diff --git a/.gitignore b/.gitignore index 37c9fe57..bea91a67 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,3 @@ *.pdb Debug/ -packages/ diff --git a/RoboCat/Chapter3.vcxproj b/RoboCat/Chapter3.vcxproj index c2d193be..9442fa83 100644 --- a/RoboCat/Chapter3.vcxproj +++ b/RoboCat/Chapter3.vcxproj @@ -128,7 +128,7 @@ ProgramDatabase EnableFastChecks ..\SDL\include;Inc;..\ - Use + Create RoboCatPCH.h @@ -370,11 +370,11 @@ - - - + + + + - @@ -383,14 +383,18 @@ - - + + + + + + @@ -404,14 +408,14 @@ - - + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + \ No newline at end of file diff --git a/RoboCat/Color.h b/RoboCat/Color.h new file mode 100644 index 00000000..84cad9ae --- /dev/null +++ b/RoboCat/Color.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include + +struct Color +{ + Uint8 r, g, b, a = 255; + + Color::Color() + { + r = g = b = a = 255; + } + + Color::Color(Uint8 x, Uint8 y, Uint8 z, Uint8 w) + { + r = x; + g = y; + b = z; + a = w; + } + + void incrementColor(Uint8 amt = 1) + { + r += amt; + if (r > 255) + r = 0; + + g += amt; + //g += (amt * 2); + if (g > 255) + g = 0; + + b += amt; + //b += (amt + 2); + if (b > 255) + b = 0; + } + + void wrapColor() + { + if (r > 255) + r = 0; + + if (g > 255) + g = 0; + + if (b > 255) + b = 0; + } + + friend std::ostream& operator<<(std::ostream& out, const Color& col) + { + out << "[" << col.r << "," << col.g << "," << col.b << "," << col.a << "]"; + return out; + } + + std::string ToString() + { + return "[" + std::to_string(r) + "," + std::to_string(g) + "," + std::to_string(b) + "," + std::to_string(a) + "]"; + } +}; \ No newline at end of file diff --git a/RoboCat/Inc/OutputWindow.h b/RoboCat/Inc/OutputWindow.h index a12ad9ef..73312118 100644 --- a/RoboCat/Inc/OutputWindow.h +++ b/RoboCat/Inc/OutputWindow.h @@ -1,3 +1,4 @@ +#pragma once // Encapsulates a simulated "output window," where // new messages are written from top to bottom diff --git a/RoboCat/Inc/RoboCatShared.h b/RoboCat/Inc/RoboCatShared.h index bc232e1f..83a3871a 100644 --- a/RoboCat/Inc/RoboCatShared.h +++ b/RoboCat/Inc/RoboCatShared.h @@ -49,12 +49,6 @@ using std::unordered_set; class RoboCat; class GameObject; -#include "RoboMath.h" - -#include "LinkingContext.h" -#include "ByteSwap.h" -#include "MemoryBitStream.h" - #include "StringUtils.h" #include "SocketAddress.h" #include "SocketAddressFactory.h" diff --git a/RoboCat/Inc/SocketAddress.h b/RoboCat/Inc/SocketAddress.h index 05bad2b8..0c8d5671 100644 --- a/RoboCat/Inc/SocketAddress.h +++ b/RoboCat/Inc/SocketAddress.h @@ -1,3 +1,5 @@ +#pragma once + class SocketAddress { public: diff --git a/RoboCat/Inc/SocketAddressFactory.h b/RoboCat/Inc/SocketAddressFactory.h index fe1e0516..2f0bfe67 100644 --- a/RoboCat/Inc/SocketAddressFactory.h +++ b/RoboCat/Inc/SocketAddressFactory.h @@ -1,4 +1,4 @@ - +#pragma once class SocketAddressFactory { diff --git a/RoboCat/Inc/SocketUtil.h b/RoboCat/Inc/SocketUtil.h index 50a726c3..8f7211c0 100644 --- a/RoboCat/Inc/SocketUtil.h +++ b/RoboCat/Inc/SocketUtil.h @@ -1,3 +1,6 @@ +#pragma once + + enum class SocketAddressFamily { INET = AF_INET, diff --git a/RoboCat/Inc/TCPSocket.h b/RoboCat/Inc/TCPSocket.h index 0779a82b..3b3a42bd 100644 --- a/RoboCat/Inc/TCPSocket.h +++ b/RoboCat/Inc/TCPSocket.h @@ -1,3 +1,6 @@ +#pragma once + + class TCPSocket { public: diff --git a/RoboCat/Inc/UDPSocket.h b/RoboCat/Inc/UDPSocket.h index 939df407..e7b9c5e1 100644 --- a/RoboCat/Inc/UDPSocket.h +++ b/RoboCat/Inc/UDPSocket.h @@ -1,3 +1,4 @@ +#pragma once class UDPSocket diff --git a/RoboCat/PlayerUser.cpp b/RoboCat/PlayerUser.cpp new file mode 100644 index 00000000..096d88fa --- /dev/null +++ b/RoboCat/PlayerUser.cpp @@ -0,0 +1,421 @@ +#include "RoboCatPCH.h" +#include "PlayerUser.h" +#include +#include + +// FUNCTION FROM user704565 AT https://stackoverflow.com/a/16286297: +std::vector split(std::string str, std::string sep) { + char* cstr = const_cast(str.c_str()); + char* current; + std::vector arr; + current = strtok(cstr, sep.c_str()); + while (current != NULL) { + arr.push_back(current); + current = strtok(NULL, sep.c_str()); + } + return arr; +} + + +PlayerUser::PlayerUser() +{ + renderer = nullptr; + window = nullptr; + unitManager = UnitManager(); +} + +PlayerUser::PlayerUser(int _flags, int _pnum, int _xpos) +{ + unitManager = UnitManager(); + sendSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + recvSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + + playerNumber = _pnum; + if (SDL_Init(SDL_INIT_EVERYTHING) == 0) + { + playerName = _pnum == 0 ? "Server" : "Player" + std::to_string(playerNumber); + std::cout << playerName << " client "<< " Subsystems Initialized!\n"; + + std::string windowName = playerName + " Window"; + + window = SDL_CreateWindow(windowName.c_str(), _xpos, SDL_WINDOWPOS_CENTERED, 500, 500, _flags); + if (window) + { + std::cout << "Window Created!\n"; + SDL_SetWindowMinimumSize(window, 100, 100); + } + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + if (renderer) + { + SDL_SetRenderDrawColor(renderer, 121, 121, 121, 255); + std::cout << "Renderer created!\n"; + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + } + } +} + +PlayerUser::~PlayerUser() +{ + closeSockets(); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); +} + +void PlayerUser::initTcpClient(std::string sendPort, std::string recvPort) +{ + sendRecvFlag = 0; + + // Create socket + sendSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (sendSocket == nullptr) + { + SocketUtil::ReportError("Creating client socket"); + ExitProcess(1); + } + + LOG("%s", "Client socket created"); + + // Bind() - "Bind" socket -> tells OS we want to use a specific address + + std::string address = StringUtils::Sprintf("127.0.0.1:%s", sendPort.c_str()); + SocketAddressPtr clientAddress = SocketAddressFactory::CreateIPv4FromString(address.c_str()); + if (clientAddress == nullptr) + { + SocketUtil::ReportError("Creating client address"); + ExitProcess(1); + } + + if (sendSocket->Bind(*clientAddress) != NO_ERROR) + { + SocketUtil::ReportError("Binding client socket"); + // This doesn't block! + ExitProcess(1); + } + + LOG("%s", "Bound client socket"); + + // Connect() -> Connect socket to remote host + + SocketAddressPtr servAddress = SocketAddressFactory::CreateIPv4FromString("127.0.0.1:"+recvPort); + if (servAddress == nullptr) + { + SocketUtil::ReportError("Creating server address"); + ExitProcess(1); + } + + if (sendSocket->Connect(*servAddress) != NO_ERROR) + { + SocketUtil::ReportError("Connecting to server"); + ExitProcess(1); + } + + LOG("%s", "Connected to server!"); + + quit = false; + std::thread receiveNewThread([&]() { // don't use [&] :) + while (!quit) // Need to add a quit here to have it really exit! + { + char buffer[4096]; + int32_t bytesReceived = sendSocket->Receive(buffer, 4096); + if (bytesReceived == 0) + { + // handle disconnect + } + if (bytesReceived < 0) + { + SocketUtil::ReportError("Receiving"); + return; + } + + std::string receivedMsg(buffer, bytesReceived); + LOG("Received message: %s", receivedMsg.c_str()); + if (receivedMsg[0] == '$') // CREATE UNIT + { + decodeUnitString(receivedMsg.erase(0, 1)); + } + else if (receivedMsg[0] == '!') // DELETE UNIT + { + decodeDeleteString(receivedMsg.erase(0, 1)); + } + } + }); + + std::cout << "Press enter to exit at any time!\n"; + std::cin.get(); + quit = true; +// recvConnSocket->~TCPSocket(); // Forcibly close socket (shouldn't call destructors like this -- make a new function for it! + receiveNewThread.join(); +} + +void PlayerUser::initTcpServer(std::string listenPort) +{ + sendRecvFlag = 1; + // Create socket + recvSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (recvSocket == nullptr) + { + SocketUtil::ReportError("Creating listening socket"); + ExitProcess(1); + } + + //recvSocket->SetNonBlockingMode(true); + + LOG("%s", "Listening socket created"); + + // Bind() - "Bind" socket -> tells OS we want to use a specific address + + SocketAddressPtr listenAddress = SocketAddressFactory::CreateIPv4FromString("127.0.0.1:"+ listenPort); + if (listenAddress == nullptr) + { + SocketUtil::ReportError("Creating listen address"); + ExitProcess(1); + } + + if (recvSocket->Bind(*listenAddress) != NO_ERROR) + { + SocketUtil::ReportError("Binding listening socket"); + // This doesn't block! + ExitProcess(1); + } + + LOG("%s", "Bound listening socket"); + + // Blocking function call -> Waits for some input; halts the program until something "interesting" happens + // Non-Blocking function call -> Returns right away, as soon as the action is completed + + // Listen() - Listen on socket -> Non-blocking; tells OS we care about incoming connections on this socket + if (recvSocket->Listen() != NO_ERROR) + { + SocketUtil::ReportError("Listening on listening socket"); + ExitProcess(1); + } + + LOG("%s", "Listening on socket"); + + // Accept() - Accept on socket -> Blocking; Waits for incoming connection and completes TCP handshake + + LOG("%s", "Waiting to accept connections..."); + SocketAddress incomingAddress; + recvConnSocket = recvSocket->Accept(incomingAddress); + while (recvConnSocket == nullptr) + { + recvConnSocket = recvSocket->Accept(incomingAddress); + // SocketUtil::ReportError("Accepting connection"); + // ExitProcess(1); + } + + LOG("Accepted connection from %s", incomingAddress.ToString().c_str()); + + quit = false; + std::thread receiveThread([&]() { // don't use [&] :) + while (!quit) // Need to add a quit here to have it really exit! + { + char buffer[4096]; + int32_t bytesReceived = recvConnSocket->Receive(buffer, 4096); + if (bytesReceived == 0) + { + // handle disconnect + } + if (bytesReceived < 0) + { + SocketUtil::ReportError("Receiving"); + return; + } + + std::string receivedMsg(buffer, bytesReceived); + LOG("Received message from %s: %s", incomingAddress.ToString().c_str(), receivedMsg.c_str()); + if (receivedMsg[0] == '$') // CREATE UNIT + { + decodeUnitString(receivedMsg.erase(0, 1)); + } + else if (receivedMsg[0] == '!') // DELETE UNIT + { + decodeDeleteString(receivedMsg.erase(0, 1)); + } + } + }); + + std::cout << "Press enter to exit at any time!\n"; + std::cin.get(); + quit = true; +// recvConnSocket->~TCPSocket(); // Forcibly close socket (shouldn't call destructors like this -- make a new function for it! + std::cout << "HERE!"; + receiveThread.join(); +} + +std::string PlayerUser::packageUnitIntoString(int _id) +{ + std::string toReturn = "$"; + + Unit* temp = unitManager.getUnit(_id); + if (temp != nullptr) + { + Vector2 pos = temp->getPosition(); + Vector2 size = temp->getSize(); + Color col = temp->getColor(); + + toReturn += + std::to_string(temp->getID()) + SEPERATOR_TOKEN + + std::to_string(temp->getType()) + SEPERATOR_TOKEN + + std::to_string(pos.x) + SEPERATOR_TOKEN + + std::to_string(pos.y) + SEPERATOR_TOKEN + + std::to_string(size.x) + SEPERATOR_TOKEN + + std::to_string(size.y) + SEPERATOR_TOKEN + + std::to_string(col.r) + SEPERATOR_TOKEN + + std::to_string(col.g) + SEPERATOR_TOKEN + + std::to_string(col.b) + SEPERATOR_TOKEN + + std::to_string(col.a); + } + + return toReturn; +} + +void PlayerUser::decodeUnitString(std::string _unitString, bool onlyPrint) +{ + if (_unitString.length() == 0) + return; + + vector splitUnitString; + + if (_unitString[0] == '$') + _unitString = _unitString.erase(0, 1); + splitUnitString = split(_unitString, SEPERATOR_TOKEN); + + int _id = std::stoi(splitUnitString[0]); + int _type = std::stoi(splitUnitString[1]); + Vector2 _pos = Vector2(std::stoi(splitUnitString[2]), std::stoi(splitUnitString[3])); + Vector2 _size = Vector2(std::stoi(splitUnitString[4]), std::stoi(splitUnitString[5])); + Color _col = Color( + (Uint8)std::stoi(splitUnitString[6]), + (Uint8)std::stoi(splitUnitString[7]), + (Uint8)std::stoi(splitUnitString[8]), + (Uint8)std::stoi(splitUnitString[9])); + + if (!onlyPrint) + recieveNewUnit(_id, _type, _pos, _size, _col); + else + { + std::string str = "ID: " + std::to_string(_id) + '\n' + + "Type: " + std::to_string(_type) + '\n' + + "Position: " + _pos.ToString() + '\n' + + "Size: " + _size.ToString() + '\n' + + "Color: " + _col.ToString() +'\n'; + + std::cout << str; + } +} + +void PlayerUser::sendUnitIterator(int _id) +{ + std::string msg = ""; + + if (sendRecvFlag == 0) + { + msg = packageUnitIntoString(_id); + sendSocket->Send(msg.c_str(), msg.length()); + } + else if (sendRecvFlag == 1) + { + msg = packageUnitIntoString(_id); + recvConnSocket->Send(msg.c_str(), msg.length()); + } +} + +void PlayerUser::sendUnitID(int _id) +{ + if (sendRecvFlag == 0) + { + std::string msg = packageUnitIntoString(_id); + sendSocket->Send(msg.c_str(), msg.length()); + } + else if (sendRecvFlag == 1) + { + std::string msg = packageUnitIntoString(_id); + recvConnSocket->Send(msg.c_str(), msg.length()); + } +} + +void PlayerUser::recieveNewUnit(int _id, int _type, Vector2 _pos, Vector2 _size, Color _col) +{ + // ensure unit does not exist locally + if (unitManager.getUnit(_id) == nullptr) + { + unitManager.createReceivedUnit(_pos, _size, _col, _type, _id); + } +} + +int PlayerUser::createRandomUnit() +{ + int w, h; + SDL_GetWindowSize(window, &w, &h); + int which = rand() % 3; + + int toReturn = -1; + + switch (which) + { + case 0: + toReturn = unitManager.createSquare(Vector2(w, h)); + break; + case 1: + toReturn = unitManager.createRectV(Vector2(w, h)); + break; + case 2: + toReturn = unitManager.createRectH(Vector2(w, h)); + break; + } + return toReturn; +} + +int PlayerUser::deleteRandomUnit() +{ + int toReturn = -1; + + Unit* rand = unitManager.getRandomUnit(); + if (rand != nullptr) + toReturn = rand->getID(); + + return toReturn; +} + +void PlayerUser::sendUnitDelete(int _id) +{ + std::string deletePackage = "!" + std::to_string(_id); + if (sendRecvFlag == 0) + { + std::string msg = deletePackage; + sendSocket->Send(msg.c_str(), msg.length()); + } + else if (sendRecvFlag == 1) + { + std::string msg = deletePackage; + recvConnSocket->Send(msg.c_str(), msg.length()); + } +} + +void PlayerUser::decodeDeleteString(std::string _deleteString) +{ + if (_deleteString.length() == 0) + return; + + unitManager.deleteUnit(std::stoi(_deleteString)); +} + +void PlayerUser::closeSockets() +{ + if (sendRecvFlag == 0) + { + sendSocket->~TCPSocket(); + } + else if (sendRecvFlag == 1) + { + + recvConnSocket->~TCPSocket(); + recvConnSocket->~TCPSocket(); + } +} + +void PlayerUser::shutdown() +{ + quit = true; +} diff --git a/RoboCat/PlayerUser.h b/RoboCat/PlayerUser.h new file mode 100644 index 00000000..051fa383 --- /dev/null +++ b/RoboCat/PlayerUser.h @@ -0,0 +1,38 @@ +#pragma once + +#include "RoboCatPCH.h" +#include +#include "UnitManager.h" + +struct PlayerUser +{ + SDL_Renderer* renderer; + SDL_Window* window; + UnitManager unitManager; + int playerNumber; + std::string playerName; + std::string SEPERATOR_TOKEN = "!"; + int sendRecvFlag = -1; + bool quit; + + TCPSocketPtr sendSocket, recvSocket, recvConnSocket; + + PlayerUser(); + PlayerUser(int _flags, int _pnum, int _xpos); + ~PlayerUser(); + + void initTcpClient(std::string sendPort, std::string recvPort); + void initTcpServer(std::string listenPort); + + std::string packageUnitIntoString(int _id); + void decodeUnitString(std::string _unitString, bool onlyPrint = false); + void sendUnitIterator(int _it); + void sendUnitID(int _id); + void recieveNewUnit(int _id, int _type, Vector2 _pos, Vector2 _size, Color _col); + int createRandomUnit(); + int deleteRandomUnit(); + void sendUnitDelete(int _id); + void decodeDeleteString(std::string _deleteString); + void closeSockets(); + void shutdown(); +}; \ No newline at end of file diff --git a/RoboCat/Src/oldMain.cpp b/RoboCat/Src/oldMain.cpp new file mode 100644 index 00000000..2d3485b7 --- /dev/null +++ b/RoboCat/Src/oldMain.cpp @@ -0,0 +1,53 @@ +// +#include "RoboCatPCH.h" +// +//#include +//#include +//#include +//#include +// +//#if _WIN32 +// +// +//int main(int argc, const char** argv) +//{ +// UNREFERENCED_PARAMETER(argc); +// UNREFERENCED_PARAMETER(argv); +//#else +//const char** __argv; +//int __argc; +//int main(int argc, const char** argv) +//{ +// __argc = argc; +// __argv = argv; +//#endif +// +// SocketUtil::StaticInit(); +// +// OutputWindow win; +// +// std::thread t([&win]() +// { +// int msgNo = 1; +// while (true) +// { +// std::this_thread::sleep_for(std::chrono::milliseconds(250)); +// std::string msgIn("~~~auto message~~~"); +// std::stringstream ss(msgIn); +// ss << msgNo; +// win.Write(ss.str()); +// msgNo++; +// } +// }); +// +// while (true) +// { +// std::string input; +// std::getline(std::cin, input); +// win.WriteFromStdin(input); +// } +// +// SocketUtil::CleanUp(); +// +// return 0; +//} diff --git a/RoboCat/TCPHandler.h b/RoboCat/TCPHandler.h new file mode 100644 index 00000000..e7acddba --- /dev/null +++ b/RoboCat/TCPHandler.h @@ -0,0 +1,156 @@ +#pragma once +#include +#include "TCPSocket.h" +#include + + +class TCPServer +{ +public: + TCPSocketPtr listenSocket; + TCPSocketPtr connSocket; + SocketAddress incomingAddress; + + TCPServer::TCPServer() + { + listenSocket = SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (listenSocket == nullptr) + { + SocketUtil::ReportError("Creating listening socket"); + LOG("%s", "Listening socket created"); + ExitProcess(1); + } + } + + void Bind(std::string IP) + { + SocketAddressPtr listenAddress = SocketAddressFactory::CreateIPv4FromString(IP); + + if (listenAddress == nullptr) + { + SocketUtil::ReportError("Creating listen address"); + + } + + if (listenSocket->Bind(*listenAddress) != NO_ERROR) + { + SocketUtil::ReportError("Binding listening socket"); + } + + LOG("%s", "Bound listening socket"); + } + + void Listen() + { + if (listenSocket->Listen() != NO_ERROR) + { + SocketUtil::ReportError("Listening on listening socket"); + ExitProcess(1); + } + + LOG("%s", "Listening on socket"); + } + + void Accept() + { + LOG("%s", "Waiting to accept connections..."); + SocketAddress incomingAddress; + TCPSocketPtr connSocket = listenSocket->Accept(incomingAddress); + while (connSocket == nullptr) + { + connSocket = listenSocket->Accept(incomingAddress); + + } + + LOG("Accepted connection from %s", incomingAddress.ToString().c_str()); + } +}; + +class TCPClient +{ +public: + TCPSocketPtr clientSocket; + std::string port; + std::string msg = ""; + + TCPClient::TCPClient() + { + SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (clientSocket == nullptr) + { + SocketUtil::ReportError("Creating client socket"); + ExitProcess(1); + } + + LOG("%s", "Client socket created"); + + port = 8080; + } + + TCPClient::TCPClient(int p) + { + SocketUtil::CreateTCPSocket(SocketAddressFamily::INET); + if (clientSocket == nullptr) + { + SocketUtil::ReportError("Creating client socket"); + ExitProcess(1); + } + + LOG("%s", "Client socket created"); + + port = p; + } + + void Bind() + { + std::string address = StringUtils::Sprintf("127.0.0.1:%s", port.c_str()); + SocketAddressPtr clientAddress = SocketAddressFactory::CreateIPv4FromString(address.c_str()); + if (clientAddress == nullptr) + { + SocketUtil::ReportError("Creating client address"); + ExitProcess(1); + } + + if (clientSocket->Bind(*clientAddress) != NO_ERROR) + { + SocketUtil::ReportError("Binding client socket"); + // This doesn't block! + ExitProcess(1); + } + + LOG("%s", "Bound client socket"); + + } + + void Connect() + { + SocketAddressPtr servAddress = SocketAddressFactory::CreateIPv4FromString("127.0.0.1:8080"); + if (servAddress == nullptr) + { + SocketUtil::ReportError("Creating server address"); + ExitProcess(1); + } + + if (clientSocket->Connect(*servAddress) != NO_ERROR) + { + SocketUtil::ReportError("Connecting to server"); + ExitProcess(1); + } + + LOG("%s", "Connected to server!"); + + while (true) + { + std::string msg("Hello server! How are you?"); + if (msg != "") + clientSocket->Send(msg.c_str(), msg.length()); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } + + void Send() + { + clientSocket->Send(msg.c_str(), msg.length()); + msg = ""; + } +}; \ No newline at end of file diff --git a/RoboCat/Unit.cpp b/RoboCat/Unit.cpp new file mode 100644 index 00000000..e7796e7f --- /dev/null +++ b/RoboCat/Unit.cpp @@ -0,0 +1,50 @@ +#include "RoboCatPCH.h" +#include "Unit.h" + +void Unit::update(float dt, Vector2 screen) +{ + int gravity = 4; + + switch (type) + { + case 0: + // square - cycle through colors + color.incrementColor(); + break; + + case 1: + // vRect - fall + if (position.y >= screen.y) + { + position.y = -size.y; + } + position.y += gravity; + rect.y = position.y; + break; + + case 2: + // hRect - teleport + if (position.x <= 0) + right = true; + else if (position.x + size.x >= screen.x) + right = false; + + if (right) + position.x += 3; + else + position.x -= 3; + + rect.x = position.x; + + break; + } +} + +void Unit::render(SDL_Renderer* renderer) +{ + SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a); + // draw rect + SDL_RenderFillRect(renderer, &rect); + + SDL_RenderPresent(renderer); +} \ No newline at end of file diff --git a/RoboCat/Unit.h b/RoboCat/Unit.h new file mode 100644 index 00000000..cadefac3 --- /dev/null +++ b/RoboCat/Unit.h @@ -0,0 +1,87 @@ +#pragma once +#include +#include "Color.h" +#include "SDL.h" +#include + +struct Vector2 +{ + int x; + int y; + + Vector2::Vector2() { x = 0; y = 0; }; + Vector2::Vector2(float a, float b) { x = a; y = b; }; + + friend std::ostream& operator<<(std::ostream& out, const Vector2& vec) + { + out << "[" << vec.x << "," << vec.y << "]"; + return out; + } + + std::string ToString() + { + return "[" + std::to_string(x) + "," + std::to_string(y) + "]"; + } +}; + +class Unit +{ +private: + + Vector2 position; + Vector2 size; // width + height + Color color; + + SDL_Rect rect; + + // 0 - square, 1 - vRect, 2 - hRect + int type; + int unitID; + + bool right; + +public: + + Unit::Unit() + { + position = Vector2(0, 0); + size = Vector2(1, 1); + type = 0; + + initRect(); + right = true; + } + + Unit::Unit(Vector2 pos, Vector2 s, int t, Color col, int id) + { + position = pos; + size = s; + type = t; + color = col; + unitID = id; + + initRect(); + right = true; + } + + void initRect() + { + rect.x = position.x; + rect.y = position.y; + rect.w = size.x; + rect.h = size.y; + } + + Vector2 getPosition() { return position; }; + void setPosition(Vector2 pos) { position = pos; rect.x = position.x; rect.y = position.y; }; + int getType() { return type; }; + SDL_Rect getRect() { return rect; }; + + void update(float dt, Vector2 screen); + + void render(SDL_Renderer* renderer); + + int getID() { return unitID; }; + Vector2 getSize() { return size; }; + Color getColor() { return color; }; +}; \ No newline at end of file diff --git a/RoboCat/UnitManager.cpp b/RoboCat/UnitManager.cpp new file mode 100644 index 00000000..1be33bf5 --- /dev/null +++ b/RoboCat/UnitManager.cpp @@ -0,0 +1,163 @@ +#include "RoboCatPCH.h" +#include "UnitManager.h" + +void UnitManager::createReceivedUnit(Vector2 _pos, Vector2 _size, Color _col, int _type, int _id) +{ + Unit temp = Unit(); + bool canCreate = true; + switch (_type) + { + case 0: // square + case 1: // vRect + case 2: // hRect + temp = Unit(Vector2(_pos.x, _pos.y), _size, _type, _col, _id); + break; + default: + canCreate = false; + } + + if (canCreate) + { + units.push_back(temp); + count++; + } +} + +int UnitManager::createSquare(Vector2 screen) +{ + int posx = GetRandInt(0, screen.x); + int posy = GetRandInt(0, screen.y); + int size = GetRandInt(20, 121) ; + Color col = colors.at(GetRandInt(0, colors.size())); + + Unit temp = Unit(Vector2(posx, posy), Vector2(size, size), 0, col, GetRandUnitInt(0,1000)); + units.push_back(temp); + count++; + return temp.getID(); +} + +int UnitManager::createRectV(Vector2 screen) +{ + int posx = GetRandInt(0, screen.x); + int posy = GetRandInt(0, screen.y); + int sizex = GetRandInt(20, 40); + int sizey = GetRandInt(40, 61); + Color col = colors.at(GetRandInt(0, colors.size())); + + Unit temp = Unit(Vector2(posx, posy), Vector2(sizex, sizey), 1, col, GetRandUnitInt(0, 1000)); + units.push_back(temp); + count++; + return temp.getID(); +} + +int UnitManager::createRectH(Vector2 screen) +{ + int posx = GetRandInt(0, screen.x); + int posy = GetRandInt(0, screen.y); + int sizex = GetRandInt(60, 81); + int sizey = GetRandInt(40, 60); + Color col = colors.at(GetRandInt(0, colors.size())); + + Unit temp = Unit(Vector2(posx, posy), Vector2(sizex, sizey), 2, col, GetRandUnitInt(0, 1000)); + units.push_back(temp); + count++; + return temp.getID(); +} + +void UnitManager::createColors() +{ + colors.push_back(Color(200, 75, 60, 255)); + colors.push_back(Color(61, 226, 255, 255)); + colors.push_back(Color(155, 132, 245, 255)); + colors.push_back(Color(255, 168, 197, 255)); + colors.push_back(Color(12, 12, 179, 255)); + colors.push_back(Color(252, 0, 93, 255)); + colors.push_back(Color(255, 91, 15, 255)); + colors.push_back(Color(76, 199, 74, 255)); +} + +void UnitManager::updateUnits(float dt, Vector2 screen) +{ + for (int i = 0; i < count; i++) + units.at(i).update(dt, screen); +} + +void UnitManager::RenderUnits(SDL_Renderer* renderer) +{ + for (int i = 0; i < count; i++) + units.at(i).render(renderer); +} + +int UnitManager::GetRandInt(int min, int max) +{ + int r = std::rand() % max + min; + return r; +} + +int UnitManager::GetRandUnitInt(int min, int max) +{ + int r = std::rand() % max + min; + bool validID = true; + for (int i = 0; i < count; i++) + if (units[i].getID() == r) + validID = false; + + while (!validID) + { + validID = true; + r = std::rand() % max + min; + for (int i = 0; i < count; i++) + if (units[i].getID() == r) + validID = false; + } + + return r; +} + +Unit* UnitManager::getUnit(int id) +{ + Unit* toReturn = nullptr; + + for (int i = 0; i < count; i++) + if (units[i].getID() == id) + { + toReturn = &units[i]; + break; + } + + return toReturn; +} + +int UnitManager::getUnitIteratorFromID(int id) +{ + int toReturn = -1; + + for (int i = 0; i < count; i++) + { + if (id == units[i].getID()) + { + toReturn = i; + break; + } + } + + return toReturn; +} + +Unit* UnitManager::getRandomUnit() +{ + Unit* toReturn = nullptr; + + if (count > 0) + toReturn = &units[rand() % count]; + + return toReturn; +} + +void UnitManager::deleteUnit(int id) +{ + int it = getUnitIteratorFromID(id); + if (it != -1) + units.erase(units.begin() + it); + count--; +} diff --git a/RoboCat/UnitManager.h b/RoboCat/UnitManager.h new file mode 100644 index 00000000..759024ba --- /dev/null +++ b/RoboCat/UnitManager.h @@ -0,0 +1,48 @@ +#pragma once +#include "Unit.h" +#include "Color.h" +#include +#include + +class UnitManager +{ +private: + std::vector colors; + +public: + int count; + std::vector units; + + UnitManager::UnitManager() + { + std::srand(time(NULL)); + count = 0; + createColors(); + } + + void createReceivedUnit(Vector2 _pos, Vector2 _size, Color _col, int _type, int _id); + + int createSquare(Vector2 screen); + + int createRectV(Vector2 screen); + + int createRectH(Vector2 screen); + + void createColors(); + + void updateUnits(float dt, Vector2 screen); + + void RenderUnits(SDL_Renderer* renderer); + + int GetRandInt(int min, int max); + + int GetRandUnitInt(int min, int max); + + Unit* getUnit(int id); + + int getUnitIteratorFromID(int id); + + Unit* getRandomUnit(); + + void deleteUnit(int id); +}; diff --git a/RoboCat/main.cpp b/RoboCat/main.cpp new file mode 100644 index 00000000..fe703734 --- /dev/null +++ b/RoboCat/main.cpp @@ -0,0 +1,182 @@ +#include +#include "SDL.h" +#include +#undef main +#include "Unit.h" +#include "UnitManager.h" +#include +#include +#include "PlayerUser.h" + +PlayerUser* p1, * p2; + +bool isRunning; +bool fullscreen; + +void handleEvents(); +void update(float dt); +void render(); + +#define TICK_INTERVAL 30 + +static Uint32 next_time; + + +Uint32 time_left(void) +{ + Uint32 now; + + now = SDL_GetTicks(); + if (next_time <= now) + return 0; + else + return next_time - now; +} + +std::string CLIENT_SEND_PORT = "1250", CLIENT_RECV_PORT = "2250"; + + +#if _WIN32 +int main(int argc, const char** argv) +{ + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); +#else +const char** __argv; +int __argc; +int main(int argc, const char** argv, const char** argz) +{ + __argc = argc; + __argv = argv; + __argz = argz; +#endif + + SocketUtil::StaticInit(); + + fullscreen = false; + int flags = 0; + flags = SDL_WINDOW_RESIZABLE; + if (fullscreen) { + flags = flags | SDL_WINDOW_FULLSCREEN; + } + + p1 = new PlayerUser(flags, 1, 100); + p2 = new PlayerUser(flags, 2, 1300); + + CLIENT_SEND_PORT = std::to_string(rand() % 1000 + 8999); + CLIENT_RECV_PORT = std::to_string(rand() % 1000 + 8999); + + OutputWindow p1Client,p2Client; + std::thread p1c([&p1Client]() + { + p1->initTcpClient(CLIENT_SEND_PORT, CLIENT_RECV_PORT); + }); + std::thread p2c([&p2Client]() + { + p2->initTcpServer(CLIENT_RECV_PORT); + }); + + + Uint32 lastUpdate = SDL_GetTicks(); + + isRunning = true; + + while (isRunning) + { + // for physics loop + Uint32 current = SDL_GetTicks(); + float dt = (current - lastUpdate) / 1000.0f; + + handleEvents(); + update(dt); + render(); + + SDL_Delay(time_left()); + next_time += TICK_INTERVAL; + lastUpdate = current; + } + + //frees memory associated with renderer and window + + + p1->shutdown(); + p1c.join(); + + p2->shutdown(); + p2c.join(); + + delete p2; + delete p1; + SocketUtil::CleanUp(); + SDL_Quit(); + + return 0; +} + +void handleEvents() +{ + SDL_Event event; + SDL_PollEvent(&event); + + + switch (event.type) + { + case SDL_QUIT: + isRunning = false; + std::system("Pause"); + break; + case SDL_KEYDOWN: + { + bool isP1Window = event.window.windowID == SDL_GetWindowID(p1->window); + PlayerUser* eventUser = (isP1Window ? p1 : p2); + + if (event.key.keysym.sym == SDLK_j) + { + std::cout << "Create rand unit here" << " FROM " << (eventUser->playerName) << std::endl; + + int id = eventUser->createRandomUnit(); + if (id != -1) + eventUser->sendUnitIterator(id); + } + else if (event.key.keysym.sym == SDLK_k) + { + std::cout << "Delete rand unit here" << " FROM " << (eventUser->playerName) << std::endl; + + int id = eventUser->deleteRandomUnit(); + if (id != -1) + { + eventUser->sendUnitDelete(id); + eventUser->unitManager.deleteUnit(id); + } + } + else if (event.key.keysym.sym == SDLK_ESCAPE) + isRunning = false; + } + default: + break; + } +} + +void render() +{ + SDL_SetRenderDrawColor(p1->renderer, 121, 121, 121, 255); + SDL_RenderClear(p1->renderer); + SDL_RenderPresent(p1->renderer); + p1->unitManager.RenderUnits(p1->renderer); + + SDL_SetRenderDrawColor(p2->renderer, 121, 121, 121, 255); + SDL_RenderClear(p2->renderer); + SDL_RenderPresent(p2->renderer); + p2->unitManager.RenderUnits(p2->renderer); +} + +//simple update function +void update(float dt) +{ + int w, h; + SDL_GetWindowSize(p1->window, &w, &h); + p1->unitManager.updateUnits(dt, Vector2(w, h)); + + SDL_GetWindowSize(p2->window, &w, &h); + p2->unitManager.updateUnits(dt, Vector2(w, h)); +} \ No newline at end of file diff --git a/RoboCat/packages.config b/RoboCat/packages.config index 9ff6486d..94957f1a 100644 --- a/RoboCat/packages.config +++ b/RoboCat/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/Assets/BMP.bmp b/VS_Proj/gpr-430-assignment2/Assets/BMP.bmp new file mode 100644 index 00000000..cc29e5ea Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/Assets/BMP.bmp differ diff --git a/VS_Proj/gpr-430-assignment2/Assets/Background_Image.jpg b/VS_Proj/gpr-430-assignment2/Assets/Background_Image.jpg new file mode 100644 index 00000000..bbd7decc Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/Assets/Background_Image.jpg differ diff --git a/VS_Proj/gpr-430-assignment2/Assets/Untitled.bmp b/VS_Proj/gpr-430-assignment2/Assets/Untitled.bmp new file mode 100644 index 00000000..cc29e5ea Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/Assets/Untitled.bmp differ diff --git a/VS_Proj/gpr-430-assignment2/Assets/Untitled.jpg b/VS_Proj/gpr-430-assignment2/Assets/Untitled.jpg new file mode 100644 index 00000000..9bd60691 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/Assets/Untitled.jpg differ diff --git a/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/Colour.cpp b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/Colour.cpp new file mode 100644 index 00000000..39433c59 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/Colour.cpp @@ -0,0 +1,31 @@ +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +Colour.cpp +*/ + +#include "Colour.h" + +//Constructor - without alpha +Colour::Colour(unsigned __int8 r, unsigned __int8 g, unsigned __int8 b) +{ + mR = r; + mG = g; + mB = b; + mA = 255; +} + +//Constructor - with alpha +Colour::Colour(unsigned __int8 r, unsigned __int8 g, unsigned __int8 b, unsigned __int8 a) +{ + mR = r; + mG = g; + mB = b; + mA = a; +} + +//Destructor +Colour::~Colour() +{ + +} \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/Colour.h b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/Colour.h new file mode 100644 index 00000000..216b028c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/Colour.h @@ -0,0 +1,43 @@ +#pragma once + +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +Colour.h + + File information: + This file contains data used for colours. +*/ + +class Colour +{ + //-------------------------Private data------------------------- + + //Red channel + unsigned __int8 mR; + + //Green channel + unsigned __int8 mG; + + //Blue channel + unsigned __int8 mB; + + //Alpha channel + unsigned __int8 mA; + + //-------------------------Public data------------------------- +public: + + //Constructor(s) + Colour(unsigned __int8 r, unsigned __int8 g, unsigned __int8 b); + Colour(unsigned __int8 r, unsigned __int8 g, unsigned __int8 b, unsigned __int8 a); + + //Destructor + ~Colour(); + + //Accessor(s) + unsigned __int8 getR() { return mR; }; + unsigned __int8 getG() { return mG; }; + unsigned __int8 getB() { return mB; }; + unsigned __int8 getA() { return mA; }; +}; diff --git a/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/GraphicsLibrary.cpp b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/GraphicsLibrary.cpp new file mode 100644 index 00000000..56029438 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/GraphicsLibrary.cpp @@ -0,0 +1,125 @@ +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +GraphicsLibrary.cpp +*/ + +#include "GraphicsLibrary.h" + +#include +#include + +//Constructor +GraphicsLibrary::GraphicsLibrary(float screenSizeX, float screenSizeY) +{ + //Setup data - screen size + mScreenSizeX = screenSizeX; + mScreenSizeY = screenSizeY; + + //Allegro display + mpDisplay = nullptr; +} + +//Destructor +GraphicsLibrary::~GraphicsLibrary() +{ + //Delete bitmaps + std::vector>::iterator iterator; + for (iterator = mBitmapPointersVector.begin(); iterator != mBitmapPointersVector.end(); ++iterator) + { + al_destroy_bitmap(iterator->second); + } + mBitmapPointersVector.clear(); + + //Clean up display + al_destroy_display(mpDisplay); + mpDisplay = nullptr; +} + +bool GraphicsLibrary::init(std::string backgroundFilePath) +{ + //Init allegro + if (!al_init()) + { + std::cout << "error initting Allegro\n"; + system("pause"); + return false; + } + + //Init image addon + if (!al_init_image_addon()) + { + std::cout << "error initting image add-on\n"; + system("pause"); + return false; + } + + //Init font add on + if (!al_init_font_addon()) + { + std::cout << "error initting font add-on\n"; + system("pause"); + return false; + } + + //Init ttf add on + if (!al_init_ttf_addon()) + { + std::cout << "error initting ttf add-on\n"; + system("pause"); + return false; + } + + //Setup display + mpDisplay = al_create_display(mScreenSizeX, mScreenSizeY); + + if (mpDisplay == nullptr) + { + return false; + } + + return true; +} + +void GraphicsLibrary::render() +{ + //Flip display buffers + al_flip_display(); +} + +void GraphicsLibrary::loadImage(std::string imageFilePath, std::string imageIdentifier) +{ + //Add the name of the image and the loaded bitmap to the vector of pairs + mBitmapPointersVector.push_back(std::make_pair(imageIdentifier, al_load_bitmap(imageFilePath.c_str()))); +} + +void GraphicsLibrary::drawImage(std::string imageIdentifier, float posX, float posY) +{ + //Find the image and draw if it exists + std::vector>::iterator iterator; + + for (iterator = mBitmapPointersVector.begin(); iterator != mBitmapPointersVector.end(); ++iterator) + { + if (iterator->first == imageIdentifier) + { + al_draw_bitmap(iterator->second, posX, posY, 0); + } + } +} + +void GraphicsLibrary::drawTintedImage(std::string imageIdentifier, float posX, float posY, Colour col) +{ + //Find the image and draw if it exists + std::vector>::iterator iterator; + + //Set colour + ALLEGRO_COLOR colour = al_map_rgba(col.getR(), col.getG(), col.getB(), col.getA()); + + for (iterator = mBitmapPointersVector.begin(); iterator != mBitmapPointersVector.end(); ++iterator) + { + if (iterator->first == imageIdentifier) + { + al_draw_tinted_bitmap(iterator->second, colour, posX, posY, 0); + } + } +} \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/GraphicsLibrary.h b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/GraphicsLibrary.h new file mode 100644 index 00000000..a8a9519c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/GraphicsLibrary.h @@ -0,0 +1,67 @@ +#pragma once + +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +GraphicsLibrary.h + + File information: + This file contains function abstractions from Allegro 5, wrapped up in my Graphics Library. This will + be used to render images and text to the screen. + + Source I am consulting: Allegro 5.0.10 Manual - http://cdn.allegro.cc/file/library/allegro/5.0.10/allegro-5.0.10-manual.pdf +*/ + +#include +#include + +#include "Colour.h" + +//https://github.com/liballeg/allegro_wiki/wiki/Allegro-in-Visual-Studio#using-nuget-within-visual-studio +#include +#include +#include +#include +#include +#include + +class GraphicsLibrary +{ + //-------------------------Private data------------------------- + + //Screen data + float mScreenSizeX; + float mScreenSizeY; + + //Allegro display + ALLEGRO_DISPLAY* mpDisplay; + + //Other images to draw + std::vector> mBitmapPointersVector; + + friend class InputSystem; + + //-------------------------Public data------------------------- +public: + + //Constructor(s) + GraphicsLibrary(float screenSizeX, float screenSizeY); + + //Destructor + ~GraphicsLibrary(); + + //Accessor(s) + float getScreenSizeX() { return mScreenSizeX; }; + float getScreenSizeY() { return mScreenSizeY; }; + + //Mutator(s) + + //Functions + bool init(std::string backgroundFilePath); + void render(); + void loadImage(std::string imageFilePath, std::string imageIdentifier); + + //Drawing functions + void drawImage(std::string imageIdentifier, float posX, float posY); + void drawTintedImage(std::string imageIdentifier, float posX, float posY, Colour col); +}; \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/InputSystem.cpp b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/InputSystem.cpp new file mode 100644 index 00000000..1193b038 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/InputSystem.cpp @@ -0,0 +1,135 @@ +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +InputSystem.cpp +*/ + +#include "InputSystem.h" + +#include + +//Constructor +InputSystem::InputSystem() +{ + //Create an event queue + mpEventQueue = al_create_event_queue(); +} + +//Destructor +InputSystem::~InputSystem() +{ + //Cleanup event queue + al_destroy_event_queue(mpEventQueue); + mpEventQueue = nullptr; +} + +float InputSystem::getMouseX() +{ + //Update mouse state + ALLEGRO_MOUSE_STATE mouseState; + al_get_mouse_state(&mouseState); + + return mouseState.x; +} + +float InputSystem::getMouseY() +{ + //Update mouse state + ALLEGRO_MOUSE_STATE mouseState; + al_get_mouse_state(&mouseState); + + return mouseState.y; +} + +std::pair InputSystem::getMousePosition() +{ + //Update mouse state + ALLEGRO_MOUSE_STATE mouseState; + al_get_mouse_state(&mouseState); + + return std::make_pair(mouseState.x, mouseState.y); +} + +//Init +bool InputSystem::init(GraphicsLibrary* pGraphicsLib) +{ + //Init keyboard + if (!al_install_keyboard()) + { + std::cout << "error installing Allegro keyboard plugin\n"; + system("pause"); + return false; + } + + //Init mouse + if (!al_install_mouse()) + { + std::cout << "error installing Allegro mouse plugin\n"; + system("pause"); + return false; + } + + //Register screen event source + al_register_event_source(mpEventQueue, al_get_display_event_source(pGraphicsLib->mpDisplay)); + + //Register keyboard event source + al_register_event_source(mpEventQueue, al_get_keyboard_event_source()); + + //Register mouse event source + al_register_event_source(mpEventQueue, al_get_mouse_event_source()); + + return true; +} + +MouseButton InputSystem::getMouseInput() +{ + //If there is an event + al_wait_for_event(mpEventQueue, &mEvent); + + if (mEvent.type == InputMode::MouseDown) + { + //Update mouse state + ALLEGRO_MOUSE_STATE mouseState; + al_get_mouse_state(&mouseState); + + //Check the button pressed + if (mouseState.buttons & 1) //Left mouse held + { + return MouseButton::LeftMouse; + } + else if (mouseState.buttons & 2) //Right mouse held + { + return MouseButton::RightMouse; + } + else if (mouseState.buttons & 4) //Middle mouse held + { + return MouseButton::MiddleMouse; + } + } +} + +KeyCode InputSystem::getKeyboardInput() +{ + //If there is an event + al_wait_for_event(mpEventQueue, &mEvent); + + if (mEvent.type == InputMode::KeyPressed) + { + //Check the type + switch (mEvent.keyboard.keycode) + { + case KeyCode::Escape: + return KeyCode::Escape; + break; + + case KeyCode::R: + return KeyCode::R; + break; + + default: + /*return KeyCode::NONE*/; + } + } + + //return KeyCode::NONE; +} \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/InputSystem.h b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/InputSystem.h new file mode 100644 index 00000000..3a69029e --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/InputSystem.h @@ -0,0 +1,68 @@ +#pragma once + +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +InputSystem.h + + File information: + This file contains the keycodes for input, which can be used in any way desired by other classes + and files. +*/ + +#include "GraphicsLibrary.h" + +//Include allegro libraries for input +#include + +enum KeyCode +{ + Escape = ALLEGRO_KEY_ESCAPE, + R = ALLEGRO_KEY_R +}; + +enum MouseButton +{ + LeftMouse = 0, + RightMouse = 1, + MiddleMouse = 2 +}; + +enum InputMode +{ + NONE = -1, + KeyPressed = ALLEGRO_EVENT_KEY_DOWN, + KeyReleased = ALLEGRO_EVENT_KEY_UP, + MouseDown = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, + MouseUp = ALLEGRO_EVENT_MOUSE_BUTTON_UP +}; + +class InputSystem +{ + //-------------------------Private data------------------------- + + //Event queue + ALLEGRO_EVENT_QUEUE* mpEventQueue; + + //Event + ALLEGRO_EVENT mEvent; + + //-------------------------Public data------------------------- +public: + + //Constructor(s) + InputSystem(); + + //Destructor + ~InputSystem(); + + //Accessor(s) + float getMouseX(); + float getMouseY(); + std::pair getMousePosition(); + + //Functions + bool init(GraphicsLibrary* pGraphicsLib); + MouseButton getMouseInput(); + KeyCode getKeyboardInput(); +}; \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/LICENSE b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/LICENSE new file mode 100644 index 00000000..52e8a5fb --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Adel Talhouk + +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. diff --git a/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/README.md b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/README.md new file mode 100644 index 00000000..8cc97298 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/allegro_wrapper_functions-main/README.md @@ -0,0 +1,50 @@ +# allegro_wrapper_functions +Some Allegro 5 wrapper functions for C++ + +I wrote some code for my Computer Architecture final project in FA21 that allowed me to use abstracted Allegro 5 functions. Feel free to use this code, but please keep the block comment in each file :) + +EXAMPLE INIT FUNCTION IN MAIN.CPP: + +//-------------------------Graphics Data------------------------- + +GraphicsLibrary* pGraphics; + +float screenSizeX = 1600.0; + +float screenSizeY = 900.0; + +//-------------------------Input Data------------------------- + +InputSystem* pInput; + +//-------------------------Assets------------------------- + +const std::string ASSET_PATH = "..\\Assets\\"; + +const std::string BACKGROUND_IMAGE_FILE = "Background_Image.jpg"; + +//-------------------------Asset Identifiers------------------------- + +const std::string backgroundImageSprite = "background_image_image"; + +bool init() + +{ + + bool bSuccessfulInit = false; + + //Setup the graphical window + pGraphics = new GraphicsLibrary(screenSizeX, screenSizeY); + bSuccessfulInit = pGraphics->init(ASSET_PATH + BACKGROUND_IMAGE_FILE); + + //Add images to the graphcis library + pGraphics->loadImage(ASSET_PATH + BACKGROUND_IMAGE_FILE, backgroundImageSprite); + + //Setup the input system + pInput = new InputSystem(); + if (bSuccessfulInit) + bSuccessfulInit = pInput->init(pGraphics); + + //Init and return if it succeeded or not + return bSuccessfulInit; +} diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2.sln b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2.sln new file mode 100644 index 00000000..c46c8835 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31005.135 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr-430-assignment2", "gpr-430-assignment2\gpr-430-assignment2.vcxproj", "{4047DAB2-5011-452C-94CB-937A01520E5D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4047DAB2-5011-452C-94CB-937A01520E5D}.Debug|x64.ActiveCfg = Debug|x64 + {4047DAB2-5011-452C-94CB-937A01520E5D}.Debug|x64.Build.0 = Debug|x64 + {4047DAB2-5011-452C-94CB-937A01520E5D}.Debug|x86.ActiveCfg = Debug|Win32 + {4047DAB2-5011-452C-94CB-937A01520E5D}.Debug|x86.Build.0 = Debug|Win32 + {4047DAB2-5011-452C-94CB-937A01520E5D}.Release|x64.ActiveCfg = Release|x64 + {4047DAB2-5011-452C-94CB-937A01520E5D}.Release|x64.Build.0 = Release|x64 + {4047DAB2-5011-452C-94CB-937A01520E5D}.Release|x86.ActiveCfg = Release|Win32 + {4047DAB2-5011-452C-94CB-937A01520E5D}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {65C8244C-A330-4BF2-B011-978C7F9FDEA1} + EndGlobalSection +EndGlobal diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/BG.jpg b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/BG.jpg new file mode 100644 index 00000000..bbd7decc Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/BG.jpg differ diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/BMP.bmp b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/BMP.bmp new file mode 100644 index 00000000..cc29e5ea Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/BMP.bmp differ diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/Colour.cpp b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/Colour.cpp new file mode 100644 index 00000000..39433c59 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/Colour.cpp @@ -0,0 +1,31 @@ +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +Colour.cpp +*/ + +#include "Colour.h" + +//Constructor - without alpha +Colour::Colour(unsigned __int8 r, unsigned __int8 g, unsigned __int8 b) +{ + mR = r; + mG = g; + mB = b; + mA = 255; +} + +//Constructor - with alpha +Colour::Colour(unsigned __int8 r, unsigned __int8 g, unsigned __int8 b, unsigned __int8 a) +{ + mR = r; + mG = g; + mB = b; + mA = a; +} + +//Destructor +Colour::~Colour() +{ + +} \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/Colour.h b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/Colour.h new file mode 100644 index 00000000..216b028c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/Colour.h @@ -0,0 +1,43 @@ +#pragma once + +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +Colour.h + + File information: + This file contains data used for colours. +*/ + +class Colour +{ + //-------------------------Private data------------------------- + + //Red channel + unsigned __int8 mR; + + //Green channel + unsigned __int8 mG; + + //Blue channel + unsigned __int8 mB; + + //Alpha channel + unsigned __int8 mA; + + //-------------------------Public data------------------------- +public: + + //Constructor(s) + Colour(unsigned __int8 r, unsigned __int8 g, unsigned __int8 b); + Colour(unsigned __int8 r, unsigned __int8 g, unsigned __int8 b, unsigned __int8 a); + + //Destructor + ~Colour(); + + //Accessor(s) + unsigned __int8 getR() { return mR; }; + unsigned __int8 getG() { return mG; }; + unsigned __int8 getB() { return mB; }; + unsigned __int8 getA() { return mA; }; +}; diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/GraphicsLibrary.cpp b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/GraphicsLibrary.cpp new file mode 100644 index 00000000..bfd7de5d --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/GraphicsLibrary.cpp @@ -0,0 +1,126 @@ +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +GraphicsLibrary.cpp +*/ + +#include "GraphicsLibrary.h" + +#include +#include + +//Constructor +GraphicsLibrary::GraphicsLibrary(float screenSizeX, float screenSizeY) +{ + //Setup data - screen size + mScreenSizeX = screenSizeX; + mScreenSizeY = screenSizeY; + + //Allegro display + mpDisplay = nullptr; +} + +//Destructor +GraphicsLibrary::~GraphicsLibrary() +{ + //Delete bitmaps + std::vector>::iterator iterator; + for (iterator = mBitmapPointersVector.begin(); iterator != mBitmapPointersVector.end(); ++iterator) + { + al_destroy_bitmap(iterator->second); + } + mBitmapPointersVector.clear(); + + //Clean up display + al_destroy_display(mpDisplay); + mpDisplay = nullptr; +} + +bool GraphicsLibrary::init(std::string backgroundFilePath) +{ + //Init allegro + if (!al_init()) + { + std::cout << "error initting Allegro\n"; + system("pause"); + return false; + } + + //Init image addon + if (!al_init_image_addon()) + { + std::cout << "error initting image add-on\n"; + system("pause"); + return false; + } + + //Init font add on + if (!al_init_font_addon()) + { + std::cout << "error initting font add-on\n"; + system("pause"); + return false; + } + + //Init ttf add on + if (!al_init_ttf_addon()) + { + std::cout << "error initting ttf add-on\n"; + system("pause"); + return false; + } + + //Setup display + mpDisplay = al_create_display(mScreenSizeX, mScreenSizeY); + + if (mpDisplay == nullptr) + { + return false; + } + + return true; +} + +void GraphicsLibrary::render() +{ + //Flip display buffers + al_flip_display(); +} + +void GraphicsLibrary::loadImage(std::string imageFilePath, std::string imageIdentifier) +{ + //Add the name of the image and the loaded bitmap to the vector of pairs + ALLEGRO_BITMAP *bmp = al_load_bitmap(imageFilePath.c_str()); + mBitmapPointersVector.push_back(std::make_pair(imageIdentifier, bmp)); +} + +void GraphicsLibrary::drawImage(std::string imageIdentifier, float posX, float posY) +{ + //Find the image and draw if it exists + std::vector>::iterator iterator; + + for (iterator = mBitmapPointersVector.begin(); iterator != mBitmapPointersVector.end(); ++iterator) + { + if (iterator->first == imageIdentifier) + { + al_draw_bitmap(iterator->second, posX, posY, 0); + } + } +} + +void GraphicsLibrary::drawTintedImage(std::string imageIdentifier, float posX, float posY, Colour col) +{ + //Find the image and draw if it exists + std::vector>::iterator iterator; + + //Set colour + ALLEGRO_COLOR colour = al_map_rgba(col.getR(), col.getG(), col.getB(), col.getA()); + + for (iterator = mBitmapPointersVector.begin(); iterator != mBitmapPointersVector.end(); ++iterator) + { + if (iterator->first == imageIdentifier) + { + al_draw_tinted_bitmap(iterator->second, colour, posX, posY, 0); + } + } +} \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/GraphicsLibrary.h b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/GraphicsLibrary.h new file mode 100644 index 00000000..a8a9519c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/GraphicsLibrary.h @@ -0,0 +1,67 @@ +#pragma once + +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +GraphicsLibrary.h + + File information: + This file contains function abstractions from Allegro 5, wrapped up in my Graphics Library. This will + be used to render images and text to the screen. + + Source I am consulting: Allegro 5.0.10 Manual - http://cdn.allegro.cc/file/library/allegro/5.0.10/allegro-5.0.10-manual.pdf +*/ + +#include +#include + +#include "Colour.h" + +//https://github.com/liballeg/allegro_wiki/wiki/Allegro-in-Visual-Studio#using-nuget-within-visual-studio +#include +#include +#include +#include +#include +#include + +class GraphicsLibrary +{ + //-------------------------Private data------------------------- + + //Screen data + float mScreenSizeX; + float mScreenSizeY; + + //Allegro display + ALLEGRO_DISPLAY* mpDisplay; + + //Other images to draw + std::vector> mBitmapPointersVector; + + friend class InputSystem; + + //-------------------------Public data------------------------- +public: + + //Constructor(s) + GraphicsLibrary(float screenSizeX, float screenSizeY); + + //Destructor + ~GraphicsLibrary(); + + //Accessor(s) + float getScreenSizeX() { return mScreenSizeX; }; + float getScreenSizeY() { return mScreenSizeY; }; + + //Mutator(s) + + //Functions + bool init(std::string backgroundFilePath); + void render(); + void loadImage(std::string imageFilePath, std::string imageIdentifier); + + //Drawing functions + void drawImage(std::string imageIdentifier, float posX, float posY); + void drawTintedImage(std::string imageIdentifier, float posX, float posY, Colour col); +}; \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/InputSystem.cpp b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/InputSystem.cpp new file mode 100644 index 00000000..1193b038 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/InputSystem.cpp @@ -0,0 +1,135 @@ +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +InputSystem.cpp +*/ + +#include "InputSystem.h" + +#include + +//Constructor +InputSystem::InputSystem() +{ + //Create an event queue + mpEventQueue = al_create_event_queue(); +} + +//Destructor +InputSystem::~InputSystem() +{ + //Cleanup event queue + al_destroy_event_queue(mpEventQueue); + mpEventQueue = nullptr; +} + +float InputSystem::getMouseX() +{ + //Update mouse state + ALLEGRO_MOUSE_STATE mouseState; + al_get_mouse_state(&mouseState); + + return mouseState.x; +} + +float InputSystem::getMouseY() +{ + //Update mouse state + ALLEGRO_MOUSE_STATE mouseState; + al_get_mouse_state(&mouseState); + + return mouseState.y; +} + +std::pair InputSystem::getMousePosition() +{ + //Update mouse state + ALLEGRO_MOUSE_STATE mouseState; + al_get_mouse_state(&mouseState); + + return std::make_pair(mouseState.x, mouseState.y); +} + +//Init +bool InputSystem::init(GraphicsLibrary* pGraphicsLib) +{ + //Init keyboard + if (!al_install_keyboard()) + { + std::cout << "error installing Allegro keyboard plugin\n"; + system("pause"); + return false; + } + + //Init mouse + if (!al_install_mouse()) + { + std::cout << "error installing Allegro mouse plugin\n"; + system("pause"); + return false; + } + + //Register screen event source + al_register_event_source(mpEventQueue, al_get_display_event_source(pGraphicsLib->mpDisplay)); + + //Register keyboard event source + al_register_event_source(mpEventQueue, al_get_keyboard_event_source()); + + //Register mouse event source + al_register_event_source(mpEventQueue, al_get_mouse_event_source()); + + return true; +} + +MouseButton InputSystem::getMouseInput() +{ + //If there is an event + al_wait_for_event(mpEventQueue, &mEvent); + + if (mEvent.type == InputMode::MouseDown) + { + //Update mouse state + ALLEGRO_MOUSE_STATE mouseState; + al_get_mouse_state(&mouseState); + + //Check the button pressed + if (mouseState.buttons & 1) //Left mouse held + { + return MouseButton::LeftMouse; + } + else if (mouseState.buttons & 2) //Right mouse held + { + return MouseButton::RightMouse; + } + else if (mouseState.buttons & 4) //Middle mouse held + { + return MouseButton::MiddleMouse; + } + } +} + +KeyCode InputSystem::getKeyboardInput() +{ + //If there is an event + al_wait_for_event(mpEventQueue, &mEvent); + + if (mEvent.type == InputMode::KeyPressed) + { + //Check the type + switch (mEvent.keyboard.keycode) + { + case KeyCode::Escape: + return KeyCode::Escape; + break; + + case KeyCode::R: + return KeyCode::R; + break; + + default: + /*return KeyCode::NONE*/; + } + } + + //return KeyCode::NONE; +} \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/InputSystem.h b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/InputSystem.h new file mode 100644 index 00000000..3a69029e --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/InputSystem.h @@ -0,0 +1,68 @@ +#pragma once + +/* +Allegro Wrapper Functions +Written by Adel Talhouk in FA21 +InputSystem.h + + File information: + This file contains the keycodes for input, which can be used in any way desired by other classes + and files. +*/ + +#include "GraphicsLibrary.h" + +//Include allegro libraries for input +#include + +enum KeyCode +{ + Escape = ALLEGRO_KEY_ESCAPE, + R = ALLEGRO_KEY_R +}; + +enum MouseButton +{ + LeftMouse = 0, + RightMouse = 1, + MiddleMouse = 2 +}; + +enum InputMode +{ + NONE = -1, + KeyPressed = ALLEGRO_EVENT_KEY_DOWN, + KeyReleased = ALLEGRO_EVENT_KEY_UP, + MouseDown = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, + MouseUp = ALLEGRO_EVENT_MOUSE_BUTTON_UP +}; + +class InputSystem +{ + //-------------------------Private data------------------------- + + //Event queue + ALLEGRO_EVENT_QUEUE* mpEventQueue; + + //Event + ALLEGRO_EVENT mEvent; + + //-------------------------Public data------------------------- +public: + + //Constructor(s) + InputSystem(); + + //Destructor + ~InputSystem(); + + //Accessor(s) + float getMouseX(); + float getMouseY(); + std::pair getMousePosition(); + + //Functions + bool init(GraphicsLibrary* pGraphicsLib); + MouseButton getMouseInput(); + KeyCode getKeyboardInput(); +}; \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/gpr-430-assignment2.vcxproj b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/gpr-430-assignment2.vcxproj new file mode 100644 index 00000000..285b94a6 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/gpr-430-assignment2.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {4047dab2-5011-452c-94cb-937a01520e5d} + gpr430assignment2 + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/main.cpp b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/main.cpp new file mode 100644 index 00000000..0449cc93 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/main.cpp @@ -0,0 +1,61 @@ +#include +#include "Colour.h" +#include "GraphicsLibrary.h" +#include "InputSystem.h" +#include + + +//-------------------------Graphics Data------------------------- + +GraphicsLibrary * pGraphics; + +float screenSizeX = 1600.0; + +float screenSizeY = 900.0; + +//-------------------------Input Data------------------------- + +InputSystem* pInput; + +//-------------------------Assets------------------------- + +const std::string ASSET_PATH = "..\\Assets/"; + +const std::string BACKGROUND_IMAGE_FILE = "Background_Image.jpg"; + +//-------------------------Asset Identifiers------------------------- + +const std::string backgroundImageSprite = "background_image_image"; + +bool init() + +{ + + bool bSuccessfulInit = false; + + //Setup the graphical window + pGraphics = new GraphicsLibrary(screenSizeX, screenSizeY); + bSuccessfulInit = pGraphics->init(ASSET_PATH + BACKGROUND_IMAGE_FILE); + + //Add images to the graphcis library + pGraphics->loadImage(ASSET_PATH + BACKGROUND_IMAGE_FILE, backgroundImageSprite); + + pGraphics->drawImage(backgroundImageSprite, screenSizeX/2, screenSizeY/2); + + //Setup the input system + pInput = new InputSystem(); + if (bSuccessfulInit) + bSuccessfulInit = pInput->init(pGraphics); + + //Init and return if it succeeded or not + return bSuccessfulInit; +} + +int main() +{ + bool t = init(); + + std::cin.get(); + + return 0; +} \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/packages.config b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/packages.config new file mode 100644 index 00000000..f7916a63 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/gpr-430-assignment2/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/.signature.p7s b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/.signature.p7s new file mode 100644 index 00000000..b3748100 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/.signature.p7s differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/Allegro.5.1.12.4.nupkg b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/Allegro.5.1.12.4.nupkg new file mode 100644 index 00000000..a2136946 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/Allegro.5.1.12.4.nupkg differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/Allegro.targets b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/Allegro.targets new file mode 100644 index 00000000..03c82eb1 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/Allegro.targets @@ -0,0 +1,193 @@ + + + + $(MSBuildThisFileDirectory)lib\$(Platform)\v140\md\ + $(MSBuildThisFileDirectory)bin\$(Platform)\v140\md\ + + + $(MSBuildThisFileDirectory)lib\$(Platform)\v140\mt\ + $(MSBuildThisFileDirectory)bin\$(Platform)\v140\mt\ + + + + -static + + + -debug + + + + + $(AllegroLib)allegro$(AllegroSuffix).lib; + $(AllegroLib)allegro_main$(AllegroSuffix).lib + + + $(AllegroBin)allegro$(AllegroSuffix)-5.1.dll + + + + + + $(AllegroLib)allegro_monolith$(AllegroSuffix).lib; + opengl32.lib; + winmm.lib; + Shlwapi.lib; + psapi.lib + + + + + + $(AllegroLib)allegro_image$(AllegroSuffix).lib; + + + $(AllegroBin)allegro_image$(AllegroSuffix)-5.1.dll; + + + + + + $(AllegroLib)allegro_physfs$(AllegroSuffix).lib + + + $(AllegroBin)allegro_physfs$(AllegroSuffix)-5.1.dll + + + + + + $(AllegroLib)allegro_color$(AllegroSuffix).lib + + + $(AllegroBin)allegro_color$(AllegroSuffix)-5.1.dll + + + + + + $(AllegroLib)allegro_memfile$(AllegroSuffix).lib + + + $(AllegroBin)allegro_memfile$(AllegroSuffix)-5.1.dll + + + + + + $(AllegroLib)allegro_font$(AllegroSuffix).lib + + + $(AllegroBin)allegro_font$(AllegroSuffix)-5.1.dll + + + + + + $(AllegroLib)allegro_ttf$(AllegroSuffix).lib; + + + $(AllegroBin)allegro_ttf$(AllegroSuffix)-5.1.dll; + + + + + + $(AllegroLib)allegro_primitives$(AllegroSuffix).lib + + + $(AllegroBin)allegro_primitives$(AllegroSuffix)-5.1.dll + + + + + + $(AllegroLib)allegro_dialog$(AllegroSuffix).lib + + + $(AllegroBin)allegro_dialog$(AllegroSuffix)-5.1.dll + + + + + + $(AllegroLib)allegro_audio$(AllegroSuffix).lib + + + $(AllegroBin)allegro_audio$(AllegroSuffix)-5.1.dll + + + + + + $(AllegroLib)allegro_acodec$(AllegroSuffix).lib; + + + $(AllegroBin)allegro_acodec$(AllegroSuffix)-5.1.dll; + + + + + + + $(AllegroLib)allegro_video$(AllegroSuffix).lib + + + $(AllegroBin)allegro_video$(AllegroSuffix)-5.1.dll + + + + + + %(PreprocessorDefinitions);ALLEGRO_STATICLINK + + + + $(MSBuildThisFileDirectory)include\; + %(AdditionalIncludeDirectories) + + + + + + + + $(Allegro_CoreLibs); + $(Allegro_AddonImageLibs); + $(Allegro_AddonColorLibs); + $(Allegro_AddonMemfileLibs); + $(Allegro_AddonFontLibs); + $(Allegro_AddonTTFLibs); + $(Allegro_AddonPhysfsLibs); + $(Allegro_AddonDialogLibs); + $(Allegro_AddonAudioLibs); + $(Allegro_AddonAcodecLibs); + $(Allegro_AddonPrimitivesLibs); + $(Allegro_AddonVideoLibs); + %(AdditionalDependencies) + + + + + + + + + + + $(Allegro_CoreDLLs); + $(Allegro_AddonImageDLLs); + $(Allegro_AddonColorDLLs); + $(Allegro_AddonMemfileDLLs); + $(Allegro_AddonFontDLLs); + $(Allegro_AddonTTFDLLs); + $(Allegro_AddonPhysfsDLLs); + $(Allegro_AddonDialogDLLs); + $(Allegro_AddonAudioDLLs); + $(Allegro_AddonAcodecDLLs); + $(Allegro_AddonPrimitivesDLLs); + $(Allegro_AddonVideoDLLs); + + + + + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/AllegroDeps.targets b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/AllegroDeps.targets new file mode 100644 index 00000000..e753e95b --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/AllegroDeps.targets @@ -0,0 +1,63 @@ + + + + $(MSBuildThisFileDirectory)lib\$(Platform)\v140\mt\ + + + + + $(AllegroLib)jpeg.lib; + $(AllegroLib)libpng16.lib; + $(AllegroLib)zlib.lib + + + + + + $(AllegroLib)freetype.lib + + + + + + $(AllegroLib)dumb.lib; + $(AllegroLib)FLAC.lib; + $(AllegroLib)vorbis.lib; + $(AllegroLib)vorbisfile.lib; + $(AllegroLib)ogg.lib + + + + + + $(AllegroLib)physfs.lib + + + + + + $(AllegroLib)theoradec.lib + + + + + + + $(MSBuildThisFileDirectory)\include\; + %(AdditionalIncludeDirectories) + + + + + + + $(Allegro_AddonImageDeps); + $(Allegro_AddonTTFDeps); + $(Allegro_AddonAcodecDeps); + $(Allegro_AddonPhysfsDeps); + $(Allegro_AddonVideoDeps); + %(AdditionalDependencies) + + + + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/AllegroUI.xml b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/AllegroUI.xml new file mode 100644 index 00000000..4e1ed382 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/AllegroUI.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro-debug-5.1.dll new file mode 100644 index 00000000..b5f5ce7e Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_acodec-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_acodec-debug-5.1.dll new file mode 100644 index 00000000..8c944564 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_acodec-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_audio-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_audio-debug-5.1.dll new file mode 100644 index 00000000..974c7956 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_audio-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_color-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_color-debug-5.1.dll new file mode 100644 index 00000000..60e8482e Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_color-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_dialog-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_dialog-debug-5.1.dll new file mode 100644 index 00000000..16dd7694 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_dialog-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_font-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_font-debug-5.1.dll new file mode 100644 index 00000000..c42071ea Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_font-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_image-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_image-debug-5.1.dll new file mode 100644 index 00000000..ff70a1d6 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_image-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_main-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_main-debug-5.1.dll new file mode 100644 index 00000000..79f6979b Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_main-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_memfile-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_memfile-debug-5.1.dll new file mode 100644 index 00000000..364023d9 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_memfile-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_physfs-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_physfs-debug-5.1.dll new file mode 100644 index 00000000..3f7b2bd5 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_physfs-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_primitives-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_primitives-debug-5.1.dll new file mode 100644 index 00000000..1d3100cb Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_primitives-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_ttf-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_ttf-debug-5.1.dll new file mode 100644 index 00000000..928ed6f0 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_ttf-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_video-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_video-debug-5.1.dll new file mode 100644 index 00000000..9a544c16 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/md/allegro_video-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro-5.1.dll new file mode 100644 index 00000000..e9d1cc24 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_acodec-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_acodec-5.1.dll new file mode 100644 index 00000000..df354f2e Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_acodec-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_audio-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_audio-5.1.dll new file mode 100644 index 00000000..37b42051 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_audio-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_color-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_color-5.1.dll new file mode 100644 index 00000000..aa8e4a02 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_color-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_dialog-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_dialog-5.1.dll new file mode 100644 index 00000000..44e8c282 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_dialog-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_font-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_font-5.1.dll new file mode 100644 index 00000000..e4f6b2e1 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_font-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_image-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_image-5.1.dll new file mode 100644 index 00000000..f7db96e7 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_image-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_main-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_main-5.1.dll new file mode 100644 index 00000000..9de2b735 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_main-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_memfile-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_memfile-5.1.dll new file mode 100644 index 00000000..db0516bd Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_memfile-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_physfs-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_physfs-5.1.dll new file mode 100644 index 00000000..1eefa689 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_physfs-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_primitives-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_primitives-5.1.dll new file mode 100644 index 00000000..67873eba Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_primitives-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_ttf-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_ttf-5.1.dll new file mode 100644 index 00000000..b5223886 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_ttf-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_video-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_video-5.1.dll new file mode 100644 index 00000000..c2772e78 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/win32/v140/mt/allegro_video-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro-debug-5.1.dll new file mode 100644 index 00000000..c8a21253 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_acodec-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_acodec-debug-5.1.dll new file mode 100644 index 00000000..7b4289fa Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_acodec-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_audio-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_audio-debug-5.1.dll new file mode 100644 index 00000000..1635369f Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_audio-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_color-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_color-debug-5.1.dll new file mode 100644 index 00000000..fe1e936b Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_color-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_dialog-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_dialog-debug-5.1.dll new file mode 100644 index 00000000..e2f4d17e Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_dialog-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_font-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_font-debug-5.1.dll new file mode 100644 index 00000000..083eee48 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_font-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_image-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_image-debug-5.1.dll new file mode 100644 index 00000000..daca5243 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_image-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_main-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_main-debug-5.1.dll new file mode 100644 index 00000000..db2c70c1 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_main-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_memfile-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_memfile-debug-5.1.dll new file mode 100644 index 00000000..db5d1620 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_memfile-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_physfs-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_physfs-debug-5.1.dll new file mode 100644 index 00000000..2152c88f Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_physfs-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_primitives-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_primitives-debug-5.1.dll new file mode 100644 index 00000000..f22ea87d Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_primitives-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_ttf-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_ttf-debug-5.1.dll new file mode 100644 index 00000000..885e3bc9 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_ttf-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_video-debug-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_video-debug-5.1.dll new file mode 100644 index 00000000..c8f6fed0 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/md/allegro_video-debug-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro-5.1.dll new file mode 100644 index 00000000..3c8ced1e Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_acodec-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_acodec-5.1.dll new file mode 100644 index 00000000..0f638597 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_acodec-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_audio-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_audio-5.1.dll new file mode 100644 index 00000000..353ab653 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_audio-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_color-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_color-5.1.dll new file mode 100644 index 00000000..e27819c3 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_color-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_dialog-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_dialog-5.1.dll new file mode 100644 index 00000000..0f3912f4 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_dialog-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_font-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_font-5.1.dll new file mode 100644 index 00000000..8585d85a Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_font-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_image-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_image-5.1.dll new file mode 100644 index 00000000..3cf23eb2 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_image-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_main-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_main-5.1.dll new file mode 100644 index 00000000..9499aafc Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_main-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_memfile-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_memfile-5.1.dll new file mode 100644 index 00000000..c67c5160 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_memfile-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_physfs-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_physfs-5.1.dll new file mode 100644 index 00000000..bb621cd6 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_physfs-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_primitives-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_primitives-5.1.dll new file mode 100644 index 00000000..3613c526 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_primitives-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_ttf-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_ttf-5.1.dll new file mode 100644 index 00000000..80a49f70 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_ttf-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_video-5.1.dll b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_video-5.1.dll new file mode 100644 index 00000000..c877ebd1 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/bin/x64/v140/mt/allegro_video-5.1.dll differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/alcompat.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/alcompat.h new file mode 100644 index 00000000..8b79d7f6 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/alcompat.h @@ -0,0 +1,23 @@ +#ifndef __al_included_allegro5_alcompat_h +#define __al_included_allegro5_alcompat_h + +#ifdef __cplusplus + extern "C" { +#endif + + +#define ALLEGRO_DST_COLOR (ALLEGRO_DEST_COLOR) +#define ALLEGRO_INVERSE_DST_COLOR (ALLEGRO_INVERSE_DEST_COLOR) + +#define al_current_time() (al_get_time()) +#define al_event_queue_is_empty(q) (al_is_event_queue_empty(q)) +#define al_toggle_display_flag(d, f, o) (al_set_display_flag((d), (f), (o))) + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro.h new file mode 100644 index 00000000..06d40987 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro.h @@ -0,0 +1,79 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Main header file for the entire Allegro library. + * (separate modules can be included from the allegro/ directory) + * + * By Shawn Hargreaves. + * + * Vincent Penquerc'h split the original allegro.h into separate headers. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_allegro_h +#define __al_included_allegro5_allegro_h + + +#include "allegro5/base.h" + +#include "allegro5/altime.h" +#include "allegro5/bitmap.h" +#include "allegro5/bitmap_draw.h" +#include "allegro5/bitmap_io.h" +#include "allegro5/bitmap_lock.h" +#include "allegro5/blender.h" +#include "allegro5/clipboard.h" +#include "allegro5/color.h" +#include "allegro5/config.h" +#include "allegro5/cpu.h" +#include "allegro5/debug.h" +#include "allegro5/display.h" +#include "allegro5/drawing.h" +#include "allegro5/error.h" +#include "allegro5/events.h" +#include "allegro5/file.h" +#include "allegro5/fixed.h" +#include "allegro5/fmaths.h" +#include "allegro5/fshook.h" +#include "allegro5/fullscreen_mode.h" +#include "allegro5/haptic.h" +#include "allegro5/joystick.h" +#include "allegro5/keyboard.h" +#include "allegro5/memory.h" +#include "allegro5/monitor.h" +#include "allegro5/mouse.h" +#include "allegro5/mouse_cursor.h" +#include "allegro5/path.h" +#include "allegro5/render_state.h" +#include "allegro5/shader.h" +#include "allegro5/system.h" +#include "allegro5/threads.h" +#include "allegro5/timer.h" +#include "allegro5/tls.h" +#include "allegro5/touch_input.h" +#include "allegro5/transformations.h" +#include "allegro5/utf8.h" + + +#ifndef ALLEGRO_NO_COMPATIBILITY + #include "allegro5/alcompat.h" +#endif + + +#ifdef ALLEGRO_EXTRA_HEADER + #include ALLEGRO_EXTRA_HEADER +#endif + + +#endif + + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro5.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro5.h new file mode 100644 index 00000000..8e604c69 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro5.h @@ -0,0 +1,2 @@ +#include "allegro.h" + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_acodec.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_acodec.h new file mode 100644 index 00000000..a107ad61 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_acodec.h @@ -0,0 +1,40 @@ +#ifndef __al_included_allegro5_allegro_acodec_h +#define __al_included_allegro5_allegro_acodec_h + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_ACODEC_SRC + #define _ALLEGRO_ACODEC_DLL __declspec(dllexport) + #else + #define _ALLEGRO_ACODEC_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_ACODEC_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_ACODEC_FUNC(type, name, args) _ALLEGRO_ACODEC_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_ACODEC_FUNC(type, name, args) extern type name args +#else + #define ALLEGRO_ACODEC_FUNC AL_FUNC +#endif + + +ALLEGRO_ACODEC_FUNC(bool, al_init_acodec_addon, (void)); +ALLEGRO_ACODEC_FUNC(uint32_t, al_get_allegro_acodec_version, (void)); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_audio.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_audio.h new file mode 100644 index 00000000..99e20716 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_audio.h @@ -0,0 +1,403 @@ +/* + * Updated for 4.9 api inclusion by Ryan Dickie + * Originally done by KC/Milan + */ + +#ifndef __al_included_allegro5_allegro_audio_h +#define __al_included_allegro5_allegro_audio_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* Title: Audio types + */ + +#include "allegro5/allegro.h" + + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_KCM_AUDIO_SRC + #define _ALLEGRO_KCM_AUDIO_DLL __declspec(dllexport) + #else + #define _ALLEGRO_KCM_AUDIO_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_KCM_AUDIO_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) _ALLEGRO_KCM_AUDIO_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) extern _ALLEGRO_KCM_AUDIO_DLL type name args +#else + #define ALLEGRO_KCM_AUDIO_FUNC AL_FUNC +#endif + + +/* Internal, used to communicate with acodec. */ +/* Must be in 512 <= n < 1024 */ +#define _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE (512) + +/* User event type emitted when a stream fragment is ready to be + * refilled with more audio data. + * Must be in 512 <= n < 1024 + * + */ +#define ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT (513) +#define ALLEGRO_EVENT_AUDIO_STREAM_FINISHED (514) + +#define ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT (515) + +typedef struct ALLEGRO_AUDIO_RECORDER_EVENT ALLEGRO_AUDIO_RECORDER_EVENT; +struct ALLEGRO_AUDIO_RECORDER_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_AUDIO_RECORDER) + struct ALLEGRO_USER_EVENT_DESCRIPTOR *__internal__descr; + void *buffer; + unsigned int samples; +}; + + +/* Enum: ALLEGRO_AUDIO_DEPTH + */ +enum ALLEGRO_AUDIO_DEPTH +{ + /* Sample depth and type, and signedness. Mixers only use 32-bit signed + * float (-1..+1). The unsigned value is a bit-flag applied to the depth + * value. + */ + ALLEGRO_AUDIO_DEPTH_INT8 = 0x00, + ALLEGRO_AUDIO_DEPTH_INT16 = 0x01, + ALLEGRO_AUDIO_DEPTH_INT24 = 0x02, + ALLEGRO_AUDIO_DEPTH_FLOAT32 = 0x03, + + ALLEGRO_AUDIO_DEPTH_UNSIGNED = 0x08, + + /* For convenience */ + ALLEGRO_AUDIO_DEPTH_UINT8 = ALLEGRO_AUDIO_DEPTH_INT8 | + ALLEGRO_AUDIO_DEPTH_UNSIGNED, + ALLEGRO_AUDIO_DEPTH_UINT16 = ALLEGRO_AUDIO_DEPTH_INT16 | + ALLEGRO_AUDIO_DEPTH_UNSIGNED, + ALLEGRO_AUDIO_DEPTH_UINT24 = ALLEGRO_AUDIO_DEPTH_INT24 | + ALLEGRO_AUDIO_DEPTH_UNSIGNED +}; + + +/* Enum: ALLEGRO_CHANNEL_CONF + */ +enum ALLEGRO_CHANNEL_CONF +{ + /* Speaker configuration (mono, stereo, 2.1, 3, etc). With regards to + * behavior, most of this code makes no distinction between, say, 4.1 and + * 5 speaker setups.. they both have 5 "channels". However, users would + * like the distinction, and later when the higher-level stuff is added, + * the differences will become more important. (v>>4)+(v&0xF) should yield + * the total channel count. + */ + ALLEGRO_CHANNEL_CONF_1 = 0x10, + ALLEGRO_CHANNEL_CONF_2 = 0x20, + ALLEGRO_CHANNEL_CONF_3 = 0x30, + ALLEGRO_CHANNEL_CONF_4 = 0x40, + ALLEGRO_CHANNEL_CONF_5_1 = 0x51, + ALLEGRO_CHANNEL_CONF_6_1 = 0x61, + ALLEGRO_CHANNEL_CONF_7_1 = 0x71 +#define ALLEGRO_MAX_CHANNELS 8 +}; + + +/* Enum: ALLEGRO_PLAYMODE + */ +enum ALLEGRO_PLAYMODE +{ + ALLEGRO_PLAYMODE_ONCE = 0x100, + ALLEGRO_PLAYMODE_LOOP = 0x101, + ALLEGRO_PLAYMODE_BIDIR = 0x102, + _ALLEGRO_PLAYMODE_STREAM_ONCE = 0x103, /* internal */ + _ALLEGRO_PLAYMODE_STREAM_ONEDIR = 0x104 /* internal */ +}; + + +/* Enum: ALLEGRO_MIXER_QUALITY + */ +enum ALLEGRO_MIXER_QUALITY +{ + ALLEGRO_MIXER_QUALITY_POINT = 0x110, + ALLEGRO_MIXER_QUALITY_LINEAR = 0x111, + ALLEGRO_MIXER_QUALITY_CUBIC = 0x112 +}; + + +/* Enum: ALLEGRO_AUDIO_PAN_NONE + */ +#define ALLEGRO_AUDIO_PAN_NONE (-1000.0f) + +/* Type: ALLEGRO_SAMPLE + */ +typedef struct ALLEGRO_SAMPLE ALLEGRO_SAMPLE; + + +/* Type: ALLEGRO_SAMPLE_ID + */ +typedef struct ALLEGRO_SAMPLE_ID ALLEGRO_SAMPLE_ID; + +struct ALLEGRO_SAMPLE_ID { + int _index; + int _id; +}; + + +/* Type: ALLEGRO_SAMPLE_INSTANCE + */ +typedef struct ALLEGRO_SAMPLE_INSTANCE ALLEGRO_SAMPLE_INSTANCE; + + +/* Type: ALLEGRO_AUDIO_STREAM + */ +typedef struct ALLEGRO_AUDIO_STREAM ALLEGRO_AUDIO_STREAM; + + +/* Type: ALLEGRO_MIXER + */ +typedef struct ALLEGRO_MIXER ALLEGRO_MIXER; + + +/* Type: ALLEGRO_VOICE + */ +typedef struct ALLEGRO_VOICE ALLEGRO_VOICE; + + +/* Type: ALLEGRO_AUDIO_RECORDER + */ +typedef struct ALLEGRO_AUDIO_RECORDER ALLEGRO_AUDIO_RECORDER; + + +#ifndef __cplusplus +typedef enum ALLEGRO_AUDIO_DEPTH ALLEGRO_AUDIO_DEPTH; +typedef enum ALLEGRO_CHANNEL_CONF ALLEGRO_CHANNEL_CONF; +typedef enum ALLEGRO_PLAYMODE ALLEGRO_PLAYMODE; +typedef enum ALLEGRO_MIXER_QUALITY ALLEGRO_MIXER_QUALITY; +#endif + + +/* Sample functions */ + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_create_sample, (void *buf, + unsigned int samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, + ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_sample, (ALLEGRO_SAMPLE *spl)); + + +/* Sample instance functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE_INSTANCE*, al_create_sample_instance, ( + ALLEGRO_SAMPLE *data)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_sample_instance, ( + ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_frequency, (const ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_length, (const ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_sample_depth, (const ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_sample_channels, (const ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(void *, al_get_sample_data, (const ALLEGRO_SAMPLE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_frequency, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_length, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_position, (const ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_speed, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_gain, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_pan, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_time, (const ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_sample_instance_depth, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_sample_instance_channels, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_PLAYMODE, al_get_sample_instance_playmode, (const ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_sample_instance_playing, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_sample_instance_attached, (const ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_position, (ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_length, (ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_speed, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_gain, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_pan, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_playmode, (ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_PLAYMODE val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_playing, (ALLEGRO_SAMPLE_INSTANCE *spl, bool val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample, (ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_get_sample, (ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_play_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_stop_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); + + +/* Stream functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM*, al_create_audio_stream, (size_t buffer_count, + unsigned int samples, unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_drain_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_frequency, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_length, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_fragments, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_available_audio_stream_fragments, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_speed, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_gain, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_pan, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_audio_stream_channels, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_audio_stream_depth, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_PLAYMODE, al_get_audio_stream_playmode, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_audio_stream_playing, (const ALLEGRO_AUDIO_STREAM *spl)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_audio_stream_attached, (const ALLEGRO_AUDIO_STREAM *spl)); +ALLEGRO_KCM_AUDIO_FUNC(uint64_t, al_get_audio_stream_played_samples, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(void *, al_get_audio_stream_fragment, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_speed, (ALLEGRO_AUDIO_STREAM *stream, float val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_gain, (ALLEGRO_AUDIO_STREAM *stream, float val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_pan, (ALLEGRO_AUDIO_STREAM *stream, float val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_playmode, (ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_PLAYMODE val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_playing, (ALLEGRO_AUDIO_STREAM *stream, bool val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_fragment, (ALLEGRO_AUDIO_STREAM *stream, void *val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_rewind_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_seek_audio_stream_secs, (ALLEGRO_AUDIO_STREAM *stream, double time)); +ALLEGRO_KCM_AUDIO_FUNC(double, al_get_audio_stream_position_secs, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(double, al_get_audio_stream_length_secs, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_loop_secs, (ALLEGRO_AUDIO_STREAM *stream, double start, double end)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_audio_stream_event_source, (ALLEGRO_AUDIO_STREAM *stream)); + +/* Mixer functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER*, al_create_mixer, (unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_mixer, (ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_sample_instance_to_mixer, ( + ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_audio_stream_to_mixer, (ALLEGRO_AUDIO_STREAM *stream, + ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_mixer_to_mixer, (ALLEGRO_MIXER *stream, + ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_postprocess_callback, ( + ALLEGRO_MIXER *mixer, + void (*cb)(void *buf, unsigned int samples, void *data), + void *data)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_mixer_frequency, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_mixer_channels, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_mixer_depth, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER_QUALITY, al_get_mixer_quality, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_mixer_gain, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_mixer_playing, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_mixer_attached, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_frequency, (ALLEGRO_MIXER *mixer, unsigned int val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_quality, (ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_gain, (ALLEGRO_MIXER *mixer, float gain)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_playing, (ALLEGRO_MIXER *mixer, bool val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_mixer, (ALLEGRO_MIXER *mixer)); + +/* Voice functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_VOICE*, al_create_voice, (unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, + ALLEGRO_CHANNEL_CONF chan_conf)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_voice, (ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_sample_instance_to_voice, ( + ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_audio_stream_to_voice, ( + ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_VOICE *voice )); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_mixer_to_voice, (ALLEGRO_MIXER *mixer, + ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_detach_voice, (ALLEGRO_VOICE *voice)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_voice_frequency, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_voice_position, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_voice_channels, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_voice_depth, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_voice_playing, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_voice_position, (ALLEGRO_VOICE *voice, unsigned int val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_voice_playing, (ALLEGRO_VOICE *voice, bool val)); + +/* Misc. audio functions */ +ALLEGRO_KCM_AUDIO_FUNC(bool, al_install_audio, (void)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_uninstall_audio, (void)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_is_audio_installed, (void)); +ALLEGRO_KCM_AUDIO_FUNC(uint32_t, al_get_allegro_audio_version, (void)); + +ALLEGRO_KCM_AUDIO_FUNC(size_t, al_get_channel_count, (ALLEGRO_CHANNEL_CONF conf)); +ALLEGRO_KCM_AUDIO_FUNC(size_t, al_get_audio_depth_size, (ALLEGRO_AUDIO_DEPTH conf)); + +ALLEGRO_KCM_AUDIO_FUNC(void, al_fill_silence, (void *buf, unsigned int samples, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); + +/* Simple audio layer */ +ALLEGRO_KCM_AUDIO_FUNC(bool, al_reserve_samples, (int reserve_samples)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER *, al_get_default_mixer, (void)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_default_mixer, (ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_restore_default_mixer, (void)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_play_sample, (ALLEGRO_SAMPLE *data, + float gain, float pan, float speed, ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_stop_sample, (ALLEGRO_SAMPLE_ID *spl_id)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_stop_samples, (void)); + +/* File type handlers */ +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_loader, (const char *ext, + ALLEGRO_SAMPLE *(*loader)(const char *filename))); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_saver, (const char *ext, + bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl))); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_audio_stream_loader, (const char *ext, + ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename, + size_t buffer_count, unsigned int samples))); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_loader_f, (const char *ext, + ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE *fp))); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_saver_f, (const char *ext, + bool (*saver)(ALLEGRO_FILE *fp, ALLEGRO_SAMPLE *spl))); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_audio_stream_loader_f, (const char *ext, + ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE *fp, + size_t buffer_count, unsigned int samples))); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_load_sample, (const char *filename)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_save_sample, (const char *filename, + ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM *, al_load_audio_stream, (const char *filename, + size_t buffer_count, unsigned int samples)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_load_sample_f, (ALLEGRO_FILE* fp, const char *ident)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_save_sample_f, (ALLEGRO_FILE* fp, const char *ident, + ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM *, al_load_audio_stream_f, (ALLEGRO_FILE* fp, const char *ident, + size_t buffer_count, unsigned int samples)); + +/* Recording functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_RECORDER *, al_create_audio_recorder, (size_t fragment_count, + unsigned int samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_start_audio_recorder, (ALLEGRO_AUDIO_RECORDER *r)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_stop_audio_recorder, (ALLEGRO_AUDIO_RECORDER *r)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_is_audio_recorder_recording, (ALLEGRO_AUDIO_RECORDER *r)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_audio_recorder_event_source, + (ALLEGRO_AUDIO_RECORDER *r)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_RECORDER_EVENT *, al_get_audio_recorder_event, (ALLEGRO_EVENT *event)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_audio_recorder, (ALLEGRO_AUDIO_RECORDER *r)); + +#ifdef __cplusplus +} /* End extern "C" */ +#endif + +#endif + + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_color.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_color.h new file mode 100644 index 00000000..865fe65a --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_color.h @@ -0,0 +1,68 @@ +#ifndef __al_included_allegro5_allegro_color_h +#define __al_included_allegro5_allegro_color_h + +#include "allegro5/allegro.h" + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_COLOR_SRC + #define _ALLEGRO_COLOR_DLL __declspec(dllexport) + #else + #define _ALLEGRO_COLOR_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_COLOR_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_COLOR_FUNC(type, name, args) _ALLEGRO_COLOR_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_COLOR_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_COLOR_FUNC(type, name, args) extern _ALLEGRO_COLOR_DLL type name args +#else + #define ALLEGRO_COLOR_FUNC AL_FUNC +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +ALLEGRO_COLOR_FUNC(uint32_t, al_get_allegro_color_version, (void)); + +ALLEGRO_COLOR_FUNC(void, al_color_hsv_to_rgb, (float hue, float saturation, + float value, float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_hsl, (float red, float green, float blue, + float *hue, float *saturation, float *lightness)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_hsv, (float red, float green, float blue, + float *hue, float *saturation, float *value)); +ALLEGRO_COLOR_FUNC(void, al_color_hsl_to_rgb, (float hue, float saturation, float lightness, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(bool, al_color_name_to_rgb, (char const *name, float *r, float *g, + float *b)); +ALLEGRO_COLOR_FUNC(const char*, al_color_rgb_to_name, (float r, float g, float b)); +ALLEGRO_COLOR_FUNC(void, al_color_cmyk_to_rgb, (float cyan, float magenta, float yellow, + float key, float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_cmyk, (float red, float green, float blue, + float *cyan, float *magenta, float *yellow, float *key)); +ALLEGRO_COLOR_FUNC(void, al_color_yuv_to_rgb, (float y, float u, float v, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_yuv, (float red, float green, float blue, + float *y, float *u, float *v)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_html, (float red, float green, float blue, + char *string)); +ALLEGRO_COLOR_FUNC(bool, al_color_html_to_rgb, (char const *string, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_yuv, (float y, float u, float v)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_cmyk, (float c, float m, float y, float k)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_hsl, (float h, float s, float l)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_hsv, (float h, float s, float v)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_name, (char const *name)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_html, (char const *string)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_direct3d.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_direct3d.h new file mode 100644 index 00000000..7a21bc71 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_direct3d.h @@ -0,0 +1,54 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Header file for Direct3D specific API. + * + * By Milan Mimica. + * + */ + +#ifndef __al_included_allegro5_allegro_direct3d_h +#define __al_included_allegro5_allegro_direct3d_h + +#include +#if defined ALLEGRO_CFG_SHADER_HLSL && defined __cplusplus +#include +#endif +#include "allegro5/platform/alplatf.h" + +/* Display creation flag. */ +#define ALLEGRO_DIRECT3D ALLEGRO_DIRECT3D_INTERNAL + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Public Direct3D-related API + */ + +AL_FUNC(LPDIRECT3DDEVICE9, al_get_d3d_device, (ALLEGRO_DISPLAY *)); +AL_FUNC(LPDIRECT3DTEXTURE9, al_get_d3d_system_texture, (ALLEGRO_BITMAP *)); +AL_FUNC(LPDIRECT3DTEXTURE9, al_get_d3d_video_texture, (ALLEGRO_BITMAP *)); +AL_FUNC(bool, al_have_d3d_non_pow2_texture_support, (void)); +AL_FUNC(bool, al_have_d3d_non_square_texture_support, (void)); +AL_FUNC(void, al_get_d3d_texture_position, (ALLEGRO_BITMAP *bitmap, int *u, int *v)); +AL_FUNC(bool, al_get_d3d_texture_size, (ALLEGRO_BITMAP *bitmap, int *width, int *height)); +AL_FUNC(bool, al_is_d3d_device_lost, (ALLEGRO_DISPLAY *display)); +AL_FUNC(void, al_set_d3d_device_release_callback, (void (*callback)(ALLEGRO_DISPLAY *display))); +AL_FUNC(void, al_set_d3d_device_restore_callback, (void (*callback)(ALLEGRO_DISPLAY *display))); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_font.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_font.h new file mode 100644 index 00000000..c32115ed --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_font.h @@ -0,0 +1,155 @@ +#ifndef __al_included_allegro5_allegro_font_h +#define __al_included_allegro5_allegro_font_h + +#include "allegro5/allegro.h" + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_FONT_SRC + #define _ALLEGRO_FONT_DLL __declspec(dllexport) + #else + #define _ALLEGRO_FONT_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_FONT_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_FONT_FUNC(type, name, args) _ALLEGRO_FONT_DLL type __cdecl name args + #define ALLEGRO_FONT_METHOD(type, name, args) type (__cdecl *name) args + #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (__cdecl *name) args + #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_FONT_FUNC(type, name, args) extern type name args + #define ALLEGRO_FONT_METHOD(type, name, args) type (*name) args + #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (*name) args + #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) __attribute__ ((format (printf, a, b))) +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_FONT_FUNC(type, name, args) extern _ALLEGRO_FONT_DLL type name args + #define ALLEGRO_FONT_METHOD(type, name, args) type (*name) args + #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (*name) args + #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) +#else + #define ALLEGRO_FONT_FUNC AL_FUNC + #define ALLEGRO_FONT_METHOD AL_METHOD + #define ALLEGRO_FONT_FUNCPTR AL_FUNCPTR + #define ALLEGRO_FONT_PRINTFUNC AL_PRINTFUNC +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_FONT +*/ +typedef struct ALLEGRO_FONT ALLEGRO_FONT; +typedef struct ALLEGRO_FONT_VTABLE ALLEGRO_FONT_VTABLE; + +struct ALLEGRO_FONT +{ + void *data; + int height; + ALLEGRO_FONT *fallback; + ALLEGRO_FONT_VTABLE *vtable; +}; + +/* text- and font-related stuff */ +struct ALLEGRO_FONT_VTABLE +{ + ALLEGRO_FONT_METHOD(int, font_height, (const ALLEGRO_FONT *f)); + ALLEGRO_FONT_METHOD(int, font_ascent, (const ALLEGRO_FONT *f)); + ALLEGRO_FONT_METHOD(int, font_descent, (const ALLEGRO_FONT *f)); + ALLEGRO_FONT_METHOD(int, char_length, (const ALLEGRO_FONT *f, int ch)); + ALLEGRO_FONT_METHOD(int, text_length, (const ALLEGRO_FONT *f, const ALLEGRO_USTR *text)); + ALLEGRO_FONT_METHOD(int, render_char, (const ALLEGRO_FONT *f, ALLEGRO_COLOR color, int ch, float x, float y)); + ALLEGRO_FONT_METHOD(int, render, (const ALLEGRO_FONT *f, ALLEGRO_COLOR color, const ALLEGRO_USTR *text, float x, float y)); + ALLEGRO_FONT_METHOD(void, destroy, (ALLEGRO_FONT *f)); + ALLEGRO_FONT_METHOD(void, get_text_dimensions, (const ALLEGRO_FONT *f, + const ALLEGRO_USTR *text, int *bbx, int *bby, int *bbw, int *bbh)); + ALLEGRO_FONT_METHOD(int, get_font_ranges, (ALLEGRO_FONT *font, + int ranges_count, int *ranges)); + + ALLEGRO_FONT_METHOD(bool, get_glyph_dimensions, (const ALLEGRO_FONT *f, + int codepoint, int *bbx, int *bby, int *bbw, int *bbh)); + ALLEGRO_FONT_METHOD(int, get_glyph_advance, (const ALLEGRO_FONT *font, + int codepoint1, int codepoint2)); + +}; + +enum { + ALLEGRO_NO_KERNING = -1, + ALLEGRO_ALIGN_LEFT = 0, + ALLEGRO_ALIGN_CENTRE = 1, + ALLEGRO_ALIGN_CENTER = 1, + ALLEGRO_ALIGN_RIGHT = 2, + ALLEGRO_ALIGN_INTEGER = 4, +}; + +ALLEGRO_FONT_FUNC(bool, al_register_font_loader, (const char *ext, ALLEGRO_FONT *(*load)(const char *filename, int size, int flags))); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_load_bitmap_font, (const char *filename)); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_load_bitmap_font_flags, (const char *filename, int flags)); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_load_font, (const char *filename, int size, int flags)); + +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_grab_font_from_bitmap, (ALLEGRO_BITMAP *bmp, int n, const int ranges[])); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_create_builtin_font, (void)); + +ALLEGRO_FONT_FUNC(void, al_draw_ustr, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, ALLEGRO_USTR const *ustr)); +ALLEGRO_FONT_FUNC(void, al_draw_text, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *text)); +ALLEGRO_FONT_FUNC(void, al_draw_justified_text, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, char const *text)); +ALLEGRO_FONT_FUNC(void, al_draw_justified_ustr, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, ALLEGRO_USTR const *text)); +ALLEGRO_FONT_PRINTFUNC(void, al_draw_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *format, ...), 6, 7); +ALLEGRO_FONT_PRINTFUNC(void, al_draw_justified_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, char const *format, ...), 8, 9); +ALLEGRO_FONT_FUNC(int, al_get_text_width, (const ALLEGRO_FONT *f, const char *str)); +ALLEGRO_FONT_FUNC(int, al_get_ustr_width, (const ALLEGRO_FONT *f, const ALLEGRO_USTR *ustr)); +ALLEGRO_FONT_FUNC(int, al_get_font_line_height, (const ALLEGRO_FONT *f)); +ALLEGRO_FONT_FUNC(int, al_get_font_ascent, (const ALLEGRO_FONT *f)); +ALLEGRO_FONT_FUNC(int, al_get_font_descent, (const ALLEGRO_FONT *f)); +ALLEGRO_FONT_FUNC(void, al_destroy_font, (ALLEGRO_FONT *f)); +ALLEGRO_FONT_FUNC(void, al_get_ustr_dimensions, (const ALLEGRO_FONT *f, + ALLEGRO_USTR const *text, + int *bbx, int *bby, int *bbw, int *bbh)); +ALLEGRO_FONT_FUNC(void, al_get_text_dimensions, (const ALLEGRO_FONT *f, + char const *text, + int *bbx, int *bby, int *bbw, int *bbh)); +ALLEGRO_FONT_FUNC(bool, al_init_font_addon, (void)); +ALLEGRO_FONT_FUNC(void, al_shutdown_font_addon, (void)); +ALLEGRO_FONT_FUNC(uint32_t, al_get_allegro_font_version, (void)); +ALLEGRO_FONT_FUNC(int, al_get_font_ranges, (ALLEGRO_FONT *font, + int ranges_count, int *ranges)); + +ALLEGRO_FONT_FUNC(void, al_draw_glyph, (const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, int codepoint)); +ALLEGRO_FONT_FUNC(int, al_get_glyph_width, (const ALLEGRO_FONT *f, + int codepoint)); +ALLEGRO_FONT_FUNC(bool, al_get_glyph_dimensions, (const ALLEGRO_FONT *f, + int codepoint, int *bbx, int *bby, int *bbw, int *bbh)); +ALLEGRO_FONT_FUNC(int, al_get_glyph_advance, (const ALLEGRO_FONT *f, + int codepoint1, int codepoint2)); + +ALLEGRO_FONT_FUNC(void, al_draw_multiline_text, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, int flags, const char *text)); +ALLEGRO_FONT_FUNC(void, al_draw_multiline_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, int flags, const char *format, ...)); +ALLEGRO_FONT_FUNC(void, al_draw_multiline_ustr, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, int flags, const ALLEGRO_USTR *text)); + +ALLEGRO_FONT_FUNC(void, al_do_multiline_text, (const ALLEGRO_FONT *font, + float max_width, const char *text, + bool (*cb)(int line_num, const char *line, int size, void *extra), + void *extra)); + +ALLEGRO_FONT_FUNC(void, al_do_multiline_ustr, (const ALLEGRO_FONT *font, + float max_width, const ALLEGRO_USTR *ustr, + bool (*cb)(int line_num, const ALLEGRO_USTR *line, void *extra), + void *extra)); + +ALLEGRO_FONT_FUNC(void, al_set_fallback_font, (ALLEGRO_FONT *font, + ALLEGRO_FONT *fallback)); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_get_fallback_font, ( + ALLEGRO_FONT *font)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_image.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_image.h new file mode 100644 index 00000000..868f3da2 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_image.h @@ -0,0 +1,42 @@ +#ifndef __al_included_allegro5_allegro_image_h +#define __al_included_allegro5_allegro_image_h + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_IIO_SRC + #define _ALLEGRO_IIO_DLL __declspec(dllexport) + #else + #define _ALLEGRO_IIO_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_IIO_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_IIO_FUNC(type, name, args) _ALLEGRO_IIO_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_IIO_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_IIO_FUNC(type, name, args) extern _ALLEGRO_IIO_DLL type name args +#else + #define ALLEGRO_IIO_FUNC AL_FUNC +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +ALLEGRO_IIO_FUNC(bool, al_init_image_addon, (void)); +ALLEGRO_IIO_FUNC(void, al_shutdown_image_addon, (void)); +ALLEGRO_IIO_FUNC(uint32_t, al_get_allegro_image_version, (void)); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_memfile.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_memfile.h new file mode 100644 index 00000000..5d8f6c48 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_memfile.h @@ -0,0 +1,40 @@ +#ifndef __al_included_allegro5_memfile_h +#define __al_included_allegro5_memfile_h + +#include "allegro5/allegro.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_MEMFILE_SRC + #define _ALLEGRO_MEMFILE_DLL __declspec(dllexport) + #else + #define _ALLEGRO_MEMFILE_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_MEMFILE_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_MEMFILE_FUNC(type, name, args) _ALLEGRO_MEMFILE_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_MEMFILE_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_MEMFILE_FUNC(type, name, args) extern _ALLEGRO_MEMFILE_DLL type name args +#else + #define ALLEGRO_MEMFILE_FUNC AL_FUNC +#endif + + +ALLEGRO_MEMFILE_FUNC(ALLEGRO_FILE *, al_open_memfile, (void *mem, int64_t size, const char *mode)); +ALLEGRO_MEMFILE_FUNC(uint32_t, al_get_allegro_memfile_version, (void)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_native_dialog.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_native_dialog.h new file mode 100644 index 00000000..3a1ba72d --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_native_dialog.h @@ -0,0 +1,160 @@ +#ifndef __al_included_allegro5_allegro_native_dialog_h +#define __al_included_allegro5_allegro_native_dialog_h + +#include "allegro5/allegro.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_NATIVE_DIALOG_SRC + #define _ALLEGRO_DIALOG_DLL __declspec(dllexport) + #else + #define _ALLEGRO_DIALOG_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_DIALOG_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_DIALOG_FUNC(type, name, args) _ALLEGRO_DIALOG_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_DIALOG_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_DIALOG_FUNC(type, name, args) extern _ALLEGRO_DIALOG_DLL type name args +#else + #define ALLEGRO_DIALOG_FUNC AL_FUNC +#endif + +#ifdef ALLEGRO_WITH_XWINDOWS + #define ALLEGRO_GTK_TOPLEVEL ALLEGRO_GTK_TOPLEVEL_INTERNAL +#endif + +/* Type: ALLEGRO_FILECHOOSER + */ +typedef struct ALLEGRO_FILECHOOSER ALLEGRO_FILECHOOSER; + +/* Type: ALLEGRO_TEXTLOG + */ +typedef struct ALLEGRO_TEXTLOG ALLEGRO_TEXTLOG; + +/* Type: ALLEGRO_MENU + */ +typedef struct ALLEGRO_MENU ALLEGRO_MENU; + +/* Type: ALLEGRO_MENU_INFO + */ +typedef struct ALLEGRO_MENU_INFO { + const char *caption; + uint16_t id; + int flags; + ALLEGRO_BITMAP *icon; +} ALLEGRO_MENU_INFO; + +#define ALLEGRO_MENU_SEPARATOR { NULL, -1, 0, NULL } +#define ALLEGRO_START_OF_MENU(caption, id) { caption "->", id, 0, NULL } +#define ALLEGRO_END_OF_MENU { NULL, 0, 0, NULL } + +ALLEGRO_DIALOG_FUNC(bool, al_init_native_dialog_addon, (void)); +ALLEGRO_DIALOG_FUNC(void, al_shutdown_native_dialog_addon, (void)); + +ALLEGRO_DIALOG_FUNC(ALLEGRO_FILECHOOSER *, al_create_native_file_dialog, (char const *initial_path, + char const *title, char const *patterns, int mode)); +ALLEGRO_DIALOG_FUNC(bool, al_show_native_file_dialog, (ALLEGRO_DISPLAY *display, ALLEGRO_FILECHOOSER *dialog)); +ALLEGRO_DIALOG_FUNC(int, al_get_native_file_dialog_count, (const ALLEGRO_FILECHOOSER *dialog)); +ALLEGRO_DIALOG_FUNC(const char *, al_get_native_file_dialog_path, (const ALLEGRO_FILECHOOSER *dialog, + size_t index)); +ALLEGRO_DIALOG_FUNC(void, al_destroy_native_file_dialog, (ALLEGRO_FILECHOOSER *dialog)); + +ALLEGRO_DIALOG_FUNC(int, al_show_native_message_box, (ALLEGRO_DISPLAY *display, char const *title, + char const *heading, char const *text, char const *buttons, int flags)); + +ALLEGRO_DIALOG_FUNC(ALLEGRO_TEXTLOG *, al_open_native_text_log, (char const *title, int flags)); +ALLEGRO_DIALOG_FUNC(void, al_close_native_text_log, (ALLEGRO_TEXTLOG *textlog)); +ALLEGRO_DIALOG_FUNC(void, al_append_native_text_log, (ALLEGRO_TEXTLOG *textlog, char const *format, ...)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_native_text_log_event_source, (ALLEGRO_TEXTLOG *textlog)); + +/* creating/modifying menus */ +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_create_menu, (void)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_create_popup_menu, (void)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_build_menu, (ALLEGRO_MENU_INFO *info)); +ALLEGRO_DIALOG_FUNC(int, al_append_menu_item, (ALLEGRO_MENU *parent, char const *title, uint16_t id, int flags, + ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu)); +ALLEGRO_DIALOG_FUNC(int, al_insert_menu_item, (ALLEGRO_MENU *parent, int pos, char const *title, uint16_t id, + int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu)); +ALLEGRO_DIALOG_FUNC(bool, al_remove_menu_item, (ALLEGRO_MENU *menu, int pos)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_clone_menu, (ALLEGRO_MENU *menu)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_clone_menu_for_popup, (ALLEGRO_MENU *menu)); +ALLEGRO_DIALOG_FUNC(void, al_destroy_menu, (ALLEGRO_MENU *menu)); + +/* properties */ +ALLEGRO_DIALOG_FUNC(const char *, al_get_menu_item_caption, (ALLEGRO_MENU *menu, int pos)); +ALLEGRO_DIALOG_FUNC(void, al_set_menu_item_caption, (ALLEGRO_MENU *menu, int pos, const char *caption)); +ALLEGRO_DIALOG_FUNC(int, al_get_menu_item_flags, (ALLEGRO_MENU *menu, int pos)); +ALLEGRO_DIALOG_FUNC(void, al_set_menu_item_flags, (ALLEGRO_MENU *menu, int pos, int flags)); +ALLEGRO_DIALOG_FUNC(int, al_toggle_menu_item_flags, (ALLEGRO_MENU *menu, int pos, int flags)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_BITMAP *, al_get_menu_item_icon, (ALLEGRO_MENU *menu, int pos)); +ALLEGRO_DIALOG_FUNC(void, al_set_menu_item_icon, (ALLEGRO_MENU *menu, int pos, ALLEGRO_BITMAP *icon)); + +/* querying menus */ +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_find_menu, (ALLEGRO_MENU *haystack, uint16_t id)); +ALLEGRO_DIALOG_FUNC(bool, al_find_menu_item, (ALLEGRO_MENU *haystack, uint16_t id, ALLEGRO_MENU **menu, int *index)); + +/* menu events */ +ALLEGRO_DIALOG_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_default_menu_event_source, (void)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_EVENT_SOURCE *, al_enable_menu_event_source, (ALLEGRO_MENU *menu)); +ALLEGRO_DIALOG_FUNC(void, al_disable_menu_event_source, (ALLEGRO_MENU *menu)); + +/* displaying menus */ +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_get_display_menu, (ALLEGRO_DISPLAY *display)); +ALLEGRO_DIALOG_FUNC(bool, al_set_display_menu, (ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu)); +ALLEGRO_DIALOG_FUNC(bool, al_popup_menu, (ALLEGRO_MENU *popup, ALLEGRO_DISPLAY *display)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_remove_display_menu, (ALLEGRO_DISPLAY *display)); + +ALLEGRO_DIALOG_FUNC(uint32_t, al_get_allegro_native_dialog_version, (void)); + +enum { + ALLEGRO_FILECHOOSER_FILE_MUST_EXIST = 1, + ALLEGRO_FILECHOOSER_SAVE = 2, + ALLEGRO_FILECHOOSER_FOLDER = 4, + ALLEGRO_FILECHOOSER_PICTURES = 8, + ALLEGRO_FILECHOOSER_SHOW_HIDDEN = 16, + ALLEGRO_FILECHOOSER_MULTIPLE = 32 +}; + +enum { + ALLEGRO_MESSAGEBOX_WARN = 1<<0, + ALLEGRO_MESSAGEBOX_ERROR = 1<<1, + ALLEGRO_MESSAGEBOX_OK_CANCEL = 1<<2, + ALLEGRO_MESSAGEBOX_YES_NO = 1<<3, + ALLEGRO_MESSAGEBOX_QUESTION = 1<<4 +}; + +enum { + ALLEGRO_TEXTLOG_NO_CLOSE = 1<<0, + ALLEGRO_TEXTLOG_MONOSPACE = 1<<1 +}; + +enum { + ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE = 600, + ALLEGRO_EVENT_MENU_CLICK = 601 +}; + +enum { + ALLEGRO_MENU_ITEM_ENABLED = 0, + ALLEGRO_MENU_ITEM_CHECKBOX = 1, + ALLEGRO_MENU_ITEM_CHECKED = 2, + ALLEGRO_MENU_ITEM_DISABLED = 4 +}; + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_opengl.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_opengl.h new file mode 100644 index 00000000..8930ba35 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_opengl.h @@ -0,0 +1,177 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Main header file for all OpenGL drivers. + * + * By Milan Mimica. + * + */ + + +#ifndef __al_included_allegro5_allegro_opengl_h +#define __al_included_allegro5_allegro_opengl_h + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(ALLEGRO_WINDOWS) +#include +#endif + +#if defined ALLEGRO_IPHONE + +#include +#include +#include +#include + +/* Apple defines OES versions for these - however the separated alpha ones + * don't seem to work on the device and just crash. + */ +#define glBlendEquation glBlendEquationOES +#define glBlendFuncSeparate glBlendFuncSeparateOES +#define glBlendEquationSeparate glBlendEquationSeparateOES +#ifdef GL_FUNC_ADD +#undef GL_FUNC_ADD +#undef GL_FUNC_SUBTRACT +#undef GL_FUNC_REVERSE_SUBTRACT +#endif +#define GL_FUNC_ADD GL_FUNC_ADD_OES +#define GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_OES +#define GL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT_OES + +#elif defined ALLEGRO_MACOSX + +#include +#include +#include + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +#elif defined ALLEGRO_ANDROID || defined ALLEGRO_RASPBERRYPI + +#include +#include + +#ifdef ALLEGRO_CFG_OPENGLES2 +#include +#include +#else +#define GL_FUNC_ADD GL_FUNC_ADD_OES +#define GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_OES +#define GL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT_OES +#endif + +#define GL_RGBA8 GL_RGBA8_OES + +#ifndef ALLEGRO_RASPBERRYPI +#define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_OES +#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES +#define glBlendEquation glBlendEquationOES +#define glBlendFuncSeparate glBlendFuncSeparateOES +#define glBlendEquationSeparate glBlendEquationSeparateOES +#define glGenerateMipmapEXT glGenerateMipmapOES +#define glBindFramebufferEXT glBindFramebufferOES +#define glDeleteFramebuffersEXT glDeleteFramebuffersOES +#else +#define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING +#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER +#define glBlendEquation glBlendEquation +#define glBlendFuncSeparate glBlendFuncSeparate +#define glBlendEquationSeparate glBlendEquationSeparate +#define glGenerateMipmapEXT glGenerateMipmap +#define glBindFramebufferEXT glBindFramebuffer +#define glDeleteFramebuffersEXT glDeleteFramebuffers +#endif + +#else /* ALLEGRO_MACOSX */ + +/* HACK: Prevent both Mesa and SGI's broken headers from screwing us */ +#define __glext_h_ +#define __glxext_h_ +#include +#undef __glext_h_ +#undef __glxext_h_ + +#endif /* ALLEGRO_MACOSX */ + +#ifdef ALLEGRO_RASPBERRYPI +#include +#include +#endif + +#include "allegro5/opengl/gl_ext.h" + +#ifdef ALLEGRO_WINDOWS + +/* Missing #defines from Mingw */ +#ifndef PFD_SWAP_LAYER_BUFFERS +#define PFD_SWAP_LAYER_BUFFERS 0x00000800 +#endif + +#ifndef PFD_GENERIC_ACCELERATED +#define PFD_GENERIC_ACCELERATED 0x00001000 +#endif + +#ifndef PFD_SUPPORT_DIRECTDRAW +#define PFD_SUPPORT_DIRECTDRAW 0x00002000 +#endif + +#ifndef CDS_FULLSCREEN +#define CDS_FULLSCREEN 0x00000004 +#endif + +#ifndef ENUM_CURRENT_SETTINGS +#define ENUM_CURRENT_SETTINGS ((DWORD)-1) +#endif + +#endif /* ALLEGRO_WINDOWS */ + +#if defined ALLEGRO_WINDOWS + #define ALLEGRO_DEFINE_PROC_TYPE(type, name, args) \ + typedef type (APIENTRY * name) args; +#else + #define ALLEGRO_DEFINE_PROC_TYPE(type, name, args) \ + typedef type (*name) args; +#endif + +/* + * Public OpenGL-related API + */ + +/* Enum: ALLEGRO_OPENGL_VARIANT + */ +typedef enum ALLEGRO_OPENGL_VARIANT { + ALLEGRO_DESKTOP_OPENGL = 0, + ALLEGRO_OPENGL_ES +} ALLEGRO_OPENGL_VARIANT; + +AL_FUNC(uint32_t, al_get_opengl_version, (void)); +AL_FUNC(bool, al_have_opengl_extension, (const char *extension)); +AL_FUNC(void*, al_get_opengl_proc_address, (const char *name)); +AL_FUNC(ALLEGRO_OGL_EXT_LIST*, al_get_opengl_extension_list, (void)); +AL_FUNC(GLuint, al_get_opengl_texture, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_remove_opengl_fbo, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(GLuint, al_get_opengl_fbo, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(bool, al_get_opengl_texture_size, (ALLEGRO_BITMAP *bitmap, + int *w, int *h)); +AL_FUNC(void, al_get_opengl_texture_position, (ALLEGRO_BITMAP *bitmap, + int *u, int *v)); +AL_FUNC(void, al_set_current_opengl_context, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_opengl_variant, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_physfs.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_physfs.h new file mode 100644 index 00000000..494da6a4 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_physfs.h @@ -0,0 +1,41 @@ +#ifndef __al_included_allegro5_allegro_physfs_h +#define __al_included_allegro5_allegro_physfs_h + +#include "allegro5/allegro.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_PHYSFS_SRC + #define _ALLEGRO_PHYSFS_DLL __declspec(dllexport) + #else + #define _ALLEGRO_PHYSFS_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_PHYSFS_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_PHYSFS_FUNC(type, name, args) _ALLEGRO_PHYSFS_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_PHYSFS_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_PHYSFS_FUNC(type, name, args) extern _ALLEGRO_PHYSFS_DLL type name args +#else + #define ALLEGRO_PHYSFS_FUNC AL_FUNC +#endif + + +ALLEGRO_PHYSFS_FUNC(void, al_set_physfs_file_interface, (void)); +ALLEGRO_PHYSFS_FUNC(uint32_t, al_get_allegro_physfs_version, (void)); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_primitives.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_primitives.h new file mode 100644 index 00000000..fe31440c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_primitives.h @@ -0,0 +1,253 @@ +#ifndef __al_included_allegro5_allegro_primitives_h +#define __al_included_allegro5_allegro_primitives_h + +#include + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) +#ifndef ALLEGRO_STATICLINK +#ifdef ALLEGRO_PRIMITIVES_SRC +#define _ALLEGRO_PRIM_DLL __declspec(dllexport) +#else +#define _ALLEGRO_PRIM_DLL __declspec(dllimport) +#endif +#else +#define _ALLEGRO_PRIM_DLL +#endif +#endif + +#if defined ALLEGRO_MSVC +#define ALLEGRO_PRIM_FUNC(type, name, args) _ALLEGRO_PRIM_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 +#define ALLEGRO_PRIM_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 +#define ALLEGRO_PRIM_FUNC(type, name, args) extern _ALLEGRO_PRIM_DLL type name args +#else +#define ALLEGRO_PRIM_FUNC AL_FUNC +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Enum: ALLEGRO_PRIM_TYPE + */ +typedef enum ALLEGRO_PRIM_TYPE +{ + ALLEGRO_PRIM_LINE_LIST, + ALLEGRO_PRIM_LINE_STRIP, + ALLEGRO_PRIM_LINE_LOOP, + ALLEGRO_PRIM_TRIANGLE_LIST, + ALLEGRO_PRIM_TRIANGLE_STRIP, + ALLEGRO_PRIM_TRIANGLE_FAN, + ALLEGRO_PRIM_POINT_LIST, + ALLEGRO_PRIM_NUM_TYPES +} ALLEGRO_PRIM_TYPE; + +enum +{ + ALLEGRO_PRIM_MAX_USER_ATTR = _ALLEGRO_PRIM_MAX_USER_ATTR +}; + +/* Enum: ALLEGRO_PRIM_ATTR + */ +typedef enum ALLEGRO_PRIM_ATTR +{ + ALLEGRO_PRIM_POSITION = 1, + ALLEGRO_PRIM_COLOR_ATTR, + ALLEGRO_PRIM_TEX_COORD, + ALLEGRO_PRIM_TEX_COORD_PIXEL, + ALLEGRO_PRIM_USER_ATTR, + ALLEGRO_PRIM_ATTR_NUM = ALLEGRO_PRIM_USER_ATTR + ALLEGRO_PRIM_MAX_USER_ATTR +} ALLEGRO_PRIM_ATTR; + +/* Enum: ALLEGRO_PRIM_STORAGE + */ +typedef enum ALLEGRO_PRIM_STORAGE +{ + ALLEGRO_PRIM_FLOAT_2, + ALLEGRO_PRIM_FLOAT_3, + ALLEGRO_PRIM_SHORT_2, + ALLEGRO_PRIM_FLOAT_1, + ALLEGRO_PRIM_FLOAT_4, + ALLEGRO_PRIM_UBYTE_4, + ALLEGRO_PRIM_SHORT_4, + ALLEGRO_PRIM_NORMALIZED_UBYTE_4, + ALLEGRO_PRIM_NORMALIZED_SHORT_2, + ALLEGRO_PRIM_NORMALIZED_SHORT_4, + ALLEGRO_PRIM_NORMALIZED_USHORT_2, + ALLEGRO_PRIM_NORMALIZED_USHORT_4, + ALLEGRO_PRIM_HALF_FLOAT_2, + ALLEGRO_PRIM_HALF_FLOAT_4 +} ALLEGRO_PRIM_STORAGE; + +/* Enum: ALLEGRO_LINE_JOIN + */ +typedef enum ALLEGRO_LINE_JOIN +{ + ALLEGRO_LINE_JOIN_NONE, + ALLEGRO_LINE_JOIN_BEVEL, + ALLEGRO_LINE_JOIN_ROUND, + ALLEGRO_LINE_JOIN_MITER, + ALLEGRO_LINE_JOIN_MITRE = ALLEGRO_LINE_JOIN_MITER +} ALLEGRO_LINE_JOIN; + +/* Enum: ALLEGRO_LINE_CAP + */ +typedef enum ALLEGRO_LINE_CAP +{ + ALLEGRO_LINE_CAP_NONE, + ALLEGRO_LINE_CAP_SQUARE, + ALLEGRO_LINE_CAP_ROUND, + ALLEGRO_LINE_CAP_TRIANGLE, + ALLEGRO_LINE_CAP_CLOSED +} ALLEGRO_LINE_CAP; + +/* Enum: ALLEGRO_PRIM_BUFFER_FLAGS + */ +typedef enum ALLEGRO_PRIM_BUFFER_FLAGS +{ + ALLEGRO_PRIM_BUFFER_STREAM = 0x01, + ALLEGRO_PRIM_BUFFER_STATIC = 0x02, + ALLEGRO_PRIM_BUFFER_DYNAMIC = 0x04, + ALLEGRO_PRIM_BUFFER_READWRITE = 0x08 +} ALLEGRO_PRIM_BUFFER_FLAGS; + +/* Enum: ALLEGRO_VERTEX_CACHE_SIZE + */ +#define ALLEGRO_VERTEX_CACHE_SIZE 256 + +/* Enum: ALLEGRO_PRIM_QUALITY + */ +#define ALLEGRO_PRIM_QUALITY 10 + +/* Type: ALLEGRO_VERTEX_ELEMENT + */ +typedef struct ALLEGRO_VERTEX_ELEMENT ALLEGRO_VERTEX_ELEMENT; + +struct ALLEGRO_VERTEX_ELEMENT { + int attribute; + int storage; + int offset; +}; + +/* Type: ALLEGRO_VERTEX_DECL + */ +typedef struct ALLEGRO_VERTEX_DECL ALLEGRO_VERTEX_DECL; + +/* Duplicated in allegro5/internal/aintern_tri_soft.h */ +#ifndef _ALLEGRO_VERTEX_DEFINED +#define _ALLEGRO_VERTEX_DEFINED + +/* Type: ALLEGRO_VERTEX + */ +typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX; + +struct ALLEGRO_VERTEX { + float x, y, z; + float u, v; + ALLEGRO_COLOR color; +}; +#endif + +/* Type: ALLEGRO_VERTEX_BUFFER + */ +typedef struct ALLEGRO_VERTEX_BUFFER ALLEGRO_VERTEX_BUFFER; + +/* Type: ALLEGRO_INDEX_BUFFER + */ +typedef struct ALLEGRO_INDEX_BUFFER ALLEGRO_INDEX_BUFFER; + +ALLEGRO_PRIM_FUNC(uint32_t, al_get_allegro_primitives_version, (void)); + +/* +* Primary Functions +*/ +ALLEGRO_PRIM_FUNC(bool, al_init_primitives_addon, (void)); +ALLEGRO_PRIM_FUNC(void, al_shutdown_primitives_addon, (void)); +ALLEGRO_PRIM_FUNC(int, al_draw_prim, (const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture, int start, int end, int type)); +ALLEGRO_PRIM_FUNC(int, al_draw_indexed_prim, (const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type)); +ALLEGRO_PRIM_FUNC(int, al_draw_vertex_buffer, (ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_BITMAP* texture, int start, int end, int type)); +ALLEGRO_PRIM_FUNC(int, al_draw_indexed_buffer, (ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_BITMAP* texture, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type)); + +ALLEGRO_PRIM_FUNC(ALLEGRO_VERTEX_DECL*, al_create_vertex_decl, (const ALLEGRO_VERTEX_ELEMENT* elements, int stride)); +ALLEGRO_PRIM_FUNC(void, al_destroy_vertex_decl, (ALLEGRO_VERTEX_DECL* decl)); + +/* + * Vertex buffers + */ +ALLEGRO_PRIM_FUNC(ALLEGRO_VERTEX_BUFFER*, al_create_vertex_buffer, (ALLEGRO_VERTEX_DECL* decl, const void* initial_data, int num_vertices, int flags)); +ALLEGRO_PRIM_FUNC(void, al_destroy_vertex_buffer, (ALLEGRO_VERTEX_BUFFER* buffer)); +ALLEGRO_PRIM_FUNC(void*, al_lock_vertex_buffer, (ALLEGRO_VERTEX_BUFFER* buffer, int offset, int length, int flags)); +ALLEGRO_PRIM_FUNC(void, al_unlock_vertex_buffer, (ALLEGRO_VERTEX_BUFFER* buffer)); +ALLEGRO_PRIM_FUNC(int, al_get_vertex_buffer_size, (ALLEGRO_VERTEX_BUFFER* buffer)); + +/* + * Index buffers + */ +ALLEGRO_PRIM_FUNC(ALLEGRO_INDEX_BUFFER*, al_create_index_buffer, (int index_size, const void* initial_data, int num_indices, int flags)); +ALLEGRO_PRIM_FUNC(void, al_destroy_index_buffer, (ALLEGRO_INDEX_BUFFER* buffer)); +ALLEGRO_PRIM_FUNC(void*, al_lock_index_buffer, (ALLEGRO_INDEX_BUFFER* buffer, int offset, int length, int flags)); +ALLEGRO_PRIM_FUNC(void, al_unlock_index_buffer, (ALLEGRO_INDEX_BUFFER* buffer)); +ALLEGRO_PRIM_FUNC(int, al_get_index_buffer_size, (ALLEGRO_INDEX_BUFFER* buffer)); + +/* +* Utilities for high level primitives. +*/ +ALLEGRO_PRIM_FUNC(bool, al_triangulate_polygon, (const float* vertices, size_t vertex_stride, const int* vertex_counts, void (*emit_triangle)(int, int, int, void*), void* userdata)); + + +/* +* Custom primitives +*/ +ALLEGRO_PRIM_FUNC(void, al_draw_soft_triangle, (ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, + void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*first)(uintptr_t, int, int, int, int), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int, int))); +ALLEGRO_PRIM_FUNC(void, al_draw_soft_line, (ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state, + void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int))); + +/* +*High level primitives +*/ +ALLEGRO_PRIM_FUNC(void, al_draw_line, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_triangle, (float x1, float y1, float x2, float y2, float x3, float y3, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_rectangle, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_rounded_rectangle, (float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR color, float thickness)); + +ALLEGRO_PRIM_FUNC(void, al_calculate_arc, (float* dest, int stride, float cx, float cy, float rx, float ry, float start_theta, float delta_theta, float thickness, int num_points)); +ALLEGRO_PRIM_FUNC(void, al_draw_circle, (float cx, float cy, float r, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_ellipse, (float cx, float cy, float rx, float ry, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_arc, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_elliptical_arc, (float cx, float cy, float rx, float ry, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_pieslice, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); + +ALLEGRO_PRIM_FUNC(void, al_calculate_spline, (float* dest, int stride, float points[8], float thickness, int num_segments)); +ALLEGRO_PRIM_FUNC(void, al_draw_spline, (float points[8], ALLEGRO_COLOR color, float thickness)); + +ALLEGRO_PRIM_FUNC(void, al_calculate_ribbon, (float* dest, int dest_stride, const float *points, int points_stride, float thickness, int num_segments)); +ALLEGRO_PRIM_FUNC(void, al_draw_ribbon, (const float *points, int points_stride, ALLEGRO_COLOR color, float thickness, int num_segments)); + +ALLEGRO_PRIM_FUNC(void, al_draw_filled_triangle, (float x1, float y1, float x2, float y2, float x3, float y3, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_rectangle, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_ellipse, (float cx, float cy, float rx, float ry, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_circle, (float cx, float cy, float r, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_pieslice, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_rounded_rectangle, (float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR color)); + +ALLEGRO_PRIM_FUNC(void, al_draw_polyline, (const float* vertices, int vertex_stride, int vertex_count, int join_style, int cap_style, ALLEGRO_COLOR color, float thickness, float miter_limit)); + +ALLEGRO_PRIM_FUNC(void, al_draw_polygon, (const float* vertices, int vertex_count, int join_style, ALLEGRO_COLOR color, float thickness, float miter_limit)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_polygon, (const float* vertices, int vertex_count, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_polygon_with_holes, (const float* vertices, const int* vertex_counts, ALLEGRO_COLOR color)); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_ttf.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_ttf.h new file mode 100644 index 00000000..92af6f1f --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_ttf.h @@ -0,0 +1,49 @@ +#ifndef __al_included_allegro5_allegro_ttf_h +#define __al_included_allegro5_allegro_ttf_h + +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define ALLEGRO_TTF_NO_KERNING 1 +#define ALLEGRO_TTF_MONOCHROME 2 +#define ALLEGRO_TTF_NO_AUTOHINT 4 + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_TTF_SRC + #define _ALLEGRO_TTF_DLL __declspec(dllexport) + #else + #define _ALLEGRO_TTF_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_TTF_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_TTF_FUNC(type, name, args) _ALLEGRO_TTF_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_TTF_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_TTF_FUNC(type, name, args) extern _ALLEGRO_TTF_DLL type name args +#else + #define ALLEGRO_TTF_FUNC AL_FUNC +#endif + +ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font, (char const *filename, int size, int flags)); +ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_f, (ALLEGRO_FILE *file, char const *filename, int size, int flags)); +ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_stretch, (char const *filename, int w, int h, int flags)); +ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_stretch_f, (ALLEGRO_FILE *file, char const *filename, int w, int h, int flags)); +ALLEGRO_TTF_FUNC(bool, al_init_ttf_addon, (void)); +ALLEGRO_TTF_FUNC(void, al_shutdown_ttf_addon, (void)); +ALLEGRO_TTF_FUNC(uint32_t, al_get_allegro_ttf_version, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_video.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_video.h new file mode 100644 index 00000000..f2cb3473 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_video.h @@ -0,0 +1,77 @@ +#ifndef __al_included_allegro_video_h +#define __al_included_allegro_video_h + +#ifdef __cplusplus + extern "C" { +#endif + +#include "allegro5/allegro5.h" +#include "allegro5/allegro_audio.h" + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_VIDEO_SRC + #define _ALLEGRO_VIDEO_DLL __declspec(dllexport) + #else + #define _ALLEGRO_VIDEO_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_VIDEO_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_VIDEO_FUNC(type, name, args) _ALLEGRO_VIDEO_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_VIDEO_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_VIDEO_FUNC(type, name, args) extern _ALLEGRO_VIDEO_DLL type name args +#else + #define ALLEGRO_VIDEO_FUNC AL_FUNC +#endif + +/* Enum: ALLEGRO_VIDEO_EVENT_TYPE + */ +enum ALLEGRO_VIDEO_EVENT_TYPE +{ + ALLEGRO_EVENT_VIDEO_FRAME_SHOW = 550, + ALLEGRO_EVENT_VIDEO_FINISHED = 551, + _ALLEGRO_EVENT_VIDEO_SEEK = 552 /* internal */ +}; + +enum ALLEGRO_VIDEO_POSITION_TYPE +{ + ALLEGRO_VIDEO_POSITION_ACTUAL = 0, + ALLEGRO_VIDEO_POSITION_VIDEO_DECODE = 1, + ALLEGRO_VIDEO_POSITION_AUDIO_DECODE = 2 +}; + +/* Enum: ALLEGRO_VIDEO_POSITION_TYPE + */ +typedef enum ALLEGRO_VIDEO_POSITION_TYPE ALLEGRO_VIDEO_POSITION_TYPE; + +typedef struct ALLEGRO_VIDEO ALLEGRO_VIDEO; + +ALLEGRO_VIDEO_FUNC(ALLEGRO_VIDEO *, al_open_video, (char const *filename)); +ALLEGRO_VIDEO_FUNC(void, al_close_video, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(void, al_start_video, (ALLEGRO_VIDEO *video, ALLEGRO_MIXER *mixer)); +ALLEGRO_VIDEO_FUNC(void, al_start_video_with_voice, (ALLEGRO_VIDEO *video, ALLEGRO_VOICE *voice)); +ALLEGRO_VIDEO_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_video_event_source, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(void, al_set_video_playing, (ALLEGRO_VIDEO *video, bool playing)); +ALLEGRO_VIDEO_FUNC(bool, al_is_video_playing, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(double, al_get_video_audio_rate, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(double, al_get_video_fps, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(float, al_get_video_scaled_width, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(float, al_get_video_scaled_height, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(ALLEGRO_BITMAP *, al_get_video_frame, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(double, al_get_video_position, (ALLEGRO_VIDEO *video, ALLEGRO_VIDEO_POSITION_TYPE which)); +ALLEGRO_VIDEO_FUNC(bool, al_seek_video, (ALLEGRO_VIDEO *video, double pos_in_seconds)); +ALLEGRO_VIDEO_FUNC(bool, al_init_video_addon, (void)); +ALLEGRO_VIDEO_FUNC(void, al_shutdown_video_addon, (void)); +ALLEGRO_VIDEO_FUNC(uint32_t, al_get_allegro_video_version, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_windows.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_windows.h new file mode 100644 index 00000000..f87d4754 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/allegro_windows.h @@ -0,0 +1,44 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Header file for Windows specific API. + * + * By Trent Gamblin. + * + */ + +#ifndef __al_included_allegro5_allegro_windows_h +#define __al_included_allegro5_allegro_windows_h + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Public Windows-related API + */ + +AL_FUNC(HWND, al_get_win_window_handle, (ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_win_add_window_callback, (ALLEGRO_DISPLAY *display, + bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam, + LPARAM lparam, LRESULT *result, void *userdata), void *userdata)); +AL_FUNC(bool, al_win_remove_window_callback, (ALLEGRO_DISPLAY *display, + bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam, + LPARAM lparam, LRESULT *result, void *userdata), void *userdata)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/altime.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/altime.h new file mode 100644 index 00000000..bb0e520d --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/altime.h @@ -0,0 +1,30 @@ +#ifndef __al_included_allegro5_altime_h +#define __al_included_allegro5_altime_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_TIMEOUT + */ +typedef struct ALLEGRO_TIMEOUT ALLEGRO_TIMEOUT; +struct ALLEGRO_TIMEOUT { + uint64_t __pad1__; + uint64_t __pad2__; +}; + + + +AL_FUNC(double, al_get_time, (void)); +AL_FUNC(void, al_rest, (double seconds)); +AL_FUNC(void, al_init_timeout, (ALLEGRO_TIMEOUT *timeout, double seconds)); + + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/base.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/base.h new file mode 100644 index 00000000..96b6371f --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/base.h @@ -0,0 +1,96 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Base header, defines basic stuff needed by pretty much + * everything else. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_base_h +#define __al_included_allegro5_base_h + +#ifndef ALLEGRO_NO_STD_HEADERS + #include + #ifdef _MSC_VER + /* enable posix for limits.h and only limits.h + enabling it for all msvc headers will potentially + disable a lot of commonly used msvcrt functions */ + #define _POSIX_ + #include + #undef _POSIX_ + #else + #include + #endif + #include + #include + #include + #include + #include + #include +#endif + +#if (defined DEBUGMODE) && (defined FORTIFY) + #include +#endif + +#if (defined DEBUGMODE) && (defined DMALLOC) + #include +#endif + +#include "allegro5/internal/alconfig.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define ALLEGRO_VERSION 5 +#define ALLEGRO_SUB_VERSION 1 +#define ALLEGRO_WIP_VERSION 12 + +/* Not sure we need it, but since ALLEGRO_VERSION_STR contains it: + * 0 = GIT + * 1 = first release + * 2... = hotfixes? + * + * Note x.y.z (= x.y.z.0) has release number 1, and x.y.z.1 has release + * number 2, just to confuse you. + */ +#define ALLEGRO_RELEASE_NUMBER 1 + +#define ALLEGRO_VERSION_STR "5.1.12 (WIP)" +#define ALLEGRO_DATE_STR "2015" +#define ALLEGRO_DATE 20150929 /* yyyymmdd */ +#define ALLEGRO_VERSION_INT \ + ((ALLEGRO_VERSION << 24) | (ALLEGRO_SUB_VERSION << 16) | \ + (ALLEGRO_WIP_VERSION << 8) | ALLEGRO_RELEASE_NUMBER) + +AL_FUNC(uint32_t, al_get_allegro_version, (void)); +AL_FUNC(int, al_run_main, (int argc, char **argv, int (*)(int, char **))); + +/*******************************************/ +/************ Some global stuff ************/ +/*******************************************/ + +/* Type: ALLEGRO_PI + */ +#define ALLEGRO_PI 3.14159265358979323846 + +#define AL_ID(a,b,c,d) (((a)<<24) | ((b)<<16) | ((c)<<8) | (d)) + + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap.h new file mode 100644 index 00000000..e93851d5 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap.h @@ -0,0 +1,78 @@ +#ifndef __al_included_allegro5_bitmap_h +#define __al_included_allegro5_bitmap_h + +#include "allegro5/color.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_BITMAP + */ +typedef struct ALLEGRO_BITMAP ALLEGRO_BITMAP; + + +/* + * Bitmap flags + */ +enum { + ALLEGRO_MEMORY_BITMAP = 0x0001, + _ALLEGRO_KEEP_BITMAP_FORMAT = 0x0002, /* now a bitmap loader flag */ + ALLEGRO_FORCE_LOCKING = 0x0004, /* no longer honoured */ + ALLEGRO_NO_PRESERVE_TEXTURE = 0x0008, + _ALLEGRO_ALPHA_TEST = 0x0010, /* now a render state flag */ + _ALLEGRO_INTERNAL_OPENGL = 0x0020, + ALLEGRO_MIN_LINEAR = 0x0040, + ALLEGRO_MAG_LINEAR = 0x0080, + ALLEGRO_MIPMAP = 0x0100, + _ALLEGRO_NO_PREMULTIPLIED_ALPHA = 0x0200, /* now a bitmap loader flag */ + ALLEGRO_VIDEO_BITMAP = 0x0400, + ALLEGRO_CONVERT_BITMAP = 0x1000 +}; + + +AL_FUNC(void, al_set_new_bitmap_format, (int format)); +AL_FUNC(void, al_set_new_bitmap_flags, (int flags)); +AL_FUNC(int, al_get_new_bitmap_format, (void)); +AL_FUNC(int, al_get_new_bitmap_flags, (void)); +AL_FUNC(void, al_add_new_bitmap_flag, (int flag)); + +AL_FUNC(int, al_get_bitmap_width, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_height, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_format, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_flags, (ALLEGRO_BITMAP *bitmap)); + +AL_FUNC(ALLEGRO_BITMAP*, al_create_bitmap, (int w, int h)); +AL_FUNC(void, al_destroy_bitmap, (ALLEGRO_BITMAP *bitmap)); + +AL_FUNC(void, al_put_pixel, (int x, int y, ALLEGRO_COLOR color)); +AL_FUNC(void, al_put_blended_pixel, (int x, int y, ALLEGRO_COLOR color)); +AL_FUNC(ALLEGRO_COLOR, al_get_pixel, (ALLEGRO_BITMAP *bitmap, int x, int y)); + +/* Masking */ +AL_FUNC(void, al_convert_mask_to_alpha, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color)); + +/* Clipping */ +AL_FUNC(void, al_set_clipping_rectangle, (int x, int y, int width, int height)); +AL_FUNC(void, al_reset_clipping_rectangle, (void)); +AL_FUNC(void, al_get_clipping_rectangle, (int *x, int *y, int *w, int *h)); + +/* Sub bitmaps */ +AL_FUNC(ALLEGRO_BITMAP *, al_create_sub_bitmap, (ALLEGRO_BITMAP *parent, int x, int y, int w, int h)); +AL_FUNC(bool, al_is_sub_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(ALLEGRO_BITMAP *, al_get_parent_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_x, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_y, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_reparent_bitmap, (ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP *parent, int x, int y, int w, int h)); + +/* Miscellaneous */ +AL_FUNC(ALLEGRO_BITMAP *, al_clone_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_convert_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_convert_bitmaps, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_draw.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_draw.h new file mode 100644 index 00000000..83e3e144 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_draw.h @@ -0,0 +1,42 @@ +#ifndef __al_included_allegro5_bitmap_draw_h +#define __al_included_allegro5_bitmap_draw_h + +#include "allegro5/bitmap.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Flags for the blitting functions */ +enum { + ALLEGRO_FLIP_HORIZONTAL = 0x00001, + ALLEGRO_FLIP_VERTICAL = 0x00002 +}; + +/* Blitting */ +AL_FUNC(void, al_draw_bitmap, (ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags)); +AL_FUNC(void, al_draw_bitmap_region, (ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, float dx, float dy, int flags)); +AL_FUNC(void, al_draw_scaled_bitmap, (ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags)); +AL_FUNC(void, al_draw_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, float cx, float cy, float dx, float dy, float angle, int flags)); +AL_FUNC(void, al_draw_scaled_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags)); + +/* Tinted blitting */ +AL_FUNC(void, al_draw_tinted_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float dx, float dy, int flags)); +AL_FUNC(void, al_draw_tinted_bitmap_region, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, int flags)); +AL_FUNC(void, al_draw_tinted_scaled_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags)); +AL_FUNC(void, al_draw_tinted_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float angle, int flags)); +AL_FUNC(void, al_draw_tinted_scaled_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags)); +AL_FUNC(void, al_draw_tinted_scaled_rotated_bitmap_region, ( + ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, + ALLEGRO_COLOR tint, + float cx, float cy, float dx, float dy, float xscale, float yscale, + float angle, int flags)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_io.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_io.h new file mode 100644 index 00000000..70ff94cd --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_io.h @@ -0,0 +1,47 @@ +#ifndef __al_included_allegro5_bitmap_io_h +#define __al_included_allegro5_bitmap_io_h + +#include "allegro5/bitmap.h" +#include "allegro5/file.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Bitmap loader flag + */ +enum { + ALLEGRO_KEEP_BITMAP_FORMAT = 0x0002, /* was a bitmap flag in 5.0 */ + ALLEGRO_NO_PREMULTIPLIED_ALPHA = 0x0200, /* was a bitmap flag in 5.0 */ + ALLEGRO_KEEP_INDEX = 0x0800 +}; + +typedef ALLEGRO_BITMAP *(*ALLEGRO_IIO_LOADER_FUNCTION)(const char *filename, int flags); +typedef ALLEGRO_BITMAP *(*ALLEGRO_IIO_FS_LOADER_FUNCTION)(ALLEGRO_FILE *fp, int flags); +typedef bool (*ALLEGRO_IIO_SAVER_FUNCTION)(const char *filename, ALLEGRO_BITMAP *bitmap); +typedef bool (*ALLEGRO_IIO_FS_SAVER_FUNCTION)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bitmap); +typedef bool (*ALLEGRO_IIO_IDENTIFIER_FUNCTION)(ALLEGRO_FILE *f); + +AL_FUNC(bool, al_register_bitmap_loader, (const char *ext, ALLEGRO_IIO_LOADER_FUNCTION loader)); +AL_FUNC(bool, al_register_bitmap_saver, (const char *ext, ALLEGRO_IIO_SAVER_FUNCTION saver)); +AL_FUNC(bool, al_register_bitmap_loader_f, (const char *ext, ALLEGRO_IIO_FS_LOADER_FUNCTION fs_loader)); +AL_FUNC(bool, al_register_bitmap_saver_f, (const char *ext, ALLEGRO_IIO_FS_SAVER_FUNCTION fs_saver)); +AL_FUNC(bool, al_register_bitmap_identifier, (const char *ext, + ALLEGRO_IIO_IDENTIFIER_FUNCTION identifier)); +AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap, (const char *filename)); +AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap_flags, (const char *filename, int flags)); +AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap_f, (ALLEGRO_FILE *fp, const char *ident)); +AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap_flags_f, (ALLEGRO_FILE *fp, const char *ident, int flags)); +AL_FUNC(bool, al_save_bitmap, (const char *filename, ALLEGRO_BITMAP *bitmap)); +AL_FUNC(bool, al_save_bitmap_f, (ALLEGRO_FILE *fp, const char *ident, ALLEGRO_BITMAP *bitmap)); +AL_FUNC(char const *, al_identify_bitmap_f, (ALLEGRO_FILE *fp)); +AL_FUNC(char const *, al_identify_bitmap, (char const *filename)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_lock.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_lock.h new file mode 100644 index 00000000..198e58a0 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/bitmap_lock.h @@ -0,0 +1,45 @@ +#ifndef __al_included_allegro5_bitmap_lock_h +#define __al_included_allegro5_bitmap_lock_h + +#include "allegro5/bitmap.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* + * Locking flags + */ +enum { + ALLEGRO_LOCK_READWRITE = 0, + ALLEGRO_LOCK_READONLY = 1, + ALLEGRO_LOCK_WRITEONLY = 2 +}; + + +/* Type: ALLEGRO_LOCKED_REGION + */ +typedef struct ALLEGRO_LOCKED_REGION ALLEGRO_LOCKED_REGION; +struct ALLEGRO_LOCKED_REGION { + void *data; + int format; + int pitch; + int pixel_size; +}; + + +AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap, (ALLEGRO_BITMAP *bitmap, int format, int flags)); +AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap_region, (ALLEGRO_BITMAP *bitmap, int x, int y, int width, int height, int format, int flags)); +AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap_blocked, (ALLEGRO_BITMAP *bitmap, int flags)); +AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap_region_blocked, (ALLEGRO_BITMAP *bitmap, int x_block, int y_block, + int width_block, int height_block, int flags)); +AL_FUNC(void, al_unlock_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(bool, al_is_bitmap_locked, (ALLEGRO_BITMAP *bitmap)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/blender.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/blender.h new file mode 100644 index 00000000..120ed784 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/blender.h @@ -0,0 +1,48 @@ +#ifndef __al_included_allegro5_blender_h +#define __al_included_allegro5_blender_h + +#ifdef __cplusplus + extern "C" { +#endif + + +/* + * Blending modes + */ +enum ALLEGRO_BLEND_MODE { + ALLEGRO_ZERO = 0, + ALLEGRO_ONE = 1, + ALLEGRO_ALPHA = 2, + ALLEGRO_INVERSE_ALPHA = 3, + ALLEGRO_SRC_COLOR = 4, + ALLEGRO_DEST_COLOR = 5, + ALLEGRO_INVERSE_SRC_COLOR = 6, + ALLEGRO_INVERSE_DEST_COLOR = 7, + ALLEGRO_CONST_COLOR = 8, + ALLEGRO_INVERSE_CONST_COLOR = 9, + ALLEGRO_NUM_BLEND_MODES +}; + +enum ALLEGRO_BLEND_OPERATIONS { + ALLEGRO_ADD = 0, + ALLEGRO_SRC_MINUS_DEST = 1, + ALLEGRO_DEST_MINUS_SRC = 2, + ALLEGRO_NUM_BLEND_OPERATIONS +}; + + +AL_FUNC(void, al_set_blender, (int op, int source, int dest)); +AL_FUNC(void, al_set_blend_color, (ALLEGRO_COLOR color)); +AL_FUNC(void, al_get_blender, (int *op, int *source, int *dest)); +AL_FUNC(ALLEGRO_COLOR, al_get_blend_color, (void)); +AL_FUNC(void, al_set_separate_blender, (int op, int source, int dest, + int alpha_op, int alpha_source, int alpha_dest)); +AL_FUNC(void, al_get_separate_blender, (int *op, int *source, int *dest, + int *alpha_op, int *alpha_src, int *alpha_dest)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/clipboard.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/clipboard.h new file mode 100644 index 00000000..46851fe4 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/clipboard.h @@ -0,0 +1,42 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Clipboard handling. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_clipboard_h +#define __al_included_allegro5_clipboard_h + +#include "allegro5/base.h" +#include "allegro5/display.h" +#include "allegro5/utf8.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(char *, al_get_clipboard_text, (ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_set_clipboard_text, (ALLEGRO_DISPLAY *display, const char *text)); +AL_FUNC(bool, al_clipboard_has_text, (ALLEGRO_DISPLAY *display)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/color.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/color.h new file mode 100644 index 00000000..41b94bfb --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/color.h @@ -0,0 +1,89 @@ +#ifndef __al_included_allegro5_color_h +#define __al_included_allegro5_color_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_COLOR + */ +typedef struct ALLEGRO_COLOR ALLEGRO_COLOR; + +struct ALLEGRO_COLOR +{ + float r, g, b, a; +}; + + +/* Enum: ALLEGRO_PIXEL_FORMAT + */ +typedef enum ALLEGRO_PIXEL_FORMAT +{ + ALLEGRO_PIXEL_FORMAT_ANY = 0, + ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA = 1, + ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA = 2, + ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA = 3, + ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA = 4, + ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA = 5, + ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA = 6, + ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA = 7, + ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA = 8, + ALLEGRO_PIXEL_FORMAT_ARGB_8888 = 9, + ALLEGRO_PIXEL_FORMAT_RGBA_8888 = 10, + ALLEGRO_PIXEL_FORMAT_ARGB_4444 = 11, + ALLEGRO_PIXEL_FORMAT_RGB_888 = 12, /* 24 bit format */ + ALLEGRO_PIXEL_FORMAT_RGB_565 = 13, + ALLEGRO_PIXEL_FORMAT_RGB_555 = 14, + ALLEGRO_PIXEL_FORMAT_RGBA_5551 = 15, + ALLEGRO_PIXEL_FORMAT_ARGB_1555 = 16, + ALLEGRO_PIXEL_FORMAT_ABGR_8888 = 17, + ALLEGRO_PIXEL_FORMAT_XBGR_8888 = 18, + ALLEGRO_PIXEL_FORMAT_BGR_888 = 19, /* 24 bit format */ + ALLEGRO_PIXEL_FORMAT_BGR_565 = 20, + ALLEGRO_PIXEL_FORMAT_BGR_555 = 21, + ALLEGRO_PIXEL_FORMAT_RGBX_8888 = 22, + ALLEGRO_PIXEL_FORMAT_XRGB_8888 = 23, + ALLEGRO_PIXEL_FORMAT_ABGR_F32 = 24, + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE = 25, + ALLEGRO_PIXEL_FORMAT_RGBA_4444 = 26, + ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 = 27, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1 = 28, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3 = 29, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5 = 30, + ALLEGRO_NUM_PIXEL_FORMATS +} ALLEGRO_PIXEL_FORMAT; + + +/* Pixel mapping */ +AL_FUNC(ALLEGRO_COLOR, al_map_rgb, (unsigned char r, unsigned char g, unsigned char b)); +AL_FUNC(ALLEGRO_COLOR, al_map_rgba, (unsigned char r, unsigned char g, unsigned char b, unsigned char a)); +AL_FUNC(ALLEGRO_COLOR, al_map_rgb_f, (float r, float g, float b)); +AL_FUNC(ALLEGRO_COLOR, al_map_rgba_f, (float r, float g, float b, float a)); +AL_FUNC(ALLEGRO_COLOR, al_premul_rgba, + (unsigned char r, unsigned char g, unsigned char b, unsigned char a)); +AL_FUNC(ALLEGRO_COLOR, al_premul_rgba_f, + (float r, float g, float b, float a)); + +/* Pixel unmapping */ +AL_FUNC(void, al_unmap_rgb, (ALLEGRO_COLOR color, unsigned char *r, unsigned char *g, unsigned char *b)); +AL_FUNC(void, al_unmap_rgba, (ALLEGRO_COLOR color, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)); +AL_FUNC(void, al_unmap_rgb_f, (ALLEGRO_COLOR color, float *r, float *g, float *b)); +AL_FUNC(void, al_unmap_rgba_f, (ALLEGRO_COLOR color, float *r, float *g, float *b, float *a)); + +/* Pixel formats */ +AL_FUNC(int, al_get_pixel_size, (int format)); +AL_FUNC(int, al_get_pixel_format_bits, (int format)); +AL_FUNC(int, al_get_pixel_block_size, (int format)); +AL_FUNC(int, al_get_pixel_block_width, (int format)); +AL_FUNC(int, al_get_pixel_block_height, (int format)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/config.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/config.h new file mode 100644 index 00000000..9402b00d --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/config.h @@ -0,0 +1,49 @@ +#ifndef __al_included_allegro5_config_h +#define __al_included_allegro5_config_h + +#include "allegro5/file.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Type: ALLEGRO_CONFIG + */ +typedef struct ALLEGRO_CONFIG ALLEGRO_CONFIG; + +/* Type: ALLEGRO_CONFIG_SECTION + */ +typedef struct ALLEGRO_CONFIG_SECTION ALLEGRO_CONFIG_SECTION; + +/* Type: ALLEGRO_CONFIG_ENTRY + */ +typedef struct ALLEGRO_CONFIG_ENTRY ALLEGRO_CONFIG_ENTRY; + +AL_FUNC(ALLEGRO_CONFIG *, al_create_config, (void)); +AL_FUNC(void, al_add_config_section, (ALLEGRO_CONFIG *config, const char *name)); +AL_FUNC(void, al_set_config_value, (ALLEGRO_CONFIG *config, const char *section, const char *key, const char *value)); +AL_FUNC(void, al_add_config_comment, (ALLEGRO_CONFIG *config, const char *section, const char *comment)); +AL_FUNC(const char*, al_get_config_value, (const ALLEGRO_CONFIG *config, const char *section, const char *key)); +AL_FUNC(ALLEGRO_CONFIG*, al_load_config_file, (const char *filename)); +AL_FUNC(ALLEGRO_CONFIG*, al_load_config_file_f, (ALLEGRO_FILE *filename)); +AL_FUNC(bool, al_save_config_file, (const char *filename, const ALLEGRO_CONFIG *config)); +AL_FUNC(bool, al_save_config_file_f, (ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)); +AL_FUNC(void, al_merge_config_into, (ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add)); +AL_FUNC(ALLEGRO_CONFIG *, al_merge_config, (const ALLEGRO_CONFIG *cfg1, const ALLEGRO_CONFIG *cfg2)); +AL_FUNC(void, al_destroy_config, (ALLEGRO_CONFIG *config)); +AL_FUNC(bool, al_remove_config_section, (ALLEGRO_CONFIG *config, + char const *section)); +AL_FUNC(bool, al_remove_config_key, (ALLEGRO_CONFIG *config, + char const *section, char const *key)); + +AL_FUNC(char const *, al_get_first_config_section, (ALLEGRO_CONFIG const *config, ALLEGRO_CONFIG_SECTION **iterator)); +AL_FUNC(char const *, al_get_next_config_section, (ALLEGRO_CONFIG_SECTION **iterator)); +AL_FUNC(char const *, al_get_first_config_entry, (ALLEGRO_CONFIG const *config, char const *section, + ALLEGRO_CONFIG_ENTRY **iterator)); +AL_FUNC(char const *, al_get_next_config_entry, (ALLEGRO_CONFIG_ENTRY **iterator)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/cpu.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/cpu.h new file mode 100644 index 00000000..512d76c4 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/cpu.h @@ -0,0 +1,39 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * CPU and system information handling. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_cpu_h +#define __al_included_allegro5_cpu_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(int, al_get_cpu_count, (void)); +AL_FUNC(int, al_get_ram_size, (void)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/debug.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/debug.h new file mode 100644 index 00000000..c0dd3780 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/debug.h @@ -0,0 +1,94 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Debug facilities. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_debug_h +#define __al_included_allegro5_debug_h + +#include +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(bool, _al_trace_prefix, (char const *channel, int level, + char const *file, int line, char const *function)); + +AL_PRINTFUNC(void, _al_trace_suffix, (const char *msg, ...), 1, 2); + +#if defined(DEBUGMODE) || defined(ALLEGRO_CFG_RELEASE_LOGGING) + /* Must not be used with a trailing semicolon. */ + #ifdef ALLEGRO_GCC + #define ALLEGRO_DEBUG_CHANNEL(x) \ + static char const *__al_debug_channel __attribute__((unused)) = x; + #else + #define ALLEGRO_DEBUG_CHANNEL(x) \ + static char const *__al_debug_channel = x; + #endif + #define ALLEGRO_TRACE_CHANNEL_LEVEL(channel, level) \ + !_al_trace_prefix(channel, level, __FILE__, __LINE__, __func__) \ + ? (void)0 : _al_trace_suffix +#else + #define ALLEGRO_TRACE_CHANNEL_LEVEL(channel, x) 1 ? (void) 0 : _al_trace_suffix + #define ALLEGRO_DEBUG_CHANNEL(x) +#endif + +#define ALLEGRO_TRACE_LEVEL(x) ALLEGRO_TRACE_CHANNEL_LEVEL(__al_debug_channel, x) +#define ALLEGRO_DEBUG ALLEGRO_TRACE_LEVEL(0) +#define ALLEGRO_INFO ALLEGRO_TRACE_LEVEL(1) +#define ALLEGRO_WARN ALLEGRO_TRACE_LEVEL(2) +#define ALLEGRO_ERROR ALLEGRO_TRACE_LEVEL(3) + +/* Run-time assertions. */ +AL_FUNCPTR(void, _al_user_assert_handler, (char const *expr, char const *file, + int line, char const *func)); + +AL_FUNC(void, al_register_assert_handler, (void (*handler)(char const *expr, + char const *file, int line, char const *func))); + +AL_FUNC(void, al_register_trace_handler, (void (*handler)(char const *))); + +#ifdef NDEBUG + #define ALLEGRO_ASSERT(e) ((void)(0 && (e))) +#else + #define ALLEGRO_ASSERT(e) \ + ((e) ? (void) 0 \ + : (_al_user_assert_handler) ? \ + _al_user_assert_handler(#e, __FILE__, __LINE__, __func__) \ + : assert(e)) +#endif + +/* Compile time assertions. */ +#define ALLEGRO_ASSERT_CONCAT_(a, b) a##b +#define ALLEGRO_ASSERT_CONCAT(a, b) ALLEGRO_ASSERT_CONCAT_(a, b) +#define ALLEGRO_STATIC_ASSERT(module, e) \ + struct ALLEGRO_ASSERT_CONCAT(static_assert_##module##_line_, __LINE__) \ + { unsigned int bf : !!(e); } + +/* We are lazy and use just ASSERT while Allegro itself is compiled. */ +#ifdef ALLEGRO_LIB_BUILD + #define ASSERT(x) ALLEGRO_ASSERT(x) +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/display.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/display.h new file mode 100644 index 00000000..87238667 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/display.h @@ -0,0 +1,181 @@ +#ifndef __al_included_allegro5_display_h +#define __al_included_allegro5_display_h + +#include "allegro5/bitmap.h" +#include "allegro5/color.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Possible bit combinations for the flags parameter of al_create_display. */ +enum { + ALLEGRO_WINDOWED = 1 << 0, + ALLEGRO_FULLSCREEN = 1 << 1, + ALLEGRO_OPENGL = 1 << 2, + ALLEGRO_DIRECT3D_INTERNAL = 1 << 3, + ALLEGRO_RESIZABLE = 1 << 4, + ALLEGRO_FRAMELESS = 1 << 5, + ALLEGRO_NOFRAME = ALLEGRO_FRAMELESS, /* older synonym */ + ALLEGRO_GENERATE_EXPOSE_EVENTS = 1 << 6, + ALLEGRO_OPENGL_3_0 = 1 << 7, + ALLEGRO_OPENGL_FORWARD_COMPATIBLE = 1 << 8, + ALLEGRO_FULLSCREEN_WINDOW = 1 << 9, + ALLEGRO_MINIMIZED = 1 << 10, + ALLEGRO_PROGRAMMABLE_PIPELINE = 1 << 11, + ALLEGRO_GTK_TOPLEVEL_INTERNAL = 1 << 12, + ALLEGRO_MAXIMIZED = 1 << 13, +}; + +/* Possible parameters for al_set_display_option. + * Make sure to update ALLEGRO_EXTRA_DISPLAY_SETTINGS if you modify + * anything here. + */ +enum ALLEGRO_DISPLAY_OPTIONS { + ALLEGRO_RED_SIZE = 0, + ALLEGRO_GREEN_SIZE = 1, + ALLEGRO_BLUE_SIZE = 2, + ALLEGRO_ALPHA_SIZE = 3, + ALLEGRO_RED_SHIFT = 4, + ALLEGRO_GREEN_SHIFT = 5, + ALLEGRO_BLUE_SHIFT = 6, + ALLEGRO_ALPHA_SHIFT = 7, + ALLEGRO_ACC_RED_SIZE = 8, + ALLEGRO_ACC_GREEN_SIZE = 9, + ALLEGRO_ACC_BLUE_SIZE = 10, + ALLEGRO_ACC_ALPHA_SIZE = 11, + ALLEGRO_STEREO = 12, + ALLEGRO_AUX_BUFFERS = 13, + ALLEGRO_COLOR_SIZE = 14, + ALLEGRO_DEPTH_SIZE = 15, + ALLEGRO_STENCIL_SIZE = 16, + ALLEGRO_SAMPLE_BUFFERS = 17, + ALLEGRO_SAMPLES = 18, + ALLEGRO_RENDER_METHOD = 19, + ALLEGRO_FLOAT_COLOR = 20, + ALLEGRO_FLOAT_DEPTH = 21, + ALLEGRO_SINGLE_BUFFER = 22, + ALLEGRO_SWAP_METHOD = 23, + ALLEGRO_COMPATIBLE_DISPLAY = 24, + ALLEGRO_UPDATE_DISPLAY_REGION = 25, + ALLEGRO_VSYNC = 26, + ALLEGRO_MAX_BITMAP_SIZE = 27, + ALLEGRO_SUPPORT_NPOT_BITMAP = 28, + ALLEGRO_CAN_DRAW_INTO_BITMAP = 29, + ALLEGRO_SUPPORT_SEPARATE_ALPHA = 30, + ALLEGRO_AUTO_CONVERT_BITMAPS = 31, + ALLEGRO_SUPPORTED_ORIENTATIONS = 32, + ALLEGRO_DISPLAY_OPTIONS_COUNT +}; + +enum +{ + ALLEGRO_DONTCARE, + ALLEGRO_REQUIRE, + ALLEGRO_SUGGEST +}; + + +/* Bitflags so they can be used for the ALLEGRO_SUPPORTED_ORIENTATIONS option. */ +enum ALLEGRO_DISPLAY_ORIENTATION +{ + ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN = 0, + ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES = 1, + ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES = 2, + ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES = 4, + ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES = 8, + ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT = 5, + ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE = 10, + ALLEGRO_DISPLAY_ORIENTATION_ALL = 15, + ALLEGRO_DISPLAY_ORIENTATION_FACE_UP = 16, + ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN = 32 +}; + + +/* Formally part of the primitives addon. */ +enum +{ + _ALLEGRO_PRIM_MAX_USER_ATTR = 10 +}; + + +/* Type: ALLEGRO_DISPLAY + */ +typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY; + + +/* Enum: ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE +*/ +#define ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE 255 + +AL_FUNC(void, al_set_new_display_refresh_rate, (int refresh_rate)); +AL_FUNC(void, al_set_new_display_flags, (int flags)); +AL_FUNC(int, al_get_new_display_refresh_rate, (void)); +AL_FUNC(int, al_get_new_display_flags, (void)); + +AL_FUNC(void, al_set_new_window_title, (char *title)); +AL_FUNC(const char *, al_get_new_window_title, (void)); + +AL_FUNC(int, al_get_display_width, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_height, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_format, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_refresh_rate, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_flags, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_orientation, (ALLEGRO_DISPLAY* display)); +AL_FUNC(bool, al_set_display_flag, (ALLEGRO_DISPLAY *display, int flag, bool onoff)); + +AL_FUNC(ALLEGRO_DISPLAY*, al_create_display, (int w, int h)); +AL_FUNC(void, al_destroy_display, (ALLEGRO_DISPLAY *display)); +AL_FUNC(ALLEGRO_DISPLAY*, al_get_current_display, (void)); +AL_FUNC(void, al_set_target_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_set_target_backbuffer, (ALLEGRO_DISPLAY *display)); +AL_FUNC(ALLEGRO_BITMAP*, al_get_backbuffer, (ALLEGRO_DISPLAY *display)); +AL_FUNC(ALLEGRO_BITMAP*, al_get_target_bitmap, (void)); + +AL_FUNC(bool, al_acknowledge_resize, (ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_resize_display, (ALLEGRO_DISPLAY *display, int width, int height)); +AL_FUNC(void, al_flip_display, (void)); +AL_FUNC(void, al_update_display_region, (int x, int y, int width, int height)); +AL_FUNC(bool, al_is_compatible_bitmap, (ALLEGRO_BITMAP *bitmap)); + +AL_FUNC(bool, al_wait_for_vsync, (void)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_display_event_source, (ALLEGRO_DISPLAY *display)); + +AL_FUNC(void, al_set_display_icon, (ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon)); +AL_FUNC(void, al_set_display_icons, (ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *icons[])); + +/* Stuff for multihead/window management */ +AL_FUNC(int, al_get_new_display_adapter, (void)); +AL_FUNC(void, al_set_new_display_adapter, (int adapter)); +AL_FUNC(void, al_set_new_window_position, (int x, int y)); +AL_FUNC(void, al_get_new_window_position, (int *x, int *y)); +AL_FUNC(void, al_set_window_position, (ALLEGRO_DISPLAY *display, int x, int y)); +AL_FUNC(void, al_get_window_position, (ALLEGRO_DISPLAY *display, int *x, int *y)); +AL_FUNC(bool, al_set_window_constraints, (ALLEGRO_DISPLAY *display, int min_w, int min_h, int max_w, int max_h)); +AL_FUNC(bool, al_get_window_constraints, (ALLEGRO_DISPLAY *display, int *min_w, int *min_h, int *max_w, int *max_h)); + +AL_FUNC(void, al_set_window_title, (ALLEGRO_DISPLAY *display, const char *title)); + +/* Defined in display_settings.c */ +AL_FUNC(void, al_set_new_display_option, (int option, int value, int importance)); +AL_FUNC(int, al_get_new_display_option, (int option, int *importance)); +AL_FUNC(void, al_reset_new_display_options, (void)); +AL_FUNC(void, al_set_display_option, (ALLEGRO_DISPLAY *display, int option, int value)); +AL_FUNC(int, al_get_display_option, (ALLEGRO_DISPLAY *display, int option)); + +/*Deferred drawing*/ +AL_FUNC(void, al_hold_bitmap_drawing, (bool hold)); +AL_FUNC(bool, al_is_bitmap_drawing_held, (void)); + +AL_FUNC(void, al_acknowledge_drawing_halt, (ALLEGRO_DISPLAY *display)); +AL_FUNC(void, al_acknowledge_drawing_resume, (ALLEGRO_DISPLAY *display)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/drawing.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/drawing.h new file mode 100644 index 00000000..dd21dc6c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/drawing.h @@ -0,0 +1,22 @@ +#ifndef __al_included_allegro5_drawing_h +#define __al_included_allegro5_drawing_h + +#include "allegro5/color.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Drawing primitives */ +AL_FUNC(void, al_clear_to_color, (ALLEGRO_COLOR color)); +AL_FUNC(void, al_clear_depth_buffer, (float x)); +AL_FUNC(void, al_draw_pixel, (float x, float y, ALLEGRO_COLOR color)); + + +#ifdef __cplusplus + } +#endif + +#endif +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/error.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/error.h new file mode 100644 index 00000000..306c7aa0 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/error.h @@ -0,0 +1,39 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Error handling. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_error_h +#define __al_included_allegro5_error_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(int, al_get_errno, (void)); +AL_FUNC(void, al_set_errno, (int errnum)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/events.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/events.h new file mode 100644 index 00000000..7904d714 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/events.h @@ -0,0 +1,273 @@ +#ifndef __al_included_allegro5_events_h +#define __al_included_allegro5_events_h + +#include "allegro5/altime.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_EVENT_TYPE + */ +typedef unsigned int ALLEGRO_EVENT_TYPE; + +enum +{ + ALLEGRO_EVENT_JOYSTICK_AXIS = 1, + ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN = 2, + ALLEGRO_EVENT_JOYSTICK_BUTTON_UP = 3, + ALLEGRO_EVENT_JOYSTICK_CONFIGURATION = 4, + + ALLEGRO_EVENT_KEY_DOWN = 10, + ALLEGRO_EVENT_KEY_CHAR = 11, + ALLEGRO_EVENT_KEY_UP = 12, + + ALLEGRO_EVENT_MOUSE_AXES = 20, + ALLEGRO_EVENT_MOUSE_BUTTON_DOWN = 21, + ALLEGRO_EVENT_MOUSE_BUTTON_UP = 22, + ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY = 23, + ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY = 24, + ALLEGRO_EVENT_MOUSE_WARPED = 25, + + ALLEGRO_EVENT_TIMER = 30, + + ALLEGRO_EVENT_DISPLAY_EXPOSE = 40, + ALLEGRO_EVENT_DISPLAY_RESIZE = 41, + ALLEGRO_EVENT_DISPLAY_CLOSE = 42, + ALLEGRO_EVENT_DISPLAY_LOST = 43, + ALLEGRO_EVENT_DISPLAY_FOUND = 44, + ALLEGRO_EVENT_DISPLAY_SWITCH_IN = 45, + ALLEGRO_EVENT_DISPLAY_SWITCH_OUT = 46, + ALLEGRO_EVENT_DISPLAY_ORIENTATION = 47, + ALLEGRO_EVENT_DISPLAY_HALT_DRAWING = 48, + ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING = 49, + + ALLEGRO_EVENT_TOUCH_BEGIN = 50, + ALLEGRO_EVENT_TOUCH_END = 51, + ALLEGRO_EVENT_TOUCH_MOVE = 52, + ALLEGRO_EVENT_TOUCH_CANCEL = 53, + + ALLEGRO_EVENT_DISPLAY_CONNECTED = 60, + ALLEGRO_EVENT_DISPLAY_DISCONNECTED = 61 +}; + + +/* Function: ALLEGRO_EVENT_TYPE_IS_USER + * + * 1 <= n < 512 - builtin events + * 512 <= n < 1024 - reserved user events (for addons) + * 1024 <= n - unreserved user events + */ +#define ALLEGRO_EVENT_TYPE_IS_USER(t) ((t) >= 512) + + +/* Function: ALLEGRO_GET_EVENT_TYPE + */ +#define ALLEGRO_GET_EVENT_TYPE(a, b, c, d) AL_ID(a, b, c, d) + + +/* Type: ALLEGRO_EVENT_SOURCE + */ +typedef struct ALLEGRO_EVENT_SOURCE ALLEGRO_EVENT_SOURCE; + +struct ALLEGRO_EVENT_SOURCE +{ + int __pad[32]; +}; + + + +/* + * Event structures + * + * All event types have the following fields in common. + * + * type -- the type of event this is + * timestamp -- when this event was generated + * source -- which event source generated this event + * + * For people writing event sources: The common fields must be at the + * very start of each event structure, i.e. put _AL_EVENT_HEADER at the + * front. + */ + +#define _AL_EVENT_HEADER(srctype) \ + ALLEGRO_EVENT_TYPE type; \ + srctype *source; \ + double timestamp; + + +typedef struct ALLEGRO_ANY_EVENT +{ + _AL_EVENT_HEADER(ALLEGRO_EVENT_SOURCE) +} ALLEGRO_ANY_EVENT; + + +typedef struct ALLEGRO_DISPLAY_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_DISPLAY) + int x, y; + int width, height; + int orientation; +} ALLEGRO_DISPLAY_EVENT; + + +typedef struct ALLEGRO_JOYSTICK_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_JOYSTICK) + struct ALLEGRO_JOYSTICK *id; + int stick; + int axis; + float pos; + int button; +} ALLEGRO_JOYSTICK_EVENT; + + + +typedef struct ALLEGRO_KEYBOARD_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_KEYBOARD) + struct ALLEGRO_DISPLAY *display; /* the window the key was pressed in */ + int keycode; /* the physical key pressed */ + int unichar; /* unicode character or negative */ + unsigned int modifiers; /* bitfield */ + bool repeat; /* auto-repeated or not */ +} ALLEGRO_KEYBOARD_EVENT; + + + +typedef struct ALLEGRO_MOUSE_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_MOUSE) + struct ALLEGRO_DISPLAY *display; + /* (display) Window the event originate from + * (x, y) Primary mouse position + * (z) Mouse wheel position (1D 'wheel'), or, + * (w, z) Mouse wheel position (2D 'ball') + * (pressure) The pressure applied, for stylus (0 or 1 for normal mouse) + */ + int x, y, z, w; + int dx, dy, dz, dw; + unsigned int button; + float pressure; +} ALLEGRO_MOUSE_EVENT; + + + +typedef struct ALLEGRO_TIMER_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_TIMER) + int64_t count; + double error; +} ALLEGRO_TIMER_EVENT; + + + +/* Type: ALLEGRO_TOUCH_EVENT + */ +typedef struct ALLEGRO_TOUCH_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_TOUCH_INPUT) + struct ALLEGRO_DISPLAY *display; + /* (id) Identifier of the event, always positive number. + * (x, y) Touch position on the screen in 1:1 resolution. + * (dx, dy) Relative touch position. + * (primary) True, if touch is a primary one (usually first one). + */ + int id; + float x, y; + float dx, dy; + bool primary; +} ALLEGRO_TOUCH_EVENT; + + + +/* Type: ALLEGRO_USER_EVENT + */ +typedef struct ALLEGRO_USER_EVENT ALLEGRO_USER_EVENT; + +struct ALLEGRO_USER_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_EVENT_SOURCE) + struct ALLEGRO_USER_EVENT_DESCRIPTOR *__internal__descr; + intptr_t data1; + intptr_t data2; + intptr_t data3; + intptr_t data4; +}; + + + +/* Type: ALLEGRO_EVENT + */ +typedef union ALLEGRO_EVENT ALLEGRO_EVENT; + +union ALLEGRO_EVENT +{ + /* This must be the same as the first field of _AL_EVENT_HEADER. */ + ALLEGRO_EVENT_TYPE type; + /* `any' is to allow the user to access the other fields which are + * common to all event types, without using some specific type + * structure. + */ + ALLEGRO_ANY_EVENT any; + ALLEGRO_DISPLAY_EVENT display; + ALLEGRO_JOYSTICK_EVENT joystick; + ALLEGRO_KEYBOARD_EVENT keyboard; + ALLEGRO_MOUSE_EVENT mouse; + ALLEGRO_TIMER_EVENT timer; + ALLEGRO_TOUCH_EVENT touch; + ALLEGRO_USER_EVENT user; +}; + + + +/* Event sources */ + +AL_FUNC(void, al_init_user_event_source, (ALLEGRO_EVENT_SOURCE *)); +AL_FUNC(void, al_destroy_user_event_source, (ALLEGRO_EVENT_SOURCE *)); +/* The second argument is ALLEGRO_EVENT instead of ALLEGRO_USER_EVENT + * to prevent users passing a pointer to a too-short structure. + */ +AL_FUNC(bool, al_emit_user_event, (ALLEGRO_EVENT_SOURCE *, ALLEGRO_EVENT *, + void (*dtor)(ALLEGRO_USER_EVENT *))); +AL_FUNC(void, al_unref_user_event, (ALLEGRO_USER_EVENT *)); +AL_FUNC(void, al_set_event_source_data, (ALLEGRO_EVENT_SOURCE*, intptr_t data)); +AL_FUNC(intptr_t, al_get_event_source_data, (const ALLEGRO_EVENT_SOURCE*)); + + + +/* Event queues */ + +/* Type: ALLEGRO_EVENT_QUEUE + */ +typedef struct ALLEGRO_EVENT_QUEUE ALLEGRO_EVENT_QUEUE; + +AL_FUNC(ALLEGRO_EVENT_QUEUE*, al_create_event_queue, (void)); +AL_FUNC(void, al_destroy_event_queue, (ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(void, al_register_event_source, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT_SOURCE*)); +AL_FUNC(void, al_unregister_event_source, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT_SOURCE*)); +AL_FUNC(void, al_pause_event_queue, (ALLEGRO_EVENT_QUEUE*, bool)); +AL_FUNC(bool, al_is_event_queue_paused, (const ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(bool, al_is_event_queue_empty, (ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(bool, al_get_next_event, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT *ret_event)); +AL_FUNC(bool, al_peek_next_event, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT *ret_event)); +AL_FUNC(bool, al_drop_next_event, (ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(void, al_flush_event_queue, (ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(void, al_wait_for_event, (ALLEGRO_EVENT_QUEUE*, + ALLEGRO_EVENT *ret_event)); +AL_FUNC(bool, al_wait_for_event_timed, (ALLEGRO_EVENT_QUEUE*, + ALLEGRO_EVENT *ret_event, + float secs)); +AL_FUNC(bool, al_wait_for_event_until, (ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT *ret_event, + ALLEGRO_TIMEOUT *timeout)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/file.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/file.h new file mode 100644 index 00000000..b1873e8e --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/file.h @@ -0,0 +1,107 @@ +#ifndef __al_included_allegro5_file_h +#define __al_included_allegro5_file_h + +#include "allegro5/base.h" +#include "allegro5/path.h" +#include "allegro5/utf8.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_FILE + */ +typedef struct ALLEGRO_FILE ALLEGRO_FILE; + + +/* Type: ALLEGRO_FILE_INTERFACE + */ +typedef struct ALLEGRO_FILE_INTERFACE +{ + AL_METHOD(void *, fi_fopen, (const char *path, const char *mode)); + AL_METHOD(bool, fi_fclose, (ALLEGRO_FILE *handle)); + AL_METHOD(size_t, fi_fread, (ALLEGRO_FILE *f, void *ptr, size_t size)); + AL_METHOD(size_t, fi_fwrite, (ALLEGRO_FILE *f, const void *ptr, size_t size)); + AL_METHOD(bool, fi_fflush, (ALLEGRO_FILE *f)); + AL_METHOD(int64_t, fi_ftell, (ALLEGRO_FILE *f)); + AL_METHOD(bool, fi_fseek, (ALLEGRO_FILE *f, int64_t offset, int whence)); + AL_METHOD(bool, fi_feof, (ALLEGRO_FILE *f)); + AL_METHOD(int, fi_ferror, (ALLEGRO_FILE *f)); + AL_METHOD(const char *, fi_ferrmsg, (ALLEGRO_FILE *f)); + AL_METHOD(void, fi_fclearerr, (ALLEGRO_FILE *f)); + AL_METHOD(int, fi_fungetc, (ALLEGRO_FILE *f, int c)); + AL_METHOD(off_t, fi_fsize, (ALLEGRO_FILE *f)); +} ALLEGRO_FILE_INTERFACE; + + +/* Enum: ALLEGRO_SEEK + */ +typedef enum ALLEGRO_SEEK +{ + ALLEGRO_SEEK_SET = 0, + ALLEGRO_SEEK_CUR, + ALLEGRO_SEEK_END +} ALLEGRO_SEEK; + + +/* The basic operations. */ +AL_FUNC(ALLEGRO_FILE*, al_fopen, (const char *path, const char *mode)); +AL_FUNC(ALLEGRO_FILE*, al_fopen_interface, (const ALLEGRO_FILE_INTERFACE *vt, const char *path, const char *mode)); +AL_FUNC(ALLEGRO_FILE*, al_create_file_handle, (const ALLEGRO_FILE_INTERFACE *vt, void *userdata)); +AL_FUNC(bool, al_fclose, (ALLEGRO_FILE *f)); +AL_FUNC(size_t, al_fread, (ALLEGRO_FILE *f, void *ptr, size_t size)); +AL_FUNC(size_t, al_fwrite, (ALLEGRO_FILE *f, const void *ptr, size_t size)); +AL_FUNC(bool, al_fflush, (ALLEGRO_FILE *f)); +AL_FUNC(int64_t, al_ftell, (ALLEGRO_FILE *f)); +AL_FUNC(bool, al_fseek, (ALLEGRO_FILE *f, int64_t offset, int whence)); +AL_FUNC(bool, al_feof, (ALLEGRO_FILE *f)); +AL_FUNC(int, al_ferror, (ALLEGRO_FILE *f)); +AL_FUNC(const char *, al_ferrmsg, (ALLEGRO_FILE *f)); +AL_FUNC(void, al_fclearerr, (ALLEGRO_FILE *f)); +AL_FUNC(int, al_fungetc, (ALLEGRO_FILE *f, int c)); +AL_FUNC(int64_t, al_fsize, (ALLEGRO_FILE *f)); + +/* Convenience functions. */ +AL_FUNC(int, al_fgetc, (ALLEGRO_FILE *f)); +AL_FUNC(int, al_fputc, (ALLEGRO_FILE *f, int c)); +AL_FUNC(int16_t, al_fread16le, (ALLEGRO_FILE *f)); +AL_FUNC(int16_t, al_fread16be, (ALLEGRO_FILE *f)); +AL_FUNC(size_t, al_fwrite16le, (ALLEGRO_FILE *f, int16_t w)); +AL_FUNC(size_t, al_fwrite16be, (ALLEGRO_FILE *f, int16_t w)); +AL_FUNC(int32_t, al_fread32le, (ALLEGRO_FILE *f)); +AL_FUNC(int32_t, al_fread32be, (ALLEGRO_FILE *f)); +AL_FUNC(size_t, al_fwrite32le, (ALLEGRO_FILE *f, int32_t l)); +AL_FUNC(size_t, al_fwrite32be, (ALLEGRO_FILE *f, int32_t l)); +AL_FUNC(char*, al_fgets, (ALLEGRO_FILE *f, char * const p, size_t max)); +AL_FUNC(ALLEGRO_USTR *, al_fget_ustr, (ALLEGRO_FILE *f)); +AL_FUNC(int, al_fputs, (ALLEGRO_FILE *f, const char *p)); +AL_FUNC(int, al_fprintf, (ALLEGRO_FILE *f, const char *format, ...)); +AL_FUNC(int, al_vfprintf, (ALLEGRO_FILE *f, const char* format, va_list args)); + +/* Specific to stdio backend. */ +AL_FUNC(ALLEGRO_FILE*, al_fopen_fd, (int fd, const char *mode)); +AL_FUNC(ALLEGRO_FILE*, al_make_temp_file, (const char *tmpl, + ALLEGRO_PATH **ret_path)); + +/* Specific to slices. */ +AL_FUNC(ALLEGRO_FILE*, al_fopen_slice, (ALLEGRO_FILE *fp, + size_t initial_size, const char *mode)); + +/* Thread-local state. */ +AL_FUNC(const ALLEGRO_FILE_INTERFACE *, al_get_new_file_interface, (void)); +AL_FUNC(void, al_set_new_file_interface, (const ALLEGRO_FILE_INTERFACE * + file_interface)); +AL_FUNC(void, al_set_standard_file_interface, (void)); + +/* ALLEGRO_FILE field accessors */ +AL_FUNC(void *, al_get_file_userdata, (ALLEGRO_FILE *f)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fixed.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fixed.h new file mode 100644 index 00000000..7ecc79e7 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fixed.h @@ -0,0 +1,41 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Fixed point type. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_fixed_h +#define __al_included_allegro5_fixed_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: al_fixed + */ +typedef int32_t al_fixed; + +AL_VAR(const al_fixed, al_fixtorad_r); +AL_VAR(const al_fixed, al_radtofix_r); + +#ifdef __cplusplus + } +#endif + +#endif + + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fmaths.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fmaths.h new file mode 100644 index 00000000..e94e4cab --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fmaths.h @@ -0,0 +1,46 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Fixed point math routines. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_fmaths_h +#define __al_included_allegro5_fmaths_h + +#include "allegro5/base.h" +#include "allegro5/fixed.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(al_fixed, al_fixsqrt, (al_fixed x)); +AL_FUNC(al_fixed, al_fixhypot, (al_fixed x, al_fixed y)); +AL_FUNC(al_fixed, al_fixatan, (al_fixed x)); +AL_FUNC(al_fixed, al_fixatan2, (al_fixed y, al_fixed x)); + +AL_ARRAY(al_fixed, _al_fix_cos_tbl); +AL_ARRAY(al_fixed, _al_fix_tan_tbl); +AL_ARRAY(al_fixed, _al_fix_acos_tbl); + +#ifdef __cplusplus + } +#endif + +#include "allegro5/inline/fmaths.inl" + +#endif + + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fshook.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fshook.h new file mode 100644 index 00000000..dcd35b68 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fshook.h @@ -0,0 +1,148 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * File System Hooks. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_fshook_h +#define __al_included_allegro5_fshook_h + +#include "allegro5/base.h" +#include "allegro5/file.h" +#include "allegro5/path.h" + +#ifdef ALLEGRO_HAVE_SYS_TYPES_H + #include +#else +/* 4 Gig max offsets if sys/types doesn't exist. */ +typedef unsigned int off_t; +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_FS_ENTRY + */ +typedef struct ALLEGRO_FS_ENTRY ALLEGRO_FS_ENTRY; + +struct ALLEGRO_FS_ENTRY { + struct ALLEGRO_FS_INTERFACE const *vtable; +}; + + +/* Enum: ALLEGRO_FILE_MODE + */ +typedef enum ALLEGRO_FILE_MODE +{ + ALLEGRO_FILEMODE_READ = 1, + ALLEGRO_FILEMODE_WRITE = 1 << 1, + ALLEGRO_FILEMODE_EXECUTE = 1 << 2, + ALLEGRO_FILEMODE_HIDDEN = 1 << 3, + ALLEGRO_FILEMODE_ISFILE = 1 << 4, + ALLEGRO_FILEMODE_ISDIR = 1 << 5 +} ALLEGRO_FILE_MODE; + + +#ifndef EOF + #define EOF (-1) +#endif + + +/* Type: ALLEGRO_FS_INTERFACE + */ +typedef struct ALLEGRO_FS_INTERFACE ALLEGRO_FS_INTERFACE; + +struct ALLEGRO_FS_INTERFACE { + AL_METHOD(ALLEGRO_FS_ENTRY *, fs_create_entry, (const char *path)); + AL_METHOD(void, fs_destroy_entry, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(const char *, fs_entry_name, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(bool, fs_update_entry, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(uint32_t, fs_entry_mode, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(time_t, fs_entry_atime, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(time_t, fs_entry_mtime, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(time_t, fs_entry_ctime, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(off_t, fs_entry_size, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(bool, fs_entry_exists, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(bool, fs_remove_entry, (ALLEGRO_FS_ENTRY *e)); + + AL_METHOD(bool, fs_open_directory, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(ALLEGRO_FS_ENTRY *, fs_read_directory,(ALLEGRO_FS_ENTRY *e)); + AL_METHOD(bool, fs_close_directory, (ALLEGRO_FS_ENTRY *e)); + + AL_METHOD(bool, fs_filename_exists, (const char *path)); + AL_METHOD(bool, fs_remove_filename, (const char *path)); + AL_METHOD(char *, fs_get_current_directory, (void)); + AL_METHOD(bool, fs_change_directory, (const char *path)); + AL_METHOD(bool, fs_make_directory, (const char *path)); + + AL_METHOD(ALLEGRO_FILE *, fs_open_file, (ALLEGRO_FS_ENTRY *e, + const char *mode)); +}; + +AL_FUNC(ALLEGRO_FS_ENTRY *, al_create_fs_entry, (const char *path)); +AL_FUNC(void, al_destroy_fs_entry, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(const char *, al_get_fs_entry_name,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(bool, al_update_fs_entry, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(uint32_t, al_get_fs_entry_mode,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(time_t, al_get_fs_entry_atime,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(time_t, al_get_fs_entry_mtime,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(time_t, al_get_fs_entry_ctime,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(off_t, al_get_fs_entry_size,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(bool, al_fs_entry_exists, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(bool, al_remove_fs_entry, (ALLEGRO_FS_ENTRY *e)); + +AL_FUNC(bool, al_open_directory, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(ALLEGRO_FS_ENTRY *, al_read_directory, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(bool, al_close_directory, (ALLEGRO_FS_ENTRY *e)); + +AL_FUNC(bool, al_filename_exists, (const char *path)); +AL_FUNC(bool, al_remove_filename, (const char *path)); +AL_FUNC(char *, al_get_current_directory, (void)); +AL_FUNC(bool, al_change_directory, (const char *path)); +AL_FUNC(bool, al_make_directory, (const char *path)); + +AL_FUNC(ALLEGRO_FILE *, al_open_fs_entry, (ALLEGRO_FS_ENTRY *e, + const char *mode)); + + + +/* Helper function for iterating over a directory using a callback. */ + +/* Type: ALLEGRO_FOR_EACH_FS_ENTRY_RESULT + */ +typedef enum ALLEGRO_FOR_EACH_FS_ENTRY_RESULT { + ALLEGRO_FOR_EACH_FS_ENTRY_ERROR = -1, + ALLEGRO_FOR_EACH_FS_ENTRY_OK = 0, + ALLEGRO_FOR_EACH_FS_ENTRY_SKIP = 1, + ALLEGRO_FOR_EACH_FS_ENTRY_STOP = 2 +} ALLEGRO_FOR_EACH_FS_ENTRY_RESULT; + +AL_FUNC(int, al_for_each_fs_entry, (ALLEGRO_FS_ENTRY *dir, + int (*callback)(ALLEGRO_FS_ENTRY *entry, void *extra), + void *extra)); + + +/* Thread-local state. */ +AL_FUNC(const ALLEGRO_FS_INTERFACE *, al_get_fs_interface, (void)); +AL_FUNC(void, al_set_fs_interface, (const ALLEGRO_FS_INTERFACE *vtable)); +AL_FUNC(void, al_set_standard_fs_interface, (void)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fullscreen_mode.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fullscreen_mode.h new file mode 100644 index 00000000..4f5cb777 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/fullscreen_mode.h @@ -0,0 +1,31 @@ +#ifndef __al_included_allegro5_fullscreen_mode_h +#define __al_included_allegro5_fullscreen_mode_h + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_DISPLAY_MODE + */ +typedef struct ALLEGRO_DISPLAY_MODE +{ + int width; + int height; + int format; + int refresh_rate; +} ALLEGRO_DISPLAY_MODE; + + +AL_FUNC(int, al_get_num_display_modes, (void)); +AL_FUNC(ALLEGRO_DISPLAY_MODE*, al_get_display_mode, (int index, + ALLEGRO_DISPLAY_MODE *mode)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/haptic.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/haptic.h new file mode 100644 index 00000000..bbb0e553 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/haptic.h @@ -0,0 +1,245 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Haptic (that is, force feedback) routines for Allegro. + * + * By Beoran. + * + * See LICENSE.txt for copyright information. + */ + +#ifndef __al_included_allegro5_haptic_h +#define __al_included_allegro5_haptic_h + +#include "allegro5/base.h" +#include "allegro5/display.h" +#include "allegro5/events.h" +#include "allegro5/joystick.h" +#include "allegro5/keyboard.h" +#include "allegro5/mouse.h" +#include "allegro5/touch_input.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Enum: ALLEGRO_HAPTIC_CONSTANTS + */ +enum ALLEGRO_HAPTIC_CONSTANTS +{ + ALLEGRO_HAPTIC_RUMBLE = 1 << 0, + ALLEGRO_HAPTIC_PERIODIC = 1 << 1, + ALLEGRO_HAPTIC_CONSTANT = 1 << 2, + ALLEGRO_HAPTIC_SPRING = 1 << 3, + ALLEGRO_HAPTIC_FRICTION = 1 << 4, + ALLEGRO_HAPTIC_DAMPER = 1 << 5, + ALLEGRO_HAPTIC_INERTIA = 1 << 6, + ALLEGRO_HAPTIC_RAMP = 1 << 7, + ALLEGRO_HAPTIC_SQUARE = 1 << 8, + ALLEGRO_HAPTIC_TRIANGLE = 1 << 9, + ALLEGRO_HAPTIC_SINE = 1 << 10, + ALLEGRO_HAPTIC_SAW_UP = 1 << 11, + ALLEGRO_HAPTIC_SAW_DOWN = 1 << 12, + ALLEGRO_HAPTIC_CUSTOM = 1 << 13, + ALLEGRO_HAPTIC_GAIN = 1 << 14, + ALLEGRO_HAPTIC_ANGLE = 1 << 15, + ALLEGRO_HAPTIC_RADIUS = 1 << 16, + ALLEGRO_HAPTIC_AZIMUTH = 1 << 17, + ALLEGRO_HAPTIC_AUTOCENTER= 1 << 18, +}; + + + +/* Type: ALLEGRO_HAPTIC + */ +typedef struct ALLEGRO_HAPTIC ALLEGRO_HAPTIC; + +/* Direction of a haptic effect. Angle is a value between 0 and 2*M_PI. + * An angle 0 means oriented towards the user, M_PI is away from the user + * (towards the screen). Angle is only supported if the device capabilities + * include ALLEGRO_HAPTIC_ANGLE. + * + * Radius (if supported) is the distance of the effect from the user as a + * value between 0 and 1. Normally it is zero. Radius is only supported if the + * device capabilities include ALLEGRO_HAPTIC_RADIUS. + * + * Azimuth is the angle of elevation, between -M_PI/2 and M_PI/2. + * Zero points to the horizontal plane, -M_PI/2 points down, and M_PI/2 points + * up. Azimuth is only supported if the device capabilities include + * ALLEGRO_HAPTIC_AZIMUTH. + */ +struct ALLEGRO_HAPTIC_DIRECTION +{ + double angle; + double radius; + double azimuth; +}; + +/* In all of the following structs, the doubles that express duration + * represent time in seconds. The double that represent levels of intensity + * are between 0.0 and 1.0. + */ + +/* Delay to start the replay and duration of the replay, expressed in seconds. */ +struct ALLEGRO_HAPTIC_REPLAY +{ + double length; + double delay; +}; + +/* Envelope of the effect. */ +struct ALLEGRO_HAPTIC_ENVELOPE +{ + double attack_length; + double attack_level; + double fade_length; + double fade_level; +}; + +/* Constant effect. Level is between 0.0 and 1.0. */ +struct ALLEGRO_HAPTIC_CONSTANT_EFFECT +{ + double level; + struct ALLEGRO_HAPTIC_ENVELOPE envelope; +}; + +/* Ramp effect. Both start_level and end level are between 0.0 and 1.0. */ +struct ALLEGRO_HAPTIC_RAMP_EFFECT +{ + double start_level; + double end_level; + struct ALLEGRO_HAPTIC_ENVELOPE envelope; +}; + +/* Condition effect. */ +struct ALLEGRO_HAPTIC_CONDITION_EFFECT +{ + double right_saturation; + double left_saturation; + double right_coeff; + double left_coeff; + double deadband; + double center; +}; + +/* Periodic (wave) effect. */ +struct ALLEGRO_HAPTIC_PERIODIC_EFFECT +{ + int waveform; + double period; + double magnitude; + double offset; + double phase; + + struct ALLEGRO_HAPTIC_ENVELOPE envelope; + int custom_len; + double *custom_data; +}; + +/* Simple rumble effect with a magnitude between 0.0 and 1.0 for both + * the strong and the weak rumble motors in the haptic device. + */ +struct ALLEGRO_HAPTIC_RUMBLE_EFFECT +{ + double strong_magnitude; + double weak_magnitude; +}; + +union ALLEGRO_HAPTIC_EFFECT_UNION +{ + struct ALLEGRO_HAPTIC_CONSTANT_EFFECT constant; + struct ALLEGRO_HAPTIC_RAMP_EFFECT ramp; + struct ALLEGRO_HAPTIC_PERIODIC_EFFECT periodic; + struct ALLEGRO_HAPTIC_CONDITION_EFFECT condition; + struct ALLEGRO_HAPTIC_RUMBLE_EFFECT rumble; +}; + + +/* Type: ALLEGRO_HAPTIC_EFFECT + */ +struct ALLEGRO_HAPTIC_EFFECT +{ + + int type; + struct ALLEGRO_HAPTIC_DIRECTION direction; + struct ALLEGRO_HAPTIC_REPLAY replay; + union ALLEGRO_HAPTIC_EFFECT_UNION data; +}; + +typedef struct ALLEGRO_HAPTIC_EFFECT ALLEGRO_HAPTIC_EFFECT; + + +/* Type: ALLEGRO_HAPTIC_EFFECT_ID + */ +typedef struct ALLEGRO_HAPTIC_EFFECT_ID ALLEGRO_HAPTIC_EFFECT_ID; + +struct ALLEGRO_HAPTIC_EFFECT_ID +{ + ALLEGRO_HAPTIC *_haptic; + int _id; + int _handle; + void * _pointer; + double _effect_duration; + bool _playing; + double _start_time; + double _end_time; + void * driver; +}; + + +AL_FUNC(bool, al_install_haptic, (void)); +AL_FUNC(void, al_uninstall_haptic, (void)); +AL_FUNC(bool, al_is_haptic_installed, (void)); + +AL_FUNC(bool, al_is_mouse_haptic, (ALLEGRO_MOUSE *)); +AL_FUNC(bool, al_is_joystick_haptic, (ALLEGRO_JOYSTICK *)); +AL_FUNC(bool, al_is_keyboard_haptic, (ALLEGRO_KEYBOARD *)); +AL_FUNC(bool, al_is_display_haptic, (ALLEGRO_DISPLAY *)); +AL_FUNC(bool, al_is_touch_input_haptic, (ALLEGRO_TOUCH_INPUT *)); + +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_mouse, (ALLEGRO_MOUSE *)); +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_joystick, (ALLEGRO_JOYSTICK *)); +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_keyboard, (ALLEGRO_KEYBOARD *)); +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_display, (ALLEGRO_DISPLAY *)); +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_touch_input, (ALLEGRO_TOUCH_INPUT *)); + +AL_FUNC(bool, al_release_haptic, (ALLEGRO_HAPTIC *)); + +AL_FUNC(bool, al_is_haptic_active, (ALLEGRO_HAPTIC *)); +AL_FUNC(int, al_get_haptic_capabilities, (ALLEGRO_HAPTIC *)); +AL_FUNC(bool, al_is_haptic_capable, (ALLEGRO_HAPTIC *, int)); + +AL_FUNC(bool, al_set_haptic_gain, (ALLEGRO_HAPTIC *, double)); +AL_FUNC(double, al_get_haptic_gain, (ALLEGRO_HAPTIC *)); + +AL_FUNC(bool, al_set_haptic_autocenter, (ALLEGRO_HAPTIC *, double)); +AL_FUNC(double, al_get_haptic_autocenter, (ALLEGRO_HAPTIC *)); + + +AL_FUNC(int, al_get_max_haptic_effects, (ALLEGRO_HAPTIC *)); +AL_FUNC(bool, al_is_haptic_effect_ok, (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *)); +AL_FUNC(bool, al_upload_haptic_effect, (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, ALLEGRO_HAPTIC_EFFECT_ID *)); +AL_FUNC(bool, al_play_haptic_effect, (ALLEGRO_HAPTIC_EFFECT_ID *, int)); +AL_FUNC(bool, al_upload_and_play_haptic_effect, (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, ALLEGRO_HAPTIC_EFFECT_ID *, int)); +AL_FUNC(bool, al_stop_haptic_effect, (ALLEGRO_HAPTIC_EFFECT_ID *)); +AL_FUNC(bool, al_is_haptic_effect_playing, (ALLEGRO_HAPTIC_EFFECT_ID *)); +AL_FUNC(bool, al_release_haptic_effect, (ALLEGRO_HAPTIC_EFFECT_ID *)); +AL_FUNC(double, al_get_haptic_effect_duration, (ALLEGRO_HAPTIC_EFFECT *)); +AL_FUNC(bool, al_rumble_haptic, (ALLEGRO_HAPTIC *, double, double, ALLEGRO_HAPTIC_EFFECT_ID *)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/inline/fmaths.inl b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/inline/fmaths.inl new file mode 100644 index 00000000..ca669e89 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/inline/fmaths.inl @@ -0,0 +1,254 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Fixed point math inline functions (generic C). + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_inline_fmaths_inl +#define __al_included_allegro5_inline_fmaths_inl + +#include "allegro5/error.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* al_ftofix and al_fixtof are used in generic C versions of al_fixmul and al_fixdiv */ +AL_INLINE(al_fixed, al_ftofix, (double x), +{ + if (x > 32767.0) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + + if (x < -32767.0) { + al_set_errno(ERANGE); + return -0x7FFFFFFF; + } + + return (al_fixed)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); +}) + + +AL_INLINE(double, al_fixtof, (al_fixed x), +{ + return (double)x / 65536.0; +}) + + +AL_INLINE(al_fixed, al_fixadd, (al_fixed x, al_fixed y), +{ + al_fixed result = x + y; + + if (result >= 0) { + if ((x < 0) && (y < 0)) { + al_set_errno(ERANGE); + return -0x7FFFFFFF; + } + else + return result; + } + else { + if ((x > 0) && (y > 0)) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + else + return result; + } +}) + + +AL_INLINE(al_fixed, al_fixsub, (al_fixed x, al_fixed y), +{ + al_fixed result = x - y; + + if (result >= 0) { + if ((x < 0) && (y > 0)) { + al_set_errno(ERANGE); + return -0x7FFFFFFF; + } + else + return result; + } + else { + if ((x > 0) && (y < 0)) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + else + return result; + } +}) + + +/* In benchmarks conducted circa May 2005 we found that, in the main: + * - IA32 machines performed faster with one implementation; + * - AMD64 and G4 machines performed faster with another implementation. + * + * Benchmarks were mainly done with differing versions of gcc. + * Results varied with other compilers, optimisation levels, etc. + * so this is not optimal, though a tenable compromise. + * + * Note that the following implementation are NOT what were benchmarked. + * We had forgotten to put in overflow detection in those versions. + * If you don't need overflow detection then previous versions in the + * CVS tree might be worth looking at. + * + * PS. Don't move the #ifs inside the AL_INLINE; BCC doesn't like it. + */ +#if (defined ALLEGRO_I386) || (!defined LONG_LONG) + AL_INLINE(al_fixed, al_fixmul, (al_fixed x, al_fixed y), + { + return al_ftofix(al_fixtof(x) * al_fixtof(y)); + }) +#else + AL_INLINE(al_fixed, al_fixmul, (al_fixed x, al_fixed y), + { + LONG_LONG lx = x; + LONG_LONG ly = y; + LONG_LONG lres = (lx*ly); + + if (lres > 0x7FFFFFFF0000LL) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + else if (lres < -0x7FFFFFFF0000LL) { + al_set_errno(ERANGE); + return 0x80000000; + } + else { + int res = lres >> 16; + return res; + } + }) +#endif /* al_fixmul() C implementations */ + + +#if (defined ALLEGRO_CFG_NO_FPU) && (defined LONG_LONG) +AL_INLINE(al_fixed, al_fixdiv, (al_fixed x, al_fixed y), +{ + LONG_LONG lres = x; + if (y == 0) { + al_set_errno(ERANGE); + return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF; + } + lres <<= 16; + lres /= y; + if (lres > 0x7FFFFFFF) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + else if (lres < -0x7FFFFFFF) { + al_set_errno(ERANGE); + return 0x80000000; + } + else { + return (al_fixed)(lres); + } +}) +#else +AL_INLINE(al_fixed, al_fixdiv, (al_fixed x, al_fixed y), +{ + if (y == 0) { + al_set_errno(ERANGE); + return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF; + } + else + return al_ftofix(al_fixtof(x) / al_fixtof(y)); +}) +#endif + + +AL_INLINE(int, al_fixfloor, (al_fixed x), +{ + /* (x >> 16) is not portable */ + if (x >= 0) + return (x >> 16); + else + return ~((~x) >> 16); +}) + + +AL_INLINE(int, al_fixceil, (al_fixed x), +{ + if (x > 0x7FFF0000) { + al_set_errno(ERANGE); + return 0x7FFF; + } + + return al_fixfloor(x + 0xFFFF); +}) + + +AL_INLINE(al_fixed, al_itofix, (int x), +{ + return x << 16; +}) + + +AL_INLINE(int, al_fixtoi, (al_fixed x), +{ + return al_fixfloor(x) + ((x & 0x8000) >> 15); +}) + + +AL_INLINE(al_fixed, al_fixcos, (al_fixed x), +{ + return _al_fix_cos_tbl[((x + 0x4000) >> 15) & 0x1FF]; +}) + + +AL_INLINE(al_fixed, al_fixsin, (al_fixed x), +{ + return _al_fix_cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF]; +}) + + +AL_INLINE(al_fixed, al_fixtan, (al_fixed x), +{ + return _al_fix_tan_tbl[((x + 0x4000) >> 15) & 0xFF]; +}) + + +AL_INLINE(al_fixed, al_fixacos, (al_fixed x), +{ + if ((x < -65536) || (x > 65536)) { + al_set_errno(EDOM); + return 0; + } + + return _al_fix_acos_tbl[(x+65536+127)>>8]; +}) + + +AL_INLINE(al_fixed, al_fixasin, (al_fixed x), +{ + if ((x < -65536) || (x > 65536)) { + al_set_errno(EDOM); + return 0; + } + + return 0x00400000 - _al_fix_acos_tbl[(x+65536+127)>>8]; +}) + +#ifdef __cplusplus + } +#endif + +#endif + + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/internal/alconfig.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/internal/alconfig.h new file mode 100644 index 00000000..36475692 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/internal/alconfig.h @@ -0,0 +1,268 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +/* for backward compatibility */ +#ifdef USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN + #define ALLEGRO_USE_CONSOLE +#endif + + +/* include platform-specific stuff */ + +#include "allegro5/platform/alplatf.h" + + + +#if defined ALLEGRO_WATCOM + #include "allegro5/platform/alwatcom.h" +#elif defined ALLEGRO_MINGW32 + #include "allegro5/platform/almngw32.h" +#elif defined ALLEGRO_BCC32 + #include "allegro5/platform/albcc32.h" +#elif defined ALLEGRO_MSVC + #include "allegro5/platform/almsvc.h" +#elif defined ALLEGRO_IPHONE + #include "allegro5/platform/aliphonecfg.h" +#elif defined ALLEGRO_MACOSX + #include "allegro5/platform/alosxcfg.h" +#elif defined ALLEGRO_ANDROID + #include "allegro5/platform/alandroidcfg.h" +#elif defined ALLEGRO_RASPBERRYPI + #include "allegro5/platform/alraspberrypicfg.h" +#elif defined ALLEGRO_UNIX + #include "allegro5/platform/alucfg.h" +#elif defined ALLEGRO_SDL + #include "allegro5/platform/allegro_sdl_config.h" +#else + #error platform not supported +#endif + + +#include "allegro5/platform/astdint.h" +#include "allegro5/platform/astdbool.h" + + + +/* special definitions for the GCC compiler */ +#ifdef __GNUC__ + #define ALLEGRO_GCC + + #ifndef AL_INLINE + #ifdef __cplusplus + #define AL_INLINE(type, name, args, code) \ + static inline type name args; \ + static inline type name args code + /* Needed if this header is included by C99 code, as + * "extern __inline__" in C99 exports a new global function. + */ + #elif __GNUC_STDC_INLINE__ + #define AL_INLINE(type, name, args, code) \ + extern __inline__ __attribute__((__gnu_inline__)) type name args; \ + extern __inline__ __attribute__((__gnu_inline__)) type name args code + #else + #define AL_INLINE(type, name, args, code) \ + extern __inline__ type name args; \ + extern __inline__ type name args code + #endif + #endif + + #ifndef AL_INLINE_STATIC + #ifdef __cplusplus + #define AL_INLINE_STATIC(type, name, args, code) \ + AL_INLINE(type, name, args, code) + #else + #define AL_INLINE_STATIC(type, name, args, code) \ + static __inline__ type name args; \ + static __inline__ type name args code + #endif + #endif + + #define AL_PRINTFUNC(type, name, args, a, b) AL_FUNC(type, name, args) __attribute__ ((format (printf, a, b))) + + #ifndef INLINE + #define INLINE __inline__ + #endif + + #ifndef ZERO_SIZE_ARRAY + #if __GNUC__ < 3 + #define ZERO_SIZE_ARRAY(type, name) __extension__ type name[0] + #else + #define ZERO_SIZE_ARRAY(type, name) type name[] /* ISO C99 flexible array members */ + #endif + #endif + + #ifndef LONG_LONG + #define LONG_LONG long long + #ifdef ALLEGRO_GUESS_INTTYPES_OK + #define int64_t signed long long + #define uint64_t unsigned long long + #endif + #endif + + #ifdef __i386__ + #define ALLEGRO_I386 + #endif + + #ifdef __amd64__ + #define ALLEGRO_AMD64 + #endif + + #ifdef __arm__ + #define ALLEGRO_ARM + #endif + + #ifndef AL_FUNC_DEPRECATED + #if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) + #define AL_FUNC_DEPRECATED(type, name, args) AL_FUNC(__attribute__ ((deprecated)) type, name, args) + #define AL_PRINTFUNC_DEPRECATED(type, name, args, a, b) AL_PRINTFUNC(__attribute__ ((deprecated)) type, name, args, a, b) + #define AL_INLINE_DEPRECATED(type, name, args, code) AL_INLINE(__attribute__ ((deprecated)) type, name, args, code) + #endif + #endif + + #ifndef AL_ALIAS + #define AL_ALIAS(DECL, CALL) \ + static __attribute__((unused)) __inline__ DECL \ + { \ + return CALL; \ + } + #endif + + #ifndef AL_ALIAS_VOID_RET + #define AL_ALIAS_VOID_RET(DECL, CALL) \ + static __attribute__((unused)) __inline__ void DECL \ + { \ + CALL; \ + } + #endif +#endif + + +/* the rest of this file fills in some default definitions of language + * features and helper functions, which are conditionalised so they will + * only be included if none of the above headers defined custom versions. + */ + +#ifndef INLINE + #define INLINE +#endif + +#ifndef ZERO_SIZE_ARRAY + #define ZERO_SIZE_ARRAY(type, name) type name[] +#endif + +#ifndef AL_VAR + #define AL_VAR(type, name) extern type name +#endif + +#ifndef AL_ARRAY + #define AL_ARRAY(type, name) extern type name[] +#endif + +#ifndef AL_FUNC + #define AL_FUNC(type, name, args) type name args +#endif + +#ifndef AL_PRINTFUNC + #define AL_PRINTFUNC(type, name, args, a, b) AL_FUNC(type, name, args) +#endif + +#ifndef AL_METHOD + #define AL_METHOD(type, name, args) type (*name) args +#endif + +#ifndef AL_FUNCPTR + #define AL_FUNCPTR(type, name, args) extern type (*name) args +#endif + +#ifndef AL_FUNCPTRARRAY + #define AL_FUNCPTRARRAY(type, name, args) extern type (*name[]) args +#endif + +#ifndef AL_INLINE + #define AL_INLINE(type, name, args, code) type name args; +#endif + +#ifndef AL_FUNC_DEPRECATED + #define AL_FUNC_DEPRECATED(type, name, args) AL_FUNC(type, name, args) + #define AL_PRINTFUNC_DEPRECATED(type, name, args, a, b) AL_PRINTFUNC(type, name, args, a, b) + #define AL_INLINE_DEPRECATED(type, name, args, code) AL_INLINE(type, name, args, code) +#endif + +#ifndef AL_ALIAS + #define AL_ALIAS(DECL, CALL) \ + static INLINE DECL \ + { \ + return CALL; \ + } +#endif + +#ifndef AL_ALIAS_VOID_RET + #define AL_ALIAS_VOID_RET(DECL, CALL) \ + static INLINE void DECL \ + { \ + CALL; \ + } +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + + +/* endian-independent 3-byte accessor macros */ +#ifdef ALLEGRO_LITTLE_ENDIAN + + #define READ3BYTES(p) ((*(unsigned char *)(p)) \ + | (*((unsigned char *)(p) + 1) << 8) \ + | (*((unsigned char *)(p) + 2) << 16)) + + #define WRITE3BYTES(p,c) ((*(unsigned char *)(p) = (c)), \ + (*((unsigned char *)(p) + 1) = (c) >> 8), \ + (*((unsigned char *)(p) + 2) = (c) >> 16)) + +#elif defined ALLEGRO_BIG_ENDIAN + + #define READ3BYTES(p) ((*(unsigned char *)(p) << 16) \ + | (*((unsigned char *)(p) + 1) << 8) \ + | (*((unsigned char *)(p) + 2))) + + #define WRITE3BYTES(p,c) ((*(unsigned char *)(p) = (c) >> 16), \ + (*((unsigned char *)(p) + 1) = (c) >> 8), \ + (*((unsigned char *)(p) + 2) = (c))) + +#else + #error endianess not defined +#endif + + +/* generic versions of the video memory access helpers */ +/* FIXME: why do we need macros for this? */ +#define bmp_write16(addr, c) (*((uint16_t *)(addr)) = (c)) +#define bmp_write32(addr, c) (*((uint32_t *)(addr)) = (c)) + +#define bmp_read16(addr) (*((uint16_t *)(addr))) +#define bmp_read32(addr) (*((uint32_t *)(addr))) + + + +#ifdef __cplusplus + } +#endif + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/joystick.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/joystick.h new file mode 100644 index 00000000..4b3e648b --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/joystick.h @@ -0,0 +1,91 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Joystick routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_joystick_h +#define __al_included_allegro5_joystick_h + +#include "allegro5/base.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* internal values */ +#define _AL_MAX_JOYSTICK_AXES 3 +#define _AL_MAX_JOYSTICK_STICKS 16 +#define _AL_MAX_JOYSTICK_BUTTONS 32 + + + +/* Type: ALLEGRO_JOYSTICK + */ +typedef struct ALLEGRO_JOYSTICK ALLEGRO_JOYSTICK; + + + +/* Type: ALLEGRO_JOYSTICK_STATE + */ +typedef struct ALLEGRO_JOYSTICK_STATE ALLEGRO_JOYSTICK_STATE; + +struct ALLEGRO_JOYSTICK_STATE +{ + struct { + float axis[_AL_MAX_JOYSTICK_AXES]; /* -1.0 to 1.0 */ + } stick[_AL_MAX_JOYSTICK_STICKS]; + int button[_AL_MAX_JOYSTICK_BUTTONS]; /* 0 to 32767 */ +}; + + +/* Enum: ALLEGRO_JOYFLAGS + */ +enum ALLEGRO_JOYFLAGS +{ + ALLEGRO_JOYFLAG_DIGITAL = 0x01, + ALLEGRO_JOYFLAG_ANALOGUE = 0x02 +}; + + + +AL_FUNC(bool, al_install_joystick, (void)); +AL_FUNC(void, al_uninstall_joystick, (void)); +AL_FUNC(bool, al_is_joystick_installed, (void)); +AL_FUNC(bool, al_reconfigure_joysticks, (void)); + +AL_FUNC(int, al_get_num_joysticks, (void)); +AL_FUNC(ALLEGRO_JOYSTICK *, al_get_joystick, (int joyn)); +AL_FUNC(void, al_release_joystick, (ALLEGRO_JOYSTICK *)); +AL_FUNC(bool, al_get_joystick_active, (ALLEGRO_JOYSTICK *)); +AL_FUNC(const char*, al_get_joystick_name, (ALLEGRO_JOYSTICK *)); + +AL_FUNC(int, al_get_joystick_num_sticks, (ALLEGRO_JOYSTICK *)); +AL_FUNC(int, al_get_joystick_stick_flags, (ALLEGRO_JOYSTICK *, int stick)); /* junk? */ +AL_FUNC(const char*, al_get_joystick_stick_name, (ALLEGRO_JOYSTICK *, int stick)); + +AL_FUNC(int, al_get_joystick_num_axes, (ALLEGRO_JOYSTICK *, int stick)); +AL_FUNC(const char*, al_get_joystick_axis_name, (ALLEGRO_JOYSTICK *, int stick, int axis)); + +AL_FUNC(int, al_get_joystick_num_buttons, (ALLEGRO_JOYSTICK *)); +AL_FUNC(const char*, al_get_joystick_button_name, (ALLEGRO_JOYSTICK *, int buttonn)); + +AL_FUNC(void, al_get_joystick_state, (ALLEGRO_JOYSTICK *, ALLEGRO_JOYSTICK_STATE *ret_state)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_joystick_event_source, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/keyboard.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/keyboard.h new file mode 100644 index 00000000..54aad116 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/keyboard.h @@ -0,0 +1,72 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Keyboard routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_keyboard_h +#define __al_included_allegro5_keyboard_h + +#include "allegro5/base.h" +#include "allegro5/events.h" +#include "allegro5/keycodes.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct ALLEGRO_KEYBOARD ALLEGRO_KEYBOARD; + + + +/* Type: ALLEGRO_KEYBOARD_STATE + */ +typedef struct ALLEGRO_KEYBOARD_STATE ALLEGRO_KEYBOARD_STATE; + +struct ALLEGRO_KEYBOARD_STATE +{ + struct ALLEGRO_DISPLAY *display; /* public */ + /* internal */ + unsigned int __key_down__internal__[(ALLEGRO_KEY_MAX + 31) / 32]; +}; + + +AL_FUNC(bool, al_is_keyboard_installed, (void)); +AL_FUNC(bool, al_install_keyboard, (void)); +AL_FUNC(void, al_uninstall_keyboard, (void)); + +AL_FUNC(bool, al_set_keyboard_leds, (int leds)); + +AL_FUNC(const char *, al_keycode_to_name, (int keycode)); + +AL_FUNC(void, al_get_keyboard_state, (ALLEGRO_KEYBOARD_STATE *ret_state)); +AL_FUNC(bool, al_key_down, (const ALLEGRO_KEYBOARD_STATE *, int keycode)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_keyboard_event_source, (void)); + + +/* TODO: use the config system */ +AL_VAR(bool, _al_three_finger_flag); +AL_VAR(bool, _al_key_led_flag); + +#ifdef __cplusplus + } +#endif + +#endif + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/keycodes.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/keycodes.h new file mode 100644 index 00000000..0a899017 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/keycodes.h @@ -0,0 +1,214 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Keycode constants. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_keycodes_h +#define __al_included_allegro5_keycodes_h + + + +/* Note these values are deliberately the same as in Allegro 4.1.x */ +enum +{ + ALLEGRO_KEY_A = 1, + ALLEGRO_KEY_B = 2, + ALLEGRO_KEY_C = 3, + ALLEGRO_KEY_D = 4, + ALLEGRO_KEY_E = 5, + ALLEGRO_KEY_F = 6, + ALLEGRO_KEY_G = 7, + ALLEGRO_KEY_H = 8, + ALLEGRO_KEY_I = 9, + ALLEGRO_KEY_J = 10, + ALLEGRO_KEY_K = 11, + ALLEGRO_KEY_L = 12, + ALLEGRO_KEY_M = 13, + ALLEGRO_KEY_N = 14, + ALLEGRO_KEY_O = 15, + ALLEGRO_KEY_P = 16, + ALLEGRO_KEY_Q = 17, + ALLEGRO_KEY_R = 18, + ALLEGRO_KEY_S = 19, + ALLEGRO_KEY_T = 20, + ALLEGRO_KEY_U = 21, + ALLEGRO_KEY_V = 22, + ALLEGRO_KEY_W = 23, + ALLEGRO_KEY_X = 24, + ALLEGRO_KEY_Y = 25, + ALLEGRO_KEY_Z = 26, + + ALLEGRO_KEY_0 = 27, + ALLEGRO_KEY_1 = 28, + ALLEGRO_KEY_2 = 29, + ALLEGRO_KEY_3 = 30, + ALLEGRO_KEY_4 = 31, + ALLEGRO_KEY_5 = 32, + ALLEGRO_KEY_6 = 33, + ALLEGRO_KEY_7 = 34, + ALLEGRO_KEY_8 = 35, + ALLEGRO_KEY_9 = 36, + + ALLEGRO_KEY_PAD_0 = 37, + ALLEGRO_KEY_PAD_1 = 38, + ALLEGRO_KEY_PAD_2 = 39, + ALLEGRO_KEY_PAD_3 = 40, + ALLEGRO_KEY_PAD_4 = 41, + ALLEGRO_KEY_PAD_5 = 42, + ALLEGRO_KEY_PAD_6 = 43, + ALLEGRO_KEY_PAD_7 = 44, + ALLEGRO_KEY_PAD_8 = 45, + ALLEGRO_KEY_PAD_9 = 46, + + ALLEGRO_KEY_F1 = 47, + ALLEGRO_KEY_F2 = 48, + ALLEGRO_KEY_F3 = 49, + ALLEGRO_KEY_F4 = 50, + ALLEGRO_KEY_F5 = 51, + ALLEGRO_KEY_F6 = 52, + ALLEGRO_KEY_F7 = 53, + ALLEGRO_KEY_F8 = 54, + ALLEGRO_KEY_F9 = 55, + ALLEGRO_KEY_F10 = 56, + ALLEGRO_KEY_F11 = 57, + ALLEGRO_KEY_F12 = 58, + + ALLEGRO_KEY_ESCAPE = 59, + ALLEGRO_KEY_TILDE = 60, + ALLEGRO_KEY_MINUS = 61, + ALLEGRO_KEY_EQUALS = 62, + ALLEGRO_KEY_BACKSPACE = 63, + ALLEGRO_KEY_TAB = 64, + ALLEGRO_KEY_OPENBRACE = 65, + ALLEGRO_KEY_CLOSEBRACE = 66, + ALLEGRO_KEY_ENTER = 67, + ALLEGRO_KEY_SEMICOLON = 68, + ALLEGRO_KEY_QUOTE = 69, + ALLEGRO_KEY_BACKSLASH = 70, + ALLEGRO_KEY_BACKSLASH2 = 71, /* DirectInput calls this DIK_OEM_102: "< > | on UK/Germany keyboards" */ + ALLEGRO_KEY_COMMA = 72, + ALLEGRO_KEY_FULLSTOP = 73, + ALLEGRO_KEY_SLASH = 74, + ALLEGRO_KEY_SPACE = 75, + + ALLEGRO_KEY_INSERT = 76, + ALLEGRO_KEY_DELETE = 77, + ALLEGRO_KEY_HOME = 78, + ALLEGRO_KEY_END = 79, + ALLEGRO_KEY_PGUP = 80, + ALLEGRO_KEY_PGDN = 81, + ALLEGRO_KEY_LEFT = 82, + ALLEGRO_KEY_RIGHT = 83, + ALLEGRO_KEY_UP = 84, + ALLEGRO_KEY_DOWN = 85, + + ALLEGRO_KEY_PAD_SLASH = 86, + ALLEGRO_KEY_PAD_ASTERISK = 87, + ALLEGRO_KEY_PAD_MINUS = 88, + ALLEGRO_KEY_PAD_PLUS = 89, + ALLEGRO_KEY_PAD_DELETE = 90, + ALLEGRO_KEY_PAD_ENTER = 91, + + ALLEGRO_KEY_PRINTSCREEN = 92, + ALLEGRO_KEY_PAUSE = 93, + + ALLEGRO_KEY_ABNT_C1 = 94, + ALLEGRO_KEY_YEN = 95, + ALLEGRO_KEY_KANA = 96, + ALLEGRO_KEY_CONVERT = 97, + ALLEGRO_KEY_NOCONVERT = 98, + ALLEGRO_KEY_AT = 99, + ALLEGRO_KEY_CIRCUMFLEX = 100, + ALLEGRO_KEY_COLON2 = 101, + ALLEGRO_KEY_KANJI = 102, + + ALLEGRO_KEY_PAD_EQUALS = 103, /* MacOS X */ + ALLEGRO_KEY_BACKQUOTE = 104, /* MacOS X */ + ALLEGRO_KEY_SEMICOLON2 = 105, /* MacOS X -- TODO: ask lillo what this should be */ + ALLEGRO_KEY_COMMAND = 106, /* MacOS X */ + + ALLEGRO_KEY_BACK = 107, /* Android back key */ + ALLEGRO_KEY_VOLUME_UP = 108, + ALLEGRO_KEY_VOLUME_DOWN = 109, + + /* Android game keys */ + ALLEGRO_KEY_SEARCH = 110, + ALLEGRO_KEY_DPAD_CENTER = 111, + ALLEGRO_KEY_BUTTON_X = 112, + ALLEGRO_KEY_BUTTON_Y = 113, + ALLEGRO_KEY_DPAD_UP = 114, + ALLEGRO_KEY_DPAD_DOWN = 115, + ALLEGRO_KEY_DPAD_LEFT = 116, + ALLEGRO_KEY_DPAD_RIGHT = 117, + ALLEGRO_KEY_SELECT = 118, + ALLEGRO_KEY_START = 119, + ALLEGRO_KEY_BUTTON_L1 = 120, + ALLEGRO_KEY_BUTTON_R1 = 121, + ALLEGRO_KEY_BUTTON_L2 = 122, + ALLEGRO_KEY_BUTTON_R2 = 123, + ALLEGRO_KEY_BUTTON_A = 124, + ALLEGRO_KEY_BUTTON_B = 125, + ALLEGRO_KEY_THUMBL = 126, + ALLEGRO_KEY_THUMBR = 127, + + ALLEGRO_KEY_UNKNOWN = 128, + + /* All codes up to before ALLEGRO_KEY_MODIFIERS can be freely + * assignedas additional unknown keys, like various multimedia + * and application keys keyboards may have. + */ + + ALLEGRO_KEY_MODIFIERS = 215, + + ALLEGRO_KEY_LSHIFT = 215, + ALLEGRO_KEY_RSHIFT = 216, + ALLEGRO_KEY_LCTRL = 217, + ALLEGRO_KEY_RCTRL = 218, + ALLEGRO_KEY_ALT = 219, + ALLEGRO_KEY_ALTGR = 220, + ALLEGRO_KEY_LWIN = 221, + ALLEGRO_KEY_RWIN = 222, + ALLEGRO_KEY_MENU = 223, + ALLEGRO_KEY_SCROLLLOCK = 224, + ALLEGRO_KEY_NUMLOCK = 225, + ALLEGRO_KEY_CAPSLOCK = 226, + + ALLEGRO_KEY_MAX +}; + + + +enum +{ + ALLEGRO_KEYMOD_SHIFT = 0x00001, + ALLEGRO_KEYMOD_CTRL = 0x00002, + ALLEGRO_KEYMOD_ALT = 0x00004, + ALLEGRO_KEYMOD_LWIN = 0x00008, + ALLEGRO_KEYMOD_RWIN = 0x00010, + ALLEGRO_KEYMOD_MENU = 0x00020, + ALLEGRO_KEYMOD_ALTGR = 0x00040, + ALLEGRO_KEYMOD_COMMAND = 0x00080, + ALLEGRO_KEYMOD_SCROLLLOCK = 0x00100, + ALLEGRO_KEYMOD_NUMLOCK = 0x00200, + ALLEGRO_KEYMOD_CAPSLOCK = 0x00400, + ALLEGRO_KEYMOD_INALTSEQ = 0x00800, + ALLEGRO_KEYMOD_ACCENT1 = 0x01000, + ALLEGRO_KEYMOD_ACCENT2 = 0x02000, + ALLEGRO_KEYMOD_ACCENT3 = 0x04000, + ALLEGRO_KEYMOD_ACCENT4 = 0x08000 +}; + + + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/memory.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/memory.h new file mode 100644 index 00000000..697557ce --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/memory.h @@ -0,0 +1,73 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Memory management routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_memory_h +#define __al_included_allegro5_memory_h + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_MEMORY_INTERFACE + */ +typedef struct ALLEGRO_MEMORY_INTERFACE ALLEGRO_MEMORY_INTERFACE; + +struct ALLEGRO_MEMORY_INTERFACE { + void *(*mi_malloc)(size_t n, int line, const char *file, const char *func); + void (*mi_free)(void *ptr, int line, const char *file, const char *func); + void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file, const char *func); + void *(*mi_calloc)(size_t count, size_t n, int line, const char *file, const char *func); +}; + +AL_FUNC(void, al_set_memory_interface, (ALLEGRO_MEMORY_INTERFACE *iface)); + + +/* Function: al_malloc + */ +#define al_malloc(n) \ + (al_malloc_with_context((n), __LINE__, __FILE__, __func__)) + +/* Function: al_free + */ +#define al_free(p) \ + (al_free_with_context((p), __LINE__, __FILE__, __func__)) + +/* Function: al_realloc + */ +#define al_realloc(p, n) \ + (al_realloc_with_context((p), (n), __LINE__, __FILE__, __func__)) + +/* Function: al_calloc + */ +#define al_calloc(c, n) \ + (al_calloc_with_context((c), (n), __LINE__, __FILE__, __func__)) + + +AL_FUNC(void *, al_malloc_with_context, (size_t n, + int line, const char *file, const char *func)); +AL_FUNC(void, al_free_with_context, (void *ptr, + int line, const char *file, const char *func)); +AL_FUNC(void *, al_realloc_with_context, (void *ptr, size_t n, + int line, const char *file, const char *func)); +AL_FUNC(void *, al_calloc_with_context, (size_t count, size_t n, + int line, const char *file, const char *func)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/monitor.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/monitor.h new file mode 100644 index 00000000..2e939da3 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/monitor.h @@ -0,0 +1,33 @@ +#ifndef __al_included_allegro5_monitor_h +#define __al_included_allegro5_monitor_h + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_MONITOR_INFO + */ +typedef struct ALLEGRO_MONITOR_INFO +{ + int x1; + int y1; + int x2; + int y2; +} ALLEGRO_MONITOR_INFO; + +enum { + ALLEGRO_DEFAULT_DISPLAY_ADAPTER = -1 +}; + +AL_FUNC(int, al_get_num_video_adapters, (void)); +AL_FUNC(bool, al_get_monitor_info, (int adapter, ALLEGRO_MONITOR_INFO *info)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/mouse.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/mouse.h new file mode 100644 index 00000000..f4e85c93 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/mouse.h @@ -0,0 +1,82 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Mouse routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_mouse_h +#define __al_included_allegro5_mouse_h + +#include "allegro5/base.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Allow up to four extra axes for future expansion. */ +#define ALLEGRO_MOUSE_MAX_EXTRA_AXES 4 + + +typedef struct ALLEGRO_MOUSE ALLEGRO_MOUSE; + + +/* Type: ALLEGRO_MOUSE_STATE + */ +typedef struct ALLEGRO_MOUSE_STATE ALLEGRO_MOUSE_STATE; + +struct ALLEGRO_MOUSE_STATE +{ + /* (x, y) Primary mouse position + * (z) Mouse wheel position (1D 'wheel'), or, + * (w, z) Mouse wheel position (2D 'ball') + * display - the display the mouse is on (coordinates are relative to this) + * pressure - the pressure appleid to the mouse (for stylus/tablet) + */ + int x; + int y; + int z; + int w; + int more_axes[ALLEGRO_MOUSE_MAX_EXTRA_AXES]; + int buttons; + float pressure; + struct ALLEGRO_DISPLAY *display; +}; + + +AL_FUNC(bool, al_is_mouse_installed, (void)); +AL_FUNC(bool, al_install_mouse, (void)); +AL_FUNC(void, al_uninstall_mouse, (void)); +AL_FUNC(unsigned int, al_get_mouse_num_buttons, (void)); +AL_FUNC(unsigned int, al_get_mouse_num_axes, (void)); +AL_FUNC(bool, al_set_mouse_xy, (struct ALLEGRO_DISPLAY *display, int x, int y)); +AL_FUNC(bool, al_set_mouse_z, (int z)); +AL_FUNC(bool, al_set_mouse_w, (int w)); +AL_FUNC(bool, al_set_mouse_axis, (int axis, int value)); +AL_FUNC(void, al_get_mouse_state, (ALLEGRO_MOUSE_STATE *ret_state)); +AL_FUNC(bool, al_mouse_button_down, (const ALLEGRO_MOUSE_STATE *state, int button)); +AL_FUNC(int, al_get_mouse_state_axis, (const ALLEGRO_MOUSE_STATE *state, int axis)); +AL_FUNC(bool, al_get_mouse_cursor_position, (int *ret_x, int *ret_y)); +AL_FUNC(bool, al_grab_mouse, (struct ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_ungrab_mouse, (void)); +AL_FUNC(void, al_set_mouse_wheel_precision, (int precision)); +AL_FUNC(int, al_get_mouse_wheel_precision, (void)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_mouse_event_source, (void)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/mouse_cursor.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/mouse_cursor.h new file mode 100644 index 00000000..69c7043c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/mouse_cursor.h @@ -0,0 +1,58 @@ +#ifndef __al_included_allegro5_mouse_cursor_h +#define __al_included_allegro5_mouse_cursor_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct ALLEGRO_MOUSE_CURSOR ALLEGRO_MOUSE_CURSOR; + +typedef enum ALLEGRO_SYSTEM_MOUSE_CURSOR +{ + ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE = 0, + ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT = 1, + ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW = 2, + ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY = 3, + ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION = 4, + ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT = 5, + ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE = 6, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N = 7, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W = 8, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S = 9, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E = 10, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW = 11, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW = 12, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE = 13, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE = 14, + ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS = 15, + ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION = 16, + ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK = 17, + ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT = 18, + ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE = 19, + ALLEGRO_NUM_SYSTEM_MOUSE_CURSORS +} ALLEGRO_SYSTEM_MOUSE_CURSOR; + +struct ALLEGRO_BITMAP; +struct ALLEGRO_DISPLAY; + + +AL_FUNC(ALLEGRO_MOUSE_CURSOR *, al_create_mouse_cursor, ( + struct ALLEGRO_BITMAP *sprite, int xfocus, int yfocus)); +AL_FUNC(void, al_destroy_mouse_cursor, (ALLEGRO_MOUSE_CURSOR *)); +AL_FUNC(bool, al_set_mouse_cursor, (struct ALLEGRO_DISPLAY *display, + ALLEGRO_MOUSE_CURSOR *cursor)); +AL_FUNC(bool, al_set_system_mouse_cursor, (struct ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id)); +AL_FUNC(bool, al_show_mouse_cursor, (struct ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_hide_mouse_cursor, (struct ALLEGRO_DISPLAY *display)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_alias.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_alias.h new file mode 100644 index 00000000..4cb71a0f --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_alias.h @@ -0,0 +1,2564 @@ +/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ +/**/ + +#ifdef _ALLEGRO_GL_VERSION_1_2 +#define glBlendColor _al_glBlendColor +#define glBlendEquation _al_glBlendEquation +#define glDrawRangeElements _al_glDrawRangeElements +#define glColorTable _al_glColorTable +#define glColorTableParameterfv _al_glColorTableParameterfv +#define glColorTableParameteriv _al_glColorTableParameteriv +#define glCopyColorTable _al_glCopyColorTable +#define glGetColorTable _al_glGetColorTable +#define glGetColorTableParameterfv _al_glGetColorTableParameterfv +#define glGetColorTableParameteriv _al_glGetColorTableParameteriv +#define glColorSubTable _al_glColorSubTable +#define glCopyColorSubTable _al_glCopyColorSubTable +#define glTexImage3D _al_glTexImage3D +#define glTexSubImage3D _al_glTexSubImage3D +#define glCopyTexSubImage3D _al_glCopyTexSubImage3D +#endif + +#if defined _ALLEGRO_GL_ARB_imaging +#define glConvolutionFilter1D _al_glConvolutionFilter1D +#define glConvolutionFilter2D _al_glConvolutionFilter2D +#define glConvolutionParameterf _al_glConvolutionParameterf +#define glConvolutionParameterfv _al_glConvolutionParameterfv +#define glConvolutionParameteri _al_glConvolutionParameteri +#define glConvolutionParameteriv _al_glConvolutionParameteriv +#define glCopyConvolutionFilter1D _al_glCopyConvolutionFilter1D +#define glCopyConvolutionFilter2D _al_glCopyConvolutionFilter2D +#define glGetConvolutionFilter _al_glGetConvolutionFilter +#define glGetConvolutionParameterfv _al_glGetConvolutionParameterfv +#define glGetConvolutionParameteriv _al_glGetConvolutionParameteriv +#define glGetSeparableFilter _al_glGetSeparableFilter +#define glSeparableFilter2D _al_glSeparableFilter2D +#define glGetHistogram _al_glGetHistogram +#define glGetHistogramParameterfv _al_glGetHistogramParameterfv +#define glGetHistogramParameteriv _al_glGetHistogramParameteriv +#define glGetMinmax _al_glGetMinmax +#define glGetMinmaxParameterfv _al_glGetMinmaxParameterfv +#define glGetMinmaxParameteriv _al_glGetMinmaxParameteriv +#define glHistogram _al_glHistogram +#define glMinmax _al_glMinmax +#define glResetHistogram _al_glResetHistogram +#define glResetMinmax _al_glResetMinmax +#endif + +#if defined _ALLEGRO_GL_VERSION_1_3 +#define glActiveTexture _al_glActiveTexture +#define glClientActiveTexture _al_glClientActiveTexture +#define glMultiTexCoord1d _al_glMultiTexCoord1d +#define glMultiTexCoord1dv _al_glMultiTexCoord1dv +#define glMultiTexCoord1f _al_glMultiTexCoord1f +#define glMultiTexCoord1fv _al_glMultiTexCoord1fv +#define glMultiTexCoord1i _al_glMultiTexCoord1i +#define glMultiTexCoord1iv _al_glMultiTexCoord1iv +#define glMultiTexCoord1s _al_glMultiTexCoord1s +#define glMultiTexCoord1sv _al_glMultiTexCoord1sv +#define glMultiTexCoord2d _al_glMultiTexCoord2d +#define glMultiTexCoord2dv _al_glMultiTexCoord2dv +#define glMultiTexCoord2f _al_glMultiTexCoord2f +#define glMultiTexCoord2fv _al_glMultiTexCoord2fv +#define glMultiTexCoord2i _al_glMultiTexCoord2i +#define glMultiTexCoord2iv _al_glMultiTexCoord2iv +#define glMultiTexCoord2s _al_glMultiTexCoord2s +#define glMultiTexCoord2sv _al_glMultiTexCoord2sv +#define glMultiTexCoord3d _al_glMultiTexCoord3d +#define glMultiTexCoord3dv _al_glMultiTexCoord3dv +#define glMultiTexCoord3f _al_glMultiTexCoord3f +#define glMultiTexCoord3fv _al_glMultiTexCoord3fv +#define glMultiTexCoord3i _al_glMultiTexCoord3i +#define glMultiTexCoord3iv _al_glMultiTexCoord3iv +#define glMultiTexCoord3s _al_glMultiTexCoord3s +#define glMultiTexCoord3sv _al_glMultiTexCoord3sv +#define glMultiTexCoord4d _al_glMultiTexCoord4d +#define glMultiTexCoord4dv _al_glMultiTexCoord4dv +#define glMultiTexCoord4f _al_glMultiTexCoord4f +#define glMultiTexCoord4fv _al_glMultiTexCoord4fv +#define glMultiTexCoord4i _al_glMultiTexCoord4i +#define glMultiTexCoord4iv _al_glMultiTexCoord4iv +#define glMultiTexCoord4s _al_glMultiTexCoord4s +#define glMultiTexCoord4sv _al_glMultiTexCoord4sv +#define glLoadTransposeMatrixf _al_glLoadTransposeMatrixf +#define glLoadTransposeMatrixd _al_glLoadTransposeMatrixd +#define glMultTransposeMatrixf _al_glMultTransposeMatrixf +#define glMultTransposeMatrixd _al_glMultTransposeMatrixd +#define glSampleCoverage _al_glSampleCoverage +#define glCompressedTexImage3D _al_glCompressedTexImage3D +#define glCompressedTexImage2D _al_glCompressedTexImage2D +#define glCompressedTexImage1D _al_glCompressedTexImage1D +#define glCompressedTexSubImage3D _al_glCompressedTexSubImage3D +#define glCompressedTexSubImage2D _al_glCompressedTexSubImage2D +#define glCompressedTexSubImage1D _al_glCompressedTexSubImage1D +#define glGetCompressedTexImage _al_glGetCompressedTexImage +#endif + +#if defined _ALLEGRO_GL_VERSION_1_4 +#define glBlendFuncSeparate _al_glBlendFuncSeparate +#define glFogCoordf _al_glFogCoordf +#define glFogCoordfv _al_glFogCoordfv +#define glFogCoordd _al_glFogCoordd +#define glFogCoorddv _al_glFogCoorddv +#define glFogCoordPointer _al_glFogCoordPointer +#define glMultiDrawArrays _al_glMultiDrawArrays +#define glMultiDrawElements _al_glMultiDrawElements +#define glPointParameterf _al_glPointParameterf +#define glPointParameterfv _al_glPointParameterfv +#define glPointParameteri _al_glPointParameteri +#define glPointParameteriv _al_glPointParameteriv +#define glSecondaryColor3b _al_glSecondaryColor3b +#define glSecondaryColor3bv _al_glSecondaryColor3bv +#define glSecondaryColor3d _al_glSecondaryColor3d +#define glSecondaryColor3dv _al_glSecondaryColor3dv +#define glSecondaryColor3f _al_glSecondaryColor3f +#define glSecondaryColor3fv _al_glSecondaryColor3fv +#define glSecondaryColor3i _al_glSecondaryColor3i +#define glSecondaryColor3iv _al_glSecondaryColor3iv +#define glSecondaryColor3s _al_glSecondaryColor3s +#define glSecondaryColor3sv _al_glSecondaryColor3sv +#define glSecondaryColor3ub _al_glSecondaryColor3ub +#define glSecondaryColor3ubv _al_glSecondaryColor3ubv +#define glSecondaryColor3ui _al_glSecondaryColor3ui +#define glSecondaryColor3uiv _al_glSecondaryColor3uiv +#define glSecondaryColor3us _al_glSecondaryColor3us +#define glSecondaryColor3usv _al_glSecondaryColor3usv +#define glSecondaryColorPointer _al_glSecondaryColorPointer +#define glWindowPos2d _al_glWindowPos2d +#define glWindowPos2dv _al_glWindowPos2dv +#define glWindowPos2f _al_glWindowPos2f +#define glWindowPos2fv _al_glWindowPos2fv +#define glWindowPos2i _al_glWindowPos2i +#define glWindowPos2iv _al_glWindowPos2iv +#define glWindowPos2s _al_glWindowPos2s +#define glWindowPos2sv _al_glWindowPos2sv +#define glWindowPos3d _al_glWindowPos3d +#define glWindowPos3dv _al_glWindowPos3dv +#define glWindowPos3f _al_glWindowPos3f +#define glWindowPos3fv _al_glWindowPos3fv +#define glWindowPos3i _al_glWindowPos3i +#define glWindowPos3iv _al_glWindowPos3iv +#define glWindowPos3s _al_glWindowPos3s +#define glWindowPos3sv _al_glWindowPos3sv +#endif + + +#if defined _ALLEGRO_GL_VERSION_1_5 +#define glBindBuffer _al_glBindBuffer +#define glDeleteBuffers _al_glDeleteBuffers +#define glGenBuffers _al_glGenBuffers +#define glIsBuffer _al_glIsBuffer +#define glBufferData _al_glBufferData +#define glBufferSubData _al_glBufferSubData +#define glGetBufferSubData _al_glGetBufferSubData +#define glMapBuffer _al_glMapBuffer +#define glUnmapBuffer _al_glUnmapBuffer +#define glGetBufferParameteriv _al_glGetBufferParameteriv +#define glGetBufferPointerv _al_glGetBufferPointerv +#define glGenQueries _al_glGenQueries +#define glDeleteQueries _al_glDeleteQueries +#define glIsQuery _al_glIsQuery +#define glBeginQuery _al_glBeginQuery +#define glEndQuery _al_glEndQuery +#define glGetQueryiv _al_glGetQueryiv +#define glGetQueryObjectiv _al_glGetQueryObjectiv +#define glGetQueryObjectuiv _al_glGetQueryObjectuiv +#endif + + +#if defined _ALLEGRO_GL_VERSION_2_0 +#define glBlendEquationSeparate _al_glBlendEquationSeparate +#define glCreateProgram _al_glCreateProgram +#define glCreateShader _al_glCreateShader +#define glDeleteProgram _al_glDeleteProgram +#define glDeleteShader _al_glDeleteShader +#define glAttachShader _al_glAttachShader +#define glDetachShader _al_glDetachShader +#define glShaderSource _al_glShaderSource +#define glCompileShader _al_glCompileShader +#define glIsProgram _al_glIsProgram +#define glIsShader _al_glIsShader +#define glLinkProgram _al_glLinkProgram +#define glUseProgram _al_glUseProgram +#define glValidateProgram _al_glValidateProgram +#define glUniform1f _al_glUniform1f +#define glUniform2f _al_glUniform2f +#define glUniform3f _al_glUniform3f +#define glUniform4f _al_glUniform4f +#define glUniform1i _al_glUniform1i +#define glUniform2i _al_glUniform2i +#define glUniform3i _al_glUniform3i +#define glUniform4i _al_glUniform4i +#define glUniform1fv _al_glUniform1fv +#define glUniform2fv _al_glUniform2fv +#define glUniform3fv _al_glUniform3fv +#define glUniform4fv _al_glUniform4fv +#define glUniform1iv _al_glUniform1iv +#define glUniform2iv _al_glUniform2iv +#define glUniform3iv _al_glUniform3iv +#define glUniform4iv _al_glUniform4iv +#define glUniformMatrix2fv _al_glUniformMatrix2fv +#define glUniformMatrix3fv _al_glUniformMatrix3fv +#define glUniformMatrix4fv _al_glUniformMatrix4fv +#define glGetShaderfv _al_glGetShaderfv +#define glGetShaderiv _al_glGetShaderiv +#define glGetProgramfv _al_glGetProgramfv +#define glGetProgramiv _al_glGetProgramiv +#define glGetShaderInfoLog _al_glGetShaderInfoLog +#define glGetProgramInfoLog _al_glGetProgramInfoLog +#define glGetAttachedShaders _al_glGetAttachedShaders +#define glGetUniformLocation _al_glGetUniformLocation +#define glGetActiveUniform _al_glGetActiveUniform +#define glGetUniformfv _al_glGetUniformfv +#define glGetUniformiv _al_glGetUniformiv +#define glGetShaderSource _al_glGetShaderSource +#define glVertexAttrib1f _al_glVertexAttrib1f +#define glVertexAttrib1s _al_glVertexAttrib1s +#define glVertexAttrib1d _al_glVertexAttrib1d +#define glVertexAttrib2f _al_glVertexAttrib2f +#define glVertexAttrib2s _al_glVertexAttrib2s +#define glVertexAttrib2d _al_glVertexAttrib2d +#define glVertexAttrib3f _al_glVertexAttrib3f +#define glVertexAttrib3s _al_glVertexAttrib3s +#define glVertexAttrib3d _al_glVertexAttrib3d +#define glVertexAttrib4f _al_glVertexAttrib4f +#define glVertexAttrib4s _al_glVertexAttrib4s +#define glVertexAttrib4d _al_glVertexAttrib4d +#define glVertexAttrib4Nub _al_glVertexAttrib4Nub +#define glVertexAttrib1fv _al_glVertexAttrib1fv +#define glVertexAttrib1sv _al_glVertexAttrib1sv +#define glVertexAttrib1dv _al_glVertexAttrib1dv +#define glVertexAttrib2fv _al_glVertexAttrib2fv +#define glVertexAttrib2sv _al_glVertexAttrib2sv +#define glVertexAttrib2dv _al_glVertexAttrib2dv +#define glVertexAttrib3fv _al_glVertexAttrib3fv +#define glVertexAttrib3sv _al_glVertexAttrib3sv +#define glVertexAttrib3dv _al_glVertexAttrib3dv +#define glVertexAttrib4fv _al_glVertexAttrib4fv +#define glVertexAttrib4sv _al_glVertexAttrib4sv +#define glVertexAttrib4dv _al_glVertexAttrib4dv +#define glVertexAttrib4iv _al_glVertexAttrib4iv +#define glVertexAttrib4bv _al_glVertexAttrib4bv +#define glVertexAttrib4ubv _al_glVertexAttrib4ubv +#define glVertexAttrib4usv _al_glVertexAttrib4usv +#define glVertexAttrib4uiv _al_glVertexAttrib4uiv +#define glVertexAttrib4Nbv _al_glVertexAttrib4Nbv +#define glVertexAttrib4Nsv _al_glVertexAttrib4Nsv +#define glVertexAttrib4Niv _al_glVertexAttrib4Niv +#define glVertexAttrib4Nubv _al_glVertexAttrib4Nubv +#define glVertexAttrib4Nusv _al_glVertexAttrib4Nusv +#define glVertexAttrib4Nuiv _al_glVertexAttrib4Nuiv +#define glVertexAttribPointer _al_glVertexAttribPointer +#define glEnableVertexAttribArray _al_glEnableVertexAttribArray +#define glDisableVertexAttribArray _al_glDisableVertexAttribArray + +#define glBindAttribLocation _al_glBindAttribLocation +#define glGetActiveAttrib _al_glGetActiveAttrib +#define glGetAttribLocation _al_glGetAttribLocation +#define glGetVertexAttribdv _al_glGetVertexAttribdv +#define glGetVertexAttribfv _al_glGetVertexAttribfv +#define glGetVertexAttribiv _al_glGetVertexAttribiv +#define glGetVertexAttribPointerv _al_glGetVertexAttribPointerv + +#define glDrawBuffers _al_glDrawBuffers + +#define glStencilOpSeparate _al_glStencilOpSeparate +#define glStencilFuncSeparate _al_glStencilFuncSeparate + +#endif + + +#if defined _ALLEGRO_GL_VERSION_2_1 +#define glUniformMatrix2x3fv _al_glUniformMatrix2x3fv +#define glUniformMatrix3x2fv _al_glUniformMatrix3x2fv +#define glUniformMatrix2x4fv _al_glUniformMatrix2x4fv +#define glUniformMatrix4x2fv _al_glUniformMatrix4x2fv +#define glUniformMatrix3x4fv _al_glUniformMatrix3x4fv +#define glUniformMatrix4x3fv _al_glUniformMatrix4x3fv +#endif + +#if defined _ALLEGRO_GL_VERSION_3_0 +/*OpenGL3.0alsoreusesentrypointsfromtheseextensions:*/ +/*ARB_framebuffer_object*/ +/*ARB_map_buffer_range*/ +/*ARB_vertex_array_object*/ +#define glColorMaski _al_glColorMaski +#define glGetBooleani_v _al_glGetBooleani_v +#define glGetIntegeri_v _al_glGetIntegeri_v +#define glEnablei _al_glEnablei +#define glDisablei _al_glDisablei +#define glIsEnabledi _al_glIsEnabledi +#define glBeginTransformFeedback _al_glBeginTransformFeedback +#define glEndTransformFeedback _al_glEndTransformFeedback +#define glBindBufferRange _al_glBindBufferRange +#define glBindBufferBase _al_glBindBufferBase +#define glTransformFeedbackVaryings _al_glTransformFeedbackVaryings +#define glGetTransformFeedbackVarying _al_glGetTransformFeedbackVarying +#define glClampColor _al_glClampColor +#define glBeginConditionalRender _al_glBeginConditionalRender +#define glEndConditionalRender _al_glEndConditionalRender +#define glVertexAttribI1i _al_glVertexAttribI1i +#define glVertexAttribI2i _al_glVertexAttribI2i +#define glVertexAttribI3i _al_glVertexAttribI3i +#define glVertexAttribI4i _al_glVertexAttribI4i +#define glVertexAttribI1ui _al_glVertexAttribI1ui +#define glVertexAttribI2ui _al_glVertexAttribI2ui +#define glVertexAttribI3ui _al_glVertexAttribI3ui +#define glVertexAttribI4ui _al_glVertexAttribI4ui +#define glVertexAttribI1iv _al_glVertexAttribI1iv +#define glVertexAttribI2iv _al_glVertexAttribI2iv +#define glVertexAttribI3iv _al_glVertexAttribI3iv +#define glVertexAttribI4iv _al_glVertexAttribI4iv +#define glVertexAttribI1uiv _al_glVertexAttribI1uiv +#define glVertexAttribI2uiv _al_glVertexAttribI2uiv +#define glVertexAttribI3uiv _al_glVertexAttribI3uiv +#define glVertexAttribI4uiv _al_glVertexAttribI4uiv +#define glVertexAttribI4bv _al_glVertexAttribI4bv +#define glVertexAttribI4sv _al_glVertexAttribI4sv +#define glVertexAttribI4ubv _al_glVertexAttribI4ubv +#define glVertexAttribI4usv _al_glVertexAttribI4usv +#define glVertexAttribIPointer _al_glVertexAttribIPointer +#define glGetVertexAttribIiv _al_glGetVertexAttribIiv +#define glGetVertexAttribIuiv _al_glGetVertexAttribIuiv +#define glGetUniformuiv _al_glGetUniformuiv +#define glBindFragDataLocation _al_glBindFragDataLocation +#define glGetFragDataLocation _al_glGetFragDataLocation +#define glUniform1ui _al_glUniform1ui +#define glUniform2ui _al_glUniform2ui +#define glUniform3ui _al_glUniform3ui +#define glUniform4ui _al_glUniform4ui +#define glUniform1uiv _al_glUniform1uiv +#define glUniform2uiv _al_glUniform2uiv +#define glUniform3uiv _al_glUniform3uiv +#define glUniform4uiv _al_glUniform4uiv +#define glTexParameterIiv _al_glTexParameterIiv +#define glTexParameterIuiv _al_glTexParameterIuiv +#define glGetTexParameterIiv _al_glGetTexParameterIiv +#define glGetTexParameterIuiv _al_glGetTexParameterIuiv +#define glClearBufferiv _al_glClearBufferiv +#define glClearBufferuiv _al_glClearBufferuiv +#define glClearBufferfv _al_glClearBufferfv +#define glClearBufferfi _al_glClearBufferfi +#define glGetStringi _al_glGetStringi +#endif + + +#if defined _ALLEGRO_GL_VERSION_3_1 +/*OpenGL3.1alsoreusesentrypointsfromtheseextensions:*/ +/*ARB_copy_buffer*/ +/*ARB_uniform_buffer_object*/ +#define glDrawArraysInstanced _al_glDrawArraysInstanced +#define glDrawElementsInstanced _al_glDrawElementsInstanced +#define glTexBuffer _al_glTexBuffer +#define glPrimitiveRestartIndex _al_glPrimitiveRestartIndex +#endif + +#if defined _ALLEGRO_GL_VERSION_3_2 +/*OpenGL3.2alsoreusesentrypointsfromtheseextensions:*/ +/*ARB_draw_elements_base_vertex*/ +/*ARB_provoking_vertex*/ +/*ARB_sync*/ +/*ARB_texture_multisample*/ +#define glGetInteger64i_v _al_glGetInteger64i_v +#define glGetBufferParameteri64v _al_glGetBufferParameteri64v +#define glProgramParameteri _al_glProgramParameteri +#define glFramebufferTexture _al_glFramebufferTexture +#endif + +#if defined _ALLEGRO_GL_VERSION_3_3 +/*OpenGL3.3alsoreusesentrypointsfromtheseextensions:*/ +/*ARB_blend_func_extended*/ +/*ARB_sampler_objects*/ +/*ARB_explicit_attrib_location,butithasnone*/ +/*ARB_occlusion_query2(noentrypoints)*/ +/*ARB_shader_bit_encoding(noentrypoints)*/ +/*ARB_texture_rgb10_a2ui(noentrypoints)*/ +/*ARB_texture_swizzle(noentrypoints)*/ +/*ARB_timer_query*/ +/*ARB_vertex_type_2_10_10_10_rev*/ +#endif + + +/**/ +/**/ + +#ifdef _ALLEGRO_GL_ARB_multitexture +#define glActiveTextureARB _al_glActiveTextureARB +#define glClientActiveTextureARB _al_glClientActiveTextureARB +#define glMultiTexCoord1dARB _al_glMultiTexCoord1dARB +#define glMultiTexCoord1dvARB _al_glMultiTexCoord1dvARB +#define glMultiTexCoord1fARB _al_glMultiTexCoord1fARB +#define glMultiTexCoord1fvARB _al_glMultiTexCoord1fvARB +#define glMultiTexCoord1iARB _al_glMultiTexCoord1iARB +#define glMultiTexCoord1ivARB _al_glMultiTexCoord1ivARB +#define glMultiTexCoord1sARB _al_glMultiTexCoord1sARB +#define glMultiTexCoord1svARB _al_glMultiTexCoord1svARB +#define glMultiTexCoord2dARB _al_glMultiTexCoord2dARB +#define glMultiTexCoord2dvARB _al_glMultiTexCoord2dvARB +#define glMultiTexCoord2fARB _al_glMultiTexCoord2fARB +#define glMultiTexCoord2fvARB _al_glMultiTexCoord2fvARB +#define glMultiTexCoord2iARB _al_glMultiTexCoord2iARB +#define glMultiTexCoord2ivARB _al_glMultiTexCoord2ivARB +#define glMultiTexCoord2sARB _al_glMultiTexCoord2sARB +#define glMultiTexCoord2svARB _al_glMultiTexCoord2svARB +#define glMultiTexCoord3dARB _al_glMultiTexCoord3dARB +#define glMultiTexCoord3dvARB _al_glMultiTexCoord3dvARB +#define glMultiTexCoord3fARB _al_glMultiTexCoord3fARB +#define glMultiTexCoord3fvARB _al_glMultiTexCoord3fvARB +#define glMultiTexCoord3iARB _al_glMultiTexCoord3iARB +#define glMultiTexCoord3ivARB _al_glMultiTexCoord3ivARB +#define glMultiTexCoord3sARB _al_glMultiTexCoord3sARB +#define glMultiTexCoord3svARB _al_glMultiTexCoord3svARB +#define glMultiTexCoord4dARB _al_glMultiTexCoord4dARB +#define glMultiTexCoord4dvARB _al_glMultiTexCoord4dvARB +#define glMultiTexCoord4fARB _al_glMultiTexCoord4fARB +#define glMultiTexCoord4fvARB _al_glMultiTexCoord4fvARB +#define glMultiTexCoord4iARB _al_glMultiTexCoord4iARB +#define glMultiTexCoord4ivARB _al_glMultiTexCoord4ivARB +#define glMultiTexCoord4sARB _al_glMultiTexCoord4sARB +#define glMultiTexCoord4svARB _al_glMultiTexCoord4svARB +#endif + +#if defined _ALLEGRO_GL_ARB_transpose_matrix +#define glLoadTransposeMatrixfARB _al_glLoadTransposeMatrixfARB +#define glLoadTransposeMatrixdARB _al_glLoadTransposeMatrixdARB +#define glMultTransposeMatrixfARB _al_glMultTransposeMatrixfARB +#define glMultTransposeMatrixdARB _al_glMultTransposeMatrixdARB +#endif + +#if defined _ALLEGRO_GL_ARB_multisample +#define glSampleCoverageARB _al_glSampleCoverageARB +#endif + +#if defined _ALLEGRO_GL_ARB_texture_compression +#define glCompressedTexImage3DARB _al_glCompressedTexImage3DARB +#define glCompressedTexImage2DARB _al_glCompressedTexImage2DARB +#define glCompressedTexImage1DARB _al_glCompressedTexImage1DARB +#define glCompressedTexSubImage3DARB _al_glCompressedTexSubImage3DARB +#define glCompressedTexSubImage2DARB _al_glCompressedTexSubImage2DARB +#define glCompressedTexSubImage1DARB _al_glCompressedTexSubImage1DARB +#define glGetCompressedTexImageARB _al_glGetCompressedTexImageARB +#endif + +#if defined _ALLEGRO_GL_ARB_point_parameters +#define glPointParameterfARB _al_glPointParameterfARB +#define glPointParameterfvARB _al_glPointParameterfvARB +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_blend +#define glWeightbvARB _al_glWeightbvARB +#define glWeightsvARB _al_glWeightsvARB +#define glWeightivARB _al_glWeightivARB +#define glWeightfvARB _al_glWeightfvARB +#define glWeightdvARB _al_glWeightdvARB +#define glWeightubvARB _al_glWeightubvARB +#define glWeightusvARB _al_glWeightusvARB +#define glWeightuivARB _al_glWeightuivARB +#define glWeightPointerARB _al_glWeightPointerARB +#define glVertexBlendARB _al_glVertexBlendARB +#endif + +#if defined _ALLEGRO_GL_ARB_matrix_palette +#define glCurrentPaletteMatrixARB _al_glCurrentPaletteMatrixARB +#define glMatrixIndexubvARB _al_glMatrixIndexubvARB +#define glMatrixIndexusvARB _al_glMatrixIndexusvARB +#define glMatrixIndexuivARB _al_glMatrixIndexuivARB +#define glMatrixIndexPointerARB _al_glMatrixIndexPointerARB +#endif + +#if defined _ALLEGRO_GL_ARB_window_pos +#define glWindowPos2dARB _al_glWindowPos2dARB +#define glWindowPos2dvARB _al_glWindowPos2dvARB +#define glWindowPos2fARB _al_glWindowPos2fARB +#define glWindowPos2fvARB _al_glWindowPos2fvARB +#define glWindowPos2iARB _al_glWindowPos2iARB +#define glWindowPos2ivARB _al_glWindowPos2ivARB +#define glWindowPos2sARB _al_glWindowPos2sARB +#define glWindowPos2svARB _al_glWindowPos2svARB +#define glWindowPos3dARB _al_glWindowPos3dARB +#define glWindowPos3dvARB _al_glWindowPos3dvARB +#define glWindowPos3fARB _al_glWindowPos3fARB +#define glWindowPos3fvARB _al_glWindowPos3fvARB +#define glWindowPos3iARB _al_glWindowPos3iARB +#define glWindowPos3ivARB _al_glWindowPos3ivARB +#define glWindowPos3sARB _al_glWindowPos3sARB +#define glWindowPos3svARB _al_glWindowPos3svARB +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_program +#define glVertexAttrib1dARB _al_glVertexAttrib1dARB +#define glVertexAttrib1dvARB _al_glVertexAttrib1dvARB +#define glVertexAttrib1fARB _al_glVertexAttrib1fARB +#define glVertexAttrib1fvARB _al_glVertexAttrib1fvARB +#define glVertexAttrib1sARB _al_glVertexAttrib1sARB +#define glVertexAttrib1svARB _al_glVertexAttrib1svARB +#define glVertexAttrib2dARB _al_glVertexAttrib2dARB +#define glVertexAttrib2dvARB _al_glVertexAttrib2dvARB +#define glVertexAttrib2fARB _al_glVertexAttrib2fARB +#define glVertexAttrib2fvARB _al_glVertexAttrib2fvARB +#define glVertexAttrib2sARB _al_glVertexAttrib2sARB +#define glVertexAttrib2svARB _al_glVertexAttrib2svARB +#define glVertexAttrib3dARB _al_glVertexAttrib3dARB +#define glVertexAttrib3dvARB _al_glVertexAttrib3dvARB +#define glVertexAttrib3fARB _al_glVertexAttrib3fARB +#define glVertexAttrib3fvARB _al_glVertexAttrib3fvARB +#define glVertexAttrib3sARB _al_glVertexAttrib3sARB +#define glVertexAttrib3svARB _al_glVertexAttrib3svARB +#define glVertexAttrib4NbvARB _al_glVertexAttrib4NbvARB +#define glVertexAttrib4NivARB _al_glVertexAttrib4NivARB +#define glVertexAttrib4NsvARB _al_glVertexAttrib4NsvARB +#define glVertexAttrib4NubARB _al_glVertexAttrib4NubARB +#define glVertexAttrib4NubvARB _al_glVertexAttrib4NubvARB +#define glVertexAttrib4NuivARB _al_glVertexAttrib4NuivARB +#define glVertexAttrib4NusvARB _al_glVertexAttrib4NusvARB +#define glVertexAttrib4bvARB _al_glVertexAttrib4bvARB +#define glVertexAttrib4dARB _al_glVertexAttrib4dARB +#define glVertexAttrib4dvARB _al_glVertexAttrib4dvARB +#define glVertexAttrib4fARB _al_glVertexAttrib4fARB +#define glVertexAttrib4fvARB _al_glVertexAttrib4fvARB +#define glVertexAttrib4ivARB _al_glVertexAttrib4ivARB +#define glVertexAttrib4sARB _al_glVertexAttrib4sARB +#define glVertexAttrib4svARB _al_glVertexAttrib4svARB +#define glVertexAttrib4ubvARB _al_glVertexAttrib4ubvARB +#define glVertexAttrib4uivARB _al_glVertexAttrib4uivARB +#define glVertexAttrib4usvARB _al_glVertexAttrib4usvARB +#define glVertexAttribPointerARB _al_glVertexAttribPointerARB +#define glEnableVertexAttribArrayARB _al_glEnableVertexAttribArrayARB +#define glDisableVertexAttribArrayARB _al_glDisableVertexAttribArrayARB +#define glProgramStringARB _al_glProgramStringARB +#define glBindProgramARB _al_glBindProgramARB +#define glDeleteProgramsARB _al_glDeleteProgramsARB +#define glGenProgramsARB _al_glGenProgramsARB +#define glProgramEnvParameter4dARB _al_glProgramEnvParameter4dARB +#define glProgramEnvParameter4dvARB _al_glProgramEnvParameter4dvARB +#define glProgramEnvParameter4fARB _al_glProgramEnvParameter4fARB +#define glProgramEnvParameter4fvARB _al_glProgramEnvParameter4fvARB +#define glProgramLocalParameter4dARB _al_glProgramLocalParameter4dARB +#define glProgramLocalParameter4dvARB _al_glProgramLocalParameter4dvARB +#define glProgramLocalParameter4fARB _al_glProgramLocalParameter4fARB +#define glProgramLocalParameter4fvARB _al_glProgramLocalParameter4fvARB +#define glGetProgramEnvParameterdvARB _al_glGetProgramEnvParameterdvARB +#define glGetProgramEnvParameterfvARB _al_glGetProgramEnvParameterfvARB +#define glGetProgramLocalParameterdvARB _al_glGetProgramLocalParameterdvARB +#define glGetProgramLocalParameterfvARB _al_glGetProgramLocalParameterfvARB +#define glGetProgramivARB _al_glGetProgramivARB +#define glGetProgramStringARB _al_glGetProgramStringARB +#define glGetVertexAttribdvARB _al_glGetVertexAttribdvARB +#define glGetVertexAttribfvARB _al_glGetVertexAttribfvARB +#define glGetVertexAttribivARB _al_glGetVertexAttribivARB +#define glGetVertexAttribPointervARB _al_glGetVertexAttribPointervARB +#define glIsProgramARB _al_glIsProgramARB +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_buffer_object +#define glBindBufferARB _al_glBindBufferARB +#define glDeleteBuffersARB _al_glDeleteBuffersARB +#define glGenBuffersARB _al_glGenBuffersARB +#define glIsBufferARB _al_glIsBufferARB +#define glBufferDataARB _al_glBufferDataARB +#define glBufferSubDataARB _al_glBufferSubDataARB +#define glGetBufferSubDataARB _al_glGetBufferSubDataARB +#define glMapBufferARB _al_glMapBufferARB +#define glUnmapBufferARB _al_glUnmapBufferARB +#define glGetBufferParameterivARB _al_glGetBufferParameterivARB +#define glGetBufferPointervARB _al_glGetBufferPointervARB +#endif + +#if defined _ALLEGRO_GL_ARB_occlusion_query +#define glGenQueriesARB _al_glGenQueriesARB +#define glDeleteQueriesARB _al_glDeleteQueriesARB +#define glIsQueryARB _al_glIsQueryARB +#define glBeginQueryARB _al_glBeginQueryARB +#define glEndQueryARB _al_glEndQueryARB +#define glGetQueryivARB _al_glGetQueryivARB +#define glGetQueryObjectivARB _al_glGetQueryObjectivARB +#define glGetQueryObjectuivARB _al_glGetQueryObjectuivARB +#endif + +#if defined _ALLEGRO_GL_ARB_shader_objects +#define glDeleteObjectARB _al_glDeleteObjectARB +#define glGetHandleARB _al_glGetHandleARB +#define glDetachObjectARB _al_glDetachObjectARB +#define glCreateShaderObjectARB _al_glCreateShaderObjectARB +#define glShaderSourceARB _al_glShaderSourceARB +#define glCompileShaderARB _al_glCompileShaderARB +#define glCreateProgramObjectARB _al_glCreateProgramObjectARB +#define glAttachObjectARB _al_glAttachObjectARB +#define glLinkProgramARB _al_glLinkProgramARB +#define glUseProgramObjectARB _al_glUseProgramObjectARB +#define glValidateProgramARB _al_glValidateProgramARB +#define glUniform1fARB _al_glUniform1fARB +#define glUniform2fARB _al_glUniform2fARB +#define glUniform3fARB _al_glUniform3fARB +#define glUniform4fARB _al_glUniform4fARB +#define glUniform1iARB _al_glUniform1iARB +#define glUniform2iARB _al_glUniform2iARB +#define glUniform3iARB _al_glUniform3iARB +#define glUniform4iARB _al_glUniform4iARB +#define glUniform1fvARB _al_glUniform1fvARB +#define glUniform2fvARB _al_glUniform2fvARB +#define glUniform3fvARB _al_glUniform3fvARB +#define glUniform4fvARB _al_glUniform4fvARB +#define glUniform1ivARB _al_glUniform1ivARB +#define glUniform2ivARB _al_glUniform2ivARB +#define glUniform3ivARB _al_glUniform3ivARB +#define glUniform4ivARB _al_glUniform4ivARB +#define glUniformMatrix2fvARB _al_glUniformMatrix2fvARB +#define glUniformMatrix3fvARB _al_glUniformMatrix3fvARB +#define glUniformMatrix4fvARB _al_glUniformMatrix4fvARB +#define glGetObjectParameterfvARB _al_glGetObjectParameterfvARB +#define glGetObjectParameterivARB _al_glGetObjectParameterivARB +#define glGetInfoLogARB _al_glGetInfoLogARB +#define glGetAttachedObjectsARB _al_glGetAttachedObjectsARB +#define glGetUniformLocationARB _al_glGetUniformLocationARB +#define glGetActiveUniformARB _al_glGetActiveUniformARB +#define glGetUniformfvARB _al_glGetUniformfvARB +#define glGetUniformivARB _al_glGetUniformivARB +#define glGetShaderSourceARB _al_glGetShaderSourceARB +#endif + +#ifdef _ALLEGRO_GL_ARB_vertex_shader +#ifndef GL_ARB_vertex_program +#define glVertexAttrib1fARB _al_glVertexAttrib1fARB +#define glVertexAttrib1sARB _al_glVertexAttrib1sARB +#define glVertexAttrib1dARB _al_glVertexAttrib1dARB +#define glVertexAttrib2fARB _al_glVertexAttrib2fARB +#define glVertexAttrib2sARB _al_glVertexAttrib2sARB +#define glVertexAttrib2dARB _al_glVertexAttrib2dARB +#define glVertexAttrib3fARB _al_glVertexAttrib3fARB +#define glVertexAttrib3sARB _al_glVertexAttrib3sARB +#define glVertexAttrib3dARB _al_glVertexAttrib3dARB +#define glVertexAttrib4fARB _al_glVertexAttrib4fARB +#define glVertexAttrib4sARB _al_glVertexAttrib4sARB +#define glVertexAttrib4dARB _al_glVertexAttrib4dARB +#define glVertexAttrib4NubARB _al_glVertexAttrib4NubARB +#define glVertexAttrib1fvARB _al_glVertexAttrib1fvARB +#define glVertexAttrib1svARB _al_glVertexAttrib1svARB +#define glVertexAttrib1dvARB _al_glVertexAttrib1dvARB +#define glVertexAttrib2fvARB _al_glVertexAttrib2fvARB +#define glVertexAttrib2svARB _al_glVertexAttrib2svARB +#define glVertexAttrib2dvARB _al_glVertexAttrib2dvARB +#define glVertexAttrib3fvARB _al_glVertexAttrib3fvARB +#define glVertexAttrib3svARB _al_glVertexAttrib3svARB +#define glVertexAttrib3dvARB _al_glVertexAttrib3dvARB +#define glVertexAttrib4fvARB _al_glVertexAttrib4fvARB +#define glVertexAttrib4svARB _al_glVertexAttrib4svARB +#define glVertexAttrib4dvARB _al_glVertexAttrib4dvARB +#define glVertexAttrib4ivARB _al_glVertexAttrib4ivARB +#define glVertexAttrib4bvARB _al_glVertexAttrib4bvARB +#define glVertexAttrib4ubvARB _al_glVertexAttrib4ubvARB +#define glVertexAttrib4usvARB _al_glVertexAttrib4usvARB +#define glVertexAttrib4uivARB _al_glVertexAttrib4uivARB +#define glVertexAttrib4NbvARB _al_glVertexAttrib4NbvARB +#define glVertexAttrib4NsvARB _al_glVertexAttrib4NsvARB +#define glVertexAttrib4NivARB _al_glVertexAttrib4NivARB +#define glVertexAttrib4NubvARB _al_glVertexAttrib4NubvARB +#define glVertexAttrib4NusvARB _al_glVertexAttrib4NusvARB +#define glVertexAttrib4NuivARB _al_glVertexAttrib4NuivARB +#define glVertexAttribPointerARB _al_glVertexAttribPointerARB +#define glEnableVertexAttribArrayARB _al_glEnableVertexAttribArrayARB +#define glDisableVertexAttribArrayARB _al_glDisableVertexAttribArrayARB +#endif +#define glBindAttribLocationARB _al_glBindAttribLocationARB +#define glGetActiveAttribARB _al_glGetActiveAttribARB +#define glGetAttribLocationARB _al_glGetAttribLocationARB +#ifndef GL_ARB_vertex_program +#define glGetVertexAttribdvARB _al_glGetVertexAttribdvARB +#define glGetVertexAttribfvARB _al_glGetVertexAttribfvARB +#define glGetVertexAttribivARB _al_glGetVertexAttribivARB +#define glGetVertexAttribPointervARB _al_glGetVertexAttribPointervARB +#endif +#endif + +#if defined _ALLEGRO_GL_ARB_draw_buffers +#define glDrawBuffersARB _al_glDrawBuffersARB +#endif + +#if defined _ALLEGRO_GL_ARB_color_buffer_float +#define glClampColorARB _al_glClampColorARB +#endif + +#if defined _ALLEGRO_GL_ARB_draw_instanced +#define glDrawArraysInstancedARB _al_glDrawArraysInstancedARB +#define glDrawElementsInstancedARB _al_glDrawElementsInstancedARB +#endif + +#if defined _ALLEGRO_GL_ARB_framebuffer_object +#define glIsRenderbuffer _al_glIsRenderbuffer +#define glBindRenderbuffer _al_glBindRenderbuffer +#define glDeleteRenderbuffers _al_glDeleteRenderbuffers +#define glGenRenderbuffers _al_glGenRenderbuffers +#define glRenderbufferStorage _al_glRenderbufferStorage +#define glGetRenderbufferParameteriv _al_glGetRenderbufferParameteriv +#define glIsFramebuffer _al_glIsFramebuffer +#define glBindFramebuffer _al_glBindFramebuffer +#define glDeleteFramebuffers _al_glDeleteFramebuffers +#define glGenFramebuffers _al_glGenFramebuffers +#define glCheckFramebufferStatus _al_glCheckFramebufferStatus +#define glFramebufferTexture1D _al_glFramebufferTexture1D +#define glFramebufferTexture2D _al_glFramebufferTexture2D +#define glFramebufferTexture3D _al_glFramebufferTexture3D +#define glFramebufferRenderbuffer _al_glFramebufferRenderbuffer +#define glGetFramebufferAttachmentParameteriv _al_glGetFramebufferAttachmentParameteriv +#define glGenerateMipmap _al_glGenerateMipmap +#define glBlitFramebuffer _al_glBlitFramebuffer +#define glRenderbufferStorageMultisample _al_glRenderbufferStorageMultisample +#define glFramebufferTextureLayer _al_glFramebufferTextureLayer +#endif + +#if defined _ALLEGRO_GL_ARB_geometry_shader4 +#define glProgramParameteriARB _al_glProgramParameteriARB +#define glFramebufferTextureARB _al_glFramebufferTextureARB +#define glFramebufferTextureLayerARB _al_glFramebufferTextureLayerARB +#define glFramebufferTextureFaceARB _al_glFramebufferTextureFaceARB +#endif + +#if defined _ALLEGRO_GL_ARB_instanced_arrays +#define glVertexAttribDivisor _al_glVertexAttribDivisor +#endif + +#if defined _ALLEGRO_GL_ARB_map_buffer_range +#define glMapBufferRange _al_glMapBufferRange +#define glFlushMappedBufferRange _al_glFlushMappedBufferRange +#endif + +#if defined _ALLEGRO_GL_ARB_texture_buffer_object +#define glTexBufferARB _al_glTexBufferARB +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_array_object +#define glBindVertexArray _al_glBindVertexArray +#define glDeleteVertexArrays _al_glDeleteVertexArrays +#define glGenVertexArrays _al_glGenVertexArrays +#define glIsVertexArray _al_glIsVertexArray +#endif + +#if defined _ALLEGRO_GL_ARB_uniform_buffer_object +#define glGetUniformIndices _al_glGetUniformIndices +#define glGetActiveUniformsiv _al_glGetActiveUniformsiv +#define glGetActiveUniformName _al_glGetActiveUniformName +#define glGetUniformBlockIndex _al_glGetUniformBlockIndex +#define glGetActiveUniformBlockiv _al_glGetActiveUniformBlockiv +#define glGetActiveUniformBlockName _al_glGetActiveUniformBlockName +#define glUniformBlockBinding _al_glUniformBlockBinding +#endif + +#if defined _ALLEGRO_GL_ARB_copy_buffer +#define glCopyBufferSubData _al_glCopyBufferSubData +#endif + + +#if defined _ALLEGRO_GL_ARB_draw_elements_base_vertex +#define glDrawElementsBaseVertex _al_glDrawElementsBaseVertex +#define glDrawRangeElementsBaseVertex _al_glDrawRangeElementsBaseVertex +#define glDrawElementsInstancedBaseVertex _al_glDrawElementsInstancedBaseVertex +#define glMultiDrawElementsBaseVertex _al_glMultiDrawElementsBaseVertex +#endif + +#if defined _ALLEGRO_GL_ARB_provoking_vertex +#define glProvokingVertex _al_glProvokingVertex +#endif + +#if defined _ALLEGRO_GL_ARB_sync +#define glFenceSync _al_glFenceSync +#define glIsSync _al_glIsSync +#define glDeleteSync _al_glDeleteSync +#define glClientWaitSync _al_glClientWaitSync +#define glWaitSync _al_glWaitSync +#define glGetInteger64v _al_glGetInteger64v +#define glGetSynciv _al_glGetSynciv +#endif + +#if defined _ALLEGRO_GL_ARB_texture_multisample +#define glTexImage2DMultisample _al_glTexImage2DMultisample +#define glTexImage3DMultisample _al_glTexImage3DMultisample +#define glGetMultisamplefv _al_glGetMultisamplefv +#define glSampleMaski _al_glSampleMaski +#endif + +#if defined _ALLEGRO_GL_ARB_draw_buffers_blend +#define glBlendEquationi _al_glBlendEquationi +#define glBlendEquationSeparatei _al_glBlendEquationSeparatei +#define glBlendFunci _al_glBlendFunci +#define glBlendFuncSeparatei _al_glBlendFuncSeparatei +#endif + +#if defined _ALLEGRO_GL_ARB_sample_shading +#define glMinSampleShading _al_glMinSampleShading +#endif + +#if defined _ALLEGRO_GL_ARB_shading_language_include +#define glNamedStringARB _al_glNamedStringARB +#define glDeleteNamedStringARB _al_glDeleteNamedStringARB +#define glCompileShaderIncludeARB _al_glCompileShaderIncludeARB +#define glIsNamedStringARB _al_glIsNamedStringARB +#define glGetNamedStringARB _al_glGetNamedStringARB +#define glGetNamedStringivARB _al_glGetNamedStringivARB +#endif + +#if defined _ALLEGRO_GL_ARB_blend_func_extended +#define glBindFragDataLocationIndexed _al_glBindFragDataLocationIndexed +#define glGetFragDataIndex _al_glGetFragDataIndex +#endif + +#if defined _ALLEGRO_GL_ARB_sampler_objects +#define glGenSamplers _al_glGenSamplers +#define glDeleteSamplers _al_glDeleteSamplers +#define glIsSampler _al_glIsSampler +#define glBindSampler _al_glBindSampler +#define glSamplerParameteri _al_glSamplerParameteri +#define glSamplerParameteriv _al_glSamplerParameteriv +#define glSamplerParameterf _al_glSamplerParameterf +#define glSamplerParameterfv _al_glSamplerParameterfv +#define glSamplerParameterIiv _al_glSamplerParameterIiv +#define glSamplerParameterIuiv _al_glSamplerParameterIuiv +#define glGetSamplerParameteriv _al_glGetSamplerParameteriv +#define glGetSamplerParameterIiv _al_glGetSamplerParameterIiv +#define glGetSamplerParameterfv _al_glGetSamplerParameterfv +#define glGetSamplerParameterIfv _al_glGetSamplerParameterIfv +#endif + +#if defined _ALLEGRO_GL_ARB_timer_query +#define glQueryCounter _al_glQueryCounter +#define glGetQueryObjecti64v _al_glGetQueryObjecti64v +#define glGetQueryObjectui64v _al_glGetQueryObjectui64v +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev +#define glVertexP2ui _al_glVertexP2ui +#define glVertexP2uiv _al_glVertexP2uiv +#define glVertexP3ui _al_glVertexP3ui +#define glVertexP3uiv _al_glVertexP3uiv +#define glVertexP4ui _al_glVertexP4ui +#define glVertexP4uiv _al_glVertexP4uiv +#define glTexCoordP1ui _al_glTexCoordP1ui +#define glTexCoordP1uiv _al_glTexCoordP1uiv +#define glTexCoordP2ui _al_glTexCoordP2ui +#define glTexCoordP2uiv _al_glTexCoordP2uiv +#define glTexCoordP3ui _al_glTexCoordP3ui +#define glTexCoordP3uiv _al_glTexCoordP3uiv +#define glTexCoordP4ui _al_glTexCoordP4ui +#define glTexCoordP4uiv _al_glTexCoordP4uiv +#define glMultiTexCoordP1ui _al_glMultiTexCoordP1ui +#define glMultiTexCoordP1uiv _al_glMultiTexCoordP1uiv +#define glMultiTexCoordP2ui _al_glMultiTexCoordP2ui +#define glMultiTexCoordP2uiv _al_glMultiTexCoordP2uiv +#define glMultiTexCoordP3ui _al_glMultiTexCoordP3ui +#define glMultiTexCoordP3uiv _al_glMultiTexCoordP3uiv +#define glMultiTexCoordP4ui _al_glMultiTexCoordP4ui +#define glMultiTexCoordP4uiv _al_glMultiTexCoordP4uiv +#define glNormalP3ui _al_glNormalP3ui +#define glNormalP3uiv _al_glNormalP3uiv +#define glColorP3ui _al_glColorP3ui +#define glColorP3uiv _al_glColorP3uiv +#define glColorP4ui _al_glColorP4ui +#define glColorP4uiv _al_glColorP4uiv +#define glSecondaryColorP3ui _al_glSecondaryColorP3ui +#define glSecondaryColorP3uiv _al_glSecondaryColorP3uiv +#define glVertexAttribP1ui _al_glVertexAttribP1ui +#define glVertexAttribP1uiv _al_glVertexAttribP1uiv +#define glVertexAttribP2ui _al_glVertexAttribP2ui +#define glVertexAttribP2uiv _al_glVertexAttribP2uiv +#define glVertexAttribP3ui _al_glVertexAttribP3ui +#define glVertexAttribP3uiv _al_glVertexAttribP3uiv +#define glVertexAttribP4ui _al_glVertexAttribP4ui +#define glVertexAttribP4uiv _al_glVertexAttribP4uiv +#endif + +#if defined _ALLEGRO_GL_ARB_draw_indirect +#define glDrawArraysIndirect _al_glDrawArraysIndirect +#define glDrawElementsIndirect _al_glDrawElementsIndirect +#endif + +#if defined _ALLEGRO_GL_ARB_gpu_shader_fp64 +#define glUniform1d _al_glUniform1d +#define glUniform2d _al_glUniform2d +#define glUniform3d _al_glUniform3d +#define glUniform4d _al_glUniform4d +#define glUniform1dv _al_glUniform1dv +#define glUniform2dv _al_glUniform2dv +#define glUniform3dv _al_glUniform3dv +#define glUniform4dv _al_glUniform4dv +#define glUniformMatrix2dv _al_glUniformMatrix2dv +#define glUniformMatrix3dv _al_glUniformMatrix3dv +#define glUniformMatrix4dv _al_glUniformMatrix4dv +#define glUniformMatrix2x3dv _al_glUniformMatrix2x3dv +#define glUniformMatrix2x4dv _al_glUniformMatrix2x4dv +#define glUniformMatrix3x2dv _al_glUniformMatrix3x2dv +#define glUniformMatrix3x4dv _al_glUniformMatrix3x4dv +#define glUniformMatrix4x2dv _al_glUniformMatrix4x2dv +#define glUniformMatrix4x3dv _al_glUniformMatrix4x3dv +#define glGetUniformdv _al_glGetUniformdv +#define glProgramUniform1dEXT _al_glProgramUniform1dEXT +#define glProgramUniform2dEXT _al_glProgramUniform2dEXT +#define glProgramUniform3dEXT _al_glProgramUniform3dEXT +#define glProgramUniform4dEXT _al_glProgramUniform4dEXT +#define glProgramUniform1dvEXT _al_glProgramUniform1dvEXT +#define glProgramUniform2dvEXT _al_glProgramUniform2dvEXT +#define glProgramUniform3dvEXT _al_glProgramUniform3dvEXT +#define glProgramUniform4dvEXT _al_glProgramUniform4dvEXT +#define glProgramUniformMatrix2dvEXT _al_glProgramUniformMatrix2dvEXT +#define glProgramUniformMatrix3dvEXT _al_glProgramUniformMatrix3dvEXT +#define glProgramUniformMatrix4dvEXT _al_glProgramUniformMatrix4dvEXT +#define glProgramUniformMatrix2x3dvEXT _al_glProgramUniformMatrix2x3dvEXT +#define glProgramUniformMatrix2x4dvEXT _al_glProgramUniformMatrix2x4dvEXT +#define glProgramUniformMatrix3x2dvEXT _al_glProgramUniformMatrix3x2dvEXT +#define glProgramUniformMatrix3x4dvEXT _al_glProgramUniformMatrix3x4dvEXT +#define glProgramUniformMatrix4x2dvEXT _al_glProgramUniformMatrix4x2dvEXT +#define glProgramUniformMatrix4x3dvEXT _al_glProgramUniformMatrix4x3dvEXT +#endif + +#if defined _ALLEGRO_GL_ARB_shader_subroutine +#define glGetSubroutineUniformLocation _al_glGetSubroutineUniformLocation +#define glGetSubroutineIndex _al_glGetSubroutineIndex +#define glGetActiveSubroutineUniformiv _al_glGetActiveSubroutineUniformiv +#define glGetActiveSubroutineUniformName _al_glGetActiveSubroutineUniformName +#define glGetActiveSubroutineName _al_glGetActiveSubroutineName +#define glUniformSubroutinesuiv _al_glUniformSubroutinesuiv +#define glGetUniformSubroutineuiv _al_glGetUniformSubroutineuiv +#define glGetProgramStageiv _al_glGetProgramStageiv +#endif + +#if defined _ALLEGRO_GL_ARB_tessellation_shader +#define glPatchParameteri _al_glPatchParameteri +#define glPatchParameterfv _al_glPatchParameterfv +#endif + +#if defined _ALLEGRO_GL_ARB_transform_feedback2 +#define glBindTransformFeedback _al_glBindTransformFeedback +#define glDeleteTransformFeedbacks _al_glDeleteTransformFeedbacks +#define glGenTransformFeedbacks _al_glGenTransformFeedbacks +#define glIsTransformFeedback _al_glIsTransformFeedback +#define glPauseTransformFeedback _al_glPauseTransformFeedback +#define glResumeTransformFeedback _al_glResumeTransformFeedback +#define glDrawTransformFeedback _al_glDrawTransformFeedback +#endif + +#if defined _ALLEGRO_GL_ARB_transform_feedback3 +#define glDrawTransformFeedbackStream _al_glDrawTransformFeedbackStream +#define glBeginQueryIndexed _al_glBeginQueryIndexed +#define glEndQueryIndexed _al_glEndQueryIndexed +#define glGetQueryIndexediv _al_glGetQueryIndexediv +#endif + + +/**/ + + +#if defined _ALLEGRO_GL_EXT_blend_color +#define glBlendColorEXT _al_glBlendColorEXT +#endif + +#if defined _ALLEGRO_GL_EXT_polygon_offset +#define glPolygonOffsetEXT _al_glPolygonOffsetEXT +#endif + +#if defined _ALLEGRO_GL_EXT_texture3D +#define glTexImage3DEXT _al_glTexImage3DEXT +#define glTexSubImage3DEXT _al_glTexSubImage3DEXT +#endif + +#if defined _ALLEGRO_GL_SGIS_texture_filter4 +#define glGetTexFilterFuncSGIS _al_glGetTexFilterFuncSGIS +#define glTexFilterFuncSGIS _al_glTexFilterFuncSGIS +#endif + +#if defined _ALLEGRO_GL_EXT_subtexture +#define glTexSubImage1DEXT _al_glTexSubImage1DEXT +#define glTexSubImage2DEXT _al_glTexSubImage2DEXT +#endif + +#if defined _ALLEGRO_GL_EXT_copy_texture +#define glCopyTexImage1DEXT _al_glCopyTexImage1DEXT +#define glCopyTexImage2DEXT _al_glCopyTexImage2DEXT +#define glCopyTexSubImage1DEXT _al_glCopyTexSubImage1DEXT +#define glCopyTexSubImage2DEXT _al_glCopyTexSubImage2DEXT +#define glCopyTexSubImage3DEXT _al_glCopyTexSubImage3DEXT +#endif + +#if defined _ALLEGRO_GL_EXT_histogram +#define glGetHistogramEXT _al_glGetHistogramEXT +#define glGetHistogramParameterfvEXT _al_glGetHistogramParameterfvEXT +#define glGetHistogramParameterivEXT _al_glGetHistogramParameterivEXT +#define glGetMinmaxEXT _al_glGetMinmaxEXT +#define glGetMinmaxParameterfvEXT _al_glGetMinmaxParameterfvEXT +#define glGetMinmaxParameterivEXT _al_glGetMinmaxParameterivEXT +#define glHistogramEXT _al_glHistogramEXT +#define glMinmaxEXT _al_glMinmaxEXT +#define glResetHistogramEXT _al_glResetHistogramEXT +#define glResetMinmaxEXT _al_glResetMinmaxEXT +#endif + +#if defined _ALLEGRO_GL_EXT_convolution +#define glConvolutionFilter1DEXT _al_glConvolutionFilter1DEXT +#define glConvolutionFilter2DEXT _al_glConvolutionFilter2DEXT +#define glConvolutionParameterfEXT _al_glConvolutionParameterfEXT +#define glConvolutionParameterfvEXT _al_glConvolutionParameterfvEXT +#define glConvolutionParameteriEXT _al_glConvolutionParameteriEXT +#define glConvolutionParameterivEXT _al_glConvolutionParameterivEXT +#define glCopyConvolutionFilter1DEXT _al_glCopyConvolutionFilter1DEXT +#define glCopyConvolutionFilter2DEXT _al_glCopyConvolutionFilter2DEXT +#define glGetConvolutionFilterEXT _al_glGetConvolutionFilterEXT +#define glGetConvolutionParameterfvEXT _al_glGetConvolutionParameterfvEXT +#define glGetConvolutionParameterivEXT _al_glGetConvolutionParameterivEXT +#define glGetSeparableFilterEXT _al_glGetSeparableFilterEXT +#define glSeparableFilter2DEXT _al_glSeparableFilter2DEXT +#endif + +#if defined _ALLEGRO_GL_SGI_color_table +#define glColorTableSGI _al_glColorTableSGI +#define glColorTableParameterfvSGI _al_glColorTableParameterfvSGI +#define glColorTableParameterivSGI _al_glColorTableParameterivSGI +#define glCopyColorTableSGI _al_glCopyColorTableSGI +#define glGetColorTableSGI _al_glGetColorTableSGI +#define glGetColorTableParameterfvSGI _al_glGetColorTableParameterfvSGI +#define glGetColorTableParameterivSGI _al_glGetColorTableParameterivSGI +#endif + +#if defined _ALLEGRO_GL_SGIX_pixel_texture +#define glPixelTexGenSGIX _al_glPixelTexGenSGIX +#endif + +#if defined _ALLEGRO_GL_SGIS_pixel_texture +#define glPixelTexGenParameteriSGIS _al_glPixelTexGenParameteriSGIS +#define glPixelTexGenParameterivSGIS _al_glPixelTexGenParameterivSGIS +#define glPixelTexGenParameterfSGIS _al_glPixelTexGenParameterfSGIS +#define glPixelTexGenParameterfvSGIS _al_glPixelTexGenParameterfvSGIS +#define glGetPixelTexGenParameterivSGIS _al_glGetPixelTexGenParameterivSGIS +#define glGetPixelTexGenParameterfvSGIS _al_glGetPixelTexGenParameterfvSGIS +#endif + +#if defined _ALLEGRO_GL_SGIS_texture4D +#define glTexImage4DSGIS _al_glTexImage4DSGIS +#define glTexSubImage4DSGIS _al_glTexSubImage4DSGIS +#endif + +#if defined _ALLEGRO_GL_EXT_texture_object +#define glAreTexturesResidentEXT _al_glAreTexturesResidentEXT +#define glBindTextureEXT _al_glBindTextureEXT +#define glDeleteTexturesEXT _al_glDeleteTexturesEXT +#define glGenTexturesEXT _al_glGenTexturesEXT +#define glIsTextureEXT _al_glIsTextureEXT +#define glPrioritizeTexturesEXT _al_glPrioritizeTexturesEXT +#endif + +#if defined _ALLEGRO_GL_SGIS_detail_texture +#define glDetailTexFuncSGIS _al_glDetailTexFuncSGIS +#define glGetDetailTexFuncSGIS _al_glGetDetailTexFuncSGIS +#endif + +#if defined _ALLEGRO_GL_SGIS_sharpen_texture +#define glSharpenTexFuncSGIS _al_glSharpenTexFuncSGIS +#define glGetSharpenTexFuncSGIS _al_glGetSharpenTexFuncSGIS +#endif + +#if defined _ALLEGRO_GL_SGIS_multisample +#define glSampleMaskSGIS _al_glSampleMaskSGIS +#define glSamplePatternSGIS _al_glSamplePatternSGIS +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_array +#define glArrayElementEXT _al_glArrayElementEXT +#define glColorPointerEXT _al_glColorPointerEXT +#define glDrawArraysEXT _al_glDrawArraysEXT +#define glEdgeFlagPointerEXT _al_glEdgeFlagPointerEXT +#define glGetPointervEXT _al_glGetPointervEXT +#define glIndexPointerEXT _al_glIndexPointerEXT +#define glNormalPointerEXT _al_glNormalPointerEXT +#define glTexCoordPointerEXT _al_glTexCoordPointerEXT +#define glVertexPointerEXT _al_glVertexPointerEXT +#endif + +#if defined _ALLEGRO_GL_EXT_blend_minmax +#define glBlendEquationEXT _al_glBlendEquationEXT +#endif + +#if defined _ALLEGRO_GL_SGIX_sprite +#define glSpriteParameterfSGIX _al_glSpriteParameterfSGIX +#define glSpriteParameterfvSGIX _al_glSpriteParameterfvSGIX +#define glSpriteParameteriSGIX _al_glSpriteParameteriSGIX +#define glSpriteParameterivSGIX _al_glSpriteParameterivSGIX +#endif + +#if defined _ALLEGRO_GL_EXT_point_parameters +#define glPointParameterfEXT _al_glPointParameterfEXT +#define glPointParameterfvEXT _al_glPointParameterfvEXT +#endif + +#if defined _ALLEGRO_GL_SGIS_point_parameters +#define glPointParameterfSGIS _al_glPointParameterfSGIS +#define glPointParameterfvSGIS _al_glPointParameterfvSGIS +#endif + +#if defined _ALLEGRO_GL_SGIX_instruments +#define glGetInstrumentsSGIX _al_glGetInstrumentsSGIX +#define glInstrumentsBufferSGIX _al_glInstrumentsBufferSGIX +#define glPollInstrumentsSGIX _al_glPollInstrumentsSGIX +#define glReadInstrumentsSGIX _al_glReadInstrumentsSGIX +#define glStartInstrumentsSGIX _al_glStartInstrumentsSGIX +#define glStopInstrumentsSGIX _al_glStopInstrumentsSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_framezoom +#define glFrameZoomSGIX _al_glFrameZoomSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_tag_sample_buffer +#define glTagSampleBufferSGIX _al_glTagSampleBufferSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_polynomial_ffd +#define glDeformationMap3dSGIX _al_glDeformationMap3dSGIX +#define glDeformationMap3fSGIX _al_glDeformationMap3fSGIX +#define glDeformSGIX _al_glDeformSGIX +#define glLoadIdentityDeformationMapSGIX _al_glLoadIdentityDeformationMapSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_reference_plane +#define glReferencePlaneSGIX _al_glReferencePlaneSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_flush_raster +#define glFlushRasterSGIX _al_glFlushRasterSGIX +#endif + +#if defined _ALLEGRO_GL_SGIS_fog_function +#define glFogFuncSGIS _al_glFogFuncSGIS +#define glGetFogFuncSGIS _al_glGetFogFuncSGIS +#endif + +#if defined _ALLEGRO_GL_HP_image_transform +#define glImageTransformParameteriHP _al_glImageTransformParameteriHP +#define glImageTransformParameterfHP _al_glImageTransformParameterfHP +#define glImageTransformParameterivHP _al_glImageTransformParameterivHP +#define glImageTransformParameterfvHP _al_glImageTransformParameterfvHP +#define glGetImageTransformParameterivHP _al_glGetImageTransformParameterivHP +#define glGetImageTransformParameterfvHP _al_glGetImageTransformParameterfvHP +#endif + +#if defined _ALLEGRO_GL_EXT_color_subtable +#ifndef GL_EXT_paletted_texture +#define glColorSubTableEXT _al_glColorSubTableEXT +#endif +#define glCopyColorSubTableEXT _al_glCopyColorSubTableEXT +#endif + +#if defined _ALLEGRO_GL_PGI_misc_hints +#define glHintPGI _al_glHintPGI +#endif + +#if defined _ALLEGRO_GL_EXT_paletted_texture +#define glColorTableEXT _al_glColorTableEXT +#define glGetColorTableEXT _al_glGetColorTableEXT +#define glGetColorTableParameterivEXT _al_glGetColorTableParameterivEXT +#define glGetColorTableParameterfvEXT _al_glGetColorTableParameterfvEXT +#endif + +#if defined _ALLEGRO_GL_SGIX_list_priority +#define glGetListParameterfvSGIX _al_glGetListParameterfvSGIX +#define glGetListParameterivSGIX _al_glGetListParameterivSGIX +#define glListParameterfSGIX _al_glListParameterfSGIX +#define glListParameterfvSGIX _al_glListParameterfvSGIX +#define glListParameteriSGIX _al_glListParameteriSGIX +#define glListParameterivSGIX _al_glListParameterivSGIX +#endif + +#if defined _ALLEGRO_GL_EXT_index_material +#define glIndexMaterialEXT _al_glIndexMaterialEXT +#endif + +#if defined _ALLEGRO_GL_EXT_index_func +#define glIndexFuncEXT _al_glIndexFuncEXT +#endif + +#if defined _ALLEGRO_GL_EXT_compiled_vertex_array +#define glLockArraysEXT _al_glLockArraysEXT +#define glUnlockArraysEXT _al_glUnlockArraysEXT +#endif + +#if defined _ALLEGRO_GL_EXT_cull_vertex +#define glCullParameterdvEXT _al_glCullParameterdvEXT +#define glCullParameterfvEXT _al_glCullParameterfvEXT +#endif + +#if defined _ALLEGRO_GL_SGIX_fragment_lighting +#define glFragmentColorMaterialSGIX _al_glFragmentColorMaterialSGIX +#define glFragmentLightfSGIX _al_glFragmentLightfSGIX +#define glFragmentLightfvSGIX _al_glFragmentLightfvSGIX +#define glFragmentLightiSGIX _al_glFragmentLightiSGIX +#define glFragmentLightivSGIX _al_glFragmentLightivSGIX +#define glFragmentLightModelfSGIX _al_glFragmentLightModelfSGIX +#define glFragmentLightModelfvSGIX _al_glFragmentLightModelfvSGIX +#define glFragmentLightModeliSGIX _al_glFragmentLightModeliSGIX +#define glFragmentLightModelivSGIX _al_glFragmentLightModelivSGIX +#define glFragmentMaterialfSGIX _al_glFragmentMaterialfSGIX +#define glFragmentMaterialfvSGIX _al_glFragmentMaterialfvSGIX +#define glFragmentMaterialiSGIX _al_glFragmentMaterialiSGIX +#define glFragmentMaterialivSGIX _al_glFragmentMaterialivSGIX +#define glGetFragmentLightfvSGIX _al_glGetFragmentLightfvSGIX +#define glGetFragmentLightivSGIX _al_glGetFragmentLightivSGIX +#define glGetFragmentMaterialfvSGIX _al_glGetFragmentMaterialfvSGIX +#define glGetFragmentMaterialivSGIX _al_glGetFragmentMaterialivSGIX +#define glLightEnviSGIX _al_glLightEnviSGIX +#endif + +#if defined _ALLEGRO_GL_EXT_draw_range_elements +#define glDrawRangeElementsEXT _al_glDrawRangeElementsEXT +#endif + +#if defined _ALLEGRO_GL_EXT_light_texture +#define glApplyTextureEXT _al_glApplyTextureEXT +#define glTextureLightEXT _al_glTextureLightEXT +#define glTextureMaterialEXT _al_glTextureMaterialEXT +#endif + +#if defined _ALLEGRO_GL_SGIX_async +#define glAsyncMarkerSGIX _al_glAsyncMarkerSGIX +#define glFinishAsyncSGIX _al_glFinishAsyncSGIX +#define glPollAsyncSGIX _al_glPollAsyncSGIX +#define glGenAsyncMarkersSGIX _al_glGenAsyncMarkersSGIX +#define glDeleteAsyncMarkersSGIX _al_glDeleteAsyncMarkersSGIX +#define glIsAsyncMarkerSGIX _al_glIsAsyncMarkerSGIX +#endif + +#if defined _ALLEGRO_GL_INTEL_parallel_arrays +#define glVertexPointervINTEL _al_glVertexPointervINTEL +#define glNormalPointervINTEL _al_glNormalPointervINTEL +#define glColorPointervINTEL _al_glColorPointervINTEL +#define glTexCoordPointervINTEL _al_glTexCoordPointervINTEL +#endif + +#if defined _ALLEGRO_GL_EXT_pixel_transform +#define glPixelTransformParameteriEXT _al_glPixelTransformParameteriEXT +#define glPixelTransformParameterfEXT _al_glPixelTransformParameterfEXT +#define glPixelTransformParameterivEXT _al_glPixelTransformParameterivEXT +#define glPixelTransformParameterfvEXT _al_glPixelTransformParameterfvEXT +#endif + +#if defined _ALLEGRO_GL_EXT_secondary_color +#define glSecondaryColor3bEXT _al_glSecondaryColor3bEXT +#define glSecondaryColor3bvEXT _al_glSecondaryColor3bvEXT +#define glSecondaryColor3dEXT _al_glSecondaryColor3dEXT +#define glSecondaryColor3dvEXT _al_glSecondaryColor3dvEXT +#define glSecondaryColor3fEXT _al_glSecondaryColor3fEXT +#define glSecondaryColor3fvEXT _al_glSecondaryColor3fvEXT +#define glSecondaryColor3iEXT _al_glSecondaryColor3iEXT +#define glSecondaryColor3ivEXT _al_glSecondaryColor3ivEXT +#define glSecondaryColor3sEXT _al_glSecondaryColor3sEXT +#define glSecondaryColor3svEXT _al_glSecondaryColor3svEXT +#define glSecondaryColor3ubEXT _al_glSecondaryColor3ubEXT +#define glSecondaryColor3ubvEXT _al_glSecondaryColor3ubvEXT +#define glSecondaryColor3uiEXT _al_glSecondaryColor3uiEXT +#define glSecondaryColor3uivEXT _al_glSecondaryColor3uivEXT +#define glSecondaryColor3usEXT _al_glSecondaryColor3usEXT +#define glSecondaryColor3usvEXT _al_glSecondaryColor3usvEXT +#define glSecondaryColorPointerEXT _al_glSecondaryColorPointerEXT +#endif + +#if defined _ALLEGRO_GL_EXT_texture_perturb_normal +#define glTextureNormalEXT _al_glTextureNormalEXT +#endif + +#if defined _ALLEGRO_GL_EXT_multi_draw_arrays +#define glMultiDrawArraysEXT _al_glMultiDrawArraysEXT +#define glMultiDrawElementsEXT _al_glMultiDrawElementsEXT +#endif + +#if defined _ALLEGRO_GL_EXT_fog_coord +#define glFogCoordfEXT _al_glFogCoordfEXT +#define glFogCoordfvEXT _al_glFogCoordfvEXT +#define glFogCoorddEXT _al_glFogCoorddEXT +#define glFogCoorddvEXT _al_glFogCoorddvEXT +#define glFogCoordPointerEXT _al_glFogCoordPointerEXT +#endif + +#if defined _ALLEGRO_GL_EXT_coordinate_frame +#define glTangent3bEXT _al_glTangent3bEXT +#define glTangent3bvEXT _al_glTangent3bvEXT +#define glTangent3dEXT _al_glTangent3dEXT +#define glTangent3dvEXT _al_glTangent3dvEXT +#define glTangent3fEXT _al_glTangent3fEXT +#define glTangent3fvEXT _al_glTangent3fvEXT +#define glTangent3iEXT _al_glTangent3iEXT +#define glTangent3ivEXT _al_glTangent3ivEXT +#define glTangent3sEXT _al_glTangent3sEXT +#define glTangent3svEXT _al_glTangent3svEXT +#define glBinormal3bEXT _al_glBinormal3bEXT +#define glBinormal3bvEXT _al_glBinormal3bvEXT +#define glBinormal3dEXT _al_glBinormal3dEXT +#define glBinormal3dvEXT _al_glBinormal3dvEXT +#define glBinormal3fEXT _al_glBinormal3fEXT +#define glBinormal3fvEXT _al_glBinormal3fvEXT +#define glBinormal3iEXT _al_glBinormal3iEXT +#define glBinormal3ivEXT _al_glBinormal3ivEXT +#define glBinormal3sEXT _al_glBinormal3sEXT +#define glBinormal3svEXT _al_glBinormal3svEXT +#define glTangentPointerEXT _al_glTangentPointerEXT +#define glBinormalPointerEXT _al_glBinormalPointerEXT +#endif + +#if defined _ALLEGRO_GL_SUNX_constant_data +#define glFinishTextureSUNX _al_glFinishTextureSUNX +#endif + +#if defined _ALLEGRO_GL_SUN_global_alpha +#define glGlobalAlphaFactorbSUN _al_glGlobalAlphaFactorbSUN +#define glGlobalAlphaFactorsSUN _al_glGlobalAlphaFactorsSUN +#define glGlobalAlphaFactoriSUN _al_glGlobalAlphaFactoriSUN +#define glGlobalAlphaFactorfSUN _al_glGlobalAlphaFactorfSUN +#define glGlobalAlphaFactordSUN _al_glGlobalAlphaFactordSUN +#define glGlobalAlphaFactorubSUN _al_glGlobalAlphaFactorubSUN +#define glGlobalAlphaFactorusSUN _al_glGlobalAlphaFactorusSUN +#define glGlobalAlphaFactoruiSUN _al_glGlobalAlphaFactoruiSUN +#endif + +#if defined _ALLEGRO_GL_SUN_triangle_list +#define glReplacementCodeuiSUN _al_glReplacementCodeuiSUN +#define glReplacementCodeusSUN _al_glReplacementCodeusSUN +#define glReplacementCodeubSUN _al_glReplacementCodeubSUN +#define glReplacementCodeuivSUN _al_glReplacementCodeuivSUN +#define glReplacementCodeusvSUN _al_glReplacementCodeusvSUN +#define glReplacementCodeubvSUN _al_glReplacementCodeubvSUN +#define glReplacementCodePointerSUN _al_glReplacementCodePointerSUN +#endif + +#if defined _ALLEGRO_GL_SUN_vertex +#define glColor4ubVertex2fSUN _al_glColor4ubVertex2fSUN +#define glColor4ubVertex2fvSUN _al_glColor4ubVertex2fvSUN +#define glColor4ubVertex3fSUN _al_glColor4ubVertex3fSUN +#define glColor4ubVertex3fvSUN _al_glColor4ubVertex3fvSUN +#define glColor3fVertex3fSUN _al_glColor3fVertex3fSUN +#define glColor3fVertex3fvSUN _al_glColor3fVertex3fvSUN +#define glNormal3fVertex3fSUN _al_glNormal3fVertex3fSUN +#define glNormal3fVertex3fvSUN _al_glNormal3fVertex3fvSUN +#define glColor4fNormal3fVertex3fSUN _al_glColor4fNormal3fVertex3fSUN +#define glColor4fNormal3fVertex3fvSUN _al_glColor4fNormal3fVertex3fvSUN +#define glTexCoord2fVertex3fSUN _al_glTexCoord2fVertex3fSUN +#define glTexCoord2fVertex3fvSUN _al_glTexCoord2fVertex3fvSUN +#define glTexCoord4fVertex4fSUN _al_glTexCoord4fVertex4fSUN +#define glTexCoord4fVertex4fvSUN _al_glTexCoord4fVertex4fvSUN +#define glTexCoord2fColor4ubVertex3fSUN _al_glTexCoord2fColor4ubVertex3fSUN +#define glTexCoord2fColor4ubVertex3fvSUN _al_glTexCoord2fColor4ubVertex3fvSUN +#define glTexCoord2fColor3fVertex3fSUN _al_glTexCoord2fColor3fVertex3fSUN +#define glTexCoord2fColor3fVertex3fvSUN _al_glTexCoord2fColor3fVertex3fvSUN +#define glTexCoord2fNormal3fVertex3fSUN _al_glTexCoord2fNormal3fVertex3fSUN +#define glTexCoord2fNormal3fVertex3fvSUN _al_glTexCoord2fNormal3fVertex3fvSUN +#define glTexCoord2fColor4fNormal3fVertex3fSUN _al_glTexCoord2fColor4fNormal3fVertex3fSUN +#define glTexCoord2fColor4fNormal3fVertex3fvSUN _al_glTexCoord2fColor4fNormal3fVertex3fvSUN +#define glTexCoord4fColor4fNormal3fVertex4fSUN _al_glTexCoord4fColor4fNormal3fVertex4fSUN +#define glTexCoord4fColor4fNormal3fVertex4fvSUN _al_glTexCoord4fColor4fNormal3fVertex4fvSUN +#define glReplacementCodeuiVertex3fSUN _al_glReplacementCodeuiVertex3fSUN +#define glReplacementCodeuiVertex3fvSUN _al_glReplacementCodeuiVertex3fvSUN +#define glReplacementCodeuiColor4ubVertex3fSUN _al_glReplacementCodeuiColor4ubVertex3fSUN +#define glReplacementCodeuiColor4ubVertex3fvSUN _al_glReplacementCodeuiColor4ubVertex3fvSUN +#define glReplacementCodeuiColor3fVertex3fSUN _al_glReplacementCodeuiColor3fVertex3fSUN +#define glReplacementCodeuiColor3fVertex3fvSUN _al_glReplacementCodeuiColor3fVertex3fvSUN +#define glReplacementCodeuiNormal3fVertex3fSUN _al_glReplacementCodeuiNormal3fVertex3fSUN +#define glReplacementCodeuiNormal3fVertex3fvSUN _al_glReplacementCodeuiNormal3fVertex3fvSUN +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN _al_glReplacementCodeuiColor4fNormal3fVertex3fSUN +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN _al_glReplacementCodeuiColor4fNormal3fVertex3fvSUN +#define glReplacementCodeuiTexCoord2fVertex3fSUN _al_glReplacementCodeuiTexCoord2fVertex3fSUN +#define glReplacementCodeuiTexCoord2fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fVertex3fvSUN +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN _al_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN _al_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN +#endif + +#if defined _ALLEGRO_GL_EXT_blend_func_separate +#define glBlendFuncSeparateEXT _al_glBlendFuncSeparateEXT +#endif + +#if defined _ALLEGRO_GL_INGR_blend_func_separate +#define glBlendFuncSeparateINGR _al_glBlendFuncSeparateINGR +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_weighting +#define glVertexWeightfEXT _al_glVertexWeightfEXT +#define glVertexWeightfvEXT _al_glVertexWeightfvEXT +#define glVertexWeightPointerEXT _al_glVertexWeightPointerEXT +#endif + +#if defined _ALLEGRO_GL_NV_vertex_array_range +#define glFlushVertexArrayRangeNV _al_glFlushVertexArrayRangeNV +#define glVertexArrayRangeNV _al_glVertexArrayRangeNV +#endif + +#if defined _ALLEGRO_GL_NV_register_combiners +#define glCombinerParameterfvNV _al_glCombinerParameterfvNV +#define glCombinerParameterfNV _al_glCombinerParameterfNV +#define glCombinerParameterivNV _al_glCombinerParameterivNV +#define glCombinerParameteriNV _al_glCombinerParameteriNV +#define glCombinerInputNV _al_glCombinerInputNV +#define glCombinerOutputNV _al_glCombinerOutputNV +#define glFinalCombinerInputNV _al_glFinalCombinerInputNV +#define glGetCombinerInputParameterfvNV _al_glGetCombinerInputParameterfvNV +#define glGetCombinerInputParameterivNV _al_glGetCombinerInputParameterivNV +#define glGetCombinerOutputParameterfvNV _al_glGetCombinerOutputParameterfvNV +#define glGetCombinerOutputParameterivNV _al_glGetCombinerOutputParameterivNV +#define glGetFinalCombinerInputParameterfvNV _al_glGetFinalCombinerInputParameterfvNV +#define glGetFinalCombinerInputParameterivNV _al_glGetFinalCombinerInputParameterivNV +#endif + +#if defined _ALLEGRO_GL_MESA_resize_buffers +#define glResizeBuffersMESA _al_glResizeBuffersMESA +#endif + +#if defined _ALLEGRO_GL_MESA_window_pos +#define glWindowPos2dMESA _al_glWindowPos2dMESA +#define glWindowPos2dvMESA _al_glWindowPos2dvMESA +#define glWindowPos2fMESA _al_glWindowPos2fMESA +#define glWindowPos2fvMESA _al_glWindowPos2fvMESA +#define glWindowPos2iMESA _al_glWindowPos2iMESA +#define glWindowPos2ivMESA _al_glWindowPos2ivMESA +#define glWindowPos2sMESA _al_glWindowPos2sMESA +#define glWindowPos2svMESA _al_glWindowPos2svMESA +#define glWindowPos3dMESA _al_glWindowPos3dMESA +#define glWindowPos3dvMESA _al_glWindowPos3dvMESA +#define glWindowPos3fMESA _al_glWindowPos3fMESA +#define glWindowPos3fvMESA _al_glWindowPos3fvMESA +#define glWindowPos3iMESA _al_glWindowPos3iMESA +#define glWindowPos3ivMESA _al_glWindowPos3ivMESA +#define glWindowPos3sMESA _al_glWindowPos3sMESA +#define glWindowPos3svMESA _al_glWindowPos3svMESA +#define glWindowPos4dMESA _al_glWindowPos4dMESA +#define glWindowPos4dvMESA _al_glWindowPos4dvMESA +#define glWindowPos4fMESA _al_glWindowPos4fMESA +#define glWindowPos4fvMESA _al_glWindowPos4fvMESA +#define glWindowPos4iMESA _al_glWindowPos4iMESA +#define glWindowPos4ivMESA _al_glWindowPos4ivMESA +#define glWindowPos4sMESA _al_glWindowPos4sMESA +#define glWindowPos4svMESA _al_glWindowPos4svMESA +#endif + +#if defined _ALLEGRO_GL_IBM_multimode_draw_arrays +#define glMultiModeDrawArraysIBM _al_glMultiModeDrawArraysIBM +#define glMultiModeDrawElementsIBM _al_glMultiModeDrawElementsIBM +#endif + +#ifdef AGK_IBM_vertex_array_lists +#define glColorPointerListIBM _al_glColorPointerListIBM +#define glSecondaryColorPointerListIBM _al_glSecondaryColorPointerListIBM +#define glEdgeFlagPointerListIBM _al_glEdgeFlagPointerListIBM +#define glFogCoordPointerListIBM _al_glFogCoordPointerListIBM +#define glIndexPointerListIBM _al_glIndexPointerListIBM +#define glNormalPointerListIBM _al_glNormalPointerListIBM +#define glTexCoordPointerListIBM _al_glTexCoordPointerListIBM +#define glVertexPointerListIBM _al_glVertexPointerListIBM +#endif + +#if defined _ALLEGRO_GL_3DFX_tbuffer +#define glTbufferMask3DFX _al_glTbufferMask3DFX +#endif + +#if defined _ALLEGRO_GL_EXT_multisample +#define glSampleMaskEXT _al_glSampleMaskEXT +#define glSamplePatternEXT _al_glSamplePatternEXT +#endif + +#if defined _ALLEGRO_GL_SGIS_texture_color_mask +#define glTextureColorMaskSGIS _al_glTextureColorMaskSGIS +#endif + +#if defined _ALLEGRO_GL_SGIX_igloo_interface +#define glIglooInterfaceSGIX _al_glIglooInterfaceSGIX +#endif + +#if defined _ALLEGRO_GL_NV_fence +#define glDeleteFencesNV _al_glDeleteFencesNV +#define glGenFencesNV _al_glGenFencesNV +#define glIsFenceNV _al_glIsFenceNV +#define glTestFenceNV _al_glTestFenceNV +#define glGetFenceivNV _al_glGetFenceivNV +#define glFinishFenceNV _al_glFinishFenceNV +#define glSetFenceNV _al_glSetFenceNV +#endif + +#if defined _ALLEGRO_GL_NV_evaluators +#define glMapControlPointsNV _al_glMapControlPointsNV +#define glMapParameterivNV _al_glMapParameterivNV +#define glMapParameterfvNV _al_glMapParameterfvNV +#define glGetMapControlPointsNV _al_glGetMapControlPointsNV +#define glGetMapParameterivNV _al_glGetMapParameterivNV +#define glGetMapParameterfvNV _al_glGetMapParameterfvNV +#define glGetMapAttribParameterivNV _al_glGetMapAttribParameterivNV +#define glGetMapAttribParameterfvNV _al_glGetMapAttribParameterfvNV +#define glEvalMapsNV _al_glEvalMapsNV +#endif + +#if defined _ALLEGRO_GL_NV_register_combiners2 +#define glCombinerStageParameterfvNV _al_glCombinerStageParameterfvNV +#define glGetCombinerStageParameterfvNV _al_glGetCombinerStageParameterfvNV +#endif + +#if defined _ALLEGRO_GL_NV_vertex_program +#define glAreProgramsResidentNV _al_glAreProgramsResidentNV +#define glBindProgramNV _al_glBindProgramNV +#define glDeleteProgramsNV _al_glDeleteProgramsNV +#define glExecuteProgramNV _al_glExecuteProgramNV +#define glGenProgramsNV _al_glGenProgramsNV +#define glGetProgramParameterdvNV _al_glGetProgramParameterdvNV +#define glGetProgramParameterfvNV _al_glGetProgramParameterfvNV +#define glGetProgramivNV _al_glGetProgramivNV +#define glGetProgramStringNV _al_glGetProgramStringNV +#define glGetTrackMatrixivNV _al_glGetTrackMatrixivNV +#define glGetVertexAttribdvNV _al_glGetVertexAttribdvNV +#define glGetVertexAttribfvNV _al_glGetVertexAttribfvNV +#define glGetVertexAttribivNV _al_glGetVertexAttribivNV +#define glGetVertexAttribPointervNV _al_glGetVertexAttribPointervNV +#define glIsProgramNV _al_glIsProgramNV +#define glLoadProgramNV _al_glLoadProgramNV +#define glProgramParameter4dNV _al_glProgramParameter4dNV +#define glProgramParameter4dvNV _al_glProgramParameter4dvNV +#define glProgramParameter4fNV _al_glProgramParameter4fNV +#define glProgramParameter4fvNV _al_glProgramParameter4fvNV +#define glProgramParameters4dvNV _al_glProgramParameters4dvNV +#define glProgramParameters4fvNV _al_glProgramParameters4fvNV +#define glRequestResidentProgramsNV _al_glRequestResidentProgramsNV +#define glTrackMatrixNV _al_glTrackMatrixNV +#define glVertexAttribPointerNV _al_glVertexAttribPointerNV +#define glVertexAttrib1dNV _al_glVertexAttrib1dNV +#define glVertexAttrib1dvNV _al_glVertexAttrib1dvNV +#define glVertexAttrib1fNV _al_glVertexAttrib1fNV +#define glVertexAttrib1fvNV _al_glVertexAttrib1fvNV +#define glVertexAttrib1sNV _al_glVertexAttrib1sNV +#define glVertexAttrib1svNV _al_glVertexAttrib1svNV +#define glVertexAttrib2dNV _al_glVertexAttrib2dNV +#define glVertexAttrib2dvNV _al_glVertexAttrib2dvNV +#define glVertexAttrib2fNV _al_glVertexAttrib2fNV +#define glVertexAttrib2fvNV _al_glVertexAttrib2fvNV +#define glVertexAttrib2sNV _al_glVertexAttrib2sNV +#define glVertexAttrib2svNV _al_glVertexAttrib2svNV +#define glVertexAttrib3dNV _al_glVertexAttrib3dNV +#define glVertexAttrib3dvNV _al_glVertexAttrib3dvNV +#define glVertexAttrib3fNV _al_glVertexAttrib3fNV +#define glVertexAttrib3fvNV _al_glVertexAttrib3fvNV +#define glVertexAttrib3sNV _al_glVertexAttrib3sNV +#define glVertexAttrib3svNV _al_glVertexAttrib3svNV +#define glVertexAttrib4dNV _al_glVertexAttrib4dNV +#define glVertexAttrib4dvNV _al_glVertexAttrib4dvNV +#define glVertexAttrib4fNV _al_glVertexAttrib4fNV +#define glVertexAttrib4fvNV _al_glVertexAttrib4fvNV +#define glVertexAttrib4sNV _al_glVertexAttrib4sNV +#define glVertexAttrib4svNV _al_glVertexAttrib4svNV +#define glVertexAttrib4ubNV _al_glVertexAttrib4ubNV +#define glVertexAttrib4ubvNV _al_glVertexAttrib4ubvNV +#define glVertexAttribs1dvNV _al_glVertexAttribs1dvNV +#define glVertexAttribs1fvNV _al_glVertexAttribs1fvNV +#define glVertexAttribs1svNV _al_glVertexAttribs1svNV +#define glVertexAttribs2dvNV _al_glVertexAttribs2dvNV +#define glVertexAttribs2fvNV _al_glVertexAttribs2fvNV +#define glVertexAttribs2svNV _al_glVertexAttribs2svNV +#define glVertexAttribs3dvNV _al_glVertexAttribs3dvNV +#define glVertexAttribs3fvNV _al_glVertexAttribs3fvNV +#define glVertexAttribs3svNV _al_glVertexAttribs3svNV +#define glVertexAttribs4dvNV _al_glVertexAttribs4dvNV +#define glVertexAttribs4fvNV _al_glVertexAttribs4fvNV +#define glVertexAttribs4svNV _al_glVertexAttribs4svNV +#define glVertexAttribs4ubvNV _al_glVertexAttribs4ubvNV +#endif + +#if defined _ALLEGRO_GL_ATI_envmap_bumpmap +#define glTexBumpParameterivATI _al_glTexBumpParameterivATI +#define glTexBumpParameterfvATI _al_glTexBumpParameterfvATI +#define glGetTexBumpParameterivATI _al_glGetTexBumpParameterivATI +#define glGetTexBumpParameterfvATI _al_glGetTexBumpParameterfvATI +#endif + +#if defined _ALLEGRO_GL_ATI_fragment_shader +#define glGenFragmentShadersATI _al_glGenFragmentShadersATI +#define glBindFragmentShaderATI _al_glBindFragmentShaderATI +#define glDeleteFragmentShaderATI _al_glDeleteFragmentShaderATI +#define glBeginFragmentShaderATI _al_glBeginFragmentShaderATI +#define glEndFragmentShaderATI _al_glEndFragmentShaderATI +#define glPassTexCoordATI _al_glPassTexCoordATI +#define glSampleMapATI _al_glSampleMapATI +#define glColorFragmentOp1ATI _al_glColorFragmentOp1ATI +#define glColorFragmentOp2ATI _al_glColorFragmentOp2ATI +#define glColorFragmentOp3ATI _al_glColorFragmentOp3ATI +#define glAlphaFragmentOp1ATI _al_glAlphaFragmentOp1ATI +#define glAlphaFragmentOp2ATI _al_glAlphaFragmentOp2ATI +#define glAlphaFragmentOp3ATI _al_glAlphaFragmentOp3ATI +#define glSetFragmentShaderConstantATI _al_glSetFragmentShaderConstantATI +#endif + +#if defined _ALLEGRO_GL_ATI_pn_triangles +#define glPNTrianglesiATI _al_glPNTrianglesiATI +#define glPNTrianglesfATI _al_glPNTrianglesfATI +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_array_object +#define glNewObjectBufferATI _al_glNewObjectBufferATI +#define glIsObjectBufferATI _al_glIsObjectBufferATI +#define glUpdateObjectBufferATI _al_glUpdateObjectBufferATI +#define glGetObjectBufferfvATI _al_glGetObjectBufferfvATI +#define glGetObjectBufferivATI _al_glGetObjectBufferivATI +#define glFreeObjectBufferATI _al_glFreeObjectBufferATI +#define glArrayObjectATI _al_glArrayObjectATI +#define glGetArrayObjectfvATI _al_glGetArrayObjectfvATI +#define glGetArrayObjectivATI _al_glGetArrayObjectivATI +#define glVariantArrayObjectATI _al_glVariantArrayObjectATI +#define glGetVariantArrayObjectfvATI _al_glGetVariantArrayObjectfvATI +#define glGetVariantArrayObjectivATI _al_glGetVariantArrayObjectivATI +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_shader +#define glBeginVertexShaderEXT _al_glBeginVertexShaderEXT +#define glEndVertexShaderEXT _al_glEndVertexShaderEXT +#define glBindVertexShaderEXT _al_glBindVertexShaderEXT +#define glGenVertexShadersEXT _al_glGenVertexShadersEXT +#define glDeleteVertexShaderEXT _al_glDeleteVertexShaderEXT +#define glShaderOp1EXT _al_glShaderOp1EXT +#define glShaderOp2EXT _al_glShaderOp2EXT +#define glShaderOp3EXT _al_glShaderOp3EXT +#define glSwizzleEXT _al_glSwizzleEXT +#define glWriteMaskEXT _al_glWriteMaskEXT +#define glInsertComponentEXT _al_glInsertComponentEXT +#define glExtractComponentEXT _al_glExtractComponentEXT +#define glGenSymbolsEXT _al_glGenSymbolsEXT +#define glSetInvariantEXT _al_glSetInvariantEXT +#define glSetLocalConstantEXT _al_glSetLocalConstantEXT +#define glVariantbvEXT _al_glVariantbvEXT +#define glVariantsvEXT _al_glVariantsvEXT +#define glVariantivEXT _al_glVariantivEXT +#define glVariantfvEXT _al_glVariantfvEXT +#define glVariantdvEXT _al_glVariantdvEXT +#define glVariantubvEXT _al_glVariantubvEXT +#define glVariantusvEXT _al_glVariantusvEXT +#define glVariantuivEXT _al_glVariantuivEXT +#define glVariantPointerEXT _al_glVariantPointerEXT +#define glEnableVariantClientStateEXT _al_glEnableVariantClientStateEXT +#define glDisableVariantClientStateEXT _al_glDisableVariantClientStateEXT +#define glBindLightParameterEXT _al_glBindLightParameterEXT +#define glBindMaterialParameterEXT _al_glBindMaterialParameterEXT +#define glBindTexGenParameterEXT _al_glBindTexGenParameterEXT +#define glBindTextureUnitParameterEXT _al_glBindTextureUnitParameterEXT +#define glBindParameterEXT _al_glBindParameterEXT +#define glIsVariantEnabledEXT _al_glIsVariantEnabledEXT +#define glGetVariantBooleanvEXT _al_glGetVariantBooleanvEXT +#define glGetVariantIntegervEXT _al_glGetVariantIntegervEXT +#define glGetVariantFloatvEXT _al_glGetVariantFloatvEXT +#define glGetVariantPointervEXT _al_glGetVariantPointervEXT +#define glGetInvariantBooleanvEXT _al_glGetInvariantBooleanvEXT +#define glGetInvariantIntegervEXT _al_glGetInvariantIntegervEXT +#define glGetInvariantFloatvEXT _al_glGetInvariantFloatvEXT +#define glGetLocalConstantBooleanvEXT _al_glGetLocalConstantBooleanvEXT +#define glGetLocalConstantIntegervEXT _al_glGetLocalConstantIntegervEXT +#define glGetLocalConstantFloatvEXT _al_glGetLocalConstantFloatvEXT +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_streams +#define glVertexStream1sATI _al_glVertexStream1sATI +#define glVertexStream1svATI _al_glVertexStream1svATI +#define glVertexStream1iATI _al_glVertexStream1iATI +#define glVertexStream1ivATI _al_glVertexStream1ivATI +#define glVertexStream1fATI _al_glVertexStream1fATI +#define glVertexStream1fvATI _al_glVertexStream1fvATI +#define glVertexStream1dATI _al_glVertexStream1dATI +#define glVertexStream1dvATI _al_glVertexStream1dvATI +#define glVertexStream2sATI _al_glVertexStream2sATI +#define glVertexStream2svATI _al_glVertexStream2svATI +#define glVertexStream2iATI _al_glVertexStream2iATI +#define glVertexStream2ivATI _al_glVertexStream2ivATI +#define glVertexStream2fATI _al_glVertexStream2fATI +#define glVertexStream2fvATI _al_glVertexStream2fvATI +#define glVertexStream2dATI _al_glVertexStream2dATI +#define glVertexStream2dvATI _al_glVertexStream2dvATI +#define glVertexStream3sATI _al_glVertexStream3sATI +#define glVertexStream3svATI _al_glVertexStream3svATI +#define glVertexStream3iATI _al_glVertexStream3iATI +#define glVertexStream3ivATI _al_glVertexStream3ivATI +#define glVertexStream3fATI _al_glVertexStream3fATI +#define glVertexStream3fvATI _al_glVertexStream3fvATI +#define glVertexStream3dATI _al_glVertexStream3dATI +#define glVertexStream3dvATI _al_glVertexStream3dvATI +#define glVertexStream4sATI _al_glVertexStream4sATI +#define glVertexStream4svATI _al_glVertexStream4svATI +#define glVertexStream4iATI _al_glVertexStream4iATI +#define glVertexStream4ivATI _al_glVertexStream4ivATI +#define glVertexStream4fATI _al_glVertexStream4fATI +#define glVertexStream4fvATI _al_glVertexStream4fvATI +#define glVertexStream4dATI _al_glVertexStream4dATI +#define glVertexStream4dvATI _al_glVertexStream4dvATI +#define glNormalStream3bATI _al_glNormalStream3bATI +#define glNormalStream3bvATI _al_glNormalStream3bvATI +#define glNormalStream3sATI _al_glNormalStream3sATI +#define glNormalStream3svATI _al_glNormalStream3svATI +#define glNormalStream3iATI _al_glNormalStream3iATI +#define glNormalStream3ivATI _al_glNormalStream3ivATI +#define glNormalStream3fATI _al_glNormalStream3fATI +#define glNormalStream3fvATI _al_glNormalStream3fvATI +#define glNormalStream3dATI _al_glNormalStream3dATI +#define glNormalStream3dvATI _al_glNormalStream3dvATI +#define glClientActiveVertexStreamATI _al_glClientActiveVertexStreamATI +#define glVertexBlendEnviATI _al_glVertexBlendEnviATI +#define glVertexBlendEnvfATI _al_glVertexBlendEnvfATI +#endif + +#if defined _ALLEGRO_GL_ATI_element_array +#define glElementPointerATI _al_glElementPointerATI +#define glDrawElementArrayATI _al_glDrawElementArrayATI +#define glDrawRangeElementArrayATI _al_glDrawRangeElementArrayATI +#endif + +#if defined _ALLEGRO_GL_SUN_mesh_array +#define glDrawMeshArraysSUN _al_glDrawMeshArraysSUN +#endif + +#if defined _ALLEGRO_GL_NV_occlusion_query +#define glGenOcclusionQueriesNV _al_glGenOcclusionQueriesNV +#define glDeleteOcclusionQueriesNV _al_glDeleteOcclusionQueriesNV +#define glIsOcclusionQueryNV _al_glIsOcclusionQueryNV +#define glBeginOcclusionQueryNV _al_glBeginOcclusionQueryNV +#define glEndOcclusionQueryNV _al_glEndOcclusionQueryNV +#define glGetOcclusionQueryivNV _al_glGetOcclusionQueryivNV +#define glGetOcclusionQueryuivNV _al_glGetOcclusionQueryuivNV +#endif + +#if defined _ALLEGRO_GL_NV_point_sprite +#define glPointParameteriNV _al_glPointParameteriNV +#define glPointParameterivNV _al_glPointParameterivNV +#endif + +#if defined _ALLEGRO_GL_EXT_stencil_two_side +#define glActiveStencilFaceEXT _al_glActiveStencilFaceEXT +#endif + +#if defined _ALLEGRO_GL_APPLE_element_array +#define glElementPointerAPPLE _al_glElementPointerAPPLE +#define glDrawElementArrayAPPLE _al_glDrawElementArrayAPPLE +#define glDrawRangeElementArrayAPPLE _al_glDrawRangeElementArrayAPPLE +#define glMultiDrawElementArrayAPPLE _al_glMultiDrawElementArrayAPPLE +#define glMultiDrawRangeElementArrayAPPLE _al_glMultiDrawRangeElementArrayAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_fence +#define glGenFencesAPPLE _al_glGenFencesAPPLE +#define glDeleteFencesAPPLE _al_glDeleteFencesAPPLE +#define glSetFenceAPPLE _al_glSetFenceAPPLE +#define glIsFenceAPPLE _al_glIsFenceAPPLE +#define glTestFenceAPPLE _al_glTestFenceAPPLE +#define glFinishFenceAPPLE _al_glFinishFenceAPPLE +#define glTestObjectAPPLE _al_glTestObjectAPPLE +#define glFinishObjectAPPLE _al_glFinishObjectAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_array_object +#define glBindVertexArrayAPPLE _al_glBindVertexArrayAPPLE +#define glDeleteVertexArraysAPPLE _al_glDeleteVertexArraysAPPLE +#define glGenVertexArraysAPPLE _al_glGenVertexArraysAPPLE +#define glIsVertexArrayAPPLE _al_glIsVertexArrayAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_array_range +#define glVertexArrayRangeAPPLE _al_glVertexArrayRangeAPPLE +#define glFlushVertexArrayRangeAPPLE _al_glFlushVertexArrayRangeAPPLE +#define glVertexArrayParameteriAPPLE _al_glVertexArrayParameteriAPPLE +#endif + +#if defined _ALLEGRO_GL_ATI_draw_buffers +#define glDrawBuffersATI _al_glDrawBuffersATI +#endif + +#if defined _ALLEGRO_GL_NV_fragment_program +#define glProgramNamedParameter4fNV _al_glProgramNamedParameter4fNV +#define glProgramNamedParameter4dNV _al_glProgramNamedParameter4dNV +#define glProgramNamedParameter4fvNV _al_glProgramNamedParameter4fvNV +#define glProgramNamedParameter4dvNV _al_glProgramNamedParameter4dvNV +#define glGetProgramNamedParameterfvNV _al_glGetProgramNamedParameterfvNV +#define glGetProgramNamedParameterdvNV _al_glGetProgramNamedParameterdvNV +#endif + +#if defined _ALLEGRO_GL_NV_half_float +#define glVertex2hNV _al_glVertex2hNV +#define glVertex2hvNV _al_glVertex2hvNV +#define glVertex3hNV _al_glVertex3hNV +#define glVertex3hvNV _al_glVertex3hvNV +#define glVertex4hNV _al_glVertex4hNV +#define glVertex4hvNV _al_glVertex4hvNV +#define glNormal3hNV _al_glNormal3hNV +#define glNormal3hvNV _al_glNormal3hvNV +#define glColor3hNV _al_glColor3hNV +#define glColor3hvNV _al_glColor3hvNV +#define glColor4hNV _al_glColor4hNV +#define glColor4hvNV _al_glColor4hvNV +#define glTexCoord1hNV _al_glTexCoord1hNV +#define glTexCoord1hvNV _al_glTexCoord1hvNV +#define glTexCoord2hNV _al_glTexCoord2hNV +#define glTexCoord2hvNV _al_glTexCoord2hvNV +#define glTexCoord3hNV _al_glTexCoord3hNV +#define glTexCoord3hvNV _al_glTexCoord3hvNV +#define glTexCoord4hNV _al_glTexCoord4hNV +#define glTexCoord4hvNV _al_glTexCoord4hvNV +#define glMultiTexCoord1hNV _al_glMultiTexCoord1hNV +#define glMultiTexCoord1hvNV _al_glMultiTexCoord1hvNV +#define glMultiTexCoord2hNV _al_glMultiTexCoord2hNV +#define glMultiTexCoord2hvNV _al_glMultiTexCoord2hvNV +#define glMultiTexCoord3hNV _al_glMultiTexCoord3hNV +#define glMultiTexCoord3hvNV _al_glMultiTexCoord3hvNV +#define glMultiTexCoord4hNV _al_glMultiTexCoord4hNV +#define glMultiTexCoord4hvNV _al_glMultiTexCoord4hvNV +#define glFogCoordhNV _al_glFogCoordhNV +#define glFogCoordhvNV _al_glFogCoordhvNV +#define glSecondaryColor3hNV _al_glSecondaryColor3hNV +#define glSecondaryColor3hvNV _al_glSecondaryColor3hvNV +#define glVertexWeighthNV _al_glVertexWeighthNV +#define glVertexWeighthvNV _al_glVertexWeighthvNV +#define glVertexAttrib1hNV _al_glVertexAttrib1hNV +#define glVertexAttrib1hvNV _al_glVertexAttrib1hvNV +#define glVertexAttrib2hNV _al_glVertexAttrib2hNV +#define glVertexAttrib2hvNV _al_glVertexAttrib2hvNV +#define glVertexAttrib3hNV _al_glVertexAttrib3hNV +#define glVertexAttrib3hvNV _al_glVertexAttrib3hvNV +#define glVertexAttrib4hNV _al_glVertexAttrib4hNV +#define glVertexAttrib4hvNV _al_glVertexAttrib4hvNV +#define glVertexAttribs1hvNV _al_glVertexAttribs1hvNV +#define glVertexAttribs2hvNV _al_glVertexAttribs2hvNV +#define glVertexAttribs3hvNV _al_glVertexAttribs3hvNV +#define glVertexAttribs4hvNV _al_glVertexAttribs4hvNV +#endif + +#if defined _ALLEGRO_GL_NV_pixel_data_range +#define glPixelDataRangeNV _al_glPixelDataRangeNV +#define glFlushPixelDataRangeNV _al_glFlushPixelDataRangeNV +#endif + +#if defined _ALLEGRO_GL_NV_primitive_restart +#define glPrimitiveRestartNV _al_glPrimitiveRestartNV +#define glPrimitiveRestartIndexNV _al_glPrimitiveRestartIndexNV +#endif + +#if defined _ALLEGRO_GL_ATI_map_object_buffer +#define glMapObjectBufferATI _al_glMapObjectBufferATI +#define glUnmapObjectBufferATI _al_glUnmapObjectBufferATI +#endif + +#if defined _ALLEGRO_GL_ATI_separate_stencil +#define glStencilOpSeparateATI _al_glStencilOpSeparateATI +#define glStencilFuncSeparateATI _al_glStencilFuncSeparateATI +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_attrib_array_object +#define glVertexAttribArrayObjectATI _al_glVertexAttribArrayObjectATI +#define glGetVertexAttribArrayObjectfvATI _al_glGetVertexAttribArrayObjectfvATI +#define glGetVertexAttribArrayObjectivATI _al_glGetVertexAttribArrayObjectivATI +#endif + +#if defined _ALLEGRO_GL_OES_byte_coordinates +#define glVertex2bOES _al_glVertex2bOES +#define glVertex3bOES _al_glVertex3bOES +#define glVertex4bOES _al_glVertex4bOES +#define glVertex2bvOES _al_glVertex2bvOES +#define glVertex3bvOES _al_glVertex3bvOES +#define glVertex4bvOES _al_glVertex4bvOES +#define glTexCoord1bOES _al_glTexCoord1bOES +#define glTexCoord2bOES _al_glTexCoord2bOES +#define glTexCoord3bOES _al_glTexCoord3bOES +#define glTexCoord4bOES _al_glTexCoord4bOES +#define glTexCoord1bvOES _al_glTexCoord1bvOES +#define glTexCoord2bvOES _al_glTexCoord2bvOES +#define glTexCoord3bvOES _al_glTexCoord3bvOES +#define glTexCoord4bvOES _al_glTexCoord4bvOES +#define glMultiTexCoord1bOES _al_glMultiTexCoord1bOES +#define glMultiTexCoord2bOES _al_glMultiTexCoord2bOES +#define glMultiTexCoord3bOES _al_glMultiTexCoord3bOES +#define glMultiTexCoord4bOES _al_glMultiTexCoord4bOES +#define glMultiTexCoord1bvOES _al_glMultiTexCoord1bvOES +#define glMultiTexCoord2bvOES _al_glMultiTexCoord2bvOES +#define glMultiTexCoord3bvOES _al_glMultiTexCoord3bvOES +#define glMultiTexCoord4bvOES _al_glMultiTexCoord4bvOES +#endif + +#if defined _ALLEGRO_GL_OES_fixed_point +#define glVertex2xOES _al_glVertex2xOES +#define glVertex3xOES _al_glVertex3xOES +#define glVertex4xOES _al_glVertex4xOES +#define glVertex2xvOES _al_glVertex2xvOES +#define glVertex3xvOES _al_glVertex3xvOES +#define glVertex4xvOES _al_glVertex4xvOES +#define glNormal3xOES _al_glNormal3xOES +#define glNormal3xvOES _al_glNormal3xvOES +#define glTexCoord1xOES _al_glTexCoord1xOES +#define glTexCoord2xOES _al_glTexCoord2xOES +#define glTexCoord3xOES _al_glTexCoord3xOES +#define glTexCoord4xOES _al_glTexCoord4xOES +#define glTexCoord1xvOES _al_glTexCoord1xvOES +#define glTexCoord2xvOES _al_glTexCoord2xvOES +#define glTexCoord3xvOES _al_glTexCoord3xvOES +#define glTexCoord4xvOES _al_glTexCoord4xvOES +#define glMultiTexCoord1xOES _al_glMultiTexCoord1xOES +#define glMultiTexCoord2xOES _al_glMultiTexCoord2xOES +#define glMultiTexCoord3xOES _al_glMultiTexCoord3xOES +#define glMultiTexCoord4xOES _al_glMultiTexCoord4xOES +#define glMultiTexCoord1xvOES _al_glMultiTexCoord1xvOES +#define glMultiTexCoord2xvOES _al_glMultiTexCoord2xvOES +#define glMultiTexCoord3xvOES _al_glMultiTexCoord3xvOES +#define glMultiTexCoord4xvOES _al_glMultiTexCoord4xvOES +#define glColor3xOES _al_glColor3xOES +#define glColor4xOES _al_glColor4xOES +#define glColor3xvOES _al_glColor3xvOES +#define glColor4xvOES _al_glColor4xvOES +#define glIndexxOES _al_glIndexxOES +#define glIndexxvOES _al_glIndexxvOES +#define glRectxOES _al_glRectxOES +#define glRectxvOES _al_glRectxvOES +#define glDepthRangexOES _al_glDepthRangexOES +#define glLoadMatrixxOES _al_glLoadMatrixxOES +#define glMultMatrixxOES _al_glMultMatrixxOES +#define glLoadTransposeMatrixxOES _al_glLoadTransposeMatrixxOES +#define glMultTransposeMatrixxOES _al_glMultTransposeMatrixxOES +#define glRotatexOES _al_glRotatexOES +#define glScalexOES _al_glScalexOES +#define glTranslatexOES _al_glTranslatexOES +#define glFrustumxOES _al_glFrustumxOES +#define glOrthoxOES _al_glOrthoxOES +#define glTexGenxOES _al_glTexGenxOES +#define glTexGenxvOES _al_glTexGenxvOES +#define glGetTexGenxvOES _al_glGetTexGenxvOES +#define glClipPlanexOES _al_glClipPlanexOES +#define glGetClipPlanexOES _al_glGetClipPlanexOES +#define glRasterPos2xOES _al_glRasterPos2xOES +#define glRasterPos3xOES _al_glRasterPos3xOES +#define glRasterPos4xOES _al_glRasterPos4xOES +#define glRasterPos2xvOES _al_glRasterPos2xvOES +#define glRasterPos3xvOES _al_glRasterPos3xvOES +#define glRasterPos4xvOES _al_glRasterPos4xvOES +#define glMaterialxOES _al_glMaterialxOES +#define glMaterialxvOES _al_glMaterialxvOES +#define glGetMaterialxOES _al_glGetMaterialxOES +#define glLightxOES _al_glLightxOES +#define glLightxvOES _al_glLightxvOES +#define glGetLightxOES _al_glGetLightxOES +#define glLightModelxOES _al_glLightModelxOES +#define glLightModelxvOES _al_glLightModelxvOES +#define glPointSizexOES _al_glPointSizexOES +#define glLineWidthxOES _al_glLineWidthxOES +#define glPolygonOffsetxOES _al_glPolygonOffsetxOES +#define glPixelStorex _al_glPixelStorex +#define glPixelTransferxOES _al_glPixelTransferxOES +#define glPixelMapx _al_glPixelMapx +#define glGetPixelMapxv _al_glGetPixelMapxv +#define glConvolutionParameterxOES _al_glConvolutionParameterxOES +#define glConvolutionParameterxvOES _al_glConvolutionParameterxvOES +#define glGetConvolutionParameterxvOES _al_glGetConvolutionParameterxvOES +#define glGetHistogramParameterxvOES _al_glGetHistogramParameterxvOES +#define glPixelZoomxOES _al_glPixelZoomxOES +#define glBitmapxOES _al_glBitmapxOES +#define glTexParameterxOES _al_glTexParameterxOES +#define glTexParameterxvOES _al_glTexParameterxvOES +#define glGetTexParameterxvOES _al_glGetTexParameterxvOES +#define glGetTexLevelParameterxvOES _al_glGetTexLevelParameterxvOES +#define glPrioritizeTexturesxOES _al_glPrioritizeTexturesxOES +#define glTexEnvxOES _al_glTexEnvxOES +#define glTexEnvxvOES _al_glTexEnvxvOES +#define glGetTexEnvxvOES _al_glGetTexEnvxvOES +#define glFogxOES _al_glFogxOES +#define glFogxvOES _al_glFogxvOES +#define glSampleCoverageOES _al_glSampleCoverageOES +#define glAlphaFuncxOES _al_glAlphaFuncxOES +#define glBlendColorxOES _al_glBlendColorxOES +#define glClearColorxOES _al_glClearColorxOES +#define glClearDepthxOES _al_glClearDepthxOES +#define glClearAccumxOES _al_glClearAccumxOES +#define glAccumxOES _al_glAccumxOES +#define glMap1xOES _al_glMap1xOES +#define glMap2xOES _al_glMap2xOES +#define glMapGrid1xOES _al_glMapGrid1xOES +#define glMapGrid2xOES _al_glMapGrid2xOES +#define glGetMapxvOES _al_glGetMapxvOES +#define glEvalCoord1xOES _al_glEvalCoord1xOES +#define glEvalCoord2xOES _al_glEvalCoord2xOES +#define glEvalCoord1xvOES _al_glEvalCoord1xvOES +#define glEvalCoord2xvOES _al_glEvalCoord2xvOES +#define glFeedbackBufferxOES _al_glFeedbackBufferxOES +#define glPassThroughxOES _al_glPassThroughxOES +#define glGetFixedvOES _al_glGetFixedvOES +#endif + +#if defined _ALLEGRO_GL_OES_single_precision +#define glDepthRangefOES _al_glDepthRangefOES +#define glFrustumfOES _al_glFrustumfOES +#define glOrthofOES _al_glOrthofOES +#define glClipPlanefOES _al_glClipPlanefOES +#define glGetClipPlanefOES _al_glGetClipPlanefOES +#define glClearDepthfOES _al_glClearDepthfOES +#endif + +#if defined _ALLEGRO_GL_OES_query_matrix +#define glQueryMatrixxOES _al_glQueryMatrixxOES +#endif + +#if defined _ALLEGRO_GL_EXT_depth_bounds_test +#define glDepthBoundsEXT _al_glDepthBoundsEXT +#endif + + +#if defined _ALLEGRO_GL_EXT_blend_equation_separate +#define glBlendEquationSeparateEXT _al_glBlendEquationSeparateEXT +#endif + + +#if defined _ALLEGRO_GL_EXT_framebuffer_object +#define glIsRenderbufferEXT _al_glIsRenderbufferEXT +#define glBindRenderbufferEXT _al_glBindRenderbufferEXT +#define glDeleteRenderbuffersEXT _al_glDeleteRenderbuffersEXT +#define glGenRenderbuffersEXT _al_glGenRenderbuffersEXT +#define glRenderbufferStorageEXT _al_glRenderbufferStorageEXT +#define glGetRenderbufferParameterivEXT _al_glGetRenderbufferParameterivEXT +#define glIsFramebufferEXT _al_glIsFramebufferEXT +#define glBindFramebufferEXT _al_glBindFramebufferEXT +#define glDeleteFramebuffersEXT _al_glDeleteFramebuffersEXT +#define glGenFramebuffersEXT _al_glGenFramebuffersEXT +#define glCheckFramebufferStatusEXT _al_glCheckFramebufferStatusEXT +#define glFramebufferTexture1DEXT _al_glFramebufferTexture1DEXT +#define glFramebufferTexture2DEXT _al_glFramebufferTexture2DEXT +#define glFramebufferTexture3DEXT _al_glFramebufferTexture3DEXT +#define glFramebufferRenderbufferEXT _al_glFramebufferRenderbufferEXT +#define glGetFramebufferAttachmentParameterivEXT _al_glGetFramebufferAttachmentParameterivEXT +#define glGenerateMipmapEXT _al_glGenerateMipmapEXT +#endif + +#if defined _ALLEGRO_GL_GREMEDY_string_marker +#define glStringMarkerGREMEDY _al_glStringMarkerGREMEDY +#endif + +#if defined _ALLEGRO_GL_EXT_stencil_clear_tag +#define glStencilClearTagEXT _al_glStencilClearTagEXT +#endif + +#if defined _ALLEGRO_GL_EXT_framebuffer_blit +#define glBlitFramebufferEXT _al_glBlitFramebufferEXT +#endif + +#if defined _ALLEGRO_GL_EXT_framebuffer_multisample +#define glRenderbufferStorageMultisampleEXT _al_glRenderbufferStorageMultisampleEXT +#endif + +#if defined _ALLEGRO_GL_EXT_timer_query +#define glGetQueryObjecti64vEXT _al_glGetQueryObjecti64vEXT +#define glGetQueryObjectui64vEXT _al_glGetQueryObjectui64vEXT +#endif + +#if defined _ALLEGRO_GL_EXT_gpu_program_parameters +#define glProgramEnvParameters4fvEXT _al_glProgramEnvParameters4fvEXT +#define glProgramLocalParameters4fvEXT _al_glProgramLocalParameters4fvEXT +#endif + +#if defined _ALLEGRO_GL_APPLE_flush_buffer_range +#define glBufferParameteriAPPLE _al_glBufferParameteriAPPLE +#define glFlushMappedBufferRangeAPPLE _al_glFlushMappedBufferRangeAPPLE +#endif + +#if defined _ALLEGRO_GL_EXT_bindable_uniform +#define glUniformBufferEXT _al_glUniformBufferEXT +#define glGetUniformBufferSizeEXT _al_glGetUniformBufferSizeEXT +#define glGetUniformOffsetEXT _al_glGetUniformOffsetEXT +#endif + +#if defined _ALLEGRO_GL_EXT_draw_buffers2 +#define glColorMaskIndexedEXT _al_glColorMaskIndexedEXT +#define glGetBooleanIndexedvEXT _al_glGetBooleanIndexedvEXT +#define glGetIntegerIndexedvEXT _al_glGetIntegerIndexedvEXT +#define glEnableIndexedEXT _al_glEnableIndexedEXT +#define glDisableIndexedEXT _al_glDisableIndexedEXT +#define glIsEnabledIndexedEXT _al_glIsEnabledIndexedEXT +#endif + +#if defined _ALLEGRO_GL_EXT_draw_instanced +#define glDrawArraysInstancedEXT _al_glDrawArraysInstancedEXT +#define glDrawElementsInstancedEXT _al_glDrawElementsInstancedEXT +#endif + +#if defined _ALLEGRO_GL_EXT_geometry_shader4 +#define glProgramParameteriEXT _al_glProgramParameteriEXT +#define glFramebufferTextureEXT _al_glFramebufferTextureEXT +#if !defined _ALLEGRO_GL_EXT_texture_array +#define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT +#endif +#define glFramebufferTextureFaceEXT _al_glFramebufferTextureFaceEXT +#endif + +#if defined _ALLEGRO_GL_EXT_gpu_shader4 +#define glVertexAttribI1iEXT _al_glVertexAttribI1iEXT +#define glVertexAttribI2iEXT _al_glVertexAttribI2iEXT +#define glVertexAttribI3iEXT _al_glVertexAttribI3iEXT +#define glVertexAttribI4iEXT _al_glVertexAttribI4iEXT +#define glVertexAttribI1uiEXT _al_glVertexAttribI1uiEXT +#define glVertexAttribI2uiEXT _al_glVertexAttribI2uiEXT +#define glVertexAttribI3uiEXT _al_glVertexAttribI3uiEXT +#define glVertexAttribI4uiEXT _al_glVertexAttribI4uiEXT +#define glVertexAttribI1ivEXT _al_glVertexAttribI1ivEXT +#define glVertexAttribI2ivEXT _al_glVertexAttribI2ivEXT +#define glVertexAttribI3ivEXT _al_glVertexAttribI3ivEXT +#define glVertexAttribI4ivEXT _al_glVertexAttribI4ivEXT +#define glVertexAttribI1uivEXT _al_glVertexAttribI1uivEXT +#define glVertexAttribI2uivEXT _al_glVertexAttribI2uivEXT +#define glVertexAttribI3uivEXT _al_glVertexAttribI3uivEXT +#define glVertexAttribI4uivEXT _al_glVertexAttribI4uivEXT +#define glVertexAttribI4bvEXT _al_glVertexAttribI4bvEXT +#define glVertexAttribI4svEXT _al_glVertexAttribI4svEXT +#define glVertexAttribI4ubvEXT _al_glVertexAttribI4ubvEXT +#define glVertexAttribI4usvEXT _al_glVertexAttribI4usvEXT +#define glVertexAttribIPointerEXT _al_glVertexAttribIPointerEXT +#define glGetVertexAttribIivEXT _al_glGetVertexAttribIivEXT +#define glGetVertexAttribIuivEXT _al_glGetVertexAttribIuivEXT +#define glUniform1uiEXT _al_glUniform1uiEXT +#define glUniform2uiEXT _al_glUniform2uiEXT +#define glUniform3uiEXT _al_glUniform3uiEXT +#define glUniform4uiEXT _al_glUniform4uiEXT +#define glUniform1uivEXT _al_glUniform1uivEXT +#define glUniform2uivEXT _al_glUniform2uivEXT +#define glUniform3uivEXT _al_glUniform3uivEXT +#define glUniform4uivEXT _al_glUniform4uivEXT +#define glGetUniformuivEXT _al_glGetUniformuivEXT +#define glBindFragDataLocationEXT _al_glBindFragDataLocationEXT +#define glGetFragDataLocationEXT _al_glGetFragDataLocationEXT +#endif + +#if defined _ALLEGRO_GL_EXT_texture_array +#define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT +#endif + +#if defined _ALLEGRO_GL_EXT_texture_buffer_object +#define glTexBufferEXT _al_glTexBufferEXT +#endif + +#if defined _ALLEGRO_GL_texture_integer +#define glClearColorIiEXT _al_glClearColorIiEXT +#define glClearColorIuiEXT _al_glClearColorIuiEXT +#define glTexParameterIivEXT _al_glTexParameterIivEXT +#define glTexParameterIuivEXT _al_glTexParameterIuivEXT +#define glGetTexParameterIivEXT _al_glGetTexParameterIivEXT +#define glGetTexParameterIiuvEXT _al_glGetTexParameterIiuvEXT +#endif + +#if defined _ALLEGRO_GL_NV_depth_buffer_float +#define glDepthRangedNV _al_glDepthRangedNV +#define glClearDepthdNV _al_glClearDepthdNV +#define glDepthBoundsdNV _al_glDepthBoundsdNV +#endif + +#if defined _ALLEGRO_GL_NV_framebuffer_multisample_coverage +#define glRenderbufferStorageMultsampleCoverageNV _al_glRenderbufferStorageMultsampleCoverageNV +#endif + +#if defined _ALLEGRO_GL_NV_geometry_program4 +#define glProgramVertexLimitNV _al_glProgramVertexLimitNV +#if !defined _ALLEGRO_GL_EXT_geometry_shader4 +#define glFramebufferTextureEXT _al_glFramebufferTextureEXT +#if !defined _ALLEGRO_GL_EXT_texture_array +#define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT +#endif +#endif +#endif + +#if defined _ALLEGRO_GL_NV_gpu_program4 +#define glProgramLocalParameterI4iNV _al_glProgramLocalParameterI4iNV +#define glProgramLocalParameterI4ivNV _al_glProgramLocalParameterI4ivNV +#define glProgramLocalParametersI4ivNV _al_glProgramLocalParametersI4ivNV +#define glProgramLocalParameterI4uiNV _al_glProgramLocalParameterI4uiNV +#define glProgramLocalParameterI4uivNV _al_glProgramLocalParameterI4uivNV +#define glProgramLocalParametersI4uivNV _al_glProgramLocalParametersI4uivNV +#define glProgramEnvParameterI4iNV _al_glProgramEnvParameterI4iNV +#define glProgramEnvParameterI4ivNV _al_glProgramEnvParameterI4ivNV +#define glProgramEnvParametersI4ivNV _al_glProgramEnvParametersI4ivNV +#define glProgramEnvParameterI4uiNV _al_glProgramEnvParameterI4uiNV +#define glProgramEnvParameterI4uivNV _al_glProgramEnvParameterI4uivNV +#define glProgramEnvParametersI4uivNV _al_glProgramEnvParametersI4uivNV +#define glGetProgramLocalParameterIivNV _al_glGetProgramLocalParameterIivNV +#define glGetProgramLocalParameterIuivNV _al_glGetProgramLocalParameterIuivNV +#define glGetProgramEnvParameterIivNV _al_glGetProgramEnvParameterIivNV +#define glGetProgramEnvParameterIuivNV _al_glGetProgramEnvParameterIuivNV +#endif + +#if defined _ALLEGRO_GL_NV_parameter_buffer_object +#if !defined _ALLEGRO_GL_NV_transform_feedback +#define glBindBufferRangeNV _al_glBindBufferRangeNV +#define glBindBufferOffsetNV _al_glBindBufferOffsetNV +#define glBindBufferBaseNV _al_glBindBufferBaseNV +#endif +#define glProgramBufferParametersfvNV _al_glProgramBufferParametersfvNV +#define glProgramBufferParametersIivNV _al_glProgramBufferParametersIivNV +#define glProgramBufferParametersIuivNV _al_glProgramBufferParametersIuivNV +#if !defined _ALLEGRO_GL_EXT_draw_buffers2 +#define glGetIntegerIndexedvEXT _al_glGetIntegerIndexedvEXT +#endif +#endif + +#if defined _ALLEGRO_GL_NV_transform_feedback +#define glBindBufferRangeNV _al_glBindBufferRangeNV +#define glBindBufferOffsetNV _al_glBindBufferOffsetNV +#define glBindBufferBaseNV _al_glBindBufferBaseNV +#define glTransformFeedbackAttribsNV _al_glTransformFeedbackAttribsNV +#define glTransformFeedbackVaryingsNV _al_glTransformFeedbackVaryingsNV +#define glBeginTransformFeedbackNV _al_glBeginTransformFeedbackNV +#define glEndTransformFeedbackNV _al_glEndTransformFeedbackNV +#define glGetVaryingLocationNV _al_glGetVaryingLocationNV +#define glGetActiveVaryingNV _al_glGetActiveVaryingNV +#define glActiveVaryingNV _al_glActiveVaryingNV +#define glGetTransformFeedbackVaryingNV _al_glGetTransformFeedbackVaryingNV +#if !defined _ALLEGRO_GL_EXT_draw_buffers2 +#define glGetBooleanIndexedvEXT _al_glGetBooleanIndexedvEXT +/*AGL_API(void,GetIntegerIndexedvEXT,(GLenum,GLuint,GLint*))*/ +#endif +#endif + +#if defined _ALLEGRO_GL_NV_vertex_program4 +#ifndef _ALLEGRO_GL_EXT_gpu_shader4 +#define glVertexAttribI1iEXT _al_glVertexAttribI1iEXT +#define glVertexAttribI2iEXT _al_glVertexAttribI2iEXT +#define glVertexAttribI3iEXT _al_glVertexAttribI3iEXT +#define glVertexAttribI4iEXT _al_glVertexAttribI4iEXT +#define glVertexAttribI1uiEXT _al_glVertexAttribI1uiEXT +#define glVertexAttribI2uiEXT _al_glVertexAttribI2uiEXT +#define glVertexAttribI3uiEXT _al_glVertexAttribI3uiEXT +#define glVertexAttribI4uiEXT _al_glVertexAttribI4uiEXT +#define glVertexAttribI1ivEXT _al_glVertexAttribI1ivEXT +#define glVertexAttribI2ivEXT _al_glVertexAttribI2ivEXT +#define glVertexAttribI3ivEXT _al_glVertexAttribI3ivEXT +#define glVertexAttribI4ivEXT _al_glVertexAttribI4ivEXT +#define glVertexAttribI1uivEXT _al_glVertexAttribI1uivEXT +#define glVertexAttribI2uivEXT _al_glVertexAttribI2uivEXT +#define glVertexAttribI3uivEXT _al_glVertexAttribI3uivEXT +#define glVertexAttribI4uivEXT _al_glVertexAttribI4uivEXT +#define glVertexAttribI4bvEXT _al_glVertexAttribI4bvEXT +#define glVertexAttribI4svEXT _al_glVertexAttribI4svEXT +#define glVertexAttribI4ubvEXT _al_glVertexAttribI4ubvEXT +#define glVertexAttribI4usvEXT _al_glVertexAttribI4usvEXT +#define glVertexAttribIPointerEXT _al_glVertexAttribIPointerEXT +#define glGetVertexAttribIivEXT _al_glGetVertexAttribIivEXT +#define glGetVertexAttribIuivEXT _al_glGetVertexAttribIuivEXT +#endif +#endif + +#if defined _ALLEGRO_GL_GREMEDY_frame_terminator +#define glFrameTerminatorGREMEDY _al_glFrameTerminatorGREMEDY +#endif + +#if defined _ALLEGRO_GL_NV_conditional_render +#define glBeginConditionalRenderNV _al_glBeginConditionalRenderNV +#define glEndConditionalRenderNV _al_glEndConditionalRenderNV +#endif + +#if defined _ALLEGRO_GL_EXT_transform_feedback +#define glBeginTransformFeedbackEXT _al_glBeginTransformFeedbackEXT +#define glEndTransformFeedbackEXT _al_glEndTransformFeedbackEXT +#define glBindBufferRangeEXT _al_glBindBufferRangeEXT +#define glBindBufferOffsetEXT _al_glBindBufferOffsetEXT +#define glBindBufferBaseEXT _al_glBindBufferBaseEXT +#define glTransformFeedbackVaryingsEXT _al_glTransformFeedbackVaryingsEXT +#define glGetTransformFeedbackVaryingEXT _al_glGetTransformFeedbackVaryingEXT +#endif + +#if defined _ALLEGRO_GL_EXT_direct_state_access +#define glClientAttribDefaultEXT _al_glClientAttribDefaultEXT +#define glPushClientAttribDefaultEXT _al_glPushClientAttribDefaultEXT +#define glMatrixLoadfEXT _al_glMatrixLoadfEXT +#define glMatrixLoaddEXT _al_glMatrixLoaddEXT +#define glMatrixMultfEXT _al_glMatrixMultfEXT +#define glMatrixMultdEXT _al_glMatrixMultdEXT +#define glMatrixLoadIdentityEXT _al_glMatrixLoadIdentityEXT +#define glMatrixRotatefEXT _al_glMatrixRotatefEXT +#define glMatrixRotatedEXT _al_glMatrixRotatedEXT +#define glMatrixScalefEXT _al_glMatrixScalefEXT +#define glMatrixScaledEXT _al_glMatrixScaledEXT +#define glMatrixTranslatefEXT _al_glMatrixTranslatefEXT +#define glMatrixTranslatedEXT _al_glMatrixTranslatedEXT +#define glMatrixFrustumEXT _al_glMatrixFrustumEXT +#define glMatrixOrthoEXT _al_glMatrixOrthoEXT +#define glMatrixPopEXT _al_glMatrixPopEXT +#define glMatrixPushEXT _al_glMatrixPushEXT +#define glMatrixLoadTransposefEXT _al_glMatrixLoadTransposefEXT +#define glMatrixLoadTransposedEXT _al_glMatrixLoadTransposedEXT +#define glMatrixMultTransposefEXT _al_glMatrixMultTransposefEXT +#define glMatrixMultTransposedEXT _al_glMatrixMultTransposedEXT +#define glTextureParameterfEXT _al_glTextureParameterfEXT +#define glTextureParameterfvEXT _al_glTextureParameterfvEXT +#define glTextureParameteriEXT _al_glTextureParameteriEXT +#define glTextureParameterivEXT _al_glTextureParameterivEXT +#define glTextureImage1DEXT _al_glTextureImage1DEXT +#define glTextureImage2DEXT _al_glTextureImage2DEXT +#define glTextureSubImage1DEXT _al_glTextureSubImage1DEXT +#define glTextureSubImage2DEXT _al_glTextureSubImage2DEXT +#define glCopyTextureImage1DEXT _al_glCopyTextureImage1DEXT +#define glCopyTextureImage2DEXT _al_glCopyTextureImage2DEXT +#define glCopyTextureSubImage1DEXT _al_glCopyTextureSubImage1DEXT +#define glCopyTextureSubImage2DEXT _al_glCopyTextureSubImage2DEXT +#define glGetTextureImageEXT _al_glGetTextureImageEXT +#define glGetTextureParameterfvEXT _al_glGetTextureParameterfvEXT +#define glGetTextureParameterivEXT _al_glGetTextureParameterivEXT +#define glGetTextureLevelParameterfvEXT _al_glGetTextureLevelParameterfvEXT +#define glGetTextureLevelParameterivEXT _al_glGetTextureLevelParameterivEXT +#define glTextureImage3DEXT _al_glTextureImage3DEXT +#define glTextureSubImage3DEXT _al_glTextureSubImage3DEXT +#define glCopyTextureSubImage3DEXT _al_glCopyTextureSubImage3DEXT +#define glMultiTexParameterfEXT _al_glMultiTexParameterfEXT +#define glMultiTexParameterfvEXT _al_glMultiTexParameterfvEXT +#define glMultiTexParameteriEXT _al_glMultiTexParameteriEXT +#define glMultiTexParameterivEXT _al_glMultiTexParameterivEXT +#define glMultiTexImage1DEXT _al_glMultiTexImage1DEXT +#define glMultiTexImage2DEXT _al_glMultiTexImage2DEXT +#define glMultiTexSubImage1DEXT _al_glMultiTexSubImage1DEXT +#define glMultiTexSubImage2DEXT _al_glMultiTexSubImage2DEXT +#define glCopyMultiTexImage1DEXT _al_glCopyMultiTexImage1DEXT +#define glCopyMultiTexImage2DEXT _al_glCopyMultiTexImage2DEXT +#define glCopyMultiTexSubImage1DEXT _al_glCopyMultiTexSubImage1DEXT +#define glCopyMultiTexSubImage2DEXT _al_glCopyMultiTexSubImage2DEXT +#define glGetMultiTexImageEXT _al_glGetMultiTexImageEXT +#define glGetMultiTexParameterfvEXT _al_glGetMultiTexParameterfvEXT +#define glGetMultiTexParameterivEXT _al_glGetMultiTexParameterivEXT +#define glGetMultiTexLevelParameterfvEXT _al_glGetMultiTexLevelParameterfvEXT +#define glGetMultiTexLevelParameterivEXT _al_glGetMultiTexLevelParameterivEXT +#define glMultiTexImage3DEXT _al_glMultiTexImage3DEXT +#define glMultiTexSubImage3DEXT _al_glMultiTexSubImage3DEXT +#define glCopyMultiTexSubImage3DEXT _al_glCopyMultiTexSubImage3DEXT +#define glBindMultiTextureEXT _al_glBindMultiTextureEXT +#define glEnableClientStateIndexedEXT _al_glEnableClientStateIndexedEXT +#define glDisableClientStateIndexedEXT _al_glDisableClientStateIndexedEXT +#define glMultiTexCoordPointerEXT _al_glMultiTexCoordPointerEXT +#define glMultiTexEnvfEXT _al_glMultiTexEnvfEXT +#define glMultiTexEnvfvEXT _al_glMultiTexEnvfvEXT +#define glMultiTexEnviEXT _al_glMultiTexEnviEXT +#define glMultiTexEnvivEXT _al_glMultiTexEnvivEXT +#define glMultiTexGendEXT _al_glMultiTexGendEXT +#define glMultiTexGendvEXT _al_glMultiTexGendvEXT +#define glMultiTexGenfEXT _al_glMultiTexGenfEXT +#define glMultiTexGenfvEXT _al_glMultiTexGenfvEXT +#define glMultiTexGeniEXT _al_glMultiTexGeniEXT +#define glMultiTexGenivEXT _al_glMultiTexGenivEXT +#define glGetMultiTexEnvfvEXT _al_glGetMultiTexEnvfvEXT +#define glGetMultiTexEnvivEXT _al_glGetMultiTexEnvivEXT +#define glGetMultiTexGendvEXT _al_glGetMultiTexGendvEXT +#define glGetMultiTexGenfvEXT _al_glGetMultiTexGenfvEXT +#define glGetMultiTexGenivEXT _al_glGetMultiTexGenivEXT +#define glGetFloatIndexedvEXT _al_glGetFloatIndexedvEXT +#define glGetDoubleIndexedvEXT _al_glGetDoubleIndexedvEXT +#define glGetPointerIndexedvEXT _al_glGetPointerIndexedvEXT +#define glCompressedTextureImage3DEXT _al_glCompressedTextureImage3DEXT +#define glCompressedTextureImage2DEXT _al_glCompressedTextureImage2DEXT +#define glCompressedTextureImage1DEXT _al_glCompressedTextureImage1DEXT +#define glCompressedTextureSubImage3DEXT _al_glCompressedTextureSubImage3DEXT +#define glCompressedTextureSubImage2DEXT _al_glCompressedTextureSubImage2DEXT +#define glCompressedTextureSubImage1DEXT _al_glCompressedTextureSubImage1DEXT +#define glGetCompressedTextureImageEXT _al_glGetCompressedTextureImageEXT +#define glCompressedMultiTexImage3DEXT _al_glCompressedMultiTexImage3DEXT +#define glCompressedMultiTexImage2DEXT _al_glCompressedMultiTexImage2DEXT +#define glCompressedMultiTexImage1DEXT _al_glCompressedMultiTexImage1DEXT +#define glCompressedMultiTexSubImage3DEXT _al_glCompressedMultiTexSubImage3DEXT +#define glCompressedMultiTexSubImage2DEXT _al_glCompressedMultiTexSubImage2DEXT +#define glCompressedMultiTexSubImage1DEXT _al_glCompressedMultiTexSubImage1DEXT +#define glGetCompressedMultiTexImageEXT _al_glGetCompressedMultiTexImageEXT +#define glNamedProgramStringEXT _al_glNamedProgramStringEXT +#define glNamedProgramLocalParameter4dEXT _al_glNamedProgramLocalParameter4dEXT +#define glNamedProgramLocalParameter4dvEXT _al_glNamedProgramLocalParameter4dvEXT +#define glNamedProgramLocalParameter4fEXT _al_glNamedProgramLocalParameter4fEXT +#define glNamedProgramLocalParameter4fvEXT _al_glNamedProgramLocalParameter4fvEXT +#define glGetNamedProgramLocalParameterdvEXT _al_glGetNamedProgramLocalParameterdvEXT +#define glGetNamedProgramLocalParameterfvEXT _al_glGetNamedProgramLocalParameterfvEXT +#define glGetNamedProgramivEXT _al_glGetNamedProgramivEXT +#define glGetNamedProgramStringEXT _al_glGetNamedProgramStringEXT +#define glNamedProgramLocalParameters4fvEXT _al_glNamedProgramLocalParameters4fvEXT +#define glNamedProgramLocalParameterI4iEXT _al_glNamedProgramLocalParameterI4iEXT +#define glNamedProgramLocalParameterI4ivEXT _al_glNamedProgramLocalParameterI4ivEXT +#define glNamedProgramLocalParametersI4ivEXT _al_glNamedProgramLocalParametersI4ivEXT +#define glNamedProgramLocalParameterI4uiEXT _al_glNamedProgramLocalParameterI4uiEXT +#define glNamedProgramLocalParameterI4uivEXT _al_glNamedProgramLocalParameterI4uivEXT +#define glNamedProgramLocalParametersI4uivEXT _al_glNamedProgramLocalParametersI4uivEXT +#define glGetNamedProgramLocalParameterIivEXT _al_glGetNamedProgramLocalParameterIivEXT +#define glGetNamedProgramLocalParameterIuivEXT _al_glGetNamedProgramLocalParameterIuivEXT +#define glTextureParameterIivEXT _al_glTextureParameterIivEXT +#define glTextureParameterIuivEXT _al_glTextureParameterIuivEXT +#define glGetTextureParameterIivEXT _al_glGetTextureParameterIivEXT +#define glGetTextureParameterIuivEXT _al_glGetTextureParameterIuivEXT +#define glMultiTexParameterIivEXT _al_glMultiTexParameterIivEXT +#define glMultiTexParameterIuivEXT _al_glMultiTexParameterIuivEXT +#define glGetMultiTexParameterIivEXT _al_glGetMultiTexParameterIivEXT +#define glGetMultiTexParameterIuivEXT _al_glGetMultiTexParameterIuivEXT +#define glProgramUniform1fEXT _al_glProgramUniform1fEXT +#define glProgramUniform2fEXT _al_glProgramUniform2fEXT +#define glProgramUniform3fEXT _al_glProgramUniform3fEXT +#define glProgramUniform4fEXT _al_glProgramUniform4fEXT +#define glProgramUniform1iEXT _al_glProgramUniform1iEXT +#define glProgramUniform2iEXT _al_glProgramUniform2iEXT +#define glProgramUniform3iEXT _al_glProgramUniform3iEXT +#define glProgramUniform4iEXT _al_glProgramUniform4iEXT +#define glProgramUniform1fvEXT _al_glProgramUniform1fvEXT +#define glProgramUniform2fvEXT _al_glProgramUniform2fvEXT +#define glProgramUniform3fvEXT _al_glProgramUniform3fvEXT +#define glProgramUniform4fvEXT _al_glProgramUniform4fvEXT +#define glProgramUniform1ivEXT _al_glProgramUniform1ivEXT +#define glProgramUniform2ivEXT _al_glProgramUniform2ivEXT +#define glProgramUniform3ivEXT _al_glProgramUniform3ivEXT +#define glProgramUniform4ivEXT _al_glProgramUniform4ivEXT +#define glProgramUniformMatrix2fvEXT _al_glProgramUniformMatrix2fvEXT +#define glProgramUniformMatrix3fvEXT _al_glProgramUniformMatrix3fvEXT +#define glProgramUniformMatrix4fvEXT _al_glProgramUniformMatrix4fvEXT +#define glProgramUniformMatrix2x3fvEXT _al_glProgramUniformMatrix2x3fvEXT +#define glProgramUniformMatrix3x2fvEXT _al_glProgramUniformMatrix3x2fvEXT +#define glProgramUniformMatrix2x4fvEXT _al_glProgramUniformMatrix2x4fvEXT +#define glProgramUniformMatrix4x2fvEXT _al_glProgramUniformMatrix4x2fvEXT +#define glProgramUniformMatrix3x4fvEXT _al_glProgramUniformMatrix3x4fvEXT +#define glProgramUniformMatrix4x3fvEXT _al_glProgramUniformMatrix4x3fvEXT +#define glProgramUniform1uiEXT _al_glProgramUniform1uiEXT +#define glProgramUniform2uiEXT _al_glProgramUniform2uiEXT +#define glProgramUniform3uiEXT _al_glProgramUniform3uiEXT +#define glProgramUniform4uiEXT _al_glProgramUniform4uiEXT +#define glProgramUniform1uivEXT _al_glProgramUniform1uivEXT +#define glProgramUniform2uivEXT _al_glProgramUniform2uivEXT +#define glProgramUniform3uivEXT _al_glProgramUniform3uivEXT +#define glProgramUniform4uivEXT _al_glProgramUniform4uivEXT +#define glNamedBufferDataEXT _al_glNamedBufferDataEXT +#define glNamedBufferSubDataEXT _al_glNamedBufferSubDataEXT +#define glMapNamedBufferEXT _al_glMapNamedBufferEXT +#define glUnmapNamedBufferEXT _al_glUnmapNamedBufferEXT +#define glGetNamedBufferParameterivEXT _al_glGetNamedBufferParameterivEXT +#define glGetNamedBufferPointervEXT _al_glGetNamedBufferPointervEXT +#define glGetNamedBufferSubDataEXT _al_glGetNamedBufferSubDataEXT +#define glTextureBufferEXT _al_glTextureBufferEXT +#define glMultiTexBufferEXT _al_glMultiTexBufferEXT +#define glNamedRenderbufferStorageEXT _al_glNamedRenderbufferStorageEXT +#define glGetNamedRenderbufferParameterivEXT _al_glGetNamedRenderbufferParameterivEXT +#define glCheckNamedFramebufferStatusEXT _al_glCheckNamedFramebufferStatusEXT +#define glNamedFramebufferTexture1DEXT _al_glNamedFramebufferTexture1DEXT +#define glNamedFramebufferTexture2DEXT _al_glNamedFramebufferTexture2DEXT +#define glNamedFramebufferTexture3DEXT _al_glNamedFramebufferTexture3DEXT +#define glNamedFramebufferRenderbufferEXT _al_glNamedFramebufferRenderbufferEXT +#define glGetNamedFramebufferAttachmentParameterivEXT _al_glGetNamedFramebufferAttachmentParameterivEXT +#define glGenerateTextureMipmapEXT _al_glGenerateTextureMipmapEXT +#define glGenerateMultiTexMipmapEXT _al_glGenerateMultiTexMipmapEXT +#define glFramebufferDrawBufferEXT _al_glFramebufferDrawBufferEXT +#define glFramebufferDrawBuffersEXT _al_glFramebufferDrawBuffersEXT +#define glFramebufferReadBufferEXT _al_glFramebufferReadBufferEXT +#define glGetFramebufferParameterivEXT _al_glGetFramebufferParameterivEXT +#define glNamedRenderbufferStorageMultisampleEXT _al_glNamedRenderbufferStorageMultisampleEXT +#define glNamedRenderbufferStorageMultisampleCoverageEXT _al_glNamedRenderbufferStorageMultisampleCoverageEXT +#define glNamedFramebufferTextureEXT _al_glNamedFramebufferTextureEXT +#define glNamedFramebufferTextureLayerEXT _al_glNamedFramebufferTextureLayerEXT +#define glNamedFramebufferTextureFaceEXT _al_glNamedFramebufferTextureFaceEXT +#define glTextureRenderbufferEXT _al_glTextureRenderbufferEXT +#define glMultiTexRenderbufferEXT _al_glMultiTexRenderbufferEXT +#endif + +#if defined _ALLEGRO_GL_NV_explicit_multisample +#define glGetMultisamplefvNV _al_glGetMultisamplefvNV +#define glSampleMaskIndexedNV _al_glSampleMaskIndexedNV +#define glTexRenderbufferNV _al_glTexRenderbufferNV +#endif + +#if defined _ALLEGRO_GL_NV_transform_feedback2 +#define glBindTransformFeedbackNV _al_glBindTransformFeedbackNV +#define glDeleteTransformFeedbacksNV _al_glDeleteTransformFeedbacksNV +#define glGenTransformFeedbacksNV _al_glGenTransformFeedbacksNV +#define glIsTransformFeedbackNV _al_glIsTransformFeedbackNV +#define glPauseTransformFeedbackNV _al_glPauseTransformFeedbackNV +#define glResumeTransformFeedbackNV _al_glResumeTransformFeedbackNV +#define glDrawTransformFeedbackNV _al_glDrawTransformFeedbackNV +#endif + +#if defined _ALLEGRO_GL_AMD_performance_monitor +#define glGetPerfMonitorGroupsAMD _al_glGetPerfMonitorGroupsAMD +#define glGetPerfMonitorCountersAMD _al_glGetPerfMonitorCountersAMD +#define glGetPerfMonitorGroupStringAMD _al_glGetPerfMonitorGroupStringAMD +#define glGetPerfMonitorCounterStringAMD _al_glGetPerfMonitorCounterStringAMD +#define glGetPerfMonitorCounterInfoAMD _al_glGetPerfMonitorCounterInfoAMD +#define glGenPerfMonitorsAMD _al_glGenPerfMonitorsAMD +#define glDeletePerfMonitorsAMD _al_glDeletePerfMonitorsAMD +#define glSelectPerfMonitorCountersAMD _al_glSelectPerfMonitorCountersAMD +#define glBeginPerfMonitorAMD _al_glBeginPerfMonitorAMD +#define glEndPerfMonitorAMD _al_glEndPerfMonitorAMD +#define glGetPerfMonitorCounterDataAMD _al_glGetPerfMonitorCounterDataAMD +#endif + +#if defined _ALLEGRO_GL_AMD_vertex_shader_tesselator +#define glTessellationFactorAMD _al_glTessellationFactorAMD +#define glTessellationModeAMD _al_glTessellationModeAMD +#endif + +#if defined _ALLEGRO_GL_EXT_provoking_vertex +#define glProvokingVertexEXT _al_glProvokingVertexEXT +#endif + +#if defined _ALLEGRO_GL_AMD_draw_buffers_blend +#define glBlendFuncIndexedAMD _al_glBlendFuncIndexedAMD +#define glBlendFuncSeparateIndexedAMD _al_glBlendFuncSeparateIndexedAMD +#define glBlendEquationIndexedAMD _al_glBlendEquationIndexedAMD +#define glBlendEquationSeparateIndexedAMD _al_glBlendEquationSeparateIndexedAMD +#endif + +#if defined _ALLEGRO_GL_APPLE_texture_range +#define glTextureRangeAPPLE _al_glTextureRangeAPPLE +#define glGetTexParameterPointervAPPLE _al_glGetTexParameterPointervAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_program_evaluators +#define glEnableVertexAttribAPPLE _al_glEnableVertexAttribAPPLE +#define glDisableVertexAttribAPPLE _al_glDisableVertexAttribAPPLE +#define glIsVertexAttribEnabledAPPLE _al_glIsVertexAttribEnabledAPPLE +#define glMapVertexAttrib1dAPPLE _al_glMapVertexAttrib1dAPPLE +#define glMapVertexAttrib1fAPPLE _al_glMapVertexAttrib1fAPPLE +#define glMapVertexAttrib2dAPPLE _al_glMapVertexAttrib2dAPPLE +#define glMapVertexAttrib2fAPPLE _al_glMapVertexAttrib2fAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_object_purgeable +#define glObjectPurgeableAPPLE _al_glObjectPurgeableAPPLE +#define glObjectUnpurgeableAPPLE _al_glObjectUnpurgeableAPPLE +#define glGetObjectParameterivAPPLE _al_glGetObjectParameterivAPPLE +#endif + +#if defined _ALLEGRO_GL_NV_video_capture +#define glBeginVideoCaptureNV _al_glBeginVideoCaptureNV +#define glBindVideoCaptureStreamBufferNV _al_glBindVideoCaptureStreamBufferNV +#define glBindVideoCaptureStreamTextureNV _al_glBindVideoCaptureStreamTextureNV +#define glEndVideoCaptureNV _al_glEndVideoCaptureNV +#define glGetVideoCaptureivNV _al_glGetVideoCaptureivNV +#define glGetVideoCaptureStreamivNV _al_glGetVideoCaptureStreamivNV +#define glGetVideoCaptureStreamfvNV _al_glGetVideoCaptureStreamfvNV +#define glGetVideoCaptureStreamdvNV _al_glGetVideoCaptureStreamdvNV +#define glVideoCaptureNV _al_glVideoCaptureNV +#define glVideoCaptureStreamParameterivNV _al_glVideoCaptureStreamParameterivNV +#define glVideoCaptureStreamParameterfvNV _al_glVideoCaptureStreamParameterfvNV +#define glVideoCaptureStreamParameterdvNV _al_glVideoCaptureStreamParameterdvNV +#endif + +#if defined _ALLEGRO_GL_EXT_separate_shader_objects +#define glUseShaderProgramEXT _al_glUseShaderProgramEXT +#define glActiveProgramEXT _al_glActiveProgramEXT +#define glCreateShaderProgramEXT _al_glCreateShaderProgramEXT +#endif + +#if defined _ALLEGRO_GL_NV_shader_buffer_load +#define glMakeBufferResidentNV _al_glMakeBufferResidentNV +#define glMakeBufferNonResidentNV _al_glMakeBufferNonResidentNV +#define glIsBufferResidentNV _al_glIsBufferResidentNV +#define glMakeNamedBufferResidentNV _al_glMakeNamedBufferResidentNV +#define glMakeNamedBufferNonResidentNV _al_glMakeNamedBufferNonResidentNV +#define glIsNamedBufferResidentNV _al_glIsNamedBufferResidentNV +#define glGetBufferParameterui64vNV _al_glGetBufferParameterui64vNV +#define glGetNamedBufferParameterui64vNV _al_glGetNamedBufferParameterui64vNV +#define glGetIntegerui64vNV _al_glGetIntegerui64vNV +#define glUniformui64NV _al_glUniformui64NV +#define glUniformui64vNV _al_glUniformui64vNV +#define glGetUniformui64vNV _al_glGetUniformui64vNV +#define glProgramUniformui64NV _al_glProgramUniformui64NV +#define glProgramUniformui64vNV _al_glProgramUniformui64vNV +#endif + +#if defined _ALLEGRO_GL_NV_vertex_buffer_unified_memory +#define glBufferAddressRangeNV _al_glBufferAddressRangeNV +#define glVertexFormatNV _al_glVertexFormatNV +#define glNormalFormatNV _al_glNormalFormatNV +#define glColorFormatNV _al_glColorFormatNV +#define glIndexFormatNV _al_glIndexFormatNV +#define glTexCoordFormatNV _al_glTexCoordFormatNV +#define glEdgeFlagFormatNV _al_glEdgeFlagFormatNV +#define glSecondaryColorFormatNV _al_glSecondaryColorFormatNV +#define glFogCoordFormatNV _al_glFogCoordFormatNV +#define glVertexAttribFormatNV _al_glVertexAttribFormatNV +#define glVertexAttribIFormatNV _al_glVertexAttribIFormatNV +#define glGetIntegerui64i_vNV _al_glGetIntegerui64i_vNV +#endif + +#if defined _ALLEGRO_GL_NV_texture_barrier +#define glTextureBarrierNV _al_glTextureBarrierNV +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_api.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_api.h new file mode 100644 index 00000000..13903718 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_api.h @@ -0,0 +1,2563 @@ +/* */ + +#ifdef _ALLEGRO_GL_VERSION_1_2 +AGL_API(void, BlendColor, (GLclampf, GLclampf, GLclampf, GLclampf)) +AGL_API(void, BlendEquation, (GLenum)) +AGL_API(void, DrawRangeElements, (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *)) +AGL_API(void, ColorTable, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ColorTableParameterfv, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, ColorTableParameteriv, (GLenum, GLenum, const GLint *)) +AGL_API(void, CopyColorTable, (GLenum, GLenum, GLint, GLint, GLsizei)) +AGL_API(void, GetColorTable, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetColorTableParameterfv, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetColorTableParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, ColorSubTable, (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyColorSubTable, (GLenum, GLsizei, GLint, GLint, GLsizei)) +AGL_API(void, TexImage3D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyTexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_ARB_imaging +AGL_API(void, ConvolutionFilter1D, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ConvolutionFilter2D, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ConvolutionParameterf, (GLenum, GLenum, GLfloat)) +AGL_API(void, ConvolutionParameterfv, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, ConvolutionParameteri, (GLenum, GLenum, GLint)) +AGL_API(void, ConvolutionParameteriv, (GLenum, GLenum, const GLint *)) +AGL_API(void, CopyConvolutionFilter1D, (GLenum, GLenum, GLint, GLint, GLsizei)) +AGL_API(void, CopyConvolutionFilter2D, (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, GetConvolutionFilter, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetConvolutionParameterfv, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetConvolutionParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetSeparableFilter, (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *)) +AGL_API(void, SeparableFilter2D, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *)) +AGL_API(void, GetHistogram, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetHistogramParameterfv, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetHistogramParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetMinmax, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetMinmaxParameterfv, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMinmaxParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, Histogram, (GLenum, GLsizei, GLenum, GLboolean)) +AGL_API(void, Minmax, (GLenum, GLenum, GLboolean)) +AGL_API(void, ResetHistogram, (GLenum)) +AGL_API(void, ResetMinmax, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_VERSION_1_3 +AGL_API(void, ActiveTexture, (GLenum)) +AGL_API(void, ClientActiveTexture, (GLenum)) +AGL_API(void, MultiTexCoord1d, (GLenum, GLdouble)) +AGL_API(void, MultiTexCoord1dv, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord1f, (GLenum, GLfloat)) +AGL_API(void, MultiTexCoord1fv, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord1i, (GLenum, GLint)) +AGL_API(void, MultiTexCoord1iv, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord1s, (GLenum, GLshort)) +AGL_API(void, MultiTexCoord1sv, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord2d, (GLenum, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord2dv, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord2f, (GLenum, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord2fv, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord2i, (GLenum, GLint, GLint)) +AGL_API(void, MultiTexCoord2iv, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord2s, (GLenum, GLshort, GLshort)) +AGL_API(void, MultiTexCoord2sv, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord3d, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord3dv, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord3f, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord3fv, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord3i, (GLenum, GLint, GLint, GLint)) +AGL_API(void, MultiTexCoord3iv, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord3s, (GLenum, GLshort, GLshort, GLshort)) +AGL_API(void, MultiTexCoord3sv, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord4d, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord4dv, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord4f, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord4fv, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord4i, (GLenum, GLint, GLint, GLint, GLint)) +AGL_API(void, MultiTexCoord4iv, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord4s, (GLenum, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, MultiTexCoord4sv, (GLenum, const GLshort *)) +AGL_API(void, LoadTransposeMatrixf, (const GLfloat *)) +AGL_API(void, LoadTransposeMatrixd, (const GLdouble *)) +AGL_API(void, MultTransposeMatrixf, (const GLfloat *)) +AGL_API(void, MultTransposeMatrixd, (const GLdouble *)) +AGL_API(void, SampleCoverage, (GLclampf, GLboolean)) +AGL_API(void, CompressedTexImage3D, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexImage2D, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexImage1D, (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage1D, (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetCompressedTexImage, (GLenum, GLint, GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_VERSION_1_4 +AGL_API(void, BlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, FogCoordf, (GLfloat)) +AGL_API(void, FogCoordfv, (const GLfloat *)) +AGL_API(void, FogCoordd, (GLdouble)) +AGL_API(void, FogCoorddv, (const GLdouble *)) +AGL_API(void, FogCoordPointer, (GLenum, GLsizei, const GLvoid *)) +AGL_API(void, MultiDrawArrays, (GLenum, GLint *, GLsizei *, GLsizei)) +AGL_API(void, MultiDrawElements, (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei)) +AGL_API(void, PointParameterf, (GLenum, GLfloat)) +AGL_API(void, PointParameterfv, (GLenum, const GLfloat *)) +AGL_API(void, PointParameteri, (GLenum, GLint)) +AGL_API(void, PointParameteriv, (GLenum, const GLint *)) +AGL_API(void, SecondaryColor3b, (GLbyte, GLbyte, GLbyte)) +AGL_API(void, SecondaryColor3bv, (const GLbyte *)) +AGL_API(void, SecondaryColor3d, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, SecondaryColor3dv, (const GLdouble *)) +AGL_API(void, SecondaryColor3f, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, SecondaryColor3fv, (const GLfloat *)) +AGL_API(void, SecondaryColor3i, (GLint, GLint, GLint)) +AGL_API(void, SecondaryColor3iv, (const GLint *)) +AGL_API(void, SecondaryColor3s, (GLshort, GLshort, GLshort)) +AGL_API(void, SecondaryColor3sv, (const GLshort *)) +AGL_API(void, SecondaryColor3ub, (GLubyte, GLubyte, GLubyte)) +AGL_API(void, SecondaryColor3ubv, (const GLubyte *)) +AGL_API(void, SecondaryColor3ui, (GLuint, GLuint, GLuint)) +AGL_API(void, SecondaryColor3uiv, (const GLuint *)) +AGL_API(void, SecondaryColor3us, (GLushort, GLushort, GLushort)) +AGL_API(void, SecondaryColor3usv, (const GLushort *)) +AGL_API(void, SecondaryColorPointer, (GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, WindowPos2d, (GLdouble, GLdouble)) +AGL_API(void, WindowPos2dv, (const GLdouble *)) +AGL_API(void, WindowPos2f, (GLfloat, GLfloat)) +AGL_API(void, WindowPos2fv, (const GLfloat *)) +AGL_API(void, WindowPos2i, (GLint, GLint)) +AGL_API(void, WindowPos2iv, (const GLint *)) +AGL_API(void, WindowPos2s, (GLshort, GLshort)) +AGL_API(void, WindowPos2sv, (const GLshort *)) +AGL_API(void, WindowPos3d, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, WindowPos3dv, (const GLdouble *)) +AGL_API(void, WindowPos3f, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, WindowPos3fv, (const GLfloat *)) +AGL_API(void, WindowPos3i, (GLint, GLint, GLint)) +AGL_API(void, WindowPos3iv, (const GLint *)) +AGL_API(void, WindowPos3s, (GLshort, GLshort, GLshort)) +AGL_API(void, WindowPos3sv, (const GLshort *)) +#endif + + +#if defined _ALLEGRO_GL_VERSION_1_5 +AGL_API(void, BindBuffer, (GLenum, GLuint)) +AGL_API(void, DeleteBuffers, (GLsizei, const GLuint *)) +AGL_API(void, GenBuffers, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsBuffer, (GLuint)) +AGL_API(void, BufferData, (GLenum, GLsizeiptr, const GLvoid *, GLenum)) +AGL_API(void, BufferSubData, (GLenum, GLintptr, GLsizeiptr, const GLvoid *)) +AGL_API(void, GetBufferSubData, (GLenum, GLintptr, GLsizeiptr, GLvoid *)) +AGL_API(GLvoid*, MapBuffer, (GLenum, GLenum)) +AGL_API(GLboolean, UnmapBuffer, (GLenum)) +AGL_API(void, GetBufferParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetBufferPointerv, (GLenum, GLenum, GLvoid* *)) +AGL_API(void, GenQueries, (GLsizei, GLuint *)) +AGL_API(void, DeleteQueries, (GLsizei, const GLuint *)) +AGL_API(GLboolean, IsQuery, (GLuint)) +AGL_API(void, BeginQuery, (GLenum, GLuint)) +AGL_API(void, EndQuery, (GLenum)) +AGL_API(void, GetQueryiv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetQueryObjectiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetQueryObjectuiv, (GLuint, GLenum, GLuint *)) +#endif + + +#if defined _ALLEGRO_GL_VERSION_2_0 +AGL_API(void, BlendEquationSeparate, (GLenum, GLenum)) +AGL_API(GLuint, CreateProgram, (void)) +AGL_API(GLuint, CreateShader, (GLenum)) +AGL_API(void, DeleteProgram, (GLuint)) +AGL_API(void, DeleteShader, (GLuint)) +AGL_API(void, AttachShader, (GLuint, GLuint)) +AGL_API(void, DetachShader, (GLuint, GLuint)) +AGL_API(void, ShaderSource, (GLuint, GLsizei, const GLchar **, const GLint *)) +AGL_API(void, CompileShader, (GLuint)) +AGL_API(GLboolean, IsProgram, (GLuint)) +AGL_API(GLboolean, IsShader, (GLuint)) +AGL_API(void, LinkProgram, (GLuint)) +AGL_API(void, UseProgram, (GLuint)) +AGL_API(void, ValidateProgram, (GLuint)) +AGL_API(void, Uniform1f, (GLint, GLfloat)) +AGL_API(void, Uniform2f, (GLint, GLfloat, GLfloat)) +AGL_API(void, Uniform3f, (GLint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Uniform4f, (GLint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Uniform1i, (GLint, GLint)) +AGL_API(void, Uniform2i, (GLint, GLint, GLint)) +AGL_API(void, Uniform3i, (GLint, GLint, GLint, GLint)) +AGL_API(void, Uniform4i, (GLint, GLint, GLint, GLint, GLint)) +AGL_API(void, Uniform1fv, (GLint, GLsizei, const GLfloat *)) +AGL_API(void, Uniform2fv, (GLint, GLsizei, const GLfloat *)) +AGL_API(void, Uniform3fv, (GLint, GLsizei, const GLfloat *)) +AGL_API(void, Uniform4fv, (GLint, GLsizei, const GLfloat *)) +AGL_API(void, Uniform1iv, (GLint, GLsizei, const GLint *)) +AGL_API(void, Uniform2iv, (GLint, GLsizei, const GLint *)) +AGL_API(void, Uniform3iv, (GLint, GLsizei, const GLint *)) +AGL_API(void, Uniform4iv, (GLint, GLsizei, const GLint *)) +AGL_API(void, UniformMatrix2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, GetShaderfv, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetShaderiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetProgramfv, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetProgramiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetShaderInfoLog, (GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, GetProgramInfoLog, (GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, GetAttachedShaders, (GLuint, GLsizei, GLsizei *, GLuint *)) +AGL_API(GLint, GetUniformLocation, (GLuint, const GLchar *)) +AGL_API(void, GetActiveUniform, (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *)) +AGL_API(void, GetUniformfv, (GLuint, GLint, GLfloat *)) +AGL_API(void, GetUniformiv, (GLuint, GLint, GLint *)) +AGL_API(void, GetShaderSource, (GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, VertexAttrib1f, (GLuint, GLfloat)) +AGL_API(void, VertexAttrib1s, (GLuint, GLshort)) +AGL_API(void, VertexAttrib1d, (GLuint, GLdouble)) +AGL_API(void, VertexAttrib2f, (GLuint, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib2s, (GLuint, GLshort, GLshort)) +AGL_API(void, VertexAttrib2d, (GLuint, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib3f, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib3s, (GLuint, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib3d, (GLuint, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4f, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib4s, (GLuint, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib4d, (GLuint, GLdouble,GLdouble,GLdouble,GLdouble)) +AGL_API(void, VertexAttrib4Nub, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) +AGL_API(void, VertexAttrib1fv, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib1sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib1dv, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib2fv, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib2sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib2dv, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib3fv, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib3sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib3dv, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4fv, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib4sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4dv, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4bv, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4ubv, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4usv, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttrib4Nbv, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4Nsv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4Niv, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4Nubv, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4Nusv, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4Nuiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribPointer,(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) +AGL_API(void, EnableVertexAttribArray, (GLuint)) +AGL_API(void, DisableVertexAttribArray, (GLuint)) + +AGL_API(void, BindAttribLocation, (GLuint, GLuint, const GLchar *)) +AGL_API(void, GetActiveAttrib, (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *)) +AGL_API(GLint, GetAttribLocation, (GLuint, const GLchar *)) +AGL_API(void, GetVertexAttribdv, (GLuint, GLenum, GLdouble *)) +AGL_API(void, GetVertexAttribfv, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribPointerv, (GLuint, GLenum, GLvoid **)) + +AGL_API(void, DrawBuffers, (GLsizei n, const GLenum *)) + +AGL_API(void, StencilOpSeparate, (GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, StencilFuncSeparate, (GLenum, GLenum, GLint, GLuint)) + +#endif + + +#if defined _ALLEGRO_GL_VERSION_2_1 +AGL_API(void, UniformMatrix2x3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix3x2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix2x4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix4x2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix3x4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix4x3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_VERSION_3_0 +/* OpenGL 3.0 also reuses entry points from these extensions: */ +/* ARB_framebuffer_object */ +/* ARB_map_buffer_range */ +/* ARB_vertex_array_object */ +AGL_API(void, ColorMaski, (GLuint, GLboolean, GLboolean, GLboolean, GLboolean)) +AGL_API(void, GetBooleani_v, (GLenum, GLuint, GLboolean *)) +AGL_API(void, GetIntegeri_v, (GLenum, GLuint, GLint *)) +AGL_API(void, Enablei, (GLenum, GLuint)) +AGL_API(void, Disablei, (GLenum, GLuint)) +AGL_API(GLboolean, IsEnabledi, (GLenum, GLuint)) +AGL_API(void, BeginTransformFeedback, (GLenum)) +AGL_API(void, EndTransformFeedback, (void)) +AGL_API(void, BindBufferRange, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) +AGL_API(void, BindBufferBase, (GLenum, GLuint, GLuint)) +AGL_API(void, TransformFeedbackVaryings, (GLuint, GLsizei, const GLint *, GLenum)) +AGL_API(void, GetTransformFeedbackVarying, (GLuint, GLuint, GLint *)) +AGL_API(void, ClampColor, (GLenum, GLenum)) +AGL_API(void, BeginConditionalRender, (GLuint, GLenum)) +AGL_API(void, EndConditionalRender, (void)) +AGL_API(void, VertexAttribI1i, (GLuint, GLint)) +AGL_API(void, VertexAttribI2i, (GLuint, GLint, GLint)) +AGL_API(void, VertexAttribI3i, (GLuint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI4i, (GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI1ui, (GLuint, GLuint)) +AGL_API(void, VertexAttribI2ui, (GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI3ui, (GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI4ui, (GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI1iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI2iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI3iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI4iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI1uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI2uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI3uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4bv, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttribI4sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttribI4ubv, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttribI4usv, (GLuint, const GLushort *)) +AGL_API(void, VertexAttribIPointer, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetVertexAttribIiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribIuiv, (GLuint, GLenum, GLuint *)) +AGL_API(void, GetUniformuiv, (GLuint, GLint, GLuint *)) +AGL_API(void, BindFragDataLocation, (GLuint, GLuint, const GLchar *)) +AGL_API(GLint, GetFragDataLocation, (GLuint, const GLchar *)) +AGL_API(void, Uniform1ui, (GLint, GLuint)) +AGL_API(void, Uniform2ui, (GLint, GLuint, GLuint)) +AGL_API(void, Uniform3ui, (GLint, GLuint, GLuint, GLuint)) +AGL_API(void, Uniform4ui, (GLint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, Uniform1uiv, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform2uiv, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform3uiv, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform4uiv, (GLint, GLsizei, const GLuint *)) +AGL_API(void, TexParameterIiv, (GLenum, GLenum, const GLint *)) +AGL_API(void, TexParameterIuiv, (GLenum, GLenum, const GLuint *)) +AGL_API(void, GetTexParameterIiv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetTexParameterIuiv, (GLenum, GLenum, GLuint *)) +AGL_API(void, ClearBufferiv, (GLenum, GLint, const GLint *)) +AGL_API(void, ClearBufferuiv, (GLenum, GLint, const GLuint *)) +AGL_API(void, ClearBufferfv, (GLenum, GLint, const GLfloat *)) +AGL_API(void, ClearBufferfi, (GLenum, GLint, GLfloat, GLint)) +AGL_API(const GLubyte *, GetStringi, (GLenum, GLuint)) +#endif + + +#if defined _ALLEGRO_GL_VERSION_3_1 +/* OpenGL 3.1 also reuses entry points from these extensions: */ +/* ARB_copy_buffer */ +/* ARB_uniform_buffer_object */ +AGL_API(void, DrawArraysInstanced, (GLenum, GLint, GLsizei, GLsizei)) +AGL_API(void, DrawElementsInstanced, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) +AGL_API(void, TexBuffer, (GLenum, GLenum, GLuint)) +AGL_API(void, PrimitiveRestartIndex, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_VERSION_3_2 +/* OpenGL 3.2 also reuses entry points from these extensions: */ +/* ARB_draw_elements_base_vertex */ +/* ARB_provoking_vertex */ +/* ARB_sync */ +/* ARB_texture_multisample */ +AGL_API(void, GetInteger64i_v, (GLenum target, GLuint index, GLint64 *data)) +AGL_API(void, GetBufferParameteri64v, (GLenum target, GLenum pname, GLint64 *params)) +AGL_API(void, ProgramParameteri, (GLuint program, GLenum pname, GLint value)) +AGL_API(void, FramebufferTexture, (GLenum target, GLenum attachment, GLuint texture, GLint level)) +#endif + +#if defined _ALLEGRO_GL_VERSION_3_3 +/* OpenGL 3.3 also reuses entry points from these extensions: */ +/* ARB_blend_func_extended */ +/* ARB_sampler_objects */ +/* ARB_explicit_attrib_location, but it has none */ +/* ARB_occlusion_query2 (no entry points) */ +/* ARB_shader_bit_encoding (no entry points) */ +/* ARB_texture_rgb10_a2ui (no entry points) */ +/* ARB_texture_swizzle (no entry points) */ +/* ARB_timer_query */ +/* ARB_vertex_type_2_10_10_10_rev */ +#endif + + +/* */ +/* */ + +#ifdef _ALLEGRO_GL_ARB_multitexture +AGL_API(void, ActiveTextureARB, (GLenum)) +AGL_API(void, ClientActiveTextureARB, (GLenum)) +AGL_API(void, MultiTexCoord1dARB, (GLenum, GLdouble)) +AGL_API(void, MultiTexCoord1dvARB, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord1fARB, (GLenum, GLfloat)) +AGL_API(void, MultiTexCoord1fvARB, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord1iARB, (GLenum, GLint)) +AGL_API(void, MultiTexCoord1ivARB, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord1sARB, (GLenum, GLshort)) +AGL_API(void, MultiTexCoord1svARB, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord2dARB, (GLenum, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord2dvARB, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord2fARB, (GLenum, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord2fvARB, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord2iARB, (GLenum, GLint, GLint)) +AGL_API(void, MultiTexCoord2ivARB, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord2sARB, (GLenum, GLshort, GLshort)) +AGL_API(void, MultiTexCoord2svARB, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord3dARB, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord3dvARB, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord3fARB, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord3fvARB, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord3iARB, (GLenum, GLint, GLint, GLint)) +AGL_API(void, MultiTexCoord3ivARB, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord3sARB, (GLenum, GLshort, GLshort, GLshort)) +AGL_API(void, MultiTexCoord3svARB, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord4dARB, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord4dvARB, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord4fARB, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord4fvARB, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord4iARB, (GLenum, GLint, GLint, GLint, GLint)) +AGL_API(void, MultiTexCoord4ivARB, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord4sARB, (GLenum, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, MultiTexCoord4svARB, (GLenum, const GLshort *)) +#endif + +#if defined _ALLEGRO_GL_ARB_transpose_matrix +AGL_API(void, LoadTransposeMatrixfARB, (const GLfloat *)) +AGL_API(void, LoadTransposeMatrixdARB, (const GLdouble *)) +AGL_API(void, MultTransposeMatrixfARB, (const GLfloat *)) +AGL_API(void, MultTransposeMatrixdARB, (const GLdouble *)) +#endif + +#if defined _ALLEGRO_GL_ARB_multisample +AGL_API(void, SampleCoverageARB, (GLclampf, GLboolean)) +#endif + +#if defined _ALLEGRO_GL_ARB_texture_compression +AGL_API(void, CompressedTexImage3DARB, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexImage2DARB, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexImage1DARB, (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage3DARB, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage2DARB, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage1DARB, (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetCompressedTexImageARB, (GLenum, GLint, GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_ARB_point_parameters +AGL_API(void, PointParameterfARB, (GLenum, GLfloat)) +AGL_API(void, PointParameterfvARB, (GLenum, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_blend +AGL_API(void, WeightbvARB, (GLint, const GLbyte *)) +AGL_API(void, WeightsvARB, (GLint, const GLshort *)) +AGL_API(void, WeightivARB, (GLint, const GLint *)) +AGL_API(void, WeightfvARB, (GLint, const GLfloat *)) +AGL_API(void, WeightdvARB, (GLint, const GLdouble *)) +AGL_API(void, WeightubvARB, (GLint, const GLubyte *)) +AGL_API(void, WeightusvARB, (GLint, const GLushort *)) +AGL_API(void, WeightuivARB, (GLint, const GLuint *)) +AGL_API(void, WeightPointerARB, (GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, VertexBlendARB, (GLint)) +#endif + +#if defined _ALLEGRO_GL_ARB_matrix_palette +AGL_API(void, CurrentPaletteMatrixARB, (GLint)) +AGL_API(void, MatrixIndexubvARB, (GLint, const GLubyte *)) +AGL_API(void, MatrixIndexusvARB, (GLint, const GLushort *)) +AGL_API(void, MatrixIndexuivARB, (GLint, const GLuint *)) +AGL_API(void, MatrixIndexPointerARB, (GLint, GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_ARB_window_pos +AGL_API(void, WindowPos2dARB, (GLdouble, GLdouble)) +AGL_API(void, WindowPos2dvARB, (const GLdouble *)) +AGL_API(void, WindowPos2fARB, (GLfloat, GLfloat)) +AGL_API(void, WindowPos2fvARB, (const GLfloat *)) +AGL_API(void, WindowPos2iARB, (GLint, GLint)) +AGL_API(void, WindowPos2ivARB, (const GLint *)) +AGL_API(void, WindowPos2sARB, (GLshort, GLshort)) +AGL_API(void, WindowPos2svARB, (const GLshort *)) +AGL_API(void, WindowPos3dARB, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, WindowPos3dvARB, (const GLdouble *)) +AGL_API(void, WindowPos3fARB, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, WindowPos3fvARB, (const GLfloat *)) +AGL_API(void, WindowPos3iARB, (GLint, GLint, GLint)) +AGL_API(void, WindowPos3ivARB, (const GLint *)) +AGL_API(void, WindowPos3sARB, (GLshort, GLshort, GLshort)) +AGL_API(void, WindowPos3svARB, (const GLshort *)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_program +AGL_API(void, VertexAttrib1dARB, (GLuint, GLdouble)) +AGL_API(void, VertexAttrib1dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib1fARB, (GLuint, GLfloat)) +AGL_API(void, VertexAttrib1fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib1sARB, (GLuint, GLshort)) +AGL_API(void, VertexAttrib1svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib2dARB, (GLuint, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib2dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib2fARB, (GLuint, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib2fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib2sARB, (GLuint, GLshort, GLshort)) +AGL_API(void, VertexAttrib2svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib3dARB, (GLuint, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib3dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib3fARB, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib3fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib3sARB, (GLuint, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib3svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4NbvARB, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4NivARB, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4NsvARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4NubARB, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) +AGL_API(void, VertexAttrib4NubvARB, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4NuivARB, (GLuint, const GLuint *)) +AGL_API(void, VertexAttrib4NusvARB, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4bvARB, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4dARB, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4fARB, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib4fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib4ivARB, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4sARB, (GLuint, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib4svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4ubvARB, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4uivARB, (GLuint, const GLuint *)) +AGL_API(void, VertexAttrib4usvARB, (GLuint, const GLushort *)) +AGL_API(void, VertexAttribPointerARB, (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) +AGL_API(void, EnableVertexAttribArrayARB, (GLuint)) +AGL_API(void, DisableVertexAttribArrayARB, (GLuint)) +AGL_API(void, ProgramStringARB, (GLenum, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, BindProgramARB, (GLenum, GLuint)) +AGL_API(void, DeleteProgramsARB, (GLsizei, const GLuint *)) +AGL_API(void, GenProgramsARB, (GLsizei, GLuint *)) +AGL_API(void, ProgramEnvParameter4dARB, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, ProgramEnvParameter4dvARB, (GLenum, GLuint, const GLdouble *)) +AGL_API(void, ProgramEnvParameter4fARB, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramEnvParameter4fvARB, (GLenum, GLuint, const GLfloat *)) +AGL_API(void, ProgramLocalParameter4dARB, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, ProgramLocalParameter4dvARB, (GLenum, GLuint, const GLdouble *)) +AGL_API(void, ProgramLocalParameter4fARB, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramLocalParameter4fvARB, (GLenum, GLuint, const GLfloat *)) +AGL_API(void, GetProgramEnvParameterdvARB, (GLenum, GLuint, GLdouble *)) +AGL_API(void, GetProgramEnvParameterfvARB, (GLenum, GLuint, GLfloat *)) +AGL_API(void, GetProgramLocalParameterdvARB, (GLenum, GLuint, GLdouble *)) +AGL_API(void, GetProgramLocalParameterfvARB, (GLenum, GLuint, GLfloat *)) +AGL_API(void, GetProgramivARB, (GLenum, GLenum, GLint *)) +AGL_API(void, GetProgramStringARB, (GLenum, GLenum, GLvoid *)) +AGL_API(void, GetVertexAttribdvARB, (GLuint, GLenum, GLdouble *)) +AGL_API(void, GetVertexAttribfvARB, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribivARB, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribPointervARB, (GLuint, GLenum, GLvoid* *)) +AGL_API(GLboolean, IsProgramARB, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_buffer_object +AGL_API(void, BindBufferARB, (GLenum, GLuint)) +AGL_API(void, DeleteBuffersARB, (GLsizei, const GLuint *)) +AGL_API(void, GenBuffersARB, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsBufferARB, (GLuint)) +AGL_API(void, BufferDataARB, (GLenum, GLsizeiptrARB, const GLvoid *, GLenum)) +AGL_API(void, BufferSubDataARB, (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *)) +AGL_API(void, GetBufferSubDataARB, (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *)) +AGL_API(GLvoid*, MapBufferARB, (GLenum, GLenum)) +AGL_API(GLboolean, UnmapBufferARB, (GLenum)) +AGL_API(void, GetBufferParameterivARB, (GLenum, GLenum, GLint *)) +AGL_API(void, GetBufferPointervARB, (GLenum, GLenum, GLvoid* *)) +#endif + +#if defined _ALLEGRO_GL_ARB_occlusion_query +AGL_API(void, GenQueriesARB, (GLsizei, GLuint *)) +AGL_API(void, DeleteQueriesARB, (GLsizei, const GLuint *)) +AGL_API(GLboolean, IsQueryARB, (GLuint)) +AGL_API(void, BeginQueryARB, (GLenum, GLuint)) +AGL_API(void, EndQueryARB, (GLenum)) +AGL_API(void, GetQueryivARB, (GLenum, GLenum, GLint *)) +AGL_API(void, GetQueryObjectivARB, (GLuint, GLenum, GLint *)) +AGL_API(void, GetQueryObjectuivARB, (GLuint, GLenum, GLuint *)) +#endif + +#if defined _ALLEGRO_GL_ARB_shader_objects +AGL_API(void, DeleteObjectARB, (GLhandleARB)) +AGL_API(GLhandleARB, GetHandleARB, (GLenum)) +AGL_API(void, DetachObjectARB, (GLhandleARB, GLhandleARB)) +AGL_API(GLhandleARB, CreateShaderObjectARB, (GLenum)) +AGL_API(void, ShaderSourceARB, (GLhandleARB, GLsizei, const GLcharARB **, const GLint *)) +AGL_API(void, CompileShaderARB, (GLhandleARB)) +AGL_API(GLhandleARB, CreateProgramObjectARB, (void)) +AGL_API(void, AttachObjectARB, (GLhandleARB, GLhandleARB)) +AGL_API(void, LinkProgramARB, (GLhandleARB)) +AGL_API(void, UseProgramObjectARB, (GLhandleARB)) +AGL_API(void, ValidateProgramARB, (GLhandleARB)) +AGL_API(void, Uniform1fARB, (GLint, GLfloat)) +AGL_API(void, Uniform2fARB, (GLint, GLfloat, GLfloat)) +AGL_API(void, Uniform3fARB, (GLint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Uniform4fARB, (GLint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Uniform1iARB, (GLint, GLint)) +AGL_API(void, Uniform2iARB, (GLint, GLint, GLint)) +AGL_API(void, Uniform3iARB, (GLint, GLint, GLint, GLint)) +AGL_API(void, Uniform4iARB, (GLint, GLint, GLint, GLint, GLint)) +AGL_API(void, Uniform1fvARB, (GLint, GLsizei, GLfloat *)) +AGL_API(void, Uniform2fvARB, (GLint, GLsizei, GLfloat *)) +AGL_API(void, Uniform3fvARB, (GLint, GLsizei, GLfloat *)) +AGL_API(void, Uniform4fvARB, (GLint, GLsizei, GLfloat *)) +AGL_API(void, Uniform1ivARB, (GLint, GLsizei, GLint *)) +AGL_API(void, Uniform2ivARB, (GLint, GLsizei, GLint *)) +AGL_API(void, Uniform3ivARB, (GLint, GLsizei, GLint *)) +AGL_API(void, Uniform4ivARB, (GLint, GLsizei, GLint *)) +AGL_API(void, UniformMatrix2fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) +AGL_API(void, UniformMatrix3fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) +AGL_API(void, UniformMatrix4fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) +AGL_API(void, GetObjectParameterfvARB, (GLhandleARB, GLenum, GLfloat *)) +AGL_API(void, GetObjectParameterivARB, (GLhandleARB, GLenum, GLint *)) +AGL_API(void, GetInfoLogARB, (GLhandleARB, GLsizei, GLsizei *, GLcharARB *)) +AGL_API(void, GetAttachedObjectsARB, (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *)) +AGL_API(GLint, GetUniformLocationARB, (GLhandleARB, const GLcharARB *)) +AGL_API(void, GetActiveUniformARB, (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *)) +AGL_API(void, GetUniformfvARB, (GLhandleARB, GLint, GLfloat *)) +AGL_API(void, GetUniformivARB, (GLhandleARB, GLint, GLint *)) +AGL_API(void, GetShaderSourceARB, (GLhandleARB, GLsizei, GLsizei *, GLcharARB *)) +#endif + +#ifdef _ALLEGRO_GL_ARB_vertex_shader +#ifndef GL_ARB_vertex_program +AGL_API(void, VertexAttrib1fARB, (GLuint, GLfloat)) +AGL_API(void, VertexAttrib1sARB, (GLuint, GLshort)) +AGL_API(void, VertexAttrib1dARB, (GLuint, GLdouble)) +AGL_API(void, VertexAttrib2fARB, (GLuint, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib2sARB, (GLuint, GLshort, GLshort)) +AGL_API(void, VertexAttrib2dARB, (GLuint, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib3fARB, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib3sARB, (GLuint, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib3dARB, (GLuint, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4fARB, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib4sARB, (GLuint, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib4dARB, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4NubARB, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) +AGL_API(void, VertexAttrib1fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib1svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib1dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib2fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib2svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib2dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib3fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib3svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib3dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib4svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4ivARB, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4bvARB, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4ubvARB, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4usvARB, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4uivARB, (GLuint, const GLuint *)) +AGL_API(void, VertexAttrib4NbvARB, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4NsvARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4NivARB, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4NubvARB, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4NusvARB, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4NuivARB, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribPointerARB, (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) +AGL_API(void, EnableVertexAttribArrayARB, (GLuint)) +AGL_API(void, DisableVertexAttribArrayARB, (GLuint)) +#endif +AGL_API(void, BindAttribLocationARB, (GLhandleARB, GLuint, const GLcharARB *)) +AGL_API(void, GetActiveAttribARB, (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *)) +AGL_API(GLint, GetAttribLocationARB, (GLhandleARB, const GLcharARB *)) +#ifndef GL_ARB_vertex_program +AGL_API(void, GetVertexAttribdvARB, (GLuint, GLenum, GLdouble *)) +AGL_API(void, GetVertexAttribfvARB, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribivARB, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribPointervARB, (GLuint, GLenum, GLvoid **)) +#endif +#endif + +#if defined _ALLEGRO_GL_ARB_draw_buffers +AGL_API(void, DrawBuffersARB, (GLsizei n, const GLenum *bufs)) +#endif + +#if defined _ALLEGRO_GL_ARB_color_buffer_float +AGL_API(void, ClampColorARB, (GLenum, GLenum clamp)) +#endif + +#if defined _ALLEGRO_GL_ARB_draw_instanced +AGL_API(void, DrawArraysInstancedARB, (GLenum, GLint, GLsizei, GLsizei)) +AGL_API(void, DrawElementsInstancedARB, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_ARB_framebuffer_object +AGL_API(GLboolean, IsRenderbuffer, (GLuint)) +AGL_API(void, BindRenderbuffer, (GLenum, GLuint)) +AGL_API(void, DeleteRenderbuffers, (GLsizei, const GLuint *)) +AGL_API(void, GenRenderbuffers, (GLsizei, GLuint *)) +AGL_API(void, RenderbufferStorage, (GLenum, GLenum, GLsizei, GLsizei)) +AGL_API(void, GetRenderbufferParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(GLboolean, IsFramebuffer, (GLuint)) +AGL_API(void, BindFramebuffer, (GLenum, GLuint)) +AGL_API(void, DeleteFramebuffers, (GLsizei, const GLuint *)) +AGL_API(void, GenFramebuffers, (GLsizei, GLuint *)) +AGL_API(GLenum, CheckFramebufferStatus, (GLenum)) +AGL_API(void, FramebufferTexture1D, (GLenum, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTexture2D, (GLenum, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTexture3D, (GLenum, GLenum, GLenum, GLuint, GLint, GLint)) +AGL_API(void, FramebufferRenderbuffer, (GLenum, GLenum, GLenum, GLuint)) +AGL_API(void, GetFramebufferAttachmentParameteriv, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GenerateMipmap, (GLenum)) +AGL_API(void, BlitFramebuffer, (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) +AGL_API(void, RenderbufferStorageMultisample, (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) +AGL_API(void, FramebufferTextureLayer, (GLenum, GLenum, GLuint, GLint, GLint)) +#endif + +#if defined _ALLEGRO_GL_ARB_geometry_shader4 +AGL_API(void, ProgramParameteriARB, (GLuint, GLenum, GLint)) +AGL_API(void, FramebufferTextureARB, (GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTextureLayerARB, (GLenum, GLenum, GLuint, GLint, GLint)) +AGL_API(void, FramebufferTextureFaceARB, (GLenum, GLenum, GLuint, GLint, GLenum)) +#endif + +#if defined _ALLEGRO_GL_ARB_instanced_arrays +AGL_API(void, VertexAttribDivisor, (GLuint, GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_map_buffer_range +AGL_API(void, MapBufferRange, (GLenum, GLintptr, GLsizeiptr, GLbitfield)) +AGL_API(void, FlushMappedBufferRange, (GLenum, GLintptr, GLsizeiptr)) +#endif + +#if defined _ALLEGRO_GL_ARB_texture_buffer_object +AGL_API(void, TexBufferARB, (GLenum, GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_array_object +AGL_API(void, BindVertexArray, (GLuint)) +AGL_API(void, DeleteVertexArrays, (GLsizei, const GLuint *)) +AGL_API(void, GenVertexArrays, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsVertexArray, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_uniform_buffer_object +AGL_API(void, GetUniformIndices, (GLuint, GLsizei, const GLchar* *, GLuint *)) +AGL_API(void, GetActiveUniformsiv, (GLuint, GLsizei, const GLuint *, GLenum, GLint *)) +AGL_API(void, GetActiveUniformName, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(GLuint, GetUniformBlockIndex, (GLuint, const GLchar *)) +AGL_API(void, GetActiveUniformBlockiv, (GLuint, GLuint, GLenum, GLint *)) +AGL_API(void, GetActiveUniformBlockName, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, UniformBlockBinding, (GLuint, GLuint, GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_copy_buffer +AGL_API(void, CopyBufferSubData, (GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr)) +#endif + + +#if defined _ALLEGRO_GL_ARB_draw_elements_base_vertex +AGL_API(void, DrawElementsBaseVertex, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)) +AGL_API(void, DrawRangeElementsBaseVertex, (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)) +AGL_API(void, DrawElementsInstancedBaseVertex, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex)) +AGL_API(void, MultiDrawElementsBaseVertex, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex)) +#endif + +#if defined _ALLEGRO_GL_ARB_provoking_vertex +AGL_API(void, ProvokingVertex, (GLenum mode)) +#endif + +#if defined _ALLEGRO_GL_ARB_sync +AGL_API(GLsync, FenceSync, (GLenum condition, GLbitfield flags)) +AGL_API(GLboolean, IsSync, (GLsync sync)) +AGL_API(void, DeleteSync, (GLsync sync)) +AGL_API(GLenum, ClientWaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) +AGL_API(void, WaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) +AGL_API(void, GetInteger64v, (GLenum pname, GLint64 *params)) +AGL_API(void, GetSynciv, (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)) +#endif + +#if defined _ALLEGRO_GL_ARB_texture_multisample +AGL_API(void, TexImage2DMultisample, (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) +AGL_API(void, TexImage3DMultisample, (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)) +AGL_API(void, GetMultisamplefv, (GLenum pname, GLuint index, GLfloat *val)) +AGL_API(void, SampleMaski, (GLuint index, GLbitfield mask)) +#endif + +#if defined _ALLEGRO_GL_ARB_draw_buffers_blend +AGL_API(void, BlendEquationi, (GLuint buf, GLenum mode)) +AGL_API(void, BlendEquationSeparatei, (GLuint buf, GLenum modeRGB, GLenum modeAlpha)) +AGL_API(void, BlendFunci, (GLuint buf, GLenum src, GLenum dst)) +AGL_API(void, BlendFuncSeparatei, (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)) +#endif + +#if defined _ALLEGRO_GL_ARB_sample_shading +AGL_API(void, MinSampleShading, (GLclampf value)) +#endif + +#if defined _ALLEGRO_GL_ARB_shading_language_include +AGL_API(void, NamedStringARB, (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string)) +AGL_API(void, DeleteNamedStringARB, (GLint namelen, const GLchar *name)) +AGL_API(void, CompileShaderIncludeARB, (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length)) +AGL_API(GLboolean, IsNamedStringARB, (GLint namelen, const GLchar *name)) +AGL_API(void, GetNamedStringARB, (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string)) +AGL_API(void, GetNamedStringivARB, (GLint namelen, const GLchar *name, GLenum pname, GLint *params)) +#endif + +#if defined _ALLEGRO_GL_ARB_blend_func_extended +AGL_API(void, BindFragDataLocationIndexed, (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name)) +AGL_API(GLint, GetFragDataIndex, (GLuint program, const GLchar *name)) +#endif + +#if defined _ALLEGRO_GL_ARB_sampler_objects +AGL_API(void, GenSamplers, (GLsizei count, GLuint *samplers)) +AGL_API(void, DeleteSamplers, (GLsizei count, const GLuint *samplers)) +AGL_API(GLboolean, IsSampler, (GLuint sampler)) +AGL_API(void, BindSampler, (GLenum unit, GLuint sampler)) +AGL_API(void, SamplerParameteri, (GLuint sampler, GLenum pname, GLint param)) +AGL_API(void, SamplerParameteriv, (GLuint sampler, GLenum pname, const GLint *param)) +AGL_API(void, SamplerParameterf, (GLuint sampler, GLenum pname, GLfloat param)) +AGL_API(void, SamplerParameterfv, (GLuint sampler, GLenum pname, const GLfloat *param)) +AGL_API(void, SamplerParameterIiv, (GLuint sampler, GLenum pname, const GLint *param)) +AGL_API(void, SamplerParameterIuiv, (GLuint sampler, GLenum pname, const GLuint *param)) +AGL_API(void, GetSamplerParameteriv, (GLuint sampler, GLenum pname, GLint *params)) +AGL_API(void, GetSamplerParameterIiv, (GLuint sampler, GLenum pname, GLint *params)) +AGL_API(void, GetSamplerParameterfv, (GLuint sampler, GLenum pname, GLfloat *params)) +AGL_API(void, GetSamplerParameterIfv, (GLuint sampler, GLenum pname, GLfloat *params)) +#endif + +#if defined _ALLEGRO_GL_ARB_timer_query +AGL_API(void, QueryCounter, (GLuint id, GLenum target)) +AGL_API(void, GetQueryObjecti64v, (GLuint id, GLenum pname, GLint64 *params)) +AGL_API(void, GetQueryObjectui64v, (GLuint id, GLenum pname, GLuint64 *params)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev +AGL_API(void, VertexP2ui, (GLenum type, GLuint value)) +AGL_API(void, VertexP2uiv, (GLenum type, const GLuint *value)) +AGL_API(void, VertexP3ui, (GLenum type, GLuint value)) +AGL_API(void, VertexP3uiv, (GLenum type, const GLuint *value)) +AGL_API(void, VertexP4ui, (GLenum type, GLuint value)) +AGL_API(void, VertexP4uiv, (GLenum type, const GLuint *value)) +AGL_API(void, TexCoordP1ui, (GLenum type, GLuint coords)) +AGL_API(void, TexCoordP1uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, TexCoordP2ui, (GLenum type, GLuint coords)) +AGL_API(void, TexCoordP2uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, TexCoordP3ui, (GLenum type, GLuint coords)) +AGL_API(void, TexCoordP3uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, TexCoordP4ui, (GLenum type, GLuint coords)) +AGL_API(void, TexCoordP4uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, MultiTexCoordP1ui, (GLenum texture, GLenum type, GLuint coords)) +AGL_API(void, MultiTexCoordP1uiv, (GLenum texture, GLenum type, const GLuint *coords)) +AGL_API(void, MultiTexCoordP2ui, (GLenum texture, GLenum type, GLuint coords)) +AGL_API(void, MultiTexCoordP2uiv, (GLenum texture, GLenum type, const GLuint *coords)) +AGL_API(void, MultiTexCoordP3ui, (GLenum texture, GLenum type, GLuint coords)) +AGL_API(void, MultiTexCoordP3uiv, (GLenum texture, GLenum type, const GLuint *coords)) +AGL_API(void, MultiTexCoordP4ui, (GLenum texture, GLenum type, GLuint coords)) +AGL_API(void, MultiTexCoordP4uiv, (GLenum texture, GLenum type, const GLuint *coords)) +AGL_API(void, NormalP3ui, (GLenum type, GLuint coords)) +AGL_API(void, NormalP3uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, ColorP3ui, (GLenum type, GLuint color)) +AGL_API(void, ColorP3uiv, (GLenum type, const GLuint *color)) +AGL_API(void, ColorP4ui, (GLenum type, GLuint color)) +AGL_API(void, ColorP4uiv, (GLenum type, const GLuint *color)) +AGL_API(void, SecondaryColorP3ui, (GLenum type, GLuint color)) +AGL_API(void, SecondaryColorP3uiv, (GLenum type, const GLuint *color)) +AGL_API(void, VertexAttribP1ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) +AGL_API(void, VertexAttribP1uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) +AGL_API(void, VertexAttribP2ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) +AGL_API(void, VertexAttribP2uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) +AGL_API(void, VertexAttribP3ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) +AGL_API(void, VertexAttribP3uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) +AGL_API(void, VertexAttribP4ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) +AGL_API(void, VertexAttribP4uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) +#endif + +#if defined _ALLEGRO_GL_ARB_draw_indirect +AGL_API(void, DrawArraysIndirect, (GLenum mode, const GLvoid *indirect)) +AGL_API(void, DrawElementsIndirect, (GLenum mode, GLenum type, const GLvoid *indirect)) +#endif + +#if defined _ALLEGRO_GL_ARB_gpu_shader_fp64 +AGL_API(void, Uniform1d, (GLint location, GLdouble x)) +AGL_API(void, Uniform2d, (GLint location, GLdouble x, GLdouble y)) +AGL_API(void, Uniform3d, (GLint location, GLdouble x, GLdouble y, GLdouble z)) +AGL_API(void, Uniform4d, (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +AGL_API(void, Uniform1dv, (GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, Uniform2dv, (GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, Uniform3dv, (GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, Uniform4dv, (GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, UniformMatrix2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix2x3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix2x4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix3x2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix3x4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix4x2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix4x3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, GetUniformdv, (GLuint program, GLint location, GLdouble *params)) +AGL_API(void, ProgramUniform1dEXT, (GLuint program, GLint location, GLdouble x)) +AGL_API(void, ProgramUniform2dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y)) +AGL_API(void, ProgramUniform3dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z)) +AGL_API(void, ProgramUniform4dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +AGL_API(void, ProgramUniform1dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, ProgramUniform2dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, ProgramUniform3dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, ProgramUniform4dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix2x3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix2x4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix3x2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix3x4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix4x2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix4x3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +#endif + +#if defined _ALLEGRO_GL_ARB_shader_subroutine +AGL_API(GLint, GetSubroutineUniformLocation, (GLuint program, GLenum shadertype, const GLchar *name)) +AGL_API(GLuint, GetSubroutineIndex, (GLuint program, GLenum shadertype, const GLchar *name)) +AGL_API(void, GetActiveSubroutineUniformiv, (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values)) +AGL_API(void, GetActiveSubroutineUniformName, (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)) +AGL_API(void, GetActiveSubroutineName, (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)) +AGL_API(void, UniformSubroutinesuiv, (GLenum shadertype, GLsizei count, const GLuint *indices)) +AGL_API(void, GetUniformSubroutineuiv, (GLenum shadertype, GLint location, GLuint *params)) +AGL_API(void, GetProgramStageiv, (GLuint program, GLenum shadertype, GLenum pname, GLint *values)) +#endif + +#if defined _ALLEGRO_GL_ARB_tessellation_shader +AGL_API(void, PatchParameteri, (GLenum pname, GLint value)) +AGL_API(void, PatchParameterfv, (GLenum pname, const GLfloat *values)) +#endif + +#if defined _ALLEGRO_GL_ARB_transform_feedback2 +AGL_API(void, BindTransformFeedback, (GLenum target, GLuint id)) +AGL_API(void, DeleteTransformFeedbacks, (GLsizei n, const GLuint *ids)) +AGL_API(void, GenTransformFeedbacks, (GLsizei n, GLuint *ids)) +AGL_API(GLboolean, IsTransformFeedback, (GLuint id)) +AGL_API(void, PauseTransformFeedback, (void)) +AGL_API(void, ResumeTransformFeedback, (void)) +AGL_API(void, DrawTransformFeedback, (GLenum mode, GLuint id)) +#endif + +#if defined _ALLEGRO_GL_ARB_transform_feedback3 +AGL_API(void, DrawTransformFeedbackStream, (GLenum mode, GLuint id, GLuint stream)) +AGL_API(void, BeginQueryIndexed, (GLenum target, GLuint index, GLuint id)) +AGL_API(void, EndQueryIndexed, (GLenum target, GLuint index)) +AGL_API(void, GetQueryIndexediv, (GLenum target, GLuint index, GLenum pname, GLint *params)) +#endif + + +/* */ + + +#if defined _ALLEGRO_GL_EXT_blend_color +AGL_API(void, BlendColorEXT, (GLclampf, GLclampf, GLclampf, GLclampf)) +#endif + +#if defined _ALLEGRO_GL_EXT_polygon_offset +AGL_API(void, PolygonOffsetEXT, (GLfloat, GLfloat)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture3D +AGL_API(void, TexImage3DEXT, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TexSubImage3DEXT, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_texture_filter4 +AGL_API(void, GetTexFilterFuncSGIS, (GLenum, GLenum, GLfloat *)) +AGL_API(void, TexFilterFuncSGIS, (GLenum, GLenum, GLsizei, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_EXT_subtexture +AGL_API(void, TexSubImage1DEXT, (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TexSubImage2DEXT, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_copy_texture +AGL_API(void, CopyTexImage1DEXT, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) +AGL_API(void, CopyTexImage2DEXT, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) +AGL_API(void, CopyTexSubImage1DEXT, (GLenum, GLint, GLint, GLint, GLint, GLsizei)) +AGL_API(void, CopyTexSubImage2DEXT, (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, CopyTexSubImage3DEXT, (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_EXT_histogram +AGL_API(void, GetHistogramEXT, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetHistogramParameterfvEXT, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetHistogramParameterivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, GetMinmaxEXT, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetMinmaxParameterfvEXT, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMinmaxParameterivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, HistogramEXT, (GLenum, GLsizei, GLenum, GLboolean)) +AGL_API(void, MinmaxEXT, (GLenum, GLenum, GLboolean)) +AGL_API(void, ResetHistogramEXT, (GLenum)) +AGL_API(void, ResetMinmaxEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_convolution +AGL_API(void, ConvolutionFilter1DEXT, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ConvolutionFilter2DEXT, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ConvolutionParameterfEXT, (GLenum, GLenum, GLfloat)) +AGL_API(void, ConvolutionParameterfvEXT, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, ConvolutionParameteriEXT, (GLenum, GLenum, GLint)) +AGL_API(void, ConvolutionParameterivEXT, (GLenum, GLenum, const GLint *)) +AGL_API(void, CopyConvolutionFilter1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei)) +AGL_API(void, CopyConvolutionFilter2DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, GetConvolutionFilterEXT, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetConvolutionParameterfvEXT, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetConvolutionParameterivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, GetSeparableFilterEXT, (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *)) +AGL_API(void, SeparableFilter2DEXT, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_SGI_color_table +AGL_API(void, ColorTableSGI, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ColorTableParameterfvSGI, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, ColorTableParameterivSGI, (GLenum, GLenum, const GLint *)) +AGL_API(void, CopyColorTableSGI, (GLenum, GLenum, GLint, GLint, GLsizei)) +AGL_API(void, GetColorTableSGI, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetColorTableParameterfvSGI, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetColorTableParameterivSGI, (GLenum, GLenum, GLint *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_pixel_texture +AGL_API(void, PixelTexGenSGIX, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_SGIS_pixel_texture +AGL_API(void, PixelTexGenParameteriSGIS, (GLenum, GLint)) +AGL_API(void, PixelTexGenParameterivSGIS, (GLenum, const GLint *)) +AGL_API(void, PixelTexGenParameterfSGIS, (GLenum, GLfloat)) +AGL_API(void, PixelTexGenParameterfvSGIS, (GLenum, const GLfloat *)) +AGL_API(void, GetPixelTexGenParameterivSGIS, (GLenum, GLint *)) +AGL_API(void, GetPixelTexGenParameterfvSGIS, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_texture4D +AGL_API(void, TexImage4DSGIS, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TexSubImage4DSGIS, (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture_object +AGL_API(GLboolean, AreTexturesResidentEXT, (GLsizei, const GLuint *, GLboolean *)) +AGL_API(void, BindTextureEXT, (GLenum, GLuint)) +AGL_API(void, DeleteTexturesEXT, (GLsizei, const GLuint *)) +AGL_API(void, GenTexturesEXT, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsTextureEXT, (GLuint)) +AGL_API(void, PrioritizeTexturesEXT, (GLsizei, const GLuint *, const GLclampf *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_detail_texture +AGL_API(void, DetailTexFuncSGIS, (GLenum, GLsizei, const GLfloat *)) +AGL_API(void, GetDetailTexFuncSGIS, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_sharpen_texture +AGL_API(void, SharpenTexFuncSGIS, (GLenum, GLsizei, const GLfloat *)) +AGL_API(void, GetSharpenTexFuncSGIS, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_multisample +AGL_API(void, SampleMaskSGIS, (GLclampf, GLboolean)) +AGL_API(void, SamplePatternSGIS, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_array +AGL_API(void, ArrayElementEXT, (GLint)) +AGL_API(void, ColorPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) +AGL_API(void, DrawArraysEXT, (GLenum, GLint, GLsizei)) +AGL_API(void, EdgeFlagPointerEXT, (GLsizei, GLsizei, const GLboolean *)) +AGL_API(void, GetPointervEXT, (GLenum, GLvoid* *)) +AGL_API(void, IndexPointerEXT, (GLenum, GLsizei, GLsizei, const GLvoid *)) +AGL_API(void, NormalPointerEXT, (GLenum, GLsizei, GLsizei, const GLvoid *)) +AGL_API(void, TexCoordPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) +AGL_API(void, VertexPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_blend_minmax +AGL_API(void, BlendEquationEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_SGIX_sprite +AGL_API(void, SpriteParameterfSGIX, (GLenum, GLfloat)) +AGL_API(void, SpriteParameterfvSGIX, (GLenum, const GLfloat *)) +AGL_API(void, SpriteParameteriSGIX, (GLenum, GLint)) +AGL_API(void, SpriteParameterivSGIX, (GLenum, const GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_point_parameters +AGL_API(void, PointParameterfEXT, (GLenum, GLfloat)) +AGL_API(void, PointParameterfvEXT, (GLenum, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_point_parameters +AGL_API(void, PointParameterfSGIS, (GLenum, GLfloat)) +AGL_API(void, PointParameterfvSGIS, (GLenum, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_instruments +AGL_API(GLint, GetInstrumentsSGIX, (void)) +AGL_API(void, InstrumentsBufferSGIX, (GLsizei, GLint *)) +AGL_API(GLint, PollInstrumentsSGIX, (GLint *)) +AGL_API(void, ReadInstrumentsSGIX, (GLint)) +AGL_API(void, StartInstrumentsSGIX, (void)) +AGL_API(void, StopInstrumentsSGIX, (GLint)) +#endif + +#if defined _ALLEGRO_GL_SGIX_framezoom +AGL_API(void, FrameZoomSGIX, (GLint)) +#endif + +#if defined _ALLEGRO_GL_SGIX_tag_sample_buffer +AGL_API(void, TagSampleBufferSGIX, (void)) +#endif + +#if defined _ALLEGRO_GL_SGIX_polynomial_ffd +AGL_API(void, DeformationMap3dSGIX, (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *)) +AGL_API(void, DeformationMap3fSGIX, (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *)) +AGL_API(void, DeformSGIX, (GLbitfield)) +AGL_API(void, LoadIdentityDeformationMapSGIX, (GLbitfield)) +#endif + +#if defined _ALLEGRO_GL_SGIX_reference_plane +AGL_API(void, ReferencePlaneSGIX, (const GLdouble *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_flush_raster +AGL_API(void, FlushRasterSGIX, (void)) +#endif + +#if defined _ALLEGRO_GL_SGIS_fog_function +AGL_API(void, FogFuncSGIS, (GLsizei, const GLfloat *)) +AGL_API(void, GetFogFuncSGIS, (GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_HP_image_transform +AGL_API(void, ImageTransformParameteriHP, (GLenum, GLenum, GLint)) +AGL_API(void, ImageTransformParameterfHP, (GLenum, GLenum, GLfloat)) +AGL_API(void, ImageTransformParameterivHP, (GLenum, GLenum, const GLint *)) +AGL_API(void, ImageTransformParameterfvHP, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, GetImageTransformParameterivHP, (GLenum, GLenum, GLint *)) +AGL_API(void, GetImageTransformParameterfvHP, (GLenum, GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_EXT_color_subtable +#ifndef GL_EXT_paletted_texture +AGL_API(void, ColorSubTableEXT, (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +#endif +AGL_API(void, CopyColorSubTableEXT, (GLenum, GLsizei, GLint, GLint, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_PGI_misc_hints +AGL_API(void, HintPGI, (GLenum, GLint)) +#endif + +#if defined _ALLEGRO_GL_EXT_paletted_texture +AGL_API(void, ColorTableEXT, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, GetColorTableEXT, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetColorTableParameterivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, GetColorTableParameterfvEXT, (GLenum, GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_list_priority +AGL_API(void, GetListParameterfvSGIX, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetListParameterivSGIX, (GLuint, GLenum, GLint *)) +AGL_API(void, ListParameterfSGIX, (GLuint, GLenum, GLfloat)) +AGL_API(void, ListParameterfvSGIX, (GLuint, GLenum, const GLfloat *)) +AGL_API(void, ListParameteriSGIX, (GLuint, GLenum, GLint)) +AGL_API(void, ListParameterivSGIX, (GLuint, GLenum, const GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_index_material +AGL_API(void, IndexMaterialEXT, (GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_index_func +AGL_API(void, IndexFuncEXT, (GLenum, GLclampf)) +#endif + +#if defined _ALLEGRO_GL_EXT_compiled_vertex_array +AGL_API(void, LockArraysEXT, (GLint, GLsizei)) +AGL_API(void, UnlockArraysEXT, (void)) +#endif + +#if defined _ALLEGRO_GL_EXT_cull_vertex +AGL_API(void, CullParameterdvEXT, (GLenum, GLdouble *)) +AGL_API(void, CullParameterfvEXT, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_fragment_lighting +AGL_API(void, FragmentColorMaterialSGIX, (GLenum, GLenum)) +AGL_API(void, FragmentLightfSGIX, (GLenum, GLenum, GLfloat)) +AGL_API(void, FragmentLightfvSGIX, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, FragmentLightiSGIX, (GLenum, GLenum, GLint)) +AGL_API(void, FragmentLightivSGIX, (GLenum, GLenum, const GLint *)) +AGL_API(void, FragmentLightModelfSGIX, (GLenum, GLfloat)) +AGL_API(void, FragmentLightModelfvSGIX, (GLenum, const GLfloat *)) +AGL_API(void, FragmentLightModeliSGIX, (GLenum, GLint)) +AGL_API(void, FragmentLightModelivSGIX, (GLenum, const GLint *)) +AGL_API(void, FragmentMaterialfSGIX, (GLenum, GLenum, GLfloat)) +AGL_API(void, FragmentMaterialfvSGIX, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, FragmentMaterialiSGIX, (GLenum, GLenum, GLint)) +AGL_API(void, FragmentMaterialivSGIX, (GLenum, GLenum, const GLint *)) +AGL_API(void, GetFragmentLightfvSGIX, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetFragmentLightivSGIX, (GLenum, GLenum, GLint *)) +AGL_API(void, GetFragmentMaterialfvSGIX, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetFragmentMaterialivSGIX, (GLenum, GLenum, GLint *)) +AGL_API(void, LightEnviSGIX, (GLenum, GLint)) +#endif + +#if defined _ALLEGRO_GL_EXT_draw_range_elements +AGL_API(void, DrawRangeElementsEXT, (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_light_texture +AGL_API(void, ApplyTextureEXT, (GLenum)) +AGL_API(void, TextureLightEXT, (GLenum)) +AGL_API(void, TextureMaterialEXT, (GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_SGIX_async +AGL_API(void, AsyncMarkerSGIX, (GLuint)) +AGL_API(GLint, FinishAsyncSGIX, (GLuint *)) +AGL_API(GLint, PollAsyncSGIX, (GLuint *)) +AGL_API(GLuint, GenAsyncMarkersSGIX, (GLsizei)) +AGL_API(void, DeleteAsyncMarkersSGIX, (GLuint, GLsizei)) +AGL_API(GLboolean, IsAsyncMarkerSGIX, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_INTEL_parallel_arrays +AGL_API(void, VertexPointervINTEL, (GLint, GLenum, const GLvoid* *)) +AGL_API(void, NormalPointervINTEL, (GLenum, const GLvoid* *)) +AGL_API(void, ColorPointervINTEL, (GLint, GLenum, const GLvoid* *)) +AGL_API(void, TexCoordPointervINTEL, (GLint, GLenum, const GLvoid* *)) +#endif + +#if defined _ALLEGRO_GL_EXT_pixel_transform +AGL_API(void, PixelTransformParameteriEXT, (GLenum, GLenum, GLint)) +AGL_API(void, PixelTransformParameterfEXT, (GLenum, GLenum, GLfloat)) +AGL_API(void, PixelTransformParameterivEXT, (GLenum, GLenum, const GLint *)) +AGL_API(void, PixelTransformParameterfvEXT, (GLenum, GLenum, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_EXT_secondary_color +AGL_API(void, SecondaryColor3bEXT, (GLbyte, GLbyte, GLbyte)) +AGL_API(void, SecondaryColor3bvEXT, (const GLbyte *)) +AGL_API(void, SecondaryColor3dEXT, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, SecondaryColor3dvEXT, (const GLdouble *)) +AGL_API(void, SecondaryColor3fEXT, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, SecondaryColor3fvEXT, (const GLfloat *)) +AGL_API(void, SecondaryColor3iEXT, (GLint, GLint, GLint)) +AGL_API(void, SecondaryColor3ivEXT, (const GLint *)) +AGL_API(void, SecondaryColor3sEXT, (GLshort, GLshort, GLshort)) +AGL_API(void, SecondaryColor3svEXT, (const GLshort *)) +AGL_API(void, SecondaryColor3ubEXT, (GLubyte, GLubyte, GLubyte)) +AGL_API(void, SecondaryColor3ubvEXT, (const GLubyte *)) +AGL_API(void, SecondaryColor3uiEXT, (GLuint, GLuint, GLuint)) +AGL_API(void, SecondaryColor3uivEXT, (const GLuint *)) +AGL_API(void, SecondaryColor3usEXT, (GLushort, GLushort, GLushort)) +AGL_API(void, SecondaryColor3usvEXT, (const GLushort *)) +AGL_API(void, SecondaryColorPointerEXT, (GLint, GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture_perturb_normal +AGL_API(void, TextureNormalEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_multi_draw_arrays +AGL_API(void, MultiDrawArraysEXT, (GLenum, GLint *, GLsizei *, GLsizei)) +AGL_API(void, MultiDrawElementsEXT, (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_EXT_fog_coord +AGL_API(void, FogCoordfEXT, (GLfloat)) +AGL_API(void, FogCoordfvEXT, (const GLfloat *)) +AGL_API(void, FogCoorddEXT, (GLdouble)) +AGL_API(void, FogCoorddvEXT, (const GLdouble *)) +AGL_API(void, FogCoordPointerEXT, (GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_coordinate_frame +AGL_API(void, Tangent3bEXT, (GLbyte, GLbyte, GLbyte)) +AGL_API(void, Tangent3bvEXT, (const GLbyte *)) +AGL_API(void, Tangent3dEXT, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, Tangent3dvEXT, (const GLdouble *)) +AGL_API(void, Tangent3fEXT, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, Tangent3fvEXT, (const GLfloat *)) +AGL_API(void, Tangent3iEXT, (GLint, GLint, GLint)) +AGL_API(void, Tangent3ivEXT, (const GLint *)) +AGL_API(void, Tangent3sEXT, (GLshort, GLshort, GLshort)) +AGL_API(void, Tangent3svEXT, (const GLshort *)) +AGL_API(void, Binormal3bEXT, (GLbyte, GLbyte, GLbyte)) +AGL_API(void, Binormal3bvEXT, (const GLbyte *)) +AGL_API(void, Binormal3dEXT, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, Binormal3dvEXT, (const GLdouble *)) +AGL_API(void, Binormal3fEXT, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, Binormal3fvEXT, (const GLfloat *)) +AGL_API(void, Binormal3iEXT, (GLint, GLint, GLint)) +AGL_API(void, Binormal3ivEXT, (const GLint *)) +AGL_API(void, Binormal3sEXT, (GLshort, GLshort, GLshort)) +AGL_API(void, Binormal3svEXT, (const GLshort *)) +AGL_API(void, TangentPointerEXT, (GLenum, GLsizei, const GLvoid *)) +AGL_API(void, BinormalPointerEXT, (GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_SUNX_constant_data +AGL_API(void, FinishTextureSUNX, (void)) +#endif + +#if defined _ALLEGRO_GL_SUN_global_alpha +AGL_API(void, GlobalAlphaFactorbSUN, (GLbyte)) +AGL_API(void, GlobalAlphaFactorsSUN, (GLshort)) +AGL_API(void, GlobalAlphaFactoriSUN, (GLint)) +AGL_API(void, GlobalAlphaFactorfSUN, (GLfloat)) +AGL_API(void, GlobalAlphaFactordSUN, (GLdouble)) +AGL_API(void, GlobalAlphaFactorubSUN, (GLubyte)) +AGL_API(void, GlobalAlphaFactorusSUN, (GLushort)) +AGL_API(void, GlobalAlphaFactoruiSUN, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_SUN_triangle_list +AGL_API(void, ReplacementCodeuiSUN, (GLuint)) +AGL_API(void, ReplacementCodeusSUN, (GLushort)) +AGL_API(void, ReplacementCodeubSUN, (GLubyte)) +AGL_API(void, ReplacementCodeuivSUN, (const GLuint *)) +AGL_API(void, ReplacementCodeusvSUN, (const GLushort *)) +AGL_API(void, ReplacementCodeubvSUN, (const GLubyte *)) +AGL_API(void, ReplacementCodePointerSUN, (GLenum, GLsizei, const GLvoid* *)) +#endif + +#if defined _ALLEGRO_GL_SUN_vertex +AGL_API(void, Color4ubVertex2fSUN, (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat)) +AGL_API(void, Color4ubVertex2fvSUN, (const GLubyte *, const GLfloat *)) +AGL_API(void, Color4ubVertex3fSUN, (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Color4ubVertex3fvSUN, (const GLubyte *, const GLfloat *)) +AGL_API(void, Color3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Color3fVertex3fvSUN, (const GLfloat *, const GLfloat *)) +AGL_API(void, Normal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Normal3fVertex3fvSUN, (const GLfloat *, const GLfloat *)) +AGL_API(void, Color4fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Color4fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord2fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fVertex3fvSUN, (const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord4fVertex4fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord4fVertex4fvSUN, (const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord2fColor4ubVertex3fSUN, (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fColor4ubVertex3fvSUN, (const GLfloat *, const GLubyte *, const GLfloat *)) +AGL_API(void, TexCoord2fColor3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fColor3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord2fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord2fColor4fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fColor4fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord4fColor4fNormal3fVertex4fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord4fColor4fNormal3fVertex4fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiVertex3fvSUN, (const GLuint *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiColor4ubVertex3fSUN, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiColor4ubVertex3fvSUN, (const GLuint *, const GLubyte *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiColor3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiColor3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiColor4fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiColor4fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiTexCoord2fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiTexCoord2fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_EXT_blend_func_separate +AGL_API(void, BlendFuncSeparateEXT, (GLenum, GLenum, GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_INGR_blend_func_separate +AGL_API(void, BlendFuncSeparateINGR, (GLenum, GLenum, GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_weighting +AGL_API(void, VertexWeightfEXT, (GLfloat)) +AGL_API(void, VertexWeightfvEXT, (const GLfloat *)) +AGL_API(void, VertexWeightPointerEXT, (GLsizei, GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_NV_vertex_array_range +AGL_API(void, FlushVertexArrayRangeNV, (void)) +AGL_API(void, VertexArrayRangeNV, (GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_NV_register_combiners +AGL_API(void, CombinerParameterfvNV, (GLenum, const GLfloat *)) +AGL_API(void, CombinerParameterfNV, (GLenum, GLfloat)) +AGL_API(void, CombinerParameterivNV, (GLenum, const GLint *)) +AGL_API(void, CombinerParameteriNV, (GLenum, GLint)) +AGL_API(void, CombinerInputNV, (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, CombinerOutputNV, (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean)) +AGL_API(void, FinalCombinerInputNV, (GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, GetCombinerInputParameterfvNV, (GLenum, GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetCombinerInputParameterivNV, (GLenum, GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetCombinerOutputParameterfvNV, (GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetCombinerOutputParameterivNV, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetFinalCombinerInputParameterfvNV, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetFinalCombinerInputParameterivNV, (GLenum, GLenum, GLint *)) +#endif + +#if defined _ALLEGRO_GL_MESA_resize_buffers +AGL_API(void, ResizeBuffersMESA, (void)) +#endif + +#if defined _ALLEGRO_GL_MESA_window_pos +AGL_API(void, WindowPos2dMESA, (GLdouble, GLdouble)) +AGL_API(void, WindowPos2dvMESA, (const GLdouble *)) +AGL_API(void, WindowPos2fMESA, (GLfloat, GLfloat)) +AGL_API(void, WindowPos2fvMESA, (const GLfloat *)) +AGL_API(void, WindowPos2iMESA, (GLint, GLint)) +AGL_API(void, WindowPos2ivMESA, (const GLint *)) +AGL_API(void, WindowPos2sMESA, (GLshort, GLshort)) +AGL_API(void, WindowPos2svMESA, (const GLshort *)) +AGL_API(void, WindowPos3dMESA, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, WindowPos3dvMESA, (const GLdouble *)) +AGL_API(void, WindowPos3fMESA, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, WindowPos3fvMESA, (const GLfloat *)) +AGL_API(void, WindowPos3iMESA, (GLint, GLint, GLint)) +AGL_API(void, WindowPos3ivMESA, (const GLint *)) +AGL_API(void, WindowPos3sMESA, (GLshort, GLshort, GLshort)) +AGL_API(void, WindowPos3svMESA, (const GLshort *)) +AGL_API(void, WindowPos4dMESA, (GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, WindowPos4dvMESA, (const GLdouble *)) +AGL_API(void, WindowPos4fMESA, (GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, WindowPos4fvMESA, (const GLfloat *)) +AGL_API(void, WindowPos4iMESA, (GLint, GLint, GLint, GLint)) +AGL_API(void, WindowPos4ivMESA, (const GLint *)) +AGL_API(void, WindowPos4sMESA, (GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, WindowPos4svMESA, (const GLshort *)) +#endif + +#if defined _ALLEGRO_GL_IBM_multimode_draw_arrays +AGL_API(void, MultiModeDrawArraysIBM, (GLenum, const GLint *, const GLsizei *, GLsizei, GLint)) +AGL_API(void, MultiModeDrawElementsIBM, (const GLenum *, const GLsizei *, GLenum, const GLvoid* *, GLsizei, GLint)) +#endif + +#ifdef AGK_IBM_vertex_array_lists +AGL_API(void, ColorPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, SecondaryColorPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, EdgeFlagPointerListIBM, (GLint, const GLboolean* *, GLint)) +AGL_API(void, FogCoordPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, IndexPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, NormalPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, TexCoordPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, VertexPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) +#endif + +#if defined _ALLEGRO_GL_3DFX_tbuffer +AGL_API(void, TbufferMask3DFX, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_EXT_multisample +AGL_API(void, SampleMaskEXT, (GLclampf, GLboolean)) +AGL_API(void, SamplePatternEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_SGIS_texture_color_mask +AGL_API(void, TextureColorMaskSGIS, (GLboolean, GLboolean, GLboolean, GLboolean)) +#endif + +#if defined _ALLEGRO_GL_SGIX_igloo_interface +AGL_API(void, IglooInterfaceSGIX, (GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_NV_fence +AGL_API(void, DeleteFencesNV, (GLsizei, const GLuint *)) +AGL_API(void, GenFencesNV, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsFenceNV, (GLuint)) +AGL_API(GLboolean, TestFenceNV, (GLuint)) +AGL_API(void, GetFenceivNV, (GLuint, GLenum, GLint *)) +AGL_API(void, FinishFenceNV, (GLuint)) +AGL_API(void, SetFenceNV, (GLuint, GLenum)) +#endif + +#if defined _ALLEGRO_GL_NV_evaluators +AGL_API(void, MapControlPointsNV, (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *)) +AGL_API(void, MapParameterivNV, (GLenum, GLenum, const GLint *)) +AGL_API(void, MapParameterfvNV, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, GetMapControlPointsNV, (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *)) +AGL_API(void, GetMapParameterivNV, (GLenum, GLenum, GLint *)) +AGL_API(void, GetMapParameterfvNV, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMapAttribParameterivNV, (GLenum, GLuint, GLenum, GLint *)) +AGL_API(void, GetMapAttribParameterfvNV, (GLenum, GLuint, GLenum, GLfloat *)) +AGL_API(void, EvalMapsNV, (GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_NV_register_combiners2 +AGL_API(void, CombinerStageParameterfvNV, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, GetCombinerStageParameterfvNV, (GLenum, GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_NV_vertex_program +AGL_API(GLboolean, AreProgramsResidentNV, (GLsizei, const GLuint *, GLboolean *)) +AGL_API(void, BindProgramNV, (GLenum, GLuint)) +AGL_API(void, DeleteProgramsNV, (GLsizei, const GLuint *)) +AGL_API(void, ExecuteProgramNV, (GLenum, GLuint, const GLfloat *)) +AGL_API(void, GenProgramsNV, (GLsizei, GLuint *)) +AGL_API(void, GetProgramParameterdvNV, (GLenum, GLuint, GLenum, GLdouble *)) +AGL_API(void, GetProgramParameterfvNV, (GLenum, GLuint, GLenum, GLfloat *)) +AGL_API(void, GetProgramivNV, (GLuint, GLenum, GLint *)) +AGL_API(void, GetProgramStringNV, (GLuint, GLenum, GLubyte *)) +AGL_API(void, GetTrackMatrixivNV, (GLenum, GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribdvNV, (GLuint, GLenum, GLdouble *)) +AGL_API(void, GetVertexAttribfvNV, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribivNV, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribPointervNV, (GLuint, GLenum, GLvoid* *)) +AGL_API(GLboolean, IsProgramNV, (GLuint)) +AGL_API(void, LoadProgramNV, (GLenum, GLuint, GLsizei, const GLubyte *)) +AGL_API(void, ProgramParameter4dNV, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, ProgramParameter4dvNV, (GLenum, GLuint, const GLdouble *)) +AGL_API(void, ProgramParameter4fNV, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramParameter4fvNV, (GLenum, GLuint, const GLfloat *)) +AGL_API(void, ProgramParameters4dvNV, (GLenum, GLuint, GLuint, const GLdouble *)) +AGL_API(void, ProgramParameters4fvNV, (GLenum, GLuint, GLuint, const GLfloat *)) +AGL_API(void, RequestResidentProgramsNV, (GLsizei, const GLuint *)) +AGL_API(void, TrackMatrixNV, (GLenum, GLuint, GLenum, GLenum)) +AGL_API(void, VertexAttribPointerNV, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, VertexAttrib1dNV, (GLuint, GLdouble)) +AGL_API(void, VertexAttrib1dvNV, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib1fNV, (GLuint, GLfloat)) +AGL_API(void, VertexAttrib1fvNV, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib1sNV, (GLuint, GLshort)) +AGL_API(void, VertexAttrib1svNV, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib2dNV, (GLuint, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib2dvNV, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib2fNV, (GLuint, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib2fvNV, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib2sNV, (GLuint, GLshort, GLshort)) +AGL_API(void, VertexAttrib2svNV, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib3dNV, (GLuint, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib3dvNV, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib3fNV, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib3fvNV, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib3sNV, (GLuint, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib3svNV, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4dNV, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4dvNV, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4fNV, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib4fvNV, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib4sNV, (GLuint, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib4svNV, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4ubNV, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) +AGL_API(void, VertexAttrib4ubvNV, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttribs1dvNV, (GLuint, GLsizei, const GLdouble *)) +AGL_API(void, VertexAttribs1fvNV, (GLuint, GLsizei, const GLfloat *)) +AGL_API(void, VertexAttribs1svNV, (GLuint, GLsizei, const GLshort *)) +AGL_API(void, VertexAttribs2dvNV, (GLuint, GLsizei, const GLdouble *)) +AGL_API(void, VertexAttribs2fvNV, (GLuint, GLsizei, const GLfloat *)) +AGL_API(void, VertexAttribs2svNV, (GLuint, GLsizei, const GLshort *)) +AGL_API(void, VertexAttribs3dvNV, (GLuint, GLsizei, const GLdouble *)) +AGL_API(void, VertexAttribs3fvNV, (GLuint, GLsizei, const GLfloat *)) +AGL_API(void, VertexAttribs3svNV, (GLuint, GLsizei, const GLshort *)) +AGL_API(void, VertexAttribs4dvNV, (GLuint, GLsizei, const GLdouble *)) +AGL_API(void, VertexAttribs4fvNV, (GLuint, GLsizei, const GLfloat *)) +AGL_API(void, VertexAttribs4svNV, (GLuint, GLsizei, const GLshort *)) +AGL_API(void, VertexAttribs4ubvNV, (GLuint, GLsizei, const GLubyte *)) +#endif + +#if defined _ALLEGRO_GL_ATI_envmap_bumpmap +AGL_API(void, TexBumpParameterivATI, (GLenum, const GLint *)) +AGL_API(void, TexBumpParameterfvATI, (GLenum, const GLfloat *)) +AGL_API(void, GetTexBumpParameterivATI, (GLenum, GLint *)) +AGL_API(void, GetTexBumpParameterfvATI, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_ATI_fragment_shader +AGL_API(GLuint, GenFragmentShadersATI, (GLuint)) +AGL_API(void, BindFragmentShaderATI, (GLuint)) +AGL_API(void, DeleteFragmentShaderATI, (GLuint)) +AGL_API(void, BeginFragmentShaderATI, (void)) +AGL_API(void, EndFragmentShaderATI, (void)) +AGL_API(void, PassTexCoordATI, (GLuint, GLuint, GLenum)) +AGL_API(void, SampleMapATI, (GLuint, GLuint, GLenum)) +AGL_API(void, ColorFragmentOp1ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ColorFragmentOp2ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ColorFragmentOp3ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, AlphaFragmentOp1ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, AlphaFragmentOp2ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, AlphaFragmentOp3ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, SetFragmentShaderConstantATI, (GLuint, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_ATI_pn_triangles +AGL_API(void, PNTrianglesiATI, (GLenum, GLint)) +AGL_API(void, PNTrianglesfATI, (GLenum, GLfloat)) +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_array_object +AGL_API(GLuint, NewObjectBufferATI, (GLsizei, const GLvoid *, GLenum)) +AGL_API(GLboolean, IsObjectBufferATI, (GLuint)) +AGL_API(void, UpdateObjectBufferATI, (GLuint, GLuint, GLsizei, const GLvoid *, GLenum)) +AGL_API(void, GetObjectBufferfvATI, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetObjectBufferivATI, (GLuint, GLenum, GLint *)) +AGL_API(void, FreeObjectBufferATI, (GLuint)) +AGL_API(void, ArrayObjectATI, (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint)) +AGL_API(void, GetArrayObjectfvATI, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetArrayObjectivATI, (GLenum, GLenum, GLint *)) +AGL_API(void, VariantArrayObjectATI, (GLuint, GLenum, GLsizei, GLuint, GLuint)) +AGL_API(void, GetVariantArrayObjectfvATI, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVariantArrayObjectivATI, (GLuint, GLenum, GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_shader +AGL_API(void, BeginVertexShaderEXT, (void)) +AGL_API(void, EndVertexShaderEXT, (void)) +AGL_API(void, BindVertexShaderEXT, (GLuint)) +AGL_API(GLuint, GenVertexShadersEXT, (GLuint)) +AGL_API(void, DeleteVertexShaderEXT, (GLuint)) +AGL_API(void, ShaderOp1EXT, (GLenum, GLuint, GLuint)) +AGL_API(void, ShaderOp2EXT, (GLenum, GLuint, GLuint, GLuint)) +AGL_API(void, ShaderOp3EXT, (GLenum, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, SwizzleEXT, (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, WriteMaskEXT, (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, InsertComponentEXT, (GLuint, GLuint, GLuint)) +AGL_API(void, ExtractComponentEXT, (GLuint, GLuint, GLuint)) +AGL_API(GLuint, GenSymbolsEXT, (GLenum, GLenum, GLenum, GLuint)) +AGL_API(void, SetInvariantEXT, (GLuint, GLenum, const GLvoid *)) +AGL_API(void, SetLocalConstantEXT, (GLuint, GLenum, const GLvoid *)) +AGL_API(void, VariantbvEXT, (GLuint, const GLbyte *)) +AGL_API(void, VariantsvEXT, (GLuint, const GLshort *)) +AGL_API(void, VariantivEXT, (GLuint, const GLint *)) +AGL_API(void, VariantfvEXT, (GLuint, const GLfloat *)) +AGL_API(void, VariantdvEXT, (GLuint, const GLdouble *)) +AGL_API(void, VariantubvEXT, (GLuint, const GLubyte *)) +AGL_API(void, VariantusvEXT, (GLuint, const GLushort *)) +AGL_API(void, VariantuivEXT, (GLuint, const GLuint *)) +AGL_API(void, VariantPointerEXT, (GLuint, GLenum, GLuint, const GLvoid *)) +AGL_API(void, EnableVariantClientStateEXT, (GLuint)) +AGL_API(void, DisableVariantClientStateEXT, (GLuint)) +AGL_API(GLuint, BindLightParameterEXT, (GLenum, GLenum)) +AGL_API(GLuint, BindMaterialParameterEXT, (GLenum, GLenum)) +AGL_API(GLuint, BindTexGenParameterEXT, (GLenum, GLenum, GLenum)) +AGL_API(GLuint, BindTextureUnitParameterEXT, (GLenum, GLenum)) +AGL_API(GLuint, BindParameterEXT, (GLenum)) +AGL_API(GLboolean, IsVariantEnabledEXT, (GLuint, GLenum)) +AGL_API(void, GetVariantBooleanvEXT, (GLuint, GLenum, GLboolean *)) +AGL_API(void, GetVariantIntegervEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVariantFloatvEXT, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVariantPointervEXT, (GLuint, GLenum, GLvoid* *)) +AGL_API(void, GetInvariantBooleanvEXT, (GLuint, GLenum, GLboolean *)) +AGL_API(void, GetInvariantIntegervEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetInvariantFloatvEXT, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetLocalConstantBooleanvEXT, (GLuint, GLenum, GLboolean *)) +AGL_API(void, GetLocalConstantIntegervEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetLocalConstantFloatvEXT, (GLuint, GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_streams +AGL_API(void, VertexStream1sATI, (GLenum, GLshort)) +AGL_API(void, VertexStream1svATI, (GLenum, const GLshort *)) +AGL_API(void, VertexStream1iATI, (GLenum, GLint)) +AGL_API(void, VertexStream1ivATI, (GLenum, const GLint *)) +AGL_API(void, VertexStream1fATI, (GLenum, GLfloat)) +AGL_API(void, VertexStream1fvATI, (GLenum, const GLfloat *)) +AGL_API(void, VertexStream1dATI, (GLenum, GLdouble)) +AGL_API(void, VertexStream1dvATI, (GLenum, const GLdouble *)) +AGL_API(void, VertexStream2sATI, (GLenum, GLshort, GLshort)) +AGL_API(void, VertexStream2svATI, (GLenum, const GLshort *)) +AGL_API(void, VertexStream2iATI, (GLenum, GLint, GLint)) +AGL_API(void, VertexStream2ivATI, (GLenum, const GLint *)) +AGL_API(void, VertexStream2fATI, (GLenum, GLfloat, GLfloat)) +AGL_API(void, VertexStream2fvATI, (GLenum, const GLfloat *)) +AGL_API(void, VertexStream2dATI, (GLenum, GLdouble, GLdouble)) +AGL_API(void, VertexStream2dvATI, (GLenum, const GLdouble *)) +AGL_API(void, VertexStream3sATI, (GLenum, GLshort, GLshort, GLshort)) +AGL_API(void, VertexStream3svATI, (GLenum, const GLshort *)) +AGL_API(void, VertexStream3iATI, (GLenum, GLint, GLint, GLint)) +AGL_API(void, VertexStream3ivATI, (GLenum, const GLint *)) +AGL_API(void, VertexStream3fATI, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexStream3fvATI, (GLenum, const GLfloat *)) +AGL_API(void, VertexStream3dATI, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexStream3dvATI, (GLenum, const GLdouble *)) +AGL_API(void, VertexStream4sATI, (GLenum, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexStream4svATI, (GLenum, const GLshort *)) +AGL_API(void, VertexStream4iATI, (GLenum, GLint, GLint, GLint, GLint)) +AGL_API(void, VertexStream4ivATI, (GLenum, const GLint *)) +AGL_API(void, VertexStream4fATI, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexStream4fvATI, (GLenum, const GLfloat *)) +AGL_API(void, VertexStream4dATI, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexStream4dvATI, (GLenum, const GLdouble *)) +AGL_API(void, NormalStream3bATI, (GLenum, GLbyte, GLbyte, GLbyte)) +AGL_API(void, NormalStream3bvATI, (GLenum, const GLbyte *)) +AGL_API(void, NormalStream3sATI, (GLenum, GLshort, GLshort, GLshort)) +AGL_API(void, NormalStream3svATI, (GLenum, const GLshort *)) +AGL_API(void, NormalStream3iATI, (GLenum, GLint, GLint, GLint)) +AGL_API(void, NormalStream3ivATI, (GLenum, const GLint *)) +AGL_API(void, NormalStream3fATI, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, NormalStream3fvATI, (GLenum, const GLfloat *)) +AGL_API(void, NormalStream3dATI, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, NormalStream3dvATI, (GLenum, const GLdouble *)) +AGL_API(void, ClientActiveVertexStreamATI, (GLenum)) +AGL_API(void, VertexBlendEnviATI, (GLenum, GLint)) +AGL_API(void, VertexBlendEnvfATI, (GLenum, GLfloat)) +#endif + +#if defined _ALLEGRO_GL_ATI_element_array +AGL_API(void, ElementPointerATI, (GLenum, const GLvoid *)) +AGL_API(void, DrawElementArrayATI, (GLenum, GLsizei)) +AGL_API(void, DrawRangeElementArrayATI, (GLenum, GLuint, GLuint, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_SUN_mesh_array +AGL_API(void, DrawMeshArraysSUN, (GLenum, GLint, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_NV_occlusion_query +AGL_API(void, GenOcclusionQueriesNV, (GLsizei, GLuint *)) +AGL_API(void, DeleteOcclusionQueriesNV, (GLsizei, const GLuint *)) +AGL_API(GLboolean, IsOcclusionQueryNV, (GLuint)) +AGL_API(void, BeginOcclusionQueryNV, (GLuint)) +AGL_API(void, EndOcclusionQueryNV, (void)) +AGL_API(void, GetOcclusionQueryivNV, (GLuint, GLenum, GLint *)) +AGL_API(void, GetOcclusionQueryuivNV, (GLuint, GLenum, GLuint *)) +#endif + +#if defined _ALLEGRO_GL_NV_point_sprite +AGL_API(void, PointParameteriNV, (GLenum, GLint)) +AGL_API(void, PointParameterivNV, (GLenum, const GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_stencil_two_side +AGL_API(void, ActiveStencilFaceEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_APPLE_element_array +AGL_API(void, ElementPointerAPPLE, (GLenum, const GLvoid *)) +AGL_API(void, DrawElementArrayAPPLE, (GLenum, GLint, GLsizei)) +AGL_API(void, DrawRangeElementArrayAPPLE, (GLenum, GLuint, GLuint, GLint, GLsizei)) +AGL_API(void, MultiDrawElementArrayAPPLE, (GLenum, const GLint *, const GLsizei *, GLsizei)) +AGL_API(void, MultiDrawRangeElementArrayAPPLE, (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_APPLE_fence +AGL_API(void, GenFencesAPPLE, (GLsizei, GLuint *)) +AGL_API(void, DeleteFencesAPPLE, (GLsizei, const GLuint *)) +AGL_API(void, SetFenceAPPLE, (GLuint)) +AGL_API(GLboolean, IsFenceAPPLE, (GLuint)) +AGL_API(GLboolean, TestFenceAPPLE, (GLuint)) +AGL_API(void, FinishFenceAPPLE, (GLuint)) +AGL_API(GLboolean, TestObjectAPPLE, (GLenum, GLuint)) +AGL_API(void, FinishObjectAPPLE, (GLenum, GLint)) +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_array_object +AGL_API(void, BindVertexArrayAPPLE, (GLuint)) +AGL_API(void, DeleteVertexArraysAPPLE, (GLsizei, const GLuint *)) +AGL_API(void, GenVertexArraysAPPLE, (GLsizei, const GLuint *)) +AGL_API(GLboolean, IsVertexArrayAPPLE, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_array_range +AGL_API(void, VertexArrayRangeAPPLE, (GLsizei, GLvoid *)) +AGL_API(void, FlushVertexArrayRangeAPPLE, (GLsizei, GLvoid *)) +AGL_API(void, VertexArrayParameteriAPPLE, (GLenum, GLint)) +#endif + +#if defined _ALLEGRO_GL_ATI_draw_buffers +AGL_API(void, DrawBuffersATI, (GLsizei, const GLenum *)) +#endif + +#if defined _ALLEGRO_GL_NV_fragment_program +AGL_API(void, ProgramNamedParameter4fNV, (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramNamedParameter4dNV, (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, ProgramNamedParameter4fvNV, (GLuint, GLsizei, const GLubyte *, const GLfloat *)) +AGL_API(void, ProgramNamedParameter4dvNV, (GLuint, GLsizei, const GLubyte *, const GLdouble *)) +AGL_API(void, GetProgramNamedParameterfvNV, (GLuint, GLsizei, const GLubyte *, GLfloat *)) +AGL_API(void, GetProgramNamedParameterdvNV, (GLuint, GLsizei, const GLubyte *, GLdouble *)) +#endif + +#if defined _ALLEGRO_GL_NV_half_float +AGL_API(void, Vertex2hNV, (GLhalfNV, GLhalfNV)) +AGL_API(void, Vertex2hvNV, (const GLhalfNV *)) +AGL_API(void, Vertex3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Vertex3hvNV, (const GLhalfNV *)) +AGL_API(void, Vertex4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Vertex4hvNV, (const GLhalfNV *)) +AGL_API(void, Normal3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Normal3hvNV, (const GLhalfNV *)) +AGL_API(void, Color3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Color3hvNV, (const GLhalfNV *)) +AGL_API(void, Color4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Color4hvNV, (const GLhalfNV *)) +AGL_API(void, TexCoord1hNV, (GLhalfNV)) +AGL_API(void, TexCoord1hvNV, (const GLhalfNV *)) +AGL_API(void, TexCoord2hNV, (GLhalfNV, GLhalfNV)) +AGL_API(void, TexCoord2hvNV, (const GLhalfNV *)) +AGL_API(void, TexCoord3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, TexCoord3hvNV, (const GLhalfNV *)) +AGL_API(void, TexCoord4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, TexCoord4hvNV, (const GLhalfNV *)) +AGL_API(void, MultiTexCoord1hNV, (GLenum, GLhalfNV)) +AGL_API(void, MultiTexCoord1hvNV, (GLenum, const GLhalfNV *)) +AGL_API(void, MultiTexCoord2hNV, (GLenum, GLhalfNV, GLhalfNV)) +AGL_API(void, MultiTexCoord2hvNV, (GLenum, const GLhalfNV *)) +AGL_API(void, MultiTexCoord3hNV, (GLenum, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, MultiTexCoord3hvNV, (GLenum, const GLhalfNV *)) +AGL_API(void, MultiTexCoord4hNV, (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, MultiTexCoord4hvNV, (GLenum, const GLhalfNV *)) +AGL_API(void, FogCoordhNV, (GLhalfNV)) +AGL_API(void, FogCoordhvNV, (const GLhalfNV *)) +AGL_API(void, SecondaryColor3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, SecondaryColor3hvNV, (const GLhalfNV *)) +AGL_API(void, VertexWeighthNV, (GLhalfNV)) +AGL_API(void, VertexWeighthvNV, (const GLhalfNV *)) +AGL_API(void, VertexAttrib1hNV, (GLuint, GLhalfNV)) +AGL_API(void, VertexAttrib1hvNV, (GLuint, const GLhalfNV *)) +AGL_API(void, VertexAttrib2hNV, (GLuint, GLhalfNV, GLhalfNV)) +AGL_API(void, VertexAttrib2hvNV, (GLuint, const GLhalfNV *)) +AGL_API(void, VertexAttrib3hNV, (GLuint, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, VertexAttrib3hvNV, (GLuint, const GLhalfNV *)) +AGL_API(void, VertexAttrib4hNV, (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, VertexAttrib4hvNV, (GLuint, const GLhalfNV *)) +AGL_API(void, VertexAttribs1hvNV, (GLuint, GLsizei, const GLhalfNV *)) +AGL_API(void, VertexAttribs2hvNV, (GLuint, GLsizei, const GLhalfNV *)) +AGL_API(void, VertexAttribs3hvNV, (GLuint, GLsizei, const GLhalfNV *)) +AGL_API(void, VertexAttribs4hvNV, (GLuint, GLsizei, const GLhalfNV *)) +#endif + +#if defined _ALLEGRO_GL_NV_pixel_data_range +AGL_API(void, PixelDataRangeNV, (GLenum, GLsizei, GLvoid *)) +AGL_API(void, FlushPixelDataRangeNV, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_NV_primitive_restart +AGL_API(void, PrimitiveRestartNV, (void)) +AGL_API(void, PrimitiveRestartIndexNV, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_ATI_map_object_buffer +AGL_API(GLvoid*, MapObjectBufferATI, (GLuint)) +AGL_API(void, UnmapObjectBufferATI, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_ATI_separate_stencil +AGL_API(void, StencilOpSeparateATI, (GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, StencilFuncSeparateATI, (GLenum, GLenum, GLint, GLuint)) +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_attrib_array_object +AGL_API(void, VertexAttribArrayObjectATI, (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint)) +AGL_API(void, GetVertexAttribArrayObjectfvATI, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribArrayObjectivATI, (GLuint, GLenum, GLint *)) +#endif + +#if defined _ALLEGRO_GL_OES_byte_coordinates +AGL_API(void, Vertex2bOES, ( GLbyte, GLbyte )) +AGL_API(void, Vertex3bOES, ( GLbyte, GLbyte, GLbyte )) +AGL_API(void, Vertex4bOES, ( GLbyte, GLbyte, GLbyte, GLbyte )) +AGL_API(void, Vertex2bvOES, ( const GLbyte * )) +AGL_API(void, Vertex3bvOES, ( const GLbyte * )) +AGL_API(void, Vertex4bvOES, ( const GLbyte * )) +AGL_API(void, TexCoord1bOES, ( GLbyte )) +AGL_API(void, TexCoord2bOES, ( GLbyte, GLbyte )) +AGL_API(void, TexCoord3bOES, ( GLbyte, GLbyte, GLbyte )) +AGL_API(void, TexCoord4bOES, ( GLbyte, GLbyte, GLbyte, GLbyte )) +AGL_API(void, TexCoord1bvOES, ( const GLbyte * )) +AGL_API(void, TexCoord2bvOES, ( const GLbyte * )) +AGL_API(void, TexCoord3bvOES, ( const GLbyte * )) +AGL_API(void, TexCoord4bvOES, ( const GLbyte * )) +AGL_API(void, MultiTexCoord1bOES, ( GLenum, GLbyte )) +AGL_API(void, MultiTexCoord2bOES, ( GLenum, GLbyte, GLbyte )) +AGL_API(void, MultiTexCoord3bOES, ( GLenum, GLbyte, GLbyte, GLbyte )) +AGL_API(void, MultiTexCoord4bOES, ( GLenum, GLbyte, GLbyte, GLbyte, GLbyte )) +AGL_API(void, MultiTexCoord1bvOES, ( GLenum texture, const GLbyte * )) +AGL_API(void, MultiTexCoord2bvOES, ( GLenum texture, const GLbyte * )) +AGL_API(void, MultiTexCoord3bvOES, ( GLenum texture, const GLbyte * )) +AGL_API(void, MultiTexCoord4bvOES, ( GLenum texture, const GLbyte * )) +#endif + +#if defined _ALLEGRO_GL_OES_fixed_point +AGL_API(void, Vertex2xOES, (GLfixed, GLfixed)) +AGL_API(void, Vertex3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, Vertex4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, Vertex2xvOES, (const GLfixed *)) +AGL_API(void, Vertex3xvOES, (const GLfixed *)) +AGL_API(void, Vertex4xvOES, (const GLfixed *)) +AGL_API(void, Normal3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, Normal3xvOES, (const GLfixed *)) +AGL_API(void, TexCoord1xOES, (GLfixed)) +AGL_API(void, TexCoord2xOES, (GLfixed, GLfixed)) +AGL_API(void, TexCoord3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, TexCoord4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, TexCoord1xvOES, (const GLfixed *)) +AGL_API(void, TexCoord2xvOES, (const GLfixed *)) +AGL_API(void, TexCoord3xvOES, (const GLfixed *)) +AGL_API(void, TexCoord4xvOES, (const GLfixed *)) +AGL_API(void, MultiTexCoord1xOES, (GLenum, GLfixed)) +AGL_API(void, MultiTexCoord2xOES, (GLenum, GLfixed, GLfixed)) +AGL_API(void, MultiTexCoord3xOES, (GLenum, GLfixed, GLfixed, GLfixed)) +AGL_API(void, MultiTexCoord4xOES, (GLenum, GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, MultiTexCoord1xvOES, (GLenum, const GLfixed *)) +AGL_API(void, MultiTexCoord2xvOES, (GLenum, const GLfixed *)) +AGL_API(void, MultiTexCoord3xvOES, (GLenum, const GLfixed *)) +AGL_API(void, MultiTexCoord4xvOES, (GLenum, const GLfixed *)) +AGL_API(void, Color3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, Color4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, Color3xvOES, (const GLfixed *)) +AGL_API(void, Color4xvOES, (const GLfixed *)) +AGL_API(void, IndexxOES, (GLfixed)) +AGL_API(void, IndexxvOES, (const GLfixed *)) +AGL_API(void, RectxOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, RectxvOES, (const GLfixed [2], const GLfixed [2])) +AGL_API(void, DepthRangexOES, (GLclampx, GLclampx)) +AGL_API(void, LoadMatrixxOES, (const GLfixed [16])) +AGL_API(void, MultMatrixxOES, (const GLfixed [16])) +AGL_API(void, LoadTransposeMatrixxOES, (const GLfixed [16])) +AGL_API(void, MultTransposeMatrixxOES, (const GLfixed [16])) +AGL_API(void, RotatexOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, ScalexOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, TranslatexOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, FrustumxOES, (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, OrthoxOES, (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, TexGenxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, TexGenxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetTexGenxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, ClipPlanexOES, (GLenum, const GLfixed *)) +AGL_API(void, GetClipPlanexOES, (GLenum, GLfixed *)) +AGL_API(void, RasterPos2xOES, (GLfixed, GLfixed)) +AGL_API(void, RasterPos3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, RasterPos4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, RasterPos2xvOES, (const GLfixed *)) +AGL_API(void, RasterPos3xvOES, (const GLfixed *)) +AGL_API(void, RasterPos4xvOES, (const GLfixed *)) +AGL_API(void, MaterialxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, MaterialxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetMaterialxOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, LightxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, LightxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetLightxOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, LightModelxOES, (GLenum, GLfixed)) +AGL_API(void, LightModelxvOES, (GLenum, const GLfixed *)) +AGL_API(void, PointSizexOES, (GLfixed size)) +AGL_API(void, LineWidthxOES, (GLfixed width)) +AGL_API(void, PolygonOffsetxOES, (GLfixed factor, GLfixed units)) +AGL_API(void, PixelStorex, (GLenum pname, GLfixed param)) +AGL_API(void, PixelTransferxOES, (GLenum pname, GLfixed param)) +AGL_API(void, PixelMapx, (GLenum, GLint, const GLfixed *)) +AGL_API(void, GetPixelMapxv, (GLenum, GLint, GLfixed *)) +AGL_API(void, ConvolutionParameterxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, ConvolutionParameterxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetConvolutionParameterxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, GetHistogramParameterxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, PixelZoomxOES, (GLfixed, GLfixed)) +AGL_API(void, BitmapxOES, (GLsizei, GLsizei, GLfixed, GLfixed, GLfixed, GLfixed, const GLubyte *)) +AGL_API(void, TexParameterxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, TexParameterxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetTexParameterxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, GetTexLevelParameterxvOES, (GLenum, GLint, GLenum, GLfixed *)) +AGL_API(void, PrioritizeTexturesxOES, (GLsizei, GLuint *, GLclampx *)) +AGL_API(void, TexEnvxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, TexEnvxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetTexEnvxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, FogxOES, (GLenum, GLfixed)) +AGL_API(void, FogxvOES, (GLenum, const GLfixed *)) +AGL_API(void, SampleCoverageOES, (GLclampx, GLboolean)) +AGL_API(void, AlphaFuncxOES, (GLenum, GLclampx)) +AGL_API(void, BlendColorxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) +AGL_API(void, ClearColorxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) +AGL_API(void, ClearDepthxOES, (GLclampx)) +AGL_API(void, ClearAccumxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) +AGL_API(void, AccumxOES, (GLenum, GLfixed)) +AGL_API(void, Map1xOES, (GLenum, GLfixed, GLfixed, GLint, GLint, const GLfixed *)) +AGL_API(void, Map2xOES, (GLenum, GLfixed, GLfixed, GLint, GLint, GLfixed, GLfixed, GLint, GLint, const GLfixed *)) +AGL_API(void, MapGrid1xOES, (GLint, GLfixed, GLfixed)) +AGL_API(void, MapGrid2xOES, (GLint, GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, GetMapxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, EvalCoord1xOES, (GLfixed)) +AGL_API(void, EvalCoord2xOES, (GLfixed, GLfixed)) +AGL_API(void, EvalCoord1xvOES, (const GLfixed *)) +AGL_API(void, EvalCoord2xvOES, (const GLfixed *)) +AGL_API(void, FeedbackBufferxOES, (GLsizei, GLenum, GLfixed *)) +AGL_API(void, PassThroughxOES, (GLfixed)) +AGL_API(void, GetFixedvOES, (GLenum, GLfixed *)) +#endif + +#if defined _ALLEGRO_GL_OES_single_precision +AGL_API(void, DepthRangefOES, (GLclampf, GLclampf)) +AGL_API(void, FrustumfOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, OrthofOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ClipPlanefOES, (GLenum, const GLfloat*)) +AGL_API(void, GetClipPlanefOES, (GLenum, GLfloat*)) +AGL_API(void, ClearDepthfOES, (GLclampd)) +#endif + +#if defined _ALLEGRO_GL_OES_query_matrix +AGL_API(GLbitfield, QueryMatrixxOES, (GLfixed [16], GLint [16] )) +#endif + +#if defined _ALLEGRO_GL_EXT_depth_bounds_test +AGL_API(void, DepthBoundsEXT, (GLclampd, GLclampd)) +#endif + + +#if defined _ALLEGRO_GL_EXT_blend_equation_separate +AGL_API(void, BlendEquationSeparateEXT, (GLenum, GLenum)) +#endif + + +#if defined _ALLEGRO_GL_EXT_framebuffer_object +AGL_API(GLboolean, IsRenderbufferEXT, (GLuint)) +AGL_API(void, BindRenderbufferEXT, (GLenum, GLuint)) +AGL_API(void, DeleteRenderbuffersEXT, (GLsizei, const GLuint *)) +AGL_API(void, GenRenderbuffersEXT, (GLsizei, GLuint *)) +AGL_API(void, RenderbufferStorageEXT, (GLenum, GLenum, GLsizei, GLsizei)) +AGL_API(void, GetRenderbufferParameterivEXT, (GLenum, GLenum, GLint*)) +AGL_API(GLboolean, IsFramebufferEXT, (GLuint)) +AGL_API(void, BindFramebufferEXT, (GLenum, GLuint)) +AGL_API(void, DeleteFramebuffersEXT, (GLsizei, const GLuint *)) +AGL_API(void, GenFramebuffersEXT, (GLsizei, GLuint *)) +AGL_API(GLenum, CheckFramebufferStatusEXT, (GLenum)) +AGL_API(void, FramebufferTexture1DEXT, (GLenum, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTexture2DEXT, (GLenum, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTexture3DEXT, (GLenum, GLenum, GLenum, GLuint, GLint, GLint)) +AGL_API(void, FramebufferRenderbufferEXT, (GLenum, GLenum, GLenum, GLuint)) +AGL_API(void, GetFramebufferAttachmentParameterivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GenerateMipmapEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_GREMEDY_string_marker +AGL_API(void, StringMarkerGREMEDY, (GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_stencil_clear_tag +AGL_API(void, StencilClearTagEXT, (GLsizei, GLuint)) +#endif + +#if defined _ALLEGRO_GL_EXT_framebuffer_blit +AGL_API(void, BlitFramebufferEXT, (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_framebuffer_multisample +AGL_API(void, RenderbufferStorageMultisampleEXT, (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_EXT_timer_query +AGL_API(void, GetQueryObjecti64vEXT, (GLuint, GLenum, GLint64EXT *)) +AGL_API(void, GetQueryObjectui64vEXT, (GLuint, GLenum, GLuint64EXT *)) +#endif + +#if defined _ALLEGRO_GL_EXT_gpu_program_parameters +AGL_API(void, ProgramEnvParameters4fvEXT, (GLenum, GLuint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramLocalParameters4fvEXT, (GLenum, GLuint, GLsizei, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_APPLE_flush_buffer_range +AGL_API(void, BufferParameteriAPPLE, (GLenum, GLenum, GLint)) +AGL_API(void, FlushMappedBufferRangeAPPLE, (GLenum, GLintptr, GLsizeiptr)) +#endif + +#if defined _ALLEGRO_GL_EXT_bindable_uniform +AGL_API(void, UniformBufferEXT, (GLuint, GLint, GLuint)) +AGL_API(GLint, GetUniformBufferSizeEXT, (GLuint, GLint)) +AGL_API(GLintptr, GetUniformOffsetEXT, (GLuint program, GLint)) +#endif + +#if defined _ALLEGRO_GL_EXT_draw_buffers2 +AGL_API(void, ColorMaskIndexedEXT, (GLuint, GLboolean, GLboolean, GLboolean, GLboolean)) +AGL_API(void, GetBooleanIndexedvEXT, (GLenum, GLuint, GLboolean *)) +AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLint *)) +AGL_API(void, EnableIndexedEXT, (GLenum, GLuint)) +AGL_API(void, DisableIndexedEXT, (GLenum, GLuint)) +AGL_API(GLboolean, IsEnabledIndexedEXT, (GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_EXT_draw_instanced +AGL_API(void, DrawArraysInstancedEXT, (GLenum, GLint, GLsizei, GLsizei)) +AGL_API(void, DrawElementsInstancedEXT, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_EXT_geometry_shader4 +AGL_API(void, ProgramParameteriEXT, (GLuint, GLenum, GLint)) +AGL_API(void, FramebufferTextureEXT, (GLenum, GLenum, GLuint, GLint)) +#if !defined _ALLEGRO_GL_EXT_texture_array +AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) +#endif +AGL_API(void, FramebufferTextureFaceEXT, (GLenum, GLenum, GLuint, GLint, GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_gpu_shader4 +AGL_API(void, VertexAttribI1iEXT, (GLuint, GLint)) +AGL_API(void, VertexAttribI2iEXT, (GLuint, GLint, GLint)) +AGL_API(void, VertexAttribI3iEXT, (GLuint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI4iEXT, (GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI1uiEXT, (GLuint, GLuint)) +AGL_API(void, VertexAttribI2uiEXT, (GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI3uiEXT, (GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI4uiEXT, (GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI1ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI2ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI3ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI4ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI1uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI2uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI3uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4bvEXT, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttribI4svEXT, (GLuint, const GLshort *)) +AGL_API(void, VertexAttribI4ubvEXT, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttribI4usvEXT, (GLuint, const GLushort *)) +AGL_API(void, VertexAttribIPointerEXT, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetVertexAttribIivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribIuivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, Uniform1uiEXT, (GLint, GLuint)) +AGL_API(void, Uniform2uiEXT, (GLint, GLuint, GLuint)) +AGL_API(void, Uniform3uiEXT, (GLint, GLuint, GLuint, GLuint)) +AGL_API(void, Uniform4uiEXT, (GLint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, Uniform1uivEXT, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform2uivEXT, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform3uivEXT, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform4uivEXT, (GLint, GLsizei, const GLuint *)) +AGL_API(void, GetUniformuivEXT, (GLuint, GLint location, GLint *)) +AGL_API(void, BindFragDataLocationEXT, (GLuint, GLuint, const GLchar *)) +AGL_API(GLint, GetFragDataLocationEXT, (GLuint, const GLchar *)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture_array +AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture_buffer_object +AGL_API(void, TexBufferEXT, (GLenum, GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_texture_integer +AGL_API(void, ClearColorIiEXT, (GLint, GLint, GLint, GLint)) +AGL_API(void, ClearColorIuiEXT, (GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, TexParameterIivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, TexParameterIuivEXT, (GLenum, GLenum, GLuint *)) +AGL_API(void, GetTexParameterIivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, GetTexParameterIiuvEXT, (GLenum, GLenum, GLuint *)) +#endif + +#if defined _ALLEGRO_GL_NV_depth_buffer_float +AGL_API(void, DepthRangedNV, (GLdouble, GLdouble)) +AGL_API(void, ClearDepthdNV, (GLdouble)) +AGL_API(void, DepthBoundsdNV, (GLdouble, GLdouble)) +#endif + +#if defined _ALLEGRO_GL_NV_framebuffer_multisample_coverage +AGL_API(void, RenderbufferStorageMultsampleCoverageNV, (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_NV_geometry_program4 +AGL_API(void, ProgramVertexLimitNV, (GLenum, GLint)) +#if !defined _ALLEGRO_GL_EXT_geometry_shader4 +AGL_API(void, FramebufferTextureEXT, (GLenum, GLenum, GLuint, GLint)) +#if !defined _ALLEGRO_GL_EXT_texture_array +AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) +#endif +#endif +#endif + +#if defined _ALLEGRO_GL_NV_gpu_program4 +AGL_API(void, ProgramLocalParameterI4iNV, (GLenum, GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, ProgramLocalParameterI4ivNV, (GLenum, GLuint, const GLint *)) +AGL_API(void, ProgramLocalParametersI4ivNV, (GLenum, GLuint, GLsizei, const GLint *)) +AGL_API(void, ProgramLocalParameterI4uiNV, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ProgramLocalParameterI4uivNV, (GLenum, GLuint, const GLuint *)) +AGL_API(void, ProgramLocalParametersI4uivNV, (GLenum, GLuint, GLsizei, const GLuint *)) +AGL_API(void, ProgramEnvParameterI4iNV, (GLenum, GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, ProgramEnvParameterI4ivNV, (GLenum, GLuint, const GLint *)) +AGL_API(void, ProgramEnvParametersI4ivNV, (GLenum, GLuint, GLsizei, const GLint *)) +AGL_API(void, ProgramEnvParameterI4uiNV, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ProgramEnvParameterI4uivNV, (GLenum, GLuint, const GLuint *)) +AGL_API(void, ProgramEnvParametersI4uivNV, (GLenum, GLuint, GLsizei, const GLuint *)) +AGL_API(void, GetProgramLocalParameterIivNV, (GLenum, GLuint, GLint *)) +AGL_API(void, GetProgramLocalParameterIuivNV,(GLenum, GLuint, GLuint *)) +AGL_API(void, GetProgramEnvParameterIivNV, (GLenum, GLuint, GLint *)) +AGL_API(void, GetProgramEnvParameterIuivNV, (GLenum, GLuint, GLuint *)) +#endif + +#if defined _ALLEGRO_GL_NV_parameter_buffer_object +#if !defined _ALLEGRO_GL_NV_transform_feedback +AGL_API(void, BindBufferRangeNV, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) +AGL_API(void, BindBufferOffsetNV,(GLenum, GLuint, GLuint, GLintptr)) +AGL_API(void, BindBufferBaseNV, (GLenum, GLuint, GLuint)) +#endif +AGL_API(void, ProgramBufferParametersfvNV, (GLenum, GLuint, GLuint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramBufferParametersIivNV, (GLenum, GLuint, GLuint, GLsizei, const GLint *)) +AGL_API(void, ProgramBufferParametersIuivNV,(GLenum, GLuint, GLuint, GLuint, const GLuint *)) +#if !defined _ALLEGRO_GL_EXT_draw_buffers2 +AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLboolean *)) +#endif +#endif + +#if defined _ALLEGRO_GL_NV_transform_feedback +AGL_API(void, BindBufferRangeNV, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) +AGL_API(void, BindBufferOffsetNV,(GLenum, GLuint, GLuint, GLintptr)) +AGL_API(void, BindBufferBaseNV, (GLenum, GLuint, GLuint)) +AGL_API(void, TransformFeedbackAttribsNV, (GLsizei, const GLint *, GLenum)) +AGL_API(void, TransformFeedbackVaryingsNV,(GLuint, GLsizei, const GLint *, GLenum)) +AGL_API(void, BeginTransformFeedbackNV, (GLenum)) +AGL_API(void, EndTransformFeedbackNV, (void)) +AGL_API(GLint, GetVaryingLocationNV, (GLuint, const GLchar *)) +AGL_API(void, GetActiveVaryingNV, (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *)) +AGL_API(void, ActiveVaryingNV, (GLuint, const GLchar *)) +AGL_API(void, GetTransformFeedbackVaryingNV, (GLuint, GLuint, GLint *)) +#if !defined _ALLEGRO_GL_EXT_draw_buffers2 +AGL_API(void, GetBooleanIndexedvEXT, (GLenum, GLuint, GLboolean *)) +/*AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLint *))*/ +#endif +#endif + +#if defined _ALLEGRO_GL_NV_vertex_program4 +#ifndef _ALLEGRO_GL_EXT_gpu_shader4 +AGL_API(void, VertexAttribI1iEXT, (GLuint, GLint)) +AGL_API(void, VertexAttribI2iEXT, (GLuint, GLint, GLint)) +AGL_API(void, VertexAttribI3iEXT, (GLuint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI4iEXT, (GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI1uiEXT, (GLuint, GLuint)) +AGL_API(void, VertexAttribI2uiEXT, (GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI3uiEXT, (GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI4uiEXT, (GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI1ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI2ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI3ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI4ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI1uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI2uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI3uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4bvEXT, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttribI4svEXT, (GLuint, const GLshort *)) +AGL_API(void, VertexAttribI4ubvEXT, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttribI4usvEXT, (GLuint, const GLushort *)) +AGL_API(void, VertexAttribIPointerEXT, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetVertexAttribIivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribIuivEXT, (GLuint, GLenum, GLint *)) +#endif +#endif + +#if defined _ALLEGRO_GL_GREMEDY_frame_terminator +AGL_API(void, FrameTerminatorGREMEDY, (void)) +#endif + +#if defined _ALLEGRO_GL_NV_conditional_render +AGL_API(void, BeginConditionalRenderNV, (GLuint, GLenum)) +AGL_API(void, EndConditionalRenderNV, (void)) +#endif + +#if defined _ALLEGRO_GL_EXT_transform_feedback +AGL_API(void, BeginTransformFeedbackEXT, (GLenum)) +AGL_API(void, EndTransformFeedbackEXT, (void)) +AGL_API(void, BindBufferRangeEXT, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) +AGL_API(void, BindBufferOffsetEXT, (GLenum, GLuint, GLuint, GLintptr)) +AGL_API(void, BindBufferBaseEXT, (GLenum, GLuint, GLuint)) +AGL_API(void, TransformFeedbackVaryingsEXT, (GLuint, GLsizei, const GLint *, GLenum)) +AGL_API(void, GetTransformFeedbackVaryingEXT, (GLuint, GLuint, GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_direct_state_access +AGL_API(void, ClientAttribDefaultEXT, (GLbitfield)) +AGL_API(void, PushClientAttribDefaultEXT, (GLbitfield)) +AGL_API(void, MatrixLoadfEXT, (GLenum, const GLfloat *)) +AGL_API(void, MatrixLoaddEXT, (GLenum, const GLdouble *)) +AGL_API(void, MatrixMultfEXT, (GLenum, const GLfloat *)) +AGL_API(void, MatrixMultdEXT, (GLenum, const GLdouble *)) +AGL_API(void, MatrixLoadIdentityEXT, (GLenum)) +AGL_API(void, MatrixRotatefEXT, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MatrixRotatedEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixScalefEXT, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MatrixScaledEXT, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixTranslatefEXT, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MatrixTranslatedEXT, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixFrustumEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixOrthoEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixPopEXT, (GLenum)) +AGL_API(void, MatrixPushEXT, (GLenum)) +AGL_API(void, MatrixLoadTransposefEXT, (GLenum, const GLfloat *)) +AGL_API(void, MatrixLoadTransposedEXT, (GLenum, const GLdouble *)) +AGL_API(void, MatrixMultTransposefEXT, (GLenum, const GLfloat *)) +AGL_API(void, MatrixMultTransposedEXT, (GLenum, const GLdouble *)) +AGL_API(void, TextureParameterfEXT, (GLuint, GLenum, GLenum, GLfloat)) +AGL_API(void, TextureParameterfvEXT, (GLuint, GLenum, GLenum, const GLfloat *)) +AGL_API(void, TextureParameteriEXT, (GLuint, GLenum, GLenum, GLint)) +AGL_API(void, TextureParameterivEXT, (GLuint, GLenum, GLenum, const GLint *)) +AGL_API(void, TextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyTextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) +AGL_API(void, CopyTextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) +AGL_API(void, CopyTextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei)) +AGL_API(void, CopyTextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, GetTextureImageEXT, (GLuint, GLenum, GLint, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetTextureParameterfvEXT, (GLuint, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetTextureParameterivEXT, (GLuint, GLenum, GLenum, GLint *)) +AGL_API(void, GetTextureLevelParameterfvEXT, (GLuint, GLenum, GLint, GLenum, GLfloat *)) +AGL_API(void, GetTextureLevelParameterivEXT, (GLuint, GLenum, GLint, GLenum, GLint *)) +AGL_API(void, TextureImage3DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyTextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, MultiTexParameterfEXT, (GLenum, GLenum, GLenum, GLfloat)) +AGL_API(void, MultiTexParameterfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) +AGL_API(void, MultiTexParameteriEXT, (GLenum, GLenum, GLenum, GLint)) +AGL_API(void, MultiTexParameterivEXT, (GLenum, GLenum, GLenum, const GLint *)) +AGL_API(void, MultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, MultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, MultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, MultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyMultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) +AGL_API(void, CopyMultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) +AGL_API(void, CopyMultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei)) +AGL_API(void, CopyMultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, GetMultiTexImageEXT, (GLenum, GLenum, GLint, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetMultiTexParameterfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMultiTexParameterivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetMultiTexLevelParameterfvEXT, (GLenum, GLenum, GLint, GLenum, GLfloat *)) +AGL_API(void, GetMultiTexLevelParameterivEXT, (GLenum, GLenum, GLint, GLenum, GLint *)) +AGL_API(void, MultiTexImage3DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, MultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyMultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, BindMultiTextureEXT, (GLenum, GLenum, GLuint)) +AGL_API(void, EnableClientStateIndexedEXT, (GLenum, GLuint)) +AGL_API(void, DisableClientStateIndexedEXT, (GLenum, GLuint)) +AGL_API(void, MultiTexCoordPointerEXT, (GLenum, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, MultiTexEnvfEXT, (GLenum, GLenum, GLenum, GLfloat)) +AGL_API(void, MultiTexEnvfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) +AGL_API(void, MultiTexEnviEXT, (GLenum, GLenum, GLenum, GLint)) +AGL_API(void, MultiTexEnvivEXT, (GLenum, GLenum, GLenum, const GLint *)) +AGL_API(void, MultiTexGendEXT, (GLenum, GLenum, GLenum, GLdouble)) +AGL_API(void, MultiTexGendvEXT, (GLenum, GLenum, GLenum, const GLdouble *)) +AGL_API(void, MultiTexGenfEXT, (GLenum, GLenum, GLenum, GLfloat)) +AGL_API(void, MultiTexGenfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) +AGL_API(void, MultiTexGeniEXT, (GLenum, GLenum, GLenum, GLint)) +AGL_API(void, MultiTexGenivEXT, (GLenum, GLenum, GLenum, const GLint *)) +AGL_API(void, GetMultiTexEnvfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMultiTexEnvivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetMultiTexGendvEXT, (GLenum, GLenum, GLenum, GLdouble *)) +AGL_API(void, GetMultiTexGenfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMultiTexGenivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetFloatIndexedvEXT, (GLenum, GLuint, GLfloat *)) +AGL_API(void, GetDoubleIndexedvEXT, (GLenum, GLuint, GLdouble *)) +AGL_API(void, GetPointerIndexedvEXT, (GLenum, GLuint, GLvoid* *)) +AGL_API(void, CompressedTextureImage3DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetCompressedTextureImageEXT, (GLuint, GLenum, GLint, GLvoid *)) +AGL_API(void, CompressedMultiTexImage3DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetCompressedMultiTexImageEXT, (GLenum, GLenum, GLint, GLvoid *)) +AGL_API(void, NamedProgramStringEXT, (GLuint, GLenum, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, NamedProgramLocalParameter4dEXT, (GLuint, GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, NamedProgramLocalParameter4dvEXT, (GLuint, GLenum, GLuint, const GLdouble *)) +AGL_API(void, NamedProgramLocalParameter4fEXT, (GLuint, GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, NamedProgramLocalParameter4fvEXT, (GLuint, GLenum, GLuint, const GLfloat *)) +AGL_API(void, GetNamedProgramLocalParameterdvEXT, (GLuint, GLenum, GLuint, GLdouble *)) +AGL_API(void, GetNamedProgramLocalParameterfvEXT, (GLuint, GLenum, GLuint, GLfloat *)) +AGL_API(void, GetNamedProgramivEXT, (GLuint, GLenum, GLenum, GLint *)) +AGL_API(void, GetNamedProgramStringEXT, (GLuint, GLenum, GLenum, GLvoid *)) +AGL_API(void, NamedProgramLocalParameters4fvEXT, (GLuint, GLenum, GLuint, GLsizei, const GLfloat *)) +AGL_API(void, NamedProgramLocalParameterI4iEXT, (GLuint, GLenum, GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, NamedProgramLocalParameterI4ivEXT, (GLuint, GLenum, GLuint, const GLint *)) +AGL_API(void, NamedProgramLocalParametersI4ivEXT, (GLuint, GLenum, GLuint, GLsizei, const GLint *)) +AGL_API(void, NamedProgramLocalParameterI4uiEXT, (GLuint, GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, NamedProgramLocalParameterI4uivEXT, (GLuint, GLenum, GLuint, const GLuint *)) +AGL_API(void, NamedProgramLocalParametersI4uivEXT, (GLuint, GLenum, GLuint, GLsizei, const GLuint *)) +AGL_API(void, GetNamedProgramLocalParameterIivEXT, (GLuint, GLenum, GLuint, GLint *)) +AGL_API(void, GetNamedProgramLocalParameterIuivEXT, (GLuint, GLenum, GLuint, GLuint *)) +AGL_API(void, TextureParameterIivEXT, (GLuint, GLenum, GLenum, const GLint *)) +AGL_API(void, TextureParameterIuivEXT, (GLuint, GLenum, GLenum, const GLuint *)) +AGL_API(void, GetTextureParameterIivEXT, (GLuint, GLenum, GLenum, GLint *)) +AGL_API(void, GetTextureParameterIuivEXT, (GLuint, GLenum, GLenum, GLuint *)) +AGL_API(void, MultiTexParameterIivEXT, (GLenum, GLenum, GLenum, const GLint *)) +AGL_API(void, MultiTexParameterIuivEXT, (GLenum, GLenum, GLenum, const GLuint *)) +AGL_API(void, GetMultiTexParameterIivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetMultiTexParameterIuivEXT, (GLenum, GLenum, GLenum, GLuint *)) +AGL_API(void, ProgramUniform1fEXT, (GLuint, GLint, GLfloat)) +AGL_API(void, ProgramUniform2fEXT, (GLuint, GLint, GLfloat, GLfloat)) +AGL_API(void, ProgramUniform3fEXT, (GLuint, GLint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramUniform4fEXT, (GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramUniform1iEXT, (GLuint, GLint, GLint)) +AGL_API(void, ProgramUniform2iEXT, (GLuint, GLint, GLint, GLint)) +AGL_API(void, ProgramUniform3iEXT, (GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, ProgramUniform4iEXT, (GLuint, GLint, GLint, GLint, GLint, GLint)) +AGL_API(void, ProgramUniform1fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramUniform2fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramUniform3fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramUniform4fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramUniform1ivEXT, (GLuint, GLint, GLsizei, const GLint *)) +AGL_API(void, ProgramUniform2ivEXT, (GLuint, GLint, GLsizei, const GLint *)) +AGL_API(void, ProgramUniform3ivEXT, (GLuint, GLint, GLsizei, const GLint *)) +AGL_API(void, ProgramUniform4ivEXT, (GLuint, GLint, GLsizei, const GLint *)) +AGL_API(void, ProgramUniformMatrix2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix2x3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix3x2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix2x4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix4x2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix3x4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix4x3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniform1uiEXT, (GLuint, GLint, GLuint)) +AGL_API(void, ProgramUniform2uiEXT, (GLuint, GLint, GLuint, GLuint)) +AGL_API(void, ProgramUniform3uiEXT, (GLuint, GLint, GLuint, GLuint, GLuint)) +AGL_API(void, ProgramUniform4uiEXT, (GLuint, GLint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ProgramUniform1uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) +AGL_API(void, ProgramUniform2uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) +AGL_API(void, ProgramUniform3uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) +AGL_API(void, ProgramUniform4uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) +AGL_API(void, NamedBufferDataEXT, (GLuint, GLsizeiptr, const GLvoid *, GLenum)) +AGL_API(void, NamedBufferSubDataEXT, (GLuint, GLintptr, GLsizeiptr, const GLvoid *)) +AGL_API(GLvoid*, MapNamedBufferEXT, (GLuint, GLenum)) +AGL_API(GLboolean, UnmapNamedBufferEXT, (GLuint)) +AGL_API(void, GetNamedBufferParameterivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetNamedBufferPointervEXT, (GLuint, GLenum, GLvoid* *)) +AGL_API(void, GetNamedBufferSubDataEXT, (GLuint, GLintptr, GLsizeiptr, GLvoid *)) +AGL_API(void, TextureBufferEXT, (GLuint, GLenum, GLenum, GLuint)) +AGL_API(void, MultiTexBufferEXT, (GLenum, GLenum, GLenum, GLuint)) +AGL_API(void, NamedRenderbufferStorageEXT, (GLuint, GLenum, GLsizei, GLsizei)) +AGL_API(void, GetNamedRenderbufferParameterivEXT, (GLuint, GLenum, GLint *)) +AGL_API(GLenum, CheckNamedFramebufferStatusEXT, (GLuint, GLenum)) +AGL_API(void, NamedFramebufferTexture1DEXT, (GLuint, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, NamedFramebufferTexture2DEXT, (GLuint, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, NamedFramebufferTexture3DEXT, (GLuint, GLenum, GLenum, GLuint, GLint, GLint)) +AGL_API(void, NamedFramebufferRenderbufferEXT, (GLuint, GLenum, GLenum, GLuint)) +AGL_API(void, GetNamedFramebufferAttachmentParameterivEXT, (GLuint, GLenum, GLenum, GLint *)) +AGL_API(void, GenerateTextureMipmapEXT, (GLuint, GLenum)) +AGL_API(void, GenerateMultiTexMipmapEXT, (GLenum, GLenum)) +AGL_API(void, FramebufferDrawBufferEXT, (GLuint, GLenum)) +AGL_API(void, FramebufferDrawBuffersEXT, (GLuint, GLsizei, const GLenum *)) +AGL_API(void, FramebufferReadBufferEXT, (GLuint, GLenum)) +AGL_API(void, GetFramebufferParameterivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, NamedRenderbufferStorageMultisampleEXT, (GLuint, GLsizei, GLenum, GLsizei, GLsizei)) +AGL_API(void, NamedRenderbufferStorageMultisampleCoverageEXT, (GLuint, GLsizei, GLsizei, GLenum, GLsizei, GLsizei)) +AGL_API(void, NamedFramebufferTextureEXT, (GLuint, GLenum, GLuint, GLint)) +AGL_API(void, NamedFramebufferTextureLayerEXT, (GLuint, GLenum, GLuint, GLint, GLint)) +AGL_API(void, NamedFramebufferTextureFaceEXT, (GLuint, GLenum, GLuint, GLint, GLenum)) +AGL_API(void, TextureRenderbufferEXT, (GLuint, GLenum, GLuint)) +AGL_API(void, MultiTexRenderbufferEXT, (GLenum, GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_NV_explicit_multisample +AGL_API(void, GetMultisamplefvNV, (GLenum, GLuint, GLfloat *)) +AGL_API(void, SampleMaskIndexedNV, (GLuint, GLbitfield)) +AGL_API(void, TexRenderbufferNV, (GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_NV_transform_feedback2 +AGL_API(void, BindTransformFeedbackNV, (GLenum, GLuint)) +AGL_API(void, DeleteTransformFeedbacksNV, (GLsizei, const GLuint *)) +AGL_API(void, GenTransformFeedbacksNV, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsTransformFeedbackNV, (GLuint)) +AGL_API(void, PauseTransformFeedbackNV, (void)) +AGL_API(void, ResumeTransformFeedbackNV, (void)) +AGL_API(void, DrawTransformFeedbackNV, (GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_AMD_performance_monitor +AGL_API(void, GetPerfMonitorGroupsAMD, (GLint *, GLsizei, GLuint *)) +AGL_API(void, GetPerfMonitorCountersAMD, (GLuint, GLint *, GLint *, GLsizei, GLuint *)) +AGL_API(void, GetPerfMonitorGroupStringAMD, (GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, GetPerfMonitorCounterStringAMD, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, GetPerfMonitorCounterInfoAMD, (GLuint, GLuint, GLenum, void *)) +AGL_API(void, GenPerfMonitorsAMD, (GLsizei, GLuint *)) +AGL_API(void, DeletePerfMonitorsAMD, (GLsizei, GLuint *)) +AGL_API(void, SelectPerfMonitorCountersAMD, (GLuint, GLboolean, GLuint, GLint, GLuint *)) +AGL_API(void, BeginPerfMonitorAMD, (GLuint)) +AGL_API(void, EndPerfMonitorAMD, (GLuint)) +AGL_API(void, GetPerfMonitorCounterDataAMD, (GLuint, GLenum, GLsizei, GLuint *, GLint *)) +#endif + +#if defined _ALLEGRO_GL_AMD_vertex_shader_tesselator +AGL_API(void, TessellationFactorAMD, (GLfloat)) +AGL_API(void, TessellationModeAMD, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_provoking_vertex +AGL_API(void, ProvokingVertexEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_AMD_draw_buffers_blend +AGL_API(void, BlendFuncIndexedAMD, (GLuint buf, GLenum src, GLenum dst)) +AGL_API(void, BlendFuncSeparateIndexedAMD, (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)) +AGL_API(void, BlendEquationIndexedAMD, (GLuint buf, GLenum mode)) +AGL_API(void, BlendEquationSeparateIndexedAMD, (GLuint buf, GLenum modeRGB, GLenum modeAlpha)) +#endif + +#if defined _ALLEGRO_GL_APPLE_texture_range +AGL_API(void, TextureRangeAPPLE, (GLenum target, GLsizei length, const GLvoid *pointer)) +AGL_API(void, GetTexParameterPointervAPPLE, (GLenum target, GLenum pname, GLvoid* *params)) +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_program_evaluators +AGL_API(void, EnableVertexAttribAPPLE, (GLuint index, GLenum pname)) +AGL_API(void, DisableVertexAttribAPPLE, (GLuint index, GLenum pname)) +AGL_API(GLboolean, IsVertexAttribEnabledAPPLE, (GLuint index, GLenum pname)) +AGL_API(void, MapVertexAttrib1dAPPLE, (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)) +AGL_API(void, MapVertexAttrib1fAPPLE, (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)) +AGL_API(void, MapVertexAttrib2dAPPLE, (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)) +AGL_API(void, MapVertexAttrib2fAPPLE, (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)) +#endif + +#if defined _ALLEGRO_GL_APPLE_object_purgeable +AGL_API(GLenum, ObjectPurgeableAPPLE, (GLenum objectType, GLuint name, GLenum option)) +AGL_API(GLenum, ObjectUnpurgeableAPPLE, (GLenum objectType, GLuint name, GLenum option)) +AGL_API(void, GetObjectParameterivAPPLE, (GLenum objectType, GLuint name, GLenum pname, GLint *params)) +#endif + +#if defined _ALLEGRO_GL_NV_video_capture +AGL_API(void, BeginVideoCaptureNV, (GLuint video_capture_slot)) +AGL_API(void, BindVideoCaptureStreamBufferNV, (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset)) +AGL_API(void, BindVideoCaptureStreamTextureNV, (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture)) +AGL_API(void, EndVideoCaptureNV, (GLuint video_capture_slot)) +AGL_API(void, GetVideoCaptureivNV, (GLuint video_capture_slot, GLenum pname, GLint *params)) +AGL_API(void, GetVideoCaptureStreamivNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params)) +AGL_API(void, GetVideoCaptureStreamfvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params)) +AGL_API(void, GetVideoCaptureStreamdvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params)) +AGL_API(GLenum, VideoCaptureNV, (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time)) +AGL_API(void, VideoCaptureStreamParameterivNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params)) +AGL_API(void, VideoCaptureStreamParameterfvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params)) +AGL_API(void, VideoCaptureStreamParameterdvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params)) +#endif + +#if defined _ALLEGRO_GL_EXT_separate_shader_objects +AGL_API(void, UseShaderProgramEXT, (GLenum type, GLuint program)) +AGL_API(void, ActiveProgramEXT, (GLuint program)) +AGL_API(GLuint, CreateShaderProgramEXT, (GLenum type, const GLchar *string)) +#endif + +#if defined _ALLEGRO_GL_NV_shader_buffer_load +AGL_API(void, MakeBufferResidentNV, (GLenum target, GLenum access)) +AGL_API(void, MakeBufferNonResidentNV, (GLenum target)) +AGL_API(GLboolean, IsBufferResidentNV, (GLenum target)) +AGL_API(void, MakeNamedBufferResidentNV, (GLuint buffer, GLenum access)) +AGL_API(void, MakeNamedBufferNonResidentNV, (GLuint buffer)) +AGL_API(GLboolean, IsNamedBufferResidentNV, (GLuint buffer)) +AGL_API(void, GetBufferParameterui64vNV, (GLenum target, GLenum pname, GLuint64EXT *params)) +AGL_API(void, GetNamedBufferParameterui64vNV, (GLuint buffer, GLenum pname, GLuint64EXT *params)) +AGL_API(void, GetIntegerui64vNV, (GLenum value, GLuint64EXT *result)) +AGL_API(void, Uniformui64NV, (GLint location, GLuint64EXT value)) +AGL_API(void, Uniformui64vNV, (GLint location, GLsizei count, const GLuint64EXT *value)) +AGL_API(void, GetUniformui64vNV, (GLuint program, GLint location, GLuint64EXT *params)) +AGL_API(void, ProgramUniformui64NV, (GLuint program, GLint location, GLuint64EXT value)) +AGL_API(void, ProgramUniformui64vNV, (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value)) +#endif + +#if defined _ALLEGRO_GL_NV_vertex_buffer_unified_memory +AGL_API(void, BufferAddressRangeNV, (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length)) +AGL_API(void, VertexFormatNV, (GLint size, GLenum type, GLsizei stride)) +AGL_API(void, NormalFormatNV, (GLenum type, GLsizei stride)) +AGL_API(void, ColorFormatNV, (GLint size, GLenum type, GLsizei stride)) +AGL_API(void, IndexFormatNV, (GLenum type, GLsizei stride)) +AGL_API(void, TexCoordFormatNV, (GLint size, GLenum type, GLsizei stride)) +AGL_API(void, EdgeFlagFormatNV, (GLsizei stride)) +AGL_API(void, SecondaryColorFormatNV, (GLint size, GLenum type, GLsizei stride)) +AGL_API(void, FogCoordFormatNV, (GLenum type, GLsizei stride)) +AGL_API(void, VertexAttribFormatNV, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride)) +AGL_API(void, VertexAttribIFormatNV, (GLuint index, GLint size, GLenum type, GLsizei stride)) +AGL_API(void, GetIntegerui64i_vNV, (GLenum value, GLuint index, GLuint64EXT *result)) +#endif + +#if defined _ALLEGRO_GL_NV_texture_barrier +AGL_API(void, TextureBarrierNV, (void)) +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_defs.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_defs.h new file mode 100644 index 00000000..855963be --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_defs.h @@ -0,0 +1,5108 @@ +/* */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#define _ALLEGRO_GL_VERSION_1_2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#endif + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging +#define _ALLEGRO_GL_ARB_imaging +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#endif + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#define _ALLEGRO_GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#endif + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#define _ALLEGRO_GL_VERSION_1_4 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#endif + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#define _ALLEGRO_GL_VERSION_1_5 +/* New types */ +#include +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +/* Renamed enumerants */ +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +/* Promoted exts */ +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#endif + + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +#define _ALLEGRO_GL_VERSION_2_0 +/* New types */ +typedef char GLchar; + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#endif + + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#define _ALLEGRO_GL_VERSION_2_1 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#endif + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 +#define _ALLEGRO_GL_VERSION_3_0 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#endif + +#ifndef GL_VERSION_3_0_DEPRECATED +#define GL_VERSION_3_0_DEPRECATED +#define _ALLEGRO_GL_VERSION_3_0_DEPRECATED +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_ALPHA_INTEGER 0x8D97 +/* Reuse tokens from ARB_framebuffer_object */ +/* reuse GL_TEXTURE_LUMINANCE_TYPE */ +/* reuse GL_TEXTURE_INTENSITY_TYPE */ +#endif + + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 +#define _ALLEGRO_GL_VERSION_3_1 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#endif + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 +#define _ALLEGRO_GL_VERSION_3_2 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#endif + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 +#define _ALLEGRO_GL_VERSION_3_3 +#endif + + + +/* */ +/* */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture +#define _ALLEGRO_GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix +#define _ALLEGRO_GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample +#define _ALLEGRO_GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map +#define _ALLEGRO_GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression +#define _ALLEGRO_GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp +#define _ALLEGRO_GL_ARB_texture_border_clamp +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters +#define _ALLEGRO_GL_ARB_point_parameters +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend +#define _ALLEGRO_GL_ARB_vertex_blend +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette +#define _ALLEGRO_GL_ARB_matrix_palette +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine +#define _ALLEGRO_GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 +#define _ALLEGRO_GL_ARB_texture_env_dot3 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat +#define _ALLEGRO_GL_ARB_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture +#define _ALLEGRO_GL_ARB_depth_texture +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos +#define _ALLEGRO_GL_ARB_window_pos +#endif + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow +#define _ALLEGRO_GL_ARB_shadow +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient +#define _ALLEGRO_GL_ARB_shadow_ambient +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program +#define _ALLEGRO_GL_ARB_vertex_program +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#endif + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program +#define _ALLEGRO_GL_ARB_fragment_program +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object +#define _ALLEGRO_GL_ARB_vertex_buffer_object +#include +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query +#define _ALLEGRO_GL_ARB_occlusion_query +#define GL_SAMPLES_PASSED_ARB 0x8914 +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#endif + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects +#define _ALLEGRO_GL_ARB_shader_objects +typedef char GLcharARB; +typedef unsigned long GLhandleARB; +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#define GL_SHADER_OBJECT_ARB 0x8B48 +/* GL_FLOAT */ +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +/* GL_INT */ +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#endif + + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader +#define _ALLEGRO_GL_ARB_vertex_shader +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#if !defined GL_ARB_shader_objects +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#endif +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#if !defined GL_ARB_shader_objects +#define GL_SHADER_OBJECT_ARB 0x8B48 +#endif +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#if !defined GL_ARB_shader_objects +/* GL_FLOAT */ +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#endif +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader +#define _ALLEGRO_GL_ARB_fragment_shader +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#if !defined GL_ARB_shader_objects && !defined GL_ARB_vertex_shader +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_SHADER_OBJECT_ARB 0x8B48 +#endif +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 +#define _ALLEGRO_GL_ARB_shading_language_100 +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two +#define _ALLEGRO_GL_ARB_texture_non_power_of_two +#endif + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite +#define _ALLEGRO_GL_ARB_point_sprite +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +/* GL_FALSE */ +/* GL_TRUE */ +#endif + + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers +#define _ALLEGRO_GL_ARB_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#endif + + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle +#define _ALLEGRO_GL_ARB_texture_rectangle +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif +#ifdef ALLEGRO_MACOSX +#ifndef GL_EXT_texture_rectangle +#define GL_EXT_texture_rectangle +#define _ALLEGRO_GL_EXT_texture_rectangle +#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 +#endif +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float +#define _ALLEGRO_GL_ARB_color_buffer_float +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +#endif + + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel +#define _ALLEGRO_GL_ARB_half_float_pixel +#define GL_HALF_FLOAT_ARB 0x140B +#endif + + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float +#define _ALLEGRO_GL_ARB_texture_float +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object +#define _ALLEGRO_GL_ARB_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float +#define _ALLEGRO_GL_ARB_depth_buffer_float +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#endif + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced +#define _ALLEGRO_GL_ARB_draw_instanced +#endif + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object +#define _ALLEGRO_GL_ARB_framebuffer_object +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_INDEX 0x8222 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#endif + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB +#define _ALLEGRO_GL_ARB_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#endif + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 +#define _ALLEGRO_GL_ARB_geometry_shader4 +#define GL_LINES_ADJACENCY_ARB 0x000A +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B +#define GL_TRIANGLES_ADJACENCY_ARB 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 +/* reuse GL_MAX_VARYING_COMPONENTS */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ +#endif + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex +#define _ALLEGRO_GL_ARB_half_float_vertex +#define GL_HALF_FLOAT 0x140B +#endif + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays +#define _ALLEGRO_GL_ARB_instanced_arrays +#endif + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range +#define _ALLEGRO_GL_ARB_map_buffer_range +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#endif + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object +#define _ALLEGRO_GL_ARB_texture_buffer_object +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E +#endif + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc +#define _ALLEGRO_GL_ARB_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg +#define _ALLEGRO_GL_ARB_texture_rg +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#endif + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object +#define _ALLEGRO_GL_ARB_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#endif + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object +#define _ALLEGRO_GL_ARB_uniform_buffer_object +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#endif + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility +#define _ALLEGRO_GL_ARB_compatibility +/* ARB_compatibility just defines tokens from core 3.0 */ +#endif + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer +#define _ALLEGRO_GL_ARB_copy_buffer +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#endif + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod +#define _ALLEGRO_GL_ARB_shader_texture_lod +#endif + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp +#define _ALLEGRO_GL_ARB_depth_clamp +#define GL_DEPTH_CLAMP 0x864F +#endif + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex +#define _ALLEGRO_GL_ARB_draw_elements_base_vertex +#endif + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions +#define _ALLEGRO_GL_ARB_fragment_coord_conventions +#endif + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex +#define _ALLEGRO_GL_ARB_provoking_vertex +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#endif + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map +#define _ALLEGRO_GL_ARB_seamless_cube_map +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#endif + +#ifndef GL_ARB_sync +#define GL_ARB_sync +#define _ALLEGRO_GL_ARB_sync +#if (defined _MSC_VER) && (_MSC_VER < 1400) +typedef __int64 GLint64; +typedef unsigned __int64 GLuint64; +#else +typedef int64_t GLint64; +typedef uint64_t GLuint64; +#endif +typedef struct __GLsync *GLsync; +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#endif + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample +#define _ALLEGRO_GL_ARB_texture_multisample +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#endif + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra +#define _ALLEGRO_GL_ARB_vertex_array_bgra +/* reuse GL_BGRA */ +#endif + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend +#define _ALLEGRO_GL_ARB_draw_buffers_blend +#endif + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading +#define _ALLEGRO_GL_ARB_sample_shading +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#endif + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array +#define _ALLEGRO_GL_ARB_texture_cube_map_array +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#endif + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather +#define _ALLEGRO_GL_ARB_texture_gather +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#endif + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod +#define _ALLEGRO_GL_ARB_texture_query_lod +#endif + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include +#define _ALLEGRO_GL_ARB_shading_language_include +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA +#endif + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc +#define _ALLEGRO_GL_ARB_texture_compression_bptc +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended +#define _ALLEGRO_GL_ARB_blend_func_extended +#define GL_SRC1_COLOR 0x88F9 +/* reuse GL_SRC1_ALPHA */ +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#endif + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location +#define _ALLEGRO_GL_ARB_explicit_attrib_location +#endif + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 +#define _ALLEGRO_GL_ARB_occlusion_query2 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#endif + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects +#define _ALLEGRO_GL_ARB_sampler_objects +#define GL_SAMPLER_BINDING 0x8919 +#endif + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding +#define _ALLEGRO_GL_ARB_shader_bit_encoding +#endif + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui +#define _ALLEGRO_GL_ARB_texture_rgb10_a2ui +#define GL_RGB10_A2UI 0x906F +#endif + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle +#define _ALLEGRO_GL_ARB_texture_swizzle +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#endif + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query +#define _ALLEGRO_GL_ARB_timer_query +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 +#endif + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev +#define _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev +/* reuse GL_UNSIGNED_INT_2_10_10_10_REV */ +#define GL_INT_2_10_10_10_REV 0x8D9F +#endif + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect +#define _ALLEGRO_GL_ARB_draw_indirect +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#endif + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 +#define _ALLEGRO_GL_ARB_gpu_shader5 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#endif + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 +#define _ALLEGRO_GL_ARB_gpu_shader_fp64 +/* reuse GL_DOUBLE */ +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#endif + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine +#define _ALLEGRO_GL_ARB_shader_subroutine +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +/* reuse GL_UNIFORM_SIZE */ +/* reuse GL_UNIFORM_NAME_LENGTH */ +#endif + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader +#define _ALLEGRO_GL_ARB_tessellation_shader +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +/* reuse GL_TRIANGLES */ +/* reuse GL_QUADS */ +#define GL_ISOLINES 0x8E7A +/* reuse GL_EQUAL */ +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +/* reuse GL_CCW */ +/* reuse GL_CW */ +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#endif + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 +#define _ALLEGRO_GL_ARB_texture_buffer_object_rgb32 +/* reuse GL_RGB32F */ +/* reuse GL_RGB32UI */ +/* reuse GL_RGB32I */ +#endif + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 +#define _ALLEGRO_GL_ARB_transform_feedback2 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#endif + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 +#define _ALLEGRO_GL_ARB_transform_feedback3 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#endif + + +/* */ + + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr +#define _ALLEGRO_GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color +#define _ALLEGRO_GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset +#define _ALLEGRO_GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture +#define _ALLEGRO_GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D +#define _ALLEGRO_GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 +#define _ALLEGRO_GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram +#define _ALLEGRO_GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture +#define _ALLEGRO_GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture +/* NV's headers don't define EXT_copy_texture yet provide the API */ +#ifndef ALLEGRO_GL_HEADER_NV +#define _ALLEGRO_GL_EXT_copy_texture +#endif +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram +#define _ALLEGRO_GL_EXT_histogram +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution +#define _ALLEGRO_GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix +#define _ALLEGRO_GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table +#define _ALLEGRO_GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture +#define _ALLEGRO_GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture +#define _ALLEGRO_GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D +#define _ALLEGRO_GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table +#define _ALLEGRO_GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka +#define _ALLEGRO_GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object +#define _ALLEGRO_GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture +#define _ALLEGRO_GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture +#define _ALLEGRO_GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels +#define _ALLEGRO_GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod +#define _ALLEGRO_GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample +#define _ALLEGRO_GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal +#define _ALLEGRO_GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array +#define _ALLEGRO_GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap +#define _ALLEGRO_GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap +#define _ALLEGRO_GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow +#define _ALLEGRO_GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp +#define _ALLEGRO_GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax +#define _ALLEGRO_GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract +#define _ALLEGRO_GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace +#define _ALLEGRO_GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles +#define _ALLEGRO_GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select +#define _ALLEGRO_GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite +#define _ALLEGRO_GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer +#define _ALLEGRO_GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters +#define _ALLEGRO_GL_EXT_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters +#define _ALLEGRO_GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments +#define _ALLEGRO_GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias +#define _ALLEGRO_GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom +#define _ALLEGRO_GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_FfdMaskSGIX +#define GL_FfdMaskSGIX +#define _ALLEGRO_GL_FfdMaskSGIX +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer +#define _ALLEGRO_GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd +#define _ALLEGRO_GL_SGIX_polynomial_ffd +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane +#define _ALLEGRO_GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture +#define _ALLEGRO_GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster +#define _ALLEGRO_GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function +#define _ALLEGRO_GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset +#define _ALLEGRO_GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform +#define _ALLEGRO_GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes +#define _ALLEGRO_GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env +#define _ALLEGRO_GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable +#define _ALLEGRO_GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints +#define _ALLEGRO_GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints +#define _ALLEGRO_GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture +#define _ALLEGRO_GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint +#define _ALLEGRO_GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority +#define _ALLEGRO_GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 +#define _ALLEGRO_GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment +#define _ALLEGRO_GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias +#define _ALLEGRO_GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient +#define _ALLEGRO_GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material +#define _ALLEGRO_GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func +#define _ALLEGRO_GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats +#define _ALLEGRO_GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array +#define _ALLEGRO_GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex +#define _ALLEGRO_GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb +#define _ALLEGRO_GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting +#define _ALLEGRO_GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip +#define _ALLEGRO_GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting +#define _ALLEGRO_GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements +#define _ALLEGRO_GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading +#define _ALLEGRO_GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog +#define _ALLEGRO_GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture +#define _ALLEGRO_GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#ifndef GL_FRAGMENT_DEPTH_EXT +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#endif +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax +#define _ALLEGRO_GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_SGIX_impact_pixel_texture +#define _ALLEGRO_GL_SGIX_impact_pixel_texture +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra +#define _ALLEGRO_GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_SGIX_async +#define GL_SGIX_async +#define _ALLEGRO_GL_SGIX_async +#define GL_ASYNC_MARKER_SGIX 0x8329 +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel +#define _ALLEGRO_GL_SGIX_async_pixel +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram +#define _ALLEGRO_GL_SGIX_async_histogram +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays +#define _ALLEGRO_GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test +#define _ALLEGRO_GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform +#define _ALLEGRO_GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette +#define _ALLEGRO_GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color +#define _ALLEGRO_GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color +#define _ALLEGRO_GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal +#define _ALLEGRO_GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays +#define _ALLEGRO_GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord +#define _ALLEGRO_GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates +#define _ALLEGRO_GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame +#define _ALLEGRO_GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine +#define _ALLEGRO_GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector +#define _ALLEGRO_GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint +#define _ALLEGRO_GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale +#define _ALLEGRO_GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data +#define _ALLEGRO_GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha +#define _ALLEGRO_GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list +#define _ALLEGRO_GL_SUN_triangle_list +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex +#define _ALLEGRO_GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate +#define _ALLEGRO_GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp +#define _ALLEGRO_GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate +#define _ALLEGRO_GL_INGR_blend_func_separate +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read +#define _ALLEGRO_GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap +#define _ALLEGRO_GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels +#define _ALLEGRO_GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection +#define _ALLEGRO_GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map +#define _ALLEGRO_GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes +#define _ALLEGRO_GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias +#define _ALLEGRO_GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic +#define _ALLEGRO_GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting +#define _ALLEGRO_GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent +#define _ALLEGRO_GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range +#define _ALLEGRO_GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners +#define _ALLEGRO_GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* GL_TEXTURE0_ARB */ +/* GL_TEXTURE1_ARB */ +/* GL_ZERO */ +/* GL_NONE */ +/* GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance +#define _ALLEGRO_GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss +#define _ALLEGRO_GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 +#define _ALLEGRO_GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc +#define _ALLEGRO_GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers +#define _ALLEGRO_GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos +#define _ALLEGRO_GL_MESA_window_pos +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex +#define _ALLEGRO_GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays +#define _ALLEGRO_GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists +#define _ALLEGRO_GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample +#define _ALLEGRO_GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba +#define _ALLEGRO_GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_SGI_depth_pass_instrument +#define _ALLEGRO_GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 +#define _ALLEGRO_GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample +#define _ALLEGRO_GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer +#ifndef ALLEGRO_GL_HEADER_NV +#define _ALLEGRO_GL_3DFX_tbuffer +#endif +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample +#define _ALLEGRO_GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip +#define _ALLEGRO_GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy +#define _ALLEGRO_GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample +#define _ALLEGRO_GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen +#define _ALLEGRO_GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask +#ifndef ALLEGRO_GL_HEADER_NV +#define _ALLEGRO_GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif +#endif + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface +#define _ALLEGRO_GL_SGIX_igloo_interface +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 +#define _ALLEGRO_GL_EXT_texture_env_dot3 +/* GL_DOT3_RGB_EXT */ +/* GL_DOT3_RGBA_EXT */ +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once +#define _ALLEGRO_GL_ATI_texture_mirror_once +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif + +#ifndef GL_NV_fence +#define GL_NV_fence +#define _ALLEGRO_GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat +#define _ALLEGRO_GL_IBM_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators +#define _ALLEGRO_GL_NV_evaluators +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil +#define _ALLEGRO_GL_NV_packed_depth_stencil +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 +#define _ALLEGRO_GL_NV_register_combiners2 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle +#define _ALLEGRO_GL_NV_texture_rectangle +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader +#define _ALLEGRO_GL_NV_texture_shader +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 +#define _ALLEGRO_GL_NV_texture_shader2 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 +#define _ALLEGRO_GL_NV_vertex_array_range2 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program +#define _ALLEGRO_GL_NV_vertex_program +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp +#define _ALLEGRO_GL_SGIX_texture_coordinate_clamp +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint +#define _ALLEGRO_GL_SGIX_scalebias_hint +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif + +#ifndef GL_OML_interlace +#define GL_OML_interlace +#define _ALLEGRO_GL_OML_interlace +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif + +#ifndef GL_OML_subsample +#define GL_OML_subsample +#define _ALLEGRO_GL_OML_subsample +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif + +#ifndef GL_OML_resample +#define GL_OML_resample +#define _ALLEGRO_GL_OML_resample +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color +#define _ALLEGRO_GL_NV_copy_depth_to_color +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap +#define _ALLEGRO_GL_ATI_envmap_bumpmap +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader +#define _ALLEGRO_GL_ATI_fragment_shader +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles +#define _ALLEGRO_GL_ATI_pn_triangles +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object +#define _ALLEGRO_GL_ATI_vertex_array_object +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader +#define _ALLEGRO_GL_EXT_vertex_shader +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams +#define _ALLEGRO_GL_ATI_vertex_streams +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#endif + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array +#define _ALLEGRO_GL_ATI_element_array +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#endif + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array +#define _ALLEGRO_GL_SUN_mesh_array +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum +#define _ALLEGRO_GL_SUN_slice_accum +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint +#define _ALLEGRO_GL_NV_multisample_filter_hint +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp +#define _ALLEGRO_GL_NV_depth_clamp +#define GL_DEPTH_CLAMP_NV 0x864F +#endif + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query +#define _ALLEGRO_GL_NV_occlusion_query +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#endif + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite +#define _ALLEGRO_GL_NV_point_sprite +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 +#define _ALLEGRO_GL_NV_texture_shader3 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side +#define _ALLEGRO_GL_EXT_stencil_two_side +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader +#define _ALLEGRO_GL_ATI_text_fragment_shader +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage +#define _ALLEGRO_GL_APPLE_client_storage +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array +#define _ALLEGRO_GL_APPLE_element_array +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A +#endif + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence +#define _ALLEGRO_GL_APPLE_fence +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object +#define _ALLEGRO_GL_APPLE_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range +#define _ALLEGRO_GL_APPLE_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 +#define _ALLEGRO_GL_APPLE_ycbcr_422 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc +#define _ALLEGRO_GL_S3_s3tc +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers +#define _ALLEGRO_GL_ATI_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 +#define _ALLEGRO_GL_ATI_texture_env_combine3 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float +#define _ALLEGRO_GL_ATI_texture_float +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer +#define _ALLEGRO_GL_NV_float_buffer +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program +#define _ALLEGRO_GL_NV_fragment_program +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#endif + +#ifndef GL_NV_half_float +#define GL_NV_half_float +#define _ALLEGRO_GL_NV_half_float +typedef short GLhalfNV; +#define GL_HALF_FLOAT_NV 0x140B +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range +#define _ALLEGRO_GL_NV_pixel_data_range +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#endif + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart +#define _ALLEGRO_GL_NV_primitive_restart +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal +#define _ALLEGRO_GL_NV_texture_expand_normal +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer +#define _ALLEGRO_GL_ATI_map_object_buffer +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object +#define _ALLEGRO_GL_ATI_vertex_attrib_array_object +#endif + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates +#define _ALLEGRO_GL_OES_byte_coordinates +/* GL_BYTE */ +#endif + +#ifndef GL_OES_fixed_point +#define GL_OES_fixed_point +#define _ALLEGRO_GL_OES_fixed_point +typedef int GLfixed; +typedef int GLclampx; +#define GL_FIXED_OES 0x140C +#endif + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision +#define _ALLEGRO_GL_OES_single_precision +#endif + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture +#define _ALLEGRO_GL_OES_compressed_paletted_texture +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + +#ifndef GL_OES_read_format +#define GL_OES_read_format +#define _ALLEGRO_GL_OES_read_format +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif + +#ifndef GL_OES_query_matrix +#define GL_OES_query_matrix +#define _ALLEGRO_GL_OES_query_matrix +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test +#define _ALLEGRO_GL_EXT_depth_bounds_test +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp +#define _ALLEGRO_GL_EXT_texture_mirror_clamp +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate +#define _ALLEGRO_GL_EXT_blend_equation_separate +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 /* Same as GL_BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#endif + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert +#define _ALLEGRO_GL_MESA_pack_invert +#define GL_PACK_INVERT_MESA 0x8758 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture +#define _ALLEGRO_GL_MESA_ycbcr_texture +#define GL_YCBCR_MESA 0x8757 +/* Same as GL_UNSIGNED_SHORT_8_8_APPLE and GL_UNSIGNED_SHORT_8_8_REV_APPLE */ +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#endif + + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object +#define _ALLEGRO_GL_EXT_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif + + + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option +#define _ALLEGRO_GL_NV_fragment_program_option +#endif + + + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 +#define _ALLEGRO_GL_NV_fragment_program2 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif + + + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option +#define _ALLEGRO_GL_NV_vertex_program2_option +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#endif + + + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 +#define _ALLEGRO_GL_NV_vertex_program3 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#endif + + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 +#define _ALLEGRO_GL_EXT_texture_compression_dxt1 +#ifndef ALLEGRO_GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif +#endif + + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object +#define _ALLEGRO_GL_EXT_framebuffer_object +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_STENCIL_INDEX_EXT 0x8D45 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_FRAMEBUFFER_STATUS_ERROR_EXT 0x8CDE +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#endif + + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker +#define _ALLEGRO_GL_GREMEDY_string_marker +#endif + + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil +#define _ALLEGRO_GL_EXT_packed_depth_stencil +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#endif + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag +#define _ALLEGRO_GL_EXT_stencil_clear_tag +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +#endif + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB +#define _ALLEGRO_GL_EXT_texture_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit +#define _ALLEGRO_GL_EXT_framebuffer_blit +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CAA +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample +#define _ALLEGRO_GL_EXT_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack +#define _ALLEGRO_GL_MESAX_texture_stack +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#endif + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query +#define _ALLEGRO_GL_EXT_timer_query +#if (defined _MSC_VER) && (_MSC_VER < 1400) +typedef __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +#else +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif +#define GL_TIME_ELAPSED_EXT 0x88BF +#endif + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters +#define _ALLEGRO_GL_EXT_gpu_program_parameters +#endif + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range +#define _ALLEGRO_GL_APPLE_flush_buffer_range +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform +#define _ALLEGRO_GL_EXT_bindable_uniform +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#endif + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 +#define _ALLEGRO_GL_EXT_draw_buffers2 +#endif + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced +#define _ALLEGRO_GL_EXT_draw_instanced +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB +#define _ALLEGRO_GL_EXT_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 +#define _ALLEGRO_GL_EXT_geometry_shader4 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 +#define _ALLEGRO_GL_EXT_gpu_shader4 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +#endif + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float +#define _ALLEGRO_GL_EXT_packed_float +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array +#define _ALLEGRO_GL_EXT_texture_array +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object +#define _ALLEGRO_GL_EXT_texture_buffer_object +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc +#define _ALLEGRO_GL_EXT_texture_compression_latc +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc +#define _ALLEGRO_GL_EXT_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer +#define _ALLEGRO_GL_EXT_texture_integer +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent +#define _ALLEGRO_GL_EXT_texture_shared_exponent +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float +#define _ALLEGRO_GL_NV_depth_buffer_float +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#endif + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 +#define _ALLEGRO_GL_NV_fragment_program4 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage +#define _ALLEGRO_GL_NV_framebuffer_multisample_coverage +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 +#define _ALLEGRO_GL_NV_geometry_program4 +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#if !defined GL_EXT_geometry_shader4 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 +#define _ALLEGRO_GL_NV_gpu_program4 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#endif + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object +#define _ALLEGRO_GL_NV_parameter_buffer_object +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +#endif + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback +#define _ALLEGRO_GL_NV_transform_feedback +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#if !defined GL_NV_register_combiners +#define GL_SECONDARY_COLOR_NV 0x852D +#endif +#if !defined GL_EXT_gpu_shader4 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#endif +#endif + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 +#define _ALLEGRO_GL_NV_vertex_program4 +#if !defined GL_EXT_vertex_shader4 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#endif +#endif + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator +#define _ALLEGRO_GL_GREMEDY_frame_terminator +#endif + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render +#define _ALLEGRO_GL_NV_conditional_render +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +#endif + +#ifndef GL_NV_present_video +#define GL_NV_present_video +#define _ALLEGRO_GL_NV_present_video +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B +#endif + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback +#define _ALLEGRO_GL_EXT_transform_feedback +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#endif + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access +#define _ALLEGRO_GL_EXT_direct_state_access +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +#endif + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle +#define _ALLEGRO_GL_EXT_texture_swizzle +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 +#endif + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample +#define _ALLEGRO_GL_NV_explicit_multisample +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#endif + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 +#define _ALLEGRO_GL_NV_transform_feedback2 +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 +#endif + +#ifndef GL_ATI_meminfo +#define GL_ATI_meminfo +#define _ALLEGRO_GL_ATI_meminfo +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD +#endif + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor +#define _ALLEGRO_GL_AMD_performance_monitor +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +#endif + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 +#define _ALLEGRO_GL_AMD_texture_texture4 +#endif + +#ifndef GL_AMD_vertex_shader_tesselator +#define GL_AMD_vertex_shader_tesselator +#define _ALLEGRO_GL_AMD_vertex_shader_tesselator +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_DISCRETE_AMD 0x9006 +#define GL_CONTINUOUS_AMD 0x9007 +#endif + +#ifndef GL_EXT_provoking_vertex +#define GL_EXT_provoking_vertex +#define _ALLEGRO_GL_EXT_provoking_vertex +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_PROVOKING_VERTEX_EXT 0x8E4F +#endif + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm +#define _ALLEGRO_GL_EXT_texture_snorm +#define GL_ALPHA_SNORM 0x9010 +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_ALPHA8_SNORM 0x9014 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_ALPHA16_SNORM 0x9018 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_INTENSITY16_SNORM 0x901B +/* reuse GL_RED_SNORM */ +/* reuse GL_RG_SNORM */ +/* reuse GL_RGB_SNORM */ +/* reuse GL_RGBA_SNORM */ +/* reuse GL_R8_SNORM */ +/* reuse GL_RG8_SNORM */ +/* reuse GL_RGB8_SNORM */ +/* reuse GL_RGBA8_SNORM */ +/* reuse GL_R16_SNORM */ +/* reuse GL_RG16_SNORM */ +/* reuse GL_RGB16_SNORM */ +/* reuse GL_RGBA16_SNORM */ +/* reuse GL_SIGNED_NORMALIZED */ +#endif + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend +#define _ALLEGRO_GL_AMD_draw_buffers_blend +#endif + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range +#define _ALLEGRO_GL_APPLE_texture_range +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +/* reuse GL_STORAGE_CACHED_APPLE */ +/* reuse GL_STORAGE_SHARED_APPLE */ +#endif + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels +#define _ALLEGRO_GL_APPLE_float_pixels +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F +#endif + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators +#define _ALLEGRO_GL_APPLE_vertex_program_evaluators +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 +#endif + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil +#define _ALLEGRO_GL_APPLE_aux_depth_stencil +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 +#endif + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable +#define _ALLEGRO_GL_APPLE_object_purgeable +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D +#endif + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes +#define _ALLEGRO_GL_APPLE_row_bytes +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 +#endif + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 +#define _ALLEGRO_GL_APPLE_rgb_422 +#define GL_RGB_422_APPLE 0x8A1F +/* reuse GL_UNSIGNED_SHORT_8_8_APPLE */ +/* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */ +#endif + +#ifndef GL_NV_video_capture +#define GL_NV_video_capture +#define _ALLEGRO_GL_NV_video_capture +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_SUCCESS_NV 0x902F +#define GL_FAILURE_NV 0x9030 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C +#endif + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects +#define _ALLEGRO_GL_EXT_separate_shader_objects +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D +#endif + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 +#define _ALLEGRO_GL_NV_parameter_buffer_object2 +#endif + +#ifndef GL_NV_shader_buffer_load +#define GL_NV_shader_buffer_load +#define _ALLEGRO_GL_NV_shader_buffer_load +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 +#endif + +#ifndef GL_NV_vertex_buffer_unified_memory +#define GL_NV_vertex_buffer_unified_memory +#define _ALLEGRO_GL_NV_vertex_buffer_unified_memory +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#endif + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier +#define _ALLEGRO_GL_NV_texture_barrier +#endif + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export +#define _ALLEGRO_GL_AMD_shader_stencil_export +#endif + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture +#define _ALLEGRO_GL_AMD_seamless_cubemap_per_texture +/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS_ARB */ +#endif + +#ifndef GL_AMD_conservative_depth +#define GL_AMD_conservative_depth +#define _ALLEGRO_GL_AMD_conservative_depth +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_list.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_list.h new file mode 100644 index 00000000..e4e4b342 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/gl_ext_list.h @@ -0,0 +1,359 @@ +AGL_EXT(ARB_imaging, 0) +AGL_EXT(ARB_multitexture, 1_2_1) +AGL_EXT(ARB_transpose_matrix, 1_3) +AGL_EXT(ARB_multisample, 1_3) +AGL_EXT(ARB_texture_env_add, 1_3) +AGL_EXT(ARB_texture_cube_map, 1_3) +AGL_EXT(ARB_texture_compression, 1_3) +AGL_EXT(ARB_texture_border_clamp, 1_3) +AGL_EXT(ARB_point_parameters, 1_4) +AGL_EXT(ARB_vertex_blend, 0) +AGL_EXT(ARB_texture_env_combine, 1_3) +AGL_EXT(ARB_texture_env_crossbar, 1_4) +AGL_EXT(ARB_texture_env_dot3, 1_3) +AGL_EXT(ARB_texture_mirrored_repeat, 1_4) +AGL_EXT(ARB_depth_texture, 1_4) +AGL_EXT(ARB_shadow, 1_4) +AGL_EXT(ARB_shadow_ambient, 0) +AGL_EXT(ARB_window_pos, 1_4) +AGL_EXT(ARB_vertex_program, 0) +AGL_EXT(ARB_fragment_program, 0) +AGL_EXT(ARB_vertex_buffer_object, 1_5) +AGL_EXT(ARB_occlusion_query, 1_5) +AGL_EXT(ARB_shader_objects, 0) /* Those were promoted to Core in */ +AGL_EXT(ARB_vertex_shader, 0) /* 2.0 with modifications. */ +AGL_EXT(ARB_fragment_shader, 0) /* */ +AGL_EXT(ARB_shading_language_100, 0) /* */ +AGL_EXT(ARB_texture_non_power_of_two,2_0) +AGL_EXT(ARB_point_sprite, 2_0) +AGL_EXT(ARB_fragment_program_shadow, 0) +AGL_EXT(ARB_draw_buffers, 2_0) +AGL_EXT(ARB_texture_rectangle, 3_1) +AGL_EXT(ARB_color_buffer_float, 3_0) +AGL_EXT(ARB_half_float_pixel, 3_0) +AGL_EXT(ARB_texture_float, 3_0) +AGL_EXT(ARB_pixel_buffer_object, 2_1) +AGL_EXT(ARB_instanced_arrays, 0) +AGL_EXT(ARB_draw_instanced, 3_1) +AGL_EXT(ARB_geometry_shader4, 0) +AGL_EXT(ARB_texture_buffer_object, 3_1) +AGL_EXT(ARB_depth_buffer_float, 3_0) +AGL_EXT(ARB_framebuffer_object, 3_0) +AGL_EXT(ARB_framebuffer_sRGB, 3_0) +AGL_EXT(ARB_half_float_vertex, 3_0) +AGL_EXT(ARB_map_buffer_range, 3_0) +AGL_EXT(ARB_texture_compression_rgtc,3_0) +AGL_EXT(ARB_texture_rg, 3_0) +AGL_EXT(ARB_vertex_array_object, 3_0) +AGL_EXT(ARB_copy_buffer, 3_1) +AGL_EXT(ARB_compatibility, 0) +AGL_EXT(ARB_uniform_buffer_object, 3_1) +AGL_EXT(ARB_shader_texture_lod, 0) +AGL_EXT(ARB_depth_clamp, 3_2) +AGL_EXT(ARB_draw_elements_base_vertex, 3_2) +AGL_EXT(ARB_fragment_coord_conventions, 3_2) +AGL_EXT(ARB_provoking_vertex, 3_2) +AGL_EXT(ARB_seamless_cube_map, 3_2) +AGL_EXT(ARB_sync, 3_2) +AGL_EXT(ARB_texture_multisample, 3_2) +AGL_EXT(ARB_vertex_array_bgra, 0) +AGL_EXT(ARB_draw_buffers_blend, 0) +AGL_EXT(ARB_sample_shading, 0) +AGL_EXT(ARB_texture_cube_map_array, 0) +AGL_EXT(ARB_texture_gather, 0) +AGL_EXT(ARB_texture_query_lod, 0) +AGL_EXT(ARB_shading_language_include, 0) +AGL_EXT(ARB_texture_compression_bptc, 0) +AGL_EXT(ARB_blend_func_extended, 3_3) +AGL_EXT(ARB_explicit_attrib_location, 3_3) +AGL_EXT(ARB_occlusion_query2, 3_3) +AGL_EXT(ARB_sampler_objects, 3_3) +AGL_EXT(ARB_shader_bit_encoding, 3_3) +AGL_EXT(ARB_texture_rgb10_a2ui, 3_3) +AGL_EXT(ARB_texture_swizzle, 3_3) +AGL_EXT(ARB_timer_query, 3_3) +AGL_EXT(ARB_vertex_type_2_10_10_10_rev, 3_3) +AGL_EXT(ARB_draw_indirect, 4_0) +AGL_EXT(ARB_gpu_shader5, 4_0) +AGL_EXT(ARB_gpu_shader_fp64, 4_0) +AGL_EXT(ARB_shader_subroutine, 4_0) +AGL_EXT(ARB_tessellation_shader, 4_0) +AGL_EXT(ARB_texture_buffer_object_rgb32, 4_0) +AGL_EXT(ARB_transform_feedback2, 4_0) +AGL_EXT(ARB_transform_feedback3, 4_0) + +AGL_EXT(EXT_abgr, 0) +AGL_EXT(EXT_blend_color, 1_1) +AGL_EXT(EXT_polygon_offset, 1_1) +AGL_EXT(EXT_texture, 1_1) +AGL_EXT(EXT_texture3D, 1_2) +AGL_EXT(SGIS_texture_filter4, 0) +AGL_EXT(EXT_subtexture, 1_1) +AGL_EXT(EXT_copy_texture, 1_1) +AGL_EXT(EXT_histogram, 0) +AGL_EXT(EXT_convolution, 0) +AGL_EXT(SGI_color_matrix, 0) +AGL_EXT(SGI_color_table, 0) +AGL_EXT(SGIS_pixel_texture, 0) +AGL_EXT(SGIX_pixel_texture, 0) +AGL_EXT(SGIS_texture4D, 0) +AGL_EXT(SGI_texture_color_table, 0) +AGL_EXT(EXT_cmyka, 0) +AGL_EXT(EXT_texture_object, 1_1) +AGL_EXT(SGIS_detail_texture, 0) +AGL_EXT(SGIS_sharpen_texture, 0) +AGL_EXT(EXT_packed_pixels, 1_2) +AGL_EXT(SGIS_texture_lod, 1_2) +AGL_EXT(SGIS_multisample, 1_3) +AGL_EXT(EXT_rescale_normal, 1_2) +AGL_EXT(EXT_vertex_array, 1_1) +AGL_EXT(EXT_misc_attribute, 0) +AGL_EXT(SGIS_generate_mipmap, 1_4) +AGL_EXT(SGIX_clipmap, 0) +AGL_EXT(SGIX_shadow, 0) +AGL_EXT(SGIS_texture_edge_clamp, 1_2) +AGL_EXT(SGIS_texture_border_clamp, 0) +AGL_EXT(EXT_blend_minmax, 0) +AGL_EXT(EXT_blend_subtract, 0) +AGL_EXT(EXT_blend_logic_op, 1_1) +AGL_EXT(SGIX_interlace, 0) +AGL_EXT(SGIS_texture_select, 0) +AGL_EXT(SGIX_sprite, 0) +AGL_EXT(SGIX_texture_multi_buffer, 0) +AGL_EXT(EXT_point_parameters, 0) +AGL_EXT(SGIX_instruments, 0) +AGL_EXT(SGIX_texture_scale_bias, 0) +AGL_EXT(SGIX_framezoom, 0) +AGL_EXT(SGIX_tag_sample_buffer, 0) +AGL_EXT(SGIX_reference_plane, 0) +AGL_EXT(SGIX_flush_raster, 0) +AGL_EXT(SGIX_depth_texture, 0) +AGL_EXT(SGIS_fog_function, 0) +AGL_EXT(SGIX_fog_offset, 0) +AGL_EXT(HP_image_transform, 0) +AGL_EXT(HP_convolution_border_modes, 0) +AGL_EXT(SGIX_texture_add_env, 0) +AGL_EXT(EXT_color_subtable, 0) +AGL_EXT(PGI_vertex_hints, 0) +AGL_EXT(PGI_misc_hints, 0) +AGL_EXT(EXT_paletted_texture, 0) +AGL_EXT(EXT_clip_volume_hint, 0) +AGL_EXT(SGIX_list_priority, 0) +AGL_EXT(SGIX_ir_instrument1, 0) +AGL_EXT(SGIX_texture_lod_bias, 0) +AGL_EXT(SGIX_shadow_ambient, 0) +AGL_EXT(EXT_index_texture, 0) +AGL_EXT(EXT_index_material, 0) +AGL_EXT(EXT_index_func, 0) +AGL_EXT(EXT_index_array_formats, 0) +AGL_EXT(EXT_compiled_vertex_array, 0) +AGL_EXT(EXT_cull_vertex, 0) +AGL_EXT(SGIX_ycrcb, 0) +AGL_EXT(EXT_fragment_lighting, 0) +AGL_EXT(IBM_rasterpos_clip, 0) +AGL_EXT(HP_texture_lighting, 0) +AGL_EXT(EXT_draw_range_elements, 0) +AGL_EXT(WIN_phong_shading, 0) +AGL_EXT(WIN_specular_fog, 0) +AGL_EXT(EXT_light_texture, 0) +AGL_EXT(SGIX_blend_alpha_minmax, 0) +AGL_EXT(EXT_scene_marker, 0) +AGL_EXT(SGIX_pixel_texture_bits, 0) +AGL_EXT(EXT_bgra, 1_2) +AGL_EXT(SGIX_async, 0) +AGL_EXT(SGIX_async_pixel, 0) +AGL_EXT(SGIX_async_histogram, 0) +AGL_EXT(INTEL_texture_scissor, 0) +AGL_EXT(INTEL_parallel_arrays, 0) +AGL_EXT(HP_occlusion_test, 0) +AGL_EXT(EXT_pixel_transform, 0) +AGL_EXT(EXT_pixel_transform_color_table, 0) +AGL_EXT(EXT_shared_texture_palette, 0) +AGL_EXT(EXT_separate_specular_color, 1_2) +AGL_EXT(EXT_secondary_color, 1_4) +AGL_EXT(EXT_texture_env, 0) +AGL_EXT(EXT_texture_perturb_normal, 0) +AGL_EXT(EXT_multi_draw_arrays, 1_4) +AGL_EXT(EXT_fog_coord, 1_4) +AGL_EXT(REND_screen_coordinates, 0) +AGL_EXT(EXT_coordinate_frame, 0) +AGL_EXT(EXT_texture_env_combine, 0) +AGL_EXT(APPLE_specular_vector, 0) +AGL_EXT(APPLE_transform_hint, 0) +AGL_EXT(SUNX_constant_data, 0) +AGL_EXT(SUN_global_alpha, 0) +AGL_EXT(SUN_triangle_list, 0) +AGL_EXT(SUN_vertex, 0) +AGL_EXT(EXT_blend_func_separate, 1_4) +AGL_EXT(INGR_color_clamp, 0) +AGL_EXT(INGR_interlace_read, 0) +AGL_EXT(EXT_stencil_wrap, 1_4) +AGL_EXT(EXT_422_pixels, 0) +AGL_EXT(NV_texgen_reflection, 0) +AGL_EXT(SGIX_texture_range, 0) +AGL_EXT(SUN_convolution_border_modes, 0) +AGL_EXT(EXT_texture_env_add, 0) +AGL_EXT(EXT_texture_lod_bias, 1_4) +AGL_EXT(EXT_texture_filter_anisotropic, 0) +AGL_EXT(EXT_vertex_weighting, 0) +AGL_EXT(NV_light_max_exponent, 0) +AGL_EXT(NV_vertex_array_range, 0) +AGL_EXT(NV_register_combiners, 0) +AGL_EXT(NV_fog_distance, 0) +AGL_EXT(NV_texgen_emboss, 0) +AGL_EXT(NV_blend_square, 1_4) +AGL_EXT(NV_texture_env_combine4, 0) +AGL_EXT(MESA_resize_buffers, 0) +AGL_EXT(MESA_window_pos, 0) +AGL_EXT(EXT_texture_compression_s3tc, 0) +AGL_EXT(IBM_cull_vertex, 0) +AGL_EXT(IBM_multimode_draw_arrays, 0) +AGL_EXT(IBM_vertex_array_lists, 0) +AGL_EXT(3DFX_texture_compression_FXT1, 0) +AGL_EXT(3DFX_multisample, 0) +AGL_EXT(3DFX_tbuffer, 0) +AGL_EXT(SGIX_vertex_preclip, 0) +AGL_EXT(SGIX_resample, 0) +AGL_EXT(SGIS_texture_color_mask, 0) +AGL_EXT(EXT_texture_env_dot3, 0) +AGL_EXT(ATI_texture_mirror_once, 0) +AGL_EXT(NV_fence, 0) +AGL_EXT(IBM_static_data, 0) +AGL_EXT(IBM_texture_mirrored_repeat, 0) +AGL_EXT(NV_evaluators, 0) +AGL_EXT(NV_packed_depth_stencil, 3_0) +AGL_EXT(NV_register_combiners2, 0) +AGL_EXT(NV_texture_compression_vtc, 0) +AGL_EXT(NV_texture_rectangle, 0) +AGL_EXT(NV_texture_shader, 0) +AGL_EXT(NV_texture_shader2, 0) +AGL_EXT(NV_vertex_array_range2, 0) +AGL_EXT(NV_vertex_program, 0) +AGL_EXT(SGIX_texture_coordinate_clamp, 0) +AGL_EXT(OML_interlace, 0) +AGL_EXT(OML_subsample, 0) +AGL_EXT(OML_resample, 0) +AGL_EXT(NV_copy_depth_to_color, 0) +AGL_EXT(ATI_envmap_bumpmap, 0) +AGL_EXT(ATI_fragment_shader, 0) +AGL_EXT(ATI_pn_triangles, 0) +AGL_EXT(ATI_vertex_array_object, 0) +AGL_EXT(EXT_vertex_shader, 0) +AGL_EXT(ATI_vertex_streams, 0) +AGL_EXT(ATI_element_array, 0) +AGL_EXT(SUN_mesh_array, 0) +AGL_EXT(SUN_slice_accum, 0) +AGL_EXT(NV_multisample_filter_hint, 0) +AGL_EXT(NV_depth_clamp, 0) +AGL_EXT(NV_occlusion_query, 0) +AGL_EXT(NV_point_sprite, 0) +AGL_EXT(NV_texture_shader3, 0) +AGL_EXT(NV_vertex_program1_1, 0) +AGL_EXT(EXT_shadow_funcs, 1_5) +AGL_EXT(EXT_stencil_two_side, 0) +AGL_EXT(ATI_text_fragment_shader, 0) +AGL_EXT(APPLE_client_storage, 0) +AGL_EXT(APPLE_element_array, 0) +AGL_EXT(APPLE_fence, 0) +AGL_EXT(APPLE_vertex_array_object, 3_0) +AGL_EXT(APPLE_vertex_array_range, 0) +AGL_EXT(APPLE_ycbcr_422, 0) +AGL_EXT(S3_s3tc, 0) +AGL_EXT(ATI_draw_buffers, 0) +AGL_EXT(ATI_texture_env_combine3, 0) +AGL_EXT(ATI_texture_float, 0) +AGL_EXT(NV_float_buffer, 0) +AGL_EXT(NV_fragment_program, 0) +AGL_EXT(NV_half_float, 3_0) +AGL_EXT(NV_pixel_data_range, 0) +AGL_EXT(NV_primitive_restart, 3_1) +AGL_EXT(NV_texture_expand_normal, 0) +AGL_EXT(NV_vertex_program2, 0) +AGL_EXT(ATI_map_object_buffer, 0) +AGL_EXT(ATI_separate_stencil, 2_0) +AGL_EXT(ATI_vertex_attrib_array_object, 0) +AGL_EXT(OES_byte_coordinates, 0) +AGL_EXT(OES_fixed_point, 0) +AGL_EXT(OES_single_precision, 0) +AGL_EXT(OES_compressed_paletted_texture, 0) +AGL_EXT(OES_read_format, 0) +AGL_EXT(OES_query_matrix, 0) +AGL_EXT(OES_framebuffer_object, 0) +AGL_EXT(OES_texture_npot, 0) +AGL_EXT(EXT_depth_bounds_test, 0) +AGL_EXT(EXT_texture_mirror_clamp, 0) +AGL_EXT(EXT_blend_equation_separate, 0) +AGL_EXT(MESA_pack_invert, 0) +AGL_EXT(MESA_ycbcr_texture, 0) +AGL_EXT(EXT_pixel_buffer_object, 0) +AGL_EXT(NV_fragment_program_option, 0) +AGL_EXT(NV_fragment_program2, 0) +AGL_EXT(NV_vertex_program2_option, 0) +AGL_EXT(NV_vertex_program3, 0) +AGL_EXT(EXT_texture_compression_dxt1, 0) +AGL_EXT(EXT_framebuffer_object, 3_0) +AGL_EXT(GREMEDY_string_marker, 0) +AGL_EXT(EXT_packed_depth_stencil, 0) +AGL_EXT(EXT_stencil_clear_tag, 0) +AGL_EXT(EXT_texture_sRGB, 2_1) +AGL_EXT(EXT_framebuffer_blit, 3_0) +AGL_EXT(EXT_framebuffer_multisample, 3_0) +AGL_EXT(MESAX_texture_stack, 0) +AGL_EXT(EXT_timer_query, 0) +AGL_EXT(EXT_gpu_program_parameters, 0) +AGL_EXT(APPLE_flush_buffer_range, 0) +#ifdef ALLEGRO_MACOSX +AGL_EXT(EXT_texture_rectangle, 0) +#endif +AGL_EXT(EXT_bindable_uniform, 0) +AGL_EXT(EXT_draw_buffers2, 3_0) +AGL_EXT(EXT_draw_instanced, 0) +AGL_EXT(EXT_framebuffer_sRGB, 3_0) +AGL_EXT(EXT_geometry_shader4, 0) +AGL_EXT(EXT_gpu_shader4, 3_0) +AGL_EXT(EXT_packed_float, 3_0) +AGL_EXT(EXT_texture_array, 3_0) +AGL_EXT(EXT_texture_buffer_object, 0) +AGL_EXT(EXT_texture_compression_latc, 0) +AGL_EXT(EXT_texture_compression_rgtc,3_0) +AGL_EXT(EXT_texture_integer, 3_0) +AGL_EXT(EXT_texture_shared_exponent, 3_0) +AGL_EXT(NV_depth_buffer_float, 3_0) +AGL_EXT(NV_fragment_program4, 0) +AGL_EXT(NV_framebuffer_multisample_coverage, 0) +AGL_EXT(NV_geometry_program4, 0) +AGL_EXT(NV_gpu_program4, 0) +AGL_EXT(NV_parameter_buffer_object, 0) +AGL_EXT(NV_transform_feedback, 0) +AGL_EXT(NV_vertex_program4, 0) +AGL_EXT(GREMEDY_frame_terminator, 0) +AGL_EXT(NV_conditional_render, 3_0) +AGL_EXT(NV_present_video, 0) +AGL_EXT(EXT_direct_state_access, 0) +AGL_EXT(EXT_transform_feedback, 3_0) +AGL_EXT(EXT_texture_swizzle, 0) +AGL_EXT(NV_explicit_multisample, 0) +AGL_EXT(NV_transform_feedback2, 0) +AGL_EXT(ATI_meminfo, 0) +AGL_EXT(AMD_performance_monitor, 0) +AGL_EXT(AMD_texture_texture4, 0) +AGL_EXT(AMD_vertex_shader_tesselator, 0) +AGL_EXT(EXT_provoking_vertex, 0) +AGL_EXT(EXT_texture_snorm, 0) +AGL_EXT(AMD_draw_buffers_blend, 0) +AGL_EXT(APPLE_texture_range, 0) +AGL_EXT(APPLE_float_pixels, 0) +AGL_EXT(APPLE_vertex_program_evaluators, 0) +AGL_EXT(APPLE_aux_depth_stencil, 0) +AGL_EXT(APPLE_object_purgeable, 0) +AGL_EXT(APPLE_row_bytes, 0) +AGL_EXT(APPLE_rgb_422, 0) +AGL_EXT(NV_video_capture, 0) +AGL_EXT(EXT_separate_shader_objects, 0) +AGL_EXT(NV_parameter_buffer_object2, 0) +AGL_EXT(NV_shader_buffer_load, 0) +AGL_EXT(NV_vertex_buffer_unified_memory, 0) +AGL_EXT(NV_texture_barrier, 0) +AGL_EXT(AMD_shader_stencil_export, 0) +AGL_EXT(AMD_seamless_cubemap_per_texture, 0) +AGL_EXT(AMD_conservative_depth, 0) diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_alias.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_alias.h new file mode 100644 index 00000000..595cd569 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_alias.h @@ -0,0 +1,213 @@ +/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ +#ifdef _ALLEGRO_GLX_VERSION_1_3 +/*GLX1.3*/ +#define glXGetFBConfigs _al_glXGetFBConfigs +#define glXChooseFBConfig _al_glXChooseFBConfig +#define glXGetFBConfigAttrib _al_glXGetFBConfigAttrib +#define glXGetVisualFromFBConfig _al_glXGetVisualFromFBConfig +#define glXCreateWindow _al_glXCreateWindow +#define glXDestroyWindow _al_glXDestroyWindow +#define glXCreatePixmap _al_glXCreatePixmap +#define glXDestroyPixmap _al_glXDestroyPixmap +#define glXCreatePbuffer _al_glXCreatePbuffer +#define glXDestroyPbuffer _al_glXDestroyPbuffer +#define glXQueryDrawable _al_glXQueryDrawable +#define glXCreateNewContext _al_glXCreateNewContext +#define glXMakeContextCurrent _al_glXMakeContextCurrent +#define glXGetCurrentReadDrawable _al_glXGetCurrentReadDrawable +#define glXGetCurrentDisplay _al_glXGetCurrentDisplay +#define glXQueryContext _al_glXQueryContext +#define glXSelectEvent _al_glXSelectEvent +#define glXGetSelectedEvent _al_glXGetSelectedEvent +#endif +#ifdef _ALLEGRO_GLX_VERSION_1_4 +/*GLX1.4*/ +#define glXGetProcAddress _al_glXGetProcAddress +#endif + +#ifdef _ALLEGRO_GLX_ARB_get_proc_address +/*GLX_ARB_get_proc_address*/ +#define glXGetProcAddressARB _al_glXGetProcAddressARB +#endif + +#ifdef _ALLEGRO_GLX_ARB_create_context +#define glXCreateContextAttribsARB _al_glXCreateContextAttribsARB +#endif + +#ifdef _ALLEGRO_GLX_SGI_swap_control +/*GLX_SGI_swap_control*/ +#define glXSwapIntervalSGI _al_glXSwapIntervalSGI +#endif + +#ifdef _ALLEGRO_GLX_SGI_video_sync +/*GLX_SGI_video_sync*/ +#define glXGetVideoSyncSGI _al_glXGetVideoSyncSGI +#define glXWaitVideoSyncSGI _al_glXWaitVideoSyncSGI +#endif + +#ifdef _ALLEGRO_GLX_SGI_make_current_read +/*GLX_SGI_make_current_read*/ +#define glXMakeCurrentReadSGI _al_glXMakeCurrentReadSGI +#define glXGetCurrentReadDrawableSGI _al_glXGetCurrentReadDrawableSGI +#endif + +#ifdef _ALLEGRO_GLX_SGIX_video_source +/*GLX_SGIX_video_source*/ +/*ThisoneneedsSGI'sheaderfiletobeincludedfirst*/ +#ifdef _VL_H_ +#define glXCreateGLXVideoSourceSGIX _al_glXCreateGLXVideoSourceSGIX +#define glXDestroyGLXVideoSourceSGIX _al_glXDestroyGLXVideoSourceSGIX +#endif +#endif + +#ifdef _ALLEGRO_GLX_EXT_import_context +/*GLX_EXT_import_context*/ +#define glXGetCurrentDisplayEXT _al_glXGetCurrentDisplayEXT +#define glXQueryContextInfoEXT _al_glXQueryContextInfoEXT +#define glXGetContextIDEXT _al_glXGetContextIDEXT +#define glXImportContextEXT _al_glXImportContextEXT +#define glXFreeContextEXT _al_glXFreeContextEXT +#endif + +#ifdef _ALLEGRO_GLX_SGIX_fbconfig +/*GLX_SGIX_fbconfig*/ +#define glXGetFBConfigAttribSGIX _al_glXGetFBConfigAttribSGIX +#define glXChooseFBConfigSGIX _al_glXChooseFBConfigSGIX +#define glXCreateGLXPixmapWithConfigSGIX _al_glXCreateGLXPixmapWithConfigSGIX +#define glXCreateContextWithConfigSGIX _al_glXCreateContextWithConfigSGIX +#define glXGetVisualFromFBConfigSGIX _al_glXGetVisualFromFBConfigSGIX +#define glXGetFBConfigFromVisualSGIX _al_glXGetFBConfigFromVisualSGIX +#endif + +#ifdef _ALLEGRO_GLX_SGIX_pbuffer +/*GLX_SGIX_pbuffer*/ +#define glXCreateGLXPbufferSGIX _al_glXCreateGLXPbufferSGIX +#define glXDestroyGLXPbufferSGIX _al_glXDestroyGLXPbufferSGIX +#define glXQueryGLXPbufferSGIX _al_glXQueryGLXPbufferSGIX +#define glXSelectEventSGIX _al_glXSelectEventSGIX +#define glXGetSelectedEventSGIX _al_glXGetSelectedEventSGIX +#endif + +#ifdef _ALLEGRO_GLX_SGI_cushion +/*GLX_SGI_cushion*/ +#define glXCushionSGI _al_glXCushionSGI +#endif + +#ifdef _ALLEGRO_GLX_SGIX_video_resize +/*GLX_SGIX_video_resize*/ +#define glXBindChannelToWindowSGIX _al_glXBindChannelToWindowSGIX +#define glXChannelRectSGIX _al_glXChannelRectSGIX +#define glXQueryChannelRectSGIX _al_glXQueryChannelRectSGIX +#define glXQueryChannelDeltasSGIX _al_glXQueryChannelDeltasSGIX +#define glXChannelRectSyncSGIX _al_glXChannelRectSyncSGIX +#endif + +#ifdef _ALLEGRO_GLX_SGIX_dmbuffer +/*GLX_SGIX_dmbuffer*/ +/*ThisoneneedsSGI'sheaderfiletobeincludedfirst*/ +#ifdef _DM_BUFFER_H_ +#define glXAssociateDMPbufferSGIX _al_glXAssociateDMPbufferSGIX +#endif +#endif + +#ifdef _ALLEGRO_GLX_SGIX_swap_group +/*GLX_SGIX_swap_group*/ +#define glXJoinSwapGroupSGIX _al_glXJoinSwapGroupSGIX +#endif + +#ifdef _ALLEGRO_GLX_SGIX_swap_barrier +/*GLX_SGIX_swap_barrier*/ +#define glXBindSwapBarrierSGIX _al_glXBindSwapBarrierSGIX +#define glXQueryMaxSwapBarriersSGIX _al_glXQueryMaxSwapBarriersSGIX +#endif + +#ifdef _ALLEGRO_GLX_SUN_get_transparent_index +/*GLX_SUN_get_transparent_index*/ +#define glXGetTransparentIndexSUN _al_glXGetTransparentIndexSUN +#endif + +#ifdef _ALLEGRO_GLX_MESA_copy_sub_buffer +/*GLX_MESA_copy_sub_buffer*/ +#define glXCopySubBufferMESA _al_glXCopySubBufferMESA +#endif + +#ifdef _ALLEGRO_GLX_MESA_pixmap_colormap +/*GLX_MESA_pixmap_colormap*/ +#define glXCreateGLXPixmapMESA _al_glXCreateGLXPixmapMESA +#endif + +#ifdef _ALLEGRO_GLX_MESA_release_buffers +/*GLX_MESA_release_buffers*/ +#define glXReleaseBuffersMESA _al_glXReleaseBuffersMESA +#endif + +#ifdef _ALLEGRO_GLX_MESA_set_3dfx_mode +/*GLX_MESA_set_3dfx_mode*/ +#define glXSet3DfxModeMESA _al_glXSet3DfxModeMESA +#endif + +#ifdef _ALLEGRO_GLX_OML_sync_control +/*GLX_OML_sync_control*/ +#define glXGetSyncValuesOML _al_glXGetSyncValuesOML +#define glXGetMscRateOML _al_glXGetMscRateOML +#define glXSwapBuffersMscOML _al_glXSwapBuffersMscOML +#define glXWaitForMscOML _al_glXWaitForMscOML +#define glXWaitForSbcOML _al_glXWaitForSbcOML +#endif + + +#ifdef _ALLEGRO_GLX_SGIX_hyperpipe +#define glXQueryHyperpipeNetworkSGIX _al_glXQueryHyperpipeNetworkSGIX +#define glXHyperpipeConfigSGIX _al_glXHyperpipeConfigSGIX +#define glXQueryHyperpipeConfigSGIX _al_glXQueryHyperpipeConfigSGIX +#define glXDestroyHyperpipeConfigSGIX _al_glXDestroyHyperpipeConfigSGIX +#define glXBindHyperpipeSGIX _al_glXBindHyperpipeSGIX +#define glXQueryHyperpipeBestAttribSGIX _al_glXQueryHyperpipeBestAttribSGIX +#define glXHyperpipeAttribSGIX _al_glXHyperpipeAttribSGIX +#define glXQueryHyperpipeAttribSGIX _al_glXQueryHyperpipeAttribSGIX +#endif + + +#ifdef _ALLEGRO_GLX_MESA_agp_offset +#define glXGetAGPOffsetMESA _al_glXGetAGPOffsetMESA +#endif + + +#ifdef _ALLEGRO_GLX_EXT_texture_from_pixmap +#define glXBindTexImageEXT _al_glXBindTexImageEXT +#define glXReleaseTextImageEXT _al_glXReleaseTextImageEXT +#endif + +#ifdef _ALLEGRO_GLX_NV_video_output +#define glXGetVideoDeviceNV _al_glXGetVideoDeviceNV +#define glXReleaseVideoDeviceNV _al_glXReleaseVideoDeviceNV +#define glXBindVideoImageNV _al_glXBindVideoImageNV +#define glXReleaseVideoImageNV _al_glXReleaseVideoImageNV +#define glXSendPbufferToVideoNV _al_glXSendPbufferToVideoNV +#define glXGetVideoInfoNV _al_glXGetVideoInfoNV +#endif + +#ifdef _ALLEGRO_GLX_NV_swap_group +#define glXJoinSwapGroupNV _al_glXJoinSwapGroupNV +#define glXBindSwapBarrierNV _al_glXBindSwapBarrierNV +#define glXQuerySwapGroupNV _al_glXQuerySwapGroupNV +#define glXQueryMaxSwapGroupsNV _al_glXQueryMaxSwapGroupsNV +#define glXQueryFrameCountNV _al_glXQueryFrameCountNV +#define glXResetFrameCountNV _al_glXResetFrameCountNV +#endif + +#ifdef _ALLEGRO_GLX_NV_video_capture +#define glXBindVideoCaptureDeviceNV _al_glXBindVideoCaptureDeviceNV +#define glXEnumerateVideoCaptureDevicesNV _al_glXEnumerateVideoCaptureDevicesNV +#define glXLockVideoCaptureDeviceNV _al_glXLockVideoCaptureDeviceNV +#define glXQueryVideoCaptureDeviceNV _al_glXQueryVideoCaptureDeviceNV +#define glXReleaseVideoCaptureDeviceNV _al_glXReleaseVideoCaptureDeviceNV +#endif + +#ifdef _ALLEGRO_GLX_EXT_swap_control +#define glXSwapIntervalEXT _al_glXSwapIntervalEXT +#endif + +#ifdef _ALLEGRO_GLX_NV_copy_image +#define glXCopyImageSubDataNV _al_glXCopyImageSubDataNV +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_api.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_api.h new file mode 100644 index 00000000..528357c5 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_api.h @@ -0,0 +1,212 @@ +#ifdef _ALLEGRO_GLX_VERSION_1_3 +/* GLX 1.3 */ +AGL_API(GLXFBConfig *, GetFBConfigs, (Display *, int, int *)) +AGL_API(GLXFBConfig *, ChooseFBConfig, (Display *, int, const int *, int *)) +AGL_API(int, GetFBConfigAttrib, (Display *, GLXFBConfig, int, int *)) +AGL_API(XVisualInfo *, GetVisualFromFBConfig, (Display *, GLXFBConfig)) +AGL_API(GLXWindow, CreateWindow, (Display *, GLXFBConfig, Window, const int *)) +AGL_API(void, DestroyWindow, (Display *, GLXWindow)) +AGL_API(GLXPixmap, CreatePixmap, (Display *, GLXFBConfig, Pixmap, const int *)) +AGL_API(void, DestroyPixmap, (Display *, GLXPixmap)) +AGL_API(GLXPbuffer, CreatePbuffer, (Display *, GLXFBConfig, const int *)) +AGL_API(void, DestroyPbuffer, (Display *, GLXPbuffer)) +AGL_API(void, QueryDrawable, (Display *, GLXDrawable, int, unsigned int *)) +AGL_API(GLXContext, CreateNewContext, (Display *, GLXFBConfig, int, GLXContext, Bool)) +AGL_API(Bool, MakeContextCurrent, (Display *, GLXDrawable, GLXDrawable, GLXContext)) +AGL_API(GLXDrawable, GetCurrentReadDrawable, (void)) +AGL_API(Display *, GetCurrentDisplay, (void)) +AGL_API(int, QueryContext, (Display *, GLXContext, int, int *)) +AGL_API(void, SelectEvent, (Display *, GLXDrawable, unsigned long)) +AGL_API(void, GetSelectedEvent, (Display *, GLXDrawable, unsigned long *)) +#endif +#ifdef _ALLEGRO_GLX_VERSION_1_4 +/* GLX 1.4 */ +AGL_API(__GLXextFuncPtr, GetProcAddress, (const GLubyte *)) +#endif + +#ifdef _ALLEGRO_GLX_ARB_get_proc_address +/* GLX_ARB_get_proc_address */ +AGL_API(__GLXextFuncPtr, GetProcAddressARB, (const GLubyte *)) +#endif + +#ifdef _ALLEGRO_GLX_ARB_create_context +AGL_API(GLXContext, CreateContextAttribsARB, (Display *, GLXFBConfig, GLXContext, Bool, const int *)) +#endif + +#ifdef _ALLEGRO_GLX_SGI_swap_control +/* GLX_SGI_swap_control */ +AGL_API(int, SwapIntervalSGI, (int)) +#endif + +#ifdef _ALLEGRO_GLX_SGI_video_sync +/* GLX_SGI_video_sync */ +AGL_API(int, GetVideoSyncSGI, (unsigned int *)) +AGL_API(int, WaitVideoSyncSGI, (int, int, unsigned int *)) +#endif + +#ifdef _ALLEGRO_GLX_SGI_make_current_read +/* GLX_SGI_make_current_read */ +AGL_API(Bool, MakeCurrentReadSGI, (Display *, GLXDrawable, GLXDrawable, GLXContext)) +AGL_API(GLXDrawable, GetCurrentReadDrawableSGI, (void)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_video_source +/* GLX_SGIX_video_source */ +/* This one needs SGI's header file to be included first */ +#ifdef _VL_H_ +AGL_API(GLXVideoSourceSGIX, CreateGLXVideoSourceSGIX, (Display *, int, VLServer, VLPath, int, VLNode)) +AGL_API(void, DestroyGLXVideoSourceSGIX, (Display *, GLXVideoSourceSGIX)) +#endif +#endif + +#ifdef _ALLEGRO_GLX_EXT_import_context +/* GLX_EXT_import_context */ +AGL_API(Display *, GetCurrentDisplayEXT, (void)) +AGL_API(int, QueryContextInfoEXT, (Display *, GLXContext, int, int *)) +AGL_API(GLXContextID, GetContextIDEXT, (const GLXContext)) +AGL_API(GLXContext, ImportContextEXT, (Display *, GLXContextID)) +AGL_API(void, FreeContextEXT, (Display *, GLXContext)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_fbconfig +/* GLX_SGIX_fbconfig */ +AGL_API(int, GetFBConfigAttribSGIX, (Display *, GLXFBConfigSGIX, int, int *)) +AGL_API(GLXFBConfigSGIX *, ChooseFBConfigSGIX, (Display *, int, int *, int *)) +AGL_API(GLXPixmap, CreateGLXPixmapWithConfigSGIX, (Display *, GLXFBConfigSGIX, Pixmap)) +AGL_API(GLXContext, CreateContextWithConfigSGIX, (Display *, GLXFBConfigSGIX, int, GLXContext, Bool)) +AGL_API(XVisualInfo *, GetVisualFromFBConfigSGIX, (Display *, GLXFBConfigSGIX)) +AGL_API(GLXFBConfigSGIX, GetFBConfigFromVisualSGIX, (Display *, XVisualInfo *)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_pbuffer +/* GLX_SGIX_pbuffer */ +AGL_API(GLXPbufferSGIX, CreateGLXPbufferSGIX, (Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *)) +AGL_API(void, DestroyGLXPbufferSGIX, (Display *, GLXPbufferSGIX)) +AGL_API(int, QueryGLXPbufferSGIX, (Display *, GLXPbufferSGIX, int, unsigned int *)) +AGL_API(void, SelectEventSGIX, (Display *, GLXDrawable, unsigned long)) +AGL_API(void, GetSelectedEventSGIX, (Display *, GLXDrawable, unsigned long *)) +#endif + +#ifdef _ALLEGRO_GLX_SGI_cushion +/* GLX_SGI_cushion */ +AGL_API(void, CushionSGI, (Display *, Window, float)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_video_resize +/* GLX_SGIX_video_resize */ +AGL_API(int, BindChannelToWindowSGIX, (Display *, int, int, Window)) +AGL_API(int, ChannelRectSGIX, (Display *, int, int, int, int, int, int)) +AGL_API(int, QueryChannelRectSGIX, (Display *, int, int, int *, int *, int *, int *)) +AGL_API(int, QueryChannelDeltasSGIX, (Display *, int, int, int *, int *, int *, int *)) +AGL_API(int, ChannelRectSyncSGIX, (Display *, int, int, GLenum)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_dmbuffer +/* GLX_SGIX_dmbuffer */ +/* This one needs SGI's header file to be included first */ +#ifdef _DM_BUFFER_H_ +AGL_API(Bool, AssociateDMPbufferSGIX, (Display *, GLXPbufferSGIX, DMparams *, DMbuffer)) +#endif +#endif + +#ifdef _ALLEGRO_GLX_SGIX_swap_group +/* GLX_SGIX_swap_group */ +AGL_API(void, JoinSwapGroupSGIX, (Display *, GLXDrawable, GLXDrawable)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_swap_barrier +/* GLX_SGIX_swap_barrier */ +AGL_API(void, BindSwapBarrierSGIX, (Display *, GLXDrawable, int)) +AGL_API(Bool, QueryMaxSwapBarriersSGIX, (Display *, int, int *)) +#endif + +#ifdef _ALLEGRO_GLX_SUN_get_transparent_index +/* GLX_SUN_get_transparent_index */ +AGL_API(Status, GetTransparentIndexSUN, (Display *, Window, Window, long *)) +#endif + +#ifdef _ALLEGRO_GLX_MESA_copy_sub_buffer +/* GLX_MESA_copy_sub_buffer */ +AGL_API(void, CopySubBufferMESA, (Display *, GLXDrawable, int, int, int, int)) +#endif + +#ifdef _ALLEGRO_GLX_MESA_pixmap_colormap +/* GLX_MESA_pixmap_colormap */ +AGL_API(GLXPixmap, CreateGLXPixmapMESA, (Display *, XVisualInfo *, Pixmap, Colormap)) +#endif + +#ifdef _ALLEGRO_GLX_MESA_release_buffers +/* GLX_MESA_release_buffers */ +AGL_API(Bool, ReleaseBuffersMESA, (Display *, GLXDrawable)) +#endif + +#ifdef _ALLEGRO_GLX_MESA_set_3dfx_mode +/* GLX_MESA_set_3dfx_mode */ +AGL_API(Bool, Set3DfxModeMESA, (int)) +#endif + +#ifdef _ALLEGRO_GLX_OML_sync_control +/* GLX_OML_sync_control */ +AGL_API(Bool, GetSyncValuesOML, (Display *, GLXDrawable, int64_t *, int64_t *, int64_t *)) +AGL_API(Bool, GetMscRateOML, (Display *, GLXDrawable, int32_t *, int32_t *)) +AGL_API(int64_t, SwapBuffersMscOML, (Display *, GLXDrawable, int64_t, int64_t, int64_t)) +AGL_API(Bool, WaitForMscOML, (Display *, GLXDrawable, int64_t, int64_t, int64_t, int64_t *, int64_t *, int64_t *)) +AGL_API(Bool, WaitForSbcOML, (Display *, GLXDrawable, int64_t, int64_t *, int64_t *, int64_t *)) +#endif + + +#ifdef _ALLEGRO_GLX_SGIX_hyperpipe +AGL_API(GLXHyperpipeNetworkSGIX *, QueryHyperpipeNetworkSGIX, (Display *dpy, int *npipes)) +AGL_API(int, HyperpipeConfigSGIX, (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId)) +AGL_API(GLXHyperpipeConfigSGIX *, QueryHyperpipeConfigSGIX, (Display *dpy, int hpId, int *npipes)) +AGL_API(int, DestroyHyperpipeConfigSGIX, (Display * dpy, int hpId)) +AGL_API(int, BindHyperpipeSGIX, (Display *dpy, int hpId)) +AGL_API(int, QueryHyperpipeBestAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList)) +AGL_API(int, HyperpipeAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *attribList)) +AGL_API(int, QueryHyperpipeAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList)) +#endif + + +#ifdef _ALLEGRO_GLX_MESA_agp_offset +AGL_API(unsigned int, GetAGPOffsetMESA, (const void *pointer)) +#endif + + +#ifdef _ALLEGRO_GLX_EXT_texture_from_pixmap +AGL_API(void, BindTexImageEXT, (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list)) +AGL_API(void, ReleaseTextImageEXT, (Display *dpy, GLXDrawable drawable, int buffer)) +#endif + +#ifdef _ALLEGRO_GLX_NV_video_output +AGL_API(int, GetVideoDeviceNV, (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice)) +AGL_API(int, ReleaseVideoDeviceNV, (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice)) +AGL_API(int, BindVideoImageNV, (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer)) +AGL_API(int, ReleaseVideoImageNV, (Display *dpy, GLXPbuffer pbuf)) +AGL_API(int, SendPbufferToVideoNV, (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock)) +AGL_API(int, GetVideoInfoNV, (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputVideo, unsigned long *pulCounterOutputPbuffer)) +#endif + +#ifdef _ALLEGRO_GLX_NV_swap_group +AGL_API(Bool, JoinSwapGroupNV, (Display *dpy, GLXDrawable drawable, GLuint group)) +AGL_API(Bool, BindSwapBarrierNV, (Display *dpy, GLuint group, GLuint barrier)) +AGL_API(Bool, QuerySwapGroupNV, (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier)) +AGL_API(Bool, QueryMaxSwapGroupsNV, (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers)) +AGL_API(Bool, QueryFrameCountNV, (Display *dpy, int screen, GLuint *count)) +AGL_API(Bool, ResetFrameCountNV, (Display *dpy, int screen)) +#endif + +#ifdef _ALLEGRO_GLX_NV_video_capture +AGL_API(int, BindVideoCaptureDeviceNV, (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device)) +AGL_API(GLXVideoCaptureDeviceNV *, EnumerateVideoCaptureDevicesNV, (Display *dpy, int screen, int *nelements)) +AGL_API(void, LockVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device)) +AGL_API(int, QueryVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value)) +AGL_API(void, ReleaseVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device)) +#endif + +#ifdef _ALLEGRO_GLX_EXT_swap_control +AGL_API(int, SwapIntervalEXT, (Display *dpy, GLXDrawable drawable, int interval)) +#endif + +#ifdef _ALLEGRO_GLX_NV_copy_image +AGL_API(void, CopyImageSubDataNV, (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth)) +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_defs.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_defs.h new file mode 100644 index 00000000..21e00977 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_defs.h @@ -0,0 +1,505 @@ +/* HACK: Prevent both Mesa and SGI's broken headers from screwing us */ +#define __glxext_h_ +#include +#undef __glxext_h_ + +#ifndef GLX_VERSION_1_3 +#define _ALLEGRO_GLX_VERSION_1_3 +#define GLX_VERSION_1_3 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#endif + +#ifndef GLX_VERSION_1_4 +#define _ALLEGRO_GLX_VERSION_1_4 +#define GLX_VERSION_1_4 +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 +#endif + +#ifndef GLX_ARB_get_proc_address +#define _ALLEGRO_GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address +typedef void (*__GLXextFuncPtr)(void); +#endif + +#ifndef GLX_ARB_multisample +#define _ALLEGRO_GLX_ARB_multisample +#define GLX_ARB_multisample +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 +#endif + +#ifndef GLX_ARB_vertex_buffer_object +#define GLX_ARB_vertex_buffer_object +#define _ALLEGRO_GLX_ARB_vertex_buffer_object +#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 +#endif + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float +#define _ALLEGRO_GLX_ARB_fbconfig_float +#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 +#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 +#endif + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context +#define _ALLEGRO_GLX_ARB_create_context +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#endif + +#ifndef GLX_ARB_create_context_profile +#define GLX_ARB_create_context_profile +#define _ALLEGRO_GLX_ARB_create_context_profile +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#endif + +#ifndef GLX_SGIS_multisample +#define _ALLEGRO_GLX_SGIS_multisample +#define GLX_SGIS_multisample +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 +#endif + +/* Fix for system headers that define GLX_VERSION_1_4 but do not define + * GLX_SAMPLES and GLX_SAMPLE_BUFFERS. */ +#ifndef GLX_SAMPLES +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 +#endif + +#ifndef GLX_EXT_visual_info +#define _ALLEGRO_GLX_EXT_visual_info +#define GLX_EXT_visual_info +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#endif + +#ifndef GLX_EXT_visual_rating +#define _ALLEGRO_GLX_EXT_visual_rating +#define GLX_EXT_visual_rating +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +/* GLX_NONE_EXT */ +#endif + +#ifndef GLX_EXT_import_context +#define _ALLEGRO_GLX_EXT_import_context +#define GLX_EXT_import_context +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C +#endif + +#ifndef GLX_SGIX_fbconfig +#define _ALLEGRO_GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 +/* GLX_SCREEN_EXT */ +#endif + +#ifndef GLX_SGIX_pbuffer +#define _ALLEGRO_GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer +typedef XID GLXPbufferSGIX; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXBufferClobberEventSGIX; +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#endif + +#ifndef GLX_SGIX_video_resize +#define _ALLEGRO_GLX_SGIX_video_resize +#define GLX_SGIX_video_resize +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 +#endif + +#ifndef GLX_SGIX_dmbuffer +#define _ALLEGRO_GLX_SGIX_dmbuffer +#define GLX_SGIX_dmbuffer +#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 +#endif + +#ifndef GLX_SGIS_blended_overlay +#define _ALLEGRO_GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay +#define GLX_BLENDED_RGBA_SGIS 0x8025 +#endif + +#ifndef GLX_SGIS_shared_multisample +#define _ALLEGRO_GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 +#endif + +#ifndef GLX_3DFX_multisample +#define _ALLEGRO_GLX_3DFX_multisample +#define GLX_3DFX_multisample +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 +#endif + +#ifndef GLX_MESA_set_3dfx_mode +#define _ALLEGRO_GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 +#endif + +#ifndef GLX_SGIX_visual_select_group +#define _ALLEGRO_GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 +#endif + +#ifndef GLX_OML_swap_method +#define _ALLEGRO_GLX_OML_swap_method +#define GLX_OML_swap_method +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 +#endif + +#ifndef GLX_SGIX_video_source +#define _ALLEGRO_GLX_SGIX_video_source +#define GLX_SGIX_video_source +typedef XID GLXVideoSourceSGIX; +#endif + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync +#define _ALLEGRO_GLX_SGI_video_sync +#endif + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control +#define _ALLEGRO_GLX_SGI_swap_control +#endif + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read +#define _ALLEGRO_GLX_SGI_make_current_read +#endif + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion +#define _ALLEGRO_GLX_SGI_cushion +#endif + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group +#define _ALLEGRO_GLX_SGIX_swap_group +#endif + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier +#define _ALLEGRO_GLX_SGIX_swap_barrier +#endif + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index +#define _ALLEGRO_GLX_SUN_get_transparent_index +#endif + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer +#define _ALLEGRO_GLX_MESA_copy_sub_buffer +#endif + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap +#define _ALLEGRO_GLX_MESA_pixmap_colormap +#endif + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers +#define _ALLEGRO_GLX_MESA_release_buffers +#endif + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control +#define _ALLEGRO_GLX_OML_sync_control +#endif + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe +#define _ALLEGRO_GLX_SGIX_hyperpipe +#define GLX_HYPERPIPE_ID_SGIX 0x8030 +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; +} GLXHyperpipeNetworkSGIX; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin; + int srcYOrigin; + int srcWidth; + int srcHeight; + int destXOrigin; + int destYOrigin; + int destWidth; + int destHeight; +} GLXPipeRect; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin; + int YOrigin; + int maxHeight; + int maxWidth; +} GLXPipeRectLimits; +#endif + + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset +#define _ALLEGRO_GLX_MESA_agp_offset +#endif + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB +#define _ALLEGRO_GLX_EXT_framebuffer_sRGB +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 +#endif + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float +#define _ALLEGRO_GLX_EXT_fbconfig_packed_float +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#endif + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap +#define _ALLEGRO_GLX_EXT_texture_from_pixmap +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT +#define GLX_BACK_EXT GLX_BACK_LEFT_EXT +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB +#endif + +#ifndef GLX_NV_present_video +#define GLX_NV_present_video +#define _ALLEGRO_GLX_NV_present_video +#define GLX_GLX_NUM_VIDEO_SLOTS_NV 0x20F0 +#endif + +#ifndef GLX_NV_video_output +#define GLX_NV_video_output +#define _ALLEGRO_GLX_NV_video_output +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +typedef unsigned int GLXVideoDeviceNV; +#endif + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group +#define _ALLEGRO_GLX_NV_swap_group +#endif + +#ifndef GLX_NV_video_capture +#define GLX_NV_video_capture +#define _ALLEGRO_GLX_NV_video_capture +#define GLX_DEVICE_ID_NV 0x20CD +#define GLX_UNIQUE_ID_NV 0x20CE +#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF +typedef XID GLXVideoCaptureDeviceNV; +#endif + +#ifndef GLX_EXT_swap_control +#define GLX_EXT_swap_control +#define _ALLEGRO_GLX_EXT_swap_control +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 +#endif + +#ifndef GLX_NV_copy_image +#define GLX_NV_copy_image +#define _ALLEGRO_GLX_NV_copy_image +#endif + +#ifndef GLX_INTEL_swap_event +#define GLX_INTEL_swap_event +#define _ALLEGRO_GLX_INTEL_swap_event +#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 +#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 +#define GLX_COPY_COMPLETE_INTEL 0x8181 +#define GLX_FLIP_COMPLETE_INTEL 0x8182 +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_list.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_list.h new file mode 100644 index 00000000..342522c2 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/glx_ext_list.h @@ -0,0 +1,40 @@ +AGL_EXT(ARB_get_proc_address, 0) +AGL_EXT(ARB_multisample, 0) +AGL_EXT(ARB_fbconfig_float, 0) +AGL_EXT(ARB_create_context, 0) +AGL_EXT(ARB_vertex_buffer_object, 0) +AGL_EXT(EXT_visual_info, 0) +AGL_EXT(SGI_swap_control, 0) +AGL_EXT(SGI_video_sync, 0) +AGL_EXT(SGI_make_current_read, 0) +AGL_EXT(SGIX_video_source, 0) +AGL_EXT(EXT_visual_rating, 0) +AGL_EXT(EXT_import_context, 0) +AGL_EXT(SGIX_fbconfig, 0) +AGL_EXT(SGIX_pbuffer, 0) +AGL_EXT(SGI_cushion, 0) +AGL_EXT(SGIX_video_resize, 0) +AGL_EXT(SGIX_dm_buffer, 0) +AGL_EXT(SGIX_swap_group, 0) +AGL_EXT(SGIX_swap_barrier, 0) +AGL_EXT(SGIS_color_range, 0) +AGL_EXT(SGIS_blended_overlay, 0) +AGL_EXT(SUN_get_transparent_index, 0) +AGL_EXT(MESA_copy_sub_buffer, 0) +AGL_EXT(MESA_pixmap_colormap, 0) +AGL_EXT(MESA_release_buffers, 0) +AGL_EXT(MESA_set_3dfx_mode, 0) +AGL_EXT(SGIX_visual_select_group, 0) +AGL_EXT(OML_swap_method, 0) +AGL_EXT(OML_sync_control, 0) +AGL_EXT(SGIX_hyperpipe, 0) +AGL_EXT(MESA_agp_offset, 0) +AGL_EXT(EXT_framebuffer_sRGB, 0) +AGL_EXT(EXT_packed_float, 0) +AGL_EXT(EXT_texture_from_pixmap, 0) +AGL_EXT(NV_video_output, 0) +AGL_EXT(NV_swap_group, 0) +AGL_EXT(NV_video_capture, 0) +AGL_EXT(EXT_swap_control, 0) +AGL_EXT(NV_copy_image, 0) +AGL_EXT(INTEL_swap_event, 0) diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_alias.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_alias.h new file mode 100644 index 00000000..ab0cf1f2 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_alias.h @@ -0,0 +1,168 @@ +/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ +/*WGL_ARB_buffer_region*/ +#define wglCreateBufferRegionARB _al_wglCreateBufferRegionARB +#define wglDeleteBufferRegionARB _al_wglDeleteBufferRegionARB +#define wglSaveBufferRegionARB _al_wglSaveBufferRegionARB +#define wglRestoreBufferRegionARB _al_wglRestoreBufferRegionARB + +/*WGL_ARB_extensions_string*/ +#define wglGetExtensionsStringARB _al_wglGetExtensionsStringARB + +/*WGL_ARB_pixel_format*/ +#define wglGetPixelFormatAttribivARB _al_wglGetPixelFormatAttribivARB +#define wglGetPixelFormatAttribfvARB _al_wglGetPixelFormatAttribfvARB +#define wglChoosePixelFormatARB _al_wglChoosePixelFormatARB + +/*WGL_ARB_make_current_read*/ +#define wglMakeContextCurrentARB _al_wglMakeContextCurrentARB +#define wglGetCurrentReadDCARB _al_wglGetCurrentReadDCARB + +/*WGL_ARB_pbuffer*/ +#define wglCreatePbufferARB _al_wglCreatePbufferARB +#define wglGetPbufferDCARB _al_wglGetPbufferDCARB +#define wglReleasePbufferDCARB _al_wglReleasePbufferDCARB +#define wglDestroyPbufferARB _al_wglDestroyPbufferARB +#define wglQueryPbufferARB _al_wglQueryPbufferARB + +/*WGL_ARB_render_texture*/ +#define wglBindTexImageARB _al_wglBindTexImageARB +#define wglReleaseTexImageARB _al_wglReleaseTexImageARB +#define wglSetPbufferAttribARB _al_wglSetPbufferAttribARB + +/*WGL_ARB_create_context*/ +#define wglCreateContextAttribsARB _al_wglCreateContextAttribsARB + +/*WGL_EXT_display_color_table*/ +#define wglCreateDisplayColorTableEXT _al_wglCreateDisplayColorTableEXT +#define wglLoadDisplayColorTableEXT _al_wglLoadDisplayColorTableEXT +#define wglBindDisplayColorTableEXT _al_wglBindDisplayColorTableEXT +#define wglDestroyDisplayColorTableEXT _al_wglDestroyDisplayColorTableEXT + +/*WGL_EXT_extensions_string*/ +#define wglGetExtensionsStringEXT _al_wglGetExtensionsStringEXT + +/*WGL_EXT_make_current_read*/ +#define wglMakeContextCurrentEXT _al_wglMakeContextCurrentEXT +#define wglGetCurrentReadDCEXT _al_wglGetCurrentReadDCEXT + +/*WGL_EXT_pbuffer*/ +#define wglCreatePbufferEXT _al_wglCreatePbufferEXT +#define wglGetPbufferDCEXT _al_wglGetPbufferDCEXT +#define wglReleasePbufferDCEXT _al_wglReleasePbufferDCEXT +#define wglDestroyPbufferEXT _al_wglDestroyPbufferEXT +#define wglQueryPbufferEXT _al_wglQueryPbufferEXT + +/*WGL_EXT_pixel_format*/ +#define wglGetPixelFormatAttribivEXT _al_wglGetPixelFormatAttribivEXT +#define wglGetPixelFormatAttribfvEXT _al_wglGetPixelFormatAttribfvEXT +#define wglChoosePixelFormatEXT _al_wglChoosePixelFormatEXT + +/*WGL_EXT_swap_control*/ +#define wglSwapIntervalEXT _al_wglSwapIntervalEXT +#define wglGetSwapIntervalEXT _al_wglGetSwapIntervalEXT + +/*WGL_NV_vertex_array_range*/ +#define wglAllocateMemoryNV _al_wglAllocateMemoryNV +#define wglFreeMemoryNV _al_wglFreeMemoryNV + +/*WGL_OML_sync_control*/ +#define wglGetSyncValuesOML _al_wglGetSyncValuesOML +#define wglGetMscRateOML _al_wglGetMscRateOML +#define wglSwapBuffersMscOML _al_wglSwapBuffersMscOML +#define wglSwapLayerBuffersMscOML _al_wglSwapLayerBuffersMscOML +#define wglWaitForMscOML _al_wglWaitForMscOML +#define wglWaitForSbcOML _al_wglWaitForSbcOML + +/*WGL_I3D_digital_video_control*/ +#define wglGetDigitalVideoParametersI3D _al_wglGetDigitalVideoParametersI3D +#define wglSetDigitalVideoParametersI3D _al_wglSetDigitalVideoParametersI3D + +/*WGL_I3D_gamma*/ +#define wglGetGammaTableParametersI3D _al_wglGetGammaTableParametersI3D +#define wglSetGammaTableParametersI3D _al_wglSetGammaTableParametersI3D +#define wglGetGammaTableI3D _al_wglGetGammaTableI3D +#define wglSetGammaTableI3D _al_wglSetGammaTableI3D + +/*WGL_I3D_genlock*/ +#define wglEnableGenlockI3D _al_wglEnableGenlockI3D +#define wglDisableGenlockI3D _al_wglDisableGenlockI3D +#define wglIsEnabledGenlockI3D _al_wglIsEnabledGenlockI3D +#define wglGenlockSourceI3D _al_wglGenlockSourceI3D +#define wglGetGenlockSourceI3D _al_wglGetGenlockSourceI3D +#define wglGenlockSourceEdgeI3D _al_wglGenlockSourceEdgeI3D +#define wglGetGenlockSourceEdgeI3D _al_wglGetGenlockSourceEdgeI3D +#define wglGenlockSampleRateI3D _al_wglGenlockSampleRateI3D +#define wglGetGenlockSampleRateI3D _al_wglGetGenlockSampleRateI3D +#define wglGenlockSourceDelayI3D _al_wglGenlockSourceDelayI3D +#define wglGetGenlockSourceDelayI3D _al_wglGetGenlockSourceDelayI3D +#define wglQueryGenlockMaxSourceDelayI3D _al_wglQueryGenlockMaxSourceDelayI3D + +/*WGL_I3D_image_buffer*/ +#define wglCreateImageBufferI3D _al_wglCreateImageBufferI3D +#define wglDestroyImageBufferI3D _al_wglDestroyImageBufferI3D +#define wglAssociateImageBufferEventsI3D _al_wglAssociateImageBufferEventsI3D +#define wglReleaseImageBufferEventsI3D _al_wglReleaseImageBufferEventsI3D + +/*WGL_I3D_swap_frame_lock*/ +#define wglEnableFrameLockI3D _al_wglEnableFrameLockI3D +#define wglDisableFrameLockI3D _al_wglDisableFrameLockI3D +#define wglIsEnabledFrameLockI3D _al_wglIsEnabledFrameLockI3D +#define wglQueryFrameLockMasterI3D _al_wglQueryFrameLockMasterI3D + +/*WGL_I3D_swap_frame_usage*/ +#define wglGetFrameUsageI3D _al_wglGetFrameUsageI3D +#define wglBeginFrameTrackingI3D _al_wglBeginFrameTrackingI3D +#define wglEndFrameTrackingI3D _al_wglEndFrameTrackingI3D +#define wglQueryFrameTrackingI3D _al_wglQueryFrameTrackingI3D + +/*glAddSwapHintRectWIN*/ +#define wglAddSwapHintRectWIN _al_wglAddSwapHintRectWIN + +/*WGL_NV_present_video*/ +#define wglEnumerateVideoDevicesNV _al_wglEnumerateVideoDevicesNV +#define wglBindVideoDeviceNV _al_wglBindVideoDeviceNV +#define wglQueryCurrentContextNV _al_wglQueryCurrentContextNV + +/*WGL_NV_video_out*/ +#define wglGetVideoDeviceNV _al_wglGetVideoDeviceNV +#define wglReleaseVideoDeviceNV _al_wglReleaseVideoDeviceNV +#define wglBindVideoImageNV _al_wglBindVideoImageNV +#define wglReleaseVideoImageNV _al_wglReleaseVideoImageNV +#define wglSendPbufferToVideoNV _al_wglSendPbufferToVideoNV +#define wglGetVideoInfoNV _al_wglGetVideoInfoNV + +/*WGL_NV_swap_group*/ +#define wglJoinSwapGroupNV _al_wglJoinSwapGroupNV +#define wglBindSwapBarrierNV _al_wglBindSwapBarrierNV +#define wglQuerySwapGroupNV _al_wglQuerySwapGroupNV +#define wglQueryMaxSwapGroupsNV _al_wglQueryMaxSwapGroupsNV +#define wglQueryFrameCountNV _al_wglQueryFrameCountNV +#define wglResetFrameCountNV _al_wglResetFrameCountNV + +/*WGL_NV_gpu_affinity*/ +#define wglEnumGpusNV _al_wglEnumGpusNV +#define wglEnumGpuDevicesNV _al_wglEnumGpuDevicesNV +#define wglCreateAffinityDCNV _al_wglCreateAffinityDCNV +#define wglEnumGpusFromAffinityDCNV _al_wglEnumGpusFromAffinityDCNV +#define wglDeleteDCNV _al_wglDeleteDCNV + +/*WGL_AMD_gpu_association*/ +#define wglGetGPUIDsAMD _al_wglGetGPUIDsAMD +#define wglGetGPUInfoAMD _al_wglGetGPUInfoAMD +#define wglGetContextGPUIDAMD _al_wglGetContextGPUIDAMD +#define wglCreateAssociatedContextAMD _al_wglCreateAssociatedContextAMD +#define wglCreateAssociatedContextAttribsAMD _al_wglCreateAssociatedContextAttribsAMD +#define wglDeleteAssociatedContextAMD _al_wglDeleteAssociatedContextAMD +#define wglMakeAssociatedContextCurrentAMD _al_wglMakeAssociatedContextCurrentAMD +#define wglGetCurrentAssociatedContextAMD _al_wglGetCurrentAssociatedContextAMD +#define wglBlitContextFramebufferAMD _al_wglBlitContextFramebufferAMD + +/*WGL_NV_video_capture*/ +#define wglBindVideoCaptureDeviceNV _al_wglBindVideoCaptureDeviceNV +#define wglEnumerateVideoCaptureDevicesNV _al_wglEnumerateVideoCaptureDevicesNV +#define wglLockVideoCaptureDeviceNV _al_wglLockVideoCaptureDeviceNV +#define wglQueryVideoCaptureDeviceNV _al_wglQueryVideoCaptureDeviceNV +#define wglReleaseVideoCaptureDeviceNV _al_wglReleaseVideoCaptureDeviceNV + +/*WGL_NV_copy_image*/ +#define wglCopyImageSubDataNV _al_wglCopyImageSubDataNV diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_api.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_api.h new file mode 100644 index 00000000..40aa9642 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_api.h @@ -0,0 +1,167 @@ +/* WGL_ARB_buffer_region */ +AGL_API(HANDLE, CreateBufferRegionARB, (HDC, int, UINT)) +AGL_API(VOID, DeleteBufferRegionARB, (HANDLE)) +AGL_API(BOOL, SaveBufferRegionARB, (HANDLE, int, int, int, int)) +AGL_API(BOOL, RestoreBufferRegionARB, (HANDLE, int, int, int, int, int, int)) + +/* WGL_ARB_extensions_string */ +AGL_API(const char *, GetExtensionsStringARB, (HDC)) + +/* WGL_ARB_pixel_format */ +AGL_API(BOOL, GetPixelFormatAttribivARB, (HDC, int, int, UINT, const int *, int *)) +AGL_API(BOOL, GetPixelFormatAttribfvARB, (HDC, int, int, UINT, const int *, FLOAT *)) +AGL_API(BOOL, ChoosePixelFormatARB, (HDC, const int *, const FLOAT *, UINT, int *, UINT *)) + +/* WGL_ARB_make_current_read */ +AGL_API(BOOL, MakeContextCurrentARB, (HDC, HDC, HGLRC)) +AGL_API(HDC, GetCurrentReadDCARB, (void)) + +/* WGL_ARB_pbuffer */ +AGL_API(HPBUFFERARB, CreatePbufferARB, (HDC, int, int, int, const int *)) +AGL_API(HDC, GetPbufferDCARB, (HPBUFFERARB)) +AGL_API(int, ReleasePbufferDCARB, (HPBUFFERARB, HDC)) +AGL_API(BOOL, DestroyPbufferARB, (HPBUFFERARB)) +AGL_API(BOOL, QueryPbufferARB, (HPBUFFERARB, int, int *)) + +/* WGL_ARB_render_texture */ +AGL_API(BOOL, BindTexImageARB, (HPBUFFERARB, int)) +AGL_API(BOOL, ReleaseTexImageARB, (HPBUFFERARB, int)) +AGL_API(BOOL, SetPbufferAttribARB, (HPBUFFERARB, const int *)) + +/* WGL_ARB_create_context */ +AGL_API(HGLRC, CreateContextAttribsARB, (HDC, HGLRC, const int *)) + +/* WGL_EXT_display_color_table */ +AGL_API(GLboolean, CreateDisplayColorTableEXT, (GLushort)) +AGL_API(GLboolean, LoadDisplayColorTableEXT, (const GLushort *, GLuint)) +AGL_API(GLboolean, BindDisplayColorTableEXT, (GLushort)) +AGL_API(VOID, DestroyDisplayColorTableEXT, (GLushort)) + +/* WGL_EXT_extensions_string */ +AGL_API(const char *, GetExtensionsStringEXT, (void)) + +/* WGL_EXT_make_current_read */ +AGL_API(BOOL, MakeContextCurrentEXT, (HDC, HDC, HGLRC)) +AGL_API(HDC, GetCurrentReadDCEXT, (void)) + +/* WGL_EXT_pbuffer */ +AGL_API(HPBUFFEREXT, CreatePbufferEXT, (HDC, int, int, int, const int *)) +AGL_API(HDC, GetPbufferDCEXT, (HPBUFFEREXT)) +AGL_API(int, ReleasePbufferDCEXT, (HPBUFFEREXT, HDC)) +AGL_API(BOOL, DestroyPbufferEXT, (HPBUFFEREXT)) +AGL_API(BOOL, QueryPbufferEXT, (HPBUFFEREXT, int, int *)) + +/* WGL_EXT_pixel_format */ +AGL_API(BOOL, GetPixelFormatAttribivEXT, (HDC, int, int, UINT, int *, int *)) +AGL_API(BOOL, GetPixelFormatAttribfvEXT, (HDC, int, int, UINT, int *, FLOAT *)) +AGL_API(BOOL, ChoosePixelFormatEXT, (HDC, const int *, const FLOAT *, UINT, int *, UINT *)) + +/* WGL_EXT_swap_control */ +AGL_API(BOOL, SwapIntervalEXT, (int)) +AGL_API(int, GetSwapIntervalEXT, (void)) + +/* WGL_NV_vertex_array_range */ +AGL_API(void*, AllocateMemoryNV, (GLsizei, GLfloat, GLfloat, GLfloat)) +AGL_API(void, FreeMemoryNV, (void *)) + +/* WGL_OML_sync_control */ +AGL_API(BOOL, GetSyncValuesOML, (HDC, INT64 *, INT64 *, INT64 *)) +AGL_API(BOOL, GetMscRateOML, (HDC, INT32 *, INT32 *)) +AGL_API(INT64, SwapBuffersMscOML, (HDC, INT64, INT64, INT64)) +AGL_API(INT64, SwapLayerBuffersMscOML, (HDC, int, INT64, INT64, INT64)) +AGL_API(BOOL, WaitForMscOML, (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *)) +AGL_API(BOOL, WaitForSbcOML, (HDC, INT64, INT64 *, INT64 *, INT64 *)) + +/* WGL_I3D_digital_video_control */ +AGL_API(BOOL, GetDigitalVideoParametersI3D, (HDC, int, int *)) +AGL_API(BOOL, SetDigitalVideoParametersI3D, (HDC, int, const int *)) + +/* WGL_I3D_gamma */ +AGL_API(BOOL, GetGammaTableParametersI3D, (HDC, int, int *)) +AGL_API(BOOL, SetGammaTableParametersI3D, (HDC, int, const int *)) +AGL_API(BOOL, GetGammaTableI3D, (HDC, int, USHORT *, USHORT *, USHORT *)) +AGL_API(BOOL, SetGammaTableI3D, (HDC, int, const USHORT *, const USHORT *, const USHORT *)) + +/* WGL_I3D_genlock */ +AGL_API(BOOL, EnableGenlockI3D, (HDC)) +AGL_API(BOOL, DisableGenlockI3D, (HDC)) +AGL_API(BOOL, IsEnabledGenlockI3D, (HDC, BOOL *)) +AGL_API(BOOL, GenlockSourceI3D, (HDC, UINT)) +AGL_API(BOOL, GetGenlockSourceI3D, (HDC, UINT *)) +AGL_API(BOOL, GenlockSourceEdgeI3D, (HDC, UINT)) +AGL_API(BOOL, GetGenlockSourceEdgeI3D, (HDC, UINT *)) +AGL_API(BOOL, GenlockSampleRateI3D, (HDC, UINT)) +AGL_API(BOOL, GetGenlockSampleRateI3D, (HDC, UINT *)) +AGL_API(BOOL, GenlockSourceDelayI3D, (HDC, UINT)) +AGL_API(BOOL, GetGenlockSourceDelayI3D, (HDC, UINT *)) +AGL_API(BOOL, QueryGenlockMaxSourceDelayI3D, (HDC, UINT *, UINT *)) + +/* WGL_I3D_image_buffer */ +AGL_API(LPVOID, CreateImageBufferI3D, (HDC, DWORD, UINT)) +AGL_API(BOOL, DestroyImageBufferI3D, (HDC, LPVOID)) +AGL_API(BOOL, AssociateImageBufferEventsI3D, (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT)) +AGL_API(BOOL, ReleaseImageBufferEventsI3D, (HDC, const LPVOID *, UINT)) + +/* WGL_I3D_swap_frame_lock */ +AGL_API(BOOL, EnableFrameLockI3D, (void)) +AGL_API(BOOL, DisableFrameLockI3D, (void)) +AGL_API(BOOL, IsEnabledFrameLockI3D, (BOOL *)) +AGL_API(BOOL, QueryFrameLockMasterI3D, (BOOL *)) + +/* WGL_I3D_swap_frame_usage */ +AGL_API(BOOL, GetFrameUsageI3D, (float *)) +AGL_API(BOOL, BeginFrameTrackingI3D, (void)) +AGL_API(BOOL, EndFrameTrackingI3D, (void)) +AGL_API(BOOL, QueryFrameTrackingI3D, (DWORD *, DWORD *, float *)) + +/* glAddSwapHintRectWIN */ +AGL_API(void, AddSwapHintRectWIN, (int, int, int, int)) + +/* WGL_NV_present_video */ +AGL_API(int, EnumerateVideoDevicesNV, (HDC, HVIDEOOUTPUTDEVICENV *)) +AGL_API(BOOL, BindVideoDeviceNV, (HDC, unsigned int, HVIDEOOUTPUTDEVICENV, const int *)) +AGL_API(BOOL, QueryCurrentContextNV, (int, int *)) + +/* WGL_NV_video_out */ +AGL_API(BOOL, GetVideoDeviceNV, (HDC, int, HPVIDEODEV *)) +AGL_API(BOOL, ReleaseVideoDeviceNV, (HPVIDEODEV)) +AGL_API(BOOL, BindVideoImageNV, (HPVIDEODEV, HPBUFFERARB, int)) +AGL_API(BOOL, ReleaseVideoImageNV, (HPBUFFERARB, int)) +AGL_API(BOOL, SendPbufferToVideoNV, (HPBUFFERARB, int, unsigned long *, BOOL)) +AGL_API(BOOL, GetVideoInfoNV, (HPVIDEODEV, unsigned long *, unsigned long *)) + +/* WGL_NV_swap_group */ +AGL_API(BOOL, JoinSwapGroupNV, (HDC hDC, GLuint group)) +AGL_API(BOOL, BindSwapBarrierNV, (GLuint group, GLuint barrier)) +AGL_API(BOOL, QuerySwapGroupNV, (HDC hDC, GLuint *group, GLuint *barrier)) +AGL_API(BOOL, QueryMaxSwapGroupsNV, (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers)) +AGL_API(BOOL, QueryFrameCountNV, (HDC hDC, GLuint *count)) +AGL_API(BOOL, ResetFrameCountNV, (HDC hDC)) + +/* WGL_NV_gpu_affinity */ +AGL_API(BOOL, EnumGpusNV, (UINT, HGPUNV *)) +AGL_API(BOOL, EnumGpuDevicesNV, (HGPUNV, UINT, PGPU_DEVICE)) +AGL_API(HDC, CreateAffinityDCNV, (const HGPUNV *)) +AGL_API(BOOL, EnumGpusFromAffinityDCNV, (HDC, UINT, HGPUNV *)) +AGL_API(BOOL, DeleteDCNV, (HDC)) + +/* WGL_AMD_gpu_association */ +AGL_API(UINT, GetGPUIDsAMD, (UINT, UINT *)) +AGL_API(INT, GetGPUInfoAMD, (UINT, int, GLenum, UINT, void *)) +AGL_API(UINT, GetContextGPUIDAMD, (HGLRC)) +AGL_API(HGLRC, CreateAssociatedContextAMD, (UINT)) +AGL_API(HGLRC, CreateAssociatedContextAttribsAMD, (UINT, HGLRC, const int *)) +AGL_API(BOOL, DeleteAssociatedContextAMD, (HGLRC)) +AGL_API(BOOL, MakeAssociatedContextCurrentAMD, (HGLRC)) +AGL_API(HGLRC, GetCurrentAssociatedContextAMD, (void)) +AGL_API(VOID, BlitContextFramebufferAMD, (HGLRC, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) + +/* WGL_NV_video_capture */ +AGL_API(BOOL, BindVideoCaptureDeviceNV, (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice)) +AGL_API(UINT, EnumerateVideoCaptureDevicesNV, (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList)) +AGL_API(BOOL, LockVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice)) +AGL_API(BOOL, QueryVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue)) +AGL_API(BOOL, ReleaseVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice)) + +/* WGL_NV_copy_image */ +AGL_API(BOOL, CopyImageSubDataNV, (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth)) diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_defs.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_defs.h new file mode 100644 index 00000000..aed3eac5 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_defs.h @@ -0,0 +1,386 @@ +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#endif + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer +DECLARE_HANDLE(HPBUFFERARB); +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#endif + + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float +#define AWGL_ARB_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +#endif + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define ERROR_INVALID_PROFILE_ARB 0x2096 +#endif + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer +DECLARE_HANDLE(HPBUFFEREXT); +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#endif + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#endif + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 +#endif + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 +#endif + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 +#endif + +#ifndef WGL_WIN_swap_hint +#define WGL_WIN_swap_hint +#endif + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 +#endif + +#ifndef WGL_NV_video_out +#define WGL_NV_video_out +DECLARE_HANDLE(HPVIDEODEV); +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC +#endif + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group +#endif + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity +DECLARE_HANDLE(HPGPUNV); +DECLARE_HANDLE(HGPUNV); + +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 +#endif + +#ifndef WGL_AMD_gpu_association +#define WGL_AMD_gpu_association +#define WGL_GPU_VENDOR_AMD 0x1F00 +#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 +#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define WGL_GPU_RAM_AMD 0x21A3 +#define WGL_GPU_CLOCK_AMD 0x21A4 +#define WGL_GPU_NUM_PIPES_AMD 0x21A5 +#define WGL_GPU_NUM_SIMD_AMD 0x21A6 +#define WGL_GPU_NUM_RB_AMD 0x21A7 +#define WGL_GPU_NUM_SPI_AMD 0x21A8 +#endif + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF +#endif + +#ifndef WGL_NV_copy_image +#define WGL_NV_copy_image +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_list.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_list.h new file mode 100644 index 00000000..1fd69621 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/GLext/wgl_ext_list.h @@ -0,0 +1,38 @@ +AGL_EXT(ARB_buffer_region, 0) +AGL_EXT(ARB_multisample, 0) +AGL_EXT(ARB_extensions_string, 0) +AGL_EXT(ARB_pixel_format, 0) +AGL_EXT(ARB_make_current_read, 0) +AGL_EXT(ARB_pbuffer, 0) +AGL_EXT(ARB_render_texture, 0) +AGL_EXT(ARB_pixel_format_float, 0) +AGL_EXT(EXT_display_color_table, 0) +AGL_EXT(EXT_extensions_string, 0) +AGL_EXT(EXT_make_current_read, 0) +AGL_EXT(EXT_pixel_format, 0) +AGL_EXT(EXT_pbuffer, 0) +AGL_EXT(EXT_swap_control, 0) +AGL_EXT(EXT_depth_float, 0) +AGL_EXT(EXT_multisample, 0) +AGL_EXT(OML_sync_control, 0) +AGL_EXT(I3D_digital_video_control, 0) +AGL_EXT(I3D_gamma, 0) +AGL_EXT(I3D_genlock, 0) +AGL_EXT(I3D_image_buffer, 0) +AGL_EXT(I3D_swap_frame_lock, 0) +AGL_EXT(I3D_swap_frame_usage, 0) +AGL_EXT(NV_render_depth_texture, 0) +AGL_EXT(NV_render_texture_rectangle, 0) +AGL_EXT(ATI_pixel_format_float, 0) +AGL_EXT(EXT_framebuffer_sRGB, 0) +AGL_EXT(EXT_pixel_format_packed_float,0) +AGL_EXT(WIN_swap_hint, 0) +AGL_EXT(3DL_stereo_control, 0) +AGL_EXT(NV_swap_group, 0) +AGL_EXT(NV_gpu_affinity, 0) +AGL_EXT(NV_video_out, 0) +AGL_EXT(NV_present_video, 0) +AGL_EXT(ARB_create_context, 0) +AGL_EXT(AMD_gpu_association, 0) +AGL_EXT(NV_copy_image, 0) +AGL_EXT(NV_video_capture, 0) diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/gl_ext.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/gl_ext.h new file mode 100644 index 00000000..df8cc559 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/opengl/gl_ext.h @@ -0,0 +1,140 @@ + +#ifndef __al_included_allegro5_gl_ext_h +#define __al_included_allegro5_gl_ext_h + + +/* + * MSVC declares the following extensions and MinGW doesn't. In order to + * export the same symbols on both platforms we removed the extensions from + * MSVC. + */ +#ifdef ALLEGRO_MSVC + #undef GL_EXT_vertex_array + #undef GL_EXT_paletted_texture + #undef GL_WIN_swap_hint + #undef GL_WIN_draw_range_elements +#endif + +/* GL extension definitions. */ + +/* For example: + * + * #define GL_BGRA 0x80E1 + * + */ + +#if !defined ALLEGRO_CFG_OPENGLES +#include "allegro5/opengl/GLext/gl_ext_defs.h" +#endif +#if defined ALLEGRO_WINDOWS && !defined ALLEGRO_EXCLUDE_WGL +#include "allegro5/opengl/GLext/wgl_ext_defs.h" +#elif defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX +#include "allegro5/opengl/GLext/glx_ext_defs.h" +#endif + +/* GL extension types */ + +/* For example: + * + * typedef void (APIENTRY * _ALLEGRO_glBlendEquation_t (GLenum); + * + */ + +#ifndef APIENTRY +#define APIENTRY +#define APIENTRY_defined +#endif + +#define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_gl##name##_t) args; +# include "allegro5/opengl/GLext/gl_ext_api.h" +#undef AGL_API +#ifdef ALLEGRO_WINDOWS +#define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_wgl##name##_t) args; +# include "allegro5/opengl/GLext/wgl_ext_api.h" +#undef AGL_API +#elif defined ALLEGRO_UNIX +#define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_glX##name##_t) args; +# include "allegro5/opengl/GLext/glx_ext_api.h" +#undef AGL_API +#endif + +#ifdef APIENTRY_defined +#undef APIENTRY +#undef APIENTRY_defined +#endif + +/* GL extension declarations */ + +/* For example: + * + * #define glBlendEquation _al_glBlendEquation + * extern _ALLEGRO_glBlendEquation_t _al_glBlendEquation; + * + */ + +#define AGL_API(type, name, args) AL_VAR(_ALLEGRO_gl##name##_t, _al_gl##name); +# include "allegro5/opengl/GLext/gl_ext_alias.h" +# include "allegro5/opengl/GLext/gl_ext_api.h" +#undef AGL_API +#ifdef ALLEGRO_WINDOWS +#define AGL_API(type, name, args) AL_VAR(_ALLEGRO_wgl##name##_t, _al_wgl##name); +# include "allegro5/opengl/GLext/wgl_ext_alias.h" +# include "allegro5/opengl/GLext/wgl_ext_api.h" +#undef AGL_API +#elif defined ALLEGRO_UNIX +#define AGL_API(type, name, args) extern _ALLEGRO_glX##name##_t _al_glX##name; +# include "allegro5/opengl/GLext/glx_ext_alias.h" +# include "allegro5/opengl/GLext/glx_ext_api.h" +#undef AGL_API +#endif + +/* A list of all supported extensions. + * + * For example: + * int ALLEGRO_GL_ARB_imaging; + * + */ + +typedef struct ALLEGRO_OGL_EXT_LIST { +# define AGL_EXT(name, ver) int ALLEGRO_GL_##name; +# include "allegro5/opengl/GLext/gl_ext_list.h" +# undef AGL_EXT + +#ifdef ALLEGRO_UNIX +# define AGL_EXT(name, ver) int ALLEGRO_GLX_##name; +# include "allegro5/opengl/GLext/glx_ext_list.h" +# undef AGL_EXT +#elif defined ALLEGRO_WINDOWS +# define AGL_EXT(name, ver) int ALLEGRO_WGL_##name; +# include "allegro5/opengl/GLext/wgl_ext_list.h" +# undef AGL_EXT + +#endif +} ALLEGRO_OGL_EXT_LIST; + + +/* GL extension Structure. Holds the pointers to all the functions + * of all extensions, for a single context. + * + * Example: + * ALLEGRO_BlendEquation_t BlendEquation; + */ +typedef struct ALLEGRO_OGL_EXT_API { +#define AGL_API(type, name, args) _ALLEGRO_gl##name##_t name; +# include "allegro5/opengl/GLext/gl_ext_api.h" +#undef AGL_API +#ifdef ALLEGRO_WINDOWS +#define AGL_API(type, name, args) _ALLEGRO_wgl##name##_t name; +# include "allegro5/opengl/GLext/wgl_ext_api.h" +#undef AGL_API +#elif defined ALLEGRO_UNIX +#define AGL_API(type, name, args) _ALLEGRO_glX##name##_t name; +# include "allegro5/opengl/GLext/glx_ext_api.h" +#undef AGL_API +#endif +} ALLEGRO_OGL_EXT_API; + + + +#endif + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/path.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/path.h new file mode 100644 index 00000000..ce229cb4 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/path.h @@ -0,0 +1,55 @@ +#ifndef __al_included_allegro5_path_h +#define __al_included_allegro5_path_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef ALLEGRO_WINDOWS +# define ALLEGRO_NATIVE_PATH_SEP '\\' +# define ALLEGRO_NATIVE_DRIVE_SEP ':' +#else +# define ALLEGRO_NATIVE_PATH_SEP '/' +# define ALLEGRO_NATIVE_DRIVE_SEP '\0' +#endif + +typedef struct ALLEGRO_PATH ALLEGRO_PATH; + +AL_FUNC(ALLEGRO_PATH*, al_create_path, (const char *str)); +AL_FUNC(ALLEGRO_PATH*, al_create_path_for_directory, (const char *str)); +AL_FUNC(ALLEGRO_PATH*, al_clone_path, (const ALLEGRO_PATH *path)); + +AL_FUNC(int, al_get_path_num_components, (const ALLEGRO_PATH *path)); +AL_FUNC(const char*, al_get_path_component, (const ALLEGRO_PATH *path, int i)); +AL_FUNC(void, al_replace_path_component, (ALLEGRO_PATH *path, int i, const char *s)); +AL_FUNC(void, al_remove_path_component, (ALLEGRO_PATH *path, int i)); +AL_FUNC(void, al_insert_path_component, (ALLEGRO_PATH *path, int i, const char *s)); +AL_FUNC(const char*, al_get_path_tail, (const ALLEGRO_PATH *path)); +AL_FUNC(void, al_drop_path_tail, (ALLEGRO_PATH *path)); +AL_FUNC(void, al_append_path_component, (ALLEGRO_PATH *path, const char *s)); +AL_FUNC(bool, al_join_paths, (ALLEGRO_PATH *path, const ALLEGRO_PATH *tail)); +AL_FUNC(bool, al_rebase_path, (const ALLEGRO_PATH *head, ALLEGRO_PATH *tail)); +AL_FUNC(const char*, al_path_cstr, (const ALLEGRO_PATH *path, char delim)); +AL_FUNC(void, al_destroy_path, (ALLEGRO_PATH *path)); + +AL_FUNC(void, al_set_path_drive, (ALLEGRO_PATH *path, const char *drive)); +AL_FUNC(const char*, al_get_path_drive, (const ALLEGRO_PATH *path)); + +AL_FUNC(void, al_set_path_filename, (ALLEGRO_PATH *path, const char *filename)); +AL_FUNC(const char*, al_get_path_filename, (const ALLEGRO_PATH *path)); + +AL_FUNC(const char*, al_get_path_extension, (const ALLEGRO_PATH *path)); +AL_FUNC(bool, al_set_path_extension, (ALLEGRO_PATH *path, char const *extension)); +AL_FUNC(const char*, al_get_path_basename, (const ALLEGRO_PATH *path)); + +AL_FUNC(bool, al_make_path_canonical, (ALLEGRO_PATH *path)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alandroid.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alandroid.h new file mode 100644 index 00000000..261cd7df --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alandroid.h @@ -0,0 +1,29 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android-specific header defines. + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_ANDROID + #error bad include +#endif + +#include + +#ifdef __cplusplus +extern "C" int main(int argc, char ** argv); +#else +extern int main(int argc, char ** argv); +#endif + +/* Nothing left */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alandroidcfg.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alandroidcfg.h new file mode 100644 index 00000000..9399c43e --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alandroidcfg.h @@ -0,0 +1,25 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on Android platforms. + * + * By Thomas Fjellstrom. + * + * See readme.txt for copyright information. + */ + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "Android" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alandroid.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintandroid.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +#define ALLEGRO_EXCLUDE_GLX diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/albcc32.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/albcc32.h new file mode 100644 index 00000000..102eec87 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/albcc32.h @@ -0,0 +1,98 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with Borland C++Builder. + * + * By Greg Hackmann. + * + * See readme.txt for copyright information. + */ + + +/* +#ifdef ALLEGRO_SRC + #error Currently BCC32 cannot build the library +#endif +*/ + + +#include +#include +#include +#include + + +#pragma warn -8004 /* unused assigned value */ +#pragma warn -8008 /* condition always met */ +#pragma warn -8057 /* unused parameter */ +#pragma warn -8066 /* unreachable code */ + + +/* describe this platform */ +#define ALLEGRO_PLATFORM_STR "BCC32" +#define ALLEGRO_WINDOWS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN +#define ALLEGRO_GUESS_INTTYPES_OK + /* TODO: check if BCC has inttypes.h and/or stdint.h */ + +#ifdef ALLEGRO_USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN +#endif + + +/* describe how function prototypes look to BCC32 */ +#if (defined ALLEGRO_STATICLINK) + #define _AL_DLL +#elif (defined ALLEGRO_SRC) + #define _AL_DLL __declspec(dllexport) +#else + #define _AL_DLL __declspec(dllimport) +#endif + +#define AL_VAR(type, name) extern _AL_DLL type name +#define AL_ARRAY(type, name) extern _AL_DLL type name[] +#define AL_FUNC(type, name, args) extern _AL_DLL type name args +#define AL_METHOD(type, name, args) type (*name) args +#define AL_FUNCPTR(type, name, args) extern _AL_DLL type (*name) args + + +#define END_OF_INLINE(name) +//#define AL_INLINE(type, name, args, code) extern __inline type name args code END_OF_INLINE(name) + +#define INLINE __inline + +#undef AL_INLINE +#undef AL_INLINE_STATIC + +#define AL_INLINE(type, name, args, code) extern __inline type __cdecl name args code END_OF_INLINE(name) +#define AL_INLINE_STATIC(type, name, args, code) static __inline type name args code END_OF_INLINE(name) + +#define LONG_LONG __int64 +#define int64_t signed __int64 +#define uint64_t unsigned __int64 + +#define __func__ "FIXME" + +#define _wfindfirst __wfindfirst +#define _wfindnext __wfindnext + +#define WinMain _main + +/* windows specific defines */ +#ifdef NONAMELESSUNION + #undef NONAMELESSUNION +#endif +/* This fixes 99.999999% of Borland C++Builder's problems with structs. */ + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/aliphone.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/aliphone.h new file mode 100644 index 00000000..228c07ee --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/aliphone.h @@ -0,0 +1,11 @@ +#ifndef ALLEGRO_IPHONE + #error bad include +#endif + +#ifndef ALLEGRO_LIB_BUILD +#define ALLEGRO_MAGIC_MAIN +#define main _al_mangled_main +#ifdef __cplusplus + extern "C" int _al_mangled_main(int, char **); +#endif +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/aliphonecfg.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/aliphonecfg.h new file mode 100644 index 00000000..a4739acc --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/aliphonecfg.h @@ -0,0 +1,33 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on iOS. + * + * See readme.txt for copyright information. + */ + + +#include +#include + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "IPHONE" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/aliphone.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintiphone.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +#define ALLEGRO_EXCLUDE_GLX + +#ifndef AL_INLINE +#define AL_INLINE(type, name, args, code) \ +static __inline__ type name args; \ +static __inline__ type name args code +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/allegro_sdl_config.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/allegro_sdl_config.h new file mode 100644 index 00000000..79e98d1b --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/allegro_sdl_config.h @@ -0,0 +1,8 @@ +#define ALLEGRO_PLATFORM_STR "SDL" + +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/allegro_internal_sdl.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/allegro_sdl_thread.h" + +// FIXME: remove once we don't use Unix specifics anymore +#include +#include diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/almngw32.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/almngw32.h new file mode 100644 index 00000000..cfda24fd --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/almngw32.h @@ -0,0 +1,84 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with Mingw32. + * + * By Michael Rickmann. + * + * Native build version by Henrik Stokseth. + * + * See readme.txt for copyright information. + */ + + +#include +#include +#include +#include + +#include "allegro5/platform/alplatf.h" + + +/* describe this platform */ +#ifdef ALLEGRO_STATICLINK + #define ALLEGRO_PLATFORM_STR "MinGW32.s" +#else + #define ALLEGRO_PLATFORM_STR "MinGW32" +#endif + +#define ALLEGRO_WINDOWS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN + +#ifdef ALLEGRO_USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN +#endif + + +/* describe how function prototypes look to MINGW32 */ +#if (defined ALLEGRO_STATICLINK) || (defined ALLEGRO_SRC) + #define _AL_DLL +#else + #define _AL_DLL __declspec(dllimport) +#endif + +#define AL_VAR(type, name) extern _AL_DLL type name +#define AL_ARRAY(type, name) extern _AL_DLL type name[] +#define AL_FUNC(type, name, args) extern type name args +#define AL_METHOD(type, name, args) type (*name) args +#define AL_FUNCPTR(type, name, args) extern _AL_DLL type (*name) args + + +/* windows specific defines */ + +#if (defined ALLEGRO_SRC) +/* pathches to handle DX7 headers on a win9x system */ + +/* should WINNT be defined on win9x systems? */ +#ifdef WINNT + #undef WINNT +#endif + +/* defined in windef.h */ +#ifndef HMONITOR_DECLARED + #define HMONITOR_DECLARED 1 +#endif + +#endif /* ALLEGRO_SRC */ + +/* another instance of missing constants in the mingw32 headers */ +#ifndef ENUM_CURRENT_SETTINGS + #define ENUM_CURRENT_SETTINGS ((DWORD)-1) +#endif + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/almsvc.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/almsvc.h new file mode 100644 index 00000000..906a95fb --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/almsvc.h @@ -0,0 +1,107 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with MSVC. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#include +#include +#include +#include + +#include "allegro5/platform/alplatf.h" + +#pragma warning (disable: 4200 4244 4305 4800) + + +/* describe this platform */ +#ifdef ALLEGRO_STATICLINK + #define ALLEGRO_PLATFORM_STR "MSVC.s" +#else + #define ALLEGRO_PLATFORM_STR "MSVC" +#endif + +#define ALLEGRO_WINDOWS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN +#define ALLEGRO_GUESS_INTTYPES_OK + +#ifdef ALLEGRO_USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN +#endif + + +/* describe how function prototypes look to MSVC */ +#ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_SRC + #define _AL_DLL __declspec(dllexport) + #else + #define _AL_DLL __declspec(dllimport) + #endif +#else + #define _AL_DLL +#endif + +#define AL_VAR(type, name) extern _AL_DLL type name +#define AL_ARRAY(type, name) extern _AL_DLL type name[] +#define AL_FUNC(type, name, args) _AL_DLL type __cdecl name args +#define AL_METHOD(type, name, args) type (__cdecl *name) args +#define AL_FUNCPTR(type, name, args) extern _AL_DLL type (__cdecl *name) args + +#ifdef AL_INLINE + #define END_OF_INLINE(name) void *_force_instantiate_##name = name; +#else + #define END_OF_INLINE(name) +#endif + +#undef AL_INLINE +#undef AL_INLINE_STATIC + +#define AL_INLINE(type, name, args, code) __inline _AL_DLL type __cdecl name args code END_OF_INLINE(name) +#define AL_INLINE_STATIC(type, name, args, code) __inline type __cdecl name args code END_OF_INLINE(name) + +#define INLINE __inline + +#define LONG_LONG __int64 + +/* VC10 is the first version to define int64_t and uint64_t */ +#if _MSC_VER < 1600 +#define int64_t signed __int64 +#define uint64_t unsigned __int64 +#endif + +/* __func__ is C99 */ +#ifndef __func__ + /* MSVC versions before VC7 don't have __FUNCTION__ */ + #if _MSC_VER < 1300 + #define __func__ "???" + #else + #define __func__ __FUNCTION__ + #endif +#endif + + +/* life would be so easy if compilers would all use the same names! */ +#if (!defined S_IRUSR) + #define S_IRUSR S_IREAD + #define S_IWUSR S_IWRITE + #define S_IXUSR S_IEXEC +#endif + + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alosx.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alosx.h new file mode 100644 index 00000000..0c36c84f --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alosx.h @@ -0,0 +1,80 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * MacOS X specific header defines. + * + * By Angelo Mottola. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_alosx_h +#define __al_included_allegro5_alosx_h + +#ifndef ALLEGRO_MACOSX + #error bad include +#endif + + + +#include +#include +#include +#include +#include +#include +#if defined __OBJC__ && defined ALLEGRO_SRC + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import +#endif + +ALLEGRO_PATH *_al_osx_get_path(int id); + +#ifndef ALLEGRO_LIB_BUILD + #ifndef ALLEGRO_NO_MAGIC_MAIN + #define ALLEGRO_MAGIC_MAIN + #if __GNUC__ >= 4 + #define main __attribute__ ((visibility("default"))) _al_mangled_main + #else + #define main _al_mangled_main + #endif + #ifdef __cplusplus + extern "C" int _al_mangled_main(int, char **); + /* We can't provide a prototype for C without restricting + * users into a single function signature for main(). + */ + #endif + #endif +#endif + +/* Keyboard driver */ +#define KEYBOARD_MACOSX AL_ID('O','S','X','K') + +#endif + +/* Local variables: */ +/* mode: objc */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alosxcfg.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alosxcfg.h new file mode 100644 index 00000000..830cf116 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alosxcfg.h @@ -0,0 +1,36 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with MacOS X. + * + * By Angelo Mottola. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_alosxcfg_h +#define __al_included_allegro5_alosxcfg_h + +/* Include configuration information. */ +#include "allegro5/platform/alplatf.h" + +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +/* Describe this platform */ +#define ALLEGRO_PLATFORM_STR "MacOS X" + + +/* Arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alosx.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintosx.h" + + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alplatf.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alplatf.h new file mode 100644 index 00000000..e892b051 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alplatf.h @@ -0,0 +1,114 @@ +/* alplatf.h is generated from alplatf.h.cmake */ +/* #undef ALLEGRO_MINGW32 */ +/* #undef ALLEGRO_UNIX */ +#define ALLEGRO_MSVC +/* #undef ALLEGRO_MACOSX */ +/* #undef ALLEGRO_BCC32 */ +/* #undef ALLEGRO_IPHONE */ +/* #undef ALLEGRO_ANDROID */ +/* #undef ALLEGRO_RASPBERRYPI */ +/* #undef ALLEGRO_CFG_NO_FPU */ +/* #undef ALLEGRO_CFG_DLL_TLS */ +/* #undef ALLEGRO_CFG_PTHREADS_TLS */ +#define ALLEGRO_CFG_RELEASE_LOGGING + +#define ALLEGRO_CFG_D3D +/* #undef ALLEGRO_CFG_D3D9EX */ +#define ALLEGRO_CFG_D3DX9 +#define ALLEGRO_CFG_XINPUT +#define ALLEGRO_CFG_OPENGL +/* #undef ALLEGRO_CFG_OPENGLES */ +/* #undef ALLEGRO_CFG_OPENGLES2 */ +#define ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE +#define ALLEGRO_CFG_SHADER_GLSL +#define ALLEGRO_CFG_SHADER_HLSL +/* #undef ALLEGRO_CFG_OPENGL_S3TC_LOCKING */ + +/* #undef ALLEGRO_CFG_ANDROID_LEGACY */ + +/*---------------------------------------------------------------------------*/ + +/* Define to 1 if you have the corresponding header file. */ +/* #undef ALLEGRO_HAVE_DIRENT_H */ +#define ALLEGRO_HAVE_INTTYPES_H +/* #undef ALLEGRO_HAVE_LINUX_AWE_VOICE_H */ +/* #undef ALLEGRO_HAVE_LINUX_INPUT_H */ +/* #undef ALLEGRO_HAVE_LINUX_SOUNDCARD_H */ +/* #undef ALLEGRO_HAVE_MACHINE_SOUNDCARD_H */ +/* #undef ALLEGRO_HAVE_SOUNDCARD_H */ +#define ALLEGRO_HAVE_STDBOOL_H +#define ALLEGRO_HAVE_STDINT_H +/* #undef ALLEGRO_HAVE_SV_PROCFS_H */ +/* #undef ALLEGRO_HAVE_SYS_IO_H */ +/* #undef ALLEGRO_HAVE_SYS_SOUNDCARD_H */ +#define ALLEGRO_HAVE_SYS_STAT_H +/* #undef ALLEGRO_HAVE_SYS_TIME_H */ +#define ALLEGRO_HAVE_TIME_H +/* #undef ALLEGRO_HAVE_SYS_UTSNAME_H */ +#define ALLEGRO_HAVE_SYS_TYPES_H +/* #undef ALLEGRO_HAVE_OSATOMIC_H */ +/* #undef ALLEGRO_HAVE_SYS_INOTIFY_H */ +#define ALLEGRO_HAVE_SAL_H + +/* Define to 1 if the corresponding functions are available. */ +/* #undef ALLEGRO_HAVE_GETEXECNAME */ +/* #undef ALLEGRO_HAVE_MKSTEMP */ +/* #undef ALLEGRO_HAVE_MMAP */ +/* #undef ALLEGRO_HAVE_MPROTECT */ +/* #undef ALLEGRO_HAVE_SCHED_YIELD */ +/* #undef ALLEGRO_HAVE_SYSCONF */ +/* #undef ALLEGRO_HAVE_SYSCTL */ + +/* #undef ALLEGRO_HAVE_FSEEKO */ +/* #undef ALLEGRO_HAVE_FTELLO */ +/* #undef ALLEGRO_HAVE_STRERROR_R */ +#define ALLEGRO_HAVE_STRERROR_S +#define ALLEGRO_HAVE_VA_COPY + +/* Define to 1 if procfs reveals argc and argv */ +/* #undef ALLEGRO_HAVE_PROCFS_ARGCV */ + +/*---------------------------------------------------------------------------*/ + +/* Define if target machine is little endian. */ +#define ALLEGRO_LITTLE_ENDIAN + +/* Define if target machine is big endian. */ +/* #undef ALLEGRO_BIG_ENDIAN */ + +/* Define if target platform is Darwin. */ +/* #undef ALLEGRO_DARWIN */ + +/*---------------------------------------------------------------------------*/ + +/* Define if you need support for X-Windows. */ +/* #undef ALLEGRO_WITH_XWINDOWS */ + +/* Define if XCursor ARGB extension is available. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XCURSOR */ + +/* Define if XF86VidMode extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE */ + +/* Define if Xinerama extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XINERAMA */ + +/* Define if XRandR extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XRANDR */ + +/* Define if XIM extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XIM */ + +/* Define if XInput 2.2 X11 extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XINPUT2 */ + +/*---------------------------------------------------------------------------*/ + +/* Define if target platform is linux. */ +/* #undef ALLEGRO_LINUX */ + +/* Define if we are building with SDL backend. */ +/* #undef ALLEGRO_SDL */ + +/*---------------------------------------------------------------------------*/ +/* vi: set ft=c ts=3 sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alraspberrypi.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alraspberrypi.h new file mode 100644 index 00000000..629a02ff --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alraspberrypi.h @@ -0,0 +1,25 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Raspberry Pi-specific header defines. + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_RASPBERRYPI + #error bad include +#endif + +#ifdef ALLEGRO_LIB_BUILD +#include "allegro5/platform/aintuthr.h" +#endif + +/* Nothing left */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alraspberrypicfg.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alraspberrypicfg.h new file mode 100644 index 00000000..17941ca7 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alraspberrypicfg.h @@ -0,0 +1,29 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on Raspberry Pi platforms. + * + * By Trent Gamblin. + * + * See readme.txt for copyright information. + */ + +#include +#include +#include + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "RaspberryPi" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alraspberrypi.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintraspberrypi.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +#define ALLEGRO_EXCLUDE_GLX diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alucfg.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alucfg.h new file mode 100644 index 00000000..b9947c88 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alucfg.h @@ -0,0 +1,40 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on Unix platforms. + * + * By Michael Bukin. + * + * See readme.txt for copyright information. + */ + + +#include +#include + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "Unix" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alunix.h" + +#ifdef _this_is_a_hack_to_fool_scons +#include "alunix.h" +#endif + +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintunix.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +/* Include configuration information. */ +#include "allegro5/platform/alplatf.h" + +/* Enable OpenGL if GLX is available. */ +#ifdef ALLEGRO_GLX +#define ALLEGRO_CFG_OPENGL +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alunix.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alunix.h new file mode 100644 index 00000000..ae1b858a --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alunix.h @@ -0,0 +1,23 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Unix-specific header defines. + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_UNIX + #error bad include +#endif + + +/* Nothing left */ + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alwatcom.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alwatcom.h new file mode 100644 index 00000000..2e5b0bc5 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alwatcom.h @@ -0,0 +1,182 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with Watcom. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __SW_3S + #error Allegro only supports stack based calling convention +#endif + +#ifndef __SW_S + #error Stack overflow checking must be disabled +#endif + +#include +#include +#include +#include +#include +#include + + +#pragma disable_message (120 201 202) + + +/* these are available in OpenWatcom 1.3 (12.3) */ +#if __WATCOMC__ >= 1230 + #define ALLEGRO_HAVE_INTTYPES_H 1 + #define ALLEGRO_HAVE_STDINT_H 1 +#else + #define ALLEGRO_GUESS_INTTYPES_OK +#endif + + +/* describe this platform */ +#define ALLEGRO_PLATFORM_STR "Watcom" +#define ALLEGRO_DOS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN + +#define LONG_LONG long long +#ifdef ALLEGRO_GUESS_INTTYPES_OK + #define int64_t signed long long + #define uint64_t unsigned long long +#endif + + +/* emulate some important djgpp routines */ +#define inportb(port) inp(port) +#define inportw(port) inpw(port) +#define outportb(port, val) outp(port, val) +#define outportw(port, val) outpw(port, val) + +#define ffblk find_t +#define ff_name name +#define ff_attrib attrib +#define ff_fsize size +#define ff_ftime wr_time +#define ff_fdate wr_date + +#define findfirst(name, dta, attrib) _dos_findfirst(name, attrib, dta) +#define findnext(dta) _dos_findnext(dta) + +#define random() rand() +#define srandom(n) srand(n) + +#define _dos_ds _default_ds() + +#define dosmemget(offset, length, buffer) memcpy(buffer, (void *)(offset), length) +#define dosmemput(buffer, length, offset) memcpy((void *)(offset), buffer, length) + +#define __djgpp_nearptr_enable() 1 +#define __djgpp_nearptr_disable() + +#define __djgpp_base_address 0 +#define __djgpp_conventional_base 0 + +#define _crt0_startup_flags 1 +#define _CRT0_FLAG_NEARPTR 1 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union __dpmi_regs +{ + struct { + unsigned long edi, esi, ebp, res, ebx, edx, ecx, eax; + } d; + struct { + unsigned short di, di_hi, si, si_hi, bp, bp_hi, res, res_hi; + unsigned short bx, bx_hi, dx, dx_hi, cx, cx_hi, ax, ax_hi; + unsigned short flags, es, ds, fs, gs, ip, cs, sp, ss; + } x; + struct { + unsigned char edi[4], esi[4], ebp[4], res[4]; + unsigned char bl, bh, ebx_b2, ebx_b3, dl, dh, edx_b2, edx_b3; + unsigned char cl, ch, ecx_b2, ecx_b3, al, ah, eax_b2, eax_b3; + } h; +} __dpmi_regs; + + +typedef struct __dpmi_meminfo +{ + unsigned long handle; + unsigned long size; + unsigned long address; +} __dpmi_meminfo; + + +typedef struct __dpmi_free_mem_info +{ + unsigned long largest_available_free_block_in_bytes; + unsigned long maximum_unlocked_page_allocation_in_pages; + unsigned long maximum_locked_page_allocation_in_pages; + unsigned long linear_address_space_size_in_pages; + unsigned long total_number_of_unlocked_pages; + unsigned long total_number_of_free_pages; + unsigned long total_number_of_physical_pages; + unsigned long free_linear_address_space_in_pages; + unsigned long size_of_paging_file_partition_in_pages; + unsigned long reserved[3]; +} __dpmi_free_mem_info; + + +extern unsigned long __tb; + + +int __dpmi_int(int vector, __dpmi_regs *regs); +int __dpmi_allocate_dos_memory(int paragraphs, int *ret); +int __dpmi_free_dos_memory(int selector); +int __dpmi_physical_address_mapping(__dpmi_meminfo *info); +int __dpmi_free_physical_address_mapping(__dpmi_meminfo *info); +int __dpmi_lock_linear_region(__dpmi_meminfo *info); +int __dpmi_unlock_linear_region(__dpmi_meminfo *info); +int __dpmi_allocate_ldt_descriptors(int count); +int __dpmi_free_ldt_descriptor(int descriptor); +int __dpmi_get_segment_base_address(int selector, unsigned long *addr); +int __dpmi_set_segment_base_address(int selector, unsigned long address); +int __dpmi_set_segment_limit(int selector, unsigned long limit); +int __dpmi_get_free_memory_information(__dpmi_free_mem_info *info); +int __dpmi_simulate_real_mode_interrupt(int vector, __dpmi_regs *regs); +int __dpmi_simulate_real_mode_procedure_retf(__dpmi_regs *regs); +int _go32_dpmi_lock_data(void *lockaddr, unsigned long locksize); +int _go32_dpmi_lock_code(void *lockaddr, unsigned long locksize); + +long _allocate_real_mode_callback(void (*handler)(__dpmi_regs *r), __dpmi_regs *regs); + + +/* memory locking macros */ +void _unlock_dpmi_data(void *addr, int size); + +#ifdef __cplusplus +} +#endif + + +#define END_OF_FUNCTION(x) void x##_end(void) { } +#define END_OF_STATIC_FUNCTION(x) static void x##_end(void) { } +#define LOCK_DATA(d, s) _go32_dpmi_lock_data(d, s) +#define LOCK_CODE(c, s) _go32_dpmi_lock_code(c, s) +#define UNLOCK_DATA(d,s) _unlock_dpmi_data(d, s) +#define LOCK_VARIABLE(x) LOCK_DATA((void *)&x, sizeof(x)) +#define LOCK_FUNCTION(x) LOCK_CODE((void *)FP_OFF(x), (long)FP_OFF(x##_end) - (long)FP_OFF(x)) + + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/aldos.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintdos.h" diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alwin.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alwin.h new file mode 100644 index 00000000..eab4b10f --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/alwin.h @@ -0,0 +1,148 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows-specific header defines. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_WINDOWS + #error bad include +#endif + +/*******************************************/ +/********** magic main emulation ***********/ +/*******************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +AL_FUNC(int, _WinMain, (void *_main, void *hInst, void *hPrev, char *Cmd, int nShow)); + +#ifdef __cplusplus +} +#endif + + +/* The following is due to torhu from A.cc (see + * http://www.allegro.cc/forums/thread/596872/756993#target) + */ +#ifndef ALLEGRO_NO_MAGIC_MAIN + #if defined _MSC_VER && !defined ALLEGRO_LIB_BUILD + #pragma comment(linker,"/ENTRY:mainCRTStartup") + #endif +#endif + + +/*******************************************/ +/************ joystick drivers *************/ +/*******************************************/ +#define AL_JOY_TYPE_DIRECTX AL_ID('D','X',' ',' ') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_directx); + +#ifdef __cplusplus +} +#endif + +#define _AL_JOYSTICK_DRIVER_DIRECTX \ + { AL_JOY_TYPE_DIRECTX, &_al_joydrv_directx, true }, + +#define AL_JOY_TYPE_XINPUT AL_ID('X','I',' ',' ') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_xinput); + +#ifdef __cplusplus +} +#endif + +#define _AL_JOYSTICK_DRIVER_XINPUT \ + { AL_JOY_TYPE_XINPUT, &_al_joydrv_xinput, true }, + +#define AL_JOY_TYPE_WINDOWS_ALL AL_ID('X','D',' ',' ') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_windows_all); + +#ifdef __cplusplus +} +#endif + +#define _AL_JOYSTICK_DRIVER_WINDOWS_ALL \ + { AL_JOY_TYPE_WINDOWS_ALL, &_al_joydrv_windows_all, true }, + + + +/*******************************************/ +/************ haptic drivers *************/ +/*******************************************/ + +#define AL_HAPTIC_TYPE_DIRECTX AL_ID('D','X','F','F') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_HAPTIC_DRIVER, _al_hapdrv_directx); + +#ifdef __cplusplus +} +#endif + +#define _AL_HAPTIC_DRIVER_DIRECTX \ + { AL_HAPTIC_TYPE_DIRECTX, &_al_hapdrv_directx, true }, + + +#define AL_HAPTIC_TYPE_XINPUT AL_ID('X','I','F','F') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_HAPTIC_DRIVER, _al_hapdrv_xinput); + +#ifdef __cplusplus +} +#endif + +#define _AL_HAPTIC_DRIVER_XINPUT \ + { AL_HAPTIC_TYPE_XINPUT, &_al_hapdrv_xinput, true }, + + +#define AL_HAPTIC_TYPE_WINDOWS_ALL AL_ID('X','D','F','F') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_HAPTIC_DRIVER, _al_hapdrv_windows_all); + +#ifdef __cplusplus +} +#endif + +#define _AL_HAPTIC_DRIVER_WINDOWS_ALL \ + { AL_HAPTIC_TYPE_WINDOWS_ALL, &_al_hapdrv_windows_all, true }, + + diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/astdbool.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/astdbool.h new file mode 100644 index 00000000..591f4769 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/astdbool.h @@ -0,0 +1,35 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * A header file to get C99's stdbool.h. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_astdbool_h +#define __al_included_allegro5_astdbool_h + +#ifndef __cplusplus +# ifdef ALLEGRO_HAVE_STDBOOL_H +# include +# else +# ifndef ALLEGRO_HAVE__BOOL + typedef unsigned char _Bool; +# endif +# define bool _Bool +# define false 0 +# define true 1 +# define __bool_true_false_are_defined 1 +# endif +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/astdint.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/astdint.h new file mode 100644 index 00000000..6db81de3 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/platform/astdint.h @@ -0,0 +1,75 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * A header file to get definitions of uint*_t and int*_t. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_astdint_h +#define __al_included_allegro5_astdint_h + +/* Please only include this file from include/allegro5/internal/alconfig.h + * and don't add more than inttypes.h/stdint.h emulation here. Thanks. + */ + + + +#if defined ALLEGRO_HAVE_INTTYPES_H + #include +#elif defined ALLEGRO_HAVE_STDINT_H + #include +#elif defined ALLEGRO_I386 && defined ALLEGRO_LITTLE_ENDIAN + #ifndef ALLEGRO_GUESS_INTTYPES_OK + #warning Guessing the definitions of fixed-width integer types. + #endif + #define int8_t signed char + #define uint8_t unsigned char + #define int16_t signed short + #define uint16_t unsigned short + #define int32_t signed int + #define uint32_t unsigned int + + #ifdef ALLEGRO_WINDOWS + + #ifndef _INTPTR_T_DEFINED + #ifdef _WIN64 + #define intptr_t __int64 + #else + #define intptr_t int + #endif + #define _INTPTR_T_DEFINED + #endif + + #ifndef _UINTPTR_T_DEFINED + #ifdef _WIN64 + #define uintptr_t unsigned __int64 + #else + #define uintptr_t unsigned int + #endif + #define _UINTPTR_T_DEFINED + #endif + + #else + + #define intptr_t int32_t + #define uintptr_t uint32_t + + #endif + +#else + #error I dunno how to get the definitions of fixed-width integer types on your platform. Please report this to your friendly Allegro developer. +#endif + + + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/render_state.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/render_state.h new file mode 100644 index 00000000..fad924da --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/render_state.h @@ -0,0 +1,53 @@ +#ifndef __al_included_allegro5_render_state_h +#define __al_included_allegro5_render_state_h + +#ifdef __cplusplus + extern "C" { +#endif + +/* Enum: ALLEGRO_RENDER_STATE + */ +typedef enum ALLEGRO_RENDER_STATE { + /* ALLEGRO_ALPHA_TEST was the name of a rare bitmap flag only used on the + * Wiz port. Reuse the name but retain the same value. + */ + ALLEGRO_ALPHA_TEST = 0x0010, + ALLEGRO_WRITE_MASK, + ALLEGRO_DEPTH_TEST, + ALLEGRO_DEPTH_FUNCTION, + ALLEGRO_ALPHA_FUNCTION, + ALLEGRO_ALPHA_TEST_VALUE +} ALLEGRO_RENDER_STATE; + +/* Enum: ALLEGRO_RENDER_FUNCTION + */ +typedef enum ALLEGRO_RENDER_FUNCTION { + ALLEGRO_RENDER_NEVER, + ALLEGRO_RENDER_ALWAYS, + ALLEGRO_RENDER_LESS, + ALLEGRO_RENDER_EQUAL, + ALLEGRO_RENDER_LESS_EQUAL, + ALLEGRO_RENDER_GREATER, + ALLEGRO_RENDER_NOT_EQUAL, + ALLEGRO_RENDER_GREATER_EQUAL +} ALLEGRO_RENDER_FUNCTION; + +/* Enum: ALLEGRO_WRITE_MASK_FLAGS + */ +typedef enum ALLEGRO_WRITE_MASK_FLAGS { + ALLEGRO_MASK_RED = 1 << 0, + ALLEGRO_MASK_GREEN = 1 << 1, + ALLEGRO_MASK_BLUE = 1 << 2, + ALLEGRO_MASK_ALPHA = 1 << 3, + ALLEGRO_MASK_DEPTH = 1 << 4, + ALLEGRO_MASK_RGB = (ALLEGRO_MASK_RED | ALLEGRO_MASK_GREEN | ALLEGRO_MASK_BLUE), + ALLEGRO_MASK_RGBA = (ALLEGRO_MASK_RGB | ALLEGRO_MASK_ALPHA) +} ALLEGRO_WRITE_MASK_FLAGS; + +AL_FUNC(void, al_set_render_state, (ALLEGRO_RENDER_STATE state, int value)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/shader.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/shader.h new file mode 100644 index 00000000..32fc0718 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/shader.h @@ -0,0 +1,78 @@ +#ifndef __al_included_allegro5_shader_h +#define __al_included_allegro5_shader_h + +#include "allegro5/base.h" +#include "allegro5/transformations.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_SHADER + */ +typedef struct ALLEGRO_SHADER ALLEGRO_SHADER; + +enum ALLEGRO_SHADER_TYPE { + ALLEGRO_VERTEX_SHADER = 1, + ALLEGRO_PIXEL_SHADER = 2 +}; + +/* Enum: ALLEGRO_SHADER_TYPE + */ +typedef enum ALLEGRO_SHADER_TYPE ALLEGRO_SHADER_TYPE; + +enum ALLEGRO_SHADER_PLATFORM { + ALLEGRO_SHADER_AUTO = 0, + ALLEGRO_SHADER_GLSL = 1, + ALLEGRO_SHADER_HLSL = 2 +}; + +/* Enum: ALLEGRO_SHADER_PLATFORM + */ +typedef enum ALLEGRO_SHADER_PLATFORM ALLEGRO_SHADER_PLATFORM; + +/* Shader variable names */ +#define ALLEGRO_SHADER_VAR_COLOR "al_color" +#define ALLEGRO_SHADER_VAR_POS "al_pos" +#define ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX "al_projview_matrix" +#define ALLEGRO_SHADER_VAR_TEX "al_tex" +#define ALLEGRO_SHADER_VAR_TEXCOORD "al_texcoord" +#define ALLEGRO_SHADER_VAR_TEX_MATRIX "al_tex_matrix" +#define ALLEGRO_SHADER_VAR_USER_ATTR "al_user_attr_" +#define ALLEGRO_SHADER_VAR_USE_TEX "al_use_tex" +#define ALLEGRO_SHADER_VAR_USE_TEX_MATRIX "al_use_tex_matrix" + +AL_FUNC(ALLEGRO_SHADER *, al_create_shader, (ALLEGRO_SHADER_PLATFORM platform)); +AL_FUNC(bool, al_attach_shader_source, (ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *source)); +AL_FUNC(bool, al_attach_shader_source_file, (ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *filename)); +AL_FUNC(bool, al_build_shader, (ALLEGRO_SHADER *shader)); +AL_FUNC(const char *, al_get_shader_log, (ALLEGRO_SHADER *shader)); +AL_FUNC(ALLEGRO_SHADER_PLATFORM, al_get_shader_platform, (ALLEGRO_SHADER *shader)); +AL_FUNC(bool, al_use_shader, (ALLEGRO_SHADER *shader)); +AL_FUNC(void, al_destroy_shader, (ALLEGRO_SHADER *shader)); + +AL_FUNC(bool, al_set_shader_sampler, (const char *name, ALLEGRO_BITMAP *bitmap, + int unit)); +AL_FUNC(bool, al_set_shader_matrix, (const char *name, + ALLEGRO_TRANSFORM *matrix)); +AL_FUNC(bool, al_set_shader_int, (const char *name, int i)); +AL_FUNC(bool, al_set_shader_float, (const char *name, float f)); +AL_FUNC(bool, al_set_shader_int_vector, (const char *name, int num_components, + int *i, int num_elems)); +AL_FUNC(bool, al_set_shader_float_vector, (const char *name, int num_components, + float *f, int num_elems)); +AL_FUNC(bool, al_set_shader_bool, (const char *name, bool b)); + +AL_FUNC(char const *, al_get_default_shader_source, (ALLEGRO_SHADER_PLATFORM platform, + ALLEGRO_SHADER_TYPE type)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/system.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/system.h new file mode 100644 index 00000000..da525ca9 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/system.h @@ -0,0 +1,50 @@ +#ifndef __al_included_allegro5_system_h +#define __al_included_allegro5_system_h + +#include "allegro5/config.h" +#include "allegro5/path.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct ALLEGRO_SYSTEM ALLEGRO_SYSTEM; + +/* Function: al_init + */ +#define al_init() (al_install_system(ALLEGRO_VERSION_INT, atexit)) + +AL_FUNC(bool, al_install_system, (int version, int (*atexit_ptr)(void (*)(void)))); +AL_FUNC(void, al_uninstall_system, (void)); +AL_FUNC(bool, al_is_system_installed, (void)); +AL_FUNC(ALLEGRO_SYSTEM *, al_get_system_driver, (void)); +AL_FUNC(ALLEGRO_CONFIG *, al_get_system_config, (void)); + +enum { + ALLEGRO_RESOURCES_PATH = 0, + ALLEGRO_TEMP_PATH, + ALLEGRO_USER_DATA_PATH, + ALLEGRO_USER_HOME_PATH, + ALLEGRO_USER_SETTINGS_PATH, + ALLEGRO_USER_DOCUMENTS_PATH, + ALLEGRO_EXENAME_PATH, + ALLEGRO_LAST_PATH /* must be last */ +}; + +AL_FUNC(ALLEGRO_PATH *, al_get_standard_path, (int id)); +AL_FUNC(void, al_set_exe_name, (char const *path)); + +AL_FUNC(void, al_set_org_name, (const char *org_name)); +AL_FUNC(void, al_set_app_name, (const char *app_name)); +AL_FUNC(const char *, al_get_org_name, (void)); +AL_FUNC(const char *, al_get_app_name, (void)); + +AL_FUNC(bool, al_inhibit_screensaver, (bool inhibit)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/threads.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/threads.h new file mode 100644 index 00000000..c0d127fa --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/threads.h @@ -0,0 +1,67 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_threads_h +#define __al_included_allegro5_threads_h + +#include "allegro5/altime.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_THREAD + */ +typedef struct ALLEGRO_THREAD ALLEGRO_THREAD; + +/* Type: ALLEGRO_MUTEX + */ +typedef struct ALLEGRO_MUTEX ALLEGRO_MUTEX; + +/* Type: ALLEGRO_COND + */ +typedef struct ALLEGRO_COND ALLEGRO_COND; + + +AL_FUNC(ALLEGRO_THREAD *, al_create_thread, + (void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg)); +AL_FUNC(void, al_start_thread, (ALLEGRO_THREAD *outer)); +AL_FUNC(void, al_join_thread, (ALLEGRO_THREAD *outer, void **ret_value)); +AL_FUNC(void, al_set_thread_should_stop, (ALLEGRO_THREAD *outer)); +AL_FUNC(bool, al_get_thread_should_stop, (ALLEGRO_THREAD *outer)); +AL_FUNC(void, al_destroy_thread, (ALLEGRO_THREAD *thread)); +AL_FUNC(void, al_run_detached_thread, (void *(*proc)(void *arg), void *arg)); + +AL_FUNC(ALLEGRO_MUTEX *, al_create_mutex, (void)); +AL_FUNC(ALLEGRO_MUTEX *, al_create_mutex_recursive, (void)); +AL_FUNC(void, al_lock_mutex, (ALLEGRO_MUTEX *mutex)); +AL_FUNC(void, al_unlock_mutex, (ALLEGRO_MUTEX *mutex)); +AL_FUNC(void, al_destroy_mutex, (ALLEGRO_MUTEX *mutex)); + +AL_FUNC(ALLEGRO_COND *, al_create_cond, (void)); +AL_FUNC(void, al_destroy_cond, (ALLEGRO_COND *cond)); +AL_FUNC(void, al_wait_cond, (ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)); +AL_FUNC(int, al_wait_cond_until, (ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex, + const ALLEGRO_TIMEOUT *timeout)); +AL_FUNC(void, al_broadcast_cond, (ALLEGRO_COND *cond)); +AL_FUNC(void, al_signal_cond, (ALLEGRO_COND *cond)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/timer.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/timer.h new file mode 100644 index 00000000..60db65aa --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/timer.h @@ -0,0 +1,66 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Timer routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_timer_h +#define __al_included_allegro5_timer_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Function: ALLEGRO_USECS_TO_SECS + */ +#define ALLEGRO_USECS_TO_SECS(x) ((x) / 1000000.0) + +/* Function: ALLEGRO_MSECS_TO_SECS + */ +#define ALLEGRO_MSECS_TO_SECS(x) ((x) / 1000.0) + +/* Function: ALLEGRO_BPS_TO_SECS + */ +#define ALLEGRO_BPS_TO_SECS(x) (1.0 / (x)) + +/* Function: ALLEGRO_BPM_TO_SECS + */ +#define ALLEGRO_BPM_TO_SECS(x) (60.0 / (x)) + + +/* Type: ALLEGRO_TIMER + */ +typedef struct ALLEGRO_TIMER ALLEGRO_TIMER; + + +AL_FUNC(ALLEGRO_TIMER*, al_create_timer, (double speed_secs)); +AL_FUNC(void, al_destroy_timer, (ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_start_timer, (ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_stop_timer, (ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_resume_timer, (ALLEGRO_TIMER *timer)); +AL_FUNC(bool, al_get_timer_started, (const ALLEGRO_TIMER *timer)); +AL_FUNC(double, al_get_timer_speed, (const ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_set_timer_speed, (ALLEGRO_TIMER *timer, double speed_secs)); +AL_FUNC(int64_t, al_get_timer_count, (const ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_set_timer_count, (ALLEGRO_TIMER *timer, int64_t count)); +AL_FUNC(void, al_add_timer_count, (ALLEGRO_TIMER *timer, int64_t diff)); +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_timer_event_source, (ALLEGRO_TIMER *timer)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/tls.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/tls.h new file mode 100644 index 00000000..949b18a7 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/tls.h @@ -0,0 +1,66 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread local storage routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_tls_h +#define __al_included_allegro5_tls_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Enum: ALLEGRO_STATE_FLAGS + */ +typedef enum ALLEGRO_STATE_FLAGS +{ + ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS = 0x0001, + ALLEGRO_STATE_NEW_BITMAP_PARAMETERS = 0x0002, + ALLEGRO_STATE_DISPLAY = 0x0004, + ALLEGRO_STATE_TARGET_BITMAP = 0x0008, + ALLEGRO_STATE_BLENDER = 0x0010, + ALLEGRO_STATE_NEW_FILE_INTERFACE = 0x0020, + ALLEGRO_STATE_TRANSFORM = 0x0040, + ALLEGRO_STATE_PROJECTION_TRANSFORM = 0x0100, + + ALLEGRO_STATE_BITMAP = ALLEGRO_STATE_TARGET_BITMAP +\ + ALLEGRO_STATE_NEW_BITMAP_PARAMETERS, + + ALLEGRO_STATE_ALL = 0xffff + +} ALLEGRO_STATE_FLAGS; + + +/* Type: ALLEGRO_STATE + */ +typedef struct ALLEGRO_STATE ALLEGRO_STATE; + +struct ALLEGRO_STATE +{ + /* Internally, a thread_local_state structure is placed here. */ + char _tls[1024]; +}; + + +AL_FUNC(void, al_store_state, (ALLEGRO_STATE *state, int flags)); +AL_FUNC(void, al_restore_state, (ALLEGRO_STATE const *state)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/touch_input.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/touch_input.h new file mode 100644 index 00000000..8fec5fc7 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/touch_input.h @@ -0,0 +1,96 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Touch input routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_touch_input_h +#define __al_included_allegro5_touch_input_h + +#include "allegro5/base.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Enum: ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT + */ +#define ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT 16 + + +/* Type: ALLEGRO_TOUCH_INPUT + */ +typedef struct ALLEGRO_TOUCH_INPUT ALLEGRO_TOUCH_INPUT; + + +/* Type: ALLEGRO_TOUCH_INPUT_STATE + */ +typedef struct ALLEGRO_TOUCH_INPUT_STATE ALLEGRO_TOUCH_INPUT_STATE; + + +/* Type: ALLEGRO_TOUCH_STATE + */ +typedef struct ALLEGRO_TOUCH_STATE ALLEGRO_TOUCH_STATE; + + +struct ALLEGRO_TOUCH_STATE +{ + /* (id) An identifier of touch. If touch is valid this number is positive. + * (x, y) Touch position on the screen in 1:1 resolution. + * (dx, dy) Relative touch position. + * (primary) True, if touch is a primary one (usually first one). + * (display) Display at which the touch belong. + */ + int id; + float x, y; + float dx, dy; + bool primary; + struct ALLEGRO_DISPLAY *display; +}; + +struct ALLEGRO_TOUCH_INPUT_STATE +{ + ALLEGRO_TOUCH_STATE touches[ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT]; +}; + + +/* Enum: ALLEGRO_MOUSE_EMULATION_MODE + */ +typedef enum ALLEGRO_MOUSE_EMULATION_MODE +{ + ALLEGRO_MOUSE_EMULATION_NONE, + ALLEGRO_MOUSE_EMULATION_TRANSPARENT, + ALLEGRO_MOUSE_EMULATION_INCLUSIVE, + ALLEGRO_MOUSE_EMULATION_EXCLUSIVE, + ALLEGRO_MOUSE_EMULATION_5_0_x +} ALLEGRO_MOUSE_EMULATION_MODE; + + +AL_FUNC(bool, al_is_touch_input_installed, (void)); +AL_FUNC(bool, al_install_touch_input, (void)); +AL_FUNC(void, al_uninstall_touch_input, (void)); +AL_FUNC(void, al_get_touch_input_state, (ALLEGRO_TOUCH_INPUT_STATE *ret_state)); + +AL_FUNC(void, al_set_mouse_emulation_mode, (int mode)); +AL_FUNC(int, al_get_mouse_emulation_mode, (void)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_touch_input_event_source, (void)); +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_touch_input_mouse_emulation_event_source, (void)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/transformations.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/transformations.h new file mode 100644 index 00000000..84368e7a --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/transformations.h @@ -0,0 +1,52 @@ +#ifndef __al_included_allegro5_transformations_h +#define __al_included_allegro5_transformations_h + +#include "allegro5/display.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_TRANSFORM + */ +typedef struct ALLEGRO_TRANSFORM ALLEGRO_TRANSFORM; + +struct ALLEGRO_TRANSFORM { + float m[4][4]; +}; + +/* Transformations*/ +AL_FUNC(void, al_use_transform, (const ALLEGRO_TRANSFORM* trans)); +AL_FUNC(void, al_use_projection_transform, (const ALLEGRO_TRANSFORM* trans)); +AL_FUNC(void, al_copy_transform, (ALLEGRO_TRANSFORM* dest, const ALLEGRO_TRANSFORM* src)); +AL_FUNC(void, al_identity_transform, (ALLEGRO_TRANSFORM* trans)); +AL_FUNC(void, al_build_transform, (ALLEGRO_TRANSFORM* trans, float x, float y, float sx, float sy, float theta)); +AL_FUNC(void, al_build_camera_transform, (ALLEGRO_TRANSFORM *trans, + float position_x, float position_y, float position_z, + float look_x, float look_y, float look_z, + float up_x, float up_y, float up_z)); +AL_FUNC(void, al_translate_transform, (ALLEGRO_TRANSFORM* trans, float x, float y)); +AL_FUNC(void, al_translate_transform_3d, (ALLEGRO_TRANSFORM *trans, float x, float y, float z)); +AL_FUNC(void, al_rotate_transform, (ALLEGRO_TRANSFORM* trans, float theta)); +AL_FUNC(void, al_rotate_transform_3d, (ALLEGRO_TRANSFORM *trans, float x, float y, float z, float angle)); +AL_FUNC(void, al_scale_transform, (ALLEGRO_TRANSFORM* trans, float sx, float sy)); +AL_FUNC(void, al_scale_transform_3d, (ALLEGRO_TRANSFORM *trans, float sx, float sy, float sz)); +AL_FUNC(void, al_transform_coordinates, (const ALLEGRO_TRANSFORM* trans, float* x, float* y)); +AL_FUNC(void, al_transform_coordinates_3d, (const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z)); +AL_FUNC(void, al_compose_transform, (ALLEGRO_TRANSFORM* trans, const ALLEGRO_TRANSFORM* other)); +AL_FUNC(const ALLEGRO_TRANSFORM*, al_get_current_transform, (void)); +AL_FUNC(const ALLEGRO_TRANSFORM*, al_get_current_inverse_transform, (void)); +AL_FUNC(const ALLEGRO_TRANSFORM *, al_get_current_projection_transform, (void)); +AL_FUNC(void, al_invert_transform, (ALLEGRO_TRANSFORM *trans)); +AL_FUNC(int, al_check_inverse, (const ALLEGRO_TRANSFORM *trans, float tol)); +AL_FUNC(void, al_orthographic_transform, (ALLEGRO_TRANSFORM *trans, float left, float top, float n, float right, float bottom, float f)); +AL_FUNC(void, al_perspective_transform, (ALLEGRO_TRANSFORM *trans, float left, float top, float n, float right, float bottom, float f)); +AL_FUNC(void, al_horizontal_shear_transform, (ALLEGRO_TRANSFORM *trans, float theta)); +AL_FUNC(void, al_vertical_shear_transform, (ALLEGRO_TRANSFORM *trans, float theta)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/utf8.h b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/utf8.h new file mode 100644 index 00000000..f0459dac --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/include/allegro5/utf8.h @@ -0,0 +1,150 @@ +#ifndef __al_included_allegro5_utf8_h +#define __al_included_allegro5_utf8_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_USTR + */ +typedef struct _al_tagbstring ALLEGRO_USTR; + +/* Type: ALLEGRO_USTR_INFO + */ +typedef struct _al_tagbstring ALLEGRO_USTR_INFO; + +#ifndef __al_tagbstring_defined +#define __al_tagbstring_defined +struct _al_tagbstring { + int mlen; + int slen; + unsigned char * data; +}; +#endif + +/* Creating strings */ +AL_FUNC(ALLEGRO_USTR *, al_ustr_new, (const char *s)); +AL_FUNC(ALLEGRO_USTR *, al_ustr_new_from_buffer, (const char *s, size_t size)); +AL_PRINTFUNC(ALLEGRO_USTR *, al_ustr_newf, (const char *fmt, ...), 1, 2); +AL_FUNC(void, al_ustr_free, (ALLEGRO_USTR *us)); +AL_FUNC(const char *, al_cstr, (const ALLEGRO_USTR *us)); +AL_FUNC(void, al_ustr_to_buffer, (const ALLEGRO_USTR *us, char *buffer, int size)); +AL_FUNC(char *, al_cstr_dup, (const ALLEGRO_USTR *us)); +AL_FUNC(ALLEGRO_USTR *, al_ustr_dup, (const ALLEGRO_USTR *us)); +AL_FUNC(ALLEGRO_USTR *, al_ustr_dup_substr, (const ALLEGRO_USTR *us, + int start_pos, int end_pos)); + +/* Predefined string */ +AL_FUNC(const ALLEGRO_USTR *, al_ustr_empty_string, (void)); + +/* Reference strings */ +AL_FUNC(const ALLEGRO_USTR *, al_ref_cstr, (ALLEGRO_USTR_INFO *info, const char *s)); +AL_FUNC(const ALLEGRO_USTR *, al_ref_buffer, (ALLEGRO_USTR_INFO *info, const char *s, + size_t size)); +AL_FUNC(const ALLEGRO_USTR *, al_ref_ustr, (ALLEGRO_USTR_INFO *info, + const ALLEGRO_USTR *us, int start_pos, int end_pos)); + +/* Sizes and offsets */ +AL_FUNC(size_t, al_ustr_size, (const ALLEGRO_USTR *us)); +AL_FUNC(size_t, al_ustr_length, (const ALLEGRO_USTR *us)); +AL_FUNC(int, al_ustr_offset, (const ALLEGRO_USTR *us, int index)); +AL_FUNC(bool, al_ustr_next, (const ALLEGRO_USTR *us, int *pos)); +AL_FUNC(bool, al_ustr_prev, (const ALLEGRO_USTR *us, int *pos)); + +/* Get codepoints */ +AL_FUNC(int32_t, al_ustr_get, (const ALLEGRO_USTR *us, int pos)); +AL_FUNC(int32_t, al_ustr_get_next, (const ALLEGRO_USTR *us, int *pos)); +AL_FUNC(int32_t, al_ustr_prev_get, (const ALLEGRO_USTR *us, int *pos)); + +/* Insert */ +AL_FUNC(bool, al_ustr_insert, (ALLEGRO_USTR *us1, int pos, + const ALLEGRO_USTR *us2)); +AL_FUNC(bool, al_ustr_insert_cstr, (ALLEGRO_USTR *us, int pos, + const char *us2)); +AL_FUNC(size_t, al_ustr_insert_chr, (ALLEGRO_USTR *us, int pos, int32_t c)); + +/* Append */ +AL_FUNC(bool, al_ustr_append, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); +AL_FUNC(bool, al_ustr_append_cstr, (ALLEGRO_USTR *us, const char *s)); +AL_FUNC(size_t, al_ustr_append_chr, (ALLEGRO_USTR *us, int32_t c)); +AL_PRINTFUNC(bool, al_ustr_appendf, (ALLEGRO_USTR *us, const char *fmt, ...), + 2, 3); +AL_FUNC(bool, al_ustr_vappendf, (ALLEGRO_USTR *us, const char *fmt, + va_list ap)); + +/* Remove */ +AL_FUNC(bool, al_ustr_remove_chr, (ALLEGRO_USTR *us, int pos)); +AL_FUNC(bool, al_ustr_remove_range, (ALLEGRO_USTR *us, int start_pos, + int end_pos)); +AL_FUNC(bool, al_ustr_truncate, (ALLEGRO_USTR *us, int start_pos)); +AL_FUNC(bool, al_ustr_ltrim_ws, (ALLEGRO_USTR *us)); +AL_FUNC(bool, al_ustr_rtrim_ws, (ALLEGRO_USTR *us)); +AL_FUNC(bool, al_ustr_trim_ws, (ALLEGRO_USTR *us)); + +/* Assign */ +AL_FUNC(bool, al_ustr_assign, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); +AL_FUNC(bool, al_ustr_assign_substr, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, + int start_pos, int end_pos)); +AL_FUNC(bool, al_ustr_assign_cstr, (ALLEGRO_USTR *us1, const char *s)); + +/* Replace */ +AL_FUNC(size_t, al_ustr_set_chr, (ALLEGRO_USTR *us, int pos, int32_t c)); +AL_FUNC(bool, al_ustr_replace_range, (ALLEGRO_USTR *us1, int start_pos1, + int end_pos1, const ALLEGRO_USTR *us2)); + +/* Searching */ +AL_FUNC(int, al_ustr_find_chr, (const ALLEGRO_USTR *us, int start_pos, + int32_t c)); +AL_FUNC(int, al_ustr_rfind_chr, (const ALLEGRO_USTR *us, int start_pos, + int32_t c)); +AL_FUNC(int, al_ustr_find_set, (const ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *accept)); +AL_FUNC(int, al_ustr_find_set_cstr, (const ALLEGRO_USTR *us, int start_pos, + const char *accept)); +AL_FUNC(int, al_ustr_find_cset, (const ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *reject)); +AL_FUNC(int, al_ustr_find_cset_cstr, (const ALLEGRO_USTR *us, int start_pos, + const char *reject)); +AL_FUNC(int, al_ustr_find_str, (const ALLEGRO_USTR *haystack, int start_pos, + const ALLEGRO_USTR *needle)); +AL_FUNC(int, al_ustr_find_cstr, (const ALLEGRO_USTR *haystack, int start_pos, + const char *needle)); +AL_FUNC(int, al_ustr_rfind_str, (const ALLEGRO_USTR *haystack, int start_pos, + const ALLEGRO_USTR *needle)); +AL_FUNC(int, al_ustr_rfind_cstr, (const ALLEGRO_USTR *haystack, int start_pos, + const char *needle)); +AL_FUNC(bool, al_ustr_find_replace, (ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace)); +AL_FUNC(bool, al_ustr_find_replace_cstr, (ALLEGRO_USTR *us, int start_pos, + const char *find, const char *replace)); + +/* Compare */ +AL_FUNC(bool, al_ustr_equal, (const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); +AL_FUNC(int, al_ustr_compare, (const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); +AL_FUNC(int, al_ustr_ncompare, (const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, + int n)); +AL_FUNC(bool, al_ustr_has_prefix,(const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); +AL_FUNC(bool, al_ustr_has_prefix_cstr, (const ALLEGRO_USTR *u, const char *s)); +AL_FUNC(bool, al_ustr_has_suffix,(const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); +AL_FUNC(bool, al_ustr_has_suffix_cstr,(const ALLEGRO_USTR *us1, const char *s)); + +/* Low level UTF-8 functions */ +AL_FUNC(size_t, al_utf8_width, (int32_t c)); +AL_FUNC(size_t, al_utf8_encode, (char s[], int32_t c)); + +/* UTF-16 */ +AL_FUNC(ALLEGRO_USTR *, al_ustr_new_from_utf16, (uint16_t const *s)); +AL_FUNC(size_t, al_ustr_size_utf16, (const ALLEGRO_USTR *us)); +AL_FUNC(size_t, al_ustr_encode_utf16, (const ALLEGRO_USTR *us, uint16_t *s, size_t n)); +AL_FUNC(size_t, al_utf16_width, (int c)); +AL_FUNC(size_t, al_utf16_encode, (uint16_t s[], int32_t c)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro-debug.lib new file mode 100644 index 00000000..96d27066 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_acodec-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_acodec-debug.lib new file mode 100644 index 00000000..86dbd34f Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_acodec-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_audio-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_audio-debug.lib new file mode 100644 index 00000000..9fb47f64 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_audio-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_color-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_color-debug.lib new file mode 100644 index 00000000..39e951d2 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_color-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_dialog-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_dialog-debug.lib new file mode 100644 index 00000000..6896ffba Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_dialog-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_font-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_font-debug.lib new file mode 100644 index 00000000..c3c7398c Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_font-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_image-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_image-debug.lib new file mode 100644 index 00000000..68ba22cc Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_image-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_main-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_main-debug.lib new file mode 100644 index 00000000..dbf1f33d Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_main-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_memfile-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_memfile-debug.lib new file mode 100644 index 00000000..3498f891 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_memfile-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_physfs-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_physfs-debug.lib new file mode 100644 index 00000000..6164b808 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_physfs-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_primitives-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_primitives-debug.lib new file mode 100644 index 00000000..12b2f29e Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_primitives-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_ttf-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_ttf-debug.lib new file mode 100644 index 00000000..c2b63545 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_ttf-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_video-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_video-debug.lib new file mode 100644 index 00000000..ee3260fb Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/md/allegro_video-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro.lib new file mode 100644 index 00000000..5a30054a Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_acodec.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_acodec.lib new file mode 100644 index 00000000..b5a68e31 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_acodec.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_audio.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_audio.lib new file mode 100644 index 00000000..682d499c Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_audio.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_color.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_color.lib new file mode 100644 index 00000000..3dcd25a4 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_color.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_dialog.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_dialog.lib new file mode 100644 index 00000000..4dc8abc3 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_dialog.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_font.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_font.lib new file mode 100644 index 00000000..ec141b5f Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_font.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_image.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_image.lib new file mode 100644 index 00000000..87e6a57c Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_image.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_main.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_main.lib new file mode 100644 index 00000000..9c8516ee Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_main.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_memfile.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_memfile.lib new file mode 100644 index 00000000..b5b417fd Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_memfile.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_monolith-static.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_monolith-static.lib new file mode 100644 index 00000000..2c1b99a3 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_monolith-static.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_physfs.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_physfs.lib new file mode 100644 index 00000000..7dbdad8c Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_physfs.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_primitives.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_primitives.lib new file mode 100644 index 00000000..f021f958 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_primitives.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_ttf.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_ttf.lib new file mode 100644 index 00000000..87103e8f Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_ttf.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_video.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_video.lib new file mode 100644 index 00000000..f2963246 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/win32/v140/mt/allegro_video.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro-debug.lib new file mode 100644 index 00000000..c2e89390 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_acodec-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_acodec-debug.lib new file mode 100644 index 00000000..0245c66d Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_acodec-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_audio-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_audio-debug.lib new file mode 100644 index 00000000..031e232c Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_audio-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_color-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_color-debug.lib new file mode 100644 index 00000000..d4f0a252 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_color-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_dialog-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_dialog-debug.lib new file mode 100644 index 00000000..c47ca6aa Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_dialog-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_font-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_font-debug.lib new file mode 100644 index 00000000..b5c597a7 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_font-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_image-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_image-debug.lib new file mode 100644 index 00000000..44714c03 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_image-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_main-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_main-debug.lib new file mode 100644 index 00000000..74c35644 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_main-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_memfile-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_memfile-debug.lib new file mode 100644 index 00000000..61ab3a22 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_memfile-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_physfs-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_physfs-debug.lib new file mode 100644 index 00000000..e391689f Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_physfs-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_primitives-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_primitives-debug.lib new file mode 100644 index 00000000..74e95492 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_primitives-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_ttf-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_ttf-debug.lib new file mode 100644 index 00000000..261d680b Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_ttf-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_video-debug.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_video-debug.lib new file mode 100644 index 00000000..1f992eab Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/md/allegro_video-debug.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro.lib new file mode 100644 index 00000000..b8c95c9d Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_acodec.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_acodec.lib new file mode 100644 index 00000000..140f6c66 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_acodec.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_audio.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_audio.lib new file mode 100644 index 00000000..1c1c6d81 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_audio.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_color.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_color.lib new file mode 100644 index 00000000..4b395512 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_color.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_dialog.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_dialog.lib new file mode 100644 index 00000000..cae0890f Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_dialog.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_font.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_font.lib new file mode 100644 index 00000000..c76947b8 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_font.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_image.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_image.lib new file mode 100644 index 00000000..5c1a0b5d Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_image.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_main.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_main.lib new file mode 100644 index 00000000..65ffbe8d Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_main.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_memfile.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_memfile.lib new file mode 100644 index 00000000..8ee895ad Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_memfile.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_monolith-static.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_monolith-static.lib new file mode 100644 index 00000000..cf67be98 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_monolith-static.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_physfs.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_physfs.lib new file mode 100644 index 00000000..63f2e5c2 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_physfs.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_primitives.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_primitives.lib new file mode 100644 index 00000000..8302e430 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_primitives.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_ttf.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_ttf.lib new file mode 100644 index 00000000..8d179039 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_ttf.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_video.lib b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_video.lib new file mode 100644 index 00000000..b77780ca Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/Allegro.5.1.12.4/build/native/lib/x64/v140/mt/allegro_video.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/.signature.p7s b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/.signature.p7s new file mode 100644 index 00000000..e6340843 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/.signature.p7s differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/AllegroDeps.1.3.0.4.nupkg b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/AllegroDeps.1.3.0.4.nupkg new file mode 100644 index 00000000..b7361564 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/AllegroDeps.1.3.0.4.nupkg differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/AllegroDeps.targets b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/AllegroDeps.targets new file mode 100644 index 00000000..e753e95b --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/AllegroDeps.targets @@ -0,0 +1,63 @@ + + + + $(MSBuildThisFileDirectory)lib\$(Platform)\v140\mt\ + + + + + $(AllegroLib)jpeg.lib; + $(AllegroLib)libpng16.lib; + $(AllegroLib)zlib.lib + + + + + + $(AllegroLib)freetype.lib + + + + + + $(AllegroLib)dumb.lib; + $(AllegroLib)FLAC.lib; + $(AllegroLib)vorbis.lib; + $(AllegroLib)vorbisfile.lib; + $(AllegroLib)ogg.lib + + + + + + $(AllegroLib)physfs.lib + + + + + + $(AllegroLib)theoradec.lib + + + + + + + $(MSBuildThisFileDirectory)\include\; + %(AdditionalIncludeDirectories) + + + + + + + $(Allegro_AddonImageDeps); + $(Allegro_AddonTTFDeps); + $(Allegro_AddonAcodecDeps); + $(Allegro_AddonPhysfsDeps); + $(Allegro_AddonVideoDeps); + %(AdditionalDependencies) + + + + diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/all.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/all.h new file mode 100644 index 00000000..2851cf59 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/all.h @@ -0,0 +1,371 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__ALL_H +#define FLAC__ALL_H + +#include "export.h" + +#include "assert.h" +#include "callback.h" +#include "format.h" +#include "metadata.h" +#include "ordinals.h" +#include "stream_decoder.h" +#include "stream_encoder.h" + +/** \mainpage + * + * \section intro Introduction + * + * This is the documentation for the FLAC C and C++ APIs. It is + * highly interconnected; this introduction should give you a top + * level idea of the structure and how to find the information you + * need. As a prerequisite you should have at least a basic + * knowledge of the FLAC format, documented + * here. + * + * \section c_api FLAC C API + * + * The FLAC C API is the interface to libFLAC, a set of structures + * describing the components of FLAC streams, and functions for + * encoding and decoding streams, as well as manipulating FLAC + * metadata in files. The public include files will be installed + * in your include area (for example /usr/include/FLAC/...). + * + * By writing a little code and linking against libFLAC, it is + * relatively easy to add FLAC support to another program. The + * library is licensed under Xiph's BSD license. + * Complete source code of libFLAC as well as the command-line + * encoder and plugins is available and is a useful source of + * examples. + * + * Aside from encoders and decoders, libFLAC provides a powerful + * metadata interface for manipulating metadata in FLAC files. It + * allows the user to add, delete, and modify FLAC metadata blocks + * and it can automatically take advantage of PADDING blocks to avoid + * rewriting the entire FLAC file when changing the size of the + * metadata. + * + * libFLAC usually only requires the standard C library and C math + * library. In particular, threading is not used so there is no + * dependency on a thread library. However, libFLAC does not use + * global variables and should be thread-safe. + * + * libFLAC also supports encoding to and decoding from Ogg FLAC. + * However the metadata editing interfaces currently have limited + * read-only support for Ogg FLAC files. + * + * \section cpp_api FLAC C++ API + * + * The FLAC C++ API is a set of classes that encapsulate the + * structures and functions in libFLAC. They provide slightly more + * functionality with respect to metadata but are otherwise + * equivalent. For the most part, they share the same usage as + * their counterparts in libFLAC, and the FLAC C API documentation + * can be used as a supplement. The public include files + * for the C++ API will be installed in your include area (for + * example /usr/include/FLAC++/...). + * + * libFLAC++ is also licensed under + * Xiph's BSD license. + * + * \section getting_started Getting Started + * + * A good starting point for learning the API is to browse through + * the modules. Modules are logical + * groupings of related functions or classes, which correspond roughly + * to header files or sections of header files. Each module includes a + * detailed description of the general usage of its functions or + * classes. + * + * From there you can go on to look at the documentation of + * individual functions. You can see different views of the individual + * functions through the links in top bar across this page. + * + * If you prefer a more hands-on approach, you can jump right to some + * example code. + * + * \section porting_guide Porting Guide + * + * Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink + * has been introduced which gives detailed instructions on how to + * port your code to newer versions of FLAC. + * + * \section embedded_developers Embedded Developers + * + * libFLAC has grown larger over time as more functionality has been + * included, but much of it may be unnecessary for a particular embedded + * implementation. Unused parts may be pruned by some simple editing of + * src/libFLAC/Makefile.am. In general, the decoders, encoders, and + * metadata interface are all independent from each other. + * + * It is easiest to just describe the dependencies: + * + * - All modules depend on the \link flac_format Format \endlink module. + * - The decoders and encoders depend on the bitbuffer. + * - The decoder is independent of the encoder. The encoder uses the + * decoder because of the verify feature, but this can be removed if + * not needed. + * - Parts of the metadata interface require the stream decoder (but not + * the encoder). + * - Ogg support is selectable through the compile time macro + * \c FLAC__HAS_OGG. + * + * For example, if your application only requires the stream decoder, no + * encoder, and no metadata interface, you can remove the stream encoder + * and the metadata interface, which will greatly reduce the size of the + * library. + * + * Also, there are several places in the libFLAC code with comments marked + * with "OPT:" where a #define can be changed to enable code that might be + * faster on a specific platform. Experimenting with these can yield faster + * binaries. + */ + +/** \defgroup porting Porting Guide for New Versions + * + * This module describes differences in the library interfaces from + * version to version. It assists in the porting of code that uses + * the libraries to newer versions of FLAC. + * + * One simple facility for making porting easier that has been added + * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each + * library's includes (e.g. \c include/FLAC/export.h). The + * \c #defines mirror the libraries' + * libtool version numbers, + * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT, + * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE. + * These can be used to support multiple versions of an API during the + * transition phase, e.g. + * + * \code + * #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 + * legacy code + * #else + * new code + * #endif + * \endcode + * + * The the source will work for multiple versions and the legacy code can + * easily be removed when the transition is complete. + * + * Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in + * include/FLAC/export.h), which can be used to determine whether or not + * the library has been compiled with support for Ogg FLAC. This is + * simpler than trying to call an Ogg init function and catching the + * error. + */ + +/** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.2 to FLAC 1.1.3. + * + * The main change between the APIs in 1.1.2 and 1.1.3 is that they have + * been simplified. First, libOggFLAC has been merged into libFLAC and + * libOggFLAC++ has been merged into libFLAC++. Second, both the three + * decoding layers and three encoding layers have been merged into a + * single stream decoder and stream encoder. That is, the functionality + * of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged + * into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and + * FLAC__FileEncoder into FLAC__StreamEncoder. Only the + * FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means + * is there is now a single API that can be used to encode or decode + * streams to/from native FLAC or Ogg FLAC and the single API can work + * on both seekable and non-seekable streams. + * + * Instead of creating an encoder or decoder of a certain layer, now the + * client will always create a FLAC__StreamEncoder or + * FLAC__StreamDecoder. The old layers are now differentiated by the + * initialization function. For example, for the decoder, + * FLAC__stream_decoder_init() has been replaced by + * FLAC__stream_decoder_init_stream(). This init function takes + * callbacks for the I/O, and the seeking callbacks are optional. This + * allows the client to use the same object for seekable and + * non-seekable streams. For decoding a FLAC file directly, the client + * can use FLAC__stream_decoder_init_file() and pass just a filename + * and fewer callbacks; most of the other callbacks are supplied + * internally. For situations where fopen()ing by filename is not + * possible (e.g. Unicode filenames on Windows) the client can instead + * open the file itself and supply the FILE* to + * FLAC__stream_decoder_init_FILE(). The init functions now returns a + * FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState. + * Since the callbacks and client data are now passed to the init + * function, the FLAC__stream_decoder_set_*_callback() functions and + * FLAC__stream_decoder_set_client_data() are no longer needed. The + * rest of the calls to the decoder are the same as before. + * + * There are counterpart init functions for Ogg FLAC, e.g. + * FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls + * and callbacks are the same as for native FLAC. + * + * As an example, in FLAC 1.1.2 a seekable stream decoder would have + * been set up like so: + * + * \code + * FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new(); + * if(decoder == NULL) do_something; + * FLAC__seekable_stream_decoder_set_md5_checking(decoder, true); + * [... other settings ...] + * FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback); + * FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback); + * FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback); + * FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback); + * FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback); + * FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback); + * FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback); + * FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback); + * FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data); + * if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something; + * \endcode + * + * In FLAC 1.1.3 it is like this: + * + * \code + * FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); + * if(decoder == NULL) do_something; + * FLAC__stream_decoder_set_md5_checking(decoder, true); + * [... other settings ...] + * if(FLAC__stream_decoder_init_stream( + * decoder, + * my_read_callback, + * my_seek_callback, // or NULL + * my_tell_callback, // or NULL + * my_length_callback, // or NULL + * my_eof_callback, // or NULL + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * or you could do; + * + * \code + * [...] + * FILE *file = fopen("somefile.flac","rb"); + * if(file == NULL) do_somthing; + * if(FLAC__stream_decoder_init_FILE( + * decoder, + * file, + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * or just: + * + * \code + * [...] + * if(FLAC__stream_decoder_init_file( + * decoder, + * "somefile.flac", + * my_write_callback, + * my_metadata_callback, // or NULL + * my_error_callback, + * my_client_data + * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; + * \endcode + * + * Another small change to the decoder is in how it handles unparseable + * streams. Before, when the decoder found an unparseable stream + * (reserved for when the decoder encounters a stream from a future + * encoder that it can't parse), it changed the state to + * \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead + * drops sync and calls the error callback with a new error code + * \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is + * more robust. If your error callback does not discriminate on the the + * error state, your code does not need to be changed. + * + * The encoder now has a new setting: + * FLAC__stream_encoder_set_apodization(). This is for setting the + * method used to window the data before LPC analysis. You only need to + * add a call to this function if the default is not suitable. There + * are also two new convenience functions that may be useful: + * FLAC__metadata_object_cuesheet_calculate_cddb_id() and + * FLAC__metadata_get_cuesheet(). + * + * The \a bytes parameter to FLAC__StreamDecoderReadCallback, + * FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback + * is now \c size_t instead of \c unsigned. + */ + +/** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.3 to FLAC 1.1.4. + * + * There were no changes to any of the interfaces from 1.1.3 to 1.1.4. + * There was a slight change in the implementation of + * FLAC__stream_encoder_set_metadata(); the function now makes a copy + * of the \a metadata array of pointers so the client no longer needs + * to maintain it after the call. The objects themselves that are + * pointed to by the array are still not copied though and must be + * maintained until the call to FLAC__stream_encoder_finish(). + */ + +/** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.1.4 to FLAC 1.2.0. + * + * There were only very minor changes to the interfaces from 1.1.4 to 1.2.0. + * In libFLAC, \c FLAC__format_sample_rate_is_subset() was added. + * In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added. + * + * Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN + * has changed to reflect the conversion of one of the reserved bits + * into active use. It used to be \c 2 and now is \c 1. However the + * FLAC frame header length has not changed, so to skip the proper + * number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN + + * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN + */ + +/** \defgroup flac FLAC C API + * + * The FLAC C API is the interface to libFLAC, a set of structures + * describing the components of FLAC streams, and functions for + * encoding and decoding streams, as well as manipulating FLAC + * metadata in files. + * + * You should start with the format components as all other modules + * are dependent on it. + */ + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/assert.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/assert.h new file mode 100644 index 00000000..dc9bcef4 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/assert.h @@ -0,0 +1,46 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__ASSERT_H +#define FLAC__ASSERT_H + +/* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */ +#ifdef DEBUG +#include +#define FLAC__ASSERT(x) assert(x) +#define FLAC__ASSERT_DECLARATION(x) x +#else +#define FLAC__ASSERT(x) +#define FLAC__ASSERT_DECLARATION(x) +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/callback.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/callback.h new file mode 100644 index 00000000..ce8787ff --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/callback.h @@ -0,0 +1,185 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2004-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__CALLBACK_H +#define FLAC__CALLBACK_H + +#include "ordinals.h" +#include /* for size_t */ + +/** \file include/FLAC/callback.h + * + * \brief + * This module defines the structures for describing I/O callbacks + * to the other FLAC interfaces. + * + * See the detailed documentation for callbacks in the + * \link flac_callbacks callbacks \endlink module. + */ + +/** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures + * \ingroup flac + * + * \brief + * This module defines the structures for describing I/O callbacks + * to the other FLAC interfaces. + * + * The purpose of the I/O callback functions is to create a common way + * for the metadata interfaces to handle I/O. + * + * Originally the metadata interfaces required filenames as the way of + * specifying FLAC files to operate on. This is problematic in some + * environments so there is an additional option to specify a set of + * callbacks for doing I/O on the FLAC file, instead of the filename. + * + * In addition to the callbacks, a FLAC__IOHandle type is defined as an + * opaque structure for a data source. + * + * The callback function prototypes are similar (but not identical) to the + * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use + * stdio streams to implement the callbacks, you can pass fread, fwrite, and + * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or + * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle + * is required. \warning You generally CANNOT directly use fseek or ftell + * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems + * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with + * large files. You will have to find an equivalent function (e.g. ftello), + * or write a wrapper. The same is true for feof() since this is usually + * implemented as a macro, not as a function whose address can be taken. + * + * \{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** This is the opaque handle type used by the callbacks. Typically + * this is a \c FILE* or address of a file descriptor. + */ +typedef void* FLAC__IOHandle; + +/** Signature for the read callback. + * The signature and semantics match POSIX fread() implementations + * and can generally be used interchangeably. + * + * \param ptr The address of the read buffer. + * \param size The size of the records to be read. + * \param nmemb The number of records to be read. + * \param handle The handle to the data source. + * \retval size_t + * The number of records read. + */ +typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); + +/** Signature for the write callback. + * The signature and semantics match POSIX fwrite() implementations + * and can generally be used interchangeably. + * + * \param ptr The address of the write buffer. + * \param size The size of the records to be written. + * \param nmemb The number of records to be written. + * \param handle The handle to the data source. + * \retval size_t + * The number of records written. + */ +typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); + +/** Signature for the seek callback. + * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT + * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long' + * and 32-bits wide. + * + * \param handle The handle to the data source. + * \param offset The new position, relative to \a whence + * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END + * \retval int + * \c 0 on success, \c -1 on error. + */ +typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence); + +/** Signature for the tell callback. + * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT + * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long' + * and 32-bits wide. + * + * \param handle The handle to the data source. + * \retval FLAC__int64 + * The current position on success, \c -1 on error. + */ +typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle); + +/** Signature for the EOF callback. + * The signature and semantics mostly match POSIX feof() but WATCHOUT: + * on many systems, feof() is a macro, so in this case a wrapper function + * must be provided instead. + * + * \param handle The handle to the data source. + * \retval int + * \c 0 if not at end of file, nonzero if at end of file. + */ +typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle); + +/** Signature for the close callback. + * The signature and semantics match POSIX fclose() implementations + * and can generally be used interchangeably. + * + * \param handle The handle to the data source. + * \retval int + * \c 0 on success, \c EOF on error. + */ +typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle); + +/** A structure for holding a set of callbacks. + * Each FLAC interface that requires a FLAC__IOCallbacks structure will + * describe which of the callbacks are required. The ones that are not + * required may be set to NULL. + * + * If the seek requirement for an interface is optional, you can signify that + * a data sorce is not seekable by setting the \a seek field to \c NULL. + */ +typedef struct { + FLAC__IOCallback_Read read; + FLAC__IOCallback_Write write; + FLAC__IOCallback_Seek seek; + FLAC__IOCallback_Tell tell; + FLAC__IOCallback_Eof eof; + FLAC__IOCallback_Close close; +} FLAC__IOCallbacks; + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/export.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/export.h new file mode 100644 index 00000000..9cc9e137 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/export.h @@ -0,0 +1,97 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__EXPORT_H +#define FLAC__EXPORT_H + +/** \file include/FLAC/export.h + * + * \brief + * This module contains #defines and symbols for exporting function + * calls, and providing version information and compiled-in features. + * + * See the \link flac_export export \endlink module. + */ + +/** \defgroup flac_export FLAC/export.h: export symbols + * \ingroup flac + * + * \brief + * This module contains #defines and symbols for exporting function + * calls, and providing version information and compiled-in features. + * + * If you are compiling with MSVC and will link to the static library + * (libFLAC.lib) you should define FLAC__NO_DLL in your project to + * make sure the symbols are exported properly. + * + * \{ + */ + +#if defined(FLAC__NO_DLL) +#define FLAC_API + +#elif defined(_MSC_VER) +#ifdef FLAC_API_EXPORTS +#define FLAC_API __declspec(dllexport) +#else +#define FLAC_API __declspec(dllimport) +#endif + +#elif defined(FLAC__USE_VISIBILITY_ATTR) +#define FLAC_API __attribute__ ((visibility ("default"))) + +#else +#define FLAC_API + +#endif + +/** These #defines will mirror the libtool-based library version number, see + * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning + */ +#define FLAC_API_VERSION_CURRENT 11 +#define FLAC_API_VERSION_REVISION 0 /**< see above */ +#define FLAC_API_VERSION_AGE 3 /**< see above */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */ +extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC; + +#ifdef __cplusplus +} +#endif + +/* \} */ + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/format.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/format.h new file mode 100644 index 00000000..7424565b --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/format.h @@ -0,0 +1,1025 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__FORMAT_H +#define FLAC__FORMAT_H + +#include "export.h" +#include "ordinals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file include/FLAC/format.h + * + * \brief + * This module contains structure definitions for the representation + * of FLAC format components in memory. These are the basic + * structures used by the rest of the interfaces. + * + * See the detailed documentation in the + * \link flac_format format \endlink module. + */ + +/** \defgroup flac_format FLAC/format.h: format components + * \ingroup flac + * + * \brief + * This module contains structure definitions for the representation + * of FLAC format components in memory. These are the basic + * structures used by the rest of the interfaces. + * + * First, you should be familiar with the + * FLAC format. Many of the values here + * follow directly from the specification. As a user of libFLAC, the + * interesting parts really are the structures that describe the frame + * header and metadata blocks. + * + * The format structures here are very primitive, designed to store + * information in an efficient way. Reading information from the + * structures is easy but creating or modifying them directly is + * more complex. For the most part, as a user of a library, editing + * is not necessary; however, for metadata blocks it is, so there are + * convenience functions provided in the \link flac_metadata metadata + * module \endlink to simplify the manipulation of metadata blocks. + * + * \note + * It's not the best convention, but symbols ending in _LEN are in bits + * and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of + * global variables because they are usually used when declaring byte + * arrays and some compilers require compile-time knowledge of array + * sizes when declared on the stack. + * + * \{ + */ + + +/* + Most of the values described in this file are defined by the FLAC + format specification. There is nothing to tune here. +*/ + +/** The largest legal metadata type code. */ +#define FLAC__MAX_METADATA_TYPE_CODE (126u) + +/** The minimum block size, in samples, permitted by the format. */ +#define FLAC__MIN_BLOCK_SIZE (16u) + +/** The maximum block size, in samples, permitted by the format. */ +#define FLAC__MAX_BLOCK_SIZE (65535u) + +/** The maximum block size, in samples, permitted by the FLAC subset for + * sample rates up to 48kHz. */ +#define FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ (4608u) + +/** The maximum number of channels permitted by the format. */ +#define FLAC__MAX_CHANNELS (8u) + +/** The minimum sample resolution permitted by the format. */ +#define FLAC__MIN_BITS_PER_SAMPLE (4u) + +/** The maximum sample resolution permitted by the format. */ +#define FLAC__MAX_BITS_PER_SAMPLE (32u) + +/** The maximum sample resolution permitted by libFLAC. + * + * \warning + * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, + * the reference encoder/decoder is currently limited to 24 bits because + * of prevalent 32-bit math, so make sure and use this value when + * appropriate. + */ +#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u) + +/** The maximum sample rate permitted by the format. The value is + * ((2 ^ 16) - 1) * 10; see FLAC format + * as to why. + */ +#define FLAC__MAX_SAMPLE_RATE (655350u) + +/** The maximum LPC order permitted by the format. */ +#define FLAC__MAX_LPC_ORDER (32u) + +/** The maximum LPC order permitted by the FLAC subset for sample rates + * up to 48kHz. */ +#define FLAC__SUBSET_MAX_LPC_ORDER_48000HZ (12u) + +/** The minimum quantized linear predictor coefficient precision + * permitted by the format. + */ +#define FLAC__MIN_QLP_COEFF_PRECISION (5u) + +/** The maximum quantized linear predictor coefficient precision + * permitted by the format. + */ +#define FLAC__MAX_QLP_COEFF_PRECISION (15u) + +/** The maximum order of the fixed predictors permitted by the format. */ +#define FLAC__MAX_FIXED_ORDER (4u) + +/** The maximum Rice partition order permitted by the format. */ +#define FLAC__MAX_RICE_PARTITION_ORDER (15u) + +/** The maximum Rice partition order permitted by the FLAC Subset. */ +#define FLAC__SUBSET_MAX_RICE_PARTITION_ORDER (8u) + +/** The version string of the release, stamped onto the libraries and binaries. + * + * \note + * This does not correspond to the shared library version number, which + * is used to determine binary compatibility. + */ +extern FLAC_API const char *FLAC__VERSION_STRING; + +/** The vendor string inserted by the encoder into the VORBIS_COMMENT block. + * This is a NUL-terminated ASCII string; when inserted into the + * VORBIS_COMMENT the trailing null is stripped. + */ +extern FLAC_API const char *FLAC__VENDOR_STRING; + +/** The byte string representation of the beginning of a FLAC stream. */ +extern FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4]; /* = "fLaC" */ + +/** The 32-bit integer big-endian representation of the beginning of + * a FLAC stream. + */ +extern FLAC_API const unsigned FLAC__STREAM_SYNC; /* = 0x664C6143 */ + +/** The length of the FLAC signature in bits. */ +extern FLAC_API const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */ + +/** The length of the FLAC signature in bytes. */ +#define FLAC__STREAM_SYNC_LENGTH (4u) + + +/***************************************************************************** + * + * Subframe structures + * + *****************************************************************************/ + +/*****************************************************************************/ + +/** An enumeration of the available entropy coding methods. */ +typedef enum { + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0, + /**< Residual is coded by partitioning into contexts, each with it's own + * 4-bit Rice parameter. */ + + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 + /**< Residual is coded by partitioning into contexts, each with it's own + * 5-bit Rice parameter. */ +} FLAC__EntropyCodingMethodType; + +/** Maps a FLAC__EntropyCodingMethodType to a C string. + * + * Using a FLAC__EntropyCodingMethodType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[]; + + +/** Contents of a Rice partitioned residual + */ +typedef struct { + + unsigned *parameters; + /**< The Rice parameters for each context. */ + + unsigned *raw_bits; + /**< Widths for escape-coded partitions. Will be non-zero for escaped + * partitions and zero for unescaped partitions. + */ + + unsigned capacity_by_order; + /**< The capacity of the \a parameters and \a raw_bits arrays + * specified as an order, i.e. the number of array elements + * allocated is 2 ^ \a capacity_by_order. + */ +} FLAC__EntropyCodingMethod_PartitionedRiceContents; + +/** Header for a Rice partitioned residual. (c.f. format specification) + */ +typedef struct { + + unsigned order; + /**< The partition order, i.e. # of contexts = 2 ^ \a order. */ + + const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents; + /**< The context's Rice parameters and/or raw bits. */ + +} FLAC__EntropyCodingMethod_PartitionedRice; + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN; /**< == 5 (bits) */ +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */ + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; +/**< == (1<format specification) + */ +typedef struct { + FLAC__EntropyCodingMethodType type; + union { + FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice; + } data; +} FLAC__EntropyCodingMethod; + +extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 (bits) */ + +/*****************************************************************************/ + +/** An enumeration of the available subframe types. */ +typedef enum { + FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */ + FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */ + FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */ + FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */ +} FLAC__SubframeType; + +/** Maps a FLAC__SubframeType to a C string. + * + * Using a FLAC__SubframeType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__SubframeTypeString[]; + + +/** CONSTANT subframe. (c.f. format specification) + */ +typedef struct { + FLAC__int32 value; /**< The constant signal value. */ +} FLAC__Subframe_Constant; + + +/** VERBATIM subframe. (c.f. format specification) + */ +typedef struct { + const FLAC__int32 *data; /**< A pointer to verbatim signal. */ +} FLAC__Subframe_Verbatim; + + +/** FIXED subframe. (c.f. format specification) + */ +typedef struct { + FLAC__EntropyCodingMethod entropy_coding_method; + /**< The residual coding method. */ + + unsigned order; + /**< The polynomial order. */ + + FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; + /**< Warmup samples to prime the predictor, length == order. */ + + const FLAC__int32 *residual; + /**< The residual signal, length == (blocksize minus order) samples. */ +} FLAC__Subframe_Fixed; + + +/** LPC subframe. (c.f. format specification) + */ +typedef struct { + FLAC__EntropyCodingMethod entropy_coding_method; + /**< The residual coding method. */ + + unsigned order; + /**< The FIR order. */ + + unsigned qlp_coeff_precision; + /**< Quantized FIR filter coefficient precision in bits. */ + + int quantization_level; + /**< The qlp coeff shift needed. */ + + FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; + /**< FIR filter coefficients. */ + + FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; + /**< Warmup samples to prime the predictor, length == order. */ + + const FLAC__int32 *residual; + /**< The residual signal, length == (blocksize minus order) samples. */ +} FLAC__Subframe_LPC; + +extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */ + + +/** FLAC subframe structure. (c.f. format specification) + */ +typedef struct { + FLAC__SubframeType type; + union { + FLAC__Subframe_Constant constant; + FLAC__Subframe_Fixed fixed; + FLAC__Subframe_LPC lpc; + FLAC__Subframe_Verbatim verbatim; + } data; + unsigned wasted_bits; +} FLAC__Subframe; + +/** == 1 (bit) + * + * This used to be a zero-padding bit (hence the name + * FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit. It still has a + * mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1 + * to mean something else. + */ +extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN; +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */ +extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */ + +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK; /**< = 0x00 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK; /**< = 0x02 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK; /**< = 0x10 */ +extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /**< = 0x40 */ + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Frame structures + * + *****************************************************************************/ + +/** An enumeration of the available channel assignments. */ +typedef enum { + FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */ + FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */ + FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */ +} FLAC__ChannelAssignment; + +/** Maps a FLAC__ChannelAssignment to a C string. + * + * Using a FLAC__ChannelAssignment as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__ChannelAssignmentString[]; + +/** An enumeration of the possible frame numbering methods. */ +typedef enum { + FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */ + FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */ +} FLAC__FrameNumberType; + +/** Maps a FLAC__FrameNumberType to a C string. + * + * Using a FLAC__FrameNumberType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__FrameNumberTypeString[]; + + +/** FLAC frame header structure. (c.f. format specification) + */ +typedef struct { + unsigned blocksize; + /**< The number of samples per subframe. */ + + unsigned sample_rate; + /**< The sample rate in Hz. */ + + unsigned channels; + /**< The number of channels (== number of subframes). */ + + FLAC__ChannelAssignment channel_assignment; + /**< The channel assignment for the frame. */ + + unsigned bits_per_sample; + /**< The sample resolution. */ + + FLAC__FrameNumberType number_type; + /**< The numbering scheme used for the frame. As a convenience, the + * decoder will always convert a frame number to a sample number because + * the rules are complex. */ + + union { + FLAC__uint32 frame_number; + FLAC__uint64 sample_number; + } number; + /**< The frame number or sample number of first sample in frame; + * use the \a number_type value to determine which to use. */ + + FLAC__uint8 crc; + /**< CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) + * of the raw frame header bytes, meaning everything before the CRC byte + * including the sync code. + */ +} FLAC__FrameHeader; + +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 1 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN; /**< == 1 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /**< == 3 (bits) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */ + + +/** FLAC frame footer structure. (c.f. format specification) + */ +typedef struct { + FLAC__uint16 crc; + /**< CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with + * 0) of the bytes before the crc, back to and including the frame header + * sync code. + */ +} FLAC__FrameFooter; + +extern FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */ + + +/** FLAC frame structure. (c.f. format specification) + */ +typedef struct { + FLAC__FrameHeader header; + FLAC__Subframe subframes[FLAC__MAX_CHANNELS]; + FLAC__FrameFooter footer; +} FLAC__Frame; + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Meta-data structures + * + *****************************************************************************/ + +/** An enumeration of the available metadata block types. */ +typedef enum { + + FLAC__METADATA_TYPE_STREAMINFO = 0, + /**< STREAMINFO block */ + + FLAC__METADATA_TYPE_PADDING = 1, + /**< PADDING block */ + + FLAC__METADATA_TYPE_APPLICATION = 2, + /**< APPLICATION block */ + + FLAC__METADATA_TYPE_SEEKTABLE = 3, + /**< SEEKTABLE block */ + + FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, + /**< VORBISCOMMENT block (a.k.a. FLAC tags) */ + + FLAC__METADATA_TYPE_CUESHEET = 5, + /**< CUESHEET block */ + + FLAC__METADATA_TYPE_PICTURE = 6, + /**< PICTURE block */ + + FLAC__METADATA_TYPE_UNDEFINED = 7, + /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ + + FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE, + /**< No type will ever be greater than this. There is not enough room in the protocol block. */ +} FLAC__MetadataType; + +/** Maps a FLAC__MetadataType to a C string. + * + * Using a FLAC__MetadataType as the index to this array will + * give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__MetadataTypeString[]; + + +/** FLAC STREAMINFO structure. (c.f. format specification) + */ +typedef struct { + unsigned min_blocksize, max_blocksize; + unsigned min_framesize, max_framesize; + unsigned sample_rate; + unsigned channels; + unsigned bits_per_sample; + FLAC__uint64 total_samples; + FLAC__byte md5sum[16]; +} FLAC__StreamMetadata_StreamInfo; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; /**< == 16 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; /**< == 16 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; /**< == 24 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; /**< == 24 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; /**< == 20 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; /**< == 3 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; /**< == 5 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; /**< == 36 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< == 128 (bits) */ + +/** The total stream length of the STREAMINFO block in bytes. */ +#define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u) + +/** FLAC PADDING structure. (c.f. format specification) + */ +typedef struct { + int dummy; + /**< Conceptually this is an empty struct since we don't store the + * padding bytes. Empty structs are not allowed by some C compilers, + * hence the dummy. + */ +} FLAC__StreamMetadata_Padding; + + +/** FLAC APPLICATION structure. (c.f. format specification) + */ +typedef struct { + FLAC__byte id[4]; + FLAC__byte *data; +} FLAC__StreamMetadata_Application; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */ + +/** SeekPoint structure used in SEEKTABLE blocks. (c.f. format specification) + */ +typedef struct { + FLAC__uint64 sample_number; + /**< The sample number of the target frame. */ + + FLAC__uint64 stream_offset; + /**< The offset, in bytes, of the target frame with respect to + * beginning of the first frame. */ + + unsigned frame_samples; + /**< The number of samples in the target frame. */ +} FLAC__StreamMetadata_SeekPoint; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN; /**< == 16 (bits) */ + +/** The total stream length of a seek point in bytes. */ +#define FLAC__STREAM_METADATA_SEEKPOINT_LENGTH (18u) + +/** The value used in the \a sample_number field of + * FLAC__StreamMetadataSeekPoint used to indicate a placeholder + * point (== 0xffffffffffffffff). + */ +extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + + +/** FLAC SEEKTABLE structure. (c.f. format specification) + * + * \note From the format specification: + * - The seek points must be sorted by ascending sample number. + * - Each seek point's sample number must be the first sample of the + * target frame. + * - Each seek point's sample number must be unique within the table. + * - Existence of a SEEKTABLE block implies a correct setting of + * total_samples in the stream_info block. + * - Behavior is undefined when more than one SEEKTABLE block is + * present in a stream. + */ +typedef struct { + unsigned num_points; + FLAC__StreamMetadata_SeekPoint *points; +} FLAC__StreamMetadata_SeekTable; + + +/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. format specification) + * + * For convenience, the APIs maintain a trailing NUL character at the end of + * \a entry which is not counted toward \a length, i.e. + * \code strlen(entry) == length \endcode + */ +typedef struct { + FLAC__uint32 length; + FLAC__byte *entry; +} FLAC__StreamMetadata_VorbisComment_Entry; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */ + + +/** FLAC VORBIS_COMMENT structure. (c.f. format specification) + */ +typedef struct { + FLAC__StreamMetadata_VorbisComment_Entry vendor_string; + FLAC__uint32 num_comments; + FLAC__StreamMetadata_VorbisComment_Entry *comments; +} FLAC__StreamMetadata_VorbisComment; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN; /**< == 32 (bits) */ + + +/** FLAC CUESHEET track index structure. (See the + * format specification for + * the full description of each field.) + */ +typedef struct { + FLAC__uint64 offset; + /**< Offset in samples, relative to the track offset, of the index + * point. + */ + + FLAC__byte number; + /**< The index point number. */ +} FLAC__StreamMetadata_CueSheet_Index; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN; /**< == 8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN; /**< == 3*8 (bits) */ + + +/** FLAC CUESHEET track structure. (See the + * format specification for + * the full description of each field.) + */ +typedef struct { + FLAC__uint64 offset; + /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */ + + FLAC__byte number; + /**< The track number. */ + + char isrc[13]; + /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing \c NUL byte */ + + unsigned type:1; + /**< The track type: 0 for audio, 1 for non-audio. */ + + unsigned pre_emphasis:1; + /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */ + + FLAC__byte num_indices; + /**< The number of track index points. */ + + FLAC__StreamMetadata_CueSheet_Index *indices; + /**< NULL if num_indices == 0, else pointer to array of index points. */ + +} FLAC__StreamMetadata_CueSheet_Track; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN; /**< == 8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN; /**< == 12*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN; /**< == 6+13*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN; /**< == 8 (bits) */ + + +/** FLAC CUESHEET structure. (See the + * format specification + * for the full description of each field.) + */ +typedef struct { + char media_catalog_number[129]; + /**< Media catalog number, in ASCII printable characters 0x20-0x7e. In + * general, the media catalog number may be 0 to 128 bytes long; any + * unused characters should be right-padded with NUL characters. + */ + + FLAC__uint64 lead_in; + /**< The number of lead-in samples. */ + + FLAC__bool is_cd; + /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false. */ + + unsigned num_tracks; + /**< The number of tracks. */ + + FLAC__StreamMetadata_CueSheet_Track *tracks; + /**< NULL if num_tracks == 0, else pointer to array of tracks. */ + +} FLAC__StreamMetadata_CueSheet; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN; /**< == 128*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN; /**< == 64 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN; /**< == 7+258*8 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN; /**< == 8 (bits) */ + + +/** An enumeration of the PICTURE types (see FLAC__StreamMetadataPicture and id3 v2.4 APIC tag). */ +typedef enum { + FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER = 0, /**< Other */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD = 1, /**< 32x32 pixels 'file icon' (PNG only) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON = 2, /**< Other file icon */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER = 3, /**< Cover (front) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER = 4, /**< Cover (back) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE = 5, /**< Leaflet page */ + FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA = 6, /**< Media (e.g. label side of CD) */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST = 7, /**< Lead artist/lead performer/soloist */ + FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST = 8, /**< Artist/performer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR = 9, /**< Conductor */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BAND = 10, /**< Band/Orchestra */ + FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER = 11, /**< Composer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST = 12, /**< Lyricist/text writer */ + FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION = 13, /**< Recording Location */ + FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING = 14, /**< During recording */ + FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE = 15, /**< During performance */ + FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE = 16, /**< Movie/video screen capture */ + FLAC__STREAM_METADATA_PICTURE_TYPE_FISH = 17, /**< A bright coloured fish */ + FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION = 18, /**< Illustration */ + FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE = 19, /**< Band/artist logotype */ + FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE = 20, /**< Publisher/Studio logotype */ + FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED +} FLAC__StreamMetadata_Picture_Type; + +/** Maps a FLAC__StreamMetadata_Picture_Type to a C string. + * + * Using a FLAC__StreamMetadata_Picture_Type as the index to this array + * will give the string equivalent. The contents should not be + * modified. + */ +extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[]; + +/** FLAC PICTURE structure. (See the + * format specification + * for the full description of each field.) + */ +typedef struct { + FLAC__StreamMetadata_Picture_Type type; + /**< The kind of picture stored. */ + + char *mime_type; + /**< Picture data's MIME type, in ASCII printable characters + * 0x20-0x7e, NUL terminated. For best compatibility with players, + * use picture data of MIME type \c image/jpeg or \c image/png. A + * MIME type of '-->' is also allowed, in which case the picture + * data should be a complete URL. In file storage, the MIME type is + * stored as a 32-bit length followed by the ASCII string with no NUL + * terminator, but is converted to a plain C string in this structure + * for convenience. + */ + + FLAC__byte *description; + /**< Picture's description in UTF-8, NUL terminated. In file storage, + * the description is stored as a 32-bit length followed by the UTF-8 + * string with no NUL terminator, but is converted to a plain C string + * in this structure for convenience. + */ + + FLAC__uint32 width; + /**< Picture's width in pixels. */ + + FLAC__uint32 height; + /**< Picture's height in pixels. */ + + FLAC__uint32 depth; + /**< Picture's color depth in bits-per-pixel. */ + + FLAC__uint32 colors; + /**< For indexed palettes (like GIF), picture's number of colors (the + * number of palette entries), or \c 0 for non-indexed (i.e. 2^depth). + */ + + FLAC__uint32 data_length; + /**< Length of binary picture data in bytes. */ + + FLAC__byte *data; + /**< Binary picture data. */ + +} FLAC__StreamMetadata_Picture; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN; /**< == 32 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN; /**< == 32 (bits) */ + + +/** Structure that is used when a metadata block of unknown type is loaded. + * The contents are opaque. The structure is used only internally to + * correctly handle unknown metadata. + */ +typedef struct { + FLAC__byte *data; +} FLAC__StreamMetadata_Unknown; + + +/** FLAC metadata block structure. (c.f. format specification) + */ +typedef struct { + FLAC__MetadataType type; + /**< The type of the metadata block; used determine which member of the + * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED + * then \a data.unknown must be used. */ + + FLAC__bool is_last; + /**< \c true if this metadata block is the last, else \a false */ + + unsigned length; + /**< Length, in bytes, of the block data as it appears in the stream. */ + + union { + FLAC__StreamMetadata_StreamInfo stream_info; + FLAC__StreamMetadata_Padding padding; + FLAC__StreamMetadata_Application application; + FLAC__StreamMetadata_SeekTable seek_table; + FLAC__StreamMetadata_VorbisComment vorbis_comment; + FLAC__StreamMetadata_CueSheet cue_sheet; + FLAC__StreamMetadata_Picture picture; + FLAC__StreamMetadata_Unknown unknown; + } data; + /**< Polymorphic block data; use the \a type value to determine which + * to use. */ +} FLAC__StreamMetadata; + +extern FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN; /**< == 1 (bit) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN; /**< == 7 (bits) */ +extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bits) */ + +/** The total stream length of a metadata block header in bytes. */ +#define FLAC__STREAM_METADATA_HEADER_LENGTH (4u) + +/*****************************************************************************/ + + +/***************************************************************************** + * + * Utility functions + * + *****************************************************************************/ + +/** Tests that a sample rate is valid for FLAC. + * + * \param sample_rate The sample rate to test for compliance. + * \retval FLAC__bool + * \c true if the given sample rate conforms to the specification, else + * \c false. + */ +FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate); + +/** Tests that a blocksize at the given sample rate is valid for the FLAC + * subset. + * + * \param blocksize The blocksize to test for compliance. + * \param sample_rate The sample rate is needed, since the valid subset + * blocksize depends on the sample rate. + * \retval FLAC__bool + * \c true if the given blocksize conforms to the specification for the + * subset at the given sample rate, else \c false. + */ +FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate); + +/** Tests that a sample rate is valid for the FLAC subset. The subset rules + * for valid sample rates are slightly more complex since the rate has to + * be expressible completely in the frame header. + * + * \param sample_rate The sample rate to test for compliance. + * \retval FLAC__bool + * \c true if the given sample rate conforms to the specification for the + * subset, else \c false. + */ +FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate); + +/** Check a Vorbis comment entry name to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment names must be composed only of characters from + * [0x20-0x3C,0x3E-0x7D]. + * + * \param name A NUL-terminated string to be checked. + * \assert + * \code name != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name); + +/** Check a Vorbis comment entry value to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment values must be valid UTF-8 sequences. + * + * \param value A string to be checked. + * \param length A the length of \a value in bytes. May be + * \c (unsigned)(-1) to indicate that \a value is a plain + * UTF-8 NUL-terminated string. + * \assert + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length); + +/** Check a Vorbis comment entry to see if it conforms to the Vorbis + * comment specification. + * + * Vorbis comment entries must be of the form 'name=value', and 'name' and + * 'value' must be legal according to + * FLAC__format_vorbiscomment_entry_name_is_legal() and + * FLAC__format_vorbiscomment_entry_value_is_legal() respectively. + * + * \param entry An entry to be checked. + * \param length The length of \a entry in bytes. + * \assert + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if entry name is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length); + +/** Check a seek table to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * seek table. + * + * \param seek_table A pointer to a seek table to be checked. + * \assert + * \code seek_table != NULL \endcode + * \retval FLAC__bool + * \c false if seek table is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table); + +/** Sort a seek table's seek points according to the format specification. + * This includes a "unique-ification" step to remove duplicates, i.e. + * seek points with identical \a sample_number values. Duplicate seek + * points are converted into placeholder points and sorted to the end of + * the table. + * + * \param seek_table A pointer to a seek table to be sorted. + * \assert + * \code seek_table != NULL \endcode + * \retval unsigned + * The number of duplicate seek points converted into placeholders. + */ +FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table); + +/** Check a cue sheet to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * cue sheet. + * + * \param cue_sheet A pointer to an existing cue sheet to be checked. + * \param check_cd_da_subset If \c true, check CUESHEET against more + * stringent requirements for a CD-DA (audio) disc. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code cue_sheet != NULL \endcode + * \retval FLAC__bool + * \c false if cue sheet is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation); + +/** Check picture data to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * PICTURE block. + * + * \param picture A pointer to existing picture data to be checked. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code picture != NULL \endcode + * \retval FLAC__bool + * \c false if picture data is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/metadata.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/metadata.h new file mode 100644 index 00000000..89515329 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/metadata.h @@ -0,0 +1,2182 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__METADATA_H +#define FLAC__METADATA_H + +#include /* for off_t */ +#include "export.h" +#include "callback.h" +#include "format.h" + +/* -------------------------------------------------------------------- + (For an example of how all these routines are used, see the source + code for the unit tests in src/test_libFLAC/metadata_*.c, or + metaflac in src/metaflac/) + ------------------------------------------------------------------*/ + +/** \file include/FLAC/metadata.h + * + * \brief + * This module provides functions for creating and manipulating FLAC + * metadata blocks in memory, and three progressively more powerful + * interfaces for traversing and editing metadata in FLAC files. + * + * See the detailed documentation for each interface in the + * \link flac_metadata metadata \endlink module. + */ + +/** \defgroup flac_metadata FLAC/metadata.h: metadata interfaces + * \ingroup flac + * + * \brief + * This module provides functions for creating and manipulating FLAC + * metadata blocks in memory, and three progressively more powerful + * interfaces for traversing and editing metadata in native FLAC files. + * Note that currently only the Chain interface (level 2) supports Ogg + * FLAC files, and it is read-only i.e. no writing back changed + * metadata to file. + * + * There are three metadata interfaces of increasing complexity: + * + * Level 0: + * Read-only access to the STREAMINFO, VORBIS_COMMENT, CUESHEET, and + * PICTURE blocks. + * + * Level 1: + * Read-write access to all metadata blocks. This level is write- + * efficient in most cases (more on this below), and uses less memory + * than level 2. + * + * Level 2: + * Read-write access to all metadata blocks. This level is write- + * efficient in all cases, but uses more memory since all metadata for + * the whole file is read into memory and manipulated before writing + * out again. + * + * What do we mean by efficient? Since FLAC metadata appears at the + * beginning of the file, when writing metadata back to a FLAC file + * it is possible to grow or shrink the metadata such that the entire + * file must be rewritten. However, if the size remains the same during + * changes or PADDING blocks are utilized, only the metadata needs to be + * overwritten, which is much faster. + * + * Efficient means the whole file is rewritten at most one time, and only + * when necessary. Level 1 is not efficient only in the case that you + * cause more than one metadata block to grow or shrink beyond what can + * be accomodated by padding. In this case you should probably use level + * 2, which allows you to edit all the metadata for a file in memory and + * write it out all at once. + * + * All levels know how to skip over and not disturb an ID3v2 tag at the + * front of the file. + * + * All levels access files via their filenames. In addition, level 2 + * has additional alternative read and write functions that take an I/O + * handle and callbacks, for situations where access by filename is not + * possible. + * + * In addition to the three interfaces, this module defines functions for + * creating and manipulating various metadata objects in memory. As we see + * from the Format module, FLAC metadata blocks in memory are very primitive + * structures for storing information in an efficient way. Reading + * information from the structures is easy but creating or modifying them + * directly is more complex. The metadata object routines here facilitate + * this by taking care of the consistency and memory management drudgery. + * + * Unless you will be using the level 1 or 2 interfaces to modify existing + * metadata however, you will not probably not need these. + * + * From a dependency standpoint, none of the encoders or decoders require + * the metadata module. This is so that embedded users can strip out the + * metadata module from libFLAC to reduce the size and complexity. + */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \defgroup flac_metadata_level0 FLAC/metadata.h: metadata level 0 interface + * \ingroup flac_metadata + * + * \brief + * The level 0 interface consists of individual routines to read the + * STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring + * only a filename. + * + * They try to skip any ID3v2 tag at the head of the file. + * + * \{ + */ + +/** Read the STREAMINFO metadata block of the given FLAC file. This function + * will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param streaminfo A pointer to space for the STREAMINFO block. Since + * FLAC__StreamMetadata is a simple structure with no + * memory allocation involved, you pass the address of + * an existing structure. It need not be initialized. + * \assert + * \code filename != NULL \endcode + * \code streaminfo != NULL \endcode + * \retval FLAC__bool + * \c true if a valid STREAMINFO block was read from \a filename. Returns + * \c false if there was a memory allocation error, a file decoder error, + * or the file contained no STREAMINFO block. (A memory allocation error + * is possible because this function must set up a file decoder.) + */ +FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo); + +/** Read the VORBIS_COMMENT metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param tags The address where the returned pointer will be + * stored. The \a tags object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \assert + * \code filename != NULL \endcode + * \code tags != NULL \endcode + * \retval FLAC__bool + * \c true if a valid VORBIS_COMMENT block was read from \a filename, + * and \a *tags will be set to the address of the metadata structure. + * Returns \c false if there was a memory allocation error, a file + * decoder error, or the file contained no VORBIS_COMMENT block, and + * \a *tags will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags); + +/** Read the CUESHEET metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * + * \param filename The path to the FLAC file to read. + * \param cuesheet The address where the returned pointer will be + * stored. The \a cuesheet object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \assert + * \code filename != NULL \endcode + * \code cuesheet != NULL \endcode + * \retval FLAC__bool + * \c true if a valid CUESHEET block was read from \a filename, + * and \a *cuesheet will be set to the address of the metadata + * structure. Returns \c false if there was a memory allocation + * error, a file decoder error, or the file contained no CUESHEET + * block, and \a *cuesheet will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet); + +/** Read a PICTURE metadata block of the given FLAC file. This + * function will try to skip any ID3v2 tag at the head of the file. + * Since there can be more than one PICTURE block in a file, this + * function takes a number of parameters that act as constraints to + * the search. The PICTURE block with the largest area matching all + * the constraints will be returned, or \a *picture will be set to + * \c NULL if there was no such block. + * + * \param filename The path to the FLAC file to read. + * \param picture The address where the returned pointer will be + * stored. The \a picture object must be deleted by + * the caller using FLAC__metadata_object_delete(). + * \param type The desired picture type. Use \c -1 to mean + * "any type". + * \param mime_type The desired MIME type, e.g. "image/jpeg". The + * string will be matched exactly. Use \c NULL to + * mean "any MIME type". + * \param description The desired description. The string will be + * matched exactly. Use \c NULL to mean "any + * description". + * \param max_width The maximum width in pixels desired. Use + * \c (unsigned)(-1) to mean "any width". + * \param max_height The maximum height in pixels desired. Use + * \c (unsigned)(-1) to mean "any height". + * \param max_depth The maximum color depth in bits-per-pixel desired. + * Use \c (unsigned)(-1) to mean "any depth". + * \param max_colors The maximum number of colors desired. Use + * \c (unsigned)(-1) to mean "any number of colors". + * \assert + * \code filename != NULL \endcode + * \code picture != NULL \endcode + * \retval FLAC__bool + * \c true if a valid PICTURE block was read from \a filename, + * and \a *picture will be set to the address of the metadata + * structure. Returns \c false if there was a memory allocation + * error, a file decoder error, or the file contained no PICTURE + * block, and \a *picture will be set to \c NULL. + */ +FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__StreamMetadata **picture, FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors); + +/* \} */ + + +/** \defgroup flac_metadata_level1 FLAC/metadata.h: metadata level 1 interface + * \ingroup flac_metadata + * + * \brief + * The level 1 interface provides read-write access to FLAC file metadata and + * operates directly on the FLAC file. + * + * The general usage of this interface is: + * + * - Create an iterator using FLAC__metadata_simple_iterator_new() + * - Attach it to a file using FLAC__metadata_simple_iterator_init() and check + * the exit code. Call FLAC__metadata_simple_iterator_is_writable() to + * see if the file is writable, or only read access is allowed. + * - Use FLAC__metadata_simple_iterator_next() and + * FLAC__metadata_simple_iterator_prev() to traverse the blocks. + * This is does not read the actual blocks themselves. + * FLAC__metadata_simple_iterator_next() is relatively fast. + * FLAC__metadata_simple_iterator_prev() is slower since it needs to search + * forward from the front of the file. + * - Use FLAC__metadata_simple_iterator_get_block_type() or + * FLAC__metadata_simple_iterator_get_block() to access the actual data at + * the current iterator position. The returned object is yours to modify + * and free. + * - Use FLAC__metadata_simple_iterator_set_block() to write a modified block + * back. You must have write permission to the original file. Make sure to + * read the whole comment to FLAC__metadata_simple_iterator_set_block() + * below. + * - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks. + * Use the object creation functions from + * \link flac_metadata_object here \endlink to generate new objects. + * - Use FLAC__metadata_simple_iterator_delete_block() to remove the block + * currently referred to by the iterator, or replace it with padding. + * - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when + * finished. + * + * \note + * The FLAC file remains open the whole time between + * FLAC__metadata_simple_iterator_init() and + * FLAC__metadata_simple_iterator_delete(), so make sure you are not altering + * the file during this time. + * + * \note + * Do not modify the \a is_last, \a length, or \a type fields of returned + * FLAC__StreamMetadata objects. These are managed automatically. + * + * \note + * If any of the modification functions + * (FLAC__metadata_simple_iterator_set_block(), + * FLAC__metadata_simple_iterator_delete_block(), + * FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false, + * you should delete the iterator as it may no longer be valid. + * + * \{ + */ + +struct FLAC__Metadata_SimpleIterator; +/** The opaque structure definition for the level 1 iterator type. + * See the + * \link flac_metadata_level1 metadata level 1 module \endlink + * for a detailed description. + */ +typedef struct FLAC__Metadata_SimpleIterator FLAC__Metadata_SimpleIterator; + +/** Status type for FLAC__Metadata_SimpleIterator. + * + * The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status(). + */ +typedef enum { + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0, + /**< The iterator is in the normal OK state */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, + /**< The data passed into a function violated the function's usage criteria */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE, + /**< The iterator could not open the target file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE, + /**< The iterator could not find the FLAC signature at the start of the file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE, + /**< The iterator tried to write to a file that was not writable */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA, + /**< The iterator encountered input that does not conform to the FLAC metadata specification */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR, + /**< The iterator encountered an error while reading the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, + /**< The iterator encountered an error while seeking in the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR, + /**< The iterator encountered an error while writing the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR, + /**< The iterator encountered an error renaming the FLAC file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR, + /**< The iterator encountered an error removing the temporary file */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed */ + + FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR + /**< The caller violated an assertion or an unexpected error occurred */ + +} FLAC__Metadata_SimpleIteratorStatus; + +/** Maps a FLAC__Metadata_SimpleIteratorStatus to a C string. + * + * Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[]; + + +/** Create a new iterator instance. + * + * \retval FLAC__Metadata_SimpleIterator* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void); + +/** Free an iterator instance. Deletes the object pointed to by \a iterator. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + */ +FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator); + +/** Get the current status of the iterator. Call this after a function + * returns \c false to get the reason for the error. Also resets the status + * to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + * \retval FLAC__Metadata_SimpleIteratorStatus + * The current status of the iterator. + */ +FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator); + +/** Initialize the iterator to point to the first metadata block in the + * given FLAC file. + * + * \param iterator A pointer to an existing iterator. + * \param filename The path to the FLAC file. + * \param read_only If \c true, the FLAC file will be opened + * in read-only mode; if \c false, the FLAC + * file will be opened for edit even if no + * edits are performed. + * \param preserve_file_stats If \c true, the owner and modification + * time will be preserved even if the FLAC + * file is written to. + * \assert + * \code iterator != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c false if a memory allocation error occurs, the file can't be + * opened, or another error occurs, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats); + +/** Returns \c true if the FLAC file is writable. If \c false, calls to + * FLAC__metadata_simple_iterator_set_block() and + * FLAC__metadata_simple_iterator_insert_block_after() will fail. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + * \retval FLAC__bool + * See above. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator); + +/** Moves the iterator forward one metadata block, returning \c false if + * already at the end. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c false if already at the last metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator); + +/** Moves the iterator backward one metadata block, returning \c false if + * already at the beginning. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c false if already at the first metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator); + +/** Returns a flag telling if the current metadata block is the last. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if the current metadata block is the last in the file, + * else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the offset of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval off_t + * The offset of the metadata block at the current iterator position. + * This is the byte offset relative to the beginning of the file of + * the current metadata block's header. + */ +FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the type of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__MetadataType + * The type of the metadata block at the current iterator position. + */ +FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the length of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval unsigned + * The length of the metadata block at the current iterator position. + * The is same length as that in the + * metadata block header, + * i.e. the length of the metadata body that follows the header. + */ +FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); + +/** Get the application ID of the \c APPLICATION block at the current + * position. This avoids reading the actual block data which can save + * time for large blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \param id A pointer to a buffer of at least \c 4 bytes where + * the ID will be stored. + * \assert + * \code iterator != NULL \endcode + * \code id != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if the ID was successfully read, else \c false, in which + * case you should check FLAC__metadata_simple_iterator_status() to + * find out why. If the status is + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the + * current metadata block is not an \c APPLICATION block. Otherwise + * if the status is + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error + * occurred and the iterator can no longer be used. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id); + +/** Get the metadata block at the current position. You can modify the + * block but must use FLAC__metadata_simple_iterator_set_block() to + * write it back to the FLAC file. + * + * You must call FLAC__metadata_object_delete() on the returned object + * when you are finished with it. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__StreamMetadata* + * The current metadata block, or \c NULL if there was a memory + * allocation error. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator); + +/** Write a block back to the FLAC file. This function tries to be + * as efficient as possible; how the block is actually written is + * shown by the following: + * + * Existing block is a STREAMINFO block and the new block is a + * STREAMINFO block: the new block is written in place. Make sure + * you know what you're doing when changing the values of a + * STREAMINFO block. + * + * Existing block is a STREAMINFO block and the new block is a + * not a STREAMINFO block: this is an error since the first block + * must be a STREAMINFO block. Returns \c false without altering the + * file. + * + * Existing block is not a STREAMINFO block and the new block is a + * STREAMINFO block: this is an error since there may be only one + * STREAMINFO block. Returns \c false without altering the file. + * + * Existing block and new block are the same length: the existing + * block will be replaced by the new block, written in place. + * + * Existing block is longer than new block: if use_padding is \c true, + * the existing block will be overwritten in place with the new + * block followed by a PADDING block, if possible, to make the total + * size the same as the existing block. Remember that a padding + * block requires at least four bytes so if the difference in size + * between the new block and existing block is less than that, the + * entire file will have to be rewritten, using the new block's + * exact size. If use_padding is \c false, the entire file will be + * rewritten, replacing the existing block by the new block. + * + * Existing block is shorter than new block: if use_padding is \c true, + * the function will try and expand the new block into the following + * PADDING block, if it exists and doing so won't shrink the PADDING + * block to less than 4 bytes. If there is no following PADDING + * block, or it will shrink to less than 4 bytes, or use_padding is + * \c false, the entire file is rewritten, replacing the existing block + * with the new block. Note that in this case any following PADDING + * block is preserved as is. + * + * After writing the block, the iterator will remain in the same + * place, i.e. pointing to the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block The block to set. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); + +/** This is similar to FLAC__metadata_simple_iterator_set_block() + * except that instead of writing over an existing block, it appends + * a block after the existing block. \a use_padding is again used to + * tell the function to try an expand into following padding in an + * attempt to avoid rewriting the entire file. + * + * This function will fail and return \c false if given a STREAMINFO + * block. + * + * After writing the block, the iterator will be pointing to the + * new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block The block to set. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); + +/** Deletes the block at the current position. This will cause the + * entire FLAC file to be rewritten, unless \a use_padding is \c true, + * in which case the block will be replaced by an equal-sized PADDING + * block. The iterator will be left pointing to the block before the + * one just deleted. + * + * You may not delete the STREAMINFO block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param use_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding); + +/* \} */ + + +/** \defgroup flac_metadata_level2 FLAC/metadata.h: metadata level 2 interface + * \ingroup flac_metadata + * + * \brief + * The level 2 interface provides read-write access to FLAC file metadata; + * all metadata is read into memory, operated on in memory, and then written + * to file, which is more efficient than level 1 when editing multiple blocks. + * + * Currently Ogg FLAC is supported for read only, via + * FLAC__metadata_chain_read_ogg() but a subsequent + * FLAC__metadata_chain_write() will fail. + * + * The general usage of this interface is: + * + * - Create a new chain using FLAC__metadata_chain_new(). A chain is a + * linked list of FLAC metadata blocks. + * - Read all metadata into the the chain from a FLAC file using + * FLAC__metadata_chain_read() or FLAC__metadata_chain_read_ogg() and + * check the status. + * - Optionally, consolidate the padding using + * FLAC__metadata_chain_merge_padding() or + * FLAC__metadata_chain_sort_padding(). + * - Create a new iterator using FLAC__metadata_iterator_new() + * - Initialize the iterator to point to the first element in the chain + * using FLAC__metadata_iterator_init() + * - Traverse the chain using FLAC__metadata_iterator_next and + * FLAC__metadata_iterator_prev(). + * - Get a block for reading or modification using + * FLAC__metadata_iterator_get_block(). The pointer to the object + * inside the chain is returned, so the block is yours to modify. + * Changes will be reflected in the FLAC file when you write the + * chain. You can also add and delete blocks (see functions below). + * - When done, write out the chain using FLAC__metadata_chain_write(). + * Make sure to read the whole comment to the function below. + * - Delete the chain using FLAC__metadata_chain_delete(). + * + * \note + * Even though the FLAC file is not open while the chain is being + * manipulated, you must not alter the file externally during + * this time. The chain assumes the FLAC file will not change + * between the time of FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg() + * and FLAC__metadata_chain_write(). + * + * \note + * Do not modify the is_last, length, or type fields of returned + * FLAC__StreamMetadata objects. These are managed automatically. + * + * \note + * The metadata objects returned by FLAC__metadata_iterator_get_block() + * are owned by the chain; do not FLAC__metadata_object_delete() them. + * In the same way, blocks passed to FLAC__metadata_iterator_set_block() + * become owned by the chain and they will be deleted when the chain is + * deleted. + * + * \{ + */ + +struct FLAC__Metadata_Chain; +/** The opaque structure definition for the level 2 chain type. + */ +typedef struct FLAC__Metadata_Chain FLAC__Metadata_Chain; + +struct FLAC__Metadata_Iterator; +/** The opaque structure definition for the level 2 iterator type. + */ +typedef struct FLAC__Metadata_Iterator FLAC__Metadata_Iterator; + +typedef enum { + FLAC__METADATA_CHAIN_STATUS_OK = 0, + /**< The chain is in the normal OK state */ + + FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT, + /**< The data passed into a function violated the function's usage criteria */ + + FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE, + /**< The chain could not open the target file */ + + FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE, + /**< The chain could not find the FLAC signature at the start of the file */ + + FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE, + /**< The chain tried to write to a file that was not writable */ + + FLAC__METADATA_CHAIN_STATUS_BAD_METADATA, + /**< The chain encountered input that does not conform to the FLAC metadata specification */ + + FLAC__METADATA_CHAIN_STATUS_READ_ERROR, + /**< The chain encountered an error while reading the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR, + /**< The chain encountered an error while seeking in the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR, + /**< The chain encountered an error while writing the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR, + /**< The chain encountered an error renaming the FLAC file */ + + FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR, + /**< The chain encountered an error removing the temporary file */ + + FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed */ + + FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR, + /**< The caller violated an assertion or an unexpected error occurred */ + + FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS, + /**< One or more of the required callbacks was NULL */ + + FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH, + /**< FLAC__metadata_chain_write() was called on a chain read by + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * or + * FLAC__metadata_chain_write_with_callbacks()/FLAC__metadata_chain_write_with_callbacks_and_tempfile() + * was called on a chain read by + * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Matching read/write methods must always be used. */ + + FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL + /**< FLAC__metadata_chain_write_with_callbacks() was called when the + * chain write requires a tempfile; use + * FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead. + * Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was + * called when the chain write does not require a tempfile; use + * FLAC__metadata_chain_write_with_callbacks() instead. + * Always check FLAC__metadata_chain_check_if_tempfile_needed() + * before writing via callbacks. */ + +} FLAC__Metadata_ChainStatus; + +/** Maps a FLAC__Metadata_ChainStatus to a C string. + * + * Using a FLAC__Metadata_ChainStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__Metadata_ChainStatusString[]; + +/*********** FLAC__Metadata_Chain ***********/ + +/** Create a new chain instance. + * + * \retval FLAC__Metadata_Chain* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void); + +/** Free a chain instance. Deletes the object pointed to by \a chain. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain); + +/** Get the current status of the chain. Call this after a function + * returns \c false to get the reason for the error. Also resets the + * status to FLAC__METADATA_CHAIN_STATUS_OK. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__Metadata_ChainStatus + * The current status of the chain. + */ +FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain); + +/** Read all metadata from a FLAC file into the chain. + * + * \param chain A pointer to an existing chain. + * \param filename The path to the FLAC file to read. + * \assert + * \code chain != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a filename, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename); + +/** Read all metadata from an Ogg FLAC file into the chain. + * + * \note Ogg FLAC metadata data writing is not supported yet and + * FLAC__metadata_chain_write() will fail. + * + * \param chain A pointer to an existing chain. + * \param filename The path to the Ogg FLAC file to read. + * \assert + * \code chain != NULL \endcode + * \code filename != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a filename, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename); + +/** Read all metadata from a FLAC stream into the chain via I/O callbacks. + * + * The \a handle need only be open for reading, but must be seekable. + * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * \param chain A pointer to an existing chain. + * \param handle The I/O handle of the FLAC stream to read. The + * handle will NOT be closed after the metadata is read; + * that is the duty of the caller. + * \param callbacks + * A set of callbacks to use for I/O. The mandatory + * callbacks are \a read, \a seek, and \a tell. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a handle, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Read all metadata from an Ogg FLAC stream into the chain via I/O callbacks. + * + * The \a handle need only be open for reading, but must be seekable. + * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * \note Ogg FLAC metadata data writing is not supported yet and + * FLAC__metadata_chain_write() will fail. + * + * \param chain A pointer to an existing chain. + * \param handle The I/O handle of the Ogg FLAC stream to read. The + * handle will NOT be closed after the metadata is read; + * that is the duty of the caller. + * \param callbacks + * A set of callbacks to use for I/O. The mandatory + * callbacks are \a read, \a seek, and \a tell. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if a valid list of metadata blocks was read from + * \a handle, else \c false. On failure, check the status with + * FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Checks if writing the given chain would require the use of a + * temporary file, or if it could be written in place. + * + * Under certain conditions, padding can be utilized so that writing + * edited metadata back to the FLAC file does not require rewriting the + * entire file. If rewriting is required, then a temporary workfile is + * required. When writing metadata using callbacks, you must check + * this function to know whether to call + * FLAC__metadata_chain_write_with_callbacks() or + * FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When + * writing with FLAC__metadata_chain_write(), the temporary file is + * handled internally. + * + * \param chain A pointer to an existing chain. + * \param use_padding + * Whether or not padding will be allowed to be used + * during the write. The value of \a use_padding given + * here must match the value later passed to + * FLAC__metadata_chain_write_with_callbacks() or + * FLAC__metadata_chain_write_with_callbacks_with_tempfile(). + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if writing the current chain would require a tempfile, or + * \c false if metadata can be written in place. + */ +FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding); + +/** Write all metadata out to the FLAC file. This function tries to be as + * efficient as possible; how the metadata is actually written is shown by + * the following: + * + * If the current chain is the same size as the existing metadata, the new + * data is written in place. + * + * If the current chain is longer than the existing metadata, and + * \a use_padding is \c true, and the last block is a PADDING block of + * sufficient length, the function will truncate the final padding block + * so that the overall size of the metadata is the same as the existing + * metadata, and then just rewrite the metadata. Otherwise, if not all of + * the above conditions are met, the entire FLAC file must be rewritten. + * If you want to use padding this way it is a good idea to call + * FLAC__metadata_chain_sort_padding() first so that you have the maximum + * amount of padding to work with, unless you need to preserve ordering + * of the PADDING blocks for some reason. + * + * If the current chain is shorter than the existing metadata, and + * \a use_padding is \c true, and the final block is a PADDING block, the padding + * is extended to make the overall size the same as the existing data. If + * \a use_padding is \c true and the last block is not a PADDING block, a new + * PADDING block is added to the end of the new data to make it the same + * size as the existing data (if possible, see the note to + * FLAC__metadata_simple_iterator_set_block() about the four byte limit) + * and the new data is written in place. If none of the above apply or + * \a use_padding is \c false, the entire FLAC file is rewritten. + * + * If \a preserve_file_stats is \c true, the owner and modification time will + * be preserved even if the FLAC file is written. + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(). + * + * \param chain A pointer to an existing chain. + * \param use_padding See above. + * \param preserve_file_stats See above. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats); + +/** Write all metadata out to a FLAC stream via callbacks. + * + * (See FLAC__metadata_chain_write() for the details on how padding is + * used to write metadata in place if possible.) + * + * The \a handle must be open for updating and be seekable. The + * equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b" + * for Windows). + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned + * \c false. + * + * \param chain A pointer to an existing chain. + * \param use_padding See FLAC__metadata_chain_write() + * \param handle The I/O handle of the FLAC stream to write. The + * handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param callbacks A set of callbacks to use for I/O. The mandatory + * callbacks are \a write and \a seek. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); + +/** Write all metadata out to a FLAC stream via callbacks. + * + * (See FLAC__metadata_chain_write() for the details on how padding is + * used to write metadata in place if possible.) + * + * This version of the write-with-callbacks function must be used when + * FLAC__metadata_chain_check_if_tempfile_needed() returns true. In + * this function, you must supply an I/O handle corresponding to the + * FLAC file to edit, and a temporary handle to which the new FLAC + * file will be written. It is the caller's job to move this temporary + * FLAC file on top of the original FLAC file to complete the metadata + * edit. + * + * The \a handle must be open for reading and be seekable. The + * equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" + * for Windows). + * + * The \a temp_handle must be open for writing. The + * equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb" + * for Windows). It should be an empty stream, or at least positioned + * at the start-of-file (in which case it is the caller's duty to + * truncate it on return). + * + * For this write function to be used, the chain must have been read with + * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), + * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). + * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned + * \c true. + * + * \param chain A pointer to an existing chain. + * \param use_padding See FLAC__metadata_chain_write() + * \param handle The I/O handle of the original FLAC stream to read. + * The handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param callbacks A set of callbacks to use for I/O on \a handle. + * The mandatory callbacks are \a read, \a seek, and + * \a eof. + * \param temp_handle The I/O handle of the FLAC stream to write. The + * handle will NOT be closed after the metadata is + * written; that is the duty of the caller. + * \param temp_callbacks + * A set of callbacks to use for I/O on temp_handle. + * The only mandatory callback is \a write. + * \assert + * \code chain != NULL \endcode + * \retval FLAC__bool + * \c true if the write succeeded, else \c false. On failure, + * check the status with FLAC__metadata_chain_status(). + */ +FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks); + +/** Merge adjacent PADDING blocks into a single block. + * + * \note This function does not write to the FLAC file, it only + * modifies the chain. + * + * \warning Any iterator on the current chain will become invalid after this + * call. You should delete the iterator and get a new one. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain); + +/** This function will move all PADDING blocks to the end on the metadata, + * then merge them into a single block. + * + * \note This function does not write to the FLAC file, it only + * modifies the chain. + * + * \warning Any iterator on the current chain will become invalid after this + * call. You should delete the iterator and get a new one. + * + * \param chain A pointer to an existing chain. + * \assert + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain); + + +/*********** FLAC__Metadata_Iterator ***********/ + +/** Create a new iterator instance. + * + * \retval FLAC__Metadata_Iterator* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void); + +/** Free an iterator instance. Deletes the object pointed to by \a iterator. + * + * \param iterator A pointer to an existing iterator. + * \assert + * \code iterator != NULL \endcode + */ +FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator); + +/** Initialize the iterator to point to the first metadata block in the + * given chain. + * + * \param iterator A pointer to an existing iterator. + * \param chain A pointer to an existing and initialized (read) chain. + * \assert + * \code iterator != NULL \endcode + * \code chain != NULL \endcode + */ +FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain); + +/** Moves the iterator forward one metadata block, returning \c false if + * already at the end. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if already at the last metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator); + +/** Moves the iterator backward one metadata block, returning \c false if + * already at the beginning. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if already at the first metadata block of the chain, else + * \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator); + +/** Get the type of the metadata block at the current position. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__MetadataType + * The type of the metadata block at the current iterator position. + */ +FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator); + +/** Get the metadata block at the current position. You can modify + * the block in place but must write the chain before the changes + * are reflected to the FLAC file. You do not need to call + * FLAC__metadata_iterator_set_block() to reflect the changes; + * the pointer returned by FLAC__metadata_iterator_get_block() + * points directly into the chain. + * + * \warning + * Do not call FLAC__metadata_object_delete() on the returned object; + * to delete a block use FLAC__metadata_iterator_delete_block(). + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__StreamMetadata* + * The current metadata block. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator); + +/** Set the metadata block at the current position, replacing the existing + * block. The new block passed in becomes owned by the chain and it will be + * deleted when the chain is deleted. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \code block != NULL \endcode + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/** Removes the current block from the chain. If \a replace_with_padding is + * \c true, the block will instead be replaced with a padding block of equal + * size. You can not delete the STREAMINFO block. The iterator will be + * left pointing to the block before the one just "deleted", even if + * \a replace_with_padding is \c true. + * + * \param iterator A pointer to an existing initialized iterator. + * \param replace_with_padding See above. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, + * otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding); + +/** Insert a new block before the current block. You cannot insert a block + * before the first STREAMINFO block. You cannot insert a STREAMINFO block + * as there can be only one, the one that already exists at the head when you + * read in a chain. The chain takes ownership of the new block and it will be + * deleted when the chain is deleted. The iterator will be left pointing to + * the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block to insert. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/** Insert a new block after the current block. You cannot insert a STREAMINFO + * block as there can be only one, the one that already exists at the head when + * you read in a chain. The chain takes ownership of the new block and it will + * be deleted when the chain is deleted. The iterator will be left pointing to + * the new block. + * + * \param iterator A pointer to an existing initialized iterator. + * \param block A pointer to a metadata block to insert. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_iterator_init() + * \retval FLAC__bool + * \c false if the conditions in the above description are not met, or + * a memory allocation error occurs, otherwise \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); + +/* \} */ + + +/** \defgroup flac_metadata_object FLAC/metadata.h: metadata object methods + * \ingroup flac_metadata + * + * \brief + * This module contains methods for manipulating FLAC metadata objects. + * + * Since many are variable length we have to be careful about the memory + * management. We decree that all pointers to data in the object are + * owned by the object and memory-managed by the object. + * + * Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete() + * functions to create all instances. When using the + * FLAC__metadata_object_set_*() functions to set pointers to data, set + * \a copy to \c true to have the function make it's own copy of the data, or + * to \c false to give the object ownership of your data. In the latter case + * your pointer must be freeable by free() and will be free()d when the object + * is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as + * the data pointer to a FLAC__metadata_object_set_*() function as long as + * the length argument is 0 and the \a copy argument is \c false. + * + * The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function + * will return \c NULL in the case of a memory allocation error, otherwise a new + * object. The FLAC__metadata_object_set_*() functions return \c false in the + * case of a memory allocation error. + * + * We don't have the convenience of C++ here, so note that the library relies + * on you to keep the types straight. In other words, if you pass, for + * example, a FLAC__StreamMetadata* that represents a STREAMINFO block to + * FLAC__metadata_object_application_set_data(), you will get an assertion + * failure. + * + * For convenience the FLAC__metadata_object_vorbiscomment_*() functions + * maintain a trailing NUL on each Vorbis comment entry. This is not counted + * toward the length or stored in the stream, but it can make working with plain + * comments (those that don't contain embedded-NULs in the value) easier. + * Entries passed into these functions have trailing NULs added if missing, and + * returned entries are guaranteed to have a trailing NUL. + * + * The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis + * comment entry/name/value will first validate that it complies with the Vorbis + * comment specification and return false if it does not. + * + * There is no need to recalculate the length field on metadata blocks you + * have modified. They will be calculated automatically before they are + * written back to a file. + * + * \{ + */ + + +/** Create a new metadata object instance of the given type. + * + * The object will be "empty"; i.e. values and data pointers will be \c 0, + * with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have + * the vendor string set (but zero comments). + * + * Do not pass in a value greater than or equal to + * \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're + * doing. + * + * \param type Type of object to create + * \retval FLAC__StreamMetadata* + * \c NULL if there was an error allocating memory or the type code is + * greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type); + +/** Create a copy of an existing metadata object. + * + * The copy is a "deep" copy, i.e. dynamically allocated data within the + * object is also copied. The caller takes ownership of the new block and + * is responsible for freeing it with FLAC__metadata_object_delete(). + * + * \param object Pointer to object to copy. + * \assert + * \code object != NULL \endcode + * \retval FLAC__StreamMetadata* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object); + +/** Free a metadata object. Deletes the object pointed to by \a object. + * + * The delete is a "deep" delete, i.e. dynamically allocated data within the + * object is also deleted. + * + * \param object A pointer to an existing object. + * \assert + * \code object != NULL \endcode + */ +FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object); + +/** Compares two metadata objects. + * + * The compare is "deep", i.e. dynamically allocated data within the + * object is also compared. + * + * \param block1 A pointer to an existing object. + * \param block2 A pointer to an existing object. + * \assert + * \code block1 != NULL \endcode + * \code block2 != NULL \endcode + * \retval FLAC__bool + * \c true if objects are identical, else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2); + +/** Sets the application data of an APPLICATION block. + * + * If \a copy is \c true, a copy of the data is stored; otherwise, the object + * takes ownership of the pointer. The existing data will be freed if this + * function is successful, otherwise the original data will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a data if \a copy is \c true. + * + * \param object A pointer to an existing APPLICATION object. + * \param data A pointer to the data to set. + * \param length The length of \a data in bytes. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode + * \code (data != NULL && length > 0) || + * (data == NULL && length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy); + +/** Resize the seekpoint array. + * + * If the size shrinks, elements will truncated; if it grows, new placeholder + * points will be added to the end. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param new_num_points The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) || + * (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points); + +/** Set a seekpoint in a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \param point The point to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points > point_num \endcode + */ +FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); + +/** Insert a seekpoint into a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \param point The point to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points >= point_num \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); + +/** Delete a seekpoint from a seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param point_num Index into seekpoint array to set. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code object->data.seek_table.num_points > point_num \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num); + +/** Check a seektable to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * seektable. + * + * \param object A pointer to an existing SEEKTABLE object. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if seek table is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object); + +/** Append a number of placeholder points to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param num The number of placeholder points to append. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num); + +/** Append a specific seek point template to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param sample_number The sample number of the seek point template. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number); + +/** Append specific seek point templates to the end of a seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param sample_numbers An array of sample numbers for the seek points. + * \param num The number of seek point templates to append. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num); + +/** Append a set of evenly-spaced seek point templates to the end of a + * seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param num The number of placeholder points to append. + * \param total_samples The total number of samples to be encoded; + * the seekpoints will be spaced approximately + * \a total_samples / \a num samples apart. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code total_samples > 0 \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples); + +/** Append a set of evenly-spaced seek point templates to the end of a + * seek table. + * + * \note + * As with the other ..._seektable_template_... functions, you should + * call FLAC__metadata_object_seektable_template_sort() when finished + * to make the seek table legal. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param samples The number of samples apart to space the placeholder + * points. The first point will be at sample \c 0, the + * second at sample \a samples, then 2*\a samples, and + * so on. As long as \a samples and \a total_samples + * are greater than \c 0, there will always be at least + * one seekpoint at sample \c 0. + * \param total_samples The total number of samples to be encoded; + * the seekpoints will be spaced + * \a samples samples apart. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \code samples > 0 \endcode + * \code total_samples > 0 \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *object, unsigned samples, FLAC__uint64 total_samples); + +/** Sort a seek table's seek points according to the format specification, + * removing duplicates. + * + * \param object A pointer to a seek table to be sorted. + * \param compact If \c false, behaves like FLAC__format_seektable_sort(). + * If \c true, duplicates are deleted and the seek table is + * shrunk appropriately; the number of placeholder points + * present in the seek table will be the same after the call + * as before. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact); + +/** Sets the vendor string in a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The entry to set the vendor string to. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Resize the comment array. + * + * If the size shrinks, elements will truncated; if it grows, new empty + * fields will be added to the end. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param new_num_comments The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) || + * (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments); + +/** Sets a comment in a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num Index into comment array to set. + * \param entry The entry to set the comment to. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code comment_num < object->data.vorbis_comment.num_comments \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Insert a comment in a VORBIS_COMMENT block at the given index. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num The index at which to insert the comment. The comments + * at and after \a comment_num move right one position. + * To append a comment to the end, set \a comment_num to + * \c object->data.vorbis_comment.num_comments . + * \param entry The comment to insert. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code object->data.vorbis_comment.num_comments >= comment_num \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Appends a comment to a VORBIS_COMMENT block. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The comment to insert. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); + +/** Replaces comments in a VORBIS_COMMENT block with a new one. + * + * For convenience, a trailing NUL is added to the entry if it doesn't have + * one already. + * + * Depending on the the value of \a all, either all or just the first comment + * whose field name(s) match the given entry's name will be replaced by the + * given entry. If no comments match, \a entry will simply be appended. + * + * If \a copy is \c true, a copy of the entry is stored; otherwise, the object + * takes ownership of the \c entry.entry pointer. + * + * \note If this function returns \c false, the caller still owns the + * pointer. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param entry The comment to insert. + * \param all If \c true, all comments whose field name matches + * \a entry's field name will be removed, and \a entry will + * be inserted at the position of the first matching + * comment. If \c false, only the first comment whose + * field name matches \a entry's field name will be + * replaced with \a entry. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code (entry.entry != NULL && entry.length > 0) || + * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy); + +/** Delete a comment in a VORBIS_COMMENT block at the given index. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param comment_num The index of the comment to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code object->data.vorbis_comment.num_comments > comment_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num); + +/** Creates a Vorbis comment entry from NUL-terminated name and value strings. + * + * On return, the filled-in \a entry->entry pointer will point to malloc()ed + * memory and shall be owned by the caller. For convenience the entry will + * have a terminating NUL. + * + * \param entry A pointer to a Vorbis comment entry. The entry's + * \c entry pointer should not point to allocated + * memory as it will be overwritten. + * \param field_name The field name in ASCII, \c NUL terminated. + * \param field_value The field value in UTF-8, \c NUL terminated. + * \assert + * \code entry != NULL \endcode + * \code field_name != NULL \endcode + * \code field_value != NULL \endcode + * \retval FLAC__bool + * \c false if malloc() fails, or if \a field_name or \a field_value does + * not comply with the Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value); + +/** Splits a Vorbis comment entry into NUL-terminated name and value strings. + * + * The returned pointers to name and value will be allocated by malloc() + * and shall be owned by the caller. + * + * \param entry An existing Vorbis comment entry. + * \param field_name The address of where the returned pointer to the + * field name will be stored. + * \param field_value The address of where the returned pointer to the + * field value will be stored. + * \assert + * \code (entry.entry != NULL && entry.length > 0) \endcode + * \code memchr(entry.entry, '=', entry.length) != NULL \endcode + * \code field_name != NULL \endcode + * \code field_value != NULL \endcode + * \retval FLAC__bool + * \c false if memory allocation fails or \a entry does not comply with the + * Vorbis comment specification, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value); + +/** Check if the given Vorbis comment entry's field name matches the given + * field name. + * + * \param entry An existing Vorbis comment entry. + * \param field_name The field name to check. + * \param field_name_length The length of \a field_name, not including the + * terminating \c NUL. + * \assert + * \code (entry.entry != NULL && entry.length > 0) \endcode + * \retval FLAC__bool + * \c true if the field names match, else \c false + */ +FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length); + +/** Find a Vorbis comment with the given field name. + * + * The search begins at entry number \a offset; use an offset of 0 to + * search from the beginning of the comment array. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param offset The offset into the comment array from where to start + * the search. + * \param field_name The field name of the comment to find. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \code field_name != NULL \endcode + * \retval int + * The offset in the comment array of the first comment whose field + * name matches \a field_name, or \c -1 if no match was found. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name); + +/** Remove first Vorbis comment matching the given field name. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param field_name The field name of comment to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \retval int + * \c -1 for memory allocation error, \c 0 for no matching entries, + * \c 1 for one matching entry deleted. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name); + +/** Remove all Vorbis comments matching the given field name. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param field_name The field name of comments to delete. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode + * \retval int + * \c -1 for memory allocation error, \c 0 for no matching entries, + * else the number of matching entries deleted. + */ +FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name); + +/** Create a new CUESHEET track instance. + * + * The object will be "empty"; i.e. values and data pointers will be \c 0. + * + * \retval FLAC__StreamMetadata_CueSheet_Track* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(void); + +/** Create a copy of an existing CUESHEET track object. + * + * The copy is a "deep" copy, i.e. dynamically allocated data within the + * object is also copied. The caller takes ownership of the new object and + * is responsible for freeing it with + * FLAC__metadata_object_cuesheet_track_delete(). + * + * \param object Pointer to object to copy. + * \assert + * \code object != NULL \endcode + * \retval FLAC__StreamMetadata_CueSheet_Track* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object); + +/** Delete a CUESHEET track object + * + * \param object A pointer to an existing CUESHEET track object. + * \assert + * \code object != NULL \endcode + */ +FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object); + +/** Resize a track's index point array. + * + * If the size shrinks, elements will truncated; if it grows, new blank + * indices will be added to the end. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param new_num_indices The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) || + * (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices); + +/** Insert an index point in a CUESHEET track at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param index_num The index into the track's index array at which to + * insert the index point. NOTE: this is not necessarily + * the same as the index point's \a number field. The + * indices at and after \a index_num move right one + * position. To append an index point to the end, set + * \a index_num to + * \c object->data.cue_sheet.tracks[track_num].num_indices . + * \param index The index point to insert. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index index); + +/** Insert a blank index point in a CUESHEET track at the given index. + * + * A blank index point is one in which all field values are zero. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param index_num The index into the track's index array at which to + * insert the index point. NOTE: this is not necessarily + * the same as the index point's \a number field. The + * indices at and after \a index_num move right one + * position. To append an index point to the end, set + * \a index_num to + * \c object->data.cue_sheet.tracks[track_num].num_indices . + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); + +/** Delete an index point in a CUESHEET track at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index into the track array of the track to + * modify. NOTE: this is not necessarily the same + * as the track's \a number field. + * \param index_num The index into the track's index array of the index + * to delete. NOTE: this is not necessarily the same + * as the index's \a number field. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); + +/** Resize the track array. + * + * If the size shrinks, elements will truncated; if it grows, new blank + * tracks will be added to the end. + * + * \param object A pointer to an existing CUESHEET object. + * \param new_num_tracks The desired length of the array; may be \c 0. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) || + * (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode + * \retval FLAC__bool + * \c false if memory allocation error, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks); + +/** Sets a track in a CUESHEET block. + * + * If \a copy is \c true, a copy of the track is stored; otherwise, the object + * takes ownership of the \a track pointer. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num Index into track array to set. NOTE: this is not + * necessarily the same as the track's \a number field. + * \param track The track to set the track to. You may safely pass in + * a const pointer if \a copy is \c true. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code track_num < object->data.cue_sheet.num_tracks \endcode + * \code (track->indices != NULL && track->num_indices > 0) || + * (track->indices == NULL && track->num_indices == 0) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); + +/** Insert a track in a CUESHEET block at the given index. + * + * If \a copy is \c true, a copy of the track is stored; otherwise, the object + * takes ownership of the \a track pointer. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index at which to insert the track. NOTE: this + * is not necessarily the same as the track's \a number + * field. The tracks at and after \a track_num move right + * one position. To append a track to the end, set + * \a track_num to \c object->data.cue_sheet.num_tracks . + * \param track The track to insert. You may safely pass in a const + * pointer if \a copy is \c true. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks >= track_num \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); + +/** Insert a blank track in a CUESHEET block at the given index. + * + * A blank track is one in which all field values are zero. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index at which to insert the track. NOTE: this + * is not necessarily the same as the track's \a number + * field. The tracks at and after \a track_num move right + * one position. To append a track to the end, set + * \a track_num to \c object->data.cue_sheet.num_tracks . + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks >= track_num \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num); + +/** Delete a track in a CUESHEET block at the given index. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index into the track array of the track to + * delete. NOTE: this is not necessarily the same + * as the track's \a number field. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \code object->data.cue_sheet.num_tracks > track_num \endcode + * \retval FLAC__bool + * \c false if realloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num); + +/** Check a cue sheet to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * cue sheet. + * + * \param object A pointer to an existing CUESHEET object. + * \param check_cd_da_subset If \c true, check CUESHEET against more + * stringent requirements for a CD-DA (audio) disc. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \retval FLAC__bool + * \c false if cue sheet is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation); + +/** Calculate and return the CDDB/freedb ID for a cue sheet. The function + * assumes the cue sheet corresponds to a CD; the result is undefined + * if the cuesheet's is_cd bit is not set. + * + * \param object A pointer to an existing CUESHEET object. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode + * \retval FLAC__uint32 + * The unsigned integer representation of the CDDB/freedb ID + */ +FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object); + +/** Sets the MIME type of a PICTURE block. + * + * If \a copy is \c true, a copy of the string is stored; otherwise, the object + * takes ownership of the pointer. The existing string will be freed if this + * function is successful, otherwise the original string will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a mime_type if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param mime_type A pointer to the MIME type string. The string must be + * ASCII characters 0x20-0x7e, NUL-terminated. No validation + * is done. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (mime_type != NULL) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMetadata *object, char *mime_type, FLAC__bool copy); + +/** Sets the description of a PICTURE block. + * + * If \a copy is \c true, a copy of the string is stored; otherwise, the object + * takes ownership of the pointer. The existing string will be freed if this + * function is successful, otherwise the original string will remain if \a copy + * is \c true and malloc() fails. + * + * \note It is safe to pass a const pointer to \a description if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param description A pointer to the description string. The string must be + * valid UTF-8, NUL-terminated. No validation is done. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (description != NULL) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMetadata *object, FLAC__byte *description, FLAC__bool copy); + +/** Sets the picture data of a PICTURE block. + * + * If \a copy is \c true, a copy of the data is stored; otherwise, the object + * takes ownership of the pointer. Also sets the \a data_length field of the + * metadata object to what is passed in as the \a length parameter. The + * existing data will be freed if this function is successful, otherwise the + * original data and data_length will remain if \a copy is \c true and + * malloc() fails. + * + * \note It is safe to pass a const pointer to \a data if \a copy is \c true. + * + * \param object A pointer to an existing PICTURE object. + * \param data A pointer to the data to set. + * \param length The length of \a data in bytes. + * \param copy See above. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \code (data != NULL && length > 0) || + * (data == NULL && length == 0 && copy == false) \endcode + * \retval FLAC__bool + * \c false if \a copy is \c true and malloc() fails, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, FLAC__uint32 length, FLAC__bool copy); + +/** Check a PICTURE block to see if it conforms to the FLAC specification. + * See the format specification for limits on the contents of the + * PICTURE block. + * + * \param object A pointer to existing PICTURE block to be checked. + * \param violation Address of a pointer to a string. If there is a + * violation, a pointer to a string explanation of the + * violation will be returned here. \a violation may be + * \c NULL if you don't need the returned string. Do not + * free the returned string; it will always point to static + * data. + * \assert + * \code object != NULL \endcode + * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode + * \retval FLAC__bool + * \c false if PICTURE block is illegal, else \c true. + */ +FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/ordinals.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/ordinals.h new file mode 100644 index 00000000..b1e1acfc --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/ordinals.h @@ -0,0 +1,86 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__ORDINALS_H +#define FLAC__ORDINALS_H + +#if defined(_MSC_VER) && _MSC_VER < 1600 + +/* Microsoft Visual Studio earlier than the 2010 version did not provide + * the 1999 ISO C Standard header file . + */ + +typedef __int8 FLAC__int8; +typedef unsigned __int8 FLAC__uint8; + +typedef __int16 FLAC__int16; +typedef __int32 FLAC__int32; +typedef __int64 FLAC__int64; +typedef unsigned __int16 FLAC__uint16; +typedef unsigned __int32 FLAC__uint32; +typedef unsigned __int64 FLAC__uint64; + +#else + +/* For MSVC 2010 and everything else which provides . */ + +#include + +typedef int8_t FLAC__int8; +typedef uint8_t FLAC__uint8; + +typedef int16_t FLAC__int16; +typedef int32_t FLAC__int32; +typedef int64_t FLAC__int64; +typedef uint16_t FLAC__uint16; +typedef uint32_t FLAC__uint32; +typedef uint64_t FLAC__uint64; + +#endif + +typedef int FLAC__bool; + +typedef FLAC__uint8 FLAC__byte; + + +#ifdef true +#undef true +#endif +#ifdef false +#undef false +#endif +#ifndef __cplusplus +#define true 1 +#define false 0 +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/stream_decoder.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/stream_decoder.h new file mode 100644 index 00000000..9bfdd1f5 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/stream_decoder.h @@ -0,0 +1,1560 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__STREAM_DECODER_H +#define FLAC__STREAM_DECODER_H + +#include /* for FILE */ +#include "export.h" +#include "format.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file include/FLAC/stream_decoder.h + * + * \brief + * This module contains the functions which implement the stream + * decoder. + * + * See the detailed documentation in the + * \link flac_stream_decoder stream decoder \endlink module. + */ + +/** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces + * \ingroup flac + * + * \brief + * This module describes the decoder layers provided by libFLAC. + * + * The stream decoder can be used to decode complete streams either from + * the client via callbacks, or directly from a file, depending on how + * it is initialized. When decoding via callbacks, the client provides + * callbacks for reading FLAC data and writing decoded samples, and + * handling metadata and errors. If the client also supplies seek-related + * callback, the decoder function for sample-accurate seeking within the + * FLAC input is also available. When decoding from a file, the client + * needs only supply a filename or open \c FILE* and write/metadata/error + * callbacks; the rest of the callbacks are supplied internally. For more + * info see the \link flac_stream_decoder stream decoder \endlink module. + */ + +/** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface + * \ingroup flac_decoder + * + * \brief + * This module contains the functions which implement the stream + * decoder. + * + * The stream decoder can decode native FLAC, and optionally Ogg FLAC + * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. + * + * The basic usage of this decoder is as follows: + * - The program creates an instance of a decoder using + * FLAC__stream_decoder_new(). + * - The program overrides the default settings using + * FLAC__stream_decoder_set_*() functions. + * - The program initializes the instance to validate the settings and + * prepare for decoding using + * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() + * or FLAC__stream_decoder_init_file() for native FLAC, + * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() + * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC + * - The program calls the FLAC__stream_decoder_process_*() functions + * to decode data, which subsequently calls the callbacks. + * - The program finishes the decoding with FLAC__stream_decoder_finish(), + * which flushes the input and output and resets the decoder to the + * uninitialized state. + * - The instance may be used again or deleted with + * FLAC__stream_decoder_delete(). + * + * In more detail, the program will create a new instance by calling + * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() + * functions to override the default decoder options, and call + * one of the FLAC__stream_decoder_init_*() functions. + * + * There are three initialization functions for native FLAC, one for + * setting up the decoder to decode FLAC data from the client via + * callbacks, and two for decoding directly from a FLAC file. + * + * For decoding via callbacks, use FLAC__stream_decoder_init_stream(). + * You must also supply several callbacks for handling I/O. Some (like + * seeking) are optional, depending on the capabilities of the input. + * + * For decoding directly from a file, use FLAC__stream_decoder_init_FILE() + * or FLAC__stream_decoder_init_file(). Then you must only supply an open + * \c FILE* or filename and fewer callbacks; the decoder will handle + * the other callbacks internally. + * + * There are three similarly-named init functions for decoding from Ogg + * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the + * library has been built with Ogg support. + * + * Once the decoder is initialized, your program will call one of several + * functions to start the decoding process: + * + * - FLAC__stream_decoder_process_single() - Tells the decoder to process at + * most one metadata block or audio frame and return, calling either the + * metadata callback or write callback, respectively, once. If the decoder + * loses sync it will return with only the error callback being called. + * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder + * to process the stream from the current location and stop upon reaching + * the first audio frame. The client will get one metadata, write, or error + * callback per metadata block, audio frame, or sync error, respectively. + * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder + * to process the stream from the current location until the read callback + * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or + * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata, + * write, or error callback per metadata block, audio frame, or sync error, + * respectively. + * + * When the decoder has finished decoding (normally or through an abort), + * the instance is finished by calling FLAC__stream_decoder_finish(), which + * ensures the decoder is in the correct state and frees memory. Then the + * instance may be deleted with FLAC__stream_decoder_delete() or initialized + * again to decode another stream. + * + * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. + * At any point after the stream decoder has been initialized, the client can + * call this function to seek to an exact sample within the stream. + * Subsequently, the first time the write callback is called it will be + * passed a (possibly partial) block starting at that sample. + * + * If the client cannot seek via the callback interface provided, but still + * has another way of seeking, it can flush the decoder using + * FLAC__stream_decoder_flush() and start feeding data from the new position + * through the read callback. + * + * The stream decoder also provides MD5 signature checking. If this is + * turned on before initialization, FLAC__stream_decoder_finish() will + * report when the decoded MD5 signature does not match the one stored + * in the STREAMINFO block. MD5 checking is automatically turned off + * (until the next FLAC__stream_decoder_reset()) if there is no signature + * in the STREAMINFO block or when a seek is attempted. + * + * The FLAC__stream_decoder_set_metadata_*() functions deserve special + * attention. By default, the decoder only calls the metadata_callback for + * the STREAMINFO block. These functions allow you to tell the decoder + * explicitly which blocks to parse and return via the metadata_callback + * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), + * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), + * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify + * which blocks to return. Remember that metadata blocks can potentially + * be big (for example, cover art) so filtering out the ones you don't + * use can reduce the memory requirements of the decoder. Also note the + * special forms FLAC__stream_decoder_set_metadata_respond_application(id) + * and FLAC__stream_decoder_set_metadata_ignore_application(id) for + * filtering APPLICATION blocks based on the application ID. + * + * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but + * they still can legally be filtered from the metadata_callback. + * + * \note + * The "set" functions may only be called when the decoder is in the + * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after + * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but + * before FLAC__stream_decoder_init_*(). If this is the case they will + * return \c true, otherwise \c false. + * + * \note + * FLAC__stream_decoder_finish() resets all settings to the constructor + * defaults, including the callbacks. + * + * \{ + */ + + +/** State values for a FLAC__StreamDecoder + * + * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). + */ +typedef enum { + + FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, + /**< The decoder is ready to search for metadata. */ + + FLAC__STREAM_DECODER_READ_METADATA, + /**< The decoder is ready to or is in the process of reading metadata. */ + + FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, + /**< The decoder is ready to or is in the process of searching for the + * frame sync code. + */ + + FLAC__STREAM_DECODER_READ_FRAME, + /**< The decoder is ready to or is in the process of reading a frame. */ + + FLAC__STREAM_DECODER_END_OF_STREAM, + /**< The decoder has reached the end of the stream. */ + + FLAC__STREAM_DECODER_OGG_ERROR, + /**< An error occurred in the underlying Ogg layer. */ + + FLAC__STREAM_DECODER_SEEK_ERROR, + /**< An error occurred while seeking. The decoder must be flushed + * with FLAC__stream_decoder_flush() or reset with + * FLAC__stream_decoder_reset() before decoding can continue. + */ + + FLAC__STREAM_DECODER_ABORTED, + /**< The decoder was aborted by the read callback. */ + + FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. The decoder is in an invalid + * state and can no longer be used. + */ + + FLAC__STREAM_DECODER_UNINITIALIZED + /**< The decoder is in the uninitialized state; one of the + * FLAC__stream_decoder_init_*() functions must be called before samples + * can be processed. + */ + +} FLAC__StreamDecoderState; + +/** Maps a FLAC__StreamDecoderState to a C string. + * + * Using a FLAC__StreamDecoderState as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; + + +/** Possible return values for the FLAC__stream_decoder_init_*() functions. + */ +typedef enum { + + FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, + /**< Initialization was successful. */ + + FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, + /**< The library was not compiled with support for the given container + * format. + */ + + FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, + /**< A required callback was not supplied. */ + + FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. */ + + FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, + /**< fopen() failed in FLAC__stream_decoder_init_file() or + * FLAC__stream_decoder_init_ogg_file(). */ + + FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED + /**< FLAC__stream_decoder_init_*() was called when the decoder was + * already initialized, usually because + * FLAC__stream_decoder_finish() was not called. + */ + +} FLAC__StreamDecoderInitStatus; + +/** Maps a FLAC__StreamDecoderInitStatus to a C string. + * + * Using a FLAC__StreamDecoderInitStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[]; + + +/** Return values for the FLAC__StreamDecoder read callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, + /**< The read was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, + /**< The read was attempted while at the end of the stream. Note that + * the client must only return this value when the read callback was + * called when already at the end of the stream. Otherwise, if the read + * itself moves to the end of the stream, the client should still return + * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on + * the next read callback it should return + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count + * of \c 0. + */ + + FLAC__STREAM_DECODER_READ_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + +} FLAC__StreamDecoderReadStatus; + +/** Maps a FLAC__StreamDecoderReadStatus to a C string. + * + * Using a FLAC__StreamDecoderReadStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; + + +/** Return values for the FLAC__StreamDecoder seek callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_SEEK_STATUS_OK, + /**< The seek was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamDecoderSeekStatus; + +/** Maps a FLAC__StreamDecoderSeekStatus to a C string. + * + * Using a FLAC__StreamDecoderSeekStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[]; + + +/** Return values for the FLAC__StreamDecoder tell callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_TELL_STATUS_OK, + /**< The tell was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_TELL_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + /**< Client does not support telling the position. */ + +} FLAC__StreamDecoderTellStatus; + +/** Maps a FLAC__StreamDecoderTellStatus to a C string. + * + * Using a FLAC__StreamDecoderTellStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[]; + + +/** Return values for the FLAC__StreamDecoder length callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_LENGTH_STATUS_OK, + /**< The length call was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + + FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + /**< Client does not support reporting the length. */ + +} FLAC__StreamDecoderLengthStatus; + +/** Maps a FLAC__StreamDecoderLengthStatus to a C string. + * + * Using a FLAC__StreamDecoderLengthStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[]; + + +/** Return values for the FLAC__StreamDecoder write callback. + */ +typedef enum { + + FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, + /**< The write was OK and decoding can continue. */ + + FLAC__STREAM_DECODER_WRITE_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the process call. */ + +} FLAC__StreamDecoderWriteStatus; + +/** Maps a FLAC__StreamDecoderWriteStatus to a C string. + * + * Using a FLAC__StreamDecoderWriteStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; + + +/** Possible values passed back to the FLAC__StreamDecoder error callback. + * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- + * all. The rest could be caused by bad sync (false synchronization on + * data that is not the start of a frame) or corrupted data. The error + * itself is the decoder's best guess at what happened assuming a correct + * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER + * could be caused by a correct sync on the start of a frame, but some + * data in the frame header was corrupted. Or it could be the result of + * syncing on a point the stream that looked like the starting of a frame + * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + * could be because the decoder encountered a valid frame made by a future + * version of the encoder which it cannot parse, or because of a false + * sync making it appear as though an encountered frame was generated by + * a future encoder. + */ +typedef enum { + + FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, + /**< An error in the stream caused the decoder to lose synchronization. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, + /**< The decoder encountered a corrupted frame header. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, + /**< The frame's data did not match the CRC in the footer. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + /**< The decoder encountered reserved fields in use in the stream. */ + +} FLAC__StreamDecoderErrorStatus; + +/** Maps a FLAC__StreamDecoderErrorStatus to a C string. + * + * Using a FLAC__StreamDecoderErrorStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; + + +/*********************************************************************** + * + * class FLAC__StreamDecoder + * + ***********************************************************************/ + +struct FLAC__StreamDecoderProtected; +struct FLAC__StreamDecoderPrivate; +/** The opaque structure definition for the stream decoder type. + * See the \link flac_stream_decoder stream decoder module \endlink + * for a detailed description. + */ +typedef struct { + struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ +} FLAC__StreamDecoder; + +/** Signature for the read callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs more input data. The address of the + * buffer to be filled is supplied, along with the number of bytes the + * buffer can hold. The callback may choose to supply less data and + * modify the byte count but must be careful not to overflow the buffer. + * The callback then returns a status code chosen from + * FLAC__StreamDecoderReadStatus. + * + * Here is an example of a read callback for stdio streams: + * \code + * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(*bytes > 0) { + * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); + * if(ferror(file)) + * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + * else if(*bytes == 0) + * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + * else + * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + * } + * else + * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param buffer A pointer to a location for the callee to store + * data to be decoded. + * \param bytes A pointer to the size of the buffer. On entry + * to the callback, it contains the maximum number + * of bytes that may be stored in \a buffer. The + * callee must set it to the actual number of bytes + * stored (0 in case of error or end-of-stream) before + * returning. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderReadStatus + * The callee's return status. Note that the callback should return + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if + * zero bytes were read and there is no more data to be read. + */ +typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + +/** Signature for the seek callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs to seek the input stream. The decoder + * will pass the absolute byte offset to seek to, 0 meaning the + * beginning of the stream. + * + * Here is an example of a seek callback for stdio streams: + * \code + * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(file == stdin) + * return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; + * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) + * return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + * else + * return FLAC__STREAM_DECODER_SEEK_STATUS_OK; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param absolute_byte_offset The offset from the beginning of the stream + * to seek to. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderSeekStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); + +/** Signature for the tell callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder wants to know the current position of the + * stream. The callback should return the byte offset from the + * beginning of the stream. + * + * Here is an example of a tell callback for stdio streams: + * \code + * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * off_t pos; + * if(file == stdin) + * return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; + * else if((pos = ftello(file)) < 0) + * return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; + * else { + * *absolute_byte_offset = (FLAC__uint64)pos; + * return FLAC__STREAM_DECODER_TELL_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param absolute_byte_offset A pointer to storage for the current offset + * from the beginning of the stream. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderTellStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + +/** Signature for the length callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder wants to know the total length of the stream + * in bytes. + * + * Here is an example of a length callback for stdio streams: + * \code + * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * struct stat filestats; + * + * if(file == stdin) + * return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; + * else if(fstat(fileno(file), &filestats) != 0) + * return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; + * else { + * *stream_length = (FLAC__uint64)filestats.st_size; + * return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param stream_length A pointer to storage for the length of the stream + * in bytes. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderLengthStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); + +/** Signature for the EOF callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_decoder_init*_stream(). The supplied function will be + * called when the decoder needs to know if the end of the stream has + * been reached. + * + * Here is an example of a EOF callback for stdio streams: + * FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data) + * \code + * { + * FILE *file = ((MyClientData*)client_data)->file; + * return feof(file)? true : false; + * } + * \endcode + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__bool + * \c true if the currently at the end of the stream, else \c false. + */ +typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data); + +/** Signature for the write callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called when the decoder has decoded a + * single audio frame. The decoder will pass the frame metadata as well + * as an array of pointers (one for each channel) pointing to the + * decoded audio. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param frame The description of the decoded frame. See + * FLAC__Frame. + * \param buffer An array of pointers to decoded channels of data. + * Each pointer will point to an array of signed + * samples of length \a frame->header.blocksize. + * Channels will be ordered according to the FLAC + * specification; see the documentation for the + * frame header. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + * \retval FLAC__StreamDecoderWriteStatus + * The callee's return status. + */ +typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); + +/** Signature for the metadata callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called when the decoder has decoded a + * metadata block. In a valid FLAC file there will always be one + * \c STREAMINFO block, followed by zero or more other metadata blocks. + * These will be supplied by the decoder in the same order as they + * appear in the stream and always before the first audio frame (i.e. + * write callback). The metadata block that is passed in must not be + * modified, and it doesn't live beyond the callback, so you should make + * a copy of it with FLAC__metadata_object_clone() if you will need it + * elsewhere. Since metadata blocks can potentially be large, by + * default the decoder only calls the metadata callback for the + * \c STREAMINFO block; you can instruct the decoder to pass or filter + * other blocks with FLAC__stream_decoder_set_metadata_*() calls. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param metadata The decoded metadata block. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + */ +typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); + +/** Signature for the error callback. + * + * A function pointer matching this signature must be passed to one of + * the FLAC__stream_decoder_init_*() functions. + * The supplied function will be called whenever an error occurs during + * decoding. + * + * \note In general, FLAC__StreamDecoder functions which change the + * state should not be called on the \a decoder while in the callback. + * + * \param decoder The decoder instance calling the callback. + * \param status The error encountered by the decoder. + * \param client_data The callee's client data set through + * FLAC__stream_decoder_init_*(). + */ +typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +/** Create a new stream decoder instance. The instance is created with + * default settings; see the individual FLAC__stream_decoder_set_*() + * functions for each setting's default. + * + * \retval FLAC__StreamDecoder* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void); + +/** Free a decoder instance. Deletes the object pointed to by \a decoder. + * + * \param decoder A pointer to an existing decoder. + * \assert + * \code decoder != NULL \endcode + */ +FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder); + + +/*********************************************************************** + * + * Public class method prototypes + * + ***********************************************************************/ + +/** Set the serial number for the FLAC stream within the Ogg container. + * The default behavior is to use the serial number of the first Ogg + * page. Setting a serial number here will explicitly specify which + * stream is to be decoded. + * + * \note + * This does not need to be set for native FLAC decoding. + * + * \default \c use serial number of first page + * \param decoder A decoder instance to set. + * \param serial_number See above. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long serial_number); + +/** Set the "MD5 signature checking" flag. If \c true, the decoder will + * compute the MD5 signature of the unencoded audio data while decoding + * and compare it to the signature from the STREAMINFO block, if it + * exists, during FLAC__stream_decoder_finish(). + * + * MD5 signature checking will be turned off (until the next + * FLAC__stream_decoder_reset()) if there is no signature in the + * STREAMINFO block or when a seek is attempted. + * + * Clients that do not use the MD5 check should leave this off to speed + * up decoding. + * + * \default \c false + * \param decoder A decoder instance to set. + * \param value Flag value (see above). + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value); + +/** Direct the decoder to pass on all metadata blocks of type \a type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param type See above. + * \assert + * \code decoder != NULL \endcode + * \a type is valid + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); + +/** Direct the decoder to pass on all APPLICATION metadata blocks of the + * given \a id. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param id See above. + * \assert + * \code decoder != NULL \endcode + * \code id != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); + +/** Direct the decoder to pass on all metadata blocks of any type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder); + +/** Direct the decoder to filter out all metadata blocks of type \a type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param type See above. + * \assert + * \code decoder != NULL \endcode + * \a type is valid + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); + +/** Direct the decoder to filter out all APPLICATION metadata blocks of + * the given \a id. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \param id See above. + * \assert + * \code decoder != NULL \endcode + * \code id != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); + +/** Direct the decoder to filter out all metadata blocks of any type. + * + * \default By default, only the \c STREAMINFO block is returned via the + * metadata callback. + * \param decoder A decoder instance to set. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if the decoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder); + +/** Get the current decoder state. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderState + * The current decoder state. + */ +FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder); + +/** Get the current decoder state as a C string. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval const char * + * The decoder state as a C string. Do not modify the contents. + */ +FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder); + +/** Get the "MD5 signature checking" flag. + * This is the value of the setting, not whether or not the decoder is + * currently checking the MD5 (remember, it can be turned off automatically + * by a seek). When the decoder is reset the flag will be restored to the + * value returned by this function. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * See above. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder); + +/** Get the total number of samples in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the \c STREAMINFO block. A value of \c 0 means "unknown". + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder); + +/** Get the current number of channels in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder); + +/** Get the current channel assignment in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__ChannelAssignment + * See above. + */ +FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder); + +/** Get the current sample resolution in the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder); + +/** Get the current sample rate in Hz of the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder); + +/** Get the current blocksize of the stream being decoded. + * Will only be valid after decoding has started and will contain the + * value from the most recently decoded frame header. + * + * \param decoder A decoder instance to query. + * \assert + * \code decoder != NULL \endcode + * \retval unsigned + * See above. + */ +FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder); + +/** Returns the decoder's current read position within the stream. + * The position is the byte offset from the start of the stream. + * Bytes before this position have been fully decoded. Note that + * there may still be undecoded bytes in the decoder's read FIFO. + * The returned position is correct even after a seek. + * + * \warning This function currently only works for native FLAC, + * not Ogg FLAC streams. + * + * \param decoder A decoder instance to query. + * \param position Address at which to return the desired position. + * \assert + * \code decoder != NULL \endcode + * \code position != NULL \endcode + * \retval FLAC__bool + * \c true if successful, \c false if the stream is not native FLAC, + * or there was an error from the 'tell' callback or it returned + * \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position); + +/** Initialize the decoder instance to decode native FLAC streams. + * + * This flavor of initialization sets up the decoder to decode from a + * native FLAC stream. I/O is performed via callbacks to the client. + * For decoding from a plain file via filename or open FILE*, + * FLAC__stream_decoder_init_file() and FLAC__stream_decoder_init_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param read_callback See FLAC__StreamDecoderReadCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamDecoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is not \c NULL then a + * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param tell_callback See FLAC__StreamDecoderTellCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param length_callback See FLAC__StreamDecoderLengthCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a length_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param eof_callback See FLAC__StreamDecoderEofCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a eof_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c false + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC streams. + * + * This flavor of initialization sets up the decoder to decode from a + * FLAC stream in an Ogg container. I/O is performed via callbacks to the + * client. For decoding from a plain file via filename or open FILE*, + * FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE() + * provide a simpler interface. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param read_callback See FLAC__StreamDecoderReadCallback. This + * pointer must not be \c NULL. + * \param seek_callback See FLAC__StreamDecoderSeekCallback. This + * pointer may be \c NULL if seeking is not + * supported. If \a seek_callback is not \c NULL then a + * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. + * Alternatively, a dummy seek callback that just + * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param tell_callback See FLAC__StreamDecoderTellCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a tell_callback must also be supplied. + * Alternatively, a dummy tell callback that just + * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param length_callback See FLAC__StreamDecoderLengthCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a length_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param eof_callback See FLAC__StreamDecoderEofCallback. This + * pointer may be \c NULL if not supported by the client. If + * \a seek_callback is not \c NULL then a + * \a eof_callback must also be supplied. + * Alternatively, a dummy length callback that just + * returns \c false + * may also be supplied, all though this is slightly + * less efficient for the decoder. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode native FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a + * plain native FLAC file. For non-stdio streams, you must use + * FLAC__stream_decoder_init_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param file An open FLAC file. The file should have been + * opened with mode \c "rb" and rewound. The file + * becomes owned by the decoder and should not be + * manipulated by the client while decoding. + * Unless \a file is \c stdin, it will be closed + * when FLAC__stream_decoder_finish() is called. + * Note however that seeking will not work when + * decoding from \c stdout since it is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a + * plain Ogg FLAC file. For non-stdio streams, you must use + * FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param file An open FLAC file. The file should have been + * opened with mode \c "rb" and rewound. The file + * becomes owned by the decoder and should not be + * manipulated by the client while decoding. + * Unless \a file is \c stdin, it will be closed + * when FLAC__stream_decoder_finish() is called. + * Note however that seeking will not work when + * decoding from \c stdout since it is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \code file != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( + FLAC__StreamDecoder *decoder, + FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode native FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a plain + * native FLAC file. If POSIX fopen() semantics are not sufficient, (for + * example, with Unicode filenames on Windows), you must use + * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \param decoder An uninitialized decoder instance. + * \param filename The name of the file to decode from. The file will + * be opened with fopen(). Use \c NULL to decode from + * \c stdin. Note that \c stdin is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Initialize the decoder instance to decode Ogg FLAC files. + * + * This flavor of initialization sets up the decoder to decode from a plain + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for + * example, with Unicode filenames on Windows), you must use + * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream() + * and provide callbacks for the I/O. + * + * This function should be called after FLAC__stream_decoder_new() and + * FLAC__stream_decoder_set_*() but before any of the + * FLAC__stream_decoder_process_*() functions. Will set and return the + * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA + * if initialization succeeded. + * + * \note Support for Ogg FLAC in the library is optional. If this + * library has been built without support for Ogg FLAC, this function + * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. + * + * \param decoder An uninitialized decoder instance. + * \param filename The name of the file to decode from. The file will + * be opened with fopen(). Use \c NULL to decode from + * \c stdin. Note that \c stdin is not seekable. + * \param write_callback See FLAC__StreamDecoderWriteCallback. This + * pointer must not be \c NULL. + * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This + * pointer may be \c NULL if the callback is not + * desired. + * \param error_callback See FLAC__StreamDecoderErrorCallback. This + * pointer must not be \c NULL. + * \param client_data This value will be supplied to callbacks in their + * \a client_data argument. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__StreamDecoderInitStatus + * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; + * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + */ +FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( + FLAC__StreamDecoder *decoder, + const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data +); + +/** Finish the decoding process. + * Flushes the decoding buffer, releases resources, resets the decoder + * settings to their defaults, and returns the decoder state to + * FLAC__STREAM_DECODER_UNINITIALIZED. + * + * In the event of a prematurely-terminated decode, it is not strictly + * necessary to call this immediately before FLAC__stream_decoder_delete() + * but it is good practice to match every FLAC__stream_decoder_init_*() + * with a FLAC__stream_decoder_finish(). + * + * \param decoder An uninitialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if MD5 checking is on AND a STREAMINFO block was available + * AND the MD5 signature in the STREAMINFO block was non-zero AND the + * signature does not match the one computed by the decoder; else + * \c true. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder); + +/** Flush the stream input. + * The decoder's input buffer will be cleared and the state set to + * \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. This will also turn + * off MD5 checking. + * + * \param decoder A decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false if a memory allocation + * error occurs (in which case the state will be set to + * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder); + +/** Reset the decoding process. + * The decoder's input buffer will be cleared and the state set to + * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to + * FLAC__stream_decoder_finish() except that the settings are + * preserved; there is no need to call FLAC__stream_decoder_init_*() + * before decoding again. MD5 checking will be restored to its original + * setting. + * + * If the decoder is seekable, or was initialized with + * FLAC__stream_decoder_init*_FILE() or FLAC__stream_decoder_init*_file(), + * the decoder will also attempt to seek to the beginning of the file. + * If this rewind fails, this function will return \c false. It follows + * that FLAC__stream_decoder_reset() cannot be used when decoding from + * \c stdin. + * + * If the decoder was initialized with FLAC__stream_encoder_init*_stream() + * and is not seekable (i.e. no seek callback was provided or the seek + * callback returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED), it + * is the duty of the client to start feeding data from the beginning of + * the stream on the next FLAC__stream_decoder_process() or + * FLAC__stream_decoder_process_interleaved() call. + * + * \param decoder A decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false if a memory allocation occurs + * (in which case the state will be set to + * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR) or a seek error + * occurs (the state will be unchanged). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder); + +/** Decode one metadata block or audio frame. + * This version instructs the decoder to decode a either a single metadata + * block or a single frame and stop, unless the callbacks return a fatal + * error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * As the decoder needs more input it will call the read callback. + * Depending on what was decoded, the metadata or write callback will be + * called with the decoded metadata block or audio frame. + * + * Unless there is a fatal read error or end of stream, this function + * will return once one whole frame is decoded. In other words, if the + * stream is not synchronized or points to a corrupt frame header, the + * decoder will continue to try and resync until it gets to a valid + * frame, then decode one frame, then return. If the decoder points to + * a frame whose frame CRC in the frame footer does not match the + * computed frame CRC, this function will issue a + * FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the + * error callback, and return, having decoded one complete, although + * corrupt, frame. (Such corrupted frames are sent as silence of the + * correct length to the write callback.) + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder); + +/** Decode until the end of the metadata. + * This version instructs the decoder to decode from the current position + * and continue until all the metadata has been read, or until the + * callbacks return a fatal error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * As the decoder needs more input it will call the read callback. + * As each metadata block is decoded, the metadata callback will be called + * with the decoded metadata. + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder); + +/** Decode until the end of the stream. + * This version instructs the decoder to decode from the current position + * and continue until the end of stream (the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the + * callbacks return a fatal error. + * + * As the decoder needs more input it will call the read callback. + * As each metadata block and frame is decoded, the metadata or write + * callback will be called with the decoded metadata or frame. + * + * \param decoder An initialized decoder instance. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder); + +/** Skip one audio frame. + * This version instructs the decoder to 'skip' a single frame and stop, + * unless the callbacks return a fatal error or the read callback returns + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. + * + * The decoding flow is the same as what occurs when + * FLAC__stream_decoder_process_single() is called to process an audio + * frame, except that this function does not decode the parsed data into + * PCM or call the write callback. The integrity of the frame is still + * checked the same way as in the other process functions. + * + * This function will return once one whole frame is skipped, in the + * same way that FLAC__stream_decoder_process_single() will return once + * one whole frame is decoded. + * + * This function can be used in more quickly determining FLAC frame + * boundaries when decoding of the actual data is not needed, for + * example when an application is separating a FLAC stream into frames + * for editing or storing in a container. To do this, the application + * can use FLAC__stream_decoder_skip_single_frame() to quickly advance + * to the next frame, then use + * FLAC__stream_decoder_get_decode_position() to find the new frame + * boundary. + * + * This function should only be called when the stream has advanced + * past all the metadata, otherwise it will return \c false. + * + * \param decoder An initialized decoder instance not in a metadata + * state. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c false if any fatal read, write, or memory allocation error + * occurred (meaning decoding must stop), or if the decoder + * is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or + * FLAC__STREAM_DECODER_READ_METADATA state, else \c true; for more + * information about the decoder, check the decoder state with + * FLAC__stream_decoder_get_state(). + */ +FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder); + +/** Flush the input and seek to an absolute sample. + * Decoding will resume at the given sample. Note that because of + * this, the next write callback may contain a partial block. The + * client must support seeking the input or this function will fail + * and return \c false. Furthermore, if the decoder state is + * \c FLAC__STREAM_DECODER_SEEK_ERROR, then the decoder must be flushed + * with FLAC__stream_decoder_flush() or reset with + * FLAC__stream_decoder_reset() before decoding can continue. + * + * \param decoder A decoder instance. + * \param sample The target sample number to seek to. + * \assert + * \code decoder != NULL \endcode + * \retval FLAC__bool + * \c true if successful, else \c false. + */ +FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/stream_encoder.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/stream_encoder.h new file mode 100644 index 00000000..efc213ae --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/FLAC/stream_encoder.h @@ -0,0 +1,1790 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__STREAM_ENCODER_H +#define FLAC__STREAM_ENCODER_H + +#include /* for FILE */ +#include "export.h" +#include "format.h" +#include "stream_decoder.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file include/FLAC/stream_encoder.h + * + * \brief + * This module contains the functions which implement the stream + * encoder. + * + * See the detailed documentation in the + * \link flac_stream_encoder stream encoder \endlink module. + */ + +/** \defgroup flac_encoder FLAC/ \*_encoder.h: encoder interfaces + * \ingroup flac + * + * \brief + * This module describes the encoder layers provided by libFLAC. + * + * The stream encoder can be used to encode complete streams either to the + * client via callbacks, or directly to a file, depending on how it is + * initialized. When encoding via callbacks, the client provides a write + * callback which will be called whenever FLAC data is ready to be written. + * If the client also supplies a seek callback, the encoder will also + * automatically handle the writing back of metadata discovered while + * encoding, like stream info, seek points offsets, etc. When encoding to + * a file, the client needs only supply a filename or open \c FILE* and an + * optional progress callback for periodic notification of progress; the + * write and seek callbacks are supplied internally. For more info see the + * \link flac_stream_encoder stream encoder \endlink module. + */ + +/** \defgroup flac_stream_encoder FLAC/stream_encoder.h: stream encoder interface + * \ingroup flac_encoder + * + * \brief + * This module contains the functions which implement the stream + * encoder. + * + * The stream encoder can encode to native FLAC, and optionally Ogg FLAC + * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. + * + * The basic usage of this encoder is as follows: + * - The program creates an instance of an encoder using + * FLAC__stream_encoder_new(). + * - The program overrides the default settings using + * FLAC__stream_encoder_set_*() functions. At a minimum, the following + * functions should be called: + * - FLAC__stream_encoder_set_channels() + * - FLAC__stream_encoder_set_bits_per_sample() + * - FLAC__stream_encoder_set_sample_rate() + * - FLAC__stream_encoder_set_ogg_serial_number() (if encoding to Ogg FLAC) + * - FLAC__stream_encoder_set_total_samples_estimate() (if known) + * - If the application wants to control the compression level or set its own + * metadata, then the following should also be called: + * - FLAC__stream_encoder_set_compression_level() + * - FLAC__stream_encoder_set_verify() + * - FLAC__stream_encoder_set_metadata() + * - The rest of the set functions should only be called if the client needs + * exact control over how the audio is compressed; thorough understanding + * of the FLAC format is necessary to achieve good results. + * - The program initializes the instance to validate the settings and + * prepare for encoding using + * - FLAC__stream_encoder_init_stream() or FLAC__stream_encoder_init_FILE() + * or FLAC__stream_encoder_init_file() for native FLAC + * - FLAC__stream_encoder_init_ogg_stream() or FLAC__stream_encoder_init_ogg_FILE() + * or FLAC__stream_encoder_init_ogg_file() for Ogg FLAC + * - The program calls FLAC__stream_encoder_process() or + * FLAC__stream_encoder_process_interleaved() to encode data, which + * subsequently calls the callbacks when there is encoder data ready + * to be written. + * - The program finishes the encoding with FLAC__stream_encoder_finish(), + * which causes the encoder to encode any data still in its input pipe, + * update the metadata with the final encoding statistics if output + * seeking is possible, and finally reset the encoder to the + * uninitialized state. + * - The instance may be used again or deleted with + * FLAC__stream_encoder_delete(). + * + * In more detail, the stream encoder functions similarly to the + * \link flac_stream_decoder stream decoder \endlink, but has fewer + * callbacks and more options. Typically the client will create a new + * instance by calling FLAC__stream_encoder_new(), then set the necessary + * parameters with FLAC__stream_encoder_set_*(), and initialize it by + * calling one of the FLAC__stream_encoder_init_*() functions. + * + * Unlike the decoders, the stream encoder has many options that can + * affect the speed and compression ratio. When setting these parameters + * you should have some basic knowledge of the format (see the + * user-level documentation + * or the formal description). The + * FLAC__stream_encoder_set_*() functions themselves do not validate the + * values as many are interdependent. The FLAC__stream_encoder_init_*() + * functions will do this, so make sure to pay attention to the state + * returned by FLAC__stream_encoder_init_*() to make sure that it is + * FLAC__STREAM_ENCODER_INIT_STATUS_OK. Any parameters that are not set + * before FLAC__stream_encoder_init_*() will take on the defaults from + * the constructor. + * + * There are three initialization functions for native FLAC, one for + * setting up the encoder to encode FLAC data to the client via + * callbacks, and two for encoding directly to a file. + * + * For encoding via callbacks, use FLAC__stream_encoder_init_stream(). + * You must also supply a write callback which will be called anytime + * there is raw encoded data to write. If the client can seek the output + * it is best to also supply seek and tell callbacks, as this allows the + * encoder to go back after encoding is finished to write back + * information that was collected while encoding, like seek point offsets, + * frame sizes, etc. + * + * For encoding directly to a file, use FLAC__stream_encoder_init_FILE() + * or FLAC__stream_encoder_init_file(). Then you must only supply a + * filename or open \c FILE*; the encoder will handle all the callbacks + * internally. You may also supply a progress callback for periodic + * notification of the encoding progress. + * + * There are three similarly-named init functions for encoding to Ogg + * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the + * library has been built with Ogg support. + * + * The call to FLAC__stream_encoder_init_*() currently will also immediately + * call the write callback several times, once with the \c fLaC signature, + * and once for each encoded metadata block. Note that for Ogg FLAC + * encoding you will usually get at least twice the number of callbacks than + * with native FLAC, one for the Ogg page header and one for the page body. + * + * After initializing the instance, the client may feed audio data to the + * encoder in one of two ways: + * + * - Channel separate, through FLAC__stream_encoder_process() - The client + * will pass an array of pointers to buffers, one for each channel, to + * the encoder, each of the same length. The samples need not be + * block-aligned, but each channel should have the same number of samples. + * - Channel interleaved, through + * FLAC__stream_encoder_process_interleaved() - The client will pass a single + * pointer to data that is channel-interleaved (i.e. channel0_sample0, + * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). + * Again, the samples need not be block-aligned but they must be + * sample-aligned, i.e. the first value should be channel0_sample0 and + * the last value channelN_sampleM. + * + * Note that for either process call, each sample in the buffers should be a + * signed integer, right-justified to the resolution set by + * FLAC__stream_encoder_set_bits_per_sample(). For example, if the resolution + * is 16 bits per sample, the samples should all be in the range [-32768,32767]. + * + * When the client is finished encoding data, it calls + * FLAC__stream_encoder_finish(), which causes the encoder to encode any + * data still in its input pipe, and call the metadata callback with the + * final encoding statistics. Then the instance may be deleted with + * FLAC__stream_encoder_delete() or initialized again to encode another + * stream. + * + * For programs that write their own metadata, but that do not know the + * actual metadata until after encoding, it is advantageous to instruct + * the encoder to write a PADDING block of the correct size, so that + * instead of rewriting the whole stream after encoding, the program can + * just overwrite the PADDING block. If only the maximum size of the + * metadata is known, the program can write a slightly larger padding + * block, then split it after encoding. + * + * Make sure you understand how lengths are calculated. All FLAC metadata + * blocks have a 4 byte header which contains the type and length. This + * length does not include the 4 bytes of the header. See the format page + * for the specification of metadata blocks and their lengths. + * + * \note + * If you are writing the FLAC data to a file via callbacks, make sure it + * is open for update (e.g. mode "w+" for stdio streams). This is because + * after the first encoding pass, the encoder will try to seek back to the + * beginning of the stream, to the STREAMINFO block, to write some data + * there. (If using FLAC__stream_encoder_init*_file() or + * FLAC__stream_encoder_init*_FILE(), the file is managed internally.) + * + * \note + * The "set" functions may only be called when the encoder is in the + * state FLAC__STREAM_ENCODER_UNINITIALIZED, i.e. after + * FLAC__stream_encoder_new() or FLAC__stream_encoder_finish(), but + * before FLAC__stream_encoder_init_*(). If this is the case they will + * return \c true, otherwise \c false. + * + * \note + * FLAC__stream_encoder_finish() resets all settings to the constructor + * defaults. + * + * \{ + */ + + +/** State values for a FLAC__StreamEncoder. + * + * The encoder's state can be obtained by calling FLAC__stream_encoder_get_state(). + * + * If the encoder gets into any other state besides \c FLAC__STREAM_ENCODER_OK + * or \c FLAC__STREAM_ENCODER_UNINITIALIZED, it becomes invalid for encoding and + * must be deleted with FLAC__stream_encoder_delete(). + */ +typedef enum { + + FLAC__STREAM_ENCODER_OK = 0, + /**< The encoder is in the normal OK state and samples can be processed. */ + + FLAC__STREAM_ENCODER_UNINITIALIZED, + /**< The encoder is in the uninitialized state; one of the + * FLAC__stream_encoder_init_*() functions must be called before samples + * can be processed. + */ + + FLAC__STREAM_ENCODER_OGG_ERROR, + /**< An error occurred in the underlying Ogg layer. */ + + FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR, + /**< An error occurred in the underlying verify stream decoder; + * check FLAC__stream_encoder_get_verify_decoder_state(). + */ + + FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA, + /**< The verify decoder detected a mismatch between the original + * audio signal and the decoded audio signal. + */ + + FLAC__STREAM_ENCODER_CLIENT_ERROR, + /**< One of the callbacks returned a fatal error. */ + + FLAC__STREAM_ENCODER_IO_ERROR, + /**< An I/O error occurred while opening/reading/writing a file. + * Check \c errno. + */ + + FLAC__STREAM_ENCODER_FRAMING_ERROR, + /**< An error occurred while writing the stream; usually, the + * write_callback returned an error. + */ + + FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR + /**< Memory allocation failed. */ + +} FLAC__StreamEncoderState; + +/** Maps a FLAC__StreamEncoderState to a C string. + * + * Using a FLAC__StreamEncoderState as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderStateString[]; + + +/** Possible return values for the FLAC__stream_encoder_init_*() functions. + */ +typedef enum { + + FLAC__STREAM_ENCODER_INIT_STATUS_OK = 0, + /**< Initialization was successful. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR, + /**< General failure to set up encoder; call FLAC__stream_encoder_get_state() for cause. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER, + /**< The library was not compiled with support for the given container + * format. + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS, + /**< A required callback was not supplied. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS, + /**< The encoder has an invalid setting for number of channels. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE, + /**< The encoder has an invalid setting for bits-per-sample. + * FLAC supports 4-32 bps but the reference encoder currently supports + * only up to 24 bps. + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE, + /**< The encoder has an invalid setting for the input sample rate. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE, + /**< The encoder has an invalid setting for the block size. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER, + /**< The encoder has an invalid setting for the maximum LPC order. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION, + /**< The encoder has an invalid setting for the precision of the quantized linear predictor coefficients. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER, + /**< The specified block size is less than the maximum LPC order. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE, + /**< The encoder is bound to the Subset but other settings violate it. */ + + FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA, + /**< The metadata input to the encoder is invalid, in one of the following ways: + * - FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0 + * - One of the metadata blocks contains an undefined type + * - It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal() + * - It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal() + * - It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block + */ + + FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED + /**< FLAC__stream_encoder_init_*() was called when the encoder was + * already initialized, usually because + * FLAC__stream_encoder_finish() was not called. + */ + +} FLAC__StreamEncoderInitStatus; + +/** Maps a FLAC__StreamEncoderInitStatus to a C string. + * + * Using a FLAC__StreamEncoderInitStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderInitStatusString[]; + + +/** Return values for the FLAC__StreamEncoder read callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE, + /**< The read was OK and decoding can continue. */ + + FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM, + /**< The read was attempted at the end of the stream. */ + + FLAC__STREAM_ENCODER_READ_STATUS_ABORT, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED + /**< Client does not support reading back from the output. */ + +} FLAC__StreamEncoderReadStatus; + +/** Maps a FLAC__StreamEncoderReadStatus to a C string. + * + * Using a FLAC__StreamEncoderReadStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderReadStatusString[]; + + +/** Return values for the FLAC__StreamEncoder write callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_WRITE_STATUS_OK = 0, + /**< The write was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR + /**< An unrecoverable error occurred. The encoder will return from the process call. */ + +} FLAC__StreamEncoderWriteStatus; + +/** Maps a FLAC__StreamEncoderWriteStatus to a C string. + * + * Using a FLAC__StreamEncoderWriteStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[]; + + +/** Return values for the FLAC__StreamEncoder seek callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_SEEK_STATUS_OK, + /**< The seek was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamEncoderSeekStatus; + +/** Maps a FLAC__StreamEncoderSeekStatus to a C string. + * + * Using a FLAC__StreamEncoderSeekStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[]; + + +/** Return values for the FLAC__StreamEncoder tell callback. + */ +typedef enum { + + FLAC__STREAM_ENCODER_TELL_STATUS_OK, + /**< The tell was OK and encoding can continue. */ + + FLAC__STREAM_ENCODER_TELL_STATUS_ERROR, + /**< An unrecoverable error occurred. */ + + FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ + +} FLAC__StreamEncoderTellStatus; + +/** Maps a FLAC__StreamEncoderTellStatus to a C string. + * + * Using a FLAC__StreamEncoderTellStatus as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +extern FLAC_API const char * const FLAC__StreamEncoderTellStatusString[]; + + +/*********************************************************************** + * + * class FLAC__StreamEncoder + * + ***********************************************************************/ + +struct FLAC__StreamEncoderProtected; +struct FLAC__StreamEncoderPrivate; +/** The opaque structure definition for the stream encoder type. + * See the \link flac_stream_encoder stream encoder module \endlink + * for a detailed description. + */ +typedef struct { + struct FLAC__StreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__StreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ +} FLAC__StreamEncoder; + +/** Signature for the read callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_encoder_init_ogg_stream() if seeking is supported. + * The supplied function will be called when the encoder needs to read back + * encoded data. This happens during the metadata callback, when the encoder + * has to read, modify, and rewrite the metadata (e.g. seekpoints) gathered + * while encoding. The address of the buffer to be filled is supplied, along + * with the number of bytes the buffer can hold. The callback may choose to + * supply less data and modify the byte count but must be careful not to + * overflow the buffer. The callback then returns a status code chosen from + * FLAC__StreamEncoderReadStatus. + * + * Here is an example of a read callback for stdio streams: + * \code + * FLAC__StreamEncoderReadStatus read_cb(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(*bytes > 0) { + * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); + * if(ferror(file)) + * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; + * else if(*bytes == 0) + * return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM; + * else + * return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; + * } + * else + * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param buffer A pointer to a location for the callee to store + * data to be encoded. + * \param bytes A pointer to the size of the buffer. On entry + * to the callback, it contains the maximum number + * of bytes that may be stored in \a buffer. The + * callee must set it to the actual number of bytes + * stored (0 in case of error or end-of-stream) before + * returning. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_set_client_data(). + * \retval FLAC__StreamEncoderReadStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderReadStatus (*FLAC__StreamEncoderReadCallback)(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); + +/** Signature for the write callback. + * + * A function pointer matching this signature must be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * by the encoder anytime there is raw encoded data ready to write. It may + * include metadata mixed with encoded audio frames and the data is not + * guaranteed to be aligned on frame or metadata block boundaries. + * + * The only duty of the callback is to write out the \a bytes worth of data + * in \a buffer to the current position in the output stream. The arguments + * \a samples and \a current_frame are purely informational. If \a samples + * is greater than \c 0, then \a current_frame will hold the current frame + * number that is being written; otherwise it indicates that the write + * callback is being called to write metadata. + * + * \note + * Unlike when writing to native FLAC, when writing to Ogg FLAC the + * write callback will be called twice when writing each audio + * frame; once for the page header, and once for the page body. + * When writing the page header, the \a samples argument to the + * write callback will be \c 0. + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param buffer An array of encoded data of length \a bytes. + * \param bytes The byte length of \a buffer. + * \param samples The number of samples encoded by \a buffer. + * \c 0 has a special meaning; see above. + * \param current_frame The number of the current frame being encoded. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderWriteStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderWriteStatus (*FLAC__StreamEncoderWriteCallback)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); + +/** Signature for the seek callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * when the encoder needs to seek the output stream. The encoder will pass + * the absolute byte offset to seek to, 0 meaning the beginning of the stream. + * + * Here is an example of a seek callback for stdio streams: + * \code + * FLAC__StreamEncoderSeekStatus seek_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * if(file == stdin) + * return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED; + * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) + * return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; + * else + * return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param absolute_byte_offset The offset from the beginning of the stream + * to seek to. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderSeekStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderSeekStatus (*FLAC__StreamEncoderSeekCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); + +/** Signature for the tell callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * when the encoder needs to know the current position of the output stream. + * + * \warning + * The callback must return the true current byte offset of the output to + * which the encoder is writing. If you are buffering the output, make + * sure and take this into account. If you are writing directly to a + * FILE* from your write callback, ftell() is sufficient. If you are + * writing directly to a file descriptor from your write callback, you + * can use lseek(fd, SEEK_CUR, 0). The encoder may later seek back to + * these points to rewrite metadata after encoding. + * + * Here is an example of a tell callback for stdio streams: + * \code + * FLAC__StreamEncoderTellStatus tell_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) + * { + * FILE *file = ((MyClientData*)client_data)->file; + * off_t pos; + * if(file == stdin) + * return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED; + * else if((pos = ftello(file)) < 0) + * return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR; + * else { + * *absolute_byte_offset = (FLAC__uint64)pos; + * return FLAC__STREAM_ENCODER_TELL_STATUS_OK; + * } + * } + * \endcode + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param absolute_byte_offset The address at which to store the current + * position of the output. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + * \retval FLAC__StreamEncoderTellStatus + * The callee's return status. + */ +typedef FLAC__StreamEncoderTellStatus (*FLAC__StreamEncoderTellCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); + +/** Signature for the metadata callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_stream(). The supplied function will be called + * once at the end of encoding with the populated STREAMINFO structure. This + * is so the client can seek back to the beginning of the file and write the + * STREAMINFO block with the correct statistics after encoding (like + * minimum/maximum frame size and total samples). + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param metadata The final populated STREAMINFO block. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + */ +typedef void (*FLAC__StreamEncoderMetadataCallback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); + +/** Signature for the progress callback. + * + * A function pointer matching this signature may be passed to + * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE(). + * The supplied function will be called when the encoder has finished + * writing a frame. The \c total_frames_estimate argument to the + * callback will be based on the value from + * FLAC__stream_encoder_set_total_samples_estimate(). + * + * \note In general, FLAC__StreamEncoder functions which change the + * state should not be called on the \a encoder while in the callback. + * + * \param encoder The encoder instance calling the callback. + * \param bytes_written Bytes written so far. + * \param samples_written Samples written so far. + * \param frames_written Frames written so far. + * \param total_frames_estimate The estimate of the total number of + * frames to be written. + * \param client_data The callee's client data set through + * FLAC__stream_encoder_init_*(). + */ +typedef void (*FLAC__StreamEncoderProgressCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data); + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +/** Create a new stream encoder instance. The instance is created with + * default settings; see the individual FLAC__stream_encoder_set_*() + * functions for each setting's default. + * + * \retval FLAC__StreamEncoder* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void); + +/** Free an encoder instance. Deletes the object pointed to by \a encoder. + * + * \param encoder A pointer to an existing encoder. + * \assert + * \code encoder != NULL \endcode + */ +FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder); + + +/*********************************************************************** + * + * Public class method prototypes + * + ***********************************************************************/ + +/** Set the serial number for the FLAC stream to use in the Ogg container. + * + * \note + * This does not need to be set for native FLAC encoding. + * + * \note + * It is recommended to set a serial number explicitly as the default of '0' + * may collide with other streams. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param serial_number See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long serial_number); + +/** Set the "verify" flag. If \c true, the encoder will verify it's own + * encoded output by feeding it through an internal decoder and comparing + * the original signal against the decoded signal. If a mismatch occurs, + * the process call will return \c false. Note that this will slow the + * encoding process by the extra time required for decoding and comparison. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set the Subset flag. If \c true, + * the encoder will comply with the Subset and will check the + * settings during FLAC__stream_encoder_init_*() to see if all settings + * comply. If \c false, the settings may take advantage of the full + * range that the format allows. + * + * Make sure you know what it entails before setting this to \c false. + * + * \default \c true + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set the number of channels to be encoded. + * + * \default \c 2 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the sample resolution of the input to be encoded. + * + * \warning + * Do not feed the encoder data that is wider than the value you + * set here or you will generate an invalid stream. + * + * \default \c 16 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the sample rate (in Hz) of the input to be encoded. + * + * \default \c 44100 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the compression level + * + * The compression level is roughly proportional to the amount of effort + * the encoder expends to compress the file. A higher level usually + * means more computation but higher compression. The default level is + * suitable for most applications. + * + * Currently the levels range from \c 0 (fastest, least compression) to + * \c 8 (slowest, most compression). A value larger than \c 8 will be + * treated as \c 8. + * + * This function automatically calls the following other \c _set_ + * functions with appropriate values, so the client does not need to + * unless it specifically wants to override them: + * - FLAC__stream_encoder_set_do_mid_side_stereo() + * - FLAC__stream_encoder_set_loose_mid_side_stereo() + * - FLAC__stream_encoder_set_apodization() + * - FLAC__stream_encoder_set_max_lpc_order() + * - FLAC__stream_encoder_set_qlp_coeff_precision() + * - FLAC__stream_encoder_set_do_qlp_coeff_prec_search() + * - FLAC__stream_encoder_set_do_escape_coding() + * - FLAC__stream_encoder_set_do_exhaustive_model_search() + * - FLAC__stream_encoder_set_min_residual_partition_order() + * - FLAC__stream_encoder_set_max_residual_partition_order() + * - FLAC__stream_encoder_set_rice_parameter_search_dist() + * + * The actual values set for each level are: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
leveldo mid-side stereoloose mid-side stereoapodizationmax lpc orderqlp coeff precisionqlp coeff prec searchescape codingexhaustive model searchmin residual partition ordermax residual partition orderrice parameter search dist
0 false false tukey(0.5) 0 0 false false false 0 3 0
1 true true tukey(0.5) 0 0 false false false 0 3 0
2 true false tukey(0.5) 0 0 false false false 0 3 0
3 false false tukey(0.5) 6 0 false false false 0 4 0
4 true true tukey(0.5) 8 0 false false false 0 4 0
5 true false tukey(0.5) 8 0 false false false 0 5 0
6 true false tukey(0.5);partial_tukey(2) 8 0 false false false 0 6 0
7 true false tukey(0.5);partial_tukey(2) 12 0 false false false 0 6 0
8 true false tukey(0.5);partial_tukey(2);punchout_tukey(3) 12 0 false false false 0 6 0
+ * + * \default \c 5 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the blocksize to use while encoding. + * + * The number of samples to use per frame. Use \c 0 to let the encoder + * estimate a blocksize; this is usually best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set to \c true to enable mid-side encoding on stereo input. The + * number of channels must be 2 for this to have any effect. Set to + * \c false to use only independent channel coding. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Set to \c true to enable adaptive switching between mid-side and + * left-right encoding on stereo input. Set to \c false to use + * exhaustive searching. Setting this to \c true requires + * FLAC__stream_encoder_set_do_mid_side_stereo() to also be set to + * \c true in order to have any effect. + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value Flag value (see above). + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); + +/** Sets the apodization function(s) the encoder will use when windowing + * audio data for LPC analysis. + * + * The \a specification is a plain ASCII string which specifies exactly + * which functions to use. There may be more than one (up to 32), + * separated by \c ';' characters. Some functions take one or more + * comma-separated arguments in parentheses. + * + * The available functions are \c bartlett, \c bartlett_hann, + * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, + * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, + * \c rectangle, \c triangle, \c tukey(P), \c partial_tukey(n[/ov[/P]]), + * \c punchout_tukey(n[/ov[/P]]), \c welch. + * + * For \c gauss(STDDEV), STDDEV specifies the standard deviation + * (0blocksize / (2 ^ order). + * + * Set both min and max values to \c 0 to force a single context, + * whose Rice parameter is based on the residual signal variance. + * Otherwise, set a min and max order, and the encoder will search + * all orders, using the mean of each context for its Rice parameter, + * and use the best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set the maximum partition order to search when coding the residual. + * This is used in tandem with + * FLAC__stream_encoder_set_min_residual_partition_order(). + * + * The partition order determines the context size in the residual. + * The context size will be approximately blocksize / (2 ^ order). + * + * Set both min and max values to \c 0 to force a single context, + * whose Rice parameter is based on the residual signal variance. + * Otherwise, set a min and max order, and the encoder will search + * all orders, using the mean of each context for its Rice parameter, + * and use the best. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); + +/** Deprecated. Setting this value has no effect. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value); + +/** Set an estimate of the total samples that will be encoded. + * This is merely an estimate and may be set to \c 0 if unknown. + * This value will be written to the STREAMINFO block before encoding, + * and can remove the need for the caller to rewrite the value later + * if the value is known before encoding. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value); + +/** Set the metadata blocks to be emitted to the stream before encoding. + * A value of \c NULL, \c 0 implies no metadata; otherwise, supply an + * array of pointers to metadata blocks. The array is non-const since + * the encoder may need to change the \a is_last flag inside them, and + * in some cases update seek point offsets. Otherwise, the encoder will + * not modify or free the blocks. It is up to the caller to free the + * metadata blocks after encoding finishes. + * + * \note + * The encoder stores only copies of the pointers in the \a metadata array; + * the metadata blocks themselves must survive at least until after + * FLAC__stream_encoder_finish() returns. Do not free the blocks until then. + * + * \note + * The STREAMINFO block is always written and no STREAMINFO block may + * occur in the supplied array. + * + * \note + * By default the encoder does not create a SEEKTABLE. If one is supplied + * in the \a metadata array, but the client has specified that it does not + * support seeking, then the SEEKTABLE will be written verbatim. However + * by itself this is not very useful as the client will not know the stream + * offsets for the seekpoints ahead of time. In order to get a proper + * seektable the client must support seeking. See next note. + * + * \note + * SEEKTABLE blocks are handled specially. Since you will not know + * the values for the seek point stream offsets, you should pass in + * a SEEKTABLE 'template', that is, a SEEKTABLE object with the + * required sample numbers (or placeholder points), with \c 0 for the + * \a frame_samples and \a stream_offset fields for each point. If the + * client has specified that it supports seeking by providing a seek + * callback to FLAC__stream_encoder_init_stream() or both seek AND read + * callback to FLAC__stream_encoder_init_ogg_stream() (or by using + * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE()), + * then while it is encoding the encoder will fill the stream offsets in + * for you and when encoding is finished, it will seek back and write the + * real values into the SEEKTABLE block in the stream. There are helper + * routines for manipulating seektable template blocks; see metadata.h: + * FLAC__metadata_object_seektable_template_*(). If the client does + * not support seeking, the SEEKTABLE will have inaccurate offsets which + * will slow down or remove the ability to seek in the FLAC stream. + * + * \note + * The encoder instance \b will modify the first \c SEEKTABLE block + * as it transforms the template to a valid seektable while encoding, + * but it is still up to the caller to free all metadata blocks after + * encoding. + * + * \note + * A VORBIS_COMMENT block may be supplied. The vendor string in it + * will be ignored. libFLAC will use it's own vendor string. libFLAC + * will not modify the passed-in VORBIS_COMMENT's vendor string, it + * will simply write it's own into the stream. If no VORBIS_COMMENT + * block is present in the \a metadata array, libFLAC will write an + * empty one, containing only the vendor string. + * + * \note The Ogg FLAC mapping requires that the VORBIS_COMMENT block be + * the second metadata block of the stream. The encoder already supplies + * the STREAMINFO block automatically. If \a metadata does not contain a + * VORBIS_COMMENT block, the encoder will supply that too. Otherwise, if + * \a metadata does contain a VORBIS_COMMENT block and it is not the + * first, the init function will reorder \a metadata by moving the + * VORBIS_COMMENT block to the front; the relative ordering of the other + * blocks will remain as they were. + * + * \note The Ogg FLAC mapping limits the number of metadata blocks per + * stream to \c 65535. If \a num_blocks exceeds this the function will + * return \c false. + * + * \default \c NULL, 0 + * \param encoder An encoder instance to set. + * \param metadata See above. + * \param num_blocks See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + * \c false if the encoder is already initialized, or if + * \a num_blocks > 65535 if encoding to Ogg FLAC, else \c true. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks); + +/** Get the current encoder state. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderState + * The current encoder state. + */ +FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder); + +/** Get the state of the verify stream decoder. + * Useful when the stream encoder state is + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamDecoderState + * The verify stream decoder state. + */ +FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder); + +/** Get the current encoder state as a C string. + * This version automatically resolves + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR by getting the + * verify decoder's state. + * + * \param encoder A encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval const char * + * The encoder state as a C string. Do not modify the contents. + */ +FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder); + +/** Get relevant values about the nature of a verify decoder error. + * Useful when the stream encoder state is + * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. The arguments should + * be addresses in which the stats will be returned, or NULL if value + * is not desired. + * + * \param encoder An encoder instance to query. + * \param absolute_sample The absolute sample number of the mismatch. + * \param frame_number The number of the frame in which the mismatch occurred. + * \param channel The channel in which the mismatch occurred. + * \param sample The number of the sample (relative to the frame) in + * which the mismatch occurred. + * \param expected The expected value for the sample in question. + * \param got The actual value returned by the decoder. + * \assert + * \code encoder != NULL \endcode + */ +FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got); + +/** Get the "verify" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_verify(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder); + +/** Get the frame header. + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of pointers to each channel's signal. + * \param samples The number of samples in one channel. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__stream_encoder_get_state() to see what + * went wrong. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); + +/** Submit data for encoding. + * This version allows you to supply the input data where the channels + * are interleaved into a single array (i.e. channel0_sample0, + * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). + * The samples need not be block-aligned but they must be + * sample-aligned, i.e. the first value should be channel0_sample0 + * and the last value channelN_sampleM. Each sample should be a signed + * integer, right-justified to the resolution set by + * FLAC__stream_encoder_set_bits_per_sample(). For example, if the + * resolution is 16 bits per sample, the samples should all be in the + * range [-32768,32767]. + * + * For applications where channel order is important, channels must + * follow the order as described in the + * frame header. + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of channel-interleaved data (see above). + * \param samples The number of samples in one channel, the same as for + * FLAC__stream_encoder_process(). For example, if + * encoding two channels, \c 1000 \a samples corresponds + * to a \a buffer of 2000 values. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__stream_encoder_get_state() to see what + * went wrong. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/dumb.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/dumb.h new file mode 100644 index 00000000..2789d7ee --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/dumb.h @@ -0,0 +1,687 @@ +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * dumb.h - The user header file for DUMB. / / \ \ + * | < / \_ + * Include this file in any of your files in | \/ /\ / + * which you wish to use the DUMB functions \_ / > / + * and variables. | \ / / + * | ' / + * Allegro users, you will probably want aldumb.h. \__/ + */ + +#ifndef DUMB_H +#define DUMB_H + + +#include +#include + + +#ifdef __cplusplus + extern "C" { +#endif + + +#define DUMB_MAJOR_VERSION 0 +#define DUMB_MINOR_VERSION 9 +#define DUMB_REVISION_VERSION 3 + +#define DUMB_VERSION (DUMB_MAJOR_VERSION*10000 + DUMB_MINOR_VERSION*100 + DUMB_REVISION_VERSION) + +#define DUMB_VERSION_STR "0.9.3" + +#define DUMB_NAME "DUMB v"DUMB_VERSION_STR + +#define DUMB_YEAR 2005 +#define DUMB_MONTH 8 +#define DUMB_DAY 7 + +#define DUMB_YEAR_STR2 "05" +#define DUMB_YEAR_STR4 "2005" +#define DUMB_MONTH_STR1 "8" +#define DUMB_DAY_STR1 "7" + +#if DUMB_MONTH < 10 +#define DUMB_MONTH_STR2 "0"DUMB_MONTH_STR1 +#else +#define DUMB_MONTH_STR2 DUMB_MONTH_STR1 +#endif + +#if DUMB_DAY < 10 +#define DUMB_DAY_STR2 "0"DUMB_DAY_STR1 +#else +#define DUMB_DAY_STR2 DUMB_DAY_STR1 +#endif + + +/* WARNING: The month and day were inadvertently swapped in the v0.8 release. + * Please do not compare this constant against any date in 2002. In + * any case, DUMB_VERSION is probably more useful for this purpose. + */ +#define DUMB_DATE (DUMB_YEAR*10000 + DUMB_MONTH*100 + DUMB_DAY) + +#define DUMB_DATE_STR DUMB_DAY_STR1"."DUMB_MONTH_STR1"."DUMB_YEAR_STR4 + + +#undef MIN +#undef MAX +#undef MID + +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) +#define MID(x,y,z) MAX((x), MIN((y), (z))) + +#undef ABS +#define ABS(x) (((x) >= 0) ? (x) : (-(x))) + + +#ifdef DEBUGMODE + +#ifndef ASSERT +#include +#define ASSERT(n) assert(n) +#endif +#ifndef TRACE +// it would be nice if this did actually trace ... +#define TRACE 1 ? (void)0 : (void)printf +#endif + +#else + +#ifndef ASSERT +#define ASSERT(n) +#endif +#ifndef TRACE +#define TRACE 1 ? (void)0 : (void)printf +#endif + +#endif + + +#define DUMB_ID(a,b,c,d) (((unsigned int)(a) << 24) | \ + ((unsigned int)(b) << 16) | \ + ((unsigned int)(c) << 8) | \ + ((unsigned int)(d) )) + + + +#ifndef LONG_LONG +#if defined __GNUC__ || defined __INTEL_COMPILER || defined __MWERKS__ +#define LONG_LONG long long +#elif defined _MSC_VER || defined __WATCOMC__ +#define LONG_LONG __int64 +#elif defined __sgi +#define LONG_LONG long long +#else +#error 64-bit integer type unknown +#endif +#endif + +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 301 /* GCC 3.1+ */ +#ifndef DUMB_DECLARE_DEPRECATED +#define DUMB_DECLARE_DEPRECATED +#endif +#define DUMB_DEPRECATED __attribute__((__deprecated__)) +#else +#define DUMB_DEPRECATED +#endif + + +/* Basic Sample Type. Normal range is -0x800000 to 0x7FFFFF. */ + +typedef int sample_t; + + +/* Library Clean-up Management */ + +int dumb_atexit(void (*proc)(void)); + +void dumb_exit(void); + + +/* File Input Functions */ + +typedef struct DUMBFILE_SYSTEM +{ + void *(*open)(const char *filename); + int (*skip)(void *f, long n); + int (*getc)(void *f); + long (*getnc)(char *ptr, long n, void *f); + void (*close)(void *f); +} +DUMBFILE_SYSTEM; + +typedef struct DUMBFILE DUMBFILE; + +void register_dumbfile_system(DUMBFILE_SYSTEM *dfs); + +DUMBFILE *dumbfile_open(const char *filename); +DUMBFILE *dumbfile_open_ex(void *file, DUMBFILE_SYSTEM *dfs); + +long dumbfile_pos(DUMBFILE *f); +int dumbfile_skip(DUMBFILE *f, long n); + +int dumbfile_getc(DUMBFILE *f); + +int dumbfile_igetw(DUMBFILE *f); +int dumbfile_mgetw(DUMBFILE *f); + +long dumbfile_igetl(DUMBFILE *f); +long dumbfile_mgetl(DUMBFILE *f); + +unsigned long dumbfile_cgetul(DUMBFILE *f); +signed long dumbfile_cgetsl(DUMBFILE *f); + +long dumbfile_getnc(char *ptr, long n, DUMBFILE *f); + +int dumbfile_error(DUMBFILE *f); +int dumbfile_close(DUMBFILE *f); + + +/* stdio File Input Module */ + +void dumb_register_stdfiles(void); + +DUMBFILE *dumbfile_open_stdfile(FILE *p); + + +/* Memory File Input Module */ + +DUMBFILE *dumbfile_open_memory(const char *data, long size); + + +/* DUH Management */ + +typedef struct DUH DUH; + +#define DUH_SIGNATURE DUMB_ID('D','U','H','!') + +void unload_duh(DUH *duh); + +DUH *load_duh(const char *filename); +DUH *read_duh(DUMBFILE *f); + +long duh_get_length(DUH *duh); + +const char *duh_get_tag(DUH *duh, const char *key); + + +/* Signal Rendering Functions */ + +typedef struct DUH_SIGRENDERER DUH_SIGRENDERER; + +DUH_SIGRENDERER *duh_start_sigrenderer(DUH *duh, int sig, int n_channels, long pos); + +#ifdef DUMB_DECLARE_DEPRECATED +typedef void (*DUH_SIGRENDERER_CALLBACK)(void *data, sample_t **samples, int n_channels, long length); +/* This is deprecated, but is not marked as such because GCC tends to + * complain spuriously when the typedef is used later. See comments below. + */ + +void duh_sigrenderer_set_callback( + DUH_SIGRENDERER *sigrenderer, + DUH_SIGRENDERER_CALLBACK callback, void *data +) DUMB_DEPRECATED; +/* The 'callback' argument's type has changed for const-correctness. See the + * DUH_SIGRENDERER_CALLBACK definition just above. Also note that the samples + * in the buffer are now 256 times as large; the normal range is -0x800000 to + * 0x7FFFFF. The function has been renamed partly because its functionality + * has changed slightly and partly so that its name is more meaningful. The + * new one is duh_sigrenderer_set_analyser_callback(), and the typedef for + * the function pointer has also changed, from DUH_SIGRENDERER_CALLBACK to + * DUH_SIGRENDERER_ANALYSER_CALLBACK. (If you wanted to use this callback to + * apply a DSP effect, don't worry; there is a better way of doing this. It + * is undocumented, so contact me and I shall try to help. Contact details + * are in readme.txt.) + */ + +typedef void (*DUH_SIGRENDERER_ANALYSER_CALLBACK)(void *data, const sample_t *const *samples, int n_channels, long length); +/* This is deprecated, but is not marked as such because GCC tends to + * complain spuriously when the typedef is used later. See comments below. + */ + +void duh_sigrenderer_set_analyser_callback( + DUH_SIGRENDERER *sigrenderer, + DUH_SIGRENDERER_ANALYSER_CALLBACK callback, void *data +) DUMB_DEPRECATED; +/* This is deprecated because the meaning of the 'samples' parameter in the + * callback needed to change. For stereo applications, the array used to be + * indexed with samples[channel][pos]. It is now indexed with + * samples[0][pos*2+channel]. Mono sample data are still indexed with + * samples[0][pos]. The array is still 2D because samples will probably only + * ever be interleaved in twos. In order to fix your code, adapt it to the + * new sample layout and then call + * duh_sigrenderer_set_sample_analyser_callback below instead of this + * function. + */ +#endif + +typedef void (*DUH_SIGRENDERER_SAMPLE_ANALYSER_CALLBACK)(void *data, const sample_t *const *samples, int n_channels, long length); + +void duh_sigrenderer_set_sample_analyser_callback( + DUH_SIGRENDERER *sigrenderer, + DUH_SIGRENDERER_SAMPLE_ANALYSER_CALLBACK callback, void *data +); + +int duh_sigrenderer_get_n_channels(DUH_SIGRENDERER *sigrenderer); +long duh_sigrenderer_get_position(DUH_SIGRENDERER *sigrenderer); + +void duh_sigrenderer_set_sigparam(DUH_SIGRENDERER *sigrenderer, unsigned char id, long value); + +#ifdef DUMB_DECLARE_DEPRECATED +long duh_sigrenderer_get_samples( + DUH_SIGRENDERER *sigrenderer, + float volume, float delta, + long size, sample_t **samples +) DUMB_DEPRECATED; +/* The sample format has changed, so if you were using this function, + * you should switch to duh_sigrenderer_generate_samples() and change + * how you interpret the samples array. See the comments for + * duh_sigrenderer_set_analyser_callback(). + */ +#endif + +long duh_sigrenderer_generate_samples( + DUH_SIGRENDERER *sigrenderer, + float volume, float delta, + long size, sample_t **samples +); + +void duh_sigrenderer_get_current_sample(DUH_SIGRENDERER *sigrenderer, float volume, sample_t *samples); + +void duh_end_sigrenderer(DUH_SIGRENDERER *sigrenderer); + + +/* DUH Rendering Functions */ + +long duh_render( + DUH_SIGRENDERER *sigrenderer, + int bits, int unsign, + float volume, float delta, + long size, void *sptr +); + +#ifdef DUMB_DECLARE_DEPRECATED + +long duh_render_signal( + DUH_SIGRENDERER *sigrenderer, + float volume, float delta, + long size, sample_t **samples +) DUMB_DEPRECATED; +/* Please use duh_sigrenderer_generate_samples(), and see the + * comments for the deprecated duh_sigrenderer_get_samples() too. + */ + +typedef DUH_SIGRENDERER DUH_RENDERER DUMB_DEPRECATED; +/* Please use DUH_SIGRENDERER instead of DUH_RENDERER. */ + +DUH_SIGRENDERER *duh_start_renderer(DUH *duh, int n_channels, long pos) DUMB_DEPRECATED; +/* Please use duh_start_sigrenderer() instead. Pass 0 for 'sig'. */ + +int duh_renderer_get_n_channels(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; +long duh_renderer_get_position(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; +/* Please use the duh_sigrenderer_*() equivalents of these two functions. */ + +void duh_end_renderer(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; +/* Please use duh_end_sigrenderer() instead. */ + +DUH_SIGRENDERER *duh_renderer_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer) DUMB_DEPRECATED; +DUH_SIGRENDERER *duh_renderer_get_sigrenderer(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; +DUH_SIGRENDERER *duh_renderer_decompose_to_sigrenderer(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; +/* These functions have become no-ops that just return the parameter. + * So, for instance, replace + * duh_renderer_encapsulate_sigrenderer(my_sigrenderer) + * with + * my_sigrenderer + */ + +#endif + + +/* Impulse Tracker Support */ + +extern int dumb_it_max_to_mix; + +typedef struct DUMB_IT_SIGDATA DUMB_IT_SIGDATA; +typedef struct DUMB_IT_SIGRENDERER DUMB_IT_SIGRENDERER; + +DUMB_IT_SIGDATA *duh_get_it_sigdata(DUH *duh); +DUH_SIGRENDERER *duh_encapsulate_it_sigrenderer(DUMB_IT_SIGRENDERER *it_sigrenderer, int n_channels, long pos); +DUMB_IT_SIGRENDERER *duh_get_it_sigrenderer(DUH_SIGRENDERER *sigrenderer); + +DUH_SIGRENDERER *dumb_it_start_at_order(DUH *duh, int n_channels, int startorder); + +void dumb_it_set_loop_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data), void *data); +void dumb_it_set_xm_speed_zero_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data), void *data); +void dumb_it_set_midi_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data, int channel, unsigned char midi_byte), void *data); + +int dumb_it_callback_terminate(void *data); +int dumb_it_callback_midi_block(void *data, int channel, unsigned char midi_byte); + +DUH *dumb_load_it(const char *filename); +DUH *dumb_load_xm(const char *filename); +DUH *dumb_load_s3m(const char *filename); +DUH *dumb_load_mod(const char *filename); + +DUH *dumb_read_it(DUMBFILE *f); +DUH *dumb_read_xm(DUMBFILE *f); +DUH *dumb_read_s3m(DUMBFILE *f); +DUH *dumb_read_mod(DUMBFILE *f); + +DUH *dumb_load_it_quick(const char *filename); +DUH *dumb_load_xm_quick(const char *filename); +DUH *dumb_load_s3m_quick(const char *filename); +DUH *dumb_load_mod_quick(const char *filename); + +DUH *dumb_read_it_quick(DUMBFILE *f); +DUH *dumb_read_xm_quick(DUMBFILE *f); +DUH *dumb_read_s3m_quick(DUMBFILE *f); +DUH *dumb_read_mod_quick(DUMBFILE *f); + +long dumb_it_build_checkpoints(DUMB_IT_SIGDATA *sigdata); +void dumb_it_do_initial_runthrough(DUH *duh); + +const unsigned char *dumb_it_sd_get_song_message(DUMB_IT_SIGDATA *sd); + +int dumb_it_sd_get_n_orders(DUMB_IT_SIGDATA *sd); +int dumb_it_sd_get_n_samples(DUMB_IT_SIGDATA *sd); +int dumb_it_sd_get_n_instruments(DUMB_IT_SIGDATA *sd); + +const unsigned char *dumb_it_sd_get_sample_name(DUMB_IT_SIGDATA *sd, int i); +const unsigned char *dumb_it_sd_get_sample_filename(DUMB_IT_SIGDATA *sd, int i); +const unsigned char *dumb_it_sd_get_instrument_name(DUMB_IT_SIGDATA *sd, int i); +const unsigned char *dumb_it_sd_get_instrument_filename(DUMB_IT_SIGDATA *sd, int i); + +int dumb_it_sd_get_initial_global_volume(DUMB_IT_SIGDATA *sd); +void dumb_it_sd_set_initial_global_volume(DUMB_IT_SIGDATA *sd, int gv); + +int dumb_it_sd_get_mixing_volume(DUMB_IT_SIGDATA *sd); +void dumb_it_sd_set_mixing_volume(DUMB_IT_SIGDATA *sd, int mv); + +int dumb_it_sd_get_initial_speed(DUMB_IT_SIGDATA *sd); +void dumb_it_sd_set_initial_speed(DUMB_IT_SIGDATA *sd, int speed); + +int dumb_it_sd_get_initial_tempo(DUMB_IT_SIGDATA *sd); +void dumb_it_sd_set_initial_tempo(DUMB_IT_SIGDATA *sd, int tempo); + +int dumb_it_sd_get_initial_channel_volume(DUMB_IT_SIGDATA *sd, int channel); +void dumb_it_sd_set_initial_channel_volume(DUMB_IT_SIGDATA *sd, int channel, int volume); + +int dumb_it_sr_get_current_order(DUMB_IT_SIGRENDERER *sr); +int dumb_it_sr_get_current_row(DUMB_IT_SIGRENDERER *sr); + +int dumb_it_sr_get_global_volume(DUMB_IT_SIGRENDERER *sr); +void dumb_it_sr_set_global_volume(DUMB_IT_SIGRENDERER *sr, int gv); + +int dumb_it_sr_get_tempo(DUMB_IT_SIGRENDERER *sr); +void dumb_it_sr_set_tempo(DUMB_IT_SIGRENDERER *sr, int tempo); + +int dumb_it_sr_get_speed(DUMB_IT_SIGRENDERER *sr); +void dumb_it_sr_set_speed(DUMB_IT_SIGRENDERER *sr, int speed); + +#define DUMB_IT_N_CHANNELS 64 +#define DUMB_IT_N_NNA_CHANNELS 192 +#define DUMB_IT_TOTAL_CHANNELS (DUMB_IT_N_CHANNELS + DUMB_IT_N_NNA_CHANNELS) + +/* Channels passed to any of these functions are 0-based */ +int dumb_it_sr_get_channel_volume(DUMB_IT_SIGRENDERER *sr, int channel); +void dumb_it_sr_set_channel_volume(DUMB_IT_SIGRENDERER *sr, int channel, int volume); + +int dumb_it_sr_get_channel_muted(DUMB_IT_SIGRENDERER *sr, int channel); +void dumb_it_sr_set_channel_muted(DUMB_IT_SIGRENDERER *sr, int channel, int muted); + +typedef struct DUMB_IT_CHANNEL_STATE DUMB_IT_CHANNEL_STATE; + +struct DUMB_IT_CHANNEL_STATE +{ + int channel; /* 0-based; meaningful for NNA channels */ + int sample; /* 1-based; 0 if nothing playing, then other fields undef */ + int freq; /* in Hz */ + float volume; /* 1.0 maximum; affected by ALL factors, inc. mixing vol */ + unsigned char pan; /* 0-64, 100 for surround */ + signed char subpan; /* use (pan + subpan/256.0f) or ((pan<<8)+subpan) */ + unsigned char filter_cutoff; /* 0-127 cutoff=127 AND resonance=0 */ + unsigned char filter_subcutoff; /* 0-255 -> no filters (subcutoff */ + unsigned char filter_resonance; /* 0-127 always 0 in this case) */ + /* subcutoff only changes from zero if filter envelopes are in use. The + * calculation (filter_cutoff + filter_subcutoff/256.0f) gives a more + * accurate filter cutoff measurement as a float. It would often be more + * useful to use a scaled int such as ((cutoff<<8) + subcutoff). + */ +}; + +/* Values of 64 or more will access NNA channels here. */ +void dumb_it_sr_get_channel_state(DUMB_IT_SIGRENDERER *sr, int channel, DUMB_IT_CHANNEL_STATE *state); + + +/* Signal Design Helper Values */ + +/* Use pow(DUMB_SEMITONE_BASE, n) to get the 'delta' value to transpose up by + * n semitones. To transpose down, use negative n. + */ +#define DUMB_SEMITONE_BASE 1.059463094359295309843105314939748495817 + +/* Use pow(DUMB_QUARTERTONE_BASE, n) to get the 'delta' value to transpose up + * by n quartertones. To transpose down, use negative n. + */ +#define DUMB_QUARTERTONE_BASE 1.029302236643492074463779317738953977823 + +/* Use pow(DUMB_PITCH_BASE, n) to get the 'delta' value to transpose up by n + * units. In this case, 256 units represent one semitone; 3072 units + * represent one octave. These units are used by the sequence signal (SEQU). + */ +#define DUMB_PITCH_BASE 1.000225659305069791926712241547647863626 + + +/* Signal Design Function Types */ + +typedef void sigdata_t; +typedef void sigrenderer_t; + +typedef sigdata_t *(*DUH_LOAD_SIGDATA)(DUH *duh, DUMBFILE *file); + +typedef sigrenderer_t *(*DUH_START_SIGRENDERER)( + DUH *duh, + sigdata_t *sigdata, + int n_channels, + long pos +); + +typedef void (*DUH_SIGRENDERER_SET_SIGPARAM)( + sigrenderer_t *sigrenderer, + unsigned char id, long value +); + +typedef long (*DUH_SIGRENDERER_GENERATE_SAMPLES)( + sigrenderer_t *sigrenderer, + float volume, float delta, + long size, sample_t **samples +); + +typedef void (*DUH_SIGRENDERER_GET_CURRENT_SAMPLE)( + sigrenderer_t *sigrenderer, + float volume, + sample_t *samples +); + +typedef void (*DUH_END_SIGRENDERER)(sigrenderer_t *sigrenderer); + +typedef void (*DUH_UNLOAD_SIGDATA)(sigdata_t *sigdata); + + +/* Signal Design Function Registration */ + +typedef struct DUH_SIGTYPE_DESC +{ + long type; + DUH_LOAD_SIGDATA load_sigdata; + DUH_START_SIGRENDERER start_sigrenderer; + DUH_SIGRENDERER_SET_SIGPARAM sigrenderer_set_sigparam; + DUH_SIGRENDERER_GENERATE_SAMPLES sigrenderer_generate_samples; + DUH_SIGRENDERER_GET_CURRENT_SAMPLE sigrenderer_get_current_sample; + DUH_END_SIGRENDERER end_sigrenderer; + DUH_UNLOAD_SIGDATA unload_sigdata; +} +DUH_SIGTYPE_DESC; + +void dumb_register_sigtype(DUH_SIGTYPE_DESC *desc); + + +// Decide where to put these functions; new heading? + +sigdata_t *duh_get_raw_sigdata(DUH *duh, int sig, long type); + +DUH_SIGRENDERER *duh_encapsulate_raw_sigrenderer(sigrenderer_t *vsigrenderer, DUH_SIGTYPE_DESC *desc, int n_channels, long pos); +sigrenderer_t *duh_get_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type); + + +/* Standard Signal Types */ + +//void dumb_register_sigtype_sample(void); + + +/* Sample Buffer Allocation Helpers */ + +#ifdef DUMB_DECLARE_DEPRECATED +sample_t **create_sample_buffer(int n_channels, long length) DUMB_DEPRECATED; +/* DUMB has been changed to interleave stereo samples. Use + * allocate_sample_buffer() instead, and see the comments for + * duh_sigrenderer_set_analyser_callback(). + */ +#endif +sample_t **allocate_sample_buffer(int n_channels, long length); +void destroy_sample_buffer(sample_t **samples); + + +/* Silencing Helper */ + +void dumb_silence(sample_t *samples, long length); + + +/* Click Removal Helpers */ + +typedef struct DUMB_CLICK_REMOVER DUMB_CLICK_REMOVER; + +DUMB_CLICK_REMOVER *dumb_create_click_remover(void); +void dumb_record_click(DUMB_CLICK_REMOVER *cr, long pos, sample_t step); +void dumb_remove_clicks(DUMB_CLICK_REMOVER *cr, sample_t *samples, long length, int step, float halflife); +sample_t dumb_click_remover_get_offset(DUMB_CLICK_REMOVER *cr); +void dumb_destroy_click_remover(DUMB_CLICK_REMOVER *cr); + +DUMB_CLICK_REMOVER **dumb_create_click_remover_array(int n); +void dumb_record_click_array(int n, DUMB_CLICK_REMOVER **cr, long pos, sample_t *step); +void dumb_record_click_negative_array(int n, DUMB_CLICK_REMOVER **cr, long pos, sample_t *step); +void dumb_remove_clicks_array(int n, DUMB_CLICK_REMOVER **cr, sample_t **samples, long length, float halflife); +void dumb_click_remover_get_offset_array(int n, DUMB_CLICK_REMOVER **cr, sample_t *offset); +void dumb_destroy_click_remover_array(int n, DUMB_CLICK_REMOVER **cr); + + +/* Resampling Helpers */ + +#define DUMB_RQ_ALIASING 0 +#define DUMB_RQ_LINEAR 1 +#define DUMB_RQ_CUBIC 2 +#define DUMB_RQ_N_LEVELS 3 +extern int dumb_resampling_quality; + +typedef struct DUMB_RESAMPLER DUMB_RESAMPLER; + +typedef void (*DUMB_RESAMPLE_PICKUP)(DUMB_RESAMPLER *resampler, void *data); + +struct DUMB_RESAMPLER +{ + void *src; + long pos; + int subpos; + long start, end; + int dir; + DUMB_RESAMPLE_PICKUP pickup; + void *pickup_data; + int min_quality; + int max_quality; + /* Everything below this point is internal: do not use. */ + union { + sample_t x24[3*2]; + short x16[3*2]; + signed char x8[3*2]; + } x; + int overshot; +}; + +void dumb_reset_resampler(DUMB_RESAMPLER *resampler, sample_t *src, int src_channels, long pos, long start, long end); +DUMB_RESAMPLER *dumb_start_resampler(sample_t *src, int src_channels, long pos, long start, long end); +long dumb_resample_1_1(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume, float delta); +long dumb_resample_1_2(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +long dumb_resample_2_1(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +long dumb_resample_2_2(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +void dumb_resample_get_current_sample_1_1(DUMB_RESAMPLER *resampler, float volume, sample_t *dst); +void dumb_resample_get_current_sample_1_2(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_resample_get_current_sample_2_1(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_resample_get_current_sample_2_2(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_end_resampler(DUMB_RESAMPLER *resampler); + +void dumb_reset_resampler_16(DUMB_RESAMPLER *resampler, short *src, int src_channels, long pos, long start, long end); +DUMB_RESAMPLER *dumb_start_resampler_16(short *src, int src_channels, long pos, long start, long end); +long dumb_resample_16_1_1(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume, float delta); +long dumb_resample_16_1_2(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +long dumb_resample_16_2_1(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +long dumb_resample_16_2_2(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +void dumb_resample_get_current_sample_16_1_1(DUMB_RESAMPLER *resampler, float volume, sample_t *dst); +void dumb_resample_get_current_sample_16_1_2(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_resample_get_current_sample_16_2_1(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_resample_get_current_sample_16_2_2(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_end_resampler_16(DUMB_RESAMPLER *resampler); + +void dumb_reset_resampler_8(DUMB_RESAMPLER *resampler, signed char *src, int src_channels, long pos, long start, long end); +DUMB_RESAMPLER *dumb_start_resampler_8(signed char *src, int src_channels, long pos, long start, long end); +long dumb_resample_8_1_1(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume, float delta); +long dumb_resample_8_1_2(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +long dumb_resample_8_2_1(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +long dumb_resample_8_2_2(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +void dumb_resample_get_current_sample_8_1_1(DUMB_RESAMPLER *resampler, float volume, sample_t *dst); +void dumb_resample_get_current_sample_8_1_2(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_resample_get_current_sample_8_2_1(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_resample_get_current_sample_8_2_2(DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_end_resampler_8(DUMB_RESAMPLER *resampler); + +void dumb_reset_resampler_n(int n, DUMB_RESAMPLER *resampler, void *src, int src_channels, long pos, long start, long end); +DUMB_RESAMPLER *dumb_start_resampler_n(int n, void *src, int src_channels, long pos, long start, long end); +long dumb_resample_n_1_1(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume, float delta); +long dumb_resample_n_1_2(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +long dumb_resample_n_2_1(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +long dumb_resample_n_2_2(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta); +void dumb_resample_get_current_sample_n_1_1(int n, DUMB_RESAMPLER *resampler, float volume, sample_t *dst); +void dumb_resample_get_current_sample_n_1_2(int n, DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_resample_get_current_sample_n_2_1(int n, DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_resample_get_current_sample_n_2_2(int n, DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst); +void dumb_end_resampler_n(int n, DUMB_RESAMPLER *resampler); + + +/* DUH Construction */ + +DUH *make_duh( + long length, + int n_tags, + const char *const tag[][2], + int n_signals, + DUH_SIGTYPE_DESC *desc[], + sigdata_t *sigdata[] +); + +void duh_set_length(DUH *duh, long length); + + +#ifdef __cplusplus + } +#endif + + +#endif /* DUMB_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftconfig.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftconfig.h new file mode 100644 index 00000000..22d70fd3 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftconfig.h @@ -0,0 +1,450 @@ +/***************************************************************************/ +/* */ +/* ftconfig.h */ +/* */ +/* ANSI-specific configuration file (specification only). */ +/* */ +/* Copyright 1996-2004, 2006-2008, 2010-2011, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This header file contains a number of macro definitions that are used */ + /* by the rest of the engine. Most of the macros here are automatically */ + /* determined at compile time, and you should not need to change it to */ + /* port FreeType, except to compile the library with a non-ANSI */ + /* compiler. */ + /* */ + /* Note however that if some specific modifications are needed, we */ + /* advise you to place a modified copy in your build directory. */ + /* */ + /* The build directory is usually `builds/', and contains */ + /* system-specific files that are always included first when building */ + /* the library. */ + /* */ + /* This ANSI version should stay in `include/config/'. */ + /* */ + /*************************************************************************/ + +#ifndef __FTCONFIG_H__ +#define __FTCONFIG_H__ + +#include +#include FT_CONFIG_OPTIONS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ + /* */ + /* These macros can be toggled to suit a specific system. The current */ + /* ones are defaults used to compile FreeType in an ANSI C environment */ + /* (16bit compilers are also supported). Copy this file to your own */ + /* `builds/' directory, and edit it to port the engine. */ + /* */ + /*************************************************************************/ + + + /* There are systems (like the Texas Instruments 'C54x) where a `char' */ + /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ + /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ + /* is probably unexpected. */ + /* */ + /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ + /* `char' type. */ + +#ifndef FT_CHAR_BIT +#define FT_CHAR_BIT CHAR_BIT +#endif + + + /* The size of an `int' type. */ +#if FT_UINT_MAX == 0xFFFFUL +#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) +#elif FT_UINT_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) +#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `int' type!" +#endif + + /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ + /* DM642) is recognized but avoided. */ +#if FT_ULONG_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `long' type!" +#endif + + + /* FT_UNUSED is a macro used to indicate that a given parameter is not */ + /* used -- this is only used to get rid of unpleasant compiler warnings */ +#ifndef FT_UNUSED +#define FT_UNUSED( arg ) ( (arg) = (arg) ) +#endif + + + /*************************************************************************/ + /* */ + /* AUTOMATIC CONFIGURATION MACROS */ + /* */ + /* These macros are computed from the ones defined above. Don't touch */ + /* their definition, unless you know precisely what you are doing. No */ + /* porter should need to mess with them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Mac support */ + /* */ + /* This is the only necessary change, so it is defined here instead */ + /* providing a new configuration file. */ + /* */ +#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) + /* no Carbon frameworks for 64bit 10.4.x */ + /* AvailabilityMacros.h is available since Mac OS X 10.2, */ + /* so guess the system version by maximum errno before inclusion */ +#include +#ifdef ECANCELED /* defined since 10.2 */ +#include "AvailabilityMacros.h" +#endif +#if defined( __LP64__ ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) +#undef FT_MACINTOSH +#endif + +#elif defined( __SC__ ) || defined( __MRC__ ) + /* Classic MacOS compilers */ +#include "ConditionalMacros.h" +#if TARGET_OS_MAC +#define FT_MACINTOSH 1 +#endif + +#endif + + + /*************************************************************************/ + /* */ + /*
*/ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int16 */ + /* */ + /* */ + /* A typedef for a 16bit signed integer type. */ + /* */ + typedef signed short FT_Int16; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt16 */ + /* */ + /* */ + /* A typedef for a 16bit unsigned integer type. */ + /* */ + typedef unsigned short FT_UInt16; + + /* */ + + + /* this #if 0 ... #endif clause is for documentation purposes */ +#if 0 + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int32 */ + /* */ + /* */ + /* A typedef for a 32bit signed integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef signed XXX FT_Int32; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt32 */ + /* */ + /* A typedef for a 32bit unsigned integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef unsigned XXX FT_UInt32; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int64 */ + /* */ + /* A typedef for a 64bit signed integer type. The size depends on */ + /* the configuration. Only defined if there is real 64bit support; */ + /* otherwise, it gets emulated with a structure (if necessary). */ + /* */ + typedef signed XXX FT_Int64; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt64 */ + /* */ + /* A typedef for a 64bit unsigned integer type. The size depends on */ + /* the configuration. Only defined if there is real 64bit support; */ + /* otherwise, it gets emulated with a structure (if necessary). */ + /* */ + typedef unsigned XXX FT_UInt64; + + /* */ + +#endif + +#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) + + typedef signed int FT_Int32; + typedef unsigned int FT_UInt32; + +#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) + + typedef signed long FT_Int32; + typedef unsigned long FT_UInt32; + +#else +#error "no 32bit type found -- please check your configuration files" +#endif + + + /* look up an integer type that is at least 32 bits */ +#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) + + typedef int FT_Fast; + typedef unsigned int FT_UFast; + +#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) + + typedef long FT_Fast; + typedef unsigned long FT_UFast; + +#endif + + + /* determine whether we have a 64-bit int type for platforms without */ + /* Autoconf */ +#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) + + /* FT_LONG64 must be defined if a 64-bit type is available */ +#define FT_LONG64 +#define FT_INT64 long +#define FT_UINT64 unsigned long + + /*************************************************************************/ + /* */ + /* A 64-bit data type may create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ + /* types if __STDC__ is defined. You can however ignore this rule */ + /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 +#define FT_UINT64 unsigned __int64 + +#elif defined( __BORLANDC__ ) /* Borland C++ */ + + /* XXXX: We should probably check the value of __BORLANDC__ in order */ + /* to test the compiler version. */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 +#define FT_UINT64 unsigned __int64 + +#elif defined( __WATCOMC__ ) /* Watcom C++ */ + + /* Watcom doesn't provide 64-bit data types */ + +#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ + +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#elif defined( __GNUC__ ) + + /* GCC provides the `long long' type */ +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#endif /* _MSC_VER */ + +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ + +#ifdef FT_LONG64 + typedef FT_INT64 FT_Int64; + typedef FT_UINT64 FT_UInt64; +#endif + + +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) +#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT + + +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT + +#define FT_LOCAL( x ) static x +#define FT_LOCAL_DEF( x ) static x + +#else + +#ifdef __cplusplus +#define FT_LOCAL( x ) extern "C" x +#define FT_LOCAL_DEF( x ) extern "C" x +#else +#define FT_LOCAL( x ) extern x +#define FT_LOCAL_DEF( x ) x +#endif + +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ + +#define FT_LOCAL_ARRAY( x ) extern const x +#define FT_LOCAL_ARRAY_DEF( x ) const x + + +#ifndef FT_BASE + +#ifdef __cplusplus +#define FT_BASE( x ) extern "C" x +#else +#define FT_BASE( x ) extern x +#endif + +#endif /* !FT_BASE */ + + +#ifndef FT_BASE_DEF + +#ifdef __cplusplus +#define FT_BASE_DEF( x ) x +#else +#define FT_BASE_DEF( x ) x +#endif + +#endif /* !FT_BASE_DEF */ + + +#ifndef FT_EXPORT + +#ifdef __cplusplus +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif /* !FT_EXPORT */ + + +#ifndef FT_EXPORT_DEF + +#ifdef __cplusplus +#define FT_EXPORT_DEF( x ) extern "C" x +#else +#define FT_EXPORT_DEF( x ) extern x +#endif + +#endif /* !FT_EXPORT_DEF */ + + +#ifndef FT_EXPORT_VAR + +#ifdef __cplusplus +#define FT_EXPORT_VAR( x ) extern "C" x +#else +#define FT_EXPORT_VAR( x ) extern x +#endif + +#endif /* !FT_EXPORT_VAR */ + + /* The following macros are needed to compile the library with a */ + /* C++ compiler and with 16bit compilers. */ + /* */ + + /* This is special. Within C++, you must specify `extern "C"' for */ + /* functions which are used via function pointers, and you also */ + /* must do that for structures which contain function pointers to */ + /* assure C linkage -- it's not possible to have (local) anonymous */ + /* functions which are accessed by (global) function pointers. */ + /* */ + /* */ + /* FT_CALLBACK_DEF is used to _define_ a callback function. */ + /* */ + /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ + /* contains pointers to callback functions. */ + /* */ + /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ + /* that contains pointers to callback functions. */ + /* */ + /* */ + /* Some 16bit compilers have to redefine these macros to insert */ + /* the infamous `_cdecl' or `__fastcall' declarations. */ + /* */ +#ifndef FT_CALLBACK_DEF +#ifdef __cplusplus +#define FT_CALLBACK_DEF( x ) extern "C" x +#else +#define FT_CALLBACK_DEF( x ) static x +#endif +#endif /* FT_CALLBACK_DEF */ + +#ifndef FT_CALLBACK_TABLE +#ifdef __cplusplus +#define FT_CALLBACK_TABLE extern "C" +#define FT_CALLBACK_TABLE_DEF extern "C" +#else +#define FT_CALLBACK_TABLE extern +#define FT_CALLBACK_TABLE_DEF /* nothing */ +#endif +#endif /* FT_CALLBACK_TABLE */ + + +FT_END_HEADER + + +#endif /* __FTCONFIG_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftheader.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftheader.h new file mode 100644 index 00000000..b6236299 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftheader.h @@ -0,0 +1,832 @@ +/***************************************************************************/ +/* */ +/* ftheader.h */ +/* */ +/* Build macros of the FreeType 2 library. */ +/* */ +/* Copyright 1996-2008, 2010, 2012, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef __FT_HEADER_H__ +#define __FT_HEADER_H__ + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_BEGIN_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_END_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_BEGIN_HEADER extern "C" { +#else +#define FT_BEGIN_HEADER /* nothing */ +#endif + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_END_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_BEGIN_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_END_HEADER } +#else +#define FT_END_HEADER /* nothing */ +#endif + + + /*************************************************************************/ + /* */ + /* Aliases for the FreeType 2 public and configuration files. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /*
*/ + /* header_file_macros */ + /* */ + /* */ + /* Header File Macros */ + /* */ + /* <Abstract> */ + /* Macro definitions used to #include specific header files. */ + /* */ + /* <Description> */ + /* The following macros are defined to the name of specific */ + /* FreeType~2 header files. They can be used directly in #include */ + /* statements as in: */ + /* */ + /* { */ + /* #include FT_FREETYPE_H */ + /* #include FT_MULTIPLE_MASTERS_H */ + /* #include FT_GLYPH_H */ + /* } */ + /* */ + /* There are several reasons why we are now using macros to name */ + /* public header files. The first one is that such macros are not */ + /* limited to the infamous 8.3~naming rule required by DOS (and */ + /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ + /* */ + /* The second reason is that it allows for more flexibility in the */ + /* way FreeType~2 is installed on a given system. */ + /* */ + /*************************************************************************/ + + + /* configuration files */ + + /************************************************************************* + * + * @macro: + * FT_CONFIG_CONFIG_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 configuration data. + * + */ +#ifndef FT_CONFIG_CONFIG_H +#define FT_CONFIG_CONFIG_H <config/ftconfig.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_STANDARD_LIBRARY_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 interface to the standard C library functions. + * + */ +#ifndef FT_CONFIG_STANDARD_LIBRARY_H +#define FT_CONFIG_STANDARD_LIBRARY_H <config/ftstdlib.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_OPTIONS_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 project-specific configuration options. + * + */ +#ifndef FT_CONFIG_OPTIONS_H +#define FT_CONFIG_OPTIONS_H <config/ftoption.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_MODULES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 modules that are statically linked to new library + * instances in @FT_Init_FreeType. + * + */ +#ifndef FT_CONFIG_MODULES_H +#define FT_CONFIG_MODULES_H <config/ftmodule.h> +#endif + + /* */ + + /* public headers */ + + /************************************************************************* + * + * @macro: + * FT_FREETYPE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * base FreeType~2 API. + * + */ +#define FT_FREETYPE_H <freetype.h> + + + /************************************************************************* + * + * @macro: + * FT_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 error codes (and messages). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_ERRORS_H <fterrors.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 module error offsets (and messages). + * + */ +#define FT_MODULE_ERRORS_H <ftmoderr.h> + + + /************************************************************************* + * + * @macro: + * FT_SYSTEM_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 interface to low-level operations (i.e., memory management + * and stream i/o). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_SYSTEM_H <ftsystem.h> + + + /************************************************************************* + * + * @macro: + * FT_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing type + * definitions related to glyph images (i.e., bitmaps, outlines, + * scan-converter parameters). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_IMAGE_H <ftimage.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * basic data types defined by FreeType~2. + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_TYPES_H <fttypes.h> + + + /************************************************************************* + * + * @macro: + * FT_LIST_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list management API of FreeType~2. + * + * (Most applications will never need to include this file.) + * + */ +#define FT_LIST_H <ftlist.h> + + + /************************************************************************* + * + * @macro: + * FT_OUTLINE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * scalable outline management API of FreeType~2. + * + */ +#define FT_OUTLINE_H <ftoutln.h> + + + /************************************************************************* + * + * @macro: + * FT_SIZES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API which manages multiple @FT_Size objects per face. + * + */ +#define FT_SIZES_H <ftsizes.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * module management API of FreeType~2. + * + */ +#define FT_MODULE_H <ftmodapi.h> + + + /************************************************************************* + * + * @macro: + * FT_RENDER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * renderer module management API of FreeType~2. + * + */ +#define FT_RENDER_H <ftrender.h> + + + /************************************************************************* + * + * @macro: + * FT_AUTOHINTER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the auto-hinting module. + * + */ +#define FT_AUTOHINTER_H <ftautoh.h> + + + /************************************************************************* + * + * @macro: + * FT_CFF_DRIVER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the CFF driver module. + * + */ +#define FT_CFF_DRIVER_H <ftcffdrv.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_DRIVER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the TrueType driver module. + * + */ +#define FT_TRUETYPE_DRIVER_H <ftttdrv.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPE1_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the Type~1 format. + * + */ +#define FT_TYPE1_TABLES_H <t1tables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_IDS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * enumeration values which identify name strings, languages, encodings, + * etc. This file really contains a _large_ set of constant macro + * definitions, taken from the TrueType and OpenType specifications. + * + */ +#define FT_TRUETYPE_IDS_H <ttnameid.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the TrueType (as well as OpenType) format. + * + */ +#define FT_TRUETYPE_TABLES_H <tttables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TAGS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of TrueType four-byte `tags' which identify blocks in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_TRUETYPE_TAGS_H <tttags.h> + + + /************************************************************************* + * + * @macro: + * FT_BDF_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which accesses BDF-specific strings from a + * face. + * + */ +#define FT_BDF_H <ftbdf.h> + + + /************************************************************************* + * + * @macro: + * FT_CID_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which access CID font information from a + * face. + * + */ +#define FT_CID_H <ftcid.h> + + + /************************************************************************* + * + * @macro: + * FT_GZIP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports gzip-compressed files. + * + */ +#define FT_GZIP_H <ftgzip.h> + + + /************************************************************************* + * + * @macro: + * FT_LZW_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports LZW-compressed files. + * + */ +#define FT_LZW_H <ftlzw.h> + + + /************************************************************************* + * + * @macro: + * FT_BZIP2_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports bzip2-compressed files. + * + */ +#define FT_BZIP2_H <ftbzip2.h> + + + /************************************************************************* + * + * @macro: + * FT_WINFONTS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports Windows FNT files. + * + */ +#define FT_WINFONTS_H <ftwinfnt.h> + + + /************************************************************************* + * + * @macro: + * FT_GLYPH_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional glyph management component. + * + */ +#define FT_GLYPH_H <ftglyph.h> + + + /************************************************************************* + * + * @macro: + * FT_BITMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional bitmap conversion component. + * + */ +#define FT_BITMAP_H <ftbitmap.h> + + + /************************************************************************* + * + * @macro: + * FT_BBOX_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional exact bounding box computation routines. + * + */ +#define FT_BBOX_H <ftbbox.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional FreeType~2 cache sub-system. + * + */ +#define FT_CACHE_H <ftcache.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `glyph image' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for @FT_Glyph elements. You can also + * use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to + * store small glyph bitmaps, as it will use less memory. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * glyph image-related cache declarations. + * + */ +#define FT_CACHE_IMAGE_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_SMALL_BITMAPS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `small bitmaps' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for small glyph bitmaps in a relatively + * memory-efficient way. You can also use the API defined in + * @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, + * including scalable outlines. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * small bitmaps-related cache declarations. + * + */ +#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_CHARMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `charmap' API of the FreeType~2 cache sub-system. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * charmap-based cache declarations. + * + */ +#define FT_CACHE_CHARMAP_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_MAC_H + * + * @description: + * A macro used in #include statements to name the file containing the + * Macintosh-specific FreeType~2 API. The latter is used to access + * fonts embedded in resource forks. + * + * This header file must be explicitly included by client applications + * compiled on the Mac (note that the base API still works though). + * + */ +#define FT_MAC_H <ftmac.h> + + + /************************************************************************* + * + * @macro: + * FT_MULTIPLE_MASTERS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional multiple-masters management API of FreeType~2. + * + */ +#define FT_MULTIPLE_MASTERS_H <ftmm.h> + + + /************************************************************************* + * + * @macro: + * FT_SFNT_NAMES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which accesses embedded `name' strings in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_SFNT_NAMES_H <ftsnames.h> + + + /************************************************************************* + * + * @macro: + * FT_OPENTYPE_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, + * GPOS, GSUB, JSTF). + * + */ +#define FT_OPENTYPE_VALIDATE_H <ftotval.h> + + + /************************************************************************* + * + * @macro: + * FT_GX_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, + * mort, morx, bsln, just, kern, opbd, trak, prop). + * + */ +#define FT_GX_VALIDATE_H <ftgxval.h> + + + /************************************************************************* + * + * @macro: + * FT_PFR_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which accesses PFR-specific data. + * + */ +#define FT_PFR_H <ftpfr.h> + + + /************************************************************************* + * + * @macro: + * FT_STROKER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions to stroke outline paths. + */ +#define FT_STROKER_H <ftstroke.h> + + + /************************************************************************* + * + * @macro: + * FT_SYNTHESIS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs artificial obliquing and emboldening. + */ +#define FT_SYNTHESIS_H <ftsynth.h> + + + /************************************************************************* + * + * @macro: + * FT_XFREE86_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions specific to the XFree86 and + * X.Org X11 servers. + */ +#define FT_XFREE86_H <ftxf86.h> + + + /************************************************************************* + * + * @macro: + * FT_TRIGONOMETRY_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs trigonometric computations (e.g., + * cosines and arc tangents). + */ +#define FT_TRIGONOMETRY_H <fttrigon.h> + + + /************************************************************************* + * + * @macro: + * FT_LCD_FILTER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_LCD_FILTER_H <ftlcdfil.h> + + + /************************************************************************* + * + * @macro: + * FT_UNPATENTED_HINTING_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_UNPATENTED_HINTING_H <ttunpat.h> + + + /************************************************************************* + * + * @macro: + * FT_INCREMENTAL_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_INCREMENTAL_H <ftincrem.h> + + + /************************************************************************* + * + * @macro: + * FT_GASP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns entries from the TrueType GASP table. + */ +#define FT_GASP_H <ftgasp.h> + + + /************************************************************************* + * + * @macro: + * FT_ADVANCES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns individual and ranged glyph advances. + */ +#define FT_ADVANCES_H <ftadvanc.h> + + + /* */ + +#define FT_ERROR_DEFINITIONS_H <fterrdef.h> + + + /* The internals of the cache sub-system are no longer exposed. We */ + /* default to FT_CACHE_H at the moment just in case, but we know of */ + /* no rogue client that uses them. */ + /* */ +#define FT_CACHE_MANAGER_H <ftcache.h> +#define FT_CACHE_INTERNAL_MRU_H <ftcache.h> +#define FT_CACHE_INTERNAL_MANAGER_H <ftcache.h> +#define FT_CACHE_INTERNAL_CACHE_H <ftcache.h> +#define FT_CACHE_INTERNAL_GLYPH_H <ftcache.h> +#define FT_CACHE_INTERNAL_IMAGE_H <ftcache.h> +#define FT_CACHE_INTERNAL_SBITS_H <ftcache.h> + + +#define FT_INCREMENTAL_H <ftincrem.h> + +#define FT_TRUETYPE_UNPATENTED_H <ttunpat.h> + + + /* + * Include internal headers definitions from <internal/...> + * only when building the library. + */ +#ifdef FT2_BUILD_LIBRARY +#define FT_INTERNAL_INTERNAL_H <internal/internal.h> +#include FT_INTERNAL_INTERNAL_H +#endif /* FT2_BUILD_LIBRARY */ + + +#endif /* __FT2_BUILD_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftmodule.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftmodule.h new file mode 100644 index 00000000..76d271a7 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftmodule.h @@ -0,0 +1,32 @@ +/* + * This file registers the FreeType modules compiled into the library. + * + * If you use GNU make, this file IS NOT USED! Instead, it is created in + * the objects directory (normally `<topdir>/objs/') based on information + * from `<topdir>/modules.cfg'. + * + * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile + * FreeType without GNU make. + * + */ + +FT_USE_MODULE( FT_Module_Class, autofit_module_class ) +FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) +FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) +FT_USE_MODULE( FT_Module_Class, psaux_module_class ) +FT_USE_MODULE( FT_Module_Class, psnames_module_class ) +FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) +FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) +FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) + +/* EOF */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftoption.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftoption.h new file mode 100644 index 00000000..95fd36e2 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftoption.h @@ -0,0 +1,901 @@ +/***************************************************************************/ +/* */ +/* ftoption.h */ +/* */ +/* User-selectable configuration macros (specification only). */ +/* */ +/* Copyright 1996-2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOPTION_H__ +#define __FTOPTION_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* USER-SELECTABLE CONFIGURATION MACROS */ + /* */ + /* This file contains the default configuration macro definitions for */ + /* a standard build of the FreeType library. There are three ways to */ + /* use this file to build project-specific versions of the library: */ + /* */ + /* - You can modify this file by hand, but this is not recommended in */ + /* cases where you would like to build several versions of the */ + /* library from a single source directory. */ + /* */ + /* - You can put a copy of this file in your build directory, more */ + /* precisely in `$BUILD/config/ftoption.h', where `$BUILD' is the */ + /* name of a directory that is included _before_ the FreeType include */ + /* path during compilation. */ + /* */ + /* The default FreeType Makefiles and Jamfiles use the build */ + /* directory `builds/<system>' by default, but you can easily change */ + /* that for your own projects. */ + /* */ + /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ + /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ + /* locate this file during the build. For example, */ + /* */ + /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ + /* #include <config/ftheader.h> */ + /* */ + /* will use `$BUILD/myftoptions.h' instead of this file for macro */ + /* definitions. */ + /* */ + /* Note also that you can similarly pre-define the macro */ + /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ + /* that are statically linked to the library at compile time. By */ + /* default, this file is <config/ftmodule.h>. */ + /* */ + /* We highly recommend using the third method whenever possible. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Uncomment the line below if you want to activate sub-pixel rendering */ + /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ + /* */ + /* Note that this feature is covered by several Microsoft patents */ + /* and should not be activated in any default build of the library. */ + /* */ + /* This macro has no impact on the FreeType API, only on its */ + /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ + /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ + /* the original size in case this macro isn't defined; however, each */ + /* triplet of subpixels has R=G=B. */ + /* */ + /* This is done to allow FreeType clients to run unmodified, forcing */ + /* them to display normal gray-level anti-aliased glyphs. */ + /* */ +/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + + /*************************************************************************/ + /* */ + /* Many compilers provide a non-ANSI 64-bit data type that can be used */ + /* by FreeType to speed up some computations. However, this will create */ + /* some problems when compiling the library in strict ANSI mode. */ + /* */ + /* For this reason, the use of 64-bit integers is normally disabled when */ + /* the __STDC__ macro is defined. You can however disable this by */ + /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ + /* */ + /* For most compilers, this will only create compilation warnings when */ + /* building the library. */ + /* */ + /* ObNote: The compiler-specific 64-bit integers are detected in the */ + /* file `ftconfig.h' either statically or through the */ + /* `configure' script on supported platforms. */ + /* */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* If this macro is defined, do not try to use an assembler version of */ + /* performance-critical functions (e.g. FT_MulFix). You should only do */ + /* that to verify that the assembler function works properly, or to */ + /* execute benchmark tests of the various implementations. */ +/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ + + + /*************************************************************************/ + /* */ + /* If this macro is defined, try to use an inlined assembler version of */ + /* the `FT_MulFix' function, which is a `hotspot' when loading and */ + /* hinting glyphs, and which should be executed as fast as possible. */ + /* */ + /* Note that if your compiler or CPU is not supported, this will default */ + /* to the standard and portable implementation found in `ftcalc.c'. */ + /* */ +#define FT_CONFIG_OPTION_INLINE_MULFIX + + + /*************************************************************************/ + /* */ + /* LZW-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `compress' program. This is mostly used to parse many of the PCF */ + /* files that come with various X11 distributions. The implementation */ + /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ + /* (see src/lzw/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +#define FT_CONFIG_OPTION_USE_LZW + + + /*************************************************************************/ + /* */ + /* Gzip-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses `zlib' to */ + /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. See also */ + /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ + /* */ +#define FT_CONFIG_OPTION_USE_ZLIB + + + /*************************************************************************/ + /* */ + /* ZLib library selection */ + /* */ + /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ + /* It allows FreeType's `ftgzip' component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ + /* Unix or VMS where it generally is already available. */ + /* */ + /* If you let it undefined, the component will use its own copy */ + /* of the zlib sources instead. These have been modified to be */ + /* included directly within the component and *not* export external */ + /* function names. This allows you to link any program with FreeType */ + /* _and_ ZLib without linking conflicts. */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + + /*************************************************************************/ + /* */ + /* Bzip2-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `bzip2' program. This is mostly used to parse many of the PCF */ + /* files that come with XFree86. The implementation uses `libbz2' to */ + /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ + /* Contrary to gzip, bzip2 currently is not included and need to use */ + /* the system available bzip2 implementation. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_BZIP2 */ + + + /*************************************************************************/ + /* */ + /* Define to disable the use of file stream functions and types, FILE, */ + /* fopen() etc. Enables the use of smaller system libraries on embedded */ + /* systems that have multiple system libraries, some with or without */ + /* file stream support, in the cases where file stream support is not */ + /* necessary such as memory loading of font files. */ + /* */ +/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ + + + /*************************************************************************/ + /* */ + /* PNG bitmap support. */ + /* */ + /* FreeType now handles loading color bitmap glyphs in the PNG format. */ + /* This requires help from the external libpng library. Uncompressed */ + /* color bitmaps do not need any external libraries and will be */ + /* supported regardless of this configuration. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_PNG */ + + + /*************************************************************************/ + /* */ + /* HarfBuzz support. */ + /* */ + /* FreeType uses the HarfBuzz library to improve auto-hinting of */ + /* OpenType fonts. If available, many glyphs not directly addressable */ + /* by a font's character map will be hinted also. */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ + + + /*************************************************************************/ + /* */ + /* DLL export compilation */ + /* */ + /* When compiling FreeType as a DLL, some systems/compilers need a */ + /* special keyword in front OR after the return type of function */ + /* declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ + /* will be later automatically defined as `extern return_type' to */ + /* allow normal compilation. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +#define FT_EXPORT(x) extern x +#define FT_EXPORT_DEF(x) x + +/* #define FT_EXPORT(x) __declspec(dllexport) x */ +/* #define FT_BASE(x) __declspec(dllexport) x */ + + /*************************************************************************/ + /* */ + /* Glyph Postscript Names handling */ + /* */ + /* By default, FreeType 2 is compiled with the `psnames' module. This */ + /* module is in charge of converting a glyph name string into a */ + /* Unicode value, or return a Macintosh standard glyph name for the */ + /* use with the TrueType `post' table. */ + /* */ + /* Undefine this macro if you do not want `psnames' compiled in your */ + /* build of FreeType. This has the following effects: */ + /* */ + /* - The TrueType driver will provide its own set of glyph names, */ + /* if you build it to support postscript names in the TrueType */ + /* `post' table. */ + /* */ + /* - The Type 1 driver will not be able to synthesize a Unicode */ + /* charmap out of the glyphs found in the fonts. */ + /* */ + /* You would normally undefine this configuration macro when building */ + /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ + /* */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Postscript Names to Unicode Values support */ + /* */ + /* By default, FreeType 2 is built with the `PSNames' module compiled */ + /* in. Among other things, the module is used to convert a glyph name */ + /* into a Unicode value. This is especially useful in order to */ + /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* through a big table named the `Adobe Glyph List' (AGL). */ + /* */ + /* Undefine this macro if you do not want the Adobe Glyph List */ + /* compiled in your `PSNames' module. The Type 1 driver will not be */ + /* able to synthesize a Unicode charmap out of the glyphs found in the */ + /* fonts. */ + /* */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /*************************************************************************/ + /* */ + /* Support for Mac fonts */ + /* */ + /* Define this macro if you want support for outline fonts in Mac */ + /* format (mac dfont, mac resource, macbinary containing a mac */ + /* resource) on non-Mac platforms. */ + /* */ + /* Note that the `FOND' resource isn't checked. */ + /* */ +#define FT_CONFIG_OPTION_MAC_FONTS + + + /*************************************************************************/ + /* */ + /* Guessing methods to access embedded resource forks */ + /* */ + /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ + /* GNU/Linux). */ + /* */ + /* Resource forks which include fonts data are stored sometimes in */ + /* locations which users or developers don't expected. In some cases, */ + /* resource forks start with some offset from the head of a file. In */ + /* other cases, the actual resource fork is stored in file different */ + /* from what the user specifies. If this option is activated, */ + /* FreeType tries to guess whether such offsets or different file */ + /* names must be used. */ + /* */ + /* Note that normal, direct access of resource forks is controlled via */ + /* the FT_CONFIG_OPTION_MAC_FONTS option. */ + /* */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + + + /*************************************************************************/ + /* */ + /* Allow the use of FT_Incremental_Interface to load typefaces that */ + /* contain no glyph data, but supply it via a callback function. */ + /* This is required by clients supporting document formats which */ + /* supply font data incrementally as the document is parsed, such */ + /* as the Ghostscript interpreter for the PostScript language. */ + /* */ +#define FT_CONFIG_OPTION_INCREMENTAL + + + /*************************************************************************/ + /* */ + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ + /* */ + /* This must be greater than 4KByte if you use FreeType to rasterize */ + /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ + /* allocation of the render pool. */ + /* */ +#define FT_RENDER_POOL_SIZE 16384L + + + /*************************************************************************/ + /* */ + /* FT_MAX_MODULES */ + /* */ + /* The maximum number of modules that can be registered in a single */ + /* FreeType library object. 32 is the default. */ + /* */ +#define FT_MAX_MODULES 32 + + + /*************************************************************************/ + /* */ + /* Debug level */ + /* */ + /* FreeType can be compiled in debug or trace mode. In debug mode, */ + /* errors are reported through the `ftdebug' component. In trace */ + /* mode, additional messages are sent to the standard output during */ + /* execution. */ + /* */ + /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ + /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ + /* */ + /* Don't define any of these macros to compile in `release' mode! */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Autofitter debugging */ + /* */ + /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ + /* control the autofitter behaviour for debugging purposes with global */ + /* boolean variables (consequently, you should *never* enable this */ + /* while compiling in `release' mode): */ + /* */ + /* _af_debug_disable_horz_hints */ + /* _af_debug_disable_vert_hints */ + /* _af_debug_disable_blue_hints */ + /* */ + /* Additionally, the following functions provide dumps of various */ + /* internal autofit structures to stdout (using `printf'): */ + /* */ + /* af_glyph_hints_dump_points */ + /* af_glyph_hints_dump_segments */ + /* af_glyph_hints_dump_edges */ + /* */ + /* As an argument, they use another global variable: */ + /* */ + /* _af_debug_hints */ + /* */ + /* Please have a look at the `ftgrid' demo program to see how those */ + /* variables and macros should be used. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_AUTOFIT */ + + + /*************************************************************************/ + /* */ + /* Memory Debugging */ + /* */ + /* FreeType now comes with an integrated memory debugger that is */ + /* capable of detecting simple errors like memory leaks or double */ + /* deletes. To compile it within your build of the library, you */ + /* should define FT_DEBUG_MEMORY here. */ + /* */ + /* Note that the memory debugger is only activated at runtime when */ + /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_DEBUG_MEMORY */ + + + /*************************************************************************/ + /* */ + /* Module errors */ + /* */ + /* If this macro is set (which is _not_ the default), the higher byte */ + /* of an error code gives the module in which the error has occurred, */ + /* while the lower byte is the real error code. */ + /* */ + /* Setting this macro makes sense for debugging purposes only, since */ + /* it would break source compatibility of certain programs that use */ + /* FreeType 2. */ + /* */ + /* More details can be found in the files ftmoderr.h and fterrors.h. */ + /* */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + + + /*************************************************************************/ + /* */ + /* Position Independent Code */ + /* */ + /* If this macro is set (which is _not_ the default), FreeType2 will */ + /* avoid creating constants that require address fixups. Instead the */ + /* constants will be moved into a struct and additional intialization */ + /* code will be used. */ + /* */ + /* Setting this macro is needed for systems that prohibit address */ + /* fixups, such as BREW. */ + /* */ +/* #define FT_CONFIG_OPTION_PIC */ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ + /* embedded bitmaps in all formats using the SFNT module (namely */ + /* TrueType & OpenType). */ + /* */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ + /* load and enumerate the glyph Postscript names in a TrueType or */ + /* OpenType file. */ + /* */ + /* Note that when you do not compile the `PSNames' module by undefining */ + /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ + /* contain additional code used to read the PS Names table from a font. */ + /* */ + /* (By default, the module uses `PSNames' to extract glyph names.) */ + /* */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ + /* access the internal name table in a SFNT-based format like TrueType */ + /* or OpenType. The name table contains various strings used to */ + /* describe the font, like family name, copyright, version, etc. It */ + /* does not contain any glyph name though. */ + /* */ + /* Accessing SFNT names is done through the functions declared in */ + /* `ftsnames.h'. */ + /* */ +#define TT_CONFIG_OPTION_SFNT_NAMES + + + /*************************************************************************/ + /* */ + /* TrueType CMap support */ + /* */ + /* Here you can fine-tune which TrueType CMap table format shall be */ + /* supported. */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_13 +#define TT_CONFIG_CMAP_FORMAT_14 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ + /* a bytecode interpreter in the TrueType driver. */ + /* */ + /* By undefining this, you will only compile the code necessary to load */ + /* TrueType glyphs without hinting. */ + /* */ + /* Do not #undef this macro here, since the build system might */ + /* define it for certain configurations only. */ + /* */ +#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ + /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ + /* replaces the native TrueType hinting mechanism when anything but */ + /* FT_RENDER_MODE_MONO is requested. */ + /* */ + /* Enabling this causes the TrueType driver to ignore instructions under */ + /* certain conditions. This is done in accordance with the guide here, */ + /* with some minor differences: */ + /* */ + /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ + /* */ + /* By undefining this, you only compile the code necessary to hint */ + /* TrueType glyphs with native TT hinting. */ + /* */ + /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ + /* defined. */ + /* */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + + + /*************************************************************************/ + /* */ + /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ + /* of the TrueType bytecode interpreter is used that doesn't implement */ + /* any of the patented opcodes and algorithms. The patents related to */ + /* TrueType hinting have expired worldwide since May 2010; this option */ + /* is now deprecated. */ + /* */ + /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ + /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ + /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ + /* */ + /* This macro is only useful for a small number of font files (mostly */ + /* for Asian scripts) that require bytecode interpretation to properly */ + /* load glyphs. For all other fonts, this produces unpleasant results, */ + /* thus the unpatented interpreter is never used to load glyphs from */ + /* TrueType fonts unless one of the following two options is used. */ + /* */ + /* - The unpatented interpreter is explicitly activated by the user */ + /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ + /* when opening the FT_Face. */ + /* */ + /* - FreeType detects that the FT_Face corresponds to one of the */ + /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ + /* contains a hard-coded list of font names and other matching */ + /* parameters (see function `tt_face_init' in file */ + /* `src/truetype/ttobjs.c'). */ + /* */ + /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ + /* */ + /* { */ + /* FT_Parameter parameter; */ + /* FT_Open_Args open_args; */ + /* */ + /* */ + /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ + /* */ + /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ + /* open_args.pathname = my_font_pathname; */ + /* open_args.num_params = 1; */ + /* open_args.params = ¶meter; */ + /* */ + /* error = FT_Open_Face( library, &open_args, index, &face ); */ + /* ... */ + /* } */ + /* */ +/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ + /* bytecode interpreter with a huge switch statement, rather than a call */ + /* table. This results in smaller and faster code for a number of */ + /* architectures. */ + /* */ + /* Note however that on some compiler/processor combinations, undefining */ + /* this macro will generate faster, though larger, code. */ + /* */ +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ + /* TrueType glyph loader to use Apple's definition of how to handle */ + /* component offsets in composite glyphs. */ + /* */ + /* Apple and MS disagree on the default behavior of component offsets */ + /* in composites. Apple says that they should be scaled by the scaling */ + /* factors in the transformation matrix (roughly, it's more complex) */ + /* while MS says they should not. OpenType defines two bits in the */ + /* composite flags array which can be used to disambiguate, but old */ + /* fonts will not have them. */ + /* */ + /* http://www.microsoft.com/typography/otspec/glyf.htm */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ + /* support for Apple's distortable font technology (fvar, gvar, cvar, */ + /* and avar tables). This has many similarities to Type 1 Multiple */ + /* Masters support. */ + /* */ +#define TT_CONFIG_OPTION_GX_VAR_SUPPORT + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ + /* an embedded `BDF ' table within SFNT-based bitmap formats. */ + /* */ +#define TT_CONFIG_OPTION_BDF + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ + /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ + /* required. */ + /* */ +#define T1_MAX_DICT_DEPTH 5 + + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 16 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ + /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ + /* files into an existing face. Note that if set, the T1 driver will be */ + /* unable to produce kerning distances. */ + /* */ +#undef T1_CONFIG_OPTION_NO_AFM + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of the Multiple Masters font support in the Type 1 */ + /* driver. */ + /* */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** C F F D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ + /* possible to set up the default values of the four control points that */ + /* define the stem darkening behaviour of the (new) CFF engine. For */ + /* more details please read the documentation of the */ + /* `darkening-parameters' property of the cff driver module (file */ + /* `ftcffdrv.h'), which allows the control at run-time. */ + /* */ + /* Do *not* undefine these macros! */ + /* */ +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 + +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 +#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 + + + /*************************************************************************/ + /* */ + /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ + /* engine gets compiled into FreeType. If defined, it is possible to */ + /* switch between the two engines using the `hinting-engine' property of */ + /* the cff driver module. */ + /* */ +/* #define CFF_CONFIG_OPTION_OLD_ENGINE */ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ + /* */ +#define AF_CONFIG_OPTION_CJK + + /*************************************************************************/ + /* */ + /* Compile autofit module with Indic script support. */ + /* */ +#define AF_CONFIG_OPTION_INDIC + + /*************************************************************************/ + /* */ + /* Compile autofit module with warp hinting. The idea of the warping */ + /* code is to slightly scale and shift a glyph within a single dimension */ + /* so that as much of its segments are aligned (more or less) on the */ + /* grid. To find out the optimal scaling and shifting value, various */ + /* parameter combinations are tried and scored. */ + /* */ + /* This experimental option is only active if the render mode is */ + /* FT_RENDER_MODE_LIGHT. */ + /* */ +/* #define AF_CONFIG_OPTION_USE_WARPER */ + + /* */ + + + /* + * This macro is obsolete. Support has been removed in FreeType + * version 2.5. + */ +/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /* + * This macro is defined if either unpatented or native TrueType + * hinting is requested by the definitions above. + */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#define TT_USE_BYTECODE_INTERPRETER +#undef TT_CONFIG_OPTION_UNPATENTED_HINTING +#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING +#define TT_USE_BYTECODE_INTERPRETER +#endif + + + /* + * Check CFF darkening parameters. The checks are the same as in function + * `cff_property_set' in file `cffdrivr.c'. + */ +#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \ + \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \ + CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500 +#error "Invalid CFF darkening parameters!" +#endif + +FT_END_HEADER + + +#endif /* __FTOPTION_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftstdlib.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftstdlib.h new file mode 100644 index 00000000..b940efc4 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/config/ftstdlib.h @@ -0,0 +1,174 @@ +/***************************************************************************/ +/* */ +/* ftstdlib.h */ +/* */ +/* ANSI-specific library and header configuration file (specification */ +/* only). */ +/* */ +/* Copyright 2002-2007, 2009, 2011-2012 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to group all #includes to the ANSI C library that */ + /* FreeType normally requires. It also defines macros to rename the */ + /* standard functions within the FreeType source code. */ + /* */ + /* Load a file which defines __FTSTDLIB_H__ before this one to override */ + /* it. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSTDLIB_H__ +#define __FTSTDLIB_H__ + + +#include <stddef.h> + +#define ft_ptrdiff_t ptrdiff_t + + + /**********************************************************************/ + /* */ + /* integer limits */ + /* */ + /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ + /* of `int' and `long' in bytes at compile-time. So far, this works */ + /* for all platforms the library has been tested on. */ + /* */ + /* Note that on the extremely rare platforms that do not provide */ + /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ + /* old Crays where `int' is 36 bits), we do not make any guarantee */ + /* about the correct behaviour of FT2 with all fonts. */ + /* */ + /* In these case, `ftconfig.h' will refuse to compile anyway with a */ + /* message like `couldn't find 32-bit type' or something similar. */ + /* */ + /**********************************************************************/ + + +#include <limits.h> + +#define FT_CHAR_BIT CHAR_BIT +#define FT_USHORT_MAX USHRT_MAX +#define FT_INT_MAX INT_MAX +#define FT_INT_MIN INT_MIN +#define FT_UINT_MAX UINT_MAX +#define FT_ULONG_MAX ULONG_MAX + + + /**********************************************************************/ + /* */ + /* character and string processing */ + /* */ + /**********************************************************************/ + + +#include <string.h> + +#define ft_memchr memchr +#define ft_memcmp memcmp +#define ft_memcpy memcpy +#define ft_memmove memmove +#define ft_memset memset +#define ft_strcat strcat +#define ft_strcmp strcmp +#define ft_strcpy strcpy +#define ft_strlen strlen +#define ft_strncmp strncmp +#define ft_strncpy strncpy +#define ft_strrchr strrchr +#define ft_strstr strstr + + + /**********************************************************************/ + /* */ + /* file handling */ + /* */ + /**********************************************************************/ + + +#include <stdio.h> + +#define FT_FILE FILE +#define ft_fclose fclose +#define ft_fopen fopen +#define ft_fread fread +#define ft_fseek fseek +#define ft_ftell ftell +#define ft_sprintf sprintf + + + /**********************************************************************/ + /* */ + /* sorting */ + /* */ + /**********************************************************************/ + + +#include <stdlib.h> + +#define ft_qsort qsort + + + /**********************************************************************/ + /* */ + /* memory allocation */ + /* */ + /**********************************************************************/ + + +#define ft_scalloc calloc +#define ft_sfree free +#define ft_smalloc malloc +#define ft_srealloc realloc + + + /**********************************************************************/ + /* */ + /* miscellaneous */ + /* */ + /**********************************************************************/ + + +#define ft_atol atol +#define ft_labs labs + + + /**********************************************************************/ + /* */ + /* execution control */ + /* */ + /**********************************************************************/ + + +#include <setjmp.h> + +#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ + /* jmp_buf is defined as a macro */ + /* on certain platforms */ + +#define ft_longjmp longjmp +#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */ + + + /* the following is only used for debugging purposes, i.e., if */ + /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ + +#include <stdarg.h> + + +#endif /* __FTSTDLIB_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/freetype.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/freetype.h new file mode 100644 index 00000000..27fd44bf --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/freetype.h @@ -0,0 +1,4048 @@ +/***************************************************************************/ +/* */ +/* freetype.h */ +/* */ +/* FreeType high-level API and common types (specification only). */ +/* */ +/* Copyright 1996-2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FREETYPE_H__ +#define __FREETYPE_H__ + + +#ifndef FT_FREETYPE_H +#error "`ft2build.h' hasn't been included yet!" +#error "Please always use macros to include FreeType header files." +#error "Example:" +#error " #include <ft2build.h>" +#error " #include FT_FREETYPE_H" +#endif + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_TYPES_H +#include FT_ERRORS_H + + +FT_BEGIN_HEADER + + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* header_inclusion */ + /* */ + /* <Title> */ + /* FreeType's header inclusion scheme */ + /* */ + /* <Abstract> */ + /* How client applications should include FreeType header files. */ + /* */ + /* <Description> */ + /* To be as flexible as possible (and for historical reasons), */ + /* FreeType uses a very special inclusion scheme to load header */ + /* files, for example */ + /* */ + /* { */ + /* #include <ft2build.h> */ + /* */ + /* #include FT_FREETYPE_H */ + /* #include FT_OUTLINE_H */ + /* } */ + /* */ + /* A compiler and its preprocessor only needs an include path to find */ + /* the file `ft2build.h'; the exact locations and names of the other */ + /* FreeType header files are hidden by preprocessor macro names, */ + /* loaded by `ft2build.h'. The API documentation always gives the */ + /* header macro name needed for a particular function. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* user_allocation */ + /* */ + /* <Title> */ + /* User allocation */ + /* */ + /* <Abstract> */ + /* How client applications should allocate FreeType data structures. */ + /* */ + /* <Description> */ + /* FreeType assumes that structures allocated by the user and passed */ + /* as arguments are zeroed out except for the actual data. In other */ + /* words, it is recommended to use `calloc' (or variants of it) */ + /* instead of `malloc' for allocation. */ + /* */ + /*************************************************************************/ + + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S I C T Y P E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /* <Title> */ + /* Base Interface */ + /* */ + /* <Abstract> */ + /* The FreeType~2 base font interface. */ + /* */ + /* <Description> */ + /* This section describes the most important public high-level API */ + /* functions of FreeType~2. */ + /* */ + /* <Order> */ + /* FT_Library */ + /* FT_Face */ + /* FT_Size */ + /* FT_GlyphSlot */ + /* FT_CharMap */ + /* FT_Encoding */ + /* FT_ENC_TAG */ + /* */ + /* FT_FaceRec */ + /* */ + /* FT_FACE_FLAG_SCALABLE */ + /* FT_FACE_FLAG_FIXED_SIZES */ + /* FT_FACE_FLAG_FIXED_WIDTH */ + /* FT_FACE_FLAG_HORIZONTAL */ + /* FT_FACE_FLAG_VERTICAL */ + /* FT_FACE_FLAG_COLOR */ + /* FT_FACE_FLAG_SFNT */ + /* FT_FACE_FLAG_CID_KEYED */ + /* FT_FACE_FLAG_TRICKY */ + /* FT_FACE_FLAG_KERNING */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS */ + /* FT_FACE_FLAG_GLYPH_NAMES */ + /* FT_FACE_FLAG_EXTERNAL_STREAM */ + /* FT_FACE_FLAG_HINTER */ + /* FT_FACE_FLAG_TRICKY */ + /* */ + /* FT_HAS_HORIZONTAL */ + /* FT_HAS_VERTICAL */ + /* FT_HAS_KERNING */ + /* FT_HAS_FIXED_SIZES */ + /* FT_HAS_GLYPH_NAMES */ + /* FT_HAS_MULTIPLE_MASTERS */ + /* FT_HAS_COLOR */ + /* */ + /* FT_IS_SFNT */ + /* FT_IS_SCALABLE */ + /* FT_IS_FIXED_WIDTH */ + /* FT_IS_CID_KEYED */ + /* FT_IS_TRICKY */ + /* */ + /* FT_STYLE_FLAG_BOLD */ + /* FT_STYLE_FLAG_ITALIC */ + /* */ + /* FT_SizeRec */ + /* FT_Size_Metrics */ + /* */ + /* FT_GlyphSlotRec */ + /* FT_Glyph_Metrics */ + /* FT_SubGlyph */ + /* */ + /* FT_Bitmap_Size */ + /* */ + /* FT_Init_FreeType */ + /* FT_Done_FreeType */ + /* */ + /* FT_New_Face */ + /* FT_Done_Face */ + /* FT_Reference_Face */ + /* FT_New_Memory_Face */ + /* FT_Open_Face */ + /* FT_Open_Args */ + /* FT_Parameter */ + /* FT_Attach_File */ + /* FT_Attach_Stream */ + /* */ + /* FT_Set_Char_Size */ + /* FT_Set_Pixel_Sizes */ + /* FT_Request_Size */ + /* FT_Select_Size */ + /* FT_Size_Request_Type */ + /* FT_Size_RequestRec */ + /* FT_Size_Request */ + /* FT_Set_Transform */ + /* FT_Load_Glyph */ + /* FT_Get_Char_Index */ + /* FT_Get_First_Char */ + /* FT_Get_Next_Char */ + /* FT_Get_Name_Index */ + /* FT_Load_Char */ + /* */ + /* FT_OPEN_MEMORY */ + /* FT_OPEN_STREAM */ + /* FT_OPEN_PATHNAME */ + /* FT_OPEN_DRIVER */ + /* FT_OPEN_PARAMS */ + /* */ + /* FT_LOAD_DEFAULT */ + /* FT_LOAD_RENDER */ + /* FT_LOAD_MONOCHROME */ + /* FT_LOAD_LINEAR_DESIGN */ + /* FT_LOAD_NO_SCALE */ + /* FT_LOAD_NO_HINTING */ + /* FT_LOAD_NO_BITMAP */ + /* FT_LOAD_NO_AUTOHINT */ + /* FT_LOAD_COLOR */ + /* */ + /* FT_LOAD_VERTICAL_LAYOUT */ + /* FT_LOAD_IGNORE_TRANSFORM */ + /* FT_LOAD_FORCE_AUTOHINT */ + /* FT_LOAD_NO_RECURSE */ + /* FT_LOAD_PEDANTIC */ + /* */ + /* FT_LOAD_TARGET_NORMAL */ + /* FT_LOAD_TARGET_LIGHT */ + /* FT_LOAD_TARGET_MONO */ + /* FT_LOAD_TARGET_LCD */ + /* FT_LOAD_TARGET_LCD_V */ + /* */ + /* FT_LOAD_TARGET_MODE */ + /* */ + /* FT_Render_Glyph */ + /* FT_Render_Mode */ + /* FT_Get_Kerning */ + /* FT_Kerning_Mode */ + /* FT_Get_Track_Kerning */ + /* FT_Get_Glyph_Name */ + /* FT_Get_Postscript_Name */ + /* */ + /* FT_CharMapRec */ + /* FT_Select_Charmap */ + /* FT_Set_Charmap */ + /* FT_Get_Charmap_Index */ + /* */ + /* FT_Get_FSType_Flags */ + /* FT_Get_SubGlyph_Info */ + /* */ + /* FT_Face_Internal */ + /* FT_Size_Internal */ + /* FT_Slot_Internal */ + /* */ + /* FT_FACE_FLAG_XXX */ + /* FT_STYLE_FLAG_XXX */ + /* FT_OPEN_XXX */ + /* FT_LOAD_XXX */ + /* FT_LOAD_TARGET_XXX */ + /* FT_SUBGLYPH_FLAG_XXX */ + /* FT_FSTYPE_XXX */ + /* */ + /* FT_HAS_FAST_GLYPHS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Glyph_Metrics */ + /* */ + /* <Description> */ + /* A structure used to model the metrics of a single glyph. The */ + /* values are expressed in 26.6 fractional pixel format; if the flag */ + /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ + /* are expressed in font units instead. */ + /* */ + /* <Fields> */ + /* width :: */ + /* The glyph's width. */ + /* */ + /* height :: */ + /* The glyph's height. */ + /* */ + /* horiBearingX :: */ + /* Left side bearing for horizontal layout. */ + /* */ + /* horiBearingY :: */ + /* Top side bearing for horizontal layout. */ + /* */ + /* horiAdvance :: */ + /* Advance width for horizontal layout. */ + /* */ + /* vertBearingX :: */ + /* Left side bearing for vertical layout. */ + /* */ + /* vertBearingY :: */ + /* Top side bearing for vertical layout. Larger positive values */ + /* mean further below the vertical glyph origin. */ + /* */ + /* vertAdvance :: */ + /* Advance height for vertical layout. Positive values mean the */ + /* glyph has a positive advance downward. */ + /* */ + /* <Note> */ + /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ + /* dimensions of the hinted glyph (in case hinting is applicable). */ + /* */ + /* Stroking a glyph with an outside border does not increase */ + /* `horiAdvance' or `vertAdvance'; you have to manually adjust these */ + /* values to account for the added width and height. */ + /* */ + typedef struct FT_Glyph_Metrics_ + { + FT_Pos width; + FT_Pos height; + + FT_Pos horiBearingX; + FT_Pos horiBearingY; + FT_Pos horiAdvance; + + FT_Pos vertBearingX; + FT_Pos vertBearingY; + FT_Pos vertAdvance; + + } FT_Glyph_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap_Size */ + /* */ + /* <Description> */ + /* This structure models the metrics of a bitmap strike (i.e., a set */ + /* of glyphs for a given point size and resolution) in a bitmap font. */ + /* It is used for the `available_sizes' field of @FT_Face. */ + /* */ + /* <Fields> */ + /* height :: The vertical distance, in pixels, between two */ + /* consecutive baselines. It is always positive. */ + /* */ + /* width :: The average width, in pixels, of all glyphs in the */ + /* strike. */ + /* */ + /* size :: The nominal size of the strike in 26.6 fractional */ + /* points. This field is not very useful. */ + /* */ + /* x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional */ + /* pixels. */ + /* */ + /* y_ppem :: The vertical ppem (nominal height) in 26.6 fractional */ + /* pixels. */ + /* */ + /* <Note> */ + /* Windows FNT: */ + /* The nominal size given in a FNT font is not reliable. Thus when */ + /* the driver finds it incorrect, it sets `size' to some calculated */ + /* values and sets `x_ppem' and `y_ppem' to the pixel width and */ + /* height given in the font, respectively. */ + /* */ + /* TrueType embedded bitmaps: */ + /* `size', `width', and `height' values are not contained in the */ + /* bitmap strike itself. They are computed from the global font */ + /* parameters. */ + /* */ + typedef struct FT_Bitmap_Size_ + { + FT_Short height; + FT_Short width; + + FT_Pos size; + + FT_Pos x_ppem; + FT_Pos y_ppem; + + } FT_Bitmap_Size; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Library */ + /* */ + /* <Description> */ + /* A handle to a FreeType library instance. Each `library' is */ + /* completely independent from the others; it is the `root' of a set */ + /* of objects like fonts, faces, sizes, etc. */ + /* */ + /* It also embeds a memory manager (see @FT_Memory), as well as a */ + /* scan-line converter object (see @FT_Raster). */ + /* */ + /* In multi-threaded applications, make sure that the same FT_Library */ + /* object or any of its children doesn't get accessed in parallel. */ + /* */ + /* <Note> */ + /* Library objects are normally created by @FT_Init_FreeType, and */ + /* destroyed with @FT_Done_FreeType. If you need reference-counting */ + /* (cf. @FT_Reference_Library), use @FT_New_Library and */ + /* @FT_Done_Library. */ + /* */ + typedef struct FT_LibraryRec_ *FT_Library; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Module */ + /* */ + /* <Description> */ + /* A handle to a given FreeType module object. Each module can be a */ + /* font driver, a renderer, or anything else that provides services */ + /* to the formers. */ + /* */ + typedef struct FT_ModuleRec_* FT_Module; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Driver */ + /* */ + /* <Description> */ + /* A handle to a given FreeType font driver object. Each font driver */ + /* is a special module capable of creating faces from font files. */ + /* */ + typedef struct FT_DriverRec_* FT_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Renderer */ + /* */ + /* <Description> */ + /* A handle to a given FreeType renderer. A renderer is a special */ + /* module in charge of converting a glyph image to a bitmap, when */ + /* necessary. Each renderer supports a given glyph image format, and */ + /* one or more target surface depths. */ + /* */ + typedef struct FT_RendererRec_* FT_Renderer; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face */ + /* */ + /* <Description> */ + /* A handle to a given typographic face object. A face object models */ + /* a given typeface, in a given style. */ + /* */ + /* <Note> */ + /* Each face object also owns a single @FT_GlyphSlot object, as well */ + /* as one or more @FT_Size objects. */ + /* */ + /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ + /* a given filepathname or a custom input stream. */ + /* */ + /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ + /* */ + /* <Also> */ + /* See @FT_FaceRec for the publicly accessible fields of a given face */ + /* object. */ + /* */ + typedef struct FT_FaceRec_* FT_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size */ + /* */ + /* <Description> */ + /* A handle to an object used to model a face scaled to a given */ + /* character size. */ + /* */ + /* <Note> */ + /* Each @FT_Face has an _active_ @FT_Size object that is used by */ + /* functions like @FT_Load_Glyph to determine the scaling */ + /* transformation that in turn is used to load and hint glyphs and */ + /* metrics. */ + /* */ + /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ + /* @FT_Request_Size or even @FT_Select_Size to change the content */ + /* (i.e., the scaling values) of the active @FT_Size. */ + /* */ + /* You can use @FT_New_Size to create additional size objects for a */ + /* given @FT_Face, but they won't be used by other functions until */ + /* you activate it through @FT_Activate_Size. Only one size can be */ + /* activated at any given time per face. */ + /* */ + /* <Also> */ + /* See @FT_SizeRec for the publicly accessible fields of a given size */ + /* object. */ + /* */ + typedef struct FT_SizeRec_* FT_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a given `glyph slot'. A slot is a container where it */ + /* is possible to load any of the glyphs contained in its parent */ + /* face. */ + /* */ + /* In other words, each time you call @FT_Load_Glyph or */ + /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ + /* i.e., the glyph's metrics, its image (bitmap or outline), and */ + /* other control information. */ + /* */ + /* <Also> */ + /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ + /* */ + typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_CharMap */ + /* */ + /* <Description> */ + /* A handle to a given character map. A charmap is used to translate */ + /* character codes in a given encoding into glyph indexes for its */ + /* parent's face. Some font formats may provide several charmaps per */ + /* font. */ + /* */ + /* Each face object owns zero or more charmaps, but only one of them */ + /* can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char. */ + /* */ + /* The list of available charmaps in a face is available through the */ + /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ + /* */ + /* The currently active charmap is available as `face->charmap'. */ + /* You should call @FT_Set_Charmap to change it. */ + /* */ + /* <Note> */ + /* When a new face is created (either through @FT_New_Face or */ + /* @FT_Open_Face), the library looks for a Unicode charmap within */ + /* the list and automatically activates it. */ + /* */ + /* <Also> */ + /* See @FT_CharMapRec for the publicly accessible fields of a given */ + /* character map. */ + /* */ + typedef struct FT_CharMapRec_* FT_CharMap; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_ENC_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags into an unsigned long. It is */ + /* used to define `encoding' identifiers (see @FT_Encoding). */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_ENC_TAG( value, a, b, c, d ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ + +#ifndef FT_ENC_TAG +#define FT_ENC_TAG( value, a, b, c, d ) \ + value = ( ( (FT_UInt32)(a) << 24 ) | \ + ( (FT_UInt32)(b) << 16 ) | \ + ( (FT_UInt32)(c) << 8 ) | \ + (FT_UInt32)(d) ) + +#endif /* FT_ENC_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Encoding */ + /* */ + /* <Description> */ + /* An enumeration used to specify character sets supported by */ + /* charmaps. Used in the @FT_Select_Charmap API function. */ + /* */ + /* <Note> */ + /* Despite the name, this enumeration lists specific character */ + /* repertories (i.e., charsets), and not text encoding methods (e.g., */ + /* UTF-8, UTF-16, etc.). */ + /* */ + /* Other encodings might be defined in the future. */ + /* */ + /* <Values> */ + /* FT_ENCODING_NONE :: */ + /* The encoding value~0 is reserved. */ + /* */ + /* FT_ENCODING_UNICODE :: */ + /* Corresponds to the Unicode character set. This value covers */ + /* all versions of the Unicode repertoire, including ASCII and */ + /* Latin-1. Most fonts include a Unicode charmap, but not all */ + /* of them. */ + /* */ + /* For example, if you want to access Unicode value U+1F028 (and */ + /* the font contains it), use value 0x1F028 as the input value for */ + /* @FT_Get_Char_Index. */ + /* */ + /* FT_ENCODING_MS_SYMBOL :: */ + /* Corresponds to the Microsoft Symbol encoding, used to encode */ + /* mathematical symbols in the 32..255 character code range. For */ + /* more information, see */ + /* `http://www.kostis.net/charsets/symbol.htm'. */ + /* */ + /* FT_ENCODING_SJIS :: */ + /* Corresponds to Japanese SJIS encoding. More info at */ + /* at `http://en.wikipedia.org/wiki/Shift_JIS'. */ + /* See note on multi-byte encodings below. */ + /* */ + /* FT_ENCODING_GB2312 :: */ + /* Corresponds to an encoding system for Simplified Chinese as used */ + /* used in mainland China. */ + /* */ + /* FT_ENCODING_BIG5 :: */ + /* Corresponds to an encoding system for Traditional Chinese as */ + /* used in Taiwan and Hong Kong. */ + /* */ + /* FT_ENCODING_WANSUNG :: */ + /* Corresponds to the Korean encoding system known as Wansung. */ + /* For more information see */ + /* `http://msdn.microsoft.com/en-US/goglobal/cc305154'. */ + /* */ + /* FT_ENCODING_JOHAB :: */ + /* The Korean standard character set (KS~C 5601-1992), which */ + /* corresponds to MS Windows code page 1361. This character set */ + /* includes all possible Hangeul character combinations. */ + /* */ + /* FT_ENCODING_ADOBE_LATIN_1 :: */ + /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ + /* PostScript font. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_ADOBE_STANDARD :: */ + /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_EXPERT :: */ + /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_CUSTOM :: */ + /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_APPLE_ROMAN :: */ + /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ + /* and OpenType fonts contain a charmap for this encoding, since */ + /* older versions of Mac OS are able to use it. */ + /* */ + /* FT_ENCODING_OLD_LATIN_2 :: */ + /* This value is deprecated and was never used nor reported by */ + /* FreeType. Don't use or test for it. */ + /* */ + /* FT_ENCODING_MS_SJIS :: */ + /* Same as FT_ENCODING_SJIS. Deprecated. */ + /* */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Same as FT_ENCODING_BIG5. Deprecated. */ + /* */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* Same as FT_ENCODING_JOHAB. Deprecated. */ + /* */ + /* <Note> */ + /* By default, FreeType automatically synthesizes a Unicode charmap */ + /* for PostScript fonts, using their glyph names dictionaries. */ + /* However, it also reports the encodings defined explicitly in the */ + /* font file, for the cases when they are needed, with the Adobe */ + /* values as well. */ + /* */ + /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ + /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ + /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ + /* which encoding is really present. If, for example, the */ + /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ + /* the font is encoded in KOI8-R. */ + /* */ + /* FT_ENCODING_NONE is always set (with a single exception) by the */ + /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ + /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ + /* which encoding is really present. For example, */ + /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ + /* Russian). */ + /* */ + /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ + /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ + /* FT_ENCODING_APPLE_ROMAN). */ + /* */ + /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID that may */ + /* be needed to be able to distinguish Apple encoding variants. See */ + /* */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt */ + /* */ + /* to get an idea how to do that. Basically, if the language ID */ + /* is~0, don't use it, otherwise subtract 1 from the language ID. */ + /* Then examine `encoding_id'. If, for example, `encoding_id' is */ + /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ + /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ + /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* variant the Arabic encoding. */ + /* */ + typedef enum FT_Encoding_ + { + FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), + + FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), + FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), + + FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), + FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ), + FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), + FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), + FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), + + /* for backwards compatibility */ + FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, + FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312, + FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, + FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, + FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, + + FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ), + + FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ), + + FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' ) + + } FT_Encoding; + + + /* these constants are deprecated; use the corresponding `FT_Encoding' */ + /* values instead */ +#define ft_encoding_none FT_ENCODING_NONE +#define ft_encoding_unicode FT_ENCODING_UNICODE +#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL +#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 +#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 +#define ft_encoding_sjis FT_ENCODING_SJIS +#define ft_encoding_gb2312 FT_ENCODING_GB2312 +#define ft_encoding_big5 FT_ENCODING_BIG5 +#define ft_encoding_wansung FT_ENCODING_WANSUNG +#define ft_encoding_johab FT_ENCODING_JOHAB + +#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD +#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT +#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM +#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_CharMapRec */ + /* */ + /* <Description> */ + /* The base charmap structure. */ + /* */ + /* <Fields> */ + /* face :: A handle to the parent face object. */ + /* */ + /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ + /* this with @FT_Select_Charmap. */ + /* */ + /* platform_id :: An ID number describing the platform for the */ + /* following encoding ID. This comes directly from */ + /* the TrueType specification and should be emulated */ + /* for other formats. */ + /* */ + /* encoding_id :: A platform specific encoding number. This also */ + /* comes from the TrueType specification and should be */ + /* emulated similarly. */ + /* */ + typedef struct FT_CharMapRec_ + { + FT_Face face; + FT_Encoding encoding; + FT_UShort platform_id; + FT_UShort encoding_id; + + } FT_CharMapRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S E O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ + /* model private data of a given @FT_Face object. */ + /* */ + /* This structure might change between releases of FreeType~2 and is */ + /* not generally available to client applications. */ + /* */ + typedef struct FT_Face_InternalRec_* FT_Face_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_FaceRec */ + /* */ + /* <Description> */ + /* FreeType root face class structure. A face object models a */ + /* typeface in a font file. */ + /* */ + /* <Fields> */ + /* num_faces :: The number of faces in the font file. Some */ + /* font formats can have multiple faces in */ + /* a font file. */ + /* */ + /* face_index :: The index of the face in the font file. It */ + /* is set to~0 if there is only one face in */ + /* the font file. */ + /* */ + /* face_flags :: A set of bit flags that give important */ + /* information about the face; see */ + /* @FT_FACE_FLAG_XXX for the details. */ + /* */ + /* style_flags :: A set of bit flags indicating the style of */ + /* the face; see @FT_STYLE_FLAG_XXX for the */ + /* details. */ + /* */ + /* num_glyphs :: The number of glyphs in the face. If the */ + /* face is scalable and has sbits (see */ + /* `num_fixed_sizes'), it is set to the number */ + /* of outline glyphs. */ + /* */ + /* For CID-keyed fonts, this value gives the */ + /* highest CID used in the font. */ + /* */ + /* family_name :: The face's family name. This is an ASCII */ + /* string, usually in English, that describes */ + /* the typeface's family (like `Times New */ + /* Roman', `Bodoni', `Garamond', etc). This */ + /* is a least common denominator used to list */ + /* fonts. Some formats (TrueType & OpenType) */ + /* provide localized and Unicode versions of */ + /* this string. Applications should use the */ + /* format specific interface to access them. */ + /* Can be NULL (e.g., in fonts embedded in a */ + /* PDF file). */ + /* */ + /* style_name :: The face's style name. This is an ASCII */ + /* string, usually in English, that describes */ + /* the typeface's style (like `Italic', */ + /* `Bold', `Condensed', etc). Not all font */ + /* formats provide a style name, so this field */ + /* is optional, and can be set to NULL. As */ + /* for `family_name', some formats provide */ + /* localized and Unicode versions of this */ + /* string. Applications should use the format */ + /* specific interface to access them. */ + /* */ + /* num_fixed_sizes :: The number of bitmap strikes in the face. */ + /* Even if the face is scalable, there might */ + /* still be bitmap strikes, which are called */ + /* `sbits' in that case. */ + /* */ + /* available_sizes :: An array of @FT_Bitmap_Size for all bitmap */ + /* strikes in the face. It is set to NULL if */ + /* there is no bitmap strike. */ + /* */ + /* num_charmaps :: The number of charmaps in the face. */ + /* */ + /* charmaps :: An array of the charmaps of the face. */ + /* */ + /* generic :: A field reserved for client uses. See the */ + /* @FT_Generic type description. */ + /* */ + /* bbox :: The font bounding box. Coordinates are */ + /* expressed in font units (see */ + /* `units_per_EM'). The box is large enough */ + /* to contain any glyph from the font. Thus, */ + /* `bbox.yMax' can be seen as the `maximum */ + /* ascender', and `bbox.yMin' as the `minimum */ + /* descender'. Only relevant for scalable */ + /* formats. */ + /* */ + /* Note that the bounding box might be off by */ + /* (at least) one pixel for hinted fonts. See */ + /* @FT_Size_Metrics for further discussion. */ + /* */ + /* units_per_EM :: The number of font units per EM square for */ + /* this face. This is typically 2048 for */ + /* TrueType fonts, and 1000 for Type~1 fonts. */ + /* Only relevant for scalable formats. */ + /* */ + /* ascender :: The typographic ascender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMax'. Only relevant for scalable */ + /* formats. */ + /* */ + /* descender :: The typographic descender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMin'. Note that this field is */ + /* usually negative. Only relevant for */ + /* scalable formats. */ + /* */ + /* height :: This value is the vertical distance */ + /* between two consecutive baselines, */ + /* expressed in font units. It is always */ + /* positive. Only relevant for scalable */ + /* formats. */ + /* */ + /* If you want the global glyph height, use */ + /* `ascender - descender'. */ + /* */ + /* max_advance_width :: The maximum advance width, in font units, */ + /* for all glyphs in this face. This can be */ + /* used to make word wrapping computations */ + /* faster. Only relevant for scalable */ + /* formats. */ + /* */ + /* max_advance_height :: The maximum advance height, in font units, */ + /* for all glyphs in this face. This is only */ + /* relevant for vertical layouts, and is set */ + /* to `height' for fonts that do not provide */ + /* vertical metrics. Only relevant for */ + /* scalable formats. */ + /* */ + /* underline_position :: The position, in font units, of the */ + /* underline line for this face. It is the */ + /* center of the underlining stem. Only */ + /* relevant for scalable formats. */ + /* */ + /* underline_thickness :: The thickness, in font units, of the */ + /* underline for this face. Only relevant for */ + /* scalable formats. */ + /* */ + /* glyph :: The face's associated glyph slot(s). */ + /* */ + /* size :: The current active size for this face. */ + /* */ + /* charmap :: The current active charmap for this face. */ + /* */ + /* <Note> */ + /* Fields may be changed after a call to @FT_Attach_File or */ + /* @FT_Attach_Stream. */ + /* */ + typedef struct FT_FaceRec_ + { + FT_Long num_faces; + FT_Long face_index; + + FT_Long face_flags; + FT_Long style_flags; + + FT_Long num_glyphs; + + FT_String* family_name; + FT_String* style_name; + + FT_Int num_fixed_sizes; + FT_Bitmap_Size* available_sizes; + + FT_Int num_charmaps; + FT_CharMap* charmaps; + + FT_Generic generic; + + /*# The following member variables (down to `underline_thickness') */ + /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ + /*# for bitmap fonts. */ + FT_BBox bbox; + + FT_UShort units_per_EM; + FT_Short ascender; + FT_Short descender; + FT_Short height; + + FT_Short max_advance_width; + FT_Short max_advance_height; + + FT_Short underline_position; + FT_Short underline_thickness; + + FT_GlyphSlot glyph; + FT_Size size; + FT_CharMap charmap; + + /*@private begin */ + + FT_Driver driver; + FT_Memory memory; + FT_Stream stream; + + FT_ListRec sizes_list; + + FT_Generic autohint; /* face-specific auto-hinter data */ + void* extensions; /* unused */ + + FT_Face_Internal internal; + + /*@private end */ + + } FT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FACE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `face_flags' field of the */ + /* @FT_FaceRec structure. They inform client applications of */ + /* properties of the corresponding face. */ + /* */ + /* <Values> */ + /* FT_FACE_FLAG_SCALABLE :: */ + /* Indicates that the face contains outline glyphs. This doesn't */ + /* prevent bitmap strikes, i.e., a face can have both this and */ + /* and @FT_FACE_FLAG_FIXED_SIZES set. */ + /* */ + /* FT_FACE_FLAG_FIXED_SIZES :: */ + /* Indicates that the face contains bitmap strikes. See also the */ + /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ + /* */ + /* FT_FACE_FLAG_FIXED_WIDTH :: */ + /* Indicates that the face contains fixed-width characters (like */ + /* Courier, Lucido, MonoType, etc.). */ + /* */ + /* FT_FACE_FLAG_SFNT :: */ + /* Indicates that the face uses the `sfnt' storage scheme. For */ + /* now, this means TrueType and OpenType. */ + /* */ + /* FT_FACE_FLAG_HORIZONTAL :: */ + /* Indicates that the face contains horizontal glyph metrics. This */ + /* should be set for all common formats. */ + /* */ + /* FT_FACE_FLAG_VERTICAL :: */ + /* Indicates that the face contains vertical glyph metrics. This */ + /* is only available in some formats, not all of them. */ + /* */ + /* FT_FACE_FLAG_KERNING :: */ + /* Indicates that the face contains kerning information. If set, */ + /* the kerning distance can be retrieved through the function */ + /* @FT_Get_Kerning. Otherwise the function always return the */ + /* vector (0,0). Note that FreeType doesn't handle kerning data */ + /* from the `GPOS' table (as present in some OpenType fonts). */ + /* */ + /* FT_FACE_FLAG_FAST_GLYPHS :: */ + /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ + /* */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ + /* Indicates that the font contains multiple masters and is capable */ + /* of interpolating between them. See the multiple-masters */ + /* specific API for details. */ + /* */ + /* FT_FACE_FLAG_GLYPH_NAMES :: */ + /* Indicates that the font contains glyph names that can be */ + /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ + /* fonts contain broken glyph name tables. Use the function */ + /* @FT_Has_PS_Glyph_Names when needed. */ + /* */ + /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ + /* Used internally by FreeType to indicate that a face's stream was */ + /* provided by the client application and should not be destroyed */ + /* when @FT_Done_Face is called. Don't read or test this flag. */ + /* */ + /* FT_FACE_FLAG_HINTER :: */ + /* Set if the font driver has a hinting machine of its own. For */ + /* example, with TrueType fonts, it makes sense to use data from */ + /* the SFNT `gasp' table only if the native TrueType hinting engine */ + /* (with the bytecode interpreter) is available and active. */ + /* */ + /* FT_FACE_FLAG_CID_KEYED :: */ + /* Set if the font is CID-keyed. In that case, the font is not */ + /* accessed by glyph indices but by CID values. For subsetted */ + /* CID-keyed fonts this has the consequence that not all index */ + /* values are a valid argument to FT_Load_Glyph. Only the CID */ + /* values for which corresponding glyphs in the subsetted font */ + /* exist make FT_Load_Glyph return successfully; in all other cases */ + /* you get an `FT_Err_Invalid_Argument' error. */ + /* */ + /* Note that CID-keyed fonts that are in an SFNT wrapper don't */ + /* have this flag set since the glyphs are accessed in the normal */ + /* way (using contiguous indices); the `CID-ness' isn't visible to */ + /* the application. */ + /* */ + /* FT_FACE_FLAG_TRICKY :: */ + /* Set if the font is `tricky', this is, it always needs the */ + /* font format's native hinting engine to get a reasonable result. */ + /* A typical example is the Chinese font `mingli.ttf' that uses */ + /* TrueType bytecode instructions to move and scale all of its */ + /* subglyphs. */ + /* */ + /* It is not possible to autohint such fonts using */ + /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ + /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */ + /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ + /* probably never want this except for demonstration purposes. */ + /* */ + /* Currently, there are about a dozen TrueType fonts in the list of */ + /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ + /* */ + /* FT_FACE_FLAG_COLOR :: */ + /* Set if the font has color glyph tables. To access color glyphs */ + /* use @FT_LOAD_COLOR. */ + /* */ +#define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) +#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) +#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) +#define FT_FACE_FLAG_SFNT ( 1L << 3 ) +#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 ) +#define FT_FACE_FLAG_VERTICAL ( 1L << 5 ) +#define FT_FACE_FLAG_KERNING ( 1L << 6 ) +#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 ) +#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 ) +#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) +#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) +#define FT_FACE_FLAG_HINTER ( 1L << 11 ) +#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) +#define FT_FACE_FLAG_TRICKY ( 1L << 13 ) +#define FT_FACE_FLAG_COLOR ( 1L << 14 ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_HORIZONTAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * horizontal metrics (this is true for all font formats though). + * + * @also: + * @FT_HAS_VERTICAL can be used to check for vertical metrics. + * + */ +#define FT_HAS_HORIZONTAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_VERTICAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains real + * vertical metrics (and not only synthesized ones). + * + */ +#define FT_HAS_VERTICAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_KERNING( face ) + * + * @description: + * A macro that returns true whenever a face object contains kerning + * data that can be accessed with @FT_Get_Kerning. + * + */ +#define FT_HAS_KERNING( face ) \ + ( face->face_flags & FT_FACE_FLAG_KERNING ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SCALABLE( face ) + * + * @description: + * A macro that returns true whenever a face object contains a scalable + * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, + * and PFR font formats. + * + */ +#define FT_IS_SCALABLE( face ) \ + ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SFNT( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font + * whose format is based on the SFNT storage scheme. This usually + * means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded + * bitmap fonts. + * + * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and + * @FT_TRUETYPE_TABLES_H are available. + * + */ +#define FT_IS_SFNT( face ) \ + ( face->face_flags & FT_FACE_FLAG_SFNT ) + + + /************************************************************************* + * + * @macro: + * FT_IS_FIXED_WIDTH( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font face + * that contains fixed-width (or `monospace', `fixed-pitch', etc.) + * glyphs. + * + */ +#define FT_IS_FIXED_WIDTH( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FIXED_SIZES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * embedded bitmaps. See the `available_sizes' field of the + * @FT_FaceRec structure. + * + */ +#define FT_HAS_FIXED_SIZES( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FAST_GLYPHS( face ) + * + * @description: + * Deprecated. + * + */ +#define FT_HAS_FAST_GLYPHS( face ) 0 + + + /************************************************************************* + * + * @macro: + * FT_HAS_GLYPH_NAMES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some glyph + * names that can be accessed through @FT_Get_Glyph_Name. + * + */ +#define FT_HAS_GLYPH_NAMES( face ) \ + ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_MULTIPLE_MASTERS( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * multiple masters. The functions provided by @FT_MULTIPLE_MASTERS_H + * are then available to choose the exact design you want. + * + */ +#define FT_HAS_MULTIPLE_MASTERS( face ) \ + ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + + + /************************************************************************* + * + * @macro: + * FT_IS_CID_KEYED( face ) + * + * @description: + * A macro that returns true whenever a face object contains a CID-keyed + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more + * details. + * + * If this macro is true, all functions defined in @FT_CID_H are + * available. + * + */ +#define FT_IS_CID_KEYED( face ) \ + ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + + + /************************************************************************* + * + * @macro: + * FT_IS_TRICKY( face ) + * + * @description: + * A macro that returns true whenever a face represents a `tricky' font. + * See the discussion of @FT_FACE_FLAG_TRICKY for more details. + * + */ +#define FT_IS_TRICKY( face ) \ + ( face->face_flags & FT_FACE_FLAG_TRICKY ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_COLOR( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * tables for color glyphs. + * + */ +#define FT_HAS_COLOR( face ) \ + ( face->face_flags & FT_FACE_FLAG_COLOR ) + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_STYLE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit-flags used to indicate the style of a given face. */ + /* These are used in the `style_flags' field of @FT_FaceRec. */ + /* */ + /* <Values> */ + /* FT_STYLE_FLAG_ITALIC :: */ + /* Indicates that a given face style is italic or oblique. */ + /* */ + /* FT_STYLE_FLAG_BOLD :: */ + /* Indicates that a given face is bold. */ + /* */ + /* <Note> */ + /* The style information as provided by FreeType is very basic. More */ + /* details are beyond the scope and should be done on a higher level */ + /* (for example, by analyzing various fields of the `OS/2' table in */ + /* SFNT based fonts). */ + /* */ +#define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) +#define FT_STYLE_FLAG_BOLD ( 1 << 1 ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ + /* model private data of a given @FT_Size object. */ + /* */ + typedef struct FT_Size_InternalRec_* FT_Size_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Metrics */ + /* */ + /* <Description> */ + /* The size metrics structure gives the metrics of a size object. */ + /* */ + /* <Fields> */ + /* x_ppem :: The width of the scaled EM square in pixels, hence */ + /* the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal width'. */ + /* */ + /* y_ppem :: The height of the scaled EM square in pixels, */ + /* hence the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal height'. */ + /* */ + /* x_scale :: A 16.16 fractional scaling value used to convert */ + /* horizontal metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* y_scale :: A 16.16 fractional scaling value used to convert */ + /* vertical metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* ascender :: The ascender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* descender :: The descender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* height :: The height in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* max_advance :: The maximum advance width in 26.6 fractional */ + /* pixels. See @FT_FaceRec for the details. */ + /* */ + /* <Note> */ + /* The scaling values, if relevant, are determined first during a */ + /* size changing operation. The remaining fields are then set by the */ + /* driver. For scalable formats, they are usually set to scaled */ + /* values of the corresponding fields in @FT_FaceRec. */ + /* */ + /* Note that due to glyph hinting, these values might not be exact */ + /* for certain fonts. Thus they must be treated as unreliable */ + /* with an error margin of at least one pixel! */ + /* */ + /* Indeed, the only way to get the exact metrics is to render _all_ */ + /* glyphs. As this would be a definite performance hit, it is up to */ + /* client applications to perform such computations. */ + /* */ + /* The FT_Size_Metrics structure is valid for bitmap fonts also. */ + /* */ + typedef struct FT_Size_Metrics_ + { + FT_UShort x_ppem; /* horizontal pixels per EM */ + FT_UShort y_ppem; /* vertical pixels per EM */ + + FT_Fixed x_scale; /* scaling values used to convert font */ + FT_Fixed y_scale; /* units to 26.6 fractional pixels */ + + FT_Pos ascender; /* ascender in 26.6 frac. pixels */ + FT_Pos descender; /* descender in 26.6 frac. pixels */ + FT_Pos height; /* text height in 26.6 frac. pixels */ + FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ + + } FT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SizeRec */ + /* */ + /* <Description> */ + /* FreeType root size class structure. A size object models a face */ + /* object at a given size. */ + /* */ + /* <Fields> */ + /* face :: Handle to the parent face object. */ + /* */ + /* generic :: A typeless pointer, unused by the FreeType library or */ + /* any of its drivers. It can be used by client */ + /* applications to link their own data to each size */ + /* object. */ + /* */ + /* metrics :: Metrics for this size object. This field is read-only. */ + /* */ + typedef struct FT_SizeRec_ + { + FT_Face face; /* parent face object */ + FT_Generic generic; /* generic pointer for client uses */ + FT_Size_Metrics metrics; /* size metrics */ + FT_Size_Internal internal; + + } FT_SizeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SubGlyph */ + /* */ + /* <Description> */ + /* The subglyph structure is an internal object used to describe */ + /* subglyphs (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The subglyph implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + /* You can however retrieve subglyph information with */ + /* @FT_Get_SubGlyph_Info. */ + /* */ + typedef struct FT_SubGlyphRec_* FT_SubGlyph; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Slot_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ + /* model private data of a given @FT_GlyphSlot object. */ + /* */ + typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphSlotRec */ + /* */ + /* <Description> */ + /* FreeType root glyph slot class structure. A glyph slot is a */ + /* container where individual glyphs can be loaded, be they in */ + /* outline or bitmap format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library instance */ + /* this slot belongs to. */ + /* */ + /* face :: A handle to the parent face object. */ + /* */ + /* next :: In some cases (like some font tools), several */ + /* glyph slots per face object can be a good */ + /* thing. As this is rare, the glyph slots are */ + /* listed through a direct, single-linked list */ + /* using its `next' field. */ + /* */ + /* generic :: A typeless pointer unused by the FreeType */ + /* library or any of its drivers. It can be */ + /* used by client applications to link their own */ + /* data to each glyph slot object. */ + /* */ + /* metrics :: The metrics of the last loaded glyph in the */ + /* slot. The returned values depend on the last */ + /* load flags (see the @FT_Load_Glyph API */ + /* function) and can be expressed either in 26.6 */ + /* fractional pixels or font units. */ + /* */ + /* Note that even when the glyph image is */ + /* transformed, the metrics are not. */ + /* */ + /* linearHoriAdvance :: The advance width of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* linearVertAdvance :: The advance height of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* advance :: This shorthand is, depending on */ + /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ + /* (hinted) advance width for the glyph, in 26.6 */ + /* fractional pixel format. As specified with */ + /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ + /* `horiAdvance' or the `vertAdvance' value of */ + /* `metrics' field. */ + /* */ + /* format :: This field indicates the format of the image */ + /* contained in the glyph slot. Typically */ + /* @FT_GLYPH_FORMAT_BITMAP, */ + /* @FT_GLYPH_FORMAT_OUTLINE, or */ + /* @FT_GLYPH_FORMAT_COMPOSITE, but others are */ + /* possible. */ + /* */ + /* bitmap :: This field is used as a bitmap descriptor */ + /* when the slot format is */ + /* @FT_GLYPH_FORMAT_BITMAP. Note that the */ + /* address and content of the bitmap buffer can */ + /* change between calls of @FT_Load_Glyph and a */ + /* few other functions. */ + /* */ + /* bitmap_left :: The bitmap's left bearing expressed in */ + /* integer pixels. Only valid if the format is */ + /* @FT_GLYPH_FORMAT_BITMAP, this is, if the */ + /* glyph slot contains a bitmap. */ + /* */ + /* bitmap_top :: The bitmap's top bearing expressed in integer */ + /* pixels. Remember that this is the distance */ + /* from the baseline to the top-most glyph */ + /* scanline, upwards y~coordinates being */ + /* *positive*. */ + /* */ + /* outline :: The outline descriptor for the current glyph */ + /* image if its format is */ + /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ + /* loaded, `outline' can be transformed, */ + /* distorted, embolded, etc. However, it must */ + /* not be freed. */ + /* */ + /* num_subglyphs :: The number of subglyphs in a composite glyph. */ + /* This field is only valid for the composite */ + /* glyph format that should normally only be */ + /* loaded with the @FT_LOAD_NO_RECURSE flag. */ + /* */ + /* subglyphs :: An array of subglyph descriptors for */ + /* composite glyphs. There are `num_subglyphs' */ + /* elements in there. Currently internal to */ + /* FreeType. */ + /* */ + /* control_data :: Certain font drivers can also return the */ + /* control data for a given glyph image (e.g. */ + /* TrueType bytecode, Type~1 charstrings, etc.). */ + /* This field is a pointer to such data. */ + /* */ + /* control_len :: This is the length in bytes of the control */ + /* data. */ + /* */ + /* other :: Really wicked formats can use this pointer to */ + /* present their own glyph image to client */ + /* applications. Note that the application */ + /* needs to know about the image format. */ + /* */ + /* lsb_delta :: The difference between hinted and unhinted */ + /* left side bearing while autohinting is */ + /* active. Zero otherwise. */ + /* */ + /* rsb_delta :: The difference between hinted and unhinted */ + /* right side bearing while autohinting is */ + /* active. Zero otherwise. */ + /* */ + /* <Note> */ + /* If @FT_Load_Glyph is called with default flags (see */ + /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ + /* its native format (e.g., an outline glyph for TrueType and Type~1 */ + /* formats). */ + /* */ + /* This image can later be converted into a bitmap by calling */ + /* @FT_Render_Glyph. This function finds the current renderer for */ + /* the native image's format, then invokes it. */ + /* */ + /* The renderer is in charge of transforming the native image through */ + /* the slot's face transformation fields, then converting it into a */ + /* bitmap that is returned in `slot->bitmap'. */ + /* */ + /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ + /* to specify the position of the bitmap relative to the current pen */ + /* position (e.g., coordinates (0,0) on the baseline). Of course, */ + /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* <Note> */ + /* Here a small pseudo code fragment that shows how to use */ + /* `lsb_delta' and `rsb_delta': */ + /* */ + /* { */ + /* FT_Pos origin_x = 0; */ + /* FT_Pos prev_rsb_delta = 0; */ + /* */ + /* */ + /* for all glyphs do */ + /* <compute kern between current and previous glyph and add it to */ + /* `origin_x'> */ + /* */ + /* <load glyph with `FT_Load_Glyph'> */ + /* */ + /* if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 ) */ + /* origin_x -= 64; */ + /* else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 ) */ + /* origin_x += 64; */ + /* */ + /* prev_rsb_delta = face->glyph->rsb_delta; */ + /* */ + /* <save glyph image, or render glyph, or ...> */ + /* */ + /* origin_x += face->glyph->advance.x; */ + /* endfor */ + /* } */ + /* */ + typedef struct FT_GlyphSlotRec_ + { + FT_Library library; + FT_Face face; + FT_GlyphSlot next; + FT_UInt reserved; /* retained for binary compatibility */ + FT_Generic generic; + + FT_Glyph_Metrics metrics; + FT_Fixed linearHoriAdvance; + FT_Fixed linearVertAdvance; + FT_Vector advance; + + FT_Glyph_Format format; + + FT_Bitmap bitmap; + FT_Int bitmap_left; + FT_Int bitmap_top; + + FT_Outline outline; + + FT_UInt num_subglyphs; + FT_SubGlyph subglyphs; + + void* control_data; + long control_len; + + FT_Pos lsb_delta; + FT_Pos rsb_delta; + + void* other; + + FT_Slot_Internal internal; + + } FT_GlyphSlotRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* F U N C T I O N S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Init_FreeType */ + /* */ + /* <Description> */ + /* Initialize a new FreeType library object. The set of modules */ + /* that are registered by this function is determined at build time. */ + /* */ + /* <Output> */ + /* alibrary :: A handle to a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case you want to provide your own memory allocating routines, */ + /* use @FT_New_Library instead, followed by a call to */ + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ + /* */ + /* For multi-threading applications each thread should have its own */ + /* FT_Library object. */ + /* */ + /* If you need reference-counting (cf. @FT_Reference_Library), use */ + /* @FT_New_Library and @FT_Done_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_FreeType */ + /* */ + /* <Description> */ + /* Destroy a given FreeType library object and all of its children, */ + /* including resources, drivers, faces, sizes, etc. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_FreeType( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OPEN_XXX */ + /* */ + /* <Description> */ + /* A list of bit-field constants used within the `flags' field of the */ + /* @FT_Open_Args structure. */ + /* */ + /* <Values> */ + /* FT_OPEN_MEMORY :: This is a memory-based stream. */ + /* */ + /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ + /* */ + /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ + /* name. */ + /* */ + /* FT_OPEN_DRIVER :: Use the `driver' field. */ + /* */ + /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ + /* */ + /* <Note> */ + /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ + /* flags are mutually exclusive. */ + /* */ +#define FT_OPEN_MEMORY 0x1 +#define FT_OPEN_STREAM 0x2 +#define FT_OPEN_PATHNAME 0x4 +#define FT_OPEN_DRIVER 0x8 +#define FT_OPEN_PARAMS 0x10 + + + /* these constants are deprecated; use the corresponding `FT_OPEN_XXX' */ + /* values instead */ +#define ft_open_memory FT_OPEN_MEMORY +#define ft_open_stream FT_OPEN_STREAM +#define ft_open_pathname FT_OPEN_PATHNAME +#define ft_open_driver FT_OPEN_DRIVER +#define ft_open_params FT_OPEN_PARAMS + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Parameter */ + /* */ + /* <Description> */ + /* A simple structure used to pass more or less generic parameters to */ + /* @FT_Open_Face. */ + /* */ + /* <Fields> */ + /* tag :: A four-byte identification tag. */ + /* */ + /* data :: A pointer to the parameter data. */ + /* */ + /* <Note> */ + /* The ID and function of parameters are driver-specific. See the */ + /* various FT_PARAM_TAG_XXX flags for more information. */ + /* */ + typedef struct FT_Parameter_ + { + FT_ULong tag; + FT_Pointer data; + + } FT_Parameter; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Open_Args */ + /* */ + /* <Description> */ + /* A structure used to indicate how to open a new font file or */ + /* stream. A pointer to such a structure can be used as a parameter */ + /* for the functions @FT_Open_Face and @FT_Attach_Stream. */ + /* */ + /* <Fields> */ + /* flags :: A set of bit flags indicating how to use the */ + /* structure. */ + /* */ + /* memory_base :: The first byte of the file in memory. */ + /* */ + /* memory_size :: The size in bytes of the file in memory. */ + /* */ + /* pathname :: A pointer to an 8-bit file pathname. */ + /* */ + /* stream :: A handle to a source stream object. */ + /* */ + /* driver :: This field is exclusively used by @FT_Open_Face; */ + /* it simply specifies the font driver to use to open */ + /* the face. If set to~0, FreeType tries to load the */ + /* face with each one of the drivers in its list. */ + /* */ + /* num_params :: The number of extra parameters. */ + /* */ + /* params :: Extra parameters passed to the font driver when */ + /* opening a new face. */ + /* */ + /* <Note> */ + /* The stream type is determined by the contents of `flags' that */ + /* are tested in the following order by @FT_Open_Face: */ + /* */ + /* If the @FT_OPEN_MEMORY bit is set, assume that this is a */ + /* memory file of `memory_size' bytes, located at `memory_address'. */ + /* The data are are not copied, and the client is responsible for */ + /* releasing and destroying them _after_ the corresponding call to */ + /* @FT_Done_Face. */ + /* */ + /* Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a */ + /* custom input stream `stream' is used. */ + /* */ + /* Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this */ + /* is a normal file and use `pathname' to open it. */ + /* */ + /* If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to */ + /* open the file with the driver whose handler is in `driver'. */ + /* */ + /* If the @FT_OPEN_PARAMS bit is set, the parameters given by */ + /* `num_params' and `params' is used. They are ignored otherwise. */ + /* */ + /* Ideally, both the `pathname' and `params' fields should be tagged */ + /* as `const'; this is missing for API backwards compatibility. In */ + /* other words, applications should treat them as read-only. */ + /* */ + typedef struct FT_Open_Args_ + { + FT_UInt flags; + const FT_Byte* memory_base; + FT_Long memory_size; + FT_String* pathname; + FT_Stream stream; + FT_Module driver; + FT_Int num_params; + FT_Parameter* params; + + } FT_Open_Args; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font by its pathname. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* pathname :: A path to the font file. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See @FT_Open_Face for more details. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Use @FT_Done_Face to destroy the created @FT_Face object (along */ + /* with its slot and sizes). */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face( FT_Library library, + const char* filepathname, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font that has been */ + /* loaded into memory. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* file_base :: A pointer to the beginning of the font data. */ + /* */ + /* file_size :: The size of the memory chunk used by the font data. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See @FT_Open_Face for more details. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You must not deallocate the memory before calling @FT_Done_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Memory_Face( FT_Library library, + const FT_Byte* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Open_Face */ + /* */ + /* <Description> */ + /* Create a face object from a given resource described by */ + /* @FT_Open_Args. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* args :: A pointer to an `FT_Open_Args' structure that must */ + /* be filled by the caller. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See note below. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object that can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* FT_Open_Face can be used to quickly check whether the font */ + /* format of a given font resource is supported by FreeType. If the */ + /* `face_index' field is negative, the function's return value is~0 */ + /* if the font format is recognized, or non-zero otherwise; */ + /* the function returns a more or less empty face handle in `*aface' */ + /* (if `aface' isn't NULL). The only useful field in this special */ + /* case is `face->num_faces' that gives the number of faces within */ + /* the font file. After examination, the returned @FT_Face structure */ + /* should be deallocated with a call to @FT_Done_Face. */ + /* */ + /* Each new face object created with this function also owns a */ + /* default @FT_Size object, accessible as `face->size'. */ + /* */ + /* One @FT_Library instance can have multiple face objects, this is, */ + /* @FT_Open_Face and its siblings can be called multiple times using */ + /* the same `library' argument. */ + /* */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_File */ + /* */ + /* <Description> */ + /* This function calls @FT_Attach_Stream to attach a file. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* filepathname :: The pathname. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_Stream */ + /* */ + /* <Description> */ + /* `Attach' data to a face object. Normally, this is used to read */ + /* additional information for the face object. For example, you can */ + /* attach an AFM file that comes with a Type~1 font to get the */ + /* kerning values and other metrics. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* parameters :: A pointer to @FT_Open_Args that must be filled by */ + /* the caller. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The meaning of the `attach' (i.e., what really happens when the */ + /* new file is read) is not fixed by FreeType itself. It really */ + /* depends on the font format (and thus the font driver). */ + /* */ + /* Client applications are expected to know what they are doing */ + /* when invoking this function. Most drivers simply do not implement */ + /* file attachments. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Reference_Face */ + /* */ + /* <Description> */ + /* A counter gets initialized to~1 at the time an @FT_Face structure */ + /* is created. This function increments the counter. @FT_Done_Face */ + /* then only destroys a face if the counter is~1, otherwise it simply */ + /* decrements the counter. */ + /* */ + /* This function helps in managing life-cycles of structures that */ + /* reference @FT_Face objects. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.4.2 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Reference_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Face */ + /* */ + /* <Description> */ + /* Discard a given face object, as well as all of its child slots and */ + /* sizes. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Size */ + /* */ + /* <Description> */ + /* Select a bitmap strike. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* strike_index :: The index of the bitmap strike in the */ + /* `available_sizes' field of @FT_FaceRec structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Size( FT_Face face, + FT_Int strike_index ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Size_Request_Type */ + /* */ + /* <Description> */ + /* An enumeration type that lists the supported size request types. */ + /* */ + /* <Values> */ + /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ + /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ + /* used to determine both scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ + /* The real dimension. The sum of the the `ascender' and (minus */ + /* of) the `descender' fields of @FT_FaceRec are used to determine */ + /* both scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_BBOX :: */ + /* The font bounding box. The width and height of the `bbox' field */ + /* of @FT_FaceRec are used to determine the horizontal and vertical */ + /* scaling value, respectively. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_CELL :: */ + /* The `max_advance_width' field of @FT_FaceRec is used to */ + /* determine the horizontal scaling value; the vertical scaling */ + /* value is determined the same way as */ + /* @FT_SIZE_REQUEST_TYPE_REAL_DIM does. Finally, both scaling */ + /* values are set to the smaller one. This type is useful if you */ + /* want to specify the font size for, say, a window of a given */ + /* dimension and 80x24 cells. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_SCALES :: */ + /* Specify the scaling values directly. */ + /* */ + /* <Note> */ + /* The above descriptions only apply to scalable formats. For bitmap */ + /* formats, the behaviour is up to the driver. */ + /* */ + /* See the note section of @FT_Size_Metrics if you wonder how size */ + /* requesting relates to scaling values. */ + /* */ + typedef enum FT_Size_Request_Type_ + { + FT_SIZE_REQUEST_TYPE_NOMINAL, + FT_SIZE_REQUEST_TYPE_REAL_DIM, + FT_SIZE_REQUEST_TYPE_BBOX, + FT_SIZE_REQUEST_TYPE_CELL, + FT_SIZE_REQUEST_TYPE_SCALES, + + FT_SIZE_REQUEST_TYPE_MAX + + } FT_Size_Request_Type; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_RequestRec */ + /* */ + /* <Description> */ + /* A structure used to model a size request. */ + /* */ + /* <Fields> */ + /* type :: See @FT_Size_Request_Type. */ + /* */ + /* width :: The desired width. */ + /* */ + /* height :: The desired height. */ + /* */ + /* horiResolution :: The horizontal resolution. If set to zero, */ + /* `width' is treated as a 26.6 fractional pixel */ + /* value. */ + /* */ + /* vertResolution :: The vertical resolution. If set to zero, */ + /* `height' is treated as a 26.6 fractional pixel */ + /* value. */ + /* */ + /* <Note> */ + /* If `width' is zero, then the horizontal scaling value is set equal */ + /* to the vertical scaling value, and vice versa. */ + /* */ + typedef struct FT_Size_RequestRec_ + { + FT_Size_Request_Type type; + FT_Long width; + FT_Long height; + FT_UInt horiResolution; + FT_UInt vertResolution; + + } FT_Size_RequestRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Request */ + /* */ + /* <Description> */ + /* A handle to a size request structure. */ + /* */ + typedef struct FT_Size_RequestRec_ *FT_Size_Request; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Request_Size */ + /* */ + /* <Description> */ + /* Resize the scale of the active @FT_Size object in a face. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* req :: A pointer to a @FT_Size_RequestRec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Although drivers may select the bitmap strike matching the */ + /* request, you should not rely on this if you intend to select a */ + /* particular bitmap strike. Use @FT_Select_Size instead in that */ + /* case. */ + /* */ + /* The relation between the requested size and the resulting glyph */ + /* size is dependent entirely on how the size is defined in the */ + /* source face. The font designer chooses the final size of each */ + /* glyph relative to this size. For more information refer to */ + /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Request_Size( FT_Face face, + FT_Size_Request req ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Char_Size */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in points). */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* char_width :: The nominal width, in 26.6 fractional points. */ + /* */ + /* char_height :: The nominal height, in 26.6 fractional points. */ + /* */ + /* horz_resolution :: The horizontal resolution in dpi. */ + /* */ + /* vert_resolution :: The vertical resolution in dpi. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If either the character width or height is zero, it is set equal */ + /* to the other value. */ + /* */ + /* If either the horizontal or vertical resolution is zero, it is set */ + /* equal to the other value. */ + /* */ + /* A character width or height smaller than 1pt is set to 1pt; if */ + /* both resolution values are zero, they are set to 72dpi. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Pixel_Sizes */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in pixels). */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* pixel_width :: The nominal width, in pixels. */ + /* */ + /* pixel_height :: The nominal height, in pixels. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You should not rely on the resulting glyphs matching, or being */ + /* constrained, to this pixel size. Refer to @FT_Request_Size to */ + /* understand how requested sizes relate to actual sizes. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Glyph */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* glyph_index :: The index of the glyph in the font file. For */ + /* CID-keyed fonts (either in PS or in CFF format) */ + /* this argument specifies the CID value. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The loaded glyph may be transformed. See @FT_Set_Transform for */ + /* the details. */ + /* */ + /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ + /* returned for invalid CID values (this is, for CID values that */ + /* don't have a corresponding glyph in the font). See the discussion */ + /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Char */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object, according to its character code. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* char_code :: The glyph's character code, according to the */ + /* current charmap used in the face. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ); + + + /************************************************************************* + * + * @enum: + * FT_LOAD_XXX + * + * @description: + * A list of bit-field constants used with @FT_Load_Glyph to indicate + * what kind of operations to perform during glyph loading. + * + * @values: + * FT_LOAD_DEFAULT :: + * Corresponding to~0, this value is used as the default glyph load + * operation. In this case, the following happens: + * + * 1. FreeType looks for a bitmap for the glyph corresponding to the + * face's current size. If one is found, the function returns. + * The bitmap data can be accessed from the glyph slot (see note + * below). + * + * 2. If no embedded bitmap is searched or found, FreeType looks for a + * scalable outline. If one is found, it is loaded from the font + * file, scaled to device pixels, then `hinted' to the pixel grid + * in order to optimize it. The outline data can be accessed from + * the glyph slot (see note below). + * + * Note that by default, the glyph loader doesn't render outlines into + * bitmaps. The following flags are used to modify this default + * behaviour to more specific and useful cases. + * + * FT_LOAD_NO_SCALE :: + * Don't scale the loaded outline glyph but keep it in font units. + * + * This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and + * unsets @FT_LOAD_RENDER. + * + * If the font is `tricky' (see @FT_FACE_FLAG_TRICKY for more), using + * FT_LOAD_NO_SCALE usually yields meaningless outlines because the + * subglyphs must be scaled and positioned with hinting instructions. + * This can be solved by loading the font without FT_LOAD_NO_SCALE and + * setting the character size to `font->units_per_EM'. + * + * FT_LOAD_NO_HINTING :: + * Disable hinting. This generally generates `blurrier' bitmap glyphs + * when the glyph are rendered in any of the anti-aliased modes. See + * also the note below. + * + * This flag is implied by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_RENDER :: + * Call @FT_Render_Glyph after the glyph is loaded. By default, the + * glyph is rendered in @FT_RENDER_MODE_NORMAL mode. This can be + * overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME. + * + * This flag is unset by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_NO_BITMAP :: + * Ignore bitmap strikes when loading. Bitmap-only fonts ignore this + * flag. + * + * @FT_LOAD_NO_SCALE always sets this flag. + * + * FT_LOAD_VERTICAL_LAYOUT :: + * Load the glyph for vertical text layout. In particular, the + * `advance' value in the @FT_GlyphSlotRec structure is set to the + * `vertAdvance' value of the `metrics' field. + * + * In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use + * this flag currently. Reason is that in this case vertical metrics + * get synthesized, and those values are not always consistent across + * various font formats. + * + * FT_LOAD_FORCE_AUTOHINT :: + * Indicates that the auto-hinter is preferred over the font's native + * hinter. See also the note below. + * + * FT_LOAD_PEDANTIC :: + * Indicates that the font driver should perform pedantic verifications + * during glyph loading. This is mostly used to detect broken glyphs + * in fonts. By default, FreeType tries to handle broken fonts also. + * + * In particular, errors from the TrueType bytecode engine are not + * passed to the application if this flag is not set; this might + * result in partially hinted or distorted glyphs in case a glyph's + * bytecode is buggy. + * + * FT_LOAD_NO_RECURSE :: + * Indicate that the font driver should not load composite glyphs + * recursively. Instead, it should set the `num_subglyph' and + * `subglyphs' values of the glyph slot accordingly, and set + * `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE. The description of + * subglyphs can then be accessed with @FT_Get_SubGlyph_Info. + * + * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. + * + * FT_LOAD_IGNORE_TRANSFORM :: + * Indicates that the transform matrix set by @FT_Set_Transform should + * be ignored. + * + * FT_LOAD_MONOCHROME :: + * This flag is used with @FT_LOAD_RENDER to indicate that you want to + * render an outline glyph to a 1-bit monochrome bitmap glyph, with + * 8~pixels packed into each byte of the bitmap data. + * + * Note that this has no effect on the hinting algorithm used. You + * should rather use @FT_LOAD_TARGET_MONO so that the + * monochrome-optimized hinting algorithm is used. + * + * FT_LOAD_LINEAR_DESIGN :: + * Indicates that the `linearHoriAdvance' and `linearVertAdvance' + * fields of @FT_GlyphSlotRec should be kept in font units. See + * @FT_GlyphSlotRec for details. + * + * FT_LOAD_NO_AUTOHINT :: + * Disable auto-hinter. See also the note below. + * + * FT_LOAD_COLOR :: + * This flag is used to request loading of color embedded-bitmap + * images. The resulting color bitmaps, if available, will have the + * @FT_PIXEL_MODE_BGRA format. When the flag is not used and color + * bitmaps are found, they will be converted to 256-level gray + * bitmaps transparently. Those bitmaps will be in the + * @FT_PIXEL_MODE_GRAY format. + * + * FT_LOAD_CROP_BITMAP :: + * Ignored. Deprecated. + * + * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: + * Ignored. Deprecated. + * + * @note: + * By default, hinting is enabled and the font's native hinter (see + * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can + * disable hinting by setting @FT_LOAD_NO_HINTING or change the + * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set + * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be + * used at all. + * + * See the description of @FT_FACE_FLAG_TRICKY for a special exception + * (affecting only a handful of Asian fonts). + * + * Besides deciding which hinter to use, you can also decide which + * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. + * + * Note that the auto-hinter needs a valid Unicode cmap (either a native + * one or synthesized by FreeType) for producing correct results. If a + * font provides an incorrect mapping (for example, assigning the + * character code U+005A, LATIN CAPITAL LETTER Z, to a glyph depicting a + * mathematical integral sign), the auto-hinter might produce useless + * results. + * + */ +#define FT_LOAD_DEFAULT 0x0 +#define FT_LOAD_NO_SCALE ( 1L << 0 ) +#define FT_LOAD_NO_HINTING ( 1L << 1 ) +#define FT_LOAD_RENDER ( 1L << 2 ) +#define FT_LOAD_NO_BITMAP ( 1L << 3 ) +#define FT_LOAD_VERTICAL_LAYOUT ( 1L << 4 ) +#define FT_LOAD_FORCE_AUTOHINT ( 1L << 5 ) +#define FT_LOAD_CROP_BITMAP ( 1L << 6 ) +#define FT_LOAD_PEDANTIC ( 1L << 7 ) +#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ( 1L << 9 ) +#define FT_LOAD_NO_RECURSE ( 1L << 10 ) +#define FT_LOAD_IGNORE_TRANSFORM ( 1L << 11 ) +#define FT_LOAD_MONOCHROME ( 1L << 12 ) +#define FT_LOAD_LINEAR_DESIGN ( 1L << 13 ) +#define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) + /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ +#define FT_LOAD_COLOR ( 1L << 20 ) + + /* */ + + /* used internally only by certain font drivers! */ +#define FT_LOAD_ADVANCE_ONLY ( 1L << 8 ) +#define FT_LOAD_SBITS_ONLY ( 1L << 14 ) + + + /************************************************************************** + * + * @enum: + * FT_LOAD_TARGET_XXX + * + * @description: + * A list of values that are used to select a specific hinting algorithm + * to use by the hinter. You should OR one of these values to your + * `load_flags' when calling @FT_Load_Glyph. + * + * Note that font's native hinters may ignore the hinting algorithm you + * have specified (e.g., the TrueType bytecode interpreter). You can set + * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. + * + * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it + * always implies @FT_LOAD_FORCE_AUTOHINT. + * + * @values: + * FT_LOAD_TARGET_NORMAL :: + * This corresponds to the default hinting algorithm, optimized for + * standard gray-level rendering. For monochrome output, use + * @FT_LOAD_TARGET_MONO instead. + * + * FT_LOAD_TARGET_LIGHT :: + * A lighter hinting algorithm for non-monochrome modes. Many + * generated glyphs are more fuzzy but better resemble its original + * shape. A bit like rendering on Mac OS~X. + * + * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. + * + * FT_LOAD_TARGET_MONO :: + * Strong hinting algorithm that should only be used for monochrome + * output. The result is probably unpleasant if the glyph is rendered + * in non-monochrome modes. + * + * FT_LOAD_TARGET_LCD :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally + * decimated LCD displays. + * + * FT_LOAD_TARGET_LCD_V :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically + * decimated LCD displays. + * + * @note: + * You should use only _one_ of the FT_LOAD_TARGET_XXX values in your + * `load_flags'. They can't be ORed. + * + * If @FT_LOAD_RENDER is also set, the glyph is rendered in the + * corresponding mode (i.e., the mode that matches the used algorithm + * best). An exeption is FT_LOAD_TARGET_MONO since it implies + * @FT_LOAD_MONOCHROME. + * + * You can use a hinting algorithm that doesn't correspond to the same + * rendering mode. As an example, it is possible to use the `light' + * hinting algorithm and have the results rendered in horizontal LCD + * pixel mode, with code like + * + * { + * FT_Load_Glyph( face, glyph_index, + * load_flags | FT_LOAD_TARGET_LIGHT ); + * + * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); + * } + * + */ +#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) + +#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) +#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) +#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) +#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) +#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) + + + /************************************************************************** + * + * @macro: + * FT_LOAD_TARGET_MODE + * + * @description: + * Return the @FT_Render_Mode corresponding to a given + * @FT_LOAD_TARGET_XXX value. + * + */ +#define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Transform */ + /* */ + /* <Description> */ + /* A function used to set the transformation that is applied to glyph */ + /* images when they are loaded into a glyph slot through */ + /* @FT_Load_Glyph. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ + /* the identity matrix. */ + /* delta :: A pointer to the translation vector. Use~0 for the null */ + /* vector. */ + /* */ + /* <Note> */ + /* The transformation is only applied to scalable image formats after */ + /* the glyph has been loaded. It means that hinting is unaltered by */ + /* the transformation and is performed on the character size given in */ + /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ + /* */ + /* Note that this also transforms the `face.glyph.advance' field, but */ + /* *not* the values in `face.glyph.metrics'. */ + /* */ + FT_EXPORT( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Render_Mode */ + /* */ + /* <Description> */ + /* An enumeration type that lists the render modes supported by */ + /* FreeType~2. Each mode corresponds to a specific type of scanline */ + /* conversion performed on the outline. */ + /* */ + /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ + /* field in the @FT_GlyphSlotRec structure gives the format of the */ + /* returned bitmap. */ + /* */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ + /* */ + /* <Values> */ + /* FT_RENDER_MODE_NORMAL :: */ + /* This is the default render mode; it corresponds to 8-bit */ + /* anti-aliased bitmaps. */ + /* */ + /* FT_RENDER_MODE_LIGHT :: */ + /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ + /* defined as a separate value because render modes are also used */ + /* indirectly to define hinting algorithm selectors. See */ + /* @FT_LOAD_TARGET_XXX for details. */ + /* */ + /* FT_RENDER_MODE_MONO :: */ + /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ + /* opacity). */ + /* */ + /* FT_RENDER_MODE_LCD :: */ + /* This mode corresponds to horizontal RGB and BGR sub-pixel */ + /* displays like LCD screens. It produces 8-bit bitmaps that are */ + /* 3~times the width of the original glyph outline in pixels, and */ + /* which use the @FT_PIXEL_MODE_LCD mode. */ + /* */ + /* FT_RENDER_MODE_LCD_V :: */ + /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ + /* (like PDA screens, rotated LCD displays, etc.). It produces */ + /* 8-bit bitmaps that are 3~times the height of the original */ + /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ + /* */ + /* <Note> */ + /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ + /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ + /* (not active in the default builds). It is up to the caller to */ + /* either call @FT_Library_SetLcdFilter (if available) or do the */ + /* filtering itself. */ + /* */ + /* The selected render mode only affects vector glyphs of a font. */ + /* Embedded bitmaps often have a different pixel mode like */ + /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ + /* them into 8-bit pixmaps. */ + /* */ + typedef enum FT_Render_Mode_ + { + FT_RENDER_MODE_NORMAL = 0, + FT_RENDER_MODE_LIGHT, + FT_RENDER_MODE_MONO, + FT_RENDER_MODE_LCD, + FT_RENDER_MODE_LCD_V, + + FT_RENDER_MODE_MAX + + } FT_Render_Mode; + + + /* these constants are deprecated; use the corresponding */ + /* `FT_Render_Mode' values instead */ +#define ft_render_mode_normal FT_RENDER_MODE_NORMAL +#define ft_render_mode_mono FT_RENDER_MODE_MONO + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Render_Glyph */ + /* */ + /* <Description> */ + /* Convert a given glyph image to a bitmap. It does so by inspecting */ + /* the glyph image format, finding the relevant renderer, and */ + /* invoking it. */ + /* */ + /* <InOut> */ + /* slot :: A handle to the glyph slot containing the image to */ + /* convert. */ + /* */ + /* <Input> */ + /* render_mode :: This is the render mode used to render the glyph */ + /* image into a bitmap. See @FT_Render_Mode for a */ + /* list of possible values. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* To get meaningful results, font scaling values must be set with */ + /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Kerning_Mode */ + /* */ + /* <Description> */ + /* An enumeration used to specify which kerning values to return in */ + /* @FT_Get_Kerning. */ + /* */ + /* <Values> */ + /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ + /* distances (value is~0). */ + /* */ + /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ + /* distances. */ + /* */ + /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ + /* units. */ + /* */ + typedef enum FT_Kerning_Mode_ + { + FT_KERNING_DEFAULT = 0, + FT_KERNING_UNFITTED, + FT_KERNING_UNSCALED + + } FT_Kerning_Mode; + + + /* these constants are deprecated; use the corresponding */ + /* `FT_Kerning_Mode' values instead */ +#define ft_kerning_default FT_KERNING_DEFAULT +#define ft_kerning_unfitted FT_KERNING_UNFITTED +#define ft_kerning_unscaled FT_KERNING_UNSCALED + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Kerning */ + /* */ + /* <Description> */ + /* Return the kerning vector between two glyphs of a same face. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* kern_mode :: See @FT_Kerning_Mode for more information. */ + /* Determines the scale and dimension of the returned */ + /* kerning vector. */ + /* */ + /* <Output> */ + /* akerning :: The kerning vector. This is either in font units */ + /* or in pixels (26.6 format) for scalable formats, */ + /* and in pixels for fixed-sizes formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this method. Other layouts, or more sophisticated */ + /* kernings, are out of the scope of this API function -- they can be */ + /* implemented through format-specific interfaces. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Track_Kerning */ + /* */ + /* <Description> */ + /* Return the track kerning for a given face object at a given size. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* point_size :: The point size in 16.16 fractional points. */ + /* */ + /* degree :: The degree of tightness. Increasingly negative */ + /* values represent tighter track kerning, while */ + /* increasingly positive values represent looser track */ + /* kerning. Value zero means no track kerning. */ + /* */ + /* <Output> */ + /* akerning :: The kerning in 16.16 fractional points, to be */ + /* uniformly applied between all glyphs. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Currently, only the Type~1 font driver supports track kerning, */ + /* using data from AFM files (if attached with @FT_Attach_File or */ + /* @FT_Attach_Stream). */ + /* */ + /* Only very few AFM files come with track kerning data; please refer */ + /* to the Adobe's AFM specification for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Track_Kerning( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII name of a given glyph in a face. This only */ + /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* buffer_max :: The maximum number of bytes available in the */ + /* buffer. */ + /* */ + /* <Output> */ + /* buffer :: A pointer to a target buffer where the name is */ + /* copied to. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error is returned if the face doesn't provide glyph names or if */ + /* the glyph index is invalid. In all cases of failure, the first */ + /* byte of `buffer' is set to~0 to indicate an empty name. */ + /* */ + /* The glyph name is truncated to fit within the buffer if it is too */ + /* long. The returned string is always zero-terminated. */ + /* */ + /* Be aware that FreeType reorders glyph indices internally so that */ + /* glyph index~0 always corresponds to the `missing glyph' (called */ + /* `.notdef'). */ + /* */ + /* This function always returns an error if the config macro */ + /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoptions.h'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Postscript_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII PostScript name of a given face, if available. */ + /* This only works with PostScript and TrueType fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to the face's PostScript name. NULL if unavailable. */ + /* */ + /* <Note> */ + /* The returned pointer is owned by the face and is destroyed with */ + /* it. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Postscript_Name( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap by its encoding tag (as listed in */ + /* `freetype.h'). */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* encoding :: A handle to the selected encoding. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if no charmap in the face */ + /* corresponds to the encoding queried here. */ + /* */ + /* Because many fonts contain more than a single cmap for Unicode */ + /* encoding, this function has some special code to select the one */ + /* that covers Unicode best (`best' in the sense that a UCS-4 cmap is */ + /* preferred to a UCS-2 cmap). It is thus preferable to */ + /* @FT_Set_Charmap in this case. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap for character code to glyph index mapping. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the selected charmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if the charmap is not part of */ + /* the face (i.e., if it is not listed in the `face->charmaps' */ + /* table). */ + /* */ + /* It also fails if a type~14 charmap is selected. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ); + + + /************************************************************************* + * + * @function: + * FT_Get_Charmap_Index + * + * @description: + * Retrieve index of a given charmap. + * + * @input: + * charmap :: + * A handle to a charmap. + * + * @return: + * The index into the array of character maps within the face to which + * `charmap' belongs. If an error occurs, -1 is returned. + * + */ + FT_EXPORT( FT_Int ) + FT_Get_Charmap_Index( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Char_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code. This function */ + /* uses a charmap object to do the mapping. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within the */ + /* file. This is done to ensure that value~0 always corresponds to */ + /* the `missing glyph'. If the first glyph is not named `.notdef', */ + /* then for Type~1 and Type~42 fonts, `.notdef' will be moved into */ + /* the glyph ID~0 position, and whatever was there will be moved to */ + /* the position `.notdef' had. For Type~1 fonts, if there is no */ + /* `.notdef' glyph at all, then one will be created at index~0 and */ + /* whatever was there will be moved to the last index -- Type~42 */ + /* fonts are considered invalid under this condition. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_First_Char */ + /* */ + /* <Description> */ + /* This function is used to return the first character code in the */ + /* current charmap of a given face. It also returns the */ + /* corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of first character code. 0~if charmap is */ + /* empty. */ + /* */ + /* <Return> */ + /* The charmap's first character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_Next_Char to be able to */ + /* parse all character codes available in a given charmap. The code */ + /* should look like this: */ + /* */ + /* { */ + /* FT_ULong charcode; */ + /* FT_UInt gindex; */ + /* */ + /* */ + /* charcode = FT_Get_First_Char( face, &gindex ); */ + /* while ( gindex != 0 ) */ + /* { */ + /* ... do something with (charcode,gindex) pair ... */ + /* */ + /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ + /* } */ + /* } */ + /* */ + /* Note that `*agindex' is set to~0 if the charmap is empty. The */ + /* result itself can be~0 in two cases: if the charmap is empty or */ + /* if the value~0 is the first valid character code. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Next_Char */ + /* */ + /* <Description> */ + /* This function is used to return the next character code in the */ + /* current charmap of a given face following the value `char_code', */ + /* as well as the corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* char_code :: The starting character code. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of next character code. 0~if charmap */ + /* is empty. */ + /* */ + /* <Return> */ + /* The charmap's next character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_First_Char to walk */ + /* over all character codes available in a given charmap. See the */ + /* note for this function for a simple code example. */ + /* */ + /* Note that `*agindex' is set to~0 when there are no more codes in */ + /* the charmap. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong char_code, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Name_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given glyph name. This function uses */ + /* driver specific objects to do the translation. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* glyph_name :: The glyph name. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ); + + + /************************************************************************* + * + * @macro: + * FT_SUBGLYPH_FLAG_XXX + * + * @description: + * A list of constants used to describe subglyphs. Please refer to the + * TrueType specification for the meaning of the various flags. + * + * @values: + * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: + * FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES :: + * FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID :: + * FT_SUBGLYPH_FLAG_SCALE :: + * FT_SUBGLYPH_FLAG_XY_SCALE :: + * FT_SUBGLYPH_FLAG_2X2 :: + * FT_SUBGLYPH_FLAG_USE_MY_METRICS :: + * + */ +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 + + + /************************************************************************* + * + * @func: + * FT_Get_SubGlyph_Info + * + * @description: + * Retrieve a description of a given subglyph. Only use it if + * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is + * returned otherwise. + * + * @input: + * glyph :: + * The source glyph slot. + * + * sub_index :: + * The index of the subglyph. Must be less than + * `glyph->num_subglyphs'. + * + * @output: + * p_index :: + * The glyph index of the subglyph. + * + * p_flags :: + * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. + * + * p_arg1 :: + * The subglyph's first argument (if any). + * + * p_arg2 :: + * The subglyph's second argument (if any). + * + * p_transform :: + * The subglyph transformation (if any). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be + * interpreted depending on the flags returned in `*p_flags'. See the + * TrueType specification for details. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, + FT_UInt sub_index, + FT_Int *p_index, + FT_UInt *p_flags, + FT_Int *p_arg1, + FT_Int *p_arg2, + FT_Matrix *p_transform ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FSTYPE_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `fsType' field of the OS/2 table */ + /* in a TrueType or OpenType font and the `FSType' entry in a */ + /* PostScript font. These bit flags are returned by */ + /* @FT_Get_FSType_Flags; they inform client applications of embedding */ + /* and subsetting restrictions associated with a font. */ + /* */ + /* See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for */ + /* more details. */ + /* */ + /* <Values> */ + /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ + /* Fonts with no fsType bit set may be embedded and permanently */ + /* installed on the remote system by an application. */ + /* */ + /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ + /* Fonts that have only this bit set must not be modified, embedded */ + /* or exchanged in any manner without first obtaining permission of */ + /* the font software copyright owner. */ + /* */ + /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ + /* If this bit is set, the font may be embedded and temporarily */ + /* loaded on the remote system. Documents containing Preview & */ + /* Print fonts must be opened `read-only'; no edits can be applied */ + /* to the document. */ + /* */ + /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ + /* If this bit is set, the font may be embedded but must only be */ + /* installed temporarily on other systems. In contrast to Preview */ + /* & Print fonts, documents containing editable fonts may be opened */ + /* for reading, editing is permitted, and changes may be saved. */ + /* */ + /* FT_FSTYPE_NO_SUBSETTING :: */ + /* If this bit is set, the font may not be subsetted prior to */ + /* embedding. */ + /* */ + /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ + /* If this bit is set, only bitmaps contained in the font may be */ + /* embedded; no outline data may be embedded. If there are no */ + /* bitmaps available in the font, then the font is unembeddable. */ + /* */ + /* <Note> */ + /* While the fsType flags can indicate that a font may be embedded, a */ + /* license with the font vendor may be separately required to use the */ + /* font in this way. */ + /* */ +#define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 +#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 +#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 +#define FT_FSTYPE_EDITABLE_EMBEDDING 0x0008 +#define FT_FSTYPE_NO_SUBSETTING 0x0100 +#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_FSType_Flags */ + /* */ + /* <Description> */ + /* Return the fsType flags for a font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* The fsType flags, @FT_FSTYPE_XXX. */ + /* */ + /* <Note> */ + /* Use this function rather than directly reading the `fs_type' field */ + /* in the @PS_FontInfoRec structure, which is only guaranteed to */ + /* return the correct results for Type~1 fonts. */ + /* */ + /* <Since> */ + /* 2.3.8 */ + /* */ + FT_EXPORT( FT_UShort ) + FT_Get_FSType_Flags( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_variants */ + /* */ + /* <Title> */ + /* Glyph Variants */ + /* */ + /* <Abstract> */ + /* The FreeType~2 interface to Unicode Ideographic Variation */ + /* Sequences (IVS), using the SFNT cmap format~14. */ + /* */ + /* <Description> */ + /* Many CJK characters have variant forms. They are a sort of grey */ + /* area somewhere between being totally irrelevant and semantically */ + /* distinct; for this reason, the Unicode consortium decided to */ + /* introduce Ideographic Variation Sequences (IVS), consisting of a */ + /* Unicode base character and one of 240 variant selectors */ + /* (U+E0100-U+E01EF), instead of further extending the already huge */ + /* code range for CJK characters. */ + /* */ + /* An IVS is registered and unique; for further details please refer */ + /* to Unicode Technical Standard #37, the Ideographic Variation */ + /* Database: */ + /* */ + /* http://www.unicode.org/reports/tr37/ */ + /* */ + /* To date (November 2014), the character with the most variants is */ + /* U+9089, having 32 such IVS. */ + /* */ + /* Adobe and MS decided to support IVS with a new cmap subtable */ + /* (format~14). It is an odd subtable because it is not a mapping of */ + /* input code points to glyphs, but contains lists of all variants */ + /* supported by the font. */ + /* */ + /* A variant may be either `default' or `non-default'. A default */ + /* variant is the one you will get for that code point if you look it */ + /* up in the standard Unicode cmap. A non-default variant is a */ + /* different glyph. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIndex */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code as modified by */ + /* the variation selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character code point in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode code point of the variation selector. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means either `undefined character code', or */ + /* `undefined selector code', or `no variation selector cmap */ + /* subtable', or `current CharMap is not Unicode'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + /* This function is only meaningful if */ + /* a) the font has a variation selector cmap sub table, */ + /* and */ + /* b) the current charmap has a Unicode encoding. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIsDefault */ + /* */ + /* <Description> */ + /* Check whether this variant of this Unicode character is the one to */ + /* be found in the `cmap'. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode codepoint of the variation selector. */ + /* */ + /* <Return> */ + /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ + /* variation selector cmap, or -1 if it is not a variant. */ + /* */ + /* <Note> */ + /* This function is only meaningful if the font has a variation */ + /* selector cmap subtable. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantSelectors */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* in the font. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to an array of selector code points, or NULL if there is */ + /* no valid variant selector cmap subtable. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantsOfChar */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* for the specified character code. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* <Return> */ + /* A pointer to an array of variant selector code points that are */ + /* active for the given character, or NULL if the corresponding list */ + /* is empty. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharsOfVariant */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode character codes found for */ + /* the specified variant selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* variantSelector :: */ + /* The variant selector code point in Unicode. */ + /* */ + /* <Return> */ + /* A list of all the code points that are specified by this selector */ + /* (both default and non-default codes are returned) or NULL if there */ + /* is no valid cmap or the variant selector is invalid. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /* <Title> */ + /* Computations */ + /* */ + /* <Abstract> */ + /* Crunching fixed numbers and vectors. */ + /* */ + /* <Description> */ + /* This section contains various functions used to perform */ + /* computations on 16.16 fixed-float numbers or 2d vectors. */ + /* */ + /* <Order> */ + /* FT_MulDiv */ + /* FT_MulFix */ + /* FT_DivFix */ + /* FT_RoundFix */ + /* FT_CeilFix */ + /* FT_FloorFix */ + /* FT_Vector_Transform */ + /* FT_Matrix_Multiply */ + /* FT_Matrix_Invert */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* with maximum accuracy (it uses a 64-bit intermediate integer */ + /* whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */ + /* used to multiply a given value by a 16.16 fixed-point factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*b)/0x10000'. */ + /* */ + /* <Note> */ + /* This function has been optimized for the case where the absolute */ + /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ + /* As this happens mainly when scaling from notional units to */ + /* fractional pixels in FreeType, it resulted in noticeable speed */ + /* improvements between versions 2.x and 1.x. */ + /* */ + /* As a conclusion, always try to place a 16.16 factor as the */ + /* _second_ argument of this function; this can make a great */ + /* difference. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_DivFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */ + /* used to divide a given value by a 16.16 fixed-point factor. */ + /* */ + /* <Input> */ + /* a :: The numerator. */ + /* b :: The denominator. Use a 16.16 factor here. */ + /* */ + /* <Return> */ + /* The result of `(a*0x10000)/b'. */ + /* */ + FT_EXPORT( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_RoundFix */ + /* */ + /* <Description> */ + /* A very simple function used to round a 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number to be rounded. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x8000) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_RoundFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_CeilFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the ceiling function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the ceiling function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x10000 - 1) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_CeilFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FloorFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the floor function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the floor function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `a & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_FloorFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Vector_Transform */ + /* */ + /* <Description> */ + /* Transform a single vector through a 2x2 matrix. */ + /* */ + /* <InOut> */ + /* vector :: The target vector to transform. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the source 2x2 matrix. */ + /* */ + /* <Note> */ + /* The result is undefined if either `vector' or `matrix' is invalid. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Transform( FT_Vector* vec, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* version */ + /* */ + /* <Title> */ + /* FreeType Version */ + /* */ + /* <Abstract> */ + /* Functions and macros related to FreeType versions. */ + /* */ + /* <Description> */ + /* Note that those functions and macros are of limited use because */ + /* even a new release of FreeType with only documentation changes */ + /* increases the version number. */ + /* */ + /* <Order> */ + /* FT_Library_Version */ + /* */ + /* FREETYPE_MAJOR */ + /* FREETYPE_MINOR */ + /* FREETYPE_PATCH */ + /* */ + /* FT_Face_CheckTrueTypePatents */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* FREETYPE_XXX */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FREETYPE_XXX + * + * @description: + * These three macros identify the FreeType source code version. + * Use @FT_Library_Version to access them at runtime. + * + * @values: + * FREETYPE_MAJOR :: The major version number. + * FREETYPE_MINOR :: The minor version number. + * FREETYPE_PATCH :: The patch level. + * + * @note: + * The version number of FreeType if built as a dynamic link library + * with the `libtool' package is _not_ controlled by these three + * macros. + * + */ +#define FREETYPE_MAJOR 2 +#define FREETYPE_MINOR 5 +#define FREETYPE_PATCH 5 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Library_Version */ + /* */ + /* <Description> */ + /* Return the version of the FreeType library being used. This is */ + /* useful when dynamically linking to the library, since one cannot */ + /* use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and */ + /* @FREETYPE_PATCH. */ + /* */ + /* <Input> */ + /* library :: A source library handle. */ + /* */ + /* <Output> */ + /* amajor :: The major version number. */ + /* */ + /* aminor :: The minor version number. */ + /* */ + /* apatch :: The patch version number. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' argument is because */ + /* certain programs implement library initialization in a custom way */ + /* that doesn't use @FT_Init_FreeType. */ + /* */ + /* In such cases, the library version might not be available before */ + /* the library object has been created. */ + /* */ + FT_EXPORT( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_CheckTrueTypePatents */ + /* */ + /* <Description> */ + /* Parse all bytecode instructions of a TrueType font file to check */ + /* whether any of the patented opcodes are used. This is only useful */ + /* if you want to be able to use the unpatented hinter with */ + /* fonts that do *not* use these opcodes. */ + /* */ + /* Note that this function parses *all* glyph instructions in the */ + /* font file, which may be slow. */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* <Return> */ + /* 1~if this is a TrueType font that uses one of the patented */ + /* opcodes, 0~otherwise. */ + /* */ + /* <Note> */ + /* Since May 2010, TrueType hinting is no longer patented. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_CheckTrueTypePatents( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* <Description> */ + /* Enable or disable the unpatented hinter for a given face. */ + /* Only enable it if you have determined that the face doesn't */ + /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* value :: New boolean setting. */ + /* */ + /* <Return> */ + /* The old setting value. This will always be false if this is not */ + /* an SFNT font, or if the unpatented hinter is not compiled in this */ + /* instance of the library. */ + /* */ + /* <Note> */ + /* Since May 2010, TrueType hinting is no longer patented. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_SetUnpatentedHinting( FT_Face face, + FT_Bool value ); + + /* */ + + +FT_END_HEADER + +#endif /* __FREETYPE_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ft2build.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ft2build.h new file mode 100644 index 00000000..6f8eb7f3 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ft2build.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* */ +/* Copyright 1996-2001, 2006, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This is the `entry point' for FreeType header file inclusions. It is */ + /* the only header file which should be included directly; all other */ + /* FreeType header files should be accessed with macro names (after */ + /* including `ft2build.h'). */ + /* */ + /* A typical example is */ + /* */ + /* #include <ft2build.h> */ + /* #include FT_FREETYPE_H */ + /* */ + /*************************************************************************/ + + +#ifndef __FT2BUILD_H__ +#define __FT2BUILD_H__ + +#include <config/ftheader.h> + +#endif /* __FT2BUILD_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftadvanc.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftadvanc.h new file mode 100644 index 00000000..955f93fa --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftadvanc.h @@ -0,0 +1,187 @@ +/***************************************************************************/ +/* */ +/* ftadvanc.h */ +/* */ +/* Quick computation of advance widths (specification only). */ +/* */ +/* Copyright 2008, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTADVANC_H__ +#define __FTADVANC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * quick_advance + * + * @title: + * Quick retrieval of advance values + * + * @abstract: + * Retrieve horizontal and vertical advance values without processing + * glyph outlines, if possible. + * + * @description: + * This section contains functions to quickly extract advance values + * without handling glyph outlines, if possible. + * + * @order: + * FT_Get_Advance + * FT_Get_Advances + * + */ + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* FT_ADVANCE_FLAG_FAST_ONLY */ + /* */ + /* <Description> */ + /* A bit-flag to be OR-ed with the `flags' parameter of the */ + /* @FT_Get_Advance and @FT_Get_Advances functions. */ + /* */ + /* If set, it indicates that you want these functions to fail if the */ + /* corresponding hinting mode or font driver doesn't allow for very */ + /* quick advance computation. */ + /* */ + /* Typically, glyphs that are either unscaled, unhinted, bitmapped, */ + /* or light-hinted can have their advance width computed very */ + /* quickly. */ + /* */ + /* Normal and bytecode hinted modes that require loading, scaling, */ + /* and hinting of the glyph outline, are extremely slow by */ + /* comparison. */ + /* */ +#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000UL + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advance */ + /* */ + /* <Description> */ + /* Retrieve the advance value of a given glyph outline in an */ + /* @FT_Face. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph, used to determine what kind */ + /* of advances you need. */ + /* <Output> */ + /* padvance :: The advance value. If scaling is performed (based on */ + /* the value of `load_flags'), the advance value is in */ + /* 16.16 format. Otherwise, it is in font units. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ + /* vertical advance corresponding to a vertical layout. */ + /* Otherwise, it is the horizontal advance in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* A scaled advance is returned in 16.16 format but isn't transformed */ + /* by the affine transformation specified by @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advance( FT_Face face, + FT_UInt gindex, + FT_Int32 load_flags, + FT_Fixed *padvance ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Advances */ + /* */ + /* <Description> */ + /* Retrieve the advance values of several glyph outlines in an */ + /* @FT_Face. */ + /* */ + /* <Input> */ + /* face :: The source @FT_Face handle. */ + /* */ + /* start :: The first glyph index. */ + /* */ + /* count :: The number of advance values you want to retrieve. */ + /* */ + /* load_flags :: A set of bit flags similar to those used when */ + /* calling @FT_Load_Glyph. */ + /* */ + /* <Output> */ + /* padvance :: The advance values. This array, to be provided by the */ + /* caller, must contain at least `count' elements. */ + /* */ + /* If scaling is performed (based on the value of */ + /* `load_flags'), the advance values are in 16.16 format. */ + /* Otherwise, they are in font units. */ + /* */ + /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ + /* vertical advances corresponding to a vertical layout. */ + /* Otherwise, they are the horizontal advances in a */ + /* horizontal layout. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ + /* if the corresponding font backend doesn't have a quick way to */ + /* retrieve the advances. */ + /* */ + /* Scaled advances are returned in 16.16 format but aren't */ + /* transformed by the affine transformation specified by */ + /* @FT_Set_Transform. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Advances( FT_Face face, + FT_UInt start, + FT_UInt count, + FT_Int32 load_flags, + FT_Fixed *padvances ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTADVANC_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftautoh.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftautoh.h new file mode 100644 index 00000000..59191abb --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftautoh.h @@ -0,0 +1,402 @@ +/***************************************************************************/ +/* */ +/* ftautoh.h */ +/* */ +/* FreeType API for controlling the auto-hinter (specification only). */ +/* */ +/* Copyright 2012, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTAUTOH_H__ +#define __FTAUTOH_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * auto_hinter + * + * @title: + * The auto-hinter + * + * @abstract: + * Controlling the auto-hinting module. + * + * @description: + * While FreeType's auto-hinter doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * Note that the auto-hinter's module name is `autofitter' for + * historical reasons. + * + */ + + + /************************************************************************** + * + * @property: + * glyph-to-script-map + * + * @description: + * *Experimental* *only* + * + * The auto-hinter provides various script modules to hint glyphs. + * Examples of supported scripts are Latin or CJK. Before a glyph is + * auto-hinted, the Unicode character map of the font gets examined, and + * the script is then determined based on Unicode character ranges, see + * below. + * + * OpenType fonts, however, often provide much more glyphs than + * character codes (small caps, superscripts, ligatures, swashes, etc.), + * to be controlled by so-called `features'. Handling OpenType features + * can be quite complicated and thus needs a separate library on top of + * FreeType. + * + * The mapping between glyph indices and scripts (in the auto-hinter + * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an + * array with `num_glyphs' elements, as found in the font's @FT_Face + * structure. The `glyph-to-script-map' property returns a pointer to + * this array, which can be modified as needed. Note that the + * modification should happen before the first glyph gets processed by + * the auto-hinter so that the global analysis of the font shapes + * actually uses the modified mapping. + * + * The following example code demonstrates how to access it (omitting + * the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_GlyphToScriptMap prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * + * prop.face = face; + * + * FT_Property_Get( library, "autofitter", + * "glyph-to-script-map", &prop ); + * + * // adjust `prop.map' as needed right here + * + * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT ); + * } + * + */ + + + /************************************************************************** + * + * @enum: + * FT_AUTOHINTER_SCRIPT_XXX + * + * @description: + * *Experimental* *only* + * + * A list of constants used for the @glyph-to-script-map property to + * specify the script submodule the auto-hinter should use for hinting a + * particular glyph. + * + * @values: + * FT_AUTOHINTER_SCRIPT_NONE :: + * Don't auto-hint this glyph. + * + * FT_AUTOHINTER_SCRIPT_LATIN :: + * Apply the latin auto-hinter. For the auto-hinter, `latin' is a + * very broad term, including Cyrillic and Greek also since characters + * from those scripts share the same design constraints. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0020 - U+007F // Basic Latin (no control characters) + * U+00A0 - U+00FF // Latin-1 Supplement (no control characters) + * U+0100 - U+017F // Latin Extended-A + * U+0180 - U+024F // Latin Extended-B + * U+0250 - U+02AF // IPA Extensions + * U+02B0 - U+02FF // Spacing Modifier Letters + * U+0300 - U+036F // Combining Diacritical Marks + * U+0370 - U+03FF // Greek and Coptic + * U+0400 - U+04FF // Cyrillic + * U+0500 - U+052F // Cyrillic Supplement + * U+1D00 - U+1D7F // Phonetic Extensions + * U+1D80 - U+1DBF // Phonetic Extensions Supplement + * U+1DC0 - U+1DFF // Combining Diacritical Marks Supplement + * U+1E00 - U+1EFF // Latin Extended Additional + * U+1F00 - U+1FFF // Greek Extended + * U+2000 - U+206F // General Punctuation + * U+2070 - U+209F // Superscripts and Subscripts + * U+20A0 - U+20CF // Currency Symbols + * U+2150 - U+218F // Number Forms + * U+2460 - U+24FF // Enclosed Alphanumerics + * U+2C60 - U+2C7F // Latin Extended-C + * U+2DE0 - U+2DFF // Cyrillic Extended-A + * U+2E00 - U+2E7F // Supplemental Punctuation + * U+A640 - U+A69F // Cyrillic Extended-B + * U+A720 - U+A7FF // Latin Extended-D + * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligatures) + * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols + * U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_CJK :: + * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old + * Vietnamese, and some other scripts. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+1100 - U+11FF // Hangul Jamo + * U+2E80 - U+2EFF // CJK Radicals Supplement + * U+2F00 - U+2FDF // Kangxi Radicals + * U+2FF0 - U+2FFF // Ideographic Description Characters + * U+3000 - U+303F // CJK Symbols and Punctuation + * U+3040 - U+309F // Hiragana + * U+30A0 - U+30FF // Katakana + * U+3100 - U+312F // Bopomofo + * U+3130 - U+318F // Hangul Compatibility Jamo + * U+3190 - U+319F // Kanbun + * U+31A0 - U+31BF // Bopomofo Extended + * U+31C0 - U+31EF // CJK Strokes + * U+31F0 - U+31FF // Katakana Phonetic Extensions + * U+3200 - U+32FF // Enclosed CJK Letters and Months + * U+3300 - U+33FF // CJK Compatibility + * U+3400 - U+4DBF // CJK Unified Ideographs Extension A + * U+4DC0 - U+4DFF // Yijing Hexagram Symbols + * U+4E00 - U+9FFF // CJK Unified Ideographs + * U+A960 - U+A97F // Hangul Jamo Extended-A + * U+AC00 - U+D7AF // Hangul Syllables + * U+D7B0 - U+D7FF // Hangul Jamo Extended-B + * U+F900 - U+FAFF // CJK Compatibility Ideographs + * U+FE10 - U+FE1F // Vertical forms + * U+FE30 - U+FE4F // CJK Compatibility Forms + * U+FF00 - U+FFEF // Halfwidth and Fullwidth Forms + * U+1B000 - U+1B0FF // Kana Supplement + * U+1D300 - U+1D35F // Tai Xuan Hing Symbols + * U+1F200 - U+1F2FF // Enclosed Ideographic Supplement + * U+20000 - U+2A6DF // CJK Unified Ideographs Extension B + * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C + * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D + * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_INDIC :: + * Apply the indic auto-hinter, covering all major scripts from the + * Indian sub-continent and some other related scripts like Thai, Lao, + * or Tibetan. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0900 - U+0DFF // Indic Range + * U+0F00 - U+0FFF // Tibetan + * U+1900 - U+194F // Limbu + * U+1B80 - U+1BBF // Sundanese + * U+1C80 - U+1CDF // Meetei Mayak + * U+A800 - U+A82F // Syloti Nagri + * U+11800 - U+118DF // Sharada + * } + * + * Note that currently Indic support is rudimentary only, missing blue + * zone support. + * + */ +#define FT_AUTOHINTER_SCRIPT_NONE 0 +#define FT_AUTOHINTER_SCRIPT_LATIN 1 +#define FT_AUTOHINTER_SCRIPT_CJK 2 +#define FT_AUTOHINTER_SCRIPT_INDIC 3 + + + /************************************************************************** + * + * @struct: + * FT_Prop_GlyphToScriptMap + * + * @description: + * *Experimental* *only* + * + * The data exchange structure for the @glyph-to-script-map property. + * + */ + typedef struct FT_Prop_GlyphToScriptMap_ + { + FT_Face face; + FT_Byte* map; + + } FT_Prop_GlyphToScriptMap; + + + /************************************************************************** + * + * @property: + * fallback-script + * + * @description: + * *Experimental* *only* + * + * If no auto-hinter script module can be assigned to a glyph, a + * fallback script gets assigned to it (see also the + * @glyph-to-script-map property). By default, this is + * @FT_AUTOHINTER_SCRIPT_CJK. Using the `fallback-script' property, + * this fallback value can be changed. + * + * { + * FT_Library library; + * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "fallback-script", &fallback_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * fallback script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the fallback script will affect this face. + * + */ + + + /************************************************************************** + * + * @property: + * default-script + * + * @description: + * *Experimental* *only* + * + * If Freetype gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make + * the HarfBuzz library access OpenType features for getting better + * glyph coverages, this property sets the (auto-fitter) script to be + * used for the default (OpenType) script data of a font's GSUB table. + * Features for the default script are intended for all scripts not + * explicitly handled in GSUB; an example is a `dlig' feature, + * containing the combination of the characters `T', `E', and `L' to + * form a `TEL' ligature. + * + * By default, this is @FT_AUTOHINTER_SCRIPT_LATIN. Using the + * `default-script' property, this default value can be changed. + * + * { + * FT_Library library; + * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "default-script", &default_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * default script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the default script will affect this face. + * + */ + + + /************************************************************************** + * + * @property: + * increase-x-height + * + * @description: + * For ppem values in the range 6~<= ppem <= `increase-x-height', round + * up the font's x~height much more often than normally. If the value + * is set to~0, which is the default, this feature is switched off. Use + * this property to improve the legibility of small font sizes if + * necessary. + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_IncreaseXHeight prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * FT_Set_Char_Size( face, 10 * 64, 0, 72, 0 ); + * + * prop.face = face; + * prop.limit = 14; + * + * FT_Property_Set( library, "autofitter", + * "increase-x-height", &prop ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * Set this value right after calling @FT_Set_Char_Size, but before + * loading any glyph (using the auto-hinter). + * + */ + + + /************************************************************************** + * + * @struct: + * FT_Prop_IncreaseXHeight + * + * @description: + * The data exchange structure for the @increase-x-height property. + * + */ + typedef struct FT_Prop_IncreaseXHeight_ + { + FT_Face face; + FT_UInt limit; + + } FT_Prop_IncreaseXHeight; + + /* */ + + +FT_END_HEADER + +#endif /* __FTAUTOH_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbbox.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbbox.h new file mode 100644 index 00000000..d6800e24 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbbox.h @@ -0,0 +1,101 @@ +/***************************************************************************/ +/* */ +/* ftbbox.h */ +/* */ +/* FreeType exact bbox computation (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2007, 2011, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This component has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /* It is separated from the rest of the engine for various technical */ + /* reasons. It may well be integrated in `ftoutln' later. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTBBOX_H__ +#define __FTBBOX_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_BBox */ + /* */ + /* <Description> */ + /* Compute the exact bounding box of an outline. This is slower */ + /* than computing the control box. However, it uses an advanced */ + /* algorithm that returns _very_ quickly when the two boxes */ + /* coincide. Otherwise, the outline Bézier arcs are traversed to */ + /* extract their extrema. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline. */ + /* */ + /* <Output> */ + /* abbox :: The outline's exact bounding box. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If the font is tricky and the glyph has been loaded with */ + /* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */ + /* reasonable values for the BBox it is necessary to load the glyph */ + /* at a large ppem value (so that the hinting instructions can */ + /* properly shift and scale the subglyphs), then extracting the BBox, */ + /* which can be eventually converted back to font units. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTBBOX_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbdf.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbdf.h new file mode 100644 index 00000000..6d262e41 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbdf.h @@ -0,0 +1,210 @@ +/***************************************************************************/ +/* */ +/* ftbdf.h */ +/* */ +/* FreeType API for accessing BDF-specific strings (specification). */ +/* */ +/* Copyright 2002-2004, 2006, 2009, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBDF_H__ +#define __FTBDF_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bdf_fonts */ + /* */ + /* <Title> */ + /* BDF and PCF Files */ + /* */ + /* <Abstract> */ + /* BDF and PCF specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions specific to BDF */ + /* and PCF fonts. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * BDF_PropertyType + * + * @description: + * A list of BDF property types. + * + * @values: + * BDF_PROPERTY_TYPE_NONE :: + * Value~0 is used to indicate a missing property. + * + * BDF_PROPERTY_TYPE_ATOM :: + * Property is a string atom. + * + * BDF_PROPERTY_TYPE_INTEGER :: + * Property is a 32-bit signed integer. + * + * BDF_PROPERTY_TYPE_CARDINAL :: + * Property is a 32-bit unsigned integer. + */ + typedef enum BDF_PropertyType_ + { + BDF_PROPERTY_TYPE_NONE = 0, + BDF_PROPERTY_TYPE_ATOM = 1, + BDF_PROPERTY_TYPE_INTEGER = 2, + BDF_PROPERTY_TYPE_CARDINAL = 3 + + } BDF_PropertyType; + + + /********************************************************************** + * + * @type: + * BDF_Property + * + * @description: + * A handle to a @BDF_PropertyRec structure to model a given + * BDF/PCF property. + */ + typedef struct BDF_PropertyRec_* BDF_Property; + + + /********************************************************************** + * + * @struct: + * BDF_PropertyRec + * + * @description: + * This structure models a given BDF/PCF property. + * + * @fields: + * type :: + * The property type. + * + * u.atom :: + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be + * NULL, indicating an empty string. + * + * u.integer :: + * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. + * + * u.cardinal :: + * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. + */ + typedef struct BDF_PropertyRec_ + { + BDF_PropertyType type; + union { + const char* atom; + FT_Int32 integer; + FT_UInt32 cardinal; + + } u; + + } BDF_PropertyRec; + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Charset_ID + * + * @description: + * Retrieve a BDF font character set identity, according to + * the BDF specification. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * acharset_encoding :: + * Charset encoding, as a C~string, owned by the face. + * + * acharset_registry :: + * Charset registry, as a C~string, owned by the face. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with BDF faces, returning an error otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Property + * + * @description: + * Retrieve a BDF property from a BDF or PCF font file. + * + * @input: + * face :: A handle to the input face. + * + * name :: The property name. + * + * @output: + * aproperty :: The property. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function works with BDF _and_ PCF fonts. It returns an error + * otherwise. It also returns an error if the property is not in the + * font. + * + * A `property' is a either key-value pair within the STARTPROPERTIES + * ... ENDPROPERTIES block of a BDF font or a key-value pair from the + * `info->props' array within a `FontRec' structure of a PCF font. + * + * Integer properties are always stored as `signed' within PCF fonts; + * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value + * for BDF fonts only. + * + * In case of error, `aproperty->type' is always set to + * @BDF_PROPERTY_TYPE_NONE. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + /* */ + +FT_END_HEADER + +#endif /* __FTBDF_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbitmap.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbitmap.h new file mode 100644 index 00000000..eae71690 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbitmap.h @@ -0,0 +1,232 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.h */ +/* */ +/* FreeType utility functions for bitmaps (specification). */ +/* */ +/* Copyright 2004-2006, 2008, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBITMAP_H__ +#define __FTBITMAP_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bitmap_handling */ + /* */ + /* <Title> */ + /* Bitmap Handling */ + /* */ + /* <Abstract> */ + /* Handling FT_Bitmap objects. */ + /* */ + /* <Description> */ + /* This section contains functions for handling @FT_Bitmap objects. */ + /* Note that none of the functions changes the bitmap's `flow' (as */ + /* indicated by the sign of the `pitch' field in `FT_Bitmap'). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_New */ + /* */ + /* <Description> */ + /* Initialize a pointer to an @FT_Bitmap structure. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the bitmap structure. */ + /* */ + FT_EXPORT( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Copy */ + /* */ + /* <Description> */ + /* Copy a bitmap into another one. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: A handle to the source bitmap. */ + /* */ + /* <Output> */ + /* target :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Copy( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Embolden */ + /* */ + /* <Description> */ + /* Embolden a bitmap. The new bitmap will be about `xStrength' */ + /* pixels wider and `yStrength' pixels higher. The left and bottom */ + /* borders are kept unchanged. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* xStrength :: How strong the glyph is emboldened horizontally. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* yStrength :: How strong the glyph is emboldened vertically. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* <InOut> */ + /* bitmap :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The current implementation restricts `xStrength' to be less than */ + /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ + /* */ + /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ + /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ + /* */ + /* Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format */ + /* are converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Embolden( FT_Library library, + FT_Bitmap* bitmap, + FT_Pos xStrength, + FT_Pos yStrength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Convert */ + /* */ + /* <Description> */ + /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp */ + /* to a bitmap object with depth 8bpp, making the number of used */ + /* bytes line (a.k.a. the `pitch') a multiple of `alignment'. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: The source bitmap. */ + /* */ + /* alignment :: The pitch of the bitmap is a multiple of this */ + /* parameter. Common values are 1, 2, or 4. */ + /* */ + /* <Output> */ + /* target :: The target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* It is possible to call @FT_Bitmap_Convert multiple times without */ + /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ + /* */ + /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ + /* */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GlyphSlot_Own_Bitmap */ + /* */ + /* <Description> */ + /* Make sure that a glyph slot owns `slot->bitmap'. */ + /* */ + /* <Input> */ + /* slot :: The glyph slot. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function is to be used in combination with */ + /* @FT_Bitmap_Embolden. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Done */ + /* */ + /* <Description> */ + /* Destroy a bitmap object created with @FT_Bitmap_New. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* bitmap :: The bitmap object to be freed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBITMAP_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbzip2.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbzip2.h new file mode 100644 index 00000000..4dce161f --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftbzip2.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* ftbzip2.h */ +/* */ +/* Bzip2-compressed stream support. */ +/* */ +/* Copyright 2010 by */ +/* Joel Klinghed. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBZIP2_H__ +#define __FTBZIP2_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bzip2 */ + /* */ + /* <Title> */ + /* BZIP2 Streams */ + /* */ + /* <Abstract> */ + /* Using bzip2-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Bzip2-specific functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************ + * + * @function: + * FT_Stream_OpenBzip2 + * + * @description: + * Open a new stream to parse bzip2-compressed font files. This is + * mainly used to support the compressed `*.pcf.bz2' fonts that come + * with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, bzip2 compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a bzip2 compressed stream + * from it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with bzip2 support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenBzip2( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTBZIP2_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcache.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcache.h new file mode 100644 index 00000000..a30e925c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcache.h @@ -0,0 +1,1057 @@ +/***************************************************************************/ +/* */ +/* ftcache.h */ +/* */ +/* FreeType Cache subsystem (specification). */ +/* */ +/* Copyright 1996-2008, 2010, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCACHE_H__ +#define __FTCACHE_H__ + + +#include <ft2build.h> +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************* + * + * <Section> + * cache_subsystem + * + * <Title> + * Cache Sub-System + * + * <Abstract> + * How to cache face, size, and glyph data with FreeType~2. + * + * <Description> + * This section describes the FreeType~2 cache sub-system, which is used + * to limit the number of concurrently opened @FT_Face and @FT_Size + * objects, as well as caching information like character maps and glyph + * images while limiting their maximum memory usage. + * + * Note that all types and functions begin with the `FTC_' prefix. + * + * The cache is highly portable and thus doesn't know anything about the + * fonts installed on your system, or how to access them. This implies + * the following scheme: + * + * First, available or installed font faces are uniquely identified by + * @FTC_FaceID values, provided to the cache by the client. Note that + * the cache only stores and compares these values, and doesn't try to + * interpret them in any way. + * + * Second, the cache calls, only when needed, a client-provided function + * to convert an @FTC_FaceID into a new @FT_Face object. The latter is + * then completely managed by the cache, including its termination + * through @FT_Done_Face. To monitor termination of face objects, the + * finalizer callback in the `generic' field of the @FT_Face object can + * be used, which might also be used to store the @FTC_FaceID of the + * face. + * + * Clients are free to map face IDs to anything else. The most simple + * usage is to associate them to a (pathname,face_index) pair that is + * used to call @FT_New_Face. However, more complex schemes are also + * possible. + * + * Note that for the cache to work correctly, the face ID values must be + * *persistent*, which means that the contents they point to should not + * change at runtime, or that their value should not become invalid. + * + * If this is unavoidable (e.g., when a font is uninstalled at runtime), + * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let + * the cache get rid of any references to the old @FTC_FaceID it may + * keep internally. Failure to do so will lead to incorrect behaviour + * or even crashes. + * + * To use the cache, start with calling @FTC_Manager_New to create a new + * @FTC_Manager object, which models a single cache instance. You can + * then look up @FT_Face and @FT_Size objects with + * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively. + * + * If you want to use the charmap caching, call @FTC_CMapCache_New, then + * later use @FTC_CMapCache_Lookup to perform the equivalent of + * @FT_Get_Char_Index, only much faster. + * + * If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then + * later use @FTC_ImageCache_Lookup to retrieve the corresponding + * @FT_Glyph objects from the cache. + * + * If you need lots of small bitmaps, it is much more memory efficient + * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This + * returns @FTC_SBitRec structures, which are used to store small + * bitmaps directly. (A small bitmap is one whose metrics and + * dimensions all fit into 8-bit integers). + * + * We hope to also provide a kerning cache in the near future. + * + * + * <Order> + * FTC_Manager + * FTC_FaceID + * FTC_Face_Requester + * + * FTC_Manager_New + * FTC_Manager_Reset + * FTC_Manager_Done + * FTC_Manager_LookupFace + * FTC_Manager_LookupSize + * FTC_Manager_RemoveFaceID + * + * FTC_Node + * FTC_Node_Unref + * + * FTC_ImageCache + * FTC_ImageCache_New + * FTC_ImageCache_Lookup + * + * FTC_SBit + * FTC_SBitCache + * FTC_SBitCache_New + * FTC_SBitCache_Lookup + * + * FTC_CMapCache + * FTC_CMapCache_New + * FTC_CMapCache_Lookup + * + *************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC TYPE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: FTC_FaceID + * + * @description: + * An opaque pointer type that is used to identity face objects. The + * contents of such objects is application-dependent. + * + * These pointers are typically used to point to a user-defined + * structure containing a font file path, and face index. + * + * @note: + * Never use NULL as a valid @FTC_FaceID. + * + * Face IDs are passed by the client to the cache manager that calls, + * when needed, the @FTC_Face_Requester to translate them into new + * @FT_Face objects. + * + * If the content of a given face ID changes at runtime, or if the value + * becomes invalid (e.g., when uninstalling a font), you should + * immediately call @FTC_Manager_RemoveFaceID before any other cache + * function. + * + * Failure to do so will result in incorrect behaviour or even + * memory leaks and crashes. + */ + typedef FT_Pointer FTC_FaceID; + + + /************************************************************************ + * + * @functype: + * FTC_Face_Requester + * + * @description: + * A callback function provided by client applications. It is used by + * the cache manager to translate a given @FTC_FaceID into a new valid + * @FT_Face object, on demand. + * + * <Input> + * face_id :: + * The face ID to resolve. + * + * library :: + * A handle to a FreeType library object. + * + * req_data :: + * Application-provided request data (see note below). + * + * <Output> + * aface :: + * A new @FT_Face handle. + * + * <Return> + * FreeType error code. 0~means success. + * + * <Note> + * The third parameter `req_data' is the same as the one passed by the + * client when @FTC_Manager_New is called. + * + * The face requester should not perform funny things on the returned + * face object, like creating a new @FT_Size for it, or setting a + * transformation through @FT_Set_Transform! + */ + typedef FT_Error + (*FTC_Face_Requester)( FTC_FaceID face_id, + FT_Library library, + FT_Pointer req_data, + FT_Face* aface ); + + /* */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Manager */ + /* */ + /* <Description> */ + /* This object corresponds to one instance of the cache-subsystem. */ + /* It is used to cache one or more @FT_Face objects, along with */ + /* corresponding @FT_Size objects. */ + /* */ + /* The manager intentionally limits the total number of opened */ + /* @FT_Face and @FT_Size objects to control memory usage. See the */ + /* `max_faces' and `max_sizes' parameters of @FTC_Manager_New. */ + /* */ + /* The manager is also used to cache `nodes' of various types while */ + /* limiting their total memory usage. */ + /* */ + /* All limitations are enforced by keeping lists of managed objects */ + /* in most-recently-used order, and flushing old nodes to make room */ + /* for new ones. */ + /* */ + typedef struct FTC_ManagerRec_* FTC_Manager; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Node */ + /* */ + /* <Description> */ + /* An opaque handle to a cache node object. Each cache node is */ + /* reference-counted. A node with a count of~0 might be flushed */ + /* out of a full cache whenever a lookup request is performed. */ + /* */ + /* If you look up nodes, you have the ability to `acquire' them, */ + /* i.e., to increment their reference count. This will prevent the */ + /* node from being flushed out of the cache until you explicitly */ + /* `release' it (see @FTC_Node_Unref). */ + /* */ + /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ + /* */ + typedef struct FTC_NodeRec_* FTC_Node; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_New */ + /* */ + /* <Description> */ + /* Create a new cache manager. */ + /* */ + /* <Input> */ + /* library :: The parent FreeType library handle to use. */ + /* */ + /* max_faces :: Maximum number of opened @FT_Face objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ + /* Use~0 for defaults. Note that this value does not */ + /* account for managed @FT_Face and @FT_Size objects. */ + /* */ + /* requester :: An application-provided callback used to translate */ + /* face IDs into real @FT_Face objects. */ + /* */ + /* req_data :: A generic pointer that is passed to the requester */ + /* each time it is called (see @FTC_Face_Requester). */ + /* */ + /* <Output> */ + /* amanager :: A handle to a new manager object. 0~in case of */ + /* failure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Reset */ + /* */ + /* <Description> */ + /* Empty a given cache manager. This simply gets rid of all the */ + /* currently cached @FT_Face and @FT_Size objects within the manager. */ + /* */ + /* <InOut> */ + /* manager :: A handle to the manager. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Reset( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Done */ + /* */ + /* <Description> */ + /* Destroy a given manager after emptying it. */ + /* */ + /* <Input> */ + /* manager :: A handle to the target cache manager object. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Done( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupFace */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Face object that corresponds to a given face ID */ + /* through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* face_id :: The ID of the face object. */ + /* */ + /* <Output> */ + /* aface :: A handle to the face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Face object is always owned by the manager. You */ + /* should never try to discard it yourself. */ + /* */ + /* The @FT_Face object doesn't necessarily have a current size object */ + /* (i.e., face->size can be~0). If you need a specific `font size', */ + /* use @FTC_Manager_LookupSize instead. */ + /* */ + /* Never change the face's transformation matrix (i.e., never call */ + /* the @FT_Set_Transform function) on a returned face! If you need */ + /* to transform glyphs, do it yourself after glyph loading. */ + /* */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory was available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_ScalerRec */ + /* */ + /* <Description> */ + /* A structure used to describe a given character size in either */ + /* pixels or points to the cache manager. See */ + /* @FTC_Manager_LookupSize. */ + /* */ + /* <Fields> */ + /* face_id :: The source face ID. */ + /* */ + /* width :: The character width. */ + /* */ + /* height :: The character height. */ + /* */ + /* pixel :: A Boolean. If 1, the `width' and `height' fields are */ + /* interpreted as integer pixel character sizes. */ + /* Otherwise, they are expressed as 1/64th of points. */ + /* */ + /* x_res :: Only used when `pixel' is value~0 to indicate the */ + /* horizontal resolution in dpi. */ + /* */ + /* y_res :: Only used when `pixel' is value~0 to indicate the */ + /* vertical resolution in dpi. */ + /* */ + /* <Note> */ + /* This type is mainly used to retrieve @FT_Size objects through the */ + /* cache manager. */ + /* */ + typedef struct FTC_ScalerRec_ + { + FTC_FaceID face_id; + FT_UInt width; + FT_UInt height; + FT_Int pixel; + FT_UInt x_res; + FT_UInt y_res; + + } FTC_ScalerRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_Scaler */ + /* */ + /* <Description> */ + /* A handle to an @FTC_ScalerRec structure. */ + /* */ + typedef struct FTC_ScalerRec_* FTC_Scaler; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupSize */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Size object that corresponds to a given */ + /* @FTC_ScalerRec pointer through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* scaler :: A scaler handle. */ + /* */ + /* <Output> */ + /* asize :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Size object is always owned by the manager. You */ + /* should never try to discard it by yourself. */ + /* */ + /* You can access the parent @FT_Face object simply as `size->face' */ + /* if you need it. Note that this object is also owned by the */ + /* manager. */ + /* */ + /* <Note> */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory is available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Node_Unref */ + /* */ + /* <Description> */ + /* Decrement a cache node's internal reference count. When the count */ + /* reaches 0, it is not destroyed but becomes eligible for subsequent */ + /* cache flushes. */ + /* */ + /* <Input> */ + /* node :: The cache node handle. */ + /* */ + /* manager :: The cache manager handle. */ + /* */ + FT_EXPORT( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); + + + /************************************************************************* + * + * @function: + * FTC_Manager_RemoveFaceID + * + * @description: + * A special function used to indicate to the cache manager that + * a given @FTC_FaceID is no longer valid, either because its + * content changed, or because it was deallocated or uninstalled. + * + * @input: + * manager :: + * The cache manager handle. + * + * face_id :: + * The @FTC_FaceID to be removed. + * + * @note: + * This function flushes all nodes from the cache corresponding to this + * `face_id', with the exception of nodes with a non-null reference + * count. + * + * Such nodes are however modified internally so as to never appear + * in later lookups with the same `face_id' value, and to be immediately + * destroyed when released by all their users. + * + */ + FT_EXPORT( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * FTC_CMapCache + * + * @description: + * An opaque handle used to model a charmap cache. This cache is to + * hold character codes -> glyph indices mappings. + * + */ + typedef struct FTC_CMapCacheRec_* FTC_CMapCache; + + + /************************************************************************* + * + * @function: + * FTC_CMapCache_New + * + * @description: + * Create a new charmap cache. + * + * @input: + * manager :: + * A handle to the cache manager. + * + * @output: + * acache :: + * A new cache handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Like all other caches, this one will be destroyed with the cache + * manager. + * + */ + FT_EXPORT( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ); + + + /************************************************************************ + * + * @function: + * FTC_CMapCache_Lookup + * + * @description: + * Translate a character code into a glyph index, using the charmap + * cache. + * + * @input: + * cache :: + * A charmap cache handle. + * + * face_id :: + * The source face ID. + * + * cmap_index :: + * The index of the charmap in the source face. Any negative value + * means to use the cache @FT_Face's default charmap. + * + * char_code :: + * The character code (in the corresponding charmap). + * + * @return: + * Glyph index. 0~means `no glyph'. + * + */ + FT_EXPORT( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cache, + FTC_FaceID face_id, + FT_Int cmap_index, + FT_UInt32 char_code ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @struct: + * FTC_ImageTypeRec + * + * @description: + * A structure used to model the type of images in a glyph cache. + * + * @fields: + * face_id :: + * The face ID. + * + * width :: + * The width in pixels. + * + * height :: + * The height in pixels. + * + * flags :: + * The load flags, as in @FT_Load_Glyph. + * + */ + typedef struct FTC_ImageTypeRec_ + { + FTC_FaceID face_id; + FT_Int width; + FT_Int height; + FT_Int32 flags; + + } FTC_ImageTypeRec; + + + /************************************************************************* + * + * @type: + * FTC_ImageType + * + * @description: + * A handle to an @FTC_ImageTypeRec structure. + * + */ + typedef struct FTC_ImageTypeRec_* FTC_ImageType; + + + /* */ + + +#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ + ( (d1)->face_id == (d2)->face_id && \ + (d1)->width == (d2)->width && \ + (d1)->flags == (d2)->flags ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_ImageCache */ + /* */ + /* <Description> */ + /* A handle to a glyph image cache object. They are designed to */ + /* hold many distinct glyph images while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_ImageCacheRec_* FTC_ImageCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_New */ + /* */ + /* <Description> */ + /* Create a new glyph image cache. */ + /* */ + /* <Input> */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_Lookup */ + /* */ + /* <Description> */ + /* Retrieve a given glyph image from a glyph image cache. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* type :: A pointer to a glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* scaler :: A pointer to a scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ + /* glyphs; you should always use the FreeType cache API instead. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_LookupScaler( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBit */ + /* */ + /* <Description> */ + /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ + /* structure for details. */ + /* */ + typedef struct FTC_SBitRec_* FTC_SBit; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_SBitRec */ + /* */ + /* <Description> */ + /* A very compact structure used to describe a small glyph bitmap. */ + /* */ + /* <Fields> */ + /* width :: The bitmap width in pixels. */ + /* */ + /* height :: The bitmap height in pixels. */ + /* */ + /* left :: The horizontal distance from the pen position to the */ + /* left bitmap border (a.k.a. `left side bearing', or */ + /* `lsb'). */ + /* */ + /* top :: The vertical distance from the pen position (on the */ + /* baseline) to the upper bitmap border (a.k.a. `top */ + /* side bearing'). The distance is positive for upwards */ + /* y~coordinates. */ + /* */ + /* format :: The format of the glyph bitmap (monochrome or gray). */ + /* */ + /* max_grays :: Maximum gray level value (in the range 1 to~255). */ + /* */ + /* pitch :: The number of bytes per bitmap line. May be positive */ + /* or negative. */ + /* */ + /* xadvance :: The horizontal advance width in pixels. */ + /* */ + /* yadvance :: The vertical advance height in pixels. */ + /* */ + /* buffer :: A pointer to the bitmap pixels. */ + /* */ + typedef struct FTC_SBitRec_ + { + FT_Byte width; + FT_Byte height; + FT_Char left; + FT_Char top; + + FT_Byte format; + FT_Byte max_grays; + FT_Short pitch; + FT_Char xadvance; + FT_Char yadvance; + + FT_Byte* buffer; + + } FTC_SBitRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBitCache */ + /* */ + /* <Description> */ + /* A handle to a small bitmap cache. These are special cache objects */ + /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ + /* much more efficient way than the traditional glyph image cache */ + /* implemented by @FTC_ImageCache. */ + /* */ + typedef struct FTC_SBitCacheRec_* FTC_SBitCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_New */ + /* */ + /* <Description> */ + /* Create a new cache to store small glyph bitmaps. */ + /* */ + /* <Input> */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_Lookup */ + /* */ + /* <Description> */ + /* Look up a given small glyph bitmap in a given sbit cache and */ + /* `lock' it to prevent its flushing from the cache until needed. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* type :: A pointer to the glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* scaler :: A pointer to the scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_LookupScaler( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTCACHE_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcffdrv.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcffdrv.h new file mode 100644 index 00000000..f7031bc8 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcffdrv.h @@ -0,0 +1,262 @@ +/***************************************************************************/ +/* */ +/* ftcffdrv.h */ +/* */ +/* FreeType API for controlling the CFF driver (specification only). */ +/* */ +/* Copyright 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCFFDRV_H__ +#define __FTCFFDRV_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * cff_driver + * + * @title: + * The CFF driver + * + * @abstract: + * Controlling the CFF driver module. + * + * @description: + * While FreeType's CFF driver doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The list below gives the available properties + * together with the necessary macros and structures. + * + * The CFF driver's module name is `cff'. + * + * *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine* + * + * The rasterizer is positioning horizontal features (e.g., ascender + * height & x-height, or crossbars) on the pixel grid and minimizing the + * amount of antialiasing applied to them, while placing vertical + * features (vertical stems) on the pixel grid without hinting, thus + * representing the stem position and weight accurately. Sometimes the + * vertical stems may be only partially black. In this context, + * `antialiasing' means that stems are not positioned exactly on pixel + * borders, causing a fuzzy appearance. + * + * There are two principles behind this approach. + * + * 1) No hinting in the horizontal direction: Unlike `superhinted' + * TrueType, which changes glyph widths to accommodate regular + * inter-glyph spacing, Adobe's approach is `faithful to the design' in + * representing both the glyph width and the inter-glyph spacing + * designed for the font. This makes the screen display as close as it + * can be to the result one would get with infinite resolution, while + * preserving what is considered the key characteristics of each glyph. + * Note that the distances between unhinted and grid-fitted positions at + * small sizes are comparable to kerning values and thus would be + * noticeable (and distracting) while reading if hinting were applied. + * + * One of the reasons to not hint horizontally is antialiasing for LCD + * screens: The pixel geometry of modern displays supplies three + * vertical sub-pixels as the eye moves horizontally across each visible + * pixel. On devices where we can be certain this characteristic is + * present a rasterizer can take advantage of the sub-pixels to add + * increments of weight. In Western writing systems this turns out to + * be the more critical direction anyway; the weights and spacing of + * vertical stems (see above) are central to Armenian, Cyrillic, Greek, + * and Latin type designs. Even when the rasterizer uses greyscale + * antialiasing instead of color (a necessary compromise when one + * doesn't know the screen characteristics), the unhinted vertical + * features preserve the design's weight and spacing much better than + * aliased type would. + * + * 2) Aligment in the vertical direction: Weights and spacing along the + * y~axis are less critical; what is much more important is the visual + * alignment of related features (like cap-height and x-height). The + * sense of alignment for these is enhanced by the sharpness of grid-fit + * edges, while the cruder vertical resolution (full pixels instead of + * 1/3 pixels) is less of a problem. + * + * On the technical side, horizontal alignment zones for ascender, + * x-height, and other important height values (traditionally called + * `blue zones') as defined in the font are positioned independently, + * each being rounded to the nearest pixel edge, taking care of + * overshoot suppression at small sizes, stem darkening, and scaling. + * + * Hstems (this is, hint values defined in the font to help align + * horizontal features) that fall within a blue zone are said to be + * `captured' and are aligned to that zone. Uncaptured stems are moved + * in one of four ways, top edge up or down, bottom edge up or down. + * Unless there are conflicting hstems, the smallest movement is taken + * to minimize distortion. + * + * @order: + * hinting-engine + * no-stem-darkening + * darkening-parameters + * + */ + + + /************************************************************************** + * + * @property: + * hinting-engine + * + * @description: + * Thanks to Adobe, which contributed a new hinting (and parsing) + * engine, an application can select between `freetype' and `adobe' if + * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration + * macro isn't defined, `hinting-engine' does nothing. + * + * The default engine is `freetype' if CFF_CONFIG_OPTION_OLD_ENGINE is + * defined, and `adobe' otherwise. + * + * The following example code demonstrates how to select Adobe's hinting + * engine (omitting the error handling). + * + * { + * FT_Library library; + * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "hinting-engine", &hinting_engine ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_CFF_HINTING_XXX + * + * @description: + * A list of constants used for the @hinting-engine property to select + * the hinting engine for CFF fonts. + * + * @values: + * FT_CFF_HINTING_FREETYPE :: + * Use the old FreeType hinting engine. + * + * FT_CFF_HINTING_ADOBE :: + * Use the hinting engine contributed by Adobe. + * + */ +#define FT_CFF_HINTING_FREETYPE 0 +#define FT_CFF_HINTING_ADOBE 1 + + + /************************************************************************** + * + * @property: + * no-stem-darkening + * + * @description: + * By default, the Adobe CFF engine darkens stems at smaller sizes, + * regardless of hinting, to enhance contrast. This feature requires + * a rendering system with proper gamma correction. Setting this + * property, stem darkening gets switched off. + * + * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is set. + * + * { + * FT_Library library; + * FT_Bool no_stem_darkening = TRUE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "no-stem-darkening", &no_stem_darkening ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /************************************************************************** + * + * @property: + * darkening-parameters + * + * @description: + * By default, the Adobe CFF engine darkens stems as follows (if the + * `no-stem-darkening' property isn't set): + * + * { + * stem width <= 0.5px: darkening amount = 0.4px + * stem width = 1px: darkening amount = 0.275px + * stem width = 1.667px: darkening amount = 0.275px + * stem width >= 2.333px: darkening amount = 0px + * } + * + * and piecewise linear in-between. At configuration time, these four + * control points can be set with the macro + * `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'. At runtime, the control + * points can be changed using the `darkening-parameters' property, as + * the following example demonstrates. + * + * { + * FT_Library library; + * FT_Int darken_params[8] = { 500, 300, // x1, y1 + * 1000, 200, // x2, y2 + * 1500, 100, // x3, y3 + * 2000, 0 }; // x4, y4 + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "darkening-parameters", darken_params ); + * } + * + * The x~values give the stem width, and the y~values the darkening + * amount. The unit is 1000th of pixels. All coordinate values must be + * positive; the x~values must be monotonically increasing; the + * y~values must be monotonically decreasing and smaller than or + * equal to 500 (corresponding to half a pixel); the slope of each + * linear piece must be shallower than -1 (e.g., -.4). + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + /* */ + + +FT_END_HEADER + + +#endif /* __FTCFFDRV_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftchapters.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftchapters.h new file mode 100644 index 00000000..d333761c --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftchapters.h @@ -0,0 +1,121 @@ +/***************************************************************************/ +/* */ +/* This file defines the structure of the FreeType reference. */ +/* It is used by the python script that generates the HTML files. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* general_remarks */ +/* */ +/* <Title> */ +/* General Remarks */ +/* */ +/* <Sections> */ +/* header_inclusion */ +/* user_allocation */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* core_api */ +/* */ +/* <Title> */ +/* Core API */ +/* */ +/* <Sections> */ +/* version */ +/* basic_types */ +/* base_interface */ +/* glyph_variants */ +/* glyph_management */ +/* mac_specific */ +/* sizes_management */ +/* header_file_macros */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* format_specific */ +/* */ +/* <Title> */ +/* Format-Specific API */ +/* */ +/* <Sections> */ +/* multiple_masters */ +/* truetype_tables */ +/* type1_tables */ +/* sfnt_names */ +/* bdf_fonts */ +/* cid_fonts */ +/* pfr_fonts */ +/* winfnt_fonts */ +/* font_formats */ +/* gasp_table */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* module_specific */ +/* */ +/* <Title> */ +/* Controlling FreeType Modules */ +/* */ +/* <Sections> */ +/* auto_hinter */ +/* cff_driver */ +/* tt_driver */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* cache_subsystem */ +/* */ +/* <Title> */ +/* Cache Sub-System */ +/* */ +/* <Sections> */ +/* cache_subsystem */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* support_api */ +/* */ +/* <Title> */ +/* Support API */ +/* */ +/* <Sections> */ +/* computations */ +/* list_processing */ +/* outline_processing */ +/* quick_advance */ +/* bitmap_handling */ +/* raster */ +/* glyph_stroker */ +/* system_interface */ +/* module_management */ +/* gzip */ +/* lzw */ +/* bzip2 */ +/* lcd_filtering */ +/* */ +/***************************************************************************/ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcid.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcid.h new file mode 100644 index 00000000..17550d87 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftcid.h @@ -0,0 +1,167 @@ +/***************************************************************************/ +/* */ +/* ftcid.h */ +/* */ +/* FreeType API for accessing CID font information (specification). */ +/* */ +/* Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCID_H__ +#define __FTCID_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cid_fonts */ + /* */ + /* <Title> */ + /* CID Fonts */ + /* */ + /* <Abstract> */ + /* CID-keyed font specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of CID-keyed font specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Registry_Ordering_Supplement + * + * @description: + * Retrieve the Registry/Ordering/Supplement triple (also known as the + * "R/O/S") from a CID-keyed font. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * registry :: + * The registry, as a C~string, owned by the face. + * + * ordering :: + * The ordering, as a C~string, owned by the face. + * + * supplement :: + * The supplement. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces, returning an error + * otherwise. + * + * @since: + * 2.3.6 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Is_Internally_CID_Keyed + * + * @description: + * Retrieve the type of the input face, CID keyed or not. In + * constrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SNFT wrapper. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * is_cid :: + * The type of the face as an @FT_Bool. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid ); + + + /********************************************************************** + * + * @function: + * FT_Get_CID_From_Glyph_Index + * + * @description: + * Retrieve the CID of the input glyph index. + * + * @input: + * face :: + * A handle to the input face. + * + * glyph_index :: + * The input glyph index. + * + * @output: + * cid :: + * The CID as an @FT_UInt. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.9 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTCID_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fterrdef.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fterrdef.h new file mode 100644 index 00000000..99b2fade --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fterrdef.h @@ -0,0 +1,249 @@ +/***************************************************************************/ +/* */ +/* fterrdef.h */ +/* */ +/* FreeType error codes (specification). */ +/* */ +/* Copyright 2002, 2004, 2006, 2007, 2010-2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST OF ERROR CODES/MESSAGES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + + /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */ + /* including this file. */ + + + /* generic errors */ + + FT_NOERRORDEF_( Ok, 0x00, + "no error" ) + + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, + "cannot open resource" ) + FT_ERRORDEF_( Unknown_File_Format, 0x02, + "unknown file format" ) + FT_ERRORDEF_( Invalid_File_Format, 0x03, + "broken file" ) + FT_ERRORDEF_( Invalid_Version, 0x04, + "invalid FreeType version" ) + FT_ERRORDEF_( Lower_Module_Version, 0x05, + "module version is too low" ) + FT_ERRORDEF_( Invalid_Argument, 0x06, + "invalid argument" ) + FT_ERRORDEF_( Unimplemented_Feature, 0x07, + "unimplemented feature" ) + FT_ERRORDEF_( Invalid_Table, 0x08, + "broken table" ) + FT_ERRORDEF_( Invalid_Offset, 0x09, + "broken offset within table" ) + FT_ERRORDEF_( Array_Too_Large, 0x0A, + "array allocation size too large" ) + FT_ERRORDEF_( Missing_Module, 0x0B, + "missing module" ) + FT_ERRORDEF_( Missing_Property, 0x0C, + "missing property" ) + + /* glyph/character errors */ + + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, + "invalid glyph index" ) + FT_ERRORDEF_( Invalid_Character_Code, 0x11, + "invalid character code" ) + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, + "unsupported glyph image format" ) + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, + "cannot render this glyph format" ) + FT_ERRORDEF_( Invalid_Outline, 0x14, + "invalid outline" ) + FT_ERRORDEF_( Invalid_Composite, 0x15, + "invalid composite glyph" ) + FT_ERRORDEF_( Too_Many_Hints, 0x16, + "too many hints" ) + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, + "invalid pixel size" ) + + /* handle errors */ + + FT_ERRORDEF_( Invalid_Handle, 0x20, + "invalid object handle" ) + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, + "invalid library handle" ) + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, + "invalid module handle" ) + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, + "invalid face handle" ) + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, + "invalid size handle" ) + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, + "invalid glyph slot handle" ) + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, + "invalid charmap handle" ) + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, + "invalid cache manager handle" ) + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, + "invalid stream handle" ) + + /* driver errors */ + + FT_ERRORDEF_( Too_Many_Drivers, 0x30, + "too many modules" ) + FT_ERRORDEF_( Too_Many_Extensions, 0x31, + "too many extensions" ) + + /* memory errors */ + + FT_ERRORDEF_( Out_Of_Memory, 0x40, + "out of memory" ) + FT_ERRORDEF_( Unlisted_Object, 0x41, + "unlisted object" ) + + /* stream errors */ + + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, + "cannot open stream" ) + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, + "invalid stream seek" ) + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, + "invalid stream skip" ) + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, + "invalid stream read" ) + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, + "invalid stream operation" ) + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, + "invalid frame operation" ) + FT_ERRORDEF_( Nested_Frame_Access, 0x57, + "nested frame access" ) + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, + "invalid frame read" ) + + /* raster errors */ + + FT_ERRORDEF_( Raster_Uninitialized, 0x60, + "raster uninitialized" ) + FT_ERRORDEF_( Raster_Corrupted, 0x61, + "raster corrupted" ) + FT_ERRORDEF_( Raster_Overflow, 0x62, + "raster overflow" ) + FT_ERRORDEF_( Raster_Negative_Height, 0x63, + "negative height while rastering" ) + + /* cache errors */ + + FT_ERRORDEF_( Too_Many_Caches, 0x70, + "too many registered caches" ) + + /* TrueType and SFNT errors */ + + FT_ERRORDEF_( Invalid_Opcode, 0x80, + "invalid opcode" ) + FT_ERRORDEF_( Too_Few_Arguments, 0x81, + "too few arguments" ) + FT_ERRORDEF_( Stack_Overflow, 0x82, + "stack overflow" ) + FT_ERRORDEF_( Code_Overflow, 0x83, + "code overflow" ) + FT_ERRORDEF_( Bad_Argument, 0x84, + "bad argument" ) + FT_ERRORDEF_( Divide_By_Zero, 0x85, + "division by zero" ) + FT_ERRORDEF_( Invalid_Reference, 0x86, + "invalid reference" ) + FT_ERRORDEF_( Debug_OpCode, 0x87, + "found debug opcode" ) + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, + "found ENDF opcode in execution stream" ) + FT_ERRORDEF_( Nested_DEFS, 0x89, + "nested DEFS" ) + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, + "invalid code range" ) + FT_ERRORDEF_( Execution_Too_Long, 0x8B, + "execution context too long" ) + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, + "too many function definitions" ) + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, + "too many instruction definitions" ) + FT_ERRORDEF_( Table_Missing, 0x8E, + "SFNT font table missing" ) + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, + "horizontal header (hhea) table missing" ) + FT_ERRORDEF_( Locations_Missing, 0x90, + "locations (loca) table missing" ) + FT_ERRORDEF_( Name_Table_Missing, 0x91, + "name table missing" ) + FT_ERRORDEF_( CMap_Table_Missing, 0x92, + "character map (cmap) table missing" ) + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, + "horizontal metrics (hmtx) table missing" ) + FT_ERRORDEF_( Post_Table_Missing, 0x94, + "PostScript (post) table missing" ) + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, + "invalid horizontal metrics" ) + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, + "invalid character map (cmap) format" ) + FT_ERRORDEF_( Invalid_PPem, 0x97, + "invalid ppem value" ) + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, + "invalid vertical metrics" ) + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, + "could not find context" ) + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, + "invalid PostScript (post) table format" ) + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, + "invalid PostScript (post) table" ) + + /* CFF, CID, and Type 1 errors */ + + FT_ERRORDEF_( Syntax_Error, 0xA0, + "opcode syntax error" ) + FT_ERRORDEF_( Stack_Underflow, 0xA1, + "argument stack underflow" ) + FT_ERRORDEF_( Ignore, 0xA2, + "ignore" ) + FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, + "no Unicode glyph name found" ) + FT_ERRORDEF_( Glyph_Too_Big, 0xA4, + "glyph to big for hinting" ) + + /* BDF errors */ + + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, + "`STARTFONT' field missing" ) + FT_ERRORDEF_( Missing_Font_Field, 0xB1, + "`FONT' field missing" ) + FT_ERRORDEF_( Missing_Size_Field, 0xB2, + "`SIZE' field missing" ) + FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, + "`FONTBOUNDINGBOX' field missing" ) + FT_ERRORDEF_( Missing_Chars_Field, 0xB4, + "`CHARS' field missing" ) + FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, + "`STARTCHAR' field missing" ) + FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, + "`ENCODING' field missing" ) + FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, + "`BBX' field missing" ) + FT_ERRORDEF_( Bbx_Too_Big, 0xB8, + "`BBX' too big" ) + FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, + "Font header corrupted or missing fields" ) + FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, + "Font glyphs corrupted or missing fields" ) + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fterrors.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fterrors.h new file mode 100644 index 00000000..0fa3e4dc --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fterrors.h @@ -0,0 +1,198 @@ +/***************************************************************************/ +/* */ +/* fterrors.h */ +/* */ +/* FreeType error code handling (specification). */ +/* */ +/* Copyright 1996-2002, 2004, 2007, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This special header file is used to define the handling of FT2 */ + /* enumeration constants. It can also be used to generate error message */ + /* strings with a small macro trick explained below. */ + /* */ + /* I - Error Formats */ + /* ----------------- */ + /* */ + /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ + /* defined in ftoption.h in order to make the higher byte indicate */ + /* the module where the error has happened (this is not compatible */ + /* with standard builds of FreeType 2). See the file `ftmoderr.h' for */ + /* more details. */ + /* */ + /* */ + /* II - Error Message strings */ + /* -------------------------- */ + /* */ + /* The error definitions below are made through special macros that */ + /* allow client applications to build a table of error message strings */ + /* if they need it. The strings are not included in a normal build of */ + /* FreeType 2 to save space (most client applications do not use */ + /* them). */ + /* */ + /* To do so, you have to define the following macros before including */ + /* this file: */ + /* */ + /* FT_ERROR_START_LIST :: */ + /* This macro is called before anything else to define the start of */ + /* the error list. It is followed by several FT_ERROR_DEF calls */ + /* (see below). */ + /* */ + /* FT_ERROR_DEF( e, v, s ) :: */ + /* This macro is called to define one single error. */ + /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ + /* `v' is the error numerical value. */ + /* `s' is the corresponding error string. */ + /* */ + /* FT_ERROR_END_LIST :: */ + /* This macro ends the list. */ + /* */ + /* Additionally, you have to undefine __FTERRORS_H__ before #including */ + /* this file. */ + /* */ + /* Here is a simple example: */ + /* */ + /* { */ + /* #undef __FTERRORS_H__ */ + /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ + /* #define FT_ERROR_START_LIST { */ + /* #define FT_ERROR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int err_code; */ + /* const char* err_msg; */ + /* } ft_errors[] = */ + /* */ + /* #include FT_ERRORS_H */ + /* } */ + /* */ + /*************************************************************************/ + + +#ifndef __FTERRORS_H__ +#define __FTERRORS_H__ + + + /* include module base error codes */ +#include FT_MODULE_ERRORS_H + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + + + /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ + /* By default, we use `FT_Err_'. */ + /* */ +#ifndef FT_ERR_PREFIX +#define FT_ERR_PREFIX FT_Err_ +#endif + + + /* FT_ERR_BASE is used as the base for module-specific errors. */ + /* */ +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS + +#ifndef FT_ERR_BASE +#define FT_ERR_BASE FT_Mod_Err_Base +#endif + +#else + +#undef FT_ERR_BASE +#define FT_ERR_BASE 0 + +#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ + + + /* If FT_ERRORDEF is not defined, we need to define a simple */ + /* enumeration type. */ + /* */ +#ifndef FT_ERRORDEF + +#define FT_ERRORDEF( e, v, s ) e = v, +#define FT_ERROR_START_LIST enum { +#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_ERRORDEF */ + + + /* this macro is used to define an error */ +#define FT_ERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) + + /* this is only used for <module>_Err_Ok, which must be 0! */ +#define FT_NOERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) + + +#ifdef FT_ERROR_START_LIST + FT_ERROR_START_LIST +#endif + + + /* now include the error codes */ +#include FT_ERROR_DEFINITIONS_H + + +#ifdef FT_ERROR_END_LIST + FT_ERROR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SIMPLE CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_ERROR_START_LIST +#undef FT_ERROR_END_LIST + +#undef FT_ERRORDEF +#undef FT_ERRORDEF_ +#undef FT_NOERRORDEF_ + +#undef FT_NEED_EXTERN_C +#undef FT_ERR_BASE + + /* FT_ERR_PREFIX is needed internally */ +#ifndef FT2_BUILD_LIBRARY +#undef FT_ERR_PREFIX +#endif + +#endif /* __FTERRORS_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgasp.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgasp.h new file mode 100644 index 00000000..3f3d7654 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgasp.h @@ -0,0 +1,129 @@ +/***************************************************************************/ +/* */ +/* ftgasp.h */ +/* */ +/* Access of TrueType's `gasp' table (specification). */ +/* */ +/* Copyright 2007, 2008, 2011 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef _FT_GASP_H_ +#define _FT_GASP_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + + /*************************************************************************** + * + * @section: + * gasp_table + * + * @title: + * Gasp Table + * + * @abstract: + * Retrieving TrueType `gasp' table entries. + * + * @description: + * The function @FT_Get_Gasp can be used to query a TrueType or OpenType + * font for specific entries in its `gasp' table, if any. This is + * mainly useful when implementing native TrueType hinting with the + * bytecode interpreter to duplicate the Windows text rendering results. + */ + + /************************************************************************* + * + * @enum: + * FT_GASP_XXX + * + * @description: + * A list of values and/or bit-flags returned by the @FT_Get_Gasp + * function. + * + * @values: + * FT_GASP_NO_TABLE :: + * This special value means that there is no GASP table in this face. + * It is up to the client to decide what to do. + * + * FT_GASP_DO_GRIDFIT :: + * Grid-fitting and hinting should be performed at the specified ppem. + * This *really* means TrueType bytecode interpretation. If this bit + * is not set, no hinting gets applied. + * + * FT_GASP_DO_GRAY :: + * Anti-aliased rendering should be performed at the specified ppem. + * If not set, do monochrome rendering. + * + * FT_GASP_SYMMETRIC_SMOOTHING :: + * If set, smoothing along multiple axes must be used with ClearType. + * + * FT_GASP_SYMMETRIC_GRIDFIT :: + * Grid-fitting must be used with ClearType's symmetric smoothing. + * + * @note: + * The bit-flags `FT_GASP_DO_GRIDFIT' and `FT_GASP_DO_GRAY' are to be + * used for standard font rasterization only. Independently of that, + * `FT_GASP_SYMMETRIC_SMOOTHING' and `FT_GASP_SYMMETRIC_GRIDFIT' are to + * be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT' and + * `FT_GASP_DO_GRAY' are consequently ignored). + * + * `ClearType' is Microsoft's implementation of LCD rendering, partly + * protected by patents. + * + * @since: + * 2.3.0 + */ +#define FT_GASP_NO_TABLE -1 +#define FT_GASP_DO_GRIDFIT 0x01 +#define FT_GASP_DO_GRAY 0x02 +#define FT_GASP_SYMMETRIC_SMOOTHING 0x08 +#define FT_GASP_SYMMETRIC_GRIDFIT 0x10 + + + /************************************************************************* + * + * @func: + * FT_Get_Gasp + * + * @description: + * Read the `gasp' table from a TrueType or OpenType font file and + * return the entry corresponding to a given character pixel size. + * + * @input: + * face :: The source face handle. + * ppem :: The vertical character pixel size. + * + * @return: + * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no + * `gasp' table in the face. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Int ) + FT_Get_Gasp( FT_Face face, + FT_UInt ppem ); + + /* */ + + +#endif /* _FT_GASP_H_ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftglyph.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftglyph.h new file mode 100644 index 00000000..15fa6a99 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftglyph.h @@ -0,0 +1,605 @@ +/***************************************************************************/ +/* */ +/* ftglyph.h */ +/* */ +/* FreeType convenience functions to handle glyphs (specification). */ +/* */ +/* Copyright 1996-2003, 2006, 2008, 2009, 2011, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTGLYPH_H__ +#define __FTGLYPH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_management */ + /* */ + /* <Title> */ + /* Glyph Management */ + /* */ + /* <Abstract> */ + /* Generic interface to manage individual glyph data. */ + /* */ + /* <Description> */ + /* This section contains definitions used to manage glyph data */ + /* through generic FT_Glyph objects. Each of them can contain a */ + /* bitmap, a vector outline, or even images in other formats. */ + /* */ + /*************************************************************************/ + + + /* forward declaration to a private type */ + typedef struct FT_Glyph_Class_ FT_Glyph_Class; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Glyph */ + /* */ + /* <Description> */ + /* Handle to an object used to model generic glyph images. It is a */ + /* pointer to the @FT_GlyphRec structure and can contain a glyph */ + /* bitmap or pointer. */ + /* */ + /* <Note> */ + /* Glyph objects are not owned by the library. You must thus release */ + /* them manually (through @FT_Done_Glyph) _before_ calling */ + /* @FT_Done_FreeType. */ + /* */ + typedef struct FT_GlyphRec_* FT_Glyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphRec */ + /* */ + /* <Description> */ + /* The root glyph structure contains a given glyph image plus its */ + /* advance width in 16.16 fixed-point format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library object. */ + /* */ + /* clazz :: A pointer to the glyph's class. Private. */ + /* */ + /* format :: The format of the glyph's image. */ + /* */ + /* advance :: A 16.16 vector that gives the glyph's advance width. */ + /* */ + typedef struct FT_GlyphRec_ + { + FT_Library library; + const FT_Glyph_Class* clazz; + FT_Glyph_Format format; + FT_Vector advance; + + } FT_GlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_BitmapGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model a bitmap glyph image. This is */ + /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ + /* */ + typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BitmapGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for bitmap glyph images. This really is a */ + /* `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* left :: The left-side bearing, i.e., the horizontal distance */ + /* from the current pen position to the left border of the */ + /* glyph bitmap. */ + /* */ + /* top :: The top-side bearing, i.e., the vertical distance from */ + /* the current pen position to the top border of the glyph */ + /* bitmap. This distance is positive for upwards~y! */ + /* */ + /* bitmap :: A descriptor for the bitmap. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_BITMAP'. This lets you access */ + /* the bitmap's contents easily. */ + /* */ + /* The corresponding pixel buffer is always owned by @FT_BitmapGlyph */ + /* and is thus created and destroyed with it. */ + /* */ + typedef struct FT_BitmapGlyphRec_ + { + FT_GlyphRec root; + FT_Int left; + FT_Int top; + FT_Bitmap bitmap; + + } FT_BitmapGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_OutlineGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model an outline glyph image. This */ + /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ + /* */ + typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_OutlineGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for outline (vectorial) glyph images. This */ + /* really is a `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* outline :: A descriptor for the outline. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ + /* the outline's content easily. */ + /* */ + /* As the outline is extracted from a glyph slot, its coordinates are */ + /* expressed normally in 26.6 pixels, unless the flag */ + /* @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */ + /* */ + /* The outline's tables are always owned by the object and are */ + /* destroyed with it. */ + /* */ + typedef struct FT_OutlineGlyphRec_ + { + FT_GlyphRec root; + FT_Outline outline; + + } FT_OutlineGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph */ + /* */ + /* <Description> */ + /* A function used to extract a glyph image from a slot. Note that */ + /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* slot :: A handle to the source glyph slot. */ + /* */ + /* <Output> */ + /* aglyph :: A handle to the glyph object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Copy */ + /* */ + /* <Description> */ + /* A function used to copy a glyph image. Note that the created */ + /* @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* source :: A handle to the source glyph object. */ + /* */ + /* <Output> */ + /* target :: A handle to the target glyph object. 0~in case of */ + /* error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Transform */ + /* */ + /* <Description> */ + /* Transform a glyph image if its format is scalable. */ + /* */ + /* <InOut> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to a 2x2 matrix to apply. */ + /* */ + /* delta :: A pointer to a 2d vector to apply. Coordinates are */ + /* expressed in 1/64th of a pixel. */ + /* */ + /* <Return> */ + /* FreeType error code (if not 0, the glyph format is not scalable). */ + /* */ + /* <Note> */ + /* The 2x2 transformation matrix is also applied to the glyph's */ + /* advance vector. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_BBox_Mode */ + /* */ + /* <Description> */ + /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ + /* */ + /* <Values> */ + /* FT_GLYPH_BBOX_UNSCALED :: */ + /* Return unscaled font units. */ + /* */ + /* FT_GLYPH_BBOX_SUBPIXELS :: */ + /* Return unfitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_GRIDFIT :: */ + /* Return grid-fitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_TRUNCATE :: */ + /* Return coordinates in integer pixels. */ + /* */ + /* FT_GLYPH_BBOX_PIXELS :: */ + /* Return grid-fitted pixel coordinates. */ + /* */ + typedef enum FT_Glyph_BBox_Mode_ + { + FT_GLYPH_BBOX_UNSCALED = 0, + FT_GLYPH_BBOX_SUBPIXELS = 0, + FT_GLYPH_BBOX_GRIDFIT = 1, + FT_GLYPH_BBOX_TRUNCATE = 2, + FT_GLYPH_BBOX_PIXELS = 3 + + } FT_Glyph_BBox_Mode; + + + /* these constants are deprecated; use the corresponding */ + /* `FT_Glyph_BBox_Mode' values instead */ +#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED +#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS +#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT +#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE +#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Get_CBox */ + /* */ + /* <Description> */ + /* Return a glyph's `control box'. The control box encloses all the */ + /* outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* that contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component, which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the source glyph object. */ + /* */ + /* mode :: The mode that indicates how to interpret the returned */ + /* bounding box values. */ + /* */ + /* <Output> */ + /* acbox :: The glyph coordinate bounding box. Coordinates are */ + /* expressed in 1/64th of pixels if it is grid-fitted. */ + /* */ + /* <Note> */ + /* Coordinates are relative to the glyph origin, using the y~upwards */ + /* convention. */ + /* */ + /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ + /* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font */ + /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ + /* is another name for this constant. */ + /* */ + /* If the font is tricky and the glyph has been loaded with */ + /* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */ + /* reasonable values for the CBox it is necessary to load the glyph */ + /* at a large ppem value (so that the hinting instructions can */ + /* properly shift and scale the subglyphs), then extracting the CBox, */ + /* which can be eventually converted back to font units. */ + /* */ + /* Note that the maximum coordinates are exclusive, which means that */ + /* one can compute the width and height of the glyph image (be it in */ + /* integer or 26.6 pixels) as: */ + /* */ + /* { */ + /* width = bbox.xMax - bbox.xMin; */ + /* height = bbox.yMax - bbox.yMin; */ + /* } */ + /* */ + /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ + /* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, */ + /* which corresponds to: */ + /* */ + /* { */ + /* bbox.xMin = FLOOR(bbox.xMin); */ + /* bbox.yMin = FLOOR(bbox.yMin); */ + /* bbox.xMax = CEILING(bbox.xMax); */ + /* bbox.yMax = CEILING(bbox.yMax); */ + /* } */ + /* */ + /* To get the bbox in pixel coordinates, set `bbox_mode' to */ + /* @FT_GLYPH_BBOX_TRUNCATE. */ + /* */ + /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ + /* to @FT_GLYPH_BBOX_PIXELS. */ + /* */ + FT_EXPORT( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_To_Bitmap */ + /* */ + /* <Description> */ + /* Convert a given glyph object to a bitmap glyph object. */ + /* */ + /* <InOut> */ + /* the_glyph :: A pointer to a handle to the target glyph. */ + /* */ + /* <Input> */ + /* render_mode :: An enumeration that describes how the data is */ + /* rendered. */ + /* */ + /* origin :: A pointer to a vector used to translate the glyph */ + /* image before rendering. Can be~0 (if no */ + /* translation). The origin is expressed in */ + /* 26.6 pixels. */ + /* */ + /* destroy :: A boolean that indicates that the original glyph */ + /* image should be destroyed by this function. It is */ + /* never destroyed in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does nothing if the glyph format isn't scalable. */ + /* */ + /* The glyph image is translated with the `origin' vector before */ + /* rendering. */ + /* */ + /* The first parameter is a pointer to an @FT_Glyph handle, that will */ + /* be _replaced_ by this function (with newly allocated data). */ + /* Typically, you would use (omitting error handling): */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyph; */ + /* FT_BitmapGlyph glyph_bitmap; */ + /* */ + /* */ + /* // load glyph */ + /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ + /* */ + /* // extract glyph image */ + /* error = FT_Get_Glyph( face->glyph, &glyph ); */ + /* */ + /* // convert to a bitmap (default render mode + destroying old) */ + /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ + /* { */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ + /* 0, 1 ); */ + /* if ( error ) // `glyph' unchanged */ + /* ... */ + /* } */ + /* */ + /* // access bitmap content by typecasting */ + /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ + /* */ + /* // do funny stuff with it, like blitting/drawing */ + /* ... */ + /* */ + /* // discard glyph image (bitmap or not) */ + /* FT_Done_Glyph( glyph ); */ + /* } */ + /* */ + /* */ + /* Here another example, again without error handling: */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyphs[MAX_GLYPHS] */ + /* */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ + /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* { */ + /* FT_Glyph bitmap = glyphs[idx]; */ + /* */ + /* */ + /* ... */ + /* */ + /* // after this call, `bitmap' no longer points into */ + /* // the `glyphs' array (and the old value isn't destroyed) */ + /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ + /* */ + /* ... */ + /* */ + /* FT_Done_Glyph( bitmap ); */ + /* } */ + /* */ + /* ... */ + /* */ + /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ + /* FT_Done_Glyph( glyphs[idx] ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Glyph */ + /* */ + /* <Description> */ + /* Destroy a given glyph. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + FT_EXPORT( void ) + FT_Done_Glyph( FT_Glyph glyph ); + + /* */ + + + /* other helpful functions */ + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Multiply */ + /* */ + /* <Description> */ + /* Perform the matrix operation `b = a*b'. */ + /* */ + /* <Input> */ + /* a :: A pointer to matrix `a'. */ + /* */ + /* <InOut> */ + /* b :: A pointer to matrix `b'. */ + /* */ + /* <Note> */ + /* The result is undefined if either `a' or `b' is zero. */ + /* */ + FT_EXPORT( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix* b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Invert */ + /* */ + /* <Description> */ + /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ + /* */ + /* <InOut> */ + /* matrix :: A pointer to the target matrix. Remains untouched in */ + /* case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLYPH_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgxval.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgxval.h new file mode 100644 index 00000000..88c3d937 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgxval.h @@ -0,0 +1,357 @@ +/***************************************************************************/ +/* */ +/* ftgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004-2006, 2013 by */ +/* Masatake YAMATO, Redhat K.K, */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGXVAL_H__ +#define __FTGXVAL_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gx_validation */ + /* */ + /* <Title> */ + /* TrueTypeGX/AAT Validation */ + /* */ + /* <Abstract> */ + /* An API to validate TrueTypeGX/AAT tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ + /* trak, prop, lcar). */ + /* */ + /* <Order> */ + /* FT_TrueTypeGX_Validate */ + /* FT_TrueTypeGX_Free */ + /* */ + /* FT_ClassicKern_Validate */ + /* FT_ClassicKern_Free */ + /* */ + /* FT_VALIDATE_GX_LENGTH */ + /* FT_VALIDATE_GXXXX */ + /* FT_VALIDATE_CKERNXXX */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* */ + /* Warning: Use FT_VALIDATE_XXX to validate a table. */ + /* Following definitions are for gxvalid developers. */ + /* */ + /* */ + /*************************************************************************/ + +#define FT_VALIDATE_feat_INDEX 0 +#define FT_VALIDATE_mort_INDEX 1 +#define FT_VALIDATE_morx_INDEX 2 +#define FT_VALIDATE_bsln_INDEX 3 +#define FT_VALIDATE_just_INDEX 4 +#define FT_VALIDATE_kern_INDEX 5 +#define FT_VALIDATE_opbd_INDEX 6 +#define FT_VALIDATE_trak_INDEX 7 +#define FT_VALIDATE_prop_INDEX 8 +#define FT_VALIDATE_lcar_INDEX 9 +#define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX + + + /************************************************************************* + * + * @macro: + * FT_VALIDATE_GX_LENGTH + * + * @description: + * The number of tables checked in this module. Use it as a parameter + * for the `table-length' argument of function @FT_TrueTypeGX_Validate. + */ +#define FT_VALIDATE_GX_LENGTH (FT_VALIDATE_GX_LAST_INDEX + 1) + + /* */ + + /* Up to 0x1000 is used by otvalid. + Ox2xxx is reserved for feature OT extension. */ +#define FT_VALIDATE_GX_START 0x4000 +#define FT_VALIDATE_GX_BITFIELD( tag ) \ + ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_GXXXX + * + * @description: + * A list of bit-field constants used with @FT_TrueTypeGX_Validate to + * indicate which TrueTypeGX/AAT Type tables should be validated. + * + * @values: + * FT_VALIDATE_feat :: + * Validate `feat' table. + * + * FT_VALIDATE_mort :: + * Validate `mort' table. + * + * FT_VALIDATE_morx :: + * Validate `morx' table. + * + * FT_VALIDATE_bsln :: + * Validate `bsln' table. + * + * FT_VALIDATE_just :: + * Validate `just' table. + * + * FT_VALIDATE_kern :: + * Validate `kern' table. + * + * FT_VALIDATE_opbd :: + * Validate `opbd' table. + * + * FT_VALIDATE_trak :: + * Validate `trak' table. + * + * FT_VALIDATE_prop :: + * Validate `prop' table. + * + * FT_VALIDATE_lcar :: + * Validate `lcar' table. + * + * FT_VALIDATE_GX :: + * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, + * opbd, trak, prop and lcar). + * + */ + +#define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat ) +#define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort ) +#define FT_VALIDATE_morx FT_VALIDATE_GX_BITFIELD( morx ) +#define FT_VALIDATE_bsln FT_VALIDATE_GX_BITFIELD( bsln ) +#define FT_VALIDATE_just FT_VALIDATE_GX_BITFIELD( just ) +#define FT_VALIDATE_kern FT_VALIDATE_GX_BITFIELD( kern ) +#define FT_VALIDATE_opbd FT_VALIDATE_GX_BITFIELD( opbd ) +#define FT_VALIDATE_trak FT_VALIDATE_GX_BITFIELD( trak ) +#define FT_VALIDATE_prop FT_VALIDATE_GX_BITFIELD( prop ) +#define FT_VALIDATE_lcar FT_VALIDATE_GX_BITFIELD( lcar ) + +#define FT_VALIDATE_GX ( FT_VALIDATE_feat | \ + FT_VALIDATE_mort | \ + FT_VALIDATE_morx | \ + FT_VALIDATE_bsln | \ + FT_VALIDATE_just | \ + FT_VALIDATE_kern | \ + FT_VALIDATE_opbd | \ + FT_VALIDATE_trak | \ + FT_VALIDATE_prop | \ + FT_VALIDATE_lcar ) + + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Validate + * + * @description: + * Validate various TrueTypeGX tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library that + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the tables to be validated. See + * @FT_VALIDATE_GXXXX for possible values. + * + * table_length :: + * The size of the `tables' array. Normally, @FT_VALIDATE_GX_LENGTH + * should be passed. + * + * @output: + * tables :: + * The array where all validated sfnt tables are stored. + * The array itself must be allocated by a client. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with TrueTypeGX fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the buffers pointed to by + * each `tables' element, by calling @FT_TrueTypeGX_Free. A NULL value + * indicates that the table either doesn't exist in the font, the + * application hasn't asked for validation, or the validator doesn't have + * the ability to validate the sfnt table. + */ + FT_EXPORT( FT_Error ) + FT_TrueTypeGX_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Free + * + * @description: + * Free the buffer allocated by TrueTypeGX validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer allocated by + * @FT_TrueTypeGX_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_TrueTypeGX_Validate only. + */ + FT_EXPORT( void ) + FT_TrueTypeGX_Free( FT_Face face, + FT_Bytes table ); + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_CKERNXXX + * + * @description: + * A list of bit-field constants used with @FT_ClassicKern_Validate + * to indicate the classic kern dialect or dialects. If the selected + * type doesn't fit, @FT_ClassicKern_Validate regards the table as + * invalid. + * + * @values: + * FT_VALIDATE_MS :: + * Handle the `kern' table as a classic Microsoft kern table. + * + * FT_VALIDATE_APPLE :: + * Handle the `kern' table as a classic Apple kern table. + * + * FT_VALIDATE_CKERN :: + * Handle the `kern' as either classic Apple or Microsoft kern table. + */ +#define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 ) +#define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 ) + +#define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) + + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Validate + * + * @description: + * Validate classic (16-bit format) kern table to assure that the offsets + * and indices are valid. The idea is that a higher-level library that + * actually does the text layout can access those tables without error + * checking (which can be quite time consuming). + * + * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both + * the new 32-bit format and the classic 16-bit format, while + * FT_ClassicKern_Validate only supports the classic 16-bit format. + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the dialect to be validated. See + * @FT_VALIDATE_CKERNXXX for possible values. + * + * @output: + * ckern_table :: + * A pointer to the kern table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * After use, the application should deallocate the buffers pointed to by + * `ckern_table', by calling @FT_ClassicKern_Free. A NULL value + * indicates that the table doesn't exist in the font. + */ + FT_EXPORT( FT_Error ) + FT_ClassicKern_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *ckern_table ); + + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Free + * + * @description: + * Free the buffer allocated by classic Kern validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_ClassicKern_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_ClassicKern_Validate only. + */ + FT_EXPORT( void ) + FT_ClassicKern_Free( FT_Face face, + FT_Bytes table ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGXVAL_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgzip.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgzip.h new file mode 100644 index 00000000..eb346c6d --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftgzip.h @@ -0,0 +1,148 @@ +/***************************************************************************/ +/* */ +/* ftgzip.h */ +/* */ +/* Gzip-compressed stream support. */ +/* */ +/* Copyright 2002-2004, 2006, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGZIP_H__ +#define __FTGZIP_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gzip */ + /* */ + /* <Title> */ + /* GZIP Streams */ + /* */ + /* <Abstract> */ + /* Using gzip-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Gzip-specific functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************ + * + * @function: + * FT_Stream_OpenGzip + * + * @description: + * Open a new stream to parse gzip-compressed font files. This is + * mainly used to support the compressed `*.pcf.gz' fonts that come + * with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, gzip compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a gzipped stream from + * it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ); + + + /************************************************************************ + * + * @function: + * FT_Gzip_Uncompress + * + * @description: + * Decompress a zipped input buffer into an output buffer. This function + * is modeled after zlib's `uncompress' function. + * + * @input: + * memory :: + * A FreeType memory handle. + * + * input :: + * The input buffer. + * + * input_len :: + * The length of the input buffer. + * + * @output: + * output:: + * The output buffer. + * + * @inout: + * output_len :: + * Before calling the function, this is the the total size of the + * output buffer, which must be large enough to hold the entire + * uncompressed data (so the size of the uncompressed data must be + * known in advance). After calling the function, `output_len' is the + * size of the used data in `output'. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Gzip_Uncompress( FT_Memory memory, + FT_Byte* output, + FT_ULong* output_len, + const FT_Byte* input, + FT_ULong input_len ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGZIP_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftimage.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftimage.h new file mode 100644 index 00000000..2f7ca2aa --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftimage.h @@ -0,0 +1,1220 @@ +/***************************************************************************/ +/* */ +/* ftimage.h */ +/* */ +/* FreeType glyph image formats and default raster interface */ +/* (specification). */ +/* */ +/* Copyright 1996-2010, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Note: A `raster' is simply a scan-line converter, used to render */ + /* FT_Outlines into FT_Bitmaps. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTIMAGE_H__ +#define __FTIMAGE_H__ + + + /* _STANDALONE_ is from ftgrays.c */ +#ifndef _STANDALONE_ +#include <ft2build.h> +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pos */ + /* */ + /* <Description> */ + /* The type FT_Pos is used to store vectorial coordinates. Depending */ + /* on the context, these can represent distances in integer font */ + /* units, or 16.16, or 26.6 fixed-point pixel coordinates. */ + /* */ + typedef signed long FT_Pos; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Vector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector; coordinates are of */ + /* the FT_Pos type. */ + /* */ + /* <Fields> */ + /* x :: The horizontal coordinate. */ + /* y :: The vertical coordinate. */ + /* */ + typedef struct FT_Vector_ + { + FT_Pos x; + FT_Pos y; + + } FT_Vector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BBox */ + /* */ + /* <Description> */ + /* A structure used to hold an outline's bounding box, i.e., the */ + /* coordinates of its extrema in the horizontal and vertical */ + /* directions. */ + /* */ + /* <Fields> */ + /* xMin :: The horizontal minimum (left-most). */ + /* */ + /* yMin :: The vertical minimum (bottom-most). */ + /* */ + /* xMax :: The horizontal maximum (right-most). */ + /* */ + /* yMax :: The vertical maximum (top-most). */ + /* */ + /* <Note> */ + /* The bounding box is specified with the coordinates of the lower */ + /* left and the upper right corner. In PostScript, those values are */ + /* often called (llx,lly) and (urx,ury), respectively. */ + /* */ + /* If `yMin' is negative, this value gives the glyph's descender. */ + /* Otherwise, the glyph doesn't descend below the baseline. */ + /* Similarly, if `ymax' is positive, this value gives the glyph's */ + /* ascender. */ + /* */ + /* `xMin' gives the horizontal distance from the glyph's origin to */ + /* the left edge of the glyph's bounding box. If `xMin' is negative, */ + /* the glyph extends to the left of the origin. */ + /* */ + typedef struct FT_BBox_ + { + FT_Pos xMin, yMin; + FT_Pos xMax, yMax; + + } FT_BBox; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Pixel_Mode */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of pixels in a */ + /* given bitmap. Note that additional formats may be added in the */ + /* future. */ + /* */ + /* <Values> */ + /* FT_PIXEL_MODE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_PIXEL_MODE_MONO :: */ + /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ + /* are stored in most-significant order (MSB), which means that */ + /* the left-most pixel in a byte has value 128. */ + /* */ + /* FT_PIXEL_MODE_GRAY :: */ + /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ + /* images. Each pixel is stored in one byte. Note that the number */ + /* of `gray' levels is stored in the `num_grays' field of the */ + /* @FT_Bitmap structure (it generally is 256). */ + /* */ + /* FT_PIXEL_MODE_GRAY2 :: */ + /* A 2-bit per pixel bitmap, used to represent embedded */ + /* anti-aliased bitmaps in font files according to the OpenType */ + /* specification. We haven't found a single font using this */ + /* format, however. */ + /* */ + /* FT_PIXEL_MODE_GRAY4 :: */ + /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ + /* bitmaps in font files according to the OpenType specification. */ + /* We haven't found a single font using this format, however. */ + /* */ + /* FT_PIXEL_MODE_LCD :: */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on LCD displays; the bitmap is three times */ + /* wider than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD. */ + /* */ + /* FT_PIXEL_MODE_LCD_V :: */ + /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ + /* used for display on rotated LCD displays; the bitmap is three */ + /* times taller than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD_V. */ + /* */ + /* FT_PIXEL_MODE_BGRA :: */ + /* An image with four 8-bit channels per pixel, representing a */ + /* color image (such as emoticons) with alpha channel. For each */ + /* pixel, the format is BGRA, which means, the blue channel comes */ + /* first in memory. The color channels are pre-multiplied and in */ + /* the sRGB colorspace. For example, full red at half-translucent */ + /* opacity will be represented as `00,00,80,80', not `00,00,FF,80'. */ + /* See also @FT_LOAD_COLOR. */ + /* */ + typedef enum FT_Pixel_Mode_ + { + FT_PIXEL_MODE_NONE = 0, + FT_PIXEL_MODE_MONO, + FT_PIXEL_MODE_GRAY, + FT_PIXEL_MODE_GRAY2, + FT_PIXEL_MODE_GRAY4, + FT_PIXEL_MODE_LCD, + FT_PIXEL_MODE_LCD_V, + FT_PIXEL_MODE_BGRA, + + FT_PIXEL_MODE_MAX /* do not remove */ + + } FT_Pixel_Mode; + + + /* these constants are deprecated; use the corresponding `FT_Pixel_Mode' */ + /* values instead. */ +#define ft_pixel_mode_none FT_PIXEL_MODE_NONE +#define ft_pixel_mode_mono FT_PIXEL_MODE_MONO +#define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY +#define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 +#define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap */ + /* */ + /* <Description> */ + /* A structure used to describe a bitmap or pixmap to the raster. */ + /* Note that we now manage pixmaps of various depths through the */ + /* `pixel_mode' field. */ + /* */ + /* <Fields> */ + /* rows :: The number of bitmap rows. */ + /* */ + /* width :: The number of pixels in bitmap row. */ + /* */ + /* pitch :: The pitch's absolute value is the number of bytes */ + /* taken by one bitmap row, including padding. */ + /* However, the pitch is positive when the bitmap has */ + /* a `down' flow, and negative when it has an `up' */ + /* flow. In all cases, the pitch is an offset to add */ + /* to a bitmap pointer in order to go down one row. */ + /* */ + /* Note that `padding' means the alignment of a */ + /* bitmap to a byte border, and FreeType functions */ + /* normally align to the smallest possible integer */ + /* value. */ + /* */ + /* For the B/W rasterizer, `pitch' is always an even */ + /* number. */ + /* */ + /* To change the pitch of a bitmap (say, to make it a */ + /* multiple of 4), use @FT_Bitmap_Convert. */ + /* Alternatively, you might use callback functions to */ + /* directly render to the application's surface; see */ + /* the file `example2.cpp' in the tutorial for a */ + /* demonstration. */ + /* */ + /* buffer :: A typeless pointer to the bitmap buffer. This */ + /* value should be aligned on 32-bit boundaries in */ + /* most cases. */ + /* */ + /* num_grays :: This field is only used with */ + /* @FT_PIXEL_MODE_GRAY; it gives the number of gray */ + /* levels used in the bitmap. */ + /* */ + /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ + /* See @FT_Pixel_Mode for possible values. */ + /* */ + /* palette_mode :: This field is intended for paletted pixel modes; */ + /* it indicates how the palette is stored. Not */ + /* used currently. */ + /* */ + /* palette :: A typeless pointer to the bitmap palette; this */ + /* field is intended for paletted pixel modes. Not */ + /* used currently. */ + /* */ + /* <Note> */ + /* For now, the only pixel modes supported by FreeType are mono and */ + /* grays. However, drivers might be added in the future to support */ + /* more `colorful' options. */ + /* */ + typedef struct FT_Bitmap_ + { + unsigned int rows; + unsigned int width; + int pitch; + unsigned char* buffer; + unsigned short num_grays; + unsigned char pixel_mode; + unsigned char palette_mode; + void* palette; + + } FT_Bitmap; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline */ + /* */ + /* <Description> */ + /* This structure is used to describe an outline to the scan-line */ + /* converter. */ + /* */ + /* <Fields> */ + /* n_contours :: The number of contours in the outline. */ + /* */ + /* n_points :: The number of points in the outline. */ + /* */ + /* points :: A pointer to an array of `n_points' @FT_Vector */ + /* elements, giving the outline's point coordinates. */ + /* */ + /* tags :: A pointer to an array of `n_points' chars, giving */ + /* each outline point's type. */ + /* */ + /* If bit~0 is unset, the point is `off' the curve, */ + /* i.e., a Bézier control point, while it is `on' if */ + /* set. */ + /* */ + /* Bit~1 is meaningful for `off' points only. If set, */ + /* it indicates a third-order Bézier arc control point; */ + /* and a second-order control point if unset. */ + /* */ + /* If bit~2 is set, bits 5-7 contain the drop-out mode */ + /* (as defined in the OpenType specification; the value */ + /* is the same as the argument to the SCANMODE */ + /* instruction). */ + /* */ + /* Bits 3 and~4 are reserved for internal purposes. */ + /* */ + /* contours :: An array of `n_contours' shorts, giving the end */ + /* point of each contour within the outline. For */ + /* example, the first contour is defined by the points */ + /* `0' to `contours[0]', the second one is defined by */ + /* the points `contours[0]+1' to `contours[1]', etc. */ + /* */ + /* flags :: A set of bit flags used to characterize the outline */ + /* and give hints to the scan-converter and hinter on */ + /* how to convert/grid-fit it. See @FT_OUTLINE_XXX. */ + /* */ + /* <Note> */ + /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ + /* first point of each contour. The drop-out mode as given with */ + /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ + /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ + /* */ + typedef struct FT_Outline_ + { + short n_contours; /* number of contours in glyph */ + short n_points; /* number of points in the glyph */ + + FT_Vector* points; /* the outline's points */ + char* tags; /* the points flags */ + short* contours; /* the contour end points */ + + int flags; /* outline masks */ + + } FT_Outline; + + /* */ + + /* Following limits must be consistent with */ + /* FT_Outline.{n_contours,n_points} */ +#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX +#define FT_OUTLINE_POINTS_MAX SHRT_MAX + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OUTLINE_XXX */ + /* */ + /* <Description> */ + /* A list of bit-field constants use for the flags in an outline's */ + /* `flags' field. */ + /* */ + /* <Values> */ + /* FT_OUTLINE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_OUTLINE_OWNER :: */ + /* If set, this flag indicates that the outline's field arrays */ + /* (i.e., `points', `flags', and `contours') are `owned' by the */ + /* outline object, and should thus be freed when it is destroyed. */ + /* */ + /* FT_OUTLINE_EVEN_ODD_FILL :: */ + /* By default, outlines are filled using the non-zero winding rule. */ + /* If set to 1, the outline will be filled using the even-odd fill */ + /* rule (only works with the smooth rasterizer). */ + /* */ + /* FT_OUTLINE_REVERSE_FILL :: */ + /* By default, outside contours of an outline are oriented in */ + /* clock-wise direction, as defined in the TrueType specification. */ + /* This flag is set if the outline uses the opposite direction */ + /* (typically for Type~1 fonts). This flag is ignored by the scan */ + /* converter. */ + /* */ + /* FT_OUTLINE_IGNORE_DROPOUTS :: */ + /* By default, the scan converter will try to detect drop-outs in */ + /* an outline and correct the glyph bitmap to ensure consistent */ + /* shape continuity. If set, this flag hints the scan-line */ + /* converter to ignore such cases. See below for more information. */ + /* */ + /* FT_OUTLINE_SMART_DROPOUTS :: */ + /* Select smart dropout control. If unset, use simple dropout */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ + /* below for more information. */ + /* */ + /* FT_OUTLINE_INCLUDE_STUBS :: */ + /* If set, turn pixels on for `stubs', otherwise exclude them. */ + /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ + /* more information. */ + /* */ + /* FT_OUTLINE_HIGH_PRECISION :: */ + /* This flag indicates that the scan-line converter should try to */ + /* convert this outline to bitmaps with the highest possible */ + /* quality. It is typically set for small character sizes. Note */ + /* that this is only a hint that might be completely ignored by a */ + /* given scan-converter. */ + /* */ + /* FT_OUTLINE_SINGLE_PASS :: */ + /* This flag is set to force a given scan-converter to only use a */ + /* single pass over the outline to render a bitmap glyph image. */ + /* Normally, it is set for very large character sizes. It is only */ + /* a hint that might be completely ignored by a given */ + /* scan-converter. */ + /* */ + /* <Note> */ + /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ + /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ + /* rasterizer. */ + /* */ + /* There exists a second mechanism to pass the drop-out mode to the */ + /* B/W rasterizer; see the `tags' field in @FT_Outline. */ + /* */ + /* Please refer to the description of the `SCANTYPE' instruction in */ + /* the OpenType specification (in file `ttinst1.doc') how simple */ + /* drop-outs, smart drop-outs, and stubs are defined. */ + /* */ +#define FT_OUTLINE_NONE 0x0 +#define FT_OUTLINE_OWNER 0x1 +#define FT_OUTLINE_EVEN_ODD_FILL 0x2 +#define FT_OUTLINE_REVERSE_FILL 0x4 +#define FT_OUTLINE_IGNORE_DROPOUTS 0x8 +#define FT_OUTLINE_SMART_DROPOUTS 0x10 +#define FT_OUTLINE_INCLUDE_STUBS 0x20 + +#define FT_OUTLINE_HIGH_PRECISION 0x100 +#define FT_OUTLINE_SINGLE_PASS 0x200 + + + /* these constants are deprecated; use the corresponding */ + /* `FT_OUTLINE_XXX' values instead */ +#define ft_outline_none FT_OUTLINE_NONE +#define ft_outline_owner FT_OUTLINE_OWNER +#define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL +#define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL +#define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS +#define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION +#define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS + + /* */ + +#define FT_CURVE_TAG( flag ) ( flag & 3 ) + +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 + +#define FT_CURVE_TAG_HAS_SCANMODE 4 + +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ + +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) + +#define FT_Curve_Tag_On FT_CURVE_TAG_ON +#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC +#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC +#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X +#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_MoveToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `move */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `move to' is emitted to start a new contour in an outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `move to'. */ + /* */ + /* user :: A typeless pointer, which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_MoveToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_LineToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `line */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `line to' is emitted to indicate a segment in the outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `line to'. */ + /* */ + /* user :: A typeless pointer, which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_LineToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_LineTo_Func FT_Outline_LineToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_ConicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `conic */ + /* to' function during outline walking or decomposition. */ + /* */ + /* A `conic to' is emitted to indicate a second-order Bézier arc in */ + /* the outline. */ + /* */ + /* <Input> */ + /* control :: An intermediate control point between the last position */ + /* and the new target in `to'. */ + /* */ + /* to :: A pointer to the target end point of the conic arc. */ + /* */ + /* user :: A typeless pointer, which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_ConicToFunc)( const FT_Vector* control, + const FT_Vector* to, + void* user ); + +#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_CubicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `cubic */ + /* to' function during outline walking or decomposition. */ + /* */ + /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first Bézier control point. */ + /* */ + /* control2 :: A pointer to the second Bézier control point. */ + /* */ + /* to :: A pointer to the target end point. */ + /* */ + /* user :: A typeless pointer, which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_CubicToFunc)( const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to, + void* user ); + +#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline_Funcs */ + /* */ + /* <Description> */ + /* A structure to hold various function pointers used during outline */ + /* decomposition in order to emit segments, conic, and cubic Béziers. */ + /* */ + /* <Fields> */ + /* move_to :: The `move to' emitter. */ + /* */ + /* line_to :: The segment emitter. */ + /* */ + /* conic_to :: The second-order Bézier arc emitter. */ + /* */ + /* cubic_to :: The third-order Bézier arc emitter. */ + /* */ + /* shift :: The shift that is applied to coordinates before they */ + /* are sent to the emitter. */ + /* */ + /* delta :: The delta that is applied to coordinates before they */ + /* are sent to the emitter, but after the shift. */ + /* */ + /* <Note> */ + /* The point coordinates sent to the emitters are the transformed */ + /* version of the original coordinates (this is important for high */ + /* accuracy during scan-conversion). The transformation is simple: */ + /* */ + /* { */ + /* x' = (x << shift) - delta */ + /* y' = (x << shift) - delta */ + /* } */ + /* */ + /* Set the values of `shift' and `delta' to~0 to get the original */ + /* point coordinates. */ + /* */ + typedef struct FT_Outline_Funcs_ + { + FT_Outline_MoveToFunc move_to; + FT_Outline_LineToFunc line_to; + FT_Outline_ConicToFunc conic_to; + FT_Outline_CubicToFunc cubic_to; + + int shift; + FT_Pos delta; + + } FT_Outline_Funcs; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_IMAGE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags to an unsigned long type. */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ +#ifndef FT_IMAGE_TAG +#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ + value = ( ( (unsigned long)_x1 << 24 ) | \ + ( (unsigned long)_x2 << 16 ) | \ + ( (unsigned long)_x3 << 8 ) | \ + (unsigned long)_x4 ) +#endif /* FT_IMAGE_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_Format */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of a given glyph */ + /* image. Note that this version of FreeType only supports two image */ + /* formats, even though future font drivers will be able to register */ + /* their own format. */ + /* */ + /* <Values> */ + /* FT_GLYPH_FORMAT_NONE :: */ + /* The value~0 is reserved. */ + /* */ + /* FT_GLYPH_FORMAT_COMPOSITE :: */ + /* The glyph image is a composite of several other images. This */ + /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ + /* report compound glyphs (like accented characters). */ + /* */ + /* FT_GLYPH_FORMAT_BITMAP :: */ + /* The glyph image is a bitmap, and can be described as an */ + /* @FT_Bitmap. You generally need to access the `bitmap' field of */ + /* the @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_OUTLINE :: */ + /* The glyph image is a vectorial outline made of line segments */ + /* and Bézier arcs; it can be described as an @FT_Outline; you */ + /* generally want to access the `outline' field of the */ + /* @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_PLOTTER :: */ + /* The glyph image is a vectorial path with no inside and outside */ + /* contours. Some Type~1 fonts, like those in the Hershey family, */ + /* contain glyphs in this format. These are described as */ + /* @FT_Outline, but FreeType isn't currently capable of rendering */ + /* them correctly. */ + /* */ + typedef enum FT_Glyph_Format_ + { + FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), + + FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ) + + } FT_Glyph_Format; + + + /* these constants are deprecated; use the corresponding */ + /* `FT_Glyph_Format' values instead. */ +#define ft_glyph_format_none FT_GLYPH_FORMAT_NONE +#define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE +#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP +#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE +#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** R A S T E R D E F I N I T I O N S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A raster is a scan converter, in charge of rendering an outline into */ + /* a a bitmap. This section contains the public API for rasters. */ + /* */ + /* Note that in FreeType 2, all rasters are now encapsulated within */ + /* specific modules called `renderers'. See `ftrender.h' for more */ + /* details on renderers. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* raster */ + /* */ + /* <Title> */ + /* Scanline Converter */ + /* */ + /* <Abstract> */ + /* How vectorial outlines are converted into bitmaps and pixmaps. */ + /* */ + /* <Description> */ + /* This section contains technical definitions. */ + /* */ + /* <Order> */ + /* FT_Raster */ + /* FT_Span */ + /* FT_SpanFunc */ + /* */ + /* FT_Raster_Params */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* FT_Raster_NewFunc */ + /* FT_Raster_DoneFunc */ + /* FT_Raster_ResetFunc */ + /* FT_Raster_SetModeFunc */ + /* FT_Raster_RenderFunc */ + /* FT_Raster_Funcs */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Raster */ + /* */ + /* <Description> */ + /* An opaque handle (pointer) to a raster object. Each object can be */ + /* used independently to convert an outline into a bitmap or pixmap. */ + /* */ + typedef struct FT_RasterRec_* FT_Raster; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Span */ + /* */ + /* <Description> */ + /* A structure used to model a single span of gray pixels when */ + /* rendering an anti-aliased bitmap. */ + /* */ + /* <Fields> */ + /* x :: The span's horizontal start position. */ + /* */ + /* len :: The span's length in pixels. */ + /* */ + /* coverage :: The span color/coverage, ranging from 0 (background) */ + /* to 255 (foreground). */ + /* */ + /* <Note> */ + /* This structure is used by the span drawing callback type named */ + /* @FT_SpanFunc that takes the y~coordinate of the span as a */ + /* parameter. */ + /* */ + /* The coverage value is always between 0 and 255. If you want less */ + /* gray values, the callback function has to reduce them. */ + /* */ + typedef struct FT_Span_ + { + short x; + unsigned short len; + unsigned char coverage; + + } FT_Span; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_SpanFunc */ + /* */ + /* <Description> */ + /* A function used as a call-back by the anti-aliased renderer in */ + /* order to let client applications draw themselves the gray pixel */ + /* spans on each scan line. */ + /* */ + /* <Input> */ + /* y :: The scanline's y~coordinate. */ + /* */ + /* count :: The number of spans to draw on this scanline. */ + /* */ + /* spans :: A table of `count' spans to draw on the scanline. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Note> */ + /* This callback allows client applications to directly render the */ + /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ + /* */ + /* This can be used to write anti-aliased outlines directly to a */ + /* given background bitmap, and even perform translucency. */ + /* */ + /* Note that the `count' field cannot be greater than a fixed value */ + /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ + /* `ftoption.h'. By default, this value is set to~32, which means */ + /* that if there are more than 32~spans on a given scanline, the */ + /* callback is called several times with the same `y' parameter in */ + /* order to draw all callbacks. */ + /* */ + /* Otherwise, the callback is only called once per scan-line, and */ + /* only for those scanlines that do have `gray' pixels on them. */ + /* */ + typedef void + (*FT_SpanFunc)( int y, + int count, + const FT_Span* spans, + void* user ); + +#define FT_Raster_Span_Func FT_SpanFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitTest_Func */ + /* */ + /* <Description> */ + /* Deprecated, unimplemented. */ + /* */ + typedef int + (*FT_Raster_BitTest_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitSet_Func */ + /* */ + /* <Description> */ + /* Deprecated, unimplemented. */ + /* */ + typedef void + (*FT_Raster_BitSet_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flag constants as used in the `flags' field of a */ + /* @FT_Raster_Params structure. */ + /* */ + /* <Values> */ + /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ + /* */ + /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ + /* anti-aliased glyph image should be */ + /* generated. Otherwise, it will be */ + /* monochrome (1-bit). */ + /* */ + /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ + /* rendering. In this mode, client */ + /* applications must provide their own span */ + /* callback. This lets them directly */ + /* draw or compose over an existing bitmap. */ + /* If this bit is not set, the target */ + /* pixmap's buffer _must_ be zeroed before */ + /* rendering. */ + /* */ + /* Direct rendering is only possible with */ + /* anti-aliased glyphs. */ + /* */ + /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ + /* rendering mode. If set, the output will */ + /* be clipped to a box specified in the */ + /* `clip_box' field of the */ + /* @FT_Raster_Params structure. */ + /* */ + /* Note that by default, the glyph bitmap */ + /* is clipped to the target pixmap, except */ + /* in direct rendering mode where all spans */ + /* are generated if no clipping box is set. */ + /* */ +#define FT_RASTER_FLAG_DEFAULT 0x0 +#define FT_RASTER_FLAG_AA 0x1 +#define FT_RASTER_FLAG_DIRECT 0x2 +#define FT_RASTER_FLAG_CLIP 0x4 + + /* these constants are deprecated; use the corresponding */ + /* `FT_RASTER_FLAG_XXX' values instead */ +#define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT +#define ft_raster_flag_aa FT_RASTER_FLAG_AA +#define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT +#define ft_raster_flag_clip FT_RASTER_FLAG_CLIP + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Params */ + /* */ + /* <Description> */ + /* A structure to hold the arguments used by a raster's render */ + /* function. */ + /* */ + /* <Fields> */ + /* target :: The target bitmap. */ + /* */ + /* source :: A pointer to the source glyph image (e.g., an */ + /* @FT_Outline). */ + /* */ + /* flags :: The rendering flags. */ + /* */ + /* gray_spans :: The gray span drawing callback. */ + /* */ + /* black_spans :: Unused. */ + /* */ + /* bit_test :: Unused. */ + /* */ + /* bit_set :: Unused. */ + /* */ + /* user :: User-supplied data that is passed to each drawing */ + /* callback. */ + /* */ + /* clip_box :: An optional clipping box. It is only used in */ + /* direct rendering mode. Note that coordinates here */ + /* should be expressed in _integer_ pixels (and not in */ + /* 26.6 fixed-point units). */ + /* */ + /* <Note> */ + /* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA */ + /* bit flag is set in the `flags' field, otherwise a monochrome */ + /* bitmap is generated. */ + /* */ + /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ + /* raster will call the `gray_spans' callback to draw gray pixel */ + /* spans. This allows direct composition over a pre-existing bitmap */ + /* through user-provided callbacks to perform the span drawing and */ + /* composition. Not supported by the monochrome rasterizer. */ + /* */ + typedef struct FT_Raster_Params_ + { + const FT_Bitmap* target; + const void* source; + int flags; + FT_SpanFunc gray_spans; + FT_SpanFunc black_spans; /* unused */ + FT_Raster_BitTest_Func bit_test; /* unused */ + FT_Raster_BitSet_Func bit_set; /* unused */ + void* user; + FT_BBox clip_box; + + } FT_Raster_Params; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_NewFunc */ + /* */ + /* <Description> */ + /* A function used to create a new raster object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory allocator. */ + /* */ + /* <Output> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `memory' parameter is a typeless pointer in order to avoid */ + /* un-wanted dependencies on the rest of the FreeType code. In */ + /* practice, it is an @FT_Memory object, i.e., a handle to the */ + /* standard FreeType memory allocator. However, this field can be */ + /* completely ignored by a given raster implementation. */ + /* */ + typedef int + (*FT_Raster_NewFunc)( void* memory, + FT_Raster* raster ); + +#define FT_Raster_New_Func FT_Raster_NewFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_DoneFunc */ + /* */ + /* <Description> */ + /* A function used to destroy a given raster object. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + typedef void + (*FT_Raster_DoneFunc)( FT_Raster raster ); + +#define FT_Raster_Done_Func FT_Raster_DoneFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_ResetFunc */ + /* */ + /* <Description> */ + /* FreeType provides an area of memory called the `render pool', */ + /* available to all registered rasters. This pool can be freely used */ + /* during a given scan-conversion but is shared by all rasters. Its */ + /* content is thus transient. */ + /* */ + /* This function is called each time the render pool changes, or just */ + /* after a new raster object is created. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* pool_base :: The address in memory of the render pool. */ + /* */ + /* pool_size :: The size in bytes of the render pool. */ + /* */ + /* <Note> */ + /* Rasters can ignore the render pool and rely on dynamic memory */ + /* allocation if they want to (a handle to the memory allocator is */ + /* passed to the raster constructor). However, this is not */ + /* recommended for efficiency purposes. */ + /* */ + typedef void + (*FT_Raster_ResetFunc)( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ); + +#define FT_Raster_Reset_Func FT_Raster_ResetFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_SetModeFunc */ + /* */ + /* <Description> */ + /* This function is a generic facility to change modes or attributes */ + /* in a given raster. This can be used for debugging purposes, or */ + /* simply to allow implementation-specific `features' in a given */ + /* raster module. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* mode :: A 4-byte tag used to name the mode or property. */ + /* */ + /* args :: A pointer to the new mode/property to use. */ + /* */ + typedef int + (*FT_Raster_SetModeFunc)( FT_Raster raster, + unsigned long mode, + void* args ); + +#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_RenderFunc */ + /* */ + /* <Description> */ + /* Invoke a given raster to scan-convert a given glyph image into a */ + /* target bitmap. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* store the rendering parameters. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The exact format of the source image depends on the raster's glyph */ + /* format defined in its @FT_Raster_Funcs structure. It can be an */ + /* @FT_Outline or anything else in order to support a large array of */ + /* glyph formats. */ + /* */ + /* Note also that the render function can fail and return a */ + /* `FT_Err_Unimplemented_Feature' error code if the raster used does */ + /* not support direct composition. */ + /* */ + /* XXX: For now, the standard raster doesn't support direct */ + /* composition but this should change for the final release (see */ + /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ + /* for examples of distinct implementations that support direct */ + /* composition). */ + /* */ + typedef int + (*FT_Raster_RenderFunc)( FT_Raster raster, + const FT_Raster_Params* params ); + +#define FT_Raster_Render_Func FT_Raster_RenderFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Funcs */ + /* */ + /* <Description> */ + /* A structure used to describe a given raster class to the library. */ + /* */ + /* <Fields> */ + /* glyph_format :: The supported glyph format for this raster. */ + /* */ + /* raster_new :: The raster constructor. */ + /* */ + /* raster_reset :: Used to reset the render pool within the raster. */ + /* */ + /* raster_render :: A function to render a glyph into a given bitmap. */ + /* */ + /* raster_done :: The raster destructor. */ + /* */ + typedef struct FT_Raster_Funcs_ + { + FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; + FT_Raster_ResetFunc raster_reset; + FT_Raster_SetModeFunc raster_set_mode; + FT_Raster_RenderFunc raster_render; + FT_Raster_DoneFunc raster_done; + + } FT_Raster_Funcs; + + /* */ + + +FT_END_HEADER + +#endif /* __FTIMAGE_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftincrem.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftincrem.h new file mode 100644 index 00000000..4c0246c5 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftincrem.h @@ -0,0 +1,354 @@ +/***************************************************************************/ +/* */ +/* ftincrem.h */ +/* */ +/* FreeType incremental loading (specification). */ +/* */ +/* Copyright 2002, 2003, 2006-2008, 2010, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTINCREM_H__ +#define __FTINCREM_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * incremental + * + * @title: + * Incremental Loading + * + * @abstract: + * Custom Glyph Loading. + * + * @description: + * This section contains various functions used to perform so-called + * `incremental' glyph loading. This is a mode where all glyphs loaded + * from a given @FT_Face are provided by the client application. + * + * Apart from that, all other tables are loaded normally from the font + * file. This mode is useful when FreeType is used within another + * engine, e.g., a PostScript Imaging Processor. + * + * To enable this mode, you must use @FT_Open_Face, passing an + * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an + * @FT_Incremental_Interface value. See the comments for + * @FT_Incremental_InterfaceRec for an example. + * + */ + + + /*************************************************************************** + * + * @type: + * FT_Incremental + * + * @description: + * An opaque type describing a user-provided object used to implement + * `incremental' glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g., PostScript interpreters), + * where the glyph data isn't in the font file, or must be overridden by + * different values. + * + * @note: + * It is up to client applications to create and implement @FT_Incremental + * objects, as long as they provide implementations for the methods + * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc + * and @FT_Incremental_GetGlyphMetricsFunc. + * + * See the description of @FT_Incremental_InterfaceRec to understand how + * to use incremental objects with FreeType. + * + */ + typedef struct FT_IncrementalRec_* FT_Incremental; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_MetricsRec + * + * @description: + * A small structure used to contain the basic glyph metrics returned + * by the @FT_Incremental_GetGlyphMetricsFunc method. + * + * @fields: + * bearing_x :: + * Left bearing, in font units. + * + * bearing_y :: + * Top bearing, in font units. + * + * advance :: + * Horizontal component of glyph advance, in font units. + * + * advance_v :: + * Vertical component of glyph advance, in font units. + * + * @note: + * These correspond to horizontal or vertical metrics depending on the + * value of the `vertical' argument to the function + * @FT_Incremental_GetGlyphMetricsFunc. + * + */ + typedef struct FT_Incremental_MetricsRec_ + { + FT_Long bearing_x; + FT_Long bearing_y; + FT_Long advance; + FT_Long advance_v; /* since 2.3.12 */ + + } FT_Incremental_MetricsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_Metrics + * + * @description: + * A handle to an @FT_Incremental_MetricsRec structure. + * + */ + typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphDataFunc + * + * @description: + * A function called by FreeType to access a given glyph's data bytes + * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is + * enabled. + * + * Note that the format of the glyph's data bytes depends on the font + * file format. For TrueType, it must correspond to the raw bytes within + * the `glyf' table. For PostScript formats, it must correspond to the + * *unencrypted* charstring bytes, without any `lenIV' header. It is + * undefined for any other format. + * + * @input: + * incremental :: + * Handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * @output: + * adata :: + * A structure describing the returned glyph data bytes (which will be + * accessed as a read-only byte block). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If this function returns successfully the method + * @FT_Incremental_FreeGlyphDataFunc will be called later to release + * the data bytes. + * + * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for + * compound glyphs. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Data* adata ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_FreeGlyphDataFunc + * + * @description: + * A function used to release the glyph data bytes returned by a + * successful call to @FT_Incremental_GetGlyphDataFunc. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * data :: + * A structure describing the glyph data bytes (which will be accessed + * as a read-only byte block). + * + */ + typedef void + (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, + FT_Data* data ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphMetricsFunc + * + * @description: + * A function used to retrieve the basic metrics of a given glyph index + * before accessing its data. This is necessary because, in certain + * formats like TrueType, the metrics are stored in a different place from + * the glyph images proper. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * vertical :: + * If true, return vertical metrics. + * + * ametrics :: + * This parameter is used for both input and output. + * The original glyph metrics, if any, in font units. If metrics are + * not available all the values must be set to zero. + * + * @output: + * ametrics :: + * The replacement glyph metrics in font units. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphMetricsFunc) + ( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Bool vertical, + FT_Incremental_MetricsRec *ametrics ); + + + /************************************************************************** + * + * @struct: + * FT_Incremental_FuncsRec + * + * @description: + * A table of functions for accessing fonts that load data + * incrementally. Used in @FT_Incremental_InterfaceRec. + * + * @fields: + * get_glyph_data :: + * The function to get glyph data. Must not be null. + * + * free_glyph_data :: + * The function to release glyph data. Must not be null. + * + * get_glyph_metrics :: + * The function to get glyph metrics. May be null if the font does + * not provide overriding glyph metrics. + * + */ + typedef struct FT_Incremental_FuncsRec_ + { + FT_Incremental_GetGlyphDataFunc get_glyph_data; + FT_Incremental_FreeGlyphDataFunc free_glyph_data; + FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; + + } FT_Incremental_FuncsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_InterfaceRec + * + * @description: + * A structure to be used with @FT_Open_Face to indicate that the user + * wants to support incremental glyph loading. You should use it with + * @FT_PARAM_TAG_INCREMENTAL as in the following example: + * + * { + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; + * + * + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; + * + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; + * + * // set up FT_Open_Args structure + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument + * + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * } + * + */ + typedef struct FT_Incremental_InterfaceRec_ + { + const FT_Incremental_FuncsRec* funcs; + FT_Incremental object; + + } FT_Incremental_InterfaceRec; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_Interface + * + * @description: + * A pointer to an @FT_Incremental_InterfaceRec structure. + * + */ + typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * A constant used as the tag of @FT_Parameter structures to indicate + * an incremental loading object to be used by FreeType. + * + */ +#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) + + /* */ + + +FT_END_HEADER + +#endif /* __FTINCREM_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlcdfil.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlcdfil.h new file mode 100644 index 00000000..e8679c1a --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlcdfil.h @@ -0,0 +1,251 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.h */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs */ +/* (specification). */ +/* */ +/* Copyright 2006-2008, 2010, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_LCD_FILTER_H__ +#define __FT_LCD_FILTER_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * lcd_filtering + * + * @title: + * LCD Filtering + * + * @abstract: + * Reduce color fringes of LCD-optimized bitmaps. + * + * @description: + * The @FT_Library_SetLcdFilter API can be used to specify a low-pass + * filter, which is then applied to LCD-optimized bitmaps generated + * through @FT_Render_Glyph. This is useful to reduce color fringes + * that would occur with unfiltered rendering. + * + * Note that no filter is active by default, and that this function is + * *not* implemented in default builds of the library. You need to + * #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file + * in order to activate it. + * + * FreeType generates alpha coverage maps, which are linear by nature. + * For instance, the value 0x80 in bitmap representation means that + * (within numerical precision) 0x80/0xFF fraction of that pixel is + * covered by the glyph's outline. The blending function for placing + * text over a background is + * + * { + * dst = alpha * src + (1 - alpha) * dst , + * } + * + * which is known as OVER. However, when calculating the output of the + * OVER operator, the source colors should first be transformed to a + * linear color space, then alpha blended in that space, and transformed + * back to the output color space. + * + * When linear light blending is used, the default FIR5 filtering + * weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as + * they have been designed for black on white rendering while lacking + * gamma correction. To preserve color neutrality, weights for a FIR5 + * filter should be chosen according to two free parameters `a' and `c', + * and the FIR weights should be + * + * { + * [a - c, a + c, 2 * a, a + c, a - c] . + * } + * + * This formula generates equal weights for all the color primaries + * across the filter kernel, which makes it colorless. One suggested + * set of weights is + * + * { + * [0x10, 0x50, 0x60, 0x50, 0x10] , + * } + * + * where `a' has value 0x30 and `b' value 0x20. The weights in filter + * may have a sum larger than 0x100, which increases coloration slightly + * but also improves contrast. + */ + + + /**************************************************************************** + * + * @enum: + * FT_LcdFilter + * + * @description: + * A list of values to identify various types of LCD filters. + * + * @values: + * FT_LCD_FILTER_NONE :: + * Do not perform filtering. When used with subpixel rendering, this + * results in sometimes severe color fringes. + * + * FT_LCD_FILTER_DEFAULT :: + * The default filter reduces color fringes considerably, at the cost + * of a slight blurriness in the output. + * + * FT_LCD_FILTER_LIGHT :: + * The light filter is a variant that produces less blurriness at the + * cost of slightly more color fringes than the default one. It might + * be better, depending on taste, your monitor, or your personal vision. + * + * FT_LCD_FILTER_LEGACY :: + * This filter corresponds to the original libXft color filter. It + * provides high contrast output but can exhibit really bad color + * fringes if glyphs are not extremely well hinted to the pixel grid. + * In other words, it only works well if the TrueType bytecode + * interpreter is enabled *and* high-quality hinted fonts are used. + * + * This filter is only provided for comparison purposes, and might be + * disabled or stay unsupported in the future. + * + * @since: + * 2.3.0 + */ + typedef enum FT_LcdFilter_ + { + FT_LCD_FILTER_NONE = 0, + FT_LCD_FILTER_DEFAULT = 1, + FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY = 16, + + FT_LCD_FILTER_MAX /* do not remove */ + + } FT_LcdFilter; + + + /************************************************************************** + * + * @func: + * FT_Library_SetLcdFilter + * + * @description: + * This function is used to apply color filtering to LCD decimated + * bitmaps, like the ones used when calling @FT_Render_Glyph with + * @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V. + * + * @input: + * library :: + * A handle to the target library instance. + * + * filter :: + * The filter type. + * + * You can use @FT_LCD_FILTER_NONE here to disable this feature, or + * @FT_LCD_FILTER_DEFAULT to use a default filter that should work + * well on most LCD screens. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This feature is always disabled by default. Clients must make an + * explicit call to this function with a `filter' value other than + * @FT_LCD_FILTER_NONE in order to enable it. + * + * Due to *PATENTS* covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature' if the + * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * defined in your build of the library, which should correspond to all + * default builds of FreeType. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char. + * + * It does _not_ affect the output of @FT_Outline_Render and + * @FT_Outline_Get_Bitmap. + * + * If this feature is activated, the dimensions of LCD glyph bitmaps are + * either larger or taller than the dimensions of the corresponding + * outline with regards to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and + * up to 3~pixels to the right. + * + * The bitmap offset values are adjusted correctly, so clients shouldn't + * need to modify their layout and glyph positioning code when enabling + * the filter. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ); + + + /************************************************************************** + * + * @func: + * FT_Library_SetLcdFilterWeights + * + * @description: + * Use this function to override the filter weights selected by + * @FT_Library_SetLcdFilter. By default, FreeType uses the quintuple + * (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10, + * 0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and + * FT_LCD_FILTER_LEGACY. + * + * @input: + * library :: + * A handle to the target library instance. + * + * weights :: + * A pointer to an array; the function copies the first five bytes and + * uses them to specify the filter weights. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Due to *PATENTS* covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature' if the + * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * defined in your build of the library, which should correspond to all + * default builds of FreeType. + * + * This function must be called after @FT_Library_SetLcdFilter to have + * any effect. + * + * @since: + * 2.4.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilterWeights( FT_Library library, + unsigned char *weights ); + + /* */ + + +FT_END_HEADER + +#endif /* __FT_LCD_FILTER_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlist.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlist.h new file mode 100644 index 00000000..9950a279 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlist.h @@ -0,0 +1,276 @@ +/***************************************************************************/ +/* */ +/* ftlist.h */ +/* */ +/* Generic list support for FreeType (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2007, 2010, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file implements functions relative to list processing. Its */ + /* data structures are defined in `freetype.h'. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTLIST_H__ +#define __FTLIST_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /* <Title> */ + /* List Processing */ + /* */ + /* <Abstract> */ + /* Simple management of lists. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to list */ + /* processing using doubly-linked nodes. */ + /* */ + /* <Order> */ + /* FT_List */ + /* FT_ListNode */ + /* FT_ListRec */ + /* FT_ListNodeRec */ + /* */ + /* FT_List_Add */ + /* FT_List_Insert */ + /* FT_List_Find */ + /* FT_List_Remove */ + /* FT_List_Up */ + /* FT_List_Iterate */ + /* FT_List_Iterator */ + /* FT_List_Finalize */ + /* FT_List_Destructor */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Find */ + /* */ + /* <Description> */ + /* Find the list node for a given listed object. */ + /* */ + /* <Input> */ + /* list :: A pointer to the parent list. */ + /* data :: The address of the listed object. */ + /* */ + /* <Return> */ + /* List node. NULL if it wasn't found. */ + /* */ + FT_EXPORT( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Add */ + /* */ + /* <Description> */ + /* Append an element to the end of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to append. */ + /* */ + FT_EXPORT( void ) + FT_List_Add( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Insert */ + /* */ + /* <Description> */ + /* Insert an element at the head of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to parent list. */ + /* node :: The node to insert. */ + /* */ + FT_EXPORT( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Remove */ + /* */ + /* <Description> */ + /* Remove a node from a list. This function doesn't check whether */ + /* the node is in the list! */ + /* */ + /* <Input> */ + /* node :: The node to remove. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* */ + FT_EXPORT( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Up */ + /* */ + /* <Description> */ + /* Move a node to the head/top of a list. Used to maintain LRU */ + /* lists. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to move. */ + /* */ + FT_EXPORT( void ) + FT_List_Up( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Iterator */ + /* */ + /* <Description> */ + /* An FT_List iterator function that is called during a list parse */ + /* by @FT_List_Iterate. */ + /* */ + /* <Input> */ + /* node :: The current iteration list node. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. */ + /* Can be used to point to the iteration's state. */ + /* */ + typedef FT_Error + (*FT_List_Iterator)( FT_ListNode node, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Iterate */ + /* */ + /* <Description> */ + /* Parse a list and calls a given iterator function on each element. */ + /* Note that parsing is stopped as soon as one of the iterator calls */ + /* returns a non-zero value. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* iterator :: An iterator function, called on each node of the list. */ + /* user :: A user-supplied field that is passed as the second */ + /* argument to the iterator. */ + /* */ + /* <Return> */ + /* The result (a FreeType error code) of the last iterator call. */ + /* */ + FT_EXPORT( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Destructor */ + /* */ + /* <Description> */ + /* An @FT_List iterator function that is called during a list */ + /* finalization by @FT_List_Finalize to destroy all elements in a */ + /* given list. */ + /* */ + /* <Input> */ + /* system :: The current system object. */ + /* */ + /* data :: The current object to destroy. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. It can */ + /* be used to point to the iteration's state. */ + /* */ + typedef void + (*FT_List_Destructor)( FT_Memory memory, + void* data, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Finalize */ + /* */ + /* <Description> */ + /* Destroy all elements in the list as well as the list itself. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* */ + /* destroy :: A list destructor that will be applied to each element */ + /* of the list. Set this to NULL if not needed. */ + /* */ + /* memory :: The current memory object that handles deallocation. */ + /* */ + /* user :: A user-supplied field that is passed as the last */ + /* argument to the destructor. */ + /* */ + /* <Note> */ + /* This function expects that all nodes added by @FT_List_Add or */ + /* @FT_List_Insert have been dynamically allocated. */ + /* */ + FT_EXPORT( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTLIST_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlzw.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlzw.h new file mode 100644 index 00000000..857c0c52 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftlzw.h @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* ftlzw.h */ +/* */ +/* LZW-compressed stream support. */ +/* */ +/* Copyright 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTLZW_H__ +#define __FTLZW_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* lzw */ + /* */ + /* <Title> */ + /* LZW Streams */ + /* */ + /* <Abstract> */ + /* Using LZW-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of LZW-specific functions. */ + /* */ + /*************************************************************************/ + + /************************************************************************ + * + * @function: + * FT_Stream_OpenLZW + * + * @description: + * Open a new stream to parse LZW-compressed font files. This is + * mainly used to support the compressed `*.pcf.Z' fonts that come + * with XFree86. + * + * @input: + * stream :: The target embedding stream. + * + * source :: The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream + * + * In certain builds of the library, LZW compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a LZW stream from it + * and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with LZW support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTLZW_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmac.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmac.h new file mode 100644 index 00000000..42874fe6 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmac.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* ftmac.h */ +/* */ +/* Additional Mac-specific API. */ +/* */ +/* Copyright 1996-2001, 2004, 2006, 2007, 2013 by */ +/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* NOTE: Include this file after FT_FREETYPE_H and after any */ +/* Mac-specific headers (because this header uses Mac types such as */ +/* Handle, FSSpec, FSRef, etc.) */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMAC_H__ +#define __FTMAC_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + +/* gcc-3.4.1 and later can warn about functions tagged as deprecated */ +#ifndef FT_DEPRECATED_ATTRIBUTE +#if defined(__GNUC__) && \ + ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) +#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#else +#define FT_DEPRECATED_ATTRIBUTE +#endif +#endif + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* mac_specific */ + /* */ + /* <Title> */ + /* Mac Specific Interface */ + /* */ + /* <Abstract> */ + /* Only available on the Macintosh. */ + /* */ + /* <Description> */ + /* The following definitions are only available if FreeType is */ + /* compiled on a Macintosh. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FOND */ + /* */ + /* <Description> */ + /* Create a new face object from a FOND resource. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* fond :: A FOND resource. */ + /* */ + /* face_index :: Only supported for the -1 `sanity check' special */ + /* case. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Notes> */ + /* This function can be used to create @FT_Face objects from fonts */ + /* that are installed in the system as follows. */ + /* */ + /* { */ + /* fond = GetResource( 'FOND', fontName ); */ + /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font (e.g., Times New Roman */ + /* Bold). */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFilePath_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return a pathname of the disk file and face index for given font */ + /* name that is handled by ATS framework. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* path :: Buffer to store pathname of the file. For passing */ + /* to @FT_New_Face. The client must allocate this */ + /* buffer before calling this function. */ + /* */ + /* maxPathSize :: Lengths of the buffer `path' that client allocated. */ + /* */ + /* face_index :: Index of the face. For passing to @FT_New_Face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, + UInt8* path, + UInt32 maxPathSize, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSSpec to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSSpec to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ + /* it accepts an FSSpec instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSRef */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSRef to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSRef to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ + /* it accepts an FSRef instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSRef( FT_Library library, + const FSRef *ref, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + /* */ + + +FT_END_HEADER + + +#endif /* __FTMAC_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmm.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmm.h new file mode 100644 index 00000000..2dcfd678 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmm.h @@ -0,0 +1,373 @@ +/***************************************************************************/ +/* */ +/* ftmm.h */ +/* */ +/* FreeType Multiple Master font interface (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMM_H__ +#define __FTMM_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* multiple_masters */ + /* */ + /* <Title> */ + /* Multiple Masters */ + /* */ + /* <Abstract> */ + /* How to manage Multiple Masters fonts. */ + /* */ + /* <Description> */ + /* The following types and functions are used to manage Multiple */ + /* Master fonts, i.e., the selection of specific design instances by */ + /* setting design axis coordinates. */ + /* */ + /* George Williams has extended this interface to make it work with */ + /* both Type~1 Multiple Masters fonts and GX distortable (var) */ + /* fonts. Some of these routines only work with MM fonts, others */ + /* will work with both types. They are similar enough that a */ + /* consistent interface makes sense. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters fonts. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + typedef struct FT_MM_Axis_ + { + FT_String* name; + FT_Long minimum; + FT_Long maximum; + + } FT_MM_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Multi_Master */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* font. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* num_axis :: Number of axes. Cannot exceed~4. */ + /* */ + /* num_designs :: Number of designs; should be normally 2^num_axis */ + /* even though the Type~1 specification strangely */ + /* allows for intermediate designs to be present. This */ + /* number cannot exceed~16. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* */ + typedef struct FT_Multi_Master_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_MM_Axis axis[T1_MAX_MM_AXIS]; + + } FT_Multi_Master; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters and GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* Not always meaningful for GX. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* def :: The axis's default design coordinate. */ + /* FreeType computes meaningful default values for MM; it */ + /* is then an integer value, not in 16.16 format. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + /* tag :: The axis's tag (the GX equivalent to `name'). */ + /* FreeType provides default values for MM if possible. */ + /* */ + /* strid :: The entry in `name' table (another GX version of */ + /* `name'). */ + /* Not meaningful for MM. */ + /* */ + typedef struct FT_Var_Axis_ + { + FT_String* name; + + FT_Fixed minimum; + FT_Fixed def; + FT_Fixed maximum; + + FT_ULong tag; + FT_UInt strid; + + } FT_Var_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Named_Style */ + /* */ + /* <Description> */ + /* A simple structure used to model a named style in a GX var font. */ + /* */ + /* This structure can't be used for MM fonts. */ + /* */ + /* <Fields> */ + /* coords :: The design coordinates for this style. */ + /* This is an array with one entry for each axis. */ + /* */ + /* strid :: The entry in `name' table identifying this style. */ + /* */ + typedef struct FT_Var_Named_Style_ + { + FT_Fixed* coords; + FT_UInt strid; + + } FT_Var_Named_Style; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Var */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* or GX var distortable font. */ + /* */ + /* Some fields are specific to one format and not to the other. */ + /* */ + /* <Fields> */ + /* num_axis :: The number of axes. The maximum value is~4 for */ + /* MM; no limit in GX. */ + /* */ + /* num_designs :: The number of designs; should be normally */ + /* 2^num_axis for MM fonts. Not meaningful for GX */ + /* (where every glyph could have a different */ + /* number of designs). */ + /* */ + /* num_namedstyles :: The number of named styles; only meaningful for */ + /* GX that allows certain design coordinates to */ + /* have a string ID (in the `name' table) */ + /* associated with them. The font can tell the */ + /* user that, for example, Weight=1.5 is `Bold'. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* GX fonts contain slightly more data than MM. */ + /* */ + /* namedstyles :: A table of named styles. */ + /* Only meaningful with GX. */ + /* */ + typedef struct FT_MM_Var_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_UInt num_namedstyles; + FT_Var_Axis* axis; + FT_Var_Named_Style* namedstyle; + + } FT_MM_Var; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Multi_Master */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master descriptor of a given font. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_MM_Var */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master/GX var descriptor of a given font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters/GX var descriptor. */ + /* Allocates a data structure, which the user must free. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Var( FT_Face face, + FT_MM_Var* *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters fonts, choose an interpolated font design */ + /* through design coordinates. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Master or GX Var fonts, choose an interpolated font */ + /* design through design coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Blend_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters and GX var fonts, choose an interpolated font */ + /* design through normalized blend coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: The design coordinates array (each element must be */ + /* between 0 and 1.0). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Blend_Coordinates */ + /* */ + /* <Description> */ + /* This is another name of @FT_Set_MM_Blend_Coordinates. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTMM_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmodapi.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmodapi.h new file mode 100644 index 00000000..980f15d3 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmodapi.h @@ -0,0 +1,667 @@ +/***************************************************************************/ +/* */ +/* ftmodapi.h */ +/* */ +/* FreeType modules public interface (specification). */ +/* */ +/* Copyright 1996-2003, 2006, 2008-2010, 2012, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMODAPI_H__ +#define __FTMODAPI_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /* <Title> */ + /* Module Management */ + /* */ + /* <Abstract> */ + /* How to add, upgrade, remove, and control modules from FreeType. */ + /* */ + /* <Description> */ + /* The definitions below are used to manage modules within FreeType. */ + /* Modules can be added, upgraded, and removed at runtime. */ + /* Additionally, some module properties can be controlled also. */ + /* */ + /* Here is a list of possible values of the `module_name' field in */ + /* the @FT_Module_Class structure. */ + /* */ + /* { */ + /* autofitter */ + /* bdf */ + /* cff */ + /* gxvalid */ + /* otvalid */ + /* pcf */ + /* pfr */ + /* psaux */ + /* pshinter */ + /* psnames */ + /* raster1, raster5 */ + /* sfnt */ + /* smooth, smooth-lcd, smooth-lcdv */ + /* truetype */ + /* type1 */ + /* type42 */ + /* t1cid */ + /* winfonts */ + /* } */ + /* */ + /* Note that the FreeType Cache sub-system is not a FreeType module. */ + /* */ + /* <Order> */ + /* FT_Module */ + /* FT_Module_Constructor */ + /* FT_Module_Destructor */ + /* FT_Module_Requester */ + /* FT_Module_Class */ + /* */ + /* FT_Add_Module */ + /* FT_Get_Module */ + /* FT_Remove_Module */ + /* FT_Add_Default_Modules */ + /* */ + /* FT_Property_Set */ + /* FT_Property_Get */ + /* */ + /* FT_New_Library */ + /* FT_Done_Library */ + /* FT_Reference_Library */ + /* */ + /* FT_Renderer */ + /* FT_Renderer_Class */ + /* */ + /* FT_Get_Renderer */ + /* FT_Set_Renderer */ + /* */ + /* FT_Set_Debug_Hook */ + /* */ + /*************************************************************************/ + + + /* module bit flags */ +#define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ +#define FT_MODULE_RENDERER 2 /* this module is a renderer */ +#define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ +#define FT_MODULE_STYLER 8 /* this module is a styler */ + +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ + /* scalable fonts */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ + /* support vector outlines */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ + /* own hinter */ + + + /* deprecated values */ +#define ft_module_font_driver FT_MODULE_FONT_DRIVER +#define ft_module_renderer FT_MODULE_RENDERER +#define ft_module_hinter FT_MODULE_HINTER +#define ft_module_styler FT_MODULE_STYLER + +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER + + + typedef FT_Pointer FT_Module_Interface; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Constructor */ + /* */ + /* <Description> */ + /* A function used to initialize (not create) a new module object. */ + /* */ + /* <Input> */ + /* module :: The module to initialize. */ + /* */ + typedef FT_Error + (*FT_Module_Constructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destructor */ + /* */ + /* <Description> */ + /* A function used to finalize (not destroy) a given module object. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + typedef void + (*FT_Module_Destructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Requester */ + /* */ + /* <Description> */ + /* A function used to query a given module for a specific interface. */ + /* */ + /* <Input> */ + /* module :: The module to be searched. */ + /* */ + /* name :: The name of the interface in the module. */ + /* */ + typedef FT_Module_Interface + (*FT_Module_Requester)( FT_Module module, + const char* name ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Module_Class */ + /* */ + /* <Description> */ + /* The module class descriptor. */ + /* */ + /* <Fields> */ + /* module_flags :: Bit flags describing the module. */ + /* */ + /* module_size :: The size of one module object/instance in */ + /* bytes. */ + /* */ + /* module_name :: The name of the module. */ + /* */ + /* module_version :: The version, as a 16.16 fixed number */ + /* (major.minor). */ + /* */ + /* module_requires :: The version of FreeType this module requires, */ + /* as a 16.16 fixed number (major.minor). Starts */ + /* at version 2.0, i.e., 0x20000. */ + /* */ + /* module_init :: The initializing function. */ + /* */ + /* module_done :: The finalizing function. */ + /* */ + /* get_interface :: The interface requesting function. */ + /* */ + typedef struct FT_Module_Class_ + { + FT_ULong module_flags; + FT_Long module_size; + const FT_String* module_name; + FT_Fixed module_version; + FT_Fixed module_requires; + + const void* module_interface; + + FT_Module_Constructor module_init; + FT_Module_Destructor module_done; + FT_Module_Requester get_interface; + + } FT_Module_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Module */ + /* */ + /* <Description> */ + /* Add a new module to a given library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* clazz :: A pointer to class descriptor for the module. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module */ + /* */ + /* <Description> */ + /* Find a module by its name. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module handle. 0~if none was found. */ + /* */ + /* <Note> */ + /* FreeType's internal modules aren't documented very well, and you */ + /* should look up the source code for details. */ + /* */ + FT_EXPORT( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Remove_Module */ + /* */ + /* <Description> */ + /* Remove a given module from a library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to a library object. */ + /* */ + /* <Input> */ + /* module :: A handle to a module object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The module object is destroyed by the function in case of success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ); + + + /********************************************************************** + * + * @function: + * FT_Property_Set + * + * @description: + * Set a property for a given module. + * + * @input: + * library :: + * A handle to the library the module is part of. + * + * module_name :: + * The module name. + * + * property_name :: + * The property name. Properties are described in the `Synopsis' + * subsection of the module's documentation. + * + * Note that only a few modules have properties. + * + * value :: + * A generic pointer to a variable or structure that gives the new + * value of the property. The exact definition of `value' is + * dependent on the property; see the `Synopsis' subsection of the + * module's documentation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `module_name' isn't a valid module name, or `property_name' + * doesn't specify a valid property, or if `value' doesn't represent a + * valid value for the given property, an error is returned. + * + * The following example sets property `bar' (a simple integer) in + * module `foo' to value~1. + * + * { + * FT_UInt bar; + * + * + * bar = 1; + * FT_Property_Set( library, "foo", "bar", &bar ); + * } + * + * Note that the FreeType Cache sub-system doesn't recognize module + * property changes. To avoid glyph lookup confusion within the cache + * you should call @FTC_Manager_Reset to completely flush the cache if + * a module property gets changed after @FTC_Manager_New has been + * called. + * + * It is not possible to set properties of the FreeType Cache + * sub-system itself with FT_Property_Set; use @FTC_Property_Set + * instead. + * + * @since: + * 2.4.11 + * + */ + FT_EXPORT( FT_Error ) + FT_Property_Set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + const void* value ); + + + /********************************************************************** + * + * @function: + * FT_Property_Get + * + * @description: + * Get a module's property value. + * + * @input: + * library :: + * A handle to the library the module is part of. + * + * module_name :: + * The module name. + * + * property_name :: + * The property name. Properties are described in the `Synopsis' + * subsection of the module's documentation. + * + * @inout: + * value :: + * A generic pointer to a variable or structure that gives the + * value of the property. The exact definition of `value' is + * dependent on the property; see the `Synopsis' subsection of the + * module's documentation. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `module_name' isn't a valid module name, or `property_name' + * doesn't specify a valid property, or if `value' doesn't represent a + * valid value for the given property, an error is returned. + * + * The following example gets property `baz' (a range) in module `foo'. + * + * { + * typedef range_ + * { + * FT_Int32 min; + * FT_Int32 max; + * + * } range; + * + * range baz; + * + * + * FT_Property_Get( library, "foo", "baz", &baz ); + * } + * + * It is not possible to retrieve properties of the FreeType Cache + * sub-system with FT_Property_Get; use @FTC_Property_Get instead. + * + * @since: + * 2.4.11 + * + */ + FT_EXPORT( FT_Error ) + FT_Property_Get( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + void* value ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Reference_Library */ + /* */ + /* <Description> */ + /* A counter gets initialized to~1 at the time an @FT_Library */ + /* structure is created. This function increments the counter. */ + /* @FT_Done_Library then only destroys a library if the counter is~1, */ + /* otherwise it simply decrements the counter. */ + /* */ + /* This function helps in managing life-cycles of structures that */ + /* reference @FT_Library objects. */ + /* */ + /* <Input> */ + /* library :: A handle to a target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.4.2 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Reference_Library( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Library */ + /* */ + /* <Description> */ + /* This function is used to create a new FreeType library instance */ + /* from a given memory object. It is thus possible to use libraries */ + /* with distinct memory allocators within the same program. */ + /* */ + /* Normally, you would call this function (followed by a call to */ + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ + /* instead of @FT_Init_FreeType to initialize the FreeType library. */ + /* */ + /* Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a */ + /* library instance. */ + /* */ + /* <Input> */ + /* memory :: A handle to the original memory object. */ + /* */ + /* <Output> */ + /* alibrary :: A pointer to handle of a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Library */ + /* */ + /* <Description> */ + /* Discard a given library object. This closes all drivers and */ + /* discards all resource objects. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* See the discussion of reference counters in the description of */ + /* @FT_Reference_Library. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Library( FT_Library library ); + + /* */ + + typedef void + (*FT_DebugHook_Func)( void* arg ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Debug_Hook */ + /* */ + /* <Description> */ + /* Set a debug hook function for debugging the interpreter of a font */ + /* format. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* hook_index :: The index of the debug hook. You should use the */ + /* values defined in `ftobjs.h', e.g., */ + /* `FT_DEBUG_HOOK_TRUETYPE'. */ + /* */ + /* debug_hook :: The function used to debug the interpreter. */ + /* */ + /* <Note> */ + /* Currently, four debug hook slots are available, but only two (for */ + /* the TrueType and the Type~1 interpreter) are defined. */ + /* */ + /* Since the internal headers of FreeType are no longer installed, */ + /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ + /* This is a bug and will be fixed in a forthcoming release. */ + /* */ + FT_EXPORT( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Default_Modules */ + /* */ + /* <Description> */ + /* Add the set of default drivers to a given library object. */ + /* This is only useful when you create a library object with */ + /* @FT_New_Library (usually to plug a custom memory manager). */ + /* */ + /* <InOut> */ + /* library :: A handle to a new library object. */ + /* */ + FT_EXPORT( void ) + FT_Add_Default_Modules( FT_Library library ); + + + + /************************************************************************** + * + * @section: + * truetype_engine + * + * @title: + * The TrueType Engine + * + * @abstract: + * TrueType bytecode support. + * + * @description: + * This section contains a function used to query the level of TrueType + * bytecode support compiled in this version of the library. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_TrueTypeEngineType + * + * @description: + * A list of values describing which kind of TrueType bytecode + * engine is implemented in a given FT_Library instance. It is used + * by the @FT_Get_TrueType_Engine_Type function. + * + * @values: + * FT_TRUETYPE_ENGINE_TYPE_NONE :: + * The library doesn't implement any kind of bytecode interpreter. + * + * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: + * The library implements a bytecode interpreter that doesn't + * support the patented operations of the TrueType virtual machine. + * + * Its main use is to load certain Asian fonts that position and + * scale glyph components with bytecode instructions. It produces + * bad output for most other fonts. + * + * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: + * The library implements a bytecode interpreter that covers + * the full instruction set of the TrueType virtual machine (this + * was governed by patents until May 2010, hence the name). + * + * @since: + * 2.2 + * + */ + typedef enum FT_TrueTypeEngineType_ + { + FT_TRUETYPE_ENGINE_TYPE_NONE = 0, + FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, + FT_TRUETYPE_ENGINE_TYPE_PATENTED + + } FT_TrueTypeEngineType; + + + /************************************************************************** + * + * @func: + * FT_Get_TrueType_Engine_Type + * + * @description: + * Return an @FT_TrueTypeEngineType value to indicate which level of + * the TrueType virtual machine a given library instance supports. + * + * @input: + * library :: + * A library instance. + * + * @return: + * A value indicating which level is supported. + * + * @since: + * 2.2 + * + */ + FT_EXPORT( FT_TrueTypeEngineType ) + FT_Get_TrueType_Engine_Type( FT_Library library ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTMODAPI_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmoderr.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmoderr.h new file mode 100644 index 00000000..5a27db15 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftmoderr.h @@ -0,0 +1,194 @@ +/***************************************************************************/ +/* */ +/* ftmoderr.h */ +/* */ +/* FreeType module error offsets (specification). */ +/* */ +/* Copyright 2001-2005, 2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the FreeType module error codes. */ + /* */ + /* If the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in `ftoption.h' is */ + /* set, the lower byte of an error value identifies the error code as */ + /* usual. In addition, the higher byte identifies the module. For */ + /* example, the error `FT_Err_Invalid_File_Format' has value 0x0003, the */ + /* error `TT_Err_Invalid_File_Format' has value 0x1303, the error */ + /* `T1_Err_Invalid_File_Format' has value 0x1403, etc. */ + /* */ + /* Note that `FT_Err_Ok', `TT_Err_Ok', etc. are always equal to zero, */ + /* including the high byte. */ + /* */ + /* If FT_CONFIG_OPTION_USE_MODULE_ERRORS isn't set, the higher byte of */ + /* an error value is set to zero. */ + /* */ + /* To hide the various `XXX_Err_' prefixes in the source code, FreeType */ + /* provides some macros in `fttypes.h'. */ + /* */ + /* FT_ERR( err ) */ + /* Add current error module prefix (as defined with the */ + /* `FT_ERR_PREFIX' macro) to `err'. For example, in the BDF module */ + /* the line */ + /* */ + /* error = FT_ERR( Invalid_Outline ); */ + /* */ + /* expands to */ + /* */ + /* error = BDF_Err_Invalid_Outline; */ + /* */ + /* For simplicity, you can always use `FT_Err_Ok' directly instead */ + /* of `FT_ERR( Ok )'. */ + /* */ + /* FT_ERR_EQ( errcode, err ) */ + /* FT_ERR_NEQ( errcode, err ) */ + /* Compare error code `errcode' with the error `err' for equality */ + /* and inequality, respectively. Example: */ + /* */ + /* if ( FT_ERR_EQ( error, Invalid_Outline ) ) */ + /* ... */ + /* */ + /* Using this macro you don't have to think about error prefixes. */ + /* Of course, if module errors are not active, the above example is */ + /* the same as */ + /* */ + /* if ( error == FT_Err_Invalid_Outline ) */ + /* ... */ + /* */ + /* FT_ERROR_BASE( errcode ) */ + /* FT_ERROR_MODULE( errcode ) */ + /* Get base error and module error code, respectively. */ + /* */ + /* */ + /* It can also be used to create a module error message table easily */ + /* with something like */ + /* */ + /* { */ + /* #undef __FTMODERR_H__ */ + /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ + /* #define FT_MODERR_START_LIST { */ + /* #define FT_MODERR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int mod_err_offset; */ + /* const char* mod_err_msg */ + /* } ft_mod_errors[] = */ + /* */ + /* #include FT_MODULE_ERRORS_H */ + /* } */ + /* */ + /*************************************************************************/ + + +#ifndef __FTMODERR_H__ +#define __FTMODERR_H__ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#ifndef FT_MODERRDEF + +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = v, +#else +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, +#endif + +#define FT_MODERR_START_LIST enum { +#define FT_MODERR_END_LIST FT_Mod_Err_Max }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_MODERRDEF */ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST MODULE ERROR BASES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_MODERR_START_LIST + FT_MODERR_START_LIST +#endif + + + FT_MODERRDEF( Base, 0x000, "base module" ) + FT_MODERRDEF( Autofit, 0x100, "autofitter module" ) + FT_MODERRDEF( BDF, 0x200, "BDF module" ) + FT_MODERRDEF( Bzip2, 0x300, "Bzip2 module" ) + FT_MODERRDEF( Cache, 0x400, "cache module" ) + FT_MODERRDEF( CFF, 0x500, "CFF module" ) + FT_MODERRDEF( CID, 0x600, "CID module" ) + FT_MODERRDEF( Gzip, 0x700, "Gzip module" ) + FT_MODERRDEF( LZW, 0x800, "LZW module" ) + FT_MODERRDEF( OTvalid, 0x900, "OpenType validation module" ) + FT_MODERRDEF( PCF, 0xA00, "PCF module" ) + FT_MODERRDEF( PFR, 0xB00, "PFR module" ) + FT_MODERRDEF( PSaux, 0xC00, "PS auxiliary module" ) + FT_MODERRDEF( PShinter, 0xD00, "PS hinter module" ) + FT_MODERRDEF( PSnames, 0xE00, "PS names module" ) + FT_MODERRDEF( Raster, 0xF00, "raster module" ) + FT_MODERRDEF( SFNT, 0x1000, "SFNT module" ) + FT_MODERRDEF( Smooth, 0x1100, "smooth raster module" ) + FT_MODERRDEF( TrueType, 0x1200, "TrueType module" ) + FT_MODERRDEF( Type1, 0x1300, "Type 1 module" ) + FT_MODERRDEF( Type42, 0x1400, "Type 42 module" ) + FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" ) + FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" ) + + +#ifdef FT_MODERR_END_LIST + FT_MODERR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_MODERR_START_LIST +#undef FT_MODERR_END_LIST +#undef FT_MODERRDEF +#undef FT_NEED_EXTERN_C + + +#endif /* __FTMODERR_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftotval.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftotval.h new file mode 100644 index 00000000..75ba03ee --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftotval.h @@ -0,0 +1,204 @@ +/***************************************************************************/ +/* */ +/* ftotval.h */ +/* */ +/* FreeType API for validating OpenType tables (specification). */ +/* */ +/* Copyright 2004-2007, 2013, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* */ +/* Warning: This module might be moved to a different library in the */ +/* future to avoid a tight dependency between FreeType and the */ +/* OpenType specification. */ +/* */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOTVAL_H__ +#define __FTOTVAL_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* ot_validation */ + /* */ + /* <Title> */ + /* OpenType Validation */ + /* */ + /* <Abstract> */ + /* An API to validate OpenType tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ + /* */ + /* <Order> */ + /* FT_OpenType_Validate */ + /* FT_OpenType_Free */ + /* */ + /* FT_VALIDATE_OTXXX */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_OTXXX + * + * @description: + * A list of bit-field constants used with @FT_OpenType_Validate to + * indicate which OpenType tables should be validated. + * + * @values: + * FT_VALIDATE_BASE :: + * Validate BASE table. + * + * FT_VALIDATE_GDEF :: + * Validate GDEF table. + * + * FT_VALIDATE_GPOS :: + * Validate GPOS table. + * + * FT_VALIDATE_GSUB :: + * Validate GSUB table. + * + * FT_VALIDATE_JSTF :: + * Validate JSTF table. + * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * + * FT_VALIDATE_OT :: + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). + * + */ +#define FT_VALIDATE_BASE 0x0100 +#define FT_VALIDATE_GDEF 0x0200 +#define FT_VALIDATE_GPOS 0x0400 +#define FT_VALIDATE_GSUB 0x0800 +#define FT_VALIDATE_JSTF 0x1000 +#define FT_VALIDATE_MATH 0x2000 + +#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH + + /********************************************************************** + * + * @function: + * FT_OpenType_Validate + * + * @description: + * Validate various OpenType tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library that + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field that specifies the tables to be validated. See + * @FT_VALIDATE_OTXXX for possible values. + * + * @output: + * BASE_table :: + * A pointer to the BASE table. + * + * GDEF_table :: + * A pointer to the GDEF table. + * + * GPOS_table :: + * A pointer to the GPOS table. + * + * GSUB_table :: + * A pointer to the GSUB table. + * + * JSTF_table :: + * A pointer to the JSTF table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with OpenType fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the five tables with + * @FT_OpenType_Free. A NULL value indicates that the table either + * doesn't exist in the font, or the application hasn't asked for + * validation. + */ + FT_EXPORT( FT_Error ) + FT_OpenType_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *BASE_table, + FT_Bytes *GDEF_table, + FT_Bytes *GPOS_table, + FT_Bytes *GSUB_table, + FT_Bytes *JSTF_table ); + + /********************************************************************** + * + * @function: + * FT_OpenType_Free + * + * @description: + * Free the buffer allocated by OpenType validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_OpenType_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_OpenType_Validate only. + */ + FT_EXPORT( void ) + FT_OpenType_Free( FT_Face face, + FT_Bytes table ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTOTVAL_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftoutln.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftoutln.h new file mode 100644 index 00000000..d3b8fbd2 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftoutln.h @@ -0,0 +1,574 @@ +/***************************************************************************/ +/* */ +/* ftoutln.h */ +/* */ +/* Support for the FT_Outline type used to store glyph shapes of */ +/* most scalable font formats (specification). */ +/* */ +/* Copyright 1996-2003, 2005-2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOUTLN_H__ +#define __FTOUTLN_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /* <Title> */ + /* Outline Processing */ + /* */ + /* <Abstract> */ + /* Functions to create, transform, and render vectorial glyph images. */ + /* */ + /* <Description> */ + /* This section contains routines used to create and destroy scalable */ + /* glyph images known as `outlines'. These can also be measured, */ + /* transformed, and converted into bitmaps and pixmaps. */ + /* */ + /* <Order> */ + /* FT_Outline */ + /* FT_Outline_New */ + /* FT_Outline_Done */ + /* FT_Outline_Copy */ + /* FT_Outline_Translate */ + /* FT_Outline_Transform */ + /* FT_Outline_Embolden */ + /* FT_Outline_EmboldenXY */ + /* FT_Outline_Reverse */ + /* FT_Outline_Check */ + /* */ + /* FT_Outline_Get_CBox */ + /* FT_Outline_Get_BBox */ + /* */ + /* FT_Outline_Get_Bitmap */ + /* FT_Outline_Render */ + /* FT_Outline_Decompose */ + /* FT_Outline_Funcs */ + /* FT_Outline_MoveToFunc */ + /* FT_Outline_LineToFunc */ + /* FT_Outline_ConicToFunc */ + /* FT_Outline_CubicToFunc */ + /* */ + /* FT_Orientation */ + /* FT_Outline_Get_Orientation */ + /* */ + /* FT_OUTLINE_XXX */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and Bézier arcs. This function also emits `move to' */ + /* operations to indicate the start of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e., function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* <InOut> */ + /* user :: A typeless pointer that is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* A contour that contains a single point only is represented by a */ + /* `move to' operation followed by `line to' to the same point. In */ + /* most cases, it is best to filter this out before using the */ + /* outline for stroking purposes (otherwise it would result in a */ + /* visible dot when round caps are used). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_New */ + /* */ + /* <Description> */ + /* Create a new outline of a given size. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object from where the */ + /* outline is allocated. Note however that the new */ + /* outline will *not* necessarily be *freed*, when */ + /* destroying the library, by @FT_Done_FreeType. */ + /* */ + /* numPoints :: The maximum number of points within the outline. */ + /* Must be smaller than or equal to 0xFFFF (65535). */ + /* */ + /* numContours :: The maximum number of contours within the outline. */ + /* This value must be in the range 0 to `numPoints'. */ + /* */ + /* <Output> */ + /* anoutline :: A handle to the new outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' parameter is simply */ + /* to use the library's memory allocator. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Done */ + /* */ + /* <Description> */ + /* Destroy an outline created with @FT_Outline_New. */ + /* */ + /* <Input> */ + /* library :: A handle of the library object used to allocate the */ + /* outline. */ + /* */ + /* outline :: A pointer to the outline object to be discarded. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If the outline's `owner' field is not set, only the outline */ + /* descriptor will be released. */ + /* */ + /* The reason why this function takes an `library' parameter is */ + /* simply to use ft_mem_free(). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Check */ + /* */ + /* <Description> */ + /* Check the contents of an outline descriptor. */ + /* */ + /* <Input> */ + /* outline :: A handle to a source outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Check( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* that contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component, which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + /* <Note> */ + /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Translate */ + /* */ + /* <Description> */ + /* Apply a simple translation to the points of an outline. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* xOffset :: The horizontal offset. */ + /* */ + /* yOffset :: The vertical offset. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Translate( const FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Copy */ + /* */ + /* <Description> */ + /* Copy an outline into another one. Both objects must have the */ + /* same sizes (number of points & number of contours) when this */ + /* function is called. */ + /* */ + /* <Input> */ + /* source :: A handle to the source outline. */ + /* */ + /* <Output> */ + /* target :: A handle to the target outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Copy( const FT_Outline* source, + FT_Outline *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Transform */ + /* */ + /* <Description> */ + /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ + /* for applying rotations, slanting, flipping, etc. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation matrix. */ + /* */ + /* <Note> */ + /* You can use @FT_Outline_Translate if you need to translate the */ + /* outline's points. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Transform( const FT_Outline* outline, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Embolden */ + /* */ + /* <Description> */ + /* Embolden an outline. The new outline will be at most 4~times */ + /* `strength' pixels wider and higher. You may think of the left and */ + /* bottom borders as unchanged. */ + /* */ + /* Negative `strength' values to reduce the outline thickness are */ + /* possible also. */ + /* */ + /* <InOut> */ + /* outline :: A handle to the target outline. */ + /* */ + /* <Input> */ + /* strength :: How strong the glyph is emboldened. Expressed in */ + /* 26.6 pixel format. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The used algorithm to increase or decrease the thickness of the */ + /* glyph doesn't change the number of points; this means that certain */ + /* situations like acute angles or intersections are sometimes */ + /* handled incorrectly. */ + /* */ + /* If you need `better' metrics values you should call */ + /* @FT_Outline_Get_CBox or @FT_Outline_Get_BBox. */ + /* */ + /* Example call: */ + /* */ + /* { */ + /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ + /* if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE ) */ + /* FT_Outline_Embolden( &face->slot->outline, strength ); */ + /* } */ + /* */ + /* To get meaningful results, font scaling values must be set with */ + /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Embolden( FT_Outline* outline, + FT_Pos strength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_EmboldenXY */ + /* */ + /* <Description> */ + /* Embolden an outline. The new outline will be `xstrength' pixels */ + /* wider and `ystrength' pixels higher. Otherwise, it is similar to */ + /* @FT_Outline_Embolden, which uses the same strength in both */ + /* directions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_EmboldenXY( FT_Outline* outline, + FT_Pos xstrength, + FT_Pos ystrength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Reverse */ + /* */ + /* <Description> */ + /* Reverse the drawing direction of an outline. This is used to */ + /* ensure consistent fill conventions for mirrored glyphs. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Note> */ + /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ + /* the outline's `flags' field. */ + /* */ + /* It shouldn't be used by a normal client application, unless it */ + /* knows what it is doing. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Reverse( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_Bitmap */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap. The outline's image is simply */ + /* OR-ed to the target bitmap. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the target bitmap descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does NOT CREATE the bitmap, it only renders an */ + /* outline image within the one you pass to it! Consequently, the */ + /* various fields in `abitmap' should be set accordingly. */ + /* */ + /* It will use the raster corresponding to the default glyph format. */ + /* */ + /* The value of the `num_grays' field in `abitmap' is ignored. If */ + /* you select the gray-level rasterizer, and you want less than 256 */ + /* gray levels, you have to use @FT_Outline_Render directly. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + const FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Render */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap using the current scan-convert. */ + /* This function uses an @FT_Raster_Params structure as an argument, */ + /* allowing advanced features like direct composition, translucency, */ + /* etc. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* describe the rendering operation. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You should know what you are doing and how @FT_Raster_Params works */ + /* to use this function. */ + /* */ + /* The field `params.source' will be set to `outline' before the scan */ + /* converter is called, which means that the value you give to it is */ + /* actually ignored. */ + /* */ + /* The gray-level rasterizer always uses 256 gray levels. If you */ + /* want less gray levels, you have to provide your own span callback. */ + /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ + /* @FT_Raster_Params structure for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ); + + + /************************************************************************** + * + * @enum: + * FT_Orientation + * + * @description: + * A list of values used to describe an outline's contour orientation. + * + * The TrueType and PostScript specifications use different conventions + * to determine whether outline contours should be filled or unfilled. + * + * @values: + * FT_ORIENTATION_TRUETYPE :: + * According to the TrueType specification, clockwise contours must + * be filled, and counter-clockwise ones must be unfilled. + * + * FT_ORIENTATION_POSTSCRIPT :: + * According to the PostScript specification, counter-clockwise contours + * must be filled, and clockwise ones must be unfilled. + * + * FT_ORIENTATION_FILL_RIGHT :: + * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to + * remember that in TrueType, everything that is to the right of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_FILL_LEFT :: + * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to + * remember that in PostScript, everything that is to the left of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_NONE :: + * The orientation cannot be determined. That is, different parts of + * the glyph have different orientation. + * + */ + typedef enum FT_Orientation_ + { + FT_ORIENTATION_TRUETYPE = 0, + FT_ORIENTATION_POSTSCRIPT = 1, + FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, + FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT, + FT_ORIENTATION_NONE + + } FT_Orientation; + + + /************************************************************************** + * + * @function: + * FT_Outline_Get_Orientation + * + * @description: + * This function analyzes a glyph outline and tries to compute its + * fill orientation (see @FT_Orientation). This is done by integrating + * the total area covered by the outline. The positive integral + * corresponds to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT + * is returned. The negative integral corresponds to the counter-clockwise + * orientation and @FT_ORIENTATION_TRUETYPE is returned. + * + * Note that this will return @FT_ORIENTATION_TRUETYPE for empty + * outlines. + * + * @input: + * outline :: + * A handle to the source outline. + * + * @return: + * The orientation. + * + */ + FT_EXPORT( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTOUTLN_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftpfr.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftpfr.h new file mode 100644 index 00000000..7d503539 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftpfr.h @@ -0,0 +1,172 @@ +/***************************************************************************/ +/* */ +/* ftpfr.h */ +/* */ +/* FreeType API for accessing PFR-specific data (specification only). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2008, 2009 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTPFR_H__ +#define __FTPFR_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* pfr_fonts */ + /* */ + /* <Title> */ + /* PFR Fonts */ + /* */ + /* <Abstract> */ + /* PFR/TrueDoc specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of PFR-specific functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Metrics + * + * @description: + * Return the outline and metrics resolutions of a given PFR face. + * + * @input: + * face :: Handle to the input face. It can be a non-PFR face. + * + * @output: + * aoutline_resolution :: + * Outline resolution. This is equivalent to `face->units_per_EM' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_resolution :: + * Metrics resolution. This is equivalent to `outline_resolution' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_x_scale :: + * A 16.16 fixed-point number used to scale distance expressed + * in metrics units to device sub-pixels. This is equivalent to + * `face->size->x_scale', but for metrics only. Optional (parameter + * can be NULL). + * + * ametrics_y_scale :: + * Same as `ametrics_x_scale' but for the vertical direction. + * optional (parameter can be NULL). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If the input face is not a PFR, this function will return an error. + * However, in all cases, it will return valid values. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Kerning + * + * @description: + * Return the kerning pair corresponding to two glyphs in a PFR face. + * The distance is expressed in metrics units, unlike the result of + * @FT_Get_Kerning. + * + * @input: + * face :: A handle to the input face. + * + * left :: Index of the left glyph. + * + * right :: Index of the right glyph. + * + * @output: + * avector :: A kerning vector. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function always return distances in original PFR metrics + * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED + * mode, which always returns distances converted to outline units. + * + * You can use the value of the `x_scale' and `y_scale' parameters + * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Advance + * + * @description: + * Return a given glyph advance, expressed in original metrics units, + * from a PFR font. + * + * @input: + * face :: A handle to the input face. + * + * gindex :: The glyph index. + * + * @output: + * aadvance :: The glyph advance in metrics units. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics + * to convert the advance to device sub-pixels (i.e., 1/64th of pixels). + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTPFR_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftrender.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftrender.h new file mode 100644 index 00000000..e8d36363 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftrender.h @@ -0,0 +1,237 @@ +/***************************************************************************/ +/* */ +/* ftrender.h */ +/* */ +/* FreeType renderer modules public interface (specification). */ +/* */ +/* Copyright 1996-2001, 2005, 2006, 2010 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTRENDER_H__ +#define __FTRENDER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + + /* create a new glyph object */ + typedef FT_Error + (*FT_Glyph_InitFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + + /* destroys a given glyph object */ + typedef void + (*FT_Glyph_DoneFunc)( FT_Glyph glyph ); + + typedef void + (*FT_Glyph_TransformFunc)( FT_Glyph glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + typedef void + (*FT_Glyph_GetBBoxFunc)( FT_Glyph glyph, + FT_BBox* abbox ); + + typedef FT_Error + (*FT_Glyph_CopyFunc)( FT_Glyph source, + FT_Glyph target ); + + typedef FT_Error + (*FT_Glyph_PrepareFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + +/* deprecated */ +#define FT_Glyph_Init_Func FT_Glyph_InitFunc +#define FT_Glyph_Done_Func FT_Glyph_DoneFunc +#define FT_Glyph_Transform_Func FT_Glyph_TransformFunc +#define FT_Glyph_BBox_Func FT_Glyph_GetBBoxFunc +#define FT_Glyph_Copy_Func FT_Glyph_CopyFunc +#define FT_Glyph_Prepare_Func FT_Glyph_PrepareFunc + + + struct FT_Glyph_Class_ + { + FT_Long glyph_size; + FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; + FT_Glyph_DoneFunc glyph_done; + FT_Glyph_CopyFunc glyph_copy; + FT_Glyph_TransformFunc glyph_transform; + FT_Glyph_GetBBoxFunc glyph_bbox; + FT_Glyph_PrepareFunc glyph_prepare; + }; + + + typedef FT_Error + (*FT_Renderer_RenderFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_UInt mode, + const FT_Vector* origin ); + + typedef FT_Error + (*FT_Renderer_TransformFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + + typedef void + (*FT_Renderer_GetCBoxFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_BBox* cbox ); + + + typedef FT_Error + (*FT_Renderer_SetModeFunc)( FT_Renderer renderer, + FT_ULong mode_tag, + FT_Pointer mode_ptr ); + +/* deprecated identifiers */ +#define FTRenderer_render FT_Renderer_RenderFunc +#define FTRenderer_transform FT_Renderer_TransformFunc +#define FTRenderer_getCBox FT_Renderer_GetCBoxFunc +#define FTRenderer_setMode FT_Renderer_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Renderer_Class */ + /* */ + /* <Description> */ + /* The renderer module class descriptor. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Module_Class fields. */ + /* */ + /* glyph_format :: The glyph image format this renderer handles. */ + /* */ + /* render_glyph :: A method used to render the image that is in a */ + /* given glyph slot into a bitmap. */ + /* */ + /* transform_glyph :: A method used to transform the image that is in */ + /* a given glyph slot. */ + /* */ + /* get_glyph_cbox :: A method used to access the glyph's cbox. */ + /* */ + /* set_mode :: A method used to pass additional parameters. */ + /* */ + /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to its raster's class. */ + /* */ + typedef struct FT_Renderer_Class_ + { + FT_Module_Class root; + + FT_Glyph_Format glyph_format; + + FT_Renderer_RenderFunc render_glyph; + FT_Renderer_TransformFunc transform_glyph; + FT_Renderer_GetCBoxFunc get_glyph_cbox; + FT_Renderer_SetModeFunc set_mode; + + FT_Raster_Funcs* raster_class; + + } FT_Renderer_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Renderer */ + /* */ + /* <Description> */ + /* Retrieve the current renderer for a given glyph format. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* format :: The glyph format. */ + /* */ + /* <Return> */ + /* A renderer handle. 0~if none found. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + /* To add a new renderer, simply use @FT_Add_Module. To retrieve a */ + /* renderer by its name, use @FT_Get_Module. */ + /* */ + FT_EXPORT( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Renderer */ + /* */ + /* <Description> */ + /* Set the current renderer to use, and set additional mode. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* renderer :: A handle to the renderer object. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* parameters :: Additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case of success, the renderer will be used to convert glyph */ + /* images in the renderer's known format into bitmaps. */ + /* */ + /* This doesn't change the current renderer for other formats. */ + /* */ + /* Currently, only the B/W renderer, if compiled with */ + /* FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels */ + /* anti-aliasing mode; this option must be set directly in */ + /* `ftraster.c' and is undefined by default) accepts a single tag */ + /* `pal5' to set its gray palette as a character string with */ + /* 5~elements. Consequently, the third and fourth argument are zero */ + /* normally. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTRENDER_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsizes.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsizes.h new file mode 100644 index 00000000..41670457 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsizes.h @@ -0,0 +1,159 @@ +/***************************************************************************/ +/* */ +/* ftsizes.h */ +/* */ +/* FreeType size objects management (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2006, 2009, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Typical application would normally not need to use these functions. */ + /* However, they have been placed in a public API for the rare cases */ + /* where they are needed. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSIZES_H__ +#define __FTSIZES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sizes_management */ + /* */ + /* <Title> */ + /* Size Management */ + /* */ + /* <Abstract> */ + /* Managing multiple sizes per face. */ + /* */ + /* <Description> */ + /* When creating a new face object (e.g., with @FT_New_Face), an */ + /* @FT_Size object is automatically created and used to store all */ + /* pixel-size dependent information, available in the `face->size' */ + /* field. */ + /* */ + /* It is however possible to create more sizes for a given face, */ + /* mostly in order to manage several character pixel sizes of the */ + /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ + /* */ + /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ + /* modify the contents of the current `active' size; you thus need */ + /* to use @FT_Activate_Size to change it. */ + /* */ + /* 99% of applications won't need the functions provided here, */ + /* especially if they use the caching sub-system, so be cautious */ + /* when using these. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Size */ + /* */ + /* <Description> */ + /* Create a new size object from a given face object. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* asize :: A handle to a new size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You need to call @FT_Activate_Size in order to select the new size */ + /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ + /* @FT_Load_Glyph, @FT_Load_Char, etc. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size* size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Size */ + /* */ + /* <Description> */ + /* Discard a given size object. Note that @FT_Done_Face */ + /* automatically discards all size objects allocated with */ + /* @FT_New_Size. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Size( FT_Size size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Activate_Size */ + /* */ + /* <Description> */ + /* Even though it is possible to create several size objects for a */ + /* given face (see @FT_New_Size for details), functions like */ + /* @FT_Load_Glyph or @FT_Load_Char only use the one that has been */ + /* activated last to determine the `current character pixel size'. */ + /* */ + /* This function can be used to `activate' a previously created size */ + /* object. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If `face' is the size's parent face object, this function changes */ + /* the value of `face->size' to the input size handle. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Activate_Size( FT_Size size ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTSIZES_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsnames.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsnames.h new file mode 100644 index 00000000..88af4403 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsnames.h @@ -0,0 +1,200 @@ +/***************************************************************************/ +/* */ +/* ftsnames.h */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (specification). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2003, 2006, 2009, 2010, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_SFNT_NAMES_H__ +#define __FT_SFNT_NAMES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sfnt_names */ + /* */ + /* <Title> */ + /* SFNT Names */ + /* */ + /* <Abstract> */ + /* Access the names embedded in TrueType and OpenType files. */ + /* */ + /* <Description> */ + /* The TrueType and OpenType specifications allow the inclusion of */ + /* a special `names table' in font files. This table contains */ + /* textual (and internationalized) information regarding the font, */ + /* like family name, copyright, version, etc. */ + /* */ + /* The definitions below are used to access them if available. */ + /* */ + /* Note that this has nothing to do with glyph names! */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SfntName */ + /* */ + /* <Description> */ + /* A structure used to model an SFNT `name' table entry. */ + /* */ + /* <Fields> */ + /* platform_id :: The platform ID for `string'. */ + /* */ + /* encoding_id :: The encoding ID for `string'. */ + /* */ + /* language_id :: The language ID for `string'. */ + /* */ + /* name_id :: An identifier for `string'. */ + /* */ + /* string :: The `name' string. Note that its format differs */ + /* depending on the (platform,encoding) pair. It can */ + /* be a Pascal String, a UTF-16 one, etc. */ + /* */ + /* Generally speaking, the string is not */ + /* zero-terminated. Please refer to the TrueType */ + /* specification for details. */ + /* */ + /* string_len :: The length of `string' in bytes. */ + /* */ + /* <Note> */ + /* Possible values for `platform_id', `encoding_id', `language_id', */ + /* and `name_id' are given in the file `ttnameid.h'. For details */ + /* please refer to the TrueType or OpenType specification. */ + /* */ + /* See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ + /* @TT_ISO_ID_XXX, and @TT_MS_ID_XXX. */ + /* */ + typedef struct FT_SfntName_ + { + FT_UShort platform_id; + FT_UShort encoding_id; + FT_UShort language_id; + FT_UShort name_id; + + FT_Byte* string; /* this string is *not* null-terminated! */ + FT_UInt string_len; /* in bytes */ + + } FT_SfntName; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name_Count */ + /* */ + /* <Description> */ + /* Retrieve the number of name strings in the SFNT `name' table. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Return> */ + /* The number of strings in the `name' table. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name */ + /* */ + /* <Description> */ + /* Retrieve a string of the SFNT `name' table for a given index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* idx :: The index of the `name' string. */ + /* */ + /* <Output> */ + /* aname :: The indexed @FT_SfntName structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `string' array returned in the `aname' structure is not */ + /* null-terminated. The application should deallocate it if it is no */ + /* longer in use. */ + /* */ + /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ + /* `name' table entries, then do a loop until you get the right */ + /* platform, encoding, and name ID. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ); + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred family subfamily names in `name' + * table since OpenType version 1.4. For backwards compatibility with + * legacy systems that have a 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY + * + * @description: + * A constant used as the tag of @FT_Parameter structures to make + * FT_Open_Face() ignore preferred subfamily names in `name' table since + * OpenType version 1.4. For backwards compatibility with legacy + * systems that have a 4-face-per-family restriction. + * + */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) + + /* */ + + +FT_END_HEADER + +#endif /* __FT_SFNT_NAMES_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftstroke.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftstroke.h new file mode 100644 index 00000000..bd311709 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftstroke.h @@ -0,0 +1,785 @@ +/***************************************************************************/ +/* */ +/* ftstroke.h */ +/* */ +/* FreeType path stroker (specification). */ +/* */ +/* Copyright 2002-2006, 2008, 2009, 2011-2012, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_STROKE_H__ +#define __FT_STROKE_H__ + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************ + * + * @section: + * glyph_stroker + * + * @title: + * Glyph Stroker + * + * @abstract: + * Generating bordered and stroked glyphs. + * + * @description: + * This component generates stroked outlines of a given vectorial + * glyph. It also allows you to retrieve the `outside' and/or the + * `inside' borders of the stroke. + * + * This can be useful to generate `bordered' glyph, i.e., glyphs + * displayed with a coloured (and anti-aliased) border around their + * shape. + * + * @order: + * FT_Stroker + * + * FT_Stroker_LineJoin + * FT_Stroker_LineCap + * FT_StrokerBorder + * + * FT_Outline_GetInsideBorder + * FT_Outline_GetOutsideBorder + * + * FT_Glyph_Stroke + * FT_Glyph_StrokeBorder + * + * FT_Stroker_New + * FT_Stroker_Set + * FT_Stroker_Rewind + * FT_Stroker_ParseOutline + * FT_Stroker_Done + * + * FT_Stroker_BeginSubPath + * FT_Stroker_EndSubPath + * + * FT_Stroker_LineTo + * FT_Stroker_ConicTo + * FT_Stroker_CubicTo + * + * FT_Stroker_GetBorderCounts + * FT_Stroker_ExportBorder + * FT_Stroker_GetCounts + * FT_Stroker_Export + * + */ + + + /************************************************************** + * + * @type: + * FT_Stroker + * + * @description: + * Opaque handle to a path stroker object. + */ + typedef struct FT_StrokerRec_* FT_Stroker; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineJoin + * + * @description: + * These values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * FT_STROKER_LINEJOIN_ROUND :: + * Used to render rounded line joins. Circular arcs are used + * to join two lines smoothly. + * + * FT_STROKER_LINEJOIN_BEVEL :: + * Used to render beveled line joins. The outer corner of + * the joined lines is filled by enclosing the triangular + * region of the corner with a straight line between the + * outer corners of each stroke. + * + * FT_STROKER_LINEJOIN_MITER_FIXED :: + * Used to render mitered line joins, with fixed bevels if the + * miter limit is exceeded. The outer edges of the strokes + * for the two segments are extended until they meet at an + * angle. If the segments meet at too sharp an angle (such + * that the miter would extend from the intersection of the + * segments a distance greater than the product of the miter + * limit value and the border radius), then a bevel join (see + * above) is used instead. This prevents long spikes being + * created. FT_STROKER_LINEJOIN_MITER_FIXED generates a miter + * line join as used in PostScript and PDF. + * + * FT_STROKER_LINEJOIN_MITER_VARIABLE :: + * FT_STROKER_LINEJOIN_MITER :: + * Used to render mitered line joins, with variable bevels if + * the miter limit is exceeded. The intersection of the + * strokes is clipped at a line perpendicular to the bisector + * of the angle between the strokes, at the distance from the + * intersection of the segments equal to the product of the + * miter limit value and the border radius. This prevents + * long spikes being created. + * FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line + * join as used in XPS. FT_STROKER_LINEJOIN_MITER is an alias + * for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for + * backwards compatibility. + */ + typedef enum FT_Stroker_LineJoin_ + { + FT_STROKER_LINEJOIN_ROUND = 0, + FT_STROKER_LINEJOIN_BEVEL = 1, + FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, + FT_STROKER_LINEJOIN_MITER = FT_STROKER_LINEJOIN_MITER_VARIABLE, + FT_STROKER_LINEJOIN_MITER_FIXED = 3 + + } FT_Stroker_LineJoin; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineCap + * + * @description: + * These values determine how the end of opened sub-paths are + * rendered in a stroke. + * + * @values: + * FT_STROKER_LINECAP_BUTT :: + * The end of lines is rendered as a full stop on the last + * point itself. + * + * FT_STROKER_LINECAP_ROUND :: + * The end of lines is rendered as a half-circle around the + * last point. + * + * FT_STROKER_LINECAP_SQUARE :: + * The end of lines is rendered as a square around the + * last point. + */ + typedef enum FT_Stroker_LineCap_ + { + FT_STROKER_LINECAP_BUTT = 0, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINECAP_SQUARE + + } FT_Stroker_LineCap; + + + /************************************************************** + * + * @enum: + * FT_StrokerBorder + * + * @description: + * These values are used to select a given stroke border + * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. + * + * @values: + * FT_STROKER_BORDER_LEFT :: + * Select the left border, relative to the drawing direction. + * + * FT_STROKER_BORDER_RIGHT :: + * Select the right border, relative to the drawing direction. + * + * @note: + * Applications are generally interested in the `inside' and `outside' + * borders. However, there is no direct mapping between these and the + * `left' and `right' ones, since this really depends on the glyph's + * drawing orientation, which varies between font formats. + * + * You can however use @FT_Outline_GetInsideBorder and + * @FT_Outline_GetOutsideBorder to get these. + */ + typedef enum FT_StrokerBorder_ + { + FT_STROKER_BORDER_LEFT = 0, + FT_STROKER_BORDER_RIGHT + + } FT_StrokerBorder; + + + /************************************************************** + * + * @function: + * FT_Outline_GetInsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `inside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Outline_GetOutsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `outside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_New + * + * @description: + * Create a new stroker object. + * + * @input: + * library :: + * FreeType library handle. + * + * @output: + * astroker :: + * A new stroker object handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_New( FT_Library library, + FT_Stroker *astroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Set + * + * @description: + * Reset a stroker object's attributes. + * + * @input: + * stroker :: + * The target stroker handle. + * + * radius :: + * The border radius. + * + * line_cap :: + * The line cap style. + * + * line_join :: + * The line join style. + * + * miter_limit :: + * The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and + * FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles, + * expressed as 16.16 fixed-point value. + * + * @note: + * The radius is expressed in the same units as the outline + * coordinates. + * + * This function calls @FT_Stroker_Rewind automatically. + */ + FT_EXPORT( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Rewind + * + * @description: + * Reset a stroker object without changing its attributes. + * You should call this function before beginning a new + * series of calls to @FT_Stroker_BeginSubPath or + * @FT_Stroker_EndSubPath. + * + * @input: + * stroker :: + * The target stroker handle. + */ + FT_EXPORT( void ) + FT_Stroker_Rewind( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ParseOutline + * + * @description: + * A convenience function used to parse a whole outline with + * the stroker. The resulting outline(s) can be retrieved + * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The source outline. + * + * opened :: + * A boolean. If~1, the outline is treated as an open path instead + * of a closed one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `opened' is~0 (the default), the outline is treated as a closed + * path, and the stroker generates two distinct `border' outlines. + * + * If `opened' is~1, the outline is processed as an open path, and the + * stroker generates a single `stroke' outline. + * + * This function calls @FT_Stroker_Rewind automatically. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ); + + + /************************************************************** + * + * @function: + * FT_Stroker_BeginSubPath + * + * @description: + * Start a new sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the start vector. + * + * open :: + * A boolean. If~1, the sub-path is treated as an open one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function is useful when you need to stroke a path that is + * not stored as an @FT_Outline object. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ); + + + /************************************************************** + * + * @function: + * FT_Stroker_EndSubPath + * + * @description: + * Close the current sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function after @FT_Stroker_BeginSubPath. + * If the subpath was not `opened', this function `draws' a + * single line segment to the start position when needed. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_LineTo + * + * @description: + * `Draw' a single line segment in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ConicTo + * + * @description: + * `Draw' a single quadratic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control :: + * A pointer to a Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_CubicTo + * + * @description: + * `Draw' a single cubic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control1 :: + * A pointer to the first Bézier control point. + * + * control2 :: + * A pointer to second Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetBorderCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export one of the `border' or `stroke' + * outlines generated by the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_GetCounts instead if you want to + * retrieve the counts associated to both borders. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ExportBorder + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the corresponding border to your own @FT_Outline + * structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * outline :: + * The target outline handle. + * + * @note: + * Always call this function after @FT_Stroker_GetBorderCounts to + * get sure that there is enough room in your @FT_Outline object to + * receive all new data. + * + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_Export instead if you want to + * retrieve all borders at once. + */ + FT_EXPORT( void ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export all points/borders from the stroked + * outline/path. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Export + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export all borders to your own @FT_Outline structure. + * + * Note that this function appends the border points and + * contours to your outline, but does not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The target outline handle. + */ + FT_EXPORT( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Done + * + * @description: + * Destroy a stroker object. + * + * @input: + * stroker :: + * A stroker handle. Can be NULL. + */ + FT_EXPORT( void ) + FT_Stroker_Done( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Glyph_Stroke + * + * @description: + * Stroke a given outline glyph object with a given stroker. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + * + * Adding stroke may yield a significantly wider and taller glyph + * depending on how large of a radius was used to stroke the glyph. You + * may need to manually adjust horizontal and vertical advance amounts + * to account for this added size. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ); + + + /************************************************************** + * + * @function: + * FT_Glyph_StrokeBorder + * + * @description: + * Stroke a given outline glyph object with a given stroker, but + * only return either its inside or outside border. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * inside :: + * A Boolean. If~1, return the inside border, otherwise + * the outside border. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + * + * Adding stroke may yield a significantly wider and taller glyph + * depending on how large of a radius was used to stroke the glyph. You + * may need to manually adjust horizontal and vertical advance amounts + * to account for this added size. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ); + + /* */ + +FT_END_HEADER + +#endif /* __FT_STROKE_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsynth.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsynth.h new file mode 100644 index 00000000..d0ea7308 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsynth.h @@ -0,0 +1,82 @@ +/***************************************************************************/ +/* */ +/* ftsynth.h */ +/* */ +/* FreeType synthesizing code for emboldening and slanting */ +/* (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2006, 2008, 2012, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS ALPHA CODE! THIS API *********/ + /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ + /********* FREETYPE DEVELOPMENT TEAM *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* Main reason for not lifting the functions in this module to a */ + /* `standard' API is that the used parameters for emboldening and */ + /* slanting are not configurable. Consider the functions as a */ + /* code resource that should be copied into the application and */ + /* adapted to the particular needs. */ + + +#ifndef __FTSYNTH_H__ +#define __FTSYNTH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ + /* taste). This function is actually a convenience function, providing */ + /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ + /* */ + /* For emboldened outlines the height, width, and advance metrics are */ + /* increased by the strength of the emboldening. You can also call */ + /* @FT_Outline_Get_CBox to get precise values. */ + FT_EXPORT( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); + + /* Slant an outline glyph to the right by about 12 degrees. */ + FT_EXPORT( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTSYNTH_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsystem.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsystem.h new file mode 100644 index 00000000..7436ed26 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftsystem.h @@ -0,0 +1,355 @@ +/***************************************************************************/ +/* */ +/* ftsystem.h */ +/* */ +/* FreeType low-level system interface definition (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2005, 2010, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTSYSTEM_H__ +#define __FTSYSTEM_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* system_interface */ + /* */ + /* <Title> */ + /* System Interface */ + /* */ + /* <Abstract> */ + /* How FreeType manages memory and i/o. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to memory */ + /* management and i/o access. You need to understand this */ + /* information if you want to use a custom memory manager or you own */ + /* i/o streams. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* M E M O R Y M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Memory + * + * @description: + * A handle to a given memory manager object, defined with an + * @FT_MemoryRec structure. + * + */ + typedef struct FT_MemoryRec_* FT_Memory; + + + /************************************************************************* + * + * @functype: + * FT_Alloc_Func + * + * @description: + * A function used to allocate `size' bytes from `memory'. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * size :: + * The size in bytes to allocate. + * + * @return: + * Address of new memory block. 0~in case of failure. + * + */ + typedef void* + (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + + /************************************************************************* + * + * @functype: + * FT_Free_Func + * + * @description: + * A function used to release a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * block :: + * The address of the target memory block. + * + */ + typedef void + (*FT_Free_Func)( FT_Memory memory, + void* block ); + + + /************************************************************************* + * + * @functype: + * FT_Realloc_Func + * + * @description: + * A function used to re-allocate a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * cur_size :: + * The block's current size in bytes. + * + * new_size :: + * The block's requested new size. + * + * block :: + * The block's current address. + * + * @return: + * New block address. 0~in case of memory shortage. + * + * @note: + * In case of error, the old block must still be available. + * + */ + typedef void* + (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + + /************************************************************************* + * + * @struct: + * FT_MemoryRec + * + * @description: + * A structure used to describe a given memory manager to FreeType~2. + * + * @fields: + * user :: + * A generic typeless pointer for user data. + * + * alloc :: + * A pointer type to an allocation function. + * + * free :: + * A pointer type to an memory freeing function. + * + * realloc :: + * A pointer type to a reallocation function. + * + */ + struct FT_MemoryRec_ + { + void* user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + }; + + + /*************************************************************************/ + /* */ + /* I / O M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Stream + * + * @description: + * A handle to an input stream. + * + * @also: + * See @FT_StreamRec for the publicly accessible fields of a given + * stream object. + * + */ + typedef struct FT_StreamRec_* FT_Stream; + + + /************************************************************************* + * + * @struct: + * FT_StreamDesc + * + * @description: + * A union type used to store either a long or a pointer. This is used + * to store a file descriptor or a `FILE*' in an input stream. + * + */ + typedef union FT_StreamDesc_ + { + long value; + void* pointer; + + } FT_StreamDesc; + + + /************************************************************************* + * + * @functype: + * FT_Stream_IoFunc + * + * @description: + * A function used to seek and read data from a given input stream. + * + * @input: + * stream :: + * A handle to the source stream. + * + * offset :: + * The offset of read in stream (always from start). + * + * buffer :: + * The address of the read buffer. + * + * count :: + * The number of bytes to read from the stream. + * + * @return: + * The number of bytes effectively read by the stream. + * + * @note: + * This function might be called to perform a seek or skip operation + * with a `count' of~0. A non-zero return value then indicates an + * error. + * + */ + typedef unsigned long + (*FT_Stream_IoFunc)( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ); + + + /************************************************************************* + * + * @functype: + * FT_Stream_CloseFunc + * + * @description: + * A function used to close a given input stream. + * + * @input: + * stream :: + * A handle to the target stream. + * + */ + typedef void + (*FT_Stream_CloseFunc)( FT_Stream stream ); + + + /************************************************************************* + * + * @struct: + * FT_StreamRec + * + * @description: + * A structure used to describe an input stream. + * + * @input: + * base :: + * For memory-based streams, this is the address of the first stream + * byte in memory. This field should always be set to NULL for + * disk-based streams. + * + * size :: + * The stream size in bytes. + * + * In case of compressed streams where the size is unknown before + * actually doing the decompression, the value is set to 0x7FFFFFFF. + * (Note that this size value can occur for normal streams also; it is + * thus just a hint.) + * + * pos :: + * The current position within the stream. + * + * descriptor :: + * This field is a union that can hold an integer or a pointer. It is + * used by stream implementations to store file descriptors or `FILE*' + * pointers. + * + * pathname :: + * This field is completely ignored by FreeType. However, it is often + * useful during debugging to use it to store the stream's filename + * (where available). + * + * read :: + * The stream's input function. + * + * close :: + * The stream's close function. + * + * memory :: + * The memory manager to use to preload frames. This is set + * internally by FreeType and shouldn't be touched by stream + * implementations. + * + * cursor :: + * This field is set and used internally by FreeType when parsing + * frames. + * + * limit :: + * This field is set and used internally by FreeType when parsing + * frames. + * + */ + typedef struct FT_StreamRec_ + { + unsigned char* base; + unsigned long size; + unsigned long pos; + + FT_StreamDesc descriptor; + FT_StreamDesc pathname; + FT_Stream_IoFunc read; + FT_Stream_CloseFunc close; + + FT_Memory memory; + unsigned char* cursor; + unsigned char* limit; + + } FT_StreamRec; + + /* */ + + +FT_END_HEADER + +#endif /* __FTSYSTEM_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fttrigon.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fttrigon.h new file mode 100644 index 00000000..9c7b5432 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fttrigon.h @@ -0,0 +1,350 @@ +/***************************************************************************/ +/* */ +/* fttrigon.h */ +/* */ +/* FreeType trigonometric functions (specification). */ +/* */ +/* Copyright 2001, 2003, 2005, 2007, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTTRIGON_H__ +#define __FTTRIGON_H__ + +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Angle + * + * @description: + * This type is used to model angle values in FreeType. Note that the + * angle is a 16.16 fixed-point value expressed in degrees. + * + */ + typedef FT_Fixed FT_Angle; + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI + * + * @description: + * The angle pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI ( 180L << 16 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_2PI + * + * @description: + * The angle 2*pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI2 + * + * @description: + * The angle pi/2 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI4 + * + * @description: + * The angle pi/4 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) + + + /************************************************************************* + * + * @function: + * FT_Sin + * + * @description: + * Return the sinus of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The sinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Sin( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Cos + * + * @description: + * Return the cosinus of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The cosinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Cos( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Tan + * + * @description: + * Return the tangent of a given angle in fixed-point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The tangent value. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Tan( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Atan2 + * + * @description: + * Return the arc-tangent corresponding to a given vector (x,y) in + * the 2d plane. + * + * @input: + * x :: + * The horizontal vector coordinate. + * + * y :: + * The vertical vector coordinate. + * + * @return: + * The arc-tangent value (i.e. angle). + * + */ + FT_EXPORT( FT_Angle ) + FT_Atan2( FT_Fixed x, + FT_Fixed y ); + + + /************************************************************************* + * + * @function: + * FT_Angle_Diff + * + * @description: + * Return the difference between two angles. The result is always + * constrained to the ]-PI..PI] interval. + * + * @input: + * angle1 :: + * First angle. + * + * angle2 :: + * Second angle. + * + * @return: + * Constrained value of `value2-value1'. + * + */ + FT_EXPORT( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Unit + * + * @description: + * Return the unit vector corresponding to a given angle. After the + * call, the value of `vec.x' will be `sin(angle)', and the value of + * `vec.y' will be `cos(angle)'. + * + * This function is useful to retrieve both the sinus and cosinus of a + * given angle quickly. + * + * @output: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The input angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Rotate + * + * @description: + * Rotate a vector by a given angle. + * + * @inout: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The input angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Length + * + * @description: + * Return the length of a given vector. + * + * @input: + * vec :: + * The address of target vector. + * + * @return: + * The vector length, expressed in the same units that the original + * vector coordinates. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Polarize + * + * @description: + * Compute both the length and angle of a given vector. + * + * @input: + * vec :: + * The address of source vector. + * + * @output: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_From_Polar + * + * @description: + * Compute vector coordinates from a length and angle. + * + * @output: + * vec :: + * The address of source vector. + * + * @input: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTTRIGON_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftttdrv.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftttdrv.h new file mode 100644 index 00000000..35884139 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftttdrv.h @@ -0,0 +1,170 @@ +/***************************************************************************/ +/* */ +/* ftttdrv.h */ +/* */ +/* FreeType API for controlling the TrueType driver */ +/* (specification only). */ +/* */ +/* Copyright 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTTTDRV_H__ +#define __FTTTDRV_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * tt_driver + * + * @title: + * The TrueType driver + * + * @abstract: + * Controlling the TrueType driver module. + * + * @description: + * While FreeType's TrueType driver doesn't expose API functions by + * itself, it is possible to control its behaviour with @FT_Property_Set + * and @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * The TrueType driver's module name is `truetype'. + * + */ + + + /************************************************************************** + * + * @property: + * interpreter-version + * + * @description: + * Currently, two versions are available, representing the bytecode + * interpreter with and without subpixel hinting support, + * respectively. The default is subpixel support if + * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel + * support otherwise (since it isn't available then). + * + * If subpixel hinting is on, many TrueType bytecode instructions + * behave differently compared to B/W or grayscale rendering. The + * main idea is to render at a much increased horizontal resolution, + * then sampling down the created output to subpixel precision. + * However, many older fonts are not suited to this and must be + * specially taken care of by applying (hardcoded) font-specific + * tweaks. + * + * Details on subpixel hinting and some of the necessary tweaks can be + * found in Greg Hitchcock's whitepaper at + * `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * + * The following example code demonstrates how to activate subpixel + * hinting (omitting the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_38; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "truetype", + * "interpreter-version", + * &interpreter_version ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + */ + + + /************************************************************************** + * + * @enum: + * TT_INTERPRETER_VERSION_XXX + * + * @description: + * A list of constants used for the @interpreter-version property to + * select the hinting engine for Truetype fonts. + * + * The numeric value in the constant names represents the version + * number as returned by the `GETINFO' bytecode instruction. + * + * @values: + * TT_INTERPRETER_VERSION_35 :: + * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in + * Windows~98; only grayscale and B/W rasterizing is supported. + * + * TT_INTERPRETER_VERSION_38 :: + * Version~38 corresponds to MS rasterizer v.1.9; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as + * can be found, for example, in the Internet Explorer~9 running on + * Windows~7). + * + * @note: + * This property controls the behaviour of the bytecode interpreter + * and thus how outlines get hinted. It does *not* control how glyph + * get rasterized! In particular, it does not control subpixel color + * filtering. + * + * If FreeType has not been compiled with configuration option + * FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an + * `FT_Err_Unimplemented_Feature' error. + * + * Depending on the graphics framework, Microsoft uses different + * bytecode engines. As a consequence, the version numbers returned by + * a call to the `GETINFO[1]' bytecode instruction are more convoluted + * than desired. + * + * { + * framework Windows version result of GETINFO[1] + * ---------------------------------------------------- + * GDI before XP 35 + * GDI XP and later 37 + * GDI+ old before Vista 37 + * GDI+ old Vista, 7 38 + * GDI+ after 7 40 + * DWrite before 8 39 + * DWrite 8 and later 40 + * } + * + * Since FreeType doesn't provide all capabilities of DWrite ClearType, + * using version~38 seems justified. + * + */ +#define TT_INTERPRETER_VERSION_35 35 +#define TT_INTERPRETER_VERSION_38 38 + + /* */ + + +FT_END_HEADER + + +#endif /* __FTTTDRV_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fttypes.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fttypes.h new file mode 100644 index 00000000..2c01e873 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/fttypes.h @@ -0,0 +1,602 @@ +/***************************************************************************/ +/* */ +/* fttypes.h */ +/* */ +/* FreeType simple types definitions (specification only). */ +/* */ +/* Copyright 1996-2002, 2004, 2006-2009, 2012-2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTTYPES_H__ +#define __FTTYPES_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_SYSTEM_H +#include FT_IMAGE_H + +#include <stddef.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /* <Title> */ + /* Basic Data Types */ + /* */ + /* <Abstract> */ + /* The basic data types defined by the library. */ + /* */ + /* <Description> */ + /* This section contains the basic data types defined by FreeType~2, */ + /* ranging from simple scalar types to bitmap descriptors. More */ + /* font-specific structures are defined in a different section. */ + /* */ + /* <Order> */ + /* FT_Byte */ + /* FT_Bytes */ + /* FT_Char */ + /* FT_Int */ + /* FT_UInt */ + /* FT_Int16 */ + /* FT_UInt16 */ + /* FT_Int32 */ + /* FT_UInt32 */ + /* FT_Int64 */ + /* FT_UInt64 */ + /* FT_Short */ + /* FT_UShort */ + /* FT_Long */ + /* FT_ULong */ + /* FT_Bool */ + /* FT_Offset */ + /* FT_PtrDist */ + /* FT_String */ + /* FT_Tag */ + /* FT_Error */ + /* FT_Fixed */ + /* FT_Pointer */ + /* FT_Pos */ + /* FT_Vector */ + /* FT_BBox */ + /* FT_Matrix */ + /* FT_FWord */ + /* FT_UFWord */ + /* FT_F2Dot14 */ + /* FT_UnitVector */ + /* FT_F26Dot6 */ + /* FT_Data */ + /* */ + /* FT_MAKE_TAG */ + /* */ + /* FT_Generic */ + /* FT_Generic_Finalizer */ + /* */ + /* FT_Bitmap */ + /* FT_Pixel_Mode */ + /* FT_Palette_Mode */ + /* FT_Glyph_Format */ + /* FT_IMAGE_TAG */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bool */ + /* */ + /* <Description> */ + /* A typedef of unsigned char, used for simple booleans. As usual, */ + /* values 1 and~0 represent true and false, respectively. */ + /* */ + typedef unsigned char FT_Bool; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_FWord */ + /* */ + /* <Description> */ + /* A signed 16-bit integer used to store a distance in original font */ + /* units. */ + /* */ + typedef signed short FT_FWord; /* distance in FUnits */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UFWord */ + /* */ + /* <Description> */ + /* An unsigned 16-bit integer used to store a distance in original */ + /* font units. */ + /* */ + typedef unsigned short FT_UFWord; /* unsigned distance */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Char */ + /* */ + /* <Description> */ + /* A simple typedef for the _signed_ char type. */ + /* */ + typedef signed char FT_Char; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Byte */ + /* */ + /* <Description> */ + /* A simple typedef for the _unsigned_ char type. */ + /* */ + typedef unsigned char FT_Byte; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bytes */ + /* */ + /* <Description> */ + /* A typedef for constant memory areas. */ + /* */ + typedef const FT_Byte* FT_Bytes; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Tag */ + /* */ + /* <Description> */ + /* A typedef for 32-bit tags (as used in the SFNT format). */ + /* */ + typedef FT_UInt32 FT_Tag; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_String */ + /* */ + /* <Description> */ + /* A simple typedef for the char type, usually used for strings. */ + /* */ + typedef char FT_String; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Short */ + /* */ + /* <Description> */ + /* A typedef for signed short. */ + /* */ + typedef signed short FT_Short; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UShort */ + /* */ + /* <Description> */ + /* A typedef for unsigned short. */ + /* */ + typedef unsigned short FT_UShort; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int */ + /* */ + /* <Description> */ + /* A typedef for the int type. */ + /* */ + typedef signed int FT_Int; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt */ + /* */ + /* <Description> */ + /* A typedef for the unsigned int type. */ + /* */ + typedef unsigned int FT_UInt; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Long */ + /* */ + /* <Description> */ + /* A typedef for signed long. */ + /* */ + typedef signed long FT_Long; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ULong */ + /* */ + /* <Description> */ + /* A typedef for unsigned long. */ + /* */ + typedef unsigned long FT_ULong; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F2Dot14 */ + /* */ + /* <Description> */ + /* A signed 2.14 fixed-point type used for unit vectors. */ + /* */ + typedef signed short FT_F2Dot14; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F26Dot6 */ + /* */ + /* <Description> */ + /* A signed 26.6 fixed-point type used for vectorial pixel */ + /* coordinates. */ + /* */ + typedef signed long FT_F26Dot6; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Fixed */ + /* */ + /* <Description> */ + /* This type is used to store 16.16 fixed-point values, like scaling */ + /* values or matrix coefficients. */ + /* */ + typedef signed long FT_Fixed; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Error */ + /* */ + /* <Description> */ + /* The FreeType error code type. A value of~0 is always interpreted */ + /* as a successful operation. */ + /* */ + typedef int FT_Error; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pointer */ + /* */ + /* <Description> */ + /* A simple typedef for a typeless pointer. */ + /* */ + typedef void* FT_Pointer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Offset */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ + /* _unsigned_ integer type used to express a file size or position, */ + /* or a memory block size. */ + /* */ + typedef size_t FT_Offset; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_PtrDist */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ + /* largest _signed_ integer type used to express the distance */ + /* between two pointers. */ + /* */ + typedef ft_ptrdiff_t FT_PtrDist; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_UnitVector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector unit vector. Uses */ + /* FT_F2Dot14 types. */ + /* */ + /* <Fields> */ + /* x :: Horizontal coordinate. */ + /* */ + /* y :: Vertical coordinate. */ + /* */ + typedef struct FT_UnitVector_ + { + FT_F2Dot14 x; + FT_F2Dot14 y; + + } FT_UnitVector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Matrix */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2x2 matrix. Coefficients are */ + /* in 16.16 fixed-point format. The computation performed is: */ + /* */ + /* { */ + /* x' = x*xx + y*xy */ + /* y' = x*yx + y*yy */ + /* } */ + /* */ + /* <Fields> */ + /* xx :: Matrix coefficient. */ + /* */ + /* xy :: Matrix coefficient. */ + /* */ + /* yx :: Matrix coefficient. */ + /* */ + /* yy :: Matrix coefficient. */ + /* */ + typedef struct FT_Matrix_ + { + FT_Fixed xx, xy; + FT_Fixed yx, yy; + + } FT_Matrix; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Data */ + /* */ + /* <Description> */ + /* Read-only binary data represented as a pointer and a length. */ + /* */ + /* <Fields> */ + /* pointer :: The data. */ + /* */ + /* length :: The length of the data in bytes. */ + /* */ + typedef struct FT_Data_ + { + const FT_Byte* pointer; + FT_Int length; + + } FT_Data; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Generic_Finalizer */ + /* */ + /* <Description> */ + /* Describe a function used to destroy the `client' data of any */ + /* FreeType object. See the description of the @FT_Generic type for */ + /* details of usage. */ + /* */ + /* <Input> */ + /* The address of the FreeType object that is under finalization. */ + /* Its client data is accessed through its `generic' field. */ + /* */ + typedef void (*FT_Generic_Finalizer)(void* object); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Generic */ + /* */ + /* <Description> */ + /* Client applications often need to associate their own data to a */ + /* variety of FreeType core objects. For example, a text layout API */ + /* might want to associate a glyph cache to a given size object. */ + /* */ + /* Some FreeType object contains a `generic' field, of type */ + /* FT_Generic, which usage is left to client applications and font */ + /* servers. */ + /* */ + /* It can be used to store a pointer to client-specific data, as well */ + /* as the address of a `finalizer' function, which will be called by */ + /* FreeType when the object is destroyed (for example, the previous */ + /* client example would put the address of the glyph cache destructor */ + /* in the `finalizer' field). */ + /* */ + /* <Fields> */ + /* data :: A typeless pointer to any client-specified data. This */ + /* field is completely ignored by the FreeType library. */ + /* */ + /* finalizer :: A pointer to a `generic finalizer' function, which */ + /* will be called when the object is destroyed. If this */ + /* field is set to NULL, no code will be called. */ + /* */ + typedef struct FT_Generic_ + { + void* data; + FT_Generic_Finalizer finalizer; + + } FT_Generic; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_MAKE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags that are used to label */ + /* TrueType tables into an unsigned long, to be used within FreeType. */ + /* */ + /* <Note> */ + /* The produced values *must* be 32-bit integers. Don't redefine */ + /* this macro. */ + /* */ +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + (FT_Tag) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* L I S T M A N A G E M E N T */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ListNode */ + /* */ + /* <Description> */ + /* Many elements and objects in FreeType are listed through an */ + /* @FT_List record (see @FT_ListRec). As its name suggests, an */ + /* FT_ListNode is a handle to a single list element. */ + /* */ + typedef struct FT_ListNodeRec_* FT_ListNode; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_List */ + /* */ + /* <Description> */ + /* A handle to a list record (see @FT_ListRec). */ + /* */ + typedef struct FT_ListRec_* FT_List; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListNodeRec */ + /* */ + /* <Description> */ + /* A structure used to hold a single list element. */ + /* */ + /* <Fields> */ + /* prev :: The previous element in the list. NULL if first. */ + /* */ + /* next :: The next element in the list. NULL if last. */ + /* */ + /* data :: A typeless pointer to the listed object. */ + /* */ + typedef struct FT_ListNodeRec_ + { + FT_ListNode prev; + FT_ListNode next; + void* data; + + } FT_ListNodeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListRec */ + /* */ + /* <Description> */ + /* A structure used to hold a simple doubly-linked list. These are */ + /* used in many parts of FreeType. */ + /* */ + /* <Fields> */ + /* head :: The head (first element) of doubly-linked list. */ + /* */ + /* tail :: The tail (last element) of doubly-linked list. */ + /* */ + typedef struct FT_ListRec_ + { + FT_ListNode head; + FT_ListNode tail; + + } FT_ListRec; + + /* */ + + +#define FT_IS_EMPTY( list ) ( (list).head == 0 ) +#define FT_BOOL( x ) ( (FT_Bool)( x ) ) + + /* concatenate C tokens */ +#define FT_ERR_XCAT( x, y ) x ## y +#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) + + /* see `ftmoderr.h' for descriptions of the following macros */ + +#define FT_ERR( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) + +#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) +#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) + +#define FT_ERR_EQ( x, e ) \ + ( FT_ERROR_BASE( x ) == FT_ERROR_BASE( FT_ERR( e ) ) ) +#define FT_ERR_NEQ( x, e ) \ + ( FT_ERROR_BASE( x ) != FT_ERROR_BASE( FT_ERR( e ) ) ) + + +FT_END_HEADER + +#endif /* __FTTYPES_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftwinfnt.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftwinfnt.h new file mode 100644 index 00000000..50261581 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftwinfnt.h @@ -0,0 +1,275 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.h */ +/* */ +/* FreeType API for accessing Windows fnt-specific data. */ +/* */ +/* Copyright 2003, 2004, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTWINFNT_H__ +#define __FTWINFNT_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* winfnt_fonts */ + /* */ + /* <Title> */ + /* Window FNT Files */ + /* */ + /* <Abstract> */ + /* Windows FNT specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Windows FNT specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FT_WinFNT_ID_XXX + * + * @description: + * A list of valid values for the `charset' byte in + * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX + * encodings (except for cp1361) can be found at + * ftp://ftp.unicode.org/public in the MAPPINGS/VENDORS/MICSFT/WINDOWS + * subdirectory. cp1361 is roughly a superset of + * MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * + * @values: + * FT_WinFNT_ID_DEFAULT :: + * This is used for font enumeration and font creation as a + * `don't care' value. Valid font files don't contain this value. + * When querying for information about the character set of the font + * that is currently selected into a specified device context, this + * return value (of the related Windows API) simply denotes failure. + * + * FT_WinFNT_ID_SYMBOL :: + * There is no known mapping table available. + * + * FT_WinFNT_ID_MAC :: + * Mac Roman encoding. + * + * FT_WinFNT_ID_OEM :: + * From Michael Pöttgen <michael@poettgen.de>: + * + * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM + * is used for the charset of vector fonts, like `modern.fon', + * `roman.fon', and `script.fon' on Windows. + * + * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value + * specifies a character set that is operating-system dependent. + * + * The `IFIMETRICS' documentation from the `Windows Driver + * Development Kit' says: This font supports an OEM-specific + * character set. The OEM character set is system dependent. + * + * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the + * second default codepage that most international versions of + * Windows have. It is one of the OEM codepages from + * + * http://www.microsoft.com/globaldev/reference/cphome.mspx, + * + * and is used for the `DOS boxes', to support legacy applications. + * A German Windows version for example usually uses ANSI codepage + * 1252 and OEM codepage 850. + * + * FT_WinFNT_ID_CP874 :: + * A superset of Thai TIS 620 and ISO 8859-11. + * + * FT_WinFNT_ID_CP932 :: + * A superset of Japanese Shift-JIS (with minor deviations). + * + * FT_WinFNT_ID_CP936 :: + * A superset of simplified Chinese GB 2312-1980 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP949 :: + * A superset of Korean Hangul KS~C 5601-1987 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP950 :: + * A superset of traditional Chinese Big~5 ETen (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP1250 :: + * A superset of East European ISO 8859-2 (with slightly different + * ordering). + * + * FT_WinFNT_ID_CP1251 :: + * A superset of Russian ISO 8859-5 (with different ordering). + * + * FT_WinFNT_ID_CP1252 :: + * ANSI encoding. A superset of ISO 8859-1. + * + * FT_WinFNT_ID_CP1253 :: + * A superset of Greek ISO 8859-7 (with minor modifications). + * + * FT_WinFNT_ID_CP1254 :: + * A superset of Turkish ISO 8859-9. + * + * FT_WinFNT_ID_CP1255 :: + * A superset of Hebrew ISO 8859-8 (with some modifications). + * + * FT_WinFNT_ID_CP1256 :: + * A superset of Arabic ISO 8859-6 (with different ordering). + * + * FT_WinFNT_ID_CP1257 :: + * A superset of Baltic ISO 8859-13 (with some deviations). + * + * FT_WinFNT_ID_CP1258 :: + * For Vietnamese. This encoding doesn't cover all necessary + * characters. + * + * FT_WinFNT_ID_CP1361 :: + * Korean (Johab). + */ + +#define FT_WinFNT_ID_CP1252 0 +#define FT_WinFNT_ID_DEFAULT 1 +#define FT_WinFNT_ID_SYMBOL 2 +#define FT_WinFNT_ID_MAC 77 +#define FT_WinFNT_ID_CP932 128 +#define FT_WinFNT_ID_CP949 129 +#define FT_WinFNT_ID_CP1361 130 +#define FT_WinFNT_ID_CP936 134 +#define FT_WinFNT_ID_CP950 136 +#define FT_WinFNT_ID_CP1253 161 +#define FT_WinFNT_ID_CP1254 162 +#define FT_WinFNT_ID_CP1258 163 +#define FT_WinFNT_ID_CP1255 177 +#define FT_WinFNT_ID_CP1256 178 +#define FT_WinFNT_ID_CP1257 186 +#define FT_WinFNT_ID_CP1251 204 +#define FT_WinFNT_ID_CP874 222 +#define FT_WinFNT_ID_CP1250 238 +#define FT_WinFNT_ID_OEM 255 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_HeaderRec */ + /* */ + /* <Description> */ + /* Windows FNT Header info. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_ + { + FT_UShort version; + FT_ULong file_size; + FT_Byte copyright[60]; + FT_UShort file_type; + FT_UShort nominal_point_size; + FT_UShort vertical_resolution; + FT_UShort horizontal_resolution; + FT_UShort ascent; + FT_UShort internal_leading; + FT_UShort external_leading; + FT_Byte italic; + FT_Byte underline; + FT_Byte strike_out; + FT_UShort weight; + FT_Byte charset; + FT_UShort pixel_width; + FT_UShort pixel_height; + FT_Byte pitch_and_family; + FT_UShort avg_width; + FT_UShort max_width; + FT_Byte first_char; + FT_Byte last_char; + FT_Byte default_char; + FT_Byte break_char; + FT_UShort bytes_per_row; + FT_ULong device_offset; + FT_ULong face_name_offset; + FT_ULong bits_pointer; + FT_ULong bits_offset; + FT_Byte reserved; + FT_ULong flags; + FT_UShort A_space; + FT_UShort B_space; + FT_UShort C_space; + FT_UShort color_table_offset; + FT_ULong reserved1[4]; + + } FT_WinFNT_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_Header */ + /* */ + /* <Description> */ + /* A handle to an @FT_WinFNT_HeaderRec structure. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieve a Windows FNT font info header. + * + * @input: + * face :: A handle to the input face. + * + * @output: + * aheader :: The WinFNT header. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with Windows FNT faces, returning an error + * otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTWINFNT_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftxf86.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftxf86.h new file mode 100644 index 00000000..89d1993e --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ftxf86.h @@ -0,0 +1,84 @@ +/***************************************************************************/ +/* */ +/* ftxf86.h */ +/* */ +/* Support functions for X11. */ +/* */ +/* Copyright 2002-2004, 2006, 2007, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTXF86_H__ +#define __FTXF86_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* font_formats */ + /* */ + /* <Title> */ + /* Font Formats */ + /* */ + /* <Abstract> */ + /* Getting the font format. */ + /* */ + /* <Description> */ + /* The single function in this section can be used to get the font */ + /* format. Note that this information is not needed normally; */ + /* however, there are special cases (like in PDF devices) where it is */ + /* important to differentiate, in spite of FreeType's uniform API. */ + /* */ + /* This function is in the X11/xf86 namespace for historical reasons */ + /* and in no way depends on that windowing system. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_X11_Font_Format */ + /* */ + /* <Description> */ + /* Return a string describing the format of a given face, using values */ + /* that can be used as an X11 FONT_PROPERTY. Possible values are */ + /* `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */ + /* `PFR', and `Windows~FNT'. */ + /* */ + /* <Input> */ + /* face :: */ + /* Input face handle. */ + /* */ + /* <Return> */ + /* Font format string. NULL in case of error. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_X11_Font_Format( FT_Face face ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTXF86_H__ */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/t1tables.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/t1tables.h new file mode 100644 index 00000000..61aefdd5 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/t1tables.h @@ -0,0 +1,760 @@ +/***************************************************************************/ +/* */ +/* t1tables.h */ +/* */ +/* Basic Type 1/Type 2 tables definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2004, 2006, 2008, 2009, 2011, 2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1TABLES_H__ +#define __T1TABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* type1_tables */ + /* */ + /* <Title> */ + /* Type 1 Tables */ + /* */ + /* <Abstract> */ + /* Type~1 (PostScript) specific font tables. */ + /* */ + /* <Description> */ + /* This section contains the definition of Type 1-specific tables, */ + /* including structures related to other PostScript font formats. */ + /* */ + /* <Order> */ + /* PS_FontInfoRec */ + /* PS_FontInfo */ + /* PS_PrivateRec */ + /* PS_Private */ + /* */ + /* CID_FaceDictRec */ + /* CID_FaceDict */ + /* CID_FaceInfoRec */ + /* CID_FaceInfo */ + /* */ + /* FT_Has_PS_Glyph_Names */ + /* FT_Get_PS_Font_Info */ + /* FT_Get_PS_Font_Private */ + /* FT_Get_PS_Font_Value */ + /* */ + /* T1_Blend_Flags */ + /* T1_EncodingType */ + /* PS_Dict_Keys */ + /* */ + /*************************************************************************/ + + + /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ + /* structures in order to support Multiple Master fonts. */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfoRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* FontInfo dictionary. */ + /* */ + typedef struct PS_FontInfoRec_ + { + FT_String* version; + FT_String* notice; + FT_String* full_name; + FT_String* family_name; + FT_String* weight; + FT_Long italic_angle; + FT_Bool is_fixed_pitch; + FT_Short underline_position; + FT_UShort underline_thickness; + + } PS_FontInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfo */ + /* */ + /* <Description> */ + /* A handle to a @PS_FontInfoRec structure. */ + /* */ + typedef struct PS_FontInfoRec_* PS_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_FontInfo */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_FontInfoRec T1_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_PrivateRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 private dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* Private dictionary. */ + /* */ + typedef struct PS_PrivateRec_ + { + FT_Int unique_id; + FT_Int lenIV; + + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Short blue_values[14]; + FT_Short other_blues[10]; + + FT_Short family_blues [14]; + FT_Short family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_fuzz; + + FT_UShort standard_width[1]; + FT_UShort standard_height[1]; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Bool force_bold; + FT_Bool round_stem_up; + + FT_Short snap_widths [13]; /* including std width */ + FT_Short snap_heights[13]; /* including std height */ + + FT_Fixed expansion_factor; + + FT_Long language_group; + FT_Long password; + + FT_Short min_feature[2]; + + } PS_PrivateRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Private */ + /* */ + /* <Description> */ + /* A handle to a @PS_PrivateRec structure. */ + /* */ + typedef struct PS_PrivateRec_* PS_Private; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_Private */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_PrivateRec T1_Private; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_Blend_Flags */ + /* */ + /* <Description> */ + /* A set of flags used to indicate which fields are present in a */ + /* given blend dictionary (font info or private). Used to support */ + /* Multiple Masters fonts. */ + /* */ + /* <Values> */ + /* T1_BLEND_UNDERLINE_POSITION :: */ + /* T1_BLEND_UNDERLINE_THICKNESS :: */ + /* T1_BLEND_ITALIC_ANGLE :: */ + /* T1_BLEND_BLUE_VALUES :: */ + /* T1_BLEND_OTHER_BLUES :: */ + /* T1_BLEND_STANDARD_WIDTH :: */ + /* T1_BLEND_STANDARD_HEIGHT :: */ + /* T1_BLEND_STEM_SNAP_WIDTHS :: */ + /* T1_BLEND_STEM_SNAP_HEIGHTS :: */ + /* T1_BLEND_BLUE_SCALE :: */ + /* T1_BLEND_BLUE_SHIFT :: */ + /* T1_BLEND_FAMILY_BLUES :: */ + /* T1_BLEND_FAMILY_OTHER_BLUES :: */ + /* T1_BLEND_FORCE_BOLD :: */ + /* */ + typedef enum T1_Blend_Flags_ + { + /* required fields in a FontInfo blend dictionary */ + T1_BLEND_UNDERLINE_POSITION = 0, + T1_BLEND_UNDERLINE_THICKNESS, + T1_BLEND_ITALIC_ANGLE, + + /* required fields in a Private blend dictionary */ + T1_BLEND_BLUE_VALUES, + T1_BLEND_OTHER_BLUES, + T1_BLEND_STANDARD_WIDTH, + T1_BLEND_STANDARD_HEIGHT, + T1_BLEND_STEM_SNAP_WIDTHS, + T1_BLEND_STEM_SNAP_HEIGHTS, + T1_BLEND_BLUE_SCALE, + T1_BLEND_BLUE_SHIFT, + T1_BLEND_FAMILY_BLUES, + T1_BLEND_FAMILY_OTHER_BLUES, + T1_BLEND_FORCE_BOLD, + + T1_BLEND_MAX /* do not remove */ + + } T1_Blend_Flags; + + + /* these constants are deprecated; use the corresponding */ + /* `T1_Blend_Flags' values instead */ +#define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION +#define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS +#define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE +#define t1_blend_blue_values T1_BLEND_BLUE_VALUES +#define t1_blend_other_blues T1_BLEND_OTHER_BLUES +#define t1_blend_standard_widths T1_BLEND_STANDARD_WIDTH +#define t1_blend_standard_height T1_BLEND_STANDARD_HEIGHT +#define t1_blend_stem_snap_widths T1_BLEND_STEM_SNAP_WIDTHS +#define t1_blend_stem_snap_heights T1_BLEND_STEM_SNAP_HEIGHTS +#define t1_blend_blue_scale T1_BLEND_BLUE_SCALE +#define t1_blend_blue_shift T1_BLEND_BLUE_SHIFT +#define t1_blend_family_blues T1_BLEND_FAMILY_BLUES +#define t1_blend_family_other_blues T1_BLEND_FAMILY_OTHER_BLUES +#define t1_blend_force_bold T1_BLEND_FORCE_BOLD +#define t1_blend_max T1_BLEND_MAX + + /* */ + + + /* maximum number of Multiple Masters designs, as defined in the spec */ +#define T1_MAX_MM_DESIGNS 16 + + /* maximum number of Multiple Masters axes, as defined in the spec */ +#define T1_MAX_MM_AXIS 4 + + /* maximum number of elements in a design map */ +#define T1_MAX_MM_MAP_POINTS 20 + + + /* this structure is used to store the BlendDesignMap entry for an axis */ + typedef struct PS_DesignMap_ + { + FT_Byte num_points; + FT_Long* design_points; + FT_Fixed* blend_points; + + } PS_DesignMapRec, *PS_DesignMap; + + /* backwards-compatible definition */ + typedef PS_DesignMapRec T1_DesignMap; + + + typedef struct PS_BlendRec_ + { + FT_UInt num_designs; + FT_UInt num_axis; + + FT_String* axis_names[T1_MAX_MM_AXIS]; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; + PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; + + FT_Fixed* weight_vector; + FT_Fixed* default_weight_vector; + + PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; + PS_Private privates [T1_MAX_MM_DESIGNS + 1]; + + FT_ULong blend_bitflags; + + FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; + + /* since 2.3.0 */ + + /* undocumented, optional: the default design instance; */ + /* corresponds to default_weight_vector -- */ + /* num_default_design_vector == 0 means it is not present */ + /* in the font and associated metrics files */ + FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; + FT_UInt num_default_design_vector; + + } PS_BlendRec, *PS_Blend; + + + /* backwards-compatible definition */ + typedef PS_BlendRec T1_Blend; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDictRec */ + /* */ + /* <Description> */ + /* A structure used to represent data in a CID top-level dictionary. */ + /* */ + typedef struct CID_FaceDictRec_ + { + PS_PrivateRec private_dict; + + FT_UInt len_buildchar; + FT_Fixed forcebold_threshold; + FT_Pos stroke_width; + FT_Fixed expansion_factor; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_UInt num_subrs; + FT_ULong subrmap_offset; + FT_Int sd_bytes; + + } CID_FaceDictRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDict */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceDictRec structure. */ + /* */ + typedef struct CID_FaceDictRec_* CID_FaceDict; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FontDict */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceDictRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef CID_FaceDictRec CID_FontDict; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfoRec */ + /* */ + /* <Description> */ + /* A structure used to represent CID Face information. */ + /* */ + typedef struct CID_FaceInfoRec_ + { + FT_String* cid_font_name; + FT_Fixed cid_version; + FT_Int cid_font_type; + + FT_String* registry; + FT_String* ordering; + FT_Int supplement; + + PS_FontInfoRec font_info; + FT_BBox font_bbox; + FT_ULong uid_base; + + FT_Int num_xuid; + FT_ULong xuid[16]; + + FT_ULong cidmap_offset; + FT_Int fd_bytes; + FT_Int gd_bytes; + FT_ULong cid_count; + + FT_Int num_dicts; + CID_FaceDict font_dicts; + + FT_ULong data_offset; + + } CID_FaceInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfo */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceInfoRec structure. */ + /* */ + typedef struct CID_FaceInfoRec_* CID_FaceInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Info */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef CID_FaceInfoRec CID_Info; + + + /************************************************************************ + * + * @function: + * FT_Has_PS_Glyph_Names + * + * @description: + * Return true if a given face provides reliable PostScript glyph + * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, + * except that certain fonts (mostly TrueType) contain incorrect + * glyph name tables. + * + * When this function returns true, the caller is sure that the glyph + * names returned by @FT_Get_Glyph_Name are reliable. + * + * @input: + * face :: + * face handle + * + * @return: + * Boolean. True if glyph names are reliable. + * + */ + FT_EXPORT( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Info + * + * @description: + * Retrieve the @PS_FontInfoRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_info :: + * Output font info structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the font info structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function will + * return the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfo afont_info ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Private + * + * @description: + * Retrieve the @PS_PrivateRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_private :: + * Output private dictionary structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the @PS_PrivateRec structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Private( FT_Face face, + PS_Private afont_private ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_EncodingType */ + /* */ + /* <Description> */ + /* An enumeration describing the `Encoding' entry in a Type 1 */ + /* dictionary. */ + /* */ + /* <Values> */ + /* T1_ENCODING_TYPE_NONE :: */ + /* T1_ENCODING_TYPE_ARRAY :: */ + /* T1_ENCODING_TYPE_STANDARD :: */ + /* T1_ENCODING_TYPE_ISOLATIN1 :: */ + /* T1_ENCODING_TYPE_EXPERT :: */ + /* */ + typedef enum T1_EncodingType_ + { + T1_ENCODING_TYPE_NONE = 0, + T1_ENCODING_TYPE_ARRAY, + T1_ENCODING_TYPE_STANDARD, + T1_ENCODING_TYPE_ISOLATIN1, + T1_ENCODING_TYPE_EXPERT + + } T1_EncodingType; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* PS_Dict_Keys */ + /* */ + /* <Description> */ + /* An enumeration used in calls to @FT_Get_PS_Font_Value to identify */ + /* the Type~1 dictionary entry to retrieve. */ + /* */ + /* <Values> */ + /* PS_DICT_FONT_TYPE :: */ + /* PS_DICT_FONT_MATRIX :: */ + /* PS_DICT_FONT_BBOX :: */ + /* PS_DICT_PAINT_TYPE :: */ + /* PS_DICT_FONT_NAME :: */ + /* PS_DICT_UNIQUE_ID :: */ + /* PS_DICT_NUM_CHAR_STRINGS :: */ + /* PS_DICT_CHAR_STRING_KEY :: */ + /* PS_DICT_CHAR_STRING :: */ + /* PS_DICT_ENCODING_TYPE :: */ + /* PS_DICT_ENCODING_ENTRY :: */ + /* PS_DICT_NUM_SUBRS :: */ + /* PS_DICT_SUBR :: */ + /* PS_DICT_STD_HW :: */ + /* PS_DICT_STD_VW :: */ + /* PS_DICT_NUM_BLUE_VALUES :: */ + /* PS_DICT_BLUE_VALUE :: */ + /* PS_DICT_BLUE_FUZZ :: */ + /* PS_DICT_NUM_OTHER_BLUES :: */ + /* PS_DICT_OTHER_BLUE :: */ + /* PS_DICT_NUM_FAMILY_BLUES :: */ + /* PS_DICT_FAMILY_BLUE :: */ + /* PS_DICT_NUM_FAMILY_OTHER_BLUES :: */ + /* PS_DICT_FAMILY_OTHER_BLUE :: */ + /* PS_DICT_BLUE_SCALE :: */ + /* PS_DICT_BLUE_SHIFT :: */ + /* PS_DICT_NUM_STEM_SNAP_H :: */ + /* PS_DICT_STEM_SNAP_H :: */ + /* PS_DICT_NUM_STEM_SNAP_V :: */ + /* PS_DICT_STEM_SNAP_V :: */ + /* PS_DICT_FORCE_BOLD :: */ + /* PS_DICT_RND_STEM_UP :: */ + /* PS_DICT_MIN_FEATURE :: */ + /* PS_DICT_LEN_IV :: */ + /* PS_DICT_PASSWORD :: */ + /* PS_DICT_LANGUAGE_GROUP :: */ + /* PS_DICT_VERSION :: */ + /* PS_DICT_NOTICE :: */ + /* PS_DICT_FULL_NAME :: */ + /* PS_DICT_FAMILY_NAME :: */ + /* PS_DICT_WEIGHT :: */ + /* PS_DICT_IS_FIXED_PITCH :: */ + /* PS_DICT_UNDERLINE_POSITION :: */ + /* PS_DICT_UNDERLINE_THICKNESS :: */ + /* PS_DICT_FS_TYPE :: */ + /* PS_DICT_ITALIC_ANGLE :: */ + /* */ + typedef enum PS_Dict_Keys_ + { + /* conventionally in the font dictionary */ + PS_DICT_FONT_TYPE, /* FT_Byte */ + PS_DICT_FONT_MATRIX, /* FT_Fixed */ + PS_DICT_FONT_BBOX, /* FT_Fixed */ + PS_DICT_PAINT_TYPE, /* FT_Byte */ + PS_DICT_FONT_NAME, /* FT_String* */ + PS_DICT_UNIQUE_ID, /* FT_Int */ + PS_DICT_NUM_CHAR_STRINGS, /* FT_Int */ + PS_DICT_CHAR_STRING_KEY, /* FT_String* */ + PS_DICT_CHAR_STRING, /* FT_String* */ + PS_DICT_ENCODING_TYPE, /* T1_EncodingType */ + PS_DICT_ENCODING_ENTRY, /* FT_String* */ + + /* conventionally in the font Private dictionary */ + PS_DICT_NUM_SUBRS, /* FT_Int */ + PS_DICT_SUBR, /* FT_String* */ + PS_DICT_STD_HW, /* FT_UShort */ + PS_DICT_STD_VW, /* FT_UShort */ + PS_DICT_NUM_BLUE_VALUES, /* FT_Byte */ + PS_DICT_BLUE_VALUE, /* FT_Short */ + PS_DICT_BLUE_FUZZ, /* FT_Int */ + PS_DICT_NUM_OTHER_BLUES, /* FT_Byte */ + PS_DICT_OTHER_BLUE, /* FT_Short */ + PS_DICT_NUM_FAMILY_BLUES, /* FT_Byte */ + PS_DICT_FAMILY_BLUE, /* FT_Short */ + PS_DICT_NUM_FAMILY_OTHER_BLUES, /* FT_Byte */ + PS_DICT_FAMILY_OTHER_BLUE, /* FT_Short */ + PS_DICT_BLUE_SCALE, /* FT_Fixed */ + PS_DICT_BLUE_SHIFT, /* FT_Int */ + PS_DICT_NUM_STEM_SNAP_H, /* FT_Byte */ + PS_DICT_STEM_SNAP_H, /* FT_Short */ + PS_DICT_NUM_STEM_SNAP_V, /* FT_Byte */ + PS_DICT_STEM_SNAP_V, /* FT_Short */ + PS_DICT_FORCE_BOLD, /* FT_Bool */ + PS_DICT_RND_STEM_UP, /* FT_Bool */ + PS_DICT_MIN_FEATURE, /* FT_Short */ + PS_DICT_LEN_IV, /* FT_Int */ + PS_DICT_PASSWORD, /* FT_Long */ + PS_DICT_LANGUAGE_GROUP, /* FT_Long */ + + /* conventionally in the font FontInfo dictionary */ + PS_DICT_VERSION, /* FT_String* */ + PS_DICT_NOTICE, /* FT_String* */ + PS_DICT_FULL_NAME, /* FT_String* */ + PS_DICT_FAMILY_NAME, /* FT_String* */ + PS_DICT_WEIGHT, /* FT_String* */ + PS_DICT_IS_FIXED_PITCH, /* FT_Bool */ + PS_DICT_UNDERLINE_POSITION, /* FT_Short */ + PS_DICT_UNDERLINE_THICKNESS, /* FT_UShort */ + PS_DICT_FS_TYPE, /* FT_UShort */ + PS_DICT_ITALIC_ANGLE, /* FT_Long */ + + PS_DICT_MAX = PS_DICT_ITALIC_ANGLE + + } PS_Dict_Keys; + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Value + * + * @description: + * Retrieve the value for the supplied key from a PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * key :: + * An enumeration value representing the dictionary key to retrieve. + * + * idx :: + * For array values, this specifies the index to be returned. + * + * value :: + * A pointer to memory into which to write the value. + * + * valen_len :: + * The size, in bytes, of the memory supplied for the value. + * + * @output: + * value :: + * The value matching the above key, if it exists. + * + * @return: + * The amount of memory (in bytes) required to hold the requested + * value (if it exists, -1 otherwise). + * + * @note: + * The values returned are not pointers into the internal structures of + * the face, but are `fresh' copies, so that the memory containing them + * belongs to the calling application. This also enforces the + * `read-only' nature of these values, i.e., this function cannot be + * used to manipulate the face. + * + * `value' is a void pointer because the values returned can be of + * various types. + * + * If either `value' is NULL or `value_len' is too small, just the + * required memory size for the requested entry is returned. + * + * The `idx' parameter is used, not only to retrieve elements of, for + * example, the FontMatrix or FontBBox, but also to retrieve name keys + * from the CharStrings dictionary, and the charstrings themselves. It + * is ignored for atomic values. + * + * PS_DICT_BLUE_SCALE returns a value that is scaled up by 1000. To + * get the value as in the font stream, you need to divide by + * 65536000.0 (to remove the FT_Fixed scale, and the x1000 scale). + * + * IMPORTANT: Only key/value pairs read by the FreeType interpreter can + * be retrieved. So, for example, PostScript procedures such as NP, + * ND, and RD are not available. Arbitrary keys are, obviously, not be + * available either. + * + * If the font's format is not PostScript-based, this function returns + * the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Long ) + FT_Get_PS_Font_Value( FT_Face face, + PS_Dict_Keys key, + FT_UInt idx, + void *value, + FT_Long value_len ); + + /* */ + +FT_END_HEADER + +#endif /* __T1TABLES_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ttnameid.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ttnameid.h new file mode 100644 index 00000000..e65b5581 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ttnameid.h @@ -0,0 +1,1237 @@ +/***************************************************************************/ +/* */ +/* ttnameid.h */ +/* */ +/* TrueType name ID definitions (specification only). */ +/* */ +/* Copyright 1996-2004, 2006-2008, 2012-2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTNAMEID_H__ +#define __TTNAMEID_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + + + /*************************************************************************/ + /* */ + /* Possible values for the `platform' identifier code in the name */ + /* records of the TTF `name' table. */ + /* */ + /*************************************************************************/ + + + /*********************************************************************** + * + * @enum: + * TT_PLATFORM_XXX + * + * @description: + * A list of valid values for the `platform_id' identifier code in + * @FT_CharMapRec and @FT_SfntName structures. + * + * @values: + * TT_PLATFORM_APPLE_UNICODE :: + * Used by Apple to indicate a Unicode character map and/or name entry. + * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note + * that name entries in this format are coded as big-endian UCS-2 + * character codes _only_. + * + * TT_PLATFORM_MACINTOSH :: + * Used by Apple to indicate a MacOS-specific charmap and/or name entry. + * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that + * most TrueType fonts contain an Apple roman charmap to be usable on + * MacOS systems (even if they contain a Microsoft charmap as well). + * + * TT_PLATFORM_ISO :: + * This value was used to specify ISO/IEC 10646 charmaps. It is however + * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding + * `encoding_id' values. + * + * TT_PLATFORM_MICROSOFT :: + * Used by Microsoft to indicate Windows-specific charmaps. See + * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. + * Note that most fonts contain a Unicode charmap using + * (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). + * + * TT_PLATFORM_CUSTOM :: + * Used to indicate application-specific charmaps. + * + * TT_PLATFORM_ADOBE :: + * This value isn't part of any font format specification, but is used + * by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec + * structure. See @TT_ADOBE_ID_XXX. + */ + +#define TT_PLATFORM_APPLE_UNICODE 0 +#define TT_PLATFORM_MACINTOSH 1 +#define TT_PLATFORM_ISO 2 /* deprecated */ +#define TT_PLATFORM_MICROSOFT 3 +#define TT_PLATFORM_CUSTOM 4 +#define TT_PLATFORM_ADOBE 7 /* artificial */ + + + /*********************************************************************** + * + * @enum: + * TT_APPLE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. + * + * @values: + * TT_APPLE_ID_DEFAULT :: + * Unicode version 1.0. + * + * TT_APPLE_ID_UNICODE_1_1 :: + * Unicode 1.1; specifies Hangul characters starting at U+34xx. + * + * TT_APPLE_ID_ISO_10646 :: + * Deprecated (identical to preceding). + * + * TT_APPLE_ID_UNICODE_2_0 :: + * Unicode 2.0 and beyond (UTF-16 BMP only). + * + * TT_APPLE_ID_UNICODE_32 :: + * Unicode 3.1 and beyond, using UTF-32. + * + * TT_APPLE_ID_VARIANT_SELECTOR :: + * From Adobe, not Apple. Not a normal cmap. Specifies variations + * on a real cmap. + */ + +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ + + + /*********************************************************************** + * + * @enum: + * TT_MAC_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MACINTOSH charmaps and name entries. + * + * @values: + * TT_MAC_ID_ROMAN :: + * TT_MAC_ID_JAPANESE :: + * TT_MAC_ID_TRADITIONAL_CHINESE :: + * TT_MAC_ID_KOREAN :: + * TT_MAC_ID_ARABIC :: + * TT_MAC_ID_HEBREW :: + * TT_MAC_ID_GREEK :: + * TT_MAC_ID_RUSSIAN :: + * TT_MAC_ID_RSYMBOL :: + * TT_MAC_ID_DEVANAGARI :: + * TT_MAC_ID_GURMUKHI :: + * TT_MAC_ID_GUJARATI :: + * TT_MAC_ID_ORIYA :: + * TT_MAC_ID_BENGALI :: + * TT_MAC_ID_TAMIL :: + * TT_MAC_ID_TELUGU :: + * TT_MAC_ID_KANNADA :: + * TT_MAC_ID_MALAYALAM :: + * TT_MAC_ID_SINHALESE :: + * TT_MAC_ID_BURMESE :: + * TT_MAC_ID_KHMER :: + * TT_MAC_ID_THAI :: + * TT_MAC_ID_LAOTIAN :: + * TT_MAC_ID_GEORGIAN :: + * TT_MAC_ID_ARMENIAN :: + * TT_MAC_ID_MALDIVIAN :: + * TT_MAC_ID_SIMPLIFIED_CHINESE :: + * TT_MAC_ID_TIBETAN :: + * TT_MAC_ID_MONGOLIAN :: + * TT_MAC_ID_GEEZ :: + * TT_MAC_ID_SLAVIC :: + * TT_MAC_ID_VIETNAMESE :: + * TT_MAC_ID_SINDHI :: + * TT_MAC_ID_UNINTERP :: + */ + +#define TT_MAC_ID_ROMAN 0 +#define TT_MAC_ID_JAPANESE 1 +#define TT_MAC_ID_TRADITIONAL_CHINESE 2 +#define TT_MAC_ID_KOREAN 3 +#define TT_MAC_ID_ARABIC 4 +#define TT_MAC_ID_HEBREW 5 +#define TT_MAC_ID_GREEK 6 +#define TT_MAC_ID_RUSSIAN 7 +#define TT_MAC_ID_RSYMBOL 8 +#define TT_MAC_ID_DEVANAGARI 9 +#define TT_MAC_ID_GURMUKHI 10 +#define TT_MAC_ID_GUJARATI 11 +#define TT_MAC_ID_ORIYA 12 +#define TT_MAC_ID_BENGALI 13 +#define TT_MAC_ID_TAMIL 14 +#define TT_MAC_ID_TELUGU 15 +#define TT_MAC_ID_KANNADA 16 +#define TT_MAC_ID_MALAYALAM 17 +#define TT_MAC_ID_SINHALESE 18 +#define TT_MAC_ID_BURMESE 19 +#define TT_MAC_ID_KHMER 20 +#define TT_MAC_ID_THAI 21 +#define TT_MAC_ID_LAOTIAN 22 +#define TT_MAC_ID_GEORGIAN 23 +#define TT_MAC_ID_ARMENIAN 24 +#define TT_MAC_ID_MALDIVIAN 25 +#define TT_MAC_ID_SIMPLIFIED_CHINESE 25 +#define TT_MAC_ID_TIBETAN 26 +#define TT_MAC_ID_MONGOLIAN 27 +#define TT_MAC_ID_GEEZ 28 +#define TT_MAC_ID_SLAVIC 29 +#define TT_MAC_ID_VIETNAMESE 30 +#define TT_MAC_ID_SINDHI 31 +#define TT_MAC_ID_UNINTERP 32 + + + /*********************************************************************** + * + * @enum: + * TT_ISO_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ISO charmaps and name entries. + * + * Their use is now deprecated. + * + * @values: + * TT_ISO_ID_7BIT_ASCII :: + * ASCII. + * TT_ISO_ID_10646 :: + * ISO/10646. + * TT_ISO_ID_8859_1 :: + * Also known as Latin-1. + */ + +#define TT_ISO_ID_7BIT_ASCII 0 +#define TT_ISO_ID_10646 1 +#define TT_ISO_ID_8859_1 2 + + + /*********************************************************************** + * + * @enum: + * TT_MS_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MICROSOFT charmaps and name entries. + * + * @values: + * TT_MS_ID_SYMBOL_CS :: + * Corresponds to Microsoft symbol encoding. See + * @FT_ENCODING_MS_SYMBOL. + * + * TT_MS_ID_UNICODE_CS :: + * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See + * @FT_ENCODING_UNICODE. + * + * TT_MS_ID_SJIS :: + * Corresponds to SJIS Japanese encoding. See @FT_ENCODING_SJIS. + * + * TT_MS_ID_GB2312 :: + * Corresponds to Simplified Chinese as used in Mainland China. See + * @FT_ENCODING_GB2312. + * + * TT_MS_ID_BIG_5 :: + * Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. + * See @FT_ENCODING_BIG5. + * + * TT_MS_ID_WANSUNG :: + * Corresponds to Korean Wansung encoding. See @FT_ENCODING_WANSUNG. + * + * TT_MS_ID_JOHAB :: + * Corresponds to Johab encoding. See @FT_ENCODING_JOHAB. + * + * TT_MS_ID_UCS_4 :: + * Corresponds to UCS-4 or UTF-32 charmaps. This has been added to + * the OpenType specification version 1.4 (mid-2001.) + */ + +#define TT_MS_ID_SYMBOL_CS 0 +#define TT_MS_ID_UNICODE_CS 1 +#define TT_MS_ID_SJIS 2 +#define TT_MS_ID_GB2312 3 +#define TT_MS_ID_BIG_5 4 +#define TT_MS_ID_WANSUNG 5 +#define TT_MS_ID_JOHAB 6 +#define TT_MS_ID_UCS_4 10 + + + /*********************************************************************** + * + * @enum: + * TT_ADOBE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! + * + * @values: + * TT_ADOBE_ID_STANDARD :: + * Adobe standard encoding. + * TT_ADOBE_ID_EXPERT :: + * Adobe expert encoding. + * TT_ADOBE_ID_CUSTOM :: + * Adobe custom encoding. + * TT_ADOBE_ID_LATIN_1 :: + * Adobe Latin~1 encoding. + */ + +#define TT_ADOBE_ID_STANDARD 0 +#define TT_ADOBE_ID_EXPERT 1 +#define TT_ADOBE_ID_CUSTOM 2 +#define TT_ADOBE_ID_LATIN_1 3 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MACINTOSH. These values are also used as return values */ + /* for function @FT_Get_CMap_Language_ID. */ + /* */ + /* The canonical source for the Apple assigned Language ID's is at */ + /* */ + /* https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html */ + /* */ +#define TT_MAC_LANGID_ENGLISH 0 +#define TT_MAC_LANGID_FRENCH 1 +#define TT_MAC_LANGID_GERMAN 2 +#define TT_MAC_LANGID_ITALIAN 3 +#define TT_MAC_LANGID_DUTCH 4 +#define TT_MAC_LANGID_SWEDISH 5 +#define TT_MAC_LANGID_SPANISH 6 +#define TT_MAC_LANGID_DANISH 7 +#define TT_MAC_LANGID_PORTUGUESE 8 +#define TT_MAC_LANGID_NORWEGIAN 9 +#define TT_MAC_LANGID_HEBREW 10 +#define TT_MAC_LANGID_JAPANESE 11 +#define TT_MAC_LANGID_ARABIC 12 +#define TT_MAC_LANGID_FINNISH 13 +#define TT_MAC_LANGID_GREEK 14 +#define TT_MAC_LANGID_ICELANDIC 15 +#define TT_MAC_LANGID_MALTESE 16 +#define TT_MAC_LANGID_TURKISH 17 +#define TT_MAC_LANGID_CROATIAN 18 +#define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 +#define TT_MAC_LANGID_URDU 20 +#define TT_MAC_LANGID_HINDI 21 +#define TT_MAC_LANGID_THAI 22 +#define TT_MAC_LANGID_KOREAN 23 +#define TT_MAC_LANGID_LITHUANIAN 24 +#define TT_MAC_LANGID_POLISH 25 +#define TT_MAC_LANGID_HUNGARIAN 26 +#define TT_MAC_LANGID_ESTONIAN 27 +#define TT_MAC_LANGID_LETTISH 28 +#define TT_MAC_LANGID_SAAMISK 29 +#define TT_MAC_LANGID_FAEROESE 30 +#define TT_MAC_LANGID_FARSI 31 +#define TT_MAC_LANGID_RUSSIAN 32 +#define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 +#define TT_MAC_LANGID_FLEMISH 34 +#define TT_MAC_LANGID_IRISH 35 +#define TT_MAC_LANGID_ALBANIAN 36 +#define TT_MAC_LANGID_ROMANIAN 37 +#define TT_MAC_LANGID_CZECH 38 +#define TT_MAC_LANGID_SLOVAK 39 +#define TT_MAC_LANGID_SLOVENIAN 40 +#define TT_MAC_LANGID_YIDDISH 41 +#define TT_MAC_LANGID_SERBIAN 42 +#define TT_MAC_LANGID_MACEDONIAN 43 +#define TT_MAC_LANGID_BULGARIAN 44 +#define TT_MAC_LANGID_UKRAINIAN 45 +#define TT_MAC_LANGID_BYELORUSSIAN 46 +#define TT_MAC_LANGID_UZBEK 47 +#define TT_MAC_LANGID_KAZAKH 48 +#define TT_MAC_LANGID_AZERBAIJANI 49 +#define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT 49 +#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 +#define TT_MAC_LANGID_ARMENIAN 51 +#define TT_MAC_LANGID_GEORGIAN 52 +#define TT_MAC_LANGID_MOLDAVIAN 53 +#define TT_MAC_LANGID_KIRGHIZ 54 +#define TT_MAC_LANGID_TAJIKI 55 +#define TT_MAC_LANGID_TURKMEN 56 +#define TT_MAC_LANGID_MONGOLIAN 57 +#define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT 57 +#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 +#define TT_MAC_LANGID_PASHTO 59 +#define TT_MAC_LANGID_KURDISH 60 +#define TT_MAC_LANGID_KASHMIRI 61 +#define TT_MAC_LANGID_SINDHI 62 +#define TT_MAC_LANGID_TIBETAN 63 +#define TT_MAC_LANGID_NEPALI 64 +#define TT_MAC_LANGID_SANSKRIT 65 +#define TT_MAC_LANGID_MARATHI 66 +#define TT_MAC_LANGID_BENGALI 67 +#define TT_MAC_LANGID_ASSAMESE 68 +#define TT_MAC_LANGID_GUJARATI 69 +#define TT_MAC_LANGID_PUNJABI 70 +#define TT_MAC_LANGID_ORIYA 71 +#define TT_MAC_LANGID_MALAYALAM 72 +#define TT_MAC_LANGID_KANNADA 73 +#define TT_MAC_LANGID_TAMIL 74 +#define TT_MAC_LANGID_TELUGU 75 +#define TT_MAC_LANGID_SINHALESE 76 +#define TT_MAC_LANGID_BURMESE 77 +#define TT_MAC_LANGID_KHMER 78 +#define TT_MAC_LANGID_LAO 79 +#define TT_MAC_LANGID_VIETNAMESE 80 +#define TT_MAC_LANGID_INDONESIAN 81 +#define TT_MAC_LANGID_TAGALOG 82 +#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 +#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 +#define TT_MAC_LANGID_AMHARIC 85 +#define TT_MAC_LANGID_TIGRINYA 86 +#define TT_MAC_LANGID_GALLA 87 +#define TT_MAC_LANGID_SOMALI 88 +#define TT_MAC_LANGID_SWAHILI 89 +#define TT_MAC_LANGID_RUANDA 90 +#define TT_MAC_LANGID_RUNDI 91 +#define TT_MAC_LANGID_CHEWA 92 +#define TT_MAC_LANGID_MALAGASY 93 +#define TT_MAC_LANGID_ESPERANTO 94 +#define TT_MAC_LANGID_WELSH 128 +#define TT_MAC_LANGID_BASQUE 129 +#define TT_MAC_LANGID_CATALAN 130 +#define TT_MAC_LANGID_LATIN 131 +#define TT_MAC_LANGID_QUECHUA 132 +#define TT_MAC_LANGID_GUARANI 133 +#define TT_MAC_LANGID_AYMARA 134 +#define TT_MAC_LANGID_TATAR 135 +#define TT_MAC_LANGID_UIGHUR 136 +#define TT_MAC_LANGID_DZONGKHA 137 +#define TT_MAC_LANGID_JAVANESE 138 +#define TT_MAC_LANGID_SUNDANESE 139 + + +#if 0 /* these seem to be errors that have been dropped */ + +#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 +#define TT_MAC_LANGID_IRISH_GAELIC 141 + +#endif + + + /* The following codes are new as of 2000-03-10 */ +#define TT_MAC_LANGID_GALICIAN 140 +#define TT_MAC_LANGID_AFRIKAANS 141 +#define TT_MAC_LANGID_BRETON 142 +#define TT_MAC_LANGID_INUKTITUT 143 +#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 +#define TT_MAC_LANGID_MANX_GAELIC 145 +#define TT_MAC_LANGID_IRISH_GAELIC 146 +#define TT_MAC_LANGID_TONGAN 147 +#define TT_MAC_LANGID_GREEK_POLYTONIC 148 +#define TT_MAC_LANGID_GREELANDIC 149 +#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MICROSOFT. */ + /* */ + /* The canonical source for the MS assigned LCIDs is */ + /* */ + /* http://www.microsoft.com/globaldev/reference/lcid-all.mspx */ + /* */ + +#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 +#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 +#define TT_MS_LANGID_ARABIC_IRAQ 0x0801 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0C01 +#define TT_MS_LANGID_ARABIC_LIBYA 0x1001 +#define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 +#define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1C01 +#define TT_MS_LANGID_ARABIC_OMAN 0x2001 +#define TT_MS_LANGID_ARABIC_YEMEN 0x2401 +#define TT_MS_LANGID_ARABIC_SYRIA 0x2801 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2C01 +#define TT_MS_LANGID_ARABIC_LEBANON 0x3001 +#define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 +#define TT_MS_LANGID_ARABIC_UAE 0x3801 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3C01 +#define TT_MS_LANGID_ARABIC_QATAR 0x4001 +#define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 +#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 +#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 +#define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 +#define TT_MS_LANGID_CHINESE_PRC 0x0804 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0C04 +#define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 + +#if 1 /* this looks like the correct value */ +#define TT_MS_LANGID_CHINESE_MACAU 0x1404 +#else /* but beware, Microsoft may change its mind... + the most recent Word reference has the following: */ +#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG +#endif + +#if 0 /* used only with .NET `cultures'; commented out */ +#define TT_MS_LANGID_CHINESE_TRADITIONAL 0x7C04 +#endif + +#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 +#define TT_MS_LANGID_DANISH_DENMARK 0x0406 +#define TT_MS_LANGID_GERMAN_GERMANY 0x0407 +#define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0C07 +#define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 +#define TT_MS_LANGID_GREEK_GREECE 0x0408 + + /* don't ask what this one means... It is commented out currently. */ +#if 0 +#define TT_MS_LANGID_GREEK_GREECE2 0x2008 +#endif + +#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 +#define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 +#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0C09 +#define TT_MS_LANGID_ENGLISH_CANADA 0x1009 +#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 +#define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1C09 +#define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 +#define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 +#define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2C09 +#define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 +#define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 +#define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3C09 +#define TT_MS_LANGID_ENGLISH_INDIA 0x4009 +#define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 +#define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040A +#define TT_MS_LANGID_SPANISH_MEXICO 0x080A +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0C0A +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100A +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140A +#define TT_MS_LANGID_SPANISH_PANAMA 0x180A +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1C0A +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200A +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240A +#define TT_MS_LANGID_SPANISH_PERU 0x280A +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2C0A +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300A +#define TT_MS_LANGID_SPANISH_CHILE 0x340A +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380A +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3C0A +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400A +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440A +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480A +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4C0A +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500A +#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540A + /* The following ID blatantly violate MS specs by using a */ + /* sublanguage > 0x1F. */ +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40AU +#define TT_MS_LANGID_FINNISH_FINLAND 0x040B +#define TT_MS_LANGID_FRENCH_FRANCE 0x040C +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080C +#define TT_MS_LANGID_FRENCH_CANADA 0x0C0C +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100C +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140C +#define TT_MS_LANGID_FRENCH_MONACO 0x180C +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1C0C +#define TT_MS_LANGID_FRENCH_REUNION 0x200C +#define TT_MS_LANGID_FRENCH_CONGO 0x240C + /* which was formerly: */ +#define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280C +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2C0C +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300C +#define TT_MS_LANGID_FRENCH_MALI 0x340C +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380C +#define TT_MS_LANGID_FRENCH_HAITI 0x3C0C + /* and another violation of the spec (see 0xE40AU) */ +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40CU +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040D +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040E +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040F +#define TT_MS_LANGID_ITALIAN_ITALY 0x0410 +#define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 +#define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 +#define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 +#define TT_MS_LANGID_POLISH_POLAND 0x0415 +#define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 +#define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 +#define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 +#define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041A +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081A +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0C1A + +#if 0 /* this used to be this value, but it looks like we were wrong */ +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101A +#else /* current sources say */ +#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101A +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141A + /* and XPsp2 Platform SDK added (2004-07-26) */ + /* Names are shortened to be significant within 40 chars. */ +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181A +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181A +#endif + +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041B +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041C +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041D +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081D +#define TT_MS_LANGID_THAI_THAILAND 0x041E +#define TT_MS_LANGID_TURKISH_TURKEY 0x041F +#define TT_MS_LANGID_URDU_PAKISTAN 0x0420 +#define TT_MS_LANGID_URDU_INDIA 0x0820 +#define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 +#define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 +#define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 +#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 +#define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 +#define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 +#define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 +#define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 +#define TT_MS_LANGID_FARSI_IRAN 0x0429 +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042A +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042B +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042C +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082C +#define TT_MS_LANGID_BASQUE_SPAIN 0x042D +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042E +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042F +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 +#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 +#define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 +#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 +#define TT_MS_LANGID_HINDI_INDIA 0x0439 +#define TT_MS_LANGID_MALTESE_MALTA 0x043A + /* Added by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043B +#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083B +#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3B +#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103B +#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143B +#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183B +#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3B +#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203B +#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243B + /* ... and we also keep our old identifier... */ +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043B + +#if 0 /* this seems to be a previous inversion */ +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C +#else +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C +#endif + +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043D +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043E +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083E +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043F +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ + TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN + +#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 +#define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 +#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 +#define TT_MS_LANGID_BENGALI_INDIA 0x0445 +#define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 +#define TT_MS_LANGID_PUNJABI_INDIA 0x0446 +#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 +#define TT_MS_LANGID_GUJARATI_INDIA 0x0447 +#define TT_MS_LANGID_ORIYA_INDIA 0x0448 +#define TT_MS_LANGID_TAMIL_INDIA 0x0449 +#define TT_MS_LANGID_TELUGU_INDIA 0x044A +#define TT_MS_LANGID_KANNADA_INDIA 0x044B +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044C +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044D +#define TT_MS_LANGID_MARATHI_INDIA 0x044E +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044F +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 +#define TT_MS_LANGID_TIBETAN_CHINA 0x0451 + /* Don't use the next constant! It has */ + /* (1) the wrong spelling (Dzonghka) */ + /* (2) Microsoft doesn't officially define it -- */ + /* at least it is not in the List of Local */ + /* ID Values. */ + /* (3) Dzongkha is not the same language as */ + /* Tibetan, so merging it is wrong anyway. */ + /* */ + /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW. */ +#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 + +#if 0 + /* the following used to be defined */ +#define TT_MS_LANGID_TIBETAN_BHUTAN 0x0451 + /* ... but it was changed; */ +#else + /* So we will continue to #define it, but with the correct value */ +#define TT_MS_LANGID_TIBETAN_BHUTAN TT_MS_LANGID_DZONGHKA_BHUTAN +#endif + +#define TT_MS_LANGID_WELSH_WALES 0x0452 +#define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 +#define TT_MS_LANGID_LAO_LAOS 0x0454 +#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 +#define TT_MS_LANGID_GALICIAN_SPAIN 0x0456 +#define TT_MS_LANGID_KONKANI_INDIA 0x0457 +#define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 +#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 +#define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 + /* Missing a LCID for Sindhi in Devanagari script */ +#define TT_MS_LANGID_SYRIAC_SYRIA 0x045A +#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045B +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045C +#define TT_MS_LANGID_INUKTITUT_CANADA 0x045D +#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045E +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045F +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085F + /* Missing a LCID for Tifinagh script */ +#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 + /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ + /* script is yet unclear... might be Arabic, Nagari or Sharada */ +#define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 + /* ... and aliased (by MS) for compatibility reasons. */ +#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA +#define TT_MS_LANGID_NEPALI_NEPAL 0x0461 +#define TT_MS_LANGID_NEPALI_INDIA 0x0861 +#define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 +#define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 +#define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 +#define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_DIVEHI_MALDIVES TT_MS_LANGID_DHIVEHI_MALDIVES +#define TT_MS_LANGID_EDO_NIGERIA 0x0466 +#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 +#define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 +#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 +#define TT_MS_LANGID_YORUBA_NIGERIA 0x046A +#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046B +#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086B +#define TT_MS_LANGID_QUECHUA_PERU 0x0C6B +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046C + /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ + TT_MS_LANGID_SEPEDI_SOUTH_AFRICA + /* language codes 0x046D, 0x046E and 0x046F are (still) unknown. */ +#define TT_MS_LANGID_IGBO_NIGERIA 0x0470 +#define TT_MS_LANGID_KANURI_NIGERIA 0x0471 +#define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 +#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 +#define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 + /* also spelled in the `Passport SDK' list as: */ +#define TT_MS_LANGID_TIGRIGNA_ERYTREA TT_MS_LANGID_TIGRIGNA_ERYTHREA +#define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 +#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 +#define TT_MS_LANGID_LATIN 0x0476 +#define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 + /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */ + /* not written (but OTOH the peculiar writing system is worth */ + /* studying). */ +#define TT_MS_LANGID_YI_CHINA 0x0478 +#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 + /* language codes from 0x047A to 0x047F are (still) unknown. */ +#define TT_MS_LANGID_UIGHUR_CHINA 0x0480 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 + +#if 0 /* not deemed useful for fonts */ +#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04FF +#endif + + + /*************************************************************************/ + /* */ + /* Possible values of the `name' identifier field in the name records of */ + /* the TTF `name' table. These values are platform independent. */ + /* */ +#define TT_NAME_ID_COPYRIGHT 0 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 +#define TT_NAME_ID_FULL_NAME 4 +#define TT_NAME_ID_VERSION_STRING 5 +#define TT_NAME_ID_PS_NAME 6 +#define TT_NAME_ID_TRADEMARK 7 + + /* the following values are from the OpenType spec */ +#define TT_NAME_ID_MANUFACTURER 8 +#define TT_NAME_ID_DESIGNER 9 +#define TT_NAME_ID_DESCRIPTION 10 +#define TT_NAME_ID_VENDOR_URL 11 +#define TT_NAME_ID_DESIGNER_URL 12 +#define TT_NAME_ID_LICENSE 13 +#define TT_NAME_ID_LICENSE_URL 14 + /* number 15 is reserved */ +#define TT_NAME_ID_PREFERRED_FAMILY 16 +#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 +#define TT_NAME_ID_MAC_FULL_NAME 18 + + /* The following code is new as of 2000-01-21 */ +#define TT_NAME_ID_SAMPLE_TEXT 19 + + /* This is new in OpenType 1.3 */ +#define TT_NAME_ID_CID_FINDFONT_NAME 20 + + /* This is new in OpenType 1.5 */ +#define TT_NAME_ID_WWS_FAMILY 21 +#define TT_NAME_ID_WWS_SUBFAMILY 22 + + + /*************************************************************************/ + /* */ + /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ + /* */ + /* Updated 08-Nov-2008. */ + /* */ + + /* Bit 0 Basic Latin */ +#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ + /* Bit 1 C1 Controls and Latin-1 Supplement */ +#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ + /* Bit 2 Latin Extended-A */ +#define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ + /* Bit 3 Latin Extended-B */ +#define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ + /* Bit 4 IPA Extensions */ + /* Phonetic Extensions */ + /* Phonetic Extensions Supplement */ +#define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ + /* U+1D00-U+1D7F */ + /* U+1D80-U+1DBF */ + /* Bit 5 Spacing Modifier Letters */ + /* Modifier Tone Letters */ +#define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ + /* U+A700-U+A71F */ + /* Bit 6 Combining Diacritical Marks */ + /* Combining Diacritical Marks Supplement */ +#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ + /* U+1DC0-U+1DFF */ + /* Bit 7 Greek and Coptic */ +#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ + /* Bit 8 Coptic */ +#define TT_UCR_COPTIC (1L << 8) /* U+2C80-U+2CFF */ + /* Bit 9 Cyrillic */ + /* Cyrillic Supplement */ + /* Cyrillic Extended-A */ + /* Cyrillic Extended-B */ +#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ + /* U+0500-U+052F */ + /* U+2DE0-U+2DFF */ + /* U+A640-U+A69F */ + /* Bit 10 Armenian */ +#define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ + /* Bit 11 Hebrew */ +#define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ + /* Bit 12 Vai */ +#define TT_UCR_VAI (1L << 12) /* U+A500-U+A63F */ + /* Bit 13 Arabic */ + /* Arabic Supplement */ +#define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ + /* U+0750-U+077F */ + /* Bit 14 NKo */ +#define TT_UCR_NKO (1L << 14) /* U+07C0-U+07FF */ + /* Bit 15 Devanagari */ +#define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ + /* Bit 16 Bengali */ +#define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ + /* Bit 17 Gurmukhi */ +#define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ + /* Bit 18 Gujarati */ +#define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ + /* Bit 19 Oriya */ +#define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ + /* Bit 20 Tamil */ +#define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ + /* Bit 21 Telugu */ +#define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ + /* Bit 22 Kannada */ +#define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ + /* Bit 23 Malayalam */ +#define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ + /* Bit 24 Thai */ +#define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ + /* Bit 25 Lao */ +#define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ + /* Bit 26 Georgian */ + /* Georgian Supplement */ +#define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ + /* U+2D00-U+2D2F */ + /* Bit 27 Balinese */ +#define TT_UCR_BALINESE (1L << 27) /* U+1B00-U+1B7F */ + /* Bit 28 Hangul Jamo */ +#define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ + /* Bit 29 Latin Extended Additional */ + /* Latin Extended-C */ + /* Latin Extended-D */ +#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ + /* U+2C60-U+2C7F */ + /* U+A720-U+A7FF */ + /* Bit 30 Greek Extended */ +#define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ + /* Bit 31 General Punctuation */ + /* Supplemental Punctuation */ +#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ + /* U+2E00-U+2E7F */ + /* Bit 32 Superscripts And Subscripts */ +#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ + /* Bit 33 Currency Symbols */ +#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ + /* Bit 34 Combining Diacritical Marks For Symbols */ +#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ + /* Bit 35 Letterlike Symbols */ +#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ + /* Bit 36 Number Forms */ +#define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ + /* Bit 37 Arrows */ + /* Supplemental Arrows-A */ + /* Supplemental Arrows-B */ + /* Miscellaneous Symbols and Arrows */ +#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ + /* U+27F0-U+27FF */ + /* U+2900-U+297F */ + /* U+2B00-U+2BFF */ + /* Bit 38 Mathematical Operators */ + /* Supplemental Mathematical Operators */ + /* Miscellaneous Mathematical Symbols-A */ + /* Miscellaneous Mathematical Symbols-B */ +#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ + /* U+2A00-U+2AFF */ + /* U+27C0-U+27EF */ + /* U+2980-U+29FF */ + /* Bit 39 Miscellaneous Technical */ +#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ + /* Bit 40 Control Pictures */ +#define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ + /* Bit 41 Optical Character Recognition */ +#define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ + /* Bit 42 Enclosed Alphanumerics */ +#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ + /* Bit 43 Box Drawing */ +#define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ + /* Bit 44 Block Elements */ +#define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ + /* Bit 45 Geometric Shapes */ +#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ + /* Bit 46 Miscellaneous Symbols */ +#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ + /* Bit 47 Dingbats */ +#define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ + /* Bit 48 CJK Symbols and Punctuation */ +#define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ + /* Bit 49 Hiragana */ +#define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ + /* Bit 50 Katakana */ + /* Katakana Phonetic Extensions */ +#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ + /* U+31F0-U+31FF */ + /* Bit 51 Bopomofo */ + /* Bopomofo Extended */ +#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ + /* U+31A0-U+31BF */ + /* Bit 52 Hangul Compatibility Jamo */ +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ + /* Bit 53 Phags-Pa */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+A840-U+A87F */ +#define TT_UCR_KANBUN TT_UCR_CJK_MISC /* deprecated */ +#define TT_UCR_PHAGSPA + /* Bit 54 Enclosed CJK Letters and Months */ +#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ + /* Bit 55 CJK Compatibility */ +#define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ + /* Bit 56 Hangul Syllables */ +#define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ + /* Bit 57 High Surrogates */ + /* High Private Use Surrogates */ + /* Low Surrogates */ + /* */ + /* According to OpenType specs v.1.3+, */ + /* setting bit 57 implies that there is */ + /* at least one codepoint beyond the */ + /* Basic Multilingual Plane that is */ + /* supported by this font. So it really */ + /* means >= U+10000 */ +#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ + /* U+DB80-U+DBFF */ + /* U+DC00-U+DFFF */ +#define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES + /* Bit 58 Phoenician */ +#define TT_UCR_PHOENICIAN (1L << 26) /*U+10900-U+1091F*/ + /* Bit 59 CJK Unified Ideographs */ + /* CJK Radicals Supplement */ + /* Kangxi Radicals */ + /* Ideographic Description Characters */ + /* CJK Unified Ideographs Extension A */ + /* CJK Unified Ideographs Extension B */ + /* Kanbun */ +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ + /* U+2E80-U+2EFF */ + /* U+2F00-U+2FDF */ + /* U+2FF0-U+2FFF */ + /* U+3400-U+4DB5 */ + /*U+20000-U+2A6DF*/ + /* U+3190-U+319F */ + /* Bit 60 Private Use */ +#define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ + /* Bit 61 CJK Strokes */ + /* CJK Compatibility Ideographs */ + /* CJK Compatibility Ideographs Supplement */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+31C0-U+31EF */ + /* U+F900-U+FAFF */ + /*U+2F800-U+2FA1F*/ + /* Bit 62 Alphabetic Presentation Forms */ +#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ + /* Bit 63 Arabic Presentation Forms-A */ +#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ + /* Bit 64 Combining Half Marks */ +#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ + /* Bit 65 Vertical forms */ + /* CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE10-U+FE1F */ + /* U+FE30-U+FE4F */ + /* Bit 66 Small Form Variants */ +#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ + /* Bit 67 Arabic Presentation Forms-B */ +#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFE */ + /* Bit 68 Halfwidth and Fullwidth Forms */ +#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ + /* Bit 69 Specials */ +#define TT_UCR_SPECIALS (1L << 5) /* U+FFF0-U+FFFD */ + /* Bit 70 Tibetan */ +#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FFF */ + /* Bit 71 Syriac */ +#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ + /* Bit 72 Thaana */ +#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ + /* Bit 73 Sinhala */ +#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ + /* Bit 74 Myanmar */ +#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ + /* Bit 75 Ethiopic */ + /* Ethiopic Supplement */ + /* Ethiopic Extended */ +#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ + /* U+1380-U+139F */ + /* U+2D80-U+2DDF */ + /* Bit 76 Cherokee */ +#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ + /* Bit 77 Unified Canadian Aboriginal Syllabics */ +#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+167F */ + /* Bit 78 Ogham */ +#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ + /* Bit 79 Runic */ +#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ + /* Bit 80 Khmer */ + /* Khmer Symbols */ +#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ + /* U+19E0-U+19FF */ + /* Bit 81 Mongolian */ +#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ + /* Bit 82 Braille Patterns */ +#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ + /* Bit 83 Yi Syllables */ + /* Yi Radicals */ +#define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ + /* U+A490-U+A4CF */ + /* Bit 84 Tagalog */ + /* Hanunoo */ + /* Buhid */ + /* Tagbanwa */ +#define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ + /* U+1720-U+173F */ + /* U+1740-U+175F */ + /* U+1760-U+177F */ + /* Bit 85 Old Italic */ +#define TT_UCR_OLD_ITALIC (1L << 21) /*U+10300-U+1032F*/ + /* Bit 86 Gothic */ +#define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ + /* Bit 87 Deseret */ +#define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ + /* Bit 88 Byzantine Musical Symbols */ + /* Musical Symbols */ + /* Ancient Greek Musical Notation */ +#define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ + /*U+1D100-U+1D1FF*/ + /*U+1D200-U+1D24F*/ + /* Bit 89 Mathematical Alphanumeric Symbols */ +#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ + /* Bit 90 Private Use (plane 15) */ + /* Private Use (plane 16) */ +#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ + /*U+100000-U+10FFFD*/ + /* Bit 91 Variation Selectors */ + /* Variation Selectors Supplement */ +#define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ + /*U+E0100-U+E01EF*/ + /* Bit 92 Tags */ +#define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ + /* Bit 93 Limbu */ +#define TT_UCR_LIMBU (1L << 29) /* U+1900-U+194F */ + /* Bit 94 Tai Le */ +#define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ + /* Bit 95 New Tai Lue */ +#define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ + /* Bit 96 Buginese */ +#define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ + /* Bit 97 Glagolitic */ +#define TT_UCR_GLAGOLITIC (1L << 1) /* U+2C00-U+2C5F */ + /* Bit 98 Tifinagh */ +#define TT_UCR_TIFINAGH (1L << 2) /* U+2D30-U+2D7F */ + /* Bit 99 Yijing Hexagram Symbols */ +#define TT_UCR_YIJING (1L << 3) /* U+4DC0-U+4DFF */ + /* Bit 100 Syloti Nagri */ +#define TT_UCR_SYLOTI_NAGRI (1L << 4) /* U+A800-U+A82F */ + /* Bit 101 Linear B Syllabary */ + /* Linear B Ideograms */ + /* Aegean Numbers */ +#define TT_UCR_LINEAR_B (1L << 5) /*U+10000-U+1007F*/ + /*U+10080-U+100FF*/ + /*U+10100-U+1013F*/ + /* Bit 102 Ancient Greek Numbers */ +#define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) /*U+10140-U+1018F*/ + /* Bit 103 Ugaritic */ +#define TT_UCR_UGARITIC (1L << 7) /*U+10380-U+1039F*/ + /* Bit 104 Old Persian */ +#define TT_UCR_OLD_PERSIAN (1L << 8) /*U+103A0-U+103DF*/ + /* Bit 105 Shavian */ +#define TT_UCR_SHAVIAN (1L << 9) /*U+10450-U+1047F*/ + /* Bit 106 Osmanya */ +#define TT_UCR_OSMANYA (1L << 10) /*U+10480-U+104AF*/ + /* Bit 107 Cypriot Syllabary */ +#define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) /*U+10800-U+1083F*/ + /* Bit 108 Kharoshthi */ +#define TT_UCR_KHAROSHTHI (1L << 12) /*U+10A00-U+10A5F*/ + /* Bit 109 Tai Xuan Jing Symbols */ +#define TT_UCR_TAI_XUAN_JING (1L << 13) /*U+1D300-U+1D35F*/ + /* Bit 110 Cuneiform */ + /* Cuneiform Numbers and Punctuation */ +#define TT_UCR_CUNEIFORM (1L << 14) /*U+12000-U+123FF*/ + /*U+12400-U+1247F*/ + /* Bit 111 Counting Rod Numerals */ +#define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) /*U+1D360-U+1D37F*/ + /* Bit 112 Sundanese */ +#define TT_UCR_SUNDANESE (1L << 16) /* U+1B80-U+1BBF */ + /* Bit 113 Lepcha */ +#define TT_UCR_LEPCHA (1L << 17) /* U+1C00-U+1C4F */ + /* Bit 114 Ol Chiki */ +#define TT_UCR_OL_CHIKI (1L << 18) /* U+1C50-U+1C7F */ + /* Bit 115 Saurashtra */ +#define TT_UCR_SAURASHTRA (1L << 19) /* U+A880-U+A8DF */ + /* Bit 116 Kayah Li */ +#define TT_UCR_KAYAH_LI (1L << 20) /* U+A900-U+A92F */ + /* Bit 117 Rejang */ +#define TT_UCR_REJANG (1L << 21) /* U+A930-U+A95F */ + /* Bit 118 Cham */ +#define TT_UCR_CHAM (1L << 22) /* U+AA00-U+AA5F */ + /* Bit 119 Ancient Symbols */ +#define TT_UCR_ANCIENT_SYMBOLS (1L << 23) /*U+10190-U+101CF*/ + /* Bit 120 Phaistos Disc */ +#define TT_UCR_PHAISTOS_DISC (1L << 24) /*U+101D0-U+101FF*/ + /* Bit 121 Carian */ + /* Lycian */ + /* Lydian */ +#define TT_UCR_OLD_ANATOLIAN (1L << 25) /*U+102A0-U+102DF*/ + /*U+10280-U+1029F*/ + /*U+10920-U+1093F*/ + /* Bit 122 Domino Tiles */ + /* Mahjong Tiles */ +#define TT_UCR_GAME_TILES (1L << 26) /*U+1F030-U+1F09F*/ + /*U+1F000-U+1F02F*/ + /* Bit 123-127 Reserved for process-internal usage */ + + + /*************************************************************************/ + /* */ + /* Some compilers have a very limited length of identifiers. */ + /* */ +#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) +#define HAVE_LIMIT_ON_IDENTS +#endif + + +#ifndef HAVE_LIMIT_ON_IDENTS + + + /*************************************************************************/ + /* */ + /* Here some alias #defines in order to be clearer. */ + /* */ + /* These are not always #defined to stay within the 31~character limit, */ + /* which some compilers have. */ + /* */ + /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ + /* Borland compilers (read: from BC++ 3.1 on) can increase this limit. */ + /* If you get a warning with such a compiler, use the -i40 switch. */ + /* */ +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ + TT_UCR_ARABIC_PRESENTATIONS_A +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ + TT_UCR_ARABIC_PRESENTATIONS_B + +#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ + TT_UCR_COMBINING_DIACRITICS +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ + TT_UCR_COMBINING_DIACRITICS_SYMB + + +#endif /* !HAVE_LIMIT_ON_IDENTS */ + + +FT_END_HEADER + +#endif /* __TTNAMEID_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/tttables.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/tttables.h new file mode 100644 index 00000000..e1d8b05e --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/tttables.h @@ -0,0 +1,829 @@ +/***************************************************************************/ +/* */ +/* tttables.h */ +/* */ +/* Basic SFNT/TrueType tables definitions and interface */ +/* (specification only). */ +/* */ +/* Copyright 1996-2005, 2008-2014 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTTABLES_H__ +#define __TTTABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + /* <Title> */ + /* TrueType Tables */ + /* */ + /* <Abstract> */ + /* TrueType specific table types and functions. */ + /* */ + /* <Description> */ + /* This section contains the definition of TrueType-specific tables */ + /* as well as some routines used to access and process them. */ + /* */ + /* <Order> */ + /* TT_Header */ + /* TT_HoriHeader */ + /* TT_VertHeader */ + /* TT_OS2 */ + /* TT_Postscript */ + /* TT_PCLT */ + /* TT_MaxProfile */ + /* */ + /* FT_Sfnt_Tag */ + /* FT_Get_Sfnt_Table */ + /* FT_Load_Sfnt_Table */ + /* FT_Sfnt_Table_Info */ + /* */ + /* FT_Get_CMap_Language_ID */ + /* FT_Get_CMap_Format */ + /* */ + /* FT_PARAM_TAG_UNPATENTED_HINTING */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Header */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType font header table. All */ + /* fields follow the TrueType specification. */ + /* */ + typedef struct TT_Header_ + { + FT_Fixed Table_Version; + FT_Fixed Font_Revision; + + FT_Long CheckSum_Adjust; + FT_Long Magic_Number; + + FT_UShort Flags; + FT_UShort Units_Per_EM; + + FT_Long Created [2]; + FT_Long Modified[2]; + + FT_Short xMin; + FT_Short yMin; + FT_Short xMax; + FT_Short yMax; + + FT_UShort Mac_Style; + FT_UShort Lowest_Rec_PPEM; + + FT_Short Font_Direction; + FT_Short Index_To_Loc_Format; + FT_Short Glyph_Data_Format; + + } TT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HoriHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType horizontal header, the `hhea' */ + /* table, as well as the corresponding horizontal metrics table, */ + /* i.e., the `hmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of all */ + /* glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoAscender' field */ + /* of the OS/2 table instead if you want */ + /* the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the distance */ + /* from the baseline to the bottom-most of */ + /* all glyph points found in the font. It */ + /* is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Width_Max :: This field is the maximum of all advance */ + /* widths found in the font. It can be */ + /* used to compute the maximum width of an */ + /* arbitrary string of text. */ + /* */ + /* min_Left_Side_Bearing :: The minimum left side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Right_Side_Bearing :: The minimum right side bearing of all */ + /* glyphs within the font. */ + /* */ + /* xMax_Extent :: The maximum horizontal extent (i.e., the */ + /* `width' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ + /* table -- this value can be smaller than */ + /* the total number of glyphs in the font. */ + /* */ + /* long_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields, */ + /* which are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_HoriHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Width_Max; /* advance width maximum */ + + FT_Short min_Left_Side_Bearing; /* minimum left-sb */ + FT_Short min_Right_Side_Bearing; /* minimum right-sb */ + FT_Short xMax_Extent; /* xmax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_HMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they are used to connect the metrics header to the relevant */ + /* `HMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_HoriHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_VertHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType vertical header, the `vhea' */ + /* table, as well as the corresponding vertical metrics table, i.e., */ + /* the `vmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of */ + /* all glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoAscender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the */ + /* distance from the baseline to the */ + /* bottom-most of all glyph points found */ + /* in the font. It is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Height_Max :: This field is the maximum of all */ + /* advance heights found in the font. It */ + /* can be used to compute the maximum */ + /* height of an arbitrary string of text. */ + /* */ + /* min_Top_Side_Bearing :: The minimum top side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ + /* glyphs within the font. */ + /* */ + /* yMax_Extent :: The maximum vertical extent (i.e., the */ + /* `height' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* caret_Offset :: The cursor's offset for slanted fonts. */ + /* This value is `reserved' in vmtx */ + /* version 1.0. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of VMetrics entries in the */ + /* `vmtx' table -- this value can be */ + /* smaller than the total number of glyphs */ + /* in the font. */ + /* */ + /* long_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields, */ + /* which are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_VertHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Height_Max; /* advance height maximum */ + + FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ + FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ + FT_Short yMax_Extent; /* xmax or ymax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_VMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_VertHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_OS2 */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType OS/2 table. All fields */ + /* comply to the OpenType specification. */ + /* */ + /* Note that we now support old Mac fonts that do not include an OS/2 */ + /* table. In this case, the `version' field is always set to 0xFFFF. */ + /* */ + typedef struct TT_OS2_ + { + FT_UShort version; /* 0x0001 - more or 0xFFFF */ + FT_Short xAvgCharWidth; + FT_UShort usWeightClass; + FT_UShort usWidthClass; + FT_Short fsType; + FT_Short ySubscriptXSize; + FT_Short ySubscriptYSize; + FT_Short ySubscriptXOffset; + FT_Short ySubscriptYOffset; + FT_Short ySuperscriptXSize; + FT_Short ySuperscriptYSize; + FT_Short ySuperscriptXOffset; + FT_Short ySuperscriptYOffset; + FT_Short yStrikeoutSize; + FT_Short yStrikeoutPosition; + FT_Short sFamilyClass; + + FT_Byte panose[10]; + + FT_ULong ulUnicodeRange1; /* Bits 0-31 */ + FT_ULong ulUnicodeRange2; /* Bits 32-63 */ + FT_ULong ulUnicodeRange3; /* Bits 64-95 */ + FT_ULong ulUnicodeRange4; /* Bits 96-127 */ + + FT_Char achVendID[4]; + + FT_UShort fsSelection; + FT_UShort usFirstCharIndex; + FT_UShort usLastCharIndex; + FT_Short sTypoAscender; + FT_Short sTypoDescender; + FT_Short sTypoLineGap; + FT_UShort usWinAscent; + FT_UShort usWinDescent; + + /* only version 1 and higher: */ + + FT_ULong ulCodePageRange1; /* Bits 0-31 */ + FT_ULong ulCodePageRange2; /* Bits 32-63 */ + + /* only version 2 and higher: */ + + FT_Short sxHeight; + FT_Short sCapHeight; + FT_UShort usDefaultChar; + FT_UShort usBreakChar; + FT_UShort usMaxContext; + + /* only version 5 and higher: */ + + FT_UShort usLowerOpticalPointSize; /* in twips (1/20th points) */ + FT_UShort usUpperOpticalPointSize; /* in twips (1/20th points) */ + + } TT_OS2; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Postscript */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PostScript table. All fields */ + /* comply to the TrueType specification. This structure does not */ + /* reference the PostScript glyph names, which can be nevertheless */ + /* accessed with the `ttpost' module. */ + /* */ + typedef struct TT_Postscript_ + { + FT_Fixed FormatType; + FT_Fixed italicAngle; + FT_Short underlinePosition; + FT_Short underlineThickness; + FT_ULong isFixedPitch; + FT_ULong minMemType42; + FT_ULong maxMemType42; + FT_ULong minMemType1; + FT_ULong maxMemType1; + + /* Glyph names follow in the file, but we don't */ + /* load them by default. See the ttpost.c file. */ + + } TT_Postscript; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_PCLT */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PCLT table. All fields */ + /* comply to the TrueType specification. */ + /* */ + typedef struct TT_PCLT_ + { + FT_Fixed Version; + FT_ULong FontNumber; + FT_UShort Pitch; + FT_UShort xHeight; + FT_UShort Style; + FT_UShort TypeFamily; + FT_UShort CapHeight; + FT_UShort SymbolSet; + FT_Char TypeFace[16]; + FT_Char CharacterComplement[8]; + FT_Char FileName[6]; + FT_Char StrokeWeight; + FT_Char WidthType; + FT_Byte SerifStyle; + FT_Byte Reserved; + + } TT_PCLT; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_MaxProfile */ + /* */ + /* <Description> */ + /* The maximum profile is a table containing many max values, which */ + /* can be used to pre-allocate arrays. This ensures that no memory */ + /* allocation occurs during a glyph load. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numGlyphs :: The number of glyphs in this TrueType */ + /* font. */ + /* */ + /* maxPoints :: The maximum number of points in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositePoints'. */ + /* */ + /* maxContours :: The maximum number of contours in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositeContours'. */ + /* */ + /* maxCompositePoints :: The maximum number of points in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxPoints'. */ + /* */ + /* maxCompositeContours :: The maximum number of contours in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxContours'. */ + /* */ + /* maxZones :: The maximum number of zones used for */ + /* glyph hinting. */ + /* */ + /* maxTwilightPoints :: The maximum number of points in the */ + /* twilight zone used for glyph hinting. */ + /* */ + /* maxStorage :: The maximum number of elements in the */ + /* storage area used for glyph hinting. */ + /* */ + /* maxFunctionDefs :: The maximum number of function */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxInstructionDefs :: The maximum number of instruction */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxStackElements :: The maximum number of stack elements used */ + /* during bytecode interpretation. */ + /* */ + /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ + /* used for glyph hinting. */ + /* */ + /* maxComponentElements :: The maximum number of simple (i.e., non- */ + /* composite) glyphs in a composite glyph. */ + /* */ + /* maxComponentDepth :: The maximum nesting depth of composite */ + /* glyphs. */ + /* */ + /* <Note> */ + /* This structure is only used during font loading. */ + /* */ + typedef struct TT_MaxProfile_ + { + FT_Fixed version; + FT_UShort numGlyphs; + FT_UShort maxPoints; + FT_UShort maxContours; + FT_UShort maxCompositePoints; + FT_UShort maxCompositeContours; + FT_UShort maxZones; + FT_UShort maxTwilightPoints; + FT_UShort maxStorage; + FT_UShort maxFunctionDefs; + FT_UShort maxInstructionDefs; + FT_UShort maxStackElements; + FT_UShort maxSizeOfInstructions; + FT_UShort maxComponentElements; + FT_UShort maxComponentDepth; + + } TT_MaxProfile; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Sfnt_Tag */ + /* */ + /* <Description> */ + /* An enumeration used to specify the index of an SFNT table. */ + /* Used in the @FT_Get_Sfnt_Table API function. */ + /* */ + /* <Values> */ + /* FT_SFNT_HEAD :: To access the font's @TT_Header structure. */ + /* */ + /* FT_SFNT_MAXP :: To access the font's @TT_MaxProfile structure. */ + /* */ + /* FT_SFNT_OS2 :: To access the font's @TT_OS2 structure. */ + /* */ + /* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */ + /* */ + /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader struture. */ + /* */ + /* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */ + /* */ + /* FT_SFNT_PCLT :: To access the font's @TT_PCLT structure. */ + /* */ + typedef enum FT_Sfnt_Tag_ + { + FT_SFNT_HEAD, + FT_SFNT_MAXP, + FT_SFNT_OS2, + FT_SFNT_HHEA, + FT_SFNT_VHEA, + FT_SFNT_POST, + FT_SFNT_PCLT, + + FT_SFNT_MAX + + } FT_Sfnt_Tag; + + /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag' */ + /* values instead */ +#define ft_sfnt_head FT_SFNT_HEAD +#define ft_sfnt_maxp FT_SFNT_MAXP +#define ft_sfnt_os2 FT_SFNT_OS2 +#define ft_sfnt_hhea FT_SFNT_HHEA +#define ft_sfnt_vhea FT_SFNT_VHEA +#define ft_sfnt_post FT_SFNT_POST +#define ft_sfnt_pclt FT_SFNT_PCLT + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Table */ + /* */ + /* <Description> */ + /* Return a pointer to a given SFNT table within a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source. */ + /* */ + /* tag :: The index of the SFNT table. */ + /* */ + /* <Return> */ + /* A type-less pointer to the table. This will be~0 in case of */ + /* error, or if the corresponding table was not found *OR* loaded */ + /* from the file. */ + /* */ + /* Use a typecast according to `tag' to access the structure */ + /* elements. */ + /* */ + /* <Note> */ + /* The table is owned by the face object and disappears with it. */ + /* */ + /* This function is only useful to access SFNT tables that are loaded */ + /* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */ + /* a list. */ + /* */ + /* Here an example how to access the `vhea' table: */ + /* */ + /* { */ + /* TT_VertHeader* vert_header; */ + /* */ + /* */ + /* vert_header = */ + /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA ); */ + /* } */ + /* */ + FT_EXPORT( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ); + + + /************************************************************************** + * + * @function: + * FT_Load_Sfnt_Table + * + * @description: + * Load any font table into client memory. + * + * @input: + * face :: + * A handle to the source face. + * + * tag :: + * The four-byte tag of the table to load. Use the value~0 if you want + * to access the whole font file. Otherwise, you can use one of the + * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new + * one with @FT_MAKE_TAG. + * + * offset :: + * The starting offset in the table (or file if tag == 0). + * + * @output: + * buffer :: + * The target buffer address. The client must ensure that the memory + * array is big enough to hold the data. + * + * @inout: + * length :: + * If the `length' parameter is NULL, then try to load the whole table. + * Return an error code if it fails. + * + * Else, if `*length' is~0, exit immediately while returning the + * table's (or file) full size in it. + * + * Else the number of bytes to read from the table or file, from the + * starting offset. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If you need to determine the table's length you should first call this + * function with `*length' set to~0, as in the following example: + * + * { + * FT_ULong length = 0; + * + * + * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + * if ( error ) { ... table does not exist ... } + * + * buffer = malloc( length ); + * if ( buffer == NULL ) { ... not enough memory ... } + * + * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); + * if ( error ) { ... could not load table ... } + * } + * + * Note that structures like @TT_Header or @TT_OS2 can't be used with + * this function; they are limited to @FT_Get_Sfnt_Table. Reason is that + * those structures depend on the processor architecture, with varying + * size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian). + * + */ + FT_EXPORT( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + /************************************************************************** + * + * @function: + * FT_Sfnt_Table_Info + * + * @description: + * Return information on an SFNT table. + * + * @input: + * face :: + * A handle to the source face. + * + * table_index :: + * The index of an SFNT table. The function returns + * FT_Err_Table_Missing for an invalid value. + * + * @inout: + * tag :: + * The name tag of the SFNT table. If the value is NULL, `table_index' + * is ignored, and `length' returns the number of SFNT tables in the + * font. + * + * @output: + * length :: + * The length of the SFNT table (or the number of SFNT tables, depending + * on `tag'). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * While parsing fonts, FreeType handles SFNT tables with length zero as + * missing. + * + */ + FT_EXPORT( FT_Error ) + FT_Sfnt_Table_Info( FT_Face face, + FT_UInt table_index, + FT_ULong *tag, + FT_ULong *length ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Language_ID */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap language ID. Definitions of */ + /* language ID values are in `ttnameid.h'. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The language ID of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, just return~0 as the default value. */ + /* */ + /* For a format~14 cmap (to access Unicode IVS), the return value is */ + /* 0xFFFFFFFF. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Format */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap format. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The format of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, return -1. */ + /* */ + FT_EXPORT( FT_Long ) + FT_Get_CMap_Format( FT_CharMap charmap ); + + /* */ + + +FT_END_HEADER + +#endif /* __TTTABLES_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/tttags.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/tttags.h new file mode 100644 index 00000000..d59aa19a --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/tttags.h @@ -0,0 +1,111 @@ +/***************************************************************************/ +/* */ +/* tttags.h */ +/* */ +/* Tags for TrueType and OpenType tables (specification only). */ +/* */ +/* Copyright 1996-2001, 2004, 2005, 2007, 2008, 2013 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTAGS_H__ +#define __TTAGS_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + +#define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' ) +#define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' ) +#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) +#define TTAG_BDF FT_MAKE_TAG( 'B', 'D', 'F', ' ' ) +#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) +#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) +#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) +#define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' ) +#define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' ) +#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) +#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) +#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) +#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) +#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) +#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) +#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) +#define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) +#define TTAG_FOND FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) +#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) +#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) +#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) +#define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' ) +#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) +#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) +#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) +#define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) +#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) +#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) +#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) +#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) +#define TTAG_JSTF FT_MAKE_TAG( 'J', 'S', 'T', 'F' ) +#define TTAG_just FT_MAKE_TAG( 'j', 'u', 's', 't' ) +#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) +#define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) +#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) +#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_LWFN FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) +#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) +#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) +#define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) +#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) +#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) +#define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) +#define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) +#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) +#define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) +#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) +#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) +#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_POST FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) +#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) +#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) +#define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_sbix FT_MAKE_TAG( 's', 'b', 'i', 'x' ) +#define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) +#define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) +#define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) +#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) +#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) +#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) +#define TTAG_TYP1 FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) +#define TTAG_typ1 FT_MAKE_TAG( 't', 'y', 'p', '1' ) +#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) +#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) +#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) +#define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) + + +FT_END_HEADER + +#endif /* __TTAGS_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ttunpat.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ttunpat.h new file mode 100644 index 00000000..bf53ddd5 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/freetype2/ttunpat.h @@ -0,0 +1,60 @@ +/***************************************************************************/ +/* */ +/* ttunpat.h */ +/* */ +/* Definitions for the unpatented TrueType hinting system */ +/* */ +/* Copyright 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by Graham Asher <graham.asher@btinternet.com> */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTUNPAT_H__ +#define __TTUNPAT_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_UNPATENTED_HINTING + * + * @description: + * A constant used as the tag of an @FT_Parameter structure to indicate + * that unpatented methods only should be used by the TrueType bytecode + * interpreter for a typeface opened by @FT_Open_Face. + * + */ +#define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) + + /* */ + + +FT_END_HEADER + + +#endif /* __TTUNPAT_H__ */ + + +/* END */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jconfig.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jconfig.h new file mode 100644 index 00000000..7fbc1ac6 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jconfig.h @@ -0,0 +1,50 @@ +/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */ +/* see jconfig.txt for explanations */ + +#define JPEG_LIB_VERSION 62 +#define LIBJPEG_TURBO_VERSION 1.4.0 +#define C_ARITH_CODING_SUPPORTED +#define D_ARITH_CODING_SUPPORTED +#define MEM_SRCDST_SUPPORTED + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +/* #define void char */ +/* #define const */ +#undef __CHAR_UNSIGNED__ +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */ +#undef INCOMPLETE_TYPES_BROKEN + +/* Define "boolean" as unsigned char, not int, per Windows custom */ +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ + +/* Define "INT32" as int, not long, per Windows custom */ +#if !(defined(_BASETSD_H_) || defined(_BASETSD_H)) /* don't conflict if basetsd.h already read */ +typedef short INT16; +typedef signed int INT32; +#endif +#define XMD_H /* prevent jmorecfg.h from redefining it */ + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED + +#endif /* JPEG_INTERNALS */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jerror.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jerror.h new file mode 100644 index 00000000..402613e0 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jerror.h @@ -0,0 +1,316 @@ +/* + * jerror.h + * + * This file was part of the Independent JPEG Group's software: + * Copyright (C) 1994-1997, Thomas G. Lane. + * Modified 1997-2009 by Guido Vollbeding. + * libjpeg-turbo Modifications: + * Copyright (C) 2014, D. R. Commander. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +#if JPEG_LIB_VERSION < 70 +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, arithmetic coding is not implemented") +#endif +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +#if JPEG_LIB_VERSION >= 70 +JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request") +#endif +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +#if JPEG_LIB_VERSION >= 70 +JMESSAGE(JERR_BAD_DROP_SAMPLING, + "Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c") +#endif +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +#if JPEG_LIB_VERSION >= 70 +JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") +#endif +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT_SHORT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +#if JPEG_LIB_VERSION >= 70 +JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") +#endif +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") +#if JPEG_LIB_VERSION < 70 +JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request") +#if defined(C_ARITH_CODING_SUPPORTED) || defined(D_ARITH_CODING_SUPPORTED) +JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") +JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") +#endif +#endif + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jmorecfg.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jmorecfg.h new file mode 100644 index 00000000..108e7de9 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jmorecfg.h @@ -0,0 +1,388 @@ +/* + * jmorecfg.h + * + * This file was part of the Independent JPEG Group's software: + * Copyright (C) 1991-1997, Thomas G. Lane. + * libjpeg-turbo Modifications: + * Copyright (C) 2009, 2011, 2014, D. R. Commander. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef __CHAR_UNSIGNED__ +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* __CHAR_UNSIGNED__ */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef __CHAR_UNSIGNED__ +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* __CHAR_UNSIGNED__ */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef __CHAR_UNSIGNED__ +typedef char UINT8; +#else /* not __CHAR_UNSIGNED__ */ +typedef short UINT8; +#endif /* __CHAR_UNSIGNED__ */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +typedef long INT32; +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* Originally, this macro was used as a way of defining function prototypes + * for both modern compilers as well as older compilers that did not support + * prototype parameters. libjpeg-turbo has never supported these older, + * non-ANSI compilers, but the macro is still included because there is some + * software out there that uses it. + */ + +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist + + +/* libjpeg-turbo no longer supports platforms that have far symbols (MS-DOS), + * but again, some software relies on this macro. + */ + +#undef FAR +#define FAR + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * The RGB_RED, RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE macros are a vestigial + * feature of libjpeg. The idea was that, if an application developer needed + * to compress from/decompress to a BGR/BGRX/RGBX/XBGR/XRGB buffer, they could + * change these macros, rebuild libjpeg, and link their application statically + * with it. In reality, few people ever did this, because there were some + * severe restrictions involved (cjpeg and djpeg no longer worked properly, + * compressing/decompressing RGB JPEGs no longer worked properly, and the color + * quantizer wouldn't work with pixel sizes other than 3.) Further, since all + * of the O/S-supplied versions of libjpeg were built with the default values + * of RGB_RED, RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE, many applications have + * come to regard these values as immutable. + * + * The libjpeg-turbo colorspace extensions provide a much cleaner way of + * compressing from/decompressing to buffers with arbitrary component orders + * and pixel sizes. Thus, we do not support changing the values of RGB_RED, + * RGB_GREEN, RGB_BLUE, or RGB_PIXELSIZE. In addition to the restrictions + * listed above, changing these values will also break the SIMD extensions and + * the regression tests. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + +#define JPEG_NUMCS 17 + +#define EXT_RGB_RED 0 +#define EXT_RGB_GREEN 1 +#define EXT_RGB_BLUE 2 +#define EXT_RGB_PIXELSIZE 3 + +#define EXT_RGBX_RED 0 +#define EXT_RGBX_GREEN 1 +#define EXT_RGBX_BLUE 2 +#define EXT_RGBX_PIXELSIZE 4 + +#define EXT_BGR_RED 2 +#define EXT_BGR_GREEN 1 +#define EXT_BGR_BLUE 0 +#define EXT_BGR_PIXELSIZE 3 + +#define EXT_BGRX_RED 2 +#define EXT_BGRX_GREEN 1 +#define EXT_BGRX_BLUE 0 +#define EXT_BGRX_PIXELSIZE 4 + +#define EXT_XBGR_RED 3 +#define EXT_XBGR_GREEN 2 +#define EXT_XBGR_BLUE 1 +#define EXT_XBGR_PIXELSIZE 4 + +#define EXT_XRGB_RED 1 +#define EXT_XRGB_GREEN 2 +#define EXT_XRGB_BLUE 3 +#define EXT_XRGB_PIXELSIZE 4 + +static const int rgb_red[JPEG_NUMCS] = { + -1, -1, RGB_RED, -1, -1, -1, EXT_RGB_RED, EXT_RGBX_RED, + EXT_BGR_RED, EXT_BGRX_RED, EXT_XBGR_RED, EXT_XRGB_RED, + EXT_RGBX_RED, EXT_BGRX_RED, EXT_XBGR_RED, EXT_XRGB_RED, + -1 +}; + +static const int rgb_green[JPEG_NUMCS] = { + -1, -1, RGB_GREEN, -1, -1, -1, EXT_RGB_GREEN, EXT_RGBX_GREEN, + EXT_BGR_GREEN, EXT_BGRX_GREEN, EXT_XBGR_GREEN, EXT_XRGB_GREEN, + EXT_RGBX_GREEN, EXT_BGRX_GREEN, EXT_XBGR_GREEN, EXT_XRGB_GREEN, + -1 +}; + +static const int rgb_blue[JPEG_NUMCS] = { + -1, -1, RGB_BLUE, -1, -1, -1, EXT_RGB_BLUE, EXT_RGBX_BLUE, + EXT_BGR_BLUE, EXT_BGRX_BLUE, EXT_XBGR_BLUE, EXT_XRGB_BLUE, + EXT_RGBX_BLUE, EXT_BGRX_BLUE, EXT_XBGR_BLUE, EXT_XRGB_BLUE, + -1 +}; + +static const int rgb_pixelsize[JPEG_NUMCS] = { + -1, -1, RGB_PIXELSIZE, -1, -1, -1, EXT_RGB_PIXELSIZE, EXT_RGBX_PIXELSIZE, + EXT_BGR_PIXELSIZE, EXT_BGRX_PIXELSIZE, EXT_XBGR_PIXELSIZE, EXT_XRGB_PIXELSIZE, + EXT_RGBX_PIXELSIZE, EXT_BGRX_PIXELSIZE, EXT_XBGR_PIXELSIZE, EXT_XRGB_PIXELSIZE, + -1 +}; + +/* Definitions for speed-related optimizations. */ + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#ifndef WITH_SIMD +#define MULTIPLIER int /* type for fastest integer multiply */ +#else +#define MULTIPLIER short /* prefer 16-bit with SIMD for parellelism */ +#endif +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + */ + +#ifndef FAST_FLOAT +#define FAST_FLOAT float +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jpeglib.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jpeglib.h new file mode 100644 index 00000000..9615c5d0 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/jpeglib.h @@ -0,0 +1,1115 @@ +/* + * jpeglib.h + * + * This file was part of the Independent JPEG Group's software: + * Copyright (C) 1991-1998, Thomas G. Lane. + * Modified 2002-2009 by Guido Vollbeding. + * libjpeg-turbo Modifications: + * Copyright (C) 2009-2011, 2013-2014, D. R. Commander. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +#ifdef __cplusplus +#ifndef DONT_USE_EXTERN_C +extern "C" { +#endif +#endif + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + */ + +typedef JSAMPLE *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values from 1 to 16 are supported. + * Note that different components may receive different IDCT scalings. + */ +#if JPEG_LIB_VERSION >= 70 + int DCT_h_scaled_size; + int DCT_v_scaled_size; +#else + int DCT_scaled_size; +#endif + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_[h_]scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +#define JCS_EXTENSIONS 1 +#define JCS_ALPHA_EXTENSIONS 1 + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue as specified by the RGB_RED, + RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE macros */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK, /* Y/Cb/Cr/K */ + JCS_EXT_RGB, /* red/green/blue */ + JCS_EXT_RGBX, /* red/green/blue/x */ + JCS_EXT_BGR, /* blue/green/red */ + JCS_EXT_BGRX, /* blue/green/red/x */ + JCS_EXT_XBGR, /* x/blue/green/red */ + JCS_EXT_XRGB, /* x/red/green/blue */ + /* When out_color_space it set to JCS_EXT_RGBX, JCS_EXT_BGRX, JCS_EXT_XBGR, + or JCS_EXT_XRGB during decompression, the X byte is undefined, and in + order to ensure the best performance, libjpeg-turbo can set that byte to + whatever value it wishes. Use the following colorspace constants to + ensure that the X byte is set to 0xFF, so that it can be interpreted as an + opaque alpha channel. */ + JCS_EXT_RGBA, /* red/green/blue/alpha */ + JCS_EXT_BGRA, /* blue/green/red/alpha */ + JCS_EXT_ABGR, /* alpha/blue/green/red */ + JCS_EXT_ARGB, /* alpha/red/green/blue */ + JCS_RGB565 /* 5-bit red/6-bit green/5-bit blue */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + +#if JPEG_LIB_VERSION >= 70 + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + JDIMENSION jpeg_width; /* scaled JPEG image width */ + JDIMENSION jpeg_height; /* scaled JPEG image height */ + /* Dimensions of actual JPEG image that will be written to file, + * derived from input dimensions by scaling factors above. + * These fields are computed by jpeg_start_compress(). + * You can also use jpeg_calc_jpeg_dimensions() to determine these values + * in advance of calling jpeg_start_compress(). + */ +#endif + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; +#if JPEG_LIB_VERSION >= 70 + int q_scale_factor[NUM_QUANT_TBLS]; +#endif + /* ptrs to coefficient quantization tables, or NULL if not defined, + * and corresponding scale factors (percentage, initialized 100). + */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ +#if JPEG_LIB_VERSION >= 70 + boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */ +#endif + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + +#if JPEG_LIB_VERSION >= 70 + int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ + int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ +#endif + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + +#if JPEG_LIB_VERSION >= 80 + int block_size; /* the basic DCT block size: 1..16 */ + const int * natural_order; /* natural-order position array */ + int lim_Se; /* min( Se, DCTSIZE2-1 ) */ +#endif + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + +#if JPEG_LIB_VERSION >= 80 + boolean is_baseline; /* TRUE if Baseline SOF0 encountered */ +#endif + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + +#if JPEG_LIB_VERSION >= 70 + int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ + int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ +#else + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ +#endif + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_[v_]scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + +#if JPEG_LIB_VERSION >= 80 + /* These fields are derived from Se of first SOS marker. + */ + int block_size; /* the basic DCT block size: 1..16 */ + const int * natural_order; /* natural-order position array for entropy decode */ + int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */ +#endif + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + void (*error_exit) (j_common_ptr cinfo); + /* Conditionally emit a trace or warning message */ + void (*emit_message) (j_common_ptr cinfo, int msg_level); + /* Routine that actually outputs a trace or error message */ + void (*output_message) (j_common_ptr cinfo); + /* Format a message string for the most recent JPEG error or message */ + void (*format_message) (j_common_ptr cinfo, char * buffer); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + void (*reset_error_mgr) (j_common_ptr cinfo); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + void (*progress_monitor) (j_common_ptr cinfo); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + void (*init_destination) (j_compress_ptr cinfo); + boolean (*empty_output_buffer) (j_compress_ptr cinfo); + void (*term_destination) (j_compress_ptr cinfo); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + void (*init_source) (j_decompress_ptr cinfo); + boolean (*fill_input_buffer) (j_decompress_ptr cinfo); + void (*skip_input_data) (j_decompress_ptr cinfo, long num_bytes); + boolean (*resync_to_restart) (j_decompress_ptr cinfo, int desired); + void (*term_source) (j_decompress_ptr cinfo); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + void * (*alloc_small) (j_common_ptr cinfo, int pool_id, size_t sizeofobject); + void * (*alloc_large) (j_common_ptr cinfo, int pool_id, + size_t sizeofobject); + JSAMPARRAY (*alloc_sarray) (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, JDIMENSION numrows); + JBLOCKARRAY (*alloc_barray) (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, JDIMENSION numrows); + jvirt_sarray_ptr (*request_virt_sarray) (j_common_ptr cinfo, int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess); + jvirt_barray_ptr (*request_virt_barray) (j_common_ptr cinfo, int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess); + void (*realize_virt_arrays) (j_common_ptr cinfo); + JSAMPARRAY (*access_virt_sarray) (j_common_ptr cinfo, jvirt_sarray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable); + JBLOCKARRAY (*access_virt_barray) (j_common_ptr cinfo, jvirt_barray_ptr ptr, + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable); + void (*free_pool) (j_common_ptr cinfo, int pool_id); + void (*self_destruct) (j_common_ptr cinfo); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef boolean (*jpeg_marker_parser_method) (j_decompress_ptr cinfo); + + +/* Originally, this macro was used as a way of defining function prototypes + * for both modern compilers as well as older compilers that did not support + * prototype parameters. libjpeg-turbo has never supported these older, + * non-ANSI compilers, but the macro is still included because there is some + * software out there that uses it. + */ + +#define JPP(arglist) arglist + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error (struct jpeg_error_mgr * err); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress (j_compress_ptr cinfo, int version, + size_t structsize); +EXTERN(void) jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, + size_t structsize); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress (j_compress_ptr cinfo); +EXTERN(void) jpeg_destroy_decompress (j_decompress_ptr cinfo); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile); +EXTERN(void) jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile); + +#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) +/* Data source and destination managers: memory buffers. */ +EXTERN(void) jpeg_mem_dest (j_compress_ptr cinfo, unsigned char ** outbuffer, + unsigned long * outsize); +EXTERN(void) jpeg_mem_src (j_decompress_ptr cinfo, unsigned char * inbuffer, + unsigned long insize); +#endif + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults (j_compress_ptr cinfo); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace (j_compress_ptr cinfo, + J_COLOR_SPACE colorspace); +EXTERN(void) jpeg_default_colorspace (j_compress_ptr cinfo); +EXTERN(void) jpeg_set_quality (j_compress_ptr cinfo, int quality, + boolean force_baseline); +EXTERN(void) jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, + boolean force_baseline); +#if JPEG_LIB_VERSION >= 70 +EXTERN(void) jpeg_default_qtables (j_compress_ptr cinfo, + boolean force_baseline); +#endif +EXTERN(void) jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, boolean force_baseline); +EXTERN(int) jpeg_quality_scaling (int quality); +EXTERN(void) jpeg_simple_progression (j_compress_ptr cinfo); +EXTERN(void) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table (j_common_ptr cinfo); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table (j_common_ptr cinfo); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress (j_compress_ptr cinfo, + boolean write_all_tables); +EXTERN(JDIMENSION) jpeg_write_scanlines (j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines); +EXTERN(void) jpeg_finish_compress (j_compress_ptr cinfo); + +#if JPEG_LIB_VERSION >= 70 +/* Precalculate JPEG dimensions for current compression parameters. */ +EXTERN(void) jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo); +#endif + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION num_lines); + +/* Write a special marker. See libjpeg.txt concerning safe usage. */ +EXTERN(void) jpeg_write_marker (j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header (j_compress_ptr cinfo, int marker, + unsigned int datalen); +EXTERN(void) jpeg_write_m_byte (j_compress_ptr cinfo, int val); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables (j_compress_ptr cinfo); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header (j_decompress_ptr cinfo, boolean require_image); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress (j_decompress_ptr cinfo); +EXTERN(JDIMENSION) jpeg_read_scanlines (j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines); +EXTERN(boolean) jpeg_finish_decompress (j_decompress_ptr cinfo); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, + JDIMENSION max_lines); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans (j_decompress_ptr cinfo); +EXTERN(boolean) jpeg_start_output (j_decompress_ptr cinfo, int scan_number); +EXTERN(boolean) jpeg_finish_output (j_decompress_ptr cinfo); +EXTERN(boolean) jpeg_input_complete (j_decompress_ptr cinfo); +EXTERN(void) jpeg_new_colormap (j_decompress_ptr cinfo); +EXTERN(int) jpeg_consume_input (j_decompress_ptr cinfo); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +#if JPEG_LIB_VERSION >= 80 +EXTERN(void) jpeg_core_output_dimensions (j_decompress_ptr cinfo); +#endif +EXTERN(void) jpeg_calc_output_dimensions (j_decompress_ptr cinfo); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor (j_decompress_ptr cinfo, + int marker_code, + jpeg_marker_parser_method routine); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients (j_decompress_ptr cinfo); +EXTERN(void) jpeg_write_coefficients (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays); +EXTERN(void) jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, + j_compress_ptr dstinfo); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress (j_compress_ptr cinfo); +EXTERN(void) jpeg_abort_decompress (j_decompress_ptr cinfo); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort (j_common_ptr cinfo); +EXTERN(void) jpeg_destroy (j_common_ptr cinfo); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#ifdef __cplusplus +#ifndef DONT_USE_EXTERN_C +} +#endif +#endif + +#endif /* JPEGLIB_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/png.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/png.h new file mode 100644 index 00000000..372599bf --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/png.h @@ -0,0 +1,3292 @@ + +/* png.h - header file for PNG reference library + * + * libpng version 1.6.17, March 26, 2015 + * + * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license (See LICENSE, below) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.6.17, March 26, 2015: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 12.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 12.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-7 13 10210 12.so.0.10[.0] + * 1.2.10rc1-2 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.4.0beta1-5 14 10400 14.so.0.0[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.4.0beta7-8 14 10400 14.so.0.0[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.4.0beta9-14 14 10400 14.so.0.0[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.4.0beta15-36 14 10400 14.so.0.0[.0] + * 1.4.0beta37-87 14 10400 14.so.14.0[.0] + * 1.4.0rc01 14 10400 14.so.14.0[.0] + * 1.4.0beta88-109 14 10400 14.so.14.0[.0] + * 1.4.0rc02-08 14 10400 14.so.14.0[.0] + * 1.4.0 14 10400 14.so.14.0[.0] + * 1.4.1beta01-03 14 10401 14.so.14.1[.0] + * 1.4.1rc01 14 10401 14.so.14.1[.0] + * 1.4.1beta04-12 14 10401 14.so.14.1[.0] + * 1.4.1 14 10401 14.so.14.1[.0] + * 1.4.2 14 10402 14.so.14.2[.0] + * 1.4.3 14 10403 14.so.14.3[.0] + * 1.4.4 14 10404 14.so.14.4[.0] + * 1.5.0beta01-58 15 10500 15.so.15.0[.0] + * 1.5.0rc01-07 15 10500 15.so.15.0[.0] + * 1.5.0 15 10500 15.so.15.0[.0] + * 1.5.1beta01-11 15 10501 15.so.15.1[.0] + * 1.5.1rc01-02 15 10501 15.so.15.1[.0] + * 1.5.1 15 10501 15.so.15.1[.0] + * 1.5.2beta01-03 15 10502 15.so.15.2[.0] + * 1.5.2rc01-03 15 10502 15.so.15.2[.0] + * 1.5.2 15 10502 15.so.15.2[.0] + * 1.5.3beta01-10 15 10503 15.so.15.3[.0] + * 1.5.3rc01-02 15 10503 15.so.15.3[.0] + * 1.5.3beta11 15 10503 15.so.15.3[.0] + * 1.5.3 [omitted] + * 1.5.4beta01-08 15 10504 15.so.15.4[.0] + * 1.5.4rc01 15 10504 15.so.15.4[.0] + * 1.5.4 15 10504 15.so.15.4[.0] + * 1.5.5beta01-08 15 10505 15.so.15.5[.0] + * 1.5.5rc01 15 10505 15.so.15.5[.0] + * 1.5.5 15 10505 15.so.15.5[.0] + * 1.5.6beta01-07 15 10506 15.so.15.6[.0] + * 1.5.6rc01-03 15 10506 15.so.15.6[.0] + * 1.5.6 15 10506 15.so.15.6[.0] + * 1.5.7beta01-05 15 10507 15.so.15.7[.0] + * 1.5.7rc01-03 15 10507 15.so.15.7[.0] + * 1.5.7 15 10507 15.so.15.7[.0] + * 1.6.0beta01-40 16 10600 16.so.16.0[.0] + * 1.6.0rc01-08 16 10600 16.so.16.0[.0] + * 1.6.0 16 10600 16.so.16.0[.0] + * 1.6.1beta01-09 16 10601 16.so.16.1[.0] + * 1.6.1rc01 16 10601 16.so.16.1[.0] + * 1.6.1 16 10601 16.so.16.1[.0] + * 1.6.2beta01 16 10602 16.so.16.2[.0] + * 1.6.2rc01-06 16 10602 16.so.16.2[.0] + * 1.6.2 16 10602 16.so.16.2[.0] + * 1.6.3beta01-11 16 10603 16.so.16.3[.0] + * 1.6.3rc01 16 10603 16.so.16.3[.0] + * 1.6.3 16 10603 16.so.16.3[.0] + * 1.6.4beta01-02 16 10604 16.so.16.4[.0] + * 1.6.4rc01 16 10604 16.so.16.4[.0] + * 1.6.4 16 10604 16.so.16.4[.0] + * 1.6.5 16 10605 16.so.16.5[.0] + * 1.6.6 16 10606 16.so.16.6[.0] + * 1.6.7beta01-04 16 10607 16.so.16.7[.0] + * 1.6.7rc01-03 16 10607 16.so.16.7[.0] + * 1.6.7 16 10607 16.so.16.7[.0] + * 1.6.8beta01-02 16 10608 16.so.16.8[.0] + * 1.6.8rc01-02 16 10608 16.so.16.8[.0] + * 1.6.8 16 10608 16.so.16.8[.0] + * 1.6.9beta01-04 16 10609 16.so.16.9[.0] + * 1.6.9rc01-02 16 10609 16.so.16.9[.0] + * 1.6.9 16 10609 16.so.16.9[.0] + * 1.6.10beta01-03 16 10610 16.so.16.10[.0] + * 1.6.10rc01-03 16 10610 16.so.16.10[.0] + * 1.6.10 16 10610 16.so.16.10[.0] + * 1.6.11beta01-06 16 10611 16.so.16.11[.0] + * 1.6.11rc01-02 16 10611 16.so.16.11[.0] + * 1.6.11 16 10611 16.so.16.11[.0] + * 1.6.12rc01-03 16 10612 16.so.16.12[.0] + * 1.6.12 16 10612 16.so.16.12[.0] + * 1.6.13beta01-04 16 10613 16.so.16.13[.0] + * 1.6.13rc01-02 16 10613 16.so.16.13[.0] + * 1.6.13 16 10613 16.so.16.13[.0] + * 1.6.14beta01-07 16 10614 16.so.16.14[.0] + * 1.6.14rc01-02 16 10614 16.so.16.14[.0] + * 1.6.14 16 10614 16.so.16.14[.0] + * 1.6.15beta01-08 16 10615 16.so.16.15[.0] + * 1.6.15rc01-03 16 10615 16.so.16.15[.0] + * 1.6.15 16 10615 16.so.16.15[.0] + * 1.6.16beta01-03 16 10616 16.so.16.16[.0] + * 1.6.16rc01-02 16 10616 16.so.16.16[.0] + * 1.6.16 16 10616 16.so.16.16[.0] + * 1.6.17beta01-06 16 10617 16.so.16.17[.0] + * 1.6.17rc01-06 16 10617 16.so.16.17[.0] + * 1.6.17 16 10617 16.so.16.17[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcNN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng-manual.txt or libpng.3 for more information. The PNG + * specification is available as a W3C Recommendation and as an ISO + * Specification, <http://www.w3.org/TR/2003/REC-PNG-20031110/ + */ + +/* + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * + * If you modify libpng you may insert additional notices immediately following + * this sentence. + * + * This code is released under the libpng license. + * + * libpng versions 1.2.6, August 15, 2004, through 1.6.17, March 26, 2015, are + * Copyright (c) 2004, 2006-2015 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.2.5 + * with the following individual added to the list of Contributing Authors: + * + * Cosmin Truta + * + * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are + * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.0.6 + * with the following individuals added to the list of Contributing Authors: + * + * Simon-Pierre Cadieux + * Eric S. Raymond + * Gilles Vollant + * + * and with the following additions to the disclaimer: + * + * There is no warranty against interference with your enjoyment of the + * library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is with + * the user. + * + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are + * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-0.96, + * with the following individuals added to the list of Contributing Authors: + * + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik + * + * libpng versions 0.89, June 1996, through 0.96, May 1997, are + * Copyright (c) 1996, 1997 Andreas Dilger + * Distributed according to the same disclaimer and license as libpng-0.88, + * with the following individuals added to the list of Contributing Authors: + * + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner + * + * libpng versions 0.5, May 1995, through 0.88, January 1996, are + * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + * + * For the purposes of this copyright and license, "Contributing Authors" + * is defined as the following set of individuals: + * + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner + * + * The PNG Reference Library is supplied "AS IS". The Contributing Authors + * and Group 42, Inc. disclaim all warranties, expressed or implied, + * including, without limitation, the warranties of merchantability and of + * fitness for any purpose. The Contributing Authors and Group 42, Inc. + * assume no liability for direct, indirect, incidental, special, exemplary, + * or consequential damages, which may result from the use of the PNG + * Reference Library, even if advised of the possibility of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject + * to the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. + * + * 2. Altered versions must be plainly marked as such and must not + * be misrepresented as being the original source. + * + * 3. This Copyright notice may not be removed or altered from + * any source or altered source distribution. + * + * The Contributing Authors and Group 42, Inc. specifically permit, without + * fee, and encourage the use of this source code as a component to + * supporting the PNG file format in commercial products. If you use this + * source code in a product, acknowledgment is not required but would be + * appreciated. + */ + +/* + * A "png_get_copyright" function is available, for convenient use in "about" + * boxes and the like: + * + * printf("%s", png_get_copyright(NULL)); + * + * Also, the PNG logo (in PNG format, of course) is supplied in the + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + */ + +/* + * Libpng is OSI Certified Open Source Software. OSI Certified is a + * certification mark of the Open Source Initiative. + */ + +/* + * The contributing authors would like to thank all those who helped + * with testing, bug fixes, and patience. This wouldn't have been + * possible without all of you. + * + * Thanks to Frank J. T. Wojcik for helping with the documentation. + */ + +/* + * Y2K compliance in libpng: + * ========================= + * + * March 26, 2015 + * + * Since the PNG Development group is an ad-hoc body, we can't make + * an official declaration. + * + * This is your unofficial assurance that libpng from version 0.71 and + * upward through 1.6.17 are Y2K compliant. It is my belief that + * earlier versions were also Y2K compliant. + * + * Libpng only has two year fields. One is a 2-byte unsigned integer + * that will hold years up to 65535. The other, which is deprecated, + * holds the date in text format, and will hold years up to 9999. + * + * The integer is + * "png_uint_16 year" in png_time_struct. + * + * The string is + * "char time_buffer[29]" in png_struct. This is no longer used + * in libpng-1.6.x and will be removed from libpng-1.7.0. + * + * There are seven time-related functions: + * png.c: png_convert_to_rfc_1123_buffer() in png.c + * (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and + * png_convert_to_rfc_1152() in error prior to libpng-0.98) + * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c + * png_convert_from_time_t() in pngwrite.c + * png_get_tIME() in pngget.c + * png_handle_tIME() in pngrutil.c, called in pngread.c + * png_set_tIME() in pngset.c + * png_write_tIME() in pngwutil.c, called in pngwrite.c + * + * All handle dates properly in a Y2K environment. The + * png_convert_from_time_t() function calls gmtime() to convert from system + * clock time, which returns (year - 1900), which we properly convert to + * the full 4-digit year. There is a possibility that libpng applications + * are not passing 4-digit years into the png_convert_to_rfc_1123_buffer() + * function, or that they are incorrectly passing only a 2-digit year + * instead of "year - 1900" into the png_convert_from_struct_tm() function, + * but this is not under our control. The libpng documentation has always + * stated that it works with 4-digit years, and the APIs have been + * documented as such. + * + * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned + * integer to hold the year, and can hold years as large as 65535. + * + * zlib, upon which libpng depends, is also Y2K compliant. It contains + * no date-related code. + * + * Glenn Randers-Pehrson + * libpng maintainer + * PNG Development Group + */ + +#ifndef PNG_H +#define PNG_H + +/* This is not the place to learn how to use libpng. The file libpng-manual.txt + * describes how to use libpng, and the file example.c summarizes it + * with some code on which to build. This file is useful for looking + * at the actual function definitions and structure components. If that + * file has been stripped from your copy of libpng, you can find it at + * <http://www.libpng.org/pub/png/libpng-manual.txt> + * + * If you just need to read a PNG file and don't want to read the documentation + * skip to the end of this file and read the section entitled 'simplified API'. + */ + +/* Version information for png.h - this should match the version in png.c */ +#define PNG_LIBPNG_VER_STRING "1.6.17" +#define PNG_HEADER_VERSION_STRING \ + " libpng version 1.6.17 - March 26, 2015\n" + +#define PNG_LIBPNG_VER_SONUM 16 +#define PNG_LIBPNG_VER_DLLNUM 16 + +/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ +#define PNG_LIBPNG_VER_MAJOR 1 +#define PNG_LIBPNG_VER_MINOR 6 +#define PNG_LIBPNG_VER_RELEASE 17 + +/* This should match the numeric part of the final component of + * PNG_LIBPNG_VER_STRING, omitting any leading zero: + */ + +#define PNG_LIBPNG_VER_BUILD 0 + +/* Release Status */ +#define PNG_LIBPNG_BUILD_ALPHA 1 +#define PNG_LIBPNG_BUILD_BETA 2 +#define PNG_LIBPNG_BUILD_RC 3 +#define PNG_LIBPNG_BUILD_STABLE 4 +#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 + +/* Release-Specific Flags */ +#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with + PNG_LIBPNG_BUILD_STABLE only */ +#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_SPECIAL */ +#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_PRIVATE */ + +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE + +/* Careful here. At one time, Guy wanted to use 082, but that would be octal. + * We must not include leading zeros. + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only + * version 1.0.0 was mis-numbered 100 instead of 10000). From + * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release + */ +#define PNG_LIBPNG_VER 10617 /* 1.6.17 */ + +/* Library configuration: these options cannot be changed after + * the library has been built. + */ +#ifndef PNGLCONF_H + /* If pnglibconf.h is missing, you can + * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h + */ +# include "pnglibconf.h" +#endif + +#ifndef PNG_VERSION_INFO_ONLY + /* Machine specific configuration. */ +# include "pngconf.h" +#endif + +/* + * Added at libpng-1.2.8 + * + * Ref MSDN: Private as priority over Special + * VS_FF_PRIVATEBUILD File *was not* built using standard release + * procedures. If this value is given, the StringFileInfo block must + * contain a PrivateBuild string. + * + * VS_FF_SPECIALBUILD File *was* built by the original company using + * standard release procedures but is a variation of the standard + * file of the same version number. If this value is given, the + * StringFileInfo block must contain a SpecialBuild string. + */ + +#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) +#else +# ifdef PNG_LIBPNG_SPECIALBUILD +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) +# else +# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) +# endif +#endif + +#ifndef PNG_VERSION_INFO_ONLY + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Version information for C files, stored in png.c. This had better match + * the version above. + */ +#define png_libpng_ver png_get_header_ver(NULL) + +/* This file is arranged in several sections: + * + * 1. Any configuration options that can be specified by for the application + * code when it is built. (Build time configuration is in pnglibconf.h) + * 2. Type definitions (base types are defined in pngconf.h), structure + * definitions. + * 3. Exported library functions. + * 4. Simplified API. + * + * The library source code has additional files (principally pngpriv.h) that + * allow configuration of the library. + */ +/* Section 1: run time configuration + * See pnglibconf.h for build time configuration + * + * Run time configuration allows the application to choose between + * implementations of certain arithmetic APIs. The default is set + * at build time and recorded in pnglibconf.h, but it is safe to + * override these (and only these) settings. Note that this won't + * change what the library does, only application code, and the + * settings can (and probably should) be made on a per-file basis + * by setting the #defines before including png.h + * + * Use macros to read integers from PNG data or use the exported + * functions? + * PNG_USE_READ_MACROS: use the macros (see below) Note that + * the macros evaluate their argument multiple times. + * PNG_NO_USE_READ_MACROS: call the relevant library function. + * + * Use the alternative algorithm for compositing alpha samples that + * does not use division? + * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' + * algorithm. + * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. + * + * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is + * false? + * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error + * APIs to png_warning. + * Otherwise the calls are mapped to png_error. + */ + +/* Section 2: type definitions, including structures and compile time + * constants. + * See pngconf.h for base types that vary by machine/system + */ + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef char* png_libpng_version_1_6_17; + +/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. + * + * png_struct is the cache of information used while reading or writing a single + * PNG file. One of these is always required, although the simplified API + * (below) hides the creation and destruction of it. + */ +typedef struct png_struct_def png_struct; +typedef const png_struct * png_const_structp; +typedef png_struct * png_structp; +typedef png_struct * * png_structpp; + +/* png_info contains information read from or to be written to a PNG file. One + * or more of these must exist while reading or creating a PNG file. The + * information is not used by libpng during read but is used to control what + * gets written when a PNG file is created. "png_get_" function calls read + * information during read and "png_set_" functions calls write information + * when creating a PNG. + * been moved into a separate header file that is not accessible to + * applications. Read libpng-manual.txt or libpng.3 for more info. + */ +typedef struct png_info_def png_info; +typedef png_info * png_infop; +typedef const png_info * png_const_infop; +typedef png_info * * png_infopp; + +/* Types with names ending 'p' are pointer types. The corresponding types with + * names ending 'rp' are identical pointer types except that the pointer is + * marked 'restrict', which means that it is the only pointer to the object + * passed to the function. Applications should not use the 'restrict' types; + * it is always valid to pass 'p' to a pointer with a function argument of the + * corresponding 'rp' type. Different compilers have different rules with + * regard to type matching in the presence of 'restrict'. For backward + * compatibility libpng callbacks never have 'restrict' in their parameters and, + * consequentially, writing portable application code is extremely difficult if + * an attempt is made to use 'restrict'. + */ +typedef png_struct * PNG_RESTRICT png_structrp; +typedef const png_struct * PNG_RESTRICT png_const_structrp; +typedef png_info * PNG_RESTRICT png_inforp; +typedef const png_info * PNG_RESTRICT png_const_inforp; + +/* Three color definitions. The order of the red, green, and blue, (and the + * exact size) is not important, although the size of the fields need to + * be png_byte or png_uint_16 (as defined below). + */ +typedef struct png_color_struct +{ + png_byte red; + png_byte green; + png_byte blue; +} png_color; +typedef png_color * png_colorp; +typedef const png_color * png_const_colorp; +typedef png_color * * png_colorpp; + +typedef struct png_color_16_struct +{ + png_byte index; /* used for palette files */ + png_uint_16 red; /* for use in red green blue files */ + png_uint_16 green; + png_uint_16 blue; + png_uint_16 gray; /* for use in grayscale files */ +} png_color_16; +typedef png_color_16 * png_color_16p; +typedef const png_color_16 * png_const_color_16p; +typedef png_color_16 * * png_color_16pp; + +typedef struct png_color_8_struct +{ + png_byte red; /* for use in red green blue files */ + png_byte green; + png_byte blue; + png_byte gray; /* for use in grayscale files */ + png_byte alpha; /* for alpha channel files */ +} png_color_8; +typedef png_color_8 * png_color_8p; +typedef const png_color_8 * png_const_color_8p; +typedef png_color_8 * * png_color_8pp; + +/* + * The following two structures are used for the in-core representation + * of sPLT chunks. + */ +typedef struct png_sPLT_entry_struct +{ + png_uint_16 red; + png_uint_16 green; + png_uint_16 blue; + png_uint_16 alpha; + png_uint_16 frequency; +} png_sPLT_entry; +typedef png_sPLT_entry * png_sPLT_entryp; +typedef const png_sPLT_entry * png_const_sPLT_entryp; +typedef png_sPLT_entry * * png_sPLT_entrypp; + +/* When the depth of the sPLT palette is 8 bits, the color and alpha samples + * occupy the LSB of their respective members, and the MSB of each member + * is zero-filled. The frequency member always occupies the full 16 bits. + */ + +typedef struct png_sPLT_struct +{ + png_charp name; /* palette name */ + png_byte depth; /* depth of palette samples */ + png_sPLT_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ +} png_sPLT_t; +typedef png_sPLT_t * png_sPLT_tp; +typedef const png_sPLT_t * png_const_sPLT_tp; +typedef png_sPLT_t * * png_sPLT_tpp; + +#ifdef PNG_TEXT_SUPPORTED +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, + * and whether that contents is compressed or not. The "key" field + * points to a regular zero-terminated C string. The "text" fields can be a + * regular C string, an empty string, or a NULL pointer. + * However, the structure returned by png_get_text() will always contain + * the "text" field as a regular zero-terminated C string (possibly + * empty), never a NULL pointer, so it can be safely used in printf() and + * other string-handling functions. Note that the "itxt_length", "lang", and + * "lang_key" members of the structure only exist when the library is built + * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by + * default without iTXt support. Also note that when iTXt *is* supported, + * the "lang" and "lang_key" fields contain NULL pointers when the + * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or + * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the + * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" + * which is always 0 or 1, or its "compression method" which is always 0. + */ +typedef struct png_text_struct +{ + int compression; /* compression value: + -1: tEXt, none + 0: zTXt, deflate + 1: iTXt, none + 2: iTXt, deflate */ + png_charp key; /* keyword, 1-79 character description of "text" */ + png_charp text; /* comment, may be an empty string (ie "") + or a NULL pointer */ + png_size_t text_length; /* length of the text string */ + png_size_t itxt_length; /* length of the itxt string */ + png_charp lang; /* language code, 0-79 characters + or a NULL pointer */ + png_charp lang_key; /* keyword translated UTF-8 string, 0 or more + chars or a NULL pointer */ +} png_text; +typedef png_text * png_textp; +typedef const png_text * png_const_textp; +typedef png_text * * png_textpp; +#endif + +/* Supported compression types for text in PNG files (tEXt, and zTXt). + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ +#define PNG_TEXT_COMPRESSION_NONE_WR -3 +#define PNG_TEXT_COMPRESSION_zTXt_WR -2 +#define PNG_TEXT_COMPRESSION_NONE -1 +#define PNG_TEXT_COMPRESSION_zTXt 0 +#define PNG_ITXT_COMPRESSION_NONE 1 +#define PNG_ITXT_COMPRESSION_zTXt 2 +#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ + +/* png_time is a way to hold the time in an machine independent way. + * Two conversions are provided, both from time_t and struct tm. There + * is no portable way to convert to either of these structures, as far + * as I know. If you know of a portable way, send it to me. As a side + * note - PNG has always been Year 2000 compliant! + */ +typedef struct png_time_struct +{ + png_uint_16 year; /* full year, as in, 1995 */ + png_byte month; /* month of year, 1 - 12 */ + png_byte day; /* day of month, 1 - 31 */ + png_byte hour; /* hour of day, 0 - 23 */ + png_byte minute; /* minute of hour, 0 - 59 */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ +} png_time; +typedef png_time * png_timep; +typedef const png_time * png_const_timep; +typedef png_time * * png_timepp; + +#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ + defined(PNG_USER_CHUNKS_SUPPORTED) +/* png_unknown_chunk is a structure to hold queued chunks for which there is + * no specific support. The idea is that we can use this to queue + * up private chunks for output even though the library doesn't actually + * know about their semantics. + * + * The data in the structure is set by libpng on read and used on write. + */ +typedef struct png_unknown_chunk_t +{ + png_byte name[5]; /* Textual chunk name with '\0' terminator */ + png_byte *data; /* Data, should not be modified on read! */ + png_size_t size; + + /* On write 'location' must be set using the flag values listed below. + * Notice that on read it is set by libpng however the values stored have + * more bits set than are listed below. Always treat the value as a + * bitmask. On write set only one bit - setting multiple bits may cause the + * chunk to be written in multiple places. + */ + png_byte location; /* mode of operation at read time */ +} +png_unknown_chunk; + +typedef png_unknown_chunk * png_unknown_chunkp; +typedef const png_unknown_chunk * png_const_unknown_chunkp; +typedef png_unknown_chunk * * png_unknown_chunkpp; +#endif + +/* Flag values for the unknown chunk location byte. */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_AFTER_IDAT 0x08 + +/* Maximum positive integer used in PNG is (2^31)-1 */ +#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) +#define PNG_UINT_32_MAX ((png_uint_32)(-1)) +#define PNG_SIZE_MAX ((png_size_t)(-1)) + +/* These are constants for fixed point values encoded in the + * PNG specification manner (x100000) + */ +#define PNG_FP_1 100000 +#define PNG_FP_HALF 50000 +#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) +#define PNG_FP_MIN (-PNG_FP_MAX) + +/* These describe the color_type field in png_info. */ +/* color type masks */ +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +/* color types. Note that not all combinations are legal */ +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) +/* aliases */ +#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA +#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA + +/* This is for compression type. PNG 1.0-1.2 only define the single type. */ +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE + +/* This is for filter type. PNG 1.0-1.2 only define the single type. */ +#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ +#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE + +/* These are for the interlacing type. These values should NOT be changed. */ +#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ +#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ +#define PNG_INTERLACE_LAST 2 /* Not a valid value */ + +/* These are for the oFFs chunk. These values should NOT be changed. */ +#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ +#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ +#define PNG_OFFSET_LAST 2 /* Not a valid value */ + +/* These are for the pCAL chunk. These values should NOT be changed. */ +#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ +#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ +#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ +#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ +#define PNG_EQUATION_LAST 4 /* Not a valid value */ + +/* These are for the sCAL chunk. These values should NOT be changed. */ +#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ +#define PNG_SCALE_METER 1 /* meters per pixel */ +#define PNG_SCALE_RADIAN 2 /* radians per pixel */ +#define PNG_SCALE_LAST 3 /* Not a valid value */ + +/* These are for the pHYs chunk. These values should NOT be changed. */ +#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ +#define PNG_RESOLUTION_METER 1 /* pixels/meter */ +#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ + +/* These are for the sRGB chunk. These values should NOT be changed. */ +#define PNG_sRGB_INTENT_PERCEPTUAL 0 +#define PNG_sRGB_INTENT_RELATIVE 1 +#define PNG_sRGB_INTENT_SATURATION 2 +#define PNG_sRGB_INTENT_ABSOLUTE 3 +#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ + +/* This is for text chunks */ +#define PNG_KEYWORD_MAX_LENGTH 79 + +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ +#define PNG_MAX_PALETTE_LENGTH 256 + +/* These determine if an ancillary chunk's data has been successfully read + * from the PNG header, or if the application has filled in the corresponding + * data in the info_struct to be written into the output file. The values + * of the PNG_INFO_<chunk> defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_size_t rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info * png_row_infop; +typedef png_row_info * * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. Note that the 'write' function must not + * modify the buffer it is passed. The 'read' function, on the other hand, is + * expected to return the read data in the buffer. + */ +typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); +typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t)); +typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); +typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, + int)); +typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); +typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); + +/* The following callback receives png_uint_32 row_number, int pass for the + * png_bytep data of the row. When transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, + png_bytep)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, + png_unknown_chunkp)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +/* not used anywhere */ +/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This must match the function definition in <setjmp.h>, and the application + * must include this before png.h to obtain the definition of jmp_buf. The + * function is required to be PNG_NORETURN, but this is not checked. If the + * function does return the application will crash via an abort() or similar + * system level call. + * + * If you get a warning here while building the library you may need to make + * changes to ensure that pnglibconf.h records the calling convention used by + * your compiler. This may be very difficult - try using a different compiler + * to build the library! + */ +PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ +/* Added to libpng-1.2.34 */ +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ +/* Added to libpng-1.4.0 */ +#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ +/* Added to libpng-1.5.4 */ +#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ +#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +/* NOTE: prior to 1.5 these functions had no 'API' style declaration, + * this allowed the zlib default functions to be used on Windows + * platforms. In 1.5 the zlib default malloc (which just calls malloc and + * ignores the first argument) should be completely compatible with the + * following. + */ +typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, + png_alloc_size_t)); +typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); + +/* Section 3: exported functions + * Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng-manual.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + * + * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in + * pngconf.h and in the *.dfn files in the scripts directory. + * + * PNG_EXPORT(ordinal, type, name, (args)); + * + * ordinal: ordinal that is used while building + * *.def files. The ordinal value is only + * relevant when preprocessing png.h with + * the *.dfn files for building symbol table + * entries, and are removed by pngconf.h. + * type: return type of the function + * name: function name + * args: function arguments, with types + * + * When we wish to append attributes to a function prototype we use + * the PNG_EXPORTA() macro instead. + * + * PNG_EXPORTA(ordinal, type, name, (args), attributes); + * + * ordinal, type, name, and args: same as in PNG_EXPORT(). + * attributes: function attributes + */ + +/* Returns the version number of the library */ +PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); + +/* Tell lib we have already handled the first <num_bytes> magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +PNG_EXPORTA(4, png_structp, png_create_read_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +PNG_EXPORTA(5, png_structp, png_create_write_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn), + PNG_ALLOCATED); + +PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, + (png_const_structrp png_ptr)); + +PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, + png_size_t size)); + +/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp + * match up. + */ +#ifdef PNG_SETJMP_SUPPORTED +/* This function returns the jmp_buf built in to *png_ptr. It must be + * supplied with an appropriate 'longjmp' function to use on that jmp_buf + * unless the default error function is overridden in which case NULL is + * acceptable. The size of the jmp_buf is checked against the actual size + * allocated by the library - the call will return NULL on a mismatch + * indicating an ABI mismatch. + */ +PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr, + png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); +# define png_jmpbuf(png_ptr) \ + (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) +#endif +/* This function should be used by libpng applications in place of + * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it + * will use it; otherwise it will call PNG_ABORT(). This function was + * added in libpng-1.5.0. + */ +PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), + PNG_NORETURN); + +#ifdef PNG_READ_SUPPORTED +/* Reset the compression stream */ +PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED); +#endif + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(11, png_structp, png_create_read_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +PNG_EXPORTA(12, png_structp, png_create_write_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +#endif + +/* Write the PNG file signature. */ +PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep + chunk_name, png_const_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, + png_const_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, + png_const_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); + +/* Allocate and initialize the info structure */ +PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), + PNG_ALLOCATED); + +/* DEPRECATED: this function allowed init structures to be created using the + * default allocation method (typically malloc). Use is deprecated in 1.6.0 and + * the API will be removed in the future. + */ +PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, + png_size_t png_info_struct_size), PNG_DEPRECATED); + +/* Writes all the PNG information before the image. */ +PNG_EXPORT(20, void, png_write_info_before_PLTE, + (png_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(21, void, png_write_info, + (png_structrp png_ptr, png_const_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. */ +PNG_EXPORT(22, void, png_read_info, + (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED + /* Convert to a US string format: there is no localization support in this + * routine. The original implementation used a 29 character buffer in + * png_struct, this will be removed in future versions. + */ +#if PNG_LIBPNG_VER < 10700 +/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ +PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, + png_const_timep ptime),PNG_DEPRECATED); +#endif +PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], + png_const_timep ptime)); +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* Convert from a struct tm to png_time */ +PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, + const struct tm * ttime)); + +/* Convert from time_t to png_time. Uses gmtime() */ +PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime)); +#endif /* CONVERT_tIME */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr)); +PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); +PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); +PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion + * of a tRNS chunk if present. + */ +PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand the grayscale to 24-bit RGB if necessary. */ +PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB to grayscale. */ +#define PNG_ERROR_ACTION_NONE 1 +#define PNG_ERROR_ACTION_WARN 2 +#define PNG_ERROR_ACTION_ERROR 3 +#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ + +PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr, + int error_action, double red, double green)) +PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green)) + +PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp + png_ptr)); +#endif + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, + png_colorp palette)); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* How the alpha channel is interpreted - this affects how the color channels + * of a PNG file are returned to the calling application when an alpha channel, + * or a tRNS chunk in a palette file, is present. + * + * This has no effect on the way pixels are written into a PNG output + * datastream. The color samples in a PNG datastream are never premultiplied + * with the alpha samples. + * + * The default is to return data according to the PNG specification: the alpha + * channel is a linear measure of the contribution of the pixel to the + * corresponding composited pixel, and the color channels are unassociated + * (not premultiplied). The gamma encoded color channels must be scaled + * according to the contribution and to do this it is necessary to undo + * the encoding, scale the color values, perform the composition and reencode + * the values. This is the 'PNG' mode. + * + * The alternative is to 'associate' the alpha with the color information by + * storing color channel values that have been scaled by the alpha. + * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes + * (the latter being the two common names for associated alpha color channels). + * + * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha + * value is equal to the maximum value. + * + * The final choice is to gamma encode the alpha channel as well. This is + * broken because, in practice, no implementation that uses this choice + * correctly undoes the encoding before handling alpha composition. Use this + * choice only if other serious errors in the software or hardware you use + * mandate it; the typical serious error is for dark halos to appear around + * opaque areas of the composited PNG image because of arithmetic overflow. + * + * The API function png_set_alpha_mode specifies which of these choices to use + * with an enumerated 'mode' value and the gamma of the required output: + */ +#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ +#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ +#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ +#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ +#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ +#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode, + double output_gamma)) +PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, + int mode, png_fixed_point output_gamma)) +#endif + +#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) +/* The output_gamma value is a screen gamma in libpng terminology: it expresses + * how to decode the output values, not how they are encoded. + */ +#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ +#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ +#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ +#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ +#endif + +/* The following are examples of calls to png_set_alpha_mode to achieve the + * required overall gamma correction and, where necessary, alpha + * premultiplication. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * This is the default libpng handling of the alpha channel - it is not + * pre-multiplied into the color components. In addition the call states + * that the output is for a sRGB system and causes all PNG files without gAMA + * chunks to be assumed to be encoded using sRGB. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * In this case the output is assumed to be something like an sRGB conformant + * display preceeded by a power-law lookup table of power 1.45. This is how + * early Mac systems behaved. + * + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); + * This is the classic Jim Blinn approach and will work in academic + * environments where everything is done by the book. It has the shortcoming + * of assuming that input PNG data with no gamma information is linear - this + * is unlikely to be correct unless the PNG files where generated locally. + * Most of the time the output precision will be so low as to show + * significant banding in dark areas of the image. + * + * png_set_expand_16(pp); + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); + * This is a somewhat more realistic Jim Blinn inspired approach. PNG files + * are assumed to have the sRGB encoding if not marked with a gamma value and + * the output is always 16 bits per component. This permits accurate scaling + * and processing of the data. If you know that your input PNG files were + * generated locally you might need to replace PNG_DEFAULT_sRGB with the + * correct value for your system. + * + * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); + * If you just need to composite the PNG image onto an existing background + * and if you control the code that does this you can use the optimization + * setting. In this case you just copy completely opaque pixels to the + * output. For pixels that are not completely transparent (you just skip + * those) you do the composition math using png_composite or png_composite_16 + * below then encode the resultant 8-bit or 16-bit values to match the output + * encoding. + * + * Other cases + * If neither the PNG nor the standard linear encoding work for you because + * of the software or hardware you use then you have a big problem. The PNG + * case will probably result in halos around the image. The linear encoding + * will probably result in a washed out, too bright, image (it's actually too + * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably + * substantially reduce the halos. Alternatively try: + * + * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); + * This option will also reduce the halos, but there will be slight dark + * halos round the opaque parts of the image where the background is light. + * In the OPTIMIZED mode the halos will be light halos where the background + * is dark. Take your pick - the halos are unavoidable unless you can get + * your hardware/software fixed! (The OPTIMIZED approach is slightly + * faster.) + * + * When the default gamma of PNG files doesn't match the output gamma. + * If you have PNG files with no gamma information png_set_alpha_mode allows + * you to provide a default gamma, but it also sets the ouput gamma to the + * matching value. If you know your PNG files have a gamma that doesn't + * match the output you can take advantage of the fact that + * png_set_alpha_mode always sets the output gamma but only sets the PNG + * default if it is not already set: + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * The first call sets both the default and the output gamma values, the + * second call overrides the output gamma without changing the default. This + * is easier than achieving the same effect with png_set_gamma. You must use + * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will + * fire if more than one call to png_set_alpha_mode and png_set_background is + * made in the same read operation, however multiple calls with PNG_ALPHA_PNG + * are ignored. + */ + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, + int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +# define PNG_FILLER_BEFORE 0 +# define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, + png_uint_32 filler, int flags)); +#endif /* READ_FILLER || WRITE_FILLER */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p + true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. + * MUST be called before png_read_update_info or png_start_read_image, + * otherwise it will not have the desired effect. Note that it is still + * necessary to call png_read_row or png_read_rows png_get_image_height + * times for each pass. +*/ +PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS by replacing with a background color. Prior to + * libpng-1.5.4 this API must not be called before the PNG file header has been + * read. Doing so will result in unexpected behavior and possible warnings or + * errors if the PNG file contains a bKGD chunk. + */ +PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)) +PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma)) +#endif +#ifdef PNG_READ_BACKGROUND_SUPPORTED +# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +# define PNG_BACKGROUND_GAMMA_SCREEN 1 +# define PNG_BACKGROUND_GAMMA_FILE 2 +# define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale a 16-bit depth file down to 8-bit, accurately. */ +PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ +/* Strip the second byte of information from a 16-bit depth file. */ +PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* Turn on quantizing, and reduce the palette to the number of colors + * available. + */ +PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_const_uint_16p histogram, int full_quantize)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* The threshold on gamma processing is configurable but hard-wired into the + * library. The following is the floating point variant. + */ +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) + +/* Handle gamma correction. Screen_gamma=(display_exponent). + * NOTE: this API simply sets the screen and file gamma values. It will + * therefore override the value for gamma in a PNG file if it is called after + * the file header has been read - use with care - call before reading the PNG + * file for best results! + * + * These routines accept the same gamma values as png_set_alpha_mode (described + * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either + * API (floating point or fixed.) Notice, however, that the 'file_gamma' value + * is the inverse of a 'screen gamma' value. + */ +PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr, + double screen_gamma, double override_file_gamma)) +PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr, + png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set how many lines between output flushes - 0 for no flushing */ +PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); +#endif + +/* Optional update palette with requested transformations */ +PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); + +/* Optional call to update the users info structure */ +PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, + png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. */ +PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read a row of data. */ +PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row, + png_bytep display_row)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the whole image into memory at once. */ +PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image)); +#endif + +/* Write a row of image data */ +PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr, + png_const_bytep row)); + +/* Write a few rows of image data: (*row) is not written; however, the type + * is declared as writeable to maintain compatibility with previous versions + * of libpng and to allow the 'display_row' array from read_rows to be passed + * unchanged to write_rows. + */ +PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row, + png_uint_32 num_rows)); + +/* Write the image data */ +PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); + +/* Write the end of the PNG file. */ +PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, + png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. */ +PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +/* Free any memory associated with the png_info_struct */ +PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr, + png_infopp info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr)); + +/* Set the libpng method of handling chunk CRC errors */ +PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action, + int ancil_action)); + +/* Values for png_set_crc_action() say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +#ifdef PNG_WRITE_SUPPORTED +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* Set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, + int filters)); +#endif /* WRITE */ + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#ifdef PNG_WRITE_SUPPORTED +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, + int heuristic_method, int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs)) +PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, + (png_structrp png_ptr, int heuristic_method, int num_weights, + png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs)) +#endif /* WRITE_WEIGHTED_FILTER */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED +PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr, + int level)); + +PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr, + int window_bits)); + +PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr, + int method)); +#endif /* WRITE_CUSTOMIZE_COMPRESSION */ + +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +/* Also set zlib parameters for compressing non-IDAT chunks */ +PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr, + int level)); + +PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(225, void, png_set_text_compression_window_bits, + (png_structrp png_ptr, int window_bits)); + +PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr, + int method)); +#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ +#endif /* WRITE */ + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng-manual.txt for + * more information. + */ + +#ifdef PNG_STDIO_SUPPORTED +/* Initialize the input/output for the PNG file to the default functions. */ +PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + * It is probably a mistake to use NULL for output_flush_fn if + * write_data_fn is not also NULL unless you have built libpng with + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's + * default flush function, which uses the standard *FILE structure, will + * be used. + */ +PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); + +PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, + png_read_status_ptr read_row_fn)); + +PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr, + png_user_transform_ptr read_user_transform_fn)); +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr, + png_user_transform_ptr write_user_transform_fn)); +#endif + +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr, + png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, + (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +/* Return information about the row currently being processed. Note that these + * APIs do not fail but will return unexpected results if called outside a user + * transform callback. Also note that when transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp)); +PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +/* This callback is called only for *unknown* chunks. If + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known + * chunks to be treated as unknown, however in this case the callback must do + * any processing required by the chunk (e.g. by calling the appropriate + * png_set_ APIs.) + * + * There is no write support - on write, by default, all the chunks in the + * 'unknown' list are written in the specified position. + * + * The integer return from the callback function is interpreted thus: + * + * negative: An error occurred; png_chunk_error will be called. + * zero: The chunk was not handled, the chunk will be saved. A critical + * chunk will cause an error at this point unless it is to be saved. + * positive: The chunk was handled, libpng will ignore/discard it. + * + * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about + * how this behavior will change in libpng 1.7 + */ +PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr, + png_voidp progressive_ptr, png_progressive_info_ptr info_fn, + png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); + +/* Returns the user pointer associated with the push read functions */ +PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, + (png_const_structrp png_ptr)); + +/* Function to be called when data becomes available */ +PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, + png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* A function which may be called *only* within png_process_data to stop the + * processing of any more data. The function returns the number of bytes + * remaining, excluding any that libpng has cached internally. A subsequent + * call to png_process_data must supply these bytes again. If the argument + * 'save' is set to true the routine will first save all the pending data and + * will always return 0. + */ +PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save)); + +/* A function which may be called *only* outside (after) a call to + * png_process_data. It returns the number of bytes of data to skip in the + * input. Normally it will return 0, but if it returns a non-zero value the + * application must skip than number of bytes of input data and pass the + * following data to the next call to png_process_data. + */ +PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp)); + +/* Function that combines rows. 'new_row' is a flag that should come from + * the callback and be non-NULL if anything needs to be done; the library + * stores its own version of the new data internally and ignores the passed + * in value. + */ +PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr, + png_bytep old_row, png_const_bytep new_row)); +#endif /* PROGRESSIVE_READ */ + +PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); +/* Added at libpng version 1.4.0 */ +PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Added at libpng version 1.2.4 */ +PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Frees a pointer allocated by png_malloc() */ +PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); + +/* Free data that was allocated internally */ +PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 free_me, int num)); + +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application; this works on the png_info structure passed + * in, it does not change the state for other png_info structures. + * + * It is unlikely that this function works correctly as of 1.6.0 and using it + * may result either in memory leaks or double free of allocated data. + */ +PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, + png_inforp info_ptr, int freer, png_uint_32 mask)); + +/* Assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_FREE_UNKN 0x0200 +#endif +/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */ +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED); +PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr, + png_voidp ptr), PNG_DEPRECATED); +#endif + +#ifdef PNG_ERROR_TEXT_SUPPORTED +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr, + png_const_charp error_message), PNG_NORETURN); + +/* The same, but the chunk name is prepended to the error string. */ +PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr, + png_const_charp error_message), PNG_NORETURN); + +#else +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN); +# define png_error(s1,s2) png_err(s1) +# define png_chunk_error(s1,s2) png_err(s1) +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr, + png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr, + png_const_charp warning_message)); +#else +# define png_warning(s1,s2) ((void)(s1)) +# define png_chunk_warning(s1,s2) ((void)(s1)) +#endif + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +/* Benign error in libpng. Can continue, but may have a problem. + * User can choose whether to handle as a fatal error or as a warning. */ +PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); + +#ifdef PNG_READ_SUPPORTED +/* Same, chunk name is prepended to message (only during read) */ +PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); +#endif + +PNG_EXPORT(109, void, png_set_benign_errors, + (png_structrp png_ptr, int allowed)); +#else +# ifdef PNG_ALLOW_BENIGN_ERRORS +# define png_benign_error png_warning +# define png_chunk_benign_error png_chunk_warning +# else +# define png_benign_error png_error +# define png_chunk_benign_error png_chunk_error +# endif +#endif + +/* The png_set_<chunk> functions are for storing values in the png_info_struct. + * Similarly, the png_get_<chunk> calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_<chunk> functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* Returns row_pointers, which is an array of pointers to scanlines that was + * returned from png_read_png(). + */ +PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Set row_pointers, which is an array of pointers to scanlines for use + * by png_write_png(). + */ +PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr, + png_inforp info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image height in pixels. */ +PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image bit_depth. */ +PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image color_type. */ +PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image filter_type. */ +PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image interlace_type. */ +PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image compression_type. */ +PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +#endif /* EASY_ACCESS */ + +#ifdef PNG_READ_SUPPORTED +/* Returns pointer to signature string read from PNG header */ +PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, + png_inforp info_ptr, png_color_16p *background)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_color_16p background)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)) +PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z, + double *green_X, double *green_Y, double *green_Z, double *blue_X, + double *blue_Y, double *blue_Z)) +PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_white_x, png_fixed_point *int_white_y, + png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, + png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) +PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, png_fixed_point *int_green_X, + png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z)) +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr, + png_inforp info_ptr, + double white_x, double white_y, double red_x, double red_y, double green_x, + double green_y, double blue_x, double blue_y)) +PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr, + png_inforp info_ptr, double red_X, double red_Y, double red_Z, + double green_X, double green_Y, double green_Z, double blue_X, + double blue_Y, double blue_Z)) +PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_white_x, + png_fixed_point int_white_y, png_fixed_point int_red_x, + png_fixed_point int_red_y, png_fixed_point int_green_x, + png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)) +PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z)) +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *file_gamma)) +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_file_gamma)) +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, + png_inforp info_ptr, double file_gamma)) +PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_file_gamma)) +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_16p *hist)); +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_uint_16p hist)); +#endif + +PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr, + png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, png_charp *purpose, png_int_32 *X0, + png_int_32 *X1, int *type, int *nparams, png_charp *units, + png_charpp *params)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_const_charp units, png_charpp params)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr, + png_inforp info_ptr, png_colorp *palette, int *num_palette)); + +PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, + png_inforp info_ptr, png_const_colorp palette, int num_palette)); + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_color_8p *sig_bit)); +#endif + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_color_8p sig_bit)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *file_srgb_intent)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, + png_inforp info_ptr, int srgb_intent)); +PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, + png_inforp info_ptr, int srgb_intent)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, + png_inforp info_ptr, png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_sPLT_tpp entries)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)); +#endif + +#ifdef PNG_TEXT_SUPPORTED +/* png_get_text also returns the number of text chunks in *num_text */ +PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr, + png_inforp info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#ifdef PNG_TEXT_SUPPORTED +PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_textp text_ptr, int num_text)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr, + png_inforp info_ptr, png_timep *mod_time)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_timep mod_time)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, + png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, + png_color_16p *trans_color)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr, + png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); +#endif + +#ifdef PNG_sCAL_SUPPORTED +PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *unit, double *width, double *height)) +#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ + defined(PNG_FLOATING_POINT_SUPPORTED) +/* NOTE: this API is currently implemented using floating point arithmetic, + * consequently it can only be used on systems with floating point support. + * In any case the range of values supported by png_fixed_point is small and it + * is highly recommended that png_get_sCAL_s be used instead. + */ +PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, + png_fixed_point *width, png_fixed_point *height)) +#endif +PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, + (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, + png_charpp swidth, png_charpp sheight)); + +PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, double width, double height)) +PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, png_fixed_point width, + png_fixed_point height)) +PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, + png_const_charp swidth, png_const_charp sheight)); +#endif /* sCAL */ + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +/* Provide the default handling for all unknown chunks or, optionally, for + * specific unknown chunks. + * + * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was + * ignored and the default was used, the per-chunk setting only had an effect on + * write. If you wish to have chunk-specific handling on read in code that must + * work on earlier versions you must use a user chunk callback to specify the + * desired handling (keep or discard.) + * + * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The + * parameter is interpreted as follows: + * + * READ: + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Known chunks: do normal libpng processing, do not keep the chunk (but + * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + * Unknown chunks: for a specific chunk use the global default, when used + * as the default discard the chunk data. + * PNG_HANDLE_CHUNK_NEVER: + * Discard the chunk data. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Keep the chunk data if the chunk is not critical else raise a chunk + * error. + * PNG_HANDLE_CHUNK_ALWAYS: + * Keep the chunk data. + * + * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, + * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent + * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks + * it simply resets the behavior to the libpng default. + * + * INTERACTION WTIH USER CHUNK CALLBACKS: + * The per-chunk handling is always used when there is a png_user_chunk_ptr + * callback and the callback returns 0; the chunk is then always stored *unless* + * it is critical and the per-chunk setting is other than ALWAYS. Notice that + * the global default is *not* used in this case. (In effect the per-chunk + * value is incremented to at least IF_SAFE.) + * + * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and + * per-chunk defaults will be honored. If you want to preserve the current + * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE + * as the default - if you don't do this libpng 1.6 will issue a warning. + * + * If you want unhandled unknown chunks to be discarded in libpng 1.6 and + * earlier simply return '1' (handled). + * + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: + * If this is *not* set known chunks will always be handled by libpng and + * will never be stored in the unknown chunk list. Known chunks listed to + * png_set_keep_unknown_chunks will have no effect. If it is set then known + * chunks listed with a keep other than AS_DEFAULT will *never* be processed + * by libpng, in addition critical chunks must either be processed by the + * callback or saved. + * + * The IHDR and IEND chunks must not be listed. Because this turns off the + * default handling for chunks that would otherwise be recognized the + * behavior of libpng transformations may well become incorrect! + * + * WRITE: + * When writing chunks the options only apply to the chunks specified by + * png_set_unknown_chunks (below), libpng will *always* write known chunks + * required by png_set_ calls and will always write the core critical chunks + * (as required for PLTE). + * + * Each chunk in the png_set_unknown_chunks list is looked up in the + * png_set_keep_unknown_chunks list to find the keep setting, this is then + * interpreted as follows: + * + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Write safe-to-copy chunks and write other chunks if the global + * default is set to _ALWAYS, otherwise don't write this chunk. + * PNG_HANDLE_CHUNK_NEVER: + * Do not write the chunk. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Write the chunk if it is safe-to-copy, otherwise do not write it. + * PNG_HANDLE_CHUNK_ALWAYS: + * Write the chunk. + * + * Note that the default behavior is effectively the opposite of the read case - + * in read unknown chunks are not stored by default, in write they are written + * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different + * - on write the safe-to-copy bit is checked, on read the critical bit is + * checked and on read if the chunk is critical an error will be raised. + * + * num_chunks: + * =========== + * If num_chunks is positive, then the "keep" parameter specifies the manner + * for handling only those chunks appearing in the chunk_list array, + * otherwise the chunk list array is ignored. + * + * If num_chunks is 0 the "keep" parameter specifies the default behavior for + * unknown chunks, as described above. + * + * If num_chunks is negative, then the "keep" parameter specifies the manner + * for handling all unknown chunks plus all chunks recognized by libpng + * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to + * be processed by libpng. + */ +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, + int keep, png_const_bytep chunk_list, int num_chunks)); + +/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; + * the result is therefore true (non-zero) if special handling is required, + * false for the default handling. + */ +PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, + png_const_bytep chunk_name)); +#endif + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_unknown_chunkp unknowns, + int num_unknowns)); + /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added + * unknowns to the location currently stored in the png_struct. This is + * invariably the wrong value on write. To fix this call the following API + * for each chunk in the list with the correct location. If you know your + * code won't be compiled on earlier versions you can rely on + * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing + * the correct thing. + */ + +PNG_EXPORT(175, void, png_set_unknown_chunk_location, + (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); + +PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, + png_inforp info_ptr, png_unknown_chunkpp entries)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + * If you need to turn it off for a chunk that your application has freed, + * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); + */ +PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr, + png_inforp info_ptr, int mask)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* The "params" pointer is currently not used and is for future expansion. */ +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif +#ifdef PNG_WRITE_SUPPORTED +PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif +#endif + +PNG_EXPORT(180, png_const_charp, png_get_copyright, + (png_const_structrp png_ptr)); +PNG_EXPORT(181, png_const_charp, png_get_header_ver, + (png_const_structrp png_ptr)); +PNG_EXPORT(182, png_const_charp, png_get_header_version, + (png_const_structrp png_ptr)); +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, + (png_const_structrp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr, + png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 +#define PNG_HANDLE_CHUNK_LAST 4 + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. + */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr, + png_uint_32 strip_mode)); +#endif + +/* Added in libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr, + png_uint_32 user_width_max, png_uint_32 user_height_max)); +PNG_EXPORT(187, png_uint_32, png_get_user_width_max, + (png_const_structrp png_ptr)); +PNG_EXPORT(188, png_uint_32, png_get_user_height_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.0 */ +PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, + png_uint_32 user_chunk_cache_max)); +PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.1 */ +PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, + png_alloc_size_t user_chunk_cache_max)); +PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, + (png_const_structrp png_ptr)); +#endif + +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_FP_EXPORT(196, float, png_get_x_offset_inches, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, + png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +# ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +# endif /* pHYs */ +#endif /* INCH_CONVERSIONS */ + +/* Added in libpng-1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr)); + +/* Removed from libpng 1.6; use png_get_io_chunk_type. */ +PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), + PNG_DEPRECATED) + +PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, + (png_const_structrp png_ptr)); + +/* The flags returned by png_get_io_state() are the following: */ +# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ +# define PNG_IO_READING 0x0001 /* currently reading */ +# define PNG_IO_WRITING 0x0002 /* currently writing */ +# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ +# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ +# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ +# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ +# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ +# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ +#endif /* IO_STATE */ + +/* Interlace support. The following macros are always defined so that if + * libpng interlace handling is turned off the macros may be used to handle + * interlaced images within the application. + */ +#define PNG_INTERLACE_ADAM7_PASSES 7 + +/* Two macros to return the first row and first column of the original, + * full, image which appears in a given pass. 'pass' is in the range 0 + * to 6 and the result is in the range 0 to 7. + */ +#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) +#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) + +/* A macro to return the offset between pixels in the output row for a pair of + * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that + * follows. Note that ROW_OFFSET is the offset from one row to the next whereas + * COL_OFFSET is from one column to the next, within a row. + */ +#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) +#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) + +/* Two macros to help evaluate the number of rows or columns in each + * pass. This is expressed as a shift - effectively log2 of the number or + * rows or columns in each 8x8 tile of the original image. + */ +#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) +#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) + +/* Hence two macros to determine the number of rows or columns in a given + * pass of an image given its height or width. In fact these macros may + * return non-zero even though the sub-image is empty, because the other + * dimension may be empty for a small image. + */ +#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\ + -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass)) +#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\ + -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass)) + +/* For the reader row callbacks (both progressive and sequential) it is + * necessary to find the row in the output image given a row in an interlaced + * image, so two more macros: + */ +#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ + (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass)) +#define PNG_COL_FROM_PASS_COL(x_in, pass) \ + (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass)) + +/* Two macros which return a boolean (0 or 1) saying whether the given row + * or column is in a particular pass. These use a common utility macro that + * returns a mask for a given pass - the offset 'off' selects the row or + * column version. The mask has the appropriate bit set for each column in + * the tile. + */ +#define PNG_PASS_MASK(pass,off) ( \ + ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \ + ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) + +#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ + ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) +#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ + ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ + * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 \ + - (png_uint_16)(alpha)) + 128); \ + (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ + * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(65535 \ + - (png_uint_32)(alpha)) + 32768); \ + (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); } + +#else /* Standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = \ + (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + 127) / 255)) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = \ + (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ + 32767) / 65535)) +#endif /* READ_COMPOSITE_NODIV */ + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); +PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); +PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); +#endif + +PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr, + png_const_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); +#endif +#ifdef PNG_SAVE_INT_32_SUPPORTED +PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); +#endif + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ +#endif + +#ifdef PNG_USE_READ_MACROS +/* Inline macros to do direct reads of bytes from the input buffer. + * The png_get_int_32() routine assumes we are using two's complement + * format for negative values, which is almost certainly true. + */ +# define PNG_get_uint_32(buf) \ + (((png_uint_32)(*(buf)) << 24) + \ + ((png_uint_32)(*((buf) + 1)) << 16) + \ + ((png_uint_32)(*((buf) + 2)) << 8) + \ + ((png_uint_32)(*((buf) + 3)))) + + /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the + * function) incorrectly returned a value of type png_uint_32. + */ +# define PNG_get_uint_16(buf) \ + ((png_uint_16) \ + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) + +# define PNG_get_int_32(buf) \ + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ + : (png_int_32)png_get_uint_32(buf))) + + /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, + * but defining a macro name prefixed with PNG_PREFIX. + */ +# ifndef PNG_PREFIX +# define png_get_uint_32(buf) PNG_get_uint_32(buf) +# define png_get_uint_16(buf) PNG_get_uint_16(buf) +# define png_get_int_32(buf) PNG_get_int_32(buf) +# endif +#else +# ifdef PNG_PREFIX + /* No macros; revert to the (redefined) function */ +# define PNG_get_uint_32 (png_get_uint_32) +# define PNG_get_uint_16 (png_get_uint_16) +# define PNG_get_int_32 (png_get_int_32) +# endif +#endif + +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +/******************************************************************************* + * SIMPLIFIED API + ******************************************************************************* + * + * Please read the documentation in libpng-manual.txt (TODO: write said + * documentation) if you don't understand what follows. + * + * The simplified API hides the details of both libpng and the PNG file format + * itself. It allows PNG files to be read into a very limited number of + * in-memory bitmap formats or to be written from the same formats. If these + * formats do not accomodate your needs then you can, and should, use the more + * sophisticated APIs above - these support a wide variety of in-memory formats + * and a wide variety of sophisticated transformations to those formats as well + * as a wide variety of APIs to manipulate ancillary information. + * + * To read a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure (see below) on the stack and set the + * version field to PNG_IMAGE_VERSION. + * 2) Call the appropriate png_image_begin_read... function. + * 3) Set the png_image 'format' member to the required sample format. + * 4) Allocate a buffer for the image and, if required, the color-map. + * 5) Call png_image_finish_read to read the image and, if required, the + * color-map into your buffers. + * + * There are no restrictions on the format of the PNG input itself; all valid + * color types, bit depths, and interlace methods are acceptable, and the + * input image is transformed as necessary to the requested in-memory format + * during the png_image_finish_read() step. The only caveat is that if you + * request a color-mapped image from a PNG that is full-color or makes + * complex use of an alpha channel the transformation is extremely lossy and the + * result may look terrible. + * + * To write a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. + * 2) Initialize the members of the structure that describe the image, setting + * the 'format' member to the format of the image samples. + * 3) Call the appropriate png_image_write... function with a pointer to the + * image and, if necessary, the color-map to write the PNG data. + * + * png_image is a structure that describes the in-memory format of an image + * when it is being read or defines the in-memory format of an image that you + * need to write: + */ +#define PNG_IMAGE_VERSION 1 + +typedef struct png_control *png_controlp; +typedef struct +{ + png_controlp opaque; /* Initialize to NULL, free with png_image_free */ + png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ + png_uint_32 width; /* Image width in pixels (columns) */ + png_uint_32 height; /* Image height in pixels (rows) */ + png_uint_32 format; /* Image format as defined below */ + png_uint_32 flags; /* A bit mask containing informational flags */ + png_uint_32 colormap_entries; + /* Number of entries in the color-map */ + + /* In the event of an error or warning the following field will be set to a + * non-zero value and the 'message' field will contain a '\0' terminated + * string with the libpng error or warning message. If both warnings and + * an error were encountered, only the error is recorded. If there + * are multiple warnings, only the first one is recorded. + * + * The upper 30 bits of this value are reserved, the low two bits contain + * a value as follows: + */ +# define PNG_IMAGE_WARNING 1 +# define PNG_IMAGE_ERROR 2 + /* + * The result is a two-bit code such that a value more than 1 indicates + * a failure in the API just called: + * + * 0 - no warning or error + * 1 - warning + * 2 - error + * 3 - error preceded by warning + */ +# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) + + png_uint_32 warning_or_error; + + char message[64]; +} png_image, *png_imagep; + +/* The samples of the image have one to four channels whose components have + * original values in the range 0 to 1.0: + * + * 1: A single gray or luminance channel (G). + * 2: A gray/luminance channel and an alpha channel (GA). + * 3: Three red, green, blue color channels (RGB). + * 4: Three color channels and an alpha channel (RGBA). + * + * The components are encoded in one of two ways: + * + * a) As a small integer, value 0..255, contained in a single byte. For the + * alpha channel the original value is simply value/255. For the color or + * luminance channels the value is encoded according to the sRGB specification + * and matches the 8-bit format expected by typical display devices. + * + * The color/gray channels are not scaled (pre-multiplied) by the alpha + * channel and are suitable for passing to color management software. + * + * b) As a value in the range 0..65535, contained in a 2-byte integer. All + * channels can be converted to the original value by dividing by 65535; all + * channels are linear. Color channels use the RGB encoding (RGB end-points) of + * the sRGB specification. This encoding is identified by the + * PNG_FORMAT_FLAG_LINEAR flag below. + * + * When the simplified API needs to convert between sRGB and linear colorspaces, + * the actual sRGB transfer curve defined in the sRGB specification (see the + * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 + * approximation used elsewhere in libpng. + * + * When an alpha channel is present it is expected to denote pixel coverage + * of the color or luminance channels and is returned as an associated alpha + * channel: the color/gray channels are scaled (pre-multiplied) by the alpha + * value. + * + * The samples are either contained directly in the image data, between 1 and 8 + * bytes per pixel according to the encoding, or are held in a color-map indexed + * by bytes in the image data. In the case of a color-map the color-map entries + * are individual samples, encoded as above, and the image data has one byte per + * pixel to select the relevant sample from the color-map. + */ + +/* PNG_FORMAT_* + * + * #defines to be used in png_image::format. Each #define identifies a + * particular layout of sample data and, if present, alpha values. There are + * separate defines for each of the two component encodings. + * + * A format is built up using single bit flag values. All combinations are + * valid. Formats can be built up from the flag values or you can use one of + * the predefined values below. When testing formats always use the FORMAT_FLAG + * macros to test for individual features - future versions of the library may + * add new flags. + * + * When reading or writing color-mapped images the format should be set to the + * format of the entries in the color-map then png_image_{read,write}_colormap + * called to read or write the color-map and set the format correctly for the + * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! + * + * NOTE: libpng can be built with particular features disabled, if you see + * compiler errors because the definition of one of the following flags has been + * compiled out it is because libpng does not have the required support. It is + * possible, however, for the libpng configuration to enable the format on just + * read or just write; in that case you may see an error at run time. You can + * guard against this by checking for the definition of the appropriate + * "_SUPPORTED" macro, one of: + * + * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED + */ +#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ +#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ +#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */ +#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ + +#ifdef PNG_FORMAT_BGR_SUPPORTED +# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ +#endif + +#ifdef PNG_FORMAT_AFIRST_SUPPORTED +# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ +#endif + +/* Commonly used formats have predefined macros. + * + * First the single byte (sRGB) formats: + */ +#define PNG_FORMAT_GRAY 0 +#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA +#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR +#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) +#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) + +/* Then the linear 2-byte formats. When naming these "Y" is used to + * indicate a luminance (gray) channel. + */ +#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR +#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) +#define PNG_FORMAT_LINEAR_RGB_ALPHA \ + (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) + +/* With color-mapped formats the image data is one byte for each pixel, the byte + * is an index into the color-map which is formatted as above. To obtain a + * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP + * to one of the above definitions, or you can use one of the definitions below. + */ +#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) + +/* PNG_IMAGE macros + * + * These are convenience macros to derive information from a png_image + * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the + * actual image sample values - either the entries in the color-map or the + * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values + * for the pixels and will always return 1 for color-mapped formats. The + * remaining macros return information about the rows in the image and the + * complete image. + * + * NOTE: All the macros that take a png_image::format parameter are compile time + * constants if the format parameter is, itself, a constant. Therefore these + * macros can be used in array declarations and case labels where required. + * Similarly the macros are also pre-processor constants (sizeof is not used) so + * they can be used in #if tests. + * + * First the information about the samples. + */ +#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ + (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) + /* Return the total number of channels in a given format: 1..4 */ + +#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ + ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) + /* Return the size in bytes of a single component of a pixel or color-map + * entry (as appropriate) in the image: 1 or 2. + */ + +#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) + /* This is the size of the sample data for one sample. If the image is + * color-mapped it is the size of one color-map entry (and image pixels are + * one byte in size), otherwise it is the size of one image pixel. + */ + +#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) + /* The maximum size of the color-map required by the format expressed in a + * count of components. This can be used to compile-time allocate a + * color-map: + * + * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; + * + * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; + * + * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the + * information from one of the png_image_begin_read_ APIs and dynamically + * allocate the required memory. + */ + +/* Corresponding information about the pixels */ +#define PNG_IMAGE_PIXEL_(test,fmt)\ + (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) + +#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) + /* The number of separate channels (components) in a pixel; 1 for a + * color-mapped image. + */ + +#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) + /* The size, in bytes, of each component in a pixel; 1 for a color-mapped + * image. + */ + +#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) + /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ + +/* Information about the whole row, or whole image */ +#define PNG_IMAGE_ROW_STRIDE(image)\ + (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) + /* Return the total number of components in a single row of the image; this + * is the minimum 'row stride', the minimum count of components between each + * row. For a color-mapped image this is the minimum number of bytes in a + * row. + */ + +#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ + (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) + /* Return the size, in bytes, of an image buffer given a png_image and a row + * stride - the number of components to leave space for in each row. + */ + +#define PNG_IMAGE_SIZE(image)\ + PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) + /* Return the size, in bytes, of the image in memory given just a png_image; + * the row stride is the minimum stride required for the image. + */ + +#define PNG_IMAGE_COLORMAP_SIZE(image)\ + (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) + /* Return the size, in bytes, of the color-map of this image. If the image + * format is not a color-map format this will return a size sufficient for + * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if + * you don't want to allocate a color-map in this case. + */ + +/* PNG_IMAGE_FLAG_* + * + * Flags containing additional information about the image are held in the + * 'flags' field of png_image. + */ +#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 + /* This indicates the the RGB values of the in-memory bitmap do not + * correspond to the red, green and blue end-points defined by sRGB. + */ + +#define PNG_IMAGE_FLAG_FAST 0x02 + /* On write emphasise speed over compression; the resultant PNG file will be + * larger but will be produced significantly faster, particular for large + * images. Do not use this option for images which will be distributed, only + * used it when producing intermediate files that will be read back in + * repeatedly. For a typical 24-bit image the option will double the read + * speed at the cost of increasing the image size by 25%, however for many + * more compressible images the PNG file can be 10 times larger with only a + * slight speed gain. + */ + +#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 + /* On read if the image is a 16-bit per component image and there is no gAMA + * or sRGB chunk assume that the components are sRGB encoded. Notice that + * images output by the simplified API always have gamma information; setting + * this flag only affects the interpretation of 16-bit images from an + * external source. It is recommended that the application expose this flag + * to the user; the user can normally easily recognize the difference between + * linear and sRGB encoding. This flag has no effect on write - the data + * passed to the write APIs must have the correct encoding (as defined + * above.) + * + * If the flag is not set (the default) input 16-bit per component data is + * assumed to be linear. + * + * NOTE: the flag can only be set after the png_image_begin_read_ call, + * because that call initializes the 'flags' field. + */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* READ APIs + * --------- + * + * The png_image passed to the read APIs must have been initialized by setting + * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) + */ +#ifdef PNG_STDIO_SUPPORTED +PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, + const char *file_name)); + /* The named file is opened for read and the image header is filled in + * from the PNG header in the file. + */ + +PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, + FILE* file)); + /* The PNG header is read from the stdio FILE object. */ +#endif /* STDIO */ + +PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, + png_const_voidp memory, png_size_t size)); + /* The PNG header is read from the given memory buffer. */ + +PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, + png_const_colorp background, void *buffer, png_int_32 row_stride, + void *colormap)); + /* Finish reading the image into the supplied buffer and clean up the + * png_image structure. + * + * row_stride is the step, in byte or 2-byte units as appropriate, + * between adjacent rows. A positive stride indicates that the top-most row + * is first in the buffer - the normal top-down arrangement. A negative + * stride indicates that the bottom-most row is first in the buffer. + * + * background need only be supplied if an alpha channel must be removed from + * a png_byte format and the removal is to be done by compositing on a solid + * color; otherwise it may be NULL and any composition will be done directly + * onto the buffer. The value is an sRGB color to use for the background, + * for grayscale output the green channel is used. + * + * background must be supplied when an alpha channel must be removed from a + * single byte color-mapped output format, in other words if: + * + * 1) The original format from png_image_begin_read_from_* had + * PNG_FORMAT_FLAG_ALPHA set. + * 2) The format set by the application does not. + * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and + * PNG_FORMAT_FLAG_LINEAR *not* set. + * + * For linear output removing the alpha channel is always done by compositing + * on black and background is ignored. + * + * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must + * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. + * image->colormap_entries will be updated to the actual number of entries + * written to the colormap; this may be less than the original value. + */ + +PNG_EXPORT(238, void, png_image_free, (png_imagep image)); + /* Free any data allocated by libpng in image->opaque, setting the pointer to + * NULL. May be called at any time after the structure is initialized. + */ +#endif /* SIMPLIFIED_READ */ + +#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED +#ifdef PNG_STDIO_SUPPORTED +/* WRITE APIS + * ---------- + * For write you must initialize a png_image structure to describe the image to + * be written. To do this use memset to set the whole structure to 0 then + * initialize fields describing your image. + * + * version: must be set to PNG_IMAGE_VERSION + * opaque: must be initialized to NULL + * width: image width in pixels + * height: image height in rows + * format: the format of the data (image and color-map) you wish to write + * flags: set to 0 unless one of the defined flags applies; set + * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB + * values do not correspond to the colors in sRGB. + * colormap_entries: set to the number of entries in the color-map (0 to 256) + */ +PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, + const char *file, int convert_to_8bit, const void *buffer, + png_int_32 row_stride, const void *colormap)); + /* Write the image to the named file. */ + +PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, + int convert_to_8_bit, const void *buffer, png_int_32 row_stride, + const void *colormap)); + /* Write the image to the given (FILE*). */ + +/* With both write APIs if image is in one of the linear formats with 16-bit + * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG + * gamma encoded according to the sRGB specification, otherwise a 16-bit linear + * encoded PNG file is written. + * + * With color-mapped data formats the colormap parameter point to a color-map + * with at least image->colormap_entries encoded in the specified format. If + * the format is linear the written PNG color-map will be converted to sRGB + * regardless of the convert_to_8_bit flag. + * + * With all APIs row_stride is handled as in the read APIs - it is the spacing + * from one row to the next in component sized units (1 or 2 bytes) and if + * negative indicates a bottom-up row layout in the buffer. + * + * Note that the write API does not support interlacing or sub-8-bit pixels. + */ +#endif /* STDIO */ +#endif /* SIMPLIFIED_WRITE */ +/******************************************************************************* + * END OF SIMPLIFIED API + ******************************************************************************/ +#endif /* SIMPLIFIED_{READ|WRITE} */ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +PNG_EXPORT(242, void, png_set_check_for_invalid_index, + (png_structrp png_ptr, int allowed)); +# ifdef PNG_GET_PALETTE_MAX_SUPPORTED +PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, + png_const_infop info_ptr)); +# endif +#endif /* CHECK_FOR_INVALID_INDEX */ + +/******************************************************************************* + * IMPLEMENTATION OPTIONS + ******************************************************************************* + * + * Support for arbitrary implementation-specific optimizations. The API allows + * particular options to be turned on or off. 'Option' is the number of the + * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given + * by the PNG_OPTION_ defines below. + * + * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions, + * are detected at run time, however sometimes it may be impossible + * to do this in user mode, in which case it is necessary to discover + * the capabilities in an OS specific way. Such capabilities are + * listed here when libpng has support for them and must be turned + * ON by the application if present. + * + * SOFTWARE: sometimes software optimizations actually result in performance + * decrease on some architectures or systems, or with some sets of + * PNG images. 'Software' options allow such optimizations to be + * selected at run time. + */ +#ifdef PNG_SET_OPTION_SUPPORTED +#ifdef PNG_ARM_NEON_API_SUPPORTED +# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ +#endif +#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ +#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ +#define PNG_OPTION_NEXT 6 /* Next option - numbers must be even */ + +/* Return values: NOTE: there are four values and 'off' is *not* zero */ +#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ +#define PNG_OPTION_INVALID 1 /* Option number out of range */ +#define PNG_OPTION_OFF 2 +#define PNG_OPTION_ON 3 + +PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, + int onoff)); +#endif /* SET_OPTION */ + +/******************************************************************************* + * END OF HARDWARE AND SOFTWARE OPTIONS + ******************************************************************************/ + +/* Maintainer: Put new public prototypes here ^, in libpng.3, in project + * defs, and in scripts/symbols.def. + */ + +/* The last ordinal number (this is the *last* one already used; the next + * one to use is one more than this.) + */ +#ifdef PNG_EXPORT_LAST_ORDINAL + PNG_EXPORT_LAST_ORDINAL(244); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* Do not put anything past this line */ +#endif /* PNG_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/pngconf.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/pngconf.h new file mode 100644 index 00000000..3f9493e4 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/pngconf.h @@ -0,0 +1,622 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.6.17, March 26, 2015 + * + * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ + +/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C + * compiler for correct compilation. The following header files are required by + * the standard. If your compiler doesn't provide these header files, or they + * do not match the standard, you will need to provide/improve them. + */ +#include <limits.h> +#include <stddef.h> + +/* Library header files. These header files are all defined by ISOC90; libpng + * expects conformant implementations, however, an ISOC90 conformant system need + * not provide these header files if the functionality cannot be implemented. + * In this case it will be necessary to disable the relevant parts of libpng in + * the build of pnglibconf.h. + * + * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not + * include this unnecessary header file. + */ + +#ifdef PNG_STDIO_SUPPORTED + /* Required for the definition of FILE: */ +# include <stdio.h> +#endif + +#ifdef PNG_SETJMP_SUPPORTED + /* Required for the definition of jmp_buf and the declaration of longjmp: */ +# include <setjmp.h> +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED + /* Required for struct tm: */ +# include <time.h> +#endif + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using + * PNG_NO_CONST; this is no longer supported except for data declarations which + * apparently still cause problems in 2011 on some compilers. + */ +#define PNG_CONST const /* backward compatibility only */ + +/* This controls optimization of the reading of 16 and 32 bit values + * from PNG files. It can be set on a per-app-file basis - it + * just changes whether a macro is used when the function is called. + * The library builder sets the default; if read functions are not + * built into the library the macro implementation is forced on. + */ +#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED +# define PNG_USE_READ_MACROS +#endif +#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) +# if PNG_DEFAULT_READ_MACROS +# define PNG_USE_READ_MACROS +# endif +#endif + +/* COMPILER SPECIFIC OPTIONS. + * + * These options are provided so that a variety of difficult compilers + * can be used. Some are fixed at build time (e.g. PNG_API_RULE + * below) but still have compiler specific implementations, others + * may be changed on a per-file basis when compiling against libpng. + */ + +/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect + * against legacy (pre ISOC90) compilers that did not understand function + * prototypes. It is not required for modern C compilers. + */ +#ifndef PNGARG +# define PNGARG(arglist) arglist +#endif + +/* Function calling conventions. + * ============================= + * Normally it is not necessary to specify to the compiler how to call + * a function - it just does it - however on x86 systems derived from + * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems + * and some others) there are multiple ways to call a function and the + * default can be changed on the compiler command line. For this reason + * libpng specifies the calling convention of every exported function and + * every function called via a user supplied function pointer. This is + * done in this file by defining the following macros: + * + * PNGAPI Calling convention for exported functions. + * PNGCBAPI Calling convention for user provided (callback) functions. + * PNGCAPI Calling convention used by the ANSI-C library (required + * for longjmp callbacks and sometimes used internally to + * specify the calling convention for zlib). + * + * These macros should never be overridden. If it is necessary to + * change calling convention in a private build this can be done + * by setting PNG_API_RULE (which defaults to 0) to one of the values + * below to select the correct 'API' variants. + * + * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. + * This is correct in every known environment. + * PNG_API_RULE=1 Use the operating system convention for PNGAPI and + * the 'C' calling convention (from PNGCAPI) for + * callbacks (PNGCBAPI). This is no longer required + * in any known environment - if it has to be used + * please post an explanation of the problem to the + * libpng mailing list. + * + * These cases only differ if the operating system does not use the C + * calling convention, at present this just means the above cases + * (x86 DOS/Windows sytems) and, even then, this does not apply to + * Cygwin running on those systems. + * + * Note that the value must be defined in pnglibconf.h so that what + * the application uses to call the library matches the conventions + * set when building the library. + */ + +/* Symbol export + * ============= + * When building a shared library it is almost always necessary to tell + * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' + * is used to mark the symbols. On some systems these symbols can be + * extracted at link time and need no special processing by the compiler, + * on other systems the symbols are flagged by the compiler and just + * the declaration requires a special tag applied (unfortunately) in a + * compiler dependent way. Some systems can do either. + * + * A small number of older systems also require a symbol from a DLL to + * be flagged to the program that calls it. This is a problem because + * we do not know in the header file included by application code that + * the symbol will come from a shared library, as opposed to a statically + * linked one. For this reason the application must tell us by setting + * the magic flag PNG_USE_DLL to turn on the special processing before + * it includes png.h. + * + * Four additional macros are used to make this happen: + * + * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from + * the build or imported if PNG_USE_DLL is set - compiler + * and system specific. + * + * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to + * 'type', compiler specific. + * + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to + * make a symbol exported from the DLL. Not used in the + * public header files; see pngpriv.h for how it is used + * in the libpng build. + * + * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come + * from a DLL - used to define PNG_IMPEXP when + * PNG_USE_DLL is set. + */ + +/* System specific discovery. + * ========================== + * This code is used at build time to find PNG_IMPEXP, the API settings + * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL + * import processing is possible. On Windows systems it also sets + * compiler-specific macros to the values required to change the calling + * conventions of the various functions. + */ +#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ + defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) + /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or + * MinGW on any architecture currently supported by Windows. Also includes + * Watcom builds but these need special treatment because they are not + * compatible with GCC or Visual C because of different calling conventions. + */ +# if PNG_API_RULE == 2 + /* If this line results in an error, either because __watcall is not + * understood or because of a redefine just below you cannot use *this* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ +# define PNGCAPI __watcall +# endif + +# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) +# define PNGCAPI __cdecl +# if PNG_API_RULE == 1 + /* If this line results in an error __stdcall is not understood and + * PNG_API_RULE should not have been set to '1'. + */ +# define PNGAPI __stdcall +# endif +# else + /* An older compiler, or one not detected (erroneously) above, + * if necessary override on the command line to get the correct + * variants for the compiler. + */ +# ifndef PNGCAPI +# define PNGCAPI _cdecl +# endif +# if PNG_API_RULE == 1 && !defined(PNGAPI) +# define PNGAPI _stdcall +# endif +# endif /* compiler/api */ + + /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ + +# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) +# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" +# endif + +# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ + (defined(__BORLANDC__) && __BORLANDC__ < 0x500) + /* older Borland and MSC + * compilers used '__export' and required this to be after + * the type. + */ +# ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP +# endif +# define PNG_DLL_EXPORT __export +# else /* newer compiler */ +# define PNG_DLL_EXPORT __declspec(dllexport) +# ifndef PNG_DLL_IMPORT +# define PNG_DLL_IMPORT __declspec(dllimport) +# endif +# endif /* compiler */ + +#else /* !Windows */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# define PNGAPI _System +# else /* !Windows/x86 && !OS/2 */ + /* Use the defaults, or define PNG*API on the command line (but + * this will have to be done for every compile!) + */ +# endif /* other system, !OS/2 */ +#endif /* !Windows/x86 */ + +/* Now do all the defaulting . */ +#ifndef PNGCAPI +# define PNGCAPI +#endif +#ifndef PNGCBAPI +# define PNGCBAPI PNGCAPI +#endif +#ifndef PNGAPI +# define PNGAPI PNGCAPI +#endif + +/* PNG_IMPEXP may be set on the compilation system command line or (if not set) + * then in an internal header file when building the library, otherwise (when + * using the library) it is set here. + */ +#ifndef PNG_IMPEXP +# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) + /* This forces use of a DLL, disallowing static linking */ +# define PNG_IMPEXP PNG_DLL_IMPORT +# endif + +# ifndef PNG_IMPEXP +# define PNG_IMPEXP +# endif +#endif + +/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat + * 'attributes' as a storage class - the attributes go at the start of the + * function definition, and attributes are always appended regardless of the + * compiler. This considerably simplifies these macros but may cause problems + * if any compilers both need function attributes and fail to handle them as + * a storage class (this is unlikely.) + */ +#ifndef PNG_FUNCTION +# define PNG_FUNCTION(type, name, args, attributes) attributes type name args +#endif + +#ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type +#endif + + /* The ordinal value is only relevant when preprocessing png.h for symbol + * table entries, so we discard it here. See the .dfn files in the + * scripts directory. + */ +#ifndef PNG_EXPORTA + +# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ + PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \ + extern attributes) +#endif + +/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, + * so make something non-empty to satisfy the requirement: + */ +#define PNG_EMPTY /*empty list*/ + +#define PNG_EXPORT(ordinal, type, name, args)\ + PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) + +/* Use PNG_REMOVED to comment out a removed interface. */ +#ifndef PNG_REMOVED +# define PNG_REMOVED(ordinal, type, name, args, attributes) +#endif + +#ifndef PNG_CALLBACK +# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args) +#endif + +/* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. + * + * Added at libpng-1.2.41. + */ + +#ifndef PNG_NO_PEDANTIC_WARNINGS +# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_PEDANTIC_WARNINGS_SUPPORTED +# endif +#endif + +#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED + /* Support for compiler specific function attributes. These are used + * so that where compiler support is available, incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng + * version 1.2.41. Disabling these removes the warnings but may also produce + * less efficient code. + */ +# if defined(__clang__) && defined(__has_attribute) + /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ +# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# if !defined(PNG_PRIVATE) +# ifdef __has_extension +# if __has_extension(attribute_unavailable_with_message) +# define PNG_PRIVATE __attribute__((__unavailable__(\ + "This function is not exported by libpng."))) +# endif +# endif +# endif +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif + +# elif defined(__GNUC__) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if __GNUC__ >= 3 +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# ifndef PNG_PRIVATE +# if 0 /* Doesn't work so we use deprecated instead*/ +# define PNG_PRIVATE \ + __attribute__((warning("This function is not exported by libpng."))) +# else +# define PNG_PRIVATE \ + __attribute__((__deprecated__)) +# endif +# endif +# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ +# endif /* __GNUC__ >= 3 */ + +# elif defined(_MSC_VER) && (_MSC_VER >= 1300) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* not supported */ +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __declspec(noreturn) +# endif +# ifndef PNG_ALLOCATED +# if (_MSC_VER >= 1400) +# define PNG_ALLOCATED __declspec(restrict) +# endif +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __declspec(deprecated) +# endif +# ifndef PNG_PRIVATE +# define PNG_PRIVATE __declspec(deprecated) +# endif +# ifndef PNG_RESTRICT +# if (_MSC_VER >= 1400) +# define PNG_RESTRICT __restrict +# endif +# endif + +# elif defined(__WATCOMC__) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif +#endif /* PNG_PEDANTIC_WARNINGS */ + +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED /* Use of this function is deprecated */ +#endif +#ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* The result of this function must be checked */ +#endif +#ifndef PNG_NORETURN +# define PNG_NORETURN /* This function does not return */ +#endif +#ifndef PNG_ALLOCATED +# define PNG_ALLOCATED /* The result of the function is new memory */ +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE /* This is a private libpng function */ +#endif +#ifndef PNG_RESTRICT +# define PNG_RESTRICT /* The C99 "restrict" feature */ +#endif + +#ifndef PNG_FP_EXPORT /* A floating point API. */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args); +# else /* No floating point APIs */ +# define PNG_FP_EXPORT(ordinal, type, name, args) +# endif +#endif +#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ +# ifdef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args); +# else /* No fixed point APIs */ +# define PNG_FIXED_EXPORT(ordinal, type, name, args) +# endif +#endif + +#ifndef PNG_BUILDING_SYMBOL_TABLE +/* Some typedefs to get us started. These should be safe on most of the common + * platforms. + * + * png_uint_32 and png_int_32 may, currently, be larger than required to hold a + * 32-bit value however this is not normally advisable. + * + * png_uint_16 and png_int_16 should always be two bytes in size - this is + * verified at library build time. + * + * png_byte must always be one byte in size. + * + * The checks below use constants from limits.h, as defined by the ISOC90 + * standard. + */ +#if CHAR_BIT == 8 && UCHAR_MAX == 255 + typedef unsigned char png_byte; +#else +# error "libpng requires 8 bit bytes" +#endif + +#if INT_MIN == -32768 && INT_MAX == 32767 + typedef int png_int_16; +#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 + typedef short png_int_16; +#else +# error "libpng requires a signed 16 bit type" +#endif + +#if UINT_MAX == 65535 + typedef unsigned int png_uint_16; +#elif USHRT_MAX == 65535 + typedef unsigned short png_uint_16; +#else +# error "libpng requires an unsigned 16 bit type" +#endif + +#if INT_MIN < -2147483646 && INT_MAX > 2147483646 + typedef int png_int_32; +#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 + typedef long int png_int_32; +#else +# error "libpng requires a signed 32 bit (or more) type" +#endif + +#if UINT_MAX > 4294967294 + typedef unsigned int png_uint_32; +#elif ULONG_MAX > 4294967294 + typedef unsigned long int png_uint_32; +#else +# error "libpng requires an unsigned 32 bit (or more) type" +#endif + +/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, + * requires an ISOC90 compiler and relies on consistent behavior of sizeof. + */ +typedef size_t png_size_t; +typedef ptrdiff_t png_ptrdiff_t; + +/* libpng needs to know the maximum value of 'size_t' and this controls the + * definition of png_alloc_size_t, below. This maximum value of size_t limits + * but does not control the maximum allocations the library makes - there is + * direct application control of this through png_set_user_limits(). + */ +#ifndef PNG_SMALL_SIZE_T + /* Compiler specific tests for systems where size_t is known to be less than + * 32 bits (some of these systems may no longer work because of the lack of + * 'far' support; see above.) + */ +# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ + (defined(_MSC_VER) && defined(MAXSEG_64K)) +# define PNG_SMALL_SIZE_T +# endif +#endif + +/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no + * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to + * png_alloc_size_t are not necessary; in fact, it is recommended not to use + * them at all so that the compiler can complain when something turns out to be + * problematic. + * + * Casts in the other direction (from png_alloc_size_t to png_size_t or + * png_uint_32) should be explicitly applied; however, we do not expect to + * encounter practical situations that require such conversions. + * + * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than + * 4294967295 - i.e. less than the maximum value of png_uint_32. + */ +#ifdef PNG_SMALL_SIZE_T + typedef png_uint_32 png_alloc_size_t; +#else + typedef png_size_t png_alloc_size_t; +#endif + +/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler + * implementations of Intel CPU specific support of user-mode segmented address + * spaces, where 16-bit pointers address more than 65536 bytes of memory using + * separate 'segment' registers. The implementation requires two different + * types of pointer (only one of which includes the segment value.) + * + * If required this support is available in version 1.2 of libpng and may be + * available in versions through 1.5, although the correctness of the code has + * not been verified recently. + */ + +/* Typedef for floating-point numbers that are converted to fixed-point with a + * multiple of 100,000, e.g., gamma + */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void * png_voidp; +typedef const void * png_const_voidp; +typedef png_byte * png_bytep; +typedef const png_byte * png_const_bytep; +typedef png_uint_32 * png_uint_32p; +typedef const png_uint_32 * png_const_uint_32p; +typedef png_int_32 * png_int_32p; +typedef const png_int_32 * png_const_int_32p; +typedef png_uint_16 * png_uint_16p; +typedef const png_uint_16 * png_const_uint_16p; +typedef png_int_16 * png_int_16p; +typedef const png_int_16 * png_const_int_16p; +typedef char * png_charp; +typedef const char * png_const_charp; +typedef png_fixed_point * png_fixed_point_p; +typedef const png_fixed_point * png_const_fixed_point_p; +typedef png_size_t * png_size_tp; +typedef const png_size_t * png_const_size_tp; + +#ifdef PNG_STDIO_SUPPORTED +typedef FILE * png_FILE_p; +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * png_doublep; +typedef const double * png_const_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte * * png_bytepp; +typedef png_uint_32 * * png_uint_32pp; +typedef png_int_32 * * png_int_32pp; +typedef png_uint_16 * * png_uint_16pp; +typedef png_int_16 * * png_int_16pp; +typedef const char * * png_const_charpp; +typedef char * * png_charpp; +typedef png_fixed_point * * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char * * * png_charppp; + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +#endif /* PNGCONF_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/pnglibconf.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/pnglibconf.h new file mode 100644 index 00000000..b4ec3c31 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/libpng16/pnglibconf.h @@ -0,0 +1,214 @@ +/* libpng 1.6.17 STANDARD API DEFINITION */ + +/* pnglibconf.h - library build configuration */ + +/* Libpng version 1.6.17 - March 26, 2015 */ + +/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */ + +/* This code is released under the libpng license. */ +/* For conditions of distribution and use, see the disclaimer */ +/* and license in png.h */ + +/* pnglibconf.h */ +/* Machine generated file: DO NOT EDIT */ +/* Derived from: scripts/pnglibconf.dfa */ +#ifndef PNGLCONF_H +#define PNGLCONF_H +/* options */ +#define PNG_16BIT_SUPPORTED +#define PNG_ALIGNED_MEMORY_SUPPORTED +/*#undef PNG_ARM_NEON_API_SUPPORTED*/ +/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ +#define PNG_BENIGN_ERRORS_SUPPORTED +#define PNG_BENIGN_READ_ERRORS_SUPPORTED +/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ +#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_COLORSPACE_SUPPORTED +#define PNG_CONSOLE_IO_SUPPORTED +#define PNG_CONVERT_tIME_SUPPORTED +#define PNG_EASY_ACCESS_SUPPORTED +/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ +#define PNG_ERROR_TEXT_SUPPORTED +#define PNG_FIXED_POINT_SUPPORTED +#define PNG_FLOATING_ARITHMETIC_SUPPORTED +#define PNG_FLOATING_POINT_SUPPORTED +#define PNG_FORMAT_AFIRST_SUPPORTED +#define PNG_FORMAT_BGR_SUPPORTED +#define PNG_GAMMA_SUPPORTED +#define PNG_GET_PALETTE_MAX_SUPPORTED +#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#define PNG_INCH_CONVERSIONS_SUPPORTED +#define PNG_INFO_IMAGE_SUPPORTED +#define PNG_IO_STATE_SUPPORTED +#define PNG_MNG_FEATURES_SUPPORTED +#define PNG_POINTER_INDEXING_SUPPORTED +#define PNG_PROGRESSIVE_READ_SUPPORTED +#define PNG_READ_16BIT_SUPPORTED +#define PNG_READ_ALPHA_MODE_SUPPORTED +#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_READ_BACKGROUND_SUPPORTED +#define PNG_READ_BGR_SUPPORTED +#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_READ_COMPOSITE_NODIV_SUPPORTED +#define PNG_READ_COMPRESSED_TEXT_SUPPORTED +#define PNG_READ_EXPAND_16_SUPPORTED +#define PNG_READ_EXPAND_SUPPORTED +#define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_GAMMA_SUPPORTED +#define PNG_READ_GET_PALETTE_MAX_SUPPORTED +#define PNG_READ_GRAY_TO_RGB_SUPPORTED +#define PNG_READ_INTERLACING_SUPPORTED +#define PNG_READ_INT_FUNCTIONS_SUPPORTED +#define PNG_READ_INVERT_ALPHA_SUPPORTED +#define PNG_READ_INVERT_SUPPORTED +#define PNG_READ_OPT_PLTE_SUPPORTED +#define PNG_READ_PACKSWAP_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_QUANTIZE_SUPPORTED +#define PNG_READ_RGB_TO_GRAY_SUPPORTED +#define PNG_READ_SCALE_16_TO_8_SUPPORTED +#define PNG_READ_SHIFT_SUPPORTED +#define PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_STRIP_ALPHA_SUPPORTED +#define PNG_READ_SUPPORTED +#define PNG_READ_SWAP_ALPHA_SUPPORTED +#define PNG_READ_SWAP_SUPPORTED +#define PNG_READ_TEXT_SUPPORTED +#define PNG_READ_TRANSFORMS_SUPPORTED +#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_READ_USER_CHUNKS_SUPPORTED +#define PNG_READ_USER_TRANSFORM_SUPPORTED +#define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_gAMA_SUPPORTED +#define PNG_READ_hIST_SUPPORTED +#define PNG_READ_iCCP_SUPPORTED +#define PNG_READ_iTXt_SUPPORTED +#define PNG_READ_oFFs_SUPPORTED +#define PNG_READ_pCAL_SUPPORTED +#define PNG_READ_pHYs_SUPPORTED +#define PNG_READ_sBIT_SUPPORTED +#define PNG_READ_sCAL_SUPPORTED +#define PNG_READ_sPLT_SUPPORTED +#define PNG_READ_sRGB_SUPPORTED +#define PNG_READ_tEXt_SUPPORTED +#define PNG_READ_tIME_SUPPORTED +#define PNG_READ_tRNS_SUPPORTED +#define PNG_READ_zTXt_SUPPORTED +#define PNG_SAVE_INT_32_SUPPORTED +#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SEQUENTIAL_READ_SUPPORTED +#define PNG_SETJMP_SUPPORTED +#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED +#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +#define PNG_SET_OPTION_SUPPORTED +#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SET_USER_LIMITS_SUPPORTED +#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED +#define PNG_SIMPLIFIED_READ_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_SUPPORTED +#define PNG_STDIO_SUPPORTED +#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_TEXT_SUPPORTED +#define PNG_TIME_RFC1123_SUPPORTED +#define PNG_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_USER_CHUNKS_SUPPORTED +#define PNG_USER_LIMITS_SUPPORTED +#define PNG_USER_MEM_SUPPORTED +#define PNG_USER_TRANSFORM_INFO_SUPPORTED +#define PNG_USER_TRANSFORM_PTR_SUPPORTED +#define PNG_WARNINGS_SUPPORTED +#define PNG_WRITE_16BIT_SUPPORTED +#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_WRITE_BGR_SUPPORTED +#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED +#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +#define PNG_WRITE_FILLER_SUPPORTED +#define PNG_WRITE_FILTER_SUPPORTED +#define PNG_WRITE_FLUSH_SUPPORTED +#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED +#define PNG_WRITE_INTERLACING_SUPPORTED +#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED +#define PNG_WRITE_INVERT_ALPHA_SUPPORTED +#define PNG_WRITE_INVERT_SUPPORTED +#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED +#define PNG_WRITE_PACKSWAP_SUPPORTED +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED +#define PNG_WRITE_SUPPORTED +#define PNG_WRITE_SWAP_ALPHA_SUPPORTED +#define PNG_WRITE_SWAP_SUPPORTED +#define PNG_WRITE_TEXT_SUPPORTED +#define PNG_WRITE_TRANSFORMS_SUPPORTED +#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_WRITE_USER_TRANSFORM_SUPPORTED +#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_gAMA_SUPPORTED +#define PNG_WRITE_hIST_SUPPORTED +#define PNG_WRITE_iCCP_SUPPORTED +#define PNG_WRITE_iTXt_SUPPORTED +#define PNG_WRITE_oFFs_SUPPORTED +#define PNG_WRITE_pCAL_SUPPORTED +#define PNG_WRITE_pHYs_SUPPORTED +#define PNG_WRITE_sBIT_SUPPORTED +#define PNG_WRITE_sCAL_SUPPORTED +#define PNG_WRITE_sPLT_SUPPORTED +#define PNG_WRITE_sRGB_SUPPORTED +#define PNG_WRITE_tEXt_SUPPORTED +#define PNG_WRITE_tIME_SUPPORTED +#define PNG_WRITE_tRNS_SUPPORTED +#define PNG_WRITE_zTXt_SUPPORTED +#define PNG_bKGD_SUPPORTED +#define PNG_cHRM_SUPPORTED +#define PNG_gAMA_SUPPORTED +#define PNG_hIST_SUPPORTED +#define PNG_iCCP_SUPPORTED +#define PNG_iTXt_SUPPORTED +#define PNG_oFFs_SUPPORTED +#define PNG_pCAL_SUPPORTED +#define PNG_pHYs_SUPPORTED +#define PNG_sBIT_SUPPORTED +#define PNG_sCAL_SUPPORTED +#define PNG_sPLT_SUPPORTED +#define PNG_sRGB_SUPPORTED +#define PNG_tEXt_SUPPORTED +#define PNG_tIME_SUPPORTED +#define PNG_tRNS_SUPPORTED +#define PNG_zTXt_SUPPORTED +/* end of options */ +/* settings */ +#define PNG_API_RULE 0 +#define PNG_COST_SHIFT 3 +#define PNG_DEFAULT_READ_MACROS 1 +#define PNG_GAMMA_THRESHOLD_FIXED 5000 +#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE +#define PNG_INFLATE_BUF_SIZE 1024 +#define PNG_MAX_GAMMA_8 11 +#define PNG_QUANTIZE_BLUE_BITS 5 +#define PNG_QUANTIZE_GREEN_BITS 5 +#define PNG_QUANTIZE_RED_BITS 5 +#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) +#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 +#define PNG_USER_CHUNK_CACHE_MAX 1000 +#define PNG_USER_CHUNK_MALLOC_MAX 8000000 +#define PNG_USER_HEIGHT_MAX 1000000 +#define PNG_USER_WIDTH_MAX 1000000 +#define PNG_WEIGHT_SHIFT 8 +#define PNG_ZBUF_SIZE 8192 +#define PNG_ZLIB_VERNUM 0 /* unknown */ +#define PNG_Z_DEFAULT_COMPRESSION (-1) +#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 +#define PNG_Z_DEFAULT_STRATEGY 1 +#define PNG_sCAL_PRECISION 5 +#define PNG_sRGB_PROFILE_CHECKS 2 +/* end of settings */ +#endif /* PNGLCONF_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/ogg/ogg.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/ogg/ogg.h new file mode 100644 index 00000000..cea4ebed --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/ogg/ogg.h @@ -0,0 +1,210 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $ + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stddef.h> +#include <ogg/os_types.h> + +typedef struct { + void *iov_base; + size_t iov_len; +} ogg_iovec_t; + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern int oggpack_writecheck(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern int oggpackB_writecheck(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, + int count, long e_o_s, ogg_int64_t granulepos); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); +extern int ogg_sync_check(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_check(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(const ogg_page *og); +extern int ogg_page_continued(const ogg_page *og); +extern int ogg_page_bos(const ogg_page *og); +extern int ogg_page_eos(const ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); +extern int ogg_page_serialno(const ogg_page *og); +extern long ogg_page_pageno(const ogg_page *og); +extern int ogg_page_packets(const ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/ogg/os_types.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/ogg/os_types.h new file mode 100644 index 00000000..8bf82107 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/ogg/os_types.h @@ -0,0 +1,147 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 19098 2014-02-26 19:06:45Z giles $ + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <stdint.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# elif defined(__MINGW32__) +# include <sys/types.h> + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include <sys/types.h> + typedef SInt16 ogg_int16_t; + typedef UInt16 ogg_uint16_t; + typedef SInt32 ogg_int32_t; + typedef UInt32 ogg_uint32_t; + typedef SInt64 ogg_int64_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include <inttypes.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined(__HAIKU__) + + /* Haiku */ +# include <sys/types.h> + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include <inttypes.h> + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#elif defined(__TMS320C6X__) + + /* TI C64x compiler */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#else + +# include <ogg/config_types.h> + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/physfs.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/physfs.h new file mode 100644 index 00000000..3c252c6e --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/physfs.h @@ -0,0 +1,2395 @@ +/** + * \file physfs.h + * + * Main header file for PhysicsFS. + */ + +/** + * \mainpage PhysicsFS + * + * The latest version of PhysicsFS can be found at: + * http://icculus.org/physfs/ + * + * PhysicsFS; a portable, flexible file i/o abstraction. + * + * This API gives you access to a system file system in ways superior to the + * stdio or system i/o calls. The brief benefits: + * + * - It's portable. + * - It's safe. No file access is permitted outside the specified dirs. + * - It's flexible. Archives (.ZIP files) can be used transparently as + * directory structures. + * + * This system is largely inspired by Quake 3's PK3 files and the related + * fs_* cvars. If you've ever tinkered with these, then this API will be + * familiar to you. + * + * With PhysicsFS, you have a single writing directory and multiple + * directories (the "search path") for reading. You can think of this as a + * filesystem within a filesystem. If (on Windows) you were to set the + * writing directory to "C:\MyGame\MyWritingDirectory", then no PHYSFS calls + * could touch anything above this directory, including the "C:\MyGame" and + * "C:\" directories. This prevents an application's internal scripting + * language from piddling over c:\\config.sys, for example. If you'd rather + * give PHYSFS full access to the system's REAL file system, set the writing + * dir to "C:\", but that's generally A Bad Thing for several reasons. + * + * Drive letters are hidden in PhysicsFS once you set up your initial paths. + * The search path creates a single, hierarchical directory structure. + * Not only does this lend itself well to general abstraction with archives, + * it also gives better support to operating systems like MacOS and Unix. + * Generally speaking, you shouldn't ever hardcode a drive letter; not only + * does this hurt portability to non-Microsoft OSes, but it limits your win32 + * users to a single drive, too. Use the PhysicsFS abstraction functions and + * allow user-defined configuration options, too. When opening a file, you + * specify it like it was on a Unix filesystem: if you want to write to + * "C:\MyGame\MyConfigFiles\game.cfg", then you might set the write dir to + * "C:\MyGame" and then open "MyConfigFiles/game.cfg". This gives an + * abstraction across all platforms. Specifying a file in this way is termed + * "platform-independent notation" in this documentation. Specifying a + * a filename in a form such as "C:\mydir\myfile" or + * "MacOS hard drive:My Directory:My File" is termed "platform-dependent + * notation". The only time you use platform-dependent notation is when + * setting up your write directory and search path; after that, all file + * access into those directories are done with platform-independent notation. + * + * All files opened for writing are opened in relation to the write directory, + * which is the root of the writable filesystem. When opening a file for + * reading, PhysicsFS goes through the search path. This is NOT the + * same thing as the PATH environment variable. An application using + * PhysicsFS specifies directories to be searched which may be actual + * directories, or archive files that contain files and subdirectories of + * their own. See the end of these docs for currently supported archive + * formats. + * + * Once the search path is defined, you may open files for reading. If you've + * got the following search path defined (to use a win32 example again): + * + * - C:\\mygame + * - C:\\mygame\\myuserfiles + * - D:\\mygamescdromdatafiles + * - C:\\mygame\\installeddatafiles.zip + * + * Then a call to PHYSFS_openRead("textfiles/myfile.txt") (note the directory + * separator, lack of drive letter, and lack of dir separator at the start of + * the string; this is platform-independent notation) will check for + * C:\\mygame\\textfiles\\myfile.txt, then + * C:\\mygame\\myuserfiles\\textfiles\\myfile.txt, then + * D:\\mygamescdromdatafiles\\textfiles\\myfile.txt, then, finally, for + * textfiles\\myfile.txt inside of C:\\mygame\\installeddatafiles.zip. + * Remember that most archive types and platform filesystems store their + * filenames in a case-sensitive manner, so you should be careful to specify + * it correctly. + * + * Files opened through PhysicsFS may NOT contain "." or ".." or ":" as dir + * elements. Not only are these meaningless on MacOS Classic and/or Unix, + * they are a security hole. Also, symbolic links (which can be found in + * some archive types and directly in the filesystem on Unix platforms) are + * NOT followed until you call PHYSFS_permitSymbolicLinks(). That's left to + * your own discretion, as following a symlink can allow for access outside + * the write dir and search paths. For portability, there is no mechanism for + * creating new symlinks in PhysicsFS. + * + * The write dir is not included in the search path unless you specifically + * add it. While you CAN change the write dir as many times as you like, + * you should probably set it once and stick to it. Remember that your + * program will not have permission to write in every directory on Unix and + * NT systems. + * + * All files are opened in binary mode; there is no endline conversion for + * textfiles. Other than that, PhysicsFS has some convenience functions for + * platform-independence. There is a function to tell you the current + * platform's dir separator ("\\" on windows, "/" on Unix, ":" on MacOS), + * which is needed only to set up your search/write paths. There is a + * function to tell you what CD-ROM drives contain accessible discs, and a + * function to recommend a good search path, etc. + * + * A recommended order for the search path is the write dir, then the base dir, + * then the cdrom dir, then any archives discovered. Quake 3 does something + * like this, but moves the archives to the start of the search path. Build + * Engine games, like Duke Nukem 3D and Blood, place the archives last, and + * use the base dir for both searching and writing. There is a helper + * function (PHYSFS_setSaneConfig()) that puts together a basic configuration + * for you, based on a few parameters. Also see the comments on + * PHYSFS_getBaseDir(), and PHYSFS_getUserDir() for info on what those + * are and how they can help you determine an optimal search path. + * + * PhysicsFS 2.0 adds the concept of "mounting" archives to arbitrary points + * in the search path. If a zipfile contains "maps/level.map" and you mount + * that archive at "mods/mymod", then you would have to open + * "mods/mymod/maps/level.map" to access the file, even though "mods/mymod" + * isn't actually specified in the .zip file. Unlike the Unix mentality of + * mounting a filesystem, "mods/mymod" doesn't actually have to exist when + * mounting the zipfile. It's a "virtual" directory. The mounting mechanism + * allows the developer to seperate archives in the tree and avoid trampling + * over files when added new archives, such as including mod support in a + * game...keeping external content on a tight leash in this manner can be of + * utmost importance to some applications. + * + * PhysicsFS is mostly thread safe. The error messages returned by + * PHYSFS_getLastError are unique by thread, and library-state-setting + * functions are mutex'd. For efficiency, individual file accesses are + * not locked, so you can not safely read/write/seek/close/etc the same + * file from two threads at the same time. Other race conditions are bugs + * that should be reported/patched. + * + * While you CAN use stdio/syscall file access in a program that has PHYSFS_* + * calls, doing so is not recommended, and you can not use system + * filehandles with PhysicsFS and vice versa. + * + * Note that archives need not be named as such: if you have a ZIP file and + * rename it with a .PKG extension, the file will still be recognized as a + * ZIP archive by PhysicsFS; the file's contents are used to determine its + * type where possible. + * + * Currently supported archive types: + * - .ZIP (pkZip/WinZip/Info-ZIP compatible) + * - .GRP (Build Engine groupfile archives) + * - .PAK (Quake I/II archive format) + * - .HOG (Descent I/II HOG file archives) + * - .MVL (Descent II movielib archives) + * - .WAD (DOOM engine archives) + * + * + * String policy for PhysicsFS 2.0 and later: + * + * PhysicsFS 1.0 could only deal with null-terminated ASCII strings. All high + * ASCII chars resulted in undefined behaviour, and there was no Unicode + * support at all. PhysicsFS 2.0 supports Unicode without breaking binary + * compatibility with the 1.0 API by using UTF-8 encoding of all strings + * passed in and out of the library. + * + * All strings passed through PhysicsFS are in null-terminated UTF-8 format. + * This means that if all you care about is English (ASCII characters <= 127) + * then you just use regular C strings. If you care about Unicode (and you + * should!) then you need to figure out what your platform wants, needs, and + * offers. If you are on Windows and build with Unicode support, your TCHAR + * strings are two bytes per character (this is called "UCS-2 encoding"). You + * should convert them to UTF-8 before handing them to PhysicsFS with + * PHYSFS_utf8FromUcs2(). If you're using Unix or Mac OS X, your wchar_t + * strings are four bytes per character ("UCS-4 encoding"). Use + * PHYSFS_utf8FromUcs4(). Mac OS X can give you UTF-8 directly from a + * CFString, and many Unixes generally give you C strings in UTF-8 format + * everywhere. If you have a single-byte high ASCII charset, like so-many + * European "codepages" you may be out of luck. We'll convert from "Latin1" + * to UTF-8 only, and never back to Latin1. If you're above ASCII 127, all + * bets are off: move to Unicode or use your platform's facilities. Passing a + * C string with high-ASCII data that isn't UTF-8 encoded will NOT do what + * you expect! + * + * Naturally, there's also PHYSFS_utf8ToUcs2() and PHYSFS_utf8ToUcs4() to get + * data back into a format you like. Behind the scenes, PhysicsFS will use + * Unicode where possible: the UTF-8 strings on Windows will be converted + * and used with the multibyte Windows APIs, for example. + * + * PhysicsFS offers basic encoding conversion support, but not a whole string + * library. Get your stuff into whatever format you can work with. + * + * Some platforms and archivers don't offer full Unicode support behind the + * scenes. For example, OS/2 only offers "codepages" and the filesystem + * itself doesn't support multibyte encodings. We make an earnest effort to + * convert to/from the current locale here, but all bets are off if + * you want to hand an arbitrary Japanese character through to these systems. + * Modern OSes (Mac OS X, Linux, Windows, PocketPC, etc) should all be fine. + * Many game-specific archivers are seriously unprepared for Unicode (the + * Descent HOG/MVL and Build Engine GRP archivers, for example, only offer a + * DOS 8.3 filename, for example). Nothing can be done for these, but they + * tend to be legacy formats for existing content that was all ASCII (and + * thus, valid UTF-8) anyhow. Other formats, like .ZIP, don't explicitly + * offer Unicode support, but unofficially expect filenames to be UTF-8 + * encoded, and thus Just Work. Most everything does the right thing without + * bothering you, but it's good to be aware of these nuances in case they + * don't. + * + * + * Other stuff: + * + * Please see the file LICENSE.txt in the source's root directory for licensing + * and redistribution rights. + * + * Please see the file CREDITS.txt in the source's root directory for a more or + * less complete list of who's responsible for this. + * + * \author Ryan C. Gordon. + */ + +#ifndef _INCLUDE_PHYSFS_H_ +#define _INCLUDE_PHYSFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +#if (defined _MSC_VER) +#define __EXPORT__ __declspec(dllexport) +#elif (__GNUC__ >= 3) +#define __EXPORT__ __attribute__((visibility("default"))) +#else +#define __EXPORT__ +#endif +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ + +/** + * \typedef PHYSFS_uint8 + * \brief An unsigned, 8-bit integer type. + */ +typedef unsigned char PHYSFS_uint8; + +/** + * \typedef PHYSFS_sint8 + * \brief A signed, 8-bit integer type. + */ +typedef signed char PHYSFS_sint8; + +/** + * \typedef PHYSFS_uint16 + * \brief An unsigned, 16-bit integer type. + */ +typedef unsigned short PHYSFS_uint16; + +/** + * \typedef PHYSFS_sint16 + * \brief A signed, 16-bit integer type. + */ +typedef signed short PHYSFS_sint16; + +/** + * \typedef PHYSFS_uint32 + * \brief An unsigned, 32-bit integer type. + */ +typedef unsigned int PHYSFS_uint32; + +/** + * \typedef PHYSFS_sint32 + * \brief A signed, 32-bit integer type. + */ +typedef signed int PHYSFS_sint32; + +/** + * \typedef PHYSFS_uint64 + * \brief An unsigned, 64-bit integer type. + * \warning on platforms without any sort of 64-bit datatype, this is + * equivalent to PHYSFS_uint32! + */ + +/** + * \typedef PHYSFS_sint64 + * \brief A signed, 64-bit integer type. + * \warning on platforms without any sort of 64-bit datatype, this is + * equivalent to PHYSFS_sint32! + */ + + +#if (defined PHYSFS_NO_64BIT_SUPPORT) /* oh well. */ +typedef PHYSFS_uint32 PHYSFS_uint64; +typedef PHYSFS_sint32 PHYSFS_sint64; +#elif (defined _MSC_VER) +typedef signed __int64 PHYSFS_sint64; +typedef unsigned __int64 PHYSFS_uint64; +#else +typedef unsigned long long PHYSFS_uint64; +typedef signed long long PHYSFS_sint64; +#endif + + +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +/* Make sure the types really have the right sizes */ +#define PHYSFS_COMPILE_TIME_ASSERT(name, x) \ + typedef int PHYSFS_dummy_ ## name[(x) * 2 - 1] + +PHYSFS_COMPILE_TIME_ASSERT(uint8, sizeof(PHYSFS_uint8) == 1); +PHYSFS_COMPILE_TIME_ASSERT(sint8, sizeof(PHYSFS_sint8) == 1); +PHYSFS_COMPILE_TIME_ASSERT(uint16, sizeof(PHYSFS_uint16) == 2); +PHYSFS_COMPILE_TIME_ASSERT(sint16, sizeof(PHYSFS_sint16) == 2); +PHYSFS_COMPILE_TIME_ASSERT(uint32, sizeof(PHYSFS_uint32) == 4); +PHYSFS_COMPILE_TIME_ASSERT(sint32, sizeof(PHYSFS_sint32) == 4); + +#ifndef PHYSFS_NO_64BIT_SUPPORT +PHYSFS_COMPILE_TIME_ASSERT(uint64, sizeof(PHYSFS_uint64) == 8); +PHYSFS_COMPILE_TIME_ASSERT(sint64, sizeof(PHYSFS_sint64) == 8); +#endif + +#undef PHYSFS_COMPILE_TIME_ASSERT + +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ + + +/** + * \struct PHYSFS_File + * \brief A PhysicsFS file handle. + * + * You get a pointer to one of these when you open a file for reading, + * writing, or appending via PhysicsFS. + * + * As you can see from the lack of meaningful fields, you should treat this + * as opaque data. Don't try to manipulate the file handle, just pass the + * pointer you got, unmolested, to various PhysicsFS APIs. + * + * \sa PHYSFS_openRead + * \sa PHYSFS_openWrite + * \sa PHYSFS_openAppend + * \sa PHYSFS_close + * \sa PHYSFS_read + * \sa PHYSFS_write + * \sa PHYSFS_seek + * \sa PHYSFS_tell + * \sa PHYSFS_eof + * \sa PHYSFS_setBuffer + * \sa PHYSFS_flush + */ +typedef struct PHYSFS_File +{ + void *opaque; /**< That's all you get. Don't touch. */ +} PHYSFS_File; + + +/** + * \def PHYSFS_file + * \brief 1.0 API compatibility define. + * + * PHYSFS_file is identical to PHYSFS_File. This #define is here for backwards + * compatibility with the 1.0 API, which had an inconsistent capitalization + * convention in this case. New code should use PHYSFS_File, as this #define + * may go away someday. + * + * \sa PHYSFS_File + */ +#define PHYSFS_file PHYSFS_File + + +/** + * \struct PHYSFS_ArchiveInfo + * \brief Information on various PhysicsFS-supported archives. + * + * This structure gives you details on what sort of archives are supported + * by this implementation of PhysicsFS. Archives tend to be things like + * ZIP files and such. + * + * \warning Not all binaries are created equal! PhysicsFS can be built with + * or without support for various archives. You can check with + * PHYSFS_supportedArchiveTypes() to see if your archive type is + * supported. + * + * \sa PHYSFS_supportedArchiveTypes + */ +typedef struct PHYSFS_ArchiveInfo +{ + const char *extension; /**< Archive file extension: "ZIP", for example. */ + const char *description; /**< Human-readable archive description. */ + const char *author; /**< Person who did support for this archive. */ + const char *url; /**< URL related to this archive */ +} PHYSFS_ArchiveInfo; + + +/** + * \struct PHYSFS_Version + * \brief Information the version of PhysicsFS in use. + * + * Represents the library's version as three levels: major revision + * (increments with massive changes, additions, and enhancements), + * minor revision (increments with backwards-compatible changes to the + * major revision), and patchlevel (increments with fixes to the minor + * revision). + * + * \sa PHYSFS_VERSION + * \sa PHYSFS_getLinkedVersion + */ +typedef struct PHYSFS_Version +{ + PHYSFS_uint8 major; /**< major revision */ + PHYSFS_uint8 minor; /**< minor revision */ + PHYSFS_uint8 patch; /**< patchlevel */ +} PHYSFS_Version; + +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +#define PHYSFS_VER_MAJOR 2 +#define PHYSFS_VER_MINOR 0 +#define PHYSFS_VER_PATCH 3 +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ + + +/* PhysicsFS state stuff ... */ + +/** + * \def PHYSFS_VERSION(x) + * \brief Macro to determine PhysicsFS version program was compiled against. + * + * This macro fills in a PHYSFS_Version structure with the version of the + * library you compiled against. This is determined by what header the + * compiler uses. Note that if you dynamically linked the library, you might + * have a slightly newer or older version at runtime. That version can be + * determined with PHYSFS_getLinkedVersion(), which, unlike PHYSFS_VERSION, + * is not a macro. + * + * \param x A pointer to a PHYSFS_Version struct to initialize. + * + * \sa PHYSFS_Version + * \sa PHYSFS_getLinkedVersion + */ +#define PHYSFS_VERSION(x) \ +{ \ + (x)->major = PHYSFS_VER_MAJOR; \ + (x)->minor = PHYSFS_VER_MINOR; \ + (x)->patch = PHYSFS_VER_PATCH; \ +} + + +/** + * \fn void PHYSFS_getLinkedVersion(PHYSFS_Version *ver) + * \brief Get the version of PhysicsFS that is linked against your program. + * + * If you are using a shared library (DLL) version of PhysFS, then it is + * possible that it will be different than the version you compiled against. + * + * This is a real function; the macro PHYSFS_VERSION tells you what version + * of PhysFS you compiled against: + * + * \code + * PHYSFS_Version compiled; + * PHYSFS_Version linked; + * + * PHYSFS_VERSION(&compiled); + * PHYSFS_getLinkedVersion(&linked); + * printf("We compiled against PhysFS version %d.%d.%d ...\n", + * compiled.major, compiled.minor, compiled.patch); + * printf("But we linked against PhysFS version %d.%d.%d.\n", + * linked.major, linked.minor, linked.patch); + * \endcode + * + * This function may be called safely at any time, even before PHYSFS_init(). + * + * \sa PHYSFS_VERSION + */ +__EXPORT__ void PHYSFS_getLinkedVersion(PHYSFS_Version *ver); + + +/** + * \fn int PHYSFS_init(const char *argv0) + * \brief Initialize the PhysicsFS library. + * + * This must be called before any other PhysicsFS function. + * + * This should be called prior to any attempts to change your process's + * current working directory. + * + * \param argv0 the argv[0] string passed to your program's mainline. + * This may be NULL on most platforms (such as ones without a + * standard main() function), but you should always try to pass + * something in here. Unix-like systems such as Linux _need_ to + * pass argv[0] from main() in here. + * \return nonzero on success, zero on error. Specifics of the error can be + * gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_deinit + * \sa PHYSFS_isInit + */ +__EXPORT__ int PHYSFS_init(const char *argv0); + + +/** + * \fn int PHYSFS_deinit(void) + * \brief Deinitialize the PhysicsFS library. + * + * This closes any files opened via PhysicsFS, blanks the search/write paths, + * frees memory, and invalidates all of your file handles. + * + * Note that this call can FAIL if there's a file open for writing that + * refuses to close (for example, the underlying operating system was + * buffering writes to network filesystem, and the fileserver has crashed, + * or a hard drive has failed, etc). It is usually best to close all write + * handles yourself before calling this function, so that you can gracefully + * handle a specific failure. + * + * Once successfully deinitialized, PHYSFS_init() can be called again to + * restart the subsystem. All default API states are restored at this + * point, with the exception of any custom allocator you might have + * specified, which survives between initializations. + * + * \return nonzero on success, zero on error. Specifics of the error can be + * gleaned from PHYSFS_getLastError(). If failure, state of PhysFS is + * undefined, and probably badly screwed up. + * + * \sa PHYSFS_init + * \sa PHYSFS_isInit + */ +__EXPORT__ int PHYSFS_deinit(void); + + +/** + * \fn const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void) + * \brief Get a list of supported archive types. + * + * Get a list of archive types supported by this implementation of PhysicFS. + * These are the file formats usable for search path entries. This is for + * informational purposes only. Note that the extension listed is merely + * convention: if we list "ZIP", you can open a PkZip-compatible archive + * with an extension of "XYZ", if you like. + * + * The returned value is an array of pointers to PHYSFS_ArchiveInfo structures, + * with a NULL entry to signify the end of the list: + * + * \code + * PHYSFS_ArchiveInfo **i; + * + * for (i = PHYSFS_supportedArchiveTypes(); *i != NULL; i++) + * { + * printf("Supported archive: [%s], which is [%s].\n", + * (*i)->extension, (*i)->description); + * } + * \endcode + * + * The return values are pointers to static internal memory, and should + * be considered READ ONLY, and never freed. + * + * \return READ ONLY Null-terminated array of READ ONLY structures. + */ +__EXPORT__ const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void); + + +/** + * \fn void PHYSFS_freeList(void *listVar) + * \brief Deallocate resources of lists returned by PhysicsFS. + * + * Certain PhysicsFS functions return lists of information that are + * dynamically allocated. Use this function to free those resources. + * + * \param listVar List of information specified as freeable by this function. + * + * \sa PHYSFS_getCdRomDirs + * \sa PHYSFS_enumerateFiles + * \sa PHYSFS_getSearchPath + */ +__EXPORT__ void PHYSFS_freeList(void *listVar); + + +/** + * \fn const char *PHYSFS_getLastError(void) + * \brief Get human-readable error information. + * + * Get the last PhysicsFS error message as a human-readable, null-terminated + * string. This will be NULL if there's been no error since the last call to + * this function. The pointer returned by this call points to an internal + * buffer. Each thread has a unique error state associated with it, but each + * time a new error message is set, it will overwrite the previous one + * associated with that thread. It is safe to call this function at anytime, + * even before PHYSFS_init(). + * + * It is not wise to expect a specific string of characters here, since the + * error message may be localized into an unfamiliar language. These strings + * are meant to be passed on directly to the user. + * + * \return READ ONLY string of last error message. + */ +__EXPORT__ const char *PHYSFS_getLastError(void); + + +/** + * \fn const char *PHYSFS_getDirSeparator(void) + * \brief Get platform-dependent dir separator string. + * + * This returns "\\" on win32, "/" on Unix, and ":" on MacOS. It may be more + * than one character, depending on the platform, and your code should take + * that into account. Note that this is only useful for setting up the + * search/write paths, since access into those dirs always use '/' + * (platform-independent notation) to separate directories. This is also + * handy for getting platform-independent access when using stdio calls. + * + * \return READ ONLY null-terminated string of platform's dir separator. + */ +__EXPORT__ const char *PHYSFS_getDirSeparator(void); + + +/** + * \fn void PHYSFS_permitSymbolicLinks(int allow) + * \brief Enable or disable following of symbolic links. + * + * Some physical filesystems and archives contain files that are just pointers + * to other files. On the physical filesystem, opening such a link will + * (transparently) open the file that is pointed to. + * + * By default, PhysicsFS will check if a file is really a symlink during open + * calls and fail if it is. Otherwise, the link could take you outside the + * write and search paths, and compromise security. + * + * If you want to take that risk, call this function with a non-zero parameter. + * Note that this is more for sandboxing a program's scripting language, in + * case untrusted scripts try to compromise the system. Generally speaking, + * a user could very well have a legitimate reason to set up a symlink, so + * unless you feel there's a specific danger in allowing them, you should + * permit them. + * + * Symlinks are only explicitly checked when dealing with filenames + * in platform-independent notation. That is, when setting up your + * search and write paths, etc, symlinks are never checked for. + * + * Symbolic link permission can be enabled or disabled at any time after + * you've called PHYSFS_init(), and is disabled by default. + * + * \param allow nonzero to permit symlinks, zero to deny linking. + * + * \sa PHYSFS_symbolicLinksPermitted + */ +__EXPORT__ void PHYSFS_permitSymbolicLinks(int allow); + + +/* !!! FIXME: const this? */ +/** + * \fn char **PHYSFS_getCdRomDirs(void) + * \brief Get an array of paths to available CD-ROM drives. + * + * The dirs returned are platform-dependent ("D:\" on Win32, "/cdrom" or + * whatnot on Unix). Dirs are only returned if there is a disc ready and + * accessible in the drive. So if you've got two drives (D: and E:), and only + * E: has a disc in it, then that's all you get. If the user inserts a disc + * in D: and you call this function again, you get both drives. If, on a + * Unix box, the user unmounts a disc and remounts it elsewhere, the next + * call to this function will reflect that change. + * + * This function refers to "CD-ROM" media, but it really means "inserted disc + * media," such as DVD-ROM, HD-DVD, CDRW, and Blu-Ray discs. It looks for + * filesystems, and as such won't report an audio CD, unless there's a + * mounted filesystem track on it. + * + * The returned value is an array of strings, with a NULL entry to signify the + * end of the list: + * + * \code + * char **cds = PHYSFS_getCdRomDirs(); + * char **i; + * + * for (i = cds; *i != NULL; i++) + * printf("cdrom dir [%s] is available.\n", *i); + * + * PHYSFS_freeList(cds); + * \endcode + * + * This call may block while drives spin up. Be forewarned. + * + * When you are done with the returned information, you may dispose of the + * resources by calling PHYSFS_freeList() with the returned pointer. + * + * \return Null-terminated array of null-terminated strings. + * + * \sa PHYSFS_getCdRomDirsCallback + */ +__EXPORT__ char **PHYSFS_getCdRomDirs(void); + + +/** + * \fn const char *PHYSFS_getBaseDir(void) + * \brief Get the path where the application resides. + * + * Helper function. + * + * Get the "base dir". This is the directory where the application was run + * from, which is probably the installation directory, and may or may not + * be the process's current working directory. + * + * You should probably use the base dir in your search path. + * + * \return READ ONLY string of base dir in platform-dependent notation. + * + * \sa PHYSFS_getUserDir + */ +__EXPORT__ const char *PHYSFS_getBaseDir(void); + + +/** + * \fn const char *PHYSFS_getUserDir(void) + * \brief Get the path where user's home directory resides. + * + * Helper function. + * + * Get the "user dir". This is meant to be a suggestion of where a specific + * user of the system can store files. On Unix, this is her home directory. + * On systems with no concept of multiple home directories (MacOS, win95), + * this will default to something like "C:\mybasedir\users\username" + * where "username" will either be the login name, or "default" if the + * platform doesn't support multiple users, either. + * + * You should probably use the user dir as the basis for your write dir, and + * also put it near the beginning of your search path. + * + * \return READ ONLY string of user dir in platform-dependent notation. + * + * \sa PHYSFS_getBaseDir + */ +__EXPORT__ const char *PHYSFS_getUserDir(void); + + +/** + * \fn const char *PHYSFS_getWriteDir(void) + * \brief Get path where PhysicsFS will allow file writing. + * + * Get the current write dir. The default write dir is NULL. + * + * \return READ ONLY string of write dir in platform-dependent notation, + * OR NULL IF NO WRITE PATH IS CURRENTLY SET. + * + * \sa PHYSFS_setWriteDir + */ +__EXPORT__ const char *PHYSFS_getWriteDir(void); + + +/** + * \fn int PHYSFS_setWriteDir(const char *newDir) + * \brief Tell PhysicsFS where it may write files. + * + * Set a new write dir. This will override the previous setting. + * + * This call will fail (and fail to change the write dir) if the current + * write dir still has files open in it. + * + * \param newDir The new directory to be the root of the write dir, + * specified in platform-dependent notation. Setting to NULL + * disables the write dir, so no files can be opened for + * writing via PhysicsFS. + * \return non-zero on success, zero on failure. All attempts to open a file + * for writing via PhysicsFS will fail until this call succeeds. + * Specifics of the error can be gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_getWriteDir + */ +__EXPORT__ int PHYSFS_setWriteDir(const char *newDir); + + +/** + * \fn int PHYSFS_addToSearchPath(const char *newDir, int appendToPath) + * \brief Add an archive or directory to the search path. + * + * This is a legacy call in PhysicsFS 2.0, equivalent to: + * PHYSFS_mount(newDir, NULL, appendToPath); + * + * You must use this and not PHYSFS_mount if binary compatibility with + * PhysicsFS 1.0 is important (which it may not be for many people). + * + * \sa PHYSFS_mount + * \sa PHYSFS_removeFromSearchPath + * \sa PHYSFS_getSearchPath + */ +__EXPORT__ int PHYSFS_addToSearchPath(const char *newDir, int appendToPath); + + +/** + * \fn int PHYSFS_removeFromSearchPath(const char *oldDir) + * \brief Remove a directory or archive from the search path. + * + * This must be a (case-sensitive) match to a dir or archive already in the + * search path, specified in platform-dependent notation. + * + * This call will fail (and fail to remove from the path) if the element still + * has files open in it. + * + * \param oldDir dir/archive to remove. + * \return nonzero on success, zero on failure. + * Specifics of the error can be gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_addToSearchPath + * \sa PHYSFS_getSearchPath + */ +__EXPORT__ int PHYSFS_removeFromSearchPath(const char *oldDir); + + +/** + * \fn char **PHYSFS_getSearchPath(void) + * \brief Get the current search path. + * + * The default search path is an empty list. + * + * The returned value is an array of strings, with a NULL entry to signify the + * end of the list: + * + * \code + * char **i; + * + * for (i = PHYSFS_getSearchPath(); *i != NULL; i++) + * printf("[%s] is in the search path.\n", *i); + * \endcode + * + * When you are done with the returned information, you may dispose of the + * resources by calling PHYSFS_freeList() with the returned pointer. + * + * \return Null-terminated array of null-terminated strings. NULL if there + * was a problem (read: OUT OF MEMORY). + * + * \sa PHYSFS_getSearchPathCallback + * \sa PHYSFS_addToSearchPath + * \sa PHYSFS_removeFromSearchPath + */ +__EXPORT__ char **PHYSFS_getSearchPath(void); + + +/** + * \fn int PHYSFS_setSaneConfig(const char *organization, const char *appName, const char *archiveExt, int includeCdRoms, int archivesFirst) + * \brief Set up sane, default paths. + * + * Helper function. + * + * The write dir will be set to "userdir/.organization/appName", which is + * created if it doesn't exist. + * + * The above is sufficient to make sure your program's configuration directory + * is separated from other clutter, and platform-independent. The period + * before "mygame" even hides the directory on Unix systems. + * + * The search path will be: + * + * - The Write Dir (created if it doesn't exist) + * - The Base Dir (PHYSFS_getBaseDir()) + * - All found CD-ROM dirs (optionally) + * + * These directories are then searched for files ending with the extension + * (archiveExt), which, if they are valid and supported archives, will also + * be added to the search path. If you specified "PKG" for (archiveExt), and + * there's a file named data.PKG in the base dir, it'll be checked. Archives + * can either be appended or prepended to the search path in alphabetical + * order, regardless of which directories they were found in. + * + * All of this can be accomplished from the application, but this just does it + * all for you. Feel free to add more to the search path manually, too. + * + * \param organization Name of your company/group/etc to be used as a + * dirname, so keep it small, and no-frills. + * + * \param appName Program-specific name of your program, to separate it + * from other programs using PhysicsFS. + * + * \param archiveExt File extension used by your program to specify an + * archive. For example, Quake 3 uses "pk3", even though + * they are just zipfiles. Specify NULL to not dig out + * archives automatically. Do not specify the '.' char; + * If you want to look for ZIP files, specify "ZIP" and + * not ".ZIP" ... the archive search is case-insensitive. + * + * \param includeCdRoms Non-zero to include CD-ROMs in the search path, and + * (if (archiveExt) != NULL) search them for archives. + * This may cause a significant amount of blocking + * while discs are accessed, and if there are no discs + * in the drive (or even not mounted on Unix systems), + * then they may not be made available anyhow. You may + * want to specify zero and handle the disc setup + * yourself. + * + * \param archivesFirst Non-zero to prepend the archives to the search path. + * Zero to append them. Ignored if !(archiveExt). + * + * \return nonzero on success, zero on error. Specifics of the error can be + * gleaned from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_setSaneConfig(const char *organization, + const char *appName, + const char *archiveExt, + int includeCdRoms, + int archivesFirst); + + +/* Directory management stuff ... */ + +/** + * \fn int PHYSFS_mkdir(const char *dirName) + * \brief Create a directory. + * + * This is specified in platform-independent notation in relation to the + * write dir. All missing parent directories are also created if they + * don't exist. + * + * So if you've got the write dir set to "C:\mygame\writedir" and call + * PHYSFS_mkdir("downloads/maps") then the directories + * "C:\mygame\writedir\downloads" and "C:\mygame\writedir\downloads\maps" + * will be created if possible. If the creation of "maps" fails after we + * have successfully created "downloads", then the function leaves the + * created directory behind and reports failure. + * + * \param dirName New dir to create. + * \return nonzero on success, zero on error. Specifics of the error can be + * gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_delete + */ +__EXPORT__ int PHYSFS_mkdir(const char *dirName); + + +/** + * \fn int PHYSFS_delete(const char *filename) + * \brief Delete a file or directory. + * + * (filename) is specified in platform-independent notation in relation to the + * write dir. + * + * A directory must be empty before this call can delete it. + * + * Deleting a symlink will remove the link, not what it points to, regardless + * of whether you "permitSymLinks" or not. + * + * So if you've got the write dir set to "C:\mygame\writedir" and call + * PHYSFS_delete("downloads/maps/level1.map") then the file + * "C:\mygame\writedir\downloads\maps\level1.map" is removed from the + * physical filesystem, if it exists and the operating system permits the + * deletion. + * + * Note that on Unix systems, deleting a file may be successful, but the + * actual file won't be removed until all processes that have an open + * filehandle to it (including your program) close their handles. + * + * Chances are, the bits that make up the file still exist, they are just + * made available to be written over at a later point. Don't consider this + * a security method or anything. :) + * + * \param filename Filename to delete. + * \return nonzero on success, zero on error. Specifics of the error can be + * gleaned from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_delete(const char *filename); + + +/** + * \fn const char *PHYSFS_getRealDir(const char *filename) + * \brief Figure out where in the search path a file resides. + * + * The file is specified in platform-independent notation. The returned + * filename will be the element of the search path where the file was found, + * which may be a directory, or an archive. Even if there are multiple + * matches in different parts of the search path, only the first one found + * is used, just like when opening a file. + * + * So, if you look for "maps/level1.map", and C:\\mygame is in your search + * path and C:\\mygame\\maps\\level1.map exists, then "C:\mygame" is returned. + * + * If a any part of a match is a symbolic link, and you've not explicitly + * permitted symlinks, then it will be ignored, and the search for a match + * will continue. + * + * If you specify a fake directory that only exists as a mount point, it'll + * be associated with the first archive mounted there, even though that + * directory isn't necessarily contained in a real archive. + * + * \param filename file to look for. + * \return READ ONLY string of element of search path containing the + * the file in question. NULL if not found. + */ +__EXPORT__ const char *PHYSFS_getRealDir(const char *filename); + + +/** + * \fn char **PHYSFS_enumerateFiles(const char *dir) + * \brief Get a file listing of a search path's directory. + * + * Matching directories are interpolated. That is, if "C:\mydir" is in the + * search path and contains a directory "savegames" that contains "x.sav", + * "y.sav", and "z.sav", and there is also a "C:\userdir" in the search path + * that has a "savegames" subdirectory with "w.sav", then the following code: + * + * \code + * char **rc = PHYSFS_enumerateFiles("savegames"); + * char **i; + * + * for (i = rc; *i != NULL; i++) + * printf(" * We've got [%s].\n", *i); + * + * PHYSFS_freeList(rc); + * \endcode + * + * \...will print: + * + * \verbatim + * We've got [x.sav]. + * We've got [y.sav]. + * We've got [z.sav]. + * We've got [w.sav].\endverbatim + * + * Feel free to sort the list however you like. We only promise there will + * be no duplicates, but not what order the final list will come back in. + * + * Don't forget to call PHYSFS_freeList() with the return value from this + * function when you are done with it. + * + * \param dir directory in platform-independent notation to enumerate. + * \return Null-terminated array of null-terminated strings. + * + * \sa PHYSFS_enumerateFilesCallback + */ +__EXPORT__ char **PHYSFS_enumerateFiles(const char *dir); + + +/** + * \fn int PHYSFS_exists(const char *fname) + * \brief Determine if a file exists in the search path. + * + * Reports true if there is an entry anywhere in the search path by the + * name of (fname). + * + * Note that entries that are symlinks are ignored if + * PHYSFS_permitSymbolicLinks(1) hasn't been called, so you + * might end up further down in the search path than expected. + * + * \param fname filename in platform-independent notation. + * \return non-zero if filename exists. zero otherwise. + * + * \sa PHYSFS_isDirectory + * \sa PHYSFS_isSymbolicLink + */ +__EXPORT__ int PHYSFS_exists(const char *fname); + + +/** + * \fn int PHYSFS_isDirectory(const char *fname) + * \brief Determine if a file in the search path is really a directory. + * + * Determine if the first occurence of (fname) in the search path is + * really a directory entry. + * + * Note that entries that are symlinks are ignored if + * PHYSFS_permitSymbolicLinks(1) hasn't been called, so you + * might end up further down in the search path than expected. + * + * \param fname filename in platform-independent notation. + * \return non-zero if filename exists and is a directory. zero otherwise. + * + * \sa PHYSFS_exists + * \sa PHYSFS_isSymbolicLink + */ +__EXPORT__ int PHYSFS_isDirectory(const char *fname); + + +/** + * \fn int PHYSFS_isSymbolicLink(const char *fname) + * \brief Determine if a file in the search path is really a symbolic link. + * + * Determine if the first occurence of (fname) in the search path is + * really a symbolic link. + * + * Note that entries that are symlinks are ignored if + * PHYSFS_permitSymbolicLinks(1) hasn't been called, and as such, + * this function will always return 0 in that case. + * + * \param fname filename in platform-independent notation. + * \return non-zero if filename exists and is a symlink. zero otherwise. + * + * \sa PHYSFS_exists + * \sa PHYSFS_isDirectory + */ +__EXPORT__ int PHYSFS_isSymbolicLink(const char *fname); + + +/** + * \fn PHYSFS_sint64 PHYSFS_getLastModTime(const char *filename) + * \brief Get the last modification time of a file. + * + * The modtime is returned as a number of seconds since the epoch + * (Jan 1, 1970). The exact derivation and accuracy of this time depends on + * the particular archiver. If there is no reasonable way to obtain this + * information for a particular archiver, or there was some sort of error, + * this function returns (-1). + * + * \param filename filename to check, in platform-independent notation. + * \return last modified time of the file. -1 if it can't be determined. + */ +__EXPORT__ PHYSFS_sint64 PHYSFS_getLastModTime(const char *filename); + + +/* i/o stuff... */ + +/** + * \fn PHYSFS_File *PHYSFS_openWrite(const char *filename) + * \brief Open a file for writing. + * + * Open a file for writing, in platform-independent notation and in relation + * to the write dir as the root of the writable filesystem. The specified + * file is created if it doesn't exist. If it does exist, it is truncated to + * zero bytes, and the writing offset is set to the start. + * + * Note that entries that are symlinks are ignored if + * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a + * symlink with this function will fail in such a case. + * + * \param filename File to open. + * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics + * of the error can be gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_openRead + * \sa PHYSFS_openAppend + * \sa PHYSFS_write + * \sa PHYSFS_close + */ +__EXPORT__ PHYSFS_File *PHYSFS_openWrite(const char *filename); + + +/** + * \fn PHYSFS_File *PHYSFS_openAppend(const char *filename) + * \brief Open a file for appending. + * + * Open a file for writing, in platform-independent notation and in relation + * to the write dir as the root of the writable filesystem. The specified + * file is created if it doesn't exist. If it does exist, the writing offset + * is set to the end of the file, so the first write will be the byte after + * the end. + * + * Note that entries that are symlinks are ignored if + * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a + * symlink with this function will fail in such a case. + * + * \param filename File to open. + * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics + * of the error can be gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_openRead + * \sa PHYSFS_openWrite + * \sa PHYSFS_write + * \sa PHYSFS_close + */ +__EXPORT__ PHYSFS_File *PHYSFS_openAppend(const char *filename); + + +/** + * \fn PHYSFS_File *PHYSFS_openRead(const char *filename) + * \brief Open a file for reading. + * + * Open a file for reading, in platform-independent notation. The search path + * is checked one at a time until a matching file is found, in which case an + * abstract filehandle is associated with it, and reading may be done. + * The reading offset is set to the first byte of the file. + * + * Note that entries that are symlinks are ignored if + * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a + * symlink with this function will fail in such a case. + * + * \param filename File to open. + * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics + * of the error can be gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_openWrite + * \sa PHYSFS_openAppend + * \sa PHYSFS_read + * \sa PHYSFS_close + */ +__EXPORT__ PHYSFS_File *PHYSFS_openRead(const char *filename); + + +/** + * \fn int PHYSFS_close(PHYSFS_File *handle) + * \brief Close a PhysicsFS filehandle. + * + * This call is capable of failing if the operating system was buffering + * writes to the physical media, and, now forced to write those changes to + * physical media, can not store the data for some reason. In such a case, + * the filehandle stays open. A well-written program should ALWAYS check the + * return value from the close call in addition to every writing call! + * + * \param handle handle returned from PHYSFS_open*(). + * \return nonzero on success, zero on error. Specifics of the error can be + * gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_openRead + * \sa PHYSFS_openWrite + * \sa PHYSFS_openAppend + */ +__EXPORT__ int PHYSFS_close(PHYSFS_File *handle); + + +/** + * \fn PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) + * \brief Read data from a PhysicsFS filehandle + * + * The file must be opened for reading. + * + * \param handle handle returned from PHYSFS_openRead(). + * \param buffer buffer to store read data into. + * \param objSize size in bytes of objects being read from (handle). + * \param objCount number of (objSize) objects to read from (handle). + * \return number of objects read. PHYSFS_getLastError() can shed light on + * the reason this might be < (objCount), as can PHYSFS_eof(). + * -1 if complete failure. + * + * \sa PHYSFS_eof + */ +__EXPORT__ PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle, + void *buffer, + PHYSFS_uint32 objSize, + PHYSFS_uint32 objCount); + +/** + * \fn PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, const void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) + * \brief Write data to a PhysicsFS filehandle + * + * The file must be opened for writing. + * + * \param handle retval from PHYSFS_openWrite() or PHYSFS_openAppend(). + * \param buffer buffer of bytes to write to (handle). + * \param objSize size in bytes of objects being written to (handle). + * \param objCount number of (objSize) objects to write to (handle). + * \return number of objects written. PHYSFS_getLastError() can shed light on + * the reason this might be < (objCount). -1 if complete failure. + */ +__EXPORT__ PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, + const void *buffer, + PHYSFS_uint32 objSize, + PHYSFS_uint32 objCount); + + +/* File position stuff... */ + +/** + * \fn int PHYSFS_eof(PHYSFS_File *handle) + * \brief Check for end-of-file state on a PhysicsFS filehandle. + * + * Determine if the end of file has been reached in a PhysicsFS filehandle. + * + * \param handle handle returned from PHYSFS_openRead(). + * \return nonzero if EOF, zero if not. + * + * \sa PHYSFS_read + * \sa PHYSFS_tell + */ +__EXPORT__ int PHYSFS_eof(PHYSFS_File *handle); + + +/** + * \fn PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle) + * \brief Determine current position within a PhysicsFS filehandle. + * + * \param handle handle returned from PHYSFS_open*(). + * \return offset in bytes from start of file. -1 if error occurred. + * Specifics of the error can be gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_seek + */ +__EXPORT__ PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle); + + +/** + * \fn int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos) + * \brief Seek to a new position within a PhysicsFS filehandle. + * + * The next read or write will occur at that place. Seeking past the + * beginning or end of the file is not allowed, and causes an error. + * + * \param handle handle returned from PHYSFS_open*(). + * \param pos number of bytes from start of file to seek to. + * \return nonzero on success, zero on error. Specifics of the error can be + * gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_tell + */ +__EXPORT__ int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos); + + +/** + * \fn PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle) + * \brief Get total length of a file in bytes. + * + * Note that if the file size can't be determined (since the archive is + * "streamed" or whatnot) than this will report (-1). Also note that if + * another process/thread is writing to this file at the same time, then + * the information this function supplies could be incorrect before you + * get it. Use with caution, or better yet, don't use at all. + * + * \param handle handle returned from PHYSFS_open*(). + * \return size in bytes of the file. -1 if can't be determined. + * + * \sa PHYSFS_tell + * \sa PHYSFS_seek + */ +__EXPORT__ PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle); + + +/* Buffering stuff... */ + +/** + * \fn int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 bufsize) + * \brief Set up buffering for a PhysicsFS file handle. + * + * Define an i/o buffer for a file handle. A memory block of (bufsize) bytes + * will be allocated and associated with (handle). + * + * For files opened for reading, up to (bufsize) bytes are read from (handle) + * and stored in the internal buffer. Calls to PHYSFS_read() will pull + * from this buffer until it is empty, and then refill it for more reading. + * Note that compressed files, like ZIP archives, will decompress while + * buffering, so this can be handy for offsetting CPU-intensive operations. + * The buffer isn't filled until you do your next read. + * + * For files opened for writing, data will be buffered to memory until the + * buffer is full or the buffer is flushed. Closing a handle implicitly + * causes a flush...check your return values! + * + * Seeking, etc transparently accounts for buffering. + * + * You can resize an existing buffer by calling this function more than once + * on the same file. Setting the buffer size to zero will free an existing + * buffer. + * + * PhysicsFS file handles are unbuffered by default. + * + * Please check the return value of this function! Failures can include + * not being able to seek backwards in a read-only file when removing the + * buffer, not being able to allocate the buffer, and not being able to + * flush the buffer to disk, among other unexpected problems. + * + * \param handle handle returned from PHYSFS_open*(). + * \param bufsize size, in bytes, of buffer to allocate. + * \return nonzero if successful, zero on error. + * + * \sa PHYSFS_flush + * \sa PHYSFS_read + * \sa PHYSFS_write + * \sa PHYSFS_close + */ +__EXPORT__ int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 bufsize); + + +/** + * \fn int PHYSFS_flush(PHYSFS_File *handle) + * \brief Flush a buffered PhysicsFS file handle. + * + * For buffered files opened for writing, this will put the current contents + * of the buffer to disk and flag the buffer as empty if possible. + * + * For buffered files opened for reading or unbuffered files, this is a safe + * no-op, and will report success. + * + * \param handle handle returned from PHYSFS_open*(). + * \return nonzero if successful, zero on error. + * + * \sa PHYSFS_setBuffer + * \sa PHYSFS_close + */ +__EXPORT__ int PHYSFS_flush(PHYSFS_File *handle); + + +/* Byteorder stuff... */ + +/** + * \fn PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 val) + * \brief Swap littleendian signed 16 to platform's native byte order. + * + * Take a 16-bit signed value in littleendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + */ +__EXPORT__ PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 val); + + +/** + * \fn PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 val) + * \brief Swap littleendian unsigned 16 to platform's native byte order. + * + * Take a 16-bit unsigned value in littleendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + */ +__EXPORT__ PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 val); + +/** + * \fn PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 val) + * \brief Swap littleendian signed 32 to platform's native byte order. + * + * Take a 32-bit signed value in littleendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + */ +__EXPORT__ PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 val); + + +/** + * \fn PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 val) + * \brief Swap littleendian unsigned 32 to platform's native byte order. + * + * Take a 32-bit unsigned value in littleendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + */ +__EXPORT__ PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 val); + +/** + * \fn PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 val) + * \brief Swap littleendian signed 64 to platform's native byte order. + * + * Take a 64-bit signed value in littleendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 val); + + +/** + * \fn PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 val) + * \brief Swap littleendian unsigned 64 to platform's native byte order. + * + * Take a 64-bit unsigned value in littleendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 val); + + +/** + * \fn PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 val) + * \brief Swap bigendian signed 16 to platform's native byte order. + * + * Take a 16-bit signed value in bigendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + */ +__EXPORT__ PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 val); + + +/** + * \fn PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 val) + * \brief Swap bigendian unsigned 16 to platform's native byte order. + * + * Take a 16-bit unsigned value in bigendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + */ +__EXPORT__ PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 val); + +/** + * \fn PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 val) + * \brief Swap bigendian signed 32 to platform's native byte order. + * + * Take a 32-bit signed value in bigendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + */ +__EXPORT__ PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 val); + + +/** + * \fn PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 val) + * \brief Swap bigendian unsigned 32 to platform's native byte order. + * + * Take a 32-bit unsigned value in bigendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + */ +__EXPORT__ PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 val); + + +/** + * \fn PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 val) + * \brief Swap bigendian signed 64 to platform's native byte order. + * + * Take a 64-bit signed value in bigendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 val); + + +/** + * \fn PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 val) + * \brief Swap bigendian unsigned 64 to platform's native byte order. + * + * Take a 64-bit unsigned value in bigendian format and convert it to + * the platform's native byte order. + * + * \param val value to convert + * \return converted value. + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 val); + + +/** + * \fn int PHYSFS_readSLE16(PHYSFS_File *file, PHYSFS_sint16 *val) + * \brief Read and convert a signed 16-bit littleendian value. + * + * Convenience function. Read a signed 16-bit littleendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_readSLE16(PHYSFS_File *file, PHYSFS_sint16 *val); + + +/** + * \fn int PHYSFS_readULE16(PHYSFS_File *file, PHYSFS_uint16 *val) + * \brief Read and convert an unsigned 16-bit littleendian value. + * + * Convenience function. Read an unsigned 16-bit littleendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + * + */ +__EXPORT__ int PHYSFS_readULE16(PHYSFS_File *file, PHYSFS_uint16 *val); + + +/** + * \fn int PHYSFS_readSBE16(PHYSFS_File *file, PHYSFS_sint16 *val) + * \brief Read and convert a signed 16-bit bigendian value. + * + * Convenience function. Read a signed 16-bit bigendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_readSBE16(PHYSFS_File *file, PHYSFS_sint16 *val); + + +/** + * \fn int PHYSFS_readUBE16(PHYSFS_File *file, PHYSFS_uint16 *val) + * \brief Read and convert an unsigned 16-bit bigendian value. + * + * Convenience function. Read an unsigned 16-bit bigendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + * + */ +__EXPORT__ int PHYSFS_readUBE16(PHYSFS_File *file, PHYSFS_uint16 *val); + + +/** + * \fn int PHYSFS_readSLE32(PHYSFS_File *file, PHYSFS_sint32 *val) + * \brief Read and convert a signed 32-bit littleendian value. + * + * Convenience function. Read a signed 32-bit littleendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_readSLE32(PHYSFS_File *file, PHYSFS_sint32 *val); + + +/** + * \fn int PHYSFS_readULE32(PHYSFS_File *file, PHYSFS_uint32 *val) + * \brief Read and convert an unsigned 32-bit littleendian value. + * + * Convenience function. Read an unsigned 32-bit littleendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + * + */ +__EXPORT__ int PHYSFS_readULE32(PHYSFS_File *file, PHYSFS_uint32 *val); + + +/** + * \fn int PHYSFS_readSBE32(PHYSFS_File *file, PHYSFS_sint32 *val) + * \brief Read and convert a signed 32-bit bigendian value. + * + * Convenience function. Read a signed 32-bit bigendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_readSBE32(PHYSFS_File *file, PHYSFS_sint32 *val); + + +/** + * \fn int PHYSFS_readUBE32(PHYSFS_File *file, PHYSFS_uint32 *val) + * \brief Read and convert an unsigned 32-bit bigendian value. + * + * Convenience function. Read an unsigned 32-bit bigendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + * + */ +__EXPORT__ int PHYSFS_readUBE32(PHYSFS_File *file, PHYSFS_uint32 *val); + + +/** + * \fn int PHYSFS_readSLE64(PHYSFS_File *file, PHYSFS_sint64 *val) + * \brief Read and convert a signed 64-bit littleendian value. + * + * Convenience function. Read a signed 64-bit littleendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + * + * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ int PHYSFS_readSLE64(PHYSFS_File *file, PHYSFS_sint64 *val); + + +/** + * \fn int PHYSFS_readULE64(PHYSFS_File *file, PHYSFS_uint64 *val) + * \brief Read and convert an unsigned 64-bit littleendian value. + * + * Convenience function. Read an unsigned 64-bit littleendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ int PHYSFS_readULE64(PHYSFS_File *file, PHYSFS_uint64 *val); + + +/** + * \fn int PHYSFS_readSBE64(PHYSFS_File *file, PHYSFS_sint64 *val) + * \brief Read and convert a signed 64-bit bigendian value. + * + * Convenience function. Read a signed 64-bit bigendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + * + * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ int PHYSFS_readSBE64(PHYSFS_File *file, PHYSFS_sint64 *val); + + +/** + * \fn int PHYSFS_readUBE64(PHYSFS_File *file, PHYSFS_uint64 *val) + * \brief Read and convert an unsigned 64-bit bigendian value. + * + * Convenience function. Read an unsigned 64-bit bigendian value from a + * file and convert it to the platform's native byte order. + * + * \param file PhysicsFS file handle from which to read. + * \param val pointer to where value should be stored. + * \return zero on failure, non-zero on success. If successful, (*val) will + * store the result. On failure, you can find out what went wrong + * from PHYSFS_getLastError(). + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ int PHYSFS_readUBE64(PHYSFS_File *file, PHYSFS_uint64 *val); + + +/** + * \fn int PHYSFS_writeSLE16(PHYSFS_File *file, PHYSFS_sint16 val) + * \brief Convert and write a signed 16-bit littleendian value. + * + * Convenience function. Convert a signed 16-bit value from the platform's + * native byte order to littleendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_writeSLE16(PHYSFS_File *file, PHYSFS_sint16 val); + + +/** + * \fn int PHYSFS_writeULE16(PHYSFS_File *file, PHYSFS_uint16 val) + * \brief Convert and write an unsigned 16-bit littleendian value. + * + * Convenience function. Convert an unsigned 16-bit value from the platform's + * native byte order to littleendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_writeULE16(PHYSFS_File *file, PHYSFS_uint16 val); + + +/** + * \fn int PHYSFS_writeSBE16(PHYSFS_File *file, PHYSFS_sint16 val) + * \brief Convert and write a signed 16-bit bigendian value. + * + * Convenience function. Convert a signed 16-bit value from the platform's + * native byte order to bigendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_writeSBE16(PHYSFS_File *file, PHYSFS_sint16 val); + + +/** + * \fn int PHYSFS_writeUBE16(PHYSFS_File *file, PHYSFS_uint16 val) + * \brief Convert and write an unsigned 16-bit bigendian value. + * + * Convenience function. Convert an unsigned 16-bit value from the platform's + * native byte order to bigendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_writeUBE16(PHYSFS_File *file, PHYSFS_uint16 val); + + +/** + * \fn int PHYSFS_writeSLE32(PHYSFS_File *file, PHYSFS_sint32 val) + * \brief Convert and write a signed 32-bit littleendian value. + * + * Convenience function. Convert a signed 32-bit value from the platform's + * native byte order to littleendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_writeSLE32(PHYSFS_File *file, PHYSFS_sint32 val); + + +/** + * \fn int PHYSFS_writeULE32(PHYSFS_File *file, PHYSFS_uint32 val) + * \brief Convert and write an unsigned 32-bit littleendian value. + * + * Convenience function. Convert an unsigned 32-bit value from the platform's + * native byte order to littleendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_writeULE32(PHYSFS_File *file, PHYSFS_uint32 val); + + +/** + * \fn int PHYSFS_writeSBE32(PHYSFS_File *file, PHYSFS_sint32 val) + * \brief Convert and write a signed 32-bit bigendian value. + * + * Convenience function. Convert a signed 32-bit value from the platform's + * native byte order to bigendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_writeSBE32(PHYSFS_File *file, PHYSFS_sint32 val); + + +/** + * \fn int PHYSFS_writeUBE32(PHYSFS_File *file, PHYSFS_uint32 val) + * \brief Convert and write an unsigned 32-bit bigendian value. + * + * Convenience function. Convert an unsigned 32-bit value from the platform's + * native byte order to bigendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + */ +__EXPORT__ int PHYSFS_writeUBE32(PHYSFS_File *file, PHYSFS_uint32 val); + + +/** + * \fn int PHYSFS_writeSLE64(PHYSFS_File *file, PHYSFS_sint64 val) + * \brief Convert and write a signed 64-bit littleendian value. + * + * Convenience function. Convert a signed 64-bit value from the platform's + * native byte order to littleendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ int PHYSFS_writeSLE64(PHYSFS_File *file, PHYSFS_sint64 val); + + +/** + * \fn int PHYSFS_writeULE64(PHYSFS_File *file, PHYSFS_uint64 val) + * \brief Convert and write an unsigned 64-bit littleendian value. + * + * Convenience function. Convert an unsigned 64-bit value from the platform's + * native byte order to littleendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ int PHYSFS_writeULE64(PHYSFS_File *file, PHYSFS_uint64 val); + + +/** + * \fn int PHYSFS_writeSBE64(PHYSFS_File *file, PHYSFS_sint64 val) + * \brief Convert and write a signed 64-bit bigending value. + * + * Convenience function. Convert a signed 64-bit value from the platform's + * native byte order to bigendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ int PHYSFS_writeSBE64(PHYSFS_File *file, PHYSFS_sint64 val); + + +/** + * \fn int PHYSFS_writeUBE64(PHYSFS_File *file, PHYSFS_uint64 val) + * \brief Convert and write an unsigned 64-bit bigendian value. + * + * Convenience function. Convert an unsigned 64-bit value from the platform's + * native byte order to bigendian and write it to a file. + * + * \param file PhysicsFS file handle to which to write. + * \param val Value to convert and write. + * \return zero on failure, non-zero on success. On failure, you can + * find out what went wrong from PHYSFS_getLastError(). + * + * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without + * any sort of 64-bit support. + */ +__EXPORT__ int PHYSFS_writeUBE64(PHYSFS_File *file, PHYSFS_uint64 val); + + +/* Everything above this line is part of the PhysicsFS 1.0 API. */ + +/** + * \fn int PHYSFS_isInit(void) + * \brief Determine if the PhysicsFS library is initialized. + * + * Once PHYSFS_init() returns successfully, this will return non-zero. + * Before a successful PHYSFS_init() and after PHYSFS_deinit() returns + * successfully, this will return zero. This function is safe to call at + * any time. + * + * \return non-zero if library is initialized, zero if library is not. + * + * \sa PHYSFS_init + * \sa PHYSFS_deinit + */ +__EXPORT__ int PHYSFS_isInit(void); + + +/** + * \fn int PHYSFS_symbolicLinksPermitted(void) + * \brief Determine if the symbolic links are permitted. + * + * This reports the setting from the last call to PHYSFS_permitSymbolicLinks(). + * If PHYSFS_permitSymbolicLinks() hasn't been called since the library was + * last initialized, symbolic links are implicitly disabled. + * + * \return non-zero if symlinks are permitted, zero if not. + * + * \sa PHYSFS_permitSymbolicLinks + */ +__EXPORT__ int PHYSFS_symbolicLinksPermitted(void); + + +/** + * \struct PHYSFS_Allocator + * \brief PhysicsFS allocation function pointers. + * + * (This is for limited, hardcore use. If you don't immediately see a need + * for it, you can probably ignore this forever.) + * + * You create one of these structures for use with PHYSFS_setAllocator. + * Allocators are assumed to be reentrant by the caller; please mutex + * accordingly. + * + * Allocations are always discussed in 64-bits, for future expansion...we're + * on the cusp of a 64-bit transition, and we'll probably be allocating 6 + * gigabytes like it's nothing sooner or later, and I don't want to change + * this again at that point. If you're on a 32-bit platform and have to + * downcast, it's okay to return NULL if the allocation is greater than + * 4 gigabytes, since you'd have to do so anyhow. + * + * \sa PHYSFS_setAllocator + */ +typedef struct PHYSFS_Allocator +{ + int (*Init)(void); /**< Initialize. Can be NULL. Zero on failure. */ + void (*Deinit)(void); /**< Deinitialize your allocator. Can be NULL. */ + void *(*Malloc)(PHYSFS_uint64); /**< Allocate like malloc(). */ + void *(*Realloc)(void *, PHYSFS_uint64); /**< Reallocate like realloc(). */ + void (*Free)(void *); /**< Free memory from Malloc or Realloc. */ +} PHYSFS_Allocator; + + +/** + * \fn int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator) + * \brief Hook your own allocation routines into PhysicsFS. + * + * (This is for limited, hardcore use. If you don't immediately see a need + * for it, you can probably ignore this forever.) + * + * By default, PhysicsFS will use whatever is reasonable for a platform + * to manage dynamic memory (usually ANSI C malloc/realloc/calloc/free, but + * some platforms might use something else), but in some uncommon cases, the + * app might want more control over the library's memory management. This + * lets you redirect PhysicsFS to use your own allocation routines instead. + * You can only call this function before PHYSFS_init(); if the library is + * initialized, it'll reject your efforts to change the allocator mid-stream. + * You may call this function after PHYSFS_deinit() if you are willing to + * shut down the library and restart it with a new allocator; this is a safe + * and supported operation. The allocator remains intact between deinit/init + * calls. If you want to return to the platform's default allocator, pass a + * NULL in here. + * + * If you aren't immediately sure what to do with this function, you can + * safely ignore it altogether. + * + * \param allocator Structure containing your allocator's entry points. + * \return zero on failure, non-zero on success. This call only fails + * when used between PHYSFS_init() and PHYSFS_deinit() calls. + */ +__EXPORT__ int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator); + + +/** + * \fn int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath) + * \brief Add an archive or directory to the search path. + * + * If this is a duplicate, the entry is not added again, even though the + * function succeeds. You may not add the same archive to two different + * mountpoints: duplicate checking is done against the archive and not the + * mountpoint. + * + * When you mount an archive, it is added to a virtual file system...all files + * in all of the archives are interpolated into a single hierachical file + * tree. Two archives mounted at the same place (or an archive with files + * overlapping another mountpoint) may have overlapping files: in such a case, + * the file earliest in the search path is selected, and the other files are + * inaccessible to the application. This allows archives to be used to + * override previous revisions; you can use the mounting mechanism to place + * archives at a specific point in the file tree and prevent overlap; this + * is useful for downloadable mods that might trample over application data + * or each other, for example. + * + * The mountpoint does not need to exist prior to mounting, which is different + * than those familiar with the Unix concept of "mounting" may not expect. + * As well, more than one archive can be mounted to the same mountpoint, or + * mountpoints and archive contents can overlap...the interpolation mechanism + * still functions as usual. + * + * \param newDir directory or archive to add to the path, in + * platform-dependent notation. + * \param mountPoint Location in the interpolated tree that this archive + * will be "mounted", in platform-independent notation. + * NULL or "" is equivalent to "/". + * \param appendToPath nonzero to append to search path, zero to prepend. + * \return nonzero if added to path, zero on failure (bogus archive, dir + * missing, etc). Specifics of the error can be + * gleaned from PHYSFS_getLastError(). + * + * \sa PHYSFS_removeFromSearchPath + * \sa PHYSFS_getSearchPath + * \sa PHYSFS_getMountPoint + */ +__EXPORT__ int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath); + +/** + * \fn int PHYSFS_getMountPoint(const char *dir) + * \brief Determine a mounted archive's mountpoint. + * + * You give this function the name of an archive or dir you successfully + * added to the search path, and it reports the location in the interpolated + * tree where it is mounted. Files mounted with a NULL mountpoint or through + * PHYSFS_addToSearchPath() will report "/". The return value is READ ONLY + * and valid until the archive is removed from the search path. + * + * \param dir directory or archive previously added to the path, in + * platform-dependent notation. This must match the string + * used when adding, even if your string would also reference + * the same file with a different string of characters. + * \return READ-ONLY string of mount point if added to path, NULL on failure + * (bogus archive, etc) Specifics of the error can be gleaned from + * PHYSFS_getLastError(). + * + * \sa PHYSFS_removeFromSearchPath + * \sa PHYSFS_getSearchPath + * \sa PHYSFS_getMountPoint + */ +__EXPORT__ const char *PHYSFS_getMountPoint(const char *dir); + + +/** + * \typedef PHYSFS_StringCallback + * \brief Function signature for callbacks that report strings. + * + * These are used to report a list of strings to an original caller, one + * string per callback. All strings are UTF-8 encoded. Functions should not + * try to modify or free the string's memory. + * + * These callbacks are used, starting in PhysicsFS 1.1, as an alternative to + * functions that would return lists that need to be cleaned up with + * PHYSFS_freeList(). The callback means that the library doesn't need to + * allocate an entire list and all the strings up front. + * + * Be aware that promises data ordering in the list versions are not + * necessarily so in the callback versions. Check the documentation on + * specific APIs, but strings may not be sorted as you expect. + * + * \param data User-defined data pointer, passed through from the API + * that eventually called the callback. + * \param str The string data about which the callback is meant to inform. + * + * \sa PHYSFS_getCdRomDirsCallback + * \sa PHYSFS_getSearchPathCallback + */ +typedef void (*PHYSFS_StringCallback)(void *data, const char *str); + + +/** + * \typedef PHYSFS_EnumFilesCallback + * \brief Function signature for callbacks that enumerate files. + * + * These are used to report a list of directory entries to an original caller, + * one file/dir/symlink per callback. All strings are UTF-8 encoded. + * Functions should not try to modify or free any string's memory. + * + * These callbacks are used, starting in PhysicsFS 1.1, as an alternative to + * functions that would return lists that need to be cleaned up with + * PHYSFS_freeList(). The callback means that the library doesn't need to + * allocate an entire list and all the strings up front. + * + * Be aware that promises data ordering in the list versions are not + * necessarily so in the callback versions. Check the documentation on + * specific APIs, but strings may not be sorted as you expect. + * + * \param data User-defined data pointer, passed through from the API + * that eventually called the callback. + * \param origdir A string containing the full path, in platform-independent + * notation, of the directory containing this file. In most + * cases, this is the directory on which you requested + * enumeration, passed in the callback for your convenience. + * \param fname The filename that is being enumerated. It may not be in + * alphabetical order compared to other callbacks that have + * fired, and it will not contain the full path. You can + * recreate the fullpath with $origdir/$fname ... The file + * can be a subdirectory, a file, a symlink, etc. + * + * \sa PHYSFS_enumerateFilesCallback + */ +typedef void (*PHYSFS_EnumFilesCallback)(void *data, const char *origdir, + const char *fname); + + +/** + * \fn void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback c, void *d) + * \brief Enumerate CD-ROM directories, using an application-defined callback. + * + * Internally, PHYSFS_getCdRomDirs() just calls this function and then builds + * a list before returning to the application, so functionality is identical + * except for how the information is represented to the application. + * + * Unlike PHYSFS_getCdRomDirs(), this function does not return an array. + * Rather, it calls a function specified by the application once per + * detected disc: + * + * \code + * + * static void foundDisc(void *data, const char *cddir) + * { + * printf("cdrom dir [%s] is available.\n", cddir); + * } + * + * // ... + * PHYSFS_getCdRomDirsCallback(foundDisc, NULL); + * \endcode + * + * This call may block while drives spin up. Be forewarned. + * + * \param c Callback function to notify about detected drives. + * \param d Application-defined data passed to callback. Can be NULL. + * + * \sa PHYSFS_StringCallback + * \sa PHYSFS_getCdRomDirs + */ +__EXPORT__ void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback c, void *d); + + +/** + * \fn void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback c, void *d) + * \brief Enumerate the search path, using an application-defined callback. + * + * Internally, PHYSFS_getSearchPath() just calls this function and then builds + * a list before returning to the application, so functionality is identical + * except for how the information is represented to the application. + * + * Unlike PHYSFS_getSearchPath(), this function does not return an array. + * Rather, it calls a function specified by the application once per + * element of the search path: + * + * \code + * + * static void printSearchPath(void *data, const char *pathItem) + * { + * printf("[%s] is in the search path.\n", pathItem); + * } + * + * // ... + * PHYSFS_getSearchPathCallback(printSearchPath, NULL); + * \endcode + * + * Elements of the search path are reported in order search priority, so the + * first archive/dir that would be examined when looking for a file is the + * first element passed through the callback. + * + * \param c Callback function to notify about search path elements. + * \param d Application-defined data passed to callback. Can be NULL. + * + * \sa PHYSFS_StringCallback + * \sa PHYSFS_getSearchPath + */ +__EXPORT__ void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback c, void *d); + + +/** + * \fn void PHYSFS_enumerateFilesCallback(const char *dir, PHYSFS_EnumFilesCallback c, void *d) + * \brief Get a file listing of a search path's directory, using an application-defined callback. + * + * Internally, PHYSFS_enumerateFiles() just calls this function and then builds + * a list before returning to the application, so functionality is identical + * except for how the information is represented to the application. + * + * Unlike PHYSFS_enumerateFiles(), this function does not return an array. + * Rather, it calls a function specified by the application once per + * element of the search path: + * + * \code + * + * static void printDir(void *data, const char *origdir, const char *fname) + * { + * printf(" * We've got [%s] in [%s].\n", fname, origdir); + * } + * + * // ... + * PHYSFS_enumerateFilesCallback("/some/path", printDir, NULL); + * \endcode + * + * Items sent to the callback are not guaranteed to be in any order whatsoever. + * There is no sorting done at this level, and if you need that, you should + * probably use PHYSFS_enumerateFiles() instead, which guarantees + * alphabetical sorting. This form reports whatever is discovered in each + * archive before moving on to the next. Even within one archive, we can't + * guarantee what order it will discover data. <em>Any sorting you find in + * these callbacks is just pure luck. Do not rely on it.</em> + * + * \param dir Directory, in platform-independent notation, to enumerate. + * \param c Callback function to notify about search path elements. + * \param d Application-defined data passed to callback. Can be NULL. + * + * \sa PHYSFS_EnumFilesCallback + * \sa PHYSFS_enumerateFiles + */ +__EXPORT__ void PHYSFS_enumerateFilesCallback(const char *dir, + PHYSFS_EnumFilesCallback c, + void *d); + +/** + * \fn void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len) + * \brief Convert a UCS-4 string to a UTF-8 string. + * + * UCS-4 strings are 32-bits per character: \c wchar_t on Unix. + * + * To ensure that the destination buffer is large enough for the conversion, + * please allocate a buffer that is the same size as the source buffer. UTF-8 + * never uses more than 32-bits per character, so while it may shrink a UCS-4 + * string, it will never expand it. + * + * Strings that don't fit in the destination buffer will be truncated, but + * will always be null-terminated and never have an incomplete UTF-8 + * sequence at the end. If the buffer length is 0, this function does nothing. + * + * \param src Null-terminated source string in UCS-4 format. + * \param dst Buffer to store converted UTF-8 string. + * \param len Size, in bytes, of destination buffer. + */ +__EXPORT__ void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, + PHYSFS_uint64 len); + +/** + * \fn void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len) + * \brief Convert a UTF-8 string to a UCS-4 string. + * + * UCS-4 strings are 32-bits per character: \c wchar_t on Unix. + * + * To ensure that the destination buffer is large enough for the conversion, + * please allocate a buffer that is four times the size of the source buffer. + * UTF-8 uses from one to four bytes per character, but UCS-4 always uses + * four, so an entirely low-ASCII string will quadruple in size! + * + * Strings that don't fit in the destination buffer will be truncated, but + * will always be null-terminated and never have an incomplete UCS-4 + * sequence at the end. If the buffer length is 0, this function does nothing. + * + * \param src Null-terminated source string in UTF-8 format. + * \param dst Buffer to store converted UCS-4 string. + * \param len Size, in bytes, of destination buffer. + */ +__EXPORT__ void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, + PHYSFS_uint64 len); + +/** + * \fn void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len) + * \brief Convert a UCS-2 string to a UTF-8 string. + * + * UCS-2 strings are 16-bits per character: \c TCHAR on Windows, when building + * with Unicode support. + * + * To ensure that the destination buffer is large enough for the conversion, + * please allocate a buffer that is double the size of the source buffer. + * UTF-8 never uses more than 32-bits per character, so while it may shrink + * a UCS-2 string, it may also expand it. + * + * Strings that don't fit in the destination buffer will be truncated, but + * will always be null-terminated and never have an incomplete UTF-8 + * sequence at the end. If the buffer length is 0, this function does nothing. + * + * Please note that UCS-2 is not UTF-16; we do not support the "surrogate" + * values at this time. + * + * \param src Null-terminated source string in UCS-2 format. + * \param dst Buffer to store converted UTF-8 string. + * \param len Size, in bytes, of destination buffer. + */ +__EXPORT__ void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, + PHYSFS_uint64 len); + +/** + * \fn PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len) + * \brief Convert a UTF-8 string to a UCS-2 string. + * + * UCS-2 strings are 16-bits per character: \c TCHAR on Windows, when building + * with Unicode support. + * + * To ensure that the destination buffer is large enough for the conversion, + * please allocate a buffer that is double the size of the source buffer. + * UTF-8 uses from one to four bytes per character, but UCS-2 always uses + * two, so an entirely low-ASCII string will double in size! + * + * Strings that don't fit in the destination buffer will be truncated, but + * will always be null-terminated and never have an incomplete UCS-2 + * sequence at the end. If the buffer length is 0, this function does nothing. + * + * Please note that UCS-2 is not UTF-16; we do not support the "surrogate" + * values at this time. + * + * \param src Null-terminated source string in UTF-8 format. + * \param dst Buffer to store converted UCS-2 string. + * \param len Size, in bytes, of destination buffer. + */ +__EXPORT__ void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, + PHYSFS_uint64 len); + +/** + * \fn void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len) + * \brief Convert a UTF-8 string to a Latin1 string. + * + * Latin1 strings are 8-bits per character: a popular "high ASCII" + * encoding. + * + * To ensure that the destination buffer is large enough for the conversion, + * please allocate a buffer that is double the size of the source buffer. + * UTF-8 expands latin1 codepoints over 127 from 1 to 2 bytes, so the string + * may grow in some cases. + * + * Strings that don't fit in the destination buffer will be truncated, but + * will always be null-terminated and never have an incomplete UTF-8 + * sequence at the end. If the buffer length is 0, this function does nothing. + * + * Please note that we do not supply a UTF-8 to Latin1 converter, since Latin1 + * can't express most Unicode codepoints. It's a legacy encoding; you should + * be converting away from it at all times. + * + * \param src Null-terminated source string in Latin1 format. + * \param dst Buffer to store converted UTF-8 string. + * \param len Size, in bytes, of destination buffer. + */ +__EXPORT__ void PHYSFS_utf8FromLatin1(const char *src, char *dst, + PHYSFS_uint64 len); + +/* Everything above this line is part of the PhysicsFS 2.0 API. */ + + +#ifdef __cplusplus +} +#endif + +#endif /* !defined _INCLUDE_PHYSFS_H_ */ + +/* end of physfs.h ... */ + diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/png.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/png.h new file mode 100644 index 00000000..372599bf --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/png.h @@ -0,0 +1,3292 @@ + +/* png.h - header file for PNG reference library + * + * libpng version 1.6.17, March 26, 2015 + * + * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license (See LICENSE, below) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.6.17, March 26, 2015: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 12.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 12.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-7 13 10210 12.so.0.10[.0] + * 1.2.10rc1-2 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.4.0beta1-5 14 10400 14.so.0.0[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.4.0beta7-8 14 10400 14.so.0.0[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.4.0beta9-14 14 10400 14.so.0.0[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.4.0beta15-36 14 10400 14.so.0.0[.0] + * 1.4.0beta37-87 14 10400 14.so.14.0[.0] + * 1.4.0rc01 14 10400 14.so.14.0[.0] + * 1.4.0beta88-109 14 10400 14.so.14.0[.0] + * 1.4.0rc02-08 14 10400 14.so.14.0[.0] + * 1.4.0 14 10400 14.so.14.0[.0] + * 1.4.1beta01-03 14 10401 14.so.14.1[.0] + * 1.4.1rc01 14 10401 14.so.14.1[.0] + * 1.4.1beta04-12 14 10401 14.so.14.1[.0] + * 1.4.1 14 10401 14.so.14.1[.0] + * 1.4.2 14 10402 14.so.14.2[.0] + * 1.4.3 14 10403 14.so.14.3[.0] + * 1.4.4 14 10404 14.so.14.4[.0] + * 1.5.0beta01-58 15 10500 15.so.15.0[.0] + * 1.5.0rc01-07 15 10500 15.so.15.0[.0] + * 1.5.0 15 10500 15.so.15.0[.0] + * 1.5.1beta01-11 15 10501 15.so.15.1[.0] + * 1.5.1rc01-02 15 10501 15.so.15.1[.0] + * 1.5.1 15 10501 15.so.15.1[.0] + * 1.5.2beta01-03 15 10502 15.so.15.2[.0] + * 1.5.2rc01-03 15 10502 15.so.15.2[.0] + * 1.5.2 15 10502 15.so.15.2[.0] + * 1.5.3beta01-10 15 10503 15.so.15.3[.0] + * 1.5.3rc01-02 15 10503 15.so.15.3[.0] + * 1.5.3beta11 15 10503 15.so.15.3[.0] + * 1.5.3 [omitted] + * 1.5.4beta01-08 15 10504 15.so.15.4[.0] + * 1.5.4rc01 15 10504 15.so.15.4[.0] + * 1.5.4 15 10504 15.so.15.4[.0] + * 1.5.5beta01-08 15 10505 15.so.15.5[.0] + * 1.5.5rc01 15 10505 15.so.15.5[.0] + * 1.5.5 15 10505 15.so.15.5[.0] + * 1.5.6beta01-07 15 10506 15.so.15.6[.0] + * 1.5.6rc01-03 15 10506 15.so.15.6[.0] + * 1.5.6 15 10506 15.so.15.6[.0] + * 1.5.7beta01-05 15 10507 15.so.15.7[.0] + * 1.5.7rc01-03 15 10507 15.so.15.7[.0] + * 1.5.7 15 10507 15.so.15.7[.0] + * 1.6.0beta01-40 16 10600 16.so.16.0[.0] + * 1.6.0rc01-08 16 10600 16.so.16.0[.0] + * 1.6.0 16 10600 16.so.16.0[.0] + * 1.6.1beta01-09 16 10601 16.so.16.1[.0] + * 1.6.1rc01 16 10601 16.so.16.1[.0] + * 1.6.1 16 10601 16.so.16.1[.0] + * 1.6.2beta01 16 10602 16.so.16.2[.0] + * 1.6.2rc01-06 16 10602 16.so.16.2[.0] + * 1.6.2 16 10602 16.so.16.2[.0] + * 1.6.3beta01-11 16 10603 16.so.16.3[.0] + * 1.6.3rc01 16 10603 16.so.16.3[.0] + * 1.6.3 16 10603 16.so.16.3[.0] + * 1.6.4beta01-02 16 10604 16.so.16.4[.0] + * 1.6.4rc01 16 10604 16.so.16.4[.0] + * 1.6.4 16 10604 16.so.16.4[.0] + * 1.6.5 16 10605 16.so.16.5[.0] + * 1.6.6 16 10606 16.so.16.6[.0] + * 1.6.7beta01-04 16 10607 16.so.16.7[.0] + * 1.6.7rc01-03 16 10607 16.so.16.7[.0] + * 1.6.7 16 10607 16.so.16.7[.0] + * 1.6.8beta01-02 16 10608 16.so.16.8[.0] + * 1.6.8rc01-02 16 10608 16.so.16.8[.0] + * 1.6.8 16 10608 16.so.16.8[.0] + * 1.6.9beta01-04 16 10609 16.so.16.9[.0] + * 1.6.9rc01-02 16 10609 16.so.16.9[.0] + * 1.6.9 16 10609 16.so.16.9[.0] + * 1.6.10beta01-03 16 10610 16.so.16.10[.0] + * 1.6.10rc01-03 16 10610 16.so.16.10[.0] + * 1.6.10 16 10610 16.so.16.10[.0] + * 1.6.11beta01-06 16 10611 16.so.16.11[.0] + * 1.6.11rc01-02 16 10611 16.so.16.11[.0] + * 1.6.11 16 10611 16.so.16.11[.0] + * 1.6.12rc01-03 16 10612 16.so.16.12[.0] + * 1.6.12 16 10612 16.so.16.12[.0] + * 1.6.13beta01-04 16 10613 16.so.16.13[.0] + * 1.6.13rc01-02 16 10613 16.so.16.13[.0] + * 1.6.13 16 10613 16.so.16.13[.0] + * 1.6.14beta01-07 16 10614 16.so.16.14[.0] + * 1.6.14rc01-02 16 10614 16.so.16.14[.0] + * 1.6.14 16 10614 16.so.16.14[.0] + * 1.6.15beta01-08 16 10615 16.so.16.15[.0] + * 1.6.15rc01-03 16 10615 16.so.16.15[.0] + * 1.6.15 16 10615 16.so.16.15[.0] + * 1.6.16beta01-03 16 10616 16.so.16.16[.0] + * 1.6.16rc01-02 16 10616 16.so.16.16[.0] + * 1.6.16 16 10616 16.so.16.16[.0] + * 1.6.17beta01-06 16 10617 16.so.16.17[.0] + * 1.6.17rc01-06 16 10617 16.so.16.17[.0] + * 1.6.17 16 10617 16.so.16.17[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcNN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng-manual.txt or libpng.3 for more information. The PNG + * specification is available as a W3C Recommendation and as an ISO + * Specification, <http://www.w3.org/TR/2003/REC-PNG-20031110/ + */ + +/* + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * + * If you modify libpng you may insert additional notices immediately following + * this sentence. + * + * This code is released under the libpng license. + * + * libpng versions 1.2.6, August 15, 2004, through 1.6.17, March 26, 2015, are + * Copyright (c) 2004, 2006-2015 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.2.5 + * with the following individual added to the list of Contributing Authors: + * + * Cosmin Truta + * + * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are + * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.0.6 + * with the following individuals added to the list of Contributing Authors: + * + * Simon-Pierre Cadieux + * Eric S. Raymond + * Gilles Vollant + * + * and with the following additions to the disclaimer: + * + * There is no warranty against interference with your enjoyment of the + * library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is with + * the user. + * + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are + * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-0.96, + * with the following individuals added to the list of Contributing Authors: + * + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik + * + * libpng versions 0.89, June 1996, through 0.96, May 1997, are + * Copyright (c) 1996, 1997 Andreas Dilger + * Distributed according to the same disclaimer and license as libpng-0.88, + * with the following individuals added to the list of Contributing Authors: + * + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner + * + * libpng versions 0.5, May 1995, through 0.88, January 1996, are + * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + * + * For the purposes of this copyright and license, "Contributing Authors" + * is defined as the following set of individuals: + * + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner + * + * The PNG Reference Library is supplied "AS IS". The Contributing Authors + * and Group 42, Inc. disclaim all warranties, expressed or implied, + * including, without limitation, the warranties of merchantability and of + * fitness for any purpose. The Contributing Authors and Group 42, Inc. + * assume no liability for direct, indirect, incidental, special, exemplary, + * or consequential damages, which may result from the use of the PNG + * Reference Library, even if advised of the possibility of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject + * to the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. + * + * 2. Altered versions must be plainly marked as such and must not + * be misrepresented as being the original source. + * + * 3. This Copyright notice may not be removed or altered from + * any source or altered source distribution. + * + * The Contributing Authors and Group 42, Inc. specifically permit, without + * fee, and encourage the use of this source code as a component to + * supporting the PNG file format in commercial products. If you use this + * source code in a product, acknowledgment is not required but would be + * appreciated. + */ + +/* + * A "png_get_copyright" function is available, for convenient use in "about" + * boxes and the like: + * + * printf("%s", png_get_copyright(NULL)); + * + * Also, the PNG logo (in PNG format, of course) is supplied in the + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + */ + +/* + * Libpng is OSI Certified Open Source Software. OSI Certified is a + * certification mark of the Open Source Initiative. + */ + +/* + * The contributing authors would like to thank all those who helped + * with testing, bug fixes, and patience. This wouldn't have been + * possible without all of you. + * + * Thanks to Frank J. T. Wojcik for helping with the documentation. + */ + +/* + * Y2K compliance in libpng: + * ========================= + * + * March 26, 2015 + * + * Since the PNG Development group is an ad-hoc body, we can't make + * an official declaration. + * + * This is your unofficial assurance that libpng from version 0.71 and + * upward through 1.6.17 are Y2K compliant. It is my belief that + * earlier versions were also Y2K compliant. + * + * Libpng only has two year fields. One is a 2-byte unsigned integer + * that will hold years up to 65535. The other, which is deprecated, + * holds the date in text format, and will hold years up to 9999. + * + * The integer is + * "png_uint_16 year" in png_time_struct. + * + * The string is + * "char time_buffer[29]" in png_struct. This is no longer used + * in libpng-1.6.x and will be removed from libpng-1.7.0. + * + * There are seven time-related functions: + * png.c: png_convert_to_rfc_1123_buffer() in png.c + * (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and + * png_convert_to_rfc_1152() in error prior to libpng-0.98) + * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c + * png_convert_from_time_t() in pngwrite.c + * png_get_tIME() in pngget.c + * png_handle_tIME() in pngrutil.c, called in pngread.c + * png_set_tIME() in pngset.c + * png_write_tIME() in pngwutil.c, called in pngwrite.c + * + * All handle dates properly in a Y2K environment. The + * png_convert_from_time_t() function calls gmtime() to convert from system + * clock time, which returns (year - 1900), which we properly convert to + * the full 4-digit year. There is a possibility that libpng applications + * are not passing 4-digit years into the png_convert_to_rfc_1123_buffer() + * function, or that they are incorrectly passing only a 2-digit year + * instead of "year - 1900" into the png_convert_from_struct_tm() function, + * but this is not under our control. The libpng documentation has always + * stated that it works with 4-digit years, and the APIs have been + * documented as such. + * + * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned + * integer to hold the year, and can hold years as large as 65535. + * + * zlib, upon which libpng depends, is also Y2K compliant. It contains + * no date-related code. + * + * Glenn Randers-Pehrson + * libpng maintainer + * PNG Development Group + */ + +#ifndef PNG_H +#define PNG_H + +/* This is not the place to learn how to use libpng. The file libpng-manual.txt + * describes how to use libpng, and the file example.c summarizes it + * with some code on which to build. This file is useful for looking + * at the actual function definitions and structure components. If that + * file has been stripped from your copy of libpng, you can find it at + * <http://www.libpng.org/pub/png/libpng-manual.txt> + * + * If you just need to read a PNG file and don't want to read the documentation + * skip to the end of this file and read the section entitled 'simplified API'. + */ + +/* Version information for png.h - this should match the version in png.c */ +#define PNG_LIBPNG_VER_STRING "1.6.17" +#define PNG_HEADER_VERSION_STRING \ + " libpng version 1.6.17 - March 26, 2015\n" + +#define PNG_LIBPNG_VER_SONUM 16 +#define PNG_LIBPNG_VER_DLLNUM 16 + +/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ +#define PNG_LIBPNG_VER_MAJOR 1 +#define PNG_LIBPNG_VER_MINOR 6 +#define PNG_LIBPNG_VER_RELEASE 17 + +/* This should match the numeric part of the final component of + * PNG_LIBPNG_VER_STRING, omitting any leading zero: + */ + +#define PNG_LIBPNG_VER_BUILD 0 + +/* Release Status */ +#define PNG_LIBPNG_BUILD_ALPHA 1 +#define PNG_LIBPNG_BUILD_BETA 2 +#define PNG_LIBPNG_BUILD_RC 3 +#define PNG_LIBPNG_BUILD_STABLE 4 +#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 + +/* Release-Specific Flags */ +#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with + PNG_LIBPNG_BUILD_STABLE only */ +#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_SPECIAL */ +#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_PRIVATE */ + +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE + +/* Careful here. At one time, Guy wanted to use 082, but that would be octal. + * We must not include leading zeros. + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only + * version 1.0.0 was mis-numbered 100 instead of 10000). From + * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release + */ +#define PNG_LIBPNG_VER 10617 /* 1.6.17 */ + +/* Library configuration: these options cannot be changed after + * the library has been built. + */ +#ifndef PNGLCONF_H + /* If pnglibconf.h is missing, you can + * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h + */ +# include "pnglibconf.h" +#endif + +#ifndef PNG_VERSION_INFO_ONLY + /* Machine specific configuration. */ +# include "pngconf.h" +#endif + +/* + * Added at libpng-1.2.8 + * + * Ref MSDN: Private as priority over Special + * VS_FF_PRIVATEBUILD File *was not* built using standard release + * procedures. If this value is given, the StringFileInfo block must + * contain a PrivateBuild string. + * + * VS_FF_SPECIALBUILD File *was* built by the original company using + * standard release procedures but is a variation of the standard + * file of the same version number. If this value is given, the + * StringFileInfo block must contain a SpecialBuild string. + */ + +#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) +#else +# ifdef PNG_LIBPNG_SPECIALBUILD +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) +# else +# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) +# endif +#endif + +#ifndef PNG_VERSION_INFO_ONLY + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Version information for C files, stored in png.c. This had better match + * the version above. + */ +#define png_libpng_ver png_get_header_ver(NULL) + +/* This file is arranged in several sections: + * + * 1. Any configuration options that can be specified by for the application + * code when it is built. (Build time configuration is in pnglibconf.h) + * 2. Type definitions (base types are defined in pngconf.h), structure + * definitions. + * 3. Exported library functions. + * 4. Simplified API. + * + * The library source code has additional files (principally pngpriv.h) that + * allow configuration of the library. + */ +/* Section 1: run time configuration + * See pnglibconf.h for build time configuration + * + * Run time configuration allows the application to choose between + * implementations of certain arithmetic APIs. The default is set + * at build time and recorded in pnglibconf.h, but it is safe to + * override these (and only these) settings. Note that this won't + * change what the library does, only application code, and the + * settings can (and probably should) be made on a per-file basis + * by setting the #defines before including png.h + * + * Use macros to read integers from PNG data or use the exported + * functions? + * PNG_USE_READ_MACROS: use the macros (see below) Note that + * the macros evaluate their argument multiple times. + * PNG_NO_USE_READ_MACROS: call the relevant library function. + * + * Use the alternative algorithm for compositing alpha samples that + * does not use division? + * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' + * algorithm. + * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. + * + * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is + * false? + * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error + * APIs to png_warning. + * Otherwise the calls are mapped to png_error. + */ + +/* Section 2: type definitions, including structures and compile time + * constants. + * See pngconf.h for base types that vary by machine/system + */ + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef char* png_libpng_version_1_6_17; + +/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. + * + * png_struct is the cache of information used while reading or writing a single + * PNG file. One of these is always required, although the simplified API + * (below) hides the creation and destruction of it. + */ +typedef struct png_struct_def png_struct; +typedef const png_struct * png_const_structp; +typedef png_struct * png_structp; +typedef png_struct * * png_structpp; + +/* png_info contains information read from or to be written to a PNG file. One + * or more of these must exist while reading or creating a PNG file. The + * information is not used by libpng during read but is used to control what + * gets written when a PNG file is created. "png_get_" function calls read + * information during read and "png_set_" functions calls write information + * when creating a PNG. + * been moved into a separate header file that is not accessible to + * applications. Read libpng-manual.txt or libpng.3 for more info. + */ +typedef struct png_info_def png_info; +typedef png_info * png_infop; +typedef const png_info * png_const_infop; +typedef png_info * * png_infopp; + +/* Types with names ending 'p' are pointer types. The corresponding types with + * names ending 'rp' are identical pointer types except that the pointer is + * marked 'restrict', which means that it is the only pointer to the object + * passed to the function. Applications should not use the 'restrict' types; + * it is always valid to pass 'p' to a pointer with a function argument of the + * corresponding 'rp' type. Different compilers have different rules with + * regard to type matching in the presence of 'restrict'. For backward + * compatibility libpng callbacks never have 'restrict' in their parameters and, + * consequentially, writing portable application code is extremely difficult if + * an attempt is made to use 'restrict'. + */ +typedef png_struct * PNG_RESTRICT png_structrp; +typedef const png_struct * PNG_RESTRICT png_const_structrp; +typedef png_info * PNG_RESTRICT png_inforp; +typedef const png_info * PNG_RESTRICT png_const_inforp; + +/* Three color definitions. The order of the red, green, and blue, (and the + * exact size) is not important, although the size of the fields need to + * be png_byte or png_uint_16 (as defined below). + */ +typedef struct png_color_struct +{ + png_byte red; + png_byte green; + png_byte blue; +} png_color; +typedef png_color * png_colorp; +typedef const png_color * png_const_colorp; +typedef png_color * * png_colorpp; + +typedef struct png_color_16_struct +{ + png_byte index; /* used for palette files */ + png_uint_16 red; /* for use in red green blue files */ + png_uint_16 green; + png_uint_16 blue; + png_uint_16 gray; /* for use in grayscale files */ +} png_color_16; +typedef png_color_16 * png_color_16p; +typedef const png_color_16 * png_const_color_16p; +typedef png_color_16 * * png_color_16pp; + +typedef struct png_color_8_struct +{ + png_byte red; /* for use in red green blue files */ + png_byte green; + png_byte blue; + png_byte gray; /* for use in grayscale files */ + png_byte alpha; /* for alpha channel files */ +} png_color_8; +typedef png_color_8 * png_color_8p; +typedef const png_color_8 * png_const_color_8p; +typedef png_color_8 * * png_color_8pp; + +/* + * The following two structures are used for the in-core representation + * of sPLT chunks. + */ +typedef struct png_sPLT_entry_struct +{ + png_uint_16 red; + png_uint_16 green; + png_uint_16 blue; + png_uint_16 alpha; + png_uint_16 frequency; +} png_sPLT_entry; +typedef png_sPLT_entry * png_sPLT_entryp; +typedef const png_sPLT_entry * png_const_sPLT_entryp; +typedef png_sPLT_entry * * png_sPLT_entrypp; + +/* When the depth of the sPLT palette is 8 bits, the color and alpha samples + * occupy the LSB of their respective members, and the MSB of each member + * is zero-filled. The frequency member always occupies the full 16 bits. + */ + +typedef struct png_sPLT_struct +{ + png_charp name; /* palette name */ + png_byte depth; /* depth of palette samples */ + png_sPLT_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ +} png_sPLT_t; +typedef png_sPLT_t * png_sPLT_tp; +typedef const png_sPLT_t * png_const_sPLT_tp; +typedef png_sPLT_t * * png_sPLT_tpp; + +#ifdef PNG_TEXT_SUPPORTED +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, + * and whether that contents is compressed or not. The "key" field + * points to a regular zero-terminated C string. The "text" fields can be a + * regular C string, an empty string, or a NULL pointer. + * However, the structure returned by png_get_text() will always contain + * the "text" field as a regular zero-terminated C string (possibly + * empty), never a NULL pointer, so it can be safely used in printf() and + * other string-handling functions. Note that the "itxt_length", "lang", and + * "lang_key" members of the structure only exist when the library is built + * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by + * default without iTXt support. Also note that when iTXt *is* supported, + * the "lang" and "lang_key" fields contain NULL pointers when the + * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or + * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the + * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" + * which is always 0 or 1, or its "compression method" which is always 0. + */ +typedef struct png_text_struct +{ + int compression; /* compression value: + -1: tEXt, none + 0: zTXt, deflate + 1: iTXt, none + 2: iTXt, deflate */ + png_charp key; /* keyword, 1-79 character description of "text" */ + png_charp text; /* comment, may be an empty string (ie "") + or a NULL pointer */ + png_size_t text_length; /* length of the text string */ + png_size_t itxt_length; /* length of the itxt string */ + png_charp lang; /* language code, 0-79 characters + or a NULL pointer */ + png_charp lang_key; /* keyword translated UTF-8 string, 0 or more + chars or a NULL pointer */ +} png_text; +typedef png_text * png_textp; +typedef const png_text * png_const_textp; +typedef png_text * * png_textpp; +#endif + +/* Supported compression types for text in PNG files (tEXt, and zTXt). + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ +#define PNG_TEXT_COMPRESSION_NONE_WR -3 +#define PNG_TEXT_COMPRESSION_zTXt_WR -2 +#define PNG_TEXT_COMPRESSION_NONE -1 +#define PNG_TEXT_COMPRESSION_zTXt 0 +#define PNG_ITXT_COMPRESSION_NONE 1 +#define PNG_ITXT_COMPRESSION_zTXt 2 +#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ + +/* png_time is a way to hold the time in an machine independent way. + * Two conversions are provided, both from time_t and struct tm. There + * is no portable way to convert to either of these structures, as far + * as I know. If you know of a portable way, send it to me. As a side + * note - PNG has always been Year 2000 compliant! + */ +typedef struct png_time_struct +{ + png_uint_16 year; /* full year, as in, 1995 */ + png_byte month; /* month of year, 1 - 12 */ + png_byte day; /* day of month, 1 - 31 */ + png_byte hour; /* hour of day, 0 - 23 */ + png_byte minute; /* minute of hour, 0 - 59 */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ +} png_time; +typedef png_time * png_timep; +typedef const png_time * png_const_timep; +typedef png_time * * png_timepp; + +#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ + defined(PNG_USER_CHUNKS_SUPPORTED) +/* png_unknown_chunk is a structure to hold queued chunks for which there is + * no specific support. The idea is that we can use this to queue + * up private chunks for output even though the library doesn't actually + * know about their semantics. + * + * The data in the structure is set by libpng on read and used on write. + */ +typedef struct png_unknown_chunk_t +{ + png_byte name[5]; /* Textual chunk name with '\0' terminator */ + png_byte *data; /* Data, should not be modified on read! */ + png_size_t size; + + /* On write 'location' must be set using the flag values listed below. + * Notice that on read it is set by libpng however the values stored have + * more bits set than are listed below. Always treat the value as a + * bitmask. On write set only one bit - setting multiple bits may cause the + * chunk to be written in multiple places. + */ + png_byte location; /* mode of operation at read time */ +} +png_unknown_chunk; + +typedef png_unknown_chunk * png_unknown_chunkp; +typedef const png_unknown_chunk * png_const_unknown_chunkp; +typedef png_unknown_chunk * * png_unknown_chunkpp; +#endif + +/* Flag values for the unknown chunk location byte. */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_AFTER_IDAT 0x08 + +/* Maximum positive integer used in PNG is (2^31)-1 */ +#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) +#define PNG_UINT_32_MAX ((png_uint_32)(-1)) +#define PNG_SIZE_MAX ((png_size_t)(-1)) + +/* These are constants for fixed point values encoded in the + * PNG specification manner (x100000) + */ +#define PNG_FP_1 100000 +#define PNG_FP_HALF 50000 +#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) +#define PNG_FP_MIN (-PNG_FP_MAX) + +/* These describe the color_type field in png_info. */ +/* color type masks */ +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +/* color types. Note that not all combinations are legal */ +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) +/* aliases */ +#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA +#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA + +/* This is for compression type. PNG 1.0-1.2 only define the single type. */ +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE + +/* This is for filter type. PNG 1.0-1.2 only define the single type. */ +#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ +#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE + +/* These are for the interlacing type. These values should NOT be changed. */ +#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ +#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ +#define PNG_INTERLACE_LAST 2 /* Not a valid value */ + +/* These are for the oFFs chunk. These values should NOT be changed. */ +#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ +#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ +#define PNG_OFFSET_LAST 2 /* Not a valid value */ + +/* These are for the pCAL chunk. These values should NOT be changed. */ +#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ +#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ +#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ +#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ +#define PNG_EQUATION_LAST 4 /* Not a valid value */ + +/* These are for the sCAL chunk. These values should NOT be changed. */ +#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ +#define PNG_SCALE_METER 1 /* meters per pixel */ +#define PNG_SCALE_RADIAN 2 /* radians per pixel */ +#define PNG_SCALE_LAST 3 /* Not a valid value */ + +/* These are for the pHYs chunk. These values should NOT be changed. */ +#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ +#define PNG_RESOLUTION_METER 1 /* pixels/meter */ +#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ + +/* These are for the sRGB chunk. These values should NOT be changed. */ +#define PNG_sRGB_INTENT_PERCEPTUAL 0 +#define PNG_sRGB_INTENT_RELATIVE 1 +#define PNG_sRGB_INTENT_SATURATION 2 +#define PNG_sRGB_INTENT_ABSOLUTE 3 +#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ + +/* This is for text chunks */ +#define PNG_KEYWORD_MAX_LENGTH 79 + +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ +#define PNG_MAX_PALETTE_LENGTH 256 + +/* These determine if an ancillary chunk's data has been successfully read + * from the PNG header, or if the application has filled in the corresponding + * data in the info_struct to be written into the output file. The values + * of the PNG_INFO_<chunk> defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_size_t rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info * png_row_infop; +typedef png_row_info * * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. Note that the 'write' function must not + * modify the buffer it is passed. The 'read' function, on the other hand, is + * expected to return the read data in the buffer. + */ +typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); +typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t)); +typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); +typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, + int)); +typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); +typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); + +/* The following callback receives png_uint_32 row_number, int pass for the + * png_bytep data of the row. When transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, + png_bytep)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, + png_unknown_chunkp)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +/* not used anywhere */ +/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This must match the function definition in <setjmp.h>, and the application + * must include this before png.h to obtain the definition of jmp_buf. The + * function is required to be PNG_NORETURN, but this is not checked. If the + * function does return the application will crash via an abort() or similar + * system level call. + * + * If you get a warning here while building the library you may need to make + * changes to ensure that pnglibconf.h records the calling convention used by + * your compiler. This may be very difficult - try using a different compiler + * to build the library! + */ +PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ +/* Added to libpng-1.2.34 */ +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ +/* Added to libpng-1.4.0 */ +#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ +/* Added to libpng-1.5.4 */ +#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ +#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +/* NOTE: prior to 1.5 these functions had no 'API' style declaration, + * this allowed the zlib default functions to be used on Windows + * platforms. In 1.5 the zlib default malloc (which just calls malloc and + * ignores the first argument) should be completely compatible with the + * following. + */ +typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, + png_alloc_size_t)); +typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); + +/* Section 3: exported functions + * Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng-manual.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + * + * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in + * pngconf.h and in the *.dfn files in the scripts directory. + * + * PNG_EXPORT(ordinal, type, name, (args)); + * + * ordinal: ordinal that is used while building + * *.def files. The ordinal value is only + * relevant when preprocessing png.h with + * the *.dfn files for building symbol table + * entries, and are removed by pngconf.h. + * type: return type of the function + * name: function name + * args: function arguments, with types + * + * When we wish to append attributes to a function prototype we use + * the PNG_EXPORTA() macro instead. + * + * PNG_EXPORTA(ordinal, type, name, (args), attributes); + * + * ordinal, type, name, and args: same as in PNG_EXPORT(). + * attributes: function attributes + */ + +/* Returns the version number of the library */ +PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); + +/* Tell lib we have already handled the first <num_bytes> magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +PNG_EXPORTA(4, png_structp, png_create_read_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +PNG_EXPORTA(5, png_structp, png_create_write_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn), + PNG_ALLOCATED); + +PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, + (png_const_structrp png_ptr)); + +PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, + png_size_t size)); + +/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp + * match up. + */ +#ifdef PNG_SETJMP_SUPPORTED +/* This function returns the jmp_buf built in to *png_ptr. It must be + * supplied with an appropriate 'longjmp' function to use on that jmp_buf + * unless the default error function is overridden in which case NULL is + * acceptable. The size of the jmp_buf is checked against the actual size + * allocated by the library - the call will return NULL on a mismatch + * indicating an ABI mismatch. + */ +PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr, + png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); +# define png_jmpbuf(png_ptr) \ + (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) +#endif +/* This function should be used by libpng applications in place of + * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it + * will use it; otherwise it will call PNG_ABORT(). This function was + * added in libpng-1.5.0. + */ +PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), + PNG_NORETURN); + +#ifdef PNG_READ_SUPPORTED +/* Reset the compression stream */ +PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED); +#endif + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(11, png_structp, png_create_read_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +PNG_EXPORTA(12, png_structp, png_create_write_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +#endif + +/* Write the PNG file signature. */ +PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep + chunk_name, png_const_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, + png_const_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, + png_const_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); + +/* Allocate and initialize the info structure */ +PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), + PNG_ALLOCATED); + +/* DEPRECATED: this function allowed init structures to be created using the + * default allocation method (typically malloc). Use is deprecated in 1.6.0 and + * the API will be removed in the future. + */ +PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, + png_size_t png_info_struct_size), PNG_DEPRECATED); + +/* Writes all the PNG information before the image. */ +PNG_EXPORT(20, void, png_write_info_before_PLTE, + (png_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(21, void, png_write_info, + (png_structrp png_ptr, png_const_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. */ +PNG_EXPORT(22, void, png_read_info, + (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED + /* Convert to a US string format: there is no localization support in this + * routine. The original implementation used a 29 character buffer in + * png_struct, this will be removed in future versions. + */ +#if PNG_LIBPNG_VER < 10700 +/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ +PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, + png_const_timep ptime),PNG_DEPRECATED); +#endif +PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], + png_const_timep ptime)); +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* Convert from a struct tm to png_time */ +PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, + const struct tm * ttime)); + +/* Convert from time_t to png_time. Uses gmtime() */ +PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime)); +#endif /* CONVERT_tIME */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr)); +PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); +PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); +PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion + * of a tRNS chunk if present. + */ +PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand the grayscale to 24-bit RGB if necessary. */ +PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB to grayscale. */ +#define PNG_ERROR_ACTION_NONE 1 +#define PNG_ERROR_ACTION_WARN 2 +#define PNG_ERROR_ACTION_ERROR 3 +#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ + +PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr, + int error_action, double red, double green)) +PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green)) + +PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp + png_ptr)); +#endif + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, + png_colorp palette)); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* How the alpha channel is interpreted - this affects how the color channels + * of a PNG file are returned to the calling application when an alpha channel, + * or a tRNS chunk in a palette file, is present. + * + * This has no effect on the way pixels are written into a PNG output + * datastream. The color samples in a PNG datastream are never premultiplied + * with the alpha samples. + * + * The default is to return data according to the PNG specification: the alpha + * channel is a linear measure of the contribution of the pixel to the + * corresponding composited pixel, and the color channels are unassociated + * (not premultiplied). The gamma encoded color channels must be scaled + * according to the contribution and to do this it is necessary to undo + * the encoding, scale the color values, perform the composition and reencode + * the values. This is the 'PNG' mode. + * + * The alternative is to 'associate' the alpha with the color information by + * storing color channel values that have been scaled by the alpha. + * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes + * (the latter being the two common names for associated alpha color channels). + * + * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha + * value is equal to the maximum value. + * + * The final choice is to gamma encode the alpha channel as well. This is + * broken because, in practice, no implementation that uses this choice + * correctly undoes the encoding before handling alpha composition. Use this + * choice only if other serious errors in the software or hardware you use + * mandate it; the typical serious error is for dark halos to appear around + * opaque areas of the composited PNG image because of arithmetic overflow. + * + * The API function png_set_alpha_mode specifies which of these choices to use + * with an enumerated 'mode' value and the gamma of the required output: + */ +#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ +#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ +#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ +#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ +#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ +#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode, + double output_gamma)) +PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, + int mode, png_fixed_point output_gamma)) +#endif + +#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) +/* The output_gamma value is a screen gamma in libpng terminology: it expresses + * how to decode the output values, not how they are encoded. + */ +#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ +#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ +#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ +#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ +#endif + +/* The following are examples of calls to png_set_alpha_mode to achieve the + * required overall gamma correction and, where necessary, alpha + * premultiplication. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * This is the default libpng handling of the alpha channel - it is not + * pre-multiplied into the color components. In addition the call states + * that the output is for a sRGB system and causes all PNG files without gAMA + * chunks to be assumed to be encoded using sRGB. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * In this case the output is assumed to be something like an sRGB conformant + * display preceeded by a power-law lookup table of power 1.45. This is how + * early Mac systems behaved. + * + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); + * This is the classic Jim Blinn approach and will work in academic + * environments where everything is done by the book. It has the shortcoming + * of assuming that input PNG data with no gamma information is linear - this + * is unlikely to be correct unless the PNG files where generated locally. + * Most of the time the output precision will be so low as to show + * significant banding in dark areas of the image. + * + * png_set_expand_16(pp); + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); + * This is a somewhat more realistic Jim Blinn inspired approach. PNG files + * are assumed to have the sRGB encoding if not marked with a gamma value and + * the output is always 16 bits per component. This permits accurate scaling + * and processing of the data. If you know that your input PNG files were + * generated locally you might need to replace PNG_DEFAULT_sRGB with the + * correct value for your system. + * + * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); + * If you just need to composite the PNG image onto an existing background + * and if you control the code that does this you can use the optimization + * setting. In this case you just copy completely opaque pixels to the + * output. For pixels that are not completely transparent (you just skip + * those) you do the composition math using png_composite or png_composite_16 + * below then encode the resultant 8-bit or 16-bit values to match the output + * encoding. + * + * Other cases + * If neither the PNG nor the standard linear encoding work for you because + * of the software or hardware you use then you have a big problem. The PNG + * case will probably result in halos around the image. The linear encoding + * will probably result in a washed out, too bright, image (it's actually too + * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably + * substantially reduce the halos. Alternatively try: + * + * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); + * This option will also reduce the halos, but there will be slight dark + * halos round the opaque parts of the image where the background is light. + * In the OPTIMIZED mode the halos will be light halos where the background + * is dark. Take your pick - the halos are unavoidable unless you can get + * your hardware/software fixed! (The OPTIMIZED approach is slightly + * faster.) + * + * When the default gamma of PNG files doesn't match the output gamma. + * If you have PNG files with no gamma information png_set_alpha_mode allows + * you to provide a default gamma, but it also sets the ouput gamma to the + * matching value. If you know your PNG files have a gamma that doesn't + * match the output you can take advantage of the fact that + * png_set_alpha_mode always sets the output gamma but only sets the PNG + * default if it is not already set: + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * The first call sets both the default and the output gamma values, the + * second call overrides the output gamma without changing the default. This + * is easier than achieving the same effect with png_set_gamma. You must use + * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will + * fire if more than one call to png_set_alpha_mode and png_set_background is + * made in the same read operation, however multiple calls with PNG_ALPHA_PNG + * are ignored. + */ + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, + int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +# define PNG_FILLER_BEFORE 0 +# define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, + png_uint_32 filler, int flags)); +#endif /* READ_FILLER || WRITE_FILLER */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p + true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. + * MUST be called before png_read_update_info or png_start_read_image, + * otherwise it will not have the desired effect. Note that it is still + * necessary to call png_read_row or png_read_rows png_get_image_height + * times for each pass. +*/ +PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS by replacing with a background color. Prior to + * libpng-1.5.4 this API must not be called before the PNG file header has been + * read. Doing so will result in unexpected behavior and possible warnings or + * errors if the PNG file contains a bKGD chunk. + */ +PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)) +PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma)) +#endif +#ifdef PNG_READ_BACKGROUND_SUPPORTED +# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +# define PNG_BACKGROUND_GAMMA_SCREEN 1 +# define PNG_BACKGROUND_GAMMA_FILE 2 +# define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale a 16-bit depth file down to 8-bit, accurately. */ +PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ +/* Strip the second byte of information from a 16-bit depth file. */ +PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* Turn on quantizing, and reduce the palette to the number of colors + * available. + */ +PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_const_uint_16p histogram, int full_quantize)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* The threshold on gamma processing is configurable but hard-wired into the + * library. The following is the floating point variant. + */ +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) + +/* Handle gamma correction. Screen_gamma=(display_exponent). + * NOTE: this API simply sets the screen and file gamma values. It will + * therefore override the value for gamma in a PNG file if it is called after + * the file header has been read - use with care - call before reading the PNG + * file for best results! + * + * These routines accept the same gamma values as png_set_alpha_mode (described + * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either + * API (floating point or fixed.) Notice, however, that the 'file_gamma' value + * is the inverse of a 'screen gamma' value. + */ +PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr, + double screen_gamma, double override_file_gamma)) +PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr, + png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set how many lines between output flushes - 0 for no flushing */ +PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); +#endif + +/* Optional update palette with requested transformations */ +PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); + +/* Optional call to update the users info structure */ +PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, + png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. */ +PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read a row of data. */ +PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row, + png_bytep display_row)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the whole image into memory at once. */ +PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image)); +#endif + +/* Write a row of image data */ +PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr, + png_const_bytep row)); + +/* Write a few rows of image data: (*row) is not written; however, the type + * is declared as writeable to maintain compatibility with previous versions + * of libpng and to allow the 'display_row' array from read_rows to be passed + * unchanged to write_rows. + */ +PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row, + png_uint_32 num_rows)); + +/* Write the image data */ +PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); + +/* Write the end of the PNG file. */ +PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, + png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. */ +PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +/* Free any memory associated with the png_info_struct */ +PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr, + png_infopp info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr)); + +/* Set the libpng method of handling chunk CRC errors */ +PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action, + int ancil_action)); + +/* Values for png_set_crc_action() say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +#ifdef PNG_WRITE_SUPPORTED +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* Set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, + int filters)); +#endif /* WRITE */ + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#ifdef PNG_WRITE_SUPPORTED +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, + int heuristic_method, int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs)) +PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, + (png_structrp png_ptr, int heuristic_method, int num_weights, + png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs)) +#endif /* WRITE_WEIGHTED_FILTER */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED +PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr, + int level)); + +PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr, + int window_bits)); + +PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr, + int method)); +#endif /* WRITE_CUSTOMIZE_COMPRESSION */ + +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +/* Also set zlib parameters for compressing non-IDAT chunks */ +PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr, + int level)); + +PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr, + int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(225, void, png_set_text_compression_window_bits, + (png_structrp png_ptr, int window_bits)); + +PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr, + int method)); +#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ +#endif /* WRITE */ + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng-manual.txt for + * more information. + */ + +#ifdef PNG_STDIO_SUPPORTED +/* Initialize the input/output for the PNG file to the default functions. */ +PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + * It is probably a mistake to use NULL for output_flush_fn if + * write_data_fn is not also NULL unless you have built libpng with + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's + * default flush function, which uses the standard *FILE structure, will + * be used. + */ +PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); + +PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, + png_read_status_ptr read_row_fn)); + +PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr, + png_user_transform_ptr read_user_transform_fn)); +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr, + png_user_transform_ptr write_user_transform_fn)); +#endif + +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr, + png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, + (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +/* Return information about the row currently being processed. Note that these + * APIs do not fail but will return unexpected results if called outside a user + * transform callback. Also note that when transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp)); +PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +/* This callback is called only for *unknown* chunks. If + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known + * chunks to be treated as unknown, however in this case the callback must do + * any processing required by the chunk (e.g. by calling the appropriate + * png_set_ APIs.) + * + * There is no write support - on write, by default, all the chunks in the + * 'unknown' list are written in the specified position. + * + * The integer return from the callback function is interpreted thus: + * + * negative: An error occurred; png_chunk_error will be called. + * zero: The chunk was not handled, the chunk will be saved. A critical + * chunk will cause an error at this point unless it is to be saved. + * positive: The chunk was handled, libpng will ignore/discard it. + * + * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about + * how this behavior will change in libpng 1.7 + */ +PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr, + png_voidp progressive_ptr, png_progressive_info_ptr info_fn, + png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); + +/* Returns the user pointer associated with the push read functions */ +PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, + (png_const_structrp png_ptr)); + +/* Function to be called when data becomes available */ +PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, + png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* A function which may be called *only* within png_process_data to stop the + * processing of any more data. The function returns the number of bytes + * remaining, excluding any that libpng has cached internally. A subsequent + * call to png_process_data must supply these bytes again. If the argument + * 'save' is set to true the routine will first save all the pending data and + * will always return 0. + */ +PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save)); + +/* A function which may be called *only* outside (after) a call to + * png_process_data. It returns the number of bytes of data to skip in the + * input. Normally it will return 0, but if it returns a non-zero value the + * application must skip than number of bytes of input data and pass the + * following data to the next call to png_process_data. + */ +PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp)); + +/* Function that combines rows. 'new_row' is a flag that should come from + * the callback and be non-NULL if anything needs to be done; the library + * stores its own version of the new data internally and ignores the passed + * in value. + */ +PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr, + png_bytep old_row, png_const_bytep new_row)); +#endif /* PROGRESSIVE_READ */ + +PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); +/* Added at libpng version 1.4.0 */ +PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Added at libpng version 1.2.4 */ +PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + +/* Frees a pointer allocated by png_malloc() */ +PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); + +/* Free data that was allocated internally */ +PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 free_me, int num)); + +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application; this works on the png_info structure passed + * in, it does not change the state for other png_info structures. + * + * It is unlikely that this function works correctly as of 1.6.0 and using it + * may result either in memory leaks or double free of allocated data. + */ +PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, + png_inforp info_ptr, int freer, png_uint_32 mask)); + +/* Assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_FREE_UNKN 0x0200 +#endif +/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */ +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED); +PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr, + png_voidp ptr), PNG_DEPRECATED); +#endif + +#ifdef PNG_ERROR_TEXT_SUPPORTED +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr, + png_const_charp error_message), PNG_NORETURN); + +/* The same, but the chunk name is prepended to the error string. */ +PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr, + png_const_charp error_message), PNG_NORETURN); + +#else +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN); +# define png_error(s1,s2) png_err(s1) +# define png_chunk_error(s1,s2) png_err(s1) +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr, + png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr, + png_const_charp warning_message)); +#else +# define png_warning(s1,s2) ((void)(s1)) +# define png_chunk_warning(s1,s2) ((void)(s1)) +#endif + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +/* Benign error in libpng. Can continue, but may have a problem. + * User can choose whether to handle as a fatal error or as a warning. */ +PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); + +#ifdef PNG_READ_SUPPORTED +/* Same, chunk name is prepended to message (only during read) */ +PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); +#endif + +PNG_EXPORT(109, void, png_set_benign_errors, + (png_structrp png_ptr, int allowed)); +#else +# ifdef PNG_ALLOW_BENIGN_ERRORS +# define png_benign_error png_warning +# define png_chunk_benign_error png_chunk_warning +# else +# define png_benign_error png_error +# define png_chunk_benign_error png_chunk_error +# endif +#endif + +/* The png_set_<chunk> functions are for storing values in the png_info_struct. + * Similarly, the png_get_<chunk> calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_<chunk> functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* Returns row_pointers, which is an array of pointers to scanlines that was + * returned from png_read_png(). + */ +PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Set row_pointers, which is an array of pointers to scanlines for use + * by png_write_png(). + */ +PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr, + png_inforp info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image height in pixels. */ +PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image bit_depth. */ +PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image color_type. */ +PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image filter_type. */ +PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image interlace_type. */ +PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image compression_type. */ +PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +#endif /* EASY_ACCESS */ + +#ifdef PNG_READ_SUPPORTED +/* Returns pointer to signature string read from PNG header */ +PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, + png_const_inforp info_ptr)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, + png_inforp info_ptr, png_color_16p *background)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_color_16p background)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)) +PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z, + double *green_X, double *green_Y, double *green_Z, double *blue_X, + double *blue_Y, double *blue_Z)) +PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_white_x, png_fixed_point *int_white_y, + png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, + png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) +PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, png_fixed_point *int_green_X, + png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z)) +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr, + png_inforp info_ptr, + double white_x, double white_y, double red_x, double red_y, double green_x, + double green_y, double blue_x, double blue_y)) +PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr, + png_inforp info_ptr, double red_X, double red_Y, double red_Z, + double green_X, double green_Y, double green_Z, double blue_X, + double blue_Y, double blue_Z)) +PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_white_x, + png_fixed_point int_white_y, png_fixed_point int_red_x, + png_fixed_point int_red_y, png_fixed_point int_green_x, + png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)) +PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z)) +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, + png_const_inforp info_ptr, double *file_gamma)) +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_file_gamma)) +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, + png_inforp info_ptr, double file_gamma)) +PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, png_fixed_point int_file_gamma)) +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_16p *hist)); +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_uint_16p hist)); +#endif + +PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr, + png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, png_charp *purpose, png_int_32 *X0, + png_int_32 *X1, int *type, int *nparams, png_charp *units, + png_charpp *params)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_const_charp units, png_charpp params)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr, + png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr, + png_inforp info_ptr, png_colorp *palette, int *num_palette)); + +PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, + png_inforp info_ptr, png_const_colorp palette, int num_palette)); + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_color_8p *sig_bit)); +#endif + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_color_8p sig_bit)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *file_srgb_intent)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, + png_inforp info_ptr, int srgb_intent)); +PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, + png_inforp info_ptr, int srgb_intent)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, + png_inforp info_ptr, png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_sPLT_tpp entries)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)); +#endif + +#ifdef PNG_TEXT_SUPPORTED +/* png_get_text also returns the number of text chunks in *num_text */ +PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr, + png_inforp info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#ifdef PNG_TEXT_SUPPORTED +PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_textp text_ptr, int num_text)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr, + png_inforp info_ptr, png_timep *mod_time)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_timep mod_time)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, + png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, + png_color_16p *trans_color)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr, + png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); +#endif + +#ifdef PNG_sCAL_SUPPORTED +PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *unit, double *width, double *height)) +#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ + defined(PNG_FLOATING_POINT_SUPPORTED) +/* NOTE: this API is currently implemented using floating point arithmetic, + * consequently it can only be used on systems with floating point support. + * In any case the range of values supported by png_fixed_point is small and it + * is highly recommended that png_get_sCAL_s be used instead. + */ +PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, + png_fixed_point *width, png_fixed_point *height)) +#endif +PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, + (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, + png_charpp swidth, png_charpp sheight)); + +PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, double width, double height)) +PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, png_fixed_point width, + png_fixed_point height)) +PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, + png_inforp info_ptr, int unit, + png_const_charp swidth, png_const_charp sheight)); +#endif /* sCAL */ + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +/* Provide the default handling for all unknown chunks or, optionally, for + * specific unknown chunks. + * + * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was + * ignored and the default was used, the per-chunk setting only had an effect on + * write. If you wish to have chunk-specific handling on read in code that must + * work on earlier versions you must use a user chunk callback to specify the + * desired handling (keep or discard.) + * + * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The + * parameter is interpreted as follows: + * + * READ: + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Known chunks: do normal libpng processing, do not keep the chunk (but + * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + * Unknown chunks: for a specific chunk use the global default, when used + * as the default discard the chunk data. + * PNG_HANDLE_CHUNK_NEVER: + * Discard the chunk data. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Keep the chunk data if the chunk is not critical else raise a chunk + * error. + * PNG_HANDLE_CHUNK_ALWAYS: + * Keep the chunk data. + * + * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, + * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent + * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks + * it simply resets the behavior to the libpng default. + * + * INTERACTION WTIH USER CHUNK CALLBACKS: + * The per-chunk handling is always used when there is a png_user_chunk_ptr + * callback and the callback returns 0; the chunk is then always stored *unless* + * it is critical and the per-chunk setting is other than ALWAYS. Notice that + * the global default is *not* used in this case. (In effect the per-chunk + * value is incremented to at least IF_SAFE.) + * + * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and + * per-chunk defaults will be honored. If you want to preserve the current + * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE + * as the default - if you don't do this libpng 1.6 will issue a warning. + * + * If you want unhandled unknown chunks to be discarded in libpng 1.6 and + * earlier simply return '1' (handled). + * + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: + * If this is *not* set known chunks will always be handled by libpng and + * will never be stored in the unknown chunk list. Known chunks listed to + * png_set_keep_unknown_chunks will have no effect. If it is set then known + * chunks listed with a keep other than AS_DEFAULT will *never* be processed + * by libpng, in addition critical chunks must either be processed by the + * callback or saved. + * + * The IHDR and IEND chunks must not be listed. Because this turns off the + * default handling for chunks that would otherwise be recognized the + * behavior of libpng transformations may well become incorrect! + * + * WRITE: + * When writing chunks the options only apply to the chunks specified by + * png_set_unknown_chunks (below), libpng will *always* write known chunks + * required by png_set_ calls and will always write the core critical chunks + * (as required for PLTE). + * + * Each chunk in the png_set_unknown_chunks list is looked up in the + * png_set_keep_unknown_chunks list to find the keep setting, this is then + * interpreted as follows: + * + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Write safe-to-copy chunks and write other chunks if the global + * default is set to _ALWAYS, otherwise don't write this chunk. + * PNG_HANDLE_CHUNK_NEVER: + * Do not write the chunk. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Write the chunk if it is safe-to-copy, otherwise do not write it. + * PNG_HANDLE_CHUNK_ALWAYS: + * Write the chunk. + * + * Note that the default behavior is effectively the opposite of the read case - + * in read unknown chunks are not stored by default, in write they are written + * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different + * - on write the safe-to-copy bit is checked, on read the critical bit is + * checked and on read if the chunk is critical an error will be raised. + * + * num_chunks: + * =========== + * If num_chunks is positive, then the "keep" parameter specifies the manner + * for handling only those chunks appearing in the chunk_list array, + * otherwise the chunk list array is ignored. + * + * If num_chunks is 0 the "keep" parameter specifies the default behavior for + * unknown chunks, as described above. + * + * If num_chunks is negative, then the "keep" parameter specifies the manner + * for handling all unknown chunks plus all chunks recognized by libpng + * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to + * be processed by libpng. + */ +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, + int keep, png_const_bytep chunk_list, int num_chunks)); + +/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; + * the result is therefore true (non-zero) if special handling is required, + * false for the default handling. + */ +PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, + png_const_bytep chunk_name)); +#endif + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_unknown_chunkp unknowns, + int num_unknowns)); + /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added + * unknowns to the location currently stored in the png_struct. This is + * invariably the wrong value on write. To fix this call the following API + * for each chunk in the list with the correct location. If you know your + * code won't be compiled on earlier versions you can rely on + * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing + * the correct thing. + */ + +PNG_EXPORT(175, void, png_set_unknown_chunk_location, + (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); + +PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, + png_inforp info_ptr, png_unknown_chunkpp entries)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + * If you need to turn it off for a chunk that your application has freed, + * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); + */ +PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr, + png_inforp info_ptr, int mask)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* The "params" pointer is currently not used and is for future expansion. */ +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif +#ifdef PNG_WRITE_SUPPORTED +PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif +#endif + +PNG_EXPORT(180, png_const_charp, png_get_copyright, + (png_const_structrp png_ptr)); +PNG_EXPORT(181, png_const_charp, png_get_header_ver, + (png_const_structrp png_ptr)); +PNG_EXPORT(182, png_const_charp, png_get_header_version, + (png_const_structrp png_ptr)); +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, + (png_const_structrp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr, + png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 +#define PNG_HANDLE_CHUNK_LAST 4 + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. + */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr, + png_uint_32 strip_mode)); +#endif + +/* Added in libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr, + png_uint_32 user_width_max, png_uint_32 user_height_max)); +PNG_EXPORT(187, png_uint_32, png_get_user_width_max, + (png_const_structrp png_ptr)); +PNG_EXPORT(188, png_uint_32, png_get_user_height_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.0 */ +PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, + png_uint_32 user_chunk_cache_max)); +PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.1 */ +PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, + png_alloc_size_t user_chunk_cache_max)); +PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, + (png_const_structrp png_ptr)); +#endif + +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_FP_EXPORT(196, float, png_get_x_offset_inches, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, + png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +# ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +# endif /* pHYs */ +#endif /* INCH_CONVERSIONS */ + +/* Added in libpng-1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr)); + +/* Removed from libpng 1.6; use png_get_io_chunk_type. */ +PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), + PNG_DEPRECATED) + +PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, + (png_const_structrp png_ptr)); + +/* The flags returned by png_get_io_state() are the following: */ +# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ +# define PNG_IO_READING 0x0001 /* currently reading */ +# define PNG_IO_WRITING 0x0002 /* currently writing */ +# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ +# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ +# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ +# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ +# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ +# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ +#endif /* IO_STATE */ + +/* Interlace support. The following macros are always defined so that if + * libpng interlace handling is turned off the macros may be used to handle + * interlaced images within the application. + */ +#define PNG_INTERLACE_ADAM7_PASSES 7 + +/* Two macros to return the first row and first column of the original, + * full, image which appears in a given pass. 'pass' is in the range 0 + * to 6 and the result is in the range 0 to 7. + */ +#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) +#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) + +/* A macro to return the offset between pixels in the output row for a pair of + * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that + * follows. Note that ROW_OFFSET is the offset from one row to the next whereas + * COL_OFFSET is from one column to the next, within a row. + */ +#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) +#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) + +/* Two macros to help evaluate the number of rows or columns in each + * pass. This is expressed as a shift - effectively log2 of the number or + * rows or columns in each 8x8 tile of the original image. + */ +#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) +#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) + +/* Hence two macros to determine the number of rows or columns in a given + * pass of an image given its height or width. In fact these macros may + * return non-zero even though the sub-image is empty, because the other + * dimension may be empty for a small image. + */ +#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\ + -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass)) +#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\ + -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass)) + +/* For the reader row callbacks (both progressive and sequential) it is + * necessary to find the row in the output image given a row in an interlaced + * image, so two more macros: + */ +#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ + (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass)) +#define PNG_COL_FROM_PASS_COL(x_in, pass) \ + (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass)) + +/* Two macros which return a boolean (0 or 1) saying whether the given row + * or column is in a particular pass. These use a common utility macro that + * returns a mask for a given pass - the offset 'off' selects the row or + * column version. The mask has the appropriate bit set for each column in + * the tile. + */ +#define PNG_PASS_MASK(pass,off) ( \ + ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \ + ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) + +#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ + ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) +#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ + ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ + * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 \ + - (png_uint_16)(alpha)) + 128); \ + (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ + * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(65535 \ + - (png_uint_32)(alpha)) + 32768); \ + (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); } + +#else /* Standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = \ + (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + 127) / 255)) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = \ + (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ + 32767) / 65535)) +#endif /* READ_COMPOSITE_NODIV */ + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); +PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); +PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); +#endif + +PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr, + png_const_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); +#endif +#ifdef PNG_SAVE_INT_32_SUPPORTED +PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); +#endif + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ +#endif + +#ifdef PNG_USE_READ_MACROS +/* Inline macros to do direct reads of bytes from the input buffer. + * The png_get_int_32() routine assumes we are using two's complement + * format for negative values, which is almost certainly true. + */ +# define PNG_get_uint_32(buf) \ + (((png_uint_32)(*(buf)) << 24) + \ + ((png_uint_32)(*((buf) + 1)) << 16) + \ + ((png_uint_32)(*((buf) + 2)) << 8) + \ + ((png_uint_32)(*((buf) + 3)))) + + /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the + * function) incorrectly returned a value of type png_uint_32. + */ +# define PNG_get_uint_16(buf) \ + ((png_uint_16) \ + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) + +# define PNG_get_int_32(buf) \ + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ + : (png_int_32)png_get_uint_32(buf))) + + /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, + * but defining a macro name prefixed with PNG_PREFIX. + */ +# ifndef PNG_PREFIX +# define png_get_uint_32(buf) PNG_get_uint_32(buf) +# define png_get_uint_16(buf) PNG_get_uint_16(buf) +# define png_get_int_32(buf) PNG_get_int_32(buf) +# endif +#else +# ifdef PNG_PREFIX + /* No macros; revert to the (redefined) function */ +# define PNG_get_uint_32 (png_get_uint_32) +# define PNG_get_uint_16 (png_get_uint_16) +# define PNG_get_int_32 (png_get_int_32) +# endif +#endif + +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +/******************************************************************************* + * SIMPLIFIED API + ******************************************************************************* + * + * Please read the documentation in libpng-manual.txt (TODO: write said + * documentation) if you don't understand what follows. + * + * The simplified API hides the details of both libpng and the PNG file format + * itself. It allows PNG files to be read into a very limited number of + * in-memory bitmap formats or to be written from the same formats. If these + * formats do not accomodate your needs then you can, and should, use the more + * sophisticated APIs above - these support a wide variety of in-memory formats + * and a wide variety of sophisticated transformations to those formats as well + * as a wide variety of APIs to manipulate ancillary information. + * + * To read a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure (see below) on the stack and set the + * version field to PNG_IMAGE_VERSION. + * 2) Call the appropriate png_image_begin_read... function. + * 3) Set the png_image 'format' member to the required sample format. + * 4) Allocate a buffer for the image and, if required, the color-map. + * 5) Call png_image_finish_read to read the image and, if required, the + * color-map into your buffers. + * + * There are no restrictions on the format of the PNG input itself; all valid + * color types, bit depths, and interlace methods are acceptable, and the + * input image is transformed as necessary to the requested in-memory format + * during the png_image_finish_read() step. The only caveat is that if you + * request a color-mapped image from a PNG that is full-color or makes + * complex use of an alpha channel the transformation is extremely lossy and the + * result may look terrible. + * + * To write a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. + * 2) Initialize the members of the structure that describe the image, setting + * the 'format' member to the format of the image samples. + * 3) Call the appropriate png_image_write... function with a pointer to the + * image and, if necessary, the color-map to write the PNG data. + * + * png_image is a structure that describes the in-memory format of an image + * when it is being read or defines the in-memory format of an image that you + * need to write: + */ +#define PNG_IMAGE_VERSION 1 + +typedef struct png_control *png_controlp; +typedef struct +{ + png_controlp opaque; /* Initialize to NULL, free with png_image_free */ + png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ + png_uint_32 width; /* Image width in pixels (columns) */ + png_uint_32 height; /* Image height in pixels (rows) */ + png_uint_32 format; /* Image format as defined below */ + png_uint_32 flags; /* A bit mask containing informational flags */ + png_uint_32 colormap_entries; + /* Number of entries in the color-map */ + + /* In the event of an error or warning the following field will be set to a + * non-zero value and the 'message' field will contain a '\0' terminated + * string with the libpng error or warning message. If both warnings and + * an error were encountered, only the error is recorded. If there + * are multiple warnings, only the first one is recorded. + * + * The upper 30 bits of this value are reserved, the low two bits contain + * a value as follows: + */ +# define PNG_IMAGE_WARNING 1 +# define PNG_IMAGE_ERROR 2 + /* + * The result is a two-bit code such that a value more than 1 indicates + * a failure in the API just called: + * + * 0 - no warning or error + * 1 - warning + * 2 - error + * 3 - error preceded by warning + */ +# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) + + png_uint_32 warning_or_error; + + char message[64]; +} png_image, *png_imagep; + +/* The samples of the image have one to four channels whose components have + * original values in the range 0 to 1.0: + * + * 1: A single gray or luminance channel (G). + * 2: A gray/luminance channel and an alpha channel (GA). + * 3: Three red, green, blue color channels (RGB). + * 4: Three color channels and an alpha channel (RGBA). + * + * The components are encoded in one of two ways: + * + * a) As a small integer, value 0..255, contained in a single byte. For the + * alpha channel the original value is simply value/255. For the color or + * luminance channels the value is encoded according to the sRGB specification + * and matches the 8-bit format expected by typical display devices. + * + * The color/gray channels are not scaled (pre-multiplied) by the alpha + * channel and are suitable for passing to color management software. + * + * b) As a value in the range 0..65535, contained in a 2-byte integer. All + * channels can be converted to the original value by dividing by 65535; all + * channels are linear. Color channels use the RGB encoding (RGB end-points) of + * the sRGB specification. This encoding is identified by the + * PNG_FORMAT_FLAG_LINEAR flag below. + * + * When the simplified API needs to convert between sRGB and linear colorspaces, + * the actual sRGB transfer curve defined in the sRGB specification (see the + * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 + * approximation used elsewhere in libpng. + * + * When an alpha channel is present it is expected to denote pixel coverage + * of the color or luminance channels and is returned as an associated alpha + * channel: the color/gray channels are scaled (pre-multiplied) by the alpha + * value. + * + * The samples are either contained directly in the image data, between 1 and 8 + * bytes per pixel according to the encoding, or are held in a color-map indexed + * by bytes in the image data. In the case of a color-map the color-map entries + * are individual samples, encoded as above, and the image data has one byte per + * pixel to select the relevant sample from the color-map. + */ + +/* PNG_FORMAT_* + * + * #defines to be used in png_image::format. Each #define identifies a + * particular layout of sample data and, if present, alpha values. There are + * separate defines for each of the two component encodings. + * + * A format is built up using single bit flag values. All combinations are + * valid. Formats can be built up from the flag values or you can use one of + * the predefined values below. When testing formats always use the FORMAT_FLAG + * macros to test for individual features - future versions of the library may + * add new flags. + * + * When reading or writing color-mapped images the format should be set to the + * format of the entries in the color-map then png_image_{read,write}_colormap + * called to read or write the color-map and set the format correctly for the + * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! + * + * NOTE: libpng can be built with particular features disabled, if you see + * compiler errors because the definition of one of the following flags has been + * compiled out it is because libpng does not have the required support. It is + * possible, however, for the libpng configuration to enable the format on just + * read or just write; in that case you may see an error at run time. You can + * guard against this by checking for the definition of the appropriate + * "_SUPPORTED" macro, one of: + * + * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED + */ +#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ +#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ +#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */ +#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ + +#ifdef PNG_FORMAT_BGR_SUPPORTED +# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ +#endif + +#ifdef PNG_FORMAT_AFIRST_SUPPORTED +# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ +#endif + +/* Commonly used formats have predefined macros. + * + * First the single byte (sRGB) formats: + */ +#define PNG_FORMAT_GRAY 0 +#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA +#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR +#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) +#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) + +/* Then the linear 2-byte formats. When naming these "Y" is used to + * indicate a luminance (gray) channel. + */ +#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR +#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) +#define PNG_FORMAT_LINEAR_RGB_ALPHA \ + (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) + +/* With color-mapped formats the image data is one byte for each pixel, the byte + * is an index into the color-map which is formatted as above. To obtain a + * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP + * to one of the above definitions, or you can use one of the definitions below. + */ +#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) + +/* PNG_IMAGE macros + * + * These are convenience macros to derive information from a png_image + * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the + * actual image sample values - either the entries in the color-map or the + * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values + * for the pixels and will always return 1 for color-mapped formats. The + * remaining macros return information about the rows in the image and the + * complete image. + * + * NOTE: All the macros that take a png_image::format parameter are compile time + * constants if the format parameter is, itself, a constant. Therefore these + * macros can be used in array declarations and case labels where required. + * Similarly the macros are also pre-processor constants (sizeof is not used) so + * they can be used in #if tests. + * + * First the information about the samples. + */ +#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ + (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) + /* Return the total number of channels in a given format: 1..4 */ + +#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ + ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) + /* Return the size in bytes of a single component of a pixel or color-map + * entry (as appropriate) in the image: 1 or 2. + */ + +#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) + /* This is the size of the sample data for one sample. If the image is + * color-mapped it is the size of one color-map entry (and image pixels are + * one byte in size), otherwise it is the size of one image pixel. + */ + +#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) + /* The maximum size of the color-map required by the format expressed in a + * count of components. This can be used to compile-time allocate a + * color-map: + * + * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; + * + * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; + * + * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the + * information from one of the png_image_begin_read_ APIs and dynamically + * allocate the required memory. + */ + +/* Corresponding information about the pixels */ +#define PNG_IMAGE_PIXEL_(test,fmt)\ + (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) + +#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) + /* The number of separate channels (components) in a pixel; 1 for a + * color-mapped image. + */ + +#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) + /* The size, in bytes, of each component in a pixel; 1 for a color-mapped + * image. + */ + +#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) + /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ + +/* Information about the whole row, or whole image */ +#define PNG_IMAGE_ROW_STRIDE(image)\ + (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) + /* Return the total number of components in a single row of the image; this + * is the minimum 'row stride', the minimum count of components between each + * row. For a color-mapped image this is the minimum number of bytes in a + * row. + */ + +#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ + (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) + /* Return the size, in bytes, of an image buffer given a png_image and a row + * stride - the number of components to leave space for in each row. + */ + +#define PNG_IMAGE_SIZE(image)\ + PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) + /* Return the size, in bytes, of the image in memory given just a png_image; + * the row stride is the minimum stride required for the image. + */ + +#define PNG_IMAGE_COLORMAP_SIZE(image)\ + (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) + /* Return the size, in bytes, of the color-map of this image. If the image + * format is not a color-map format this will return a size sufficient for + * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if + * you don't want to allocate a color-map in this case. + */ + +/* PNG_IMAGE_FLAG_* + * + * Flags containing additional information about the image are held in the + * 'flags' field of png_image. + */ +#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 + /* This indicates the the RGB values of the in-memory bitmap do not + * correspond to the red, green and blue end-points defined by sRGB. + */ + +#define PNG_IMAGE_FLAG_FAST 0x02 + /* On write emphasise speed over compression; the resultant PNG file will be + * larger but will be produced significantly faster, particular for large + * images. Do not use this option for images which will be distributed, only + * used it when producing intermediate files that will be read back in + * repeatedly. For a typical 24-bit image the option will double the read + * speed at the cost of increasing the image size by 25%, however for many + * more compressible images the PNG file can be 10 times larger with only a + * slight speed gain. + */ + +#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 + /* On read if the image is a 16-bit per component image and there is no gAMA + * or sRGB chunk assume that the components are sRGB encoded. Notice that + * images output by the simplified API always have gamma information; setting + * this flag only affects the interpretation of 16-bit images from an + * external source. It is recommended that the application expose this flag + * to the user; the user can normally easily recognize the difference between + * linear and sRGB encoding. This flag has no effect on write - the data + * passed to the write APIs must have the correct encoding (as defined + * above.) + * + * If the flag is not set (the default) input 16-bit per component data is + * assumed to be linear. + * + * NOTE: the flag can only be set after the png_image_begin_read_ call, + * because that call initializes the 'flags' field. + */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* READ APIs + * --------- + * + * The png_image passed to the read APIs must have been initialized by setting + * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) + */ +#ifdef PNG_STDIO_SUPPORTED +PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, + const char *file_name)); + /* The named file is opened for read and the image header is filled in + * from the PNG header in the file. + */ + +PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, + FILE* file)); + /* The PNG header is read from the stdio FILE object. */ +#endif /* STDIO */ + +PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, + png_const_voidp memory, png_size_t size)); + /* The PNG header is read from the given memory buffer. */ + +PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, + png_const_colorp background, void *buffer, png_int_32 row_stride, + void *colormap)); + /* Finish reading the image into the supplied buffer and clean up the + * png_image structure. + * + * row_stride is the step, in byte or 2-byte units as appropriate, + * between adjacent rows. A positive stride indicates that the top-most row + * is first in the buffer - the normal top-down arrangement. A negative + * stride indicates that the bottom-most row is first in the buffer. + * + * background need only be supplied if an alpha channel must be removed from + * a png_byte format and the removal is to be done by compositing on a solid + * color; otherwise it may be NULL and any composition will be done directly + * onto the buffer. The value is an sRGB color to use for the background, + * for grayscale output the green channel is used. + * + * background must be supplied when an alpha channel must be removed from a + * single byte color-mapped output format, in other words if: + * + * 1) The original format from png_image_begin_read_from_* had + * PNG_FORMAT_FLAG_ALPHA set. + * 2) The format set by the application does not. + * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and + * PNG_FORMAT_FLAG_LINEAR *not* set. + * + * For linear output removing the alpha channel is always done by compositing + * on black and background is ignored. + * + * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must + * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. + * image->colormap_entries will be updated to the actual number of entries + * written to the colormap; this may be less than the original value. + */ + +PNG_EXPORT(238, void, png_image_free, (png_imagep image)); + /* Free any data allocated by libpng in image->opaque, setting the pointer to + * NULL. May be called at any time after the structure is initialized. + */ +#endif /* SIMPLIFIED_READ */ + +#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED +#ifdef PNG_STDIO_SUPPORTED +/* WRITE APIS + * ---------- + * For write you must initialize a png_image structure to describe the image to + * be written. To do this use memset to set the whole structure to 0 then + * initialize fields describing your image. + * + * version: must be set to PNG_IMAGE_VERSION + * opaque: must be initialized to NULL + * width: image width in pixels + * height: image height in rows + * format: the format of the data (image and color-map) you wish to write + * flags: set to 0 unless one of the defined flags applies; set + * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB + * values do not correspond to the colors in sRGB. + * colormap_entries: set to the number of entries in the color-map (0 to 256) + */ +PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, + const char *file, int convert_to_8bit, const void *buffer, + png_int_32 row_stride, const void *colormap)); + /* Write the image to the named file. */ + +PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, + int convert_to_8_bit, const void *buffer, png_int_32 row_stride, + const void *colormap)); + /* Write the image to the given (FILE*). */ + +/* With both write APIs if image is in one of the linear formats with 16-bit + * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG + * gamma encoded according to the sRGB specification, otherwise a 16-bit linear + * encoded PNG file is written. + * + * With color-mapped data formats the colormap parameter point to a color-map + * with at least image->colormap_entries encoded in the specified format. If + * the format is linear the written PNG color-map will be converted to sRGB + * regardless of the convert_to_8_bit flag. + * + * With all APIs row_stride is handled as in the read APIs - it is the spacing + * from one row to the next in component sized units (1 or 2 bytes) and if + * negative indicates a bottom-up row layout in the buffer. + * + * Note that the write API does not support interlacing or sub-8-bit pixels. + */ +#endif /* STDIO */ +#endif /* SIMPLIFIED_WRITE */ +/******************************************************************************* + * END OF SIMPLIFIED API + ******************************************************************************/ +#endif /* SIMPLIFIED_{READ|WRITE} */ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +PNG_EXPORT(242, void, png_set_check_for_invalid_index, + (png_structrp png_ptr, int allowed)); +# ifdef PNG_GET_PALETTE_MAX_SUPPORTED +PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, + png_const_infop info_ptr)); +# endif +#endif /* CHECK_FOR_INVALID_INDEX */ + +/******************************************************************************* + * IMPLEMENTATION OPTIONS + ******************************************************************************* + * + * Support for arbitrary implementation-specific optimizations. The API allows + * particular options to be turned on or off. 'Option' is the number of the + * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given + * by the PNG_OPTION_ defines below. + * + * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions, + * are detected at run time, however sometimes it may be impossible + * to do this in user mode, in which case it is necessary to discover + * the capabilities in an OS specific way. Such capabilities are + * listed here when libpng has support for them and must be turned + * ON by the application if present. + * + * SOFTWARE: sometimes software optimizations actually result in performance + * decrease on some architectures or systems, or with some sets of + * PNG images. 'Software' options allow such optimizations to be + * selected at run time. + */ +#ifdef PNG_SET_OPTION_SUPPORTED +#ifdef PNG_ARM_NEON_API_SUPPORTED +# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ +#endif +#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ +#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ +#define PNG_OPTION_NEXT 6 /* Next option - numbers must be even */ + +/* Return values: NOTE: there are four values and 'off' is *not* zero */ +#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ +#define PNG_OPTION_INVALID 1 /* Option number out of range */ +#define PNG_OPTION_OFF 2 +#define PNG_OPTION_ON 3 + +PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, + int onoff)); +#endif /* SET_OPTION */ + +/******************************************************************************* + * END OF HARDWARE AND SOFTWARE OPTIONS + ******************************************************************************/ + +/* Maintainer: Put new public prototypes here ^, in libpng.3, in project + * defs, and in scripts/symbols.def. + */ + +/* The last ordinal number (this is the *last* one already used; the next + * one to use is one more than this.) + */ +#ifdef PNG_EXPORT_LAST_ORDINAL + PNG_EXPORT_LAST_ORDINAL(244); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* Do not put anything past this line */ +#endif /* PNG_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/pngconf.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/pngconf.h new file mode 100644 index 00000000..3f9493e4 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/pngconf.h @@ -0,0 +1,622 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.6.17, March 26, 2015 + * + * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ + +/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C + * compiler for correct compilation. The following header files are required by + * the standard. If your compiler doesn't provide these header files, or they + * do not match the standard, you will need to provide/improve them. + */ +#include <limits.h> +#include <stddef.h> + +/* Library header files. These header files are all defined by ISOC90; libpng + * expects conformant implementations, however, an ISOC90 conformant system need + * not provide these header files if the functionality cannot be implemented. + * In this case it will be necessary to disable the relevant parts of libpng in + * the build of pnglibconf.h. + * + * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not + * include this unnecessary header file. + */ + +#ifdef PNG_STDIO_SUPPORTED + /* Required for the definition of FILE: */ +# include <stdio.h> +#endif + +#ifdef PNG_SETJMP_SUPPORTED + /* Required for the definition of jmp_buf and the declaration of longjmp: */ +# include <setjmp.h> +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED + /* Required for struct tm: */ +# include <time.h> +#endif + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using + * PNG_NO_CONST; this is no longer supported except for data declarations which + * apparently still cause problems in 2011 on some compilers. + */ +#define PNG_CONST const /* backward compatibility only */ + +/* This controls optimization of the reading of 16 and 32 bit values + * from PNG files. It can be set on a per-app-file basis - it + * just changes whether a macro is used when the function is called. + * The library builder sets the default; if read functions are not + * built into the library the macro implementation is forced on. + */ +#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED +# define PNG_USE_READ_MACROS +#endif +#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) +# if PNG_DEFAULT_READ_MACROS +# define PNG_USE_READ_MACROS +# endif +#endif + +/* COMPILER SPECIFIC OPTIONS. + * + * These options are provided so that a variety of difficult compilers + * can be used. Some are fixed at build time (e.g. PNG_API_RULE + * below) but still have compiler specific implementations, others + * may be changed on a per-file basis when compiling against libpng. + */ + +/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect + * against legacy (pre ISOC90) compilers that did not understand function + * prototypes. It is not required for modern C compilers. + */ +#ifndef PNGARG +# define PNGARG(arglist) arglist +#endif + +/* Function calling conventions. + * ============================= + * Normally it is not necessary to specify to the compiler how to call + * a function - it just does it - however on x86 systems derived from + * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems + * and some others) there are multiple ways to call a function and the + * default can be changed on the compiler command line. For this reason + * libpng specifies the calling convention of every exported function and + * every function called via a user supplied function pointer. This is + * done in this file by defining the following macros: + * + * PNGAPI Calling convention for exported functions. + * PNGCBAPI Calling convention for user provided (callback) functions. + * PNGCAPI Calling convention used by the ANSI-C library (required + * for longjmp callbacks and sometimes used internally to + * specify the calling convention for zlib). + * + * These macros should never be overridden. If it is necessary to + * change calling convention in a private build this can be done + * by setting PNG_API_RULE (which defaults to 0) to one of the values + * below to select the correct 'API' variants. + * + * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. + * This is correct in every known environment. + * PNG_API_RULE=1 Use the operating system convention for PNGAPI and + * the 'C' calling convention (from PNGCAPI) for + * callbacks (PNGCBAPI). This is no longer required + * in any known environment - if it has to be used + * please post an explanation of the problem to the + * libpng mailing list. + * + * These cases only differ if the operating system does not use the C + * calling convention, at present this just means the above cases + * (x86 DOS/Windows sytems) and, even then, this does not apply to + * Cygwin running on those systems. + * + * Note that the value must be defined in pnglibconf.h so that what + * the application uses to call the library matches the conventions + * set when building the library. + */ + +/* Symbol export + * ============= + * When building a shared library it is almost always necessary to tell + * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' + * is used to mark the symbols. On some systems these symbols can be + * extracted at link time and need no special processing by the compiler, + * on other systems the symbols are flagged by the compiler and just + * the declaration requires a special tag applied (unfortunately) in a + * compiler dependent way. Some systems can do either. + * + * A small number of older systems also require a symbol from a DLL to + * be flagged to the program that calls it. This is a problem because + * we do not know in the header file included by application code that + * the symbol will come from a shared library, as opposed to a statically + * linked one. For this reason the application must tell us by setting + * the magic flag PNG_USE_DLL to turn on the special processing before + * it includes png.h. + * + * Four additional macros are used to make this happen: + * + * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from + * the build or imported if PNG_USE_DLL is set - compiler + * and system specific. + * + * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to + * 'type', compiler specific. + * + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to + * make a symbol exported from the DLL. Not used in the + * public header files; see pngpriv.h for how it is used + * in the libpng build. + * + * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come + * from a DLL - used to define PNG_IMPEXP when + * PNG_USE_DLL is set. + */ + +/* System specific discovery. + * ========================== + * This code is used at build time to find PNG_IMPEXP, the API settings + * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL + * import processing is possible. On Windows systems it also sets + * compiler-specific macros to the values required to change the calling + * conventions of the various functions. + */ +#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ + defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) + /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or + * MinGW on any architecture currently supported by Windows. Also includes + * Watcom builds but these need special treatment because they are not + * compatible with GCC or Visual C because of different calling conventions. + */ +# if PNG_API_RULE == 2 + /* If this line results in an error, either because __watcall is not + * understood or because of a redefine just below you cannot use *this* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ +# define PNGCAPI __watcall +# endif + +# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) +# define PNGCAPI __cdecl +# if PNG_API_RULE == 1 + /* If this line results in an error __stdcall is not understood and + * PNG_API_RULE should not have been set to '1'. + */ +# define PNGAPI __stdcall +# endif +# else + /* An older compiler, or one not detected (erroneously) above, + * if necessary override on the command line to get the correct + * variants for the compiler. + */ +# ifndef PNGCAPI +# define PNGCAPI _cdecl +# endif +# if PNG_API_RULE == 1 && !defined(PNGAPI) +# define PNGAPI _stdcall +# endif +# endif /* compiler/api */ + + /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ + +# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) +# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" +# endif + +# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ + (defined(__BORLANDC__) && __BORLANDC__ < 0x500) + /* older Borland and MSC + * compilers used '__export' and required this to be after + * the type. + */ +# ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP +# endif +# define PNG_DLL_EXPORT __export +# else /* newer compiler */ +# define PNG_DLL_EXPORT __declspec(dllexport) +# ifndef PNG_DLL_IMPORT +# define PNG_DLL_IMPORT __declspec(dllimport) +# endif +# endif /* compiler */ + +#else /* !Windows */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# define PNGAPI _System +# else /* !Windows/x86 && !OS/2 */ + /* Use the defaults, or define PNG*API on the command line (but + * this will have to be done for every compile!) + */ +# endif /* other system, !OS/2 */ +#endif /* !Windows/x86 */ + +/* Now do all the defaulting . */ +#ifndef PNGCAPI +# define PNGCAPI +#endif +#ifndef PNGCBAPI +# define PNGCBAPI PNGCAPI +#endif +#ifndef PNGAPI +# define PNGAPI PNGCAPI +#endif + +/* PNG_IMPEXP may be set on the compilation system command line or (if not set) + * then in an internal header file when building the library, otherwise (when + * using the library) it is set here. + */ +#ifndef PNG_IMPEXP +# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) + /* This forces use of a DLL, disallowing static linking */ +# define PNG_IMPEXP PNG_DLL_IMPORT +# endif + +# ifndef PNG_IMPEXP +# define PNG_IMPEXP +# endif +#endif + +/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat + * 'attributes' as a storage class - the attributes go at the start of the + * function definition, and attributes are always appended regardless of the + * compiler. This considerably simplifies these macros but may cause problems + * if any compilers both need function attributes and fail to handle them as + * a storage class (this is unlikely.) + */ +#ifndef PNG_FUNCTION +# define PNG_FUNCTION(type, name, args, attributes) attributes type name args +#endif + +#ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type +#endif + + /* The ordinal value is only relevant when preprocessing png.h for symbol + * table entries, so we discard it here. See the .dfn files in the + * scripts directory. + */ +#ifndef PNG_EXPORTA + +# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ + PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \ + extern attributes) +#endif + +/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, + * so make something non-empty to satisfy the requirement: + */ +#define PNG_EMPTY /*empty list*/ + +#define PNG_EXPORT(ordinal, type, name, args)\ + PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) + +/* Use PNG_REMOVED to comment out a removed interface. */ +#ifndef PNG_REMOVED +# define PNG_REMOVED(ordinal, type, name, args, attributes) +#endif + +#ifndef PNG_CALLBACK +# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args) +#endif + +/* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. + * + * Added at libpng-1.2.41. + */ + +#ifndef PNG_NO_PEDANTIC_WARNINGS +# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_PEDANTIC_WARNINGS_SUPPORTED +# endif +#endif + +#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED + /* Support for compiler specific function attributes. These are used + * so that where compiler support is available, incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng + * version 1.2.41. Disabling these removes the warnings but may also produce + * less efficient code. + */ +# if defined(__clang__) && defined(__has_attribute) + /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ +# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# if !defined(PNG_PRIVATE) +# ifdef __has_extension +# if __has_extension(attribute_unavailable_with_message) +# define PNG_PRIVATE __attribute__((__unavailable__(\ + "This function is not exported by libpng."))) +# endif +# endif +# endif +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif + +# elif defined(__GNUC__) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if __GNUC__ >= 3 +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# ifndef PNG_PRIVATE +# if 0 /* Doesn't work so we use deprecated instead*/ +# define PNG_PRIVATE \ + __attribute__((warning("This function is not exported by libpng."))) +# else +# define PNG_PRIVATE \ + __attribute__((__deprecated__)) +# endif +# endif +# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ +# endif /* __GNUC__ >= 3 */ + +# elif defined(_MSC_VER) && (_MSC_VER >= 1300) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* not supported */ +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __declspec(noreturn) +# endif +# ifndef PNG_ALLOCATED +# if (_MSC_VER >= 1400) +# define PNG_ALLOCATED __declspec(restrict) +# endif +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __declspec(deprecated) +# endif +# ifndef PNG_PRIVATE +# define PNG_PRIVATE __declspec(deprecated) +# endif +# ifndef PNG_RESTRICT +# if (_MSC_VER >= 1400) +# define PNG_RESTRICT __restrict +# endif +# endif + +# elif defined(__WATCOMC__) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif +#endif /* PNG_PEDANTIC_WARNINGS */ + +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED /* Use of this function is deprecated */ +#endif +#ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* The result of this function must be checked */ +#endif +#ifndef PNG_NORETURN +# define PNG_NORETURN /* This function does not return */ +#endif +#ifndef PNG_ALLOCATED +# define PNG_ALLOCATED /* The result of the function is new memory */ +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE /* This is a private libpng function */ +#endif +#ifndef PNG_RESTRICT +# define PNG_RESTRICT /* The C99 "restrict" feature */ +#endif + +#ifndef PNG_FP_EXPORT /* A floating point API. */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args); +# else /* No floating point APIs */ +# define PNG_FP_EXPORT(ordinal, type, name, args) +# endif +#endif +#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ +# ifdef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args); +# else /* No fixed point APIs */ +# define PNG_FIXED_EXPORT(ordinal, type, name, args) +# endif +#endif + +#ifndef PNG_BUILDING_SYMBOL_TABLE +/* Some typedefs to get us started. These should be safe on most of the common + * platforms. + * + * png_uint_32 and png_int_32 may, currently, be larger than required to hold a + * 32-bit value however this is not normally advisable. + * + * png_uint_16 and png_int_16 should always be two bytes in size - this is + * verified at library build time. + * + * png_byte must always be one byte in size. + * + * The checks below use constants from limits.h, as defined by the ISOC90 + * standard. + */ +#if CHAR_BIT == 8 && UCHAR_MAX == 255 + typedef unsigned char png_byte; +#else +# error "libpng requires 8 bit bytes" +#endif + +#if INT_MIN == -32768 && INT_MAX == 32767 + typedef int png_int_16; +#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 + typedef short png_int_16; +#else +# error "libpng requires a signed 16 bit type" +#endif + +#if UINT_MAX == 65535 + typedef unsigned int png_uint_16; +#elif USHRT_MAX == 65535 + typedef unsigned short png_uint_16; +#else +# error "libpng requires an unsigned 16 bit type" +#endif + +#if INT_MIN < -2147483646 && INT_MAX > 2147483646 + typedef int png_int_32; +#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 + typedef long int png_int_32; +#else +# error "libpng requires a signed 32 bit (or more) type" +#endif + +#if UINT_MAX > 4294967294 + typedef unsigned int png_uint_32; +#elif ULONG_MAX > 4294967294 + typedef unsigned long int png_uint_32; +#else +# error "libpng requires an unsigned 32 bit (or more) type" +#endif + +/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, + * requires an ISOC90 compiler and relies on consistent behavior of sizeof. + */ +typedef size_t png_size_t; +typedef ptrdiff_t png_ptrdiff_t; + +/* libpng needs to know the maximum value of 'size_t' and this controls the + * definition of png_alloc_size_t, below. This maximum value of size_t limits + * but does not control the maximum allocations the library makes - there is + * direct application control of this through png_set_user_limits(). + */ +#ifndef PNG_SMALL_SIZE_T + /* Compiler specific tests for systems where size_t is known to be less than + * 32 bits (some of these systems may no longer work because of the lack of + * 'far' support; see above.) + */ +# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ + (defined(_MSC_VER) && defined(MAXSEG_64K)) +# define PNG_SMALL_SIZE_T +# endif +#endif + +/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no + * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to + * png_alloc_size_t are not necessary; in fact, it is recommended not to use + * them at all so that the compiler can complain when something turns out to be + * problematic. + * + * Casts in the other direction (from png_alloc_size_t to png_size_t or + * png_uint_32) should be explicitly applied; however, we do not expect to + * encounter practical situations that require such conversions. + * + * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than + * 4294967295 - i.e. less than the maximum value of png_uint_32. + */ +#ifdef PNG_SMALL_SIZE_T + typedef png_uint_32 png_alloc_size_t; +#else + typedef png_size_t png_alloc_size_t; +#endif + +/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler + * implementations of Intel CPU specific support of user-mode segmented address + * spaces, where 16-bit pointers address more than 65536 bytes of memory using + * separate 'segment' registers. The implementation requires two different + * types of pointer (only one of which includes the segment value.) + * + * If required this support is available in version 1.2 of libpng and may be + * available in versions through 1.5, although the correctness of the code has + * not been verified recently. + */ + +/* Typedef for floating-point numbers that are converted to fixed-point with a + * multiple of 100,000, e.g., gamma + */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void * png_voidp; +typedef const void * png_const_voidp; +typedef png_byte * png_bytep; +typedef const png_byte * png_const_bytep; +typedef png_uint_32 * png_uint_32p; +typedef const png_uint_32 * png_const_uint_32p; +typedef png_int_32 * png_int_32p; +typedef const png_int_32 * png_const_int_32p; +typedef png_uint_16 * png_uint_16p; +typedef const png_uint_16 * png_const_uint_16p; +typedef png_int_16 * png_int_16p; +typedef const png_int_16 * png_const_int_16p; +typedef char * png_charp; +typedef const char * png_const_charp; +typedef png_fixed_point * png_fixed_point_p; +typedef const png_fixed_point * png_const_fixed_point_p; +typedef png_size_t * png_size_tp; +typedef const png_size_t * png_const_size_tp; + +#ifdef PNG_STDIO_SUPPORTED +typedef FILE * png_FILE_p; +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * png_doublep; +typedef const double * png_const_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte * * png_bytepp; +typedef png_uint_32 * * png_uint_32pp; +typedef png_int_32 * * png_int_32pp; +typedef png_uint_16 * * png_uint_16pp; +typedef png_int_16 * * png_int_16pp; +typedef const char * * png_const_charpp; +typedef char * * png_charpp; +typedef png_fixed_point * * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char * * * png_charppp; + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +#endif /* PNGCONF_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/pnglibconf.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/pnglibconf.h new file mode 100644 index 00000000..b4ec3c31 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/pnglibconf.h @@ -0,0 +1,214 @@ +/* libpng 1.6.17 STANDARD API DEFINITION */ + +/* pnglibconf.h - library build configuration */ + +/* Libpng version 1.6.17 - March 26, 2015 */ + +/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */ + +/* This code is released under the libpng license. */ +/* For conditions of distribution and use, see the disclaimer */ +/* and license in png.h */ + +/* pnglibconf.h */ +/* Machine generated file: DO NOT EDIT */ +/* Derived from: scripts/pnglibconf.dfa */ +#ifndef PNGLCONF_H +#define PNGLCONF_H +/* options */ +#define PNG_16BIT_SUPPORTED +#define PNG_ALIGNED_MEMORY_SUPPORTED +/*#undef PNG_ARM_NEON_API_SUPPORTED*/ +/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ +#define PNG_BENIGN_ERRORS_SUPPORTED +#define PNG_BENIGN_READ_ERRORS_SUPPORTED +/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ +#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_COLORSPACE_SUPPORTED +#define PNG_CONSOLE_IO_SUPPORTED +#define PNG_CONVERT_tIME_SUPPORTED +#define PNG_EASY_ACCESS_SUPPORTED +/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ +#define PNG_ERROR_TEXT_SUPPORTED +#define PNG_FIXED_POINT_SUPPORTED +#define PNG_FLOATING_ARITHMETIC_SUPPORTED +#define PNG_FLOATING_POINT_SUPPORTED +#define PNG_FORMAT_AFIRST_SUPPORTED +#define PNG_FORMAT_BGR_SUPPORTED +#define PNG_GAMMA_SUPPORTED +#define PNG_GET_PALETTE_MAX_SUPPORTED +#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#define PNG_INCH_CONVERSIONS_SUPPORTED +#define PNG_INFO_IMAGE_SUPPORTED +#define PNG_IO_STATE_SUPPORTED +#define PNG_MNG_FEATURES_SUPPORTED +#define PNG_POINTER_INDEXING_SUPPORTED +#define PNG_PROGRESSIVE_READ_SUPPORTED +#define PNG_READ_16BIT_SUPPORTED +#define PNG_READ_ALPHA_MODE_SUPPORTED +#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_READ_BACKGROUND_SUPPORTED +#define PNG_READ_BGR_SUPPORTED +#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_READ_COMPOSITE_NODIV_SUPPORTED +#define PNG_READ_COMPRESSED_TEXT_SUPPORTED +#define PNG_READ_EXPAND_16_SUPPORTED +#define PNG_READ_EXPAND_SUPPORTED +#define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_GAMMA_SUPPORTED +#define PNG_READ_GET_PALETTE_MAX_SUPPORTED +#define PNG_READ_GRAY_TO_RGB_SUPPORTED +#define PNG_READ_INTERLACING_SUPPORTED +#define PNG_READ_INT_FUNCTIONS_SUPPORTED +#define PNG_READ_INVERT_ALPHA_SUPPORTED +#define PNG_READ_INVERT_SUPPORTED +#define PNG_READ_OPT_PLTE_SUPPORTED +#define PNG_READ_PACKSWAP_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_QUANTIZE_SUPPORTED +#define PNG_READ_RGB_TO_GRAY_SUPPORTED +#define PNG_READ_SCALE_16_TO_8_SUPPORTED +#define PNG_READ_SHIFT_SUPPORTED +#define PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_STRIP_ALPHA_SUPPORTED +#define PNG_READ_SUPPORTED +#define PNG_READ_SWAP_ALPHA_SUPPORTED +#define PNG_READ_SWAP_SUPPORTED +#define PNG_READ_TEXT_SUPPORTED +#define PNG_READ_TRANSFORMS_SUPPORTED +#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_READ_USER_CHUNKS_SUPPORTED +#define PNG_READ_USER_TRANSFORM_SUPPORTED +#define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_gAMA_SUPPORTED +#define PNG_READ_hIST_SUPPORTED +#define PNG_READ_iCCP_SUPPORTED +#define PNG_READ_iTXt_SUPPORTED +#define PNG_READ_oFFs_SUPPORTED +#define PNG_READ_pCAL_SUPPORTED +#define PNG_READ_pHYs_SUPPORTED +#define PNG_READ_sBIT_SUPPORTED +#define PNG_READ_sCAL_SUPPORTED +#define PNG_READ_sPLT_SUPPORTED +#define PNG_READ_sRGB_SUPPORTED +#define PNG_READ_tEXt_SUPPORTED +#define PNG_READ_tIME_SUPPORTED +#define PNG_READ_tRNS_SUPPORTED +#define PNG_READ_zTXt_SUPPORTED +#define PNG_SAVE_INT_32_SUPPORTED +#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SEQUENTIAL_READ_SUPPORTED +#define PNG_SETJMP_SUPPORTED +#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED +#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +#define PNG_SET_OPTION_SUPPORTED +#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SET_USER_LIMITS_SUPPORTED +#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED +#define PNG_SIMPLIFIED_READ_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_SUPPORTED +#define PNG_STDIO_SUPPORTED +#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_TEXT_SUPPORTED +#define PNG_TIME_RFC1123_SUPPORTED +#define PNG_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_USER_CHUNKS_SUPPORTED +#define PNG_USER_LIMITS_SUPPORTED +#define PNG_USER_MEM_SUPPORTED +#define PNG_USER_TRANSFORM_INFO_SUPPORTED +#define PNG_USER_TRANSFORM_PTR_SUPPORTED +#define PNG_WARNINGS_SUPPORTED +#define PNG_WRITE_16BIT_SUPPORTED +#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_WRITE_BGR_SUPPORTED +#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED +#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +#define PNG_WRITE_FILLER_SUPPORTED +#define PNG_WRITE_FILTER_SUPPORTED +#define PNG_WRITE_FLUSH_SUPPORTED +#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED +#define PNG_WRITE_INTERLACING_SUPPORTED +#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED +#define PNG_WRITE_INVERT_ALPHA_SUPPORTED +#define PNG_WRITE_INVERT_SUPPORTED +#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED +#define PNG_WRITE_PACKSWAP_SUPPORTED +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED +#define PNG_WRITE_SUPPORTED +#define PNG_WRITE_SWAP_ALPHA_SUPPORTED +#define PNG_WRITE_SWAP_SUPPORTED +#define PNG_WRITE_TEXT_SUPPORTED +#define PNG_WRITE_TRANSFORMS_SUPPORTED +#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_WRITE_USER_TRANSFORM_SUPPORTED +#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_gAMA_SUPPORTED +#define PNG_WRITE_hIST_SUPPORTED +#define PNG_WRITE_iCCP_SUPPORTED +#define PNG_WRITE_iTXt_SUPPORTED +#define PNG_WRITE_oFFs_SUPPORTED +#define PNG_WRITE_pCAL_SUPPORTED +#define PNG_WRITE_pHYs_SUPPORTED +#define PNG_WRITE_sBIT_SUPPORTED +#define PNG_WRITE_sCAL_SUPPORTED +#define PNG_WRITE_sPLT_SUPPORTED +#define PNG_WRITE_sRGB_SUPPORTED +#define PNG_WRITE_tEXt_SUPPORTED +#define PNG_WRITE_tIME_SUPPORTED +#define PNG_WRITE_tRNS_SUPPORTED +#define PNG_WRITE_zTXt_SUPPORTED +#define PNG_bKGD_SUPPORTED +#define PNG_cHRM_SUPPORTED +#define PNG_gAMA_SUPPORTED +#define PNG_hIST_SUPPORTED +#define PNG_iCCP_SUPPORTED +#define PNG_iTXt_SUPPORTED +#define PNG_oFFs_SUPPORTED +#define PNG_pCAL_SUPPORTED +#define PNG_pHYs_SUPPORTED +#define PNG_sBIT_SUPPORTED +#define PNG_sCAL_SUPPORTED +#define PNG_sPLT_SUPPORTED +#define PNG_sRGB_SUPPORTED +#define PNG_tEXt_SUPPORTED +#define PNG_tIME_SUPPORTED +#define PNG_tRNS_SUPPORTED +#define PNG_zTXt_SUPPORTED +/* end of options */ +/* settings */ +#define PNG_API_RULE 0 +#define PNG_COST_SHIFT 3 +#define PNG_DEFAULT_READ_MACROS 1 +#define PNG_GAMMA_THRESHOLD_FIXED 5000 +#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE +#define PNG_INFLATE_BUF_SIZE 1024 +#define PNG_MAX_GAMMA_8 11 +#define PNG_QUANTIZE_BLUE_BITS 5 +#define PNG_QUANTIZE_GREEN_BITS 5 +#define PNG_QUANTIZE_RED_BITS 5 +#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) +#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 +#define PNG_USER_CHUNK_CACHE_MAX 1000 +#define PNG_USER_CHUNK_MALLOC_MAX 8000000 +#define PNG_USER_HEIGHT_MAX 1000000 +#define PNG_USER_WIDTH_MAX 1000000 +#define PNG_WEIGHT_SHIFT 8 +#define PNG_ZBUF_SIZE 8192 +#define PNG_ZLIB_VERNUM 0 /* unknown */ +#define PNG_Z_DEFAULT_COMPRESSION (-1) +#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 +#define PNG_Z_DEFAULT_STRATEGY 1 +#define PNG_sCAL_PRECISION 5 +#define PNG_sRGB_PROFILE_CHECKS 2 +/* end of settings */ +#endif /* PNGLCONF_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/codec.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/codec.h new file mode 100644 index 00000000..5c266963 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/codec.h @@ -0,0 +1,591 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $ + + ********************************************************************/ + +/**\mainpage + * + * \section intro Introduction + * + * This is the documentation for <tt>libtheora</tt> C API. + * The current reference + * implementation for <a href="http://www.theora.org/">Theora</a>, a free, + * patent-unencumbered video codec. + * Theora is derived from On2's VP3 codec with additional features and + * integration with Ogg multimedia formats by + * <a href="http://www.xiph.org/">the Xiph.Org Foundation</a>. + * Complete documentation of the format itself is available in + * <a href="http://www.theora.org/doc/Theora.pdf">the Theora + * specification</a>. + * + * \subsection Organization + * + * The functions documented here are actually subdivided into three + * separate libraries: + * - <tt>libtheoraenc</tt> contains the encoder interface, + * described in \ref encfuncs. + * - <tt>libtheoradec</tt> contains the decoder interface and + * routines shared with the encoder. + * You must also link to this if you link to <tt>libtheoraenc</tt>. + * The routines in this library are described in \ref decfuncs and + * \ref basefuncs. + * - <tt>libtheora</tt> contains the \ref oldfuncs. + * + * New code should link to <tt>libtheoradec</tt> and, if using encoder + * features, <tt>libtheoraenc</tt>. Together these two export both + * the standard and the legacy API, so this is all that is needed by + * any code. The older <tt>libtheora</tt> library is provided just for + * compatibility with older build configurations. + * + * In general the recommended 1.x API symbols can be distinguished + * by their <tt>th_</tt> or <tt>TH_</tt> namespace prefix. + * The older, legacy API uses <tt>theora_</tt> or <tt>OC_</tt> + * prefixes instead. + */ + +/**\file + * The shared <tt>libtheoradec</tt> and <tt>libtheoraenc</tt> C API. + * You don't need to include this directly.*/ + +#if !defined(_O_THEORA_CODEC_H_) +# define _O_THEORA_CODEC_H_ (1) +# include <ogg/ogg.h> + +#if defined(__cplusplus) +extern "C" { +#endif + + + +/**\name Return codes*/ +/*@{*/ +/**An invalid pointer was provided.*/ +#define TH_EFAULT (-1) +/**An invalid argument was provided.*/ +#define TH_EINVAL (-10) +/**The contents of the header were incomplete, invalid, or unexpected.*/ +#define TH_EBADHEADER (-20) +/**The header does not belong to a Theora stream.*/ +#define TH_ENOTFORMAT (-21) +/**The bitstream version is too high.*/ +#define TH_EVERSION (-22) +/**The specified function is not implemented.*/ +#define TH_EIMPL (-23) +/**There were errors in the video data packet.*/ +#define TH_EBADPACKET (-24) +/**The decoded packet represented a dropped frame. + The player can continue to display the current frame, as the contents of the + decoded frame buffer have not changed.*/ +#define TH_DUPFRAME (1) +/*@}*/ + +/**The currently defined color space tags. + * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora + * specification</a>, Chapter 4, for exact details on the meaning + * of each of these color spaces.*/ +typedef enum{ + /**The color space was not specified at the encoder. + It may be conveyed by an external means.*/ + TH_CS_UNSPECIFIED, + /**A color space designed for NTSC content.*/ + TH_CS_ITU_REC_470M, + /**A color space designed for PAL/SECAM content.*/ + TH_CS_ITU_REC_470BG, + /**The total number of currently defined color spaces.*/ + TH_CS_NSPACES +}th_colorspace; + +/**The currently defined pixel format tags. + * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora + * specification</a>, Section 4.4, for details on the precise sample + * locations.*/ +typedef enum{ + /**Chroma decimation by 2 in both the X and Y directions (4:2:0). + The Cb and Cr chroma planes are half the width and half the + height of the luma plane.*/ + TH_PF_420, + /**Currently reserved.*/ + TH_PF_RSVD, + /**Chroma decimation by 2 in the X direction (4:2:2). + The Cb and Cr chroma planes are half the width of the luma plane, but full + height.*/ + TH_PF_422, + /**No chroma decimation (4:4:4). + The Cb and Cr chroma planes are full width and full height.*/ + TH_PF_444, + /**The total number of currently defined pixel formats.*/ + TH_PF_NFORMATS +}th_pixel_fmt; + + + +/**A buffer for a single color plane in an uncompressed image. + * This contains the image data in a left-to-right, top-down format. + * Each row of pixels is stored contiguously in memory, but successive + * rows need not be. + * Use \a stride to compute the offset of the next row. + * The encoder accepts both positive \a stride values (top-down in memory) + * and negative (bottom-up in memory). + * The decoder currently always generates images with positive strides.*/ +typedef struct{ + /**The width of this plane.*/ + int width; + /**The height of this plane.*/ + int height; + /**The offset in bytes between successive rows.*/ + int stride; + /**A pointer to the beginning of the first row.*/ + unsigned char *data; +}th_img_plane; + +/**A complete image buffer for an uncompressed frame. + * The chroma planes may be decimated by a factor of two in either + * direction, as indicated by th_info#pixel_fmt. + * The width and height of the Y' plane must be multiples of 16. + * They may need to be cropped for display, using the rectangle + * specified by th_info#pic_x, th_info#pic_y, th_info#pic_width, + * and th_info#pic_height. + * All samples are 8 bits. + * \note The term YUV often used to describe a colorspace is ambiguous. + * The exact parameters of the RGB to YUV conversion process aside, in + * many contexts the U and V channels actually have opposite meanings. + * To avoid this confusion, we are explicit: the name of the color + * channels are Y'CbCr, and they appear in that order, always. + * The prime symbol denotes that the Y channel is non-linear. + * Cb and Cr stand for "Chroma blue" and "Chroma red", respectively.*/ +typedef th_img_plane th_ycbcr_buffer[3]; + +/**Theora bitstream information. + * This contains the basic playback parameters for a stream, and corresponds to + * the initial 'info' header packet. + * To initialize an encoder, the application fills in this structure and + * passes it to th_encode_alloc(). + * A default encoding mode is chosen based on the values of the #quality and + * #target_bitrate fields. + * On decode, it is filled in by th_decode_headerin(), and then passed to + * th_decode_alloc(). + * + * Encoded Theora frames must be a multiple of 16 in size; + * this is what the #frame_width and #frame_height members represent. + * To handle arbitrary picture sizes, a crop rectangle is specified in the + * #pic_x, #pic_y, #pic_width and #pic_height members. + * + * All frame buffers contain pointers to the full, padded frame. + * However, the current encoder <em>will not</em> reference pixels outside of + * the cropped picture region, and the application does not need to fill them + * in. + * The decoder <em>will</em> allocate storage for a full frame, but the + * application <em>should not</em> rely on the padding containing sensible + * data. + * + * It is also generally recommended that the offsets and sizes should still be + * multiples of 2 to avoid chroma sampling shifts when chroma is sub-sampled. + * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora + * specification</a>, Section 4.4, for more details. + * + * Frame rate, in frames per second, is stored as a rational fraction, as is + * the pixel aspect ratio. + * Note that this refers to the aspect ratio of the individual pixels, not of + * the overall frame itself. + * The frame aspect ratio can be computed from pixel aspect ratio using the + * image dimensions.*/ +typedef struct{ + /**\name Theora version + * Bitstream version information.*/ + /*@{*/ + unsigned char version_major; + unsigned char version_minor; + unsigned char version_subminor; + /*@}*/ + /**The encoded frame width. + * This must be a multiple of 16, and less than 1048576.*/ + ogg_uint32_t frame_width; + /**The encoded frame height. + * This must be a multiple of 16, and less than 1048576.*/ + ogg_uint32_t frame_height; + /**The displayed picture width. + * This must be no larger than width.*/ + ogg_uint32_t pic_width; + /**The displayed picture height. + * This must be no larger than height.*/ + ogg_uint32_t pic_height; + /**The X offset of the displayed picture. + * This must be no larger than #frame_width-#pic_width or 255, whichever is + * smaller.*/ + ogg_uint32_t pic_x; + /**The Y offset of the displayed picture. + * This must be no larger than #frame_height-#pic_height, and + * #frame_height-#pic_height-#pic_y must be no larger than 255. + * This slightly funny restriction is due to the fact that the offset is + * specified from the top of the image for consistency with the standard + * graphics left-handed coordinate system used throughout this API, while + * it is stored in the encoded stream as an offset from the bottom.*/ + ogg_uint32_t pic_y; + /**\name Frame rate + * The frame rate, as a fraction. + * If either is 0, the frame rate is undefined.*/ + /*@{*/ + ogg_uint32_t fps_numerator; + ogg_uint32_t fps_denominator; + /*@}*/ + /**\name Aspect ratio + * The aspect ratio of the pixels. + * If either value is zero, the aspect ratio is undefined. + * If not specified by any external means, 1:1 should be assumed. + * The aspect ratio of the full picture can be computed as + * \code + * aspect_numerator*pic_width/(aspect_denominator*pic_height). + * \endcode */ + /*@{*/ + ogg_uint32_t aspect_numerator; + ogg_uint32_t aspect_denominator; + /*@}*/ + /**The color space.*/ + th_colorspace colorspace; + /**The pixel format.*/ + th_pixel_fmt pixel_fmt; + /**The target bit-rate in bits per second. + If initializing an encoder with this struct, set this field to a non-zero + value to activate CBR encoding by default.*/ + int target_bitrate; + /**The target quality level. + Valid values range from 0 to 63, inclusive, with higher values giving + higher quality. + If initializing an encoder with this struct, and #target_bitrate is set + to zero, VBR encoding at this quality will be activated by default.*/ + /*Currently this is set so that a qi of 0 corresponds to distortions of 24 + times the JND, and each increase by 16 halves that value. + This gives us fine discrimination at low qualities, yet effective rate + control at high qualities. + The qi value 63 is special, however. + For this, the highest quality, we use one half of a JND for our threshold. + Due to the lower bounds placed on allowable quantizers in Theora, we will + not actually be able to achieve quality this good, but this should + provide as close to visually lossless quality as Theora is capable of. + We could lift the quantizer restrictions without breaking VP3.1 + compatibility, but this would result in quantized coefficients that are + too large for the current bitstream to be able to store. + We'd have to redesign the token syntax to store these large coefficients, + which would make transcoding complex.*/ + int quality; + /**The amount to shift to extract the last keyframe number from the granule + * position. + * This can be at most 31. + * th_info_init() will set this to a default value (currently <tt>6</tt>, + * which is good for streaming applications), but you can set it to 0 to + * make every frame a keyframe. + * The maximum distance between key frames is + * <tt>1<<#keyframe_granule_shift</tt>. + * The keyframe frequency can be more finely controlled with + * #TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, which can also be adjusted + * during encoding (for example, to force the next frame to be a keyframe), + * but it cannot be set larger than the amount permitted by this field after + * the headers have been output.*/ + int keyframe_granule_shift; +}th_info; + +/**The comment information. + * + * This structure holds the in-stream metadata corresponding to + * the 'comment' header packet. + * The comment header is meant to be used much like someone jotting a quick + * note on the label of a video. + * It should be a short, to the point text note that can be more than a couple + * words, but not more than a short paragraph. + * + * The metadata is stored as a series of (tag, value) pairs, in + * length-encoded string vectors. + * The first occurrence of the '=' character delimits the tag and value. + * A particular tag may occur more than once, and order is significant. + * The character set encoding for the strings is always UTF-8, but the tag + * names are limited to ASCII, and treated as case-insensitive. + * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora + * specification</a>, Section 6.3.3 for details. + * + * In filling in this structure, th_decode_headerin() will null-terminate + * the user_comment strings for safety. + * However, the bitstream format itself treats them as 8-bit clean vectors, + * possibly containing null characters, and so the length array should be + * treated as their authoritative length. + */ +typedef struct th_comment{ + /**The array of comment string vectors.*/ + char **user_comments; + /**An array of the corresponding length of each vector, in bytes.*/ + int *comment_lengths; + /**The total number of comment strings.*/ + int comments; + /**The null-terminated vendor string. + This identifies the software used to encode the stream.*/ + char *vendor; +}th_comment; + + + +/**A single base matrix.*/ +typedef unsigned char th_quant_base[64]; + +/**A set of \a qi ranges.*/ +typedef struct{ + /**The number of ranges in the set.*/ + int nranges; + /**The size of each of the #nranges ranges. + These must sum to 63.*/ + const int *sizes; + /**#nranges <tt>+1</tt> base matrices. + Matrices \a i and <tt>i+1</tt> form the endpoints of range \a i.*/ + const th_quant_base *base_matrices; +}th_quant_ranges; + +/**A complete set of quantization parameters. + The quantizer for each coefficient is calculated as: + \code + Q=MAX(MIN(qmin[qti][ci!=0],scale[ci!=0][qi]*base[qti][pli][qi][ci]/100), + 1024). + \endcode + + \a qti is the quantization type index: 0 for intra, 1 for inter. + <tt>ci!=0</tt> is 0 for the DC coefficient and 1 for AC coefficients. + \a qi is the quality index, ranging between 0 (low quality) and 63 (high + quality). + \a pli is the color plane index: 0 for Y', 1 for Cb, 2 for Cr. + \a ci is the DCT coefficient index. + Coefficient indices correspond to the normal 2D DCT block + ordering--row-major with low frequencies first--\em not zig-zag order. + + Minimum quantizers are constant, and are given by: + \code + qmin[2][2]={{4,2},{8,4}}. + \endcode + + Parameters that can be stored in the bitstream are as follows: + - The two scale matrices ac_scale and dc_scale. + \code + scale[2][64]={dc_scale,ac_scale}. + \endcode + - The base matrices for each \a qi, \a qti and \a pli (up to 384 in all). + In order to avoid storing a full 384 base matrices, only a sparse set of + matrices are stored, and the rest are linearly interpolated. + This is done as follows. + For each \a qti and \a pli, a series of \a n \a qi ranges is defined. + The size of each \a qi range can vary arbitrarily, but they must sum to + 63. + Then, <tt>n+1</tt> matrices are specified, one for each endpoint of the + ranges. + For interpolation purposes, each range's endpoints are the first \a qi + value it contains and one past the last \a qi value it contains. + Fractional values are rounded to the nearest integer, with ties rounded + away from zero. + + Base matrices are stored by reference, so if the same matrices are used + multiple times, they will only appear once in the bitstream. + The bitstream is also capable of omitting an entire set of ranges and + its associated matrices if they are the same as either the previous + set (indexed in row-major order) or if the inter set is the same as the + intra set. + + - Loop filter limit values. + The same limits are used for the loop filter in all color planes, despite + potentially differing levels of quantization in each. + + For the current encoder, <tt>scale[ci!=0][qi]</tt> must be no greater + than <tt>scale[ci!=0][qi-1]</tt> and <tt>base[qti][pli][qi][ci]</tt> must + be no greater than <tt>base[qti][pli][qi-1][ci]</tt>. + These two conditions ensure that the actual quantizer for a given \a qti, + \a pli, and \a ci does not increase as \a qi increases. + This is not required by the decoder.*/ +typedef struct{ + /**The DC scaling factors.*/ + ogg_uint16_t dc_scale[64]; + /**The AC scaling factors.*/ + ogg_uint16_t ac_scale[64]; + /**The loop filter limit values.*/ + unsigned char loop_filter_limits[64]; + /**The \a qi ranges for each \a ci and \a pli.*/ + th_quant_ranges qi_ranges[2][3]; +}th_quant_info; + + + +/**The number of Huffman tables used by Theora.*/ +#define TH_NHUFFMAN_TABLES (80) +/**The number of DCT token values in each table.*/ +#define TH_NDCT_TOKENS (32) + +/**A Huffman code for a Theora DCT token. + * Each set of Huffman codes in a given table must form a complete, prefix-free + * code. + * There is no requirement that all the tokens in a table have a valid code, + * but the current encoder is not optimized to take advantage of this. + * If each of the five grouops of 16 tables does not contain at least one table + * with a code for every token, then the encoder may fail to encode certain + * frames. + * The complete table in the first group of 16 does not have to be in the same + * place as the complete table in the other groups, but the complete tables in + * the remaining four groups must all be in the same place.*/ +typedef struct{ + /**The bit pattern for the code, with the LSbit of the pattern aligned in + * the LSbit of the word.*/ + ogg_uint32_t pattern; + /**The number of bits in the code. + * This must be between 0 and 32, inclusive.*/ + int nbits; +}th_huff_code; + + + +/**\defgroup basefuncs Functions Shared by Encode and Decode*/ +/*@{*/ +/**\name Basic shared functions*/ +/*@{*/ +/**Retrieves a human-readable string to identify the library vendor and + * version. + * \return the version string.*/ +extern const char *th_version_string(void); +/**Retrieves the library version number. + * This is the highest bitstream version that the encoder library will produce, + * or that the decoder library can decode. + * This number is composed of a 16-bit major version, 8-bit minor version + * and 8 bit sub-version, composed as follows: + * \code + * (VERSION_MAJOR<<16)+(VERSION_MINOR<<8)+(VERSION_SUBMINOR) + * \endcode + * \return the version number.*/ +extern ogg_uint32_t th_version_number(void); +/**Converts a granule position to an absolute frame index, starting at + * <tt>0</tt>. + * The granule position is interpreted in the context of a given + * #th_enc_ctx or #th_dec_ctx handle (either will suffice). + * \param _encdec A previously allocated #th_enc_ctx or #th_dec_ctx + * handle. + * \param _granpos The granule position to convert. + * \returns The absolute frame index corresponding to \a _granpos. + * \retval -1 The given granule position was invalid (i.e. negative).*/ +extern ogg_int64_t th_granule_frame(void *_encdec,ogg_int64_t _granpos); +/**Converts a granule position to an absolute time in seconds. + * The granule position is interpreted in the context of a given + * #th_enc_ctx or #th_dec_ctx handle (either will suffice). + * \param _encdec A previously allocated #th_enc_ctx or #th_dec_ctx + * handle. + * \param _granpos The granule position to convert. + * \return The absolute time in seconds corresponding to \a _granpos. + * This is the "end time" for the frame, or the latest time it should + * be displayed. + * It is not the presentation time. + * \retval -1 The given granule position was invalid (i.e. negative).*/ +extern double th_granule_time(void *_encdec,ogg_int64_t _granpos); +/**Determines whether a Theora packet is a header or not. + * This function does no verification beyond checking the packet type bit, so + * it should not be used for bitstream identification; use + * th_decode_headerin() for that. + * As per the Theora specification, an empty (0-byte) packet is treated as a + * data packet (a delta frame with no coded blocks). + * \param _op An <tt>ogg_packet</tt> containing encoded Theora data. + * \retval 1 The packet is a header packet + * \retval 0 The packet is a video data packet.*/ +extern int th_packet_isheader(ogg_packet *_op); +/**Determines whether a theora packet is a key frame or not. + * This function does no verification beyond checking the packet type and + * key frame bits, so it should not be used for bitstream identification; use + * th_decode_headerin() for that. + * As per the Theora specification, an empty (0-byte) packet is treated as a + * delta frame (with no coded blocks). + * \param _op An <tt>ogg_packet</tt> containing encoded Theora data. + * \retval 1 The packet contains a key frame. + * \retval 0 The packet contains a delta frame. + * \retval -1 The packet is not a video data packet.*/ +extern int th_packet_iskeyframe(ogg_packet *_op); +/*@}*/ + + +/**\name Functions for manipulating header data*/ +/*@{*/ +/**Initializes a th_info structure. + * This should be called on a freshly allocated #th_info structure before + * attempting to use it. + * \param _info The #th_info struct to initialize.*/ +extern void th_info_init(th_info *_info); +/**Clears a #th_info structure. + * This should be called on a #th_info structure after it is no longer + * needed. + * \param _info The #th_info struct to clear.*/ +extern void th_info_clear(th_info *_info); + +/**Initialize a #th_comment structure. + * This should be called on a freshly allocated #th_comment structure + * before attempting to use it. + * \param _tc The #th_comment struct to initialize.*/ +extern void th_comment_init(th_comment *_tc); +/**Add a comment to an initialized #th_comment structure. + * \note Neither th_comment_add() nor th_comment_add_tag() support + * comments containing null values, although the bitstream format does + * support them. + * To add such comments you will need to manipulate the #th_comment + * structure directly. + * \param _tc The #th_comment struct to add the comment to. + * \param _comment Must be a null-terminated UTF-8 string containing the + * comment in "TAG=the value" form.*/ +extern void th_comment_add(th_comment *_tc, char *_comment); +/**Add a comment to an initialized #th_comment structure. + * \note Neither th_comment_add() nor th_comment_add_tag() support + * comments containing null values, although the bitstream format does + * support them. + * To add such comments you will need to manipulate the #th_comment + * structure directly. + * \param _tc The #th_comment struct to add the comment to. + * \param _tag A null-terminated string containing the tag associated with + * the comment. + * \param _val The corresponding value as a null-terminated string.*/ +extern void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val); +/**Look up a comment value by its tag. + * \param _tc An initialized #th_comment structure. + * \param _tag The tag to look up. + * \param _count The instance of the tag. + * The same tag can appear multiple times, each with a distinct + * value, so an index is required to retrieve them all. + * The order in which these values appear is significant and + * should be preserved. + * Use th_comment_query_count() to get the legal range for + * the \a _count parameter. + * \return A pointer to the queried tag's value. + * This points directly to data in the #th_comment structure. + * It should not be modified or freed by the application, and + * modifications to the structure may invalidate the pointer. + * \retval NULL If no matching tag is found.*/ +extern char *th_comment_query(th_comment *_tc,char *_tag,int _count); +/**Look up the number of instances of a tag. + * Call this first when querying for a specific tag and then iterate over the + * number of instances with separate calls to th_comment_query() to + * retrieve all the values for that tag in order. + * \param _tc An initialized #th_comment structure. + * \param _tag The tag to look up. + * \return The number on instances of this particular tag.*/ +extern int th_comment_query_count(th_comment *_tc,char *_tag); +/**Clears a #th_comment structure. + * This should be called on a #th_comment structure after it is no longer + * needed. + * It will free all memory used by the structure members. + * \param _tc The #th_comment struct to clear.*/ +extern void th_comment_clear(th_comment *_tc); +/*@}*/ +/*@}*/ + + + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/theora.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/theora.h new file mode 100644 index 00000000..af6eb6f3 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/theora.h @@ -0,0 +1,784 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: theora.h,v 1.17 2003/12/06 18:06:19 arc Exp $ + + ********************************************************************/ + +#ifndef _O_THEORA_H_ +#define _O_THEORA_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include <stddef.h> /* for size_t */ + +#include <ogg/ogg.h> + +/** \file + * The libtheora pre-1.0 legacy C API. + * + * \ingroup oldfuncs + * + * \section intro Introduction + * + * This is the documentation for the libtheora legacy C API, declared in + * the theora.h header, which describes the old interface used before + * the 1.0 release. This API was widely deployed for several years and + * remains supported, but for new code we recommend the cleaner API + * declared in theoradec.h and theoraenc.h. + * + * libtheora is the reference implementation for + * <a href="http://www.theora.org/">Theora</a>, a free video codec. + * Theora is derived from On2's VP3 codec with improved integration with + * Ogg multimedia formats by <a href="http://www.xiph.org/">Xiph.Org</a>. + * + * \section overview Overview + * + * This library will both decode and encode theora packets to/from raw YUV + * frames. In either case, the packets will most likely either come from or + * need to be embedded in an Ogg stream. Use + * <a href="http://xiph.org/ogg/">libogg</a> or + * <a href="http://www.annodex.net/software/liboggz/index.html">liboggz</a> + * to extract/package these packets. + * + * \section decoding Decoding Process + * + * Decoding can be separated into the following steps: + * -# initialise theora_info and theora_comment structures using + * theora_info_init() and theora_comment_init(): + \verbatim + theora_info info; + theora_comment comment; + + theora_info_init(&info); + theora_comment_init(&comment); + \endverbatim + * -# retrieve header packets from Ogg stream (there should be 3) and decode + * into theora_info and theora_comment structures using + * theora_decode_header(). See \ref identification for more information on + * identifying which packets are theora packets. + \verbatim + int i; + for (i = 0; i < 3; i++) + { + (get a theora packet "op" from the Ogg stream) + theora_decode_header(&info, &comment, op); + } + \endverbatim + * -# initialise the decoder based on the information retrieved into the + * theora_info struct by theora_decode_header(). You will need a + * theora_state struct. + \verbatim + theora_state state; + + theora_decode_init(&state, &info); + \endverbatim + * -# pass in packets and retrieve decoded frames! See the yuv_buffer + * documentation for information on how to retrieve raw YUV data. + \verbatim + yuf_buffer buffer; + while (last packet was not e_o_s) { + (get a theora packet "op" from the Ogg stream) + theora_decode_packetin(&state, op); + theora_decode_YUVout(&state, &buffer); + } + \endverbatim + * + * + * \subsection identification Identifying Theora Packets + * + * All streams inside an Ogg file have a unique serial_no attached to the + * stream. Typically, you will want to + * - retrieve the serial_no for each b_o_s (beginning of stream) page + * encountered within the Ogg file; + * - test the first (only) packet on that page to determine if it is a theora + * packet; + * - once you have found a theora b_o_s page then use the retrieved serial_no + * to identify future packets belonging to the same theora stream. + * + * Note that you \e cannot use theora_packet_isheader() to determine if a + * packet is a theora packet or not, as this function does not perform any + * checking beyond whether a header bit is present. Instead, use the + * theora_decode_header() function and check the return value; or examine the + * header bytes at the beginning of the Ogg page. + */ + + +/** \defgroup oldfuncs Legacy pre-1.0 C API */ +/* @{ */ + +/** + * A YUV buffer for passing uncompressed frames to and from the codec. + * This holds a Y'CbCr frame in planar format. The CbCr planes can be + * subsampled and have their own separate dimensions and row stride + * offsets. Note that the strides may be negative in some + * configurations. For theora the width and height of the largest plane + * must be a multiple of 16. The actual meaningful picture size and + * offset are stored in the theora_info structure; frames returned by + * the decoder may need to be cropped for display. + * + * All samples are 8 bits. Within each plane samples are ordered by + * row from the top of the frame to the bottom. Within each row samples + * are ordered from left to right. + * + * During decode, the yuv_buffer struct is allocated by the user, but all + * fields (including luma and chroma pointers) are filled by the library. + * These pointers address library-internal memory and their contents should + * not be modified. + * + * Conversely, during encode the user allocates the struct and fills out all + * fields. The user also manages the data addressed by the luma and chroma + * pointers. See the encoder_example.c and dump_video.c example files in + * theora/examples/ for more information. + */ +typedef struct { + int y_width; /**< Width of the Y' luminance plane */ + int y_height; /**< Height of the luminance plane */ + int y_stride; /**< Offset in bytes between successive rows */ + + int uv_width; /**< Width of the Cb and Cr chroma planes */ + int uv_height; /**< Height of the chroma planes */ + int uv_stride; /**< Offset between successive chroma rows */ + unsigned char *y; /**< Pointer to start of luminance data */ + unsigned char *u; /**< Pointer to start of Cb data */ + unsigned char *v; /**< Pointer to start of Cr data */ + +} yuv_buffer; + +/** + * A Colorspace. + */ +typedef enum { + OC_CS_UNSPECIFIED, /**< The colorspace is unknown or unspecified */ + OC_CS_ITU_REC_470M, /**< This is the best option for 'NTSC' content */ + OC_CS_ITU_REC_470BG, /**< This is the best option for 'PAL' content */ + OC_CS_NSPACES /**< This marks the end of the defined colorspaces */ +} theora_colorspace; + +/** + * A Chroma subsampling + * + * These enumerate the available chroma subsampling options supported + * by the theora format. See Section 4.4 of the specification for + * exact definitions. + */ +typedef enum { + OC_PF_420, /**< Chroma subsampling by 2 in each direction (4:2:0) */ + OC_PF_RSVD, /**< Reserved value */ + OC_PF_422, /**< Horizonatal chroma subsampling by 2 (4:2:2) */ + OC_PF_444, /**< No chroma subsampling at all (4:4:4) */ +} theora_pixelformat; + +/** + * Theora bitstream info. + * Contains the basic playback parameters for a stream, + * corresponding to the initial 'info' header packet. + * + * Encoded theora frames must be a multiple of 16 in width and height. + * To handle other frame sizes, a crop rectangle is specified in + * frame_height and frame_width, offset_x and * offset_y. The offset + * and size should still be a multiple of 2 to avoid chroma sampling + * shifts. Offset values in this structure are measured from the + * upper left of the image. + * + * Frame rate, in frames per second, is stored as a rational + * fraction. Aspect ratio is also stored as a rational fraction, and + * refers to the aspect ratio of the frame pixels, not of the + * overall frame itself. + * + * See <a href="http://svn.xiph.org/trunk/theora/examples/encoder_example.c"> + * examples/encoder_example.c</a> for usage examples of the + * other paramters and good default settings for the encoder parameters. + */ +typedef struct { + ogg_uint32_t width; /**< encoded frame width */ + ogg_uint32_t height; /**< encoded frame height */ + ogg_uint32_t frame_width; /**< display frame width */ + ogg_uint32_t frame_height; /**< display frame height */ + ogg_uint32_t offset_x; /**< horizontal offset of the displayed frame */ + ogg_uint32_t offset_y; /**< vertical offset of the displayed frame */ + ogg_uint32_t fps_numerator; /**< frame rate numerator **/ + ogg_uint32_t fps_denominator; /**< frame rate denominator **/ + ogg_uint32_t aspect_numerator; /**< pixel aspect ratio numerator */ + ogg_uint32_t aspect_denominator; /**< pixel aspect ratio denominator */ + theora_colorspace colorspace; /**< colorspace */ + int target_bitrate; /**< nominal bitrate in bits per second */ + int quality; /**< Nominal quality setting, 0-63 */ + int quick_p; /**< Quick encode/decode */ + + /* decode only */ + unsigned char version_major; + unsigned char version_minor; + unsigned char version_subminor; + + void *codec_setup; + + /* encode only */ + int dropframes_p; + int keyframe_auto_p; + ogg_uint32_t keyframe_frequency; + ogg_uint32_t keyframe_frequency_force; /* also used for decode init to + get granpos shift correct */ + ogg_uint32_t keyframe_data_target_bitrate; + ogg_int32_t keyframe_auto_threshold; + ogg_uint32_t keyframe_mindistance; + ogg_int32_t noise_sensitivity; + ogg_int32_t sharpness; + + theora_pixelformat pixelformat; /**< chroma subsampling mode to expect */ + +} theora_info; + +/** Codec internal state and context. + */ +typedef struct{ + theora_info *i; + ogg_int64_t granulepos; + + void *internal_encode; + void *internal_decode; + +} theora_state; + +/** + * Comment header metadata. + * + * This structure holds the in-stream metadata corresponding to + * the 'comment' header packet. + * + * Meta data is stored as a series of (tag, value) pairs, in + * length-encoded string vectors. The first occurence of the + * '=' character delimits the tag and value. A particular tag + * may occur more than once. The character set encoding for + * the strings is always UTF-8, but the tag names are limited + * to case-insensitive ASCII. See the spec for details. + * + * In filling in this structure, theora_decode_header() will + * null-terminate the user_comment strings for safety. However, + * the bitstream format itself treats them as 8-bit clean, + * and so the length array should be treated as authoritative + * for their length. + */ +typedef struct theora_comment{ + char **user_comments; /**< An array of comment string vectors */ + int *comment_lengths; /**< An array of corresponding string vector lengths in bytes */ + int comments; /**< The total number of comment string vectors */ + char *vendor; /**< The vendor string identifying the encoder, null terminated */ + +} theora_comment; + + +/**\name theora_control() codes */ +/* \anchor decctlcodes_old + * These are the available request codes for theora_control() + * when called with a decoder instance. + * By convention decoder control codes are odd, to distinguish + * them from \ref encctlcodes_old "encoder control codes" which + * are even. + * + * Note that since the 1.0 release, both the legacy and the final + * implementation accept all the same control codes, but only the + * final API declares the newer codes. + * + * Keep any experimental or vendor-specific values above \c 0x8000.*/ + +/*@{*/ + +/**Get the maximum post-processing level. + * The decoder supports a post-processing filter that can improve + * the appearance of the decoded images. This returns the highest + * level setting for this post-processor, corresponding to maximum + * improvement and computational expense. + */ +#define TH_DECCTL_GET_PPLEVEL_MAX (1) + +/**Set the post-processing level. + * Sets the level of post-processing to use when decoding the + * compressed stream. This must be a value between zero (off) + * and the maximum returned by TH_DECCTL_GET_PPLEVEL_MAX. + */ +#define TH_DECCTL_SET_PPLEVEL (3) + +/**Sets the maximum distance between key frames. + * This can be changed during an encode, but will be bounded by + * <tt>1<<th_info#keyframe_granule_shift</tt>. + * If it is set before encoding begins, th_info#keyframe_granule_shift will + * be enlarged appropriately. + * + * \param[in] buf <tt>ogg_uint32_t</tt>: The maximum distance between key + * frames. + * \param[out] buf <tt>ogg_uint32_t</tt>: The actual maximum distance set. + * \retval OC_FAULT \a theora_state or \a buf is <tt>NULL</tt>. + * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>. + * \retval OC_IMPL Not supported by this implementation.*/ +#define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4) + +/**Set the granule position. + * Call this after a seek, to update the internal granulepos + * in the decoder, to insure that subsequent frames are marked + * properly. If you track timestamps yourself and do not use + * the granule postion returned by the decoder, then you do + * not need to use this control. + */ +#define TH_DECCTL_SET_GRANPOS (5) + +/**\anchor encctlcodes_old */ + +/**Sets the quantization parameters to use. + * The parameters are copied, not stored by reference, so they can be freed + * after this call. + * <tt>NULL</tt> may be specified to revert to the default parameters. + * + * \param[in] buf #th_quant_info + * \retval OC_FAULT \a theora_state is <tt>NULL</tt>. + * \retval OC_EINVAL Encoding has already begun, the quantization parameters + * are not acceptable to this version of the encoder, + * \a buf is <tt>NULL</tt> and \a buf_sz is not zero, + * or \a buf is non-<tt>NULL</tt> and \a buf_sz is + * not <tt>sizeof(#th_quant_info)</tt>. + * \retval OC_IMPL Not supported by this implementation.*/ +#define TH_ENCCTL_SET_QUANT_PARAMS (2) + +/**Disables any encoder features that would prevent lossless transcoding back + * to VP3. + * This primarily means disabling block-level QI values and not using 4MV mode + * when any of the luma blocks in a macro block are not coded. + * It also includes using the VP3 quantization tables and Huffman codes; if you + * set them explicitly after calling this function, the resulting stream will + * not be VP3-compatible. + * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source + * material, or when using a picture region smaller than the full frame (e.g. + * a non-multiple-of-16 width or height), then non-VP3 bitstream features will + * still be disabled, but the stream will still not be VP3-compatible, as VP3 + * was not capable of encoding such formats. + * If you call this after encoding has already begun, then the quantization + * tables and codebooks cannot be changed, but the frame-level features will + * be enabled or disabled as requested. + * + * \param[in] buf <tt>int</tt>: a non-zero value to enable VP3 compatibility, + * or 0 to disable it (the default). + * \param[out] buf <tt>int</tt>: 1 if all bitstream features required for + * VP3-compatibility could be set, and 0 otherwise. + * The latter will be returned if the pixel format is not + * 4:2:0, the picture region is smaller than the full frame, + * or if encoding has begun, preventing the quantization + * tables and codebooks from being set. + * \retval OC_FAULT \a theora_state or \a buf is <tt>NULL</tt>. + * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>. + * \retval OC_IMPL Not supported by this implementation.*/ +#define TH_ENCCTL_SET_VP3_COMPATIBLE (10) + +/**Gets the maximum speed level. + * Higher speed levels favor quicker encoding over better quality per bit. + * Depending on the encoding mode, and the internal algorithms used, quality + * may actually improve, but in this case bitrate will also likely increase. + * In any case, overall rate/distortion performance will probably decrease. + * The maximum value, and the meaning of each value, may change depending on + * the current encoding mode (VBR vs. CQI, etc.). + * + * \param[out] buf int: The maximum encoding speed level. + * \retval OC_FAULT \a theora_state or \a buf is <tt>NULL</tt>. + * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>. + * \retval OC_IMPL Not supported by this implementation in the current + * encoding mode.*/ +#define TH_ENCCTL_GET_SPLEVEL_MAX (12) + +/**Sets the speed level. + * By default a speed value of 1 is used. + * + * \param[in] buf int: The new encoding speed level. + * 0 is slowest, larger values use less CPU. + * \retval OC_FAULT \a theora_state or \a buf is <tt>NULL</tt>. + * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>, or the + * encoding speed level is out of bounds. + * The maximum encoding speed level may be + * implementation- and encoding mode-specific, and can be + * obtained via #TH_ENCCTL_GET_SPLEVEL_MAX. + * \retval OC_IMPL Not supported by this implementation in the current + * encoding mode.*/ +#define TH_ENCCTL_SET_SPLEVEL (14) + +/*@}*/ + +#define OC_FAULT -1 /**< General failure */ +#define OC_EINVAL -10 /**< Library encountered invalid internal data */ +#define OC_DISABLED -11 /**< Requested action is disabled */ +#define OC_BADHEADER -20 /**< Header packet was corrupt/invalid */ +#define OC_NOTFORMAT -21 /**< Packet is not a theora packet */ +#define OC_VERSION -22 /**< Bitstream version is not handled */ +#define OC_IMPL -23 /**< Feature or action not implemented */ +#define OC_BADPACKET -24 /**< Packet is corrupt */ +#define OC_NEWPACKET -25 /**< Packet is an (ignorable) unhandled extension */ +#define OC_DUPFRAME 1 /**< Packet is a dropped frame */ + +/** + * Retrieve a human-readable string to identify the encoder vendor and version. + * \returns A version string. + */ +extern const char *theora_version_string(void); + +/** + * Retrieve a 32-bit version number. + * This number is composed of a 16-bit major version, 8-bit minor version + * and 8 bit sub-version, composed as follows: +<pre> + (VERSION_MAJOR<<16) + (VERSION_MINOR<<8) + (VERSION_SUB) +</pre> +* \returns The version number. +*/ +extern ogg_uint32_t theora_version_number(void); + +/** + * Initialize the theora encoder. + * \param th The theora_state handle to initialize for encoding. + * \param ti A theora_info struct filled with the desired encoding parameters. + * \retval 0 Success + */ +extern int theora_encode_init(theora_state *th, theora_info *ti); + +/** + * Submit a YUV buffer to the theora encoder. + * \param t A theora_state handle previously initialized for encoding. + * \param yuv A buffer of YUV data to encode. Note that both the yuv_buffer + * struct and the luma/chroma buffers within should be allocated by + * the user. + * \retval OC_EINVAL Encoder is not ready, or is finished. + * \retval -1 The size of the given frame differs from those previously input + * \retval 0 Success + */ +extern int theora_encode_YUVin(theora_state *t, yuv_buffer *yuv); + +/** + * Request the next packet of encoded video. + * The encoded data is placed in a user-provided ogg_packet structure. + * \param t A theora_state handle previously initialized for encoding. + * \param last_p whether this is the last packet the encoder should produce. + * \param op An ogg_packet structure to fill. libtheora will set all + * elements of this structure, including a pointer to encoded + * data. The memory for the encoded data is owned by libtheora. + * \retval 0 No internal storage exists OR no packet is ready + * \retval -1 The encoding process has completed + * \retval 1 Success + */ +extern int theora_encode_packetout( theora_state *t, int last_p, + ogg_packet *op); + +/** + * Request a packet containing the initial header. + * A pointer to the header data is placed in a user-provided ogg_packet + * structure. + * \param t A theora_state handle previously initialized for encoding. + * \param op An ogg_packet structure to fill. libtheora will set all + * elements of this structure, including a pointer to the header + * data. The memory for the header data is owned by libtheora. + * \retval 0 Success + */ +extern int theora_encode_header(theora_state *t, ogg_packet *op); + +/** + * Request a comment header packet from provided metadata. + * A pointer to the comment data is placed in a user-provided ogg_packet + * structure. + * \param tc A theora_comment structure filled with the desired metadata + * \param op An ogg_packet structure to fill. libtheora will set all + * elements of this structure, including a pointer to the encoded + * comment data. The memory for the comment data is owned by + * libtheora. + * \retval 0 Success + */ +extern int theora_encode_comment(theora_comment *tc, ogg_packet *op); + +/** + * Request a packet containing the codebook tables for the stream. + * A pointer to the codebook data is placed in a user-provided ogg_packet + * structure. + * \param t A theora_state handle previously initialized for encoding. + * \param op An ogg_packet structure to fill. libtheora will set all + * elements of this structure, including a pointer to the codebook + * data. The memory for the header data is owned by libtheora. + * \retval 0 Success + */ +extern int theora_encode_tables(theora_state *t, ogg_packet *op); + +/** + * Decode an Ogg packet, with the expectation that the packet contains + * an initial header, comment data or codebook tables. + * + * \param ci A theora_info structure to fill. This must have been previously + * initialized with theora_info_init(). If \a op contains an initial + * header, theora_decode_header() will fill \a ci with the + * parsed header values. If \a op contains codebook tables, + * theora_decode_header() will parse these and attach an internal + * representation to \a ci->codec_setup. + * \param cc A theora_comment structure to fill. If \a op contains comment + * data, theora_decode_header() will fill \a cc with the parsed + * comments. + * \param op An ogg_packet structure which you expect contains an initial + * header, comment data or codebook tables. + * + * \retval OC_BADHEADER \a op is NULL; OR the first byte of \a op->packet + * has the signature of an initial packet, but op is + * not a b_o_s packet; OR this packet has the signature + * of an initial header packet, but an initial header + * packet has already been seen; OR this packet has the + * signature of a comment packet, but the initial header + * has not yet been seen; OR this packet has the signature + * of a comment packet, but contains invalid data; OR + * this packet has the signature of codebook tables, + * but the initial header or comments have not yet + * been seen; OR this packet has the signature of codebook + * tables, but contains invalid data; + * OR the stream being decoded has a compatible version + * but this packet does not have the signature of a + * theora initial header, comments, or codebook packet + * \retval OC_VERSION The packet data of \a op is an initial header with + * a version which is incompatible with this version of + * libtheora. + * \retval OC_NEWPACKET the stream being decoded has an incompatible (future) + * version and contains an unknown signature. + * \retval 0 Success + * + * \note The normal usage is that theora_decode_header() be called on the + * first three packets of a theora logical bitstream in succession. + */ +extern int theora_decode_header(theora_info *ci, theora_comment *cc, + ogg_packet *op); + +/** + * Initialize a theora_state handle for decoding. + * \param th The theora_state handle to initialize. + * \param c A theora_info struct filled with the desired decoding parameters. + * This is of course usually obtained from a previous call to + * theora_decode_header(). + * \retval 0 Success + */ +extern int theora_decode_init(theora_state *th, theora_info *c); + +/** + * Input a packet containing encoded data into the theora decoder. + * \param th A theora_state handle previously initialized for decoding. + * \param op An ogg_packet containing encoded theora data. + * \retval 0 Success + * \retval OC_BADPACKET \a op does not contain encoded video data + */ +extern int theora_decode_packetin(theora_state *th,ogg_packet *op); + +/** + * Output the next available frame of decoded YUV data. + * \param th A theora_state handle previously initialized for decoding. + * \param yuv A yuv_buffer in which libtheora should place the decoded data. + * Note that the buffer struct itself is allocated by the user, but + * that the luma and chroma pointers will be filled in by the + * library. Also note that these luma and chroma regions should be + * considered read-only by the user. + * \retval 0 Success + */ +extern int theora_decode_YUVout(theora_state *th,yuv_buffer *yuv); + +/** + * Report whether a theora packet is a header or not + * This function does no verification beyond checking the header + * flag bit so it should not be used for bitstream identification; + * use theora_decode_header() for that. + * + * \param op An ogg_packet containing encoded theora data. + * \retval 1 The packet is a header packet + * \retval 0 The packet is not a header packet (and so contains frame data) + * + * Thus function was added in the 1.0alpha4 release. + */ +extern int theora_packet_isheader(ogg_packet *op); + +/** + * Report whether a theora packet is a keyframe or not + * + * \param op An ogg_packet containing encoded theora data. + * \retval 1 The packet contains a keyframe image + * \retval 0 The packet is contains an interframe delta + * \retval -1 The packet is not an image data packet at all + * + * Thus function was added in the 1.0alpha4 release. + */ +extern int theora_packet_iskeyframe(ogg_packet *op); + +/** + * Report the granulepos shift radix + * + * When embedded in Ogg, Theora uses a two-part granulepos, + * splitting the 64-bit field into two pieces. The more-significant + * section represents the frame count at the last keyframe, + * and the less-significant section represents the count of + * frames since the last keyframe. In this way the overall + * field is still non-decreasing with time, but usefully encodes + * a pointer to the last keyframe, which is necessary for + * correctly restarting decode after a seek. + * + * This function reports the number of bits used to represent + * the distance to the last keyframe, and thus how the granulepos + * field must be shifted or masked to obtain the two parts. + * + * Since libtheora returns compressed data in an ogg_packet + * structure, this may be generally useful even if the Theora + * packets are not being used in an Ogg container. + * + * \param ti A previously initialized theora_info struct + * \returns The bit shift dividing the two granulepos fields + * + * This function was added in the 1.0alpha5 release. + */ +int theora_granule_shift(theora_info *ti); + +/** + * Convert a granulepos to an absolute frame index, starting at 0. + * The granulepos is interpreted in the context of a given theora_state handle. + * + * Note that while the granulepos encodes the frame count (i.e. starting + * from 1) this call returns the frame index, starting from zero. Thus + * One can calculate the presentation time by multiplying the index by + * the rate. + * + * \param th A previously initialized theora_state handle (encode or decode) + * \param granulepos The granulepos to convert. + * \returns The frame index corresponding to \a granulepos. + * \retval -1 The given granulepos is undefined (i.e. negative) + * + * Thus function was added in the 1.0alpha4 release. + */ +extern ogg_int64_t theora_granule_frame(theora_state *th,ogg_int64_t granulepos); + +/** + * Convert a granulepos to absolute time in seconds. The granulepos is + * interpreted in the context of a given theora_state handle, and gives + * the end time of a frame's presentation as used in Ogg mux ordering. + * + * \param th A previously initialized theora_state handle (encode or decode) + * \param granulepos The granulepos to convert. + * \returns The absolute time in seconds corresponding to \a granulepos. + * This is the "end time" for the frame, or the latest time it should + * be displayed. + * It is not the presentation time. + * \retval -1. The given granulepos is undefined (i.e. negative), or + * \retval -1. The function has been disabled because floating + * point support is not available. + */ +extern double theora_granule_time(theora_state *th,ogg_int64_t granulepos); + +/** + * Initialize a theora_info structure. All values within the given theora_info + * structure are initialized, and space is allocated within libtheora for + * internal codec setup data. + * \param c A theora_info struct to initialize. + */ +extern void theora_info_init(theora_info *c); + +/** + * Clear a theora_info structure. All values within the given theora_info + * structure are cleared, and associated internal codec setup data is freed. + * \param c A theora_info struct to initialize. + */ +extern void theora_info_clear(theora_info *c); + +/** + * Free all internal data associated with a theora_state handle. + * \param t A theora_state handle. + */ +extern void theora_clear(theora_state *t); + +/** + * Initialize an allocated theora_comment structure + * \param tc An allocated theora_comment structure + **/ +extern void theora_comment_init(theora_comment *tc); + +/** + * Add a comment to an initialized theora_comment structure + * \param tc A previously initialized theora comment structure + * \param comment A null-terminated string encoding the comment in the form + * "TAG=the value" + * + * Neither theora_comment_add() nor theora_comment_add_tag() support + * comments containing null values, although the bitstream format + * supports this. To add such comments you will need to manipulate + * the theora_comment structure directly. + **/ + +extern void theora_comment_add(theora_comment *tc, char *comment); + +/** + * Add a comment to an initialized theora_comment structure. + * \param tc A previously initialized theora comment structure + * \param tag A null-terminated string containing the tag + * associated with the comment. + * \param value The corresponding value as a null-terminated string + * + * Neither theora_comment_add() nor theora_comment_add_tag() support + * comments containing null values, although the bitstream format + * supports this. To add such comments you will need to manipulate + * the theora_comment structure directly. + **/ +extern void theora_comment_add_tag(theora_comment *tc, + char *tag, char *value); + +/** + * Look up a comment value by tag. + * \param tc Tn initialized theora_comment structure + * \param tag The tag to look up + * \param count The instance of the tag. The same tag can appear multiple + * times, each with a distinct and ordered value, so an index + * is required to retrieve them all. + * \returns A pointer to the queried tag's value + * \retval NULL No matching tag is found + * + * \note Use theora_comment_query_count() to get the legal range for the + * count parameter. + **/ + +extern char *theora_comment_query(theora_comment *tc, char *tag, int count); + +/** Look up the number of instances of a tag. + * \param tc An initialized theora_comment structure + * \param tag The tag to look up + * \returns The number on instances of a particular tag. + * + * Call this first when querying for a specific tag and then interate + * over the number of instances with separate calls to + * theora_comment_query() to retrieve all instances in order. + **/ +extern int theora_comment_query_count(theora_comment *tc, char *tag); + +/** + * Clear an allocated theora_comment struct so that it can be freed. + * \param tc An allocated theora_comment structure. + **/ +extern void theora_comment_clear(theora_comment *tc); + +/**Encoder control function. + * This is used to provide advanced control the encoding process. + * \param th A #theora_state handle. + * \param req The control code to process. + * See \ref encctlcodes_old "the list of available + * control codes" for details. + * \param buf The parameters for this control code. + * \param buf_sz The size of the parameter buffer.*/ +extern int theora_control(theora_state *th,int req,void *buf,size_t buf_sz); + +/* @} */ /* end oldfuncs doxygen group */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _O_THEORA_H_ */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/theoradec.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/theoradec.h new file mode 100644 index 00000000..b20f0e3a --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/theora/theoradec.h @@ -0,0 +1,325 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: + last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $ + + ********************************************************************/ + +/**\file + * The <tt>libtheoradec</tt> C decoding API.*/ + +#if !defined(_O_THEORA_THEORADEC_H_) +# define _O_THEORA_THEORADEC_H_ (1) +# include <stddef.h> +# include <ogg/ogg.h> +# include "codec.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + + +/**\name th_decode_ctl() codes + * \anchor decctlcodes + * These are the available request codes for th_decode_ctl(). + * By convention, these are odd, to distinguish them from the + * \ref encctlcodes "encoder control codes". + * Keep any experimental or vendor-specific values above \c 0x8000.*/ +/*@{*/ +/**Gets the maximum post-processing level. + * The decoder supports a post-processing filter that can improve + * the appearance of the decoded images. This returns the highest + * level setting for this post-processor, corresponding to maximum + * improvement and computational expense. + * + * \param[out] _buf int: The maximum post-processing level. + * \retval TH_EFAULT \a _dec_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>. + * \retval TH_EIMPL Not supported by this implementation.*/ +#define TH_DECCTL_GET_PPLEVEL_MAX (1) +/**Sets the post-processing level. + * By default, post-processing is disabled. + * + * Sets the level of post-processing to use when decoding the + * compressed stream. This must be a value between zero (off) + * and the maximum returned by TH_DECCTL_GET_PPLEVEL_MAX. + * + * \param[in] _buf int: The new post-processing level. + * 0 to disable; larger values use more CPU. + * \retval TH_EFAULT \a _dec_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the + * post-processing level is out of bounds. + * The maximum post-processing level may be + * implementation-specific, and can be obtained via + * #TH_DECCTL_GET_PPLEVEL_MAX. + * \retval TH_EIMPL Not supported by this implementation.*/ +#define TH_DECCTL_SET_PPLEVEL (3) +/**Sets the granule position. + * Call this after a seek, before decoding the first frame, to ensure that the + * proper granule position is returned for all subsequent frames. + * If you track timestamps yourself and do not use the granule position + * returned by the decoder, then you need not call this function. + * + * \param[in] _buf <tt>ogg_int64_t</tt>: The granule position of the next + * frame. + * \retval TH_EFAULT \a _dec_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(ogg_int64_t)</tt>, or the + * granule position is negative.*/ +#define TH_DECCTL_SET_GRANPOS (5) +/**Sets the striped decode callback function. + * If set, this function will be called as each piece of a frame is fully + * decoded in th_decode_packetin(). + * You can pass in a #th_stripe_callback with + * th_stripe_callback#stripe_decoded set to <tt>NULL</tt> to disable the + * callbacks at any point. + * Enabling striped decode does not prevent you from calling + * th_decode_ycbcr_out() after the frame is fully decoded. + * + * \param[in] _buf #th_stripe_callback: The callback parameters. + * \retval TH_EFAULT \a _dec_ctx or \a _buf is <tt>NULL</tt>. + * \retval TH_EINVAL \a _buf_sz is not + * <tt>sizeof(th_stripe_callback)</tt>.*/ +#define TH_DECCTL_SET_STRIPE_CB (7) + +/**Enables telemetry and sets the macroblock display mode */ +#define TH_DECCTL_SET_TELEMETRY_MBMODE (9) +/**Enables telemetry and sets the motion vector display mode */ +#define TH_DECCTL_SET_TELEMETRY_MV (11) +/**Enables telemetry and sets the adaptive quantization display mode */ +#define TH_DECCTL_SET_TELEMETRY_QI (13) +/**Enables telemetry and sets the bitstream breakdown visualization mode */ +#define TH_DECCTL_SET_TELEMETRY_BITS (15) +/*@}*/ + + + +/**A callback function for striped decode. + * This is a function pointer to an application-provided function that will be + * called each time a section of the image is fully decoded in + * th_decode_packetin(). + * This allows the application to process the section immediately, while it is + * still in cache. + * Note that the frame is decoded bottom to top, so \a _yfrag0 will steadily + * decrease with each call until it reaches 0, at which point the full frame + * is decoded. + * The number of fragment rows made available in each call depends on the pixel + * format and the number of post-processing filters enabled, and may not even + * be constant for the entire frame. + * If a non-<tt>NULL</tt> \a _granpos pointer is passed to + * th_decode_packetin(), the granule position for the frame will be stored + * in it before the first callback is made. + * If an entire frame is dropped (a 0-byte packet), then no callbacks will be + * made at all for that frame. + * \param _ctx An application-provided context pointer. + * \param _buf The image buffer for the decoded frame. + * \param _yfrag0 The Y coordinate of the first row of 8x8 fragments + * decoded. + * Multiply this by 8 to obtain the pixel row number in the + * luma plane. + * If the chroma planes are subsampled in the Y direction, + * this will always be divisible by two. + * \param _yfrag_end The Y coordinate of the first row of 8x8 fragments past + * the newly decoded section. + * If the chroma planes are subsampled in the Y direction, + * this will always be divisible by two. + * I.e., this section contains fragment rows + * <tt>\a _yfrag0 ...\a _yfrag_end -1</tt>.*/ +typedef void (*th_stripe_decoded_func)(void *_ctx,th_ycbcr_buffer _buf, + int _yfrag0,int _yfrag_end); + +/**The striped decode callback data to pass to #TH_DECCTL_SET_STRIPE_CB.*/ +typedef struct{ + /**An application-provided context pointer. + * This will be passed back verbatim to the application.*/ + void *ctx; + /**The callback function pointer.*/ + th_stripe_decoded_func stripe_decoded; +}th_stripe_callback; + + + +/**\name Decoder state + The following data structures are opaque, and their contents are not + publicly defined by this API. + Referring to their internals directly is unsupported, and may break without + warning.*/ +/*@{*/ +/**The decoder context.*/ +typedef struct th_dec_ctx th_dec_ctx; +/**Setup information. + This contains auxiliary information (Huffman tables and quantization + parameters) decoded from the setup header by th_decode_headerin() to be + passed to th_decode_alloc(). + It can be re-used to initialize any number of decoders, and can be freed + via th_setup_free() at any time.*/ +typedef struct th_setup_info th_setup_info; +/*@}*/ + + + +/**\defgroup decfuncs Functions for Decoding*/ +/*@{*/ +/**\name Functions for decoding + * You must link to <tt>libtheoradec</tt> if you use any of the + * functions in this section. + * + * The functions are listed in the order they are used in a typical decode. + * The basic steps are: + * - Parse the header packets by repeatedly calling th_decode_headerin(). + * - Allocate a #th_dec_ctx handle with th_decode_alloc(). + * - Call th_setup_free() to free any memory used for codec setup + * information. + * - Perform any additional decoder configuration with th_decode_ctl(). + * - For each video data packet: + * - Submit the packet to the decoder via th_decode_packetin(). + * - Retrieve the uncompressed video data via th_decode_ycbcr_out(). + * - Call th_decode_free() to release all decoder memory.*/ +/*@{*/ +/**Decodes the header packets of a Theora stream. + * This should be called on the initial packets of the stream, in succession, + * until it returns <tt>0</tt>, indicating that all headers have been + * processed, or an error is encountered. + * At least three header packets are required, and additional optional header + * packets may follow. + * This can be used on the first packet of any logical stream to determine if + * that stream is a Theora stream. + * \param _info A #th_info structure to fill in. + * This must have been previously initialized with + * th_info_init(). + * The application may immediately begin using the contents of + * this structure after the first header is decoded, though it + * must continue to be passed in on all subsequent calls. + * \param _tc A #th_comment structure to fill in. + * The application may immediately begin using the contents of + * this structure after the second header is decoded, though it + * must continue to be passed in on all subsequent calls. + * \param _setup Returns a pointer to additional, private setup information + * needed by the decoder. + * The contents of this pointer must be initialized to + * <tt>NULL</tt> on the first call, and the returned value must + * continue to be passed in on all subsequent calls. + * \param _op An <tt>ogg_packet</tt> structure which contains one of the + * initial packets of an Ogg logical stream. + * \return A positive value indicates that a Theora header was successfully + * processed. + * \retval 0 The first video data packet was encountered after all + * required header packets were parsed. + * The packet just passed in on this call should be saved + * and fed to th_decode_packetin() to begin decoding + * video data. + * \retval TH_EFAULT One of \a _info, \a _tc, or \a _setup was + * <tt>NULL</tt>. + * \retval TH_EBADHEADER \a _op was <tt>NULL</tt>, the packet was not the next + * header packet in the expected sequence, or the format + * of the header data was invalid. + * \retval TH_EVERSION The packet data was a Theora info header, but for a + * bitstream version not decodable with this version of + * <tt>libtheoradec</tt>. + * \retval TH_ENOTFORMAT The packet was not a Theora header. + */ +extern int th_decode_headerin(th_info *_info,th_comment *_tc, + th_setup_info **_setup,ogg_packet *_op); +/**Allocates a decoder instance. + * + * <b>Security Warning:</b> The Theora format supports very large frame sizes, + * potentially even larger than the address space of a 32-bit machine, and + * creating a decoder context allocates the space for several frames of data. + * If the allocation fails here, your program will crash, possibly at some + * future point because the OS kernel returned a valid memory range and will + * only fail when it tries to map the pages in it the first time they are + * used. + * Even if it succeeds, you may experience a denial of service if the frame + * size is large enough to cause excessive paging. + * If you are integrating libtheora in a larger application where such things + * are undesirable, it is highly recommended that you check the frame size in + * \a _info before calling this function and refuse to decode streams where it + * is larger than some reasonable maximum. + * libtheora will not check this for you, because there may be machines that + * can handle such streams and applications that wish to. + * \param _info A #th_info struct filled via th_decode_headerin(). + * \param _setup A #th_setup_info handle returned via + * th_decode_headerin(). + * \return The initialized #th_dec_ctx handle. + * \retval NULL If the decoding parameters were invalid.*/ +extern th_dec_ctx *th_decode_alloc(const th_info *_info, + const th_setup_info *_setup); +/**Releases all storage used for the decoder setup information. + * This should be called after you no longer want to create any decoders for + * a stream whose headers you have parsed with th_decode_headerin(). + * \param _setup The setup information to free. + * This can safely be <tt>NULL</tt>.*/ +extern void th_setup_free(th_setup_info *_setup); +/**Decoder control function. + * This is used to provide advanced control of the decoding process. + * \param _dec A #th_dec_ctx handle. + * \param _req The control code to process. + * See \ref decctlcodes "the list of available control codes" + * for details. + * \param _buf The parameters for this control code. + * \param _buf_sz The size of the parameter buffer.*/ +extern int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf, + size_t _buf_sz); +/**Submits a packet containing encoded video data to the decoder. + * \param _dec A #th_dec_ctx handle. + * \param _op An <tt>ogg_packet</tt> containing encoded video data. + * \param _granpos Returns the granule position of the decoded packet. + * If non-<tt>NULL</tt>, the granule position for this specific + * packet is stored in this location. + * This is computed incrementally from previously decoded + * packets. + * After a seek, the correct granule position must be set via + * #TH_DECCTL_SET_GRANPOS for this to work properly. + * \retval 0 Success. + * A new decoded frame can be retrieved by calling + * th_decode_ycbcr_out(). + * \retval TH_DUPFRAME The packet represented a dropped (0-byte) frame. + * The player can skip the call to th_decode_ycbcr_out(), + * as the contents of the decoded frame buffer have not + * changed. + * \retval TH_EFAULT \a _dec or \a _op was <tt>NULL</tt>. + * \retval TH_EBADPACKET \a _op does not contain encoded video data. + * \retval TH_EIMPL The video data uses bitstream features which this + * library does not support.*/ +extern int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op, + ogg_int64_t *_granpos); +/**Outputs the next available frame of decoded Y'CbCr data. + * If a striped decode callback has been set with #TH_DECCTL_SET_STRIPE_CB, + * then the application does not need to call this function. + * \param _dec A #th_dec_ctx handle. + * \param _ycbcr A video buffer structure to fill in. + * <tt>libtheoradec</tt> will fill in all the members of this + * structure, including the pointers to the uncompressed video + * data. + * The memory for this video data is owned by + * <tt>libtheoradec</tt>. + * It may be freed or overwritten without notification when + * subsequent frames are decoded. + * \retval 0 Success + * \retval TH_EFAULT \a _dec or \a _ycbcr was <tt>NULL</tt>. + */ +extern int th_decode_ycbcr_out(th_dec_ctx *_dec, + th_ycbcr_buffer _ycbcr); +/**Frees an allocated decoder instance. + * \param _dec A #th_dec_ctx handle.*/ +extern void th_decode_free(th_dec_ctx *_dec); +/*@}*/ +/*@}*/ + + + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/turbojpeg.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/turbojpeg.h new file mode 100644 index 00000000..1ada65a2 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/turbojpeg.h @@ -0,0 +1,1538 @@ +/* + * Copyright (C)2009-2014 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __TURBOJPEG_H__ +#define __TURBOJPEG_H__ + +#if defined(_WIN32) && defined(DLLDEFINE) +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT +#endif +#define DLLCALL + + +/** + * @addtogroup TurboJPEG + * TurboJPEG API. This API provides an interface for generating, decoding, and + * transforming planar YUV and JPEG images in memory. + * + * @anchor YUVnotes + * YUV Image Format Notes + * ---------------------- + * Technically, the JPEG format uses the YCbCr colorspace (which is technically + * not a colorspace but a color transform), but per the convention of the + * digital video community, the TurboJPEG API uses "YUV" to refer to an image + * format consisting of Y, Cb, and Cr image planes. + * + * Each plane is simply a 2D array of bytes, each byte representing the value + * of one of the components (Y, Cb, or Cr) at a particular location in the + * image. The width and height of each plane are determined by the image + * width, height, and level of chrominance subsampling. The luminance plane + * width is the image width padded to the nearest multiple of the horizontal + * subsampling factor (2 in the case of 4:2:0 and 4:2:2, 4 in the case of + * 4:1:1, 1 in the case of 4:4:4 or grayscale.) Similarly, the luminance plane + * height is the image height padded to the nearest multiple of the vertical + * subsampling factor (2 in the case of 4:2:0 or 4:4:0, 1 in the case of 4:4:4 + * or grayscale.) This is irrespective of any additional padding that may be + * specified as an argument to the various YUV functions. The chrominance + * plane width is equal to the luminance plane width divided by the horizontal + * subsampling factor, and the chrominance plane height is equal to the + * luminance plane height divided by the vertical subsampling factor. + * + * For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling is + * used, then the luminance plane would be 36 x 35 bytes, and each of the + * chrominance planes would be 18 x 35 bytes. If you specify a line padding of + * 4 bytes on top of this, then the luminance plane would be 36 x 35 bytes, and + * each of the chrominance planes would be 20 x 35 bytes. + * + * @{ + */ + + +/** + * The number of chrominance subsampling options + */ +#define TJ_NUMSAMP 6 + +/** + * Chrominance subsampling options. + * When pixels are converted from RGB to YCbCr (see #TJCS_YCbCr) or from CMYK + * to YCCK (see #TJCS_YCCK) as part of the JPEG compression process, some of + * the Cb and Cr (chrominance) components can be discarded or averaged together + * to produce a smaller image with little perceptible loss of image clarity + * (the human eye is more sensitive to small changes in brightness than to + * small changes in color.) This is called "chrominance subsampling". + */ +enum TJSAMP +{ + /** + * 4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG or + * YUV image will contain one chrominance component for every pixel in the + * source image. + */ + TJSAMP_444=0, + /** + * 4:2:2 chrominance subsampling. The JPEG or YUV image will contain one + * chrominance component for every 2x1 block of pixels in the source image. + */ + TJSAMP_422, + /** + * 4:2:0 chrominance subsampling. The JPEG or YUV image will contain one + * chrominance component for every 2x2 block of pixels in the source image. + */ + TJSAMP_420, + /** + * Grayscale. The JPEG or YUV image will contain no chrominance components. + */ + TJSAMP_GRAY, + /** + * 4:4:0 chrominance subsampling. The JPEG or YUV image will contain one + * chrominance component for every 1x2 block of pixels in the source image. + * + * @note 4:4:0 subsampling is not fully accelerated in libjpeg-turbo. + */ + TJSAMP_440, + /** + * 4:1:1 chrominance subsampling. The JPEG or YUV image will contain one + * chrominance component for every 4x1 block of pixels in the source image. + * JPEG images compressed with 4:1:1 subsampling will be almost exactly the + * same size as those compressed with 4:2:0 subsampling, and in the + * aggregate, both subsampling methods produce approximately the same + * perceptual quality. However, 4:1:1 is better able to reproduce sharp + * horizontal features. + * + * @note 4:1:1 subsampling is not fully accelerated in libjpeg-turbo. + */ + TJSAMP_411 +}; + +/** + * MCU block width (in pixels) for a given level of chrominance subsampling. + * MCU block sizes: + * - 8x8 for no subsampling or grayscale + * - 16x8 for 4:2:2 + * - 8x16 for 4:4:0 + * - 16x16 for 4:2:0 + * - 32x8 for 4:1:1 + */ +static const int tjMCUWidth[TJ_NUMSAMP] = {8, 16, 16, 8, 8, 32}; + +/** + * MCU block height (in pixels) for a given level of chrominance subsampling. + * MCU block sizes: + * - 8x8 for no subsampling or grayscale + * - 16x8 for 4:2:2 + * - 8x16 for 4:4:0 + * - 16x16 for 4:2:0 + * - 32x8 for 4:1:1 + */ +static const int tjMCUHeight[TJ_NUMSAMP] = {8, 8, 16, 8, 16, 8}; + + +/** + * The number of pixel formats + */ +#define TJ_NUMPF 12 + +/** + * Pixel formats + */ +enum TJPF +{ + /** + * RGB pixel format. The red, green, and blue components in the image are + * stored in 3-byte pixels in the order R, G, B from lowest to highest byte + * address within each pixel. + */ + TJPF_RGB=0, + /** + * BGR pixel format. The red, green, and blue components in the image are + * stored in 3-byte pixels in the order B, G, R from lowest to highest byte + * address within each pixel. + */ + TJPF_BGR, + /** + * RGBX pixel format. The red, green, and blue components in the image are + * stored in 4-byte pixels in the order R, G, B from lowest to highest byte + * address within each pixel. The X component is ignored when compressing + * and undefined when decompressing. + */ + TJPF_RGBX, + /** + * BGRX pixel format. The red, green, and blue components in the image are + * stored in 4-byte pixels in the order B, G, R from lowest to highest byte + * address within each pixel. The X component is ignored when compressing + * and undefined when decompressing. + */ + TJPF_BGRX, + /** + * XBGR pixel format. The red, green, and blue components in the image are + * stored in 4-byte pixels in the order R, G, B from highest to lowest byte + * address within each pixel. The X component is ignored when compressing + * and undefined when decompressing. + */ + TJPF_XBGR, + /** + * XRGB pixel format. The red, green, and blue components in the image are + * stored in 4-byte pixels in the order B, G, R from highest to lowest byte + * address within each pixel. The X component is ignored when compressing + * and undefined when decompressing. + */ + TJPF_XRGB, + /** + * Grayscale pixel format. Each 1-byte pixel represents a luminance + * (brightness) level from 0 to 255. + */ + TJPF_GRAY, + /** + * RGBA pixel format. This is the same as @ref TJPF_RGBX, except that when + * decompressing, the X component is guaranteed to be 0xFF, which can be + * interpreted as an opaque alpha channel. + */ + TJPF_RGBA, + /** + * BGRA pixel format. This is the same as @ref TJPF_BGRX, except that when + * decompressing, the X component is guaranteed to be 0xFF, which can be + * interpreted as an opaque alpha channel. + */ + TJPF_BGRA, + /** + * ABGR pixel format. This is the same as @ref TJPF_XBGR, except that when + * decompressing, the X component is guaranteed to be 0xFF, which can be + * interpreted as an opaque alpha channel. + */ + TJPF_ABGR, + /** + * ARGB pixel format. This is the same as @ref TJPF_XRGB, except that when + * decompressing, the X component is guaranteed to be 0xFF, which can be + * interpreted as an opaque alpha channel. + */ + TJPF_ARGB, + /** + * CMYK pixel format. Unlike RGB, which is an additive color model used + * primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive + * color model used primarily for printing. In the CMYK color model, the + * value of each color component typically corresponds to an amount of cyan, + * magenta, yellow, or black ink that is applied to a white background. In + * order to convert between CMYK and RGB, it is necessary to use a color + * management system (CMS.) A CMS will attempt to map colors within the + * printer's gamut to perceptually similar colors in the display's gamut and + * vice versa, but the mapping is typically not 1:1 or reversible, nor can it + * be defined with a simple formula. Thus, such a conversion is out of scope + * for a codec library. However, the TurboJPEG API allows for compressing + * CMYK pixels into a YCCK JPEG image (see #TJCS_YCCK) and decompressing YCCK + * JPEG images into CMYK pixels. + */ + TJPF_CMYK +}; + + +/** + * Red offset (in bytes) for a given pixel format. This specifies the number + * of bytes that the red component is offset from the start of the pixel. For + * instance, if a pixel of format TJ_BGRX is stored in <tt>char pixel[]</tt>, + * then the red component will be <tt>pixel[tjRedOffset[TJ_BGRX]]</tt>. + */ +static const int tjRedOffset[TJ_NUMPF] = {0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1, -1}; +/** + * Green offset (in bytes) for a given pixel format. This specifies the number + * of bytes that the green component is offset from the start of the pixel. + * For instance, if a pixel of format TJ_BGRX is stored in + * <tt>char pixel[]</tt>, then the green component will be + * <tt>pixel[tjGreenOffset[TJ_BGRX]]</tt>. + */ +static const int tjGreenOffset[TJ_NUMPF] = {1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2, -1}; +/** + * Blue offset (in bytes) for a given pixel format. This specifies the number + * of bytes that the Blue component is offset from the start of the pixel. For + * instance, if a pixel of format TJ_BGRX is stored in <tt>char pixel[]</tt>, + * then the blue component will be <tt>pixel[tjBlueOffset[TJ_BGRX]]</tt>. + */ +static const int tjBlueOffset[TJ_NUMPF] = {2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3, -1}; + +/** + * Pixel size (in bytes) for a given pixel format. + */ +static const int tjPixelSize[TJ_NUMPF] = {3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4}; + + +/** + * The number of JPEG colorspaces + */ +#define TJ_NUMCS 5 + +/** + * JPEG colorspaces + */ +enum TJCS +{ + /** + * RGB colorspace. When compressing the JPEG image, the R, G, and B + * components in the source image are reordered into image planes, but no + * colorspace conversion or subsampling is performed. RGB JPEG images can be + * decompressed to any of the extended RGB pixel formats or grayscale, but + * they cannot be decompressed to YUV images. + */ + TJCS_RGB=0, + /** + * YCbCr colorspace. YCbCr is not an absolute colorspace but rather a + * mathematical transformation of RGB designed solely for storage and + * transmission. YCbCr images must be converted to RGB before they can + * actually be displayed. In the YCbCr colorspace, the Y (luminance) + * component represents the black & white portion of the original image, and + * the Cb and Cr (chrominance) components represent the color portion of the + * original image. Originally, the analog equivalent of this transformation + * allowed the same signal to drive both black & white and color televisions, + * but JPEG images use YCbCr primarily because it allows the color data to be + * optionally subsampled for the purposes of reducing bandwidth or disk + * space. YCbCr is the most common JPEG colorspace, and YCbCr JPEG images + * can be compressed from and decompressed to any of the extended RGB pixel + * formats or grayscale, or they can be decompressed to YUV planar images. + */ + TJCS_YCbCr, + /** + * Grayscale colorspace. The JPEG image retains only the luminance data (Y + * component), and any color data from the source image is discarded. + * Grayscale JPEG images can be compressed from and decompressed to any of + * the extended RGB pixel formats or grayscale, or they can be decompressed + * to YUV planar images. + */ + TJCS_GRAY, + /** + * CMYK colorspace. When compressing the JPEG image, the C, M, Y, and K + * components in the source image are reordered into image planes, but no + * colorspace conversion or subsampling is performed. CMYK JPEG images can + * only be decompressed to CMYK pixels. + */ + TJCS_CMYK, + /** + * YCCK colorspace. YCCK (AKA "YCbCrK") is not an absolute colorspace but + * rather a mathematical transformation of CMYK designed solely for storage + * and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be + * reversibly transformed into YCCK, and as with YCbCr, the chrominance + * components in the YCCK pixels can be subsampled without incurring major + * perceptual loss. YCCK JPEG images can only be compressed from and + * decompressed to CMYK pixels. + */ + TJCS_YCCK +}; + + +/** + * The uncompressed source/destination image is stored in bottom-up (Windows, + * OpenGL) order, not top-down (X11) order. + */ +#define TJFLAG_BOTTOMUP 2 +/** + * When decompressing an image that was compressed using chrominance + * subsampling, use the fastest chrominance upsampling algorithm available in + * the underlying codec. The default is to use smooth upsampling, which + * creates a smooth transition between neighboring chrominance components in + * order to reduce upsampling artifacts in the decompressed image. + */ +#define TJFLAG_FASTUPSAMPLE 256 +/** + * Disable buffer (re)allocation. If passed to #tjCompress2() or + * #tjTransform(), this flag will cause those functions to generate an error if + * the JPEG image buffer is invalid or too small rather than attempting to + * allocate or reallocate that buffer. This reproduces the behavior of earlier + * versions of TurboJPEG. + */ +#define TJFLAG_NOREALLOC 1024 +/** + * Use the fastest DCT/IDCT algorithm available in the underlying codec. The + * default if this flag is not specified is implementation-specific. For + * example, the implementation of TurboJPEG for libjpeg[-turbo] uses the fast + * algorithm by default when compressing, because this has been shown to have + * only a very slight effect on accuracy, but it uses the accurate algorithm + * when decompressing, because this has been shown to have a larger effect. + */ +#define TJFLAG_FASTDCT 2048 +/** + * Use the most accurate DCT/IDCT algorithm available in the underlying codec. + * The default if this flag is not specified is implementation-specific. For + * example, the implementation of TurboJPEG for libjpeg[-turbo] uses the fast + * algorithm by default when compressing, because this has been shown to have + * only a very slight effect on accuracy, but it uses the accurate algorithm + * when decompressing, because this has been shown to have a larger effect. + */ +#define TJFLAG_ACCURATEDCT 4096 + + +/** + * The number of transform operations + */ +#define TJ_NUMXOP 8 + +/** + * Transform operations for #tjTransform() + */ +enum TJXOP +{ + /** + * Do not transform the position of the image pixels + */ + TJXOP_NONE=0, + /** + * Flip (mirror) image horizontally. This transform is imperfect if there + * are any partial MCU blocks on the right edge (see #TJXOPT_PERFECT.) + */ + TJXOP_HFLIP, + /** + * Flip (mirror) image vertically. This transform is imperfect if there are + * any partial MCU blocks on the bottom edge (see #TJXOPT_PERFECT.) + */ + TJXOP_VFLIP, + /** + * Transpose image (flip/mirror along upper left to lower right axis.) This + * transform is always perfect. + */ + TJXOP_TRANSPOSE, + /** + * Transverse transpose image (flip/mirror along upper right to lower left + * axis.) This transform is imperfect if there are any partial MCU blocks in + * the image (see #TJXOPT_PERFECT.) + */ + TJXOP_TRANSVERSE, + /** + * Rotate image clockwise by 90 degrees. This transform is imperfect if + * there are any partial MCU blocks on the bottom edge (see + * #TJXOPT_PERFECT.) + */ + TJXOP_ROT90, + /** + * Rotate image 180 degrees. This transform is imperfect if there are any + * partial MCU blocks in the image (see #TJXOPT_PERFECT.) + */ + TJXOP_ROT180, + /** + * Rotate image counter-clockwise by 90 degrees. This transform is imperfect + * if there are any partial MCU blocks on the right edge (see + * #TJXOPT_PERFECT.) + */ + TJXOP_ROT270 +}; + + +/** + * This option will cause #tjTransform() to return an error if the transform is + * not perfect. Lossless transforms operate on MCU blocks, whose size depends + * on the level of chrominance subsampling used (see #tjMCUWidth + * and #tjMCUHeight.) If the image's width or height is not evenly divisible + * by the MCU block size, then there will be partial MCU blocks on the right + * and/or bottom edges. It is not possible to move these partial MCU blocks to + * the top or left of the image, so any transform that would require that is + * "imperfect." If this option is not specified, then any partial MCU blocks + * that cannot be transformed will be left in place, which will create + * odd-looking strips on the right or bottom edge of the image. + */ +#define TJXOPT_PERFECT 1 +/** + * This option will cause #tjTransform() to discard any partial MCU blocks that + * cannot be transformed. + */ +#define TJXOPT_TRIM 2 +/** + * This option will enable lossless cropping. See #tjTransform() for more + * information. + */ +#define TJXOPT_CROP 4 +/** + * This option will discard the color data in the input image and produce + * a grayscale output image. + */ +#define TJXOPT_GRAY 8 +/** + * This option will prevent #tjTransform() from outputting a JPEG image for + * this particular transform (this can be used in conjunction with a custom + * filter to capture the transformed DCT coefficients without transcoding + * them.) + */ +#define TJXOPT_NOOUTPUT 16 + + +/** + * Scaling factor + */ +typedef struct +{ + /** + * Numerator + */ + int num; + /** + * Denominator + */ + int denom; +} tjscalingfactor; + +/** + * Cropping region + */ +typedef struct +{ + /** + * The left boundary of the cropping region. This must be evenly divisible + * by the MCU block width (see #tjMCUWidth.) + */ + int x; + /** + * The upper boundary of the cropping region. This must be evenly divisible + * by the MCU block height (see #tjMCUHeight.) + */ + int y; + /** + * The width of the cropping region. Setting this to 0 is the equivalent of + * setting it to the width of the source JPEG image - x. + */ + int w; + /** + * The height of the cropping region. Setting this to 0 is the equivalent of + * setting it to the height of the source JPEG image - y. + */ + int h; +} tjregion; + +/** + * Lossless transform + */ +typedef struct tjtransform +{ + /** + * Cropping region + */ + tjregion r; + /** + * One of the @ref TJXOP "transform operations" + */ + int op; + /** + * The bitwise OR of one of more of the @ref TJXOPT_CROP "transform options" + */ + int options; + /** + * Arbitrary data that can be accessed within the body of the callback + * function + */ + void *data; + /** + * A callback function that can be used to modify the DCT coefficients + * after they are losslessly transformed but before they are transcoded to a + * new JPEG image. This allows for custom filters or other transformations + * to be applied in the frequency domain. + * + * @param coeffs pointer to an array of transformed DCT coefficients. (NOTE: + * this pointer is not guaranteed to be valid once the callback returns, so + * applications wishing to hand off the DCT coefficients to another function + * or library should make a copy of them within the body of the callback.) + * + * @param arrayRegion #tjregion structure containing the width and height of + * the array pointed to by <tt>coeffs</tt> as well as its offset relative to + * the component plane. TurboJPEG implementations may choose to split each + * component plane into multiple DCT coefficient arrays and call the callback + * function once for each array. + * + * @param planeRegion #tjregion structure containing the width and height of + * the component plane to which <tt>coeffs</tt> belongs + * + * @param componentID ID number of the component plane to which + * <tt>coeffs</tt> belongs (Y, Cb, and Cr have, respectively, ID's of 0, 1, + * and 2 in typical JPEG images.) + * + * @param transformID ID number of the transformed image to which + * <tt>coeffs</tt> belongs. This is the same as the index of the transform + * in the <tt>transforms</tt> array that was passed to #tjTransform(). + * + * @param transform a pointer to a #tjtransform structure that specifies the + * parameters and/or cropping region for this transform + * + * @return 0 if the callback was successful, or -1 if an error occurred. + */ + int (*customFilter)(short *coeffs, tjregion arrayRegion, + tjregion planeRegion, int componentIndex, int transformIndex, + struct tjtransform *transform); +} tjtransform; + +/** + * TurboJPEG instance handle + */ +typedef void* tjhandle; + + +/** + * Pad the given width to the nearest 32-bit boundary + */ +#define TJPAD(width) (((width)+3)&(~3)) + +/** + * Compute the scaled value of <tt>dimension</tt> using the given scaling + * factor. This macro performs the integer equivalent of <tt>ceil(dimension * + * scalingFactor)</tt>. + */ +#define TJSCALED(dimension, scalingFactor) ((dimension * scalingFactor.num \ + + scalingFactor.denom - 1) / scalingFactor.denom) + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Create a TurboJPEG compressor instance. + * + * @return a handle to the newly-created instance, or NULL if an error + * occurred (see #tjGetErrorStr().) + */ +DLLEXPORT tjhandle DLLCALL tjInitCompress(void); + + +/** + * Compress an RGB, grayscale, or CMYK image into a JPEG image. + * + * @param handle a handle to a TurboJPEG compressor or transformer instance + * + * @param srcBuf pointer to an image buffer containing RGB, grayscale, or + * CMYK pixels to be compressed + * + * @param width width (in pixels) of the source image + * + * @param pitch bytes per line in the source image. Normally, this should be + * <tt>width * #tjPixelSize[pixelFormat]</tt> if the image is unpadded, or + * <tt>#TJPAD(width * #tjPixelSize[pixelFormat])</tt> if each line of the image + * is padded to the nearest 32-bit boundary, as is the case for Windows + * bitmaps. You can also be clever and use this parameter to skip lines, etc. + * Setting this parameter to 0 is the equivalent of setting it to + * <tt>width * #tjPixelSize[pixelFormat]</tt>. + * + * @param height height (in pixels) of the source image + * + * @param pixelFormat pixel format of the source image (see @ref TJPF + * "Pixel formats".) + * + * @param jpegBuf address of a pointer to an image buffer that will receive the + * JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer + * to accommodate the size of the JPEG image. Thus, you can choose to: + * -# pre-allocate the JPEG buffer with an arbitrary size using #tjAlloc() and + * let TurboJPEG grow the buffer as needed, + * -# set <tt>*jpegBuf</tt> to NULL to tell TurboJPEG to allocate the buffer + * for you, or + * -# pre-allocate the buffer to a "worst case" size determined by calling + * #tjBufSize(). This should ensure that the buffer never has to be + * re-allocated (setting #TJFLAG_NOREALLOC guarantees this.) + * . + * If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your + * pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC, + * you should always check <tt>*jpegBuf</tt> upon return from this function, as + * it may have changed. + * + * @param jpegSize pointer to an unsigned long variable that holds the size of + * the JPEG image buffer. If <tt>*jpegBuf</tt> points to a pre-allocated + * buffer, then <tt>*jpegSize</tt> should be set to the size of the buffer. + * Upon return, <tt>*jpegSize</tt> will contain the size of the JPEG image (in + * bytes.) If <tt>*jpegBuf</tt> points to a JPEG image buffer that is being + * reused from a previous call to one of the JPEG compression functions, then + * <tt>*jpegSize</tt> is ignored. + * + * @param jpegSubsamp the level of chrominance subsampling to be used when + * generating the JPEG image (see @ref TJSAMP + * "Chrominance subsampling options".) + * + * @param jpegQual the image quality of the generated JPEG image (1 = worst, + * 100 = best) + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, + int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, + unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags); + + +/** + * Compress a YUV planar image into a JPEG image. + * + * @param handle a handle to a TurboJPEG compressor or transformer instance + * + * @param srcBuf pointer to an image buffer containing a YUV planar image to be + * compressed. The size of this buffer should match the value returned by + * #tjBufSizeYUV2() for the given image width, height, padding, and level of + * chrominance subsampling. The Y, U (Cb), and V (Cr) image planes should be + * stored sequentially in the source buffer (refer to @ref YUVnotes + * "YUV Image Format Notes".) + * + * @param width width (in pixels) of the source image. If the width is not an + * even multiple of the MCU block width (see #tjMCUWidth), then an intermediate + * buffer copy will be performed within TurboJPEG. + * + * @param pad the line padding used in the source image. For instance, if each + * line in each plane of the YUV image is padded to the nearest multiple of 4 + * bytes, then <tt>pad</tt> should be set to 4. + * + * @param height height (in pixels) of the source image. If the height is not + * an even multiple of the MCU block height (see #tjMCUHeight), then an + * intermediate buffer copy will be performed within TurboJPEG. + * + * @param subsamp the level of chrominance subsampling used in the source + * image (see @ref TJSAMP "Chrominance subsampling options".) + * + * @param jpegBuf address of a pointer to an image buffer that will receive the + * JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to + * accommodate the size of the JPEG image. Thus, you can choose to: + * -# pre-allocate the JPEG buffer with an arbitrary size using #tjAlloc() and + * let TurboJPEG grow the buffer as needed, + * -# set <tt>*jpegBuf</tt> to NULL to tell TurboJPEG to allocate the buffer + * for you, or + * -# pre-allocate the buffer to a "worst case" size determined by calling + * #tjBufSize(). This should ensure that the buffer never has to be + * re-allocated (setting #TJFLAG_NOREALLOC guarantees this.) + * . + * If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your + * pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC, + * you should always check <tt>*jpegBuf</tt> upon return from this function, as + * it may have changed. + * + * @param jpegSize pointer to an unsigned long variable that holds the size of + * the JPEG image buffer. If <tt>*jpegBuf</tt> points to a pre-allocated + * buffer, then <tt>*jpegSize</tt> should be set to the size of the buffer. + * Upon return, <tt>*jpegSize</tt> will contain the size of the JPEG image (in + * bytes.) If <tt>*jpegBuf</tt> points to a JPEG image buffer that is being + * reused from a previous call to one of the JPEG compression functions, then + * <tt>*jpegSize</tt> is ignored. + * + * @param jpegQual the image quality of the generated JPEG image (1 = worst, + * 100 = best) + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, unsigned char *srcBuf, + int width, int pad, int height, int subsamp, unsigned char **jpegBuf, + unsigned long *jpegSize, int jpegQual, int flags); + + +/** + * Compress a set of Y, U (Cb), and V (Cr) image planes into a JPEG image. + * + * @param handle a handle to a TurboJPEG compressor or transformer instance + * + * @param srcPlanes an array of pointers to Y, U (Cb), and V (Cr) image planes + * (or just a Y plane, if compressing a grayscale image) that contain a YUV + * image to be compressed. These planes can be contiguous or non-contiguous in + * memory. The size of each plane should match the value returned by + * #tjPlaneSizeYUV() for the given image width, height, strides, and level of + * chrominance subsampling. Refer to @ref YUVnotes "YUV Image Format Notes" + * for more details. + * + * @param width width (in pixels) of the source image. If the width is not an + * even multiple of the MCU block width (see #tjMCUWidth), then an intermediate + * buffer copy will be performed within TurboJPEG. + * + * @param strides an array of integers, each specifying the number of bytes per + * line in the corresponding plane of the YUV source image. Setting the stride + * for any plane to 0 is the same as setting it to the plane width (see + * @ref YUVnotes "YUV Image Format Notes".) If <tt>strides</tt> is NULL, then + * the strides for all planes will be set to their respective plane widths. + * You can adjust the strides in order to specify an arbitrary amount of line + * padding in each plane or to create a JPEG image from a subregion of a larger + * YUV planar image. + * + * @param height height (in pixels) of the source image. If the height is not + * an even multiple of the MCU block height (see #tjMCUHeight), then an + * intermediate buffer copy will be performed within TurboJPEG. + * + * @param subsamp the level of chrominance subsampling used in the source + * image (see @ref TJSAMP "Chrominance subsampling options".) + * + * @param jpegBuf address of a pointer to an image buffer that will receive the + * JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to + * accommodate the size of the JPEG image. Thus, you can choose to: + * -# pre-allocate the JPEG buffer with an arbitrary size using #tjAlloc() and + * let TurboJPEG grow the buffer as needed, + * -# set <tt>*jpegBuf</tt> to NULL to tell TurboJPEG to allocate the buffer + * for you, or + * -# pre-allocate the buffer to a "worst case" size determined by calling + * #tjBufSize(). This should ensure that the buffer never has to be + * re-allocated (setting #TJFLAG_NOREALLOC guarantees this.) + * . + * If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your + * pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC, + * you should always check <tt>*jpegBuf</tt> upon return from this function, as + * it may have changed. + * + * @param jpegSize pointer to an unsigned long variable that holds the size of + * the JPEG image buffer. If <tt>*jpegBuf</tt> points to a pre-allocated + * buffer, then <tt>*jpegSize</tt> should be set to the size of the buffer. + * Upon return, <tt>*jpegSize</tt> will contain the size of the JPEG image (in + * bytes.) If <tt>*jpegBuf</tt> points to a JPEG image buffer that is being + * reused from a previous call to one of the JPEG compression functions, then + * <tt>*jpegSize</tt> is ignored. + * + * @param jpegQual the image quality of the generated JPEG image (1 = worst, + * 100 = best) + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle, + unsigned char **srcPlanes, int width, int *strides, int height, int subsamp, + unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQual, int flags); + + +/** + * The maximum size of the buffer (in bytes) required to hold a JPEG image with + * the given parameters. The number of bytes returned by this function is + * larger than the size of the uncompressed source image. The reason for this + * is that the JPEG format uses 16-bit coefficients, and it is thus possible + * for a very high-quality JPEG image with very high-frequency content to + * expand rather than compress when converted to the JPEG format. Such images + * represent a very rare corner case, but since there is no way to predict the + * size of a JPEG image prior to compression, the corner case has to be + * handled. + * + * @param width width (in pixels) of the image + * + * @param height height (in pixels) of the image + * + * @param jpegSubsamp the level of chrominance subsampling to be used when + * generating the JPEG image (see @ref TJSAMP + * "Chrominance subsampling options".) + * + * @return the maximum size of the buffer (in bytes) required to hold the + * image, or -1 if the arguments are out of bounds. + */ +DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, + int jpegSubsamp); + + +/** + * The size of the buffer (in bytes) required to hold a YUV planar image with + * the given parameters. + * + * @param width width (in pixels) of the image + * + * @param pad the width of each line in each plane of the image is padded to + * the nearest multiple of this number of bytes (must be a power of 2.) + * + * @param height height (in pixels) of the image + * + * @param subsamp level of chrominance subsampling in the image (see + * @ref TJSAMP "Chrominance subsampling options".) + * + * @return the size of the buffer (in bytes) required to hold the image, or + * -1 if the arguments are out of bounds. + */ +DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height, + int subsamp); + + +/** + * The size of the buffer (in bytes) required to hold a YUV image plane with + * the given parameters. + * + * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) + * + * @param width width (in pixels) of the YUV image. NOTE: this is the width of + * the whole image, not the plane width. + * + * @param stride bytes per line in the image plane. Setting this to 0 is the + * equivalent of setting it to the plane width. + * + * @param height height (in pixels) of the YUV image. NOTE: this is the height + * of the whole image, not the plane height. + * + * @param subsamp level of chrominance subsampling in the image (see + * @ref TJSAMP "Chrominance subsampling options".) + * + * @return the size of the buffer (in bytes) required to hold the YUV image + * plane, or -1 if the arguments are out of bounds. + */ +DLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width, + int stride, int height, int subsamp); + + +/** + * The plane width of a YUV image plane with the given parameters. Refer to + * @ref YUVnotes "YUV Image Format Notes" for a description of plane width. + * + * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) + * + * @param width width (in pixels) of the YUV image + * + * @param subsamp level of chrominance subsampling in the image (see + * @ref TJSAMP "Chrominance subsampling options".) + * + * @return the plane width of a YUV image plane with the given parameters, or + * -1 if the arguments are out of bounds. + */ +DLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp); + + +/** + * The plane height of a YUV image plane with the given parameters. Refer to + * @ref YUVnotes "YUV Image Format Notes" for a description of plane height. + * + * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) + * + * @param height height (in pixels) of the YUV image + * + * @param subsamp level of chrominance subsampling in the image (see + * @ref TJSAMP "Chrominance subsampling options".) + * + * @return the plane height of a YUV image plane with the given parameters, or + * -1 if the arguments are out of bounds. + */ +DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp); + + +/** + * Encode an RGB or grayscale image into a YUV planar image. This function + * uses the accelerated color conversion routines in the underlying + * codec but does not execute any of the other steps in the JPEG compression + * process. + * + * @param handle a handle to a TurboJPEG compressor or transformer instance + * + * @param srcBuf pointer to an image buffer containing RGB or grayscale pixels + * to be encoded + * + * @param width width (in pixels) of the source image + * + * @param pitch bytes per line in the source image. Normally, this should be + * <tt>width * #tjPixelSize[pixelFormat]</tt> if the image is unpadded, or + * <tt>#TJPAD(width * #tjPixelSize[pixelFormat])</tt> if each line of the image + * is padded to the nearest 32-bit boundary, as is the case for Windows + * bitmaps. You can also be clever and use this parameter to skip lines, etc. + * Setting this parameter to 0 is the equivalent of setting it to + * <tt>width * #tjPixelSize[pixelFormat]</tt>. + * + * @param height height (in pixels) of the source image + * + * @param pixelFormat pixel format of the source image (see @ref TJPF + * "Pixel formats".) + * + * @param dstBuf pointer to an image buffer that will receive the YUV image. + * Use #tjBufSizeYUV2() to determine the appropriate size for this buffer based + * on the image width, height, padding, and level of chrominance subsampling. + * The Y, U (Cb), and V (Cr) image planes will be stored sequentially in the + * buffer (refer to @ref YUVnotes "YUV Image Format Notes".) + * + * @param pad the width of each line in each plane of the YUV image will be + * padded to the nearest multiple of this number of bytes (must be a power of + * 2.) To generate images suitable for X Video, <tt>pad</tt> should be set to + * 4. + * + * @param subsamp the level of chrominance subsampling to be used when + * generating the YUV image (see @ref TJSAMP + * "Chrominance subsampling options".) To generate images suitable for X + * Video, <tt>subsamp</tt> should be set to @ref TJSAMP_420. This produces an + * image compatible with the I420 (AKA "YUV420P") format. + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, + unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, + unsigned char *dstBuf, int pad, int subsamp, int flags); + + +/** + * Encode an RGB or grayscale image into separate Y, U (Cb), and V (Cr) image + * planes. This function uses the accelerated color conversion routines in the + * underlying codec but does not execute any of the other steps in the JPEG + * compression process. + * + * @param handle a handle to a TurboJPEG compressor or transformer instance + * + * @param srcBuf pointer to an image buffer containing RGB or grayscale pixels + * to be encoded + * + * @param width width (in pixels) of the source image + * + * @param pitch bytes per line in the source image. Normally, this should be + * <tt>width * #tjPixelSize[pixelFormat]</tt> if the image is unpadded, or + * <tt>#TJPAD(width * #tjPixelSize[pixelFormat])</tt> if each line of the image + * is padded to the nearest 32-bit boundary, as is the case for Windows + * bitmaps. You can also be clever and use this parameter to skip lines, etc. + * Setting this parameter to 0 is the equivalent of setting it to + * <tt>width * #tjPixelSize[pixelFormat]</tt>. + * + * @param height height (in pixels) of the source image + * + * @param pixelFormat pixel format of the source image (see @ref TJPF + * "Pixel formats".) + * + * @param dstPlanes an array of pointers to Y, U (Cb), and V (Cr) image planes + * (or just a Y plane, if generating a grayscale image) that will receive the + * encoded image. These planes can be contiguous or non-contiguous in memory. + * Use #tjPlaneSizeYUV() to determine the appropriate size for each plane based + * on the image width, height, strides, and level of chrominance subsampling. + * Refer to @ref YUVnotes "YUV Image Format Notes" for more details. + * + * @param strides an array of integers, each specifying the number of bytes per + * line in the corresponding plane of the output image. Setting the stride for + * any plane to 0 is the same as setting it to the plane width (see + * @ref YUVnotes "YUV Image Format Notes".) If <tt>strides</tt> is NULL, then + * the strides for all planes will be set to their respective plane widths. + * You can adjust the strides in order to add an arbitrary amount of line + * padding to each plane or to encode an RGB or grayscale image into a + * subregion of a larger YUV planar image. + * + * @param subsamp the level of chrominance subsampling to be used when + * generating the YUV image (see @ref TJSAMP + * "Chrominance subsampling options".) To generate images suitable for X + * Video, <tt>subsamp</tt> should be set to @ref TJSAMP_420. This produces an + * image compatible with the I420 (AKA "YUV420P") format. + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, + unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, + unsigned char **dstPlanes, int *strides, int subsamp, int flags); + + +/** + * Create a TurboJPEG decompressor instance. + * + * @return a handle to the newly-created instance, or NULL if an error + * occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT tjhandle DLLCALL tjInitDecompress(void); + + +/** + * Retrieve information about a JPEG image without decompressing it. + * + * @param handle a handle to a TurboJPEG decompressor or transformer instance + * + * @param jpegBuf pointer to a buffer containing a JPEG image + * + * @param jpegSize size of the JPEG image (in bytes) + * + * @param width pointer to an integer variable that will receive the width (in + * pixels) of the JPEG image + * + * @param height pointer to an integer variable that will receive the height + * (in pixels) of the JPEG image + * + * @param jpegSubsamp pointer to an integer variable that will receive the + * level of chrominance subsampling used when the JPEG image was compressed + * (see @ref TJSAMP "Chrominance subsampling options".) + * + * @param jpegColorspace pointer to an integer variable that will receive one + * of the JPEG colorspace constants, indicating the colorspace of the JPEG + * image (see @ref TJCS "JPEG colorspaces".) + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, + int *jpegSubsamp, int *jpegColorspace); + + +/** + * Returns a list of fractional scaling factors that the JPEG decompressor in + * this implementation of TurboJPEG supports. + * + * @param numscalingfactors pointer to an integer variable that will receive + * the number of elements in the list + * + * @return a pointer to a list of fractional scaling factors, or NULL if an + * error is encountered (see #tjGetErrorStr().) +*/ +DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors); + + +/** + * Decompress a JPEG image to an RGB, grayscale, or CMYK image. + * + * @param handle a handle to a TurboJPEG decompressor or transformer instance + * + * @param jpegBuf pointer to a buffer containing the JPEG image to decompress + * + * @param jpegSize size of the JPEG image (in bytes) + * + * @param dstBuf pointer to an image buffer that will receive the decompressed + * image. This buffer should normally be <tt>pitch * scaledHeight</tt> bytes + * in size, where <tt>scaledHeight</tt> can be determined by calling + * #TJSCALED() with the JPEG image height and one of the scaling factors + * returned by #tjGetScalingFactors(). The <tt>dstBuf</tt> pointer may also be + * used to decompress into a specific region of a larger buffer. + * + * @param width desired width (in pixels) of the destination image. If this is + * different than the width of the JPEG image being decompressed, then + * TurboJPEG will use scaling in the JPEG decompressor to generate the largest + * possible image that will fit within the desired width. If <tt>width</tt> is + * set to 0, then only the height will be considered when determining the + * scaled image size. + * + * @param pitch bytes per line in the destination image. Normally, this is + * <tt>scaledWidth * #tjPixelSize[pixelFormat]</tt> if the decompressed image + * is unpadded, else <tt>#TJPAD(scaledWidth * #tjPixelSize[pixelFormat])</tt> + * if each line of the decompressed image is padded to the nearest 32-bit + * boundary, as is the case for Windows bitmaps. (NOTE: <tt>scaledWidth</tt> + * can be determined by calling #TJSCALED() with the JPEG image width and one + * of the scaling factors returned by #tjGetScalingFactors().) You can also be + * clever and use the pitch parameter to skip lines, etc. Setting this + * parameter to 0 is the equivalent of setting it to + * <tt>scaledWidth * #tjPixelSize[pixelFormat]</tt>. + * + * @param height desired height (in pixels) of the destination image. If this + * is different than the height of the JPEG image being decompressed, then + * TurboJPEG will use scaling in the JPEG decompressor to generate the largest + * possible image that will fit within the desired height. If <tt>height</tt> + * is set to 0, then only the width will be considered when determining the + * scaled image size. + * + * @param pixelFormat pixel format of the destination image (see @ref + * TJPF "Pixel formats".) + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, + int width, int pitch, int height, int pixelFormat, int flags); + + +/** + * Decompress a JPEG image to a YUV planar image. This function performs JPEG + * decompression but leaves out the color conversion step, so a planar YUV + * image is generated instead of an RGB image. + * + * @param handle a handle to a TurboJPEG decompressor or transformer instance + * + * @param jpegBuf pointer to a buffer containing the JPEG image to decompress + * + * @param jpegSize size of the JPEG image (in bytes) + * + * @param dstBuf pointer to an image buffer that will receive the YUV image. + * Use #tjBufSizeYUV2() to determine the appropriate size for this buffer based + * on the image width, height, padding, and level of subsampling. The Y, + * U (Cb), and V (Cr) image planes will be stored sequentially in the buffer + * (refer to @ref YUVnotes "YUV Image Format Notes".) + * + * @param width desired width (in pixels) of the YUV image. If this is + * different than the width of the JPEG image being decompressed, then + * TurboJPEG will use scaling in the JPEG decompressor to generate the largest + * possible image that will fit within the desired width. If <tt>width</tt> is + * set to 0, then only the height will be considered when determining the + * scaled image size. If the scaled width is not an even multiple of the MCU + * block width (see #tjMCUWidth), then an intermediate buffer copy will be + * performed within TurboJPEG. + * + * @param pad the width of each line in each plane of the YUV image will be + * padded to the nearest multiple of this number of bytes (must be a power of + * 2.) To generate images suitable for X Video, <tt>pad</tt> should be set to + * 4. + * + * @param height desired height (in pixels) of the YUV image. If this is + * different than the height of the JPEG image being decompressed, then + * TurboJPEG will use scaling in the JPEG decompressor to generate the largest + * possible image that will fit within the desired height. If <tt>height</tt> + * is set to 0, then only the width will be considered when determining the + * scaled image size. If the scaled height is not an even multiple of the MCU + * block height (see #tjMCUHeight), then an intermediate buffer copy will be + * performed within TurboJPEG. + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, + int width, int pad, int height, int flags); + + +/** + * Decompress a JPEG image into separate Y, U (Cb), and V (Cr) image + * planes. This function performs JPEG decompression but leaves out the color + * conversion step, so a planar YUV image is generated instead of an RGB image. + * + * @param handle a handle to a TurboJPEG decompressor or transformer instance + * + * @param jpegBuf pointer to a buffer containing the JPEG image to decompress + * + * @param jpegSize size of the JPEG image (in bytes) + * + * @param dstPlanes an array of pointers to Y, U (Cb), and V (Cr) image planes + * (or just a Y plane, if decompressing a grayscale image) that will receive + * the YUV image. These planes can be contiguous or non-contiguous in memory. + * Use #tjPlaneSizeYUV() to determine the appropriate size for each plane based + * on the scaled image width, scaled image height, strides, and level of + * chrominance subsampling. Refer to @ref YUVnotes "YUV Image Format Notes" + * for more details. + * + * @param width desired width (in pixels) of the YUV image. If this is + * different than the width of the JPEG image being decompressed, then + * TurboJPEG will use scaling in the JPEG decompressor to generate the largest + * possible image that will fit within the desired width. If <tt>width</tt> is + * set to 0, then only the height will be considered when determining the + * scaled image size. If the scaled width is not an even multiple of the MCU + * block width (see #tjMCUWidth), then an intermediate buffer copy will be + * performed within TurboJPEG. + * + * @param strides an array of integers, each specifying the number of bytes per + * line in the corresponding plane of the output image. Setting the stride for + * any plane to 0 is the same as setting it to the scaled plane width (see + * @ref YUVnotes "YUV Image Format Notes".) If <tt>strides</tt> is NULL, then + * the strides for all planes will be set to their respective scaled plane + * widths. You can adjust the strides in order to add an arbitrary amount of + * line padding to each plane or to decompress the JPEG image into a subregion + * of a larger YUV planar image. + * + * @param height desired height (in pixels) of the YUV image. If this is + * different than the height of the JPEG image being decompressed, then + * TurboJPEG will use scaling in the JPEG decompressor to generate the largest + * possible image that will fit within the desired height. If <tt>height</tt> + * is set to 0, then only the width will be considered when determining the + * scaled image size. If the scaled height is not an even multiple of the MCU + * block height (see #tjMCUHeight), then an intermediate buffer copy will be + * performed within TurboJPEG. + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, unsigned char **dstPlanes, + int width, int *strides, int height, int flags); + + +/** + * Decode a YUV planar image into an RGB or grayscale image. This function + * uses the accelerated color conversion routines in the underlying + * codec but does not execute any of the other steps in the JPEG decompression + * process. + * + * @param handle a handle to a TurboJPEG decompressor or transformer instance + * + * @param srcBuf pointer to an image buffer containing a YUV planar image to be + * decoded. The size of this buffer should match the value returned by + * #tjBufSizeYUV2() for the given image width, height, padding, and level of + * chrominance subsampling. The Y, U (Cb), and V (Cr) image planes should be + * stored sequentially in the source buffer (refer to @ref YUVnotes + * "YUV Image Format Notes".) + * + * @param pad Use this parameter to specify that the width of each line in each + * plane of the YUV source image is padded to the nearest multiple of this + * number of bytes (must be a power of 2.) + * + * @param subsamp the level of chrominance subsampling used in the YUV source + * image (see @ref TJSAMP "Chrominance subsampling options".) + * + * @param dstBuf pointer to an image buffer that will receive the decoded + * image. This buffer should normally be <tt>pitch * height</tt> bytes in + * size, but the <tt>dstBuf</tt> pointer can also be used to decode into a + * specific region of a larger buffer. + * + * @param width width (in pixels) of the source and destination images + * + * @param pitch bytes per line in the destination image. Normally, this should + * be <tt>width * #tjPixelSize[pixelFormat]</tt> if the destination image is + * unpadded, or <tt>#TJPAD(width * #tjPixelSize[pixelFormat])</tt> if each line + * of the destination image should be padded to the nearest 32-bit boundary, as + * is the case for Windows bitmaps. You can also be clever and use the pitch + * parameter to skip lines, etc. Setting this parameter to 0 is the equivalent + * of setting it to <tt>width * #tjPixelSize[pixelFormat]</tt>. + * + * @param height height (in pixels) of the source and destination images + * + * @param pixelFormat pixel format of the destination image (see @ref TJPF + * "Pixel formats".) + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjDecodeYUV(tjhandle handle, unsigned char *srcBuf, + int pad, int subsamp, unsigned char *dstBuf, int width, int pitch, + int height, int pixelFormat, int flags); + + +/** + * Decode a set of Y, U (Cb), and V (Cr) image planes into an RGB or grayscale + * image. This function uses the accelerated color conversion routines in the + * underlying codec but does not execute any of the other steps in the JPEG + * decompression process. + * + * @param handle a handle to a TurboJPEG decompressor or transformer instance + * + * @param srcPlanes an array of pointers to Y, U (Cb), and V (Cr) image planes + * (or just a Y plane, if decoding a grayscale image) that contain a YUV image + * to be decoded. These planes can be contiguous or non-contiguous in memory. + * The size of each plane should match the value returned by #tjPlaneSizeYUV() + * for the given image width, height, strides, and level of chrominance + * subsampling. Refer to @ref YUVnotes "YUV Image Format Notes" for more + * details. + * + * @param strides an array of integers, each specifying the number of bytes per + * line in the corresponding plane of the YUV source image. Setting the stride + * for any plane to 0 is the same as setting it to the plane width (see + * @ref YUVnotes "YUV Image Format Notes".) If <tt>strides</tt> is NULL, then + * the strides for all planes will be set to their respective plane widths. + * You can adjust the strides in order to specify an arbitrary amount of line + * padding in each plane or to decode a subregion of a larger YUV planar image. + * + * @param subsamp the level of chrominance subsampling used in the YUV source + * image (see @ref TJSAMP "Chrominance subsampling options".) + * + * @param dstBuf pointer to an image buffer that will receive the decoded + * image. This buffer should normally be <tt>pitch * height</tt> bytes in + * size, but the <tt>dstBuf</tt> pointer can also be used to decode into a + * specific region of a larger buffer. + * + * @param width width (in pixels) of the source and destination images + * + * @param pitch bytes per line in the destination image. Normally, this should + * be <tt>width * #tjPixelSize[pixelFormat]</tt> if the destination image is + * unpadded, or <tt>#TJPAD(width * #tjPixelSize[pixelFormat])</tt> if each line + * of the destination image should be padded to the nearest 32-bit boundary, as + * is the case for Windows bitmaps. You can also be clever and use the pitch + * parameter to skip lines, etc. Setting this parameter to 0 is the equivalent + * of setting it to <tt>width * #tjPixelSize[pixelFormat]</tt>. + * + * @param height height (in pixels) of the source and destination images + * + * @param pixelFormat pixel format of the destination image (see @ref TJPF + * "Pixel formats".) + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, + unsigned char **srcPlanes, int *strides, int subsamp, unsigned char *dstBuf, + int width, int pitch, int height, int pixelFormat, int flags); + + +/** + * Create a new TurboJPEG transformer instance. + * + * @return a handle to the newly-created instance, or NULL if an error + * occurred (see #tjGetErrorStr().) + */ +DLLEXPORT tjhandle DLLCALL tjInitTransform(void); + + +/** + * Losslessly transform a JPEG image into another JPEG image. Lossless + * transforms work by moving the raw DCT coefficients from one JPEG image + * structure to another without altering the values of the coefficients. While + * this is typically faster than decompressing the image, transforming it, and + * re-compressing it, lossless transforms are not free. Each lossless + * transform requires reading and performing Huffman decoding on all of the + * coefficients in the source image, regardless of the size of the destination + * image. Thus, this function provides a means of generating multiple + * transformed images from the same source or applying multiple + * transformations simultaneously, in order to eliminate the need to read the + * source coefficients multiple times. + * + * @param handle a handle to a TurboJPEG transformer instance + * + * @param jpegBuf pointer to a buffer containing the JPEG source image to + * transform + * + * @param jpegSize size of the JPEG source image (in bytes) + * + * @param n the number of transformed JPEG images to generate + * + * @param dstBufs pointer to an array of n image buffers. <tt>dstBufs[i]</tt> + * will receive a JPEG image that has been transformed using the parameters in + * <tt>transforms[i]</tt>. TurboJPEG has the ability to reallocate the JPEG + * buffer to accommodate the size of the JPEG image. Thus, you can choose to: + * -# pre-allocate the JPEG buffer with an arbitrary size using #tjAlloc() and + * let TurboJPEG grow the buffer as needed, + * -# set <tt>dstBufs[i]</tt> to NULL to tell TurboJPEG to allocate the buffer + * for you, or + * -# pre-allocate the buffer to a "worst case" size determined by calling + * #tjBufSize() with the transformed or cropped width and height. This should + * ensure that the buffer never has to be re-allocated (setting + * #TJFLAG_NOREALLOC guarantees this.) + * . + * If you choose option 1, <tt>dstSizes[i]</tt> should be set to the size of + * your pre-allocated buffer. In any case, unless you have set + * #TJFLAG_NOREALLOC, you should always check <tt>dstBufs[i]</tt> upon return + * from this function, as it may have changed. + * + * @param dstSizes pointer to an array of n unsigned long variables that will + * receive the actual sizes (in bytes) of each transformed JPEG image. If + * <tt>dstBufs[i]</tt> points to a pre-allocated buffer, then + * <tt>dstSizes[i]</tt> should be set to the size of the buffer. Upon return, + * <tt>dstSizes[i]</tt> will contain the size of the JPEG image (in bytes.) + * + * @param transforms pointer to an array of n #tjtransform structures, each of + * which specifies the transform parameters and/or cropping region for the + * corresponding transformed output image. + * + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags" + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, int n, unsigned char **dstBufs, + unsigned long *dstSizes, tjtransform *transforms, int flags); + + +/** + * Destroy a TurboJPEG compressor, decompressor, or transformer instance. + * + * @param handle a handle to a TurboJPEG compressor, decompressor or + * transformer instance + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjDestroy(tjhandle handle); + + +/** + * Allocate an image buffer for use with TurboJPEG. You should always use + * this function to allocate the JPEG destination buffer(s) for #tjCompress2() + * and #tjTransform() unless you are disabling automatic buffer + * (re)allocation (by setting #TJFLAG_NOREALLOC.) + * + * @param bytes the number of bytes to allocate + * + * @return a pointer to a newly-allocated buffer with the specified number of + * bytes. + * + * @sa tjFree() + */ +DLLEXPORT unsigned char* DLLCALL tjAlloc(int bytes); + + +/** + * Free an image buffer previously allocated by TurboJPEG. You should always + * use this function to free JPEG destination buffer(s) that were automatically + * (re)allocated by #tjCompress2() or #tjTransform() or that were manually + * allocated using #tjAlloc(). + * + * @param buffer address of the buffer to free + * + * @sa tjAlloc() + */ +DLLEXPORT void DLLCALL tjFree(unsigned char *buffer); + + +/** + * Returns a descriptive error message explaining why the last command failed. + * + * @return a descriptive error message explaining why the last command failed. + */ +DLLEXPORT char* DLLCALL tjGetErrorStr(void); + + +/* Deprecated functions and macros */ +#define TJFLAG_FORCEMMX 8 +#define TJFLAG_FORCESSE 16 +#define TJFLAG_FORCESSE2 32 +#define TJFLAG_FORCESSE3 128 + + +/* Backward compatibility functions and macros (nothing to see here) */ +#define NUMSUBOPT TJ_NUMSAMP +#define TJ_444 TJSAMP_444 +#define TJ_422 TJSAMP_422 +#define TJ_420 TJSAMP_420 +#define TJ_411 TJSAMP_420 +#define TJ_GRAYSCALE TJSAMP_GRAY + +#define TJ_BGR 1 +#define TJ_BOTTOMUP TJFLAG_BOTTOMUP +#define TJ_FORCEMMX TJFLAG_FORCEMMX +#define TJ_FORCESSE TJFLAG_FORCESSE +#define TJ_FORCESSE2 TJFLAG_FORCESSE2 +#define TJ_ALPHAFIRST 64 +#define TJ_FORCESSE3 TJFLAG_FORCESSE3 +#define TJ_FASTUPSAMPLE TJFLAG_FASTUPSAMPLE +#define TJ_YUV 512 + +DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height); + +DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height, + int jpegSubsamp); + +DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, + int subsamp); + +DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, + int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, + unsigned long *compressedSize, int jpegSubsamp, int jpegQual, int flags); + +DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, + unsigned char *srcBuf, int width, int pitch, int height, int pixelSize, + unsigned char *dstBuf, int subsamp, int flags); + +DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, + unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, + unsigned char *dstBuf, int subsamp, int flags); + +DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height); + +DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, + int *jpegSubsamp); + +DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, + int width, int pitch, int height, int pixelSize, int flags); + +DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, + int flags); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/codec.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/codec.h new file mode 100644 index 00000000..999aa335 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/codec.h @@ -0,0 +1,243 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id: codec.h 17021 2010-03-24 09:29:41Z xiphmont $ + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include <ogg/ogg.h> + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independent from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, const char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + const char *tag, const char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, const char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +extern const char *vorbis_version_string(void); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_idheader(ogg_packet *op); +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/vorbisenc.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/vorbisenc.h new file mode 100644 index 00000000..02332b50 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/vorbisenc.h @@ -0,0 +1,436 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: vorbis encode-engine setup + last mod: $Id: vorbisenc.h 17021 2010-03-24 09:29:41Z xiphmont $ + + ********************************************************************/ + +/** \file + * Libvorbisenc is a convenient API for setting up an encoding + * environment using libvorbis. Libvorbisenc encapsulates the + * actions needed to set up the encoder properly. + */ + +#ifndef _OV_ENC_H_ +#define _OV_ENC_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "codec.h" + +/** + * This is the primary function within libvorbisenc for setting up managed + * bitrate modes. + * + * Before this function is called, the \ref vorbis_info + * struct should be initialized by using vorbis_info_init() from the libvorbis + * API. After encoding, vorbis_info_clear() should be called. + * + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set + * constraints for the encoded file. This function uses these settings to + * select the appropriate encoding mode and set it up. + * + * \param vi Pointer to an initialized \ref vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset. + * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset. + * \param min_bitrate Desired minimum bitrate. -1 indicates unset. + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success. + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request. + */ +extern int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +/** + * This function performs step-one of a three-step bitrate-managed encode + * setup. It functions similarly to the one-step setup performed by \ref + * vorbis_encode_init but allows an application to make further encode setup + * tweaks using \ref vorbis_encode_ctl before finally calling \ref + * vorbis_encode_setup_init to complete the setup process. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set + * constraints for the encoded file. This function uses these settings to + * select the appropriate encoding mode and set it up. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset. + * \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset. + * \param min_bitrate Desired minimum bitrate. -1 indicates unset. + * + * \return Zero for success, and negative for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request. + */ +extern int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +/** + * This function performs step-one of a three-step variable bitrate + * (quality-based) encode setup. It functions similarly to the one-step setup + * performed by \ref vorbis_encode_init_vbr() but allows an application to + * make further encode setup tweaks using \ref vorbis_encode_ctl() before + * finally calling \ref vorbis_encode_setup_init to complete the setup + * process. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using \ref vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param quality Desired quality level, currently from -0.1 to 1.0 (lo to hi). + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request. + */ +extern int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + + float quality + ); + +/** + * This is the primary function within libvorbisenc for setting up variable + * bitrate ("quality" based) modes. + * + * + * Before this function is called, the vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API. After + * encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized vorbis_info struct. + * \param channels The number of channels to be encoded. + * \param rate The sampling rate of the source audio. + * \param base_quality Desired quality level, currently from -0.1 to 1.0 (lo to hi). + * + * + * \return Zero for success, or a negative number for failure. + * + * \retval 0 Success + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * \retval OV_EINVAL Invalid setup request, eg, out of range argument. + * \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request. + */ +extern int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality + ); + +/** + * This function performs the last stage of three-step encoding setup, as + * described in the API overview under managed bitrate modes. + * + * Before this function is called, the \ref vorbis_info struct should be + * initialized by using vorbis_info_init() from the libvorbis API, one of + * \ref vorbis_encode_setup_managed() or \ref vorbis_encode_setup_vbr() called to + * initialize the high-level encoding setup, and \ref vorbis_encode_ctl() + * called if necessary to make encoding setup changes. + * vorbis_encode_setup_init() finalizes the highlevel encoding structure into + * a complete encoding setup after which the application may make no further + * setup changes. + * + * After encoding, vorbis_info_clear() should be called. + * + * \param vi Pointer to an initialized \ref vorbis_info struct. + * + * \return Zero for success, and negative values for failure. + * + * \retval 0 Success. + * \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption. + * + * \retval OV_EINVAL Attempt to use vorbis_encode_setup_init() without first + * calling one of vorbis_encode_setup_managed() or vorbis_encode_setup_vbr() to + * initialize the high-level encoding setup + * + */ +extern int vorbis_encode_setup_init(vorbis_info *vi); + +/** + * This function implements a generic interface to miscellaneous encoder + * settings similar to the classic UNIX 'ioctl()' system call. Applications + * may use vorbis_encode_ctl() to query or set bitrate management or quality + * mode details by using one of several \e request arguments detailed below. + * vorbis_encode_ctl() must be called after one of + * vorbis_encode_setup_managed() or vorbis_encode_setup_vbr(). When used + * to modify settings, \ref vorbis_encode_ctl() must be called before \ref + * vorbis_encode_setup_init(). + * + * \param vi Pointer to an initialized vorbis_info struct. + * + * \param number Specifies the desired action; See \ref encctlcodes "the list + * of available requests". + * + * \param arg void * pointing to a data structure matching the request + * argument. + * + * \retval 0 Success. Any further return information (such as the result of a + * query) is placed into the storage pointed to by *arg. + * + * \retval OV_EINVAL Invalid argument, or an attempt to modify a setting after + * calling vorbis_encode_setup_init(). + * + * \retval OV_EIMPL Unimplemented or unknown request + */ +extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg); + +/** + * \deprecated This is a deprecated interface. Please use vorbis_encode_ctl() + * with the \ref ovectl_ratemanage2_arg struct and \ref + * OV_ECTL_RATEMANAGE2_GET and \ref OV_ECTL_RATEMANAGE2_SET calls in new code. + * + * The \ref ovectl_ratemanage_arg structure is used with vorbis_encode_ctl() + * and the \ref OV_ECTL_RATEMANAGE_GET, \ref OV_ECTL_RATEMANAGE_SET, \ref + * OV_ECTL_RATEMANAGE_AVG, \ref OV_ECTL_RATEMANAGE_HARD calls in order to + * query and modify specifics of the encoder's bitrate management + * configuration. +*/ +struct ovectl_ratemanage_arg { + int management_active; /**< nonzero if bitrate management is active*/ +/** hard lower limit (in kilobits per second) below which the stream bitrate + will never be allowed for any given bitrate_hard_window seconds of time.*/ + long bitrate_hard_min; +/** hard upper limit (in kilobits per second) above which the stream bitrate + will never be allowed for any given bitrate_hard_window seconds of time.*/ + long bitrate_hard_max; +/** the window period (in seconds) used to regulate the hard bitrate minimum + and maximum*/ + double bitrate_hard_window; +/** soft lower limit (in kilobits per second) below which the average bitrate + tracker will start nudging the bitrate higher.*/ + long bitrate_av_lo; +/** soft upper limit (in kilobits per second) above which the average bitrate + tracker will start nudging the bitrate lower.*/ + long bitrate_av_hi; +/** the window period (in seconds) used to regulate the average bitrate + minimum and maximum.*/ + double bitrate_av_window; +/** Regulates the relative centering of the average and hard windows; in + libvorbis 1.0 and 1.0.1, the hard window regulation overlapped but + followed the average window regulation. In libvorbis 1.1 a bit-reservoir + interface replaces the old windowing interface; the older windowing + interface is simulated and this field has no effect.*/ + double bitrate_av_window_center; +}; + +/** + * \name struct ovectl_ratemanage2_arg + * + * The ovectl_ratemanage2_arg structure is used with vorbis_encode_ctl() and + * the OV_ECTL_RATEMANAGE2_GET and OV_ECTL_RATEMANAGE2_SET calls in order to + * query and modify specifics of the encoder's bitrate management + * configuration. + * +*/ +struct ovectl_ratemanage2_arg { + int management_active; /**< nonzero if bitrate management is active */ +/** Lower allowed bitrate limit in kilobits per second */ + long bitrate_limit_min_kbps; +/** Upper allowed bitrate limit in kilobits per second */ + long bitrate_limit_max_kbps; + long bitrate_limit_reservoir_bits; /**<Size of the bitrate reservoir in bits */ +/** Regulates the bitrate reservoir's preferred fill level in a range from 0.0 + * to 1.0; 0.0 tries to bank bits to buffer against future bitrate spikes, 1.0 + * buffers against future sudden drops in instantaneous bitrate. Default is + * 0.1 + */ + double bitrate_limit_reservoir_bias; +/** Average bitrate setting in kilobits per second */ + long bitrate_average_kbps; +/** Slew rate limit setting for average bitrate adjustment; sets the minimum + * time in seconds the bitrate tracker may swing from one extreme to the + * other when boosting or damping average bitrate. + */ + double bitrate_average_damping; +}; + + +/** + * \name vorbis_encode_ctl() codes + * + * \anchor encctlcodes + * + * These values are passed as the \c number parameter of vorbis_encode_ctl(). + * The type of the referent of that function's \c arg pointer depends on these + * codes. + */ +/*@{*/ + +/** + * Query the current encoder bitrate management setting. + * + *Argument: <tt>struct ovectl_ratemanage2_arg *</tt> + * + * Used to query the current encoder bitrate management setting. Also used to + * initialize fields of an ovectl_ratemanage2_arg structure for use with + * \ref OV_ECTL_RATEMANAGE2_SET. + */ +#define OV_ECTL_RATEMANAGE2_GET 0x14 + +/** + * Set the current encoder bitrate management settings. + * + * Argument: <tt>struct ovectl_ratemanage2_arg *</tt> + * + * Used to set the current encoder bitrate management settings to the values + * listed in the ovectl_ratemanage2_arg. Passing a NULL pointer will disable + * bitrate management. +*/ +#define OV_ECTL_RATEMANAGE2_SET 0x15 + +/** + * Returns the current encoder hard-lowpass setting (kHz) in the double + * pointed to by arg. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_LOWPASS_GET 0x20 + +/** + * Sets the encoder hard-lowpass to the value (kHz) pointed to by arg. Valid + * lowpass settings range from 2 to 99. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_LOWPASS_SET 0x21 + +/** + * Returns the current encoder impulse block setting in the double pointed + * to by arg. + * + * Argument: <tt>double *</tt> +*/ +#define OV_ECTL_IBLOCK_GET 0x30 + +/** + * Sets the impulse block bias to the the value pointed to by arg. + * + * Argument: <tt>double *</tt> + * + * Valid range is -15.0 to 0.0 [default]. A negative impulse block bias will + * direct to encoder to use more bits when incoding short blocks that contain + * strong impulses, thus improving the accuracy of impulse encoding. + */ +#define OV_ECTL_IBLOCK_SET 0x31 + +/** + * Returns the current encoder coupling setting in the int pointed + * to by arg. + * + * Argument: <tt>int *</tt> +*/ +#define OV_ECTL_COUPLING_GET 0x40 + +/** + * Enables/disables channel coupling in multichannel encoding according to arg. + * + * Argument: <tt>int *</tt> + * + * Zero disables channel coupling for multichannel inputs, nonzer enables + * channel coupling. Setting has no effect on monophonic encoding or + * multichannel counts that do not offer coupling. At present, coupling is + * available for stereo and 5.1 encoding. + */ +#define OV_ECTL_COUPLING_SET 0x41 + + /* deprecated rate management supported only for compatibility */ + +/** + * Old interface to querying bitrate management settings. + * + * Deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_GET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_GET 0x10 +/** + * Old interface to modifying bitrate management settings. + * + * deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_SET 0x11 +/** + * Old interface to setting average-bitrate encoding mode. + * + * Deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_AVG 0x12 +/** + * Old interface to setting bounded-bitrate encoding modes. + * + * deprecated after move to bit-reservoir style management in 1.1 rendered + * this interface partially obsolete. + * + * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead. + * + * Argument: <tt>struct ovectl_ratemanage_arg *</tt> + */ +#define OV_ECTL_RATEMANAGE_HARD 0x13 + +/*@}*/ + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/vorbisfile.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/vorbisfile.h new file mode 100644 index 00000000..9271331e --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/vorbis/vorbisfile.h @@ -0,0 +1,206 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $ + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include <stdio.h> +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#ifndef OV_EXCLUDE_STATIC_CALLBACKS + +/* a few sets of convenient callbacks, especially for use under + * Windows where ov_open_callbacks() should always be used instead of + * ov_open() to avoid problems with incompatible crt.o version linking + * issues. */ + +static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + +#ifdef __MINGW32__ + return fseeko64(f,off,whence); +#elif defined (_WIN32) + return _fseeki64(f,off,whence); +#else + return fseek(f,off,whence); +#endif +} + +/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as + * static data. That means that every file which includes this header + * will get its own copy of these structs whether it uses them or + * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS. + * These static symbols are essential on platforms such as Windows on + * which several different versions of stdio support may be linked to + * by different DLLs, and we need to be certain we know which one + * we're using (the same one as the main application). + */ + +static ov_callbacks OV_CALLBACKS_DEFAULT = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) NULL, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) fclose, + (long (*)(void *)) NULL +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) NULL, + (long (*)(void *)) NULL +}; + +#endif + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatibility; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_fopen(const char *path,OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + const char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + const char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream, + void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/zconf.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/zconf.h new file mode 100644 index 00000000..9ccbb0a6 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/zconf.h @@ -0,0 +1,513 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H +/* #undef Z_PREFIX */ +/* #undef Z_HAVE_UNISTD_H */ + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include <limits.h> +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include <sys/types.h> /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include <stdarg.h> /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include <stddef.h> /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/zlib.h b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/zlib.h new file mode 100644 index 00000000..3e0c7672 --- /dev/null +++ b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/include/zlib.h @@ -0,0 +1,1768 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.8, April 28th, 2013 + + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 8 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/FLAC.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/FLAC.lib new file mode 100644 index 00000000..259fd064 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/FLAC.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/dumb.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/dumb.lib new file mode 100644 index 00000000..316b2503 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/dumb.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/freetype.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/freetype.lib new file mode 100644 index 00000000..5843b10a Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/freetype.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/jpeg.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/jpeg.lib new file mode 100644 index 00000000..76b6d897 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/jpeg.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/libpng16.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/libpng16.lib new file mode 100644 index 00000000..67e76c78 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/libpng16.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/ogg.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/ogg.lib new file mode 100644 index 00000000..cd025c66 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/ogg.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/physfs.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/physfs.lib new file mode 100644 index 00000000..dd78a993 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/physfs.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/theoradec.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/theoradec.lib new file mode 100644 index 00000000..2fa46d41 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/theoradec.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/vorbis.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/vorbis.lib new file mode 100644 index 00000000..456c2171 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/vorbis.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/vorbisfile.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/vorbisfile.lib new file mode 100644 index 00000000..0cdecba1 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/vorbisfile.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/zlib.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/zlib.lib new file mode 100644 index 00000000..14828972 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/win32/v140/mt/zlib.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/FLAC.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/FLAC.lib new file mode 100644 index 00000000..06f47b58 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/FLAC.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/dumb.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/dumb.lib new file mode 100644 index 00000000..39962c7a Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/dumb.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/freetype.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/freetype.lib new file mode 100644 index 00000000..4bb81033 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/freetype.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/jpeg.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/jpeg.lib new file mode 100644 index 00000000..a577306b Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/jpeg.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/libpng16.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/libpng16.lib new file mode 100644 index 00000000..f67bc5be Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/libpng16.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/ogg.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/ogg.lib new file mode 100644 index 00000000..fc935d1c Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/ogg.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/physfs.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/physfs.lib new file mode 100644 index 00000000..3c362d85 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/physfs.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/theoradec.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/theoradec.lib new file mode 100644 index 00000000..d5da8fe2 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/theoradec.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/vorbis.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/vorbis.lib new file mode 100644 index 00000000..6f441c7d Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/vorbis.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/vorbisfile.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/vorbisfile.lib new file mode 100644 index 00000000..2e8bf7d8 Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/vorbisfile.lib differ diff --git a/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/zlib.lib b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/zlib.lib new file mode 100644 index 00000000..5af903ce Binary files /dev/null and b/VS_Proj/gpr-430-assignment2/packages/AllegroDeps.1.3.0.4/build/native/lib/x64/v140/mt/zlib.lib differ diff --git a/allegro/CHANGES-5.0.txt b/allegro/CHANGES-5.0.txt new file mode 100644 index 00000000..2b4ec6c0 --- /dev/null +++ b/allegro/CHANGES-5.0.txt @@ -0,0 +1,4698 @@ +Allegro changelog for 5.0.x series +Changes from 5.0.10 to 5.0.11 (January 2015) +Changes from 5.0.9 to 5.0.10 (June 2013) +Changes from 5.0.8 to 5.0.9 (February 2013) +Changes from 5.0.7 to 5.0.8 (November 2012) +Changes from 5.0.6 to 5.0.7 (June 2012) +Changes from 5.0.5 to 5.0.6 (March 2012) +Changes from 5.0.4 to 5.0.5 (November 2011) +Changes from 5.0.3 to 5.0.4 (August 2011) +Changes from 5.0.2.1 to 5.0.3 (May 2011) +Changes from 5.0.2 to 5.0.2.1 (April 2011) +Changes from 5.0.1 to 5.0.2 (April 2011) +Changes from 5.0.0 to 5.0.1 (March 2011) +Changes from 5.0.0 RC5 to 5.0.0 (February 2011) +Changes from 5.0.0 RC4 to 5.0.0 RC5 (February 2011) +Changes from 5.0.0 RC3 to 5.0.0 RC4 (December 2010) +Changes from 5.0.0 RC2 to 5.0.0 RC3 (December 2010) +Changes from 5.0.0 RC1 to 5.0.0 RC2 (December 2010) +Changes from 4.9.22 to 5.0.0 RC1 (November 2010) +Changes from 4.9.21 to 4.9.22 (September 2010) +Changes from 4.9.20 to 4.9.21 (July 2010) +Changes from 4.9.19 to 4.9.20 (May 2010) +Changes from 4.9.18 to 4.9.19 (April 2010) +Changes from 4.9.17 to 4.9.18 (March 2010) +Changes from 4.9.16 to 4.9.17 (February 2010) +Changes from 4.9.15.1 to 4.9.16 (November 2009) +Changes from 4.9.15 to 4.9.15.1 (October 2009) +Changes from 4.9.14 to 4.9.15 (October 2009) +Changes from 4.9.13 to 4.9.14 (September 2009) +Changes from 4.9.12 to 4.9.13 (August 2009) +Changes from 4.9.11 to 4.9.12 (July 2009) +Changes from 4.9.10.1 to 4.9.11 (June 2009) +Changes from 4.9.10 to 4.9.10.1 (May 2009) +Changes from 4.9.9.1 to 4.9.10 (May 2009) +Changes from 4.9.9 to 4.9.9.1 (March 2009) +Changes from 4.9.8 to 4.9.9 (March 2009) +Changes from 4.9.7.1 to 4.9.8 (February 2009) +Changes from 4.9.7 to 4.9.7.1 (December 2008) +Changes from 4.9.6 to 4.9.7 (December 2008) +Changes from 4.9.5 to 4.9.6 (November 2008) +Changes from 4.9.4 to 4.9.5 (October 2008) +Changes from 4.9.3 to 4.9.4 (September 2008) +Changes from 4.9.2 to 4.9.3 (April 2008) +Changes from 4.9.1 to 4.9.2 (November 2007) +Changes from 4.9.0 to 4.9.1 (March 2007) +Changes from 4.2 series to 4.9.0 (July 2006) +Allegro changelog for 5.0.x series +********************************** + +See ‘changes._tx’ for changes in earlier versions of Allegro. These +lists serve as summaries; the full histories are in the git repository. + +Changes from 5.0.10 to 5.0.11 (January 2015) +******************************************** + +The main developers this time were: SiegeLord and Peter Wang. + +Core: + + • Fix OSX backend on OSX 10.10 (lordnoriyuki). + +Audio addon: + + • Fix/avoid all sound examples freezing on OSX with the aqueue driver + (Elias Pschernig). + + • Fix a deadlock in Pulseaudio driver. + +Other: + + • Fix build warnings. + + • Improve documentation (syntax highlighting). + +Changes from 5.0.9 to 5.0.10 (June 2013) +**************************************** + +The main developers this time were: Trent Gamblin, Paul Suntsov, Peter +Wang. + +Core: + + • Register system interface even if no display driver available on + Windows. + +Displays: + + • Don’t crash in al_create_display if there is no display driver. + + • Don’t crash at shutdown if there is no display driver (Windows). + + • Don’t fail init if both D3D, GL drivers unavailable (Windows). + + • Run fullscreen toggle on main thread (OS X). + + • Destroy the backbuffer bitmap when destroying the display (OS X). + + • Switch to new NSTrackingArea API (OS X). + + • Check availability of fullscreen button on window frame at run-time + (OS X). + +Graphics: + + • Add ALLEGRO_SRC_COLOR, ALLEGRO_DEST_COLOR, + ALLEGRO_INVERSE_SRC_COLOR, ALLEGRO_INVERSE_DEST_COLOR blending + modes (initially by Jon Rafkind and Elias Pschernig). + + • Let al_destroy_bitmap implicitly untarget the bitmap on the calling + thread. + + • Use memory bitmap drawing when either bitmap is locked (OpenGL). + + • Add const qualifiers to glUniform*v() functions (Aaron Bolyard). + +Input: + + • al_set_mouse_xy on Windows resulted in the mouse getting set to the + wrong position in windowed modes. + + • Scale the user supplied mouse cursor if it’s too big (Windows). + + • Fix mouse warping on OS X. + + • Fix mouse warping in Linux evdev mouse driver. + +Audio addon: + + • pulseaudio: Use smaller buffer size by default, and make it + configurable. + + • pulseaudio: Clean up state transitions. + + • Fix looping in Ogg Vorbis stream (Todd Cope). + + • Enable the use of the unpatched DirectX SDK to build Allegro with + MinGW. + +Color addon: + + • Fix al_color_rgb_to_html blue component (Jeff Bernard). + +Font addons: + + • Make al_init_ttf_addon return true for subsequent calls. + +Primitives addon: + + • Disallow 3 component vectors for ALLEGRO_PRIM_TEX_COORD. + + • Check that the vertex declaration is valid before creating it. + + • Respect filter settings of textures in the D3D backend. + +Build system: + + • Do not install most internal header files. + + • Do not search for and link with unneeded X libraries. + +Examples: + + • ex_audio_timer: New example. + +Other: + + • Minor fixes. + + • Various documentation updates. + + • A lot of code refactoring. + +Changes from 5.0.8 to 5.0.9 (February 2013) +******************************************* + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Peter Wang. + +Core: + + • Clean up logging subsystem at shutdown (muhkuh). + + • Fix a problem with creating a display after Allegro is shut down + then re-initialised on X11. + + • Fix use of clobbered return value from setlocale() on X11. + + • Fix use of double math functions for float arguments (Nick Trout). + +Displays: + + • Fix al_set/get_window position on Windows so getting/setting to the + same position continuosly doesn’t move the window. (Michael + Swiger) + + • Add al_set_display_icons (plural). Implemented on X11 and Windows. + + • Made al_get_display_mode return the closest thing to a pixel format + possible with the WGL driver (tobing). + + • Move WGL context destruction out of the message pump thread and + into the user/main thread. + + • Allow command-tab to work in fullscreen window mode on OS X. + +Graphics: + + • Avoid null pointer dereference when setting a target bitmap after + its video_texture has already been released (D3D). + + • Make d3d_lock_region fail immediately if _al_d3d_sync_bitmap + failed, likely because the device was lost. + + • Set device_lost flag immediately when d3d_display_thread_proc finds + the device is lost. + + • Sync bitmaps before resizing display to prevent changes being lost + after the resize (D3D). + + • Revert a faulty FBO rebinding optimisation in al_set_target_bitmap. + + • Fix OpenGL extensions being completely ignored on OS X. + + • Support stencil buffer on iOS. + +Input: + + • Partially fix mouse buttons “sticking” on Mac, e.g. holding the + mouse and toggling fullscreen window. + +Filesystem: + + • Keep absolute path in ALLEGRO_FS_ENTRYs so that later changes to + the working directory do not affect the interpretation of the path. + + • Set ALLEGRO_FILEMODE_HIDDEN properly on Unix. + + • Make sure stat mode bits are cleared in default implementation of + al_update_fs_entry. + + • Support Unicode paths on Windows. + + • Change description of al_get_fs_entry_name about not returning + absolute path if created from relative path; no longer true for + either the default or Physfs implementations. + +Audio addons: + + • Shut down threads properly when when destroying FLAC and modaudio + streams. + + • Fix PulseAudio driver trying to connect to a non-existent server + forever. + +Image I/O addon: + + • Fixed loading interlaced .png files with libpng. + + • Use Allegro built-in loaders in preference to OS X loaders for + BMP/TGA/PCX. The OS X TGA loader doesn’t support alpha and this is + also more consistent. + + • Restored ability of the native OSX image loader to load grayscale + pictures. + +Native dialog addon: + + • Add al_init_native_dialog_addon and + al_shutdown_native_dialog_addon. + +Build system: + + • Rename allegro*-5.0.pc files to allegro*-5.pc. The old names are + deprecated but retained on the 5.0 branch for backwards + compatibility. + + • Only generate and install pkg-config files for libraries that we + build. + + • Install iPhone internals headers (Nick Trout). + +Examples: + + • ex_icon2: New example. + + • speed: Use builtin font. + +Other: + + • Documentation updates. + + • A lot of code refactoring. + +Changes from 5.0.7 to 5.0.8 (November 2012) +******************************************* + +The main developers this time were: Dennis Busch, Trent Gamblin, Elias +Pschernig, Paul Suntsov, Peter Wang. + +Core: + + • Added alternate spelling: ALLEGRO_ALIGN_CENTER. + +Displays: + + • Rewrite D3D display format listing code, which was broken. This + should re-enable multi-sampling and fix ex_depth_mask being slow + with D3D. + + • Fixed a case where changing fullscreen mode in D3D via + al_resize_display caused a crash and loss of loaded bitmaps + information. + + • Fixed a case where changing fullscreen mode in OpenGL (on Windows) + via al_resize_display cause nothing to be rendered after the mode + change. + + • Fix crashes when resizing a WGL fullscreen window. + + • Fixed missing/incorrect resize events under Windows. + + • Fix al_set_new_display_adapter on OS X. + + • Fix use of invalidated pointers in D3D driver when the first format + fails. + + • Fix bug where setting the mouse cursor had no effect when the mouse + was captured (mouse button held down). + + • Fix windows not having a minimise button when set to windowed state + from fullscreen window state. + + • Respect ALLEGRO_FRAMELESS flag properly when toggling from + fullscreen window state to windowed state (Windows). + + • Don’t generate DISPLAY_LOST events when resizing a fullscreen + display. + + • Scale window icon to sizes returned by GetSystemMetrics (Windows). + + • Fixed ALLEGRO_FULLSCREEN_WINDOW under OS X. + + • Added al_osx_get_window function (Dennis Gooden). + +Graphics: + + • al_draw_pixel was crashing when drawn on sub-bitmaps on OpenGL. + + • Fix a potential crash when drawing the screen to a bitmap with D3D. + + • Avoid null pointer dereference when setting a target bitmap after + its video_texture has already been released (D3D). + + • Lock bitmap to prevent slowness when creating a cursor from a + non-memory bitmap on Windows. + + • Conditionally lock bitmap when creating cursor on X11 (previously + it did so even if already locked). + + • Don’t use NSOpenGLPFAAccelerated unnecessarily (OS X). + +Input: + + • Fix incorrect keyboard modifier flags after leaving and re-entering + a window (Windows). + + • Fixed a bug with mouse enter/leave events for resized windows under + OSX (Dennis Gooden). + + • Temporary fix for delay after mouse warp on OS X. + +File I/O: + + • Fix al_fputc on big-endian. Reported by Andreas Rönnquist and + Tobias Hansen. + + • Make al_fputc return value like fputc when out of range. + + • Fix al_read_directory crash on 64-bit Windows (simast). + +Image addon: + + • Don’t include native image loader source files in builds with the + native image loaders disabled (OSX, iOS). + + • Added a missing autorelease-pool to the OSX bitmap saving function + (sleepywind). + + • Fix OSX native image loader for loading not-premultiplied RGB data. + Previously the data was “de-multiplied”, with possibly all + information lost. + + • Fix OSX native image loader for loading bitmaps without an alpha + channel. They appeared completely black previously. + +Font addons: + + • Add builtin font creation function. + + • Added ALLEGRO_ALIGN_INTEGER text drawing flag (Todd Cope). + + • Made TTF addon include padding on the top and left edges of pages + (Todd Cope). + +Audio addon: + + • Use programmatically generated interpolators. They cover an + additional case which was missed and should be slightly more + efficient. + + • Support linear interpolation for 16-bit mixers. + + • Add cubic interpolation for mixers (off by default). + + • Fix potential deadlock in stop_voice for OpenAL. + + • Fix potential deadlock in stop_voice for DirectSound. + + • Improve buffer filling behaviour for DirectSound, reducing pops and + crackles significantly on slower machines. + + • Increase default buffer size for DirectSound to 8192 samples. + + • Fix setting the speed of an audio stream after it was attached to + the mixer. + +Native dialogs addon: + + • Do not unload of rich edit module when closing one text log window + while another exists. Reported by URB753. + + • Use default colours for Windows text log implementation, avoiding + problems when the previous custom colours failed, leading to black + text on a nearly black background. + +Build system: + + • Install pkg-config files when cross-compiling on Unix. + +Examples: + + • ex_synth: Add button to save waveform to a file. + + • ex_multisample: Demonstrate using moving bitmaps. + + • speed: Avoid poor performance due to needless redraws. + + • Renamed a5teroids to Cosmic Protector + +Other: + + • Many minor bug fixes. + + • Various documentation updates. + +Changes from 5.0.6 to 5.0.7 (June 2012) +*************************************** + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Peter Wang. + +Core: + + • Fix ALLEGRO_STATIC_ASSERT collisions from different files included + in the same translation unit. Reported by tobing. + + • Make al_ref_cstr, al_ref_ustr and al_ref_buffer return const + ALLEGRO_USTR_ instead of just an ALLEGRO_USTR_ (Paul Suntsov). + + • Make al_ustr_empty_string const correct. + + • Fix many memory leak/warnings on MacOS X (Pär Arvidsson). + + • Fix typo preventing get_executable_name from using System V procfs + correctly. Reported by Max Savenkov. + +Displays: + + • Add ALLEGRO_FRAMELESS as a preferred synonym for the confusing + ALLEGRO_NOFRAME flag. + + • Rename al_toggle_display_flag to al_set_display_flag, retaining the + older name for compatibility. + + • Set WM_NAME for some window managers (X11). + +Graphics: + + • Force al_create_bitmap to not create oversized bitmaps, to mitigate + integer overflow problems. + + • Removed initial black frame on all Allegro programs. + +OpenGL: + + • Texture should be ‘complete’ (min/mag and wrap set) before + glTexImage2D. + + • Fixed a bug in al_unlock_bitmap where the pixel alignment + mistakenly was used as row length. + + • Fixed typo in names of some OpenGL extension functions. + + • Display list of OpenGL extensions in allegro.log also for OpenGL + 3.0. + +Direct3D: + + • Fixed a bug in the D3D driver where separate alpha blending was + being tested for when it shouldn’t have been (Max Savenkov). + +Input: + + • Monitor /dev/input instead of /dev on Linux for hotplugging + joysticks (Jon Rafkind). + + • Do not permanently change the locale for the X11 keyboard driver. + Set LC_CTYPE only, not LC_ALL. + +Audio addon: + + • Fix desychronization due to inaccurate sample positions when + resampling. Thanks to _Bnu for discovering the issue and Paul + Suntsov for devising the correct solution. + + • Fix linear interpolation across audio stream buffer fragments. + + • Fix two minor memory leaks in the PulseAudio driver. + +Image I/O addon: + + • Improve compatibility of BMP loader. In particular, support + bitmaps with V2-V5 headers and certain alpha bit masks. + + • Fix TGA loader using more memory than necessary. Reported by Max + Savenkov. + +Font addon: + + • Use user set pixel format for fonts. + +Native dialogs addon: + + • Clear mouse state after dialogs or else it gets messed up (OSX). + + • Fix some warnings in gtk_dialog.c. + + • Wrap use of NSAlert so it can be run on the main thread with return + value. + +Examples: + + • Add ex_resample_test. + + • ex_audio_props: Add bidir button. + + • ex_joystick_events: Support hotplugging and fix display of 3-axis + sticks. + + • Add test_driver –no-display flag. (Tobias Hansen) + +Other: + + • Various documentation updates. + + • Other minor bug fixes. + + • Fix whatis entries of man pages. (Tobias Hansen) + +Changes from 5.0.5 to 5.0.6 (March 2012) +**************************************** + +The main developers this time were: Trent Gamblin, Matthew Leverton, +Elias Pschernig, Paul Suntsov, Peter Wang. + +Core: + + • Added al_register_assert_handler. + +Graphics: + + • Added al_draw_tinted_scaled_rotated_bitmap_region. + + • Added al_reset_clipping_rectangle convenience function. + + • Added al_get_parent_bitmap. + + • Fixed a bug in the OpenGL driver when drawing the backbuffer + outside the clipping rectangle of the target bitmap. + + • Make blitting from backbuffer work when using multisampling on + Windows/D3D. + +Displays: + + • Set ALLEGRO_MINIMIZED display flag on Windows (Zac Evans). + + • Don’t generate bogus resize events after restoring minimised window + on Windows. + + • Fixed bug on Windows where two SWITCH_IN events were fired when + window was minimized/restored (Michael Swiger). + + • Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic under + Windows as well as a bug where repeatedly setting the flag to on + would make the window grow bigger and bigger (Michael Swiger). + + • Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic in + X11. + + • Prevent a deadlock during display creation on X. + + • Fallback to the ‘old’ visual selection method on X instead of + crashing if the ‘new’ visual selection doesn’t work. + +Input: + + • Use the same logic in set_mouse_xy for FULLSCREEN_WINDOW as was + used for FULLSCREEN. (Max OS X) + +Filesystem: + + • Added al_fopen_slice. + + • Added al_set_exe_name which allows overriding Allegro’s idea of the + path to the current executable. + + • Make al_get_standard_path(ALLEGRO_TEMP_PATH) treat the value of + TMPDIR et al. as a directory name even without a trailing slash. + (Unix) + + • Make stdio al_fopen implementation set proper errno on failure. + +Audio addons: + + • Add mixer gain property and functions. + + • Improve code to check that DLL symbols are loaded in the acodec + addon. The old method was hacky and broke under -O2 using GCC + 4.6.1. + +Image I/O addon: + + • Improved accuracy of un-alpha-premultiplying in the native OSX + bitmap loader. + +Primitives addon: + + • Added al_draw_filled_pieslice and al_draw_pieslice. + + • Added al_draw_elliptical_arc. + +TTF addon: + + • Added al_load_ttf_font_stretch functions (tobing). + + • Added ALLEGRO_TTF_NO_AUTOHINT font loading flag to disable the Auto + Hinter which is enabled by default in newer version of FreeType + (Michał Cichoń). + + • Clear locked region so pixel borders aren’t random garbage that can + be seen sometimes with linear filtering on. + + • Unlock glyph cache page at end of text_length and + get_text_dimensions (jmasterx). + +Examples: + + • Added new examples: ex_audio_chain, ex_display_events, + ex_file_slice. + + • ex_ogre3d: Make it work under Windows (AMCerasoli). + + • a5teroids: Support gamepads that report small non-zero values for + sticks that are at rest. + +Other: + + • Added index to HTML version of the reference manual (Jon Rafkind). + + • Various documentation updates. + + • Other minor bug fixes. + +Changes from 5.0.4 to 5.0.5 (November 2011) +******************************************* + +The main developers this time were: Elias Pschernig and Trent Gamblin. + +Graphics: + + • Fixed several instances of windows being positioned wrong on + Windows: regular windows, WGL FULLSCREEN_WINDOW, and + ALLEGRO_NOFRAME windows. + + • Don’t re-bind the FBO in al_set_target_bitmap if the new target + bitmap shares the parent bitmap with the new target bitmap (Paul + Suntsov). + + • Zero out fake refresh rate information from the nvidia proprietary + driver on X11 (Peter Wang). + + • Implemented the ALLEGRO_FULLSCREEN_WINDOW flag for iOS. + +Input: + + • Make al_set_mouse_xy work in fullscreen on Windows. + + • Fixed a race condition in al_init_joystick. + + • Fixed problem on OS X where having two identical gamepads attached + would cause joystick initialization to hang (Thanks to Todd Cope + for pointing it out.) + + • Fixed iphone joystick events (it assumed a call to al_get_joystick + but that’s not required when using events). + +TTF fonts: + + • Save new bitmap flags and bitmap format at time of loading font and + use them when creating pages. + +Primitives addon: + + • Very thin arcs/pieslices were not drawn due to an overzealous check + (Paul Suntsov). + +Native dialogs addon: + + • Implemented al_show_native_message_box for iOS. + +Other: + + • Use .../Library/Application Support for ALLEGRO_USER_SETTINGS_PATH + and ALLEGRO_USER_DATA_PATH on iOS. + + • Listen for applicationDidBecomeActive and + applicationWillResignActive instead of + applicationWillEnterForeground and applicationDidEnterBackground on + iOS. This makes all of the common situations where you want to + pause your game work, such as the lock button. + + • Fix some memory leaks on iOS. + +Documentation: + + • Various documentation updates. + + • Generate multiple copies of a man page for all the API entries that + it documents. + +Changes from 5.0.3 to 5.0.4 (August 2011) +***************************************** + +The main developers this time were: Trent Gamblin, Matthew Leverton, +Elias Pschernig, Jon Rafkind, Paul Suntsov, Peter Wang and torhu. + +Core: + + • Restore searching of directories on PATH for DLLs to load on + Windows. + + • Fix crash on shutdown in headless Unix environment (no X11 + display). + + • Change all instances of al_malloc + memset(0) to al_calloc. + +Graphics: + + • Save memory in OpenGL case by freeing bitmap memory after uploading + a texture. Use a temporary buffer when converting lock buffer back + to native texture format. + + • Don’t release or refresh memory or sub-bitmaps when D3D device gets + lost/found. + + • Do not set D3D sub bitmaps to modified when first creating them. + This can cause major slowdowns when creating a lot of sub-bitmaps + and is likely responsible for slow font performance/startup when + using D3D. + + • Fix incorrect number of display formats in D3D (tobing). + + • Honor ALLEGRO_VSYNC in the WGL driver. + + • Make titlebar icons the right size on Windows. + + • Fix typo causing weird results of al_get_monitor_info on X. + + • Don’t setup FBO for a sub-bitmap whose parent is locked. + + • Specialise ADD/ONE/INVERSE_ALPHA blend mode software scanline + drawers. + + • Toggle ALLEGRO_VIDEO_BITMAP flag off when creating a memory bitmap + (both bits were previously on). + + • Add null bitmap assertion to al_clone_bitmap. + +Input: + + • New system for mapping extended keys in Windows keyboard driver. + Mainly for getting the same keycode for numpad keys independently + of the state of Num Lock. + + • More reliable updating of the toggle modifiers in Windows keyboard + driver (Num Lock, Caps Lock, and Scroll Lock). + +Timers: + + • Fix race conditions when starting timers from different threads. + +Audio addons: + + • Don’t mix into a global temporary sample buffer, causing noise when + two separate mixers are trying to run in parallel. + + • Make it possible to start/stop an audio stream which is attached to + a voice. + + • ALSA voices could not be resumed after being stopped, because the + update threads quit as soon as a voice is stopped. + + • OpenAL backend did not handle the case where _al_voice_update + returns less than a full buffer. + + • Attempt to load FLAC and Vorbis DLLs only once to avoid Windows + popping up too many error windows. + +Native dialogs addon: + + • al_show_native_messagebox() on Windows: add UTF-8 support; show + heading; show information icon by default. + +TTF addon: + + • Reduce memory usage. + + • Don’t make multiple passes over strings when computing text + dimensions. + +Build system: + + • Make sure static builds on Windows never use DLL_TLS (Zac Evans). + + • Made compilation possible with different combinations of Xinerama, + XF86VidMode, or Randr being present. + + • cmake: Use find_path HINTS instead of PATHS in our DirectX SDK + scripts. + + • cmake: Search for D3DX9 once instead of multiple times (John-Kim + Murphy). + + • cmake: Find FLAC/Ogg/Vorbis libraries under the names generated by + the official MSVC project files. + + • Include zlib.h explicitly for libpng 1.5. + +Examples: + + • Add multisampling to SPEED example. Change examples to use + ALLEGRO_SUGGEST for multisampling. + + • Include the font for speed.app under OSX within the bundle so it + can be run by double clicking. + + • Use default blending/pre-multiplied alpha in ex_blend2. + +Other: + + • Various documentation updates. + + • Fix minor memory leaks. + +Bindings: + + • Better way to make the Python wrapper work with both Python 2 and + 3. + + • Include Windows-specific functions in the Python wrapper. + +Changes from 5.0.2.1 to 5.0.3 (May 2011) +**************************************** + +Input: + + • Fixed keyboard repeat for extended keys on Windows. Added + ALLEGRO_KEY_MENU. (torhu) + + • Make Delete key in Windows send KEY_CHAR event with unichar code + 127 (Peter Wang). + +Filesystem: + + • al_remove_filename returned false even if successful (reported by + xpolife). + +Graphics: + + • On OpenGL ES 1.1, glReadPixels can only read 4 byte pixels (Trent + Gamblin). + +Font addon: + + • Fix a small memory leak when unregistering a handler with + al_register_font_loader (Trent Gamblin). + +Primitives addon: + + • Fix assertion failures when drawing al_draw_ellipse, al_draw_arc, + al_draw_rounded_rectangle, al_draw_filled_rounded_rectangle at very + small scales (reported by Carl Olsson). + +Native dialogs addon: + + • gtk: Fix truncated string if the final button contained a non-ASCII + character (Peter Wang). + +Other: + + • Minor build fixes and documentation updates. + +Changes from 5.0.2 to 5.0.2.1 (April 2011) +****************************************** + + • Fix regression on Windows where the keyboard state was not updated + unless the keyboard event source is registered to an event queue. + +Changes from 5.0.1 to 5.0.2 (April 2011) +**************************************** + +Input: + + • Fix inverted mouse wheel on X11. + + • Make unicode field in KEY_CHAR events zero for Fn, arrow keys, etc. + for OS X (jmasterx, Peter Hull). + + • Support ALLEGRO_KEY_PAD_ENTER and detect left/right Alt and Ctrl + keys independently on Windows (torhu, Matthew Leverton). + +Changes from 5.0.0 to 5.0.1 (March 2011) +**************************************** + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Peter Wang. Other contributions noted in-line. + +Graphics: + + • Automatically destroy framebuffer objects (FBOs) created for + non-memory bitmaps after a while. This solves the problem of + running out of resources if you set many different target bitmaps. + + • Make al_get_opengl_fbo attempt to create an FBO if one doesn’t + exist. + + • Avoid very small textures in Direct3D. + + • Do not sync from memory when first creating/uploading a bitmap + (D3D). + + • Try to fix the problem of the taskbar appearing above fullscreen + windows on Windows. + + • Center the window after toggling fullscreen on Windows. + +Input: + + • Support 4-way mouse-wheel and up to 32 mouse buttons in X11. + +Audio addons: + + • Avoid buffer overrun while reading from vorbis files. + + • Added optional support for Tremor in place of libvorbis on any + platform. + + • Do not prefer DirectSound with OpenAL. This can cause problems and + also will override user config. + + • Play silence where needed in DirectSound driver. + +TTF addon: + + • Do not hold bitmap drawing when changing target bitmap, which is + invalid and caused transformations to be misapplied. + + • Remove FBO for a cache bitmap once we are no longer adding glyphs + to it. + +Build system: + + • Force “default” visibility of _al_mangled_main on OS X, otherwise + the dynamic linker cannot find the symbol if building with XCode4 + (Owen Anderson and Peter Hull). + + • Generated pkg-config files should take into account LIB_SUFFIX + variable (Cristian Morales Vega). + + • Update allegro_font pkg-config file to not require + allegro_primitives. + +Documentation: + + • Various documentation updates. + + • Add copy of DejaVu font licence. + +Bindings: + + • Add allegro_main addon to the Python wrapper. Make the wrapper + work with Python 3, which has a different string representation. + Add parameter type checking for custom types. + +Changes from 5.0.0 RC5 to 5.0.0 (February 2011) +*********************************************** + +Color addon: + + • Use colour names from CSS. This is the same as the previous list + but with all grey/gray alternatives. + +Documentation: + + • Minor documentation updates. + +Changes from 5.0.0 RC4 to 5.0.0 RC5 (February 2011) +*************************************************** + +The main developers this time were: Thomas Fjellstrom, Trent Gamblin, +Peter Hull, Matthew Leverton and Peter Wang. Other contributions noted +in-line. + +System: + + • Load allegro5.cfg from the directory containing the executable, not + the initial working directory. + +Graphics: + + • Make al_get_monitor_info return success code. + + • Replace al_set_new_display_adaptor(-1) with a named constant + ALLEGRO_DEFAULT_DISPLAY_ADAPTER. + + • Fix numerous bugs in X mode setting and multi monitor related code, + and introduce new xrandr code. + + • Generate ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY when mouse leaves OS X + window (Evert Glebbeek). + + • Hide OS X window during exiting fullscreen window mode, to prevent + the hideous misaligned animation from showing. + + • Fix erroneous assertions in OpenGL backend. + + • Added a hack which makes OpenGL mode work under Wine for me (Elias + Pschernig). + + • Add support for some al_get_display_options in D3D port. + +Keyboard: + + • Don’t send KEY_CHAR events for modifier and dead keys (with + contributions from torhu). + + • Don’t send KEY_DOWN events for non-physical key events. + + • osx: Allow unicode entry (single keypresses only). + + • x11: Set the keycode field in KEY_CHAR events to the code of the + last key pressed, as stated in the documentation, even if the char + is due to a compose sequence. + + • x11: Get rid of historic behaviour where the unicode field is + always zero when Alt is held down. + + • Rename ALLEGRO_KEY_EQUALS_PAD to ALLEGRO_KEY_PAD_EQUALS for + consistency. + +Mouse: + + • Add al_grab_mouse and al_ungrab_mouse. Implemented on X11 and + Windows. + + • Allow the user configure a key binding to toggle mouse grabbing on + a window. + + • Support horizontal mouse wheel on Windows (jmasterx). + + • Calculate Y position for al_set_mouse_xy correctly in OS X windowed + mode (X-G). + + • Use more appropriate CURSOR_LINK cursor on OS X (X-G). + + • Assign different button IDs for separate touches on iPhone (Michał + Cichoń). + + • iphone: Remove fake mouse move events as they’re unncessary and can + cause problems with user input tracking. + +Filesystem: + + • Clean up al_get_standard_path(): remove SYSTEM_DATA, + SYSTEM_SETTINGS, PROGRAM paths; add RESOURCES and USER_DOCUMENTS + paths. Use system API calls if possible. + + • Implement ALLEGRO_USER_DATA_PATH under Linux. Honor + XDG_DATA/CONFIG_HOME environment variables. + + • Fix al_make_directory on Windows due to problems with calls to + stat() with trailing slashes. + +Native dialogs addon: + + • Use string arguments to al_create_native_file_dialog() and + al_get_native_file_dialog_path() instead of ALLEGRO_PATH. + + • Enhance the Windows file selector (initial patch by Todd Cope): + + • Use Windows’ folder selector for ALLEGRO_FILECHOOSER_FOLDER. + + • Implement patterns. + + • Display the title of the dialog that the user specified. + +Primitives addon: + + • Fix changing the D3D blender state without updating the cached + state. + +TTF addon: + + • Align glyphs in ttf font sheets so as to work around problems with + forced S3TC compression with some OpenGL drivers (Elias Pschernig). + +Examples: + + • SPEED: add full screen flag, use standard paths for highscores and + data. + +Build system: + + • Check PulseAudio backend will compile before enabling support. + + • Give a louder warning if FLAC/Vorbis/DUMB compile tests fail. + +Other: + + • Many leaks fixed on OS X. + + • Minor bug fixes and documentation updates. + +Changes from 5.0.0 RC3 to 5.0.0 RC4 (December 2010) +*************************************************** + +The main developers this time were: Trent Gamblin, Matthew Leverton, +Elias Pschernig, Peter Wang. + +Graphics: + + • d3d: Don’t generate intermediate resize events during modal resize + loop. + + • Optimize D3D9 driver by caching blender state and scissor rectangle + so redundant calls to D3D9 functions are avoided (Michał Cichoń). + + • gl: Use glGenerateMipmapEXT to generate mipmaps when FBOs are used. + + • x11: Don’t restore display mode if another fullscreen display is + active. + +Input: + + • iphone: Reverse button/axis events that were swapped at some point. + +File I/O: + + • Change the way user code implements new ALLEGRO_FILE structures. + This adds al_create_file_handle and al_get_file_userdata. + + • Implement default ungetc behavior - used if the interface does not + supply its own. + + • Add al_fopen_interface. + +Memfile addon: + + • Implement ungetc. + + • Add rw file modes. + + • Rename header to allegro_memfile.h. + + • Add documentation. + +Image I/O addon: + + • Fix endian issues in TGA and Mac OS X image loaders. + +Other: + + • Use _NSGetExecutablePath for + al_get_standard_path(ALLEGRO_EXENAME_PATH) on OS X (Jeff Connelly). + + • Minor bug fixes and documentation updates. + +Changes from 5.0.0 RC2 to 5.0.0 RC3 (December 2010) +*************************************************** + +The main developers this time were: Michał Cichoń, Trent Gamblin, Peter +Wang. + +Graphics: + + • Honour subbitmap clipping rectangle under OpenGL (Elias Pschernig). + + • Fix an error in the Direct3D primitives blending. + + • al_set_new_window_position() did not have an effect for resizable + windows on X11. + + • Fix windows only showing up on first monitor on X11 (Thomas + Fjellstrom). + + • Implement al_get_monitor_info() for iDevices. + +Input: + + • Separate character inputs from physical key down events. This + removes unichar and modifiers fields from ALLEGRO_EVENT_KEY_DOWN, + and replaces ALLEGRO_EVENT_KEY_REPEAT by ALLEGRO_EVENT_KEY_CHAR. We + decided this design flaw was better fixed now than later. + + • Make Mac OS X keyboard driver properly distinguish key down and key + repeat events. + +TTF addon: + + • Respect ALLEGRO_NO_PREMULTIPLIED_ALPHA flag when loading TTF fonts. + +Other: + + • Fix returning a garbage pointer in maybe_load_library_at_cwd (Vadik + Mironov). + + • Remove dependency on dxguid. + + • Minor compilation fixes and documentation updates. + +Changes from 5.0.0 RC1 to 5.0.0 RC2 (December 2010) +*************************************************** + +The developers this time were: Trent Gamblin, Elias Pschernig and Peter +Wang. + +System: + + • Add al_is_system_installed and hide al_get_system_driver. + + • Prevent ‘DLL hijacking’ security issue on Windows. + +Graphics: + + • Change to using premultiplied alpha by default. The new bitmap + flag ALLEGRO_NO_PREMULTIPLIED_ALPHA was added. + + • Change the value of ALLEGRO_VIDEO_BITMAP to non-zero. + + • Change al_get_opengl_version to return a packed integer. + + • Made al_get_opengl_version return an OpenGL ES version (if using + OpenGL ES) rather than an attempted estimate at a desktop GL + version. + + • Added function al_get_opengl_variant that returns either + ALLEGRO_DESKTOP_OPENGL or ALLEGRO_OPENGL_ES. + + • Make al_have_opengl_extension return bool. + + • Fix OpenGL graphics mode height value on Windows. + + • Only try to create one Direct3D display at a time. + + • Make screensaver activate on Windows Vista and above unless + inhibited. + + • Avoid potential divide-by-zeroes when computing the refresh rate in + X11 video modes. + +Events: + + • Delete an incorrect mutex destroy in al_unregister_event_source. + +Input: + + • Revert the joystick driver used on OS X 10.4 to the pre-hotplugging + version, rather than one which contained an earlier attempt at + implementing hotplugging. Select the 10.4 or greater joystick + driver at runtime. + +iPhone: + + • Added two iPhone-specific functions: + al_iphone_override_screen_scale and al_iphone_program_has_halted. + +Image I/O addon: + + • Made the iPhone and OSX image loaders not try and correct colors to + some arbitrary color space, but instead use the values directly + from the image. + +Native dialogs addon: + + • Tolerate null display in al_show_native_file_dialog on Windows. + + • Make GTK native dialog implementation only call GTK from a single + thread. + + • Define al_show_native_message_box to be usable without installing + Allegro. + +Primitives addon: + + • Make primitives addon compilable again without OpenGL. + +Examples: + + • ex_ttf: Test the monochrome flag. + + • Work around problems with MSVC and UTF-8 string literals. ex_utf8 + is now not built under MSVC. + + • Don’t use WIN32 executable type on examples that require the + console (David Capello). + +Other: + + • Minor bug fixes and documentation updates. + +Changes from 4.9.22 to 5.0.0 RC1 (November 2010) +************************************************ + +The developers this time were: Trent Gamblin, Evert Glebbeek, Elias +Pschernig, Paul Suntsov, Peter Wang. + +Graphics: + + • Make al_resize_display keep the original resolution (or change + back) if it can’t set the users request, on Windows. + + • Do not emit ALLEGRO_DISPLAY_RESIZE events from the Windows and X11 + display drivers when using al_resize_display. + + • [X11] Make al_get_num_display_modes and al_get_display_mode work if + the adapter is set to default. Right now there was no way to query + the modes of the default monitor. + + • [X11] Use _NET_WM_STATE_FULLSCREEN hint for “true” fullscreen + displays. Enable mouse grabbing in fullscreen modes. + + • Added ALLEGRO_EVENT_DISPLAY_ORIENTATION and implement it on iOS. + + • Dennis Busch fixed a problem with displays not showing up on the + primary display by default in some dual head setups, on Windows. + + • Increase the precision of texture coordinate deltas in the software + triangle renderer, from floats to doubles. + + • Remove al_get_frontbuffer(). It wasn’t implemented anywhere. + + • Implement min/mag filter and mipmap flags for Direct3D. + +Input: + + • Report correct initial mouse position if a display is created with + the mouse pointer inside, or if the mouse routines are installed + after a display is created (X11, Windows). + + • John Murphy fixed improperly mapped axes on the Windows joystick + driver. + +Events: + + • Do not register user event sources with the destructor system as it + cannot work reliably. User event sources must be destroyed + manually. + +Filesystem: + + • Make al_get_fs_entry_name and al_get_current_directory return + strings instead of ALLEGRO_PATH. + + • Make al_make_directory create parent directories as needed. + + • Fix al_create_fs_entry to not trim the root path “/” down to the + empty string with the stdio backend. + +Path routines: + + • Remove al_make_path_absolute and replace it by al_rebase_path. + + • Remove undocumented behavior of setting a default organization name + of “allegro” for all apps. + + • Correctly return standard paths as directories on OS X. + +Threads: + + • Rename al_wait_cond_timed to al_wait_cond_until to match + al_wait_cond_until. + +Config routines: + + • Add a blank line between sections when writing out a config file. + +Other core: + + • Move the Windows event loops back into the same thread as the D3D + event loop. It’s a requirement of D3D, else you can get crashes as + I was when resetting the device (like tabbing away from a + fullscreen app). + + • Add some missing standard entries to the OS X menu bar (the “hide”, + “hide others” and the window list, mainly). + +Audio addon: + + • Automatically stop sample instances which point to a buffer of a + sample which is about to be destroyed with al_destroy_sample. + + • alsa: Resume properly after suspending. + +Image I/O addon: + + • Make GDI+ support compile cleanly with the headers that come with + MinGW package w32api-3.15. + + • Speed up PNG and BMP saving, and NSImageFromAllegroBitmap loading. + +TTF addon: + + • Add a flag for loading TTFs without anti-aliasing + (ALLEGRO_TTF_MONOCHROME). + +Primitives addon: + + • Fix several failed sub-bitmap related unit tests on Windows. + + • Made thick outlined triangles look nicer when the triangles are + very thin. + + • Add a debug-only check for primitives addon initialization to aid + in code portability. + +Examples: + + • Added example demonstrating the effect of premultiplied alpha. + + • Make ‘F’ toggle fullscreen window in SPEED (in-game). + + • Minor improvements to the a5teroids demo. + +Documentation: + + • Many documentation updates. + + • Add list of contributors and a readme for packagers. + + • Make make_doc tool build cleanly on MSVC, and work around a problem + with recent version of Pandoc on Windows. + + • Improve styling of PDF output. + + • Add generated man pages to archives. + +Bindings: + + • Implemented array types in the Python wrapper. + +Changes from 4.9.21 to 4.9.22 (September 2010) +********************************************** + +The developers this time included: Michał Cichoń, Trent Gamblin, Evert +Glebbeek, Angelo Mottola, Elias Pschernig, Paul Suntsov and Peter Wang. + +System: + + • Allow the X11 port to initialise without an X server connection. + +Graphics: + + • Fix many bugs with bitmap locking. + + • Fix many bugs to do with transformations, flipping and clipping. + + • Fix many bugs to do with sub-bitmaps as source and destination. + + • Renamed al_draw_[tinted_]rotated_scaled_bitmap to + al_draw_[tinted_]scaled_rotated_bitmap to match the parameter + order. + + • Reimplemented bitmap software rendering routines using newly + optimised software triangle renderer, formerly in the primitives + addon. + + • Add pixel_size field to ALLEGRO_LOCKED_REGION. + + • Fix bugs to do with pixel alignment on OpenGL. + + • Fix OpenGL pixel transfer of 15 bpp formats, where Allegro does not + Allegro does not care whether the unused bit is set or not, but + when transferring to OpenGL it will be interpreted as an alpha bit. + + • Disabled support for drawing a bitmap into itself. + + • Changed specification of al_draw_*bitmap to not allow + transformation and ignore blending/tinting when the screen itself + is being drawn (except when drawn into a memory bitmap). + + • Allow bitmap regions to be outside the bitmap area in drawing + routines. + + • Added al_add_new_bitmap_flag convenience function. + + • Added three new bitmaps flags ALLEGRO_MAG_LINEAR, + ALLEGRO_MIN_LINEAR, ALLEGRO_MIPMAP. Removed the config settings for + linear/anisotropic min/mag filtering. DirectX side not yet + updated. + + • Register destructors for bitmaps, so they will be implicitly + destroyed when Allegro is shut down. This was only true for some + bitmaps previously. + + • Don’t allocate memory buffers for video bitmaps when using OpenGL. + + • Make al_get_opengl_extension_list() return NULL if called on a + non-GL display. + + • Fix al_create_display for OpenGL forward compatible contexts. + + • Add al_set_current_opengl_context as an explicit way to set the + OpenGL context. + + • Rename al_is_opengl_extension_supported to + al_have_opengl_extension. + + • Produce more accurate/correct color when going from less to more + bits per component. + + • Fix al_set_new_window_position() everywhere. + + • Avoid potential deadlock if resizing window to the same size on + X11. + + • Fixed turning off vsync in X11. + + • Added al_is_d3d_device_lost function. + + • Dynamically load dinput and d3d DLLs on Windows. + + • Replaced PeekMessage with GetMessage in window event loops for the + D3D and WGL drivers (David Capello). + +Input: + + • Added hotplugging support for joysticks on Linux, Windows and OS X. + + • Added al_reconfigure_joysticks function. + + • Merged all joystick devices under a single joystick event source. + + • Removed al_get_joystick_number. + + • Add al_is_joystick_installed. + + • The OS X joystick driver was rewritten; it requires OS X 10.5. The + older driver still exists for OS X 10.4 and earlier but is in a + semi-updated state with regards to hotplugging. + + • Allow user to override joystick device paths in the config file + (Linux). + + • Fix iphone touch input and clipping for modes other than + w=768,h=1024. + + • Fixed missing mouse movement messages on IPhone on touch-up/down. + Also changed how mouse buttons are reported - always as button 1 + now. + +Config: + + • Give config iterators proper types instead of void *. + + • Make al_get_system_config() always return non-NULL if a system + driver is installed. + +Events: + + • Rename al_event_queue_is_empty to al_is_event_queue_empty (with + compatibility define). + +Timers: + + • Add al_add_timer_count function. + + • Rename al_timer_is_started to al_get_timer_started. + + • Rename al_current_time to al_get_time (with compatibility define). + +File I/O: + + • Add al_open_fs_entry to open a file handle from an FS_ENTRY. + + • Add al_fclearerr. + + • Set ALLEGRO_FILEMODE_HIDDEN flag on entries for file names + beginning with dot (OS X). + + • Remove al_is_path_present, al_fs_entry_is_directory, + al_fs_entry_is_file (all trivial). + +Primitives addon: + + • Optimised most of the software rendering routines by a lot. + + • Triangle drawer was skipping pixels in very thin triangles. + + • Handle lost d3d devices better. + + • Fix some bugs found during testing. + +Image I/O addon: + + • Fix native image loader on Mac OS X: images that were not 72 dpi + would be rescaled to a smaller size. + + • Added native bitmap saving support for OSX. + + • Fix jpeg saving when locked region has negative pitch. + +Native dialogs addon: + + • Add Windows and OS X text log implementations. + + • Add ALLEGRO_FILECHOOSER and ALLEGRO_TEXTLOG types instead of + conflating them into ALLEGRO_NATIVE_DIALOG. + + • Fix race condition in al_open_native_text_log. + + • Rename al_destroy_native_dialog to al_destroy_native_file_dialog. + + • Rename al_get_native_dialog_event_source to + al_get_native_text_log_event_source. + + • Speed up text log appending by making the reader/writers + asynchronous. + + • Register destructors for file chooser and text log dialogs. + + • Fix file chooser on Windows returning multiple selections with + slashes appended to filenames. If an initial path was specified + then the dialog wouldn’t open at all; fixed. + + • Let native dialog functions fail gracefully. + +Audio addons: + + • Init destructors even if audio driver fails to install. + + • Dynamically load dsound DLL on Windows. + +Font addons: + + • Added al_shutdown_ttf_addon. + + • Prevent SIGSEGV for double-closing a file in the TTF addon if it is + not a valid font file. + + • Make al_grab_font_from_bitmap not cause a segmentation fault if the + bitmap is garbage. + + • Some TTF fonts would not render right at small sizes; fixed. + + • Make al_destroy_font ignore NULL. + +Tests: + + • Added a test suite (finally). + + • Add a shell script to produce test coverage results using lcov. + +Examples: + + • Add ex_haiku, an example based on Mark Oates’s Haiku game. Mark + generously agreed to let us include it as an Allegro example. + + • Added a new example ex_joystick_hotplugging. + + • Added a new example ex_filter. + + • Make ex_fs_window work on MSVC. + + • Allow a5teroids to run without audio, or if audio data doesn’t + load. + +Build system: + + • Re-added CMake option that allows forced static linking of libFLAC. + + • Replaced the old iphone xcode project with a cmake iphone + toolchain. + +Documentation: + + • Many updates to the reference manual. + +Bindings: + + • Added a workaround to the Python wrapper for a Mingw bug. + +Changes from 4.9.20 to 4.9.21 (July 2010) +***************************************** + +The main developers this time were: Trent Gamblin, Matthew Leverton, +Elias Pschernig, Paul Suntsov, Peter Wang. + +Graphics: + + • Fixed the mis-termed “blend color”. There is no more color state. + + • al_set*_blender functions lose the color parameter. + + • Added 5 new bitmap drawing functions al_draw_tinted*_bitmap + with a color parameter. The parameter is used just like the + “blend color” before. + + • All text drawing functions gain a color parameter and use it + like they used the “blend color” before. + + • Primitive drawing functions previously sometimes (and + sometimes not) used the “blend color”. Not any longer. + + • Make the current blending mode thread-local state instead of + per-display state. + + • Add explicit display arguments to functions which require a + display, but don’t require the rendering context to be current. + + • Make al_set_target_bitmap change the current display as necessary. + al_set_target_bitmap(NULL) releases the rendering context. + + • Add al_set_target_backbuffer as a convenience. + + • Remove al_set_current_display. + + • Give each bitmap its own transformation, i.e. every bitmap has a + transformation, which is in effect when that bitmap is the target. + + • Remove sub-bitmap clip-to-parent restriction on create. Add + out-of-bounds blitting support to memory bitmaps. + + • Merge sub-bitmap and parent bitmap clipping; clip source bitmap to + (0,0)-(w,h); fix flipping to/from clipped bitmaps. + + • Made mouse cursors independent of displays. You may create cursors + without a display, and you may use a cursor with any display. + + • Rename al_{set,get}_current_video_adapter to *new_display_adapter + for consistency. + + • Move the new display video adapter and new window position to + thread-local state, like other new display parameters. Make + al_store_state also save those parameters with + ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS. + + • Rename al_transform_transform to al_compose_transform. Switched + the order of parameters in al_compose_transform and + al_copy_transform to match the rest of the transform functions. + + • Made memory bitmap manipulation without a display possible + (again?). + + • Fixed window resizing in D3D driver. Simplify resize-postponing on + Windows. + + • Make al_create_display abort early when the new_display_adapter is + greater than the screen count (X11). + + • Added ALLEGRO_MINIMIZED flag to the X11 port. + + • Fixed OpenGL version string parsing (bug #3016654). + +Other core: + + • Renamed al_install_timer to al_create_timer, and al_uninstall_timer + to al_destroy_timer. + + • Rename al_{get,set}_{appname,orgname} to *app_name and *org_name. + + • Fix assertion failure in al_create_mutex_recursive on Windows + (spoofle). + +Primitives addon: + + • Made the D3D driver of the primitives addon work with multiple + displays. Also made it handle the display being destroyed + properly. + + • Simplified shader recreating on thread destruction when using the + primitives addon with D3D. + + • Avoid double free when shutting down the primitives addon multiple + times. + + • Older Intel cards don’t implement DrawIndexedPrimitiveUP correctly. + Altered the D3D code to work around that. + +Audio addon: + + • Allow setting the DirectSound buffer size via allegro5.cfg. + +Image addon: + + • Make GDI+ image loader work with MinGW. + +Font addon: + + • Nicolas Martyanoff added al_get_font_descent/ascent functions which + query per-font properties. Previously it was necessary to call + al_get_text_dimensions (which now just reports the text dimensions + as it should). + +Native dialogs addon: + + • Add text log window functions (GTK only for now). + +Documentation: + + • Many updates to the reference manual. + + • Improve styling and add Allegro version to HTML pages. + + • Separated readme_a5.txt into multiple files, and hopefully improve + them. + +Build system: + + • Remove INSTALL_PREFIX. Windows users can now use + CMAKE_INSTALL_PREFIX to set the install path. + + • Allow the user to place dependencies in a subdirectory “deps”, + which will be automatically searched. + +Examples: + + • Use text log windows in many examples. + + • Add ex_noframe: test bitmap manipulation without a display. + +Bindings: + + • Update Python bindings. + +Changes from 4.9.19 to 4.9.20 (May 2010) +**************************************** + +The developers this time were: Thomas Fjellstrom, Evert Glebbeek, +Matthew Leverton, Milan Mimica, Paul Suntsov, Trent Gamblin, Elias +Pschernig, Peter Wang. With significant contributions from Michał +Cichoń. + +Core: + + • Add al_malloc, al_free, et al. These are now used consistently + throughout Allegro and its addons. + + • Replace al_set_memory_management_functions by a simpler function, + al_set_memory_interface. + + • Renamed some D3D/Windows specific functions to follow the + al_{verb}_{stuff} convention. + +Graphics: + + • Move image I/O framework to core, i.e. al_load_bitmap, + al_save_bitmap and bitmap file type registration. Image codecs + remain in allegro_image. + + • Added a simple display capabilities querying capability to + al_get_display_option: ALLEGRO_MAX_BITMAP_SIZE, + ALLEGRO_SUPPORT_NPOT_BITMAP, ALLEGRO_CAN_DRAW_INTO_BITMAP, + ALLEGRO_SUPPORT_SEPARATE_ALPHA. (OpenGL only for now) + + • Fix in OpenGL 3.0 context creation. + + • Make the extensions mechanism compatible with OpenGL version >= 3. + Declared symbols needed by OpenGL 3.2 and 3.3 and brought OpenGL + extensions up to date. + + • Fix an assertion in _al_draw_bitmap_region_memory so it does not + trigger when source and destination are the same bitmap. + + • Fix some locking issues by setting GL_PACK_ALIGNMENT and + GL_UNPACK_ALIGNMENT before reading/writing pixels. + + • Partial implementation of ALLEGRO_FULLSCREEN_WINDOW on OS X (Snow + Leopard, probably Leopard). + + • Started X11 fullscreen support (resolution switching). + + • Fix handling of X11 size hints. + + • Fixed a deadlock related to fullscreen windows under X11 caused by + using a nested lock for a condition variable. + + • Use _NET_WM_ICON to set icon on X11 instead of XSetWMHints. + + • Get the iPhone OpenGL version more properly. Only use separate + blending on iPhone with OpenGL ES 2.0+. + + • Release the splash view and windows on iPhone, which makes + backgrounding Allegro apps on OS 4.0 work. + + • Updated iphone port for IPad (only tested in the simulator). + +Input: + + • Disabled Raw Input code in Windows. Mouse events now reflect + system cursor movements even in fullscreen mode. + + • Prevent late WM_MOUSELEAVE notifications from overriding mouse + state display field (Windows). + + • Update pollable mouse state with axes events as well as button + events on iPhone. + +Filesystem: + + • Made the filesystem entry functions work under Windows even if the + name passed to al_create_fs_entry has a trailing slash or + backslash. + +Config routines: + + • Add al_{load,save}_config_file_f. + + • Reorder al_save_config_file* arguments to match al_save_bitmap and + al_save_sample. + + • Optimise config routines to work well for thousands of + keys/sections. + +Image addon: + + • Added a GDI+ implementation of the image codecs, which will be used + in favour of libjpeg/libpng if Allegro is compiled with MSVC. Then + allegro_image will not require JPEG/PNG DLLs at runtime. + + • Removed format specific image functions. + + • Fixed bug in native png loader on iphone: was using the source + color space instead of the target color space which made it fail + whenever they differed (alpha-less paletted pictures). + + • Add an autorelease pool around iphone native image loading to stop + memory leaks. + +Font addons: + + • Sever the tie between allegro_font and allegro_image. The user + needs to initialise the image addon separately now. + + • Rename al_load_ttf_font_entry to al_load_ttf_font_f. + + • Fixed problem with glyph precision after applying transformations + in the ttf addon. + +Primitives addon: + + • Added al_init_primitives addon function. This is now required. + + • Removed ALLEGRO_PRIM_COLOR; ALLEGRO_COLOR can now be used where it + was required. + + • v textures coordinates were off for OpenGL non-power-of-two + textures. + + • Free the vertex cache in al_destroy_display on X11. + + • Added the dummy vertex shader support to D3D driver of the + primitives addon. Without this, custom vertices either resulted in + warnings or outright crashes on some systems. + + • Bring D3D driver up to speed a little bit: transformations now work + properly with sub-bitmap targets; the half-pixel offset now + properly interacts with transformations; al_set_target_bitmap does + not clear the transformation; the proper transformation is set at + display creation. + + • Cull the primitives that are completely outside the clipping + region. + + • Scale the numbers of vertices for the curvy primitives with the + scale of the current transformation. + +Audio addon: + + • Remove driver parameter from al_install_audio. + + • Rename al_get_depth_size to al_get_audio_depth_size. + + • Rename al_get_audio_stream_buffer to al_get_audio_stream_fragment. + + • Many improvements to AQueue driver. + +Audio codecs: + + • Add MOD/S3M/XM/IT file support, using the DUMB library. + + • Revert to a monolithic allegro_acodec addon, i.e. remove separate + allegro_flac, allegro_vorbis addons. WAV file support is in + allegro_acodec. + + • Implement DLL loading for FLAC/Vorbis/DUMB on Windows. + allegro_acodec will load the DLL at runtime to enable support for + that format. If your program does not require said format, you + don’t need to distribute the DLL. + + • Remove format-specific loader/saver audio codec functions. + + • Make acodec loaders have consistent file closing behaviour. + + • Optimised wave file loading. + +Examples: + + • Make SPEED port run acceptably on graphics drivers without FBOs. + +Documentation: + + • Added documentation for the public Direct3D specific functions. + + • Documented ALLEGRO_OPENGL_3_0 and + ALLEGRO_OPENGL_FORWARD_COMPATIBLE. + +Other: + + • Many bug and documentation fixes. + +Changes from 4.9.18 to 4.9.19 (April 2010) +****************************************** + +The main developers this time were: Milan Mimica, Trent Gamblin, Paul +Suntsov, Peter Wang. Other contributions from: Evert Glebbeek and Shawn +Hargreaves. + +Graphics: + + • Implemented support for transformations for memory bitmaps. + + • Transformations now work properly when the target bitmap is a + sub-bitmap in OpenGL (still broken in D3D). Also fixed OpenGL + bitmap drawing in the same scenario (it used to always revert to + software drawing). + + • Use the memory drawers when the source bitmap is the backbuffer + with the rotated/scaled bitmaps. + + • Make al_put_pixel clip even if the bitmap is locked, which was the + reason why software primitives were not clipping. + + • Added al_put_blended_pixel, the blended version of al_put_pixel. + + • Sub bitmaps of sub bitmaps must be clipped to the first parent. + + • Don’t clear the transformation when setting the target bitmap in + OpenGL. + + • Implemented ALLEGRO_NOFRAME and ALLEGRO_FULLSCREEN_WINDOW in WGL. + + • Set the ALLEGRO_DISPLAY->refresh_rate variable for fullscreen modes + under D3D. + + • Make d3d_clear return immediately if the display is in a lost + state. + + • Rewrote the function that reads the OpenGL version so it works for + previously unrecognised versions, and future versions. + + • Check for framebuffer extension on iPhone properly. + + • Fixed locking bugs on iPhone. allegro_ttf works now. + +Input: + + • Removed al_set_mouse_range. + + • Don’t call al_get_mouse_state if the mouse driver isn’t installed + (Windows). + + • Send events even when the mouse cursor leaves the window, while any + buttons are held down (Windows and Mac OS X; X11 already did this). + + • Allow mouse presses and accelerometer data simultaneously. + (iPhone) + +File I/O: + + • Optimise al_fread{16,32}* by using only one call to al_fread each. + + • Optimise al_fgetc() for stdio backend. + +Path: + + • Fix an infinite loop in _find_executable_file when searching for + the executable on the PATH (Alan Coopersmith). + +Primitives addon: + + • Made the software driver for the primitives addon check for + blending properly. Also, fixed two line shaders. + + • Made the D3D driver thread-safe. The whole addon should be + thread-safe now. + + • The addon now officially supports 3D vertices, even though the + software component can’t draw them yet. + + • Changed the way the primitives addon handles the OpenGL state + (fixes a few bugs and makes life easier for raw-OpenGL people) + +Image addon: + + • Optimised BMP, PCX, TGA loaders. + + • Fix loading 16-bit BMP files. + + • Fix loading grayscale TGA images. + + • Nial Giacomelli fixed a bug where images could be corrupt using the + native Apple image loader (iPhone). + +Audio addon: + + • Add al_is_audio_installed. + + • Fix al_attach_sample_instance_to_mixer for int16 mixers. + + • Implement attaching an INT16 mixer to another INT16 mixer. + + • Handle conversion when an INT16 mixer is attached to a UINT16 + voice. + +Build system: + + • Add an option to disable Apple native image loader (iPhone and OS + X). + + • Add ttf addon target to iPhone xcode project. + +Examples: + + • Special contribution from Shawn “the Progenitor” Hargreaves. + +Changes from 4.9.17 to 4.9.18 (March 2010) +****************************************** + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Evert Glebbeek, Peter Wang. Other contributions from: Milan Mimica, +Paul Suntsov, Peter Hull. + +Graphics: + + • Fixed broken drawing into memory bitmaps as access to the global + transformation required an active display. Now both transformation + and current blending mode are stored in the display but provisions + are made for them to also work if the current thread has no + display. + + • Fixed a bunch of clipping problems with OpenGL, especially with + sub-bitmaps. + + • Fix bug in OpenGL FBO setup when the target bitmap is the + sub-bitmap of a bitmap with an FBO. + + • Fixed crash in al_get_num_display_modes under OSX 10.5. + + • Fixed some problems in _al_convert_to_display_bitmap that caused + problems in WGL FS display resize. + + • Fixed al_set_current_display(NULL) on WGL. + + • Added subtractive blending. al_set_blender() takes another + parameter. + + • Added ALLEGRO_FULLSCREEN_WINDOW display flag (X11 and D3D for now). + + • Allow changing ALLEGRO_FULLSCREEN_WINDOW with + al_toggle_display_flag. + + • Figured out how to switch display modes using Carbon on OS X 10.6. + + • Stop the OpenGL driver on iPhone from changing the currently bound + FBO behind our back when locking a bitmap. + + • Prevent screen flicker at app startup by simulating the splash + screen (iPhone). + +Input: + + • Added “pressure” field to the mouse event struct and mouse state, + which can be used with pressure sensitive pointing devices, + i.e. tablets/stylus (currently OS X only). + + • Report scroll ball “w” position in mouse event struct, on OS X. + + • Removed OS X 10.1 specific code from mouse driver. We don’t + support OS X 10.1 any more. + + • Fix building of Linux joystick driver on some systems. + +Threads: + + • Fix a problem when al_join_thread() is called immediately after + al_start_thread(). The thread could be joined before the user’s + thread function starts at all. + + • Fix a possible deadlock with al_join_thread() on Windows (thanks to + Michał Cichoń for the report). + + • Fix some error messages running threading examples on OS X. + +Other core: + + • Added version check to al_install_system. + + • Rename al_free_path to al_destroy_path for consistency. + + • Make it possible to have an empty organization name with + al_set_org_name(). + + • Changed implementation of AL_ASSERT to use POSIX-standard assert + instead. + + • Removed al_register_assert_handler. + + • Fix timer macros which did not parenthesize their arguments. + + • Make stricmp, strlwr, strupr macros conditionally defined. + +Audio addon: + + • Rename al_attach_sample_to_mixer to + al_attach_sample_instance_to_mixer. + + • Fix a premature free() when detaching samples and other audio + objects. + + • Fix mixers attaching to mixers. + + • Pass correct number of samples to mixer postprocess callback. + + • AudioQueue code was not compiled even though version requirements + may have been met (OS X). + +Primitives addon: + + • Make high-level primitives functions thread safe. (note: the + DirectX driver is not yet thread safe) + + • Fix a bug causing crashes on Windows 7 when using the primitives + addon and Direct3D (Invalid vertex declarations were being used). + + • Fixed another issue with primitives drawing to memory bitmaps. + + • Hopefully fix the bitmap clipping bugs, and make the D3D and + OGL/Software outputs to be near-identical again. + +Image addon: + + • Added a “native loader” for MacOS X that uses the NSImage bitmap + loading functions. In addition to .png and .jpg, this allows us to + read a whole zoo of image formats (listed in allegro.log). + + • Add native support for tif, jpg, gif, png, BMPf, ico, cur, xbm + formats to under IPhone. + + • Fixed an over-zealous ASSERT() that disallowed passing NULL to + al_register_bitmap_loader() despite this being an allowed value. + + • Avoid using a field which is deprecated in libpng 1.4. + +Color addon: + + • Make al_color_name_to_rgb return a bool. + +Native dialogs addon: + + • Fixed some erratic behaviour and crashes on OS X. + +Build system: + + • Set VERSION and SOVERSION properties on targets to give Unix shared + libraries proper sonames. e.g. liballegro[_addon].so.4.9, + liballegro[_addon].4.9.dylib + + • Static libraries are now named without version number suffixes to + minimise the differences with the shared libraries, which no longer + have the versions in their base names. + e.g. liballegro[_addon]-static.a, allegro[_addon]-static.lib + + • Windows import libraries are also named without version suffixes, + e.g. liballegro[_addon].a, allegro[_addon].lib + + • DLLs are named with a short version suffix, not the full version. + e.g. allegro-4.9.dll instead of allegro-4.9.18.dll + + • Add support for Mac OS X frameworks (untested), which are enabled + with WANT_FRAMEWORKS and WANT_EMBED. There is one framework per + addon. + + • Search for static OGG/Vorbis libraries built with MSVC named + libogg_static.lib, etc. + + • Updated iPhone XCode project. + +Examples: + + • ex_mixer_pp: New example to test mixer postprocessing callbacks. + + • ex_threads: Make it more visually interesting and test out + per-display transformations. + + • ex_ogre3d: New example demonstrating use of Ogre graphics rendering + alongside Allegro (currently GLX only). Commented out in the build + system for now. + + • ex_fs_window: New example to test ALLEGRO_FULLSCREEN_WINDOW flag + and al_toggle_display_flag. + + • ex_blend2: Updated to test subtractive blending, including + scaled/rotated blits and the primitives addon. + + • ex_mouse_events: Show “w” field. + + • ex_prim: Added possibility to click the mouse to advance screens + (for iPhone). + + • ex_vsync: Display config parameters and warning. + + • ex_gldepth: Make the textures appear again though we’re not sure + why they disappeared. + +Documentation: + + • Many documentation updates. + + • Add which header file and which library to link with for each page + of the reference manual. + + • Minor improvements to HTML styling and man page output. + +Changes from 4.9.16 to 4.9.17 (February 2010) +********************************************* + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Evert Glebbeek, Paul Suntsov, Peter Wang. + +Core: + + • Removed END_OF_MAIN() everywhere. + + For MSVC, we pass a linker option through a #pragma. + + On Mac OS X, we rename main() and call it from a real main() + function in the allegro-main addon. The prototype for main() for + C++ applications should be "int main(int, char **)", or the code + will not compile on OS X. For C, either of the normal ANSI forms is + fine. + + #define ALLEGRO_NO_MAGIC_MAIN disables the #pragma or name + mangling, so you can write a WinMain() or use al_run_main() + yourself. + +Graphics: + + • Fixed a bug in the OpenGL driver where al_draw_bitmap() wouldn’t + handle blitting from the back buffer. + + • Changing the blending color now works with deferred drawing (Todd + Cope). + + • Avoid some problems with window resizing in Windows/D3D. + + • Added al_get_d3d_texture_position. + + • Fixed bug under X11 where al_create_display() would always use the + display options from the first al_create_display() call. + + • Properly implemented osx_get_opengl_pixelformat_attributes(). + + • Fixed automatic detection of colour depth on OS X. + + • Fixed al_get_num_display_modes() on Mac OS X 10.6. + + • Removed al_get_num_display_formats, al_get_display_format_option, + al_set_new_display_format functions as they can’t be implemented on + OSX/iPhone/GPX ports (and were awkward to use). + + • Replaced al_toggle_window_frame function with a new function + al_toggle_display_flags. + + • al_load_bitmap() and al_convert_mask_to_alpha() no longer reset the + current transformation. + + • Add a minimize button to all non-resizable windows on Windows. + + • The wgl display switch-in/out vtable entries were swapped (Milan + Mimica). + +Input: + + • Some keycodes were out of order in src/win/wkeyboard.c + + • Fixed mouse range after resizing window on Windows. + + • Fixed (or worked around) a joystick axis detection problem on Mac + OS X. + + • Change timer counts from ‘long’ to ‘int64_t’. + +File I/O: + + • Remove ‘ret_success’ arguments from al_fread32be/le. + +allegro-main addon: + + • Added an “allegro-main” addon to hold the main() function that is + required on Mac OS X. This way the user can opt out of it. + +Primitives addon: + + • Added support for sub-bitmap textures in OpenGL driver. + + • Added support for sub-bitmap textures in D3D driver. Made D3D + sub-bitmaps work better with user D3D code. + +Audio addons: + + • Changed the _stream suffix to _f in the audio loading functions. + + • Added the stream versions of loading functions for wav, ogg and + flac. + + • Rename audio I/O functions to al_load_{format}, al_save_{format}, + al_load_{format}_f and al_save_{format}_f. + + • Added al_load_sample_f, al_save_sample_f, al_load_audio_stream_f + and the related functions. + + • Fixed a bug where al_save_sample was improperly handling the + extension. + + • al_drain_audio_stream would hang on an audio stream in the + ‘playing’ state (the default) which wasn’t attached to anything. + + • Fixed a potential deadlock on destroying audio streams by shutting + down the audio driver. + + • Comment out PA_SINK_SUSPENDED check, which breaks the PulseAudio + driver, at least on Ubuntu 9.10. + + • Replace unnecessary uses of ‘long’ in audio interfaces. + +Image addons: + + • Fixed return values of al_save_bmp_f and al_save_pcx_f being + ignored. + + • Changed the _stream suffix to _f in the image loading functions. + +TTF addon: + + • Drawing TTF fonts no longer resets the current transformation. + +Build system: + + • Add the CMake option FLAC_STATIC, required when using MSVC with a + static FLAC library. + + • Link with zlib if linking with PhysicsFS is not enough. + + • Updated iPhone project files. + +Documentation: + + • Many documentation updates. + +Examples: + + • ex_display_options: Added mouse support, query current display + settings, display error if a mode can’t be set. + +Bindings: + + • Made the Python wrapper work under OSX. + + • Added a CMake option to build the Python wrapper. + + • Added al_run_main() mainly to support the Python wrapper on OSX. + +Changes from 4.9.15.1 to 4.9.16 (November 2009) +*********************************************** + +The main developers this time were: Trent Gamblin and Paul Suntsov. + +Graphics: + + • Fixed clipping of the right/bottom edges for the software + primitives. + + • Enable sub-pixel accuracy for rotated blitting in software. + + • Made the D3D output look closer to the OGL/Software output. + + • OpenGL driver now respects the ‘linear’ texture filtering + configuration option. Anisotropic is interpreted as linear at this + time. + + • Added deferred bitmap drawing (al_hold_bitmap_drawing). + + • Made the font addons use deferred bitmap drawing instead of the + primitives addon, removing the link between the two addons. + + • Changed al_transform_vertex to al_transform_coordinates to make the + function more versatile. + + • Transfered transformations from the primitives addon into the core. + Added documentation for that, as well as a new example, + ex_transform. Transformations work for hardware accelerated bitmap + drawing (including fonts) but the software component is not + implemented as of yet. Also fixed some bugs inside the code of the + transformations. + + • Increase performance of screen->bitmap blitting in the D3D driver. + + • Fixed a strange bug with textured primitives (u/v repeat flags were + being ignored on occasion). + + • Added ALLEGRO_VIDEO_BITMAP for consistency. + +Input: + + • Work around a memory leak in iPhone OS that occurs when the + accelerometer is on during touch input. + +Other core: + + • Don’t #define true/false/bool macros in C++. + +Audio addon: + + • Some minor cleanups to the Audio Queue driver. + +Changes from 4.9.15 to 4.9.15.1 (October 2009) +********************************************** + + • Fixed a problem building on MinGW (dodgy dinput.h). + +Changes from 4.9.14 to 4.9.15 (October 2009) +******************************************** + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Matthew Leverton, Paul Suntsov, Peter Wang. + +Core: + + • Set the initial title of new windows to the app name. + + • Add al_set/get_event_source_data. + + • Make locking work on bitmaps that didn’t have an FBO prior to the + call on iPhone. + + • Make al_get_opengl_fbo work on iPhone. + + • Made iPhone port properly choose a visual (so depth buffer creation + works). + +Font addon: + + • Improved drawing speed for longish strings. The font addon now + depends on the primitives addon. + +Primitives addon: + + • Made the ribbon drawer handle the case of extremely sharp corners + more gracefully. + + • Make al_draw_pixel use blend color in the D3D driver. + + • Added POINT_LIST to the primitive types. + + • Various fixes for the D3D driver: fixed line loop drawing; made the + indexed primitives a little faster; added workabouts for people + with old/Intel graphics cards. + + • Fall back to software if given a memory bitmap as a texture. + + • Removed OpenGL state saving code, it was causing massive slowdown + when drawing. Also removed glFlush for the same reason. + +Audio addon: + + • Added PulseAudio driver. + + • Support AudioQueue driver on Mac OS X. + + • Add al_uninstall_audio exit function. + + • Added ALLEGRO_EVENT_AUDIO_STREAM_FINISHED event to signify when + non-looping streams made with al_load_audio_stream reach the end of + the file. + + • Fixed a deadlock when destroying voices. + + • Handle underruns in the r/w ALSA updater. + + • Minor change to the ALSA driver to improve compatibility with + PulseAudio. + +Documentation: + + • Replaced awk/sh documentation scripts with C programs. + +Changes from 4.9.13 to 4.9.14 (September 2009) +********************************************** + +The main developers this time were: Trent Gamblin, Elias Pschernig, Paul +Suntsov, Peter Wang. Other contributions from: Evert Glebbeek, Matthew +Leverton. + +Ports: + + • Elias Pschernig and Trent Gamblin started a iPhone port. + +Graphics: + + • Added al_get_opengl_texture_size and al_get_opengl_texture_position + functions. + + • Try to take into account GL_PACK_ALIGNMENT, GL_UNPACK_ALIGNMENT + when locking OpenGL bitmaps. + + • Fixed all (hopefully) conversion mistakes in the color conversion + macros. + + • Sped up memory blitting, which was using conversion even with + identical formats (in some cases). + + • Make al_set_current_display(NULL); unset the current display. + + • Added ALLEGRO_LOCK_READWRITE flag for al_lock_bitmap (in place of + 0). + + • Fixed window titles which contain non-ASCII characters in X11. + + • Added OES_framebuffer_object extension. + +Input: + + • Added a lot more system mouse cursors. + + • Renamed al_get_cursor_position to al_get_mouse_cursor_position. + + • Prevent Windows from intercepting ALT for system menus. + +Filesystem: + + • Make the path returned by al_get_entry_name() owned by the + filesystem entry so the user doesn’t need to free it manually. + + • Renamed the filesystem entry functions, mainly to include + “fs_entry” in their names instead of just “entry”. + + • Reordered and renamed ALLEGRO_FS_INTERFACE members. + + • Make al_read_directory() not return . and .. directory entries. + + • Renamed al_create_path_for_dir to al_create_path_for_directory. + + • Added al_set_standard_file_interface, al_set_standard_fs_interface. + +Events: + + • Exported ALLEGRO_EVENT_TYPE_IS_USER. + +Threads: + + • Added a new function al_run_detached_thread. + +Other core: + + • Put prefixes on register_assert_handler, register_trace_handler. + + • Added functions to return the compiled Allegro version and addon + versions. + + • Added al_ prefix to fixed point routines and document them. + + • Added al_get_system_config(). + + • Renamed al_system_driver() to al_get_system_driver(). + + • Added 64-bit intptr_t detection for Windows. + + • Added work-around to make OS X port compile in 64 bit mode. + +Addons: + + • Renamed addons from a5_* to allegro_*. + +Image addon: + + • Renamed the IIO addon to “allegro_image”. + + • Renamed *_entry functions that take ALLEGRO_FILE * arguments to + *_stream. + + • Fixed off-by-one error in greyscale JPEG loader. + +Audio addons: + + • Renamed the kcm_audio addon to “allegro_audio”. + + • Renamed ALLEGRO_STREAM and stream functions to ALLEGRO_AUDIO_STREAM + and al_*audio_stream*. + + • Renamed al_stream_from_file to al_load_audio_stream + + • Added int16 mixing and configurable frequency and depth for default + mixer/voice (see configuration file). + + • Fixed FLAC decoding and added FLAC streaming support. + + • Changed the function signature of al_get_stream_fragment() to be + more straightforward. + + • Fixed bug in kcm audio that caused data to be deleted that was + still used. + + • Made ALSA audio driver work when the driver does not support mmap + (commonly because the ALSA really is PulseAudio). + + • Removed al_is_channel_conf function. + +Font addons: + + • Optimized font loading by converting the mask color on a memory + copy instead of have to lock a texture. + + • Made the ttf addon read from file streams. + +Primitives addon: + + • Fixed the direction of the last segment in software line loop, and + fixed the offsets in the line drawer. + + • Fixed the thick ribbon code in the primitives addon, was broken for + straight segments. + + • Various fixes/hacks for the D3D driver of the primitives addon: + hack to make the indexed primitives work and a fix for the textured + primitives. + + • Various enhancements to the transformations API: const correctness, + transformation inverses and getting the current transformation. + + • Added support for custom vertex formats. + + • Flipped the v axis of texture coordinates for primitives. Now + (u=0, v=0) correspond to (x=0, y=0) on the texture bitmap. + + • Added a way to use texture coordinates measured in pixels. Changed + ALLEGRO_VERTEX to use them by default. + +PhysicsFS: + + • PhysFS readdir didn’t prepend the parent directory name to the + returned entry’s path. + + • Set execute bit on PhysFS directory entries. + +Examples: + + • Made examples report errors using the native dialogs addon if + WANT_POPUP_EXAMPLES is enabled in CMake (default). + + • Added new example ex_draw_bitmap, which simply measures FPS when + drawing a bunch of bitmaps (similar to exaccel in A4). + +Documentation: + + • Many documentation updates and clarifications. + + • Fixed up Info and PDF documentation. + +Bindings: + + • Added a script to generate a 1:1 Python wrapper (see ‘python’ + directory). + +Changes from 4.9.12 to 4.9.13 (August 2009) +******************************************* + +The main developers this time were: Trent Gamblin, Elias Pschernig, Paul +Suntsov, Peter Wang. Other contributions from: Todd Cope, Evert +Glebbeek, Michael Harrington, Matthew Leverton. + +Ports: + + • Trent Gamblin started a port to the GP2X Wiz handheld console. + +Graphics: + + • Some OpenGL bitmap routines were not checking whether the target + bitmap was locked. + + • Scaled bitmap drawer was not setting the blend mode. + + • Fixed a bug where al_map_rgb followed by al_unmap_rgb would return + different values. + + • Fixed problems with sub-sub-bitmaps. + + • Fixed window placement on OS X, which did not properly translate + the coordinates specified by the user with + al_set_new_window_position(). + + • Made is_wgl_extension_supported() fail gracefuly. + + • Added ALLEGRO_ALPHA_TEST bitmap flag. + + • Minor optimizations in some memory blitting routines. + +Input: + + • Replaced (ALLEGRO_EVENT_SOURCE *) casting with type-safe functions, + namely al_get_keyboard_event_source, al_get_mouse_event_source, + al_get_joystick_event_source, al_get_display_event_source, + al_get_timer_event_source, etc. + + • Made it so that users can derive their own structures from + ALLEGRO_EVENT_SOURCE. al_create_user_event_source() is replaced by + al_init_user_event_source(). + + • Fixed a problem on Windows where the joystick never regains focus + when tabbing away from a window. + + • Fixed a problem with missing key repeat with broken X.Org drivers. + + • Implemented ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY, + ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY for X11. + +Image I/O addon: + + • Changed return type of al_save_bitmap() to bool. + + • Separated al_add_image_handler into al_register_bitmap_loader, + al_register_bitmap_saver, etc. + + • Made JPEG and PNG loaders handle al_create_bitmap() failing. + + • Speed up JPEG loading and saving. + + • Fixed a reinitialisation issue in iio. + +Audio addons: + + • Moved basic sample loading/saving routines to kcm_audio from acodec + and added file type registration functions. + + • Moved WAV support into kcm_audio. + + • Made WAV loader not choke on extra chunks in the wave. + + • Separated acodec into a5_flac, a5_vorbis addons. You need to + initialise them explicitly. Removed sndfile support. + + • Renamed al_*_oggvorbis to al_*_ogg_vorbis. + + • Changed argument order in al_save_sample and al_stream_from_file. + + • Reordered parameters in al_attach_* functions to follow the word + order. + + • Renamed a few streaming functions to refer to fragments/buffers as + fragments consistently. + + • Added missing getters for ALLEGRO_SAMPLE fields. + + • Fixed mutex locking problems with kcm_audio objects. + + • Avoid underfilling a stream when it is fed with a short looping + stream. + +Other addons: + + • Added glyph advance caching for the TTF addon. + + • Renamed al_register_font_extension to al_register_font_loader. + Match the file name extension case insensitively. + +Documentation: + + • Lots of documentation updates. + + • Added a short “Getting started guide” to the reference manual. + +Examples: + + • Added another example for kcm_audio streaming: ex_synth. + +Build system: + + • Fix pkg-config .pc files generated for static linking. + + • DLL symbols are now exported by name, not ordinals. + +Changes from 4.9.11 to 4.9.12 (July 2009) +***************************************** + + • Fixed bugs in Windows keyboard driver (Todd Cope). + + • Fixed problems with ALLEGRO_MOUSE_STATE buttons on Windows (Milan + Mimica). + + • Fixed problems with PhysicsFS addon DLL on MSVC (Peter Wang). + + • Set the D3D texture address mode to CLAMP (Todd Cope). + + • Fixed hang if Allegro was initialized more than once on Windows + (Michael Harrington). + + • Added a CMake option to force the use of DllMain style TLS on + Windows, for use with C# bindings (Michael Harrington). + + • Fixed a bug where drawing circles with a small radius would crash + (Elias Pschernig). + + • Fixed several memory leaks throughout the libraries (Trent + Gamblin). + + • Fixed some compilation warnings on Mac OS X (Evert Glebbeek). + + • Small documentation updates. + +Changes from 4.9.10.1 to 4.9.11 (June 2009) +******************************************* + +The main developers this time were: Trent Gamblin, Milan Mimica, Elias +Pschernig, Paul Suntsov, Peter Wang. Other contributions from: +Christopher Bludau, David Capello, Todd Cope, Evert Glebbeek, Peter +Hull. + +Graphics: + + • Changed rotation direction in memory blitting routines to match + D3D/OpenGL routines. + + • Made al_set_target_bitmap not create an FBO if the bitmap is + locked. + + • Added explicit FBO handling functions al_get_opengl_fbo and + al_remove_opengl_fbo in case we weren’t quite clever enough above + and the user has to intervene manually. + + • Added OpenGL 3.1 support and a bunch of new OpenGL extensions. + + • Fixed al_inhibit_screensaver on Windows + + • Fixed selection of X pixel formats with WGL if a new bitmap has + alpha. + + • Made X11 icon work regardless of the backbuffer format. + +Input: + + • Ditched DirectInput keyboard driver and replaced it with WinAPI. + Fixes several issues the old driver had. + + • Rewrote Windows mouse driver to use WinAPI instad of DirectInput. + + • Added al_get_joystick_number. + +Filesystem: + + • Merged ALLEGRO_FS_HOOK_ENTRY_INTERFACE into ALLEGRO_FS_INTERFACE + and made ALLEGRO_FS_INTERFACE public. + + • Added al_set_fs_interface and al_get_fs_interface. + + • Made al_opendir take an ALLEGRO_FS_ENTRY. + + • Removed functions which are obsolete or probably have no use. + + • Made al_get_standard_path(ALLEGRO_PROGRAM_PATH) return a path with + an empty filename. + +Path routines: + + • Renamed functions to follow conventions. + +File I/O: + + • Fix al_fgets() returning wrong pointer value on success. + +Primitives addon: + + • Added support for textured primitives in software. + + • Introduced ALLEGRO_PRIM_COLOR, removed ALLEGRO_VBUFFER. + + • Exposed the software line and triangle drawers to the user. + + • Added rounded rectangles. + + • Fix an extraneous pixel bug in the triangle drawer. + +Audio addon: + + • Change from using generic get/set audio property functions to + specific getter/setter functions. + + • Change return types on many functions to return true on success + instead of zero. (Watch out when porting your code, the C compiler + won’t help.) + +Native dialogs: + + • Added a Windows implementation. + + • Added a title to al_show_native_message_box(). + +Other addons: + + • Implemented the filesystem interface for PhysicsFS and demonstrate + its use in ex_physfs. + + • Fixed al_color_html_to_rgb. + +Examples: + + • Added an OpenGL pixel shader example. + +Build system: + + • Output separate pkg-config .pc files for static linking. + +Changes from 4.9.10 to 4.9.10.1 (May 2009) +****************************************** + + • Fixed uses of snprintf on MSVC. + + • Disabled ex_curl on Windows as it requires Winsock. + +Changes from 4.9.9.1 to 4.9.10 (May 2009) +***************************************** + +The main developers this time were: Trent Gamblin, Evert Glebbeek, Milan +Mimica, Elias Pschernig, Peter Wang. Other contributions from: Peter +Hull, Paul Suntsov. + +Graphics: + + • Renamed al_clear() to al_clear_to_color(). + + • Renamed al_opengl_version() to al_get_opengl_version(). + + • Changed the direction of rotation for al_draw_rotated* from + counter-clockwise to clockwise. + + • Added new pixel format ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which + guanrantees component ordering. + + • Added ALLEGRO_NO_PRESERVE_TEXTURE flag. + + • Fixed horizontal flipping in plain software blitting routines. + + • Fixed some blending bugs in the OpenGL driver. + + • Made OpenGL driver fall back to software rendering if separate + alpha blending is requested but not supported. + + • Added a config option which allows pretending a lower OpenGL + version. + + • Implemented al_get_num_display_formats(), + al_get_display_format_option() and al_set_new_display_format() for + WGL. + + • Fixed bug in al_get_display_format_option() with the GLX driver. + + • Fixed a bug in the D3D driver that made display creation crash if + the first scored mode failed. + + • Made the OpenGL driver prefer the backbuffer format for new + bitmaps. + + • Defer FBO creation to when first setting a bitmap as target bitmap. + +Input: + + • Renamed some joystick functions. + + • Account for caps lock state in OS X keyboard driver. + + • Made UTF-8 input work on X11. + +File I/O: + + • Separated part of fshook API into a distinct file I/O API (actually + generic streams). + + • Make the file I/O API match stdio more closely and account for + corner cases. (incomplete) + + • Made it possible to set a stream vtable on a per-thread basis, + which affects al_fopen() for that thread. + + • Added al_fget_ustr() to read a line conveniently. + + • Change al_fputs() not to do its own CR insertion. + + • Add al_fopen_fd() to create an ALLEGRO_FILE from an existing file + descriptor. + +Filesystem: + + • Changed al_getcwd, al_get_entry_name to return ALLEGRO_PATHs. + + • Renamed al_get_path to al_get_standard_path, and to return an + ALLEGRO_PATH. + + • Changed al_readdir to return an ALLEGRO_FS_ENTRY. + + • Added al_path_create_dir. + + • Removed some filesystem querying functions which take string paths + (ALLEGRO_FS_ENTRY versions will do). + +Config routines: + + • Added functions to traverse configurations structures. + + • Change al_save_config_file() return type to bool. + + • Removed an arbitrary limit on the length of config values. + + • Renamed configuration files to allegro5.cfg and allegro5rc. + +String routines: + + • Allegro 4-era string routines removed. + + • Added al_ustr_to_buffer(). + +Other core: + + • Renamed al_thread_should_stop to al_get_thread_should_stop. + + • Added a new internal logging mechanism with configurable debug + “channels”, verbosity levels and output formatting. + + • Cleaned up ASSERT namespace pollution. + +Font addons: + + • Renamed font and TTF addon functions to conform to conventions. + + • Added al_init_ttf_addon. + + • Implemented slightly nicer text drawing API: + + • functions are called “draw_text” instead of “textout” + • centre/right alignment handled by a flag instead of functions + • functions accepting ALLEGRO_USTR arguments provided + • substring support is removed so ‘count’ arguments not needed + in usual case, however ALLEGRO_USTR functions provide similar + thing. + + • Removed al_font_is_compatible_font. + + • Sped up al_grab_font_from_bitmap() by five times. + + • ttf: Fixed a possible bug with kerning of unicode code points > + 127. + +Image I/O addon: + + • Renamed everything in the IIO addon. + + • Exposed al_load_bmp/al_save_bmp etc. + +Audio addon: + + • Renamed al_mixer_set_postprocess_callback. + + • Added two config options to OSS driver. + + • Made ALSA read config settings from [alsa] section. + +Native dialogs: + + • Added al_show_native_message_box() which works like + allegro_message() in A4. Implemented for GTK and OS X. + +PhysicsFS addon: + + • Added PhysicsFS addon. + +Primitives addon: + + • Removed global state flags. + + • Removed normals from ALLEGRO_VERTEX. + + • Removed read/write flags from vertex buffers. + +Examples: + + • Added an example that tests al_get_display_format_option(). + + • Added an example which shows playing a sample directly to a voice. + + • Added an example for PhysicsFS addon. + + • Added a (silly) example that loads an image off the network using + libcurl. + + • Added ex_dir which demonstrates the use of al_readdir and + al_get_entry_name. + +Other: + + • Many bug and documentation fixes. + +Changes from 4.9.9 to 4.9.9.1 (March 2009) +****************************************** + + • Made it compile and work with MSVC and MinGW 3.4.5. + + • Enabled SSE instruction set in MSVC. + + • Fixed X11 XIM keyboard input (partially?). + + • Fall back on the reference (software) rasterizer in D3D. + +Changes from 4.9.8 to 4.9.9 (March 2009) +**************************************** + +The main developers this time were: Trent Gamblin, Evert Glebbeek, Milan +Mimica, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions +from: Todd Cope, Angelo Mottola, Trezker. + +Graphics: + + • Added display options API and scoring, based on AllegroGL, for + finer control over display creation. + + • Added API to query possible display formats (implemented on X, Mac + OS X). + + • Changed the bitmap locking mechanism. The caller can choose a + pixel format. + + • Added support for multisampling. + + • Simplified the semantics of al_update_display_region(). + + • Optimised software blitting routines. + + • Optimised al_map_rgb/al_map_rgba. + + • Replaced al_draw_rectangle() and al_draw_line() from core library + with al_draw_rectangle_ex() and al_draw_line_ex() from the + primitives addon. + + • Implemented al_wait_for_vsync() everywhere except WGL. + + • Fixed problems with sub-bitmaps with the OpenGL driver. + + • Fixed bugs in software scaled/rotated blit routines. + + • Added a new pixel format ALLEGRO_PIXEL_FORMAT_ABGR_F32. Removed + ALLEGRO_PIXEL_FORMAT_ANY_15_WITH_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_24_WITH_ALPHA. + + • Added support for creating OpenGL 3.0 contexts (untested; only + WGL/GLX for now). Relevant display flags are ALLEGRO_OPENGL_3_0 + and ALLEGRO_OPENGL_FORWARD_COMPATIBLE. + + • Allow disabling any OpenGL extensions from allegro.cfg to test + alternative rendering paths. + + • Fixed problem with windows only activating on title bar clicks + (Windows). + + • Fixed a minimize/restore bug in D3D (with the help of Christopher + Bludau). + +Input: + + • Implemented al_set_mouse_xy under X11. + + • Added ALLEGRO_EVENT_MOUSE_WARPED event for al_set_mouse_xy(). + +Path routines: + + • Made al_path_get_drive/filename return the empty string instead of + NULL if the drive or filename is missing. + + • Changed al_path_set_extension/al_path_get_extension to include the + leading dot. + + • Made al_path_get_extension(), al_path_get_basename(), + al_path_to_string() return pointers to internal strings. + +Unicode: + + • Changed type of ALLEGRO_USTR; now you should use pointers to + ALLEGRO_USTRs. + + • Added UTF-16 conversion routines. + +Other core: + + • Added ALLEGRO_GET_EVENT_TYPE for constructing integers for event + type IDs. + + • Renamed configuration function names to conform to conventions. + + • Removed public MIN/MAX/ABS/MID/SGN/CLAMP/TRUE/FALSE macros. + + • Replaced AL_PI by ALLEGRO_PI and documented it as part of public + API. + +Audio addons: + + • Added stream seeking and stream start/end loop points. + + • Add panning support for kcm_audio (stereo only). + +Font addons: + + • Made al_font_grab_font_from_bitmap() accept code point ranges. + + • Made font routines use new UTF-8 routines; lifted some arbitrary + limits. + + • Fixed artefacts in bitmap font and TTF rendering. + +Image I/O addon: + + • Made the capability to load/save images from/to ALLEGRO_FS_ENTRYs + public. + + • Added missing locking to .png save function. + +Other addons: + + • Added native_dialog addon, with file selector dialogs. + + • Fixed many bugs in the primitives addon. + + • Made hsv/hsl color functions accept angles outside the 0..360° + range. + + • Fixed a bug in al_color_name_to_rgb. + +Examples: + + • New programs: ex_audio_props, ex_blend_bench, ex_blend_test, + ex_blit, ex_clip, ex_draw, ex_font_justify, ex_gl_depth, ex_logo, + ex_multisample, ex_native_filechooser, ex_path_test, ex_rotate, + ex_stream_seek, ex_vsync, ex_warp_mouse. (ex_draw demonstrated + known bugs currently.) + + • Updated programs: ex_joystick_events, ex_monitorinfo + ex_pixelformat, ex_scale, ex_subbitmap. + +Build system: + + • Added pkg-config support. .pc files are generated and installed on + Unix. + + • Allowed gcc to generate SSE instructions on x86 by default. For + Pentium 2 (or lower) compatibility you must uncheck a CMake option + before building Allegro. + +Other: + + • Many other bug fixes. + +Changes from 4.9.7.1 to 4.9.8 (February 2009) +********************************************* + +The main developers this time were: Thomas Fjellstrom, Trent Gamblin, +Evert Glebbeek, Matthew Leverton, Milan Mimica, Elias Pschernig, Paul +Suntsov, Peter Wang. + +General: + + • Lots of bug fixes. + +File system hooks: + + • Rationalised file system hook functions. Failure reasons can be + retrieved with al_get_errno(). + + • Enable large file support on 32-bit systems. + + • Converted the library and addons to use file system hook functions. + +Path functions: + + • Added al_path_clone(), al_path_make_canonical(), + al_path_make_absolute(), al_path_set_extension(), + al_{get,set}_org_name, al_{get,set}_app_name} functions. + + • Made al_path_get_extension() not include the leading “.” of the + extension, + + • Add AL_EXENAME_PATH, AL_USER_SETTINGS_PATH, AL_SYSTEM_SETTINGS_PATH + enums for al_get_path(). + +String routines: + + • Added a new, dynamically allocating UTF-8 string API. This uses + bstrlib internally, which is distributed under a BSD licence. + Allegro 5 will expect all strings to be either ASCII compatible, or + in UTF-8 encoding. + + • Removed many old Unicode string functions. (Eventually they will + all be removed.) + +Config routines: + + • Clarified behaviour of al_config_add_comment, al_config_set_value + with regards to whitespace and leading comment marks. + +Graphics: + + • Bug fixes on Windows and Mac OS X for resizing, switching away, + setting full screens, multi-monitor, etc. + + • Added an al_get_opengl_texture() convenience function. + + • Added separate alpha blending. + + • Added ALLEGRO_PIXEL_FORMAT_ANY. + + • Honour al_set_new_window_position() in X11 port. + + • Made the X11 port fail to set a full screen mode if the requested + resolution cannot be set rather than falling back to a windowed + mode. + +Input: + + • Added a field to the mouse state struct to indicate the display the + mouse is currently on. + + • Made DirectX enumerate all joysticks/gamepads properly by using a + device type new to DirectInput 8. + + • Fixed a bug in wmouse.c where y was not changed in al_set_mouse_xy. + + • Support ALLEGRO_EVENT_MOUSE_ENTER/LEAVE_DISPLAY events in Windows. + +Addons: + + • Added a primitives addon. + + • Revamp interface for kcm_audio addon to make simple cases easier. + + • Added native .wav support and save sample routines to acodec addon. + + • Added a colors addon. + + • Added memory file addon and example. + +TTF addon: + + • Added al_ttf_get_text_dimensions() function. + + • Allow specifying the font size more precisely by passing a negative + font size. + + • Guess the filenames of kerning info for Type1 fonts. + +Documentation: + + • Added a new documentation system using Pandoc. Now we can generate + HTML, man, Info and PDF formats. + + • Added and fixed lots of documentation. + +Examples: + + • Added ex_prim, ex_mouse_focus examples. + + • Made ex_blend2 more comprehensive. + + • Updated ex_get_path example. + + • Made ex_ttf accept the TTF file name on the command line. + +Build system: + + • Use official CMAKE_BUILD_TYPE method of selecting which build + configuration. This should work better for non-make builds, + however, it’s no longer possible to build multiple configurations + with a single configuration step as we could previously. + +Removals: + + • Remove outdated A4 tools. + + • Remove icodec addon. + + • SCons build was unmaintained and not working. + +Changes from 4.9.7 to 4.9.7.1 (December 2008) +********************************************* + + • Scan aintern_dtor.h for export symbols, needed for MSVC. + +Changes from 4.9.6 to 4.9.7 (December 2008) +******************************************* + +The main developers this time were: Trent Gamblin, Evert Glebbeek, Peter +Hull, Milan Mimica, Peter Wang. + +Graphics: + + • Fixed a bug where the “display” field of a bitmap was not correctly + reset when it was transfered to another display on OS X. + + • Made al_create_display() respect al_set_new_window_position() on OS + X. + + • Fixed the bug that caused input focus to be lost in OS X when a + window was resized. + + • Made resizable Allegro windows respond properly to the green “+” + button at the top of the screen on OS X. + + • Properly implemented fullscreen resize in WGL. + + • Made the memory blenders work the same as the hardware ones. + + • Made al_get_pixel()/al_draw_pixel() handle sub bitmaps in case the + bitmap was locked. + + • In the OpenGL driver, if the bitmap is locked by the user, use + memory drawing on the locked region. + + • Added implementations of al_inhibit_screensaver() for the X and Mac + OS X ports. + + • Added multi-monitor support to Mac OS X port (untested!). + + • Other fixes. + +Input: + + • Made al_get_keyboard_state() return structures with the ‘display’ + field correctly set. + + • Made keyboard event member ‘unichar’ uppercase when Shift/CapsLock + is on, in Windows. + + • Made mouse cursor show/hide work with Mac OS X full screen. + +Config routines: + + • Preserve comment and empty lines in config files when writing. + +Addons: + + • Add a simple interface layer for kcm_audio. + + • Made kcm_audio objects automatically be destroyed when it is shut + down. + + • Renamed functions in kcm_audio to conform better with the rest of + the library. + + • Made the TTF addon aggregate glyph cache bitmaps into larger + bitmaps for faster glyph rendering (less source bitmap switching). + +Examples: + + • Add an example to test the ALLEGRO_KEYBOARD_STATE ‘display’ field. + + • Add an example for testing config routines. + + • Add an example for checking software blending routines against + hardware blending. + + • Add an example for the simple interface for kcm_audio. + +Changes from 4.9.5 to 4.9.6 (November 2008) +******************************************* + +The core developers this time were: Thomas Fjellstrom, Trent Gamblin, +Evert Glebbeek, Peter Hull, Milan Mimica, Jon Rafkind, Peter Wang. + +Allegro 4.9.6 and onwards are licensed under the zlib licence (see +LICENSE.txt). This is a simple permissive free software licence, close +in spirit to the ‘giftware’ licence, but is clearer and more well-known. + +General: + + • Added filesystem hook (fshook) and path API functions. + + • Many minor bug fixes. + +Graphics: + + • Added allegro5/a5_opengl.h, which has to be included by programs to + use OpenGL specifics. ALLEGRO_EXCLUDE_GLX and ALLEGRO_EXCLUDE_WGL + can be #defined to exclude GLX and WGL OpenGL extensions + respectively. + + • Added allegro/a5_direct3d.h, which has to be included by programs + to use D3D specifics. + + • Fixed some drawing from and onto sub-bitmaps. + + • Fixed blending with the wrong color in case of sub-bitmaps. + + • Fixed a bug in the D3D driver where the transformation matrix was + not reset after drawing a bitmap. + + • Added draw pixel to OpenGL driver. + + • Added more OpenGL extensions. + + • Added function to inhibit screen saver (currently Windows only). + +Config routines: + + • Added al_config_create(). + + • Deleted al_config_set_global(). Made empty section name equivalent + to the global section. + + • Read system wide and home directory config files on Unix (Ryan + Patterson). + +Events: + + • Added support for injecting user-defined events into event queues. + +Audio addon: + + • Made the ALSA driver read the device name from the config file + (Ryan Patterson). + +Examples: + + • Added ex_subbitmap example. + + • Added ex_disable_screensaver example. + +Build system: + + • Rationalised library names and made CMake and SCons build systems + agree on the names. + +Changes from 4.9.4 to 4.9.5 (October 2008) +****************************************** + +The core developers this time were: Trent Gamblin, Evert Glebbeek, Peter +Hull, Milan Mimica, Elias Pschernig, Jon Rafkind, Peter Wang. + +Graphics: + + • Added fullscreen support on Mac OS X. + + • Added support for resizable windows on Mac OS X. + + • Made frameless windows respond to events on Mac OS X. + + • Fixed a problem with D3D blending. + + • Made D3D driver work on systems without hardware vertex processing. + + • Made WGL driver fail more gracefully. + + • Implemented sprite flipping for OpenGL drivers (Steven Wallace). + + • Added al_is_sub_bitmap() function. + +Input: + + • Fixed input with multiple windows on Windows. + + • Fixed keyboard autorepeat events in X11. + + • Added al_is_keyboard_installed(). + + • Fixed key shifts on Windows (ported from 4.2). + + • Fixed mouse button reporting on Mac OS X. + + • Implemented system mouse cursors on MacOS X. + + • Fixed mouse cursors with alpha channels on X11. + + • Some work on Mac OS X joystick support (incomplete). + +Events: + + • Simplified internals of events system further. At the same time, + this change happens to also allow event queues to grow unboundedly. + (You should still avoid letting them get too big, of course.) + +Audio addons: + + • Made ALLEGRO_STREAM objects emit events for empty fragments that + need to be refilled. + + • Added a possiblity to drain a stream created by + al_stream_from_file(). + + • Added a function to rewind a stream. + + • Added gain support to ALLEGRO_STREAM and ALLEGRO_SAMPLE objects. + + • Made it possible to attach a sample to a mixer that isn’t already + attached to something. + + • Fixed Ogg Vorbis loader on big-endian systems. + + • Made the OpenAL driver the least preferred driver, as it doesn’t + play stereo samples properly. + +Image addons: + + • Added JPEG support to iio addon, using libjpeg. + + • Fixed TGA loader on big-endian systems. + + • Fixed image loading in icodec addon. + +Font addon: + + • Fixed count-restricted text output functions calculations on + non-ASCII strings. + + • Made al_textout* functions always a ‘count’ parameter. + + • Renamed al_font_text_length* to al_font_text_width*. + + • Harmonised the order of al_font_textout* and al_font_textprintf* + arguments. + +Examples: + + • Added ex_bitmap_flip example (Steven Wallace). + + • Added ex_mixer_chain example. + + • Split ex_events into smaller examples. + + • Made the demo use ALLEGRO_STREAM to play music. + + • Build an app bundle from the demo, on Mac OS X. + +Build system: + + • Improved detection of external dependencies in CMake build. + + • Guess compiler locations for MinGW and MSVC (CMake). + + • Many improvements to scons build, including install support. + +General: + + • Many other bug fixes. + +Changes from 4.9.3 to 4.9.4 (September 2008) +******************************************** + +The core developers this time were: Trent Gamblin, Peter Hull, Milan +Mimica, Elias Pschernig and Peter Wang. Ryan Dickie and Jon Rafkind +also contributed. + +General: + + • Many bug fixes all around. + + • Added a public threads API. + + • Added a basic configuration API. + + • Added al_store_state/al_restore_state functions. + + • Added al_get_errno/al_set_errno (not used much yet). + + • Renamed some functions/structures to be more consistent. + + • Code formatting improvements. + + • Added more debugging messages. + + • Removed a lot of A4 code that is no longer used. + +Graphics: + + • Added support for some new OpenGL extensions. + + • Multihead support on Windows (preliminary support on OSX and + Linux). + + • Many enhancements to all drivers. + + • Merged common parts of WGL and D3D drivers. + + • Borderless windows, setting window positions and titles. + + • Fullscreen support on OSX and Linux. + + • Do not clear bitmaps when they are created. + + • Improved compile times and DLL sizes by simplifying “memblit” + functions. + + • Added EXPOSE, SWITCH_IN and SWITCH_OUT display events. + +Build system: + + • Many bug fixes and enhancements to SCons and CMake build systems. + + • Support for Turbo C++ 2006. + + • Support for cross-compiling on Linux to MinGW (CMake). + +Events: + + • Filled in a display field for all relevant events. + + • Added al_wait_for_event_until. + +Addons: + + • Added an ImageMagick addon + + • Added iio (Image IO) addon + + • Supports BMP, PCX, TGA. + + • Supports PNG support with libpng. + + • Added new audio addon, kcm_audio. (The ‘audio’ addon was taken in + a new direction between the 4.9.3 and 4.9.4 releases, but we + decided against that, so actually it’s actually a continuation of + the old audio addon.) + + • Added audio streaming functionality. + + • Added OSS, ALSA, DirectSound drivers. + + • A lot of reorganisation, internally and externally. + + • Added TTF font addon, using FreeType. + + • Made all addons use “al_” prefix. + +Examples: + + • Lots of new examples. + + • Wait for keypress in some examples instead of arbitrary delay. + + • Clean up files when done in some examples. + +Changes from 4.9.2 to 4.9.3 (April 2008) +**************************************** + +Graphics: + + • Milan Mimica did lots of work on the OpenGL drivers, such as adding + an OpenGL driver for Windows and making the OpenGL code shared + between platforms. + + • Peter Hull added an OpenGL graphics driver for Mac OS X. + + • Milan Mimica made the OpenGL driver share contexts between + displays. + + • Peter Wang and Milan Mimica made the OpenGL driver work with cards + that don’t support non-power-of-two (NPOT) textures. + + • Trent Gamblin added support for NPOT textures in the Direct3D + driver. + + • Trent Gamblin fixed blending in memory drawing functions. + + • Trent Gamblin added al_draw_pixel() which obeys blending. + + • Trent Gamblin made al_clear() not affected by blending in D3D. + + • Milan Mimica added the following functions to the public API: + al_opengl_version(), al_is_opengl_extension_supported(), + al_get_opengl_proc_address(), al_get_opengl_extension_list(). + + • Milan Mimica added sub-bitmaps support for memory bitmaps and in + the OpenGL display driver. + + • Milan Mimica made displays keep a list of bitmaps. When destroying + a display its bitmaps will be managed properly, e.g. converted to + memory bitmaps if necessary. All display bitmaps will be + automatically destroyed on exit. + + • Peter Wang made X window resizing work without GLX 1.3. + + • Trent Gamblin fixed a bug in the Direct3D driver when windows were + minimized (thanks to David McCallum). + + • Trent Gamblin fixed the coordinates of Direct3D primitives to match + OpenGL style. + + • Peter Hull fixed some logic in bitmap drawing and al_load_bitmap(). + +Fonts: + + • Milan Mimica made font drawing faster, by making glyphs sub-bitmaps + of a larger glyph sheet. + + • Milan Mimica and Peter Wang made font loading faster. + + • Trent Gamblin added versions of text output functions which take as + an explicit argument the length of the strings. + +Audio: + + • A new audio API implementation, originally by Chris Robinson, was + added (currently as an addon only). It has received additional + work in the past from Milan Mimica and recently much work from Ryan + Dickie. + + • Ryan Dickie also added an acodec addon, which has loaders for FLAC, + Wave and Ogg Vorbis files, using other libraries. + +Timers: + + • Ryan Dickie changed the type of timestamps throughout the API from + int expressed in milliseconds to double expressed in seconds and + improved timer resolution on Windows. + + • Ryan Dickie added an ‘error’ field to the timer event, and added + error and overhead statistics to exnew_timer. + + • Trent Gamblin made the Windows timer use QueryPerformanceCounter. + + • Peter Wang split al_wait_for_event() into two functions, a version + that takes a timeout and a version that doesn’t. + + • Trent Gamblin merged the Windows and Unix timer source files. + +Input: + + • Peter Wang renamed some joystick and timer functions to adhere to + the ‘al_<verb>_<noun>’ convention. + + • Peter Wang made al_num_joysticks() more lenient if there is no + joystick driver installed. + +Other: + + • David Capello added support for various different BMPs. + + • Elias Pschernig fixed compilation of the X port in case the + XVidMode extension is unavailable (thanks to Thomas Fjellstrom). + + • Elias Pschernig added a exnew_timer example. + + • Trent Gamblin added exnew_multiwin and exnew_drawpixels. + + • Peter Wang added exnew_timedwait and exnew_scale. + + • Jon Rafkind and Elias Pschernig updated the SCons build. + + • Jon Rafkind added a ‘_s’ suffix to static libraries in the SCons + build. + + • Elias Pschernig did some work on cross-compilation with SCons and + MinGW. + + • Milan Mimica made the CMake build work with MSVC project solutions + and made the library build with MSVC 8. + + • Jacod Dawid added a nicer spaceship graphic for a5teroids demo. + + • Many more bug fixes and documentation updates. + +Changes from 4.9.1 to 4.9.2 (November 2007) +******************************************* + +_This list is still to be summarised._ + + • Trent Gamblin made the mouse cursor always hide when the user calls + al_hide_mouse_cursor in fullscreen (D3D). + + • Trent Gamblin fixed some signedness warnings and implemented + show/hide_mouse in the display vtable for D3D. + + • Elias Pschernig made show/hide cursor use the display driver + instead of the 4.2 gfx_driver. + + • Elias Pschernig fixed missing keyboard events in exnew_mouse_events + example. + + • Elias Pschernig wired the X11 mouse driver to the XGLX system + driver. + + • Jon Rafkind made various fixes to get the OSX build to compile + + • Trent Gamblin added exnew_mouse_events. + + • Trent Gamblin added exnew_mouse. + + • Jon Rafkind made the scons build get the library name dynamically. + + • Jon Rafkind made the scons build link Allegro using -l instead of + using the full path. + + • Trent Gamblin added a note about MINGDIR in readme_a5.txt. + + • Trent Gamblin removed -lalleg_unsharable from allegro-config.in, + since assembly is not used anymore. + + • Jon Rafkind fixed up allegro-config. + + • Trent Gamblin added some documentation on ALLEGRO_MSESTATE. + + • Trent Gamblin listed the examples in readme_a5.txt. + + • Trent Gamblin improved some inline documentation. + + • Jon Rafkind removed /lib from install path in unix.scons. + + • Jon Rafkind added the new demo to the scons build and allowed + addons to be built statically or shared. + + • Trent Gamblin made the glx line drawing function use blending. + + • Trent Gamblin added cmake instructions to readme_a5.txt. + + • Elias Pschernig added readme_a5.txt. + + • Trent Gamblin fixed warnings in the demo. + + • Trent Gamblin fixed a crash-on-exit bug in tls.c. + + • Trent Gamblin replaced the old demo with a temporary one. + + • Peter Wang fixed gcc string warnings. + + • Peter Wang added some assertions to display_new.c. + + • Peter Wang merged changes from the 4.2 branch. + + • Elias Pschernig removed an unnecessary import from the naturaldocs + upload script. + + • Elias Pschernig added a script to automatically upload the + naturaldocs generated documentation to the website. + + • Peter Wang fixed missed renamings from AL_ to ALLEGRO_ in the Linux + and X code. + + • Elias Pschernig merged 4.9-newgfx back to 4.9. + + • Peter Wang fixed a "ALLEGRO__JOYSTICK" typo. + + • Trent Gamblin renamed AL_ to ALLEGRO_ in input, events, and timer + code. + + • Elias Pschernig implemented outline flag and blending for + draw_rectangle in the GLX driver. + + • Elias Pschernig added another mysha.pcx for the font example. + + • Elias Pschernig re-added GLX checked to scons build which went + missing in the merge. + + • Elias Pschernig added icon.xpm which went missing in the merge. + + • Peter Wang replaced _al_draw_bitmap_region_memory_fast with + _al_draw_bitmap_region_memory. + + • Trent Gamblin made memblit.c compile a little faster in debug mode. + + • Peter Wang mergedd changes in r7948:10859 on 4.9 branch to + 4.9-newgfx branch. + + • Peter Wang enabled WANT_D3D by default. Only set ALLEGRO_D3D on + Windows. + + • Trent Gamblin made al_acknowledge_resize take the display as a + parameter. + + • Trent Gamblin fixed some warnings and made the MinGW build + compilable statically with gcc 4.2.1. + + • Peter Wang fixed a bug in ALLEGRO_CONVERT_BGR_565_TO_ARGB_4444. + + • Peter Wang renamed al_memory_management_functions() to + al_set_memory_management_functions() and added some extra + documenation for it. + + • Peter Wang removed NaturalDocs markup for Allegro 4.x display + functions. + + • Peter Wang made OpenGL libraries link if building with X11 support. + + • Peter Wang fixed a signedness warning. + + • Peter Wang made al_destroy_bitmap return immediately when passed a + null pointer instead of segfaulting. + + • Elias Pschernig made some cosmetic improvements to the code. + + • Elias Pschernig removed a bad optimization. + + • Elias Pschernig removed > GLX 1.1 specific code. + + • Trent Gamblin fixed several of the floating point unmapping + functions that were doing integer division. + + • Elias Pschernig implemented blending in the GLX driver. + + • Elias Pschernig fixed GLX rotation to use radians and allow + negative angles. + + • Elias Pschernig implemented rotated blitting in the GLX driver. + + • Jon Rafkind made scons install addons/font. + + • Jon Rafkind added a scons file for addons. + + • Jon Rafkind used target_scanner to find makedoc instead of using + Depends. + + • Jon Rafkind forced makedoc to be a dependancy of the docs. + + • Trent Gamblin made 60hz the default refresh rate of the D3D driver. + + • Trent Gamblin changed al_create_mouse_cursor to accept + ALLEGRO_BITMAP structures. + + • Trent Gamblin renamed __al_unmap_rgba to al_unmap_rgba_ex in the + glx driver. + + • Trent Gamblin made al_(map|unmap)_rgb(a)_*_ex public. + + • Trent Gamblin made D3D windows show the resize cursor when resizing + windows. + + • Jon Rafkind added allegro includes for asmdef. + + • Jon Rafkind erased older build demo target. + + • Jon Rafkind added the demo to the scons build. + + • Jon Rafkind made it so assembly files can be built statically. + + • Jon Rafkind made scons always build asmdef. + + • Trent Gamblin made al_acknowledge_resize and al_resize_display + adjust clipping in the D3D driver. Mad eal_set_current_display + + • Trent Gamblin used higher compatibility flags to Direct3DCreate9, + made D3D driver die more gracefully on unsupported configurations, + removed flags from draw_line, and did more error checking. + + • Trent Gamblin turned al_init macros into an inline function. + + • Trent Gamblin commented out a TRACE line that was causing the + entire log to be overwritten. + + • Peter Wang fixed an incorrect call to _al_vector_find_and_delete. + + • Peter Wang made various formatting fixes. + + • Peter Wang converted CR/LF line endings to LF. + + • Trent Gamblin added NaturalDocs for the graphics api. + + • Trent Gamblin fixed an instance where a variable could have been + used uninitialized. + + • Trent Gamblin fixed texture coordinates in the D3D driver. + + • Trent Gamblin fixed formatting and an improper assertion. + + • Trent Gamblin removed a redundant call to al_set_target_bitmap. + + • Trent Gamblin fixed a bug in the DX joystick code that caused it to + assert when it shouldn’t. + + • Trent Gamblin made al_create_display call al_flip_display so the + window is cleared. + + • Trent Gamblin made the D3D driver work where render-to-texture is + not supported. + + • Trent Gamblin removed masking support completely. + + • Elias Pschernig got the font example working with the GLX driver. + + • Elias Pschernig renamed the font addon in the scons build. + + • Jon Rafkind made scons build modules in a separate directory. + + • Jon Rafkind bumped the version to match cmake. + + • Jon Rafkind fixed esd to be like the other unix modules. + + • Trent Gamblin changed color map and unmap functions to use the + target bitmap. + + • Trent Gamblin added the font example to the cmake build process. + + • Elias Pschernig added the font example to the scons build process. + + • Elias Pschernig removed special handling of “src” dir, and made + various cosmetic changes. + + • Trent Gamblin made cmake install to MINGDIR. + + • Trent Gamblin added a better font and example for the bitmap font + addon. + + • Trent Gamblin removed unix header from install on other platforms. + + • Trent Gamblin added a bitmap font addon. + + • Trent Gamblin fixed a locking bug in the D3D driver. + + • Elias Pschernig removed masking from the GLX driver. + + • Trent Gamblin implemented blending for memory bitmaps (very slow + unless the blend mode is ALLEGRO_ONE,ALLEGRO_ZERO with a pure white + blend color). + + • Trent Gamblin implemented blending for the D3D driver. + + • Trent Gamblin added + ALLEGRO_PIXEL_FORMAT_ANY_(15|16|24|32)_(WITH_ALPHA|NO_ALPHA) + formats, used ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA in locking + examples, and ixed some formatting. + + • Trent Gamblin added al_clone_bitmap which makes an exact copy of + the color-data of a bitmap. + + • Trent Gamblin added a ALLEGRO_KEEP_BITMAP_FORMAT flag that forces + Allegro to use the same format as the disk file when loading + bitmaps. + + • Elias Pschernig implemented video bitmap masking for the GLX driver + (by converting to alpha textures and drawing with alpha blending). + + • Elias Pschernig fixed clipping in the GLX driver. + + • Trent Gamblin removed ALLEGRO_MASK_SOURCE flag in favor of + ALLEGRO_USE_MASKING. Mask color is now a bitmap property. Removed + ALLEGRO_NO_ALPHA flag and changed the meaning of ALLEGRO_USE_ALPHA + to mean do alpha blending or not. Added + al_set/get_bitmap_mask_color and removed al_set/get_mask_color. + New masking example added (exnew_masking). + + • Trent Gamblin added proper clipping to al_put_pixel. + + • Trent Gamblin renamed graphics stuff from AL_ to ALLEGRO_ and + removed patterned drawing. + + • Elias Pschernig implemented clipping for the X11 GLX driver (only + for screen so far). + + • Trent Gamblin removed unused set_bitmap_clip entry from the bitmap + vtable. + + • Trent Gamblin made clipping always enabled and made the clipping + functions operate on the current target bitamp. + + • Trent Gamblin removed src/compat/coblit.c. + + • Trent Gamblin renamed scroll_display to scroll_screen in display.c + + • Trent Gamblin Removed commented code from src/display.c. Removed + include/allegro/display.h and src/compat/cogfx.c + + • Elias Pschernig renamed XDUMMY driver to XGLX. + + • Elias Pschernig made some cosmetic changes. + + • Elias Pschernig made exblend work over the compatibility screen. + + • Elias Pschernig implemented upload_compat_screen method in the GLX + driver. + + • Elias Pschernig optimized al_lock_bitmap/al_unlock_bitmap slightly. + + • Elias Pschernig added a flags parameter to the drawing primitives + methods. + + • Trent Gamblin added flags to primitives in display vtable and + renamed draw_filled_rectangle vtable entry to draw_rectangle. + + • Elias Pschernig implemented AL_SINGLEBUFFER flag and fixed bug with + AL_FULLSCREEN in the GLX driver. + + • Trent Gamblin added a mode parameter to al_set_drawing_pattern. + + • Trent Gamblin added AL_OUTLINED flag that is the default for + primitives. + + • Trent Gamblin added al_set_drawing_pattern and + al_get_drawing_pattern, added a flags parameters to all the + primitive drawing functions that can be: AL_FILLED, AL_PATTERNED, + and added hline and vline functions for memory bitmaps. + + • Trent Gamblin ifdefed d3d stuff in win/wnewsys.c. + + • Trent Gamblin removed d3dx9 library from CMakeLists.txt. + + • Trent Gamblin ifdefed Direct3D stuff in display.c. + + • Jon Rafkind made scons read win32 files from cmake file list. + + • Trent Gamblin added al_wait_for_vsync and made it work with the D3D + driver. + + • Elias Pschernig implemented immediate-resize for al_resize_display, + and implemented fullscreen resizing. + + • Trent Gamblin added al_enable_bitmap_clip and + al_is_bitmap_clip_enabled, added al_create_sub_bitmap, and made it + work with D3D and memory bitmaps. + + • Elias Pschernig improved fullscreen handling. + + • Elias Pschernig added shutdown_system vtable entry to the system + driver, and automatically call it on program exit. This allows + unsetting fullscreen modes in the X11 driver. + + • Trent Gamblin added al_set_bitmap_clip and al_get_bitmap_clip, and + made them work with D3D and memory bitmaps. + + • Elias Pschernig added XF86Vidmode fullscreen modes. + + • Elias Pschernig added xdummy files to cmake files list. + + • Elias Pschernig made al_resize_display work on non-resizable + windows. + + • Elias Pschernig fixed opengl setup being issued in wrong thread. + + • Elias Pschernig moved src/misc/colconv.c from windows sources to + general sources. + + • Elias Pschernig uncommented accidentally commented out line. + + • Elias Pschernig made scons read the list of source files from + cmake/FileList.cmake, so there’s only one place to add new files. + + • Trent Gamblin made _al_get_pixel_value faster. + + • Trent Gamblin made al_unmap_rgba_i use a table instead of relying + on al_unmap_rgba_f. + + • Peter Wang changed #includes to use file names from the root of the + include hierarchy, i.e. #include “allegro/internal/foo.h” instead + of #include “internal/foo.h” and likewise for + allegro/platform/foo.h. + + • Peter Wang removed some stray CR characters. + + • Trent Gamblin added al_get_bitmap_width, al_get_bitmap_height, + al_get_bitmap_format, and al_get_bitmap_flags. + + • Trent Gamblin made al_draw_rotated_(scaled_)bitmap only lock the + region of the destination is needs to for memory bitmaps. + + • Trent Gamblin made al_draw_scaled_bitmap use the AL_FLIP_* flags. + + • Trent Gamblin added an example of resizing a fullscreen display. + + • Elias Pschernig updated xdummy driver and implemented + al_resize_display for it. + + • Elias Pschernig added another testcase. + + • Trent Gamblin added al_get_display_width and al_get_display_height, + made al_get_display_* work on the current display, and renamed + al_notify_resize to al_acknowledge_resize. + + • Trent Gamblin uncommented everything in cogfx.c (removing the + display parameter). + + • Trent Gamblin made exnew_lockscreen use pitch. + + • Trent Gamblin fixed scaled conversion macros (4444, 555, 565), + added XRGB_8888 pixel format, made windowed mode default, moved + get_num_display_modes and get_display_mode into the system vtable. + + • Trent Gamblin made exnew_lockbitmap use pitch. + + • Trent Gamblin fixed D3D unlocking bug, and used desktop format in + windowed mode if not specified. + + • Elias Pschernig fixed a bug where events reported the wrong source + display under X11. + + • Elias Pschernig added three simple test cases. + + • Elias Pschernig fixed al_lock_bitmap and al_unlock_bitmap + implementation in the xdummy driver (for now it works in a slow + way). + + • Trent Gamblin made al_notify_resize return success/failure and + added al_resize_display to resize the display from code. + + • Elias Pschernig started implementing lock_region and unlock_region + for the xdummy driver. + + • Elias Pschernig split xdraw.c out of xdisplay.c, used _AL_THREAD + instead of pthreads in the xdummy driver, added a lock to the + xdummy driver, in order to implement al_destroy_display, used the + correct format. + + • Elias Pschernig fixed a comment typo. + + • Elias Pschernig fixed a typo in AL_CONVERT_PALETTE_8_TO_ABGR_8888. + + • Trent Gamblin improved D3D line drawing, added + al_get_num_display_modes and al_get_display_mode, and cleaned up & + organized some code. + + • Trent Gamblin removed _al_win_delete_from_vector. + + • Trent Gamblin added draw_memory_bitmap_region vtable hook to + AL_DISPLAY. + + • Elias Pschernig implemented enough of the xdummy driver to run + exnewap (doesn’t display correctly yet though). + + • Elias Pschernig updated scons build files. + + • Elias Pschernig Removed windows specific includes from exnewapi.c. + + • Elias Pschernig added missing al_convert_mask_to_alpha prototype. + + • Peter Wang fixed src/tls.c to compile under Linux (not tested). + + • Trent Gamblin put TLS support back in for MSVC and UNIX. + + • Trent Gamblin cleaned up some code, added headers to new source + files, grouped thread local variables into one structure (UNIX + support is broken for now), and made mask color thread local. + + • Trent Gamblin added clear, filled rectangle, and line for memory + bitmaps. + + • Trent Gamblin made it so the system driver is no longer hard coded, + added switch_out method to display vtable, made the D3D window and + system driver code generic. + + • Trent Gamblin merged 4.9-elias and 4.9-trentg into 4.9-newgfx. + + • Elias Pschernig adjusted prototype of _al_init to implementation. + + • Elias Pschernig fixed a bogus cast. + + • Elias Pschernig fixed typo in al_get_new_diplay_format for + non-mingw. + + • Trent Gamblin made display and bitmap parameters local to the + calling thread. + + • Trent Gamblin added al_draw_rotated_bitmap and + al_draw_rotated_scaled_bitmap for memory bitmaps using Allegro’s + software rotation code as a base. + + • Trent Gamblin ported a stretch blit fix from 4.2, made al_init call + allegro_init, made al_draw_bitmap(_region) much faster on memory + bitmaps, and added al_draw_scaled_bitmap for memory bitmaps. + + • Trent Gamblin renamed AL_LOCKED_RECTANGLE to AL_LOCKED_REGION, and + started on memory bitmaps (al_draw_bitmap and al_draw_bitmap region + work). + + • Trent Gamblin made seperate functions for getting/setting + display/bitmap parameters, made backbuffer-as-source bitmap work in + D3D, and changed parameter ordering of some functions. + + • Trent Gamblin added al_is_compatible_bitmap removed dependancy on + Allegro’s 3D math functions from the D3D driver. + + • Trent Gamblin added al_convert_mask_to_alpha, made put/get_pixel + faster if the bitmap is locked ahead of time, and brought back + AL_MASK_SOURCE. + + • Trent Gamblin committed various bugfixes, implemented the RGB + mapping/unmapping functions from Bob’s API. + + • Trent Gamblin removed the D3DX library dependancy. + + • Trent Gamblin committed various bugfixes and got all of the + examples working with the D3D driver. + + • Trent Gamblin fixed some of the compatibility conversions. + + • Trent Gamblin changed the examples back to autodetecting the + graphics driver. + + • Trent Gamblin made fullscreen mode work with the D3D driver, and + non-resizable windows. + + • Trent Gamblin finished bitmap conversion functions, improved + locking, implemented get/put pixel, and made some speed + improvements. + + • Trent Gamblin added a bitmap conversion function. + + • Trent Gamblin got the demo game running in D3D. + + • Trent Gamblin removed an unnecessary bitmap copy. + + • Trent Gamblin added a skeleton D3D driver. + + • Peter Wang fixed the generation of allegro-config under Mac OS. + + • Michael Jensen fixed a mistake in the documenation for + is_compatible_font. + + • Peter Wang fixed wrong variable in example code for load_font(); + + • Trent Gamblin fixed some problems with the cmake build on Windows. + + • Peter Wang removed the second parameter in a call to + _al_event_source_needs_to_generate_event() which was missed + earlier. + + • Peter Wang exposed some internal documentation on destructors, + events and event sources to NaturalDocs. + + • Peter Wang changed al_wait_for_event() so that a timeout value of + “0” means to not wait at all. To wait an indefinite amount of time + the caller should pass the AL_WAIT_FOREVER constant. + + • Peter Wang removed the declarations of al_event_source_set_mask and + al_event_source_mask which were missed in the previous change. + + • Peter Wang removed event masking abilities, that is, for the user + to prevent an event source from generating particular event types. + This was implemented using bitfields which limited the number of + event types to 32. Although the limit could be raised event + masking was probably not very useful anyway. In all, the functions + removed are: al_event_source_mask, al_event_source_set_mask, + al_wait_for_specific_event. The al_wait_for_specific_event() API + also required event types to be bitfields. + + • Peter Wang fixed some spelling mistakes in the examples. + + • Peter Wang bumped the version to 4.9.2. + + • Peter Wang moved allegro/branches/4.3 to allegro/branches/4.9. + + • Ryan Patterson clarified the documentation of stop_sample(). + + • Peter Wang and Trent Gamblin fixed some issues with the CMake + build. The allegro-config script was not generated properly and + liballeg_unsharable wasn’t being installed. + + • Matthew Leverton changed an instance of long long to LONG_LONG and + an LL suffix into a (LONG_LONG) cast, both for MSVC 6. + + • Matthew Leverton submitted a fix for MSVC 6 regarding MSVC’s lack + of a __FUNCTION__ macro. + + • orz, Matthew Leverton, and Peter Wang made the ALLEGRO_USE_C=1 + option to work under MinGW and MSVC. + + • Anthony Cassidy fixed a typo. + + • Peter Wang removed the ‘msvc’ target from the fix.sh help message + as it should not be used by users any more. Added a comment that + it is used by zipup.sh. + + • Anthony ‘Timorg’ Cassidy made d_menu_proc fill up its assigned area + with the gui_bg_color. + +Changes from 4.9.0 to 4.9.1 (March 2007) +**************************************** + +_Note that 4.9.1 was called 4.3.1 when it was originally released._ + + • Added a new mouse and cursor API. The new functions are: + + al_install_mouse, al_uninstall_mouse, al_get_mouse, + al_get_mouse_num_buttons, al_get_mouse_num_axes, al_set_mouse_xy, + al_set_mouse_z, al_set_mouse_w, al_set_mouse_axis, + al_set_mouse_range, al_get_mouse_state, al_mouse_button_down, + al_mouse_state_axis + + al_create_mouse_cursor, al_destroy_mouse_cursor, + al_set_mouse_cursor, al_set_system_mouse_cursor, + al_show_mouse_cursor, al_hide_mouse_cursor + + • Added documentation for some parts of the 4.9 API using the + NaturalDocs generation system. The documentation is nowhere near + as good as a proper manual, but it’s still better than nothing. + + • Added a commented example demonstating the new API + (exnew_events.c). + + • Added CMake and SCons build systems. These are mainly for use by + Allegro developers at present. + + • Various bug fixes and minor changes. + +Changes from 4.2 series to 4.9.0 (July 2006) +******************************************** + +_Note that 4.9.0 was called 4.3.0 when it was originally released._ + +Basically we’re just wrapping up what we have in version control up to +now. See the commit logs if you want details. + +This release introduces a few new subsystems. We have an event system, +a new keyboard API, a new joystick API, a new timer API, and the start +of a new graphics API. All of these are subject to change, as is usual +for a WIP. + +We are maintaining a certain level of source compatibility with the 4.2 +API. If it’s easy to maintain compatibility then we do it, otherwise +compatibility is dropped. Obscure features are more likely to be +dropped. + +This release has had minimal testing on Linux/x86, Windows/x86 (MinGW) +and Windows/x86 (MSVC). It seems to work on some Linux/x86-64 machines +also. Other ports are broken or untested. + +The new functions are as follows (in no particular order). No real +documentation exists at the moment but interesting header files are: +altime.h, display.h, draw.h, events.h, joystick.h, keyboard.h, timer.h. + + • al_current_time al_rest + + • al_create_video_bitmap al_create_system_bitmap al_scroll_display + al_request_scroll al_poll_scroll al_show_video_bitmap + al_request_video_bitmap al_enable_triple_buffer al_create_display + al_set_update_method al_destroy_display al_flip_display + al_get_buffer al_get_update_method al_enable_vsync al_disable_vsync + al_toggle_vsync al_vsync_is_enabled al_blit al_blit_region + al_blit_scaled + + • al_event_source_set_mask al_event_source_mask + + • al_create_event_queue al_destroy_event_queue + al_register_event_source al_unregister_event_source + al_event_queue_is_empty al_get_next_event al_peek_next_event + al_drop_next_event al_flush_event_queue al_wait_for_event + al_wait_for_specific_event + + • al_install_joystick al_uninstall_joystick al_num_joysticks + al_get_joystick al_release_joystick al_joystick_name + al_joystick_num_sticks al_joystick_stick_flags + al_joystick_stick_name al_joystick_num_axes al_joystick_axis_name + al_joystick_button_name al_get_joystick_state + + • al_install_keyboard al_uninstall_keyboard al_get_keyboard + al_set_keyboard_leds al_keycode_to_name al_get_keyboard_state + al_key_down + + • al_install_timer al_uninstall_timer al_start_timer al_stop_timer + al_timer_is_started al_timer_get_speed al_timer_set_speed + al_timer_get_count al_timer_set_count + diff --git a/allegro/CHANGES-5.1.txt b/allegro/CHANGES-5.1.txt new file mode 100644 index 00000000..4e395611 --- /dev/null +++ b/allegro/CHANGES-5.1.txt @@ -0,0 +1,2109 @@ +Allegro changelog for 5.1.x series +Changes from 5.1.13 to 5.1.13.1 (February 2016) +Changes from 5.1.12 to 5.1.13 (January 2016) +Changes from 5.1.11 to 5.1.12 (September 2015) +Changes from 5.1.10 to 5.1.11 (June 2015) +Changes from 5.1.9 to 5.1.10 (May 2015) +Changes from 5.1.8 to 5.1.9 (January 2015) +Changes from 5.1.7 to 5.1.8 (January 2014) +Changes from 5.1.6 to 5.1.7 (May 2013) +Changes from 5.1.5 to 5.1.6 (March 2013) +Changes from 5.1.4 to 5.1.5 (January 2013) +Changes from 5.1.3 to 5.1.4 (October 2012) +Changes from 5.1.2 to 5.1.3 (August 2012) +Changes from 5.1.1 to 5.1.2 (May 2012) +Changes from 5.1.0 to 5.1.1 (February 2012) +Changes from 5.0.x to 5.1.0 (November 2011) +Allegro changelog for 5.1.x series +********************************** + +See ‘changes-5.0.txt’ for changes in Allegro 5.0.x. These lists serve +as summaries; the full histories are in the git repository. + +Changes from 5.1.13 to 5.1.13.1 (February 2016) +*********************************************** + +The main developers this time were: SiegeLord. + +Image addon: + + • Fix regression in bitmap loading when compiled under MSVC. + +Changes from 5.1.12 to 5.1.13 (January 2016) +******************************************** + +The main developers this time were: Julian Smythe, Elias Pschernig and +Peter Hull. + +Graphics: + + • Add ‘al_get_opengl_program_object’ (SiegeLord). + +Input: + + • Fix spurious triggering of the mouse grab key when it wasn’t + otherwise set (SiegeLord). + +Android port: + + • Avoid multiple HALT/RESUME events on Android (Max Savenkov). + + • Implement ‘al_get_monitor_info’ for Android (Reuben Bell). + + • Fix Android crash on file access. + + • Implement ALLEGRO_FULLSCREEN_WINDOW on Android. + + • Fix crash if display is destroyed while the app is switched out. + + • Add support for x86_64 Android. + + • Add ‘al_android_set_apk_fs_interface’. + +Linux port: + + • Allow using OpenGL ES in X11. + + • Fix the initial display size not being correct sometimes + (SiegeLord). + + • Fix a race condition in the XInput joystick driver (Trent Gamblin). + +OSX port: + + • Fix various memory leaks. + + • Fix ‘al_set_window_title’. + + • Fix a lot of decrepid and deprecated code. + + • Fix single buffer flip display (SiegeLord). + +Windows port: + + • Fix Windows UNC path handling. + + • Fix clipboard nul-termination issues (Trent Gamblin). + + • Set the window title immediately upon window creation (SiegeLord). + +Build system: + + • Define CMAKE_FIND_ROOT_PATH for i686-w64-mingw32 cross compiler + (Martijn van Iersel). + + • Allow building with older CMakes again (SiegeLord). + + • Do not catche compile tests’ failure (Bruce Pascoe). + + • Add a way to statically link the runtime with MinGW (SiegeLord). + + • Don’t link the MSVC C runtime at all when requesting a static + runtime and building a static library (SiegeLord). + +Documentation: + + • Add links to the source code of the definitions of the most API + entries. + + • Fix sidebar generation with modern Pandoc (Boris Carvajal). + +Python: + + • Fix ordering issue for HAPTIC* structs. + + • Fix missing ALLEGRO_PRIM_ATTR_NUM. + +Other: + + • Add a ‘none’ debug level to turn off logging entirely in debug + builds (SiegeLord). + + • Reconfigure logging after the configuration files are loaded + (SiegeLord). + + • Fix al_set_new_window_title() off-by-1 (Bruce Pascoe). + + • Don’t call al_get_time() before system is installed (SiegeLord). + +Audio addon: + + • Add ‘al_get_default_voice’ and ‘al_set_default_voice’. + + • Flush the pulse audio stream rather than draining it, fixing some + audio breaks (SiegeLord). + + • Fill audio stream fragments with silence in the audio addon rather + than in the acodec addon, fixing some garbage output (SiegeLord). + + • Fix possible deadlock when destroying audio streams (SiegeLord). + +Acodec addon: + + • Don’t read past the audio chunk’s end when streaming wav files + (SiegeLord). + + • Turn off allegro_acodec dynamic loading by default, fixing a common + footgun (Bruce Pascoe). + +Image addon: + + • An enormous amount of work supporting reading of esoteric (and not) + BMP format variants (palletted, GIMP-style, etc). New tests were + added using the manual bmp suites. + +Native dialog addon: + + • Update code to work with modern OSX versions. + + • Clean up menu handling on OSX. + +Changes from 5.1.11 to 5.1.12 (September 2015) +********************************************** + +The main developers this time were: Bruce Pascoe, Beoran, Elias +Pschernig, SiegeLord, Trent Gamblin. + +Graphics: + + • Add ‘al_set_blend_color’ and ‘al_set_blender’, for additional + blending modes. + + • Add ‘ALLEGRO_MAXIMIZED’ display flag. + + • Add ‘al_reparent_bitmap’, ‘al_get_bitmap_x/y’. This allows + changing the offset of a sub-bitmap. + + • Make ‘ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA’ actually pick a format + without an alpha channel. + + • Add ‘al_premul_rgba’ and ‘al_premul_rgba_f’ convenience functions + for dealing with pre-multiplied alpha blending mode. + +Input: + + • Fix key auto-repeat on modern X11 versions. + + • Fix mis-detection of some joysticks on Android. + +Android port: + + • Fix a crash when minimizing the app before Allegro has been + initialized. + +iOS port: + +Linux port: + + • Add ‘al_get_x_window_id’ (Robert MacGregor) + +OSX port: + + • Fix some deprecated API usage. + +Windows port: + + • Fix a dangling pointer issue resulting in crashes when resizing on + Windows + 10. +Build system: + + • Build with multiple processors when using MSVC. + + • Make XInput2/touch input optional on Linux. + +Documentation: + + • Various documentation improvements. + + • Fix some badly formatted flags (Rodolfo Lam). + +Other: + + • Allow injecting Allegro events into event queses using + ‘al_emit_user_event’ (Ryan Roden-Corrent) + + • Add ‘al_set_new_window_title’ and ‘al_get_new_window_title’. + + • Add ‘al_get_clipboard_text’, ‘al_set_clipboard_text’ and + ‘al_clipboard_has_text’. + + • Add ‘al_resume_timer’ (Ryan Roden-Corrent). + + • Add ‘al_get_cpu_count’ and ‘al_get_ram_size’. + +Audio addon: + + • Add multiple voice support for the AQueue driver. + + • Fix a bug when ‘al_restore_default_mixer’ was called multiple + times. + +Color addon: + +Font addon: + + • Add ‘al_draw_glyph’, ‘al_get_glyph_width’, + ‘al_get_glyph_dimensions’ and ‘al_get_glyph_advance’. These + functions are useful when additional control is needed when drawing + text. + + • Add ‘al_set_fallback_font’. + +Image addon: + + • Add ‘al_register_bitmap_identifier’, ‘al_identify_bitmap’ and + ‘al_identify_bitmap_f’. This allows detecting the bitmap type by + looking at the initial few bytes in the file rather than relying + solely on the extension. + + • Allow saving bitmaps with uppercase extensions (Daniel). + +Native dialog addon: + + • Fix crashes when creating menus with sub-menus (Todd Cope). + +Video addon: + + • Allow using both Ffmpeg and Theora backends simultaneously. + + • Reduce latency of ‘al_get_video_frame’ for the Theora backend. + + • Make the Theora backend send the ‘ALLEGRO_VIDEO_FRAME_SHOW’ events. + + • Rename ‘al_get_video_width/height’ to + ‘al_get_video_scaled_width/height’ which now return the aspect + corrected size of the video frame. + + • Rename ‘al_pause_video/al_is_video_paused’ to + ‘al_get/set_video_playing’. + + • Add ‘ALLEGRO_EVENT_VIDEO_FINISHED’ event. + + • Remove ‘ALLEGRO_EVENT_VIDEO_FRAME_ALLOC’ event. + + • Remove ‘al_get_video_aspect_ratio’. + +Examples: + + • New examples: ex_reparent, ex_inject_events, ex_clipboard, ex_cpu, + ex_timer_pause. + +Changes from 5.1.10 to 5.1.11 (June 2015) +***************************************** + +The main developers this time were: SiegeLord, Trent Gamblin. + +Input: + + • Rename ‘al_get_haptic_active’ to ‘al_is_haptic_active’ for + consistency. + + • Rename ‘al_get_num_haptic_effects’ to ‘al_get_max_haptic_effects’. + + • Implement the missing ‘al_is_touch_input_haptic’ function. + + • Move the loops parameter of ‘al_upload_and_play_haptic_effect’ + after the id to be consistent with ‘al_play_haptic_effect’. + +OSX port: + + • Fix mouse warping in OSX. + + • Add retina display support to OSX. + +Windows port: + + • Fix querying display modes before creating a display. + + • Make the Windows joystick implementation more fault tolerant. + + • Initialize display callbacks when creating faux fullscreen (Edgar + Reynaldo). + +Build system: + + • Fix the conditional compilation of sal.h (Edgar Reynaldo). + + • Don’t look at WinSDK when we’re not on MSVC, fixing MinGW builds + when MSVC is installed as well. + + • Fix the static FLAC compile tests on Android and Windows. + + • Make the OSX frameworks install in the proper location again. + + • Add ‘WANT_STATIC_RUNTIME’ CMake build option (currently MSVC-only). + +Documentation: + + • Various documentation improvements. + +Other: + + • Return a valid configuration from ‘al_get_system_config’ before + Allegro is installed. This allows you to override the various + configuration options without using an on-disk ‘allegro5.cfg’. + + • Compile in the logging support in release modes by default. Now + logging can be turned on in release builds without recompiling the + program by editing the system configuration. + + • Detect file-overruns when saving configuration files (Bruce + Pascoe). + +Color addon: + + • When converting from YUV to RGB, clamp the returned values between + 0 and 1. + +Video addon: + + • Use an enum in place of magic numbers for ‘al_get_video_position’ + constants. + +Changes from 5.1.9 to 5.1.10 (May 2015) +*************************************** + +The main developers this time were: SiegeLord, Elias Pschernig, Trent +Gamblin, Polybios. + +Input: + + • Add ‘al_set_mouse_wheel_precision’ and + ‘al_get_mouse_wheel_precision’. + +Graphics: + + • Added ‘al_transform_coordinates_3d’. + + • Added ‘al_build_camera_transform’. + + • Make the projection transform a bitmap local state. This removes + ‘al_set_projection_transform’ and ‘al_get_projection_transform’, + and replaces them with ‘al_use_projection_transform’ and + ‘al_get_current_projection_transform’ with similar semantics to the + regular transforms. + +OSX port: + + • Improved joystick axis layouts on Mac OS X, and added support for + some dpards (Max Savenkov). + +X11 port: + + • Fix some memory leaks (ElectricSolstice). + + • Make the XInput2 check more accurate (we require a specific + version). + +Windows port: + + • Remove taskbar hiding on Windows. + + • Fix high precision mice on Windows. + + • Fix some D3D conflicts with the OpenGL backend. + + • Remove the prohibition of building OpenGL-only DLLs. + + • Added LRESULT argument to WindowProc callback, fixing + ‘al_win_add_window_callback’ for some event types (Aaron Bolyard). + +Android port: + + • Fix some memory leaks. + + • Make it possible to specify the Android target during building. + +iOS port: + + • Add an XCode project to help build Allegro when CMake support + fails. + + • Restore the CMake support. + + • Makes the examples run on the iOS simulator out of the box. + + • Various small fixes (Trent Gamblin, jmasterx). + + • Remove ‘al_iphone_get_last_shake_time’ and + a‘l_iphone_get_battery_level’. + + • Hack around iOS not creating mipmaps (jmasterx). + + • If the supported orientation is + ‘ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN’, default to supporting all + orientations. + + • Get Cosmic Protector to compile again. + +Build system: + + • Revamp the detection of DirectX dependencies. Now it should work + out of the box for at least MSVC and mingw-w64. + + • Fix GDIPlus finding script (pkrcel). + + • Bump the minimum version of CMake to 2.8.5. + +Documentation: + + • Many documentation improvements, as always (special thanks to + Polybios). + + • Make the PDF output prettier with better fonts and an up-to-date + version number. + + • Make the Javascript search for online documentation support partial + matches. + + • Make [section] links work in HTML. + + • Allow the docs to have more than 1024 entries (Allegro is getting + huge!). + +Other: + + • Make the test driver a little more resistant to failure. + + • Various fixes to the experimental SDL backend. + + • Update the CONTRIBUTORS.txt. + +Audio addon: + + • Fix deadlock when destroying an audio stream soon after its + creation. + + • Add VOC file support (pkrcel). + + • Disable processing of the XM zero-speed event. + + • Disable processing of module loop points if ‘ALLEGRO_PLAYMODE_ONCE’ + is set. + + • Fix a buffer overflow bug. + +Image addon: + + • Fix loading of indexed + transparent PNGs with the libpng backend. + +Dialog addon: + + • Fix some style issues with the Windows file dialog. + + • Fix a bug with multiple filenames with the Windows file dialog. + + • Change the semantics of the patterns in + ‘al_create_native_file_dialog’ to support future expansion of the + patterns to support both AND and OR style filtering. + + • Make the GTK file selection dialog look like it’s from 2004 (as + opposed to mid-1990s). + +TTF addon: + + • Fix some warnings. + + • Make the page size dynamic, allowing for fonts with up to 8192x8192 + glyphs by default. + +Examples: + + • New examples: ex_camera, ex_projection2. + +Changes from 5.1.8 to 5.1.9 (January 2015) +****************************************** + +The main developers this time were: Trent Gamblin, SiegeLord, Elias +Pschernig. + +Core: + + • Fix OSX backend on OSX 10.10 (lordnoriyuki). + + • Simplify how sub-bitmaps interact with their parent bitmaps. You + can now destroy a sub-bitmap at any time (not only before the + parent is destroyed). Additionally, when the parent is converted + using ‘al_convert_bitmap’, all the sub-bitmaps are also + automatically converted. + + • Switch to using unicode Win32 (e.g. this fixes using + ‘al_set_window_title’ with unicode strings). + + • Add some Linux WM hints so make Allegro windows work more smoothly + (especially with Unity). + +Filesystem: + + • Add ‘al_fprintf’ (DanielH and Tobias Scheuer). + + • Add ‘al_for_each_fs_entry’, a convenience function that helps + enumerating the contents of a directory more easily using a + callback function (Beoran). + + • Fix for ‘al_get_standard_path’ with Unicode (vkensou). + +Input: + + • Add X11 touch driver (Ryan Gumbs). + + • Emulate mouse pressure for backends that don’t support pressure. + + • Added Windows haptics driver, XInput joystick driver (Beoran). + + • Fix OSX joystick deinitialization. + +Graphics: + + • Add block compression pixel formats + (ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1/DXT3/DXT5) for + compressed video bitmaps. This includes an API to fetch compressed + block size (‘al_get_pixel_block_width/height/size’) as well as API + to load and unload compressed bitmap data without paying a runtime + compression cost (‘al_lock_bitmap_blocked’). Unfortunately, due to + patent concerns this last feature is disabled for OpenGL (if you + thinks those concerns don’t apply to you, you can enable it by + passing ‘-DWANT_OPENGL_S3TC_LOCKING=1’ to cmake). + + • Make real fullscreen modes work on OS X again. May not be perfect + still. (thanks to SDL). + +Shaders: + + • Don’t clobber the 0’th texture unit in OpenGL and Direct3D. This + simplifies working with shaders. + +Android port: + + • Bump minimum Android API level from 10 to 12 (aka version 3.1). + + • Add controller support to the Android port. An accelerometer + ‘joystick’ is still the first joystick. Supports two analog sticks + and 10 buttons (A B X Y L1 R1 DPAD_L DPAD_R DPAD_U DPAD_D). + Supports hotplugging and theoretically multiple joysticks (needs + testing). + + • Set correct orientation at startup on Android (thanks to Aikei_c). + +Build system: + + • Various CMake fixes. + +Other: + + • Add Travis and AppVeyor continuous integration support. + + • Fix a lot of memory leaks. + + • Many documentation improvements. + +Audio addon: + + • Disallow attaching a mixer to itself. + + • Fix uni- and bi-directional looping of zero-length samples. + + • Fix/avoid all sound examples freezing on OSX with the aqueue + driver. + +Image addon: + + • Add functionality to load Direct Draw Surface files (.dds). Only + compressed pixel formats are supported (DXT1, DXT3 and DXT5). + +Dialog addon: + + • Fix native file dialog default paths on Windows (Edgar Reynaldo). + + • Fix unintended behaviour in ‘al_set_menu_item_flags’ (Malcolm + Harrow). + + • Fix some bugs with native menus in OSX. + +Video addon: + + • Fix for now undefined AVCODEC_MAX_AUDIO_FRAME_SIZE (Dennis Busch). + +TTF addon: + + • Fix a crashing bug in the TTF addon. + + • Make ‘al_load_ttf_font_stretch’ return NULL if invalid width/height + are passed. + +Font addon: + + • Add multi line text output for the font addon + (‘al_draw_multiline_text’, ‘al_draw_multiline_textf’ and + ‘al_draw_multiline_ustr’). + +Primitives addon: + + • Fix some sharp-angle polyline drawing bugs. + +Examples: + + • New examples: ex_compressed, ex_font_multiline. + + • ex_dir: demonstrate ‘al_for_each_fs_entry’. + + • ex_haptic2: demonstrate hotplugging. + +Changes from 5.1.7 to 5.1.8 (January 2014) +****************************************** + +The main developers this time were: Beoran, SiegeLord, Trent Gamblin, +Markus Henschel, Peter Wang. + +Core: + + • Allow MSVC to use DLL TLS but disable DLL TLS by default. + + • Do not include windows.h via allegro.h. + + • Fix some memory leaks on X11. + +Graphics: + + • Spell ALLEGRO_DST_COLOR, ALLEGRO_INVERSE_DST_COLOR with “DEST” + (with compatibility defines). + + • Fix bug which meant ALLEGRO_INVERSE_SRC_COLOR and + ALLEGRO_INVERSE_DEST_COLOR never actually worked on D3D. + + • Fix horizontal and vertical shears which were not composing with + translations correctly. + + • Optimise al_restore_state if saved target display/bitmap are + unchanged. + + • Fix _al_display_settings_sorter ordering of indexes when scores are + equal. + + • Use a minimum 16x16 texture workaround even on desktop OpenGL. + + • Propagate errors up OpenGL lock bitmap implementations. + + • Use proxy bitmap when locking writable backbuffer regions on GLES. + + • Clean up FBO creation during bitmap locking. + + • Move the half-pixel shift in D3D into the projection matrix. Use + the texture dimensions to compute the half-pixel shift. + + • Fix al_get_d3d_texture_size returning zeros. + + • Remove ALLEGRO_FORCE_LOCKING flag. + + • Setup GL viewport and projection in al_acknowledge_resize on + Android. + + • Improve implementation of display options on Android: use the same + display setting scoring code as other ports; handle SUGGEST display + options properly; map ALLEGRO_COLOR_SIZE to EGL_BUFFER_SIZE + attributes. + +Filesystem: + + • Add al_ferror and al_ferror. Initial patch by Tobias Scheuer. + + • Make al_fclose have a return value. + + • Check al_fclose return value in saving routines. + + • Make al_fopen_fd not leak a FILE handle in a failure path. + + • Make al_make_temp_file allocate temporary buffer to match the + template. + + • android: Interpret the path to APK asset as AssetManager doesn’t. + + • android: Correctly return -1 for APK asset file size if it can’t be + determined. A side-effect is that FreeType (via the TTF addon) can + now load TTFs stored compressed in APK assets. + + • android: Support ungetc on APK file streams. + + • android: Fix EOF handling in AllegroInputStream. + +Input: + + • Initial haptics API, only implemented on Linux to begin with. + + • Use Linux input API for joystick driver instead of deprecated + joystick API. + + • Use Linux joystick driver on Android if OUYA model detected + (Jonathan Lilliemarck). + + • Use thread for hotplugging joysticks on Linux instead of timerfd + (due to Android). + + • Report unichar in KEY_CHAR events on Android. (Todd Cope) + + • Added some Android gaming key codes. + + • iOS touch coordinates need to be multiplied by contentScaleFactor. + + • Android touch input id 0 was incorrectly treated as invalid. (Max + Savenkov) + +Shaders: + + • Automatically call OnLostDevice and OnResetDevice on HLSL shaders. + + • Remove #version specifier from all shaders. + +Audio addon: + + • Remove generic audio event source and AudioQueue events. + + • Don’t queue silent fragments at start of new audio streams. + + • Make stream_read return correct number of filled samples when no + data is available (zero). + + • A DirectSound voice could not be restarted once it has been + stopped. + + • Fix crash when attaching empty stream to dsound voice. + + • Reset buffer position in stop instead of play in dsound voice. + + • Fix calculation of current sample position in dsound voice. + + • Reset audio stream when al_set_audio_stream_playing to false for + voice and mixer cases, and make all fragments available for refill. + + • Emit stream fragment events when a stream is started. + + • Remove unnecessary reallocation of the channel matrix. + + • Add al_fill_silence. + + • Add al_get_audio_stream_played_samples. + + • Fix deadlock in Pulseaudio driver. Reported by Bluebird. + + • Let al_set_sample_instance_playing work for unattached instances + and sample instances with no data set. Reported by Bluebird. + + • Enable the use of the unpatched DirectX SDK to build. + +Audio codec addon: + + • Fix looping in Ogg Vorbis stream. (Todd Cope) + + • Seeking in wavs would always have returned success. + +Image addon: + + • Fix many problems in Android native image loader, including: + supporting ALLEGRO_NO_PREMULTIPLIED_ALPHA, respecting the new + bitmap format, working for non-APK assets, not crashing on failure. + +Native dialogs addon: + + • Change native menu ids from int to uint16_t due to limitation with + Windows. (Matthew Leverton) + +Primitives addon: + + • Rename the primitives buffer flags. + + • Simplify the prim buffer hints. + + • Simplify the al_create_vertex_buffer API. + + • Actually implement uninitialized vertex buffers. + + • Add indexed buffer API. + + • Polylines with ALLEGRO_LINE_CAP_CLOSED cap style did not draw + correctly with thickness == 0. + + • Take into account the projection matrix when computing the scale of + the high level primitives. + + • Replace enum arguments for al_draw_polyline and al_draw_polygon + with integers to reduce chance of ABI issues. + +TTF addon: + + • Fix a bug where some glyphs would be blank. + + • Allow glyph allocation to fail without crashing. + +Android port: + + • Separate Allegro library Java code from the original example + project for Android (Jonathan Lilliemarck). + + • Build Allegro library as a JAR. + + • Rename Java package to org.liballeg.android. + + • Change how the application shared library is specified. Override + the AllegroActivity constructor instead of specifying in + AndroidManifest.xml. + + • Add a method to tell if the user exited main in the Android Java + code. + + • Add a fix for the case of launching another activity from your game + on Android and then returning to the game after it finishes. + + • Refactoring and clean up. + +iOS port: + + • Remove al_iphone_get/set_screen_scale as not really needed and + confusing. + +Build system: + + • Integrate Android port into build system, including building and + launching examples for debugging. + + • Detect OpenGLES/2 libraries on Android. + + • Let clang use same options as gcc in build system. + +Python: + + • Made the C-parser used in the Python API generator understand more + type constructs. (Elias Pschernig) + +Examples: + + • Make demos and most examples run (somewhat) on Android. + + • Add touch input support to various examples. + + • New examples: ex_file, ex_haptic, ex_haptic2, ex_touch_input. + + • ex_prim: Demonstrate indexed buffers. + +Other: + + • More more minor bug fixes and changes. + + • Documentation updates. + + • Syntax highlight the C source examples and prototypes in the + documentation. + +Changes from 5.1.6 to 5.1.7 (May 2013) +************************************** + +The main developers this time were: Peter Wang, Trent Gamblin. + +Graphics: + + • Added al_horizontal_shear_transform, al_vertical_shear_transform + (Jeff Bernard). + + • Make al_destroy_bitmap maintain the current display when + untargeting the bitmap to be destroyed. + + • Delete al_create_custom_bitmap. + + • Delete al_ortho_transform compatibility macro. + + • Make al_get_d3d_texture_size fail instead of crash if passed a + non-D3D bitmap. + + • Make al_get_opengl_texture_size return success code to match D3D. + + • Rename al_d3d_set_release/restore_callback to be consistent with + existing naming, and pass the display as an argument. + + • Check availability of fullscreen button on window frame at run-time + (OS X). + +Input: + + • Fix mouse warping on OS X. + + • Fix mouse warping in Linux evdev mouse driver. + +Audio addon: + + • pulseaudio: Use smaller buffer size by default, and make it + configurable. + + • pulseaudio: Clean up state transitions. + +Color addon: + + • Fix al_color_rgb_to_html blue component (Jeff Bernard). + + • Implement al_color_html_to_rgb and al_color_html more strictly. + +Primitives addon: + + • Delete al_draw_polygon_with_holes. + + • Delete stride-less version of al_draw_polyline*. + + • Simplify interface of al_triangulate_polygon and + al_draw_filled_polygon_with_holes. + +Video addon: + + • Make al_seek_video return a result. + + • Fix crash when unable to open a Ogg video. + + • Don’t scan to end of headers of unknown stream for Ogg video. + + • Stop reading at end of Ogg video. + + • Try to account for audio buffers in positioning of Ogg video. + + • Implement seek to beginning of file (only) in Ogg backend. + + • Replace deprecated av_find_stream_info() call (Nick Black). + +Android port: + + • Fix some Android switch in/out and exit issues. + +Build system: + + • Do not install most internal header files. + + • Do not search for and link with unneeded X libraries. + +Examples: + + • ex_audio_timer: New example. + + • Revise and comment the ex_prim_shader example and shaders (Paul + Suntsov). + +Other: + + • Various documentation updates. + + • Minor fixes and much code refactoring. + +Changes from 5.1.5 to 5.1.6 (March 2013) +**************************************** + +The main developers this time were: Trent Gamblin, Paul Suntsov, Peter +Wang. + +Core: + + • Fix use of clobbered return value from setlocale() on X11. + + • Register system interface even if no display driver available on + Windows. + + • Fix use of double math functions for float arguments (Nick Trout). + +Shaders: + + • Revamped shader API. The shader API is now part of the core + library, and the shader addon removed. + + • Shaders are now a per-bitmap property, set with al_use_shader. A + bitmap without a set shader uses a default shader internally, that + allows Allegro drawing functions to work as in non-programmable + pipeline mode. + + • Shader variable setters operate on the shader of the target bitmap. + + • Rename ALLEGRO_USE_PROGRAMMABLE_PIPELINE to + ALLEGRO_PROGRAMMABLE_PIPELINE. + + • Rename al_link_shader to al_build_shader. + + • Remove al_set_shader. + + • Remove the al_set_shader_*_array functions. These functions cannot + be easily (or at all) implemented with the D3D backend. + + • Add al_get_shader_platform and al_get_default_shader_source. + + • Remove al_get_opengl_program_object, al_set_opengl_program_object, + al_get_direct3d_effect, al_set_direct3d_effect. + + • Remove Cg shader backend. + + • Add macros for shader variable names (Jon Rafkind). + +Displays: + + • Made al_get_display_mode return the closest thing to a pixel format + possible with the WGL driver (tobing). + + • Move WGL context destruction out of the message pump thread and + into the user/main thread. + + • Allow command-tab to work in fullscreen window mode on OS X. + + • Remove “user_reload” parameter from al_acknowledge_drawing_resume. + + • Don’t crash in al_create_display if there is no display driver. + + • Don’t crash at shutdown if there is no display driver (Windows). + + • Don’t fail init if both D3D, GL drivers unavailable (Windows). + + • Sync bitmaps before resizing display to prevent changes being lost + after the resize (D3D). + + • Load the D3D9X module during display creation and unload it when + the D3D system shuts down. + + • Run fullscreen toggle on main thread (OS X). + + • Destroy the backbuffer bitmap when destroying the display (OS X). + + • Switch to new NSTrackingArea API (OS X). + + • Set ALLEGRO_NO_PRESERVE_TEXTURE on backbuffer (OpenGL). + +Graphics: + + • Let al_destroy_bitmap implicitly untarget the bitmap on the calling + thread. + + • Fix a bug where bitmap locking may change the target bitmap but not + restore it back to NULL (OpenGL). + + • Use memory bitmap drawing when either bitmap is locked (OpenGL). + + • Fix a crash in D3D destroying sub-bitmaps. + + • Add const qualifiers to glUniform*v() functions (Aaron Bolyard). + +Input: + + • Partially fix mouse buttons “sticking” on Mac, e.g. holding the + mouse and toggling fullscreen window. + + • al_set_mouse_xy on Windows resulted in the mouse getting set to the + wrong position in windowed modes + + • Scale the user supplied mouse cursor if it’s too big (Windows). + + • Add key constants for some Android keys, those that are used in + Xperia Play controls. + +Audio addons: + + • Fix PulseAudio driver trying to connect to a non-existent server + forever. + + • Avoid memory leaks with audio event source. + + • Use smaller buffer size for OpenSL. + +Image addon: + + • Use Allegro built-in loaders in preference to OS X loaders for + BMP/TGA/PCX. The OS X TGA loader doesn’t support alpha and this is + also more consistent. + +Font addons: + + • Make al_init_font_addon return success value. + + • Make al_init_ttf_addon return true for subsequent calls. + +Native dialogs addon: + + • Fix a crash on iOS due to threading/TLS issues geting the display + (Nick Trout). + +Primitives addon: + + • Speed up al_triangulate_polygon_with_holes. + + • Speed up drawing of the rounds for polylines. + + • Add custom vertex attributes to the primitives addon. + + • Replace vertex shader binary generated by vsa.exe (removed from + DirectX SDKs for a while now) by that generated by fxc.exe. + + • A minor revamp of the HLSL default shader system in the primitives + addon. + + • Fix a few incorrect usages of al_lock_vertex_buffer + + • Disallow 3 component vectors for ALLEGRO_PRIM_TEX_COORD. + + • Add a whole bunch of new ALLEGRO_PRIM_STORAGE values. + + • Primitives addon was ignoring the filter settings of textures in + the D3D backend. + +Android port: + + • Generate KEY_CHAR on Android. + + • Add key constants for Android. + + • Set target bitmap to display backuffer after program is resumed. + + • Use different functions for OpenGL ES 1 and OpenGL ES 2 on Android. + +iOS port: + + • Support stencil buffer on iOS. + + • Remove unnecessary autorelease pools. There was a crash when using + Airplay that goes away without the pools. + + • Make Airplay work the standard way most apps do unless the Allegro + user explicitly creates a display on the second screen. + + • Don’t autorotate displays other than device. + + • Fix some threading and memory issues. + +Raspberry Pi port: + + • Allow for color size, depth and stencil sizes. + + • Support al_show_mouse_cursor and al_hide_mouse_cursor. Disabled as + it sometimes ends up stuck on the screen until reboot. + +Examples: + + • New examples: ex_prim_shader, ex_shader_target. + +Other: + + • Various documentation updates. + + • Minor fixes and code refactoring. + +Changes from 5.1.4 to 5.1.5 (January 2013) +****************************************** + +The main developers this time were: Trent Gamblin, Elias Pschernig, Jon +Rafkind, Peter Wang. + +Ports: + + • Initial port to Raspberry Pi by Trent Gamblin. + +Core: + + • Added an al_register_trace_handler function. + + • Clean up logging subsystem at shutdown (muhkuh). + + • Fix a problem with creating a display after Allegro is shut down + then re-initialised on X11. + +Displays: + + • Fix crashes when resizing a WGL fullscreen window. + + • Fix use of invalidated pointers in D3D driver when the first format + fails. + + • Fix bug where setting the mouse cursor had no effect when the mouse + was captured (mouse button held down). + + • Fix windows not having a minimise button when set to windowed state + from fullscreen window state. + + • Respect ALLEGRO_FRAMELESS flag properly when toggling from + fullscreen window state to windowed state (Windows). + + • Don’t generate DISPLAY_LOST events when resizing a fullscreen + display. + + • Fix al_set/get_window position on Windows so getting/setting to the + same position continuosly doesn’t move the window. (Michael + Swiger) + + • Rename al_change_display_option to al_set_display_option. + + • Add al_set_display_icons (plural), implemented for X11 and Windows. + + • Add ALLEGRO_GTK_TOPLEVEL display flag for X11. + + • Fix window resizing when using shaders (X11). + +Graphics: + + • Avoid null pointer dereference when setting a target bitmap after + its video_texture has already been released (D3D). + + • Make d3d_lock_region fail immediately if _al_d3d_sync_bitmap + failed, likely because the device was lost. + + • Set device_lost flag immediately when d3d_display_thread_proc finds + the device is lost. + + • Fix OpenGL extensions being completely ignored on OS X. + + • Added a quick hack to fix bitmap locking on desktop OpenGL when + using shaders. + +Config: + + • Added al_remove_config_key and al_remove_config_section functions. + +File I/O: + + • Fix al_read_directory crash on 64-bit Windows (simast). + +Filesystem: + + • Keep absolute path in ALLEGRO_FS_ENTRYs so that later changes to + the current working directory do not affect the interpretation of + the path. + + • Set ALLEGRO_FILEMODE_HIDDEN properly on Unix. + + • Make sure stat mode bits are cleared in default implementation of + al_update_fs_entry. + + • Support Unicode paths on Windows. + + • Change description of al_get_fs_entry_name about not returning + absolute path if created from relative path; no longer true for + either the default or Physfs implementations. + +Audio addons: + + • Fix setting the speed of an audio stream after it was attached to + the mixer (Paul Suntsov). + + • Shut down threads properly when when destroying FLAC and modaudio + streams. + +Font addon: + + • Avoid making x offset non-integral for ALLEGRO_ALIGN_CENTRE. + + • Make al_draw_justified_* respect ALLEGRO_ALIGN_INTEGER. + +TTF addon: + + • Don’t save the projection transform if no display is set. + +Image addon: + + • Added a missing autorelease-pool to the OSX bitmap saving function + (sleepywind). + + • Fix OSX native image loader for loading not-premultiplied RGB data. + Previously the data was “de-multiplied”, with possibly all + information lost. + + • Fix OSX native image loader for loading bitmaps without an alpha + channel. They appeared completely black previously. + + • Fixed loading interlaced .png files with libpng. + +Native dialogs addon: + + • Do not unload of rich edit module when closing one text log window + while another exists. Reported by URB753. + + • Use default colours for Windows text log implementation, avoiding + problems when the previous custom colours failed, leading to black + text on a nearly black background. + + • Add al_shutdown_native_dialog_addon. + + • Add native menu support on X11 (requires ALLEGRO_GTK_TOPLEVEL). + + • Add native menu support on OS X. + +PhysicsFS addon: + + • Implement al_change_directory semantics (Todd Cope). + +Primitives addon: + + • Fixed textured primitives when using shaders (OpenGL). + +Shader addon: + + • Add dynamic loading of d3dx9_xx.dll (Michał Cichoń). + + • Add dynamic loading of Cg DLLs (Michał Cichoń). + + • Started implementing default shaders. Only GLSL so far. + + • Fix null pointer dereference in al_create_shader if backend init + fails. + +Android port: + + • Fix setting the current display on Android. + + • Don’t set the backbuffer when setting up the OpenGL view. + +Build system: + + • Rename allegro*-5.1.pc files to allegro*-5.pc. The new names will + be available in future 5.0.x releases. + + • Generate and install allegro_shader pkg-config file. + + • Only generate and install pkg-config files for libraries that we + build. + +Examples: + + • ex_icon2: New example. + + • ex_shader_multitex: New example. + + • ex_shader: Choose shader platform on command-line; external shader + sources. + + • ex_menu: Various changes. + + • speed: Avoid poor performance due to needless redraws. + +Other: + + • Documentation updates, many thanks to beoran. + + • A lot of code refactoring. + +Changes from 5.1.3 to 5.1.4 (October 2012) +****************************************** + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Peter Wang. + +Graphics: + + • Fixed al_convert_bitmap using the target instead of the source + format when converting its data. + + • Fix a crash in Direct3D in al_set_target_bitmap when switching from + a memory target. + + • Fix a potential crash when drawing the screen to a bitmap with D3D. + + • WGL shouldn’t need to preserve bitmaps. + + • Update the projection transform when setting up the OpenGL context + on X11 (SiegeLord). + + • Lock bitmap to prevent slowness when creating a cursor from a + non-memory bitmap on Windows. + + • Conditionally lock bitmap when creating cursor on X11 (previously + it did so even if already locked). + +Input: + + • Make al_install_touch_input fail under Windows if there is no touch + device. + + • Temporary fix for delay after mouse warp on OS X. + +File I/O: + + • Fix al_fputc on big-endian. Reported by Andreas Rönnquist and + Tobias Hansen. + + • Make al_fputc return value like fputc when out of range. + +Image addon: + + • gdiplus: Only preserve indexed images with KEEP_INDEX flag on. + +Font addons: + + • Added ALLEGRO_ALIGN_INTEGER text drawing flag (Todd Cope). + + • Added a new al_get_font_ranges function. + + • Made TTF addon include padding on the top and left edges of pages + (Todd Cope). + +Audio addon: + + • Use programmatically generated interpolators. They cover an + additional case which was missed and should be slightly more + efficient. + + • Support linear interpolation for 16-bit mixers. + + • Add cubic interpolation for mixers (off by default). + + • Fix potential deadlock in stop_voice for OpenAL. + + • Fix potential deadlock in stop_voice for DirectSound. + + • Improve buffer filling behaviour for DirectSound, reducing pops and + crackles significantly on slower machines. + + • Increase default buffer size for DirectSound to 8192 samples. + +Android port: + + • Support ALLEGRO_KEYBOARD_STATE. + + • Fix return type of APK_tell (Todd Cope). + + • Allow use of OpenGL ES 2 under Android. + +iOS port: + + • Make orientation changes work on iOS with SDK 6. + +Build system: + + • Rename native dialog library back to allegro_dialog to match 5.0. + + • Install pkg-config files when cross-compiling on Unix. + +Python: + + • Make the Python wrapper also check for the monolith DLL. + +Examples: + + • ex_synth: Add button to save waveform to a file. + + • ex_multisample: Demonstrate using moving bitmaps. + + • Renamed a5teroids to Cosmic Protector + +Other: + + • Minor bug fixes and documentation updates. + +Changes from 5.1.2 to 5.1.3 (August 2012) +***************************************** + +The main developers this time were: Dennis Busch, Trent Gamblin, Elias +Pschernig, Jon Rafkind, Paul Suntsov, Peter Wang. + +Displays: + + • Rewrite D3D display format listing code, which was broken. This + should re-enable multi-sampling and fix ex_depth_mask being slow + with D3D. + + • Fixed a case where changing fullscreen mode in D3D via + al_resize_display caused a crash and loss of loaded bitmaps + information. + + • Fixed a case where changing fullscreen mode in OpenGL (on Windows) + via al_resize_display cause nothing to be rendered after the mode + change. + + • Fixed OpenGL (Windows) bitmap preservation between fullscreen mode + changes. + + • Fixed missing/incorrect resize events under Windows. + + • Fixed ALLEGRO_FULLSCREEN_WINDOW under OS X. + + • Fix al_set_new_display_adapter on OS X. + + • Enable fullscreen icon on resizable windows on OS X 10.7 and up. + + • Added al_osx_get_window function (Dennis Gooden). + +Graphics: + + • Rename al_ortho_transform to al_orthographic_transform and give it + a more consistent parameter order. + + • Add al_perspective_transform and + al_translate|scale|rotate_transform_3d. + + • al_draw_pixel was crashing when drawn on sub-bitmaps on OpenGL. + + • Make ogl_flush_vertex_cache disable GL_TEXTURE_2D state. + + • Don’t use NSOpenGLPFAAccelerated unnecessarily (OS X). + +Input: + + • Fix incorrect keyboard modifier flags after leaving and re-entering + a window (Windows). + + • Fixed a bug with mouse enter/leave events for resized windows under + OSX (Dennis Gooden). + +Audio addon: + + • Add OpenSL ES driver for Android. + +Font addons: + + • Add builtin font creation function. + + • Preserve projection transformation when caching glyphs in the TTF + addon. + +Image addon: + + • Don’t include native image loader source files when the native + image loaders are disabled. + +Primitives addon: + + • Add vertex buffer API. + +Native dialogs addon: + + • Run NSAlert on the main thread (OS X). + +Android port: + + • Many bug and compatibility fixes. + + • Support al_inhibit_screensaver on Android. + + • Generate SWITCH_IN/OUT events on Android similar to iOS. + + • Support render state API on Android. + + • Make al_acknowledge_drawing_resume take a user callback parameter + for interdependant textures. + + • Support building Android port for x86. + + • Add an ANDROID_APP_NAME CMake variable which will replace all + org/liballeg/app and org_liballeg_app with your own app name + +Build system: + + • Make the monolith dll under Windows use proper dll exports with + MSVC. + + • Properly include the main addon in the monolith build. + + • Add Physfs and Cg include directories. + +Examples: + + • Added new examples: ex_projection, ex_vertex_buffer. + +Other: + + • Documented the allegro_main addon. + + • Various minor bug fixes and cleanups. + +Changes from 5.1.1 to 5.1.2 (May 2012) +************************************** + +The main developers this time were: Thomas Fjellstrom, Trent Gamblin, +Elias Pschernig, Peter Wang. + +Core: + + • Add userdata to Windows window callbacks and rename the functions + (Matthew Leverton). + + • Fix ALLEGRO_STATIC_ASSERT collisions from different files included + in the same translation unit. Reported by tobing. + + • Make al_ustr_empty_string const correct. + + • Fix many memory leak/warnings on MacOS X (Pär Arvidsson). + +Filesystem: + + • Make stdio al_fopen implementation set proper errno on failure. + + • Make al_get_standard_path(ALLEGRO_TEMP_PATH) treat environment + values as directory names even without a trailing slash on Unix. + + • Fix typo preventing get_executable_name from using System V procfs + correctly. Reported by Max Savenkov. + +Displays: + + • Fixed bug on Windows where two SWITCH_IN events were fired when + window was minimized/restored (Michael Swiger). + + • Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic under + Windows as well as a bug where repeatedly setting the flag to on + would make the window grow bigger and bigger (Michael Swiger). + + • Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic in + X11. + + • Rename al_toggle_display_flag to al_set_display_flag, retaining the + older name for compatibility. + + • Add ALLEGRO_FRAMELESS as a preferred synonym for the confusing + ALLEGRO_NOFRAME flag. + + • Set WM_NAME for some window managers (X11). + + • Disable the idle timer on iOS (screen lock) when entering airplay + mode. + + • Make al_destroy_display handle display disconnection properly. The + user will need to clean up then call al_destroy_display after + receiving ALLEGRO_EVENT_DISPLAY_DISCONNECTED (iOS). + +Graphics: + + • Added al_get_parent_bitmap (Paul Suntsov). + + • Make blitting from backbuffer work when using multisampling on + Windows/D3D. + + • Redefine pixel format LUMINANCE_8 as SINGLE_CHANNEL_8. + + • Map SINGLE_CHANNEL_8 to red channel only. Fix some software pixel + format conversion bugs previously present with the LUMINANCE_8 + format. + + • Added al_create_custom_bitmap. + + • Remove ALLEGRO_PRESERVE_TEXTURE flag. The idea is to always + preserve textures unless directed otherwise by the user with + ALLEGRO_NO_PRESERVE_TEXTURE. + + • Added al_clear_depth_buffer and al_set_render_state functions. + + • Force al_create_bitmap to not create oversized bitmaps, to mitigate + integer overflow problems. + + • Removed initial black frame on all Allegro programs. + +OpenGL: + + • Fix null pointer dereference if backbuffer creation fails. + Reported by Max Savenkov. + + • Made the ALLEGRO_OPENGL_FORWARD_COMPATIBLE flag work with + al_draw_bitmap. + + • Texture should be ‘complete’ (min/mag and wrap set) before + glTexImage2D. + + • Restore matrix manipulation code for unlocking backbuffer in GL + <1.4 case. + + • Fixed a bug in al_unlock_bitmap where the pixel alignment + mistakenly was used as row length. + + • Never set the projection when using programmable pipeline mode + unless a program object is bound. + + • Do not preserve bound texture state. + + • Disable GL_NORMAL_ARRAY in non-programmable pipeline mode. + + • Fixed typo in names of some OpenGL extension functions. + + • Display list of OpenGL extensions in allegro.log also for OpenGL + 3.0. + + • Check for OES_texture_npot as well for non-power-of-two support. + + • Fix loading of some textures on iOS. + +Direct3D: + + • Fixed a bug in the D3D driver where separate alpha blending was + being tested for when it shouldn’t have been (Max Savenkov). + + • Do not manage depth stencil surface. + + • Arrange code so that sleep and hibernate work using the release and + restore callbacks. + + • Fix device reset problem in D3D. + + • Make sub-bitmap restore properly on lost device. + +Input: + + • Increase max number of joystick “sticks”. Due to analogue buttons + being mapped to axes, the number of sticks on a single device may + be much higher than expected. + + • Monitor /dev/input instead of /dev on Linux for hotplugging + joysticks (Jon Rafkind). + + • Do not permanently change the locale for the X11 keyboard driver. + Set LC_CTYPE only, not LC_ALL. + + • Update ALLEGRO_MOUSE_STATE even if mouse emulation event source + isn’t attached to an event queue (Android and iOS). + + • Don’t report shakes at program start accidentally (iOS). + +Android port: + + • Many graphics-related changes (too many to list). + + • Make Android port always choose a double buffered graphics mode. + + • Don’t force 16-bit mode if no COLOR_SIZE specified. + + • Go fullscreen (no title/status bar). + + • Generate ALLEGRO_EVENT_DISPLAY_HALT_DRAWING, RESUME_DRAWING events + instead of SWITCH_IN/OUT. + + • Add an APK file driver for reading assets directly from Android app + bundles. + + • Additions and fixes to accelerometer and orientation code. + + • Support for volume keys. + + • Added a dummy mouse driver, enough to get al_get_mouse_state + working. + + • Improve compatibility of touch input emulation driver with iOS + touch input emulation. + + • Add al_android_get_os_version(). + + • Fix linking problem on Android 2.2 and below. + + • Update and clean up sample project. + +Audio addon: + + • Fix desychronization due to inaccurate sample positions when + resampling. Thanks to _Bnu for discovering the issue and Paul + Suntsov for devising the correct solution. + + • Fix linear interpolation across audio stream buffer fragments. + + • Add stub OpenSL driver (Jon Rafkind). + +Image addon: + + • Improved accuracy of un-alpha-premultiplying in the native OSX + bitmap loader. + + • Improve compatibility of BMP loader. In particular, support + bitmaps with V2-V5 headers and certain alpha bit masks. + + • Improve robustness of BMP loader against some corrupt files. + + • Fix TGA loader using more memory than necessary. Reported by Max + Savenkov. + + • Image loading in Android now works. + +Font addon: + + • Use user set pixel format for fonts. + +TTF addon: + + • Added ALLEGRO_TTF_NO_AUTOHINT font loading flag to disable the Auto + Hinter which is enabled by default in newer version of FreeType + (Michał Cichoń). + + • Unlock glyph cache page at end of text_length and + get_text_dimensions (jmasterx). + +Primitives addon: + + • Use GL_REPEAT so textures can be tiled again. + + • Always set the texture due to missing glGetInteger on some GLES + 1.0/1.1 devices. + +Native dialogs addon: + + • Only call SetMenu from within the window thread (Matthew Leverton). + + • Clear mouse state after dialogs or else it gets messed up (OSX). + + • Fix some warnings in gtk_dialog.c. + +Build system: + + • Added OSX Framework support for the monolith library. + + • Make examples build with monolith build. + + • Add WANT_ANDROID_LEGACY to allow compiling for older Android + platforms. + +Examples: + + • a5teroids: Added high scores and other improvements. New graphics + by Tony Huisman. + + • Add ex_file_slice. + + • Add ex_resample_test. + + • Add ex_depth_mask. + + • ex_audio_props: Add bidir button. + + • ex_joystick_events: Support hotplugging and fix display of 3-axis + sticks. + + • ex_polygon: Test al_draw_filled_polygon_with_holes. + + • ex_get_path: Test al_set_exe_name. + + • Made the skater demo run from within xcode. + + • Add test_driver –no-display flag. (Tobias Hansen) + + • Add test_driver –force-opengl-2.0 option. + + • Make .png and .tga loading tests to not require a backbuffer with + an alpha channel. + +Other: + + • Many minor bug fixes. + + • Many documentation updates. + + • Fix whatis entries of man pages. (Tobias Hansen) + +Changes from 5.1.0 to 5.1.1 (February 2012) +******************************************* + +The main developers were: Thomas Fjellstrom, Trent Gamblin, Matthew +Leverton, Elias Pschernig, Jon Rafkind, Peter Wang. + +Ports: + + • Thomas Fjellstrom started an Android port. Displays, keys and + touch events work. + +Core: + + • Make al_ref_cstr, al_ref_ustr and al_ref_buffer return const + ALLEGRO_USTR_ instead of just an ALLEGRO_USTR_ (Paul Suntsov). + +Graphics: + + • Fixed a bug in the OpenGL driver when drawing the backbuffer + outside the clipping rectangle of the target bitmap. + +Displays: + + • Fixed a problem with wrong window size when restoring a minimised + window, in code that was added to support window constraints + (jmasterx). + + • Set ALLEGRO_MINIMIZED display flag on Windows (Zac Evans). + + • Prevent a deadlock during display creation on X. + + • Fallback to the ‘old’ visual selection method on X instead of + crashing if the ‘new’ visual selection doesn’t work. + + • Implement XEmbed protocol. + + • Add hot plug display support on iOS (Airplay and wired.) + +Input: + + • Use the same logic in set_mouse_xy for FULLSCREEN_WINDOW as was + used for FULLSCREEN. (Max OS X) + +Audio addons: + + • Add audio recording API with implementations for ALSA, AudioQueue, + DirectSound8 and PulseAudio. + + • Improve code to check that DLL symbols are loaded in the acodec + addon. The old method was hacky and broke under -O2 using GCC + 4.6.1. (Paul Suntsov) + +Image addon: + + • Some initial Android support. + + • Write libjpeg errors to Allegro log. + +TTF addon: + + • Clear locked region so pixel borders aren’t random garbage that can + be seen sometimes with linear filtering on. + +Video addon: + + • Added Ogg Theora/Vorbis backend. + + • Fixed a few warnings with ffmpeg version 0.7/0.8. + +Build system: + + • Add monolith library option. + + • Detect the new MinGW cross-compiler in Ubuntu. + +Examples: + + • Added new examples: ex_record, ex_record_name, ex_display_events. + + • ex_ogre3d: Make it work under Windows (AMCerasoli). + + • skater: small bug fixes, mouse support, add missing files for + scrollers. + + • a5teroids: Support gamepads that report small non-zero values for + sticks that are at rest. + + • Added pong example in Python. + +Other: + + • Added index to HTML version of the reference manual. + + • Various documentation updates. + + • Other minor bug fixes. + +Changes from 5.0.x to 5.1.0 (November 2011) +******************************************* + +The main developers were: Michał Cichoń, Trent Gamblin, Matthew +Leverton, Elias Pschernig, Paul Suntsov, Peter Wang. + +Core: + + • Added al_register_assert_handler. + + • Added API for registering callbacks to intercept window messages on + Windows. + +Graphics: + + • Added bitmap conversion API: al_convert_bitmap, al_convert_bitmaps, + with bitmap flag ALLEGRO_CONVERT_BITMAP and display option + ALLEGRO_AUTO_CONVERT_BITMAPS. Automatic bitmap conversion is + enabled by default. + + • Added al_draw_tinted_scaled_rotated_bitmap_region. + + • Added new ALLEGRO_PIXEL_FORMAT_LUMINANCE_8 format. + + • Added a new bitmap flag ALLEGRO_KEEP_INDEX. + + • Separate bitmap loader flags from bitmap flags. This adds three + functions: al_load_bitmap_flags, al_load_bitmap_flags_f and + al_load_bitmap_font_flags. + + • Add ALLEGRO_SRC_COLOR, ALLEGRO_DST_COLOR blending modes (Jon + Rafkind). + + • Add ALLEGRO_INVERSE_SRC_COLOR and ALLEGRO_INVERSE_DST_COLOR + blending modes. + + • Made al_compose_transform do a full 3d multiply. + + • Added al_get_current_inverse_transform, al_ortho_transform, + al_get_projection_transform, al_set_projection_transform. + + • Added al_reset_clipping_rectangle convenience function. + + • Added al_get_d3d_texture_size. + + • Added al_d3d_set_release_callback and al_d3d_set_restore_callback + for release/restoring user d3d objects. + +Displays: + + • Added al_get_display_orientation. + + • Added a new display option ALLEGRO_SUPPORTED_ORIENTATIONS to + specify the supported orientations (default is just portrait as + before). + + • Added al_change_display_option function, initially only for + ALLEGRO_SUPPORTED_ORIENTATIONS. + + • Add two new display events (only implemented on iOS right now). + ALLEGRO_EVENT_DISPLAY_HALT_DRAWING tells the app to stop all + drawing and ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING tells it it can + start drawing again. SWITCH_OUT/IN on iOS were redefined from + “going into/out of background” to “going active/inactive”. + + • Added the function al_acknowledge_drawing_halt. + + • Added window size constraint functions (jmasterx). + +Input: + + • Add API related to touch input. The implementation covers iDevices + and Windows 7 drivers for touch input. A number of mouse emulation + modes are provided. + +Events: + + • Add al_pause_event_queue, al_is_event_queue_paused. + +Filesystem: + + • Added al_fopen_slice. + + • Added al_set_exe_name which allows overriding Allegro’s idea of the + path to the current executable. + +Audio addon: + + • Add mixer gain property and functions. + + • Add a ‘global’ audio event source, generating some audio events + from the Audio Queues driver: AUDIO_ROUTE_CHANGE, + AUDIO_INTERRUPTION, AUDIO_END_INTERRUPTION. + +Native dialogs addon: + + • Add menus to native dialogs (Windows and GTK). + +Primitives addon: + + • Add simple polygon triangulator and polygon drawing routines. + + • Added al_draw_polyline and al_draw_polyline_ex. + + • Added al_draw_filled_pieslice and al_draw_pieslice. + + • Added al_draw_elliptical_arc. + +TTF addon: + + • Added al_load_ttf_font_stretch functions (tobing). + +Shader addon: + + • Added a shader addon and programmable pipeline support. + +Video addon: + + • Added a video player addon, currently using ffmpeg. + +iOS port: + + • Added al_iphone_override_screen_scale, al_iphone_get_screen_scale, + al_iphone_set_statusbar_orientation, al_iphone_get_last_shake_time, + al_iphone_get_battery_level, al_iphone_get_window, + al_iphone_get_view. + +Examples: + + • Added new example programs: ex_audio_chain, ex_loading_thread, + ex_menu, ex_palette, ex_polygon, ex_shader, ex_window_constraints, + ex_video. + + • Added skater demo ported from Allegro 4.4. + diff --git a/allegro/CHANGES-5.2.txt b/allegro/CHANGES-5.2.txt new file mode 100644 index 00000000..79b54d9e --- /dev/null +++ b/allegro/CHANGES-5.2.txt @@ -0,0 +1,985 @@ +Allegro changelog for 5.2.x series +Changes from 5.2.6 to 5.2.7 (March 2021) +Changes from 5.2.5 to 5.2.6 (February 2020) +Changes from 5.2.4 to 5.2.5 (February 2019) +Changes from 5.2.3 to 5.2.4 (February 2018) +Changes from 5.2.2 to 5.2.3 (October 2017) +Changes from 5.2.1.1 to 5.2.2 (December 2016) +Changes from 5.2.1 to 5.2.1.1 (August 2016) +Changes from 5.2.0 to 5.2.1 (July 2016) +Changes from 5.1.13.1 to 5.2.0 (April 2016) +Allegro changelog for 5.2.x series +********************************** + +These lists serve as summaries; the full histories are in the git +repository. + +Changes from 5.2.6 to 5.2.7 (March 2021) +**************************************** + +The main developers this time were: SiegeLord, Peter Hull, Elias +Pschernig, Aldrik Ramaekers, Andreas Rönnquist. + +Build system: + + • Allow generating projects with a suffix (lorry-lee). + + • Fix build under Clang-CL in Visual Studio. + +Core: + + • Avoid some undefined behavior errors. + + • Return key modifiers in ‘ALLEGRO_EVENT_KEY_UP’ and + ‘ALLEGRO_EVENT_KEY_DOWN’. + + • Allow calling ‘al_map_*’ color functions before Allegro is + initialized. + + • Allow minimum bitmap size to be something other than 16 on + non-Android platforms (controlled via ‘allegro5.cfg’). + + • Add ‘al_get_monitor_refresh_rate’ (only implemented on Windows for + now). + +Graphics: + + • Fix ‘ALLEGRO_KEEP_INDEX’ flag for bitmaps. + + • Add ‘ALLEGRO_OPENGL_CORE_PROFILE’ display flag. + +Emscripten: + + • The experimental Emscripten support (via the SDL backend) is now + documented in ‘README_sdl.txt’. + +OSX: + + • Move more Cocoa operations to the main thread. + + • Explicitly link CoreVideo to fix the static build. + +Windows: + + • Issue #1125: Speed up OpenGL extension detection (Tobias Scheuer). + + • Use Unicode APIs when enumerating joysticks. + + • Use ‘WM_DEVICECHANGE’ rather than polling to detect joystick + hotlugging, reducing input drops and lags (Todd Cope). + + • Fix joystick polling period. + + • Restore WinXP compatibility by using slightly older API when + loading shared libraries (Julian Smythe). + + • Fix build with HLSL disabled (Julian Smythe). + + • Raise DirectInput ‘MAX_JOYSTICKS’ to 32 and ‘DEVICE_BUFFER_SIZE’ to + 128. + +SDL: + + • Issue #1224: Fix bug in SDL voice driver. + +Audio addon: + + • Allows playing sounds in reverse by specifying a negative speed. + +Acodec addon: + + • Fix edge-case looping in Ogg Vorbis stream (Cody Licorish) + +Audio addon: + + • Use more sensible values for PulseAudio’s playback buffer, + potentially resolving some crashes and high CPU usage. + +Native Dialog Addon: + + • Migrate from GTK2 to GTK3. Sadly, we lose menu icons as GTK3 + dropped support for them. + +TTF addon: + + • Allow initializing TTF addon before the Font addon. + + • Shut-down the TTF addon automatically in ‘al_uninstall_system’. + +PhysFS addon: + + • Fix handling of native path separators. + + • Stop using deprecated PhysFS API. + +Primitives addon: + + • Fix segfault in ‘al_draw_ribbon’ when ‘num_segments > 128’ (Rodolfo + Borges). + + • Issue 1215: Correctly handle small scales when determining + subdivision level for high level primitives (Robin Heydon). + +Documentation: + + • Fix LaTeX errors in the generation of the reference manual PDF. + + • Add links to examples into the reference manual. + + • Allow pressing ‘S’ to focus the search bar in the docs. + + • Assorted documentation improvements. + +Misc: + + • Add a security policy and an associated private security mailing + list - allegro-security@lists.liballeg.org. + + • Add Emscripten-powered examples to + https://liballeg.org/examples_demos.html. + +Examples: + + • ‘ex_audio_simple’ now displays instructions and supports + bidirectional looping. + + • Add default files to some audio examples. + +Changes from 5.2.5 to 5.2.6 (February 2020) +******************************************* + +The main developers this time were: SiegeLord, Peter Hull, Karthik Kumar +Viswanathan, Elias Pschernig, Sebastian Krzyszkowiak, Doug Thompson, +PmProg, RmBeer. + +Core: + + • Fix timestamps being clamped to ints on touch inputs with X11. + + • Fix al_utf8_width argument type mismatch on platforms where + ‘sizeof(int) != 4’. + + • Fix building for GNU/Linux without GNU extensions enabled + + • Some refactoring to simplify adding new drivers. + +Graphics: + + • Fix for OpenGL version selection and reporting on Windows and X + (Edgar Reynaldo). + + • Report OpenGL version in display options on Android, iOS and + Raspberry Pi. + + • Fix creation of the bitmap depth buffer for non-square bitmaps + (Kevin Wellwood). + + • Fix ‘ALLEGRO_ALPHA_TEST_VALUE’ not being interpreted correctly. + + • Fix reported bitshifts for ‘ARGB_4444’ and ‘RGBA_4444’ pixel + formats. + + • Fix alpha test with the GLSL version. + +Android: + + • Do not build Android examples outside of Android. + + • Use the cmake toolchain provided by the Android NDK. + + • Use FLAG_KEEP_SCREEN_ON instead of a wakelock for screensaver + inhibition. + + • Use DisplayListener to listen to orientation changes. + + • Implement ‘ALLEGRO_FRAMELESS’ on Android. This hides the + navigation buttons and the bar on top. + +Linux: + + • Fix ‘al_inhibit_screensaver’ function. + +OSX: + + • Ensure system calls happen on the main thread. + + • Make things work on Catalina. + +Hurd: + + • Fix pthreads (Andreas Rönnquist). + +Windows: + + • Implement Windows version check using non-deprecated functions. + + • Abstract UNICODE vs ANSI string handling, switch to using UNICODE + by default. + + • Enable debug window for ‘DEBUGMODE’ on Windows. + +SDL: + + • Fix requesting GLES profile on GL Allegro. + + • Add audio recorder implementation. + + • Don’t link with dl, it’s unnecessary. + +Addons: + + • Add a whole bunch of ‘al_is_*_initialized’ functions (Mark Oates). + +Acodec addon: + + • Add MP3 support via the MiniMP3 library. + +Audio addon: + + • Allow calling ‘al_destroy_audio_recorder’ on NULL. + + • Fix some stream garbage audio issues for high playback speeds. + +Image addon: + + • Add support for FreeImage library. + + • Always prefer non-system image loaders. + +Python wrapper: + + • Fix a number of bugs (zachs18 and others). + +Misc: + + • Add an ‘.editorconfig’ file. + + • Convert our internal Python scripts to Python 3. + +Examples: + + • ‘ex_draw_bitmap’ - Add more options. + +Changes from 5.2.4 to 5.2.5 (February 2019) +******************************************* + +The main developers this time were: Sebastian Krzyszkowiak, SiegeLord, +Elias Pschernig, Bruce Pascoe, Aldrik Ramaekers, Firat Salgur. + +Core: + + • Try to identify bitmap format for unknown extensions. + + • Add some missing OpenGL 4.3 functions. + + • Add ‘al_create_thread_with_stacksize’ to create threads with a + custom stack size. (Aldrik Ramaekers) + + • Add ‘al_get_system_id’ function, letting you disambiguate platforms + at runtime. + +Graphics: + + • Add ‘al_get_monitor_dpi’ to query the DPI of a monitor. + + • Add new API for making blender a bitmap-local state (like + transformations), which can simplify some code. See + ‘al_set_bitmap_blender’ and the related APIs. Also see the + ‘ex_blend_target’ example. + + • Added ‘al_transpose_transform’. This is useful for rotation + transformations. + + • Rework internal GLES support for better portability. + + • Don’t force POT bitmaps on GLES. + + • Fix repeated bitmap locking on OpenGL. + +Android: + + • Various documentation and other improvements (Christian Mauduit). + + • Fix OpenGL version reporting after display creation. + +iOS: + + • Fix OpenGL version reporting after display creation. + +Linux: + + • Improve linux joystick detections. + + • Fix a number of memory leaks/crashes in the audio addon when using + pulseaudio/alsa. (Julian Smythe) + + • Fix compilation with Mesa 18.2.5 and later. + + • Fix OpenGL version reporting after display creation (Edgar + Reynaldo). + + • Fix requesting specific OpenGL versions via display options (Edgar + Reynaldo). + +OSX: + + • Make ‘al_get_monitor_info’ return the correct values for Retina + displays. + + • Fix vsync on OSX 10.14+. + +RaspberryPi: + + • Fix OpenGL version reporting after display creation. + +Windows: + + • Fix toggling of menu checkboxes by id. + + • Fix ‘al_draw_indexed_primitive’ while using Direct3D. + + • Fix crash when passing ‘NULL’ display to + ‘al_show_native_file_dialog’ while using + ‘ALLEGRO_FILECHOOSER_FOLDER’. + + • Fix OpenGL version reporting after display creation (Edgar + Reynaldo). + + • Fix requesting specific OpenGL versions via display options (Edgar + Reynaldo). + +SDL: + + • Sebastian Krzyszkowiak has spent a lot of effort to making the SDL + backend usable as a nearly fully featured Allegro backend. You can + use it on platforms native Allegro implementations do not support + (such as emscripten, etc.). + +Addons: + + • Better logging when failing to load a resource. + + • Fix a memory leak when destroying a mixer with attached streams. + + • Fix a memory leak in the audio destroying a mixer with attached + streams. + +Acodec addon: + + • Allow modules to loop properly when the user hasn’t specified loop + points. (Todd Cope) + +Audio addon: + + • Better support for big endian. (Douglas Mencken) + +TTF addon: + + • Added support of HarfBuzz in FreeType (Arves100). + +Documentation: + + • Source links now point to the correct commit on GitHub. + + • General improvements and clarifications. + +Examples: + + • Add ‘ex_blend_target’. + +Changes from 5.2.3 to 5.2.4 (February 2018) +******************************************* + +The main developers this time were: Sebastian Krzyszkowiak, Elias +Pschernig, SiegeLord + +Core: + + • Fix errors when reading/writing 0 byte buffers (Bruce Pascoe). + + • Re-initialize TLS when Allegro is installed (Issue #865). + + • Add ‘al_transform_coordinates_4d’. + + • Don’t initialize the trace mutex multiple times (Issue #874). + + • Fix 3D (non-projection) transforms with ‘al_hold_bitmap_drawing’. + +Raspberry Pi port: + + • Fix compilation on RPI. + +Android port: + + • Remove limit on the working directory length. + + • Fix ‘ALLEGRO_MAXIMIZED’ flag. + + • Fix build with older Android NDKs. + + • Remove ‘glClear’ hack for Android 2.1. + +Linux port: + + • Make compositor bypass configurable in X11, and bypass only when + fullscreen by default. + +OSX port: + + • Fix a few OSX retina scaling issues (Issue #851). + +Audio addon: + + • Fix ALSA lag. + + • Add an option to use the desktop window when initializing + DirectSound (Issue #877). + +Font addon: + + • Add support for bmfont format. + +Native dialog addon: + + • Resize the display on Windows when hiding/showing the menu (Issue + #860). + + • Detect when ‘al_popup_menu’ fails to actually work under GTK (Issue + #808). + + • Don’t clear the top-level menu when destroying the popup menu. + +Build system: + + • Don’t link in libm on MSVC for DUMB (Issue #847). + + • Don’t use the LOCATION property (Issue #847). + + • Don’t use SYSTEM for DirectX includes. + + • Add hints for mingw-w64 path locations for DirectX includes/libs. + +Python binding: + + • Fix the Python code-generation scripts to run under Python 2. + +Lua binding: + + • Add script to generate LuaJIT C API for Allegro 5 (BQ). + +Documentation: + + • Many improvements (Andreas Rönnquist, others) + +Examples: + + • Add a texture to the skybox in ‘ex_camera’. + +Changes from 5.2.2 to 5.2.3 (October 2017) +****************************************** + +The main developers this time were: Elias Pschernig, SiegeLord, +Sebastian Krzyszkowiak, Vitaliy V. Tokarev, Simon Naarmann, Bruno Félix +Rezende Ribeiro, Trent Gamblin). + +Core: + + • Add ‘al_path_ustr’ (Bruce Pascoe). + + • Handle NULL sections more gracefully with the config API. + + • Add missing ‘glStencilMaskSeparate prototype’ (Aaron Bolyard). + + • Add ‘al_clear_keyboard_state’. + + • Don’t add blank lines before config sections when writing them out. + + • Fix ‘fs_stdio_read_directory’ appending an extra slash. + + • Fix ‘al_set_window_constraints’ when the flag ALLEGRO_MAXIMIZED is + set. + + • Fix ‘al_set_clipping_rectangle’ when out-of-bounds (Bruce Pascoe). + + • Enable blocked locking of S3TC formats unconditionally. + +Raspberry Pi port: + + • Set default file interface when attempting to read + /boot/config.txt. + +Android port: + + • Replace the old build system that used deprecated tools with a new + Gradle-based system. + + • Work around crashes on some Androids when an FBO is bound during + ‘egl_SwapBuffers’. + + • Fix LocalRef leak when opening files using APK interface. + + • Remove -Wno-psabi switches from Toolchain-android.cmake. + +Linux port: + + • Make three finger salute and LED toggle configurable. + + • Fix KEY_CHAR events under X11 with compose key enabled. + + • Fix clearing the ‘ALLEGRO_MAXIMIZED’ flag under X11. + + • Add ‘al_x_set_initial_icon’. + + • Free wm_hints in ‘set_initial_icon’. + + • Read Allegro system config from ~/.allegro5rc on Unix. + +Windows port: + + • Make bitmap contents persist again after device loss. + + • Add large file support for MSVC. + + • Only test cooperative lavel if device is known to be lost. + + • Don’t leak the ‘D3DEffect’ when attaching multiple sources. + + • Fix ‘al_get_monitor_info’ (Tobias Scheuer). + +OSX port: + + • Various fixes for OSX 10.6. + + • Fix some Bluetooth mice on OS X (Tom Bass). + + • Fixed deprecation warning when starting OSX console app (Tom Bass). + + • Fix OSX magic main with the LTO switch (Evert Glebbeek). + +Audio addon: + + • Allow setting the buffer size for ALSA. + + • Don’t apply gain twice for sample instances and streams when pan is + not ‘ALLEGRO_PAN_NONE’. + + • Disallow attaching mixers with different channel configurations. + + • Add ‘al_set_sample_instance_channel_matrix’ and + ‘al_set_audio_stream_channel_matrix’. + + • Don’t free the extra pointer in DirectSound if voice fails to play + for some reason. + + • Add ‘al_lock_sample_id’ and ‘al_unlock_sample_id’. + + • For OpenAL, detach from buffers before deleting. + + • Return true when seeking mod audio streams. + +Acodec addon: + + • Free audio stream buffer in flac_stream_close. + + • Add DUMB 2.0 support. + +Color addon: + + • Add XYZ, xyY, Lab and LCH color spaces. + + • Remove “purwablue” named color, add “rebeccablue”. + +Native dialog addon: + + • Improve save dialogs under GTK driver. + + • Improved path behavior in GTK native file dialog ([bk]door.maus). + + • Enable ‘ALLEGRO_FILECHOOSER_FOLDER’ On Linux (Todd Cope). + + • Use unique ids to identify menu items internally, fixing their + event sources. + + • Make the native message box return 2 on Windows when cancel is + pressed. + +Image addon: + + • Set compression level to ‘Z_DEFAULT_COMPRESSION’ in png saver by + default. + + • Make PNG, JPEG compression level configurable. + + • Make PNG gamma value configurable. + + • Add WebP support with libwebp. + +Video addon: + + • Allow calling ‘al_init_video_addon’ after ‘al_shutdown_video_addon’ + was called. + +Build system: + + • Detect and link optional FreeType dependencies. + + • Add a CMake option to prefer static dependencies. + + • Fix SDL platform build. + +Python binding: + + • Fix some corrupted regexps in the generation script (verderten). + +Documentation: + + • Lots of improvements as usual (Edgar Reynaldo, Mark Oates, twobit). + +Examples: + + • Fix various issues with ‘ex_curl’. + + • Fix memory leak in ‘ex_audio_simple’ (Rm Beer). + +Changes from 5.2.1.1 to 5.2.2 (December 2016) +********************************************* + +The main developers this time were: Trent Gamblin, SiegeLord, Elias +Pschernig. + +Core: + + • Don’t accumulate time in the timer while it is stopped. + + • Use dynamic OpenGL ES checks, so binaries produced on newer + platforms don’t crash on older ones. + + • Destabilize the OpenGL extensions API (BREAKING CHANGE!). + +Raspberry Pi port: + + • Add various optimizations. + + • Fix ‘al_set_mouse_xy’ under X. + +Android port: + + • Fix buffer overrun and memory leak in the clipboard support. + + • Add WANT_GLES3 to disable some of the newer features on platforms + where they aren’t supported. + + • Fix build in Android versions below 3.1. + + • Fix a crash when activity is destroyed/paused. + + • Allow building for android mips, arm64 and mips64. + + • Add ‘al_android_get_jni_env’ and ‘al_android_get_activity’ utility + functions. + + • Update manifest files for newer Android versions. + +Windows port: + + • Handle keyboard input properly when Ctrl is pressed (Tobias + Scheuer). + +Hurd port: + + • Define a fallback PATH_MAX (Andreas Rönnquist). + +OSX port: + + • Clear window to black when going in/out of fullscreen. + + • Fix window centering when going out of FULLSCREEN_WINDOW mode. + + • Fix OSX 10.12 build. + + • Allow 32 bit builds on OSX (MarcusCalhoun-Lopez). + +Build system: + + • Fix issues with building on GCC6 on Windows. + + • Fix source directory littering while configuring the Android build. + +Python binding: + + • Add support Python 3 (Gabriel Queiroz). + +Documentation: + + • Document the behavior of ‘al_set_target_bitmap’ with respect to + transformations (Edgar Reynaldo). + + • Fix typo in ‘al_use_transform’ docs (Ryan Roden-Corrent). + +Examples: + + • Add kerning to the ‘al_get_glyph’ example in ex_ttf. + + • Various fixes in ex_camera (Erich Erstu). + +Changes from 5.2.1 to 5.2.1.1 (August 2016) +******************************************* + +The main developers this time were: Trent Gamblin, SiegeLord. + +Core: + + • Enforce backwards compatibility in the version check, rather than + erroneously allowing forwards compatiblity. + + • Temporarily remove new extensions in ALLEGRO_OGL_EXT_LIST as that + broke ABI compatibility. + +OSX port: + + • Temporarily revert changes in joystick detection, as it did not + interact well with some joysticks. + +Windows port: + + • Fix the clear display to black right away to avoid an ugly white + flash change. + +Changes from 5.2.0 to 5.2.1 (July 2016) +*************************************** + +The main developers this time were: Elias Pschernig, Trent Gamblin, +SiegeLord, Ryan Roden-Corrent, Boris Carvajal and Peter Hull. + +Core: + + • Optimize bitmap holding a bit (Bruce Pascoe). + + • Add ‘al_get/set_depth/samples’ (OpenGL only for now). + + • Optimize destruction performance when you have thousands of objects + (e.g. sub-bitmaps). + + • Use low floating point precision for the OpenGL fragment shaders, + which helps performance a lot on mobile platforms. + + • Don’t stop and join the timer thread when stopping the last timer + (prevents unnecessary delay in this situation on some platforms). + + • Add ‘al_backup_dirty_bitmap’ and ‘al_backup_dirty_bitmaps’ to more + finely control when bitmap context backup is performed. + +Android port: + + • Fix Android app issues when woken up during sleep. + + • Specify the Android toolchain file on the command line now. + ANDROID_NDK_TOOLCHAIN_ROOT now has to be specified in an + environment variable. + +OSX port: + + • Improve joystick enumeration (Todd Cope). + + • Make ‘al_set_new_window_title’ work correctly. + + • Don’t send duplicate mouse move events. + + • Fix mouse warping behavior. + + • Exit fullscreen mode if ALLEGRO_FULLSCREEN_WINDOW is set when + destroying a display (otherwise if you destroy and recreate display + without terminating the program, a white window kicks around). + +iOS port: + + • Make it compile again. + + • Don’t backup textures as it is unnecessary. + + • Update minimum iOS to version to 6.1. + + • Disable the native png loader in favor of libpng, as it is broken + on Apple’s end. + + • Create library when creating the archive. + +Windows port: + + • Fix the D3D target bitmap bug. + + • Clear display to black right away to avoid an ugly white flash. + +Raspberry Pi port: + + • Fix system cursor support. + +Linux port: + + • Make ‘al_set_new_window_title’ work correctly. + +Build system: + + • Use PROJECT_SOURCE_DIR and PROJECT_BINARY_DIR instead of + CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR. This lets you use Allegro as + a sub-project in your CMake project. + + • Fix GDIPlus finding in cmake-gui (Bruce Pascoe). + + • Add .gitignore and ignore build/ dir (Mark Oates). + + • Fix building examples with non-Allegro dependencies with the + monolith build. + +Documentation: + + • Various documentation updates (Daniel Johnson and others). + +Other: + + • Add more ‘#include’ statements in Allegro headers, so it’s easier + to use them in isolation (Jordan Woehr). + + • Allow marking tests as being hardware only. + + • Prefix some private Allegro macros and types to not pollute the + namespace. + + • Make set_shader_uniform api const-correct (Bruce Pascoe). + +Audio addon: + + • Adjust loop end position when calling + ‘al_set_sample_instance_length’. + +Acodec addon: + + • Allow file-backed audio streams to be restarted after they finish. + + • Add Opus codec support. + +Image addon: + + • Fail gracefully if not built with PNG/JPG loaders. + +Native dialog addon: + +Font addon: + + • Make ‘al_get_text_dimensions’ and ‘al_get_glyph_dimensions’ return + exact bounding boxes (koro). + + • Add ‘ALLEGRO_GLYPH’ structure and ‘al_get_glyph’, allowing for some + additional optimization when drawing fonts. + +Examples: + + • Add more controls to ‘ex_audio_props’. + + • Add an example of using Enet with Allegro. + +Changes from 5.1.13.1 to 5.2.0 (April 2016) +******************************************* + +The main developers this time were: SiegeLord, Polybios, Mark Oates, +Elias Pschernig and Jonathan Seeley. + +Core: + + • Add ‘al_is_event_source_registered’ (koro). + + • Make destructors log messages more meaningful. + + • Mouse emulation API for touch devices is now unstable. + + • Rename ‘al_convert_bitmaps’ to ‘al_convert_memory_bitmaps’. + +Input: + + • Haptic API is now unstable. + +Android port: + + • Fixed bogus display destruction on Android which previously caused + zombie states. + +OSX port: + + • Fix OSX mouse state position scaling. + + • Fix other various scaling issues. + + • Make toggling ALLEGRO_FRAMELESS work. + + • Fix an issue where fullscreen windows would occasionally leave + empty space for the titlebar. + + • Fix incorrect debug assert in the audio addon. + +Windows port: + + • Make Allegro apps DPI-aware by default, which means that they won’t + be scaled by the OS. + + • Fix compilation for the CPU detection code on some compilers. + + • Don’t sync the D3D bitmap when locking with WRITE_ONLY. + + • Remove dsound.dll runtime loading. + + • Don’t link xinput and d3dx9 libraries (they are still required at + runtime though if you’re using the relevant features). + + • Fix a bug where al_wait_for_event_timed can block despite 0 timeout + (Aldo Nunez). + +Build system: + + • Install PDB files when building with MSVC. + +Documentation: + + • Fix source links for API entries with multi-line prototypes. + + • Make the readme look prettier on GitHub. + + • Tons of assorted documentation improvements, especially for the + audio addon. + +Other: + + • Add a stability system where some unstable APIs need to be opted + into by defining ‘ALLEGRO_UNSTABLE’ before including Allegro + headers. + +Audio addon: + + • Fix sporadic deadlocks + + • Recorder API is now unstable. + +Native dialog addon: + + • ‘al_toggle_menu_item_flags’ is now unstable. + +TTF addon: + + • Add an option to pre-cache the glyphs, useful for platforms where + the current algorithm is buggy (typically some Android devices). + +Video addon: + + • Temporarily remove FFmpeg backend, as it was too buggy, didn’t + build and was too hard to fix. + +Examples: + + • Make ‘ex_vsync’ less likely cause a seizure. + + • Make ‘ex_draw_bitmap’ and ‘ex_touch_input’ switch in/out on + Android. + + • Add documentation to ‘ex_bitmap’ (Daniel Johnson). + + • Improve ‘ex_logo’ text entry experience. + diff --git a/allegro/CMakeLists.txt b/allegro/CMakeLists.txt new file mode 100644 index 00000000..7dcab2bc --- /dev/null +++ b/allegro/CMakeLists.txt @@ -0,0 +1,1200 @@ +# +# +# TODO: +# +# - some documentation targets still missing +# - installing documentation +# + +#-----------------------------------------------------------------------------# +# +# Build system setup +# +#-----------------------------------------------------------------------------# + +# Set the project name. +# We use C++ in a few cases. +set(ALLEGRO_PROJECT_SUFFIX "" CACHE STRING "Project suffix") +set(ALLEGRO_PROJECT_NAME "ALLEGRO" CACHE STRING "Project default name") + +project(${ALLEGRO_PROJECT_NAME}${ALLEGRO_PROJECT_SUFFIX} C CXX) + +cmake_minimum_required(VERSION 2.8.5 FATAL_ERROR) +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) + if(POLICY CMP0026) + cmake_policy(SET CMP0026 NEW) + endif() + if(POLICY CMP0072) + cmake_policy(SET CMP0072 NEW) + endif() + if(POLICY CMP0060) + cmake_policy(SET CMP0060 NEW) + endif() +endif(COMMAND cmake_policy) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Profile." + FORCE) +endif() +# Restrict configuration types to the selected build type. +# Note: This needs to be done before the project command +set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}" CACHE INTERNAL "internal") + +if(ANDROID) + option(WANT_ANDROID_LEGACY "Build for Android 4 (1.6)" OFF) + set(ANDROID_TARGET "android-12" CACHE STRING "What Android target to compile for.") +endif(ANDROID) +option(ALLEGRO_SDL "Build using the SDL backend (experimental)" OFF) +option(WANT_STATIC_RUNTIME "Whether or not to link the C and C++ runtimes statically (currently only implemented on Windows)" OFF) + +set(ALLEGRO_VERSION 5.2.7) +string(REGEX MATCH "^[0-9]+[.][0-9]+" ALLEGRO_SOVERSION ${ALLEGRO_VERSION}) +string(REPLACE "." "" ALLEGRO_DLL_SHORTVER ${ALLEGRO_SOVERSION}) + +# Search in the `cmake' directory for additional CMake modules. +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +# Search in `deps' directories for dependency files. +file(GLOB deps_subdirs + "${PROJECT_SOURCE_DIR}/deps" + "${PROJECT_SOURCE_DIR}/deps/*" + "${PROJECT_BINARY_DIR}/deps" + "${PROJECT_BINARY_DIR}/deps/*" + ) +foreach(subdir ${deps_subdirs}) + if(EXISTS "${subdir}/include" OR EXISTS "${subdir}/lib") + if(CMAKE_FIND_ROOT_PATH) + message(STATUS "Adding ${subdir} to CMAKE_FIND_ROOT_PATH") + list(APPEND CMAKE_FIND_ROOT_PATH "${subdir}") + else() + message(STATUS "Adding ${subdir} to CMAKE_PREFIX_PATH") + list(APPEND CMAKE_PREFIX_PATH "${subdir}") + endif() + endif() +endforeach(subdir) + +# Search for C header files in these directories. +include_directories( + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_BINARY_DIR}/include + ) + +# Put libraries into `lib'. +set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) + +# Lists of all the source files. +include(FileList) + +# Our own CMake macros and functions. +include(Common) + +#-----------------------------------------------------------------------------# +# +# Build options +# +#-----------------------------------------------------------------------------# + +if(NOT IPHONE) + option(SHARED "Build shared libraries" on) + set(BUILD_SHARED_LIBS ${SHARED}) # actual CMake variable +endif(NOT IPHONE) + +# On some 64-bit platforms, libraries should be installed into `lib64' +# instead of `lib'. Set this to 64 to do that. +set(LIB_SUFFIX "" CACHE STRING "Suffix for 'lib' directories, e.g. '64'") + +option(WANT_FRAMEWORKS "Want frameworks on Mac OS X" off) +option(WANT_EMBED + "Make frameworks embeddable in application bundles (Mac OS X)" on) + +set(FRAMEWORK_INSTALL_PREFIX "/Library/Frameworks" CACHE STRING + "Directory in which to install Mac OS X frameworks") + +option(PREFER_STATIC_DEPS "Whether to prefer static dependencies." off) + +# +# Platforms and drivers. +# + +option(WANT_X11 "X11 support" on) +option(WANT_X11_XF86VIDMODE "X11 XF86VidMode Extension support" on) +option(WANT_X11_XINERAMA "X11 Xinerama Extension support" on) +option(WANT_X11_XRANDR "X11 XRandR Extension support" on) +option(WANT_X11_XSCREENSAVER "X11 XScreenSaver Extension support" on) +option(WANT_D3D "Enable Direct3D graphics driver (Windows)" on) +option(WANT_D3D9EX "Enable Direct3D 9Ex extensions (Vista)" off) +option(WANT_OPENGL "Enable OpenGL graphics driver (Windows, X11, OS X))" on) +option(WANT_SHADERS_GL "Build GLSL shader support (OpenGL)" on) +option(WANT_SHADERS_D3D "Build HLSL shader support (Direct3D)" on) + +set(GL_BUILD_TYPE "auto" CACHE STRING "OpenGL profile to build Allegro against") +set_property(CACHE GL_BUILD_TYPE PROPERTY STRINGS "auto;gl;gles1;gles2+") +set(GL_AUTO_BUILD_TYPE "gl") +option(WANT_GLES3 "Use GLES3-only features in a GLES2+ build" off) + +# +# Addons. +# + +option(WANT_FONT "Enable bitmap font add-on" on) +option(WANT_AUDIO "Enable allegro_audio engine" on) +option(WANT_IMAGE "Enable image load/save addon" on) + +if (NOT IPHONE) + option(WANT_IMAGE_JPG "Enable JPEG support in image addon" on) + option(WANT_IMAGE_PNG "Enable PNG support in image addon" on) + option(WANT_IMAGE_FREEIMAGE "Enable FreeImage support in image addon" on) +endif (NOT IPHONE) +option(WANT_IMAGE_WEBP "Enable WebP support in image addon" on) + +option(WANT_TTF "Enable TTF addon" on) +option(WANT_COLOR "Enable color addon" on) +option(WANT_MEMFILE "Enable memfile addon" on) +option(WANT_PHYSFS "Enable PhysicsFS addon" on) +option(WANT_PRIMITIVES "Enable primitives addon" on) +option(WANT_NATIVE_DIALOG "Enable native dialog addon" on) +option(WANT_VIDEO "Enable video player addon" on) + +option(WANT_MONOLITH "Include all addons in the main library" off) + +# +# Wrappers. +# + +option(WANT_PYTHON_WRAPPER "Enable generation of the Python wrapper" off) +option(WANT_LUAJIT "Enable generation of the Luajit wrapper" off) + +# +# Documentation. +# + +option(WANT_DOCS "Generate documentation" on) +option(WANT_DOCS_HTML "Generate HTML documentation" on) +option(WANT_DOCS_MAN "Generate man pages" on) +option(WANT_DOCS_INFO "Generate Info document" off) +option(WANT_DOCS_PDF "Generate PDF document (requires pdflatex)" off) +option(WANT_DOCS_PDF_PAPER "Whether PDF output is destined for paper" off) + +# +# For developers. +# + +option(STRICT_WARN "Halt at warnings" off) +option(WANT_MUDFLAP "Enable gcc mudflap (requires gcc 4.0+)" off) +option(WANT_RELEASE_LOGGING "Enable logging even in release mode" on) + +if(WANT_RELEASE_LOGGING) + set(ALLEGRO_CFG_RELEASE_LOGGING 1) +endif() + +# +# Minor options. +# + +if(NOT IPHONE) + option(WANT_ALLOW_SSE "Allow compiler to use SSE instructions (x86)" on) +endif(NOT IPHONE) + +option(NO_FPU "No floating point unit" off) +option(WANT_DLL_TLS "Force use of DllMain for TLS (Windows)" off) +option(WANT_DEMO "Build demo programs" on) +option(WANT_EXAMPLES "Build example programs" on) +option(WANT_POPUP_EXAMPLES "Use popups instead of printf for fatal errors" on) +option(WANT_TESTS "Build test programs" on) + +option(WANT_WAIT_EVENT_SLEEP "Use sleep instead of threads in al_wait_for_event (only useful for emscripten without web workers)" off) + +if(WANT_WAIT_EVENT_SLEEP) + set(ALLEGRO_WAIT_EVENT_SLEEP 1) +endif() + +#-----------------------------------------------------------------------------# +# +# Set up compilers +# +#-----------------------------------------------------------------------------# + +include(CheckCSourceCompiles) +include(CheckCXXSourceCompiles) + +if(CMAKE_COMPILER_IS_GNUCC) + set(COMPILER_GCC 1) + set(COMPILER_GCC_OR_CLANG 1) +endif() +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(COMPILER_GCC_OR_CLANG 1) +endif() + +if(WIN32) + if(WANT_DLL_TLS AND SHARED) + set(ALLEGRO_CFG_DLL_TLS 1) + endif(WANT_DLL_TLS AND SHARED) +endif(WIN32) + +if(MSVC) + set(COMPILER_MSVC 1) + set(ALLEGRO_MSVC 1) + + # Guess VCINSTALLDIR from the value of CMAKE_C_COMPILER if it's not set. + # XXX CMAKE_C_COMPILER will often be simply "cl" so this won't work. + if("$ENV{VCINSTALLDIR}" STREQUAL "") + string(REGEX REPLACE "/bin/[^/]*$" "" VCINSTALLDIR "${CMAKE_C_COMPILER}") + message(STATUS "Guessed MSVC directory: ${VCINSTALLDIR}") + else("$ENV{VCINSTALLDIR}" STREQUAL "") + file(TO_CMAKE_PATH "$ENV{VCINSTALLDIR}" VCINSTALLDIR) + message(STATUS "Using VCINSTALLDIR: ${VCINSTALLDIR}") + endif("$ENV{VCINSTALLDIR}" STREQUAL "") + + # Install in VCINSTALLDIR by default + if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${VCINSTALLDIR} + CACHE PATH "Install path prefix, prepended onto install directories." + FORCE) + endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + + set(EXECUTABLE_TYPE "WIN32") +endif(MSVC) + +if(MINGW) + # For alplatf.h + set(ALLEGRO_MINGW32 1) + + # Guess MINGDIR from the value of CMAKE_C_COMPILER if it's not set. + if("$ENV{MINGDIR}" STREQUAL "") + string(REGEX REPLACE "/bin/[^/]*$" "" MINGDIR "${CMAKE_C_COMPILER}") + message(STATUS "Guessed MinGW directory: ${MINGDIR}") + else("$ENV{MINGDIR}" STREQUAL "") + file(TO_CMAKE_PATH "$ENV{MINGDIR}" MINGDIR) + message(STATUS "Using MINGDIR: ${MINGDIR}") + endif("$ENV{MINGDIR}" STREQUAL "") + + # Search in MINGDIR for headers and libraries. + if(CMAKE_FIND_ROOT_PATH) + list(APPEND CMAKE_FIND_ROOT_PATH "${MINGDIR}") + else() + list(APPEND CMAKE_PREFIX_PATH "${MINGDIR}") + endif() + + # Install to MINGDIR + if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX ${MINGDIR} + CACHE PATH "Install path prefix, prepended onto install directories." + FORCE) + endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + + # Check for a common problem (at the time of writing). + run_c_compile_test(" + #include <windows.h> + int main(void) + { + int x = DM_POSITION; + return 0; + }" + HAVE_DM_POSITION) + if(NOT HAVE_DM_POSITION) + message(FATAL_ERROR + "Missing DM_POSITION. Please update your MinGW " + "w32api package, delete CMakeCache.txt and try again.") + endif(NOT HAVE_DM_POSITION) +endif(MINGW) + +if(UNIX AND NOT APPLE AND NOT ANDROID) + set(ALLEGRO_UNIX 1) +endif(UNIX AND NOT APPLE AND NOT ANDROID) + +if(APPLE AND NOT IPHONE) + set(MACOSX 1) +endif(APPLE AND NOT IPHONE) + +if(MACOSX) + set(ALLEGRO_MACOSX 1) + set(ALLEGRO_CFG_PTHREADS_TLS 1) + set(ALLEGRO_UNIX 0) + set(WANT_X11 off) + + # This flag is required on some versions of Mac OS X to avoid linker + # problems with global variables which are not explicitly initialised. + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-common") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common") +endif(MACOSX) + +if(IPHONE) + set(ALLEGRO_CFG_PTHREADS_TLS 1) + set(ALLEGRO_IPHONE 1) + set(ALLEGRO_UNIX 0) + set(ALLEGRO_LITTLE_ENDIAN 1) + set(WANT_X11 off) + set(GL_AUTO_BUILD_TYPE "gles2+") + set(WANT_GLES3 yes) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") + set(CMAKE_EXE_LINKER_FLAGS "-framework CoreGraphics -framework QuartzCore -framework UIKit -framework Foundation -framework CoreFoundation -framework MobileCoreServices") +endif(IPHONE) + +if(BORLAND) + set(ALLEGRO_BCC32 1) +endif(BORLAND) + +if(ANDROID) + set(ALLEGRO_ANDROID 1) + set(ALLEGRO_CFG_PTHREADS_TLS 1) + set(WANT_X11 off) + set(GL_AUTO_BUILD_TYPE "gles2+") +endif(ANDROID) + +if(ALLEGRO_RASPBERRYPI) + set(ALLEGRO_CFG_PTHREADS_TLS 1) + set(GL_AUTO_BUILD_TYPE "gles2+") + set(ALLEGRO_EXCLUDE_GLX 1) +endif(ALLEGRO_RASPBERRYPI) + +if(EMSCRIPTEN) + set(GL_AUTO_BUILD_TYPE "gles2+") + set(ALLEGRO_LITTLE_ENDIAN 1) + if (NOT ALLEGRO_SDL) + message(FATAL_ERROR + "Emscripten support currently requires the SDL backend (set ALLEGRO_SDL)") + endif(NOT ALLEGRO_SDL) +endif() + +if(ALLEGRO_SDL) + set(ALLEGRO_UNIX 0) + set(WANT_X11 off) + include(FindSDL2) +endif(ALLEGRO_SDL) + +# Tell the compiler it can use SSE instructions on x86 architectures. +# If compatibility with Pentium 2's and below is required then the user +# should switch WANT_ALLOW_SSE off. + +# Workaround for a possible bug in CMake. Even if we set this variable in +# the toolchain file when cross-compiling, as we should, it is empty. +if(NOT CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_NAME MATCHES "Windows") + set(CMAKE_SYSTEM_PROCESSOR i686) +endif() + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "i.86") + set(ARCH_X86 1) +endif() +# CMake reports "x86" on my Windows Vista machine +if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86") + set(ARCH_X86 1) +endif() + +if(ARCH_X86 AND WANT_ALLOW_SSE) + if(COMPILER_GCC_OR_CLANG) + message(STATUS "Allowing GCC/Clang to use SSE instructions") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse") + endif(COMPILER_GCC_OR_CLANG) + + # Flags for other compilers should be added here. + + if(COMPILER_MSVC) + message(STATUS "Allowing MSVC to use SSE instructions") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:SSE") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE") + endif(COMPILER_MSVC) +endif() + +#-----------------------------------------------------------------------------# +# +# Build types +# +#-----------------------------------------------------------------------------# + +# Warnings. + +if(COMPILER_GCC_OR_CLANG) + set(WFLAGS "-W -Wall -Wpointer-arith") + set(WFLAGS_C_ONLY "-Wmissing-declarations -Wstrict-prototypes") + if(ALLEGRO_UNIX) + # Unfortunately we can't use this flag when magic main is used, + # the mangled_main won't have a forward declaration. + set(WFLAGS_C_ONLY "${WFLAGS_C_ONLY} -Wmissing-prototypes") + endif(ALLEGRO_UNIX) + if(WIN32) + # Helps to ensure the Windows port remains compatible with MSVC. + set(WFLAGS_C_ONLY "${WFLAGS_C_ONLY} -Wdeclaration-after-statement") + endif(WIN32) + if(STRICT_WARN) + set(WFLAGS "${WFLAGS} -Werror") + endif() +endif() +if(COMPILER_MSVC) + set(WFLAGS "/W3 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + # Clang is more strict than MSVC's compiler here. + set(WFLAGS "${WFLAGS} -Wno-c++11-narrowing") + endif() +endif(COMPILER_MSVC) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WFLAGS} ${WFLAGS_C_ONLY}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WFLAGS}") + +if(WANT_MUDFLAP AND COMPILER_GCC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmudflapth") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmudflapth") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fmudflapth -lmudflapth") +endif(WANT_MUDFLAP AND COMPILER_GCC) + +# Debugging. + +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUGMODE=1 -DD3D_DEBUG_INFO") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUGMODE=1 -DD3D_DEBUG_INFO") + +# Profiling. + +list(APPEND CMAKE_BUILD_CONFIGURATIONS Profile) +if(COMPILER_GCC_OR_CLANG) + set(CMAKE_C_FLAGS_PROFILE "-pg" + CACHE STRING "profiling flags") + set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_C_FLAGS_PROFILE}" + CACHE STRING "profiling flags") + set(CMAKE_EXE_LINKER_FLAGS_PROFILE "-pg" + CACHE STRING "profiling flags") + set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "-pg" + CACHE STRING "profiling flags") + mark_as_advanced( + CMAKE_C_FLAGS_PROFILE + CMAKE_CXX_FLAGS_PROFILE + CMAKE_EXE_LINKER_FLAGS_PROFILE + CMAKE_SHARED_LINKER_FLAGS_PROFILE + ) +endif(COMPILER_GCC_OR_CLANG) + +#-----------------------------------------------------------------------------# +# +# Begin tests +# +#-----------------------------------------------------------------------------# + +include(CheckFunctionExists) +include(CheckIncludeFiles) +include(CheckLibraryExists) +include(CheckSymbolExists) +include(CheckTypeSize) +include(FindPkgConfig) + +include(TestBigEndian) + +if(NOT ALLEGRO_BIG_ENDIAN AND NOT ALLEGRO_LITTLE_ENDIAN) + test_big_endian(ALLEGRO_BIG_ENDIAN) + if(NOT ALLEGRO_BIG_ENDIAN) + set(ALLEGRO_LITTLE_ENDIAN 1) + endif(NOT ALLEGRO_BIG_ENDIAN) +endif(NOT ALLEGRO_BIG_ENDIAN AND NOT ALLEGRO_LITTLE_ENDIAN) + +check_include_files(dirent.h ALLEGRO_HAVE_DIRENT_H) +check_include_files(inttypes.h ALLEGRO_HAVE_INTTYPES_H) +check_include_files(linux/input.h ALLEGRO_HAVE_LINUX_INPUT_H) +check_include_files(stdbool.h ALLEGRO_HAVE_STDBOOL_H) +check_include_files(stdint.h ALLEGRO_HAVE_STDINT_H) +check_include_files(sys/io.h ALLEGRO_HAVE_SYS_IO_H) +check_include_files(sys/stat.h ALLEGRO_HAVE_SYS_STAT_H) +check_include_files(sys/time.h ALLEGRO_HAVE_SYS_TIME_H) +check_include_files(time.h ALLEGRO_HAVE_TIME_H) +check_include_files(sys/utsname.h ALLEGRO_HAVE_SYS_UTSNAME_H) +check_include_files(sys/types.h ALLEGRO_HAVE_SYS_TYPES_H) +check_include_files(soundcard.h ALLEGRO_HAVE_SOUNDCARD_H) +check_include_files(sys/soundcard.h ALLEGRO_HAVE_SYS_SOUNDCARD_H) +check_include_files(machine/soundcard.h ALLEGRO_HAVE_MACHINE_SOUNDCARD_H) +check_include_files(linux/soundcard.h ALLEGRO_HAVE_LINUX_SOUNDCARD_H) +check_include_files(libkern/OSAtomic.h ALLEGRO_HAVE_OSATOMIC_H) +check_include_files(sys/inotify.h ALLEGRO_HAVE_SYS_INOTIFY_H) +check_include_files(sal.h ALLEGRO_HAVE_SAL_H) + +check_function_exists(getexecname ALLEGRO_HAVE_GETEXECNAME) +check_function_exists(mkstemp ALLEGRO_HAVE_MKSTEMP) +check_function_exists(mmap ALLEGRO_HAVE_MMAP) +check_function_exists(mprotect ALLEGRO_HAVE_MPROTECT) +check_function_exists(sched_yield ALLEGRO_HAVE_SCHED_YIELD) +check_function_exists(sysconf ALLEGRO_HAVE_SYSCONF) +check_function_exists(fseeko ALLEGRO_HAVE_FSEEKO) +check_function_exists(ftello ALLEGRO_HAVE_FTELLO) +check_function_exists(strerror_r ALLEGRO_HAVE_STRERROR_R) +check_function_exists(strerror_s ALLEGRO_HAVE_STRERROR_S) +if(WIN32) + check_function_exists(_ftelli64 ALLEGRO_HAVE_FTELLI64) + check_function_exists(_fseeki64 ALLEGRO_HAVE_FSEEKI64) +endif() + +check_type_size("_Bool" ALLEGRO_HAVE__BOOL) + +run_c_compile_test(" + #include <sys/procfs.h> + int main(void) { + struct prpsinfo psinfo; + psinfo.pr_argc = 0; + return 0; + }" + ALLEGRO_HAVE_PROCFS_ARGCV + ) + +run_c_compile_test(" + #include <sys/procfs.h> + #include <sys/ioctl.h> + int main(void) { + struct prpsinfo psinfo; + ioctl(0, PIOCPSINFO, &psinfo); + return 0; + }" + ALLEGRO_HAVE_SV_PROCFS_H + ) + +run_c_compile_test(" + #include <stdarg.h> + int main(void) { + va_list a, b; + va_copy(a, b); + return 0; + }" + ALLEGRO_HAVE_VA_COPY + ) + +#-----------------------------------------------------------------------------# +# +# Driver configuration +# +#-----------------------------------------------------------------------------# + +# +# These are the conventions for this CMakeFile. +# +# The WANT_* variables indicate whether the user wants to have an optional +# feature enabled, i.e. whether they have selected something in the CMake UI. +# +# The CAN_* variables indicate whether a feature *can* be enabled on this +# system/platform. As these variable values are cached, CAN_ variables could +# be set even though the user has turned a corresponding WANT_* variable +# off---it might have been tested and set in a previous run. +# +# The SUPPORT_* variables are the conjunction of WANT_FEATURE and CAN_FEATURE, +# i.e. the user wants it and the system can support it. +# +# Those variables are internal to the CMake build. Allegro header files use +# preprocessor constants with names like ALLEGRO_WITH_* and ALLEGRO_HAVE_*. +# Sometimes we make use of those variables in this CMakeFile as well, but +# generally that's just due to sloppiness. +# + +if(PREFER_STATIC_DEPS) + set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_STATIC_LIBRARY_SUFFIX}" + "${CMAKE_SHARED_LIBRARY_SUFFIX}" + "${CMAKE_SHARED_MODULE_SUFFIX}") +endif() + +if(WANT_OPENGL) + find_package(OpenGL) + + if(GL_BUILD_TYPE MATCHES "auto") + set(GL_REAL_BUILD_TYPE ${GL_AUTO_BUILD_TYPE}) + else() + set(GL_REAL_BUILD_TYPE ${GL_BUILD_TYPE}) + endif() + + if(GL_REAL_BUILD_TYPE MATCHES "gl$") + if(OPENGL_FOUND AND OPENGL_GLU_FOUND) + set(SUPPORT_OPENGL 1) + set(ALLEGRO_CFG_OPENGL 1) + set(ALLEGRO_CFG_OPENGL_FIXED_FUNCTION 1) + # We assume that the OpenGL library is not very old. + set(ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE 1) + if(OPENGL_opengl_LIBRARY) # prefer GLVND if available + set(OPENGL_LIBRARIES ${OPENGL_opengl_LIBRARY} ${OPENGL_glu_LIBRARY}) + endif() + include_directories(SYSTEM ${OPENGL_INCLUDE_DIR}) + message("Using OpenGL") + else(OPENGL_FOUND) + if(GL_BUILD_TYPE MATCHES "auto") + set(GL_REAL_BUILD_TYPE "gles2+") + endif() + endif() + endif() + + if(GL_REAL_BUILD_TYPE MATCHES "gles2") + + # on cmake 2.8.1 OpenGL ES is not found in the iphone case + # XXX incorporate IPHONE case into FindOpenGLES/2 + if(IPHONE) + set(OPENGLES2_FOUND 1) + set(OPENGLES2_LIBRARIES "-framework OpenGLES") + elseif(EMSCRIPTEN) + set(OPENGLES2_FOUND 1) + else() + find_package(OpenGLES2) + endif() + + if(OPENGLES2_FOUND) + set(SUPPORT_OPENGL 1) + set(SUPPORT_OPENGLES 1) + set(SUPPORT_OPENGLES2 1) + set(ALLEGRO_CFG_OPENGL 1) + set(ALLEGRO_CFG_OPENGLES 1) + set(ALLEGRO_CFG_OPENGLES2 1) + if(WANT_GLES3) + set(SUPPORT_OPENGLES3 1) + set(ALLEGRO_CFG_OPENGLES3 1) + message("Using OpenGL ES 3.0") + else(WANT_GLES3) + message("Using OpenGL ES 2.0") + endif(WANT_GLES3) + set(ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE 1) + set(OPENGL_LIBRARIES "${OPENGLES2_LIBRARIES}") + if(NOT IPHONE) + include_directories(SYSTEM ${OPENGLES2_INCLUDE_DIR}) + endif() + else(OPENGLES2_FOUND) + if(GL_BUILD_TYPE MATCHES "auto") + set(GL_REAL_BUILD_TYPE "gles1") + endif() + endif(OPENGLES2_FOUND) + endif() + + if(GL_REAL_BUILD_TYPE MATCHES "gles1") + + # on cmake 2.8.1 OpenGL ES is not found in the iphone case + # XXX incorporate IPHONE case into FindOpenGLES/2 + if(IPHONE) + set(OPENGLES1_FOUND 1) + set(OPENGLES1_LIBRARIES "-framework OpenGLES") + else() + find_package(OpenGLES1) + endif() + + if(OPENGLES1_FOUND) + set(SUPPORT_OPENGL 1) + set(SUPPORT_OPENGLES 1) + set(SUPPORT_OPENGLES1 1) + set(ALLEGRO_CFG_OPENGL 1) + set(ALLEGRO_CFG_OPENGLES 1) + set(ALLEGRO_CFG_OPENGLES1 1) + set(ALLEGRO_CFG_OPENGL_FIXED_FUNCTION 1) + message("Using OpenGL ES 1.1") + set(OPENGL_LIBRARIES ${OPENGLES1_LIBRARIES}) + if(NOT IPHONE) + include_directories(SYSTEM ${OPENGLES1_INCLUDE_DIR}) + endif() + endif(OPENGLES1_FOUND) + + endif() + +endif(WANT_OPENGL) + +# +# Unix-specific +# + +if(UNIX) # includes MACOSX + if(NOT IPHONE AND NOT ANDROID) + find_package(Threads) + if(NOT CMAKE_USE_PTHREADS_INIT) + message(FATAL_ERROR + "Unix port requires pthreads support, not detected.") + endif(NOT CMAKE_USE_PTHREADS_INIT) + endif() +endif(UNIX) + +# +# SDL +# + +if(ALLEGRO_SDL AND NOT SUPPORT_OPENGL) + message(FATAL_ERROR "SDL support currently requires OpenGL or OpenGL ES support.") +endif(ALLEGRO_SDL AND NOT SUPPORT_OPENGL) + +# +# X Window System +# + +if(WANT_X11) + find_package(X11) + if(X11_FOUND) + set(SUPPORT_X11 1) + set(ALLEGRO_WITH_XWINDOWS 1) + endif(X11_FOUND) +endif(WANT_X11) + +if(ALLEGRO_UNIX AND NOT SUPPORT_X11 AND WANT_X11) # not MACOSX + message(FATAL_ERROR + "X11 not found. You may need to install X11 development libraries.") +endif(ALLEGRO_UNIX AND NOT SUPPORT_X11 AND WANT_X11) + +if(SUPPORT_X11 AND NOT SUPPORT_OPENGL) + message(FATAL_ERROR "X11 support currently requires OpenGL or OpenGL ES support.") +endif(SUPPORT_X11 AND NOT SUPPORT_OPENGL) + +if(SUPPORT_X11) + set(CMAKE_REQUIRED_LIBRARIES ${X11_LIBRARIES}) + + if (OpenGL_GLX_FOUND) + set(OPENGL_LIBRARIES "${OPENGL_LIBRARIES}" "${OPENGL_glx_LIBRARY}") + endif() + + if (NOT OPENGL_LIBRARIES MATCHES "(libGL\\.|libGLX\\.)" AND NOT ALLEGRO_EXCLUDE_GLX) + message(FATAL_ERROR "X11 support currently requires GLX (set OPENGL_glx_LIBRARY and OpenGL_GLX_FOUND).") + endif() + + check_library_exists(Xcursor XcursorImageCreate "" CAN_XCURSOR) + if(CAN_XCURSOR) + set(ALLEGRO_XWINDOWS_WITH_XCURSOR 1) + find_library(XCURSOR_LIB "Xcursor") + list(APPEND X11_LIBRARIES "${XCURSOR_LIB}") + else(CAN_XCURSOR) + message(FATAL_ERROR "X11 support requires Xcursor library.") + endif(CAN_XCURSOR) + + check_library_exists(Xpm XpmCreatePixmapFromData "" CAN_XPM) + if(CAN_XPM) + set(ALLEGRO_XWINDOWS_WITH_XPM 1) + find_library(XPM_LIB "Xpm") + list(APPEND X11_LIBRARIES "${XPM_LIB}") + endif(CAN_XPM) + + check_include_file("X11/extensions/XInput2.h" CAN_XINPUT2) + run_c_compile_test(" + #include <X11/extensions/XInput2.h> + int main(void) { (void)XI_TouchBegin; return 0; }" + XINPUT2_COMPILES + ) + if(CAN_XINPUT2 AND XINPUT2_COMPILES) + list(APPEND X11_LIBRARIES "Xi") + set(ALLEGRO_XWINDOWS_WITH_XINPUT2 1) + else() + message("XInput2 library version 2.2 or higher not found, disabling touch support.") + endif() + + if(WANT_X11_XF86VIDMODE) + check_include_file("X11/extensions/xf86vmode.h" HAVE_XF86VIDMODE_H) + check_library_exists(Xxf86vm XF86VidModeQueryExtension "" CAN_XF86VIDMODE) + if(CAN_XF86VIDMODE AND HAVE_XF86VIDMODE_H) + set(ALLEGRO_XWINDOWS_WITH_XF86VIDMODE 1) + list(APPEND X11_LIBRARIES "Xxf86vm") + endif() + endif(WANT_X11_XF86VIDMODE) + + if(WANT_X11_XINERAMA) + check_include_file("X11/extensions/Xinerama.h" HAVE_XINERAMA_H) + check_library_exists(Xinerama XineramaQueryExtension "" CAN_XINERAMA) + if(CAN_XINERAMA AND HAVE_XINERAMA_H) + set(ALLEGRO_XWINDOWS_WITH_XINERAMA 1) + find_library(XINERAMA_LIB "Xinerama") + list(APPEND X11_LIBRARIES "${XINERAMA_LIB}") + endif() + endif(WANT_X11_XINERAMA) + + if(WANT_X11_XRANDR) + check_include_file("X11/extensions/Xrandr.h" HAVE_XRANDR_H) + check_library_exists(Xrandr XRRQueryExtension "" CAN_XRANDR) + if(CAN_XRANDR AND HAVE_XRANDR_H) + set(ALLEGRO_XWINDOWS_WITH_XRANDR 1) + find_library(XRANDR_LIB "Xrandr") + list(APPEND X11_LIBRARIES "${XRANDR_LIB}") + endif() + endif(WANT_X11_XRANDR) + + if(WANT_X11_XSCREENSAVER) + check_include_file("X11/extensions/scrnsaver.h" HAVE_XSCREENSAVER_H) + check_library_exists(Xss XScreenSaverQueryExtension "" CAN_XSCREENSAVER) + if(CAN_XSCREENSAVER AND HAVE_XSCREENSAVER_H) + set(ALLEGRO_XWINDOWS_WITH_XSCREENSAVER 1) + find_library(XSCREENSAVER_LIB "Xss") + list(APPEND X11_LIBRARIES "${XSCREENSAVER_LIB}") + endif() + endif(WANT_X11_XSCREENSAVER) + + if(NOT ALLEGRO_RASPBERRYPI) + check_library_exists(X11 XOpenIM "" CAN_XIM) + if(CAN_XIM) + set(ALLEGRO_XWINDOWS_WITH_XIM 1) + endif(CAN_XIM) + endif(NOT ALLEGRO_RASPBERRYPI) + + set(CMAKE_REQUIRED_LIBRARIES) +endif(SUPPORT_X11) + +# +# Windows +# + +if(WIN32) + find_package(DirectX) + + if(DINPUT_FOUND) + # At least some copies of dinput.h redefine some types multiple times. + # We must add the directory as a system directory so that the compiler + # will suppress such errors. + include_directories(${DINPUT_INCLUDE_DIR}) + else(DINPUT_FOUND) + message(FATAL_ERROR + "Windows port requires DirectInput (not found).") + endif(DINPUT_FOUND) + + # Xinput support for xbox compatible controllers. + if(XINPUT_FOUND) + set(SUPPORT_XINPUT 1) + set(ALLEGRO_CFG_XINPUT 1) + endif(XINPUT_FOUND) + + if(WANT_D3D) + if(D3D9_FOUND) + set(SUPPORT_D3D 1) + set(ALLEGRO_CFG_D3D 1) + endif(D3D9_FOUND) + endif(WANT_D3D) + + if(SUPPORT_D3D) + if(D3DX9_FOUND) + include_directories(BEFORE ${D3DX9_INCLUDE_DIR}) + set(ALLEGRO_CFG_D3DX9 1) + else() + message("D3DX9 not found. You will not be able to compress or " + "decompress textures on the GPU.") + endif() + endif(SUPPORT_D3D) + + if(WANT_D3D9EX AND SUPPORT_D3D) + set(ALLEGRO_CFG_D3D9EX 1) + endif(WANT_D3D9EX AND SUPPORT_D3D) + +endif(WIN32) + +#-----------------------------------------------------------------------------# +# +# Main library +# +#-----------------------------------------------------------------------------# + +if(WIN32 AND SHARED) + if(NOT SUPPORT_D3D OR NOT SUPPORT_OPENGL) + message("WARNING: " + "Both D3D and OpenGL should be present for the SHARED build " + " to ensure maximum DLL compatibility.") + endif(NOT SUPPORT_D3D OR NOT SUPPORT_OPENGL) +endif(WIN32 AND SHARED) + +# List of source files need to compile Allegro in this configuration on +# this platform. +set(LIBRARY_SOURCES + ${ALLEGRO_SRC_FILES} + ) + +# Libraries that we always need to link against on this platform. +set(PLATFORM_LIBS) + +if(ALLEGRO_UNIX) # not MACOSX + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_UNIX_FILES}) + list(APPEND PLATFORM_LIBS m ${CMAKE_THREAD_LIBS_INIT}) +endif(ALLEGRO_UNIX) + +if(SUPPORT_X11 AND NOT ALLEGRO_RASPBERRYPI) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_X_FILES}) + list(APPEND PLATFORM_LIBS ${X11_LIBRARIES}) +endif(SUPPORT_X11 AND NOT ALLEGRO_RASPBERRYPI) + +if(WIN32) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_WIN_FILES}) + list(APPEND PLATFORM_LIBS + user32 gdi32 comdlg32 ole32 winmm kernel32 psapi shlwapi + ) + if(SUPPORT_D3D) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_D3D_FILES}) + list(APPEND PLATFORM_LIBS ${D3D9_LIBRARIES}) + endif(SUPPORT_D3D) + + list(APPEND PLATFORM_LIBS ${DINPUT_LIBRARIES}) + if(MINGW AND NOT SHARED) + list(APPEND PLATFORM_LIBS stdc++) + endif(MINGW AND NOT SHARED) +endif(WIN32) + +if(MACOSX) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_MACOSX_FILES}) + find_library(APPKIT_LIBRARY AppKit) + find_library(IOKIT_LIBRARY IOKit) + find_library(COREVIDEO_LIBRARY CoreVideo) + list(APPEND PLATFORM_LIBS ${APPKIT_LIBRARY}) + list(APPEND PLATFORM_LIBS ${IOKIT_LIBRARY}) + list(APPEND PLATFORM_LIBS ${COREVIDEO_LIBRARY}) +endif(MACOSX) + +if(IPHONE) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_IPHONE_FILES}) +endif(IPHONE) + +if(ANDROID) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_ANDROID_FILES}) + list(APPEND PLATFORM_LIBS m log) +endif(ANDROID) + +if(ALLEGRO_RASPBERRYPI) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_RASPBERRYPI_FILES}) + list(APPEND PLATFORM_LIBS ${X11_LIBRARIES}) +endif(ALLEGRO_RASPBERRYPI) + +if(SUPPORT_OPENGL) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_OPENGL_FILES}) + if(WIN32) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_WGL_FILES}) + endif(WIN32) + list(APPEND PLATFORM_LIBS ${OPENGL_LIBRARIES}) +endif(SUPPORT_OPENGL) + +if(SUPPORT_OPENGL AND WANT_SHADERS_GL AND NOT ALLEGRO_CFG_OPENGLES1) + set(ALLEGRO_CFG_SHADER_GLSL 1) +endif() + +if(SUPPORT_D3D AND WANT_SHADERS_D3D AND D3DX9_FOUND) + set(ALLEGRO_CFG_SHADER_HLSL 1) +endif() + +# Header files that we need to install. +set(ALLEGRO_PUBLIC_HEADERS + ${ALLEGRO_INCLUDE_ALLEGRO_FILES} + ${ALLEGRO_INCLUDE_ALLEGRO_INLINE_FILES} + ${ALLEGRO_INCLUDE_ALLEGRO_INTERNAL_FILES} + ${ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES} + ) +if(WIN32) + list(APPEND ALLEGRO_PUBLIC_HEADERS + ${ALLEGRO_INCLUDE_ALLEGRO_WINDOWS_FILES} + ) +endif(WIN32) +if(MACOSX) + list(APPEND ALLEGRO_PUBLIC_HEADERS + ${ALLEGRO_INCLUDE_ALLEGRO_MACOSX_FILES} + ) +endif(MACOSX) +if(IPHONE) + list(APPEND ALLEGRO_PUBLIC_HEADERS + ${ALLEGRO_INCLUDE_ALLEGRO_IPHONE_FILES} + ) +endif(IPHONE) +if(SUPPORT_X11 AND NOT ALLEGRO_RASPBERRYPI) + list(APPEND ALLEGRO_PUBLIC_HEADERS + ${ALLEGRO_INCLUDE_ALLEGRO_X_FILES} + ) +endif(SUPPORT_X11 AND NOT ALLEGRO_RASPBERRYPI) +if(ANDROID) + list(APPEND ALLEGRO_PUBLIC_HEADERS ${ALLEGRO_INCLUDE_ALLEGRO_ANDROID_FILES}) +endif(ANDROID) +if(SUPPORT_OPENGL) + list(APPEND ALLEGRO_PUBLIC_HEADERS + ${ALLEGRO_INCLUDE_ALLEGRO_OPENGL_FILES} + ${ALLEGRO_INCLUDE_ALLEGRO_OPENGL_GLEXT_FILES} + ) +endif(SUPPORT_OPENGL) + +foreach(genfile ${ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES_GENERATED}) + list(APPEND ALLEGRO_PUBLIC_HEADERS + ${CMAKE_CURRENT_BINARY_DIR}/${genfile} + ) +endforeach(genfile) + +if(ALLEGRO_SDL) + list(APPEND LIBRARY_SOURCES ${ALLEGRO_SRC_SDL_FILES}) + list(APPEND PLATFORM_LIBS ${SDL2_LIBRARY} m) + include_directories(${SDL2_INCLUDE_DIR}) +endif(ALLEGRO_SDL) + +set_our_header_properties(${ALLEGRO_PUBLIC_HEADERS}) + +if(NOT WANT_MONOLITH) + # ALLEGRO_LIB_BUILD is defined for all Allegro sources (core and addon) + # ALLEGRO_SRC is defined only while compiling the core sources (its use is + # to get the DLL #defines right under Windows for creating DLL export + # functions when it is defined or import DLL functions when it is not). + add_our_library(allegro + Allegro-${ALLEGRO_SOVERSION} + "${LIBRARY_SOURCES};${ALLEGRO_PUBLIC_HEADERS}" + "${LIBRARY_CFLAGS} -DALLEGRO_SRC" + "${PLATFORM_LIBS}" + ) +endif(NOT WANT_MONOLITH) + +# Addons and examples should link with this target. +set(ALLEGRO_LINK_WITH allegro) + +install_our_headers(${ALLEGRO_PUBLIC_HEADERS}) + +#-----------------------------------------------------------------------------# +# +# Add-ons +# +#-----------------------------------------------------------------------------# + +set(MONOLITH_SOURCES ${LIBRARY_SOURCES}) + +add_subdirectory(addons) + +if(WANT_MONOLITH) + include_directories(${MONOLITH_INCLUDE_DIRECTORIES}) + + # For OSX, we need to set the header location inside the framework for each + # file (relative to the current directory, so for example when the + # AllegroImage framework is built we need to set the path for + # allegro5/allegro_image.h but when the AllegroMonolith framework is built + # we need to set the path for addons/image/allegro5/allegro_image.h - + # otherwise the header is silently missing). + set_our_header_properties(${MONOLITH_HEADERS}) + + link_directories(${MONOLITH_LINK_DIRECTORIES}) + add_our_library(allegro_monolith + AllegroMonolith-${ALLEGRO_SOVERSION} + "${MONOLITH_SOURCES};${ALLEGRO_PUBLIC_HEADERS}" + "${LIBRARY_CFLAGS} -DALLEGRO_SRC ${MONOLITH_DEFINES}" + "${PLATFORM_LIBS};${MONOLITH_LIBRARIES}" + ) + + set(ALLEGRO_MONOLITH_LINK_WITH allegro_monolith) +endif(WANT_MONOLITH) + +#-----------------------------------------------------------------------------# +# +# Produce configuration file +# +#-----------------------------------------------------------------------------# + +if(NO_FPU) + set(ALLEGRO_CFG_NO_FPU 1) +endif(NO_FPU) + +# All relevant variables must be set before here. +configure_file( + include/allegro5/platform/alplatf.h.cmake + ${PROJECT_BINARY_DIR}/include/allegro5/platform/alplatf.h + ) + +#-----------------------------------------------------------------------------# +# +# Android +# +#-----------------------------------------------------------------------------# + +if(ANDROID) + include(AndroidApp) + add_subdirectory(android) +endif(ANDROID) + +#-----------------------------------------------------------------------------# +# +# Demo +# +#-----------------------------------------------------------------------------# + +if(NOT MSVC80 AND WANT_DEMO) # XXX disabled because it breaks MSVC's intellisense for some reason + add_subdirectory(demos/cosmic_protector) + add_subdirectory(demos/speed) + add_subdirectory(demos/skater) +endif(NOT MSVC80 AND WANT_DEMO) + +#-----------------------------------------------------------------------------# +# +# Examples +# +#-----------------------------------------------------------------------------# + +if(WANT_EXAMPLES) + add_subdirectory(examples) +endif(WANT_EXAMPLES) + +#-----------------------------------------------------------------------------# +# +# Tests +# +#-----------------------------------------------------------------------------# + +if(WANT_TESTS) + add_subdirectory(tests) +endif(WANT_TESTS) + +#-----------------------------------------------------------------------------# +# +# contrib/Luajit +# +#-----------------------------------------------------------------------------# + +if(WANT_LUAJIT) + add_subdirectory(contrib/luajit) +endif(WANT_LUAJIT) + +#-----------------------------------------------------------------------------# +# +# pkg-config files +# +#-----------------------------------------------------------------------------# + +set(prefix "${CMAKE_INSTALL_PREFIX}") +set(INCLUDE_PREFIX "\${prefix}") +# XXX these should be configurable separately +set(bindir "\${exec_prefix}/bin") +set(includedir "\${prefix}/include") +set(libdir "\${exec_prefix}/lib${LIB_SUFFIX}") + +if(WANT_MONOLITH) + set(PKG_CONFIG_FILES allegro_monolith) +else() + set(PKG_CONFIG_FILES allegro ${ADDON_PKG_CONFIG_FILES}) +endif(WANT_MONOLITH) + +# Install pkg-config files on Unix, and when cross-compiling on Unix. + +if(UNIX AND NOT WANT_FRAMEWORKS AND NOT IPHONE) + set(INSTALL_PKG_CONFIG_FILES true) +endif() +if(CMAKE_CROSSCOMPILING AND CMAKE_HOST_UNIX) + set(INSTALL_PKG_CONFIG_FILES true) +endif() + +if(INSTALL_PKG_CONFIG_FILES) + append_lib_type_suffix(lib_type) + append_lib_linkage_suffix(lib_linkage) + + # Our pkg-config files are now named allegro*-5.pc, which will + # work across branches. Allegro 5.0.8 and prior used the names + # allegro*-5.0.pc so on the 5.0 branch we will continue to install + # those files, for backwards compatibility. + foreach(versuffix 5) + foreach(name ${PKG_CONFIG_FILES}) + if (SHARED) + set(outname ${name}${lib_type}-${versuffix}.pc) + else (SHARED) + # For static linking: get extra libraries to link with. + get_target_property(link_with ${name} static_link_with) + set(outname ${name}${lib_type}-static-${versuffix}.pc) + endif (SHARED) + configure_file( + misc/${name}.pc.in + ${LIBRARY_OUTPUT_PATH}/pkgconfig/${outname} + @ONLY + ) + install(FILES ${LIBRARY_OUTPUT_PATH}/pkgconfig/${outname} + DESTINATION "lib${LIB_SUFFIX}/pkgconfig" + ) + endforeach(name) + endforeach(versuffix) +endif(INSTALL_PKG_CONFIG_FILES) + +#-----------------------------------------------------------------------------# +# +# Documentation +# +#-----------------------------------------------------------------------------# + +if(WANT_DOCS) + add_subdirectory(docs) +endif(WANT_DOCS) + +#-----------------------------------------------------------------------------# +# +# Wrappers +# +#-----------------------------------------------------------------------------# + +if(WANT_PYTHON_WRAPPER) + add_subdirectory(python) +endif(WANT_PYTHON_WRAPPER) + +#-----------------------------------------------------------------------------# +# vim: set sts=4 sw=4 et: diff --git a/allegro/CONTRIBUTORS.txt b/allegro/CONTRIBUTORS.txt new file mode 100644 index 00000000..c079fa61 --- /dev/null +++ b/allegro/CONTRIBUTORS.txt @@ -0,0 +1,99 @@ +People who have contributed code to Allegro 5: + +Aaron Bolyard +Aldo Nunez +Aldrik Ramaekers +Andreas Rönnquist +Angelo Mottola +Arves100 +BQ +Ben Davis +Beoran +Boris Carvajal +Bruce Pascoe +Bruno Félix Rezende Ribeiro +Chris Robinson +Christian Mauduit (ufoot) +Daniel Johnson +David Capello +Dennis Busch +Dennis Gooden +Doug Thompson +Douglas Mencken +Edgar Reynaldo +ElectricSolstice +Elias Pschernig +Eric Botcazou +Erich Erstu +Evert Glebbeek +Firat Salgur +Gabriel Queiroz +George Foot +Grzegorz Adam Hankiewicz +Henrik Stokseth +Hyena +Isaac Cruz +Javier González Garcés +Jeff Bernard +John-Kim Murphy +Jonathan Lilliemarck +Jonathan Seeley +Jordan Woehr +Julian Smythe +Marcus Calhoun-Lopez +Mark Oates +Markus Henschel +Martijn van Iersel +Matt Smith +Matthew Leverton +Max Savenkov +Michael Bukin +Michael Swiger +Michał Cichoń +Miguel A. Gavidia +Milan Mimica +Nick Black +Nick Trout +Peter Hull +Peter Wang +Polybios +Reuben Bell +Robert MacGregor +Robert Ohannessian +Rodolfo Lam +Ryan Dickie +Ryan Gumbs +Ryan Patterson +Ryan Roden-Corrent +Sebastian Krzyszkowiak +SiegeLord +Simon Naarmann +sleepywind +Steven Wallace +Sven Sandberg +Thomas Fjellstrom +Tobias Hansen +Tobias Scheuer +Todd Cope +Tom Bass +Trent Gamblin +Vitaliy V. Tokarev +[bk]door.maus +beoran +gameovera +jmasterx +juvinious +kazzmir +koro +pedro-w +pkrcel +simast +sleepywind +torhu +twobit +verderten +vkensou + +Please let us know if we left anyone out. + +We must also thank everyone who contributed to previous versions of Allegro! diff --git a/allegro/LICENSE.txt b/allegro/LICENSE.txt new file mode 100644 index 00000000..36491508 --- /dev/null +++ b/allegro/LICENSE.txt @@ -0,0 +1,94 @@ +Copyright (c) 2004-2015 the Allegro 5 Development Team + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + +------------------------------------------------------------------------------- + +Allegro includes some files from bstrlib under the following terms. +<http://bstring.sourceforge.net/> + +Copyright (c) 2002-2008 Paul Hsieh +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + Neither the name of bstrlib nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------------- + +Allegro includes the following files originally based on SDL 2.0.0: + +- src/macosx/osxclipboard.c +- src/win/wclipboard.c +- src/x/xclipboard.c + +These files are licensed under the under the following terms: + + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +------------------------------------------------------------------------------- + +Some Allegro examples use a font from DejaVu fonts, their license can +be found here: +<http://dejavu-fonts.org/wiki/index.php?title=License> + +------------------------------------------------------------------------------- + +The Cosmic Protector demo game graphics were made by Tony Huisman, and are +included under a Creative Commons BY Attribution license. + diff --git a/allegro/README.txt b/allegro/README.txt new file mode 100644 index 00000000..e4a2ee27 --- /dev/null +++ b/allegro/README.txt @@ -0,0 +1,177 @@ +Welcome to Allegro! +=================== + +Allegro is a cross-platform library mainly aimed at video game and +multimedia programming. It handles common, low-level tasks such as +creating windows, accepting user input, loading data, drawing images, +playing sounds, etc. and generally abstracting away the underlying +platform. However, Allegro is not a game engine: you are free to design +and structure your program as you like. + +Allegro 5 has the following additional features: + +- Supported on Windows, Linux, Mac OSX, iPhone and Android +- User-friendly, intuitive C API usable from C++ and many other programming languages +- Hardware accelerated bitmap and graphical primitive drawing support (via OpenGL or Direct3D) +- Audio recording support +- Font loading and drawing +- Video playback +- Abstractions over shaders and low-level polygon drawing +- And more! + +This readme contains general information which applies to all platforms +that Allegro builds on. + +README_cmake.txt discusses some build options for cmake. + +README_msvc.txt discusses compilation on Windows with Microsoft Visual C/C++. + +README_make.txt discusses compilation with GNU make. This applies to Unix-like +operating systems such as Linux, MacOS X and MinGW on Windows. + +README_macosx.txt has a few additional notes for MacOS X. + +README_iphone.txt discusses iPhone operating systems. + + + +Requirements +============ + +We assume you have C and C++ compilers installed and functioning. +We support gcc, clang and MSVC. + +Allegro also requires CMake 2.8.5 or later to build. +You may download it from <http://www.cmake.org/> + + + +Library dependencies +==================== + +Allegro is divided into a core library and a number of addon libraries. +The core library depends on certain libraries to function. If you don't have +those, nothing will work. These are required for the core library: + +- DirectX SDK (Windows only) + + You can get this for MSVC from the Microsoft web site (large download). + + Alternatively, smaller downloads for MSVC and MinGW are available + here: <http://liballeg.org/download.html#miscellaneous-files>. Some + MinGW distributions come with sufficient DirectX SDK to support + compiling Allegro. + +- X11 development libraries (Linux/Unix only) + The libraries will be part of your Linux distribution, but you may have to + install them explicitly. + +- OpenGL development libraries (optional only on Windows) + +The addons, too, may require additional libraries. Since the addons are +strictly optional, they are not required to build Allegro, but a lot of +functionality may be disabled if they are not present. + +Windows users may find some precompiled binaries for the additional libraries +from <http://gnuwin32.sourceforge.net/>. You need to get the `bin` and `lib` +packages. The `bin` packages contain DLLs, and the `lib` packages contain the +headers and import libraries. + +Mac users may find some dependencies in Homebrew, Fink or MacPorts. +<http://brew.sh/>, <http://www.finkproject.org/> and +<http://www.macports.org/> + +Linux users likely have all the dependencies already, except PhysicsFS +and DUMB. If your distribution uses separate development packages, they +will need to be installed. The packages are probably named *-dev or *-devel. + +These are the dependencies required for the addons: + +- libpng and zlib, for PNG image support (Unix and older MinGW only) + Home page: <http://www.libpng.org/pub/png/> + Windows binaries: <http://gnuwin32.sourceforge.net/packages/libpng.htm> + + On Windows/Mac OS X/iPhone/Android, PNG image support is available by + using the native facilities on the respective operating systems, so + libpng is not required. + +- libjpeg, for JPEG image support (Unix and older MinGW only) + Home page: <http://www.ijg.org/> + Windows binaries: <http://gnuwin32.sourceforge.net/packages/jpeg.htm> + + On Windows/Mac OS X/iPhone/Android, JPEG image support is available + by using the native facilities on the respective operating systems, + so libjpeg is not required. + +- libwebp, for WebP image support + Home page: <https://developers.google.com/speed/webp/> + + On Android, WebP image support is available by using the native + facilities of the operating system, so libwebp is not required. + +- FreeType, for TrueType font support. + Home page: <http://freetype.sourceforge.net/> + Windows binaries: <http://gnuwin32.sourceforge.net/packages/freetype.htm> + +- Ogg Vorbis, a free lossy audio format. (libogg, libvorbis, libvorbisfile) + Home page: <http://www.vorbis.com/> + +- Opus, a free lossy audio codec. (libogg, libopus, libopusfile) + Home page: <http://www.opus-codec.org/> + +- FLAC, a free lossless audio codec. (libFLAC, libogg) + Home page: <http://flac.sourceforge.net/> + +- DUMB, an IT, XM, S3M and MOD player library. (libdumb) + Home page: <http://dumb.sourceforge.net/> + +- OpenAL, a 3D audio API. + The audio addon can use OpenAL, although the 3D capabilities aren't used. + <http://kcat.strangesoft.net/openal.html> + + On Mac OS X, OpenAL is *required* but should come with the OS anyway. + + On Linux and Windows, OpenAL will only be used if you request it, hence there + is no reason to install it specifically. + +- PhysicsFS, provides access to archives, e.g. .zip files. + Home page: <http://icculus.org/physfs/> + +On Windows it may be a pain to place all these libraries such that they can be +found. Please see the README_cmake.txt section on the "deps subdirectory" +when the time comes. + + + +API documentation +================= + +To build the documentation you will need Pandoc. +Pandoc's home page is <http://johnmacfarlane.net/pandoc/> + +Installing Pandoc from source can be challenging, but you can build Allegro +without building the documentation. + +Online documentation is available on the Allegro web site: +<http://docs.liballeg.org/> + + + +Building with CMake +=================== + +Building with CMake is a two step process. During the _configuration_ step, +cmake will detect your compiler setup and find the libraries which are +installed on your system. At the same time, you may select options to +customise your build. If you are unsure of what you are doing, leave all the +options at the defaults. + +Once the configuration step is successful, you will invoke another tool to +build Allegro. The tool depends on your compiler, but is usually either +`make`, or your IDE. + +To avoid problems, unpack Allegro into a directory *without spaces or other +"weird" characters in the path*. This is a known problem. + +Now read README_msvc.txt, README_make.txt or README_macosx.txt. + diff --git a/allegro/README_android.txt b/allegro/README_android.txt new file mode 100644 index 00000000..506009f8 --- /dev/null +++ b/allegro/README_android.txt @@ -0,0 +1,384 @@ +Android +======= + +This port should support Android 3.1 (Honeycomb, API level 13) and above. + + +Dependencies +============ + +This port depends on having CMake, the Android SDK, the Android NDK and +a Java JDK. + +We assume you are building on Linux or otherwise a Unix-like system, +including MSYS. + + +Install the SDK +=============== + + +The most simple way is to install Android Studio which by default will +place a copy of the SDK into ~/Android/Sdk. + +Alternatively you can also download the command-line SDK tools. In that +case you will have to accept the licenses, for example like this: + + ~/Android/Sdk/tools/bin/sdkmanager --licenses + + +Install the NDK +=============== + + +The most simple way is again to use Android Studio. Create a new project +with C++ support and it will ask you if you want to install the NDK and +will then proceed to place it into ~/Android/Sdk/ndk-bundle. + +Alternatively you can download the NDK and place anywhere you like. + + +Java +==== + + +Android Studio comes with a java runtime environment. To use it for +building Android libraries set the evironment variable JAVA_HOME like +this: + +export JAVA_HOME=~/android-studio/jre + + + +Build dependencies for Allegro +============================== + +Now you should build the dependencies for the Allegro addons that you want +(you can skip this if just want to try out some simple examples). Most of +the libraries use the standard GNU build system, and follow the same pattern. +For example, to build libpng: + + tar zxf libpng-1.6.37.tar.xz + cd libpng-1.6.37 + # see https://developer.android.com/ndk/guides/other_build_systems + export ABI=armeabi-v7a + export HOST=arm-linux-androideabi + export CHOST=armv7a-linux-androideabi + export SDK=21 + export HOST_TAG=linux-x86_64 + export PREFIX=$HOME/allegro/build/deps + export NDK=$HOME/Android/Sdk/ndk-bundle + export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG + export AR=$TOOLCHAIN/bin/$HOST-ar + export AS=$TOOLCHAIN/bin/$HOST-as + export CC=$TOOLCHAIN/bin/$CHOST$SDK-clang + export CXX=$TOOLCHAIN/bin/$CHOST$SDK-clang++ + export LD=$TOOLCHAIN/bin/$HOST-ld + export RANLIB=$TOOLCHAIN/bin/$HOST-ranlib + export STRIP=$TOOLCHAIN/bin/$HOST-strip + ./configure --host $HOST --prefix $PREFIX + make + make install + +For HOST_TAG you will want: + linux-x86_64 if you are using Linux + darwin-x86_64 in OSX + windows in 32-bit Windows + windows-x86_64 in 64-bit Windows + +For ABI and HOST you will generally use the following (use a separate build folder for each): + + if ABI == "x86" then HOST = "i686-linux-android" + if ABI == "x86_64" then HOST = "x86_64-linux-android" + if ABI == "armeabi-v7" then HOST = "arm-linux-androideabi" + if ABI == "arm64-v8a" then HOST = "aarch64-linux-android" + +CHOST is HOST, except if ABI is armeabi-v7 then CHOST = "armv7a-linux-android". + +The above commands will usually install both static and shared libraries into +the `deps` directory where it can be found by CMake, next. If you want only +static or shared libraries, you can usually pass `--disable-static` or +`--disable-shared` to configure. + +The static libraries should be easier to use (though I often had problems with +unresolved symbols when it came to run the programs, to investigate later). + +If you wish to use shared libraries, be aware that shared objects must be +named like "libFOO.so", despite standard practice. Most libraries you build +will have version suffixes by default, e.g. libpng16.so.1.6. Renaming the +file after it is produced will not work as the versions are embedded as the +soname. For libraries built using libtool, you can avoid the version suffixes +as follows: + + make LDFLAGS=-avoid-version + make LDFLAGS=-avoid-version install + +though you may want to edit the Makefiles instead to avoid overriding +important flags in LDFLAGS. + +You need to ensure that CMake finds the the library file that matches the +soname. Either delete the symlinks (e.g. libpng.so -> libpng16.so) +or modify the paths in CMake variables manually. + + +Building Allegro +================ + +The following steps will build Allegro for Android. It uses the cmake +toolchain provided by the Android NDK. (Adjust the path if yours is not +under ~/Android/Sdk/ndk-bundle.) + + mkdir build_android_armeabi-v7a + cd build_android_armeabi-v7a + cmake .. -DCMAKE_TOOLCHAIN_FILE=~/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake + -DANDROID_ABI=armeabi-v7a + -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DWANT_EXAMPLES=ON + -DCMAKE_INSTALL_PREFIX=~/allegro/build/deps + +You can also use all the normal cmake options supported by Allegro or +run cmake (or cmake-gui) to modify them. + + Finally run: + + make + make install + +Change ANDROID_ABI to whichever architecture you are building for. +The recognized architectures are: + + -DANDROID_ABI="armeabi" + -DANDROID_ABI="armeabi-v7a" + -DANDROID_ABI="armeabi-v7a with NEON" + -DANDROID_ABI="arm64-v8a" + -DANDROID_ABI="x86" + -DANDROID_ABI="x86_64" + +See here for more information: https://developer.android.com/ndk/guides/abis.html + +This produces the normal Allegro native libraries (liballegro-*.so) as +well as allegro-release.aar. + +You may want to add -DWANT_MONOLITH=ON if you prefer a single Allegro library +instead of one for each addon. + + +Running examples +================ + +You need the adb tool (the Android Debug Bridge) set up, and USB debugging +enabled on your device or emulator. This can be quite involved, so please +refer to the Android tool documentation. + +There are makefile targets named "run_FOO", so you can install and run +examples easily by typing, e.g. + + make run_speed + +Many demos and examples do work, minimally, but most do not support touch +input or react to orientation changes, etc. Good examples to try are +ex_draw_bitmap and ex_touch_input. + +If you want to build just the .apk for an example, there are targets +for that as well: + + make ex_draw_bitmap_apk + adb -d install -r ./examples/ex_draw_bitmap.project/app/build/outputs/apk/debug/app-debug.apk + adb -d shell 'am start -n org.liballeg.ex_draw_bitmap/org.liballeg.app.MainActivity' + + +How startup works on Android +============================ + +The startup process begins with your application's MainActivity class. +In the static initialiser for the Activity, you must manually load the +shared libraries that you require, i.e. Allegro and its addons, +with dependencies loaded first. For a C++ program, you may need to load +the shared library of your chosen STL implementation. + +After that the onCreate method of the AllegroActivity will be executed, which +does some Allegro initialisation. Allegro will then load your application +from another shared library. The library name can be specified by overriding +the constructor in your Activity class, otherwise the default is "libapp.so". +After loading, the `main` function in the library is finally called. + +Poking around in the android/example directory may help. + + +Using Allegro in your game +========================== + +If you build with examples or demos, look into your build folder for +any of them, for example + +build/demos/speed + +It will have a folder called speed.project which is a gradle project +ready to compile for Android. You can use it as a template for your +own game code. (Either by opening it in Android Studio or by using +commandline gradle to compile.) + +Read the next section if you would like to create an Android project +using Allegro from scratch. + + +Using Allegro in a new project +============================== + +Start Android Studio. + +Note: Android Studio is not strictly required, you can edit the files mentioned +below with any text editor instead of in Android Studio and run ./gradlew instead +of rebuilding from within the IDE. +Android Studio just is usually more convenient to use when porting a game to Android. + +On the welcome dialog, select "Start a new Android Studio project". + +On the "Create Android Project" screen, make sure to check the +"Include C++ support" checkbox and click Next. + +On the "Target Android Devices" screen leave everything at the defaults +and click Next. + +On the "Add an Activity to Mobile" screen pick "Empty Activity". + +On the "Configure Activity" screen leave the defaults and click Next. + +On the "Customize C++ Support" screen leave everything at defaults +and click Finish. + +You should be able to click the green arrow at the top and run your +application. If not make sure to fix any problems in your Android +Studio setup - usually it will prompt you to download any missing +components like the NDK or (the special Android) CMake. After that you +should be able to run your new Android app, either in an emulator or on +a real device. + +The program we now have already shows how to mix native code and Java +code, it just does not use Allegro yet. + +Find MainActivity.java and adapt it to look like this (do not +modify your package line at the top though): + +import org.liballeg.android.AllegroActivity; +public class MainActivity extends AllegroActivity { + static { + System.loadLibrary("allegro"); + System.loadLibrary("allegro_primitives"); + System.loadLibrary("allegro_image"); + System.loadLibrary("allegro_font"); + System.loadLibrary("allegro_ttf"); + System.loadLibrary("allegro_audio"); + System.loadLibrary("allegro_acodec"); + System.loadLibrary("allegro_color"); + } + public MainActivity() { + super("libnative-lib.so"); + } +} + +If you used the monolith library, you only need a single +System.loadLibrary for that. + +The "import org.liballeg.android.AllegroActivity" line will be red. +Let's fix that. Find the allegro-release.aar from build/lib, where +build is the build folder you used when building Allegro. Open your +Project-level build.gradle and make your "allprojects" section look +like this: + +allprojects { + repositories { + google() + jcenter() + flatDir { dirs 'libs' } + } +} + +Then copy allegro-release.aar into the app/libs folder of your Android +Studio project. For example I did the following: + +cp ~/allegro-build/lib/allegro-release.aar ~/AndroidStudioProjects/MyApplication/app/libs/ + +Now open your app-level build.gradle and add this line inside of the +dependencies section: + +implementation "org.liballeg.android:allegro-release:1.0@aar" + +On older versions of Android studio use this instead: + +compile "org.liballeg.android:allegro-release:1.0@aar" + +Next hit the "Sync Now" link that should have appeared at the top of +Android Studio. If you look back at MainActivity.java, nothing should +be red any longer. + +Now run your app again. + +It will open but crash right away. That is because we are still using +the sample C++ code. Let's instead use some Allegro code. Find the +native-lib.cpp and replace its code with this: + +#include <allegro5/allegro5.h> + + int main(int argc, char **argv) { + al_init(); + auto display = al_create_display(0, 0); + auto queue = al_create_event_queue(); + auto timer = al_create_timer(1 / 60.0); + auto redraw = true; + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + while (true) { + if (redraw) { + al_clear_to_color(al_map_rgb_f(1, al_get_time() - (int)(al_get_time()), 0)); + al_flip_display(); + redraw = false; + } + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_TIMER) { + redraw = true; + } + } + return 0; + } + +The #include <allegro5/allegro5.h> will be red. Oh no. Again, let's fix +it. Find CMakeLists.txt under External Build Files and add a line like +this: + +include_directories(${ANDROID_NDK_TOOLCHAIN_ROOT}/user/{ARCH}/include) + +Where ${ANDROID_NDK_TOOLCHAIN_ROOT}/user/{ARCH} should be the path where +the Allegro headers were installed during Allegro's "make install", for +example: + +include_directories($HOME/android-toolchain-arm/user/arm/include) + +Then add a line like this: + +target_link_libraries(native-lib ${ANDROID_NDK_TOOLCHAIN_ROOT}/user/{ARCH}/lib/liballegro.so) + +For example: + +target_link_libraries(native-lib $HOME/android-toolchain-arm/user/arm/lib/liballegro.so) + +Finally, create these folders in your project: + +app/src/main/jniLibs/armeabi-v7a +app/src/main/jniLibs/arm64-v8a +app/src/main/jniLibs/x86 +app/src/main/jniLibs/x86_64 +app/src/main/jniLibs/mips +app/src/main/jniLibs/mips64 + +And copy the .so files in the corresponding folder for its architecture. + +You may have to use "Build->Refresh Linked C++ Projects" for Android +Studio to pick up the CMakeLists.txt changes. + +Run the app again. If it worked, congratulations! You just ran your +first Allegro program on Android! + +(The sample code will just flash your screen yellow and red with no way to quit, so you will have to force quit it.) diff --git a/allegro/README_cmake.txt b/allegro/README_cmake.txt new file mode 100644 index 00000000..bafd54cd --- /dev/null +++ b/allegro/README_cmake.txt @@ -0,0 +1,37 @@ +CMake options +------------- + +Our build system supports many options. Here are some of them: + +The option `CMAKE_BUILD_TYPE` selects release, debug or profiling +configurations. Valid values are: Release, Debug, RelWithDebInfo, MinSizeRel, +Profile. + +The option `SHARED` controls whether libraries are built as shared libraries +or static libraries. Shared libraries are built by default. + +*Note:* For MinGW with gcc < 4, you cannot build a static library because +TLS (thread local storage, using __thread) support was not introduced +until version 4. + +There are many options named WANT_*. Unselecting these will prevent the +associated addon or feature from being built. + +HTML and man page documentation will be built by default, but Info and PDF +(through pdfLaTeX) can also be selected from the CMake options. + + + +deps subdirectory +----------------- + +As a convenience, you may create a subdirectory called "deps" in the main +Allegro directory, or in the build directory. Inside you can place header and +library files for dependencies that Allegro will search for. Allegro will +search in these locations: + + deps/include + deps/lib + deps/<anything>/include + deps/<anything>/lib + diff --git a/allegro/README_iphone.txt b/allegro/README_iphone.txt new file mode 100644 index 00000000..10c032d1 --- /dev/null +++ b/allegro/README_iphone.txt @@ -0,0 +1,76 @@ +iPhone +====== + +Can use either OpenGL ES 1 or 2 for graphics, by default OpenGL ES 1 is +used. + +The accelerometer axes are reported as joystick axes. + +Dependencies +------------ + +The download section on liballeg.org has some pre-compiled iPhone +versions of Freetype (.ttf support), Tremor (.ogg support) and +Physfs (.zip) support. + +Make a directory in the root allegro5 directory called deps. Off of that +make an include directory and put your headers there. The structure should +look like: + +allegro5 + deps + include + allegro5 + <copy this from misc/Allegro 5 iOS> + freetype2 + <ft2build.h etc here> + physfs.h + +Building using CMake +-------------------- + +To build for the iOS simulator, run these commands from the build directory: + + cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-iphone.cmake -G Xcode \ + -DIOS_PLATFORM="iphonesimulator" .. + xcodebuild + +This will generate the static libraries inside the lib/RelWithDebInfo directory +by default. Note that cmake will occasionally pick up the OSX dependencies, +rather than the iPhone dependencies. If that happens, you may want to disable +the system you don't want via cmake (e.g. -DWANT_PHYSFS=no). + +You can also open the XCode project (named ALLEGRO.xcodeproj) and run the +examples. + +To build for the iOS device, the procedure is similar. It is easiest to disable +the building of demos, examples and tests as those currently require manual +modification of the generated XCode project (to enable code signing). + + cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-iphone.cmake -G Xcode \ + -DIOS_PLATFORM="iphoneos" -DWANT_EXAMPLES=off -DWANT_DEMO=off -DWANT_TESTS=off .. + xcodebuild + +This should generate some ARM libraries in the same location. You might need to +manually modify the generated XCode project to enable more architectures. + +Building using a pre-built XCode project +---------------------------------------- + +If the above doesn't work for you, you can try the pre-built XCode project. + +Use the Xcode project in misc/Allegro 5 iOS. By default it will build for the +simulator. You will have to change the target to build for an iOS device. The +project builds armv7/armv7s/arm64 fat binaries. The project is compiled into +a single static library (monolith). + +You can find the resulting library in ~/Library/Developer/Xcode/DerivedData. + +The Xcode project currently does not build the audio, acodec or video +addons. To build them, add the source files, add addons/audio etc to +your header search path and put the dependency includes in +deps/include. + +To install you'll have to copy the library (in DerivedData/*) and the headers +manually. The headers you need are the ones you copied to deps, plus the +ones in allegro5/include plus <addon>/allegro5 for each of the addons. diff --git a/allegro/README_macosx.txt b/allegro/README_macosx.txt new file mode 100644 index 00000000..7611fca6 --- /dev/null +++ b/allegro/README_macosx.txt @@ -0,0 +1,57 @@ +Mac OS X-specific notes +======================= + +Building Allegro on Mac OS X is the same as on other Unix-like operating systems. +See README_make.txt. + +Building with Xcode +------------------- + +You may also use Xcode to build Allegro. This works similar to the instructions +in README_make.txt, except add the parameter -GXcode when invoking cmake. + +Instead of creating a makefile this will create an Xcode project which you can +double click and open in Xcode and then hit the arrow button to compile. + +Using the Clang compiler (OS X 10.6+) +------------------------------------- + +It is possible to build Allegro using the Clang compiler that ships with OS +X 10.6 (Snow Leopard). Clang is installed in /Developer/usr/bin. +To use it, you have to tell Cmake to use Clang instead of gcc. From the +terminal, this is most easily accomplished by the commands + + export PATH=/Developer/usr/bin:$PATH + export CC=clang + +before you run Cmake. If you use the graphical version of Cmake, you will +be given the option of selecting the C compiler to use. Simply select +/Developer/usr/bin/clang. +The installation otherwise continues as usual. + +Retina display support (OS X 10.7+) +----------------------------------- + +Allegro has an option to support high DPI displays by treating them as a regular +high-resolution display. To do so, use XCode to set the NSHighResolutionCapable +property in the Info.plist of your bundled app to YES. Alternatively, add these +two lines to the Info.plist using a text editor: + + <key>NSHighResolutionCapable</key> + <true/> + +If you are making an unbundled app this feature appears to be enabled by +default, but it is not recommended to rely on this working: make a bundled +app for the most predictable performance. + +When changing the display DPI or moving the window between two displays with +different DPIs, Allegro displays behave in the following way: + +- If the ALLEGRO_DISPLAY was created with the ALLEGRO_RESIZABLE flag it will + send an ALLEGRO_DISPLAY_RESIZE event. This will have the effect of your app's + window remaining visually the same, while the display size in pixels will + increase or decrease. This is the recommended situation. + +- If the ALLEGRO_DISPLAY was not created with the ALLEGRO_RESIZABLE flag, then + the display size in pixels will remain the same, but the app's window will + appear to grow or shrink. diff --git a/allegro/README_make.txt b/allegro/README_make.txt new file mode 100644 index 00000000..cce21443 --- /dev/null +++ b/allegro/README_make.txt @@ -0,0 +1,57 @@ +Building Allegro with make +========================== + +This document discusses building Allegro using CMake and GNU make from a +terminal window. This document applies to Unix-like operating systems such as +Linux, and also Mac OS X and MinGW. + +1. Unpack Allegro. + +2. Create a build directory under the Allegro directory and go there. + + cd /path/to/allegro + mkdir build + cd build + +3. Run `cmake` with whatever options you want. See README_cmake.txt +for details about options you can set. + + cmake .. + +Here ".." is the path to the Allegro directory. + +Alternatively, you can use `ccmake` (Unix) or `cmake-gui` (Windows) to bring up +an interactive option selector. e.g. `ccmake ..` or `cmake-gui ..`. + +You may need to tell CMake which "generator" to use; cmake -h will tell you +which generators are available. We recommend using the Makefile generator +(default everywhere except Windows). On MinGW you will have a choice between +"MinGW Makefiles" or "MSYS Makefiles". If `sh.exe` is on your PATH then you +must use "MSYS Makefiles", otherwise use "MinGW Makefiles". + +More examples: + + cmake .. -G "MinGW Makefiles" + + cmake .. -G "MSYS Makefiles" + +4. Now, if that step was successful you can run `make` to build Allegro. +On MinGW your make might actually be called `mingw32-make`. + + make + +Since multicore processors are common now, you might wish to speed that up by +passing a "-j<n>" option, where <n> is the number of parallel jobs to spawn. + + +5. You may optionally install Allegro into your system path with the install +target. + + make install + +MinGW users might need to set the MINGDIR environment variable first. + +The DESTDIR variable is supported for staged installs. + + make install DESTDIR=/tmp/allegro-package + diff --git a/allegro/README_msvc.txt b/allegro/README_msvc.txt new file mode 100644 index 00000000..1b654c48 --- /dev/null +++ b/allegro/README_msvc.txt @@ -0,0 +1,91 @@ +Building Allegro with MSVC +========================== + +There are a lot of variations to the build process, but we will just stick with +one to keep things simple. If you know what you are doing, you can do +something else. + +1. Unpack Allegro into a directory *without spaces or other "weird" characters +in the path*. This is a known problem. + +2. Create a build directory under the Allegro directory. Optionally, create a +deps directory and place the headers and libraries of third party dependencies +in there. See README_cmake.txt about this. + +3. Start the Microsoft Visual Studio IDE, then bring up a command prompt by +clicking "Tools > Visual Studio 20xx Command Prompt". + +4. Make sure cmake is in your PATH. Typing "cmake" should display the help +message. If it doesn't, you can set the PATH manually by typing +"SET PATH=C:\cmake\bin\;%PATH%" or similar. +Make sure the MSVC compiler cl.exe and lib.exe also run correctly. + +5. Go to the Allegro build directory: + + cd \allegro\Build + +6. Run CMake to configure everything. We will use the CMake GUI. + + cmake-gui .. + +7. Press "Configure". Watch for messages about missing headers and libraries. +If anything is missing, you can give CMake a helping hand by setting +_INCLUDE_DIR and _LIBRARY options manually, e.g. if ZLIB is not found you +would set ZLIB_INCLUDE_DIR and ZLIB_LIBRARY. +You may have to switch to "Advanced View" in order to see the variables. +Once done, press "Configure" again. + +8. Press "Generate". CMake will now generate a project solution. + +*Note:* +As of the time this is written, CMake has a bug that causes the DLLs in +MSVC 10 to be named incorrectly. To work around this, generate MSVC 9 projects +instead. You may need to uncomment the line "#define ALLEGRO_HAVE_STDINT_H" +in alplatf.h. Alternatively, use nmake instead of project files. + +9. Open up the project solution with the MSVC IDE and start building. + + + +Running the examples +==================== + +If you build Allegro as a shared library (the default), the example programs +will probably not run as-is, because they cannot find the Allegro DLLs. +You may: + +- manually copy the Allegro DLLs into the Build/examples directory where they + will be found when the example is run; or + +- build the INSTALL project, which copies the library files into the MSVC + search path (%VCINSTALLDIR%\bin). You may not want to make a mess in there. + +- The most drastic solution is to copy them into your C:\WINDOWS\SYSTEM32 + directory, but most people prefer not to make a mess in that directory. + +By default, Allegro will load FLAC and Ogg Vorbis DLLs at runtime. If it +cannot find them, FLAC and Vorbis file format support will be disabled. +Again, the solution is to copy those DLLs where they can be found. + + + +Hints on setting up Visual C++ 2005 Express Edition +=================================================== + +After installing Visual C++, you need to install the Platform SDK (or Windows +SDK), otherwise CMake will fail at a linking step. You can do a web install to +avoid downloading a massive file. For me, installation seemed to take an +inordinately long (half an hour or more), but eventually it completed. +Don't be too quick to hit Cancel. + +You also need to install the DirectX SDK. This is a big download, which I +don't know how to avoid. + +Next, you'll need to tell VC++ about the Platform SDK. Start the IDE. Under +"Tools > Options > Projects and Solutions > VC++ Directories", add the Platform +SDK executable (bin), include and lib directories to the respective lists. +The DirectX SDK seems to add itself when it's installed. + +For debugging, use the DirectX control panel applet to switch to the debugging +runtime. It's really useful. + diff --git a/allegro/README_packaging.txt b/allegro/README_packaging.txt new file mode 100644 index 00000000..9aece72a --- /dev/null +++ b/allegro/README_packaging.txt @@ -0,0 +1,8 @@ +Note to packagers (e.g. for Linux distributions) +------------------------------------------------ + +Allegro 5.x is *not* source compatible with Allegro 4.2.x or 4.4.x. +When packaging Allegro 5, please make it possible for users to install +Allegro 4.x and 5.x simultaneously. For example, if you already have +an 'allegro' package, then you might name the new package 'allegro5'. + diff --git a/allegro/README_pkgconfig.txt b/allegro/README_pkgconfig.txt new file mode 100644 index 00000000..e6146730 --- /dev/null +++ b/allegro/README_pkgconfig.txt @@ -0,0 +1,61 @@ +Using pkg-config with Allegro +============================= + +On Unix-like operating systems, we use the pkg-config tool to simplify the +process of linking with Allegro. + +To print the list of Allegro libraries installed, you can run: + + pkg-config --list-all | grep allegro + +You may need to set the PKG_CONFIG_PATH environment variable appropriately if +/usr/local/lib/pkgconfig is not hardcoded for your version of pkg-config or +if you installed to a non-standard location. For example: + + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig + +To print the command line options required to link with the core Allegro +library and the image addon, you would run: + + pkg-config --libs allegro-5 allegro_image-5 + +which outputs something like: + + -L/usr/lib -lallegro_image -lallegro + +If you use static libraries, you need to add the --static option: + + pkg-config --libs --static allegro-static-5 allegro_image-static-5 + +which will include additional libraries needed for static linking. + +This can be combined with shell command substitution: + + gcc mygame.c -o mygame $(pkg-config --libs allegro-5 allegro_image-5) + +If Allegro is installed to a non-standard location, the compiler will need +command line options to find the header files. The pkg-config `--cflags` +option provides that information. You can combine it with `--libs` as well: + + pkg-config --cflags --libs allegro-5 allegro_image-5 + +Most build systems will allow you to call pkg-config in a similar way to the +shell. For example, a very basic Makefile might look like this: + + ALLEGRO_LIBRARIES := allegro-5 allegro_image-5 + ALLEGRO_FLAGS := $(shell pkg-config --cflags --libs $(ALLEGRO_LIBRARIES)) + + mygame: mygame.c + $(CC) -o $@ $^ $(ALLEGRO_FLAGS) + + +Historical note +--------------- + +Prior to Allegro 5.0.9 the .pc files were named allegro-5.0.pc and so on. +To ease transitioning to future versions of Allegro the minor version +number was dropped, leaving allegro-5.pc and so on. The old names are +deprecated but will remain available in 5.0.x releases. +Configuration scripts should look for Allegro using the new pkg-config +names first, then the old names, for greater compatibility. + diff --git a/allegro/README_raspberrypi.txt b/allegro/README_raspberrypi.txt new file mode 100644 index 00000000..d8047a7e --- /dev/null +++ b/allegro/README_raspberrypi.txt @@ -0,0 +1,36 @@ +Building +-------- + +mkdir build +cd build +cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-raspberrypi.cmake +make + +Virtual machine +--------------- + +Building with a cross compiler is not yet documented. Building directly +on a Raspberry Pi or in a Raspberry Pi VM is very similar to building on +"regular" Linux. apt-get install the -dev packages you need, run cmake and +make sure everything you need is found. + +For example, you can use an image from: + + http://www.raspberrypi.org/downloads + +and a kernel: + + http://xecdesign.com/downloads/linux-qemu/kernel-qemu + +With a qemu command line like: + + qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb \ + -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" \ + -hda 2012-12-16-wheezy-raspbian.img \ + -redir tcp:2222::22 -net nic -net user + +You can ssh into the VM with: + + ssh -p 2222 pi@127.0.0.1 + +Within the guest you can access the host at 10.0.2.2. diff --git a/allegro/README_releasing.txt b/allegro/README_releasing.txt new file mode 100644 index 00000000..944719d1 --- /dev/null +++ b/allegro/README_releasing.txt @@ -0,0 +1,65 @@ +How to Make a Release +--------------------- + +This guide explains how to make an Allegro release. This all assumes that we're +on Linux. + +1. Starting with the master branch, pick a commit which you want to be the base of + the release branch. Typically this will be HEAD, but if there are some + unbaked commits there, you may want to use an earlier commit. Call this + branch with the new release name (e.g. 5.2.2 in this case): + + git branch 5.2.2 master + + From now on, aside from changing the version numbers, all commits on this + release branch should be cherry-picked from the master branch. For all + cherry-picks, prefer using the -x switch, like so: + + git cherry-pick -x badf00d + +2. On the master branch, bump the version to the next release and update the + dates. This is done in `include/allegro5/base.h`. Also, change + ALLEGRO_VERSION in `CMakeLists.txt`. Commit this change. + +3. Write a changelog file. This is located in docs/src/changes-5.2.txt. + + Typically you will want to look through the commits made since the last + release, e.g. using `git log <last_release>..<this_release>` (e.g. `git log + 5.2.1..5.2.2`). Follow the format of the previous changelogs. It's up to + you how to determine who are the 'main developers'. For the 5.1.9+ release, + I've abitrarily determined it to be developers who've committed 95% of the + lines of code (this isn't very important). You probably will want to have + other developers check it over in case something is wrong/missing. Commit + this change. + +4. We are now done with the master branch. You can push these changes to + github. Check out the release branch now. + +5. Cherry-pick the commit with the changelog onto this branch. + +6. Bump the version from "GIT" to "WIP" if it's unstable, or remove "GIT" if + it's stable, while preserving the major, minor and patch numbers, but + increasing the release number by 1. Also, update the dates at this time. + This is all done in `include/allegro5/base.h`. Commit this change. + +7. Tag the previous commit with the same version number and the release number + (e.g. "5.2.2.0" if you're releasing 5.2.2. An example command would be: + + git tag -a -m "Tag 5.2.2.0 (WIP)" 5.2.2.0 + +8. Create the source archives by running `misc/create_release_archives.sh` and + passing in the release version. This will create 3 source archives (.tar.gz, + .7z and .zip) in the current directory. And example invocation would be: + + ./misc/create_release_archives.sh 5.2.2.0 + +9. Upload the source archives to github. Go to the releases tab, and make a + new release with the tag you just created. + +10. Build the docs, including the pdf. Add these to the website via the + liballeg.github.io repository. + +11. Make an announcement on the website. This involves making a news item, + changing the download area and copy-pasting the change list. + +12. Make an announcement on allegro.cc. You're done! diff --git a/allegro/README_sdl.txt b/allegro/README_sdl.txt new file mode 100644 index 00000000..2cd2beb3 --- /dev/null +++ b/allegro/README_sdl.txt @@ -0,0 +1,122 @@ +SDL +=== + +This is an experimental port which uses SDL2 to create the Allegro +window and OpenGL context. + + +Dependencies +------------ + +SDL2 is required. + + +Building +-------- + +Pass -D ALLEGRO_SDL=on to cmake to enable building for SDL2. + + +Limitations +----------- + +SDL2 requires calling SDL_PumpEvents() from the main thread regularly to +generate events. Currently Allegro5 makes those calls from the timer +subsystem - so as long as you have any timers running things will work +fine. If your Allegro 5 program uses no timers it may get stuck because +no SDL2 events can be received. + + +Emscripten +---------- + +One reason the SDL2 port is useful is that it allows running Allegro on +platforms not supported directly by Allegro, such as Emscripten. This is +even more experimental but here are some example steps that will compile +most of the examples for running in a web browser: + +1. Make sure to set up the emscripten environment by running the + +emsdk_env.sh + +or equivalent as provided by emscripten. + +2. Create a build folder. + +mkdir build_emscripten +cd build_emscripten + +3. The "--preload-file data" option below includes a folder named "data" +with each binary, so we make sure each example and demo has such a +folder: + +mkdir -p demos/speed/data +demos/speed/data/nothing.txt + +4. Configure CMake, using emcmake. + +USE_FLAGS=( + -s USE_FREETYPE=1 + -s USE_VORBIS=1 + -s USE_OGG=1 + -s USE_LIBJPEG=1 + -s USE_SDL=2 + -s USE_LIBPNG=1 + -s FULL_ES2=1 + -s ASYNCIFY + -s TOTAL_MEMORY=2147418112 + -O3 + ) + +emcmake cmake {path-to-allegro-source-folder} + -D CMAKE_BUILD_TYPE=Release + -D ALLEGRO_SDL=ON + -D SHARED=OFF + -D WANT_MONOLITH=ON + -D WANT_ALLOW_SSE=OFF + -D WANT_DOCS=OFF + -D WANT_TESTS=OFF + -D WANT_OPENAL=OFF + -D ALLEGRO_WAIT_EVENT_SLEEP=ON + # not sure why these are not found automatically with emcmake, so + # we use a hack - we manually specify the cache path, so cmake + # will fail on first run in the compile test but populate the cache + # (from the -s options) and on second run it all works + -D SDL2_INCLUDE_DIR=$EM_CACHE/sysroot/include + -D PNG_PNG_INCLUDE_DIR=$EM_CACHE/sysroot/include + -D PNG_LIBRARY=$EM_CACHE/sysroot/lib/wasm32-emscripten/libpng.a + -D JPEG_INCLUDE_DIR=$EM_CACHE/sysroot/include + -D JPEG_LIBRARY=$EM_CACHE/sysroot/lib/wasm32-emscripten/libjpeg.a + -D FREETYPE_INCLUDE_DIRS=$EM_CACHE/sysroot/include + -D FREETYPE_LIBRARY=$EM_CACHE/sysroot/lib/wasm32-emscripten/libfreetype.a + -D VORBIS_INCLUDE_DIR=$EM_CACHE/sysroot/include/vorbis + -D VORBIS_LIBRARY=$EM_CACHE/sysroot/lib/wasm32-emscripten/libvorbis.a + -D VORBISFILE_LIBRARY=$EM_CACHE/sysroot/lib/wasm32-emscripten/libvorbis.a + -D OGG_INCLUDE_DIR=$EM_CACHE/sysroot/include + -D OGG_LIBRARY=$EM_CACHE/sysroot/lib/wasm32-emscripten/libogg.a + -D CMAKE_C_FLAGS="${USE_FLAGS}" + -D CMAKE_CXX_FLAGS="${USE_FLAGS}" + -D CMAKE_EXE_LINKER_FLAGS="${USE_FLAGS} --preload-file data" + -D CMAKE_EXECUTABLE_SUFFIX_CXX=".html" + +Emscripten will take care of downloading the dependencies mentioned above via +its ports system. + +To compile your own game adjust as necessary. You can use the +lib/liballegro_monolith-static.a library. + +5. Compile the library and examples. + +make + +Since that can take awhile (a lot slower than regular compilation speed), you +may want to compile individual examples, e.g. + +make ex_draw_bitmap + +6. To run the examples, navigate to the examples folder. At this point it is +easiest to start a local webserver, and then navigate to the examples using a +web browser. E.g. you could use the Python's web server module which prints out +a URL you can open: + +python3 -m http.server diff --git a/allegro/README_windows.txt b/allegro/README_windows.txt new file mode 100644 index 00000000..1e36c2a6 --- /dev/null +++ b/allegro/README_windows.txt @@ -0,0 +1,35 @@ +Windows-specific notes +====================== + +DPI Awareness +------------- + +By default, apps created with Allegro are marked as DPI aware, and are not +scaled by the OS. This is mostly transparent on your end, the only complication +comes when the DPI changes on the fly (e.g. your app's window gets moved +between displays with different DPIs): + +- If the ALLEGRO_DISPLAY was created with the ALLEGRO_RESIZABLE flag it will + send an ALLEGRO_DISPLAY_RESIZE event. This will have the effect of your app's + window remaining visually the same, while the display size in pixels will + increase or decrease. This is the recommended situation. + +- If the ALLEGRO_DISPLAY was not created with the ALLEGRO_RESIZABLE flag, then + the display size in pixels will remain the same, but the app's window will + appear to grow or shrink. + +If you for some reason want to opt out of DPI-awareness, utilize the +application manifests to specify that your app is not DPI-aware. + +Runtime DLL Loading +------------------- + +For some of its features, Allegro will look for certain DLLs on the +system it runs on, but will not explicitly depend them at build time. +These are as follows: + +- msftedit.dll or riched20.dll or riched32.dll - For the native dialog addon. + +- d3dx9_${version}.dll - Shader support for the Direct3D backend. + +- xinput1_${version}.dll - XInput-based joysticks. diff --git a/allegro/SECURITY.md b/allegro/SECURITY.md new file mode 100644 index 00000000..f6fdd6f9 --- /dev/null +++ b/allegro/SECURITY.md @@ -0,0 +1,22 @@ +# Security Policy + +## Report a security issue + +The Allegro project team welcomes security reports and is committed to +providing prompt attention to security issues. Security issues should be +reported privately by sending an email to +<allegro-security@lists.liballeg.org>. + +## Version support + +| Version | Supported | +| ------- | ------------------ | +| >= 5.2.x| Yes | +| < 5.2 | No | + +## Security advisories + +Remediation of security vulnerabilities is prioritized by the project team +based on the overall impact. The project team is committed to transparency in +the disclosure process. The Allegro team announces security issues Allegro +Release notes, as well as the Allegro website on a best-effort basis. diff --git a/allegro/addons/CMakeLists.txt b/allegro/addons/CMakeLists.txt new file mode 100644 index 00000000..3e71563e --- /dev/null +++ b/allegro/addons/CMakeLists.txt @@ -0,0 +1,241 @@ +# FOO_LINK_WITH and SUPPORT_FOO need to be propagated up to the parent scope so +# examples know if they can use the FOO addon, and what to link against. +# FOO_LINK_WITH should be the name of a single target. The target should +# automatically pull in dependencies so they don't need to be listed. + +include(FindPackageHandleStandardArgs) + +set(ADDON_PKG_CONFIG_FILES) + +if(WANT_PRIMITIVES) + add_subdirectory(primitives) + set(SUPPORT_PRIMITIVES 1) + set(SUPPORT_PRIMITIVES 1 PARENT_SCOPE) + set(PRIMITIVES_LINK_WITH ${PRIMITIVES_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_primitives) +endif(WANT_PRIMITIVES) + +if(WANT_IMAGE) + add_subdirectory(image) + set(SUPPORT_IMAGE 1) + set(SUPPORT_IMAGE 1 PARENT_SCOPE) + set(IMAGE_LINK_WITH ${IMAGE_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_image) +endif(WANT_IMAGE) + +if(WANT_FONT AND SUPPORT_IMAGE) + add_subdirectory(font) + set(SUPPORT_FONT 1) + set(SUPPORT_FONT 1 PARENT_SCOPE) + set(FONT_LINK_WITH ${FONT_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_font) +endif(WANT_FONT AND SUPPORT_IMAGE) + +if(WANT_AUDIO) + add_subdirectory(audio) + if(SUPPORT_AUDIO) + set(SUPPORT_AUDIO 1 PARENT_SCOPE) + set(AUDIO_LINK_WITH ${AUDIO_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_audio) + endif(SUPPORT_AUDIO) +endif(WANT_AUDIO) + +if(SUPPORT_AUDIO) + add_subdirectory(acodec) + if(SUPPORT_ACODEC) + set(SUPPORT_ACODEC 1 PARENT_SCOPE) + set(ACODEC_LINK_WITH ${ACODEC_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_acodec) + endif(SUPPORT_ACODEC) +endif(SUPPORT_AUDIO) + +if(SUPPORT_FONT AND WANT_TTF) + find_package(Freetype) + + option(FREETYPE_ZLIB "Enable if FreeType static library needs zlib linked in." off) + option(FREETYPE_BZIP2 "Enable if FreeType static library needs bzip2 linked in." off) + option(FREETYPE_PNG "Enable if FreeType static library needs png linked in." off) + option(FREETYPE_HARFBUZZ "Enable if FreeType static library needs harfbuzz linked in." off) + + if(FREETYPE_FOUND) + set(FREETYPE_TEST_SOURCE " + #include <ft2build.h> + #include FT_FREETYPE_H + int main(void) { + FT_Library ft; + FT_Open_Args args; + FT_Face face; + FT_Int32 ft_load_flags; + FT_Error e; + int ft_index; + FT_Init_FreeType(&ft); + FT_Open_Face(ft, &args, 0, &face); + return FT_Load_Glyph(face, ft_index, ft_load_flags); + }") + + set(TTF_INCLUDE_DIRECTORIES ${FREETYPE_INCLUDE_DIRS}) + + set(CMAKE_REQUIRED_LIBRARIES ${FREETYPE_LIBRARIES}) + set(CMAKE_REQUIRED_INCLUDES ${FREETYPE_INCLUDE_DIRS}) + run_c_compile_test("${FREETYPE_TEST_SOURCE}" TTF_COMPILES) + if(TTF_COMPILES) + set(TTF_LIBRARIES ${FREETYPE_LIBRARIES}) + else() + if(FREETYPE_ZLIB) + find_package(ZLIB) + endif() + + if(FREETYPE_BZIP2) + find_package(BZip2) + endif() + + if(FREETYPE_PNG) + find_package(PNG) + endif() + + if (FREETYPE_HARFBUZZ) + find_package(HarfBuzz) + endif() + + # Try compiling with the extra dependencies. + set(FREETYPE_STATIC_LIBRARIES ${FREETYPE_LIBRARIES}) + if(FREETYPE_ZLIB AND ZLIB_FOUND) + list(APPEND FREETYPE_STATIC_LIBRARIES "${ZLIB_LIBRARIES}") + endif() + + if(FREETYPE_BZIP2 AND BZIP2_FOUND) + list(APPEND FREETYPE_STATIC_LIBRARIES "${BZIP2_LIBRARIES}") + endif() + + if(FREETYPE_PNG AND PNG_FOUND) + list(APPEND FREETYPE_STATIC_LIBRARIES "${PNG_LIBRARIES}") + endif() + + if (FREETYPE_HARFBUZZ AND HARFBUZZ_FOUND) + # there's a circular dependency between Harfbuzz and Freetype, so one of them has to be + # repeated to ensure proper static linking order + list(APPEND FREETYPE_STATIC_LIBRARIES "${HARFBUZZ_LIBRARIES}" "${FREETYPE_LIBRARIES}") + endif() + + set(CMAKE_REQUIRED_LIBRARIES ${FREETYPE_STATIC_LIBRARIES}) + set(CMAKE_REQUIRED_INCLUDES ${FREETYPE_INCLUDE_DIRS}) + run_c_compile_test("${FREETYPE_TEST_SOURCE}" TTF_COMPILES_WITH_EXTRA_DEPS) + if(TTF_COMPILES_WITH_EXTRA_DEPS) + set(TTF_COMPILES 1) + set(TTF_LIBRARIES ${FREETYPE_STATIC_LIBRARIES}) + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + + if(TTF_COMPILES) + add_subdirectory(ttf) + set(SUPPORT_TTF 1 PARENT_SCOPE) + set(TTF_LINK_WITH ${TTF_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_ttf) + else() + message(WARNING "FreeType doesn't compile. Disabling support.") + endif() + else(FREETYPE_FOUND) + message("WARNING: FreeType not found, disabling support.") + endif(FREETYPE_FOUND) +endif(SUPPORT_FONT AND WANT_TTF) + +if(WANT_COLOR) + add_subdirectory(color) + set(SUPPORT_COLOR 1 PARENT_SCOPE) + set(COLOR_LINK_WITH ${COLOR_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_color) +endif(WANT_COLOR) + +if(WANT_MEMFILE) + add_subdirectory(memfile) + set(SUPPORT_MEMFILE 1 PARENT_SCOPE) + set(MEMFILE_LINK_WITH ${MEMFILE_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_memfile) +endif(WANT_MEMFILE) + +if(WANT_PHYSFS) + find_package(PhysFS) + # FindPhysFS.cmake in cmake-2.6.2 doesn't call this but it should. + find_package_handle_standard_args(PHYSFS DEFAULT_MSG + PHYSFS_LIBRARY PHYSFS_INCLUDE_DIR) + mark_as_advanced(PHYSFS_INCLUDE_DIR) + mark_as_advanced(PHYSFS_LIBRARY) + + find_package(ZLIB) + + # Does this copy of PhysicsFS require zlib to be linked separately? + # FindPhysFS should really figure this out for us, but it doesn't. + if(PHYSFS_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${PHYSFS_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${PHYSFS_LIBRARY}) + run_c_compile_test(" + #include <physfs.h> + + int main(int argc, char **argv) + { + (void)argc; + PHYSFS_init(argv[0]); + PHYSFS_deinit(); + return 0; + }" + PHYSFS_IMPLICIT_ZLIB) + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + + if(PHYSFS_IMPLICIT_ZLIB) + set(PHYSFS_LIBRARIES ${PHYSFS_LIBRARY}) + set(SUPPORT_PHYSFS 1) + elseif(ZLIB_FOUND) + set(PHYSFS_LIBRARIES ${PHYSFS_LIBRARY} ${ZLIB_LIBRARY}) + set(SUPPORT_PHYSFS 1) + else() + message("WARNING: PhysicsFS needs zlib, zlib not found, disabling PhysFS support.") + endif() + endif(PHYSFS_FOUND) + + if(SUPPORT_PHYSFS) + add_subdirectory(physfs) + set(SUPPORT_PHYSFS 1 PARENT_SCOPE) + set(PHYSFS_LINK_WITH ${PHYSFS_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_physfs) + endif(SUPPORT_PHYSFS) +endif(WANT_PHYSFS) + +if(WANT_NATIVE_DIALOG) + add_subdirectory(native_dialog) + if(SUPPORT_NATIVE_DIALOG) + set(SUPPORT_NATIVE_DIALOG 1 PARENT_SCOPE) + set(NATIVE_DIALOG_LINK_WITH ${NATIVE_DIALOG_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_dialog) + endif() +endif(WANT_NATIVE_DIALOG) + +if(WANT_VIDEO) + add_subdirectory(video) + if(SUPPORT_VIDEO) + set(SUPPORT_VIDEO 1 PARENT_SCOPE) + set(VIDEO_LINK_WITH ${VIDEO_LINK_WITH} PARENT_SCOPE) + list(APPEND ADDON_PKG_CONFIG_FILES allegro_video) + endif(SUPPORT_VIDEO) +endif(WANT_VIDEO) + +add_subdirectory(main) +# SUPPORT_MAIN and MAIN_LINK_WITH are spelt as such in this scope, +# but are prefixed with ALLEGRO in the parent scope. +set(SUPPORT_ALLEGRO_MAIN ${SUPPORT_MAIN} PARENT_SCOPE) +set(ALLEGRO_MAIN_LINK_WITH ${MAIN_LINK_WITH} PARENT_SCOPE) +list(APPEND ADDON_PKG_CONFIG_FILES allegro_main) + +set(MONOLITH_SOURCES ${MONOLITH_SOURCES} PARENT_SCOPE) +set(MONOLITH_INCLUDE_DIRECTORIES ${MONOLITH_INCLUDE_DIRECTORIES} PARENT_SCOPE) +set(MONOLITH_LINK_DIRECTORIES ${MONOLITH_LINK_DIRECTORIES} PARENT_SCOPE) +set(MONOLITH_LIBRARIES ${MONOLITH_LIBRARIES} PARENT_SCOPE) +set(MONOLITH_HEADERS ${MONOLITH_HEADERS} PARENT_SCOPE) +set(MONOLITH_DEFINES ${MONOLITH_DEFINES} PARENT_SCOPE) + +set(ADDON_PKG_CONFIG_FILES ${ADDON_PKG_CONFIG_FILES} PARENT_SCOPE) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/acodec/CMakeLists.txt b/allegro/addons/acodec/CMakeLists.txt new file mode 100644 index 00000000..d8f5a821 --- /dev/null +++ b/allegro/addons/acodec/CMakeLists.txt @@ -0,0 +1,371 @@ +include_directories(../audio) + +option(WANT_FLAC "Enable FLAC support" on) +if(WIN32) + option(FLAC_STATIC "Set this if linking with a static FLAC library" off) +endif() +option(WANT_VORBIS "Enable Ogg Vorbis support using libvorbis" on) +option(WANT_TREMOR "Enable Ogg Vorbis support using Tremor" off) +option(WANT_OPUS "Enable Opus support using libopus" on) +option(WANT_MODAUDIO "Enable MOD Audio support" on) +option(WANT_ACODEC_DYNAMIC_LOAD "Enable DLL loading in acodec (Windows)" off) +option(WANT_MP3 "Enable MP3 support" on) + +#-----------------------------------------------------------------------------# + +set(ACODEC_INCLUDE_FILES + allegro5/allegro_acodec.h + ) + +set_our_header_properties(${ACODEC_INCLUDE_FILES}) + +set(ACODEC_SOURCES + acodec.c + wav.c + helper.c + voc.c # built-in enhanced port of A4 loader + ) +set(ACODEC_LIBRARIES) + +# For dynamic loading, we want to make sure that CMake has found an import +# library and not a static library. We assume that the name of the DLL to load +# is the same as the import library, bar the extension. +# +# With MSVC, static libraries and import libraries share the same extension. +# Luckily the MSVC static libraries for FLAC and Vorbis are named with a +# _static suffix. +# With MinGW, static libraries end with .a, and import libraries end with +# .dll.a so we can tell them apart. (The regex for this is a bodge.) +set(WIN32_STATIC_LIB_REGEX "_static[.]|[^l][.]a") + +function(get_dll_name implib dllname_var) + if(MINGW) + # Guess the name of dlltool from gcc. + string(REGEX REPLACE "gcc.*" dlltool DLLTOOL ${CMAKE_C_COMPILER}) + execute_process( + COMMAND ${DLLTOOL} -I ${implib} + OUTPUT_VARIABLE dllname + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + elseif(MSVC) + # Not sure this is the best way. + execute_process( + COMMAND lib /LIST ${implib} + OUTPUT_VARIABLE output + ) + if(output STREQUAL "") + message("WARNING: Failed to execute lib /list") + else() + string(REGEX MATCH "[^\n]+[.]dll" dllname "${output}") + endif() + endif() + if(NOT dllname) + # Guess from the basename. + get_filename_component(basename "${implib}" NAME_WE) + set(dllname "${basename}.dll") + endif() + message(STATUS "DLL name for ${implib}: ${dllname}") + set(${dllname_var} ${dllname} PARENT_SCOPE) +endfunction(get_dll_name) + +# +# FLAC +# + +if(WANT_FLAC) + find_package(FLAC) + if(FLAC_FOUND) + if(FLAC_LIBRARY MATCHES "${WIN32_STATIC_LIB_REGEX}") + set(FLAC_STATIC 1) + endif() + if(FLAC_STATIC) + set(FLAC__NO_DLL "-DFLAC__NO_DLL") + endif() + set(CMAKE_REQUIRED_INCLUDES ${FLAC_INCLUDE_DIR}) + if(MSVC) + set(CMAKE_REQUIRED_LIBRARIES ${FLAC_LIBRARIES}) + else() + # FLAC requires libm on Android, doesn't seem to hurt elsewhere either. + set(CMAKE_REQUIRED_LIBRARIES ${FLAC_LIBRARIES} m) + endif() + set(CMAKE_REQUIRED_DEFINITIONS ${FLAC__NO_DLL}) + run_c_compile_test(" + #include <FLAC/stream_decoder.h> + int main(void) + { + (void)FLAC__stream_decoder_new(); + return 0; + }" + FLAC_COMPILES) + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_DEFINITIONS) + if(FLAC_COMPILES) + set(SUPPORT_FLAC 1) + endif(FLAC_COMPILES) + endif(FLAC_FOUND) + if(NOT SUPPORT_FLAC) + message("WARNING: libFLAC not found or compile test failed, disabling support.") + endif(NOT SUPPORT_FLAC) +endif(WANT_FLAC) + +if(SUPPORT_FLAC) + include_directories(SYSTEM ${FLAC_INCLUDE_DIR}) + set(ALLEGRO_CFG_ACODEC_FLAC 1) + list(APPEND ACODEC_SOURCES flac.c) + + list(APPEND ACODEC_INCLUDE_DIRECTORIES ${FLAC_INCLUDE_DIR}) + + if(WIN32) + if(WANT_ACODEC_DYNAMIC_LOAD) + if(FLAC_STATIC) + message("WARNING: Dynamic loading will be disabled for FLAC as" + " static library was found: ${FLAC_LIBRARY}") + else() + get_dll_name(${FLAC_LIBRARY} ALLEGRO_CFG_ACODEC_FLAC_DLL) + endif() + endif() + endif(WIN32) + + if(NOT ALLEGRO_CFG_ACODEC_FLAC_DLL) + list(APPEND ACODEC_LIBRARIES ${FLAC_LIBRARIES}) + endif() +endif(SUPPORT_FLAC) + +# +# MOD audio +# + +if(WANT_MODAUDIO) + find_package(DUMB) + if(DUMB_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${DUMB_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${DUMB_LIBRARIES}) + run_c_compile_test(" + #define _FILE_OFFSET_BITS 64 + #include <dumb.h> + #if (DUMB_MAJOR_VERSION) == 1 + #error libdumb 1.0 not supported, get >= 2.0 or 0.9.3 + #endif + int main(void) + { + dumb_register_stdfiles(); + return 0; + }" + DUMB_COMPILES) + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + if(DUMB_COMPILES) + set(SUPPORT_MODAUDIO 1) + endif(DUMB_COMPILES) + endif(DUMB_FOUND) + if(NOT SUPPORT_MODAUDIO) + message("WARNING: libdumb >= 2.0 or <= 0.9.3 not found or compile " + "test failed, disabling support. See " + "<https://github.com/kode54/dumb> for 2.0 or " + "<http://dumb.sourceforge.net/> for 0.9.3.") + endif(NOT SUPPORT_MODAUDIO) +endif(WANT_MODAUDIO) + +if(SUPPORT_MODAUDIO) + include_directories(SYSTEM ${DUMB_INCLUDE_DIR}) + set(ALLEGRO_CFG_ACODEC_MODAUDIO 1) + list(APPEND ACODEC_SOURCES modaudio.c) + + list(APPEND ACODEC_INCLUDE_DIRECTORIES ${DUMB_INCLUDE_DIR}) + + if(WIN32 AND WANT_ACODEC_DYNAMIC_LOAD) + if(DUMB_LIBRARY MATCHES "${WIN32_STATIC_LIB_REGEX}") + message("WARNING: Dynamic loading will be disabled for DUMB" + " as static library was found: ${DUMB_LIBRARY}") + else() + get_dll_name(${DUMB_LIBRARY} ALLEGRO_CFG_ACODEC_DUMB_DLL) + endif() + endif() + + if(NOT ALLEGRO_CFG_ACODEC_DUMB_DLL) + list(APPEND ACODEC_LIBRARIES ${DUMB_LIBRARIES}) + endif() +endif() + +# +# Vorbis/Tremor +# + +if(WANT_TREMOR) + find_package(Tremor) + if(TREMOR_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${TREMOR_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${TREMOR_LIBRARIES}) + run_c_compile_test(" + #include <tremor/ivorbisfile.h> + int main(void) + { + OggVorbis_File f; + ov_info(&f, -1); + return 0; + }" + TREMOR_COMPILES) + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + if(TREMOR_COMPILES OR IPHONE OR ALLEGRO_RASPBERRYPI) + set(SUPPORT_VORBIS 1) + endif(TREMOR_COMPILES OR IPHONE OR ALLEGRO_RASPBERRYPI) + endif(TREMOR_FOUND) + if(NOT SUPPORT_VORBIS) + message("WARNING: Tremor not found although WANT_TREMOR was specified.") + else(NOT SUPPORT_VORBIS) + # mimic regular libogg/libvorbis + set(OGG_INCLUDE_DIR ${TREMOR_INCLUDE_DIR}) + set(VORBIS_INCLUDE_DIR ${TREMOR_INCLUDE_DIR}) + set(VORBIS_LIBRARIES ${TREMOR_LIBRARIES}) + set(ALLEGRO_CFG_ACODEC_TREMOR 1) + endif(NOT SUPPORT_VORBIS) +elseif(WANT_VORBIS) + find_package(Vorbis) + if(VORBIS_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${OGG_INCLUDE_DIR} ${VORBIS_INCLUDE_DIR}) + if(COMPILER_GCC_OR_CLANG) + # libm is required when linking statically. + set(CMAKE_REQUIRED_LIBRARIES "${VORBIS_LIBRARIES};m") + else() + set(CMAKE_REQUIRED_LIBRARIES "${VORBIS_LIBRARIES}") + endif(COMPILER_GCC_OR_CLANG) + run_c_compile_test(" + #include <vorbis/vorbisfile.h> + int main(void) + { + OggVorbis_File f; + ov_callbacks callback; + vorbis_info *v = 0; + (void)v; + ov_info(&f, -1); + callback = OV_CALLBACKS_NOCLOSE; + return 0; + }" + VORBIS_COMPILES) + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + if(VORBIS_COMPILES) + set(SUPPORT_VORBIS 1) + endif() + endif(VORBIS_FOUND) + if(NOT SUPPORT_VORBIS) + message("WARNING: libvorbis not found or compile test failed, disabling support.") + endif(NOT SUPPORT_VORBIS) +endif() + +if(SUPPORT_VORBIS) + include_directories(SYSTEM ${OGG_INCLUDE_DIR} ${VORBIS_INCLUDE_DIR}) + set(ALLEGRO_CFG_ACODEC_VORBIS 1) + list(APPEND ACODEC_SOURCES ogg.c) + + list(APPEND ACODEC_INCLUDE_DIRECTORIES ${OGG_INCLUDE_DIR} ${VORBIS_INCLUDE_DIR}) + + if(WIN32 AND WANT_ACODEC_DYNAMIC_LOAD AND NOT WANT_TREMOR) + if(VORBISFILE_LIBRARY MATCHES "${WIN32_STATIC_LIB_REGEX}") + message("WARNING: Dynamic loading will be disabled for Vorbis" + " as static library was found: ${VORBISFILE_LIBRARY}") + else() + get_dll_name(${VORBISFILE_LIBRARY} ALLEGRO_CFG_ACODEC_VORBISFILE_DLL) + endif() + endif() + + if(NOT ALLEGRO_CFG_ACODEC_VORBISFILE_DLL) + list(APPEND ACODEC_LIBRARIES ${VORBIS_LIBRARIES}) + endif() +endif(SUPPORT_VORBIS) + +# +# Opus +# + +if(WANT_OPUS) + find_package(Opus) + if(OPUS_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${OGG_INCLUDE_DIR} ${OPUS_INCLUDE_DIR}) + if(COMPILER_GCC_OR_CLANG) + # libm is required when linking statically. + set(CMAKE_REQUIRED_LIBRARIES "${OPUS_LIBRARIES};m") + else() + set(CMAKE_REQUIRED_LIBRARIES "${OPUS_LIBRARIES}") + endif(COMPILER_GCC_OR_CLANG) + run_c_compile_test(" + #include <opus/opusfile.h> + int main(void) + { + OggOpusFile *f; + OpusHead *v = 0; + (void)v; + op_free(f); + return 0; + }" + OPUS_COMPILES) + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + if(OPUS_COMPILES) + set(SUPPORT_OPUS 1) + endif() + endif(OPUS_FOUND) + if(NOT SUPPORT_OPUS) + message("WARNING: libopus not found or compile test failed, disabling support.") + endif(NOT SUPPORT_OPUS) +endif() + +if(SUPPORT_OPUS) + include_directories(SYSTEM ${OGG_INCLUDE_DIR} ${OPUS_INCLUDE_DIR}) + set(ALLEGRO_CFG_ACODEC_OPUS 1) + list(APPEND ACODEC_SOURCES opus.c) + + list(APPEND ACODEC_INCLUDE_DIRECTORIES ${OGG_INCLUDE_DIR} ${OPUS_INCLUDE_DIR}) + + if(WIN32 AND WANT_ACODEC_DYNAMIC_LOAD) + if(OPUSFILE_LIBRARY MATCHES "${WIN32_STATIC_LIB_REGEX}") + message("WARNING: Dynamic loading will be disabled for Opus" + " as static library was found: ${OPUSFILE_LIBRARY}") + else() + get_dll_name(${OPUSFILE_LIBRARY} ALLEGRO_CFG_ACODEC_OPUSFILE_DLL) + endif() + endif() + + if(NOT ALLEGRO_CFG_ACODEC_OPUSFILE_DLL) + list(APPEND ACODEC_LIBRARIES ${OPUS_LIBRARIES}) + endif() +endif(SUPPORT_OPUS) + + +# +# MP3 +# +if(WANT_MP3) + find_package(MiniMP3) + if(MINIMP3_FOUND) + include_directories(SYSTEM ${MINIMP3_INCLUDE_DIRS}) + set(ALLEGRO_CFG_ACODEC_MP3 1) + list(APPEND ACODEC_SOURCES mp3.c) + endif(MINIMP3_FOUND) + if(NOT MINIMP3_FOUND) + message("WARNING: minimp3 was not found") + endif(NOT MINIMP3_FOUND) +endif() + + +configure_file( + allegro5/internal/aintern_acodec_cfg.h.cmake + ${PROJECT_BINARY_DIR}/include/allegro5/internal/aintern_acodec_cfg.h + ) + +add_our_addon_library(allegro_acodec + AllegroAcodec-${ALLEGRO_SOVERSION} + "${ACODEC_SOURCES};${ACODEC_INCLUDE_FILES}" + "-DALLEGRO_ACODEC_SRC ${FLAC__NO_DLL}" + "${AUDIO_LINK_WITH};${ACODEC_LIBRARIES}" + ) + +install_our_headers(${ACODEC_INCLUDE_FILES}) + +add_addon(acodec) + + +#-----------------------------------------------------------------------------# +# vim: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/acodec/acodec.c b/allegro/addons/acodec/acodec.c new file mode 100644 index 00000000..f8013b99 --- /dev/null +++ b/allegro/addons/acodec/acodec.c @@ -0,0 +1,83 @@ +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_acodec_cfg.h" +#include "acodec.h" + + +/* globals */ +static bool acodec_inited = false; + + +/* Function: al_get_allegro_acodec_version + */ +uint32_t al_get_allegro_acodec_version(void) +{ + return ALLEGRO_VERSION_INT; +} + + +/* Function: al_init_acodec_addon + */ +bool al_init_acodec_addon(void) +{ + bool ret = true; + + ret &= al_register_sample_loader(".wav", _al_load_wav); + ret &= al_register_sample_saver(".wav", _al_save_wav); + ret &= al_register_audio_stream_loader(".wav", _al_load_wav_audio_stream); + + ret &= al_register_sample_loader_f(".wav", _al_load_wav_f); + ret &= al_register_sample_saver_f(".wav", _al_save_wav_f); + ret &= al_register_audio_stream_loader_f(".wav", _al_load_wav_audio_stream_f); + + /* buil-in VOC loader */ + ret &= al_register_sample_loader(".voc", _al_load_voc); + ret &= al_register_sample_loader_f(".voc", _al_load_voc_f); + +#ifdef ALLEGRO_CFG_ACODEC_FLAC + ret &= al_register_sample_loader(".flac", _al_load_flac); + ret &= al_register_audio_stream_loader(".flac", _al_load_flac_audio_stream); + ret &= al_register_sample_loader_f(".flac", _al_load_flac_f); + ret &= al_register_audio_stream_loader_f(".flac", _al_load_flac_audio_stream_f); +#endif + +#ifdef ALLEGRO_CFG_ACODEC_MODAUDIO + ret &= _al_register_dumb_loaders(); +#endif + +#ifdef ALLEGRO_CFG_ACODEC_VORBIS + ret &= al_register_sample_loader(".ogg", _al_load_ogg_vorbis); + ret &= al_register_audio_stream_loader(".ogg", _al_load_ogg_vorbis_audio_stream); + ret &= al_register_sample_loader_f(".ogg", _al_load_ogg_vorbis_f); + ret &= al_register_audio_stream_loader_f(".ogg", _al_load_ogg_vorbis_audio_stream_f); +#endif + +#ifdef ALLEGRO_CFG_ACODEC_OPUS + ret &= al_register_sample_loader(".opus", _al_load_ogg_opus); + ret &= al_register_audio_stream_loader(".opus", _al_load_ogg_opus_audio_stream); + ret &= al_register_sample_loader_f(".opus", _al_load_ogg_opus_f); + ret &= al_register_audio_stream_loader_f(".opus", _al_load_ogg_opus_audio_stream_f); +#endif + +#ifdef ALLEGRO_CFG_ACODEC_MP3 + ret &= al_register_sample_loader(".mp3", _al_load_mp3); + ret &= al_register_audio_stream_loader(".mp3", _al_load_mp3_audio_stream); + ret &= al_register_sample_loader_f(".mp3", _al_load_mp3_f); + ret &= al_register_audio_stream_loader_f(".mp3", _al_load_mp3_audio_stream_f); +#endif + + acodec_inited = ret; + + return ret; +} + + +/* Function: al_is_acodec_addon_initialized + */ +bool al_is_acodec_addon_initialized(void) +{ + return acodec_inited; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/acodec/acodec.h b/allegro/addons/acodec/acodec.h new file mode 100644 index 00000000..ca9b0a82 --- /dev/null +++ b/allegro/addons/acodec/acodec.h @@ -0,0 +1,64 @@ +#ifndef __al_included_acodec_acodec_h +#define __al_included_acodec_acodec_h + +#include "allegro5/internal/aintern_acodec_cfg.h" + +ALLEGRO_SAMPLE *_al_load_wav(const char *filename); +ALLEGRO_SAMPLE *_al_load_wav_f(ALLEGRO_FILE *fp); +ALLEGRO_AUDIO_STREAM *_al_load_wav_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples); +ALLEGRO_AUDIO_STREAM *_al_load_wav_audio_stream_f(ALLEGRO_FILE* f, + size_t buffer_count, unsigned int samples); +bool _al_save_wav(const char *filename, ALLEGRO_SAMPLE *spl); +bool _al_save_wav_f(ALLEGRO_FILE *pf, ALLEGRO_SAMPLE *spl); + +/* + * Built-in Port of A4 Creative Voice file (.voc) Loader. + * should not implement streams since it's unlikely this container + * will ever be used as such. + */ +ALLEGRO_SAMPLE *_al_load_voc(const char *filename); +ALLEGRO_SAMPLE *_al_load_voc_f(ALLEGRO_FILE *fp); + + +#ifdef ALLEGRO_CFG_ACODEC_FLAC +ALLEGRO_SAMPLE *_al_load_flac(const char *filename); +ALLEGRO_SAMPLE *_al_load_flac_f(ALLEGRO_FILE *f); +ALLEGRO_AUDIO_STREAM *_al_load_flac_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples); +ALLEGRO_AUDIO_STREAM *_al_load_flac_audio_stream_f(ALLEGRO_FILE* f, + size_t buffer_count, unsigned int samples); +#endif + +#ifdef ALLEGRO_CFG_ACODEC_MODAUDIO +bool _al_register_dumb_loaders(void); +#endif + +#ifdef ALLEGRO_CFG_ACODEC_VORBIS +ALLEGRO_SAMPLE *_al_load_ogg_vorbis(const char *filename); +ALLEGRO_SAMPLE *_al_load_ogg_vorbis_f(ALLEGRO_FILE *file); +ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples); +ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream_f(ALLEGRO_FILE* file, + size_t buffer_count, unsigned int samples); +#endif + +#ifdef ALLEGRO_CFG_ACODEC_OPUS +ALLEGRO_SAMPLE *_al_load_ogg_opus(const char *filename); +ALLEGRO_SAMPLE *_al_load_ogg_opus_f(ALLEGRO_FILE *file); +ALLEGRO_AUDIO_STREAM *_al_load_ogg_opus_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples); +ALLEGRO_AUDIO_STREAM *_al_load_ogg_opus_audio_stream_f(ALLEGRO_FILE* file, + size_t buffer_count, unsigned int samples); +#endif + +#ifdef ALLEGRO_CFG_ACODEC_MP3 +ALLEGRO_SAMPLE *_al_load_mp3(const char *filename); +ALLEGRO_SAMPLE *_al_load_mp3_f(ALLEGRO_FILE *f); +ALLEGRO_AUDIO_STREAM *_al_load_mp3_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples); +ALLEGRO_AUDIO_STREAM *_al_load_mp3_audio_stream_f(ALLEGRO_FILE* f, + size_t buffer_count, unsigned int samples); +#endif + +#endif diff --git a/allegro/addons/acodec/allegro5/allegro_acodec.h b/allegro/addons/acodec/allegro5/allegro_acodec.h new file mode 100644 index 00000000..cdbe7e01 --- /dev/null +++ b/allegro/addons/acodec/allegro5/allegro_acodec.h @@ -0,0 +1,41 @@ +#ifndef __al_included_allegro5_allegro_acodec_h +#define __al_included_allegro5_allegro_acodec_h + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_ACODEC_SRC + #define _ALLEGRO_ACODEC_DLL __declspec(dllexport) + #else + #define _ALLEGRO_ACODEC_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_ACODEC_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_ACODEC_FUNC(type, name, args) _ALLEGRO_ACODEC_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_ACODEC_FUNC(type, name, args) extern type name args +#else + #define ALLEGRO_ACODEC_FUNC AL_FUNC +#endif + + +ALLEGRO_ACODEC_FUNC(bool, al_init_acodec_addon, (void)); +ALLEGRO_ACODEC_FUNC(bool, al_is_acodec_addon_initialized, (void)); +ALLEGRO_ACODEC_FUNC(uint32_t, al_get_allegro_acodec_version, (void)); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/addons/acodec/allegro5/internal/aintern_acodec_cfg.h.cmake b/allegro/addons/acodec/allegro5/internal/aintern_acodec_cfg.h.cmake new file mode 100644 index 00000000..56ac55f7 --- /dev/null +++ b/allegro/addons/acodec/allegro5/internal/aintern_acodec_cfg.h.cmake @@ -0,0 +1,13 @@ +#cmakedefine ALLEGRO_CFG_ACODEC_FLAC +#cmakedefine ALLEGRO_CFG_ACODEC_MODAUDIO +#cmakedefine ALLEGRO_CFG_ACODEC_VORBIS +#cmakedefine ALLEGRO_CFG_ACODEC_TREMOR +#cmakedefine ALLEGRO_CFG_ACODEC_OPUS +#cmakedefine ALLEGRO_CFG_ACODEC_MP3 + + +/* Define if the library should be loaded dynamically. */ +#cmakedefine ALLEGRO_CFG_ACODEC_FLAC_DLL "@ALLEGRO_CFG_ACODEC_FLAC_DLL@" +#cmakedefine ALLEGRO_CFG_ACODEC_DUMB_DLL "@ALLEGRO_CFG_ACODEC_DUMB_DLL@" +#cmakedefine ALLEGRO_CFG_ACODEC_VORBISFILE_DLL "@ALLEGRO_CFG_ACODEC_VORBISFILE_DLL@" +#cmakedefine ALLEGRO_CFG_ACODEC_OPUSFILE_DLL "@ALLEGRO_CFG_ACODEC_OPUSFILE_DLL@" diff --git a/allegro/addons/acodec/flac.c b/allegro/addons/acodec/flac.c new file mode 100644 index 00000000..1266cde3 --- /dev/null +++ b/allegro/addons/acodec/flac.c @@ -0,0 +1,643 @@ +/* + * Allegro FLAC reader + * author: Ryan Dickie, (c) 2008 + * streaming support by Elias Pschernig + */ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_system.h" +#include "acodec.h" +#include "helper.h" + +#ifndef ALLEGRO_CFG_ACODEC_FLAC + #error configuration problem, ALLEGRO_CFG_ACODEC_FLAC not set +#endif + +#include <FLAC/stream_decoder.h> +#include <stdio.h> + +ALLEGRO_DEBUG_CHANNEL("acodec") + + +typedef struct FLACFILE { + FLAC__StreamDecoder *decoder; + double sample_rate; + int sample_size; + int channels; + + /* The file buffer. */ + uint64_t buffer_pos, buffer_size; + char *buffer; + + /* Number of samples in the complete FLAC. */ + uint64_t total_samples; + + /* Sample position one past last decoded sample. */ + uint64_t decoded_samples; + + /* Sample position one past last streamed sample. */ + uint64_t streamed_samples; + + ALLEGRO_FILE *fh; + uint64_t loop_start, loop_end; /* in samples */ +} FLACFILE; + + +/* dynamic loading support (Windows only currently) */ +#ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL +static void *flac_dll = NULL; +static bool flac_virgin = true; +#endif + +static struct +{ + FLAC__StreamDecoder *(*FLAC__stream_decoder_new)(void); + void (*FLAC__stream_decoder_delete)(FLAC__StreamDecoder *decoder); + FLAC__StreamDecoderInitStatus (*FLAC__stream_decoder_init_stream)( + FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, + void *client_data); + FLAC__bool (*FLAC__stream_decoder_process_single)(FLAC__StreamDecoder *decoder); + FLAC__bool (*FLAC__stream_decoder_process_until_end_of_metadata)(FLAC__StreamDecoder *decoder); + FLAC__bool (*FLAC__stream_decoder_process_until_end_of_stream)(FLAC__StreamDecoder *decoder); + FLAC__bool (*FLAC__stream_decoder_seek_absolute)(FLAC__StreamDecoder *decoder, FLAC__uint64 sample); + FLAC__bool (*FLAC__stream_decoder_flush)(FLAC__StreamDecoder *decoder); + FLAC__bool (*FLAC__stream_decoder_finish)(FLAC__StreamDecoder *decoder); +} lib; + + +#ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL +static void shutdown_dynlib(void) +{ + if (flac_dll) { + _al_close_library(flac_dll); + flac_dll = NULL; + flac_virgin = true; + } +} +#endif + + +static bool init_dynlib(void) +{ +#ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL + if (flac_dll) { + return true; + } + + if (!flac_virgin) { + return false; + } + + flac_virgin = false; + + flac_dll = _al_open_library(ALLEGRO_CFG_ACODEC_FLAC_DLL); + if (!flac_dll) { + ALLEGRO_ERROR("Could not load " ALLEGRO_CFG_ACODEC_FLAC_DLL "\n"); + return false; + } + + _al_add_exit_func(shutdown_dynlib, "shutdown_dynlib"); + + #define INITSYM(x) \ + do \ + { \ + lib.x = _al_import_symbol(flac_dll, #x); \ + if (lib.x == 0) { \ + ALLEGRO_ERROR("undefined symbol in lib structure: " #x "\n"); \ + return false; \ + } \ + } while(0) +#else + #define INITSYM(x) (lib.x = (x)) +#endif + + memset(&lib, 0, sizeof(lib)); + + INITSYM(FLAC__stream_decoder_new); + INITSYM(FLAC__stream_decoder_delete); + INITSYM(FLAC__stream_decoder_init_stream); + INITSYM(FLAC__stream_decoder_process_single); + INITSYM(FLAC__stream_decoder_process_until_end_of_metadata); + INITSYM(FLAC__stream_decoder_process_until_end_of_stream); + INITSYM(FLAC__stream_decoder_seek_absolute); + INITSYM(FLAC__stream_decoder_flush); + INITSYM(FLAC__stream_decoder_finish); + + return true; + +#undef INITSYM +} + + +static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, + FLAC__byte buffer[], size_t *bytes, void *dptr) +{ + FLACFILE *ff = (FLACFILE *)dptr; + ALLEGRO_FILE *fh = ff->fh; + (void)decoder; + if (*bytes > 0) { + *bytes = al_fread(fh, buffer, *bytes); + if (al_ferror(fh)) + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + else if (*bytes == 0) + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + else + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + else + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; +} + + +static FLAC__StreamDecoderSeekStatus seek_callback( + const FLAC__StreamDecoder *decoder, + FLAC__uint64 absolute_byte_offset, void *dptr) +{ + FLACFILE *ff = (FLACFILE *)dptr; + ALLEGRO_FILE *fh = ff->fh; + (void)decoder; + + if (!al_fseek(fh, absolute_byte_offset, ALLEGRO_SEEK_SET)) + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + else + return FLAC__STREAM_DECODER_SEEK_STATUS_OK; +} + + +static FLAC__StreamDecoderTellStatus tell_callback( + const FLAC__StreamDecoder *decoder, + FLAC__uint64 *absolute_byte_offset, void *dptr) +{ + FLACFILE *ff = (FLACFILE *)dptr; + ALLEGRO_FILE *fh = ff->fh; + int64_t pos = 0; + (void)decoder; + + pos = al_ftell(fh); + if (pos == -1) + return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; + + *absolute_byte_offset = (FLAC__uint64)pos; + return FLAC__STREAM_DECODER_TELL_STATUS_OK; +} + + +static FLAC__StreamDecoderLengthStatus length_callback( + const FLAC__StreamDecoder *decoder, + FLAC__uint64 *stream_length, void *dptr) +{ + FLACFILE *ff = (FLACFILE *)dptr; + ALLEGRO_FILE *fh = ff->fh; + (void)decoder; + + /* XXX check error */ + *stream_length = (FLAC__uint64)al_fsize(fh); + + return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; +} + + +static FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *dptr) +{ + FLACFILE *ff = (FLACFILE *)dptr; + ALLEGRO_FILE *fh = ff->fh; + (void)decoder; + + if (al_feof(fh)) + return true; + + return false; +} + + +static void metadata_callback(const FLAC__StreamDecoder *decoder, + const FLAC__StreamMetadata *metadata, void *client_data) +{ + FLACFILE *out = (FLACFILE *)client_data; + + (void)decoder; + + if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { + out->total_samples = metadata->data.stream_info.total_samples; + out->sample_rate = metadata->data.stream_info.sample_rate; + out->channels = metadata->data.stream_info.channels; + out->sample_size = metadata->data.stream_info.bits_per_sample / 8; + } +} + + +static void error_callback(const FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderErrorStatus status, void *client_data) +{ + (void)decoder; + (void)client_data; + +#ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL + (void)status; + ALLEGRO_ERROR("Got FLAC error callback\n"); /* lazy */ +#else + ALLEGRO_ERROR("Got FLAC error callback: %s\n", + FLAC__StreamDecoderErrorStatusString[status]); +#endif +} + + +static FLAC__StreamDecoderWriteStatus write_callback( + const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, + const FLAC__int32 * const buffer[], void *client_data) +{ + FLACFILE *ff = (FLACFILE *) client_data; + long len = frame->header.blocksize; + long bytes = len * ff->channels * ff->sample_size; + FLAC__uint8 *buf8; + FLAC__int16 *buf16; + float *buf32; + int sample_index; + int channel_index; + int out_index; + + if (ff->buffer_pos + bytes > ff->buffer_size) { + ff->buffer = al_realloc(ff->buffer, ff->buffer_pos + bytes); + ff->buffer_size = ff->buffer_pos + bytes; + } + + /* FLAC returns FLAC__int32 and I need to convert it to my own format. */ + buf8 = (FLAC__uint8 *) (ff->buffer + ff->buffer_pos); + buf16 = (FLAC__int16 *) buf8; + buf32 = (float *) buf8; + + (void)decoder; + (void)client_data; + + /* Flatten the array */ + /* TODO: test this array flattening process on 5.1 and higher flac files */ + out_index = 0; + switch (ff->sample_size) { + case 1: + for (sample_index = 0; sample_index < len; sample_index++) { + for (channel_index = 0; + channel_index < ff->channels; + channel_index++) { + buf8[out_index++] = + (FLAC__uint8) buffer[channel_index][sample_index]; + } + } + break; + + case 2: + for (sample_index = 0; sample_index < len; sample_index++) { + for (channel_index = 0; channel_index < ff->channels; + channel_index++) { + buf16[out_index++] = + (FLAC__int16) buffer[channel_index][sample_index]; + } + } + break; + + case 3: + for (sample_index = 0; sample_index < len; sample_index++) { + for (channel_index = 0; channel_index < ff->channels; + channel_index++) + { + /* Little endian */ + /* FIXME: does this work? I only have 16-bit sound card mixer + * garbages for other 24-bit codecs too. + */ + buf8[out_index++] = (FLAC__uint8) (buffer[channel_index][sample_index] & 0xFF); + buf8[out_index++] = (FLAC__uint8) ((buffer[channel_index][sample_index] & 0xFF00) >> 8); + buf8[out_index++] = (FLAC__uint8) ((buffer[channel_index][sample_index] & 0xFF0000) >> 16); + } + } + break; + + case 4: + for (sample_index = 0; sample_index < len; sample_index++) { + for (channel_index = 0; channel_index < ff->channels; + channel_index++) { + buf32[out_index++] = + (float) buffer[channel_index][sample_index]; + } + } + break; + + default: + /* Word_size not supported. */ + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + + ff->decoded_samples += len; + ff->buffer_pos += bytes; + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; +} + +static void flac_close(FLACFILE *ff) +{ + lib.FLAC__stream_decoder_finish(ff->decoder); + lib.FLAC__stream_decoder_delete(ff->decoder); + /* Don't close ff->fh here. */ + al_free(ff); +} + +/* In seconds. */ +static double flac_stream_get_position(ALLEGRO_AUDIO_STREAM *stream) +{ + FLACFILE *ff = (FLACFILE *)stream->extra; + return ff->streamed_samples / ff->sample_rate; +} + + +/* + * Updates 'stream' with the next chunk of data. + * Returns the actual number of bytes written. + */ +static size_t flac_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, + size_t buf_size) +{ + int bytes_per_sample; + uint64_t wanted_samples; + uint64_t read_samples; + size_t written_bytes = 0; + size_t read_bytes; + FLACFILE *ff = (FLACFILE *)stream->extra; + + bytes_per_sample = ff->sample_size * ff->channels; + wanted_samples = buf_size / bytes_per_sample; + + if (ff->streamed_samples + wanted_samples > ff->loop_end) { + if (ff->loop_end > ff->streamed_samples) + wanted_samples = ff->loop_end - ff->streamed_samples; + else + return 0; + } + + while (wanted_samples > 0) { + read_samples = ff->decoded_samples - ff->streamed_samples; + + /* If the buffer size is small, we shouldn't read a new frame or our + * buffer keeps growing - so only refill when needed. + */ + if (!read_samples) { + if (!lib.FLAC__stream_decoder_process_single(ff->decoder)) + break; + read_samples = ff->decoded_samples - ff->streamed_samples; + if (!read_samples) { + break; + } + } + + if (read_samples > wanted_samples) + read_samples = wanted_samples; + ff->streamed_samples += read_samples; + wanted_samples -= read_samples; + read_bytes = read_samples * bytes_per_sample; + /* Copy data from the FLAC file buffer to the stream buffer. */ + memcpy((uint8_t *)data + written_bytes, ff->buffer, read_bytes); + /* Make room in the FLACFILE buffer. */ + memmove(ff->buffer, ff->buffer + read_bytes, + ff->buffer_pos - read_bytes); + ff->buffer_pos -= read_bytes; + written_bytes += read_bytes; + } + + return written_bytes; +} + +/* Called from al_destroy_audio_stream. */ +static void flac_stream_close(ALLEGRO_AUDIO_STREAM *stream) +{ + FLACFILE *ff = stream->extra; + _al_acodec_stop_feed_thread(stream); + + al_fclose(ff->fh); + al_free(ff->buffer); + flac_close(ff); +} + +static bool real_seek(ALLEGRO_AUDIO_STREAM *stream, uint64_t sample) +{ + FLACFILE *ff = stream->extra; + + /* We use ff->streamed_samples as the exact sample position for looping and + * returning the position. Therefore we also use it as reference position + * when seeking - that is, we call flush below to make the FLAC decoder + * discard any additional samples it may have buffered already. + * */ + lib.FLAC__stream_decoder_flush(ff->decoder); + lib.FLAC__stream_decoder_seek_absolute(ff->decoder, sample); + + ff->buffer_pos = 0; + ff->streamed_samples = sample; + ff->decoded_samples = sample; + return true; +} + +static bool flac_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time) +{ + FLACFILE *ff = stream->extra; + uint64_t sample = time * ff->sample_rate; + return real_seek(stream, sample); +} + +static bool flac_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) +{ + FLACFILE *ff = stream->extra; + return real_seek(stream, ff->loop_start); +} + +static double flac_stream_get_length(ALLEGRO_AUDIO_STREAM *stream) +{ + FLACFILE *ff = stream->extra; + return ff->total_samples / ff->sample_rate; +} + +static bool flac_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, double start, + double end) +{ + FLACFILE *ff = stream->extra; + ff->loop_start = start * ff->sample_rate; + ff->loop_end = end * ff->sample_rate; + return true; +} + +static FLACFILE *flac_open(ALLEGRO_FILE* f) +{ + FLACFILE *ff; + FLAC__StreamDecoderInitStatus init_status; + + if (!init_dynlib()) { + return NULL; + } + + ff = al_calloc(1, sizeof *ff); + + ff->decoder = lib.FLAC__stream_decoder_new(); + if (!ff->decoder) { + ALLEGRO_ERROR("Error allocating FLAC decoder\n"); + goto error; + } + + ff->fh = f; + if (!ff->fh) { + ALLEGRO_ERROR("Error opening FLAC file\n"); + goto error; + } + + init_status = lib.FLAC__stream_decoder_init_stream(ff->decoder, read_callback, + seek_callback, tell_callback, length_callback, eof_callback, + write_callback, metadata_callback, error_callback, ff); + if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { +#ifdef ALLEGRO_CFG_ACODEC_FLAC_DLL + ALLEGRO_ERROR("Error initializing FLAC decoder\n"); /* lazy */ +#else + ALLEGRO_ERROR("Error initializing FLAC decoder: %s\n", + FLAC__StreamDecoderInitStatusString[init_status]); +#endif + goto error; + } + + lib.FLAC__stream_decoder_process_until_end_of_metadata(ff->decoder); + + if (ff->sample_size == 0) { + ALLEGRO_ERROR("Error: don't support sub 8-bit sizes\n"); + goto error; + } + + ALLEGRO_DEBUG("Loaded FLAC sample with properties:\n"); + ALLEGRO_DEBUG(" channels %d\n", ff->channels); + ALLEGRO_DEBUG(" sample_size %d\n", ff->sample_size); + ALLEGRO_DEBUG(" rate %.f\n", ff->sample_rate); + ALLEGRO_DEBUG(" total_samples %ld\n", (long) ff->total_samples); + + return ff; + +error: + if (ff) { + if (ff->decoder) + lib.FLAC__stream_decoder_delete(ff->decoder); + al_free(ff); + } + return NULL; +} + +ALLEGRO_SAMPLE *_al_load_flac(const char *filename) +{ + ALLEGRO_FILE *f; + ALLEGRO_SAMPLE *spl; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + spl = _al_load_flac_f(f); + + al_fclose(f); + + return spl; +} + +ALLEGRO_SAMPLE *_al_load_flac_f(ALLEGRO_FILE *f) +{ + ALLEGRO_SAMPLE *sample; + FLACFILE *ff; + + ff = flac_open(f); + if (!ff) { + return NULL; + } + + ff->buffer_size = ff->total_samples * ff->channels * ff->sample_size; + ff->buffer = al_malloc(ff->buffer_size); + + lib.FLAC__stream_decoder_process_until_end_of_stream(ff->decoder); + + sample = al_create_sample(ff->buffer, ff->total_samples, ff->sample_rate, + _al_word_size_to_depth_conf(ff->sample_size), + _al_count_to_channel_conf(ff->channels), true); + + if (!sample) { + ALLEGRO_ERROR("Failed to create a sample.\n"); + al_free(ff->buffer); + } + + flac_close(ff); + + return sample; +} + +ALLEGRO_AUDIO_STREAM *_al_load_flac_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + stream = _al_load_flac_audio_stream_f(f, buffer_count, samples); + if (!stream) { + al_fclose(f); + } + + return stream; +} + +ALLEGRO_AUDIO_STREAM *_al_load_flac_audio_stream_f(ALLEGRO_FILE* f, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_AUDIO_STREAM *stream; + FLACFILE *ff; + + ff = flac_open(f); + if (!ff) { + return NULL; + } + + stream = al_create_audio_stream(buffer_count, samples, ff->sample_rate, + _al_word_size_to_depth_conf(ff->sample_size), + _al_count_to_channel_conf(ff->channels)); + + if (stream) { + stream->extra = ff; + ff->loop_start = 0; + ff->loop_end = ff->total_samples; + stream->feeder = flac_stream_update; + stream->unload_feeder = flac_stream_close; + stream->rewind_feeder = flac_stream_rewind; + stream->seek_feeder = flac_stream_seek; + stream->get_feeder_position = flac_stream_get_position; + stream->get_feeder_length = flac_stream_get_length; + stream->set_feeder_loop = flac_stream_set_loop; + _al_acodec_start_feed_thread(stream); + } + else { + ALLEGRO_ERROR("Failed to create stream.\n"); + al_fclose(ff->fh); + flac_close(ff); + } + + return stream; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/acodec/helper.c b/allegro/addons/acodec/helper.c new file mode 100644 index 00000000..26194ca7 --- /dev/null +++ b/allegro/addons/acodec/helper.c @@ -0,0 +1,36 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_system.h" +#include "helper.h" + +void _al_acodec_start_feed_thread(ALLEGRO_AUDIO_STREAM *stream) +{ + stream->feed_thread = al_create_thread(_al_kcm_feed_stream, stream); + stream->feed_thread_started_cond = al_create_cond(); + stream->feed_thread_started_mutex = al_create_mutex(); + al_start_thread(stream->feed_thread); +} + +void _al_acodec_stop_feed_thread(ALLEGRO_AUDIO_STREAM *stream) +{ + ALLEGRO_EVENT quit_event; + + /* Need to wait for the thread to start, otherwise the quit event may be + * sent before the event source is registered with the queue. */ + al_lock_mutex(stream->feed_thread_started_mutex); + while (!stream->feed_thread_started) { + al_wait_cond(stream->feed_thread_started_cond, stream->feed_thread_started_mutex); + } + al_unlock_mutex(stream->feed_thread_started_mutex); + + quit_event.type = _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE; + al_emit_user_event(al_get_audio_stream_event_source(stream), &quit_event, NULL); + al_join_thread(stream->feed_thread, NULL); + al_destroy_thread(stream->feed_thread); + al_destroy_cond(stream->feed_thread_started_cond); + al_destroy_mutex(stream->feed_thread_started_mutex); + + stream->feed_thread = NULL; +} diff --git a/allegro/addons/acodec/helper.h b/allegro/addons/acodec/helper.h new file mode 100644 index 00000000..91a018c9 --- /dev/null +++ b/allegro/addons/acodec/helper.h @@ -0,0 +1,7 @@ +#ifndef __al_included_acodec_helper_h +#define __al_included_acodec_helper_h + +void _al_acodec_start_feed_thread(ALLEGRO_AUDIO_STREAM *stream); +void _al_acodec_stop_feed_thread(ALLEGRO_AUDIO_STREAM *stream); + +#endif diff --git a/allegro/addons/acodec/modaudio.c b/allegro/addons/acodec/modaudio.c new file mode 100644 index 00000000..358b5445 --- /dev/null +++ b/allegro/addons/acodec/modaudio.c @@ -0,0 +1,671 @@ +/* + * Allegro MOD reader + * author: Matthew Leverton + */ + + +#define _FILE_OFFSET_BITS 64 +#include "allegro5/allegro.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_system.h" +#include "acodec.h" +#include "helper.h" + +#ifndef ALLEGRO_CFG_ACODEC_MODAUDIO + #error configuration problem, ALLEGRO_CFG_ACODEC_MODAUDIO not set +#endif + +// We use the deprecated duh_render in DUMB 2. +#define DUMB_DECLARE_DEPRECATED +#include <dumb.h> +#include <stdio.h> + +ALLEGRO_DEBUG_CHANNEL("acodec") + +/* In addition to DUMB 0.9.3 at http://dumb.sourceforge.net/, + * we support kode54's fork of DUMB at https://github.com/kode54/dumb. + * The newest version before kode54's fork was DUMB 0.9.3, and the first + * forked version that A5 supports is already 2.0.0. + */ + +/* forward declarations */ +static bool init_libdumb(void); +static size_t modaudio_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, + size_t buf_size); +static bool modaudio_stream_rewind(ALLEGRO_AUDIO_STREAM *stream); +static bool modaudio_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time); +static double modaudio_stream_get_position(ALLEGRO_AUDIO_STREAM *stream); +static double modaudio_stream_get_length(ALLEGRO_AUDIO_STREAM *stream); +static bool modaudio_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, + double start, double end); +static void modaudio_stream_close(ALLEGRO_AUDIO_STREAM *stream); + + +typedef struct MOD_FILE +{ + DUH *duh; + DUH_SIGRENDERER *sig; + ALLEGRO_FILE *fh; + double length; + long loop_start, loop_end; +} MOD_FILE; + + +static bool libdumb_loaded = false; + + +/* dynamic loading support (Windows only currently) */ +#ifdef ALLEGRO_CFG_ACODEC_DUMB_DLL +static void *dumb_dll = NULL; +#endif + +/* + * dumb_off_t is introduced in DUMB 2.0, it's a signed 64+ bit integer. + * dumb_ssize_t is a platform-independent signed size_t. + * DUMB 0.9.3 expects long wherever dumb_off_t or dumb_ssize_t appear. + * + * _al_dumb_size_t takes care of another, less documented, difference + * between the versions. + */ +#if (DUMB_MAJOR_VERSION) < 2 +typedef long dumb_off_t; +typedef long dumb_ssize_t; +typedef long _al_dumb_size_t; +#else +typedef size_t _al_dumb_size_t; +#endif + +static struct +{ + long (*duh_sigrenderer_get_position)(DUH_SIGRENDERER *); + void (*duh_end_sigrenderer)(DUH_SIGRENDERER *); + void (*unload_duh)(DUH *); + DUH_SIGRENDERER *(*duh_start_sigrenderer)(DUH *, int, int, long); + dumb_off_t (*duh_get_length)(DUH *); + void (*dumb_exit)(void); + DUMB_IT_SIGRENDERER *(*duh_get_it_sigrenderer)(DUH_SIGRENDERER *); + void (*dumb_it_set_loop_callback)(DUMB_IT_SIGRENDERER *, int (*)(void *), void *); + void (*dumb_it_set_xm_speed_zero_callback)(DUMB_IT_SIGRENDERER *, int (*)(void *), void *); + int (*dumb_it_callback_terminate)(void *); + +#if (DUMB_MAJOR_VERSION) >= 2 + /* + * DUMB 2.0 deprecates duh_render, and suggests instead duh_render_int + * and duh_render_float. But I (Simon N.) don't know how to use those. + * I have already written some documentation for DUMB 2.0 that got merged + * upstream, but I haven't gotten around to this issue yet. + */ + long (*duh_render)(DUH_SIGRENDERER *, + int, int, float, float, long, void *); /* deprecated */ + void (*register_dumbfile_system)(const DUMBFILE_SYSTEM *); + DUMBFILE *(*dumbfile_open_ex)(void *, const DUMBFILE_SYSTEM *); + DUH *(*dumb_read_any)(DUMBFILE *, int, int); +#else + long (*duh_render)(DUH_SIGRENDERER *, + int, int, float, float, long, void *); + void (*register_dumbfile_system)(DUMBFILE_SYSTEM *); + DUMBFILE *(*dumbfile_open_ex)(void *, DUMBFILE_SYSTEM *); + DUH *(*dumb_read_mod)(DUMBFILE *); + DUH *(*dumb_read_it)(DUMBFILE *); + DUH *(*dumb_read_xm)(DUMBFILE *); + DUH *(*dumb_read_s3m)(DUMBFILE *); +#endif +} lib; + +/* Set up DUMB's file system */ +static DUMBFILE_SYSTEM dfs, dfs_f; + +static void *dfs_open(const char *filename) +{ + return al_fopen(filename, "rb"); +} + +static int dfs_skip(void *f, dumb_off_t n) +{ + return al_fseek(f, n, ALLEGRO_SEEK_CUR) ? 0 : -1; +} + +static int dfs_getc(void *f) +{ + return al_fgetc(f); +} + +static dumb_ssize_t dfs_getnc(char *ptr, _al_dumb_size_t n, void *f) +{ + return al_fread(f, ptr, n); +} + +static void dfs_close(void *f) +{ + /* Don't actually close f here. */ + (void)f; +} + +#if (DUMB_MAJOR_VERSION) >= 2 +static int dfs_seek(void *f, dumb_off_t n) +{ + return al_fseek(f, n, ALLEGRO_SEEK_SET) ? 0 : -1; +} + +static dumb_off_t dfs_get_size(void *f) +{ + return al_fsize(f); +} +#endif + +/* Stream Functions */ + +static size_t modaudio_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, + size_t buf_size) +{ + MOD_FILE *const df = stream->extra; + + /* the mod files are stereo and 16-bit */ + const int sample_size = 4; + size_t written = 0; + size_t i; + + DUMB_IT_SIGRENDERER *it_sig = lib.duh_get_it_sigrenderer(df->sig); + if (it_sig) { + lib.dumb_it_set_loop_callback(it_sig, + stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONCE + ? lib.dumb_it_callback_terminate : NULL, NULL); + } + + while (written < buf_size) { + written += lib.duh_render(df->sig, 16, 0, 1.0, 65536.0 / 44100.0, + (buf_size - written) / sample_size, &(((char *)data)[written])) * sample_size; + if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONCE) { + break; + } + } + + /* Fill the remainder with silence */ + for (i = written; i < buf_size; ++i) + ((char *)data)[i] = 0; + + return written; +} + +static void modaudio_stream_close(ALLEGRO_AUDIO_STREAM *stream) +{ + MOD_FILE *const df = stream->extra; + _al_acodec_stop_feed_thread(stream); + + lib.duh_end_sigrenderer(df->sig); + lib.unload_duh(df->duh); + if (df->fh) + al_fclose(df->fh); +} + +static bool modaudio_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) +{ + MOD_FILE *const df = stream->extra; + lib.duh_end_sigrenderer(df->sig); + df->sig = lib.duh_start_sigrenderer(df->duh, 0, 2, df->loop_start); + return true; +} + +static bool modaudio_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time) +{ + MOD_FILE *const df = stream->extra; + + lib.duh_end_sigrenderer(df->sig); + df->sig = lib.duh_start_sigrenderer(df->duh, 0, 2, time * 65536); + + return true; +} + +static double modaudio_stream_get_position(ALLEGRO_AUDIO_STREAM *stream) +{ + MOD_FILE *const df = stream->extra; + return lib.duh_sigrenderer_get_position(df->sig) / 65536.0; +} + +static double modaudio_stream_get_length(ALLEGRO_AUDIO_STREAM *stream) +{ + MOD_FILE *const df = stream->extra; + return df->length; +} + +static bool modaudio_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, + double start, double end) +{ + MOD_FILE *const df = stream->extra; + + df->loop_start = start * 65536; + df->loop_end = end * 65536; + + return true; +} + +static ALLEGRO_AUDIO_STREAM *modaudio_stream_init(ALLEGRO_FILE* f, + size_t buffer_count, unsigned int samples +#if (DUMB_MAJOR_VERSION) < 2 + /* For DUMB 0.9.3, we must choose a loader function ourselves. */ + , DUH *(loader)(DUMBFILE *) +#endif +) +{ + ALLEGRO_AUDIO_STREAM *stream; + DUMBFILE *df; + DUH_SIGRENDERER *sig = NULL; + DUH *duh = NULL; + DUMB_IT_SIGRENDERER *it_sig = NULL; + int64_t start_pos = -1; + + df = lib.dumbfile_open_ex(f, &dfs_f); + if (!df) { + ALLEGRO_ERROR("dumbfile_open_ex failed.\n"); + return NULL; + } + + start_pos = al_ftell(f); + +#if (DUMB_MAJOR_VERSION) >= 2 + /* + * DUMB 2.0 introduces dumb_read_any. It takes two extra int arguments. + * + * The first int, restrict_, changes how a MOD module is interpreted. + * int restrict_ is a two-bit bitfield, and 0 is a good default. + * For discussion, see: https://github.com/kode54/dumb/issues/53 + * + * The second int, subsong, matters only for very few formats. + * A5 doesn't allow to choose a subsong from the 5.2 API anyway, thus 0. + */ + duh = lib.dumb_read_any(df, 0, 0); +#else + duh = loader(df); +#endif + if (!duh) { + ALLEGRO_ERROR("Failed to create DUH.\n"); + goto Error; + } + + sig = lib.duh_start_sigrenderer(duh, 0, 2, 0); + if (!sig) { + ALLEGRO_ERROR("duh_start_sigrenderer failed.\n"); + goto Error; + } + + it_sig = lib.duh_get_it_sigrenderer(sig); + if (it_sig) { + /* Turn off freezing for XM files. Seems completely pointless. */ + lib.dumb_it_set_xm_speed_zero_callback(it_sig, lib.dumb_it_callback_terminate, NULL); + } + + stream = al_create_audio_stream(buffer_count, samples, 44100, + ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); + + if (stream) { + MOD_FILE *mf = al_malloc(sizeof(MOD_FILE)); + mf->duh = duh; + mf->sig = sig; + mf->fh = NULL; + mf->length = lib.duh_get_length(duh) / 65536.0; + if (mf->length < 0) + mf->length = 0; + mf->loop_start = -1; + mf->loop_end = -1; + + stream->extra = mf; + stream->feeder = modaudio_stream_update; + stream->unload_feeder = modaudio_stream_close; + stream->rewind_feeder = modaudio_stream_rewind; + stream->seek_feeder = modaudio_stream_seek; + stream->get_feeder_position = modaudio_stream_get_position; + stream->get_feeder_length = modaudio_stream_get_length; + stream->set_feeder_loop = modaudio_stream_set_loop; + _al_acodec_start_feed_thread(stream); + } + else { + ALLEGRO_ERROR("Failed to create stream.\n"); + goto Error; + } + + return stream; + +Error: + + if (sig) { + lib.duh_end_sigrenderer(sig); + } + + if (duh) { + lib.unload_duh(duh); + } + + /* try to return back to where we started to load */ + if (start_pos != -1) + al_fseek(f, start_pos, ALLEGRO_SEEK_SET); + + return NULL; +} + +static void shutdown_libdumb(void) +{ + if (libdumb_loaded) { + lib.dumb_exit(); + libdumb_loaded = false; + } + +#ifdef ALLEGRO_CFG_ACODEC_DUMB_DLL + if (dumb_dll) { + _al_close_library(dumb_dll); + dumb_dll = NULL; + } +#endif +} + +static bool init_libdumb(void) +{ + if (libdumb_loaded) { + return true; + } + +#ifdef ALLEGRO_CFG_ACODEC_DUMB_DLL + dumb_dll = _al_open_library(ALLEGRO_CFG_ACODEC_DUMB_DLL); + if (!dumb_dll) { + ALLEGRO_ERROR("Could not load " ALLEGRO_CFG_ACODEC_DUMB_DLL "\n"); + return false; + } + + #define INITSYM(x) \ + do \ + { \ + lib.x = _al_import_symbol(dumb_dll, #x); \ + if (lib.x == 0) { \ + ALLEGRO_ERROR("undefined symbol in lib structure: " #x "\n"); \ + return false; \ + } \ + } while(0) +#else + #define INITSYM(x) (lib.x = (x)) +#endif + + _al_add_exit_func(shutdown_libdumb, "shutdown_libdumb"); + + memset(&lib, 0, sizeof(lib)); + + INITSYM(duh_render); /* see comment on duh_render deprecation above */ + INITSYM(duh_sigrenderer_get_position); + INITSYM(duh_end_sigrenderer); + INITSYM(unload_duh); + INITSYM(duh_start_sigrenderer); + INITSYM(dumbfile_open_ex); + INITSYM(duh_get_length); + INITSYM(dumb_exit); + INITSYM(register_dumbfile_system); + INITSYM(duh_get_it_sigrenderer); + INITSYM(dumb_it_set_loop_callback); + INITSYM(dumb_it_set_xm_speed_zero_callback); + INITSYM(dumb_it_callback_terminate); + + dfs.open = dfs_open; + dfs.skip = dfs_skip; + dfs.getc = dfs_getc; + dfs.getnc = dfs_getnc; + dfs.close = dfs_close; + +#if (DUMB_MAJOR_VERSION) >= 2 + INITSYM(dumb_read_any); + + dfs.seek = dfs_seek; + dfs.get_size = dfs_get_size; +#else + INITSYM(dumb_read_it); + INITSYM(dumb_read_xm); + INITSYM(dumb_read_s3m); + INITSYM(dumb_read_mod); +#endif + + /* Set up DUMB's default I/O to go through Allegro... */ + lib.register_dumbfile_system(&dfs); + + /* But we'll actually use them through this version: */ + dfs_f = dfs; + dfs_f.open = NULL; + dfs_f.close = NULL; + + libdumb_loaded = true; + return true; +} + +#if (DUMB_MAJOR_VERSION) >= 2 + +static ALLEGRO_AUDIO_STREAM *load_dumb_audio_stream_f(ALLEGRO_FILE *f, + size_t buffer_count, unsigned int samples) +{ + if (!init_libdumb()) + return NULL; + return modaudio_stream_init(f, buffer_count, samples); +} + +/* + * DUMB 2.0 figures out the file format for us. + * Need only one loader from disk file and one loader from DUMBFILE. + */ +static ALLEGRO_AUDIO_STREAM *load_dumb_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) + return NULL; + + stream = load_dumb_audio_stream_f(f, buffer_count, samples); + + if (!stream) { + al_fclose(f); + return NULL; + } + + ((MOD_FILE *)stream->extra)->fh = f; + + return stream; +} + +#else +/* + * For DUMB 0.9.3: + * + * 4 separate loaders for the 4 file formats supported by DUMB 0.9.3, + * then 4 loaders that take a DUMBFILE. The loaders from file are + * all identical, except for the function called in the middle. + */ + +static ALLEGRO_AUDIO_STREAM *load_mod_audio_stream_f(ALLEGRO_FILE *f, + size_t buffer_count, unsigned int samples) +{ + if (!init_libdumb()) + return NULL; + return modaudio_stream_init(f, buffer_count, samples, lib.dumb_read_mod); +} + +static ALLEGRO_AUDIO_STREAM *load_it_audio_stream_f(ALLEGRO_FILE *f, + size_t buffer_count, unsigned int samples) +{ + if (!init_libdumb()) + return NULL; + return modaudio_stream_init(f, buffer_count, samples, lib.dumb_read_it); +} + +static ALLEGRO_AUDIO_STREAM *load_xm_audio_stream_f(ALLEGRO_FILE *f, + size_t buffer_count, unsigned int samples) +{ + if (!init_libdumb()) + return NULL; + return modaudio_stream_init(f, buffer_count, samples, lib.dumb_read_xm); +} + +static ALLEGRO_AUDIO_STREAM *load_s3m_audio_stream_f(ALLEGRO_FILE *f, + size_t buffer_count, unsigned int samples) +{ + if (!init_libdumb()) + return NULL; + return modaudio_stream_init(f, buffer_count, samples, lib.dumb_read_s3m); +} + +static ALLEGRO_AUDIO_STREAM *load_mod_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + stream = load_mod_audio_stream_f(f, buffer_count, samples); + + if (!stream) { + al_fclose(f); + return NULL; + } + + ((MOD_FILE *)stream->extra)->fh = f; + + return stream; +} + +static ALLEGRO_AUDIO_STREAM *load_it_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + stream = load_it_audio_stream_f(f, buffer_count, samples); + + if (!stream) { + al_fclose(f); + return NULL; + } + + ((MOD_FILE *)stream->extra)->fh = f; + + return stream; +} + +static ALLEGRO_AUDIO_STREAM *load_xm_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + stream = load_xm_audio_stream_f(f, buffer_count, samples); + + if (!stream) { + al_fclose(f); + return NULL; + } + + ((MOD_FILE *)stream->extra)->fh = f; + + return stream; +} + +static ALLEGRO_AUDIO_STREAM *load_s3m_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + stream = load_s3m_audio_stream_f(f, buffer_count, samples); + + if (!stream) { + al_fclose(f); + return NULL; + } + + ((MOD_FILE *)stream->extra)->fh = f; + + return stream; +} + +#endif // DUMB_MAJOR_VERSION + +bool _al_register_dumb_loaders(void) +{ + bool ret = true; +#if (DUMB_MAJOR_VERSION) >= 2 + /* + * DUMB 2.0 offers a single loader for at least 13 formats, see their + * readme. Amiga NoiseTracker isn't listed there, but it's DUMB-supported. + * It merely has no common extensions, see: + * https://github.com/kode54/dumb/issues/53 + */ + ret &= al_register_audio_stream_loader(".669", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".669", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".amf", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".amf", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".asy", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".asy", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".it", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".it", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".mod", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".mod", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".mtm", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".mtm", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".okt", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".okt", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".psm", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".psm", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".ptm", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".ptm", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".riff", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".riff", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".s3m", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".s3m", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".stm", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".stm", load_dumb_audio_stream_f); + ret &= al_register_audio_stream_loader(".xm", load_dumb_audio_stream); + ret &= al_register_audio_stream_loader_f(".xm", load_dumb_audio_stream_f); +#else + /* + * DUMB 0.9.3 supported only these 4 formats and had no *_any loader. + * Avoid DUMB 1.0 because of versioning problems: dumb.h from git tag 1.0 + * reports 0.9.3 in its version numbers. + */ + ret &= al_register_audio_stream_loader(".xm", load_xm_audio_stream); + ret &= al_register_audio_stream_loader_f(".xm", load_xm_audio_stream_f); + ret &= al_register_audio_stream_loader(".it", load_it_audio_stream); + ret &= al_register_audio_stream_loader_f(".it", load_it_audio_stream_f); + ret &= al_register_audio_stream_loader(".mod", load_mod_audio_stream); + ret &= al_register_audio_stream_loader_f(".mod", load_mod_audio_stream_f); + ret &= al_register_audio_stream_loader(".s3m", load_s3m_audio_stream); + ret &= al_register_audio_stream_loader_f(".s3m", load_s3m_audio_stream_f); +#endif // DUMB_MAJOR_VERSION + return ret; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/acodec/mp3.c b/allegro/addons/acodec/mp3.c new file mode 100644 index 00000000..56dd091f --- /dev/null +++ b/allegro/addons/acodec/mp3.c @@ -0,0 +1,346 @@ +/* + * Allegro5 MP3 reader. + * Requires MiniMP3 from https://github.com/lieff/minimp3 + * author: Mark Watkin (pmprog) 2019 + */ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_system.h" +#include "acodec.h" +#include "helper.h" + +#define MINIMP3_IMPLEMENTATION +#include <minimp3.h> +#include <minimp3_ex.h> + +ALLEGRO_DEBUG_CHANNEL("acodec") + +typedef struct MP3FILE +{ + mp3dec_t dec; + + uint8_t* file_buffer; /* encoded MP3 file */ + int64_t file_size; /* in bytes */ + int64_t next_frame_offset; /* next frame offset, in bytes */ + + int file_pos; /* position in samples */ + int file_samples; /* in samples */ + double loop_start; + double loop_end; + + mp3d_sample_t frame_buffer[MINIMP3_MAX_SAMPLES_PER_FRAME]; /* decoded MP3 frame */ + int frame_pos; /* position in the frame buffer, in samples */ + + int* frame_offsets; /* in bytes */ + int num_frames; + int frame_samples; /* in samples, same across all frames */ + + int freq; + ALLEGRO_CHANNEL_CONF chan_conf; +} MP3FILE; + +ALLEGRO_SAMPLE *_al_load_mp3(const char *filename) +{ + ALLEGRO_FILE *f; + ALLEGRO_SAMPLE *spl; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_WARN("Could not open file '%s'.\n", filename); + return NULL; + } + + spl = _al_load_mp3_f(f); + + al_fclose(f); + + return spl; +} + +ALLEGRO_SAMPLE *_al_load_mp3_f(ALLEGRO_FILE *f) +{ + mp3dec_t dec; + mp3dec_init(&dec); + + mp3dec_file_info_t info; + ALLEGRO_SAMPLE *spl = NULL; + + /* Read our file size. */ + int64_t filesize = al_fsize(f); + if (filesize == -1) { + ALLEGRO_WARN("Could not determine file size.\n"); + return NULL; + } + + /* Allocate buffer and read all the file. */ + uint8_t* mp3data = (uint8_t*)al_malloc(filesize); + size_t readbytes = al_fread(f, mp3data, filesize); + if (readbytes != (size_t)filesize) { + ALLEGRO_WARN("Failed to read file into memory.\n"); + al_free(mp3data); + return NULL; + } + + /* Decode the file contents, and copy to a new buffer. */ + mp3dec_load_buf(&dec, mp3data, filesize, &info, NULL, NULL); + al_free(mp3data); + + if (info.buffer == NULL) { + ALLEGRO_WARN("Could not decode MP3.\n"); + return NULL; + } + + /* Create sample from info variable. */ + spl = al_create_sample(info.buffer, info.samples / info.channels, info.hz, + _al_word_size_to_depth_conf(sizeof(mp3d_sample_t)), + _al_count_to_channel_conf(info.channels), true); + + return spl; +} + +ALLEGRO_AUDIO_STREAM *_al_load_mp3_audio_stream(const char *filename, size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_WARN("Could not open file '%s'.\n", filename); + return NULL; + } + + stream = _al_load_mp3_audio_stream_f(f, buffer_count, samples); + if (!stream) { + al_fclose(f); + } + + return stream; +} +#include <stdio.h> + +static bool mp3_stream_seek(ALLEGRO_AUDIO_STREAM * stream, double time) +{ + MP3FILE *mp3file = (MP3FILE *) stream->extra; + int file_pos = time * mp3file->freq; + int frame = file_pos / mp3file->frame_samples; + /* It is necessary to start decoding a little earlier than where we are + * seeking to, because frames will reuse decoder state from previous frames. + * minimp3 assures us that 10 frames is sufficient. */ + int sync_frame = _ALLEGRO_MAX(0, frame - 10); + int frame_pos = file_pos - frame * mp3file->frame_samples; + if (frame < 0 || frame > mp3file->num_frames) { + ALLEGRO_WARN("Seeking outside the stream bounds: %f\n", time); + return false; + } + int frame_offset = mp3file->frame_offsets[frame]; + int sync_frame_offset = mp3file->frame_offsets[sync_frame]; + + mp3dec_frame_info_t frame_info; + do { + mp3dec_decode_frame(&mp3file->dec, + mp3file->file_buffer + sync_frame_offset, + mp3file->file_size - sync_frame_offset, + mp3file->frame_buffer, &frame_info); + sync_frame_offset += frame_info.frame_bytes; + } while (sync_frame_offset <= frame_offset); + + mp3file->next_frame_offset = frame_offset + frame_info.frame_bytes; + mp3file->file_pos = file_pos; + mp3file->frame_pos = frame_pos; + + return true; +} + +static bool mp3_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) +{ + MP3FILE *mp3file = (MP3FILE *) stream->extra; + + return mp3_stream_seek(stream, mp3file->loop_start); +} + +static double mp3_stream_get_position(ALLEGRO_AUDIO_STREAM *stream) +{ + MP3FILE *mp3file = (MP3FILE *) stream->extra; + + return (double)mp3file->file_pos / mp3file->freq; +} + +static double mp3_stream_get_length(ALLEGRO_AUDIO_STREAM * stream) +{ + MP3FILE *mp3file = (MP3FILE *) stream->extra; + + return (double)mp3file->file_samples / mp3file->freq; +} + +static bool mp3_stream_set_loop(ALLEGRO_AUDIO_STREAM * stream, double start, double end) +{ + MP3FILE *mp3file = (MP3FILE *) stream->extra; + mp3file->loop_start = start; + mp3file->loop_end = end; + return true; +} + +/* mp3_stream_update: + * Updates 'stream' with the next chunk of data. + * Returns the actual number of bytes written. + */ +static size_t mp3_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, + size_t buf_size) +{ + MP3FILE *mp3file = (MP3FILE *) stream->extra; + int sample_size = sizeof(mp3d_sample_t) * al_get_channel_count(mp3file->chan_conf); + int samples_needed = buf_size / sample_size;; + double ctime = mp3_stream_get_position(stream); + double btime = (double)samples_needed / mp3file->freq; + + if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR && ctime + btime > mp3file->loop_end) { + samples_needed = (mp3file->loop_end - ctime) * mp3file->freq; + } + if (samples_needed < 0) + return 0; + + mp3dec_t dec; + mp3dec_init(&dec); + + int samples_read = 0; + while (samples_read < samples_needed) { + int samples_from_this_frame = _ALLEGRO_MIN( + mp3file->frame_samples - mp3file->frame_pos, + samples_needed - samples_read + ); + memcpy(data, + mp3file->frame_buffer + mp3file->frame_pos * al_get_channel_count(mp3file->chan_conf), + samples_from_this_frame * sample_size); + + mp3file->frame_pos += samples_from_this_frame; + mp3file->file_pos += samples_from_this_frame; + data = (char*)(data) + samples_from_this_frame * sample_size; + samples_read += samples_from_this_frame; + + if (mp3file->frame_pos >= mp3file->frame_samples) { + mp3dec_frame_info_t frame_info; + int frame_samples = mp3dec_decode_frame(&mp3file->dec, + mp3file->file_buffer + mp3file->next_frame_offset, + mp3file->file_size - mp3file->next_frame_offset, + mp3file->frame_buffer, &frame_info); + if (frame_samples == 0) { + mp3_stream_rewind(stream); + break; + } + mp3file->frame_pos = 0; + mp3file->next_frame_offset += frame_info.frame_bytes; + } + } + return samples_read * sample_size; +} + +static void mp3_stream_close(ALLEGRO_AUDIO_STREAM *stream) +{ + MP3FILE *mp3file = (MP3FILE *) stream->extra; + + _al_acodec_stop_feed_thread(stream); + + al_free(mp3file->frame_offsets); + al_free(mp3file->file_buffer); + al_free(mp3file); + stream->extra = NULL; + stream->feed_thread = NULL; +} + +ALLEGRO_AUDIO_STREAM *_al_load_mp3_audio_stream_f(ALLEGRO_FILE* f, size_t buffer_count, unsigned int samples) +{ + MP3FILE* mp3file = al_calloc(sizeof(MP3FILE), 1); + mp3dec_init(&mp3file->dec); + + /* Read our file size. */ + mp3file->file_size = al_fsize(f); + if (mp3file->file_size == -1) { + ALLEGRO_WARN("Could not determine file size.\n"); + goto failure; + } + + /* Allocate buffer and read all the file. */ + mp3file->file_buffer = (uint8_t*)al_malloc(mp3file->file_size); + size_t readbytes = al_fread(f, mp3file->file_buffer, mp3file->file_size); + if (readbytes != (size_t)mp3file->file_size) { + ALLEGRO_WARN("Failed to read file into memory.\n"); + goto failure; + } + al_fclose(f); + + /* Go through all the frames, to build the offset table. */ + int frame_offset_capacity = 0; + int offset_so_far = 0; + while (true) { + if (mp3file->num_frames + 1 > frame_offset_capacity) { + frame_offset_capacity = mp3file->num_frames * 3 / 2 + 1; + mp3file->frame_offsets = al_realloc(mp3file->frame_offsets, + sizeof(int) * frame_offset_capacity); + } + + mp3dec_frame_info_t frame_info; + int frame_samples = mp3dec_decode_frame(&mp3file->dec, + mp3file->file_buffer + offset_so_far, + mp3file->file_size - offset_so_far, NULL, &frame_info); + if (frame_samples == 0) { + if (mp3file->num_frames == 0) { + ALLEGRO_WARN("Could not decode the first frame.\n"); + goto failure; + } + else { + break; + } + } + /* Grab the file information from the first frame. */ + if (offset_so_far == 0) { + ALLEGRO_DEBUG("Channels %d, frequency %d\n", frame_info.channels, frame_info.hz); + mp3file->chan_conf = _al_count_to_channel_conf(frame_info.channels); + mp3file->freq = frame_info.hz; + mp3file->frame_samples = frame_samples; + } + + mp3file->frame_offsets[mp3file->num_frames] = offset_so_far; + mp3file->num_frames += 1; + offset_so_far += frame_info.frame_bytes; + mp3file->file_samples += frame_samples; + } + mp3file->loop_end = (double)mp3file->file_samples * mp3file->freq; + + ALLEGRO_AUDIO_STREAM *stream = al_create_audio_stream( + buffer_count, samples, mp3file->freq, + _al_word_size_to_depth_conf(sizeof(mp3d_sample_t)), + mp3file->chan_conf); + if (!stream) { + ALLEGRO_WARN("Failed to create stream.\n"); + goto failure; + } + + stream->extra = mp3file; + stream->feeder = mp3_stream_update; + stream->unload_feeder = mp3_stream_close; + stream->rewind_feeder = mp3_stream_rewind; + stream->seek_feeder = mp3_stream_seek; + stream->get_feeder_position = mp3_stream_get_position; + stream->get_feeder_length = mp3_stream_get_length; + stream->set_feeder_loop = mp3_stream_set_loop; + + mp3_stream_rewind(stream); + + _al_acodec_start_feed_thread(stream); + + return stream; +failure: + al_free(mp3file->frame_offsets); + al_free(mp3file->file_buffer); + al_free(mp3file->frame_buffer); + al_free(mp3file); + return NULL; +} diff --git a/allegro/addons/acodec/ogg.c b/allegro/addons/acodec/ogg.c new file mode 100644 index 00000000..e22a0611 --- /dev/null +++ b/allegro/addons/acodec/ogg.c @@ -0,0 +1,536 @@ +/* + * Allegro5 Ogg Vorbis reader. + * Can load samples and do streaming + * author: Ryan Dickie (c) 2008 + */ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_system.h" +#include "acodec.h" +#include "helper.h" + +#ifndef ALLEGRO_CFG_ACODEC_VORBIS + #error configuration problem, ALLEGRO_CFG_ACODEC_VORBIS not set +#endif + +ALLEGRO_DEBUG_CHANNEL("acodec") + +#if defined(ALLEGRO_CFG_ACODEC_TREMOR) + #include <tremor/ivorbisfile.h> + #define TREMOR 1 +#else + #include <vorbis/vorbisfile.h> +#endif + +typedef struct AL_OV_DATA AL_OV_DATA; + +struct AL_OV_DATA { + OggVorbis_File *vf; + vorbis_info *vi; + ALLEGRO_FILE *file; + int bitstream; + double loop_start; + double loop_end; +}; + + +/* dynamic loading support (Windows only currently) */ +#ifdef ALLEGRO_CFG_ACODEC_VORBISFILE_DLL +static void *ov_dll = NULL; +static bool ov_virgin = true; +#endif + +static struct +{ + int (*ov_clear)(OggVorbis_File *); + ogg_int64_t (*ov_pcm_total)(OggVorbis_File *, int); + vorbis_info *(*ov_info)(OggVorbis_File *, int); +#ifndef TREMOR + int (*ov_open_callbacks)(void *, OggVorbis_File *, const char *, long, ov_callbacks); + double (*ov_time_total)(OggVorbis_File *, int); + int (*ov_time_seek_lap)(OggVorbis_File *, double); + double (*ov_time_tell)(OggVorbis_File *); + long (*ov_read)(OggVorbis_File *, char *, int, int, int, int, int *); +#else + int (*ov_open_callbacks)(void *, OggVorbis_File *, const char *, long, ov_callbacks); + ogg_int64_t (*ov_time_total)(OggVorbis_File *, int); + int (*ov_time_seek)(OggVorbis_File *, ogg_int64_t); + ogg_int64_t (*ov_time_tell)(OggVorbis_File *); + long (*ov_read)(OggVorbis_File *, char *, int, int *); +#endif +} lib; + + +#ifdef ALLEGRO_CFG_ACODEC_VORBISFILE_DLL +static void shutdown_dynlib(void) +{ + if (ov_dll) { + _al_close_library(ov_dll); + ov_dll = NULL; + ov_virgin = true; + } +} +#endif + + +static bool init_dynlib(void) +{ +#ifdef ALLEGRO_CFG_ACODEC_VORBISFILE_DLL + if (ov_dll) { + return true; + } + + if (!ov_virgin) { + return false; + } + + ov_virgin = false; + + ov_dll = _al_open_library(ALLEGRO_CFG_ACODEC_VORBISFILE_DLL); + if (!ov_dll) { + ALLEGRO_ERROR("Could not load " ALLEGRO_CFG_ACODEC_VORBISFILE_DLL "\n"); + return false; + } + + _al_add_exit_func(shutdown_dynlib, "shutdown_dynlib"); + + #define INITSYM(x) \ + do \ + { \ + lib.x = _al_import_symbol(ov_dll, #x); \ + if (lib.x == 0) { \ + ALLEGRO_ERROR("undefined symbol in lib structure: " #x "\n"); \ + return false; \ + } \ + } while(0) +#else + #define INITSYM(x) (lib.x = (x)) +#endif + + memset(&lib, 0, sizeof(lib)); + + INITSYM(ov_clear); + INITSYM(ov_open_callbacks); + INITSYM(ov_pcm_total); + INITSYM(ov_info); +#ifndef TREMOR + INITSYM(ov_time_total); + INITSYM(ov_time_seek_lap); + INITSYM(ov_time_tell); + INITSYM(ov_read); +#else + INITSYM(ov_time_total); + INITSYM(ov_time_seek); + INITSYM(ov_time_tell); + INITSYM(ov_read); +#endif + + return true; + +#undef INITSYM +} + + +static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *dptr) +{ + AL_OV_DATA *ov = (AL_OV_DATA *)dptr; + size_t ret = 0; + + ret = al_fread(ov->file, ptr, size*nmemb); + + return ret; +} + + +static int seek_callback(void *dptr, ogg_int64_t offset, int whence) +{ + AL_OV_DATA *ov = (AL_OV_DATA *)dptr; + + switch(whence) { + case SEEK_SET: whence = ALLEGRO_SEEK_SET; break; + case SEEK_CUR: whence = ALLEGRO_SEEK_CUR; break; + case SEEK_END: whence = ALLEGRO_SEEK_END; break; + } + + if (!al_fseek(ov->file, offset, whence)) { + return -1; + } + + return 0; +} + + +static long tell_callback(void *dptr) +{ + AL_OV_DATA *ov = (AL_OV_DATA *)dptr; + int64_t ret = 0; + + ret = al_ftell(ov->file); + if (ret == -1) + return -1; + + return (long)ret; +} + + +static int close_callback(void *dptr) +{ + /* Don't close dptr->file here. */ + (void)dptr; + return 0; +} + + +static ov_callbacks callbacks = { + read_callback, + seek_callback, + close_callback, + tell_callback +}; + + +ALLEGRO_SAMPLE *_al_load_ogg_vorbis(const char *filename) +{ + ALLEGRO_FILE *f; + ALLEGRO_SAMPLE *spl; + ASSERT(filename); + + ALLEGRO_INFO("Loading sample %s.\n", filename); + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + spl = _al_load_ogg_vorbis_f(f); + + al_fclose(f); + + return spl; +} + + +ALLEGRO_SAMPLE *_al_load_ogg_vorbis_f(ALLEGRO_FILE *file) +{ + /* Note: decoding library returns floats. I always return 16-bit (most + * commonly supported). + */ +#ifdef ALLEGRO_LITTLE_ENDIAN + const int endian = 0; /* 0 for Little-Endian, 1 for Big-Endian */ +#else + const int endian = 1; /* 0 for Little-Endian, 1 for Big-Endian */ +#endif + int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ + int signedness = 1; /* 0 for unsigned, 1 for signed */ + const int packet_size = 4096; /* suggestion for size to read at a time */ + OggVorbis_File vf; + vorbis_info* vi; + char *buffer; + long pos; + ALLEGRO_SAMPLE *sample; + int channels; + long rate; + long total_samples; + int bitstream; + long total_size; + AL_OV_DATA ov; + long read; + + if (!init_dynlib()) { + return NULL; + } + + ov.file = file; + if (lib.ov_open_callbacks(&ov, &vf, NULL, 0, callbacks) < 0) { + ALLEGRO_ERROR("Audio file does not appear to be an Ogg bitstream.\n"); + return NULL; + } + + vi = lib.ov_info(&vf, -1); + + channels = vi->channels; + rate = vi->rate; + total_samples = lib.ov_pcm_total(&vf, -1); + bitstream = -1; + total_size = total_samples * channels * word_size; + + ALLEGRO_DEBUG("channels %d\n", channels); + ALLEGRO_DEBUG("word_size %d\n", word_size); + ALLEGRO_DEBUG("rate %ld\n", rate); + ALLEGRO_DEBUG("total_samples %ld\n", total_samples); + ALLEGRO_DEBUG("total_size %ld\n", total_size); + + buffer = al_malloc(total_size); + if (!buffer) { + ALLEGRO_ERROR("Unable to allocate buffer (%ld).\n", total_size); + return NULL; + } + + pos = 0; + while (pos < total_size) { + const int read_size = _ALLEGRO_MIN(packet_size, total_size - pos); + ASSERT(pos + read_size <= total_size); + + /* XXX error handling */ +#ifndef TREMOR + read = lib.ov_read(&vf, buffer + pos, read_size, endian, word_size, + signedness, &bitstream); +#else + (void)endian; + (void)signedness; + read = lib.ov_read(&vf, buffer + pos, read_size, &bitstream); +#endif + pos += read; + if (read == 0) + break; + } + + lib.ov_clear(&vf); + + sample = al_create_sample(buffer, total_samples, rate, + _al_word_size_to_depth_conf(word_size), + _al_count_to_channel_conf(channels), true); + + if (!sample) { + ALLEGRO_ERROR("Failed to create sample.\n"); + al_free(buffer); + } + + return sample; +} + + +static bool ogg_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time) +{ + AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; + if (time >= extra->loop_end) + return false; +#ifndef TREMOR + return (lib.ov_time_seek_lap(extra->vf, time) != -1); +#else + return lib.ov_time_seek(extra->vf, time*1000) != -1; +#endif +} + + +static bool ogg_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) +{ + AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; + return ogg_stream_seek(stream, extra->loop_start); +} + + +static double ogg_stream_get_position(ALLEGRO_AUDIO_STREAM *stream) +{ + AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; +#ifndef TREMOR + return lib.ov_time_tell(extra->vf); +#else + return lib.ov_time_tell(extra->vf)/1000.0; +#endif +} + + +static double ogg_stream_get_length(ALLEGRO_AUDIO_STREAM *stream) +{ + AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; +#ifndef TREMOR + double ret = lib.ov_time_total(extra->vf, -1); +#else + double ret = lib.ov_time_total(extra->vf, -1)/1000.0; +#endif + return ret; +} + + +static bool ogg_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, double start, double end) +{ + AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; + + extra->loop_start = start; + extra->loop_end = end; + + return true; +} + + +/* To be called when stream is destroyed */ +static void ogg_stream_close(ALLEGRO_AUDIO_STREAM *stream) +{ + AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; + + _al_acodec_stop_feed_thread(stream); + + al_fclose(extra->file); + + lib.ov_clear(extra->vf); + al_free(extra->vf); + al_free(extra); + stream->extra = NULL; +} + + +static size_t ogg_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, + size_t buf_size) +{ + AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; + +#ifdef ALLEGRO_LITTLE_ENDIAN + const int endian = 0; /* 0 for Little-Endian, 1 for Big-Endian */ +#else + const int endian = 1; /* 0 for Little-Endian, 1 for Big-Endian */ +#endif + const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ + const int signedness = 1; /* 0 for unsigned, 1 for signed */ + + unsigned long pos = 0; + int read_length = buf_size; +#ifndef TREMOR + double ctime = lib.ov_time_tell(extra->vf); +#else + double ctime = lib.ov_time_tell(extra->vf)/1000.0; +#endif + double rate = extra->vi->rate; + double btime = ((double)buf_size / ((double)word_size * (double)extra->vi->channels)) / rate; + unsigned long read; + + if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { + if (ctime + btime > extra->loop_end) { + const int frame_size = word_size * extra->vi->channels; + read_length = (extra->loop_end - ctime) * rate * (double)word_size * (double)extra->vi->channels; + if (read_length < 0) + return 0; + if (read_length % frame_size > 0) { + read_length += (frame_size - (read_length % frame_size)); + } + } + } + while (pos < (unsigned long)read_length) { +#ifndef TREMOR + read = lib.ov_read(extra->vf, (char *)data + pos, + read_length - pos, endian, word_size, signedness, &extra->bitstream); +#else + (void)endian; + (void)signedness; + read = lib.ov_read(extra->vf, (char *)data + pos, + read_length - pos, &extra->bitstream); +#endif + pos += read; + + if (read == 0) { + /* Return the number of useful bytes written. */ + return pos; + } + } + + return pos; +} + + +ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + ALLEGRO_INFO("Loading stream %s.\n", filename); + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + stream = _al_load_ogg_vorbis_audio_stream_f(f, buffer_count, samples); + if (!stream) { + al_fclose(f); + } + + return stream; +} + + +ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream_f(ALLEGRO_FILE *file, + size_t buffer_count, unsigned int samples) +{ + const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ + OggVorbis_File* vf; + vorbis_info* vi; + int channels; + long rate; + long total_samples; + long total_size; + AL_OV_DATA* extra; + ALLEGRO_AUDIO_STREAM* stream; + + if (!init_dynlib()) { + return NULL; + } + + extra = al_malloc(sizeof(AL_OV_DATA)); + if (extra == NULL) { + ALLEGRO_ERROR("Failed to allocate AL_OV_DATA struct.\n"); + return NULL; + } + + extra->file = file; + + vf = al_malloc(sizeof(OggVorbis_File)); + if (lib.ov_open_callbacks(extra, vf, NULL, 0, callbacks) < 0) { + ALLEGRO_ERROR("ogg: Input does not appear to be an Ogg bitstream.\n"); + return NULL; + } + + extra->vf = vf; + + vi = lib.ov_info(vf, -1); + channels = vi->channels; + rate = vi->rate; + total_samples = lib.ov_pcm_total(vf, -1); + total_size = total_samples * channels * word_size; + + extra->vi = vi; + + extra->bitstream = -1; + + ALLEGRO_DEBUG("channels %d\n", channels); + ALLEGRO_DEBUG("word_size %d\n", word_size); + ALLEGRO_DEBUG("rate %ld\n", rate); + ALLEGRO_DEBUG("total_samples %ld\n", total_samples); + ALLEGRO_DEBUG("total_size %ld\n", total_size); + + stream = al_create_audio_stream(buffer_count, samples, rate, + _al_word_size_to_depth_conf(word_size), + _al_count_to_channel_conf(channels)); + if (!stream) { + ALLEGRO_ERROR("Failed to create the stream.\n"); + lib.ov_clear(vf); + al_free(vf); + return NULL; + } + + stream->extra = extra; + + extra->loop_start = 0.0; + extra->loop_end = ogg_stream_get_length(stream); + stream->quit_feed_thread = false; + stream->feeder = ogg_stream_update; + stream->rewind_feeder = ogg_stream_rewind; + stream->seek_feeder = ogg_stream_seek; + stream->get_feeder_position = ogg_stream_get_position; + stream->get_feeder_length = ogg_stream_get_length; + stream->set_feeder_loop = ogg_stream_set_loop; + stream->unload_feeder = ogg_stream_close; + _al_acodec_start_feed_thread(stream); + + return stream; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/acodec/opus.c b/allegro/addons/acodec/opus.c new file mode 100644 index 00000000..1c66909e --- /dev/null +++ b/allegro/addons/acodec/opus.c @@ -0,0 +1,472 @@ +/* + * Allegro5 Opus reader. + * author: Boris Carvajal (c) 2016 + * Based on ogg.c code + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_system.h" +#include "acodec.h" +#include "helper.h" + +#ifndef ALLEGRO_CFG_ACODEC_OPUS + #error configuration problem, ALLEGRO_CFG_ACODEC_OPUS not set +#endif + +ALLEGRO_DEBUG_CHANNEL("acodec") + +#include <opus/opusfile.h> + +typedef struct AL_OP_DATA AL_OP_DATA; + +struct AL_OP_DATA { + OggOpusFile *of; + ALLEGRO_FILE *file; + int channels; + int bitstream; + double loop_start; + double loop_end; +}; + +/* dynamic loading support (Windows only currently) */ +#ifdef ALLEGRO_CFG_ACODEC_OPUSFILE_DLL +static void *op_dll = NULL; +static bool op_virgin = true; +#endif + +static struct +{ + void (*op_free)(OggOpusFile *_of); + int (*op_channel_count)(const OggOpusFile *_of,int _li); + OggOpusFile *(*op_open_callbacks)(void *_source, const OpusFileCallbacks *_cb, const unsigned char *_initial_data, size_t _initial_bytes, int *_error); + ogg_int64_t (*op_pcm_total)(const OggOpusFile *_of, int _li); + int (*op_pcm_seek)(OggOpusFile *_of, ogg_int64_t _pcm_offset); + ogg_int64_t (*op_pcm_tell)(const OggOpusFile *_of); + int (*op_read)(OggOpusFile *_of, opus_int16 *_pcm, int _buf_size, int *_li); +} lib; + + +#ifdef ALLEGRO_CFG_ACODEC_OPUSFILE_DLL +static void shutdown_dynlib(void) +{ + if (op_dll) { + _al_close_library(op_dll); + op_dll = NULL; + op_virgin = true; + } +} +#endif + + +static bool init_dynlib(void) +{ +#ifdef ALLEGRO_CFG_ACODEC_OPUSFILE_DLL + if (op_dll) { + return true; + } + + if (!op_virgin) { + return false; + } + + op_virgin = false; + + op_dll = _al_open_library(ALLEGRO_CFG_ACODEC_OPUSFILE_DLL); + if (!op_dll) { + ALLEGRO_WARN("Could not load " ALLEGRO_CFG_ACODEC_OPUSFILE_DLL "\n"); + return false; + } + + _al_add_exit_func(shutdown_dynlib, "shutdown_dynlib"); + + #define INITSYM(x) \ + do \ + { \ + lib.x = _al_import_symbol(op_dll, #x); \ + if (lib.x == 0) { \ + ALLEGRO_ERROR("undefined symbol in lib structure: " #x "\n"); \ + return false; \ + } \ + } while(0) +#else + #define INITSYM(x) (lib.x = (x)) +#endif + + memset(&lib, 0, sizeof(lib)); + + INITSYM(op_free); + INITSYM(op_channel_count); + INITSYM(op_open_callbacks); + INITSYM(op_pcm_total); + INITSYM(op_pcm_seek); + INITSYM(op_pcm_tell); + INITSYM(op_read); + + return true; + +#undef INITSYM +} + + +static int read_callback(void *stream, unsigned char *ptr, int nbytes) +{ + AL_OP_DATA *op = (AL_OP_DATA *)stream; + size_t ret = 0; + + ret = al_fread(op->file, ptr, nbytes); + + return ret; +} + + +static int seek_callback(void *stream, opus_int64 offset, int whence) +{ + AL_OP_DATA *op = (AL_OP_DATA *)stream; + + switch(whence) { + case SEEK_SET: whence = ALLEGRO_SEEK_SET; break; + case SEEK_CUR: whence = ALLEGRO_SEEK_CUR; break; + case SEEK_END: whence = ALLEGRO_SEEK_END; break; + } + + if (!al_fseek(op->file, offset, whence)) { + return -1; + } + + return 0; +} + + +static opus_int64 tell_callback(void *stream) +{ + AL_OP_DATA *op = (AL_OP_DATA *)stream; + int64_t ret = 0; + + ret = al_ftell(op->file); + if (ret == -1) + return -1; + + return ret; +} + + +static int close_callback(void *stream) +{ + /* Don't close stream->file here. */ + (void)stream; + return 0; +} + + +static OpusFileCallbacks callbacks = { + read_callback, + seek_callback, + tell_callback, + close_callback +}; + + +ALLEGRO_SAMPLE *_al_load_ogg_opus(const char *filename) +{ + ALLEGRO_FILE *f; + ALLEGRO_SAMPLE *spl; + ASSERT(filename); + + ALLEGRO_INFO("Loading sample %s.\n", filename); + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + spl = _al_load_ogg_opus_f(f); + + al_fclose(f); + + return spl; +} + + +ALLEGRO_SAMPLE *_al_load_ogg_opus_f(ALLEGRO_FILE *file) +{ + /* Note: decoding library can return 16-bit or floating-point output, + * both using native endian ordering. (TODO: Implement float output, + * individual links in the stream...) + */ + int word_size = 2; /* 2 = 16-bit. */ + const int packet_size = 5760; /* suggestion for size to read at a time */ + OggOpusFile *of; + opus_int16 *buffer; + ALLEGRO_SAMPLE *sample; + int channels; + long rate; + ogg_int64_t total_samples; + int bitstream; + ogg_int64_t total_size; + AL_OP_DATA op; + ogg_int64_t pos; + long read; + + if (!init_dynlib()) { + return NULL; + } + + op.file = file; + of = lib.op_open_callbacks(&op, &callbacks, NULL, 0, NULL); + if (!of) { + ALLEGRO_ERROR("Audio file does not appear to be an Ogg bitstream.\n"); + return NULL; + } + + bitstream = -1; + channels = lib.op_channel_count(of, bitstream); + rate = 48000; + total_samples = lib.op_pcm_total(of, bitstream); + total_size = total_samples * channels * word_size; + + ALLEGRO_DEBUG("channels %d\n", channels); + ALLEGRO_DEBUG("word_size %d\n", word_size); + ALLEGRO_DEBUG("rate %ld\n", rate); + ALLEGRO_DEBUG("total_samples %ld\n", (long)total_samples); + ALLEGRO_DEBUG("total_size %ld\n", (long)total_size); + + buffer = al_malloc(total_size); + if (!buffer) { + return NULL; + } + + pos = 0; + while (pos < total_samples) { + const int read_size = _ALLEGRO_MIN(packet_size, total_samples - pos); + ASSERT(pos + read_size <= total_samples); + + /* XXX error handling */ + read = lib.op_read(of, buffer + pos * channels, read_size, NULL); + + pos += read; + if (read == 0) + break; + } + + lib.op_free(of); + + sample = al_create_sample(buffer, total_samples, rate, + _al_word_size_to_depth_conf(word_size), + _al_count_to_channel_conf(channels), true); + + if (!sample) { + al_free(buffer); + } + + return sample; +} + + +static bool ogg_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time) +{ + AL_OP_DATA *extra = (AL_OP_DATA *) stream->extra; + + if (time >= extra->loop_end) + return false; + + return !lib.op_pcm_seek(extra->of, time * 48000);; +} + + +static bool ogg_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) +{ + AL_OP_DATA *extra = (AL_OP_DATA *) stream->extra; + + return ogg_stream_seek(stream, extra->loop_start); +} + + +static double ogg_stream_get_position(ALLEGRO_AUDIO_STREAM *stream) +{ + AL_OP_DATA *extra = (AL_OP_DATA *) stream->extra; + + return lib.op_pcm_tell(extra->of)/48000.0; +} + + +static double ogg_stream_get_length(ALLEGRO_AUDIO_STREAM *stream) +{ + AL_OP_DATA *extra = (AL_OP_DATA *) stream->extra; + + return lib.op_pcm_total(extra->of, -1)/48000.0; +} + + +static bool ogg_stream_set_loop(ALLEGRO_AUDIO_STREAM *stream, double start, double end) +{ + AL_OP_DATA *extra = (AL_OP_DATA *) stream->extra; + + extra->loop_start = start; + extra->loop_end = end; + + return true; +} + + +/* To be called when stream is destroyed */ +static void ogg_stream_close(ALLEGRO_AUDIO_STREAM *stream) +{ + AL_OP_DATA *extra = (AL_OP_DATA *) stream->extra; + + _al_acodec_stop_feed_thread(stream); + + al_fclose(extra->file); + + lib.op_free(extra->of); + al_free(extra); + stream->extra = NULL; +} + + +static size_t ogg_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, + size_t buf_size) +{ + AL_OP_DATA *extra = (AL_OP_DATA *) stream->extra; + + const int word_size = 2; /* 2 = 16-bit. opus_int16 size, for use in op_read */ + + unsigned long pos = 0; + int read_length = buf_size; + int buf_in_word; + long rate = 48000; + int channels = extra->channels; + + double ctime = lib.op_pcm_tell(extra->of)/(double)rate; + + double btime = ((double)buf_size / (word_size * channels)) / rate; + long read; + + if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { + if (ctime + btime > extra->loop_end) { + read_length = (extra->loop_end - ctime) * rate * word_size * channels; + if (read_length < 0) + return 0; + read_length += read_length % word_size; + } + } + + buf_in_word= read_length/word_size; + + while (pos < (unsigned long) read_length) { + read = lib.op_read(extra->of, (opus_int16 *)data + pos, buf_in_word - pos, NULL); + pos += read * channels; + + if (read == 0) { + /* Return the number of useful bytes written. */ + return pos*word_size; + } + } + + return pos; +} + + +ALLEGRO_AUDIO_STREAM *_al_load_ogg_opus_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + ALLEGRO_INFO("Loading stream %s.\n", filename); + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + stream = _al_load_ogg_opus_audio_stream_f(f, buffer_count, samples); + if (!stream) { + al_fclose(f); + } + + return stream; +} + + +ALLEGRO_AUDIO_STREAM *_al_load_ogg_opus_audio_stream_f(ALLEGRO_FILE *file, + size_t buffer_count, unsigned int samples) +{ + const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ + OggOpusFile* of; + int channels; + long rate; + long total_samples; + long total_size; + int bitstream; + AL_OP_DATA* extra; + ALLEGRO_AUDIO_STREAM* stream; + + if (!init_dynlib()) { + return NULL; + } + + extra = al_malloc(sizeof(AL_OP_DATA)); + if (extra == NULL) { + ALLEGRO_ERROR("Failed to allocate AL_OP_DATA struct.\n"); + return NULL; + } + + extra->file = file; + + of = lib.op_open_callbacks(extra, &callbacks, NULL, 0, NULL); + if (!of) { + ALLEGRO_ERROR("ogg: Input does not appear to be an Ogg bitstream.\n"); + return NULL; + } + + extra->of = of; + extra->bitstream = -1; + bitstream = extra->bitstream; + + extra->channels = lib.op_channel_count(of, bitstream); + channels = extra->channels; + + rate = 48000; + total_samples = lib.op_pcm_total(of, bitstream); + total_size = total_samples * channels * word_size; + + + ALLEGRO_DEBUG("channels %d\n", channels); + ALLEGRO_DEBUG("word_size %d\n", word_size); + ALLEGRO_DEBUG("rate %ld\n", rate); + ALLEGRO_DEBUG("total_samples %ld\n", total_samples); + ALLEGRO_DEBUG("total_size %ld\n", total_size); + + stream = al_create_audio_stream(buffer_count, samples, rate, + _al_word_size_to_depth_conf(word_size), + _al_count_to_channel_conf(channels)); + if (!stream) { + lib.op_free(of); + return NULL; + } + + stream->extra = extra; + + extra->loop_start = 0.0; + extra->loop_end = ogg_stream_get_length(stream); + stream->quit_feed_thread = false; + stream->feeder = ogg_stream_update; + stream->rewind_feeder = ogg_stream_rewind; + stream->seek_feeder = ogg_stream_seek; + stream->get_feeder_position = ogg_stream_get_position; + stream->get_feeder_length = ogg_stream_get_length; + stream->set_feeder_loop = ogg_stream_set_loop; + stream->unload_feeder = ogg_stream_close; + _al_acodec_start_feed_thread(stream); + + return stream; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/acodec/voc.c b/allegro/addons/acodec/voc.c new file mode 100644 index 00000000..6e3a0a0b --- /dev/null +++ b/allegro/addons/acodec/voc.c @@ -0,0 +1,357 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Allegro5 Creative Voice Audio Reader. + * + * Loosely based on A4 voc loader and tightly based on specs of the soundblaster + * hardware programming manual: + * <http://pdos.csail.mit.edu/6.828/2007/readings/hardware/SoundBlaster.pdf#1254> + * also specs are available at + * <http://sox.sourceforge.net/AudioFormats-11.html> section 11.5 + * + * List of VOC audio codecs supported: + * supported 0x0000 8-bit unsigned PCM + * 0x0001 Creative 8-bit to 4-bit ADPCM *HW implemented on the SB + * 0x0002 Creative 8-bit to 3-bit ADPCM *HW implemented on the SB + * 0x0003 Creative 8-bit to 2-bit ADPCM *HW implemented on the SB + * supported 0x0004 16-bit signed PCM + * + * these are unsupported and present only in VOC files version 1.20 and above + * 0x0006 CCITT a-Law * not really used + * 0x0007 CCITT u-Law * not really used + * 0x0200 Creative 16-bit to 4-bit ADPCM *HW implemented on the SB + * + * + * author: pkrcel (aka Andrea Provasi) <pkrcel@gmail.com> + * + * Revisions: + * 2015-01-03 Source derived from previous sndfile implementation + * cleaned up and put decoder into voc.c + * 2015-01-08 Clean up ISO C90 related warnings and tried to get + * a consistent code style and removed some comments. + * 2015-01-15 Corrected style and enriched header. + */ + + +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_audio.h" +#include "acodec.h" +#include "helper.h" + +ALLEGRO_DEBUG_CHANNEL("voc") + +typedef struct AL_VOC_DATA AL_VOC_DATA; + +struct AL_VOC_DATA { + ALLEGRO_FILE *file; + size_t datapos; + int samplerate; + short bits; /* 8 (unsigned char) or 16 (signed short) */ + short channels; /* 1 (mono) or 2 (stereo) */ + int sample_size; /* channels * bits/8 */ + int samples; /* # of samples. size = samples * sample_size */ +}; + +/* + * Fills in a VOC data header with information obtained by opening an + * caller-provided ALLEGRO_FILE. + * The datapos index will be the first data byte of the first data block which + * contains ACTUAL data. + */ + +#define READNBYTES(f, data, n, retv) \ + do { \ + if (al_fread(f, &data, n) != n) { \ + ALLEGRO_WARN("voc_open: Bad Number of bytes read in last operation"); \ + return retv; \ + } \ + } while(0) + + +static AL_VOC_DATA *voc_open(ALLEGRO_FILE *fp) +{ + AL_VOC_DATA *vocdata; + char hdrbuf[0x16]; + size_t readcount = 0; + + uint8_t blocktype = 0; + uint8_t x = 0; + + uint16_t timeconstant = 0; + uint16_t format = 0; // can be 16-bit in Blocktype 9 (voc version > 1.20 + uint16_t vocversion = 0; + uint16_t checkver = 0; // must be 1's complement of vocversion + 0x1234 + + uint32_t blocklength = 0; //length is stored in 3 bites LE, gd byteorder. + + ASSERT(fp); + + /* init VOC data */ + vocdata = al_malloc(sizeof(AL_VOC_DATA)); + memset(vocdata, 0, sizeof(*vocdata)); + memset(hdrbuf, 0, sizeof(hdrbuf)); + vocdata->file = fp; + + /* Begin checking the Header info */ + readcount = al_fread(fp, hdrbuf, 0x16); + if (readcount != 0x16 /*shorter header*/ + || !memcmp(hdrbuf, "Creative Voice File\0x1A", 0x14) /*wrong id */ + || !memcmp(hdrbuf+0x15 , "\0x00\0x1A", 0x2)) { /*wrong offset */ + ALLEGRO_ERROR("voc_open: File does not appear to be a valid VOC file"); + return NULL; + } + + al_fread(fp, &vocversion, 2); + if (vocversion != 0x10A && vocversion != 0x114) { // known ver 1.10 -1.20 + ALLEGRO_ERROR("voc_open: File is of unknown version"); + return NULL; + } + /* checksum version check */ + al_fread(fp, &checkver, 2); + if (checkver != ~vocversion + 0x1234) { + ALLEGRO_ERROR("voc_open: Bad VOC Version Identification Number"); + return NULL; + } + /* + * We're at the first datablock, we shall check type and set all the relevant + * info in the vocdata structure, including finally the datapos index to the + * first valid data byte. + */ + READNBYTES(fp, blocktype, 1, NULL); + READNBYTES(fp, blocklength, 2, NULL); + READNBYTES(fp, x, 1, NULL); + blocklength += x<<16; + switch (blocktype) { + case 1: + /* blocktype 1 is the most basic header with 1byte format, time + * constant and length equal to (datalength + 2). + */ + blocklength -= 2; + READNBYTES(fp, timeconstant, 1, NULL); + READNBYTES(fp, format, 1, NULL); + vocdata->bits = 8; /* only possible codec for Blocktype 1 */ + vocdata->channels = 1; /* block 1 alone means MONO */ + vocdata->samplerate = 1000000 / (256 - timeconstant); + vocdata->sample_size = 1; /* or better: 1 * 8 / 8 */ + /* + * Expected number of samples is at LEAST what is in this block. + * IIF lentgh 0xFFF there will be a following blocktype 2. + * We will deal with this later in load_voc. + */ + vocdata->samples = blocklength / vocdata->sample_size; + vocdata->datapos = al_ftell(fp); + break; + case 8: + /* Blocktype 8 is enhanced data block (mainly for Stereo samples I + * guess) that precedes a Blocktype 1, of which the sound infor have + * to be ignored. + * We skip to the end of the following Blocktype 1 once we get all the + * required header info. + */ + if (blocklength != 4) { + ALLEGRO_ERROR("voc_open: Got opening Blocktype 8 of wrong length"); + return NULL; + } + READNBYTES(fp, timeconstant, 2, NULL); + READNBYTES(fp, format, 1, NULL); + READNBYTES(fp, vocdata->channels, 1, NULL); + vocdata->channels += 1; /* was 0 for mono, 1 for stereo */ + vocdata->bits = 8; /* only possible codec for Blocktype 8 */ + vocdata->samplerate = 1000000 / (256 - timeconstant); + vocdata->samplerate /= vocdata->channels; + vocdata->sample_size = vocdata->channels * vocdata->bits / 8; + /* + * Now following there is a blocktype 1 which tells us the length of + * the data block and all other info are discarded. + */ + READNBYTES(fp, blocktype, 1, NULL); + if (blocktype != 1) { + ALLEGRO_ERROR("voc_open: Blocktype following type 8 is not 1"); + return NULL; + } + READNBYTES(fp, blocklength, 2, NULL); + READNBYTES(fp, x, 1, NULL); + blocklength += x<<16; + blocklength -= 2; + READNBYTES(fp, x, 2, NULL); + vocdata->samples = blocklength / vocdata->sample_size; + vocdata->datapos = al_ftell(fp); + break; + case 9: + /* + * Blocktype 9 is available only for VOC version 1.20 and above. + * Deals with 16-bit codecs and stereo and is richier than blocktype 1 + * or the BLocktype 8+1 combo + * Length is 12 bytes more than actual data. + */ + blocklength -= 12; + READNBYTES(fp, vocdata->samplerate, 4, NULL); // actual samplerate + READNBYTES(fp, vocdata->bits, 1, NULL); // actual bits + // after compression + READNBYTES(fp, vocdata->channels, 1, NULL); // actual channels + READNBYTES(fp, format, 2, NULL); + if ((vocdata->bits != 8 && vocdata->bits != 16) || + (format != 0 && format != 4)) { + ALLEGRO_ERROR("voc_open: unsupported CODEC in voc data"); + return NULL; + } + READNBYTES(fp, x, 4, NULL); // just skip 4 reserved bytes + vocdata->datapos = al_ftell(fp); + break; + case 2: // + case 3: // these cases are just + case 4: // ignored in this span + case 5: // and wll not return a + case 6: // valid VOC data. + case 7: // + default: + ALLEGRO_ERROR("voc_open: opening Block is of unsupported type"); + return NULL; + break; + } + return vocdata; +} + +static void voc_close(AL_VOC_DATA *vocdata) +{ + ASSERT(vocdata); + + al_free(vocdata); +} + + +ALLEGRO_SAMPLE *_al_load_voc(const char *filename) +{ + ALLEGRO_FILE *f; + ALLEGRO_SAMPLE *spl; + ASSERT(filename); + + ALLEGRO_INFO("Loading VOC sample %s.\n", filename); + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + spl = _al_load_voc_f(f); + + al_fclose(f); + + return spl; +} + + +ALLEGRO_SAMPLE *_al_load_voc_f(ALLEGRO_FILE *file) +{ + AL_VOC_DATA *vocdata; + ALLEGRO_SAMPLE *sample = NULL; + size_t pos = 0; /* where to write in the buffer */ + size_t read = 0; /*bytes read during last operation */ + char* buffer; + + size_t bytestoread = 0; + bool endofvoc = false; + + vocdata = al_malloc(sizeof(AL_VOC_DATA)); + memset(vocdata, 0, sizeof(*vocdata)); + /* + * Open file and populate VOC DATA, then create a buffer for the number of + * samples of the frst block. + * Iterate on the following blocks till EOF or terminator block + */ + vocdata = voc_open(file); + if (!vocdata) return NULL; + + ALLEGRO_DEBUG("channels %d\n", vocdata->channels); + ALLEGRO_DEBUG("word_size %d\n", vocdata->sample_size); + ALLEGRO_DEBUG("rate %d\n", vocdata->samplerate); + ALLEGRO_DEBUG("first_block_samples %d\n", vocdata->samples); + ALLEGRO_DEBUG("first_block_size %d\n", vocdata->samples * vocdata->sample_size); + + /* + * Let's allocate at least the first block's bytes; + */ + buffer = al_malloc(vocdata->samples * vocdata->sample_size); + if (!buffer) { + return NULL; + } + /* + * We now need to iterate over data blocks till either we hit end of file + * or we find a terminator block. + */ + bytestoread = vocdata->samples * vocdata->sample_size; + while(!endofvoc && !al_feof(vocdata->file)) { + uint32_t blocktype = 0; + uint32_t x = 0, len = 0; + read = al_fread(vocdata->file, buffer, bytestoread); + pos += read; + READNBYTES(vocdata->file, blocktype, 1, NULL); // read next block type + if (al_feof(vocdata->file)) break; + switch (blocktype) { + case 0:{ /* we found a terminator block */ + endofvoc = true; + break; + } + case 2:{ /*we found a continuation block: unlikely but handled */ + x = 0; + bytestoread = 0; + READNBYTES(vocdata->file, bytestoread, 2, NULL); + READNBYTES(vocdata->file, x, 1, NULL); + bytestoread += x<<16; + /* increase subsequently storage */ + buffer = al_realloc(buffer, sizeof(buffer) + bytestoread); + break; + } + case 1: // we found a NEW data block starter, I assume this is wrong + case 8: // and let the so far read sample data correctly in the + case 9:{ // already allocated buffer. + endofvoc = true; + break; + } + case 3: /* we found a pause block */ + case 4: /* we found a marker block */ + case 5: /* we found an ASCII c-string block */ + case 6: /* we found a repeat block */ + case 7:{ /* we found an end repeat block */ + /* all these blocks will be skipped */ + unsigned int ii; + len = 0; + x = 0; + READNBYTES(vocdata->file, len, 2, NULL); + READNBYTES(vocdata->file, x, 1, NULL); + len += x<<16; // this is the length what's left to skip */ + for (ii = 0; ii < len ; ++ii) { + al_fgetc(vocdata->file); + } + bytestoread = 0; //should let safely check for the next block */ + break; + } + default: + break; + } + } + + sample = al_create_sample(buffer, pos, vocdata->samplerate, + _al_word_size_to_depth_conf(vocdata->sample_size), + _al_count_to_channel_conf(vocdata->channels), + true); + if (!sample) + al_free(buffer); + + voc_close(vocdata); + + return sample; +} + +/* + * So far a stream implementation is not provided, since it is deemed unlikely + * that this format will ever be used as such. + */ + diff --git a/allegro/addons/acodec/wav.c b/allegro/addons/acodec/wav.c new file mode 100644 index 00000000..8c7ff994 --- /dev/null +++ b/allegro/addons/acodec/wav.c @@ -0,0 +1,530 @@ +/* + * Allegro5 WAV reader + * author: Matthew Leverton + */ + +#include <stdio.h> + +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_audio.h" +#include "acodec.h" +#include "helper.h" + +ALLEGRO_DEBUG_CHANNEL("wav") + + +typedef struct WAVFILE +{ + ALLEGRO_FILE *f; + size_t dpos; /* the starting position of the data chunk */ + int freq; /* e.g., 44100 */ + short bits; /* 8 (unsigned char) or 16 (signed short) */ + short channels; /* 1 (mono) or 2 (stereo) */ + int sample_size; /* channels * bits/8 */ + int samples; /* # of samples. size = samples * sample_size */ + double loop_start; + double loop_end; +} WAVFILE; + + +/* wav_open: + * Opens f and prepares a WAVFILE struct with the WAV format info. + * On a successful return, the ALLEGRO_FILE is at the beginning of the sample data. + * returns the WAVFILE on success, or NULL on failure. + */ +static WAVFILE *wav_open(ALLEGRO_FILE *f) +{ + WAVFILE *wavfile = NULL; + char buffer[12]; + + if (!f) + goto wav_open_error; + + /* prepare default values */ + wavfile = al_malloc(sizeof(WAVFILE)); + if (!wavfile) { + ALLEGRO_ERROR("Failed to allocate WAVFILE.\n"); + return NULL; + } + wavfile->f = f; + wavfile->freq = 22050; + wavfile->bits = 8; + wavfile->channels = 1; + + /* check the header */ + if (al_fread(f, buffer, 12) != 12) { + ALLEGRO_ERROR("Unexpected EOF while reading the header.\n"); + goto wav_open_error; + } + + if (memcmp(buffer, "RIFF", 4) || memcmp(buffer+8, "WAVE", 4)) { + ALLEGRO_ERROR("Bad magic number.\n"); + goto wav_open_error; + } + + /* Read as many leading fmt chunks as exist, then read until a data chunk + * is found. + */ + while (true) { + int length = 0; + short pcm = 0; + + if (al_fread(f, buffer, 4) != 4) { + ALLEGRO_ERROR("Unexpected EOF while reading RIFF type.\n"); + goto wav_open_error; + } + + /* check to see if it's a fmt chunk */ + if (!memcmp(buffer, "fmt ", 4)) { + + length = al_fread32le(f); + if (length < 16) { + ALLEGRO_ERROR("Bad length: %d.\n", length); + goto wav_open_error; + } + + /* should be 1 for PCM data */ + pcm = al_fread16le(f); + if (pcm != 1) { + ALLEGRO_ERROR("Bad PCM value: %d.\n", pcm); + goto wav_open_error; + } + + /* mono or stereo data */ + wavfile->channels = al_fread16le(f); + + if ((wavfile->channels != 1) && (wavfile->channels != 2)) { + ALLEGRO_ERROR("Bad number of channels: %d.\n", wavfile->channels); + goto wav_open_error; + } + + /* sample frequency */ + wavfile->freq = al_fread32le(f); + + /* skip six bytes */ + al_fseek(f, 6, ALLEGRO_SEEK_CUR); + + /* 8 or 16 bit data? */ + wavfile->bits = al_fread16le(f); + if ((wavfile->bits != 8) && (wavfile->bits != 16)) { + ALLEGRO_ERROR("Bad number of bits: %d.\n", wavfile->bits); + goto wav_open_error; + } + + /* Skip remainder of chunk */ + length -= 16; + if (length > 0) + al_fseek(f, length, ALLEGRO_SEEK_CUR); + } + else { + if (!memcmp(buffer, "data", 4)) { + ALLEGRO_ERROR("Bad RIFF type.\n"); + break; + } + ALLEGRO_INFO("Ignoring chunk: %c%c%c%c\n", buffer[0], buffer[1], + buffer[2], buffer[3]); + length = al_fread32le(f); + al_fseek(f, length, ALLEGRO_SEEK_CUR); + } + } + + /* find out how many samples exist */ + wavfile->samples = al_fread32le(f); + + if (wavfile->channels == 2) { + wavfile->samples = (wavfile->samples + 1) / 2; + } + + if (wavfile->bits == 16) { + wavfile->samples /= 2; + } + + wavfile->sample_size = wavfile->channels * wavfile->bits / 8; + + wavfile->dpos = al_ftell(f); + + return wavfile; + +wav_open_error: + + if (wavfile) + al_free(wavfile); + + return NULL; +} + +/* wav_read: + * Reads up to 'samples' number of samples from the wav ALLEGRO_FILE into 'data'. + * Returns the actual number of samples written to 'data'. + */ +static size_t wav_read(WAVFILE *wavfile, void *data, size_t samples) +{ + size_t bytes_read; + size_t cur_samples; + + ASSERT(wavfile); + + cur_samples = (al_ftell(wavfile->f) - wavfile->dpos) / wavfile->sample_size; + if (cur_samples + samples > (size_t)wavfile->samples) + samples = wavfile->samples - cur_samples; + + bytes_read = al_fread(wavfile->f, data, samples * wavfile->sample_size); + + /* PCM data in RIFF WAV files is little endian. + * PCM data in RIFX WAV files is big endian (which we don't support). + */ +#ifdef ALLEGRO_BIG_ENDIAN + if (wavfile->bits == 16) { + uint16_t *p = data; + const uint16_t *const end = p + (bytes_read >> 1); + + /* swap high/low bytes */ + while (p < end) { + *p = ((*p << 8) | (*p >> 8)); + p++; + } + } +#endif + + return bytes_read / wavfile->sample_size; +} + + +/* wav_close: + * Closes the ALLEGRO_FILE and frees the WAVFILE struct. + */ +static void wav_close(WAVFILE *wavfile) +{ + ASSERT(wavfile); + + al_free(wavfile); +} + + +static bool wav_stream_seek(ALLEGRO_AUDIO_STREAM * stream, double time) +{ + WAVFILE *wavfile = (WAVFILE *) stream->extra; + int align = (wavfile->bits / 8) * wavfile->channels; + unsigned long cpos = time * (double)(wavfile->freq * (wavfile->bits / 8) * wavfile->channels); + if (time >= wavfile->loop_end) + return false; + cpos += cpos % align; + return al_fseek(wavfile->f, wavfile->dpos + cpos, ALLEGRO_SEEK_SET); +} + + +/* wav_stream_rewind: + * Rewinds 'stream' to the beginning of the data chunk. + * Returns true on success, false on failure. + */ +static bool wav_stream_rewind(ALLEGRO_AUDIO_STREAM *stream) +{ + WAVFILE *wavfile = (WAVFILE *) stream->extra; + return wav_stream_seek(stream, wavfile->loop_start); +} + + +static double wav_stream_get_position(ALLEGRO_AUDIO_STREAM * stream) +{ + WAVFILE *wavfile = (WAVFILE *) stream->extra; + double samples_per = (double)((wavfile->bits / 8) * wavfile->channels) * (double)(wavfile->freq); + return ((double)(al_ftell(wavfile->f) - wavfile->dpos) / samples_per); +} + + +static double wav_stream_get_length(ALLEGRO_AUDIO_STREAM * stream) +{ + WAVFILE *wavfile = (WAVFILE *) stream->extra; + double total_time = (double)(wavfile->samples) / (double)(wavfile->freq); + return total_time; +} + + +static bool wav_stream_set_loop(ALLEGRO_AUDIO_STREAM * stream, double start, double end) +{ + WAVFILE *wavfile = (WAVFILE *) stream->extra; + wavfile->loop_start = start; + wavfile->loop_end = end; + return true; +} + + +/* wav_stream_update: + * Updates 'stream' with the next chunk of data. + * Returns the actual number of bytes written. + */ +static size_t wav_stream_update(ALLEGRO_AUDIO_STREAM *stream, void *data, + size_t buf_size) +{ + int bytes_per_sample, samples, samples_read; + double ctime, btime; + + WAVFILE *wavfile = (WAVFILE *) stream->extra; + bytes_per_sample = (wavfile->bits / 8) * wavfile->channels; + ctime = wav_stream_get_position(stream); + btime = ((double)buf_size / (double)bytes_per_sample) / (double)(wavfile->freq); + + if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR && ctime + btime > wavfile->loop_end) { + samples = ((wavfile->loop_end - ctime) * (double)(wavfile->freq)); + } + else { + samples = buf_size / bytes_per_sample; + } + if (samples < 0) + return 0; + + samples_read = wav_read(wavfile, data, samples); + + return samples_read * bytes_per_sample; +} + + +/* wav_stream_close: + * Closes the 'stream'. + */ +static void wav_stream_close(ALLEGRO_AUDIO_STREAM *stream) +{ + WAVFILE *wavfile = (WAVFILE *) stream->extra; + + _al_acodec_stop_feed_thread(stream); + + al_fclose(wavfile->f); + wav_close(wavfile); + stream->extra = NULL; + stream->feed_thread = NULL; +} + + +/* _al_load_wav: + * Reads a RIFF WAV format sample ALLEGRO_FILE, returning an ALLEGRO_SAMPLE + * structure, or NULL on error. + */ +ALLEGRO_SAMPLE *_al_load_wav(const char *filename) +{ + ALLEGRO_FILE *f; + ALLEGRO_SAMPLE *spl; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + spl = _al_load_wav_f(f); + + al_fclose(f); + + return spl; +} + +ALLEGRO_SAMPLE *_al_load_wav_f(ALLEGRO_FILE *fp) +{ + WAVFILE *wavfile = wav_open(fp); + ALLEGRO_SAMPLE *spl = NULL; + + if (wavfile) { + size_t n = (wavfile->bits / 8) * wavfile->channels * wavfile->samples; + char *data = al_malloc(n); + + if (data) { + spl = al_create_sample(data, wavfile->samples, wavfile->freq, + _al_word_size_to_depth_conf(wavfile->bits / 8), + _al_count_to_channel_conf(wavfile->channels), true); + + if (spl) { + memset(data, 0, n); + wav_read(wavfile, data, wavfile->samples); + } + else { + al_free(data); + } + } + wav_close(wavfile); + } + + return spl; +} + + +/* _al_load_wav_audio_stream: +*/ +ALLEGRO_AUDIO_STREAM *_al_load_wav_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + ALLEGRO_FILE *f; + ALLEGRO_AUDIO_STREAM *stream; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + stream = _al_load_wav_audio_stream_f(f, buffer_count, samples); + if (!stream) { + ALLEGRO_ERROR("Failed to load wav stream.\n"); + al_fclose(f); + } + + return stream; +} + +/* _al_load_wav_audio_stream_f: +*/ +ALLEGRO_AUDIO_STREAM *_al_load_wav_audio_stream_f(ALLEGRO_FILE* f, + size_t buffer_count, unsigned int samples) +{ + WAVFILE* wavfile; + ALLEGRO_AUDIO_STREAM* stream; + + wavfile = wav_open(f); + + if (wavfile == NULL) { + ALLEGRO_ERROR("Failed to load wav file.\n"); + return NULL; + } + + stream = al_create_audio_stream(buffer_count, samples, wavfile->freq, + _al_word_size_to_depth_conf(wavfile->bits / 8), + _al_count_to_channel_conf(wavfile->channels)); + + if (stream) { + stream->extra = wavfile; + wavfile->loop_start = 0.0; + wavfile->loop_end = wav_stream_get_length(stream); + stream->feeder = wav_stream_update; + stream->unload_feeder = wav_stream_close; + stream->rewind_feeder = wav_stream_rewind; + stream->seek_feeder = wav_stream_seek; + stream->get_feeder_position = wav_stream_get_position; + stream->get_feeder_length = wav_stream_get_length; + stream->set_feeder_loop = wav_stream_set_loop; + _al_acodec_start_feed_thread(stream); + } + else { + ALLEGRO_ERROR("Failed to load wav stream.\n"); + wav_close(wavfile); + } + + return stream; +} + + +/* _al_save_wav: + * Writes a sample into a wav ALLEGRO_FILE. + * Returns true on success, false on error. + */ +bool _al_save_wav(const char *filename, ALLEGRO_SAMPLE *spl) +{ + ALLEGRO_FILE *pf = al_fopen(filename, "wb"); + + if (pf) { + bool rvsave = _al_save_wav_f(pf, spl); + bool rvclose = al_fclose(pf); + return rvsave && rvclose; + } + else { + ALLEGRO_ERROR("Unable to open %s for writing.\n", filename); + } + + return false; +} + + +/* _al_save_wav_f: + * Writes a sample into a wav packfile. + * Returns true on success, false on error. + */ +bool _al_save_wav_f(ALLEGRO_FILE *pf, ALLEGRO_SAMPLE *spl) +{ + size_t channels, bits; + size_t data_size; + size_t samples; + size_t i, n; + + ASSERT(spl); + ASSERT(pf); + + /* XXX: makes use of ALLEGRO_SAMPLE internals */ + + channels = (spl->chan_conf >> 4) + (spl->chan_conf & 0xF); + bits = (spl->depth == ALLEGRO_AUDIO_DEPTH_INT8 || + spl->depth == ALLEGRO_AUDIO_DEPTH_UINT8) ? 8 : 16; + + if (channels < 1 || channels > 2) { + ALLEGRO_ERROR("Can only save samples with 1 or 2 channels as WAV.\n"); + return false; + } + + samples = spl->len; + data_size = samples * channels * bits / 8; + n = samples * channels; + + al_fputs(pf, "RIFF"); + al_fwrite32le(pf, 36 + data_size); + al_fputs(pf, "WAVE"); + + al_fputs(pf, "fmt "); + al_fwrite32le(pf, 16); + al_fwrite16le(pf, 1); + al_fwrite16le(pf, (int16_t)channels); + al_fwrite32le(pf, spl->frequency); + al_fwrite32le(pf, spl->frequency * channels * bits / 8); + al_fwrite16le(pf, (int16_t)(channels * bits / 8)); + al_fwrite16le(pf, (int16_t)bits); + + al_fputs(pf, "data"); + al_fwrite32le(pf, data_size); + + + if (spl->depth == ALLEGRO_AUDIO_DEPTH_UINT8) { + al_fwrite(pf, spl->buffer.u8, samples * channels); + } + else if (spl->depth == ALLEGRO_AUDIO_DEPTH_INT16) { + al_fwrite(pf, spl->buffer.s16, samples * channels * 2); + } + else if (spl->depth == ALLEGRO_AUDIO_DEPTH_INT8) { + int8_t *data = spl->buffer.s8; + for (i = 0; i < samples; ++i) { + al_fputc(pf, *data++ + 0x80); + } + } + else if (spl->depth == ALLEGRO_AUDIO_DEPTH_UINT16) { + uint16_t *data = spl->buffer.u16; + for (i = 0; i < n; ++i) { + al_fwrite16le(pf, *data++ - 0x8000); + } + } + else if (spl->depth == ALLEGRO_AUDIO_DEPTH_INT24) { + int32_t *data = spl->buffer.s24; + for (i = 0; i < n; ++i) { + const int v = ((float)(*data++ + 0x800000) / 0x7FFFFF) * 0x7FFF - 0x8000; + al_fwrite16le(pf, v); + } + } + else if (spl->depth == ALLEGRO_AUDIO_DEPTH_UINT24) { + uint32_t *data = spl->buffer.u24; + for (i = 0; i < n; ++i) { + const int v = ((float)(*data++) / 0x7FFFFF) * 0x7FFF - 0x8000; + al_fwrite16le(pf, v); + } + } + else if (spl->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) { + float *data = spl->buffer.f32; + for (i = 0; i < n; ++i) { + al_fwrite16le(pf, *data * 0x7FFF); + data++; + } + } + else { + ALLEGRO_ERROR("Unknown audio depth (%d) when saving wav ALLEGRO_FILE.\n", + spl->depth); + return false; + } + + return true; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/CMakeLists.txt b/allegro/addons/audio/CMakeLists.txt new file mode 100644 index 00000000..ca3ab15e --- /dev/null +++ b/allegro/addons/audio/CMakeLists.txt @@ -0,0 +1,191 @@ +option(WANT_ALSA "Enable ALSA digital audio driver (Unix)" on) +option(WANT_OSS "Enable OSS digital audio driver (Unix)" on) +option(WANT_PULSEAUDIO "Enable PulseAudio audio driver (Unix)" on) +option(WANT_OPENAL "Enable OpenAL digital audio driver" on) +option(WANT_OPENSL "Enable OpenSL digital audio driver (Android)" on) +option(WANT_DSOUND "Enable DSound digital audio driver (Windows)" on) +option(WANT_AQUEUE "Enable AudioQueue digital audio driver (Mac)" on) + +set(AUDIO_SOURCES + audio.c + audio_io.c + kcm_dtor.c + kcm_instance.c + kcm_mixer.c + kcm_sample.c + kcm_stream.c + kcm_voice.c + recorder.c + ) + +set(AUDIO_INCLUDE_FILES allegro5/allegro_audio.h) + +set_our_header_properties(${AUDIO_INCLUDE_FILES}) + +# The platform conditions are not really necessary but prevent confusing the +# user, e.g. it's pretty weird to get a warning about missing DSound on Unix. + +if(WANT_OSS AND ALLEGRO_UNIX) + include(AllegroFindOSS) + if(OSS_FOUND) + set(SUPPORT_OSS 1) + endif(OSS_FOUND) +endif(WANT_OSS AND ALLEGRO_UNIX) + +if(SUPPORT_OSS) + set(ALLEGRO_CFG_KCM_OSS 1) + list(APPEND AUDIO_SOURCES oss.c) + set(SUPPORT_AUDIO 1) +endif(SUPPORT_OSS) + +if(WANT_PULSEAUDIO AND ALLEGRO_UNIX) + pkg_check_modules(PULSEAUDIO libpulse-simple) + if(PULSEAUDIO_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${PULSEAUDIO_INCLUDE_DIRS}) + run_c_compile_test(" + #include <pulse/simple.h> + #include <pulse/error.h> + #include <pulse/introspect.h> + #include <pulse/mainloop.h> + int main(void) + { + /* Require pulseaudio 0.9.15 */ + pa_context *c; + pa_sink_info *si; + pa_sink_state_t *ss; + return 0; + }" + PULSEAUDIO_COMPILES) + set(CMAKE_REQUIRED_INCLUDES) + set(SUPPORT_PULSEAUDIO ${PULSEAUDIO_COMPILES}) + if(NOT SUPPORT_PULSEAUDIO) + message("WARNING: PulseAudio compile test failed, disabling support") + endif() + endif(PULSEAUDIO_FOUND) +endif(WANT_PULSEAUDIO AND ALLEGRO_UNIX) + +if(SUPPORT_PULSEAUDIO) + set(ALLEGRO_CFG_KCM_PULSEAUDIO 1) + list(APPEND AUDIO_SOURCES pulseaudio.c) + list(APPEND AUDIO_LIBRARIES ${PULSEAUDIO_LIBRARIES}) + list(APPEND AUDIO_INCLUDE_DIRECTORIES ${PULSEAUDIO_INCLUDE_DIRS}) + list(APPEND AUDIO_LINK_DIRECTORIES ${PULSEAUDIO_LIBRARY_DIRS}) + set(SUPPORT_AUDIO 1) +endif(SUPPORT_PULSEAUDIO) + +if(WANT_ALSA AND ALLEGRO_UNIX) + pkg_check_modules(ALSA alsa) + if(ALSA_FOUND) + set(SUPPORT_ALSA 1) + endif(ALSA_FOUND) +endif(WANT_ALSA AND ALLEGRO_UNIX) + +if(SUPPORT_ALSA) + set(ALLEGRO_CFG_KCM_ALSA 1) + list(APPEND AUDIO_SOURCES alsa.c) + list(APPEND AUDIO_LIBRARIES ${ALSA_LIBRARIES}) + list(APPEND AUDIO_INCLUDE_DIRECTORIES ${ALSA_INCLUDE_DIRS}) + set(SUPPORT_AUDIO 1) +endif(SUPPORT_ALSA) + +if(WANT_DSOUND AND WIN32) + find_package(DirectX) + if(DSOUND_FOUND) + set(SUPPORT_DSOUND 1) + endif(DSOUND_FOUND) +endif(WANT_DSOUND AND WIN32) + +if(SUPPORT_DSOUND) + set(ALLEGRO_CFG_KCM_DSOUND 1) + list(APPEND AUDIO_SOURCES dsound.cpp) + list(APPEND AUDIO_LIBRARIES ${DSOUND_LIBRARIES}) + list(APPEND AUDIO_INCLUDE_DIRECTORIES ${DSOUND_INCLUDE_DIR}) + set(SUPPORT_AUDIO 1) +endif(SUPPORT_DSOUND) + +if(WANT_AQUEUE AND MACOSX) + # Should check the presence just to be sure. + find_library(AUDIO_TOOLBOX_LIB NAMES AudioToolbox) + if(AUDIO_TOOLBOX_LIB) + find_path(AQUEUE_INCLUDE_DIR AudioToolbox/AudioQueue.h) + if(AQUEUE_INCLUDE_DIR) + set(SUPPORT_AQUEUE 1) + endif(AQUEUE_INCLUDE_DIR) + endif(AUDIO_TOOLBOX_LIB) + + if(NOT SUPPORT_AQUEUE) + message("WARNING: could not find AudioQueue. (This is normal on OS X 10.4)") + endif(NOT SUPPORT_AQUEUE) +endif(WANT_AQUEUE AND MACOSX) + +if(SUPPORT_AQUEUE) + set(ALLEGRO_CFG_KCM_AQUEUE 1) + list(APPEND AUDIO_SOURCES aqueue.m) + list(APPEND AUDIO_LIBRARIES ${AUDIO_TOOLBOX_LIB}) + set(SUPPORT_AUDIO 1) +endif(SUPPORT_AQUEUE) + +if(WANT_OPENAL) + find_package(OpenAL) + mark_as_advanced(OPENAL_INCLUDE_DIR OPENAL_LIBRARY) + if(OPENAL_FOUND) + set(SUPPORT_OPENAL 1) + endif(OPENAL_FOUND) +endif(WANT_OPENAL) + +if(SUPPORT_OPENAL) + set(ALLEGRO_CFG_KCM_OPENAL 1) + list(APPEND AUDIO_SOURCES openal.c) + list(APPEND AUDIO_LIBRARIES ${OPENAL_LIBRARY}) + list(APPEND AUDIO_INCLUDE_DIRECTORIES ${OPENAL_INCLUDE_DIR}) + set(SUPPORT_AUDIO 1) +endif(SUPPORT_OPENAL) + +if(WANT_OPENSL) + find_package(OpenSL) + if(OPENSL_FOUND) + set(SUPPORT_OPENSL 1) + endif(OPENSL_FOUND) +endif(WANT_OPENSL) + +if(SUPPORT_OPENSL) + set(ALLEGRO_CFG_KCM_OPENSL 1) + list(APPEND AUDIO_SOURCES opensl.c) + list(APPEND AUDIO_LIBRARIES ${OPENSL_LIBRARY}) + list(APPEND AUDIO_INCLUDE_DIRECTORIES ${OPENSL_INCLUDE_DIR}) + set(SUPPORT_AUDIO 1) +endif(SUPPORT_OPENSL) + +if(ALLEGRO_SDL) + set(ALLEGRO_CFG_KCM_SDL 1) + list(APPEND AUDIO_SOURCES sdl_audio.c) + list(APPEND AUDIO_LIBRARIES ${SDL2_LIBRARIES} ) + list(APPEND AUDIO_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR}) + set(SUPPORT_AUDIO 1) +endif(ALLEGRO_SDL) + +configure_file( + allegro5/internal/aintern_audio_cfg.h.cmake + ${PROJECT_BINARY_DIR}/include/allegro5/internal/aintern_audio_cfg.h + ) + +if(NOT SUPPORT_AUDIO) + message("WARNING: allegro_audio wanted but no supported backend found") + return() +endif(NOT SUPPORT_AUDIO) + +include_directories(SYSTEM ${AUDIO_INCLUDE_DIRECTORIES}) +link_directories(${AUDIO_LINK_DIRECTORIES}) +add_our_addon_library(allegro_audio + AllegroAudio-${ALLEGRO_SOVERSION} + "${AUDIO_SOURCES};${AUDIO_INCLUDE_FILES}" + "-DALLEGRO_KCM_AUDIO_SRC" + "${ALLEGRO_LINK_WITH};${AUDIO_LIBRARIES}" + ) + +install_our_headers(${AUDIO_INCLUDE_FILES}) + +add_addon(audio) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/audio/allegro5/allegro_audio.h b/allegro/addons/audio/allegro5/allegro_audio.h new file mode 100644 index 00000000..d57d078e --- /dev/null +++ b/allegro/addons/audio/allegro5/allegro_audio.h @@ -0,0 +1,427 @@ +/* + * Updated for 4.9 api inclusion by Ryan Dickie + * Originally done by KC/Milan + */ + +#ifndef __al_included_allegro5_allegro_audio_h +#define __al_included_allegro5_allegro_audio_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* Title: Audio types + */ + +#include "allegro5/allegro.h" + + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_KCM_AUDIO_SRC + #define _ALLEGRO_KCM_AUDIO_DLL __declspec(dllexport) + #else + #define _ALLEGRO_KCM_AUDIO_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_KCM_AUDIO_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) _ALLEGRO_KCM_AUDIO_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_KCM_AUDIO_FUNC(type, name, args) extern _ALLEGRO_KCM_AUDIO_DLL type name args +#else + #define ALLEGRO_KCM_AUDIO_FUNC AL_FUNC +#endif + +/* Enum: ALLEGRO_AUDIO_EVENT_TYPE + */ +enum ALLEGRO_AUDIO_EVENT_TYPE +{ + /* Internal, used to communicate with acodec. */ + /* Must be in 512 <= n < 1024 */ + _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE = 512, + ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT = 513, + ALLEGRO_EVENT_AUDIO_STREAM_FINISHED = 514, +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_KCM_AUDIO_SRC) + ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT = 515, +#endif +}; + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_KCM_AUDIO_SRC) +/* Type: ALLEGRO_AUDIO_RECORDER_EVENT + */ +typedef struct ALLEGRO_AUDIO_RECORDER_EVENT ALLEGRO_AUDIO_RECORDER_EVENT; +struct ALLEGRO_AUDIO_RECORDER_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_AUDIO_RECORDER) + struct ALLEGRO_USER_EVENT_DESCRIPTOR *__internal__descr; + void *buffer; + unsigned int samples; +}; +#endif + + +/* Enum: ALLEGRO_AUDIO_DEPTH + */ +enum ALLEGRO_AUDIO_DEPTH +{ + /* Sample depth and type, and signedness. Mixers only use 32-bit signed + * float (-1..+1). The unsigned value is a bit-flag applied to the depth + * value. + */ + ALLEGRO_AUDIO_DEPTH_INT8 = 0x00, + ALLEGRO_AUDIO_DEPTH_INT16 = 0x01, + ALLEGRO_AUDIO_DEPTH_INT24 = 0x02, + ALLEGRO_AUDIO_DEPTH_FLOAT32 = 0x03, + + ALLEGRO_AUDIO_DEPTH_UNSIGNED = 0x08, + + /* For convenience */ + ALLEGRO_AUDIO_DEPTH_UINT8 = ALLEGRO_AUDIO_DEPTH_INT8 | + ALLEGRO_AUDIO_DEPTH_UNSIGNED, + ALLEGRO_AUDIO_DEPTH_UINT16 = ALLEGRO_AUDIO_DEPTH_INT16 | + ALLEGRO_AUDIO_DEPTH_UNSIGNED, + ALLEGRO_AUDIO_DEPTH_UINT24 = ALLEGRO_AUDIO_DEPTH_INT24 | + ALLEGRO_AUDIO_DEPTH_UNSIGNED +}; + + +/* Enum: ALLEGRO_CHANNEL_CONF + */ +enum ALLEGRO_CHANNEL_CONF +{ + /* Speaker configuration (mono, stereo, 2.1, 3, etc). With regards to + * behavior, most of this code makes no distinction between, say, 4.1 and + * 5 speaker setups.. they both have 5 "channels". However, users would + * like the distinction, and later when the higher-level stuff is added, + * the differences will become more important. (v>>4)+(v&0xF) should yield + * the total channel count. + */ + ALLEGRO_CHANNEL_CONF_1 = 0x10, + ALLEGRO_CHANNEL_CONF_2 = 0x20, + ALLEGRO_CHANNEL_CONF_3 = 0x30, + ALLEGRO_CHANNEL_CONF_4 = 0x40, + ALLEGRO_CHANNEL_CONF_5_1 = 0x51, + ALLEGRO_CHANNEL_CONF_6_1 = 0x61, + ALLEGRO_CHANNEL_CONF_7_1 = 0x71 +#define ALLEGRO_MAX_CHANNELS 8 +}; + + +/* Enum: ALLEGRO_PLAYMODE + */ +enum ALLEGRO_PLAYMODE +{ + ALLEGRO_PLAYMODE_ONCE = 0x100, + ALLEGRO_PLAYMODE_LOOP = 0x101, + ALLEGRO_PLAYMODE_BIDIR = 0x102, + _ALLEGRO_PLAYMODE_STREAM_ONCE = 0x103, /* internal */ + _ALLEGRO_PLAYMODE_STREAM_ONEDIR = 0x104 /* internal */ +}; + + +/* Enum: ALLEGRO_MIXER_QUALITY + */ +enum ALLEGRO_MIXER_QUALITY +{ + ALLEGRO_MIXER_QUALITY_POINT = 0x110, + ALLEGRO_MIXER_QUALITY_LINEAR = 0x111, + ALLEGRO_MIXER_QUALITY_CUBIC = 0x112 +}; + + +/* Enum: ALLEGRO_AUDIO_PAN_NONE + */ +#define ALLEGRO_AUDIO_PAN_NONE (-1000.0f) + +/* Type: ALLEGRO_SAMPLE + */ +typedef struct ALLEGRO_SAMPLE ALLEGRO_SAMPLE; + + +/* Type: ALLEGRO_SAMPLE_ID + */ +typedef struct ALLEGRO_SAMPLE_ID ALLEGRO_SAMPLE_ID; + +struct ALLEGRO_SAMPLE_ID { + int _index; + int _id; +}; + + +/* Type: ALLEGRO_SAMPLE_INSTANCE + */ +typedef struct ALLEGRO_SAMPLE_INSTANCE ALLEGRO_SAMPLE_INSTANCE; + + +/* Type: ALLEGRO_AUDIO_STREAM + */ +typedef struct ALLEGRO_AUDIO_STREAM ALLEGRO_AUDIO_STREAM; + + +/* Type: ALLEGRO_MIXER + */ +typedef struct ALLEGRO_MIXER ALLEGRO_MIXER; + + +/* Type: ALLEGRO_VOICE + */ +typedef struct ALLEGRO_VOICE ALLEGRO_VOICE; + + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_KCM_AUDIO_SRC) +/* Type: ALLEGRO_AUDIO_RECORDER + */ +typedef struct ALLEGRO_AUDIO_RECORDER ALLEGRO_AUDIO_RECORDER; +#endif + + +#ifndef __cplusplus +typedef enum ALLEGRO_AUDIO_DEPTH ALLEGRO_AUDIO_DEPTH; +typedef enum ALLEGRO_CHANNEL_CONF ALLEGRO_CHANNEL_CONF; +typedef enum ALLEGRO_PLAYMODE ALLEGRO_PLAYMODE; +typedef enum ALLEGRO_MIXER_QUALITY ALLEGRO_MIXER_QUALITY; +#endif + + +/* Sample functions */ + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_create_sample, (void *buf, + unsigned int samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, + ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_sample, (ALLEGRO_SAMPLE *spl)); + + +/* Sample instance functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE_INSTANCE*, al_create_sample_instance, ( + ALLEGRO_SAMPLE *data)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_sample_instance, ( + ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_frequency, (const ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_length, (const ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_sample_depth, (const ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_sample_channels, (const ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(void *, al_get_sample_data, (const ALLEGRO_SAMPLE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_frequency, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_length, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_sample_instance_position, (const ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_speed, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_gain, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_pan, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_sample_instance_time, (const ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_sample_instance_depth, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_sample_instance_channels, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_PLAYMODE, al_get_sample_instance_playmode, (const ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_sample_instance_playing, (const ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_sample_instance_attached, (const ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_position, (ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_length, (ALLEGRO_SAMPLE_INSTANCE *spl, unsigned int val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_speed, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_gain, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_pan, (ALLEGRO_SAMPLE_INSTANCE *spl, float val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_playmode, (ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_PLAYMODE val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_playing, (ALLEGRO_SAMPLE_INSTANCE *spl, bool val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample, (ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_get_sample, (ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_play_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_stop_sample_instance, (ALLEGRO_SAMPLE_INSTANCE *spl)); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_KCM_AUDIO_SRC) +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_sample_instance_channel_matrix, (ALLEGRO_SAMPLE_INSTANCE *spl, const float *matrix)); +#endif + + +/* Stream functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM*, al_create_audio_stream, (size_t buffer_count, + unsigned int samples, unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_drain_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_frequency, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_length, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_audio_stream_fragments, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_available_audio_stream_fragments, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_speed, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_gain, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_audio_stream_pan, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_audio_stream_channels, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_audio_stream_depth, (const ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_PLAYMODE, al_get_audio_stream_playmode, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_audio_stream_playing, (const ALLEGRO_AUDIO_STREAM *spl)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_audio_stream_attached, (const ALLEGRO_AUDIO_STREAM *spl)); +ALLEGRO_KCM_AUDIO_FUNC(uint64_t, al_get_audio_stream_played_samples, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(void *, al_get_audio_stream_fragment, (const ALLEGRO_AUDIO_STREAM *stream)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_speed, (ALLEGRO_AUDIO_STREAM *stream, float val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_gain, (ALLEGRO_AUDIO_STREAM *stream, float val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_pan, (ALLEGRO_AUDIO_STREAM *stream, float val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_playmode, (ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_PLAYMODE val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_playing, (ALLEGRO_AUDIO_STREAM *stream, bool val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_fragment, (ALLEGRO_AUDIO_STREAM *stream, void *val)); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_rewind_audio_stream, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_seek_audio_stream_secs, (ALLEGRO_AUDIO_STREAM *stream, double time)); +ALLEGRO_KCM_AUDIO_FUNC(double, al_get_audio_stream_position_secs, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(double, al_get_audio_stream_length_secs, (ALLEGRO_AUDIO_STREAM *stream)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_loop_secs, (ALLEGRO_AUDIO_STREAM *stream, double start, double end)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_audio_stream_event_source, (ALLEGRO_AUDIO_STREAM *stream)); + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_KCM_AUDIO_SRC) +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_audio_stream_channel_matrix, (ALLEGRO_AUDIO_STREAM *stream, const float *matrix)); +#endif + +/* Mixer functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER*, al_create_mixer, (unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_mixer, (ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_sample_instance_to_mixer, ( + ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_audio_stream_to_mixer, (ALLEGRO_AUDIO_STREAM *stream, + ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_mixer_to_mixer, (ALLEGRO_MIXER *stream, + ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_postprocess_callback, ( + ALLEGRO_MIXER *mixer, + void (*cb)(void *buf, unsigned int samples, void *data), + void *data)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_mixer_frequency, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_mixer_channels, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_mixer_depth, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER_QUALITY, al_get_mixer_quality, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(float, al_get_mixer_gain, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_mixer_playing, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_mixer_attached, (const ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_frequency, (ALLEGRO_MIXER *mixer, unsigned int val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_quality, (ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_gain, (ALLEGRO_MIXER *mixer, float gain)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_playing, (ALLEGRO_MIXER *mixer, bool val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_detach_mixer, (ALLEGRO_MIXER *mixer)); + +/* Voice functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_VOICE*, al_create_voice, (unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, + ALLEGRO_CHANNEL_CONF chan_conf)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_voice, (ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_sample_instance_to_voice, ( + ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_audio_stream_to_voice, ( + ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_VOICE *voice )); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_attach_mixer_to_voice, (ALLEGRO_MIXER *mixer, + ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_detach_voice, (ALLEGRO_VOICE *voice)); + +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_voice_frequency, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(unsigned int, al_get_voice_position, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, al_get_voice_channels, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, al_get_voice_depth, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_get_voice_playing, (const ALLEGRO_VOICE *voice)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_voice_position, (ALLEGRO_VOICE *voice, unsigned int val)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_voice_playing, (ALLEGRO_VOICE *voice, bool val)); + +/* Misc. audio functions */ +ALLEGRO_KCM_AUDIO_FUNC(bool, al_install_audio, (void)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_uninstall_audio, (void)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_is_audio_installed, (void)); +ALLEGRO_KCM_AUDIO_FUNC(uint32_t, al_get_allegro_audio_version, (void)); + +ALLEGRO_KCM_AUDIO_FUNC(size_t, al_get_channel_count, (ALLEGRO_CHANNEL_CONF conf)); +ALLEGRO_KCM_AUDIO_FUNC(size_t, al_get_audio_depth_size, (ALLEGRO_AUDIO_DEPTH conf)); + +ALLEGRO_KCM_AUDIO_FUNC(void, al_fill_silence, (void *buf, unsigned int samples, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); + +/* Simple audio layer */ +ALLEGRO_KCM_AUDIO_FUNC(bool, al_reserve_samples, (int reserve_samples)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_MIXER *, al_get_default_mixer, (void)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_default_mixer, (ALLEGRO_MIXER *mixer)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_restore_default_mixer, (void)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_play_sample, (ALLEGRO_SAMPLE *data, + float gain, float pan, float speed, ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_stop_sample, (ALLEGRO_SAMPLE_ID *spl_id)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_stop_samples, (void)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_VOICE *, al_get_default_voice, (void)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_set_default_voice, (ALLEGRO_VOICE *voice)); + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_KCM_AUDIO_SRC) +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE_INSTANCE*, al_lock_sample_id, (ALLEGRO_SAMPLE_ID *spl_id)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_unlock_sample_id, (ALLEGRO_SAMPLE_ID *spl_id)); +#endif + +/* File type handlers */ +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_loader, (const char *ext, + ALLEGRO_SAMPLE *(*loader)(const char *filename))); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_saver, (const char *ext, + bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl))); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_audio_stream_loader, (const char *ext, + ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename, + size_t buffer_count, unsigned int samples))); + +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_loader_f, (const char *ext, + ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE *fp))); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_saver_f, (const char *ext, + bool (*saver)(ALLEGRO_FILE *fp, ALLEGRO_SAMPLE *spl))); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_audio_stream_loader_f, (const char *ext, + ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE *fp, + size_t buffer_count, unsigned int samples))); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_load_sample, (const char *filename)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_save_sample, (const char *filename, + ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM *, al_load_audio_stream, (const char *filename, + size_t buffer_count, unsigned int samples)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE *, al_load_sample_f, (ALLEGRO_FILE* fp, const char *ident)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_save_sample_f, (ALLEGRO_FILE* fp, const char *ident, + ALLEGRO_SAMPLE *spl)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_STREAM *, al_load_audio_stream_f, (ALLEGRO_FILE* fp, const char *ident, + size_t buffer_count, unsigned int samples)); + + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_KCM_AUDIO_SRC) + +/* Recording functions */ +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_RECORDER *, al_create_audio_recorder, (size_t fragment_count, + unsigned int samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_start_audio_recorder, (ALLEGRO_AUDIO_RECORDER *r)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_stop_audio_recorder, (ALLEGRO_AUDIO_RECORDER *r)); +ALLEGRO_KCM_AUDIO_FUNC(bool, al_is_audio_recorder_recording, (ALLEGRO_AUDIO_RECORDER *r)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_audio_recorder_event_source, + (ALLEGRO_AUDIO_RECORDER *r)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_RECORDER_EVENT *, al_get_audio_recorder_event, (ALLEGRO_EVENT *event)); +ALLEGRO_KCM_AUDIO_FUNC(void, al_destroy_audio_recorder, (ALLEGRO_AUDIO_RECORDER *r)); + +#endif + +#ifdef __cplusplus +} /* End extern "C" */ +#endif + +#endif + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/allegro5/internal/aintern_audio.h b/allegro/addons/audio/allegro5/internal/aintern_audio.h new file mode 100644 index 00000000..935c92bb --- /dev/null +++ b/allegro/addons/audio/allegro5/internal/aintern_audio.h @@ -0,0 +1,389 @@ +/* internal-only header + * Updated for 4.9 api inclusion by Ryan Dickie + * Originally done by KC/Milan + */ +#ifndef AINTERN_AUDIO_H +#define AINTERN_AUDIO_H + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_list.h" +#include "allegro5/internal/aintern_vector.h" +#include "../allegro_audio.h" + +struct ALLEGRO_AUDIO_RECORDER { + ALLEGRO_EVENT_SOURCE source; + + ALLEGRO_THREAD *thread; + ALLEGRO_MUTEX *mutex; + ALLEGRO_COND *cond; + /* recording is done in its own thread as + implemented by the driver */ + + ALLEGRO_AUDIO_DEPTH depth; + ALLEGRO_CHANNEL_CONF chan_conf; + unsigned int frequency; + + void **fragments; + /* the buffers to record into */ + + unsigned int fragment_count; + /* the number of fragments */ + + unsigned int samples; + /* the number of samples returned at every FRAGMENT event */ + + size_t fragment_size; + /* size in bytes of each fragument */ + + unsigned int sample_size; + /* the size in bytes of each sample */ + + volatile bool is_recording; + /* true if the driver should actively be updating + the buffer */ + + void *extra; + /* custom data for the driver to use as needed */ +}; + +typedef enum ALLEGRO_AUDIO_DRIVER_ENUM +{ + /* Various driver modes. */ + ALLEGRO_AUDIO_DRIVER_AUTODETECT = 0x20000, + ALLEGRO_AUDIO_DRIVER_OPENAL = 0x20001, + ALLEGRO_AUDIO_DRIVER_ALSA = 0x20002, + ALLEGRO_AUDIO_DRIVER_DSOUND = 0x20003, + ALLEGRO_AUDIO_DRIVER_OSS = 0x20004, + ALLEGRO_AUDIO_DRIVER_AQUEUE = 0x20005, + ALLEGRO_AUDIO_DRIVER_PULSEAUDIO = 0x20006, + ALLEGRO_AUDIO_DRIVER_OPENSL = 0x20007, + ALLEGRO_AUDIO_DRIVER_SDL = 0x20008 +} ALLEGRO_AUDIO_DRIVER_ENUM; + +typedef struct ALLEGRO_AUDIO_DRIVER ALLEGRO_AUDIO_DRIVER; +struct ALLEGRO_AUDIO_DRIVER { + const char *specifier; + + int (*open)(void); + void (*close)(void); + + int (*allocate_voice)(ALLEGRO_VOICE*); + void (*deallocate_voice)(ALLEGRO_VOICE*); + + int (*load_voice)(ALLEGRO_VOICE*, const void*); + void (*unload_voice)(ALLEGRO_VOICE*); + + int (*start_voice)(ALLEGRO_VOICE*); + int (*stop_voice)(ALLEGRO_VOICE*); + + bool (*voice_is_playing)(const ALLEGRO_VOICE*); + + unsigned int (*get_voice_position)(const ALLEGRO_VOICE*); + int (*set_voice_position)(ALLEGRO_VOICE*, unsigned int); + + + int (*allocate_recorder)(struct ALLEGRO_AUDIO_RECORDER *); + void (*deallocate_recorder)(struct ALLEGRO_AUDIO_RECORDER *); +}; + +extern ALLEGRO_AUDIO_DRIVER *_al_kcm_driver; + +const void *_al_voice_update(ALLEGRO_VOICE *voice, ALLEGRO_MUTEX *mutex, + unsigned int *samples); +bool _al_kcm_set_voice_playing(ALLEGRO_VOICE *voice, ALLEGRO_MUTEX *mutex, + bool val); + +/* A voice structure that you'd attach a mixer or sample to. Ideally there + * would be one ALLEGRO_VOICE per system/hardware voice. + */ +struct ALLEGRO_VOICE { + ALLEGRO_AUDIO_DEPTH depth; + ALLEGRO_CHANNEL_CONF chan_conf; + + unsigned int frequency; + + size_t buffer_size; + size_t num_buffers; + /* If non-0, they must be honored by the driver. */ + + ALLEGRO_SAMPLE_INSTANCE *attached_stream; + /* The stream that is attached to the voice, or NULL. + * May be an ALLEGRO_SAMPLE_INSTANCE or ALLEGRO_MIXER object. + */ + + bool is_streaming; + /* True for voices with an attached mixer. */ + + ALLEGRO_MUTEX *mutex; + ALLEGRO_COND *cond; + + _AL_LIST_ITEM *dtor_item; + + ALLEGRO_AUDIO_DRIVER *driver; + /* XXX shouldn't there only be one audio driver active + * at a time? + */ + + void *extra; + /* Extra data for use by the driver. */ +}; + + +typedef union { + float *f32; + uint32_t *u24; + int32_t *s24; + uint16_t *u16; + int16_t *s16; + uint8_t *u8; + int8_t *s8; + void *ptr; +} any_buffer_t; + +struct ALLEGRO_SAMPLE { + ALLEGRO_AUDIO_DEPTH depth; + ALLEGRO_CHANNEL_CONF chan_conf; + unsigned int frequency; + int len; + any_buffer_t buffer; + bool free_buf; + /* Whether `buffer' needs to be freed when the sample + * is destroyed, or when `buffer' changes. + */ + _AL_LIST_ITEM *dtor_item; +}; + +/* Read some samples into a mixer buffer. + * + * source: + * The object to read samples from. This may be one of several types. + * + * *vbuf: (in-out parameter) + * Pointer to pointer to destination buffer. + * (should confirm what it means to change the pointer on return) + * + * *samples: (in-out parameter) + * On input indicates the maximum number of samples that can fit into *vbuf. + * On output indicates the actual number of samples that were read. + * + * buffer_depth: + * The audio depth of the destination buffer. + * + * dest_maxc: + * The number of channels in the destination. + */ +typedef void (*stream_reader_t)(void *source, void **vbuf, + unsigned int *samples, ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc); + +typedef struct { + union { + ALLEGRO_MIXER *mixer; + ALLEGRO_VOICE *voice; + void *ptr; + } u; + bool is_voice; +} sample_parent_t; + +/* The sample struct also serves the base of ALLEGRO_AUDIO_STREAM, ALLEGRO_MIXER. */ +struct ALLEGRO_SAMPLE_INSTANCE { + /* ALLEGRO_SAMPLE_INSTANCE does not generate any events yet but ALLEGRO_AUDIO_STREAM + * does, which can inherit only ALLEGRO_SAMPLE_INSTANCE. */ + ALLEGRO_EVENT_SOURCE es; + + ALLEGRO_SAMPLE spl_data; + + volatile bool is_playing; + /* Is this sample is playing? */ + + ALLEGRO_PLAYMODE loop; + float speed; + float gain; + float pan; + + /* When resampling an audio stream there will be fractional sample + * positions due to the difference in frequencies. + */ + int pos; + int pos_bresenham_error; + + int loop_start; + int loop_end; + + int step; + int step_denom; + /* The numerator and denominator of the step are + * stored separately. The actual step is obtained by + * dividing step by step_denom */ + + float *matrix; + /* Used to convert from this format to the attached + * mixers, if any. Otherwise is NULL. + * The gain is premultiplied in. + */ + + bool is_mixer; + stream_reader_t spl_read; + /* Reads sample data into the provided buffer, using + * the specified format, converting as necessary. + */ + + ALLEGRO_MUTEX *mutex; + /* Points to the parent object's mutex. It is NULL if + * the sample is not directly or indirectly attached + * to a voice. + */ + + sample_parent_t parent; + /* The object that this sample is attached to, if any. + */ + _AL_LIST_ITEM *dtor_item; +}; + +void _al_kcm_destroy_sample(ALLEGRO_SAMPLE_INSTANCE *sample, bool unregister); +void _al_kcm_stream_set_mutex(ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_MUTEX *mutex); +void _al_kcm_detach_from_parent(ALLEGRO_SAMPLE_INSTANCE *spl); + + +typedef size_t (*stream_callback_t)(ALLEGRO_AUDIO_STREAM *, void *, size_t); +typedef void (*unload_feeder_t)(ALLEGRO_AUDIO_STREAM *); +typedef bool (*rewind_feeder_t)(ALLEGRO_AUDIO_STREAM *); +typedef bool (*seek_feeder_t)(ALLEGRO_AUDIO_STREAM *, double); +typedef double (*get_feeder_position_t)(ALLEGRO_AUDIO_STREAM *); +typedef double (*get_feeder_length_t)(ALLEGRO_AUDIO_STREAM *); +typedef bool (*set_feeder_loop_t)(ALLEGRO_AUDIO_STREAM *, double, double); + +struct ALLEGRO_AUDIO_STREAM { + ALLEGRO_SAMPLE_INSTANCE spl; + /* ALLEGRO_AUDIO_STREAM is derived from + * ALLEGRO_SAMPLE_INSTANCE. + */ + + unsigned int buf_count; + /* The stream buffer is divided into a number of + * fragments; this is the number of fragments. + */ + + void *main_buffer; + /* Pointer to a single buffer big enough to hold all + * the fragments. Each fragment has additional samples + * at the start for linear/cubic interpolation. + */ + + void **pending_bufs; + void **used_bufs; + /* Arrays of offsets into the main_buffer. + * The arrays are each 'buf_count' long. + * + * 'pending_bufs' holds pointers to fragments supplied + * by the user which are yet to be handed off to the + * audio driver. + * + * 'used_bufs' holds pointers to fragments which + * have been sent to the audio driver and so are + * ready to receive new data. + */ + + volatile bool is_draining; + /* Set to true if sample data is not going to be passed + * to the stream any more. The stream must change its + * playing state to false after all buffers have been + * played. + */ + + uint64_t consumed_fragments; + /* Number of complete fragment buffers consumed since + * the stream was started. + */ + + ALLEGRO_THREAD *feed_thread; + ALLEGRO_MUTEX *feed_thread_started_mutex; + ALLEGRO_COND *feed_thread_started_cond; + bool feed_thread_started; + volatile bool quit_feed_thread; + unload_feeder_t unload_feeder; + rewind_feeder_t rewind_feeder; + seek_feeder_t seek_feeder; + get_feeder_position_t get_feeder_position; + get_feeder_length_t get_feeder_length; + set_feeder_loop_t set_feeder_loop; + stream_callback_t feeder; + /* If ALLEGRO_AUDIO_STREAM has been created by + * al_load_audio_stream(), the stream will be fed + * by a thread using the 'feeder' callback. Such + * streams don't need to be fed by the user. + */ + + _AL_LIST_ITEM *dtor_item; + + void *extra; + /* Extra data for use by the flac/vorbis addons. */ +}; + +bool _al_kcm_refill_stream(ALLEGRO_AUDIO_STREAM *stream); + + +typedef void (*postprocess_callback_t)(void *buf, unsigned int samples, + void *userdata); + +/* ALLEGRO_MIXER is derived from ALLEGRO_SAMPLE_INSTANCE. Certain internal functions and + * pointers may take either object type, and such things are explicitly noted. + * This is never exposed to the user, though. The sample object's read method + * will be set to a different function that will call the read method of all + * attached streams (which may be a sample, or another mixer). + */ +struct ALLEGRO_MIXER { + ALLEGRO_SAMPLE_INSTANCE ss; + /* ALLEGRO_MIXER is derived from ALLEGRO_SAMPLE_INSTANCE. */ + + ALLEGRO_MIXER_QUALITY quality; + + postprocess_callback_t postprocess_callback; + void *pp_callback_userdata; + + _AL_VECTOR streams; + /* Vector of ALLEGRO_SAMPLE_INSTANCE*. Holds the list of + * streams being mixed together. + */ + _AL_LIST_ITEM *dtor_item; +}; + +extern void _al_kcm_mixer_rejig_sample_matrix(ALLEGRO_MIXER *mixer, + ALLEGRO_SAMPLE_INSTANCE *spl); +extern void _al_kcm_mixer_read(void *source, void **buf, unsigned int *samples, + ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc); + + +typedef enum { + ALLEGRO_NO_ERROR = 0, + ALLEGRO_INVALID_PARAM = 1, + ALLEGRO_INVALID_OBJECT = 2, + ALLEGRO_GENERIC_ERROR = 255 +} AL_ERROR_ENUM; + +extern void _al_set_error(int error, char* string); + +/* Supposedly internal */ +ALLEGRO_KCM_AUDIO_FUNC(void*, _al_kcm_feed_stream, (ALLEGRO_THREAD *self, void *vstream)); + +/* Helper to emit an event that the stream has got a buffer ready to be refilled. */ +void _al_kcm_emit_stream_events(ALLEGRO_AUDIO_STREAM *stream); + +void _al_kcm_init_destructors(void); +void _al_kcm_shutdown_destructors(void); +_AL_LIST_ITEM *_al_kcm_register_destructor(char const *name, void *object, + void (*func)(void*)); +void _al_kcm_unregister_destructor(_AL_LIST_ITEM *dtor_item); +void _al_kcm_foreach_destructor( + void (*callback)(void *object, void (*func)(void *), void *udata), + void *userdata); + +ALLEGRO_KCM_AUDIO_FUNC(void, _al_kcm_shutdown_default_mixer, (void)); + +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_CHANNEL_CONF, _al_count_to_channel_conf, (int num_channels)); +ALLEGRO_KCM_AUDIO_FUNC(ALLEGRO_AUDIO_DEPTH, _al_word_size_to_depth_conf, (int word_size)); + +ALLEGRO_KCM_AUDIO_FUNC(void, _al_emit_audio_event, (int event_type)); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/allegro5/internal/aintern_audio_cfg.h.cmake b/allegro/addons/audio/allegro5/internal/aintern_audio_cfg.h.cmake new file mode 100644 index 00000000..a865fd8c --- /dev/null +++ b/allegro/addons/audio/allegro5/internal/aintern_audio_cfg.h.cmake @@ -0,0 +1,7 @@ +#cmakedefine ALLEGRO_CFG_KCM_ALSA +#cmakedefine ALLEGRO_CFG_KCM_OPENAL +#cmakedefine ALLEGRO_CFG_KCM_OPENSL +#cmakedefine ALLEGRO_CFG_KCM_DSOUND +#cmakedefine ALLEGRO_CFG_KCM_OSS +#cmakedefine ALLEGRO_CFG_KCM_PULSEAUDIO +#cmakedefine ALLEGRO_CFG_KCM_AQUEUE diff --git a/allegro/addons/audio/alsa.c b/allegro/addons/audio/alsa.c new file mode 100644 index 00000000..966a7bc2 --- /dev/null +++ b/allegro/addons/audio/alsa.c @@ -0,0 +1,903 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * ALSA 1.0 sound driver. + * + * By Thomas Fjellstrom. + * + * Extensively modified by Elias Pschernig. + * + * Rewritten for 4.3 sound API by Milan Mimica, with additional + * improvements by Chris Robinson. Updated for 4.9 by Ryan Dickie + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_audio.h" + +#include <alloca.h> +#include <alsa/asoundlib.h> + +ALLEGRO_DEBUG_CHANNEL("alsa") + +#define ALSA_CHECK(a) \ +do { \ + int err = (a); \ + if (err < 0) { \ + ALLEGRO_ERROR("%s: %s\n", snd_strerror(err), #a); \ + goto Error; \ + } \ +} while(0) + + +static snd_output_t *snd_output = NULL; +static char *default_device = "default"; +static char *alsa_device = NULL; + +// TODO: Setting this to 256 causes (extreme, about than 10 seconds) +// lag if the alsa device is really pulseaudio. +// +// pw: But there are calls later which expect this variable to be set an on +// my machine (without PulseAudio) the driver doesn't work properly with +// anything lower than 32. +#define DEFAULT_PERIOD_SIZE 32 +#define MIN_PERIOD_SIZE 1 + +// This value works well on my RPI3 and Linux machine. +#define DEFAULT_BUFFER_SIZE 2048 + +static unsigned int get_period_size(void) +{ + const char *val = al_get_config_value(al_get_system_config(), + "alsa", "buffer_size"); + if (val && val[0] != '\0') { + int n = atoi(val); + if (n < MIN_PERIOD_SIZE) + n = MIN_PERIOD_SIZE; + return n; + } + + return DEFAULT_PERIOD_SIZE; +} + +static snd_pcm_uframes_t get_buffer_size(void) +{ + const char *val = al_get_config_value(al_get_system_config(), + "alsa", "buffer_size2"); + if (val && val[0] != '\0') { + int n = atoi(val); + if (n < 1) + n = 1; + return n; + } + + return DEFAULT_BUFFER_SIZE; +} + +typedef struct ALSA_VOICE { + unsigned int frame_size; /* in bytes */ + unsigned int len; /* in frames */ + snd_pcm_uframes_t frag_len; /* in frames */ + bool reversed; /* true if playing reversed ATM. */ + + volatile bool stop; + volatile bool stopped; + + struct pollfd *ufds; + int ufds_count; + + ALLEGRO_THREAD *poll_thread; + + snd_pcm_t *pcm_handle; + bool mmapped; +} ALSA_VOICE; + + + +/* initialized output */ +static int alsa_open(void) +{ + alsa_device = default_device; + + const char *config_device; + config_device = al_get_config_value(al_get_system_config(), "alsa", "device"); + if (config_device && config_device[0] != '\0') + alsa_device = strdup(config_device); + + ALSA_CHECK(snd_output_stdio_attach(&snd_output, stdout, 0)); + + /* We need to check if alsa is available in this function. */ + snd_pcm_t *test_pcm_handle; + int alsa_err = snd_pcm_open(&test_pcm_handle, alsa_device, + SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + if (alsa_err < 0) { + ALLEGRO_WARN("ALSA is not available on the system.\n"); + return 1; + } + else { + snd_pcm_close(test_pcm_handle); + } + + return 0; + + /* ALSA check is a macro that 'goto' error*/ +Error: + ALLEGRO_ERROR("Error initializing alsa!\n"); + return 1; +} + + + +/* The close method should close the device, freeing any resources, and allow + other processes to use the device */ +static void alsa_close(void) +{ + if (alsa_device != default_device) + al_free(alsa_device); + + alsa_device = NULL; + + snd_output_close(snd_output); + snd_config_update_free_global(); +} + + +/* Underrun and suspend recovery */ +static int xrun_recovery(snd_pcm_t *handle, int err) +{ + if (err == -EPIPE) { /* under-run */ + err = snd_pcm_prepare(handle); + if (err < 0) { + ALLEGRO_ERROR("Can't recover from underrun, prepare failed: %s\n", snd_strerror(err)); + } + else { + ALLEGRO_DEBUG("Recovered from underrun\n"); + } + return 0; + } + else if (err == -ESTRPIPE) { /* suspend */ + err = snd_pcm_resume(handle); + if (err < 0) { + ALLEGRO_ERROR("Can't recover from suspend, resume failed: %s\n", snd_strerror(err)); + } + else { + ALLEGRO_DEBUG("Resumed successfully\n"); + } + return 0; + } + else { + ALLEGRO_ERROR("Unknown error code: %d\n", err); + ASSERT(0); + } + + return err; +} + + +/* + * Updates the supplied non-streaming voice. + * buf - Returns a pointer to the buffer containing sample data. + * bytes - The requested size of the sample data buffer. Returns the actual + * size of returned the buffer. + * Updates 'stop', 'pos' and 'reversed' fields of the supplied voice to the + * future position. + * If the voice is played backwards, 'buf' will point to the end of the buffer + * and 'bytes' is the size that can be read towards the beginning. + */ +static int alsa_update_nonstream_voice(ALLEGRO_VOICE *voice, void **buf, int *bytes) +{ + ALSA_VOICE *alsa_voice = (ALSA_VOICE*)voice->extra; + int bpos = voice->attached_stream->pos * alsa_voice->frame_size; + int blen = alsa_voice->len * alsa_voice->frame_size; + + *buf = (char *)voice->attached_stream->spl_data.buffer.ptr + bpos; + + if (!alsa_voice->reversed) { + if (bpos + *bytes > blen) { + *bytes = blen - bpos; + if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) { + alsa_voice->stop = true; + voice->attached_stream->pos = 0; + } + if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_LOOP) { + voice->attached_stream->pos = 0; + } + else if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_BIDIR) { + alsa_voice->reversed = true; + voice->attached_stream->pos = alsa_voice->len; + } + return 1; + } + else + voice->attached_stream->pos += *bytes / alsa_voice->frame_size; + } + else { + if (bpos - *bytes < 0) { + *bytes = bpos; + /* loop will be ALLEGRO_PLAYMODE_BIDIR, other playing modes that play + backwards are not currently supported by the API */ + /*if (voice->attached_stream->loop != ALLEGRO_PLAYMODE_BIDIR) + alsa_voice->stop = true;*/ + + voice->attached_stream->pos = 0; + alsa_voice->reversed = false; + return 1; + } + else + voice->attached_stream->pos -= *bytes / alsa_voice->frame_size; + } + + return 0; +} + + +/* Returns true if the voice is ready for more data. */ +static int alsa_voice_is_ready(ALSA_VOICE *alsa_voice) +{ + unsigned short revents; + int err; + + poll(alsa_voice->ufds, alsa_voice->ufds_count, 0); + snd_pcm_poll_descriptors_revents(alsa_voice->pcm_handle, alsa_voice->ufds, + alsa_voice->ufds_count, &revents); + + if (revents & POLLERR) { + if (snd_pcm_state(alsa_voice->pcm_handle) == SND_PCM_STATE_XRUN || + snd_pcm_state(alsa_voice->pcm_handle) == SND_PCM_STATE_SUSPENDED) { + + if (snd_pcm_state(alsa_voice->pcm_handle) == SND_PCM_STATE_XRUN) + err = -EPIPE; + else + err = -ESTRPIPE; + + if (xrun_recovery(alsa_voice->pcm_handle, err) < 0) { + ALLEGRO_ERROR("Write error: %s\n", snd_strerror(err)); + return -POLLERR; + } + } else { + ALLEGRO_ERROR("Wait for poll failed\n"); + return -POLLERR; + } + } + + if (revents & POLLOUT) + return true; + + return false; +} + + +/* Custom routine which runs in another thread and fills the hardware PCM buffer + from the voice buffer. */ +static void *alsa_update_mmap(ALLEGRO_THREAD *self, void *arg) +{ + ALLEGRO_VOICE *voice = (ALLEGRO_VOICE*)arg; + ALSA_VOICE *alsa_voice = (ALSA_VOICE*)voice->extra; + snd_pcm_state_t last_state = -1; + snd_pcm_state_t state; + snd_pcm_uframes_t frames; + const snd_pcm_channel_area_t *areas; + snd_pcm_uframes_t offset; + char *mmap; + snd_pcm_sframes_t commitres; + int ret; + + ALLEGRO_INFO("ALSA update_mmap thread started\n"); + + while (!al_get_thread_should_stop(self)) { + if (alsa_voice->stop && !alsa_voice->stopped) { + snd_pcm_drop(alsa_voice->pcm_handle); + al_lock_mutex(voice->mutex); + alsa_voice->stopped = true; + al_signal_cond(voice->cond); + al_unlock_mutex(voice->mutex); + } + + if (!alsa_voice->stop && alsa_voice->stopped) { + alsa_voice->stopped = false; + } + + if (alsa_voice->stopped) { + /* Keep waiting while the voice is supposed to be stopped but present. + */ + al_lock_mutex(voice->mutex); + while (alsa_voice->stop && !al_get_thread_should_stop(self)) { + al_wait_cond(voice->cond, voice->mutex); + } + al_unlock_mutex(voice->mutex); + continue; + } + + state = snd_pcm_state(alsa_voice->pcm_handle); + if (state != last_state) { + ALLEGRO_DEBUG("state changed to: %s\n", snd_pcm_state_name(state)); + last_state = state; + } + if (state == SND_PCM_STATE_SETUP) { + int rc = snd_pcm_prepare(alsa_voice->pcm_handle); + ALLEGRO_DEBUG("snd_pcm_prepare returned: %d\n", rc); + continue; + } + if (state == SND_PCM_STATE_PREPARED) { + int rc = snd_pcm_start(alsa_voice->pcm_handle); + ALLEGRO_DEBUG("snd_pcm_start returned: %d\n", rc); + } + + ret = alsa_voice_is_ready(alsa_voice); + if (ret < 0) + break; + if (ret == 0) { + al_rest(0.005); /* TODO: Why not use an event or condition variable? */ + continue; + } + + snd_pcm_avail_update(alsa_voice->pcm_handle); + frames = alsa_voice->frag_len; + ret = snd_pcm_mmap_begin(alsa_voice->pcm_handle, &areas, &offset, &frames); + if (ret < 0) { + if ((ret = xrun_recovery(alsa_voice->pcm_handle, ret)) < 0) { + ALLEGRO_ERROR("MMAP begin avail error: %s\n", snd_strerror(ret)); + } + break; + } + + if (frames == 0) { + al_rest(0.005); /* TODO: Why not use an event or condition variable? */ + goto commit; + } + + /* mmaped driver's memory. Interleaved channels format. */ + mmap = (char *) areas[0].addr + + areas[0].first / 8 + + offset * areas[0].step / 8; + + /* Read sample data into the buffer. */ + if (!voice->is_streaming && !alsa_voice->stopped) { + void *buf; + bool reverse = alsa_voice->reversed; + int bytes = frames * alsa_voice->frame_size; + + alsa_update_nonstream_voice(voice, &buf, &bytes); + frames = bytes / alsa_voice->frame_size; + if (!reverse) { + memcpy(mmap, buf, bytes); + } + else { + /* Put a reversed copy in the driver's buffer. */ + unsigned int i; + int fs = alsa_voice->frame_size; + for (i = 1; i <= frames; i++) + memcpy(mmap + i * fs, (char *) buf - i * fs, fs); + } + } + else if (voice->is_streaming && !alsa_voice->stopped) { + /* This should fit. */ + unsigned int iframes = frames; + const void *data = _al_voice_update(voice, voice->mutex, &iframes); + frames = iframes; + if (data == NULL) + goto silence; + memcpy(mmap, data, frames * alsa_voice->frame_size); + } + else { +silence: + /* If stopped just fill with silence. */ + al_fill_silence(mmap, frames, voice->depth, voice->chan_conf); + } + +commit: + commitres = snd_pcm_mmap_commit(alsa_voice->pcm_handle, offset, frames); + if (commitres < 0 || (snd_pcm_uframes_t)commitres != frames) { + if ((ret = xrun_recovery(alsa_voice->pcm_handle, commitres >= 0 ? -EPIPE : commitres)) < 0) { + ALLEGRO_ERROR("MMAP commit error: %s\n", snd_strerror(ret)); + break; + } + } + } + + ALLEGRO_INFO("ALSA update_mmap thread stopped\n"); + + return NULL; +} + + +static void *alsa_update_rw(ALLEGRO_THREAD *self, void *arg) +{ + ALLEGRO_VOICE *voice = (ALLEGRO_VOICE*)arg; + ALSA_VOICE *alsa_voice = (ALSA_VOICE*)voice->extra; + snd_pcm_state_t last_state = -1; + snd_pcm_state_t state; + snd_pcm_uframes_t frames; + snd_pcm_sframes_t err; + + ALLEGRO_INFO("ALSA update_rw thread started\n"); + + while (!al_get_thread_should_stop(self)) { + if (alsa_voice->stop && !alsa_voice->stopped) { + snd_pcm_drop(alsa_voice->pcm_handle); + al_lock_mutex(voice->mutex); + alsa_voice->stopped = true; + al_signal_cond(voice->cond); + al_unlock_mutex(voice->mutex); + } + + if (!alsa_voice->stop && alsa_voice->stopped) { + alsa_voice->stopped = false; + } + + if (alsa_voice->stopped) { + /* Keep waiting while the voice is supposed to be stopped but present. + */ + al_lock_mutex(voice->mutex); + while (alsa_voice->stop && !al_get_thread_should_stop(self)) { + al_wait_cond(voice->cond, voice->mutex); + } + al_unlock_mutex(voice->mutex); + continue; + } + + state = snd_pcm_state(alsa_voice->pcm_handle); + if (state != last_state) { + ALLEGRO_DEBUG("state changed to: %s\n", snd_pcm_state_name(state)); + last_state = state; + } + if (state == SND_PCM_STATE_SETUP) { + int rc = snd_pcm_prepare(alsa_voice->pcm_handle); + ALLEGRO_DEBUG("snd_pcm_prepare returned: %d\n", rc); + continue; + } + if (state == SND_PCM_STATE_PREPARED) { + int rc = snd_pcm_start(alsa_voice->pcm_handle); + ALLEGRO_DEBUG("snd_pcm_start returned: %d\n", rc); + } + + snd_pcm_wait(alsa_voice->pcm_handle, 10); + err = snd_pcm_avail_update(alsa_voice->pcm_handle); + if (err < 0) { + if (err == -EPIPE) { + snd_pcm_prepare(alsa_voice->pcm_handle); + } + else { + ALLEGRO_WARN("Alsa r/w thread exited " + "with error code %s.\n", snd_strerror(-err)); + break; + } + } + if (err == 0) { + continue; + } + frames = err; + if (frames > alsa_voice->frag_len) + frames = alsa_voice->frag_len; + /* Write sample data into the buffer. */ + int bytes = frames * alsa_voice->frame_size; + uint8_t data[bytes]; + void *buf; + if (!voice->is_streaming && !alsa_voice->stopped) { + ASSERT(!alsa_voice->reversed); // FIXME + alsa_update_nonstream_voice(voice, &buf, &bytes); + frames = bytes / alsa_voice->frame_size; + } + else if (voice->is_streaming && !alsa_voice->stopped) { + /* This should fit. */ + unsigned int iframes = frames; + buf = (void *)_al_voice_update(voice, voice->mutex, &iframes); + if (buf == NULL) + goto silence; + frames = iframes; + } + else { +silence: + /* If stopped just fill with silence. */ + al_fill_silence(data, frames, voice->depth, voice->chan_conf); + buf = data; + } + err = snd_pcm_writei(alsa_voice->pcm_handle, buf, frames); + if (err < 0) { + if (err == -EPIPE) { + snd_pcm_prepare(alsa_voice->pcm_handle); + } + } + } + + ALLEGRO_INFO("ALSA update_rw thread stopped\n"); + + return NULL; +} + + +/* The load_voice method loads a sample into the driver's memory. The voice's + 'streaming' field will be set to false for these voices, and it's + 'buffer_size' field will be the total length in bytes of the sample data. + The voice's attached stream's looping mode should be honored, and loading + must fail if it cannot be. */ +static int alsa_load_voice(ALLEGRO_VOICE *voice, const void *data) +{ + ALSA_VOICE *ex_data = voice->extra; + + voice->attached_stream->pos = 0; + ex_data->len = voice->attached_stream->spl_data.len; + + return 0; + (void)data; +} + + + +/* The unload_voice method unloads a sample previously loaded with load_voice. + This method should not be called on a streaming voice. */ +static void alsa_unload_voice(ALLEGRO_VOICE *voice) +{ + (void)voice; +} + + + +/* The start_voice should, surprise, start the voice. For streaming voices, it + should start polling the device and call _al_voice_update for audio data. + For non-streaming voices, it should resume playing from the last set + position */ +static int alsa_start_voice(ALLEGRO_VOICE *voice) +{ + ALSA_VOICE *ex_data = voice->extra; + + /* We already hold voice->mutex. */ + ex_data->stop = false; + al_signal_cond(voice->cond); + + return 0; +} + + + +/* The stop_voice method should stop playback. For non-streaming voices, it + should leave the data loaded, and reset the voice position to 0. */ +static int alsa_stop_voice(ALLEGRO_VOICE *voice) +{ + ALSA_VOICE *ex_data = voice->extra; + + /* We already hold voice->mutex. */ + ex_data->stop = true; + al_signal_cond(voice->cond); + + if (!voice->is_streaming) { + voice->attached_stream->pos = 0; + } + + while (!ex_data->stopped) { + al_wait_cond(voice->cond, voice->mutex); + } + + return 0; +} + + + +/* The voice_is_playing method should only be called on non-streaming sources, + and should return true if the voice is playing */ +static bool alsa_voice_is_playing(const ALLEGRO_VOICE *voice) +{ + ALSA_VOICE *ex_data = voice->extra; + return !ex_data->stopped; +} + + +/* The allocate_voice method should grab a voice from the system, and allocate + any data common to streaming and non-streaming sources. */ +static int alsa_allocate_voice(ALLEGRO_VOICE *voice) +{ + snd_pcm_format_t format; + int chan_count; + unsigned int req_freq; + + ALSA_VOICE *ex_data = al_calloc(1, sizeof(ALSA_VOICE)); + if (!ex_data) + return 1; + + chan_count = al_get_channel_count(voice->chan_conf); + ex_data->frame_size = chan_count * al_get_audio_depth_size(voice->depth); + if (!ex_data->frame_size) + goto Error; + + ex_data->stop = true; + ex_data->stopped = true; + ex_data->reversed = false; + + ex_data->frag_len = get_period_size(); + + if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT8) + format = SND_PCM_FORMAT_S8; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) + format = SND_PCM_FORMAT_U8; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) + format = SND_PCM_FORMAT_S16; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) + format = SND_PCM_FORMAT_U16; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT24) + format = SND_PCM_FORMAT_S24; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT24) + format = SND_PCM_FORMAT_U24; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) + format = SND_PCM_FORMAT_FLOAT; + else + goto Error; + + /* Why is this? And what is this? */ + if (voice->chan_conf == ALLEGRO_CHANNEL_CONF_3) + goto Error; + + req_freq = voice->frequency; + + ALSA_CHECK(snd_pcm_open(&ex_data->pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)); + + snd_pcm_hw_params_t *hwparams; + snd_pcm_hw_params_alloca(&hwparams); + + ALSA_CHECK(snd_pcm_hw_params_any(ex_data->pcm_handle, hwparams)); + if (snd_pcm_hw_params_set_access(ex_data->pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) == 0) { + ex_data->mmapped = true; + } + else { + ALSA_CHECK(snd_pcm_hw_params_set_access(ex_data->pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)); + ex_data->mmapped = false; + } + ALSA_CHECK(snd_pcm_hw_params_set_format(ex_data->pcm_handle, hwparams, format)); + ALSA_CHECK(snd_pcm_hw_params_set_channels(ex_data->pcm_handle, hwparams, chan_count)); + ALSA_CHECK(snd_pcm_hw_params_set_rate_near(ex_data->pcm_handle, hwparams, &req_freq, NULL)); + ALSA_CHECK(snd_pcm_hw_params_set_period_size_near(ex_data->pcm_handle, hwparams, &ex_data->frag_len, NULL)); + snd_pcm_uframes_t buffer_size = get_buffer_size(); + ALSA_CHECK(snd_pcm_hw_params_set_buffer_size_near(ex_data->pcm_handle, hwparams, &buffer_size)); + ALSA_CHECK(snd_pcm_hw_params(ex_data->pcm_handle, hwparams)); + + if (voice->frequency != req_freq) { + ALLEGRO_ERROR("Unsupported rate! Requested %u, got %iu.\n", voice->frequency, req_freq); + goto Error; + } + + snd_pcm_sw_params_t *swparams; + snd_pcm_sw_params_alloca(&swparams); + + ALSA_CHECK(snd_pcm_sw_params_current(ex_data->pcm_handle, swparams)); + ALSA_CHECK(snd_pcm_sw_params_set_start_threshold(ex_data->pcm_handle, swparams, ex_data->frag_len)); + ALSA_CHECK(snd_pcm_sw_params_set_avail_min(ex_data->pcm_handle, swparams, ex_data->frag_len)); + ALSA_CHECK(snd_pcm_sw_params(ex_data->pcm_handle, swparams)); + + ex_data->ufds_count = snd_pcm_poll_descriptors_count(ex_data->pcm_handle); + ex_data->ufds = al_malloc(sizeof(struct pollfd) * ex_data->ufds_count); + ALSA_CHECK(snd_pcm_poll_descriptors(ex_data->pcm_handle, ex_data->ufds, ex_data->ufds_count)); + + voice->extra = ex_data; + + if (ex_data->mmapped) { + ex_data->poll_thread = al_create_thread(alsa_update_mmap, (void*)voice); + } + else { + ALLEGRO_WARN("Falling back to non-mmapped transfer.\n"); + snd_pcm_nonblock(ex_data->pcm_handle, 0); + ex_data->poll_thread = al_create_thread(alsa_update_rw, (void*)voice); + } + al_start_thread(ex_data->poll_thread); + + return 0; + +Error: + if (ex_data->pcm_handle) + snd_pcm_close(ex_data->pcm_handle); + al_free(ex_data); + voice->extra = NULL; + return 1; +} + + + +/* The deallocate_voice method should free the resources for the given voice, + but still retain a hold on the device. The voice should be stopped and + unloaded by the time this is called */ +static void alsa_deallocate_voice(ALLEGRO_VOICE *voice) +{ + ALSA_VOICE *alsa_voice = (ALSA_VOICE*)voice->extra; + + al_lock_mutex(voice->mutex); + al_set_thread_should_stop(alsa_voice->poll_thread); + al_broadcast_cond(voice->cond); + al_unlock_mutex(voice->mutex); + al_join_thread(alsa_voice->poll_thread, NULL); + + snd_pcm_drop(alsa_voice->pcm_handle); + snd_pcm_close(alsa_voice->pcm_handle); + + al_destroy_thread(alsa_voice->poll_thread); + al_free(alsa_voice->ufds); + al_free(voice->extra); + voice->extra = NULL; +} + + + +/* The get_voice_position method should return the current sample position of + the voice (sample_pos = byte_pos / (depth/8) / channels). This should never + be called on a streaming voice. */ +static unsigned int alsa_get_voice_position(const ALLEGRO_VOICE *voice) +{ + return voice->attached_stream->pos; +} + + + +/* The set_voice_position method should set the voice's playback position, + given the value in samples. This should never be called on a streaming + voice. */ +static int alsa_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) +{ + voice->attached_stream->pos = val; + return 0; +} + +typedef struct ALSA_RECORDER_DATA +{ + snd_pcm_t *capture_handle; + snd_pcm_hw_params_t *hw_params; +} ALSA_RECORDER_DATA; + +static void *alsa_update_recorder(ALLEGRO_THREAD *t, void *thread_data) +{ + ALLEGRO_AUDIO_RECORDER *r = thread_data; + ALSA_RECORDER_DATA *alsa = r->extra; + ALLEGRO_EVENT user_event; + uint8_t *null_buffer; + unsigned int fragment_i = 0; + + null_buffer = al_malloc(1024 * r->sample_size); + if (!null_buffer) { + ALLEGRO_ERROR("Unable to create buffer for draining ALSA.\n"); + return NULL; + } + + while (!al_get_thread_should_stop(t)) + { + al_lock_mutex(r->mutex); + if (!r->is_recording) { + /* Even if not recording, we still want to read from ALSA. + Otherwise it will buffer everything and spit it all out whenever + the recording resumes. (XXX: Just copied this from PulseAudio. + This current implementation is just a bare minimum effort...) + */ + al_unlock_mutex(r->mutex); + snd_pcm_readi(alsa->capture_handle, null_buffer, 1024); + } + else { + ALLEGRO_AUDIO_RECORDER_EVENT *e; + snd_pcm_sframes_t count; + al_unlock_mutex(r->mutex); + if ((count = snd_pcm_readi(alsa->capture_handle, r->fragments[fragment_i], r->samples)) > 0) { + user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; + e = al_get_audio_recorder_event(&user_event); + e->buffer = r->fragments[fragment_i]; + e->samples = count; + al_emit_user_event(&r->source, &user_event, NULL); + + if (++fragment_i == r->fragment_count) { + fragment_i = 0; + } + } + } + } + + al_free(null_buffer); + return NULL; +} + +static int alsa_allocate_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + ALSA_RECORDER_DATA *data; + unsigned int frequency = r->frequency; + snd_pcm_format_t format; + const char *device = default_device; + const char *config_device; + config_device = + al_get_config_value(al_get_system_config(), "alsa", "capture_device"); + if (config_device && config_device[0] != '\0') + device = config_device; + + data = al_calloc(1, sizeof(*data)); + + if (!data) { + goto Error; + } + + if (r->depth == ALLEGRO_AUDIO_DEPTH_INT8) + format = SND_PCM_FORMAT_S8; + else if (r->depth == ALLEGRO_AUDIO_DEPTH_UINT8) + format = SND_PCM_FORMAT_U8; + else if (r->depth == ALLEGRO_AUDIO_DEPTH_INT16) + format = SND_PCM_FORMAT_S16; + else if (r->depth == ALLEGRO_AUDIO_DEPTH_UINT16) + format = SND_PCM_FORMAT_U16; + else if (r->depth == ALLEGRO_AUDIO_DEPTH_INT24) + format = SND_PCM_FORMAT_S24; + else if (r->depth == ALLEGRO_AUDIO_DEPTH_UINT24) + format = SND_PCM_FORMAT_U24; + else if (r->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) + format = SND_PCM_FORMAT_FLOAT; + else + goto Error; + + ALSA_CHECK(snd_pcm_open(&data->capture_handle, device, SND_PCM_STREAM_CAPTURE, 0)); + ALSA_CHECK(snd_pcm_hw_params_malloc(&data->hw_params)); + ALSA_CHECK(snd_pcm_hw_params_any(data->capture_handle, data->hw_params)); + ALSA_CHECK(snd_pcm_hw_params_set_access(data->capture_handle, data->hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)); + ALSA_CHECK(snd_pcm_hw_params_set_format(data->capture_handle, data->hw_params, format)); + ALSA_CHECK(snd_pcm_hw_params_set_rate_near(data->capture_handle, data->hw_params, &frequency, 0)); + + if (frequency != r->frequency) { + ALLEGRO_ERROR("Unsupported rate! Requested %u, got %iu.\n", r->frequency, frequency); + goto Error; + } + + ALSA_CHECK(snd_pcm_hw_params_set_channels(data->capture_handle, data->hw_params, al_get_channel_count(r->chan_conf))); + ALSA_CHECK(snd_pcm_hw_params(data->capture_handle, data->hw_params)); + + ALSA_CHECK(snd_pcm_prepare(data->capture_handle)); + + r->extra = data; + r->thread = al_create_thread(alsa_update_recorder, r); + + return 0; + +Error: + + if (data) { + if (data->hw_params) { + snd_pcm_hw_params_free(data->hw_params); + } + if (data->capture_handle) { + snd_pcm_close(data->capture_handle); + } + al_free(data); + } + + return 1; +} + +static void alsa_deallocate_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + ALSA_RECORDER_DATA *data = r->extra; + + snd_pcm_hw_params_free(data->hw_params); + snd_pcm_close(data->capture_handle); +} + +ALLEGRO_AUDIO_DRIVER _al_kcm_alsa_driver = +{ + "ALSA", + + alsa_open, + alsa_close, + + alsa_allocate_voice, + alsa_deallocate_voice, + + alsa_load_voice, + alsa_unload_voice, + + alsa_start_voice, + alsa_stop_voice, + + alsa_voice_is_playing, + + alsa_get_voice_position, + alsa_set_voice_position, + + alsa_allocate_recorder, + alsa_deallocate_recorder +}; + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/aqueue.m b/allegro/addons/audio/aqueue.m new file mode 100644 index 00000000..b335ad8c --- /dev/null +++ b/allegro/addons/audio/aqueue.m @@ -0,0 +1,581 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Apple Audio Queue driver + * + * By Trent Gamblin. + * + * See readme.txt for copyright information. + */ + +#include <stdio.h> + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_audio_cfg.h" +#include "allegro5/internal/aintern_vector.h" + +#import <CoreAudio/CoreAudioTypes.h> +#import <AudioToolbox/AudioToolbox.h> + +#ifdef ALLEGRO_IPHONE +#import <AVFoundation/AVFoundation.h> +#endif + +#import <Foundation/NSAutoreleasePool.h> +#import <AudioToolbox/AudioQueue.h> + +#define THREAD_BEGIN NSAutoreleasePool *___p = [[NSAutoreleasePool alloc] init]; +#define THREAD_END [___p drain]; + +// Make configurable +#define BUFFER_SIZE 1024*2 // in samples +#define NUM_BUFFERS 4 + +ALLEGRO_DEBUG_CHANNEL("AudioQueue") + +typedef struct ALLEGRO_AQ_DATA { + int bits_per_sample; + int channels; + bool playing; + unsigned int buffer_size; + unsigned char *silence; + ALLEGRO_VOICE *voice; + AudioQueueRef queue; + AudioQueueBufferRef buffers[NUM_BUFFERS]; +} ALLEGRO_AQ_DATA; + +static _AL_VECTOR saved_voices = _AL_VECTOR_INITIALIZER(ALLEGRO_VOICE*); + +/* Audio queue callback */ +static void handle_buffer( + void *in_data, + AudioQueueRef inAQ, + AudioQueueBufferRef inBuffer) +{ + ALLEGRO_AQ_DATA *ex_data = in_data; + const void *data; + + (void)inAQ; // unsused + + unsigned int samples = (ex_data->buffer_size / ex_data->channels) / + (ex_data->bits_per_sample / 8); + + data = _al_voice_update(ex_data->voice, ex_data->voice->mutex, &samples); + if (data == NULL) + data = ex_data->silence; + + unsigned int copy_bytes = samples * ex_data->channels * + (ex_data->bits_per_sample / 8); + copy_bytes = _ALLEGRO_MIN(copy_bytes, inBuffer->mAudioDataBytesCapacity); + + memcpy(inBuffer->mAudioData, data, copy_bytes); + inBuffer->mAudioDataByteSize = copy_bytes; + + AudioQueueEnqueueBuffer( + ex_data->queue, + inBuffer, + 0, + NULL + ); +} + +#ifdef ALLEGRO_IPHONE +static int _aqueue_start_voice(ALLEGRO_VOICE *voice); +static int _aqueue_stop_voice(ALLEGRO_VOICE* voice); + +static void interruption_callback(void *inClientData, UInt32 inInterruptionState) +{ + unsigned i; + (void)inClientData; + for (i = 0; i < _al_vector_size(&saved_voices); i++) { + ALLEGRO_VOICE **voice = _al_vector_ref(&saved_voices, i); + if (inInterruptionState == kAudioSessionBeginInterruption) { + _aqueue_stop_voice(*voice); + } + else { + _aqueue_start_voice(*voice); + } + } +} + +// This allows plugging/unplugging of hardware/bluetooth/speakers etc while keeping the sound playing +static void property_listener(void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData) +{ + unsigned i; + (void)inClientData; + (void)inDataSize; + + if (inID == kAudioSessionProperty_AudioRouteChange) { + for (i = 0; i < _al_vector_size(&saved_voices); i++) { + ALLEGRO_VOICE **voice = _al_vector_ref(&saved_voices, i); + UInt32 reason = (UInt32)inData; + if (reason == kAudioSessionRouteChangeReason_NewDeviceAvailable) { + _aqueue_stop_voice(*voice); + _aqueue_start_voice(*voice); + } + } + } +} +#endif + +/* The open method starts up the driver and should lock the device, using the + previously set paramters, or defaults. It shouldn't need to start sending + audio data to the device yet, however. */ +static int _aqueue_open() +{ +#ifdef ALLEGRO_IPHONE + /* These settings allow ipod music playback simultaneously with + * our Allegro music/sfx, and also do not stop the streams when + * a phone call comes in (it's muted for the duration of the call). + */ + AudioSessionInitialize(NULL, NULL, interruption_callback, NULL); + + UInt32 sessionCategory = kAudioSessionCategory_AmbientSound; + AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, + sizeof(sessionCategory), &sessionCategory); + + UInt32 mix = TRUE; + AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, + sizeof(mix), &mix); + + AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, property_listener, NULL); +#endif + return 0; +} + + +/* The close method should close the device, freeing any resources, and allow + other processes to use the device */ +static void _aqueue_close() +{ + _al_vector_free(&saved_voices); +} + + +/* The allocate_voice method should grab a voice from the system, and allocate + any data common to streaming and non-streaming sources. */ +static int _aqueue_allocate_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_AQ_DATA *ex_data; + int bits_per_sample; + int channels; + + switch (voice->depth) + { + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_INT16: + bits_per_sample = 16; + break; + default: + return 1; + } + + switch (voice->chan_conf) { + case ALLEGRO_CHANNEL_CONF_1: + channels = 1; + break; + case ALLEGRO_CHANNEL_CONF_2: + channels = 2; + break; + default: + fprintf(stderr, "Unsupported number of channels\n"); + return 1; + } + + ex_data = (ALLEGRO_AQ_DATA *)al_calloc(1, sizeof(*ex_data)); + if (!ex_data) { + fprintf(stderr, "Could not allocate voice data memory\n"); + return 1; + } + + ex_data->bits_per_sample = bits_per_sample; + ex_data->channels = channels; + ex_data->buffer_size = BUFFER_SIZE*channels*(bits_per_sample/8); + ex_data->playing = false; + + voice->extra = ex_data; + ex_data->voice = voice; + + ex_data->silence = al_calloc(1, ex_data->buffer_size); + + return 0; +} + +/* The deallocate_voice method should free the resources for the given voice, + but still retain a hold on the device. The voice should be stopped and + unloaded by the time this is called */ +static void _aqueue_deallocate_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_AQ_DATA *ex_data = voice->extra; + al_free(ex_data->silence); + al_free(ex_data); + voice->extra = NULL; +} + +/* The load_voice method loads a sample into the driver's memory. The voice's + 'streaming' field will be set to false for these voices, and it's + 'buffer_size' field will be the total length in bytes of the sample data. + The voice's attached sample's looping mode should be honored, and loading + must fail if it cannot be. */ +static int _aqueue_load_voice(ALLEGRO_VOICE *voice, const void *data) +{ + /* FIXME */ + (void)voice; + (void)data; + return 1; +} + +/* The unload_voice method unloads a sample previously loaded with load_voice. + This method should not be called on a streaming voice. */ +static void _aqueue_unload_voice(ALLEGRO_VOICE *voice) +{ + /* FIXME */ + (void)voice; +} + + +static void *stream_proc(void *in_data) +{ + THREAD_BEGIN + + ALLEGRO_VOICE *voice = in_data; + ALLEGRO_AQ_DATA *ex_data = voice->extra; + + AudioStreamBasicDescription desc; + + desc.mSampleRate = voice->frequency; + desc.mFormatID = kAudioFormatLinearPCM; + if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) + desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | + kLinearPCMFormatFlagIsPacked; + else + desc.mFormatFlags = kLinearPCMFormatFlagIsFloat | + kLinearPCMFormatFlagIsPacked; +#ifdef ALLEGRO_BIG_ENDIAN + desc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; +#endif + desc.mBytesPerPacket = ex_data->channels * (ex_data->bits_per_sample/8); + desc.mFramesPerPacket = 1; + desc.mBytesPerFrame = ex_data->channels * (ex_data->bits_per_sample/8); + desc.mChannelsPerFrame = ex_data->channels; + desc.mBitsPerChannel = ex_data->bits_per_sample; + + int ret = AudioQueueNewOutput( + &desc, + handle_buffer, + ex_data, + CFRunLoopGetCurrent(), + kCFRunLoopCommonModes, + 0, + &ex_data->queue); + + int i; + for (i = 0; i < NUM_BUFFERS; ++i) { + AudioQueueAllocateBuffer( + ex_data->queue, + ex_data->buffer_size, + &ex_data->buffers[i] + ); + + memcpy(ex_data->buffers[i]->mAudioData, ex_data->silence, ex_data->buffer_size); + ex_data->buffers[i]->mAudioDataByteSize = ex_data->buffer_size; + ex_data->buffers[i]->mUserData = ex_data; + // FIXME: Safe to comment this out? + //ex_data->buffers[i]->mPacketDescriptionCount = 0; + + AudioQueueEnqueueBuffer( + ex_data->queue, + ex_data->buffers[i], + 0, + NULL + ); + } + + AudioQueueSetParameter( + ex_data->queue, + kAudioQueueParam_Volume, + 1.0f + ); + + ret = AudioQueueStart( + ex_data->queue, + NULL + ); + + do { + THREAD_BEGIN + CFRunLoopRunInMode( + kCFRunLoopDefaultMode, + 0.05, + false + ); + THREAD_END + } while (ex_data->playing); + + THREAD_END + + return NULL; +} + + +/* The start_voice should, surprise, start the voice. For streaming voices, it + should start polling the device and call _al_voice_update for audio data. + For non-streaming voices, it should resume playing from the last set + position */ +static int _aqueue_start_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_AQ_DATA *ex_data = voice->extra; + + if (voice->is_streaming && !ex_data->playing) { + *(ALLEGRO_VOICE**)_al_vector_alloc_back(&saved_voices) = voice; + ex_data->playing = true; + al_run_detached_thread(stream_proc, voice); + return 0; + } + + /* FIXME */ + return 1; +} + + +/* The stop_voice method should stop playback. For non-streaming voices, it + should leave the data loaded, and reset the voice position to 0. */ +static int _aqueue_stop_voice(ALLEGRO_VOICE* voice) +{ + ALLEGRO_AQ_DATA *ex_data = voice->extra; + + if (ex_data->playing) { + _al_vector_find_and_delete(&saved_voices, &voice); + ex_data->playing = false; + + AudioQueueDispose( + ex_data->queue, + false /* Do it asynchronously so the feeder thread can exit. */ + ); + } + + return 0; +} + +/* The voice_is_playing method should only be called on non-streaming sources, + and should return true if the voice is playing */ +static bool _aqueue_voice_is_playing(const ALLEGRO_VOICE *voice) +{ + ALLEGRO_AQ_DATA *ex_data = (ALLEGRO_AQ_DATA *)voice->extra; + + return ex_data->playing; +} + +/* The get_voice_position method should return the current sample position of + the voice (sample_pos = byte_pos / (depth/8) / channels). This should never + be called on a streaming voice. */ +static unsigned int _aqueue_get_voice_position(const ALLEGRO_VOICE *voice) +{ + /* FIXME */ + (void)voice; + return 0; +} + +/* The set_voice_position method should set the voice's playback position, + given the value in samples. This should never be called on a streaming + voice. */ +static int _aqueue_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) +{ + /* FIXME */ + (void)voice; + (void)val; + return 0; +} + +typedef struct RECORDER_DATA +{ + AudioStreamBasicDescription data_format; + AudioQueueRef queue; + + /* AudioQueue buffer information */ + AudioQueueBufferRef *buffers; + int buffer_count; + uint32_t buffer_size; + + /* User fragment buffer information. + * Which buffer are we writing into, and + * how much data has already been written? + */ + unsigned int fragment_i; + unsigned int samples_written; + +} RECORDER_DATA; + +static void _aqueue_recording_callback(void *user_data, AudioQueueRef aq, + AudioQueueBufferRef aq_buffer, const AudioTimeStamp *start_time, + UInt32 sample_count, const AudioStreamPacketDescription *descs) +{ + ALLEGRO_AUDIO_RECORDER *recorder = (ALLEGRO_AUDIO_RECORDER *) user_data; + RECORDER_DATA *data = (RECORDER_DATA *) recorder->extra; + char *input = aq_buffer->mAudioData; + + (void) aq; + (void) start_time; + (void) descs; + + if (sample_count == 0 && data->data_format.mBytesPerPacket != 0) { + sample_count = aq_buffer->mAudioDataByteSize / data->data_format.mBytesPerPacket; + } + + al_lock_mutex(recorder->mutex); + + if (recorder->is_recording) { + /* Process the full buffer, putting it into as many user fragments as it needs. + * Send an event for every full user fragment. + */ + while (sample_count > 0) { + unsigned int samples_left = recorder->samples - data->samples_written; + unsigned int samples_to_write = sample_count < samples_left ? sample_count : samples_left; + + /* Copy the incoming data into the user's fragment buffer */ + memcpy((char*)recorder->fragments[data->fragment_i] + data->samples_written * recorder->sample_size, + input, samples_to_write * recorder->sample_size); + + input += samples_to_write * recorder->sample_size; + data->samples_written += samples_to_write; + sample_count -= samples_to_write; + + /* We should have never written more samples than the user asked for */ + ALLEGRO_ASSERT(recorder->samples >= data->samples_written); + + if (data->samples_written == recorder->samples) { + ALLEGRO_EVENT user_event; + ALLEGRO_AUDIO_RECORDER_EVENT *e; + user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; + e = al_get_audio_recorder_event(&user_event); + e->buffer = recorder->fragments[data->fragment_i]; + e->samples = recorder->samples; + al_emit_user_event(&recorder->source, &user_event, NULL); + + if (++data->fragment_i == recorder->fragment_count) { + data->fragment_i = 0; + } + + data->samples_written = 0; + } + } + } + + al_unlock_mutex(recorder->mutex); + + + AudioQueueEnqueueBuffer(data->queue, aq_buffer, 0, NULL); +} + +static int _aqueue_allocate_recorder(ALLEGRO_AUDIO_RECORDER *recorder) +{ + RECORDER_DATA *data; + int i; + int ret; + + data = al_calloc(1, sizeof(*data)); + if (!data) return 1; + + data->buffer_count = 3; + data->buffers = al_calloc(data->buffer_count, sizeof(AudioQueueBufferRef)); + if (!data->buffers) { + al_free(data); + return 1; + } + + data->data_format.mFormatID = kAudioFormatLinearPCM; + data->data_format.mSampleRate = recorder->frequency; + data->data_format.mChannelsPerFrame = al_get_channel_count(recorder->chan_conf); + data->data_format.mFramesPerPacket = 1; + data->data_format.mBitsPerChannel = al_get_audio_depth_size(recorder->depth) * 8; + data->data_format.mBytesPerFrame = + data->data_format.mBytesPerPacket = data->data_format.mChannelsPerFrame * al_get_audio_depth_size(recorder->depth); + + data->data_format.mFormatFlags = kLinearPCMFormatFlagIsPacked; +#ifdef ALLEGRO_BIG_ENDIAN + data->data_format.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; +#endif + if (recorder->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) + data->data_format.mFormatFlags |= kLinearPCMFormatFlagIsFloat; + else if (!(recorder->depth & ALLEGRO_AUDIO_DEPTH_UNSIGNED)) + data->data_format.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; + + data->buffer_size = 2048; // in bytes + + ret = AudioQueueNewInput( + &data->data_format, + _aqueue_recording_callback, + recorder, + NULL, + kCFRunLoopCommonModes, + 0, + &data->queue + ); + + if (ret) { + ALLEGRO_ERROR("AudioQueueNewInput failed (%d)\n", ret); + al_free(data->buffers); + al_free(data); + return 1; + } + + /* Create the buffers */ + for (i = 0; i < data->buffer_count; ++i) { + AudioQueueAllocateBuffer(data->queue, data->buffer_size, &data->buffers[i]); + AudioQueueEnqueueBuffer(data->queue, data->buffers[i], 0, NULL); + } + + AudioQueueStart(data->queue, NULL); + + recorder->extra = data; + + /* No thread is created. */ + + return 0; +} + +static void _aqueue_deallocate_recorder(ALLEGRO_AUDIO_RECORDER *recorder) +{ + RECORDER_DATA *data = (RECORDER_DATA *) recorder->extra; + + AudioQueueStop(data->queue, true); + AudioQueueDispose(data->queue, true); + + al_free(data->buffers); + al_free(data); +} + +ALLEGRO_AUDIO_DRIVER _al_kcm_aqueue_driver = { + "Apple Audio Queues", + + _aqueue_open, + _aqueue_close, + + _aqueue_allocate_voice, + _aqueue_deallocate_voice, + + _aqueue_load_voice, + _aqueue_unload_voice, + + _aqueue_start_voice, + _aqueue_stop_voice, + + _aqueue_voice_is_playing, + + _aqueue_get_voice_position, + _aqueue_set_voice_position, + + _aqueue_allocate_recorder, + _aqueue_deallocate_recorder +}; + diff --git a/allegro/addons/audio/audio.c b/allegro/addons/audio/audio.c new file mode 100644 index 00000000..73bc5dd3 --- /dev/null +++ b/allegro/addons/audio/audio.c @@ -0,0 +1,424 @@ +/** + * Originally digi.c from allegro wiki + * Original authors: KC/Milan + * + * Converted to allegro5 by Ryan Dickie + */ + + +#include <math.h> +#include <stdio.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_audio_cfg.h" + +ALLEGRO_DEBUG_CHANNEL("audio") + +void _al_set_error(int error, char* string) +{ + ALLEGRO_ERROR("%s (error code: %d)\n", string, error); +} + +ALLEGRO_AUDIO_DRIVER *_al_kcm_driver = NULL; + +#if defined(ALLEGRO_CFG_KCM_OPENAL) + extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_openal_driver; +#endif +#if defined(ALLEGRO_CFG_KCM_OPENSL) + extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_opensl_driver; +#endif +#if defined(ALLEGRO_CFG_KCM_ALSA) + extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_alsa_driver; +#endif +#if defined(ALLEGRO_CFG_KCM_OSS) + extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_oss_driver; +#endif +#if defined(ALLEGRO_CFG_KCM_DSOUND) + extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_dsound_driver; +#endif +#if defined(ALLEGRO_CFG_KCM_AQUEUE) + extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_aqueue_driver; +#endif +#if defined(ALLEGRO_CFG_KCM_PULSEAUDIO) + extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_pulseaudio_driver; +#endif +#if defined(ALLEGRO_SDL) + extern struct ALLEGRO_AUDIO_DRIVER _al_kcm_sdl_driver; +#endif + +/* Channel configuration helpers */ + +/* Function: al_get_channel_count + */ +size_t al_get_channel_count(ALLEGRO_CHANNEL_CONF conf) +{ + return (conf>>4)+(conf&0xF); +} + +/* Depth configuration helpers */ +/* Function: al_get_audio_depth_size + */ +size_t al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH depth) +{ + switch (depth) { + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_UINT8: + return sizeof(int8_t); + case ALLEGRO_AUDIO_DEPTH_INT16: + case ALLEGRO_AUDIO_DEPTH_UINT16: + return sizeof(int16_t); + case ALLEGRO_AUDIO_DEPTH_INT24: + case ALLEGRO_AUDIO_DEPTH_UINT24: + return sizeof(int32_t); + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + return sizeof(float); + default: + ASSERT(false); + return 0; + } +} + +/* FIXME: use the allegro provided helpers */ +ALLEGRO_CHANNEL_CONF _al_count_to_channel_conf(int num_channels) +{ + switch (num_channels) { + case 1: + return ALLEGRO_CHANNEL_CONF_1; + case 2: + return ALLEGRO_CHANNEL_CONF_2; + case 3: + return ALLEGRO_CHANNEL_CONF_3; + case 4: + return ALLEGRO_CHANNEL_CONF_4; + case 6: + return ALLEGRO_CHANNEL_CONF_5_1; + case 7: + return ALLEGRO_CHANNEL_CONF_6_1; + case 8: + return ALLEGRO_CHANNEL_CONF_7_1; + default: + return 0; + } +} + +/* FIXME: assumes 8-bit is unsigned, and all others are signed. */ +ALLEGRO_AUDIO_DEPTH _al_word_size_to_depth_conf(int word_size) +{ + switch (word_size) { + case 1: + return ALLEGRO_AUDIO_DEPTH_UINT8; + case 2: + return ALLEGRO_AUDIO_DEPTH_INT16; + case 3: + return ALLEGRO_AUDIO_DEPTH_INT24; + case 4: + return ALLEGRO_AUDIO_DEPTH_FLOAT32; + default: + return 0; + } +} + +/* Function: al_fill_silence + */ +void al_fill_silence(void *buf, unsigned int samples, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) +{ + size_t bytes = samples * al_get_audio_depth_size(depth) * + al_get_channel_count(chan_conf); + + switch (depth) { + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_INT16: + case ALLEGRO_AUDIO_DEPTH_INT24: + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + memset(buf, 0, bytes); + break; + case ALLEGRO_AUDIO_DEPTH_UINT8: + memset(buf, 0x80, bytes); + break; + case ALLEGRO_AUDIO_DEPTH_UINT16: + { + uint16_t *buffer = buf; + size_t n = bytes / sizeof(uint16_t); + size_t i; + + for (i = 0; i < n; i++) + buffer[i] = 0x8000; + } + break; + case ALLEGRO_AUDIO_DEPTH_UINT24: + { + uint32_t *buffer = buf; + size_t n = bytes / sizeof(uint32_t); + size_t i; + + for (i = 0; i < n; i++) + buffer[i] = 0x800000; + } + break; + default: + ASSERT(false); + break; + } +} + +static ALLEGRO_AUDIO_DRIVER_ENUM get_config_audio_driver(void) +{ + ALLEGRO_CONFIG *config = al_get_system_config(); + const char *value; + + value = al_get_config_value(config, "audio", "driver"); + if (!value || value[0] == '\0') + return ALLEGRO_AUDIO_DRIVER_AUTODETECT; + + if (0 == _al_stricmp(value, "ALSA")) + return ALLEGRO_AUDIO_DRIVER_ALSA; + + if (0 == _al_stricmp(value, "OPENAL")) + return ALLEGRO_AUDIO_DRIVER_OPENAL; + + if (0 == _al_stricmp(value, "OPENSL")) + return ALLEGRO_AUDIO_DRIVER_OPENSL; + + if (0 == _al_stricmp(value, "OSS")) + return ALLEGRO_AUDIO_DRIVER_OSS; + + if (0 == _al_stricmp(value, "PULSEAUDIO")) + return ALLEGRO_AUDIO_DRIVER_PULSEAUDIO; + + if (0 == _al_stricmp(value, "DSOUND") || 0 == _al_stricmp(value, "DIRECTSOUND")) + return ALLEGRO_AUDIO_DRIVER_DSOUND; + + return ALLEGRO_AUDIO_DRIVER_AUTODETECT; +} + +static bool do_install_audio(ALLEGRO_AUDIO_DRIVER_ENUM mode) +{ + bool retVal; + + /* check to see if a driver is already installed and running */ + if (_al_kcm_driver) { + _al_set_error(ALLEGRO_GENERIC_ERROR, "A driver already running"); + return false; + } + + if (mode == ALLEGRO_AUDIO_DRIVER_AUTODETECT) { + mode = get_config_audio_driver(); + } + + switch (mode) { + case ALLEGRO_AUDIO_DRIVER_AUTODETECT: +#if defined(ALLEGRO_SDL) + retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_SDL); + if (retVal) + return retVal; +#endif +#if defined(ALLEGRO_CFG_KCM_AQUEUE) + retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_AQUEUE); + if (retVal) + return retVal; +#endif +/* If a PA server is running, we should use it by default as it will + * hijack ALSA and OSS and using those then just means extra lag. + * + * FIXME: Detect if no PA server is running and in that case prefer + * ALSA and OSS first. + */ +#if defined(ALLEGRO_CFG_KCM_PULSEAUDIO) + retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_PULSEAUDIO); + if (retVal) + return retVal; +#endif +#if defined(ALLEGRO_CFG_KCM_ALSA) + retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_ALSA); + if (retVal) + return retVal; +#endif +#if defined(ALLEGRO_CFG_KCM_DSOUND) + retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_DSOUND); + if (retVal) + return retVal; +#endif +#if defined(ALLEGRO_CFG_KCM_OSS) + retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_OSS); + if (retVal) + return retVal; +#endif +#if defined(ALLEGRO_CFG_KCM_OPENAL) + retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_OPENAL); + if (retVal) + return retVal; +#endif +#if defined(ALLEGRO_CFG_KCM_OPENSL) + retVal = do_install_audio(ALLEGRO_AUDIO_DRIVER_OPENSL); + if (retVal) + return retVal; +#endif + + _al_set_error(ALLEGRO_INVALID_PARAM, "No audio driver can be used."); + _al_kcm_driver = NULL; + return false; + + case ALLEGRO_AUDIO_DRIVER_AQUEUE: + #if defined(ALLEGRO_CFG_KCM_AQUEUE) + if (_al_kcm_aqueue_driver.open() == 0) { + ALLEGRO_INFO("Using Apple Audio Queue driver\n"); + _al_kcm_driver = &_al_kcm_aqueue_driver; + return true; + } + return false; + #else + _al_set_error(ALLEGRO_INVALID_PARAM, "Audio Queue driver not available on this platform"); + return false; + #endif + + case ALLEGRO_AUDIO_DRIVER_OPENAL: + #if defined(ALLEGRO_CFG_KCM_OPENAL) + if (_al_kcm_openal_driver.open() == 0) { + ALLEGRO_INFO("Using OpenAL driver\n"); + _al_kcm_driver = &_al_kcm_openal_driver; + return true; + } + return false; + #else + _al_set_error(ALLEGRO_INVALID_PARAM, "OpenAL not available on this platform"); + return false; + #endif + + case ALLEGRO_AUDIO_DRIVER_OPENSL: + #if defined(ALLEGRO_CFG_KCM_OPENSL) + if (_al_kcm_opensl_driver.open() == 0) { + ALLEGRO_INFO("Using OpenSL driver\n"); + _al_kcm_driver = &_al_kcm_opensl_driver; + return true; + } + return false; + #else + _al_set_error(ALLEGRO_INVALID_PARAM, "OpenSL not available on this platform"); + return false; + #endif + + case ALLEGRO_AUDIO_DRIVER_ALSA: + #if defined(ALLEGRO_CFG_KCM_ALSA) + if (_al_kcm_alsa_driver.open() == 0) { + ALLEGRO_INFO("Using ALSA driver\n"); + _al_kcm_driver = &_al_kcm_alsa_driver; + return true; + } + return false; + #else + _al_set_error(ALLEGRO_INVALID_PARAM, "ALSA not available on this platform"); + return false; + #endif + + case ALLEGRO_AUDIO_DRIVER_OSS: + #if defined(ALLEGRO_CFG_KCM_OSS) + if (_al_kcm_oss_driver.open() == 0) { + ALLEGRO_INFO("Using OSS driver\n"); + _al_kcm_driver = &_al_kcm_oss_driver; + return true; + } + return false; + #else + _al_set_error(ALLEGRO_INVALID_PARAM, "OSS not available on this platform"); + return false; + #endif + + case ALLEGRO_AUDIO_DRIVER_PULSEAUDIO: + #if defined(ALLEGRO_CFG_KCM_PULSEAUDIO) + if (_al_kcm_pulseaudio_driver.open() == 0) { + ALLEGRO_INFO("Using PulseAudio driver\n"); + _al_kcm_driver = &_al_kcm_pulseaudio_driver; + return true; + } + return false; + #else + _al_set_error(ALLEGRO_INVALID_PARAM, "PulseAudio not available on this platform"); + return false; + #endif + + case ALLEGRO_AUDIO_DRIVER_DSOUND: + #if defined(ALLEGRO_CFG_KCM_DSOUND) + if (_al_kcm_dsound_driver.open() == 0) { + ALLEGRO_INFO("Using DirectSound driver\n"); + _al_kcm_driver = &_al_kcm_dsound_driver; + return true; + } + return false; + #else + _al_set_error(ALLEGRO_INVALID_PARAM, "DirectSound not available on this platform"); + return false; + #endif + + case ALLEGRO_AUDIO_DRIVER_SDL: + #if defined(ALLEGRO_SDL) + if (_al_kcm_sdl_driver.open() == 0) { + ALLEGRO_INFO("Using SDL driver\n"); + _al_kcm_driver = &_al_kcm_sdl_driver; + return true; + } + return false; + #else + _al_set_error(ALLEGRO_INVALID_PARAM, "SDL not available on this platform"); + return false; + #endif + + default: + _al_set_error(ALLEGRO_INVALID_PARAM, "Invalid audio driver"); + return false; + } +} + +/* Function: al_install_audio + */ +bool al_install_audio(void) +{ + bool ret; + + if (_al_kcm_driver) + return true; + + /* The destructors are initialised even if the audio driver fails to install + * because the user may still create samples. + */ + _al_kcm_init_destructors(); + _al_add_exit_func(al_uninstall_audio, "al_uninstall_audio"); + + ret = do_install_audio(ALLEGRO_AUDIO_DRIVER_AUTODETECT); + return ret; +} + +/* Function: al_uninstall_audio + */ +void al_uninstall_audio(void) +{ + if (_al_kcm_driver) { + _al_kcm_shutdown_default_mixer(); + _al_kcm_shutdown_destructors(); + _al_kcm_driver->close(); + _al_kcm_driver = NULL; + } + else { + _al_kcm_shutdown_destructors(); + } +} + +/* Function: al_is_audio_installed + */ +bool al_is_audio_installed(void) +{ + return _al_kcm_driver ? true : false; +} + +/* Function: al_get_allegro_audio_version + */ +uint32_t al_get_allegro_audio_version(void) +{ + return ALLEGRO_VERSION_INT; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/audio_io.c b/allegro/addons/audio/audio_io.c new file mode 100644 index 00000000..b519b266 --- /dev/null +++ b/allegro/addons/audio/audio_io.c @@ -0,0 +1,396 @@ +/* + * Allegro audio codec table. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_vector.h" + +ALLEGRO_DEBUG_CHANNEL("audio") + + +#define MAX_EXTENSION_LENGTH (32) + +typedef struct ACODEC_TABLE ACODEC_TABLE; +struct ACODEC_TABLE +{ + char ext[MAX_EXTENSION_LENGTH]; + ALLEGRO_SAMPLE * (*loader)(const char *filename); + bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl); + ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename, + size_t buffer_count, unsigned int samples); + + ALLEGRO_SAMPLE * (*fs_loader)(ALLEGRO_FILE *fp); + bool (*fs_saver)(ALLEGRO_FILE *fp, ALLEGRO_SAMPLE *spl); + ALLEGRO_AUDIO_STREAM *(*fs_stream_loader)(ALLEGRO_FILE *fp, + size_t buffer_count, unsigned int samples); +}; + + +/* globals */ +static bool acodec_inited = false; +static _AL_VECTOR acodec_table = _AL_VECTOR_INITIALIZER(ACODEC_TABLE); + + +static void acodec_shutdown(void) +{ + if (acodec_inited) { + _al_vector_free(&acodec_table); + acodec_inited = false; + } +} + + +static ACODEC_TABLE *find_acodec_table_entry(const char *ext) +{ + ACODEC_TABLE *ent; + unsigned i; + + if (!acodec_inited) { + acodec_inited = true; + _al_add_exit_func(acodec_shutdown, "acodec_shutdown"); + } + + for (i = 0; i < _al_vector_size(&acodec_table); i++) { + ent = _al_vector_ref(&acodec_table, i); + if (0 == _al_stricmp(ent->ext, ext)) { + return ent; + } + } + + return NULL; +} + + +static ACODEC_TABLE *add_acodec_table_entry(const char *ext) +{ + ACODEC_TABLE *ent; + + ent = _al_vector_alloc_back(&acodec_table); + strcpy(ent->ext, ext); + ent->loader = NULL; + ent->saver = NULL; + ent->stream_loader = NULL; + + ent->fs_loader = NULL; + ent->fs_saver = NULL; + ent->fs_stream_loader = NULL; + + return ent; +} + + +/* Function: al_register_sample_loader + */ +bool al_register_sample_loader(const char *ext, + ALLEGRO_SAMPLE *(*loader)(const char *filename)) +{ + ACODEC_TABLE *ent; + + if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { + return false; + } + + ent = find_acodec_table_entry(ext); + if (!loader) { + if (!ent || !ent->loader) { + return false; /* Nothing to remove. */ + } + } + else if (!ent) { + ent = add_acodec_table_entry(ext); + } + + ent->loader = loader; + + return true; +} + + +/* Function: al_register_sample_loader_f + */ +bool al_register_sample_loader_f(const char *ext, + ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE* fp)) +{ + ACODEC_TABLE *ent; + + if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { + return false; + } + + ent = find_acodec_table_entry(ext); + if (!loader) { + if (!ent || !ent->fs_loader) { + return false; /* Nothing to remove. */ + } + } + else if (!ent) { + ent = add_acodec_table_entry(ext); + } + + ent->fs_loader = loader; + + return true; +} + + +/* Function: al_register_sample_saver + */ +bool al_register_sample_saver(const char *ext, + bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl)) +{ + ACODEC_TABLE *ent; + + if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { + return false; + } + + ent = find_acodec_table_entry(ext); + if (!saver) { + if (!ent || !ent->saver) { + return false; /* Nothing to remove. */ + } + } + else if (!ent) { + ent = add_acodec_table_entry(ext); + } + + ent->saver = saver; + + return true; +} + + +/* Function: al_register_sample_saver_f + */ +bool al_register_sample_saver_f(const char *ext, + bool (*saver)(ALLEGRO_FILE* fp, ALLEGRO_SAMPLE *spl)) +{ + ACODEC_TABLE *ent; + + if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { + return false; + } + + ent = find_acodec_table_entry(ext); + if (!saver) { + if (!ent || !ent->fs_saver) { + return false; /* Nothing to remove. */ + } + } + else if (!ent) { + ent = add_acodec_table_entry(ext); + } + + ent->fs_saver = saver; + + return true; +} + + +/* Function: al_register_audio_stream_loader + */ +bool al_register_audio_stream_loader(const char *ext, + ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename, + size_t buffer_count, unsigned int samples)) +{ + ACODEC_TABLE *ent; + + if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { + return false; + } + + ent = find_acodec_table_entry(ext); + if (!stream_loader) { + if (!ent || !ent->stream_loader) { + return false; /* Nothing to remove. */ + } + } + else if (!ent) { + ent = add_acodec_table_entry(ext); + } + + ent->stream_loader = stream_loader; + + return true; +} + + +/* Function: al_register_audio_stream_loader_f + */ +bool al_register_audio_stream_loader_f(const char *ext, + ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE* fp, + size_t buffer_count, unsigned int samples)) +{ + ACODEC_TABLE *ent; + + if (strlen(ext) + 1 >= MAX_EXTENSION_LENGTH) { + return false; + } + + ent = find_acodec_table_entry(ext); + if (!stream_loader) { + if (!ent || !ent->fs_stream_loader) { + return false; /* Nothing to remove. */ + } + } + else if (!ent) { + ent = add_acodec_table_entry(ext); + } + + ent->fs_stream_loader = stream_loader; + + return true; +} + + +/* Function: al_load_sample + */ +ALLEGRO_SAMPLE *al_load_sample(const char *filename) +{ + const char *ext; + ACODEC_TABLE *ent; + + ASSERT(filename); + ext = strrchr(filename, '.'); + if (ext == NULL) { + ALLEGRO_ERROR("Unable to determine extension for %s.\n", filename); + return NULL; + } + + ent = find_acodec_table_entry(ext); + if (ent && ent->loader) { + return (ent->loader)(filename); + } + else { + ALLEGRO_ERROR("No handler for audio file extension %s - " + "therefore not trying to load %s.\n", ext, filename); + } + + return NULL; +} + + +/* Function: al_load_sample_f + */ +ALLEGRO_SAMPLE *al_load_sample_f(ALLEGRO_FILE* fp, const char *ident) +{ + ACODEC_TABLE *ent; + + ASSERT(fp); + ASSERT(ident); + + ent = find_acodec_table_entry(ident); + if (ent && ent->fs_loader) { + return (ent->fs_loader)(fp); + } + else { + ALLEGRO_ERROR("No handler for audio file extension %s.\n", ident); + } + + return NULL; +} + + +/* Function: al_load_audio_stream + */ +ALLEGRO_AUDIO_STREAM *al_load_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +{ + const char *ext; + ACODEC_TABLE *ent; + + ASSERT(filename); + ext = strrchr(filename, '.'); + if (ext == NULL) { + ALLEGRO_ERROR("Unable to determine extension for %s.\n", filename); + return NULL; + } + + ent = find_acodec_table_entry(ext); + if (ent && ent->stream_loader) { + return (ent->stream_loader)(filename, buffer_count, samples); + } + else { + ALLEGRO_ERROR("No handler for audio file extension %s - " + "therefore not trying to load %s.\n", ext, filename); + } + + return NULL; +} + + +/* Function: al_load_audio_stream_f + */ +ALLEGRO_AUDIO_STREAM *al_load_audio_stream_f(ALLEGRO_FILE* fp, const char *ident, + size_t buffer_count, unsigned int samples) +{ + ACODEC_TABLE *ent; + + ASSERT(fp); + ASSERT(ident); + + ent = find_acodec_table_entry(ident); + if (ent && ent->fs_stream_loader) { + return (ent->fs_stream_loader)(fp, buffer_count, samples); + } + else { + ALLEGRO_ERROR("No handler for audio file extension %s.\n", ident); + } + + return NULL; +} + + +/* Function: al_save_sample + */ +bool al_save_sample(const char *filename, ALLEGRO_SAMPLE *spl) +{ + const char *ext; + ACODEC_TABLE *ent; + + ASSERT(filename); + ext = strrchr(filename, '.'); + if (ext == NULL) { + ALLEGRO_ERROR("Unable to determine extension for %s.\n", filename); + return false; + } + + ent = find_acodec_table_entry(ext); + if (ent && ent->saver) { + return (ent->saver)(filename, spl); + } + else { + ALLEGRO_ERROR("No handler for audio file extension %s - " + "therefore not trying to load %s.\n", ext, filename); + } + + return false; +} + + +/* Function: al_save_sample_f + */ +bool al_save_sample_f(ALLEGRO_FILE *fp, const char *ident, ALLEGRO_SAMPLE *spl) +{ + ACODEC_TABLE *ent; + + ASSERT(fp); + ASSERT(ident); + + ent = find_acodec_table_entry(ident); + if (ent && ent->fs_saver) { + return (ent->fs_saver)(fp, spl); + } + else { + ALLEGRO_ERROR("No handler for audio file extension %s.\n", ident); + } + + return false; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/dsound.cpp b/allegro/addons/audio/dsound.cpp new file mode 100644 index 00000000..43540146 --- /dev/null +++ b/allegro/addons/audio/dsound.cpp @@ -0,0 +1,835 @@ +/* + * Based on DirectSound driver by KC/Milan + */ +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif + +#ifndef WINVER +#define WINVER 0x0501 +#endif + +#include <stdio.h> +#include <string.h> + + +#include <windows.h> +#include <dsound.h> + +/* dsound.h from the official DirectX SDK uses __null to annotate some + * function arguments. It is #defined away by a macro in sal.h, but this + * breaks GCC headers, as they also use __null (but for a different + * purpose). This pre-processor block undefines __null which returns + * __null to acting like a GCC keyword. + * This does nothing for the unofficial DirectX SDK, which has __null + * manually removed. */ +#if defined __MINGW32__ && defined __null + #undef __null +#endif + +/* I'm not sure what library this is supposed to be in, but I couldn't find it yet */ +const IID GUID_NULL = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; + +static const IID _al_IID_IDirectSoundBuffer8 = { 0x6825a449, 0x7524, 0x4d82, { 0x92, 0x0f, 0x50, 0xe3, 0x6a, 0xb3, 0xab, 0x1e } }; +static const IID _al_IID_IDirectSoundCaptureBuffer8 = { 0x00990df4, 0x0dbb, 0x4872, { 0x83, 0x3e, 0x6d, 0x30, 0x3e, 0x80, 0xae, 0xb6 } }; +#include "allegro5/allegro.h" + +extern "C" { + +ALLEGRO_DEBUG_CHANNEL("audio-dsound") + +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_system.h" + +/* This is used to stop MinGW from complaining about type-punning */ +#define MAKE_UNION(ptr, t) \ + union { \ + LPVOID *v; \ + t p; \ + } u; \ + u.p = (ptr); + +/* DirectSound vars */ +static IDirectSound8 *device; +static IDirectSoundCapture8 *capture_device; +static char ds_err_str[100]; +static int buffer_size; // in bytes + +#define MIN_BUFFER_SIZE 1024 +#define MIN_FILL 512 +#define MAX_FILL 1024 + +static HWND get_window() +{ + const char *val = al_get_config_value(al_get_system_config(), + "directsound", "window"); + HWND ret; + if (val && strncmp(val, "foreground", 10) == 0) { + ret = GetForegroundWindow(); + ALLEGRO_INFO("Using foreground window: %p\n", ret); + } + else { + ret = GetDesktopWindow(); + ALLEGRO_INFO("Using desktop window: %p\n", ret); + } + return ret; +} + +static void dsound_set_buffer_size(int bits_per_sample) +{ + int buffer_size_in_samples = 8192; // default + const char *val = al_get_config_value(al_get_system_config(), + "directsound", "buffer_size"); + if (val && val[0] != '\0') { + int n = atoi(val); + if (n < MIN_BUFFER_SIZE) + n = MIN_BUFFER_SIZE; + buffer_size_in_samples = n; + } + + buffer_size = buffer_size_in_samples * (bits_per_sample/8); +} + +static char *ds_get_error(HRESULT hr) +{ + switch (hr) { + case DSERR_ALLOCATED: + strcpy(ds_err_str, "DSERR_ALLOCATED"); + break; + case DSERR_BADFORMAT: + strcpy(ds_err_str, "DSERR_BADFORMAT"); + break; + case DSERR_BUFFERTOOSMALL: + strcpy(ds_err_str, "DSERR_BUFFERTOOSMALL"); + break; + case DSERR_CONTROLUNAVAIL: + strcpy(ds_err_str, "DSERR_CONTROLUNAVAIL"); + break; + case DSERR_DS8_REQUIRED: + strcpy(ds_err_str, "DSERR_DS8_REQUIRED"); + break; + case DSERR_INVALIDCALL: + strcpy(ds_err_str, "DSERR_INVALIDCALL"); + break; + case DSERR_INVALIDPARAM: + strcpy(ds_err_str, "DSERR_INVALIDPARAM"); + break; + case DSERR_NOAGGREGATION: + strcpy(ds_err_str, "DSERR_NOAGGREGATION"); + break; + case DSERR_OUTOFMEMORY: + strcpy(ds_err_str, "DSERR_OUTOFMEMORY"); + break; + case DSERR_UNINITIALIZED: + strcpy(ds_err_str, "DSERR_UNINITIALIZED"); + break; + case DSERR_UNSUPPORTED: + strcpy(ds_err_str, "DSERR_UNSUPPORTED"); + break; + } + + return ds_err_str; +} + + +/* Custom struct to hold voice information DirectSound needs */ +/* TODO: review */ +typedef struct ALLEGRO_DS_DATA { + int bits_per_sample; + int channels; + DSBUFFERDESC desc; + WAVEFORMATEX wave_fmt; + LPDIRECTSOUNDBUFFER ds_buffer; + LPDIRECTSOUNDBUFFER8 ds8_buffer; + int stop_voice; + ALLEGRO_THREAD *thread; +} ALLEGRO_DS_DATA; + + +static bool _dsound_voice_is_playing(const ALLEGRO_VOICE *voice); + + +/* Custom routine which runs in another thread to periodically check if DirectSound + wants more data for a stream */ +static void* _dsound_update(ALLEGRO_THREAD *self, void *arg) +{ + ALLEGRO_VOICE *voice = (ALLEGRO_VOICE *)arg; + ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA*)voice->extra; + const int bytes_per_sample = ex_data->bits_per_sample / 8; + DWORD play_cursor = 0; + DWORD write_cursor; + DWORD saved_play_cursor = 0; + unsigned int samples; + LPVOID ptr1, ptr2; + DWORD block1_bytes, block2_bytes; + unsigned char *data; + unsigned char *silence; + HRESULT hr; + (void)self; + + /* Make a buffer full of silence. */ + silence = (unsigned char *)al_malloc(buffer_size); + samples = buffer_size / bytes_per_sample / ex_data->channels; + al_fill_silence(silence, samples, voice->depth, voice->chan_conf); + + /* Fill buffer */ + hr = ex_data->ds8_buffer->Lock(0, buffer_size, + &ptr1, &block1_bytes, &ptr2, &block2_bytes, + DSBLOCK_ENTIREBUFFER); + if (!FAILED(hr)) { + unsigned int sample_bytes; + samples = buffer_size / bytes_per_sample / ex_data->channels; + data = (unsigned char *) _al_voice_update(voice, voice->mutex, &samples); + sample_bytes = samples * bytes_per_sample * ex_data->channels; + if (sample_bytes < block1_bytes) + block1_bytes = sample_bytes; + memcpy(ptr1, data, block1_bytes); + sample_bytes -= block1_bytes; + if (sample_bytes < block2_bytes) + block2_bytes = sample_bytes; + memcpy(ptr2, data + block1_bytes, block2_bytes); + ex_data->ds8_buffer->Unlock(ptr1, block1_bytes, ptr2, block2_bytes); + } + else { + ALLEGRO_ERROR("Lock failed: %s\n", ds_get_error(hr)); + } + + ex_data->ds8_buffer->Play(0, 0, DSBPLAY_LOOPING); + + do { + if (!_dsound_voice_is_playing(voice)) { + ex_data->ds8_buffer->Play(0, 0, DSBPLAY_LOOPING); + } + + ex_data->ds8_buffer->GetCurrentPosition(&play_cursor, &write_cursor); + + /* We try to fill the gap between the saved_play_cursor and the + * play_cursor. + */ + int d = play_cursor - saved_play_cursor; + if (d < 0) + d += buffer_size; + + /* Don't fill small gaps. Let it accumulate to amortise the cost of + * mixing the samples and locking/unlocking the buffer. + */ + if (d < MIN_FILL) { + al_rest(0.005); + continue; + } + + /* Don't generate too many samples at once. The buffer may underrun + * while we wait for _al_voice_update to complete. + */ + samples = d / bytes_per_sample / ex_data->channels; + if (samples > MAX_FILL) { + samples = MAX_FILL; + } + + /* Generate the samples. */ + data = (unsigned char *) _al_voice_update(voice, voice->mutex, &samples); + if (data == NULL) { + data = silence; + } + + hr = ex_data->ds8_buffer->Lock(saved_play_cursor, + samples * bytes_per_sample * ex_data->channels, + &ptr1, &block1_bytes, &ptr2, &block2_bytes, 0); + if (!FAILED(hr)) { + memcpy(ptr1, data, block1_bytes); + memcpy(ptr2, data + block1_bytes, block2_bytes); + hr = ex_data->ds8_buffer->Unlock(ptr1, block1_bytes, + ptr2, block2_bytes); + if (FAILED(hr)) { + ALLEGRO_ERROR("Unlock failed: %s\n", ds_get_error(hr)); + } + } + else { + ALLEGRO_ERROR("Lock failed: %s\n", ds_get_error(hr)); + } + saved_play_cursor += block1_bytes + block2_bytes; + saved_play_cursor %= buffer_size; + } while (!ex_data->stop_voice); + + ex_data->ds8_buffer->Stop(); + + al_free(silence); + + ex_data->stop_voice = 0; + al_broadcast_cond(voice->cond); + + return NULL; +} + + +/* The open method starts up the driver and should lock the device, using the + previously set parameters, or defaults. It shouldn't need to start sending + audio data to the device yet, however. */ +static int _dsound_open() +{ + HRESULT hr; + ALLEGRO_INFO("Starting DirectSound...\n"); + + /* FIXME: Use default device until we have device enumeration */ + hr = DirectSoundCreate8(NULL, &device, NULL); + if (FAILED(hr)) { + ALLEGRO_ERROR("DirectSoundCreate8 failed: %s\n", ds_get_error(hr)); + return 1; + } + + ALLEGRO_DEBUG("DirectSoundCreate8 succeeded\n"); + + hr = device->SetCooperativeLevel(get_window(), DSSCL_PRIORITY); + if (FAILED(hr)) { + ALLEGRO_ERROR("SetCooperativeLevel failed: %s\n", ds_get_error(hr)); + return 1; + } + + return 0; +} + + +/* The close method should close the device, freeing any resources, and allow + other processes to use the device */ +static void _dsound_close() +{ + ALLEGRO_DEBUG("Releasing device\n"); + device->Release(); + ALLEGRO_DEBUG("Released device\n"); + ALLEGRO_INFO("DirectSound closed\n"); +} + + +/* The allocate_voice method should grab a voice from the system, and allocate + any data common to streaming and non-streaming sources. */ +static int _dsound_allocate_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_DS_DATA *ex_data; + int bits_per_sample; + int channels; + + ALLEGRO_DEBUG("Allocating voice\n"); + + /* openal doesn't support very much! */ + switch (voice->depth) + { + case ALLEGRO_AUDIO_DEPTH_UINT8: + /* format supported */ + bits_per_sample = 8; + break; + case ALLEGRO_AUDIO_DEPTH_INT8: + ALLEGRO_ERROR("DirectSound requires 8-bit data to be unsigned\n"); + return 1; + case ALLEGRO_AUDIO_DEPTH_UINT16: + ALLEGRO_ERROR("DirectSound requires 16-bit data to be signed\n"); + return 1; + case ALLEGRO_AUDIO_DEPTH_INT16: + /* format supported */ + bits_per_sample = 16; + break; + case ALLEGRO_AUDIO_DEPTH_UINT24: + ALLEGRO_ERROR("DirectSound does not support 24-bit data\n"); + return 1; + case ALLEGRO_AUDIO_DEPTH_INT24: + ALLEGRO_ERROR("DirectSound does not support 24-bit data\n"); + return 1; + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + ALLEGRO_ERROR("DirectSound does not support 32-bit floating data\n"); + return 1; + default: + ALLEGRO_ERROR("Cannot allocate unknown voice depth\n"); + return 1; + } + + switch (voice->chan_conf) { + case ALLEGRO_CHANNEL_CONF_1: + channels = 1; + break; + case ALLEGRO_CHANNEL_CONF_2: + channels = 2; + break; + default: + ALLEGRO_ERROR("Unsupported number of channels\n"); + return 1; + } + + ex_data = (ALLEGRO_DS_DATA *)al_calloc(1, sizeof(*ex_data)); + if (!ex_data) { + ALLEGRO_ERROR("Could not allocate voice data memory\n"); + return 1; + } + + ex_data->bits_per_sample = bits_per_sample; + ex_data->channels = channels; + ex_data->stop_voice = 1; + + dsound_set_buffer_size(bits_per_sample); + + voice->extra = ex_data; + + ALLEGRO_DEBUG("Allocated voice\n"); + + return 0; +} + +/* The deallocate_voice method should free the resources for the given voice, + but still retain a hold on the device. The voice should be stopped and + unloaded by the time this is called */ +static void _dsound_deallocate_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_DEBUG("Deallocating voice\n"); + + al_free(voice->extra); + voice->extra = NULL; + + ALLEGRO_DEBUG("Deallocated voice\n"); +} + +/* The load_voice method loads a sample into the driver's memory. The voice's + 'streaming' field will be set to false for these voices, and it's + 'buffer_size' field will be the total length in bytes of the sample data. + The voice's attached sample's looping mode should be honored, and loading + must fail if it cannot be. */ +static int _dsound_load_voice(ALLEGRO_VOICE *voice, const void *_data) +{ + ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; + HRESULT hr; + LPVOID ptr1, ptr2; + DWORD block1_bytes, block2_bytes; + MAKE_UNION(&ex_data->ds8_buffer, LPDIRECTSOUNDBUFFER8 *); + + ALLEGRO_DEBUG("Loading voice\n"); + + ex_data->wave_fmt.wFormatTag = WAVE_FORMAT_PCM; + ex_data->wave_fmt.nChannels = ex_data->channels; + ex_data->wave_fmt.nSamplesPerSec = voice->frequency; + ex_data->wave_fmt.nBlockAlign = ex_data->channels * (ex_data->bits_per_sample/8); + ex_data->wave_fmt.nAvgBytesPerSec = ex_data->wave_fmt.nBlockAlign * voice->frequency; + ex_data->wave_fmt.wBitsPerSample = ex_data->bits_per_sample; + ex_data->wave_fmt.cbSize = 0; + + ex_data->desc.dwSize = sizeof(DSBUFFERDESC); + ex_data->desc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_GLOBALFOCUS; /* FIXME: software mixing for now */ + ex_data->desc.dwBufferBytes = voice->buffer_size; + ex_data->desc.dwReserved = 0; + ex_data->desc.lpwfxFormat = &ex_data->wave_fmt; + ex_data->desc.guid3DAlgorithm = DS3DALG_DEFAULT; + + hr = device->CreateSoundBuffer(&ex_data->desc, &ex_data->ds_buffer, NULL); + if (FAILED(hr)) { + ALLEGRO_ERROR("CreateSoundBuffer failed: %s\n", ds_get_error(hr)); + return 1; + } + + ex_data->ds_buffer->QueryInterface(_al_IID_IDirectSoundBuffer8, u.v); + + hr = ex_data->ds8_buffer->Lock(0, voice->buffer_size, + &ptr1, &block1_bytes, &ptr2, &block2_bytes, 0); + if (FAILED(hr)) { + ALLEGRO_ERROR("Locking buffer failed: %s\n", ds_get_error(hr)); + return 1; + } + + unsigned char *data = (unsigned char *) _data; + memcpy(ptr1, data, block1_bytes); + memcpy(ptr2, data + block1_bytes, block2_bytes); + + ex_data->ds8_buffer->Unlock(ptr1, block1_bytes, ptr2, block2_bytes); + + return 0; +} + +/* The unload_voice method unloads a sample previously loaded with load_voice. + This method should not be called on a streaming voice. */ +static void _dsound_unload_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; + + ALLEGRO_DEBUG("Unloading voice\n"); + + ex_data->ds8_buffer->Release(); + + ALLEGRO_DEBUG("Unloaded voice\n"); +} + + +/* The start_voice should, surprise, start the voice. For streaming voices, it + should start polling the device and call _al_voice_update for audio data. + For non-streaming voices, it should resume playing from the last set + position */ +static int _dsound_start_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; + HRESULT hr; + MAKE_UNION(&ex_data->ds8_buffer, LPDIRECTSOUNDBUFFER8 *); + + ALLEGRO_DEBUG("Starting voice\n"); + + if (!voice->is_streaming) { + hr = ex_data->ds8_buffer->Play(0, 0, 0); + if (FAILED(hr)) { + ALLEGRO_ERROR("Streaming voice failed to start: %s\n", ds_get_error(hr)); + return 1; + } + ALLEGRO_INFO("Streaming voice started\n"); + return 0; + } + + if (ex_data->stop_voice != 0) { + ex_data->wave_fmt.wFormatTag = WAVE_FORMAT_PCM; + ex_data->wave_fmt.nChannels = ex_data->channels; + ex_data->wave_fmt.nSamplesPerSec = voice->frequency; + ex_data->wave_fmt.nBlockAlign = ex_data->channels * (ex_data->bits_per_sample/8); + ex_data->wave_fmt.nAvgBytesPerSec = ex_data->wave_fmt.nBlockAlign * voice->frequency; + ex_data->wave_fmt.wBitsPerSample = ex_data->bits_per_sample; + ex_data->wave_fmt.cbSize = 0; + + ex_data->desc.dwSize = sizeof(DSBUFFERDESC); + ex_data->desc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_GLOBALFOCUS; /* FIXME: software mixing for now */ + ex_data->desc.dwBufferBytes = buffer_size; + ex_data->desc.dwReserved = 0; + ex_data->desc.lpwfxFormat = &ex_data->wave_fmt; + ex_data->desc.guid3DAlgorithm = DS3DALG_DEFAULT; + + ALLEGRO_DEBUG("CreateSoundBuffer\n"); + + hr = device->CreateSoundBuffer(&ex_data->desc, &ex_data->ds_buffer, NULL); + if (FAILED(hr)) { + ALLEGRO_ERROR("CreateSoundBuffer failed: %s\n", ds_get_error(hr)); + return 1; + } + + ALLEGRO_DEBUG("CreateSoundBuffer succeeded\n"); + + ex_data->ds_buffer->QueryInterface(_al_IID_IDirectSoundBuffer8, u.v); + + ex_data->ds8_buffer->SetVolume(DSBVOLUME_MAX); + + ALLEGRO_DEBUG("Starting _dsound_update thread\n"); + + ex_data->stop_voice = 0; + ex_data->thread = al_create_thread(_dsound_update, (void*) voice); + al_start_thread(ex_data->thread); + } + else { + ALLEGRO_WARN("stop_voice == 0\n"); + } + + ALLEGRO_INFO("Voice started\n"); + return 0; +} + +/* The stop_voice method should stop playback. For non-streaming voices, it + should leave the data loaded, and reset the voice position to 0. */ +static int _dsound_stop_voice(ALLEGRO_VOICE* voice) +{ + ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; + + ALLEGRO_DEBUG("Stopping voice\n"); + + if (!ex_data->ds8_buffer) { + ALLEGRO_ERROR("Trying to stop empty voice buffer\n"); + return 1; + } + + /* if playing a sample */ + if (!voice->is_streaming) { + ALLEGRO_DEBUG("Stopping non-streaming voice\n"); + ex_data->ds8_buffer->Stop(); + ex_data->ds8_buffer->SetCurrentPosition(0); + ALLEGRO_INFO("Non-streaming voice stopped\n"); + return 0; + } + + if (ex_data->stop_voice == 0) { + ALLEGRO_DEBUG("Joining thread\n"); + ex_data->stop_voice = 1; + while (ex_data->stop_voice == 1) { + al_wait_cond(voice->cond, voice->mutex); + } + al_join_thread(ex_data->thread, NULL); + ALLEGRO_DEBUG("Joined thread\n"); + + ALLEGRO_DEBUG("Destroying thread\n"); + al_destroy_thread(ex_data->thread); + ALLEGRO_DEBUG("Thread destroyed\n"); + /* This is required to restart the background thread when the voice + * restarts. + */ + ex_data->stop_voice = 1; + } + + ALLEGRO_DEBUG("Releasing buffer\n"); + ex_data->ds8_buffer->Release(); + ex_data->ds8_buffer = NULL; + + ALLEGRO_INFO("Voice stopped\n"); + return 0; +} + +/* The voice_is_playing method should only be called on non-streaming sources, + and should return true if the voice is playing */ +static bool _dsound_voice_is_playing(const ALLEGRO_VOICE *voice) +{ + ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; + DWORD status; + + if (!ex_data) { + ALLEGRO_WARN("ex_data is null\n"); + return false; + } + + ex_data->ds8_buffer->GetStatus(&status); + + return (status & DSBSTATUS_PLAYING); +} + +/* The get_voice_position method should return the current sample position of + the voice (sample_pos = byte_pos / (depth/8) / channels). This should never + be called on a streaming voice. */ +static unsigned int _dsound_get_voice_position(const ALLEGRO_VOICE *voice) +{ + ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; + DWORD play_pos; + HRESULT hr; + + hr = ex_data->ds8_buffer->GetCurrentPosition(&play_pos, NULL); + if (FAILED(hr)) { + ALLEGRO_ERROR("GetCurrentPosition failed: %s\n", ds_get_error(hr)); + return 0; + } + + return play_pos / (ex_data->channels * (ex_data->bits_per_sample/8)); +} + +/* The set_voice_position method should set the voice's playback position, + given the value in samples. This should never be called on a streaming + voice. */ +static int _dsound_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) +{ + ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra; + HRESULT hr; + + val *= ex_data->channels * (ex_data->bits_per_sample/8); + + hr = ex_data->ds8_buffer->SetCurrentPosition(val); + if (FAILED(hr)) { + ALLEGRO_ERROR("SetCurrentPosition failed: %s\n", ds_get_error(hr)); + return 1; + } + + return 0; +} + +typedef struct DSOUND_RECORD_DATA { + LPDIRECTSOUNDCAPTUREBUFFER buffer; + LPDIRECTSOUNDCAPTUREBUFFER8 buffer8; + DSCBUFFERDESC desc; + WAVEFORMATEX wave_fmt; +} DSOUND_RECORD_DATA; + +static void *_dsound_update_recorder(ALLEGRO_THREAD *t, void *data) +{ + ALLEGRO_AUDIO_RECORDER *r = (ALLEGRO_AUDIO_RECORDER *) data; + DSOUND_RECORD_DATA *extra = (DSOUND_RECORD_DATA *) r->extra; + DWORD last_read_pos = 0; + ALLEGRO_EVENT user_event; + bool is_dsound_recording = false; + + size_t fragment_i = 0; + size_t bytes_written = 0; + + ALLEGRO_INFO("Starting recorder thread\n"); + + while (!al_get_thread_should_stop(t)) { + al_lock_mutex(r->mutex); + while (!r->is_recording) { + if (is_dsound_recording) { + extra->buffer8->Stop(); + is_dsound_recording = false; + } + al_wait_cond(r->cond, r->mutex); + if (al_get_thread_should_stop(t)) + goto stop_recording; + } + + if (!is_dsound_recording) { + extra->buffer8->Start(DSCBSTART_LOOPING); + is_dsound_recording = true; + extra->buffer8->GetCurrentPosition(NULL, &last_read_pos); + } + + void *buffer1, *buffer2; + DWORD buffer1_size, buffer2_size; + DWORD cap_pos, bytes_to_read; + + extra->buffer8->GetCurrentPosition(NULL, &cap_pos); + + /* never read past the end of the buffer; that way buffer2 is always NULL */ + if (last_read_pos <= cap_pos) + bytes_to_read = cap_pos - last_read_pos; + else + bytes_to_read = extra->desc.dwBufferBytes - last_read_pos; + + if (bytes_to_read) { + uint8_t *buffer; + size_t buffer_size; + + extra->buffer8->Lock(last_read_pos, bytes_to_read, &buffer1, &buffer1_size, &buffer2, &buffer2_size, 0); + + ALLEGRO_ASSERT(buffer2 == NULL); + + buffer = (uint8_t *)buffer1; + buffer_size = buffer1_size; + + while (buffer_size > 0) { + if (bytes_written + buffer_size <= r->fragment_size) { + memcpy((uint8_t*) r->fragments[fragment_i] + bytes_written, buffer, buffer_size); + bytes_written += buffer_size; + buffer_size = 0; + } + else { + ALLEGRO_AUDIO_RECORDER_EVENT *e; + size_t bytes_to_write = r->fragment_size - bytes_written; + memcpy((uint8_t*) r->fragments[fragment_i] + bytes_written, buffer, bytes_to_write); + + buffer_size -= bytes_to_write; + buffer += bytes_to_write; + + user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; + e = al_get_audio_recorder_event(&user_event); + e->buffer = r->fragments[fragment_i]; + e->samples = r->samples; + al_emit_user_event(&r->source, &user_event, NULL); + + /* advance to the next fragment */ + if (++fragment_i == r->fragment_count) { + fragment_i = 0; + } + bytes_written = 0; + } + } + + extra->buffer8->Unlock(buffer1, buffer1_size, buffer2, buffer2_size); + + /* advanced the last read position */ + last_read_pos += bytes_to_read; + if (last_read_pos >= extra->desc.dwBufferBytes) + last_read_pos -= extra->desc.dwBufferBytes; + } + + al_unlock_mutex(r->mutex); + al_rest(0.10); + } + +stop_recording: + + if (is_dsound_recording) { + extra->buffer8->Stop(); + } + + ALLEGRO_INFO("Leaving recorder thread\n"); + + return NULL; +} + +static int _dsound_open_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + HRESULT hr; + + if (capture_device != NULL) { + /* FIXME: It's wrong to assume only a single recording device, but since + there is no enumeration of devices, it doesn't matter for now. */ + ALLEGRO_ERROR("Already recording.\n"); + return 1; + } + + ALLEGRO_INFO("Creating default capture device.\n"); + + /* FIXME: Use default device until we have device enumeration */ + hr = DirectSoundCaptureCreate8(NULL, &capture_device, NULL); + if (FAILED(hr)) { + ALLEGRO_ERROR("DirectSoundCaptureCreate8 failed: %s\n", ds_get_error(hr)); + return 1; + } + + hr = device->SetCooperativeLevel(get_window(), DSSCL_PRIORITY); + if (FAILED(hr)) { + ALLEGRO_ERROR("SetCooperativeLevel failed: %s\n", ds_get_error(hr)); + return 1; + } + + DSOUND_RECORD_DATA *extra = (DSOUND_RECORD_DATA *) al_calloc(1, sizeof(*extra)); + + DSCCAPS dsccaps; + dsccaps.dwSize = sizeof(DSCCAPS); + hr = capture_device->GetCaps(&dsccaps); + if (FAILED(hr)) { + ALLEGRO_ERROR("DirectSoundCaptureCreate8::GetCaps failed: %s\n", ds_get_error(hr)); + } + else { + ALLEGRO_INFO("caps: %lu %lu\n", dsccaps.dwFormats, dsccaps.dwFormats & WAVE_FORMAT_2M16); + } + + memset(&extra->wave_fmt, 0, sizeof(extra->wave_fmt)); + extra->wave_fmt.wFormatTag = WAVE_FORMAT_PCM; + extra->wave_fmt.nChannels = (WORD)al_get_channel_count(r->chan_conf); + extra->wave_fmt.nSamplesPerSec = r->frequency; + extra->wave_fmt.wBitsPerSample = (WORD)al_get_audio_depth_size(r->depth) * 8; + extra->wave_fmt.nBlockAlign = extra->wave_fmt.nChannels * extra->wave_fmt.wBitsPerSample / 8; + extra->wave_fmt.nAvgBytesPerSec = extra->wave_fmt.nSamplesPerSec * extra->wave_fmt.nBlockAlign; + + memset(&extra->desc, 0, sizeof(extra->desc)); + extra->desc.dwSize = sizeof(extra->desc); + extra->desc.lpwfxFormat = &extra->wave_fmt; + extra->desc.dwBufferBytes = extra->wave_fmt.nAvgBytesPerSec * 5; + + hr = capture_device->CreateCaptureBuffer(&extra->desc, &extra->buffer, NULL); + if (FAILED(hr)) { + al_free(extra); + ALLEGRO_ERROR("Unable to create Capture Buffer\n"); + return 1; + } + + extra->buffer->QueryInterface(_al_IID_IDirectSoundCaptureBuffer8, (void **) &extra->buffer8); + + r->extra = extra; + r->thread = al_create_thread(_dsound_update_recorder, r); + + return 0; +} + +void _dsound_close_recorder(ALLEGRO_AUDIO_RECORDER *r) { + ALLEGRO_ASSERT(capture_device); + (void) r; + + capture_device->Release(); + capture_device = NULL; +} + +ALLEGRO_AUDIO_DRIVER _al_kcm_dsound_driver = { + "DirectSound", + + _dsound_open, + _dsound_close, + + _dsound_allocate_voice, + _dsound_deallocate_voice, + + _dsound_load_voice, + _dsound_unload_voice, + + _dsound_start_voice, + _dsound_stop_voice, + + _dsound_voice_is_playing, + + _dsound_get_voice_position, + _dsound_set_voice_position, + + _dsound_open_recorder, + _dsound_close_recorder +}; + +} /* End extern "C" */ + diff --git a/allegro/addons/audio/kcm_dtor.c b/allegro/addons/audio/kcm_dtor.c new file mode 100644 index 00000000..030ff16e --- /dev/null +++ b/allegro/addons/audio/kcm_dtor.c @@ -0,0 +1,83 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Destructors. + * + * By Peter Wang. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/internal/aintern_audio.h" + + +static _AL_DTOR_LIST *kcm_dtors = NULL; + + +/* _al_kcm_init_destructors: + * Initialise the destructor list. + */ +void _al_kcm_init_destructors(void) +{ + if (!kcm_dtors) { + kcm_dtors = _al_init_destructors(); + } +} + + +/* _al_kcm_shutdown_destructors: + * Run all destructors and free the destructor list. + */ +void _al_kcm_shutdown_destructors(void) +{ + if (kcm_dtors) { + _al_run_destructors(kcm_dtors); + _al_shutdown_destructors(kcm_dtors); + kcm_dtors = NULL; + } +} + + +/* _al_kcm_register_destructor: + * Register an object to be destroyed. + */ +_AL_LIST_ITEM *_al_kcm_register_destructor(char const *name, void *object, + void (*func)(void*)) +{ + return _al_register_destructor(kcm_dtors, name, object, func); +} + + +/* _al_kcm_unregister_destructor: + * Unregister an object to be destroyed. + */ +void _al_kcm_unregister_destructor(_AL_LIST_ITEM *dtor_item) +{ + _al_unregister_destructor(kcm_dtors, dtor_item); +} + + +/* _al_kcm_foreach_destructor: + * Call the callback for each registered object. + */ +void _al_kcm_foreach_destructor( + void (*callback)(void *object, void (*func)(void *), void *udata), + void *userdata) +{ + _al_foreach_destructor(kcm_dtors, callback, userdata); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/kcm_instance.c b/allegro/addons/audio/kcm_instance.c new file mode 100644 index 00000000..92a0c879 --- /dev/null +++ b/allegro/addons/audio/kcm_instance.c @@ -0,0 +1,690 @@ +/** + * Originally digi.c from allegro wiki + * Original authors: KC/Milan + * + * Converted to allegro5 by Ryan Dickie + */ + +/* Title: Sample Instance functions + */ + +#include <math.h> +#include <stdio.h> + +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_audio_cfg.h" + + +static void maybe_lock_mutex(ALLEGRO_MUTEX *mutex) +{ + if (mutex) { + al_lock_mutex(mutex); + } +} + + +static void maybe_unlock_mutex(ALLEGRO_MUTEX *mutex) +{ + if (mutex) { + al_unlock_mutex(mutex); + } +} + + +/* _al_kcm_stream_set_mutex: + * This function sets a sample's mutex pointer to the specified value. It is + * ALLEGRO_MIXER aware, and will recursively set any attached streams' mutex + * to the same value. + */ +void _al_kcm_stream_set_mutex(ALLEGRO_SAMPLE_INSTANCE *stream, ALLEGRO_MUTEX *mutex) +{ + ASSERT(stream); + + if (stream->mutex == mutex) + return; + stream->mutex = mutex; + + /* If this is a mixer, we need to make sure all the attached streams also + * set the same mutex. + */ + if (stream->is_mixer) { + ALLEGRO_MIXER *mixer = (ALLEGRO_MIXER *)stream; + int i; + + for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { + ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); + ALLEGRO_SAMPLE_INSTANCE *spl = *slot; + _al_kcm_stream_set_mutex(spl, mutex); + } + } +} + + +/* stream_free: + * This function is ALLEGRO_MIXER aware and frees the memory associated with + * the sample or mixer, and detaches any attached streams or mixers. + */ +static void stream_free(ALLEGRO_SAMPLE_INSTANCE *spl) +{ + if (spl) { + /* Make sure we free the mixer buffer and de-reference the attached + * streams if this is a mixer stream. + */ + if (spl->is_mixer) { + ALLEGRO_MIXER *mixer = (ALLEGRO_MIXER *)spl; + int i; + + _al_kcm_stream_set_mutex(&mixer->ss, NULL); + + for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { + ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); + ALLEGRO_SAMPLE_INSTANCE *spl = *slot; + + spl->parent.u.ptr = NULL; + spl->spl_read = NULL; + al_free(spl->matrix); + spl->matrix = NULL; + } + + _al_vector_free(&mixer->streams); + + if (spl->spl_data.buffer.ptr) { + ASSERT(spl->spl_data.free_buf); + al_free(spl->spl_data.buffer.ptr); + spl->spl_data.buffer.ptr = NULL; + } + spl->spl_data.free_buf = false; + } + + ASSERT(! spl->spl_data.free_buf); + + al_free(spl); + } +} + + +/* _al_kcm_detach_from_parent: + * This detaches the sample, stream, or mixer from anything it may be attached + * to. + */ +void _al_kcm_detach_from_parent(ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ALLEGRO_MIXER *mixer; + int i; + + if (!spl || !spl->parent.u.ptr) + return; + + if (spl->parent.is_voice) { + al_detach_voice(spl->parent.u.voice); + return; + } + + mixer = spl->parent.u.mixer; + + /* Search through the streams and check for this one */ + for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { + ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); + + if (*slot == spl) { + maybe_lock_mutex(mixer->ss.mutex); + + _al_vector_delete_at(&mixer->streams, i); + spl->parent.u.mixer = NULL; + _al_kcm_stream_set_mutex(spl, NULL); + + spl->spl_read = NULL; + + maybe_unlock_mutex(mixer->ss.mutex); + + break; + } + } + + al_free(spl->matrix); + spl->matrix = NULL; +} + + +/* Function: al_create_sample_instance + */ +ALLEGRO_SAMPLE_INSTANCE *al_create_sample_instance(ALLEGRO_SAMPLE *sample_data) +{ + ALLEGRO_SAMPLE_INSTANCE *spl; + + spl = al_calloc(1, sizeof(*spl)); + if (!spl) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Out of memory allocating sample object"); + return NULL; + } + + if (sample_data) { + spl->spl_data = *sample_data; + } + spl->spl_data.free_buf = false; + + spl->loop = ALLEGRO_PLAYMODE_ONCE; + spl->speed = 1.0f; + spl->gain = 1.0f; + spl->pan = 0.0f; + spl->pos = 0; + spl->loop_start = 0; + spl->loop_end = sample_data ? sample_data->len : 0; + spl->step = 0; + + spl->matrix = NULL; + + spl->is_mixer = false; + spl->spl_read = NULL; + + spl->mutex = NULL; + spl->parent.u.ptr = NULL; + + spl->dtor_item = _al_kcm_register_destructor("sample_instance", spl, + (void (*)(void *))al_destroy_sample_instance); + + return spl; +} + + +/* This function is ALLEGRO_MIXER aware */ +/* Function: al_destroy_sample_instance + */ +void al_destroy_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) +{ + _al_kcm_destroy_sample(spl, true); +} + + +/* Internal function: _al_kcm_destroy_sample + */ +void _al_kcm_destroy_sample(ALLEGRO_SAMPLE_INSTANCE *spl, bool unregister) +{ + if (spl) { + if (unregister) { + _al_kcm_unregister_destructor(spl->dtor_item); + } + + _al_kcm_detach_from_parent(spl); + stream_free(spl); + } +} + + +/* Function: al_play_sample_instance + */ +bool al_play_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return al_set_sample_instance_playing(spl, true); +} + + +/* Function: al_stop_sample_instance + */ +bool al_stop_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return al_set_sample_instance_playing(spl, false); +} + + +/* Function: al_get_sample_instance_frequency + */ +unsigned int al_get_sample_instance_frequency(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return spl->spl_data.frequency; +} + + +/* Function: al_get_sample_instance_length + */ +unsigned int al_get_sample_instance_length(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return spl->spl_data.len; +} + + +/* Function: al_get_sample_instance_position + */ +unsigned int al_get_sample_instance_position(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + if (spl->parent.u.ptr && spl->parent.is_voice) { + ALLEGRO_VOICE *voice = spl->parent.u.voice; + return al_get_voice_position(voice); + } + + return spl->pos; +} + + +/* Function: al_get_sample_instance_speed + */ +float al_get_sample_instance_speed(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return spl->speed; +} + + +/* Function: al_get_sample_instance_gain + */ +float al_get_sample_instance_gain(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return spl->gain; +} + + +/* Function: al_get_sample_instance_pan + */ +float al_get_sample_instance_pan(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return spl->pan; +} + + +/* Function: al_get_sample_instance_time + */ +float al_get_sample_instance_time(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return (float)(spl->spl_data.len) + / (float)spl->spl_data.frequency; +} + + +/* Function: al_get_sample_instance_depth + */ +ALLEGRO_AUDIO_DEPTH al_get_sample_instance_depth(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return spl->spl_data.depth; +} + + +/* Function: al_get_sample_instance_channels + */ +ALLEGRO_CHANNEL_CONF al_get_sample_instance_channels( + const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return spl->spl_data.chan_conf; +} + + +/* Function: al_get_sample_instance_playmode + */ +ALLEGRO_PLAYMODE al_get_sample_instance_playmode(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return spl->loop; +} + + +/* Function: al_get_sample_instance_playing + */ +bool al_get_sample_instance_playing(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + if (spl->parent.u.ptr && spl->parent.is_voice) { + ALLEGRO_VOICE *voice = spl->parent.u.voice; + return al_get_voice_playing(voice); + } + + return spl->is_playing; +} + + +/* Function: al_get_sample_instance_attached + */ +bool al_get_sample_instance_attached(const ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return (spl->parent.u.ptr != NULL); +} + + +/* Function: al_set_sample_instance_position + */ +bool al_set_sample_instance_position(ALLEGRO_SAMPLE_INSTANCE *spl, + unsigned int val) +{ + ASSERT(spl); + + if (spl->parent.u.ptr && spl->parent.is_voice) { + ALLEGRO_VOICE *voice = spl->parent.u.voice; + if (!al_set_voice_position(voice, val)) + return false; + } + else { + maybe_lock_mutex(spl->mutex); + spl->pos = val; + maybe_unlock_mutex(spl->mutex); + } + + return true; +} + + +/* Function: al_set_sample_instance_length + */ +bool al_set_sample_instance_length(ALLEGRO_SAMPLE_INSTANCE *spl, + unsigned int val) +{ + ASSERT(spl); + + if (spl->is_playing) { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to change the length of a playing sample"); + return false; + } + + spl->spl_data.len = val; + spl->loop_end = val; + return true; +} + + +/* Function: al_set_sample_instance_speed + */ +bool al_set_sample_instance_speed(ALLEGRO_SAMPLE_INSTANCE *spl, float val) +{ + ASSERT(spl); + + if (fabsf(val) < (1.0f/64.0f)) { + _al_set_error(ALLEGRO_INVALID_PARAM, + "Attempted to set zero speed"); + return false; + } + + if (spl->parent.u.ptr && spl->parent.is_voice) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Could not set voice playback speed"); + return false; + } + + spl->speed = val; + if (spl->parent.u.mixer) { + ALLEGRO_MIXER *mixer = spl->parent.u.mixer; + + maybe_lock_mutex(spl->mutex); + + spl->step = (spl->spl_data.frequency) * spl->speed; + spl->step_denom = mixer->ss.spl_data.frequency; + /* Don't wanna be trapped with a step value of 0 */ + if (spl->step == 0) { + if (spl->speed > 0.0f) + spl->step = 1; + else + spl->step = -1; + } + + maybe_unlock_mutex(spl->mutex); + } + + return true; +} + + +/* Function: al_set_sample_instance_gain + */ +bool al_set_sample_instance_gain(ALLEGRO_SAMPLE_INSTANCE *spl, float val) +{ + ASSERT(spl); + + if (spl->parent.u.ptr && spl->parent.is_voice) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Could not set gain of sample attached to voice"); + return false; + } + + if (spl->gain != val) { + spl->gain = val; + + /* If attached to a mixer already, need to recompute the sample + * matrix to take into account the gain. + */ + if (spl->parent.u.mixer) { + ALLEGRO_MIXER *mixer = spl->parent.u.mixer; + + maybe_lock_mutex(spl->mutex); + _al_kcm_mixer_rejig_sample_matrix(mixer, spl); + maybe_unlock_mutex(spl->mutex); + } + } + + return true; +} + + +/* Function: al_set_sample_instance_pan + */ +bool al_set_sample_instance_pan(ALLEGRO_SAMPLE_INSTANCE *spl, float val) +{ + ASSERT(spl); + + if (spl->parent.u.ptr && spl->parent.is_voice) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Could not set panning of sample attached to voice"); + return false; + } + if (val != ALLEGRO_AUDIO_PAN_NONE && (val < -1.0 || val > 1.0)) { + _al_set_error(ALLEGRO_GENERIC_ERROR, "Invalid pan value"); + return false; + } + + if (spl->pan != val) { + spl->pan = val; + + /* If attached to a mixer already, need to recompute the sample + * matrix to take into account the panning. + */ + if (spl->parent.u.mixer) { + ALLEGRO_MIXER *mixer = spl->parent.u.mixer; + + maybe_lock_mutex(spl->mutex); + _al_kcm_mixer_rejig_sample_matrix(mixer, spl); + maybe_unlock_mutex(spl->mutex); + } + } + + return true; +} + + +/* Function: al_set_sample_instance_playmode + */ +bool al_set_sample_instance_playmode(ALLEGRO_SAMPLE_INSTANCE *spl, + ALLEGRO_PLAYMODE val) +{ + ASSERT(spl); + + if (val < ALLEGRO_PLAYMODE_ONCE || val > ALLEGRO_PLAYMODE_BIDIR) { + _al_set_error(ALLEGRO_INVALID_PARAM, + "Invalid loop mode"); + return false; + } + + maybe_lock_mutex(spl->mutex); + + spl->loop = val; + if (spl->loop != ALLEGRO_PLAYMODE_ONCE) { + if (spl->pos < spl->loop_start) + spl->pos = spl->loop_start; + else if (spl->pos > spl->loop_end-1) + spl->pos = spl->loop_end-1; + } + + maybe_unlock_mutex(spl->mutex); + + return true; +} + + +/* Function: al_set_sample_instance_playing + */ +bool al_set_sample_instance_playing(ALLEGRO_SAMPLE_INSTANCE *spl, bool val) +{ + ASSERT(spl); + + if (!spl->parent.u.ptr || !spl->spl_data.buffer.ptr) { + spl->is_playing = val; + return true; + } + + if (spl->parent.is_voice) { + /* parent is voice */ + ALLEGRO_VOICE *voice = spl->parent.u.voice; + + return al_set_voice_playing(voice, val); + } + + /* parent is mixer */ + maybe_lock_mutex(spl->mutex); + spl->is_playing = val; + if (!val) + spl->pos = 0; + maybe_unlock_mutex(spl->mutex); + return true; +} + + +/* Function: al_detach_sample_instance + */ +bool al_detach_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + _al_kcm_detach_from_parent(spl); + ASSERT(spl->spl_read == NULL); + return true; +} + + +/* Function: al_set_sample + */ +bool al_set_sample(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data) +{ + sample_parent_t old_parent; + bool need_reattach; + + ASSERT(spl); + + /* Stop the sample if it is playing. */ + if (spl->is_playing) { + if (!al_set_sample_instance_playing(spl, false)) { + /* Shouldn't happen. */ + ASSERT(false); + return false; + } + } + + if (!data) { + if (spl->parent.u.ptr) { + _al_kcm_detach_from_parent(spl); + } + spl->spl_data.buffer.ptr = NULL; + return true; + } + + /* Have data. */ + + need_reattach = false; + if (spl->parent.u.ptr != NULL) { + if (spl->spl_data.frequency != data->frequency || + spl->spl_data.depth != data->depth || + spl->spl_data.chan_conf != data->chan_conf) { + old_parent = spl->parent; + need_reattach = true; + _al_kcm_detach_from_parent(spl); + } + } + + spl->spl_data = *data; + spl->spl_data.free_buf = false; + spl->pos = 0; + spl->loop_start = 0; + spl->loop_end = data->len; + /* Should we reset the loop mode? */ + + if (need_reattach) { + if (old_parent.is_voice) { + if (!al_attach_sample_instance_to_voice(spl, old_parent.u.voice)) { + spl->spl_data.buffer.ptr = NULL; + return false; + } + } + else { + if (!al_attach_sample_instance_to_mixer(spl, old_parent.u.mixer)) { + spl->spl_data.buffer.ptr = NULL; + return false; + } + } + } + + return true; +} + + +/* Function: al_get_sample + */ +ALLEGRO_SAMPLE *al_get_sample(ALLEGRO_SAMPLE_INSTANCE *spl) +{ + ASSERT(spl); + + return &(spl->spl_data); +} + + +/* Function: al_set_sample_instance_channel_matrix + */ +bool al_set_sample_instance_channel_matrix(ALLEGRO_SAMPLE_INSTANCE *spl, const float *matrix) +{ + ASSERT(spl); + ASSERT(matrix); + + if (spl->parent.u.ptr && spl->parent.is_voice) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Could not set channel matrix of sample attached to voice"); + return false; + } + + if (spl->parent.u.mixer) { + ALLEGRO_MIXER *mixer = spl->parent.u.mixer; + size_t dst_chans = al_get_channel_count(mixer->ss.spl_data.chan_conf); + size_t src_chans = al_get_channel_count(spl->spl_data.chan_conf); + ASSERT(spl->matrix); + + maybe_lock_mutex(spl->mutex); + + memcpy(spl->matrix, matrix, dst_chans * src_chans * sizeof(float)); + + maybe_unlock_mutex(spl->mutex); + } + + return true; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/kcm_mixer.c b/allegro/addons/audio/kcm_mixer.c new file mode 100644 index 00000000..f53a25b8 --- /dev/null +++ b/allegro/addons/audio/kcm_mixer.c @@ -0,0 +1,1021 @@ +/** + * Originally digi.c from allegro wiki + * Original authors: KC/Milan + * + * Converted to allegro5 by Ryan Dickie + */ + +/* Title: Mixer functions + */ + +#include <math.h> +#include <stdio.h> + +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_audio_cfg.h" + +ALLEGRO_DEBUG_CHANNEL("audio") + + +typedef union { + float f32[ALLEGRO_MAX_CHANNELS]; /* max: 7.1 */ + int16_t s16[ALLEGRO_MAX_CHANNELS]; + void *ptr; +} SAMP_BUF; + + + +static void maybe_lock_mutex(ALLEGRO_MUTEX *mutex) +{ + if (mutex) { + al_lock_mutex(mutex); + } +} + + +static void maybe_unlock_mutex(ALLEGRO_MUTEX *mutex) +{ + if (mutex) { + al_unlock_mutex(mutex); + } +} + + +/* _al_rechannel_matrix: + * This function provides a (temporary!) matrix that can be used to convert + * one channel configuration into another. + * + * Returns a pointer to a statically allocated array. + */ +static float *_al_rechannel_matrix(ALLEGRO_CHANNEL_CONF orig, + ALLEGRO_CHANNEL_CONF target, float gain, float pan) +{ + /* Max 7.1 (8 channels) for input and output */ + static float mat[ALLEGRO_MAX_CHANNELS][ALLEGRO_MAX_CHANNELS]; + + size_t dst_chans = al_get_channel_count(target); + size_t src_chans = al_get_channel_count(orig); + size_t i, j; + + /* Start with a simple identity matrix */ + memset(mat, 0, sizeof(mat)); + for (i = 0; i < src_chans && i < dst_chans; i++) { + mat[i][i] = 1.0; + } + + /* Multi-channel -> mono conversion (cuts rear/side channels) */ + if (dst_chans == 1 && (orig>>4) > 1) { + for (i = 0; i < 2; i++) { + mat[0][i] = 1.0 / sqrt(2.0); + } + + /* If the source has a center channel, make sure that's copied 1:1 + * (perhaps it should scale the overall output?) + */ + if ((orig >> 4) & 1) { + mat[0][(orig >> 4) - 1] = 1.0; + } + } + /* Center (or mono) -> front l/r conversion */ + else if (((orig >> 4) & 1) && !((target >> 4) & 1)) { + mat[0][(orig >> 4) - 1] = 1.0 / sqrt(2.0); + mat[1][(orig >> 4) - 1] = 1.0 / sqrt(2.0); + } + + /* Copy LFE */ + if ((orig >> 4) != (target >> 4) && + (orig & 0xF) && (target & 0xF)) + { + mat[dst_chans-1][src_chans-1] = 1.0; + } + + /* Apply panning, which is supposed to maintain a constant power level. + * I took that to mean we want: + * sqrt(rgain^2 + lgain^2) = 1.0 + */ + if (pan != ALLEGRO_AUDIO_PAN_NONE) { + float rgain = sqrt(( pan + 1.0f) / 2.0f); + float lgain = sqrt((-pan + 1.0f) / 2.0f); + + /* I dunno what to do about >2 channels, so don't even try for now. */ + for (j = 0; j < src_chans; j++) { + mat[0][j] *= lgain; + mat[1][j] *= rgain; + } + } + + /* Apply gain */ + if (gain != 1.0f) { + for (i = 0; i < dst_chans; i++) { + for (j = 0; j < src_chans; j++) { + mat[i][j] *= gain; + } + } + } + +#ifdef DEBUGMODE + { + char debug[1024]; + ALLEGRO_DEBUG("sample matrix:\n"); + for (i = 0; i < dst_chans; i++) { + strcpy(debug, ""); + for (j = 0; j < src_chans; j++) { + sprintf(debug + strlen(debug), " %f", mat[i][j]); + } + ALLEGRO_DEBUG("%s\n", debug); + } + } +#endif + + return &mat[0][0]; +} + + +/* _al_kcm_mixer_rejig_sample_matrix: + * Recompute the mixing matrix for a sample attached to a mixer. + * The caller must be holding the mixer mutex. + */ +void _al_kcm_mixer_rejig_sample_matrix(ALLEGRO_MIXER *mixer, + ALLEGRO_SAMPLE_INSTANCE *spl) +{ + float *mat; + size_t dst_chans; + size_t src_chans; + size_t i, j; + + mat = _al_rechannel_matrix(spl->spl_data.chan_conf, + mixer->ss.spl_data.chan_conf, spl->gain, spl->pan); + + dst_chans = al_get_channel_count(mixer->ss.spl_data.chan_conf); + src_chans = al_get_channel_count(spl->spl_data.chan_conf); + + if (!spl->matrix) + spl->matrix = al_calloc(1, src_chans * dst_chans * sizeof(float)); + + for (i = 0; i < dst_chans; i++) { + for (j = 0; j < src_chans; j++) { + spl->matrix[i*src_chans + j] = mat[i*ALLEGRO_MAX_CHANNELS + j]; + } + } +} + + +/* fix_looped_position: + * When a stream loops, this will fix up the position and anything else to + * allow it to safely continue playing as expected. Returns false if it + * should stop being mixed. + */ +static bool fix_looped_position(ALLEGRO_SAMPLE_INSTANCE *spl) +{ + bool is_empty; + ALLEGRO_AUDIO_STREAM *stream; + + /* Looping! Should be mostly self-explanatory */ + switch (spl->loop) { + case ALLEGRO_PLAYMODE_LOOP: + if (spl->loop_end - spl->loop_start != 0) { + if (spl->step > 0) { + while (spl->pos >= spl->loop_end) { + spl->pos -= (spl->loop_end - spl->loop_start); + } + } + else if (spl->step < 0) { + while (spl->pos < spl->loop_start) { + spl->pos += (spl->loop_end - spl->loop_start); + } + } + } + return true; + + case ALLEGRO_PLAYMODE_BIDIR: + /* When doing bi-directional looping, you need to do a follow-up + * check for the opposite direction if a loop occurred, otherwise + * you could end up misplaced on small, high-step loops. + */ + if (spl->loop_end - spl->loop_start != 0) { + if (spl->step >= 0) { + check_forward: + if (spl->pos >= spl->loop_end) { + spl->step = -spl->step; + spl->pos = spl->loop_end - (spl->pos - spl->loop_end) - 1; + goto check_backward; + } + } + else { + check_backward: + if (spl->pos < spl->loop_start || spl->pos >= spl->loop_end) { + spl->step = -spl->step; + spl->pos = spl->loop_start + (spl->loop_start - spl->pos); + goto check_forward; + } + } + } + return true; + + case ALLEGRO_PLAYMODE_ONCE: + if (spl->pos < spl->spl_data.len && spl->pos >= 0) { + return true; + } + if (spl->step >= 0) + spl->pos = 0; + else + spl->pos = spl->spl_data.len - 1; + spl->is_playing = false; + return false; + + case _ALLEGRO_PLAYMODE_STREAM_ONCE: + case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: + stream = (ALLEGRO_AUDIO_STREAM *)spl; + is_empty = false; + while (spl->pos >= spl->spl_data.len && stream->spl.is_playing && !is_empty) { + is_empty = !_al_kcm_refill_stream(stream); + if (is_empty && stream->is_draining) { + stream->spl.is_playing = false; + } + + _al_kcm_emit_stream_events(stream); + } + return !(is_empty); + } + + ASSERT(false); + return false; +} + + +#include "kcm_mixer_helpers.inc" + + +static INLINE int32_t clamp(int32_t val, int32_t min, int32_t max) +{ + /* Clamp to min */ + val -= min; + val &= (~val) >> 31; + val += min; + + /* Clamp to max */ + val -= max; + val &= val >> 31; + val += max; + + return val; +} + + +/* Mix as many sample values as possible from the source sample into a mixer + * buffer. Implements stream_reader_t. + * + * TYPE is the type of the sample values in the mixer buffer, and + * NEXT_SAMPLE_VALUE must return a buffer of the same type. + * + * Note: Uses Bresenham to keep the precise sample position. + */ +#define BRESENHAM \ + do { \ + delta = spl->step > 0 ? spl->step : spl->step - spl->step_denom + 1; \ + delta /= spl->step_denom; \ + delta_error = spl->step - delta * spl->step_denom; \ + } while (0) + +#define MAKE_MIXER(NAME, NEXT_SAMPLE_VALUE, TYPE) \ +static void NAME(void *source, void **vbuf, unsigned int *samples, \ + ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc) \ +{ \ + ALLEGRO_SAMPLE_INSTANCE *spl = (ALLEGRO_SAMPLE_INSTANCE *)source; \ + TYPE *buf = *vbuf; \ + size_t maxc = al_get_channel_count(spl->spl_data.chan_conf); \ + size_t samples_l = *samples; \ + size_t c; \ + int delta, delta_error; \ + SAMP_BUF samp_buf; \ + \ + BRESENHAM; \ + \ + if (!spl->is_playing) \ + return; \ + \ + while (samples_l > 0) { \ + const TYPE *s; \ + int old_step = spl->step; \ + \ + if (!fix_looped_position(spl)) \ + return; \ + if (old_step != spl->step) { \ + BRESENHAM; \ + } \ + \ + /* It might be worth preparing multiple sample values at once. */ \ + s = (TYPE *) NEXT_SAMPLE_VALUE(&samp_buf, spl, maxc); \ + \ + for (c = 0; c < dest_maxc; c++) { \ + ALLEGRO_STATIC_ASSERT(kcm_mixer, ALLEGRO_MAX_CHANNELS == 8); \ + switch (maxc) { \ + case 8: *buf += s[7] * spl->matrix[c*maxc + 7]; \ + /* fall through */ \ + case 7: *buf += s[6] * spl->matrix[c*maxc + 6]; \ + /* fall through */ \ + case 6: *buf += s[5] * spl->matrix[c*maxc + 5]; \ + /* fall through */ \ + case 5: *buf += s[4] * spl->matrix[c*maxc + 4]; \ + /* fall through */ \ + case 4: *buf += s[3] * spl->matrix[c*maxc + 3]; \ + /* fall through */ \ + case 3: *buf += s[2] * spl->matrix[c*maxc + 2]; \ + /* fall through */ \ + case 2: *buf += s[1] * spl->matrix[c*maxc + 1]; \ + /* fall through */ \ + case 1: *buf += s[0] * spl->matrix[c*maxc + 0]; \ + /* fall through */ \ + default: break; \ + } \ + buf++; \ + } \ + \ + spl->pos += delta; \ + spl->pos_bresenham_error += delta_error; \ + if (spl->pos_bresenham_error >= spl->step_denom) { \ + spl->pos++; \ + spl->pos_bresenham_error -= spl->step_denom; \ + } \ + samples_l--; \ + } \ + fix_looped_position(spl); \ + (void)buffer_depth; \ +} + +MAKE_MIXER(read_to_mixer_point_float_32, point_spl32, float) +MAKE_MIXER(read_to_mixer_linear_float_32, linear_spl32, float) +MAKE_MIXER(read_to_mixer_cubic_float_32, cubic_spl32, float) +MAKE_MIXER(read_to_mixer_point_int16_t_16, point_spl16, int16_t) +MAKE_MIXER(read_to_mixer_linear_int16_t_16, linear_spl16, int16_t) + +#undef MAKE_MIXER + + +/* _al_kcm_mixer_read: + * Mixes the streams attached to the mixer and writes additively to the + * specified buffer (or if *buf is NULL, indicating a voice, convert it and + * set it to the buffer pointer). + */ +void _al_kcm_mixer_read(void *source, void **buf, unsigned int *samples, + ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc) +{ + const ALLEGRO_MIXER *mixer; + ALLEGRO_MIXER *m = (ALLEGRO_MIXER *)source; + int maxc = al_get_channel_count(m->ss.spl_data.chan_conf); + int samples_l = *samples; + int i; + + if (!m->ss.is_playing) + return; + + /* Make sure the mixer buffer is big enough. */ + if (m->ss.spl_data.len*maxc < samples_l*maxc) { + al_free(m->ss.spl_data.buffer.ptr); + m->ss.spl_data.buffer.ptr = al_malloc(samples_l*maxc*al_get_audio_depth_size(m->ss.spl_data.depth)); + if (!m->ss.spl_data.buffer.ptr) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Out of memory allocating mixer buffer"); + m->ss.spl_data.len = 0; + return; + } + m->ss.spl_data.len = samples_l; + } + + mixer = m; + + /* Clear the buffer to silence. */ + memset(mixer->ss.spl_data.buffer.ptr, 0, samples_l * maxc * al_get_audio_depth_size(mixer->ss.spl_data.depth)); + + /* Mix the streams into the mixer buffer. */ + for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { + ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); + ALLEGRO_SAMPLE_INSTANCE *spl = *slot; + ASSERT(spl->spl_read); + spl->spl_read(spl, (void **) &mixer->ss.spl_data.buffer.ptr, samples, + m->ss.spl_data.depth, maxc); + } + + /* Call the post-processing callback. */ + if (mixer->postprocess_callback) { + mixer->postprocess_callback(mixer->ss.spl_data.buffer.ptr, + *samples, mixer->pp_callback_userdata); + } + + samples_l *= maxc; + + /* Apply the gain if necessary. */ + if (mixer->ss.gain != 1.0f) { + float mixer_gain = mixer->ss.gain; + unsigned long i = samples_l; + + switch (m->ss.spl_data.depth) { + case ALLEGRO_AUDIO_DEPTH_FLOAT32: { + float *p = mixer->ss.spl_data.buffer.f32; + while (i-- > 0) { + *p++ *= mixer_gain; + } + break; + } + + case ALLEGRO_AUDIO_DEPTH_INT16: { + int16_t *p = mixer->ss.spl_data.buffer.s16; + while (i-- > 0) { + *p++ *= mixer_gain; + } + break; + } + + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_INT24: + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_UINT24: + /* Unsupported mixer depths. */ + ASSERT(false); + break; + } + } + + /* Feeding to a non-voice. + * Currently we only support mixers of the same audio depth doing this. + */ + if (*buf) { + switch (m->ss.spl_data.depth) { + case ALLEGRO_AUDIO_DEPTH_FLOAT32: { + /* We don't need to clamp in the mixer yet. */ + float *lbuf = *buf; + float *src = mixer->ss.spl_data.buffer.f32; + while (samples_l-- > 0) { + *lbuf += *src; + lbuf++; + src++; + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT16: { + int16_t *lbuf = *buf; + int16_t *src = mixer->ss.spl_data.buffer.s16; + while (samples_l-- > 0) { + int32_t x = *lbuf + *src; + if (x < -32768) + x = -32768; + else if (x > 32767) + x = 32767; + *lbuf = (int16_t)x; + lbuf++; + src++; + } + break; + } + + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_INT24: + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_UINT24: + /* Unsupported mixer depths. */ + ASSERT(false); + break; + } + } + return; + } + + /* We're feeding to a voice. + * Clamp and convert the mixed data for the voice. + */ + *buf = mixer->ss.spl_data.buffer.ptr; + switch (buffer_depth & ~ALLEGRO_AUDIO_DEPTH_UNSIGNED) { + + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + /* Do we need to clamp? */ + break; + + case ALLEGRO_AUDIO_DEPTH_INT24: + switch (mixer->ss.spl_data.depth) { + case ALLEGRO_AUDIO_DEPTH_FLOAT32: { + int32_t off = ((buffer_depth & ALLEGRO_AUDIO_DEPTH_UNSIGNED) + ? 0x800000 : 0); + int32_t *lbuf = mixer->ss.spl_data.buffer.s24; + float *src = mixer->ss.spl_data.buffer.f32; + + while (samples_l > 0) { + *lbuf = clamp(*(src++) * ((float)0x7FFFFF + 0.5f), + ~0x7FFFFF, 0x7FFFFF); + *lbuf += off; + lbuf++; + samples_l--; + } + break; + } + + case ALLEGRO_AUDIO_DEPTH_INT16: + /* XXX not yet implemented */ + ASSERT(false); + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_INT24: + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_UINT24: + /* Unsupported mixer depths. */ + ASSERT(false); + break; + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT16: + switch (mixer->ss.spl_data.depth) { + case ALLEGRO_AUDIO_DEPTH_FLOAT32: { + int16_t off = ((buffer_depth & ALLEGRO_AUDIO_DEPTH_UNSIGNED) + ? 0x8000 : 0); + int16_t *lbuf = mixer->ss.spl_data.buffer.s16; + float *src = mixer->ss.spl_data.buffer.f32; + + while (samples_l > 0) { + *lbuf = clamp(*(src++) * ((float)0x7FFF + 0.5f), ~0x7FFF, 0x7FFF); + *lbuf += off; + lbuf++; + samples_l--; + } + break; + } + + case ALLEGRO_AUDIO_DEPTH_INT16: + /* Handle signedness differences. */ + if (buffer_depth != ALLEGRO_AUDIO_DEPTH_INT16) { + int16_t *lbuf = mixer->ss.spl_data.buffer.s16; + while (samples_l > 0) { + *lbuf++ ^= 0x8000; + samples_l--; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_INT24: + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_UINT24: + /* Unsupported mixer depths. */ + ASSERT(false); + break; + } + break; + + /* Ugh, do we really want to support 8-bit output? */ + case ALLEGRO_AUDIO_DEPTH_INT8: + switch (mixer->ss.spl_data.depth) { + case ALLEGRO_AUDIO_DEPTH_FLOAT32: { + int8_t off = ((buffer_depth & ALLEGRO_AUDIO_DEPTH_UNSIGNED) + ? 0x80 : 0); + int8_t *lbuf = mixer->ss.spl_data.buffer.s8; + float *src = mixer->ss.spl_data.buffer.f32; + + while (samples_l > 0) { + *lbuf = clamp(*(src++) * ((float)0x7F + 0.5f), ~0x7F, 0x7F); + *lbuf += off; + lbuf++; + samples_l--; + } + break; + } + + case ALLEGRO_AUDIO_DEPTH_INT16: + /* XXX not yet implemented */ + ASSERT(false); + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_INT24: + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_UINT24: + /* Unsupported mixer depths. */ + ASSERT(false); + break; + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_UINT24: + /* Impossible. */ + ASSERT(false); + break; + } + + (void)dest_maxc; +} + + +/* Function: al_create_mixer + */ +ALLEGRO_MIXER *al_create_mixer(unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) +{ + ALLEGRO_MIXER *mixer; + int default_mixer_quality = ALLEGRO_MIXER_QUALITY_LINEAR; + const char *p; + + /* XXX this is in the wrong place */ + p = al_get_config_value(al_get_system_config(), "audio", + "default_mixer_quality"); + if (p && p[0] != '\0') { + if (!_al_stricmp(p, "point")) { + ALLEGRO_INFO("Point sampling\n"); + default_mixer_quality = ALLEGRO_MIXER_QUALITY_POINT; + } + else if (!_al_stricmp(p, "linear")) { + ALLEGRO_INFO("Linear interpolation\n"); + default_mixer_quality = ALLEGRO_MIXER_QUALITY_LINEAR; + } + else if (!_al_stricmp(p, "cubic")) { + ALLEGRO_INFO("Cubic interpolation\n"); + default_mixer_quality = ALLEGRO_MIXER_QUALITY_CUBIC; + } + } + + if (!freq) { + _al_set_error(ALLEGRO_INVALID_PARAM, + "Attempted to create mixer with no frequency"); + return NULL; + } + + if (depth != ALLEGRO_AUDIO_DEPTH_FLOAT32 && + depth != ALLEGRO_AUDIO_DEPTH_INT16) { + _al_set_error(ALLEGRO_INVALID_PARAM, "Unsupported mixer depth"); + return NULL; + } + + mixer = al_calloc(1, sizeof(ALLEGRO_MIXER)); + if (!mixer) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Out of memory allocating mixer object"); + return NULL; + } + + mixer->ss.is_playing = true; + mixer->ss.spl_data.free_buf = true; + + mixer->ss.loop = ALLEGRO_PLAYMODE_ONCE; + /* XXX should we have a specific loop mode? */ + mixer->ss.gain = 1.0f; + mixer->ss.spl_data.depth = depth; + mixer->ss.spl_data.chan_conf = chan_conf; + mixer->ss.spl_data.frequency = freq; + + mixer->ss.is_mixer = true; + mixer->ss.spl_read = NULL; + + mixer->quality = default_mixer_quality; + + _al_vector_init(&mixer->streams, sizeof(ALLEGRO_SAMPLE_INSTANCE *)); + + mixer->dtor_item = _al_kcm_register_destructor("mixer", mixer, (void (*)(void *)) al_destroy_mixer); + + return mixer; +} + + +/* Function: al_destroy_mixer + */ +void al_destroy_mixer(ALLEGRO_MIXER *mixer) +{ + if (mixer) { + _al_kcm_unregister_destructor(mixer->dtor_item); + _al_kcm_destroy_sample(&mixer->ss, false); + } +} + + +/* This function is ALLEGRO_MIXER aware */ +/* Function: al_attach_sample_instance_to_mixer + */ +bool al_attach_sample_instance_to_mixer(ALLEGRO_SAMPLE_INSTANCE *spl, + ALLEGRO_MIXER *mixer) +{ + ALLEGRO_SAMPLE_INSTANCE **slot; + + ASSERT(mixer); + ASSERT(spl); + + /* Already referenced, do not attach. */ + if (spl->parent.u.ptr) { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to attach a sample that's already attached"); + return false; + } + + maybe_lock_mutex(mixer->ss.mutex); + + _al_kcm_stream_set_mutex(spl, mixer->ss.mutex); + + slot = _al_vector_alloc_back(&mixer->streams); + if (!slot) { + if (mixer->ss.mutex) { + al_unlock_mutex(mixer->ss.mutex); + } + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Out of memory allocating attachment pointers"); + return false; + } + (*slot) = spl; + + spl->step = (spl->spl_data.frequency) * spl->speed; + spl->step_denom = mixer->ss.spl_data.frequency; + /* Don't want to be trapped with a step value of 0. */ + if (spl->step == 0) { + if (spl->speed > 0.0f) + spl->step = 1; + else + spl->step = -1; + } + + /* Set the proper sample stream reader. */ + ASSERT(spl->spl_read == NULL); + if (spl->is_mixer) { + spl->spl_read = _al_kcm_mixer_read; + } + else { + switch (mixer->ss.spl_data.depth) { + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + switch (mixer->quality) { + case ALLEGRO_MIXER_QUALITY_POINT: + spl->spl_read = read_to_mixer_point_float_32; + break; + case ALLEGRO_MIXER_QUALITY_LINEAR: + spl->spl_read = read_to_mixer_linear_float_32; + break; + case ALLEGRO_MIXER_QUALITY_CUBIC: + spl->spl_read = read_to_mixer_cubic_float_32; + break; + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT16: + switch (mixer->quality) { + case ALLEGRO_MIXER_QUALITY_POINT: + spl->spl_read = read_to_mixer_point_int16_t_16; + break; + case ALLEGRO_MIXER_QUALITY_CUBIC: + ALLEGRO_WARN("Falling back to linear interpolation\n"); + /* fallthrough */ + case ALLEGRO_MIXER_QUALITY_LINEAR: + spl->spl_read = read_to_mixer_linear_int16_t_16; + break; + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_INT24: + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_UINT24: + /* Unsupported mixer depths. */ + ASSERT(false); + break; + } + + _al_kcm_mixer_rejig_sample_matrix(mixer, spl); + } + + spl->parent.u.mixer = mixer; + spl->parent.is_voice = false; + + maybe_unlock_mutex(mixer->ss.mutex); + + return true; +} + + +/* Function: al_attach_audio_stream_to_mixer + */ +bool al_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + ASSERT(stream); + + return al_attach_sample_instance_to_mixer(&stream->spl, mixer); +} + + +/* Function: al_attach_mixer_to_mixer + */ +bool al_attach_mixer_to_mixer(ALLEGRO_MIXER *stream, ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + ASSERT(stream); + ASSERT(mixer != stream); + + if (mixer->ss.spl_data.frequency != stream->ss.spl_data.frequency) { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to attach a mixer with different frequencies"); + return false; + } + + if (mixer->ss.spl_data.depth != stream->ss.spl_data.depth) { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Mixers of different audio depths cannot be attached to one another"); + return false; + } + + if (mixer->ss.spl_data.chan_conf != stream->ss.spl_data.chan_conf) { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Mixers of different channel configurations cannot be attached to one another"); + return false; + } + + return al_attach_sample_instance_to_mixer(&stream->ss, mixer); +} + + +/* Function: al_set_mixer_postprocess_callback + */ +bool al_set_mixer_postprocess_callback(ALLEGRO_MIXER *mixer, + void (*pp_callback)(void *buf, unsigned int samples, void *data), + void *pp_callback_userdata) +{ + ASSERT(mixer); + + maybe_lock_mutex(mixer->ss.mutex); + + mixer->postprocess_callback = pp_callback; + mixer->pp_callback_userdata = pp_callback_userdata; + + maybe_unlock_mutex(mixer->ss.mutex); + + return true; +} + + +/* Function: al_get_mixer_frequency + */ +unsigned int al_get_mixer_frequency(const ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + + return mixer->ss.spl_data.frequency; +} + + +/* Function: al_get_mixer_channels + */ +ALLEGRO_CHANNEL_CONF al_get_mixer_channels(const ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + + return mixer->ss.spl_data.chan_conf; +} + + +/* Function: al_get_mixer_depth + */ +ALLEGRO_AUDIO_DEPTH al_get_mixer_depth(const ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + + return mixer->ss.spl_data.depth; +} + + +/* Function: al_get_mixer_quality + */ +ALLEGRO_MIXER_QUALITY al_get_mixer_quality(const ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + + return mixer->quality; +} + + +/* Function: al_get_mixer_gain + */ +float al_get_mixer_gain(const ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + + return mixer->ss.gain; +} + + +/* Function: al_get_mixer_playing + */ +bool al_get_mixer_playing(const ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + + return mixer->ss.is_playing; +} + + +/* Function: al_get_mixer_attached + */ +bool al_get_mixer_attached(const ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + + return _al_vector_is_nonempty(&mixer->streams); +} + + +/* Function: al_set_mixer_frequency + */ +bool al_set_mixer_frequency(ALLEGRO_MIXER *mixer, unsigned int val) +{ + ASSERT(mixer); + + /* You can change the frequency of a mixer as long as it's not attached + * to anything. + */ + if (mixer->ss.parent.u.ptr) { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to change the frequency of an attached mixer"); + return false; + } + + mixer->ss.spl_data.frequency = val; + return true; +} + + +/* Function: al_set_mixer_quality + */ +bool al_set_mixer_quality(ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY new_quality) +{ + bool ret; + ASSERT(mixer); + + maybe_lock_mutex(mixer->ss.mutex); + + if (mixer->quality == new_quality) { + ret = true; + } + else if (_al_vector_size(&mixer->streams) == 0) { + mixer->quality = new_quality; + ret = true; + } + else { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to change the quality of a mixer with attachments"); + ret = false; + } + + maybe_unlock_mutex(mixer->ss.mutex); + + return ret; +} + + +/* Function: al_set_mixer_gain + */ +bool al_set_mixer_gain(ALLEGRO_MIXER *mixer, float new_gain) +{ + int i; + ASSERT(mixer); + + maybe_lock_mutex(mixer->ss.mutex); + + if (mixer->ss.gain != new_gain) { + mixer->ss.gain = new_gain; + + for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) { + ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i); + _al_kcm_mixer_rejig_sample_matrix(mixer, *slot); + } + } + + maybe_unlock_mutex(mixer->ss.mutex); + + return true; +} + + +/* Function: al_set_mixer_playing + */ +bool al_set_mixer_playing(ALLEGRO_MIXER *mixer, bool val) +{ + ASSERT(mixer); + + mixer->ss.is_playing = val; + return true; +} + + +/* Function: al_detach_mixer + */ +bool al_detach_mixer(ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer); + + _al_kcm_detach_from_parent(&mixer->ss); + ASSERT(mixer->ss.spl_read == NULL); + return true; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/kcm_mixer_helpers.inc b/allegro/addons/audio/kcm_mixer_helpers.inc new file mode 100644 index 00000000..c40d9bcb --- /dev/null +++ b/allegro/addons/audio/kcm_mixer_helpers.inc @@ -0,0 +1,540 @@ +// Warning: This file was created by make_resamplers.py - do not edit. +// vim: set ft=c: +static INLINE const void *point_spl32(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { + unsigned int i0 = spl->pos * maxc; + unsigned int i; + + switch (spl->spl_data.depth) { + + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + for (i = 0; i < maxc; i++) { + samp_buf->f32[i] = spl->spl_data.buffer.f32[i0 + i]; + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT24: + for (i = 0; i < maxc; i++) { + samp_buf->f32[i] = (float) spl->spl_data.buffer.s24[i0 + i] / ((float) 0x7FFFFF + 0.5f); + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT24: + for (i = 0; i < maxc; i++) { + samp_buf->f32[i] = (float) spl->spl_data.buffer.u24[i0 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT16: + for (i = 0; i < maxc; i++) { + samp_buf->f32[i] = (float) spl->spl_data.buffer.s16[i0 + i] / ((float) 0x7FFF + 0.5f); + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT16: + for (i = 0; i < maxc; i++) { + samp_buf->f32[i] = (float) spl->spl_data.buffer.u16[i0 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + for (i = 0; i < maxc; i++) { + samp_buf->f32[i] = (float) spl->spl_data.buffer.s8[i0 + i] / ((float) 0x7F + 0.5f); + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT8: + for (i = 0; i < maxc; i++) { + samp_buf->f32[i] = (float) spl->spl_data.buffer.u8[i0 + i] / ((float) 0x7F + 0.5f) - 1.0f; + } + break; + + } + return samp_buf->f32; +} + +static INLINE const void *point_spl16(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { + unsigned int i0 = spl->pos * maxc; + unsigned int i; + + switch (spl->spl_data.depth) { + + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + for (i = 0; i < maxc; i++) { + samp_buf->s16[i] = (int16_t) (spl->spl_data.buffer.f32[i0 + i] * 0x7FFF); + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT24: + for (i = 0; i < maxc; i++) { + samp_buf->s16[i] = (int16_t) (spl->spl_data.buffer.s24[i0 + i] >> 9); + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT24: + for (i = 0; i < maxc; i++) { + samp_buf->s16[i] = (int16_t) ((spl->spl_data.buffer.u24[i0 + i] - 0x800000) >> 9); + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT16: + for (i = 0; i < maxc; i++) { + samp_buf->s16[i] = spl->spl_data.buffer.s16[i0 + i]; + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT16: + for (i = 0; i < maxc; i++) { + samp_buf->s16[i] = (int16_t) (spl->spl_data.buffer.u16[i0 + i] - 0x8000); + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + for (i = 0; i < maxc; i++) { + samp_buf->s16[i] = (int16_t) spl->spl_data.buffer.s8[i0 + i] << 7; + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT8: + for (i = 0; i < maxc; i++) { + samp_buf->s16[i] = (int16_t) (spl->spl_data.buffer.u8[i0 + i] - 0x80) << 7; + } + break; + + } + return samp_buf->s16; +} + +static INLINE const void *linear_spl32(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { + int p0 = spl->pos; + int p1 = spl->pos + 1; + + switch (spl->loop) { + case ALLEGRO_PLAYMODE_ONCE: + if (p1 >= spl->spl_data.len) + p1 = p0; + break; + case ALLEGRO_PLAYMODE_LOOP: + if (p1 >= spl->loop_end) + p1 = spl->loop_start; + break; + case ALLEGRO_PLAYMODE_BIDIR: + if (p1 >= spl->loop_end) { + p1 = spl->loop_end - 1; + if (p1 < spl->loop_start) + p1 = spl->loop_start; + } + break; + case _ALLEGRO_PLAYMODE_STREAM_ONCE: + case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: + p0--; + p1--; + break; + } + + p0 *= maxc; + p1 *= maxc; + + switch (spl->spl_data.depth) { + + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const float x0 = spl->spl_data.buffer.f32[p0 + i]; + const float x1 = spl->spl_data.buffer.f32[p1 + i]; + const float s = (x0 * (1.0f - t)) + (x1 * t); + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT24: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const float x0 = (float) spl->spl_data.buffer.s24[p0 + i] / ((float) 0x7FFFFF + 0.5f); + const float x1 = (float) spl->spl_data.buffer.s24[p1 + i] / ((float) 0x7FFFFF + 0.5f); + const float s = (x0 * (1.0f - t)) + (x1 * t); + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT24: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const float x0 = (float) spl->spl_data.buffer.u24[p0 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; + const float x1 = (float) spl->spl_data.buffer.u24[p1 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; + const float s = (x0 * (1.0f - t)) + (x1 * t); + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT16: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const float x0 = (float) spl->spl_data.buffer.s16[p0 + i] / ((float) 0x7FFF + 0.5f); + const float x1 = (float) spl->spl_data.buffer.s16[p1 + i] / ((float) 0x7FFF + 0.5f); + const float s = (x0 * (1.0f - t)) + (x1 * t); + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT16: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const float x0 = (float) spl->spl_data.buffer.u16[p0 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; + const float x1 = (float) spl->spl_data.buffer.u16[p1 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; + const float s = (x0 * (1.0f - t)) + (x1 * t); + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const float x0 = (float) spl->spl_data.buffer.s8[p0 + i] / ((float) 0x7F + 0.5f); + const float x1 = (float) spl->spl_data.buffer.s8[p1 + i] / ((float) 0x7F + 0.5f); + const float s = (x0 * (1.0f - t)) + (x1 * t); + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT8: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const float x0 = (float) spl->spl_data.buffer.u8[p0 + i] / ((float) 0x7F + 0.5f) - 1.0f; + const float x1 = (float) spl->spl_data.buffer.u8[p1 + i] / ((float) 0x7F + 0.5f) - 1.0f; + const float s = (x0 * (1.0f - t)) + (x1 * t); + samp_buf->f32[i] = s; + } + } + break; + + } + return samp_buf->f32; +} + +static INLINE const void *linear_spl16(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { + int p0 = spl->pos; + int p1 = spl->pos + 1; + + switch (spl->loop) { + case ALLEGRO_PLAYMODE_ONCE: + if (p1 >= spl->spl_data.len) + p1 = p0; + break; + case ALLEGRO_PLAYMODE_LOOP: + if (p1 >= spl->loop_end) + p1 = spl->loop_start; + break; + case ALLEGRO_PLAYMODE_BIDIR: + if (p1 >= spl->loop_end) { + p1 = spl->loop_end - 1; + if (p1 < spl->loop_start) + p1 = spl->loop_start; + } + break; + case _ALLEGRO_PLAYMODE_STREAM_ONCE: + case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: + p0--; + p1--; + break; + } + + p0 *= maxc; + p1 *= maxc; + + switch (spl->spl_data.depth) { + + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + { + const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const int32_t x0 = (int16_t) (spl->spl_data.buffer.f32[p0 + i] * 0x7FFF); + const int32_t x1 = (int16_t) (spl->spl_data.buffer.f32[p1 + i] * 0x7FFF); + const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); + samp_buf->s16[i] = (int16_t) s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT24: + { + const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const int32_t x0 = (int16_t) (spl->spl_data.buffer.s24[p0 + i] >> 9); + const int32_t x1 = (int16_t) (spl->spl_data.buffer.s24[p1 + i] >> 9); + const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); + samp_buf->s16[i] = (int16_t) s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT24: + { + const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const int32_t x0 = (int16_t) ((spl->spl_data.buffer.u24[p0 + i] - 0x800000) >> 9); + const int32_t x1 = (int16_t) ((spl->spl_data.buffer.u24[p1 + i] - 0x800000) >> 9); + const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); + samp_buf->s16[i] = (int16_t) s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT16: + { + const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const int32_t x0 = spl->spl_data.buffer.s16[p0 + i]; + const int32_t x1 = spl->spl_data.buffer.s16[p1 + i]; + const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); + samp_buf->s16[i] = (int16_t) s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT16: + { + const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const int32_t x0 = (int16_t) (spl->spl_data.buffer.u16[p0 + i] - 0x8000); + const int32_t x1 = (int16_t) (spl->spl_data.buffer.u16[p1 + i] - 0x8000); + const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); + samp_buf->s16[i] = (int16_t) s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + { + const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const int32_t x0 = (int16_t) spl->spl_data.buffer.s8[p0 + i] << 7; + const int32_t x1 = (int16_t) spl->spl_data.buffer.s8[p1 + i] << 7; + const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); + samp_buf->s16[i] = (int16_t) s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT8: + { + const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int) maxc; i++) { + const int32_t x0 = (int16_t) (spl->spl_data.buffer.u8[p0 + i] - 0x80) << 7; + const int32_t x1 = (int16_t) (spl->spl_data.buffer.u8[p1 + i] - 0x80) << 7; + const int32_t s = ((x0 * (256 - t)) >> 8) + ((x1 * t) >> 8); + samp_buf->s16[i] = (int16_t) s; + } + } + break; + + } + return samp_buf->s16; +} + +static INLINE const void *cubic_spl32(SAMP_BUF * samp_buf, const ALLEGRO_SAMPLE_INSTANCE * spl, unsigned int maxc) { + int p0 = spl->pos - 1; + int p1 = spl->pos; + int p2 = spl->pos + 1; + int p3 = spl->pos + 2; + + switch (spl->loop) { + case ALLEGRO_PLAYMODE_ONCE: + if (p0 < 0) + p0 = 0; + if (p2 >= spl->spl_data.len) + p2 = spl->spl_data.len - 1; + if (p3 >= spl->spl_data.len) + p3 = spl->spl_data.len - 1; + break; + case ALLEGRO_PLAYMODE_LOOP: + case ALLEGRO_PLAYMODE_BIDIR: + /* These positions should really wrap/bounce instead of clamping + * but it's probably unnoticeable. + */ + if (p0 < spl->loop_start) + p0 = spl->loop_end - 1; + if (p2 >= spl->loop_end) + p2 = spl->loop_start; + if (p3 >= spl->loop_end) + p3 = spl->loop_start; + break; + case _ALLEGRO_PLAYMODE_STREAM_ONCE: + case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: + /* Lag by three samples in total. */ + p0 -= 2; + p1 -= 2; + p2 -= 2; + p3 -= 2; + break; + } + + p0 *= maxc; + p1 *= maxc; + p2 *= maxc; + p3 *= maxc; + + switch (spl->spl_data.depth) { + + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + signed int i; + for (i = 0; i < (signed int) maxc; i++) { + float x0 = spl->spl_data.buffer.f32[p0 + i]; + float x1 = spl->spl_data.buffer.f32[p1 + i]; + float x2 = spl->spl_data.buffer.f32[p2 + i]; + float x3 = spl->spl_data.buffer.f32[p3 + i]; + float c0 = x1; + float c1 = 0.5f * (x2 - x0); + float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); + float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); + float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT24: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + signed int i; + for (i = 0; i < (signed int) maxc; i++) { + float x0 = (float) spl->spl_data.buffer.s24[p0 + i] / ((float) 0x7FFFFF + 0.5f); + float x1 = (float) spl->spl_data.buffer.s24[p1 + i] / ((float) 0x7FFFFF + 0.5f); + float x2 = (float) spl->spl_data.buffer.s24[p2 + i] / ((float) 0x7FFFFF + 0.5f); + float x3 = (float) spl->spl_data.buffer.s24[p3 + i] / ((float) 0x7FFFFF + 0.5f); + float c0 = x1; + float c1 = 0.5f * (x2 - x0); + float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); + float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); + float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT24: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + signed int i; + for (i = 0; i < (signed int) maxc; i++) { + float x0 = (float) spl->spl_data.buffer.u24[p0 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; + float x1 = (float) spl->spl_data.buffer.u24[p1 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; + float x2 = (float) spl->spl_data.buffer.u24[p2 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; + float x3 = (float) spl->spl_data.buffer.u24[p3 + i] / ((float) 0x7FFFFF + 0.5f) - 1.0f; + float c0 = x1; + float c1 = 0.5f * (x2 - x0); + float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); + float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); + float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT16: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + signed int i; + for (i = 0; i < (signed int) maxc; i++) { + float x0 = (float) spl->spl_data.buffer.s16[p0 + i] / ((float) 0x7FFF + 0.5f); + float x1 = (float) spl->spl_data.buffer.s16[p1 + i] / ((float) 0x7FFF + 0.5f); + float x2 = (float) spl->spl_data.buffer.s16[p2 + i] / ((float) 0x7FFF + 0.5f); + float x3 = (float) spl->spl_data.buffer.s16[p3 + i] / ((float) 0x7FFF + 0.5f); + float c0 = x1; + float c1 = 0.5f * (x2 - x0); + float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); + float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); + float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT16: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + signed int i; + for (i = 0; i < (signed int) maxc; i++) { + float x0 = (float) spl->spl_data.buffer.u16[p0 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; + float x1 = (float) spl->spl_data.buffer.u16[p1 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; + float x2 = (float) spl->spl_data.buffer.u16[p2 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; + float x3 = (float) spl->spl_data.buffer.u16[p3 + i] / ((float) 0x7FFF + 0.5f) - 1.0f; + float c0 = x1; + float c1 = 0.5f * (x2 - x0); + float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); + float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); + float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_INT8: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + signed int i; + for (i = 0; i < (signed int) maxc; i++) { + float x0 = (float) spl->spl_data.buffer.s8[p0 + i] / ((float) 0x7F + 0.5f); + float x1 = (float) spl->spl_data.buffer.s8[p1 + i] / ((float) 0x7F + 0.5f); + float x2 = (float) spl->spl_data.buffer.s8[p2 + i] / ((float) 0x7F + 0.5f); + float x3 = (float) spl->spl_data.buffer.s8[p3 + i] / ((float) 0x7F + 0.5f); + float c0 = x1; + float c1 = 0.5f * (x2 - x0); + float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); + float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); + float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; + samp_buf->f32[i] = s; + } + } + break; + + case ALLEGRO_AUDIO_DEPTH_UINT8: + { + const float t = (float) spl->pos_bresenham_error / spl->step_denom; + signed int i; + for (i = 0; i < (signed int) maxc; i++) { + float x0 = (float) spl->spl_data.buffer.u8[p0 + i] / ((float) 0x7F + 0.5f) - 1.0f; + float x1 = (float) spl->spl_data.buffer.u8[p1 + i] / ((float) 0x7F + 0.5f) - 1.0f; + float x2 = (float) spl->spl_data.buffer.u8[p2 + i] / ((float) 0x7F + 0.5f) - 1.0f; + float x3 = (float) spl->spl_data.buffer.u8[p3 + i] / ((float) 0x7F + 0.5f) - 1.0f; + float c0 = x1; + float c1 = 0.5f * (x2 - x0); + float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); + float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); + float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; + samp_buf->f32[i] = s; + } + } + break; + + } + return samp_buf->f32; +} diff --git a/allegro/addons/audio/kcm_sample.c b/allegro/addons/audio/kcm_sample.c new file mode 100644 index 00000000..96576fd4 --- /dev/null +++ b/allegro/addons/audio/kcm_sample.c @@ -0,0 +1,537 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Sample audio interface. + * + * By Peter Wang. + * + * See LICENSE.txt for copyright information. + */ + +/* Title: Sample audio interface + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_vector.h" + +ALLEGRO_DEBUG_CHANNEL("audio") + + +static ALLEGRO_VOICE *allegro_voice = NULL; +static ALLEGRO_MIXER *allegro_mixer = NULL; +static ALLEGRO_MIXER *default_mixer = NULL; + + +typedef struct AUTO_SAMPLE { + ALLEGRO_SAMPLE_INSTANCE *instance; + int id; + bool locked; +} AUTO_SAMPLE; + +static _AL_VECTOR auto_samples = _AL_VECTOR_INITIALIZER(AUTO_SAMPLE); + + +static bool create_default_mixer(void); +static bool do_play_sample(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data, + float gain, float pan, float speed, ALLEGRO_PLAYMODE loop); +static void free_sample_vector(void); + + +static int string_to_depth(const char *s) +{ + // FIXME: fill in the rest + if (!_al_stricmp(s, "int16")) { + return ALLEGRO_AUDIO_DEPTH_INT16; + } + else { + return ALLEGRO_AUDIO_DEPTH_FLOAT32; + } +} + + +/* Creates the default voice and mixer if they haven't been created yet. */ +static bool create_default_mixer(void) +{ + int voice_frequency = 44100; + int voice_depth = ALLEGRO_AUDIO_DEPTH_INT16; + int mixer_frequency = 44100; + int mixer_depth = ALLEGRO_AUDIO_DEPTH_FLOAT32; + + ALLEGRO_CONFIG *config = al_get_system_config(); + const char *p; + p = al_get_config_value(config, "audio", "primary_voice_frequency"); + if (p && p[0] != '\0') { + voice_frequency = atoi(p); + } + p = al_get_config_value(config, "audio", "primary_mixer_frequency"); + if (p && p[0] != '\0') { + mixer_frequency = atoi(p); + } + p = al_get_config_value(config, "audio", "primary_voice_depth"); + if (p && p[0] != '\0') { + voice_depth = string_to_depth(p); + } + p = al_get_config_value(config, "audio", "primary_mixer_depth"); + if (p && p[0] != '\0') { + mixer_depth = string_to_depth(p); + } + + if (!allegro_voice) { + allegro_voice = al_create_voice(voice_frequency, voice_depth, + ALLEGRO_CHANNEL_CONF_2); + if (!allegro_voice) { + ALLEGRO_ERROR("al_create_voice failed\n"); + goto Error; + } + } + + if (!allegro_mixer) { + allegro_mixer = al_create_mixer(mixer_frequency, mixer_depth, + ALLEGRO_CHANNEL_CONF_2); + if (!allegro_mixer) { + ALLEGRO_ERROR("al_create_voice failed\n"); + goto Error; + } + } + + /* In case this function is called multiple times. */ + al_detach_mixer(allegro_mixer); + + if (!al_attach_mixer_to_voice(allegro_mixer, allegro_voice)) { + ALLEGRO_ERROR("al_attach_mixer_to_voice failed\n"); + goto Error; + } + + return true; + +Error: + + if (allegro_mixer) { + al_destroy_mixer(allegro_mixer); + allegro_mixer = NULL; + } + + if (allegro_voice) { + al_destroy_voice(allegro_voice); + allegro_voice = NULL; + } + + return false; +} + + +/* Function: al_create_sample + */ +ALLEGRO_SAMPLE *al_create_sample(void *buf, unsigned int samples, + unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, + ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf) +{ + ALLEGRO_SAMPLE *spl; + + ASSERT(buf); + + if (!freq) { + _al_set_error(ALLEGRO_INVALID_PARAM, "Invalid sample frequency"); + return NULL; + } + + spl = al_calloc(1, sizeof(*spl)); + if (!spl) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Out of memory allocating sample data object"); + return NULL; + } + + spl->depth = depth; + spl->chan_conf = chan_conf; + spl->frequency = freq; + spl->len = samples; + spl->buffer.ptr = buf; + spl->free_buf = free_buf; + + spl->dtor_item = _al_kcm_register_destructor("sample", spl, (void (*)(void *)) al_destroy_sample); + + return spl; +} + + +/* Stop any sample instances which are still playing a sample buffer which + * is about to be destroyed. + */ +static void stop_sample_instances_helper(void *object, void (*func)(void *), + void *userdata) +{ + ALLEGRO_SAMPLE_INSTANCE *splinst = object; + + /* This is ugly. */ + if (func == (void (*)(void *)) al_destroy_sample_instance + && al_get_sample_data(al_get_sample(splinst)) == userdata + && al_get_sample_instance_playing(splinst)) + { + al_stop_sample_instance(splinst); + } +} + + +/* Function: al_destroy_sample + */ +void al_destroy_sample(ALLEGRO_SAMPLE *spl) +{ + if (spl) { + _al_kcm_foreach_destructor(stop_sample_instances_helper, + al_get_sample_data(spl)); + _al_kcm_unregister_destructor(spl->dtor_item); + + if (spl->free_buf && spl->buffer.ptr) { + al_free(spl->buffer.ptr); + } + spl->buffer.ptr = NULL; + spl->free_buf = false; + al_free(spl); + } +} + + +/* Function: al_reserve_samples + */ +bool al_reserve_samples(int reserve_samples) +{ + int i; + int current_samples_count = (int) _al_vector_size(&auto_samples); + + ASSERT(reserve_samples >= 0); + + /* If no default mixer has been set by the user, then create a voice + * and a mixer, and set them to be the default one for use with + * al_play_sample(). + */ + if (default_mixer == NULL) { + if (!al_restore_default_mixer()) + goto Error; + } + + if (current_samples_count < reserve_samples) { + /* We need to reserve more samples than currently are reserved. */ + for (i = 0; i < reserve_samples - current_samples_count; i++) { + AUTO_SAMPLE *slot = _al_vector_alloc_back(&auto_samples); + slot->id = 0; + slot->instance = al_create_sample_instance(NULL); + slot->locked = false; + if (!slot->instance) { + ALLEGRO_ERROR("al_create_sample failed\n"); + goto Error; + } + if (!al_attach_sample_instance_to_mixer(slot->instance, default_mixer)) { + ALLEGRO_ERROR("al_attach_mixer_to_sample failed\n"); + goto Error; + } + } + } + else if (current_samples_count > reserve_samples) { + /* We need to reserve fewer samples than currently are reserved. */ + while (current_samples_count-- > reserve_samples) { + AUTO_SAMPLE *slot = _al_vector_ref(&auto_samples, current_samples_count); + al_destroy_sample_instance(slot->instance); + _al_vector_delete_at(&auto_samples, current_samples_count); + } + } + + return true; + + Error: + free_sample_vector(); + + return false; +} + + +/* Function: al_get_default_mixer + */ +ALLEGRO_MIXER *al_get_default_mixer(void) +{ + return default_mixer; +} + + +/* Function: al_set_default_mixer + */ +bool al_set_default_mixer(ALLEGRO_MIXER *mixer) +{ + ASSERT(mixer != NULL); + + if (mixer != default_mixer) { + int i; + + default_mixer = mixer; + + /* Destroy all current sample instances, recreate them, and + * attach them to the new mixer */ + for (i = 0; i < (int) _al_vector_size(&auto_samples); i++) { + AUTO_SAMPLE *slot = _al_vector_ref(&auto_samples, i); + + slot->id = 0; + al_destroy_sample_instance(slot->instance); + slot->locked = false; + + slot->instance = al_create_sample_instance(NULL); + if (!slot->instance) { + ALLEGRO_ERROR("al_create_sample failed\n"); + goto Error; + } + if (!al_attach_sample_instance_to_mixer(slot->instance, default_mixer)) { + ALLEGRO_ERROR("al_attach_mixer_to_sample failed\n"); + goto Error; + } + } + } + + return true; + +Error: + free_sample_vector(); + default_mixer = NULL; + return false; +} + + +/* Function: al_restore_default_mixer + */ +bool al_restore_default_mixer(void) +{ + if (!create_default_mixer()) + return false; + + if (!al_set_default_mixer(allegro_mixer)) + return false; + + return true; +} + + +/* Function: al_get_default_voice + */ +ALLEGRO_VOICE *al_get_default_voice(void) +{ + return allegro_voice; +} + + +/* Function: al_set_default_voice + */ +void al_set_default_voice(ALLEGRO_VOICE *voice) +{ + if (allegro_voice) { + al_destroy_voice(allegro_voice); + } + allegro_voice = voice; +} + + +/* Function: al_play_sample + */ +bool al_play_sample(ALLEGRO_SAMPLE *spl, float gain, float pan, float speed, + ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id) +{ + static int next_id = 0; + unsigned int i; + + ASSERT(spl); + + if (ret_id != NULL) { + ret_id->_id = -1; + ret_id->_index = 0; + } + + for (i = 0; i < _al_vector_size(&auto_samples); i++) { + AUTO_SAMPLE *slot = _al_vector_ref(&auto_samples, i); + + if (!al_get_sample_instance_playing(slot->instance) && !slot->locked) { + if (!do_play_sample(slot->instance, spl, gain, pan, speed, loop)) + break; + + if (ret_id != NULL) { + ret_id->_index = (int) i; + ret_id->_id = slot->id = ++next_id; + } + + return true; + } + } + + return false; +} + + +static bool do_play_sample(ALLEGRO_SAMPLE_INSTANCE *splinst, + ALLEGRO_SAMPLE *spl, float gain, float pan, float speed, ALLEGRO_PLAYMODE loop) +{ + if (!al_set_sample(splinst, spl)) { + ALLEGRO_ERROR("al_set_sample failed\n"); + return false; + } + + if (!al_set_sample_instance_gain(splinst, gain) || + !al_set_sample_instance_pan(splinst, pan) || + !al_set_sample_instance_speed(splinst, speed) || + !al_set_sample_instance_playmode(splinst, loop)) { + return false; + } + + if (!al_play_sample_instance(splinst)) { + ALLEGRO_ERROR("al_play_sample_instance failed\n"); + return false; + } + + return true; +} + + +/* Function: al_stop_sample + */ +void al_stop_sample(ALLEGRO_SAMPLE_ID *spl_id) +{ + AUTO_SAMPLE *slot; + + ASSERT(spl_id->_id != -1); + ASSERT(spl_id->_index < (int) _al_vector_size(&auto_samples)); + + slot = _al_vector_ref(&auto_samples, spl_id->_index); + if (slot->id == spl_id->_id) { + al_stop_sample_instance(slot->instance); + } +} + + +/* Function: al_lock_sample_id + */ +ALLEGRO_SAMPLE_INSTANCE* al_lock_sample_id(ALLEGRO_SAMPLE_ID *spl_id) +{ + AUTO_SAMPLE *slot; + + ASSERT(spl_id->_id != -1); + ASSERT(spl_id->_index < (int) _al_vector_size(&auto_samples)); + + slot = _al_vector_ref(&auto_samples, spl_id->_index); + if (slot->id == spl_id->_id) { + slot->locked = true; + return slot->instance; + } + return NULL; +} + + +/* Function: al_unlock_sample_id + */ +void al_unlock_sample_id(ALLEGRO_SAMPLE_ID *spl_id) +{ + AUTO_SAMPLE *slot; + + ASSERT(spl_id->_id != -1); + ASSERT(spl_id->_index < (int) _al_vector_size(&auto_samples)); + + slot = _al_vector_ref(&auto_samples, spl_id->_index); + if (slot->id == spl_id->_id) { + slot->locked = false; + } +} + + +/* Function: al_stop_samples + */ +void al_stop_samples(void) +{ + unsigned int i; + + for (i = 0; i < _al_vector_size(&auto_samples); i++) { + AUTO_SAMPLE *slot = _al_vector_ref(&auto_samples, i); + al_stop_sample_instance(slot->instance); + } +} + + +/* Function: al_get_sample_frequency + */ +unsigned int al_get_sample_frequency(const ALLEGRO_SAMPLE *spl) +{ + ASSERT(spl); + + return spl->frequency; +} + + +/* Function: al_get_sample_length + */ +unsigned int al_get_sample_length(const ALLEGRO_SAMPLE *spl) +{ + ASSERT(spl); + + return spl->len; +} + + +/* Function: al_get_sample_depth + */ +ALLEGRO_AUDIO_DEPTH al_get_sample_depth(const ALLEGRO_SAMPLE *spl) +{ + ASSERT(spl); + + return spl->depth; +} + + +/* Function: al_get_sample_channels + */ +ALLEGRO_CHANNEL_CONF al_get_sample_channels(const ALLEGRO_SAMPLE *spl) +{ + ASSERT(spl); + + return spl->chan_conf; +} + + +/* Function: al_get_sample_data + */ +void *al_get_sample_data(const ALLEGRO_SAMPLE *spl) +{ + ASSERT(spl); + + return spl->buffer.ptr; +} + + +/* Destroy all sample instances, and frees the associated vectors. */ +static void free_sample_vector(void) +{ + int j; + + for (j = 0; j < (int) _al_vector_size(&auto_samples); j++) { + AUTO_SAMPLE *slot = _al_vector_ref(&auto_samples, j); + al_destroy_sample_instance(slot->instance); + } + _al_vector_free(&auto_samples); +} + + +void _al_kcm_shutdown_default_mixer(void) +{ + free_sample_vector(); + al_destroy_mixer(allegro_mixer); + al_destroy_voice(allegro_voice); + + allegro_mixer = NULL; + allegro_voice = NULL; + default_mixer = NULL; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/kcm_stream.c b/allegro/addons/audio/kcm_stream.c new file mode 100644 index 00000000..2feecde1 --- /dev/null +++ b/allegro/addons/audio/kcm_stream.c @@ -0,0 +1,916 @@ +/** + * Originally digi.c from allegro wiki + * Original authors: KC/Milan + * + * Converted to allegro5 by Ryan Dickie + */ + +/* Title: Stream functions + */ + +#include <stdio.h> + +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_audio_cfg.h" + +ALLEGRO_DEBUG_CHANNEL("audio") + +/* + * The highest quality interpolator is a cubic interpolator requiring + * four sample points. In the streaming case we lag the true sample + * position by three. + */ +#define MAX_LAG (3) + + +/* + * To avoid deadlocks, unlock the mutex returned by this function, rather than + * whatever you passed as the argument. + */ +static ALLEGRO_MUTEX *maybe_lock_mutex(ALLEGRO_MUTEX *mutex) +{ + if (mutex) { + al_lock_mutex(mutex); + } + return mutex; +} + + +static void maybe_unlock_mutex(ALLEGRO_MUTEX *mutex) +{ + if (mutex) { + al_unlock_mutex(mutex); + } +} + +/* Function: al_create_audio_stream + */ +ALLEGRO_AUDIO_STREAM *al_create_audio_stream(size_t fragment_count, + unsigned int frag_samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, + ALLEGRO_CHANNEL_CONF chan_conf) +{ + ALLEGRO_AUDIO_STREAM *stream; + unsigned long bytes_per_sample; + unsigned long bytes_per_frag_buf; + size_t i; + + if (!fragment_count) { + _al_set_error(ALLEGRO_INVALID_PARAM, + "Attempted to create stream with no buffers"); + return NULL; + } + if (!frag_samples) { + _al_set_error(ALLEGRO_INVALID_PARAM, + "Attempted to create stream with no buffer size"); + return NULL; + } + if (!freq) { + _al_set_error(ALLEGRO_INVALID_PARAM, + "Attempted to create stream with no frequency"); + return NULL; + } + + bytes_per_sample = al_get_channel_count(chan_conf) * + al_get_audio_depth_size(depth); + bytes_per_frag_buf = frag_samples * bytes_per_sample; + + stream = al_calloc(1, sizeof(*stream)); + if (!stream) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Out of memory allocating stream object"); + return NULL; + } + + stream->spl.is_playing = true; + stream->is_draining = false; + + stream->spl.loop = _ALLEGRO_PLAYMODE_STREAM_ONCE; + stream->spl.spl_data.depth = depth; + stream->spl.spl_data.chan_conf = chan_conf; + stream->spl.spl_data.frequency = freq; + stream->spl.speed = 1.0f; + stream->spl.gain = 1.0f; + stream->spl.pan = 0.0f; + + stream->spl.step = 0; + stream->spl.pos = frag_samples; + stream->spl.spl_data.len = stream->spl.pos; + + stream->buf_count = fragment_count; + + stream->used_bufs = al_calloc(1, fragment_count * sizeof(void *) * 2); + if (!stream->used_bufs) { + al_free(stream->used_bufs); + al_free(stream); + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Out of memory allocating stream buffer pointers"); + return NULL; + } + stream->pending_bufs = stream->used_bufs + fragment_count; + + /* The main_buffer holds all the buffer fragments in contiguous memory. + * To support interpolation across buffer fragments, we allocate extra + * MAX_LAG samples at the start of each buffer fragment, to hold the + * last few sample values which came before that fragment. + */ + stream->main_buffer = al_calloc(1, + (MAX_LAG * bytes_per_sample + bytes_per_frag_buf) * fragment_count); + if (!stream->main_buffer) { + al_free(stream->used_bufs); + al_free(stream); + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Out of memory allocating stream buffer"); + return NULL; + } + + for (i = 0; i < fragment_count; i++) { + char *buffer = (char *)stream->main_buffer + + i * (MAX_LAG * bytes_per_sample + bytes_per_frag_buf); + al_fill_silence(buffer, MAX_LAG, depth, chan_conf); + stream->used_bufs[i] = buffer + MAX_LAG * bytes_per_sample; + } + + al_init_user_event_source(&stream->spl.es); + + /* This can lead to deadlocks on shutdown, hence we don't do it. */ + /* stream->dtor_item = _al_kcm_register_destructor(stream, (void (*)(void *)) al_destroy_audio_stream); */ + + return stream; +} + + +/* Function: al_destroy_audio_stream + */ +void al_destroy_audio_stream(ALLEGRO_AUDIO_STREAM *stream) +{ + if (stream) { + if (stream->feed_thread) { + stream->unload_feeder(stream); + } + /* See commented out call to _al_kcm_register_destructor. */ + /* _al_kcm_unregister_destructor(stream->dtor_item); */ + _al_kcm_detach_from_parent(&stream->spl); + + al_destroy_user_event_source(&stream->spl.es); + al_free(stream->main_buffer); + al_free(stream->used_bufs); + al_free(stream); + } +} + + +/* Function: al_drain_audio_stream + */ +void al_drain_audio_stream(ALLEGRO_AUDIO_STREAM *stream) +{ + bool playing; + + if (!al_get_audio_stream_attached(stream)) { + al_set_audio_stream_playing(stream, false); + return; + } + + stream->is_draining = true; + do { + al_rest(0.01); + playing = al_get_audio_stream_playing(stream); + } while (playing); + stream->is_draining = false; +} + + +/* Function: al_get_audio_stream_frequency + */ +unsigned int al_get_audio_stream_frequency(const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.spl_data.frequency; +} + + +/* Function: al_get_audio_stream_length + */ +unsigned int al_get_audio_stream_length(const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.spl_data.len; +} + + +/* Function: al_get_audio_stream_fragments + */ +unsigned int al_get_audio_stream_fragments(const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->buf_count; +} + + +/* Function: al_get_available_audio_stream_fragments + */ +unsigned int al_get_available_audio_stream_fragments( + const ALLEGRO_AUDIO_STREAM *stream) +{ + unsigned int i; + ASSERT(stream); + + for (i = 0; i < stream->buf_count && stream->used_bufs[i]; i++) + ; + return i; +} + + +/* Function: al_get_audio_stream_speed + */ +float al_get_audio_stream_speed(const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.speed; +} + + +/* Function: al_get_audio_stream_gain + */ +float al_get_audio_stream_gain(const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.gain; +} + + +/* Function: al_get_audio_stream_pan + */ +float al_get_audio_stream_pan(const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.pan; +} + + +/* Function: al_get_audio_stream_channels + */ +ALLEGRO_CHANNEL_CONF al_get_audio_stream_channels( + const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.spl_data.chan_conf; +} + + +/* Function: al_get_audio_stream_depth + */ +ALLEGRO_AUDIO_DEPTH al_get_audio_stream_depth( + const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.spl_data.depth; +} + + +/* Function: al_get_audio_stream_playmode + */ +ALLEGRO_PLAYMODE al_get_audio_stream_playmode( + const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.loop; +} + + +/* Function: al_get_audio_stream_playing +*/ +bool al_get_audio_stream_playing(const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return stream->spl.is_playing; +} + + +/* Function: al_get_audio_stream_attached +*/ +bool al_get_audio_stream_attached(const ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + return (stream->spl.parent.u.ptr != NULL); +} + +/* Function: al_get_audio_stream_played_samples +*/ +uint64_t al_get_audio_stream_played_samples(const ALLEGRO_AUDIO_STREAM *stream) +{ + uint64_t result; + ALLEGRO_MUTEX *stream_mutex; + ASSERT(stream); + + stream_mutex = maybe_lock_mutex(stream->spl.mutex); + if (stream->spl.spl_data.buffer.ptr) { + result = stream->consumed_fragments * stream->spl.spl_data.len + + stream->spl.pos; + } + else { + result = 0; + } + maybe_unlock_mutex(stream_mutex); + + return result; +} + +/* Function: al_get_audio_stream_fragment +*/ +void *al_get_audio_stream_fragment(const ALLEGRO_AUDIO_STREAM *stream) +{ + size_t i; + void *fragment; + ALLEGRO_MUTEX *stream_mutex; + ASSERT(stream); + + stream_mutex = maybe_lock_mutex(stream->spl.mutex); + + if (!stream->used_bufs[0]) { + /* No free fragments are available. */ + fragment = NULL; + } + else { + fragment = stream->used_bufs[0]; + for (i = 0; i < stream->buf_count-1 && stream->used_bufs[i]; i++) { + stream->used_bufs[i] = stream->used_bufs[i+1]; + } + stream->used_bufs[i] = NULL; + } + + maybe_unlock_mutex(stream_mutex); + + return fragment; +} + + +/* Function: al_set_audio_stream_speed + */ +bool al_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM *stream, float val) +{ + ASSERT(stream); + + if (val <= 0.0f) { + _al_set_error(ALLEGRO_INVALID_PARAM, + "Attempted to set stream speed to a zero or negative value"); + return false; + } + + if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Could not set voice playback speed"); + return false; + } + + stream->spl.speed = val; + if (stream->spl.parent.u.mixer) { + ALLEGRO_MIXER *mixer = stream->spl.parent.u.mixer; + ALLEGRO_MUTEX *stream_mutex = maybe_lock_mutex(stream->spl.mutex); + + stream->spl.step = (stream->spl.spl_data.frequency) * stream->spl.speed; + stream->spl.step_denom = mixer->ss.spl_data.frequency; + /* Don't wanna be trapped with a step value of 0 */ + if (stream->spl.step == 0) { + stream->spl.step = 1; + } + + maybe_unlock_mutex(stream_mutex); + } + + return true; +} + + +/* Function: al_set_audio_stream_gain + */ +bool al_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM *stream, float val) +{ + ASSERT(stream); + + if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Could not set gain of stream attached to voice"); + return false; + } + + if (stream->spl.gain != val) { + stream->spl.gain = val; + + /* If attached to a mixer already, need to recompute the sample + * matrix to take into account the gain. + */ + if (stream->spl.parent.u.mixer) { + ALLEGRO_MIXER *mixer = stream->spl.parent.u.mixer; + ALLEGRO_MUTEX *stream_mutex = maybe_lock_mutex(stream->spl.mutex); + _al_kcm_mixer_rejig_sample_matrix(mixer, &stream->spl); + maybe_unlock_mutex(stream_mutex); + } + } + + return true; +} + + +/* Function: al_set_audio_stream_pan + */ +bool al_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM *stream, float val) +{ + ASSERT(stream); + + if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Could not set gain of stream attached to voice"); + return false; + } + if (val != ALLEGRO_AUDIO_PAN_NONE && (val < -1.0 || val > 1.0)) { + _al_set_error(ALLEGRO_GENERIC_ERROR, "Invalid pan value"); + return false; + } + + if (stream->spl.pan != val) { + stream->spl.pan = val; + + /* If attached to a mixer already, need to recompute the sample + * matrix to take into account the panning. + */ + if (stream->spl.parent.u.mixer) { + ALLEGRO_MIXER *mixer = stream->spl.parent.u.mixer; + ALLEGRO_MUTEX *stream_mutex = maybe_lock_mutex(stream->spl.mutex); + _al_kcm_mixer_rejig_sample_matrix(mixer, &stream->spl); + maybe_unlock_mutex(stream_mutex); + } + } + + return true; +} + + +/* Function: al_set_audio_stream_playmode + */ +bool al_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM *stream, + ALLEGRO_PLAYMODE val) +{ + ASSERT(stream); + + if (val == ALLEGRO_PLAYMODE_ONCE) { + stream->spl.loop = _ALLEGRO_PLAYMODE_STREAM_ONCE; + return true; + } + else if (val == ALLEGRO_PLAYMODE_LOOP) { + /* Only streams creating by al_load_audio_stream() support + * looping. */ + if (!stream->feeder) + return false; + + stream->spl.loop = _ALLEGRO_PLAYMODE_STREAM_ONEDIR; + return true; + } + + // XXX _al_set_error + return false; +} + + +static void reset_stopped_stream(ALLEGRO_AUDIO_STREAM *stream) +{ + const int bytes_per_sample = + al_get_channel_count(stream->spl.spl_data.chan_conf) * + al_get_audio_depth_size(stream->spl.spl_data.depth); + const int fragment_buffer_size = + bytes_per_sample * (stream->spl.spl_data.len + MAX_LAG); + size_t i, n; + + /* Write silence to the "invisible" part in between fragment buffers to + * avoid interpolation artifacts. It's tempting to zero the complete + * memory block in one go but some of the buffers might be getting + * refilled. So they are currently "owned" by the library user and + * should not be overwritten. But zeroing the parts not visible to the + * user should be OK. + */ + for (i = 0; i < stream->buf_count; ++i) { + al_fill_silence((char *)stream->main_buffer + i * fragment_buffer_size, + MAX_LAG, stream->spl.spl_data.depth, stream->spl.spl_data.chan_conf); + } + + /* Get the current number of entries in the used_buf list. */ + for (n = 0; n < stream->buf_count && stream->used_bufs[n]; n++) + ; + + /* Move everything from pending_bufs to used_bufs. */ + i = 0; + while (i < stream->buf_count && + n < stream->buf_count && + stream->pending_bufs[i]) + { + stream->used_bufs[n] = stream->pending_bufs[i]; + stream->pending_bufs[i] = NULL; + n++; + i++; + } + + /* No fragment buffer is currently playing. */ + stream->spl.spl_data.buffer.ptr = NULL; + stream->spl.pos = stream->spl.spl_data.len; + stream->spl.pos_bresenham_error = 0; + stream->consumed_fragments = 0; +} + + +/* Function: al_set_audio_stream_playing + */ +bool al_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM *stream, bool val) +{ + bool rc = true; + ALLEGRO_MUTEX *stream_mutex; + ASSERT(stream); + + if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { + ALLEGRO_VOICE *voice = stream->spl.parent.u.voice; + if (val != stream->spl.is_playing) { + rc = _al_kcm_set_voice_playing(voice, voice->mutex, val); + } + } + + stream_mutex = maybe_lock_mutex(stream->spl.mutex); + + stream->spl.is_playing = rc && val; + + if (stream->spl.is_playing) { + /* We usually emit fragment events when a fragment is used up, but if the + * stream has zero pending fragments to begin with then no events would + * ever be emitted. + */ + _al_kcm_emit_stream_events(stream); + } + else if (!val) { + reset_stopped_stream(stream); + } + + maybe_unlock_mutex(stream_mutex); + + return rc; +} + + +/* Function: al_detach_audio_stream + */ +bool al_detach_audio_stream(ALLEGRO_AUDIO_STREAM *stream) +{ + ASSERT(stream); + + _al_kcm_detach_from_parent(&stream->spl); + ASSERT(stream->spl.spl_read == NULL); + return !al_get_audio_stream_attached(stream); +} + + +/* Function: al_set_audio_stream_fragment + */ +bool al_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM *stream, void *val) +{ + size_t i; + bool ret; + ALLEGRO_MUTEX *stream_mutex; + ASSERT(stream); + + stream_mutex = maybe_lock_mutex(stream->spl.mutex); + + for (i = 0; i < stream->buf_count && stream->pending_bufs[i] ; i++) + ; + if (i < stream->buf_count) { + stream->pending_bufs[i] = val; + ret = true; + } + else { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to set a stream buffer with a full pending list"); + ret = false; + } + + maybe_unlock_mutex(stream_mutex); + + return ret; +} + + +/* _al_kcm_refill_stream: + * Called by the mixer when the current buffer has been used up. It should + * point to the next pending buffer and adjust the sample position to reflect + * the buffer being updated. It may be necessary to call this function multiple + * times if the sample position is so far ahead that multiple buffers need to + * be consumed. + * Returns true if the next buffer is available and set up. + * Otherwise returns false. + */ +bool _al_kcm_refill_stream(ALLEGRO_AUDIO_STREAM *stream) +{ + ALLEGRO_SAMPLE_INSTANCE *spl = &stream->spl; + void *old_buf = spl->spl_data.buffer.ptr; + void *new_buf; + size_t i; + int new_pos = spl->pos - spl->spl_data.len; + + if (old_buf) { + /* Slide the buffers down one position and put the + * completed buffer into the used array to be refilled. + */ + for (i = 0; + i < stream->buf_count-1 && stream->pending_bufs[i]; + i++) { + stream->pending_bufs[i] = stream->pending_bufs[i+1]; + } + stream->pending_bufs[i] = NULL; + + for (i = 0; stream->used_bufs[i]; i++) + ; + stream->used_bufs[i] = old_buf; + } + + new_buf = stream->pending_bufs[0]; + stream->spl.spl_data.buffer.ptr = new_buf; + if (!new_buf) { + ALLEGRO_WARN("Out of buffers\n"); + return false; + } + + /* Copy the last MAX_LAG sample values to the front of the new buffer + * for interpolation. + */ + if (old_buf) { + const int bytes_per_sample = + al_get_channel_count(spl->spl_data.chan_conf) * + al_get_audio_depth_size(spl->spl_data.depth); + + memcpy( + (char *) new_buf - bytes_per_sample * MAX_LAG, + (char *) old_buf + bytes_per_sample * (spl->pos-MAX_LAG-new_pos), + bytes_per_sample * MAX_LAG); + + stream->consumed_fragments++; + } + + stream->spl.pos = new_pos; + + return true; +} + + +/* _al_kcm_feed_stream: + * A routine running in another thread that feeds the stream buffers as + * necessary, usually getting data from some file reader backend. + */ +void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream) +{ + ALLEGRO_AUDIO_STREAM *stream = vstream; + ALLEGRO_EVENT_QUEUE *queue; + bool finished_event_sent = false; + (void)self; + + ALLEGRO_DEBUG("Stream feeder thread started.\n"); + + queue = al_create_event_queue(); + al_register_event_source(queue, &stream->spl.es); + + al_lock_mutex(stream->feed_thread_started_mutex); + stream->feed_thread_started = true; + al_broadcast_cond(stream->feed_thread_started_cond); + al_unlock_mutex(stream->feed_thread_started_mutex); + + stream->quit_feed_thread = false; + + while (!stream->quit_feed_thread) { + char *fragment; + ALLEGRO_EVENT event; + + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT + && !stream->is_draining) { + unsigned long bytes; + unsigned long bytes_written; + ALLEGRO_MUTEX *stream_mutex; + + fragment = al_get_audio_stream_fragment(stream); + if (!fragment) { + /* This is not an error. */ + continue; + } + + bytes = (stream->spl.spl_data.len) * + al_get_channel_count(stream->spl.spl_data.chan_conf) * + al_get_audio_depth_size(stream->spl.spl_data.depth); + + stream_mutex = maybe_lock_mutex(stream->spl.mutex); + bytes_written = stream->feeder(stream, fragment, bytes); + maybe_unlock_mutex(stream_mutex); + + if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { + /* Keep rewinding until the fragment is filled. */ + while (bytes_written < bytes && + stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { + size_t bw; + al_rewind_audio_stream(stream); + stream_mutex = maybe_lock_mutex(stream->spl.mutex); + bw = stream->feeder(stream, fragment + bytes_written, + bytes - bytes_written); + bytes_written += bw; + maybe_unlock_mutex(stream_mutex); + } + } + else if (bytes_written < bytes) { + /* Fill the rest of the fragment with silence. */ + int silence_samples = (bytes - bytes_written) / + (al_get_channel_count(stream->spl.spl_data.chan_conf) * + al_get_audio_depth_size(stream->spl.spl_data.depth)); + al_fill_silence(fragment + bytes_written, silence_samples, + stream->spl.spl_data.depth, stream->spl.spl_data.chan_conf); + } + + if (!al_set_audio_stream_fragment(stream, fragment)) { + ALLEGRO_ERROR("Error setting stream buffer.\n"); + continue; + } + + /* The streaming source doesn't feed any more, so drain buffers. + * Don't quit in case the user decides to seek and then restart the + * stream. */ + if (bytes_written != bytes && + stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONCE) { + al_drain_audio_stream(stream); + + if (!finished_event_sent) { + ALLEGRO_EVENT fin_event; + fin_event.user.type = ALLEGRO_EVENT_AUDIO_STREAM_FINISHED; + fin_event.user.timestamp = al_get_time(); + al_emit_user_event(&stream->spl.es, &fin_event, NULL); + finished_event_sent = true; + } + } else { + finished_event_sent = false; + } + } + else if (event.type == _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE) { + ALLEGRO_EVENT fin_event; + stream->quit_feed_thread = true; + + fin_event.user.type = ALLEGRO_EVENT_AUDIO_STREAM_FINISHED; + fin_event.user.timestamp = al_get_time(); + al_emit_user_event(&stream->spl.es, &fin_event, NULL); + } + } + + al_destroy_event_queue(queue); + + ALLEGRO_DEBUG("Stream feeder thread finished.\n"); + + return NULL; +} + + +void _al_kcm_emit_stream_events(ALLEGRO_AUDIO_STREAM *stream) +{ + /* Emit one event for each stream fragment available right now. + * + * There may already be an event corresponding to an available fragment in + * some event queue, but there's nothing we can do about that. Streams may + * be added and removed from queues, events may be lost by the user, etc. + * so it would be dangerous to assume that each fragment event would be + * responded to, once and exactly once. + * + * Having said that, event queues are empty in the steady state so it is + * relatively rare that this situation occurs. + */ + int count = al_get_available_audio_stream_fragments(stream); + + while (count--) { + ALLEGRO_EVENT event; + event.user.type = ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT; + event.user.timestamp = al_get_time(); + al_emit_user_event(&stream->spl.es, &event, NULL); + } +} + + +/* Function: al_rewind_audio_stream + */ +bool al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream) +{ + bool ret; + + if (stream->rewind_feeder) { + ALLEGRO_MUTEX *stream_mutex = maybe_lock_mutex(stream->spl.mutex); + ret = stream->rewind_feeder(stream); + maybe_unlock_mutex(stream_mutex); + return ret; + } + + return false; +} + + +/* Function: al_seek_audio_stream_secs + */ +bool al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double time) +{ + bool ret; + + if (stream->seek_feeder) { + ALLEGRO_MUTEX *stream_mutex = maybe_lock_mutex(stream->spl.mutex); + ret = stream->seek_feeder(stream, time); + maybe_unlock_mutex(stream_mutex); + return ret; + } + + return false; +} + + +/* Function: al_get_audio_stream_position_secs + */ +double al_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM *stream) +{ + double ret; + + if (stream->get_feeder_position) { + ALLEGRO_MUTEX *stream_mutex = maybe_lock_mutex(stream->spl.mutex); + ret = stream->get_feeder_position(stream); + maybe_unlock_mutex(stream_mutex); + return ret; + } + + return 0.0; +} + + +/* Function: al_get_audio_stream_length_secs + */ +double al_get_audio_stream_length_secs(ALLEGRO_AUDIO_STREAM *stream) +{ + double ret; + + if (stream->get_feeder_length) { + ALLEGRO_MUTEX *stream_mutex = maybe_lock_mutex(stream->spl.mutex); + ret = stream->get_feeder_length(stream); + maybe_unlock_mutex(stream_mutex); + return ret; + } + + return 0.0; +} + + +/* Function: al_set_audio_stream_loop_secs + */ +bool al_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM *stream, + double start, double end) +{ + bool ret; + + if (start >= end) + return false; + + if (stream->set_feeder_loop) { + ALLEGRO_MUTEX *stream_mutex = maybe_lock_mutex(stream->spl.mutex); + ret = stream->set_feeder_loop(stream, start, end); + maybe_unlock_mutex(stream_mutex); + return ret; + } + + return false; +} + + +/* Function: al_get_audio_stream_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_audio_stream_event_source( + ALLEGRO_AUDIO_STREAM *stream) +{ + return &stream->spl.es; +} + +bool al_set_audio_stream_channel_matrix(ALLEGRO_AUDIO_STREAM *stream, const float *matrix) +{ + ASSERT(stream); + + if (stream->spl.parent.u.ptr && stream->spl.parent.is_voice) { + _al_set_error(ALLEGRO_GENERIC_ERROR, + "Could not set channel matrix of stream attached to voice"); + return false; + } + + return al_set_sample_instance_channel_matrix(&stream->spl, matrix); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/kcm_voice.c b/allegro/addons/audio/kcm_voice.c new file mode 100644 index 00000000..76b0d694 --- /dev/null +++ b/allegro/addons/audio/kcm_voice.c @@ -0,0 +1,544 @@ +/** + * Originally digi.c from allegro wiki + * Original authors: KC/Milan + * + * Converted to allegro5 by Ryan Dickie + */ + +/* Title: Voice functions + */ + +#include <stdio.h> + +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_audio_cfg.h" + +ALLEGRO_DEBUG_CHANNEL("audio") + + +/* forward declarations */ +static void stream_read(void *source, void **vbuf, unsigned int *samples, + ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc); + + + +/* _al_voice_update: + * Reads the attached stream and provides a buffer for the sound card. It is + * the driver's responsiblity to call this and to make sure any + * driver-specific resources associated with the voice are locked. This should + * only be called for streaming sources. + * + * The return value is a pointer to the next chunk of audio data in the format + * the voice was allocated with. It may return NULL, in which case it is the + * driver's responsilibty to play silence for the voice. The returned buffer + * must *not* be modified. The 'samples' argument is set to the samples count + * in the returned audio data and it may be less or equal to the requested + * samples count. + */ +const void *_al_voice_update(ALLEGRO_VOICE *voice, ALLEGRO_MUTEX *mutex, + unsigned int *samples) +{ + void *buf = NULL; + + /* The mutex parameter is intended to make it obvious at the call site + * that the voice mutex will be acquired here. + */ + ASSERT(voice); + ASSERT(voice->mutex == mutex); + (void)mutex; + + al_lock_mutex(voice->mutex); + if (voice->attached_stream) { + ASSERT(voice->attached_stream->spl_read); + voice->attached_stream->spl_read(voice->attached_stream, &buf, samples, + voice->depth, 0); + } + al_unlock_mutex(voice->mutex); + + return buf; +} + + +/* Function: al_create_voice + */ +ALLEGRO_VOICE *al_create_voice(unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) +{ + ALLEGRO_VOICE *voice = NULL; + + if (!freq) { + _al_set_error(ALLEGRO_INVALID_PARAM, "Invalid Voice Frequency"); + return NULL; + } + + voice = al_calloc(1, sizeof(*voice)); + if (!voice) { + return NULL; + } + + voice->depth = depth; + voice->chan_conf = chan_conf; + voice->frequency = freq; + + voice->mutex = al_create_mutex(); + voice->cond = al_create_cond(); + /* XXX why is this needed? there should only be one active driver */ + voice->driver = _al_kcm_driver; + + ASSERT(_al_kcm_driver); + if (_al_kcm_driver->allocate_voice(voice) != 0) { + al_destroy_mutex(voice->mutex); + al_destroy_cond(voice->cond); + al_free(voice); + return NULL; + } + + voice->dtor_item = _al_kcm_register_destructor("voice", voice, + (void (*)(void *)) al_destroy_voice); + + return voice; +} + + +/* Function: al_destroy_voice + */ +void al_destroy_voice(ALLEGRO_VOICE *voice) +{ + if (voice) { + _al_kcm_unregister_destructor(voice->dtor_item); + + al_detach_voice(voice); + ASSERT(al_get_voice_playing(voice) == false); + + /* We do NOT lock the voice mutex when calling this method. */ + voice->driver->deallocate_voice(voice); + al_destroy_mutex(voice->mutex); + al_destroy_cond(voice->cond); + + al_free(voice); + } +} + + +/* Function: al_attach_sample_instance_to_voice + */ +bool al_attach_sample_instance_to_voice(ALLEGRO_SAMPLE_INSTANCE *spl, + ALLEGRO_VOICE *voice) +{ + bool ret; + + ASSERT(voice); + ASSERT(spl); + + if (voice->attached_stream) { + ALLEGRO_WARN( + "Attempted to attach to a voice that already has an attachment\n"); + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to attach to a voice that already has an attachment"); + return false; + } + + if (spl->parent.u.ptr) { + ALLEGRO_WARN("Attempted to attach a sample that is already attached\n"); + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to attach a sample that is already attached"); + return false; + } + + if (voice->chan_conf != spl->spl_data.chan_conf || + voice->frequency != spl->spl_data.frequency || + voice->depth != spl->spl_data.depth) + { + ALLEGRO_WARN("Sample settings do not match voice settings\n"); + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Sample settings do not match voice settings"); + return false; + } + + al_lock_mutex(voice->mutex); + + voice->attached_stream = spl; + + voice->is_streaming = false; + voice->num_buffers = 1; + voice->buffer_size = (spl->spl_data.len) * + al_get_channel_count(voice->chan_conf) * + al_get_audio_depth_size(voice->depth); + + spl->spl_read = NULL; + _al_kcm_stream_set_mutex(spl, voice->mutex); + + spl->parent.u.voice = voice; + spl->parent.is_voice = true; + + if (voice->driver->load_voice(voice, spl->spl_data.buffer.ptr) != 0 || + (spl->is_playing && voice->driver->start_voice(voice) != 0)) + { + voice->attached_stream = NULL; + spl->spl_read = NULL; + _al_kcm_stream_set_mutex(spl, NULL); + spl->parent.u.voice = NULL; + + ALLEGRO_ERROR("Unable to load sample into voice\n"); + ret = false; + } + else { + ret = true; + } + + al_unlock_mutex(voice->mutex); + + return ret; +} + + +/* stream_read: + * This passes the next waiting stream buffer to the voice via vbuf. + */ +static void stream_read(void *source, void **vbuf, unsigned int *samples, + ALLEGRO_AUDIO_DEPTH buffer_depth, size_t dest_maxc) +{ + ALLEGRO_AUDIO_STREAM *stream = (ALLEGRO_AUDIO_STREAM*)source; + unsigned int len = stream->spl.spl_data.len; + unsigned int pos = stream->spl.pos; + + if (!stream->spl.is_playing) { + *vbuf = NULL; + *samples = 0; + return; + } + + if (*samples > len) + *samples = len; + + if (pos >= len) { + /* XXX: Handle the case where we need to call _al_kcm_refill_stream + * multiple times due to ludicrous playback speed. */ + _al_kcm_refill_stream(stream); + if (!stream->pending_bufs[0]) { + if (stream->is_draining) { + stream->spl.is_playing = false; + } + *vbuf = NULL; + *samples = 0; + return; + } + *vbuf = stream->pending_bufs[0]; + pos = *samples; + + _al_kcm_emit_stream_events(stream); + } + else { + int bytes = pos * al_get_channel_count(stream->spl.spl_data.chan_conf) + * al_get_audio_depth_size(stream->spl.spl_data.depth); + *vbuf = ((char *)stream->pending_bufs[0]) + bytes; + + if (pos + *samples > len) + *samples = len - pos; + pos += *samples; + } + + stream->spl.pos = pos; + + (void)dest_maxc; + (void)buffer_depth; +} + + +/* Function: al_attach_audio_stream_to_voice + */ +bool al_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM *stream, + ALLEGRO_VOICE *voice) +{ + bool ret; + + ASSERT(voice); + ASSERT(stream); + + if (voice->attached_stream) { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to attach to a voice that already has an attachment"); + return false; + } + + if (stream->spl.parent.u.ptr) { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Attempted to attach a stream that is already attached"); + return false; + } + + if (voice->chan_conf != stream->spl.spl_data.chan_conf || + voice->frequency != stream->spl.spl_data.frequency || + voice->depth != stream->spl.spl_data.depth) + { + _al_set_error(ALLEGRO_INVALID_OBJECT, + "Stream settings do not match voice settings"); + return false; + } + + al_lock_mutex(voice->mutex); + + voice->attached_stream = &stream->spl; + + _al_kcm_stream_set_mutex(&stream->spl, voice->mutex); + + stream->spl.parent.u.voice = voice; + stream->spl.parent.is_voice = true; + + voice->is_streaming = true; + voice->num_buffers = stream->buf_count; + voice->buffer_size = (stream->spl.spl_data.len) * + al_get_channel_count(stream->spl.spl_data.chan_conf) * + al_get_audio_depth_size(stream->spl.spl_data.depth); + + ASSERT(stream->spl.spl_read == NULL); + stream->spl.spl_read = stream_read; + + if (voice->driver->start_voice(voice) != 0) { + voice->attached_stream = NULL; + _al_kcm_stream_set_mutex(&stream->spl, NULL); + stream->spl.parent.u.voice = NULL; + stream->spl.spl_read = NULL; + + _al_set_error(ALLEGRO_GENERIC_ERROR, "Unable to start stream"); + ret = false; + } + else { + ret = true; + } + + al_unlock_mutex(voice->mutex); + + return ret; +} + + +/* Function: al_attach_mixer_to_voice + */ +bool al_attach_mixer_to_voice(ALLEGRO_MIXER *mixer, ALLEGRO_VOICE *voice) +{ + bool ret; + + ASSERT(voice); + ASSERT(mixer); + ASSERT(mixer->ss.is_mixer); + + if (voice->attached_stream) + return false; + if (mixer->ss.parent.u.ptr) + return false; + + if (voice->chan_conf != mixer->ss.spl_data.chan_conf || + voice->frequency != mixer->ss.spl_data.frequency) { + return false; + } + + al_lock_mutex(voice->mutex); + + voice->attached_stream = &mixer->ss; + ASSERT(mixer->ss.spl_read == NULL); + mixer->ss.spl_read = _al_kcm_mixer_read; + + _al_kcm_stream_set_mutex(&mixer->ss, voice->mutex); + + mixer->ss.parent.u.voice = voice; + mixer->ss.parent.is_voice = true; + + voice->is_streaming = true; + voice->num_buffers = 0; + voice->buffer_size = 0; + + if (voice->driver->start_voice(voice) != 0) { + voice->attached_stream = NULL; + _al_kcm_stream_set_mutex(&mixer->ss, NULL); + mixer->ss.parent.u.voice = NULL; + ret = false; + } + else { + ret = true; + } + + al_unlock_mutex(voice->mutex); + + return ret; +} + + +/* Function: al_detach_voice + */ +void al_detach_voice(ALLEGRO_VOICE *voice) +{ + ASSERT(voice); + + if (!voice->attached_stream) { + return; + } + + al_lock_mutex(voice->mutex); + + if (!voice->is_streaming) { + ALLEGRO_SAMPLE_INSTANCE *spl = voice->attached_stream; + + spl->pos = voice->driver->get_voice_position(voice); + spl->is_playing = voice->driver->voice_is_playing(voice); + + voice->driver->stop_voice(voice); + voice->driver->unload_voice(voice); + } + else { + voice->driver->stop_voice(voice); + } + + _al_kcm_stream_set_mutex(voice->attached_stream, NULL); + voice->attached_stream->parent.u.voice = NULL; + voice->attached_stream->spl_read = NULL; + voice->attached_stream = NULL; + + al_unlock_mutex(voice->mutex); +} + + +/* Function: al_get_voice_frequency + */ +unsigned int al_get_voice_frequency(const ALLEGRO_VOICE *voice) +{ + ASSERT(voice); + + return voice->frequency; +} + + +/* Function: al_get_voice_position + */ +unsigned int al_get_voice_position(const ALLEGRO_VOICE *voice) +{ + ASSERT(voice); + + if (voice->attached_stream && !voice->is_streaming) { + unsigned int ret; + al_lock_mutex(voice->mutex); + ret = voice->driver->get_voice_position(voice); + al_unlock_mutex(voice->mutex); + return ret; + } + else + return 0; +} + + +/* Function: al_get_voice_channels + */ +ALLEGRO_CHANNEL_CONF al_get_voice_channels(const ALLEGRO_VOICE *voice) +{ + ASSERT(voice); + + return voice->chan_conf; +} + + +/* Function: al_get_voice_depth + */ +ALLEGRO_AUDIO_DEPTH al_get_voice_depth(const ALLEGRO_VOICE *voice) +{ + ASSERT(voice); + + return voice->depth; +} + + +/* Function: al_get_voice_playing + */ +bool al_get_voice_playing(const ALLEGRO_VOICE *voice) +{ + ASSERT(voice); + + if (voice->attached_stream && !voice->is_streaming) { + bool ret; + al_lock_mutex(voice->mutex); + ret = voice->driver->voice_is_playing(voice); + al_unlock_mutex(voice->mutex); + return ret; + } + + return voice->attached_stream ? true : false; +} + + +/* Function: al_set_voice_position + */ +bool al_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) +{ + ASSERT(voice); + + if (voice->attached_stream && !voice->is_streaming) { + bool ret; + al_lock_mutex(voice->mutex); + // XXX change method + ret = voice->driver->set_voice_position(voice, val) == 0; + al_unlock_mutex(voice->mutex); + return ret; + } + + return false; +} + + +/* Function: al_set_voice_playing + */ +bool al_set_voice_playing(ALLEGRO_VOICE *voice, bool val) +{ + ASSERT(voice); + + if (!voice->attached_stream) { + ALLEGRO_DEBUG("Voice has no attachment\n"); + return false; + } + + if (voice->is_streaming) { + ALLEGRO_WARN("Attempted to change the playing state of a voice " + "with a streaming attachment (mixer or audiostreams)\n"); + return false; + } + else { + bool playing = al_get_voice_playing(voice); + if (playing == val) { + if (playing) { + ALLEGRO_DEBUG("Voice is already playing\n"); + } + else { + ALLEGRO_DEBUG("Voice is already stopped\n"); + } + return true; + } + + return _al_kcm_set_voice_playing(voice, voice->mutex, val); + } +} + + +bool _al_kcm_set_voice_playing(ALLEGRO_VOICE *voice, ALLEGRO_MUTEX *mutex, + bool val) +{ + bool ret; + + /* The mutex parameter is intended to make it obvious at the call site + * that the voice mutex will be acquired here. + */ + ASSERT(voice); + ASSERT(voice->mutex == mutex); + (void)mutex; + + al_lock_mutex(voice->mutex); + // XXX change methods + if (val) + ret = voice->driver->start_voice(voice) == 0; + else + ret = voice->driver->stop_voice(voice) == 0; + al_unlock_mutex(voice->mutex); + + return ret; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/openal.c b/allegro/addons/audio/openal.c new file mode 100644 index 00000000..a5fbc79e --- /dev/null +++ b/allegro/addons/audio/openal.c @@ -0,0 +1,667 @@ +/* + * updated for 4.9 inclusion by Ryan Dickie + * Originally done by KC/Milan + */ + +#include <stdio.h> +#include <string.h> + +#include "allegro5/allegro.h" + +#if defined(ALLEGRO_MACOSX) || defined(ALLEGRO_IPHONE) +#include <OpenAL/al.h> +#include <OpenAL/alc.h> +#else /* ALLEGRO_MACOSX */ +#include <al.h> +#include <alc.h> +#endif /* ALLEGRO_MACOSX */ + +#include "allegro5/internal/aintern_audio.h" + +ALLEGRO_DEBUG_CHANNEL("openal") + +/* OpenAL vars */ +static ALCdevice *openal_dev; +static ALCcontext *openal_context; + +/* TODO: make these configurable */ +static const size_t preferred_frag_size = 1024; +static const ALuint preferred_buf_count = 4; + +static const char *openal_get_err_str(ALenum err) +{ + switch (err) { + case AL_NO_ERROR: + return "There is no OpenAL error"; + case AL_INVALID_NAME: + return "A bad name (ID) was passed to OpenAL"; + case AL_INVALID_ENUM: + return "An invalid enum was passed to OpenAL"; + case AL_INVALID_VALUE: + return "An Invalid enum was passed to OpenAL"; + case AL_INVALID_OPERATION: + return "The requestion operation is invalid"; + case AL_OUT_OF_MEMORY: + return "OpenAL ran out of memory"; + default: + return "Unknown error"; + } +} + +static const char *alc_get_err_str(ALCenum err) +{ + switch (err) { + case ALC_NO_ERROR: + return "There is no OpenAL error"; + case ALC_INVALID_DEVICE: + return "A bad device was passed to OpenAL"; + case ALC_INVALID_CONTEXT: + return "An bad context was passed to OpenAL"; + case ALC_INVALID_ENUM: + return "An Invalid enum was passed to OpenAL"; + case ALC_INVALID_VALUE: + return "The requestion operation is invalid"; + case ALC_OUT_OF_MEMORY: + return "OpenAL ran out of memory"; + default: + return "Unknown error"; + } +} + +/* The open method starts up the driver and should lock the device, using the + previously set paramters, or defaults. It shouldn't need to start sending + audio data to the device yet, however. */ +static int _openal_open(void) +{ + ALenum openal_err; + ALCenum alc_err; + + ALLEGRO_INFO("Starting OpenAL\n"); + + /* clear the error state */ + openal_err = alGetError(); + + /* pick default device. always a good choice */ + openal_dev = alcOpenDevice(NULL); + + alc_err = ALC_NO_ERROR; + if (!openal_dev || (alc_err = alcGetError(openal_dev)) != ALC_NO_ERROR) { + ALLEGRO_ERROR("Could not open audio device: %s\n", + alc_get_err_str(alc_err)); + return 1; + } + + openal_context = alcCreateContext(openal_dev, NULL); + alc_err = ALC_NO_ERROR; + if (!openal_context || (alc_err = alcGetError(openal_dev)) != ALC_NO_ERROR) { + ALLEGRO_ERROR("Could not create current device context: %s\n", + alc_get_err_str(alc_err)); + return 1; + } + + alcMakeContextCurrent(openal_context); +#if !defined ALLEGRO_IPHONE + if ((alc_err = alcGetError(openal_dev)) != ALC_NO_ERROR) { + ALLEGRO_ERROR("Could not make context current: %s\n", + alc_get_err_str(alc_err)); + return 1; + } + + alDistanceModel(AL_NONE); + if ((openal_err = alGetError()) != AL_NO_ERROR) { + ALLEGRO_ERROR("Could not set distance model: %s\n", + openal_get_err_str(openal_err)); + return 1; + } +#endif + + ALLEGRO_DEBUG("Vendor: %s\n", alGetString(AL_VENDOR)); + ALLEGRO_DEBUG("Version: %s\n", alGetString(AL_VERSION)); + ALLEGRO_DEBUG("Renderer: %s\n", alGetString(AL_RENDERER)); + ALLEGRO_DEBUG("Extensions: %s\n", alGetString(AL_EXTENSIONS)); + + return 0; +} + +/* The close method should close the device, freeing any resources, and allow + other processes to use the device */ +static void _openal_close(void) +{ + /* clear error states */ + alGetError(); + alcGetError(openal_dev); + + /* remove traces from openal */ + alcMakeContextCurrent(NULL); + alcDestroyContext(openal_context); + alcCloseDevice(openal_dev); + + /* reset the pointers to NULL */ + openal_context = NULL; + openal_dev = NULL; +} + +/* Custom struct to hold voice information OpenAL needs */ +/* TODO: review */ +typedef struct ALLEGRO_AL_DATA { + ALuint *buffers; + + size_t num_buffers; + ALuint buffer_size; + + ALuint source; + ALuint format; + + ALLEGRO_THREAD *thread; + bool stopped; +} ALLEGRO_AL_DATA; + +/* Custom routine which runs in another thread to periodically check if OpenAL + wants more data for a stream */ +/* TODO: review */ +static void *_openal_update(ALLEGRO_THREAD *self, void *arg) +{ + ALLEGRO_VOICE *voice = (ALLEGRO_VOICE*) arg; + ALLEGRO_AL_DATA *ex_data = (ALLEGRO_AL_DATA*)voice->extra; + unsigned int i, samples_per_update; + unsigned int bytes_per_sample; + const void *data; + void *silence; + + /* Streams should not be set to looping */ + alSourcei(ex_data->source, AL_LOOPING, AL_FALSE); + + silence = al_calloc(1, ex_data->buffer_size); + if (ex_data->format == AL_FORMAT_STEREO8 || + ex_data->format == AL_FORMAT_MONO8) { + memset(silence, 0x80, ex_data->buffer_size); + } + + for (i = 0; i < ex_data->num_buffers; i++) { + alBufferData(ex_data->buffers[i], ex_data->format, silence, + ex_data->buffer_size, voice->frequency); + } + + alSourceQueueBuffers(ex_data->source, ex_data->num_buffers, + ex_data->buffers); + + alSourcePlay(ex_data->source); + + switch (ex_data->format) { + case AL_FORMAT_STEREO16: + bytes_per_sample = 4; + break; + case AL_FORMAT_STEREO8: + case AL_FORMAT_MONO16: + bytes_per_sample = 2; + break; + default: + bytes_per_sample = 1; + break; + } + + samples_per_update = ex_data->buffer_size / bytes_per_sample; + + data = silence; + + while (!al_get_thread_should_stop(self)) { + ALint status = 0; + + alGetSourcei(ex_data->source, AL_BUFFERS_PROCESSED, &status); + if (status <= 0) { + /* FIXME what is this for ? */ + al_rest(0.001); + continue; + } + + while (--status >= 0) { + ALuint buffer; + + data = _al_voice_update(voice, voice->mutex, &samples_per_update); + if (data == NULL) + data = silence; + + alSourceUnqueueBuffers(ex_data->source, 1, &buffer); + alBufferData(buffer, ex_data->format, data, + samples_per_update * bytes_per_sample, voice->frequency); + alSourceQueueBuffers(ex_data->source, 1, &buffer); + } + alGetSourcei(ex_data->source, AL_SOURCE_STATE, &status); + if (status == AL_STOPPED) { + alSourcePlay(ex_data->source); + } + } + + alSourceStop(ex_data->source); + + al_free(silence); + + ex_data->stopped = true; + al_broadcast_cond(voice->cond); + + return NULL; +} + +/* The load_voice method loads a sample into the driver's memory. The voice's + 'streaming' field will be set to false for these voices, and it's + 'buffer_size' field will be the total length in bytes of the sample data. + The voice's attached sample's looping mode should be honored, and loading + must fail if it cannot be. */ +static int _openal_load_voice(ALLEGRO_VOICE *voice, const void *data) +{ + ALLEGRO_AL_DATA *ex_data = voice->extra; + ALenum openal_err; + + if (voice->attached_stream->loop != ALLEGRO_PLAYMODE_ONCE && + voice->attached_stream->loop != ALLEGRO_PLAYMODE_LOOP) { + return 1; + } + + ex_data->buffer_size = voice->buffer_size; + if (!ex_data->buffer_size) { + ALLEGRO_ERROR("Voice buffer and data buffer size mismatch\n"); + return 1; + } + ex_data->num_buffers = 1; + + alGenSources(1, &ex_data->source); + if ((openal_err = alGetError()) != AL_NO_ERROR) { + ALLEGRO_ERROR("Could not generate (voice) source: %s\n", + openal_get_err_str(openal_err)); + return 1; + } + + ex_data->buffers = al_malloc(sizeof(ALuint) * ex_data->num_buffers); + if (!ex_data->buffers) { + alSourcei(ex_data->source, AL_BUFFER, 0); + alDeleteSources(1, &ex_data->source); + ALLEGRO_ERROR("Could not allocate voice buffer memory\n"); + return 1; + } + + alGenBuffers(ex_data->num_buffers, ex_data->buffers); + if ((openal_err = alGetError()) != AL_NO_ERROR) { + alSourcei(ex_data->source, AL_BUFFER, 0); + alDeleteSources(1, &ex_data->source); + al_free(ex_data->buffers); + ex_data->buffers = NULL; + ALLEGRO_ERROR("Could not generate (voice) buffer: %s\n", + openal_get_err_str(openal_err)); + return 1; + } + + /* copies data into a buffer */ + alBufferData(ex_data->buffers[0], ex_data->format, + data, ex_data->buffer_size, voice->frequency); + + /* sets the buffer */ + alSourcei(ex_data->source, AL_BUFFER, ex_data->buffers[0]); + + /* Loop / no loop? */ + alSourcei(ex_data->source, AL_LOOPING, + (voice->attached_stream->loop != ALLEGRO_PLAYMODE_ONCE)); + + /* make sure the volume is on */ + alSourcef(ex_data->source, AL_GAIN, 1.0f); + + if ((openal_err = alGetError()) != AL_NO_ERROR) { + alSourcei(ex_data->source, AL_BUFFER, 0); + alDeleteSources(1, &ex_data->source); + alDeleteBuffers(ex_data->num_buffers, ex_data->buffers); + al_free(ex_data->buffers); + ex_data->buffers = NULL; + ALLEGRO_ERROR("Could not attach voice source: %s\n", + openal_get_err_str(openal_err)); + return 1; + } + + return 0; +} + +/* The unload_voice method unloads a sample previously loaded with load_voice. + This method should not be called on a streaming voice. */ +static void _openal_unload_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_AL_DATA *ex_data = voice->extra; + + alSourcei(ex_data->source, AL_BUFFER, 0); + alDeleteSources(1, &ex_data->source); + alDeleteBuffers(ex_data->num_buffers, ex_data->buffers); + al_free(ex_data->buffers); + ex_data->buffers = NULL; + alGetError(); /* required! */ +} + + +/* The start_voice should, surprise, start the voice. For streaming voices, it + should start polling the device and call _al_voice_update for audio data. + For non-streaming voices, it should resume playing from the last set + position */ +static int _openal_start_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_AL_DATA *ex_data = voice->extra; + ALenum openal_err; + + /* playing a sample instead of a stream */ + if (!voice->is_streaming) { + alSourcePlay(ex_data->source); + if ((openal_err = alGetError()) != AL_NO_ERROR) { + ALLEGRO_ERROR("Could not start voice: %s\n", + openal_get_err_str(openal_err)); + return 1; + } + + ALLEGRO_INFO("Starting voice\n"); + return 0; + } + + { + ex_data->buffer_size = voice->buffer_size; + if (!ex_data->buffer_size) { + switch (ex_data->format) { + case AL_FORMAT_STEREO16: + ex_data->buffer_size = preferred_frag_size * 4; + break; + case AL_FORMAT_STEREO8: + case AL_FORMAT_MONO16: + ex_data->buffer_size = preferred_frag_size * 2; + break; + default: + ex_data->buffer_size = preferred_frag_size; + break; + } + } + + ex_data->num_buffers = voice->num_buffers; + if (!ex_data->num_buffers) + ex_data->num_buffers = preferred_buf_count; + + alGenSources(1, &ex_data->source); + if (alGetError() != AL_NO_ERROR) + return 1; + + ex_data->buffers = al_malloc(sizeof(ALuint) * ex_data->num_buffers); + if (!ex_data->buffers) { + alSourcei(ex_data->source, AL_BUFFER, 0); + alDeleteSources(1, &ex_data->source); + return 1; + } + + alGenBuffers(ex_data->num_buffers, ex_data->buffers); + if (alGetError() != AL_NO_ERROR) { + alSourcei(ex_data->source, AL_BUFFER, 0); + alDeleteSources(1, &ex_data->source); + al_free(ex_data->buffers); + ex_data->buffers = NULL; + return 1; + } + + alSourcef(ex_data->source, AL_GAIN, 1.0f); + if (alGetError() != AL_NO_ERROR) { + alSourcei(ex_data->source, AL_BUFFER, 0); + alDeleteSources(1, &ex_data->source); + alDeleteBuffers(ex_data->num_buffers, ex_data->buffers); + al_free(ex_data->buffers); + ex_data->buffers = NULL; + return 1; + } + + ex_data->stopped = false; + ex_data->thread = al_create_thread(_openal_update, (void *)voice); + al_start_thread(ex_data->thread); + } + + ALLEGRO_INFO("Starting voice\n"); + return 0; +} + +/* The stop_voice method should stop playback. For non-streaming voices, it + should leave the data loaded, and reset the voice position to 0. */ +static int _openal_stop_voice(ALLEGRO_VOICE* voice) +{ + ALLEGRO_AL_DATA *ex_data = voice->extra; + ALenum openal_err; + + if (!ex_data->buffers) { + ALLEGRO_WARN("Trying to stop empty voice buffer\n"); + return 1; + } + + /* if playing a sample */ + if (!voice->is_streaming) { + alSourceStop(ex_data->source); + if ((openal_err = alGetError()) != AL_NO_ERROR) { + ALLEGRO_ERROR("Could not stop voice: %s\n", + openal_get_err_str(openal_err)); + return 1; + } + return 0; + } + + if (ex_data->thread) { + al_set_thread_should_stop(ex_data->thread); + while (!ex_data->stopped) { + al_wait_cond(voice->cond, voice->mutex); + } + al_join_thread(ex_data->thread, NULL); + ex_data->thread = NULL; + ex_data->stopped = false; + } + + alSourcei(ex_data->source, AL_BUFFER, 0); + alDeleteSources(1, &ex_data->source); + alDeleteBuffers(ex_data->num_buffers, ex_data->buffers); + al_free(ex_data->buffers); + ex_data->buffers = NULL; + + alGetError(); /* required! */ + return 0; +} + +/* The voice_is_playing method should only be called on non-streaming sources, + and should return true if the voice is playing */ +static bool _openal_voice_is_playing(const ALLEGRO_VOICE *voice) +{ + ALLEGRO_AL_DATA *ex_data = voice->extra; + ALint status; + + if (!ex_data) + return false; + + alGetSourcei(ex_data->source, AL_SOURCE_STATE, &status); + return (status == AL_PLAYING); +} + +/* The allocate_voice method should grab a voice from the system, and allocate + any data common to streaming and non-streaming sources. */ +static int _openal_allocate_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_AL_DATA *ex_data; + + /* OpenAL doesn't support very much! */ + switch (voice->depth) { + case ALLEGRO_AUDIO_DEPTH_UINT8: + /* format supported */ + break; + case ALLEGRO_AUDIO_DEPTH_INT8: + ALLEGRO_WARN("OpenAL requires 8-bit data to be unsigned\n"); + return 1; + case ALLEGRO_AUDIO_DEPTH_UINT16: + ALLEGRO_WARN("OpenAL requires 16-bit data to be signed\n"); + return 1; + case ALLEGRO_AUDIO_DEPTH_INT16: + /* format supported */ + break; + case ALLEGRO_AUDIO_DEPTH_UINT24: + ALLEGRO_WARN("OpenAL does not support 24-bit data\n"); + return 1; + case ALLEGRO_AUDIO_DEPTH_INT24: + ALLEGRO_WARN("OpenAL does not support 24-bit data\n"); + return 1; + case ALLEGRO_AUDIO_DEPTH_FLOAT32: + ALLEGRO_WARN("OpenAL does not support 32-bit floating data\n"); + return 1; + default: + ALLEGRO_WARN("Cannot allocate unknown voice depth\n"); + return 1; + } + + ex_data = al_calloc(1, sizeof(*ex_data)); + if (!ex_data) { + ALLEGRO_ERROR("Could not allocate voice data memory\n"); + return 1; + } + + switch (voice->chan_conf) { + case ALLEGRO_CHANNEL_CONF_1: + /* format supported */ + if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) + ex_data->format = AL_FORMAT_MONO8; + else + ex_data->format = AL_FORMAT_MONO16; + break; + case ALLEGRO_CHANNEL_CONF_2: + /* format supported */ + if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) + ex_data->format = AL_FORMAT_STEREO8; + else + ex_data->format = AL_FORMAT_STEREO16; + break; + case ALLEGRO_CHANNEL_CONF_3: + ALLEGRO_ERROR("OpenAL does not support voice with 3 channel configuration\n"); + al_free(ex_data); + return 1; + case ALLEGRO_CHANNEL_CONF_4: + ex_data->format = alGetEnumValue("AL_FORMAT_QUAD16"); + if (ex_data->format) { + ALLEGRO_ERROR("OpenAL cannot allocate voice with 4.0 channel configuration\n"); + al_free(ex_data); + return 1; + } + if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) { + ALLEGRO_ERROR("OpenAL requires 16-bit signed data for 4 channel configuration\n"); + al_free(ex_data); + return 1; + } + /* else it is supported */ + break; + case ALLEGRO_CHANNEL_CONF_5_1: + ex_data->format = alGetEnumValue("AL_FORMAT_51CHN_16"); + if (!ex_data->format) { + ALLEGRO_ERROR("Cannot allocate voice with 5.1 channel configuration\n"); + al_free(ex_data); + return 1; + } + if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) { + ALLEGRO_ERROR("5.1 channel requires 16-bit signed data\n"); + al_free(ex_data); + return 1; + } + /* else it is supported */ + break; + case ALLEGRO_CHANNEL_CONF_6_1: + ex_data->format = alGetEnumValue("AL_FORMAT_61CHN_16"); + if (!ex_data->format) { + ALLEGRO_ERROR("Cannot allocate voice with 6.1 channel configuration\n"); + al_free(ex_data); + return 1; + } + if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) { + ALLEGRO_ERROR("6.1 channel requires 16-bit signed data\n"); + al_free(ex_data); + return 1; + } + /* else it is supported */ + break; + case ALLEGRO_CHANNEL_CONF_7_1: + ex_data->format = alGetEnumValue("AL_FORMAT_71CHN_16"); + if (!ex_data->format) { + ALLEGRO_ERROR("Cannot allocate voice with 7.1 channel configuration\n"); + al_free(ex_data); + return 1; + } + if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) { + ALLEGRO_ERROR("7.1 channel requires 16-bit signed data\n"); + al_free(ex_data); + return 1; + } + /* else it is supported */ + break; + default: + ALLEGRO_ERROR("Cannot allocate voice with unknown channel configuration\n"); + al_free(ex_data); + return 1; + } + + voice->extra = ex_data; + ex_data->thread = NULL; + ex_data->stopped = false; + + return 0; +} + +/* The deallocate_voice method should free the resources for the given voice, + but still retain a hold on the device. The voice should be stopped and + unloaded by the time this is called */ +static void _openal_deallocate_voice(ALLEGRO_VOICE *voice) +{ + ALLEGRO_AL_DATA *ex_data = voice->extra; + ASSERT(ex_data->thread == NULL); + (void)ex_data; + + al_free(voice->extra); + voice->extra = NULL; +} + +/* The get_voice_position method should return the current sample position of + the voice (sample_pos = byte_pos / (depth/8) / channels). This should never + be called on a streaming voice. */ +static unsigned int _openal_get_voice_position(const ALLEGRO_VOICE *voice) +{ + ALLEGRO_AL_DATA *ex_data = voice->extra; + ALint pos; + + alGetSourcei(ex_data->source, AL_SAMPLE_OFFSET, &pos); + if (alGetError() != AL_NO_ERROR) + return 0; + return pos; +} + +/* The set_voice_position method should set the voice's playback position, + given the value in samples. This should never be called on a streaming + voice. */ +static int _openal_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) +{ + ALLEGRO_AL_DATA *ex_data = voice->extra; + + alSourcei(ex_data->source, AL_SAMPLE_OFFSET, val); + if (alGetError() != AL_NO_ERROR) + return 1; + return 0; +} + +ALLEGRO_AUDIO_DRIVER _al_kcm_openal_driver = { + "OpenAL", + + _openal_open, + _openal_close, + + _openal_allocate_voice, + _openal_deallocate_voice, + + _openal_load_voice, + _openal_unload_voice, + + _openal_start_voice, + _openal_stop_voice, + + _openal_voice_is_playing, + + _openal_get_voice_position, + _openal_set_voice_position, + + NULL, + NULL +}; + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/opensl.c b/allegro/addons/audio/opensl.c new file mode 100644 index 00000000..bb6b39f6 --- /dev/null +++ b/allegro/addons/audio/opensl.c @@ -0,0 +1,724 @@ +/* OpenSL: The Standard for Embedded Audio Acceleration + * http://www.khronos.org/opensles/ + * http://www.khronos.org/registry/sles/specs/OpenSL_ES_Specification_1.1.pdf + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_audio.h" + +#include <SLES/OpenSLES.h> + +/* TODO: + * If an android application goes into the suspend state then the opensl resources + * might become 'unrealized' or 'suspended' so care needs to be taken + * to realize them again once the application is resumed. + */ + +/* Not sure if this one is needed, yet */ +// #include <SLES/OpenSLES_Android.h> + +/* Feel free to change MAX_FRAMES and MAX_BUFFERS if it affects + * choppiness for your device. + */ + +/* Number of samples to read in one call to al_voice_update */ +static const int MAX_FRAMES = 2048; + +/* Number of opensl buffers to use */ +#define MAX_BUFFERS 2 + +ALLEGRO_DEBUG_CHANNEL("opensl") + +static SLObjectItf engine; + +static const char * opensl_get_error_string(SLresult result) +{ + switch (result){ + case SL_RESULT_PRECONDITIONS_VIOLATED: return "Preconditions violated"; + case SL_RESULT_PARAMETER_INVALID: return "Invalid parameter"; + case SL_RESULT_MEMORY_FAILURE: return "Memory failure"; + case SL_RESULT_RESOURCE_ERROR: return "Resource error"; + case SL_RESULT_RESOURCE_LOST: return "Resource lost"; + case SL_RESULT_IO_ERROR: return "IO error"; + case SL_RESULT_BUFFER_INSUFFICIENT: return "Insufficient buffer"; + case SL_RESULT_CONTENT_CORRUPTED: return "Content corrupted"; + case SL_RESULT_CONTENT_UNSUPPORTED: return "Content unsupported"; + case SL_RESULT_CONTENT_NOT_FOUND: return "Content not found"; + case SL_RESULT_PERMISSION_DENIED: return "Permission denied"; + case SL_RESULT_FEATURE_UNSUPPORTED: return "Feature unsupported"; + case SL_RESULT_INTERNAL_ERROR: return "Internal error"; + case SL_RESULT_UNKNOWN_ERROR: return "Unknown error"; + case SL_RESULT_OPERATION_ABORTED: return "Operation aborted"; + case SL_RESULT_CONTROL_LOST: return "Control lost"; + } + return "Unknown OpenSL error"; +} + +/* Only the original 'engine' object should be passed here */ +static SLEngineItf getEngine(SLObjectItf engine){ + SLresult result; + SLEngineItf interface; + result = (*engine)->GetInterface(engine, SL_IID_ENGINE, &interface); + if (result == SL_RESULT_SUCCESS){ + return interface; + } else { + ALLEGRO_ERROR("Could not get opensl engine: %s\n", opensl_get_error_string(result)); + return NULL; + } +} + +/* Create an output mixer */ +static SLObjectItf createOutputMixer(SLEngineItf engine){ + SLresult result; + SLObjectItf output; + SLboolean required[1]; + SLInterfaceID ids[1]; + + /* Not all android devices support a mixer that you can control + * the volume on, so just ignore it for now. + */ + required[0] = SL_BOOLEAN_TRUE; + ids[0] = SL_IID_VOLUME; + + result = (*engine)->CreateOutputMix(engine, &output, 0, ids, required); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not create output mix: %s\n", opensl_get_error_string(result)); + return NULL; + } + + result = (*output)->Realize(output, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not realize the output mix: %s\n", opensl_get_error_string(result)); + (*output)->Destroy(output); + return NULL; + } + + return output; +} + +static int _opensl_open(void) +{ + SLresult result; + SLuint32 state; + SLEngineOption options[] = { + { SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE }, + /* + { SL_ENGINEOPTION_MAJORVERSION, (SLuint32) 1 }, + { SL_ENGINEOPTION_MINORVERSION, (SLuint32) 1 }, + */ + }; + + result = slCreateEngine(&engine, 1, options, 0, NULL, NULL); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not open audio device: %s\n", + opensl_get_error_string(result)); + return 1; + } + + /* Transition the engine to the realized state in synchronous mode */ + result = (*engine)->GetState(engine, &state); + if (result == SL_RESULT_SUCCESS){ + switch (state){ + case SL_OBJECT_STATE_UNREALIZED: { + result = (*engine)->Realize(engine, SL_BOOLEAN_FALSE); + break; + } + case SL_OBJECT_STATE_REALIZED: { + /* This is good */ + break; + } + case SL_OBJECT_STATE_SUSPENDED: { + result = (*engine)->Resume(engine, SL_BOOLEAN_FALSE); + break; + } + } + } else { + return 1; + } + + // output = createOutputMixer(getEngine(engine)); + + return 0; +} + +static void _opensl_close(void) +{ + /* + if (output != NULL){ + (*output)->Destroy(output); + output = NULL; + } + */ + + if (engine != NULL){ + (*engine)->Destroy(engine); + engine = NULL; + } +} + +typedef struct OpenSLData{ + /* Output mixer */ + SLObjectItf output; + /* Audio player */ + SLObjectItf player; + volatile enum { PLAYING, STOPPING, STOPPED } status; + + /* load_voice stuff that isn't used, but might be someday */ + /* + const void * data; + int position; + int length; + */ + + /* Size of a single sample: depth * channels */ + int frame_size; + ALLEGRO_THREAD * poll_thread; + + /* local buffers to keep opensl fed since it doesn't copy + * data by default. + */ + char * buffers[MAX_BUFFERS]; +} OpenSLData; + +static SLDataFormat_PCM setupFormat(ALLEGRO_VOICE * voice){ + SLDataFormat_PCM format; + format.formatType = SL_DATAFORMAT_PCM; + + format.numChannels = al_get_channel_count(voice->chan_conf); + + /* TODO: review the channelMasks */ + switch (voice->chan_conf){ + case ALLEGRO_CHANNEL_CONF_1: { + /* Not sure if center is right.. */ + format.channelMask = SL_SPEAKER_FRONT_CENTER; + break; + } + case ALLEGRO_CHANNEL_CONF_2: { + format.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + break; + } + case ALLEGRO_CHANNEL_CONF_3: { + format.channelMask = SL_SPEAKER_FRONT_LEFT | + SL_SPEAKER_FRONT_RIGHT | + SL_SPEAKER_FRONT_CENTER; + break; + } + case ALLEGRO_CHANNEL_CONF_4: { + format.channelMask = SL_SPEAKER_FRONT_LEFT | + SL_SPEAKER_BACK_LEFT | + SL_SPEAKER_FRONT_RIGHT | + SL_SPEAKER_BACK_RIGHT; + break; + } + case ALLEGRO_CHANNEL_CONF_5_1: { + format.channelMask = SL_SPEAKER_FRONT_LEFT | + SL_SPEAKER_BACK_LEFT | + SL_SPEAKER_FRONT_RIGHT | + SL_SPEAKER_BACK_RIGHT | + SL_SPEAKER_FRONT_CENTER | + SL_SPEAKER_LOW_FREQUENCY; + break; + } + case ALLEGRO_CHANNEL_CONF_6_1: { + format.channelMask = SL_SPEAKER_FRONT_LEFT | + SL_SPEAKER_BACK_LEFT | + SL_SPEAKER_FRONT_RIGHT | + SL_SPEAKER_BACK_RIGHT | + SL_SPEAKER_FRONT_CENTER | + SL_SPEAKER_LOW_FREQUENCY | + SL_SPEAKER_SIDE_LEFT | + SL_SPEAKER_SIDE_RIGHT; + + break; + } + case ALLEGRO_CHANNEL_CONF_7_1: { + format.channelMask = SL_SPEAKER_FRONT_LEFT | + SL_SPEAKER_BACK_LEFT | + SL_SPEAKER_FRONT_RIGHT | + SL_SPEAKER_BACK_RIGHT | + SL_SPEAKER_FRONT_CENTER | + SL_SPEAKER_LOW_FREQUENCY | + SL_SPEAKER_SIDE_LEFT | + SL_SPEAKER_SIDE_RIGHT | + SL_SPEAKER_TOP_CENTER; + break; + } + default: { + ALLEGRO_ERROR("Cannot allocate voice with unknown channel configuration\n"); + } + } + + switch (voice->frequency){ + case 8000: format.samplesPerSec = SL_SAMPLINGRATE_8; break; + case 11025: format.samplesPerSec = SL_SAMPLINGRATE_11_025; break; + case 12000: format.samplesPerSec = SL_SAMPLINGRATE_12; break; + case 16000: format.samplesPerSec = SL_SAMPLINGRATE_16; break; + case 22050: format.samplesPerSec = SL_SAMPLINGRATE_22_05; break; + case 24000: format.samplesPerSec = SL_SAMPLINGRATE_24; break; + case 32000: format.samplesPerSec = SL_SAMPLINGRATE_32; break; + case 44100: format.samplesPerSec = SL_SAMPLINGRATE_44_1; break; + case 48000: format.samplesPerSec = SL_SAMPLINGRATE_48; break; + case 64000: format.samplesPerSec = SL_SAMPLINGRATE_64; break; + case 88200: format.samplesPerSec = SL_SAMPLINGRATE_88_2; break; + case 96000: format.samplesPerSec = SL_SAMPLINGRATE_96; break; + case 192000: format.samplesPerSec = SL_SAMPLINGRATE_192; break; + default: { + ALLEGRO_ERROR("Unsupported frequency %d. Using 44100 instead.\n", voice->frequency); + format.samplesPerSec = SL_SAMPLINGRATE_44_1; + voice->frequency = 44100; + } + } + + switch (voice->depth) { + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_INT8: { + format.bitsPerSample = 8; + format.containerSize = 8; + break; + } + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_INT16: { + format.bitsPerSample = 16; + format.containerSize = 16; + break; + } + case ALLEGRO_AUDIO_DEPTH_UINT24: + case ALLEGRO_AUDIO_DEPTH_INT24: { + format.bitsPerSample = 24; + format.containerSize = 32; + break; + } + case ALLEGRO_AUDIO_DEPTH_FLOAT32: { + format.bitsPerSample = 32; + format.containerSize = 32; + break; + } + default: { + ALLEGRO_WARN("Cannot allocate unknown voice depth\n"); + } + } + +#ifdef ALLEGRO_BIG_ENDIAN + format.endianness = SL_BYTEORDER_BIGENDIAN; +#else + format.endianness = SL_BYTEORDER_LITTLEENDIAN; +#endif + + /* Then OpenSL spec says these values are needed for SLDataFormat_PCM_EX + * but not all implementations define that struct. If they do then + * the following code can be used. + */ + + /* + switch (voice->depth){ + case ALLEGRO_AUDIO_DEPTH_UINT8: + case ALLEGRO_AUDIO_DEPTH_UINT16: + case ALLEGRO_AUDIO_DEPTH_UINT24: { + format.representation = SL_PCM_REPRESENTATION_UNSIGNED_INT; + } + case ALLEGRO_AUDIO_DEPTH_INT8: + case ALLEGRO_AUDIO_DEPTH_INT16: + case ALLEGRO_AUDIO_DEPTH_INT24: { + format.representation = SL_PCM_REPRESENTATION_SIGNED_INT; + break; + } + case ALLEGRO_AUDIO_DEPTH_FLOAT32: { + format.representation = SL_PCM_REPRESENTATION_FLOAT; + break; + } + } + */ + + return format; +} + +static SLObjectItf createAudioPlayer(SLEngineItf engine, SLDataSource * source, SLDataSink * sink){ + SLresult result; + SLObjectItf player; + + SLboolean required[1]; + SLInterfaceID ids[1]; + + required[0] = SL_BOOLEAN_TRUE; + ids[0] = SL_IID_BUFFERQUEUE; + + result = (*engine)->CreateAudioPlayer(engine, &player, source, sink, 1, ids, required); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not create audio player: %s\n", opensl_get_error_string(result)); + return NULL; + } + + result = (*player)->Realize(player, SL_BOOLEAN_FALSE); + + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not realize audio player: %s\n", opensl_get_error_string(result)); + return NULL; + } + + return player; +} + +static SLObjectItf makeStreamingPlayer(ALLEGRO_VOICE * voice, SLObjectItf mixer){ + SLDataFormat_PCM format = setupFormat(voice); + SLDataLocator_BufferQueue bufferQueue; + SLDataSource audioSource; + SLDataSink audioSink; + SLDataLocator_OutputMix output; + + bufferQueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE; + bufferQueue.numBuffers = MAX_BUFFERS; + + audioSource.pFormat = (void*) &format; + audioSource.pLocator = (void*) &bufferQueue; + + output.locatorType = SL_DATALOCATOR_OUTPUTMIX; + output.outputMix = mixer; + + audioSink.pLocator = (void*) &output; + audioSink.pFormat = NULL; + + return createAudioPlayer(getEngine(engine), &audioSource, &audioSink); + + /* + SLresult result; + SLVolumeItf volume; + result = (*extra->output)->GetInterface(extra->output, SL_IID_VOLUME, &volume); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not get volume interface: %s\n", opensl_get_error_string(result)); + return 1; + } + */ + +} + +/* Number of active buffers in the queue. Will not be more than MAX_BUFFERS */ +static int bufferCount(SLObjectItf player){ + SLBufferQueueItf queue; + SLBufferQueueState state; + + (*player)->GetInterface(player, SL_IID_BUFFERQUEUE, &queue); + (*queue)->GetState(queue, &state); + return state.count; +} + +/* Attach some data to the OpenSL player. The data is not copied */ +static void enqueue(SLObjectItf player, const void * data, int bytes){ + SLresult result; + SLBufferQueueItf queue; + SLPlayItf play; + + result = (*player)->GetInterface(player, SL_IID_BUFFERQUEUE, &queue); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not get bufferqueue interface: %s\n", opensl_get_error_string(result)); + return; + } + + // ALLEGRO_DEBUG("Play voice data %p\n", data); + + result = (*queue)->Enqueue(queue, data, bytes); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not enqueue data: %s\n", opensl_get_error_string(result)); + return; + } + + // result = (*volume)->SetVolumeLevel(volume, -300); + + result = (*player)->GetInterface(player, SL_IID_PLAY, &play); + + /* In case the player is not playing, make it play */ + result = (*play)->SetPlayState(play, SL_PLAYSTATE_PLAYING); + + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not set play state on OpenSL stream\n"); + } + + /* + SLBufferQueueState state; + result = (*queue)->GetState(queue, &state); + if (result == SL_RESULT_SUCCESS){ + ALLEGRO_DEBUG("Buffer queue state count %d index %d\n", state.count, state.playIndex); + } + */ +} + +static void * opensl_update(ALLEGRO_THREAD * self, void * data){ + ALLEGRO_VOICE *voice = data; + OpenSLData * opensl = voice->extra; + + int bufferIndex = 0; + while (!al_get_thread_should_stop(self)) { + if (opensl->status == PLAYING) { + // unsigned int frames = 4096; + unsigned int frames = MAX_FRAMES; + if (voice->is_streaming) { + // streaming audio + if (bufferCount(opensl->player) < MAX_BUFFERS){ + const void * data = _al_voice_update(voice, voice->mutex, &frames); + if (data){ + /* Copy the data to a local buffer because a call to enqueue + * will use the memory in place and al_voice_update will + * re-use the same buffer for each call so we don't want + * to corrupt memory when the next call to al_voice_update + * is made. + */ + char * buffer = opensl->buffers[bufferIndex]; + memcpy(buffer, data, frames * opensl->frame_size); + enqueue(opensl->player, buffer, frames * opensl->frame_size); + + bufferIndex = (bufferIndex + 1) % MAX_BUFFERS; + } + } else { + al_rest(0.001); + } + } else { + ALLEGRO_ERROR("Unimplemented direct audio\n"); + /* + // direct buffer audio + al_lock_mutex(pv->buffer_mutex); + const char *data = pv->buffer; + unsigned int len = frames * pv->frame_size; + pv->buffer += frames * pv->frame_size; + if (pv->buffer > pv->buffer_end) { + len = pv->buffer_end - data; + pv->buffer = voice->attached_stream->spl_data.buffer.ptr; + voice->attached_stream->pos = 0; + if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) { + pv->status = PV_STOPPING; + } + } else { + voice->attached_stream->pos += frames; + } + al_unlock_mutex(pv->buffer_mutex); + + pa_simple_write(pv->s, data, len, NULL); + */ + } + } else if (opensl->status == STOPPING){ + if (bufferCount(opensl->player) == 0){ + /* When the buffer count is 0 the opensl buffer queue should + * transition to the SL_PLAYSTATE_STOPPED state automatically. + */ + opensl->status = STOPPED; + } + } else if (opensl->status == STOPPED){ + al_rest(0.001); + } + } + + return NULL; +} + +static int _opensl_allocate_voice(ALLEGRO_VOICE *voice) +{ + OpenSLData * data; + int i; + + data = al_calloc(1, sizeof(*data)); + voice->extra = data; + + data->output = createOutputMixer(getEngine(engine)); + if (data->output == NULL){ + al_free(data); + return 1; + } + + data->player = NULL; + /* + data->data = NULL; + data->position = 0; + data->length = voice->buffer_size; + */ + data->frame_size = al_get_channel_count(voice->chan_conf) * al_get_audio_depth_size(voice->depth); + data->status = STOPPED; + data->poll_thread = NULL; + for (i = 0; i < MAX_BUFFERS; i++){ + data->buffers[i] = al_malloc(data->frame_size * MAX_FRAMES); + } + + data->player = makeStreamingPlayer(voice, data->output); + if (data->player == NULL){ + return 1; + } + data->poll_thread = al_create_thread(opensl_update, (void*)voice); + al_start_thread(data->poll_thread); + + return 0; +} + +static void _opensl_deallocate_voice(ALLEGRO_VOICE *voice) +{ + OpenSLData * data = (OpenSLData*) voice->extra; + int i; + if (data->poll_thread != NULL){ + al_set_thread_should_stop(data->poll_thread); + al_join_thread(data->poll_thread, NULL); + al_destroy_thread(data->poll_thread); + data->poll_thread = NULL; + } + + if (data->player != NULL){ + (*data->player)->Destroy(data->player); + data->player = NULL; + } + + if (data->output != NULL){ + (*data->output)->Destroy(data->output); + data->output = NULL; + } + + for (i = 0; i < MAX_BUFFERS; i++){ + al_free(data->buffers[i]); + } + al_free(voice->extra); + voice->extra = NULL; +} + +/* load_voice is only called by attach_sample_instance_to_voice which + * isn't really used, so we leave it unimplemented for now. + */ +static int _opensl_load_voice(ALLEGRO_VOICE *voice, const void *data) +{ + (void) voice; + (void) data; + /* + OpenSLData * extra = (OpenSLData*) voice->extra; + ALLEGRO_DEBUG("Load voice data %p\n", data); + extra->data = data; + extra->position = 0; + */ + + return 1; +} + +static void _opensl_unload_voice(ALLEGRO_VOICE *voice) +{ + (void) voice; + /* + OpenSLData * extra = (OpenSLData*) voice->extra; + extra->data = NULL; + extra->position = 0; + */ +} + +/* +static void updateQueue(SLBufferQueueItf queue, void * context){ + OpenSLData * data = (OpenSLData*) context; + if (data->position < data->length){ + int bytes = data->frame_size * 1024; + if (data->position + bytes > data->length){ + bytes = ((data->length - data->position) / data->frame_size) * data->frame_size; + } + + SLresult result; + ALLEGRO_DEBUG("Enqueue %d bytes\n", bytes); + result = (*queue)->Enqueue(queue, (char*) data->data + data->position, bytes); + data->position += bytes; + } +} +*/ + +static int _opensl_start_voice(ALLEGRO_VOICE *voice) +{ + OpenSLData * extra = (OpenSLData*) voice->extra; + + extra->status = PLAYING; + + /* + result = (*extra->player)->GetInterface(extra->player, SL_IID_BUFFERQUEUE, &queue); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not get bufferqueue interface: %s\n", opensl_get_error_string(result)); + return 1; + } + + ALLEGRO_DEBUG("Start playing voice data %p\n", extra->data); + + result = (*queue)->Enqueue(queue, (char*) extra->data + extra->position, extra->frame_size * 32); + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not enqueue data: %s\n", opensl_get_error_string(result)); + } + extra->position += extra->frame_size * 32; + + result = (*queue)->RegisterCallback(queue, updateQueue, extra); + + if (result != SL_RESULT_SUCCESS){ + ALLEGRO_ERROR("Could not register callback: %s\n", opensl_get_error_string(result)); + } + + // result = (*volume)->SetVolumeLevel(volume, -300); + + result = (*extra->player)->GetInterface(extra->player, SL_IID_PLAY, &play); + result = (*play)->SetPlayState(play, SL_PLAYSTATE_PLAYING); + + if (result == SL_RESULT_SUCCESS){ + ALLEGRO_DEBUG("Started new OpenSL stream\n"); + } + + result = (*queue)->GetState(queue, &state); + if (result == SL_RESULT_SUCCESS){ + ALLEGRO_DEBUG("Buffer queue state count %d index %d\n", state.count, state.playIndex); + } + */ + + return 0; +} + +static int _opensl_stop_voice(ALLEGRO_VOICE* voice) +{ + OpenSLData * data = (OpenSLData*) voice->extra; + if (data->status == PLAYING){ + data->status = STOPPING; + } + + while (data->status != STOPPED){ + al_rest(0.001); + } + + return 0; +} + +static bool _opensl_voice_is_playing(const ALLEGRO_VOICE *voice) +{ + OpenSLData * extra = (OpenSLData*) voice->extra; + return extra->status == PLAYING; +} + +static unsigned int _opensl_get_voice_position(const ALLEGRO_VOICE *voice) +{ + /* TODO */ + (void) voice; + ALLEGRO_ERROR("Unimplemented: _opensl_get_voice_position\n"); + return 0; +} + +static int _opensl_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) +{ + /* TODO */ + (void) voice; + (void) val; + ALLEGRO_ERROR("Unimplemented: _opensl_set_voice_position\n"); + return 1; +} + +ALLEGRO_AUDIO_DRIVER _al_kcm_opensl_driver = { + "OpenSL", + + _opensl_open, + _opensl_close, + + _opensl_allocate_voice, + _opensl_deallocate_voice, + + _opensl_load_voice, + _opensl_unload_voice, + + _opensl_start_voice, + _opensl_stop_voice, + + _opensl_voice_is_playing, + + _opensl_get_voice_position, + _opensl_set_voice_position, + + NULL, + NULL +}; diff --git a/allegro/addons/audio/oss.c b/allegro/addons/audio/oss.c new file mode 100644 index 00000000..c96df3a4 --- /dev/null +++ b/allegro/addons/audio/oss.c @@ -0,0 +1,627 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Open Sound System sound driver. + * + * By Milan Mimica. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_audio.h" + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <string.h> +#include <poll.h> + +ALLEGRO_DEBUG_CHANNEL("oss") + +#if defined ALLEGRO_HAVE_SOUNDCARD_H + #include <soundcard.h> +#elif defined ALLEGRO_HAVE_SYS_SOUNDCARD_H + #include <sys/soundcard.h> +#elif defined ALLEGRO_HAVE_LINUX_SOUNDCARD_H + #include <linux/soundcard.h> +#elif defined ALLEGRO_HAVE_MACHINE_SOUNDCARD_H + #include <machine/soundcard.h> +#endif + +#if OSS_VERSION >= 0x040000 + #define OSS_VER_4 +#else + #define OSS_VER_3 +#endif + +#ifndef AFMT_S16_NE + #ifdef ALLEGRO_BIG_ENDIAN + #define AFMT_S16_NE AFMT_S16_BE + #else + #define AFMT_S16_NE AFMT_S16_LE + #endif +#endif +#ifndef AFMT_U16_NE + #ifdef ALLEGRO_BIG_ENDIAN + #define AFMT_U16_NE AFMT_U16_BE + #else + #define AFMT_U16_NE AFMT_U16_LE + #endif +#endif + + +/* Audio device used by OSS3. + * Make this configurable. */ +static const char* oss_audio_device_ver3 = "/dev/dsp"; + +/* Audio device is dynamically retrived in OSS4. */ +static char oss_audio_device[512]; + +/* timing policy (between 0 and 10), used by OSS4 + * Make this configurable? */ +#ifdef OSS_VER_4 +static const int oss_timing_policy = 5; +#endif + +/* Fragment size, used by OSS3 + * Make this configurable? */ +static int oss_fragsize = (8 << 16) | (10); + +/* Auxiliary buffer used to store silence. */ +#define SIL_BUF_SIZE 1024 + +static bool using_ver_4; + + +typedef struct OSS_VOICE { + int fd; + int volume; + + /* Copied from the parent ALLEGRO_VOICE. Used for convenince. */ + unsigned int len; /* in frames */ + unsigned int frame_size; /* in bytes */ + + volatile bool stopped; + volatile bool stop; + + ALLEGRO_THREAD *poll_thread; +} OSS_VOICE; + + +#ifdef OSS_VER_4 +static int oss_open_ver4() +{ + int mixer_fd, i; + oss_sysinfo sysinfo; + + if ((mixer_fd = open("/dev/mixer", O_RDWR, 0)) == -1) { + switch (errno) { + case ENXIO: + case ENODEV: + ALLEGRO_ERROR("Open Sound System is not running in your system.\n"); + break; + + case ENOENT: + ALLEGRO_ERROR("No /dev/mixer device available in your system.\n"); + ALLEGRO_ERROR("Perhaps Open Sound System is not installed or " + "running.\n"); + break; + + default: + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + } + + return 1; + } + + if (ioctl(mixer_fd, SNDCTL_SYSINFO, &sysinfo) == -1) { + if (errno == ENXIO) { + ALLEGRO_ERROR("OSS has not detected any supported sound hardware in " + "your system.\n"); + } + else if (errno == EINVAL) { + ALLEGRO_INFO("The version of OSS installed on the system is not " + "compatible with OSS4.\n"); + } + else + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + + close(mixer_fd); + return 1; + } + + /* Some OSS implementations (ALSA emulation) don't fail on SNDCTL_SYSINFO even + * though they don't support OSS4. They *seem* to set numcards to 0. */ + if (sysinfo.numcards < 1) { + ALLEGRO_WARN("The version of OSS installed on the system is not " + "compatible with OSS4.\n"); + return 1; + } + + ALLEGRO_INFO("OSS Version: %s\n", sysinfo.version); + ALLEGRO_INFO("Found %i sound cards.\n", sysinfo.numcards); + + for (i = 0; i < sysinfo.numcards; i++) { + oss_audioinfo audioinfo; + memset(&audioinfo, 0, sizeof(oss_audioinfo)); + audioinfo.dev = i; + + ALLEGRO_INFO("Trying sound card no. %i ...\n", audioinfo.dev); + + ioctl(mixer_fd, SNDCTL_AUDIOINFO, &audioinfo); + + if (audioinfo.enabled) { + if (strlen(audioinfo.devnode)) { + strncpy(oss_audio_device, audioinfo.devnode, 511); + } + else if (audioinfo.legacy_device != -1) { + sprintf(oss_audio_device, "/dev/dsp%i", audioinfo.legacy_device); + } + else { + ALLEGRO_ERROR("Cannot find device name.\n"); + } + + ALLEGRO_INFO("Using device: %s\n", oss_audio_device); + + break; + } + else { + ALLEGRO_INFO("Device disabled.\n"); + } + } + + if (i == sysinfo.numcards) { + ALLEGRO_ERROR("Couldn't find a suitable device.\n"); + close(mixer_fd); + return 1; + } + + close(mixer_fd); + + using_ver_4 = true; + + return 0; +} +#endif + +static int oss_open_ver3(void) +{ + const char *config_device; + config_device = al_get_config_value(al_get_system_config(), + "oss", "device"); + if (config_device && config_device[0] != '\0') + oss_audio_device_ver3 = config_device; + + int fd = open(oss_audio_device_ver3, O_WRONLY); + if (fd == -1) { + switch (errno) { + case ENXIO: + case ENODEV: + ALLEGRO_ERROR("Open Sound System is not running in your " + "system.\n"); + break; + + case ENOENT: + ALLEGRO_ERROR("No '%s' device available in your system.\n", + oss_audio_device_ver3); + ALLEGRO_ERROR("Perhaps Open Sound System is not installed " + "or running.\n"); + break; + + default: + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + } + + return 1; + } + + close(fd); + strncpy(oss_audio_device, oss_audio_device_ver3, 511); + ALLEGRO_INFO("Using device: %s\n", oss_audio_device); + + using_ver_4 = false; + + return 0; +} + + +static int oss_open(void) +{ + bool force_oss3 = false; + const char *force_oss3_cfg; + force_oss3_cfg = al_get_config_value(al_get_system_config(), "oss", + "force_ver3"); + if (force_oss3_cfg && force_oss3_cfg[0] != '\0') + force_oss3 = strcmp(force_oss3_cfg, "yes") ? false : true; + + if (force_oss3) { + ALLEGRO_WARN("Skipping OSS4 probe.\n"); + } + +#ifdef OSS_VER_4 + bool inited = false; + if (!force_oss3) { + if (oss_open_ver4()) + ALLEGRO_WARN("OSS ver. 4 init failed, trying ver. 3...\n"); + else + inited = true; + } + if (!inited && oss_open_ver3()) { + ALLEGRO_ERROR("Failed to init OSS.\n"); + return 1; + } +#else + ALLEGRO_INFO("OSS4 support not compiled in. Skipping OSS4 probe.\n"); + if (oss_open_ver3()) { + ALLEGRO_ERROR("Failed to init OSS.\n"); + return 1; + } +#endif + + return 0; +} + + +static void oss_close(void) +{ +} + + +static void oss_deallocate_voice(ALLEGRO_VOICE *voice) +{ + OSS_VOICE *oss_voice = voice->extra; + + /* We do NOT hold the voice mutex here, so this does NOT result in a + * deadlock when oss_update calls _al_voice_update (which tries to + * acquire the voice->mutex). + */ + al_join_thread(oss_voice->poll_thread, NULL); + al_destroy_thread(oss_voice->poll_thread); + + close(oss_voice->fd); + al_free(voice->extra); + voice->extra = NULL; +} + + +static int oss_start_voice(ALLEGRO_VOICE *voice) +{ + OSS_VOICE *ex_data = voice->extra; + ex_data->stop = false; + return 0; +} + + +static int oss_stop_voice(ALLEGRO_VOICE *voice) +{ + OSS_VOICE *ex_data = voice->extra; + + ex_data->stop = true; + if (!voice->is_streaming) { + voice->attached_stream->pos = 0; + } + + while (!ex_data->stopped) + al_rest(0.001); + + return 0; +} + + +static int oss_load_voice(ALLEGRO_VOICE *voice, const void *data) +{ + OSS_VOICE *ex_data = voice->extra; + + /* + * One way to support backward playing would be to do like alsa driver does: + * mmap(2) the FD and write reversed samples into that. To much trouble for + * an optional feature IMO. -- milan + */ + if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_BIDIR) { + ALLEGRO_INFO("Backwards playing not supported by the driver.\n"); + return -1; + } + + voice->attached_stream->pos = 0; + ex_data->len = voice->attached_stream->spl_data.len; + + return 0; + (void)data; +} + + +static void oss_unload_voice(ALLEGRO_VOICE *voice) +{ + (void)voice; +} + + +static bool oss_voice_is_playing(const ALLEGRO_VOICE *voice) +{ + OSS_VOICE *ex_data = voice->extra; + return !ex_data->stopped; +} + + +static unsigned int oss_get_voice_position(const ALLEGRO_VOICE *voice) +{ + return voice->attached_stream->pos; +} + + +static int oss_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) +{ + voice->attached_stream->pos = val; + return 0; +} + + + +/* + * Updates the supplied non-streaming voice. + * buf - Returns a pointer to the buffer containing sample data. + * bytes - The requested size of the sample data buffer. Returns the actual + * size of returned the buffer. + * Updates 'stop', 'pos' and 'reversed' fields of the supplied voice to the + * future position. + */ +static int oss_update_nonstream_voice(ALLEGRO_VOICE *voice, void **buf, int *bytes) +{ + OSS_VOICE *oss_voice = voice->extra; + int bpos = voice->attached_stream->pos * oss_voice->frame_size; + int blen = oss_voice->len * oss_voice->frame_size; + + *buf = (char *)voice->attached_stream->spl_data.buffer.ptr + bpos; + + if (bpos + *bytes > blen) { + *bytes = blen - bpos; + if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) { + oss_voice->stop = true; + voice->attached_stream->pos = 0; + } + if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_LOOP) { + voice->attached_stream->pos = 0; + } + /*else if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_BIDIR) { + oss_voice->reversed = true; + voice->attached_stream->pos = oss_voice->len; + }*/ + return 1; + } + else + voice->attached_stream->pos += *bytes / oss_voice->frame_size; + + return 0; +} + + +static void oss_update_silence(ALLEGRO_VOICE *voice, OSS_VOICE *oss_voice) +{ + char sil_buf[SIL_BUF_SIZE]; + unsigned int silent_samples; + + silent_samples = SIL_BUF_SIZE / + (al_get_audio_depth_size(voice->depth) * + al_get_channel_count(voice->chan_conf)); + al_fill_silence(sil_buf, silent_samples, voice->depth, voice->chan_conf); + if (write(oss_voice->fd, sil_buf, SIL_BUF_SIZE) == -1) { + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + } +} + + +static void* oss_update(ALLEGRO_THREAD *self, void *arg) +{ + ALLEGRO_VOICE *voice = arg; + OSS_VOICE *oss_voice = voice->extra; + (void)self; + + while (!al_get_thread_should_stop(self)) { + /* + For possible eventual non-blocking mode: + + audio_buf_info bi; + + if (ioctl(oss_voice->fd, SNDCTL_DSP_GETOSPACE, &bi) == -1) { + ALLEGRO_ERROR("Error SNDCTL_DSP_GETOSPACE, errno=%i (%s)\n", + errno, strerror(errno)); + return NULL; + } + + len = bi.bytes; + */ + + /* How many bytes are we supposed to try to write at once? */ + unsigned int frames = 1024; + + if (oss_voice->stop && !oss_voice->stopped) { + oss_voice->stopped = true; + } + + if (!oss_voice->stop && oss_voice->stopped) { + oss_voice->stopped = false; + } + + if (!voice->is_streaming && !oss_voice->stopped) { + void *buf; + int bytes = frames * oss_voice->frame_size; + + oss_update_nonstream_voice(voice, &buf, &bytes); + frames = bytes / oss_voice->frame_size; + if (write(oss_voice->fd, buf, bytes) == -1) { + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + if (errno != EINTR) + return NULL; + } + } + else if (voice->is_streaming && !oss_voice->stopped) { + const void *data = _al_voice_update(voice, voice->mutex, &frames); + if (data == NULL) { + oss_update_silence(voice, oss_voice); + continue; + } + if (write(oss_voice->fd, data, frames * oss_voice->frame_size) == -1) { + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + if (errno != EINTR) + return NULL; + } + } + else { + /* If stopped just fill with silence. */ + oss_update_silence(voice, oss_voice); + } + } + + return NULL; +} + + +static int oss_allocate_voice(ALLEGRO_VOICE *voice) +{ + int format; + int chan_count; + + OSS_VOICE *ex_data = al_calloc(1, sizeof(OSS_VOICE)); + if (!ex_data) + return 1; + + ex_data->fd = open(oss_audio_device, O_WRONLY/*, O_NONBLOCK*/); + if (ex_data->fd == -1) { + ALLEGRO_ERROR("Failed to open audio device '%s'.\n", + oss_audio_device); + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + al_free(ex_data); + return 1; + } + + chan_count = al_get_channel_count(voice->chan_conf); + + ex_data->frame_size = chan_count * al_get_audio_depth_size(voice->depth); + if (!ex_data->frame_size) + goto Error; + + ex_data->stop = true; + ex_data->stopped = true; + + if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT8) + format = AFMT_S8; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) + format = AFMT_U8; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) + format = AFMT_S16_NE; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT16) + format = AFMT_U16_NE; +#ifdef OSS_VER_4 + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT24) + format = AFMT_S24_NE; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) + format = AFMT_FLOAT; +#endif + else { + ALLEGRO_ERROR("Unsupported OSS sound format.\n"); + goto Error; + } + + int tmp_format = format; + int tmp_chan_count = chan_count; + unsigned int tmp_freq = voice->frequency; + int tmp_oss_fragsize = oss_fragsize; + + if (using_ver_4) { +#ifdef OSS_VER_4 + int tmp_oss_timing_policy = oss_timing_policy; + if (ioctl(ex_data->fd, SNDCTL_DSP_POLICY, &tmp_oss_timing_policy) == -1) { + ALLEGRO_ERROR("Failed to set_timig policity to '%i'.\n", + tmp_oss_timing_policy); + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + goto Error; + } + ALLEGRO_INFO("Accepted timing policy value: %i\n", tmp_oss_timing_policy); +#endif + } + else { + if (ioctl(ex_data->fd, SNDCTL_DSP_SETFRAGMENT, &tmp_oss_fragsize) == -1) { + ALLEGRO_ERROR("Failed to set fragment size.\n"); + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + goto Error; + } + } + + if (ioctl(ex_data->fd, SNDCTL_DSP_SETFMT, &tmp_format) == -1) { + ALLEGRO_ERROR("Failed to set sample format.\n"); + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + goto Error; + } + if (tmp_format != format) { + ALLEGRO_ERROR("Sample format not supported by the driver.\n"); + goto Error; + } + + if (ioctl(ex_data->fd, SNDCTL_DSP_CHANNELS, &tmp_chan_count)) { + ALLEGRO_ERROR("Failed to set channel count.\n"); + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + goto Error; + } + if (tmp_chan_count != chan_count) { + ALLEGRO_ERROR("Requested sample channe count %i, got %i.\n", + tmp_chan_count, chan_count); + } + + if (ioctl(ex_data->fd, SNDCTL_DSP_SPEED, &tmp_freq) == -1) { + ALLEGRO_ERROR("Failed to set sample rate.\n"); + ALLEGRO_ERROR("errno: %i -- %s\n", errno, strerror(errno)); + goto Error; + } + if (voice->frequency != tmp_freq) { + ALLEGRO_ERROR("Requested sample rate %u, got %iu.\n", voice->frequency, + tmp_freq); + } + + voice->extra = ex_data; + ex_data->poll_thread = al_create_thread(oss_update, (void*)voice); + al_start_thread(ex_data->poll_thread); + + return 0; + +Error: + close(ex_data->fd); + al_free(ex_data); + return 1; +} + + +ALLEGRO_AUDIO_DRIVER _al_kcm_oss_driver = +{ + "OSS", + + oss_open, + oss_close, + + oss_allocate_voice, + oss_deallocate_voice, + + oss_load_voice, + oss_unload_voice, + + oss_start_voice, + oss_stop_voice, + + oss_voice_is_playing, + + oss_get_voice_position, + oss_set_voice_position, + + NULL, + NULL +}; + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/pulseaudio.c b/allegro/addons/audio/pulseaudio.c new file mode 100644 index 00000000..51709571 --- /dev/null +++ b/allegro/addons/audio/pulseaudio.c @@ -0,0 +1,539 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * PulseAudio sound driver. + * + * By Matthew Leverton. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_audio.h" + +#include <pulse/simple.h> +#include <pulse/error.h> +#include <pulse/introspect.h> +#include <pulse/mainloop.h> +#include <stdlib.h> + +ALLEGRO_DEBUG_CHANNEL("PulseAudio") + +enum PULSEAUDIO_VOICE_STATUS { + PV_IDLE, + PV_PLAYING, + PV_STOPPING, + PV_JOIN +}; + +typedef struct PULSEAUDIO_VOICE +{ + pa_simple *s; + unsigned int buffer_size_in_frames; + unsigned int frame_size_in_bytes; + + ALLEGRO_THREAD *poll_thread; + /* status_cond and status are protected by voice->mutex. + * Using another mutex introduces a deadlock if waiting for a change in + * status (while holding voice->mutex, acquired by a higher layer) + * and the background thread tries to acquire voice->mutex as well. + */ + ALLEGRO_COND *status_cond; + enum PULSEAUDIO_VOICE_STATUS status; + + // direct buffer (non-streaming): + ALLEGRO_MUTEX *buffer_mutex; + char *buffer; + char *buffer_end; +} PULSEAUDIO_VOICE; + +#define DEFAULT_BUFFER_SIZE 1024 +#define MIN_BUFFER_SIZE 128 + +static unsigned int get_buffer_size(const ALLEGRO_CONFIG *config) +{ + if (config) { + const char *val = al_get_config_value(config, + "pulseaudio", "buffer_size"); + if (val && val[0] != '\0') { + int n = atoi(val); + if (n < MIN_BUFFER_SIZE) + n = MIN_BUFFER_SIZE; + return n; + } + } + + return DEFAULT_BUFFER_SIZE; +} + +static void sink_info_cb(pa_context *c, const pa_sink_info *i, int eol, + void *userdata) +{ + (void)c; + (void)eol; + + pa_sink_state_t *ret = userdata; + if (!i) + return; + *ret = i->state; +} + +static int pulseaudio_open(void) +{ + /* Use PA_CONTEXT_NOAUTOSPAWN to see if a PA server is running. + * If not, fail - we're better off using ALSA/OSS. + * + * Also check for suspended PA - again better using ALSA/OSS in + * that case (pa_simple_write just blocks until PA is unsuspended + * otherwise). + * + * TODO: Maybe we should have a force flag to the audio driver + * open method, which in the case of PA would spawn a server if + * none is running (and also unsuspend?). + */ + + pa_mainloop *mainloop = pa_mainloop_new(); + pa_context *c = pa_context_new(pa_mainloop_get_api(mainloop), + al_get_app_name()); + if (!c) { + pa_mainloop_free(mainloop); + return 1; + } + + pa_context_connect(c, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); + + while (1) { + /* Don't block or it will hang if there is no server to connect to. */ + const int blocking = 0; + if (pa_mainloop_iterate(mainloop, blocking, NULL) < 0) { + ALLEGRO_ERROR("pa_mainloop_iterate failed\n"); + pa_context_disconnect(c); + pa_context_unref(c); + pa_mainloop_free(mainloop); + return 1; + } + pa_context_state_t s = pa_context_get_state(c); + if (s == PA_CONTEXT_READY) { + ALLEGRO_DEBUG("PA_CONTEXT_READY\n"); + break; + } + if (s == PA_CONTEXT_FAILED) { + ALLEGRO_ERROR("PA_CONTEXT_FAILED\n"); + pa_context_disconnect(c); + pa_context_unref(c); + pa_mainloop_free(mainloop); + return 1; + } + } + + pa_sink_state_t state = 0; + pa_operation *op = pa_context_get_sink_info_list(c, sink_info_cb, &state); + while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) { + pa_mainloop_iterate(mainloop, 1, NULL); + } + /*if (state == PA_SINK_SUSPENDED) { + pa_context_disconnect(c); + pa_context_unref(c); + pa_mainloop_free(mainloop); + return 1; + }*/ + pa_operation_unref(op); + pa_context_disconnect(c); + pa_context_unref(c); + pa_mainloop_free(mainloop); + return 0; +} + +static void pulseaudio_close(void) +{ +} + +static void *pulseaudio_update(ALLEGRO_THREAD *self, void *data) +{ + ALLEGRO_VOICE *voice = data; + PULSEAUDIO_VOICE *pv = voice->extra; + (void)self; + + for (;;) { + enum PULSEAUDIO_VOICE_STATUS status; + + al_lock_mutex(voice->mutex); + while ((status = pv->status) == PV_IDLE) { + al_wait_cond(pv->status_cond, voice->mutex); + } + al_unlock_mutex(voice->mutex); + + if (status == PV_JOIN) { + break; + } + + if (status == PV_PLAYING) { + unsigned int frames = pv->buffer_size_in_frames; + if (voice->is_streaming) { + // streaming audio + const void *data = _al_voice_update(voice, voice->mutex, &frames); + if (data) { + pa_simple_write(pv->s, data, + frames * pv->frame_size_in_bytes, NULL); + } + } + else { + // direct buffer audio + al_lock_mutex(pv->buffer_mutex); + const char *data = pv->buffer; + unsigned int len = frames * pv->frame_size_in_bytes; + pv->buffer += frames * pv->frame_size_in_bytes; + if (pv->buffer > pv->buffer_end) { + len = pv->buffer_end - data; + pv->buffer = voice->attached_stream->spl_data.buffer.ptr; + voice->attached_stream->pos = 0; + if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) { + al_lock_mutex(voice->mutex); + pv->status = PV_STOPPING; + al_broadcast_cond(pv->status_cond); + al_unlock_mutex(voice->mutex); + } + } + else { + voice->attached_stream->pos += frames; + } + al_unlock_mutex(pv->buffer_mutex); + + pa_simple_write(pv->s, data, len, NULL); + } + } + else if (status == PV_STOPPING) { + pa_simple_drain(pv->s, NULL); + al_lock_mutex(voice->mutex); + pv->status = PV_IDLE; + al_broadcast_cond(pv->status_cond); + al_unlock_mutex(voice->mutex); + } + } + + return NULL; +} + +static int pulseaudio_allocate_voice(ALLEGRO_VOICE *voice) +{ + PULSEAUDIO_VOICE *pv = al_malloc(sizeof(PULSEAUDIO_VOICE)); + pa_sample_spec ss; + pa_buffer_attr ba; + + ss.channels = al_get_channel_count(voice->chan_conf); + ss.rate = voice->frequency; + + if (voice->depth == ALLEGRO_AUDIO_DEPTH_UINT8) + ss.format = PA_SAMPLE_U8; + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT16) + ss.format = PA_SAMPLE_S16NE; +#if PA_API_VERSION > 11 + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_INT24) + ss.format = PA_SAMPLE_S24NE; +#endif + else if (voice->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) + ss.format = PA_SAMPLE_FLOAT32NE; + else { + ALLEGRO_ERROR("Unsupported PulseAudio sound format.\n"); + al_free(pv); + return 1; + } + + // These settings match what pulseaudio does by default, but with a slightly lower latency. + // The latency can also be controlled via PULSE_LATENCY_MSEC environment variable. + ba.maxlength = -1; + ba.tlength = pa_usec_to_bytes(50 * 1000, &ss); // 50 ms of latency by default. + ba.prebuf = -1; + ba.minreq = -1; + ba.fragsize = -1; + + pv->s = pa_simple_new( + NULL, // Use the default server. + al_get_app_name(), + PA_STREAM_PLAYBACK, + NULL, // Use the default device. + "Allegro Voice", + &ss, + NULL, // Use default channel map + &ba, + NULL // Ignore error code. + ); + + if (!pv->s) { + al_free(pv); + return 1; + } + + voice->extra = pv; + + pv->buffer_size_in_frames = get_buffer_size(al_get_system_config()); + pv->frame_size_in_bytes = ss.channels * al_get_audio_depth_size(voice->depth); + + pv->status = PV_IDLE; + //pv->status_mutex = al_create_mutex(); + pv->status_cond = al_create_cond(); + pv->buffer_mutex = al_create_mutex(); + + pv->poll_thread = al_create_thread(pulseaudio_update, (void*)voice); + al_start_thread(pv->poll_thread); + + return 0; +} + +static void pulseaudio_deallocate_voice(ALLEGRO_VOICE *voice) +{ + PULSEAUDIO_VOICE *pv = voice->extra; + + al_lock_mutex(voice->mutex); + pv->status = PV_JOIN; + al_broadcast_cond(pv->status_cond); + al_unlock_mutex(voice->mutex); + + /* We do NOT hold the voice mutex here, so this does NOT result in a + * deadlock when the thread calls _al_voice_update. + */ + al_join_thread(pv->poll_thread, NULL); + al_destroy_thread(pv->poll_thread); + + al_destroy_cond(pv->status_cond); + al_destroy_mutex(pv->buffer_mutex); + + pa_simple_free(pv->s); + al_free(pv); +} + +static int pulseaudio_load_voice(ALLEGRO_VOICE *voice, const void *data) +{ + PULSEAUDIO_VOICE *pv = voice->extra; + (void)data; + + if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_BIDIR) { + ALLEGRO_INFO("Backwards playing not supported by the driver.\n"); + return 1; + } + + voice->attached_stream->pos = 0; + + pv->buffer = voice->attached_stream->spl_data.buffer.ptr; + pv->buffer_end = pv->buffer + + (voice->attached_stream->spl_data.len) * pv->frame_size_in_bytes; + + return 0; +} + +static void pulseaudio_unload_voice(ALLEGRO_VOICE *voice) +{ + (void) voice; +} + +static int pulseaudio_start_voice(ALLEGRO_VOICE *voice) +{ + PULSEAUDIO_VOICE *pv = voice->extra; + int ret; + + /* We hold the voice->mutex already. */ + + if (pv->status == PV_IDLE) { + pv->status = PV_PLAYING; + al_broadcast_cond(pv->status_cond); + ret = 0; + } + else { + ret = 1; + } + + return ret; +} + +static int pulseaudio_stop_voice(ALLEGRO_VOICE *voice) +{ + PULSEAUDIO_VOICE *pv = voice->extra; + + /* We hold the voice->mutex already. */ + + if (pv->status == PV_PLAYING) { + pv->status = PV_STOPPING; + al_broadcast_cond(pv->status_cond); + } + + while (pv->status != PV_IDLE) { + al_wait_cond(pv->status_cond, voice->mutex); + } + + return 0; +} + +static bool pulseaudio_voice_is_playing(const ALLEGRO_VOICE *voice) +{ + PULSEAUDIO_VOICE *pv = voice->extra; + return (pv->status == PV_PLAYING); +} + +static unsigned int pulseaudio_get_voice_position(const ALLEGRO_VOICE *voice) +{ + return voice->attached_stream->pos; +} + +static int pulseaudio_set_voice_position(ALLEGRO_VOICE *voice, unsigned int pos) +{ + PULSEAUDIO_VOICE *pv = voice->extra; + + pa_simple_drain(pv->s, NULL); + + al_lock_mutex(pv->buffer_mutex); + voice->attached_stream->pos = pos; + pv->buffer = (char *)voice->attached_stream->spl_data.buffer.ptr + + pos * pv->frame_size_in_bytes; + al_unlock_mutex(pv->buffer_mutex); + + return 0; +} + +/* Recording */ + +typedef struct PULSEAUDIO_RECORDER { + pa_simple *s; + pa_sample_spec ss; + pa_buffer_attr ba; +} PULSEAUDIO_RECORDER; + +static void *pulse_audio_update_recorder(ALLEGRO_THREAD *t, void *data) +{ + ALLEGRO_AUDIO_RECORDER *r = (ALLEGRO_AUDIO_RECORDER *) data; + PULSEAUDIO_RECORDER *pa = (PULSEAUDIO_RECORDER *) r->extra; + ALLEGRO_EVENT user_event; + uint8_t *null_buffer; + unsigned int fragment_i = 0; + + null_buffer = al_malloc(1024); + if (!null_buffer) { + ALLEGRO_ERROR("Unable to create buffer for draining PulseAudio.\n"); + return NULL; + } + + while (!al_get_thread_should_stop(t)) + { + al_lock_mutex(r->mutex); + if (!r->is_recording) { + /* Even if not recording, we still want to read from the PA server. + Otherwise it will buffer everything and spit it all out whenever + the recording resumes. */ + al_unlock_mutex(r->mutex); + pa_simple_read(pa->s, null_buffer, 1024, NULL); + } + else { + ALLEGRO_AUDIO_RECORDER_EVENT *e; + al_unlock_mutex(r->mutex); + if (pa_simple_read(pa->s, r->fragments[fragment_i], r->fragment_size, NULL) >= 0) { + user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; + e = al_get_audio_recorder_event(&user_event); + e->buffer = r->fragments[fragment_i]; + e->samples = r->samples; + al_emit_user_event(&r->source, &user_event, NULL); + + if (++fragment_i == r->fragment_count) { + fragment_i = 0; + } + } + } + } + + al_free(null_buffer); + return NULL; +}; + +static int pulseaudio_allocate_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + PULSEAUDIO_RECORDER *pa; + + pa = al_calloc(1, sizeof(*pa)); + if (!pa) { + ALLEGRO_ERROR("Unable to allocate memory for PULSEAUDIO_RECORDER.\n"); + return 1; + } + + pa->ss.channels = al_get_channel_count(r->chan_conf); + pa->ss.rate = r->frequency; + + if (r->depth == ALLEGRO_AUDIO_DEPTH_UINT8) + pa->ss.format = PA_SAMPLE_U8; + else if (r->depth == ALLEGRO_AUDIO_DEPTH_INT16) + pa->ss.format = PA_SAMPLE_S16NE; +#if PA_API_VERSION > 11 + else if (r->depth == ALLEGRO_AUDIO_DEPTH_INT24) + pa->ss.format = PA_SAMPLE_S24NE; +#endif + else if (r->depth == ALLEGRO_AUDIO_DEPTH_FLOAT32) + pa->ss.format = PA_SAMPLE_FLOAT32NE; + else { + ALLEGRO_ERROR("Unsupported PulseAudio sound format (depth).\n"); + al_free(pa); + return 1; + } + + /* maximum length of the PulseAudio buffer. -1 => let the server decide. */ + pa->ba.maxlength = -1; + + /* fragment size (bytes) controls how much data is returned back per read. + The documentation recommends -1 for default behavior, but that sets a + latency of around 2 seconds. Lower value decreases latency but increases + overhead. + + The following attempts to set it (the base latency) to 1/8 of a second. + */ + pa->ba.fragsize = (r->sample_size * r->frequency) / 8; + + pa->s = pa_simple_new(NULL, al_get_app_name(), PA_STREAM_RECORD, NULL, "Allegro Audio Recorder", &pa->ss, NULL, &pa->ba, NULL); + if (!pa->s) { + ALLEGRO_ERROR("pa_simple_new() failed.\n"); + al_free(pa); + return 1; + } + + r->thread = al_create_thread(pulse_audio_update_recorder, r); + r->extra = pa; + + return 0; +}; + +static void pulseaudio_deallocate_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + PULSEAUDIO_RECORDER *pa = (PULSEAUDIO_RECORDER *) r->extra; + + pa_simple_free(pa->s); + al_free(r->extra); +} + +ALLEGRO_AUDIO_DRIVER _al_kcm_pulseaudio_driver = +{ + "PulseAudio", + + pulseaudio_open, + pulseaudio_close, + + pulseaudio_allocate_voice, + pulseaudio_deallocate_voice, + + pulseaudio_load_voice, + pulseaudio_unload_voice, + + pulseaudio_start_voice, + pulseaudio_stop_voice, + + pulseaudio_voice_is_playing, + + pulseaudio_get_voice_position, + pulseaudio_set_voice_position, + + pulseaudio_allocate_recorder, + pulseaudio_deallocate_recorder +}; + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/audio/recorder.c b/allegro/addons/audio/recorder.c new file mode 100644 index 00000000..c5a2b191 --- /dev/null +++ b/allegro/addons/audio/recorder.c @@ -0,0 +1,175 @@ +/* + * Allegro audio recording + */ + +#include "allegro5/allegro_audio.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/internal/aintern_audio_cfg.h" +#include "allegro5/internal/aintern.h" + +ALLEGRO_DEBUG_CHANNEL("audio") + +ALLEGRO_STATIC_ASSERT(recorder, + sizeof(ALLEGRO_AUDIO_RECORDER_EVENT) <= sizeof(ALLEGRO_EVENT)); + + +/* Function: al_create_audio_recorder + */ +ALLEGRO_AUDIO_RECORDER *al_create_audio_recorder(size_t fragment_count, + unsigned int samples, unsigned int frequency, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) +{ + size_t i; + + ALLEGRO_AUDIO_RECORDER *r; + ASSERT(_al_kcm_driver); + + if (!_al_kcm_driver->allocate_recorder) { + ALLEGRO_ERROR("Audio driver does not support recording.\n"); + return false; + } + + r = al_calloc(1, sizeof(*r)); + if (!r) { + ALLEGRO_ERROR("Unable to allocate memory for ALLEGRO_AUDIO_RECORDER\n"); + return false; + } + + r->fragment_count = fragment_count; + r->samples = samples; + r->frequency = frequency, + r->depth = depth; + r->chan_conf = chan_conf; + + r->sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth); + + r->fragments = al_malloc(r->fragment_count * sizeof(uint8_t *)); + if (!r->fragments) { + al_free(r); + ALLEGRO_ERROR("Unable to allocate memory for ALLEGRO_AUDIO_RECORDER fragments\n"); + return false; + } + + r->fragment_size = r->samples * r->sample_size; + for (i = 0; i < fragment_count; ++i) { + r->fragments[i] = al_malloc(r->fragment_size); + if (!r->fragments[i]) { + size_t j; + for (j = 0; j < i; ++j) { + al_free(r->fragments[j]); + } + al_free(r->fragments); + + ALLEGRO_ERROR("Unable to allocate memory for ALLEGRO_AUDIO_RECORDER fragments\n"); + return false; + } + } + + if (_al_kcm_driver->allocate_recorder(r)) { + ALLEGRO_ERROR("Failed to allocate recorder from driver\n"); + return false; + } + + r->is_recording = false; + r->mutex = al_create_mutex(); + r->cond = al_create_cond(); + + al_init_user_event_source(&r->source); + + if (r->thread) { + /* the driver should have created a thread */ + al_start_thread(r->thread); + } + + return r; +}; + +/* Function: al_start_audio_recorder + */ +bool al_start_audio_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + ALLEGRO_ASSERT(r); + + al_lock_mutex(r->mutex); + r->is_recording = true; + al_signal_cond(r->cond); + al_unlock_mutex(r->mutex); + + return true; +} + +/* Function: al_stop_audio_recorder + */ +void al_stop_audio_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + al_lock_mutex(r->mutex); + if (r->is_recording) { + r->is_recording = false; + al_signal_cond(r->cond); + } + al_unlock_mutex(r->mutex); +} + +/* Function: al_is_audio_recorder_recording + */ +bool al_is_audio_recorder_recording(ALLEGRO_AUDIO_RECORDER *r) +{ + bool is_recording; + + al_lock_mutex(r->mutex); + is_recording = r->is_recording; + al_unlock_mutex(r->mutex); + + return is_recording; +} + +/* Function: al_get_audio_recorder_event + */ +ALLEGRO_AUDIO_RECORDER_EVENT *al_get_audio_recorder_event(ALLEGRO_EVENT *event) +{ + ASSERT(event->any.type == ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT); + return (ALLEGRO_AUDIO_RECORDER_EVENT *) event; +} + +/* Function: al_get_audio_recorder_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_audio_recorder_event_source(ALLEGRO_AUDIO_RECORDER *r) +{ + return &r->source; +} + +/* Function: al_destroy_audio_recorder + */ +void al_destroy_audio_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + size_t i; + + if (!r) + return; + + if (r->thread) { + al_set_thread_should_stop(r->thread); + + al_lock_mutex(r->mutex); + r->is_recording = false; + al_signal_cond(r->cond); + al_unlock_mutex(r->mutex); + + al_join_thread(r->thread, NULL); + al_destroy_thread(r->thread); + } + + if (_al_kcm_driver->deallocate_recorder) { + _al_kcm_driver->deallocate_recorder(r); + } + + al_destroy_user_event_source(&r->source); + al_destroy_mutex(r->mutex); + al_destroy_cond(r->cond); + + for (i = 0; i < r->fragment_count; ++i) { + al_free(r->fragments[i]); + } + al_free(r->fragments); + al_free(r); +} diff --git a/allegro/addons/audio/sdl_audio.c b/allegro/addons/audio/sdl_audio.c new file mode 100644 index 00000000..ef9fc058 --- /dev/null +++ b/allegro/addons/audio/sdl_audio.c @@ -0,0 +1,228 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_audio.h" +#include "allegro5/platform/allegro_internal_sdl.h" + +ALLEGRO_DEBUG_CHANNEL("SDL") + +typedef struct SDL_VOICE +{ + SDL_AudioDeviceID device; + SDL_AudioSpec spec; + ALLEGRO_VOICE *voice; + bool is_playing; +} SDL_VOICE; + +typedef struct SDL_RECORDER +{ + SDL_AudioDeviceID device; + SDL_AudioSpec spec; + unsigned int fragment; +} SDL_RECORDER; + +static void audio_callback(void *userdata, Uint8 *stream, int len) +{ + // TODO: Allegro has those mysterious "non-streaming" samples, but I + // can't figure out what their purpose is and how would I play them... + + SDL_VOICE *sv = userdata; + ALLEGRO_SAMPLE_INSTANCE *instance = sv->voice->attached_stream; + ALLEGRO_SAMPLE *sample = &instance->spl_data; + + unsigned int frames = sv->spec.samples; + const void *data = _al_voice_update(sv->voice, sv->voice->mutex, &frames); + if (data) { + // FIXME: What is frames for? + memcpy(stream, sample->buffer.ptr, len); + } +} + +static int sdl_open(void) +{ + return 0; +} + +static void sdl_close(void) +{ +} + +static SDL_AudioFormat allegro_format_to_sdl(ALLEGRO_AUDIO_DEPTH d) +{ + if (d == ALLEGRO_AUDIO_DEPTH_INT8) return AUDIO_S8; + if (d == ALLEGRO_AUDIO_DEPTH_UINT8) return AUDIO_U8; + if (d == ALLEGRO_AUDIO_DEPTH_INT16) return AUDIO_S16; + if (d == ALLEGRO_AUDIO_DEPTH_UINT16) return AUDIO_U16; + return AUDIO_F32; +} + +static ALLEGRO_AUDIO_DEPTH sdl_format_to_allegro(SDL_AudioFormat d) +{ + if (d == AUDIO_S8) return ALLEGRO_AUDIO_DEPTH_INT8; + if (d == AUDIO_U8) return ALLEGRO_AUDIO_DEPTH_UINT8; + if (d == AUDIO_S16) return ALLEGRO_AUDIO_DEPTH_INT16; + if (d == AUDIO_U16) return ALLEGRO_AUDIO_DEPTH_UINT16; + return ALLEGRO_AUDIO_DEPTH_FLOAT32; +} + +static int sdl_allocate_voice(ALLEGRO_VOICE *voice) +{ + SDL_VOICE *sv = al_malloc(sizeof *sv); + SDL_AudioSpec want; + memset(&want, 0, sizeof want); + + want.freq = voice->frequency; + want.format = allegro_format_to_sdl(voice->depth); + want.channels = al_get_channel_count(voice->chan_conf); + // TODO: Should make this configurable somehow + want.samples = 4096; + want.callback = audio_callback; + want.userdata = sv; + + sv->device = SDL_OpenAudioDevice(NULL, 0, &want, &sv->spec, + SDL_AUDIO_ALLOW_FORMAT_CHANGE); + + voice->extra = sv; + sv->voice = voice; + // we allow format change above so need to update here + voice->depth = sdl_format_to_allegro(sv->spec.format); + + return 0; +} + +static void sdl_deallocate_voice(ALLEGRO_VOICE *voice) +{ + SDL_VOICE *sv = voice->extra; + SDL_CloseAudioDevice(sv->device); + al_free(sv); +} + +static int sdl_load_voice(ALLEGRO_VOICE *voice, const void *data) +{ + (void)data; + voice->attached_stream->pos = 0; + return 0; +} + +static void sdl_unload_voice(ALLEGRO_VOICE *voice) +{ + (void) voice; +} + +static int sdl_start_voice(ALLEGRO_VOICE *voice) +{ + SDL_VOICE *sv = voice->extra; + sv->is_playing = true; + SDL_PauseAudioDevice(sv->device, 0); + return 0; +} + +static int sdl_stop_voice(ALLEGRO_VOICE *voice) +{ + SDL_VOICE *sv = voice->extra; + sv->is_playing = false; + SDL_PauseAudioDevice(sv->device, 1); + return 0; +} + +static bool sdl_voice_is_playing(const ALLEGRO_VOICE *voice) +{ + SDL_VOICE *sv = voice->extra; + return sv->is_playing; +} + +static unsigned int sdl_get_voice_position(const ALLEGRO_VOICE *voice) +{ + return voice->attached_stream->pos; +} + +static int sdl_set_voice_position(ALLEGRO_VOICE *voice, unsigned int pos) +{ + voice->attached_stream->pos = pos; + return 0; +} + +static void recorder_callback(void *userdata, Uint8 *stream, int len) +{ + ALLEGRO_AUDIO_RECORDER *r = (ALLEGRO_AUDIO_RECORDER *) userdata; + SDL_RECORDER *sdl = (SDL_RECORDER *) r->extra; + + al_lock_mutex(r->mutex); + if (!r->is_recording) { + al_unlock_mutex(r->mutex); + return; + } + + while (len > 0) { + int count = SDL_min(len, r->samples * r->sample_size); + memcpy(r->fragments[sdl->fragment], stream, count); + + ALLEGRO_EVENT user_event; + ALLEGRO_AUDIO_RECORDER_EVENT *e; + user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; + e = al_get_audio_recorder_event(&user_event); + e->buffer = r->fragments[sdl->fragment]; + e->samples = count / r->sample_size; + al_emit_user_event(&r->source, &user_event, NULL); + + sdl->fragment++; + if (sdl->fragment == r->fragment_count) { + sdl->fragment = 0; + } + len -= count; + } + + al_unlock_mutex(r->mutex); +} + +static int sdl_allocate_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + SDL_RECORDER *sdl; + + sdl = al_calloc(1, sizeof(*sdl)); + if (!sdl) { + ALLEGRO_ERROR("Unable to allocate memory for SDL_RECORDER.\n"); + return 1; + } + + SDL_AudioSpec want; + memset(&want, 0, sizeof want); + + want.freq = r->frequency; + want.format = allegro_format_to_sdl(r->depth); + want.channels = al_get_channel_count(r->chan_conf); + want.samples = r->samples; + want.callback = recorder_callback; + want.userdata = r; + + sdl->device = SDL_OpenAudioDevice(NULL, 1, &want, &sdl->spec, 0); + sdl->fragment = 0; + r->extra = sdl; + + SDL_PauseAudioDevice(sdl->device, 0); + + return 0; +} + +static void sdl_deallocate_recorder(ALLEGRO_AUDIO_RECORDER *r) +{ + SDL_RECORDER *sdl = (SDL_RECORDER *) r->extra; + SDL_CloseAudioDevice(sdl->device); + al_free(r->extra); +} + +ALLEGRO_AUDIO_DRIVER _al_kcm_sdl_driver = +{ + "SDL", + sdl_open, + sdl_close, + sdl_allocate_voice, + sdl_deallocate_voice, + sdl_load_voice, + sdl_unload_voice, + sdl_start_voice, + sdl_stop_voice, + sdl_voice_is_playing, + sdl_get_voice_position, + sdl_set_voice_position, + sdl_allocate_recorder, + sdl_deallocate_recorder +}; diff --git a/allegro/addons/color/CMakeLists.txt b/allegro/addons/color/CMakeLists.txt new file mode 100644 index 00000000..4aa2ec78 --- /dev/null +++ b/allegro/addons/color/CMakeLists.txt @@ -0,0 +1,21 @@ +set(COLOR_SOURCES color.c) + +set(COLOR_INCLUDE_FILES + allegro5/allegro_color.h + ) + +set_our_header_properties(${COLOR_INCLUDE_FILES}) + +add_our_addon_library(allegro_color + AllegroColor-${ALLEGRO_SOVERSION} + "${COLOR_SOURCES};${COLOR_INCLUDE_FILES}" + "-DALLEGRO_COLOR_SRC" + "${ALLEGRO_LINK_WITH}" + ) + +install_our_headers(${COLOR_INCLUDE_FILES}) + +add_addon(color) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/color/allegro5/allegro_color.h b/allegro/addons/color/allegro5/allegro_color.h new file mode 100644 index 00000000..d0069ce6 --- /dev/null +++ b/allegro/addons/color/allegro5/allegro_color.h @@ -0,0 +1,90 @@ +#ifndef __al_included_allegro5_allegro_color_h +#define __al_included_allegro5_allegro_color_h + +#include "allegro5/allegro.h" + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_COLOR_SRC + #define _ALLEGRO_COLOR_DLL __declspec(dllexport) + #else + #define _ALLEGRO_COLOR_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_COLOR_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_COLOR_FUNC(type, name, args) _ALLEGRO_COLOR_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_COLOR_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_COLOR_FUNC(type, name, args) extern _ALLEGRO_COLOR_DLL type name args +#else + #define ALLEGRO_COLOR_FUNC AL_FUNC +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +ALLEGRO_COLOR_FUNC(uint32_t, al_get_allegro_color_version, (void)); + +ALLEGRO_COLOR_FUNC(void, al_color_hsv_to_rgb, (float hue, float saturation, + float value, float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_hsl, (float red, float green, float blue, + float *hue, float *saturation, float *lightness)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_hsv, (float red, float green, float blue, + float *hue, float *saturation, float *value)); +ALLEGRO_COLOR_FUNC(void, al_color_hsl_to_rgb, (float hue, float saturation, float lightness, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(bool, al_color_name_to_rgb, (char const *name, float *r, float *g, + float *b)); +ALLEGRO_COLOR_FUNC(const char*, al_color_rgb_to_name, (float r, float g, float b)); +ALLEGRO_COLOR_FUNC(void, al_color_cmyk_to_rgb, (float cyan, float magenta, float yellow, + float key, float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_cmyk, (float red, float green, float blue, + float *cyan, float *magenta, float *yellow, float *key)); +ALLEGRO_COLOR_FUNC(void, al_color_yuv_to_rgb, (float y, float u, float v, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_yuv, (float red, float green, float blue, + float *y, float *u, float *v)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_html, (float red, float green, float blue, + char *string)); +ALLEGRO_COLOR_FUNC(bool, al_color_html_to_rgb, (char const *string, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_yuv, (float y, float u, float v)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_cmyk, (float c, float m, float y, float k)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_hsl, (float h, float s, float l)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_hsv, (float h, float s, float v)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_name, (char const *name)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_html, (char const *string)); +ALLEGRO_COLOR_FUNC(void, al_color_xyz_to_rgb, (float x, float y, float z, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_xyz, (float red, float green, float blue, + float *x, float *y, float *z)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_xyz, (float x, float y, float z)); +ALLEGRO_COLOR_FUNC(void, al_color_lab_to_rgb, (float l, float a, float b, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_lab, (float red, float green, float blue, + float *l, float *a, float *b)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_lab, (float l, float a, float b)); +ALLEGRO_COLOR_FUNC(void, al_color_xyy_to_rgb, (float x, float y, float y2, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_xyy, (float red, float green, float blue, + float *x, float *y, float *y2)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_xyy, (float x, float y, float y2)); +ALLEGRO_COLOR_FUNC(double, al_color_distance_ciede2000, (ALLEGRO_COLOR c1, ALLEGRO_COLOR c2)); +ALLEGRO_COLOR_FUNC(void, al_color_lch_to_rgb, (float l, float c, float h, + float *red, float *green, float *blue)); +ALLEGRO_COLOR_FUNC(void, al_color_rgb_to_lch, (float red, float green, float blue, + float *l, float *c, float *h)); +ALLEGRO_COLOR_FUNC(ALLEGRO_COLOR, al_color_lch, (float l, float c, float h)); +ALLEGRO_COLOR_FUNC(bool, al_is_color_valid, (ALLEGRO_COLOR color)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/addons/color/color.c b/allegro/addons/color/color.c new file mode 100644 index 00000000..224535a5 --- /dev/null +++ b/allegro/addons/color/color.c @@ -0,0 +1,817 @@ +/* Addon which allows converting between different color + * representations. Included are: + * - HSV (like A4) + * - names (mostly X11 color names, except where CSS redefines them) + * - HSL (the "better" HSV) + * - CMYK (a bit like the opposite of RGB) + * - YUV (the Y channel is quite useful for creating grayscale pictures) + */ +#include "allegro5/allegro.h" +#include "allegro5/allegro_color.h" +#include "allegro5/internal/aintern.h" +#include <math.h> +#include <stdio.h> + +typedef struct { + char const *name; + int r, g, b; +} ColorName; + +/* Taken from http://www.w3.org/TR/2010/PR-css3-color-20101028/#svg-color + * This must be sorted correctly for binary search. + */ +static ColorName _al_color_names[] = { + {"aliceblue", 0xf0, 0xf8, 0xff}, + {"antiquewhite", 0xfa, 0xeb, 0xd7}, + {"aqua", 0x00, 0xff, 0xff}, + {"aquamarine", 0x7f, 0xff, 0xd4}, + {"azure", 0xf0, 0xff, 0xff}, + {"beige", 0xf5, 0xf5, 0xdc}, + {"bisque", 0xff, 0xe4, 0xc4}, + {"black", 0x00, 0x00, 0x00}, + {"blanchedalmond", 0xff, 0xeb, 0xcd}, + {"blue", 0x00, 0x00, 0xff}, + {"blueviolet", 0x8a, 0x2b, 0xe2}, + {"brown", 0xa5, 0x2a, 0x2a}, + {"burlywood", 0xde, 0xb8, 0x87}, + {"cadetblue", 0x5f, 0x9e, 0xa0}, + {"chartreuse", 0x7f, 0xff, 0x00}, + {"chocolate", 0xd2, 0x69, 0x1e}, + {"coral", 0xff, 0x7f, 0x50}, + {"cornflowerblue", 0x64, 0x95, 0xed}, + {"cornsilk", 0xff, 0xf8, 0xdc}, + {"crimson", 0xdc, 0x14, 0x3c}, + {"cyan", 0x00, 0xff, 0xff}, + {"darkblue", 0x00, 0x00, 0x8b}, + {"darkcyan", 0x00, 0x8b, 0x8b}, + {"darkgoldenrod", 0xb8, 0x86, 0x0b}, + {"darkgray", 0xa9, 0xa9, 0xa9}, + {"darkgreen", 0x00, 0x64, 0x00}, + {"darkgrey", 0xa9, 0xa9, 0xa9}, + {"darkkhaki", 0xbd, 0xb7, 0x6b}, + {"darkmagenta", 0x8b, 0x00, 0x8b}, + {"darkolivegreen", 0x55, 0x6b, 0x2f}, + {"darkorange", 0xff, 0x8c, 0x00}, + {"darkorchid", 0x99, 0x32, 0xcc}, + {"darkred", 0x8b, 0x00, 0x00}, + {"darksalmon", 0xe9, 0x96, 0x7a}, + {"darkseagreen", 0x8f, 0xbc, 0x8f}, + {"darkslateblue", 0x48, 0x3d, 0x8b}, + {"darkslategray", 0x2f, 0x4f, 0x4f}, + {"darkslategrey", 0x2f, 0x4f, 0x4f}, + {"darkturquoise", 0x00, 0xce, 0xd1}, + {"darkviolet", 0x94, 0x00, 0xd3}, + {"deeppink", 0xff, 0x14, 0x93}, + {"deepskyblue", 0x00, 0xbf, 0xff}, + {"dimgray", 0x69, 0x69, 0x69}, + {"dimgrey", 0x69, 0x69, 0x69}, + {"dodgerblue", 0x1e, 0x90, 0xff}, + {"firebrick", 0xb2, 0x22, 0x22}, + {"floralwhite", 0xff, 0xfa, 0xf0}, + {"forestgreen", 0x22, 0x8b, 0x22}, + {"fuchsia", 0xff, 0x00, 0xff}, + {"gainsboro", 0xdc, 0xdc, 0xdc}, + {"ghostwhite", 0xf8, 0xf8, 0xff}, + {"gold", 0xff, 0xd7, 0x00}, + {"goldenrod", 0xda, 0xa5, 0x20}, + {"gray", 0x80, 0x80, 0x80}, + {"green", 0x00, 0x80, 0x00}, + {"greenyellow", 0xad, 0xff, 0x2f}, + {"grey", 0x80, 0x80, 0x80}, + {"honeydew", 0xf0, 0xff, 0xf0}, + {"hotpink", 0xff, 0x69, 0xb4}, + {"indianred", 0xcd, 0x5c, 0x5c}, + {"indigo", 0x4b, 0x00, 0x82}, + {"ivory", 0xff, 0xff, 0xf0}, + {"khaki", 0xf0, 0xe6, 0x8c}, + {"lavender", 0xe6, 0xe6, 0xfa}, + {"lavenderblush", 0xff, 0xf0, 0xf5}, + {"lawngreen", 0x7c, 0xfc, 0x00}, + {"lemonchiffon", 0xff, 0xfa, 0xcd}, + {"lightblue", 0xad, 0xd8, 0xe6}, + {"lightcoral", 0xf0, 0x80, 0x80}, + {"lightcyan", 0xe0, 0xff, 0xff}, + {"lightgoldenrodyellow", 0xfa, 0xfa, 0xd2}, + {"lightgray", 0xd3, 0xd3, 0xd3}, + {"lightgreen", 0x90, 0xee, 0x90}, + {"lightgrey", 0xd3, 0xd3, 0xd3}, + {"lightpink", 0xff, 0xb6, 0xc1}, + {"lightsalmon", 0xff, 0xa0, 0x7a}, + {"lightseagreen", 0x20, 0xb2, 0xaa}, + {"lightskyblue", 0x87, 0xce, 0xfa}, + {"lightslategray", 0x77, 0x88, 0x99}, + {"lightslategrey", 0x77, 0x88, 0x99}, + {"lightsteelblue", 0xb0, 0xc4, 0xde}, + {"lightyellow", 0xff, 0xff, 0xe0}, + {"lime", 0x00, 0xff, 0x00}, + {"limegreen", 0x32, 0xcd, 0x32}, + {"linen", 0xfa, 0xf0, 0xe6}, + {"magenta", 0xff, 0x00, 0xff}, + {"maroon", 0x80, 0x00, 0x00}, + {"mediumaquamarine", 0x66, 0xcd, 0xaa}, + {"mediumblue", 0x00, 0x00, 0xcd}, + {"mediumorchid", 0xba, 0x55, 0xd3}, + {"mediumpurple", 0x93, 0x70, 0xdb}, + {"mediumseagreen", 0x3c, 0xb3, 0x71}, + {"mediumslateblue", 0x7b, 0x68, 0xee}, + {"mediumspringgreen", 0x00, 0xfa, 0x9a}, + {"mediumturquoise", 0x48, 0xd1, 0xcc}, + {"mediumvioletred", 0xc7, 0x15, 0x85}, + {"midnightblue", 0x19, 0x19, 0x70}, + {"mintcream", 0xf5, 0xff, 0xfa}, + {"mistyrose", 0xff, 0xe4, 0xe1}, + {"moccasin", 0xff, 0xe4, 0xb5}, + {"navajowhite", 0xff, 0xde, 0xad}, + {"navy", 0x00, 0x00, 0x80}, + {"oldlace", 0xfd, 0xf5, 0xe6}, + {"olive", 0x80, 0x80, 0x00}, + {"olivedrab", 0x6b, 0x8e, 0x23}, + {"orange", 0xff, 0xa5, 0x00}, + {"orangered", 0xff, 0x45, 0x00}, + {"orchid", 0xda, 0x70, 0xd6}, + {"palegoldenrod", 0xee, 0xe8, 0xaa}, + {"palegreen", 0x98, 0xfb, 0x98}, + {"paleturquoise", 0xaf, 0xee, 0xee}, + {"palevioletred", 0xdb, 0x70, 0x93}, + {"papayawhip", 0xff, 0xef, 0xd5}, + {"peachpuff", 0xff, 0xda, 0xb9}, + {"peru", 0xcd, 0x85, 0x3f}, + {"pink", 0xff, 0xc0, 0xcb}, + {"plum", 0xdd, 0xa0, 0xdd}, + {"powderblue", 0xb0, 0xe0, 0xe6}, + {"purple", 0x80, 0x00, 0x80}, + {"rebeccapurple", 0x66, 0x33, 0x99}, + {"red", 0xff, 0x00, 0x00}, + {"rosybrown", 0xbc, 0x8f, 0x8f}, + {"royalblue", 0x41, 0x69, 0xe1}, + {"saddlebrown", 0x8b, 0x45, 0x13}, + {"salmon", 0xfa, 0x80, 0x72}, + {"sandybrown", 0xf4, 0xa4, 0x60}, + {"seagreen", 0x2e, 0x8b, 0x57}, + {"seashell", 0xff, 0xf5, 0xee}, + {"sienna", 0xa0, 0x52, 0x2d}, + {"silver", 0xc0, 0xc0, 0xc0}, + {"skyblue", 0x87, 0xce, 0xeb}, + {"slateblue", 0x6a, 0x5a, 0xcd}, + {"slategray", 0x70, 0x80, 0x90}, + {"slategrey", 0x70, 0x80, 0x90}, + {"snow", 0xff, 0xfa, 0xfa}, + {"springgreen", 0x00, 0xff, 0x7f}, + {"steelblue", 0x46, 0x82, 0xb4}, + {"tan", 0xd2, 0xb4, 0x8c}, + {"teal", 0x00, 0x80, 0x80}, + {"thistle", 0xd8, 0xbf, 0xd8}, + {"tomato", 0xff, 0x63, 0x47}, + {"turquoise", 0x40, 0xe0, 0xd0}, + {"violet", 0xee, 0x82, 0xee}, + {"wheat", 0xf5, 0xde, 0xb3}, + {"white", 0xff, 0xff, 0xff}, + {"whitesmoke", 0xf5, 0xf5, 0xf5}, + {"yellow", 0xff, 0xff, 0x00}, + {"yellowgreen", 0x9a, 0xcd, 0x32}, +}; + +#define NUM_COLORS (sizeof(_al_color_names) / sizeof(ColorName)) + +static double const Xn = 0.95047; +static double const Yn = 1.00000; +static double const Zn = 1.08883; +static double const delta = 6.0 / 29; +static double const delta2 = 6.0 / 29 * 6.0 / 29; +static double const delta3 = 6.0 / 29 * 6.0 / 29 * 6.0 / 29; +static double const tf7 = 1.0 / 4 / 4 / 4 / 4 / 4 / 4 / 4; + +static void assert_sorted_names(void) +{ + /* In debug mode, check once that the array is sorted. */ +#ifdef DEBUGMODE + static bool done = false; + unsigned i; + + if (!done) { + for (i = 1; i < NUM_COLORS; i++) { + ASSERT(strcmp(_al_color_names[i-1].name, _al_color_names[i].name) < 0); + } + done = true; + } +#endif +} + +static int compare(const void *va, const void *vb) +{ + char const *ca = va; + ColorName const *cb = vb; + return strcmp(ca, cb->name); +} + + +/* Function: al_color_name_to_rgb + */ +bool al_color_name_to_rgb(char const *name, float *r, float *g, float *b) +{ + void *result; + assert_sorted_names(); + result = bsearch(name, _al_color_names, NUM_COLORS, sizeof(ColorName), + compare); + if (result) { + ColorName *c = result; + *r = c->r / 255.0; + *g = c->g / 255.0; + *b = c->b / 255.0; + return true; + } + return false; +} + + +/* Function: al_color_rgb_to_name + */ +char const *al_color_rgb_to_name(float r, float g, float b) +{ + int i; + int ir = r * 255; + int ig = g * 255; + int ib = b * 255; + int n = NUM_COLORS; + int min = n, mind = 0; + /* Could optimize this, right now it does linear search. */ + for (i = 0; i < n; i++) { + int dr = _al_color_names[i].r - ir; + int dg = _al_color_names[i].g - ig; + int db = _al_color_names[i].b - ib; + int d = dr * dr + dg * dg + db * db; + if (min == n || d < mind) { + min = i; + mind = d; + } + } + return _al_color_names[min].name; +} + + +/* Function: al_color_name + */ +ALLEGRO_COLOR al_color_name(char const *name) +{ + float r, g, b; + if (al_color_name_to_rgb(name, &r, &g, &b)) + return al_map_rgb_f(r, g, b); + else + return al_map_rgb_f(0, 0, 0); +} + + +/* Function: al_color_hsv_to_rgb + */ +void al_color_hsv_to_rgb(float hue, float saturation, float value, + float *red, float *green, float *blue) +{ + int d; + float e, a, b, c; + + hue = fmodf(hue, 360); + if (hue < 0) + hue += 360; + d = hue / 60; + e = hue / 60 - d; + a = value * (1 - saturation); + b = value * (1 - e * saturation); + c = value * (1 - (1 - e) * saturation); + switch (d) { + default: + case 0: *red = value, *green = c, *blue = a; return; + case 1: *red = b, *green = value, *blue = a; return; + case 2: *red = a, *green = value, *blue = c; return; + case 3: *red = a, *green = b, *blue = value; return; + case 4: *red = c, *green = a, *blue = value; return; + case 5: *red = value, *green = a, *blue = b; return; + } +} + + +/* Function: al_color_rgb_to_hsv + */ +void al_color_rgb_to_hsv(float red, float green, float blue, + float *hue, float *saturation, float *value) +{ + float a, b, c, d; + if (red > green) { + if (red > blue) { + if (green > blue) + a = red, b = green - blue, c = blue, d = 0; + else + a = red, b = green - blue, c = green, d = 0; + } + else { + a = blue, b = red - green, c = green, d = 4; + } + } + else { + if (red > blue) + a = green, b = blue - red, c = blue, d = 2; + else if (green > blue) + a = green, b = blue - red, c = red, d = 2; + else + a = blue, b = red - green, c = red, d = 4; + } + + if (a == c) { + *hue = 0; + } + else { + *hue = 60 * (d + b / (a - c)); + if (*hue < 0) + *hue += 360; + if (*hue > 360) + *hue -= 360; + } + + if (a == 0) + *saturation = 0; + else + *saturation = (a - c) / a; + *value = a; +} + + +/* Function: al_color_hsv + */ +ALLEGRO_COLOR al_color_hsv(float h, float s, float v) +{ + float r, g, b; + + al_color_hsv_to_rgb(h, s, v, &r, &g, &b); + return al_map_rgb_f(r, g, b); +} + + +static float hsl_to_rgb_helper(float x, float a, float b) +{ + if (x < 0) + x += 1; + if (x > 1) + x -= 1; + + if (x * 6 < 1) + return b + (a - b) * 6 * x; + if (x * 6 < 3) + return a; + if (x * 6 < 4) + return b + (a - b) * (4.0 - 6.0 * x); + return b; +} + + +/* Function: al_color_hsl_to_rgb + */ +void al_color_hsl_to_rgb(float hue, float saturation, float lightness, + float *red, float *green, float *blue) +{ + float a, b, h; + + hue = fmodf(hue, 360); + if (hue < 0) + hue += 360; + h = hue / 360; + if (lightness < 0.5) + a = lightness + lightness * saturation; + else + a = lightness + saturation - lightness * saturation; + b = lightness * 2 - a; + *red = hsl_to_rgb_helper(h + 1.0 / 3.0, a, b); + *green = hsl_to_rgb_helper(h, a, b); + *blue = hsl_to_rgb_helper(h - 1.0 / 3.0, a, b); +} + + +/* Function: al_color_rgb_to_hsl + */ +void al_color_rgb_to_hsl(float red, float green, float blue, + float *hue, float *saturation, float *lightness) +{ + float a, b, c, d; + + if (red > green) { + if (red > blue) { + if (green > blue) + a = red, b = green - blue, c = blue, d = 0; + else + a = red, b = green - blue, c = green, d = 0; + } + else { + a = blue, b = red - green, c = green, d = 4; + } + } + else { + if (red > blue) + a = green, b = blue - red, c = blue, d = 2; + else if (green > blue) + a = green, b = blue - red, c = red, d = 2; + else + a = blue, b = red - green, c = red, d = 4; + } + + if (a == c) { + *hue = 0; + } + else { + *hue = 60 * (d + b / (a - c)); + if (*hue < 0) + *hue += 360; + } + + if (a == c) + *saturation = 0; + else if (a + c < 1) + *saturation = (a - c) / (a + c); + else + *saturation = (a - c) / (2 - a - c); + + *lightness = (a + c) / 2; +} + + +/* Function: al_color_hsl + */ +ALLEGRO_COLOR al_color_hsl(float h, float s, float l) +{ + float r, g, b; + al_color_hsl_to_rgb(h, s, l, &r, &g, &b); + return al_map_rgb_f(r, g, b); +} + + +/* Function: al_color_cmyk_to_rgb + */ +void al_color_cmyk_to_rgb(float cyan, float magenta, float yellow, + float key, float *red, float *green, float *blue) +{ + float max = 1 - key; + *red = max - cyan * max; + *green = max - magenta * max; + *blue = max - yellow * max; +} + + +/* Function: al_color_rgb_to_cmyk + */ +void al_color_rgb_to_cmyk(float red, float green, float blue, + float *cyan, float *magenta, float *yellow, float *key) +{ + float max = red; + if (green > max) + max = green; + if (blue > max) + max = blue; + *key = 1 - max; + if (max > 0) { + *cyan = (max - red) / max; + *magenta = (max - green) / max; + *yellow = (max - blue) / max; + } + else { + *cyan = *magenta = *yellow = 0; + } +} + + +/* Function: al_color_cmyk + */ +ALLEGRO_COLOR al_color_cmyk(float c, float m, float y, float k) +{ + float r, g, b; + al_color_cmyk_to_rgb(c, m, y, k, &r, &g, &b); + return al_map_rgb_f(r, g, b); +} + + +/* Function: al_color_yuv_to_rgb + */ +void al_color_yuv_to_rgb(float y, float u, float v, + float *red, float *green, float *blue) +{ + /* Translate range 0..1 to actual range. */ + u = 0.436 * (u * 2 - 1); + v = 0.615 * (v * 2 - 1); + *red = _ALLEGRO_CLAMP(0, 1, y + v * 1.13983); + *green = _ALLEGRO_CLAMP(0, 1, y + u * -0.39465 + v * -0.58060); + *blue = _ALLEGRO_CLAMP(0, 1, y + u * 2.03211); +} + + +/* Function: al_color_rgb_to_yuv + */ +void al_color_rgb_to_yuv(float red, float green, float blue, + float *y, float *u, float *v) +{ + *y = red * 0.299 + green * 0.587 + blue * 0.114; + *u = red * -0.14713 + green * -0.28886 + blue * 0.436; + *v = red * 0.615 + green * -0.51499 + blue * -0.10001; + /* Normalize chroma components into 0..1 range. */ + *u = (*u / 0.436 + 1) * 0.5; + *v = (*v / 0.615 + 1) * 0.5; +} + + +/* Function: al_color_yuv + */ +ALLEGRO_COLOR al_color_yuv(float y, float u, float v) +{ + float r, g, b; + al_color_yuv_to_rgb(y, u, v, &r, &g, &b); + return al_map_rgb_f(r, g, b); +} + + +/* Function: al_color_rgb_to_html + */ +void al_color_rgb_to_html(float red, float green, float blue, + char *string) +{ + sprintf(string, "#%02x%02x%02x", (int)(red * 255), + (int)(green * 255), (int)(blue * 255)); +} + + +/* Function: al_color_html_to_rgb + */ +bool al_color_html_to_rgb(char const *string, + float *red, float *green, float *blue) +{ + char const *ptr = string; + int ir, ig, ib; + ASSERT(ptr); + ASSERT(red); + ASSERT(green); + ASSERT(blue); + + *red = *green = *blue = 0.0f; + + if (*ptr == '#') + ptr++; + + if (strlen(ptr) != 6) + return false; + + if (sscanf(ptr, "%02x%02x%02x", &ir, &ig, &ib) != 3) + return false; + + *red = ir / 255.0; + *green = ig / 255.0; + *blue = ib / 255.0; + return true; +} + + +/* Function: al_color_html + */ +ALLEGRO_COLOR al_color_html(char const *string) +{ + float r, g, b; + + if (al_color_html_to_rgb(string, &r, &g, &b)) + return al_map_rgb_f(r, g, b); + else + return al_map_rgba(0, 0, 0, 0); +} + + +/* Function: al_get_allegro_color_version + */ +uint32_t al_get_allegro_color_version(void) +{ + return ALLEGRO_VERSION_INT; +} + + +/* Converts from an sRGB color component to the linear value. + */ +static double srgba_gamma_to_linear(double x) { + double const a = 0.055; + if (x < 0.04045) return x / 12.92; + return pow((x + a) / (1 + a), 2.4); +} + + +/* Converts a linear color component back into sRGB. + */ +static double srgba_linear_to_gamma(double x) { + double const a = 0.055; + if (x < 0.0031308) return x * 12.92; + return pow(x, 1 / 2.4) * (1 + a) - a; +} + + +/* Function: al_color_xyz_to_rgb + */ +void al_color_xyz_to_rgb(float x, float y, float z, + float *red, float *green, float *blue) +{ + double r = 3.2406 * x + (-1.5372 * y) + (-0.4986 * z); + double g = -0.9689 * x + 1.8758 * y + 0.0415 * z; + double b = 0.0557 * x + (-0.2040 * y) + 1.0570 * z; + *red = srgba_linear_to_gamma(r); + *green = srgba_linear_to_gamma(g); + *blue = srgba_linear_to_gamma(b); +} + + +/* Function: al_color_rgb_to_xyz + */ +void al_color_rgb_to_xyz(float red, float green, float blue, + float *x, float *y, float *z) +{ + double r = srgba_gamma_to_linear(red); + double g = srgba_gamma_to_linear(green); + double b = srgba_gamma_to_linear(blue); + *x = r * 0.4124 + g * 0.3576 + b * 0.1805; + *y = r * 0.2126 + g * 0.7152 + b * 0.0722; + *z = r * 0.0193 + g * 0.1192 + b * 0.9505; +} + + +/* Function: al_color_xyz + */ +ALLEGRO_COLOR al_color_xyz(float x, float y, float z) +{ + float r, g, b; + al_color_xyz_to_rgb(x, y, z, &r, &g, &b); + return al_map_rgb_f(r, g, b); +} + + +static double cielab_f(double x) { + if (x > delta3) return pow(x, 1.0 / 3); + return 4.0 / 29 + x / delta2 / 3; +} + + +static double cielab_f_inv(double x) { + if (x > delta) return pow(x, 3); + return (x - 4.0 / 29) * 3 * delta2; +} + + +/* Function: al_color_lab_to_rgb + */ +void al_color_lab_to_rgb(float l, float a, float b, + float *red, float *green, float *blue) +{ + float x = Xn * cielab_f_inv((l + 0.16) / 1.16 + a / 5.00); + float y = Yn * cielab_f_inv((l + 0.16) / 1.16); + float z = Zn * cielab_f_inv((l + 0.16) / 1.16 - b / 2.00); + al_color_xyz_to_rgb(x, y, z, red, green, blue); +} + + +/* Function: al_color_rgb_to_lab + */ +void al_color_rgb_to_lab(float red, float green, float blue, + float *l, float *a, float *b) +{ + float x, y, z; + al_color_rgb_to_xyz(red, green, blue, &x, &y, &z); + x /= Xn; + y /= Yn; + z /= Zn; + *l = 1.16 * cielab_f(y) - 0.16; + *a = 5.00 * (cielab_f(x) - cielab_f(y)); + *b = 2.00 * (cielab_f(y) - cielab_f(z)); +} + + +/* Function: al_color_lab + */ +ALLEGRO_COLOR al_color_lab(float l, float a, float b) +{ + float r2, g2, b2; + al_color_lab_to_rgb(l, a, b, &r2, &g2, &b2); + return al_map_rgb_f(r2, g2, b2); +} + + +/* Function: al_color_lch_to_rgb + */ +void al_color_lch_to_rgb(float l, float c, float h, + float *red, float *green, float *blue) +{ + double a = c * cos(h); + double b = c * sin(h); + al_color_lab_to_rgb(l, a, b, red, green, blue); +} + + +/* Function: al_color_rgb_to_lch + */ +void al_color_rgb_to_lch(float red, float green, float blue, + float *l, float *c, float *h) +{ + float a, b; + al_color_rgb_to_lab(red, green, blue, l, &a, &b); + *c = sqrt(a * a + b * b); + *h = fmod(ALLEGRO_PI * 2 + atan2(b, a), ALLEGRO_PI * 2); +} + + +/* Function: al_color_lch + */ +ALLEGRO_COLOR al_color_lch(float l, float c, float h) +{ + float r, g, b; + al_color_lch_to_rgb(l, c, h, &r, &g, &b); + return al_map_rgb_f(r, g, b); +} + + +/* Function: al_color_xyy_to_rgb + */ +void al_color_xyy_to_rgb(float x, float y, float y2, + float *red, float *green, float *blue) +{ + double x2 = x * y / y2; + double z2 = (1 - y2 - x) * y / y2; + al_color_xyz_to_rgb(x2, y2, z2, red, green, blue); +} + + +/* Function: al_color_rgb_to_xyy + */ +void al_color_rgb_to_xyy(float red, float green, float blue, + float *x, float *y, float *y2) +{ + float x2, z2; + al_color_rgb_to_xyz(red, green, blue, &x2, y2, &z2); + *x = x2 / (x2 + *y2 + z2); + *y = *y2 / (x2 + *y2 + z2); +} + + +/* Function: al_color_xyy + */ +ALLEGRO_COLOR al_color_xyy(float x, float y, float y2) +{ + float r, g, b; + al_color_xyy_to_rgb(x, y, y2, &r, &g, &b); + return al_map_rgb_f(r, g, b); +} + + +/* Function: al_color_distance_ciede2000 + */ +double al_color_distance_ciede2000(ALLEGRO_COLOR color1, + ALLEGRO_COLOR color2) { + /* For implementation details refer to e.g. + * http://www.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf + */ + float l1, a1, b1, l2, a2, b2; + al_color_rgb_to_lab(color1.r, color1.g, color1.b, &l1, &a1, &b1); + al_color_rgb_to_lab(color2.r, color2.g, color2.b, &l2, &a2, &b2); + double pi = ALLEGRO_PI; + double dl = l1 - l2; + double ml = (l1 + l2) / 2; + double c1 = sqrt(a1 * a1 + b1 * b1); + double c2 = sqrt(a2 * a2 + b2 * b2); + double mc = (c1 + c2) / 2; + double fac = sqrt(pow(mc, 7) / (pow(mc, 7) + tf7)); + double g = 0.5 * (1 - fac); + a1 *= 1 + g; + a2 *= 1 + g; + c1 = sqrt(a1 * a1 + b1 * b1); + c2 = sqrt(a2 * a2 + b2 * b2); + double dc = c2 - c1; + mc = (c1 + c2) / 2; + fac = sqrt(pow(mc, 7) / (pow(mc, 7) + tf7)); + double h1 = fmod(2 * pi + atan2(b1, a1), 2 * pi); + double h2 = fmod(2 * pi + atan2(b2, a2), 2 * pi); + double dh = 0; + double mh = h1 + h2; + if (c1 * c2 != 0) { + dh = h2 - h1; + if (dh > pi) dh -= 2 * pi; + if (dh < -pi) dh += 2 * pi; + if (fabs(h1 - h2) <= pi) mh = (h1 + h2) / 2; + else if (h1 + h2 < 2 * pi) mh = (h1 + h2 + 2 * pi) / 2; + else mh = (h1 + h2 - 2 * pi) / 2; + } + dh = 2 * sqrt(c1 * c2) * sin(dh / 2); + double t = 1 - 0.17 * cos(mh - pi / 6) + 0.24 * cos(2 * mh) + + 0.32 * cos(3 * mh + pi / 30) - 0.2 * cos(4 * mh - pi * 7 / 20); + double mls = pow(ml - 0.5, 2); + double sl = 1 + 1.5 * mls / sqrt(0.002 + mls); + double sc = 1 + 4.5 * mc; + double sh = 1 + 1.5 * mc * t; + double rt = -2 * fac * sin(pi / 3 * + exp(-pow(mh / pi * 36 / 5 - 11, 2))); + return sqrt(pow(dl / sl, 2) + pow(dc / sc, 2) + + pow(dh / sh, 2) + rt * dc / sc * dh / sh); +} + +/* Function al_color_is_valid + */ +bool al_is_color_valid(ALLEGRO_COLOR color) +{ + return color.r >= 0 && color.g >= 0 && color.b >= 0 && + color.r <= 1 && color.g <= 1 && color.b <= 1; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/font/CMakeLists.txt b/allegro/addons/font/CMakeLists.txt new file mode 100644 index 00000000..b924bd7f --- /dev/null +++ b/allegro/addons/font/CMakeLists.txt @@ -0,0 +1,19 @@ +set(FONT_SOURCES font.c fontbmp.c stdfont.c text.c bmfont.c xml.c) + +set(FONT_INCLUDE_FILES allegro5/allegro_font.h) + +set_our_header_properties(${FONT_INCLUDE_FILES}) + +add_our_addon_library(allegro_font + AllegroFont-${ALLEGRO_SOVERSION} + "${FONT_SOURCES};${FONT_INCLUDE_FILES}" + "-DALLEGRO_FONT_SRC" + "${ALLEGRO_LINK_WITH}" + ) + +install_our_headers(${FONT_INCLUDE_FILES}) + +add_addon(font) + +#-----------------------------------------------------------------------------# +# vim: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/font/allegro5/allegro_font.h b/allegro/addons/font/allegro5/allegro_font.h new file mode 100644 index 00000000..358c1efa --- /dev/null +++ b/allegro/addons/font/allegro5/allegro_font.h @@ -0,0 +1,146 @@ +#ifndef __al_included_allegro5_allegro_font_h +#define __al_included_allegro5_allegro_font_h + +#include "allegro5/allegro.h" + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_FONT_SRC + #define _ALLEGRO_FONT_DLL __declspec(dllexport) + #else + #define _ALLEGRO_FONT_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_FONT_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_FONT_FUNC(type, name, args) _ALLEGRO_FONT_DLL type __cdecl name args + #define ALLEGRO_FONT_METHOD(type, name, args) type (__cdecl *name) args + #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (__cdecl *name) args + #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_FONT_FUNC(type, name, args) extern type name args + #define ALLEGRO_FONT_METHOD(type, name, args) type (*name) args + #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (*name) args + #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) __attribute__ ((format (printf, a, b))) +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_FONT_FUNC(type, name, args) extern _ALLEGRO_FONT_DLL type name args + #define ALLEGRO_FONT_METHOD(type, name, args) type (*name) args + #define ALLEGRO_FONT_FUNCPTR(type, name, args) extern _ALLEGRO_FONT_DLL type (*name) args + #define ALLEGRO_FONT_PRINTFUNC(type, name, args, a, b) ALLEGRO_FONT_FUNC(type, name, args) +#else + #define ALLEGRO_FONT_FUNC AL_FUNC + #define ALLEGRO_FONT_METHOD AL_METHOD + #define ALLEGRO_FONT_FUNCPTR AL_FUNCPTR + #define ALLEGRO_FONT_PRINTFUNC AL_PRINTFUNC +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_FONT +*/ +typedef struct ALLEGRO_FONT ALLEGRO_FONT; +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_FONT_SRC) + +/* Type: ALLEGRO_GLYPH +*/ +typedef struct ALLEGRO_GLYPH ALLEGRO_GLYPH; + +struct ALLEGRO_GLYPH +{ + ALLEGRO_BITMAP *bitmap; + int x; + int y; + int w; + int h; + int kerning; + int offset_x; + int offset_y; + int advance; +}; +#endif + +enum { + ALLEGRO_NO_KERNING = -1, + ALLEGRO_ALIGN_LEFT = 0, + ALLEGRO_ALIGN_CENTRE = 1, + ALLEGRO_ALIGN_CENTER = 1, + ALLEGRO_ALIGN_RIGHT = 2, + ALLEGRO_ALIGN_INTEGER = 4, +}; + +ALLEGRO_FONT_FUNC(bool, al_register_font_loader, (const char *ext, ALLEGRO_FONT *(*load)(const char *filename, int size, int flags))); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_load_bitmap_font, (const char *filename)); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_load_bitmap_font_flags, (const char *filename, int flags)); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_load_font, (const char *filename, int size, int flags)); + +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_grab_font_from_bitmap, (ALLEGRO_BITMAP *bmp, int n, const int ranges[])); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_create_builtin_font, (void)); + +ALLEGRO_FONT_FUNC(void, al_draw_ustr, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, ALLEGRO_USTR const *ustr)); +ALLEGRO_FONT_FUNC(void, al_draw_text, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *text)); +ALLEGRO_FONT_FUNC(void, al_draw_justified_text, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, char const *text)); +ALLEGRO_FONT_FUNC(void, al_draw_justified_ustr, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, ALLEGRO_USTR const *text)); +ALLEGRO_FONT_PRINTFUNC(void, al_draw_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *format, ...), 6, 7); +ALLEGRO_FONT_PRINTFUNC(void, al_draw_justified_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, char const *format, ...), 8, 9); +ALLEGRO_FONT_FUNC(int, al_get_text_width, (const ALLEGRO_FONT *f, const char *str)); +ALLEGRO_FONT_FUNC(int, al_get_ustr_width, (const ALLEGRO_FONT *f, const ALLEGRO_USTR *ustr)); +ALLEGRO_FONT_FUNC(int, al_get_font_line_height, (const ALLEGRO_FONT *f)); +ALLEGRO_FONT_FUNC(int, al_get_font_ascent, (const ALLEGRO_FONT *f)); +ALLEGRO_FONT_FUNC(int, al_get_font_descent, (const ALLEGRO_FONT *f)); +ALLEGRO_FONT_FUNC(void, al_destroy_font, (ALLEGRO_FONT *f)); +ALLEGRO_FONT_FUNC(void, al_get_ustr_dimensions, (const ALLEGRO_FONT *f, + ALLEGRO_USTR const *text, + int *bbx, int *bby, int *bbw, int *bbh)); +ALLEGRO_FONT_FUNC(void, al_get_text_dimensions, (const ALLEGRO_FONT *f, + char const *text, + int *bbx, int *bby, int *bbw, int *bbh)); +ALLEGRO_FONT_FUNC(bool, al_init_font_addon, (void)); +ALLEGRO_FONT_FUNC(bool, al_is_font_addon_initialized, (void)); +ALLEGRO_FONT_FUNC(void, al_shutdown_font_addon, (void)); +ALLEGRO_FONT_FUNC(uint32_t, al_get_allegro_font_version, (void)); +ALLEGRO_FONT_FUNC(int, al_get_font_ranges, (ALLEGRO_FONT *font, + int ranges_count, int *ranges)); + +ALLEGRO_FONT_FUNC(void, al_draw_glyph, (const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, int codepoint)); +ALLEGRO_FONT_FUNC(int, al_get_glyph_width, (const ALLEGRO_FONT *f, + int codepoint)); +ALLEGRO_FONT_FUNC(bool, al_get_glyph_dimensions, (const ALLEGRO_FONT *f, + int codepoint, int *bbx, int *bby, int *bbw, int *bbh)); +ALLEGRO_FONT_FUNC(int, al_get_glyph_advance, (const ALLEGRO_FONT *f, + int codepoint1, int codepoint2)); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_FONT_SRC) +ALLEGRO_FONT_FUNC(bool, al_get_glyph, (const ALLEGRO_FONT *f, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *glyph)); +#endif + +ALLEGRO_FONT_FUNC(void, al_draw_multiline_text, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, int flags, const char *text)); +ALLEGRO_FONT_FUNC(void, al_draw_multiline_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, int flags, const char *format, ...)); +ALLEGRO_FONT_FUNC(void, al_draw_multiline_ustr, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, int flags, const ALLEGRO_USTR *text)); + +ALLEGRO_FONT_FUNC(void, al_do_multiline_text, (const ALLEGRO_FONT *font, + float max_width, const char *text, + bool (*cb)(int line_num, const char *line, int size, void *extra), + void *extra)); + +ALLEGRO_FONT_FUNC(void, al_do_multiline_ustr, (const ALLEGRO_FONT *font, + float max_width, const ALLEGRO_USTR *ustr, + bool (*cb)(int line_num, const ALLEGRO_USTR *line, void *extra), + void *extra)); + +ALLEGRO_FONT_FUNC(void, al_set_fallback_font, (ALLEGRO_FONT *font, + ALLEGRO_FONT *fallback)); +ALLEGRO_FONT_FUNC(ALLEGRO_FONT *, al_get_fallback_font, ( + ALLEGRO_FONT *font)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/addons/font/allegro5/internal/aintern_font.h b/allegro/addons/font/allegro5/internal/aintern_font.h new file mode 100644 index 00000000..13364507 --- /dev/null +++ b/allegro/addons/font/allegro5/internal/aintern_font.h @@ -0,0 +1,41 @@ +#ifndef __al_included_allegro_aintern_font_h +#define __al_included_allegro_aintern_font_h + +#include "allegro5/internal/aintern_list.h" + +typedef struct ALLEGRO_FONT_VTABLE ALLEGRO_FONT_VTABLE; + +struct ALLEGRO_FONT +{ + void *data; + int height; + ALLEGRO_FONT *fallback; + ALLEGRO_FONT_VTABLE *vtable; + _AL_LIST_ITEM *dtor_item; +}; + +/* text- and font-related stuff */ +struct ALLEGRO_FONT_VTABLE +{ + ALLEGRO_FONT_METHOD(int, font_height, (const ALLEGRO_FONT *f)); + ALLEGRO_FONT_METHOD(int, font_ascent, (const ALLEGRO_FONT *f)); + ALLEGRO_FONT_METHOD(int, font_descent, (const ALLEGRO_FONT *f)); + ALLEGRO_FONT_METHOD(int, char_length, (const ALLEGRO_FONT *f, int ch)); + ALLEGRO_FONT_METHOD(int, text_length, (const ALLEGRO_FONT *f, const ALLEGRO_USTR *text)); + ALLEGRO_FONT_METHOD(int, render_char, (const ALLEGRO_FONT *f, ALLEGRO_COLOR color, int ch, float x, float y)); + ALLEGRO_FONT_METHOD(int, render, (const ALLEGRO_FONT *f, ALLEGRO_COLOR color, const ALLEGRO_USTR *text, float x, float y)); + ALLEGRO_FONT_METHOD(void, destroy, (ALLEGRO_FONT *f)); + ALLEGRO_FONT_METHOD(void, get_text_dimensions, (const ALLEGRO_FONT *f, + const ALLEGRO_USTR *text, int *bbx, int *bby, int *bbw, int *bbh)); + ALLEGRO_FONT_METHOD(int, get_font_ranges, (ALLEGRO_FONT *font, + int ranges_count, int *ranges)); + + ALLEGRO_FONT_METHOD(bool, get_glyph_dimensions, (const ALLEGRO_FONT *f, + int codepoint, int *bbx, int *bby, int *bbw, int *bbh)); + ALLEGRO_FONT_METHOD(int, get_glyph_advance, (const ALLEGRO_FONT *font, + int codepoint1, int codepoint2)); + + ALLEGRO_FONT_METHOD(bool, get_glyph, (const ALLEGRO_FONT *f, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *glyph)); +}; + +#endif diff --git a/allegro/addons/font/bmfont.c b/allegro/addons/font/bmfont.c new file mode 100644 index 00000000..e0f7f959 --- /dev/null +++ b/allegro/addons/font/bmfont.c @@ -0,0 +1,519 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include <stdio.h> + +#include "allegro5/internal/aintern_font.h" + +#include "font.h" +#include "xml.h" + +ALLEGRO_DEBUG_CHANNEL("font") + +typedef struct { + int first; + int second; + int amount; +} BMFONT_KERNING; + +typedef struct { + int page; + int x, y; + int width, height; + int xoffset, yoffset; + int xadvance; + int chnl; + int kerning_pairs; + BMFONT_KERNING *kerning; +} BMFONT_CHAR; + +typedef struct BMFONT_RANGE BMFONT_RANGE; + +struct BMFONT_RANGE { + int first; + int count; + BMFONT_CHAR **characters; + BMFONT_RANGE *next; +}; + +typedef struct { + int pages_count; + ALLEGRO_BITMAP **pages; + BMFONT_RANGE *range_first; + int base; + int line_height; + int flags; + + int kerning_pairs; + BMFONT_KERNING *kerning; +} BMFONT_DATA; + +typedef struct { + ALLEGRO_FONT *font; + ALLEGRO_USTR *tag; + ALLEGRO_USTR *attribute; + BMFONT_CHAR *c; + ALLEGRO_PATH *path; +} BMFONT_PARSER; + +static void reallocate(BMFONT_RANGE *range) { + range->characters = al_realloc(range->characters, + range->count * sizeof *range->characters); +} + +static void prepend_char(BMFONT_PARSER *parser, BMFONT_RANGE *range) { + range->first--; + range->count++; + reallocate(range); + memmove(range->characters + 1, range->characters, + (range->count - 1) * sizeof *range->characters); + range->characters[0] = parser->c; +} + +static void append_char(BMFONT_PARSER *parser, BMFONT_RANGE *range) { + range->count++; + reallocate(range); + range->characters[range->count - 1] = parser->c; +} + +static void combine_ranges(BMFONT_DATA *data, + BMFONT_RANGE *range, BMFONT_RANGE *range2) { + (void)data; + range->count += range2->count; + reallocate(range); + memmove(range->characters + range->count - range2->count, + range2->characters, + range2->count * sizeof *range->characters); + range->next = range2->next; + al_free(range2->characters); + al_free(range2); +} + +static void insert_new_range(BMFONT_PARSER *parser, BMFONT_RANGE *prev, + int codepoint) { + BMFONT_RANGE *range = al_calloc(1, sizeof *range); + range->first = codepoint; + range->count = 1; + reallocate(range); + range->characters[0] = parser->c; + if (prev) { + range->next = prev->next; + prev->next = range; + } + else { + ALLEGRO_FONT *font = parser->font; + BMFONT_DATA *data = font->data; + range->next = data->range_first; + data->range_first = range; + } +} + +/* Adding a new codepoint creates either a new range consisting of that + * single codepoint, appends the codepoint to the end of a range, + * prepends it to the beginning of a range, or merges two ranges. + */ +static void add_codepoint(BMFONT_PARSER *parser, int codepoint) { + ALLEGRO_FONT *font = parser->font; + BMFONT_DATA *data = font->data; + BMFONT_RANGE *prev = NULL; + BMFONT_RANGE *range = data->range_first; + while (range) { + if (codepoint == range->first - 1) { + prepend_char(parser, range); + return; + } + if (codepoint < range->first) { + insert_new_range(parser, prev, codepoint); + return; + } + if (codepoint == range->first + range->count) { + append_char(parser, range); + BMFONT_RANGE *range2 = range->next; + if (range2 != NULL && codepoint == range2->first - 1) { + combine_ranges(data, range, range2); + } + return; + } + prev = range; + range = range->next; + } + insert_new_range(parser, prev, codepoint); +} + +static BMFONT_CHAR *find_codepoint(BMFONT_DATA *data, int codepoint) { + BMFONT_RANGE *range = data->range_first; + while (range) { + if (codepoint >= range->first && + codepoint < range->first + range->count) { + return range->characters[codepoint - range->first]; + } + range = range->next; + } + return NULL; +} + +static void add_page(BMFONT_PARSER *parser, char const *filename) { + ALLEGRO_FONT *font = parser->font; + BMFONT_DATA *data = font->data; + data->pages_count++; + data->pages = al_realloc(data->pages, data->pages_count * + sizeof *data->pages); + al_set_path_filename(parser->path, filename); + ALLEGRO_BITMAP *page = al_load_bitmap_flags( + al_path_cstr(parser->path, '/'), data->flags); + data->pages[data->pages_count - 1] = page; +} + +static bool tag_is(BMFONT_PARSER *parser, char const *str) { + return strcmp(al_cstr(parser->tag), str) == 0; +} + +static bool attribute_is(BMFONT_PARSER *parser, char const *str) { + return strcmp(al_cstr(parser->attribute), str) == 0; +} + +static int get_int(char const *value) { + return strtol(value, NULL, 10); +} + +static int xml_callback(XmlState state, char const *value, void *u) +{ + BMFONT_PARSER *parser = u; + ALLEGRO_FONT *font = parser->font; + BMFONT_DATA *data = font->data; + if (state == ElementName) { + al_ustr_assign_cstr(parser->tag, value); + if (tag_is(parser, "char")) { + parser->c = al_calloc(1, sizeof *parser->c); + } + else if (tag_is(parser, "kerning")) { + data->kerning_pairs++; + data->kerning = al_realloc(data->kerning, data->kerning_pairs * + sizeof *data->kerning); + } + } + if (state == AttributeName) { + al_ustr_assign_cstr(parser->attribute, value); + } + if (state == AttributeValue) { + if (tag_is(parser, "char")) { + if (attribute_is(parser, "x")) parser->c->x = get_int(value); + else if (attribute_is(parser, "y")) parser->c->y = get_int(value); + else if (attribute_is(parser, "xoffset")) parser->c->xoffset = get_int(value); + else if (attribute_is(parser, "yoffset")) parser->c->yoffset = get_int(value); + else if (attribute_is(parser, "width")) parser->c->width = get_int(value); + else if (attribute_is(parser, "height")) parser->c->height = get_int(value); + else if (attribute_is(parser, "page")) parser->c->page = get_int(value); + else if (attribute_is(parser, "xadvance")) parser->c->xadvance = get_int(value); + else if (attribute_is(parser, "chnl")) parser->c->chnl = get_int(value); + else if (attribute_is(parser, "id")) { + add_codepoint(parser, get_int(value)); + } + } + else if (tag_is(parser, "page")) { + if (attribute_is(parser, "file")) { + add_page(parser, value); + } + } + else if (tag_is(parser, "common")) { + if (attribute_is(parser, "lineHeight")) data->line_height = get_int(value); + else if (attribute_is(parser, "base")) data->base = get_int(value); + } + else if (tag_is(parser, "kerning")) { + BMFONT_KERNING *k = data->kerning + data->kerning_pairs - 1; + if (attribute_is(parser, "first")) k->first = get_int(value); + else if (attribute_is(parser, "second")) k->second = get_int(value); + else if (attribute_is(parser, "amount")) k->amount = get_int(value); + } + } + return 0; +} + +static int font_height(const ALLEGRO_FONT *f) { + BMFONT_DATA *data = f->data; + return data->line_height; +} + +static int font_ascent(const ALLEGRO_FONT *f) { + BMFONT_DATA *data = f->data; + return data->base; +} + +static int font_descent(const ALLEGRO_FONT *f) { + BMFONT_DATA *data = f->data; + return data->line_height - data->base; +} + +static int get_kerning(BMFONT_CHAR *prev, int c) { + if (!prev) return 0; + int i; + for (i = 0; i < prev->kerning_pairs; i++) { + if (prev->kerning[i].second == c) { + int a = prev->kerning[i].amount; + return a; + } + } + return 0; +} + +static int each_character(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, + const ALLEGRO_USTR *text, float x, float y, ALLEGRO_GLYPH *glyph, + int (*cb)(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, int ch, + float x, float y, ALLEGRO_GLYPH *glyph)) { + BMFONT_DATA *data = f->data; + int pos = 0; + int advance = 0; + int prev = 0; + while (true) { + int c = al_ustr_get_next(text, &pos); + if (c < 0) break; + if (prev) { + BMFONT_CHAR *pc = find_codepoint(data, prev); + advance += get_kerning(pc, c); + } + advance += cb(f, color, c, x + advance, y, glyph); + prev = c; + } + return advance; +} + +static int measure_char(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, + int ch, float x, float y, ALLEGRO_GLYPH *glyph) { + (void)color; + (void)y; + BMFONT_DATA *data = f->data; + BMFONT_CHAR *c = find_codepoint(data, ch); + int advance = 0; + int xo = 0, yo = 0, w = 0, h = 0; + if (c) { + advance = c->xadvance; + xo = c->xoffset; + yo = c->yoffset; + w = c->width; + h = c->height; + } + else { + if (!f->fallback) return 0; + advance = al_get_glyph_width(f->fallback, ch); + al_get_glyph_dimensions(f->fallback, ch, &xo, &yo, &w, &h); + } + if (glyph) { + if (glyph->x == INT_MAX) glyph->x = xo; + if (yo < glyph->y) glyph->y = yo; + if (yo + h > glyph->h) glyph->h = yo + h; + if (x + xo + w > glyph->w) glyph->w = x + xo + w; + } + return advance; +} + +static bool get_glyph_dimensions(const ALLEGRO_FONT *f, + int codepoint, int *bbx, int *bby, int *bbw, int *bbh) { + BMFONT_DATA *data = f->data; + BMFONT_CHAR *c = find_codepoint(data, codepoint); + if (!c) { + if (!f->fallback) return false; + return al_get_glyph_dimensions(f->fallback, codepoint, + bbx, bby, bbw, bbh); + } + *bbx = c->xoffset; + *bby = c->yoffset; + *bbw = c->width; + *bbh = c->height; + return true; +} + +static int get_glyph_advance(const ALLEGRO_FONT *f, + int codepoint1, int codepoint2) { + BMFONT_DATA *data = f->data; + BMFONT_CHAR *c = find_codepoint(data, codepoint1); + int kerning = 0; + if (codepoint1 == ALLEGRO_NO_KERNING) { + return 0; + } + + if (!c) { + if (!f->fallback) return 0; + return al_get_glyph_advance(f->fallback, codepoint1, codepoint2); + } + + if (codepoint2 != ALLEGRO_NO_KERNING) + kerning = get_kerning(c, codepoint2); + + return c->xadvance + kerning; +} + +static bool get_glyph(const ALLEGRO_FONT *f, int prev_codepoint, + int codepoint, ALLEGRO_GLYPH *glyph) { + BMFONT_DATA *data = f->data; + BMFONT_CHAR *prev = find_codepoint(data, prev_codepoint); + BMFONT_CHAR *c = find_codepoint(data, codepoint); + if (c) { + glyph->bitmap = data->pages[c->page]; + glyph->x = c->x; + glyph->y = c->y; + glyph->w = c->width; + glyph->h = c->height; + glyph->kerning = get_kerning(prev, codepoint); + glyph->offset_x = c->xoffset; + glyph->offset_y = c->yoffset; + glyph->advance = c->xadvance + glyph->kerning; + return true; + } + if (f->fallback) { + return al_get_glyph(f->fallback, prev_codepoint, codepoint, + glyph); + } + return false; +} + +static int char_length(const ALLEGRO_FONT *f, int ch) { + ALLEGRO_COLOR color = {0, 0, 0, 0}; + return measure_char(f, color, ch, 0, 0, NULL); +} + +static int text_length(const ALLEGRO_FONT *f, const ALLEGRO_USTR *text) { + ALLEGRO_COLOR color = {0, 0, 0, 0}; + return each_character(f, color, text, 0, 0, NULL, measure_char); +} + +static int render_char(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, int ch, float x, float y) { + BMFONT_DATA *data = f->data; + BMFONT_CHAR *c = find_codepoint(data, ch); + if (!c) { + if (f->fallback) return f->fallback->vtable->render_char( + f->fallback, color, ch, x, y); + return 0; + } + ALLEGRO_BITMAP *page = data->pages[c->page]; + al_draw_tinted_bitmap_region(page, color, c->x, c->y, c->width, c->height, + x + c->xoffset, y + c->yoffset, 0); + return c->xadvance; +} + +static int render_char_cb(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, + int ch, float x, float y, ALLEGRO_GLYPH *glyph) { + (void)glyph; + return render_char(f, color, ch, x, y); +} + +static int render(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, + const ALLEGRO_USTR *text, float x, float y) { + return each_character(f, color, text, x, y, NULL, render_char_cb); +} + +static void destroy_range(BMFONT_RANGE *range) { + int i; + for (i = 0; i < range->count; i++) { + BMFONT_CHAR *c = range->characters[i]; + al_free(c->kerning); + al_free(c); + } + al_free(range); +} + +static void destroy(ALLEGRO_FONT *f) { + BMFONT_DATA *data = f->data; + BMFONT_RANGE *range = data->range_first; + while (range) { + BMFONT_RANGE *next = range->next; + destroy_range(range); + range = next; + } + + int i; + for (i = 0; i < data->pages_count; i++) { + al_destroy_bitmap(data->pages[i]); + } + al_free(data->pages); + + al_free(data->kerning); + al_free(f); +} + +static void get_text_dimensions(const ALLEGRO_FONT *f, + const ALLEGRO_USTR *text, int *bbx, int *bby, int *bbw, int *bbh) { + ALLEGRO_COLOR color = {0, 0, 0, 0}; + ALLEGRO_GLYPH glyph; + glyph.x = INT_MAX; + glyph.y = INT_MAX; + glyph.w = INT_MIN; + glyph.h = INT_MIN; + each_character(f, color, text, 0, 0, &glyph, measure_char); + *bbx = glyph.x; + *bby = glyph.y; + *bbw = glyph.w - glyph.x; + *bbh = glyph.h - glyph.y; +} + +static int get_font_ranges(ALLEGRO_FONT *f, + int ranges_count, int *ranges) { + BMFONT_DATA *data = f->data; + BMFONT_RANGE *range = data->range_first; + int i = 0; + while (range) { + if (i < ranges_count) { + ranges[i * 2 + 0] = range->first; + ranges[i * 2 + 1] = range->first + range->count - 1; + } + range = range->next; + i++; + } + return i; +} + +static ALLEGRO_FONT_VTABLE _al_font_vtable_xml = { + font_height, + font_ascent, + font_descent, + char_length, + text_length, + render_char, + render, + destroy, + get_text_dimensions, + get_font_ranges, + get_glyph_dimensions, + get_glyph_advance, + get_glyph +}; + +ALLEGRO_FONT *_al_load_bmfont_xml(const char *filename, int size, + int font_flags) +{ + (void)size; + ALLEGRO_FILE *f = al_fopen(filename, "r"); + if (!f) { + ALLEGRO_DEBUG("Could not open %s.\n", filename); + return NULL; + } + + BMFONT_DATA *data = al_calloc(1, sizeof *data); + BMFONT_PARSER _parser; + BMFONT_PARSER *parser = &_parser; + parser->tag = al_ustr_new(""); + parser->attribute = al_ustr_new(""); + parser->path = al_create_path(filename); + data->flags = font_flags; + + ALLEGRO_FONT *font = al_calloc(1, sizeof *font); + font->vtable = &_al_font_vtable_xml; + font->data = data; + parser->font = font; + + _al_xml_parse(f, xml_callback, parser); + + int i; + for (i = 0; i < data->kerning_pairs; i++) { + BMFONT_KERNING *k = data->kerning + i; + BMFONT_CHAR *c = find_codepoint(data, k->first); + c->kerning_pairs++; + c->kerning = al_realloc(c->kerning, c->kerning_pairs * + sizeof *c->kerning); + c->kerning[c->kerning_pairs - 1] = *k; + } + + al_ustr_free(parser->tag); + al_ustr_free(parser->attribute); + al_destroy_path(parser->path); + + return font; +} diff --git a/allegro/addons/font/font.c b/allegro/addons/font/font.c new file mode 100644 index 00000000..5dc04d37 --- /dev/null +++ b/allegro/addons/font/font.c @@ -0,0 +1,501 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * + * See readme.txt for copyright information. + */ + +#include <string.h> +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_font.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_vector.h" + +#include "font.h" +#include <ctype.h> + +ALLEGRO_DEBUG_CHANNEL("font") + + +typedef struct +{ + ALLEGRO_USTR *extension; + ALLEGRO_FONT *(*load_font)(char const *filename, int size, int flags); +} FONT_HANDLER; + + +/* globals */ +static bool font_inited = false; +static _AL_VECTOR font_handlers = _AL_VECTOR_INITIALIZER(FONT_HANDLER); + + +/* al_font_404_character: + * This is what we render missing glyphs as. + */ +static int al_font_404_character = '^'; + + + +/* font_height: + * (mono and color vtable entry) + * Returns the height, in pixels of the font. + */ +static int font_height(const ALLEGRO_FONT *f) +{ + ASSERT(f); + return f->height; +} + + + +static int font_ascent(const ALLEGRO_FONT *f) +{ + return font_height(f); +} + + + +static int font_descent(const ALLEGRO_FONT *f) +{ + (void)f; + return 0; +} + + + +/* length: + * (mono and color vtable entry) + * Returns the length, in pixels, of a string as rendered in a font. + */ +static int length(const ALLEGRO_FONT* f, const ALLEGRO_USTR *text) +{ + int ch = 0, w = 0; + int pos = 0; + ASSERT(f); + + while ((ch = al_ustr_get_next(text, &pos)) >= 0) { + w += f->vtable->char_length(f, ch); + } + + return w; +} + + + +static void color_get_text_dimensions(ALLEGRO_FONT const *f, + const ALLEGRO_USTR *text, + int *bbx, int *bby, int *bbw, int *bbh) +{ + /* Dummy implementation - for A4-style bitmap fonts the bounding + * box of text is its width and line-height. + */ + int h = al_get_font_line_height(f); + if (bbx) *bbx = 0; + if (bby) *bby = 0; + if (bbw) *bbw = length(f, text); + if (bbh) *bbh = h; +} + + + +static ALLEGRO_FONT_COLOR_DATA *_al_font_find_page( + ALLEGRO_FONT_COLOR_DATA *cf, int ch) +{ + while (cf) { + if (ch >= cf->begin && ch < cf->end) + return cf; + cf = cf->next; + } + return NULL; +} + + +/* _color_find_glyph: + * Helper for color vtable entries, below. + */ +static ALLEGRO_BITMAP* _al_font_color_find_glyph(const ALLEGRO_FONT* f, int ch) +{ + ALLEGRO_FONT_COLOR_DATA* cf = (ALLEGRO_FONT_COLOR_DATA*)(f->data); + + cf = _al_font_find_page(cf, ch); + if (cf) { + return cf->bitmaps[ch - cf->begin]; + } + + /* if we don't find the character, then search for the missing + glyph, but don't get stuck in a loop. */ + if (ch != al_font_404_character && !f->fallback) + return _al_font_color_find_glyph(f, al_font_404_character); + return 0; +} + + + +/* color_char_length: + * (color vtable entry) + * Returns the length of a character, in pixels, as it would be rendered + * in this font. + */ +static int color_char_length(const ALLEGRO_FONT* f, int ch) +{ + ALLEGRO_BITMAP* g = _al_font_color_find_glyph(f, ch); + if (g) + return al_get_bitmap_width(g); + if (f->fallback) + return al_get_glyph_width(f->fallback, ch); + return 0; +} + + + +/* color_render_char: + * (color vtable entry) + * Renders a color character onto a bitmap, at the specified location, + * using the specified color. + * Returns the character width, in pixels. + */ +static int color_render_char(const ALLEGRO_FONT* f, + ALLEGRO_COLOR color, int ch, float x, + float y) +{ + int w = 0; + int h = f->vtable->font_height(f); + ALLEGRO_BITMAP *g; + + g = _al_font_color_find_glyph(f, ch); + if (g) { + al_draw_tinted_bitmap(g, color, x, + y + ((float)h - al_get_bitmap_height(g))/2.0f, 0); + + w = al_get_bitmap_width(g); + } + else if (f->fallback) { + al_draw_glyph(f->fallback, color, x, y, ch); + w = al_get_glyph_width(f->fallback, ch); + } + + return w; +} + +/* color_render: + * (color vtable entry) + * Renders a color font onto a bitmap, at the specified location, using + * the specified color. + */ +static int color_render(const ALLEGRO_FONT* f, ALLEGRO_COLOR color, + const ALLEGRO_USTR *text, + float x, float y) +{ + int pos = 0; + int advance = 0; + int32_t ch; + bool held = al_is_bitmap_drawing_held(); + + al_hold_bitmap_drawing(true); + while ((ch = al_ustr_get_next(text, &pos)) >= 0) { + advance += f->vtable->render_char(f, color, ch, x + advance, y); + } + al_hold_bitmap_drawing(held); + return advance; +} + + +static bool color_get_glyph(const ALLEGRO_FONT *f, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *glyph) +{ + ALLEGRO_BITMAP *g = _al_font_color_find_glyph(f, codepoint); + if (g) { + glyph->bitmap = g; + glyph->x = 0; + glyph->y = 0; + glyph->w = al_get_bitmap_width(g); + glyph->h = al_get_bitmap_height(g); + glyph->kerning = 0; + glyph->offset_x = 0; + glyph->offset_y = 0; + glyph->advance = glyph->w; + return true; + } + if (f->fallback) { + return f->fallback->vtable->get_glyph(f->fallback, prev_codepoint, codepoint, glyph); + } + return false; +} + + +/* color_destroy: + * (color vtable entry) + * Destroys a color font. + */ +static void color_destroy(ALLEGRO_FONT* f) +{ + ALLEGRO_FONT_COLOR_DATA* cf; + ALLEGRO_BITMAP *glyphs = NULL; + + if (!f) + return; + + cf = (ALLEGRO_FONT_COLOR_DATA*)(f->data); + + if (cf) + glyphs = cf->glyphs; + + while (cf) { + ALLEGRO_FONT_COLOR_DATA* next = cf->next; + int i = 0; + + for (i = cf->begin; i < cf->end; i++) al_destroy_bitmap(cf->bitmaps[i - cf->begin]); + /* Each range might point to the same bitmap. */ + if (cf->glyphs != glyphs) { + al_destroy_bitmap(cf->glyphs); + cf->glyphs = NULL; + } + + if (!next && cf->glyphs) + al_destroy_bitmap(cf->glyphs); + + al_free(cf->bitmaps); + al_free(cf); + + cf = next; + } + + al_free(f); +} + + +static int color_get_font_ranges(ALLEGRO_FONT *font, int ranges_count, + int *ranges) +{ + ALLEGRO_FONT_COLOR_DATA *cf = font->data; + int i = 0; + while (cf) { + if (i < ranges_count) { + ranges[i * 2 + 0] = cf->begin; + ranges[i * 2 + 1] = cf->end - 1; + } + i++; + cf = cf->next; + } + return i; +} + +static bool color_get_glyph_dimensions(ALLEGRO_FONT const *f, + int codepoint, int *bbx, int *bby, int *bbw, int *bbh) +{ + ALLEGRO_BITMAP *glyph = _al_font_color_find_glyph(f, codepoint); + if(!glyph) { + if (f->fallback) { + return al_get_glyph_dimensions(f->fallback, codepoint, + bbx, bby, bbw, bbh); + } + return false; + } + if (bbx) *bbx = 0; + if (bby) *bby = 0; + if (bbw) *bbw = glyph ? al_get_bitmap_width(glyph) : 0; + if (bbh) *bbh = al_get_font_line_height(f); + return true; +} + +static int color_get_glyph_advance(ALLEGRO_FONT const *f, + int codepoint1, int codepoint2) +{ + (void) codepoint2; + + /* Handle special case to simplify use in a loop. */ + if (codepoint1 == ALLEGRO_NO_KERNING) { + return 0; + } + + /* For other cases, bitmap fonts don't use any kerning, so just use the + * width of codepoint1. */ + + return color_char_length(f, codepoint1); +} + +/******** + * vtable declarations + ********/ + +ALLEGRO_FONT_VTABLE _al_font_vtable_color = { + font_height, + font_ascent, + font_descent, + color_char_length, + length, + color_render_char, + color_render, + color_destroy, + color_get_text_dimensions, + color_get_font_ranges, + color_get_glyph_dimensions, + color_get_glyph_advance, + color_get_glyph +}; + + +static void font_shutdown(void) +{ + if (!font_inited) + return; + + while (!_al_vector_is_empty(&font_handlers)) { + FONT_HANDLER *h = _al_vector_ref_back(&font_handlers); + al_ustr_free(h->extension); + _al_vector_delete_at(&font_handlers, _al_vector_size(&font_handlers)-1); + } + _al_vector_free(&font_handlers); + + font_inited = false; +} + + +/* Function: al_init_font_addon + */ +bool al_init_font_addon(void) +{ + if (font_inited) { + ALLEGRO_WARN("Font addon already initialised.\n"); + return true; + } + + al_register_font_loader(".bmp", _al_load_bitmap_font); + al_register_font_loader(".jpg", _al_load_bitmap_font); + al_register_font_loader(".pcx", _al_load_bitmap_font); + al_register_font_loader(".png", _al_load_bitmap_font); + al_register_font_loader(".tga", _al_load_bitmap_font); + + al_register_font_loader(".xml", _al_load_bmfont_xml); + al_register_font_loader(".fnt", _al_load_bmfont_xml); + + _al_add_exit_func(font_shutdown, "font_shutdown"); + + font_inited = true; + return font_inited; +} + + + +/* Function: al_is_font_addon_initialized + */ +bool al_is_font_addon_initialized(void) +{ + return font_inited; +} + + + +/* Function: al_shutdown_font_addon + */ +void al_shutdown_font_addon(void) +{ + font_shutdown(); +} + + +static FONT_HANDLER *find_extension(char const *extension) +{ + int i; + /* Go backwards so a handler registered later for the same extension + * has precedence. + */ + for (i = _al_vector_size(&font_handlers) - 1; i >= 0 ; i--) { + FONT_HANDLER *handler = _al_vector_ref(&font_handlers, i); + if (0 == _al_stricmp(al_cstr(handler->extension), extension)) + return handler; + } + return NULL; +} + + + +/* Function: al_register_font_loader + */ +bool al_register_font_loader(char const *extension, + ALLEGRO_FONT *(*load_font)(char const *filename, int size, int flags)) +{ + FONT_HANDLER *handler = find_extension(extension); + if (!handler) { + if (!load_font) + return false; /* Nothing to remove. */ + handler = _al_vector_alloc_back(&font_handlers); + handler->extension = al_ustr_new(extension); + } + else { + if (!load_font) { + al_ustr_free(handler->extension); + return _al_vector_find_and_delete(&font_handlers, handler); + } + } + handler->load_font = load_font; + return true; +} + + + +/* Function: al_load_font + */ +ALLEGRO_FONT *al_load_font(char const *filename, int size, int flags) +{ + int i; + const char *ext; + FONT_HANDLER *handler; + + ASSERT(filename); + + if (!font_inited) { + ALLEGRO_ERROR("Font addon not initialised.\n"); + return NULL; + } + + ext = strrchr(filename, '.'); + if (!ext) { + ALLEGRO_ERROR("Unable to determine filetype: '%s'\n", filename); + return NULL; + } + handler = find_extension(ext); + if (handler) + return handler->load_font(filename, size, flags); + + /* No handler for the extension was registered - try to load with + * all registered font_handlers and see if one works. So if the user + * does: + * + * al_init_font_addon() + * al_init_ttf_addon() + * + * This will first try to load an unknown (let's say Type1) font file + * with Freetype (and load it successfully in this case), then try + * to load it as a bitmap font. + */ + for (i = _al_vector_size(&font_handlers) - 1; i >= 0 ; i--) { + FONT_HANDLER *handler = _al_vector_ref(&font_handlers, i); + ALLEGRO_FONT *try = handler->load_font(filename, size, flags); + if (try) + return try; + } + + return NULL; +} + + + +/* Function: al_get_allegro_font_version + */ +uint32_t al_get_allegro_font_version(void) +{ + return ALLEGRO_VERSION_INT; +} + +/* vim: set sts=4 sw=4 et: */ + diff --git a/allegro/addons/font/font.h b/allegro/addons/font/font.h new file mode 100644 index 00000000..662f14b6 --- /dev/null +++ b/allegro/addons/font/font.h @@ -0,0 +1,22 @@ +#ifndef __al_included_allegro5_font_h +#define __al_included_allegro5_font_h + +#include "allegro5/internal/aintern_font.h" + +extern ALLEGRO_FONT_VTABLE _al_font_vtable_color; + +typedef struct ALLEGRO_FONT_COLOR_DATA +{ + int begin, end; /* first char and one-past-the-end char */ + ALLEGRO_BITMAP *glyphs; /* our glyphs */ + ALLEGRO_BITMAP **bitmaps; /* sub bitmaps pointing to our glyphs */ + struct ALLEGRO_FONT_COLOR_DATA *next; /* linked list structure */ +} ALLEGRO_FONT_COLOR_DATA; + +ALLEGRO_FONT *_al_load_bitmap_font(const char *filename, + int size, int flags); +ALLEGRO_FONT *_al_load_bmfont_xml(const char *filename, + int size, int flags); + + +#endif diff --git a/allegro/addons/font/fontbmp.c b/allegro/addons/font/fontbmp.c new file mode 100644 index 00000000..4712d2a2 --- /dev/null +++ b/allegro/addons/font/fontbmp.c @@ -0,0 +1,309 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Read font from a bitmap. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#include <string.h> + +#include "allegro5/allegro.h" + +#include "allegro5/allegro_font.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_system.h" + +#include "font.h" + +ALLEGRO_DEBUG_CHANNEL("font") + + +static void font_find_character(uint32_t *data, int pitch, + int bmp_w, int bmp_h, + int *x, int *y, int *w, int *h) +{ + /* The pixel at position 0/0 is used as background color. */ + uint32_t c = data[0]; + pitch >>= 2; + + /* look for top left corner of character */ + while (1) { + /* Reached border? */ + if (*x >= bmp_w - 1) { + *x = 0; + (*y)++; + if (*y >= bmp_h - 1) { + *w = 0; + *h = 0; + return; + } + } + if ( + data[*x + *y * pitch] == c && + data[(*x + 1) + *y * pitch] == c && + data[*x + (*y + 1) * pitch] == c && + data[(*x + 1) + (*y + 1) * pitch] != c) { + break; + } + (*x)++; + } + + /* look for right edge of character */ + *w = 1; + while ((*x + *w + 1 < bmp_w) && + data[(*x + *w + 1) + (*y + 1) * pitch] != c) { + (*w)++; + } + + /* look for bottom edge of character */ + *h = 1; + while ((*y + *h + 1 < bmp_h) && + data[*x + 1 + (*y + *h + 1) * pitch] != c) { + (*h)++; + } +} + + + +/* import_bitmap_font_color: + * Helper for import_bitmap_font, below. + */ +static int import_bitmap_font_color(uint32_t *data, int pitch, + int bmp_w, int bmp_h, + ALLEGRO_BITMAP **bits, ALLEGRO_BITMAP *glyphs, int num, + int *import_x, int *import_y) +{ + int w, h, i; + + for (i = 0; i < num; i++) { + font_find_character(data, pitch, bmp_w, bmp_h, + import_x, import_y, &w, &h); + if (w <= 0 || h <= 0) { + ALLEGRO_ERROR("Unable to find character %d\n", i); + return -1; + } + else { + bits[i] = al_create_sub_bitmap(glyphs, + *import_x + 1, *import_y + 1, w, h); + *import_x += w; + } + } + return 0; +} + + + + +/* bitmap_font_count: + * Helper for `import_bitmap_font', below. + */ +static int bitmap_font_count(ALLEGRO_BITMAP* bmp) +{ + int x = 0, y = 0, w = 0, h = 0; + int num = 0; + ALLEGRO_LOCKED_REGION *lock; + + lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_RGBA_8888, + ALLEGRO_LOCK_READONLY); + + while (1) { + font_find_character(lock->data, lock->pitch, + al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), + &x, &y, &w, &h); + if (w <= 0 || h <= 0) + break; + num++; + x += w; + } + + al_unlock_bitmap(bmp); + + return num; +} + + + +ALLEGRO_FONT *_al_load_bitmap_font(const char *fname, int size, int font_flags) +{ + ALLEGRO_BITMAP *import_bmp; + ALLEGRO_FONT *f; + ALLEGRO_STATE backup; + int range[2]; + int bmp_flags; + ASSERT(fname); + + (void)size; + + bmp_flags = 0; + if (font_flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA) { + bmp_flags |= ALLEGRO_NO_PREMULTIPLIED_ALPHA; + } + + al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); + import_bmp = al_load_bitmap_flags(fname, bmp_flags); + al_restore_state(&backup); + + if (!import_bmp) { + ALLEGRO_ERROR("Couldn't load bitmap from '%s'\n", fname); + return NULL; + } + + /* We assume a single unicode range, starting at the space + * character. + */ + range[0] = 32; + range[1] = 32 + bitmap_font_count(import_bmp) - 1; + + f = al_grab_font_from_bitmap(import_bmp, 1, range); + + al_destroy_bitmap(import_bmp); + + return f; +} + + + +/* Function: al_load_bitmap_font + */ +ALLEGRO_FONT *al_load_bitmap_font(const char *fname) +{ + int flags = 0; + + /* For backwards compatibility with the 5.0 branch. */ + if (al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA) { + flags |= ALLEGRO_NO_PREMULTIPLIED_ALPHA; + } + + return _al_load_bitmap_font(fname, 0, flags); +} + + + +/* Function: al_load_bitmap_font_flags + */ +ALLEGRO_FONT *al_load_bitmap_font_flags(const char *fname, int flags) +{ + return _al_load_bitmap_font(fname, 0, flags); +} + + + +/* Function: al_grab_font_from_bitmap + */ +ALLEGRO_FONT *al_grab_font_from_bitmap(ALLEGRO_BITMAP *bmp, + int ranges_n, const int ranges[]) +{ + ALLEGRO_FONT *f; + ALLEGRO_FONT_COLOR_DATA *cf, *prev = NULL; + ALLEGRO_STATE backup; + int i; + ALLEGRO_COLOR mask = al_get_pixel(bmp, 0, 0); + ALLEGRO_BITMAP *glyphs = NULL, *unmasked = NULL; + int import_x = 0, import_y = 0; + ALLEGRO_LOCKED_REGION *lock = NULL; + int w, h; + + ASSERT(bmp); + + w = al_get_bitmap_width(bmp); + h = al_get_bitmap_height(bmp); + + f = al_calloc(1, sizeof *f); + f->vtable = &_al_font_vtable_color; + + al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); + unmasked = al_clone_bitmap(bmp); + /* At least with OpenGL, texture pixels at the very border of + * the glyph are sometimes partly sampled from the yellow mask + * pixels. To work around this, we replace the mask with full + * transparency. + * And we best do it on a memory copy to avoid loading back a texture. + */ + al_convert_mask_to_alpha(unmasked, mask); + al_restore_state(&backup); + + al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER); + // Use the users preferred format, so don't set this below! + //al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); + + for (i = 0; i < ranges_n; i++) { + int first = ranges[i * 2]; + int last = ranges[i * 2 + 1]; + int n = 1 + last - first; + cf = al_calloc(1, sizeof(ALLEGRO_FONT_COLOR_DATA)); + + if (prev) + prev->next = cf; + else + f->data = cf; + + cf->bitmaps = al_malloc(sizeof(ALLEGRO_BITMAP*) * n); + cf->bitmaps[0] = NULL; + + if (!glyphs) { + glyphs = al_clone_bitmap(unmasked); + if (!glyphs) { + ALLEGRO_ERROR("Unable clone bitmap.\n"); + goto cleanup_and_fail_on_error; + } + + lock = al_lock_bitmap(bmp, + ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READONLY); + } + cf->glyphs = glyphs; + + if (import_bitmap_font_color(lock->data, lock->pitch, w, h, + cf->bitmaps, cf->glyphs, n, + &import_x, &import_y)) { + goto cleanup_and_fail_on_error; + } + else { + cf->begin = first; + cf->end = last + 1; + prev = cf; + } + } + al_restore_state(&backup); + + cf = f->data; + if (cf && cf->bitmaps[0]) + f->height = al_get_bitmap_height(cf->bitmaps[0]); + + if (lock) + al_unlock_bitmap(bmp); + + if (unmasked) + al_destroy_bitmap(unmasked); + + f->dtor_item = _al_register_destructor(_al_dtor_list, "font", f, + (void (*)(void *))al_destroy_font); + + return f; + +cleanup_and_fail_on_error: + + if (lock) + al_unlock_bitmap(bmp); + al_restore_state(&backup); + al_destroy_font(f); + if (unmasked) + al_destroy_bitmap(unmasked); + return NULL; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/font/stdfont.c b/allegro/addons/font/stdfont.c new file mode 100644 index 00000000..98416d0a --- /dev/null +++ b/allegro/addons/font/stdfont.c @@ -0,0 +1,465 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * A builtin bitmap font using no external data. + * + * By Dennis Busch. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" + + +ALLEGRO_DEBUG_CHANNEL("font") + + +/* Adapted from Allegro4 "font.c" (removed unnecessary height and width + * information and packed them all into a single continuous array). + * Contains the following ranges + * + * ASCII (0x0020 to 0x007F) + * Latin-1 (0x00A1 to 0x00FF) + * Extended-A (0x0100 to 0x017F) + * Euro (0x20AC) + */ +static const unsigned char builtin_rom_font_8x8[] = { + /* standard ASCII characters (0x20 to 0x7F) */ + /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x21 */ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, + /* 0x22 */ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x23 */ 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, + /* 0x24 */ 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, + /* 0x25 */ 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, + /* 0x26 */ 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, + /* 0x27 */ 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x28 */ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, + /* 0x29 */ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + /* 0x2A */ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, + /* 0x2B */ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, + /* 0x2C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, + /* 0x2D */ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, + /* 0x2E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + /* 0x2F */ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, + /* 0x30 */ 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00, + /* 0x31 */ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, + /* 0x32 */ 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, + /* 0x33 */ 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, + /* 0x34 */ 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, + /* 0x35 */ 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, + /* 0x36 */ 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, + /* 0x37 */ 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, + /* 0x38 */ 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0x39 */ 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, + /* 0x3A */ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, + /* 0x3B */ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, + /* 0x3C */ 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, + /* 0x3D */ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, + /* 0x3E */ 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, + /* 0x3F */ 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, + /* 0x40 */ 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, + /* 0x41 */ 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, + /* 0x42 */ 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, + /* 0x43 */ 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, + /* 0x44 */ 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, + /* 0x45 */ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, + /* 0x46 */ 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, + /* 0x47 */ 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00, + /* 0x48 */ 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, + /* 0x49 */ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x4A */ 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, + /* 0x4B */ 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, + /* 0x4C */ 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, + /* 0x4D */ 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, + /* 0x4E */ 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, + /* 0x4F */ 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, + /* 0x50 */ 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, + /* 0x51 */ 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, + /* 0x52 */ 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, + /* 0x53 */ 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00, + /* 0x54 */ 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x55 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, + /* 0x56 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, + /* 0x57 */ 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + /* 0x58 */ 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, + /* 0x59 */ 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, + /* 0x5A */ 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, + /* 0x5B */ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + /* 0x5C */ 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, + /* 0x5D */ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + /* 0x5E */ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, + /* 0x5F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + /* 0x60 */ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x61 */ 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + /* 0x62 */ 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, + /* 0x63 */ 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, + /* 0x64 */ 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, + /* 0x65 */ 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + /* 0x66 */ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00, + /* 0x67 */ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + /* 0x68 */ 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, + /* 0x69 */ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x6A */ 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, + /* 0x6B */ 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, + /* 0x6C */ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x6D */ 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00, + /* 0x6E */ 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + /* 0x6F */ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, + /* 0x70 */ 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, + /* 0x71 */ 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, + /* 0x72 */ 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, + /* 0x73 */ 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, + /* 0x74 */ 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, + /* 0x75 */ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + /* 0x76 */ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, + /* 0x77 */ 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + /* 0x78 */ 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, + /* 0x79 */ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + /* 0x7A */ 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, + /* 0x7B */ 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, + /* 0x7C */ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + /* 0x7D */ 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, + /* 0x7E */ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x7F */ 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, + /* ANSI Latin-1 characters (0xA1 to 0xFF) */ + /* 0xA1 */ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, + /* 0xA2 */ 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, + /* 0xA3 */ 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, + /* 0xA4 */ 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, + /* 0xA5 */ 0xCC, 0xCC, 0x78, 0xFC, 0x30, 0xFC, 0x30, 0x30, + /* 0xA6 */ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + /* 0xA7 */ 0x3E, 0x61, 0x3C, 0x66, 0x66, 0x3C, 0x86, 0x7C, + /* 0xA8 */ 0x00, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0xA9 */ 0x7E, 0x81, 0x9D, 0xA1, 0xA1, 0x9D, 0x81, 0x7E, + /* 0xAA */ 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, + /* 0xAB */ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, + /* 0xAC */ 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, + /* 0xAD */ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, + /* 0xAE */ 0x7E, 0x81, 0xB9, 0xA5, 0xB9, 0xA5, 0x81, 0x7E, + /* 0xAF */ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0xB0 */ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, + /* 0xB1 */ 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0xFC, 0x00, + /* 0xB2 */ 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, + /* 0xB3 */ 0x78, 0x0C, 0x38, 0x0C, 0x78, 0x00, 0x00, 0x00, + /* 0xB4 */ 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0xB5 */ 0x00, 0x00, 0x33, 0x33, 0x66, 0x7E, 0xC0, 0x80, + /* 0xB6 */ 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, + /* 0xB7 */ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + /* 0xB8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0x38, + /* 0xB9 */ 0x18, 0x38, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, + /* 0xBA */ 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, + /* 0xBB */ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, + /* 0xBC */ 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6F, 0xCF, 0x03, + /* 0xBD */ 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F, + /* 0xBE */ 0xE1, 0x32, 0xE4, 0x3A, 0xF6, 0x2A, 0x5F, 0x86, + /* 0xBF */ 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00, + /* 0xC0 */ 0x18, 0x0C, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, + /* 0xC1 */ 0x30, 0x60, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, + /* 0xC2 */ 0x7C, 0x82, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, + /* 0xC3 */ 0x76, 0xDC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, + /* 0xC4 */ 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, + /* 0xC5 */ 0x10, 0x28, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, + /* 0xC6 */ 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, + /* 0xC7 */ 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78, + /* 0xC8 */ 0x30, 0x18, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, + /* 0xC9 */ 0x0C, 0x18, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, + /* 0xCA */ 0x7C, 0x82, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, + /* 0xCB */ 0xC6, 0x00, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, + /* 0xCC */ 0x30, 0x18, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, + /* 0xCD */ 0x0C, 0x18, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, + /* 0xCE */ 0x3C, 0x42, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, + /* 0xCF */ 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, + /* 0xD0 */ 0xF8, 0x6C, 0x66, 0xF6, 0x66, 0x6C, 0xF8, 0x00, + /* 0xD1 */ 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, + /* 0xD2 */ 0x30, 0x18, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xD3 */ 0x18, 0x30, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xD4 */ 0x7C, 0x82, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xD5 */ 0x76, 0xDC, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xD6 */ 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xD7 */ 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, + /* 0xD8 */ 0x3A, 0x6C, 0xCE, 0xD6, 0xE6, 0x6C, 0xB8, 0x00, + /* 0xD9 */ 0x60, 0x30, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xDA */ 0x18, 0x30, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xDB */ 0x7C, 0x82, 0x00, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xDC */ 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0xDD */ 0x0C, 0x18, 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x00, + /* 0xDE */ 0xE0, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0xF0, + /* 0xDF */ 0x78, 0xCC, 0xCC, 0xD8, 0xCC, 0xC6, 0xCC, 0x00, + /* 0xE0 */ 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, + /* 0xE1 */ 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, + /* 0xE2 */ 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00, + /* 0xE3 */ 0x76, 0xDC, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, + /* 0xE4 */ 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, + /* 0xE5 */ 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, + /* 0xE6 */ 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, + /* 0xE7 */ 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38, + /* 0xE8 */ 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + /* 0xE9 */ 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + /* 0xEA */ 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, + /* 0xEB */ 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + /* 0xEC */ 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0xED */ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0xEE */ 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, + /* 0xEF */ 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0xF0 */ 0x08, 0x3C, 0x08, 0x7C, 0xCC, 0xCC, 0x78, 0x00, + /* 0xF1 */ 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00, + /* 0xF2 */ 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0xF3 */ 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0xF4 */ 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0xF5 */ 0x76, 0xDC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0xF6 */ 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0xF7 */ 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00, + /* 0xF8 */ 0x00, 0x02, 0x7C, 0xCE, 0xD6, 0xE6, 0x7C, 0x80, + /* 0xF9 */ 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0xFA */ 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0xFB */ 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0xFC */ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0xFD */ 0x18, 0x30, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + /* 0xFE */ 0xF0, 0x60, 0x7C, 0x66, 0x7C, 0x60, 0xF0, 0x00, + /* 0xFF */ 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + /* Extended-A characters (0x100 to 0x17F) */ + /* 0x100 */ 0xFE, 0x00, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, + /* 0x101 */ 0xFC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, + /* 0x102 */ 0x82, 0x7C, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x00, + /* 0x103 */ 0xC3, 0x7E, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, + /* 0x104 */ 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x1C, 0x30, 0x1E, + /* 0x105 */ 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x30, 0x1C, + /* 0x106 */ 0x0C, 0x18, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00, + /* 0x107 */ 0x1C, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, + /* 0x108 */ 0x7C, 0x82, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00, + /* 0x109 */ 0x7E, 0xC3, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, + /* 0x10A */ 0x10, 0x00, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00, + /* 0x10B */ 0x10, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, + /* 0x10C */ 0x6C, 0x38, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00, + /* 0x10D */ 0x6C, 0x38, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, + /* 0x10E */ 0x6C, 0x38, 0xF8, 0x66, 0x66, 0x66, 0xF8, 0x00, + /* 0x10F */ 0xBC, 0x4C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, + /* 0x110 */ 0xF8, 0x6C, 0x66, 0xF6, 0x66, 0x6C, 0xF8, 0x00, + /* 0x111 */ 0x08, 0x3C, 0x08, 0x7C, 0xCC, 0xCC, 0x78, 0x00, + /* 0x112 */ 0xFE, 0x00, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, + /* 0x113 */ 0xFC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + /* 0x114 */ 0x6C, 0x38, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, + /* 0x115 */ 0x6C, 0x38, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + /* 0x116 */ 0x10, 0x00, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, + /* 0x117 */ 0x10, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + /* 0x118 */ 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x18, 0x30, 0x1C, + /* 0x119 */ 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x38, 0x0C, + /* 0x11A */ 0x6C, 0x38, 0xFE, 0xC0, 0xFC, 0xC0, 0xFE, 0x00, + /* 0x11B */ 0x6C, 0x38, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + /* 0x11C */ 0x7C, 0x82, 0x7C, 0xC6, 0xC0, 0xCE, 0x7E, 0x00, + /* 0x11D */ 0x7E, 0xC3, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + /* 0x11E */ 0x82, 0x7C, 0x7C, 0xC6, 0xC0, 0xCE, 0x7E, 0x00, + /* 0x11F */ 0xC3, 0x7E, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + /* 0x120 */ 0x10, 0x00, 0x7C, 0xC6, 0xC0, 0xCE, 0x7E, 0x00, + /* 0x121 */ 0x10, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + /* 0x122 */ 0x7C, 0xC6, 0xC0, 0xCE, 0x7E, 0x18, 0x0C, 0x78, + /* 0x123 */ 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0x0C, 0x38, + /* 0x124 */ 0x78, 0x84, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, + /* 0x125 */ 0xEE, 0x7B, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, + /* 0x126 */ 0xCC, 0xFE, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, + /* 0x127 */ 0xE0, 0xFE, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, + /* 0x128 */ 0x76, 0xDC, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x129 */ 0x76, 0xDC, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x12A */ 0x78, 0x00, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x12B */ 0x78, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x12C */ 0x84, 0x78, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x12D */ 0xC6, 0x7C, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x12E */ 0x78, 0x30, 0x30, 0x30, 0x78, 0x18, 0x30, 0x1E, + /* 0x12F */ 0x30, 0x00, 0x70, 0x30, 0x30, 0x78, 0x30, 0x1C, + /* 0x130 */ 0x10, 0x00, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x131 */ 0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x132 */ 0xEE, 0x42, 0x42, 0x42, 0x52, 0x52, 0xEC, 0x00, + /* 0x133 */ 0x42, 0x00, 0xC6, 0x42, 0x42, 0x42, 0xE2, 0x0C, + /* 0x134 */ 0x7C, 0x82, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, + /* 0x135 */ 0x7C, 0xC6, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, + /* 0x136 */ 0xE6, 0x6C, 0x78, 0x6C, 0xE6, 0x30, 0x18, 0xF0, + /* 0x137 */ 0xE0, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x30, 0xE0, + /* 0x138 */ 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x6C, 0xE6, 0x00, + /* 0x139 */ 0xF3, 0x66, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, + /* 0x13A */ 0x73, 0x36, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x13B */ 0xF0, 0x60, 0x62, 0x66, 0xFE, 0x18, 0x0C, 0x78, + /* 0x13C */ 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x0C, 0x38, + /* 0x13D */ 0xF5, 0x66, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, + /* 0x13E */ 0x75, 0x36, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x13F */ 0xF0, 0x60, 0x64, 0x60, 0x62, 0x66, 0xFE, 0x00, + /* 0x140 */ 0x70, 0x30, 0x30, 0x32, 0x30, 0x30, 0x78, 0x00, + /* 0x141 */ 0xF0, 0x60, 0x70, 0x60, 0xE2, 0x66, 0xFE, 0x00, + /* 0x142 */ 0x70, 0x30, 0x38, 0x30, 0x70, 0x30, 0x78, 0x00, + /* 0x143 */ 0x0C, 0x18, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, + /* 0x144 */ 0x1C, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + /* 0x145 */ 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x30, 0x18, 0xF0, + /* 0x146 */ 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x30, 0xE0, + /* 0x147 */ 0x6C, 0x38, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, + /* 0x148 */ 0x6C, 0x38, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + /* 0x149 */ 0xC0, 0x80, 0x5C, 0x66, 0x66, 0x66, 0x66, 0x00, + /* 0x14A */ 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x0C, 0x38, + /* 0x14B */ 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x0C, 0x38, + /* 0x14C */ 0xFE, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0x14D */ 0x00, 0xFC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0x14E */ 0x6C, 0x38, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0x14F */ 0x6C, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0x150 */ 0x36, 0x6C, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0x151 */ 0x36, 0x6C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + /* 0x152 */ 0x7E, 0xDA, 0x88, 0x8C, 0x88, 0xDA, 0x7E, 0x00, + /* 0x153 */ 0x00, 0x00, 0x6C, 0x92, 0x9E, 0x90, 0x6C, 0x00, + /* 0x154 */ 0x0C, 0x18, 0xFC, 0x66, 0x7C, 0x6C, 0xE6, 0x00, + /* 0x155 */ 0x0C, 0x18, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, + /* 0x156 */ 0xFC, 0x66, 0x7C, 0x6C, 0xE6, 0x30, 0x18, 0xF0, + /* 0x157 */ 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x30, 0xE0, + /* 0x158 */ 0x6C, 0x38, 0xFC, 0x66, 0x7C, 0x6C, 0xE6, 0x00, + /* 0x159 */ 0x6C, 0x38, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, + /* 0x15A */ 0x0C, 0x18, 0x7C, 0xE0, 0x78, 0x0E, 0x7C, 0x00, + /* 0x15B */ 0x0C, 0x18, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, + /* 0x15C */ 0x7C, 0x82, 0x7C, 0xE0, 0x78, 0x0E, 0x7C, 0x00, + /* 0x15D */ 0x7C, 0xC6, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, + /* 0x15E */ 0x7C, 0xE0, 0x78, 0x0E, 0x7C, 0x18, 0x0C, 0x78, + /* 0x15F */ 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x0C, 0x38, + /* 0x160 */ 0x6C, 0x38, 0x7C, 0xE0, 0x78, 0x0E, 0x7C, 0x00, + /* 0x161 */ 0x6C, 0x38, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, + /* 0x162 */ 0xFC, 0x30, 0x30, 0x30, 0x78, 0x18, 0x0C, 0x38, + /* 0x163 */ 0x10, 0x30, 0xFC, 0x30, 0x34, 0x18, 0x0C, 0x38, + /* 0x164 */ 0x6C, 0x38, 0xFC, 0x30, 0x30, 0x30, 0x78, 0x00, + /* 0x165 */ 0x12, 0x3A, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, + /* 0x166 */ 0xFC, 0xB4, 0x30, 0x30, 0xFC, 0x30, 0x78, 0x00, + /* 0x167 */ 0x10, 0x30, 0xFC, 0x30, 0xFC, 0x34, 0x18, 0x00, + /* 0x168 */ 0x76, 0xDC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0x169 */ 0x76, 0xDC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0x16A */ 0xFE, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0x16B */ 0x00, 0xFE, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0x16C */ 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0x16D */ 0x6C, 0x38, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0x16E */ 0x38, 0x6C, 0xFE, 0xD6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0x16F */ 0x38, 0x6C, 0x38, 0xDC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0x170 */ 0x36, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, + /* 0x171 */ 0x36, 0x6C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, + /* 0x172 */ 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x30, 0x60, 0x3C, + /* 0x173 */ 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x18, 0x0E, + /* 0x174 */ 0x7C, 0x82, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + /* 0x175 */ 0x7C, 0xC6, 0x00, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + /* 0x176 */ 0x7C, 0x82, 0xCC, 0xCC, 0x78, 0x30, 0x78, 0x00, + /* 0x177 */ 0x7C, 0xC6, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + /* 0x178 */ 0xCC, 0x00, 0xCC, 0xCC, 0x78, 0x30, 0x78, 0x00, + /* 0x179 */ 0x0C, 0x18, 0xFE, 0x8C, 0x18, 0x32, 0xFE, 0x00, + /* 0x17A */ 0x0C, 0x18, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, + /* 0x17B */ 0x10, 0x00, 0xFE, 0x8C, 0x18, 0x32, 0xFE, 0x00, + /* 0x17C */ 0x10, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, + /* 0x17D */ 0x6C, 0x38, 0xFE, 0x8C, 0x18, 0x32, 0xFE, 0x00, + /* 0x17E */ 0x6C, 0x38, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, + /* 0x17F */ 0x38, 0x6C, 0x64, 0xE0, 0x60, 0x60, 0xE0, 0x00, + /* euro character (0x20AC) */ + /* 0x20AC*/ 0x3C, 0x62, 0xF8, 0x60, 0xF8, 0x62, 0x3C, 0x00 +}; + + + +/* range definitions for the above binary data */ +static const int builtin_rom_font_8x8_ranges[] = { + 0x00000020, 0x0000007F, + 0x000000A1, 0x000000FF, + 0x00000100, 0x0000017F, + 0x000020AC, 0x000020AC +}; + +static const int builtin_rom_font_8x8_ranges_count = + (sizeof(builtin_rom_font_8x8_ranges) / sizeof(int)) / 2; + + + +static void put_pixel_abgr8888_le(ALLEGRO_LOCKED_REGION *region, + int x, int y, uint32_t pixel) +{ + uint32_t *target = (uint32_t *) ((uint8_t *)region->data + + y * region->pitch + + x * region->pixel_size); + *target = pixel; +} + + + +/* decodes the binary data and creates a bitmap containing the glyps from it */ +static ALLEGRO_BITMAP *create_builtin_font_sheet(void) +{ + const int glyph_count = sizeof(builtin_rom_font_8x8) / 8; + const int glyphs_per_row = 32; + const int alloc_rows = (glyph_count + glyphs_per_row - 1) / glyphs_per_row; + + ALLEGRO_STATE state; + ALLEGRO_BITMAP *bmp; + ALLEGRO_LOCKED_REGION *lr; + int i, j, k; + + al_store_state(&state, + ALLEGRO_STATE_NEW_BITMAP_PARAMETERS | + ALLEGRO_STATE_TARGET_BITMAP); + + /* putting pixels is much faster on a memory bitmap */ + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); + + /* create bitmap onto which to render the glyphs */ + bmp = al_create_bitmap(glyphs_per_row * 8 + glyphs_per_row + 1, + alloc_rows * 8 + alloc_rows + 1); + if (bmp) { + al_set_target_bitmap(bmp); + al_clear_to_color(al_map_rgba(255, 255, 0, 255)); + lr = al_lock_bitmap(bmp, + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READWRITE); + + /* decode and render glyph pixels */ + for (i = 0; i < glyph_count; i++) { + /* for each of the 8 lines per character */ + for (j = 0; j < 8; j++) { + /* decode and draw each of the 8 pixels of the current line */ + for (k = 0; k < 8; k++) { + bool set = (builtin_rom_font_8x8[i * 8 + j] >> (7 - k)) & 0x01; + + put_pixel_abgr8888_le(lr, + (i % glyphs_per_row) * 9 + 1 + k, + (i / glyphs_per_row) * 9 + 1 + j, + set ? 0xFFFFFFFF : 0x00000000); + } + } + } + + al_unlock_bitmap(bmp); + } + else { + ALLEGRO_ERROR("Unable to create bitmap.\n"); + } + + al_restore_state(&state); + + return bmp; +} + + + +/* Function: al_create_builtin_font + */ +ALLEGRO_FONT *al_create_builtin_font(void) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_FONT *font; + + bmp = create_builtin_font_sheet(); + if (!bmp) + return NULL; + + font = al_grab_font_from_bitmap(bmp, builtin_rom_font_8x8_ranges_count, + builtin_rom_font_8x8_ranges); + + al_destroy_bitmap(bmp); + + return font; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/font/text.c b/allegro/addons/font/text.c new file mode 100644 index 00000000..c0d9aa31 --- /dev/null +++ b/allegro/addons/font/text.c @@ -0,0 +1,709 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Text drawing routines. + * + * By Shawn Hargreaves. + * + * textout_justify() by Seymour Shlien. + * + * Laurence Withers added the textout_ex() function family. + * + * See readme.txt for copyright information. + */ + + +#include <math.h> +#include <ctype.h> +#include "allegro5/allegro.h" + +#include "allegro5/allegro_font.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_font.h" +#include "allegro5/internal/aintern_system.h" + +/* If you call this, you're probably making a mistake. */ +/* +#define strlen(s) __are_you_sure__ +*/ +/* Removed the above define since some compilers seem to use some + * preprocessor magic when calling strcmp() that inserts a call to strlen. + * There might be a better way to do this. + */ + + + +/* Text usually looks best when aligned to pixels - + * but if x is 0.5 it may very well end up at an integer + * position if the current transformation scales by 2 or + * translated x by 0.5. So we simply apply the transformation, + * round to nearest integer, and backtransform that. + */ +static void align_to_integer_pixel_inner( + ALLEGRO_TRANSFORM const *fwd, + ALLEGRO_TRANSFORM const *inv, + float *x, float *y) +{ + al_transform_coordinates(fwd, x, y); + *x = floorf(*x + 0.5f); + *y = floorf(*y + 0.5f); + al_transform_coordinates(inv, x, y); +} + +static void align_to_integer_pixel(float *x, float *y) +{ + ALLEGRO_TRANSFORM const *fwd; + ALLEGRO_TRANSFORM inv; + + fwd = al_get_current_transform(); + al_copy_transform(&inv, fwd); + al_invert_transform(&inv); + align_to_integer_pixel_inner(fwd, &inv, x, y); +} + + + +/* Function: al_draw_ustr + */ +void al_draw_ustr(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, int flags, + const ALLEGRO_USTR *ustr) +{ + ASSERT(font); + ASSERT(ustr); + + if (flags & ALLEGRO_ALIGN_CENTRE) { + /* Use integer division to avoid introducing a fractional + * component to an integer x value. + */ + x -= font->vtable->text_length(font, ustr) / 2; + } + else if (flags & ALLEGRO_ALIGN_RIGHT) { + x -= font->vtable->text_length(font, ustr); + } + + if (flags & ALLEGRO_ALIGN_INTEGER) + align_to_integer_pixel(&x, &y); + + font->vtable->render(font, color, ustr, x, y); +} + + + +/* Function: al_draw_text + */ +void al_draw_text(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, int flags, + char const *text) +{ + ALLEGRO_USTR_INFO info; + ASSERT(text); + al_draw_ustr(font, color, x, y, flags, al_ref_cstr(&info, text)); +} + + + +/* Function: al_draw_justified_ustr + */ +void al_draw_justified_ustr(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x1, float x2, + float y, float diff, int flags, const ALLEGRO_USTR *ustr) +{ + const char *whitespace = " \t\n\r"; + ALLEGRO_USTR_INFO word_info; + const ALLEGRO_USTR *word; + int pos1, pos2; + int minlen; + int num_words; + int space; + float fleft, finc; + int advance; + ALLEGRO_TRANSFORM const *fwd = NULL; + ALLEGRO_TRANSFORM inv; + + ASSERT(font); + + /* count words and measure min length (without spaces) */ + num_words = 0; + minlen = 0; + pos1 = 0; + for (;;) { + pos1 = al_ustr_find_cset_cstr(ustr, pos1, whitespace); + if (pos1 == -1) + break; + pos2 = al_ustr_find_set_cstr(ustr, pos1, whitespace); + if (pos2 == -1) + pos2 = al_ustr_size(ustr); + + word = al_ref_ustr(&word_info, ustr, pos1, pos2); + minlen += font->vtable->text_length(font, word); + num_words++; + + pos1 = pos2; + } + + /* amount of room for space between words */ + space = x2 - x1 - minlen; + + if ((space <= 0) || (space > diff) || (num_words < 2)) { + /* can't justify */ + if (flags & ALLEGRO_ALIGN_INTEGER) + align_to_integer_pixel(&x1, &y); + font->vtable->render(font, color, ustr, x1, y); + return; + } + + /* distribute space left evenly between words */ + fleft = (float)x1; + finc = (float)space / (float)(num_words-1); + pos1 = 0; + + if (flags & ALLEGRO_ALIGN_INTEGER) { + fwd = al_get_current_transform(); + al_copy_transform(&inv, fwd); + al_invert_transform(&inv); + } + + for (;;) { + pos1 = al_ustr_find_cset_cstr(ustr, pos1, whitespace); + if (pos1 == -1) + break; + pos2 = al_ustr_find_set_cstr(ustr, pos1, whitespace); + if (pos2 == -1) + pos2 = al_ustr_size(ustr); + + word = al_ref_ustr(&word_info, ustr, pos1, pos2); + if (flags & ALLEGRO_ALIGN_INTEGER) { + float drawx = fleft; + float drawy = y; + align_to_integer_pixel_inner(fwd, &inv, &drawx, &drawy); + advance = font->vtable->render(font, color, word, drawx, drawy); + } + else { + advance = font->vtable->render(font, color, word, fleft, y); + } + fleft += advance + finc; + pos1 = pos2; + } +} + + +/* Function: al_draw_justified_text + */ +void al_draw_justified_text(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x1, float x2, + float y, float diff, int flags, const char *text) +{ + ALLEGRO_USTR_INFO info; + ASSERT(text); + al_draw_justified_ustr(font, color, x1, x2, y, diff, flags, + al_ref_cstr(&info, text)); +} + + +/* Function: al_draw_textf + */ +void al_draw_textf(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, + float x, float y, int flags, + const char *format, ...) +{ + ALLEGRO_USTR *buf; + va_list ap; + const char *s; + ASSERT(font); + ASSERT(format); + + /* Fast path for common case. */ + if (0 == strcmp(format, "%s")) { + va_start(ap, format); + s = va_arg(ap, const char *); + al_draw_text(font, color, x, y, flags, s); + va_end(ap); + return; + } + + va_start(ap, format); + buf = al_ustr_new(""); + al_ustr_vappendf(buf, format, ap); + va_end(ap); + + al_draw_text(font, color, x, y, flags, al_cstr(buf)); + + al_ustr_free(buf); +} + + + +/* Function: al_draw_justified_textf + */ +void al_draw_justified_textf(const ALLEGRO_FONT *f, + ALLEGRO_COLOR color, float x1, float x2, float y, + float diff, int flags, const char *format, ...) +{ + ALLEGRO_USTR *buf; + va_list ap; + ASSERT(f); + ASSERT(format); + + va_start(ap, format); + buf = al_ustr_new(""); + al_ustr_vappendf(buf, format, ap); + va_end(ap); + + al_draw_justified_text(f, color, x1, x2, y, diff, flags, + al_cstr(buf)); + + al_ustr_free(buf); +} + + + +/* Function: al_get_ustr_width + */ +int al_get_ustr_width(const ALLEGRO_FONT *f, ALLEGRO_USTR const *ustr) +{ + ASSERT(f); + ASSERT(ustr); + + return f->vtable->text_length(f, ustr); +} + + + +/* Function: al_get_text_width + */ +int al_get_text_width(const ALLEGRO_FONT *f, const char *str) +{ + ALLEGRO_USTR_INFO str_info; + const ALLEGRO_USTR *ustr; + ASSERT(f); + ASSERT(str); + + ustr = al_ref_cstr(&str_info, str); + + return f->vtable->text_length(f, ustr); +} + + + +/* Function: al_get_font_line_height + */ +int al_get_font_line_height(const ALLEGRO_FONT *f) +{ + ASSERT(f); + return f->vtable->font_height(f); +} + + + +/* Function: al_get_font_ascent + */ +int al_get_font_ascent(const ALLEGRO_FONT *f) +{ + ASSERT(f); + return f->vtable->font_ascent(f); +} + + + +/* Function: al_get_font_descent + */ +int al_get_font_descent(const ALLEGRO_FONT *f) +{ + ASSERT(f); + return f->vtable->font_descent(f); +} + + + +/* Function: al_get_ustr_dimensions + */ +void al_get_ustr_dimensions(const ALLEGRO_FONT *f, + ALLEGRO_USTR const *ustr, + int *bbx, int *bby, int *bbw, int *bbh) +{ + ASSERT(f); + ASSERT(ustr); + f->vtable->get_text_dimensions(f, ustr, bbx, bby, + bbw, bbh); +} + + + +/* Function: al_get_text_dimensions + */ +void al_get_text_dimensions(const ALLEGRO_FONT *f, + char const *text, + int *bbx, int *bby, int *bbw, int *bbh) +{ + ALLEGRO_USTR_INFO info; + ASSERT(f); + ASSERT(text); + + f->vtable->get_text_dimensions(f, al_ref_cstr(&info, text), bbx, bby, + bbw, bbh); +} + + + +/* Function: al_destroy_font + */ +void al_destroy_font(ALLEGRO_FONT *f) +{ + if (!f) + return; + + _al_unregister_destructor(_al_dtor_list, f->dtor_item); + + f->vtable->destroy(f); +} + + +/* Function: al_get_font_ranges + */ +int al_get_font_ranges(ALLEGRO_FONT *f, int ranges_count, int *ranges) +{ + return f->vtable->get_font_ranges(f, ranges_count, ranges); +} + +/* Function: al_draw_glyph + */ +void al_draw_glyph(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, float x, float y, + int codepoint) +{ + f->vtable->render_char(f, color, codepoint, x, y); +}; + +/* Function: al_get_glyph_width + */ +int al_get_glyph_width(const ALLEGRO_FONT *f, int codepoint) +{ + return f->vtable->char_length(f, codepoint); +} + +/* Function: al_get_glyph_dimensions + */ +bool al_get_glyph_dimensions(const ALLEGRO_FONT *f, + int codepoint, int *bbx, int *bby, int *bbw, int *bbh) +{ + return f->vtable->get_glyph_dimensions(f, codepoint, bbx, bby, bbw, bbh); +} + +/* Function: al_get_glyph_advance + */ +int al_get_glyph_advance(const ALLEGRO_FONT *f, int codepoint1, int codepoint2) +{ + return f->vtable->get_glyph_advance(f, codepoint1, codepoint2); +} + +/* Function: al_get_glyph + */ +bool al_get_glyph(const ALLEGRO_FONT *f, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *glyph) +{ + return f->vtable->get_glyph(f, prev_codepoint, codepoint, glyph); +}; + + +/* This helper function helps splitting an ustr in several delimited parts. + * It returns an ustr that refers to the next part of the string that + * is delimited by the delimiters in delimiter. + * Returns NULL at the end of the string. + * Pos is updated to byte index of character after the delimiter or + * to the end of the string. + */ +static const ALLEGRO_USTR *ustr_split_next(const ALLEGRO_USTR *ustr, + ALLEGRO_USTR_INFO *info, int *pos, const char *delimiter) +{ + const ALLEGRO_USTR *result; + int end, size; + + size = al_ustr_size(ustr); + if (*pos >= size) { + return NULL; + } + + end = al_ustr_find_set_cstr(ustr, *pos, delimiter); + if (end == -1) + end = size; + + result = al_ref_ustr(info, ustr, *pos, end); + /* Set pos to character AFTER delimiter */ + al_ustr_next(ustr, &end); + (*pos) = end; + return result; +} + + + +/* This returns the next "soft" line of text from ustr + * that will fit in max_with using the font font, starting at pos *pos. + * These are "soft" lines because they are broken up if needed at a space + * or tab character. + * This function updates pos if needed, and returns the next "soft" line, + * or NULL if no more soft lines. + * The soft line will not include the trailing space where the + * line was split, but pos will be set to point to after that trailing + * space so iteration can continue easily. + */ +static const ALLEGRO_USTR *get_next_soft_line(const ALLEGRO_USTR *ustr, + ALLEGRO_USTR_INFO *info, int *pos, + const ALLEGRO_FONT *font, float max_width) +{ + const ALLEGRO_USTR *result = NULL; + const char *whitespace = " \t"; + int old_end = 0; + int end = 0; + int size = al_ustr_size(ustr); + bool first_word = true; + + if (*pos >= size) { + return NULL; + } + + end = *pos; + old_end = end; + do { + /* On to the next word. */ + end = al_ustr_find_set_cstr(ustr, end, whitespace); + if (end < 0) + end = size; + + /* Reference to the line that is being built. */ + result = al_ref_ustr(info, ustr, *pos, end); + + /* Check if the line is too long. If it is, return a soft line. */ + if (al_get_ustr_width(font, result) > max_width) { + /* Corner case: a single word may not even fit the line. + * In that case, return the word/line anyway as the "soft line", + * the user can set a clip rectangle to cut it. */ + + if (first_word) { + /* Set pos to character AFTER end to allow easy iteration. */ + al_ustr_next(ustr, &end); + *pos = end; + return result; + } + else { + /* Not first word, return old end position without the new word */ + result = al_ref_ustr(info, ustr, *pos, old_end); + /* Set pos to character AFTER end to allow easy iteration. */ + al_ustr_next(ustr, &old_end); + *pos = old_end; + return result; + } + } + first_word = false; + old_end = end; + /* Skip the character at end which normally is whitespace. */ + al_ustr_next(ustr, &end); + } while (end < size); + + /* If we get here the whole ustr will fit.*/ + result = al_ref_ustr(info, ustr, *pos, size); + *pos = size; + return result; +} + + +/* Function: al_do_multiline_ustr + */ +void al_do_multiline_ustr(const ALLEGRO_FONT *font, float max_width, + const ALLEGRO_USTR *ustr, + bool (*cb)(int line_num, const ALLEGRO_USTR * line, void *extra), + void *extra) +{ + const char *linebreak = "\n"; + const ALLEGRO_USTR *hard_line, *soft_line; + ALLEGRO_USTR_INFO hard_line_info, soft_line_info; + int hard_line_pos = 0, soft_line_pos = 0; + int line_num = 0; + bool proceed; + + /* For every "hard" line separated by a newline character... */ + hard_line = ustr_split_next(ustr, &hard_line_info, &hard_line_pos, + linebreak); + while (hard_line) { + /* For every "soft" line in the "hard" line... */ + soft_line_pos = 0; + soft_line = + get_next_soft_line(hard_line, &soft_line_info, &soft_line_pos, font, + max_width); + /* No soft line here because it's an empty hard line. */ + if (!soft_line) { + /* Call the callback with empty string to indicate an empty line. */ + proceed = cb(line_num, al_ustr_empty_string(), extra); + if (!proceed) return; + line_num ++; + } + while(soft_line) { + /* Call the callback on the next soft line. */ + proceed = cb(line_num, soft_line, extra); + if (!proceed) return; + line_num++; + + soft_line = get_next_soft_line(hard_line, &soft_line_info, + &soft_line_pos, font, max_width); + } + hard_line = ustr_split_next(ustr, &hard_line_info, &hard_line_pos, + linebreak); + } +} + + + +/* Helper struct for al_do_multiline_text. */ +typedef struct DO_MULTILINE_TEXT_EXTRA { + bool (*callback)(int line_num, const char *line, int size, void *extra); + void *extra; +} DO_MULTILINE_TEXT_EXTRA; + + + +/* The functions do_multiline_text_cb is the helper callback + * that "adapts" al_do_multiline_ustr to al_do_multiline_text. + */ +static bool do_multiline_text_cb(int line_num, const ALLEGRO_USTR *line, + void *extra) { + DO_MULTILINE_TEXT_EXTRA *s = extra; + + return s->callback(line_num, al_cstr(line), al_ustr_size(line), s->extra); +} + + + +/* Function: al_do_multiline_text + */ +void al_do_multiline_text(const ALLEGRO_FONT *font, + float max_width, const char *text, + bool (*cb)(int line_num, const char *line, int size, void *extra), + void *extra) +{ + ALLEGRO_USTR_INFO info; + DO_MULTILINE_TEXT_EXTRA extra2; + ASSERT(font); + ASSERT(text); + + extra2.callback = cb; + extra2.extra = extra; + al_do_multiline_ustr(font, max_width, al_ref_cstr(&info, text), + do_multiline_text_cb, &extra2); +} + + + +/* Helper struct for al_draw_multiline_ustr. */ +typedef struct DRAW_MULTILINE_USTR_EXTRA { + const ALLEGRO_FONT *font; + ALLEGRO_COLOR color; + float x; + float y; + float line_height; + int flags; +} DRAW_MULTILINE_USTR_EXTRA; + + + +/* The function draw_multiline_ustr_cb is the helper callback + * that implements the actual drawing for al_draw_multiline_ustr. + */ +static bool draw_multiline_ustr_cb(int line_num, const ALLEGRO_USTR *line, + void *extra) { + DRAW_MULTILINE_USTR_EXTRA *s = extra; + float y; + + y = s->y + (s->line_height * line_num); + al_draw_ustr(s->font, s->color, s->x, y, s->flags, line); + return true; +} + + + +/* Function: al_draw_multiline_ustr + */ +void al_draw_multiline_ustr(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, + int flags, const ALLEGRO_USTR *ustr) +{ + DRAW_MULTILINE_USTR_EXTRA extra; + ASSERT(font); + ASSERT(ustr); + + extra.font = font; + extra.color = color; + extra.x = x; + extra.y = y; + if (line_height < 1) { + extra.line_height = al_get_font_line_height(font); + } + else { + extra.line_height = line_height; + } + extra.flags = flags; + + al_do_multiline_ustr(font, max_width, ustr, draw_multiline_ustr_cb, &extra); +} + + + +/* Function: al_draw_multiline_text + */ +void al_draw_multiline_text(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, + int flags, const char *text) +{ + ALLEGRO_USTR_INFO info; + ASSERT(font); + ASSERT(text); + + al_draw_multiline_ustr(font, color, x, y, max_width, line_height, flags, + al_ref_cstr(&info, text)); +} + + + +/* Function: al_draw_multiline_textf + */ +void al_draw_multiline_textf(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, + int flags, const char *format, ...) +{ + ALLEGRO_USTR *buf; + va_list ap; + ASSERT(font); + ASSERT(format); + + va_start(ap, format); + buf = al_ustr_new(""); + al_ustr_vappendf(buf, format, ap); + va_end(ap); + + al_draw_multiline_ustr(font, color, x, y, max_width, line_height, flags, + buf); + + al_ustr_free(buf); +} + + +/* Function: al_set_fallback_font + */ +void al_set_fallback_font(ALLEGRO_FONT *font, ALLEGRO_FONT *fallback) +{ + font->fallback = fallback; +} + +/* Function: al_get_fallback_font + */ +ALLEGRO_FONT *al_get_fallback_font(ALLEGRO_FONT *font) +{ + return font->fallback; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/font/xml.c b/allegro/addons/font/xml.c new file mode 100644 index 00000000..1b0e4da9 --- /dev/null +++ b/allegro/addons/font/xml.c @@ -0,0 +1,138 @@ +#include "allegro5/allegro.h" +#include <ctype.h> + +#include "xml.h" + +typedef struct { + XmlState state; + bool closing; + ALLEGRO_USTR *value; + int (*callback)(XmlState state, char const *value, void *u); + void *u; +} XmlParser; + +static void scalar(XmlParser *x) { + x->callback(x->state, al_cstr(x->value), x->u); + al_ustr_assign_cstr(x->value, ""); +} + +static void opt_scalar(XmlParser *x) { + if (al_ustr_size(x->value)) { + scalar(x); + } +} + +static void discard_scalar(XmlParser *x) { + al_ustr_assign_cstr(x->value, ""); +} + +static void close_tag(XmlParser *x) { + x->state = Outside; + x->closing = false; +} + +static void add_char(XmlParser *x, char c) { + char s[] = {c, 0}; + al_ustr_append_cstr(x->value, s); +} + +static void create_tag(XmlParser *x) { + scalar(x); +} + +static void open_tag(XmlParser *x) { + x->state = Outside; +} + +void _al_xml_parse(ALLEGRO_FILE *f, + int (*callback)(XmlState state, char const *value, void *u), + void *u) +{ + XmlParser x_; + XmlParser *x = &x_; + x->value = al_ustr_new(""); + x->state = Outside; + x->closing = false; + x->callback = callback; + x->u = u; + + while (true) { + int c = al_fgetc(f); + if (c < 0) { + break; + } + if (x->state == Outside) { + if (c == '<') { + opt_scalar(x); + x->state = ElementName; + continue; + } + } + else if (x->state == ElementName) { + if (c == '/') { + x->closing = true; + continue; + } + else if (c == '>') { + if (x->closing) { + discard_scalar(x); + close_tag(x); + } + else { + create_tag(x); + open_tag(x); + } + continue; + } + else if (isspace(c)) { + create_tag(x); + x->state = AttributeName; + continue; + } + } + else if (x->state == AttributeName) { + if (isspace(c)) { + continue; + } + else if (c == '/') { + x->closing = true; + continue; + } + else if (c == '?') { + x->closing = true; + continue; + } + else if (c == '>') { + if (x->closing) { + close_tag(x); + } + else { + open_tag(x); + } + continue; + } + else if (c == '=') { + scalar(x); + x->state = AttributeStart; + continue; + } + } + else if (x->state == AttributeStart) { + if (c == '"') { + x->state = AttributeValue; + } + continue; + } + else if (x->state == AttributeValue) { + if (c == '"') { + scalar(x); + x->state = AttributeName; + continue; + } + } + add_char(x, c); + } + + al_fclose(f); + al_ustr_free(x->value); +} diff --git a/allegro/addons/font/xml.h b/allegro/addons/font/xml.h new file mode 100644 index 00000000..07fb6cbd --- /dev/null +++ b/allegro/addons/font/xml.h @@ -0,0 +1,11 @@ +typedef enum { + Outside, + ElementName, + AttributeName, + AttributeStart, + AttributeValue +} XmlState; + +void _al_xml_parse(ALLEGRO_FILE *f, + int (*callback)(XmlState state, char const *value, void *u), + void *u); diff --git a/allegro/addons/image/CMakeLists.txt b/allegro/addons/image/CMakeLists.txt new file mode 100644 index 00000000..7da47d72 --- /dev/null +++ b/allegro/addons/image/CMakeLists.txt @@ -0,0 +1,184 @@ +option(WANT_NATIVE_IMAGE_LOADER "Enable the native platform image loader (if available)" on) + +set(IMAGE_SOURCES bmp.c iio.c pcx.c tga.c dds.c identify.c) +set(IMAGE_INCLUDE_FILES allegro5/allegro_image.h) + +set_our_header_properties(${IMAGE_INCLUDE_FILES}) + +# Accumulate these. +set(IMAGE_LIBRARIES) +set(IMAGE_DEFINES) + +# ALLEGRO_CFG_IIO_HAVE_* are the available libraries. +# ALLEGRO_CFG_IIO_SUPPORT_* are the supported formats. + +# First look for native libraries and mark any supported image +# type as found, so that the associated third party libraries +# don't need to be used. + +if(WANT_NATIVE_IMAGE_LOADER) + set(ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER 1) + + if(WIN32) + find_package(GDIPLUS) + if(GDIPLUS_FOUND) + set(CMAKE_REQUIRED_DEFINITIONS -DGDIPLUS_LOWERCASE=${GDIPLUS_LOWERCASE}) + set(CMAKE_REQUIRED_INCLUDES ${GDIPLUS_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${GDIPLUS_LIBRARY}) + run_cxx_compile_test(" + #include <windows.h> + #include <objidl.h> + #if GDIPLUS_LOWERCASE + #include <gdiplus.h> + #else + #include <GdiPlus.h> + #endif + using namespace Gdiplus; + int main(void) + { + int pf = PixelFormat32bppARGB; + return 0; + } + " + SUPPORT_GDIPLUS) + endif(GDIPLUS_FOUND) + if(SUPPORT_GDIPLUS) + set(ALLEGRO_CFG_IIO_HAVE_GDIPLUS 1) + set(ALLEGRO_CFG_IIO_HAVE_GDIPLUS_LOWERCASE_H ${GDIPLUS_LOWERCASE}) + set(ALLEGRO_CFG_IIO_SUPPORT_PNG 1) + set(ALLEGRO_CFG_IIO_SUPPORT_JPG 1) + list(APPEND IMAGE_SOURCES gdiplus.cpp) + list(APPEND IMAGE_LIBRARIES ${GDIPLUS_LIBRARIES}) + if(MINGW) + list(APPEND IMAGE_LIBRARIES uuid) + endif(MINGW) + list(APPEND IMAGE_DEFINES ${GDIPLUS_DEFINITIONS}) + list(APPEND IMAGE_INCLUDE_DIRECTORIES ${GDIPLUS_INCLUDE_DIR}) + include_directories(SYSTEM ${GDIPLUS_INCLUDE_DIR}) + else(SUPPORT_GDIPLUS) + message("WARNING: cannot use GDI+. Will try other libraries.") + endif(SUPPORT_GDIPLUS) + endif(WIN32) + + if (MACOSX) + set(ALLEGRO_CFG_IIO_SUPPORT_PNG 1) + set(ALLEGRO_CFG_IIO_SUPPORT_JPG 1) + list(APPEND IMAGE_SOURCES macosx.m) + endif(MACOSX) + + if(ANDROID) + set(ALLEGRO_CFG_IIO_HAVE_ANDROID 1) + set(ALLEGRO_CFG_IIO_SUPPORT_JPG 1) + set(ALLEGRO_CFG_IIO_SUPPORT_PNG 1) + set(ALLEGRO_CFG_IIO_SUPPORT_WEBP 1) + list(APPEND IMAGE_SOURCES android.c) + endif(ANDROID) + + if(IPHONE) + list(APPEND IMAGE_SOURCES iphone.m) + endif(IPHONE) +endif(WANT_NATIVE_IMAGE_LOADER) + +# Now look for third party libraries to handle the unsupported formats +if(WANT_IMAGE_FREEIMAGE) + find_package(FreeImage) + if(FREEIMAGE_FOUND) + # HAVE_FREEIMAGE means libfreeimage is available (and should be used) + set(ALLEGRO_CFG_IIO_HAVE_FREEIMAGE 1) + set(ALLEGRO_CFG_IIO_SUPPORT_FREEIMAGE 1) + list(APPEND IMAGE_SOURCES freeimage.c) + list(APPEND IMAGE_LIBRARIES ${FREEIMAGE_LIBRARIES}) + list(APPEND IMAGE_DEFINES ${FREEIMAGE_DEFINITIONS}) + list(APPEND IMAGE_INCLUDE_DIRECTORIES ${FREEIMAGE_INCLUDE_PATH}) + include_directories(SYSTEM ${FREEIMAGE_INCLUDE_PATH}) + else(FREEIMAGE_FOUND) + message("WARNING: FreeImage not found, disabling support") + endif(FREEIMAGE_FOUND) +endif(WANT_IMAGE_FREEIMAGE) + +if(WANT_IMAGE_PNG AND NOT ALLEGRO_CFG_IIO_SUPPORT_PNG) + find_package(PNG) + if(PNG_FOUND) + # HAVE_PNG means libpng is available (and should be used) + set(ALLEGRO_CFG_IIO_HAVE_PNG 1) + set(ALLEGRO_CFG_IIO_SUPPORT_PNG 1) + list(APPEND IMAGE_SOURCES png.c) + list(APPEND IMAGE_LIBRARIES ${PNG_LIBRARIES}) + list(APPEND IMAGE_DEFINES ${PNG_DEFINITIONS}) + list(APPEND IMAGE_INCLUDE_DIRECTORIES ${PNG_INCLUDE_DIR}) + include_directories(SYSTEM ${PNG_INCLUDE_DIR}) + else(PNG_FOUND) + message("WARNING: libpng not found, disabling support") + endif(PNG_FOUND) +endif(WANT_IMAGE_PNG AND NOT ALLEGRO_CFG_IIO_SUPPORT_PNG) + +if(WANT_IMAGE_JPG AND NOT ALLEGRO_CFG_IIO_SUPPORT_JPG) + find_package(JPEG) + if(JPEG_FOUND AND MINGW) + set(CMAKE_REQUIRED_INCLUDES ${JPEG_INCLUDE_DIR}) + run_c_compile_test(" + #include <stdio.h> + #include <windows.h> + #include <jpeglib.h> + #include <jerror.h> + int main(void) { + return 0; + }" + JPEG_COMPILES) + set(CMAKE_REQUIRED_INCLUDES) + set(SUPPORT_JPEG ${JPEG_COMPILES}) + else() + set(SUPPORT_JPEG ${JPEG_FOUND}) + endif() + if(SUPPORT_JPEG) + # HAVE_JPG means libjpeg is available (and should be used) + set(ALLEGRO_CFG_IIO_HAVE_JPG 1) + set(ALLEGRO_CFG_IIO_SUPPORT_JPG 1) + list(APPEND IMAGE_SOURCES jpg.c) + list(APPEND IMAGE_LIBRARIES ${JPEG_LIBRARIES}) + list(APPEND IMAGE_DEFINES ${JPEG_DEFINITIONS}) + list(APPEND IMAGE_INCLUDE_DIRECTORIES ${JPEG_INCLUDE_DIR}) + include_directories(SYSTEM ${JPEG_INCLUDE_DIR}) + else() + if(MINGW AND JPEG_FOUND AND NOT JPEG_COMPILES) + message("WARNING: libjpeg found but the headers appear to " + "conflict with your MinGW headers, so disabling support. " + "Try a later version.") + else() + message("WARNING: libjpeg not found, disabling support") + endif() + endif() +endif(WANT_IMAGE_JPG AND NOT ALLEGRO_CFG_IIO_SUPPORT_JPG) + +if(WANT_IMAGE_WEBP AND NOT ALLEGRO_CFG_IIO_SUPPORT_WEBP) + find_package(WebP) + if(WEBP_FOUND) + set(ALLEGRO_CFG_IIO_HAVE_WEBP 1) + set(ALLEGRO_CFG_IIO_SUPPORT_WEBP 1) + list(APPEND IMAGE_SOURCES webp.c) + list(APPEND IMAGE_LIBRARIES ${WEBP_LIBRARIES}) + list(APPEND IMAGE_INCLUDE_DIRECTORIES ${WEBP_INCLUDE_DIRS}) + include_directories(SYSTEM ${WEBP_INCLUDE_DIRS}) + else(WEBP_FOUND) + message("WARNING: libwebp not found, disabling support") + endif(WEBP_FOUND) +endif(WANT_IMAGE_WEBP AND NOT ALLEGRO_CFG_IIO_SUPPORT_WEBP) + +configure_file( + allegro5/internal/aintern_image_cfg.h.cmake + ${PROJECT_BINARY_DIR}/include/allegro5/internal/aintern_image_cfg.h + ) + +add_our_addon_library(allegro_image + AllegroImage-${ALLEGRO_SOVERSION} + "${IMAGE_SOURCES};${IMAGE_INCLUDE_FILES}" + "-DALLEGRO_IIO_SRC" + "${ALLEGRO_LINK_WITH};${IMAGE_LIBRARIES}" + ) + +install_our_headers(${IMAGE_INCLUDE_FILES}) + +add_addon(image) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/image/allegro5/allegro_image.h b/allegro/addons/image/allegro5/allegro_image.h new file mode 100644 index 00000000..3a853277 --- /dev/null +++ b/allegro/addons/image/allegro5/allegro_image.h @@ -0,0 +1,45 @@ +#ifndef __al_included_allegro5_allegro_image_h +#define __al_included_allegro5_allegro_image_h + +#include "allegro5/base.h" + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_IIO_SRC + #define _ALLEGRO_IIO_DLL __declspec(dllexport) + #else + #define _ALLEGRO_IIO_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_IIO_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_IIO_FUNC(type, name, args) _ALLEGRO_IIO_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_IIO_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_IIO_FUNC(type, name, args) extern _ALLEGRO_IIO_DLL type name args +#else + #define ALLEGRO_IIO_FUNC AL_FUNC +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +ALLEGRO_IIO_FUNC(bool, al_init_image_addon, (void)); +ALLEGRO_IIO_FUNC(bool, al_is_image_addon_initialized, (void)); +ALLEGRO_IIO_FUNC(void, al_shutdown_image_addon, (void)); +ALLEGRO_IIO_FUNC(uint32_t, al_get_allegro_image_version, (void)); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/allegro/addons/image/allegro5/internal/aintern_image.h b/allegro/addons/image/allegro5/internal/aintern_image.h new file mode 100644 index 00000000..e6354941 --- /dev/null +++ b/allegro/addons/image/allegro5/internal/aintern_image.h @@ -0,0 +1,105 @@ +#ifndef __al_included_allegro_aintern_image_h +#define __al_included_allegro_aintern_image_h + +#include "allegro5/platform/alplatf.h" +#include "allegro5/internal/aintern_image_cfg.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER + +#ifdef ALLEGRO_IPHONE +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_iphone_load_image, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_iphone_load_image_f, (ALLEGRO_FILE *f, int flags)); +#endif + +#ifdef ALLEGRO_MACOSX +ALLEGRO_IIO_FUNC(bool, _al_osx_register_image_loader, (void)); +#endif + +#endif + +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_pcx, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_pcx, (const char *filename, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_pcx_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_pcx_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(bool, _al_identify_pcx, (ALLEGRO_FILE *f)); + +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_bmp, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_bmp, (const char *filename, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_bmp_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_bmp_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(bool, _al_identify_bmp, (ALLEGRO_FILE *f)); + + +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_tga, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_tga, (const char *filename, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_tga_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_tga_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(bool, _al_identify_tga, (ALLEGRO_FILE *f)); + +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_dds, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_dds_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_identify_dds, (ALLEGRO_FILE *f)); + +ALLEGRO_IIO_FUNC(bool, _al_identify_png, (ALLEGRO_FILE *f)); +ALLEGRO_IIO_FUNC(bool, _al_identify_jpg, (ALLEGRO_FILE *f)); +ALLEGRO_IIO_FUNC(bool, _al_identify_webp, (ALLEGRO_FILE *f)); + +#ifdef ALLEGRO_CFG_IIO_HAVE_FREEIMAGE +ALLEGRO_IIO_FUNC(bool, _al_init_fi, (void)); +ALLEGRO_IIO_FUNC(void, _al_shutdown_fi, (void)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_fi_bitmap, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_fi_bitmap_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_identify_fi, (ALLEGRO_FILE *f)); +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS +ALLEGRO_IIO_FUNC(bool, _al_init_gdiplus, (void)); +ALLEGRO_IIO_FUNC(void, _al_shutdown_gdiplus, (void)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_gdiplus_bitmap, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_bitmap, (const char *filename, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_gdiplus_bitmap_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_png_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_jpg_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_tif_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(bool, _al_save_gdiplus_gif_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_ANDROID +ALLEGRO_BITMAP *_al_load_android_bitmap_f(ALLEGRO_FILE *fp, int flags); +ALLEGRO_BITMAP *_al_load_android_bitmap(const char *filename, int flags); +#endif + +/* ALLEGRO_CFG_IIO_HAVE_PNG/JPG implies that "native" loaders aren't available. */ + +#ifdef ALLEGRO_CFG_IIO_HAVE_PNG +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_png, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_png, (const char *filename, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_png_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_png_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_JPG +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_jpg, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_jpg, (const char *filename, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_jpg_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_jpg_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_WEBP +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_webp, (const char *filename, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_webp, (const char *filename, ALLEGRO_BITMAP *bmp)); +ALLEGRO_IIO_FUNC(ALLEGRO_BITMAP *, _al_load_webp_f, (ALLEGRO_FILE *f, int flags)); +ALLEGRO_IIO_FUNC(bool, _al_save_webp_f, (ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp)); +#endif + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/allegro/addons/image/allegro5/internal/aintern_image_cfg.h.cmake b/allegro/addons/image/allegro5/internal/aintern_image_cfg.h.cmake new file mode 100644 index 00000000..0e95ff5b --- /dev/null +++ b/allegro/addons/image/allegro5/internal/aintern_image_cfg.h.cmake @@ -0,0 +1,15 @@ +#cmakedefine ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER + +/* which libraries are present and needed? */ +#cmakedefine ALLEGRO_CFG_IIO_HAVE_FREEIMAGE +#cmakedefine ALLEGRO_CFG_IIO_HAVE_GDIPLUS +#cmakedefine ALLEGRO_CFG_IIO_HAVE_GDIPLUS_LOWERCASE_H +#cmakedefine ALLEGRO_CFG_IIO_HAVE_ANDROID +#cmakedefine ALLEGRO_CFG_IIO_HAVE_PNG +#cmakedefine ALLEGRO_CFG_IIO_HAVE_JPG +#cmakedefine ALLEGRO_CFG_IIO_HAVE_WEBP + +/* which formats are supported and wanted? */ +#cmakedefine ALLEGRO_CFG_IIO_SUPPORT_PNG +#cmakedefine ALLEGRO_CFG_IIO_SUPPORT_JPG +#cmakedefine ALLEGRO_CFG_IIO_SUPPORT_WEBP diff --git a/allegro/addons/image/android.c b/allegro/addons/image/android.c new file mode 100644 index 00000000..bf057535 --- /dev/null +++ b/allegro/addons/image/android.c @@ -0,0 +1,15 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_android.h" +#include "allegro5/internal/aintern_image.h" + +ALLEGRO_BITMAP *_al_load_android_bitmap_f(ALLEGRO_FILE *fp, int flags) +{ + return _al_android_load_image_f(fp, flags); +} + +ALLEGRO_BITMAP *_al_load_android_bitmap(const char *filename, int flags) +{ + return _al_android_load_image(filename, flags); +} + diff --git a/allegro/addons/image/bmp.c b/allegro/addons/image/bmp.c new file mode 100644 index 00000000..6968a1bc --- /dev/null +++ b/allegro/addons/image/bmp.c @@ -0,0 +1,1703 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * BMP reader. + * + * By Seymour Shlien. + * + * OS/2 BMP support and BMP save function by Jonas Petersen. + * + * See readme.txt for copyright information. + */ + + +#include <string.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_convert.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +ALLEGRO_DEBUG_CHANNEL("image") + +/* Do NOT simplify this to just (x), it doesn't work in MSVC. */ +#define INT_TO_BOOL(x) ((x) != 0) + + +#define BIT_RGB 0 +#define BIT_RLE8 1 +#define BIT_RLE4 2 +#define BIT_BITFIELDS 3 + +#define OS2INFOHEADERSIZE 12 +#define WININFOHEADERSIZE 40 +#define WININFOHEADERSIZEV2 52 +#define WININFOHEADERSIZEV3 56 +#define WININFOHEADERSIZEV4 108 +#define WININFOHEADERSIZEV5 124 + +typedef struct BMPFILEHEADER +{ + unsigned short bfType; + unsigned long bfSize; + unsigned short bfReserved1; + unsigned short bfReserved2; + unsigned long bfOffBits; +} BMPFILEHEADER; + + +/* Used for both OS/2 and Windows BMP. + * Contains only the parameters needed to load the image + */ +typedef struct BMPINFOHEADER +{ + unsigned long biWidth; + signed long biHeight; + unsigned short biBitCount; + unsigned long biCompression; + unsigned long biClrUsed; + uint32_t biRedMask; + uint32_t biGreenMask; + uint32_t biBlueMask; + bool biHaveAlphaMask; + uint32_t biAlphaMask; +} BMPINFOHEADER; + + +typedef struct WINBMPINFOHEADER +{ /* size: 40 */ + unsigned long biWidth; + signed long biHeight; + unsigned short biPlanes; + unsigned short biBitCount; + unsigned long biCompression; + unsigned long biSizeImage; + unsigned long biXPelsPerMeter; + unsigned long biYPelsPerMeter; + unsigned long biClrUsed; + unsigned long biClrImportant; +} WINBMPINFOHEADER; + + +typedef struct OS2BMPINFOHEADER +{ /* size: 12 */ + unsigned short biWidth; + unsigned short biHeight; + unsigned short biPlanes; + unsigned short biBitCount; +} OS2BMPINFOHEADER; + + +typedef void(*bmp_line_fn)(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul); + + + +/* read_bmfileheader: + * Reads a BMP file header and check that it has the BMP magic number. + */ +static int read_bmfileheader(ALLEGRO_FILE *f, BMPFILEHEADER *fileheader) +{ + fileheader->bfType = (uint16_t)al_fread16le(f); + fileheader->bfSize = (uint32_t)al_fread32le(f); + fileheader->bfReserved1 = (uint16_t)al_fread16le(f); + fileheader->bfReserved2 = (uint16_t)al_fread16le(f); + fileheader->bfOffBits = (uint32_t)al_fread32le(f); + + if (fileheader->bfType != 0x4D42) { + ALLEGRO_WARN("Not BMP format\n"); + return -1; + } + + if (al_feof(f) || al_ferror(f)) { + ALLEGRO_ERROR("Failed to read file header\n"); + return -1; + } + + return 0; +} + + + +/* read_win_bminfoheader: + * Reads information from a BMP file header. + */ +static int read_win_bminfoheader(ALLEGRO_FILE *f, BMPINFOHEADER *infoheader) +{ + WINBMPINFOHEADER win_infoheader; + + win_infoheader.biWidth = (uint32_t)al_fread32le(f); + win_infoheader.biHeight = al_fread32le(f); + win_infoheader.biPlanes = (uint16_t)al_fread16le(f); + win_infoheader.biBitCount = (uint16_t)al_fread16le(f); + win_infoheader.biCompression = (uint32_t)al_fread32le(f); + win_infoheader.biSizeImage = (uint32_t)al_fread32le(f); + win_infoheader.biXPelsPerMeter = (uint32_t)al_fread32le(f); + win_infoheader.biYPelsPerMeter = (uint32_t)al_fread32le(f); + win_infoheader.biClrUsed = (uint32_t)al_fread32le(f); + win_infoheader.biClrImportant = (uint32_t)al_fread32le(f); + + infoheader->biWidth = win_infoheader.biWidth; + infoheader->biHeight = win_infoheader.biHeight; + infoheader->biBitCount = win_infoheader.biBitCount; + infoheader->biCompression = win_infoheader.biCompression; + infoheader->biClrUsed = win_infoheader.biClrUsed; + + if (al_feof(f) || al_ferror(f)) { + ALLEGRO_ERROR("Failed to read file header\n"); + return -1; + } + + return 0; +} + + + +/* read_os2_bminfoheader: + * Reads information from an OS/2 format BMP file header. + */ +static int read_os2_bminfoheader(ALLEGRO_FILE *f, BMPINFOHEADER *infoheader) +{ + OS2BMPINFOHEADER os2_infoheader; + + os2_infoheader.biWidth = (uint16_t)al_fread16le(f); + os2_infoheader.biHeight = (uint16_t)al_fread16le(f); + os2_infoheader.biPlanes = (uint16_t)al_fread16le(f); + os2_infoheader.biBitCount = (uint16_t)al_fread16le(f); + + infoheader->biWidth = os2_infoheader.biWidth; + infoheader->biHeight = os2_infoheader.biHeight; + infoheader->biBitCount = os2_infoheader.biBitCount; + infoheader->biCompression = BIT_RGB; + infoheader->biClrUsed = 0; /* default */ + + if (al_feof(f) || al_ferror(f)) { + ALLEGRO_ERROR("Failed to read file header\n"); + return -1; + } + + return 0; +} + + + +/* decode_bitfield: + * Converts a bitfield in to a shift+mask pair + */ +static void decode_bitfield(uint32_t m, int *shift_out, uint32_t *mask_out) +{ + int shift = 0; + + if (m == 0) { + *shift_out = 0; + *mask_out = 0; + return; + } + +#ifdef __GNUC__ + shift = __builtin_ctz(m); + m >>= shift; +#else + while ((m & 1) == 0) { + m >>= 1; + ++shift; + } +#endif + + *shift_out = shift; + *mask_out = m; +} + + + +/* read_palette: + * Loads the color palette for 1,4,8 bit formats. + * OS/2 bitmaps take 3 bytes per color. + * Windows bitmaps take 4 bytes per color. + */ +static void read_palette(int ncolors, PalEntry *pal, ALLEGRO_FILE *f, + int flags, const BMPINFOHEADER *infoheader, int win_flag) +{ + int i; + unsigned char c[3]; + uint32_t r, g, b, a; + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + + int as; + uint32_t am; + + decode_bitfield(infoheader->biAlphaMask, &as, &am); + + for (i = 0; i < ncolors; i++) { + uint32_t pixel; + al_fread(f, c, 3); + r = c[2]; + g = c[1]; + b = c[0]; + + pixel = (r << 16) | (g << 8) | b; + + switch (am) { + case 0x00: + a = 255; + break; + + case 0x01: + a = ((pixel >> as) & am) * 255; + break; + + case 0xFF: + a = ((pixel >> as) & am); + break; + + default: + a = ((pixel >> as) & am) * 255 / am; + } + + if (am && premul) { + r = r * a / 255; + g = g * a / 255; + b = b * a / 255; + } + + pal[i].r = r; + pal[i].g = g; + pal[i].b = b; + pal[i].a = a; + + if (win_flag) { + al_fgetc(f); + } + } +} + + + +/* read_16le: + * Support function for reading 16-bit little endian values + * from a memory buffer. + */ +static uint16_t read_16le(void *buf) +{ + unsigned char *ucbuf = (unsigned char *)buf; + + return ucbuf[0] | (ucbuf[1] << 8); +} + + + +/* read_32le: + * Support function for reading 32-bit little endian values + * from a memory buffer. + */ +static uint32_t read_32le(void *buf) +{ + unsigned char *ucbuf = (unsigned char *)buf; + + return ucbuf[0] | (ucbuf[1] << 8) | (ucbuf[2] << 16) | (ucbuf[3] << 24); +} + + + +/* read_1bit_line: + * Support function for reading the 1 bit bitmap file format. + */ +static void read_1bit_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i, j; + unsigned char *ucbuf = (unsigned char *)buf; + size_t bytes_wanted = ((length + 7) / 8 + 3) & ~3; + + size_t bytes_read = al_fread(f, ucbuf, bytes_wanted); + memset(ucbuf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + (void)data; + + for (i = (length - 1) / 8; i >= 0; --i) { + unsigned char x = ucbuf[i]; + + for (j = 0; j < 8; ++j) + ucbuf[i*8 + 7 - j] = (x & (1 << j)) >> j; + } +} + + + +/* read_2bit_line: + * Support function for reading the 2 bit bitmap file format. + */ +static void read_2bit_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + unsigned char *ucbuf = (unsigned char *)buf; + size_t bytes_wanted = ((length + 3) / 4 + 3) & ~3; + + size_t bytes_read = al_fread(f, ucbuf, bytes_wanted); + memset(ucbuf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + (void)data; + + for (i = (length - 1) / 4; i >= 0; --i) { + unsigned char x = ucbuf[i]; + ucbuf[i*4] = (x & 0xC0) >> 6; + ucbuf[i*4+1] = (x & 0x30) >> 4; + ucbuf[i*4+2] = (x & 0x0C) >> 2; + ucbuf[i*4+3] = (x & 0x03); + } +} + + + +/* read_4bit_line: + * Support function for reading the 4 bit bitmap file format. + */ +static void read_4bit_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + unsigned char *ucbuf = (unsigned char *)buf; + size_t bytes_wanted = ((length + 1) / 2 + 3) & ~3; + + size_t bytes_read = al_fread(f, ucbuf, bytes_wanted); + memset(ucbuf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + (void)data; + + for (i = (length - 1) / 2; i >= 0; --i) { + unsigned char x = ucbuf[i]; + ucbuf[i*2] = (x & 0xF0) >> 4; + ucbuf[i*2+1] = (x & 0x0F); + } +} + + + +/* read_8bit_line: + * Support function for reading the 8 bit bitmap file format. + */ +static void read_8bit_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + size_t bytes_wanted = (length + 3) & ~3; + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + (void)data; +} + + + +/* read_16_rgb_555_line: + * Support function for reading the 16 bit / RGB555 bitmap file format. + */ +static void read_16_rgb_555_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + uint32_t *data32 = (uint32_t *)data; + size_t bytes_wanted = (length + (length & 1)) * 2; + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + + for (i = 0; i < length; ++i) { + uint16_t pixel = read_16le(buf + i*2); + data32[i] = ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888_LE(pixel); + } +} + + + +/* read_16_argb_1555_line: + * Support function for reading the 16 bit / ARGB1555 bitmap file format. + */ +static void read_16_argb_1555_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + uint32_t *data32 = (uint32_t *)data; + size_t bytes_wanted = (length + (length & 1)) * 2; + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + for (i = 0; i < length; ++i) { + uint16_t pixel = read_16le(buf + i*2); + data32[i] = ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888_LE(pixel); + + if (premul && (pixel & 0x8000)) + data32[i] = 0; + } +} + + + +/* read_16_rgb_565_line: + * Support function for reading the 16 bit / RGB565 bitmap file format. + */ +static void read_16_rgb_565_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + uint32_t *data32 = (uint32_t *)data; + size_t bytes_wanted = (length + (length & 1)) * 2; + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + + for (i = 0; i < length; i++) { + uint16_t pixel = read_16le(buf + i*2); + data32[i] = ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888_LE(pixel); + } +} + + + +/* read_24_rgb_888_line: + * Support function for reading the 24 bit / RGB888 bitmap file format. + */ +static void read_24_rgb_888_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int bi, i; + unsigned char *ucbuf = (unsigned char *)buf; + uint32_t *data32 = (uint32_t *)data; + size_t bytes_wanted = length * 3 + (length & 3); + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + + for (i = 0, bi = 0; i < (length & ~3); i += 4, bi += 3) { + uint32_t a = read_32le(buf + bi*4); // BGRB [LE:BRGB] + uint32_t b = read_32le(buf + bi*4 + 4); // GRBG [LE:GBRG] + uint32_t c = read_32le(buf + bi*4 + 8); // RBGR [LE:RGBR] + + uint32_t w = a; + uint32_t x = (a >> 24) | (b << 8); + uint32_t y = (b >> 16) | (c << 16); + uint32_t z = (c >> 8); + + data32[i] = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(w); + data32[i+1] = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(x); + data32[i+2] = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(y); + data32[i+3] = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(z); + } + + bi *= 4; + + for (; i < length; i++, bi += 3) { + uint32_t pixel = ucbuf[bi] | (ucbuf[bi+1] << 8) | (ucbuf[bi+2] << 16); + data32[i] = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(pixel); + } +} + + + +/* read_32_xrgb_8888_line: + * Support function for reading the 32 bit / XRGB8888 bitmap file format. + */ +static void read_32_xrgb_8888_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + uint32_t *data32 = (uint32_t *)data; + size_t bytes_wanted = length * 4; + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + + for (i = 0; i < length; i++) { + uint32_t pixel = read_32le(buf + i*4); + data32[i] = ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888_LE(pixel); + } +} + + + +/* read_32_rgbx_8888_line: + * Support function for reading the 32 bit / RGBX8888 bitmap file format. + */ +static void read_32_rgbx_8888_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + uint32_t *data32 = (uint32_t *)data; + size_t bytes_wanted = length * 4; + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + (void)premul; + + for (i = 0; i < length; i++) { + uint32_t pixel = read_32le(buf + i*4); + data32[i] = ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888_LE(pixel); + } +} + + + +/* read_32_argb_8888_line: + * Support function for reading the 32 bit / ARGB8888 bitmap file format. + */ +static void read_32_argb_8888_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + uint32_t *data32 = (uint32_t *)data; + size_t bytes_wanted = length * 4; + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + for (i = 0; i < length; i++) { + uint32_t pixel = read_32le(buf + i*4); + uint32_t a = (pixel & 0xFF000000U) >> 24; + data32[i] = ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888_LE(pixel); + + if (premul && a != 255) { + data[i*4+1] = data[i*4+1] * a / 255; + data[i*4+2] = data[i*4+2] * a / 255; + data[i*4+3] = data[i*4+3] * a / 255; + } + } +} + + + +/* read_32_rgba_8888_line: + * Support function for reading the 32 bit / RGBA8888 bitmap file format. + */ +static void read_32_rgba_8888_line(ALLEGRO_FILE *f, char *buf, char *data, + int length, bool premul) +{ + int i; + uint32_t *data32 = (uint32_t *)data; + size_t bytes_wanted = length * 4; + + size_t bytes_read = al_fread(f, buf, bytes_wanted); + memset(buf + bytes_read, 0, bytes_wanted - bytes_read); + + for (i = 0; i < length; i++) { + uint32_t pixel = read_32le(buf + i*4); + uint32_t a = (pixel & 0x000000FFU); + data32[i] = ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888_LE(pixel); + + if (premul && a != 255) { + data[i*4] = data[i*4] * a / 255; + data[i*4+1] = data[i*4+1] * a / 255; + data[i*4+2] = data[i*4+2] * a / 255; + } + } +} + + + +/* read_RGB_image: + * For reading the standard BMP image format + */ +static bool read_RGB_image(ALLEGRO_FILE *f, int flags, + const BMPINFOHEADER *infoheader, ALLEGRO_LOCKED_REGION *lr, + bmp_line_fn fn) +{ + int i, line, height, width, dir; + size_t linesize; + char *linebuf; + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + + height = infoheader->biHeight; + width = infoheader->biWidth; + + // Includes enough space to read the padding for a line + linesize = (infoheader->biWidth + 3) & ~3; + + if (infoheader->biBitCount < 8) + linesize *= (8 / infoheader->biBitCount); + else + linesize *= (infoheader->biBitCount / 8); + + linebuf = al_malloc(linesize); + + if (!linebuf) { + ALLEGRO_WARN("Failed to allocate pixel row buffer\n"); + return false; + } + + line = height < 0 ? 0 : height - 1; + dir = height < 0 ? 1 : -1; + height = abs(height); + + for (i = 0; i < height; i++, line += dir) { + char *data = (char *)lr->data + lr->pitch * line; + fn(f, linebuf, data, width, premul); + } + + al_free(linebuf); + + return true; +} + +/* read_RGB_image_indices: + * For reading the palette indices from BMP image format + */ +static bool read_RGB_image_indices(ALLEGRO_FILE *f, int flags, + const BMPINFOHEADER *infoheader, ALLEGRO_LOCKED_REGION *lr, + bmp_line_fn fn) +{ + int i, line, height, width, dir; + size_t linesize; + char *linebuf; + + (void)flags; + + height = infoheader->biHeight; + width = infoheader->biWidth; + + // Includes enough space to read the padding for a line + linesize = (width + 3) & ~3; + + // Indices are always 8-bit, so no need to adjust linesize + + linebuf = al_malloc(linesize); + + if (!linebuf) { + ALLEGRO_WARN("Failed to allocate pixel row buffer\n"); + return false; + } + + if (height < 0) { + dir = 1; + line = 0; + height = -height; + } else { + dir = -1; + line = height - 1; + } + + for (i = 0; i < height; i++, line += dir) { + char *data = (char *)lr->data + lr->pitch * line; + fn(f, linebuf, data, width, false); + memcpy(data, linebuf, width); + } + + al_free(linebuf); + + return true; +} + +/* read_RGB_paletted_image: + * For reading the standard palette mapped BMP image format + */ +static bool read_RGB_paletted_image(ALLEGRO_FILE *f, int flags, + const BMPINFOHEADER *infoheader, PalEntry* pal, + ALLEGRO_LOCKED_REGION *lr, bmp_line_fn fn) +{ + int i, j, line, height, width, dir; + size_t linesize; + char *linebuf; + + (void)flags; + + height = infoheader->biHeight; + width = infoheader->biWidth; + + // Includes enough space to read the padding for a line + linesize = (width + 3) & ~3; + + if (infoheader->biBitCount < 8) + linesize *= (8 / infoheader->biBitCount); + else + linesize *= (infoheader->biBitCount / 8); + + linebuf = al_malloc(linesize); + + if (!linebuf) { + ALLEGRO_WARN("Failed to allocate pixel row buffer\n"); + return false; + } + + line = height < 0 ? 0 : height - 1; + dir = height < 0 ? 1 : -1; + height = abs(height); + + for (i = 0; i < height; i++, line += dir) { + char *data = (char *)lr->data + lr->pitch * line; + fn(f, linebuf, data, width, false); + + for (j = 0; j < width; ++j) { + unsigned char idx = linebuf[j]; + data[j*4] = pal[idx].r; + data[j*4+1] = pal[idx].g; + data[j*4+2] = pal[idx].b; + data[j*4+3] = pal[idx].a; + } + } + + al_free(linebuf); + + return true; +} + + + +/* generate_scale_table: + * Helper function to generate color tables for bitfield format bitmaps. + */ +static void generate_scale_table(int* table, int entries) +{ + int i; + + for (i = 0; i < entries; ++i) + table[i] = i * 255 / (entries - 1); +} + + + +/* read_bitfields_image: + * For reading the generic bitfield compressed BMP image format + */ +static bool read_bitfields_image(ALLEGRO_FILE *f, int flags, + const BMPINFOHEADER *infoheader, ALLEGRO_LOCKED_REGION *lr) +{ + int i, k, line, height, width, dir; + size_t linesize, bytes_read; + unsigned char *linebuf; + int bytes_per_pixel = infoheader->biBitCount / 8; + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + + int rs, gs, bs, as; + uint32_t rm, gm, bm, am; + + // Temporary colour conversion tables for 1..10 bit channels + // Worst case: ~7KB is temporarily allocated + int *tempconvert[10]; + int *rtable = NULL; + int *gtable = NULL; + int *btable = NULL; + int *atable = NULL; + + height = infoheader->biHeight; + width = infoheader->biWidth; + + // Includes enough space to read the padding for a line + linesize = width * bytes_per_pixel + ((width * bytes_per_pixel) & 3); + + linebuf = al_malloc(linesize); + + if (!linebuf) { + ALLEGRO_WARN("Failed to allocate pixel row buffer\n"); + return false; + } + + decode_bitfield(infoheader->biRedMask, &rs, &rm); + decode_bitfield(infoheader->biGreenMask, &gs, &gm); + decode_bitfield(infoheader->biBlueMask, &bs, &bm); + decode_bitfield(infoheader->biAlphaMask, &as, &am); + + for (i = 0; i < (int)(sizeof(tempconvert) / sizeof(int *)); ++i) { + uint32_t mask = ~(0xFFFFFFFFU << (i+1)) & 0xFFFFFFFFU; + + switch (i) { + case 0: tempconvert[i] = _al_rgb_scale_1; break; + case 3: tempconvert[i] = _al_rgb_scale_4; break; + case 4: tempconvert[i] = _al_rgb_scale_5; break; + case 5: tempconvert[i] = _al_rgb_scale_6; break; + default: + if (rm == mask || gm == mask || bm == mask || am == mask) { + int entries = (1 << (i+1)); + + // Skip generating tables for tiny images + if (width * height > entries * 2) { + tempconvert[i] = al_malloc(sizeof(int) * entries); + generate_scale_table(tempconvert[i], entries); + } + else { + tempconvert[i] = NULL; + } + } + else { + tempconvert[i] = NULL; + } + } + + if (rm == mask) rtable = tempconvert[i]; + if (gm == mask) gtable = tempconvert[i]; + if (bm == mask) btable = tempconvert[i]; + if (am == mask) atable = tempconvert[i]; + } + + line = height < 0 ? 0 : height - 1; + dir = height < 0 ? 1 : -1; + height = abs(height); + + for (i = 0; i < height; i++, line += dir) { + unsigned char *data = (unsigned char *)lr->data + lr->pitch * line; + + bytes_read = al_fread(f, linebuf, linesize); + memset(linebuf + bytes_read, 0, linesize - bytes_read); + + for (k = 0; k < width; k++) { + uint32_t pixel = read_32le(linebuf + k*bytes_per_pixel); + uint32_t r, g, b, a = 255; + + r = ((pixel >> rs) & rm); + g = ((pixel >> gs) & gm); + b = ((pixel >> bs) & bm); + + if (rtable) r = rtable[r]; + else if (rm > 0) r = r * 255 / rm; + + if (gtable) g = gtable[g]; + else if (gm > 0) g = g * 255 / gm; + + if (btable) b = btable[b]; + else if (bm > 0) b = b * 255 / bm; + + if (am) { + a = ((pixel >> as) & am); + + if (atable) a = atable[a]; + else a = a * 255 / am; + + if (premul) { + r = r * a / 255; + g = g * a / 255; + b = b * a / 255; + } + } + + data[0] = r; + data[1] = g; + data[2] = b; + data[3] = a; + + data += 4; + } + } + + al_free(linebuf); + + for (i = 0; i < (int)(sizeof(tempconvert) / sizeof(int *)); ++i) { + if (i != 0 && i != 3 && i != 4 && i != 5) + al_free(tempconvert[i]); + } + + return true; +} + + + +/* read_RGB_image_32bit_alpha_hack: + * For reading the non-compressed BMP image format (32-bit). + * These are treatly specially because some programs put alpha information in + * the fourth byte of each pixel, which is normally just padding (and zero). + * We use a heuristic: if every pixel has zero in that fourth byte then assume + * the whole image is opaque (a=255). Otherwise treat the fourth byte as an + * alpha channel. + * + * Note that V3 headers include an alpha bit mask, which can properly indicate + * the presence or absence of an alpha channel. + * This hack is not required then. + */ +static bool read_RGB_image_32bit_alpha_hack(ALLEGRO_FILE *f, int flags, + const BMPINFOHEADER *infoheader, ALLEGRO_LOCKED_REGION *lr) +{ + int i, j, line, startline, height, width, dir; + int have_alpha = 0; + size_t linesize; + char *linebuf; + const bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + + height = infoheader->biHeight; + width = infoheader->biWidth; + + // Includes enough space to read the padding for a line + linesize = (infoheader->biWidth + 3) & ~3; + + if (infoheader->biBitCount < 8) + linesize *= (8 / infoheader->biBitCount); + else + linesize *= (infoheader->biBitCount / 8); + + linebuf = al_malloc(linesize); + + if (!linebuf) { + ALLEGRO_WARN("Failed to allocate pixel row buffer\n"); + return false; + } + + line = startline = height < 0 ? 0 : height - 1; + dir = height < 0 ? 1 : -1; + height = abs(height); + + for (i = 0; i < height; i++, line += dir) { + unsigned char *data = (unsigned char *)lr->data + lr->pitch * line; + + /* Don't premultiply alpha here or the image will come out all black */ + read_32_argb_8888_line(f, linebuf, (char *)data, width, false); + + /* Check the alpha values of every pixel in the row */ + for (j = 0; j < width; j++) { + have_alpha |= ((data[j*4+3] & 0xFF) != 0); + } + } + + /* Fixup pass - make imague opaque or premultiply alpha */ + if (!have_alpha) { + line = startline; + + for (i = 0; i < height; i++, line += dir) { + unsigned char *data = (unsigned char *)lr->data + lr->pitch * line; + + for (j = 0; j < width; j++) { + data[j*4+3] = 255; + } + } + } + else if (premul) { + line = startline; + + for (i = 0; i < height; i++, line += dir) { + unsigned char *data = (unsigned char *)lr->data + lr->pitch * line; + + for (j = 0; j < width; j++) { + data[j*4] = data[j*4] * data[j*4+3] / 255; + data[j*4+1] = data[j*4+1] * data[j*4+3] / 255; + data[j*4+2] = data[j*4+2] * data[j*4+3] / 255; + } + } + } + + al_free(linebuf); + + return true; +} + +/* read_RLE8_compressed_image: + * For reading the 8 bit RLE compressed BMP image format. + */ +static void read_RLE8_compressed_image(ALLEGRO_FILE *f, unsigned char *buf, + const BMPINFOHEADER *infoheader) +{ + int count; + unsigned char val; + unsigned char val0; + int j, pos, line, height, dir; + int eolflag, eopicflag; + + eopicflag = 0; + height = abs((int)infoheader->biHeight); + line = (infoheader->biHeight < 0) ? 0 : height - 1; + dir = (infoheader->biHeight < 0) ? 1 : -1; + + while (eopicflag == 0) { + pos = 0; /* x position in bitmap */ + eolflag = 0; /* end of line flag */ + + while ((eolflag == 0) && (eopicflag == 0)) { + count = al_fgetc(f); + if (count == EOF) + return; + if (pos + count > (int)infoheader->biWidth) { + ALLEGRO_WARN("overlong compressed line\n"); + count = infoheader->biWidth - pos; + } + + val = al_fgetc(f); + + if (count > 0) { /* repeat pixel count times */ + for (j = 0; j < count; j++) { + buf[line * infoheader->biWidth + pos] = val; + pos++; + } + } + else { + switch (val) { + + case 0: /* end of line flag */ + eolflag = 1; + break; + + case 1: /* end of picture flag */ + eopicflag = 1; + break; + + case 2: /* displace picture */ + count = al_fgetc(f); + if (count == EOF) + return; + val = al_fgetc(f); + pos += count; + line += dir * val; + break; + + default: /* read in absolute mode */ + for (j=0; j<val; j++) { + val0 = al_fgetc(f); + buf[line * infoheader->biWidth + pos] = val0; + pos++; + } + + if (j % 2 == 1) + val0 = al_fgetc(f); /* align on word boundary */ + + break; + } + } + + if (pos - 1 > (int)infoheader->biWidth) + eolflag = 1; + } + + line += dir; + if (line < 0 || line >= height) + eopicflag = 1; + } +} + + + +/* read_RLE4_compressed_image: + * For reading the 4 bit RLE compressed BMP image format. + */ +static void read_RLE4_compressed_image(ALLEGRO_FILE *f, unsigned char *buf, + const BMPINFOHEADER *infoheader) +{ + unsigned char b[8]; + int count; + unsigned short val0, val; + int j, k, pos, line, height, dir; + int eolflag, eopicflag; + + eopicflag = 0; /* end of picture flag */ + height = abs((int)infoheader->biHeight); + line = (infoheader->biHeight < 0) ? 0 : height - 1; + dir = (infoheader->biHeight < 0) ? 1 : -1; + + while (eopicflag == 0) { + pos = 0; + eolflag = 0; /* end of line flag */ + + while ((eolflag == 0) && (eopicflag == 0)) { + count = al_fgetc(f); + if (count == EOF) + return; + if (pos + count > (int)infoheader->biWidth) { + ALLEGRO_WARN("overlong compressed line\n"); + count = infoheader->biWidth - pos; + } + + val = al_fgetc(f); + + if (count > 0) { /* repeat pixels count times */ + b[1] = val & 15; + b[0] = (val >> 4) & 15; + for (j = 0; j < count; j++) { + buf[line * infoheader->biWidth + pos] = b[j % 2]; + pos++; + } + } + else { + switch (val) { + + case 0: /* end of line */ + eolflag = 1; + break; + + case 1: /* end of picture */ + eopicflag = 1; + break; + + case 2: /* displace image */ + count = al_fgetc(f); + if (count == EOF) + return; + val = al_fgetc(f); + pos += count; + line += dir * val; + break; + + default: /* read in absolute mode */ + for (j = 0; j < val; j++) { + if ((j % 4) == 0) { + val0 = (uint16_t)al_fread16le(f); + for (k = 0; k < 2; k++) { + b[2 * k + 1] = val0 & 15; + val0 = val0 >> 4; + b[2 * k] = val0 & 15; + val0 = val0 >> 4; + } + } + buf[line * infoheader->biWidth + pos] = b[j % 4]; + pos++; + } + break; + } + } + + if (pos - 1 > (int)infoheader->biWidth) + eolflag = 1; + } + + line += dir; + if (line < 0 || line >= height) + eopicflag = 1; + } +} + + + +/* Like load_bmp, but starts loading from the current place in the ALLEGRO_FILE + * specified. If successful the offset into the file will be left just after + * the image data. If unsuccessful the offset into the file is unspecified, + * i.e. you must either reset the offset to some known place or close the + * packfile. The packfile is not closed by this function. + */ +ALLEGRO_BITMAP *_al_load_bmp_f(ALLEGRO_FILE *f, int flags) +{ + BMPFILEHEADER fileheader; + BMPINFOHEADER infoheader; + ALLEGRO_BITMAP *bmp; + PalEntry pal[256]; + int64_t file_start; + int64_t header_start; + unsigned long biSize; + unsigned char *buf = NULL; + ALLEGRO_LOCKED_REGION *lr; + bool keep_index = INT_TO_BOOL(flags & ALLEGRO_KEEP_INDEX); + + ASSERT(f); + + file_start = al_ftell(f); + + if (read_bmfileheader(f, &fileheader) != 0) { + return NULL; + } + + header_start = al_ftell(f); + + biSize = (uint32_t)al_fread32le(f); + if (al_feof(f) || al_ferror(f)) { + ALLEGRO_ERROR("EOF or file error while reading bitmap header.\n"); + return NULL; + } + + switch (biSize) { + case WININFOHEADERSIZE: + case WININFOHEADERSIZEV2: + case WININFOHEADERSIZEV3: + case WININFOHEADERSIZEV4: + case WININFOHEADERSIZEV5: + if (read_win_bminfoheader(f, &infoheader) != 0) { + return NULL; + } + break; + + case OS2INFOHEADERSIZE: + if (read_os2_bminfoheader(f, &infoheader) != 0) { + return NULL; + } + ASSERT(infoheader.biCompression == BIT_RGB); + break; + + default: + ALLEGRO_WARN("Unsupported header size: %ld\n", biSize); + return NULL; + } + + /* End of header for OS/2 and BITMAPV2INFOHEADER (V1). */ + if (biSize == OS2INFOHEADERSIZE || biSize == WININFOHEADERSIZE) { + ASSERT(al_ftell(f) == header_start + (int64_t) biSize); + } + + if ((int)infoheader.biWidth < 0) { + ALLEGRO_WARN("negative width: %ld\n", infoheader.biWidth); + return NULL; + } + + if (infoheader.biBitCount != 1 && infoheader.biBitCount != 2 && infoheader.biBitCount != 4 && + infoheader.biBitCount != 8 && infoheader.biBitCount != 16 && infoheader.biBitCount != 24 && + infoheader.biBitCount != 32) { + ALLEGRO_WARN("unsupported bit depth: %d\n", infoheader.biBitCount); + return NULL; + } + + if (infoheader.biCompression == BIT_RLE4 && infoheader.biBitCount != 4) { + ALLEGRO_WARN("unsupported bit depth for RLE4 compression: %d\n", infoheader.biBitCount); + return NULL; + } + + if (infoheader.biCompression == BIT_RLE8 && infoheader.biBitCount != 8) { + ALLEGRO_WARN("unsupported bit depth for RLE8 compression: %d\n", infoheader.biBitCount); + return NULL; + } + + if (infoheader.biCompression == BIT_BITFIELDS && + infoheader.biBitCount != 16 && infoheader.biBitCount != 24 && infoheader.biBitCount != 32) { + ALLEGRO_WARN("unsupported bit depth for bitfields compression: %d\n", infoheader.biBitCount); + return NULL; + } + + /* In BITMAPINFOHEADER (V1) the RGB bit masks are not part of the header. + * In BITMAPV2INFOHEADER they form part of the header, but only valid when + * for BITFIELDS images. + */ + if (infoheader.biCompression == BIT_BITFIELDS + || biSize >= WININFOHEADERSIZEV2) { + infoheader.biRedMask = (uint32_t)al_fread32le(f); + infoheader.biGreenMask = (uint32_t)al_fread32le(f); + infoheader.biBlueMask = (uint32_t)al_fread32le(f); + } + + /* BITMAPV3INFOHEADER and above include an Alpha bit mask. */ + if (biSize < WININFOHEADERSIZEV3) { + infoheader.biHaveAlphaMask = false; + infoheader.biAlphaMask = 0x0; + } + else { + uint32_t pixel_mask = 0xFFFFFFFFU; + infoheader.biHaveAlphaMask = true; + infoheader.biAlphaMask = (uint32_t)al_fread32le(f); + + if (infoheader.biBitCount < 32) + pixel_mask = ~(pixel_mask << infoheader.biBitCount) & 0xFFFFFFFFU; + + if ((infoheader.biAlphaMask & pixel_mask) == 0) { + infoheader.biAlphaMask = 0; + ALLEGRO_WARN("Ignoring invalid alpha mask\n"); + } + } + + /* Seek past the end of the header to reach the palette / image data */ + if (biSize > WININFOHEADERSIZEV3) { + if (!al_fseek(f, file_start + 14 + biSize, ALLEGRO_SEEK_SET)) { + ALLEGRO_ERROR("Seek error\n"); + return NULL; + } + } + + if (infoheader.biBitCount <= 8) { + int i; + for (i = 0; i < 256; ++i) { + pal[i].r = 0; + pal[i].g = 0; + pal[i].b = 0; + pal[i].a = 255; + } + } + + /* Read the palette, if any. Higher bit depth images _may_ have an optional + * palette but we don't use it. + */ + if (infoheader.biCompression != BIT_BITFIELDS + && infoheader.biBitCount <= 8) { + int win_flag = (biSize != OS2INFOHEADERSIZE); + int ncolors = infoheader.biClrUsed; + int extracolors = 0; + int bytes_per_color = win_flag ? 4 : 3; + + if (win_flag) { + if (ncolors == 0) { + ncolors = (1 << infoheader.biBitCount); + } + } + else { + /* detect palette size for OS2v1 format BMP files */ + if (ncolors == 0) { + ncolors = (fileheader.bfOffBits - 14 - OS2INFOHEADERSIZE) / 3; + } + + if (ncolors == 0) { + ALLEGRO_WARN("No palette in OS2v1 BMP file!\n"); + } + } + + if (ncolors > 256) { + ALLEGRO_WARN("Too many colors: %d\n", ncolors); + ncolors = 256; + extracolors = ncolors - 256; + } + + read_palette(ncolors, pal, f, flags, &infoheader, win_flag); + if (al_feof(f) || al_ferror(f)) { + ALLEGRO_ERROR("EOF or I/O error\n"); + return NULL; + } + + if (!al_fseek(f, extracolors * bytes_per_color, ALLEGRO_SEEK_SET)) { + ALLEGRO_ERROR("Seek error\n"); + return NULL; + } + } + else if (infoheader.biClrUsed && infoheader.biBitCount > 8) { + int win_flag = (biSize != OS2INFOHEADERSIZE); + int bytes_per_color = win_flag ? 4 : 3; + + if (!al_fseek(f, infoheader.biClrUsed * bytes_per_color, ALLEGRO_SEEK_CUR)) { + ALLEGRO_ERROR("Seek error\n"); + return NULL; + } + } + + /* Skip to the pixel data only if it's outside of the image metadata */ + if (file_start + (int64_t)fileheader.bfOffBits > al_ftell(f)) { + if (!al_fseek(f, file_start + fileheader.bfOffBits, ALLEGRO_SEEK_SET)) { + ALLEGRO_ERROR("Seek error\n"); + return NULL; + } + } + + bmp = al_create_bitmap(infoheader.biWidth, abs((int)infoheader.biHeight)); + if (!bmp) { + ALLEGRO_ERROR("Failed to create bitmap\n"); + return NULL; + } + + if (infoheader.biBitCount <= 8 && keep_index) { + lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, + ALLEGRO_LOCK_WRITEONLY); + } + else { + lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ALLEGRO_LOCK_WRITEONLY); + } + + if (!lr) { + ALLEGRO_ERROR("Failed to lock region\n"); + al_destroy_bitmap(bmp); + return NULL; + } + + if (infoheader.biCompression == BIT_RLE8 + || infoheader.biCompression == BIT_RLE4) { + /* Questionable but most loaders handle this, so we should. */ + if (infoheader.biHeight < 0) { + ALLEGRO_WARN("compressed bitmap with negative height\n"); + } + + /* RLE decoding may skip pixels so clear the buffer first. */ + buf = al_calloc(infoheader.biWidth, abs((int)infoheader.biHeight)); + } + + switch (infoheader.biCompression) { + case BIT_RGB: + if (infoheader.biBitCount == 32 && !infoheader.biHaveAlphaMask) { + if (!read_RGB_image_32bit_alpha_hack(f, flags, &infoheader, lr)) + return NULL; + } + else { + bmp_line_fn fn = NULL; + + switch (infoheader.biBitCount) { + case 1: fn = read_1bit_line; break; + case 2: fn = read_2bit_line; break; + case 4: fn = read_4bit_line; break; + case 8: fn = read_8bit_line; break; + case 16: fn = read_16_rgb_555_line; break; + case 24: fn = read_24_rgb_888_line; break; + case 32: fn = read_32_xrgb_8888_line; break; + default: + ALLEGRO_ERROR("No decoding function for bit depth %d\n", infoheader.biBitCount); + return NULL; + } + + if (infoheader.biBitCount == 16 && infoheader.biAlphaMask == 0x00008000U) + fn = read_16_argb_1555_line; + else if (infoheader.biBitCount == 32 && infoheader.biAlphaMask == 0xFF000000U) + fn = read_32_argb_8888_line; + if (keep_index) { + if (!read_RGB_image_indices(f, flags, &infoheader, lr, fn)) + return NULL; + } + else if (infoheader.biBitCount <= 8) { + if (!read_RGB_paletted_image(f, flags, &infoheader, pal, lr, fn)) + return NULL; + } + else { + if (!read_RGB_image(f, flags, &infoheader, lr, fn)) + return NULL; + } + } + break; + + case BIT_RLE8: + read_RLE8_compressed_image(f, buf, &infoheader); + break; + + case BIT_RLE4: + read_RLE4_compressed_image(f, buf, &infoheader); + break; + + case BIT_BITFIELDS: + if (infoheader.biBitCount == 16) { + if (infoheader.biRedMask == 0x00007C00U && infoheader.biGreenMask == 0x000003E0U && + infoheader.biBlueMask == 0x0000001FU && infoheader.biAlphaMask == 0x00000000U) { + if (!read_RGB_image(f, flags, &infoheader, lr, read_16_rgb_555_line)) + return NULL; + } + else if (infoheader.biRedMask == 0x00007C00U && infoheader.biGreenMask == 0x000003E0U && + infoheader.biBlueMask == 0x0000001FU && infoheader.biAlphaMask == 0x00008000U) { + if (!read_RGB_image(f, flags, &infoheader, lr, read_16_argb_1555_line)) + return NULL; + } + else if (infoheader.biRedMask == 0x0000F800U && infoheader.biGreenMask == 0x000007E0U && + infoheader.biBlueMask == 0x0000001FU && infoheader.biAlphaMask == 0x00000000U) { + if (!read_RGB_image(f, flags, &infoheader, lr, read_16_rgb_565_line)) + return NULL; + } + else { + if (!read_bitfields_image(f, flags, &infoheader, lr)) + return NULL; + } + } + else if (infoheader.biBitCount == 24) { + if (infoheader.biRedMask == 0x00FF0000U && infoheader.biGreenMask == 0x0000FF00U && + infoheader.biBlueMask == 0x000000FFU && infoheader.biAlphaMask == 0x00000000U) { + if (!read_RGB_image(f, flags, &infoheader, lr, read_24_rgb_888_line)) + return NULL; + } + else { + if (!read_bitfields_image(f, flags, &infoheader, lr)) + return NULL; + } + } + else if (infoheader.biBitCount == 32) { + if (infoheader.biRedMask == 0x00FF0000U && infoheader.biGreenMask == 0x0000FF00U && + infoheader.biBlueMask == 0x000000FFU && infoheader.biAlphaMask == 0x00000000U) { + if (!read_RGB_image(f, flags, &infoheader, lr, read_32_xrgb_8888_line)) + return NULL; + } + else if (infoheader.biRedMask == 0x00FF0000U && infoheader.biGreenMask == 0x0000FF00U && + infoheader.biBlueMask == 0x000000FFU && infoheader.biAlphaMask == 0xFF000000U) { + if (!read_RGB_image(f, flags, &infoheader, lr, read_32_argb_8888_line)) + return NULL; + } + else if (infoheader.biRedMask == 0xFF000000U && infoheader.biGreenMask == 0x00FF0000U && + infoheader.biBlueMask == 0x0000FF00U && infoheader.biAlphaMask == 0x00000000U) { + if (!read_RGB_image(f, flags, &infoheader, lr, read_32_rgbx_8888_line)) + return NULL; + } + else if (infoheader.biRedMask == 0xFF000000U && infoheader.biGreenMask == 0x00FF0000U && + infoheader.biBlueMask == 0x0000FF00U && infoheader.biAlphaMask == 0x000000FFU) { + if (!read_RGB_image(f, flags, &infoheader, lr, read_32_rgba_8888_line)) + return NULL; + } + else { + if (!read_bitfields_image(f, flags, &infoheader, lr)) + return NULL; + } + } + break; + + default: + ALLEGRO_WARN("Unknown compression: %ld\n", infoheader.biCompression); + al_unlock_bitmap(bmp); + al_destroy_bitmap(bmp); + bmp = NULL; + break; + } + + if (infoheader.biCompression == BIT_RLE8 + || infoheader.biCompression == BIT_RLE4) { + int x, y; + unsigned char *data; + + for (y = 0; y < abs((int)infoheader.biHeight); y++) { + data = (unsigned char *)lr->data + lr->pitch * y; + for (x = 0; x < (int)infoheader.biWidth; x++) { + if (keep_index) { + data[0] = buf[y * infoheader.biWidth + x]; + data++; + } + else { + data[0] = pal[buf[y * infoheader.biWidth + x]].r; + data[1] = pal[buf[y * infoheader.biWidth + x]].g; + data[2] = pal[buf[y * infoheader.biWidth + x]].b; + data[3] = 255; + data += 4; + } + } + } + al_free(buf); + } + + if (bmp) { + al_unlock_bitmap(bmp); + } + + return bmp; +} + + + +/* Like save_bmp but writes into the ALLEGRO_FILE given instead of a new file. + * The packfile is not closed after writing is completed. On success the + * offset into the file is left after the TGA file just written. On failure + * the offset is left at the end of whatever incomplete data was written. + */ +bool _al_save_bmp_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + int bfSize; + int biSizeImage; + int bpp; + int filler; + int i, j; + int w, h; + ALLEGRO_LOCKED_REGION *lr; + ASSERT(f); + ASSERT(bmp); + + w = al_get_bitmap_width(bmp); + h = al_get_bitmap_height(bmp); + + bpp = 24; + filler = 3 - ((w * (bpp / 8) - 1) & 3); + biSizeImage = (w * 3 + filler) * h; + bfSize = 14 + WININFOHEADERSIZE + biSizeImage; + + al_set_errno(0); + + /* file_header */ + al_fwrite16le(f, 0x4D42); /* bfType ("BM") */ + al_fwrite32le(f, bfSize); /* bfSize */ + al_fwrite16le(f, 0); /* bfReserved1 */ + al_fwrite16le(f, 0); /* bfReserved2 */ + al_fwrite32le(f, 14 + WININFOHEADERSIZE); /* bfOffBits */ + + /* info_header */ + al_fwrite32le(f, WININFOHEADERSIZE); /* biSize */ + al_fwrite32le(f, w); /* biWidth */ + al_fwrite32le(f, h); /* biHeight */ + al_fwrite16le(f, 1); /* biPlanes */ + al_fwrite16le(f, bpp); /* biBitCount */ + al_fwrite32le(f, BIT_RGB); /* biCompression */ + al_fwrite32le(f, biSizeImage); /* biSizeImage */ + al_fwrite32le(f, 0xB12); /* biXPelsPerMeter (0xB12 = 72 dpi) */ + al_fwrite32le(f, 0xB12); /* biYPelsPerMeter */ + + al_fwrite32le(f, 0); /* biClrUsed */ + al_fwrite32le(f, 0); /* biClrImportant */ + + /* Don't really need the alpha channel, just the _LE. + * Note that there exist 32-bit BMPs now so we could try to save those. + */ + lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ALLEGRO_LOCK_READONLY); + + /* image data */ + for (i = h - 1; i >= 0; i--) { + unsigned char *data = (unsigned char *)lr->data + i * lr->pitch; + + for (j = 0; j < w; j++) { + unsigned char r = data[0]; + unsigned char g = data[1]; + unsigned char b = data[2]; + data += 4; + + al_fputc(f, b); + al_fputc(f, g); + al_fputc(f, r); + } + + for (j = 0; j < filler; j++) + al_fputc(f, 0); + } + + al_unlock_bitmap(bmp); + + return al_get_errno() ? false : true; +} + + + +ALLEGRO_BITMAP *_al_load_bmp(const char *filename, int flags) +{ + ALLEGRO_FILE *f; + ALLEGRO_BITMAP *bmp; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_load_bmp_f(f, flags); + + al_fclose(f); + + return bmp; +} + + +bool _al_save_bmp(const char *filename, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_FILE *f; + bool retsave; + bool retclose; + ASSERT(filename); + + f = al_fopen(filename, "wb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for writing.\n", filename); + return false; + } + + retsave = _al_save_bmp_f(f, bmp); + retclose = al_fclose(f); + + return retsave && retclose; +} + + +bool _al_identify_bmp(ALLEGRO_FILE *f) +{ + uint16_t x; + uint16_t y; + + y = al_fread16le(f); + + if (y != 0x4D42) + return false; + + if (!al_fseek(f, 14 - 2, ALLEGRO_SEEK_CUR)) + return false; + + x = al_fread16le(f); + switch (x) { + case WININFOHEADERSIZE: + case WININFOHEADERSIZEV2: + case WININFOHEADERSIZEV3: + case WININFOHEADERSIZEV4: + case WININFOHEADERSIZEV5: + case OS2INFOHEADERSIZE: + return true; + } + return false; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/image/dds.c b/allegro/addons/image/dds.c new file mode 100644 index 00000000..134277a7 --- /dev/null +++ b/allegro/addons/image/dds.c @@ -0,0 +1,198 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * A simple DDS reader. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +ALLEGRO_DEBUG_CHANNEL("image") + +typedef int DWORD; + +typedef struct { + DWORD dwSize; + DWORD dwFlags; + DWORD dwFourCC; + DWORD dwRGBBitCount; + DWORD dwRBitMask; + DWORD dwGBitMask; + DWORD dwBBitMask; + DWORD dwABitMask; +} DDS_PIXELFORMAT; + +typedef struct { + DWORD dwSize; + DWORD dwFlags; + DWORD dwHeight; + DWORD dwWidth; + DWORD dwPitchOrLinearSize; + DWORD dwDepth; + DWORD dwMipMapCount; + DWORD dwReserved1[11]; + DDS_PIXELFORMAT ddspf; + DWORD dwCaps; + DWORD dwCaps2; + DWORD dwCaps3; + DWORD dwCaps4; + DWORD dwReserved2; +} DDS_HEADER; + +#define DDS_HEADER_SIZE 124 +#define DDS_PIXELFORMAT_SIZE 32 + +#define FOURCC(c0, c1, c2, c3) ((int)(c0) | ((int)(c1) << 8) | ((int)(c2) << 16) | ((int)(c3) << 24)) + +#define DDPF_FOURCC 0x4 + +ALLEGRO_BITMAP *_al_load_dds_f(ALLEGRO_FILE *f, int flags) +{ + ALLEGRO_BITMAP *bmp; + DDS_HEADER header; + DWORD magic; + size_t num_read; + int w, h, fourcc, format, block_width, block_height, block_size; + ALLEGRO_STATE state; + ALLEGRO_LOCKED_REGION *lr = NULL; + int ii; + char* bitmap_data; + (void)flags; + + magic = al_fread32le(f); + if (magic != 0x20534444) { + ALLEGRO_ERROR("Invalid DDS magic number.\n"); + return NULL; + } + + num_read = al_fread(f, &header, sizeof(DDS_HEADER)); + if (num_read != DDS_HEADER_SIZE) { + ALLEGRO_ERROR("Wrong DDS header size. Got %d, expected %d.\n", + (int)num_read, DDS_HEADER_SIZE); + return NULL; + } + + if (!(header.ddspf.dwFlags & DDPF_FOURCC)) { + ALLEGRO_ERROR("Only compressed DDS formats supported.\n"); + return NULL; + } + + w = header.dwWidth; + h = header.dwHeight; + fourcc = header.ddspf.dwFourCC; + + switch (fourcc) { + case FOURCC('D', 'X', 'T', '1'): + format = ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1; + break; + case FOURCC('D', 'X', 'T', '3'): + format = ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3; + break; + case FOURCC('D', 'X', 'T', '5'): + format = ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5; + break; + default: + ALLEGRO_ERROR("Invalid pixel format.\n"); + return NULL; + } + + block_width = al_get_pixel_block_width(format); + block_height = al_get_pixel_block_height(format); + block_size = al_get_pixel_block_size(format); + + al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); + al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); + al_set_new_bitmap_format(format); + bmp = al_create_bitmap(w, h); + if (!bmp) { + ALLEGRO_ERROR("Failed to create bitmap.\n"); + goto FAIL; + } + + if (al_get_bitmap_format(bmp) != format) { + ALLEGRO_ERROR("Created a bad bitmap.\n"); + goto FAIL; + } + + lr = al_lock_bitmap_blocked(bmp, ALLEGRO_LOCK_WRITEONLY); + + if (!lr) { + switch (format) { + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1: + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3: + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5: + ALLEGRO_ERROR("Could not lock the bitmap (probably the support for locking this format has not been enabled).\n"); + break; + default: + ALLEGRO_ERROR("Could not lock the bitmap.\n"); + } + return NULL; + } + + bitmap_data = lr->data; + + for (ii = 0; ii < h / block_height; ii++) { + size_t pitch = (size_t)(w / block_width * block_size); + num_read = al_fread(f, bitmap_data, pitch); + if (num_read != pitch) { + ALLEGRO_ERROR("DDS file too short.\n"); + goto FAIL; + } + bitmap_data += lr->pitch; + } + al_unlock_bitmap(bmp); + + goto RESET; +FAIL: + if (lr) + al_unlock_bitmap(bmp); + al_destroy_bitmap(bmp); + bmp = NULL; +RESET: + al_restore_state(&state); + return bmp; +} + +ALLEGRO_BITMAP *_al_load_dds(const char *filename, int flags) +{ + ALLEGRO_FILE *f; + ALLEGRO_BITMAP *bmp; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_load_dds_f(f, flags); + + al_fclose(f); + + return bmp; +} + +bool _al_identify_dds(ALLEGRO_FILE *f) +{ + uint8_t x[4]; + uint32_t y; + al_fread(f, x, 4); + if (memcmp(x, "DDS ", 4) != 0) + return false; + y = al_fread32le(f); + if (y != 124) + return false; + return true; +} diff --git a/allegro/addons/image/freeimage.c b/allegro/addons/image/freeimage.c new file mode 100644 index 00000000..60492116 --- /dev/null +++ b/allegro/addons/image/freeimage.c @@ -0,0 +1,182 @@ +/* Allegro wrapper routines for FreeImage + * by Karthik Kumar Viswanathan <karthikkumar@gmail.com>. + */ + +#include <FreeImage.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +ALLEGRO_DEBUG_CHANNEL("image") + +static bool freeimage_initialized = false; + +static void _fiio_al_error_handler(FREE_IMAGE_FORMAT fif, const char *message) { + ALLEGRO_ERROR("FreeImage %s : %s\n", (fif == FIF_UNKNOWN)? "UNKNOWN" : FreeImage_GetFormatFromFIF(fif), message); +} + +bool _al_init_fi(void) +{ + if (freeimage_initialized) + return true; + FreeImage_Initialise(FALSE); + _al_add_exit_func(_al_shutdown_fi, "_al_shutdown_fi"); + FreeImage_SetOutputMessage(_fiio_al_error_handler); + return true; +} + +void _al_shutdown_fi(void) +{ + if (!freeimage_initialized) + return; + FreeImage_DeInitialise(); + freeimage_initialized = false; +} + +static ALLEGRO_BITMAP *_al_fi_to_al_bitmap(FIBITMAP *fib) { + int width = 0, height = 0; + ALLEGRO_BITMAP *bitmap = NULL; + width = FreeImage_GetWidth(fib); + height = FreeImage_GetHeight(fib); + bitmap = al_create_bitmap(width, height); + if (bitmap) { + ALLEGRO_LOCKED_REGION *a_lock = al_lock_bitmap(bitmap, + ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_WRITEONLY); + if (a_lock) { + unsigned char *out = (unsigned char *)a_lock->data; + int out_inc = a_lock->pitch - (width*4); + for (int j=height - 1; j > -1; --j) { + for (int i=0; i < width; ++i) { + RGBQUAD color = { 0.0, 0.0, 0.0, 0.0 } ; + if (FreeImage_GetPixelColor(fib, i, j, &color) == FALSE) { + ALLEGRO_ERROR("Unable to get pixel data at %d,%d\n", i , j); + } + *out++ = (unsigned char) color.rgbBlue; + *out++ = (unsigned char) color.rgbGreen; + *out++ = (unsigned char) color.rgbRed; + *out++ = (unsigned char) color.rgbReserved; + } + out += out_inc; + } + al_unlock_bitmap(bitmap); + } + } + return bitmap; +} + +ALLEGRO_BITMAP *_al_load_fi_bitmap(const char *filename, int flags) +{ + FIBITMAP *fib = NULL; + ALLEGRO_BITMAP *bitmap = NULL; + FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; + + ASSERT(filename); + ASSERT(freeimage_initialized == true); + + fif = FreeImage_GetFIFFromFilename(filename); + if (fif == FIF_UNKNOWN) + fif = FreeImage_GetFileType(filename, 0); + if (fif == FIF_UNKNOWN) { + ALLEGRO_WARN("Could not determine the file type for '%s'\n", filename); + return NULL; + } + + { + FIBITMAP *fibRaw = FreeImage_Load(fif, filename, flags); + if (!fibRaw) + return NULL; + fib = FreeImage_ConvertTo32Bits(fibRaw); + FreeImage_Unload(fibRaw); + if (!fib) + return NULL; + } + + bitmap = _al_fi_to_al_bitmap(fib); + FreeImage_Unload(fib); + return bitmap; +} + +static unsigned int _fiio_al_read(void *buffer, unsigned size, unsigned count, fi_handle handle) { + return (unsigned int) al_fread((ALLEGRO_FILE *)handle, buffer, (count * size)); +} + +static unsigned int _fiio_al_write(void *buffer, unsigned size, unsigned count, fi_handle handle) { + return (unsigned int) al_fwrite((ALLEGRO_FILE *)handle, buffer, (count * size)); +} + +static int _fiio_al_fseek(fi_handle handle, long offset, int origin) { + return al_fseek((ALLEGRO_FILE *)handle, offset, origin); +} + +static long _fiio_al_ftell(fi_handle handle) { + return (long) al_ftell((ALLEGRO_FILE *)handle); +} + +ALLEGRO_BITMAP *_al_load_fi_bitmap_f(ALLEGRO_FILE *f, int flags) +{ + FreeImageIO fio; + ALLEGRO_BITMAP *bitmap = NULL; + FIBITMAP *fib = NULL; + FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; + + if (flags != 0) { + ALLEGRO_WARN("Ignoring bitmap loading flags.\n"); + } + + ASSERT(f); + ASSERT(freeimage_initialized == true); + + fio.read_proc = _fiio_al_read; + fio.write_proc = _fiio_al_write; + fio.seek_proc = _fiio_al_fseek; + fio.tell_proc = _fiio_al_ftell; + + fif = FreeImage_GetFileTypeFromHandle(&fio, (fi_handle)f, 0); + if (fif == FIF_UNKNOWN) { + ALLEGRO_WARN("Could not determine the file type for Allegro file.\n"); + return NULL; + } + + { + FIBITMAP *fibRaw = FreeImage_LoadFromHandle(fif, &fio, (fi_handle)f, 0); + if (!fibRaw) + return NULL; + fib = FreeImage_ConvertTo32Bits(fibRaw); + FreeImage_Unload(fibRaw); + if (!fib) + return NULL; + } + + bitmap = _al_fi_to_al_bitmap(fib); + FreeImage_Unload(fib); + return bitmap; +} + +bool _al_identify_fi(ALLEGRO_FILE *f) +{ + FreeImageIO fio; + FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; + + ASSERT(f); + ASSERT(freeimage_initialized == true); + + fio.read_proc = _fiio_al_read; + fio.write_proc = _fiio_al_write; + fio.seek_proc = _fiio_al_fseek; + fio.tell_proc = _fiio_al_ftell; + + fif = FreeImage_GetFileTypeFromHandle(&fio, (fi_handle)f, 0); + if (fif == FIF_UNKNOWN) { + ALLEGRO_WARN("Could not determine the file type for Allegro file.\n"); + return false; + } + + return true; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/image/gdiplus.cpp b/allegro/addons/image/gdiplus.cpp new file mode 100644 index 00000000..5d33d7b7 --- /dev/null +++ b/allegro/addons/image/gdiplus.cpp @@ -0,0 +1,511 @@ +#include <windows.h> +#include <objidl.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_convert.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +#ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS_LOWERCASE_H + #include <gdiplus.h> +#else + #include <GdiPlus.h> +#endif + +ALLEGRO_DEBUG_CHANNEL("image") + +/* Needed with the MinGW w32api-3.15 headers. */ +using namespace Gdiplus; + +#if !defined(_MSC_VER) && !defined(__uuidof) +#define __uuidof(x) (IID_ ## x) +#endif + +static bool gdiplus_inited = false; +static ULONG_PTR gdiplusToken = 0; + +/* Source: + * http://msdn.microsoft.com/en-us/library/ms533843%28VS.85%29.aspx + */ +static int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) +{ + UINT num = 0; // number of image encoders + UINT size = 0; // size of the image encoder array in bytes + + Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; + + Gdiplus::GetImageEncodersSize(&num, &size); + if (size == 0) { + return -1; + } + + pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(al_malloc(size)); + if (pImageCodecInfo == NULL) { + return -1; + } + + GetImageEncoders(num, size, pImageCodecInfo); + + for (UINT j = 0; j < num; ++j) { + if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0) { + *pClsid = pImageCodecInfo[j].Clsid; + al_free(pImageCodecInfo); + return j; + } + } + + al_free(pImageCodecInfo); + return -1; +} + +/* A wrapper around an already opened ALLEGRO_FILE* pointer + */ +class AllegroWindowsStream : public IStream +{ + long refCount; + ALLEGRO_FILE *fp; + +public: + /* Create a stream from an open file handle */ + AllegroWindowsStream(ALLEGRO_FILE *fp) : + refCount(1), + fp(fp) + { + this->fp = fp; + } + + virtual ~AllegroWindowsStream() + { + } + + /* IUnknown */ + virtual ULONG STDMETHODCALLTYPE AddRef(void) + { + return (ULONG) InterlockedIncrement(&refCount); + } + + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) + { + if (iid == __uuidof(IUnknown) || iid == __uuidof(ISequentialStream) + || iid == __uuidof(IStream)) { + *ppvObject = static_cast<IStream*>(this); + AddRef(); + return S_OK; + } + else { + return E_NOINTERFACE; + } + } + + virtual ULONG STDMETHODCALLTYPE Release(void) + { + ULONG ret = InterlockedDecrement(&refCount); + if (ret == 0) { + delete this; + return 0; + } + return ret; + } + + /* ISequentialStream */ + virtual HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead) + { + size_t read = al_fread(fp, pv, cb); + if (pcbRead) { + *pcbRead = read; + } + return read == cb ? S_OK : S_FALSE; + } + + virtual HRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb, + ULONG *pcbWritten) + { + size_t written = al_fwrite(fp, pv, cb); + if (pcbWritten) { + *pcbWritten = written; + } + return written == cb ? S_OK : STG_E_CANTSAVE; + } + + /* IStream */ + virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, + ULARGE_INTEGER *plibNewPosition) + { + ALLEGRO_SEEK o; + if (dwOrigin == STREAM_SEEK_SET) { + o = ALLEGRO_SEEK_SET; + } + else if (dwOrigin == STREAM_SEEK_CUR) { + o = ALLEGRO_SEEK_CUR; + } + else { + o = ALLEGRO_SEEK_END; + } + + bool ret = al_fseek(fp, dlibMove.QuadPart, o); + + if (plibNewPosition) { + int64_t pos = al_ftell(fp); + if (pos == -1) { + return STG_E_INVALIDFUNCTION; + } + + plibNewPosition->QuadPart = pos; + } + + return ret ? S_OK : STG_E_INVALIDFUNCTION; + } + + /* The GDI+ image I/O methods need to know the file size */ + virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD grfStatFlag) + { + (void) grfStatFlag; + memset(pstatstg, 0, sizeof(*pstatstg)); + pstatstg->type = STGTY_STREAM; + pstatstg->cbSize.QuadPart = al_fsize(fp); + return S_OK; + } + + /* The following IStream methods aren't needed */ + virtual HRESULT STDMETHODCALLTYPE Clone(IStream **ppstm) + { + (void) ppstm; + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags) + { + (void) grfCommitFlags; + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE CopyTo (IStream *pstm, ULARGE_INTEGER cb, + ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) + { + (void) pstm; + (void) cb; + (void) pcbRead; + (void) pcbWritten; + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, DWORD dwLockType) + { + (void) libOffset; + (void) cb; + (void) dwLockType; + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE Revert() + { + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize) + { + (void) libNewSize; + return E_NOTIMPL; + } + + virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, DWORD dwLockType) + { + (void) libOffset; + (void) cb; + (void) dwLockType; + return E_NOTIMPL; + } +}; + +static void load_indexed_data(Gdiplus::Bitmap *gdi_bmp, + ALLEGRO_BITMAP *a_bmp, uint32_t w, uint32_t h) +{ + Gdiplus::BitmapData *gdi_lock = new Gdiplus::BitmapData(); + Gdiplus::Rect rect(0, 0, w, h); + + if (!gdi_bmp->LockBits(&rect, Gdiplus::ImageLockModeRead, + PixelFormat8bppIndexed, gdi_lock)) + { + ALLEGRO_LOCKED_REGION *a_lock = al_lock_bitmap(a_bmp, + ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, ALLEGRO_LOCK_WRITEONLY); + + if (a_lock) { + unsigned char *in = (unsigned char *)gdi_lock->Scan0; + unsigned char *out = (unsigned char *)a_lock->data; + + if (gdi_lock->Stride == a_lock->pitch) { + memcpy(out, in, h * gdi_lock->Stride); + } + else { + uint32_t rows = h; + while (rows--) { + memcpy(out, in, w); + in += gdi_lock->Stride; + out += a_lock->pitch; + } + } + al_unlock_bitmap(a_bmp); + } + + gdi_bmp->UnlockBits(gdi_lock); + } + + delete gdi_lock; +} + +static void load_non_indexed_data(Gdiplus::Bitmap *gdi_bmp, + ALLEGRO_BITMAP *a_bmp, uint32_t w, uint32_t h, bool premul) +{ + Gdiplus::BitmapData *gdi_lock = new Gdiplus::BitmapData(); + Gdiplus::Rect rect(0, 0, w, h); + + if (!gdi_bmp->LockBits(&rect, Gdiplus::ImageLockModeRead, + PixelFormat32bppARGB, gdi_lock)) + { + ALLEGRO_LOCKED_REGION *a_lock = al_lock_bitmap(a_bmp, + ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_WRITEONLY); + + if (a_lock) { + unsigned char *in = (unsigned char *)gdi_lock->Scan0; + unsigned char *out = (unsigned char *)a_lock->data; + + if (premul) { + int in_inc = gdi_lock->Stride - (w*4); + int out_inc = a_lock->pitch - (w*4); + for (unsigned int y = 0; y < h; y++) { + for (unsigned int x = 0; x < w; x++) { + unsigned char r, g, b, a; + b = *in++; + g = *in++; + r = *in++; + a = *in++; + b = b * a / 255; + g = g * a / 255; + r = r * a / 255; + *out++ = b; + *out++ = g; + *out++ = r; + *out++ = a; + } + in += in_inc; + out += out_inc; + } + } + else { + if (gdi_lock->Stride == a_lock->pitch) { + memcpy(out, in, h * gdi_lock->Stride); + } + else { + uint32_t rows = h; + while (rows--) { + memcpy(out, in, w * 4); + in += gdi_lock->Stride; + out += a_lock->pitch; + } + } + } + al_unlock_bitmap(a_bmp); + } + + gdi_bmp->UnlockBits(gdi_lock); + } + + delete gdi_lock; +} + +ALLEGRO_BITMAP *_al_load_gdiplus_bitmap_f(ALLEGRO_FILE *fp, int flags) +{ + AllegroWindowsStream *s = new AllegroWindowsStream(fp); + if (!s) { + ALLEGRO_ERROR("Unable to create AllegroWindowsStream.\n"); + return NULL; + } + + ALLEGRO_BITMAP *a_bmp = NULL; + Gdiplus::Bitmap *gdi_bmp = Gdiplus::Bitmap::FromStream(s, false); + + if (gdi_bmp) { + const uint32_t w = gdi_bmp->GetWidth(); + const uint32_t h = gdi_bmp->GetHeight(); + const PixelFormat pf = gdi_bmp->GetPixelFormat(); + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + bool keep_index = (flags & ALLEGRO_KEEP_INDEX); + + a_bmp = al_create_bitmap(w, h); + if (a_bmp) { + if (pf == PixelFormat8bppIndexed && keep_index) { + load_indexed_data(gdi_bmp, a_bmp, w, h); + } + else { + load_non_indexed_data(gdi_bmp, a_bmp, w, h, premul); + } + } + delete gdi_bmp; + } + + s->Release(); + + return a_bmp; +} + +ALLEGRO_BITMAP *_al_load_gdiplus_bitmap(const char *filename, int flags) +{ + ALLEGRO_BITMAP *bmp = NULL; + ALLEGRO_FILE *fp; + + fp = al_fopen(filename, "rb"); + if (fp) { + bmp = _al_load_gdiplus_bitmap_f(fp, flags); + al_fclose(fp); + } + + return bmp; +} + +bool _al_save_gdiplus_bitmap_f(ALLEGRO_FILE *fp, const char *ident, + ALLEGRO_BITMAP *a_bmp) +{ + CLSID encoder; + int encoder_status = -1; + + if (!_al_stricmp(ident, ".bmp")) { + encoder_status = GetEncoderClsid(L"image/bmp", &encoder); + } + else if (!_al_stricmp(ident, ".jpg") || !_al_stricmp(ident, ".jpeg")) { + encoder_status = GetEncoderClsid(L"image/jpeg", &encoder); + } + else if (!_al_stricmp(ident, ".gif")) { + encoder_status = GetEncoderClsid(L"image/gif", &encoder); + } + else if (!_al_stricmp(ident, ".tif") || !_al_stricmp(ident, ".tiff")) { + encoder_status = GetEncoderClsid(L"image/tiff", &encoder); + } + else if (!_al_stricmp(ident, ".png")) { + encoder_status = GetEncoderClsid(L"image/png", &encoder); + } + + if (encoder_status == -1) { + ALLEGRO_ERROR("Invalid encoder status.\n"); + return false; + } + + AllegroWindowsStream *s = new AllegroWindowsStream(fp); + if (!s) { + ALLEGRO_ERROR("Couldn't create AllegroWindowsStream.\n"); + return false; + } + + const int w = al_get_bitmap_width(a_bmp), h = al_get_bitmap_height(a_bmp); + bool ret = false; + + Gdiplus::Bitmap *gdi_bmp = new Gdiplus::Bitmap(w, h, PixelFormat32bppARGB); + + if (gdi_bmp) { + Gdiplus::Rect rect(0, 0, w, h); + Gdiplus::BitmapData *gdi_lock = new Gdiplus::BitmapData(); + + if (!gdi_bmp->LockBits(&rect, Gdiplus::ImageLockModeWrite, + PixelFormat32bppARGB, gdi_lock)) { + + ALLEGRO_LOCKED_REGION *a_lock = al_lock_bitmap( + a_bmp, ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_READONLY); + + if (a_lock) { + unsigned char *in = (unsigned char *)a_lock->data; + unsigned char *out = (unsigned char *)gdi_lock->Scan0; + + if (gdi_lock->Stride == a_lock->pitch) { + memcpy(out, in, h * gdi_lock->Stride); + } + else { + uint32_t rows = h; + while (rows--) { + memcpy(out, in, w * 4); + in += a_lock->pitch; + out += gdi_lock->Stride; + } + } + + al_unlock_bitmap(a_bmp); + } + gdi_bmp->UnlockBits(gdi_lock); + } + + ret = (gdi_bmp->Save(s, &encoder, NULL) == 0); + + delete gdi_lock; + delete gdi_bmp; + } + + s->Release(); + + return ret; +} + +bool _al_save_gdiplus_bitmap(const char *filename, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_FILE *fp; + bool ret = false; + + fp = al_fopen(filename, "wb"); + if (fp) { + ALLEGRO_PATH *path = al_create_path(filename); + if (path) { + ret = _al_save_gdiplus_bitmap_f(fp, al_get_path_extension(path), bmp); + al_destroy_path(path); + } + al_fclose(fp); + } + + return ret; +} + +bool _al_save_gdiplus_png_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + return _al_save_gdiplus_bitmap_f(f, ".png", bmp); +} + +bool _al_save_gdiplus_jpg_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + return _al_save_gdiplus_bitmap_f(f, ".jpg", bmp); +} + +bool _al_save_gdiplus_tif_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + return _al_save_gdiplus_bitmap_f(f, ".tif", bmp); +} + +bool _al_save_gdiplus_gif_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + return _al_save_gdiplus_bitmap_f(f, ".gif", bmp); +} + +bool _al_init_gdiplus() +{ + if (!gdiplus_inited) { + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + if (Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) + == Gdiplus::Ok) { + gdiplus_inited = TRUE; + _al_add_exit_func(_al_shutdown_gdiplus, "_al_shutdown_gdiplus"); + } + } + + return gdiplus_inited; +} + +void _al_shutdown_gdiplus() +{ + if (gdiplus_inited) { + Gdiplus::GdiplusShutdown(gdiplusToken); + gdiplus_inited = false; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/image/identify.c b/allegro/addons/image/identify.c new file mode 100644 index 00000000..996135a0 --- /dev/null +++ b/allegro/addons/image/identify.c @@ -0,0 +1,39 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_image.h" + +bool _al_identify_png(ALLEGRO_FILE *f) +{ + uint8_t x[8]; + al_fread(f, x, 8); + if (memcmp(x, "\x89PNG\r\n\x1a\n", 8) != 0) + return false; + return true; +} + +bool _al_identify_jpg(ALLEGRO_FILE *f) +{ + uint8_t x[4]; + uint16_t y; + y = al_fread16be(f); + if (y != 0xffd8) + return false; + al_fseek(f, 6 - 2, ALLEGRO_SEEK_CUR); + al_fread(f, x, 4); + if (memcmp(x, "JFIF", 4) != 0) + return false; + return true; +} + +bool _al_identify_webp(ALLEGRO_FILE *f) +{ + uint8_t x[4]; + al_fread(f, x, 4); + if (memcmp(x, "RIFF", 4) != 0) + return false; + al_fseek(f, 4, ALLEGRO_SEEK_CUR); + al_fread(f, x, 4); + if (memcmp(x, "WEBP", 4) != 0) + return false; + return true; +} diff --git a/allegro/addons/image/iio.c b/allegro/addons/image/iio.c new file mode 100644 index 00000000..c593438d --- /dev/null +++ b/allegro/addons/image/iio.c @@ -0,0 +1,191 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_image.h" +#include "allegro5/internal/aintern_image_cfg.h" + + +/* globals */ +static bool iio_inited = false; + + +/* Function: al_init_image_addon + */ +bool al_init_image_addon(void) +{ + int success; + + if (iio_inited) + return true; + + success = 0; + + success |= al_register_bitmap_loader(".pcx", _al_load_pcx); + success |= al_register_bitmap_saver(".pcx", _al_save_pcx); + success |= al_register_bitmap_loader_f(".pcx", _al_load_pcx_f); + success |= al_register_bitmap_saver_f(".pcx", _al_save_pcx_f); + success |= al_register_bitmap_identifier(".pcx", _al_identify_pcx); + + success |= al_register_bitmap_loader(".bmp", _al_load_bmp); + success |= al_register_bitmap_saver(".bmp", _al_save_bmp); + success |= al_register_bitmap_loader_f(".bmp", _al_load_bmp_f); + success |= al_register_bitmap_saver_f(".bmp", _al_save_bmp_f); + success |= al_register_bitmap_identifier(".bmp", _al_identify_bmp); + + success |= al_register_bitmap_loader(".tga", _al_load_tga); + success |= al_register_bitmap_saver(".tga", _al_save_tga); + success |= al_register_bitmap_loader_f(".tga", _al_load_tga_f); + success |= al_register_bitmap_saver_f(".tga", _al_save_tga_f); + success |= al_register_bitmap_identifier(".tga", _al_identify_tga); + + success |= al_register_bitmap_loader(".dds", _al_load_dds); + success |= al_register_bitmap_loader_f(".dds", _al_load_dds_f); + success |= al_register_bitmap_identifier(".dds", _al_identify_dds); + + /* Even if we don't have libpng or libjpeg we most likely have a + * native reader for those instead so always identify them. + */ + success |= al_register_bitmap_identifier(".png", _al_identify_png); + success |= al_register_bitmap_identifier(".jpg", _al_identify_jpg); + +/* ALLEGRO_CFG_IIO_HAVE_* is sufficient to know that the library + should be used. i.e., ALLEGRO_CFG_IIO_HAVE_GDIPLUS and + ALLEGRO_CFG_IIO_HAVE_PNG will never both be set. */ + +#ifdef ALLEGRO_CFG_IIO_HAVE_GDIPLUS + { + char const *extensions[] = {".tif", ".tiff", ".jpg", ".jpeg", ".gif", + ".png", NULL}; + int i; + + if (_al_init_gdiplus()) { + for (i = 0; extensions[i]; i++) { + success |= al_register_bitmap_loader(extensions[i], _al_load_gdiplus_bitmap); + success |= al_register_bitmap_loader_f(extensions[i], _al_load_gdiplus_bitmap_f); + success |= al_register_bitmap_saver(extensions[i], _al_save_gdiplus_bitmap); + } + + success |= al_register_bitmap_saver_f(".tif", _al_save_gdiplus_tif_f); + success |= al_register_bitmap_saver_f(".tiff", _al_save_gdiplus_tif_f); + success |= al_register_bitmap_saver_f(".gif", _al_save_gdiplus_gif_f); + success |= al_register_bitmap_saver_f(".png", _al_save_gdiplus_png_f); + success |= al_register_bitmap_saver_f(".jpg", _al_save_gdiplus_jpg_f); + success |= al_register_bitmap_saver_f(".jpeg", _al_save_gdiplus_jpg_f); + } + } +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_PNG + success |= al_register_bitmap_loader(".png", _al_load_png); + success |= al_register_bitmap_saver(".png", _al_save_png); + success |= al_register_bitmap_loader_f(".png", _al_load_png_f); + success |= al_register_bitmap_saver_f(".png", _al_save_png_f); +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_JPG + success |= al_register_bitmap_loader(".jpg", _al_load_jpg); + success |= al_register_bitmap_saver(".jpg", _al_save_jpg); + success |= al_register_bitmap_loader_f(".jpg", _al_load_jpg_f); + success |= al_register_bitmap_saver_f(".jpg", _al_save_jpg_f); + + success |= al_register_bitmap_loader(".jpeg", _al_load_jpg); + success |= al_register_bitmap_saver(".jpeg", _al_save_jpg); + success |= al_register_bitmap_loader_f(".jpeg", _al_load_jpg_f); + success |= al_register_bitmap_saver_f(".jpeg", _al_save_jpg_f); +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_WEBP + success |= al_register_bitmap_loader(".webp", _al_load_webp); + success |= al_register_bitmap_saver(".webp", _al_save_webp); + success |= al_register_bitmap_loader_f(".webp", _al_load_webp_f); + success |= al_register_bitmap_saver_f(".webp", _al_save_webp_f); + success |= al_register_bitmap_identifier(".webp", _al_identify_webp); +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_FREEIMAGE + { + char const *extensions[] = {".ico", ".jng", ".koala", ".lbm", + ".iff", ".mng", ".pbm", ".pcd", ".pgm", ".ppm", ".ras", ".wbmp", + ".psd", ".cut", ".xpm", ".hdr", ".fax", ".sgi", ".exr", ".raw", + ".j2k", ".jp2", ".jpf", ".jpm", ".jpx", ".mj2", ".pfm", ".pict", + ".jxr", ".jbg", NULL}; + int i; + + if (_al_init_fi()) { + for (i = 0; extensions[i]; i++) { + success |= al_register_bitmap_loader(extensions[i], _al_load_fi_bitmap); + success |= al_register_bitmap_loader_f(extensions[i], _al_load_fi_bitmap_f); + success |= al_register_bitmap_identifier(extensions[i], _al_identify_fi); + } + } + } +#endif + +#ifdef ALLEGRO_CFG_IIO_HAVE_ANDROID + { + char const *extensions[] = {".webp", ".jpg", ".jpeg", ".ico", ".gif", + ".wbmp", ".png", NULL}; + int i; + + + for (i = 0; extensions[i]; i++) { + success |= al_register_bitmap_loader(extensions[i], _al_load_android_bitmap); + success |= al_register_bitmap_loader_f(extensions[i], _al_load_android_bitmap_f); + //success |= al_register_bitmap_saver(extensions[i], _al_save_android_bitmap); + } + success |= al_register_bitmap_identifier(".webp", _al_identify_webp); + } +#endif + +#ifdef ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER +#ifdef ALLEGRO_IPHONE + { + char const *extensions[] = {".tif", ".tiff", ".jpg", ".jpeg", ".gif", + ".png", ".BMPf", ".ico", ".cur", ".xbm", NULL}; + int i; + for (i = 0; extensions[i]; i++) { + success |= al_register_bitmap_loader(extensions[i], _al_iphone_load_image); + success |= al_register_bitmap_loader_f(extensions[i], _al_iphone_load_image_f); + } + } +#endif + +#ifdef ALLEGRO_MACOSX + success |= _al_osx_register_image_loader(); +#endif +#endif + + if (success) + iio_inited = true; + + _al_add_exit_func(al_shutdown_image_addon, "al_shutdown_image_addon"); + + return success; +} + + +/* Function: al_is_image_addon_initialized + */ +bool al_is_image_addon_initialized(void) +{ + return iio_inited; +} + + +/* Function: al_shutdown_image_addon + */ +void al_shutdown_image_addon(void) +{ + iio_inited = false; +} + + +/* Function: al_get_allegro_image_version + */ +uint32_t al_get_allegro_image_version(void) +{ + return ALLEGRO_VERSION_INT; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/image/iio.h b/allegro/addons/image/iio.h new file mode 100644 index 00000000..4f57bb7c --- /dev/null +++ b/allegro/addons/image/iio.h @@ -0,0 +1,16 @@ +#ifndef __al_included_allegro5_iio_h +#define __al_included_allegro5_iio_h + + + +#include "allegro5/internal/aintern_image_cfg.h" + + + +typedef struct PalEntry { + int r, g, b, a; +} PalEntry; + + +#endif + diff --git a/allegro/addons/image/iphone.m b/allegro/addons/image/iphone.m new file mode 100644 index 00000000..757da169 --- /dev/null +++ b/allegro/addons/image/iphone.m @@ -0,0 +1,142 @@ +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +ALLEGRO_DEBUG_CHANNEL("image") + +static ALLEGRO_BITMAP *really_load_image(char *buffer, int size, int flags) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + ALLEGRO_BITMAP *bmp = NULL; + void *pixels = NULL; + /* Note: buffer is now owned (and later freed) by the data object. */ + NSData *nsdata = [NSData dataWithBytesNoCopy:buffer length:size]; + UIImage *uiimage = [UIImage imageWithData:nsdata]; + int w = uiimage.size.width; + int h = uiimage.size.height; + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + + /* Now we need to draw the image into a memory buffer. */ + pixels = al_malloc(w * h * 4); + CGFloat whitePoint[3] = { + 1, 1, 1 + }; + CGFloat blackPoint[3] = { + 0, 0, 0 + }; + CGFloat gamma[3] = { + 2.2, 2.2, 2.2 + }; + CGFloat matrix[9] = { + 1, 1, 1, + 1, 1, 1, + 1, 1, 1 + }; + /* This sets up a color space that results in identical values + * as the image data itself, which is the same as the standalone + * libpng loader + */ + CGColorSpaceRef cs = + CGColorSpaceCreateCalibratedRGB( + whitePoint, blackPoint, gamma, matrix + ); + CGContextRef context = CGBitmapContextCreate(pixels, w, h, 8, w * 4, + cs, kCGImageAlphaPremultipliedLast); + CGContextSetBlendMode(context, kCGBlendModeCopy); + CGContextDrawImage(context, CGRectMake(0.0, 0.0, (CGFloat)w, (CGFloat)h), + uiimage.CGImage); + CGContextRelease(context); + CGColorSpaceRelease(cs); + + /* Then create a bitmap out of the memory buffer. */ + bmp = al_create_bitmap(w, h); + if (!bmp) goto done; + ALLEGRO_LOCKED_REGION *lock = al_lock_bitmap(bmp, + ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_LOCK_WRITEONLY); + + if (!premul) { + for (int i = 0; i < h; i++) { + unsigned char *src_ptr = (unsigned char *)pixels + w * 4 * i; + unsigned char *dest_ptr = (unsigned char *)lock->data + + lock->pitch * i; + for (int x = 0; x < w; x++) { + unsigned char r, g, b, a; + r = *src_ptr++; + g = *src_ptr++; + b = *src_ptr++; + a = *src_ptr++; + // NOTE: avoid divide by zero by adding a fraction + float alpha_mul = 255.0f / (a+0.001f); + r *= alpha_mul; + g *= alpha_mul; + b *= alpha_mul; + *dest_ptr++ = r; + *dest_ptr++ = g; + *dest_ptr++ = b; + *dest_ptr++ = a; + } + } + } + else { + for (int i = 0; i < h; i++) { + memcpy(lock->data + lock->pitch * i, pixels + w * 4 * i, w * 4); + } + } + al_unlock_bitmap(bmp); +done: + al_free(pixels); + + [pool release]; + + return bmp; +} + + +ALLEGRO_BITMAP *_al_iphone_load_image_f(ALLEGRO_FILE *f, int flags) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_ASSERT(f); + + int64_t size = al_fsize(f); + if (size <= 0) { + // TODO: Read from stream until we have the whole image + ALLEGRO_ERROR("Unable to determine file size.\n"); + return NULL; + } + /* Note: This *MUST* be the Apple malloc and not any wrapper, as the + * buffer will be owned and freed by the NSData object not us. + */ + void *buffer = al_malloc(size); + al_fread(f, buffer, size); + + /* Really load the image now. */ + bmp = really_load_image(buffer, size, flags); + return bmp; +} + + +ALLEGRO_BITMAP *_al_iphone_load_image(const char *filename, int flags) +{ + ALLEGRO_FILE *fp; + ALLEGRO_BITMAP *bmp; + + ALLEGRO_ASSERT(filename); + + fp = al_fopen(filename, "rb"); + if (!fp) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_iphone_load_image_f(fp, flags); + + al_fclose(fp); + + return bmp; +} diff --git a/allegro/addons/image/jpg.c b/allegro/addons/image/jpg.c new file mode 100644 index 00000000..7eca9719 --- /dev/null +++ b/allegro/addons/image/jpg.c @@ -0,0 +1,414 @@ +/* libjpeg wrapper for Allegro 5 iio addon. + * by Elias Pschernig + */ + +#include <stdio.h> +#include <stdlib.h> +#include <setjmp.h> +#ifdef ALLEGRO_HAVE_STDINT_H +#include <stdint.h> +#endif + +#define BUFFER_SIZE 4096 + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +#include <jpeglib.h> +#include <jerror.h> + +ALLEGRO_DEBUG_CHANNEL("image") + + +struct my_src_mgr +{ + struct jpeg_source_mgr pub; + JOCTET *buffer; + ALLEGRO_FILE *fp; +}; + +struct my_dest_mgr +{ + struct jpeg_destination_mgr pub; + JOCTET *buffer; + ALLEGRO_FILE *fp; +}; + +struct my_err_mgr +{ + struct jpeg_error_mgr pub; + jmp_buf jmpenv; +}; + +static void init_source(j_decompress_ptr cinfo) +{ + (void)cinfo; +} + +static void init_destination(j_compress_ptr cinfo) +{ + struct my_dest_mgr *dest = (void *)cinfo->dest; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = BUFFER_SIZE; +} + +static boolean fill_input_buffer(j_decompress_ptr cinfo) +{ + struct my_src_mgr *src = (void *)cinfo->src; + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = al_fread(src->fp, src->buffer, BUFFER_SIZE); + return 1; +} + +static boolean empty_output_buffer(j_compress_ptr cinfo) +{ + struct my_dest_mgr *dest = (void *)cinfo->dest; + al_fwrite(dest->fp, dest->buffer, BUFFER_SIZE); + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = BUFFER_SIZE; + return 1; +} + +static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + struct my_src_mgr *src = (void *)cinfo->src; + if (num_bytes <= (long)src->pub.bytes_in_buffer) { + src->pub.next_input_byte += num_bytes; + src->pub.bytes_in_buffer -= num_bytes; + } + else { + long skip = num_bytes - src->pub.bytes_in_buffer; + al_fseek(src->fp, skip, ALLEGRO_SEEK_CUR); + src->pub.bytes_in_buffer = 0; + } +} + +static void term_source(j_decompress_ptr cinfo) +{ + (void)cinfo; +} + +static void term_destination(j_compress_ptr cinfo) +{ + struct my_dest_mgr *dest = (void *)cinfo->dest; + al_fwrite(dest->fp, dest->buffer, BUFFER_SIZE - dest->pub.free_in_buffer); +} + + +static void jpeg_packfile_src(j_decompress_ptr cinfo, ALLEGRO_FILE *fp, + JOCTET *buffer) +{ + struct my_src_mgr *src; + + if (!cinfo->src) + cinfo->src = + (*cinfo->mem->alloc_small) ((void *)cinfo, JPOOL_PERMANENT, + sizeof *src); + + src = (void *)cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; + src->pub.term_source = term_source; + src->pub.bytes_in_buffer = 0; + src->buffer = buffer; + src->fp = fp; +} + +static void jpeg_packfile_dest(j_compress_ptr cinfo, ALLEGRO_FILE *fp, + JOCTET *buffer) +{ + struct my_dest_mgr *dest; + + if (!cinfo->dest) + cinfo->dest = + (*cinfo->mem->alloc_small) ((void *)cinfo, JPOOL_PERMANENT, + sizeof *dest); + + dest = (void *)cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->pub.free_in_buffer = 0; + dest->buffer = buffer; + dest->fp = fp; +} + +static void my_error_exit(j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + struct my_err_mgr *jerr = (void *)cinfo->err; + jerr->pub.format_message(cinfo, buffer); + ALLEGRO_ERROR("jpeg error: %s\n", buffer); + longjmp(jerr->jmpenv, 1); +} + +/* We keep data for load_jpg_entry_helper in a structure allocated in the + * caller's stack frame to avoid problems with automatic variables being + * undefined after a longjmp. + */ +struct load_jpg_entry_helper_data { + bool error; + ALLEGRO_BITMAP *bmp; + JOCTET *buffer; + unsigned char *row; +}; + +static void load_jpg_entry_helper(ALLEGRO_FILE *fp, + struct load_jpg_entry_helper_data *data, int flags) +{ + struct jpeg_decompress_struct cinfo; + struct my_err_mgr jerr; + ALLEGRO_LOCKED_REGION *lock; + int w, h, s; + + /* ALLEGRO_NO_PREMULTIPLIED_ALPHA does not apply. + * ALLEGRO_KEEP_INDEX does not apply. + */ + (void)flags; + + data->error = false; + + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + if (setjmp(jerr.jmpenv) != 0) { + /* Longjmp'd. */ + data->error = true; + goto longjmp_error; + } + + data->buffer = al_malloc(BUFFER_SIZE); + if (!data->buffer) { + data->error = true; + goto error; + } + + jpeg_create_decompress(&cinfo); + jpeg_packfile_src(&cinfo, fp, data->buffer); + jpeg_read_header(&cinfo, true); + jpeg_start_decompress(&cinfo); + + w = cinfo.output_width; + h = cinfo.output_height; + s = cinfo.output_components; + + /* Only one and three components make sense in a JPG file. */ + if (s != 1 && s != 3) { + data->error = true; + ALLEGRO_ERROR("%d components makes no sense\n", s); + goto error; + } + + data->bmp = al_create_bitmap(w, h); + if (!data->bmp) { + data->error = true; + ALLEGRO_ERROR("%dx%d bitmap creation failed\n", w, h); + goto error; + } + + /* Allegro's pixel format is endian independent, so that in + * ALLEGRO_PIXEL_FORMAT_RGB_888 the lower 8 bits always hold the Blue + * component. On a little endian system this is in byte 0. On a big + * endian system this is in byte 2. + * + * libjpeg expects byte 0 to hold the Red component, byte 1 to hold the + * Green component, byte 2 to hold the Blue component. Hence on little + * endian systems we need the opposite format, ALLEGRO_PIXEL_FORMAT_BGR_888. + */ +#ifdef ALLEGRO_BIG_ENDIAN + lock = al_lock_bitmap(data->bmp, ALLEGRO_PIXEL_FORMAT_RGB_888, + ALLEGRO_LOCK_WRITEONLY); +#else + lock = al_lock_bitmap(data->bmp, ALLEGRO_PIXEL_FORMAT_BGR_888, + ALLEGRO_LOCK_WRITEONLY); +#endif + + if (s == 3) { + /* Colour. */ + int y; + + for (y = cinfo.output_scanline; y < h; y = cinfo.output_scanline) { + unsigned char *out[1]; + out[0] = ((unsigned char *)lock->data) + y * lock->pitch; + jpeg_read_scanlines(&cinfo, (void *)out, 1); + } + } + else if (s == 1) { + /* Greyscale. */ + unsigned char *in; + unsigned char *out; + int x, y; + + data->row = al_malloc(w); + for (y = cinfo.output_scanline; y < h; y = cinfo.output_scanline) { + jpeg_read_scanlines(&cinfo, (void *)&data->row, 1); + in = data->row; + out = ((unsigned char *)lock->data) + y * lock->pitch; + for (x = 0; x < w; x++) { + *out++ = *in; + *out++ = *in; + *out++ = *in; + in++; + } + } + } + + error: + jpeg_finish_decompress(&cinfo); + + longjmp_error: + jpeg_destroy_decompress(&cinfo); + + if (data->bmp) { + if (al_is_bitmap_locked(data->bmp)) { + al_unlock_bitmap(data->bmp); + } + if (data->error) { + al_destroy_bitmap(data->bmp); + data->bmp = NULL; + } + } + + al_free(data->buffer); + al_free(data->row); +} + +ALLEGRO_BITMAP *_al_load_jpg_f(ALLEGRO_FILE *fp, int flags) +{ + struct load_jpg_entry_helper_data data; + + memset(&data, 0, sizeof(data)); + load_jpg_entry_helper(fp, &data, flags); + + return data.bmp; +} + +/* See comment about load_jpg_entry_helper_data. */ +struct save_jpg_entry_helper_data { + bool error; + JOCTET *buffer; +}; + +static void save_jpg_entry_helper(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp, + struct save_jpg_entry_helper_data *data) +{ + struct jpeg_compress_struct cinfo; + struct my_err_mgr jerr; + ALLEGRO_LOCKED_REGION *lock; + + data->error = false; + + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + if (setjmp(jerr.jmpenv)) { + /* Longjmp'd. */ + data->error = true; + goto longjmp_error; + } + + data->buffer = al_malloc(BUFFER_SIZE); + if (!data->buffer) { + data->error = true; + goto error; + } + + jpeg_create_compress(&cinfo); + jpeg_packfile_dest(&cinfo, fp, data->buffer); + + cinfo.image_width = al_get_bitmap_width(bmp); + cinfo.image_height = al_get_bitmap_height(bmp); + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + + const char* level = al_get_config_value(al_get_system_config(), "image", "jpeg_quality_level"); + jpeg_set_quality(&cinfo, level ? strtol(level, NULL, 10) : 75, true); + + jpeg_start_compress(&cinfo, 1); + + /* See comment in load_jpg_entry_helper. */ +#ifdef ALLEGRO_BIG_ENDIAN + lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_RGB_888, + ALLEGRO_LOCK_READONLY); +#else + lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_BGR_888, + ALLEGRO_LOCK_READONLY); +#endif + + while (cinfo.next_scanline < cinfo.image_height) { + unsigned char *row[1]; + row[0] = ((unsigned char *)lock->data) + + (signed)cinfo.next_scanline * lock->pitch; + jpeg_write_scanlines(&cinfo, (void *)row, 1); + } + + error: + jpeg_finish_compress(&cinfo); + + longjmp_error: + jpeg_destroy_compress(&cinfo); + + if (al_is_bitmap_locked(bmp)) { + al_unlock_bitmap(bmp); + } + + al_free(data->buffer); +} + +bool _al_save_jpg_f(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp) +{ + struct save_jpg_entry_helper_data data; + + memset(&data, 0, sizeof(data)); + save_jpg_entry_helper(fp, bmp, &data); + + return !data.error; +} + +ALLEGRO_BITMAP *_al_load_jpg(char const *filename, int flags) +{ + ALLEGRO_FILE *fp; + ALLEGRO_BITMAP *bmp; + + ALLEGRO_ASSERT(filename); + + fp = al_fopen(filename, "rb"); + if (!fp) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_load_jpg_f(fp, flags); + + al_fclose(fp); + + return bmp; +} + +bool _al_save_jpg(char const *filename, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_FILE *fp; + bool retsave; + bool retclose; + + ALLEGRO_ASSERT(filename); + ALLEGRO_ASSERT(bmp); + + fp = al_fopen(filename, "wb"); + if (!fp) { + ALLEGRO_ERROR("Unable to open file %s for writing\n", filename); + return false; + } + + retsave = _al_save_jpg_f(fp, bmp); + + retclose = al_fclose(fp); + + return retsave && retclose; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/image/macosx.m b/allegro/addons/image/macosx.m new file mode 100644 index 00000000..4a83408b --- /dev/null +++ b/allegro/addons/image/macosx.m @@ -0,0 +1,302 @@ +#import <Foundation/Foundation.h> +#import <AppKit/NSImage.h> +#import <AppKit/NSGraphicsContext.h> + +#include "allegro5/allegro.h" +#include "allegro5/fshook.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +typedef float CGFloat; +#endif + +ALLEGRO_DEBUG_CHANNEL("OSXIIO") + +// Just to make sure it's never al_malloc. +#define apple_malloc malloc + +static ALLEGRO_BITMAP *really_load_image(char *buffer, int size, int flags) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; + ALLEGRO_BITMAP *bmp = NULL; + void *pixels = NULL; + /* Note: buffer is now owned (and later freed) by the data object. */ + NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:buffer length:size]; + NSImage *image = [[NSImage alloc] initWithData:nsdata]; + [nsdata release]; + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + + if (!image) + goto done; + + /* Get the image representations */ + NSArray *reps = [image representations]; + NSImageRep *image_rep = [reps objectAtIndex: 0]; + + if (!image_rep) { + [image release]; + goto done; + } + + /* Get the actual size in pixels from the representation */ + unsigned char *data[5]; + // TODO: We should check it really is a bitmap representation. + NSBitmapImageRep *bitmap_rep = (NSBitmapImageRep *)image_rep; + [bitmap_rep getBitmapDataPlanes:data]; + pixels = data[0]; + int w = [image_rep pixelsWide]; + int h = [image_rep pixelsHigh]; + int bits = [bitmap_rep bitsPerPixel]; + int samples = bits / 8; + ALLEGRO_DEBUG("Read image of size %dx%dx%d\n", w, h, bits); + + /* Then create a bitmap out of the memory buffer. */ + bmp = al_create_bitmap(w, h); + if (bmp) { + ALLEGRO_LOCKED_REGION *lock = al_lock_bitmap(bmp, + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); + int i, j; + { + for (i = 0; i < h; i++) { + uint8_t *data_row = (uint8_t *) lock->data + lock->pitch * i; + uint8_t *source_row = (uint8_t *) pixels + w * samples * i; + if (samples == 4) { + if (premul) { + for (j = 0; j < w; j++) { + int r, g, b, a; + r = source_row[j * 4 + 0]; + g = source_row[j * 4 + 1]; + b = source_row[j * 4 + 2]; + a = source_row[j * 4 + 3]; + data_row[j * 4 + 0] = r * a / 255; + data_row[j * 4 + 1] = g * a / 255; + data_row[j * 4 + 2] = b * a / 255; + data_row[j * 4 + 3] = a; + } + } + else + memcpy(data_row, source_row, w * 4); + } + else if (samples == 3) { + for (j = 0; j < w; j++) { + data_row[j * 4 + 0] = source_row[j * 3 + 0]; + data_row[j * 4 + 1] = source_row[j * 3 + 1]; + data_row[j * 4 + 2] = source_row[j * 3 + 2]; + data_row[j * 4 + 3] = 255; + } + } + else if (samples == 2) { + for (j = 0; j < w; j++) { + int a = data_row[j * 4 + 3] = source_row[j * 2 + 1]; + if (!premul) + a = 255; + data_row[j * 4 + 0] = source_row[j * 2 + 0] * a / 255; + data_row[j * 4 + 1] = source_row[j * 2 + 0] * a / 255; + data_row[j * 4 + 2] = source_row[j * 2 + 0] * a / 255; + + } + } + else if (samples == 1) { + for (j = 0; j < w; j++) { + data_row[j * 4 + 0] = source_row[j]; + data_row[j * 4 + 1] = source_row[j]; + data_row[j * 4 + 2] = source_row[j]; + data_row[j * 4 + 3] = 255; + } + } + } + } + al_unlock_bitmap(bmp); + } + + [image release]; +done: + [pool drain]; + return bmp; +} + + +static ALLEGRO_BITMAP *_al_osx_load_image_f(ALLEGRO_FILE *f, int flags) +{ + ALLEGRO_BITMAP *bmp; + ASSERT(f); + + int64_t size = al_fsize(f); + if (size <= 0) { + // TODO: Read from stream until we have the whole image + ALLEGRO_ERROR("Couldn't determine file size.\n"); + return NULL; + } + /* Note: This *MUST* be the Apple malloc and not any wrapper, as the + * buffer will be owned and freed by the NSData object not us. + */ + void *buffer = apple_malloc(size); + al_fread(f, buffer, size); + + /* Really load the image now. */ + bmp = really_load_image(buffer, size, flags); + return bmp; +} + + +static ALLEGRO_BITMAP *_al_osx_load_image(const char *filename, int flags) +{ + ALLEGRO_FILE *fp; + ALLEGRO_BITMAP *bmp; + + ASSERT(filename); + + ALLEGRO_DEBUG("Using native loader to read %s\n", filename); + fp = al_fopen(filename, "rb"); + if (!fp) { + ALLEGRO_ERROR("Unable open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_osx_load_image_f(fp, flags); + + al_fclose(fp); + + return bmp; +} + + +extern NSImage* NSImageFromAllegroBitmap(ALLEGRO_BITMAP* bmp); + +bool _al_osx_save_image_f(ALLEGRO_FILE *f, const char *ident, ALLEGRO_BITMAP *bmp) +{ + NSBitmapImageFileType type; + + if (!strcmp(ident, ".bmp")) { + type = NSBMPFileType; + } + else if (!strcmp(ident, ".jpg") || !strcmp(ident, ".jpeg")) { + type = NSJPEGFileType; + } + else if (!strcmp(ident, ".gif")) { + type = NSGIFFileType; + } + else if (!strcmp(ident, ".tif") || !strcmp(ident, ".tiff")) { + type = NSTIFFFileType; + } + else if (!strcmp(ident, ".png")) { + type = NSPNGFileType; + } + else { + ALLEGRO_ERROR("Unsupported image format: %s.\n", ident); + return false; + } + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; + + NSImage *image = NSImageFromAllegroBitmap(bmp); + NSArray *reps = [image representations]; + NSData *nsdata = [NSBitmapImageRep representationOfImageRepsInArray: reps usingType: type properties: [NSDictionary dictionary]]; + + size_t size = (size_t)[nsdata length]; + bool ret = al_fwrite(f, [nsdata bytes], size) == size; + + [image release]; + + [pool drain]; + + return ret; +} + + +bool _al_osx_save_image(const char *filename, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_FILE *fp; + bool retsave = false; + bool retclose = false; + + fp = al_fopen(filename, "wb"); + if (fp) { + ALLEGRO_PATH *path = al_create_path(filename); + if (path) { + retsave = _al_osx_save_image_f(fp, al_get_path_extension(path), bmp); + al_destroy_path(path); + } + retclose = al_fclose(fp); + } + else { + ALLEGRO_ERROR("Unable open %s for writing.\n", filename); + } + + return retsave && retclose; +} + + +bool _al_osx_save_png_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + return _al_osx_save_image_f(f, ".png", bmp); +} + +bool _al_osx_save_jpg_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + return _al_osx_save_image_f(f, ".jpg", bmp); +} + +bool _al_osx_save_tif_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + return _al_osx_save_image_f(f, ".tif", bmp); +} + +bool _al_osx_save_gif_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + return _al_osx_save_image_f(f, ".gif", bmp); +} + + +bool _al_osx_register_image_loader(void) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + bool success = false; + int num_types; + int i; + + /* Get a list of all supported image types */ + NSArray *file_types = [NSImage imageFileTypes]; + num_types = [file_types count]; + for (i = 0; i < num_types; i++) { + NSString *str = @"."; + NSString *type_str = [str stringByAppendingString: [file_types objectAtIndex: i]]; + const char *s = [type_str UTF8String]; + + /* Skip image types Allegro supports built-in */ + if (!_al_stricmp(s, ".tga") || !_al_stricmp(s, ".bmp") || !_al_stricmp(s, ".pcx")) { + continue; + } + + /* Unload previous loader, if any */ + al_register_bitmap_loader(s, NULL); + al_register_bitmap_loader_f(s, NULL); + + ALLEGRO_DEBUG("Registering native loader for bitmap type %s\n", s); + success |= al_register_bitmap_loader(s, _al_osx_load_image); + success |= al_register_bitmap_loader_f(s, _al_osx_load_image_f); + } + + char const *extensions[] = { ".tif", ".tiff", ".gif", ".png", ".jpg", ".jpeg", NULL }; + + for (i = 0; extensions[i]; i++) { + ALLEGRO_DEBUG("Registering native saver for bitmap type %s\n", extensions[i]); + success |= al_register_bitmap_saver(extensions[i], _al_osx_save_image); + } + + success |= al_register_bitmap_saver_f(".tif", _al_osx_save_tif_f); + success |= al_register_bitmap_saver_f(".tiff", _al_osx_save_tif_f); + success |= al_register_bitmap_saver_f(".gif", _al_osx_save_gif_f); + success |= al_register_bitmap_saver_f(".png", _al_osx_save_png_f); + success |= al_register_bitmap_saver_f(".jpg", _al_osx_save_jpg_f); + success |= al_register_bitmap_saver_f(".jpeg", _al_osx_save_jpg_f); + + [pool drain]; + + return success; +} + diff --git a/allegro/addons/image/pcx.c b/allegro/addons/image/pcx.c new file mode 100644 index 00000000..d9464eaa --- /dev/null +++ b/allegro/addons/image/pcx.c @@ -0,0 +1,322 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +ALLEGRO_DEBUG_CHANNEL("image") + +/* Do NOT simplify this to just (x), it doesn't work in MSVC. */ +#define INT_TO_BOOL(x) ((x) != 0) + +ALLEGRO_BITMAP *_al_load_pcx_f(ALLEGRO_FILE *f, int flags) +{ + ALLEGRO_BITMAP *b; + int c; + int width, height; + int bpp, bytes_per_line; + int x, xx, y; + char ch; + ALLEGRO_LOCKED_REGION *lr; + unsigned char *buf; + PalEntry pal[256]; + bool keep_index; + ASSERT(f); + + al_fgetc(f); /* skip manufacturer ID */ + al_fgetc(f); /* skip version flag */ + al_fgetc(f); /* skip encoding flag */ + + char color_plane = al_fgetc(f); + if (color_plane != 8) { /* we like 8 bit color planes */ + ALLEGRO_ERROR("Invalid color plane %d.\n", color_plane); + return NULL; + } + + width = -(al_fread16le(f)); /* xmin */ + height = -(al_fread16le(f)); /* ymin */ + width += al_fread16le(f) + 1; /* xmax */ + height += al_fread16le(f) + 1; /* ymax */ + + al_fread32le(f); /* skip DPI values */ + + for (c = 0; c < 16 * 3; c++) { /* skip the 16 color palette */ + al_fgetc(f); + } + + al_fgetc(f); + + bpp = al_fgetc(f) * 8; /* how many color planes? */ + + if ((bpp != 8) && (bpp != 24)) { + ALLEGRO_ERROR("Invalid bpp %d.\n", color_plane); + return NULL; + } + + bytes_per_line = al_fread16le(f); + + for (c = 0; c < 60; c++) /* skip some more junk */ + al_fgetc(f); + + if (al_feof(f) || al_ferror(f)) { + ALLEGRO_ERROR("Unexpected EOF/error.\n"); + return NULL; + } + + b = al_create_bitmap(width, height); + if (!b) { + ALLEGRO_ERROR("Failed to create bitmap.\n"); + return NULL; + } + + keep_index = INT_TO_BOOL(flags & ALLEGRO_KEEP_INDEX); + + al_set_errno(0); + + if (bpp == 8) { + /* The palette comes after the image data. We need to to keep the + * whole image in a temporary buffer before mapping the final colours. + */ + buf = (unsigned char *)al_malloc(bytes_per_line * height); + } + else { + /* We can read one line at a time. */ + buf = (unsigned char *)al_malloc(bytes_per_line * 3); + } + + if (bpp == 8 && keep_index) { + lr = al_lock_bitmap(b, ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, ALLEGRO_LOCK_WRITEONLY); + } + else { + lr = al_lock_bitmap(b, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); + } + if (!lr) { + ALLEGRO_ERROR("Failed to lock bitmap.\n"); + al_free(buf); + return NULL; + } + + xx = 0; /* index into buf, only for bpp = 8 */ + + for (y = 0; y < height; y++) { /* read RLE encoded PCX data */ + + x = 0; + + while (x < bytes_per_line * bpp / 8) { + ch = al_fgetc(f); + if ((ch & 0xC0) == 0xC0) { /* a run */ + c = (ch & 0x3F); + ch = al_fgetc(f); + } + else { + c = 1; /* single pixel */ + } + + if (bpp == 8) { + while (c--) { + if (x < width) /* ignore padding */ + buf[xx++] = ch; + x++; + } + } + else { + while (c--) { + if (x < width * 3) /* ignore padding */ + buf[x] = ch; + x++; + } + } + } + if (bpp == 24) { + char *dest = (char*)lr->data + y*lr->pitch; + for (x = 0; x < width; x++) { + dest[x*4 ] = buf[x]; + dest[x*4 + 1] = buf[x + width]; + dest[x*4 + 2] = buf[x + width * 2]; + dest[x*4 + 3] = 255; + } + } + } + + if (bpp == 8) { /* look for a 256 color palette */ + while ((c = al_fgetc(f)) != EOF) { + if (c == 12) { + for (c = 0; c < 256; c++) { + pal[c].r = al_fgetc(f); + pal[c].g = al_fgetc(f); + pal[c].b = al_fgetc(f); + } + break; + } + } + for (y = 0; y < height; y++) { + char *dest = (char*)lr->data + y*lr->pitch; + for (x = 0; x < width; x++) { + int index = buf[y * width + x]; + if (keep_index) { + dest[x] = index; + } + else { + dest[x*4 ] = pal[index].r; + dest[x*4 + 1] = pal[index].g; + dest[x*4 + 2] = pal[index].b; + dest[x*4 + 3] = 255; + } + } + } + } + + al_unlock_bitmap(b); + + al_free(buf); + + if (al_get_errno()) { + ALLEGRO_ERROR("Error detected: %d.\n", al_get_errno()); + al_destroy_bitmap(b); + return NULL; + } + + return b; +} + +bool _al_save_pcx_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + int c; + int x, y; + int i; + int w, h; + unsigned char *buf; + ASSERT(f); + ASSERT(bmp); + + al_set_errno(0); + + w = al_get_bitmap_width(bmp); + h = al_get_bitmap_height(bmp); + + al_fputc(f, 10); /* manufacturer */ + al_fputc(f, 5); /* version */ + al_fputc(f, 1); /* run length encoding */ + al_fputc(f, 8); /* 8 bits per pixel */ + al_fwrite16le(f, 0); /* xmin */ + al_fwrite16le(f, 0); /* ymin */ + al_fwrite16le(f, w - 1); /* xmax */ + al_fwrite16le(f, h - 1); /* ymax */ + al_fwrite16le(f, 320); /* HDpi */ + al_fwrite16le(f, 200); /* VDpi */ + + for (c = 0; c < 16 * 3; c++) { + al_fputc(f, 0); + } + + al_fputc(f, 0); /* reserved */ + al_fputc(f, 3); /* color planes */ + al_fwrite16le(f, w); /* number of bytes per scanline */ + al_fwrite16le(f, 1); /* color palette */ + al_fwrite16le(f, w); /* hscreen size */ + al_fwrite16le(f, h); /* vscreen size */ + for (c = 0; c < 54; c++) /* filler */ + al_fputc(f, 0); + + buf = al_malloc(w * 3); + + al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + + for (y = 0; y < h; y++) { /* for each scanline... */ + for (x = 0; x < w; x++) { + ALLEGRO_COLOR c = al_get_pixel(bmp, x, y); + unsigned char r, g, b; + al_unmap_rgb(c, &r, &g, &b); + buf[x] = r; + buf[x + w] = g; + buf[x + w * 2] = b; + } + + for (i = 0; i < 3; i++) { + int color; + int count; + x = 0; + for (;;) { + count = 0; + color = buf[x + w * i]; + do { + count++; + x++; + } while ((count < 63) && (x < w) && (color == buf[x + w * i])); + al_fputc(f, count | 0xC0); + al_fputc(f, color); + if (x >= w) + break; + } + } + } + + al_free(buf); + + al_unlock_bitmap(bmp); + + if (al_get_errno()) { + ALLEGRO_ERROR("Error detected: %d.\n", al_get_errno()); + return false; + } + else + return true; +} + +ALLEGRO_BITMAP *_al_load_pcx(const char *filename, int flags) +{ + ALLEGRO_FILE *f; + ALLEGRO_BITMAP *bmp; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_load_pcx_f(f, flags); + + al_fclose(f); + + return bmp; +} + +bool _al_save_pcx(const char *filename, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_FILE *f; + bool retsave; + bool retclose; + ASSERT(filename); + + f = al_fopen(filename, "wb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for writing.\n", filename); + return false; + } + + retsave = _al_save_pcx_f(f, bmp); + + retclose = al_fclose(f); + + return retsave && retclose; +} + +bool _al_identify_pcx(ALLEGRO_FILE *f) +{ + uint8_t x[4]; + al_fread(f, x, 4); + + if (x[0] != 0x0a) // PCX must start with 0x0a + return false; + if (x[1] == 1 || x[1] > 5) // version must be 0, 2, 3, 4, 5 + return false; + if (x[2] > 1) // compression must be 0 or 1 + return false; + if (x[3] != 8) // only 8-bit PCX files supported by Allegro! + return false; + return true; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/image/png.c b/allegro/addons/image/png.c new file mode 100644 index 00000000..13684739 --- /dev/null +++ b/allegro/addons/image/png.c @@ -0,0 +1,614 @@ +/* loadpng, Allegro wrapper routines for libpng + * by Peter Wang (tjaden@users.sf.net). + */ + + +#include <png.h> +#include <zlib.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +ALLEGRO_DEBUG_CHANNEL("image") + + +/* get_gamma: + * Get screen gamma value one of three ways. + */ +static double get_gamma(void) +{ + double gamma = -1.0; + const char* config = al_get_config_value(al_get_system_config(), "image", "png_screen_gamma"); + if (config) { + gamma = strtod(config, NULL); + } + if (gamma == -1.0) { + /* Use the environment variable if available. + * 2.2 is a good guess for PC monitors. + * 1.1 is good for my laptop. + */ + const char *gamma_str = getenv("SCREEN_GAMMA"); + return (gamma_str) ? strtod(gamma_str, NULL) : 2.2; + } + + return gamma; +} + + + +static void user_error_fn(png_structp png_ptr, png_const_charp message) +{ + jmp_buf *jmpbuf = (jmp_buf *)png_get_error_ptr(png_ptr); + ALLEGRO_DEBUG("PNG error: %s\n", message); + longjmp(*jmpbuf, 1); +} + + + +/***************************************************************************** + * Loading routines + ****************************************************************************/ + + + +/* read_data: + * Custom read function to use Allegro packfile routines, + * rather than C streams (so we can read from datafiles!) + */ +static void read_data(png_structp png_ptr, png_bytep data, size_t length) +{ + ALLEGRO_FILE *f = (ALLEGRO_FILE *)png_get_io_ptr(png_ptr); + if ((png_uint_32) al_fread(f, data, length) != length) + png_error(png_ptr, "read error (loadpng calling al_fs_entry_read)"); +} + + + +/* check_if_png: + * Check if input file is really PNG format. + */ +#define PNG_BYTES_TO_CHECK 4 + +static int check_if_png(ALLEGRO_FILE *fp) +{ + unsigned char buf[PNG_BYTES_TO_CHECK]; + + ALLEGRO_ASSERT(fp); + + if (al_fread(fp, buf, PNG_BYTES_TO_CHECK) != PNG_BYTES_TO_CHECK) + return 0; + + return (png_sig_cmp(buf, (png_size_t) 0, PNG_BYTES_TO_CHECK) == 0); +} + + + +/* really_load_png: + * Worker routine, used by load_png and load_memory_png. + */ +static ALLEGRO_BITMAP *really_load_png(png_structp png_ptr, png_infop info_ptr, + int flags) +{ + ALLEGRO_BITMAP *bmp; + png_uint_32 width, height, rowbytes, real_rowbytes; + int bit_depth, color_type, interlace_type; + double image_gamma, screen_gamma; + int intent; + int bpp; + int number_passes, pass; + int num_trans = 0; + PalEntry pal[256]; + png_bytep trans; + ALLEGRO_LOCKED_REGION *lock; + unsigned char *buf; + unsigned char *dest; + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + bool index_only; + + ALLEGRO_ASSERT(png_ptr && info_ptr); + + /* The call to png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). + */ + png_read_info(png_ptr, info_ptr); + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, + &color_type, &interlace_type, NULL, NULL); + + /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + png_set_packing(png_ptr); + + /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ + if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8)) + png_set_expand(png_ptr); + + /* Adds a full alpha channel if there is transparency information + * in a tRNS chunk. + */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + if (!(color_type & PNG_COLOR_MASK_PALETTE)) + png_set_tRNS_to_alpha(png_ptr); + png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); + } + + /* Convert 16-bits per colour component to 8-bits per colour component. */ + if (bit_depth == 16) + png_set_strip_16(png_ptr); + + /* Convert grayscale to RGB triplets */ + if ((color_type == PNG_COLOR_TYPE_GRAY) || + (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_set_gray_to_rgb(png_ptr); + + /* Optionally, tell libpng to handle the gamma correction for us. */ + screen_gamma = get_gamma(); + if (screen_gamma != 0.0) { + if (png_get_sRGB(png_ptr, info_ptr, &intent)) + png_set_gamma(png_ptr, screen_gamma, 0.45455); + else { + if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) + png_set_gamma(png_ptr, screen_gamma, image_gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + } + } + + /* Turn on interlace handling. */ + number_passes = png_set_interlace_handling(png_ptr); + + /* Call to gamma correct and add the background to the palette + * and update info structure. + */ + png_read_update_info(png_ptr, info_ptr); + + /* Palettes. */ + if (color_type & PNG_COLOR_MASK_PALETTE) { + int num_palette, i; + png_colorp palette; + + if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) { + /* We don't actually dither, we just copy the palette. */ + for (i = 0; ((i < num_palette) && (i < 256)); i++) { + pal[i].r = palette[i].red; + pal[i].g = palette[i].green; + pal[i].b = palette[i].blue; + } + + for (; i < 256; i++) + pal[i].r = pal[i].g = pal[i].b = 0; + } + } + + rowbytes = png_get_rowbytes(png_ptr, info_ptr); + + /* Allocate the memory to hold the image using the fields of info_ptr. */ + bpp = rowbytes * 8 / width; + + /* Allegro cannot handle less than 8 bpp. */ + if (bpp < 8) + bpp = 8; + + + if ((bpp == 24) || (bpp == 32)) { +#ifdef ALLEGRO_BIG_ENDIAN + png_set_bgr(png_ptr); + png_set_swap_alpha(png_ptr); +#endif + } + + bmp = al_create_bitmap(width, height); + if (!bmp) { + ALLEGRO_ERROR("al_create_bitmap failed while loading PNG.\n"); + return NULL; + } + + // TODO: can this be different from rowbytes? + real_rowbytes = ((bpp + 7) / 8) * width; + if (interlace_type == PNG_INTERLACE_ADAM7) + buf = al_malloc(real_rowbytes * height); + else + buf = al_malloc(real_rowbytes); + + if (bpp == 8 && (color_type & PNG_COLOR_MASK_PALETTE) && + (flags & ALLEGRO_KEEP_INDEX)) + { + lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, + ALLEGRO_LOCK_WRITEONLY); + index_only = true; + } + else { + lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ALLEGRO_LOCK_WRITEONLY); + index_only = false; + } + + /* Read the image, one line at a time (easier to debug!) */ + for (pass = 0; pass < number_passes; pass++) { + png_uint_32 y; + unsigned int i; + unsigned char *ptr; + dest = lock->data; + + for (y = 0; y < height; y++) { + unsigned char *dest_row_start = dest; + /* For interlaced pictures, the row needs to be initialized with + * the contents of the previous pass. + */ + if (interlace_type == PNG_INTERLACE_ADAM7) + ptr = buf + y * real_rowbytes; + else + ptr = buf; + png_read_row(png_ptr, NULL, ptr); + + switch (bpp) { + case 8: + if (index_only) { + for (i = 0; i < width; i++) { + *(dest++) = *(ptr++); + } + } + else if (color_type & PNG_COLOR_MASK_PALETTE) { + for (i = 0; i < width; i++) { + int pix = ptr[0]; + ptr++; + dest[0] = pal[pix].r; + dest[1] = pal[pix].g; + dest[2] = pal[pix].b; + if (pix < num_trans) { + int a = trans[pix]; + dest[3] = a; + if (premul) { + dest[0] = dest[0] * a / 255; + dest[1] = dest[1] * a / 255; + dest[2] = dest[2] * a / 255; + } + } else { + dest[3] = 255; + } + dest += 4; + } + } + else { + for (i = 0; i < width; i++) { + int pix = ptr[0]; + ptr++; + *(dest++) = pix; + *(dest++) = pix; + *(dest++) = pix; + *(dest++) = 255; + } + } + break; + + case 24: + for (i = 0; i < width; i++) { + uint32_t pix = _AL_READ3BYTES(ptr); + ptr += 3; + *(dest++) = pix & 0xff; + *(dest++) = (pix >> 8) & 0xff; + *(dest++) = (pix >> 16) & 0xff; + *(dest++) = 255; + } + break; + + case 32: + for (i = 0; i < width; i++) { + uint32_t pix = *(uint32_t*)ptr; + int r = pix & 0xff; + int g = (pix >> 8) & 0xff; + int b = (pix >> 16) & 0xff; + int a = (pix >> 24) & 0xff; + ptr += 4; + + if (premul) { + r = r * a / 255; + g = g * a / 255; + b = b * a / 255; + } + + *(dest++) = r; + *(dest++) = g; + *(dest++) = b; + *(dest++) = a; + } + break; + + default: + ALLEGRO_ASSERT(bpp == 8 || bpp == 24 || bpp == 32); + break; + } + dest = dest_row_start + lock->pitch; + } + } + + al_unlock_bitmap(bmp); + + al_free(buf); + + /* Read rest of file, and get additional chunks in info_ptr. */ + png_read_end(png_ptr, info_ptr); + + return bmp; +} + + +/* Load a PNG file from disk, doing colour coversion if required. + */ +ALLEGRO_BITMAP *_al_load_png_f(ALLEGRO_FILE *fp, int flags) +{ + jmp_buf jmpbuf; + ALLEGRO_BITMAP *bmp; + png_structp png_ptr; + png_infop info_ptr; + + ALLEGRO_ASSERT(fp); + + if (!check_if_png(fp)) { + ALLEGRO_ERROR("Not a png.\n"); + return NULL; + } + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also supply the + * the compiler header file version, so that we know if the application + * was compiled with a compatible version of the library. + */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + (void *)NULL, NULL, NULL); + if (!png_ptr) { + ALLEGRO_ERROR("png_ptr == NULL\n"); + return NULL; + } + + /* Allocate/initialize the memory for image information. */ + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); + ALLEGRO_ERROR("png_create_info_struct failed\n"); + return NULL; + } + + /* Set error handling. */ + if (setjmp(jmpbuf)) { + /* Free all of the memory associated with the png_ptr and info_ptr */ + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); + /* If we get here, we had a problem reading the file */ + ALLEGRO_ERROR("Error reading PNG file\n"); + return NULL; + } + png_set_error_fn(png_ptr, jmpbuf, user_error_fn, NULL); + + /* Use Allegro packfile routines. */ + png_set_read_fn(png_ptr, fp, (png_rw_ptr) read_data); + + /* We have already read some of the signature. */ + png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); + + /* Really load the image now. */ + bmp = really_load_png(png_ptr, info_ptr, flags); + + /* Clean up after the read, and free any memory allocated. */ + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); + + return bmp; +} + + + + + +ALLEGRO_BITMAP *_al_load_png(const char *filename, int flags) +{ + ALLEGRO_FILE *fp; + ALLEGRO_BITMAP *bmp; + + ALLEGRO_ASSERT(filename); + + fp = al_fopen(filename, "rb"); + if (!fp) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_load_png_f(fp, flags); + + al_fclose(fp); + + return bmp; +} + + + + +/***************************************************************************** + * Saving routines + ****************************************************************************/ + + + +/* write_data: + * Custom write function to use Allegro packfile routines, + * rather than C streams. + */ +static void write_data(png_structp png_ptr, png_bytep data, size_t length) +{ + ALLEGRO_FILE *f = (ALLEGRO_FILE *)png_get_io_ptr(png_ptr); + if ((png_uint_32) al_fwrite(f, data, length) != length) + png_error(png_ptr, "write error (loadpng calling al_fs_entry_write)"); +} + +/* Don't think Allegro has any problem with buffering + * (rather, Allegro provides no way to flush packfiles). + */ +static void flush_data(png_structp png_ptr) +{ + (void)png_ptr; +} + +/* translate_compression_level: + * Translate string with config value into proper zlib's + * compression level. Assumes default on NULL. + */ +static int translate_compression_level(const char* value) { + if (!value || strcmp(value, "default") == 0) { + return Z_DEFAULT_COMPRESSION; + } + if (strcmp(value, "best") == 0) { + return Z_BEST_COMPRESSION; + } + if (strcmp(value, "fastest") == 0) { + return Z_BEST_SPEED; + } + if (strcmp(value, "none") == 0) { + return Z_NO_COMPRESSION; + } + return strtol(value, NULL, 10); +} + +/* save_rgba: + * Core save routine for 32 bpp images. + */ +static int save_rgba(png_structp png_ptr, ALLEGRO_BITMAP *bmp) +{ + const int bmp_h = al_get_bitmap_height(bmp); + ALLEGRO_LOCKED_REGION *lock; + int y; + + lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ALLEGRO_LOCK_READONLY); + if (!lock) + return 0; + + for (y = 0; y < bmp_h; y++) { + unsigned char *p = (unsigned char *)lock->data + lock->pitch * y; + png_write_row(png_ptr, p); + } + + al_unlock_bitmap(bmp); + + return 1; +} + + + +/* Writes a non-interlaced, no-frills PNG, taking the usual save_xyz + * parameters. Returns non-zero on error. + */ +bool _al_save_png_f(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp) +{ + jmp_buf jmpbuf; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + int colour_type; + + /* Create and initialize the png_struct with the + * desired error handler functions. + */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, + (void *)NULL, NULL, NULL); + if (!png_ptr) { + ALLEGRO_ERROR("Unable to create PNG write struct.\n"); + goto Error; + } + + /* Allocate/initialize the image information data. */ + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + ALLEGRO_ERROR("Unable to create PNG info struct.\n"); + goto Error; + } + + /* Set error handling. */ + if (setjmp(jmpbuf)) { + ALLEGRO_ERROR("Failed to call setjmp.\n"); + goto Error; + } + png_set_error_fn(png_ptr, jmpbuf, user_error_fn, NULL); + + /* Use packfile routines. */ + png_set_write_fn(png_ptr, fp, (png_rw_ptr) write_data, flush_data); + + /* Set the image information here. Width and height are up to 2^31, + * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on + * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, + * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, + * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or + * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST + * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. + */ + colour_type = PNG_COLOR_TYPE_RGB_ALPHA; + + /* Set compression level. */ + int z_level = translate_compression_level( + al_get_config_value(al_get_system_config(), "image", "png_compression_level") + ); + png_set_compression_level(png_ptr, z_level); + + png_set_IHDR(png_ptr, info_ptr, + al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), + 8, colour_type, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + + /* Optionally write comments into the image ... Nah. */ + + /* Write the file header information. */ + png_write_info(png_ptr, info_ptr); + + /* Once we write out the header, the compression type on the text + * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or + * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again + * at the end. + */ + if (!save_rgba(png_ptr, bmp)) { + ALLEGRO_ERROR("save_rgba failed.\n"); + goto Error; + } + + png_write_end(png_ptr, info_ptr); + + png_destroy_write_struct(&png_ptr, &info_ptr); + + return true; + + Error: + + if (png_ptr) { + if (info_ptr) + png_destroy_write_struct(&png_ptr, &info_ptr); + else + png_destroy_write_struct(&png_ptr, NULL); + } + + return false; +} + + +bool _al_save_png(const char *filename, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_FILE *fp; + bool retsave; + bool retclose; + + ALLEGRO_ASSERT(filename); + ALLEGRO_ASSERT(bmp); + + fp = al_fopen(filename, "wb"); + if (!fp) { + ALLEGRO_ERROR("Unable to open file %s for writing\n", filename); + return false; + } + + retsave = _al_save_png_f(fp, bmp); + retclose = al_fclose(fp); + + return retsave && retclose; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/image/tga.c b/allegro/addons/image/tga.c new file mode 100644 index 00000000..ec536b9c --- /dev/null +++ b/allegro/addons/image/tga.c @@ -0,0 +1,611 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * TGA reader. + * + * By Tim Gunn. + * + * RLE support added by Michal Mertl and Salvador Eduardo Tropea. + * + * Palette reading improved by Peter Wang. + * + * Big-endian support added by Eric Botcazou. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_image.h" +#include "allegro5/internal/aintern_pixels.h" + +#include "iio.h" + +ALLEGRO_DEBUG_CHANNEL("image") + + +/* raw_tga_read8: + * Helper for reading 256-color raw data from TGA files. + */ +static INLINE unsigned char *raw_tga_read8(unsigned char *b, int w, ALLEGRO_FILE *f) +{ + return b + al_fread(f, b, w); +} + + + +/* rle_tga_read8: + * Helper for reading 256-color RLE data from TGA files. + */ +static void rle_tga_read8(unsigned char *b, int w, ALLEGRO_FILE *f) +{ + int value, count, c = 0; + + do { + count = al_fgetc(f); + if (count & 0x80) { + /* run-length packet */ + count = (count & 0x7F) + 1; + c += count; + value = al_fgetc(f); + while (count--) + *b++ = value; + } + else { + /* raw packet */ + count++; + c += count; + b = raw_tga_read8(b, count, f); + } + } while (c < w); +} + + + +/* single_tga_read32: + * Helper for reading a single 32-bit data from TGA files. + */ +static INLINE int32_t single_tga_read32(ALLEGRO_FILE *f) +{ + return al_fread32le(f); +} + + + +/* raw_tga_read32: + * Helper for reading 32-bit raw data from TGA files. + */ +static unsigned int *raw_tga_read32(unsigned int *b, int w, ALLEGRO_FILE *f) +{ + while (w--) + *b++ = single_tga_read32(f); + + return b; +} + + + +/* rle_tga_read32: + * Helper for reading 32-bit RLE data from TGA files. + */ +static void rle_tga_read32(unsigned int *b, int w, ALLEGRO_FILE *f) +{ + int color, count, c = 0; + + do { + count = al_fgetc(f); + if (count & 0x80) { + /* run-length packet */ + count = (count & 0x7F) + 1; + c += count; + color = single_tga_read32(f); + while (count--) + *b++ = color; + } + else { + /* raw packet */ + count++; + c += count; + b = raw_tga_read32(b, count, f); + } + } while (c < w); +} + + +/* single_tga_read24: + * Helper for reading a single 24-bit data from TGA files. + */ +static INLINE void single_tga_read24(ALLEGRO_FILE *f, unsigned char color[3]) +{ + al_fread(f, color, 3); +} + + + +/* raw_tga_read24: + * Helper for reading 24-bit raw data from TGA files. + */ +static unsigned char *raw_tga_read24(unsigned char *b, int w, ALLEGRO_FILE *f) +{ + while (w--) { + single_tga_read24(f, b); + b += 3; + } + + return b; +} + + + +/* rle_tga_read24: + * Helper for reading 24-bit RLE data from TGA files. + */ +static void rle_tga_read24(unsigned char *b, int w, ALLEGRO_FILE *f) +{ + int count, c = 0; + unsigned char color[3]; + + do { + count = al_fgetc(f); + if (count & 0x80) { + /* run-length packet */ + count = (count & 0x7F) + 1; + c += count; + single_tga_read24(f, color); + while (count--) { + b[0] = color[0]; + b[1] = color[1]; + b[2] = color[2]; + b += 3; + } + } + else { + /* raw packet */ + count++; + c += count; + b = raw_tga_read24(b, count, f); + } + } while (c < w); +} + + + +/* single_tga_read16: + * Helper for reading a single 16-bit data from TGA files. + */ +static INLINE int single_tga_read16(ALLEGRO_FILE *f) +{ + return al_fread16le(f); +} + + + +/* raw_tga_read16: + * Helper for reading 16-bit raw data from TGA files. + */ +static unsigned short *raw_tga_read16(unsigned short *b, int w, ALLEGRO_FILE *f) +{ + while (w--) + *b++ = single_tga_read16(f); + + return b; +} + + + +/* rle_tga_read16: + * Helper for reading 16-bit RLE data from TGA files. + */ +static void rle_tga_read16(unsigned short *b, int w, ALLEGRO_FILE *f) +{ + int color, count, c = 0; + + do { + count = al_fgetc(f); + if (count & 0x80) { + /* run-length packet */ + count = (count & 0x7F) + 1; + c += count; + color = single_tga_read16(f); + while (count--) + *b++ = color; + } + else { + /* raw packet */ + count++; + c += count; + b = raw_tga_read16(b, count, f); + } + } while (c < w); +} + + +/* Like load_tga, but starts loading from the current place in the ALLEGRO_FILE + * specified. If successful the offset into the file will be left just after + * the image data. If unsuccessful the offset into the file is unspecified, + * i.e. you must either reset the offset to some known place or close the + * packfile. The packfile is not closed by this function. + */ +ALLEGRO_BITMAP *_al_load_tga_f(ALLEGRO_FILE *f, int flags) +{ + unsigned char image_id[256], image_palette[256][3]; + unsigned char id_length, palette_type, image_type, palette_entry_size; + unsigned char bpp, descriptor_bits; + short unsigned int palette_colors; + short unsigned int image_width, image_height; + bool left_to_right; + bool top_to_bottom; + unsigned int c, i; + int y; + int compressed; + ALLEGRO_BITMAP *bmp; + ALLEGRO_LOCKED_REGION *lr; + unsigned char *buf; + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + ASSERT(f); + + id_length = al_fgetc(f); + palette_type = al_fgetc(f); + image_type = al_fgetc(f); + al_fread16le(f); /* first_color */ + palette_colors = al_fread16le(f); + palette_entry_size = al_fgetc(f); + al_fread16le(f); /* left */ + al_fread16le(f); /* top */ + image_width = al_fread16le(f); + image_height = al_fread16le(f); + bpp = al_fgetc(f); + descriptor_bits = al_fgetc(f); + + left_to_right = !(descriptor_bits & (1 << 4)); + top_to_bottom = (descriptor_bits & (1 << 5)); + + al_fread(f, image_id, id_length); + + if (palette_type == 1) { + + for (i = 0; i < palette_colors; i++) { + + switch (palette_entry_size) { + + case 16: + c = al_fread16le(f); + image_palette[i][0] = (c & 0x1F) << 3; + image_palette[i][1] = ((c >> 5) & 0x1F) << 3; + image_palette[i][2] = ((c >> 10) & 0x1F) << 3; + break; + + case 24: + case 32: + image_palette[i][0] = al_fgetc(f); + image_palette[i][1] = al_fgetc(f); + image_palette[i][2] = al_fgetc(f); + if (palette_entry_size == 32) + al_fgetc(f); + break; + } + } + } + else if (palette_type != 0) { + ALLEGRO_ERROR("Invalid palette type %d.\n", palette_type); + return NULL; + } + + /* Image type: + * 0 = no image data + * 1 = uncompressed color mapped + * 2 = uncompressed true color + * 3 = grayscale + * 9 = RLE color mapped + * 10 = RLE true color + * 11 = RLE grayscale + */ + compressed = (image_type & 8); + image_type &= 7; + + if ((image_type < 1) || (image_type > 3)) { + ALLEGRO_ERROR("Invalid image type %d.\n", image_type); + return NULL; + } + + switch (image_type) { + + case 1: + /* paletted image */ + if ((palette_type != 1) || (bpp != 8)) { + return NULL; + } + + break; + + case 2: + /* truecolor image */ + if ((palette_type == 0) && ((bpp == 15) || (bpp == 16))) { + bpp = 15; + } + else if ((palette_type == 0) && ((bpp == 24) || (bpp == 32))) { + } + else { + ALLEGRO_ERROR("Invalid palette/image/bpp combination %d/%d/%d.\n", image_type, palette_type, bpp); + return NULL; + } + break; + + case 3: + /* grayscale image */ + if ((palette_type != 0) || (bpp != 8)) { + ALLEGRO_ERROR("Invalid palette/image/bpp combination %d/%d/%d.\n", image_type, palette_type, bpp); + return NULL; + } + + for (i=0; i<256; i++) { + image_palette[i][0] = i; + image_palette[i][1] = i; + image_palette[i][2] = i; + } + break; + + default: + ALLEGRO_ERROR("Invalid image type %d.\n", image_type); + return NULL; + } + + bmp = al_create_bitmap(image_width, image_height); + if (!bmp) { + ALLEGRO_ERROR("Failed to create bitmap.\n"); + return NULL; + } + + al_set_errno(0); + + lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); + if (!lr) { + ALLEGRO_ERROR("Failed to lock bitmap.\n"); + al_destroy_bitmap(bmp); + return NULL; + } + + /* bpp + 1 accounts for 15 bpp. */ + buf = al_malloc(image_width * ((bpp + 1) / 8)); + if (!buf) { + al_unlock_bitmap(bmp); + al_destroy_bitmap(bmp); + ALLEGRO_ERROR("Failed to allocate enough memory.\n"); + return NULL; + } + + for (y = 0; y < image_height; y++) { + int true_y = (top_to_bottom) ? y : (image_height - 1 - y); + + switch (image_type) { + + case 1: + case 3: + if (compressed) + rle_tga_read8(buf, image_width, f); + else + raw_tga_read8(buf, image_width, f); + + for (i = 0; i < image_width; i++) { + int true_x = (left_to_right) ? i : (image_width - 1 - i); + int pix = buf[i]; + + unsigned char *dest = (unsigned char *)lr->data + + lr->pitch*true_y + true_x*4; + dest[0] = image_palette[pix][2]; + dest[1] = image_palette[pix][1]; + dest[2] = image_palette[pix][0]; + dest[3] = 255; + } + + break; + + case 2: + if (bpp == 32) { + if (compressed) + rle_tga_read32((unsigned int *)buf, image_width, f); + else + raw_tga_read32((unsigned int *)buf, image_width, f); + + for (i = 0; i < image_width; i++) { + int true_x = (left_to_right) ? i : (image_width - 1 - i); + unsigned char *dest = (unsigned char *)lr->data + + lr->pitch*true_y + true_x*4; + +#ifdef ALLEGRO_BIG_ENDIAN + int a = buf[i * 4 + 0]; + int r = buf[i * 4 + 1]; + int g = buf[i * 4 + 2]; + int b = buf[i * 4 + 3]; +#else + int b = buf[i * 4 + 0]; + int g = buf[i * 4 + 1]; + int r = buf[i * 4 + 2]; + int a = buf[i * 4 + 3]; +#endif + if (premul) { + r = r * a / 255; + g = g * a / 255; + b = b * a / 255; + } + + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = a; + } + } + else if (bpp == 24) { + if (compressed) + rle_tga_read24(buf, image_width, f); + else + raw_tga_read24(buf, image_width, f); + for (i = 0; i < image_width; i++) { + int true_x = (left_to_right) ? i : (image_width - 1 - i); + int b = buf[i * 3 + 0]; + int g = buf[i * 3 + 1]; + int r = buf[i * 3 + 2]; + + unsigned char *dest = (unsigned char *)lr->data + + lr->pitch*true_y + true_x*4; + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = 255; + } + } + else { + if (compressed) + rle_tga_read16((unsigned short *)buf, image_width, f); + else + raw_tga_read16((unsigned short *)buf, image_width, f); + for (i = 0; i < image_width; i++) { + int true_x = (left_to_right) ? i : (image_width - 1 - i); + int pix = *((unsigned short *)(buf + i * 2)); + int r = _al_rgb_scale_5[(pix >> 10)]; + int g = _al_rgb_scale_5[(pix >> 5) & 0x1F]; + int b = _al_rgb_scale_5[(pix & 0x1F)]; + + unsigned char *dest = (unsigned char *)lr->data + + lr->pitch*true_y + true_x*4; + dest[0] = r; + dest[1] = g; + dest[2] = b; + dest[3] = 255; + } + } + break; + } + } + + al_free(buf); + al_unlock_bitmap(bmp); + + if (al_get_errno()) { + ALLEGRO_ERROR("Error detected: %d.\n", al_get_errno()); + al_destroy_bitmap(bmp); + return NULL; + } + + return bmp; +} + + + +/* Like save_tga but writes into the ALLEGRO_FILE given instead of a new file. + * The packfile is not closed after writing is completed. On success the + * offset into the file is left after the TGA file just written. On failure + * the offset is left at the end of whatever incomplete data was written. + */ +bool _al_save_tga_f(ALLEGRO_FILE *f, ALLEGRO_BITMAP *bmp) +{ + int x, y; + int w, h; + ASSERT(f); + ASSERT(bmp); + + al_set_errno(0); + + w = al_get_bitmap_width(bmp); + h = al_get_bitmap_height(bmp); + + al_fputc(f, 0); /* id length (no id saved) */ + al_fputc(f, 0); /* palette type */ + al_fputc(f, 2); /* image type */ + al_fwrite16le(f, 0); /* first colour */ + al_fwrite16le(f, 0); /* number of colours */ + al_fputc(f, 0); /* palette entry size */ + al_fwrite16le(f, 0); /* left */ + al_fwrite16le(f, 0); /* top */ + al_fwrite16le(f, w); /* width */ + al_fwrite16le(f, h); /* height */ + al_fputc(f, 32); /* bits per pixel */ + al_fputc(f, 8); /* descriptor (bottom to top, 8-bit alpha) */ + + al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + + for (y = h - 1; y >= 0; y--) { + for (x = 0; x < w; x++) { + ALLEGRO_COLOR c = al_get_pixel(bmp, x, y); + unsigned char r, g, b, a; + al_unmap_rgba(c, &r, &g, &b, &a); + al_fputc(f, b); + al_fputc(f, g); + al_fputc(f, r); + al_fputc(f, a); + } + } + + al_unlock_bitmap(bmp); + + return al_get_errno() ? false : true; +} + + +ALLEGRO_BITMAP *_al_load_tga(const char *filename, int flags) +{ + ALLEGRO_FILE *f; + ALLEGRO_BITMAP *bmp; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_load_tga_f(f, flags); + + al_fclose(f); + + return bmp; +} + + + +bool _al_save_tga(const char *filename, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_FILE *f; + bool retsave; + bool retclose; + ASSERT(filename); + + f = al_fopen(filename, "wb"); + if (!f) { + ALLEGRO_ERROR("Unable to open %s for writing.\n", filename); + return false; + } + + retsave = _al_save_tga_f(f, bmp); + + retclose = al_fclose(f); + + return retsave && retclose; +} + + +bool _al_identify_tga(ALLEGRO_FILE *f) +{ + uint8_t x[4]; + al_fgetc(f); // skip id length + al_fread(f, x, 4); + + if (x[0] > 1) // TGA colormap must be 0 or 1 + return false; + if ((x[1] & 0xf7) == 0) // type must be 1, 2, 3, 9, 10 or 11 + return false; + if (x[2] != 0 || x[3] != 0) // color map must start at 0 + return false; + return true; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/image/webp.c b/allegro/addons/image/webp.c new file mode 100644 index 00000000..bb005fe8 --- /dev/null +++ b/allegro/addons/image/webp.c @@ -0,0 +1,188 @@ +/* Allegro wrapper routines for libwebp + * by Sebastian Krzyszkowiak (dos@dosowisko.net). + */ + + +#include <webp/decode.h> +#include <webp/encode.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/internal/aintern_image.h" + +#include "iio.h" + +ALLEGRO_DEBUG_CHANNEL("image") + + +/***************************************************************************** + * Loading routines + ****************************************************************************/ + + +static ALLEGRO_BITMAP *load_from_buffer(const uint8_t* data, size_t data_size, + int flags) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_LOCKED_REGION *lock; + bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA); + + WebPDecoderConfig config; + WebPInitDecoderConfig(&config); + + if (WebPGetFeatures(data, data_size, &config.input) != VP8_STATUS_OK) { + ALLEGRO_ERROR("Could not read WebP stream info\n"); + return NULL; + } + + bmp = al_create_bitmap(config.input.width, config.input.height); + if (!bmp) { + ALLEGRO_ERROR("al_create_bitmap failed while loading WebP.\n"); + return NULL; + } + + lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ALLEGRO_LOCK_WRITEONLY); + + config.output.colorspace = premul ? MODE_rgbA : MODE_RGBA; + config.output.u.RGBA.rgba = (uint8_t*)lock->data; + config.output.u.RGBA.stride = lock->pitch; + config.output.u.RGBA.size = lock->pitch * config.input.height; + config.output.is_external_memory = 1; + + if (WebPDecode(data, data_size, &config) != VP8_STATUS_OK) { + ALLEGRO_ERROR("Could not decode WebP stream\n"); + al_destroy_bitmap(bmp); + return NULL; + } + + al_unlock_bitmap(bmp); + + return bmp; +} + + +ALLEGRO_BITMAP *_al_load_webp_f(ALLEGRO_FILE *fp, int flags) +{ + ALLEGRO_ASSERT(fp); + ALLEGRO_BITMAP *bmp; + + size_t data_size = al_fsize(fp); + uint8_t *data = al_malloc(data_size * sizeof(uint8_t)); + + if (al_fread(fp, data, data_size) != data_size) { + ALLEGRO_ERROR("Could not read WebP file\n"); + free(data); + return NULL; + } + + bmp = load_from_buffer(data, data_size, flags); + + free(data); + + return bmp; +} + + + + + +ALLEGRO_BITMAP *_al_load_webp(const char *filename, int flags) +{ + ALLEGRO_FILE *fp; + ALLEGRO_BITMAP *bmp; + + ALLEGRO_ASSERT(filename); + + fp = al_fopen(filename, "rb"); + if (!fp) { + ALLEGRO_ERROR("Unable to open %s for reading.\n", filename); + return NULL; + } + + bmp = _al_load_webp_f(fp, flags); + + al_fclose(fp); + + return bmp; +} + + + + +/***************************************************************************** + * Saving routines + ****************************************************************************/ + + +bool _al_save_webp_f(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp) +{ + + ALLEGRO_LOCKED_REGION *lock; + bool ret = false; + + lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ALLEGRO_LOCK_READONLY); + if (!lock) { + ALLEGRO_ERROR("Failed to lock bitmap.\n"); + return false; + } + + uint8_t *output = NULL; + size_t size; + + const char* level = al_get_config_value(al_get_system_config(), "image", "webp_quality_level"); + if (!level || strcmp(level, "lossless") == 0) { + size = WebPEncodeLosslessRGBA((const uint8_t*)lock->data, + al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), + lock->pitch, &output); + } else { + size = WebPEncodeRGBA((const uint8_t*)lock->data, + al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), + lock->pitch, level ? strtol(level, NULL, 10) : 75, &output); + } + + if (al_fwrite(fp, output, size) == size) { + ret = true; + } + +#if WEBP_DECODER_ABI_VERSION >= 0x0206 + WebPFree(output); +#else + free(output); +#endif + al_unlock_bitmap(bmp); + + return ret; + +} + + +bool _al_save_webp(const char *filename, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_FILE *fp; + bool retsave; + bool retclose; + + ALLEGRO_ASSERT(filename); + ALLEGRO_ASSERT(bmp); + + fp = al_fopen(filename, "wb"); + if (!fp) { + ALLEGRO_ERROR("Unable to open file %s for writing\n", filename); + return false; + } + + retsave = _al_save_webp_f(fp, bmp); + if (!retsave) { + ALLEGRO_ERROR("Unable to store WebP bitmap in file %s\n", filename); + } + retclose = al_fclose(fp); + if (!retclose) { + ALLEGRO_ERROR("Unable to close file %s\n", filename); + } + + return retsave && retclose; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/main/CMakeLists.txt b/allegro/addons/main/CMakeLists.txt new file mode 100644 index 00000000..c8a589d6 --- /dev/null +++ b/allegro/addons/main/CMakeLists.txt @@ -0,0 +1,20 @@ +if(MACOSX) + set(MAIN_SOURCES osx_main.m) + set(SUPPORT_ALLEGRO_MAIN 1) +endif(MACOSX) + +if(NOT SUPPORT_ALLEGRO_MAIN) + set(MAIN_SOURCES generic_main.c) + set(SUPPORT_ALLEGRO_MAIN 1) +endif(NOT SUPPORT_ALLEGRO_MAIN) + +add_our_addon_library(allegro_main + AllegroMain-${ALLEGRO_SOVERSION} + "${MAIN_SOURCES}" + "-DALLEGRO_SRC" + "${ALLEGRO_LINK_WITH}" + ) + +add_addon(main) + +# vim: set sts=4 sw=4 et: diff --git a/allegro/addons/main/generic_main.c b/allegro/addons/main/generic_main.c new file mode 100644 index 00000000..66ec03fd --- /dev/null +++ b/allegro/addons/main/generic_main.c @@ -0,0 +1,12 @@ +/* Empty file */ + +/* + * MSVC will not generate an empty .lib file + */ +#ifdef _MSC_VER +#include <stdlib.h> +__declspec(dllexport) void _al_make_a_lib() +{ + exit(1); +} +#endif diff --git a/allegro/addons/main/osx_main.m b/allegro/addons/main/osx_main.m new file mode 100644 index 00000000..d6df1997 --- /dev/null +++ b/allegro/addons/main/osx_main.m @@ -0,0 +1,42 @@ +/* ______ ___ ___ +* /\ _ \ /\_ \ /\_ \ +* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ +* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ +* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ +* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ +* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ +* /\____/ +* \_/__/ +* +* main() function replacement for MacOS X. +* +* By Angelo Mottola. +* +* See readme.txt for copyright information. +*/ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintosx.h" + +#ifndef ALLEGRO_MACOSX +#error something is wrong with the makefile +#endif +#undef main + +extern int _al_mangled_main(int, char **); + +/* main: +* Replacement for main function. +*/ +int main(int argc, char *argv[]) +{ + _al_osx_run_main(argc, argv, _al_mangled_main); + return 0; +} + +/* Local variables: */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* c-file-style: "linux" */ +/* End: */ diff --git a/allegro/addons/memfile/CMakeLists.txt b/allegro/addons/memfile/CMakeLists.txt new file mode 100644 index 00000000..ca293e33 --- /dev/null +++ b/allegro/addons/memfile/CMakeLists.txt @@ -0,0 +1,20 @@ + +set(MEMFILE_SOURCES memfile.c) + +set(MEMFILE_INCLUDE_FILES allegro5/allegro_memfile.h) + +set_our_header_properties(${MEMFILE_INCLUDE_FILES}) + +add_our_addon_library(allegro_memfile + AllegroMemfile-${ALLEGRO_SOVERSION} + "${MEMFILE_SOURCES};${MEMFILE_INCLUDE_FILES}" + "-DALLEGRO_MEMFILE_SRC" + "${ALLEGRO_LINK_WITH}" + ) + +install_our_headers(${MEMFILE_INCLUDE_FILES}) + +add_addon(memfile) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/memfile/allegro5/allegro_memfile.h b/allegro/addons/memfile/allegro5/allegro_memfile.h new file mode 100644 index 00000000..5d8f6c48 --- /dev/null +++ b/allegro/addons/memfile/allegro5/allegro_memfile.h @@ -0,0 +1,40 @@ +#ifndef __al_included_allegro5_memfile_h +#define __al_included_allegro5_memfile_h + +#include "allegro5/allegro.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_MEMFILE_SRC + #define _ALLEGRO_MEMFILE_DLL __declspec(dllexport) + #else + #define _ALLEGRO_MEMFILE_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_MEMFILE_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_MEMFILE_FUNC(type, name, args) _ALLEGRO_MEMFILE_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_MEMFILE_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_MEMFILE_FUNC(type, name, args) extern _ALLEGRO_MEMFILE_DLL type name args +#else + #define ALLEGRO_MEMFILE_FUNC AL_FUNC +#endif + + +ALLEGRO_MEMFILE_FUNC(ALLEGRO_FILE *, al_open_memfile, (void *mem, int64_t size, const char *mode)); +ALLEGRO_MEMFILE_FUNC(uint32_t, al_get_allegro_memfile_version, (void)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/addons/memfile/memfile.c b/allegro/addons/memfile/memfile.c new file mode 100644 index 00000000..411c0413 --- /dev/null +++ b/allegro/addons/memfile/memfile.c @@ -0,0 +1,206 @@ +#include <allegro5/allegro.h> +#include "allegro5/allegro_memfile.h" + +typedef struct ALLEGRO_FILE_MEMFILE ALLEGRO_FILE_MEMFILE; + +struct ALLEGRO_FILE_MEMFILE { + bool readable; + bool writable; + + bool eof; + int64_t size; + int64_t pos; + char *mem; +}; + +static bool memfile_fclose(ALLEGRO_FILE *fp) +{ + al_free(al_get_file_userdata(fp)); + return true; +} + +static size_t memfile_fread(ALLEGRO_FILE *fp, void *ptr, size_t size) +{ + ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); + size_t n = 0; + + if (!mf->readable) { + al_set_errno(EPERM); + return 0; + } + + if (mf->size - mf->pos < (int64_t)size) { + /* partial read */ + n = mf->size - mf->pos; + mf->eof = true; + } + else { + n = size; + } + + memcpy(ptr, mf->mem + mf->pos, n); + mf->pos += n; + + return n; +} + +static size_t memfile_fwrite(ALLEGRO_FILE *fp, const void *ptr, size_t size) +{ + ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); + size_t n; + + if (!mf->writable) { + al_set_errno(EPERM); + return 0; + } + + if (mf->size - mf->pos < (int64_t)size) { + /* partial write */ + n = mf->size - mf->pos; + mf->eof = true; + } + else { + n = size; + } + + memcpy(mf->mem + mf->pos, ptr, n); + mf->pos += n; + + return n; +} + +static bool memfile_fflush(ALLEGRO_FILE *fp) +{ + (void)fp; + return true; +} + +static int64_t memfile_ftell(ALLEGRO_FILE *fp) +{ + ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); + + return mf->pos; +} + +static bool memfile_fseek(ALLEGRO_FILE *fp, int64_t offset, + int whence) +{ + ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); + int64_t pos = mf->pos; + + switch (whence) { + case ALLEGRO_SEEK_SET: + pos = offset; + break; + + case ALLEGRO_SEEK_CUR: + pos = mf->pos + offset; + break; + + case ALLEGRO_SEEK_END: + pos = mf->size + offset; + break; + } + + if (pos >= mf->size) + pos = mf->size; + else if (pos < 0) + pos = 0; + + mf->pos = pos; + + mf->eof = false; + + return true; +} + +/* doesn't quite match up to stdio here, + an feof after a seek will return false, + even if it seeks past the end of the file */ +static bool memfile_feof(ALLEGRO_FILE *fp) +{ + ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); + return mf->eof; +} + +static int memfile_ferror(ALLEGRO_FILE *fp) +{ + (void)fp; + return 0; +} + +static const char *memfile_ferrmsg(ALLEGRO_FILE *fp) +{ + (void)fp; + return ""; +} + +static void memfile_fclearerr(ALLEGRO_FILE *fp) +{ + ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); + mf->eof = false; +} + +static off_t memfile_fsize(ALLEGRO_FILE *fp) +{ + ALLEGRO_FILE_MEMFILE *mf = al_get_file_userdata(fp); + + return mf->size; +} + +static struct ALLEGRO_FILE_INTERFACE memfile_vtable = { + NULL, /* open */ + memfile_fclose, + memfile_fread, + memfile_fwrite, + memfile_fflush, + memfile_ftell, + memfile_fseek, + memfile_feof, + memfile_ferror, + memfile_ferrmsg, + memfile_fclearerr, + NULL, /* ungetc */ + memfile_fsize +}; + +/* Function: al_open_memfile + */ +ALLEGRO_FILE *al_open_memfile(void *mem, int64_t size, const char *mode) +{ + ALLEGRO_FILE *memfile; + ALLEGRO_FILE_MEMFILE *userdata = NULL; + + ASSERT(mem); + ASSERT(size > 0); + + userdata = al_malloc(sizeof(ALLEGRO_FILE_MEMFILE)); + if (!userdata) { + al_set_errno(ENOMEM); + return NULL; + } + + memset(userdata, 0, sizeof(*userdata)); + userdata->size = size; + userdata->pos = 0; + userdata->mem = mem; + + userdata->readable = strchr(mode, 'r') || strchr(mode, 'R'); + userdata->writable = strchr(mode, 'w') || strchr(mode, 'W'); + + memfile = al_create_file_handle(&memfile_vtable, userdata); + if (!memfile) { + al_free(userdata); + } + + return memfile; +} + +/* Function: al_get_allegro_memfile_version + */ +uint32_t al_get_allegro_memfile_version(void) +{ + return ALLEGRO_VERSION_INT; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/CMakeLists.txt b/allegro/addons/native_dialog/CMakeLists.txt new file mode 100644 index 00000000..e34e14e3 --- /dev/null +++ b/allegro/addons/native_dialog/CMakeLists.txt @@ -0,0 +1,79 @@ +set(NATIVE_DIALOG_INCLUDE_FILES allegro5/allegro_native_dialog.h) + +set_our_header_properties(${NATIVE_DIALOG_INCLUDE_FILES}) + +set(NATIVE_DIALOG_SOURCES + dialog.c + textlog.c + menu.c + ) + +set(GTK_NATIVE_DIALOG_SOURCES + gtk_dialog.c + gtk_filesel.c + gtk_menu.c + gtk_msgbox.c + gtk_textlog.c + gtk_thread.c + gtk_xgtk.c + ) + +if(APPLE AND NOT IPHONE) + list(APPEND NATIVE_DIALOG_SOURCES osx_dialog.m) + set(ALLEGRO_CFG_NATIVE_DIALOG_OSX 1) + set(SUPPORT_NATIVE_DIALOG 1) +endif(APPLE AND NOT IPHONE) + +if(APPLE AND IPHONE) + list(APPEND NATIVE_DIALOG_SOURCES iphone_dialog.m) + set(ALLEGRO_CFG_NATIVE_DIALOG_IPHONE 1) + set(SUPPORT_NATIVE_DIALOG 1) +endif(APPLE AND IPHONE) + +if(WIN32) + list(APPEND NATIVE_DIALOG_SOURCES win_dialog.c) + set(ALLEGRO_CFG_NATIVE_DIALOG_WINDOWS 1) + set(SUPPORT_NATIVE_DIALOG 1) +endif(WIN32) + +if(NOT SUPPORT_NATIVE_DIALOG AND SUPPORT_X11 AND NOT ALLEGRO_RASPBERRYPI) + pkg_check_modules(GTK gtk+-3.0) + pkg_check_modules(GT gthread-2.0) + if(GTK_FOUND AND GT_FOUND) + list(APPEND NATIVE_DIALOG_SOURCES ${GTK_NATIVE_DIALOG_SOURCES}) + list(APPEND NATIVE_DIALOG_INCLUDE_DIRECTORIES + ${GTK_INCLUDE_DIRS} ${GT_INCLUDE_DIRS}) + list(APPEND NATIVE_DIALOG_LIBRARIES ${GTK_LIBRARIES} ${GT_LIBRARIES}) + set_source_files_properties( + ${GTK_NATIVE_DIALOG_SOURCES} + PROPERTIES + COMPILE_FLAGS "${GTK_CFLAGS_STRING}" + ) + set(ALLEGRO_CFG_NATIVE_DIALOG_GTK 1) + set(SUPPORT_NATIVE_DIALOG 1) + endif() +endif() + +if(SUPPORT_NATIVE_DIALOG) + configure_file( + allegro5/internal/aintern_native_dialog_cfg.h.cmake + ${PROJECT_BINARY_DIR}/include/allegro5/internal/aintern_native_dialog_cfg.h + ) + + include_directories(SYSTEM ${NATIVE_DIALOG_INCLUDE_DIRECTORIES}) + + # Note: allegro_dialog NOT allegro_native_dialog. + add_our_addon_library(allegro_dialog + AllegroDialog-${ALLEGRO_SOVERSION} + "${NATIVE_DIALOG_SOURCES};${NATIVE_DIALOG_INCLUDE_FILES}" + "-DALLEGRO_NATIVE_DIALOG_SRC" + "${NATIVE_DIALOG_LIBRARIES};${ALLEGRO_LINK_WITH}" + ) + + install_our_headers(${NATIVE_DIALOG_INCLUDE_FILES}) + + # Note: allegro_dialog NOT allegro_native_dialog. + add_addon2(native_dialog allegro_dialog) +endif(SUPPORT_NATIVE_DIALOG) + +# vim: set sts=4 sw=4 et: diff --git a/allegro/addons/native_dialog/allegro5/allegro_native_dialog.h b/allegro/addons/native_dialog/allegro5/allegro_native_dialog.h new file mode 100644 index 00000000..2d48f517 --- /dev/null +++ b/allegro/addons/native_dialog/allegro5/allegro_native_dialog.h @@ -0,0 +1,164 @@ +#ifndef __al_included_allegro5_allegro_native_dialog_h +#define __al_included_allegro5_allegro_native_dialog_h + +#include "allegro5/allegro.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_NATIVE_DIALOG_SRC + #define _ALLEGRO_DIALOG_DLL __declspec(dllexport) + #else + #define _ALLEGRO_DIALOG_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_DIALOG_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_DIALOG_FUNC(type, name, args) _ALLEGRO_DIALOG_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_DIALOG_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_DIALOG_FUNC(type, name, args) extern _ALLEGRO_DIALOG_DLL type name args +#else + #define ALLEGRO_DIALOG_FUNC AL_FUNC +#endif + +#ifdef ALLEGRO_WITH_XWINDOWS + #define ALLEGRO_GTK_TOPLEVEL ALLEGRO_GTK_TOPLEVEL_INTERNAL +#endif + +/* Type: ALLEGRO_FILECHOOSER + */ +typedef struct ALLEGRO_FILECHOOSER ALLEGRO_FILECHOOSER; + +/* Type: ALLEGRO_TEXTLOG + */ +typedef struct ALLEGRO_TEXTLOG ALLEGRO_TEXTLOG; + +/* Type: ALLEGRO_MENU + */ +typedef struct ALLEGRO_MENU ALLEGRO_MENU; + +/* Type: ALLEGRO_MENU_INFO + */ +typedef struct ALLEGRO_MENU_INFO { + const char *caption; + uint16_t id; + int flags; + ALLEGRO_BITMAP *icon; +} ALLEGRO_MENU_INFO; + +#define ALLEGRO_MENU_SEPARATOR { NULL, -1, 0, NULL } +#define ALLEGRO_START_OF_MENU(caption, id) { caption "->", id, 0, NULL } +#define ALLEGRO_END_OF_MENU { NULL, 0, 0, NULL } + +ALLEGRO_DIALOG_FUNC(bool, al_init_native_dialog_addon, (void)); +ALLEGRO_DIALOG_FUNC(bool, al_is_native_dialog_addon_initialized, (void)); +ALLEGRO_DIALOG_FUNC(void, al_shutdown_native_dialog_addon, (void)); + +ALLEGRO_DIALOG_FUNC(ALLEGRO_FILECHOOSER *, al_create_native_file_dialog, (char const *initial_path, + char const *title, char const *patterns, int mode)); +ALLEGRO_DIALOG_FUNC(bool, al_show_native_file_dialog, (ALLEGRO_DISPLAY *display, ALLEGRO_FILECHOOSER *dialog)); +ALLEGRO_DIALOG_FUNC(int, al_get_native_file_dialog_count, (const ALLEGRO_FILECHOOSER *dialog)); +ALLEGRO_DIALOG_FUNC(const char *, al_get_native_file_dialog_path, (const ALLEGRO_FILECHOOSER *dialog, + size_t index)); +ALLEGRO_DIALOG_FUNC(void, al_destroy_native_file_dialog, (ALLEGRO_FILECHOOSER *dialog)); + +ALLEGRO_DIALOG_FUNC(int, al_show_native_message_box, (ALLEGRO_DISPLAY *display, char const *title, + char const *heading, char const *text, char const *buttons, int flags)); + +ALLEGRO_DIALOG_FUNC(ALLEGRO_TEXTLOG *, al_open_native_text_log, (char const *title, int flags)); +ALLEGRO_DIALOG_FUNC(void, al_close_native_text_log, (ALLEGRO_TEXTLOG *textlog)); +ALLEGRO_DIALOG_FUNC(void, al_append_native_text_log, (ALLEGRO_TEXTLOG *textlog, char const *format, ...)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_native_text_log_event_source, (ALLEGRO_TEXTLOG *textlog)); + +/* creating/modifying menus */ +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_create_menu, (void)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_create_popup_menu, (void)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_build_menu, (ALLEGRO_MENU_INFO *info)); +ALLEGRO_DIALOG_FUNC(int, al_append_menu_item, (ALLEGRO_MENU *parent, char const *title, uint16_t id, int flags, + ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu)); +ALLEGRO_DIALOG_FUNC(int, al_insert_menu_item, (ALLEGRO_MENU *parent, int pos, char const *title, uint16_t id, + int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu)); +ALLEGRO_DIALOG_FUNC(bool, al_remove_menu_item, (ALLEGRO_MENU *menu, int pos)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_clone_menu, (ALLEGRO_MENU *menu)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_clone_menu_for_popup, (ALLEGRO_MENU *menu)); +ALLEGRO_DIALOG_FUNC(void, al_destroy_menu, (ALLEGRO_MENU *menu)); + +/* properties */ +ALLEGRO_DIALOG_FUNC(const char *, al_get_menu_item_caption, (ALLEGRO_MENU *menu, int pos)); +ALLEGRO_DIALOG_FUNC(void, al_set_menu_item_caption, (ALLEGRO_MENU *menu, int pos, const char *caption)); +ALLEGRO_DIALOG_FUNC(int, al_get_menu_item_flags, (ALLEGRO_MENU *menu, int pos)); +ALLEGRO_DIALOG_FUNC(void, al_set_menu_item_flags, (ALLEGRO_MENU *menu, int pos, int flags)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_BITMAP *, al_get_menu_item_icon, (ALLEGRO_MENU *menu, int pos)); +ALLEGRO_DIALOG_FUNC(void, al_set_menu_item_icon, (ALLEGRO_MENU *menu, int pos, ALLEGRO_BITMAP *icon)); + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_NATIVE_DIALOG_SRC) +ALLEGRO_DIALOG_FUNC(int, al_toggle_menu_item_flags, (ALLEGRO_MENU *menu, int pos, int flags)); +#endif + +/* querying menus */ +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_find_menu, (ALLEGRO_MENU *haystack, uint16_t id)); +ALLEGRO_DIALOG_FUNC(bool, al_find_menu_item, (ALLEGRO_MENU *haystack, uint16_t id, ALLEGRO_MENU **menu, int *index)); + +/* menu events */ +ALLEGRO_DIALOG_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_default_menu_event_source, (void)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_EVENT_SOURCE *, al_enable_menu_event_source, (ALLEGRO_MENU *menu)); +ALLEGRO_DIALOG_FUNC(void, al_disable_menu_event_source, (ALLEGRO_MENU *menu)); + +/* displaying menus */ +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_get_display_menu, (ALLEGRO_DISPLAY *display)); +ALLEGRO_DIALOG_FUNC(bool, al_set_display_menu, (ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu)); +ALLEGRO_DIALOG_FUNC(bool, al_popup_menu, (ALLEGRO_MENU *popup, ALLEGRO_DISPLAY *display)); +ALLEGRO_DIALOG_FUNC(ALLEGRO_MENU *, al_remove_display_menu, (ALLEGRO_DISPLAY *display)); + +ALLEGRO_DIALOG_FUNC(uint32_t, al_get_allegro_native_dialog_version, (void)); + +enum { + ALLEGRO_FILECHOOSER_FILE_MUST_EXIST = 1, + ALLEGRO_FILECHOOSER_SAVE = 2, + ALLEGRO_FILECHOOSER_FOLDER = 4, + ALLEGRO_FILECHOOSER_PICTURES = 8, + ALLEGRO_FILECHOOSER_SHOW_HIDDEN = 16, + ALLEGRO_FILECHOOSER_MULTIPLE = 32 +}; + +enum { + ALLEGRO_MESSAGEBOX_WARN = 1<<0, + ALLEGRO_MESSAGEBOX_ERROR = 1<<1, + ALLEGRO_MESSAGEBOX_OK_CANCEL = 1<<2, + ALLEGRO_MESSAGEBOX_YES_NO = 1<<3, + ALLEGRO_MESSAGEBOX_QUESTION = 1<<4 +}; + +enum { + ALLEGRO_TEXTLOG_NO_CLOSE = 1<<0, + ALLEGRO_TEXTLOG_MONOSPACE = 1<<1 +}; + +enum { + ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE = 600, + ALLEGRO_EVENT_MENU_CLICK = 601 +}; + +enum { + ALLEGRO_MENU_ITEM_ENABLED = 0, + ALLEGRO_MENU_ITEM_CHECKBOX = 1, + ALLEGRO_MENU_ITEM_CHECKED = 2, + ALLEGRO_MENU_ITEM_DISABLED = 4 +}; + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog.h b/allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog.h new file mode 100644 index 00000000..6dc5c4f1 --- /dev/null +++ b/allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog.h @@ -0,0 +1,146 @@ +#ifndef __al_included_allegro_aintern_native_dialog_h +#define __al_included_allegro_aintern_native_dialog_h + +#include "allegro5/internal/aintern_list.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/internal/aintern_native_dialog_cfg.h" + +typedef struct ALLEGRO_NATIVE_DIALOG ALLEGRO_NATIVE_DIALOG; + +/* We could use different structs for the different dialogs. But why + * bother. + */ +struct ALLEGRO_NATIVE_DIALOG +{ + ALLEGRO_USTR *title; + int flags; + + /* Only used by file chooser. */ + ALLEGRO_PATH *fc_initial_path; + size_t fc_path_count; + ALLEGRO_PATH **fc_paths; + ALLEGRO_USTR *fc_patterns; + + /* Only used by message box. */ + ALLEGRO_USTR *mb_heading; + ALLEGRO_USTR *mb_text; + ALLEGRO_USTR *mb_buttons; + int mb_pressed_button; + + /* Only used by text log. */ + ALLEGRO_THREAD *tl_thread; + ALLEGRO_COND *tl_text_cond; + ALLEGRO_MUTEX *tl_text_mutex; + ALLEGRO_USTR *tl_pending_text; + bool tl_init_error; + bool tl_done; + bool tl_have_pending; + ALLEGRO_EVENT_SOURCE tl_events; + void *tl_textview; + + /* Only used by platform implementations. */ + bool is_active; + void *window; + void *async_queue; + + _AL_LIST_ITEM *dtor_item; +}; + +extern bool _al_init_native_dialog_addon(void); +extern void _al_shutdown_native_dialog_addon(void); +extern bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd); +extern int _al_show_native_message_box(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd); +extern bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog); +extern void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog); +extern void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog); + +typedef struct ALLEGRO_MENU_ITEM ALLEGRO_MENU_ITEM; + +struct ALLEGRO_MENU_ITEM +{ + ALLEGRO_MENU *parent; + ALLEGRO_MENU *popup; + ALLEGRO_USTR *caption; + ALLEGRO_BITMAP *icon; + + /* This id is unique. */ + uint16_t unique_id; + /* This id is user provided, can be not unique. */ + uint16_t id; + + int flags; + void *extra1, *extra2; +}; + +/* _AL_MENU_ID keeps track of menu / id pairs to help determine which + * menu belongs to an id. + */ +typedef struct _AL_MENU_ID _AL_MENU_ID; + +struct _AL_MENU_ID +{ + ALLEGRO_MENU *menu; + uint16_t unique_id; + uint16_t id; +}; + +struct ALLEGRO_MENU +{ + ALLEGRO_EVENT_SOURCE es; + ALLEGRO_DISPLAY *display; + ALLEGRO_MENU_ITEM *parent; + _AL_VECTOR items; + + bool is_event_source; + bool is_popup_menu; + + void *extra1; +}; + +/* Platform implementation must call this when a menu item is clicked. + * display: the display associated with the menu + * unique_id: the unique id associated with the menu item + * + * The function will find the appropriate ALLEGRO_MENU and emit the event. + */ +extern bool _al_emit_menu_event(ALLEGRO_DISPLAY *display, uint16_t unique_id); + +extern bool _al_walk_over_menu(ALLEGRO_MENU *menu, bool (*proc) + (ALLEGRO_MENU *menu, ALLEGRO_MENU_ITEM *item, int index, void *extra), + void *extra); +_AL_MENU_ID *_al_find_parent_menu_by_id(ALLEGRO_DISPLAY *display, uint16_t unique_id); +bool _al_find_menu_item_unique(ALLEGRO_MENU *haystack, uint16_t unique_id, ALLEGRO_MENU **menu, + int *index); + +/* Platform Specific Functions + * --------------------------- + * Each of these should return true if successful. If at all possible, they + * should all be implemented and always return true (if menus are implemented + * at all). All of the parameters will be valid. + */ + +extern bool _al_init_menu(ALLEGRO_MENU *menu); +extern bool _al_init_popup_menu(ALLEGRO_MENU *menu); +extern bool _al_destroy_menu(ALLEGRO_MENU *menu); + +/* The "int i" parameter represents the indexed location of the item in the + * item->parent->items vector. This should map up identically to what is displayed + * within the platform menu... However, if there are silent entries (e.g., on OS X), + * the index may not represent what is seen on screen. If such discrepencies exist, + * then the platform imlpementation must compensate accordingly. */ + +extern bool _al_insert_menu_item_at(ALLEGRO_MENU_ITEM *item, int i); +extern bool _al_destroy_menu_item_at(ALLEGRO_MENU_ITEM *item, int i); +extern bool _al_update_menu_item_at(ALLEGRO_MENU_ITEM *item, int i); + +extern bool _al_show_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu); +extern bool _al_hide_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu); +extern bool _al_show_popup_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu); + +/* Returns the height of the display taken up by the menu, so we can resize + * the display to compensate. Windows only at the moment.*/ +extern int _al_get_menu_display_height(void); + +#endif diff --git a/allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog_cfg.h.cmake b/allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog_cfg.h.cmake new file mode 100644 index 00000000..3369e497 --- /dev/null +++ b/allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog_cfg.h.cmake @@ -0,0 +1,3 @@ +#cmakedefine ALLEGRO_CFG_NATIVE_DIALOG_GTK +#cmakedefine ALLEGRO_CFG_NATIVE_DIALOG_OSX +#cmakedefine ALLEGRO_CFG_NATIVE_DIALOG_WINDOWS diff --git a/allegro/addons/native_dialog/dialog.c b/allegro/addons/native_dialog/dialog.c new file mode 100644 index 00000000..d89a722f --- /dev/null +++ b/allegro/addons/native_dialog/dialog.c @@ -0,0 +1,168 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_vector.h" + +ALLEGRO_DEBUG_CHANNEL("native_dialog") + +static bool inited_addon = false; + +/* Function: al_init_native_dialog_addon + */ +bool al_init_native_dialog_addon(void) +{ + if (!inited_addon) { + if (!_al_init_native_dialog_addon()) { + ALLEGRO_ERROR("_al_init_native_dialog_addon failed.\n"); + return false; + } + inited_addon = true; + al_init_user_event_source(al_get_default_menu_event_source()); + _al_add_exit_func(al_shutdown_native_dialog_addon, + "al_shutdown_native_dialog_addon"); + } + return true; +} + +/* Function: al_is_native_dialog_addon_initialized + */ +bool al_is_native_dialog_addon_initialized(void) +{ + return inited_addon; +} + +/* Function: al_shutdown_native_dialog_addon + */ +void al_shutdown_native_dialog_addon(void) +{ + if (inited_addon) { + al_destroy_user_event_source(al_get_default_menu_event_source()); + _al_shutdown_native_dialog_addon(); + inited_addon = false; + } +} + +/* Function: al_create_native_file_dialog + */ +ALLEGRO_FILECHOOSER *al_create_native_file_dialog( + char const *initial_path, + char const *title, + char const *patterns, + int mode) +{ + ALLEGRO_NATIVE_DIALOG *fc; + fc = al_calloc(1, sizeof *fc); + + if (initial_path) { + fc->fc_initial_path = al_create_path(initial_path); + } + fc->title = al_ustr_new(title); + fc->fc_patterns = al_ustr_new(patterns); + fc->flags = mode; + + fc->dtor_item = _al_register_destructor(_al_dtor_list, "native_dialog", fc, + (void (*)(void *))al_destroy_native_file_dialog); + + return (ALLEGRO_FILECHOOSER *)fc; +} + +/* Function: al_show_native_file_dialog + */ +bool al_show_native_file_dialog(ALLEGRO_DISPLAY *display, + ALLEGRO_FILECHOOSER *dialog) +{ + ALLEGRO_NATIVE_DIALOG *fd = (ALLEGRO_NATIVE_DIALOG *)dialog; + return _al_show_native_file_dialog(display, fd); +} + +/* Function: al_get_native_file_dialog_count + */ +int al_get_native_file_dialog_count(const ALLEGRO_FILECHOOSER *dialog) +{ + const ALLEGRO_NATIVE_DIALOG *fc = (const ALLEGRO_NATIVE_DIALOG *)dialog; + return fc->fc_path_count; +} + +/* Function: al_get_native_file_dialog_path + */ +const char *al_get_native_file_dialog_path( + const ALLEGRO_FILECHOOSER *dialog, size_t i) +{ + const ALLEGRO_NATIVE_DIALOG *fc = (const ALLEGRO_NATIVE_DIALOG *)dialog; + if (i < fc->fc_path_count) + return al_path_cstr(fc->fc_paths[i], ALLEGRO_NATIVE_PATH_SEP); + return NULL; +} + +/* Function: al_destroy_native_file_dialog + */ +void al_destroy_native_file_dialog(ALLEGRO_FILECHOOSER *dialog) +{ + ALLEGRO_NATIVE_DIALOG *fd = (ALLEGRO_NATIVE_DIALOG *)dialog; + size_t i; + + if (!fd) + return; + + _al_unregister_destructor(_al_dtor_list, fd->dtor_item); + + al_ustr_free(fd->title); + al_destroy_path(fd->fc_initial_path); + for (i = 0; i < fd->fc_path_count; i++) { + al_destroy_path(fd->fc_paths[i]); + } + al_free(fd->fc_paths); + al_ustr_free(fd->fc_patterns); + al_free(fd); +} + +/* Function: al_show_native_message_box + */ +int al_show_native_message_box(ALLEGRO_DISPLAY *display, + char const *title, char const *heading, char const *text, + char const *buttons, int flags) +{ + ALLEGRO_NATIVE_DIALOG *fc; + int r; + + ASSERT(title); + ASSERT(heading); + ASSERT(text); + + /* Note: the message box code cannot assume that Allegro is installed. + * al_malloc and ustr functions are okay (with the assumption that the + * user doesn't change the memory management functions in another thread + * while this message box is open). + */ + + fc = al_calloc(1, sizeof *fc); + + fc->title = al_ustr_new(title); + fc->mb_heading = al_ustr_new(heading); + fc->mb_text = al_ustr_new(text); + fc->mb_buttons = al_ustr_new(buttons); + fc->flags = flags; + + r = _al_show_native_message_box(display, fc); + + al_ustr_free(fc->title); + al_ustr_free(fc->mb_heading); + al_ustr_free(fc->mb_text); + al_ustr_free(fc->mb_buttons); + al_free(fc); + + return r; +} + +/* Function: al_get_allegro_native_dialog_version + */ +uint32_t al_get_allegro_native_dialog_version(void) +{ + return ALLEGRO_VERSION_INT; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/gtk_dialog.c b/allegro/addons/native_dialog/gtk_dialog.c new file mode 100644 index 00000000..718d4446 --- /dev/null +++ b/allegro/addons/native_dialog/gtk_dialog.c @@ -0,0 +1,66 @@ +#include <gtk/gtk.h> +#include <gdk/gdkx.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog_cfg.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "gtk_dialog.h" +#include "gtk_xgtk.h" + +ALLEGRO_DEBUG_CHANNEL("gtk_dialog") + + +bool _al_init_native_dialog_addon(void) +{ + int argc = 0; + char **argv = NULL; + gdk_set_allowed_backends("x11"); + if (!gtk_init_check(&argc, &argv)) { + ALLEGRO_ERROR("gtk_init_check failed\n"); + return false; + } + + return _al_gtk_set_display_overridable_interface(true); +} + + +void _al_shutdown_native_dialog_addon(void) +{ + _al_gtk_set_display_overridable_interface(false); +} + +static void really_make_transient(GtkWidget *window, ALLEGRO_DISPLAY_XGLX *glx) +{ + + GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(window)); + GdkDisplay *gdk = GDK_DISPLAY(gdk_window_get_display(gdk_window)); + + GdkWindow *parent = gdk_x11_window_lookup_for_display(gdk, glx->window); + if (!parent) + parent = gdk_x11_window_foreign_new_for_display(gdk, glx->window); + + if (gdk_window != NULL) + gdk_window_set_transient_for(gdk_window, parent); +} + +static void realized(GtkWidget *window, gpointer data) +{ + really_make_transient(window, (void *)data); +} + + +void _al_gtk_make_transient(ALLEGRO_DISPLAY *display, GtkWidget *window) +{ + /* Set the current display window (if any) as the parent of the dialog. */ + ALLEGRO_DISPLAY_XGLX *glx = (void *)display; + if (glx) { + if (!gtk_widget_get_realized(window)) + g_signal_connect(window, "realize", G_CALLBACK(realized), (void *)glx); + else + really_make_transient(window, glx); + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/gtk_dialog.h b/allegro/addons/native_dialog/gtk_dialog.h new file mode 100644 index 00000000..95c368aa --- /dev/null +++ b/allegro/addons/native_dialog/gtk_dialog.h @@ -0,0 +1,39 @@ +#ifndef __al_included_gtk_dialog_h +#define __al_included_gtk_dialog_h + +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" + +#define ACK_OK ((void *)0x1111) +#define ACK_ERROR ((void *)0x2222) +#define ACK_OPENED ((void *)0x3333) +#define ACK_CLOSED ((void *)0x4444) + +void _al_gtk_make_transient(ALLEGRO_DISPLAY *display, GtkWidget *window); + + +bool _al_gtk_ensure_thread(void); + + +/* The API is assumed to be synchronous, but the user calls will not be + * on the GTK thread. The following structure is used to pass data from the + * user thread to the GTK thread, and then wait until the GTK has processed it. + */ +typedef struct ARGS_BASE ARGS_BASE; + +struct ARGS_BASE +{ + ALLEGRO_MUTEX *mutex; + ALLEGRO_COND *cond; + bool done; + bool response; +}; + + +bool _al_gtk_init_args(void *ptr, size_t size); +bool _al_gtk_wait_for_args(GSourceFunc func, void *data); +void *_al_gtk_lock_args(gpointer data); +gboolean _al_gtk_release_args(gpointer data); + +#endif diff --git a/allegro/addons/native_dialog/gtk_filesel.c b/allegro/addons/native_dialog/gtk_filesel.c new file mode 100644 index 00000000..4976736a --- /dev/null +++ b/allegro/addons/native_dialog/gtk_filesel.c @@ -0,0 +1,180 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * GTK native dialog implementation. + * + * See LICENSE.txt for copyright information. + */ + +#include <gtk/gtk.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "gtk_dialog.h" +#include "gtk_xgtk.h" + +typedef struct { + ALLEGRO_DISPLAY *display; + ALLEGRO_NATIVE_DIALOG *dialog; +} GTK_FILE_DIALOG_MESSAGE; + +/* [nd_gtk thread] */ +static gboolean create_gtk_file_dialog(gpointer data) +{ + GTK_FILE_DIALOG_MESSAGE *msg = data; + ALLEGRO_DISPLAY *display = msg->display; + ALLEGRO_NATIVE_DIALOG *fd = msg->dialog; + bool save = fd->flags & ALLEGRO_FILECHOOSER_SAVE; + bool folder = fd->flags & ALLEGRO_FILECHOOSER_FOLDER; + gint result; + + GtkWidget *window; + + window = + gtk_file_chooser_dialog_new(al_cstr(fd->title), + NULL, + save ? GTK_FILE_CHOOSER_ACTION_SAVE : folder ? GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : GTK_FILE_CHOOSER_ACTION_OPEN, + "_Cancel", GTK_RESPONSE_CANCEL, + save ? "_Save" : "_Open", GTK_RESPONSE_ACCEPT, NULL); + + _al_gtk_make_transient(display, window); + + if (save) { + gtk_file_chooser_set_do_overwrite_confirmation + (GTK_FILE_CHOOSER(window), true); + } + + if (fd->fc_initial_path) { + bool is_dir; + bool exists; + const char *path = al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP); + + if (al_filename_exists(path)) { + exists = true; + ALLEGRO_FS_ENTRY *fs = al_create_fs_entry(path); + is_dir = al_get_fs_entry_mode(fs) & ALLEGRO_FILEMODE_ISDIR; + al_destroy_fs_entry(fs); + } + else { + exists = false; + is_dir = false; + } + + if (is_dir) { + gtk_file_chooser_set_current_folder + (GTK_FILE_CHOOSER(window), + al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP)); + } + else if (exists) { + gtk_file_chooser_set_filename + (GTK_FILE_CHOOSER(window), + al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP)); + } + else { + ALLEGRO_PATH *dir_path = al_clone_path(fd->fc_initial_path); + if (dir_path) { + al_set_path_filename(dir_path, NULL); + gtk_file_chooser_set_current_folder + (GTK_FILE_CHOOSER(window), + al_path_cstr(dir_path, ALLEGRO_NATIVE_PATH_SEP)); + if (save) { + gtk_file_chooser_set_current_name + (GTK_FILE_CHOOSER(window), + al_get_path_filename(fd->fc_initial_path)); + } + al_destroy_path(dir_path); + } + } + } + + if (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(window), true); + + /* FIXME: Move all this filter parsing stuff into a common file. */ + if (al_ustr_size(fd->fc_patterns) > 0) { + GtkFileFilter* filter = gtk_file_filter_new(); + int start = 0; + int end = 0; + bool is_mime_type = false; + while (true) { + int32_t c = al_ustr_get(fd->fc_patterns, end); + if (c < 0 || c == ';') { + if (end - start > 0) { + ALLEGRO_USTR* pattern = al_ustr_dup_substr(fd->fc_patterns, start, end); + if (is_mime_type) { + gtk_file_filter_add_mime_type(filter, al_cstr(pattern)); + } + else { + gtk_file_filter_add_pattern(filter, al_cstr(pattern)); + } + al_ustr_free(pattern); + } + start = end + 1; + is_mime_type = false; + } + if (c == '/') + is_mime_type = true; + if (c < 0) + break; + end += al_utf8_width(c); + } + + gtk_file_filter_set_name(filter, "All supported files"); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(window), filter); + } + + result = gtk_dialog_run(GTK_DIALOG(window)); + if (result == GTK_RESPONSE_ACCEPT) { + GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(window)); + int i; + GSList* iter; + + fd->fc_path_count = g_slist_length(filenames); + fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *)); + for (i = 0, iter = filenames; i < (int)fd->fc_path_count; i++, iter = g_slist_next(iter)) { + fd->fc_paths[i] = al_create_path((const char*)iter->data); + g_free(iter->data); + } + g_slist_free(filenames); + } + + gtk_widget_destroy(window); + + ASSERT(fd->async_queue); + g_async_queue_push(fd->async_queue, ACK_CLOSED); + + return FALSE; +} + +/* [user thread] */ +bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd) +{ + GTK_FILE_DIALOG_MESSAGE msg; + + if (!_al_gtk_ensure_thread()) + return false; + + fd->async_queue = g_async_queue_new(); + + msg.display = display; + msg.dialog = fd; + g_timeout_add(0, create_gtk_file_dialog, &msg); + + /* Wait for a signal that the window is closed. */ + while (g_async_queue_pop(fd->async_queue) != ACK_CLOSED) + ; + g_async_queue_unref(fd->async_queue); + fd->async_queue = NULL; + return true; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/gtk_menu.c b/allegro/addons/native_dialog/gtk_menu.c new file mode 100644 index 00000000..a0b645b0 --- /dev/null +++ b/allegro/addons/native_dialog/gtk_menu.c @@ -0,0 +1,425 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * GTK native dialog implementation. + * + * See LICENSE.txt for copyright information. + */ + +#include <gtk/gtk.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog_cfg.h" +#include "gtk_dialog.h" +#include "gtk_xgtk.h" + +ALLEGRO_DEBUG_CHANNEL("menu") + +typedef struct ARGS ARGS; + +struct ARGS +{ + /* Must be first. */ + ARGS_BASE base; + + GtkWidget *gtk_window; + ALLEGRO_MENU *menu; + ALLEGRO_MENU_ITEM *item; + int i; +}; + + +static void build_menu(GtkWidget *gmenu, ALLEGRO_MENU *amenu); + +/* [user thread] */ +static bool clear_menu_extras(ALLEGRO_MENU *menu, ALLEGRO_MENU_ITEM *item, int index, void *extra) +{ + (void) index; + (void) extra; + + if (item) + item->extra1 = NULL; + else + menu->extra1 = NULL; + + return false; +} + +/* [user thread] */ +static bool make_menu_item_args(ARGS *args, ALLEGRO_MENU_ITEM *item, int i) +{ + if (_al_gtk_init_args(args, sizeof(*args))) { + args->item = item; + args->i = i; + return true; + } + return false; +} + +/* [gtk thread] */ +static void menuitem_response(ALLEGRO_MENU_ITEM *menu_item) +{ + if (menu_item->parent) + _al_emit_menu_event(menu_item->parent->display, menu_item->unique_id); +} + +/* [gtk thread] */ +static void checkbox_on_toggle(ALLEGRO_MENU_ITEM *item) +{ + /* make sure the menu item remains the same state */ + if (gtk_check_menu_item_get_active(item->extra1)) { + item->flags |= ALLEGRO_MENU_ITEM_CHECKED; + } + else { + item->flags &= ~ALLEGRO_MENU_ITEM_CHECKED; + } +} + +/* [gtk thread] */ +static GtkWidget *build_menu_item(ALLEGRO_MENU_ITEM *aitem) +{ + GtkWidget *gitem; + + if (!aitem->caption) { + gitem = gtk_separator_menu_item_new(); + } + else { + ALLEGRO_USTR *caption = al_ustr_dup(aitem->caption); + + /* convert & to _ using unprintable chars as placeholders */ + al_ustr_find_replace_cstr(caption, 0, "_", "\x01\x02"); + al_ustr_find_replace_cstr(caption, 0, "&", "_"); + al_ustr_find_replace_cstr(caption, 0, "\x01\x02", "__"); + + if (aitem->flags & ALLEGRO_MENU_ITEM_CHECKBOX) { + gitem = gtk_check_menu_item_new_with_mnemonic(al_cstr(caption)); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gitem), aitem->flags & ALLEGRO_MENU_ITEM_CHECKED); + g_signal_connect_swapped (gitem, "toggled", G_CALLBACK(checkbox_on_toggle), + (gpointer) aitem); + } + else { + /* always create an image menu item, in case the user ever sets an icon */ + gitem = gtk_menu_item_new_with_mnemonic(al_cstr(caption)); + + } + + al_ustr_free(caption); + + gtk_widget_set_sensitive(gitem, !(aitem->flags & ALLEGRO_MENU_ITEM_DISABLED)); + + aitem->extra1 = gitem; + + if (aitem->popup) { + GtkWidget *gsubmenu = gtk_menu_new(); + build_menu(gsubmenu, aitem->popup); + aitem->popup->extra1 = gsubmenu; + gtk_widget_show(gsubmenu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(gitem), gsubmenu); + } + else if (aitem->id) { + g_signal_connect_swapped (gitem, "activate", + G_CALLBACK(menuitem_response), (gpointer) aitem); + } + } + + gtk_widget_show(gitem); + + return gitem; +} + +/* [gtk thread] */ +static void build_menu(GtkWidget *gmenu, ALLEGRO_MENU *amenu) +{ + size_t i; + + for (i = 0; i < _al_vector_size(&amenu->items); ++i) { + ALLEGRO_MENU_ITEM *aitem = * (ALLEGRO_MENU_ITEM **) _al_vector_ref(&amenu->items, i); + GtkWidget *gitem = build_menu_item(aitem); + gtk_menu_shell_append(GTK_MENU_SHELL(gmenu), gitem); + } +} + +/* [user thread] */ +bool _al_init_menu(ALLEGRO_MENU *menu) +{ + (void) menu; + + /* Do nothing here, because menu creation is defered until it is displayed. */ + + return true; +} + +/* [user thread] */ +bool _al_init_popup_menu(ALLEGRO_MENU *menu) +{ + return _al_init_menu(menu); +} + +/* [gtk thread] */ +static gboolean do_destroy_menu(gpointer data) +{ + ARGS *args = _al_gtk_lock_args(data); + + gtk_widget_destroy(args->menu->extra1); + args->menu->extra1 = NULL; + + return _al_gtk_release_args(args); +} + +/* [user thread] */ +bool _al_destroy_menu(ALLEGRO_MENU *menu) +{ + ARGS args; + + if (!menu->extra1) + return true; + + if (!_al_gtk_init_args(&args, sizeof(args))) + return false; + + args.menu = menu; + _al_gtk_wait_for_args(do_destroy_menu, &args); + + _al_walk_over_menu(menu, clear_menu_extras, NULL); + + return true; +} + +/* [gtk thread] */ +static gboolean do_insert_menu_item_at(gpointer data) +{ + ARGS *args = _al_gtk_lock_args(data); + if (!args->item->extra1) { + args->item->extra1 = build_menu_item(args->item); + } + gtk_menu_shell_insert(GTK_MENU_SHELL(args->item->parent->extra1), args->item->extra1, args->i); + + return _al_gtk_release_args(data); +} + +/* [user thread] */ +bool _al_insert_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + if (item->parent->extra1) { + ARGS args; + + if (!_al_gtk_init_args(&args, sizeof(args))) + return false; + + args.item = item; + args.i = i; + + _al_gtk_wait_for_args(do_insert_menu_item_at, &args); + } + + return true; +} + +/* [gtk thread] */ +static gboolean do_destroy_menu_item_at(gpointer data) +{ + ARGS *args = _al_gtk_lock_args(data); + + gtk_widget_destroy(GTK_WIDGET(args->item->extra1)); + args->item->extra1 = NULL; + + return _al_gtk_release_args(args); +} + +/* [user thread] */ +bool _al_destroy_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + if (item->extra1) { + ARGS args; + + if (!make_menu_item_args(&args, item, i)) + return false; + + _al_gtk_wait_for_args(do_destroy_menu_item_at, &args); + + if (item->popup) { + /* if this has a submenu, then deleting this item will have automatically + deleted all of its GTK widgets */ + _al_walk_over_menu(item->popup, clear_menu_extras, NULL); + } + } + return true; +} + +/* [gtk thread] */ +static gboolean do_update_menu_item_at(gpointer data) +{ + ARGS *args = _al_gtk_lock_args(data); + GtkWidget *gitem; + + gtk_widget_destroy(args->item->extra1); + args->item->extra1 = NULL; + + gitem = build_menu_item(args->item); + gtk_menu_shell_insert(GTK_MENU_SHELL(args->item->parent->extra1), gitem, args->i); + + return _al_gtk_release_args(args); +} + +/* [user thread] */ +bool _al_update_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + if (item->extra1) { + ARGS args; + + if (!make_menu_item_args(&args, item, i)) + return false; + + _al_gtk_wait_for_args(do_update_menu_item_at, &args); + } + return true; +} + +/* [gtk thread] */ +static gboolean do_show_display_menu(gpointer data) +{ + ARGS *args = _al_gtk_lock_args(data); + + if (!args->menu->extra1) { + GtkWidget *menu_bar = gtk_menu_bar_new(); + + build_menu(menu_bar, args->menu); + + GtkWidget *vbox = gtk_bin_get_child(GTK_BIN(args->gtk_window)); + gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 0); + gtk_widget_show(menu_bar); + + args->menu->extra1 = menu_bar; + } + + gtk_widget_show(gtk_widget_get_parent(args->menu->extra1)); + + return _al_gtk_release_args(args); +} + +/* [user thread] */ +bool _al_show_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + GtkWidget *gtk_window; + ARGS args; + + gtk_window = _al_gtk_get_window(display); + if (!gtk_window) { + return false; + } + + if (!_al_gtk_init_args(&args, sizeof(args))) { + return false; + } + + args.gtk_window = gtk_window; + args.menu = menu; + + return _al_gtk_wait_for_args(do_show_display_menu, &args); +} + +/* [gtk thread] */ +static gboolean do_hide_display_menu(gpointer data) +{ + ARGS *args = _al_gtk_lock_args(data); + + gtk_widget_destroy(GTK_WIDGET(args->menu->extra1)); + args->menu->extra1 = NULL; + + return _al_gtk_release_args(data); +} + +/* [user thread] */ +bool _al_hide_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + GtkWidget *gtk_window; + ARGS args; + + if (!(gtk_window = _al_gtk_get_window(display))) + return false; + + if (!_al_gtk_init_args(&args, sizeof(args))) + return false; + + args.gtk_window = gtk_window; + args.menu = menu; + _al_gtk_wait_for_args(do_hide_display_menu, &args); + _al_walk_over_menu(menu, clear_menu_extras, NULL); + + return true; +} + +/* [gtk thread] */ +static void popop_on_hide(ALLEGRO_MENU *menu) +{ + (void) menu; + /* in case we want to notify on popup close */ +} + +/* [gtk thread] */ +static gboolean do_show_popup_menu(gpointer data) +{ + ARGS *args = (ARGS *) data; + + _al_gtk_lock_args(args); + + GtkWidget *menu = NULL; + if (!args->menu->extra1) { + menu = gtk_menu_new(); + + build_menu(menu, args->menu); + + gtk_widget_show(menu); + args->menu->extra1 = menu; + + g_signal_connect_swapped (menu, "hide", + G_CALLBACK(popop_on_hide), (gpointer) args->menu); + } + + bool position_called = false; + if (menu) + gtk_menu_popup_at_widget(args->menu->extra1, menu, GDK_GRAVITY_SOUTH_WEST, + GDK_GRAVITY_NORTH_WEST, + NULL); + + if (!position_called) { + ALLEGRO_DEBUG("Position canary not called, most likely the menu didn't show " + "up due to outstanding mouse events.\n"); + } + args->base.response = position_called; + + _al_gtk_release_args(args); + + return FALSE; +} + +bool _al_show_popup_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + ARGS args; + (void)display; + + if (!_al_gtk_init_args(&args, sizeof(args))) { + return false; + } + + args.gtk_window = NULL; + args.menu = menu; + + return _al_gtk_wait_for_args(do_show_popup_menu, &args); +} + +int _al_get_menu_display_height(void) +{ + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/gtk_msgbox.c b/allegro/addons/native_dialog/gtk_msgbox.c new file mode 100644 index 00000000..06de91c8 --- /dev/null +++ b/allegro/addons/native_dialog/gtk_msgbox.c @@ -0,0 +1,144 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * GTK native dialog implementation. + * + * See LICENSE.txt for copyright information. + */ + +#include <gtk/gtk.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "gtk_dialog.h" +#include "gtk_xgtk.h" + + +typedef struct { + ALLEGRO_DISPLAY *display; + ALLEGRO_NATIVE_DIALOG *dialog; +} Msg; + + +/* Note: the message box code cannot assume that Allegro is installed. */ + +static void msgbox_destroy(GtkWidget *w, gpointer data) +{ + ALLEGRO_NATIVE_DIALOG *nd = data; + (void)w; + + ASSERT(nd->async_queue); + g_async_queue_push(nd->async_queue, ACK_CLOSED); +} + +static void msgbox_response(GtkDialog *dialog, gint response_id, + gpointer user_data) +{ + ALLEGRO_NATIVE_DIALOG *nd = (void *)user_data; + (void)dialog; + switch (response_id) { + case GTK_RESPONSE_DELETE_EVENT: + nd->mb_pressed_button = 0; + break; + case GTK_RESPONSE_YES: + case GTK_RESPONSE_OK: + nd->mb_pressed_button = 1; + break; + case GTK_RESPONSE_NO: + case GTK_RESPONSE_CANCEL: + nd->mb_pressed_button = 2; + break; + default: + nd->mb_pressed_button = response_id; + } +} + +/* [gtk thread] */ +static gboolean create_native_message_box(gpointer data) +{ + Msg *msg = data; + ALLEGRO_DISPLAY *display = msg->display; + ALLEGRO_NATIVE_DIALOG *fd = msg->dialog; + GtkWidget *window; + + /* Create a new file selection widget */ + GtkMessageType type = GTK_MESSAGE_INFO; + GtkButtonsType buttons = GTK_BUTTONS_OK; + if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) type = GTK_MESSAGE_QUESTION; + if (fd->flags & ALLEGRO_MESSAGEBOX_QUESTION) type = GTK_MESSAGE_QUESTION; + if (fd->flags & ALLEGRO_MESSAGEBOX_WARN) type = GTK_MESSAGE_WARNING; + if (fd->flags & ALLEGRO_MESSAGEBOX_ERROR) type = GTK_MESSAGE_ERROR; + if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) buttons = GTK_BUTTONS_YES_NO; + if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) buttons = GTK_BUTTONS_OK_CANCEL; + if (fd->mb_buttons) buttons = GTK_BUTTONS_NONE; + + window = gtk_message_dialog_new(NULL, 0, type, buttons, "%s", + al_cstr(fd->mb_heading)); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(window), "%s", + al_cstr(fd->mb_text)); + + _al_gtk_make_transient(display, window); + + if (fd->mb_buttons) { + int i = 1; + int pos = 0; + while (1) { + int next = al_ustr_find_chr(fd->mb_buttons, pos, '|'); + int pos2 = next; + if (next == -1) + pos2 = al_ustr_size(fd->mb_buttons); + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *button_text; + button_text = al_ref_ustr(&info, fd->mb_buttons, pos, pos2); + pos = pos2 + 1; + char buffer[256]; + al_ustr_to_buffer(button_text, buffer, sizeof buffer); + gtk_dialog_add_button(GTK_DIALOG(window), buffer, i++); + if (next == -1) + break; + } + } + + gtk_window_set_title(GTK_WINDOW(window), al_cstr(fd->title)); + + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(msgbox_destroy), fd); + + g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(msgbox_response), fd); + g_signal_connect_swapped(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), window); + + gtk_widget_show(window); + return FALSE; +} + +/* [user thread] */ +int _al_show_native_message_box(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd) +{ + Msg msg; + + if (!_al_gtk_ensure_thread()) + return 0; /* "cancelled" */ + + fd->async_queue = g_async_queue_new(); + + msg.display = display; + msg.dialog = fd; + g_timeout_add(0, create_native_message_box, &msg); + + /* Wait for a signal that the window is closed. */ + while (g_async_queue_pop(fd->async_queue) != ACK_CLOSED) + ; + g_async_queue_unref(fd->async_queue); + fd->async_queue = NULL; + return fd->mb_pressed_button; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/gtk_textlog.c b/allegro/addons/native_dialog/gtk_textlog.c new file mode 100644 index 00000000..ed21fd51 --- /dev/null +++ b/allegro/addons/native_dialog/gtk_textlog.c @@ -0,0 +1,215 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * GTK native dialog implementation. + * + * See LICENSE.txt for copyright information. + */ + +#include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "gtk_dialog.h" +#include "gtk_xgtk.h" + + +typedef struct { + ALLEGRO_NATIVE_DIALOG *dialog; +} Msg; + + +static void emit_close_event(ALLEGRO_NATIVE_DIALOG *textlog, bool keypress) +{ + ALLEGRO_EVENT event; + event.user.type = ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE; + event.user.timestamp = al_get_time(); + event.user.data1 = (intptr_t)textlog; + event.user.data2 = (intptr_t)keypress; + al_emit_user_event(&textlog->tl_events, &event, NULL); +} + +static gboolean textlog_delete(GtkWidget *w, GdkEvent *gevent, + gpointer userdata) +{ + ALLEGRO_NATIVE_DIALOG *textlog = userdata; + (void)w; + (void)gevent; + + if (!(textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE)) { + emit_close_event(textlog, false); + } + + /* Don't close the window. */ + return TRUE; +} + +static gboolean textlog_key_press(GtkWidget *w, GdkEventKey *gevent, + gpointer userdata) +{ + ALLEGRO_NATIVE_DIALOG *textlog = userdata; + (void)w; + + if (gevent->keyval == GDK_KEY_Escape) { + emit_close_event(textlog, true); + } + + return FALSE; +} + +static void textlog_destroy(GtkWidget *w, gpointer data) +{ + ALLEGRO_NATIVE_DIALOG *nd = data; + (void)w; + + ASSERT(nd->async_queue); + g_async_queue_push(nd->async_queue, ACK_CLOSED); +} + +/* [gtk thread] */ +static gboolean create_native_text_log(gpointer data) +{ + Msg *msg = data; + ALLEGRO_NATIVE_DIALOG *textlog = msg->dialog; + GtkCssProvider *css_provider; + GtkStyleContext *context; + + /* Create a new text log window. */ + GtkWidget *top = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size(GTK_WINDOW(top), 640, 480); + gtk_window_set_title(GTK_WINDOW(top), al_cstr(textlog->title)); + + if (textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE) { + gtk_window_set_deletable(GTK_WINDOW(top), false); + } + else { + g_signal_connect(G_OBJECT(top), "key-press-event", G_CALLBACK(textlog_key_press), textlog); + } + g_signal_connect(G_OBJECT(top), "delete-event", G_CALLBACK(textlog_delete), textlog); + g_signal_connect(G_OBJECT(top), "destroy", G_CALLBACK(textlog_destroy), textlog); + GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(top), scroll); + GtkWidget *view = gtk_text_view_new(); + gtk_text_view_set_editable(GTK_TEXT_VIEW(view), false); + gtk_widget_set_name(GTK_WIDGET(view), "native_text_log"); + if (textlog->flags & ALLEGRO_TEXTLOG_MONOSPACE) { + css_provider = gtk_css_provider_new(); + gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(css_provider), + "#native_text_log {\n" + " font-family: monospace;\n" + "}\n", -1, NULL); + context = gtk_widget_get_style_context(GTK_WIDGET(view)); + gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + g_object_unref(css_provider); + } + gtk_container_add(GTK_CONTAINER(scroll), view); + gtk_widget_show(view); + gtk_widget_show(scroll); + gtk_widget_show(top); + textlog->window = top; + textlog->tl_textview = view; + + ASSERT(textlog->async_queue); + g_async_queue_push(textlog->async_queue, ACK_OPENED); + return FALSE; +} + +/* [user thread] */ +bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + Msg msg; + + if (!_al_gtk_ensure_thread()) { + textlog->tl_init_error = true; + return false; + } + + textlog->async_queue = g_async_queue_new(); + + msg.dialog = textlog; + g_timeout_add(0, create_native_text_log, &msg); + + while (g_async_queue_pop(textlog->async_queue) != ACK_OPENED) + ; + + return true; +} + +/* [gtk thread] */ +static gboolean do_append_native_text_log(gpointer data) +{ + ALLEGRO_NATIVE_DIALOG *textlog = data; + al_lock_mutex(textlog->tl_text_mutex); + + GtkTextView *tv = GTK_TEXT_VIEW(textlog->tl_textview); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(tv); + GtkTextIter iter; + GtkTextMark *mark; + + gtk_text_buffer_get_end_iter(buffer, &iter); + gtk_text_buffer_insert(buffer, &iter, al_cstr(textlog->tl_pending_text), -1); + + mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE); + gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(textlog->tl_textview), mark); + gtk_text_buffer_delete_mark(buffer, mark); + + al_ustr_truncate(textlog->tl_pending_text, 0); + + textlog->tl_have_pending = false; + + al_unlock_mutex(textlog->tl_text_mutex); + return FALSE; +} + +/* [user thread] */ +void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + if (textlog->tl_have_pending) + return; + textlog->tl_have_pending = true; + + gdk_threads_add_timeout(100, do_append_native_text_log, textlog); +} + +/* [gtk thread] */ +static gboolean do_close_native_text_log(gpointer data) +{ + ALLEGRO_NATIVE_DIALOG *textlog = data; + + /* Delay closing until appends are completed. */ + if (textlog->tl_have_pending) { + return TRUE; + } + + /* This causes the GTK window as well as all of its children to + * be freed. Further it will call the destroy function which we + * connected to the destroy signal which in turn causes our + * gtk thread to quit. + */ + gtk_widget_destroy(textlog->window); + return FALSE; +} + +/* [user thread] */ +void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + gdk_threads_add_timeout(0, do_close_native_text_log, textlog); + + while (g_async_queue_pop(textlog->async_queue) != ACK_CLOSED) + ; + g_async_queue_unref(textlog->async_queue); + textlog->async_queue = NULL; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/gtk_thread.c b/allegro/addons/native_dialog/gtk_thread.c new file mode 100644 index 00000000..37c4ffa8 --- /dev/null +++ b/allegro/addons/native_dialog/gtk_thread.c @@ -0,0 +1,170 @@ +#include <gtk/gtk.h> + +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog_cfg.h" +#include "gtk_dialog.h" + +#include "allegro5/internal/aintern_vector.h" + +ALLEGRO_DEBUG_CHANNEL("gtk") + + +/* GTK is not thread safe. We launch a single thread which runs the GTK main + * loop, and it is the only thread which calls into GTK. (g_timeout_add may be + * called from other threads without locking.) + * + * We used to attempt to use gdk_threads_enter/gdk_threads_leave but hit + * some problems with deadlocks so switched to this. + */ + +// G_STATIC_MUTEX_INIT causes a warning about a missing initializer, so if we +// have version 2.32 or newer don't use it to avoid the warning. +#if GLIB_CHECK_VERSION(2, 32, 0) + #define NEWER_GLIB 1 +#else + #define NEWER_GLIB 0 +#endif +#if NEWER_GLIB + static GMutex nd_gtk_mutex; + static void nd_gtk_lock(void) { g_mutex_lock(&nd_gtk_mutex); } + static void nd_gtk_unlock(void) { g_mutex_unlock(&nd_gtk_mutex); } +#else + static GStaticMutex nd_gtk_mutex = G_STATIC_MUTEX_INIT; + static void nd_gtk_lock(void) { g_static_mutex_lock(&nd_gtk_mutex); } + static void nd_gtk_unlock(void) { g_static_mutex_unlock(&nd_gtk_mutex); } +#endif +static GThread *nd_gtk_thread = NULL; + + +static void *nd_gtk_thread_func(void *data) +{ + GAsyncQueue *queue = data; + + ALLEGRO_DEBUG("GLIB %d.%d.%d\n", + GLIB_MAJOR_VERSION, + GLIB_MINOR_VERSION, + GLIB_MICRO_VERSION); + + g_async_queue_push(queue, ACK_OK); + + gtk_main(); + + ALLEGRO_INFO("GTK stopped.\n"); + return NULL; +} + + +bool _al_gtk_ensure_thread(void) +{ + bool ok = true; + +#if !NEWER_GLIB + if (!g_thread_supported()) + g_thread_init(NULL); +#endif + + /* al_init_native_dialog_addon() didn't always exist so GTK might not have + * been initialised. gtk_init_check knows if it's been initialised already + * so we can just call it again. + */ + { + int argc = 0; + char **argv = NULL; + if (!gtk_init_check(&argc, &argv)) { + ALLEGRO_ERROR("gtk_init_check failed\n"); + return false; + } + } + + nd_gtk_lock(); + + if (!nd_gtk_thread) { + GAsyncQueue *queue = g_async_queue_new(); +#if NEWER_GLIB + nd_gtk_thread = g_thread_new("gtk thread", nd_gtk_thread_func, queue); +#else + bool joinable = FALSE; + nd_gtk_thread = g_thread_create(nd_gtk_thread_func, queue, joinable, NULL); +#endif + if (!nd_gtk_thread) { + ok = false; + } + else { + ok = (g_async_queue_pop(queue) == ACK_OK); + } + g_async_queue_unref(queue); + } + + nd_gtk_unlock(); + + return ok; +} + + +/* [user thread] */ +bool _al_gtk_init_args(void *ptr, size_t size) +{ + ARGS_BASE *args = (ARGS_BASE *)ptr; + memset(args, 0, size); + args->mutex = al_create_mutex(); + if (!args->mutex) { + return false; + } + args->cond = al_create_cond(); + if (!args->cond) { + al_destroy_mutex(args->mutex); + return false; + } + args->done = false; + args->response = true; + return args; +} + + +/* [user thread] */ +bool _al_gtk_wait_for_args(GSourceFunc func, void *data) +{ + ARGS_BASE *args = (ARGS_BASE *) data; + bool response; + + al_lock_mutex(args->mutex); + g_timeout_add(0, func, data); + while (args->done == false) { + al_wait_cond(args->cond, args->mutex); + } + al_unlock_mutex(args->mutex); + + response = args->response; + + al_destroy_mutex(args->mutex); + al_destroy_cond(args->cond); + + return response; +} + + +/* [gtk thread] */ +void *_al_gtk_lock_args(gpointer data) +{ + ARGS_BASE *args = (ARGS_BASE *) data; + al_lock_mutex(args->mutex); + return args; +} + + +/* [gtk thread] */ +gboolean _al_gtk_release_args(gpointer data) +{ + ARGS_BASE *args = (ARGS_BASE *) data; + + args->done = true; + al_signal_cond(args->cond); + al_unlock_mutex(args->mutex); + + return FALSE; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/gtk_xgtk.c b/allegro/addons/native_dialog/gtk_xgtk.c new file mode 100644 index 00000000..5780c658 --- /dev/null +++ b/allegro/addons/native_dialog/gtk_xgtk.c @@ -0,0 +1,452 @@ +#include <gtk/gtk.h> +#include <gtk/gtkx.h> + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_native_dialog_cfg.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xevents.h" +#include "allegro5/internal/aintern_xsystem.h" + +#include "gtk_dialog.h" +#include "gtk_xgtk.h" + +ALLEGRO_DEBUG_CHANNEL("gtk") + + +typedef struct ARGS_CREATE +{ + ARGS_BASE base; /* must be first */ + ALLEGRO_DISPLAY_XGLX *display; + int w; + int h; + const char *title; +} ARGS_CREATE; + +typedef struct +{ + ARGS_BASE base; /* must be first */ + ALLEGRO_DISPLAY_XGLX *display; + bool is_last; +} ARGS_DESTROY; + +typedef struct +{ + ARGS_BASE base; /* must be first */ + ALLEGRO_DISPLAY_XGLX *display; + int w; + int h; +} ARGS_RESIZE; + +typedef struct +{ + ARGS_BASE base; /* must be first */ + ALLEGRO_DISPLAY_XGLX *display; + const char *title; +} ARGS_TITLE; + +typedef struct +{ + ARGS_BASE base; /* must be first */ + ALLEGRO_DISPLAY_XGLX *display; + bool fullscreen; +} ARGS_FULLSCREEN_WINDOW; + +typedef struct +{ + ARGS_BASE base; /* must be first */ + ALLEGRO_DISPLAY_XGLX *display; + int x; + int y; +} ARGS_POSITION; + + +/* forward declarations */ +static gboolean xgtk_quit_callback(GtkWidget *widget, GdkEvent *event, + ALLEGRO_DISPLAY *display); +static gboolean xgtk_handle_configure_event(GtkWidget *widget, + GdkEventConfigure *event, ALLEGRO_DISPLAY *display); +static void xgtk_set_fullscreen_window(ALLEGRO_DISPLAY *display, bool onoff); + +static struct ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE xgtk_override_vt; + + +/* [gtk thread] */ +static gboolean do_create_display_hook(gpointer data) +{ + const ARGS_CREATE *args = _al_gtk_lock_args(data); + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)args->display; + ALLEGRO_DISPLAY_XGLX *d = args->display; + const int w = args->w; + const int h = args->h; + + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *socket; + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + d->gtk->gtkwindow = window; + gtk_window_set_default_size(GTK_WINDOW(window), w, h); + + g_signal_connect(G_OBJECT(window), "delete-event", + G_CALLBACK(xgtk_quit_callback), display); + g_signal_connect(G_OBJECT(window), "configure-event", + G_CALLBACK(xgtk_handle_configure_event), display); + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add(GTK_CONTAINER(window), vbox); + + socket = gtk_socket_new(); + d->gtk->gtksocket = socket; + gtk_box_pack_end(GTK_BOX(vbox), socket, TRUE, TRUE, 0); + gtk_socket_add_id(GTK_SOCKET(socket), d->window); + ALLEGRO_DEBUG("gtk_socket_add_id: window = %ld\n", d->window); + + gtk_window_set_title(GTK_WINDOW(window), args->title); + + gtk_widget_show_all(window); + + if (display->flags & ALLEGRO_RESIZABLE) { + /* Allow socket widget to be resized smaller than initial size. */ + gtk_widget_set_size_request(socket, -1, -1); + gtk_window_set_resizable(GTK_WINDOW(window), true); + } + else { + gtk_window_set_resizable(GTK_WINDOW(window), false); + } + + if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) { + gtk_window_fullscreen(GTK_WINDOW(window)); + } + + d->overridable_vt = &xgtk_override_vt; + + return _al_gtk_release_args(data); +} + + +/* [user thread] */ +static bool xgtk_create_display_hook(ALLEGRO_DISPLAY *display, int w, int h) +{ + ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; + ARGS_CREATE args; + + d->gtk = al_calloc(1, sizeof(*(d->gtk))); + if (!d->gtk) { + ALLEGRO_WARN("Out of memory\n"); + return false; + } + + if (!_al_gtk_ensure_thread()) { + al_free(d->gtk); + d->gtk = NULL; + return false; + } + + if (!_al_gtk_init_args(&args, sizeof(args))) { + al_free(d->gtk); + d->gtk = NULL; + return false; + } + + args.display = d; + args.w = w; + args.h = h; + args.title = al_get_new_window_title(); + + return _al_gtk_wait_for_args(do_create_display_hook, &args); +} + + +static gboolean xgtk_quit_callback(GtkWidget *widget, GdkEvent *event, + ALLEGRO_DISPLAY *display) +{ + (void)widget; + (void)event; + _al_display_xglx_closebutton(display, NULL); + return TRUE; +} + + +static gboolean xgtk_handle_configure_event(GtkWidget *widget, + GdkEventConfigure *event, ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; + (void)widget; + (void)event; + + /* Update our idea of the window position. + * event->x, event->y is incorrect. + */ + gtk_window_get_position(GTK_WINDOW(d->gtk->gtkwindow), &d->x, &d->y); + + return FALSE; +} + + +/* [gtk thread] */ +static gboolean do_destroy_display_hook(gpointer data) +{ + ARGS_DESTROY *args = _al_gtk_lock_args(data); + ALLEGRO_DISPLAY_XGLX *d = args->display; + bool is_last = args->is_last; + + gtk_widget_destroy(d->gtk->gtkwindow); + + if (is_last) { + gtk_main_quit(); + } + + return _al_gtk_release_args(data); +} + + +/* [user thread] */ +static void xgtk_destroy_display_hook(ALLEGRO_DISPLAY *display, bool is_last) +{ + ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; + ARGS_DESTROY args; + + if (!_al_gtk_init_args(&args, sizeof(args))) + return; + + args.display = d; + args.is_last = is_last; + + _al_gtk_wait_for_args(do_destroy_display_hook, &args); + + al_free(d->gtk); + d->gtk = NULL; +} + + +/* [gtk thread] */ +static gboolean do_resize_display1(gpointer data) +{ + ARGS_RESIZE *args = _al_gtk_lock_args(data); + ALLEGRO_DISPLAY_XGLX *d = args->display; + int w = args->w; + int h = args->h; + + /* Using gtk_window_resize by itself is wrong because it does not take + * into account the space occupied by other widgets in the window. + * + * Using gtk_widget_set_size_request by itself is also insufficient as it + * sets the *minimum* size. If the socket widget was already larger then + * it would do nothing. + */ + gtk_window_resize(GTK_WINDOW(d->gtk->gtkwindow), w, h); + gtk_widget_set_size_request(d->gtk->gtksocket, w, h); + + return _al_gtk_release_args(data); +} + + +/* [gtk thread] */ +static gboolean do_resize_display2(gpointer data) +{ + ARGS_RESIZE *args = _al_gtk_lock_args(data); + ALLEGRO_DISPLAY_XGLX *d = args->display; + + /* Remove the minimum size constraint again. */ + gtk_widget_set_size_request(d->gtk->gtksocket, -1, -1); + + return _al_gtk_release_args(data); +} + + +/* [user thread] */ +static bool xgtk_resize_display(ALLEGRO_DISPLAY *display, int w, int h) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; + bool ret = true; + + _al_mutex_lock(&system->lock); + + if (w != display->w || h != display->h) { + do { + const int old_resize_count = d->resize_count; + ARGS_RESIZE args; + + d->programmatic_resize = true; + + if (!_al_gtk_init_args(&args, sizeof(args))) { + ret = false; + break; + } + args.display = d; + args.w = w; + args.h = h; + _al_gtk_wait_for_args(do_resize_display1, &args); + + _al_display_xglx_await_resize(display, old_resize_count, false); + + if (_al_gtk_init_args(&args, sizeof(args))) { + args.display = d; + _al_gtk_wait_for_args(do_resize_display2, &args); + } + + d->programmatic_resize = false; + } while (0); + } + + _al_mutex_unlock(&system->lock); + + return ret; +} + + +/* [gtk thread] */ +static gboolean do_set_window_title(gpointer data) +{ + ARGS_TITLE *args = _al_gtk_lock_args(data); + ALLEGRO_DISPLAY_XGLX *d = args->display; + const char *title = args->title; + + gtk_window_set_title(GTK_WINDOW(d->gtk->gtkwindow), title); + + return _al_gtk_release_args(data); +} + + +/* [user thread] */ +static void xgtk_set_window_title(ALLEGRO_DISPLAY *display, const char *title) +{ + ARGS_TITLE args; + + if (_al_gtk_init_args(&args, sizeof(args))) { + args.display = (ALLEGRO_DISPLAY_XGLX *)display; + args.title = title; + _al_gtk_wait_for_args(do_set_window_title, &args); + } +} + + +/* [gtk thread] */ +static gboolean do_set_fullscreen_window(gpointer data) +{ + ARGS_FULLSCREEN_WINDOW *args = _al_gtk_lock_args(data); + ALLEGRO_DISPLAY_XGLX *d = args->display; + bool fullscreen = args->fullscreen; + + if (fullscreen) { + gtk_window_fullscreen(GTK_WINDOW(d->gtk->gtkwindow)); + } + else { + gtk_window_unfullscreen(GTK_WINDOW(d->gtk->gtkwindow)); + } + + return _al_gtk_release_args(args); +} + + +/* [user thread] */ +static void xgtk_set_fullscreen_window(ALLEGRO_DISPLAY *display, bool onoff) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; + + if (onoff == (display->flags & ALLEGRO_FULLSCREEN_WINDOW)) { + return; + } + + _al_mutex_lock(&system->lock); + { + int old_resize_count; + ARGS_FULLSCREEN_WINDOW args; + + display->flags ^= ALLEGRO_FULLSCREEN_WINDOW; + old_resize_count = d->resize_count; + d->programmatic_resize = true; + + if (_al_gtk_init_args(&args, sizeof(args))) { + args.display = d; + args.fullscreen = onoff; + _al_gtk_wait_for_args(do_set_fullscreen_window, &args); + + _al_display_xglx_await_resize(display, old_resize_count, + (display->flags & ALLEGRO_FULLSCREEN)); + } + + d->programmatic_resize = false; + } + _al_mutex_unlock(&system->lock); +} + + +/* [gtk thread] */ +static gboolean do_set_window_position(gpointer data) +{ + ARGS_POSITION *args = _al_gtk_lock_args(data); + + gtk_window_move(GTK_WINDOW(args->display->gtk->gtkwindow), + args->x, args->y); + + return _al_gtk_release_args(args); +} + + +/* [user thread] */ +static void xgtk_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +{ + ARGS_POSITION args; + + if (_al_gtk_init_args(&args, sizeof(args))) { + args.display = (ALLEGRO_DISPLAY_XGLX *)display; + args.x = x; + args.y = y; + _al_gtk_wait_for_args(do_set_window_position, &args); + } +} + + +/* [user thread] */ +static bool xgtk_set_window_constraints(ALLEGRO_DISPLAY *display, + int min_w, int min_h, int max_w, int max_h) +{ + // FIXME + (void)display; + (void)min_w; + (void)min_h; + (void)max_w; + (void)max_h; + return true; +} + + +static struct ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE xgtk_override_vt = +{ + xgtk_create_display_hook, + xgtk_destroy_display_hook, + xgtk_resize_display, + xgtk_set_window_title, + xgtk_set_fullscreen_window, + xgtk_set_window_position, + xgtk_set_window_constraints +}; + + +bool _al_gtk_set_display_overridable_interface(bool on) +{ + return _al_xwin_set_gtk_display_overridable_interface(ALLEGRO_VERSION_INT, + (on) ? &xgtk_override_vt : NULL); +} + + +GtkWidget *_al_gtk_get_window(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; + + if (d->overridable_vt == &xgtk_override_vt) { + return d->gtk->gtkwindow; + } + + ALLEGRO_WARN("Not display created with GTK.\n"); + return NULL; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/gtk_xgtk.h b/allegro/addons/native_dialog/gtk_xgtk.h new file mode 100644 index 00000000..213e1cf1 --- /dev/null +++ b/allegro/addons/native_dialog/gtk_xgtk.h @@ -0,0 +1,16 @@ +#ifndef __al_included_allegro5_native_dialog_gtk_xgtk_h +#define __al_included_allegro5_native_dialog_gtk_xgtk_h + +#include <gtk/gtk.h> + +struct ALLEGRO_DISPLAY_XGLX_GTK { + GtkWidget *gtkwindow; + GtkWidget *gtksocket; +}; + +bool _al_gtk_set_display_overridable_interface(bool on); +GtkWidget *_al_gtk_get_window(ALLEGRO_DISPLAY *display); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/iphone_dialog.m b/allegro/addons/native_dialog/iphone_dialog.m new file mode 100644 index 00000000..58c6700d --- /dev/null +++ b/allegro/addons/native_dialog/iphone_dialog.m @@ -0,0 +1,168 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" + +#include <UIKit/UIAlertView.h> + +#include "allegro5/allegro_iphone_objc.h" + +bool _al_init_native_dialog_addon(void) +{ + return true; +} + +void _al_shutdown_native_dialog_addon(void) +{ +} + +bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd) +{ + (void)display; + (void)fd; + return false; +} + +@interface AlertDelegate : NSObject<UIAlertViewDelegate> { + ALLEGRO_MUTEX *mutex; + ALLEGRO_COND *button_pressed; +} +@property ALLEGRO_MUTEX *mutex; +@property ALLEGRO_COND *button_pressed; +@end + +@implementation AlertDelegate +@synthesize mutex; +@synthesize button_pressed; +- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)bindex { + (void)alert; + (void)bindex; + al_lock_mutex(mutex); + al_signal_cond(button_pressed); + al_unlock_mutex(mutex); +} +- (void) createAlert:(NSArray*)array { + UIView *view = [array objectAtIndex:0]; + UIAlertView *alert = [array objectAtIndex:1]; + [view addSubview:alert]; + [alert show]; + [alert release]; +} + +@end + +int _al_show_native_message_box(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *nd) +{ + (void)display; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; + NSString *title = [NSString stringWithUTF8String:al_cstr(nd->title)]; + NSString *heading = [NSString stringWithUTF8String:al_cstr(nd->mb_heading)]; + NSString *text = [NSString stringWithUTF8String:al_cstr(nd->mb_text)]; + NSString *ok = [NSString stringWithUTF8String:"Ok"]; + NSString *message = [NSString stringWithFormat:@"%@\n\n%@", heading, text]; + + AlertDelegate *delegate = [[AlertDelegate alloc]init]; + delegate.mutex = al_create_mutex(); + delegate.button_pressed = al_create_cond(); + + // This needs to be done on the thread with the display due to TLS. + UIView *view = al_iphone_get_view(al_get_current_display()); + + UIAlertView *alert = [[UIAlertView alloc] + initWithTitle:title + message:message + delegate:delegate + cancelButtonTitle:ok + otherButtonTitles:nil]; + + [delegate performSelectorOnMainThread:@selector(createAlert:) + withObject:@[view,alert] + waitUntilDone:YES]; + + al_lock_mutex(delegate.mutex); + al_wait_cond(delegate.button_pressed, delegate.mutex); + al_unlock_mutex(delegate.mutex); + al_destroy_cond(delegate.button_pressed); + al_destroy_mutex(delegate.mutex); + + [delegate release]; + + [pool drain]; + return 0; +} + +bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + (void)textlog; + return false; +} + +void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + (void) textlog; +} + +void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + (void) textlog; +} + +bool _al_init_menu(ALLEGRO_MENU *menu) +{ + (void) menu; + return false; +} + +bool _al_init_popup_menu(ALLEGRO_MENU *menu) +{ + (void) menu; + return false; +} + +bool _al_insert_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + (void) item; + (void) i; + return false; +} + +bool _al_destroy_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + (void) item; + (void) i; + return false; +} + +bool _al_update_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + (void) item; + (void) i; + return false; +} + +bool _al_show_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + (void) display; + (void) menu; + return false; +} + +bool _al_hide_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + (void) display; + (void) menu; + return false; +} + +bool _al_show_popup_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + (void) display; + (void) menu; + return false; +} + +int _al_get_menu_display_height(void) +{ + return 0; +} diff --git a/allegro/addons/native_dialog/menu.c b/allegro/addons/native_dialog/menu.c new file mode 100644 index 00000000..a5ec0583 --- /dev/null +++ b/allegro/addons/native_dialog/menu.c @@ -0,0 +1,952 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_vector.h" + +/* DISPLAY_MENU keeps track of which menu is associated with a display */ +typedef struct DISPLAY_MENU DISPLAY_MENU; + +struct DISPLAY_MENU +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_MENU *menu; +}; + +static _AL_VECTOR display_menus = _AL_VECTOR_INITIALIZER(DISPLAY_MENU); + +/* The unique id. This is used to reverse lookup menus. + * The primarily need for this arises from Windows, which cannot store + * ALLEGRO_MENU_ID's wholesale.*/ +static uint16_t unique_id; +static _AL_VECTOR menu_ids = _AL_VECTOR_INITIALIZER(_AL_MENU_ID); + +/* The default event source is used with any menu that does not have + its own event source enabled. */ +static ALLEGRO_EVENT_SOURCE default_menu_es; + +/* Private functions */ +static ALLEGRO_MENU *clone_menu(ALLEGRO_MENU *menu, bool popup); +static ALLEGRO_MENU_ITEM *create_menu_item(char const *title, uint16_t id, int flags, ALLEGRO_MENU *popup); +static void destroy_menu_item(ALLEGRO_MENU_ITEM *item); +static bool find_menu_item_r(ALLEGRO_MENU *menu, ALLEGRO_MENU_ITEM *item, int index, void *extra); +static ALLEGRO_MENU_ITEM *interpret_menu_id_param(ALLEGRO_MENU **menu, int *id); +static ALLEGRO_MENU_INFO *parse_menu_info(ALLEGRO_MENU *parent, ALLEGRO_MENU_INFO *info); +static bool set_menu_display_r(ALLEGRO_MENU *menu, ALLEGRO_MENU_ITEM *item, int index, void *extra); + +/* True if the id is actually unique. + */ +static bool get_unique_id(uint16_t* id) +{ + if (unique_id + 1 == UINT16_MAX) { + return false; + } + *id = unique_id++; + return true; +} + +/* The menu item owns the icon bitmap. It is converted to a memory bitmap + * when set to make sure any system threads will be able to read the data. + */ +static void set_item_icon(ALLEGRO_MENU_ITEM *item, ALLEGRO_BITMAP *icon) +{ + item->icon = icon; + + if (icon && al_get_bitmap_flags(item->icon) & ALLEGRO_VIDEO_BITMAP) { + int old_flags = al_get_new_bitmap_flags(); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + item->icon = al_clone_bitmap(icon); + al_destroy_bitmap(icon); + al_set_new_bitmap_flags(old_flags); + } +} + +static ALLEGRO_MENU_ITEM *create_menu_item(char const *title, uint16_t id, int flags, ALLEGRO_MENU *popup) +{ + ALLEGRO_MENU_ITEM *item = al_calloc(1, sizeof(*item)); + if (!item) return NULL; + if (!get_unique_id(&item->unique_id)) { + return NULL; + } + + if (flags & ALLEGRO_MENU_ITEM_CHECKED) + flags |= ALLEGRO_MENU_ITEM_CHECKBOX; + + if (title) + item->caption = al_ustr_new(title); + item->id = id; + item->flags = flags; + item->popup = popup; + + return item; +} + +/* Recursively walks over the entire menu structure, calling the user proc once per menu item, + * and once per menu. The deepest menu is called first. If the proc returns true, then the + * process terminates. It is not safe for the proc to modify the structure (add/remove items). + */ +bool _al_walk_over_menu(ALLEGRO_MENU *menu, + bool (*proc)(ALLEGRO_MENU *menu, ALLEGRO_MENU_ITEM *item, int index, void *extra), void *extra) +{ + ALLEGRO_MENU_ITEM **slot; + size_t i; + ASSERT(menu); + ASSERT(proc); + + for (i = 0; i < _al_vector_size(&menu->items); ++i) { + slot = _al_vector_ref(&menu->items, i); + + if ((*slot)->popup && _al_walk_over_menu((*slot)->popup, proc, extra)) + return true; + + if (proc(menu, *slot, i, extra)) + return true; + } + + return proc(menu, NULL, -1, extra); +} + +/* A callback proc for _al_walk_over_menu that sets each menu's display parameter + * to the "extra" parameter. + */ +static bool set_menu_display_r(ALLEGRO_MENU *menu, ALLEGRO_MENU_ITEM *item, int index, void *extra) +{ + (void) index; + + if (!item) { + menu->display = extra; + } + + return false; +} + +/* A callback proc for _al_walk_over_menu that searches a menu for a given id. If found it sets + * the "parent" parameter to the menu that contains it, and the "id" parameter to the index. + */ +static bool find_menu_item_r(ALLEGRO_MENU *menu, ALLEGRO_MENU_ITEM *item, int index, void *extra) +{ + ALLEGRO_MENU_ITEM *info = (ALLEGRO_MENU_ITEM *) extra; + + if (item != NULL && info->id == item->id) { + info->id = index; + info->parent = menu; + return true; + } + + return false; +} + +/* Like find_menu_item_r, but searches by unique_id. + */ +static bool find_menu_item_r_unique(ALLEGRO_MENU *menu, ALLEGRO_MENU_ITEM *item, int index, void *extra) +{ + ALLEGRO_MENU_ITEM *info = (ALLEGRO_MENU_ITEM *) extra; + + if (item != NULL && info->unique_id == item->unique_id) { + info->id = index; + info->parent = menu; + return true; + } + + return false; +} + +/* Carefully destroy a menu item... If the item is part of a menu, it must be + * removed from it. + */ +static void destroy_menu_item(ALLEGRO_MENU_ITEM *item) +{ + ASSERT(item); + + if (!item->parent) { + /* This normally won't happen. */ + _al_destroy_menu_item_at(item, -1); + } + else { + size_t i; + for (i = 0; i < _al_vector_size(&item->parent->items); ++i) { + if (*(ALLEGRO_MENU_ITEM **)_al_vector_ref(&item->parent->items, i) == item) { + /* Notify the platform that the item is to be removed. */ + _al_destroy_menu_item_at(item, i); + + /* Remove the command from the look-up vector. */ + if (item->id != 0) { + _AL_MENU_ID *menu_id; + size_t j; + + for (j = 0; j < _al_vector_size(&menu_ids); ++j) { + menu_id = (_AL_MENU_ID *) _al_vector_ref(&menu_ids, j); + if (menu_id->menu == item->parent && menu_id->unique_id == item->unique_id) { + _al_vector_delete_at(&menu_ids, j); + break; + } + } + } + + /* Remove the menu from the parent's list. */ + _al_vector_delete_at(&item->parent->items, i); + + break; + } + } + } + + if (item->caption) + al_ustr_free(item->caption); + + if (item->popup) { + /* Delete the sub-menu. Must set the parent/display to NULL ahead of time to + * avoid recursing back here. + */ + item->popup->parent = NULL; + item->popup->display = NULL; + al_destroy_menu(item->popup); + } + + if (item->icon) { + al_destroy_bitmap(item->icon); + } + + al_free(item); +} + +/* An ALLEGRO_MENU_INFO structure represents a heirarchy of menus. This function + * recursively steps through it and builds the entire menu. + */ +static ALLEGRO_MENU_INFO *parse_menu_info(ALLEGRO_MENU *parent, ALLEGRO_MENU_INFO *info) +{ + ASSERT(parent); + ASSERT(info); + + /* The end of the menu is marked by a NULL caption and an id of 0. */ + while (info->caption || info->id) { + if (!info->caption) { + /* A separator */ + al_append_menu_item(parent, NULL, 0, 0, NULL, NULL); + ++info; + } + else if (strlen(info->caption) > 2 && + !strncmp("->", info->caption + strlen(info->caption) - 2, 2)) { + /* An item with a sub-menu has a -> marker as part of its caption. + * (e.g., "File->"). + */ + ALLEGRO_MENU *menu = al_create_menu(); + if (menu) { + /* Strip the -> mark off the end. */ + ALLEGRO_USTR *s = al_ustr_new(info->caption); + al_ustr_remove_range(s, al_ustr_size(s) - 2, al_ustr_size(s)); + al_append_menu_item(parent, al_cstr(s), info->id, 0, NULL, menu); + info = parse_menu_info(menu, info + 1); + al_ustr_free(s); + } + } + else { + /* Just ar regular item */ + al_append_menu_item(parent, info->caption, info->id, info->flags, info->icon, NULL); + ++info; + } + } + + return info + 1; +} + +/* All public functions that take a menu and id parameter have two interpretations: + * + * 1) If id > 0, then it represents an id anywhere within the menu structure, + * including child menus. If there are non-unique IDs, the first one found is + * returned, but the exact order is undefined. (IDs are meant to be unique.) + * + * 2) If id <= 0, then its absolute value represents an ordered index for that + * exact menu. + * + * If the parameters are valid, it returns a pointer to the corresponding + * MENU_ITEM, and the menu/id parameters are set to the item's parent and its + * index. Otherwise (on invalid parameters), it returns NULL and the menu/id + * parameters are left undefined. + * + * (Note that the private OS specific functions always take a direct index.) + */ +static ALLEGRO_MENU_ITEM *interpret_menu_id_param(ALLEGRO_MENU **menu, int *id) +{ + if (*id > 0) { + if (!al_find_menu_item(*menu, *id, menu, id)) + return NULL; + } + else { + *id = (0 - *id); + + if ((size_t) *id >= _al_vector_size(&((*menu)->items))) + return NULL; + } + + return *(ALLEGRO_MENU_ITEM **) _al_vector_ref(&((*menu)->items), (size_t) *id); +} + +/* A helper function for al_clone_menu() and al_clone_menu_for_popup(). + * Note that only the root menu is created as a "popup" (if popup == TRUE). + */ +static ALLEGRO_MENU *clone_menu(ALLEGRO_MENU *menu, bool popup) +{ + ALLEGRO_MENU *clone = NULL; + size_t i; + + if (menu) { + clone = popup ? al_create_popup_menu() : al_create_menu(); + + for (i = 0; i < _al_vector_size(&menu->items); ++i) { + const ALLEGRO_MENU_ITEM *item = *(ALLEGRO_MENU_ITEM **)_al_vector_ref(&menu->items, i); + ALLEGRO_BITMAP *icon = item->icon; + + if (icon) + icon = al_clone_bitmap(icon); + + al_append_menu_item(clone, item->caption ? al_cstr(item->caption) : NULL, + item->id, item->flags, icon, al_clone_menu(item->popup)); + } + } + + return clone; +} + +/* Function: al_create_menu + */ +ALLEGRO_MENU *al_create_menu(void) +{ + ALLEGRO_MENU *m = al_calloc(1, sizeof(*m)); + + if (m) { + _al_vector_init(&m->items, sizeof(ALLEGRO_MENU_ITEM*)); + + /* Make sure the platform actually supports menus */ + if (!_al_init_menu(m)) { + al_destroy_menu(m); + m = NULL; + } + } + + return m; +} + +/* Function: al_create_popup_menu + */ +ALLEGRO_MENU *al_create_popup_menu(void) +{ + ALLEGRO_MENU *m = al_calloc(1, sizeof(*m)); + + if (m) { + _al_vector_init(&m->items, sizeof(ALLEGRO_MENU_ITEM*)); + + if (!_al_init_popup_menu(m)) { + al_destroy_menu(m); + m = NULL; + } + else { + /* Popups are slightly different... They can be used multiple times + * with al_popup_menu(), but never as a display menu. + */ + m->is_popup_menu = true; + } + } + + return m; +} + +/* Function: al_clone_menu + */ +ALLEGRO_MENU *al_clone_menu(ALLEGRO_MENU *menu) +{ + return clone_menu(menu, false); +} + +/* Function: al_clone_menu_for_popup + */ +ALLEGRO_MENU *al_clone_menu_for_popup(ALLEGRO_MENU *menu) +{ + return clone_menu(menu, true); +} + +/* Function: al_build_menu + */ +ALLEGRO_MENU *al_build_menu(ALLEGRO_MENU_INFO *info) +{ + ALLEGRO_MENU *root = al_create_menu(); + + if (root) + parse_menu_info(root, info); + + return root; +} + +/* Function: al_append_menu_item + */ +int al_append_menu_item(ALLEGRO_MENU *parent, char const *title, uint16_t id, + int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu) +{ + ASSERT(parent); + + /* Same thing as inserting a menu item at position == -SIZE */ + return al_insert_menu_item(parent, 0 - (int) _al_vector_size(&parent->items), + title, id, flags, icon, submenu); +} + +/* Function: al_insert_menu_item + */ +int al_insert_menu_item(ALLEGRO_MENU *parent, int pos, char const *title, + uint16_t id, int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu) +{ + ALLEGRO_MENU_ITEM *item; + ALLEGRO_MENU_ITEM **slot; + _AL_MENU_ID *menu_id; + size_t i; + + ASSERT(parent); + + /* If not found, then treat as an append. */ + if (!interpret_menu_id_param(&parent, &pos)) + pos = _al_vector_size(&parent->items); + + /* At this point pos == the _index_ of where to insert */ + + /* The sub-menu must not already be in use. */ + if (submenu && (submenu->display || submenu->parent || submenu->is_popup_menu)) + return -1; + + item = create_menu_item(title, id, flags, submenu); + if (!item) + return -1; + item->parent = parent; + + set_item_icon(item, icon); + + i = (size_t) pos; + + if (i >= _al_vector_size(&parent->items)) { + /* Append */ + i = _al_vector_size(&parent->items); + slot = _al_vector_alloc_back(&parent->items); + } + else { + /* Insert */ + slot = _al_vector_alloc_mid(&parent->items, i); + } + + if (!slot) { + destroy_menu_item(item); + return -1; + } + *slot = item; + + if (submenu) { + submenu->parent = item; + + if (parent->display) + _al_walk_over_menu(submenu, set_menu_display_r, parent->display); + } + + _al_insert_menu_item_at(item, (int) i); + + if (id) { + /* Append the menu's ID to the search vector */ + menu_id = (_AL_MENU_ID *) _al_vector_alloc_back(&menu_ids); + menu_id->unique_id = item->unique_id; + menu_id->id = id; + menu_id->menu = parent; + } + + return (int) i; +} + +/* Function: al_remove_menu_item + */ +bool al_remove_menu_item(ALLEGRO_MENU *menu, int pos) +{ + ALLEGRO_MENU_ITEM *item; + + ASSERT(menu); + + item = interpret_menu_id_param(&menu, &pos); + if (!item) + return false; + + destroy_menu_item(item); + + return true; +} + +/* Function: al_find_menu + */ +ALLEGRO_MENU *al_find_menu(ALLEGRO_MENU *haystack, uint16_t id) +{ + int index; + + return !al_find_menu_item(haystack, id, &haystack, &index) ? NULL : + (*(ALLEGRO_MENU_ITEM **)_al_vector_ref(&haystack->items, index))->popup; +} + +/* Function: al_find_menu_item + */ +bool al_find_menu_item(ALLEGRO_MENU *haystack, uint16_t id, ALLEGRO_MENU **menu, + int *index) +{ + ALLEGRO_MENU_ITEM item; + + ASSERT(haystack); + + /* Abuse the ALLEGRO_MENU_ITEM struct as a container for the _al_walk_over_menu callback. + * If found, it will return true, and the "parent" field will be the menu that and + * the "id" will be the index. + */ + item.id = id; + + if (!_al_walk_over_menu(haystack, find_menu_item_r, &item)) + return false; + + if (menu) + *menu = item.parent; + + if (index) + *index = item.id; + + return true; +} + +/* As al_find_menu_item, but searches by the unique id. + */ +bool _al_find_menu_item_unique(ALLEGRO_MENU *haystack, uint16_t unique_id, ALLEGRO_MENU **menu, + int *index) +{ + ALLEGRO_MENU_ITEM item; + + ASSERT(haystack); + + item.unique_id = unique_id; + + if (!_al_walk_over_menu(haystack, find_menu_item_r_unique, &item)) + return false; + + if (menu) + *menu = item.parent; + + if (index) + *index = item.id; + + return true; +} + +/* Function: al_get_menu_item_caption + */ +const char *al_get_menu_item_caption(ALLEGRO_MENU *menu, int pos) +{ + ALLEGRO_MENU_ITEM *item; + + ASSERT(menu); + + item = interpret_menu_id_param(&menu, &pos); + return item && item->caption ? al_cstr(item->caption) : NULL; +} + + +/* Function: al_set_menu_item_caption + */ +void al_set_menu_item_caption(ALLEGRO_MENU *menu, int pos, const char *caption) +{ + ALLEGRO_MENU_ITEM *item; + + ASSERT(menu); + + item = interpret_menu_id_param(&menu, &pos); + + if (item && item->caption) { + al_ustr_free(item->caption); + item->caption = al_ustr_new(caption); + _al_update_menu_item_at(item, pos); + } +} + +/* Function: al_get_menu_item_flags + */ +int al_get_menu_item_flags(ALLEGRO_MENU *menu, int pos) +{ + ALLEGRO_MENU_ITEM *item; + + ASSERT(menu); + + item = interpret_menu_id_param(&menu, &pos); + return item ? item->flags : -1; +} + +/* Function: al_set_menu_item_flags + */ +void al_set_menu_item_flags(ALLEGRO_MENU *menu, int pos, int flags) +{ + ALLEGRO_MENU_ITEM *item; + + ASSERT(menu); + + item = interpret_menu_id_param(&menu, &pos); + + if (item) { + /* The CHECKBOX flag is read-only after the menu is created, and + * the CHECKED flag can only be set if it is a CHECKBOX. + */ + if (item->flags & ALLEGRO_MENU_ITEM_CHECKBOX) + flags |= ALLEGRO_MENU_ITEM_CHECKBOX; + else { + flags &= ~ALLEGRO_MENU_ITEM_CHECKED; + flags &= ~ALLEGRO_MENU_ITEM_CHECKBOX; + } + + item->flags = flags; + _al_update_menu_item_at(item, pos); + } +} + +/* Function: al_toggle_menu_item_flags + */ +int al_toggle_menu_item_flags(ALLEGRO_MENU *menu, int pos, int flags) +{ + ALLEGRO_MENU_ITEM *item; + + ASSERT(menu); + + item = interpret_menu_id_param(&menu, &pos); + + if (!item) + return -1; + + /* The CHECKBOX flag is read-only after the menu is created, and + * the CHECKED flag can only be set if it is a CHECKBOX. + */ + flags &= ~ALLEGRO_MENU_ITEM_CHECKBOX; + if (!(item->flags & ALLEGRO_MENU_ITEM_CHECKBOX)) { + flags &= ~ALLEGRO_MENU_ITEM_CHECKED; + } + + item->flags ^= flags; + _al_update_menu_item_at(item, pos); + + return item->flags & flags; +} + +/* Function: al_get_menu_item_icon + */ +ALLEGRO_BITMAP *al_get_menu_item_icon(ALLEGRO_MENU *menu, int pos) +{ + ALLEGRO_MENU_ITEM *item; + + ASSERT(menu); + + item = interpret_menu_id_param(&menu, &pos); + return item ? item->icon : NULL; +} + + +/* Function: al_set_menu_item_icon + */ +void al_set_menu_item_icon(ALLEGRO_MENU *menu, int pos, ALLEGRO_BITMAP *icon) +{ + ALLEGRO_MENU_ITEM *item; + + ASSERT(menu); + + item = interpret_menu_id_param(&menu, &pos); + + if (item) { + if (item->icon) + al_destroy_bitmap(item->icon); + + set_item_icon(item, icon); + _al_update_menu_item_at(item, pos); + } +} + +/* Function: al_destroy_menu + */ +void al_destroy_menu(ALLEGRO_MENU *menu) +{ + ALLEGRO_MENU_ITEM **slot; + size_t i; + ASSERT(menu); + + if (menu->parent) { + /* If the menu is attached to a menu item, then this is equivelant to + removing that menu item. */ + ALLEGRO_MENU *parent = menu->parent->parent; + ASSERT(parent); + + for (i = 0; i < _al_vector_size(&parent->items); ++i) { + slot = _al_vector_ref(&parent->items, i); + if (*slot == menu->parent) { + al_remove_menu_item(parent, 0 - (int) i); + return; + } + } + + /* Should never get here. */ + ASSERT(false); + return; + } + else if (menu->display && !menu->is_popup_menu) { + /* This is an active, top-level menu. */ + al_remove_display_menu(menu->display); + } + + /* Destroy each item associated with the menu. */ + while (_al_vector_size(&menu->items)) { + slot = _al_vector_ref_back(&menu->items); + destroy_menu_item(*slot); + } + + _al_vector_free(&menu->items); + + al_disable_menu_event_source(menu); + al_free(menu); +} + +/* Function: al_get_default_menu_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_default_menu_event_source(void) +{ + return &default_menu_es; +} + +/* Function: al_enable_menu_event_source + */ +ALLEGRO_EVENT_SOURCE *al_enable_menu_event_source(ALLEGRO_MENU *menu) +{ + ASSERT(menu); + + if (!menu->is_event_source) { + al_init_user_event_source(&menu->es); + menu->is_event_source = true; + } + + return &menu->es; +} + +/* Function: al_disable_menu_event_source + */ +void al_disable_menu_event_source(ALLEGRO_MENU *menu) +{ + ASSERT(menu); + + if (menu->is_event_source) { + al_destroy_user_event_source(&menu->es); + menu->is_event_source = false; + } +} + +/* Function: al_get_display_menu + */ +ALLEGRO_MENU *al_get_display_menu(ALLEGRO_DISPLAY *display) +{ + size_t i; + ASSERT(display); + + /* Search through the display_menus vector to see if this display has + * a menu associated with it. */ + for (i = 0; i < _al_vector_size(&display_menus); ++i) { + DISPLAY_MENU *dm = (DISPLAY_MENU *) _al_vector_ref(&display_menus, i); + if (dm->display == display) + return dm->menu; + } + + return NULL; +} + +/* Function: al_set_display_menu + */ +bool al_set_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + DISPLAY_MENU *dm = NULL; + size_t i; + int menu_height = _al_get_menu_display_height(); + bool automatic_menu_display_resize = true; + const char* automatic_menu_display_resize_value = + al_get_config_value(al_get_system_config(), "compatibility", "automatic_menu_display_resize"); + if (automatic_menu_display_resize_value && strcmp(automatic_menu_display_resize_value, "false") == 0) + automatic_menu_display_resize = false; + + ASSERT(display); + + /* Check if this display has a menu associated with it */ + for (i = 0; i < _al_vector_size(&display_menus); ++i) { + dm = (DISPLAY_MENU *) _al_vector_ref(&display_menus, i); + if (dm->display == display) + break; + } + + /* If no display was found, reset dm to NULL */ + if (i == _al_vector_size(&display_menus)) + dm = NULL; + + if (!menu) { + /* Removing the menu */ + + if (!dm) + return false; + + _al_hide_display_menu(display, dm->menu); + _al_walk_over_menu(dm->menu, set_menu_display_r, NULL); + _al_vector_delete_at(&display_menus, i); + + if (automatic_menu_display_resize && menu_height > 0) { + display->extra_resize_height = 0; + al_resize_display(display, al_get_display_width(display), al_get_display_height(display)); + } + } + else { + /* Setting the menu. It must not currently be attached to any + * display, and it cannot have a parent menu. */ + if (menu->display || menu->parent) + return false; + + if (dm) { + /* hide the existing menu */ + _al_hide_display_menu(display, dm->menu); + _al_walk_over_menu(dm->menu, set_menu_display_r, NULL); + } + + if (!_al_show_display_menu(display, menu)) { + /* Unable to set the new menu, but already have hidden the + * previous one, so delete the display_menus slot. */ + if (dm) + _al_vector_delete_at(&display_menus, i); + return false; + } + + /* Set the entire menu tree as owned by the display */ + _al_walk_over_menu(menu, set_menu_display_r, display); + + if (!dm) + dm = _al_vector_alloc_back(&display_menus); + + if (automatic_menu_display_resize && menu_height > 0) { + /* Temporarily disable the constraints so we don't send a RESIZE_EVENT. */ + bool old_constraints = display->use_constraints; + display->use_constraints = false; + display->extra_resize_height = menu_height; + al_resize_display(display, al_get_display_width(display), al_get_display_height(display)); + display->use_constraints = old_constraints; + } + + dm->display = display; + dm->menu = menu; + } + + return true; +} + +/* Function: al_popup_menu + */ +bool al_popup_menu(ALLEGRO_MENU *popup, ALLEGRO_DISPLAY *display) +{ + bool ret; + ASSERT(popup); + + if (!popup->is_popup_menu || popup->parent) + return false; + + if (!display) + display = al_get_current_display(); + + /* Set the entire menu tree as owned by the display */ + _al_walk_over_menu(popup, set_menu_display_r, display); + + ret = _al_show_popup_menu(display, popup); + + if (!ret) { + _al_walk_over_menu(popup, set_menu_display_r, NULL); + } + return ret; +} + +/* Function: al_remove_display_menu + */ +ALLEGRO_MENU *al_remove_display_menu(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_MENU *menu; + + ASSERT(display); + + menu = al_get_display_menu(display); + + if (menu) + al_set_display_menu(display, NULL); + + return menu; +} + +/* Tries to find the menu that has a child with the given id. If display + * is not NULL, then it must also match. The first match is returned. + */ +_AL_MENU_ID *_al_find_parent_menu_by_id(ALLEGRO_DISPLAY *display, uint16_t unique_id) +{ + _AL_MENU_ID *menu_id; + size_t i; + + for (i = 0; i < _al_vector_size(&menu_ids); ++i) { + menu_id = (_AL_MENU_ID *) _al_vector_ref(&menu_ids, i); + if (menu_id->unique_id == unique_id) { + if (!display || menu_id->menu->display == display) { + return menu_id; + } + } + } + + return NULL; +} + +/* Each platform implementation must call this when a menu has been clicked. + * The display parameter should be sent if at all possible! If it isn't sent, + * and the user is using non-unique ids, it won't know which display actually + * triggered the menu click. + */ +bool _al_emit_menu_event(ALLEGRO_DISPLAY *display, uint16_t unique_id) +{ + ALLEGRO_EVENT event; + _AL_MENU_ID *menu_id = NULL; + ALLEGRO_EVENT_SOURCE *source = al_get_default_menu_event_source(); + + /* try to find the menu that triggered the event */ + menu_id = _al_find_parent_menu_by_id(display, unique_id); + + if (!menu_id) + return false; + + if (menu_id->id == 0) + return false; + + if (menu_id) { + /* A menu was found associated with the id. See if it has an + * event source associated with it, and adjust "source" accordingly. */ + ALLEGRO_MENU *m = menu_id->menu; + while (true) { + if (m->is_event_source) { + source = &m->es; + break; + } + + if (!m->parent) + break; + + /* m->parent is of type MENU_ITEM, + * which always has a parent of type MENU */ + ASSERT(m->parent->parent); + m = m->parent->parent; + } + } + + event.user.type = ALLEGRO_EVENT_MENU_CLICK; + event.user.data1 = menu_id->id; + event.user.data2 = (intptr_t) display; + event.user.data3 = (intptr_t) menu_id->menu; + + al_emit_user_event(source, &event, NULL); + + return true; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/osx_dialog.m b/allegro/addons/native_dialog/osx_dialog.m new file mode 100644 index 00000000..1807dc95 --- /dev/null +++ b/allegro/addons/native_dialog/osx_dialog.m @@ -0,0 +1,702 @@ +#import <Cocoa/Cocoa.h> +#import <Availability.h> +#import <IOKit/hid/IOHIDLib.h> +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "allegro5/platform/aintosx.h" +#include "allegro5/allegro_osx.h" + +bool _al_init_native_dialog_addon(void) +{ + return true; +} + +void _al_shutdown_native_dialog_addon(void) +{ +} +#pragma mark File Dialog + +bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + (void)display; + int mode = fd->flags; + NSString *filename; + NSURL *directory; + + /* Set initial directory to pass to the file selector */ + if (fd->fc_initial_path) { + ALLEGRO_PATH *initial_directory = al_clone_path(fd->fc_initial_path); + /* Strip filename from path */ + al_set_path_filename(initial_directory, NULL); + + /* Convert path and filename to NSString objects */ + directory = [NSURL fileURLWithPath: [NSString stringWithUTF8String: al_path_cstr(initial_directory, '/')] + isDirectory: YES]; + filename = [NSString stringWithUTF8String: al_get_path_filename(fd->fc_initial_path)]; + al_destroy_path(initial_directory); + } else { + directory = nil; + filename = nil; + } + dispatch_sync(dispatch_get_main_queue(), ^{ + /* We need slightly different code for SAVE and LOAD dialog boxes, which + * are handled by slightly different classes. + */ + if (mode & ALLEGRO_FILECHOOSER_SAVE) { // Save dialog + NSSavePanel *panel = [NSSavePanel savePanel]; + + /* Set file save dialog box options */ + [panel setCanCreateDirectories: YES]; + [panel setCanSelectHiddenExtension: YES]; + [panel setAllowsOtherFileTypes: YES]; + if (filename) { + [panel setNameFieldStringValue:filename]; + } + [panel setDirectoryURL: directory]; + /* Open dialog box */ + if ([panel runModal] == NSOKButton) { + /* NOTE: at first glance, it looks as if this code might leak + * memory, but in fact it doesn't: the string returned by + * UTF8String is freed automatically when it goes out of scope + * (according to the UTF8String docs anyway). + */ + const char *s = [[[panel URL] path] UTF8String]; + fd->fc_path_count = 1; + fd->fc_paths = al_malloc(fd->fc_path_count * sizeof *fd->fc_paths); + fd->fc_paths[0] = al_create_path(s); + } + } else { // Open dialog + NSOpenPanel *panel = [NSOpenPanel openPanel]; + + /* Set file selection box options */ + if (mode & ALLEGRO_FILECHOOSER_FOLDER) { + [panel setCanChooseFiles: NO]; + [panel setCanChooseDirectories: YES]; + } else { + [panel setCanChooseFiles: YES]; + [panel setCanChooseDirectories: NO]; + } + + [panel setResolvesAliases:YES]; + if (mode & ALLEGRO_FILECHOOSER_MULTIPLE) + [panel setAllowsMultipleSelection: YES]; + else + [panel setAllowsMultipleSelection: NO]; + [panel setDirectoryURL:directory]; + if (filename) { + [panel setNameFieldStringValue:filename]; + } + /* Open dialog box */ + if ([panel runModal] == NSOKButton) { + size_t i; + fd->fc_path_count = [[panel URLs] count]; + fd->fc_paths = al_malloc(fd->fc_path_count * sizeof *fd->fc_paths); + for (i = 0; i < fd->fc_path_count; i++) { + /* NOTE: at first glance, it looks as if this code might leak + * memory, but in fact it doesn't: the string returned by + * UTF8String is freed automatically when it goes out of scope + * (according to the UTF8String docs anyway). + */ + NSURL* url = [[panel URLs] objectAtIndex: i]; + const char* s = [[url path] UTF8String]; + fd->fc_paths[i] = al_create_path(s); + } + } + } + + }); + _al_osx_clear_mouse_state(); + + [pool release]; + + return true; +} + +#pragma mark Alert Box +int _al_show_native_message_box(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd) +{ + (void)display; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + dispatch_sync(dispatch_get_main_queue(), ^{ + NSString* button_text; + unsigned int i; + NSAlert* box = [[NSAlert alloc] init]; + + if (fd->mb_buttons == NULL) { + button_text = @"OK"; + if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) button_text = @"Yes|No"; + if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) button_text = @"OK|Cancel"; + } + else { + button_text = [NSString stringWithUTF8String: al_cstr(fd->mb_buttons)]; + } + + NSArray* buttons = [button_text componentsSeparatedByString: @"|"]; + [box setMessageText:[NSString stringWithUTF8String: al_cstr(fd->title)]]; + [box setInformativeText:[NSString stringWithUTF8String: al_cstr(fd->mb_text)]]; + [box setAlertStyle: NSWarningAlertStyle]; + for (i = 0; i < [buttons count]; ++i) + [box addButtonWithTitle: [buttons objectAtIndex: i]]; + + int retval = [box runModal]; + fd->mb_pressed_button = retval + 1 - NSAlertFirstButtonReturn; + [box release]; + }); + [pool release]; + _al_osx_clear_mouse_state(); + return fd->mb_pressed_button; +} + +#pragma mark Text Log View + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 +@interface ALLEGLogView : NSTextView <NSWindowDelegate> +#else +@interface ALLogView : NSTextView +#endif +{ +@public + ALLEGRO_NATIVE_DIALOG *textlog; +} +- (void)keyDown: (NSEvent*)event; +- (BOOL)windowShouldClose: (id)sender; +- (void)emitCloseEventWithKeypress: (BOOL)keypress; +- (void)appendText: (NSString*)text; +@end + + +@implementation ALLEGLogView + + +- (void)keyDown: (NSEvent*)event +{ + if (([event keyCode] == 0x35) || // Escape + (([event keyCode] == 0x0D) && ([event modifierFlags] & NSCommandKeyMask))) { // Command+W + [[self window] close]; + [self emitCloseEventWithKeypress: YES]; + } + else { + [super keyDown: event]; + } +} + +- (BOOL)windowShouldClose: (id)sender +{ + (void)sender; + if (self->textlog->is_active) { + if (!(self->textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE)) { + [self emitCloseEventWithKeypress: NO]; + } + } + return YES; +} + +- (void)emitCloseEventWithKeypress: (BOOL)keypress +{ + ALLEGRO_EVENT event; + event.user.type = ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE; + event.user.timestamp = al_get_time(); + event.user.data1 = (intptr_t)self->textlog; + event.user.data2 = (intptr_t)keypress; + al_emit_user_event(&self->textlog->tl_events, &event, NULL); +} + +- (void)appendText: (NSString*)text +{ + NSTextStorage* store = [self textStorage]; + [store beginEditing]; + [[store mutableString] appendString:text]; + [store endEditing]; +} +@end + +bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + NSRect rect = NSMakeRect(0, 0, 640, 480); + int adapter = al_get_new_display_adapter(); + NSScreen *screen; + unsigned int mask = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask; + if (!(textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE)) + mask |= NSClosableWindowMask; + + if ((adapter >= 0) && (adapter < al_get_num_video_adapters())) { + screen = [[NSScreen screens] objectAtIndex: adapter]; + } else { + screen = [NSScreen mainScreen]; + } + + dispatch_sync(dispatch_get_main_queue(), ^{ + NSWindow *win = [[NSWindow alloc] initWithContentRect: rect + styleMask: mask + backing: NSBackingStoreBuffered + defer: NO + screen: screen]; + [win setReleasedWhenClosed: NO]; + [win setTitle: @"Allegro Text Log"]; + [win setMinSize: NSMakeSize(128, 128)]; + NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame: rect]; + [scrollView setHasHorizontalScroller: YES]; + [scrollView setHasVerticalScroller: YES]; + [scrollView setAutohidesScrollers: YES]; + [scrollView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + + [[scrollView contentView] setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + [[scrollView contentView] setAutoresizesSubviews: YES]; + + NSRect framerect = [[scrollView contentView] frame]; + ALLEGLogView *view = [[ALLEGLogView alloc] initWithFrame: framerect]; + view->textlog = textlog; + [view setHorizontallyResizable: YES]; + [view setVerticallyResizable: YES]; + [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; + [[view textContainer] setContainerSize: NSMakeSize(rect.size.width, 1000000)]; + [[view textContainer] setWidthTracksTextView: NO]; + [view setTextColor: [NSColor grayColor]]; + if (textlog->flags & ALLEGRO_TEXTLOG_MONOSPACE) { + [view setFont: [NSFont userFixedPitchFontOfSize: 0]]; + } + [view setEditable: NO]; + [scrollView setDocumentView: view]; + + [[win contentView] addSubview: scrollView]; + [scrollView release]; + + [win setDelegate: view]; + [win orderFront: nil]; + + /* Save handles for future use. */ + textlog->window = win; // Non-owning reference + textlog->tl_textview = view; // Non-owning reference + }); + /* Now notify al_show_native_textlog that the text log is ready. */ + textlog->is_active = true; + textlog->tl_done = true; + return true; +} + +void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + NSWindow *win = (NSWindow *)textlog->window; + if ([win isVisible]) { + [win performSelectorOnMainThread:@selector(close) withObject:nil waitUntilDone:YES]; + } + [win performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO]; + textlog->window = NULL; + textlog->tl_textview = NULL; + /* Notify everyone that we're gone. */ + textlog->is_active = false; + textlog->tl_done = true; +} + +void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + if (textlog->is_active) { + ALLEGLogView *view = (ALLEGLogView *)textlog->tl_textview; + NSString *text = [NSString stringWithUTF8String: al_cstr(textlog->tl_pending_text)]; + [view performSelectorOnMainThread:@selector(appendText:) + withObject:text + waitUntilDone:YES]; + + al_ustr_truncate(textlog->tl_pending_text, 0); + } +} + +#pragma mark Menus +/* This class manages the association between windows and menus. + * OS X has one menu per application, but Allegro has one menu + * per display (i.e. window) as Windows and Linux tend to do. + * As a result this class is used to keep track of which menu + * was assigned to which window. It listens for the notification when + * a window becomes main and swaps in the corresponding menu. + */ +@interface ALLEGTargetManager : NSObject { + NSMutableArray * _items; +} ++(ALLEGTargetManager*) sharedManager; +-(id) init; +-(void) dealloc; +-(void) setMenu: (NSMenu*) menu forWindow:(NSWindow*) window; +@end + +/* This class represents a menu item target. There is one of these + * for each NSMenu and it handles all the items in that menu. It + * maintains the correspondence between ALLEGRO_MENU_ITEMs and + * NSMenuItems, taking into account the 'App menu' (the one with + * the app's name in bold) which appears by convention on OS X. + */ +@interface ALLEGMenuTarget : NSObject +{ + NSLock* lock; + ALLEGRO_MENU* amenu; + BOOL _hasAppMenu; + NSMenu* _menu; +} +-(NSMenu*) menu; +-(id) initWithMenu:(ALLEGRO_MENU*) amenu; // Designated initializer +-(NSMenu*) menu; +-(void) show; +-(void) showPopup; +-(void) insertItem:(ALLEGRO_MENU_ITEM*) item atIndex:(int) index; +-(void) updateItem:(ALLEGRO_MENU_ITEM*) item atIndex: (int) index; +-(void) destroyItem:(ALLEGRO_MENU_ITEM*) item atIndex: (int) index; +-(void) activated: (id) sender; +-(BOOL) validateMenuItem:(NSMenuItem *)menuItem; +-(void) dealloc; ++(ALLEGMenuTarget*) targetForMenu:(ALLEGRO_MENU*) amenu; +@end + +/* Take a menu caption. If it has an accelerator char (preceeded by & or _) + * remove the & or _ from the string and return the char. + */ +static NSString* extract_accelerator(NSMutableString* caption) { + NSRange range = [caption rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"&_"]]; + if (range.location != NSNotFound && range.location < [caption length]) { + [caption deleteCharactersInRange:range]; + return [caption substringWithRange: range]; + } else { + // Not found or you ended the string with & or _ + return @""; + } +} + +bool _al_init_menu(ALLEGRO_MENU *amenu) +{ + amenu->extra1 = [[ALLEGMenuTarget alloc] initWithMenu: amenu]; + return true; +} + +bool _al_init_popup_menu(ALLEGRO_MENU *amenu) +{ + amenu->extra1 = [[ALLEGMenuTarget alloc] initWithMenu: amenu]; + return true; +} + +bool _al_insert_menu_item_at(ALLEGRO_MENU_ITEM *aitem, int i) +{ + ALLEGMenuTarget* mt = [ALLEGMenuTarget targetForMenu: aitem->parent]; + [mt insertItem: aitem atIndex: i]; + return true; +} + +bool _al_destroy_menu_item_at(ALLEGRO_MENU_ITEM *aitem, int i) +{ + ALLEGMenuTarget* mt = [ALLEGMenuTarget targetForMenu: aitem->parent]; + [mt destroyItem: aitem atIndex: i]; + return true;} + +bool _al_update_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + ALLEGMenuTarget* mt = [ALLEGMenuTarget targetForMenu: item->parent]; + [mt updateItem: item atIndex: i]; + return true; +} + +bool _al_show_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *amenu) +{ + ALLEGMenuTarget* target = [ALLEGMenuTarget targetForMenu:amenu]; + NSWindow* window = al_osx_get_window(display); + [[ALLEGTargetManager sharedManager] setMenu:target.menu + forWindow:window]; + [target performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES]; + return true; +} + +bool _al_hide_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + (void)menu; + (void)display; + /* Nowhere to hide on OS X */ + return false; +} + +bool _al_show_popup_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *amenu) +{ + (void) display; + ALLEGMenuTarget* target = [ALLEGMenuTarget targetForMenu: amenu]; + [target performSelectorOnMainThread:@selector(showPopup) withObject:nil waitUntilDone:NO]; + + return true; +} + +int _al_get_menu_display_height(void) +{ + return 0; +} + +@implementation ALLEGMenuTarget +/* Initial conversion of ALLEGRO_MENU_ITEM to NSMenuItem. + * The target (self) is set for the item. + * The checkbox state is not set here, it's done dynamically in -validateMenuItem. + */ +-(NSMenuItem*) buildMenuItemFor:(ALLEGRO_MENU_ITEM*) aitem +{ + NSMenuItem* item; + if (aitem->caption && al_ustr_length(aitem->caption) > 0) { + NSMutableString* title = [NSMutableString stringWithUTF8String:al_cstr(aitem->caption)]; + NSString* key = extract_accelerator(title); + item = [[NSMenuItem alloc] initWithTitle:title + action:@selector(activated:) + keyEquivalent:key]; + [item setTarget:self]; + aitem->extra1 = item; + return item; + } else { + item = [NSMenuItem separatorItem]; + } + return item; +} +// Insert the app menu if it's not there already +-(void) insertAppMenu +{ + if (!self->_hasAppMenu) { + NSMenuItem* apple = [[NSMenuItem alloc] init]; + [apple setTitle:@"Apple"]; + + NSMenu* appleItems = [[NSMenu alloc] init]; + [appleItems setTitle:@"Apple"]; + [apple setSubmenu:appleItems]; + [appleItems addItemWithTitle:@"Hide" action:@selector(hide:) keyEquivalent:@"h"]; + [appleItems addItemWithTitle:@"Hide others" action:@selector(hideOtherApplications:) keyEquivalent:@""]; + [appleItems addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + [appleItems addItem:[NSMenuItem separatorItem]]; + [appleItems addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"]; + [self.menu insertItem:apple atIndex:0]; + [apple release]; + self->_hasAppMenu = YES; + } +} +// Get the NSMenuItem corresponding to this ALLEGRO_MENU_ITEM +- (NSMenuItem*) itemForAllegroItem:(ALLEGRO_MENU_ITEM*) aitem +{ + int index = _al_vector_find(&self->amenu->items, &aitem); + if (index >= 0) { + /* If the app menu is showing it will be at index 0 so account for this */ + if (self->_hasAppMenu) { + ++index; + } + return [self.menu itemAtIndex:index]; + } else { + return nil; + } +} +// Get the ALLEGRO_MENU_ITEM corresponding to this NSMenuItem +- (ALLEGRO_MENU_ITEM*) allegroItemforItem: (NSMenuItem*) mi +{ + int i; + ALLEGRO_MENU_ITEM * ami; + + for (i = 0; i < (int)_al_vector_size(&self->amenu->items); i++) { + ami = *(ALLEGRO_MENU_ITEM**) _al_vector_ref(&self->amenu->items, i); + if (ami->extra1 == mi) { + return ami; + } + } + return NULL; +} +// Create target with ALLEGRO_MENU bound to it. +- (id)initWithMenu:(ALLEGRO_MENU*) source_menu +{ + self = [super init]; + if (self) { + self->_hasAppMenu = NO; + self->lock = [[NSLock alloc] init]; + self->amenu = source_menu; + self->_menu = [[NSMenu alloc] init]; + } + return self; +} +-(id) init +{ + /* This isn't a valid initializer */ + return nil; +} +// Manage the enabled and checked state (done dynamically by the framework) +-(BOOL) validateMenuItem:(NSMenuItem *)menuItem { + ALLEGRO_MENU_ITEM* aitem = [self allegroItemforItem:menuItem]; + if (aitem) { + int checked = (aitem->flags & (ALLEGRO_MENU_ITEM_CHECKBOX|ALLEGRO_MENU_ITEM_CHECKED)) == (ALLEGRO_MENU_ITEM_CHECKBOX|ALLEGRO_MENU_ITEM_CHECKED); + [menuItem setState: checked ? NSOnState : NSOffState ]; + return aitem->flags & ALLEGRO_MENU_ITEM_DISABLED ? NO : YES; + } + return YES; +} +- (void)dealloc +{ + [self->lock release]; + [self->_menu release]; + [super dealloc]; +} +// Get the menu +-(NSMenu*) menu +{ + return self->_menu; +} +// Action event when the menu is selected +-(void) activated:(id)sender { + NSMenuItem* mitem = (NSMenuItem*) sender; + ALLEGRO_MENU_ITEM* aitim = [self allegroItemforItem:mitem]; + if (aitim) { + if (aitim->flags & ALLEGRO_MENU_ITEM_CHECKBOX) { + aitim->flags ^= ALLEGRO_MENU_ITEM_CHECKED; + } + _al_emit_menu_event(aitim->parent->display, aitim->unique_id); + } +} +// Insert an item, keep the NSMenu in sync +-(void) insertItem:(ALLEGRO_MENU_ITEM*) aitem atIndex: (int) index +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSMenuItem* item = [self buildMenuItemFor:aitem]; + [self.menu insertItem:item atIndex:index]; + if (aitem->popup) { + ALLEGMenuTarget* sub = [ALLEGMenuTarget targetForMenu:aitem->popup]; + [[sub menu] setTitle:[item title]]; + [item setSubmenu:[sub menu]]; + } + [pool release]; +} +// Update an item (caption only, see -validateMenuItem: ) +-(void) updateItem:(ALLEGRO_MENU_ITEM *)aitem atIndex:(int)index +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + (void) index; + NSMenuItem* item = [self itemForAllegroItem:aitem]; + NSMutableString* caption = [NSMutableString stringWithUTF8String:al_cstr(aitem->caption)]; + NSString* key = extract_accelerator(caption); + [item setTitle:caption]; + [item setKeyEquivalent:key]; + [pool release]; +} +// Remove an item, keep the NSMenu in sync +-(void) destroyItem:(ALLEGRO_MENU_ITEM *)aitem atIndex:(int)index +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + (void) index; + NSMenuItem* item = [self itemForAllegroItem:aitem]; + [item.menu removeItem:item]; + [pool release]; +} +// Show the menu on the main application menu bar +-(void) show +{ + [self insertAppMenu]; + [NSApp setMainMenu:self.menu]; +} +// Show the menu as a pop-up on the current key window. +-(void) showPopup +{ + NSWindow *window = [NSApp keyWindow]; + NSPoint mouseLocation = [NSEvent mouseLocation]; + NSPoint locationInWindow = [window convertScreenToBase: mouseLocation]; + int eventType = NSLeftMouseDown; + int winnum = [window windowNumber]; + NSEvent *fakeMouseEvent = [NSEvent mouseEventWithType:eventType + location:locationInWindow + modifierFlags:0 + timestamp:0 + windowNumber:winnum + context:nil + eventNumber:0 + clickCount:0 + pressure:0]; + + [NSMenu popUpContextMenu:self.menu withEvent:fakeMouseEvent forView:[window contentView]]; +} +// Find the target associated with this ALLEGRO_MENU ++(ALLEGMenuTarget*) targetForMenu:(ALLEGRO_MENU *)amenu { + if (!amenu->extra1) { + amenu->extra1 = [[ALLEGMenuTarget alloc] initWithMenu:amenu]; + } + return amenu->extra1; +} +@end // ALLEGMenuTarget + +static ALLEGTargetManager* _sharedmanager = nil; +@implementation ALLEGTargetManager +// Get the singleton manager object ++(ALLEGTargetManager*) sharedManager +{ + if (!_sharedmanager) { + _sharedmanager = [[ALLEGTargetManager alloc] init]; + } + return _sharedmanager; +} +// Set up and register for notifications +-(id) init +{ + self = [super init]; + if (self) { + self->_items = [[NSMutableArray alloc] init]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onWindowChange:) name:NSWindowDidBecomeMainNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onWindowClose:) name:NSWindowWillCloseNotification object:nil]; + + } + return self; +} +// Destroy and un-register +-(void) dealloc +{ + [self->_items release]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} +// Find the index for a window which this object is managing or NSNotFound +-(NSUInteger) indexForWindow:(NSWindow*) window +{ + NSUInteger i; + for (i=0; i<[self->_items count]; ++i) { + NSDictionary* entry = [self->_items objectAtIndex:i]; + if ([window isEqual:[entry valueForKey:@"window"]]) { + return i; + } + } + return NSNotFound; +} +// Event when main window changes - locate the matching menu and show it +-(void) onWindowChange: (NSNotification*) notification +{ + NSWindow* window = [notification object]; + NSUInteger index = [self indexForWindow: window]; + if (index != NSNotFound) { + NSDictionary* entry = [self->_items objectAtIndex:index]; + NSMenu* menu = [entry valueForKey:@"menu"]; + [NSApp setMainMenu:menu]; + } + /* If not found we do nothing */ +} +// Event when window closes, remove it from the managed list +-(void) onWindowClose: (NSNotification*) notification +{ + NSWindow* window = [notification object]; + NSUInteger index = [self indexForWindow: window]; + if (index != NSNotFound) { + [self->_items removeObjectAtIndex:index]; + } + /* If not found we do nothing */ +} +// Link a menu with a window, replace any existing link +-(void) setMenu:(NSMenu *)menu forWindow:(NSWindow *)window +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSUInteger index = [self indexForWindow:window]; + if (menu) { + NSDictionary* newentry = [NSDictionary dictionaryWithObjectsAndKeys:menu, @"menu", window, @"window", nil]; + if (index == NSNotFound) { + [self->_items addObject: newentry]; + } + else { + [self->_items replaceObjectAtIndex:index withObject: newentry]; + } + } else { + /* Menu was null so delete */ + if (index != NSNotFound) { + [self->_items removeObjectAtIndex:index]; + } + } + [pool release]; +} +@end // ALLEGTargetManager diff --git a/allegro/addons/native_dialog/textlog.c b/allegro/addons/native_dialog/textlog.c new file mode 100644 index 00000000..aa7c6451 --- /dev/null +++ b/allegro/addons/native_dialog/textlog.c @@ -0,0 +1,174 @@ +#include <stdarg.h> +#include <stdio.h> +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog.h" +#include "allegro5/internal/aintern_native_dialog_cfg.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_system.h" + + +/* The GTK and OSX implementations do not require an extra thread. + * The Windows implementation does. + */ +#if defined(ALLEGRO_CFG_NATIVE_DIALOG_WINDOWS) + #define TEXT_LOG_EXTRA_THREAD true +#else + #define TEXT_LOG_EXTRA_THREAD false +#endif + + +/* This will only return when the text window is closed. */ +static void *text_log_thread_proc(ALLEGRO_THREAD *thread, void *arg) +{ + ALLEGRO_NATIVE_DIALOG *textlog = arg; + + if (!_al_open_native_text_log(textlog)) { + al_lock_mutex(textlog->tl_text_mutex); + textlog->tl_init_error = true; + al_signal_cond(textlog->tl_text_cond); + al_unlock_mutex(textlog->tl_text_mutex); + } + + return thread; +} + + +/* Function: al_open_native_text_log + */ +ALLEGRO_TEXTLOG *al_open_native_text_log(char const *title, int flags) +{ + ALLEGRO_NATIVE_DIALOG *textlog = NULL; + + /* Avoid warnings when log windows are unimplemented. */ + (void)title; + (void)flags; + + textlog = al_calloc(1, sizeof *textlog); + textlog->title = al_ustr_new(title); + textlog->flags = flags; + if (TEXT_LOG_EXTRA_THREAD) { + textlog->tl_thread = al_create_thread(text_log_thread_proc, textlog); + } + textlog->tl_text_cond = al_create_cond(); + textlog->tl_text_mutex = al_create_mutex(); + textlog->tl_pending_text = al_ustr_new(""); + al_init_user_event_source(&textlog->tl_events); + + textlog->tl_init_error = false; + textlog->tl_done = false; + + if (TEXT_LOG_EXTRA_THREAD) { + /* Unlike the other dialogs, this one never blocks as the intended + * use case is a log window running in the background for debugging + * purposes when no console can be used. Therefore we have it run + * in a separate thread. + */ + al_start_thread(textlog->tl_thread); + al_lock_mutex(textlog->tl_text_mutex); + while (!textlog->tl_done && !textlog->tl_init_error) { + al_wait_cond(textlog->tl_text_cond, textlog->tl_text_mutex); + } + al_unlock_mutex(textlog->tl_text_mutex); + } + else { + textlog->tl_init_error = !_al_open_native_text_log(textlog); + } + + if (textlog->tl_init_error) { + al_close_native_text_log((ALLEGRO_TEXTLOG *)textlog); + return NULL; + } + + textlog->dtor_item = _al_register_destructor(_al_dtor_list, "textlog", textlog, + (void (*)(void *))al_close_native_text_log); + + return (ALLEGRO_TEXTLOG *)textlog; +} + + +/* Function: al_close_native_text_log + */ +void al_close_native_text_log(ALLEGRO_TEXTLOG *textlog) +{ + ALLEGRO_NATIVE_DIALOG *dialog = (ALLEGRO_NATIVE_DIALOG *)textlog; + + if (!dialog) + return; + + if (!dialog->tl_init_error) { + dialog->tl_done = false; + + if (TEXT_LOG_EXTRA_THREAD) { + al_lock_mutex(dialog->tl_text_mutex); + _al_close_native_text_log(dialog); + while (!dialog->tl_done) { + al_wait_cond(dialog->tl_text_cond, dialog->tl_text_mutex); + } + } + else { + _al_close_native_text_log(dialog); + al_lock_mutex(dialog->tl_text_mutex); + } + + _al_unregister_destructor(_al_dtor_list, dialog->dtor_item); + } + + al_ustr_free(dialog->title); + al_ustr_free(dialog->tl_pending_text); + + al_destroy_user_event_source(&dialog->tl_events); + + al_unlock_mutex(dialog->tl_text_mutex); + + if (TEXT_LOG_EXTRA_THREAD) { + al_destroy_thread(dialog->tl_thread); + } + al_destroy_cond(dialog->tl_text_cond); + al_destroy_mutex(dialog->tl_text_mutex); + al_free(dialog); +} + + +/* Function: al_append_native_text_log + */ +void al_append_native_text_log(ALLEGRO_TEXTLOG *textlog, + char const *format, ...) +{ + ALLEGRO_NATIVE_DIALOG *dialog = (ALLEGRO_NATIVE_DIALOG *)textlog; + va_list args; + + /* Fall back to printf if no window. */ + if (!dialog) { + va_start(args, format); + vprintf(format, args); + va_end(args); + return; + } + + al_lock_mutex(dialog->tl_text_mutex); + + /* We could optimise the case where format="%s". */ + va_start(args, format); + al_ustr_vappendf(dialog->tl_pending_text, format, args); + va_end(args); + + _al_append_native_text_log(dialog); + + al_unlock_mutex(dialog->tl_text_mutex); +} + + +/* Function: al_get_native_text_log_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_native_text_log_event_source( + ALLEGRO_TEXTLOG *textlog) +{ + ALLEGRO_NATIVE_DIALOG *dialog = (ALLEGRO_NATIVE_DIALOG *)textlog; + ASSERT(dialog); + + return &dialog->tl_events; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/native_dialog/win_dialog.c b/allegro/addons/native_dialog/win_dialog.c new file mode 100644 index 00000000..03b3a9c8 --- /dev/null +++ b/allegro/addons/native_dialog/win_dialog.c @@ -0,0 +1,944 @@ +/* Each of these files implements the same, for different GUI toolkits: + * + * dialog.c - code shared between all platforms + * gtk_dialog.c - GTK file open dialog + * osx_dialog.m - OSX file open dialog + * qt_dialog.cpp - Qt file open dialog + * win_dialog.c - Windows file open dialog + * + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_native_dialog.h" + +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_wunicode.h" + +#include "allegro5/allegro_windows.h" + +#include <string.h> + +/* We use RichEdit by default. */ +#include <richedit.h> +#include <shlobj.h> // for folder selector + +ALLEGRO_DEBUG_CHANNEL("win_dialog") + +#define WM_SHOW_POPUP (WM_APP + 42) +#define WM_HIDE_MENU (WM_APP + 43) +#define WM_SHOW_MENU (WM_APP + 44) + +/* Reference count for shared resources. */ +static int wlog_count = 0; + +/* Handle of RichEdit module */ +static void *wlog_rich_edit_module = 0; + +/* Name of the edit control. Depend on system resources. */ +static TCHAR* wlog_edit_control = TEXT("EDIT"); + +/* True if output support unicode */ +static bool wlog_unicode = false; + +static ALLEGRO_MUTEX* global_mutex; + +static ALLEGRO_COND* wm_size_cond; +static bool got_wm_size_event = false; + +/* For Unicode support, define some helper functions + * which work with either UTF-16 or ANSI code pages + * depending on whether UNICODE is defined or not. + */ + +/* tcreate_path: + * Create path from TCHARs + */ +static ALLEGRO_PATH* _tcreate_path(const TCHAR* ts) +{ + char* tmp = _twin_tchar_to_utf8(ts); + ALLEGRO_PATH* path = al_create_path(tmp); + al_free(tmp); + return path; +} +/* tcreate_path: + * Create directory path from TCHARs + */ +static ALLEGRO_PATH* _tcreate_path_for_directory(const TCHAR* ts) +{ + char* tmp = _twin_tchar_to_utf8(ts); + ALLEGRO_PATH* path = al_create_path_for_directory(tmp); + al_free(tmp); + return path; +} + +bool _al_init_native_dialog_addon(void) +{ + global_mutex = al_create_mutex(); + wm_size_cond = al_create_cond(); + if (!global_mutex || !wm_size_cond) { + al_destroy_mutex(global_mutex); + al_destroy_cond(wm_size_cond); + return false; + } + return true; +} + +void _al_shutdown_native_dialog_addon(void) +{ + al_destroy_mutex(global_mutex); + al_destroy_cond(wm_size_cond); + global_mutex = NULL; + wm_size_cond = NULL; +} + + +static bool select_folder(ALLEGRO_DISPLAY_WIN *win_display, + ALLEGRO_NATIVE_DIALOG *fd) +{ + BROWSEINFO folderinfo; + LPCITEMIDLIST pidl; + /* Selected path */ + TCHAR buf[MAX_PATH] = TEXT(""); + /* Display name */ + TCHAR dbuf[MAX_PATH] = TEXT(""); + + folderinfo.hwndOwner = win_display ? win_display->window : NULL; + folderinfo.pidlRoot = NULL; + folderinfo.pszDisplayName = dbuf; + folderinfo.lpszTitle = _twin_ustr_to_tchar(fd->title); + folderinfo.ulFlags = 0; + folderinfo.lpfn = NULL; + + pidl = SHBrowseForFolder(&folderinfo); + + al_free((void*) folderinfo.lpszTitle); + + if (pidl) { + SHGetPathFromIDList(pidl, buf); + fd->fc_path_count = 1; + fd->fc_paths = al_malloc(sizeof(void *)); + fd->fc_paths[0] = _tcreate_path(buf); + return true; + } + return false; +} + +static ALLEGRO_USTR *create_filter_string(const ALLEGRO_USTR *patterns) +{ + ALLEGRO_USTR *filter = al_ustr_new(""); + bool filter_all = false; + int start, end; + + /* FIXME: Move all this filter parsing stuff into a common file. */ + if (0 == strcmp(al_cstr(patterns), "*.*")) { + filter_all = true; + } + else { + al_ustr_append_cstr(filter, "All Supported Files"); + al_ustr_append_chr(filter, '\0'); + start = al_ustr_size(filter); + al_ustr_append(filter, patterns); + + /* Remove all instances of "*.*", which will be added separately. */ + for (;;) { + int pos = al_ustr_find_cstr(filter, start, "*.*;"); + if (pos == -1) + break; + if (pos == start || al_ustr_get(filter, pos - 1) == ';') { + filter_all = true; + al_ustr_remove_range(filter, pos, pos + 4); + start = pos; + } + else { + start = pos + 4; + } + } + while (al_ustr_has_suffix_cstr(filter, ";*.*")) { + filter_all = true; + end = al_ustr_size(filter); + al_ustr_remove_range(filter, end - 4, end); + } + + al_ustr_append_chr(filter, '\0'); + } + + if (filter_all) { + al_ustr_append_cstr(filter, "All Files"); + al_ustr_append_chr(filter, '\0'); + al_ustr_append_cstr(filter, "*.*"); + al_ustr_append_chr(filter, '\0'); + } + + al_ustr_append_chr(filter, '\0'); + return filter; +} + +static int skip_nul_terminated_string(TCHAR *s) +{ + int i = 0; + + while (s[i]) + i++; + + return i+1; +} + +bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd) +{ + OPENFILENAME ofn; + ALLEGRO_DISPLAY_WIN *win_display; + int flags = 0; + bool ret; + TCHAR buf[4096]; + const int BUFSIZE = sizeof(buf) / sizeof(TCHAR); + TCHAR* wfilter = NULL; + TCHAR* wpath = NULL; + ALLEGRO_USTR *filter_string = NULL; + ALLEGRO_PATH* initial_dir_path = NULL; + + buf[0] = '\0'; + + win_display = (ALLEGRO_DISPLAY_WIN *)display; + + if (fd->flags & ALLEGRO_FILECHOOSER_FOLDER) { + return select_folder(win_display, fd); + } + + /* Selecting a file. */ + memset(&ofn, 0, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = win_display ? win_display->window : NULL; + + /* Create filter string. */ + if (fd->fc_patterns) { + filter_string = create_filter_string(fd->fc_patterns); + wfilter = _twin_ustr_to_tchar(filter_string); + ofn.lpstrFilter = wfilter; + } + else { + /* List all files by default. */ + ofn.lpstrFilter = TEXT("All Files\0*.*\0\0"); + } + + /* Provide buffer for file chosen by dialog. */ + ofn.lpstrFile = buf; + ofn.nMaxFile = BUFSIZE; + + /* Initialize file name buffer and starting directory. */ + if (fd->fc_initial_path) { + bool is_dir; + const ALLEGRO_USTR *path = al_path_ustr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP); + + if (al_filename_exists(al_cstr(path))) { + ALLEGRO_FS_ENTRY *fs = al_create_fs_entry(al_cstr(path)); + is_dir = al_get_fs_entry_mode(fs) & ALLEGRO_FILEMODE_ISDIR; + al_destroy_fs_entry(fs); + } + else { + is_dir = false; + } + + if (is_dir) { + wpath = _twin_ustr_to_tchar(path); + } + else { + /* Extract the directory from the path. */ + initial_dir_path = al_clone_path(fd->fc_initial_path); + if (initial_dir_path) { + al_set_path_filename(initial_dir_path, NULL); + wpath = _twin_utf8_to_tchar(al_path_cstr(initial_dir_path, ALLEGRO_NATIVE_PATH_SEP)); + } + } + ofn.lpstrInitialDir = wpath; + } + + if (fd->title) + ofn.lpstrTitle = _twin_ustr_to_tchar(fd->title); + + flags |= OFN_NOCHANGEDIR | OFN_EXPLORER; + if (fd->flags & ALLEGRO_FILECHOOSER_SAVE) { + flags |= OFN_OVERWRITEPROMPT; + } + else { + flags |= (fd->flags & ALLEGRO_FILECHOOSER_FILE_MUST_EXIST) ? OFN_FILEMUSTEXIST : 0; + } + flags |= (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) ? OFN_ALLOWMULTISELECT : 0; + flags |= (fd->flags & ALLEGRO_FILECHOOSER_SHOW_HIDDEN) ? 0x10000000 : 0; // NOTE: 0x10000000 is FORCESHOWHIDDEN + ofn.Flags = flags; + + if (flags & OFN_OVERWRITEPROMPT) { + ret = GetSaveFileName(&ofn); + } + else { + ret = GetOpenFileName(&ofn); + } + + if (initial_dir_path) { + al_destroy_path(initial_dir_path); + } + al_free((void*) ofn.lpstrTitle); + al_free(wfilter); + al_free(wpath); + al_ustr_free(filter_string); + + if (!ret) { + DWORD err = GetLastError(); + if (err != ERROR_SUCCESS) { + ALLEGRO_ERROR("al_show_native_file_dialog failed: %s\n", _al_win_error(err)); + } + return false; + } + + if (flags & OFN_ALLOWMULTISELECT) { + int i = 0; + /* Count number of file names in buf. */ + fd->fc_path_count = 0; + while (1) { + int j = skip_nul_terminated_string(buf + i); + if (j <= 1) + break; + fd->fc_path_count++; + i += j; + } + } + else { + fd->fc_path_count = 1; + } + + if (fd->fc_path_count == 1) { + fd->fc_paths = al_malloc(sizeof(void *)); + fd->fc_paths[0] = _tcreate_path(buf); + } + else { + int i, p; + /* If multiple files were selected, the first string in buf is the + * directory name, followed by each of the file names terminated by NUL. + */ + fd->fc_path_count -= 1; + fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *)); + i = skip_nul_terminated_string(buf); + for (p = 0; p < (int)fd->fc_path_count; p++) { + fd->fc_paths[p] = _tcreate_path_for_directory(buf); + char* tmp = _twin_tchar_to_utf8(buf + i); + al_set_path_filename(fd->fc_paths[p], tmp); + al_free(tmp); + i += skip_nul_terminated_string(buf+i); + } + } + + return true; +} + +int _al_show_native_message_box(ALLEGRO_DISPLAY *display, + ALLEGRO_NATIVE_DIALOG *fd) +{ + UINT type = MB_SETFOREGROUND; + int result; + TCHAR *text, *title; + + /* Note: the message box code cannot assume that Allegro is installed. */ + + if (fd->flags & ALLEGRO_MESSAGEBOX_QUESTION) + type |= MB_ICONQUESTION; + else if (fd->flags & ALLEGRO_MESSAGEBOX_WARN) + type |= MB_ICONWARNING; + else if (fd->flags & ALLEGRO_MESSAGEBOX_ERROR) + type |= MB_ICONERROR; + else + type |= MB_ICONINFORMATION; + + if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) + type |= MB_YESNO; + else if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) + type |= MB_OKCANCEL; + + /* heading + text are combined together */ + + if (al_ustr_size(fd->mb_heading)) + al_ustr_append_cstr(fd->mb_heading, "\n\n"); + + al_ustr_append(fd->mb_heading, fd->mb_text); + + text = _twin_ustr_to_tchar(fd->mb_heading); + if (!text) { + return 0; + } + title = _twin_ustr_to_tchar(fd->title); + if (!title) { + al_free(text); + return 0; + } + result = MessageBox(al_get_win_window_handle(display), + text, title, type); + + al_free(text); + al_free(title); + + if (result == IDYES || result == IDOK) + return 1; + else + return 2; +} + + +/* Emit close event. */ +static void wlog_emit_close_event(ALLEGRO_NATIVE_DIALOG *textlog, bool keypress) +{ + ALLEGRO_EVENT event; + event.user.type = ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE; + event.user.timestamp = al_get_time(); + event.user.data1 = (intptr_t)textlog; + event.user.data2 = (intptr_t)keypress; + al_emit_user_event(&textlog->tl_events, &event, NULL); +} + +/* convert_crlf: + * Alter this string to change every LF to CRLF + */ +static ALLEGRO_USTR* convert_crlf(ALLEGRO_USTR* s) { + int pos = 0; + int ch, prev; + while ((pos = al_ustr_find_chr(s, pos, '\n')) >= 0) { + prev = pos; + ch = al_ustr_prev_get(s, &prev); + if (ch == -2) { + return s; + } else if (ch != '\r') { + al_ustr_insert_chr(s, pos, '\r'); + al_ustr_next(s, &pos); + } + al_ustr_next(s, &pos); + } + return s; +} +/* General function to output log message. */ +static void wlog_do_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + int index; + index = GetWindowTextLength(textlog->tl_textview); + SendMessage(textlog->tl_textview, EM_SETSEL, (WPARAM)index, (LPARAM)index); + convert_crlf(textlog->tl_pending_text); + TCHAR* buf = _twin_utf8_to_tchar(al_cstr(textlog->tl_pending_text)); + SendMessage(textlog->tl_textview, EM_REPLACESEL, 0, (LPARAM) buf); + al_free(buf); + al_ustr_truncate(textlog->tl_pending_text, 0); + textlog->tl_have_pending = false; + + SendMessage(textlog->tl_textview, WM_VSCROLL, SB_BOTTOM, 0); +} + +/* Text log window callback. */ +static LRESULT CALLBACK wlog_text_log_callback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + CREATESTRUCT* create_struct; + + ALLEGRO_NATIVE_DIALOG* textlog = (ALLEGRO_NATIVE_DIALOG*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + + switch (uMsg) { + case WM_CREATE: + /* Set user data for window, so we will be able to retrieve text log structure any time */ + create_struct = (CREATESTRUCT*)lParam; + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)create_struct->lpCreateParams); + break; + + case WM_CLOSE: + if (textlog->is_active) { + if (!(textlog->flags & ALLEGRO_TEXTLOG_NO_CLOSE)) { + wlog_emit_close_event(textlog, false); + } + return 0; + } + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + case WM_KEYDOWN: + if (wParam == VK_ESCAPE) { + wlog_emit_close_event(textlog, true); + } + + break; + + case WM_MOVE: + InvalidateRect(hWnd, NULL, FALSE); + break; + + case WM_SIZE: + /* Match text log size to parent client area */ + if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED) { + RECT client_rect; + GetClientRect(hWnd, &client_rect); + MoveWindow(textlog->tl_textview, client_rect.left, client_rect.top, + client_rect.right - client_rect.left, client_rect.bottom - client_rect.top, TRUE); + } + break; + + case WM_USER: + al_lock_mutex(textlog->tl_text_mutex); + wlog_do_append_native_text_log(textlog); + al_unlock_mutex(textlog->tl_text_mutex); + break; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + + +/* We hold textlog->tl_text_mutex. */ +static bool open_native_text_log_inner(ALLEGRO_NATIVE_DIALOG *textlog) +{ + LPCTSTR font_name; + HWND hWnd; + HWND hLog; + RECT client_rect; + HFONT hFont; + MSG msg; + BOOL ret; + TCHAR* title; + + /* Create text log window. */ + title = _twin_ustr_to_tchar(textlog->title); + hWnd = CreateWindow(TEXT("Allegro Text Log"), title, + WS_CAPTION | WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU, + CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, + (HINSTANCE)GetModuleHandle(NULL), textlog); + al_free(title); + if (!hWnd) { + ALLEGRO_ERROR("CreateWindow failed\n"); + return false; + } + + /* Get client area of the log window. */ + GetClientRect(hWnd, &client_rect); + + /* Create edit control. */ + hLog = CreateWindow(wlog_edit_control, NULL, + WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_READONLY, + client_rect.left, client_rect.top, client_rect.right - client_rect.left, client_rect.bottom - client_rect.top, + hWnd, NULL, (HINSTANCE)GetModuleHandle(NULL), NULL); + if (!hLog) { + ALLEGRO_ERROR("CreateWindow failed\n"); + DestroyWindow(hWnd); + return false; + } + + /* Enable double-buffering. */ + SetWindowLong(hLog, GWL_EXSTYLE, GetWindowLong(hLog, GWL_EXSTYLE) | 0x02000000L/*WS_EX_COMPOSITED*/); + + /* Select font name. */ + if (textlog->flags & ALLEGRO_TEXTLOG_MONOSPACE) + font_name = TEXT("Courier New"); + else + font_name = TEXT("Arial"); + + /* Create font and set font. */ + hFont = CreateFont(-11, 0, 0, 0, FW_LIGHT, 0, 0, + 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + FF_MODERN | FIXED_PITCH, font_name); + + /* Assign font to the text log. */ + if (hFont) { + SendMessage(hLog, WM_SETFONT, (WPARAM)hFont, 0); + } + + /* We are ready to show our window. */ + ShowWindow(hWnd, SW_NORMAL); + + /* Save handles for future use. */ + textlog->window = hWnd; + textlog->tl_textview = hLog; + textlog->is_active = true; + + /* Now notify al_show_native_textlog that the text log is ready. */ + textlog->tl_done = true; + al_signal_cond(textlog->tl_text_cond); + al_unlock_mutex(textlog->tl_text_mutex); + + /* Process messages. */ + while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0) { + if (ret != -1 && msg.message != WM_QUIT) { + /* Intercept child window key down messages. Needed to track + * hit of ESCAPE key while text log have focus. */ + if (msg.hwnd != textlog->window && msg.message == WM_KEYDOWN) { + PostMessage(textlog->window, WM_KEYDOWN, msg.wParam, msg.lParam); + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else + break; + } + + /* Close window. Should be already closed, this is just sanity. */ + if (IsWindow(textlog->window)) { + DestroyWindow(textlog->window); + } + + /* Release font. We don't want to leave any garbage. */ + DeleteObject(hFont); + + /* Notify everyone that we're gone. */ + al_lock_mutex(textlog->tl_text_mutex); + textlog->tl_done = true; + al_signal_cond(textlog->tl_text_cond); + + return true; +} + +bool _al_open_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + WNDCLASS text_log_class; + bool rc; + + al_lock_mutex(textlog->tl_text_mutex); + + /* Note: the class registration and rich edit module loading are not + * implemented in a thread-safe manner (pretty unlikely). + */ + + /* Prepare text log class info. */ + if (wlog_count == 0) { + ALLEGRO_DEBUG("Register text log class\n"); + + memset(&text_log_class, 0, sizeof(text_log_class)); + text_log_class.hInstance = (HINSTANCE)GetModuleHandle(NULL); + text_log_class.lpszClassName = TEXT("Allegro Text Log"); + text_log_class.lpfnWndProc = wlog_text_log_callback; + text_log_class.hIcon = NULL; + text_log_class.hCursor = NULL; + text_log_class.lpszMenuName = NULL; + text_log_class.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); + + if (RegisterClass(&text_log_class) == 0) { + /* Failure, window class is a basis and we do not have one. */ + ALLEGRO_ERROR("RegisterClass failed\n"); + al_unlock_mutex(textlog->tl_text_mutex); + return false; + } + } + + /* Load RichEdit control. */ + if (wlog_count == 0) { + ALLEGRO_DEBUG("Load rich edit module\n"); + ALLEGRO_ASSERT(!wlog_rich_edit_module); + + if ((wlog_rich_edit_module = _al_open_library("msftedit.dll"))) { + /* 4.1 and emulation of 3.0, 2.0, 1.0 */ + wlog_edit_control = TEXT("RICHEDIT50W"); /*MSFTEDIT_CLASS*/ + wlog_unicode = true; + } + else if ((wlog_rich_edit_module = _al_open_library("riched20.dll"))) { + /* 3.0, 2.0 */ + wlog_edit_control = TEXT("RichEdit20W"); /*RICHEDIT_CLASS*/ + wlog_unicode = true; + } + else if ((wlog_rich_edit_module = _al_open_library("riched32.dll"))) { + /* 1.0 */ + wlog_edit_control = TEXT("RichEdit"); /*RICHEDIT_CLASS*/ + wlog_unicode = false; + } + else { + wlog_edit_control = TEXT("EDIT"); + wlog_unicode = false; + } + } + + wlog_count++; + ALLEGRO_DEBUG("wlog_count = %d\n", wlog_count); + + rc = open_native_text_log_inner(textlog); + + wlog_count--; + ALLEGRO_DEBUG("wlog_count = %d\n", wlog_count); + + /* Release RichEdit module. */ + if (wlog_count == 0 && wlog_rich_edit_module) { + ALLEGRO_DEBUG("Unload rich edit module\n"); + _al_close_library(wlog_rich_edit_module); + wlog_rich_edit_module = NULL; + } + + /* Unregister window class. */ + if (wlog_count == 0) { + ALLEGRO_DEBUG("Unregister text log class\n"); + UnregisterClass(TEXT("Allegro Text Log"), (HINSTANCE)GetModuleHandle(NULL)); + } + + al_unlock_mutex(textlog->tl_text_mutex); + + return rc; +} + +void _al_close_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + /* Just deactivate text log and send bye, bye message. */ + if (IsWindow(textlog->window)) { + textlog->is_active = false; + PostMessage(textlog->window, WM_CLOSE, 0, 0); + } +} + +void _al_append_native_text_log(ALLEGRO_NATIVE_DIALOG *textlog) +{ + if (textlog->tl_have_pending) + return; + textlog->tl_have_pending = true; + + /* Post text as user message. This guarantees that the whole processing will + * take place on text log thread. + */ + if (IsWindow(textlog->window)) { + PostMessage(textlog->window, WM_USER, (WPARAM)textlog, 0); + } +} + +static bool menu_callback(ALLEGRO_DISPLAY *display, UINT msg, WPARAM wParam, LPARAM lParam, + LPARAM* result, void *userdata) +{ + (void) userdata; + *result = 0; + + if (msg == WM_COMMAND && lParam == 0) { + const int id = LOWORD(wParam); + _AL_MENU_ID *menu_id = _al_find_parent_menu_by_id(display, id); + if (menu_id) { + int index; + if (_al_find_menu_item_unique(menu_id->menu, id, NULL, &index)) { + if (al_get_menu_item_flags(menu_id->menu, -index) & ALLEGRO_MENU_ITEM_CHECKBOX) { + /* Toggle the checkbox, since Windows doesn't do that automatically. */ + al_toggle_menu_item_flags(menu_id->menu, -index, ALLEGRO_MENU_ITEM_CHECKED); + } + } + } + _al_emit_menu_event(display, id); + return true; + } + else if (msg == WM_SYSCOMMAND) { + if ((wParam & 0xfff0) == SC_KEYMENU && al_get_display_menu(display) != NULL) { + /* Allow the ALT key to open the menu + * XXX: do we even want to do this? Should it be optional? + */ + DefWindowProc(al_get_win_window_handle(display), msg, wParam, lParam); + return true; + } + } + else if (msg == WM_SHOW_POPUP) { + ALLEGRO_MENU *menu = (ALLEGRO_MENU *) lParam; + HWND hwnd = al_get_win_window_handle(display); + POINT pos; + GetCursorPos(&pos); + SetForegroundWindow(hwnd); + TrackPopupMenuEx((HMENU) menu->extra1, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, hwnd, NULL); + + return true; + } + else if (msg == WM_HIDE_MENU) { + SetMenu(al_get_win_window_handle(display), NULL); + return true; + } + else if (msg == WM_SHOW_MENU) { + ALLEGRO_MENU *menu = (ALLEGRO_MENU *) lParam; + SetMenu(al_get_win_window_handle(display), (HMENU) menu->extra1); + return true; + } + else if (msg == WM_SIZE) { + ALLEGRO_DEBUG("Got the WM_SIZE event.\n"); + got_wm_size_event = true; + al_signal_cond(wm_size_cond); + } + else if (msg == WM_MENUSELECT) { + /* XXX: could use this as a way to indicate the popup menu was canceled */ + } + + return false; +} + +static void init_menu_info(MENUITEMINFO *info, ALLEGRO_MENU_ITEM *menu) +{ + memset(info, 0, sizeof(*info)); + + info->cbSize = sizeof(*info); + info->fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_STRING | MIIM_CHECKMARKS; + info->wID = menu->unique_id; + + if (!menu->caption) { + info->fType = MFT_SEPARATOR; + } + else { + info->fType = MFT_STRING; + info->dwTypeData = _twin_ustr_to_tchar(menu->caption); + info->cch = al_ustr_size(menu->caption); + } + + if (menu->flags & ALLEGRO_MENU_ITEM_CHECKED) { + info->fState |= MFS_CHECKED; + } + + if (menu->flags & ALLEGRO_MENU_ITEM_DISABLED) { + info->fState |= MFS_DISABLED; + } + + if (menu->icon) { + /* convert ALLEGRO_BITMAP to HBITMAP (could be moved into a public function) */ + const int h = al_get_bitmap_height(menu->icon), w = al_get_bitmap_width(menu->icon); + HDC hdc; + HBITMAP hbmp; + BITMAPINFO bi; + uint8_t *data = NULL; + ALLEGRO_LOCKED_REGION *lock; + + ZeroMemory(&bi, sizeof(BITMAPINFO)); + bi.bmiHeader.biSize = sizeof(BITMAPINFO); + bi.bmiHeader.biWidth = w; + bi.bmiHeader.biHeight = -h; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 32; + bi.bmiHeader.biCompression = BI_RGB; + + hdc = GetDC(menu->parent->display ? al_get_win_window_handle(menu->parent->display) : NULL); + + hbmp = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&data, NULL, 0); + + lock = al_lock_bitmap(menu->icon, ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_READONLY); + memcpy(data, lock->data, w * h * 4); + al_unlock_bitmap(menu->icon); + + info->hbmpUnchecked = hbmp; + menu->extra2 = hbmp; + + ReleaseDC(menu->parent->display ? al_get_win_window_handle(menu->parent->display) : NULL, hdc); + } + + if (menu->popup) { + info->hSubMenu = (HMENU) menu->popup->extra1; + } + +} +static void destroy_menu_info(MENUITEMINFO *info) { + if (info->dwTypeData) { + al_free(info->dwTypeData); + } +} +bool _al_init_menu(ALLEGRO_MENU *menu) +{ + menu->extra1 = CreateMenu(); + return menu->extra1 != NULL; +} + +bool _al_init_popup_menu(ALLEGRO_MENU *menu) +{ + menu->extra1 = CreatePopupMenu(); + return menu->extra1 != NULL; +} + +bool _al_insert_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + MENUITEMINFO info; + init_menu_info(&info, item); + + InsertMenuItem((HMENU) item->parent->extra1, i, TRUE, &info); + destroy_menu_info(&info); + return true; +} + +bool _al_update_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + MENUITEMINFO info; + + init_menu_info(&info, item); + SetMenuItemInfo((HMENU) item->parent->extra1, i, TRUE, &info); + + if (item->parent->display) + DrawMenuBar(al_get_win_window_handle(item->parent->display)); + destroy_menu_info(&info); + return true; +} + +bool _al_destroy_menu_item_at(ALLEGRO_MENU_ITEM *item, int i) +{ + DeleteMenu((HMENU) item->parent->extra1, i, MF_BYPOSITION); + + if (item->parent->display) + DrawMenuBar(al_get_win_window_handle(item->parent->display)); + + return true; +} + +bool _al_show_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + HWND hwnd = al_get_win_window_handle(display); + if (!hwnd) return false; + + ASSERT(menu->extra1); + + /* Note that duplicate callbacks are automatically filtered out, so it's safe + to call this many times. */ + al_win_add_window_callback(display, menu_callback, NULL); + + got_wm_size_event = false; + PostMessage(al_get_win_window_handle(display), WM_SHOW_MENU, 0, (LPARAM) menu); + + /* Wait for the WM_SIZE event, otherwise the compensatory + * al_resize_display (see menu.c) won't work right. */ + if (wm_size_cond && global_mutex) { + ALLEGRO_DEBUG("Sent WM_SHOW_MENU, waiting for WM_SIZE.\n"); + al_lock_mutex(global_mutex); + while (!got_wm_size_event) { + al_wait_cond(wm_size_cond, global_mutex); + } + al_unlock_mutex(global_mutex); + } + + return true; +} + +bool _al_hide_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + HWND hwnd = al_get_win_window_handle(display); + if (!hwnd) return false; + + /* Must be run from the main thread to avoid a crash. */ + got_wm_size_event = false; + PostMessage(al_get_win_window_handle(display), WM_HIDE_MENU, 0, (LPARAM) menu); + + /* Wait for the WM_SIZE event, otherwise the compensatory + * al_resize_display (see menu.c) won't work right. */ + if (wm_size_cond && global_mutex) { + ALLEGRO_DEBUG("Sent WM_HIDE_MENU, waiting for WM_SIZE.\n"); + al_lock_mutex(global_mutex); + while (!got_wm_size_event) { + al_wait_cond(wm_size_cond, global_mutex); + } + al_unlock_mutex(global_mutex); + } + + (void) menu; + + return true; +} + +bool _al_show_popup_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +{ + /* The popup request must come from the main thread. */ + + if (!display) + return false; + + al_win_add_window_callback(display, menu_callback, NULL); + PostMessage(al_get_win_window_handle(display), WM_SHOW_POPUP, 0, (LPARAM) menu); + + return true; +} + +int _al_get_menu_display_height(void) +{ + return GetSystemMetrics(SM_CYMENU); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/physfs/CMakeLists.txt b/allegro/addons/physfs/CMakeLists.txt new file mode 100644 index 00000000..e194bd2c --- /dev/null +++ b/allegro/addons/physfs/CMakeLists.txt @@ -0,0 +1,24 @@ +include_directories(SYSTEM ${PHYSFS_INCLUDE_DIR}) + +set(PHYSFS_SOURCES a5_physfs.c a5_physfs_dir.c) + +set(PHYSFS_INCLUDE_FILES allegro5/allegro_physfs.h) + +# This allows the monolith build to find the files. +set(PHYSFS_INCLUDE_DIRECTORIES ${PHYSFS_INCLUDE_DIR}) + +set_our_header_properties(${PHYSFS_INCLUDE_FILES}) + +add_our_addon_library(allegro_physfs + AllegroPhysfs-${ALLEGRO_SOVERSION} + "${PHYSFS_SOURCES};${PHYSFS_INCLUDE_FILES}" + "-DALLEGRO_PHYSFS_SRC" + "${ALLEGRO_LINK_WITH};${PHYSFS_LIBRARIES}" + ) + +install_our_headers(${PHYSFS_INCLUDE_FILES}) + +add_addon(physfs) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/physfs/a5_physfs.c b/allegro/addons/physfs/a5_physfs.c new file mode 100644 index 00000000..a7ae1867 --- /dev/null +++ b/allegro/addons/physfs/a5_physfs.c @@ -0,0 +1,311 @@ +/* + * PhysicsFS addon for Allegro. + * + * By Peter Wang. + */ + +#include <physfs.h> +#include "allegro5/allegro.h" +#include "allegro5/allegro_physfs.h" + +#include "allegro_physfs_intern.h" + + +typedef struct ALLEGRO_FILE_PHYSFS ALLEGRO_FILE_PHYSFS; + +struct ALLEGRO_FILE_PHYSFS +{ + PHYSFS_file *phys; + bool error_indicator; + char error_msg[80]; +}; + +/* forward declaration */ +static const ALLEGRO_FILE_INTERFACE file_phys_vtable; + +const ALLEGRO_FILE_INTERFACE *_al_get_phys_vtable(void) +{ + return &file_phys_vtable; +} + + +#define streq(a, b) (0 == strcmp(a, b)) + + +static ALLEGRO_FILE_PHYSFS *cast_stream(ALLEGRO_FILE *f) +{ + return (ALLEGRO_FILE_PHYSFS *)al_get_file_userdata(f); +} + + +static void phys_set_errno(ALLEGRO_FILE_PHYSFS *fp) +{ + /* It might be worth mapping some common error strings from + * PHYSFS_getLastError() onto errno values. There are no guarantees, + * though. + */ + al_set_errno(-1); + + if (fp) { + PHYSFS_ErrorCode error = PHYSFS_getLastErrorCode(); + fp->error_indicator = true; + if (error != PHYSFS_ERR_OK) { + const char* msg = PHYSFS_getErrorByCode(error); + strncpy(fp->error_msg, msg, sizeof(fp->error_msg)); + fp->error_msg[sizeof(fp->error_msg) - 1] = '\0'; + } + else { + fp->error_msg[0] = '\0'; + } + } +} + + +static void *file_phys_fopen(const char *filename, const char *mode) +{ + ALLEGRO_USTR *us; + PHYSFS_file *phys; + ALLEGRO_FILE_PHYSFS *fp; + + us = _al_physfs_process_path(filename); + + /* XXX handle '+' modes */ + /* It might be worth adding a function to parse mode strings, to be + * shared amongst these kinds of addons. + */ + if (streq(mode, "r") || streq(mode, "rb")) + phys = PHYSFS_openRead(al_cstr(us)); + else if (streq(mode, "w") || streq(mode, "wb")) + phys = PHYSFS_openWrite(al_cstr(us)); + else if (streq(mode, "a") || streq(mode, "ab")) + phys = PHYSFS_openAppend(al_cstr(us)); + else + phys = NULL; + + al_ustr_free(us); + + if (!phys) { + phys_set_errno(NULL); + return NULL; + } + + fp = al_malloc(sizeof(*fp)); + if (!fp) { + al_set_errno(ENOMEM); + PHYSFS_close(phys); + return NULL; + } + + fp->phys = phys; + fp->error_indicator = false; + fp->error_msg[0] = '\0'; + + return fp; +} + + +static bool file_phys_fclose(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + PHYSFS_file *phys_fp = fp->phys; + + al_free(fp); + + if (PHYSFS_close(phys_fp) != 0) { + al_set_errno(-1); + return false; + } + + return true; +} + + +static size_t file_phys_fread(ALLEGRO_FILE *f, void *buf, size_t buf_size) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + PHYSFS_sint64 n; + + if (buf_size == 0) + return 0; + + n = PHYSFS_readBytes(fp->phys, buf, buf_size); + if (n < 0) { + phys_set_errno(fp); + return 0; + } + return n; +} + + +static size_t file_phys_fwrite(ALLEGRO_FILE *f, const void *buf, + size_t buf_size) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + PHYSFS_sint64 n; + + n = PHYSFS_writeBytes(fp->phys, buf, buf_size); + if (n < 0) { + phys_set_errno(fp); + return 0; + } + + return n; +} + + +static bool file_phys_fflush(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + + if (!PHYSFS_flush(fp->phys)) { + phys_set_errno(fp); + return false; + } + + return true; +} + + +static int64_t file_phys_ftell(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + PHYSFS_sint64 n; + + n = PHYSFS_tell(fp->phys); + if (n < 0) { + phys_set_errno(fp); + return -1; + } + + return n; +} + + +static bool file_phys_seek(ALLEGRO_FILE *f, int64_t offset, int whence) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + PHYSFS_sint64 base; + + switch (whence) { + case ALLEGRO_SEEK_SET: + base = 0; + break; + + case ALLEGRO_SEEK_CUR: + base = PHYSFS_tell(fp->phys); + if (base < 0) { + phys_set_errno(fp); + return false; + } + break; + + case ALLEGRO_SEEK_END: + base = PHYSFS_fileLength(fp->phys); + if (base < 0) { + phys_set_errno(fp); + return false; + } + break; + + default: + al_set_errno(EINVAL); + return false; + } + + if (!PHYSFS_seek(fp->phys, base + offset)) { + phys_set_errno(fp); + return false; + } + + return true; +} + + +static bool file_phys_feof(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + + return PHYSFS_eof(fp->phys); +} + + +static int file_phys_ferror(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + + return (fp->error_indicator) ? 1 : 0; +} + + +static const char *file_phys_ferrmsg(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + + if (fp->error_indicator) + return fp->error_msg; + else + return ""; +} + + +static void file_phys_fclearerr(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + + fp->error_indicator = false; + + /* PhysicsFS doesn't provide a way to clear the EOF indicator. */ +} + + +static off_t file_phys_fsize(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_PHYSFS *fp = cast_stream(f); + PHYSFS_sint64 n; + + n = PHYSFS_fileLength(fp->phys); + if (n < 0) { + phys_set_errno(fp); + return -1; + } + + return n; +} + + +static const ALLEGRO_FILE_INTERFACE file_phys_vtable = +{ + file_phys_fopen, + file_phys_fclose, + file_phys_fread, + file_phys_fwrite, + file_phys_fflush, + file_phys_ftell, + file_phys_seek, + file_phys_feof, + file_phys_ferror, + file_phys_ferrmsg, + file_phys_fclearerr, + NULL, /* ungetc */ + file_phys_fsize +}; + + +/* Function: al_set_physfs_file_interface + */ +void al_set_physfs_file_interface(void) +{ + al_set_new_file_interface(&file_phys_vtable); + _al_set_physfs_fs_interface(); +} + + +/* Function: al_get_allegro_physfs_version + */ +uint32_t al_get_allegro_physfs_version(void) +{ + return ALLEGRO_VERSION_INT; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/physfs/a5_physfs_dir.c b/allegro/addons/physfs/a5_physfs_dir.c new file mode 100644 index 00000000..bc0ea044 --- /dev/null +++ b/allegro/addons/physfs/a5_physfs_dir.c @@ -0,0 +1,321 @@ +/* + * Filesystem driver for the PhysFS addon. + * + * By Elias Pschernig. + */ + +#include <physfs.h> +#include "allegro5/allegro.h" +#include "allegro5/allegro_physfs.h" + +#include "allegro_physfs_intern.h" + +#if defined(ENOTSUP) + #define NOTSUP ENOTSUP +#elif defined(ENOSYS) + #define NOTSUP ENOSYS +#else + #define NOTSUP EINVAL +#endif + + +typedef struct ALLEGRO_FS_ENTRY_PHYSFS ALLEGRO_FS_ENTRY_PHYSFS; + +struct ALLEGRO_FS_ENTRY_PHYSFS +{ + ALLEGRO_FS_ENTRY fs_entry; /* must be first */ + ALLEGRO_PATH *path; + const char *path_cstr; + + /* For directory listing. */ + char **file_list; + char **file_list_pos; + bool is_dir_open; +}; + +/* forward declaration */ +static const ALLEGRO_FS_INTERFACE fs_phys_vtable; + +/* current working directory */ +/* We cannot use ALLEGRO_USTR because we have nowhere to free it. */ +static char fs_phys_cwd[1024] = "/"; + +static bool path_is_absolute(const char *path) +{ + return (path && path[0] == '/'); +} + +static void ensure_trailing_slash(ALLEGRO_USTR *us) +{ + int pos = al_ustr_size(us); + if (al_ustr_prev_get(us, &pos) != '/') { + al_ustr_append_chr(us, '/'); + } +} + +ALLEGRO_USTR *_al_physfs_process_path(const char *path) +{ + ALLEGRO_USTR *us; + ALLEGRO_PATH *p = al_create_path(path); + ALLEGRO_PATH *cwd = al_create_path(fs_phys_cwd); + al_rebase_path(cwd, p); + al_destroy_path(cwd); + /* PHYSFS always uses / separator. */ + us = al_ustr_dup(al_path_ustr(p, '/')); + al_destroy_path(p); + return us; +} + +static ALLEGRO_FS_ENTRY *fs_phys_create_entry(const char *path) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e; + ALLEGRO_USTR *us; + + e = al_calloc(1, sizeof *e); + if (!e) + return NULL; + e->fs_entry.vtable = &fs_phys_vtable; + + us = _al_physfs_process_path(path); + e->path = al_create_path(al_cstr(us)); + al_ustr_free(us); + if (!e->path) { + al_free(e); + return NULL; + } + e->path_cstr = al_path_cstr(e->path, '/'); + return &e->fs_entry; +} + +static char *fs_phys_get_current_directory(void) +{ + size_t size = strlen(fs_phys_cwd) + 1; + char *s = al_malloc(size); + if (s) { + memcpy(s, fs_phys_cwd, size); + } + return s; +} + +static bool fs_phys_change_directory(const char *path) +{ + ALLEGRO_USTR *us; + bool ret; + PHYSFS_Stat stat; + + /* '/' root is guaranteed to exist but PHYSFS won't find it. */ + if (path[0] == '/' && path[1] == '\0') { + fs_phys_cwd[0] = '/'; + fs_phys_cwd[1] = '\0'; + return true; + } + + /* Figure out which directory we are trying to change to. */ + if (path_is_absolute(path)) + us = al_ustr_new(path); + else + us = _al_physfs_process_path(path); + + ret = false; + + if (!PHYSFS_stat(al_cstr(us), &stat)) + return false; + + if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY ) { + ensure_trailing_slash(us); + + /* Copy to static buffer. */ + if ((size_t) al_ustr_size(us) < sizeof(fs_phys_cwd)) { + al_ustr_to_buffer(us, fs_phys_cwd, sizeof(fs_phys_cwd)); + ret = true; + } + } + + al_ustr_free(us); + + return ret; +} + +static bool fs_phys_filename_exists(const char *path) +{ + ALLEGRO_USTR *us; + bool ret; + + us = _al_physfs_process_path(path); + ret = PHYSFS_exists(al_cstr(us)) ? true : false; + al_ustr_free(us); + return ret; +} + +static bool fs_phys_remove_filename(const char *path) +{ + ALLEGRO_USTR *us; + bool ret; + + us = _al_physfs_process_path(path); + ret = PHYSFS_delete(al_cstr(us)) ? true : false; + al_ustr_free(us); + return ret; +} + +static bool fs_phys_make_directory(const char *path) +{ + ALLEGRO_USTR *us; + bool ret; + + us = _al_physfs_process_path(path); + ret = PHYSFS_mkdir(al_cstr(us)) ? true : false; + al_ustr_free(us); + return ret; +} + +static const char *fs_phys_entry_name(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + return al_path_cstr(e->path, '/'); +} + +static bool fs_phys_update_entry(ALLEGRO_FS_ENTRY *fse) +{ + (void)fse; + return true; +} + +static off_t fs_phys_entry_size(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + PHYSFS_file *f = PHYSFS_openRead(e->path_cstr); + if (f) { + off_t s = PHYSFS_fileLength(f); + PHYSFS_close(f); + return s; + } + return 0; +} + +static uint32_t fs_phys_entry_mode(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + uint32_t mode = ALLEGRO_FILEMODE_READ; + PHYSFS_Stat stat; + if (!PHYSFS_stat(e->path_cstr, &stat)) + return mode; + + if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY ) + mode |= ALLEGRO_FILEMODE_ISDIR | ALLEGRO_FILEMODE_EXECUTE; + else + mode |= ALLEGRO_FILEMODE_ISFILE; + return mode; +} + +static time_t fs_phys_entry_mtime(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + PHYSFS_Stat stat; + if (!PHYSFS_stat(e->path_cstr, &stat)) + return -1; + return stat.modtime; +} + +static bool fs_phys_entry_exists(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + return PHYSFS_exists(e->path_cstr) != 0; +} + +static bool fs_phys_remove_entry(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + return PHYSFS_delete(e->path_cstr) != 0; +} + +static bool fs_phys_open_directory(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + + e->file_list = PHYSFS_enumerateFiles(e->path_cstr); + e->file_list_pos = e->file_list; + + e->is_dir_open = true; + return true; +} + +static ALLEGRO_FS_ENTRY *fs_phys_read_directory(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + ALLEGRO_FS_ENTRY *next; + ALLEGRO_USTR *tmp; + + if (!e->file_list_pos) + return NULL; + if (!*e->file_list_pos) + return NULL; + + tmp = al_ustr_new(e->path_cstr); + ensure_trailing_slash(tmp); + al_ustr_append_cstr(tmp, *e->file_list_pos); + next = fs_phys_create_entry(al_cstr(tmp)); + al_ustr_free(tmp); + + e->file_list_pos++; + + return next; +} + +static bool fs_phys_close_directory(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + PHYSFS_freeList(e->file_list); + e->file_list = NULL; + e->is_dir_open = false; + return true; +} + +static void fs_phys_destroy_entry(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_PHYSFS *e = (ALLEGRO_FS_ENTRY_PHYSFS *)fse; + if (e->is_dir_open) + fs_phys_close_directory(fse); + al_destroy_path(e->path); + al_free(e); +} + +static ALLEGRO_FILE *fs_phys_open_file(ALLEGRO_FS_ENTRY *fse, const char *mode) +{ + return al_fopen_interface(_al_get_phys_vtable(), fs_phys_entry_name(fse), + mode); +} + +static const ALLEGRO_FS_INTERFACE fs_phys_vtable = +{ + fs_phys_create_entry, + fs_phys_destroy_entry, + fs_phys_entry_name, + fs_phys_update_entry, + fs_phys_entry_mode, + fs_phys_entry_mtime, + fs_phys_entry_mtime, + fs_phys_entry_mtime, + fs_phys_entry_size, + fs_phys_entry_exists, + fs_phys_remove_entry, + + fs_phys_open_directory, + fs_phys_read_directory, + fs_phys_close_directory, + + fs_phys_filename_exists, + fs_phys_remove_filename, + fs_phys_get_current_directory, + fs_phys_change_directory, + fs_phys_make_directory, + + fs_phys_open_file +}; + +void _al_set_physfs_fs_interface(void) +{ + al_set_fs_interface(&fs_phys_vtable); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/physfs/allegro5/allegro_physfs.h b/allegro/addons/physfs/allegro5/allegro_physfs.h new file mode 100644 index 00000000..494da6a4 --- /dev/null +++ b/allegro/addons/physfs/allegro5/allegro_physfs.h @@ -0,0 +1,41 @@ +#ifndef __al_included_allegro5_allegro_physfs_h +#define __al_included_allegro5_allegro_physfs_h + +#include "allegro5/allegro.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_PHYSFS_SRC + #define _ALLEGRO_PHYSFS_DLL __declspec(dllexport) + #else + #define _ALLEGRO_PHYSFS_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_PHYSFS_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_PHYSFS_FUNC(type, name, args) _ALLEGRO_PHYSFS_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_PHYSFS_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_PHYSFS_FUNC(type, name, args) extern _ALLEGRO_PHYSFS_DLL type name args +#else + #define ALLEGRO_PHYSFS_FUNC AL_FUNC +#endif + + +ALLEGRO_PHYSFS_FUNC(void, al_set_physfs_file_interface, (void)); +ALLEGRO_PHYSFS_FUNC(uint32_t, al_get_allegro_physfs_version, (void)); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/addons/physfs/allegro_physfs_intern.h b/allegro/addons/physfs/allegro_physfs_intern.h new file mode 100644 index 00000000..33d67eec --- /dev/null +++ b/allegro/addons/physfs/allegro_physfs_intern.h @@ -0,0 +1,8 @@ +#ifndef __al_included_allegro5_allegro_physfs_intern_h +#define __al_included_allegro5_allegro_physfs_intern_h + +void _al_set_physfs_fs_interface(void); +const ALLEGRO_FILE_INTERFACE *_al_get_phys_vtable(void); +ALLEGRO_USTR *_al_physfs_process_path(const char *path); + +#endif diff --git a/allegro/addons/primitives/CMakeLists.txt b/allegro/addons/primitives/CMakeLists.txt new file mode 100644 index 00000000..b65a2c5e --- /dev/null +++ b/allegro/addons/primitives/CMakeLists.txt @@ -0,0 +1,37 @@ +set(PRIMITIVES_SOURCES + high_primitives.c + line_soft.c + point_soft.c + polygon.c + polyline.c + prim_directx.cpp + prim_opengl.c + prim_soft.c + prim_util.c + primitives.c + triangulator.c + ) + +if(WIN32) + # Add this file conditionally. + # The Debian folks want to remove it because it contains precompiled code. + list(APPEND PRIMITIVES_SOURCES directx_shaders.cpp) +endif(WIN32) + +set(PRIMITIVES_INCLUDE_FILES allegro5/allegro_primitives.h) + +set_our_header_properties(${PRIMITIVES_INCLUDE_FILES}) + +add_our_addon_library(allegro_primitives + AllegroPrimitives-${ALLEGRO_SOVERSION} + "${PRIMITIVES_SOURCES};${PRIMITIVES_INCLUDE_FILES}" + "-DALLEGRO_PRIMITIVES_SRC" + "${ALLEGRO_LINK_WITH}" + ) + +install_our_headers(${PRIMITIVES_INCLUDE_FILES}) + +add_addon(primitives) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/primitives/allegro5/allegro_primitives.h b/allegro/addons/primitives/allegro5/allegro_primitives.h new file mode 100644 index 00000000..27a337d1 --- /dev/null +++ b/allegro/addons/primitives/allegro5/allegro_primitives.h @@ -0,0 +1,254 @@ +#ifndef __al_included_allegro5_allegro_primitives_h +#define __al_included_allegro5_allegro_primitives_h + +#include <allegro5/allegro.h> + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) +#ifndef ALLEGRO_STATICLINK +#ifdef ALLEGRO_PRIMITIVES_SRC +#define _ALLEGRO_PRIM_DLL __declspec(dllexport) +#else +#define _ALLEGRO_PRIM_DLL __declspec(dllimport) +#endif +#else +#define _ALLEGRO_PRIM_DLL +#endif +#endif + +#if defined ALLEGRO_MSVC +#define ALLEGRO_PRIM_FUNC(type, name, args) _ALLEGRO_PRIM_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 +#define ALLEGRO_PRIM_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 +#define ALLEGRO_PRIM_FUNC(type, name, args) extern _ALLEGRO_PRIM_DLL type name args +#else +#define ALLEGRO_PRIM_FUNC AL_FUNC +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Enum: ALLEGRO_PRIM_TYPE + */ +typedef enum ALLEGRO_PRIM_TYPE +{ + ALLEGRO_PRIM_LINE_LIST, + ALLEGRO_PRIM_LINE_STRIP, + ALLEGRO_PRIM_LINE_LOOP, + ALLEGRO_PRIM_TRIANGLE_LIST, + ALLEGRO_PRIM_TRIANGLE_STRIP, + ALLEGRO_PRIM_TRIANGLE_FAN, + ALLEGRO_PRIM_POINT_LIST, + ALLEGRO_PRIM_NUM_TYPES +} ALLEGRO_PRIM_TYPE; + +enum +{ + ALLEGRO_PRIM_MAX_USER_ATTR = _ALLEGRO_PRIM_MAX_USER_ATTR +}; + +/* Enum: ALLEGRO_PRIM_ATTR + */ +typedef enum ALLEGRO_PRIM_ATTR +{ + ALLEGRO_PRIM_POSITION = 1, + ALLEGRO_PRIM_COLOR_ATTR, + ALLEGRO_PRIM_TEX_COORD, + ALLEGRO_PRIM_TEX_COORD_PIXEL, + ALLEGRO_PRIM_USER_ATTR, + ALLEGRO_PRIM_ATTR_NUM = ALLEGRO_PRIM_USER_ATTR + ALLEGRO_PRIM_MAX_USER_ATTR +} ALLEGRO_PRIM_ATTR; + +/* Enum: ALLEGRO_PRIM_STORAGE + */ +typedef enum ALLEGRO_PRIM_STORAGE +{ + ALLEGRO_PRIM_FLOAT_2, + ALLEGRO_PRIM_FLOAT_3, + ALLEGRO_PRIM_SHORT_2, + ALLEGRO_PRIM_FLOAT_1, + ALLEGRO_PRIM_FLOAT_4, + ALLEGRO_PRIM_UBYTE_4, + ALLEGRO_PRIM_SHORT_4, + ALLEGRO_PRIM_NORMALIZED_UBYTE_4, + ALLEGRO_PRIM_NORMALIZED_SHORT_2, + ALLEGRO_PRIM_NORMALIZED_SHORT_4, + ALLEGRO_PRIM_NORMALIZED_USHORT_2, + ALLEGRO_PRIM_NORMALIZED_USHORT_4, + ALLEGRO_PRIM_HALF_FLOAT_2, + ALLEGRO_PRIM_HALF_FLOAT_4 +} ALLEGRO_PRIM_STORAGE; + +/* Enum: ALLEGRO_LINE_JOIN + */ +typedef enum ALLEGRO_LINE_JOIN +{ + ALLEGRO_LINE_JOIN_NONE, + ALLEGRO_LINE_JOIN_BEVEL, + ALLEGRO_LINE_JOIN_ROUND, + ALLEGRO_LINE_JOIN_MITER, + ALLEGRO_LINE_JOIN_MITRE = ALLEGRO_LINE_JOIN_MITER +} ALLEGRO_LINE_JOIN; + +/* Enum: ALLEGRO_LINE_CAP + */ +typedef enum ALLEGRO_LINE_CAP +{ + ALLEGRO_LINE_CAP_NONE, + ALLEGRO_LINE_CAP_SQUARE, + ALLEGRO_LINE_CAP_ROUND, + ALLEGRO_LINE_CAP_TRIANGLE, + ALLEGRO_LINE_CAP_CLOSED +} ALLEGRO_LINE_CAP; + +/* Enum: ALLEGRO_PRIM_BUFFER_FLAGS + */ +typedef enum ALLEGRO_PRIM_BUFFER_FLAGS +{ + ALLEGRO_PRIM_BUFFER_STREAM = 0x01, + ALLEGRO_PRIM_BUFFER_STATIC = 0x02, + ALLEGRO_PRIM_BUFFER_DYNAMIC = 0x04, + ALLEGRO_PRIM_BUFFER_READWRITE = 0x08 +} ALLEGRO_PRIM_BUFFER_FLAGS; + +/* Enum: ALLEGRO_VERTEX_CACHE_SIZE + */ +#define ALLEGRO_VERTEX_CACHE_SIZE 256 + +/* Enum: ALLEGRO_PRIM_QUALITY + */ +#define ALLEGRO_PRIM_QUALITY 10 + +/* Type: ALLEGRO_VERTEX_ELEMENT + */ +typedef struct ALLEGRO_VERTEX_ELEMENT ALLEGRO_VERTEX_ELEMENT; + +struct ALLEGRO_VERTEX_ELEMENT { + int attribute; + int storage; + int offset; +}; + +/* Type: ALLEGRO_VERTEX_DECL + */ +typedef struct ALLEGRO_VERTEX_DECL ALLEGRO_VERTEX_DECL; + +/* Duplicated in allegro5/internal/aintern_tri_soft.h */ +#ifndef _ALLEGRO_VERTEX_DEFINED +#define _ALLEGRO_VERTEX_DEFINED + +/* Type: ALLEGRO_VERTEX + */ +typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX; + +struct ALLEGRO_VERTEX { + float x, y, z; + float u, v; + ALLEGRO_COLOR color; +}; +#endif + +/* Type: ALLEGRO_VERTEX_BUFFER + */ +typedef struct ALLEGRO_VERTEX_BUFFER ALLEGRO_VERTEX_BUFFER; + +/* Type: ALLEGRO_INDEX_BUFFER + */ +typedef struct ALLEGRO_INDEX_BUFFER ALLEGRO_INDEX_BUFFER; + +ALLEGRO_PRIM_FUNC(uint32_t, al_get_allegro_primitives_version, (void)); + +/* +* Primary Functions +*/ +ALLEGRO_PRIM_FUNC(bool, al_init_primitives_addon, (void)); +ALLEGRO_PRIM_FUNC(bool, al_is_primitives_addon_initialized, (void)); +ALLEGRO_PRIM_FUNC(void, al_shutdown_primitives_addon, (void)); +ALLEGRO_PRIM_FUNC(int, al_draw_prim, (const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture, int start, int end, int type)); +ALLEGRO_PRIM_FUNC(int, al_draw_indexed_prim, (const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type)); +ALLEGRO_PRIM_FUNC(int, al_draw_vertex_buffer, (ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_BITMAP* texture, int start, int end, int type)); +ALLEGRO_PRIM_FUNC(int, al_draw_indexed_buffer, (ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_BITMAP* texture, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type)); + +ALLEGRO_PRIM_FUNC(ALLEGRO_VERTEX_DECL*, al_create_vertex_decl, (const ALLEGRO_VERTEX_ELEMENT* elements, int stride)); +ALLEGRO_PRIM_FUNC(void, al_destroy_vertex_decl, (ALLEGRO_VERTEX_DECL* decl)); + +/* + * Vertex buffers + */ +ALLEGRO_PRIM_FUNC(ALLEGRO_VERTEX_BUFFER*, al_create_vertex_buffer, (ALLEGRO_VERTEX_DECL* decl, const void* initial_data, int num_vertices, int flags)); +ALLEGRO_PRIM_FUNC(void, al_destroy_vertex_buffer, (ALLEGRO_VERTEX_BUFFER* buffer)); +ALLEGRO_PRIM_FUNC(void*, al_lock_vertex_buffer, (ALLEGRO_VERTEX_BUFFER* buffer, int offset, int length, int flags)); +ALLEGRO_PRIM_FUNC(void, al_unlock_vertex_buffer, (ALLEGRO_VERTEX_BUFFER* buffer)); +ALLEGRO_PRIM_FUNC(int, al_get_vertex_buffer_size, (ALLEGRO_VERTEX_BUFFER* buffer)); + +/* + * Index buffers + */ +ALLEGRO_PRIM_FUNC(ALLEGRO_INDEX_BUFFER*, al_create_index_buffer, (int index_size, const void* initial_data, int num_indices, int flags)); +ALLEGRO_PRIM_FUNC(void, al_destroy_index_buffer, (ALLEGRO_INDEX_BUFFER* buffer)); +ALLEGRO_PRIM_FUNC(void*, al_lock_index_buffer, (ALLEGRO_INDEX_BUFFER* buffer, int offset, int length, int flags)); +ALLEGRO_PRIM_FUNC(void, al_unlock_index_buffer, (ALLEGRO_INDEX_BUFFER* buffer)); +ALLEGRO_PRIM_FUNC(int, al_get_index_buffer_size, (ALLEGRO_INDEX_BUFFER* buffer)); + +/* +* Utilities for high level primitives. +*/ +ALLEGRO_PRIM_FUNC(bool, al_triangulate_polygon, (const float* vertices, size_t vertex_stride, const int* vertex_counts, void (*emit_triangle)(int, int, int, void*), void* userdata)); + + +/* +* Custom primitives +*/ +ALLEGRO_PRIM_FUNC(void, al_draw_soft_triangle, (ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, + void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*first)(uintptr_t, int, int, int, int), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int, int))); +ALLEGRO_PRIM_FUNC(void, al_draw_soft_line, (ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state, + void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int))); + +/* +*High level primitives +*/ +ALLEGRO_PRIM_FUNC(void, al_draw_line, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_triangle, (float x1, float y1, float x2, float y2, float x3, float y3, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_rectangle, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_rounded_rectangle, (float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR color, float thickness)); + +ALLEGRO_PRIM_FUNC(void, al_calculate_arc, (float* dest, int stride, float cx, float cy, float rx, float ry, float start_theta, float delta_theta, float thickness, int num_points)); +ALLEGRO_PRIM_FUNC(void, al_draw_circle, (float cx, float cy, float r, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_ellipse, (float cx, float cy, float rx, float ry, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_arc, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_elliptical_arc, (float cx, float cy, float rx, float ry, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); +ALLEGRO_PRIM_FUNC(void, al_draw_pieslice, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color, float thickness)); + +ALLEGRO_PRIM_FUNC(void, al_calculate_spline, (float* dest, int stride, float points[8], float thickness, int num_segments)); +ALLEGRO_PRIM_FUNC(void, al_draw_spline, (float points[8], ALLEGRO_COLOR color, float thickness)); + +ALLEGRO_PRIM_FUNC(void, al_calculate_ribbon, (float* dest, int dest_stride, const float *points, int points_stride, float thickness, int num_segments)); +ALLEGRO_PRIM_FUNC(void, al_draw_ribbon, (const float *points, int points_stride, ALLEGRO_COLOR color, float thickness, int num_segments)); + +ALLEGRO_PRIM_FUNC(void, al_draw_filled_triangle, (float x1, float y1, float x2, float y2, float x3, float y3, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_rectangle, (float x1, float y1, float x2, float y2, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_ellipse, (float cx, float cy, float rx, float ry, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_circle, (float cx, float cy, float r, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_pieslice, (float cx, float cy, float r, float start_theta, float delta_theta, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_rounded_rectangle, (float x1, float y1, float x2, float y2, float rx, float ry, ALLEGRO_COLOR color)); + +ALLEGRO_PRIM_FUNC(void, al_draw_polyline, (const float* vertices, int vertex_stride, int vertex_count, int join_style, int cap_style, ALLEGRO_COLOR color, float thickness, float miter_limit)); + +ALLEGRO_PRIM_FUNC(void, al_draw_polygon, (const float* vertices, int vertex_count, int join_style, ALLEGRO_COLOR color, float thickness, float miter_limit)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_polygon, (const float* vertices, int vertex_count, ALLEGRO_COLOR color)); +ALLEGRO_PRIM_FUNC(void, al_draw_filled_polygon_with_holes, (const float* vertices, const int* vertex_counts, ALLEGRO_COLOR color)); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/addons/primitives/allegro5/internal/aintern_prim.h b/allegro/addons/primitives/allegro5/internal/aintern_prim.h new file mode 100644 index 00000000..fa726e0f --- /dev/null +++ b/allegro/addons/primitives/allegro5/internal/aintern_prim.h @@ -0,0 +1,79 @@ +#ifndef __al_included_allegro5_aintern_prim_h +#define __al_included_allegro5_aintern_prim_h + +#ifdef __cplusplus +extern "C" { +#endif + +enum ALLEGRO_PRIM_VERTEX_CACHE_TYPE +{ + ALLEGRO_PRIM_VERTEX_CACHE_TRIANGLE, + ALLEGRO_PRIM_VERTEX_CACHE_LINE_STRIP +}; + +struct ALLEGRO_VERTEX_DECL { + ALLEGRO_VERTEX_ELEMENT* elements; + int stride; + void* d3d_decl; + void* d3d_dummy_shader; +}; + +typedef struct ALLEGRO_PRIM_VERTEX_CACHE { + ALLEGRO_VERTEX buffer[ALLEGRO_VERTEX_CACHE_SIZE]; + ALLEGRO_VERTEX* current; + size_t size; + ALLEGRO_COLOR color; + int prim_type; + void* user_data; +} ALLEGRO_PRIM_VERTEX_CACHE; + +typedef struct ALLEGRO_BUFFER_COMMON { + uintptr_t handle; + bool write_only; + /* In elements */ + int size; + + bool is_locked; + int lock_flags; + void* locked_memory; + /* These three are in bytes */ + int local_buffer_length; + int lock_offset; + int lock_length; +} ALLEGRO_BUFFER_COMMON; + +struct ALLEGRO_VERTEX_BUFFER { + ALLEGRO_VERTEX_DECL* decl; + ALLEGRO_BUFFER_COMMON common; +}; + +struct ALLEGRO_INDEX_BUFFER { + int index_size; + ALLEGRO_BUFFER_COMMON common; +}; + +/* Internal cache for primitives. */ +void _al_prim_cache_init(ALLEGRO_PRIM_VERTEX_CACHE* cache, int prim_type, ALLEGRO_COLOR color); +void _al_prim_cache_init_ex(ALLEGRO_PRIM_VERTEX_CACHE* cache, int prim_type, ALLEGRO_COLOR color, void* user_data); +void _al_prim_cache_term(ALLEGRO_PRIM_VERTEX_CACHE* cache); +void _al_prim_cache_flush(ALLEGRO_PRIM_VERTEX_CACHE* cache); +void _al_prim_cache_push_point(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* v); +void _al_prim_cache_push_triangle(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* v0, const float* v1, const float* v2); + + +/* Internal functions. */ +float _al_prim_get_scale(void); +float _al_prim_normalize(float* vector); +int _al_prim_test_line_side(const float* origin, const float* normal, const float* point); +bool _al_prim_is_point_in_triangle(const float* point, const float* v0, const float* v1, const float* v2); +bool _al_prim_intersect_segment(const float* v0, const float* v1, const float* p0, const float* p1, float* point, float* t0, float* t1); +bool _al_prim_are_points_equal(const float* point_a, const float* point_b); + +int _al_bitmap_region_is_locked(ALLEGRO_BITMAP* bmp, int x1, int y1, int x2, int y2); +int _al_draw_buffer_common_soft(ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_BITMAP* texture, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/addons/primitives/allegro5/internal/aintern_prim_directx.h b/allegro/addons/primitives/allegro5/internal/aintern_prim_directx.h new file mode 100644 index 00000000..6abff2f4 --- /dev/null +++ b/allegro/addons/primitives/allegro5/internal/aintern_prim_directx.h @@ -0,0 +1,42 @@ +#ifndef __al_included_allegro5_aintern_prim_directx_h +#define __al_included_allegro5_aintern_prim_directx_h + +struct ALLEGRO_BITMAP; +struct ALLEGRO_VERTEX; + +#ifdef __cplusplus +extern "C" { +#endif + +int _al_draw_prim_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type); +int _al_draw_prim_indexed_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type); +void _al_set_d3d_decl(ALLEGRO_DISPLAY* display, ALLEGRO_VERTEX_DECL* ret); + +bool _al_create_vertex_buffer_directx(ALLEGRO_VERTEX_BUFFER* buf, const void* initial_data, size_t num_vertices, int flags); +void _al_destroy_vertex_buffer_directx(ALLEGRO_VERTEX_BUFFER* buf); +void* _al_lock_vertex_buffer_directx(ALLEGRO_VERTEX_BUFFER* buf); +void _al_unlock_vertex_buffer_directx(ALLEGRO_VERTEX_BUFFER* buf); + +bool _al_create_index_buffer_directx(ALLEGRO_INDEX_BUFFER* buf, const void* initial_data, size_t num_indices, int flags); +void _al_destroy_index_buffer_directx(ALLEGRO_INDEX_BUFFER* buf); +void* _al_lock_index_buffer_directx(ALLEGRO_INDEX_BUFFER* buf); +void _al_unlock_index_buffer_directx(ALLEGRO_INDEX_BUFFER* buf); + +int _al_draw_vertex_buffer_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, int start, int end, int type); +int _al_draw_indexed_buffer_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type); + +bool _al_init_d3d_driver(void); +void _al_shutdown_d3d_driver(void); + +void* _al_create_default_primitives_shader(void* dev); +void _al_setup_default_primitives_shader(void* dev, void* shader); + +void _al_setup_primitives_shader(void* dev, const ALLEGRO_VERTEX_DECL* decl); +void _al_create_primitives_shader(void* dev, ALLEGRO_VERTEX_DECL* decl); +void _al_set_texture_matrix(void* dev, float* mat); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/addons/primitives/allegro5/internal/aintern_prim_opengl.h b/allegro/addons/primitives/allegro5/internal/aintern_prim_opengl.h new file mode 100644 index 00000000..9d8e42c8 --- /dev/null +++ b/allegro/addons/primitives/allegro5/internal/aintern_prim_opengl.h @@ -0,0 +1,20 @@ +#ifndef __al_included_allegro5_aintern_prim_opengl_h +#define __al_included_allegro5_aintern_prim_opengl_h + +int _al_draw_prim_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type); +int _al_draw_prim_indexed_opengl(ALLEGRO_BITMAP *target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type); + +bool _al_create_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf, const void* initial_data, size_t num_vertices, int flags); +void _al_destroy_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf); +void* _al_lock_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf); +void _al_unlock_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf); + +bool _al_create_index_buffer_opengl(ALLEGRO_INDEX_BUFFER* buf, const void* initial_data, size_t num_indices, int flags); +void _al_destroy_index_buffer_opengl(ALLEGRO_INDEX_BUFFER* buf); +void* _al_lock_index_buffer_opengl(ALLEGRO_INDEX_BUFFER* buf); +void _al_unlock_index_buffer_opengl(ALLEGRO_INDEX_BUFFER* buf); + +int _al_draw_vertex_buffer_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, int start, int end, int type); +int _al_draw_indexed_buffer_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type); + +#endif diff --git a/allegro/addons/primitives/allegro5/internal/aintern_prim_soft.h b/allegro/addons/primitives/allegro5/internal/aintern_prim_soft.h new file mode 100644 index 00000000..e658acab --- /dev/null +++ b/allegro/addons/primitives/allegro5/internal/aintern_prim_soft.h @@ -0,0 +1,21 @@ +#ifndef __al_included_allegro5_aintern_prim_soft_h +#define __al_included_allegro5_aintern_prim_soft_h + +struct ALLEGRO_BITMAP; +struct ALLEGRO_VERTEX; + +#ifdef __cplusplus +extern "C" { +#endif + +int _al_draw_prim_soft(ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type); +int _al_draw_prim_indexed_soft(ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type); + +void _al_line_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2); +void _al_point_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/addons/primitives/directx_shaders.cpp b/allegro/addons/primitives/directx_shaders.cpp new file mode 100644 index 00000000..a27777c3 --- /dev/null +++ b/allegro/addons/primitives/directx_shaders.cpp @@ -0,0 +1,191 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * DirectX dummy shader support. Dummy shader doesn't do anything + * except making D3D happy when you pass it vertices with non-FVF + * memory layout. + * + * By Pavel Sountsov. + * + * Thanks to Michał Cichoń for the pre-compiled shader code. + * + * See readme.txt for copyright information. + */ + +#include <string.h> +#include "allegro5/allegro_primitives.h" +#include "allegro5/internal/aintern_prim.h" +#include "allegro5/platform/alplatf.h" + +#ifdef ALLEGRO_CFG_D3D + +#include "allegro5/allegro_direct3d.h" +#include "allegro5/internal/aintern_prim_directx.h" + +#include "precompiled_shaders.inc" + +void _al_create_primitives_shader(void* dev, ALLEGRO_VERTEX_DECL* decl) +{ + LPDIRECT3DDEVICE9 device = (LPDIRECT3DDEVICE9)dev; + LPDIRECT3DVERTEXSHADER9 ret = 0; + + ALLEGRO_VERTEX_ELEMENT* e; + + int position = 0; + int texture = 0; + int color = 0; + + const uint8_t* shader = NULL; + + /*position, texture, color*/ + const uint8_t* shaders[3][2][2] = + { + { + {_al_vs_pos0_tex0_col0, _al_vs_pos0_tex0_col4}, + {_al_vs_pos0_tex2_col0, _al_vs_pos0_tex2_col4} + }, + { + {_al_vs_pos2_tex0_col0, _al_vs_pos2_tex0_col4}, + {_al_vs_pos2_tex2_col0, _al_vs_pos2_tex2_col4} + }, + { + {_al_vs_pos3_tex0_col0, _al_vs_pos3_tex0_col4}, + {_al_vs_pos3_tex2_col0, _al_vs_pos3_tex2_col4} + } + }; + + e = &decl->elements[ALLEGRO_PRIM_POSITION]; + if (e->attribute) { + switch(e->storage) { + case ALLEGRO_PRIM_SHORT_2: + case ALLEGRO_PRIM_FLOAT_2: + position = 1; + break; + case ALLEGRO_PRIM_FLOAT_3: + position = 2; + break; + } + } + + e = &decl->elements[ALLEGRO_PRIM_TEX_COORD]; + if(!e->attribute) + e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; + if(e->attribute) { + texture = 1; + } + + e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR]; + if(e->attribute) { + color = 1; + } + + shader = shaders[position][texture][color]; + + IDirect3DDevice9_CreateVertexShader(device, (const DWORD*)shader, &ret); + + decl->d3d_dummy_shader = ret; +} + +void* _al_create_default_primitives_shader(void* dev) +{ + LPDIRECT3DDEVICE9 device = (LPDIRECT3DDEVICE9)dev; + LPDIRECT3DVERTEXSHADER9 shader; + IDirect3DDevice9_CreateVertexShader(device, (const DWORD*)_al_vs_pos3_tex2_col4, &shader); + return shader; +} + +static void _al_swap(float* l, float* r) +{ + float temp = *r; + *r = *l; + *l = temp; +} + +static void _al_transpose_d3d_matrix(D3DMATRIX* m) +{ + int i, j; + float* m_ptr = (float*)m; + + for (i = 1; i < 4; i++) { + for (j = 0; j < i; j++) { + _al_swap(m_ptr + (i * 4 + j), m_ptr + (j * 4 + i)); + } + } +} + +static void _al_multiply_d3d_matrix(D3DMATRIX* result, const D3DMATRIX* a, const D3DMATRIX* b) +{ + int i, j, k; + float* r_ptr = (float*)result; + float* a_ptr = (float*)a; + float* b_ptr = (float*)b; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + r_ptr[i * 4 + j] = 0.0f; + for (k = 0; k < 4; k++) { + r_ptr[i * 4 + j] += a_ptr[i * 4 + k] * b_ptr[k * 4 + j]; + } + } + } +} + +static void _al_multiply_transpose_d3d_matrix(D3DMATRIX* result, const D3DMATRIX* a, const D3DMATRIX* b) +{ + int i, j, k; + float* r_ptr = (float*)result; + float* a_ptr = (float*)a; + float* b_ptr = (float*)b; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + r_ptr[i + 4 * j] = 0.0f; + for (k = 0; k < 4; k++) { + r_ptr[i + 4 * j] += a_ptr[i * 4 + k] * b_ptr[k * 4 + j]; + } + } + } +} + +/* note: passed matrix may be modified by this function */ +void _al_set_texture_matrix(void* dev, float* mat) +{ + _al_transpose_d3d_matrix((D3DMATRIX*)mat); + IDirect3DDevice9_SetVertexShaderConstantF((IDirect3DDevice9*)dev, 4, mat, 4); +} + +static void setup_transforms(IDirect3DDevice9* device) +{ + D3DMATRIX matWorld, matView, matProj, matWorldView, matWorldViewProj; + IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &matWorld); + IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &matView); + IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &matProj); + _al_multiply_d3d_matrix(&matWorldView, &matWorld, &matView); + _al_multiply_transpose_d3d_matrix(&matWorldViewProj, &matWorldView, &matProj); + IDirect3DDevice9_SetVertexShaderConstantF(device, 0, (float*)&matWorldViewProj, 4); +} + +void _al_setup_primitives_shader(void* dev, const ALLEGRO_VERTEX_DECL* decl) +{ + IDirect3DDevice9* device = (IDirect3DDevice9*)dev; + setup_transforms(device); + IDirect3DDevice9_SetVertexShader(device, (IDirect3DVertexShader9*)decl->d3d_dummy_shader); +} + +void _al_setup_default_primitives_shader(void* dev, void* shader) +{ + IDirect3DDevice9* device = (IDirect3DDevice9*)dev; + setup_transforms(device); + IDirect3DDevice9_SetVertexShader(device, (LPDIRECT3DVERTEXSHADER9)shader); +} + +#endif /* ALLEGRO_CFG_D3D */ + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/primitives/high_primitives.c b/allegro/addons/primitives/high_primitives.c new file mode 100644 index 00000000..c3a94f30 --- /dev/null +++ b/allegro/addons/primitives/high_primitives.c @@ -0,0 +1,1278 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Some high level routines, provided for user's convinience. + * + * + * By Pavel Sountsov. + * + * + * Bezier spline plotter By Seymour Shlien. + * + * Optimised version by Sven Sandberg. + * + * I'm not sure wether or not we still use the Castelau Algorithm + * described in the book :o) + * + * Interactive Computer Graphics + * by Peter Burger and Duncan Gillies + * Addison-Wesley Publishing Co 1989 + * ISBN 0-201-17439-1 + * + * The 4 th order Bezier curve is a cubic curve passing + * through the first and fourth point. The curve does + * not pass through the middle two points. They are merely + * guide points which control the shape of the curve. The + * curve is tangent to the lines joining points 1 and 2 + * and points 3 and 4. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro_primitives.h" +#ifdef ALLEGRO_CFG_OPENGL +#include "allegro5/allegro_opengl.h" +#endif +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/debug.h" +#include <math.h> + +ALLEGRO_DEBUG_CHANNEL("primitives") + +#ifdef ALLEGRO_MSVC + #define hypotf(x, y) _hypotf((x), (y)) +#endif + +#define LOCAL_VERTEX_CACHE ALLEGRO_VERTEX vertex_cache[ALLEGRO_VERTEX_CACHE_SIZE] + +/* + * Make an estimate of the scale of the current transformation. + * We do this by computing the determinants of the 2D section of the transformation matrix. + */ +static float get_scale(void) +{ +#define DET2D(T) (fabs((T)->m[0][0] * (T)->m[1][1] - (T)->m[0][1] * (T)->m[1][0])) + + const ALLEGRO_TRANSFORM* t = al_get_current_transform(); + float scale_sq = DET2D(t); + ALLEGRO_BITMAP* b = al_get_target_bitmap(); + if (b) { + const ALLEGRO_TRANSFORM* p = al_get_current_projection_transform(); + /* Divide by 4.0f as the screen coordinates range from -1 to 1 on both axes. */ + scale_sq *= DET2D(p) * al_get_bitmap_width(b) * al_get_bitmap_height(b) / 4.0f; + } + + return sqrtf(scale_sq); + +#undef DET2D +} + +/* Function: al_draw_line + */ +void al_draw_line(float x1, float y1, float x2, float y2, + ALLEGRO_COLOR color, float thickness) +{ + if (thickness > 0) { + int ii; + float tx, ty; + float len = hypotf(x2 - x1, y2 - y1); + + ALLEGRO_VERTEX vtx[4]; + + if (len == 0) + return; + + tx = 0.5f * thickness * (y2 - y1) / len; + ty = 0.5f * thickness * -(x2 - x1) / len; + + vtx[0].x = x1 + tx; vtx[0].y = y1 + ty; + vtx[1].x = x1 - tx; vtx[1].y = y1 - ty; + vtx[2].x = x2 - tx; vtx[2].y = y2 - ty; + vtx[3].x = x2 + tx; vtx[3].y = y2 + ty; + + for (ii = 0; ii < 4; ii++) { + vtx[ii].color = color; + vtx[ii].z = 0; + } + + al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); + + } else { + ALLEGRO_VERTEX vtx[2]; + + vtx[0].x = x1; vtx[0].y = y1; + vtx[1].x = x2; vtx[1].y = y2; + + vtx[0].color = color; + vtx[1].color = color; + vtx[0].z = 0; + vtx[1].z = 0; + + al_draw_prim(vtx, 0, 0, 0, 2, ALLEGRO_PRIM_LINE_LIST); + } +} + +/* Function: al_draw_triangle + */ +void al_draw_triangle(float x1, float y1, float x2, float y2, + float x3, float y3, ALLEGRO_COLOR color, float thickness) +{ + if (thickness > 0) { + int ii = 0; + float side1, side2, side3; + float perimeter, semi_perimeter; + float outer_frac, inner_frac; + float incenter_x, incenter_y; + float incircle_rad; + int idx = 0; + ALLEGRO_VERTEX vtx[5]; + float x[3] = {x1, x2, x3}; + float y[3] = {y1, y2, y3}; + ALLEGRO_VERTEX first_inner_vtx; + ALLEGRO_VERTEX first_outer_vtx; + ALLEGRO_VERTEX ini_vtx; + float cross = (x[1] - x[0]) * (y[2] - y[0]) - (x[2] - x[0]) * (y[1] - y[0]); + + ini_vtx.x = ini_vtx.y = ini_vtx.z = ini_vtx.u = ini_vtx.v = 0; + ini_vtx.color = color; + first_inner_vtx = ini_vtx; + first_outer_vtx = ini_vtx; + + /* + * If the triangle is very flat, draw it as a line + */ + if(fabsf(cross) < 0.0001f) { + float tx, ty, lx, ly; + float len; + /* + * Find the obtuse vertex via two dot products + */ + float dot = (x[1] - x[0]) * (x[2] - x[0]) + (y[1] - y[0]) * (y[2] - y[0]); + if(dot < 0) { + x1 = x[1]; y1 = y[1]; + x2 = x[2]; y2 = y[2]; + } else { + dot = (x[0] - x[1]) * (x[2] - x[1]) + (y[0] - y[1]) * (y[2] - y[1]); + if(dot < 0) { + x1 = x[0]; y1 = y[0]; + x2 = x[2]; y2 = y[2]; + } else { + x1 = x[0]; y1 = y[0]; + x2 = x[1]; y2 = y[1]; + } + } + len = hypotf(x2 - x1, y2 - y1); + + if (len == 0) + return; + + tx = 0.5f * thickness * (y2 - y1) / len; + ty = 0.5f * thickness * -(x2 - x1) / len; + lx = 0.5f * thickness * (x2 - x1) / len; + ly = 0.5f * thickness * (y2 - y1) / len; + + vtx[0].x = x1 + tx - lx; vtx[0].y = y1 + ty - ly; + vtx[1].x = x1 - tx - lx; vtx[1].y = y1 - ty - ly; + vtx[2].x = x2 - tx + lx; vtx[2].y = y2 - ty + ly; + vtx[3].x = x2 + tx + lx; vtx[3].y = y2 + ty + ly; + + for (ii = 0; ii < 4; ii++) { + vtx[ii].color = color; + vtx[ii].z = 0; + } + + al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); + return; + } + else if(cross > 0) { + /* + * Points need to be wound correctly for the algorithm to work + */ + float t; + t = x[1]; + x[1] = x[2]; + x[2] = t; + + t = y[1]; + y[1] = y[2]; + y[2] = t; + } + + side1 = hypotf(x[1] - x[0], y[1] - y[0]); + side2 = hypotf(x[2] - x[0], y[2] - y[0]); + side3 = hypotf(x[2] - x[1], y[2] - y[1]); + + perimeter = side1 + side2 + side3; + semi_perimeter = perimeter / 2.0f; + if (semi_perimeter < 0.00001f) + return; + + incircle_rad = sqrtf((semi_perimeter - side1) * (semi_perimeter - side2) * (semi_perimeter - side3) / semi_perimeter); + + if (incircle_rad < 0.00001f) + return; + + outer_frac = (incircle_rad + thickness / 2) / incircle_rad; + inner_frac = (incircle_rad - thickness / 2) / incircle_rad; + + if(inner_frac < 0) + inner_frac = 0; + + incenter_x = (side1 * x[2] + side2 * x[1] + side3 * x[0]) / perimeter; + incenter_y = (side1 * y[2] + side2 * y[1] + side3 * y[0]) / perimeter; + + #define DRAW \ + if(ii != 0) { \ + vtx[idx++] = outer_vtx; \ + vtx[idx++] = inner_vtx; \ + \ + al_draw_prim(vtx, 0, 0, 0, idx, ALLEGRO_PRIM_TRIANGLE_FAN); \ + \ + idx = 0; \ + } + + /* + * Iterate across the vertices, and draw each side of the triangle separately + */ + for(ii = 0; ii < 3; ii++) + { + float vert_x = x[ii] - incenter_x; + float vert_y = y[ii] - incenter_y; + + float o_dx = vert_x * outer_frac; + float o_dy = vert_y * outer_frac; + + float i_dx = vert_x * inner_frac; + float i_dy = vert_y * inner_frac; + + float tdx = o_dx - i_dx; + float tdy = o_dy - i_dy; + + ALLEGRO_VERTEX inner_vtx = ini_vtx; + ALLEGRO_VERTEX outer_vtx = ini_vtx; + + if(tdx * tdx + tdy * tdy > 16 * thickness * thickness) { + float x_pos = x[(ii + 1) % 3]; + float y_pos = y[(ii + 1) % 3]; + + float x_neg = x[(ii + 2) % 3]; + float y_neg = y[(ii + 2) % 3]; + + float x1_x2 = x[ii] - x_pos; + float y1_y2 = y[ii] - y_pos; + + float x1_x3 = x[ii] - x_neg; + float y1_y3 = y[ii] - y_neg; + + float mag_1_2 = hypotf(x1_x2, y1_y2); + float mag_1_3 = hypotf(x1_x3, y1_y3); + + ALLEGRO_VERTEX next_vtx = ini_vtx; + + x1_x2 *= thickness / 2 / mag_1_2; + y1_y2 *= thickness / 2 / mag_1_2; + + x1_x3 *= thickness / 2 / mag_1_3; + y1_y3 *= thickness / 2 / mag_1_3; + + outer_vtx.x = x[ii] + x1_x3 - y1_y3; outer_vtx.y = y[ii] + y1_y3 + x1_x3; + inner_vtx.x = incenter_x + i_dx; inner_vtx.y = incenter_y + i_dy; + next_vtx.x = x[ii] + x1_x2 + y1_y2; next_vtx.y = y[ii] + y1_y2 - x1_x2; + + DRAW + + vtx[idx++] = inner_vtx; + vtx[idx++] = outer_vtx; + vtx[idx++] = next_vtx; + } else { + inner_vtx.x = incenter_x + i_dx; inner_vtx.y = incenter_y + i_dy; + outer_vtx.x = incenter_x + o_dx; outer_vtx.y = incenter_y + o_dy; + + DRAW + + vtx[idx++] = inner_vtx; + vtx[idx++] = outer_vtx; + } + + if(ii == 0) { + first_inner_vtx = inner_vtx; + first_outer_vtx = outer_vtx; + } + } + + vtx[idx++] = first_outer_vtx; + vtx[idx++] = first_inner_vtx; + + al_draw_prim(vtx, 0, 0, 0, idx, ALLEGRO_PRIM_TRIANGLE_FAN); + + #undef DRAW + } else { + ALLEGRO_VERTEX vtx[3]; + + vtx[0].x = x1; vtx[0].y = y1; + vtx[1].x = x2; vtx[1].y = y2; + vtx[2].x = x3; vtx[2].y = y3; + + vtx[0].color = color; + vtx[1].color = color; + vtx[2].color = color; + + vtx[0].z = 0; + vtx[1].z = 0; + vtx[2].z = 0; + + al_draw_prim(vtx, 0, 0, 0, 3, ALLEGRO_PRIM_LINE_LOOP); + } +} + +/* Function: al_draw_filled_triangle + */ +void al_draw_filled_triangle(float x1, float y1, float x2, float y2, + float x3, float y3, ALLEGRO_COLOR color) +{ + ALLEGRO_VERTEX vtx[3]; + + vtx[0].x = x1; vtx[0].y = y1; + vtx[1].x = x2; vtx[1].y = y2; + vtx[2].x = x3; vtx[2].y = y3; + + vtx[0].color = color; + vtx[1].color = color; + vtx[2].color = color; + + vtx[0].z = 0; + vtx[1].z = 0; + vtx[2].z = 0; + + al_draw_prim(vtx, 0, 0, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST); +} + +/* Function: al_draw_rectangle + */ +void al_draw_rectangle(float x1, float y1, float x2, float y2, + ALLEGRO_COLOR color, float thickness) +{ + int ii; + + if (thickness > 0) { + float t = thickness / 2; + ALLEGRO_VERTEX vtx[10]; + + vtx[0].x = x1 - t; vtx[0].y = y1 - t; + vtx[1].x = x1 + t; vtx[1].y = y1 + t; + vtx[2].x = x2 + t; vtx[2].y = y1 - t; + vtx[3].x = x2 - t; vtx[3].y = y1 + t; + vtx[4].x = x2 + t; vtx[4].y = y2 + t; + vtx[5].x = x2 - t; vtx[5].y = y2 - t; + vtx[6].x = x1 - t; vtx[6].y = y2 + t; + vtx[7].x = x1 + t; vtx[7].y = y2 - t; + vtx[8].x = x1 - t; vtx[8].y = y1 - t; + vtx[9].x = x1 + t; vtx[9].y = y1 + t; + + for (ii = 0; ii < 10; ii++) { + vtx[ii].color = color; + vtx[ii].z = 0; + } + + al_draw_prim(vtx, 0, 0, 0, 10, ALLEGRO_PRIM_TRIANGLE_STRIP); + } else { + ALLEGRO_VERTEX vtx[4]; + + vtx[0].x = x1; vtx[0].y = y1; + vtx[1].x = x2; vtx[1].y = y1; + vtx[2].x = x2; vtx[2].y = y2; + vtx[3].x = x1; vtx[3].y = y2; + + for (ii = 0; ii < 4; ii++) { + vtx[ii].color = color; + vtx[ii].z = 0; + } + + al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_LINE_LOOP); + } +} + +/* Function: al_draw_filled_rectangle + */ +void al_draw_filled_rectangle(float x1, float y1, float x2, float y2, + ALLEGRO_COLOR color) +{ + ALLEGRO_VERTEX vtx[4]; + int ii; + + vtx[0].x = x1; vtx[0].y = y1; + vtx[1].x = x1; vtx[1].y = y2; + vtx[2].x = x2; vtx[2].y = y2; + vtx[3].x = x2; vtx[3].y = y1; + + for (ii = 0; ii < 4; ii++) { + vtx[ii].color = color; + vtx[ii].z = 0; + } + + al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); +} + +/* Function: al_calculate_arc + */ +void al_calculate_arc(float* dest, int stride, float cx, float cy, + float rx, float ry, float start_theta, float delta_theta, float thickness, + int num_points) +{ + float theta; + float c; + float s; + float x, y, t; + int ii; + + ASSERT(dest); + ASSERT(num_points > 1); + ASSERT(rx >= 0); + ASSERT(ry >= 0); + + if (thickness > 0.0f) { + theta = delta_theta / ((float)(num_points) - 1); + c = cosf(theta); + s = sinf(theta); + x = cosf(start_theta); + y = sinf(start_theta); + + if (rx == ry) { + /* + The circle case is particularly simple + */ + float r1 = rx - thickness / 2.0f; + float r2 = rx + thickness / 2.0f; + for (ii = 0; ii < num_points; ii ++) { + *dest = r2 * x + cx; + *(dest + 1) = r2 * y + cy; + dest = (float*)(((char*)dest) + stride); + *dest = r1 * x + cx; + *(dest + 1) = r1 * y + cy; + dest = (float*)(((char*)dest) + stride); + + t = x; + x = c * x - s * y; + y = s * t + c * y; + } + } else { + if (rx != 0 && ry != 0) { + for (ii = 0; ii < num_points; ii++) { + float denom = hypotf(ry * x, rx * y); + float nx = thickness / 2 * ry * x / denom; + float ny = thickness / 2 * rx * y / denom; + + *dest = rx * x + cx + nx; + *(dest + 1) = ry * y + cy + ny; + dest = (float*)(((char*)dest) + stride); + *dest = rx * x + cx - nx; + *(dest + 1) = ry * y + cy - ny; + dest = (float*)(((char*)dest) + stride); + + t = x; + x = c * x - s * y; + y = s * t + c * y; + } + } + } + } else { + theta = delta_theta / ((float)num_points - 1); + c = cosf(theta); + s = sinf(theta); + x = cosf(start_theta); + y = sinf(start_theta); + + for (ii = 0; ii < num_points; ii++) { + *dest = rx * x + cx; + *(dest + 1) = ry * y + cy; + dest = (float*)(((char*)dest) + stride); + + t = x; + x = c * x - s * y; + y = s * t + c * y; + } + } +} + +/* Function: al_draw_pieslice + */ +void al_draw_pieslice(float cx, float cy, float r, float start_theta, + float delta_theta, ALLEGRO_COLOR color, float thickness) +{ + LOCAL_VERTEX_CACHE; + float scale = get_scale(); + int num_segments, ii; + + ASSERT(r >= 0); + + /* Just makes things a bit easier */ + if(delta_theta < 0) { + delta_theta = -delta_theta; + start_theta -= delta_theta; + } + + if (thickness <= 0) { + num_segments = fabs(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(scale * r)); + + if (num_segments < 2) + num_segments = 2; + + if (num_segments + 1 >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - 1; + } + + al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r, r, start_theta, delta_theta, 0, num_segments); + vertex_cache[0].x = cx; vertex_cache[0].y = cy; + + for (ii = 0; ii < num_segments + 1; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments + 1, ALLEGRO_PRIM_LINE_LOOP); + } else { + float ht = thickness / 2; + float inner_side_angle = asinf(ht / (r - ht)); + float outer_side_angle = asinf(ht / (r + ht)); + float central_angle = delta_theta - 2 * inner_side_angle; + bool inverted_winding = ((int)(delta_theta / ALLEGRO_PI)) % 2 == 1; + float midangle = start_theta + (fmodf(delta_theta + ALLEGRO_PI, 2 * ALLEGRO_PI) - ALLEGRO_PI) / 2; + float midpoint_dir_x = cosf(midangle); + float midpoint_dir_y = sinf(midangle); + float side_dir_x = cosf(start_theta); + float side_dir_y = sinf(start_theta); + float sine_half_delta = fabsf(side_dir_x * midpoint_dir_y - side_dir_y * midpoint_dir_x); /* Cross product */ + float connect_len = ht / sine_half_delta; + bool blunt_tip = connect_len > 2 * thickness; + + /* The angle is big enough for there to be a hole in the middle */ + if (central_angle > 0) { + float central_start_angle = start_theta + inner_side_angle; + size_t vtx_id; + int vtx_delta; + /* Two inner hole vertices and the apex (2 vertices if the apex is blunt) */ + int extra_vtx = blunt_tip ? 4 : 3; + + al_draw_arc(cx, cy, r, central_start_angle, central_angle, color, thickness); + + vertex_cache[0].x = cx + (r - thickness / 2) * cosf(central_start_angle); + vertex_cache[0].y = cy + (r - thickness / 2) * sinf(central_start_angle); + + num_segments = (inner_side_angle + outer_side_angle) / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(scale * (r + ht)); + + if (num_segments < 2) + num_segments = 2; + + if (num_segments + extra_vtx >= ALLEGRO_VERTEX_CACHE_SIZE) + num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - extra_vtx; + + al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r + ht, r + ht, central_start_angle, -(outer_side_angle + inner_side_angle), 0, num_segments); + + /* Do the tip */ + vtx_id = num_segments + 1 + (inverted_winding ? (1 + (blunt_tip ? 1 : 0)) : 0); + vtx_delta = inverted_winding ? -1 : 1; + if (blunt_tip) { + float vx = ht * (side_dir_y * (inverted_winding ? -1 : 1) - side_dir_x); + float vy = ht * (-side_dir_x * (inverted_winding ? -1 : 1) - side_dir_y); + float dot = vx * midpoint_dir_x + vy * midpoint_dir_y; + + vertex_cache[vtx_id].x = cx + vx; + vertex_cache[vtx_id].y = cy + vy; + vtx_id += vtx_delta; + + vertex_cache[vtx_id].x = cx + dot * midpoint_dir_x; + vertex_cache[vtx_id].y = cy + dot * midpoint_dir_y; + } else { + vertex_cache[vtx_id].x = cx - connect_len * midpoint_dir_x; + vertex_cache[vtx_id].y = cy - connect_len * midpoint_dir_y; + } + vtx_id += vtx_delta; + + if(connect_len > r - ht) + connect_len = r - ht; + vertex_cache[vtx_id].x = cx + connect_len * midpoint_dir_x; + vertex_cache[vtx_id].y = cy + connect_len * midpoint_dir_y; + + for (ii = 0; ii < num_segments + extra_vtx; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments + extra_vtx, ALLEGRO_PRIM_TRIANGLE_FAN); + + /* Mirror the vertices and draw them again */ + for (ii = 0; ii < num_segments + extra_vtx; ii++) { + float dot = (vertex_cache[ii].x - cx) * midpoint_dir_x + (vertex_cache[ii].y - cy) * midpoint_dir_y; + vertex_cache[ii].x = 2 * cx + 2 * dot * midpoint_dir_x - vertex_cache[ii].x; + vertex_cache[ii].y = 2 * cy + 2 * dot * midpoint_dir_y - vertex_cache[ii].y; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments + extra_vtx, ALLEGRO_PRIM_TRIANGLE_FAN); + } else { + /* Apex: 2 vertices if the apex is blunt) */ + int extra_vtx = blunt_tip ? 2 : 1; + + num_segments = (2 * outer_side_angle) / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(scale * (r + ht)); + + if (num_segments < 2) + num_segments = 2; + + if (num_segments + extra_vtx >= ALLEGRO_VERTEX_CACHE_SIZE) + num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - extra_vtx; + + al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r + ht, r + ht, start_theta - outer_side_angle, 2 * outer_side_angle + delta_theta, 0, num_segments); + + if (blunt_tip) { + float vx = ht * (side_dir_y - side_dir_x); + float vy = ht * (-side_dir_x - side_dir_y); + float dot = vx * midpoint_dir_x + vy * midpoint_dir_y; + + vertex_cache[0].x = cx + vx; + vertex_cache[0].y = cy + vy; + + vx = 2 * dot * midpoint_dir_x - vx; + vy = 2 * dot * midpoint_dir_y - vy; + + vertex_cache[num_segments + 1].x = cx + vx; + vertex_cache[num_segments + 1].y = cy + vy; + } else { + vertex_cache[0].x = cx - connect_len * midpoint_dir_x; + vertex_cache[0].y = cy - connect_len * midpoint_dir_y; + } + + for (ii = 0; ii < num_segments + extra_vtx; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments + extra_vtx, ALLEGRO_PRIM_TRIANGLE_FAN); + } + } +} + +/* Function: al_draw_filled_pieslice + */ +void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta, + float delta_theta, ALLEGRO_COLOR color) +{ + LOCAL_VERTEX_CACHE; + float scale = get_scale(); + int num_segments, ii; + + ASSERT(r >= 0); + + num_segments = fabs(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(scale * r)); + + if (num_segments < 2) + num_segments = 2; + + if (num_segments + 1 >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - 1; + } + + al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r, r, start_theta, delta_theta, 0, num_segments); + vertex_cache[0].x = cx; vertex_cache[0].y = cy; + + for (ii = 0; ii < num_segments + 1; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments + 1, ALLEGRO_PRIM_TRIANGLE_FAN); +} + +/* Function: al_draw_ellipse + */ +void al_draw_ellipse(float cx, float cy, float rx, float ry, + ALLEGRO_COLOR color, float thickness) +{ + LOCAL_VERTEX_CACHE; + float scale = get_scale(); + + ASSERT(rx >= 0); + ASSERT(ry >= 0); + + if (thickness > 0) { + int num_segments = ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx + ry) / 2.0f); + int ii; + + /* In case rx and ry are both 0. */ + if (num_segments < 2) + return; + + if (2 * num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 2; + } + + al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, 0, ALLEGRO_PI * 2, thickness, num_segments); + for (ii = 0; ii < 2 * num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, 2 * num_segments, ALLEGRO_PRIM_TRIANGLE_STRIP); + } else { + int num_segments = ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx + ry) / 2.0f); + int ii; + + /* In case rx and ry are both 0. */ + if (num_segments < 2) + return; + + if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; + } + + al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, 0, ALLEGRO_PI * 2, 0, num_segments); + for (ii = 0; ii < num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments - 1, ALLEGRO_PRIM_LINE_LOOP); + } +} + +/* Function: al_draw_filled_ellipse + */ +void al_draw_filled_ellipse(float cx, float cy, float rx, float ry, + ALLEGRO_COLOR color) +{ + LOCAL_VERTEX_CACHE; + int num_segments, ii; + float scale = get_scale(); + + ASSERT(rx >= 0); + ASSERT(ry >= 0); + + num_segments = ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx + ry) / 2.0f); + + /* In case rx and ry are both close to 0. If al_calculate_arc is passed + * 0 or 1 it will assert. + */ + if (num_segments < 2) + return; + + if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; + } + + al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, 0, ALLEGRO_PI * 2, 0, num_segments); + vertex_cache[0].x = cx; vertex_cache[0].y = cy; + + for (ii = 0; ii < num_segments + 1; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments + 1, ALLEGRO_PRIM_TRIANGLE_FAN); +} + +/* Function: al_draw_circle + */ +void al_draw_circle(float cx, float cy, float r, ALLEGRO_COLOR color, + float thickness) +{ + al_draw_ellipse(cx, cy, r, r, color, thickness); +} + +/* Function: al_draw_filled_circle + */ +void al_draw_filled_circle(float cx, float cy, float r, ALLEGRO_COLOR color) +{ + al_draw_filled_ellipse(cx, cy, r, r, color); +} + +/* Function: al_draw_elliptical_arc + */ +void al_draw_elliptical_arc(float cx, float cy, float rx, float ry, float start_theta, + float delta_theta, ALLEGRO_COLOR color, float thickness) +{ + LOCAL_VERTEX_CACHE; + float scale = get_scale(); + + ASSERT(rx >= 0 && ry >= 0); + if (thickness > 0) { + int num_segments = fabs(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx + ry) / 2.0f)); + int ii; + + if (num_segments < 2) + num_segments = 2; + + if (2 * num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 2; + } + + al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, start_theta, delta_theta, thickness, num_segments); + + for (ii = 0; ii < 2 * num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, 2 * num_segments, ALLEGRO_PRIM_TRIANGLE_STRIP); + } else { + int num_segments = fabs(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx + ry) / 2.0f)); + int ii; + + if (num_segments < 2) + num_segments = 2; + + if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; + } + + al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, start_theta, delta_theta, 0, num_segments); + + for (ii = 0; ii < num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments, ALLEGRO_PRIM_LINE_STRIP); + } +} + +/* Function: al_draw_arc + */ +void al_draw_arc(float cx, float cy, float r, float start_theta, + float delta_theta, ALLEGRO_COLOR color, float thickness) +{ + al_draw_elliptical_arc(cx, cy, r, r, start_theta, delta_theta, color, thickness); +} + +/* Function: al_draw_rounded_rectangle + */ +void al_draw_rounded_rectangle(float x1, float y1, float x2, float y2, + float rx, float ry, ALLEGRO_COLOR color, float thickness) +{ + LOCAL_VERTEX_CACHE; + float scale = get_scale(); + + ASSERT(rx >= 0); + ASSERT(ry >= 0); + + if (thickness > 0) { + int num_segments = ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx + ry) / 2.0f) / 4; + int ii; + + /* In case rx and ry are both 0. */ + if (num_segments < 2) { + al_draw_rectangle(x1, y1, x2, y2, color, thickness); + return; + } + + if (8 * num_segments + 2 >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 3) / 8; + } + + al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), 0, 0, rx, ry, 0, ALLEGRO_PI / 2, thickness, num_segments); + + for (ii = 0; ii < 2 * num_segments; ii += 2) { + vertex_cache[ii + 2 * num_segments + 1].x = x1 + rx - vertex_cache[2 * num_segments - 1 - ii].x; + vertex_cache[ii + 2 * num_segments + 1].y = y1 + ry - vertex_cache[2 * num_segments - 1 - ii].y; + vertex_cache[ii + 2 * num_segments].x = x1 + rx - vertex_cache[2 * num_segments - 1 - ii - 1].x; + vertex_cache[ii + 2 * num_segments].y = y1 + ry - vertex_cache[2 * num_segments - 1 - ii - 1].y; + + vertex_cache[ii + 4 * num_segments].x = x1 + rx - vertex_cache[ii].x; + vertex_cache[ii + 4 * num_segments].y = y2 - ry + vertex_cache[ii].y; + vertex_cache[ii + 4 * num_segments + 1].x = x1 + rx - vertex_cache[ii + 1].x; + vertex_cache[ii + 4 * num_segments + 1].y = y2 - ry + vertex_cache[ii + 1].y; + + vertex_cache[ii + 6 * num_segments + 1].x = x2 - rx + vertex_cache[2 * num_segments - 1 - ii].x; + vertex_cache[ii + 6 * num_segments + 1].y = y2 - ry + vertex_cache[2 * num_segments - 1 - ii].y; + vertex_cache[ii + 6 * num_segments].x = x2 - rx + vertex_cache[2 * num_segments - 1 - ii - 1].x; + vertex_cache[ii + 6 * num_segments].y = y2 - ry + vertex_cache[2 * num_segments - 1 - ii - 1].y; + } + for (ii = 0; ii < 2 * num_segments; ii += 2) { + vertex_cache[ii].x = x2 - rx + vertex_cache[ii].x; + vertex_cache[ii].y = y1 + ry - vertex_cache[ii].y; + vertex_cache[ii + 1].x = x2 - rx + vertex_cache[ii + 1].x; + vertex_cache[ii + 1].y = y1 + ry - vertex_cache[ii + 1].y; + } + vertex_cache[8 * num_segments] = vertex_cache[0]; + vertex_cache[8 * num_segments + 1] = vertex_cache[1]; + + for (ii = 0; ii < 8 * num_segments + 2; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, 8 * num_segments + 2, ALLEGRO_PRIM_TRIANGLE_STRIP); + } else { + int num_segments = ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx + ry) / 2.0f) / 4; + int ii; + + /* In case rx and ry are both 0. */ + if (num_segments < 2) { + al_draw_rectangle(x1, y1, x2, y2, color, thickness); + return; + } + + if (num_segments * 4 >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 4; + } + + al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), 0, 0, rx, ry, 0, ALLEGRO_PI / 2, 0, num_segments + 1); + + for (ii = 0; ii < num_segments; ii++) { + vertex_cache[ii + 1 * num_segments].x = x1 + rx - vertex_cache[num_segments - 1 - ii].x; + vertex_cache[ii + 1 * num_segments].y = y1 + ry - vertex_cache[num_segments - 1 - ii].y; + + vertex_cache[ii + 2 * num_segments].x = x1 + rx - vertex_cache[ii].x; + vertex_cache[ii + 2 * num_segments].y = y2 - ry + vertex_cache[ii].y; + + vertex_cache[ii + 3 * num_segments].x = x2 - rx + vertex_cache[num_segments - 1 - ii].x; + vertex_cache[ii + 3 * num_segments].y = y2 - ry + vertex_cache[num_segments - 1 - ii].y; + } + for (ii = 0; ii < num_segments; ii++) { + vertex_cache[ii].x = x2 - rx + vertex_cache[ii].x; + vertex_cache[ii].y = y1 + ry - vertex_cache[ii].y; + } + + for (ii = 0; ii < 4 * num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, 4 * num_segments, ALLEGRO_PRIM_LINE_LOOP); + } +} + +/* Function: al_draw_filled_rounded_rectangle + */ +void al_draw_filled_rounded_rectangle(float x1, float y1, float x2, float y2, + float rx, float ry, ALLEGRO_COLOR color) +{ + LOCAL_VERTEX_CACHE; + int ii; + float scale = get_scale(); + int num_segments = ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx + ry) / 2.0f) / 4; + + ASSERT(rx >= 0); + ASSERT(ry >= 0); + + /* In case rx and ry are both 0. */ + if (num_segments < 2) { + al_draw_filled_rectangle(x1, y1, x2, y2, color); + return; + } + + if (num_segments * 4 >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 4; + } + + al_calculate_arc(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), 0, 0, rx, ry, 0, ALLEGRO_PI / 2, 0, num_segments + 1); + + for (ii = 0; ii < num_segments; ii++) { + vertex_cache[ii + 1 * num_segments].x = x1 + rx - vertex_cache[num_segments - 1 - ii].x; + vertex_cache[ii + 1 * num_segments].y = y1 + ry - vertex_cache[num_segments - 1 - ii].y; + + vertex_cache[ii + 2 * num_segments].x = x1 + rx - vertex_cache[ii].x; + vertex_cache[ii + 2 * num_segments].y = y2 - ry + vertex_cache[ii].y; + + vertex_cache[ii + 3 * num_segments].x = x2 - rx + vertex_cache[num_segments - 1 - ii].x; + vertex_cache[ii + 3 * num_segments].y = y2 - ry + vertex_cache[num_segments - 1 - ii].y; + } + for (ii = 0; ii < num_segments; ii++) { + vertex_cache[ii].x = x2 - rx + vertex_cache[ii].x; + vertex_cache[ii].y = y1 + ry - vertex_cache[ii].y; + } + + for (ii = 0; ii < 4 * num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + /* + TODO: Doing this as a triangle fan just doesn't sound all that great, perhaps shuffle the vertices somehow to at least make it a strip + */ + al_draw_prim(vertex_cache, 0, 0, 0, 4 * num_segments, ALLEGRO_PRIM_TRIANGLE_FAN); +} + +/* Function: al_calculate_spline + */ +void al_calculate_spline(float* dest, int stride, float points[8], + float thickness, int num_segments) +{ + /* Derivatives of x(t) and y(t). */ + float x, dx, ddx, dddx; + float y, dy, ddy, dddy; + int ii = 0; + + /* Temp variables used in the setup. */ + float dt, dt2, dt3; + float xdt2_term, xdt3_term; + float ydt2_term, ydt3_term; + + /* This is enough to avoid malloc in ex_prim, which I take as a reasonable + * guess to what a common number of segments might be. To be honest, it + * probably makes no difference. + */ + float cache_point_buffer_storage[150]; + float* cache_point_buffer = cache_point_buffer_storage; + + ASSERT(num_segments > 1); + ASSERT(points); + + if (num_segments > (int)(sizeof(cache_point_buffer_storage) / sizeof(float) / 2)) { + cache_point_buffer = al_malloc(2 * sizeof(float) * num_segments); + } + + dt = 1.0 / (num_segments - 1); + dt2 = (dt * dt); + dt3 = (dt2 * dt); + + /* x coordinates. */ + xdt2_term = 3 * (points[4] - 2 * points[2] + points[0]); + xdt3_term = points[6] + 3 * (-points[4] + points[2]) - points[0]; + + xdt2_term = dt2 * xdt2_term; + xdt3_term = dt3 * xdt3_term; + + dddx = 6 * xdt3_term; + ddx = -6 * xdt3_term + 2 * xdt2_term; + dx = xdt3_term - xdt2_term + 3 * dt * (points[2] - points[0]); + x = points[0]; + + /* y coordinates. */ + ydt2_term = 3 * (points[5] - 2 * points[3] + points[1]); + ydt3_term = points[7] + 3 * (-points[5] + points[3]) - points[1]; + + ydt2_term = dt2 * ydt2_term; + ydt3_term = dt3 * ydt3_term; + + dddy = 6 * ydt3_term; + ddy = -6 * ydt3_term + 2 * ydt2_term; + dy = ydt3_term - ydt2_term + dt * 3 * (points[3] - points[1]); + y = points[1]; + + cache_point_buffer[2 * ii] = x; + cache_point_buffer[2 * ii + 1] = y; + + for (ii = 1; ii < num_segments; ii++) { + ddx += dddx; + dx += ddx; + x += dx; + + ddy += dddy; + dy += ddy; + y += dy; + + cache_point_buffer[2 * ii] = x; + cache_point_buffer[2 * ii + 1] = y; + } + al_calculate_ribbon(dest, stride, cache_point_buffer, 2 * sizeof(float), thickness, num_segments); + + if (cache_point_buffer != cache_point_buffer_storage) { + al_free(cache_point_buffer); + } +} + +/* Function: al_draw_spline + */ +void al_draw_spline(float points[8], ALLEGRO_COLOR color, float thickness) +{ + int ii; + float scale = get_scale(); + int num_segments = (int)(sqrtf(hypotf(points[2] - points[0], points[3] - points[1]) + + hypotf(points[4] - points[2], points[5] - points[3]) + + hypotf(points[6] - points[4], points[7] - points[5])) * + 1.2 * ALLEGRO_PRIM_QUALITY * scale / 10); + LOCAL_VERTEX_CACHE; + + if(num_segments < 2) + num_segments = 2; + + if (thickness > 0) { + if (2 * num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = (ALLEGRO_VERTEX_CACHE_SIZE - 1) / 2; + } + + al_calculate_spline(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), points, thickness, num_segments); + + for (ii = 0; ii < 2 * num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, 2 * num_segments, ALLEGRO_PRIM_TRIANGLE_STRIP); + } else { + if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) { + num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1; + } + + al_calculate_spline(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), points, thickness, num_segments); + + for (ii = 0; ii < num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments, ALLEGRO_PRIM_LINE_STRIP); + } +} + +/* Function: al_calculate_ribbon + */ +void al_calculate_ribbon(float* dest, int dest_stride, const float *points, + int points_stride, float thickness, int num_segments) +{ + ASSERT(points); + ASSERT(num_segments >= 2); + + if (thickness > 0) { + int ii = 0; + float x, y; + + float cur_dir_x; + float cur_dir_y; + float prev_dir_x = 0; + float prev_dir_y = 0; + float t = thickness / 2; + float tx, ty; + float nx, ny; + float sign = 1; + + for (ii = 0; ii < 2 * num_segments - 2; ii += 2) { + float dir_len; + x = *points; + y = *(points + 1); + + points = (float*)(((char*)points) + points_stride); + + cur_dir_x = *(points) - x; + cur_dir_y = *(points + 1) - y; + + dir_len = hypotf(cur_dir_x, cur_dir_y); + + if(dir_len > 0.000001f) { + cur_dir_x /= dir_len; + cur_dir_y /= dir_len; + } else if (ii == 0) { + cur_dir_x = 1; + cur_dir_y = 0; + } else { + cur_dir_x = prev_dir_x; + cur_dir_y = prev_dir_y; + } + + if (ii == 0) { + tx = -t * cur_dir_y; + ty = t * cur_dir_x; + nx = 0; + ny = 0; + } else { + float dot = cur_dir_x * prev_dir_x + cur_dir_y * prev_dir_y; + float norm_len, cosine; + if(dot < 0) { + /* + * This is by no means exact, but seems to produce acceptable results + */ + float tx_; + tx = cur_dir_x - prev_dir_x; + ty = cur_dir_y - prev_dir_y; + norm_len = hypotf(tx, ty); + + tx /= norm_len; + ty /= norm_len; + + cosine = tx * cur_dir_x + ty * cur_dir_y; + + nx = -t * tx / cosine; + ny = -t * ty / cosine; + tx_ = tx; + tx = -t * ty * cosine; + ty = t * tx_ * cosine; + sign = -sign; + } else { + float new_norm_len; + tx = cur_dir_y + prev_dir_y; + ty = -(cur_dir_x + prev_dir_x); + norm_len = hypotf(tx, ty); + + tx /= norm_len; + ty /= norm_len; + cosine = tx * (-cur_dir_y) + ty * (cur_dir_x); + new_norm_len = t / cosine; + + tx *= new_norm_len; + ty *= new_norm_len; + nx = 0; + ny = 0; + } + } + + *dest = x - sign * tx + nx; + *(dest + 1) = y - sign * ty + ny; + dest = (float*)(((char*)dest) + dest_stride); + *dest = x + sign * tx + nx; + *(dest + 1) = y + sign * ty + ny; + dest = (float*)(((char*)dest) + dest_stride); + + prev_dir_x = cur_dir_x; + prev_dir_y = cur_dir_y; + } + tx = -t * prev_dir_y; + ty = t * prev_dir_x; + + x = *points; + y = *(points + 1); + + *dest = x - sign * tx; + *(dest + 1) = y - sign * ty; + dest = (float*)(((char*)dest) + dest_stride); + *dest = x + sign * tx; + *(dest + 1) = y + sign * ty; + } else { + int ii; + for (ii = 0; ii < num_segments; ii++) { + *dest = *points; + *(dest + 1) = *(points + 1); + dest = (float*)(((char*)dest) + dest_stride); + points = (float*)(((char*)points) + points_stride); + } + } +} + +/* Function: al_draw_ribbon + */ +void al_draw_ribbon(const float *points, int points_stride, ALLEGRO_COLOR color, + float thickness, int num_segments) +{ + LOCAL_VERTEX_CACHE; + int ii; + + if (num_segments * (thickness > 0 ? 2 : 1) > ALLEGRO_VERTEX_CACHE_SIZE) { + ALLEGRO_ERROR("Ribbon has too many segments.\n"); + return; + } + + al_calculate_ribbon(&(vertex_cache[0].x), sizeof(ALLEGRO_VERTEX), points, points_stride, thickness, num_segments); + + if (thickness > 0) { + for (ii = 0; ii < 2 * num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, 2 * num_segments, ALLEGRO_PRIM_TRIANGLE_STRIP); + } else { + for (ii = 0; ii < num_segments; ii++) { + vertex_cache[ii].color = color; + vertex_cache[ii].z = 0; + } + + al_draw_prim(vertex_cache, 0, 0, 0, num_segments, ALLEGRO_PRIM_LINE_STRIP); + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/primitives/line_soft.c b/allegro/addons/primitives/line_soft.c new file mode 100644 index 00000000..801fcdde --- /dev/null +++ b/allegro/addons/primitives/line_soft.c @@ -0,0 +1,648 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Software line implementation functions. + * + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + + +#define _AL_NO_BLEND_INLINE_FUNC + +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/internal/aintern_blend.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_prim.h" +#include "allegro5/internal/aintern_prim_soft.h" +#include <math.h> + +/* +Nomenclature +shader_{texture}_{grad,solid}_{any,rgb888,rgba8888,etc}_{draw_{shade,opaque},step,first} +*/ + +typedef void (*shader_draw)(uintptr_t, int, int); +typedef void (*shader_first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*); +typedef void (*shader_step)(uintptr_t, int); + +typedef struct { + ALLEGRO_COLOR color; +} state_solid_any_2d; + +static void shader_solid_any_draw_shade(uintptr_t state, int x, int y) +{ + state_solid_any_2d* s = (state_solid_any_2d*)state; + al_put_blended_pixel(x, y, s->color); +} + +static void shader_solid_any_draw_opaque(uintptr_t state, int x, int y) +{ + state_solid_any_2d* s = (state_solid_any_2d*)state; + al_put_pixel(x, y, s->color); +} + +static void shader_solid_any_first(uintptr_t state, int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) +{ + state_solid_any_2d* s = (state_solid_any_2d*)state; + s->color = v1->color; + + (void)start_x; + (void)start_y; + (void)v2; +} + +static void shader_solid_any_step(uintptr_t state, int minor_step) +{ + (void)state; + (void)minor_step; +} + +/*----------------------------------------------------*/ + +typedef struct { + state_solid_any_2d solid; + ALLEGRO_COLOR minor_color; + ALLEGRO_COLOR major_color; +} state_grad_any_2d; + +static void get_interpolation_parameters(int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, float* param, float* minor_delta_param, float* major_delta_param) +{ + float dx = v2->x - v1->x; + float dy = v2->y - v1->y; + float lensq = dx * dx + dy * dy; + + if (lensq == 0) { + lensq = 0.0001f; + *param = 0; + } else { + *param = ((float)start_x - v1->x) * dx + ((float)start_y - v1->y) * dy; + *param /= lensq; + } + + dx = fabsf(dx); + dy = fabsf(dy); + if (dx > dy) + *minor_delta_param = dx / lensq; + else + *minor_delta_param = dy / lensq; + *major_delta_param = (dx + dy) / lensq; +} + +static void shader_grad_any_first(uintptr_t state, int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) +{ + float param; + float minor_delta_param; + float major_delta_param; + state_grad_any_2d* st = (state_grad_any_2d*)state; + ALLEGRO_COLOR diff, v1c, v2c; + + v1c = v1->color; + v2c = v2->color; + + get_interpolation_parameters(start_x, start_y, v1, v2, ¶m, &minor_delta_param, &major_delta_param); + + diff.a = v2c.a - v1c.a; + diff.r = v2c.r - v1c.r; + diff.g = v2c.g - v1c.g; + diff.b = v2c.b - v1c.b; + + st->solid.color.a = v1c.a + diff.a * param; + st->solid.color.r = v1c.r + diff.r * param; + st->solid.color.g = v1c.g + diff.g * param; + st->solid.color.b = v1c.b + diff.b * param; + + st->minor_color.a = diff.a * minor_delta_param; + st->minor_color.r = diff.r * minor_delta_param; + st->minor_color.g = diff.g * minor_delta_param; + st->minor_color.b = diff.b * minor_delta_param; + + st->major_color.a = diff.a * major_delta_param; + st->major_color.r = diff.r * major_delta_param; + st->major_color.g = diff.g * major_delta_param; + st->major_color.b = diff.b * major_delta_param; +} + +static void shader_grad_any_step(uintptr_t state, int minor_step) +{ + state_grad_any_2d* s = (state_grad_any_2d*)state; + if (minor_step) { + s->solid.color.a += s->minor_color.a; + s->solid.color.r += s->minor_color.r; + s->solid.color.g += s->minor_color.g; + s->solid.color.b += s->minor_color.b; + } else { + s->solid.color.a += s->major_color.a; + s->solid.color.r += s->major_color.r; + s->solid.color.g += s->major_color.g; + s->solid.color.b += s->major_color.b; + } +} + +/*===================== Texture Shaders =======================*/ + +static int fix_var(float var, int max_var) +{ + const int ivar = (int)floorf(var); + const int ret = ivar % max_var; + if(ret >= 0) + return ret; + else + return ret + max_var; +} + +#define SHADE_COLORS(A, B) \ + A.r = B.r * A.r; \ + A.g = B.g * A.g; \ + A.b = B.b * A.b; \ + A.a = B.a * A.a; + +#define FIX_UV const int u = fix_var(s->u, s->w); const int v = fix_var(s->v, s->h); + +typedef struct { + ALLEGRO_COLOR color; + ALLEGRO_BITMAP* texture; + int w, h; + float u, v; + float minor_du; + float minor_dv; + float major_du; + float major_dv; +} state_texture_solid_any_2d; + +static void shader_texture_solid_any_draw_shade(uintptr_t state, int x, int y) +{ + state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; + FIX_UV + + ALLEGRO_COLOR color = al_get_pixel(s->texture, u, v); + SHADE_COLORS(color, s->color) + al_put_blended_pixel(x, y, color); +} + +static void shader_texture_solid_any_draw_shade_white(uintptr_t state, int x, int y) +{ + state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; + FIX_UV + + al_put_blended_pixel(x, y, al_get_pixel(s->texture, u, v)); +} + +static void shader_texture_solid_any_draw_opaque(uintptr_t state, int x, int y) +{ + state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; + FIX_UV + + ALLEGRO_COLOR color = al_get_pixel(s->texture, u, v); + SHADE_COLORS(color, s->color) + al_put_pixel(x, y, color); +} + +static void shader_texture_solid_any_draw_opaque_white(uintptr_t state, int x, int y) +{ + state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; + FIX_UV + + al_put_pixel(x, y, al_get_pixel(s->texture, u, v)); +} + +static void shader_texture_solid_any_first(uintptr_t state, int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) +{ + float param; + float minor_delta_param; + float major_delta_param; + state_texture_solid_any_2d* st = (state_texture_solid_any_2d*)state; + float du, dv; + ALLEGRO_COLOR v1c; + + v1c = v1->color; + + get_interpolation_parameters(start_x, start_y, v1, v2, ¶m, &minor_delta_param, &major_delta_param); + + st->w = al_get_bitmap_width(st->texture); + st->h = al_get_bitmap_height(st->texture); + + du = v2->u - v1->u; + dv = v2->v - v1->v; + + st->color.r = v1c.r; + st->color.g = v1c.g; + st->color.b = v1c.b; + st->color.a = v1c.a; + + st->u = v1->u + du * param; + st->v = v1->v + dv * param; + + st->minor_du = du * minor_delta_param; + st->minor_dv = dv * minor_delta_param; + + st->major_du = du * major_delta_param; + st->major_dv = dv * major_delta_param; +} + +static void shader_texture_solid_any_step(uintptr_t state, int minor_step) +{ + state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; + if (minor_step) { + s->u += s->minor_du; + s->v += s->minor_dv; + } else { + s->u += s->major_du; + s->v += s->major_dv; + } +} + +/*----------------------------------------------------*/ + +typedef struct { + state_texture_solid_any_2d solid; + ALLEGRO_COLOR minor_color; + ALLEGRO_COLOR major_color; +} state_texture_grad_any_2d; + +static void shader_texture_grad_any_first(uintptr_t state, int start_x, int start_y, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) +{ + float param; + float minor_delta_param; + float major_delta_param; + state_texture_grad_any_2d* st = (state_texture_grad_any_2d*)state; + float du, dv; + ALLEGRO_COLOR diff, v1c, v2c; + + v1c = v1->color; + v2c = v2->color; + + get_interpolation_parameters(start_x, start_y, v1, v2, ¶m, &minor_delta_param, &major_delta_param); + + st->solid.w = al_get_bitmap_width(st->solid.texture); + st->solid.h = al_get_bitmap_height(st->solid.texture); + + du = v2->u - v1->u; + dv = v2->v - v1->v; + + st->solid.color.r = v1c.r; + st->solid.color.g = v1c.g; + st->solid.color.b = v1c.b; + st->solid.color.a = v1c.a; + + st->solid.u = v1->u + du * param; + st->solid.v = v1->v + dv * param; + + st->solid.minor_du = du * minor_delta_param; + st->solid.minor_dv = dv * minor_delta_param; + + st->solid.major_du = du * major_delta_param; + st->solid.major_dv = dv * major_delta_param; + + diff.a = v2c.a - v1c.a; + diff.r = v2c.r - v1c.r; + diff.g = v2c.g - v1c.g; + diff.b = v2c.b - v1c.b; + + st->solid.color.a = v1c.a + diff.a * param; + st->solid.color.r = v1c.r + diff.r * param; + st->solid.color.g = v1c.g + diff.g * param; + st->solid.color.b = v1c.b + diff.b * param; + + st->minor_color.a = diff.a * minor_delta_param; + st->minor_color.r = diff.r * minor_delta_param; + st->minor_color.g = diff.g * minor_delta_param; + st->minor_color.b = diff.b * minor_delta_param; + + st->major_color.a = diff.a * major_delta_param; + st->major_color.r = diff.r * major_delta_param; + st->major_color.g = diff.g * major_delta_param; + st->major_color.b = diff.b * major_delta_param; +} + +static void shader_texture_grad_any_step(uintptr_t state, int minor_step) +{ + state_texture_grad_any_2d* s = (state_texture_grad_any_2d*)state; + shader_texture_solid_any_step(state, minor_step); + if (minor_step) { + s->solid.color.a += s->minor_color.a; + s->solid.color.r += s->minor_color.r; + s->solid.color.g += s->minor_color.g; + s->solid.color.b += s->minor_color.b; + } else { + s->solid.color.a += s->major_color.a; + s->solid.color.r += s->major_color.r; + s->solid.color.g += s->major_color.g; + s->solid.color.b += s->major_color.b; + } +} + +static void line_stepper(uintptr_t state, shader_first first, shader_step step, shader_draw draw, ALLEGRO_VERTEX* vtx1, ALLEGRO_VERTEX* vtx2) +{ + float x1, y1, x2, y2; + float dx, dy; + int end_x, end_y; + + if (vtx2->y < vtx1->y) { + ALLEGRO_VERTEX* t; + t = vtx1; + vtx1 = vtx2; + vtx2 = t; + } + + vtx1->x -= 0.5001f; + vtx1->y -= 0.5001f; + vtx2->x -= 0.5001f; + vtx2->y -= 0.5001f; + + x1 = vtx1->x; + y1 = vtx1->y; + x2 = vtx2->x; + y2 = vtx2->y; + + dx = x2 - x1; + dy = y2 - y1; + + end_x = floorf(x2 + 0.5f); + end_y = floorf(y2 + 0.5f); + +#define FIRST \ + first(state, x, y, vtx1, vtx2); \ + if((x2 - x1) * ((float)x - x1) + (y2 - y1) * ((float)y - y1) >= 0) \ + draw(state, x, y); \ + (void)minor; + +#define STEP \ + step(state, minor); \ + draw(state, x, y); + +#define LAST \ + step(state, minor); \ + if((x1 - x2) * ((float)x - x2) + (y1 - y2) * ((float)y - y2) > 0) \ + draw(state, x, y); + + +#define WORKER(var1, var2, comp, dvar1, dvar2, derr1, derr2, func) \ + { \ + int minor = 1; \ + if(err comp) \ + { \ + var1 += dvar1; \ + err += derr1; \ + minor = 0; \ + } \ + \ + func \ + \ + var2 += dvar2; \ + err += derr2; \ + } + + if (dx > 0) { + if (dx > dy) { + int x = floorf(x1 + 0.5f); + int y = floorf(y1); + + float err = (y1 - (float)y) * dx - (x1 - (float)x) * dy; + + if (x < end_x) { + WORKER(y, x, > 0.5f * dx, 1, 1, -dx, dy, FIRST) + } + + while (x < end_x) { + WORKER(y, x, > 0.5f * dx, 1, 1, -dx, dy, STEP) + } + + if (x <= end_x) { + WORKER(y, x, > 0.5f * dx, 1, 1, -dx, dy, LAST) + + } + } else { + int x = floorf(x1); + int y = floorf(y1 + 0.5f); + + float err = (x1 - (float)x) * dy - (y1 - (float)y) * dx; + + if (y < end_y) { + WORKER(x, y, > 0.5f * dy, 1, 1, -dy, dx, FIRST) + } + + while (y < end_y) { + WORKER(x, y, > 0.5f * dy, 1, 1, -dy, dx, STEP) + } + + if (y <= end_y) { + WORKER(x, y, > 0.5f * dy, 1, 1, -dy, dx, LAST) + } + } + } else { + if (-dx > dy) { + int x = floorf(x1 + 0.5f); + int y = floorf(y1); + + float err = (y1 - (float)y) * dx - (x1 - (float)x) * dy; + + if (x > end_x) { + WORKER(y, x, <= 0.5f * dx, 1, -1, -dx, -dy, FIRST) + } + + while (x > end_x) { + WORKER(y, x, <= 0.5f * dx, 1, -1, -dx, -dy, STEP) + } + + if (x >= end_x) { + WORKER(y, x, <= 0.5f * dx, 1, -1, -dx, -dy, LAST) + } + } else { + int x = floorf(x1); + int y = floorf(y1 + 0.5f); + + float err = (x1 - (float)x) * dy - (y1 - (float)y) * dx; + + /* + This is the only correction that needs to be made in the opposite direction of dy (or dx) + */ + if (err > 0.5f * dy) { + x += 1; + err -= dy; + } + + if (y < end_y) { + WORKER(x, y, <= -0.5f * dy, -1, 1, dy, dx, FIRST) + } + + while (y < end_y) { + WORKER(x, y, <= -0.5f * dy, -1, 1, dy, dx, STEP) + } + + if (y <= end_y) { + WORKER(x, y, <= -0.5f * dy, -1, 1, dy, dx, LAST) + } + } + } +#undef FIRST +#undef LAST +#undef STEP +#undef WORKER +} + +/* +This one will check to see what exactly we need to draw... +I.e. this will call all of the actual renderers and set the appropriate callbacks +*/ +void _al_line_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2) +{ + int shade = 1; + int grad = 1; + int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR v1c, v2c; + + v1c = v1->color; + v2c = v2->color; + + al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED) { + shade = 0; + } + + if (v1c.r == v2c.r && v1c.g == v2c.g && v1c.b == v2c.b && v1c.a == v2c.a) { + grad = 0; + } + + if (texture) { + if (grad) { + state_texture_grad_any_2d state; + state.solid.texture = texture; + + if (shade) { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_solid_any_draw_shade); + } else { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_solid_any_draw_opaque); + } + } else { + int white = 0; + state_texture_solid_any_2d state; + + if (v1c.r == 1 && v1c.g == 1 && v1c.b == 1 && v1c.a == 1) { + white = 1; + } + state.texture = texture; + + if (shade) { + if(white) { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade_white); + } else { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade); + } + } else { + if(white) { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque_white); + } else { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque); + } + } + } + } else { + if (grad) { + state_grad_any_2d state; + if (shade) { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_grad_any_first, shader_grad_any_step, shader_solid_any_draw_shade); + } else { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_grad_any_first, shader_grad_any_step, shader_solid_any_draw_opaque); + } + } else { + state_solid_any_2d state; + if (shade) { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_shade); + } else { + al_draw_soft_line(v1, v2, (uintptr_t)&state, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_opaque); + } + } + } +} + +/* Function: al_draw_soft_line + */ +void al_draw_soft_line(ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state, + void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int)) +{ + /* + Copy the vertices, because we need to alter them a bit before drawing. + */ + ALLEGRO_VERTEX vtx1 = *v1; + ALLEGRO_VERTEX vtx2 = *v2; + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + int need_unlock = 0; + ALLEGRO_LOCKED_REGION *lr; + int min_x, max_x, min_y, max_y; + int clip_min_x, clip_min_y, clip_max_x, clip_max_y; + + al_get_clipping_rectangle(&clip_min_x, &clip_min_y, &clip_max_x, &clip_max_y); + clip_max_x += clip_min_x; + clip_max_y += clip_min_y; + + /* + TODO: Need to clip them first, make a copy of the vertices first then + */ + + /* + Lock the region we are drawing to. We are choosing the minimum and maximum + possible pixels touched from the formula (easily verified by following the + above algorithm. + */ + + if (vtx1.x >= vtx2.x) { + max_x = (int)ceilf(vtx1.x) + 1; + min_x = (int)floorf(vtx2.x) - 1; + } else { + max_x = (int)ceilf(vtx2.x) + 1; + min_x = (int)floorf(vtx1.x) - 1; + } + if (vtx1.y >= vtx2.y) { + max_y = (int)ceilf(vtx1.y) + 1; + min_y = (int)floorf(vtx2.y) - 1; + } else { + max_y = (int)ceilf(vtx2.y) + 1; + min_y = (int)floorf(vtx1.y) - 1; + } + /* + TODO: This bit is temporary, the min max's will be guaranteed to be within the bitmap + once clipping is implemented + */ + if (min_x >= clip_max_x || min_y >= clip_max_y) + return; + if (max_x >= clip_max_x) + max_x = clip_max_x; + if (max_y >= clip_max_y) + max_y = clip_max_y; + + if (max_x < clip_min_x || max_y < clip_min_y) + return; + if (min_x < clip_min_x) + min_x = clip_min_x; + if (min_y < clip_min_y) + min_y = clip_min_y; + + if (al_is_bitmap_locked(target)) { + if (!_al_bitmap_region_is_locked(target, min_x, min_y, max_x - min_x, max_y - min_y) || + _al_pixel_format_is_video_only(target->locked_region.format)) + return; + } else { + if (!(lr = al_lock_bitmap_region(target, min_x, min_y, max_x - min_x, max_y - min_y, ALLEGRO_PIXEL_FORMAT_ANY, 0))) + return; + need_unlock = 1; + } + + line_stepper(state, first, step, draw, &vtx1, &vtx2); + + if (need_unlock) + al_unlock_bitmap(target); +} diff --git a/allegro/addons/primitives/nshader.cpp b/allegro/addons/primitives/nshader.cpp new file mode 100644 index 00000000..f5026760 --- /dev/null +++ b/allegro/addons/primitives/nshader.cpp @@ -0,0 +1,320 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * This program is used to pre-compile some dummy shaders from + * nshader.fx to be used in directx_shaders.c file. You will need + * fxc.exe which can be found in a Direct3D SDK (June 2010 has it). + * + * Usage: Run the program and it will regenerate precompiled_shaders.inc. + * (Make a backup of the old ones if you need them). + * + * Note, that this is not supposed to be compiled into the library. + * Compile this manually if needed. + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + */ + +# include <iostream> +# include <algorithm> +# include <fstream> +# include <cstdlib> +# include <vector> +# include <string> +# include <sstream> +# include <cstddef> +# include <iomanip> + +using namespace std; + +typedef unsigned char byte_t; + +typedef vector<byte_t> byte_vector_t; + +struct technique_t +{ + string name; + string shader; + byte_vector_t binary; +}; + +typedef vector<technique_t> technique_vector_t; + +int compile(const string& source, const string& dest) +{ + return system(("fxc /nologo /Tfx_2_0 /Fc " + dest + " " + source + " > nul").c_str()); +} + +int assemble(const string& source, const string& dest, const string& entrypoint) +{ + return system(("fxc /nologo /O3 /Fo " + dest + " " + source + " /E " + entrypoint + " > nul").c_str()); +} + +bool extract_shader(technique_t& technique, istream& stream) +{ + technique.shader.clear(); + + bool inside = false; + bool record = false; + + string line; + while (!getline(stream, line).fail()) + { + if (!inside && !record) + { + string::size_type pos = line.find_first_of("asm"); + if (pos == string::npos || line.compare(pos, 3, "asm") != 0) + continue; + + // strip everything to including "asm" keyword + line = line.substr(pos + 3); + + inside = true; + } + + if (inside && !record) + { + string::size_type pos = line.find_first_of("{"); + if (pos == string::npos) + continue; + + record = true; + + continue; + } + + if (inside && record) + { + string::size_type pos = line.find_first_of("}"); + if (pos != string::npos) + return true; + + string::size_type non_white = line.find_first_not_of(" "); + if (non_white != string::npos) + technique.shader += line.substr(non_white) + "\n"; + else + technique.shader += "\n"; + } + } + + return false; +} + +int extract_techniques(technique_vector_t& techniques, const string& filename) +{ + techniques.clear(); + + ifstream file(filename.c_str()); + if (!file) + return 0; + + technique_t technique; + + string line; + while (!getline(file, line).fail()) + { + string::size_type pos = line.find_first_of("technique"); + if (pos != 0 || line.compare(pos, 9, "technique") != 0) + continue; + + technique.name = line.substr(10); + if (technique.name.empty()) + { + cerr << " Unnamed technique. Skipping..." << endl; + continue; + } + + cout << " Found: " << technique.name << endl; + if (!extract_shader(technique, file)) + { + cerr << " Failed! Skipping..." << endl; + continue; + } + + techniques.push_back(technique); + } + + return (int)techniques.size(); +} + +int assemble_technique(const string& filename, technique_t& technique) +{ + const string dest = "vshader.vso"; + + int result = assemble(filename, dest, "vs_" + technique.name); + if (result) + return result; + + ifstream file(dest.c_str(), ios::in | ios::binary); + if (!file) + { + _unlink(dest.c_str()); + + return 1; + } + + file.seekg(0, ios::end); + technique.binary.resize(file.tellg()); + file.seekg(0, ios::beg); + file.read((char*)&technique.binary.front(), technique.binary.size()); + file.close(); + + _unlink(dest.c_str()); + + return 0; +} + +int assemble_techniques(const string& filename, technique_vector_t& techniques) +{ + int count = 0; + + technique_vector_t::iterator it, it_end = techniques.end(); + for (it = techniques.begin(); it != it_end; ++it) + { + technique_t& technique = *it; + + cout << " Processing: " << technique.name << endl; + int assembled = assemble_technique(filename, technique); + if (assembled) + { + cerr << " Failed." << endl; + continue; + } + + ++count; + } + + return count; +} + +char toupper2(char c) +{ + return toupper(c); +} + +int generate_table(ostream& output, technique_t& technique) +{ + const int bytes_per_line = 16; + + string::size_type pos = 0; + string name = technique.name, line; + + while ((pos = name.find_first_of('_', pos)) != string::npos) + name[pos] = ' '; + + transform(name.begin(), name.end(), name.begin(), toupper2); + + output << "/*" << endl; + output << " " << name << endl << endl; + + istringstream shader(technique.shader); + while (!getline(shader, line).fail()) + output << " " << line << endl; + output << "*/" << endl; + + output << "static const uint8_t _al_vs_" << technique.name << "[] = {" << endl; + + for (size_t i = 0; i < technique.binary.size(); ++i) + { + if ((i % bytes_per_line) == 0) + output << " "; + + output << "0x" << setw(2) << setfill('0') << hex << (int)technique.binary[i]; + + if (i != technique.binary.size() - 1) + { + if ((i % bytes_per_line) == (bytes_per_line - 1)) + output << "," << endl; + else + output << ", "; + } + } + output << endl; + + output.unsetf(ios::hex); + + output << "};" << endl; + + return 0; +} + +int generate_tables(ostream& output, technique_vector_t& techniques) +{ + int count = 0; + + output << "/* Generated using nshader.cpp. Do not hand edit. */" << endl; + + technique_vector_t::iterator it, it_end = techniques.end(); + for (it = techniques.begin(); it != it_end; ++it) + { + technique_t& technique = *it; + + cout << " Processing: " << technique.name << endl; + int generated = generate_table(output, technique); + if (generated) + { + cerr << " Failed." << endl; + continue; + } + + output << endl; + + ++count; + } + + return count; +} + +int main() +{ + const string source = "nshader.fx"; + const string compiled = "nshader.fxc"; + const string output = "precompiled_shaders.inc"; + + cout << "Compiling NULL shader..." << endl; + if (int result = compile(source, compiled)) + { + cout << " Failed!" << endl; + return result; + } + cout << "Done." << endl << endl; + + cout << "Extracting techniques..." << endl; + technique_vector_t techniques; + int found = extract_techniques(techniques, compiled); + if (found) + cout << "Done. " << found << " technique(s) extracted." << endl << endl; + else + cout << "Done. No techniques extracted." << endl << endl; + + _unlink(compiled.c_str()); + + if (found == 0) + return 0; + + cout << "Assembling techniques..." << endl; + int assembled = assemble_techniques(source, techniques); + if (assembled) + cout << "Done. " << assembled << " technique(s) assembled." << endl << endl; + else + cout << "Done. No assembled techniques." << endl << endl; + + if (assembled == 0) + return 0; + + cout << "Generating tables..." << endl; + + ofstream output_file(output.c_str()); + int tables = generate_tables(output_file, techniques); + cout << "Done. " << tables << " table(s) generated." << endl << endl; + + return 0; +} diff --git a/allegro/addons/primitives/nshader.fx b/allegro/addons/primitives/nshader.fx new file mode 100644 index 00000000..2564e0f0 --- /dev/null +++ b/allegro/addons/primitives/nshader.fx @@ -0,0 +1,72 @@ +# define CAT(a, b) CAT_I(a, b) +# define CAT_I(a, b) CAT_II(a ## b) +# define CAT_II(res) res + +# define JOIN1(a) a +# define JOIN2(a, b) CAT(a, b) +# define JOIN3(a, b, c) CAT(JOIN2(a, b), c) +# define JOIN4(a, b, c, d) CAT(JOIN3(a, b, c), d) +# define JOIN5(a, b, c, d, e) CAT(JOIN4(a, b, c, d), e) +# define JOIN6(a, b, c, d, e, f) CAT(JOIN5(a, b, c, d, e), f) +# define JOIN7(a, b, c, d, e, f, g) CAT(JOIN6(a, b, c, d, e, f), g) +# define JOIN8(a, b, c, d, e, f, g, h) CAT(JOIN7(a, b, c, d, e, f, g), h) + +# define DECL_VS_IN1(v0) struct JOIN2(vs_input_, v0) { _in_##v0 } +# define DECL_VS_IN2(v0, v1) struct JOIN4(vs_input_, v0, _, v1) { _in_##v0 _in_##v1 } +# define DECL_VS_IN3(v0, v1, v2) struct JOIN6(vs_input_, v0, _, v1, _, v2) { _in_##v0 _in_##v1 _in_##v2 } + +# define DECL_VS_OUT1(v0) struct JOIN2(vs_output_, v0) { _out_##v0 } +# define DECL_VS_OUT2(v0, v1) struct JOIN4(vs_output_, v0, _, v1) { _out_##v0 _out_##v1 } +# define DECL_VS_OUT3(v0, v1, v2) struct JOIN6(vs_output_, v0, _, v1, _, v2) { _out_##v0 _out_##v1 _out_##v2 } + +# define DEF_VS_BODY1(v0) void JOIN2(vs_, v0) (in JOIN2(vs_input_, v0) i, out JOIN2(vs_output_, v0) o) { _op_##v0 } +# define DEF_VS_BODY2(v0, v1) void JOIN4(vs_, v0, _, v1) (in JOIN4(vs_input_, v0, _, v1) i, out JOIN4(vs_output_, v0, _) o) { _op_##v0 _op_##v1 } +# define DEF_VS_BODY3(v0, v1, v2) void JOIN6(vs_, v0, _, v1, _, v2)(in JOIN6(vs_input_, v0, _, v1, _, v2) i, out JOIN6(vs_output_, v0, _, v1, _, v2) o) { _op_##v0 _op_##v1 _op_##v2 } + +# define DEF_TECH1(v0) technique JOIN1(v0) { pass { VertexShader = compile vs_1_1 JOIN2(vs_, v0)(); } } +# define DEF_TECH2(v0, v1) technique JOIN3(v0, _, v1) { pass { VertexShader = compile vs_1_1 JOIN4(vs_, v0, _, v1)(); } } +# define DEF_TECH3(v0, v1, v2) technique JOIN5(v0, _, v1, _, v2) { pass { VertexShader = compile vs_1_1 JOIN6(vs_, v0, _, v1, _, v2)(); } } + +# define DEF_VS1(v0) DECL_VS_IN1(v0); DECL_VS_OUT1(v0); DEF_VS_BODY1(v0) DEF_TECH1(v0) +# define DEF_VS2(v0, v1) DECL_VS_IN2(v0, v1); DECL_VS_OUT2(v0, v1); DEF_VS_BODY2(v0, v1) DEF_TECH2(v0, v1) +# define DEF_VS3(v0, v1, v2) DECL_VS_IN3(v0, v1, v2); DECL_VS_OUT3(v0, v1, v2); DEF_VS_BODY3(v0, v1, v2) DEF_TECH3(v0, v1, v2) + +# define _in_pos0 +# define _in_pos2 float2 pos : POSITION; +# define _in_pos3 float3 pos : POSITION; +# define _in_tex0 +# define _in_tex2 float2 tex : TEXCOORD0; +# define _in_col0 +# define _in_col4 float4 col : TEXCOORD1; + +# define _out_pos0 float4 pos : POSITION; +# define _out_pos2 float4 pos : POSITION; +# define _out_pos3 float4 pos : POSITION; +# define _out_tex0 +# define _out_tex2 float2 tex : TEXCOORD0; +# define _out_col0 float4 col : COLOR0; +# define _out_col4 float4 col : COLOR0; + +# define _op_pos0 o.pos = float4(0.0f, 0.0f, 0.0f, 1.0f); +# define _op_pos2 o.pos = mul(float4(i.pos.xy, 0.0f, 1.0f), g_world_view_proj); +# define _op_pos3 o.pos = mul(float4(i.pos.xyz, 1.0f), g_world_view_proj); +# define _op_tex0 +# define _op_tex2 o.tex = mul(float4(i.tex.xy, 1.0f, 0.0f), g_texture_proj).xy; +# define _op_col0 o.col = float4(1.0f, 1.0f, 1.0f, 1.0f); +# define _op_col4 o.col = i.col; + +float4x4 g_world_view_proj : register(c0); +float4x4 g_texture_proj : register(c4); + +DEF_VS3(pos3, tex2, col4); +DEF_VS3(pos3, tex2, col0); +DEF_VS3(pos3, tex0, col4); +DEF_VS3(pos3, tex0, col0); +DEF_VS3(pos2, tex2, col4); +DEF_VS3(pos2, tex2, col0); +DEF_VS3(pos2, tex0, col4); +DEF_VS3(pos2, tex0, col0); +DEF_VS3(pos0, tex2, col4); +DEF_VS3(pos0, tex2, col0); +DEF_VS3(pos0, tex0, col4); +DEF_VS3(pos0, tex0, col0); diff --git a/allegro/addons/primitives/point_soft.c b/allegro/addons/primitives/point_soft.c new file mode 100644 index 00000000..e22b80fd --- /dev/null +++ b/allegro/addons/primitives/point_soft.c @@ -0,0 +1,87 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Software point implementation functions. + * + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + + +#define _AL_NO_BLEND_INLINE_FUNC + +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/internal/aintern_blend.h" +#include "allegro5/internal/aintern_prim.h" +#include "allegro5/internal/aintern_prim_soft.h" +#include <math.h> + +static int fix_var(float var, int max_var) +{ + const int ivar = (int)floorf(var); + const int ret = ivar % max_var; + if(ret >= 0) + return ret; + else + return ret + max_var; +} + +void _al_point_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v) +{ + int shade = 1; + int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR vc; + int clip_min_x, clip_min_y, clip_max_x, clip_max_y; + int x = (int)floorf(v->x); + int y = (int)floorf(v->x); + + al_get_clipping_rectangle(&clip_min_x, &clip_min_y, &clip_max_x, &clip_max_y); + clip_max_x += clip_min_x; + clip_max_y += clip_min_y; + + if(x < clip_min_x || x >= clip_max_x || y < clip_min_y || y >= clip_max_y) + return; + + vc = v->color; + + al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED) { + shade = 0; + } + + if (texture) { + float U = fix_var(v->u, al_get_bitmap_width(texture)); + float V = fix_var(v->v, al_get_bitmap_height(texture)); + ALLEGRO_COLOR color = al_get_pixel(texture, U, V); + + if(vc.r != 1 || vc.g != 1 || vc.b != 1 || vc.a != 1) { + color.r *= vc.r; + color.g *= vc.g; + color.b *= vc.b; + color.a *= vc.a; + } + + if (shade) { + al_put_blended_pixel(v->x, v->y, color); + } else { + al_put_pixel(v->x, v->y, color); + } + } else { + ALLEGRO_COLOR color = al_map_rgba_f(vc.r, vc.g, vc.b, vc.a); + if (shade) { + al_put_blended_pixel(v->x, v->y, color); + } else { + al_put_pixel(v->x, v->y, color); + } + } +} diff --git a/allegro/addons/primitives/polygon.c b/allegro/addons/primitives/polygon.c new file mode 100644 index 00000000..d245629b --- /dev/null +++ b/allegro/addons/primitives/polygon.c @@ -0,0 +1,84 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Polygon with holes drawing routines. + * + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/internal/aintern_prim.h" +#include <math.h> + +#ifdef ALLEGRO_MSVC + #define hypotf(x, y) _hypotf((x), (y)) +#endif + +static void polygon_push_triangle_callback(int i0, int i1, int i2, void* user_data) +{ + ALLEGRO_PRIM_VERTEX_CACHE* cache = (ALLEGRO_PRIM_VERTEX_CACHE*)user_data; + + const float* vertices = (const float*)cache->user_data; + + const float* v0 = vertices + (i0 * 2); + const float* v1 = vertices + (i1 * 2); + const float* v2 = vertices + (i2 * 2); + + _al_prim_cache_push_triangle(cache, v0, v1, v2); +} + + +/* Function: al_draw_polygon + */ +void al_draw_polygon(const float *vertices, int vertex_count, + int join_style, ALLEGRO_COLOR color, float thickness, float miter_limit) +{ + al_draw_polyline(vertices, 2 * sizeof(float), vertex_count, join_style, + ALLEGRO_LINE_CAP_CLOSED, color, thickness, miter_limit); +} + +/* Function: al_draw_filled_polygon + */ +void al_draw_filled_polygon(const float *vertices, int vertex_count, + ALLEGRO_COLOR color) +{ + ALLEGRO_PRIM_VERTEX_CACHE cache; + int vertex_counts[2]; + + _al_prim_cache_init_ex(&cache, ALLEGRO_PRIM_VERTEX_CACHE_TRIANGLE, color, (void*)vertices); + + vertex_counts[0] = vertex_count; + vertex_counts[1] = 0; /* terminator */ + al_triangulate_polygon(vertices, sizeof(float) * 2, vertex_counts, + polygon_push_triangle_callback, &cache); + + _al_prim_cache_flush(&cache); +} + +/* Function: al_draw_filled_polygon_with_holes + */ +void al_draw_filled_polygon_with_holes(const float *vertices, + const int *vertex_counts, ALLEGRO_COLOR color) +{ + ALLEGRO_PRIM_VERTEX_CACHE cache; + + _al_prim_cache_init_ex(&cache, ALLEGRO_PRIM_VERTEX_CACHE_TRIANGLE, color, (void*)vertices); + + al_triangulate_polygon(vertices, sizeof(float) * 2, vertex_counts, + polygon_push_triangle_callback, &cache); + + _al_prim_cache_flush(&cache); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/primitives/polyline.c b/allegro/addons/primitives/polyline.c new file mode 100644 index 00000000..5dc17c21 --- /dev/null +++ b/allegro/addons/primitives/polyline.c @@ -0,0 +1,542 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Polyline primitive. + * + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/internal/aintern_list.h" +#include "allegro5/internal/aintern_prim.h" +#include <float.h> +#include <math.h> + + +/* + * Computes direction, normal direction and the length of the segment. + */ +static float compute_direction_and_normal(const float* begin, const float* end, float* dir, float* normal) +{ + float length; + + /* Determine direction, normal direction and length of the line segment. */ + dir[0] = end[0] - begin[0]; + dir[1] = end[1] - begin[1]; + + length = _al_prim_normalize(dir); + + normal[0] = -dir[1]; + normal[1] = dir[0]; + + return length; +} + +/* + * Compute end cross points. + */ +static void compute_end_cross_points(const float* v0, const float* v1, float radius, float* p0, float* p1) +{ + float dir[2]; + float normal[2]; + /* XXX delete this parameter? */ + (void)radius; + + compute_direction_and_normal(v0, v1, dir, normal); + + p0[0] = v1[0] + normal[0] * radius; + p0[1] = v1[1] + normal[1] * radius; + p1[0] = v1[0] - normal[0] * radius; + p1[1] = v1[1] - normal[1] * radius; +} + +/* + * Compute cross points. + */ +static void compute_cross_points(const float* v0, const float* v1, const float* v2, float radius, + float* l0, float* l1, float* r0, float* r1, float* out_middle, float* out_angle, float* out_miter_distance) +{ + float normal_0[2], normal_1[2]; + float dir_0[2], dir_1[2]; + float middle[2]; + float diff[2]; + float miter_distance; + float angle; + float len_0, len_1; + bool sharp = false; + + /* Compute directions. */ + len_0 = compute_direction_and_normal(v0, v1, dir_0, normal_0); + len_1 = compute_direction_and_normal(v1, v2, dir_1, normal_1); + + /* Compute angle of deflection between segments. */ + diff[0] = dir_0[0] * dir_1[0] + dir_0[1] * dir_1[1]; + diff[1] = -(dir_0[0] * dir_1[1] - dir_0[1] * dir_1[0]); + + angle = (diff[0] || diff[1]) ? atan2f(diff[1], diff[0]) : 0.0f; + + /* Calculate miter distance. */ + miter_distance = angle != 0.0f ? radius / cosf(fabsf(angle) * 0.5f) : radius; + + /* If the angle is too sharp, we give up on trying not to overdraw. */ + if (miter_distance < 0) { + sharp = true; + miter_distance = 0; + } + if (miter_distance > len_0) { + sharp = true; + miter_distance = len_0; + } + if(miter_distance > len_1) { + sharp = true; + miter_distance = len_1; + } + + middle[0] = normal_0[0] + normal_1[0]; + middle[1] = normal_0[1] + normal_1[1]; + + if (middle[0] == middle[1] && middle[0] == 0.0) { + middle[0] = dir_1[0]; + middle[1] = dir_1[1]; + } + + _al_prim_normalize(middle); + + /* Compute points. */ + if (angle > 0.0f) + { + l0[0] = v1[0] + normal_0[0] * radius; + l0[1] = v1[1] + normal_0[1] * radius; + r0[0] = v1[0] + normal_1[0] * radius; + r0[1] = v1[1] + normal_1[1] * radius; + + if (sharp) { + l1[0] = v1[0] - normal_0[0] * radius; + l1[1] = v1[1] - normal_0[1] * radius; + r1[0] = v1[0] - normal_1[0] * radius; + r1[1] = v1[1] - normal_1[1] * radius; + } + else { + l1[0] = r1[0] = v1[0] - middle[0] * miter_distance; + l1[1] = r1[1] = v1[1] - middle[1] * miter_distance; + } + } + else + { + middle[0] = -middle[0]; + middle[1] = -middle[1]; + + l1[0] = v1[0] - normal_0[0] * radius; + l1[1] = v1[1] - normal_0[1] * radius; + r1[0] = v1[0] - normal_1[0] * radius; + r1[1] = v1[1] - normal_1[1] * radius; + + if (sharp) { + l0[0] = v1[0] + normal_0[0] * radius; + l0[1] = v1[1] + normal_0[1] * radius; + r0[0] = v1[0] + normal_1[0] * radius; + r0[1] = v1[1] + normal_1[1] * radius; + } + else { + l0[0] = r0[0] = v1[0] - middle[0] * miter_distance; + l0[1] = r0[1] = v1[1] - middle[1] * miter_distance; + } + } + + if (out_angle) + *out_angle = angle; + + if (out_miter_distance) + *out_miter_distance = miter_distance; + + if (out_middle) + memcpy(out_middle, middle, sizeof(float) * 2); +} + +/* + * Emits filled arc. + * + * Arc is defined by pivot point, radius, start and end angle. + * Starting and ending angle are wrapped to two pi range. + */ +static void emit_arc(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* pivot, float start, float end, float radius, int segments) +{ + float arc; + float c, s, t; + float v0[2]; + float v1[2]; + float cp[2]; + int i; + + /* This is very small arc, we will draw nothing. */ + if (fabsf(end - start) < 0.001f) + return; + + /* Make sure start both start angle is located in the + * range [0, 2 * pi) and end angle is greater than + * start angle. + */ + start = fmodf(start, ALLEGRO_PI * 2.0f); + end = fmodf(end, ALLEGRO_PI * 2.0f); + if (end <= start) + end += ALLEGRO_PI * 2.0f; + + arc = end - start; + + segments = (int)(segments * arc / ALLEGRO_PI * 2.0f); + if (segments < 1) + segments = 1; + + c = cosf(arc / segments); + s = sinf(arc / segments); + cp[0] = cosf(start) * radius; + cp[1] = sinf(start) * radius; + v0[0] = cp[0] + pivot[0]; + v0[1] = cp[1] + pivot[1]; + + for (i = 0; i < segments - 1; ++i) + { + t = cp[0]; + cp[0] = c * cp[0] - s * cp[1]; + cp[1] = s * t + c * cp[1]; + + v1[0] = cp[0] + pivot[0]; + v1[1] = cp[1] + pivot[1]; + + _al_prim_cache_push_triangle(cache, v0, pivot, v1); + + v0[0] = v1[0]; + v0[1] = v1[1]; + } + + v1[0] = cosf(end) * radius + pivot[0]; + v1[1] = sinf(end) * radius + pivot[1]; + _al_prim_cache_push_triangle(cache, v0, pivot, v1); +} + +/* + * Emits square cap. + * + * Square cap is an rectangle with edges lengths equal to radius + * and double radius, first along direction second along normal + * direction. + */ +static void emit_square_end_cap(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* pivot, const float* dir, const float* normal, float radius) +{ + /* Prepare all four vertices of the rectangle. */ + float v0[2] = { pivot[0] + normal[0] * radius, pivot[1] + normal[1] * radius }; + float v1[2] = { pivot[0] - normal[0] * radius, pivot[1] - normal[1] * radius }; + float v2[2] = { v0[0] + dir[0] * radius, v0[1] + dir[1] * radius }; + float v3[2] = { v1[0] + dir[0] * radius, v1[1] + dir[1] * radius }; + + /* Emit. */ + _al_prim_cache_push_triangle(cache, v0, v2, v3); + _al_prim_cache_push_triangle(cache, v0, v3, v1); +} + +/* + * Emits triangular cap. + */ +static void emit_triange_end_cap(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* pivot, const float* dir, const float* normal, float radius) +{ + /* Prepare all four vertices of the rectangle. */ + float v0[2] = { pivot[0] + normal[0] * radius, pivot[1] + normal[1] * radius }; + float v1[2] = { pivot[0] - normal[0] * radius, pivot[1] - normal[1] * radius }; + float v2[2] = { pivot[0] + dir[0] * radius, pivot[1] + dir[1] * radius }; + + /* Emit. */ + _al_prim_cache_push_triangle(cache, v0, v2, v1); +} + +/* + * Emits rounded cap. + */ +static void emit_round_end_cap(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* pivot, const float* dir, const float* normal, float radius) +{ + float angle = atan2f(-normal[1], -normal[0]); + /* XXX delete these parameters? */ + (void)dir; + (void)radius; + + emit_arc(cache, pivot, angle, angle + ALLEGRO_PI, radius, 16); +} + +/* + * Emits end cap. + * + * Direction of the end cap is defined by vector [v1 - v0]. p0 and p1 are starting + * and ending point of the cap. Both should be located on the circle with center + * in v1 and specified radius. p0 have to be located on the negative and p0 on the + * positive half plane defined by direction vector. + */ +static void emit_end_cap(ALLEGRO_PRIM_VERTEX_CACHE* cache, int cap_style, const float* v0, const float* v1, float radius) +{ + float dir[2]; + float normal[2]; + + /* Do do not want you to call this function for closed cap. + * It is special and there is nothing we can do with it there. + */ + ASSERT(cap_style != ALLEGRO_LINE_CAP_CLOSED); + + /* There nothing we can do for this kind of ending cap. */ + if (cap_style == ALLEGRO_LINE_CAP_NONE) + return; + + /* Compute normal and direction for our segment. */ + compute_direction_and_normal(v0, v1, dir, normal); + + /* Emit vertices for cap. */ + if (cap_style == ALLEGRO_LINE_CAP_SQUARE) + emit_square_end_cap(cache, v1, dir, normal, radius); + else if (cap_style == ALLEGRO_LINE_CAP_TRIANGLE) + emit_triange_end_cap(cache, v1, dir, normal, radius); + else if (cap_style == ALLEGRO_LINE_CAP_ROUND) + emit_round_end_cap(cache, v1, dir, normal, radius); + else { + + ASSERT("Unknown or unsupported style of ending cap." && false); + } +} + +/* + * Emits bevel join. + */ +static void emit_bevel_join(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* pivot, const float* p0, const float* p1) +{ + _al_prim_cache_push_triangle(cache, pivot, p0, p1); +} + +/* + * Emits round join. + */ +static void emit_round_join(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* pivot, const float* p0, const float* p1, float radius) +{ + float start = atan2f(p1[1] - pivot[1], p1[0] - pivot[0]); + float end = atan2f(p0[1] - pivot[1], p0[0] - pivot[0]); + + if (end < start) + end += ALLEGRO_PI * 2.0f; + + emit_arc(cache, pivot, start, end, radius, 16); +} + +/* + * Emits miter join. + */ +static void emit_miter_join(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* pivot, const float* p0, const float* p1, + float radius, const float* middle, float angle, float miter_distance, float max_miter_distance) +{ + /* XXX delete this parameter? */ + (void)radius; + + if (miter_distance > max_miter_distance) { + + float normal[2] = { -middle[1], middle[0] }; + + float offset = (miter_distance - max_miter_distance) * tanf((ALLEGRO_PI - fabsf(angle)) * 0.5f); + + float v0[2] = { + pivot[0] + middle[0] * max_miter_distance + normal[0] * offset, + pivot[1] + middle[1] * max_miter_distance + normal[1] * offset + }; + + float v1[2] = { + pivot[0] + middle[0] * max_miter_distance - normal[0] * offset, + pivot[1] + middle[1] * max_miter_distance - normal[1] * offset + }; + + _al_prim_cache_push_triangle(cache, pivot, v0, v1); + _al_prim_cache_push_triangle(cache, pivot, p0, v0); + _al_prim_cache_push_triangle(cache, pivot, p1, v1); + } + else { + + float miter[2] = { + pivot[0] + middle[0] * miter_distance, + pivot[1] + middle[1] * miter_distance, + }; + + _al_prim_cache_push_triangle(cache, pivot, p0, miter); + _al_prim_cache_push_triangle(cache, pivot, miter, p1); + } +} + + +/* Emit join between segments. + */ +static void emit_join(ALLEGRO_PRIM_VERTEX_CACHE* cache, int join_style, const float* pivot, + const float* p0, const float* p1, float radius, const float* middle, + float angle, float miter_distance, float miter_limit) +{ + /* There is nothing to do for this type of join. */ + if (join_style == ALLEGRO_LINE_JOIN_NONE) + return; + + if (join_style == ALLEGRO_LINE_JOIN_BEVEL) + emit_bevel_join(cache, pivot, p0, p1); + else if (join_style == ALLEGRO_LINE_JOIN_ROUND) + emit_round_join(cache, pivot, p0, p1, radius); + else if (join_style == ALLEGRO_LINE_JOIN_MITER) + emit_miter_join(cache, pivot, p0, p1, radius, middle, angle, miter_distance, miter_limit * radius); + else { + + ASSERT("Unknown or unsupported style of join." && false); + } +} + +static void emit_polyline(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* vertices, int vertex_stride, int vertex_count, int join_style, int cap_style, float thickness, float miter_limit) +{ +# define VERTEX(index) ((const float*)(((uint8_t*)vertices) + vertex_stride * ((vertex_count + (index)) % vertex_count))) + + float l0[2], l1[2]; + float r0[2], r1[2]; + float p0[2], p1[2]; + float radius; + int steps; + int i; + + ASSERT(thickness > 0.0f); + + /* Discard invalid lines. */ + if (vertex_count < 2) + return; + + radius = 0.5f * thickness; + + /* Single line cannot be closed. If user forgot to explicitly specify + * most desired alternative cap style, we just disable capping at all. + */ + if (vertex_count == 2 && cap_style == ALLEGRO_LINE_CAP_CLOSED) + cap_style = ALLEGRO_LINE_CAP_NONE; + + /* Prepare initial set of vertices. */ + if (cap_style != ALLEGRO_LINE_CAP_CLOSED) + { + /* We can emit ending caps right now. + * + * VERTEX(-2) and similar are safe, because it at this place + * it is guaranteed that there are at least two vertices + * in the buffer. + */ + emit_end_cap(cache, cap_style, VERTEX(1), VERTEX(0), radius); + emit_end_cap(cache, cap_style, VERTEX(-2), VERTEX(-1), radius); + + /* Compute points on the left side of the very first segment. */ + compute_end_cross_points(VERTEX(1), VERTEX(0), radius, p1, p0); + + /* For non-closed line we have N - 1 steps, but since we iterate + * from one, N is right value. + */ + steps = vertex_count; + } + else + { + /* Compute points on the left side of the very first segment. */ + compute_cross_points(VERTEX(-1), VERTEX(0), VERTEX(1), radius, l0, l1, p0, p1, NULL, NULL, NULL); + + /* Closed line use N steps, because last vertex have to be + * connected with first one. + */ + steps = vertex_count + 1; + } + + /* Process segments. */ + for (i = 1; i < steps; ++i) + { + /* Pick vertex and their neighbors. */ + const float* v0 = VERTEX(i - 1); + const float* v1 = VERTEX(i); + const float* v2 = VERTEX(i + 1); + + /* Choose correct cross points. */ + if ((cap_style == ALLEGRO_LINE_CAP_CLOSED) || (i < steps - 1)) { + + float middle[2]; + float miter_distance; + float angle; + + /* Compute cross points. */ + compute_cross_points(v0, v1, v2, radius, l0, l1, r0, r1, middle, &angle, &miter_distance); + + /* Emit join. */ + if (angle >= 0.0f) + emit_join(cache, join_style, v1, l0, r0, radius, middle, angle, miter_distance, miter_limit); + else + emit_join(cache, join_style, v1, r1, l1, radius, middle, angle, miter_distance, miter_limit); + } + else + compute_end_cross_points(v0, v1, radius, l0, l1); + + /* Emit triangles. */ + _al_prim_cache_push_triangle(cache, v0, v1, l1); + _al_prim_cache_push_triangle(cache, v0, l1, p1); + _al_prim_cache_push_triangle(cache, v0, p0, l0); + _al_prim_cache_push_triangle(cache, v0, l0, v1); + + /* Save current most right vertices. */ + memcpy(p0, r0, sizeof(float) * 2); + memcpy(p1, r1, sizeof(float) * 2); + } + +# undef VERTEX +} + +static void do_draw_polyline(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* vertices, int vertex_stride, int vertex_count, int join_style, int cap_style, ALLEGRO_COLOR color, float thickness, float miter_limit) +{ + if (thickness > 0.0f) + { + _al_prim_cache_init(cache, ALLEGRO_PRIM_VERTEX_CACHE_TRIANGLE, color); + emit_polyline(cache, vertices, vertex_stride, vertex_count, join_style, cap_style, thickness, miter_limit); + _al_prim_cache_term(cache); + } + else + { +# define VERTEX(index) ((const float*)(((uint8_t*)vertices) + vertex_stride * ((vertex_count + (index)) % vertex_count))) + + int i; + + _al_prim_cache_init(cache, ALLEGRO_PRIM_VERTEX_CACHE_LINE_STRIP, color); + + for (i = 0; i < vertex_count; ++i) { + if (cache->size >= (ALLEGRO_VERTEX_CACHE_SIZE - 2)) + _al_prim_cache_flush(cache); + + _al_prim_cache_push_point(cache, VERTEX(i)); + } + + if (cap_style == ALLEGRO_LINE_CAP_CLOSED && vertex_count > 2) { + if (cache->size >= (ALLEGRO_VERTEX_CACHE_SIZE - 2)) + _al_prim_cache_flush(cache); + + _al_prim_cache_push_point(cache, VERTEX(0)); + } + + _al_prim_cache_term(cache); + +# undef VERTEX + } +} + +/* Function: al_draw_polyline + */ +void al_draw_polyline(const float* vertices, int vertex_stride, + int vertex_count, int join_style, int cap_style, + ALLEGRO_COLOR color, float thickness, float miter_limit) +{ + ALLEGRO_PRIM_VERTEX_CACHE cache; + do_draw_polyline(&cache, vertices, vertex_stride, vertex_count, join_style, cap_style, color, thickness, miter_limit); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/primitives/precompiled_shaders.inc b/allegro/addons/primitives/precompiled_shaders.inc new file mode 100644 index 00000000..4c179a9a --- /dev/null +++ b/allegro/addons/primitives/precompiled_shaders.inc @@ -0,0 +1,618 @@ +/* Generated using nshader.cpp. Do not hand edit. */ +/* + POS3 TEX2 COL4 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_texture_proj; + // float4x4 g_world_view_proj; + // + // + // Registers: + // + // Name Reg Size + // ----------------- ----- ---- + // g_world_view_proj c0 4 + // g_texture_proj c4 2 + // + + vs_1_1 + def c6, 1, 0, 0, 0 + dcl_position v0 + dcl_texcoord v1 + dcl_texcoord1 v2 + mad r0, v0.xyzx, c6.xxxy, c6.yyyx + dp4 oPos.x, r0, c0 + dp4 oPos.y, r0, c1 + dp4 oPos.z, r0, c2 + dp4 oPos.w, r0, c3 + mad r0.xyz, v1.xyxw, c6.xxyw, c6.yyxw + dp3 oT0.x, r0, c4 + dp3 oT0.y, r0, c5 + mov oD0, v2 + + // approximately 9 instruction slots used +*/ +static const uint8_t _al_vs_pos3_tex2_col4[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x2d, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x12, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, + 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, + 0x6a, 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, + 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0x51, 0x00, 0x00, 0x05, + 0x06, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, + 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, + 0x05, 0x00, 0x01, 0x80, 0x02, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, + 0x00, 0x00, 0x24, 0x90, 0x06, 0x00, 0x40, 0xa0, 0x06, 0x00, 0x15, 0xa0, 0x09, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x02, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS3 TEX2 COL0 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_texture_proj; + // float4x4 g_world_view_proj; + // + // + // Registers: + // + // Name Reg Size + // ----------------- ----- ---- + // g_world_view_proj c0 4 + // g_texture_proj c4 2 + // + + vs_1_1 + def c6, 1, 0, 0, 0 + dcl_position v0 + dcl_texcoord v1 + mad r0, v0.xyzx, c6.xxxy, c6.yyyx + dp4 oPos.x, r0, c0 + dp4 oPos.y, r0, c1 + dp4 oPos.z, r0, c2 + dp4 oPos.w, r0, c3 + mad r0.xyz, v1.xyxw, c6.xxyw, c6.yyxw + dp3 oT0.x, r0, c4 + dp3 oT0.y, r0, c5 + mov oD0, c6.x + + // approximately 9 instruction slots used +*/ +static const uint8_t _al_vs_pos3_tex2_col0[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x2d, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x12, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, + 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, + 0x6a, 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, + 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0x51, 0x00, 0x00, 0x05, + 0x06, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, + 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x24, 0x90, 0x06, 0x00, 0x40, 0xa0, 0x06, 0x00, 0x15, 0xa0, + 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, + 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0xa0, + 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0xa0, + 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, + 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, + 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, + 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x06, 0x00, 0x00, 0xa0, + 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS3 TEX0 COL4 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_world_view_proj; + // + // + // Registers: + // + // Name Reg Size + // ----------------- ----- ---- + // g_world_view_proj c0 4 + // + + vs_1_1 + def c4, 1, 0, 0, 0 + dcl_position v0 + dcl_texcoord1 v1 + mad r0, v0.xyzx, c4.xxxy, c4.yyyx + dp4 oPos.x, r0, c0 + dp4 oPos.y, r0, c1 + dp4 oPos.z, r0, c2 + dp4 oPos.w, r0, c3 + mov oD0, v1 + + // approximately 6 instruction slots used +*/ +static const uint8_t _al_vs_pos3_tex0_col4[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x24, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x5f, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0xab, + 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, + 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x04, 0x00, 0x0f, 0xa0, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, + 0x05, 0x00, 0x01, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0f, 0x80, + 0x00, 0x00, 0x24, 0x90, 0x04, 0x00, 0x40, 0xa0, 0x04, 0x00, 0x15, 0xa0, 0x09, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0xa0, 0x09, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x0f, 0xd0, 0x01, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS3 TEX0 COL0 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_world_view_proj; + // + // + // Registers: + // + // Name Reg Size + // ----------------- ----- ---- + // g_world_view_proj c0 4 + // + + vs_1_1 + def c4, 1, 0, 0, 0 + dcl_position v0 + mad r0, v0.xyzx, c4.xxxy, c4.yyyx + dp4 oPos.x, r0, c0 + dp4 oPos.y, r0, c1 + dp4 oPos.z, r0, c2 + dp4 oPos.w, r0, c3 + mov oD0, c4.x + + // approximately 6 instruction slots used +*/ +static const uint8_t _al_vs_pos3_tex0_col0[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x24, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x5f, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0xab, + 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, + 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x04, 0x00, 0x0f, 0xa0, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x24, 0x90, 0x04, 0x00, 0x40, 0xa0, 0x04, 0x00, 0x15, 0xa0, + 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0xa0, + 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xe4, 0xa0, + 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xe4, 0xa0, + 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xe4, 0xa0, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x04, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS2 TEX2 COL4 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_texture_proj; + // float4x4 g_world_view_proj; + // + // + // Registers: + // + // Name Reg Size + // ----------------- ----- ---- + // g_world_view_proj c0 4 + // g_texture_proj c4 2 + // + + vs_1_1 + def c6, 1, 0, 0, 0 + dcl_position v0 + dcl_texcoord v1 + dcl_texcoord1 v2 + mad r0.xyz, v0.xyxw, c6.xxyw, c6.yyxw + dp3 oPos.x, r0, c0.xyww + dp3 oPos.y, r0, c1.xyww + dp3 oPos.z, r0, c2.xyww + dp3 oPos.w, r0, c3.xyww + mad r0.xyz, v1.xyxw, c6.xxyw, c6.yyxw + dp3 oT0.x, r0, c4 + dp3 oT0.y, r0, c5 + mov oD0, v2 + + // approximately 9 instruction slots used +*/ +static const uint8_t _al_vs_pos2_tex2_col4[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x2d, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x12, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, + 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, + 0x6a, 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, + 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0x51, 0x00, 0x00, 0x05, + 0x06, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, + 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, + 0x05, 0x00, 0x01, 0x80, 0x02, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, + 0x00, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xf4, 0xa0, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x02, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS2 TEX2 COL0 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_texture_proj; + // float4x4 g_world_view_proj; + // + // + // Registers: + // + // Name Reg Size + // ----------------- ----- ---- + // g_world_view_proj c0 4 + // g_texture_proj c4 2 + // + + vs_1_1 + def c6, 1, 0, 0, 0 + dcl_position v0 + dcl_texcoord v1 + mad r0.xyz, v0.xyxw, c6.xxyw, c6.yyxw + dp3 oPos.x, r0, c0.xyww + dp3 oPos.y, r0, c1.xyww + dp3 oPos.z, r0, c2.xyww + dp3 oPos.w, r0, c3.xyww + mad r0.xyz, v1.xyxw, c6.xxyw, c6.yyxw + dp3 oT0.x, r0, c4 + dp3 oT0.y, r0, c5 + mov oD0, c6.x + + // approximately 9 instruction slots used +*/ +static const uint8_t _al_vs_pos2_tex2_col0[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x2d, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x12, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, + 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x67, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, + 0x6a, 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, + 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0x51, 0x00, 0x00, 0x05, + 0x06, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, + 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, 0x06, 0x00, 0xc5, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xf4, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xf4, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xf4, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xf4, 0xa0, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x01, 0x00, 0xc4, 0x90, 0x06, 0x00, 0xd0, 0xa0, + 0x06, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, + 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, + 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x06, 0x00, 0x00, 0xa0, + 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS2 TEX0 COL4 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_world_view_proj; + // + // + // Registers: + // + // Name Reg Size + // ----------------- ----- ---- + // g_world_view_proj c0 4 + // + + vs_1_1 + def c4, 1, 0, 0, 0 + dcl_position v0 + dcl_texcoord1 v1 + mad r0.xyz, v0.xyxw, c4.xxyw, c4.yyxw + dp3 oPos.x, r0, c0.xyww + dp3 oPos.y, r0, c1.xyww + dp3 oPos.z, r0, c2.xyww + dp3 oPos.w, r0, c3.xyww + mov oD0, v1 + + // approximately 6 instruction slots used +*/ +static const uint8_t _al_vs_pos2_tex0_col4[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x24, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x5f, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0xab, + 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, + 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x04, 0x00, 0x0f, 0xa0, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, + 0x05, 0x00, 0x01, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, + 0x00, 0x00, 0xc4, 0x90, 0x04, 0x00, 0xd0, 0xa0, 0x04, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xf4, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xf4, 0xa0, 0x01, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x0f, 0xd0, 0x01, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS2 TEX0 COL0 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_world_view_proj; + // + // + // Registers: + // + // Name Reg Size + // ----------------- ----- ---- + // g_world_view_proj c0 4 + // + + vs_1_1 + def c4, 1, 0, 0, 0 + dcl_position v0 + mad r0.xyz, v0.xyxw, c4.xxyw, c4.yyxw + dp3 oPos.x, r0, c0.xyww + dp3 oPos.y, r0, c1.xyww + dp3 oPos.z, r0, c2.xyww + dp3 oPos.w, r0, c3.xyww + mov oD0, c4.x + + // approximately 6 instruction slots used +*/ +static const uint8_t _al_vs_pos2_tex0_col0[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x24, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x5f, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0xab, + 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, + 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x04, 0x00, 0x0f, 0xa0, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, 0x04, 0x00, 0xd0, 0xa0, 0x04, 0x00, 0xc5, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xf4, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0xf4, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, 0xf4, 0xa0, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0xc0, 0x00, 0x00, 0xe4, 0x80, 0x03, 0x00, 0xf4, 0xa0, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x04, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS0 TEX2 COL4 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_texture_proj; + // + // + // Registers: + // + // Name Reg Size + // -------------- ----- ---- + // g_texture_proj c4 2 + // + + vs_1_1 + def c0, 1, 0, 0, 0 + dcl_texcoord v0 + dcl_texcoord1 v1 + mad r0.xyz, v0.xyxw, c0.xxyw, c0.yyxw + dp3 oT0.x, r0, c4 + dp3 oT0.y, r0, c5 + mov oPos, c0.yyyx + mov oD0, v1 + + // approximately 5 instruction slots used +*/ +static const uint8_t _al_vs_pos0_tex2_col4[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x23, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x12, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x5f, 0x74, 0x65, + 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0x03, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x73, 0x5f, 0x32, + 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, + 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, + 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, + 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x80, + 0x01, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xc4, 0x90, + 0x00, 0x00, 0xd0, 0xa0, 0x00, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xe0, + 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0xe0, + 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xc0, + 0x00, 0x00, 0x15, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x01, 0x00, 0xe4, 0x90, + 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS0 TEX2 COL0 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + // + // Parameters: + // + // float4x4 g_texture_proj; + // + // + // Registers: + // + // Name Reg Size + // -------------- ----- ---- + // g_texture_proj c4 2 + // + + vs_1_1 + def c0, 1, 0, 0, 0 + dcl_texcoord v0 + mad r0.xyz, v0.xyxw, c0.xxyw, c0.yyxw + dp3 oT0.x, r0, c4 + dp3 oT0.y, r0, c5 + mov oPos, c0.yyyx + mov oD0, c0.x + + // approximately 5 instruction slots used +*/ +static const uint8_t _al_vs_pos0_tex2_col0[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x23, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x12, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x5f, 0x74, 0x65, + 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x00, 0xab, 0x03, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x73, 0x5f, 0x32, + 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, + 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, + 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, + 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x07, 0x80, + 0x00, 0x00, 0xc4, 0x90, 0x00, 0x00, 0xd0, 0xa0, 0x00, 0x00, 0xc5, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0xa0, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x15, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, + 0x00, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS0 TEX0 COL4 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + vs_1_1 + def c0, 0, 1, 0, 0 + dcl_texcoord1 v0 + mov oPos, c0.xxxy + mov oD0, v0 + + // approximately 2 instruction slots used +*/ +static const uint8_t _al_vs_pos0_tex0_col4[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x16, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, + 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, + 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x80, + 0x00, 0x00, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x40, 0xa0, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00 +}; + +/* + POS0 TEX0 COL0 + + // + // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 + vs_1_1 + def c0, 0, 1, 0, 0 + mov oPos, c0.xxxy + mov oD0, c0.y + + // approximately 2 instruction slots used +*/ +static const uint8_t _al_vs_pos0_tex0_col0[] = { + 0x00, 0x02, 0xfe, 0xff, 0xfe, 0xff, 0x16, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x76, 0x73, 0x5f, 0x32, 0x5f, 0x30, 0x00, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, + 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, + 0x51, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xc0, + 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0x55, 0xa0, + 0xff, 0xff, 0x00, 0x00 +}; + diff --git a/allegro/addons/primitives/prim_directx.cpp b/allegro/addons/primitives/prim_directx.cpp new file mode 100644 index 00000000..3411e333 --- /dev/null +++ b/allegro/addons/primitives/prim_directx.cpp @@ -0,0 +1,1195 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * DirectX implementation of some of the primitive routines. + * + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_prim_directx.h" +#include "allegro5/internal/aintern_prim_soft.h" +#include "allegro5/internal/aintern_prim.h" +#include "allegro5/internal/aintern_display.h" + +#include "allegro5/platform/alplatf.h" + +#ifdef ALLEGRO_CFG_D3D + +#include "allegro5/allegro_direct3d.h" +#include "allegro5/internal/aintern_direct3d.h" + +ALLEGRO_DEBUG_CHANNEL("d3d_primitives") + +static ALLEGRO_MUTEX *d3d_mutex; +/* + * In the context of this file, legacy cards pretty much refer to older Intel cards. + * They are distinguished by three misfeatures: + * 1. They don't support shaders + * 2. They don't support custom vertices + * 3. DrawIndexedPrimitiveUP is broken + * + * Since shaders are used 100% of the time, this means that for these cards + * the incoming vertices are first converted into the vertex type that these cards + * can handle. + */ +static bool legacy_card = false; +static bool know_card_type = false; + +static bool is_legacy_card(void) +{ + if (!know_card_type) { + ALLEGRO_CONFIG* sys_cfg = al_get_system_config(); + const char* detection_setting = al_get_config_value(sys_cfg, "graphics", "prim_d3d_legacy_detection"); + detection_setting = detection_setting ? detection_setting : "default"; + if (strcmp(detection_setting, "default") == 0) { + D3DCAPS9 caps; + LPDIRECT3DDEVICE9 device = al_get_d3d_device(al_get_current_display()); + device->GetDeviceCaps(&caps); + if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0)) + legacy_card = true; + } else if(strcmp(detection_setting, "force_legacy") == 0) { + legacy_card = true; + } else if(strcmp(detection_setting, "force_modern") == 0) { + legacy_card = false; + } else { + ALLEGRO_WARN("Invalid setting for prim_d3d_legacy_detection.\n"); + legacy_card = false; + } + if (legacy_card) { + ALLEGRO_WARN("Your GPU is considered legacy! Some of the features of the primitives addon will be slower/disabled.\n"); + } + know_card_type = true; + } + return legacy_card; +} + +typedef struct LEGACY_VERTEX +{ + float x, y, z; + DWORD color; + float u, v; +} LEGACY_VERTEX; + +static uint8_t* legacy_buffer; +static size_t legacy_buffer_size = 0; +#define A5V_FVF (D3DFVF_XYZ | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE4(1)) +#define A5V_LEGACY_FVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) + +typedef struct DISPLAY_LOCAL_DATA +{ + LPDIRECT3DDEVICE9 device; + LPDIRECT3DVERTEXSHADER9 shader; + ALLEGRO_INDEX_BUFFER* loop_index_buffer; +} DISPLAY_LOCAL_DATA; + +static DISPLAY_LOCAL_DATA* display_local_data; +static int display_local_data_size = 0; + +static void display_invalidated(ALLEGRO_DISPLAY* display) +{ + int ii; + LPDIRECT3DDEVICE9 device = al_get_d3d_device(display); + /* + * If there is no mutex, the addon has been shutdown earlier + */ + if(!d3d_mutex) + return; + + al_lock_mutex(d3d_mutex); + + for(ii = 0; ii < display_local_data_size; ii++) + { + if(display_local_data[ii].device == device) { + display_local_data[ii].shader->Release(); + display_local_data[ii] = display_local_data[display_local_data_size - 1]; + display_local_data_size--; + break; + } + } + + al_unlock_mutex(d3d_mutex); +} + +static DISPLAY_LOCAL_DATA get_display_local_data(ALLEGRO_DISPLAY* display) +{ + LPDIRECT3DDEVICE9 device = al_get_d3d_device(display); + DISPLAY_LOCAL_DATA ret; + bool create_new = false; + + /* + * Lock the mutex so that the entries are not messed up by a + * display blowing up/being created + */ + al_lock_mutex(d3d_mutex); + + if (display_local_data_size == 0) { + display_local_data = (DISPLAY_LOCAL_DATA*)al_malloc(sizeof(DISPLAY_LOCAL_DATA)); + display_local_data_size = 1; + create_new = true; + } + else if (display_local_data[0].device != device) { + int ii; + bool found = false; + for(ii = 1; ii < display_local_data_size; ii++) + { + if(display_local_data[ii].device == device) { + /* + * Move this entry to the front, so the search goes faster + * next time - presumably the al_draw_prim will be called + * several times for each display before switching again + */ + DISPLAY_LOCAL_DATA t = display_local_data[0]; + display_local_data[0] = display_local_data[ii]; + display_local_data[ii] = t; + + found = true; + + break; + } + } + + if (!found) { + DISPLAY_LOCAL_DATA t = display_local_data[0]; + + display_local_data_size++; + display_local_data = (DISPLAY_LOCAL_DATA *)al_realloc(display_local_data, sizeof(DISPLAY_LOCAL_DATA) * display_local_data_size); + + display_local_data[display_local_data_size - 1] = t; + create_new = true; + } + } + + if (create_new) { + int initial_indices[2] = {0, 0}; + display_local_data[0].device = device; + display_local_data[0].shader = (LPDIRECT3DVERTEXSHADER9)_al_create_default_primitives_shader(device); + display_local_data[0].loop_index_buffer = al_create_index_buffer(sizeof(int), initial_indices, 2, 0); + + _al_add_display_invalidated_callback(display, &display_invalidated); + } + + ret = display_local_data[0]; + + al_unlock_mutex(d3d_mutex); + + return ret; +} + +static void destroy_display_local_data(void) +{ + int ii; + for(ii = 0; ii < display_local_data_size; ii++) + { + display_local_data[ii].shader->Release(); + al_destroy_index_buffer(display_local_data[ii].loop_index_buffer); + } + display_local_data_size = 0; + al_free(display_local_data); + display_local_data = NULL; +} + +#endif + +bool _al_init_d3d_driver(void) +{ + #ifdef ALLEGRO_CFG_D3D + d3d_mutex = al_create_mutex(); + #endif + return true; +} + +void _al_shutdown_d3d_driver(void) +{ + #ifdef ALLEGRO_CFG_D3D + al_destroy_mutex(d3d_mutex); + al_free(legacy_buffer); + d3d_mutex = NULL; + legacy_buffer = NULL; + + destroy_display_local_data(); + + legacy_card = false; + know_card_type = false; + legacy_buffer_size = 0; + #endif +} + +#ifdef ALLEGRO_CFG_D3D + +static void* convert_to_legacy_vertices(const void* vtxs, int num_vertices, const int* indices, bool loop, bool pp) +{ + const ALLEGRO_VERTEX* vtx = (const ALLEGRO_VERTEX *)vtxs; + int ii; + int num_needed_vertices = num_vertices; + size_t needed_size; + + if (pp && !indices && !loop) { + return (void *)vtxs; + } + + if(loop) + num_needed_vertices++; + + needed_size = num_needed_vertices * (pp ? sizeof(ALLEGRO_VERTEX) : sizeof(LEGACY_VERTEX)); + + if(legacy_buffer == 0) { + legacy_buffer = (uint8_t *)al_malloc(needed_size); + legacy_buffer_size = needed_size; + } else if (needed_size > legacy_buffer_size) { + size_t new_size = needed_size * 1.5; + legacy_buffer = (uint8_t *)al_realloc(legacy_buffer, new_size); + legacy_buffer_size = new_size; + } + + if (pp) { + ALLEGRO_VERTEX *buffer = (ALLEGRO_VERTEX *)legacy_buffer; + for(ii = 0; ii < num_vertices; ii++) { + if(indices) + buffer[ii] = vtx[indices[ii]]; + else + buffer[ii] = vtx[ii]; + } + if(loop) + buffer[num_vertices] = buffer[0]; + } + else { + LEGACY_VERTEX *buffer = (LEGACY_VERTEX *)legacy_buffer; + for(ii = 0; ii < num_vertices; ii++) { + ALLEGRO_VERTEX vertex; + + if(indices) + vertex = vtx[indices[ii]]; + else + vertex = vtx[ii]; + + buffer[ii].x = vertex.x; + buffer[ii].y = vertex.y; + buffer[ii].z = vertex.z; + + buffer[ii].u = vertex.u; + buffer[ii].v = vertex.v; + + buffer[ii].color = D3DCOLOR_COLORVALUE(vertex.color.r, vertex.color.g, vertex.color.b, vertex.color.a); + } + if(loop) + buffer[num_vertices] = buffer[0]; + } + + return legacy_buffer; +} + +struct D3D_STATE +{ + DWORD old_wrap_state[2]; + DWORD old_ttf_state; + IDirect3DVertexShader9* old_vtx_shader; +}; + +static D3D_STATE setup_state(LPDIRECT3DDEVICE9 device, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, DISPLAY_LOCAL_DATA data) +{ + D3D_STATE state; + ALLEGRO_DISPLAY *disp = _al_get_bitmap_display(target); + ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)disp; + + if (!(disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { + IDirect3DPixelShader9* old_pix_shader; + device->GetVertexShader(&state.old_vtx_shader); + device->GetPixelShader(&old_pix_shader); + + if(!old_pix_shader) { + _al_d3d_set_blender(d3d_disp); + } + + if(!state.old_vtx_shader) { + /* Prepare the default shader */ + if(!is_legacy_card()) { + if(decl) + _al_setup_primitives_shader(device, decl); + else + _al_setup_default_primitives_shader(device, data.shader); + } + } + } + else { + state.old_vtx_shader = NULL; + _al_d3d_set_blender(d3d_disp); + } + + /* Set the vertex declarations */ + if(is_legacy_card() && !(disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { + device->SetFVF(A5V_LEGACY_FVF); + } else { + if(decl) { + device->SetVertexDeclaration((IDirect3DVertexDeclaration9*)decl->d3d_decl); + } else { + device->SetFVF(A5V_FVF); + } + } + + if(!state.old_vtx_shader || (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { + /* Set up the texture */ + if (texture) { + LPDIRECT3DTEXTURE9 d3d_texture; + int tex_x, tex_y; + D3DSURFACE_DESC desc; + float mat[4][4] = { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1} + }; + + d3d_texture = al_get_d3d_video_texture(texture); + + d3d_texture->GetLevelDesc(0, &desc); + al_get_d3d_texture_position(texture, &tex_x, &tex_y); + + if(decl) { + if(decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL].attribute) { + mat[0][0] = 1.0f / desc.Width; + mat[1][1] = 1.0f / desc.Height; + } else { + mat[0][0] = (float)al_get_bitmap_width(texture) / desc.Width; + mat[1][1] = (float)al_get_bitmap_height(texture) / desc.Height; + } + } else { + mat[0][0] = 1.0f / desc.Width; + mat[1][1] = 1.0f / desc.Height; + } + mat[2][0] = (float)tex_x / desc.Width; + mat[2][1] = (float)tex_y / desc.Height; + + + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_SHADER_HLSL + d3d_disp->effect->SetMatrix(ALLEGRO_SHADER_VAR_TEX_MATRIX, (D3DXMATRIX *)mat); + d3d_disp->effect->SetBool(ALLEGRO_SHADER_VAR_USE_TEX_MATRIX, true); + d3d_disp->effect->SetBool(ALLEGRO_SHADER_VAR_USE_TEX, true); + d3d_disp->effect->SetTexture(ALLEGRO_SHADER_VAR_TEX, d3d_texture); +#endif + } + else { + if(is_legacy_card()) { + device->GetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, &state.old_ttf_state); + device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + device->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *)&mat); + } else { + _al_set_texture_matrix(device, mat[0]); + } + } + + device->SetTexture(0, d3d_texture); + + } else { + /* Don't unbind the texture here if shaders are used, since the user may + * have set the 0'th texture unit manually via the shader API. */ + if (!(disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { + device->SetTexture(0, NULL); + } + } + } + + device->GetSamplerState(0, D3DSAMP_ADDRESSU, &state.old_wrap_state[0]); + device->GetSamplerState(0, D3DSAMP_ADDRESSV, &state.old_wrap_state[1]); + + device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); + device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); + + if (texture) { + int texture_flags = al_get_bitmap_flags(texture); + if (texture_flags & ALLEGRO_MIN_LINEAR) { + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + } + else { + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + } + if (texture_flags & ALLEGRO_MAG_LINEAR) { + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + } + else { + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + } + if (texture_flags & ALLEGRO_MIPMAP) { + device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + } + else { + device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + } + } + + return state; +} + +static void revert_state(D3D_STATE state, LPDIRECT3DDEVICE9 device, ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture) +{ + ALLEGRO_DISPLAY *disp = _al_get_bitmap_display(target); + ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)disp; + (void)d3d_disp; +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->End(); + d3d_disp->effect->SetBool(ALLEGRO_SHADER_VAR_USE_TEX_MATRIX, false); + d3d_disp->effect->SetBool(ALLEGRO_SHADER_VAR_USE_TEX, false); + } +#endif + + device->SetSamplerState(0, D3DSAMP_ADDRESSU, state.old_wrap_state[0]); + device->SetSamplerState(0, D3DSAMP_ADDRESSV, state.old_wrap_state[1]); + + if(!state.old_vtx_shader && is_legacy_card() && texture) { + device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, state.old_ttf_state); + } + + if (!(disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { + if(!state.old_vtx_shader) + device->SetVertexShader(0); + } +} + +static int draw_prim_raw(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, + const void* vtx, const ALLEGRO_VERTEX_DECL* decl, + const int* indices, int num_vtx, int type) +{ + int stride; + int num_primitives = 0; + LPDIRECT3DDEVICE9 device; + int min_idx = 0, max_idx = num_vtx - 1; + ALLEGRO_DISPLAY *disp = _al_get_bitmap_display(target); + ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)disp; + UINT required_passes = 1; + unsigned int i; + D3D_STATE state; + DISPLAY_LOCAL_DATA data; + (void)d3d_disp; + + if (al_is_d3d_device_lost(disp)) { + return 0; + } + + if (is_legacy_card() && !(disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { + stride = (int)sizeof(LEGACY_VERTEX); + } + else { + stride = (decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX)); + } + + /* Check for early exit */ + if((is_legacy_card() && decl) || (decl && decl->d3d_decl == 0)) { + if(!indices) + return _al_draw_prim_soft(texture, vtx, decl, 0, num_vtx, type); + else + return _al_draw_prim_indexed_soft(texture, vtx, decl, indices, num_vtx, type); + } + + int num_idx = num_vtx; + if(indices) + { + int ii; + for(ii = 0; ii < num_vtx; ii++) + { + int idx = indices[ii]; + if(ii == 0) { + min_idx = idx; + max_idx = idx; + } else if (idx < min_idx) { + min_idx = idx; + } else if (idx > max_idx) { + max_idx = idx; + } + } + num_idx = max_idx + 1 - min_idx; + } + + device = al_get_d3d_device(disp); + + data = get_display_local_data(disp); + + state = setup_state(device, decl, target, texture, data); + + /* Convert vertices for legacy cards */ + if(is_legacy_card()) { + al_lock_mutex(d3d_mutex); + vtx = convert_to_legacy_vertices(vtx, num_vtx, indices, type == ALLEGRO_PRIM_LINE_LOOP, + disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE); + } + +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->Begin(&required_passes, 0); + } +#endif + + for (i = 0; i < required_passes; i++) { +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->BeginPass(i); + } +#endif + + if (!indices || is_legacy_card()) + { + switch (type) { + case ALLEGRO_PRIM_LINE_LIST: { + num_primitives = num_vtx / 2; + device->DrawPrimitiveUP(D3DPT_LINELIST, num_primitives, vtx, stride); + break; + }; + case ALLEGRO_PRIM_LINE_STRIP: { + num_primitives = num_vtx - 1; + device->DrawPrimitiveUP(D3DPT_LINESTRIP, num_primitives, vtx, stride); + break; + }; + case ALLEGRO_PRIM_LINE_LOOP: { + num_primitives = num_vtx - 1; + device->DrawPrimitiveUP(D3DPT_LINESTRIP, num_primitives, vtx, stride); + if(!is_legacy_card()) { + int in[2]; + in[0] = 0; + in[1] = num_vtx-1; + + device->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, num_vtx, 1, in, D3DFMT_INDEX32, vtx, stride); + } else { + device->DrawPrimitiveUP(D3DPT_LINELIST, 1, (char*)vtx + stride * (num_vtx - 1), stride); + } + break; + }; + case ALLEGRO_PRIM_TRIANGLE_LIST: { + num_primitives = num_vtx / 3; + device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, num_primitives, vtx, stride); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_STRIP: { + num_primitives = num_vtx - 2; + device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, num_primitives, vtx, stride); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_FAN: { + num_primitives = num_vtx - 2; + device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, num_primitives, vtx, stride); + break; + }; + case ALLEGRO_PRIM_POINT_LIST: { + num_primitives = num_vtx; + device->DrawPrimitiveUP(D3DPT_POINTLIST, num_primitives, vtx, stride); + break; + }; + } + } else { + switch (type) { + case ALLEGRO_PRIM_LINE_LIST: { + num_primitives = num_vtx / 2; + device->DrawIndexedPrimitiveUP(D3DPT_LINELIST, min_idx, num_idx, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); + break; + }; + case ALLEGRO_PRIM_LINE_STRIP: { + num_primitives = num_vtx - 1; + device->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, min_idx, num_idx, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); + break; + }; + case ALLEGRO_PRIM_LINE_LOOP: { + int in[2]; + num_primitives = num_vtx - 1; + device->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, min_idx, num_idx, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); + + in[0] = indices[0]; + in[1] = indices[num_vtx-1]; + min_idx = in[0] > in[1] ? in[1] : in[0]; + max_idx = in[0] > in[1] ? in[0] : in[1]; + num_idx = max_idx - min_idx + 1; + device->DrawIndexedPrimitiveUP(D3DPT_LINELIST, min_idx, num_idx, 1, in, D3DFMT_INDEX32, vtx, stride); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_LIST: { + num_primitives = num_vtx / 3; + device->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, min_idx, num_idx, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_STRIP: { + num_primitives = num_vtx - 2; + device->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, min_idx, num_idx, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_FAN: { + num_primitives = num_vtx - 2; + device->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, min_idx, num_idx, num_primitives, indices, D3DFMT_INDEX32, vtx, stride); + break; + }; + case ALLEGRO_PRIM_POINT_LIST: { + /* + * D3D does not support point lists in indexed mode, so we draw them using the non-indexed mode. To gain at least a semblance + * of speed, we detect consecutive runs of vertices and draw them using a single DrawPrimitiveUP call + */ + int ii = 0; + int start_idx = indices[0]; + int run_length = 0; + for(ii = 0; ii < num_vtx; ii++) + { + run_length++; + if(indices[ii] + 1 != indices[ii + 1] || ii == num_vtx - 1) { + device->DrawPrimitiveUP(D3DPT_POINTLIST, run_length, (const char*)vtx + start_idx * stride, stride); + if(ii != num_vtx - 1) + start_idx = indices[ii + 1]; + run_length = 0; + } + } + break; + }; + } + } + +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->EndPass(); + } +#endif + } + + if(is_legacy_card()) + al_unlock_mutex(d3d_mutex); + + revert_state(state, device, target, texture); + + return num_primitives; +} + +#endif + +int _al_draw_prim_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type) +{ +#ifdef ALLEGRO_CFG_D3D + int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX); + return draw_prim_raw(target, texture, (const char*)vtxs + start * stride, decl, 0, end - start, type); +#else + (void)target; + (void)texture; + (void)vtxs; + (void)start; + (void)end; + (void)type; + (void)decl; + + return 0; +#endif +} + +int _al_draw_prim_indexed_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type) +{ +#ifdef ALLEGRO_CFG_D3D + return draw_prim_raw(target, texture, vtxs, decl, indices, num_vtx, type); +#else + (void)target; + (void)texture; + (void)vtxs; + (void)indices; + (void)num_vtx; + (void)type; + (void)decl; + + return 0; +#endif +} + +#ifdef ALLEGRO_CFG_D3D +static int draw_buffer_raw(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type) +{ + int num_primitives = 0; + int num_vtx = end - start; + LPDIRECT3DDEVICE9 device; + ALLEGRO_DISPLAY *disp = _al_get_bitmap_display(target); + ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)disp; + UINT required_passes = 1; + unsigned int i; + D3D_STATE state; + DISPLAY_LOCAL_DATA data; + (void)d3d_disp; + + if (al_is_d3d_device_lost(disp)) { + return 0; + } + + /* Check for early exit for legacy cards */ + if (vertex_buffer->decl && vertex_buffer->decl->d3d_decl == 0) { + return _al_draw_buffer_common_soft(vertex_buffer, texture, index_buffer, start, end, type); + } + + device = al_get_d3d_device(disp); + + data = get_display_local_data(disp); + + state = setup_state(device, vertex_buffer->decl, target, texture, data); + + device->SetStreamSource(0, (IDirect3DVertexBuffer9*)vertex_buffer->common.handle, 0, vertex_buffer->decl ? vertex_buffer->decl->stride : (int)sizeof(ALLEGRO_VERTEX)); + + if (index_buffer) { + device->SetIndices((IDirect3DIndexBuffer9*)index_buffer->common.handle); + } + +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->Begin(&required_passes, 0); + } +#endif + + for (i = 0; i < required_passes; i++) { +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->BeginPass(i); + } +#endif + + if (!index_buffer) { + switch (type) { + case ALLEGRO_PRIM_LINE_LIST: { + num_primitives = num_vtx / 2; + device->DrawPrimitive(D3DPT_LINELIST, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_LINE_STRIP: { + num_primitives = num_vtx - 1; + device->DrawPrimitive(D3DPT_LINESTRIP, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_LINE_LOOP: { + int* indices; + num_primitives = num_vtx - 1; + device->DrawPrimitive(D3DPT_LINESTRIP, start, num_primitives); + + if (data.loop_index_buffer) { + al_lock_mutex(d3d_mutex); + indices = (int*)al_lock_index_buffer(data.loop_index_buffer, 0, 2, ALLEGRO_LOCK_WRITEONLY); + ASSERT(indices); + indices[0] = start; + indices[1] = start + num_vtx - 1; + al_unlock_index_buffer(data.loop_index_buffer); + device->SetIndices((IDirect3DIndexBuffer9*)data.loop_index_buffer->common.handle); + device->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 0, al_get_vertex_buffer_size(vertex_buffer), 0, 1); + al_unlock_mutex(d3d_mutex); + } + break; + }; + case ALLEGRO_PRIM_TRIANGLE_LIST: { + num_primitives = num_vtx / 3; + device->DrawPrimitive(D3DPT_TRIANGLELIST, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_STRIP: { + num_primitives = num_vtx - 2; + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_FAN: { + num_primitives = num_vtx - 2; + device->DrawPrimitive(D3DPT_TRIANGLEFAN, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_POINT_LIST: { + num_primitives = num_vtx; + device->DrawPrimitive(D3DPT_POINTLIST, start, num_primitives); + break; + }; + } + } + else { + int vbuff_size = al_get_vertex_buffer_size(vertex_buffer); + switch (type) { + case ALLEGRO_PRIM_LINE_LIST: { + num_primitives = num_vtx / 2; + device->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vbuff_size, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_LINE_STRIP: { + num_primitives = num_vtx - 1; + device->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 0, vbuff_size, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_LINE_LOOP: { + /* Unimplemented, too hard to do in a consistent fashion. */ + break; + }; + case ALLEGRO_PRIM_TRIANGLE_LIST: { + num_primitives = num_vtx / 3; + device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vbuff_size, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_STRIP: { + num_primitives = num_vtx - 2; + device->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, vbuff_size, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_TRIANGLE_FAN: { + num_primitives = num_vtx - 2; + device->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0, 0, vbuff_size, start, num_primitives); + break; + }; + case ALLEGRO_PRIM_POINT_LIST: { + /* Unimplemented, too hard to do in a consistent fashion. */ + break; + }; + } + } + +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->EndPass(); + } +#endif + } + + if (is_legacy_card()) + al_unlock_mutex(d3d_mutex); + + revert_state(state, device, target, texture); + + return num_primitives; +} +#endif + +int _al_draw_vertex_buffer_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, int start, int end, int type) +{ +#ifdef ALLEGRO_CFG_D3D + return draw_buffer_raw(target, texture, vertex_buffer, NULL, start, end, type); +#else + (void)target; + (void)texture; + (void)vertex_buffer; + (void)start; + (void)end; + (void)type; + + return 0; +#endif +} + +int _al_draw_indexed_buffer_directx(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type) +{ +#ifdef ALLEGRO_CFG_D3D + return draw_buffer_raw(target, texture, vertex_buffer, index_buffer, start, end, type); +#else + (void)target; + (void)texture; + (void)vertex_buffer; + (void)index_buffer; + (void)start; + (void)end; + (void)type; + + return 0; +#endif +} + +#ifdef ALLEGRO_CFG_D3D +static int convert_storage(int storage) +{ + switch(storage) { + case ALLEGRO_PRIM_FLOAT_2: + return D3DDECLTYPE_FLOAT2; + break; + case ALLEGRO_PRIM_FLOAT_3: + return D3DDECLTYPE_FLOAT3; + break; + case ALLEGRO_PRIM_SHORT_2: + return D3DDECLTYPE_SHORT2; + break; + case ALLEGRO_PRIM_FLOAT_1: + return D3DDECLTYPE_FLOAT1; + break; + case ALLEGRO_PRIM_FLOAT_4: + return D3DDECLTYPE_FLOAT4; + break; + case ALLEGRO_PRIM_UBYTE_4: + return D3DDECLTYPE_UBYTE4; + break; + case ALLEGRO_PRIM_SHORT_4: + return D3DDECLTYPE_SHORT4; + break; + case ALLEGRO_PRIM_NORMALIZED_UBYTE_4: + return D3DDECLTYPE_UBYTE4N; + break; + case ALLEGRO_PRIM_NORMALIZED_SHORT_2: + return D3DDECLTYPE_SHORT2N; + break; + case ALLEGRO_PRIM_NORMALIZED_SHORT_4: + return D3DDECLTYPE_SHORT4N; + break; + case ALLEGRO_PRIM_NORMALIZED_USHORT_2: + return D3DDECLTYPE_USHORT2N; + break; + case ALLEGRO_PRIM_NORMALIZED_USHORT_4: + return D3DDECLTYPE_USHORT4N; + break; + case ALLEGRO_PRIM_HALF_FLOAT_2: + return D3DDECLTYPE_FLOAT16_2; + break; + case ALLEGRO_PRIM_HALF_FLOAT_4: + return D3DDECLTYPE_FLOAT16_4; + break; + default: + ASSERT(0); + return D3DDECLTYPE_UNUSED; + } +} +#endif + +void _al_set_d3d_decl(ALLEGRO_DISPLAY* display, ALLEGRO_VERTEX_DECL* ret) +{ +#ifdef ALLEGRO_CFG_D3D + { + LPDIRECT3DDEVICE9 device; + D3DVERTEXELEMENT9 d3delements[ALLEGRO_PRIM_ATTR_NUM + 1]; + int idx = 0; + ALLEGRO_VERTEX_ELEMENT* e; + D3DCAPS9 caps; + + device = al_get_d3d_device(display); + + device->GetDeviceCaps(&caps); + if(caps.PixelShaderVersion < D3DPS_VERSION(3, 0)) { + ret->d3d_decl = 0; + } else { + int i; + e = &ret->elements[ALLEGRO_PRIM_POSITION]; + if(e->attribute) { + d3delements[idx].Stream = 0; + d3delements[idx].Offset = e->offset; + d3delements[idx].Type = convert_storage(e->storage); + d3delements[idx].Method = D3DDECLMETHOD_DEFAULT; + d3delements[idx].Usage = D3DDECLUSAGE_POSITION; + d3delements[idx].UsageIndex = 0; + idx++; + } + + e = &ret->elements[ALLEGRO_PRIM_TEX_COORD]; + if(!e->attribute) + e = &ret->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; + if(e->attribute) { + d3delements[idx].Stream = 0; + d3delements[idx].Offset = e->offset; + d3delements[idx].Type = convert_storage(e->storage); + d3delements[idx].Method = D3DDECLMETHOD_DEFAULT; + d3delements[idx].Usage = D3DDECLUSAGE_TEXCOORD; + d3delements[idx].UsageIndex = 0; + idx++; + } + + e = &ret->elements[ALLEGRO_PRIM_COLOR_ATTR]; + if(e->attribute) { + d3delements[idx].Stream = 0; + d3delements[idx].Offset = e->offset; + d3delements[idx].Type = D3DDECLTYPE_FLOAT4; + d3delements[idx].Method = D3DDECLMETHOD_DEFAULT; + d3delements[idx].Usage = D3DDECLUSAGE_TEXCOORD; + d3delements[idx].UsageIndex = 1; + idx++; + } + + for (i = 0; i < _ALLEGRO_PRIM_MAX_USER_ATTR; i++) { + e = &ret->elements[ALLEGRO_PRIM_USER_ATTR + i]; + if (e->attribute) { + d3delements[idx].Stream = 0; + d3delements[idx].Offset = e->offset; + d3delements[idx].Type = convert_storage(e->storage); + d3delements[idx].Method = D3DDECLMETHOD_DEFAULT; + d3delements[idx].Usage = D3DDECLUSAGE_TEXCOORD; + d3delements[idx].UsageIndex = 2 + i; + idx++; + } + } + + d3delements[idx].Stream = 0xFF; + d3delements[idx].Offset = 0; + d3delements[idx].Type = D3DDECLTYPE_UNUSED; + d3delements[idx].Method = 0; + d3delements[idx].Usage = 0; + d3delements[idx].UsageIndex = 0; + + device->CreateVertexDeclaration(d3delements, (IDirect3DVertexDeclaration9**)&ret->d3d_decl); + } + + _al_create_primitives_shader(device, ret); + } +#else + (void)display; + ret->d3d_decl = 0; +#endif +} + +bool _al_create_vertex_buffer_directx(ALLEGRO_VERTEX_BUFFER* buf, const void* initial_data, size_t num_vertices, int flags) +{ +#ifdef ALLEGRO_CFG_D3D + LPDIRECT3DDEVICE9 device; + IDirect3DVertexBuffer9* d3d_vbuff; + DWORD fvf = A5V_FVF; + int stride = buf->decl ? buf->decl->stride : (int)sizeof(ALLEGRO_VERTEX); + HRESULT res; + void* locked_memory; + + /* There's just no point */ + if (is_legacy_card()) { + ALLEGRO_WARN("Cannot create vertex buffer for a legacy card.\n"); + return false; + } + + device = al_get_d3d_device(al_get_current_display()); + + if (buf->decl) { + device->SetVertexDeclaration((IDirect3DVertexDeclaration9*)buf->decl->d3d_decl); + fvf = 0; + } + + res = device->CreateVertexBuffer(stride * num_vertices, !(flags & ALLEGRO_PRIM_BUFFER_READWRITE) ? D3DUSAGE_WRITEONLY : 0, + fvf, D3DPOOL_MANAGED, &d3d_vbuff, 0); + if (res != D3D_OK) { + ALLEGRO_WARN("CreateVertexBuffer failed: %ld.\n", res); + return false; + } + + if (initial_data != NULL) { + d3d_vbuff->Lock(0, 0, &locked_memory, 0); + memcpy(locked_memory, initial_data, stride * num_vertices); + d3d_vbuff->Unlock(); + } + + buf->common.handle = (uintptr_t)d3d_vbuff; + + return true; +#else + (void)buf; + (void)initial_data; + (void)num_vertices; + (void)flags; + + return false; +#endif +} + +bool _al_create_index_buffer_directx(ALLEGRO_INDEX_BUFFER* buf, const void* initial_data, size_t num_indices, int flags) +{ +#ifdef ALLEGRO_CFG_D3D + LPDIRECT3DDEVICE9 device; + IDirect3DIndexBuffer9* d3d_ibuff; + HRESULT res; + void* locked_memory; + + /* There's just no point */ + if (is_legacy_card()) { + ALLEGRO_WARN("Cannot create index buffer for a legacy card.\n"); + return false; + } + + device = al_get_d3d_device(al_get_current_display()); + + res = device->CreateIndexBuffer(num_indices * buf->index_size, !(flags & ALLEGRO_PRIM_BUFFER_READWRITE) ? D3DUSAGE_WRITEONLY : 0, + buf->index_size == 4 ? D3DFMT_INDEX32 : D3DFMT_INDEX16, D3DPOOL_MANAGED, &d3d_ibuff, 0); + if (res != D3D_OK) { + ALLEGRO_WARN("CreateIndexBuffer failed: %ld.\n", res); + return false; + } + + if (initial_data != NULL) { + d3d_ibuff->Lock(0, 0, &locked_memory, 0); + memcpy(locked_memory, initial_data, num_indices * buf->index_size); + d3d_ibuff->Unlock(); + } + + buf->common.handle = (uintptr_t)d3d_ibuff; + + return true; +#else + (void)buf; + (void)initial_data; + (void)num_indices; + (void)flags; + + return false; +#endif +} + +void _al_destroy_vertex_buffer_directx(ALLEGRO_VERTEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_D3D + ((IDirect3DVertexBuffer9*)buf->common.handle)->Release(); +#else + (void)buf; +#endif +} + +void _al_destroy_index_buffer_directx(ALLEGRO_INDEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_D3D + ((IDirect3DIndexBuffer9*)buf->common.handle)->Release(); +#else + (void)buf; +#endif +} + +void* _al_lock_vertex_buffer_directx(ALLEGRO_VERTEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_D3D + DWORD flags = buf->common.lock_flags == ALLEGRO_LOCK_READONLY ? D3DLOCK_READONLY : 0; + HRESULT res; + + res = ((IDirect3DVertexBuffer9*)buf->common.handle)->Lock((UINT)buf->common.lock_offset, (UINT)buf->common.lock_length, &buf->common.locked_memory, flags); + if (res != D3D_OK) { + ALLEGRO_WARN("Locking vertex buffer failed: %ld.\n", res); + return 0; + } + + return buf->common.locked_memory; +#else + (void)buf; + + return 0; +#endif +} + +void* _al_lock_index_buffer_directx(ALLEGRO_INDEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_D3D + DWORD flags = buf->common.lock_flags == ALLEGRO_LOCK_READONLY ? D3DLOCK_READONLY : 0; + HRESULT res; + + res = ((IDirect3DIndexBuffer9*)buf->common.handle)->Lock((UINT)buf->common.lock_offset, (UINT)buf->common.lock_length, &buf->common.locked_memory, flags); + + if (res != D3D_OK) { + ALLEGRO_WARN("Locking index buffer failed: %ld.\n", res); + return 0; + } + + return buf->common.locked_memory; +#else + (void)buf; + + return 0; +#endif +} + +void _al_unlock_vertex_buffer_directx(ALLEGRO_VERTEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_D3D + ((IDirect3DVertexBuffer9*)buf->common.handle)->Unlock(); +#else + (void)buf; +#endif +} + +void _al_unlock_index_buffer_directx(ALLEGRO_INDEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_D3D + ((IDirect3DIndexBuffer9*)buf->common.handle)->Unlock(); +#else + (void)buf; +#endif +} diff --git a/allegro/addons/primitives/prim_opengl.c b/allegro/addons/primitives/prim_opengl.c new file mode 100644 index 00000000..e135b47d --- /dev/null +++ b/allegro/addons/primitives/prim_opengl.c @@ -0,0 +1,811 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL implementation of some of the primitive routines. + * + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + +#define ALLEGRO_INTERNAL_UNSTABLE + +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_prim_opengl.h" +#include "allegro5/internal/aintern_prim_soft.h" +#include "allegro5/platform/alplatf.h" +#include "allegro5/internal/aintern_prim.h" + +#ifdef ALLEGRO_CFG_OPENGL + +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_opengl.h" + +static void convert_storage(ALLEGRO_PRIM_STORAGE storage, GLenum* type, int* ncoord, bool* normalized) +{ + switch(storage) { + case ALLEGRO_PRIM_FLOAT_2: + *type = GL_FLOAT; + *ncoord = 2; + *normalized = false; + break; + case ALLEGRO_PRIM_FLOAT_3: + *type = GL_FLOAT; + *ncoord = 3; + *normalized = false; + break; + case ALLEGRO_PRIM_SHORT_2: + *type = GL_SHORT; + *ncoord = 2; + *normalized = false; + break; + case ALLEGRO_PRIM_FLOAT_1: + *type = GL_FLOAT; + *ncoord = 1; + *normalized = false; + break; + case ALLEGRO_PRIM_FLOAT_4: + *type = GL_FLOAT; + *ncoord = 4; + *normalized = false; + break; + case ALLEGRO_PRIM_UBYTE_4: + *type = GL_UNSIGNED_BYTE; + *ncoord = 4; + *normalized = false; + break; + case ALLEGRO_PRIM_SHORT_4: + *type = GL_SHORT; + *ncoord = 4; + *normalized = false; + break; + case ALLEGRO_PRIM_NORMALIZED_UBYTE_4: + *type = GL_UNSIGNED_BYTE; + *ncoord = 4; + *normalized = true; + break; + case ALLEGRO_PRIM_NORMALIZED_SHORT_2: + *type = GL_SHORT; + *ncoord = 2; + *normalized = true; + break; + case ALLEGRO_PRIM_NORMALIZED_SHORT_4: + *type = GL_SHORT; + *ncoord = 4; + *normalized = true; + break; + case ALLEGRO_PRIM_NORMALIZED_USHORT_2: + *type = GL_UNSIGNED_SHORT; + *ncoord = 2; + *normalized = true; + break; + case ALLEGRO_PRIM_NORMALIZED_USHORT_4: + *type = GL_UNSIGNED_SHORT; + *ncoord = 4; + *normalized = true; + break; +#ifndef ALLEGRO_CFG_OPENGLES + case ALLEGRO_PRIM_HALF_FLOAT_2: + *type = GL_HALF_FLOAT; + *ncoord = 2; + *normalized = false; + break; + case ALLEGRO_PRIM_HALF_FLOAT_4: + *type = GL_HALF_FLOAT; + *ncoord = 4; + *normalized = false; + break; +#endif + default: + ASSERT(0); + } +} + +static void setup_state(const char* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture) +{ + ALLEGRO_DISPLAY *display = al_get_current_display(); + GLenum type; + int ncoord; + bool normalized; + + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if(decl) { + ALLEGRO_VERTEX_ELEMENT* e; + int i; + + e = &decl->elements[ALLEGRO_PRIM_POSITION]; + if(e->attribute) { + convert_storage(e->storage, &type, &ncoord, &normalized); + + if (display->ogl_extras->varlocs.pos_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.pos_loc, ncoord, type, normalized, decl->stride, vtxs + e->offset); + glEnableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); + } + } else { + if (display->ogl_extras->varlocs.pos_loc >= 0) { + glDisableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); + } + } + + e = &decl->elements[ALLEGRO_PRIM_TEX_COORD]; + if(!e->attribute) + e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; + if(e->attribute) { + convert_storage(e->storage, &type, &ncoord, &normalized); + + if (display->ogl_extras->varlocs.texcoord_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.texcoord_loc, ncoord, type, normalized, decl->stride, vtxs + e->offset); + glEnableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); + } + } else { + if (display->ogl_extras->varlocs.texcoord_loc >= 0) { + glDisableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); + } + } + + e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR]; + if(e->attribute) { + if (display->ogl_extras->varlocs.color_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.color_loc, 4, GL_FLOAT, true, decl->stride, vtxs + e->offset); + glEnableVertexAttribArray(display->ogl_extras->varlocs.color_loc); + } + } else { + if (display->ogl_extras->varlocs.color_loc >= 0) { + glDisableVertexAttribArray(display->ogl_extras->varlocs.color_loc); + } + } + + for (i = 0; i < _ALLEGRO_PRIM_MAX_USER_ATTR; i++) { + e = &decl->elements[ALLEGRO_PRIM_USER_ATTR + i]; + if (e->attribute) { + convert_storage(e->storage, &type, &ncoord, &normalized); + + if (display->ogl_extras->varlocs.user_attr_loc[i] >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.user_attr_loc[i], ncoord, type, normalized, decl->stride, vtxs + e->offset); + glEnableVertexAttribArray(display->ogl_extras->varlocs.user_attr_loc[i]); + } + } else { + if (display->ogl_extras->varlocs.user_attr_loc[i] >= 0) { + glDisableVertexAttribArray(display->ogl_extras->varlocs.user_attr_loc[i]); + } + } + } + } else { + if (display->ogl_extras->varlocs.pos_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.pos_loc, 3, GL_FLOAT, false, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, x)); + glEnableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); + } + + if (display->ogl_extras->varlocs.texcoord_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.texcoord_loc, 2, GL_FLOAT, false, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, u)); + glEnableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); + } + + if (display->ogl_extras->varlocs.color_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.color_loc, 4, GL_FLOAT, true, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, color)); + glEnableVertexAttribArray(display->ogl_extras->varlocs.color_loc); + } + } +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + if(decl) { + ALLEGRO_VERTEX_ELEMENT* e; + e = &decl->elements[ALLEGRO_PRIM_POSITION]; + if(e->attribute) { + glEnableClientState(GL_VERTEX_ARRAY); + + convert_storage(e->storage, &type, &ncoord, &normalized); + + glVertexPointer(ncoord, type, decl->stride, vtxs + e->offset); + } else { + glDisableClientState(GL_VERTEX_ARRAY); + } + + e = &decl->elements[ALLEGRO_PRIM_TEX_COORD]; + if(!e->attribute) + e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; + if(texture && e->attribute) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + convert_storage(e->storage, &type, &ncoord, &normalized); + + glTexCoordPointer(ncoord, type, decl->stride, vtxs + e->offset); + } else { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR]; + if(e->attribute) { + glEnableClientState(GL_COLOR_ARRAY); + + glColorPointer(4, GL_FLOAT, decl->stride, vtxs + e->offset); + } else { + glDisableClientState(GL_COLOR_ARRAY); + glColor4f(1, 1, 1, 1); + } + } else { + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (!(display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) + glDisableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, x)); + glColorPointer(4, GL_FLOAT, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, color)); + glTexCoordPointer(2, GL_FLOAT, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, u)); + } +#endif + } + + if (texture) { + GLuint gl_texture = al_get_opengl_texture(texture); + int true_w, true_h; + int tex_x, tex_y; + float mat[4][4] = { + {1, 0, 0, 0}, + {0, -1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1} + }; + int height; + + if (texture->parent) + height = texture->parent->h; + else + height = texture->h; + + al_get_opengl_texture_size(texture, &true_w, &true_h); + al_get_opengl_texture_position(texture, &tex_x, &tex_y); + + mat[3][0] = (float)tex_x / true_w; + mat[3][1] = (float)(height - tex_y) / true_h; + + if(decl) { + if(decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL].attribute) { + mat[0][0] = 1.0f / true_w; + mat[1][1] = -1.0f / true_h; + } else { + mat[0][0] = (float)al_get_bitmap_width(texture) / true_w; + mat[1][1] = -(float)al_get_bitmap_height(texture) / true_h; + } + } else { + mat[0][0] = 1.0f / true_w; + mat[1][1] = -1.0f / true_h; + } + + if (!(display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { + glBindTexture(GL_TEXTURE_2D, gl_texture); + } + + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + GLint handle; + + handle = display->ogl_extras->varlocs.tex_matrix_loc; + if (handle >= 0) + glUniformMatrix4fv(handle, 1, false, (float *)mat); + + handle = display->ogl_extras->varlocs.use_tex_matrix_loc; + if (handle >= 0) + glUniform1i(handle, 1); + + if (display->ogl_extras->varlocs.use_tex_loc >= 0) { + glUniform1i(display->ogl_extras->varlocs.use_tex_loc, 1); + } + if (display->ogl_extras->varlocs.tex_loc >= 0) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, al_get_opengl_texture(texture)); + glUniform1i(display->ogl_extras->varlocs.tex_loc, 0); // 0th sampler + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glMatrixMode(GL_TEXTURE); + glLoadMatrixf(mat[0]); + glMatrixMode(GL_MODELVIEW); + + glEnable(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#endif + } + } else { + /* Don't unbind the texture here if shaders are used, since the user may + * have set the 0'th texture unit manually via the shader API. */ + if (!(display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { + glBindTexture(GL_TEXTURE_2D, 0); + } + } +} + +static void revert_state(ALLEGRO_BITMAP* texture) +{ + ALLEGRO_DISPLAY *display = al_get_current_display(); + + if(texture) { + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + float identity[16] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + GLint handle; + handle = display->ogl_extras->varlocs.tex_matrix_loc; + if (handle >= 0) + glUniformMatrix4fv(handle, 1, false, identity); + handle = display->ogl_extras->varlocs.use_tex_matrix_loc; + if (handle >= 0) + glUniform1i(handle, 0); + if (display->ogl_extras->varlocs.use_tex_loc >= 0) + glUniform1i(display->ogl_extras->varlocs.use_tex_loc, 0); +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glDisable(GL_TEXTURE_2D); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); +#endif + } + } + + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (display->ogl_extras->varlocs.pos_loc >= 0) + glDisableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); + if (display->ogl_extras->varlocs.color_loc >= 0) + glDisableVertexAttribArray(display->ogl_extras->varlocs.color_loc); + if (display->ogl_extras->varlocs.texcoord_loc >= 0) + glDisableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#endif + } +} + +static int draw_prim_raw(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, + ALLEGRO_VERTEX_BUFFER* vertex_buffer, + const void* vtx, const ALLEGRO_VERTEX_DECL* decl, + int start, int end, int type) +{ + int num_primitives = 0; + ALLEGRO_DISPLAY *disp = _al_get_bitmap_display(target); + ALLEGRO_BITMAP *opengl_target = target; + ALLEGRO_BITMAP_EXTRA_OPENGL *extra; + int num_vtx = end - start; + + if (target->parent) { + opengl_target = target->parent; + } + extra = opengl_target->extra; + + if ((!extra->is_backbuffer && disp->ogl_extras->opengl_target != + opengl_target) || al_is_bitmap_locked(target)) { + if (vertex_buffer) { + return _al_draw_buffer_common_soft(vertex_buffer, texture, NULL, start, end, type); + } + else { + return _al_draw_prim_soft(texture, vtx, decl, start, end, type); + } + } + + if (vertex_buffer) { + glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vertex_buffer->common.handle); + } + + _al_opengl_set_blender(disp); + setup_state(vtx, decl, texture); + + switch (type) { + case ALLEGRO_PRIM_LINE_LIST: { + glDrawArrays(GL_LINES, start, num_vtx); + num_primitives = num_vtx / 2; + break; + }; + case ALLEGRO_PRIM_LINE_STRIP: { + glDrawArrays(GL_LINE_STRIP, start, num_vtx); + num_primitives = num_vtx - 1; + break; + }; + case ALLEGRO_PRIM_LINE_LOOP: { + glDrawArrays(GL_LINE_LOOP, start, num_vtx); + num_primitives = num_vtx; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_LIST: { + glDrawArrays(GL_TRIANGLES, start, num_vtx); + num_primitives = num_vtx / 3; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_STRIP: { + glDrawArrays(GL_TRIANGLE_STRIP, start, num_vtx); + num_primitives = num_vtx - 2; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_FAN: { + glDrawArrays(GL_TRIANGLE_FAN, start, num_vtx); + num_primitives = num_vtx - 2; + break; + }; + case ALLEGRO_PRIM_POINT_LIST: { + glDrawArrays(GL_POINTS, start, num_vtx); + num_primitives = num_vtx; + break; + }; + } + + revert_state(texture); + + if (vertex_buffer) { + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + return num_primitives; +} + +static int draw_prim_indexed_raw(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, + ALLEGRO_VERTEX_BUFFER* vertex_buffer, + const void* vtx, const ALLEGRO_VERTEX_DECL* decl, + ALLEGRO_INDEX_BUFFER* index_buffer, + const int* indices, + int start, int end, int type) +{ + int num_primitives = 0; + ALLEGRO_DISPLAY *disp = _al_get_bitmap_display(target); + ALLEGRO_BITMAP *opengl_target = target; + ALLEGRO_BITMAP_EXTRA_OPENGL *extra; + const char* idx = (const char*)indices; + int start_offset = 0; + GLenum idx_size = GL_UNSIGNED_INT; + bool use_buffers = index_buffer != NULL; + int num_vtx = end - start; +#if defined ALLEGRO_IPHONE + GLushort* iphone_idx = NULL; +#endif + + if (use_buffers) { + idx_size = index_buffer->index_size == 4 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; + start_offset = start * index_buffer->index_size; + } + + if (target->parent) { + opengl_target = target->parent; + } + extra = opengl_target->extra; + + if ((!extra->is_backbuffer && disp->ogl_extras->opengl_target != + opengl_target) || al_is_bitmap_locked(target)) { + if (use_buffers) { + return _al_draw_buffer_common_soft(vertex_buffer, texture, index_buffer, start, end, type); + } + else { + return _al_draw_prim_indexed_soft(texture, vtx, decl, indices, num_vtx, type); + } + } + +#if defined ALLEGRO_IPHONE + if (!use_buffers) { + int ii; + iphone_idx = al_malloc(num_vtx * sizeof(GLushort)); + for (ii = start; ii < end; ii++) { + iphone_idx[ii] = (GLushort)indices[ii]; + } + idx = iphone_idx; + start = 0; + idx_size = GL_UNSIGNED_SHORT; + } +#endif + + _al_opengl_set_blender(disp); + + if (use_buffers) { + glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vertex_buffer->common.handle); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (GLuint)index_buffer->common.handle); + } + + setup_state(vtx, decl, texture); + + switch (type) { + case ALLEGRO_PRIM_LINE_LIST: { + glDrawElements(GL_LINES, num_vtx, idx_size, idx + start_offset); + num_primitives = num_vtx / 2; + break; + }; + case ALLEGRO_PRIM_LINE_STRIP: { + glDrawElements(GL_LINE_STRIP, num_vtx, idx_size, idx + start_offset); + num_primitives = num_vtx - 1; + break; + }; + case ALLEGRO_PRIM_LINE_LOOP: { + /* Unimplemented, as it's too hard to do for Direct3D */ + break; + }; + case ALLEGRO_PRIM_TRIANGLE_LIST: { + glDrawElements(GL_TRIANGLES, num_vtx, idx_size, idx + start_offset); + num_primitives = num_vtx / 3; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_STRIP: { + glDrawElements(GL_TRIANGLE_STRIP, num_vtx, idx_size, idx + start_offset); + num_primitives = num_vtx - 2; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_FAN: { + glDrawElements(GL_TRIANGLE_FAN, num_vtx, idx_size, idx + start_offset); + num_primitives = num_vtx - 2; + break; + }; + case ALLEGRO_PRIM_POINT_LIST: { + /* Unimplemented, as it's too hard to do for Direct3D */ + break; + }; + } + + revert_state(texture); + + if (use_buffers) { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + +#if defined ALLEGRO_IPHONE + al_free(iphone_idx); +#endif + + return num_primitives; +} + +#endif /* ALLEGRO_CFG_OPENGL */ + +int _al_draw_prim_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type) +{ +#ifdef ALLEGRO_CFG_OPENGL + return draw_prim_raw(target, texture, 0, vtxs, decl, start, end, type); +#else + (void)target; + (void)texture; + (void)vtxs; + (void)start; + (void)end; + (void)type; + (void)decl; + + return 0; +#endif +} + +int _al_draw_vertex_buffer_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, int start, int end, int type) +{ +#ifdef ALLEGRO_CFG_OPENGL + return draw_prim_raw(target, texture, vertex_buffer, 0, vertex_buffer->decl, start, end, type); +#else + (void)target; + (void)texture; + (void)vertex_buffer; + (void)start; + (void)end; + (void)type; + + return 0; +#endif +} + +int _al_draw_prim_indexed_opengl(ALLEGRO_BITMAP *target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type) +{ +#ifdef ALLEGRO_CFG_OPENGL + return draw_prim_indexed_raw(target, texture, NULL, vtxs, decl, NULL, indices, 0, num_vtx, type); +#else + (void)target; + (void)texture; + (void)vtxs; + (void)decl; + (void)indices; + (void)num_vtx; + (void)type; + + return 0; +#endif +} + +int _al_draw_indexed_buffer_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type) +{ +#ifdef ALLEGRO_CFG_OPENGL + return draw_prim_indexed_raw(target, texture, vertex_buffer, NULL, vertex_buffer->decl, index_buffer, NULL, start, end, type); +#else + (void)target; + (void)texture; + (void)vertex_buffer; + (void)index_buffer; + (void)start; + (void)end; + (void)type; + + return 0; +#endif +} + +#ifdef ALLEGRO_CFG_OPENGL +static bool create_buffer_common(ALLEGRO_BUFFER_COMMON* common, GLenum type, const void* initial_data, int size, int flags) +{ + GLuint vbo; + GLenum usage; + + switch (flags) + { +#if !defined ALLEGRO_CFG_OPENGLES + case ALLEGRO_PRIM_BUFFER_STREAM: + usage = GL_STREAM_DRAW; + break; +#endif + case ALLEGRO_PRIM_BUFFER_STATIC: + usage = GL_STATIC_DRAW; + break; + case ALLEGRO_PRIM_BUFFER_DYNAMIC: + usage = GL_DYNAMIC_DRAW; + break; + default: + usage = GL_STATIC_DRAW; + } + + glGenBuffers(1, &vbo); + glBindBuffer(type, vbo); + glBufferData(type, size, initial_data, usage); + glBindBuffer(type, 0); + + if (glGetError()) + return false; + + common->handle = vbo; + common->local_buffer_length = 0; + return true; +} +#endif + +bool _al_create_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf, const void* initial_data, size_t num_vertices, int flags) +{ +#ifdef ALLEGRO_CFG_OPENGL + int stride = buf->decl ? buf->decl->stride : (int)sizeof(ALLEGRO_VERTEX); + + return create_buffer_common(&buf->common, GL_ARRAY_BUFFER, initial_data, num_vertices * stride, flags); +#else + (void)buf; + (void)initial_data; + (void)num_vertices; + (void)flags; + + return false; +#endif +} + +bool _al_create_index_buffer_opengl(ALLEGRO_INDEX_BUFFER* buf, const void* initial_data, size_t num_indices, int flags) +{ +#ifdef ALLEGRO_CFG_OPENGL + return create_buffer_common(&buf->common, GL_ELEMENT_ARRAY_BUFFER, initial_data, num_indices * buf->index_size, flags);; +#else + (void)buf; + (void)initial_data; + (void)num_indices; + (void)flags; + + return false; +#endif +} + +void _al_destroy_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_OPENGL + glDeleteBuffers(1, (GLuint*)&buf->common.handle); + al_free(buf->common.locked_memory); +#else + (void)buf; +#endif +} + +void _al_destroy_index_buffer_opengl(ALLEGRO_INDEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_OPENGL + glDeleteBuffers(1, (GLuint*)&buf->common.handle); + al_free(buf->common.locked_memory); +#else + (void)buf; +#endif +} + +#ifdef ALLEGRO_CFG_OPENGL +static void* lock_buffer_common(ALLEGRO_BUFFER_COMMON* common, GLenum type) +{ + if (common->local_buffer_length < common->lock_length) { + common->locked_memory = al_realloc(common->locked_memory, common->lock_length); + common->local_buffer_length = common->lock_length; + } + + if (common->lock_flags != ALLEGRO_LOCK_WRITEONLY) { +#if !defined ALLEGRO_CFG_OPENGLES + glBindBuffer(type, (GLuint)common->handle); + glGetBufferSubData(type, common->lock_offset, common->lock_length, common->locked_memory); + glBindBuffer(type, 0); + if (glGetError()) + return 0; +#else + (void)type; + return 0; +#endif + } + return common->locked_memory; +} +#endif + +void* _al_lock_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_OPENGL + return lock_buffer_common(&buf->common, GL_ARRAY_BUFFER); +#else + (void)buf; + + return 0; +#endif +} + +void* _al_lock_index_buffer_opengl(ALLEGRO_INDEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_OPENGL + return lock_buffer_common(&buf->common, GL_ELEMENT_ARRAY_BUFFER); +#else + (void)buf; + + return 0; +#endif +} + +#ifdef ALLEGRO_CFG_OPENGL +static void unlock_buffer_common(ALLEGRO_BUFFER_COMMON* common, GLenum type) +{ + if (common->lock_flags != ALLEGRO_LOCK_READONLY) { + glBindBuffer(type, (GLuint)common->handle); + glBufferSubData(type, common->lock_offset, common->lock_length, common->locked_memory); + glBindBuffer(type, 0); + } +} +#endif + +void _al_unlock_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_OPENGL + unlock_buffer_common(&buf->common, GL_ARRAY_BUFFER); +#else + (void)buf; +#endif +} + +void _al_unlock_index_buffer_opengl(ALLEGRO_INDEX_BUFFER* buf) +{ +#ifdef ALLEGRO_CFG_OPENGL + unlock_buffer_common(&buf->common, GL_ELEMENT_ARRAY_BUFFER); +#else + (void)buf; +#endif +} diff --git a/allegro/addons/primitives/prim_soft.c b/allegro/addons/primitives/prim_soft.c new file mode 100644 index 00000000..69d0bf71 --- /dev/null +++ b/allegro/addons/primitives/prim_soft.c @@ -0,0 +1,532 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Software implementation of some of the primitive routines. + * + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" + +#include "allegro5/allegro_primitives.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_prim_soft.h" +#include "allegro5/internal/aintern_prim.h" +#include "allegro5/internal/aintern_tri_soft.h" + +/* +The vertex cache allows for bulk transformation of vertices, for faster run speeds +*/ +#define LOCAL_VERTEX_CACHE ALLEGRO_VERTEX vertex_cache[ALLEGRO_VERTEX_CACHE_SIZE] + +static void convert_vtx(ALLEGRO_BITMAP* texture, const char* src, ALLEGRO_VERTEX* dest, const ALLEGRO_VERTEX_DECL* decl) +{ + ALLEGRO_VERTEX_ELEMENT* e; + if(!decl) { + *dest = *((ALLEGRO_VERTEX*)src); + return; + } + e = &decl->elements[ALLEGRO_PRIM_POSITION]; + if(e->attribute) { + switch(e->storage) { + case ALLEGRO_PRIM_FLOAT_2: + case ALLEGRO_PRIM_FLOAT_3: + { + float *ptr = (float*)(src + e->offset); + dest->x = *(ptr); + dest->y = *(ptr + 1); + break; + } + case ALLEGRO_PRIM_SHORT_2: + { + short *ptr = (short*)(src + e->offset); + dest->x = (float)*(ptr); + dest->y = (float)*(ptr + 1); + break; + } + } + } else { + dest->x = 0; + dest->y = 0; + } + + e = &decl->elements[ALLEGRO_PRIM_TEX_COORD]; + if(!e->attribute) + e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; + if(e->attribute) { + switch(e->storage) { + case ALLEGRO_PRIM_FLOAT_2: + case ALLEGRO_PRIM_FLOAT_3: + { + float *ptr = (float*)(src + e->offset); + dest->u = *(ptr); + dest->v = *(ptr + 1); + break; + } + case ALLEGRO_PRIM_SHORT_2: + { + short *ptr = (short*)(src + e->offset); + dest->u = (float)*(ptr); + dest->v = (float)*(ptr + 1); + break; + } + } + if(texture && e->attribute == ALLEGRO_PRIM_TEX_COORD) { + dest->u *= (float)al_get_bitmap_width(texture); + dest->v *= (float)al_get_bitmap_height(texture); + } + } else { + dest->u = 0; + dest->v = 0; + } + + e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR]; + if(e->attribute) { + dest->color = *(ALLEGRO_COLOR*)(src + e->offset); + } else { + dest->color = al_map_rgba_f(1,1,1,1); + } +} + +int _al_draw_prim_soft(ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type) +{ + LOCAL_VERTEX_CACHE; + int num_primitives; + int num_vtx; + int use_cache; + int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX); + const ALLEGRO_TRANSFORM* global_trans = al_get_current_transform(); + + num_primitives = 0; + num_vtx = end - start; + use_cache = num_vtx < ALLEGRO_VERTEX_CACHE_SIZE; + + if (texture) + al_lock_bitmap(texture, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + + if (use_cache) { + int ii; + int n = 0; + const char* vtxptr = (const char*)vtxs + start * stride; + for (ii = 0; ii < num_vtx; ii++) { + convert_vtx(texture, vtxptr, &vertex_cache[ii], decl); + al_transform_coordinates(global_trans, &vertex_cache[ii].x, &vertex_cache[ii].y); + n++; + vtxptr += stride; + } + } + +#define SET_VERTEX(v, idx) \ + convert_vtx(texture, (const char*)vtxs + stride * (idx), &v, decl); \ + al_transform_coordinates(global_trans, &v.x, &v.y); \ + + switch (type) { + case ALLEGRO_PRIM_LINE_LIST: { + if (use_cache) { + int ii; + for (ii = 0; ii < num_vtx - 1; ii += 2) { + _al_line_2d(texture, &vertex_cache[ii], &vertex_cache[ii + 1]); + } + } else { + int ii; + for (ii = start; ii < end - 1; ii += 2) { + ALLEGRO_VERTEX v1, v2; + SET_VERTEX(v1, ii); + SET_VERTEX(v2, ii + 1); + + _al_line_2d(texture, &v1, &v2); + } + } + num_primitives = num_vtx / 2; + break; + }; + case ALLEGRO_PRIM_LINE_STRIP: { + if (use_cache) { + int ii; + for (ii = 1; ii < num_vtx; ii++) { + _al_line_2d(texture, &vertex_cache[ii - 1], &vertex_cache[ii]); + } + } else { + int ii; + int idx = 1; + ALLEGRO_VERTEX vtx[2]; + SET_VERTEX(vtx[0], start); + for (ii = start + 1; ii < end; ii++) { + SET_VERTEX(vtx[idx], ii) + _al_line_2d(texture, &vtx[0], &vtx[1]); + idx = 1 - idx; + } + } + num_primitives = num_vtx - 1; + break; + }; + case ALLEGRO_PRIM_LINE_LOOP: { + if (use_cache) { + int ii; + for (ii = 1; ii < num_vtx; ii++) { + _al_line_2d(texture, &vertex_cache[ii - 1], &vertex_cache[ii]); + } + _al_line_2d(texture, &vertex_cache[num_vtx - 1], &vertex_cache[0]); + } else { + int ii; + int idx = 1; + ALLEGRO_VERTEX vtx[2]; + SET_VERTEX(vtx[0], start); + for (ii = start + 1; ii < end; ii++) { + SET_VERTEX(vtx[idx], ii) + _al_line_2d(texture, &vtx[idx], &vtx[1 - idx]); + idx = 1 - idx; + } + SET_VERTEX(vtx[idx], start) + _al_line_2d(texture, &vtx[idx], &vtx[1 - idx]); + } + num_primitives = num_vtx; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_LIST: { + if (use_cache) { + int ii; + for (ii = 0; ii < num_vtx - 2; ii += 3) { + _al_triangle_2d(texture, &vertex_cache[ii], &vertex_cache[ii + 1], &vertex_cache[ii + 2]); + } + } else { + int ii; + for (ii = start; ii < end - 2; ii += 3) { + ALLEGRO_VERTEX v1, v2, v3; + SET_VERTEX(v1, ii); + SET_VERTEX(v2, ii + 1); + SET_VERTEX(v3, ii + 2); + + _al_triangle_2d(texture, &v1, &v2, &v3); + } + } + num_primitives = num_vtx / 3; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_STRIP: { + if (use_cache) { + int ii; + for (ii = 2; ii < num_vtx; ii++) { + _al_triangle_2d(texture, &vertex_cache[ii - 2], &vertex_cache[ii - 1], &vertex_cache[ii]); + } + } else { + int ii; + int idx = 2; + ALLEGRO_VERTEX vtx[3]; + SET_VERTEX(vtx[0], start); + SET_VERTEX(vtx[1], start + 1); + for (ii = start + 2; ii < end; ii++) { + SET_VERTEX(vtx[idx], ii); + + _al_triangle_2d(texture, &vtx[0], &vtx[1], &vtx[2]); + idx = (idx + 1) % 3; + } + } + num_primitives = num_vtx - 2; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_FAN: { + if (use_cache) { + int ii; + for (ii = 1; ii < num_vtx; ii++) { + _al_triangle_2d(texture, &vertex_cache[0], &vertex_cache[ii], &vertex_cache[ii - 1]); + } + } else { + int ii; + int idx = 1; + ALLEGRO_VERTEX v0; + ALLEGRO_VERTEX vtx[2]; + SET_VERTEX(v0, start); + SET_VERTEX(vtx[0], start + 1); + for (ii = start + 1; ii < end; ii++) { + SET_VERTEX(vtx[idx], ii) + _al_triangle_2d(texture, &v0, &vtx[0], &vtx[1]); + idx = 1 - idx; + } + } + num_primitives = num_vtx - 2; + break; + }; + case ALLEGRO_PRIM_POINT_LIST: { + if (use_cache) { + int ii; + for (ii = 0; ii < num_vtx; ii++) { + _al_point_2d(texture, &vertex_cache[ii]); + } + } else { + int ii; + for (ii = start; ii < end; ii++) { + ALLEGRO_VERTEX v; + SET_VERTEX(v, ii); + + _al_point_2d(texture, &v); + } + } + num_primitives = num_vtx; + break; + }; + } + + if(texture) + al_unlock_bitmap(texture); + + return num_primitives; +#undef SET_VERTEX +} + +int _al_draw_prim_indexed_soft(ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, + const int* indices, int num_vtx, int type) +{ + LOCAL_VERTEX_CACHE; + int num_primitives; + int use_cache; + int min_idx, max_idx; + int ii; + int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX); + const ALLEGRO_TRANSFORM* global_trans = al_get_current_transform(); + + num_primitives = 0; + use_cache = 1; + min_idx = indices[0]; + max_idx = indices[0]; + + /* + Determine the range we are dealing with + */ + for (ii = 1; ii < num_vtx; ii++) { + int idx = indices[ii]; + if (max_idx < idx) + max_idx = idx; + else if (min_idx > indices[ii]) + min_idx = idx; + } + if (max_idx - min_idx >= ALLEGRO_VERTEX_CACHE_SIZE) { + use_cache = 0; + } + + if (texture) + al_lock_bitmap(texture, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + + if (use_cache) { + int ii; + for (ii = 0; ii < num_vtx; ii++) { + int idx = indices[ii]; + convert_vtx(texture, (const char*)vtxs + idx * stride, &vertex_cache[idx - min_idx], decl); + al_transform_coordinates(global_trans, &vertex_cache[idx - min_idx].x, &vertex_cache[idx - min_idx].y); + } + } + +#define SET_VERTEX(v, idx) \ + convert_vtx(texture, (const char*)vtxs + stride * (idx), &v, decl); \ + al_transform_coordinates(global_trans, &v.x, &v.y); \ + + switch (type) { + case ALLEGRO_PRIM_LINE_LIST: { + if (use_cache) { + int ii; + for (ii = 0; ii < num_vtx - 1; ii += 2) { + int idx1 = indices[ii] - min_idx; + int idx2 = indices[ii + 1] - min_idx; + + _al_line_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2]); + } + } else { + int ii; + for (ii = 0; ii < num_vtx - 1; ii += 2) { + int idx1 = indices[ii]; + int idx2 = indices[ii + 1]; + + ALLEGRO_VERTEX v1, v2; + SET_VERTEX(v1, idx1); + SET_VERTEX(v2, idx2); + + _al_line_2d(texture, &v1, &v2); + } + } + num_primitives = num_vtx / 2; + break; + }; + case ALLEGRO_PRIM_LINE_STRIP: { + if (use_cache) { + int ii; + for (ii = 1; ii < num_vtx; ii++) { + int idx1 = indices[ii - 1] - min_idx; + int idx2 = indices[ii] - min_idx; + + _al_line_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2]); + } + } else { + int ii; + int idx = 1; + ALLEGRO_VERTEX vtx[2]; + SET_VERTEX(vtx[0], indices[0]); + for (ii = 1; ii < num_vtx; ii++) { + SET_VERTEX(vtx[idx], indices[ii]) + _al_line_2d(texture, &vtx[0], &vtx[1]); + idx = 1 - idx; + } + } + num_primitives = num_vtx - 1; + break; + }; + case ALLEGRO_PRIM_LINE_LOOP: { + if (use_cache) { + int ii; + int idx1, idx2; + + for (ii = 1; ii < num_vtx; ii++) { + int idx1 = indices[ii - 1] - min_idx; + int idx2 = indices[ii] - min_idx; + + _al_line_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2]); + } + idx1 = indices[0] - min_idx; + idx2 = indices[num_vtx - 1] - min_idx; + + _al_line_2d(texture, &vertex_cache[idx2], &vertex_cache[idx1]); + } else { + int ii; + int idx = 1; + ALLEGRO_VERTEX vtx[2]; + SET_VERTEX(vtx[0], indices[0]); + for (ii = 1; ii < num_vtx; ii++) { + SET_VERTEX(vtx[idx], indices[ii]) + _al_line_2d(texture, &vtx[0], &vtx[1]); + idx = 1 - idx; + } + SET_VERTEX(vtx[idx], indices[0]) + _al_line_2d(texture, &vtx[0], &vtx[1]); + } + num_primitives = num_vtx; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_LIST: { + if (use_cache) { + int ii; + for (ii = 0; ii < num_vtx - 2; ii += 3) { + int idx1 = indices[ii] - min_idx; + int idx2 = indices[ii + 1] - min_idx; + int idx3 = indices[ii + 2] - min_idx; + _al_triangle_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2], &vertex_cache[idx3]); + } + } else { + int ii; + for (ii = 0; ii < num_vtx - 2; ii += 3) { + int idx1 = indices[ii]; + int idx2 = indices[ii + 1]; + int idx3 = indices[ii + 2]; + + ALLEGRO_VERTEX v1, v2, v3; + SET_VERTEX(v1, idx1); + SET_VERTEX(v2, idx2); + SET_VERTEX(v3, idx3); + + _al_triangle_2d(texture, &v1, &v2, &v3); + } + } + num_primitives = num_vtx / 3; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_STRIP: { + if (use_cache) { + int ii; + for (ii = 2; ii < num_vtx; ii++) { + int idx1 = indices[ii - 2] - min_idx; + int idx2 = indices[ii - 1] - min_idx; + int idx3 = indices[ii] - min_idx; + _al_triangle_2d(texture, &vertex_cache[idx1], &vertex_cache[idx2], &vertex_cache[idx3]); + } + } else { + int ii; + int idx = 2; + ALLEGRO_VERTEX vtx[3]; + SET_VERTEX(vtx[0], indices[0]); + SET_VERTEX(vtx[1], indices[1]); + for (ii = 2; ii < num_vtx; ii ++) { + SET_VERTEX(vtx[idx], indices[ii]); + + _al_triangle_2d(texture, &vtx[0], &vtx[1], &vtx[2]); + idx = (idx + 1) % 3; + } + } + num_primitives = num_vtx - 2; + break; + }; + case ALLEGRO_PRIM_TRIANGLE_FAN: { + if (use_cache) { + int ii; + int idx0 = indices[0] - min_idx; + for (ii = 1; ii < num_vtx; ii++) { + int idx1 = indices[ii] - min_idx; + int idx2 = indices[ii - 1] - min_idx; + _al_triangle_2d(texture, &vertex_cache[idx0], &vertex_cache[idx1], &vertex_cache[idx2]); + } + } else { + int ii; + int idx = 1; + ALLEGRO_VERTEX v0; + ALLEGRO_VERTEX vtx[2]; + SET_VERTEX(v0, indices[0]); + SET_VERTEX(vtx[0], indices[1]); + for (ii = 2; ii < num_vtx; ii ++) { + SET_VERTEX(vtx[idx], indices[ii]) + _al_triangle_2d(texture, &v0, &vtx[0], &vtx[1]); + idx = 1 - idx; + } + } + num_primitives = num_vtx - 2; + break; + }; + case ALLEGRO_PRIM_POINT_LIST: { + if (use_cache) { + int ii; + for (ii = 0; ii < num_vtx; ii++) { + int idx = indices[ii] - min_idx; + _al_point_2d(texture, &vertex_cache[idx]); + } + } else { + int ii; + for (ii = 0; ii < num_vtx; ii++) { + ALLEGRO_VERTEX v; + SET_VERTEX(v, indices[ii]); + + _al_point_2d(texture, &v); + } + } + num_primitives = num_vtx; + break; + }; + } + + if(texture) + al_unlock_bitmap(texture); + + return num_primitives; +#undef SET_VERTEX +} + +/* Function: al_draw_soft_triangle + */ +void al_draw_soft_triangle( + ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, + void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*first)(uintptr_t, int, int, int, int), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int, int)) +{ + _al_draw_soft_triangle(v1, v2, v3, state, init, first, step, draw); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/primitives/prim_util.c b/allegro/addons/primitives/prim_util.c new file mode 100644 index 00000000..869a853a --- /dev/null +++ b/allegro/addons/primitives/prim_util.c @@ -0,0 +1,251 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Common utilities. + * + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/internal/aintern_list.h" +#include "allegro5/internal/aintern_prim.h" +#include <float.h> +#include <math.h> + +#ifdef ALLEGRO_MSVC + #define hypotf(x, y) _hypotf((x), (y)) +#endif + +# define AL_EPSILON 0.001f + + +/* + * Make an estimate of the scale of the current transformation. + */ +float _al_prim_get_scale(void) +{ + const ALLEGRO_TRANSFORM* t = al_get_current_transform(); + return (hypotf(t->m[0][0], t->m[0][1]) + hypotf(t->m[1][0], t->m[1][1])) / 2; +} + + +/* + * Normalizes vector. + */ +float _al_prim_normalize(float* vector) +{ + float length; + float inv_length; + + length = hypotf(vector[0], vector[1]); + inv_length = length > 0.0f ? 1.0f / length : 1.0f; + + vector[0] *= inv_length; + vector[1] *= inv_length; + + return length; +} + + +/* + * Tests on which side of the line point is placed. + * Positive value will be returned if point is on half plane + * determined by normal vector. Negative value will be returned + * if point is on negative half plane determined by normal vector. + * Zero will be returned if point lie on the line. + */ +int _al_prim_test_line_side(const float* origin, const float* normal, const float* point) +{ + float c = -(origin[0] * normal[0] + origin[1] * normal[1]); + float d = point[0] * normal[0] + point[1] * normal[1] + c; + if (d < 0.0f)/*-AL_EPSILON)*/ + return -1; + else if (d > 0.0f)/*AL_EPSILON)*/ + return 1; + else + return 0; +} + + +/* + * Tests if point is inside of the triangle defined by vertices v0, v1 and v2. + * + * Order of vertices does not have matter. + */ +bool _al_prim_is_point_in_triangle(const float* point, const float* v0, const float* v1, const float* v2) +{ + float edge_normal_0[2] = { -(v1[1] - v0[1]), v1[0] - v0[0] }; + float edge_normal_1[2] = { -(v2[1] - v1[1]), v2[0] - v1[0] }; + float edge_normal_2[2] = { -(v0[1] - v2[1]), v0[0] - v2[0] }; + + int edge_side_0 = _al_prim_test_line_side(v0, edge_normal_0, point); + int edge_side_1 = _al_prim_test_line_side(v1, edge_normal_1, point); + int edge_side_2 = _al_prim_test_line_side(v2, edge_normal_2, point); + + if (edge_side_0 && edge_side_1 && edge_side_2) + return (edge_side_0 == edge_side_1) && (edge_side_0 == edge_side_2); + else if (0 == edge_side_0) + return (edge_side_1 == edge_side_2); + else if (0 == edge_side_1) + return (edge_side_0 == edge_side_2); + else /*if (0 == edge_side_2)*/ + return (edge_side_0 == edge_side_1); +} + + +/* + * Tests for intersection of lines defined by points { v0, v1 } + * and { p0, p1 }. + * + * Returns true if intersection point was determined. If pointers + * are provided time and exact point of intersection will be returned. + * If test fails false will be returned. Intersection point and time + * variables will not be altered in this case. + * + * Intersection time is in { v0, v1 } line space. + */ +bool _al_prim_intersect_segment(const float* v0, const float* v1, const float* p0, const float* p1, float* point/* = NULL*/, float* t0/* = NULL*/, float* t1/* = NULL*/) +{ + float num, denom, time; + + denom = (p1[1] - p0[1]) * (v1[0] - v0[0]) - (p1[0] - p0[0]) * (v1[1] - v0[1]); + + if (fabsf(denom) == 0.0f) + return false; + + num = (p1[0] - p0[0]) * (v0[1] - p0[1]) - (p1[1] - p0[1]) * (v0[0] - p0[0]); + + time = (num / denom); + if (t0) + *t0 = time; + + if (t1) { + + const float num2 = (v1[0] - v0[0]) * (v0[1] - p0[1]) - (v1[1] - v0[1]) * (v0[0] - p0[0]); + + *t1 = (num2 / denom); + } + + if (point) { + + point[0] = v0[0] + time * (v1[0] - v0[0]); + point[1] = v0[1] + time * (v1[1] - v0[1]); + } + + return true; +} + + +/* + * Compares two points for equality. + * + * This is not exact comparison but it is sufficient + * for our needs. + */ +bool _al_prim_are_points_equal(const float* point_a, const float* point_b) +{ + return (fabsf(point_a[0] - point_b[0]) < AL_EPSILON) + && (fabsf(point_a[1] - point_b[1]) < AL_EPSILON); +} + + +/* + * + */ +void _al_prim_cache_init(ALLEGRO_PRIM_VERTEX_CACHE* cache, int prim_type, ALLEGRO_COLOR color) +{ + _al_prim_cache_init_ex(cache, prim_type, color, NULL); +} + +void _al_prim_cache_init_ex(ALLEGRO_PRIM_VERTEX_CACHE* cache, int prim_type, ALLEGRO_COLOR color, void* user_data) +{ + cache->size = 0; + cache->current = cache->buffer; + cache->color = color; + cache->prim_type = prim_type; + cache->user_data = user_data; +} + +void _al_prim_cache_term(ALLEGRO_PRIM_VERTEX_CACHE* cache) +{ + _al_prim_cache_flush(cache); +} + +void _al_prim_cache_flush(ALLEGRO_PRIM_VERTEX_CACHE* cache) +{ + if (cache->size == 0) + return; + + if (cache->prim_type == ALLEGRO_PRIM_VERTEX_CACHE_TRIANGLE) + al_draw_prim(cache->buffer, NULL, NULL, 0, cache->size, ALLEGRO_PRIM_TRIANGLE_LIST); + else if (cache->prim_type == ALLEGRO_PRIM_VERTEX_CACHE_LINE_STRIP) + al_draw_prim(cache->buffer, NULL, NULL, 0, cache->size, ALLEGRO_PRIM_LINE_STRIP); + + if (cache->prim_type == ALLEGRO_PRIM_VERTEX_CACHE_LINE_STRIP) + { + cache->buffer[0] = *(cache->current - 1); + cache->current = cache->buffer + 1; + cache->size = 1; + } + else + { + cache->current = cache->buffer; + cache->size = 0; + } +} + +void _al_prim_cache_push_triangle(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* v0, const float* v1, const float* v2) +{ + if (cache->size >= (ALLEGRO_VERTEX_CACHE_SIZE - 3)) + _al_prim_cache_flush(cache); + + cache->current->x = v0[0]; + cache->current->y = v0[1]; + cache->current->z = 0.0f; + cache->current->color = cache->color; + + ++cache->current; + + cache->current->x = v1[0]; + cache->current->y = v1[1]; + cache->current->z = 0.0f; + cache->current->color = cache->color; + + ++cache->current; + + cache->current->x = v2[0]; + cache->current->y = v2[1]; + cache->current->z = 0.0f; + cache->current->color = cache->color; + + ++cache->current; + + cache->size += 3; + + //al_draw_triangle(v0[0], v0[1], v1[0], v1[1], v2[0], v2[1], cache->color, 1.0f); +} + +void _al_prim_cache_push_point(ALLEGRO_PRIM_VERTEX_CACHE* cache, const float* v) +{ + if (cache->size >= (ALLEGRO_VERTEX_CACHE_SIZE - 1)) + _al_prim_cache_flush(cache); + + cache->current->x = v[0]; + cache->current->y = v[1]; + cache->current->z = 0.0f; + cache->current->color = cache->color; + + ++cache->current; + ++cache->size; +} diff --git a/allegro/addons/primitives/primitives.c b/allegro/addons/primitives/primitives.c new file mode 100644 index 00000000..dcf96d88 --- /dev/null +++ b/allegro/addons/primitives/primitives.c @@ -0,0 +1,595 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Core primitive addon functions. + * + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/platform/alplatf.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_prim.h" +#include "allegro5/internal/aintern_prim_directx.h" +#include "allegro5/internal/aintern_prim_opengl.h" +#include "allegro5/internal/aintern_prim_soft.h" +#include <math.h> + +#ifdef ALLEGRO_CFG_OPENGL +#include "allegro5/allegro_opengl.h" +#endif + +#ifndef ALLEGRO_DIRECT3D +#define ALLEGRO_DIRECT3D ALLEGRO_DIRECT3D_INTERNAL +#endif + +ALLEGRO_DEBUG_CHANNEL("primitives") + +static bool addon_initialized = false; + +/* Function: al_init_primitives_addon + */ +bool al_init_primitives_addon(void) +{ + bool ret = true; + ret &= _al_init_d3d_driver(); + + addon_initialized = ret; + + _al_add_exit_func(al_shutdown_primitives_addon, "primitives_shutdown"); + + return ret; +} + +/* Function: al_is_primitives_addon_initialized + */ +bool al_is_primitives_addon_initialized(void) +{ + return addon_initialized; +} + +/* Function: al_shutdown_primitives_addon + */ +void al_shutdown_primitives_addon(void) +{ + _al_shutdown_d3d_driver(); + addon_initialized = false; +} + +/* Function: al_draw_prim + */ +int al_draw_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, + ALLEGRO_BITMAP* texture, int start, int end, int type) +{ + ALLEGRO_BITMAP *target; + int ret = 0; + + ASSERT(addon_initialized); + ASSERT(vtxs); + ASSERT(end >= start); + ASSERT(start >= 0); + ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES); + + target = al_get_target_bitmap(); + + /* In theory, if we ever get a camera concept for this addon, the transformation into + * view space should occur here + */ + + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP || + (texture && al_get_bitmap_flags(texture) & ALLEGRO_MEMORY_BITMAP) || + _al_pixel_format_is_compressed(al_get_bitmap_format(target))) { + ret = _al_draw_prim_soft(texture, vtxs, decl, start, end, type); + } else { + int flags = al_get_display_flags(_al_get_bitmap_display(target)); + if (flags & ALLEGRO_OPENGL) { + ret = _al_draw_prim_opengl(target, texture, vtxs, decl, start, end, type); + } else if (flags & ALLEGRO_DIRECT3D) { + ret = _al_draw_prim_directx(target, texture, vtxs, decl, start, end, type); + } + } + + return ret; +} + +/* Function: al_draw_indexed_prim + */ +int al_draw_indexed_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, + ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type) +{ + ALLEGRO_BITMAP *target; + int ret = 0; + + ASSERT(addon_initialized); + ASSERT(vtxs); + ASSERT(indices); + ASSERT(num_vtx > 0); + ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES); + + target = al_get_target_bitmap(); + + /* In theory, if we ever get a camera concept for this addon, the transformation into + * view space should occur here + */ + + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP || + (texture && al_get_bitmap_flags(texture) & ALLEGRO_MEMORY_BITMAP) || + _al_pixel_format_is_compressed(al_get_bitmap_format(target))) { + ret = _al_draw_prim_indexed_soft(texture, vtxs, decl, indices, num_vtx, type); + } else { + int flags = al_get_display_flags(_al_get_bitmap_display(target)); + if (flags & ALLEGRO_OPENGL) { + ret = _al_draw_prim_indexed_opengl(target, texture, vtxs, decl, indices, num_vtx, type); + } else if (flags & ALLEGRO_DIRECT3D) { + ret = _al_draw_prim_indexed_directx(target, texture, vtxs, decl, indices, num_vtx, type); + } + } + + return ret; +} + +int _al_bitmap_region_is_locked(ALLEGRO_BITMAP* bmp, int x1, int y1, int w, int h) +{ + ASSERT(bmp); + + if (!al_is_bitmap_locked(bmp)) + return 0; + if (x1 + w > bmp->lock_x && y1 + h > bmp->lock_y && x1 < bmp->lock_x + bmp->lock_w && y1 < bmp->lock_y + bmp->lock_h) + return 1; + return 0; +} + +/* Function: al_get_allegro_primitives_version + */ +uint32_t al_get_allegro_primitives_version(void) +{ + return ALLEGRO_VERSION_INT; +} + +/* Function: al_create_vertex_decl + */ +ALLEGRO_VERTEX_DECL* al_create_vertex_decl(const ALLEGRO_VERTEX_ELEMENT* elements, int stride) +{ + ALLEGRO_VERTEX_DECL* ret; + ALLEGRO_DISPLAY* display; + ALLEGRO_VERTEX_ELEMENT* e; + int flags; + + ASSERT(addon_initialized); + + ret = al_malloc(sizeof(ALLEGRO_VERTEX_DECL)); + ret->elements = al_calloc(1, sizeof(ALLEGRO_VERTEX_ELEMENT) * ALLEGRO_PRIM_ATTR_NUM); + while(elements->attribute) { +#ifdef ALLEGRO_CFG_OPENGLES + if (elements->storage == ALLEGRO_PRIM_HALF_FLOAT_2 || + elements->storage == ALLEGRO_PRIM_HALF_FLOAT_4) { + ALLEGRO_WARN("This platform does not support ALLEGRO_PRIM_HALF_FLOAT_2 or ALLEGRO_PRIM_HALF_FLOAT_4.\n"); + goto fail; + } +#endif + ret->elements[elements->attribute] = *elements; + elements++; + } + + e = &ret->elements[ALLEGRO_PRIM_POSITION]; + if (e->attribute) { + if (e->storage != ALLEGRO_PRIM_FLOAT_2 && + e->storage != ALLEGRO_PRIM_FLOAT_3 && + e->storage != ALLEGRO_PRIM_SHORT_2) { + ALLEGRO_WARN("Invalid storage for ALLEGRO_PRIM_POSITION.\n"); + goto fail; + } + } + + e = &ret->elements[ALLEGRO_PRIM_TEX_COORD]; + if(!e->attribute) + e = &ret->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL]; + if (e->attribute) { + if (e->storage != ALLEGRO_PRIM_FLOAT_2 && + e->storage != ALLEGRO_PRIM_SHORT_2) { + ALLEGRO_WARN("Invalid storage for %s.\n", ret->elements[ALLEGRO_PRIM_TEX_COORD].attribute ? "ALLEGRO_PRIM_TEX_COORD" : "ALLEGRO_PRIM_TEX_COORD_PIXEL"); + goto fail; + } + } + + display = al_get_current_display(); + flags = al_get_display_flags(display); + if (flags & ALLEGRO_DIRECT3D) { + _al_set_d3d_decl(display, ret); + } + + ret->stride = stride; + return ret; +fail: + al_free(ret->elements); + al_free(ret); + return NULL; +} + +/* Function: al_destroy_vertex_decl + */ +void al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL* decl) +{ + if (!decl) + return; + al_free(decl->elements); + /* + * TODO: Somehow free the d3d_decl + */ + al_free(decl); +} + +/* Function: al_create_vertex_buffer + */ +ALLEGRO_VERTEX_BUFFER* al_create_vertex_buffer(ALLEGRO_VERTEX_DECL* decl, + const void* initial_data, int num_vertices, int flags) +{ + ALLEGRO_VERTEX_BUFFER* ret; + int display_flags = al_get_display_flags(al_get_current_display()); + ASSERT(addon_initialized); + ret = al_calloc(1, sizeof(ALLEGRO_VERTEX_BUFFER)); + ret->common.size = num_vertices; + ret->common.write_only = !(flags & ALLEGRO_PRIM_BUFFER_READWRITE); + ret->decl = decl; + +#if defined ALLEGRO_IPHONE || defined ALLEGRO_ANDROID + if (flags & ALLEGRO_PRIM_BUFFER_READWRITE) + goto fail; +#endif + + if (display_flags & ALLEGRO_OPENGL) { + if (_al_create_vertex_buffer_opengl(ret, initial_data, num_vertices, flags)) + return ret; + } + else if (display_flags & ALLEGRO_DIRECT3D) { + if (_al_create_vertex_buffer_directx(ret, initial_data, num_vertices, flags)) + return ret; + } + + /* Silence the warning */ + goto fail; +fail: + al_free(ret); + return 0; +} + +/* Function: al_create_index_buffer + */ +ALLEGRO_INDEX_BUFFER* al_create_index_buffer(int index_size, + const void* initial_data, int num_indices, int flags) +{ + ALLEGRO_INDEX_BUFFER* ret; + int display_flags = al_get_display_flags(al_get_current_display()); + ASSERT(addon_initialized); + ASSERT(index_size == 2 || index_size == 4); + ret = al_calloc(1, sizeof(ALLEGRO_INDEX_BUFFER)); + ret->common.size = num_indices; + ret->common.write_only = !(flags & ALLEGRO_PRIM_BUFFER_READWRITE); + ret->index_size = index_size; + +#if defined ALLEGRO_IPHONE || defined ALLEGRO_ANDROID + if (flags & ALLEGRO_PRIM_BUFFER_READWRITE) + goto fail; +#endif + +#if defined ALLEGRO_IPHONE + if (index_size == 4) + goto fail; +#endif + + if (display_flags & ALLEGRO_OPENGL) { + if (_al_create_index_buffer_opengl(ret, initial_data, num_indices, flags)) + return ret; + } + else if (display_flags & ALLEGRO_DIRECT3D) { + if (_al_create_index_buffer_directx(ret, initial_data, num_indices, flags)) + return ret; + } + + /* Silence the warning */ + goto fail; +fail: + al_free(ret); + return NULL; +} + +/* Function: al_destroy_vertex_buffer + */ +void al_destroy_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer) +{ + int flags = al_get_display_flags(al_get_current_display()); + ASSERT(addon_initialized); + + if (buffer == 0) + return; + + al_unlock_vertex_buffer(buffer); + + if (flags & ALLEGRO_OPENGL) { + _al_destroy_vertex_buffer_opengl(buffer); + } + else if (flags & ALLEGRO_DIRECT3D) { + _al_destroy_vertex_buffer_directx(buffer); + } + + al_free(buffer); +} + +/* Function: al_destroy_index_buffer + */ +void al_destroy_index_buffer(ALLEGRO_INDEX_BUFFER* buffer) +{ + int flags = al_get_display_flags(al_get_current_display()); + ASSERT(addon_initialized); + + if (buffer == 0) + return; + + al_unlock_index_buffer(buffer); + + if (flags & ALLEGRO_OPENGL) { + _al_destroy_index_buffer_opengl(buffer); + } + else if (flags & ALLEGRO_DIRECT3D) { + _al_destroy_index_buffer_directx(buffer); + } + + al_free(buffer); +} + +/* The sizes are in bytes here */ +static bool lock_buffer_common(ALLEGRO_BUFFER_COMMON* common, int offset, int length, int flags) +{ + if (common->is_locked || (common->write_only && flags != ALLEGRO_LOCK_WRITEONLY)) + return false; + + common->lock_offset = offset; + common->lock_length = length; + common->lock_flags = flags; + common->is_locked = true; + return true; +} + +/* Function: al_lock_vertex_buffer + */ +void* al_lock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer, int offset, + int length, int flags) +{ + int stride; + int disp_flags = al_get_display_flags(al_get_current_display()); + ASSERT(buffer); + ASSERT(addon_initialized); + + if (offset + length > buffer->common.size) + return NULL; + + stride = buffer->decl ? buffer->decl->stride : (int)sizeof(ALLEGRO_VERTEX); + + if (!lock_buffer_common(&buffer->common, offset * stride, length * stride, flags)) + return NULL; + + if (disp_flags & ALLEGRO_OPENGL) { + return _al_lock_vertex_buffer_opengl(buffer); + } + else if (disp_flags & ALLEGRO_DIRECT3D) { + return _al_lock_vertex_buffer_directx(buffer); + } + else { + return NULL; + } +} + +/* Function: al_lock_index_buffer + */ +void* al_lock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer, int offset, + int length, int flags) +{ + int disp_flags = al_get_display_flags(al_get_current_display()); + ASSERT(buffer); + ASSERT(addon_initialized); + + if (offset + length > buffer->common.size) + return NULL; + + if (!lock_buffer_common(&buffer->common, offset * buffer->index_size, length * buffer->index_size, flags)) + return NULL; + + if (disp_flags & ALLEGRO_OPENGL) { + return _al_lock_index_buffer_opengl(buffer); + } + else if (disp_flags & ALLEGRO_DIRECT3D) { + return _al_lock_index_buffer_directx(buffer); + } + else { + return NULL; + } +} + +/* Function: al_unlock_vertex_buffer + */ +void al_unlock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer) +{ + int flags = al_get_display_flags(al_get_current_display()); + ASSERT(buffer); + ASSERT(addon_initialized); + + if (!buffer->common.is_locked) + return; + + buffer->common.is_locked = false; + + if (flags & ALLEGRO_OPENGL) { + _al_unlock_vertex_buffer_opengl(buffer); + } + else if (flags & ALLEGRO_DIRECT3D) { + _al_unlock_vertex_buffer_directx(buffer); + } +} + +/* Function: al_unlock_index_buffer + */ +void al_unlock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer) +{ + int flags = al_get_display_flags(al_get_current_display()); + ASSERT(buffer); + ASSERT(addon_initialized); + + if (!buffer->common.is_locked) + return; + + buffer->common.is_locked = false; + + if (flags & ALLEGRO_OPENGL) { + _al_unlock_index_buffer_opengl(buffer); + } + else if (flags & ALLEGRO_DIRECT3D) { + _al_unlock_index_buffer_directx(buffer); + } +} + +/* Software fallback for buffer drawing */ +int _al_draw_buffer_common_soft(ALLEGRO_VERTEX_BUFFER* vertex_buffer, ALLEGRO_BITMAP* texture, ALLEGRO_INDEX_BUFFER* index_buffer, int start, int end, int type) +{ + void* vtx; + int num_primitives = 0; + int num_vtx = end - start; + int vtx_lock_start = index_buffer ? 0 : start; + int vtx_lock_len = index_buffer ? al_get_vertex_buffer_size(vertex_buffer) : num_vtx; + if (vertex_buffer->common.write_only || (index_buffer && index_buffer->common.write_only)) { + return 0; + } + + vtx = al_lock_vertex_buffer(vertex_buffer, vtx_lock_start, vtx_lock_len, ALLEGRO_LOCK_READONLY); + ASSERT(vtx); + + if (index_buffer) { + void* idx; + int* int_idx = NULL; + int ii; + + idx = al_lock_index_buffer(index_buffer, start, num_vtx, ALLEGRO_LOCK_READONLY); + ASSERT(idx); + + if (index_buffer->index_size != 4) { + int_idx = al_malloc(num_vtx * sizeof(int)); + for (ii = 0; ii < num_vtx; ii++) { + int_idx[ii] = ((unsigned short*)idx)[ii]; + } + idx = int_idx; + } + + num_primitives = _al_draw_prim_indexed_soft(texture, vtx, vertex_buffer->decl, idx, num_vtx, type); + + al_unlock_index_buffer(index_buffer); + al_free(int_idx); + } + else { + num_primitives = _al_draw_prim_soft(texture, vtx, vertex_buffer->decl, 0, num_vtx, type); + } + + al_unlock_vertex_buffer(vertex_buffer); + return num_primitives; +} + +/* Function: al_draw_vertex_buffer + */ +int al_draw_vertex_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer, + ALLEGRO_BITMAP* texture, int start, int end, int type) +{ + ALLEGRO_BITMAP *target; + int ret = 0; + + ASSERT(addon_initialized); + ASSERT(end >= start); + ASSERT(start >= 0); + ASSERT(end <= al_get_vertex_buffer_size(vertex_buffer)); + ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES); + ASSERT(vertex_buffer); + ASSERT(!vertex_buffer->common.is_locked); + + target = al_get_target_bitmap(); + + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP || + (texture && al_get_bitmap_flags(texture) & ALLEGRO_MEMORY_BITMAP) || + _al_pixel_format_is_compressed(al_get_bitmap_format(target))) { + ret = _al_draw_buffer_common_soft(vertex_buffer, texture, NULL, start, end, type); + } else { + int flags = al_get_display_flags(al_get_current_display()); + if (flags & ALLEGRO_OPENGL) { + ret = _al_draw_vertex_buffer_opengl(target, texture, vertex_buffer, start, end, type); + } + else if (flags & ALLEGRO_DIRECT3D) { + ret = _al_draw_vertex_buffer_directx(target, texture, vertex_buffer, start, end, type); + } + } + + return ret; +} + +/* Function: al_draw_indexed_buffer + */ +int al_draw_indexed_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer, + ALLEGRO_BITMAP* texture, ALLEGRO_INDEX_BUFFER* index_buffer, + int start, int end, int type) +{ + ALLEGRO_BITMAP *target; + int ret = 0; + + ASSERT(addon_initialized); + ASSERT(end >= start); + ASSERT(start >= 0); + ASSERT(end <= al_get_index_buffer_size(index_buffer)); + ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES); + ASSERT(vertex_buffer); + ASSERT(!vertex_buffer->common.is_locked); + ASSERT(index_buffer); + ASSERT(!index_buffer->common.is_locked); + + target = al_get_target_bitmap(); + + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP || + (texture && al_get_bitmap_flags(texture) & ALLEGRO_MEMORY_BITMAP) || + _al_pixel_format_is_compressed(al_get_bitmap_format(target))) { + ret = _al_draw_buffer_common_soft(vertex_buffer, texture, index_buffer, start, end, type); + } else { + int flags = al_get_display_flags(al_get_current_display()); + if (flags & ALLEGRO_OPENGL) { + ret = _al_draw_indexed_buffer_opengl(target, texture, vertex_buffer, index_buffer, start, end, type); + } + else if (flags & ALLEGRO_DIRECT3D) { + ret = _al_draw_indexed_buffer_directx(target, texture, vertex_buffer, index_buffer, start, end, type); + } + } + + return ret; +} + +/* Function: al_get_vertex_buffer_size + */ +int al_get_vertex_buffer_size(ALLEGRO_VERTEX_BUFFER* buffer) +{ + ASSERT(buffer); + return buffer->common.size; +} + +/* Function: al_get_index_buffer_size + */ +int al_get_index_buffer_size(ALLEGRO_INDEX_BUFFER* buffer) +{ + ASSERT(buffer); + return buffer->common.size; +} diff --git a/allegro/addons/primitives/triangulator.c b/allegro/addons/primitives/triangulator.c new file mode 100644 index 00000000..6fcb1e94 --- /dev/null +++ b/allegro/addons/primitives/triangulator.c @@ -0,0 +1,870 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Polygon triangulation with holes. + * + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + */ + + +# include "allegro5/allegro.h" +# include "allegro5/allegro_primitives.h" +# include "allegro5/internal/aintern_prim.h" +# include "allegro5/internal/aintern_list.h" +# include <float.h> +# include <math.h> + + +# define POLY_DEBUG 0 + + +/* */ +# define POLY_VERTEX_ATTR_REFLEX 0x0001 +# define POLY_VERTEX_ATTR_EAR_CLIP 0x0002 +# define POLY_VERTEX_ATTR_ALL (POLY_VERTEX_ATTR_REFLEX | POLY_VERTEX_ATTR_EAR_CLIP) + + +typedef void (*POLY_EMIT_TRIANGLE)(int, int, int, void*); + +typedef struct POLY { + const float* vertex_buffer; + size_t vertex_stride; + size_t vertex_count; + const int* split_indices; + size_t split_stride; + size_t split_count; + POLY_EMIT_TRIANGLE emit; + void* userdata; + _AL_LIST* vertex_list; + _AL_LIST* reflex_list; + _AL_LIST* ear_list; +} POLY; + +typedef struct POLY_SPLIT { + int begin; + size_t size; + float* point; + int max_index; +} POLY_SPLIT; + + +# if POLY_DEBUG +typedef void (*poly_debug_draw_text_t)(float x, float y, int line, const char* format, ...); + +#if defined _MSC_VER +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#define __noop ((void)0) +#endif + +EXPORT int g_poly_debug_split_step = -1; +EXPORT int g_poly_debug_step = -1; +EXPORT int g_poly_debug_step_current = 0; +EXPORT poly_debug_draw_text_t g_poly_debug_draw_text = NULL; +EXPORT float g_poly_debug_scale = 1.0f; + +#undef EXPORT + +# define POLY_DEBUG_TEXT(x,y,...) (g_poly_debug_draw_text ? g_poly_debug_draw_text(x,y,INT_MAX,__VA_ARGS__) : __noop) +# define POLY_DEBUG_TEXT_LINE(x,y,line,...) (g_poly_debug_draw_text ? g_poly_debug_draw_text(x,y,line,__VA_ARGS__) : __noop) + +# endif + + +/* Internal functions. */ +static bool poly_initialize(POLY* poly); +static void poly_classify_vertices(_AL_LIST* vertices, _AL_LIST* reflex, _AL_LIST* ear); +static void poly_classify_vertices_in_range(_AL_LIST_ITEM* begin, _AL_LIST_ITEM* end, _AL_LIST* vertices, _AL_LIST* reflex, _AL_LIST* ear); +static void poly_do_triangulate(POLY* poly); + +static _AL_LIST* poly_create_split_list(POLY* polygon); +static void poly_split_list_dtor(void* user_data); + + +/* + * Seek for closest intersection point of polygon with a ray directed + * to the right. + * + * Returns true if intersection was found. 'point', 'edge0' and 'edge1' + * are set to proper values (if not NULL). + * Returns false if intersection was not fount and none of above + * are modified. + */ +static bool poly_find_closest_intersection(_AL_LIST* vertices, const float* vertex, float* point, _AL_LIST_ITEM** edge0, _AL_LIST_ITEM** edge1) +{ + size_t i; + const float* v0 = NULL; + float v1[2]; + float intersection[2]; + float t0, t1; + float best_point[2] = {0, 0}; + float best_t; + _AL_LIST_ITEM* item = NULL; + _AL_LIST_ITEM* next = NULL; + _AL_LIST_ITEM* best_e0 = NULL; + _AL_LIST_ITEM* best_e1 = NULL; + + /* Assemble line pointing to the right. */ + v0 = vertex; + v1[0] = v0[0] + 1.0f; + v1[1] = v0[1]; + + /* Seek for the closest intersection. */ + best_t = FLT_MAX; + item = _al_list_front(vertices); + next = _al_list_next_circular(vertices, item); + for (i = 0; i < _al_list_size(vertices); ++i, item = next, next = _al_list_next_circular(vertices, next)) { + + float* p0 = (float*)_al_list_item_data(item); + float* p1 = (float*)_al_list_item_data(next); + + /* Perform quick rejection. + * + * We are interested only with outer edges. That mean only those + * whose go from the bottom to the up. Note we cannot intersect + * parallel line. + * + * Second condition reject edges lying completely on the left + * side of ray origin. + */ + if ((p0[1] < p1[1]) || (p0[0] <= vertex[0] && p1[0] <= vertex[0])) + continue; + + if (_al_prim_intersect_segment(v0, v1, p0, p1, intersection, &t0, &t1) && (t1 >= 0.0f) && (t1 <= 1.0f) && (t0 >= 0.0f) && (t0 < best_t)) { + + best_t = t0; + best_point[0] = intersection[0]; + best_point[1] = intersection[1]; + best_e0 = item; + best_e1 = next; + } + } + + if (NULL != best_e0) { + + if (NULL != point) { + + point[0] = best_point[0]; + point[1] = best_point[1]; + } + + if (NULL != edge0) + *edge0 = best_e0; + + if (NULL != edge1) + *edge1 = best_e1; + +# if POLY_DEBUG + //al_draw_line(v0[0], v0[1], point[0], point[1], al_map_rgb(255, 0, 0), 0.0f); +# endif + + return true; + } + else + return false; +} + + +/* + * Seek for the best vertex in polygon for doing split. + * + * Returns vertex after which split (hole) vertices + * can be inserted. + */ +static _AL_LIST_ITEM* poly_find_outter_split_vertex(POLY* polygon, POLY_SPLIT* split) +{ + float intersection[2]; + _AL_LIST_ITEM* edge_vertex_0; + _AL_LIST_ITEM* edge_vertex_1; + _AL_LIST_ITEM* vertex; + _AL_LIST_ITEM* reflex_item; + _AL_LIST_ITEM* best_vertex; + float best_distance; + float* p0; + float* p1; + float* p; + + if (!poly_find_closest_intersection(polygon->vertex_list, split->point, intersection, &edge_vertex_0, &edge_vertex_1)) + return NULL; + + p0 = (float*)_al_list_item_data(edge_vertex_0); + p1 = (float*)_al_list_item_data(edge_vertex_1); + + /* Maybe we hit an edge vertex? */ + if (_al_prim_are_points_equal(split->point, p0)) + return edge_vertex_0; + + if (_al_prim_are_points_equal(split->point, p1)) + return edge_vertex_1; + + /* No luck. Pick point which most far away from us. */ + if (p0[0] > p1[0]) { + + vertex = edge_vertex_0; + p = p0; + } + else { + + vertex = edge_vertex_1; + p = p1; + } + + /* Seek in reflex vertices. */ + best_vertex = NULL; + best_distance = FLT_MAX; + + for (reflex_item = _al_list_front(polygon->reflex_list); reflex_item; reflex_item = _al_list_next(polygon->reflex_list, reflex_item)) { + + _AL_LIST_ITEM* reflex_vertex = (_AL_LIST_ITEM*)_al_list_item_data(reflex_item); + + float* reflex_point = (float*)_al_list_item_data(reflex_vertex); + + if (_al_prim_is_point_in_triangle(reflex_point, split->point, p, intersection)) { + + float diff_x = reflex_point[0] - split->point[0]; + float diff_y = reflex_point[1] - split->point[1]; + + float dist = diff_x * diff_x + diff_y * diff_y; + + if (dist < best_distance) { + + best_distance = dist; + best_vertex = reflex_vertex; + } + } + } + + if (NULL != best_vertex) + vertex = best_vertex; + +//# if POLY_DEBUG +// p0 = (float*)_al_list_item_data(vertex); +// al_draw_line(p0[0], p0[1], intersection[0], intersection[1], al_map_rgb(255, 0, 0), 0.0f); +//# endif + + return vertex; +} + + +# define POLY_VERTEX(index) ((float*)(((uint8_t*)polygon->vertex_buffer) + (index) * polygon->vertex_stride)) +# define POLY_SPLIT(index) (*((int*)(((uint8_t*)polygon->split_indices) + (index) * polygon->split_stride))) +# define POLY_SPLIT_INDEX(split) (((uint8_t*)split - (uint8_t*)polygon->split_indices) / polygon->split_stride) + + +/* + * Create list of the splits. + */ +static _AL_LIST* poly_create_split_list(POLY* polygon) +{ + int i; + int last_split; + + _AL_LIST* list = _al_list_create_static(polygon->split_count); + POLY_SPLIT* splits = (POLY_SPLIT*)al_malloc(polygon->split_count * sizeof(POLY_SPLIT)); + + if ((NULL == list) || (NULL == splits)) { + + _al_list_destroy(list); + al_free(splits); + + return NULL; + } + + /* Set list destructor, so we will don't worry about + * manually releasing allocated memory. + */ + _al_list_set_dtor(list, poly_split_list_dtor); + _al_list_set_user_data(list, splits); + + last_split = POLY_SPLIT(0); + for (i = 1; i < (int)polygon->split_count; ++i) { + + int j; + float max; + POLY_SPLIT* split = splits + i; + _AL_LIST_ITEM* where; + + split->begin = last_split; + split->size = POLY_SPLIT(i) - last_split; + last_split = last_split + split->size; + + max = -FLT_MAX; + split->max_index = -1; + for (j = split->begin; j < split->begin + (int)split->size; ++j) { + + float* point = POLY_VERTEX(j); + + if (point[0] >= max) { + + max = point[0]; + split->point = point; + split->max_index = j; + } + } + + split->max_index -= split->begin; + + ASSERT(split->max_index >= 0); + + where = NULL; + if (!_al_list_is_empty(list)) { + + for (where = _al_list_front(list); where; where = _al_list_next(list, where)) { + + POLY_SPLIT* local_split = (POLY_SPLIT*)_al_list_item_data(where); + + if (local_split->point[0] < max) + break; + } + } + + if (NULL == where) + _al_list_push_back(list, split); + else + _al_list_insert_before(list, where, split); + } + + return list; +} + + +/* + * Release memory allocated by split list. This method + * serve as callback to the list. + */ +static void poly_split_list_dtor(void* user_data) +{ + /* This is array of POLY_SPLIT. */ + al_free(user_data); +} + + +/* + * Perform initialization step to polygon triangulation. + * + * Three linked list are initialized: vertex_list, reflex_list + * and ear_list. + * + * All provided splits (holes) are resolved in this step. + * Therefore at the end we have simple polygon. + */ +static bool poly_initialize(POLY* polygon) +{ + _AL_LIST* vertex_list; + _AL_LIST* reflex_list; + _AL_LIST* ear_list; + _AL_LIST* split_list; + _AL_LIST_ITEM* split_item; + size_t vertex_count; + bool use_split_list; + size_t j; + int i; + +# if POLY_DEBUG + if (g_poly_debug_split_step >= 0) + polygon->split_count = min(g_poly_debug_split_step, polygon->split_count); +# endif + + /* Every hole add two extra vertices to the list. */ + vertex_count = polygon->vertex_count + (polygon->split_count - 1) * 2; + + /* Create lists for polygon. */ + vertex_list = _al_list_create_static(vertex_count); + reflex_list = _al_list_create_static(vertex_count); + ear_list = _al_list_create_static(vertex_count); + + if (polygon->split_count > 1) { + + split_list = poly_create_split_list(polygon); + use_split_list = true; + } + else { + split_list = NULL; + use_split_list = false; + } + + if ((NULL == vertex_list) || (NULL == reflex_list) || (NULL == ear_list) || (use_split_list && (NULL == split_list))) { + + _al_list_destroy(vertex_list); + _al_list_destroy(reflex_list); + _al_list_destroy(ear_list); + _al_list_destroy(split_list); + + return false; + } + + /* Store lists in polygon. */ + polygon->vertex_list = vertex_list; + polygon->reflex_list = reflex_list; + polygon->ear_list = ear_list; + + /* Push main polygon outline. */ + for (i = 0; i < POLY_SPLIT(0); ++i) + _al_list_push_back(vertex_list, POLY_VERTEX(i)); + + if (use_split_list) { + +# if POLY_DEBUG + int current_split = 0; +# endif + + poly_classify_vertices(vertex_list, reflex_list, NULL); + + /* Resolve all holes. */ + for (split_item = _al_list_front(split_list); split_item; split_item = _al_list_next(split_list, split_item)) { + + _AL_LIST_ITEM* first_vertex; + _AL_LIST_ITEM* last_vertex; + POLY_SPLIT* split; + +# if POLY_DEBUG + if (g_poly_debug_split_step >= 0 && current_split >= g_poly_debug_split_step) + break; + + ++current_split; +# endif + + split = (POLY_SPLIT*)_al_list_item_data(split_item); + + first_vertex = poly_find_outter_split_vertex(polygon, split); + + if (NULL == first_vertex) + break; + + /* Insert hole vertices. */ + last_vertex = first_vertex; + for (j = 0; j <= split->size; ++j) + last_vertex = _al_list_insert_after(vertex_list, last_vertex, + POLY_VERTEX(split->begin + ((j + split->max_index) % split->size))); + last_vertex = _al_list_insert_after(vertex_list, last_vertex, _al_list_item_data(first_vertex)); + + _al_list_remove(reflex_list, first_vertex); + + poly_classify_vertices_in_range(first_vertex, _al_list_next(vertex_list, last_vertex), vertex_list, reflex_list, NULL); + } + + _al_list_destroy(split_list); + + poly_classify_vertices(vertex_list, NULL, ear_list); + } + else + /* Initialize reflex and ear vertex lists. */ + poly_classify_vertices(vertex_list, reflex_list, ear_list); + + return true; +} + +# undef POLY_VERTEX +# undef POLY_SPLIT +# undef POLY_SPLIT_INDEX + + +/* + * Compute polygon vertex attributes. Currently supported attributes are: + * - ear clip + * - reflex + * + * Vertex is an ear clip when triangle made by their edges does not contain + * any other vertices. + * + * Vertex is a reflex when angle between edges is greater or equal + * to 180 degrees. + * + * Optionally function may take reflex list (if not NULL). In this case test + * for ear clip is performed only on reflex vertices not on entire polygon. + * This is used for triangulation speed optimization, because convex + * (non reflect) vertices will never became reflex. + * + * Flags are used to determine for which attribute we want to check. + * Use POLY_VERTEX_ATTR_ALL to test for all attributes. + */ +static int poly_compute_vertex_attributes(_AL_LIST* vertices, _AL_LIST_ITEM* item, int flags, _AL_LIST* reflex) +{ + size_t i; + _AL_LIST_ITEM* prev = _al_list_previous_circular(vertices, item); + _AL_LIST_ITEM* next = _al_list_next_circular(vertices, item); + _AL_LIST_ITEM* point = NULL; + int result = 0; + float* v0; + float* v1; + float* v2; + float cross; + + // Oops, degenerate triangle in store. + if (_al_list_size(vertices) < 3) + return result; + + // Get points. + v0 = (float*)_al_list_item_data(prev); + v1 = (float*)_al_list_item_data(item); + v2 = (float*)_al_list_item_data(next); + + // Compute the cross product between the two edges + cross = (v0[0] - v1[0]) * (v2[1] - v1[1]) - (v0[1] - v1[1]) * (v2[0] - v1[0]); + +# if POLY_DEBUG + if (g_poly_debug_step == g_poly_debug_step_current) { + + float step = 0.25f * 0.0f; + + float dir0[2] = { v0[0] - v1[0], v0[1] - v1[1] }; + float dir2[2] = { v2[0] - v1[0], v2[1] - v1[1] }; + + POLY_DEBUG_TEXT(v1[0], v1[1], "%d", cross > 0); + + al_draw_line(v1[0], v1[1], v1[0] + dir0[0] * step, v1[1] + dir0[1] * step, al_map_rgb(255, 0, 0), 4.0f * g_poly_debug_scale); + al_draw_line(v1[0], v1[1], v1[0] + dir2[0] * step, v1[1] + dir2[1] * step, al_map_rgb(255, 0, 0), 4.0f * g_poly_debug_scale); + } +# endif + + // If internal angle is less than 180 degrees then we may + // have an ear clip vertex, otherwise we have reflex. + if (cross >= 0) + { + if (flags & POLY_VERTEX_ATTR_EAR_CLIP) + { + _AL_LIST_ITEM* start; + _AL_LIST* search_list; + size_t size; + + if (reflex) { + + search_list = reflex; + size = _al_list_size(search_list); + start = _al_list_front(reflex); + } + else { + search_list = vertices; + size = _al_list_size(search_list) - 3; + start = _al_list_next_circular(search_list, next); + } + + // Check for ear vertex. + point = start; + for (i = 0; i < size; ++i, point = _al_list_next_circular(search_list, point)) { + + float* v; + + // TODO: optimize this by removing if + if (search_list == reflex) + v = (float*)_al_list_item_data((_AL_LIST_ITEM*)_al_list_item_data(point)); + else + v = (float*)_al_list_item_data(point); + + // Ignore vertices which belong to the triangle. + if ((v == v0) || (v == v1) || (v == v2)) + continue; + + // Set point to NULL if we find any point inside the triangle. + if (_al_prim_is_point_in_triangle(v, v0, v1, v2)) { + point = NULL; + break; + } + } + + // If point is not NULL, we have ear vertex. + if ((NULL != point) || _al_list_is_empty(search_list)) + result |= POLY_VERTEX_ATTR_EAR_CLIP; + } + } + else if (flags & POLY_VERTEX_ATTR_REFLEX) + result |= POLY_VERTEX_ATTR_REFLEX; + + return result; +} + + +/* + * Classify all vertices into reflex or ear group. + * + * One of target group may be NULL so it will be simply ignored. + */ +static void poly_classify_vertices(_AL_LIST* vertices, _AL_LIST* reflex, _AL_LIST* ear) +{ + poly_classify_vertices_in_range(_al_list_front(vertices), NULL, vertices, reflex, ear); +} + + +/* + * Classify selected range of vertices [begin, end) into + * reflex or ear group. + * + * One of target group may be NULL so it will be simply ignored. + */ +static void poly_classify_vertices_in_range(_AL_LIST_ITEM* begin, _AL_LIST_ITEM* end, _AL_LIST* vertices, _AL_LIST* reflex, _AL_LIST* ear) +{ + _AL_LIST_ITEM* item = NULL; + int attribute_mask = 0; + + if (NULL != ear) + attribute_mask |= POLY_VERTEX_ATTR_EAR_CLIP; + + if (NULL != reflex) + attribute_mask |= POLY_VERTEX_ATTR_REFLEX; + + for (item = begin; item != end; item = _al_list_next(vertices, item)) + { + int attr = poly_compute_vertex_attributes(vertices, item, attribute_mask, NULL); + + if (0 == attr) + continue; + + if (attr & POLY_VERTEX_ATTR_EAR_CLIP) + _al_list_push_back(ear, item); + + if (attr & POLY_VERTEX_ATTR_REFLEX) + _al_list_push_back(reflex, item); + } +} + + +/* + * Reclassify vertex. After triangle was emitted one vertex + * is removed from the list. Two neighbor vertices may + * change their attributes. In this place we have general + * function which update lists to match new attributes + * of provided vertex. + */ +static void poly_update_vertex_attributes(_AL_LIST* vertices, _AL_LIST* reflex, _AL_LIST* ear, _AL_LIST_ITEM* vertex) +{ + _AL_LIST_ITEM* item; + + int attr = poly_compute_vertex_attributes(vertices, vertex, POLY_VERTEX_ATTR_ALL, reflex); + + // Update reflex list only if an attribute change. + item = _al_list_find_first(reflex, vertex); + if (attr & POLY_VERTEX_ATTR_REFLEX) { + + if (NULL == item) + _al_list_push_back(reflex, vertex); + + _al_list_remove(ear, vertex); + } + else { + + if (NULL != item) + _al_list_erase(reflex, item); + + item = _al_list_find_first(ear, vertex); + if (attr & POLY_VERTEX_ATTR_EAR_CLIP) { + + if (NULL == item) + _al_list_push_front(ear, vertex); + } + else { + + if (NULL != item) + _al_list_erase(ear, item); + } + } +} + + +/* + * Triangulator iterate trough list of ear vertices + * and clip isolated triangles. This process repeats + * until there are ear vertices. + */ +static void poly_do_triangulate(POLY* polygon) +{ +# define VERTEX_INDEX(vertex) ((((uint8_t*)vertex) - ((uint8_t*)polygon->vertex_buffer)) / polygon->vertex_stride) + +# if POLY_DEBUG + g_poly_debug_step_current = 0; + + { + _AL_LIST_ITEM* item; + _AL_LIST_ITEM* next; + int* histogram = al_calloc(_al_list_size(polygon->vertex_list), sizeof(int)); + + /*std::map<float*, int> histogram;*/ + + int index = 0; + for (item = _al_list_front(polygon->vertex_list); item; item = _al_list_next(polygon->vertex_list, item)) { + + float* point0; + float* point1; + float n[2]; + float l, r; + char status[3] = { 0 }; + int status_index = 0; + + next = _al_list_next_circular(polygon->vertex_list, item); + + point0 = (float*)_al_list_item_data(item); + point1 = (float*)_al_list_item_data(next); + + n[0] = -(point1[1] - point0[1]); + n[1] = point1[0] - point0[0]; + + l = 2.0f * sqrtf(n[0] * n[0] + n[1] * n[1]); + + n[0] /= l; + n[1] /= l; + + r = 1.0f * 0.0f; + + al_draw_line(point0[0] + n[0] * r, point0[1] + n[1] * r, point1[0] + n[0] * r, point1[1] + n[1] * r, al_map_rgba(255, 0, 255, 128), r * g_poly_debug_scale); + + if (_al_list_contains(polygon->reflex_list, item)) + status[status_index++] = 'R'; + if (_al_list_contains(polygon->ear_list, item)) + status[status_index++] = 'E'; + + POLY_DEBUG_TEXT_LINE(point0[0], point0[1], -histogram[VERTEX_INDEX(point0)], "%s %d", status, index++); + + ++histogram[VERTEX_INDEX(point0)]; + } + + al_free(histogram); + } +# endif + + // Repeat until there are ear clips. + while (!_al_list_is_empty(polygon->ear_list)) { + + _AL_LIST_ITEM* ear_item; + _AL_LIST_ITEM* vertex_item; + _AL_LIST_ITEM* next; + _AL_LIST_ITEM* prev; + float* v0; + float* v1; + float* v2; + + // Get point and corresponding item on polygon->vertex_list list. + ear_item = _al_list_front(polygon->ear_list); + vertex_item = (_AL_LIST_ITEM*)_al_list_item_data(ear_item); + prev = _al_list_previous_circular(polygon->vertex_list, vertex_item); + next = _al_list_next_circular(polygon->vertex_list, vertex_item); + v0 = (float*)_al_list_item_data(prev); + v1 = (float*)_al_list_item_data(vertex_item); + v2 = (float*)_al_list_item_data(next); + +# if POLY_DEBUG + if (g_poly_debug_step == g_poly_debug_step_current) { + _AL_LIST_ITEM* item; + ALLEGRO_COLOR color; + int second = 0; + + al_draw_filled_triangle(v0[0], v0[1], v1[0], v1[1], v2[0], v2[1], al_map_rgba(0, 0, 255, 64)); + + for (item = _al_list_front(polygon->vertex_list); item; item = _al_list_next(polygon->vertex_list, item)) { + + float* point = (float*)_al_list_item_data(item); + al_draw_filled_circle(point[0], point[1], 6.0f * g_poly_debug_scale, al_map_rgb(255, 255, 255)); + } + + for (item = _al_list_front(polygon->reflex_list); item; item = _al_list_next(polygon->reflex_list, item)) { + + float* point = (float*)_al_list_item_data((_AL_LIST_ITEM*)_al_list_item_data(item)); + + al_draw_filled_circle(point[0], point[1], 6.0f * g_poly_debug_scale, al_map_rgb(255, 255, 0)); + } + + color = al_map_rgb(255, 0, 0); + second = _al_list_size(polygon->ear_list) - 1; + for (item = _al_list_back(polygon->ear_list); item; item = _al_list_previous(polygon->ear_list, item), --second) { + + float* point = (float*)_al_list_item_data((_AL_LIST_ITEM*)_al_list_item_data(item)); + + if (second == 0) + color = al_map_rgb(0, 255, 0); + else if (second == 1) + color = al_map_rgb(0, 0, 255); + + al_draw_circle(point[0], point[1], 9.0f * g_poly_debug_scale, color, 2.0f * g_poly_debug_scale); + } + } + if (g_poly_debug_step >= 0 && g_poly_debug_step_current >= g_poly_debug_step) + break; + g_poly_debug_step_current++; +# endif + + // Emit triangle. + polygon->emit(VERTEX_INDEX(v0), VERTEX_INDEX(v1), VERTEX_INDEX(v2), polygon->userdata); + + // Remove polygon->ear_list clip from all lists. + _al_list_erase(polygon->ear_list, ear_item); + _al_list_erase(polygon->vertex_list, vertex_item); + _al_list_erase(polygon->reflex_list, _al_list_find_first(polygon->reflex_list, vertex_item)); + + // Update attributes of corner vertices. + poly_update_vertex_attributes(polygon->vertex_list, polygon->reflex_list, polygon->ear_list, prev); + poly_update_vertex_attributes(polygon->vertex_list, polygon->reflex_list, polygon->ear_list, next); + } + +# undef VERTEX_INDEX +} + + +/* Function: al_triangulate_polygon + * General triangulation function. + */ +bool al_triangulate_polygon( + const float* vertices, size_t vertex_stride, const int* vertex_counts, + void (*emit_triangle)(int, int, int, void*), void* userdata) +{ + POLY polygon; + int vertex_count; + int split_count; + int *splits; + int i; + bool ret; + + for (i = 0; vertex_counts[i] > 0; i++) { + /* do nothing */ + } + ASSERT(i > 0); + split_count = i; + + splits = malloc(split_count * sizeof(int)); + if (!splits) { + return false; + } + vertex_count = 0; + for (i = 0; i < split_count; i++) { + vertex_count += vertex_counts[i]; + splits[i] = vertex_count; + } + + memset(&polygon, 0, sizeof(polygon)); + polygon.vertex_buffer = vertices; + polygon.vertex_stride = vertex_stride; + polygon.vertex_count = vertex_count; + polygon.split_indices = splits; + polygon.split_stride = sizeof(int); /* XXX can simplify code now */ + polygon.split_count = split_count; + polygon.emit = emit_triangle; + polygon.userdata = userdata; + + if (poly_initialize(&polygon)) { + + poly_do_triangulate(&polygon); + + _al_list_destroy(polygon.vertex_list); + _al_list_destroy(polygon.reflex_list); + _al_list_destroy(polygon.ear_list); + + ret = true; + } + else { + ret = false; + } + + free(splits); + + return ret; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/ttf/CMakeLists.txt b/allegro/addons/ttf/CMakeLists.txt new file mode 100644 index 00000000..43974e58 --- /dev/null +++ b/allegro/addons/ttf/CMakeLists.txt @@ -0,0 +1,27 @@ +include_directories(../font) +include_directories(SYSTEM ${FREETYPE_INCLUDE_DIRS}) + +set(TTF_SOURCES ttf.c) + +set(TTF_INCLUDE_FILES allegro5/allegro_ttf.h) + +set_our_header_properties(${TTF_INCLUDE_FILES}) + +configure_file( + allegro5/internal/aintern_ttf_cfg.h.cmake + ${PROJECT_BINARY_DIR}/include/allegro5/internal/aintern_ttf_cfg.h + ) + +add_our_addon_library(allegro_ttf + AllegroTTF-${ALLEGRO_SOVERSION} + "${TTF_SOURCES};${TTF_INCLUDE_FILES}" + "-DALLEGRO_TTF_SRC" + "${FONT_LINK_WITH};${TTF_LIBRARIES}" + ) + +install_our_headers(${TTF_INCLUDE_FILES}) + +add_addon(ttf) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/ttf/allegro5/allegro_ttf.h b/allegro/addons/ttf/allegro5/allegro_ttf.h new file mode 100644 index 00000000..ce8a7106 --- /dev/null +++ b/allegro/addons/ttf/allegro5/allegro_ttf.h @@ -0,0 +1,50 @@ +#ifndef __al_included_allegro5_allegro_ttf_h +#define __al_included_allegro5_allegro_ttf_h + +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define ALLEGRO_TTF_NO_KERNING 1 +#define ALLEGRO_TTF_MONOCHROME 2 +#define ALLEGRO_TTF_NO_AUTOHINT 4 + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_TTF_SRC + #define _ALLEGRO_TTF_DLL __declspec(dllexport) + #else + #define _ALLEGRO_TTF_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_TTF_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_TTF_FUNC(type, name, args) _ALLEGRO_TTF_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_TTF_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_TTF_FUNC(type, name, args) extern _ALLEGRO_TTF_DLL type name args +#else + #define ALLEGRO_TTF_FUNC AL_FUNC +#endif + +ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font, (char const *filename, int size, int flags)); +ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_f, (ALLEGRO_FILE *file, char const *filename, int size, int flags)); +ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_stretch, (char const *filename, int w, int h, int flags)); +ALLEGRO_TTF_FUNC(ALLEGRO_FONT *, al_load_ttf_font_stretch_f, (ALLEGRO_FILE *file, char const *filename, int w, int h, int flags)); +ALLEGRO_TTF_FUNC(bool, al_init_ttf_addon, (void)); +ALLEGRO_TTF_FUNC(bool, al_is_ttf_addon_initialized, (void)); +ALLEGRO_TTF_FUNC(void, al_shutdown_ttf_addon, (void)); +ALLEGRO_TTF_FUNC(uint32_t, al_get_allegro_ttf_version, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/addons/ttf/allegro5/internal/aintern_ttf_cfg.h.cmake b/allegro/addons/ttf/allegro5/internal/aintern_ttf_cfg.h.cmake new file mode 100644 index 00000000..48072f23 --- /dev/null +++ b/allegro/addons/ttf/allegro5/internal/aintern_ttf_cfg.h.cmake @@ -0,0 +1 @@ +#cmakedefine ALLEGRO_CFG_TTF_FREETYPE diff --git a/allegro/addons/ttf/ttf.c b/allegro/addons/ttf/ttf.c new file mode 100644 index 00000000..c681b9c7 --- /dev/null +++ b/allegro/addons/ttf/ttf.c @@ -0,0 +1,1172 @@ +#define ALLEGRO_INTERNAL_UNSTABLE + +#include "allegro5/allegro.h" +#ifdef ALLEGRO_CFG_OPENGL +#include "allegro5/allegro_opengl.h" +#endif +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_vector.h" + +#include "allegro5/allegro_ttf.h" +#include "allegro5/internal/aintern_font.h" +#include "allegro5/internal/aintern_ttf_cfg.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_exitfunc.h" + +#include <ft2build.h> +#include FT_FREETYPE_H + +#include <stdlib.h> + +ALLEGRO_DEBUG_CHANNEL("font") + + +/* Some low-end drivers enable automatic S3TC compression, which + * requires glTexSubImage2D to only work on multiples of aligned + * 4x4 pixel blocks with some buggy OpenGL drivers. + * There's not much we can do about that in general - if the user + * locks a portion of a bitmap not conformin to this it will fail + * with such a driver. + * + * However in many programs this is no problem at all safe for rendering + * glyphs and simply aligning to 4 pixels here fixes it. + */ +#define ALIGN_TO_4_PIXEL + + +#define RANGE_SIZE 128 + + +typedef struct REGION +{ + short x; + short y; + short w; + short h; +} REGION; + + +typedef struct ALLEGRO_TTF_GLYPH_DATA +{ + ALLEGRO_BITMAP *page_bitmap; + REGION region; + short offset_x; + short offset_y; + short advance; +} ALLEGRO_TTF_GLYPH_DATA; + + +typedef struct ALLEGRO_TTF_GLYPH_RANGE +{ + int32_t range_start; + ALLEGRO_TTF_GLYPH_DATA *glyphs; /* [RANGE_SIZE] */ +} ALLEGRO_TTF_GLYPH_RANGE; + + +typedef struct ALLEGRO_TTF_FONT_DATA +{ + FT_Face face; + int flags; + _AL_VECTOR glyph_ranges; /* sorted array of of ALLEGRO_TTF_GLYPH_RANGE */ + + _AL_VECTOR page_bitmaps; /* of ALLEGRO_BITMAP pointers */ + int page_pos_x; + int page_pos_y; + int page_line_height; + ALLEGRO_LOCKED_REGION *page_lr; + + FT_StreamRec stream; + ALLEGRO_FILE *file; + unsigned long base_offset; + unsigned long offset; + + int bitmap_format; + int bitmap_flags; + + int min_page_size; + int max_page_size; + + bool skip_cache_misses; +} ALLEGRO_TTF_FONT_DATA; + + +/* globals */ +static bool ttf_inited; +static FT_Library ft; +static ALLEGRO_FONT_VTABLE vt; + + +static INLINE int align4(int x) +{ +#ifdef ALIGN_TO_4_PIXEL + return (x + 3) & ~3; +#else + return x; +#endif +} + + +/* Returns false if the glyph is invalid. + */ +static bool get_glyph(ALLEGRO_TTF_FONT_DATA *data, + int ft_index, ALLEGRO_TTF_GLYPH_DATA **glyph) +{ + ALLEGRO_TTF_GLYPH_RANGE *range; + int32_t range_start; + int lo, hi, mid; + ASSERT(glyph); + + range_start = ft_index - (ft_index % RANGE_SIZE); + + /* Binary search for the range. */ + lo = 0; + hi = _al_vector_size(&data->glyph_ranges); + mid = (hi + lo)/2; + range = NULL; + + while (lo < hi) { + ALLEGRO_TTF_GLYPH_RANGE *r = _al_vector_ref(&data->glyph_ranges, mid); + if (r->range_start == range_start) { + range = r; + break; + } + else if (r->range_start < range_start) { + lo = mid + 1; + } + else { + hi = mid; + } + mid = (hi + lo)/2; + } + + if (!range) { + range = _al_vector_alloc_mid(&data->glyph_ranges, mid); + range->range_start = range_start; + range->glyphs = al_calloc(RANGE_SIZE, sizeof(ALLEGRO_TTF_GLYPH_DATA)); + } + + *glyph = &range->glyphs[ft_index - range_start]; + + /* If we're skipping cache misses and it isn't already cached, return it as invalid. */ + if (data->skip_cache_misses && !(*glyph)->page_bitmap && (*glyph)->region.x >= 0) { + return false; + } + + return ft_index != 0; +} + + +static void unlock_current_page(ALLEGRO_TTF_FONT_DATA *data) +{ + if (data->page_lr) { + ALLEGRO_BITMAP **back = _al_vector_ref_back(&data->page_bitmaps); + ASSERT(al_is_bitmap_locked(*back)); + al_unlock_bitmap(*back); + data->page_lr = NULL; + ALLEGRO_DEBUG("Unlocking page: %p\n", *back); + } +} + + +static ALLEGRO_BITMAP *push_new_page(ALLEGRO_TTF_FONT_DATA *data, int glyph_size) +{ + ALLEGRO_BITMAP **back; + ALLEGRO_BITMAP *page; + ALLEGRO_STATE state; + int page_size = 1; + /* 16 seems to work well. A particular problem are fixed width fonts which + * take an inordinate amount of space. */ + while (page_size < 16 * glyph_size) { + page_size *= 2; + } + if (page_size < data->min_page_size) { + page_size = data->min_page_size; + } + if (page_size > data->max_page_size) { + page_size = data->max_page_size; + } + if (glyph_size > page_size) { + ALLEGRO_ERROR("Unable create new page, glyph too large: %d > %d\n", + glyph_size, page_size); + return NULL; + } + + unlock_current_page(data); + + /* The bitmap will be destroyed when the parent font is destroyed so + * it is not safe to register a destructor for it. + */ + _al_push_destructor_owner(); + al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); + al_set_new_bitmap_format(data->bitmap_format); + al_set_new_bitmap_flags(data->bitmap_flags); + page = al_create_bitmap(page_size, page_size); + al_restore_state(&state); + _al_pop_destructor_owner(); + + if (page) { + back = _al_vector_alloc_back(&data->page_bitmaps); + *back = page; + + data->page_pos_x = 0; + data->page_pos_y = 0; + data->page_line_height = 0; + } + + return page; +} + + +static unsigned char *alloc_glyph_region(ALLEGRO_TTF_FONT_DATA *data, + int ft_index, int w, int h, bool new, ALLEGRO_TTF_GLYPH_DATA *glyph, + bool lock_whole_page) +{ + ALLEGRO_BITMAP *page; + int w4 = align4(w); + int h4 = align4(h); + int glyph_size = w4 > h4 ? w4 : h4; + bool lock = false; + + if (_al_vector_is_empty(&data->page_bitmaps) || new) { + page = push_new_page(data, glyph_size); + if (!page) { + ALLEGRO_ERROR("Failed to create a new page for glyph %d.\n", ft_index); + return NULL; + } + } + else { + ALLEGRO_BITMAP **back = _al_vector_ref_back(&data->page_bitmaps); + page = *back; + } + + ALLEGRO_DEBUG("Glyph %d: %dx%d (%dx%d)%s\n", + ft_index, w, h, w4, h4, new ? " new" : ""); + + if (data->page_pos_x + w4 > al_get_bitmap_width(page)) { + data->page_pos_y += data->page_line_height; + data->page_pos_y = align4(data->page_pos_y); + data->page_pos_x = 0; + data->page_line_height = 0; + } + + if (data->page_pos_y + h4 > al_get_bitmap_height(page)) { + return alloc_glyph_region(data, ft_index, w, h, true, glyph, lock_whole_page); + } + + glyph->page_bitmap = page; + glyph->region.x = data->page_pos_x; + glyph->region.y = data->page_pos_y; + glyph->region.w = w; + glyph->region.h = h; + + data->page_pos_x = align4(data->page_pos_x + w4); + if (h > data->page_line_height) { + data->page_line_height = h4; + } + + REGION lock_rect; + if (lock_whole_page) { + lock_rect.x = 0; + lock_rect.y = 0; + lock_rect.w = al_get_bitmap_width(page); + lock_rect.h = al_get_bitmap_height(page); + if (!data->page_lr) { + lock = true; + ALLEGRO_DEBUG("Locking whole page: %p\n", page); + } + } + else { + /* Unlock just in case... */ + unlock_current_page(data); + lock_rect.x = glyph->region.x; + lock_rect.y = glyph->region.y; + lock_rect.w = w4; + lock_rect.h = h4; + lock = true; + ALLEGRO_DEBUG("Locking glyph region: %p %d %d %d %d\n", page, + lock_rect.x, lock_rect.y, lock_rect.w, lock_rect.h); + } + + if (lock) { + char *ptr; + int i; + + data->page_lr = al_lock_bitmap_region(page, + lock_rect.x, lock_rect.y, lock_rect.w, lock_rect.h, + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); + + if (!data->page_lr) { + ALLEGRO_ERROR("Failed to lock page.\n"); + return NULL; + } + + /* Clear the data so we don't get garbage when using filtering + * FIXME We could clear just the border but I'm not convinced that + * would be faster (yet) + */ + for (i = 0; i < lock_rect.h; i++) { + ptr = (char *)(data->page_lr->data) + (i * data->page_lr->pitch); + memset(ptr, 0, lock_rect.w * 4); + } + } + + ASSERT(data->page_lr); + + /* Copy a displaced pointer for the glyph. */ + return (unsigned char *)data->page_lr->data + + ((glyph->region.y + 1) - lock_rect.y) * data->page_lr->pitch + + ((glyph->region.x + 1) - lock_rect.x) * sizeof(int32_t); +} + + +static void copy_glyph_mono(ALLEGRO_TTF_FONT_DATA *font_data, FT_Face face, + unsigned char *glyph_data) +{ + int pitch = font_data->page_lr->pitch; + int x, y; + + for (y = 0; y < (int)face->glyph->bitmap.rows; y++) { + unsigned char const *ptr = face->glyph->bitmap.buffer + face->glyph->bitmap.pitch * y; + unsigned char *dptr = glyph_data + pitch * y; + int bit = 0; + + if (font_data->flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA) { + for (x = 0; x < (int)face->glyph->bitmap.width; x++) { + unsigned char set = ((*ptr >> (7-bit)) & 1) ? 255 : 0; + *dptr++ = 255; + *dptr++ = 255; + *dptr++ = 255; + *dptr++ = set; + bit = (bit + 1) & 7; + if (bit == 0) { + ptr++; + } + } + } + else { + for (x = 0; x < (int)face->glyph->bitmap.width; x++) { + unsigned char set = ((*ptr >> (7-bit)) & 1) ? 255 : 0; + *dptr++ = set; + *dptr++ = set; + *dptr++ = set; + *dptr++ = set; + bit = (bit + 1) & 7; + if (bit == 0) { + ptr++; + } + } + } + } +} + + +static void copy_glyph_color(ALLEGRO_TTF_FONT_DATA *font_data, FT_Face face, + unsigned char *glyph_data) +{ + int pitch = font_data->page_lr->pitch; + int x, y; + + for (y = 0; y < (int)face->glyph->bitmap.rows; y++) { + unsigned char const *ptr = face->glyph->bitmap.buffer + face->glyph->bitmap.pitch * y; + unsigned char *dptr = glyph_data + pitch * y; + + if (font_data->flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA) { + for (x = 0; x < (int)face->glyph->bitmap.width; x++) { + unsigned char c = *ptr; + *dptr++ = 255; + *dptr++ = 255; + *dptr++ = 255; + *dptr++ = c; + ptr++; + } + } + else { + for (x = 0; x < (int)face->glyph->bitmap.width; x++) { + unsigned char c = *ptr; + *dptr++ = c; + *dptr++ = c; + *dptr++ = c; + *dptr++ = c; + ptr++; + } + } + } +} + + +/* NOTE: this function may disable the bitmap hold drawing state + * and leave the current page bitmap locked. + * + * NOTE: We have previously tried to be more clever about caching multiple + * glyphs during incidental cache misses, but found that approach to be slower. + */ +static void cache_glyph(ALLEGRO_TTF_FONT_DATA *font_data, FT_Face face, + int ft_index, ALLEGRO_TTF_GLYPH_DATA *glyph, bool lock_whole_page) +{ + FT_Int32 ft_load_flags; + FT_Error e; + int w, h; + unsigned char *glyph_data; + + if (glyph->page_bitmap || glyph->region.x < 0) + return; + + /* We shouldn't ever get here, as cache misses + * should have been set to ft_index = 0. */ + ASSERT(!(font_data->skip_cache_misses && !lock_whole_page)); + + // FIXME: make this a config setting? FT_LOAD_FORCE_AUTOHINT + + // FIXME: Investigate why some fonts don't work without the + // NO_BITMAP flags. Supposedly using that flag makes small sizes + // look bad so ideally we would not used it. + ft_load_flags = FT_LOAD_RENDER | FT_LOAD_NO_BITMAP; + if (font_data->flags & ALLEGRO_TTF_MONOCHROME) + ft_load_flags |= FT_LOAD_TARGET_MONO; + if (font_data->flags & ALLEGRO_TTF_NO_AUTOHINT) + ft_load_flags |= FT_LOAD_NO_AUTOHINT; + + e = FT_Load_Glyph(face, ft_index, ft_load_flags); + if (e) { + ALLEGRO_WARN("Failed loading glyph %d from.\n", ft_index); + } + + glyph->offset_x = face->glyph->bitmap_left; + glyph->offset_y = (face->size->metrics.ascender >> 6) - face->glyph->bitmap_top; + glyph->advance = face->glyph->advance.x >> 6; + + w = face->glyph->bitmap.width; + h = face->glyph->bitmap.rows; + + if (w == 0 || h == 0) { + /* Mark this glyph so we won't try to cache it next time. */ + glyph->region.x = -1; + glyph->region.y = -1; + ALLEGRO_DEBUG("Glyph %d has zero size.\n", ft_index); + return; + } + + /* Each glyph has a 1-pixel border all around. Note: The border is kept + * even against the outer bitmap edge, to ensure consistent rendering. + */ + glyph_data = alloc_glyph_region(font_data, ft_index, + w + 2, h + 2, false, glyph, lock_whole_page); + + if (glyph_data == NULL) { + return; + } + + if (font_data->flags & ALLEGRO_TTF_MONOCHROME) + copy_glyph_mono(font_data, face, glyph_data); + else + copy_glyph_color(font_data, face, glyph_data); + + if (!lock_whole_page) { + unlock_current_page(font_data); + } +} + +/* WARNING: It is only valid to call this function when the current page is empty + * (or already locked), otherwise it will gibberify the current glyphs on that page. + * + * This leaves the current page unlocked. + */ +static void cache_glyphs(ALLEGRO_TTF_FONT_DATA *data, const char *text, size_t text_size) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR* ustr = al_ref_buffer(&info, text, text_size); + FT_Face face = data->face; + int pos = 0; + int32_t ch; + + while ((ch = al_ustr_get_next(ustr, &pos)) >= 0) { + ALLEGRO_TTF_GLYPH_DATA *glyph; + int ft_index = FT_Get_Char_Index(face, ch); + get_glyph(data, ft_index, &glyph); + cache_glyph(data, face, ft_index, glyph, true); + } +} + + +static int get_kerning(ALLEGRO_TTF_FONT_DATA const *data, FT_Face face, + int prev_ft_index, int ft_index) +{ + /* Do kerning? */ + if (!(data->flags & ALLEGRO_TTF_NO_KERNING) && prev_ft_index != -1) { + FT_Vector delta; + FT_Get_Kerning(face, prev_ft_index, ft_index, + FT_KERNING_DEFAULT, &delta); + return delta.x >> 6; + } + + return 0; +} + + +static bool ttf_get_glyph_worker(ALLEGRO_FONT const *f, int prev_ft_index, int ft_index, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *info) +{ + ALLEGRO_TTF_FONT_DATA *data = f->data; + FT_Face face = data->face; + ALLEGRO_TTF_GLYPH_DATA *glyph; + int advance = 0; + + if (!get_glyph(data, ft_index, &glyph)) { + if (f->fallback) + return f->fallback->vtable->get_glyph(f->fallback, prev_codepoint, codepoint, info); + else { + get_glyph(data, 0, &glyph); + ft_index = 0; + } + } + + cache_glyph(data, face, ft_index, glyph, false); + + advance += get_kerning(data, face, prev_ft_index, ft_index); + + if (glyph->page_bitmap) { + info->bitmap = glyph->page_bitmap; + info->x = glyph->region.x + 1; + info->y = glyph->region.y + 1; + info->w = glyph->region.w - 2; + info->h = glyph->region.h - 2; + info->kerning = advance; + info->offset_x = glyph->offset_x; + info->offset_y = glyph->offset_y; + } + else if (glyph->region.x > 0) { + ALLEGRO_ERROR("Glyph %d not on any page.\n", ft_index); + return false; + } + else { + info->bitmap = 0; + } + + advance += glyph->advance; + + info->advance = advance; + + return true; +} + + +static bool ttf_get_glyph(ALLEGRO_FONT const *f, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *glyph) +{ + ALLEGRO_TTF_FONT_DATA *data = f->data; + FT_Face face = data->face; + int prev_ft_index = (prev_codepoint == -1) ? -1 : (int)FT_Get_Char_Index(face, prev_codepoint); + int ft_index = FT_Get_Char_Index(face, codepoint); + return ttf_get_glyph_worker(f, prev_ft_index, ft_index, prev_codepoint, codepoint, glyph); +} + + +static int render_glyph(ALLEGRO_FONT const *f, ALLEGRO_COLOR color, + int prev_ft_index, int ft_index, int32_t prev_ch, int32_t ch, float xpos, float ypos) +{ + ALLEGRO_GLYPH glyph; + + if (ttf_get_glyph_worker(f, prev_ft_index, ft_index, prev_ch, ch, &glyph) == false) + return 0; + + if (glyph.bitmap != NULL) { + al_draw_tinted_bitmap_region( + glyph.bitmap, color, + glyph.x, glyph.y, glyph.w, glyph.h, + xpos + glyph.offset_x + glyph.kerning, + ypos + glyph.offset_y, + 0 + ); + } + + return glyph.advance; +} + + +static int ttf_font_height(ALLEGRO_FONT const *f) +{ + ASSERT(f); + return f->height; +} + + +static int ttf_font_ascent(ALLEGRO_FONT const *f) +{ + ALLEGRO_TTF_FONT_DATA *data; + FT_Face face; + + ASSERT(f); + + data = f->data; + face = data->face; + + return face->size->metrics.ascender >> 6; +} + + +static int ttf_font_descent(ALLEGRO_FONT const *f) +{ + ALLEGRO_TTF_FONT_DATA *data; + FT_Face face; + + ASSERT(f); + + data = f->data; + face = data->face; + + return (-face->size->metrics.descender) >> 6; +} + + +static int ttf_render_char(ALLEGRO_FONT const *f, ALLEGRO_COLOR color, + int ch, float xpos, float ypos) +{ + ALLEGRO_TTF_FONT_DATA *data = f->data; + FT_Face face = data->face; + int advance = 0; + int32_t ch32 = (int32_t) ch; + + int ft_index = FT_Get_Char_Index(face, ch32); + advance = render_glyph(f, color, -1, ft_index, -1, ch, xpos, ypos); + + return advance; +} + + +static int ttf_char_length(ALLEGRO_FONT const *f, int ch) +{ + int result; + ALLEGRO_TTF_FONT_DATA *data = f->data; + ALLEGRO_TTF_GLYPH_DATA *glyph; + FT_Face face = data->face; + int ft_index = FT_Get_Char_Index(face, ch); + if (!get_glyph(data, ft_index, &glyph)) { + if (f->fallback) { + return al_get_glyph_width(f, ch); + } + else { + get_glyph(data, 0, &glyph); + ft_index = 0; + } + } + cache_glyph(data, face, ft_index, glyph, false); + result = glyph->region.w - 2; + + return result; +} + + +static int ttf_render(ALLEGRO_FONT const *f, ALLEGRO_COLOR color, + const ALLEGRO_USTR *text, float x, float y) +{ + ALLEGRO_TTF_FONT_DATA *data = f->data; + FT_Face face = data->face; + int pos = 0; + int advance = 0; + int prev_ft_index = -1; + int32_t prev_ch = -1; + int32_t ch; + bool hold; + + hold = al_is_bitmap_drawing_held(); + al_hold_bitmap_drawing(true); + + while ((ch = al_ustr_get_next(text, &pos)) >= 0) { + int ft_index = FT_Get_Char_Index(face, ch); + advance += render_glyph(f, color, prev_ft_index, ft_index, prev_ch, ch, + x + advance, y); + prev_ft_index = ft_index; + prev_ch = ch; + } + + al_hold_bitmap_drawing(hold); + + return advance; +} + + +static int ttf_text_length(ALLEGRO_FONT const *f, const ALLEGRO_USTR *text) +{ + int pos = 0; + int x = 0; + int32_t ch, nch; + + nch = al_ustr_get_next(text, &pos); + while (nch >= 0) { + ch = nch; + nch = al_ustr_get_next(text, &pos); + + x += al_get_glyph_advance(f, ch, nch < 0 ? + ALLEGRO_NO_KERNING : nch); + } + + return x; +} + + +static void ttf_get_text_dimensions(ALLEGRO_FONT const *f, + ALLEGRO_USTR const *text, + int *bbx, int *bby, int *bbw, int *bbh) +{ + int pos = 0; + bool first = true; + int x = 0; + int32_t ch, nch; + int ymin = f->height; + int ymax = 0; + *bbx = 0; + + nch = al_ustr_get_next(text, &pos); + while (nch >= 0) { + int gx, gy, gw, gh; + ch = nch; + nch = al_ustr_get_next(text, &pos); + if (!al_get_glyph_dimensions(f, ch, &gx, &gy, &gw, &gh)) { + continue; + } + + if (nch < 0) { + x += gx + gw; + } + else { + x += al_get_glyph_advance(f, ch, nch); + } + + if (gy < ymin) { + ymin = gy; + } + + if (gh+gy > ymax) { + ymax = gh + gy; + } + + if (first) { + *bbx = gx; + first = false; + } + } + + *bby = ymin; + *bbw = x - *bbx; + *bbh = ymax - ymin; +} + + +#ifdef DEBUG_CACHE +#include "allegro5/allegro_image.h" +static void debug_cache(ALLEGRO_FONT *f) +{ + ALLEGRO_TTF_FONT_DATA *data = f->data; + _AL_VECTOR *v = &data->page_bitmaps; + static int j = 0; + int i; + + al_init_image_addon(); + + for (i = 0; i < (int)_al_vector_size(v); i++) { + ALLEGRO_BITMAP **bmp = _al_vector_ref(v, i); + ALLEGRO_USTR *u = al_ustr_newf("font%d_%d.png", j, i); + al_save_bitmap(al_cstr(u), *bmp); + al_ustr_free(u); + } + j++; +} +#endif + + +static void ttf_destroy(ALLEGRO_FONT *f) +{ + ALLEGRO_TTF_FONT_DATA *data = f->data; + int i; + + unlock_current_page(data); + +#ifdef DEBUG_CACHE + debug_cache(f); +#endif + + FT_Done_Face(data->face); + for (i = _al_vector_size(&data->glyph_ranges) - 1; i >= 0; i--) { + ALLEGRO_TTF_GLYPH_RANGE *range = _al_vector_ref(&data->glyph_ranges, i); + al_free(range->glyphs); + } + _al_vector_free(&data->glyph_ranges); + for (i = _al_vector_size(&data->page_bitmaps) - 1; i >= 0; i--) { + ALLEGRO_BITMAP **bmp = _al_vector_ref(&data->page_bitmaps, i); + al_destroy_bitmap(*bmp); + } + _al_vector_free(&data->page_bitmaps); + al_free(data); + al_free(f); +} + + +static unsigned long ftread(FT_Stream stream, unsigned long offset, + unsigned char *buffer, unsigned long count) +{ + ALLEGRO_TTF_FONT_DATA *data = stream->pathname.pointer; + unsigned long bytes; + + if (count == 0) + return 0; + + if (offset != data->offset) + al_fseek(data->file, data->base_offset + offset, ALLEGRO_SEEK_SET); + bytes = al_fread(data->file, buffer, count); + data->offset = offset + bytes; + return bytes; +} + + +static void ftclose(FT_Stream stream) +{ + ALLEGRO_TTF_FONT_DATA *data = stream->pathname.pointer; + al_fclose(data->file); + data->file = NULL; +} + +/* Function: al_load_ttf_font_f + */ +ALLEGRO_FONT *al_load_ttf_font_f(ALLEGRO_FILE *file, + char const *filename, int size, int flags) +{ + return al_load_ttf_font_stretch_f(file, filename, 0, size, flags); +} + + +/* Function: al_load_ttf_font_stretch_f + */ +ALLEGRO_FONT *al_load_ttf_font_stretch_f(ALLEGRO_FILE *file, + char const *filename, int w, int h, int flags) +{ + FT_Face face; + ALLEGRO_TTF_FONT_DATA *data; + ALLEGRO_FONT *f; + ALLEGRO_PATH *path; + FT_Open_Args args; + int result; + ALLEGRO_CONFIG* system_cfg = al_get_system_config(); + const char* min_page_size_str = + al_get_config_value(system_cfg, "ttf", "min_page_size"); + const char* max_page_size_str = + al_get_config_value(system_cfg, "ttf", "max_page_size"); + const char* cache_str = + al_get_config_value(system_cfg, "ttf", "cache_text"); + const char* skip_cache_misses_str = + al_get_config_value(system_cfg, "ttf", "skip_cache_misses"); + + if ((h > 0 && w < 0) || (h < 0 && w > 0)) { + ALLEGRO_ERROR("Height/width have opposite signs (w = %d, h = %d).\n", w, h); + return NULL; + } + + data = al_calloc(1, sizeof *data); + data->stream.read = ftread; + data->stream.close = ftclose; + data->stream.pathname.pointer = data; + data->base_offset = al_ftell(file); + data->stream.size = al_fsize(file); + data->file = file; + data->bitmap_format = al_get_new_bitmap_format(); + data->bitmap_flags = al_get_new_bitmap_flags(); + data->min_page_size = 256; + data->max_page_size = 8192; + + if (min_page_size_str) { + int min_page_size = atoi(min_page_size_str); + if (min_page_size > 0) { + data->min_page_size = min_page_size; + } + } + + if (max_page_size_str) { + int max_page_size = atoi(max_page_size_str); + if (max_page_size > 0 && max_page_size >= data->min_page_size) { + data->max_page_size = max_page_size; + } + } + + if (skip_cache_misses_str && !strcmp(skip_cache_misses_str, "true")) { + data->skip_cache_misses = true; + } + + memset(&args, 0, sizeof args); + args.flags = FT_OPEN_STREAM; + args.stream = &data->stream; + + if ((result = FT_Open_Face(ft, &args, 0, &face)) != 0) { + ALLEGRO_ERROR("Reading %s failed. Freetype error code %d\n", filename, + result); + // Note: Freetype already closed the file for us. + al_free(data); + return NULL; + } + + // FIXME: The below doesn't use Allegro's streaming. + /* Small hack for Type1 fonts which store kerning information in + * a separate file - and we try to guess the name of that file. + */ + path = al_create_path(filename); + if (!strcmp(al_get_path_extension(path), ".pfa")) { + const char *helper; + ALLEGRO_DEBUG("Type1 font assumed for %s.\n", filename); + + al_set_path_extension(path, ".afm"); + helper = al_path_cstr(path, '/'); + FT_Attach_File(face, helper); + ALLEGRO_DEBUG("Guessed afm file %s.\n", helper); + + al_set_path_extension(path, ".tfm"); + helper = al_path_cstr(path, '/'); + FT_Attach_File(face, helper); + ALLEGRO_DEBUG("Guessed tfm file %s.\n", helper); + } + al_destroy_path(path); + + if (h > 0) { + FT_Set_Pixel_Sizes(face, w, h); + } + else { + /* Set the "real dimension" of the font to be the passed size, + * in pixels. + */ + FT_Size_RequestRec req; + ASSERT(w <= 0); + ASSERT(h <= 0); + req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; + req.width = (-w) << 6; + req.height = (-h) << 6; + req.horiResolution = 0; + req.vertResolution = 0; + FT_Request_Size(face, &req); + } + + ALLEGRO_DEBUG("Font %s loaded with pixel size %d x %d.\n", filename, + w, h); + ALLEGRO_DEBUG(" ascent=%.1f, descent=%.1f, height=%.1f\n", + face->size->metrics.ascender / 64.0, + face->size->metrics.descender / 64.0, + face->size->metrics.height / 64.0); + + data->face = face; + data->flags = flags; + + _al_vector_init(&data->glyph_ranges, sizeof(ALLEGRO_TTF_GLYPH_RANGE)); + _al_vector_init(&data->page_bitmaps, sizeof(ALLEGRO_BITMAP*)); + + if (data->skip_cache_misses) { + cache_glyphs(data, "\0", 1); + } + if (cache_str) { + cache_glyphs(data, cache_str, strlen(cache_str)); + } + unlock_current_page(data); + + f = al_calloc(sizeof *f, 1); + f->height = face->size->metrics.height >> 6; + f->vtable = &vt; + f->data = data; + + f->dtor_item = _al_register_destructor(_al_dtor_list, "ttf_font", f, + (void (*)(void *))al_destroy_font); + + return f; +} + + +/* Function: al_load_ttf_font + */ +ALLEGRO_FONT *al_load_ttf_font(char const *filename, int size, int flags) +{ + return al_load_ttf_font_stretch(filename, 0, size, flags); +} + + +/* Function: al_load_ttf_font_stretch + */ +ALLEGRO_FONT *al_load_ttf_font_stretch(char const *filename, int w, int h, + int flags) +{ + ALLEGRO_FILE *f; + ALLEGRO_FONT *font; + ASSERT(filename); + + f = al_fopen(filename, "rb"); + if (!f) { + ALLEGRO_ERROR("Unable to open file for reading: %s\n", filename); + return NULL; + } + + /* The file handle is owned by the function and the file is usually only + * closed when the font is destroyed, in case Freetype has to load data + * at a later time. + */ + font = al_load_ttf_font_stretch_f(f, filename, w, h, flags); + + return font; +} + + +static int ttf_get_font_ranges(ALLEGRO_FONT *font, int ranges_count, + int *ranges) +{ + ALLEGRO_TTF_FONT_DATA *data = font->data; + FT_UInt g; + FT_ULong unicode = FT_Get_First_Char(data->face, &g); + int i = 0; + if (i < ranges_count) { + ranges[i * 2 + 0] = unicode; + ranges[i * 2 + 1] = unicode; + } + while (g) { + FT_ULong unicode2 = FT_Get_Next_Char(data->face, unicode, &g); + if (unicode + 1 != unicode2) { + if (i < ranges_count) { + ranges[i * 2 + 1] = unicode; + if (i + 1 < ranges_count) { + ranges[(i + 1) * 2 + 0] = unicode2; + } + } + i++; + } + if (i < ranges_count) { + ranges[i * 2 + 1] = unicode2; + } + unicode = unicode2; + } + return i; +} + +static bool ttf_get_glyph_dimensions(ALLEGRO_FONT const *f, + int codepoint, + int *bbx, int *bby, int *bbw, int *bbh) +{ + ALLEGRO_TTF_FONT_DATA *data = f->data; + ALLEGRO_TTF_GLYPH_DATA *glyph; + FT_Face face = data->face; + int ft_index = FT_Get_Char_Index(face, codepoint); + if (!get_glyph(data, ft_index, &glyph)) { + if (f->fallback) { + return al_get_glyph_dimensions(f->fallback, codepoint, + bbx, bby, bbw, bbh); + } + else { + get_glyph(data, 0, &glyph); + ft_index = 0; + } + } + cache_glyph(data, face, ft_index, glyph, false); + *bbx = glyph->offset_x; + *bbw = glyph->region.w - 2; + *bbh = glyph->region.h - 2; + *bby = glyph->offset_y; + + return true; +} + +static int ttf_get_glyph_advance(ALLEGRO_FONT const *f, int codepoint1, + int codepoint2) +{ + ALLEGRO_TTF_FONT_DATA *data = f->data; + FT_Face face = data->face; + int ft_index = FT_Get_Char_Index(face, codepoint1); + ALLEGRO_TTF_GLYPH_DATA *glyph; + int kerning = 0; + int advance = 0; + + if (codepoint1 == ALLEGRO_NO_KERNING) { + return 0; + } + + if (!get_glyph(data, ft_index, &glyph)) { + if (f->fallback) { + return al_get_glyph_advance(f->fallback, codepoint1, codepoint2); + } + else { + get_glyph(data, 0, &glyph); + ft_index = 0; + } + } + cache_glyph(data, face, ft_index, glyph, false); + + if (codepoint2 != ALLEGRO_NO_KERNING) { + int ft_index1 = FT_Get_Char_Index(face, codepoint1); + int ft_index2 = FT_Get_Char_Index(face, codepoint2); + kerning = get_kerning(data, face, ft_index1, ft_index2); + } + + advance = glyph->advance; + return advance + kerning; +} + + + +/* Function: al_init_ttf_addon + */ +bool al_init_ttf_addon(void) +{ + if (ttf_inited) { + ALLEGRO_WARN("TTF addon already initialised.\n"); + return true; + } + + FT_Init_FreeType(&ft); + vt.font_height = ttf_font_height; + vt.font_ascent = ttf_font_ascent; + vt.font_descent = ttf_font_descent; + vt.char_length = ttf_char_length; + vt.text_length = ttf_text_length; + vt.render_char = ttf_render_char; + vt.render = ttf_render; + vt.destroy = ttf_destroy; + vt.get_text_dimensions = ttf_get_text_dimensions; + vt.get_font_ranges = ttf_get_font_ranges; + vt.get_glyph_dimensions = ttf_get_glyph_dimensions; + vt.get_glyph_advance = ttf_get_glyph_advance; + vt.get_glyph = ttf_get_glyph; + + al_register_font_loader(".ttf", al_load_ttf_font); + + _al_add_exit_func(al_shutdown_ttf_addon, "al_shutdown_ttf_addon"); + + /* Can't fail right now - in the future we might dynamically load + * the FreeType DLL here and/or initialize FreeType (which both + * could fail and would cause a false return). + */ + ttf_inited = true; + return ttf_inited; +} + + +/* Function: al_is_ttf_addon_initialized + */ +bool al_is_ttf_addon_initialized(void) +{ + return ttf_inited; +} + + +/* Function: al_shutdown_ttf_addon + */ +void al_shutdown_ttf_addon(void) +{ + if (!ttf_inited) { + ALLEGRO_ERROR("TTF addon not initialised.\n"); + return; + } + + al_register_font_loader(".ttf", NULL); + + FT_Done_FreeType(ft); + + ttf_inited = false; +} + + +/* Function: al_get_allegro_ttf_version + */ +uint32_t al_get_allegro_ttf_version(void) +{ + return ALLEGRO_VERSION_INT; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/video/CMakeLists.txt b/allegro/addons/video/CMakeLists.txt new file mode 100644 index 00000000..61a322ba --- /dev/null +++ b/allegro/addons/video/CMakeLists.txt @@ -0,0 +1,60 @@ +option(WANT_OGG_VIDEO "Enable Ogg video (requires Theora and Vorbis)" on) + +set(VIDEO_SOURCES + video.c + ) + +set(VIDEO_INCLUDE_FILES allegro5/allegro_video.h) + +include_directories(../audio ../image .) + +set_our_header_properties(${VIDEO_INCLUDE_FILES}) + +# For monolith build. +set(VIDEO_INCLUDE_DIRECTORIES) + +if(WANT_OGG_VIDEO) + find_package(Theora) + find_package(Vorbis) + if(THEORA_FOUND AND VORBIS_FOUND) + set(SUPPORT_OGG_VIDEO 1) + endif() +endif(WANT_OGG_VIDEO) + +if(SUPPORT_OGG_VIDEO) + list(APPEND VIDEO_INCLUDE_DIRECTORIES + ${OGG_INCLUDE_DIR} + ${VORBIS_INCLUDE_DIR} + ${THEORA_INCLUDE_DIR} + ) + list(APPEND VIDEO_SOURCES ogv.c) + set(SUPPORT_VIDEO 1) + set(ALLEGRO_CFG_VIDEO_HAVE_OGV 1) + set(VIDEO_LIBRARIES ${VIDEO_LIBRARIES} ${THEORA_LIBRARIES} ${VORBIS_LIBRARIES}) +endif(SUPPORT_OGG_VIDEO) + +if(NOT SUPPORT_VIDEO) + message("WARNING: allegro_video wanted but no supported backend found") + return() +endif(NOT SUPPORT_VIDEO) + +include_directories(SYSTEM ${VIDEO_INCLUDE_DIRECTORIES}) + +configure_file( + allegro5/internal/aintern_video_cfg.h.cmake + ${PROJECT_BINARY_DIR}/include/allegro5/internal/aintern_video_cfg.h + ) + +add_our_addon_library(allegro_video + AllegroVideo-${ALLEGRO_SOVERSION} + "${VIDEO_SOURCES};${VIDEO_INCLUDE_FILES}" + "-DALLEGRO_VIDEO_SRC" + "${ALLEGRO_LINK_WITH};${AUDIO_LINK_WITH};${VIDEO_LIBRARIES}" + ) + +install_our_headers(${VIDEO_INCLUDE_FILES}) + +add_addon(video) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/addons/video/allegro5/allegro_video.h b/allegro/addons/video/allegro5/allegro_video.h new file mode 100644 index 00000000..f078978c --- /dev/null +++ b/allegro/addons/video/allegro5/allegro_video.h @@ -0,0 +1,78 @@ +#ifndef __al_included_allegro_video_h +#define __al_included_allegro_video_h + +#ifdef __cplusplus + extern "C" { +#endif + +#include "allegro5/allegro5.h" +#include "allegro5/allegro_audio.h" + +#if (defined ALLEGRO_MINGW32) || (defined ALLEGRO_MSVC) || (defined ALLEGRO_BCC32) + #ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_VIDEO_SRC + #define _ALLEGRO_VIDEO_DLL __declspec(dllexport) + #else + #define _ALLEGRO_VIDEO_DLL __declspec(dllimport) + #endif + #else + #define _ALLEGRO_VIDEO_DLL + #endif +#endif + +#if defined ALLEGRO_MSVC + #define ALLEGRO_VIDEO_FUNC(type, name, args) _ALLEGRO_VIDEO_DLL type __cdecl name args +#elif defined ALLEGRO_MINGW32 + #define ALLEGRO_VIDEO_FUNC(type, name, args) extern type name args +#elif defined ALLEGRO_BCC32 + #define ALLEGRO_VIDEO_FUNC(type, name, args) extern _ALLEGRO_VIDEO_DLL type name args +#else + #define ALLEGRO_VIDEO_FUNC AL_FUNC +#endif + +/* Enum: ALLEGRO_VIDEO_EVENT_TYPE + */ +enum ALLEGRO_VIDEO_EVENT_TYPE +{ + ALLEGRO_EVENT_VIDEO_FRAME_SHOW = 550, + ALLEGRO_EVENT_VIDEO_FINISHED = 551, + _ALLEGRO_EVENT_VIDEO_SEEK = 552 /* internal */ +}; + +enum ALLEGRO_VIDEO_POSITION_TYPE +{ + ALLEGRO_VIDEO_POSITION_ACTUAL = 0, + ALLEGRO_VIDEO_POSITION_VIDEO_DECODE = 1, + ALLEGRO_VIDEO_POSITION_AUDIO_DECODE = 2 +}; + +/* Enum: ALLEGRO_VIDEO_POSITION_TYPE + */ +typedef enum ALLEGRO_VIDEO_POSITION_TYPE ALLEGRO_VIDEO_POSITION_TYPE; + +typedef struct ALLEGRO_VIDEO ALLEGRO_VIDEO; + +ALLEGRO_VIDEO_FUNC(ALLEGRO_VIDEO *, al_open_video, (char const *filename)); +ALLEGRO_VIDEO_FUNC(void, al_close_video, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(void, al_start_video, (ALLEGRO_VIDEO *video, ALLEGRO_MIXER *mixer)); +ALLEGRO_VIDEO_FUNC(void, al_start_video_with_voice, (ALLEGRO_VIDEO *video, ALLEGRO_VOICE *voice)); +ALLEGRO_VIDEO_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_video_event_source, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(void, al_set_video_playing, (ALLEGRO_VIDEO *video, bool playing)); +ALLEGRO_VIDEO_FUNC(bool, al_is_video_playing, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(double, al_get_video_audio_rate, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(double, al_get_video_fps, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(float, al_get_video_scaled_width, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(float, al_get_video_scaled_height, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(ALLEGRO_BITMAP *, al_get_video_frame, (ALLEGRO_VIDEO *video)); +ALLEGRO_VIDEO_FUNC(double, al_get_video_position, (ALLEGRO_VIDEO *video, ALLEGRO_VIDEO_POSITION_TYPE which)); +ALLEGRO_VIDEO_FUNC(bool, al_seek_video, (ALLEGRO_VIDEO *video, double pos_in_seconds)); +ALLEGRO_VIDEO_FUNC(bool, al_init_video_addon, (void)); +ALLEGRO_VIDEO_FUNC(bool, al_is_video_addon_initialized, (void)); +ALLEGRO_VIDEO_FUNC(void, al_shutdown_video_addon, (void)); +ALLEGRO_VIDEO_FUNC(uint32_t, al_get_allegro_video_version, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/addons/video/allegro5/internal/aintern_video.h b/allegro/addons/video/allegro5/internal/aintern_video.h new file mode 100644 index 00000000..923696f9 --- /dev/null +++ b/allegro/addons/video/allegro5/internal/aintern_video.h @@ -0,0 +1,40 @@ + +typedef struct ALLEGRO_VIDEO_INTERFACE { + bool (*open_video)(ALLEGRO_VIDEO *video); + bool (*close_video)(ALLEGRO_VIDEO *video); + bool (*start_video)(ALLEGRO_VIDEO *video); + bool (*set_video_playing)(ALLEGRO_VIDEO *video); + bool (*seek_video)(ALLEGRO_VIDEO *video, double seek_to); + bool (*update_video)(ALLEGRO_VIDEO *video); +} ALLEGRO_VIDEO_INTERFACE; + +struct ALLEGRO_VIDEO { + ALLEGRO_VIDEO_INTERFACE *vtable; + + /* video */ + ALLEGRO_BITMAP *current_frame; + double video_position; + double fps; + float scaled_width; + float scaled_height; + + /* audio */ + ALLEGRO_MIXER *mixer; + ALLEGRO_VOICE *voice; + ALLEGRO_AUDIO_STREAM *audio; + double audio_position; + double audio_rate; + + /* general */ + bool es_inited; + ALLEGRO_EVENT_SOURCE es; + ALLEGRO_PATH *filename; + bool playing; + double position; + + /* implementation specific */ + void *data; +}; + +ALLEGRO_VIDEO_INTERFACE *_al_video_ogv_vtable(void); +void _al_compute_scaled_dimensions(int frame_w, int frame_h, float aspect_ratio, float *scaled_w, float *scaled_h); diff --git a/allegro/addons/video/allegro5/internal/aintern_video_cfg.h.cmake b/allegro/addons/video/allegro5/internal/aintern_video_cfg.h.cmake new file mode 100644 index 00000000..449a97ec --- /dev/null +++ b/allegro/addons/video/allegro5/internal/aintern_video_cfg.h.cmake @@ -0,0 +1 @@ +#cmakedefine ALLEGRO_CFG_VIDEO_HAVE_OGV diff --git a/allegro/addons/video/ogv.c b/allegro/addons/video/ogv.c new file mode 100644 index 00000000..4f789dc5 --- /dev/null +++ b/allegro/addons/video/ogv.c @@ -0,0 +1,1364 @@ +/* Ogg Theora/Vorbis video backend + * + * TODO: + * - seeking + * - generate video frame events + * - better ycbcr->rgb + * - improve frame skipping + * - Ogg Skeleton support + * - pass Theora test suite + * + * NOTE: we treat Ogg timestamps as the beginning of frames. In reality they + * are end timestamps. Normally this should not be noticeable, but can make a + * difference. + */ + +#include <stdio.h> +#include "allegro5/allegro5.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_video.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/internal/aintern_video.h" + +#include <ogg/ogg.h> +#include <theora/theora.h> +#include <theora/theoradec.h> +#include <vorbis/codec.h> + +ALLEGRO_DEBUG_CHANNEL("video") + + +/* XXX probably should be based on stream parameters */ +static const int NUM_FRAGS = 2; +static const int FRAG_SAMPLES = 4096; +static const int RGB_PIXEL_FORMAT = ALLEGRO_PIXEL_FORMAT_ABGR_8888; + + +typedef struct OGG_VIDEO OGG_VIDEO; +typedef struct STREAM STREAM; +typedef struct THEORA_STREAM THEORA_STREAM; +typedef struct VORBIS_STREAM VORBIS_STREAM; +typedef struct PACKET_NODE PACKET_NODE; + +enum { + STREAM_TYPE_UNKNOWN = 0, + STREAM_TYPE_THEORA, + STREAM_TYPE_VORBIS +}; + +struct PACKET_NODE { + PACKET_NODE *next; + ogg_packet pkt; +}; + +struct THEORA_STREAM { + th_info info; + th_comment comment; + th_setup_info *setup; + th_dec_ctx *ctx; + ogg_int64_t prev_framenum; + double frame_duration; +}; + +struct VORBIS_STREAM { + vorbis_info info; + vorbis_comment comment; + bool inited_for_data; + vorbis_dsp_state dsp; + vorbis_block block; + int channels; + float *next_fragment; /* channels * FRAG_SAMPLES elements */ + int next_fragment_pos; +}; + +struct STREAM { + int stream_type; + bool active; + bool headers_done; + ogg_stream_state state; + PACKET_NODE *packet_queue; + union { + THEORA_STREAM theora; + VORBIS_STREAM vorbis; + } u; +}; + +struct OGG_VIDEO { + ALLEGRO_FILE *fp; + bool reached_eof; + ogg_sync_state sync_state; + _AL_VECTOR streams; /* vector of STREAM pointers */ + STREAM *selected_video_stream; /* one of the streams */ + STREAM *selected_audio_stream; /* one of the streams */ + int seek_counter; + + /* Video output. */ + th_pixel_fmt pixel_fmt; + th_ycbcr_buffer buffer; + bool buffer_dirty; + unsigned char* rgb_data; + ALLEGRO_BITMAP *frame_bmp; + ALLEGRO_BITMAP *pic_bmp; /* frame_bmp, or subbitmap thereof */ + + ALLEGRO_EVENT_SOURCE evtsrc; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_MUTEX *mutex; + ALLEGRO_COND *cond; + ALLEGRO_THREAD *thread; +}; + + +/* forward declarations */ +static bool ogv_close_video(ALLEGRO_VIDEO *video); + + +/* Packet queue. */ + +static PACKET_NODE *create_packet_node(ogg_packet *packet) +{ + PACKET_NODE *node = al_malloc(sizeof(PACKET_NODE)); + + node->next = NULL; + node->pkt = *packet; + node->pkt.packet = al_malloc(packet->bytes); + memcpy(node->pkt.packet, packet->packet, packet->bytes); + + return node; +} + +static void free_packet_node(PACKET_NODE *node) +{ + ASSERT(node->next == NULL); + + al_free(node->pkt.packet); + al_free(node); +} + +static void add_tail_packet(STREAM *stream, PACKET_NODE *node) +{ + PACKET_NODE *cur; + + ASSERT(node->next == NULL); + + for (cur = stream->packet_queue; cur != NULL; cur = cur->next) { + if (cur->next == NULL) { + cur->next = node; + ASSERT(cur->pkt.packetno < node->pkt.packetno); + return; + } + } + + ASSERT(stream->packet_queue == NULL); + stream->packet_queue = node; +} + +static void add_head_packet(STREAM *stream, PACKET_NODE *node) +{ + ASSERT(node->next == NULL); + + node->next = stream->packet_queue; + stream->packet_queue = node; + + if (node->next) { + ASSERT(node->pkt.packetno < node->next->pkt.packetno); + } +} + +static PACKET_NODE *take_head_packet(STREAM *stream) +{ + PACKET_NODE *cur; + + cur = stream->packet_queue; + if (!cur) { + return NULL; + } + if (cur->next) { + ASSERT(cur->pkt.packetno < cur->next->pkt.packetno); + } + stream->packet_queue = cur->next; + cur->next = NULL; + return cur; +} + +static void free_packet_queue(STREAM *stream) +{ + while (stream->packet_queue) { + PACKET_NODE *node = stream->packet_queue; + stream->packet_queue = node->next; + node->next = NULL; + free_packet_node(node); + } +} + +static void deactivate_stream(STREAM *stream) +{ + stream->active = false; + free_packet_queue(stream); +} + + +/* Logical streams. */ + +static STREAM *create_stream(OGG_VIDEO *ogv, int serial) +{ + STREAM *stream; + STREAM **slot; + + stream = al_calloc(1, sizeof(STREAM)); + stream->stream_type = STREAM_TYPE_UNKNOWN; + stream->active = true; + stream->headers_done = false; + ogg_stream_init(&stream->state, serial); + stream->packet_queue = NULL; + + slot = _al_vector_alloc_back(&ogv->streams); + (*slot) = stream; + + return stream; +} + +static STREAM *find_stream(OGG_VIDEO *ogv, int serial) +{ + unsigned i; + + for (i = 0; i < _al_vector_size(&ogv->streams); i++) { + STREAM **slot = _al_vector_ref(&ogv->streams, i); + STREAM *stream = *slot; + + if (stream->state.serialno == serial) { + return stream; + } + } + + return NULL; +} + +static void free_stream(STREAM *stream) +{ + ASSERT(stream); + + ogg_stream_clear(&stream->state); + + free_packet_queue(stream); + + switch (stream->stream_type) { + case STREAM_TYPE_UNKNOWN: + break; + + case STREAM_TYPE_THEORA: + { + THEORA_STREAM *tstream = &stream->u.theora; + + ALLEGRO_DEBUG("Clean up Theora.\n"); + th_info_clear(&tstream->info); + th_comment_clear(&tstream->comment); + if (tstream->setup) { + th_setup_free(tstream->setup); + } + if (tstream->ctx) { + th_decode_free(tstream->ctx); + } + } + break; + + case STREAM_TYPE_VORBIS: + { + VORBIS_STREAM *vstream = &stream->u.vorbis; + + ALLEGRO_DEBUG("Clean up Vorbis.\n"); + vorbis_info_clear(&vstream->info); + vorbis_comment_clear(&vstream->comment); + if (vstream->inited_for_data) { + vorbis_block_clear(&vstream->block); + vorbis_dsp_clear(&vstream->dsp); + } + al_free(vstream->next_fragment); + } + break; + } + + al_free(stream); +} + +/* Returns true if got a page. */ +static bool read_page(OGG_VIDEO *ogv, ogg_page *page) +{ + const int buffer_size = 4096; + + if (al_feof(ogv->fp) || al_ferror(ogv->fp)) { + ogv->reached_eof = true; + return ogg_sync_pageout(&ogv->sync_state, page) == 1; + } + + while (ogg_sync_pageout(&ogv->sync_state, page) != 1) { + char *buffer; + size_t bytes; + int rc; + + buffer = ogg_sync_buffer(&ogv->sync_state, buffer_size); + bytes = al_fread(ogv->fp, buffer, buffer_size); + if (bytes == 0) { + ALLEGRO_DEBUG("End of file.\n"); + return false; + } + + rc = ogg_sync_wrote(&ogv->sync_state, bytes); + ASSERT(rc == 0); + } + + return true; +} + +/* Return true if got a packet for the stream. */ +static bool read_packet(OGG_VIDEO *ogv, STREAM *stream, ogg_packet *packet) +{ + ogg_page page; + int rc; + + for (;;) { + rc = ogg_stream_packetout(&stream->state, packet); + if (rc == 1) { + /* Got a packet for stream. */ + return true; + } + + if (read_page(ogv, &page)) { + STREAM *page_stream = find_stream(ogv, ogg_page_serialno(&page)); + + if (page_stream && page_stream->active) { + rc = ogg_stream_pagein(&page_stream->state, &page); + ASSERT(rc == 0); + } + } + else { + return false; + } + } +} + + +/* Header decoding. */ + +static bool try_decode_theora_header(STREAM *stream, ogg_packet *packet) +{ + int rc; + + switch (stream->stream_type) { + case STREAM_TYPE_UNKNOWN: + th_info_init(&stream->u.theora.info); + th_comment_init(&stream->u.theora.comment); + break; + case STREAM_TYPE_THEORA: + break; + case STREAM_TYPE_VORBIS: + return false; + } + + if (stream->headers_done) { + add_tail_packet(stream, create_packet_node(packet)); + return true; + } + + rc = th_decode_headerin(&stream->u.theora.info, &stream->u.theora.comment, + &stream->u.theora.setup, packet); + + if (rc > 0) { + /* Successfully parsed a Theora header. */ + if (stream->stream_type == STREAM_TYPE_UNKNOWN) { + ALLEGRO_DEBUG("Found Theora stream.\n"); + stream->stream_type = STREAM_TYPE_THEORA; + } + return true; + } + + if (rc == 0) { + /* First Theora data packet. */ + add_tail_packet(stream, create_packet_node(packet)); + stream->headers_done = true; + return true; + } + + th_info_clear(&stream->u.theora.info); + th_comment_clear(&stream->u.theora.comment); + return false; +} + +static int try_decode_vorbis_header(STREAM *stream, ogg_packet *packet) +{ + int rc; + + switch (stream->stream_type) { + case STREAM_TYPE_UNKNOWN: + vorbis_info_init(&stream->u.vorbis.info); + vorbis_comment_init(&stream->u.vorbis.comment); + break; + case STREAM_TYPE_VORBIS: + break; + case STREAM_TYPE_THEORA: + return false; + } + + rc = vorbis_synthesis_headerin(&stream->u.vorbis.info, + &stream->u.vorbis.comment, packet); + + if (rc == 0) { + /* Successfully parsed a Vorbis header. */ + if (stream->stream_type == STREAM_TYPE_UNKNOWN) { + ALLEGRO_INFO("Found Vorbis stream.\n"); + stream->stream_type = STREAM_TYPE_VORBIS; + stream->u.vorbis.inited_for_data = false; + } + return true; + } + + if (stream->stream_type == STREAM_TYPE_VORBIS && rc == OV_ENOTVORBIS) { + /* First data packet. */ + add_tail_packet(stream, create_packet_node(packet)); + stream->headers_done = true; + return true; + } + + vorbis_info_clear(&stream->u.vorbis.info); + vorbis_comment_clear(&stream->u.vorbis.comment); + return false; +} + +static bool all_headers_done(OGG_VIDEO *ogv) +{ + bool have_something = false; + unsigned i; + + for (i = 0; i < _al_vector_size(&ogv->streams); i++) { + STREAM **slot = _al_vector_ref(&ogv->streams, i); + STREAM *stream = *slot; + + switch (stream->stream_type) { + case STREAM_TYPE_THEORA: + case STREAM_TYPE_VORBIS: + have_something = true; + if (!stream->headers_done) + return false; + break; + case STREAM_TYPE_UNKNOWN: + break; + } + } + + return have_something; +} + +static void read_headers(OGG_VIDEO *ogv) +{ + ogg_page page; + ogg_packet packet; + STREAM *stream; + int serial; + int rc; + + ALLEGRO_DEBUG("Begin reading headers.\n"); + + do { + /* Read a page of data. */ + if (!read_page(ogv, &page)) { + break; + } + + /* Which stream is this page for? */ + serial = ogg_page_serialno(&page); + + /* Start a new stream or find an existing one. */ + if (ogg_page_bos(&page)) { + stream = create_stream(ogv, serial); + } + else { + stream = find_stream(ogv, serial); + } + + if (!stream) { + ALLEGRO_WARN("No stream for serial: %x\n", serial); + continue; + } + + if (!stream->active) { + continue; + } + + /* Add the page to the stream. */ + rc = ogg_stream_pagein(&stream->state, &page); + ASSERT(rc == 0); + + /* Look for a complete packet. */ + rc = ogg_stream_packetpeek(&stream->state, &packet); + if (rc == 0) { + continue; + } + if (rc == -1) { + ALLEGRO_WARN("No packet due to lost sync or hole in data.\n"); + continue; + } + + /* Try to decode the packet as a Theora or Vorbis header. */ + if (!try_decode_theora_header(stream, &packet)) { + if (!try_decode_vorbis_header(stream, &packet)) { + ALLEGRO_DEBUG("Unknown packet type ignored.\n"); + } + } + + /* Consume the packet. */ + rc = ogg_stream_packetout(&stream->state, &packet); + ASSERT(rc == 1); + + } while (!all_headers_done(ogv)); + + ALLEGRO_DEBUG("End reading headers.\n"); +} + + +/* Vorbis streams. */ + +static void setup_vorbis_stream_decode(ALLEGRO_VIDEO *video, STREAM *stream) +{ + VORBIS_STREAM * const vstream = &stream->u.vorbis; + int rc; + + rc = vorbis_synthesis_init(&vstream->dsp, &vstream->info); + ASSERT(rc == 0); + + rc = vorbis_block_init(&vstream->dsp, &vstream->block); + ASSERT(rc == 0); + + vstream->inited_for_data = true; + + video->audio_rate = vstream->info.rate; + vstream->channels = vstream->info.channels; + + vstream->next_fragment = + al_calloc(vstream->channels * FRAG_SAMPLES, sizeof(float)); + + ALLEGRO_INFO("Audio rate: %f\n", video->audio_rate); + ALLEGRO_INFO("Audio channels: %d\n", vstream->channels); +} + +static void handle_vorbis_data(VORBIS_STREAM *vstream, ogg_packet *packet) +{ + int rc; + + rc = vorbis_synthesis(&vstream->block, packet); + if (rc != 0) { + ALLEGRO_ERROR("vorbis_synthesis returned %d\n", rc); + return; + } + + rc = vorbis_synthesis_blockin(&vstream->dsp, &vstream->block); + if (rc != 0) { + ALLEGRO_ERROR("vorbis_synthesis_blockin returned %d\n", rc); + return; + } +} + +static bool generate_next_audio_fragment(VORBIS_STREAM *vstream) +{ + float **pcm = NULL; + float *p; + int samples; + int i, ch; + int rc; + + samples = vorbis_synthesis_pcmout(&vstream->dsp, &pcm); + if (samples == 0) { + return false; + } + + if (samples > FRAG_SAMPLES - vstream->next_fragment_pos) { + samples = FRAG_SAMPLES - vstream->next_fragment_pos; + } + + ASSERT(vstream->next_fragment); + p = &vstream->next_fragment[ + vstream->channels * vstream->next_fragment_pos]; + + if (vstream->channels == 2) { + for (i = 0; i < samples; i++) { + *p++ = pcm[0][i]; + *p++ = pcm[1][i]; + } + } + else if (vstream->channels == 1) { + for (i = 0; i < samples; i++) { + *p++ = pcm[0][i]; + } + } + else { + for (i = 0; i < samples; i++) { + for (ch = 0; ch < vstream->channels; ch++) { + *p++ = pcm[ch][i]; + } + } + } + + vstream->next_fragment_pos += samples; + + rc = vorbis_synthesis_read(&vstream->dsp, samples); + ASSERT(rc == 0); + return true; +} + +static void poll_vorbis_decode(OGG_VIDEO *ogv, STREAM *vstream_outer) +{ + VORBIS_STREAM * const vstream = &vstream_outer->u.vorbis; + + while (vstream->next_fragment_pos < FRAG_SAMPLES + && generate_next_audio_fragment(vstream)) + { + } + + while (vstream->next_fragment_pos < FRAG_SAMPLES) { + PACKET_NODE *node; + ogg_packet packet; + + node = take_head_packet(vstream_outer); + if (node) { + handle_vorbis_data(vstream, &node->pkt); + generate_next_audio_fragment(vstream); + free_packet_node(node); + } + else if (read_packet(ogv, vstream_outer, &packet)) { + handle_vorbis_data(vstream, &packet); + generate_next_audio_fragment(vstream); + } + else { + break; + } + } +} + +static ALLEGRO_AUDIO_STREAM *create_audio_stream(const ALLEGRO_VIDEO *video, + const STREAM *vstream_outer) +{ + const VORBIS_STREAM *vstream = &vstream_outer->u.vorbis; + ALLEGRO_AUDIO_STREAM *audio; + int chanconf; + int rc; + + switch (vstream->channels) { + case 1: chanconf = ALLEGRO_CHANNEL_CONF_1; break; + case 2: chanconf = ALLEGRO_CHANNEL_CONF_2; break; + case 3: chanconf = ALLEGRO_CHANNEL_CONF_3; break; + case 4: chanconf = ALLEGRO_CHANNEL_CONF_4; break; + case 6: chanconf = ALLEGRO_CHANNEL_CONF_5_1; break; + case 7: chanconf = ALLEGRO_CHANNEL_CONF_6_1; break; + case 8: chanconf = ALLEGRO_CHANNEL_CONF_7_1; break; + default: + ALLEGRO_WARN("Unsupported number of channels: %d\n", + vstream->channels); + return NULL; + } + + audio = al_create_audio_stream(NUM_FRAGS, FRAG_SAMPLES, + vstream->info.rate, ALLEGRO_AUDIO_DEPTH_FLOAT32, chanconf); + if (!audio) { + ALLEGRO_ERROR("Could not create audio stream.\n"); + return NULL; + } + + if (video->mixer) { + rc = al_attach_audio_stream_to_mixer(audio, video->mixer); + } + else if (video->voice) { + rc = al_attach_audio_stream_to_voice(audio, video->voice); + } + else { + rc = al_attach_audio_stream_to_mixer(audio, al_get_default_mixer()); + } + + if (rc) { + ALLEGRO_DEBUG("Audio stream ready.\n"); + } + else { + ALLEGRO_ERROR("Could not attach audio stream.\n"); + al_destroy_audio_stream(audio); + audio = NULL; + } + + return audio; +} + +static void update_audio_fragment(ALLEGRO_AUDIO_STREAM *audio_stream, + VORBIS_STREAM *vstream, bool paused, bool reached_eof) +{ + float *frag; + + frag = al_get_audio_stream_fragment(audio_stream); + if (!frag) + return; + + if (paused || vstream->next_fragment_pos < FRAG_SAMPLES) { + if (!paused && !reached_eof) { + ALLEGRO_WARN("Next fragment not ready.\n"); + } + memset(frag, 0, vstream->channels * FRAG_SAMPLES * sizeof(float)); + } + else { + memcpy(frag, vstream->next_fragment, + vstream->channels * FRAG_SAMPLES * sizeof(float)); + vstream->next_fragment_pos = 0; + } + + al_set_audio_stream_fragment(audio_stream, frag); +} + + +/* Theora streams. */ + +static void setup_theora_stream_decode(ALLEGRO_VIDEO *video, OGG_VIDEO *ogv, + STREAM *tstream_outer) +{ + THEORA_STREAM * const tstream = &tstream_outer->u.theora; + int frame_w = tstream->info.frame_width; + int frame_h = tstream->info.frame_height; + int pic_x = tstream->info.pic_x; + int pic_y = tstream->info.pic_y; + int pic_w = tstream->info.pic_width; + int pic_h = tstream->info.pic_height; + float aspect_ratio = 1.0; + + tstream->ctx = th_decode_alloc(&tstream->info, tstream->setup); + ASSERT(tstream->ctx); + th_setup_free(tstream->setup); + tstream->setup = NULL; + + ogv->pixel_fmt = tstream->info.pixel_fmt; + ogv->frame_bmp = al_create_bitmap(frame_w, frame_h); + if (pic_x == 0 && pic_y == 0 && pic_w == frame_w && pic_h == frame_h) { + ogv->pic_bmp = ogv->frame_bmp; + } + else { + ogv->pic_bmp = al_create_sub_bitmap(ogv->frame_bmp, + pic_x, pic_y, pic_w, pic_h); + } + ogv->rgb_data = + al_malloc(al_get_pixel_size(RGB_PIXEL_FORMAT) * frame_w * frame_h); + + video->fps = + (double)tstream->info.fps_numerator / + (double)tstream->info.fps_denominator; + tstream->frame_duration = + (double)tstream->info.fps_denominator / + (double)tstream->info.fps_numerator; + + if (tstream->info.aspect_denominator != 0) { + aspect_ratio = + (double)(pic_w * tstream->info.aspect_numerator) / + (double)(pic_h * tstream->info.aspect_denominator); + } + + _al_compute_scaled_dimensions(pic_w, pic_h, aspect_ratio, &video->scaled_width, + &video->scaled_height); + + tstream->prev_framenum = -1; + + ALLEGRO_INFO("Frame size: %dx%d\n", frame_w, frame_h); + ALLEGRO_INFO("Picture size: %dx%d\n", pic_w, pic_h); + ALLEGRO_INFO("Scaled size: %fx%f\n", video->scaled_width, video->scaled_height); + ALLEGRO_INFO("FPS: %f\n", video->fps); + ALLEGRO_INFO("Frame_duration: %f\n", tstream->frame_duration); +} + +static int64_t get_theora_framenum(THEORA_STREAM *tstream, ogg_packet *packet) +{ + if (packet->granulepos > 0) { + return th_granule_frame(&tstream->info, packet->granulepos); + } + + return tstream->prev_framenum + 1; +} + +static bool handle_theora_data(ALLEGRO_VIDEO *video, THEORA_STREAM *tstream, + ogg_packet *packet, bool *ret_new_frame) +{ + int64_t expected_framenum; + int64_t framenum; + int rc; + + expected_framenum = tstream->prev_framenum + 1; + framenum = get_theora_framenum(tstream, packet); + + if (framenum > expected_framenum) { + /* Packet is for a later frame, don't decode it yet. */ + ALLEGRO_DEBUG("Expected frame %ld, got %ld\n", + (long)expected_framenum, (long)framenum); + video->video_position += tstream->frame_duration; + tstream->prev_framenum++; + return false; + } + + if (framenum < expected_framenum) { + ALLEGRO_DEBUG("Expected frame %ld, got %ld (decoding anyway)\n", + (long)expected_framenum, (long)framenum); + } + + rc = th_decode_packetin(tstream->ctx, packet, NULL); + if (rc != TH_EBADPACKET) { + /* HACK: When we seek to beginning, the first few packets are actually + * headers. To properly fix this, those packets should be ignored when we + * do the seeking (see the XXX there). */ + ASSERT(rc == 0 || rc == TH_DUPFRAME); + } + + if (rc == 0) { + *ret_new_frame = true; + + video->video_position = framenum * tstream->frame_duration; + tstream->prev_framenum = framenum; + } + + return true; +} + +/* Y'CrCb to RGB conversion. */ +/* XXX simple slow implementation */ + +static unsigned char clamp(int x) +{ + if (x < 0) + return 0; + if (x > 255) + return 255; + return x; +} + +static INLINE void ycbcr_to_rgb(th_ycbcr_buffer buffer, + unsigned char* rgb_data, int pixel_size, int pitch, int xshift, int yshift) +{ + const int w = buffer[0].width; + const int h = buffer[0].height; + int x, y; + + for (y = 0; y < h; y++) { + const int y2 = y >> yshift; + for (x = 0; x < w; x++) { + const int x2 = x >> xshift; + unsigned char * const data = rgb_data + y * pitch + x * pixel_size; + const int yp = buffer[0].data[y * buffer[0].stride + x ]; + const int cb = buffer[1].data[y2 * buffer[1].stride + x2]; + const int cr = buffer[2].data[y2 * buffer[2].stride + x2]; + const int C = yp - 16; + const int D = cb - 128; + const int E = cr - 128; + + data[0] = clamp((298*C + 409*E + 128) >> 8); + data[1] = clamp((298*C - 100*D - 208*E + 128) >> 8); + data[2] = clamp((298*C + 516*D + 128) >> 8); + data[3] = 0xff; + } + } +} + +static void convert_buffer_to_rgba(OGG_VIDEO *ogv) +{ + const int pixel_size = al_get_pixel_size(RGB_PIXEL_FORMAT); + const int pitch = pixel_size * al_get_bitmap_width(ogv->frame_bmp); + + switch (ogv->pixel_fmt) { + case TH_PF_420: + ycbcr_to_rgb(ogv->buffer, ogv->rgb_data, pixel_size, pitch, 1, 1); + break; + case TH_PF_422: + ycbcr_to_rgb(ogv->buffer, ogv->rgb_data, pixel_size, pitch, 1, 0); + break; + case TH_PF_444: + ycbcr_to_rgb(ogv->buffer, ogv->rgb_data, pixel_size, pitch, 0, 0); + break; + default: + ALLEGRO_ERROR("Unsupported pixel format.\n"); + break; + } +} + +static int poll_theora_decode(ALLEGRO_VIDEO *video, STREAM *tstream_outer) +{ + OGG_VIDEO * const ogv = video->data; + THEORA_STREAM * const tstream = &tstream_outer->u.theora; + bool new_frame = false; + int num_frames = 0; + int rc; + + while (video->video_position < video->position) { + PACKET_NODE *node; + ogg_packet packet; + + node = take_head_packet(tstream_outer); + if (node) { + if (handle_theora_data(video, tstream, &node->pkt, &new_frame)) { + free_packet_node(node); + num_frames++; + } + else { + add_head_packet(tstream_outer, node); + } + } + else if (read_packet(ogv, tstream_outer, &packet)) { + if (handle_theora_data(video, tstream, &packet, &new_frame)) { + num_frames++; + } + else { + add_head_packet(tstream_outer, create_packet_node(&packet)); + } + } + else { + break; + } + + /* Only skip frames if we are really falling behind, not just slightly + * ahead of the target position. + * XXX improve frame skipping algorithm + */ + if (video->video_position + >= video->position - 3.0*tstream->frame_duration) { + break; + } + } + + if (new_frame) { + ALLEGRO_EVENT event; + al_lock_mutex(ogv->mutex); + + rc = th_decode_ycbcr_out(tstream->ctx, ogv->buffer); + ASSERT(rc == 0); + + convert_buffer_to_rgba(ogv); + + ogv->buffer_dirty = true; + + event.type = ALLEGRO_EVENT_VIDEO_FRAME_SHOW; + event.user.data1 = (intptr_t)video; + al_emit_user_event(&video->es, &event, NULL); + + al_unlock_mutex(ogv->mutex); + } + + return num_frames; +} + + +/* Seeking. */ + +static void seek_to_beginning(ALLEGRO_VIDEO *video, OGG_VIDEO *ogv, + THEORA_STREAM *tstream) +{ + unsigned i; + int rc; + bool seeked; + + for (i = 0; i < _al_vector_size(&ogv->streams); i++) { + STREAM **slot = _al_vector_ref(&ogv->streams, i); + STREAM *stream = *slot; + + ogg_stream_reset(&stream->state); + free_packet_queue(stream); + } + + if (tstream) { + ogg_int64_t granpos = 0; + + rc = th_decode_ctl(tstream->ctx, TH_DECCTL_SET_GRANPOS, &granpos, + sizeof(granpos)); + ASSERT(rc == 0); + + tstream->prev_framenum = -1; + } + + rc = ogg_sync_reset(&ogv->sync_state); + ASSERT(rc == 0); + + seeked = al_fseek(ogv->fp, 0, SEEK_SET); + ASSERT(seeked); + /* XXX read enough file data to get into position */ + + ogv->reached_eof = false; + video->audio_position = 0.0; + video->video_position = 0.0; + video->position = 0.0; + + /* XXX maybe clear backlog of time and stream fragment events */ +} + +/* Decode thread. */ + +static void *decode_thread_func(ALLEGRO_THREAD *thread, void *_video) +{ + ALLEGRO_VIDEO * const video = _video; + OGG_VIDEO * const ogv = video->data; + STREAM *tstream_outer; + THEORA_STREAM *tstream = NULL; + STREAM *vstream_outer; + VORBIS_STREAM *vstream = NULL; + ALLEGRO_TIMER *timer; + double audio_pos_step = 0.0; + double timer_dur; + + ALLEGRO_DEBUG("Thread started.\n"); + + tstream_outer = ogv->selected_video_stream; + if (tstream_outer) { + ASSERT(tstream_outer->stream_type == STREAM_TYPE_THEORA); + tstream = &tstream_outer->u.theora; + } + + vstream_outer = ogv->selected_audio_stream; + if (vstream_outer) { + ASSERT(vstream_outer->stream_type == STREAM_TYPE_VORBIS); + + video->audio = create_audio_stream(video, vstream_outer); + if (video->audio) { + vstream = &vstream_outer->u.vorbis; + audio_pos_step = (double)FRAG_SAMPLES / vstream->info.rate; + } + else { + deactivate_stream(vstream_outer); + vstream_outer = NULL; + } + } + + if (!tstream_outer && !vstream_outer) { + ALLEGRO_WARN("No audio or video stream found.\n"); + return NULL; + } + + timer_dur = 1.0; + if (audio_pos_step != 0.0) { + timer_dur = audio_pos_step / NUM_FRAGS; + } + if (tstream && tstream->frame_duration < timer_dur) { + timer_dur = tstream->frame_duration; + } + timer = al_create_timer(timer_dur); + al_register_event_source(ogv->queue, al_get_timer_event_source(timer)); + + if (video->audio) { + al_register_event_source(ogv->queue, + al_get_audio_stream_event_source(video->audio)); + } + + ALLEGRO_DEBUG("Begin decode loop.\n"); + + al_start_timer(timer); + + while (!al_get_thread_should_stop(thread)) { + ALLEGRO_EVENT ev; + + al_wait_for_event(ogv->queue, &ev); + + if (ev.type == _ALLEGRO_EVENT_VIDEO_SEEK) { + double seek_to = ev.user.data1 / 1.0e6; + /* XXX we only know how to seek to start of video */ + ASSERT(seek_to <= 0.0); + al_lock_mutex(ogv->mutex); + seek_to_beginning(video, ogv, tstream); + ogv->seek_counter++; + al_broadcast_cond(ogv->cond); + al_unlock_mutex(ogv->mutex); + continue; + } + + if (ev.type == ALLEGRO_EVENT_TIMER) { + if (vstream_outer && video->playing) { + poll_vorbis_decode(ogv, vstream_outer); + } + + /* If no audio then video is master. */ + if (!video->audio && video->playing && !ogv->reached_eof) { + video->position += tstream->frame_duration; + } + + if (tstream_outer) { + poll_theora_decode(video, tstream_outer); + } + + if (video->playing && ogv->reached_eof) { + ALLEGRO_EVENT event; + video->playing = false; + + event.type = ALLEGRO_EVENT_VIDEO_FINISHED; + event.user.data1 = (intptr_t)video; + al_emit_user_event(&video->es, &event, NULL); + } + } + + if (ev.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { + /* Audio clock is master when it exists. */ + /* XXX This doesn't work well when the process is paused then resumed, + * due to a problem with the audio addon. We get a flood of + * fragment events which pushes the position field ahead of the + * real audio position. + */ + if (video->playing && !ogv->reached_eof) { + video->audio_position += audio_pos_step; + video->position = video->audio_position - NUM_FRAGS * audio_pos_step; + } + update_audio_fragment(video->audio, vstream, !video->playing, + ogv->reached_eof); + } + } + + ALLEGRO_DEBUG("End decode loop.\n"); + + if (video->audio) { + al_drain_audio_stream(video->audio); + al_destroy_audio_stream(video->audio); + video->audio = NULL; + } + al_destroy_timer(timer); + + ALLEGRO_DEBUG("Thread exit.\n"); + + return NULL; +} + + +static bool update_frame_bmp(OGG_VIDEO *ogv) +{ + ALLEGRO_LOCKED_REGION *lr; + int y; + int pitch = al_get_pixel_size(RGB_PIXEL_FORMAT) * al_get_bitmap_width(ogv->frame_bmp); + + lr = al_lock_bitmap(ogv->frame_bmp, RGB_PIXEL_FORMAT, + ALLEGRO_LOCK_WRITEONLY); + if (!lr) { + ALLEGRO_ERROR("Failed to lock bitmap.\n"); + return false; + } + + for (y = 0; y < al_get_bitmap_height(ogv->frame_bmp); y++) { + memcpy((unsigned char*)lr->data + y * lr->pitch, ogv->rgb_data + y * pitch, pitch); + } + + al_unlock_bitmap(ogv->frame_bmp); + return true; +} + + +/* Video interface. */ + +static bool do_open_video(ALLEGRO_VIDEO *video, OGG_VIDEO *ogv) +{ + unsigned i; + + read_headers(ogv); + + /* Select the first Theora and Vorbis tracks. */ + for (i = 0; i < _al_vector_size(&ogv->streams); i++) { + STREAM **slot = _al_vector_ref(&ogv->streams, i); + STREAM *stream = *slot; + + if (stream->stream_type == STREAM_TYPE_THEORA && + !ogv->selected_video_stream) + { + setup_theora_stream_decode(video, ogv, stream); + ogv->selected_video_stream = stream; + } + else if (stream->stream_type == STREAM_TYPE_VORBIS && + !ogv->selected_audio_stream) + { + setup_vorbis_stream_decode(video, stream); + ogv->selected_audio_stream = stream; + } + else { + deactivate_stream(stream); + } + } + + return ogv->selected_video_stream || ogv->selected_audio_stream; +} + +static bool ogv_open_video(ALLEGRO_VIDEO *video) +{ + const char *filename; + ALLEGRO_FILE *fp; + OGG_VIDEO *ogv; + int rc; + + filename = al_path_cstr(video->filename, ALLEGRO_NATIVE_PATH_SEP); + fp = al_fopen(filename, "rb"); + if (!fp) { + ALLEGRO_WARN("Failed to open %s.\n", filename); + return false; + } + + ogv = al_calloc(1, sizeof(OGG_VIDEO)); + if (!ogv) { + ALLEGRO_ERROR("Out of memory.\n"); + al_fclose(fp); + return false; + } + ogv->fp = fp; + rc = ogg_sync_init(&ogv->sync_state); + ASSERT(rc == 0); + _al_vector_init(&ogv->streams, sizeof(STREAM *)); + + if (!do_open_video(video, ogv)) { + ALLEGRO_ERROR("No audio or video stream found.\n"); + ogv_close_video(video); + return false; + } + + /* ogv->mutex and ogv->thread are created in ogv_start_video. */ + + video->data = ogv; + return true; +} + +static bool ogv_close_video(ALLEGRO_VIDEO *video) +{ + OGG_VIDEO *ogv; + unsigned i; + + ogv = video->data; + if (ogv) { + if (ogv->thread) { + al_join_thread(ogv->thread, NULL); + al_destroy_user_event_source(&ogv->evtsrc); + al_destroy_event_queue(ogv->queue); + al_destroy_mutex(ogv->mutex); + al_destroy_cond(ogv->cond); + al_destroy_thread(ogv->thread); + } + + al_fclose(ogv->fp); + ogg_sync_clear(&ogv->sync_state); + for (i = 0; i < _al_vector_size(&ogv->streams); i++) { + STREAM **slot = _al_vector_ref(&ogv->streams, i); + free_stream(*slot); + } + _al_vector_free(&ogv->streams); + if (ogv->pic_bmp != ogv->frame_bmp) { + al_destroy_bitmap(ogv->pic_bmp); + } + al_destroy_bitmap(ogv->frame_bmp); + + al_free(ogv->rgb_data); + + al_free(ogv); + } + + video->data = NULL; + + return true; +} + +static bool ogv_start_video(ALLEGRO_VIDEO *video) +{ + OGG_VIDEO *ogv = video->data; + + if (ogv->thread != NULL) { + ALLEGRO_ERROR("Thread already created.\n"); + return false; + } + + ogv->thread = al_create_thread(decode_thread_func, video); + if (!ogv->thread) { + ALLEGRO_ERROR("Could not create thread.\n"); + return false; + } + + al_init_user_event_source(&ogv->evtsrc); + ogv->queue = al_create_event_queue(); + ogv->mutex = al_create_mutex(); + ogv->cond = al_create_cond(); + + al_register_event_source(ogv->queue, &ogv->evtsrc); + + al_start_thread(ogv->thread); + return true; +} + +static bool ogv_set_video_playing(ALLEGRO_VIDEO *video) +{ + OGG_VIDEO * const ogv = video->data; + if (ogv->reached_eof) { + video->playing = false; + } + return true; +} + +static bool ogv_seek_video(ALLEGRO_VIDEO *video, double seek_to) +{ + OGG_VIDEO *ogv = video->data; + ALLEGRO_EVENT ev; + int seek_counter; + + /* XXX we only know how to seek to beginning */ + if (seek_to > 0.0) { + return false; + } + + al_lock_mutex(ogv->mutex); + + seek_counter = ogv->seek_counter; + + ev.user.type = _ALLEGRO_EVENT_VIDEO_SEEK; + ev.user.data1 = seek_to * 1.0e6; + ev.user.data2 = 0; + ev.user.data3 = 0; + ev.user.data4 = 0; + al_emit_user_event(&ogv->evtsrc, &ev, NULL); + + while (seek_counter == ogv->seek_counter) { + al_wait_cond(ogv->cond, ogv->mutex); + } + + al_unlock_mutex(ogv->mutex); + + return true; +} + +static bool ogv_update_video(ALLEGRO_VIDEO *video) +{ + OGG_VIDEO *ogv = video->data; + int w, h; + bool ret; + + al_lock_mutex(ogv->mutex); + + w = ogv->buffer[0].width; + h = ogv->buffer[0].height; + + if (w > 0 && h && h > 0 && ogv->frame_bmp) { + ASSERT(w == al_get_bitmap_width(ogv->frame_bmp)); + ASSERT(h == al_get_bitmap_height(ogv->frame_bmp)); + + if (ogv->buffer_dirty) { + ret = update_frame_bmp(ogv); + ogv->buffer_dirty = false; + } + else { + ret = true; + } + + video->current_frame = ogv->pic_bmp; + } + else { + /* No frame ready yet. */ + ret = false; + } + + al_unlock_mutex(ogv->mutex); + + return ret; +} + +static ALLEGRO_VIDEO_INTERFACE ogv_vtable = { + ogv_open_video, + ogv_close_video, + ogv_start_video, + ogv_set_video_playing, + ogv_seek_video, + ogv_update_video +}; + +ALLEGRO_VIDEO_INTERFACE *_al_video_ogv_vtable(void) +{ + return &ogv_vtable; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/addons/video/video.c b/allegro/addons/video/video.c new file mode 100644 index 00000000..5d67a113 --- /dev/null +++ b/allegro/addons/video/video.c @@ -0,0 +1,327 @@ +/* This is just a quick hack. But good enough for our use of displaying + * a short intro video when our game starts up - so might as well share + * it. + * + * Known bugs: + * + * - Only very crude synching. Audio is slightly delayed and some + * videos seem to constantly drift off and then the audio gets all + * distorted... + * + * - Seeking/Pausing doesn't really work. + * + * - Memory leaks. Easy to fix but don't have time right now. + * + * Missing features: + * + * - Stream information. For example allow selection of one of several + * audio streams or subtitle overlay streams. + * + * - Non audio/video streams. For example something like: + * ALLEGRO_USTR *al_get_video_subtitle(float *x, float *y); + * + * - Buffering. Right now buffering is hardcoded to a fixed size which + * seemed enough for streaming 720p from disk in my tests. Obviously + * when streaming higher bandwidth or from a source with high + * fluctuation like an internet stream this won't work at all. + * + * - Provide an audio stream for the audio. Then could use this to + * stream audio files. Right now opening an .mp3 with the video + * addon will play it but only with the video API instead of Allegro's + * normal audio streaming API... + * + * - Audio/Video sync. For a game user-controlled sync is probably not + * too important as it can just ship with a properly synchronizeded + * video. However right now the audio delay is completely ignored. + * + * - Additional drivers. Also redo the API a bit so not everything + * has to be done by the driver. + */ + +#include "allegro5/allegro5.h" +#include "allegro5/allegro_video.h" +#include "allegro5/internal/aintern_video.h" +#include "allegro5/internal/aintern_video_cfg.h" +#include "allegro5/internal/aintern_exitfunc.h" + +ALLEGRO_DEBUG_CHANNEL("video") + + +/* globals */ +static bool video_inited = false; + +typedef struct VideoHandler { + struct VideoHandler *next; + const char *extension; + ALLEGRO_VIDEO_INTERFACE *vtable; +} VideoHandler; + +static VideoHandler *handlers; + +static ALLEGRO_VIDEO_INTERFACE *find_handler(const char *extension) +{ + VideoHandler *v = handlers; + while (v) { + if (!strcmp(extension, v->extension)) { + return v->vtable; + } + v = v->next; + } + return NULL; +} + +static void add_handler(const char *extension, ALLEGRO_VIDEO_INTERFACE *vtable) +{ + VideoHandler *v; + if (handlers == NULL) { + handlers = al_calloc(1, sizeof(VideoHandler)); + v = handlers; + } + else { + v = handlers; + while (v->next) { + v = v->next; + } + v->next = al_calloc(1, sizeof(VideoHandler)); + v = v->next; + } + v->extension = extension; + v->vtable = vtable; +} + +/* Function: al_open_video + */ +ALLEGRO_VIDEO *al_open_video(char const *filename) +{ + ALLEGRO_VIDEO *video; + const char *extension = filename + strlen(filename) - 1; + + while ((extension >= filename) && (*extension != '.')) + extension--; + video = al_calloc(1, sizeof *video); + + video->vtable = find_handler(extension); + + if (video->vtable == NULL) { + ALLEGRO_ERROR("No handler for video extension %s - " + "therefore not trying to load %s.\n", extension, filename); + al_free(video); + return NULL; + } + + video->filename = al_create_path(filename); + video->playing = true; + + if (!video->vtable->open_video(video)) { + ALLEGRO_ERROR("Could not open %s.\n", filename); + al_destroy_path(video->filename); + al_free(video); + return NULL; + } + + al_init_user_event_source(&video->es); + video->es_inited = true; + + return video; +} + +/* Function: al_close_video + */ +void al_close_video(ALLEGRO_VIDEO *video) +{ + if (video) { + video->vtable->close_video(video); + if (video->es_inited) { + al_destroy_user_event_source(&video->es); + } + al_destroy_path(video->filename); + al_free(video); + } +} + +/* Function: al_get_video_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_video_event_source(ALLEGRO_VIDEO *video) +{ + ASSERT(video); + return &video->es; +} + +/* Function: al_start_video + */ +void al_start_video(ALLEGRO_VIDEO *video, ALLEGRO_MIXER *mixer) +{ + ASSERT(video); + + /* XXX why is this not just a parameter? */ + video->mixer = mixer; + video->vtable->start_video(video); +} + +/* Function: al_start_video_with_voice + */ +void al_start_video_with_voice(ALLEGRO_VIDEO *video, ALLEGRO_VOICE *voice) +{ + ASSERT(video); + + /* XXX why is voice not just a parameter? */ + video->voice = voice; + video->vtable->start_video(video); +} + +/* Function: al_set_video_playing + */ +void al_set_video_playing(ALLEGRO_VIDEO *video, bool play) +{ + ASSERT(video); + + if (play != video->playing) { + video->playing = play; + video->vtable->set_video_playing(video); + } +} + +/* Function: al_is_video_playing + */ +bool al_is_video_playing(ALLEGRO_VIDEO *video) +{ + ASSERT(video); + + return video->playing; +} + +/* Function: al_get_video_frame + */ +ALLEGRO_BITMAP *al_get_video_frame(ALLEGRO_VIDEO *video) +{ + ASSERT(video); + + video->vtable->update_video(video); + return video->current_frame; +} + +/* Function: al_get_video_position + */ +double al_get_video_position(ALLEGRO_VIDEO *video, ALLEGRO_VIDEO_POSITION_TYPE which) +{ + ASSERT(video); + + if (which == ALLEGRO_VIDEO_POSITION_VIDEO_DECODE) + return video->video_position; + if (which == ALLEGRO_VIDEO_POSITION_AUDIO_DECODE) + return video->audio_position; + return video->position; +} + +/* Function: al_seek_video + */ +bool al_seek_video(ALLEGRO_VIDEO *video, double pos_in_seconds) +{ + ASSERT(video); + + return video->vtable->seek_video(video, pos_in_seconds); +} + +/* Function: al_get_video_audio_rate + */ +double al_get_video_audio_rate(ALLEGRO_VIDEO *video) +{ + ASSERT(video); + return video->audio_rate; +} + +/* Function: al_get_video_fps + */ +double al_get_video_fps(ALLEGRO_VIDEO *video) +{ + ASSERT(video); + return video->fps; +} + +/* Function: al_get_video_scaled_width + */ +float al_get_video_scaled_width(ALLEGRO_VIDEO *video) +{ + ASSERT(video); + return video->scaled_width; +} + +/* Function: al_get_video_scaled_height + */ +float al_get_video_scaled_height(ALLEGRO_VIDEO *video) +{ + ASSERT(video); + return video->scaled_height; +} + +/* Function: al_init_video_addon + */ +bool al_init_video_addon(void) +{ + if (video_inited) + return true; + +#ifdef ALLEGRO_CFG_VIDEO_HAVE_OGV + add_handler(".ogv", _al_video_ogv_vtable()); +#endif + + if (handlers == NULL) { + ALLEGRO_WARN("No video handlers available!\n"); + return false; + } + + _al_add_exit_func(al_shutdown_video_addon, "al_shutdown_video_addon"); + + return true; +} + + +/* Function: al_is_video_addon_initialized + */ +bool al_is_video_addon_initialized(void) +{ + return video_inited; +} + + +/* Function: al_shutdown_video_addon + */ +void al_shutdown_video_addon(void) +{ + if (!video_inited) + return; + + VideoHandler *v = handlers; + while (v) { + VideoHandler *next = v->next; + al_free(v); + v = next; + } + video_inited = false; + handlers = NULL; +} + + +/* Function: al_get_allegro_video_version + */ +uint32_t al_get_allegro_video_version(void) +{ + return ALLEGRO_VERSION_INT; +} + +/* The returned width and height are always greater than or equal to the frame + * width and height. */ +void _al_compute_scaled_dimensions(int frame_w, int frame_h, float aspect_ratio, + float *scaled_w, float *scaled_h) +{ + if (aspect_ratio > 1.0) { + *scaled_w = frame_h * aspect_ratio; + *scaled_h = frame_h; + } + else { + *scaled_w = frame_w; + *scaled_h = frame_w / aspect_ratio; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/allegro.mft b/allegro/allegro.mft new file mode 100644 index 00000000..80115c1f --- /dev/null +++ b/allegro/allegro.mft @@ -0,0 +1,2370 @@ +allegro/ +allegro/CHANGES-5.0.txt +allegro/CHANGES-5.1.txt +allegro/CHANGES-5.2.txt +allegro/CMakeLists.txt +allegro/CONTRIBUTORS.txt +allegro/LICENSE.txt +allegro/README.txt +allegro/README_android.txt +allegro/README_cmake.txt +allegro/README_iphone.txt +allegro/README_macosx.txt +allegro/README_make.txt +allegro/README_msvc.txt +allegro/README_packaging.txt +allegro/README_pkgconfig.txt +allegro/README_raspberrypi.txt +allegro/README_releasing.txt +allegro/README_sdl.txt +allegro/README_windows.txt +allegro/SECURITY.md +allegro/addons/ +allegro/addons/CMakeLists.txt +allegro/addons/acodec/ +allegro/addons/acodec/CMakeLists.txt +allegro/addons/acodec/acodec.c +allegro/addons/acodec/acodec.h +allegro/addons/acodec/allegro5/ +allegro/addons/acodec/allegro5/allegro_acodec.h +allegro/addons/acodec/allegro5/internal/ +allegro/addons/acodec/allegro5/internal/aintern_acodec_cfg.h.cmake +allegro/addons/acodec/flac.c +allegro/addons/acodec/helper.c +allegro/addons/acodec/helper.h +allegro/addons/acodec/modaudio.c +allegro/addons/acodec/mp3.c +allegro/addons/acodec/ogg.c +allegro/addons/acodec/opus.c +allegro/addons/acodec/voc.c +allegro/addons/acodec/wav.c +allegro/addons/audio/ +allegro/addons/audio/CMakeLists.txt +allegro/addons/audio/allegro5/ +allegro/addons/audio/allegro5/allegro_audio.h +allegro/addons/audio/allegro5/internal/ +allegro/addons/audio/allegro5/internal/aintern_audio.h +allegro/addons/audio/allegro5/internal/aintern_audio_cfg.h.cmake +allegro/addons/audio/alsa.c +allegro/addons/audio/aqueue.m +allegro/addons/audio/audio.c +allegro/addons/audio/audio_io.c +allegro/addons/audio/dsound.cpp +allegro/addons/audio/kcm_dtor.c +allegro/addons/audio/kcm_instance.c +allegro/addons/audio/kcm_mixer.c +allegro/addons/audio/kcm_mixer_helpers.inc +allegro/addons/audio/kcm_sample.c +allegro/addons/audio/kcm_stream.c +allegro/addons/audio/kcm_voice.c +allegro/addons/audio/openal.c +allegro/addons/audio/opensl.c +allegro/addons/audio/oss.c +allegro/addons/audio/pulseaudio.c +allegro/addons/audio/recorder.c +allegro/addons/audio/sdl_audio.c +allegro/addons/color/ +allegro/addons/color/CMakeLists.txt +allegro/addons/color/allegro5/ +allegro/addons/color/allegro5/allegro_color.h +allegro/addons/color/color.c +allegro/addons/font/ +allegro/addons/font/CMakeLists.txt +allegro/addons/font/allegro5/ +allegro/addons/font/allegro5/allegro_font.h +allegro/addons/font/allegro5/internal/ +allegro/addons/font/allegro5/internal/aintern_font.h +allegro/addons/font/bmfont.c +allegro/addons/font/font.c +allegro/addons/font/font.h +allegro/addons/font/fontbmp.c +allegro/addons/font/stdfont.c +allegro/addons/font/text.c +allegro/addons/font/xml.c +allegro/addons/font/xml.h +allegro/addons/image/ +allegro/addons/image/CMakeLists.txt +allegro/addons/image/allegro5/ +allegro/addons/image/allegro5/allegro_image.h +allegro/addons/image/allegro5/internal/ +allegro/addons/image/allegro5/internal/aintern_image.h +allegro/addons/image/allegro5/internal/aintern_image_cfg.h.cmake +allegro/addons/image/android.c +allegro/addons/image/bmp.c +allegro/addons/image/dds.c +allegro/addons/image/freeimage.c +allegro/addons/image/gdiplus.cpp +allegro/addons/image/identify.c +allegro/addons/image/iio.c +allegro/addons/image/iio.h +allegro/addons/image/iphone.m +allegro/addons/image/jpg.c +allegro/addons/image/macosx.m +allegro/addons/image/pcx.c +allegro/addons/image/png.c +allegro/addons/image/tga.c +allegro/addons/image/webp.c +allegro/addons/main/ +allegro/addons/main/CMakeLists.txt +allegro/addons/main/generic_main.c +allegro/addons/main/osx_main.m +allegro/addons/memfile/ +allegro/addons/memfile/CMakeLists.txt +allegro/addons/memfile/allegro5/ +allegro/addons/memfile/allegro5/allegro_memfile.h +allegro/addons/memfile/memfile.c +allegro/addons/native_dialog/ +allegro/addons/native_dialog/CMakeLists.txt +allegro/addons/native_dialog/allegro5/ +allegro/addons/native_dialog/allegro5/allegro_native_dialog.h +allegro/addons/native_dialog/allegro5/internal/ +allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog.h +allegro/addons/native_dialog/allegro5/internal/aintern_native_dialog_cfg.h.cmake +allegro/addons/native_dialog/dialog.c +allegro/addons/native_dialog/gtk_dialog.c +allegro/addons/native_dialog/gtk_dialog.h +allegro/addons/native_dialog/gtk_filesel.c +allegro/addons/native_dialog/gtk_menu.c +allegro/addons/native_dialog/gtk_msgbox.c +allegro/addons/native_dialog/gtk_textlog.c +allegro/addons/native_dialog/gtk_thread.c +allegro/addons/native_dialog/gtk_xgtk.c +allegro/addons/native_dialog/gtk_xgtk.h +allegro/addons/native_dialog/iphone_dialog.m +allegro/addons/native_dialog/menu.c +allegro/addons/native_dialog/osx_dialog.m +allegro/addons/native_dialog/textlog.c +allegro/addons/native_dialog/win_dialog.c +allegro/addons/physfs/ +allegro/addons/physfs/CMakeLists.txt +allegro/addons/physfs/a5_physfs.c +allegro/addons/physfs/a5_physfs_dir.c +allegro/addons/physfs/allegro5/ +allegro/addons/physfs/allegro5/allegro_physfs.h +allegro/addons/physfs/allegro_physfs_intern.h +allegro/addons/primitives/ +allegro/addons/primitives/CMakeLists.txt +allegro/addons/primitives/allegro5/ +allegro/addons/primitives/allegro5/allegro_primitives.h +allegro/addons/primitives/allegro5/internal/ +allegro/addons/primitives/allegro5/internal/aintern_prim.h +allegro/addons/primitives/allegro5/internal/aintern_prim_directx.h +allegro/addons/primitives/allegro5/internal/aintern_prim_opengl.h +allegro/addons/primitives/allegro5/internal/aintern_prim_soft.h +allegro/addons/primitives/directx_shaders.cpp +allegro/addons/primitives/high_primitives.c +allegro/addons/primitives/line_soft.c +allegro/addons/primitives/nshader.cpp +allegro/addons/primitives/nshader.fx +allegro/addons/primitives/point_soft.c +allegro/addons/primitives/polygon.c +allegro/addons/primitives/polyline.c +allegro/addons/primitives/precompiled_shaders.inc +allegro/addons/primitives/prim_directx.cpp +allegro/addons/primitives/prim_opengl.c +allegro/addons/primitives/prim_soft.c +allegro/addons/primitives/prim_util.c +allegro/addons/primitives/primitives.c +allegro/addons/primitives/triangulator.c +allegro/addons/ttf/ +allegro/addons/ttf/CMakeLists.txt +allegro/addons/ttf/allegro5/ +allegro/addons/ttf/allegro5/allegro_ttf.h +allegro/addons/ttf/allegro5/internal/ +allegro/addons/ttf/allegro5/internal/aintern_ttf_cfg.h.cmake +allegro/addons/ttf/ttf.c +allegro/addons/video/ +allegro/addons/video/CMakeLists.txt +allegro/addons/video/allegro5/ +allegro/addons/video/allegro5/allegro_video.h +allegro/addons/video/allegro5/internal/ +allegro/addons/video/allegro5/internal/aintern_video.h +allegro/addons/video/allegro5/internal/aintern_video_cfg.h.cmake +allegro/addons/video/ogv.c +allegro/addons/video/video.c +allegro/allegro5.cfg +allegro/android/ +allegro/android/CMakeLists.txt +allegro/android/gradle_project/ +allegro/android/gradle_project/allegro/ +allegro/android/gradle_project/allegro/build.gradle +allegro/android/gradle_project/allegro/src/ +allegro/android/gradle_project/allegro/src/main/ +allegro/android/gradle_project/allegro/src/main/AndroidManifest.xml +allegro/android/gradle_project/allegro/src/main/java/ +allegro/android/gradle_project/allegro/src/main/java/org/ +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/ +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroAPKList.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroAPKStream.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroActivity.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroEGL.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroInputStream.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroJoystick.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroSurface.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Clipboard.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Const.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ImageLoader.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Key.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/KeyListener.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Path.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Reflect.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ScreenLock.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Sensors.java +allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/TouchListener.java +allegro/android/gradle_project/app/ +allegro/android/gradle_project/app/build.gradle +allegro/android/gradle_project/app/src/ +allegro/android/gradle_project/app/src/main/ +allegro/android/gradle_project/app/src/main/AndroidManifest.xml +allegro/android/gradle_project/app/src/main/java/ +allegro/android/gradle_project/app/src/main/java/org/ +allegro/android/gradle_project/app/src/main/java/org/liballeg/ +allegro/android/gradle_project/app/src/main/java/org/liballeg/app/ +allegro/android/gradle_project/app/src/main/java/org/liballeg/app/MainActivity.java +allegro/android/gradle_project/build.gradle +allegro/android/gradle_project/gradle.properties +allegro/android/gradle_project/gradle/ +allegro/android/gradle_project/gradle/wrapper/ +allegro/android/gradle_project/gradle/wrapper/gradle-wrapper.jar +allegro/android/gradle_project/gradle/wrapper/gradle-wrapper.properties +allegro/android/gradle_project/gradlew +allegro/android/gradle_project/local.properties +allegro/android/gradle_project/settings.gradle +allegro/appveyor.yml +allegro/cmake/ +allegro/cmake/AllegroFindFFMPEG.cmake +allegro/cmake/AllegroFindOSS.cmake +allegro/cmake/AndroidApp.cmake +allegro/cmake/Common.cmake +allegro/cmake/FileList.cmake +allegro/cmake/FindCg.cmake +allegro/cmake/FindDUMB.cmake +allegro/cmake/FindDXGuid.cmake +allegro/cmake/FindDirectX.cmake +allegro/cmake/FindENet.cmake +allegro/cmake/FindFLAC.cmake +allegro/cmake/FindFreeImage.cmake +allegro/cmake/FindGDIPLUS.cmake +allegro/cmake/FindHarfBuzz.cmake +allegro/cmake/FindMiniMP3.cmake +allegro/cmake/FindOgg.cmake +allegro/cmake/FindOpenGLES1.cmake +allegro/cmake/FindOpenGLES2.cmake +allegro/cmake/FindOpenSL.cmake +allegro/cmake/FindOpus.cmake +allegro/cmake/FindSDL2.cmake +allegro/cmake/FindTheora.cmake +allegro/cmake/FindTremor.cmake +allegro/cmake/FindVorbis.cmake +allegro/cmake/FindWebP.cmake +allegro/cmake/Toolchain-iphone.cmake +allegro/cmake/Toolchain-mingw.cmake +allegro/cmake/Toolchain-openwiz.cmake +allegro/cmake/Toolchain-raspberrypi.cmake +allegro/contrib/ +allegro/contrib/luajit/ +allegro/contrib/luajit/CMakeLists.txt +allegro/contrib/luajit/README.txt +allegro/contrib/luajit/generate_luajit_ffi.py +allegro/demos/ +allegro/demos/cosmic_protector/ +allegro/demos/cosmic_protector/CMakeLists.txt +allegro/demos/cosmic_protector/data/ +allegro/demos/cosmic_protector/data/gfx/ +allegro/demos/cosmic_protector/data/gfx/Icon.icns +allegro/demos/cosmic_protector/data/gfx/background.jpg +allegro/demos/cosmic_protector/data/gfx/icon48.png +allegro/demos/cosmic_protector/data/gfx/large_asteroid.png +allegro/demos/cosmic_protector/data/gfx/large_bullet.png +allegro/demos/cosmic_protector/data/gfx/large_explosion_0.png +allegro/demos/cosmic_protector/data/gfx/large_explosion_1.png +allegro/demos/cosmic_protector/data/gfx/large_explosion_2.png +allegro/demos/cosmic_protector/data/gfx/large_explosion_3.png +allegro/demos/cosmic_protector/data/gfx/large_explosion_4.png +allegro/demos/cosmic_protector/data/gfx/large_font.png +allegro/demos/cosmic_protector/data/gfx/life_powerup.png +allegro/demos/cosmic_protector/data/gfx/logo.png +allegro/demos/cosmic_protector/data/gfx/medium_asteroid.png +allegro/demos/cosmic_protector/data/gfx/ship.png +allegro/demos/cosmic_protector/data/gfx/ship_icon.tga +allegro/demos/cosmic_protector/data/gfx/ship_trans.png +allegro/demos/cosmic_protector/data/gfx/small_asteroid.png +allegro/demos/cosmic_protector/data/gfx/small_bullet.png +allegro/demos/cosmic_protector/data/gfx/small_explosion_0.png +allegro/demos/cosmic_protector/data/gfx/small_explosion_1.png +allegro/demos/cosmic_protector/data/gfx/small_explosion_2.png +allegro/demos/cosmic_protector/data/gfx/small_explosion_3.png +allegro/demos/cosmic_protector/data/gfx/small_explosion_4.png +allegro/demos/cosmic_protector/data/gfx/small_font.png +allegro/demos/cosmic_protector/data/gfx/trail.png +allegro/demos/cosmic_protector/data/gfx/ufo0.png +allegro/demos/cosmic_protector/data/gfx/ufo1.png +allegro/demos/cosmic_protector/data/gfx/ufo2.png +allegro/demos/cosmic_protector/data/gfx/weapon_powerup.png +allegro/demos/cosmic_protector/data/sfx/ +allegro/demos/cosmic_protector/data/sfx/big_explosion.ogg +allegro/demos/cosmic_protector/data/sfx/collision.ogg +allegro/demos/cosmic_protector/data/sfx/fire_large.ogg +allegro/demos/cosmic_protector/data/sfx/fire_small.ogg +allegro/demos/cosmic_protector/data/sfx/game_music.ogg +allegro/demos/cosmic_protector/data/sfx/powerup.ogg +allegro/demos/cosmic_protector/data/sfx/small_explosion.ogg +allegro/demos/cosmic_protector/data/sfx/title_music.ogg +allegro/demos/cosmic_protector/include/ +allegro/demos/cosmic_protector/include/Asteroid.hpp +allegro/demos/cosmic_protector/include/BitmapResource.hpp +allegro/demos/cosmic_protector/include/Bullet.hpp +allegro/demos/cosmic_protector/include/ButtonWidget.hpp +allegro/demos/cosmic_protector/include/Debug.hpp +allegro/demos/cosmic_protector/include/DisplayResource.hpp +allegro/demos/cosmic_protector/include/Entity.hpp +allegro/demos/cosmic_protector/include/Explosion.hpp +allegro/demos/cosmic_protector/include/FontResource.hpp +allegro/demos/cosmic_protector/include/Game.hpp +allegro/demos/cosmic_protector/include/Input.hpp +allegro/demos/cosmic_protector/include/LargeAsteroid.hpp +allegro/demos/cosmic_protector/include/LargeBullet.hpp +allegro/demos/cosmic_protector/include/LargeSlowBullet.hpp +allegro/demos/cosmic_protector/include/MediumAsteroid.hpp +allegro/demos/cosmic_protector/include/Player.hpp +allegro/demos/cosmic_protector/include/PowerUp.hpp +allegro/demos/cosmic_protector/include/Resource.hpp +allegro/demos/cosmic_protector/include/ResourceManager.hpp +allegro/demos/cosmic_protector/include/SampleResource.hpp +allegro/demos/cosmic_protector/include/SmallAsteroid.hpp +allegro/demos/cosmic_protector/include/SmallBullet.hpp +allegro/demos/cosmic_protector/include/StreamResource.hpp +allegro/demos/cosmic_protector/include/UFO.hpp +allegro/demos/cosmic_protector/include/Wave.hpp +allegro/demos/cosmic_protector/include/Weapon.hpp +allegro/demos/cosmic_protector/include/Widget.hpp +allegro/demos/cosmic_protector/include/collision.hpp +allegro/demos/cosmic_protector/include/cosmic_protector.hpp +allegro/demos/cosmic_protector/include/cosmic_protector_objc.h +allegro/demos/cosmic_protector/include/gui.hpp +allegro/demos/cosmic_protector/include/joypad_c.h +allegro/demos/cosmic_protector/include/joypad_handler.h +allegro/demos/cosmic_protector/include/logic.hpp +allegro/demos/cosmic_protector/include/render.hpp +allegro/demos/cosmic_protector/include/sound.hpp +allegro/demos/cosmic_protector/src/ +allegro/demos/cosmic_protector/src/Asteroid.cpp +allegro/demos/cosmic_protector/src/BitmapResource.cpp +allegro/demos/cosmic_protector/src/Bullet.cpp +allegro/demos/cosmic_protector/src/ButtonWidget.cpp +allegro/demos/cosmic_protector/src/Debug.cpp +allegro/demos/cosmic_protector/src/DisplayResource.cpp +allegro/demos/cosmic_protector/src/Entity.cpp +allegro/demos/cosmic_protector/src/Explosion.cpp +allegro/demos/cosmic_protector/src/FontResource.cpp +allegro/demos/cosmic_protector/src/GUI.cpp +allegro/demos/cosmic_protector/src/Game.cpp +allegro/demos/cosmic_protector/src/Input.cpp +allegro/demos/cosmic_protector/src/LargeAsteroid.cpp +allegro/demos/cosmic_protector/src/LargeBullet.cpp +allegro/demos/cosmic_protector/src/LargeSlowBullet.cpp +allegro/demos/cosmic_protector/src/MediumAsteroid.cpp +allegro/demos/cosmic_protector/src/Player.cpp +allegro/demos/cosmic_protector/src/PowerUp.cpp +allegro/demos/cosmic_protector/src/Resource.cpp +allegro/demos/cosmic_protector/src/ResourceManager.cpp +allegro/demos/cosmic_protector/src/SampleResource.cpp +allegro/demos/cosmic_protector/src/SmallAsteroid.cpp +allegro/demos/cosmic_protector/src/SmallBullet.cpp +allegro/demos/cosmic_protector/src/StreamResource.cpp +allegro/demos/cosmic_protector/src/UFO.cpp +allegro/demos/cosmic_protector/src/collision.cpp +allegro/demos/cosmic_protector/src/cosmic_protector.cpp +allegro/demos/cosmic_protector/src/cosmic_protector_objc.m +allegro/demos/cosmic_protector/src/joypad_dummy.cpp +allegro/demos/cosmic_protector/src/joypad_handler.m +allegro/demos/cosmic_protector/src/logic.cpp +allegro/demos/cosmic_protector/src/render.cpp +allegro/demos/cosmic_protector/src/sound.cpp +allegro/demos/cosmic_protector/src/wave.cpp +allegro/demos/skater/ +allegro/demos/skater/CMakeLists.txt +allegro/demos/skater/blender/ +allegro/demos/skater/blender/ademo_export.py +allegro/demos/skater/blender/level.blend.gz +allegro/demos/skater/blender/readme.txt +allegro/demos/skater/data/ +allegro/demos/skater/data/audio/ +allegro/demos/skater/data/audio/ding.ogg +allegro/demos/skater/data/audio/dooropen.ogg +allegro/demos/skater/data/audio/pop.ogg +allegro/demos/skater/data/audio/skating.ogg +allegro/demos/skater/data/audio/wave.ogg +allegro/demos/skater/data/graphics/ +allegro/demos/skater/data/graphics/bananas.png +allegro/demos/skater/data/graphics/cherries.png +allegro/demos/skater/data/graphics/cloud.png +allegro/demos/skater/data/graphics/dooropen.png +allegro/demos/skater/data/graphics/doorshut.png +allegro/demos/skater/data/graphics/exitsign.png +allegro/demos/skater/data/graphics/grass.png +allegro/demos/skater/data/graphics/ice.png +allegro/demos/skater/data/graphics/icecream.png +allegro/demos/skater/data/graphics/icetip.png +allegro/demos/skater/data/graphics/orange.png +allegro/demos/skater/data/graphics/skatefast.png +allegro/demos/skater/data/graphics/skatemed.png +allegro/demos/skater/data/graphics/skater1.png +allegro/demos/skater/data/graphics/skater2.png +allegro/demos/skater/data/graphics/skater3.png +allegro/demos/skater/data/graphics/skater4.png +allegro/demos/skater/data/graphics/skateslow.png +allegro/demos/skater/data/graphics/soil.png +allegro/demos/skater/data/graphics/sweet.png +allegro/demos/skater/data/graphics/water.png +allegro/demos/skater/data/level.txt +allegro/demos/skater/data/menu/ +allegro/demos/skater/data/menu/back.png +allegro/demos/skater/data/menu/button.ogg +allegro/demos/skater/data/menu/cancunsmall.png +allegro/demos/skater/data/menu/endoflevel.ogg +allegro/demos/skater/data/menu/intro_music.ogg +allegro/demos/skater/data/menu/logofont.png +allegro/demos/skater/data/menu/menu_music.ogg +allegro/demos/skater/data/menu/skate2.ogg +allegro/demos/skater/data/menu/welcome.ogg +allegro/demos/skater/data/readme.txt +allegro/demos/skater/data/thanks.txt +allegro/demos/skater/src/ +allegro/demos/skater/src/anim.c +allegro/demos/skater/src/anim.h +allegro/demos/skater/src/background_scroller.c +allegro/demos/skater/src/background_scroller.h +allegro/demos/skater/src/credits.c +allegro/demos/skater/src/credits.h +allegro/demos/skater/src/defines.h +allegro/demos/skater/src/demodata.h +allegro/demos/skater/src/fps.c +allegro/demos/skater/src/fps.h +allegro/demos/skater/src/framework.c +allegro/demos/skater/src/framework.h +allegro/demos/skater/src/game.c +allegro/demos/skater/src/game.h +allegro/demos/skater/src/gamepad.c +allegro/demos/skater/src/gamepad.h +allegro/demos/skater/src/gamestate.h +allegro/demos/skater/src/global.c +allegro/demos/skater/src/global.h +allegro/demos/skater/src/intro.c +allegro/demos/skater/src/keyboard.c +allegro/demos/skater/src/keyboard.h +allegro/demos/skater/src/level.c +allegro/demos/skater/src/level.h +allegro/demos/skater/src/level_alloc.c +allegro/demos/skater/src/level_alloc.h +allegro/demos/skater/src/level_file.c +allegro/demos/skater/src/level_file.h +allegro/demos/skater/src/level_state.c +allegro/demos/skater/src/menu.c +allegro/demos/skater/src/menu.h +allegro/demos/skater/src/menu_about.c +allegro/demos/skater/src/menu_controls.c +allegro/demos/skater/src/menu_graphics.c +allegro/demos/skater/src/menu_main.c +allegro/demos/skater/src/menu_misc.c +allegro/demos/skater/src/menu_options.c +allegro/demos/skater/src/menu_sound.c +allegro/demos/skater/src/menu_success.c +allegro/demos/skater/src/menus.h +allegro/demos/skater/src/mouse.c +allegro/demos/skater/src/mouse.h +allegro/demos/skater/src/music.c +allegro/demos/skater/src/music.h +allegro/demos/skater/src/physics.c +allegro/demos/skater/src/physics.h +allegro/demos/skater/src/quadtree.c +allegro/demos/skater/src/quadtree.h +allegro/demos/skater/src/screenshot.c +allegro/demos/skater/src/screenshot.h +allegro/demos/skater/src/skater.c +allegro/demos/skater/src/token.c +allegro/demos/skater/src/token.h +allegro/demos/skater/src/transition.c +allegro/demos/skater/src/transition.h +allegro/demos/skater/src/vcontroller.c +allegro/demos/skater/src/vcontroller.h +allegro/demos/speed/ +allegro/demos/speed/29.txt +allegro/demos/speed/CMakeLists.txt +allegro/demos/speed/a4_aux.c +allegro/demos/speed/a4_aux.h +allegro/demos/speed/badguys.c +allegro/demos/speed/bullets.c +allegro/demos/speed/explode.c +allegro/demos/speed/hiscore.c +allegro/demos/speed/main.c +allegro/demos/speed/message.c +allegro/demos/speed/player.c +allegro/demos/speed/port.txt +allegro/demos/speed/sound.c +allegro/demos/speed/speed.h +allegro/demos/speed/speed.txt +allegro/demos/speed/title.c +allegro/demos/speed/update.pl +allegro/demos/speed/view.c +allegro/docs/ +allegro/docs/CMakeLists.txt +allegro/docs/Refman.cmake +allegro/docs/html/ +allegro/docs/html/refman/ +allegro/docs/html/refman/acodec.html +allegro/docs/html/refman/audio.html +allegro/docs/html/refman/autosuggest.js +allegro/docs/html/refman/color.html +allegro/docs/html/refman/config.html +allegro/docs/html/refman/direct3d.html +allegro/docs/html/refman/display.html +allegro/docs/html/refman/events.html +allegro/docs/html/refman/file.html +allegro/docs/html/refman/fixed.html +allegro/docs/html/refman/font.html +allegro/docs/html/refman/fshook.html +allegro/docs/html/refman/fullscreen_mode.html +allegro/docs/html/refman/getting_started.html +allegro/docs/html/refman/graphics.html +allegro/docs/html/refman/haptic.html +allegro/docs/html/refman/image.html +allegro/docs/html/refman/images/ +allegro/docs/html/refman/images/LINE_CAP.png +allegro/docs/html/refman/images/LINE_JOIN.png +allegro/docs/html/refman/images/audio.png +allegro/docs/html/refman/images/primitives1.png +allegro/docs/html/refman/images/primitives2.png +allegro/docs/html/refman/index.html +allegro/docs/html/refman/index_all.html +allegro/docs/html/refman/joystick.html +allegro/docs/html/refman/keyboard.html +allegro/docs/html/refman/main.html +allegro/docs/html/refman/memfile.html +allegro/docs/html/refman/memory.html +allegro/docs/html/refman/misc.html +allegro/docs/html/refman/monitor.html +allegro/docs/html/refman/mouse.html +allegro/docs/html/refman/native_dialog.html +allegro/docs/html/refman/opengl.html +allegro/docs/html/refman/pandoc.css +allegro/docs/html/refman/path.html +allegro/docs/html/refman/physfs.html +allegro/docs/html/refman/platform.html +allegro/docs/html/refman/primitives.html +allegro/docs/html/refman/search_index.js +allegro/docs/html/refman/shader.html +allegro/docs/html/refman/state.html +allegro/docs/html/refman/system.html +allegro/docs/html/refman/threads.html +allegro/docs/html/refman/time.html +allegro/docs/html/refman/timer.html +allegro/docs/html/refman/touch.html +allegro/docs/html/refman/transformations.html +allegro/docs/html/refman/utf8.html +allegro/docs/html/refman/video.html +allegro/docs/man/ +allegro/docs/man/ALLEGRO_AUDIO_DEPTH.3 +allegro/docs/man/ALLEGRO_AUDIO_EVENT_TYPE.3 +allegro/docs/man/ALLEGRO_AUDIO_PAN_NONE.3 +allegro/docs/man/ALLEGRO_AUDIO_RECORDER.3 +allegro/docs/man/ALLEGRO_AUDIO_RECORDER_EVENT.3 +allegro/docs/man/ALLEGRO_AUDIO_STREAM.3 +allegro/docs/man/ALLEGRO_BITMAP.3 +allegro/docs/man/ALLEGRO_BPM_TO_SECS.3 +allegro/docs/man/ALLEGRO_BPS_TO_SECS.3 +allegro/docs/man/ALLEGRO_CHANNEL_CONF.3 +allegro/docs/man/ALLEGRO_COLOR.3 +allegro/docs/man/ALLEGRO_COND.3 +allegro/docs/man/ALLEGRO_CONFIG.3 +allegro/docs/man/ALLEGRO_CONFIG_ENTRY.3 +allegro/docs/man/ALLEGRO_CONFIG_SECTION.3 +allegro/docs/man/ALLEGRO_DISPLAY.3 +allegro/docs/man/ALLEGRO_DISPLAY_MODE.3 +allegro/docs/man/ALLEGRO_EVENT.3 +allegro/docs/man/ALLEGRO_EVENT_QUEUE.3 +allegro/docs/man/ALLEGRO_EVENT_SOURCE.3 +allegro/docs/man/ALLEGRO_EVENT_TYPE.3 +allegro/docs/man/ALLEGRO_EVENT_TYPE_IS_USER.3 +allegro/docs/man/ALLEGRO_FILE.3 +allegro/docs/man/ALLEGRO_FILECHOOSER.3 +allegro/docs/man/ALLEGRO_FILE_INTERFACE.3 +allegro/docs/man/ALLEGRO_FILE_MODE.3 +allegro/docs/man/ALLEGRO_FONT.3 +allegro/docs/man/ALLEGRO_FOR_EACH_FS_ENTRY_RESULT.3 +allegro/docs/man/ALLEGRO_FS_ENTRY.3 +allegro/docs/man/ALLEGRO_FS_INTERFACE.3 +allegro/docs/man/ALLEGRO_GET_EVENT_TYPE.3 +allegro/docs/man/ALLEGRO_GLYPH.3 +allegro/docs/man/ALLEGRO_HAPTIC.3 +allegro/docs/man/ALLEGRO_HAPTIC_CONSTANTS.3 +allegro/docs/man/ALLEGRO_HAPTIC_EFFECT.3 +allegro/docs/man/ALLEGRO_HAPTIC_EFFECT_ID.3 +allegro/docs/man/ALLEGRO_INDEX_BUFFER.3 +allegro/docs/man/ALLEGRO_JOYFLAGS.3 +allegro/docs/man/ALLEGRO_JOYSTICK.3 +allegro/docs/man/ALLEGRO_JOYSTICK_STATE.3 +allegro/docs/man/ALLEGRO_KEYBOARD_STATE.3 +allegro/docs/man/ALLEGRO_LINE_CAP.3 +allegro/docs/man/ALLEGRO_LINE_JOIN.3 +allegro/docs/man/ALLEGRO_LOCKED_REGION.3 +allegro/docs/man/ALLEGRO_MEMORY_INTERFACE.3 +allegro/docs/man/ALLEGRO_MENU.3 +allegro/docs/man/ALLEGRO_MENU_INFO.3 +allegro/docs/man/ALLEGRO_MIXER.3 +allegro/docs/man/ALLEGRO_MIXER_QUALITY.3 +allegro/docs/man/ALLEGRO_MONITOR_INFO.3 +allegro/docs/man/ALLEGRO_MOUSE_EMULATION_MODE.3 +allegro/docs/man/ALLEGRO_MOUSE_STATE.3 +allegro/docs/man/ALLEGRO_MSECS_TO_SECS.3 +allegro/docs/man/ALLEGRO_MUTEX.3 +allegro/docs/man/ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE.3 +allegro/docs/man/ALLEGRO_PI.3 +allegro/docs/man/ALLEGRO_PIXEL_FORMAT.3 +allegro/docs/man/ALLEGRO_PLAYMODE.3 +allegro/docs/man/ALLEGRO_PRIM_ATTR.3 +allegro/docs/man/ALLEGRO_PRIM_BUFFER_FLAGS.3 +allegro/docs/man/ALLEGRO_PRIM_QUALITY.3 +allegro/docs/man/ALLEGRO_PRIM_STORAGE.3 +allegro/docs/man/ALLEGRO_PRIM_TYPE.3 +allegro/docs/man/ALLEGRO_RENDER_FUNCTION.3 +allegro/docs/man/ALLEGRO_RENDER_STATE.3 +allegro/docs/man/ALLEGRO_SAMPLE.3 +allegro/docs/man/ALLEGRO_SAMPLE_ID.3 +allegro/docs/man/ALLEGRO_SAMPLE_INSTANCE.3 +allegro/docs/man/ALLEGRO_SEEK.3 +allegro/docs/man/ALLEGRO_SHADER.3 +allegro/docs/man/ALLEGRO_SHADER_PLATFORM.3 +allegro/docs/man/ALLEGRO_SHADER_TYPE.3 +allegro/docs/man/ALLEGRO_STATE.3 +allegro/docs/man/ALLEGRO_STATE_FLAGS.3 +allegro/docs/man/ALLEGRO_SYSTEM_ID.3 +allegro/docs/man/ALLEGRO_TEXTLOG.3 +allegro/docs/man/ALLEGRO_THREAD.3 +allegro/docs/man/ALLEGRO_TIMEOUT.3 +allegro/docs/man/ALLEGRO_TIMER.3 +allegro/docs/man/ALLEGRO_TOUCH_INPUT.3 +allegro/docs/man/ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT.3 +allegro/docs/man/ALLEGRO_TOUCH_INPUT_STATE.3 +allegro/docs/man/ALLEGRO_TOUCH_STATE.3 +allegro/docs/man/ALLEGRO_TRANSFORM.3 +allegro/docs/man/ALLEGRO_USECS_TO_SECS.3 +allegro/docs/man/ALLEGRO_USER_EVENT.3 +allegro/docs/man/ALLEGRO_USTR.3 +allegro/docs/man/ALLEGRO_USTR_INFO.3 +allegro/docs/man/ALLEGRO_VERTEX.3 +allegro/docs/man/ALLEGRO_VERTEX_BUFFER.3 +allegro/docs/man/ALLEGRO_VERTEX_CACHE_SIZE.3 +allegro/docs/man/ALLEGRO_VERTEX_DECL.3 +allegro/docs/man/ALLEGRO_VERTEX_ELEMENT.3 +allegro/docs/man/ALLEGRO_VIDEO_EVENT_TYPE.3 +allegro/docs/man/ALLEGRO_VIDEO_POSITION_TYPE.3 +allegro/docs/man/ALLEGRO_VOICE.3 +allegro/docs/man/ALLEGRO_WRITE_MASK_FLAGS.3 +allegro/docs/man/al_acknowledge_drawing_halt.3 +allegro/docs/man/al_acknowledge_drawing_resume.3 +allegro/docs/man/al_acknowledge_resize.3 +allegro/docs/man/al_add_config_comment.3 +allegro/docs/man/al_add_config_section.3 +allegro/docs/man/al_add_new_bitmap_flag.3 +allegro/docs/man/al_add_timer_count.3 +allegro/docs/man/al_android_get_activity.3 +allegro/docs/man/al_android_get_jni_env.3 +allegro/docs/man/al_android_get_os_version.3 +allegro/docs/man/al_android_set_apk_file_interface.3 +allegro/docs/man/al_android_set_apk_fs_interface.3 +allegro/docs/man/al_append_menu_item.3 +allegro/docs/man/al_append_native_text_log.3 +allegro/docs/man/al_append_path_component.3 +allegro/docs/man/al_apply_window_constraints.3 +allegro/docs/man/al_attach_audio_stream_to_mixer.3 +allegro/docs/man/al_attach_audio_stream_to_voice.3 +allegro/docs/man/al_attach_mixer_to_mixer.3 +allegro/docs/man/al_attach_mixer_to_voice.3 +allegro/docs/man/al_attach_sample_instance_to_mixer.3 +allegro/docs/man/al_attach_sample_instance_to_voice.3 +allegro/docs/man/al_attach_shader_source.3 +allegro/docs/man/al_attach_shader_source_file.3 +allegro/docs/man/al_backup_dirty_bitmap.3 +allegro/docs/man/al_backup_dirty_bitmaps.3 +allegro/docs/man/al_broadcast_cond.3 +allegro/docs/man/al_build_camera_transform.3 +allegro/docs/man/al_build_menu.3 +allegro/docs/man/al_build_shader.3 +allegro/docs/man/al_build_transform.3 +allegro/docs/man/al_calculate_arc.3 +allegro/docs/man/al_calculate_ribbon.3 +allegro/docs/man/al_calculate_spline.3 +allegro/docs/man/al_calloc.3 +allegro/docs/man/al_calloc_with_context.3 +allegro/docs/man/al_change_directory.3 +allegro/docs/man/al_check_inverse.3 +allegro/docs/man/al_clear_depth_buffer.3 +allegro/docs/man/al_clear_keyboard_state.3 +allegro/docs/man/al_clear_to_color.3 +allegro/docs/man/al_clipboard_has_text.3 +allegro/docs/man/al_clone_bitmap.3 +allegro/docs/man/al_clone_menu.3 +allegro/docs/man/al_clone_menu_for_popup.3 +allegro/docs/man/al_clone_path.3 +allegro/docs/man/al_close_directory.3 +allegro/docs/man/al_close_native_text_log.3 +allegro/docs/man/al_close_video.3 +allegro/docs/man/al_color_cmyk.3 +allegro/docs/man/al_color_cmyk_to_rgb.3 +allegro/docs/man/al_color_distance_ciede2000.3 +allegro/docs/man/al_color_hsl.3 +allegro/docs/man/al_color_hsl_to_rgb.3 +allegro/docs/man/al_color_hsv.3 +allegro/docs/man/al_color_hsv_to_rgb.3 +allegro/docs/man/al_color_html.3 +allegro/docs/man/al_color_html_to_rgb.3 +allegro/docs/man/al_color_lab.3 +allegro/docs/man/al_color_lab_to_rgb.3 +allegro/docs/man/al_color_lch.3 +allegro/docs/man/al_color_lch_to_rgb.3 +allegro/docs/man/al_color_name.3 +allegro/docs/man/al_color_name_to_rgb.3 +allegro/docs/man/al_color_rgb_to_cmyk.3 +allegro/docs/man/al_color_rgb_to_hsl.3 +allegro/docs/man/al_color_rgb_to_hsv.3 +allegro/docs/man/al_color_rgb_to_html.3 +allegro/docs/man/al_color_rgb_to_lab.3 +allegro/docs/man/al_color_rgb_to_lch.3 +allegro/docs/man/al_color_rgb_to_name.3 +allegro/docs/man/al_color_rgb_to_xyy.3 +allegro/docs/man/al_color_rgb_to_xyz.3 +allegro/docs/man/al_color_rgb_to_yuv.3 +allegro/docs/man/al_color_xyy.3 +allegro/docs/man/al_color_xyy_to_rgb.3 +allegro/docs/man/al_color_xyz.3 +allegro/docs/man/al_color_xyz_to_rgb.3 +allegro/docs/man/al_color_yuv.3 +allegro/docs/man/al_color_yuv_to_rgb.3 +allegro/docs/man/al_compose_transform.3 +allegro/docs/man/al_convert_bitmap.3 +allegro/docs/man/al_convert_mask_to_alpha.3 +allegro/docs/man/al_convert_memory_bitmaps.3 +allegro/docs/man/al_copy_transform.3 +allegro/docs/man/al_create_audio_recorder.3 +allegro/docs/man/al_create_audio_stream.3 +allegro/docs/man/al_create_bitmap.3 +allegro/docs/man/al_create_builtin_font.3 +allegro/docs/man/al_create_cond.3 +allegro/docs/man/al_create_config.3 +allegro/docs/man/al_create_display.3 +allegro/docs/man/al_create_event_queue.3 +allegro/docs/man/al_create_file_handle.3 +allegro/docs/man/al_create_fs_entry.3 +allegro/docs/man/al_create_index_buffer.3 +allegro/docs/man/al_create_menu.3 +allegro/docs/man/al_create_mixer.3 +allegro/docs/man/al_create_mouse_cursor.3 +allegro/docs/man/al_create_mutex.3 +allegro/docs/man/al_create_mutex_recursive.3 +allegro/docs/man/al_create_native_file_dialog.3 +allegro/docs/man/al_create_path.3 +allegro/docs/man/al_create_path_for_directory.3 +allegro/docs/man/al_create_popup_menu.3 +allegro/docs/man/al_create_sample.3 +allegro/docs/man/al_create_sample_instance.3 +allegro/docs/man/al_create_shader.3 +allegro/docs/man/al_create_sub_bitmap.3 +allegro/docs/man/al_create_thread.3 +allegro/docs/man/al_create_thread_with_stacksize.3 +allegro/docs/man/al_create_timer.3 +allegro/docs/man/al_create_vertex_buffer.3 +allegro/docs/man/al_create_vertex_decl.3 +allegro/docs/man/al_create_voice.3 +allegro/docs/man/al_cstr.3 +allegro/docs/man/al_cstr_dup.3 +allegro/docs/man/al_destroy_audio_recorder.3 +allegro/docs/man/al_destroy_audio_stream.3 +allegro/docs/man/al_destroy_bitmap.3 +allegro/docs/man/al_destroy_cond.3 +allegro/docs/man/al_destroy_config.3 +allegro/docs/man/al_destroy_display.3 +allegro/docs/man/al_destroy_event_queue.3 +allegro/docs/man/al_destroy_font.3 +allegro/docs/man/al_destroy_fs_entry.3 +allegro/docs/man/al_destroy_index_buffer.3 +allegro/docs/man/al_destroy_menu.3 +allegro/docs/man/al_destroy_mixer.3 +allegro/docs/man/al_destroy_mouse_cursor.3 +allegro/docs/man/al_destroy_mutex.3 +allegro/docs/man/al_destroy_native_file_dialog.3 +allegro/docs/man/al_destroy_path.3 +allegro/docs/man/al_destroy_sample.3 +allegro/docs/man/al_destroy_sample_instance.3 +allegro/docs/man/al_destroy_shader.3 +allegro/docs/man/al_destroy_thread.3 +allegro/docs/man/al_destroy_timer.3 +allegro/docs/man/al_destroy_user_event_source.3 +allegro/docs/man/al_destroy_vertex_buffer.3 +allegro/docs/man/al_destroy_vertex_decl.3 +allegro/docs/man/al_destroy_voice.3 +allegro/docs/man/al_detach_audio_stream.3 +allegro/docs/man/al_detach_mixer.3 +allegro/docs/man/al_detach_sample_instance.3 +allegro/docs/man/al_detach_voice.3 +allegro/docs/man/al_disable_menu_event_source.3 +allegro/docs/man/al_do_multiline_text.3 +allegro/docs/man/al_do_multiline_ustr.3 +allegro/docs/man/al_drain_audio_stream.3 +allegro/docs/man/al_draw_arc.3 +allegro/docs/man/al_draw_bitmap.3 +allegro/docs/man/al_draw_bitmap_region.3 +allegro/docs/man/al_draw_circle.3 +allegro/docs/man/al_draw_ellipse.3 +allegro/docs/man/al_draw_elliptical_arc.3 +allegro/docs/man/al_draw_filled_circle.3 +allegro/docs/man/al_draw_filled_ellipse.3 +allegro/docs/man/al_draw_filled_pieslice.3 +allegro/docs/man/al_draw_filled_polygon.3 +allegro/docs/man/al_draw_filled_polygon_with_holes.3 +allegro/docs/man/al_draw_filled_rectangle.3 +allegro/docs/man/al_draw_filled_rounded_rectangle.3 +allegro/docs/man/al_draw_filled_triangle.3 +allegro/docs/man/al_draw_glyph.3 +allegro/docs/man/al_draw_indexed_buffer.3 +allegro/docs/man/al_draw_indexed_prim.3 +allegro/docs/man/al_draw_justified_text.3 +allegro/docs/man/al_draw_justified_textf.3 +allegro/docs/man/al_draw_justified_ustr.3 +allegro/docs/man/al_draw_line.3 +allegro/docs/man/al_draw_multiline_text.3 +allegro/docs/man/al_draw_multiline_textf.3 +allegro/docs/man/al_draw_multiline_ustr.3 +allegro/docs/man/al_draw_pieslice.3 +allegro/docs/man/al_draw_pixel.3 +allegro/docs/man/al_draw_polygon.3 +allegro/docs/man/al_draw_polyline.3 +allegro/docs/man/al_draw_prim.3 +allegro/docs/man/al_draw_rectangle.3 +allegro/docs/man/al_draw_ribbon.3 +allegro/docs/man/al_draw_rotated_bitmap.3 +allegro/docs/man/al_draw_rounded_rectangle.3 +allegro/docs/man/al_draw_scaled_bitmap.3 +allegro/docs/man/al_draw_scaled_rotated_bitmap.3 +allegro/docs/man/al_draw_soft_line.3 +allegro/docs/man/al_draw_soft_triangle.3 +allegro/docs/man/al_draw_spline.3 +allegro/docs/man/al_draw_text.3 +allegro/docs/man/al_draw_textf.3 +allegro/docs/man/al_draw_tinted_bitmap.3 +allegro/docs/man/al_draw_tinted_bitmap_region.3 +allegro/docs/man/al_draw_tinted_rotated_bitmap.3 +allegro/docs/man/al_draw_tinted_scaled_bitmap.3 +allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap.3 +allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap_region.3 +allegro/docs/man/al_draw_triangle.3 +allegro/docs/man/al_draw_ustr.3 +allegro/docs/man/al_draw_vertex_buffer.3 +allegro/docs/man/al_drop_next_event.3 +allegro/docs/man/al_drop_path_tail.3 +allegro/docs/man/al_emit_user_event.3 +allegro/docs/man/al_enable_menu_event_source.3 +allegro/docs/man/al_fclearerr.3 +allegro/docs/man/al_fclose.3 +allegro/docs/man/al_feof.3 +allegro/docs/man/al_ferrmsg.3 +allegro/docs/man/al_ferror.3 +allegro/docs/man/al_fflush.3 +allegro/docs/man/al_fget_ustr.3 +allegro/docs/man/al_fgetc.3 +allegro/docs/man/al_fgets.3 +allegro/docs/man/al_filename_exists.3 +allegro/docs/man/al_fill_silence.3 +allegro/docs/man/al_find_menu.3 +allegro/docs/man/al_find_menu_item.3 +allegro/docs/man/al_fixacos.3 +allegro/docs/man/al_fixadd.3 +allegro/docs/man/al_fixasin.3 +allegro/docs/man/al_fixatan.3 +allegro/docs/man/al_fixatan2.3 +allegro/docs/man/al_fixceil.3 +allegro/docs/man/al_fixcos.3 +allegro/docs/man/al_fixdiv.3 +allegro/docs/man/al_fixed.3 +allegro/docs/man/al_fixfloor.3 +allegro/docs/man/al_fixhypot.3 +allegro/docs/man/al_fixmul.3 +allegro/docs/man/al_fixsin.3 +allegro/docs/man/al_fixsqrt.3 +allegro/docs/man/al_fixsub.3 +allegro/docs/man/al_fixtan.3 +allegro/docs/man/al_fixtof.3 +allegro/docs/man/al_fixtoi.3 +allegro/docs/man/al_fixtorad_r.3 +allegro/docs/man/al_flip_display.3 +allegro/docs/man/al_flush_event_queue.3 +allegro/docs/man/al_fopen.3 +allegro/docs/man/al_fopen_fd.3 +allegro/docs/man/al_fopen_interface.3 +allegro/docs/man/al_fopen_slice.3 +allegro/docs/man/al_for_each_fs_entry.3 +allegro/docs/man/al_fprintf.3 +allegro/docs/man/al_fputc.3 +allegro/docs/man/al_fputs.3 +allegro/docs/man/al_fread.3 +allegro/docs/man/al_fread16be.3 +allegro/docs/man/al_fread16le.3 +allegro/docs/man/al_fread32be.3 +allegro/docs/man/al_fread32le.3 +allegro/docs/man/al_free.3 +allegro/docs/man/al_free_with_context.3 +allegro/docs/man/al_fs_entry_exists.3 +allegro/docs/man/al_fseek.3 +allegro/docs/man/al_fsize.3 +allegro/docs/man/al_ftell.3 +allegro/docs/man/al_ftofix.3 +allegro/docs/man/al_fungetc.3 +allegro/docs/man/al_fwrite.3 +allegro/docs/man/al_fwrite16be.3 +allegro/docs/man/al_fwrite16le.3 +allegro/docs/man/al_fwrite32be.3 +allegro/docs/man/al_fwrite32le.3 +allegro/docs/man/al_get_allegro_acodec_version.3 +allegro/docs/man/al_get_allegro_audio_version.3 +allegro/docs/man/al_get_allegro_color_version.3 +allegro/docs/man/al_get_allegro_font_version.3 +allegro/docs/man/al_get_allegro_image_version.3 +allegro/docs/man/al_get_allegro_memfile_version.3 +allegro/docs/man/al_get_allegro_native_dialog_version.3 +allegro/docs/man/al_get_allegro_physfs_version.3 +allegro/docs/man/al_get_allegro_primitives_version.3 +allegro/docs/man/al_get_allegro_ttf_version.3 +allegro/docs/man/al_get_allegro_version.3 +allegro/docs/man/al_get_allegro_video_version.3 +allegro/docs/man/al_get_app_name.3 +allegro/docs/man/al_get_audio_depth_size.3 +allegro/docs/man/al_get_audio_recorder_event.3 +allegro/docs/man/al_get_audio_recorder_event_source.3 +allegro/docs/man/al_get_audio_stream_attached.3 +allegro/docs/man/al_get_audio_stream_channels.3 +allegro/docs/man/al_get_audio_stream_depth.3 +allegro/docs/man/al_get_audio_stream_event_source.3 +allegro/docs/man/al_get_audio_stream_fragment.3 +allegro/docs/man/al_get_audio_stream_fragments.3 +allegro/docs/man/al_get_audio_stream_frequency.3 +allegro/docs/man/al_get_audio_stream_gain.3 +allegro/docs/man/al_get_audio_stream_length.3 +allegro/docs/man/al_get_audio_stream_length_secs.3 +allegro/docs/man/al_get_audio_stream_pan.3 +allegro/docs/man/al_get_audio_stream_played_samples.3 +allegro/docs/man/al_get_audio_stream_playing.3 +allegro/docs/man/al_get_audio_stream_playmode.3 +allegro/docs/man/al_get_audio_stream_position_secs.3 +allegro/docs/man/al_get_audio_stream_speed.3 +allegro/docs/man/al_get_available_audio_stream_fragments.3 +allegro/docs/man/al_get_backbuffer.3 +allegro/docs/man/al_get_bitmap_blend_color.3 +allegro/docs/man/al_get_bitmap_blender.3 +allegro/docs/man/al_get_bitmap_depth.3 +allegro/docs/man/al_get_bitmap_flags.3 +allegro/docs/man/al_get_bitmap_format.3 +allegro/docs/man/al_get_bitmap_height.3 +allegro/docs/man/al_get_bitmap_samples.3 +allegro/docs/man/al_get_bitmap_width.3 +allegro/docs/man/al_get_bitmap_x.3 +allegro/docs/man/al_get_bitmap_y.3 +allegro/docs/man/al_get_blend_color.3 +allegro/docs/man/al_get_blender.3 +allegro/docs/man/al_get_channel_count.3 +allegro/docs/man/al_get_clipboard_text.3 +allegro/docs/man/al_get_clipping_rectangle.3 +allegro/docs/man/al_get_config_value.3 +allegro/docs/man/al_get_cpu_count.3 +allegro/docs/man/al_get_current_directory.3 +allegro/docs/man/al_get_current_display.3 +allegro/docs/man/al_get_current_inverse_transform.3 +allegro/docs/man/al_get_current_projection_transform.3 +allegro/docs/man/al_get_current_transform.3 +allegro/docs/man/al_get_d3d_device.3 +allegro/docs/man/al_get_d3d_system_texture.3 +allegro/docs/man/al_get_d3d_texture_position.3 +allegro/docs/man/al_get_d3d_texture_size.3 +allegro/docs/man/al_get_d3d_video_texture.3 +allegro/docs/man/al_get_default_menu_event_source.3 +allegro/docs/man/al_get_default_mixer.3 +allegro/docs/man/al_get_default_shader_source.3 +allegro/docs/man/al_get_default_voice.3 +allegro/docs/man/al_get_display_event_source.3 +allegro/docs/man/al_get_display_flags.3 +allegro/docs/man/al_get_display_format.3 +allegro/docs/man/al_get_display_height.3 +allegro/docs/man/al_get_display_menu.3 +allegro/docs/man/al_get_display_mode.3 +allegro/docs/man/al_get_display_option.3 +allegro/docs/man/al_get_display_orientation.3 +allegro/docs/man/al_get_display_refresh_rate.3 +allegro/docs/man/al_get_display_width.3 +allegro/docs/man/al_get_errno.3 +allegro/docs/man/al_get_event_source_data.3 +allegro/docs/man/al_get_fallback_font.3 +allegro/docs/man/al_get_file_userdata.3 +allegro/docs/man/al_get_first_config_entry.3 +allegro/docs/man/al_get_first_config_section.3 +allegro/docs/man/al_get_font_ascent.3 +allegro/docs/man/al_get_font_descent.3 +allegro/docs/man/al_get_font_line_height.3 +allegro/docs/man/al_get_font_ranges.3 +allegro/docs/man/al_get_fs_entry_atime.3 +allegro/docs/man/al_get_fs_entry_ctime.3 +allegro/docs/man/al_get_fs_entry_mode.3 +allegro/docs/man/al_get_fs_entry_mtime.3 +allegro/docs/man/al_get_fs_entry_name.3 +allegro/docs/man/al_get_fs_entry_size.3 +allegro/docs/man/al_get_fs_interface.3 +allegro/docs/man/al_get_glyph.3 +allegro/docs/man/al_get_glyph_advance.3 +allegro/docs/man/al_get_glyph_dimensions.3 +allegro/docs/man/al_get_glyph_width.3 +allegro/docs/man/al_get_haptic_autocenter.3 +allegro/docs/man/al_get_haptic_capabilities.3 +allegro/docs/man/al_get_haptic_effect_duration.3 +allegro/docs/man/al_get_haptic_from_display.3 +allegro/docs/man/al_get_haptic_from_joystick.3 +allegro/docs/man/al_get_haptic_from_keyboard.3 +allegro/docs/man/al_get_haptic_from_mouse.3 +allegro/docs/man/al_get_haptic_from_touch_input.3 +allegro/docs/man/al_get_haptic_gain.3 +allegro/docs/man/al_get_index_buffer_size.3 +allegro/docs/man/al_get_joystick.3 +allegro/docs/man/al_get_joystick_active.3 +allegro/docs/man/al_get_joystick_axis_name.3 +allegro/docs/man/al_get_joystick_button_name.3 +allegro/docs/man/al_get_joystick_event_source.3 +allegro/docs/man/al_get_joystick_name.3 +allegro/docs/man/al_get_joystick_num_axes.3 +allegro/docs/man/al_get_joystick_num_buttons.3 +allegro/docs/man/al_get_joystick_num_sticks.3 +allegro/docs/man/al_get_joystick_state.3 +allegro/docs/man/al_get_joystick_stick_flags.3 +allegro/docs/man/al_get_joystick_stick_name.3 +allegro/docs/man/al_get_keyboard_event_source.3 +allegro/docs/man/al_get_keyboard_state.3 +allegro/docs/man/al_get_max_haptic_effects.3 +allegro/docs/man/al_get_menu_item_caption.3 +allegro/docs/man/al_get_menu_item_flags.3 +allegro/docs/man/al_get_menu_item_icon.3 +allegro/docs/man/al_get_mixer_attached.3 +allegro/docs/man/al_get_mixer_channels.3 +allegro/docs/man/al_get_mixer_depth.3 +allegro/docs/man/al_get_mixer_frequency.3 +allegro/docs/man/al_get_mixer_gain.3 +allegro/docs/man/al_get_mixer_playing.3 +allegro/docs/man/al_get_mixer_quality.3 +allegro/docs/man/al_get_monitor_dpi.3 +allegro/docs/man/al_get_monitor_info.3 +allegro/docs/man/al_get_monitor_refresh_rate.3 +allegro/docs/man/al_get_mouse_cursor_position.3 +allegro/docs/man/al_get_mouse_emulation_mode.3 +allegro/docs/man/al_get_mouse_event_source.3 +allegro/docs/man/al_get_mouse_num_axes.3 +allegro/docs/man/al_get_mouse_num_buttons.3 +allegro/docs/man/al_get_mouse_state.3 +allegro/docs/man/al_get_mouse_state_axis.3 +allegro/docs/man/al_get_mouse_wheel_precision.3 +allegro/docs/man/al_get_native_file_dialog_count.3 +allegro/docs/man/al_get_native_file_dialog_path.3 +allegro/docs/man/al_get_native_text_log_event_source.3 +allegro/docs/man/al_get_new_bitmap_depth.3 +allegro/docs/man/al_get_new_bitmap_flags.3 +allegro/docs/man/al_get_new_bitmap_format.3 +allegro/docs/man/al_get_new_bitmap_samples.3 +allegro/docs/man/al_get_new_display_adapter.3 +allegro/docs/man/al_get_new_display_flags.3 +allegro/docs/man/al_get_new_display_option.3 +allegro/docs/man/al_get_new_display_refresh_rate.3 +allegro/docs/man/al_get_new_file_interface.3 +allegro/docs/man/al_get_new_window_position.3 +allegro/docs/man/al_get_new_window_title.3 +allegro/docs/man/al_get_next_config_entry.3 +allegro/docs/man/al_get_next_config_section.3 +allegro/docs/man/al_get_next_event.3 +allegro/docs/man/al_get_num_display_modes.3 +allegro/docs/man/al_get_num_joysticks.3 +allegro/docs/man/al_get_num_video_adapters.3 +allegro/docs/man/al_get_opengl_extension_list.3 +allegro/docs/man/al_get_opengl_fbo.3 +allegro/docs/man/al_get_opengl_proc_address.3 +allegro/docs/man/al_get_opengl_program_object.3 +allegro/docs/man/al_get_opengl_texture.3 +allegro/docs/man/al_get_opengl_texture_position.3 +allegro/docs/man/al_get_opengl_texture_size.3 +allegro/docs/man/al_get_opengl_variant.3 +allegro/docs/man/al_get_opengl_version.3 +allegro/docs/man/al_get_org_name.3 +allegro/docs/man/al_get_parent_bitmap.3 +allegro/docs/man/al_get_path_basename.3 +allegro/docs/man/al_get_path_component.3 +allegro/docs/man/al_get_path_drive.3 +allegro/docs/man/al_get_path_extension.3 +allegro/docs/man/al_get_path_filename.3 +allegro/docs/man/al_get_path_num_components.3 +allegro/docs/man/al_get_path_tail.3 +allegro/docs/man/al_get_pixel.3 +allegro/docs/man/al_get_pixel_block_height.3 +allegro/docs/man/al_get_pixel_block_size.3 +allegro/docs/man/al_get_pixel_block_width.3 +allegro/docs/man/al_get_pixel_format_bits.3 +allegro/docs/man/al_get_pixel_size.3 +allegro/docs/man/al_get_ram_size.3 +allegro/docs/man/al_get_sample.3 +allegro/docs/man/al_get_sample_channels.3 +allegro/docs/man/al_get_sample_data.3 +allegro/docs/man/al_get_sample_depth.3 +allegro/docs/man/al_get_sample_frequency.3 +allegro/docs/man/al_get_sample_instance_attached.3 +allegro/docs/man/al_get_sample_instance_channels.3 +allegro/docs/man/al_get_sample_instance_depth.3 +allegro/docs/man/al_get_sample_instance_frequency.3 +allegro/docs/man/al_get_sample_instance_gain.3 +allegro/docs/man/al_get_sample_instance_length.3 +allegro/docs/man/al_get_sample_instance_pan.3 +allegro/docs/man/al_get_sample_instance_playing.3 +allegro/docs/man/al_get_sample_instance_playmode.3 +allegro/docs/man/al_get_sample_instance_position.3 +allegro/docs/man/al_get_sample_instance_speed.3 +allegro/docs/man/al_get_sample_instance_time.3 +allegro/docs/man/al_get_sample_length.3 +allegro/docs/man/al_get_separate_bitmap_blender.3 +allegro/docs/man/al_get_separate_blender.3 +allegro/docs/man/al_get_shader_log.3 +allegro/docs/man/al_get_shader_platform.3 +allegro/docs/man/al_get_standard_path.3 +allegro/docs/man/al_get_system_config.3 +allegro/docs/man/al_get_system_id.3 +allegro/docs/man/al_get_target_bitmap.3 +allegro/docs/man/al_get_text_dimensions.3 +allegro/docs/man/al_get_text_width.3 +allegro/docs/man/al_get_thread_should_stop.3 +allegro/docs/man/al_get_time.3 +allegro/docs/man/al_get_timer_count.3 +allegro/docs/man/al_get_timer_event_source.3 +allegro/docs/man/al_get_timer_speed.3 +allegro/docs/man/al_get_timer_started.3 +allegro/docs/man/al_get_touch_input_event_source.3 +allegro/docs/man/al_get_touch_input_mouse_emulation_event_source.3 +allegro/docs/man/al_get_touch_input_state.3 +allegro/docs/man/al_get_ustr_dimensions.3 +allegro/docs/man/al_get_ustr_width.3 +allegro/docs/man/al_get_vertex_buffer_size.3 +allegro/docs/man/al_get_video_audio_rate.3 +allegro/docs/man/al_get_video_event_source.3 +allegro/docs/man/al_get_video_fps.3 +allegro/docs/man/al_get_video_frame.3 +allegro/docs/man/al_get_video_position.3 +allegro/docs/man/al_get_video_scaled_height.3 +allegro/docs/man/al_get_video_scaled_width.3 +allegro/docs/man/al_get_voice_channels.3 +allegro/docs/man/al_get_voice_depth.3 +allegro/docs/man/al_get_voice_frequency.3 +allegro/docs/man/al_get_voice_playing.3 +allegro/docs/man/al_get_voice_position.3 +allegro/docs/man/al_get_win_window_handle.3 +allegro/docs/man/al_get_window_constraints.3 +allegro/docs/man/al_get_window_position.3 +allegro/docs/man/al_get_x_window_id.3 +allegro/docs/man/al_grab_font_from_bitmap.3 +allegro/docs/man/al_grab_mouse.3 +allegro/docs/man/al_have_d3d_non_pow2_texture_support.3 +allegro/docs/man/al_have_d3d_non_square_texture_support.3 +allegro/docs/man/al_have_opengl_extension.3 +allegro/docs/man/al_hide_mouse_cursor.3 +allegro/docs/man/al_hold_bitmap_drawing.3 +allegro/docs/man/al_horizontal_shear_transform.3 +allegro/docs/man/al_identify_bitmap.3 +allegro/docs/man/al_identify_bitmap_f.3 +allegro/docs/man/al_identity_transform.3 +allegro/docs/man/al_inhibit_screensaver.3 +allegro/docs/man/al_init.3 +allegro/docs/man/al_init_acodec_addon.3 +allegro/docs/man/al_init_font_addon.3 +allegro/docs/man/al_init_image_addon.3 +allegro/docs/man/al_init_native_dialog_addon.3 +allegro/docs/man/al_init_primitives_addon.3 +allegro/docs/man/al_init_timeout.3 +allegro/docs/man/al_init_ttf_addon.3 +allegro/docs/man/al_init_user_event_source.3 +allegro/docs/man/al_init_video_addon.3 +allegro/docs/man/al_insert_menu_item.3 +allegro/docs/man/al_insert_path_component.3 +allegro/docs/man/al_install_audio.3 +allegro/docs/man/al_install_haptic.3 +allegro/docs/man/al_install_joystick.3 +allegro/docs/man/al_install_keyboard.3 +allegro/docs/man/al_install_mouse.3 +allegro/docs/man/al_install_system.3 +allegro/docs/man/al_install_touch_input.3 +allegro/docs/man/al_invert_transform.3 +allegro/docs/man/al_iphone_get_view.3 +allegro/docs/man/al_iphone_get_window.3 +allegro/docs/man/al_iphone_set_statusbar_orientation.3 +allegro/docs/man/al_is_acodec_addon_initialized.3 +allegro/docs/man/al_is_audio_installed.3 +allegro/docs/man/al_is_audio_recorder_recording.3 +allegro/docs/man/al_is_bitmap_drawing_held.3 +allegro/docs/man/al_is_bitmap_locked.3 +allegro/docs/man/al_is_color_valid.3 +allegro/docs/man/al_is_compatible_bitmap.3 +allegro/docs/man/al_is_d3d_device_lost.3 +allegro/docs/man/al_is_display_haptic.3 +allegro/docs/man/al_is_event_queue_empty.3 +allegro/docs/man/al_is_event_queue_paused.3 +allegro/docs/man/al_is_event_source_registered.3 +allegro/docs/man/al_is_font_addon_initialized.3 +allegro/docs/man/al_is_haptic_active.3 +allegro/docs/man/al_is_haptic_capable.3 +allegro/docs/man/al_is_haptic_effect_ok.3 +allegro/docs/man/al_is_haptic_effect_playing.3 +allegro/docs/man/al_is_haptic_installed.3 +allegro/docs/man/al_is_image_addon_initialized.3 +allegro/docs/man/al_is_joystick_haptic.3 +allegro/docs/man/al_is_joystick_installed.3 +allegro/docs/man/al_is_keyboard_haptic.3 +allegro/docs/man/al_is_keyboard_installed.3 +allegro/docs/man/al_is_mouse_haptic.3 +allegro/docs/man/al_is_mouse_installed.3 +allegro/docs/man/al_is_native_dialog_addon_initialized.3 +allegro/docs/man/al_is_primitives_addon_initialized.3 +allegro/docs/man/al_is_sub_bitmap.3 +allegro/docs/man/al_is_system_installed.3 +allegro/docs/man/al_is_touch_input_haptic.3 +allegro/docs/man/al_is_touch_input_installed.3 +allegro/docs/man/al_is_ttf_addon_initialized.3 +allegro/docs/man/al_is_video_addon_initialized.3 +allegro/docs/man/al_is_video_playing.3 +allegro/docs/man/al_itofix.3 +allegro/docs/man/al_join_paths.3 +allegro/docs/man/al_join_thread.3 +allegro/docs/man/al_key_down.3 +allegro/docs/man/al_keycode_to_name.3 +allegro/docs/man/al_load_audio_stream.3 +allegro/docs/man/al_load_audio_stream_f.3 +allegro/docs/man/al_load_bitmap.3 +allegro/docs/man/al_load_bitmap_f.3 +allegro/docs/man/al_load_bitmap_flags.3 +allegro/docs/man/al_load_bitmap_flags_f.3 +allegro/docs/man/al_load_bitmap_font.3 +allegro/docs/man/al_load_bitmap_font_flags.3 +allegro/docs/man/al_load_config_file.3 +allegro/docs/man/al_load_config_file_f.3 +allegro/docs/man/al_load_font.3 +allegro/docs/man/al_load_sample.3 +allegro/docs/man/al_load_sample_f.3 +allegro/docs/man/al_load_ttf_font.3 +allegro/docs/man/al_load_ttf_font_f.3 +allegro/docs/man/al_load_ttf_font_stretch.3 +allegro/docs/man/al_load_ttf_font_stretch_f.3 +allegro/docs/man/al_lock_bitmap.3 +allegro/docs/man/al_lock_bitmap_blocked.3 +allegro/docs/man/al_lock_bitmap_region.3 +allegro/docs/man/al_lock_bitmap_region_blocked.3 +allegro/docs/man/al_lock_index_buffer.3 +allegro/docs/man/al_lock_mutex.3 +allegro/docs/man/al_lock_sample_id.3 +allegro/docs/man/al_lock_vertex_buffer.3 +allegro/docs/man/al_make_directory.3 +allegro/docs/man/al_make_path_canonical.3 +allegro/docs/man/al_make_temp_file.3 +allegro/docs/man/al_malloc.3 +allegro/docs/man/al_malloc_with_context.3 +allegro/docs/man/al_map_rgb.3 +allegro/docs/man/al_map_rgb_f.3 +allegro/docs/man/al_map_rgba.3 +allegro/docs/man/al_map_rgba_f.3 +allegro/docs/man/al_merge_config.3 +allegro/docs/man/al_merge_config_into.3 +allegro/docs/man/al_mouse_button_down.3 +allegro/docs/man/al_open_directory.3 +allegro/docs/man/al_open_fs_entry.3 +allegro/docs/man/al_open_memfile.3 +allegro/docs/man/al_open_native_text_log.3 +allegro/docs/man/al_open_video.3 +allegro/docs/man/al_orthographic_transform.3 +allegro/docs/man/al_osx_get_window.3 +allegro/docs/man/al_path_cstr.3 +allegro/docs/man/al_path_ustr.3 +allegro/docs/man/al_pause_event_queue.3 +allegro/docs/man/al_peek_next_event.3 +allegro/docs/man/al_perspective_transform.3 +allegro/docs/man/al_play_haptic_effect.3 +allegro/docs/man/al_play_sample.3 +allegro/docs/man/al_play_sample_instance.3 +allegro/docs/man/al_popup_menu.3 +allegro/docs/man/al_premul_rgba.3 +allegro/docs/man/al_premul_rgba_f.3 +allegro/docs/man/al_put_blended_pixel.3 +allegro/docs/man/al_put_pixel.3 +allegro/docs/man/al_radtofix_r.3 +allegro/docs/man/al_read_directory.3 +allegro/docs/man/al_realloc.3 +allegro/docs/man/al_realloc_with_context.3 +allegro/docs/man/al_rebase_path.3 +allegro/docs/man/al_reconfigure_joysticks.3 +allegro/docs/man/al_ref_buffer.3 +allegro/docs/man/al_ref_cstr.3 +allegro/docs/man/al_ref_ustr.3 +allegro/docs/man/al_register_assert_handler.3 +allegro/docs/man/al_register_audio_stream_loader.3 +allegro/docs/man/al_register_audio_stream_loader_f.3 +allegro/docs/man/al_register_bitmap_identifier.3 +allegro/docs/man/al_register_bitmap_loader.3 +allegro/docs/man/al_register_bitmap_loader_f.3 +allegro/docs/man/al_register_bitmap_saver.3 +allegro/docs/man/al_register_bitmap_saver_f.3 +allegro/docs/man/al_register_event_source.3 +allegro/docs/man/al_register_font_loader.3 +allegro/docs/man/al_register_sample_loader.3 +allegro/docs/man/al_register_sample_loader_f.3 +allegro/docs/man/al_register_sample_saver.3 +allegro/docs/man/al_register_sample_saver_f.3 +allegro/docs/man/al_register_trace_handler.3 +allegro/docs/man/al_release_haptic.3 +allegro/docs/man/al_release_haptic_effect.3 +allegro/docs/man/al_release_joystick.3 +allegro/docs/man/al_remove_config_key.3 +allegro/docs/man/al_remove_config_section.3 +allegro/docs/man/al_remove_display_menu.3 +allegro/docs/man/al_remove_filename.3 +allegro/docs/man/al_remove_fs_entry.3 +allegro/docs/man/al_remove_menu_item.3 +allegro/docs/man/al_remove_opengl_fbo.3 +allegro/docs/man/al_remove_path_component.3 +allegro/docs/man/al_reparent_bitmap.3 +allegro/docs/man/al_replace_path_component.3 +allegro/docs/man/al_reserve_samples.3 +allegro/docs/man/al_reset_bitmap_blender.3 +allegro/docs/man/al_reset_clipping_rectangle.3 +allegro/docs/man/al_reset_new_display_options.3 +allegro/docs/man/al_resize_display.3 +allegro/docs/man/al_rest.3 +allegro/docs/man/al_restore_default_mixer.3 +allegro/docs/man/al_restore_state.3 +allegro/docs/man/al_resume_timer.3 +allegro/docs/man/al_rewind_audio_stream.3 +allegro/docs/man/al_rotate_transform.3 +allegro/docs/man/al_rotate_transform_3d.3 +allegro/docs/man/al_rumble_haptic.3 +allegro/docs/man/al_run_detached_thread.3 +allegro/docs/man/al_run_main.3 +allegro/docs/man/al_save_bitmap.3 +allegro/docs/man/al_save_bitmap_f.3 +allegro/docs/man/al_save_config_file.3 +allegro/docs/man/al_save_config_file_f.3 +allegro/docs/man/al_save_sample.3 +allegro/docs/man/al_save_sample_f.3 +allegro/docs/man/al_scale_transform.3 +allegro/docs/man/al_scale_transform_3d.3 +allegro/docs/man/al_seek_audio_stream_secs.3 +allegro/docs/man/al_seek_video.3 +allegro/docs/man/al_set_app_name.3 +allegro/docs/man/al_set_audio_stream_channel_matrix.3 +allegro/docs/man/al_set_audio_stream_fragment.3 +allegro/docs/man/al_set_audio_stream_gain.3 +allegro/docs/man/al_set_audio_stream_loop_secs.3 +allegro/docs/man/al_set_audio_stream_pan.3 +allegro/docs/man/al_set_audio_stream_playing.3 +allegro/docs/man/al_set_audio_stream_playmode.3 +allegro/docs/man/al_set_audio_stream_speed.3 +allegro/docs/man/al_set_bitmap_blend_color.3 +allegro/docs/man/al_set_bitmap_blender.3 +allegro/docs/man/al_set_blend_color.3 +allegro/docs/man/al_set_blender.3 +allegro/docs/man/al_set_clipboard_text.3 +allegro/docs/man/al_set_clipping_rectangle.3 +allegro/docs/man/al_set_config_value.3 +allegro/docs/man/al_set_current_opengl_context.3 +allegro/docs/man/al_set_d3d_device_release_callback.3 +allegro/docs/man/al_set_d3d_device_restore_callback.3 +allegro/docs/man/al_set_default_mixer.3 +allegro/docs/man/al_set_default_voice.3 +allegro/docs/man/al_set_display_flag.3 +allegro/docs/man/al_set_display_icon.3 +allegro/docs/man/al_set_display_icons.3 +allegro/docs/man/al_set_display_menu.3 +allegro/docs/man/al_set_display_option.3 +allegro/docs/man/al_set_errno.3 +allegro/docs/man/al_set_event_source_data.3 +allegro/docs/man/al_set_exe_name.3 +allegro/docs/man/al_set_fallback_font.3 +allegro/docs/man/al_set_fs_interface.3 +allegro/docs/man/al_set_haptic_autocenter.3 +allegro/docs/man/al_set_haptic_gain.3 +allegro/docs/man/al_set_keyboard_leds.3 +allegro/docs/man/al_set_memory_interface.3 +allegro/docs/man/al_set_menu_item_caption.3 +allegro/docs/man/al_set_menu_item_flags.3 +allegro/docs/man/al_set_menu_item_icon.3 +allegro/docs/man/al_set_mixer_frequency.3 +allegro/docs/man/al_set_mixer_gain.3 +allegro/docs/man/al_set_mixer_playing.3 +allegro/docs/man/al_set_mixer_postprocess_callback.3 +allegro/docs/man/al_set_mixer_quality.3 +allegro/docs/man/al_set_mouse_axis.3 +allegro/docs/man/al_set_mouse_cursor.3 +allegro/docs/man/al_set_mouse_emulation_mode.3 +allegro/docs/man/al_set_mouse_w.3 +allegro/docs/man/al_set_mouse_wheel_precision.3 +allegro/docs/man/al_set_mouse_xy.3 +allegro/docs/man/al_set_mouse_z.3 +allegro/docs/man/al_set_new_bitmap_depth.3 +allegro/docs/man/al_set_new_bitmap_flags.3 +allegro/docs/man/al_set_new_bitmap_format.3 +allegro/docs/man/al_set_new_bitmap_samples.3 +allegro/docs/man/al_set_new_display_adapter.3 +allegro/docs/man/al_set_new_display_flags.3 +allegro/docs/man/al_set_new_display_option.3 +allegro/docs/man/al_set_new_display_refresh_rate.3 +allegro/docs/man/al_set_new_file_interface.3 +allegro/docs/man/al_set_new_window_position.3 +allegro/docs/man/al_set_new_window_title.3 +allegro/docs/man/al_set_org_name.3 +allegro/docs/man/al_set_path_drive.3 +allegro/docs/man/al_set_path_extension.3 +allegro/docs/man/al_set_path_filename.3 +allegro/docs/man/al_set_physfs_file_interface.3 +allegro/docs/man/al_set_render_state.3 +allegro/docs/man/al_set_sample.3 +allegro/docs/man/al_set_sample_instance_channel_matrix.3 +allegro/docs/man/al_set_sample_instance_gain.3 +allegro/docs/man/al_set_sample_instance_length.3 +allegro/docs/man/al_set_sample_instance_pan.3 +allegro/docs/man/al_set_sample_instance_playing.3 +allegro/docs/man/al_set_sample_instance_playmode.3 +allegro/docs/man/al_set_sample_instance_position.3 +allegro/docs/man/al_set_sample_instance_speed.3 +allegro/docs/man/al_set_separate_bitmap_blender.3 +allegro/docs/man/al_set_separate_blender.3 +allegro/docs/man/al_set_shader_bool.3 +allegro/docs/man/al_set_shader_float.3 +allegro/docs/man/al_set_shader_float_vector.3 +allegro/docs/man/al_set_shader_int.3 +allegro/docs/man/al_set_shader_int_vector.3 +allegro/docs/man/al_set_shader_matrix.3 +allegro/docs/man/al_set_shader_sampler.3 +allegro/docs/man/al_set_standard_file_interface.3 +allegro/docs/man/al_set_standard_fs_interface.3 +allegro/docs/man/al_set_system_mouse_cursor.3 +allegro/docs/man/al_set_target_backbuffer.3 +allegro/docs/man/al_set_target_bitmap.3 +allegro/docs/man/al_set_thread_should_stop.3 +allegro/docs/man/al_set_timer_count.3 +allegro/docs/man/al_set_timer_speed.3 +allegro/docs/man/al_set_video_playing.3 +allegro/docs/man/al_set_voice_playing.3 +allegro/docs/man/al_set_voice_position.3 +allegro/docs/man/al_set_window_constraints.3 +allegro/docs/man/al_set_window_position.3 +allegro/docs/man/al_set_window_title.3 +allegro/docs/man/al_show_mouse_cursor.3 +allegro/docs/man/al_show_native_file_dialog.3 +allegro/docs/man/al_show_native_message_box.3 +allegro/docs/man/al_shutdown_font_addon.3 +allegro/docs/man/al_shutdown_image_addon.3 +allegro/docs/man/al_shutdown_native_dialog_addon.3 +allegro/docs/man/al_shutdown_primitives_addon.3 +allegro/docs/man/al_shutdown_ttf_addon.3 +allegro/docs/man/al_shutdown_video_addon.3 +allegro/docs/man/al_signal_cond.3 +allegro/docs/man/al_start_audio_recorder.3 +allegro/docs/man/al_start_thread.3 +allegro/docs/man/al_start_timer.3 +allegro/docs/man/al_start_video.3 +allegro/docs/man/al_start_video_with_voice.3 +allegro/docs/man/al_stop_audio_recorder.3 +allegro/docs/man/al_stop_haptic_effect.3 +allegro/docs/man/al_stop_sample.3 +allegro/docs/man/al_stop_sample_instance.3 +allegro/docs/man/al_stop_samples.3 +allegro/docs/man/al_stop_timer.3 +allegro/docs/man/al_store_state.3 +allegro/docs/man/al_toggle_menu_item_flags.3 +allegro/docs/man/al_transform_coordinates.3 +allegro/docs/man/al_transform_coordinates_3d.3 +allegro/docs/man/al_transform_coordinates_3d_projective.3 +allegro/docs/man/al_transform_coordinates_4d.3 +allegro/docs/man/al_translate_transform.3 +allegro/docs/man/al_translate_transform_3d.3 +allegro/docs/man/al_transpose_transform.3 +allegro/docs/man/al_triangulate_polygon.3 +allegro/docs/man/al_ungrab_mouse.3 +allegro/docs/man/al_uninstall_audio.3 +allegro/docs/man/al_uninstall_haptic.3 +allegro/docs/man/al_uninstall_joystick.3 +allegro/docs/man/al_uninstall_keyboard.3 +allegro/docs/man/al_uninstall_mouse.3 +allegro/docs/man/al_uninstall_system.3 +allegro/docs/man/al_uninstall_touch_input.3 +allegro/docs/man/al_unlock_bitmap.3 +allegro/docs/man/al_unlock_index_buffer.3 +allegro/docs/man/al_unlock_mutex.3 +allegro/docs/man/al_unlock_sample_id.3 +allegro/docs/man/al_unlock_vertex_buffer.3 +allegro/docs/man/al_unmap_rgb.3 +allegro/docs/man/al_unmap_rgb_f.3 +allegro/docs/man/al_unmap_rgba.3 +allegro/docs/man/al_unmap_rgba_f.3 +allegro/docs/man/al_unref_user_event.3 +allegro/docs/man/al_unregister_event_source.3 +allegro/docs/man/al_update_display_region.3 +allegro/docs/man/al_update_fs_entry.3 +allegro/docs/man/al_upload_and_play_haptic_effect.3 +allegro/docs/man/al_upload_haptic_effect.3 +allegro/docs/man/al_use_projection_transform.3 +allegro/docs/man/al_use_shader.3 +allegro/docs/man/al_use_transform.3 +allegro/docs/man/al_ustr_append.3 +allegro/docs/man/al_ustr_append_chr.3 +allegro/docs/man/al_ustr_append_cstr.3 +allegro/docs/man/al_ustr_appendf.3 +allegro/docs/man/al_ustr_assign.3 +allegro/docs/man/al_ustr_assign_cstr.3 +allegro/docs/man/al_ustr_assign_substr.3 +allegro/docs/man/al_ustr_compare.3 +allegro/docs/man/al_ustr_dup.3 +allegro/docs/man/al_ustr_dup_substr.3 +allegro/docs/man/al_ustr_empty_string.3 +allegro/docs/man/al_ustr_encode_utf16.3 +allegro/docs/man/al_ustr_equal.3 +allegro/docs/man/al_ustr_find_chr.3 +allegro/docs/man/al_ustr_find_cset.3 +allegro/docs/man/al_ustr_find_cset_cstr.3 +allegro/docs/man/al_ustr_find_cstr.3 +allegro/docs/man/al_ustr_find_replace.3 +allegro/docs/man/al_ustr_find_replace_cstr.3 +allegro/docs/man/al_ustr_find_set.3 +allegro/docs/man/al_ustr_find_set_cstr.3 +allegro/docs/man/al_ustr_find_str.3 +allegro/docs/man/al_ustr_free.3 +allegro/docs/man/al_ustr_get.3 +allegro/docs/man/al_ustr_get_next.3 +allegro/docs/man/al_ustr_has_prefix.3 +allegro/docs/man/al_ustr_has_prefix_cstr.3 +allegro/docs/man/al_ustr_has_suffix.3 +allegro/docs/man/al_ustr_has_suffix_cstr.3 +allegro/docs/man/al_ustr_insert.3 +allegro/docs/man/al_ustr_insert_chr.3 +allegro/docs/man/al_ustr_insert_cstr.3 +allegro/docs/man/al_ustr_length.3 +allegro/docs/man/al_ustr_ltrim_ws.3 +allegro/docs/man/al_ustr_ncompare.3 +allegro/docs/man/al_ustr_new.3 +allegro/docs/man/al_ustr_new_from_buffer.3 +allegro/docs/man/al_ustr_new_from_utf16.3 +allegro/docs/man/al_ustr_newf.3 +allegro/docs/man/al_ustr_next.3 +allegro/docs/man/al_ustr_offset.3 +allegro/docs/man/al_ustr_prev.3 +allegro/docs/man/al_ustr_prev_get.3 +allegro/docs/man/al_ustr_remove_chr.3 +allegro/docs/man/al_ustr_remove_range.3 +allegro/docs/man/al_ustr_replace_range.3 +allegro/docs/man/al_ustr_rfind_chr.3 +allegro/docs/man/al_ustr_rfind_cstr.3 +allegro/docs/man/al_ustr_rfind_str.3 +allegro/docs/man/al_ustr_rtrim_ws.3 +allegro/docs/man/al_ustr_set_chr.3 +allegro/docs/man/al_ustr_size.3 +allegro/docs/man/al_ustr_size_utf16.3 +allegro/docs/man/al_ustr_to_buffer.3 +allegro/docs/man/al_ustr_trim_ws.3 +allegro/docs/man/al_ustr_truncate.3 +allegro/docs/man/al_ustr_vappendf.3 +allegro/docs/man/al_utf16_encode.3 +allegro/docs/man/al_utf16_width.3 +allegro/docs/man/al_utf8_encode.3 +allegro/docs/man/al_utf8_width.3 +allegro/docs/man/al_vertical_shear_transform.3 +allegro/docs/man/al_vfprintf.3 +allegro/docs/man/al_wait_cond.3 +allegro/docs/man/al_wait_cond_until.3 +allegro/docs/man/al_wait_for_event.3 +allegro/docs/man/al_wait_for_event_timed.3 +allegro/docs/man/al_wait_for_event_until.3 +allegro/docs/man/al_wait_for_vsync.3 +allegro/docs/man/al_win_add_window_callback.3 +allegro/docs/man/al_win_remove_window_callback.3 +allegro/docs/man/al_x_set_initial_icon.3 +allegro/docs/scripts/ +allegro/docs/scripts/aatree.c +allegro/docs/scripts/aatree.h +allegro/docs/scripts/check_consistency +allegro/docs/scripts/dawk.c +allegro/docs/scripts/dawk.h +allegro/docs/scripts/insert_timestamp.c +allegro/docs/scripts/make_doc.c +allegro/docs/scripts/make_doc.h +allegro/docs/scripts/make_html_refs.c +allegro/docs/scripts/make_index.c +allegro/docs/scripts/make_man.c +allegro/docs/scripts/make_protos.c +allegro/docs/scripts/make_search_index.c +allegro/docs/scripts/make_single.c +allegro/docs/scripts/scan_examples.c +allegro/docs/scripts/trex.c +allegro/docs/scripts/trex.h +allegro/docs/scripts/trex.txt +allegro/docs/src/ +allegro/docs/src/autosuggest.js +allegro/docs/src/changes-5.0.txt +allegro/docs/src/changes-5.1.txt +allegro/docs/src/changes-5.2.txt +allegro/docs/src/custom_header.html +allegro/docs/src/pandoc.css +allegro/docs/src/refman/ +allegro/docs/src/refman/acodec.txt +allegro/docs/src/refman/allegro_version.tex.cmake +allegro/docs/src/refman/audio.txt +allegro/docs/src/refman/color.txt +allegro/docs/src/refman/config.txt +allegro/docs/src/refman/direct3d.txt +allegro/docs/src/refman/display.txt +allegro/docs/src/refman/events.txt +allegro/docs/src/refman/file.txt +allegro/docs/src/refman/fixed.txt +allegro/docs/src/refman/font.txt +allegro/docs/src/refman/fshook.txt +allegro/docs/src/refman/fullscreen_mode.txt +allegro/docs/src/refman/getting_started.txt +allegro/docs/src/refman/graphics.txt +allegro/docs/src/refman/haptic.txt +allegro/docs/src/refman/image.txt +allegro/docs/src/refman/images/ +allegro/docs/src/refman/images/LINE_CAP.png +allegro/docs/src/refman/images/LINE_CAP.svg +allegro/docs/src/refman/images/LINE_JOIN.png +allegro/docs/src/refman/images/LINE_JOIN.svg +allegro/docs/src/refman/images/audio.png +allegro/docs/src/refman/images/audio.svg +allegro/docs/src/refman/images/primitives1.png +allegro/docs/src/refman/images/primitives1.svg +allegro/docs/src/refman/images/primitives2.png +allegro/docs/src/refman/images/primitives2.svg +allegro/docs/src/refman/inc.a.txt +allegro/docs/src/refman/inc.z.txt +allegro/docs/src/refman/index.txt +allegro/docs/src/refman/joystick.txt +allegro/docs/src/refman/keyboard.txt +allegro/docs/src/refman/latex.template +allegro/docs/src/refman/main.txt +allegro/docs/src/refman/memfile.txt +allegro/docs/src/refman/memory.txt +allegro/docs/src/refman/misc.txt +allegro/docs/src/refman/monitor.txt +allegro/docs/src/refman/mouse.txt +allegro/docs/src/refman/native_dialog.txt +allegro/docs/src/refman/opengl.txt +allegro/docs/src/refman/path.txt +allegro/docs/src/refman/physfs.txt +allegro/docs/src/refman/platform.txt +allegro/docs/src/refman/primitives.txt +allegro/docs/src/refman/shader.txt +allegro/docs/src/refman/state.txt +allegro/docs/src/refman/system.txt +allegro/docs/src/refman/threads.txt +allegro/docs/src/refman/time.txt +allegro/docs/src/refman/timer.txt +allegro/docs/src/refman/title.txt +allegro/docs/src/refman/touch.txt +allegro/docs/src/refman/transformations.txt +allegro/docs/src/refman/utf8.txt +allegro/docs/src/refman/video.txt +allegro/examples/ +allegro/examples/CMakeLists.txt +allegro/examples/Helper.cmake +allegro/examples/common.c +allegro/examples/data/ +allegro/examples/data/DejaVuSans.LICENSE +allegro/examples/data/DejaVuSans.ttf +allegro/examples/data/a4_font.fnt +allegro/examples/data/a4_font.tga +allegro/examples/data/alexlogo.bmp +allegro/examples/data/alexlogo.png +allegro/examples/data/allegro.pcx +allegro/examples/data/bkg.png +allegro/examples/data/blue_box.png +allegro/examples/data/bmpfont.tga +allegro/examples/data/cursor.tga +allegro/examples/data/ex_physfs.zip +allegro/examples/data/ex_prim_shader_pixel.glsl +allegro/examples/data/ex_prim_shader_pixel.hlsl +allegro/examples/data/ex_prim_shader_vertex.glsl +allegro/examples/data/ex_prim_shader_vertex.hlsl +allegro/examples/data/ex_shader_multitex_pixel.glsl +allegro/examples/data/ex_shader_multitex_pixel.hlsl +allegro/examples/data/ex_shader_pixel.glsl +allegro/examples/data/ex_shader_pixel.hlsl +allegro/examples/data/ex_shader_vertex.glsl +allegro/examples/data/ex_shader_vertex.hlsl +allegro/examples/data/ex_ttf.ini +allegro/examples/data/exconfig.ini +allegro/examples/data/fakeamp.bmp +allegro/examples/data/fixed_font.tga +allegro/examples/data/font.tga +allegro/examples/data/gradient1.bmp +allegro/examples/data/green.png +allegro/examples/data/haiku/ +allegro/examples/data/haiku/air_0.ogg +allegro/examples/data/haiku/air_1.ogg +allegro/examples/data/haiku/air_2.ogg +allegro/examples/data/haiku/air_3.ogg +allegro/examples/data/haiku/air_4.ogg +allegro/examples/data/haiku/air_5.ogg +allegro/examples/data/haiku/air_6.ogg +allegro/examples/data/haiku/air_7.ogg +allegro/examples/data/haiku/air_effect.png +allegro/examples/data/haiku/black_bead_opaque_A.png +allegro/examples/data/haiku/dropshadow.png +allegro/examples/data/haiku/earth4.png +allegro/examples/data/haiku/earth_0.ogg +allegro/examples/data/haiku/earth_1.ogg +allegro/examples/data/haiku/earth_2.ogg +allegro/examples/data/haiku/earth_3.ogg +allegro/examples/data/haiku/earth_4.ogg +allegro/examples/data/haiku/earth_5.ogg +allegro/examples/data/haiku/earth_6.ogg +allegro/examples/data/haiku/earth_7.ogg +allegro/examples/data/haiku/fire.png +allegro/examples/data/haiku/fire_0.ogg +allegro/examples/data/haiku/fire_1.ogg +allegro/examples/data/haiku/fire_2.ogg +allegro/examples/data/haiku/fire_3.ogg +allegro/examples/data/haiku/fire_4.ogg +allegro/examples/data/haiku/fire_5.ogg +allegro/examples/data/haiku/fire_6.ogg +allegro/examples/data/haiku/fire_7.ogg +allegro/examples/data/haiku/flame2.png +allegro/examples/data/haiku/healthy_glow.png +allegro/examples/data/haiku/main_flame2.png +allegro/examples/data/haiku/overlay_pretty.png +allegro/examples/data/haiku/select.ogg +allegro/examples/data/haiku/water.png +allegro/examples/data/haiku/water_0.ogg +allegro/examples/data/haiku/water_1.ogg +allegro/examples/data/haiku/water_2.ogg +allegro/examples/data/haiku/water_3.ogg +allegro/examples/data/haiku/water_4.ogg +allegro/examples/data/haiku/water_5.ogg +allegro/examples/data/haiku/water_6.ogg +allegro/examples/data/haiku/water_7.ogg +allegro/examples/data/haiku/water_droplets.png +allegro/examples/data/haiku/wind3.png +allegro/examples/data/icon.png +allegro/examples/data/icon.tga +allegro/examples/data/mask.pcx +allegro/examples/data/mysha.pcx +allegro/examples/data/mysha.tga +allegro/examples/data/mysha256x256.png +allegro/examples/data/mysha256x256.webp +allegro/examples/data/mysha_dxt1.dds +allegro/examples/data/mysha_dxt3.dds +allegro/examples/data/mysha_dxt5.dds +allegro/examples/data/mysha_pal.png +allegro/examples/data/obp.jpg +allegro/examples/data/planet.pcx +allegro/examples/data/sample.cfg +allegro/examples/data/texture.tga +allegro/examples/data/welcome.voc +allegro/examples/data/welcome.wav +allegro/examples/enet_common.h +allegro/examples/ex_acodec.c +allegro/examples/ex_acodec_multi.c +allegro/examples/ex_android.c +allegro/examples/ex_audio_chain.cpp +allegro/examples/ex_audio_props.cpp +allegro/examples/ex_audio_simple.c +allegro/examples/ex_audio_timer.c +allegro/examples/ex_bitmap.c +allegro/examples/ex_bitmap_file.c +allegro/examples/ex_bitmap_flip.c +allegro/examples/ex_blend.c +allegro/examples/ex_blend2.cpp +allegro/examples/ex_blend_bench.c +allegro/examples/ex_blend_target.c +allegro/examples/ex_blend_test.c +allegro/examples/ex_blit.c +allegro/examples/ex_camera.c +allegro/examples/ex_clip.c +allegro/examples/ex_clipboard.c +allegro/examples/ex_color.cpp +allegro/examples/ex_color2.c +allegro/examples/ex_compressed.c +allegro/examples/ex_config.c +allegro/examples/ex_convert.c +allegro/examples/ex_cpu.c +allegro/examples/ex_curl.c +allegro/examples/ex_d3d.cpp +allegro/examples/ex_depth_mask.c +allegro/examples/ex_depth_target.c +allegro/examples/ex_dir.c +allegro/examples/ex_disable_screensaver.c +allegro/examples/ex_display_events.c +allegro/examples/ex_display_options.c +allegro/examples/ex_draw.c +allegro/examples/ex_draw_bitmap.c +allegro/examples/ex_drawpixels.c +allegro/examples/ex_dualies.c +allegro/examples/ex_enet_client.c +allegro/examples/ex_enet_server.c +allegro/examples/ex_expose.c +allegro/examples/ex_file.c +allegro/examples/ex_file_slice.c +allegro/examples/ex_filter.c +allegro/examples/ex_font.c +allegro/examples/ex_font_justify.cpp +allegro/examples/ex_font_multiline.cpp +allegro/examples/ex_fs_resize.c +allegro/examples/ex_fs_window.c +allegro/examples/ex_get_path.c +allegro/examples/ex_gldepth.c +allegro/examples/ex_glext.c +allegro/examples/ex_haiku.c +allegro/examples/ex_haptic.c +allegro/examples/ex_haptic2.cpp +allegro/examples/ex_icon.c +allegro/examples/ex_icon2.c +allegro/examples/ex_inject_events.c +allegro/examples/ex_joystick_events.c +allegro/examples/ex_joystick_hotplugging.c +allegro/examples/ex_kcm_direct.c +allegro/examples/ex_keyboard_events.c +allegro/examples/ex_keyboard_focus.c +allegro/examples/ex_lines.c +allegro/examples/ex_loading_thread.c +allegro/examples/ex_lockbitmap.c +allegro/examples/ex_logo.c +allegro/examples/ex_membmp.c +allegro/examples/ex_memfile.c +allegro/examples/ex_menu.c +allegro/examples/ex_mixer_chain.c +allegro/examples/ex_mixer_pp.c +allegro/examples/ex_monitorinfo.c +allegro/examples/ex_mouse.c +allegro/examples/ex_mouse_cursor.c +allegro/examples/ex_mouse_events.c +allegro/examples/ex_mouse_focus.c +allegro/examples/ex_mouse_warp.c +allegro/examples/ex_multisample.c +allegro/examples/ex_multisample_target.c +allegro/examples/ex_multiwin.c +allegro/examples/ex_native_filechooser.c +allegro/examples/ex_nodisplay.c +allegro/examples/ex_noframe.c +allegro/examples/ex_ogre3d.cpp +allegro/examples/ex_opengl.c +allegro/examples/ex_opengl_pixel_shader.c +allegro/examples/ex_palette.c +allegro/examples/ex_path.c +allegro/examples/ex_path_test.c +allegro/examples/ex_physfs.c +allegro/examples/ex_pixelformat.cpp +allegro/examples/ex_polygon.c +allegro/examples/ex_premulalpha.c +allegro/examples/ex_prim.c +allegro/examples/ex_prim_shader.c +allegro/examples/ex_projection.c +allegro/examples/ex_projection2.c +allegro/examples/ex_record.c +allegro/examples/ex_record_name.c +allegro/examples/ex_reparent.c +allegro/examples/ex_resample_test.c +allegro/examples/ex_resize.c +allegro/examples/ex_resize2.c +allegro/examples/ex_rotate.c +allegro/examples/ex_saw.c +allegro/examples/ex_scale.c +allegro/examples/ex_shader.cpp +allegro/examples/ex_shader_multitex.c +allegro/examples/ex_shader_target.c +allegro/examples/ex_stream_file.c +allegro/examples/ex_stream_seek.c +allegro/examples/ex_subbitmap.c +allegro/examples/ex_synth.cpp +allegro/examples/ex_threads.c +allegro/examples/ex_threads2.c +allegro/examples/ex_timedwait.c +allegro/examples/ex_timer.c +allegro/examples/ex_timer_pause.c +allegro/examples/ex_touch_input.c +allegro/examples/ex_transform.c +allegro/examples/ex_ttf.c +allegro/examples/ex_user_events.c +allegro/examples/ex_utf8.c +allegro/examples/ex_vertex_buffer.c +allegro/examples/ex_video.c +allegro/examples/ex_vsync.c +allegro/examples/ex_window_constraints.c +allegro/examples/ex_window_maximized.c +allegro/examples/ex_window_title.c +allegro/examples/ex_windows.c +allegro/examples/ex_winfull.c +allegro/examples/nihgui.cpp +allegro/examples/nihgui.hpp +allegro/include/ +allegro/include/allegro5/ +allegro/include/allegro5/alcompat.h +allegro/include/allegro5/allegro.h +allegro/include/allegro5/allegro5.h +allegro/include/allegro5/allegro_android.h +allegro/include/allegro5/allegro_direct3d.h +allegro/include/allegro5/allegro_iphone.h +allegro/include/allegro5/allegro_iphone_objc.h +allegro/include/allegro5/allegro_opengl.h +allegro/include/allegro5/allegro_osx.h +allegro/include/allegro5/allegro_windows.h +allegro/include/allegro5/allegro_x.h +allegro/include/allegro5/altime.h +allegro/include/allegro5/base.h +allegro/include/allegro5/bitmap.h +allegro/include/allegro5/bitmap_draw.h +allegro/include/allegro5/bitmap_io.h +allegro/include/allegro5/bitmap_lock.h +allegro/include/allegro5/blender.h +allegro/include/allegro5/clipboard.h +allegro/include/allegro5/color.h +allegro/include/allegro5/config.h +allegro/include/allegro5/cpu.h +allegro/include/allegro5/debug.h +allegro/include/allegro5/display.h +allegro/include/allegro5/drawing.h +allegro/include/allegro5/error.h +allegro/include/allegro5/events.h +allegro/include/allegro5/file.h +allegro/include/allegro5/fixed.h +allegro/include/allegro5/fmaths.h +allegro/include/allegro5/fshook.h +allegro/include/allegro5/fullscreen_mode.h +allegro/include/allegro5/haptic.h +allegro/include/allegro5/inline/ +allegro/include/allegro5/inline/fmaths.inl +allegro/include/allegro5/internal/ +allegro/include/allegro5/internal/aintern.h +allegro/include/allegro5/internal/aintern_aatree.h +allegro/include/allegro5/internal/aintern_android.h +allegro/include/allegro5/internal/aintern_atomicops.h +allegro/include/allegro5/internal/aintern_bitmap.h +allegro/include/allegro5/internal/aintern_blend.h +allegro/include/allegro5/internal/aintern_config.h +allegro/include/allegro5/internal/aintern_convert.h +allegro/include/allegro5/internal/aintern_debug.h +allegro/include/allegro5/internal/aintern_direct3d.h +allegro/include/allegro5/internal/aintern_display.h +allegro/include/allegro5/internal/aintern_driver.h +allegro/include/allegro5/internal/aintern_dtor.h +allegro/include/allegro5/internal/aintern_events.h +allegro/include/allegro5/internal/aintern_exitfunc.h +allegro/include/allegro5/internal/aintern_file.h +allegro/include/allegro5/internal/aintern_float.h +allegro/include/allegro5/internal/aintern_fshook.h +allegro/include/allegro5/internal/aintern_gp2xwiz.h +allegro/include/allegro5/internal/aintern_haptic.h +allegro/include/allegro5/internal/aintern_iphone.h +allegro/include/allegro5/internal/aintern_joystick.h +allegro/include/allegro5/internal/aintern_keyboard.h +allegro/include/allegro5/internal/aintern_list.h +allegro/include/allegro5/internal/aintern_ljoynu.h +allegro/include/allegro5/internal/aintern_memblit.h +allegro/include/allegro5/internal/aintern_memdraw.h +allegro/include/allegro5/internal/aintern_mouse.h +allegro/include/allegro5/internal/aintern_opengl.h +allegro/include/allegro5/internal/aintern_osxclipboard.h +allegro/include/allegro5/internal/aintern_path.h +allegro/include/allegro5/internal/aintern_pixels.h +allegro/include/allegro5/internal/aintern_raspberrypi.h +allegro/include/allegro5/internal/aintern_shader.h +allegro/include/allegro5/internal/aintern_system.h +allegro/include/allegro5/internal/aintern_thread.h +allegro/include/allegro5/internal/aintern_timer.h +allegro/include/allegro5/internal/aintern_tls.h +allegro/include/allegro5/internal/aintern_touch_input.h +allegro/include/allegro5/internal/aintern_transform.h +allegro/include/allegro5/internal/aintern_tri_soft.h +allegro/include/allegro5/internal/aintern_vector.h +allegro/include/allegro5/internal/aintern_wclipboard.h +allegro/include/allegro5/internal/aintern_wjoyall.h +allegro/include/allegro5/internal/aintern_wjoydxnu.h +allegro/include/allegro5/internal/aintern_wjoyxi.h +allegro/include/allegro5/internal/aintern_wunicode.h +allegro/include/allegro5/internal/aintern_x.h +allegro/include/allegro5/internal/aintern_xclipboard.h +allegro/include/allegro5/internal/aintern_xcursor.h +allegro/include/allegro5/internal/aintern_xdisplay.h +allegro/include/allegro5/internal/aintern_xembed.h +allegro/include/allegro5/internal/aintern_xevents.h +allegro/include/allegro5/internal/aintern_xfullscreen.h +allegro/include/allegro5/internal/aintern_xglx_config.h +allegro/include/allegro5/internal/aintern_xkeyboard.h +allegro/include/allegro5/internal/aintern_xmouse.h +allegro/include/allegro5/internal/aintern_xsystem.h +allegro/include/allegro5/internal/aintern_xtouch.h +allegro/include/allegro5/internal/aintern_xwindow.h +allegro/include/allegro5/internal/alconfig.h +allegro/include/allegro5/internal/bstrlib.h +allegro/include/allegro5/joystick.h +allegro/include/allegro5/keyboard.h +allegro/include/allegro5/keycodes.h +allegro/include/allegro5/memory.h +allegro/include/allegro5/monitor.h +allegro/include/allegro5/mouse.h +allegro/include/allegro5/mouse_cursor.h +allegro/include/allegro5/opengl/ +allegro/include/allegro5/opengl/GLext/ +allegro/include/allegro5/opengl/GLext/gl_ext_alias.h +allegro/include/allegro5/opengl/GLext/gl_ext_api.h +allegro/include/allegro5/opengl/GLext/gl_ext_defs.h +allegro/include/allegro5/opengl/GLext/gl_ext_list.h +allegro/include/allegro5/opengl/GLext/glx_ext_alias.h +allegro/include/allegro5/opengl/GLext/glx_ext_api.h +allegro/include/allegro5/opengl/GLext/glx_ext_defs.h +allegro/include/allegro5/opengl/GLext/glx_ext_list.h +allegro/include/allegro5/opengl/GLext/wgl_ext_alias.h +allegro/include/allegro5/opengl/GLext/wgl_ext_api.h +allegro/include/allegro5/opengl/GLext/wgl_ext_defs.h +allegro/include/allegro5/opengl/GLext/wgl_ext_list.h +allegro/include/allegro5/opengl/gl_ext.h +allegro/include/allegro5/path.h +allegro/include/allegro5/platform/ +allegro/include/allegro5/platform/aintandroid.h +allegro/include/allegro5/platform/aintiphone.h +allegro/include/allegro5/platform/aintlnx.h +allegro/include/allegro5/platform/aintosx.h +allegro/include/allegro5/platform/aintraspberrypi.h +allegro/include/allegro5/platform/aintunix.h +allegro/include/allegro5/platform/aintuthr.h +allegro/include/allegro5/platform/aintwin.h +allegro/include/allegro5/platform/aintwiz.h +allegro/include/allegro5/platform/aintwthr.h +allegro/include/allegro5/platform/aintxglx.h +allegro/include/allegro5/platform/alandroid.h +allegro/include/allegro5/platform/alandroidcfg.h +allegro/include/allegro5/platform/albcc32.h +allegro/include/allegro5/platform/aldmc.h +allegro/include/allegro5/platform/aliphone.h +allegro/include/allegro5/platform/aliphonecfg.h +allegro/include/allegro5/platform/allegro_internal_sdl.h +allegro/include/allegro5/platform/allegro_sdl_config.h +allegro/include/allegro5/platform/allegro_sdl_thread.h +allegro/include/allegro5/platform/almngw32.h +allegro/include/allegro5/platform/almsvc.h +allegro/include/allegro5/platform/alosx.h +allegro/include/allegro5/platform/alosxcfg.h +allegro/include/allegro5/platform/alplatf.h.cmake +allegro/include/allegro5/platform/alraspberrypi.h +allegro/include/allegro5/platform/alraspberrypicfg.h +allegro/include/allegro5/platform/alucfg.h +allegro/include/allegro5/platform/alunix.h +allegro/include/allegro5/platform/alwatcom.h +allegro/include/allegro5/platform/alwin.h +allegro/include/allegro5/platform/alwiz.h +allegro/include/allegro5/platform/alwizcfg.h +allegro/include/allegro5/platform/astdbool.h +allegro/include/allegro5/platform/astdint.h +allegro/include/allegro5/render_state.h +allegro/include/allegro5/shader.h +allegro/include/allegro5/system.h +allegro/include/allegro5/threads.h +allegro/include/allegro5/timer.h +allegro/include/allegro5/tls.h +allegro/include/allegro5/touch_input.h +allegro/include/allegro5/transformations.h +allegro/include/allegro5/utf8.h +allegro/indent.pro +allegro/misc/ +allegro/misc/Allegro5_iOS/ +allegro/misc/Allegro5_iOS/Allegro5_iOS.xcodeproj/ +allegro/misc/Allegro5_iOS/Allegro5_iOS.xcodeproj/project.pbxproj +allegro/misc/Allegro5_iOS/allegro5/ +allegro/misc/Allegro5_iOS/allegro5/internal/ +allegro/misc/Allegro5_iOS/allegro5/internal/aintern_image_cfg.h +allegro/misc/Allegro5_iOS/allegro5/internal/aintern_ttf_cfg.h +allegro/misc/Allegro5_iOS/allegro5/platform/ +allegro/misc/Allegro5_iOS/allegro5/platform/alplatf.h +allegro/misc/allegro.pc.in +allegro/misc/allegro_acodec.pc.in +allegro/misc/allegro_audio.pc.in +allegro/misc/allegro_color.pc.in +allegro/misc/allegro_dialog.pc.in +allegro/misc/allegro_font.pc.in +allegro/misc/allegro_image.pc.in +allegro/misc/allegro_main.pc.in +allegro/misc/allegro_memfile.pc.in +allegro/misc/allegro_monolith.pc.in +allegro/misc/allegro_physfs.pc.in +allegro/misc/allegro_primitives.pc.in +allegro/misc/allegro_ttf.pc.in +allegro/misc/allegro_video.pc.in +allegro/misc/askq.c +allegro/misc/convert_line_endings.sh +allegro/misc/coverage.sh +allegro/misc/create_release_archives.sh +allegro/misc/dtou.sh +allegro/misc/embedman.bat +allegro/misc/fixver.sh +allegro/misc/gcc-uni.sh +allegro/misc/gl_mkalias.sh +allegro/misc/icon.png +allegro/misc/icon.xpm +allegro/misc/install_test.c +allegro/misc/make_converters.py +allegro/misc/make_mixer_helpers.py +allegro/misc/make_pixel_tables.py +allegro/misc/make_scanline_drawers.py +allegro/misc/mkunixdists.sh +allegro/misc/msvchelp.c +allegro/misc/regenerate.sh +allegro/misc/utod.sh +allegro/misc/vcvars.c +allegro/misc/zipup.sh +allegro/misc/zipwin.sh +allegro/python/ +allegro/python/CMakeLists.txt +allegro/python/checkdocs.py +allegro/python/ex_draw_bitmap.py +allegro/python/generate_python_ctypes.py +allegro/python/pong.py +allegro/python/readme.txt +allegro/src/ +allegro/src/allegro.c +allegro/src/android/ +allegro/src/android/android_apk_file.c +allegro/src/android/android_apk_fs.c +allegro/src/android/android_clipboard.c +allegro/src/android/android_display.c +allegro/src/android/android_image.c +allegro/src/android/android_input_stream.c +allegro/src/android/android_joystick.c +allegro/src/android/android_keyboard.c +allegro/src/android/android_mouse.c +allegro/src/android/android_sensors.c +allegro/src/android/android_system.c +allegro/src/android/android_touch.c +allegro/src/android/jni_helpers.c +allegro/src/bitmap.c +allegro/src/bitmap_draw.c +allegro/src/bitmap_io.c +allegro/src/bitmap_lock.c +allegro/src/bitmap_pixel.c +allegro/src/bitmap_type.c +allegro/src/blenders.c +allegro/src/clipboard.c +allegro/src/config.c +allegro/src/convert.c +allegro/src/cpu.c +allegro/src/debug.c +allegro/src/display.c +allegro/src/display_settings.c +allegro/src/drawing.c +allegro/src/dtor.c +allegro/src/events.c +allegro/src/evtsrc.c +allegro/src/exitfunc.c +allegro/src/file.c +allegro/src/file_slice.c +allegro/src/file_stdio.c +allegro/src/fshook.c +allegro/src/fshook_stdio.c +allegro/src/fshook_win.inc +allegro/src/fullscreen_mode.c +allegro/src/gp2xwiz/ +allegro/src/gp2xwiz/wiz_display_fb.c +allegro/src/gp2xwiz/wiz_display_opengl.c +allegro/src/gp2xwiz/wiz_joystick.c +allegro/src/gp2xwiz/wiz_system.c +allegro/src/haptic.c +allegro/src/inline.c +allegro/src/iphone/ +allegro/src/iphone/EAGLView.h +allegro/src/iphone/EAGLView.m +allegro/src/iphone/ViewController.h +allegro/src/iphone/ViewController.m +allegro/src/iphone/allegroAppDelegate.h +allegro/src/iphone/allegroAppDelegate.m +allegro/src/iphone/iphone.h +allegro/src/iphone/iphone_clipboard.m +allegro/src/iphone/iphone_display.m +allegro/src/iphone/iphone_joystick.m +allegro/src/iphone/iphone_keyboard.c +allegro/src/iphone/iphone_main.m +allegro/src/iphone/iphone_mouse.m +allegro/src/iphone/iphone_path.m +allegro/src/iphone/iphone_system.c +allegro/src/iphone/iphone_touch_input.m +allegro/src/joynu.c +allegro/src/keybdnu.c +allegro/src/libc.c +allegro/src/linux/ +allegro/src/linux/lasyncio.c +allegro/src/linux/lconsole.c +allegro/src/linux/lhaptic.c +allegro/src/linux/ljoynu.c +allegro/src/linux/lkeybdnu.c +allegro/src/linux/lmemory.c +allegro/src/linux/lmouse.c +allegro/src/linux/lmsedrv.c +allegro/src/linux/lmseev.c +allegro/src/linux/lmsegpmd.c +allegro/src/linux/lmsems.c +allegro/src/linux/lmseps2.c +allegro/src/linux/lstddrv.c +allegro/src/linux/lsystem.c +allegro/src/linux/vtswitch.c +allegro/src/macosx/ +allegro/src/macosx/hidjoy-10.4.m +allegro/src/macosx/hidjoy.m +allegro/src/macosx/hidman.m +allegro/src/macosx/keybd.m +allegro/src/macosx/osx_app_delegate.m +allegro/src/macosx/osxclipboard.m +allegro/src/macosx/osxgl.h +allegro/src/macosx/osxgl.m +allegro/src/macosx/qzmouse.m +allegro/src/macosx/system.m +allegro/src/math.c +allegro/src/memblit.c +allegro/src/memdraw.c +allegro/src/memory.c +allegro/src/misc/ +allegro/src/misc/aatree.c +allegro/src/misc/bstrlib.c +allegro/src/misc/bstrlib.txt +allegro/src/misc/list.c +allegro/src/misc/vector.c +allegro/src/monitor.c +allegro/src/mouse_cursor.c +allegro/src/mousenu.c +allegro/src/opengl/ +allegro/src/opengl/extensions.c +allegro/src/opengl/ogl_bitmap.c +allegro/src/opengl/ogl_display.c +allegro/src/opengl/ogl_draw.c +allegro/src/opengl/ogl_fbo.c +allegro/src/opengl/ogl_helpers.h +allegro/src/opengl/ogl_lock.c +allegro/src/opengl/ogl_lock_es.c +allegro/src/opengl/ogl_render_state.c +allegro/src/opengl/ogl_shader.c +allegro/src/path.c +allegro/src/pixel_tables.inc +allegro/src/pixels.c +allegro/src/raspberrypi/ +allegro/src/raspberrypi/picursor.h +allegro/src/raspberrypi/pidisplay.c +allegro/src/raspberrypi/pisystem.c +allegro/src/scanline_drawers.inc +allegro/src/sdl/ +allegro/src/sdl/sdl_display.c +allegro/src/sdl/sdl_event_hack.c +allegro/src/sdl/sdl_joystick.c +allegro/src/sdl/sdl_keyboard.c +allegro/src/sdl/sdl_mouse.c +allegro/src/sdl/sdl_system.c +allegro/src/sdl/sdl_thread.c +allegro/src/sdl/sdl_time.c +allegro/src/sdl/sdl_touch.c +allegro/src/shader.c +allegro/src/shader_source.inc +allegro/src/system.c +allegro/src/threads.c +allegro/src/timernu.c +allegro/src/tls.c +allegro/src/tls_dll.inc +allegro/src/tls_native.inc +allegro/src/tls_pthread.inc +allegro/src/touch_input.c +allegro/src/transformations.c +allegro/src/tri_soft.c +allegro/src/unix/ +allegro/src/unix/udrvlist.c +allegro/src/unix/ufdwatch.c +allegro/src/unix/ugfxdrv.c +allegro/src/unix/uhapdrv.c +allegro/src/unix/ujoydrv.c +allegro/src/unix/ukeybd.c +allegro/src/unix/umouse.c +allegro/src/unix/upath.c +allegro/src/unix/utime.c +allegro/src/unix/uxthread.c +allegro/src/utf8.c +allegro/src/win/ +allegro/src/win/d3d.h +allegro/src/win/d3d_bmp.cpp +allegro/src/win/d3d_d3dx9.cpp +allegro/src/win/d3d_disp.cpp +allegro/src/win/d3d_display_formats.cpp +allegro/src/win/d3d_render_state.cpp +allegro/src/win/d3d_shader.cpp +allegro/src/win/wclipboard.c +allegro/src/win/wgl.h +allegro/src/win/wgl_disp.c +allegro/src/win/whapall.c +allegro/src/win/whapdrv.c +allegro/src/win/whaptic.cpp +allegro/src/win/whapxi.c +allegro/src/win/wjoyall.c +allegro/src/win/wjoydrv.c +allegro/src/win/wjoydxnu.cpp +allegro/src/win/wjoyxi.c +allegro/src/win/wkeyboard.c +allegro/src/win/wmcursor.c +allegro/src/win/wmouse.c +allegro/src/win/wsystem.c +allegro/src/win/wthread.c +allegro/src/win/wtime.c +allegro/src/win/wtouch_input.c +allegro/src/win/wunicode.c +allegro/src/win/wwindow.c +allegro/src/win/wxthread.c +allegro/src/x/ +allegro/src/x/icon.xpm +allegro/src/x/xclipboard.c +allegro/src/x/xcursor.c +allegro/src/x/xdisplay.c +allegro/src/x/xevents.c +allegro/src/x/xfullscreen.c +allegro/src/x/xglx_config.c +allegro/src/x/xicon.h +allegro/src/x/xkeyboard.c +allegro/src/x/xmousenu.c +allegro/src/x/xrandr.c +allegro/src/x/xsystem.c +allegro/src/x/xtouch.c +allegro/src/x/xwindow.c +allegro/tests/ +allegro/tests/CMakeLists.txt +allegro/tests/grab_bitmap_suites.sh +allegro/tests/manual_bmpsuite1.ini +allegro/tests/manual_bmpsuite2.ini +allegro/tests/manual_bmpsuite3.ini +allegro/tests/manual_bmpsuite4.ini +allegro/tests/test_backbuffer.ini +allegro/tests/test_bitmaps.ini +allegro/tests/test_bitmaps2.ini +allegro/tests/test_blend.ini +allegro/tests/test_blend_target.ini +allegro/tests/test_ciede2000.ini +allegro/tests/test_compressed.ini +allegro/tests/test_convert.ini +allegro/tests/test_driver.c +allegro/tests/test_driver.txt +allegro/tests/test_fonts.ini +allegro/tests/test_image.ini +allegro/tests/test_locking.ini +allegro/tests/test_locking2.ini +allegro/tests/test_prim.ini +allegro/tests/test_prim2.ini +allegro/tools/ +allegro/tools/macosx/ +allegro/tools/macosx/fixbundle.c +allegro/tools/win/ +allegro/tools/win/wfixicon.c +allegro/tools/win/wfixicon.txt +allegro/tools/x11/ +allegro/tools/x11/xf2pcx.c +allegro/tools/x11/xfixicon.sh +allegro/tools/x11/xkeymap.c +allegro/tools/x11/xkeymap.txt +allegro/allegro.mft diff --git a/allegro/allegro5.cfg b/allegro/allegro5.cfg new file mode 100644 index 00000000..071ad3a0 --- /dev/null +++ b/allegro/allegro5.cfg @@ -0,0 +1,237 @@ +# +# Configuration file for the Allegro 5 library. +# +# This file should be either in the same directory as your program. +# +# On Unix, this file may also be stored as ~/.allegro5rc or /etc/allegro5rc. +# If multiple files exist, they will be merged, with values from more specific +# files overriding the less specific files. + +[graphics] + +# Graphics driver. +# Can be 'default', 'opengl' or 'direct3d' (Windows only). +driver=default + +# Display configuration selection mode. +# +# Under Linux, it can be used to force the old GLX 1.2 way of choosing +# display settings or the new FBConfig method introduced with GLX 1.3. +# +# Under Windows, when using the OpenGL driver, setting it to old will +# use DescribePixelFormat and new will use wglGetPixelFormatAttribivARB +# (provided by WGL_ARB_pixel_format extension). +# +# Can be 'old' and 'new'. Default is 'new'. +config_selection=new + +# What method to use to detect legacy cards for the Direct3D backend of the +# primitives addon. Can be 'default', which means it'll check that the pixel +# shader version supported is below some value. 'force_legacy' will force it to +# detect as a legacy card. 'force_modern' will force it to detect is as a modern +# card. +prim_d3d_legacy_detection=default + +# For compatibility reasons, video bitmaps smaller than this size are +# backed by textures with this size. This is often no longer necessary +# on more modern systems, and should be set to < 16 if you're creating +# bitmaps smaller than this size. Note that on Android, this is ignored +# if smaller than 32. +min_bitmap_size=16 + +[audio] + +# Driver can be 'default', 'openal', 'alsa', 'oss', 'pulseaudio' or 'directsound' +# depending on platform. +driver=default + +# Mixer quality can be 'linear' (default), 'cubic' (best), or 'point' (bad). +# default_mixer_quality=linear + +# The frequency to use for the default voice/mixer. Default: 44100. +# primary_voice_frequency=44100 +# primary_mixer_frequency=44100 + +# Can be 'int16', otherwise defaults to float32. +# primary_voice_depth=float32 +# primary_mixer_depth=float32 + +[oss] + +# You can skip probing for OSS4 driver by setting this option to 'yes'. +# Default is 'no'. +force_ver3=no + +# When OSS3 is used, you can choose a sound device here. +# Default is '/dev/dsp'. +device=/dev/dsp + +[alsa] + +# Set the ALSA sound device. +# Default is 'default'. +device=default + +# Set the ALSA capture device, e.g. hw:0,0 +# Default is 'default'. +capture_device=default + +# Set the period size (in samples) +# Note that this is erroneously called 'buffer_size' for backwards +# compatibility. +buffer_size=32 + +# Set the buffer size (in samples) +buffer_size2=2048 + +[pulseaudio] + +# Set the buffer size (in samples) +buffer_size=1024 + +[directsound] + +# Set the DirectSound buffer size (in samples) +buffer_size = 8192 + +# Which window to attach the device to. Can be 'desktop', or 'foreground'. Try +# flipping this if there are issues initializing audio. +window = desktop + +[opengl] + +# If you want to support old OpenGL versions, you can make Allegro +# believe an older version than what you actually have is used with +# this key. This is only for testing/debugging purposes. + +# force_opengl_version = 1.2 + +[opengl_disabled_extensions] + +# Any OpenGL extensions can be listed here to make Allegro report them +# as not available. The extensions used by Allegro itself if available +# are shown below - uncommenting them would disable them: + +# GL_ARB_texture_non_power_of_two=0 +# GL_EXT_framebuffer_object=0 + +[image] + +# Gamma handling of PNG files. +# A value of 0.0 means: Don't do any gamma correction. +# A value of -1.0 means: Use the value from the environment variable +# SCREEN_GAMMA (if available), otherwise fallback to a value of 2.2 +# (a good guess for PC monitors, and the value for sRGB colourspace). +# Otherwise, the value is taken as-is. +png_screen_gamma = -1.0 + +# Compression level for PNG files. Possible values: 0-9, "best", "fastest", +# "none" or "default" (a sane compromise between size and speed). +png_compression_level = default + +# Quality level for JPEG files. Possible values: 0-100 +jpeg_quality_level = 75 + +# Quality level for WebP files. Possible values: 0-100 or "lossless" +webp_quality_level = lossless + +[joystick] + +# Linux: Allegro normally searches for joystick device N at /dev/input/jsN. +# You can override the device file path on a per-device basis, like this. + +# device0=/dev/input/by-id/usb-blahblah-joystick + +# Windows: You can choose between the XINPUT or DIRECTINPUT driver for +# joysticks and force feedback joysticks. Xinput is the more modern +# system, but DirectInput has more force feedback capabilities for older +# joysticks. +driver=XINPUT + +# Windows: Use this to force an XInput DLL version, example "3" forces +# xinput1_3.dll. By default, the latest version is used. + +# force_xinput_version = 3 + +[keyboard] + +# You can trap/untrap the mouse cursor within a window with a key combination +# of your choice, e.g. "Ctrl-G", "Shift-Ctrl-G", "Ctrl-LShift", "RWin". +# This feature currently only works on X11 and Windows. + +# toggle_mouse_grab_key = ScrollLock + +# By default, you can press Ctrl-Alt-Delete or Ctrl-Alt-End to quit Allegro +# programs. Set this to false to disable this feature. This only works on +# Linux. + +# enable_three_finger_exit = true + +# By default, pressing the LED toggling keys (e.g. CapsLock) will also toggle +# the LED on the keyboard. Setting this to false disable that connection. +# This can only be controled on non-X11 Linux. + +# enable_key_led_toggle = true + + +[trace] +# Comma-separated list of channels to log. Default is "all" which +# disables channel filtering. Some possible channels are: +# system,display,keyboard,opengl +# Channel names can be prefixed with - to exclude only those channels. +# Each addon and source-file can define additional channels though so +# there are more. +channels=all + +# Log-level. Can be one of debug, info, warn, error, none or empty. +# In debug builds if it is empty or unset, then the level is set to debug. +# In release builds if it is empty or unset, then the level is set to none. +level= + +# Set to 0 to disable line numbers in log files. +lines=1 + +# Set to 0 to disable timestamps in log files. +timestamps=1 + +# Set to 0 to disable function names in log files. +functions=1 + +[x11] +# Can be fullscreen_only, always, never +bypass_compositor = fullscreen_only + +[xkeymap] +# Override X11 keycode. The below example maps X11 code 52 (Y) to Allegro +# code 26 (Z) and X11 code 29 (Z) to Allegro code 25 (Y). +# 52=26 +# 29=25 + + +[shader] +# If you want to support override version of the d3dx9_xx.dll library +# define this value. +# By default, latest installed version is used. + +# force_d3dx9_version = 36 + +[ttf] + +# Set these to something other than 0 to override the default page sizes for TTF +# glyphs. +min_page_size = 0 +max_page_size = 0 + +# This entry contains characters that will be pre-catched during font loading. +# cache_text = a bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + +# Uncomment if you want only the characters in the cache_text entry to ever be drawn +# skip_cache_misses = true + +[compatibility] + +# Prior to 5.2.4 on Windows you had to manually resize the display when +# showing the menu using the dialog addon. After 5.2.4 this is done +# automatically, but may break old code that handled this eventuality. +# Set this to false for such code. +automatic_menu_display_resize = true diff --git a/allegro/android/CMakeLists.txt b/allegro/android/CMakeLists.txt new file mode 100644 index 00000000..f2b9ae53 --- /dev/null +++ b/allegro/android/CMakeLists.txt @@ -0,0 +1,73 @@ +set(PROJECT ${CMAKE_CURRENT_BINARY_DIR}/gradle_project) +set(PROJECT_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/gradle_project) +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(AAR_NAME allegro-debug.aar) + set(ASSEMBLE assembleDebug) +else() + set(AAR_NAME allegro-release.aar) + set(ASSEMBLE assembleRelease) +endif() +set(ALLEGRO_AAR ${LIBRARY_OUTPUT_PATH}/${AAR_NAME}) +set(ALLEGRO_AAR ${ALLEGRO_AAR} PARENT_SCOPE) + +if (NOT EXISTS "$ENV{ANDROID_HOME}") + set(ENV{ANDROID_HOME} "$ENV{HOME}/Android/Sdk") +endif() + +if (NOT EXISTS "$ENV{ANDROID_HOME}") + message(FATAL_ERROR "Please set the ANDROID_HOME environment variable +to the location of your Android SDK, or install Android Studio in the +default location ($ENV{HOME}/Android/Sdk))") +endif() + +set(ANDROID_HOME $ENV{ANDROID_HOME}) + +message(STATUS "Using Android SDK from ${ANDROID_HOME}.") + +file(GLOB javas "${PROJECT_SOURCE}/allegro/src/main/java/org/liballeg/android/*.java") + +configure_file( + ${PROJECT_SOURCE}/local.properties + ${PROJECT}/local.properties) + +set(GRADLE_PROJECT allegro) +configure_file( + ${PROJECT_SOURCE}/settings.gradle + ${PROJECT}/settings.gradle) + +set(COPY_FILES + ${PROJECT_SOURCE}/allegro/src/main/AndroidManifest.xml + ${PROJECT_SOURCE}/gradle.properties + ${PROJECT_SOURCE}/build.gradle + ${PROJECT_SOURCE}/gradlew + ${PROJECT_SOURCE}/gradle/wrapper/gradle-wrapper.jar + ${PROJECT_SOURCE}/gradle/wrapper/gradle-wrapper.properties + ${PROJECT_SOURCE}/allegro/build.gradle + ${PROJECT_SOURCE}/allegro/src/main/AndroidManifest.xml + ${javas} + ) + +list(APPEND COPIED_FILES ${PROJECT}/local.properties) + +foreach(copy ${COPY_FILES}) + string(REPLACE "${PROJECT_SOURCE}/" "${PROJECT}/" target ${copy}) + add_custom_command( + OUTPUT ${target} + DEPENDS ${copy} + COMMAND ${CMAKE_COMMAND} -E copy + ${copy} + ${target} + ) + list(APPEND COPIED_FILES ${target}) +endforeach() + +add_custom_command( + OUTPUT ${ALLEGRO_AAR} + DEPENDS ${COPIED_FILES} + WORKING_DIRECTORY ${PROJECT} + COMMAND ./gradlew ${ASSEMBLE} + COMMAND ${CMAKE_COMMAND} -E copy allegro/build/outputs/aar/${AAR_NAME} ${ALLEGRO_AAR} + ) + +add_custom_target(aar ALL + DEPENDS ${ALLEGRO_AAR}) diff --git a/allegro/android/gradle_project/allegro/build.gradle b/allegro/android/gradle_project/allegro/build.gradle new file mode 100644 index 00000000..5b75273d --- /dev/null +++ b/allegro/android/gradle_project/allegro/build.gradle @@ -0,0 +1,17 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 26 + defaultConfig { + minSdkVersion 15 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + } + } +} + diff --git a/allegro/android/gradle_project/allegro/src/main/AndroidManifest.xml b/allegro/android/gradle_project/allegro/src/main/AndroidManifest.xml new file mode 100644 index 00000000..7c80b326 --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.liballeg"> + <application> + <activity android:name="org.liballeg.android.AllegroActivity"/> + </application> +</manifest> diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroAPKList.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroAPKList.java new file mode 100644 index 00000000..21240c0b --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroAPKList.java @@ -0,0 +1,49 @@ +package org.liballeg.android; +import java.io.IOException; +import android.util.Log; +import java.io.InputStream; + +class AllegroAPKList +{ + static String list(AllegroActivity activity, String path) + { + /* The getAssets().list() method is *very* finicky about asset + * names, there must be no leading, trailing or double slashes + * or it fails. + */ + while (path.startsWith("/")) + path = path.substring(1); + while (path.endsWith("/")) + path = path.substring(0, path.length() - 1); + try { + String[] files = activity.getResources().getAssets().list(path); + String ret = ""; + for (String file : files) { + if (!ret.isEmpty()) + ret += ";"; + ret += file; + + /* We cannot use openfs as that causes an exception on any + * compressed files. The only thing we can do is open a + * stream - if that fails we assume it is a directory, + * otherwise a normal file. + */ + try { + file = path + "/" + file; + while (file.startsWith("/")) + file = file.substring(1); + InputStream s = activity.getResources().getAssets().open(file); + s.close(); + } + catch (IOException e) { + ret += "/"; + } + } + return ret; + } + catch (IOException e) { + Log.d("APK", e.toString()); + return ""; + } + } +} diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroAPKStream.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroAPKStream.java new file mode 100644 index 00000000..08efc32b --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroAPKStream.java @@ -0,0 +1,159 @@ +package org.liballeg.android; + +import android.content.res.AssetFileDescriptor; +import android.content.res.AssetManager; +import android.util.Log; +import java.io.IOException; +import java.io.InputStream; + +class AllegroAPKStream +{ + private static final String TAG = "AllegroAPKStream"; + + private AllegroActivity activity; + private String fn; + private InputStream in; + private long pos = 0; + private long fsize = -1; + private boolean at_eof = false; + + AllegroAPKStream(AllegroActivity activity, String filename) + { + this.activity = activity; + fn = Path.simplifyPath(filename); + if (!fn.equals(filename)) { + Log.d(TAG, filename + " simplified to: " + fn); + } + } + + boolean open() + { + try { + AssetFileDescriptor fd; + fd = activity.getResources().getAssets().openFd(fn); + fsize = fd.getLength(); + fd.close(); + } + catch (IOException e) { + Log.w(TAG, "could not get file size: " + e.toString()); + fsize = -1; + } + + return reopen(); + } + + boolean reopen() + { + if (in != null) { + close(); + in = null; + } + + try { + in = activity.getResources().getAssets().open(fn, + AssetManager.ACCESS_RANDOM); + } + catch (IOException e) { + Log.d(TAG, "Got IOException in reopen. fn='" + fn + "'"); + return false; + } + + in.mark((int)Math.pow(2, 31)); + pos = 0; + at_eof = false; + return true; + } + + boolean close() + { + try { + in.close(); + in = null; + return true; + } + catch (IOException e) { + Log.d(TAG, "IOException in close"); + return false; + } + } + + boolean seek(long seekto) + { + at_eof = false; + + if (seekto >= pos) { + long seek_ahead = seekto - pos; + return force_skip(seek_ahead); + } + + /* Seek backwards by rewinding to start of file first. */ + try { + in.reset(); + pos = 0; + } + catch (IOException e) { + if (!reopen()) { + /* Leaves pos wherever it lands! */ + return false; + } + } + return force_skip(seekto); + } + + private boolean force_skip(long n) + { + if (n <= 0) + return true; + + /* NOTE: in.skip doesn't work here! */ + byte[] b = new byte[(int)n]; + while (n > 0) { + int res; + try { + res = in.read(b, 0, (int)n); + } catch (IOException e) { + Log.d(TAG, "IOException: " + e.toString()); + return false; + } + if (res <= 0) + break; + pos += res; + n -= res; + } + return true; + } + + long tell() + { + return pos; + } + + int read(byte[] b) + { + try { + int ret = in.read(b); + if (ret > 0) + pos += ret; + else if (ret == -1) { + at_eof = true; + } + return ret; + } + catch (IOException e) { + Log.d(TAG, "IOException in read"); + return -1; + } + } + + long size() + { + return fsize; + } + + boolean eof() + { + return at_eof; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroActivity.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroActivity.java new file mode 100644 index 00000000..bd314ea6 --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroActivity.java @@ -0,0 +1,627 @@ +package org.liballeg.android; + +import android.app.Activity; +import android.content.Context; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.res.AssetManager; +import android.content.res.Configuration; +import android.hardware.display.DisplayManager; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.graphics.Rect; +import android.util.Log; +import android.view.Display; +import android.view.SurfaceHolder; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import java.io.File; +import java.lang.Runnable; +import java.lang.String; +import android.view.InputDevice; +import java.util.Vector; +import android.os.Build; +import android.view.View; + +public class AllegroActivity extends Activity +{ + /* properties */ + private String userLibName = "libapp.so"; + private Handler handler; + private Sensors sensors; + private Configuration currentConfig; + private AllegroSurface surface; + private ScreenLock screenLock; + private boolean exitedMain = false; + private boolean joystickReconfigureNotified = false; + private Vector<Integer> joysticks; + private Clipboard clipboard; + private DisplayManager.DisplayListener displayListener; + + public final static int JS_A = 0; + public final static int JS_B = 1; + public final static int JS_X = 2; + public final static int JS_Y = 3; + public final static int JS_L1 = 4; + public final static int JS_R1 = 5; + public final static int JS_DPAD_L = 6; + public final static int JS_DPAD_R = 7; + public final static int JS_DPAD_U = 8; + public final static int JS_DPAD_D = 9; + public final static int JS_MENU = 10; + + public boolean joystickActive = false; + + /* native methods we call */ + native boolean nativeOnCreate(); + native void nativeOnPause(); + native void nativeOnResume(); + native void nativeOnDestroy(); + native void nativeOnOrientationChange(int orientation, boolean init); + native void nativeSendJoystickConfigurationEvent(); + + /* methods native code calls */ + + String getUserLibName() + { + //ApplicationInfo appInfo = getApplicationInfo(); + //String libDir = Reflect.getField(appInfo, "nativeLibraryDir"); + ///* Android < 2.3 doesn't have .nativeLibraryDir */ + //if (libDir == null) { + //libDir = appInfo.dataDir + "/lib"; + //} + //return libDir + "/" + userLibName; + return userLibName; + } + + String getResourcesDir() + { + //return getApplicationInfo().dataDir + "/assets"; + //return getApplicationInfo().sourceDir + "/assets/"; + return getFilesDir().getAbsolutePath(); + } + + String getPubDataDir() + { + return getFilesDir().getAbsolutePath(); + } + + String getApkPath() + { + return getApplicationInfo().sourceDir; + } + + String getModel() + { + return android.os.Build.MODEL; + } + + String getManufacturer() + { + return android.os.Build.MANUFACTURER; + } + + Rect getDisplaySize() + { + Display display = getWindowManager().getDefaultDisplay(); + Rect size = new Rect(); + + if (android.os.Build.VERSION.SDK_INT >= 13) { + display.getRectSize(size); + } + else { + size.left = 0; + size.top = 0; + size.right = display.getWidth(); + size.bottom = display.getHeight(); + } + + return size; + } + + void postRunnable(Runnable runme) + { + try { + Log.d("AllegroActivity", "postRunnable"); + handler.post( runme ); + } catch (Exception x) { + Log.d("AllegroActivity", "postRunnable exception: " + x.getMessage()); + } + } + + void createSurface() + { + try { + Log.d("AllegroActivity", "createSurface"); + surface = new AllegroSurface(getApplicationContext(), + getWindowManager().getDefaultDisplay(), this); + + SurfaceHolder holder = surface.getHolder(); + holder.addCallback(surface); + holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); + //setContentView(surface); + Window win = getWindow(); + win.setContentView(surface); + Log.d("AllegroActivity", "createSurface end"); + } catch (Exception x) { + Log.d("AllegroActivity", "createSurface exception: " + x.getMessage()); + } + } + + void postCreateSurface() + { + try { + Log.d("AllegroActivity", "postCreateSurface"); + + handler.post(new Runnable() { + public void run() { + createSurface(); + } + }); + } catch (Exception x) { + Log.d("AllegroActivity", "postCreateSurface exception: " + x.getMessage()); + } + } + + void destroySurface() + { + Log.d("AllegroActivity", "destroySurface"); + + ViewGroup vg = (ViewGroup)(surface.getParent()); + vg.removeView(surface); + surface = null; + } + + void postDestroySurface() + { + try { + Log.d("AllegroActivity", "postDestroySurface"); + + handler.post(new Runnable() { + public void run() { + destroySurface(); + } + }); + } catch (Exception x) { + Log.d("AllegroActivity", "postDestroySurface exception: " + x.getMessage()); + } + } + + void postFinish() + { + exitedMain = true; + + try { + Log.d("AllegroActivity", "posting finish!"); + handler.post(new Runnable() { + public void run() { + try { + AllegroActivity.this.finish(); + System.exit(0); + } catch (Exception x) { + Log.d("AllegroActivity", "inner exception: " + x.getMessage()); + } + } + }); + } catch (Exception x) { + Log.d("AllegroActivity", "exception: " + x.getMessage()); + } + } + + boolean getMainReturned() + { + return exitedMain; + } + + boolean inhibitScreenLock(boolean inhibit) + { + if (screenLock == null) { + screenLock = new ScreenLock(this); + } + return screenLock.inhibitScreenLock(inhibit); + } + + /* end of functions native code calls */ + + public AllegroActivity(String userLibName) + { + super(); + this.userLibName = userLibName; + + joysticks = new Vector<Integer>(); + + reconfigureJoysticks(); + + Thread t = new Thread() { + public void run() { + while (true) { + try { + Thread.sleep(100); + } + catch (Exception e) { + } + + if (joystickReconfigureNotified) { + continue; + } + + int[] all = InputDevice.getDeviceIds(); + + boolean doConfigure = false; + int count = 0; + + for (int i = 0; i < all.length; i++) { + if (isJoystick(all[i])) { + if (!joysticks.contains(all[i])) { + doConfigure = true; + break; + } + else { + count++; + } + } + } + + if (!doConfigure) { + if (count != joysticks.size()) { + doConfigure = true; + } + } + + if (doConfigure) { + Log.d("AllegroActivity", "Sending joystick reconfigure event"); + joystickReconfigureNotified = true; + nativeSendJoystickConfigurationEvent(); + } + } + } + }; + t.start(); + } + + public void updateOrientation() { + nativeOnOrientationChange(getAllegroOrientation(), false); + } + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + Log.d("AllegroActivity", "onCreate"); + + Log.d("AllegroActivity", "Files Dir: " + getFilesDir()); + File extdir = Environment.getExternalStorageDirectory(); + + boolean mExternalStorageAvailable = false; + boolean mExternalStorageWriteable = false; + String state = Environment.getExternalStorageState(); + + if (Environment.MEDIA_MOUNTED.equals(state)) { + // We can read and write the media + mExternalStorageAvailable = mExternalStorageWriteable = true; + } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { + // We can only read the media + mExternalStorageAvailable = true; + mExternalStorageWriteable = false; + } else { + // Something else is wrong. It may be one of many other states, but + // all we need to know is we can neither read nor write + mExternalStorageAvailable = mExternalStorageWriteable = false; + } + + Log.d("AllegroActivity", "External Storage Dir: " + extdir.getAbsolutePath()); + Log.d("AllegroActivity", "External Files Dir: " + getExternalFilesDir(null)); + + Log.d("AllegroActivity", "external: avail = " + mExternalStorageAvailable + + " writable = " + mExternalStorageWriteable); + + Log.d("AllegroActivity", "sourceDir: " + getApplicationInfo().sourceDir); + Log.d("AllegroActivity", "publicSourceDir: " + getApplicationInfo().publicSourceDir); + + handler = new Handler(); + sensors = new Sensors(getApplicationContext()); + clipboard = new Clipboard(this); + + currentConfig = new Configuration(getResources().getConfiguration()); + + Log.d("AllegroActivity", "before nativeOnCreate"); + if (!nativeOnCreate()) { + finish(); + Log.d("AllegroActivity", "nativeOnCreate failed"); + return; + } + + requestWindowFeature(Window.FEATURE_NO_TITLE); + this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + + Log.d("AllegroActivity", "onCreate end"); + } + + @Override + public void onStart() + { + super.onStart(); + Log.d("AllegroActivity", "onStart"); + + final AllegroActivity activity = this; + displayListener = new DisplayManager.DisplayListener() { + @Override + public void onDisplayAdded(int displayId) {} + @Override + public void onDisplayRemoved(int displayId) {} + @Override + public void onDisplayChanged(int displayId) { + activity.updateOrientation(); + } + }; + DisplayManager displayManager = (DisplayManager) getApplicationContext().getSystemService(getApplicationContext().DISPLAY_SERVICE); + displayManager.registerDisplayListener(displayListener, handler); + + nativeOnOrientationChange(getAllegroOrientation(), true); + + Log.d("AllegroActivity", "onStart end"); + } + + @Override + public void onRestart() + { + super.onRestart(); + Log.d("AllegroActivity", "onRestart."); + } + + @Override + public void onStop() + { + super.onStop(); + Log.d("AllegroActivity", "onStop."); + + DisplayManager displayManager = (DisplayManager) getApplicationContext().getSystemService(getApplicationContext().DISPLAY_SERVICE); + displayManager.unregisterDisplayListener(displayListener); + + // TODO: Should we destroy the surface here? + // onStop is paired with onRestart and onCreate with onDestroy - + // if we destroy the surface here we need to handle onRestart to + // recreate it but we currently do not. + } + + /** Called when the activity is paused. */ + @Override + public void onPause() + { + super.onPause(); + Log.d("AllegroActivity", "onPause"); + + sensors.unlisten(); + + nativeOnPause(); + Log.d("AllegroActivity", "onPause end"); + } + + /** Called when the activity is resumed/unpaused */ + @Override + public void onResume() + { + Log.d("AllegroActivity", "onResume"); + super.onResume(); + + sensors.listen(); + + nativeOnResume(); + + /* This is needed to get joysticks working again */ + reconfigureJoysticks(); + + Log.d("AllegroActivity", "onResume end"); + } + + /** Called when the activity is destroyed */ + @Override + public void onDestroy() + { + super.onDestroy(); + Log.d("AllegroActivity", "onDestroy"); + + nativeOnDestroy(); + Log.d("AllegroActivity", "onDestroy end"); + } + + /** Called when config has changed */ + @Override + public void onConfigurationChanged(Configuration conf) + { + super.onConfigurationChanged(conf); + Log.d("AllegroActivity", "onConfigurationChanged"); + // compare conf.orientation with some saved value + + int changes = currentConfig.diff(conf); + Log.d("AllegroActivity", "changes: " + Integer.toBinaryString(changes)); + + if ((changes & ActivityInfo.CONFIG_FONT_SCALE) != 0) + Log.d("AllegroActivity", "font scale changed"); + + if ((changes & ActivityInfo.CONFIG_MCC) != 0) + Log.d("AllegroActivity", "mcc changed"); + + if ((changes & ActivityInfo.CONFIG_MNC) != 0) + Log.d("AllegroActivity", " changed"); + + if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) + Log.d("AllegroActivity", "locale changed"); + + if ((changes & ActivityInfo.CONFIG_TOUCHSCREEN) != 0) + Log.d("AllegroActivity", "touchscreen changed"); + + if ((changes & ActivityInfo.CONFIG_KEYBOARD) != 0) + Log.d("AllegroActivity", "keyboard changed"); + + if ((changes & ActivityInfo.CONFIG_NAVIGATION) != 0) + Log.d("AllegroActivity", "navigation changed"); + + if ((changes & ActivityInfo.CONFIG_ORIENTATION) != 0) { + Log.d("AllegroActivity", "orientation changed"); + updateOrientation(); + } + + if ((changes & ActivityInfo.CONFIG_SCREEN_LAYOUT) != 0) + Log.d("AllegroActivity", "screen layout changed"); + + if ((changes & ActivityInfo.CONFIG_UI_MODE) != 0) + Log.d("AllegroActivity", "ui mode changed"); + + if (currentConfig.screenLayout != conf.screenLayout) { + Log.d("AllegroActivity", "screenLayout changed!"); + } + + Log.d("AllegroActivity", + "old orientation: " + currentConfig.orientation + + ", new orientation: " + conf.orientation); + + currentConfig = new Configuration(conf); + } + + /** Called when app is frozen **/ + @Override + public void onSaveInstanceState(Bundle state) + { + Log.d("AllegroActivity", "onSaveInstanceState"); + /* do nothing? */ + /* This should get rid of the following warning: + * couldn't save which view has focus because the focused view has no id. + */ + } + + void setAllegroOrientation(int alleg_orientation) + { + setRequestedOrientation(Const.toAndroidOrientation(alleg_orientation)); + } + + int getAllegroOrientation() + { + int rotation; + if (Reflect.methodExists(getWindowManager().getDefaultDisplay(), + "getRotation")) + { + /* 2.2+ */ + rotation = getWindowManager().getDefaultDisplay().getRotation(); + } + else { + rotation = getWindowManager().getDefaultDisplay().getOrientation(); + } + return Const.toAllegroOrientation(rotation); + } + + String getOsVersion() + { + return android.os.Build.VERSION.RELEASE; + } + + private boolean isJoystick(int id) { + InputDevice input = InputDevice.getDevice(id); + int sources = input.getSources(); + if ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK) { + return true; + } + return false; + } + public void reconfigureJoysticks() { + joysticks.clear(); + + int[] all = InputDevice.getDeviceIds(); + + Log.d("AllegroActivity", "Number of input devices: " + all.length); + + for (int i = 0; i < all.length; i++) { + if (isJoystick(all[i])) { + joysticks.add(all[i]); + Log.d("AllegroActivity", "Found joystick. Index=" + (joysticks.size()-1) + " id=" + all[i]); + } + } + + joystickReconfigureNotified = false; + } + + public int getNumJoysticks() { + return joysticks.size(); + } + + public int indexOfJoystick(int id) { + return joysticks.indexOf(id, 0); + } + + public void setJoystickActive() { + joystickActive = true; + } + + public void setJoystickInactive() { + joystickActive = false; + } + + private boolean got_clip = false; + private String clip_text; + private boolean set_clip = false; + private boolean set_clip_result; + + public String getClipboardText() { + got_clip = false; + try { + runOnUiThread(new Runnable() { + @Override public void run() { + clip_text = clipboard.getText(); + got_clip = true; + } + }); + } + catch (Exception e) { + Log.d("AllegroActivity", "getClipboardText failed"); + clip_text = ""; + got_clip = true; + } + while (got_clip == false); + return clip_text; + } + + public boolean hasClipboardText() { + return clipboard.hasText(); + } + + public boolean setClipboardText(String text) { + final String t = text; + set_clip = false; + try { + runOnUiThread(new Runnable() { + @Override public void run() { + set_clip_result = clipboard.setText(t); + set_clip = true; + } + }); + } + catch (Exception e) { + Log.d("AllegroActivity", "setClipboardText failed"); + set_clip_result = false; + set_clip = true; + } + while (set_clip == false); + return set_clip_result; + } + + public void setAllegroFrameless(final boolean on) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + runOnUiThread(new Runnable() { + @Override public void run() { + View view = AllegroActivity.this.getWindow().getDecorView(); + int flags = view.getSystemUiVisibility(); + int bits = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + if (on) flags |= bits; else flags &= ~bits; + view.setSystemUiVisibility(flags); + } + }); + } + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroEGL.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroEGL.java new file mode 100644 index 00000000..0c0b91d2 --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroEGL.java @@ -0,0 +1,309 @@ +package org.liballeg.android; + +import android.content.Context; +import android.util.Log; +import java.util.ArrayList; +import java.util.HashMap; +import javax.microedition.khronos.egl.*; + +class AllegroEGL +{ + private static final String TAG = "AllegroEGL"; + + private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + private static final int EGL_OPENGL_ES_BIT = 1; + private static final int EGL_OPENGL_ES2_BIT = 4; + + private static HashMap<Integer, String> eglErrors; + private static void checkEglError(String prompt, EGL10 egl) { + if (eglErrors == null) { + eglErrors = new HashMap<Integer, String>(); + eglErrors.put(EGL10.EGL_BAD_DISPLAY, "EGL_BAD_DISPLAY"); + eglErrors.put(EGL10.EGL_NOT_INITIALIZED, "EGL_NOT_INITIALIZED"); + eglErrors.put(EGL10.EGL_BAD_SURFACE, "EGL_BAD_SURFACE"); + eglErrors.put(EGL10.EGL_BAD_CONTEXT, "EGL_BAD_CONTEXT"); + eglErrors.put(EGL10.EGL_BAD_MATCH, "EGL_BAD_MATCH"); + eglErrors.put(EGL10.EGL_BAD_ACCESS, "EGL_BAD_ACCESS"); + eglErrors.put(EGL10.EGL_BAD_NATIVE_PIXMAP, "EGL_BAD_NATIVE_PIXMAP"); + eglErrors.put(EGL10.EGL_BAD_NATIVE_WINDOW, "EGL_BAD_NATIVE_WINDOW"); + eglErrors.put(EGL10.EGL_BAD_CURRENT_SURFACE, "EGL_BAD_CURRENT_SURFACE"); + eglErrors.put(EGL10.EGL_BAD_ALLOC, "EGL_BAD_ALLOC"); + eglErrors.put(EGL10.EGL_BAD_CONFIG, "EGL_BAD_CONFIG"); + eglErrors.put(EGL10.EGL_BAD_ATTRIBUTE, "EGL_BAD_ATTRIBUTE"); + eglErrors.put(EGL11.EGL_CONTEXT_LOST, "EGL_CONTEXT_LOST"); + } + + int error; + while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) { + Log.e("Allegro", String.format("%s: EGL error: %s", prompt, + eglErrors.get(error))); + } + } + + /* instance members */ + private EGLContext egl_Context; + private EGLSurface egl_Surface; + private EGLDisplay egl_Display; + private HashMap<Integer, Integer> attribMap; + private EGLConfig[] matchingConfigs; + private EGLConfig chosenConfig; + + boolean egl_Init() + { + Log.d(TAG, "egl_Init"); + EGL10 egl = (EGL10)EGLContext.getEGL(); + + EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + + int[] egl_version = { 0, 0 }; + if (!egl.eglInitialize(dpy, egl_version)) { + Log.d(TAG, "egl_Init fail"); + return false; + } + + egl_Display = dpy; + + Log.d(TAG, "egl_Init OpenGL ES " + egl_version[0] + "." + egl_version[1]); + return true; + } + + void egl_Terminate() + { + egl_makeCurrent(); + + egl_destroySurface(); + egl_destroyContext(); + + EGL10 egl = (EGL10)EGLContext.getEGL(); + egl.eglTerminate(egl_Display); + egl_Display = null; + } + + void egl_initRequiredAttribs() + { + attribMap = new HashMap(); + } + + void egl_setRequiredAttrib(int attr, int value) + { + int egl_attr = eglAttrib(attr); + if (egl_attr >= 0) { + attribMap.put(egl_attr, value); + } + } + + private int eglAttrib(int al_attr) + { + EGL10 egl = (EGL10)EGLContext.getEGL(); + final int[] mapping = attribMapping(egl); + + for (int i = 0; i < mapping.length; i += 2) { + if (al_attr == mapping[i + 1]) + return mapping[i]; + } + + assert(false); + return -1; + } + + private final int[] attribMapping(EGL10 egl) + { + return new int[] { + egl.EGL_RED_SIZE, Const.ALLEGRO_RED_SIZE, + egl.EGL_GREEN_SIZE, Const.ALLEGRO_GREEN_SIZE, + egl.EGL_BLUE_SIZE, Const.ALLEGRO_BLUE_SIZE, + egl.EGL_ALPHA_SIZE, Const.ALLEGRO_ALPHA_SIZE, + egl.EGL_BUFFER_SIZE, Const.ALLEGRO_COLOR_SIZE, + egl.EGL_DEPTH_SIZE, Const.ALLEGRO_DEPTH_SIZE, + egl.EGL_STENCIL_SIZE, Const.ALLEGRO_STENCIL_SIZE, + egl.EGL_SAMPLE_BUFFERS, Const.ALLEGRO_SAMPLE_BUFFERS, + egl.EGL_SAMPLES, Const.ALLEGRO_SAMPLES + }; + } + + int egl_chooseConfig(boolean programmable_pipeline) + { + EGL10 egl = (EGL10)EGLContext.getEGL(); + + if (programmable_pipeline) { + attribMap.put(EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT); + } else { + attribMap.put(EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT); + } + + /* Populate the matchingConfigs array. */ + matchingConfigs = new EGLConfig[20]; + int[] num = new int[1]; + boolean ok = egl.eglChooseConfig(egl_Display, requiredAttribsArray(), + matchingConfigs, matchingConfigs.length, num); + if (!ok || num[0] < 1) { + Log.e(TAG, "No matching config"); + return 0; + } + + Log.d(TAG, "eglChooseConfig returned " + num[0] + " configurations."); + return num[0]; + } + + private int[] requiredAttribsArray() + { + final int n = attribMap.size(); + final int[] arr = new int[n * 2 + 1]; + int i = 0; + + for (int attrib : attribMap.keySet()) { + arr[i++] = attrib; + arr[i++] = attribMap.get(attrib); + } + arr[i] = EGL10.EGL_NONE; /* sentinel */ + return arr; + } + + void egl_getConfigAttribs(int index, int ret[]) + { + Log.d(TAG, "Getting attribs for config at index " + index); + + for (int i = 0; i < ret.length; i++) { + ret[i] = 0; + } + + final EGL10 egl = (EGL10)EGLContext.getEGL(); + final EGLConfig config = matchingConfigs[index]; + final int[] mapping = attribMapping(egl); + final int box[] = new int[1]; + + for (int i = 0; i < mapping.length; i += 2) { + int egl_attr = mapping[i]; + int al_attr = mapping[i + 1]; + + if (egl.eglGetConfigAttrib(egl_Display, config, egl_attr, box)) { + ret[al_attr] = box[0]; + } else { + Log.e(TAG, "eglGetConfigAttrib(" + egl_attr + ") failed\n"); + } + } + } + + /* Return values: + * 0 - failure + * 1 - success + */ + int egl_createContext(int configIndex, boolean programmable_pipeline) + { + Log.d(TAG, "egl_createContext"); + + EGL10 egl = (EGL10)EGLContext.getEGL(); + + chosenConfig = matchingConfigs[configIndex]; + matchingConfigs = null; + attribMap = null; + + int version = (programmable_pipeline) ? 2 : 1; + int[] attribs = { + EGL_CONTEXT_CLIENT_VERSION, version, + EGL10.EGL_NONE + }; + + EGLContext ctx = egl.eglCreateContext(egl_Display, chosenConfig, + EGL10.EGL_NO_CONTEXT, attribs); + if (ctx == EGL10.EGL_NO_CONTEXT) { + checkEglError("eglCreateContext", egl); + Log.d(TAG, "egl_createContext no context"); + return 0; + } + + Log.d(TAG, "EGL context (OpenGL ES " + version + ") created"); + + egl_Context = ctx; + return 1; + } + + private void egl_destroyContext() + { + EGL10 egl = (EGL10)EGLContext.getEGL(); + Log.d(TAG, "destroying egl_Context"); + egl.eglDestroyContext(egl_Display, egl_Context); + egl_Context = EGL10.EGL_NO_CONTEXT; + } + + boolean egl_createSurface(AllegroSurface parent) + { + EGL10 egl = (EGL10)EGLContext.getEGL(); + EGLSurface surface = egl.eglCreateWindowSurface(egl_Display, + chosenConfig, parent, null); + if (surface == EGL10.EGL_NO_SURFACE) { + Log.d(TAG, "egl_createSurface can't create surface: " + + egl.eglGetError()); + return false; + } + + if (!egl.eglMakeCurrent(egl_Display, surface, surface, egl_Context)) { + egl.eglDestroySurface(egl_Display, surface); + Log.d(TAG, "egl_createSurface can't make current"); + return false; + } + + egl_Surface = surface; + + Log.d(TAG, "created new surface: " + surface); + + return true; + } + + private void egl_destroySurface() + { + EGL10 egl = (EGL10)EGLContext.getEGL(); + if (!egl.eglMakeCurrent(egl_Display, EGL10.EGL_NO_SURFACE, + EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)) + { + Log.d(TAG, "could not clear current context"); + } + + Log.d(TAG, "destroying egl_Surface"); + egl.eglDestroySurface(egl_Display, egl_Surface); + egl_Surface = EGL10.EGL_NO_SURFACE; + } + + void egl_clearCurrent() + { + Log.d(TAG, "egl_clearCurrent"); + EGL10 egl = (EGL10)EGLContext.getEGL(); + if (!egl.eglMakeCurrent(egl_Display, EGL10.EGL_NO_SURFACE, + EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)) + { + Log.d(TAG, "could not clear current context"); + } + Log.d(TAG, "egl_clearCurrent done"); + } + + void egl_makeCurrent() + { + EGL10 egl = (EGL10)EGLContext.getEGL(); + if (!egl.eglMakeCurrent(egl_Display, egl_Surface, egl_Surface, egl_Context)) { + // egl.eglDestroySurface(egl_Display, surface); + // egl.eglTerminate(egl_Display); + // egl_Display = null; + Log.d(TAG, "can't make thread current: "); + checkEglError("eglMakeCurrent", egl); + } + } + + void egl_SwapBuffers() + { + try { + EGL10 egl = (EGL10)EGLContext.getEGL(); + + // FIXME: Pretty sure flush is implicit with SwapBuffers + //egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null); + //egl.eglWaitGL(); + + egl.eglSwapBuffers(egl_Display, egl_Surface); + checkEglError("eglSwapBuffers", egl); + + } catch (Exception x) { + Log.d(TAG, "inner exception: " + x.getMessage()); + } + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroInputStream.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroInputStream.java new file mode 100644 index 00000000..397077ee --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroInputStream.java @@ -0,0 +1,77 @@ +package org.liballeg.android; + +import java.io.InputStream; +import android.util.Log; + +public class AllegroInputStream extends InputStream +{ + private static final String TAG = "AllegroInputStream"; + + private long handle; + + public native int nativeRead(long handle, byte[] buffer, int offset, int length); + public native void nativeClose(long handle); + + public AllegroInputStream(long handle) + { + super(); + this.handle = handle; + Log.d(TAG, "ctor handle:" + handle); + } + + @Override + public int available() + { + Log.d(TAG, "available"); + return 0; + } + + @Override + public void close() + { + Log.d(TAG, "close"); + nativeClose(handle); + } + + @Override + public void mark(int limit) + { + Log.d(TAG, "mark " + limit); + } + + @Override + public boolean markSupported() + { + Log.d(TAG, "markSupported"); + return false; + } + + @Override + public int read() + { + byte buffer[] = new byte[1]; + int ret = read(buffer, 0, buffer.length); + if (ret != -1) + return buffer[0]; + else + return -1; + } + + @Override + public int read(byte[] buffer) + { + return read(buffer, 0, buffer.length); + } + + @Override + public int read(byte[] buffer, int offset, int length) + { + Log.d(TAG, "read handle: " + handle + ", offset: " + offset + + ", length: " + length); + int ret = nativeRead(handle, buffer, offset, length); + Log.d(TAG, "read end: ret = " + ret); + return ret; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroJoystick.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroJoystick.java new file mode 100644 index 00000000..d144bfa5 --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroJoystick.java @@ -0,0 +1,86 @@ +package org.liballeg.android; + +import android.view.View.OnGenericMotionListener; +import android.view.MotionEvent; +import android.view.InputDevice; +import android.view.View; + +class AllegroJoystick implements OnGenericMotionListener +{ + private AllegroActivity activity; + private AllegroSurface surface; + + public AllegroJoystick(AllegroActivity activity, AllegroSurface surface) { + this.activity = activity; + this.surface = surface; + } + + private float axis0_x = 0.0f; + private float axis0_y = 0.0f; + private float axis0_hat_x = 0.0f; + private float axis0_hat_y = 0.0f; + private float axis1_x = 0.0f; + private float axis1_y = 0.0f; + + private void handleHat(int index1, float old, float cur, int button1, int button2) { + if (old == cur) + return; + + if (old == 0) { + if (cur < 0) + surface.nativeOnJoystickButton(index1, button1, true); + else + surface.nativeOnJoystickButton(index1, button2, true); + } + else if (old < 0) { + surface.nativeOnJoystickButton(index1, button1, false); + if (cur > 0) { + surface.nativeOnJoystickButton(index1, button2, true); + } + } + else if (old > 0) { + surface.nativeOnJoystickButton(index1, button2, false); + if (cur < 0) { + surface.nativeOnJoystickButton(index1, button1, true); + } + } + } + + @Override + public boolean onGenericMotion(View v, MotionEvent event) { + if (activity.joystickActive == false) { + return false; + } + + int id = event.getDeviceId(); + int index = activity.indexOfJoystick(id); + if (index >= 0) { + float ax = event.getAxisValue(MotionEvent.AXIS_X, 0); + float ay = event.getAxisValue(MotionEvent.AXIS_Y, 0); + float ahx = event.getAxisValue(MotionEvent.AXIS_HAT_X, 0); + float ahy = event.getAxisValue(MotionEvent.AXIS_HAT_Y, 0); + float az = event.getAxisValue(MotionEvent.AXIS_Z, 0); + float arz = event.getAxisValue(MotionEvent.AXIS_RZ, 0); + if (ax != axis0_x || ay != axis0_y) { + surface.nativeOnJoystickAxis(index, 0, 0, ax); + surface.nativeOnJoystickAxis(index, 0, 1, ay); + axis0_x = ax; + axis0_y = ay; + } + else if (ahx != axis0_hat_x || ahy != axis0_hat_y) { + handleHat(index, axis0_hat_x, ahx, AllegroActivity.JS_DPAD_L, AllegroActivity.JS_DPAD_R); + handleHat(index, axis0_hat_y, ahy, AllegroActivity.JS_DPAD_U, AllegroActivity.JS_DPAD_D); + axis0_hat_x = ahx; + axis0_hat_y = ahy; + } + if (az != axis1_x || arz != axis1_y) { + surface.nativeOnJoystickAxis(index, 1, 0, az); + surface.nativeOnJoystickAxis(index, 1, 1, arz); + axis1_x = az; + axis1_y = arz; + } + return true; + } + return false; + } +} diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroSurface.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroSurface.java new file mode 100644 index 00000000..80dd12ff --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroSurface.java @@ -0,0 +1,158 @@ +package org.liballeg.android; + +import android.content.Context; +import android.graphics.Canvas; +import android.util.Log; +import android.view.Display; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; + +class AllegroSurface extends SurfaceView implements SurfaceHolder.Callback +{ + /** native functions we call */ + public native void nativeOnCreate(); + public native boolean nativeOnDestroy(); + public native void nativeOnChange(int format, int width, int height); + public native void nativeOnJoystickAxis(int index, int stick, int axis, float value); + public native void nativeOnJoystickButton(int index, int button, boolean down); + + private AllegroActivity activity; + private AllegroJoystick joystick_listener; + + /** functions that native code calls */ + + boolean egl_Init() + { + return egl.egl_Init(); + } + + void egl_initRequiredAttribs() + { + egl.egl_initRequiredAttribs(); + } + + void egl_setRequiredAttrib(int attr, int value) + { + egl.egl_setRequiredAttrib(attr, value); + } + + int egl_chooseConfig(boolean programmable_pipeline) + { + return egl.egl_chooseConfig(programmable_pipeline); + } + + void egl_getConfigAttribs(int index, int ret[]) + { + egl.egl_getConfigAttribs(index, ret); + } + + int egl_createContext(int configIndex, boolean programmable_pipeline) + { + return egl.egl_createContext(configIndex, programmable_pipeline); + } + + boolean egl_createSurface() + { + return egl.egl_createSurface(this); + } + + void egl_clearCurrent() + { + egl.egl_clearCurrent(); + } + + void egl_makeCurrent() + { + egl.egl_makeCurrent(); + } + + void egl_SwapBuffers() + { + egl.egl_SwapBuffers(); + } + + /** main handlers */ + + private AllegroEGL egl; + private KeyListener key_listener; + private TouchListener touch_listener; + + public AllegroSurface(Context context, Display display, AllegroActivity activity) + { + super(context); + + Log.d("AllegroSurface", "PixelFormat=" + display.getPixelFormat()); + getHolder().setFormat(display.getPixelFormat()); + getHolder().addCallback(this); + + this.activity = activity; + this.egl = new AllegroEGL(); + this.key_listener = new KeyListener(context, activity); + this.touch_listener = new TouchListener(); + } + + private void grabFocus() + { + Log.d("AllegroSurface", "Grabbing focus"); + + setFocusable(true); + setFocusableInTouchMode(true); + requestFocus(); + setOnKeyListener(key_listener); + setOnTouchListener(touch_listener); + + if (android.os.Build.VERSION.SDK_INT >= 12) { + joystick_listener = new AllegroJoystick(activity, this); + setOnGenericMotionListener(joystick_listener); + } + } + + @Override + public void surfaceCreated(SurfaceHolder holder) + { + Log.d("AllegroSurface", "surfaceCreated"); + nativeOnCreate(); + grabFocus(); + Log.d("AllegroSurface", "surfaceCreated end"); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) + { + Log.d("AllegroSurface", "surfaceDestroyed"); + + if (!nativeOnDestroy()) { + Log.d("AllegroSurface", "No surface created, returning early"); + return; + } + + egl.egl_Terminate(); + + Log.d("AllegroSurface", "surfaceDestroyed end"); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) + { + Log.d("AllegroSurface", "surfaceChanged (width=" + width + " height=" + height + ")"); + nativeOnChange(0xdeadbeef, width, height); + Log.d("AllegroSurface", "surfaceChanged end"); + } + + /* unused */ + @Override + public void onDraw(Canvas canvas) + { + } + + /* Events */ + + /* XXX not exposed in C API yet */ + void setCaptureVolumeKeys(boolean onoff) + { + key_listener.setCaptureVolumeKeys(onoff); + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Clipboard.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Clipboard.java new file mode 100644 index 00000000..69da0dfa --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Clipboard.java @@ -0,0 +1,88 @@ +package org.liballeg.android; + +import android.app.Activity; + +import android.content.Context; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.util.Log; + + +class Clipboard +{ + private static final String TAG = "Clipboard"; + + private Activity activity; + private boolean clip_thread_done = false; + private String clipdata; + + Clipboard(Activity activity) + { + this.activity = activity; + } + + public boolean setText(String text) + { + final String ss = text; + + Runnable runnable = new Runnable() { + public void run() { + ClipboardManager clipboard = (ClipboardManager) + activity.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("allegro", ss); + clipboard.setPrimaryClip(clip); + clip_thread_done = true; + }; + }; + + activity.runOnUiThread(runnable); + + while (!clip_thread_done) + ; + clip_thread_done = false; + + return true; + } + + public String getText() + { + Runnable runnable = new Runnable() { + public void run() { + ClipboardManager clipboard = (ClipboardManager) + activity.getSystemService(Context.CLIPBOARD_SERVICE); + + ClipData clip = clipboard.getPrimaryClip(); + + if (clip == null) { + clipdata = null; + } else { + ClipData.Item item = clip.getItemAt(0); + + if (item == null) { + clipdata = null; + } else { + String text = item.coerceToText(activity.getApplicationContext()).toString(); + clipdata = text; + } + } + clip_thread_done = true; + } + }; + + activity.runOnUiThread(runnable); + + while (!clip_thread_done); + clip_thread_done = false; + + return clipdata; + } + + + boolean hasText() + { + /* Lazy implementation... */ + return this.getText() != null; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Const.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Const.java new file mode 100644 index 00000000..784d8e62 --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Const.java @@ -0,0 +1,100 @@ +package org.liballeg.android; + +import android.content.pm.ActivityInfo; +import android.view.Surface; + +final class Const +{ + /* color.h */ + static final int ALLEGRO_PIXEL_FORMAT_ABGR_8888 = 17; + static final int ALLEGRO_PIXEL_FORMAT_BGR_565 = 20; + static final int ALLEGRO_PIXEL_FORMAT_RGBA_4444 = 26; + static final int ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 = 27; + + /* display.h */ + static final int ALLEGRO_RED_SIZE = 0; + static final int ALLEGRO_GREEN_SIZE = 1; + static final int ALLEGRO_BLUE_SIZE = 2; + static final int ALLEGRO_ALPHA_SIZE = 3; + static final int ALLEGRO_COLOR_SIZE = 14; + static final int ALLEGRO_DEPTH_SIZE = 15; + static final int ALLEGRO_STENCIL_SIZE = 16; + static final int ALLEGRO_SAMPLE_BUFFERS = 17; + static final int ALLEGRO_SAMPLES = 18; + + static final int ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN = 0; + static final int ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES = 1; + static final int ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES = 2; + static final int ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES = 4; + static final int ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES = 8; + static final int ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT = 5; + static final int ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE = 10; + static final int ALLEGRO_DISPLAY_ORIENTATION_ALL = 15; + static final int ALLEGRO_DISPLAY_ORIENTATION_FACE_UP = 16; + static final int ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN = 32; + + /* events.h */ + static final int ALLEGRO_EVENT_TOUCH_BEGIN = 50; + static final int ALLEGRO_EVENT_TOUCH_END = 51; + static final int ALLEGRO_EVENT_TOUCH_MOVE = 52; + static final int ALLEGRO_EVENT_TOUCH_CANCEL = 53; + + static int toAndroidOrientation(int alleg_orientation) + { + switch (alleg_orientation) + { + case ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES: + return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + + case ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES: + return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + + case ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES: + return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + + case ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES: + return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + + case ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT: + return ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + + case ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE: + return ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + + case ALLEGRO_DISPLAY_ORIENTATION_ALL: + return ActivityInfo.SCREEN_ORIENTATION_SENSOR; + } + + return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; + } + + static int toAllegroOrientation(int rotation) + { + switch (rotation) { + case Surface.ROTATION_0: + return ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES; + + case Surface.ROTATION_180: + return ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES; + + /* Android device orientations are the opposite of Allegro ones. + * Allegro orientations are the orientation of the device, with 0 + * being holding the device at normal orientation, 90 with the device + * rotated 90 degrees clockwise and so on. Android orientations are + * the orientations of the GRAPHICS. By rotating the device by 90 + * degrees clockwise, the graphics are actually rotated 270 degrees, + * and that's what Android uses. + */ + + case Surface.ROTATION_90: + return ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES; + + case Surface.ROTATION_270: + return ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES; + } + + return ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ImageLoader.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ImageLoader.java new file mode 100644 index 00000000..b53f6319 --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ImageLoader.java @@ -0,0 +1,103 @@ +package org.liballeg.android; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Log; +import java.io.InputStream; + +class ImageLoader +{ + private static final String TAG = "ImageLoader"; + + static Bitmap decodeBitmapAsset(Activity activity, final String filename) + { + Bitmap decodedBitmap; + Log.d(TAG, "decodeBitmapAsset begin"); + try { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + // Only added in API level 19, avoid for now. + // options.inPremultiplied = premul; + InputStream is = activity.getResources().getAssets().open( + Path.simplifyPath(filename)); + decodedBitmap = BitmapFactory.decodeStream(is, null, options); + is.close(); + Log.d(TAG, "done waiting for decodeStream"); + } catch (Exception ex) { + Log.e(TAG, + "decodeBitmapAsset exception: " + ex.getMessage()); + decodedBitmap = null; + } + Log.d(TAG, "decodeBitmapAsset end"); + return decodedBitmap; + } + + static Bitmap decodeBitmapStream(final InputStream is) + { + Bitmap decodedBitmap; + Log.d(TAG, "decodeBitmapStream begin"); + try { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + // Only added in API level 19, avoid for now. + // options.inPremultiplied = premul; + decodedBitmap = BitmapFactory.decodeStream(is, null, options); + Log.d(TAG, "done waiting for decodeStream"); + } catch (Exception ex) { + Log.e(TAG, "decodeBitmapStream exception: " + + ex.getMessage()); + decodedBitmap = null; + } + Log.d(TAG, "decodeBitmapStream end"); + return decodedBitmap; + } + + /* Unused yet */ + /* + static Bitmap decodeBitmapByteArray(byte[] array) + { + Bitmap decodedBitmap; + Log.d(TAG, "decodeBitmapByteArray"); + try { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + Bitmap bmp = BitmapFactory.decodeByteArray(array, 0, array.length, options); + return bmp; + } + catch (Exception ex) { + Log.e(TAG, "decodeBitmapByteArray exception: " + + ex.getMessage()); + } + return null; + } + */ + + static int getBitmapFormat(Bitmap bitmap) + { + switch (bitmap.getConfig()) { + case ALPHA_8: + return Const.ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8; // not really + case ARGB_4444: + return Const.ALLEGRO_PIXEL_FORMAT_RGBA_4444; + case ARGB_8888: + return Const.ALLEGRO_PIXEL_FORMAT_ABGR_8888; + case RGB_565: + return Const.ALLEGRO_PIXEL_FORMAT_BGR_565; // untested + default: + assert(false); + return -1; + } + } + + static int[] getPixels(Bitmap bmp) + { + int width = bmp.getWidth(); + int height = bmp.getHeight(); + int[] pixels = new int[width * height]; + bmp.getPixels(pixels, 0, width, 0, 0, width, height); + return pixels; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Key.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Key.java new file mode 100644 index 00000000..ac45b22f --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Key.java @@ -0,0 +1,436 @@ +package org.liballeg.android; + +final class Key +{ + /* keycodes.h */ + static final int ALLEGRO_KEY_A = 1; + static final int ALLEGRO_KEY_B = 2; + static final int ALLEGRO_KEY_C = 3; + static final int ALLEGRO_KEY_D = 4; + static final int ALLEGRO_KEY_E = 5; + static final int ALLEGRO_KEY_F = 6; + static final int ALLEGRO_KEY_G = 7; + static final int ALLEGRO_KEY_H = 8; + static final int ALLEGRO_KEY_I = 9; + static final int ALLEGRO_KEY_J = 10; + static final int ALLEGRO_KEY_K = 11; + static final int ALLEGRO_KEY_L = 12; + static final int ALLEGRO_KEY_M = 13; + static final int ALLEGRO_KEY_N = 14; + static final int ALLEGRO_KEY_O = 15; + static final int ALLEGRO_KEY_P = 16; + static final int ALLEGRO_KEY_Q = 17; + static final int ALLEGRO_KEY_R = 18; + static final int ALLEGRO_KEY_S = 19; + static final int ALLEGRO_KEY_T = 20; + static final int ALLEGRO_KEY_U = 21; + static final int ALLEGRO_KEY_V = 22; + static final int ALLEGRO_KEY_W = 23; + static final int ALLEGRO_KEY_X = 24; + static final int ALLEGRO_KEY_Y = 25; + static final int ALLEGRO_KEY_Z = 26; + + static final int ALLEGRO_KEY_0 = 27; + static final int ALLEGRO_KEY_1 = 28; + static final int ALLEGRO_KEY_2 = 29; + static final int ALLEGRO_KEY_3 = 30; + static final int ALLEGRO_KEY_4 = 31; + static final int ALLEGRO_KEY_5 = 32; + static final int ALLEGRO_KEY_6 = 33; + static final int ALLEGRO_KEY_7 = 34; + static final int ALLEGRO_KEY_8 = 35; + static final int ALLEGRO_KEY_9 = 36; + + static final int ALLEGRO_KEY_PAD_0 = 37; + static final int ALLEGRO_KEY_PAD_1 = 38; + static final int ALLEGRO_KEY_PAD_2 = 39; + static final int ALLEGRO_KEY_PAD_3 = 40; + static final int ALLEGRO_KEY_PAD_4 = 41; + static final int ALLEGRO_KEY_PAD_5 = 42; + static final int ALLEGRO_KEY_PAD_6 = 43; + static final int ALLEGRO_KEY_PAD_7 = 44; + static final int ALLEGRO_KEY_PAD_8 = 45; + static final int ALLEGRO_KEY_PAD_9 = 46; + + static final int ALLEGRO_KEY_F1 = 47; + static final int ALLEGRO_KEY_F2 = 48; + static final int ALLEGRO_KEY_F3 = 49; + static final int ALLEGRO_KEY_F4 = 50; + static final int ALLEGRO_KEY_F5 = 51; + static final int ALLEGRO_KEY_F6 = 52; + static final int ALLEGRO_KEY_F7 = 53; + static final int ALLEGRO_KEY_F8 = 54; + static final int ALLEGRO_KEY_F9 = 55; + static final int ALLEGRO_KEY_F10 = 56; + static final int ALLEGRO_KEY_F11 = 57; + static final int ALLEGRO_KEY_F12 = 58; + + static final int ALLEGRO_KEY_ESCAPE = 59; + static final int ALLEGRO_KEY_TILDE = 60; + static final int ALLEGRO_KEY_MINUS = 61; + static final int ALLEGRO_KEY_EQUALS = 62; + static final int ALLEGRO_KEY_BACKSPACE = 63; + static final int ALLEGRO_KEY_TAB = 64; + static final int ALLEGRO_KEY_OPENBRACE = 65; + static final int ALLEGRO_KEY_CLOSEBRACE = 66; + static final int ALLEGRO_KEY_ENTER = 67; + static final int ALLEGRO_KEY_SEMICOLON = 68; + static final int ALLEGRO_KEY_QUOTE = 69; + static final int ALLEGRO_KEY_BACKSLASH = 70; + static final int ALLEGRO_KEY_BACKSLASH2 = 71; /* DirectInput calls this DIK_OEM_102: "< > | on UK/Germany keyboards" */ + static final int ALLEGRO_KEY_COMMA = 72; + static final int ALLEGRO_KEY_FULLSTOP = 73; + static final int ALLEGRO_KEY_SLASH = 74; + static final int ALLEGRO_KEY_SPACE = 75; + + static final int ALLEGRO_KEY_INSERT = 76; + static final int ALLEGRO_KEY_DELETE = 77; + static final int ALLEGRO_KEY_HOME = 78; + static final int ALLEGRO_KEY_END = 79; + static final int ALLEGRO_KEY_PGUP = 80; + static final int ALLEGRO_KEY_PGDN = 81; + static final int ALLEGRO_KEY_LEFT = 82; + static final int ALLEGRO_KEY_RIGHT = 83; + static final int ALLEGRO_KEY_UP = 84; + static final int ALLEGRO_KEY_DOWN = 85; + + static final int ALLEGRO_KEY_PAD_SLASH = 86; + static final int ALLEGRO_KEY_PAD_ASTERISK= 87; + static final int ALLEGRO_KEY_PAD_MINUS = 88; + static final int ALLEGRO_KEY_PAD_PLUS = 89; + static final int ALLEGRO_KEY_PAD_DELETE = 90; + static final int ALLEGRO_KEY_PAD_ENTER = 91; + + static final int ALLEGRO_KEY_PRINTSCREEN = 92; + static final int ALLEGRO_KEY_PAUSE = 93; + + static final int ALLEGRO_KEY_ABNT_C1 = 94; + static final int ALLEGRO_KEY_YEN = 95; + static final int ALLEGRO_KEY_KANA = 96; + static final int ALLEGRO_KEY_CONVERT = 97; + static final int ALLEGRO_KEY_NOCONVERT = 98; + static final int ALLEGRO_KEY_AT = 99; + static final int ALLEGRO_KEY_CIRCUMFLEX = 100; + static final int ALLEGRO_KEY_COLON2 = 101; + static final int ALLEGRO_KEY_KANJI = 102; + + static final int ALLEGRO_KEY_PAD_EQUALS = 103; /* MacOS X */ + static final int ALLEGRO_KEY_BACKQUOTE = 104; /* MacOS X */ + static final int ALLEGRO_KEY_SEMICOLON2 = 105; /* MacOS X -- TODO: ask lillo what this should be */ + static final int ALLEGRO_KEY_COMMAND = 106; /* MacOS X */ + static final int ALLEGRO_KEY_BACK = 107; + static final int ALLEGRO_KEY_VOLUME_UP = 108; + static final int ALLEGRO_KEY_VOLUME_DOWN = 109; + + /* Some more standard Android keys. + * These happen to be the ones used by the Xperia Play. + */ + static final int ALLEGRO_KEY_SEARCH = 110; + static final int ALLEGRO_KEY_DPAD_CENTER = 111; + static final int ALLEGRO_KEY_BUTTON_X = 112; + static final int ALLEGRO_KEY_BUTTON_Y = 113; + static final int ALLEGRO_KEY_DPAD_UP = 114; + static final int ALLEGRO_KEY_DPAD_DOWN = 115; + static final int ALLEGRO_KEY_DPAD_LEFT = 116; + static final int ALLEGRO_KEY_DPAD_RIGHT = 117; + static final int ALLEGRO_KEY_SELECT = 118; + static final int ALLEGRO_KEY_START = 119; + static final int ALLEGRO_KEY_BUTTON_L1 = 120; + static final int ALLEGRO_KEY_BUTTON_R1 = 121; + static final int ALLEGRO_KEY_BUTTON_L2 = 122; + static final int ALLEGRO_KEY_BUTTON_R2 = 123; + static final int ALLEGRO_KEY_BUTTON_A = 124; + static final int ALLEGRO_KEY_BUTTON_B = 125; + static final int ALLEGRO_KEY_THUMBL = 126; + static final int ALLEGRO_KEY_THUMBR = 127; + + static final int ALLEGRO_KEY_UNKNOWN = 128; + + /* All codes up to before ALLEGRO_KEY_MODIFIERS can be freely + * assigned as additional unknown keys, like various multimedia + * and application keys keyboards may have. + */ + + static final int ALLEGRO_KEY_MODIFIERS = 215; + + static final int ALLEGRO_KEY_LSHIFT = 215; + static final int ALLEGRO_KEY_RSHIFT = 216; + static final int ALLEGRO_KEY_LCTRL = 217; + static final int ALLEGRO_KEY_RCTRL = 218; + static final int ALLEGRO_KEY_ALT = 219; + static final int ALLEGRO_KEY_ALTGR = 220; + static final int ALLEGRO_KEY_LWIN = 221; + static final int ALLEGRO_KEY_RWIN = 222; + static final int ALLEGRO_KEY_MENU = 223; + static final int ALLEGRO_KEY_SCROLLLOCK = 224; + static final int ALLEGRO_KEY_NUMLOCK = 225; + static final int ALLEGRO_KEY_CAPSLOCK = 226; + + static final int ALLEGRO_KEY_MAX = 227; + + protected static int[] keyMap = { + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_UNKNOWN + ALLEGRO_KEY_LEFT, // KeyEvent.KEYCODE_SOFT_LEFT + ALLEGRO_KEY_RIGHT, // KeyEvent.KEYCODE_SOFT_RIGHT + ALLEGRO_KEY_HOME, // KeyEvent.KEYCODE_HOME + ALLEGRO_KEY_BACK, // KeyEvent.KEYCODE_BACK + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_CALL + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ENDCALL + ALLEGRO_KEY_0, // KeyEvent.KEYCODE_0 + ALLEGRO_KEY_1, // KeyEvent.KEYCODE_1 + ALLEGRO_KEY_2, // KeyEvent.KEYCODE_2 + ALLEGRO_KEY_3, // KeyEvent.KEYCODE_3 + ALLEGRO_KEY_4, // KeyEvent.KEYCODE_4 + ALLEGRO_KEY_5, // KeyEvent.KEYCODE_5 + ALLEGRO_KEY_6, // KeyEvent.KEYCODE_6 + ALLEGRO_KEY_7, // KeyEvent.KEYCODE_7 + ALLEGRO_KEY_8, // KeyEvent.KEYCODE_8 + ALLEGRO_KEY_9, // KeyEvent.KEYCODE_9 + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_STAR + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_POUND + ALLEGRO_KEY_UP, // KeyEvent.KEYCODE_DPAD_UP + ALLEGRO_KEY_DOWN, // KeyEvent.KEYCODE_DPAD_DOWN + ALLEGRO_KEY_LEFT, // KeyEvent.KEYCODE_DPAD_LEFT + ALLEGRO_KEY_RIGHT, // KeyEvent.KEYCODE_DPAD_RIGHT + ALLEGRO_KEY_ENTER, // KeyEvent.KEYCODE_DPAD_CENTER + ALLEGRO_KEY_VOLUME_UP, // KeyEvent.KEYCODE_VOLUME_UP + ALLEGRO_KEY_VOLUME_DOWN, // KeyEvent.KEYCODE_VOLUME_DOWN + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_POWER + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_CAMERA + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_CLEAR + ALLEGRO_KEY_A, // KeyEvent.KEYCODE_A + ALLEGRO_KEY_B, // KeyEvent.KEYCODE_B + ALLEGRO_KEY_C, // KeyEvent.KEYCODE_B + ALLEGRO_KEY_D, // KeyEvent.KEYCODE_D + ALLEGRO_KEY_E, // KeyEvent.KEYCODE_E + ALLEGRO_KEY_F, // KeyEvent.KEYCODE_F + ALLEGRO_KEY_G, // KeyEvent.KEYCODE_G + ALLEGRO_KEY_H, // KeyEvent.KEYCODE_H + ALLEGRO_KEY_I, // KeyEvent.KEYCODE_I + ALLEGRO_KEY_J, // KeyEvent.KEYCODE_J + ALLEGRO_KEY_K, // KeyEvent.KEYCODE_K + ALLEGRO_KEY_L, // KeyEvent.KEYCODE_L + ALLEGRO_KEY_M, // KeyEvent.KEYCODE_M + ALLEGRO_KEY_N, // KeyEvent.KEYCODE_N + ALLEGRO_KEY_O, // KeyEvent.KEYCODE_O + ALLEGRO_KEY_P, // KeyEvent.KEYCODE_P + ALLEGRO_KEY_Q, // KeyEvent.KEYCODE_Q + ALLEGRO_KEY_R, // KeyEvent.KEYCODE_R + ALLEGRO_KEY_S, // KeyEvent.KEYCODE_S + ALLEGRO_KEY_T, // KeyEvent.KEYCODE_T + ALLEGRO_KEY_U, // KeyEvent.KEYCODE_U + ALLEGRO_KEY_V, // KeyEvent.KEYCODE_V + ALLEGRO_KEY_W, // KeyEvent.KEYCODE_W + ALLEGRO_KEY_X, // KeyEvent.KEYCODE_X + ALLEGRO_KEY_Y, // KeyEvent.KEYCODE_Y + ALLEGRO_KEY_Z, // KeyEvent.KEYCODE_Z + ALLEGRO_KEY_COMMA, // KeyEvent.KEYCODE_COMMA + ALLEGRO_KEY_FULLSTOP, // KeyEvent.KEYCODE_PERIOD + ALLEGRO_KEY_ALT, // KeyEvent.KEYCODE_ALT_LEFT + ALLEGRO_KEY_ALTGR, // KeyEvent.KEYCODE_ALT_RIGHT + ALLEGRO_KEY_LSHIFT, // KeyEvent.KEYCODE_SHIFT_LEFT + ALLEGRO_KEY_RSHIFT, // KeyEvent.KEYCODE_SHIFT_RIGHT + ALLEGRO_KEY_TAB, // KeyEvent.KEYCODE_TAB + ALLEGRO_KEY_SPACE, // KeyEvent.KEYCODE_SPACE + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_SYM + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_EXPLORER + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ENVELOPE + ALLEGRO_KEY_ENTER, // KeyEvent.KEYCODE_ENTER + ALLEGRO_KEY_BACKSPACE, // KeyEvent.KEYCODE_DEL + ALLEGRO_KEY_TILDE, // KeyEvent.KEYCODE_GRAVE + ALLEGRO_KEY_MINUS, // KeyEvent.KEYCODE_MINUS + ALLEGRO_KEY_EQUALS, // KeyEvent.KEYCODE_EQUALS + ALLEGRO_KEY_OPENBRACE, // KeyEvent.KEYCODE_LEFT_BRACKET + ALLEGRO_KEY_CLOSEBRACE, // KeyEvent.KEYCODE_RIGHT_BRACKET + ALLEGRO_KEY_BACKSLASH, // KeyEvent.KEYCODE_BACKSLASH + ALLEGRO_KEY_SEMICOLON, // KeyEvent.KEYCODE_SEMICOLON + ALLEGRO_KEY_QUOTE, // KeyEvent.KEYCODE_APOSTROPHY + ALLEGRO_KEY_SLASH, // KeyEvent.KEYCODE_SLASH + ALLEGRO_KEY_AT, // KeyEvent.KEYCODE_AT + ALLEGRO_KEY_NUMLOCK, // KeyEvent.KEYCODE_NUM + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_HEADSETHOOK + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_FOCUS + ALLEGRO_KEY_PAD_PLUS, // KeyEvent.KEYCODE_PLUS + ALLEGRO_KEY_MENU, // KeyEvent.KEYCODE_MENU + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_NOTIFICATION + ALLEGRO_KEY_SEARCH, // KeyEvent.KEYCODE_SEARCH + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_MEDIA_STOP + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_MEDIA_NEXT + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_MEDIA_PREVIOUS + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_MEDIA_REWIND + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_MEDIA_FAST_FORWARD + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_MUTE + ALLEGRO_KEY_PGUP, // KeyEvent.KEYCODE_PAGE_UP + ALLEGRO_KEY_PGDN, // KeyEvent.KEYCODE_PAGE_DOWN + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_PICTSYMBOLS + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_SWITCH_CHARSET + ALLEGRO_KEY_BUTTON_A, // KeyEvent.KEYCODE_BUTTON_A + ALLEGRO_KEY_BUTTON_B, // KeyEvent.KEYCODE_BUTTON_B + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_BUTTON_C + ALLEGRO_KEY_BUTTON_X, // KeyEvent.KEYCODE_BUTTON_X + ALLEGRO_KEY_BUTTON_Y, // KeyEvent.KEYCODE_BUTTON_Y + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_BUTTON_Z + ALLEGRO_KEY_BUTTON_L1, // KeyEvent.KEYCODE_BUTTON_L1 + ALLEGRO_KEY_BUTTON_R1, // KeyEvent.KEYCODE_BUTTON_R1 + ALLEGRO_KEY_BUTTON_L2, // KeyEvent.KEYCODE_BUTTON_L2 + ALLEGRO_KEY_BUTTON_R2, // KeyEvent.KEYCODE_BUTTON_R2 + ALLEGRO_KEY_THUMBL, // KeyEvent.KEYCODE_THUMBL + ALLEGRO_KEY_THUMBR, // KeyEvent.KEYCODE_THUMBR + ALLEGRO_KEY_START, // KeyEvent.KEYCODE_START + ALLEGRO_KEY_SELECT, // KeyEvent.KEYCODE_SELECT + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_MODE + ALLEGRO_KEY_ESCAPE, // KeyEvent.KEYCODE_ESCAPE (111) + ALLEGRO_KEY_DELETE, // KeyEvent.KEYCODE_FORWARD_DELETE (112) + ALLEGRO_KEY_LCTRL, // KeyEvent.KEYCODE_CTRL_LEFT (113) + ALLEGRO_KEY_RCTRL, // KeyEvent.KEYCODE_CONTROL_RIGHT (114) + ALLEGRO_KEY_CAPSLOCK, // KeyEvent.KEYCODE_CAPS_LOCK (115) + ALLEGRO_KEY_SCROLLLOCK, // KeyEvent.KEYCODE_SCROLL_LOCK (116) + ALLEGRO_KEY_LWIN, // KeyEvent.KEYCODE_META_LEFT (117) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (118) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (119) + ALLEGRO_KEY_PRINTSCREEN, // KeyEvent.KEYCODE_SYSRQ (120) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (121) + ALLEGRO_KEY_HOME, // KeyEvent.KEYCODE_MOVE_HOME (122) + ALLEGRO_KEY_END, // KeyEvent.KEYCODE_MOVE_END (123) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (124) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (125) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (126) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (127) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (128) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (129) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (130) + ALLEGRO_KEY_F1, // KeyEvent.KEYCODE_ (131) + ALLEGRO_KEY_F2, // KeyEvent.KEYCODE_ (132) + ALLEGRO_KEY_F3, // KeyEvent.KEYCODE_ (133) + ALLEGRO_KEY_F4, // KeyEvent.KEYCODE_ (134) + ALLEGRO_KEY_F5, // KeyEvent.KEYCODE_ (135) + ALLEGRO_KEY_F6, // KeyEvent.KEYCODE_ (136) + ALLEGRO_KEY_F7, // KeyEvent.KEYCODE_ (137) + ALLEGRO_KEY_F8, // KeyEvent.KEYCODE_ (138) + ALLEGRO_KEY_F9, // KeyEvent.KEYCODE_ (139) + ALLEGRO_KEY_F10, // KeyEvent.KEYCODE_ (140) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (141) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (142) + ALLEGRO_KEY_NUMLOCK, // KeyEvent.KEYCODE_NUM_LOCK (143) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (144) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (145) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (146) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (147) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (148) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (149) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (150) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (151) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (152) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (153) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (154) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (155) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (156) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (157) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (158) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (159) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (160) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (161) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (162) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (163) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (164) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (165) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (166) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (167) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (168) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (169) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (170) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (171) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (172) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (173) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (174) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (175) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (176) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (177) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (178) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (179) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (180) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (181) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (182) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (183) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (184) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (185) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (186) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (187) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (188) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (189) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (190) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (191) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (192) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (193) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (194) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (195) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (196) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (197) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (198) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (199) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (200) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (201) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (202) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (203) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (204) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (205) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (206) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (207) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (208) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (209) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (210) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (211) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (212) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (213) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (214) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (215) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (216) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (217) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (218) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (219) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (220) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (221) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (222) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (223) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (224) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (225) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (226) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (227) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (228) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (229) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (230) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (231) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (232) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (233) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (234) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (235) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (236) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (237) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (238) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (239) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (240) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (241) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (242) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (243) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (244) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (245) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (246) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (247) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (248) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (249) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (250) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (251) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (252) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (253) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (254) + ALLEGRO_KEY_UNKNOWN, // KeyEvent.KEYCODE_ (255) + }; + + /* Return Allegro key code for Android key code. */ + static int alKey(int keyCode) { + return keyMap[keyCode]; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/KeyListener.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/KeyListener.java new file mode 100644 index 00000000..b832d35a --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/KeyListener.java @@ -0,0 +1,177 @@ +package org.liballeg.android; + +import android.media.AudioManager; +import android.content.Context; +import android.view.KeyEvent; +import android.view.View; + +class KeyListener implements View.OnKeyListener +{ + private Context context; + private boolean captureVolume = false; + private AllegroActivity activity; + + native void nativeOnKeyDown(int key); + native void nativeOnKeyUp(int key); + native void nativeOnKeyChar(int key, int unichar); + native void nativeOnJoystickButton(int index, int button, boolean down); + + KeyListener(Context context, AllegroActivity activity) + { + this.context = context; + this.activity = activity; + } + + void setCaptureVolumeKeys(boolean onoff) + { + captureVolume = onoff; + } + + public boolean onKeyboardKey(View v, int keyCode, KeyEvent event) + { + int unichar; + + if (event.getAction() == KeyEvent.ACTION_DOWN) { + if (!captureVolume) { + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { + volumeChange(1); + return true; + } + else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + volumeChange(-1); + return true; + } + } + if (Key.alKey(keyCode) == Key.ALLEGRO_KEY_BACKSPACE) { + unichar = '\b'; + } + else if (Key.alKey(keyCode) == Key.ALLEGRO_KEY_ENTER) { + unichar = '\r'; + } + else { + unichar = event.getUnicodeChar(); + } + + if (event.getRepeatCount() == 0) { + nativeOnKeyDown(Key.alKey(keyCode)); + nativeOnKeyChar(Key.alKey(keyCode), unichar); + } + else { + nativeOnKeyChar(Key.alKey(keyCode), unichar); + } + return true; + } + else if (event.getAction() == KeyEvent.ACTION_UP) { + nativeOnKeyUp(Key.alKey(keyCode)); + return true; + } + + return false; + } + + private int getCode(int keyCode, KeyEvent event, int index1) { + int code = -1; + if (keyCode == KeyEvent.KEYCODE_BUTTON_A) { + code = AllegroActivity.JS_A; + } + else if (keyCode == KeyEvent.KEYCODE_BUTTON_B) { + code = AllegroActivity.JS_B; + } + else if (keyCode == KeyEvent.KEYCODE_BUTTON_X) { + code = AllegroActivity.JS_X; + } + else if (keyCode == KeyEvent.KEYCODE_BUTTON_Y) { + code = AllegroActivity.JS_Y; + } + else if (keyCode == KeyEvent.KEYCODE_BUTTON_L1) { + code = AllegroActivity.JS_L1; + } + else if (keyCode == KeyEvent.KEYCODE_BUTTON_R1) { + code = AllegroActivity.JS_R1; + } + else if (keyCode == KeyEvent.KEYCODE_MENU) { + code = AllegroActivity.JS_MENU; + } + else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { + if (event.getAction() == KeyEvent.ACTION_DOWN) + nativeOnJoystickButton(index1, AllegroActivity.JS_DPAD_L, true); + else + nativeOnJoystickButton(index1, AllegroActivity.JS_DPAD_L, false); + return -2; + } + else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { + if (event.getAction() == KeyEvent.ACTION_DOWN) + nativeOnJoystickButton(index1, AllegroActivity.JS_DPAD_R, true); + else + nativeOnJoystickButton(index1, AllegroActivity.JS_DPAD_R, false); + return -2; + } + else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { + if (event.getAction() == KeyEvent.ACTION_DOWN) + nativeOnJoystickButton(index1, AllegroActivity.JS_DPAD_U, true); + else + nativeOnJoystickButton(index1, AllegroActivity.JS_DPAD_U, false); + return -2; + } + else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { + if (event.getAction() == KeyEvent.ACTION_DOWN) + nativeOnJoystickButton(index1, AllegroActivity.JS_DPAD_D, true); + else + nativeOnJoystickButton(index1, AllegroActivity.JS_DPAD_D, false); + return -2; + } + return code; + } + + public boolean onKey(View v, int keyCode, KeyEvent event) { + /* We want media player controls to keep working in background apps */ + if (keyCode == KeyEvent.KEYCODE_MEDIA_REWIND || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) { + return false; + } + + if (activity.joystickActive == false) { + return onKeyboardKey(v, keyCode, event); + } + + int id = event.getDeviceId(); + int index = activity.indexOfJoystick(id); + int code = -1; + if (index >= 0) { + code = getCode(keyCode, event, index); + } + if (code == -1) { + return onKeyboardKey(v, keyCode, event); + } + else if (code == -2) { + return true; + } + if (event.getAction() == KeyEvent.ACTION_DOWN) { + if (event.getRepeatCount() == 0) { + nativeOnJoystickButton(index, code, true); + } + } + else { + nativeOnJoystickButton(index, code, false); + } + return true; + } + + private void volumeChange(int inc) + { + AudioManager mAudioManager = + (AudioManager)this.context.getApplicationContext() + .getSystemService(Context.AUDIO_SERVICE); + + int curr = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); + int max = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + int vol = curr + inc; + + if (0 <= vol && vol <= max) { + // Set a new volume level manually with the FLAG_SHOW_UI flag. + mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, vol, + AudioManager.FLAG_SHOW_UI); + } + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Path.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Path.java new file mode 100644 index 00000000..5aaa320c --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Path.java @@ -0,0 +1,29 @@ +package org.liballeg.android; + +import android.text.TextUtils; +import java.util.ArrayList; + +final class Path +{ + // AssetManager does not interpret the path(!) so we do it here. + static String simplifyPath(final String path) + { + final String[] pieces = path.split("/"); + ArrayList<String> keep = new ArrayList<String>(); + for (String piece : pieces) { + if (piece.equals("")) + continue; + if (piece.equals(".")) + continue; + if (piece.equals("..")) { + if (keep.size() > 0) + keep.remove(keep.size() - 1); + continue; + } + keep.add(piece); + } + return TextUtils.join("/", keep); + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Reflect.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Reflect.java new file mode 100644 index 00000000..30745acb --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Reflect.java @@ -0,0 +1,92 @@ +package org.liballeg.android; + +import android.util.Log; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +final class Reflect +{ + static final String TAG = "Reflect"; + + static boolean fieldExists(Object obj, String fieldName) + { + try { + Class cls = obj.getClass(); + Field m = cls.getField(fieldName); + return true; + } catch (Exception x) { + return false; + } + } + + static boolean methodExists(Object obj, String methName) + { + try { + Class cls = obj.getClass(); + Method m = cls.getMethod(methName); + return true; + } catch (Exception x) { + return false; + } + } + + static <T> T getField(Object obj, String field) + { + try { + Class cls = obj.getClass(); + Field f = cls.getField(field); + return (T)f.get(obj); + } + catch (NoSuchFieldException x) { + Log.v(TAG, "field " + field + " not found in class " + + obj.getClass().getCanonicalName()); + return null; + } + catch (IllegalArgumentException x) { + Log.v(TAG, "IllegalArgumentException when getting field " + field + + " from class " + obj.getClass().getCanonicalName()); + return null; + } + catch (IllegalAccessException x) { + Log.v(TAG, "field " + field + " is not accessible in class " + + obj.getClass().getCanonicalName()); + return null; + } + } + + static <T> + T callMethod(Object obj, String methName, Class [] types, Object... args) + { + try { + Class cls = obj.getClass(); + Method m = cls.getMethod(methName, types); + return (T)m.invoke(obj, args); + } + catch (NoSuchMethodException x) { + Log.v(TAG, "method " + methName + " does not exist in class " + + obj.getClass().getCanonicalName()); + return null; + } + catch (NullPointerException x) { + Log.v(TAG, "can't invoke null method name"); + return null; + } + catch (SecurityException x) { + Log.v(TAG, "method " + methName + " is inaccessible in class " + + obj.getClass().getCanonicalName()); + return null; + } + catch (IllegalAccessException x) { + Log.v(TAG, "method " + methName + " is inaccessible in class " + + obj.getClass().getCanonicalName()); + return null; + } + catch (InvocationTargetException x) { + Log.v(TAG, "method " + methName + " threw an exception"); + return null; + } + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ScreenLock.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ScreenLock.java new file mode 100644 index 00000000..7957caa7 --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/ScreenLock.java @@ -0,0 +1,59 @@ +package org.liballeg.android; + +import android.app.Activity; +import android.util.Log; +import android.view.Window; +import android.view.WindowManager; + +class ScreenLock +{ + private static final String TAG = "ScreenLock"; + + private Activity activity; + + ScreenLock(Activity activity) + { + this.activity = activity; + } + + boolean inhibitScreenLock(boolean inhibit) + { + try { + if (inhibit) { + acquire(); + } + else if (!inhibit) { + release(); + } + return true; + } + catch (Exception e) { + Log.d(TAG, "Got exception in inhibitScreenLock: " + e.getMessage()); + return false; + } + } + + private void acquire() + { + activity.runOnUiThread(new Runnable() { + @Override + public void run() + { + activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + }); + } + + private void release() + { + activity.runOnUiThread(new Runnable() { + @Override + public void run() + { + activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + }); + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Sensors.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Sensors.java new file mode 100644 index 00000000..751f92ff --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/Sensors.java @@ -0,0 +1,57 @@ +package org.liballeg.android; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import java.util.List; + +public class Sensors implements SensorEventListener +{ + private static SensorManager sensorManager; + private List<Sensor> sensors; + + public native void nativeOnAccel(int id, float x, float y, float z); + + Sensors(Context context) + { + /* Only check for Accelerometers for now, not sure how we should utilize + * other types. + */ + sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); + sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); + } + + void listen() + { + for (int i = 0; i < sensors.size(); i++) { + sensorManager.registerListener(this, sensors.get(i), + SensorManager.SENSOR_DELAY_GAME); + } + } + + void unlisten() + { + for (int i = 0; i < sensors.size(); i++) { + sensorManager.unregisterListener(this, sensors.get(i)); + } + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) + { + /* what to do? */ + } + + @Override + public void onSensorChanged(SensorEvent event) + { + int i = sensors.indexOf(event.sensor); + if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { + nativeOnAccel(i, event.values[0], event.values[1], event.values[2]); + } + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/TouchListener.java b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/TouchListener.java new file mode 100644 index 00000000..c6f061b9 --- /dev/null +++ b/allegro/android/gradle_project/allegro/src/main/java/org/liballeg/android/TouchListener.java @@ -0,0 +1,115 @@ +package org.liballeg.android; + +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; + +class TouchListener implements View.OnTouchListener +{ + private static final String TAG = "TouchListener"; + + native void nativeOnTouch(int id, int action, float x, float y, + boolean primary); + + TouchListener() + { + } + + // FIXME: Pull out android version detection into the setup and just check + // some flags here, rather than checking for the existance of the fields and + // methods over and over. + @Override + public boolean onTouch(View v, MotionEvent event) + { + int action = 0; + int pointer_id = 0; + + Class[] no_args = new Class[0]; + Class[] int_arg = new Class[1]; + int_arg[0] = int.class; + + if (Reflect.methodExists(event, "getActionMasked")) { // android-8 / 2.2.x + action = Reflect.<Integer>callMethod(event, "getActionMasked", no_args); + int ptr_idx = Reflect.<Integer>callMethod(event, "getActionIndex", no_args); + pointer_id = Reflect.<Integer>callMethod(event, "getPointerId", int_arg, ptr_idx); + } else { + int raw_action = event.getAction(); + + if (Reflect.fieldExists(event, "ACTION_MASK")) { // android-5 / 2.0 + int mask = Reflect.<Integer>getField(event, "ACTION_MASK"); + action = raw_action & mask; + + int ptr_id_mask = Reflect.<Integer>getField(event, "ACTION_POINTER_ID_MASK"); + int ptr_id_shift = Reflect.<Integer>getField(event, "ACTION_POINTER_ID_SHIFT"); + + pointer_id = event.getPointerId((raw_action & ptr_id_mask) >> ptr_id_shift); + } + else { // android-4 / 1.6 + /* no ACTION_MASK? no multi touch, no pointer_id, */ + action = raw_action; + } + } + + boolean primary = false; + + if (action == MotionEvent.ACTION_DOWN) { + primary = true; + action = Const.ALLEGRO_EVENT_TOUCH_BEGIN; + } + else if (action == MotionEvent.ACTION_UP) { + primary = true; + action = Const.ALLEGRO_EVENT_TOUCH_END; + } + else if (action == MotionEvent.ACTION_MOVE) { + action = Const.ALLEGRO_EVENT_TOUCH_MOVE; + } + else if (action == MotionEvent.ACTION_CANCEL) { + action = Const.ALLEGRO_EVENT_TOUCH_CANCEL; + } + // android-5 / 2.0 + else if (Reflect.fieldExists(event, "ACTION_POINTER_DOWN") && + action == Reflect.<Integer>getField(event, "ACTION_POINTER_DOWN")) + { + action = Const.ALLEGRO_EVENT_TOUCH_BEGIN; + } + else if (Reflect.fieldExists(event, "ACTION_POINTER_UP") && + action == Reflect.<Integer>getField(event, "ACTION_POINTER_UP")) + { + action = Const.ALLEGRO_EVENT_TOUCH_END; + } + else { + Log.v(TAG, "unknown MotionEvent type: " + action); + return false; + } + + if (Reflect.methodExists(event, "getPointerCount")) { // android-5 / 2.0 + int pointer_count = Reflect.<Integer>callMethod(event, + "getPointerCount", no_args); + for (int i = 0; i < pointer_count; i++) { + float x = Reflect.<Float>callMethod(event, "getX", int_arg, i); + float y = Reflect.<Float>callMethod(event, "getY", int_arg, i); + int id = Reflect.<Integer>callMethod(event, "getPointerId", + int_arg, i); + + /* Not entirely sure we need to report move events for non-primary + * touches here but examples I've seen say that the + * ACTION_[POINTER_][UP|DOWN] report all touches and they can + * change between the last MOVE and the UP|DOWN event. + */ + if (id == pointer_id) { + nativeOnTouch(id, action, x, y, primary); + } else { + nativeOnTouch(id, Const.ALLEGRO_EVENT_TOUCH_MOVE, x, y, + primary); + } + } + } else { + nativeOnTouch(pointer_id, action, event.getX(), event.getY(), + primary); + } + + return true; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/android/gradle_project/app/build.gradle b/allegro/android/gradle_project/app/build.gradle new file mode 100644 index 00000000..d738cd03 --- /dev/null +++ b/allegro/android/gradle_project/app/build.gradle @@ -0,0 +1,23 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 26 + defaultConfig { + applicationId "org.liballeg.${APP_ID}" + minSdkVersion 15 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile "org.liballeg.android:allegro:1.0@aar" +} + diff --git a/allegro/android/gradle_project/app/src/main/AndroidManifest.xml b/allegro/android/gradle_project/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..cfa95a1f --- /dev/null +++ b/allegro/android/gradle_project/app/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.liballeg.app" + android:versionCode="1" + android:versionName="1.0"> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> + <application android:label="${APP_ID}"> + <activity android:name=".MainActivity" + android:launchMode="singleTask" + android:screenOrientation="unspecified" + android:configChanges="screenLayout|uiMode|orientation|screenSize"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/allegro/android/gradle_project/app/src/main/java/org/liballeg/app/MainActivity.java b/allegro/android/gradle_project/app/src/main/java/org/liballeg/app/MainActivity.java new file mode 100644 index 00000000..26225647 --- /dev/null +++ b/allegro/android/gradle_project/app/src/main/java/org/liballeg/app/MainActivity.java @@ -0,0 +1,44 @@ +package org.liballeg.app; +import org.liballeg.android.AllegroActivity; +import android.util.Log; + +public class MainActivity extends AllegroActivity { + + static void loadLibrary(String name) { + try { + // try loading the debug library first. + Log.d("loadLibrary", name + "-debug"); + System.loadLibrary(name + "-debug"); + } catch (UnsatisfiedLinkError e) { + try { + // If it fails load the release library. + Log.d("loadLibrary", name); + System.loadLibrary(name); + } + catch (UnsatisfiedLinkError e2) { + // We still continue as failing to load an addon may + // not be a fatal error - for example if the TTF was + // not built we can still run an example which does not + // need that addon. + Log.d("loadLibrary", name + " FAILED"); + } + } + } + + static { + loadLibrary("allegro"); + loadLibrary("allegro_primitives"); + loadLibrary("allegro_image"); + loadLibrary("allegro_font"); + loadLibrary("allegro_ttf"); + loadLibrary("allegro_audio"); + loadLibrary("allegro_acodec"); + loadLibrary("allegro_color"); + loadLibrary("allegro_memfile"); + loadLibrary("allegro_physfs"); + loadLibrary("allegro_video"); + } + public MainActivity() { + super("libnative-lib.so"); + } +} diff --git a/allegro/android/gradle_project/build.gradle b/allegro/android/gradle_project/build.gradle new file mode 100644 index 00000000..c2ff9d85 --- /dev/null +++ b/allegro/android/gradle_project/build.gradle @@ -0,0 +1,17 @@ +buildscript { + repositories { + google() + jcenter() + } + dependencies { + classpath "com.android.tools.build:gradle:3.2.0" + } +} + +allprojects { + repositories { + google() + jcenter() + flatDir { dirs 'libs' } + } +} diff --git a/allegro/android/gradle_project/gradle.properties b/allegro/android/gradle_project/gradle.properties new file mode 100644 index 00000000..d7df1928 --- /dev/null +++ b/allegro/android/gradle_project/gradle.properties @@ -0,0 +1 @@ +#org.gradle.java.home=${JAVA_HOME} diff --git a/allegro/android/gradle_project/gradle/wrapper/gradle-wrapper.jar b/allegro/android/gradle_project/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..13372aef Binary files /dev/null and b/allegro/android/gradle_project/gradle/wrapper/gradle-wrapper.jar differ diff --git a/allegro/android/gradle_project/gradle/wrapper/gradle-wrapper.properties b/allegro/android/gradle_project/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..0dd3b9a9 --- /dev/null +++ b/allegro/android/gradle_project/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Aug 24 20:59:32 EDT 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/allegro/android/gradle_project/gradlew b/allegro/android/gradle_project/gradlew new file mode 100644 index 00000000..9d82f789 --- /dev/null +++ b/allegro/android/gradle_project/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/allegro/android/gradle_project/local.properties b/allegro/android/gradle_project/local.properties new file mode 100644 index 00000000..9728a198 --- /dev/null +++ b/allegro/android/gradle_project/local.properties @@ -0,0 +1 @@ +sdk.dir=${ANDROID_HOME} diff --git a/allegro/android/gradle_project/settings.gradle b/allegro/android/gradle_project/settings.gradle new file mode 100644 index 00000000..c1be6e9a --- /dev/null +++ b/allegro/android/gradle_project/settings.gradle @@ -0,0 +1 @@ +include ":${GRADLE_PROJECT}" diff --git a/allegro/appveyor.yml b/allegro/appveyor.yml new file mode 100644 index 00000000..a9c5fabd --- /dev/null +++ b/allegro/appveyor.yml @@ -0,0 +1,16 @@ +version: "{branch}-ci-{build}" +clone_depth: 5 + +install: + - mkdir deps + - mkdir deps\include + - mkdir deps\lib + - nuget install AllegroDeps -Version 1.5.0 -OutputDirectory deps -ExcludeVersion + - ps: move deps\AllegroDeps\build\native\include\* deps\include -force + - ps: move deps\AllegroDeps\build\native\v140\win32\deps\lib\* deps\lib -force + +build_script: + - mkdir build + - cd build + - cmake .. -G "Visual Studio 14 2015" -DWANT_ACODEC_DYNAMIC_LOAD=off -DFLAC_STATIC=on + - cmake --build . --config RelWithDebInfo diff --git a/allegro/cmake/AllegroFindFFMPEG.cmake b/allegro/cmake/AllegroFindFFMPEG.cmake new file mode 100644 index 00000000..948b8da2 --- /dev/null +++ b/allegro/cmake/AllegroFindFFMPEG.cmake @@ -0,0 +1,13 @@ +# - Find FFMPEG +# +# FFMPEG_FOUND - true if FFMPEG is found +# FFMPEG_CFLAGS - required compiler flags +# FFMPEG_LDFLAGS - required linker flags + +# -lavcodec -lavformat -lswscale + +if(ALLEGRO_UNIX) + pkg_check_modules(FFMPEG libavcodec libavformat libswscale libavutil) +endif() + +# TODO: Windos and OSX diff --git a/allegro/cmake/AllegroFindOSS.cmake b/allegro/cmake/AllegroFindOSS.cmake new file mode 100644 index 00000000..9536603b --- /dev/null +++ b/allegro/cmake/AllegroFindOSS.cmake @@ -0,0 +1,73 @@ +# - Find Open Sound System +# +# OSS_FOUND - True if OSS headers found. + +# This file is Allegro-specific and requires the following variables to be +# set elsewhere: +# ALLEGRO_HAVE_MACHINE_SOUNDCARD_H +# ALLEGRO_HAVE_LINUX_SOUNDCARD_H +# ALLEGRO_HAVE_SYS_SOUNDCARD_H +# ALLEGRO_HAVE_SOUNDCARD_H + + +if(OSS_INCLUDE_DIR) + # Already in cache, be silent + set(OSS_FIND_QUIETLY TRUE) +endif(OSS_INCLUDE_DIR) + +set(CMAKE_REQUIRED_DEFINITIONS) + +if(ALLEGRO_HAVE_SOUNDCARD_H OR ALLEGRO_HAVE_SYS_SOUNDCARD_H OR + ALLEGRO_HAVE_MACHINE_SOUNDCARD_H OR ALLEGRO_LINUX_SYS_SOUNDCARD_H) + + if(ALLEGRO_HAVE_MACHINE_SOUNDCARD_H) + set(CMAKE_REQUIRED_DEFINITIONS -DALLEGRO_HAVE_MACHINE_SOUNDCARD_H) + endif(ALLEGRO_HAVE_MACHINE_SOUNDCARD_H) + + if(ALLEGRO_HAVE_LINUX_SOUNDCARD_H) + set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + -DALLEGRO_HAVE_LINUX_SOUNDCARD_H) + endif(ALLEGRO_HAVE_LINUX_SOUNDCARD_H) + + if(ALLEGRO_HAVE_SYS_SOUNDCARD_H) + set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + -DALLEGRO_HAVE_SYS_SOUNDCARD_H) + endif(ALLEGRO_HAVE_SYS_SOUNDCARD_H) + + if(ALLEGRO_HAVE_SOUNDCARD_H) + set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + -DALLEGRO_HAVE_SOUNDCARD_H) + endif(ALLEGRO_HAVE_SOUNDCARD_H) + + run_c_compile_test(" + #ifdef ALLEGRO_HAVE_SOUNDCARD_H + #include <soundcard.h> + #endif + #ifdef ALLEGRO_HAVE_SYS_SOUNDCARD_H + #include <sys/soundcard.h> + #endif + #ifdef ALLEGRO_HAVE_LINUX_SOUNDCARD_H + #include <linux/soundcard.h> + #endif + #ifdef ALLEGRO_HAVE_MACHINE_SOUNDCARD_H + #include <machine/soundcard.h> + #endif + int main(void) { + audio_buf_info abi; + return 0; + }" + OSS_COMPILES + ) + + set(CMAKE_REQUIRED_DEFINITIONS) + +endif(ALLEGRO_HAVE_SOUNDCARD_H OR ALLEGRO_HAVE_SYS_SOUNDCARD_H OR + ALLEGRO_HAVE_MACHINE_SOUNDCARD_H OR ALLEGRO_LINUX_SYS_SOUNDCARD_H) + +# Handle the QUIETLY and REQUIRED arguments and set OSS_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OSS DEFAULT_MSG + OSS_COMPILES) + +mark_as_advanced(OSS_COMPILES) diff --git a/allegro/cmake/AndroidApp.cmake b/allegro/cmake/AndroidApp.cmake new file mode 100644 index 00000000..5b25f1b4 --- /dev/null +++ b/allegro/cmake/AndroidApp.cmake @@ -0,0 +1,113 @@ +function(add_android_app prog sources) + set(PROJECT "${CMAKE_CURRENT_BINARY_DIR}/${prog}.project") + set(PROJECT_SOURCE ${CMAKE_SOURCE_DIR}/android/gradle_project) + set(native "${PROJECT}/app/src/main/jniLibs/${ANDROID_ABI}/libnative-lib.so") + set(GRADLE_PROJECT app) + set(ANDROID_HOME $ENV{ANDROID_HOME}) + set(AAR ${PROJECT}/app/libs/allegro.aar) + set(adb ${ANDROID_HOME}/platform-tools/adb) + set(APP_ID ${prog}) + + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(SUFFIX "-debug") + else() + set(SUFFIX "") + endif() + + configure_file( + ${PROJECT_SOURCE}/settings.gradle + ${PROJECT}/settings.gradle) + + configure_file( + ${PROJECT_SOURCE}/local.properties + ${PROJECT}/local.properties) + + configure_file( + ${PROJECT_SOURCE}/app/src/main/AndroidManifest.xml + ${PROJECT}/app/src/main/AndroidManifest.xml) + + configure_file( + ${PROJECT_SOURCE}/app/build.gradle + ${PROJECT}/app/build.gradle) + + set(COPY_FILES + ${PROJECT_SOURCE}/gradle.properties + ${PROJECT_SOURCE}/build.gradle + ${PROJECT_SOURCE}/gradlew + ${PROJECT_SOURCE}/gradle/wrapper/gradle-wrapper.jar + ${PROJECT_SOURCE}/gradle/wrapper/gradle-wrapper.properties + ${PROJECT_SOURCE}/app/src/main/java/org/liballeg/app/MainActivity.java + ) + + get_property(JNI_LIBS GLOBAL PROPERTY JNI_LIBS) + foreach(lib ${JNI_LIBS}) + set(jnilib ${PROJECT}/app/src/main/jniLibs/${ANDROID_ABI}/lib${lib}${SUFFIX}.so) + add_custom_command( + OUTPUT ${jnilib} + DEPENDS ${lib} + COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${lib}> ${jnilib}) + list(APPEND jnilibs ${jnilib}) + endforeach() + + list(APPEND COPIED_FILES ${PROJECT}/local.properties) + list(APPEND COPIED_FILES ${PROJECT}/app/src/main/AndroidManifest.xml) + list(APPEND COPIED_FILES ${PROJECT}/app/build.gradle) + + foreach(copy ${COPY_FILES}) + string(REPLACE "${PROJECT_SOURCE}/" "${PROJECT}/" target ${copy}) + add_custom_command( + OUTPUT ${target} + DEPENDS ${copy} + COMMAND ${CMAKE_COMMAND} -E copy ${copy} ${target} + ) + list(APPEND COPIED_FILES ${target}) + endforeach() + + # The APK to output. We always build the examples in debug mode as + # a release version would need to be signed. + set(apk_path "${PROJECT}/app/build/outputs/apk/debug/app-debug.apk") + + # Build the application as a shared library. + add_library(${prog} SHARED ${sources}) + set_target_properties(${prog} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${PROJECT}) + target_link_libraries(${prog} ${JNI_LIBS}) + + # Get the path of the application's shared object. + add_custom_command( + OUTPUT ${native} + DEPENDS ${prog} + COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${prog}> ${native} + ) + + add_custom_command( + OUTPUT ${AAR} + DEPENDS ${ALLEGRO_AAR} + COMMAND ${CMAKE_COMMAND} -E copy ${ALLEGRO_AAR} ${AAR} + ) + + # How to make the APK. + add_custom_command( + OUTPUT ${apk_path} + DEPENDS ${native} ${jnilibs} ${COPIED_FILES} ${AAR} + WORKING_DIRECTORY ${PROJECT} + COMMAND ./gradlew assembleDebug + ) + + add_custom_target(${prog}_apk + ALL + DEPENDS aar ${apk_path} + ) + + # Useful targets for testing. + add_custom_target(install_${prog} + DEPENDS ${prog}_apk + COMMAND ${adb} install -r ${apk_path} + ) + + add_custom_target(run_${prog} + DEPENDS install_${prog} + COMMAND ${adb} shell + 'am start -a android.intent.action.MAIN -n org.liballeg.${APP_ID}/org.liballeg.app.MainActivity' + ) +endfunction() diff --git a/allegro/cmake/Common.cmake b/allegro/cmake/Common.cmake new file mode 100644 index 00000000..a9f3ac81 --- /dev/null +++ b/allegro/cmake/Common.cmake @@ -0,0 +1,417 @@ +function(set_our_header_properties) + foreach(file ${ARGN}) + # Infer which subdirectory this header file should be installed. + set(loc ${file}) + string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" loc ${loc}) + string(REGEX REPLACE "^include/" "" loc ${loc}) + string(REGEX REPLACE "/[-A-Za-z0-9_]+[.](h|inl)$" "" loc ${loc}) + string(REGEX REPLACE "^addons/[^/]+/" "" loc ${loc}) + + # If we have inferred correctly then it should be under allegro5. + string(REGEX MATCH "^allegro5" matched ${loc}) + if(matched STREQUAL "allegro5") + # MACOSX_PACKAGE_LOCATION is also used in install_our_headers. + set_source_files_properties(${file} + PROPERTIES + MACOSX_PACKAGE_LOCATION Headers/${loc} + ) + else() + message(FATAL_ERROR "Could not infer where to install ${file}") + endif() + endforeach(file) +endfunction(set_our_header_properties) + +# Normally CMake caches the "failure" result of a compile test, preventing it +# from re-running. These helpers delete the cache variable on failure so that +# CMake will try again next time. +function(run_c_compile_test source var) + check_c_source_compiles("${source}" ${var}) + if (NOT ${var}) + unset(${var} CACHE) + endif(NOT ${var}) +endfunction(run_c_compile_test) + +function(run_cxx_compile_test source var) + check_cxx_source_compiles("${source}" ${var}) + if (NOT ${var}) + unset(${var} CACHE) + endif(NOT ${var}) +endfunction(run_cxx_compile_test) + +function(append_lib_type_suffix var) + string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_TOLOWER) + if(CMAKE_BUILD_TYPE_TOLOWER STREQUAL "debug") + set(${var} "${${var}}-debug" PARENT_SCOPE) + endif(CMAKE_BUILD_TYPE_TOLOWER STREQUAL "debug") + if(CMAKE_BUILD_TYPE_TOLOWER MATCHES "profile") + set(${var} "${${var}}-profile" PARENT_SCOPE) + endif(CMAKE_BUILD_TYPE_TOLOWER MATCHES "profile") +endfunction(append_lib_type_suffix) + +function(append_lib_linkage_suffix var) + if(NOT BUILD_SHARED_LIBS) + set(${var} "${${var}}-static" PARENT_SCOPE) + endif(NOT BUILD_SHARED_LIBS) +endfunction(append_lib_linkage_suffix) + +# Oh my. CMake really is bad for this - but I couldn't find a better +# way. +function(sanitize_cmake_link_flags ...) + set(return) + foreach(lib ${ARGV}) + # Watch out for -framework options (OS X) + if(NOT lib MATCHES "-framework.*" AND NOT lib MATCHES ".*framework") + # Remove absolute path. + string(REGEX REPLACE "/.*/(.*)" "\\1" lib ${lib}) + + # Remove .a/.so/.dylib. + string(REGEX REPLACE "lib(.*)\\.a" "\\1" lib ${lib}) + string(REGEX REPLACE "lib(.*)\\.so" "\\1" lib ${lib}) + string(REGEX REPLACE "lib(.*)\\.dylib" "\\1" lib ${lib}) + + # Remove -l prefix if it's there already. + string(REGEX REPLACE "-l(.*)" "\\1" lib ${lib}) + + # Make sure we don't include our own libraries. + # FIXME: Use a global list instead of a very unstable regexp. + if(NOT lib MATCHES "allegro_.*" AND NOT lib STREQUAL "allegro" AND NOT lib STREQUAL "allegro_audio") + set(return "${return} -l${lib}") + endif() + endif(NOT lib MATCHES "-framework.*" AND NOT lib MATCHES ".*framework") + endforeach(lib) + set(return ${return} PARENT_SCOPE) +endfunction(sanitize_cmake_link_flags) + +function(add_our_library target framework_name sources extra_flags link_with) + # BUILD_SHARED_LIBS controls whether this is a shared or static library. + add_library(${target} ${sources}) + + if(MSVC) + # Compile with multiple processors + set(extra_flags "${extra_flags} /MP") + if(WANT_STATIC_RUNTIME) + if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(extra_flags "${extra_flags} /MTd") + else() + set(extra_flags "${extra_flags} /MT") + endif() + if (NOT BUILD_SHARED_LIBS) + # /Zl instructs MSVC to not mention the CRT used at all, + # allowing the static libraries to be combined with any CRT version + # in the final dll/exe. + set(extra_flags "${extra_flags} /Zl") + endif() + endif() + elseif(MINGW) + if(WANT_STATIC_RUNTIME) + # TODO: The -static is a bit of a hack for MSYS2 to force the static linking of pthreads. + # There has to be a better way. + set(extra_link_flags "-static-libgcc -static-libstdc++ -static -lpthread") + endif() + endif() + + if(WIN32) + set(extra_flags "${extra_flags} -DUNICODE -D_UNICODE") + endif() + + if(NOT BUILD_SHARED_LIBS) + set(static_flag "-DALLEGRO_STATICLINK") + endif(NOT BUILD_SHARED_LIBS) + + if(NOT ANDROID) + set_target_properties(${target} + PROPERTIES + COMPILE_FLAGS "${extra_flags} ${static_flag} -DALLEGRO_LIB_BUILD" + LINK_FLAGS "${extra_link_flags}" + VERSION ${ALLEGRO_VERSION} + SOVERSION ${ALLEGRO_SOVERSION} + ) + else(NOT ANDROID) + set_target_properties(${target} + PROPERTIES + COMPILE_FLAGS "${extra_flags} ${static_flag} -DALLEGRO_LIB_BUILD" + ) + set_property(GLOBAL APPEND PROPERTY JNI_LIBS ${target}) + endif(NOT ANDROID) + + # Construct the output name. + set(output_name ${target}) + append_lib_type_suffix(output_name) + append_lib_linkage_suffix(output_name) + set_target_properties(${target} + PROPERTIES + OUTPUT_NAME ${output_name} + ) + + # Put version numbers on DLLs but not on import libraries nor static + # archives. Make MinGW not add a lib prefix to DLLs, to match MSVC. + if(WIN32 AND SHARED) + set_target_properties(${target} + PROPERTIES + PREFIX "" + SUFFIX -${ALLEGRO_SOVERSION}.dll + IMPORT_SUFFIX ${CMAKE_IMPORT_LIBRARY_SUFFIX} + ) + endif() + + # Suppress errors about _mangled_main_address being undefined on Mac OS X. + if(MACOSX) + set_target_properties(${target} + PROPERTIES + LINK_FLAGS "-flat_namespace -undefined suppress" + ) + endif(MACOSX) + + # Specify a list of libraries to be linked into the specified target. + # Library dependencies are transitive by default. Any target which links + # with this target will therefore pull in these dependencies automatically. + target_link_libraries(${target} ${link_with}) + + # Set list of dependencies that the user would need to explicitly link with + # if static linking. + sanitize_cmake_link_flags(${link_with}) + set_target_properties(${target} + PROPERTIES + static_link_with "${return}" + ) + set_our_framework_properties(${target} ${framework_name}) + install_our_library(${target} ${output_name}) +endfunction(add_our_library) + +macro(add_our_addon_library target framework_name sources extra_flags link_with) + if(WANT_MONOLITH) + set(MONOLITH_DEFINES "${MONOLITH_DEFINES} ${extra_flags}") + else() + add_our_library(${target} ${framework_name} "${sources}" "${extra_flags}" "${link_with}") + if(ANDROID) + record_android_load_libs(${target} "${link_with}") + endif() + endif() +endmacro(add_our_addon_library) + +# Record in a custom target property 'ANDROID_LOAD_LIBS' the list of shared +# objects that will need to be bundled with the APK and loaded manually if +# linking with this target. +function(record_android_load_libs target libs) + set(load_libs) + foreach(lib ${libs}) + if(lib MATCHES "/lib[^/]+[.]so$" AND NOT lib MATCHES "/sysroot/") + list(APPEND load_libs "${lib}") + endif() + endforeach() + set_target_properties(${target} PROPERTIES ANDROID_LOAD_LIBS "${load_libs}") +endfunction(record_android_load_libs) + +function(set_our_framework_properties target nm) + if(WANT_FRAMEWORKS) + if(WANT_EMBED) + set(install_name_dir "@executable_path/../Frameworks") + else() + set(install_name_dir "${FRAMEWORK_INSTALL_PREFIX}") + endif(WANT_EMBED) + set_target_properties(${target} + PROPERTIES + FRAMEWORK on + OUTPUT_NAME ${nm} + INSTALL_NAME_DIR "${install_name_dir}" + ) + endif(WANT_FRAMEWORKS) +endfunction(set_our_framework_properties) + +function(install_our_library target filename) + install(TARGETS ${target} + LIBRARY DESTINATION "lib${LIB_SUFFIX}" + ARCHIVE DESTINATION "lib${LIB_SUFFIX}" + FRAMEWORK DESTINATION "${FRAMEWORK_INSTALL_PREFIX}" + RUNTIME DESTINATION "bin" + # Doesn't work, see below. + # PUBLIC_HEADER DESTINATION "include" + ) + if(MSVC AND BUILD_SHARED_LIBS) + install(FILES ${CMAKE_BINARY_DIR}/lib/\${CMAKE_INSTALL_CONFIG_NAME}/${filename}.pdb + DESTINATION lib + CONFIGURATIONS Debug RelWithDebInfo + ) + endif() +endfunction(install_our_library) + +# Unfortunately, CMake's PUBLIC_HEADER support doesn't install into nested +# directories well, otherwise we could rely on install(TARGETS) to install +# header files associated with the target. Instead we use the install(FILES) +# to install headers. We reuse the MACOSX_PACKAGE_LOCATION property, +# substituting the "Headers" prefix with "include". +function(install_our_headers) + if(NOT WANT_FRAMEWORKS) + foreach(hdr ${ARGN}) + get_source_file_property(LOC ${hdr} MACOSX_PACKAGE_LOCATION) + string(REGEX REPLACE "^Headers" "include" LOC ${LOC}) + install(FILES ${hdr} DESTINATION ${LOC}) + endforeach() + endif() +endfunction(install_our_headers) + +function(fix_executable nm) + if(IPHONE) + string(REPLACE "_" "" bundle_nm ${nm}) + set_target_properties(${nm} PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.liballeg.${bundle_nm}") + + # FIXME:We want those as project attributes, not target attributes, but I don't know how + set_target_properties(${nm} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer") + + # We have to add an icon to every executable on IPhone else + # cmake won't create a resource copy build phase for us. + # And re-creating those by hand would be a major pain. + set_target_properties(${nm} PROPERTIES MACOSX_BUNDLE_ICON_FILE icon.png) + + set_source_files_properties("${CMAKE_SOURCE_DIR}/misc/icon.png" PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources" + ) + + endif(IPHONE) +endfunction(fix_executable) + +# Ads a target for an executable target `nm`. +# +# Arguments: +# +# SRCS - Sources. If empty, assumes it to be ${nm}.c +# LIBS - Libraries to link to. +# DEFINES - Additional defines. +# +# Free variable: EXECUTABLE_TYPE +function(add_our_executable nm) + set(flags) # none + set(single_args) # none + set(multi_args SRCS LIBS DEFINES) + cmake_parse_arguments(OPTS "${flags}" "${single_args}" "${multi_args}" + ${ARGN}) + + if(NOT OPTS_SRCS) + set(OPTS_SRCS "${nm}.c") + endif() + + if(IPHONE) + set(EXECUTABLE_TYPE MACOSX_BUNDLE) + set(OPTS_SRCS ${OPTS_SRCS} "${CMAKE_SOURCE_DIR}/misc/icon.png") + endif() + + add_executable(${nm} ${EXECUTABLE_TYPE} ${OPTS_SRCS}) + target_link_libraries(${nm} ${OPTS_LIBS}) + if(WANT_POPUP_EXAMPLES AND SUPPORT_NATIVE_DIALOG) + list(APPEND OPTS_DEFINES ALLEGRO_POPUP_EXAMPLES) + endif() + if(NOT BUILD_SHARED_LIBS) + list(APPEND OPTS_DEFINES ALLEGRO_STATICLINK) + endif() + + foreach(d ${OPTS_DEFINES}) + set_property(TARGET ${nm} APPEND PROPERTY COMPILE_DEFINITIONS ${d}) + endforeach() + + set(extra_flags "") + + if(MSVC) + # Compile with multiple processors + set(extra_flags "/MP") + if(WANT_STATIC_RUNTIME) + if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(extra_flags "${extra_flags} /MTd") + else() + set(extra_flags "${extra_flags} /MT") + endif() + endif() + endif() + + if(WIN32) + set(extra_flags "${extra_flags} -DUNICODE -D_UNICODE") + endif() + + set_target_properties(${nm} PROPERTIES COMPILE_FLAGS "${extra_flags}") + + if(MINGW) + if(NOT CMAKE_BUILD_TYPE STREQUAL Debug) + set_target_properties(${nm} PROPERTIES LINK_FLAGS "-Wl,-subsystem,windows") + endif() + endif() + + fix_executable(${nm}) +endfunction() + +function(add_copy_commands src dest destfilesvar) + set(destfiles) + foreach(basename ${ARGN}) + list(APPEND destfiles "${dest}/${basename}") + add_custom_command( + OUTPUT "${dest}/${basename}" + DEPENDS "${src}/${basename}" + COMMAND "${CMAKE_COMMAND}" -E copy + "${src}/${basename}" "${dest}/${basename}" + ) + endforeach() + set(${destfilesvar} "${destfiles}" PARENT_SCOPE) +endfunction() + +# Recreate data directory for out-of-source builds. +# Note: a symlink is unsafe as make clean will delete the contents +# of the pointed-to directory. +# +# Files are only copied if they don't are inside a .svn folder so we +# won't end up with read-only .svn folders in the build folder. +function(copy_data_dir_to_build target src dest) + if(IPHONE) + return() + endif(IPHONE) + + if(src STREQUAL dest) + return() + endif() + + file(GLOB_RECURSE files RELATIVE "${src}" "${src}/*") + add_copy_commands("${src}" "${dest}" destfiles "${files}") + add_custom_target(${target} ALL DEPENDS ${destfiles}) +endfunction(copy_data_dir_to_build) + +macro(add_monolith_sources var addon sources) + foreach(s ${${sources}}) + list(APPEND ${var} ${addon}/${s}) + endforeach(s ${sources}) +endmacro(add_monolith_sources addon sources) + +# This macro is called by each addon. It expects the following variables to +# exist: +# +# ${ADDON}_SOURCES +# ${ADDON}_INCLUDE_FILES +# ${ADDON}_INCLUDE_DIRECTORIES +# ${ADDON}_LINK_DIRECTORIES +# ${ADDON}_DEFINES +# ${ADDON}_LIBRARIES +# +# This is useful so we can build the monolith library without having any other +# special code for it in the addon CMakeLists.txt files. +macro(add_addon addon) + add_addon2(${addon} allegro_${addon}) +endmacro(add_addon) + +macro(add_addon2 addon addon_target) + string(TOUPPER ${addon} ADDON) + set(SUPPORT_${ADDON} 1 PARENT_SCOPE) + set(${ADDON}_LINK_WITH ${addon_target} PARENT_SCOPE) + add_monolith_sources(MONOLITH_SOURCES addons/${addon} ${ADDON}_SOURCES) + add_monolith_sources(MONOLITH_SOURCES addons/${addon} ${ADDON}_INCLUDE_FILES) + add_monolith_sources(MONOLITH_HEADERS addons/${addon} ${ADDON}_INCLUDE_FILES) + set(MONOLITH_SOURCES ${MONOLITH_SOURCES} PARENT_SCOPE) + list(APPEND MONOLITH_INCLUDE_DIRECTORIES ${${ADDON}_INCLUDE_DIRECTORIES}) + list(APPEND MONOLITH_INCLUDE_DIRECTORIES addons/${addon}) + list(APPEND MONOLITH_LINK_DIRECTORIES ${${ADDON}_LINK_DIRECTORIES}) + list(APPEND MONOLITH_LIBRARIES ${${ADDON}_LIBRARIES}) + set(MONOLITH_DEFINES "${MONOLITH_DEFINES} ${${ADDON}_DEFINES}") + set(MONOLITH_INCLUDE_DIRECTORIES ${MONOLITH_INCLUDE_DIRECTORIES} PARENT_SCOPE) + set(MONOLITH_LINK_DIRECTORIES ${MONOLITH_LINK_DIRECTORIES} PARENT_SCOPE) + set(MONOLITH_LIBRARIES ${MONOLITH_LIBRARIES} PARENT_SCOPE) + set(MONOLITH_HEADERS ${MONOLITH_HEADERS} PARENT_SCOPE) + set(MONOLITH_DEFINES ${MONOLITH_DEFINES} PARENT_SCOPE) +endmacro(add_addon2) + +#-----------------------------------------------------------------------------# +# vim: set ft=cmake sts=4 sw=4 et: diff --git a/allegro/cmake/FileList.cmake b/allegro/cmake/FileList.cmake new file mode 100644 index 00000000..a9dcf453 --- /dev/null +++ b/allegro/cmake/FileList.cmake @@ -0,0 +1,332 @@ +set(ALLEGRO_SRC_FILES + src/allegro.c + src/bitmap.c + src/bitmap_draw.c + src/bitmap_io.c + src/bitmap_lock.c + src/bitmap_pixel.c + src/bitmap_type.c + src/blenders.c + src/clipboard.c + src/config.c + src/convert.c + src/cpu.c + src/debug.c + src/display.c + src/display_settings.c + src/drawing.c + src/dtor.c + src/events.c + src/evtsrc.c + src/exitfunc.c + src/file.c + src/file_slice.c + src/file_stdio.c + src/fshook.c + src/fshook_stdio.c + src/fullscreen_mode.c + src/haptic.c + src/inline.c + src/joynu.c + src/keybdnu.c + src/libc.c + src/math.c + src/memblit.c + src/memdraw.c + src/memory.c + src/monitor.c + src/mousenu.c + src/mouse_cursor.c + src/path.c + src/pixels.c + src/shader.c + src/system.c + src/threads.c + src/timernu.c + src/tls.c + src/touch_input.c + src/transformations.c + src/tri_soft.c + src/utf8.c + src/misc/aatree.c + src/misc/bstrlib.c + src/misc/list.c + src/misc/vector.c + ) + +set(ALLEGRO_SRC_WIN_FILES + src/win/wclipboard.c + src/win/whapall.c + src/win/whapdrv.c + src/win/whaptic.cpp + src/win/whapxi.c + src/win/wjoyall.c + src/win/wjoydrv.c + src/win/wjoydxnu.cpp + src/win/wjoyxi.c + src/win/wkeyboard.c + src/win/wmcursor.c + src/win/wmouse.c + src/win/wsystem.c + src/win/wthread.c + src/win/wtime.c + src/win/wtouch_input.c + src/win/wunicode.c + src/win/wwindow.c + src/win/wxthread.c + ) + +set(ALLEGRO_SRC_D3D_FILES + src/win/d3d_bmp.cpp + src/win/d3d_disp.cpp + src/win/d3d_display_formats.cpp + src/win/d3d_render_state.cpp + src/win/d3d_shader.cpp + src/win/d3d_d3dx9.cpp + ) + +set(ALLEGRO_SRC_OPENGL_FILES + src/opengl/extensions.c + src/opengl/ogl_bitmap.c + src/opengl/ogl_display.c + src/opengl/ogl_draw.c + src/opengl/ogl_fbo.c + src/opengl/ogl_lock.c + src/opengl/ogl_lock_es.c + src/opengl/ogl_render_state.c + src/opengl/ogl_shader.c + ) + +set(ALLEGRO_SRC_WGL_FILES + src/win/wgl_disp.c + ) + +set(ALLEGRO_SRC_UNIX_FILES + src/unix/udrvlist.c + src/unix/ufdwatch.c + src/unix/ugfxdrv.c + src/unix/uhapdrv.c + src/unix/ujoydrv.c + src/unix/ukeybd.c + src/unix/umouse.c + src/unix/upath.c + src/unix/utime.c + src/unix/uxthread.c + ) + +set(ALLEGRO_SRC_X_FILES + src/x/xclipboard.c + src/x/xcursor.c + src/x/xdisplay.c + src/x/xevents.c + src/x/xfullscreen.c + src/x/xglx_config.c + src/x/xkeyboard.c + src/x/xmousenu.c + src/x/xrandr.c + src/x/xsystem.c + src/x/xtouch.c + src/x/xwindow.c + src/linux/lhaptic.c + src/linux/ljoynu.c + ) + +set(ALLEGRO_SRC_MACOSX_FILES + src/macosx/hidjoy.m + src/macosx/hidjoy-10.4.m + src/macosx/hidman.m + src/macosx/keybd.m + src/macosx/qzmouse.m + src/macosx/system.m + src/macosx/osxclipboard.m + src/macosx/osxgl.m + src/macosx/osx_app_delegate.m + src/unix/utime.c + src/unix/uxthread.c + ) + +set(ALLEGRO_SRC_IPHONE_FILES + src/iphone/allegroAppDelegate.m + src/iphone/EAGLView.m + src/iphone/ViewController.m + src/iphone/iphone_clipboard.m + src/iphone/iphone_display.m + src/iphone/iphone_joystick.m + src/iphone/iphone_keyboard.c + src/iphone/iphone_main.m + src/iphone/iphone_mouse.m + src/iphone/iphone_path.m + src/iphone/iphone_system.c + src/iphone/iphone_touch_input.m + src/unix/utime.c + src/unix/uxthread.c + ) + +set(ALLEGRO_SRC_ANDROID_FILES + src/unix/ufdwatch.c + src/unix/utime.c + src/unix/uxthread.c + src/android/android_apk_file.c + src/android/android_clipboard.c + src/android/android_display.c + src/android/android_image.c + src/android/android_input_stream.c + src/android/android_joystick.c + src/android/android_keyboard.c + src/android/android_mouse.c + src/android/android_sensors.c + src/android/android_system.c + src/android/android_touch.c + src/android/jni_helpers.c + src/linux/ljoynu.c + src/android/android_apk_fs.c +) + +set(ALLEGRO_SRC_RASPBERRYPI_FILES + src/unix/utime.c + src/unix/uxthread.c + src/linux/lkeybdnu.c + src/linux/lmseev.c + src/linux/lmsedrv.c + src/linux/lhaptic.c + src/linux/ljoynu.c + src/x/xevents.c + src/x/xkeyboard.c + src/x/xmousenu.c + src/x/xwindow.c + src/raspberrypi/pisystem.c + src/raspberrypi/pidisplay.c + ) + +set(ALLEGRO_SRC_SDL_FILES + src/sdl/sdl_system.c + src/sdl/sdl_time.c + src/sdl/sdl_thread.c + src/sdl/sdl_display.c + src/sdl/sdl_keyboard.c + src/sdl/sdl_mouse.c + src/sdl/sdl_touch.c + src/sdl/sdl_joystick.c + src/sdl/sdl_event_hack.c + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_FILES + include/allegro5/allegro5.h + include/allegro5/allegro.h + include/allegro5/alcompat.h + include/allegro5/altime.h + include/allegro5/base.h + include/allegro5/bitmap.h + include/allegro5/bitmap_draw.h + include/allegro5/bitmap_io.h + include/allegro5/bitmap_lock.h + include/allegro5/blender.h + include/allegro5/clipboard.h + include/allegro5/color.h + include/allegro5/config.h + include/allegro5/cpu.h + include/allegro5/debug.h + include/allegro5/display.h + include/allegro5/drawing.h + include/allegro5/error.h + include/allegro5/events.h + include/allegro5/file.h + include/allegro5/fixed.h + include/allegro5/fmaths.h + include/allegro5/fshook.h + include/allegro5/fullscreen_mode.h + include/allegro5/haptic.h + include/allegro5/joystick.h + include/allegro5/keyboard.h + include/allegro5/keycodes.h + include/allegro5/memory.h + include/allegro5/monitor.h + include/allegro5/mouse.h + include/allegro5/mouse_cursor.h + include/allegro5/path.h + include/allegro5/render_state.h + include/allegro5/shader.h + include/allegro5/system.h + include/allegro5/threads.h + include/allegro5/tls.h + include/allegro5/touch_input.h + include/allegro5/timer.h + include/allegro5/transformations.h + include/allegro5/utf8.h + include/allegro5/allegro_direct3d.h + include/allegro5/allegro_opengl.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_INLINE_FILES + include/allegro5/inline/fmaths.inl + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_INTERNAL_FILES + # Only files which need to be installed. + include/allegro5/internal/alconfig.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_OPENGL_FILES + include/allegro5/opengl/gl_ext.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_OPENGL_GLEXT_FILES + include/allegro5/opengl/GLext/gl_ext_alias.h + include/allegro5/opengl/GLext/gl_ext_defs.h + include/allegro5/opengl/GLext/glx_ext_alias.h + include/allegro5/opengl/GLext/glx_ext_defs.h + include/allegro5/opengl/GLext/wgl_ext_alias.h + include/allegro5/opengl/GLext/wgl_ext_defs.h + include/allegro5/opengl/GLext/gl_ext_api.h + include/allegro5/opengl/GLext/gl_ext_list.h + include/allegro5/opengl/GLext/glx_ext_api.h + include/allegro5/opengl/GLext/glx_ext_list.h + include/allegro5/opengl/GLext/wgl_ext_api.h + include/allegro5/opengl/GLext/wgl_ext_list.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES + # Only files which need to be installed. + include/allegro5/platform/alandroid.h + include/allegro5/platform/alandroidcfg.h + include/allegro5/platform/albcc32.h + include/allegro5/platform/aliphone.h + include/allegro5/platform/aliphonecfg.h + include/allegro5/platform/almngw32.h + include/allegro5/platform/almsvc.h + include/allegro5/platform/alosx.h + include/allegro5/platform/alosxcfg.h + include/allegro5/platform/alraspberrypi.h + include/allegro5/platform/alraspberrypicfg.h + include/allegro5/platform/alucfg.h + include/allegro5/platform/alunix.h + include/allegro5/platform/alwatcom.h + include/allegro5/platform/alwin.h + include/allegro5/platform/astdbool.h + include/allegro5/platform/astdint.h + include/allegro5/platform/allegro_sdl_config.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_WINDOWS_FILES + include/allegro5/allegro_windows.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_MACOSX_FILES + include/allegro5/allegro_osx.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_IPHONE_FILES + include/allegro5/allegro_iphone.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_ANDROID_FILES + include/allegro5/allegro_android.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES_GENERATED + include/allegro5/platform/alplatf.h + ) + +set(ALLEGRO_INCLUDE_ALLEGRO_X_FILES + include/allegro5/allegro_x.h + ) diff --git a/allegro/cmake/FindCg.cmake b/allegro/cmake/FindCg.cmake new file mode 100644 index 00000000..f6a5e68e --- /dev/null +++ b/allegro/cmake/FindCg.cmake @@ -0,0 +1,144 @@ +# NVIDIA Texture Tools 2.0 is licensed under the MIT license. +# Copyright (c) 2007 NVIDIA Corporation + +# +# Try to find NVIDIA's Cg compiler, runtime libraries, and include path. +# Once done this will define +# +# CG_FOUND =system has NVIDIA Cg and it can be used. +# CG_INCLUDE_PATH = directory where cg.h resides +# CG_LIBRARY = full path to libCg.so (Cg.DLL on win32) +# CG_GL_LIBRARY = full path to libCgGL.so (CgGL.dll on win32) +# CG_D3D9_LIBRARY = full path to cgD3D9.dll +# CG_COMPILER = full path to cgc (cgc.exe on win32) +# + +# On OSX default to using the framework version of Cg. + +IF (APPLE) + INCLUDE(${CMAKE_ROOT}/Modules/CMakeFindFrameworks.cmake) + SET(CG_FRAMEWORK_INCLUDES) + CMAKE_FIND_FRAMEWORKS(Cg) + IF (Cg_FRAMEWORKS) + FOREACH(dir ${Cg_FRAMEWORKS}) + SET(CG_FRAMEWORK_INCLUDES ${CG_FRAMEWORK_INCLUDES} + ${dir}/Headers ${dir}/PrivateHeaders) + ENDFOREACH(dir) + + # Find the include dir + FIND_PATH(CG_INCLUDE_PATH cg.h + ${CG_FRAMEWORK_INCLUDES} + ) + + # Since we are using Cg framework, we must link to it. + # Note, we use weak linking, so that it works even when Cg is not available. + SET(CG_LIBRARY "-weak_framework Cg" CACHE STRING "Cg library") + SET(CG_GL_LIBRARY "-weak_framework Cg" CACHE STRING "Cg GL library") + SET(CG_D3D9_LIBRARY "-weak_framework Cg" CACHE STRING "Cg D3D9 library") + ENDIF (Cg_FRAMEWORKS) + FIND_PROGRAM(CG_COMPILER cgc + /usr/bin + /usr/local/bin + DOC "The Cg compiler" + ) +ELSE (APPLE) + IF (WIN32) + FIND_PROGRAM( CG_COMPILER cgc + $ENV{CG_BIN_PATH} + $ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/bin + $ENV{PROGRAMFILES}/Cg + ${PROJECT_SOURCE_DIR}/../Cg + DOC "The Cg Compiler" + ) + IF (CG_COMPILER) + GET_FILENAME_COMPONENT(CG_COMPILER_DIR ${CG_COMPILER} PATH) + GET_FILENAME_COMPONENT(CG_COMPILER_SUPER_DIR ${CG_COMPILER_DIR} PATH) + ELSE (CG_COMPILER) + SET (CG_COMPILER_DIR .) + SET (CG_COMPILER_SUPER_DIR ..) + ENDIF (CG_COMPILER) + FIND_PATH( CG_INCLUDE_PATH Cg/cg.h + $ENV{CG_INC_PATH} + $ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/include + $ENV{PROGRAMFILES}/Cg + ${PROJECT_SOURCE_DIR}/../Cg + ${CG_COMPILER_SUPER_DIR}/include + ${CG_COMPILER_DIR} + DOC "The directory where Cg/cg.h resides" + ) + FIND_LIBRARY( CG_LIBRARY + NAMES Cg + PATHS + $ENV{CG_LIB_PATH} + $ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib + $ENV{PROGRAMFILES}/Cg + ${PROJECT_SOURCE_DIR}/../Cg + ${CG_COMPILER_SUPER_DIR}/lib + ${CG_COMPILER_DIR} + DOC "The Cg runtime library" + ) + FIND_LIBRARY( CG_GL_LIBRARY + NAMES CgGL + PATHS + $ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib + $ENV{PROGRAMFILES}/Cg + ${PROJECT_SOURCE_DIR}/../Cg + ${CG_COMPILER_SUPER_DIR}/lib + ${CG_COMPILER_DIR} + DOC "The Cg GL runtime library" + ) + FIND_LIBRARY( CG_D3D9_LIBRARY + NAMES cgD3D9 + PATHS + $ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib + $ENV{PROGRAMFILES}/Cg + ${PROJECT_SOURCE_DIR}/../Cg + ${CG_COMPILER_SUPER_DIR}/lib + ${CG_COMPILER_DIR} + DOC "The Cg D3D9 runtime library" + ) + ELSE (WIN32) + FIND_PROGRAM( CG_COMPILER cgc + /usr/bin + /usr/local/bin + DOC "The Cg Compiler" + ) + GET_FILENAME_COMPONENT(CG_COMPILER_DIR "${CG_COMPILER}" PATH) + GET_FILENAME_COMPONENT(CG_COMPILER_SUPER_DIR "${CG_COMPILER_DIR}" PATH) + FIND_PATH( CG_INCLUDE_PATH Cg/cg.h + /usr/include + /usr/local/include + ${CG_COMPILER_SUPER_DIR}/include + DOC "The directory where Cg/cg.h resides" + ) + FIND_LIBRARY( CG_LIBRARY Cg + PATHS + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + ${CG_COMPILER_SUPER_DIR}/lib64 + ${CG_COMPILER_SUPER_DIR}/lib + DOC "The Cg runtime library" + ) + SET(CG_LIBRARY ${CG_LIBRARY} -lpthread) + FIND_LIBRARY( CG_GL_LIBRARY CgGL + PATHS + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + ${CG_COMPILER_SUPER_DIR}/lib64 + ${CG_COMPILER_SUPER_DIR}/lib + DOC "The Cg runtime library" + ) + ENDIF (WIN32) +ENDIF (APPLE) + +IF (CG_INCLUDE_PATH) + SET( CG_FOUND 1 CACHE STRING "Set to 1 if CG is found, 0 otherwise") +ELSE (CG_INCLUDE_PATH) + SET( CG_FOUND 0 CACHE STRING "Set to 1 if CG is found, 0 otherwise") +ENDIF (CG_INCLUDE_PATH) + +MARK_AS_ADVANCED( CG_FOUND ) diff --git a/allegro/cmake/FindDUMB.cmake b/allegro/cmake/FindDUMB.cmake new file mode 100644 index 00000000..644bcc89 --- /dev/null +++ b/allegro/cmake/FindDUMB.cmake @@ -0,0 +1,32 @@ +# - Find DUMB +# Find the native DUMB includes and libraries +# +# DUMB_INCLUDE_DIR - where to find DUMB headers. +# DUMB_LIBRARIES - List of libraries when using libDUMB. +# DUMB_FOUND - True if libDUMB found. + +if(DUMB_INCLUDE_DIR) + # Already in cache, be silent + set(DUMB_FIND_QUIETLY TRUE) +endif(DUMB_INCLUDE_DIR) + +find_path(DUMB_INCLUDE_DIR dumb.h) + +find_library(DUMB_LIBRARY NAMES dumb libdumb dumb_static libdumb_static) + +# Handle the QUIETLY and REQUIRED arguments and set DUMB_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(DUMB DEFAULT_MSG + DUMB_INCLUDE_DIR DUMB_LIBRARY) + +if(DUMB_FOUND) + set(DUMB_LIBRARIES ${DUMB_LIBRARY}) + if(NOT MSVC) + set(DUMB_LIBRARIES ${DUMB_LIBRARIES};m) + endif() +else(DUMB_FOUND) + set(DUMB_LIBRARIES) +endif(DUMB_FOUND) + +mark_as_advanced(DUMB_INCLUDE_DIR DUMB_LIBRARY) diff --git a/allegro/cmake/FindDXGuid.cmake b/allegro/cmake/FindDXGuid.cmake new file mode 100644 index 00000000..504cb3f4 --- /dev/null +++ b/allegro/cmake/FindDXGuid.cmake @@ -0,0 +1,24 @@ +# - Find dxguid +# Find the dxguid libraries +# +# DXGUID_LIBRARIES - List of libraries +# DXGUID_FOUND - True if dxguid found. + +find_library(DXGUID_LIBRARY + NAMES dxguid + HINTS "$ENV{DXSDK_DIR}/Lib/$ENV{PROCESSOR_ARCHITECTURE}" + ) + +# Handle the QUIETLY and REQUIRED arguments and set DXGUID_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(DXGUID DEFAULT_MSG + DXGUID_LIBRARY) + +if(DXGUID_FOUND) + set(DXGUID_LIBRARIES ${DXGUID_LIBRARY}) +else(DXGUID_FOUND) + set(DXGUID_LIBRARIES) +endif(DXGUID_FOUND) + +mark_as_advanced(DXGUID_INCLUDE_DIR DXGUID_LIBRARY) diff --git a/allegro/cmake/FindDirectX.cmake b/allegro/cmake/FindDirectX.cmake new file mode 100644 index 00000000..17a780e3 --- /dev/null +++ b/allegro/cmake/FindDirectX.cmake @@ -0,0 +1,104 @@ +# Finds various DirectX components: +# +# DINPUT +# D3D9 +# D3DX9 +# DSOUND +# XINPUT +# +# For each component, this will fill out the following variables +# +# ${COMPONENT}_INCLUDE_DIR - Where to find the component header. +# ${COMPONENT}_LIBRARIES - List of libraries when using the component. +# ${COMPONENT}_FOUND - True if the component is found. + +macro(check_winsdk_root_dir key) + get_filename_component(CANDIDATE ${key} ABSOLUTE) + if (EXISTS ${CANDIDATE}) + set(WINSDK_ROOT_DIR ${CANDIDATE}) + endif() +endmacro() + +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Microsoft SDKs\\\\Windows\\\\v7.0;InstallationFolder]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Microsoft SDKs\\\\Windows\\\\v7.0A;InstallationFolder]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Microsoft SDKs\\\\Windows\\\\v7.1;InstallationFolder]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Microsoft SDKs\\\\Windows\\\\v7.1A;InstallationFolder]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows Kits\\\\Installed Roots;KitsRoot]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows Kits\\\\Installed Roots;KitsRoot81]") + +if(CMAKE_CL_64 OR CMAKE_SIZEOF_VOID_P EQUAL 8) + set(MINGW_W64_HINT "x86_64-w64-mingw32") + set(PROCESSOR_SUFFIX "x64") +else() + set(MINGW_W64_HINT "i686-w64-mingw32") + set(PROCESSOR_SUFFIX "x86") +endif() + +macro(find_component name header library) + if(${name}_INCLUDE_DIR) + # Already in cache, be silent + set(${name}_FIND_QUIETLY TRUE) + endif(${name}_INCLUDE_DIR) + + if(MSVC) + find_path(${name}_INCLUDE_DIR ${header} + PATH_SUFFIXES + Include + Include/um + Include/shared + PATHS + "$ENV{DXSDK_DIR}" + ${WINSDK_ROOT_DIR} + ) + + find_library(${name}_LIBRARY + NAMES lib${library} ${library} + PATH_SUFFIXES + Lib + Lib/${PROCESSOR_SUFFIX} + Lib/winv6.3/um/${PROCESSOR_SUFFIX} + Lib/Win8/um/${PROCESSOR_SUFFIX} + PATHS + "$ENV{DXSDK_DIR}" + ${WINSDK_ROOT_DIR} + ) + else() + find_path(${name}_INCLUDE_DIR ${header} + PATH_SUFFIXES + Include + ${MINGW_W64_HINT}/include + PATHS + "$ENV{DXSDK_DIR}" + ) + + find_library(${name}_LIBRARY + NAMES lib${library} ${library} + PATH_SUFFIXES + ${MINGW_W64_HINT}/lib + Lib + Lib/${PROCESSOR_SUFFIX} + PATHS + "$ENV{DXSDK_DIR}" + ) + endif() + + # Handle the QUIETLY and REQUIRED arguments and set ${name}_FOUND to TRUE if + # all listed variables are TRUE. + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(${name} DEFAULT_MSG + ${name}_INCLUDE_DIR ${name}_LIBRARY) + + if(${name}_FOUND) + set(${name}_LIBRARIES ${${name}_LIBRARY}) + else() + set(${name}_LIBRARIES) + endif() + + mark_as_advanced(${name}_INCLUDE_DIR ${name}_LIBRARY) +endmacro() + +find_component(DINPUT dinput.h dinput8) +find_component(D3D9 d3d9.h d3d9) +find_component(D3DX9 d3dx9.h d3dx9) +find_component(DSOUND dsound.h dsound) +find_component(XINPUT xinput.h xinput) diff --git a/allegro/cmake/FindENet.cmake b/allegro/cmake/FindENet.cmake new file mode 100644 index 00000000..b05f1887 --- /dev/null +++ b/allegro/cmake/FindENet.cmake @@ -0,0 +1,29 @@ +# - Find ENet +# Find the native ENet includes and libraries +# +# ENET_INCLUDE_DIR - where to find ENet headers. +# ENET_LIBRARIES - List of libraries when using libenet. +# ENET_FOUND - True if libenet found. + +if(ENET_INCLUDE_DIR) + # Already in cache, be silent + set(ENET_FIND_QUIETLY TRUE) +endif(ENET_INCLUDE_DIR) + +find_path(ENET_INCLUDE_DIR enet/enet.h) + +find_library(ENET_LIBRARY NAMES enet enet_static libenet libenet_static) + +# Handle the QUIETLY and REQUIRED arguments and set ENET_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ENET DEFAULT_MSG + ENET_INCLUDE_DIR ENET_LIBRARY) + +if(ENET_FOUND) + set(ENET_LIBRARIES ${ENET_LIBRARY}) +else(ENET_FOUND) + set(ENET_LIBRARIES) +endif(ENET_FOUND) + +mark_as_advanced(ENET_INCLUDE_DIR ENET_LIBRARY) diff --git a/allegro/cmake/FindFLAC.cmake b/allegro/cmake/FindFLAC.cmake new file mode 100644 index 00000000..7de8a06c --- /dev/null +++ b/allegro/cmake/FindFLAC.cmake @@ -0,0 +1,35 @@ +# - Find FLAC +# Find the native FLAC includes and libraries +# +# FLAC_INCLUDE_DIR - where to find FLAC headers. +# FLAC_LIBRARIES - List of libraries when using libFLAC. +# FLAC_FOUND - True if libFLAC found. + +if(FLAC_INCLUDE_DIR) + # Already in cache, be silent + set(FLAC_FIND_QUIETLY TRUE) +endif(FLAC_INCLUDE_DIR) + +find_path(FLAC_INCLUDE_DIR FLAC/stream_decoder.h) + +# MSVC built libraries can name them *_static, which is good as it +# distinguishes import libraries from static libraries with the same extension. +find_library(FLAC_LIBRARY NAMES FLAC libFLAC libFLAC_dynamic libFLAC_static) +find_library(OGG_LIBRARY NAMES ogg ogg_static libogg libogg_static) + +# Handle the QUIETLY and REQUIRED arguments and set FLAC_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FLAC DEFAULT_MSG + FLAC_INCLUDE_DIR OGG_LIBRARY FLAC_LIBRARY) + +if(FLAC_FOUND) + set(FLAC_LIBRARIES ${FLAC_LIBRARY} ${OGG_LIBRARY}) + if(WIN32) + set(FLAC_LIBRARIES ${FLAC_LIBRARIES} wsock32) + endif(WIN32) +else(FLAC_FOUND) + set(FLAC_LIBRARIES) +endif(FLAC_FOUND) + +mark_as_advanced(FLAC_INCLUDE_DIR FLAC_LIBRARY) diff --git a/allegro/cmake/FindFreeImage.cmake b/allegro/cmake/FindFreeImage.cmake new file mode 100644 index 00000000..22a65eaa --- /dev/null +++ b/allegro/cmake/FindFreeImage.cmake @@ -0,0 +1,54 @@ +# +# Try to find the FreeImage library and include path. +# Once done this will define +# +# FREEIMAGE_FOUND +# FREEIMAGE_INCLUDE_PATH +# FREEIMAGE_LIBRARY +# + +IF (WIN32) + FIND_PATH( FREEIMAGE_INCLUDE_PATH FreeImage.h + $ENV{FI_HOME}/include + ${FREEIMAGE_ROOT_DIR}/include + ${FREEIMAGE_ROOT_DIR} + DOC "The directory where FreeImage.h resides") + FIND_LIBRARY( FREEIMAGE_LIBRARY + NAMES FreeImage freeimage + PATHS + $ENV{FI_HOME}/lib/$ENV{PROCESSOR_ARCHITECTURE} + ${FREEIMAGE_ROOT_DIR}/lib + ${FREEIMAGE_ROOT_DIR} + DOC "The FreeImage library") +ELSE (WIN32) + FIND_PATH( FREEIMAGE_INCLUDE_PATH FreeImage.h + /usr/include + /usr/local/include + /sw/include + /opt/local/include + DOC "The directory where FreeImage.h resides") + FIND_LIBRARY( FREEIMAGE_LIBRARY + NAMES FreeImage freeimage + PATHS + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /sw/lib + /opt/local/lib + DOC "The FreeImage library") +ENDIF (WIN32) + +SET(FREEIMAGE_LIBRARIES ${FREEIMAGE_LIBRARY}) + +IF (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY) + SET( FREEIMAGE_FOUND TRUE CACHE INTERNAL "Set to TRUE if FreeImage is found, FALSE otherwise") +ELSE (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY) + SET( FREEIMAGE_FOUND FALSE CACHE INTERNAL "Set to TRUE if FreeImage is found, FALSE otherwise") +ENDIF (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY) + +MARK_AS_ADVANCED( + FREEIMAGE_LIBRARY + FREEIMAGE_LIBRARIES + FREEIMAGE_INCLUDE_PATH) + diff --git a/allegro/cmake/FindGDIPLUS.cmake b/allegro/cmake/FindGDIPLUS.cmake new file mode 100644 index 00000000..56956cdf --- /dev/null +++ b/allegro/cmake/FindGDIPLUS.cmake @@ -0,0 +1,63 @@ +# - Find GDI+ +# Find the GDI+ includes and libraries +# +# GDIPLUS_INCLUDE_DIR - where to find gdiplus.h +# GDIPLUS_LIBRARIES - List of libraries when using GDI+. +# GDIPLUS_FOUND - True if GDI+ found. + +if(GDIPLUS_INCLUDE_DIR) + # Already in cache, be silent + set(GDIPLUS_FIND_QUIETLY TRUE) +endif(GDIPLUS_INCLUDE_DIR) + +macro(check_winsdk_root_dir key) + get_filename_component(CANDIDATE ${key} ABSOLUTE) + if (EXISTS ${CANDIDATE}) + set(WINSDK_ROOT_DIR ${CANDIDATE}) + endif() +endmacro() + +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Microsoft SDKs\\\\Windows\\\\v7.0;InstallationFolder]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Microsoft SDKs\\\\Windows\\\\v7.0A;InstallationFolder]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Microsoft SDKs\\\\Windows\\\\v7.1;InstallationFolder]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Microsoft SDKs\\\\Windows\\\\v7.1A;InstallationFolder]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows Kits\\\\Installed Roots;KitsRoot]") +check_winsdk_root_dir("[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows Kits\\\\Installed Roots;KitsRoot81]") + +find_path(GDIPLUS_INCLUDE_DIR + NAMES + GdiPlus.h + gdiplus.h + PATH_SUFFIXES + Include + Include/um + Include/shared + PATHS + "${WINSDK_ROOT_DIR}" + ) +if(EXISTS ${GDIPLUS_INCLUDE_DIR}/GdiPlus.h) + set(GDIPLUS_LOWERCASE 0 CACHE INTERNAL "Is GdiPlus.h spelt with lowercase?") +else() + set(GDIPLUS_LOWERCASE 1 CACHE INTERNAL "Is GdiPlus.h spelt with lowercase?") +endif() + +if (MINGW) + find_library(GDIPLUS_LIBRARY NAMES libgdiplus gdiplus) +else(MINGW) + set(GDIPLUS_LIBRARY gdiplus) +endif(MINGW) + + +# Handle the QUIETLY and REQUIRED arguments and set GDIPLUS_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GDIPLUS DEFAULT_MSG + GDIPLUS_INCLUDE_DIR GDIPLUS_LIBRARY) + +if(GDIPLUS_FOUND) + set(GDIPLUS_LIBRARIES ${GDIPLUS_LIBRARY}) +else(GDIPLUS_FOUND) + set(GDIPLUS_LIBRARIES) +endif(GDIPLUS_FOUND) + +mark_as_advanced(GDIPLUS_INCLUDE_DIR GDIPLUS_LIBRARY GDIPLUS_LOWERCASE) diff --git a/allegro/cmake/FindHarfBuzz.cmake b/allegro/cmake/FindHarfBuzz.cmake new file mode 100644 index 00000000..f94d17c3 --- /dev/null +++ b/allegro/cmake/FindHarfBuzz.cmake @@ -0,0 +1,87 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# FindHarfBuzz +# ------------ +# +# Find the HarfBuzz text shaping engine includes and library. +# +# Imported Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following :prop_tgt:`IMPORTED` target: +# +# ``HarfBuzz::HarfBuzz`` +# The Harfbuzz ``harfbuzz`` library, if found +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module will set the following variables in your project: +# +# ``HARFBUZZ_FOUND`` +# true if the HarfBuzz headers and libraries were found +# ``HARFBUZZ_INCLUDE_DIRS`` +# directories containing the Harfbuzz headers. +# ``HARFBUZZ_LIBRARIES`` +# the library to link against +# ``HARFBUZZ_VERSION_STRING`` +# the version of harfbuzz found + +# Created by Ebrahim Byagowi. + +set(HARFBUZZ_FIND_ARGS + HINTS + ENV HARFBUZZ_DIR +) + +find_path( + HARFBUZZ_INCLUDE_DIRS + hb.h + ${HARFBUZZ_FIND_ARGS} + PATH_SUFFIXES + src + harfbuzz +) + +if(NOT HARFBUZZ_LIBRARY) + find_library(HARFBUZZ_LIBRARY + NAMES + harfbuzz + libharfbuzz + ${HARFBUZZ_FIND_ARGS} + PATH_SUFFIXES + lib + ) +else() + # on Windows, ensure paths are in canonical format (forward slahes): + file(TO_CMAKE_PATH "${HARFBUZZ_LIBRARY}" HARFBUZZ_LIBRARY) +endif() + +unset(HARFBUZZ_FIND_ARGS) + +# set the user variables +set(HARFBUZZ_LIBRARIES "${HARFBUZZ_LIBRARY}") + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args( + HarfBuzz + REQUIRED_VARS + HARFBUZZ_LIBRARY + HARFBUZZ_INCLUDE_DIRS + VERSION_VAR + HARFBUZZ_VERSION_STRING +) + +if(HARFBUZZ_FOUND) + if(NOT TARGET HarfBuzz::HarfBuzz) + add_library(HarfBuzz::HarfBuzz UNKNOWN IMPORTED) + set_target_properties(HarfBuzz::HarfBuzz PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${HARFBUZZ_INCLUDE_DIRS}") + set_target_properties(HarfBuzz::HarfBuzz PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${HARFBUZZ_LIBRARY}") + endif() +endif() diff --git a/allegro/cmake/FindMiniMP3.cmake b/allegro/cmake/FindMiniMP3.cmake new file mode 100644 index 00000000..a2a124a3 --- /dev/null +++ b/allegro/cmake/FindMiniMP3.cmake @@ -0,0 +1,15 @@ +# - Try to find MiniMP3 (https://github.com/lieff/minimp3) +# Once done, this will define +# +# MINIMP3_FOUND - system has MiniMP3 +# MINIMP3_INCLUDE_DIRS - the MiniMP3 include directories + +# Look for the header file. +find_path(MINIMP3_INCLUDE_DIRS + NAMES minimp3.h minimp3_ex.h +) +mark_as_advanced(MINIMP3_INCLUDE_DIRS) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MiniMP3 REQUIRED_VARS MINIMP3_INCLUDE_DIRS + FOUND_VAR MINIMP3_FOUND) diff --git a/allegro/cmake/FindOgg.cmake b/allegro/cmake/FindOgg.cmake new file mode 100644 index 00000000..1a4efcec --- /dev/null +++ b/allegro/cmake/FindOgg.cmake @@ -0,0 +1,24 @@ +# - Find ogg +# Find the native ogg includes and libraries +# +# OGG_INCLUDE_DIR - where to find ogg.h, etc. +# OGG_LIBRARIES - List of libraries when using ogg. +# OGG_FOUND - True if ogg found. + +if(OGG_INCLUDE_DIR) + # Already in cache, be silent + set(OGG_FIND_QUIETLY TRUE) +endif(OGG_INCLUDE_DIR) +find_path(OGG_INCLUDE_DIR ogg/ogg.h) +# MSVC built ogg may be named ogg_static. +# The provided project files name the library with the lib prefix. +find_library(OGG_LIBRARY NAMES ogg ogg_static libogg libogg_static) +# Handle the QUIETLY and REQUIRED arguments and set OGG_FOUND +# to TRUE if all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OGG DEFAULT_MSG OGG_INCLUDE_DIR OGG_LIBRARY) + +set(OGG_LIBRARIES ${OGG_LIBRARY}) + +mark_as_advanced(OGG_INCLUDE_DIR) +mark_as_advanced(OGG_LIBRARY) diff --git a/allegro/cmake/FindOpenGLES1.cmake b/allegro/cmake/FindOpenGLES1.cmake new file mode 100644 index 00000000..c2204347 --- /dev/null +++ b/allegro/cmake/FindOpenGLES1.cmake @@ -0,0 +1,26 @@ +# - Find OpenGLES +# Find the native OpenGLES includes and libraries +# +# OPENGLES1_INCLUDE_DIR - where to find GLES/gl.h, etc. +# OPENGLES1_LIBRARIES - List of libraries when using OpenGLES. +# OPENGLES1_FOUND - True if OpenGLES found. + +if(OPENGLES1_INCLUDE_DIR) + # Already in cache, be silent + set(OPENGLES1_FIND_QUIETLY TRUE) +endif(OPENGLES1_INCLUDE_DIR) + +find_path(OPENGLES1_INCLUDE_DIR GLES/gl.h) + +find_library(OPENGLES1_gl_LIBRARY NAMES GLESv1_CM) + +# Handle the QUIETLY and REQUIRED arguments and set OPENGLES1_FOUND +# to TRUE if all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OPENGLES1 DEFAULT_MSG + OPENGLES1_INCLUDE_DIR OPENGLES1_gl_LIBRARY) + +set(OPENGLES1_LIBRARIES ${OPENGLES1_gl_LIBRARY}) + +mark_as_advanced(OPENGLES1_INCLUDE_DIR) +mark_as_advanced(OPENGLES1_gl_LIBRARY) diff --git a/allegro/cmake/FindOpenGLES2.cmake b/allegro/cmake/FindOpenGLES2.cmake new file mode 100644 index 00000000..e33acc1c --- /dev/null +++ b/allegro/cmake/FindOpenGLES2.cmake @@ -0,0 +1,36 @@ +# - Find OpenGLES2 +# Find the native OpenGLES2 includes and libraries +# +# OPENGLES2_INCLUDE_DIR - where to find GLES2/gl.h, etc. +# OPENGLES2_LIBRARIES - List of libraries when using OpenGLES. +# OPENGLES2_FOUND - True if OpenGLES found. + +if(OPENGLES2_INCLUDE_DIR) + # Already in cache, be silent + set(OPENGLES2_FIND_QUIETLY TRUE) +endif(OPENGLES2_INCLUDE_DIR) + +find_path(OPENGLES2_INCLUDE_DIR GLES2/gl2.h) + +find_library(OPENGLES2_gl_LIBRARY NAMES GLESv2) +find_library(OPENGLES2_egl_LIBRARY NAMES EGL) + +# Handle the QUIETLY and REQUIRED arguments and set OPENGLES2_FOUND +# to TRUE if all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OPENGLES2 DEFAULT_MSG + OPENGLES2_INCLUDE_DIR OPENGLES2_gl_LIBRARY OPENGLES2_egl_LIBRARY) + +set(OPENGLES2_LIBRARIES ${OPENGLES2_gl_LIBRARY} ${OPENGLES2_egl_LIBRARY}) + +if(ALLEGRO_RASPBERRYPI) + if(EXISTS "/opt/vc/lib/libbrcmGLESv2.so") + set(OPENGLES2_LIBRARIES "/opt/vc/lib/libbrcmGLESv2.so;/opt/vc/lib/libbrcmEGL.so;/opt/vc/lib/libbcm_host.so") + else() + set(OPENGLES2_LIBRARIES "/opt/vc/lib/libGLESv2.so;/opt/vc/lib/libEGL.so;/opt/vc/lib/libbcm_host.so") + endif() +endif(ALLEGRO_RASPBERRYPI) + +mark_as_advanced(OPENGLES2_INCLUDE_DIR) +mark_as_advanced(OPENGLES2_gl_LIBRARY) +mark_as_advanced(OPENGLES2_egl_LIBRARY) diff --git a/allegro/cmake/FindOpenSL.cmake b/allegro/cmake/FindOpenSL.cmake new file mode 100644 index 00000000..f0d8d624 --- /dev/null +++ b/allegro/cmake/FindOpenSL.cmake @@ -0,0 +1,29 @@ +# - Find OpenSL (actually OpenSLES) +# Find the OpenSLES includes and libraries +# +# OPENSL_INCLUDE_DIR - where to find dsound.h +# OPENSL_LIBRARIES - List of libraries when using dsound. +# OPENSL_FOUND - True if dsound found. + +if(OPENSL_INCLUDE_DIR) + # Already in cache, be silent + set(OPENSL_FIND_QUIETLY TRUE) +endif(OPENSL_INCLUDE_DIR) + +find_path(OPENSL_INCLUDE_DIR SLES/OpenSLES.h) + +find_library(OPENSL_LIBRARY NAMES OpenSLES) + +# Handle the QUIETLY and REQUIRED arguments and set OPENSL_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OPENSL DEFAULT_MSG + OPENSL_INCLUDE_DIR OPENSL_LIBRARY) + +if(OPENSL_FOUND) + set(OPENSL_LIBRARIES ${OPENSL_LIBRARY}) +else(OPENSL_FOUND) + set(OPENSL_LIBRARIES) +endif(OPENSL_FOUND) + +mark_as_advanced(OPENSL_INCLUDE_DIR OPENSL_LIBRARY) diff --git a/allegro/cmake/FindOpus.cmake b/allegro/cmake/FindOpus.cmake new file mode 100644 index 00000000..771d4d04 --- /dev/null +++ b/allegro/cmake/FindOpus.cmake @@ -0,0 +1,38 @@ +# - Find opus +# Find the native opus includes and libraries +# +# OPUS_INCLUDE_DIR - where to find opus.h, etc. +# OPUS_LIBRARIES - List of libraries when using opus(file). +# OPUS_FOUND - True if opus found. + +if(OPUS_INCLUDE_DIR) + # Already in cache, be silent + set(OPUS_FIND_QUIETLY TRUE) +endif(OPUS_INCLUDE_DIR) + +find_package(Ogg) +if(OGG_FOUND) + find_path(OPUS_INCLUDE_DIR opusfile.h PATH_SUFFIXES opus) + # MSVC built opus may be named opus_static + # The provided project files name the library with the lib prefix. + find_library(OPUS_LIBRARY + NAMES opus opus_static libopus libopus_static) + find_library(OPUSFILE_LIBRARY + NAMES opusfile opusfile_static libopusfile libopusfile_static) + # Handle the QUIETLY and REQUIRED arguments and set OPUS_FOUND + # to TRUE if all listed variables are TRUE. + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(OPUS DEFAULT_MSG + OPUS_INCLUDE_DIR + OPUS_LIBRARY OPUSFILE_LIBRARY) +endif(OGG_FOUND) + +if(OPUS_FOUND) + set(OPUS_LIBRARIES ${OPUSFILE_LIBRARY} ${OPUS_LIBRARY} + ${OGG_LIBRARY}) +else(OPUS_FOUND) + set(OPUS_LIBRARIES) +endif(OPUS_FOUND) + +mark_as_advanced(OPUS_INCLUDE_DIR) +mark_as_advanced(OPUS_LIBRARY OPUSFILE_LIBRARY) diff --git a/allegro/cmake/FindSDL2.cmake b/allegro/cmake/FindSDL2.cmake new file mode 100644 index 00000000..acf64502 --- /dev/null +++ b/allegro/cmake/FindSDL2.cmake @@ -0,0 +1,183 @@ +# Locate SDL2 library +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDLmain.h and SDLmain.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL convention +# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). + +#============================================================================= +# CMake - Cross Platform Makefile Generator +# Copyright 2000-2017 Kitware, Inc. and Contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Kitware, Inc. nor the names of Contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +SET(SDL2_SEARCH_PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS ${SDL2_SEARCH_PATHS} +) + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS ${SDL2_SEARCH_PATHS} +) + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS ${SDL2_SEARCH_PATHS} + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/allegro/cmake/FindTheora.cmake b/allegro/cmake/FindTheora.cmake new file mode 100644 index 00000000..629f16c8 --- /dev/null +++ b/allegro/cmake/FindTheora.cmake @@ -0,0 +1,39 @@ +# - Find theora +# Find the native theora includes and libraries +# +# THEORA_INCLUDE_DIR - where to find theora.h, etc. +# THEORA_LIBRARIES - List of libraries when using theora. +# THEORA_FOUND - True if theora found. + +if(THEORA_INCLUDE_DIR) + # Already in cache, be silent + set(THEORA_FIND_QUIETLY TRUE) +endif(THEORA_INCLUDE_DIR) + +find_package(Ogg) +if(OGG_FOUND) + find_path(THEORA_INCLUDE_DIR theora/theora.h) + # MSVC built theora may be named *_static + # The provided project files name the library with the lib prefix. + find_library(THEORA_LIBRARY NAMES + theoradec theoradec_static + libtheoradec libtheoradec_static + theora theora_static + libtheora libtheora_static + ) + # Handle the QUIETLY and REQUIRED arguments and set THEORA_FOUND + # to TRUE if all listed variables are TRUE. + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(THEORA DEFAULT_MSG + THEORA_INCLUDE_DIR THEORA_LIBRARY) +endif(OGG_FOUND) + +if(THEORA_FOUND) + set(THEORA_LIBRARIES ${THEORA_LIBRARY} ${OGG_LIBRARY}) +else(THEORA_FOUND) + set(THEORA_LIBRARIES) +endif(THEORA_FOUND) + +mark_as_advanced(THEORA_INCLUDE_DIR) +mark_as_advanced(THEORA_LIBRARY) + diff --git a/allegro/cmake/FindTremor.cmake b/allegro/cmake/FindTremor.cmake new file mode 100644 index 00000000..510712bc --- /dev/null +++ b/allegro/cmake/FindTremor.cmake @@ -0,0 +1,29 @@ +# - Find Tremor +# +# TREMOR_INCLUDE_DIR - where to find Tremor headers. +# TREMOR_LIBRAY - List of libraries when using libTremor. +# TREMOR_FOUND - True if Tremor found. + +if(TREMOR_INCLUDE_DIR) + # Already in cache, be silent + set(TREMOR_FIND_QUIETLY TRUE) +endif(TREMOR_INCLUDE_DIR) + +find_path(TREMOR_INCLUDE_DIR tremor/ivorbisfile.h) +find_library(TREMOR_LIBRARY NAMES vorbisidec) + +# Handle the QUIETLY and REQUIRED arguments and set TREMOR_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(TREMOR DEFAULT_MSG + TREMOR_INCLUDE_DIR TREMOR_LIBRARY) + +mark_as_advanced(TREMOR_INCLUDE_DIR TREMOR_LIBRARY) + +if(TREMOR_FOUND) + set(TREMOR_LIBRARIES ${TREMOR_LIBRARY} ${OGG_LIBRARY}) +else(TREMOR_FOUND) + set(TREMOR_LIBRARIES) +endif(TREMOR_FOUND) + +mark_as_advanced(TREMOR_INCLUDE_DIR TREMOR_LIBRARY) diff --git a/allegro/cmake/FindVorbis.cmake b/allegro/cmake/FindVorbis.cmake new file mode 100644 index 00000000..b183c3aa --- /dev/null +++ b/allegro/cmake/FindVorbis.cmake @@ -0,0 +1,39 @@ +# - Find vorbis +# Find the native vorbis includes and libraries +# +# VORBIS_INCLUDE_DIR - where to find vorbis.h, etc. +# VORBIS_LIBRARIES - List of libraries when using vorbis(file). +# VORBIS_FOUND - True if vorbis found. + +if(VORBIS_INCLUDE_DIR) + # Already in cache, be silent + set(VORBIS_FIND_QUIETLY TRUE) +endif(VORBIS_INCLUDE_DIR) + +find_package(Ogg) +if(OGG_FOUND) + find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h) + # MSVC built vorbis may be named vorbis_static + # The provided project files name the library with the lib prefix. + find_library(VORBIS_LIBRARY + NAMES vorbis vorbis_static libvorbis libvorbis_static) + find_library(VORBISFILE_LIBRARY + NAMES vorbisfile vorbisfile_static libvorbisfile libvorbisfile_static) + # Handle the QUIETLY and REQUIRED arguments and set VORBIS_FOUND + # to TRUE if all listed variables are TRUE. + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(VORBIS DEFAULT_MSG + VORBIS_INCLUDE_DIR + VORBIS_LIBRARY VORBISFILE_LIBRARY) +endif(OGG_FOUND) + +if(VORBIS_FOUND) + set(VORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} + ${OGG_LIBRARY}) +else(VORBIS_FOUND) + set(VORBIS_LIBRARIES) +endif(VORBIS_FOUND) + +mark_as_advanced(VORBIS_INCLUDE_DIR) +mark_as_advanced(VORBIS_LIBRARY VORBISFILE_LIBRARY) + diff --git a/allegro/cmake/FindWebP.cmake b/allegro/cmake/FindWebP.cmake new file mode 100644 index 00000000..969708ec --- /dev/null +++ b/allegro/cmake/FindWebP.cmake @@ -0,0 +1,52 @@ +# - Try to find WebP. +# Once done, this will define +# +# WEBP_FOUND - system has WebP. +# WEBP_INCLUDE_DIRS - the WebP. include directories +# WEBP_LIBRARIES - link these to use WebP. +# +# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org> +# Copyright (C) 2013 Igalia S.L. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS +# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +find_package(PkgConfig) +pkg_check_modules(PC_WEBP QUIET libwebp) + +# Look for the header file. +find_path(WEBP_INCLUDE_DIRS + NAMES webp/decode.h + HINTS ${PC_WEBP_INCLUDEDIR} ${PC_WEBP_INCLUDE_DIRS} +) +mark_as_advanced(WEBP_INCLUDE_DIRS) + +# Look for the library. +find_library( + WEBP_LIBRARIES + NAMES webp + HINTS ${PC_WEBP_LIBDIR} ${PC_WEBP_LIBRARY_DIRS} +) +mark_as_advanced(WEBP_LIBRARIES) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(WebP REQUIRED_VARS WEBP_INCLUDE_DIRS WEBP_LIBRARIES + FOUND_VAR WEBP_FOUND) diff --git a/allegro/cmake/Toolchain-iphone.cmake b/allegro/cmake/Toolchain-iphone.cmake new file mode 100644 index 00000000..1a534390 --- /dev/null +++ b/allegro/cmake/Toolchain-iphone.cmake @@ -0,0 +1,8 @@ +set (IPHONE 1) +set (ALLEGRO_CFG_OPENGLES 1) +set (IOS_PLATFORM "iphoneos" CACHE STRING "iOS platform (iphoneos or iphonesimulator)") +mark_as_advanced(IOS_PLATFORM) +set (CMAKE_OSX_SYSROOT "${IOS_PLATFORM}") + +set (CMAKE_MACOSX_BUNDLE YES) +set (CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") diff --git a/allegro/cmake/Toolchain-mingw.cmake b/allegro/cmake/Toolchain-mingw.cmake new file mode 100644 index 00000000..6dff20b7 --- /dev/null +++ b/allegro/cmake/Toolchain-mingw.cmake @@ -0,0 +1,71 @@ +# Use this command to build the Windows port of Allegro +# with a mingw cross compiler: +# +# cmake -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-mingw.cmake . +# +# or for out of source: +# +# cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw.cmake .. +# +# You will need at least CMake 2.6.0. +# +# Adjust the following paths to suit your environment. +# +# This file was based on http://www.cmake.org/Wiki/CmakeMingw + +# the name of the target operating system +set(CMAKE_SYSTEM_NAME Windows) + +# Assume the target architecture. +# XXX for some reason the value set here gets cleared before we reach the +# main CMakeLists.txt; see that file for a workaround. +# set(CMAKE_SYSTEM_PROCESSOR i686) + +# Which compilers to use for C and C++, and location of target +# environment. +if(EXISTS /usr/i586-mingw32msvc) + # First look in standard location as used by Debian/Ubuntu/etc. + set(CMAKE_C_COMPILER i586-mingw32msvc-gcc) + set(CMAKE_CXX_COMPILER i586-mingw32msvc-g++) + set(CMAKE_RC_COMPILER i586-mingw32msvc-windres) + set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc) +elseif(EXISTS /usr/i686-w64-mingw32) + # First look in standard location as used by Debian/Ubuntu/etc. + set(CMAKE_C_COMPILER i686-w64-mingw32-gcc) + set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) + set(CMAKE_RC_COMPILER i686-w64-mingw32-windres) + set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) + set(CMAKE_AR:FILEPATH /usr/bin/i686-w64-mingw32-ar) +elseif(EXISTS /opt/mingw) + # You can get a MinGW environment using the script at <http://mxe.cc>. + # It downloads and builds MinGW and most of the dependencies for you. + # You can use the toolchain file generated by MXE called `mxe-conf.cmake' + # or you can use this file by adjusting the above and following paths. + set(CMAKE_C_COMPILER /opt/mingw/usr/bin/i686-pc-mingw32-gcc) + set(CMAKE_CXX_COMPILER /opt/mingw/usr/bin/i686-pc-mingw32-g++) + set(CMAKE_RC_COMPILER /opt/mingw/usr/bin/i686-pc-mingw32-windres) + set(CMAKE_FIND_ROOT_PATH /opt/mingw/usr/i686-pc-mingw32) +else() + # Else fill in local path which the user will likely adjust. + # This is the location assumed by <http://www.libsdl.org/extras/win32/cross/> + set(CMAKE_C_COMPILER /usr/local/cross-tools/bin/i386-mingw32-gcc) + set(CMAKE_CXX_COMPILER /usr/local/cross-tools/bin/i386-mingw32-g++) + set(CMAKE_RC_COMPILER /usr/local/cross-tools/bin/i386-mingw32-windres) + set(CMAKE_FIND_ROOT_PATH /usr/local/cross-tools) +endif() + +# Adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Tell pkg-config not to look at the target environment's .pc files. +# Setting PKG_CONFIG_LIBDIR sets the default search directory, but we have to +# set PKG_CONFIG_PATH as well to prevent pkg-config falling back to the host's +# path. +set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_FIND_ROOT_PATH}/lib/pkgconfig) +set(ENV{PKG_CONFIG_PATH} ${CMAKE_FIND_ROOT_PATH}/lib/pkgconfig) + +set(ENV{MINGDIR} ${CMAKE_FIND_ROOT_PATH}) diff --git a/allegro/cmake/Toolchain-openwiz.cmake b/allegro/cmake/Toolchain-openwiz.cmake new file mode 100644 index 00000000..21567248 --- /dev/null +++ b/allegro/cmake/Toolchain-openwiz.cmake @@ -0,0 +1,8 @@ +SET(GP2XWIZ on) +SET(CMAKE_SYSTEM_NAME Linux) +SET(CMAKE_C_COMPILER arm-openwiz-linux-gnu-gcc) +SET(CMAKE_CXX_COMPILER arm-openwiz-linux-gnu-g++) +SET(CMAKE_FIND_ROOT_PATH /home/trent/arm-openwiz-linux-gnu) +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/allegro/cmake/Toolchain-raspberrypi.cmake b/allegro/cmake/Toolchain-raspberrypi.cmake new file mode 100644 index 00000000..17fedbc4 --- /dev/null +++ b/allegro/cmake/Toolchain-raspberrypi.cmake @@ -0,0 +1,39 @@ +SET(ALLEGRO_RASPBERRYPI 1) +SET(CMAKE_SYSTEM_NAME Linux) + +IF("${TOOLCHAIN_ROOT}" STREQUAL "") + SET(TOOLCHAIN_ROOT "/usr/bin") +ENDIF("${TOOLCHAIN_ROOT}" STREQUAL "") + +IF("${TOOLCHAIN_PREFIX}" STREQUAL "") + SET(TOOLCHAIN_PREFIX "") +ENDIF("${TOOLCHAIN_PREFIX}" STREQUAL "") + +IF("${TOOLCHAIN_SUFFIX}" STREQUAL "") + SET(TOOLCHAIN_SUFFIX "") +ENDIF("${TOOLCHAIN_SUFFIX}" STREQUAL "") + +SET(CMAKE_C_FLAGS "-march=armv6 -mfpu=vfp -mfloat-abi=hard -Os") +SET(CMAKE_CXX_FLAGS "-march=armv6 -mfpu=vfp -mfloat-abi=hard -Os") + +if(NOT DISTCC) + set(CMAKE_C_COMPILER ${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}gcc${TOOLCHAIN_SUFFIX}) + set(CMAKE_CXX_COMPILER ${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}g++${TOOLCHAIN_SUFFIX}) +endif() +set(CMAKE_LINKER ${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}ld${TOOLCHAIN_SUFFIX}) +set(CMAKE_NM ${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}nm${TOOLCHAIN_SUFFIX}) +set(CMAKE_OBJCOPY ${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}objcopy${TOOLCHAIN_SUFFIX}) +set(CMAKE_OBJDUMP ${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}objdump${TOOLCHAIN_SUFFIX}) +set(CMAKE_STRIP ${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}strip${TOOLCHAIN_SUFFIX}) +set(CMAKE_RANLIB ${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}ranlib${TOOLCHAIN_SUFFIX}) + +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +include_directories( + "/opt/vc/include" + "/opt/vc/include/interface/vcos/pthreads" + "/opt/vc/include/interface/vmcs_host/linux" +) + diff --git a/allegro/contrib/luajit/CMakeLists.txt b/allegro/contrib/luajit/CMakeLists.txt new file mode 100644 index 00000000..a6f422e3 --- /dev/null +++ b/allegro/contrib/luajit/CMakeLists.txt @@ -0,0 +1,47 @@ +include(FindPythonInterp) + +# Construct list of files whose modification should trigger a rebuild of +# the Python API. +foreach(x ${MONOLITH_SOURCES} ${MONOLITH_HEADERS} ${ALLEGRO_PUBLIC_HEADERS}) + if(NOT ${x} MATCHES "^/.*") + file(RELATIVE_PATH xrel ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/${x}) + list(APPEND SOURCES ${xrel}) + endif() +endforeach() + +if(WIN32) + add_custom_command( + OUTPUT luajit_protos + DEPENDS ${SOURCES} + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/python/checkdocs.py + -c ${CMAKE_C_COMPILER} + -p luajit_protos + -b ${PROJECT_BINARY_DIR} + -s ${PROJECT_SOURCE_DIR} + -w + ) +else(WIN32) + add_custom_command( + OUTPUT luajit_protos + DEPENDS ${SOURCES} + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/python/checkdocs.py + -p luajit_protos + -b ${PROJECT_BINARY_DIR} + -s ${PROJECT_SOURCE_DIR} + ) +endif(WIN32) + +SET(release "") +append_lib_type_suffix(release) +append_lib_linkage_suffix(release) +SET(version "${ALLEGRO_SOVERSION}") + +add_custom_target(luajit + ALL + DEPENDS luajit_protos + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate_luajit_ffi.py + -p luajit_protos + -o al5_ffi.lua + -t \"${release}\" + -v \"${version}\" + ) diff --git a/allegro/contrib/luajit/README.txt b/allegro/contrib/luajit/README.txt new file mode 100644 index 00000000..379e5d1f --- /dev/null +++ b/allegro/contrib/luajit/README.txt @@ -0,0 +1,21 @@ +Luajit +====== + +The contents of this directory provides support for using Allegro5 from [Luajit][lj]. + + +Usage +----- + +To create a Luajit FFI desciption we use the prototypes scraped using the checkdocs.py script. + + # output a file protos.txt + ./python/checkdocs.py -p protos.txt -b build/ + + # use the prototypes to create Luajit datatypes for Allegro5 + ./contrib/luajit/generate_luajit_ffi.py -p protos.txt -o al5_ffi.lua + +See the Luajit docs on how to use this file. + + +[lj]: http://luajit.org diff --git a/allegro/contrib/luajit/generate_luajit_ffi.py b/allegro/contrib/luajit/generate_luajit_ffi.py new file mode 100644 index 00000000..59297e13 --- /dev/null +++ b/allegro/contrib/luajit/generate_luajit_ffi.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python3 + +""" +This script will use the prototypes from "checkdocs.py -s" to concoct +a 1:1 LuaJIT FFI wrapper for Allegro. Thanks to generate_python_ctypes.py. +""" + +import sys +import re +import optparse + +class Allegro: + def __init__(self): + self.typesfw = [] + self.typesfuncptr = [] + self.typedecl = [] + self.functions = [] + self.constants = {} + self.enums = [] + + def parse_protos(self, filename): + deferred = [] + + # first pass: create all structs, but without fields + for line in open(filename): + name, proto = line.split(":", 1) + proto = proto.lstrip() + pwords = proto.split(' ') + if name.endswith("()"): + self.functions.append(proto) + continue + # anonymous structs have no name at all + if name and not name.startswith("ALLEGRO_"): + continue + if name == "ALLEGRO_OGL_EXT_API": + continue + + if pwords[0] in ('union', 'struct'): + if '{' in proto: + self.typedecl.append(proto) + else: + self.typesfw.append(proto) + elif pwords[0] == 'typedef' and pwords[1] in ('union', 'struct'): + if '{' in proto: + self.typedecl.append(proto) + else: + self.typesfw.append(proto) + elif proto.startswith("enum") or\ + proto.startswith("typedef enum"): + if name: + self.enums.append('enum %s;' % name) + deferred.append(("", proto)) + elif proto.startswith("#define"): + if not name.startswith("_") and not name.startswith("GL_"): + i = eval(proto.split(None, 2)[2]) + self.constants[name] = i + else: + mob = re.match("typedef (.*) " + name, proto) + if mob: + self.typesfw.append(proto) + else: + # Probably a function pointer + self.typesfuncptr.append(proto) + + # Second pass of prototypes now we have seen them all. + for name, proto in deferred: + bo = proto.find("{") + if bo == -1: + continue + bc = proto.rfind("}") + braces = proto[bo + 1:bc] + + # Calculate enums + if proto.startswith("enum") or \ + proto.startswith("typedef enum"): + + fields = braces.split(",") + i = 0 + for field in fields: + if "=" in field: + fname, val = field.split("=", 1) + fname = fname.strip() + # replace any 'X' (an integer value in C) with + # ord('X') to match up in Python + val = re.sub("('.')", "ord(\\1)", val) + try: + i = int(eval(val, globals(), self.constants)) + except NameError: + i = val + except Exception: + raise ValueError( + "Exception while parsing '{}'".format( + val)) + else: + fname = field.strip() + if not fname: + continue + self.constants[fname] = i + try: + i += 1 + except TypeError: + pass + continue + +def typeorder(decls, declared): + """ Order the types by dependency. """ + decl, seen = set(), set() + ordered = [] + todo = decls[:] + + seen.add('ALLEGRO_EVENT_TYPE') + seen.add('ALLEGRO_KEY_MAX') + seen.add('ALLEGRO_USER_EVENT_DESCRIPTOR') + + def info(t): + brk, brk2 = t.find('{'), t.rfind('}') + tbrk = t[brk+1:brk2] if brk >= 0 and brk2 >= 0 else None + tw = t.split(' ') + name = None + if tw[0] in ('struct', 'union'): + name = tw[1] + elif tw[0] == 'typedef': + if tw[1] in ('struct', 'union'): + name = tw[2] + return name, tbrk + + for t in declared: + name, _ = info(t) + if name: + decl.add(name) + + reall = re.compile('(ALLEGRO_\w+\s*\*?)') + retname = re.compile('(ALLEGRO_\w+)') + c = 0 + while True: + lb = len(todo) + for t in todo[:]: + name, brk = info(t) + aldeps = reall.findall(brk) + ok = True + # print aldeps + for rdep in aldeps: + dep = retname.match(rdep).group(1) + if dep.startswith('ALLEGRO_GL_'): + continue # ignore + if dep in decl and rdep[-1] == '*': + continue # ok, seen type and ptr + if not dep in seen: + ok = False + break + if ok: + ordered.append(t) + todo.remove(t) + seen.add(name) + if len(todo) == 0: + break + elif lb == len(todo): + c += 1 + assert c < 10, 'loop, bad' + # ordered += todo + return ordered + +def main(): + p = optparse.OptionParser() + p.add_option("-o", "--output", help="location of generated file") + p.add_option("-p", "--protos", help="A file with all " + + "prototypes to generate LuaJIT FFI wrappers for, one per line. " + "Generate it with docs/scripts/checkdocs.py -p") + p.add_option("-t", "--type", help="the library type to " + + "use, e.g. debug") + p.add_option("-v", "--version", help="the library version to " + + "use, e.g. 5.1") + options, args = p.parse_args() + + if not options.protos: + p.print_help() + return + + al = Allegro() + + al.parse_protos(options.protos) + + f = open(options.output, "w") if options.output else sys.stdout + + release = options.type + version = options.version + f.write(r"""-- Generated by generate_luajit_ffi.py +-- Release: %(release)s-%(version)s + +local ffi = require 'ffi' + +local allegro = {} + +""" % locals()) + + f.write('-- CONSTANTS\n') + deferred = [] + for name, val in sorted(al.constants.items()): + try: + if isinstance(val, str): + val = int(eval(val, globals(), al.constants)) + f.write('allegro.%s = %s\n' % (name, str(val))) + except: + deferred.append((name, val)) + + reconst = re.compile('([A-Za-z_]\w+)') + for name, val in deferred: + val = reconst.sub(r'allegro.\1', val) + f.write('allegro.%s = %s\n' % (name, str(val))) + + f.write(r""" +ffi.cdef[[ + +typedef uint64_t off_t; +typedef int64_t time_t; +typedef void* va_list; +typedef int al_fixed; +typedef unsigned int GLuint; +typedef unsigned int ALLEGRO_EVENT_TYPE; +enum { ALLEGRO_KEY_MAX = 227 }; +""") + + # enums + f.write('\n// ENUMS\n') + reenum = re.compile('enum (\w+)') + for e in al.enums: + ename = reenum.match(e).group(1) + f.write('typedef enum %s %s;\n' % (ename, ename)) + + # types + f.write('\n// TYPES\n') + for t in al.typesfw: + f.write(t + "\n") + for t in al.typesfuncptr: + f.write(t + "\n") + seen = al.typesfw[:] + for t in typeorder(al.typedecl, seen): + f.write(t + "\n") + + # functions + f.write('\n// FUNCTIONS\n') + for fn in al.functions: + f.write(fn + "\n") + + f.write(']]\n') # end of cdef + + f.write(r""" +return allegro + """) + + f.close() + +main() diff --git a/allegro/demos/cosmic_protector/CMakeLists.txt b/allegro/demos/cosmic_protector/CMakeLists.txt new file mode 100644 index 00000000..8063b635 --- /dev/null +++ b/allegro/demos/cosmic_protector/CMakeLists.txt @@ -0,0 +1,139 @@ +if(SUPPORT_FONT AND SUPPORT_AUDIO AND SUPPORT_ACODEC) +else() + message(STATUS "Not building Cosmic Protector") + return() +endif() + +include_directories( + include + ${PROJECT_SOURCE_DIR}/addons/main + ${PROJECT_SOURCE_DIR}/addons/image + ${PROJECT_SOURCE_DIR}/addons/font + ${PROJECT_SOURCE_DIR}/addons/audio + ${PROJECT_SOURCE_DIR}/addons/acodec + ${PROJECT_SOURCE_DIR}/addons/primitives + ) + +set(DEMO_SRCS + src/Asteroid.cpp + src/BitmapResource.cpp + src/Bullet.cpp + src/ButtonWidget.cpp + src/Debug.cpp + src/DisplayResource.cpp + src/Entity.cpp + src/Explosion.cpp + src/FontResource.cpp + src/Game.cpp + src/GUI.cpp + src/Input.cpp + src/LargeAsteroid.cpp + src/LargeBullet.cpp + src/LargeSlowBullet.cpp + src/MediumAsteroid.cpp + src/Player.cpp + src/PowerUp.cpp + src/Resource.cpp + src/ResourceManager.cpp + src/SampleResource.cpp + src/StreamResource.cpp + src/SmallAsteroid.cpp + src/SmallBullet.cpp + src/UFO.cpp + src/cosmic_protector.cpp + src/collision.cpp + src/joypad_dummy.cpp + src/logic.cpp + src/render.cpp + src/sound.cpp + src/wave.cpp + ) + +if(IPHONE) + list(APPEND DEMO_SRCS src/cosmic_protector_objc.m) +endif(IPHONE) + +set_source_files_properties(${DEMO_SRCS} PROPERTIES LANGUAGE "CXX") + +file(GLOB_RECURSE DEMO_GFX RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + data/gfx/*.png data/gfx/*.jpg data/gfx/*.tga) +file(GLOB_RECURSE DEMO_SFX RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + data/sfx/*.ogg) +set(DEMO_ICON data/gfx/Icon.icns) + +if(ANDROID) + add_copy_commands( + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}/cosmic_protector.project/app/src/main/assets" + ASSETS + "${DEMO_GFX}" + "${DEMO_SFX}" + ) + add_android_app(cosmic_protector + "${DEMO_SRCS};${ASSETS}") + return() +endif(ANDROID) + +if(APPLE) + set(DEMO_EXECUTABLE_TYPE MACOSX_BUNDLE) +else(APPLE) + set(DEMO_EXECUTABLE_TYPE "${EXECUTABLE_TYPE}") +endif(APPLE) + +add_executable(cosmic_protector + ${DEMO_EXECUTABLE_TYPE} + ${DEMO_SRCS} + ${DEMO_GFX} + ${DEMO_SFX} + ${DEMO_ICON} + ) + +fix_executable(cosmic_protector) + +if(WANT_MONOLITH) + target_link_libraries(cosmic_protector + ${ALLEGRO_MONOLITH_LINK_WITH} + ) +else(WANT_MONOLITH) + target_link_libraries(cosmic_protector + ${ALLEGRO_MAIN_LINK_WITH} + ${FONT_LINK_WITH} + ${IMAGE_LINK_WITH} + ${AUDIO_LINK_WITH} + ${ACODEC_LINK_WITH} + ${PRIMITIVES_LINK_WITH} + ) +endif(WANT_MONOLITH) + +if(NOT BUILD_SHARED_LIBS) + set_target_properties(cosmic_protector PROPERTIES COMPILE_FLAGS "-DALLEGRO_STATICLINK") +endif(NOT BUILD_SHARED_LIBS) + +# Mac OS X bundle support. +set_target_properties(cosmic_protector PROPERTIES + MACOSX_BUNDLE_COPYRIGHT "Copyright 2008 Allegro Developers" + MACOSX_BUNDLE_ICON_FILE "Icon.icns" + MACOSX_BUNDLE_INFO_STRING "5.0, Copyright 2008 Allegro Developers" + MACOSX_BUNDLE_SHORT_VERSION_STRING "5.0" + MACOSX_BUNDLE_LONG_VERSION_STRING "Cosmic Protector v5.0" + MACOSX_BUNDLE_GUI_IDENTIFIER "org.liballeg.CosmicProtector" + ) +set_source_files_properties(${DEMO_GFX} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources/data/gfx" + ) +set_source_files_properties(${DEMO_SFX} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources/data/sfx" + ) +set_source_files_properties(${DEMO_ICON} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources" + ) + +copy_data_dir_to_build(copy_demo_data + "${CMAKE_CURRENT_SOURCE_DIR}/data" + "${CMAKE_CURRENT_BINARY_DIR}/data" + ) + +add_dependencies(cosmic_protector copy_demo_data) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/demos/cosmic_protector/data/gfx/Icon.icns b/allegro/demos/cosmic_protector/data/gfx/Icon.icns new file mode 100644 index 00000000..2d332cee Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/Icon.icns differ diff --git a/allegro/demos/cosmic_protector/data/gfx/background.jpg b/allegro/demos/cosmic_protector/data/gfx/background.jpg new file mode 100644 index 00000000..5ac23739 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/background.jpg differ diff --git a/allegro/demos/cosmic_protector/data/gfx/icon48.png b/allegro/demos/cosmic_protector/data/gfx/icon48.png new file mode 100644 index 00000000..542f8ebc Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/icon48.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/large_asteroid.png b/allegro/demos/cosmic_protector/data/gfx/large_asteroid.png new file mode 100644 index 00000000..615158f3 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/large_asteroid.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/large_bullet.png b/allegro/demos/cosmic_protector/data/gfx/large_bullet.png new file mode 100644 index 00000000..901e044f Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/large_bullet.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/large_explosion_0.png b/allegro/demos/cosmic_protector/data/gfx/large_explosion_0.png new file mode 100644 index 00000000..254c9b00 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/large_explosion_0.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/large_explosion_1.png b/allegro/demos/cosmic_protector/data/gfx/large_explosion_1.png new file mode 100644 index 00000000..a3aea5af Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/large_explosion_1.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/large_explosion_2.png b/allegro/demos/cosmic_protector/data/gfx/large_explosion_2.png new file mode 100644 index 00000000..a49fcb05 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/large_explosion_2.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/large_explosion_3.png b/allegro/demos/cosmic_protector/data/gfx/large_explosion_3.png new file mode 100644 index 00000000..bf1abf83 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/large_explosion_3.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/large_explosion_4.png b/allegro/demos/cosmic_protector/data/gfx/large_explosion_4.png new file mode 100644 index 00000000..ebc79c0e Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/large_explosion_4.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/large_font.png b/allegro/demos/cosmic_protector/data/gfx/large_font.png new file mode 100644 index 00000000..5e8e7ef0 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/large_font.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/life_powerup.png b/allegro/demos/cosmic_protector/data/gfx/life_powerup.png new file mode 100644 index 00000000..2725e5c7 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/life_powerup.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/logo.png b/allegro/demos/cosmic_protector/data/gfx/logo.png new file mode 100644 index 00000000..95207aff Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/logo.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/medium_asteroid.png b/allegro/demos/cosmic_protector/data/gfx/medium_asteroid.png new file mode 100644 index 00000000..812b137f Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/medium_asteroid.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/ship.png b/allegro/demos/cosmic_protector/data/gfx/ship.png new file mode 100644 index 00000000..817a93d2 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/ship.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/ship_icon.tga b/allegro/demos/cosmic_protector/data/gfx/ship_icon.tga new file mode 100644 index 00000000..72a8afc3 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/ship_icon.tga differ diff --git a/allegro/demos/cosmic_protector/data/gfx/ship_trans.png b/allegro/demos/cosmic_protector/data/gfx/ship_trans.png new file mode 100644 index 00000000..479b27a0 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/ship_trans.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/small_asteroid.png b/allegro/demos/cosmic_protector/data/gfx/small_asteroid.png new file mode 100644 index 00000000..a366ea4d Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/small_asteroid.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/small_bullet.png b/allegro/demos/cosmic_protector/data/gfx/small_bullet.png new file mode 100644 index 00000000..3e3e1398 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/small_bullet.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/small_explosion_0.png b/allegro/demos/cosmic_protector/data/gfx/small_explosion_0.png new file mode 100644 index 00000000..7278d4b2 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/small_explosion_0.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/small_explosion_1.png b/allegro/demos/cosmic_protector/data/gfx/small_explosion_1.png new file mode 100644 index 00000000..03fac4e9 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/small_explosion_1.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/small_explosion_2.png b/allegro/demos/cosmic_protector/data/gfx/small_explosion_2.png new file mode 100644 index 00000000..f37262a4 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/small_explosion_2.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/small_explosion_3.png b/allegro/demos/cosmic_protector/data/gfx/small_explosion_3.png new file mode 100644 index 00000000..68b22f7a Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/small_explosion_3.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/small_explosion_4.png b/allegro/demos/cosmic_protector/data/gfx/small_explosion_4.png new file mode 100644 index 00000000..3f745a02 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/small_explosion_4.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/small_font.png b/allegro/demos/cosmic_protector/data/gfx/small_font.png new file mode 100644 index 00000000..a56807b7 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/small_font.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/trail.png b/allegro/demos/cosmic_protector/data/gfx/trail.png new file mode 100644 index 00000000..951bee88 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/trail.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/ufo0.png b/allegro/demos/cosmic_protector/data/gfx/ufo0.png new file mode 100644 index 00000000..9dd0c2e6 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/ufo0.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/ufo1.png b/allegro/demos/cosmic_protector/data/gfx/ufo1.png new file mode 100644 index 00000000..f5669433 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/ufo1.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/ufo2.png b/allegro/demos/cosmic_protector/data/gfx/ufo2.png new file mode 100644 index 00000000..32b15b90 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/ufo2.png differ diff --git a/allegro/demos/cosmic_protector/data/gfx/weapon_powerup.png b/allegro/demos/cosmic_protector/data/gfx/weapon_powerup.png new file mode 100644 index 00000000..6eeda9f9 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/gfx/weapon_powerup.png differ diff --git a/allegro/demos/cosmic_protector/data/sfx/big_explosion.ogg b/allegro/demos/cosmic_protector/data/sfx/big_explosion.ogg new file mode 100644 index 00000000..da4eda39 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/sfx/big_explosion.ogg differ diff --git a/allegro/demos/cosmic_protector/data/sfx/collision.ogg b/allegro/demos/cosmic_protector/data/sfx/collision.ogg new file mode 100644 index 00000000..894b2945 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/sfx/collision.ogg differ diff --git a/allegro/demos/cosmic_protector/data/sfx/fire_large.ogg b/allegro/demos/cosmic_protector/data/sfx/fire_large.ogg new file mode 100644 index 00000000..a42c46f8 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/sfx/fire_large.ogg differ diff --git a/allegro/demos/cosmic_protector/data/sfx/fire_small.ogg b/allegro/demos/cosmic_protector/data/sfx/fire_small.ogg new file mode 100644 index 00000000..631c461a Binary files /dev/null and b/allegro/demos/cosmic_protector/data/sfx/fire_small.ogg differ diff --git a/allegro/demos/cosmic_protector/data/sfx/game_music.ogg b/allegro/demos/cosmic_protector/data/sfx/game_music.ogg new file mode 100644 index 00000000..8a8f8f54 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/sfx/game_music.ogg differ diff --git a/allegro/demos/cosmic_protector/data/sfx/powerup.ogg b/allegro/demos/cosmic_protector/data/sfx/powerup.ogg new file mode 100644 index 00000000..1888bb21 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/sfx/powerup.ogg differ diff --git a/allegro/demos/cosmic_protector/data/sfx/small_explosion.ogg b/allegro/demos/cosmic_protector/data/sfx/small_explosion.ogg new file mode 100644 index 00000000..3aa49a31 Binary files /dev/null and b/allegro/demos/cosmic_protector/data/sfx/small_explosion.ogg differ diff --git a/allegro/demos/cosmic_protector/data/sfx/title_music.ogg b/allegro/demos/cosmic_protector/data/sfx/title_music.ogg new file mode 100644 index 00000000..f0c7bbfa Binary files /dev/null and b/allegro/demos/cosmic_protector/data/sfx/title_music.ogg differ diff --git a/allegro/demos/cosmic_protector/include/Asteroid.hpp b/allegro/demos/cosmic_protector/include/Asteroid.hpp new file mode 100644 index 00000000..dc228d43 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Asteroid.hpp @@ -0,0 +1,22 @@ +#ifndef ASTEROID_HPP +#define ASTEROID_HPP + +class Asteroid : public Entity +{ +public: + bool logic(int step); + void render(int offx, int offy); + + void init(float x, float y, float speed_x, float speed_y, float da); + + Asteroid(float radius, int bitmapID); + ~Asteroid(); +protected: + float da; + float angle; + float speed_x; + float speed_y; + ALLEGRO_BITMAP *bitmap; +}; + +#endif // ASTEROID_HPP diff --git a/allegro/demos/cosmic_protector/include/BitmapResource.hpp b/allegro/demos/cosmic_protector/include/BitmapResource.hpp new file mode 100644 index 00000000..635daff7 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/BitmapResource.hpp @@ -0,0 +1,18 @@ +#ifndef BMPRESOURCE_HPP +#define BMPRESOURCE_HPP + +#include "cosmic_protector.hpp" + +class BitmapResource : public Resource { +public: + void destroy(void); + bool load(void); + void* get(void); + BitmapResource(const char* filename); +private: + ALLEGRO_BITMAP *bitmap; + std::string filename; +}; + +#endif // BMPRESOURCE_HPP + diff --git a/allegro/demos/cosmic_protector/include/Bullet.hpp b/allegro/demos/cosmic_protector/include/Bullet.hpp new file mode 100644 index 00000000..3e4019fa --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Bullet.hpp @@ -0,0 +1,25 @@ +#ifndef BULLET_HPP +#define BULLET_HPP + +class Bullet : public Entity +{ +public: + bool logic(int step); + + Bullet(float x, float y, float radius, float speed, float angle, + int lifetime, int damage, int bitmapID, Entity *shooter); + ~Bullet(void); +protected: + ALLEGRO_BITMAP *bitmap; + float speed; + float angle; + int lifetime; + float cosa; + float sina; + Entity *shooter; + int damage; + bool playerOnly; +}; + +#endif // BULLET_HPP + diff --git a/allegro/demos/cosmic_protector/include/ButtonWidget.hpp b/allegro/demos/cosmic_protector/include/ButtonWidget.hpp new file mode 100644 index 00000000..0c79fec2 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/ButtonWidget.hpp @@ -0,0 +1,20 @@ +#ifndef BUTTONWIDGET_HPP +#define BUTTONWIDGET_HPP + +class ButtonWidget : public Widget +{ +public: + bool activate(void); + void render(bool selected); + + ButtonWidget(int x, int y, bool center, const char *text); + ~ButtonWidget() {}; +protected: + int x; + int y; + bool center; + const char *text; +}; + +#endif // BUTTONWIDGET_HPP + diff --git a/allegro/demos/cosmic_protector/include/Debug.hpp b/allegro/demos/cosmic_protector/include/Debug.hpp new file mode 100644 index 00000000..6b5576fb --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Debug.hpp @@ -0,0 +1,9 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#include "cosmic_protector.hpp" + +void debug_message(const char *, ...); + +#endif + diff --git a/allegro/demos/cosmic_protector/include/DisplayResource.hpp b/allegro/demos/cosmic_protector/include/DisplayResource.hpp new file mode 100644 index 00000000..826b3413 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/DisplayResource.hpp @@ -0,0 +1,21 @@ +#ifndef DISPLAYRESOURCE_HPP +#define DISPLAYRESOURCE_HPP + +#include "cosmic_protector.hpp" + +class DisplayResource : public Resource { +public: + void destroy(void); + bool load(void); + void* get(void); + ALLEGRO_EVENT_QUEUE *getEventQueue(void); + DisplayResource(void); +private: + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *events; +}; + +extern bool useFullScreenMode; + +#endif // DISPLAYRESOURCE_HPP + diff --git a/allegro/demos/cosmic_protector/include/Entity.hpp b/allegro/demos/cosmic_protector/include/Entity.hpp new file mode 100644 index 00000000..ecdaccc3 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Entity.hpp @@ -0,0 +1,52 @@ +#ifndef ENTITY_HPP +#define ENTITY_HPP + +const int ENTITY_LARGE_ASTEROID = 0; +const int ENTITY_SMALL_ASTEROID = 1; + +class Entity { +public: + virtual bool logic(int step); + virtual void render(int offx = 0, int offy = 0) = 0; + virtual void render(int x, int y, ALLEGRO_COLOR c); + + virtual void spawn(void); + virtual bool hit(int damage); + + float getX(void); + float getY(void); + float getRadius(void); + bool getDestructable(void); + int getDamage(void); + bool isHighlighted(void); + bool isUFO(void); + + void setPowerUp(int type); + + void wrap(void); + Entity *getPlayerCollision(void); + Entity *getEntityCollision(void); + Entity *getAllCollision(void); + void explode(void); + + void render_four(ALLEGRO_COLOR tint); + + Entity(void); + virtual ~Entity(void) {}; +protected: + Entity *checkCollisions(std::list<Entity *>& e); + + float x; + float y; + float radius; + float dx; + float dy; + bool isDestructable; + int hp; + int powerup; + int hilightCount; + int points; + bool ufo; +}; + +#endif // ENTITY_HPP diff --git a/allegro/demos/cosmic_protector/include/Explosion.hpp b/allegro/demos/cosmic_protector/include/Explosion.hpp new file mode 100644 index 00000000..c67b7e56 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Explosion.hpp @@ -0,0 +1,21 @@ +#ifndef EXPLOSION_HPP +#define EXPLOSION_HPP + +class Explosion : public Entity +{ +public: + static const int NUM_FRAMES = 5; + static const int FRAME_TIME = 100; + + bool logic(int step); + void render(int offx, int offy); + + Explosion(float x, float y, bool big); +private: + int frameCount; + int currFrame; + bool big; +}; + +#endif // EXPLOSION_HPP + diff --git a/allegro/demos/cosmic_protector/include/FontResource.hpp b/allegro/demos/cosmic_protector/include/FontResource.hpp new file mode 100644 index 00000000..88f9ca55 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/FontResource.hpp @@ -0,0 +1,16 @@ +#ifndef FONTRESOURCE_HPP +#define FONTRESOURCE_HPP + +class FontResource : public Resource +{ +public: + void destroy(void); + bool load(void); + void* get(void); + FontResource(const char *filename); +private: + ALLEGRO_FONT *font; + std::string filename; +}; + +#endif // FONTRESOURCE_HPP diff --git a/allegro/demos/cosmic_protector/include/Game.hpp b/allegro/demos/cosmic_protector/include/Game.hpp new file mode 100644 index 00000000..b3be8684 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Game.hpp @@ -0,0 +1,22 @@ +#ifndef GAME_HPP +#define GAME_HPP + +#include "cosmic_protector.hpp" + +#ifdef ALLEGRO_MSVC +/* MSVC (up to ver. 9 at least) ignores exception specifications */ +#pragma warning( disable : 4290 ) +#endif + +const char* getResource(const char* fmt, ...); +bool loadResources(void); +bool init(void); +void done(void); +float randf(float lo, float hi); + +extern bool kb_installed; +extern bool joy_installed; + + +#endif // GAME_HPP + diff --git a/allegro/demos/cosmic_protector/include/Input.hpp b/allegro/demos/cosmic_protector/include/Input.hpp new file mode 100644 index 00000000..76bc82cc --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Input.hpp @@ -0,0 +1,49 @@ +#ifndef INPUT_HPP +#define INPUT_HPP + +#include "cosmic_protector.hpp" + +class Input : public Resource +{ +public: + Input(); + ~Input(); + +#ifdef ALLEGRO_IPHONE + void draw(void); + bool button_pressed(int x, int y, int w, int h, bool check_if_controls_at_top = true); +#endif + + void poll(void); + float lr(void); + float ud(void); + bool esc(void); + bool b1(void); + bool cheat(void); + + void destroy(void); + bool load(void); + void* get(void); +private: + ALLEGRO_KEYBOARD_STATE kbdstate; + ALLEGRO_JOYSTICK_STATE joystate; + ALLEGRO_JOYSTICK *joystick; + + ALLEGRO_EVENT_QUEUE *input_queue; + + bool joypad_u, joypad_d, joypad_l, joypad_r, joypad_b, joypad_esc; + +#ifdef ALLEGRO_IPHONE + struct Touch { + int id; + int x; + int y; + }; + std::vector<Touch> touches; + bool controls_at_top; + int size; + float joyaxis0, joyaxis1, joyaxis2; +#endif +}; + +#endif // INPUT_HPP diff --git a/allegro/demos/cosmic_protector/include/LargeAsteroid.hpp b/allegro/demos/cosmic_protector/include/LargeAsteroid.hpp new file mode 100644 index 00000000..5071ad96 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/LargeAsteroid.hpp @@ -0,0 +1,15 @@ +#ifndef LARGEASTEROID_HPP +#define LARGEASTEROID_HPP + +class LargeAsteroid : public Asteroid +{ +public: + void spawn(void); + + LargeAsteroid(); + LargeAsteroid(float x, float y, float speed_x, float speed_y, float da); + ~LargeAsteroid(); +}; + +#endif // LARGEASTEROID_HPP + diff --git a/allegro/demos/cosmic_protector/include/LargeBullet.hpp b/allegro/demos/cosmic_protector/include/LargeBullet.hpp new file mode 100644 index 00000000..cb381ea5 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/LargeBullet.hpp @@ -0,0 +1,13 @@ +#ifndef LARGEBULLET_HPP +#define LARGEBULLET_HPP + +class LargeBullet : public Bullet +{ +public: + void render(int offx, int offy); + + LargeBullet(float x, float y, float angle, Entity *shooter); +}; + +#endif // LARGEBULLET_HPP + diff --git a/allegro/demos/cosmic_protector/include/LargeSlowBullet.hpp b/allegro/demos/cosmic_protector/include/LargeSlowBullet.hpp new file mode 100644 index 00000000..90813b99 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/LargeSlowBullet.hpp @@ -0,0 +1,11 @@ +#ifndef LARGESLOWBULLET_HPP +#define LARGESLOWBULLET_HPP + +class LargeSlowBullet : public LargeBullet +{ +public: + LargeSlowBullet(float x, float y, float angle, Entity *shooter); +}; + +#endif // LARGESLOWBULLET_HPP + diff --git a/allegro/demos/cosmic_protector/include/MediumAsteroid.hpp b/allegro/demos/cosmic_protector/include/MediumAsteroid.hpp new file mode 100644 index 00000000..1a846b40 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/MediumAsteroid.hpp @@ -0,0 +1,14 @@ +#ifndef MEDIUMASTEROID_HPP +#define MEDIUMASTEROID_HPP + +class MediumAsteroid : public Asteroid +{ +public: + void spawn(void); + + MediumAsteroid(); + ~MediumAsteroid(); +}; + +#endif // MEDIUMASTEROID_HPP + diff --git a/allegro/demos/cosmic_protector/include/Player.hpp b/allegro/demos/cosmic_protector/include/Player.hpp new file mode 100644 index 00000000..c8349eec --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Player.hpp @@ -0,0 +1,51 @@ +#ifndef PLAYER_HPP +#define PLAYER_HPP + +class Player : public Entity, public Resource { +public: + static const float MAX_SPEED; + static const float MIN_SPEED; + static const float ACCEL; + static const float DECCEL; + + bool logic(int step); + void render_extra(void); + void render(int offx, int offy); + void render(int offx, int offy, ALLEGRO_COLOR tint); + bool hit(int damage); + + void destroy(void); + bool load(void); + void* get(void); + + void newGame(void); + void reset(void); + void die(void); + void givePowerUp(int type); + + void addScore(int points); + int getScore(void); + + float getAngle(void); + void getSpeed(float *dx, float *dy); + + Player(); + ~Player(); +private: + float angle; + float draw_radius; + bool draw_trail; + int weapon; + int lastShot; + int lives; + int invincibleCount; + int score; + + ALLEGRO_BITMAP *bitmap; + ALLEGRO_BITMAP *trans_bitmap; + ALLEGRO_BITMAP *trail_bitmap; + ALLEGRO_BITMAP *icon; + ALLEGRO_BITMAP *highscoreBitmap; +}; + +#endif // PLAYER_HPP diff --git a/allegro/demos/cosmic_protector/include/PowerUp.hpp b/allegro/demos/cosmic_protector/include/PowerUp.hpp new file mode 100644 index 00000000..da7dcb62 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/PowerUp.hpp @@ -0,0 +1,24 @@ +#ifndef POWERUP_HPP +#define POWERUP_HPP + +const int POWERUP_LIFE = 0; +const int POWERUP_WEAPON = 1; + +class PowerUp : public Entity +{ +public: + const float SPIN_SPEED; + + bool logic(int step); + void render(int offx, int offy); + + PowerUp(float x, float y, int type); +private: + int type; + ALLEGRO_BITMAP *bitmap; + float angle; + float da; +}; + +#endif // POWERUP_HPP + diff --git a/allegro/demos/cosmic_protector/include/Resource.hpp b/allegro/demos/cosmic_protector/include/Resource.hpp new file mode 100644 index 00000000..cd199b8f --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Resource.hpp @@ -0,0 +1,64 @@ +#ifndef RESOURCE_HPP +#define RESOURCE_HPP + +#include "cosmic_protector.hpp" + +const int RES_DISPLAY = 0; +const int RES_PLAYER = 1; +const int RES_INPUT = 2; +const int RES_LARGEFONT = 3; +const int RES_SMALLFONT = 4; + +const int RES_BITMAP_START = 5; +const int RES_LARGEASTEROID = RES_BITMAP_START+0; +const int RES_SMALLASTEROID = RES_BITMAP_START+1; +const int RES_BACKGROUND = RES_BITMAP_START+2; +const int RES_SMALLBULLET = RES_BITMAP_START+3; +const int RES_LARGEEXPLOSION0 = RES_BITMAP_START+4; +const int RES_LARGEEXPLOSION1 = RES_BITMAP_START+5; +const int RES_LARGEEXPLOSION2 = RES_BITMAP_START+6; +const int RES_LARGEEXPLOSION3 = RES_BITMAP_START+7; +const int RES_LARGEEXPLOSION4 = RES_BITMAP_START+8; +const int RES_SMALLEXPLOSION0 = RES_BITMAP_START+9; +const int RES_SMALLEXPLOSION1 = RES_BITMAP_START+10; +const int RES_SMALLEXPLOSION2 = RES_BITMAP_START+11; +const int RES_SMALLEXPLOSION3 = RES_BITMAP_START+12; +const int RES_SMALLEXPLOSION4 = RES_BITMAP_START+13; +const int RES_MEDIUMASTEROID = RES_BITMAP_START+14; +const int RES_LARGEBULLET = RES_BITMAP_START+15; +const int RES_WEAPONPOWERUP = RES_BITMAP_START+16; +const int RES_LIFEPOWERUP = RES_BITMAP_START+17; +const int RES_UFO0 = RES_BITMAP_START+18; +const int RES_UFO1 = RES_BITMAP_START+19; +const int RES_UFO2 = RES_BITMAP_START+20; +const int RES_LOGO = RES_BITMAP_START+21; + +const int RES_SAMPLE_START = RES_BITMAP_START+22; +const int RES_BIGEXPLOSION = RES_SAMPLE_START+0; +const int RES_COLLISION = RES_SAMPLE_START+1; +const int RES_FIRELARGE = RES_SAMPLE_START+2; +const int RES_FIRESMALL = RES_SAMPLE_START+3; +const int RES_SMALLEXPLOSION = RES_SAMPLE_START+4; +const int RES_POWERUP = RES_SAMPLE_START+5; +const int RES_SAMPLE_END = RES_POWERUP+1; + +const int RES_STREAM_START = RES_SAMPLE_START+6; +const int RES_TITLE_MUSIC = RES_STREAM_START+0; +const int RES_GAME_MUSIC = RES_STREAM_START+1; +const int RES_STREAM_END = RES_GAME_MUSIC+1; + +extern const char* BMP_NAMES[]; +extern const char* SAMPLE_NAMES[]; +extern const char* STREAM_NAMES[]; + +class Resource { +public: + virtual void destroy(void) = 0; + virtual bool load(void) = 0; + virtual void* get(void) = 0; + + virtual ~Resource() {}; +}; + +#endif // RESOURCE_HPP + diff --git a/allegro/demos/cosmic_protector/include/ResourceManager.hpp b/allegro/demos/cosmic_protector/include/ResourceManager.hpp new file mode 100644 index 00000000..6915eaa8 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/ResourceManager.hpp @@ -0,0 +1,24 @@ +#ifndef RESOURCEMGR_HPP +#define RESOURCEMGR_HPP + +#include "cosmic_protector.hpp" + +class ResourceManager { +public: + static ResourceManager& getInstance(void); + + void destroy(void); + + // Add with optional load + bool add(Resource* res, bool load = true); + Resource* getResource(int index); + void* getData(int index); +private: + static ResourceManager *rm; + ResourceManager(void); + + std::vector< Resource* > resources; +}; + +#endif // RESOURCEMGR_HPP + diff --git a/allegro/demos/cosmic_protector/include/SampleResource.hpp b/allegro/demos/cosmic_protector/include/SampleResource.hpp new file mode 100644 index 00000000..88dedfaa --- /dev/null +++ b/allegro/demos/cosmic_protector/include/SampleResource.hpp @@ -0,0 +1,18 @@ +#ifndef SAMPLERESOURCE_HPP +#define SAMPLERESOURCE_HPP + +#include "cosmic_protector.hpp" + +class SampleResource : public Resource { +public: + void destroy(void); + bool load(void); + void* get(void); + SampleResource(const char* filename); +private: + ALLEGRO_SAMPLE *sample_data; + std::string filename; +}; + +#endif // SAMPLERESOURCE_HPP + diff --git a/allegro/demos/cosmic_protector/include/SmallAsteroid.hpp b/allegro/demos/cosmic_protector/include/SmallAsteroid.hpp new file mode 100644 index 00000000..16aea9c1 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/SmallAsteroid.hpp @@ -0,0 +1,12 @@ +#ifndef SMALLASTEROID_HPP +#define SMALLASTEROID_HPP + +class SmallAsteroid : public Asteroid +{ +public: + SmallAsteroid(); + ~SmallAsteroid(); +}; + +#endif // SMALLASTEROID_HPP + diff --git a/allegro/demos/cosmic_protector/include/SmallBullet.hpp b/allegro/demos/cosmic_protector/include/SmallBullet.hpp new file mode 100644 index 00000000..6299b6d4 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/SmallBullet.hpp @@ -0,0 +1,13 @@ +#ifndef SMALLBULLET_HPP +#define SMALLBULLET_HPP + +class SmallBullet : public Bullet +{ +public: + void render(int offx, int offy); + + SmallBullet(float x, float y, float angle, Entity *shooter); +}; + +#endif // SMALLBULLET_HPP + diff --git a/allegro/demos/cosmic_protector/include/StreamResource.hpp b/allegro/demos/cosmic_protector/include/StreamResource.hpp new file mode 100644 index 00000000..7c72751a --- /dev/null +++ b/allegro/demos/cosmic_protector/include/StreamResource.hpp @@ -0,0 +1,18 @@ +#ifndef STREAMRESOURCE_HPP +#define STREAMRESOURCE_HPP + +#include "cosmic_protector.hpp" + +class StreamResource : public Resource { +public: + void destroy(void); + bool load(void); + void* get(void); + StreamResource(const char* filename); +private: + ALLEGRO_AUDIO_STREAM *stream; + std::string filename; +}; + +#endif // STREAMRESOURCE_HPP + diff --git a/allegro/demos/cosmic_protector/include/UFO.hpp b/allegro/demos/cosmic_protector/include/UFO.hpp new file mode 100644 index 00000000..2ca4d3c3 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/UFO.hpp @@ -0,0 +1,25 @@ +#ifndef UFO_HPP +#define UFO_HPP + +class UFO : public Entity +{ +public: + const int SHOT_SPEED; + const int ANIMATION_SPEED; + + bool logic(int step); + void render(int offx, int offy); + void render(int offx, int offy, ALLEGRO_COLOR tint); + + UFO(float x, float y, float dx, float dy); + ~UFO(); +protected: + ALLEGRO_BITMAP *bitmaps[3]; + int nextShot; + int bitmapFrame; + int bitmapFrameCount; + float speed_x; + float speed_y; +}; + +#endif // UFO_HPP diff --git a/allegro/demos/cosmic_protector/include/Wave.hpp b/allegro/demos/cosmic_protector/include/Wave.hpp new file mode 100644 index 00000000..feb92c4d --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Wave.hpp @@ -0,0 +1,15 @@ +#ifndef WAVE_HPP +#define WAVE_HPP + +class Wave +{ +public: + Wave(); + bool next(void); + +private: + int rippleNum; +}; + +#endif // WAVE_HPP + diff --git a/allegro/demos/cosmic_protector/include/Weapon.hpp b/allegro/demos/cosmic_protector/include/Weapon.hpp new file mode 100644 index 00000000..822efec6 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Weapon.hpp @@ -0,0 +1,8 @@ +#ifndef WEAPON_HPP +#define WEAPON_HPP + +const int WEAPON_SMALL = 0; +const int WEAPON_LARGE = 1; + +#endif // WEAPON_HPP + diff --git a/allegro/demos/cosmic_protector/include/Widget.hpp b/allegro/demos/cosmic_protector/include/Widget.hpp new file mode 100644 index 00000000..c48e9f86 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/Widget.hpp @@ -0,0 +1,14 @@ +#ifndef WIDGET_HPP +#define WIDGET_HPP + +class Widget +{ +public: + // Returns false to destroy the gui + virtual bool activate(void) = 0; + virtual void render(bool selected) = 0; + virtual ~Widget() {}; +}; + +#endif // WIDGET_HPP + diff --git a/allegro/demos/cosmic_protector/include/collision.hpp b/allegro/demos/cosmic_protector/include/collision.hpp new file mode 100644 index 00000000..d3e062e9 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/collision.hpp @@ -0,0 +1,7 @@ +#ifndef COLLISION_HPP +#define COLLISION_HPP + +bool checkCircleCollision(float x1, float y1, float r1, + float x2, float y2, float r2); + +#endif // COLLISION_HPP diff --git a/allegro/demos/cosmic_protector/include/cosmic_protector.hpp b/allegro/demos/cosmic_protector/include/cosmic_protector.hpp new file mode 100644 index 00000000..fca1d6b3 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/cosmic_protector.hpp @@ -0,0 +1,68 @@ +#ifndef COSMIC_PROTECTOR_HPP +#define COSMIC_PROTECTOR_HPP + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_primitives.h" + +#ifdef ALLEGRO_UNIX +#define MAX_PATH 5000 +#endif + +#include <string> +#include <iostream> +#include <fstream> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <vector> +#include <list> +#include <math.h> +#include <time.h> + +#include "Debug.hpp" +#include "Resource.hpp" +#include "BitmapResource.hpp" +#include "DisplayResource.hpp" +#include "FontResource.hpp" +#include "Game.hpp" +#include "SampleResource.hpp" +#include "StreamResource.hpp" +#include "ResourceManager.hpp" +#include "Input.hpp" +#include "sound.hpp" +#include "collision.hpp" +#include "Entity.hpp" +#include "Weapon.hpp" +#include "Bullet.hpp" +#include "SmallBullet.hpp" +#include "LargeBullet.hpp" +#include "LargeSlowBullet.hpp" +#include "PowerUp.hpp" +#include "Player.hpp" +#include "Explosion.hpp" +#include "render.hpp" +#include "Wave.hpp" +#include "Asteroid.hpp" +#include "LargeAsteroid.hpp" +#include "MediumAsteroid.hpp" +#include "SmallAsteroid.hpp" +#include "UFO.hpp" +#include "Widget.hpp" +#include "ButtonWidget.hpp" +#include "gui.hpp" +#include "logic.hpp" + +extern int BB_W; +extern int BB_H; +#ifdef ALLEGRO_IPHONE +extern bool switched_out; +void switch_game_out(bool halt); +void switch_game_in(void); +#endif + +#endif // COSMIC_PROTECTOR_HPP + diff --git a/allegro/demos/cosmic_protector/include/cosmic_protector_objc.h b/allegro/demos/cosmic_protector/include/cosmic_protector_objc.h new file mode 100644 index 00000000..c4639df6 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/cosmic_protector_objc.h @@ -0,0 +1,10 @@ +#ifdef __cplusplus +extern "C" { +#endif + +bool isMultitaskingSupported(void); + +#ifdef __cplusplus +} +#endif + diff --git a/allegro/demos/cosmic_protector/include/gui.hpp b/allegro/demos/cosmic_protector/include/gui.hpp new file mode 100644 index 00000000..922ddc1d --- /dev/null +++ b/allegro/demos/cosmic_protector/include/gui.hpp @@ -0,0 +1,8 @@ +#ifndef GUI_HPP +#define GUI_HPP + +int do_menu(void); +void do_highscores(int score); + +#endif // GUI_HPP + diff --git a/allegro/demos/cosmic_protector/include/joypad_c.h b/allegro/demos/cosmic_protector/include/joypad_c.h new file mode 100644 index 00000000..6a384277 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/joypad_c.h @@ -0,0 +1,13 @@ +#ifdef __cplusplus +extern "C" { +#endif + +void joypad_start(void); +void joypad_find(void); +void joypad_stop_finding(void); +void get_joypad_state(bool *u, bool *d, bool *l, bool *r, bool *b, bool *esc); +bool is_joypad_connected(void); + +#ifdef __cplusplus +} +#endif diff --git a/allegro/demos/cosmic_protector/include/joypad_handler.h b/allegro/demos/cosmic_protector/include/joypad_handler.h new file mode 100644 index 00000000..1070394c --- /dev/null +++ b/allegro/demos/cosmic_protector/include/joypad_handler.h @@ -0,0 +1,22 @@ +#ifdef USE_JOYPAD + +#import "JoypadSDK.h" + +@interface joypad_handler : NSObject<JoypadManagerDelegate, JoypadDeviceDelegate> +{ + JoypadManager *joypadManager; + +@public + bool connected, left, right, up, down, ba, bb, bx, by, bl, br; + bool finding; +} + +-(void)start; +-(void)find_devices; +-(void)stop_finding_devices; + +@end + +#endif + +#include "joypad_c.h" diff --git a/allegro/demos/cosmic_protector/include/logic.hpp b/allegro/demos/cosmic_protector/include/logic.hpp new file mode 100644 index 00000000..1608a3ce --- /dev/null +++ b/allegro/demos/cosmic_protector/include/logic.hpp @@ -0,0 +1,11 @@ +#ifndef LOGIC_HPP +#define LOGIC_HPP + +bool logic(int step); + +extern std::list<Entity *> entities; +extern std::list<Entity *> new_entities; +extern long lastUFO; +extern bool canUFO; + +#endif // LOGIC_HPP diff --git a/allegro/demos/cosmic_protector/include/render.hpp b/allegro/demos/cosmic_protector/include/render.hpp new file mode 100644 index 00000000..f056caf4 --- /dev/null +++ b/allegro/demos/cosmic_protector/include/render.hpp @@ -0,0 +1,9 @@ +#ifndef RENDER_HPP +#define RENDER_HPP + +void render(int step); +void showWave(int num); +void shake(void); + +#endif // RENDER_HPP + diff --git a/allegro/demos/cosmic_protector/include/sound.hpp b/allegro/demos/cosmic_protector/include/sound.hpp new file mode 100644 index 00000000..2fbc270e --- /dev/null +++ b/allegro/demos/cosmic_protector/include/sound.hpp @@ -0,0 +1,6 @@ +#ifndef SOUND_HPP +#define SOUND_HPP + +void my_play_sample(int resourceID); + +#endif // SOUND_HPP diff --git a/allegro/demos/cosmic_protector/src/Asteroid.cpp b/allegro/demos/cosmic_protector/src/Asteroid.cpp new file mode 100644 index 00000000..09ea3a3d --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Asteroid.cpp @@ -0,0 +1,52 @@ +#include "cosmic_protector.hpp" + +void Asteroid::init(float x, float y, float speed_x, float speed_y, float da) +{ + this->x = x; + this->y = y; + this->speed_x = speed_x; + this->speed_y = speed_y; + this->da = da; +} + +bool Asteroid::logic(int step) +{ + angle -= da * step; + + Player *p = (Player *)getPlayerCollision(); + if (p) { + explode(); + p->hit(1); + my_play_sample(RES_COLLISION); + return false; + } + + dx = speed_x * step; + dy = speed_y * step; + + Entity::wrap(); + + if (!Entity::logic(step)) + return false; + + return true; +} + +void Asteroid::render(int offx, int offy) +{ + al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, angle, 0); +} + +Asteroid::Asteroid(float radius, int bitmapID) +{ + this->radius = radius; + + angle = randf(0.0f, ALLEGRO_PI*2.0f); + + ResourceManager& rm = ResourceManager::getInstance(); + bitmap = (ALLEGRO_BITMAP *)rm.getData(bitmapID); +} + +Asteroid::~Asteroid() +{ +} diff --git a/allegro/demos/cosmic_protector/src/BitmapResource.cpp b/allegro/demos/cosmic_protector/src/BitmapResource.cpp new file mode 100644 index 00000000..e8a3a6f6 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/BitmapResource.cpp @@ -0,0 +1,31 @@ +#include "cosmic_protector.hpp" + +void BitmapResource::destroy(void) +{ + if (!bitmap) + return; + al_destroy_bitmap(bitmap); + bitmap = 0; +} + +bool BitmapResource::load(void) +{ + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + bitmap = al_load_bitmap(filename.c_str()); + if (!bitmap) + debug_message("Error loading bitmap %s\n", filename.c_str()); + return bitmap != 0; +} + +void* BitmapResource::get(void) +{ + return bitmap; +} + +BitmapResource::BitmapResource(const char* filename) : + bitmap(0) +{ + this->filename = std::string(filename); +} + diff --git a/allegro/demos/cosmic_protector/src/Bullet.cpp b/allegro/demos/cosmic_protector/src/Bullet.cpp new file mode 100644 index 00000000..0ef5793a --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Bullet.cpp @@ -0,0 +1,56 @@ +#include "cosmic_protector.hpp" + +bool Bullet::logic(int step) +{ + lifetime -= step; + if (lifetime <= 0) + return false; + + dx = speed * cosa * step; + dy = speed * sina * step; + + Entity *c; + if (playerOnly) + c = getPlayerCollision(); + else + c = getAllCollision(); + if (c && c != shooter) { + c->hit(damage); + my_play_sample(RES_COLLISION); + return false; + } + + Entity::wrap(); + + if (!Entity::logic(step)) + return false; + + return true; +} + +Bullet::Bullet(float x, float y, float radius, float speed, float angle, + int lifetime, int damage, int bitmapID, Entity *shooter) : + playerOnly(false) +{ + this->x = x; + this->y = y; + this->radius = radius; + this->speed = speed; + this->angle = angle; + this->lifetime = lifetime; + this->shooter = shooter; + this->damage = damage; + + cosa = cos(angle); + sina = sin(angle); + + ResourceManager& rm = ResourceManager::getInstance(); + bitmap = (ALLEGRO_BITMAP *)rm.getData(bitmapID); + + isDestructable = false; +} + +Bullet::~Bullet(void) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/ButtonWidget.cpp b/allegro/demos/cosmic_protector/src/ButtonWidget.cpp new file mode 100644 index 00000000..b15f7fa3 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/ButtonWidget.cpp @@ -0,0 +1,31 @@ +#include "cosmic_protector.hpp" + +bool ButtonWidget::activate(void) +{ + return false; +} + +void ButtonWidget::render(bool selected) +{ + ALLEGRO_FONT *myfont; + ResourceManager& rm = ResourceManager::getInstance(); + + if (center) { + if (selected) { + myfont = (ALLEGRO_FONT *)rm.getData(RES_LARGEFONT); + } + else { + myfont = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); + } + al_draw_textf(myfont, al_map_rgb(255, 255, 255), x, y-al_get_font_line_height(myfont)/2, ALLEGRO_ALIGN_CENTRE, "%s", text); + } +} + +ButtonWidget::ButtonWidget(int x, int y, bool center, const char *text) : + x(x), + y(y), + center(center), + text(text) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/Debug.cpp b/allegro/demos/cosmic_protector/src/Debug.cpp new file mode 100644 index 00000000..614bb2f7 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Debug.cpp @@ -0,0 +1,11 @@ +#include "cosmic_protector.hpp" + +void debug_message(const char * fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); +} + diff --git a/allegro/demos/cosmic_protector/src/DisplayResource.cpp b/allegro/demos/cosmic_protector/src/DisplayResource.cpp new file mode 100644 index 00000000..58b0fb13 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/DisplayResource.cpp @@ -0,0 +1,75 @@ +#include "cosmic_protector.hpp" + +bool useFullScreenMode = false; + +#ifdef ALLEGRO_IPHONE +int BB_W; +int BB_H; +#else +int BB_W = 800; +int BB_H = 600 ; +#endif + +void DisplayResource::destroy(void) +{ + if (!display) + return; + al_destroy_event_queue(events); + al_destroy_display(display); + display = 0; +} + +bool DisplayResource::load(void) +{ +#ifdef ALLEGRO_IPHONE + int flags = ALLEGRO_FULLSCREEN_WINDOW; + al_set_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE, ALLEGRO_REQUIRE); +#else + int flags = useFullScreenMode ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED; +#endif + al_set_new_display_flags(flags); + display = al_create_display(BB_W, BB_H); + if (!display) + return false; + +#ifndef ALLEGRO_IPHONE + ALLEGRO_BITMAP *bmp = al_load_bitmap(getResource("gfx/icon48.png")); + al_set_display_icon(display, bmp); + al_destroy_bitmap(bmp); +#endif + + BB_W = al_get_display_width(display); + BB_H = al_get_display_height(display); + +#ifdef ALLEGRO_IPHONE + if (BB_W < 960) { + BB_W *= 2; + BB_H *= 2; + ALLEGRO_TRANSFORM t; + al_identity_transform(&t); + al_scale_transform(&t, 0.5, 0.5); + al_use_transform(&t); + } +#endif + + events = al_create_event_queue(); + al_register_event_source(events, al_get_display_event_source(display)); + + return true; +} + +void* DisplayResource::get(void) +{ + return display; +} + +ALLEGRO_EVENT_QUEUE *DisplayResource::getEventQueue(void) +{ + return events; +} + +DisplayResource::DisplayResource(void) : + display(0) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/Entity.cpp b/allegro/demos/cosmic_protector/src/Entity.cpp new file mode 100644 index 00000000..a6e4d805 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Entity.cpp @@ -0,0 +1,189 @@ +#include "cosmic_protector.hpp" + +bool Entity::logic(int step) +{ + if (hp <= 0) { + spawn(); + ResourceManager& rm = ResourceManager::getInstance(); + Player *p = (Player *)rm.getData(RES_PLAYER); + p->addScore(points); + return false; + } + + if (hilightCount > 0) { + hilightCount -= step; + } + + return true; +} + +float Entity::getX(void) +{ + return x; +} + +float Entity::getY(void) +{ + return y; +} + +float Entity::getRadius(void) +{ + return radius; +} + +bool Entity::getDestructable(void) +{ + return isDestructable; +} + +bool Entity::isHighlighted(void) +{ + return hilightCount > 0; +} + +bool Entity::isUFO(void) +{ + return ufo; +} + +void Entity::setPowerUp(int type) +{ + powerup = type; +} + +void Entity::wrap(void) +{ + x += dx; + y += dy; + if (x < 0) + x += BB_W; + if (x >= BB_W) + x -= BB_W; + if (y < 0) + y += BB_H; + if (y >= BB_H) + y -= BB_H; +} + +void Entity::render_four(ALLEGRO_COLOR tint) +{ + int ox = 0; + render(0, 0, tint); + if (x > BB_W / 2) { + ox = -BB_W; + render(ox, 0, tint); + } + else { + ox = BB_W; + render(ox, 0, tint); + } + if (y > BB_H / 2) { + render(0, -BB_H, tint); + render(ox, -BB_H, tint); + } + else { + render(0, BB_H, tint); + render(ox, BB_H, tint); + } +} + +void Entity::render(int x, int y, ALLEGRO_COLOR c) +{ + (void)c; // To use c must override this in a sub-class. + render(x, y); +} + +Entity *Entity::checkCollisions(std::list<Entity *>& e) +{ + std::list<Entity *>::iterator it; + + for (it = e.begin(); it != e.end(); it++) { + Entity *entity = *it; + if (entity == this || !entity->getDestructable()) + continue; + float ex = entity->getX(); + float ey = entity->getY(); + float er = entity->getRadius(); + if (checkCircleCollision(ex, ey, er, x, y, radius)) + return entity; + } + + return 0; +} + +Entity *Entity::getPlayerCollision(void) +{ + std::list<Entity *> e; + + ResourceManager& rm = ResourceManager::getInstance(); + Player *player = (Player *)rm.getData(RES_PLAYER); + + e.push_back(player); + + Entity *ret = checkCollisions(e); + e.clear(); + return ret; +} + +Entity *Entity::getEntityCollision(void) +{ + return checkCollisions(entities); +} + +Entity *Entity::getAllCollision(void) +{ + Entity *e = getEntityCollision(); + if (e) + return e; + return getPlayerCollision(); +} + +// Returns true if dead +bool Entity::hit(int damage) +{ + hp -= damage; + + hilightCount = 500; + + if (hp <= 0) { + explode(); + return true; + } + + return false; +} + +void Entity::explode(void) +{ + bool big; + if (radius >= 32) + big = true; + else + big = false; + Explosion *e = new Explosion(x, y, big); + new_entities.push_back(e); + if (big) + my_play_sample(RES_BIGEXPLOSION); + else + my_play_sample(RES_SMALLEXPLOSION); +} + +void Entity::spawn(void) +{ + if (powerup >= 0) { + PowerUp *p = new PowerUp(x, y, powerup); + new_entities.push_back(p); + } +} + +Entity::Entity() : + isDestructable(true), + hp(1), + powerup(-1), + hilightCount(0), + points(0), + ufo(false) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/Explosion.cpp b/allegro/demos/cosmic_protector/src/Explosion.cpp new file mode 100644 index 00000000..de9a8fac --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Explosion.cpp @@ -0,0 +1,46 @@ +#include "cosmic_protector.hpp" + +bool Explosion::logic(int step) +{ + frameCount -= step; + if (frameCount <= 0) { + currFrame++; + frameCount = FRAME_TIME; + if (currFrame >= NUM_FRAMES) + return false; + } + + return true; +} + +void Explosion::render(int offx, int offy) +{ + ResourceManager& rm = ResourceManager::getInstance(); + ALLEGRO_BITMAP *bitmap; + int bitmapIndex; + + if (big) + bitmapIndex = RES_LARGEEXPLOSION0 + currFrame; + else + bitmapIndex = RES_SMALLEXPLOSION0 + currFrame; + + bitmap = (ALLEGRO_BITMAP *)rm.getData(bitmapIndex); + + al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, 0, 0); +} + +Explosion::Explosion(float x, float y, bool big) +{ + this->x = x; + this->y = y; + dx = 0.0f; + dy = 0.0f; + radius = (big) ? 32 : 12; + isDestructable = false; + hp = 1; + + frameCount = FRAME_TIME; + currFrame = 0; + this->big = big; +} + diff --git a/allegro/demos/cosmic_protector/src/FontResource.cpp b/allegro/demos/cosmic_protector/src/FontResource.cpp new file mode 100644 index 00000000..41d3cea0 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/FontResource.cpp @@ -0,0 +1,25 @@ +#include "cosmic_protector.hpp" + +void FontResource::destroy(void) +{ + al_destroy_font(font); + font = 0; +} + +bool FontResource::load(void) +{ + font = al_load_font(filename.c_str(), 0, 0); + return font != 0; +} + +void* FontResource::get(void) +{ + return font; +} + +FontResource::FontResource(const char *filename) : + font(0), + filename(filename) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/GUI.cpp b/allegro/demos/cosmic_protector/src/GUI.cpp new file mode 100644 index 00000000..8ca3640c --- /dev/null +++ b/allegro/demos/cosmic_protector/src/GUI.cpp @@ -0,0 +1,362 @@ +#include "cosmic_protector.hpp" +#include "joypad_c.h" + +#include <sys/stat.h> +#include <ctime> + +#ifdef ALLEGRO_MSVC + #define snprintf _snprintf +#endif + +static int do_gui(const std::vector<Widget *>& widgets, unsigned int selected) +{ + ResourceManager& rm = ResourceManager::getInstance(); + ALLEGRO_BITMAP *bg = (ALLEGRO_BITMAP *)rm.getData(RES_BACKGROUND); + Input *input = (Input *)rm.getData(RES_INPUT); + ALLEGRO_BITMAP *logo = (ALLEGRO_BITMAP *)rm.getData(RES_LOGO); + int lw = al_get_bitmap_width(logo); + int lh = al_get_bitmap_height(logo); +#ifndef ALLEGRO_IPHONE + ALLEGRO_FONT *myfont = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); +#endif + + bool redraw = true; + + for (;;) { + /* Catch close button presses */ + ALLEGRO_EVENT_QUEUE *events = ((DisplayResource *)rm.getResource(RES_DISPLAY))->getEventQueue(); + while (!al_is_event_queue_empty(events)) { + ALLEGRO_EVENT event; + al_get_next_event(events, &event); +#ifdef ALLEGRO_IPHONE + if (event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING || event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) { + switch_game_out(event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING); + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING || event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN) { + switch_game_in(); + } +#else + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + exit(0); +#endif + } + + input->poll(); +#if defined ALLEGRO_IPHONE + float ud; + if (is_joypad_connected()) { + ud = input->ud(); + } + else { + ud = input->lr(); + } +#else + float ud = input->ud(); +#endif + if (ud < 0 && selected) { + selected--; + my_play_sample(RES_FIRELARGE); + al_rest(0.200); + } + else if (ud > 0 && selected < (widgets.size()-1)) { + selected++; + my_play_sample(RES_FIRELARGE); + al_rest(0.200); + } + if (input->b1()) { + if (!widgets[selected]->activate()) + return selected; + } +#ifndef ALLEGRO_IPHONE + if (input->esc()) + return -1; +#endif + + redraw = true; + +#ifdef ALLEGRO_IPHONE + if (switched_out) { + redraw = false; + } +#endif + + al_rest(0.010); + + if (!redraw) { + continue; + } + + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + + /* draw */ + float h = al_get_bitmap_height(bg); + float w = al_get_bitmap_width(bg); + al_draw_bitmap(bg, (BB_W-w)/2, (BB_H-h)/2, 0); + + al_draw_bitmap(logo, (BB_W-lw)/2, (BB_H-lh)/4, 0); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); +#ifndef ALLEGRO_IPHONE + al_draw_textf(myfont, al_map_rgb(255, 255, 0), BB_W/2, BB_H/2, ALLEGRO_ALIGN_CENTRE, "z/y to start"); +#endif + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + for (unsigned int i = 0; i < widgets.size(); i++) { + widgets[i]->render(i == selected); + } + +#ifdef ALLEGRO_IPHONE + input->draw(); +#endif + + al_flip_display(); + } +} + +int do_menu(void) +{ + ButtonWidget play (BB_W/2, BB_H/4*3-16, true, "PLAY"); + ButtonWidget scores (BB_W/2, BB_H/4*3+16, true, "SCORES"); + ButtonWidget end (BB_W/2, BB_H/4*3+48, true, "EXIT"); + std::vector<Widget *> widgets; + widgets.push_back(&play); + widgets.push_back(&scores); + widgets.push_back(&end); + + return do_gui(widgets, 0); +} + +struct HighScore { + char name[4]; + int score; +}; + +#define NUM_SCORES 5 + +static HighScore highScores[NUM_SCORES] = { + { "AAA", 2000 }, + { "BAA", 1750 }, + { "AAC", 1500 }, + { "DAD", 1250 }, + { "AYE", 1000 } +}; + +static void insert_score(char *name, int score) +{ + int i; + for (i = NUM_SCORES-1; i >= 0; i--) { + if (highScores[i].score > score) { + i++; + break; + } + } + if (i < 0) i = 0; + if (i > (NUM_SCORES-1)) return; // yes, this is possible + + for (int j = NUM_SCORES-1; j > i; j--) { + strcpy(highScores[j].name, highScores[j-1].name); + highScores[j].score = highScores[j-1].score; + } + + strcpy(highScores[i].name, name); + highScores[i].score = score; +} + +static ALLEGRO_PATH *userResourcePath() +{ +#ifdef ALLEGRO_IPHONE + return al_get_standard_path(ALLEGRO_USER_DOCUMENTS_PATH); +#else + return al_get_standard_path(ALLEGRO_USER_SETTINGS_PATH); +#endif +} + +static void read_scores(void) +{ + ALLEGRO_PATH *fn = userResourcePath(); + + if (al_make_directory(al_path_cstr(fn, ALLEGRO_NATIVE_PATH_SEP))) { + al_set_path_filename(fn, "scores.cfg"); + ALLEGRO_CONFIG *cfg = al_load_config_file(al_path_cstr(fn, ALLEGRO_NATIVE_PATH_SEP)); + if (cfg) { + for (int i = 0; i < NUM_SCORES; i++) { + char name[] = {'n', (char)('0'+i), '\0'}; + char score[] = {'s', (char)('0'+i), '\0'}; + const char *v; + + v = al_get_config_value(cfg, "scores", name); + if (v && strlen(v) <= 3) { + strcpy(highScores[i].name, v); + } + v = al_get_config_value(cfg, "scores", score); + if (v) { + highScores[i].score = atoi(v); + } + } + + al_destroy_config(cfg); + } + } + + al_destroy_path(fn); +} + +static void write_scores(void) +{ + ALLEGRO_CONFIG *cfg = al_create_config(); + for (int i = 0; i < NUM_SCORES; i++) { + char name[] = {'n', (char)('0'+i), '\0'}; + char score[] = {'s', (char)('0'+i), '\0'}; + char sc[32]; + + al_set_config_value(cfg, "scores", name, highScores[i].name); + snprintf(sc, sizeof(sc), "%d", highScores[i].score); + al_set_config_value(cfg, "scores", score, sc); + } + + ALLEGRO_PATH *fn = userResourcePath(); + al_set_path_filename(fn, "scores.cfg"); + al_save_config_file(al_path_cstr(fn, ALLEGRO_NATIVE_PATH_SEP), cfg); + al_destroy_path(fn); + + al_destroy_config(cfg); +} + +void do_highscores(int score) +{ + read_scores(); + + ResourceManager& rm = ResourceManager::getInstance(); + Input *input = (Input *)rm.getData(RES_INPUT); + ALLEGRO_FONT *sm_font = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); + ALLEGRO_FONT *big_font = (ALLEGRO_FONT *)rm.getData(RES_LARGEFONT); + + bool is_high = score >= highScores[NUM_SCORES-1].score; + bool entering = is_high; + double bail_time = al_get_time() + 8; + int letter_num = 0; + char name[4] = " "; + int character = 0; + double next_input = al_get_time(); + double spin_start = 0; + int spin_dir = 1; + + for (;;) { + /* Catch close button presses */ + ALLEGRO_EVENT_QUEUE *events = ((DisplayResource *)rm.getResource(RES_DISPLAY))->getEventQueue(); + while (!al_is_event_queue_empty(events)) { + ALLEGRO_EVENT event; + al_get_next_event(events, &event); +#ifdef ALLEGRO_IPHONE + if (event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING || event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) { + switch_game_out(event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING); + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING || event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN) { + switch_game_in(); + } +#else + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + exit(0); +#endif + } + + input->poll(); + + if (entering && al_get_time() > next_input) { + float lr = input->lr(); + + if (lr != 0) { + if (lr < 0) { + character--; + if (character < 0) + character = 25; + spin_dir = 1; + } + else if (lr > 0) { + character++; + if (character >= 26) + character = 0; + spin_dir = -1; + } + next_input = al_get_time()+0.2; + my_play_sample(RES_FIRESMALL); + spin_start = al_get_time(); + } + + if (input->b1() && letter_num < 3) { + name[letter_num] = 'A' + character; + letter_num++; + if (letter_num >= 3) { + entering = false; + bail_time = al_get_time()+8; + insert_score(name, score); + write_scores(); + } + next_input = al_get_time()+0.2; + my_play_sample(RES_FIRELARGE); + } + } + else if (!entering) { + if (al_get_time() > bail_time) { + return; + } + else if (input->b1() && al_get_time() > next_input) { + al_rest(0.250); + return; + } + } + + al_rest(0.010); + +#ifdef ALLEGRO_IPHONE + if (switched_out) { + continue; + } +#endif + + al_clear_to_color(al_map_rgb(0, 0, 0)); + + if (entering) { + float a = ALLEGRO_PI*3/2; + float ainc = ALLEGRO_PI*2 / 26; + double elapsed = al_get_time() - spin_start; + if (elapsed < 0.1) { + a += (elapsed / 0.1) * ainc * spin_dir; + } + float scrh = BB_H / 2 - 32; + float h = al_get_font_line_height(sm_font); + for (int i = 0; i < 26; i++) { + int c = character + i; + if (c >= 26) + c -= 26; + char s[2]; + s[1] = 0; + s[0] = 'A' + c; + int x = BB_W/2 + (cos(a) * scrh) - al_get_text_width(sm_font, s); + int y = BB_H/2 + (sin(a) * scrh) - h/2; + al_draw_textf(sm_font, i == 0 ? al_map_rgb(255, 255, 0) : al_map_rgb(200, 200, 200), x, y, 0, "%s", s); + a += ainc; + } + char tmp[4] = { 0, }; + for (int i = 0; i < 3 && name[i] != ' '; i++) { + tmp[i] = name[i]; + } + al_draw_textf(big_font, al_map_rgb(0, 255, 0), BB_W/2, BB_H/2-20, ALLEGRO_ALIGN_CENTRE, "%s", tmp); + al_draw_text(sm_font, al_map_rgb(200, 200, 200), BB_W/2, BB_H/2-20+5+al_get_font_line_height(big_font), ALLEGRO_ALIGN_CENTRE, "high score!"); + } + else { + int yy = BB_H/2 - al_get_font_line_height(big_font)*NUM_SCORES/2; + for (int i = 0; i < NUM_SCORES; i++) { + al_draw_textf(big_font, al_map_rgb(255, 255, 255), BB_W/2-10, yy, ALLEGRO_ALIGN_RIGHT, "%s", highScores[i].name); + al_draw_textf(big_font, al_map_rgb(255, 255, 0), BB_W/2+10, yy, ALLEGRO_ALIGN_LEFT, "%d", highScores[i].score); + yy += al_get_font_line_height(big_font); + } + } + +#ifdef ALLEGRO_IPHONE + input->draw(); +#endif + + al_flip_display(); + } +} diff --git a/allegro/demos/cosmic_protector/src/Game.cpp b/allegro/demos/cosmic_protector/src/Game.cpp new file mode 100644 index 00000000..c0c1edbf --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Game.cpp @@ -0,0 +1,176 @@ +#include <stdio.h> +#include "cosmic_protector.hpp" +#include "joypad_c.h" + +#ifdef ALLEGRO_ANDROID + #include "allegro5/allegro_android.h" + #define IS_ANDROID (true) + #define IS_MSVC (false) +#elif defined(ALLEGRO_MSVC) + #define IS_ANDROID (false) + #define IS_MSVC (true) + #define snprintf _snprintf +#else + #define IS_ANDROID (false) + #define IS_MSVC (false) +#endif + +bool kb_installed = false; +bool joy_installed = false; + +/* + * Return the path to user resources (save states, configuration) + */ + +static ALLEGRO_PATH* getDir() +{ + ALLEGRO_PATH *dir; + + if (IS_ANDROID) { + /* Path within the APK, not normal filesystem. */ + dir = al_create_path_for_directory("data"); + } + else { + dir = al_get_standard_path(ALLEGRO_RESOURCES_PATH); + if (IS_MSVC) { + /* Hack to cope automatically with MSVC workspaces. */ + const char *last = al_get_path_component(dir, -1); + if (0 == strcmp(last, "Debug") + || 0 == strcmp(last, "RelWithDebInfo") + || 0 == strcmp(last, "Release") + || 0 == strcmp(last, "Profile")) { + al_remove_path_component(dir, -1); + } + } + al_append_path_component(dir, "data"); + } + return dir; +} + +const char* getResource(const char* fmt, ...) +{ + va_list ap; + static char res[512]; + static ALLEGRO_PATH *dir; + static ALLEGRO_PATH *path; + + va_start(ap, fmt); + memset(res, 0, 512); + snprintf(res, 511, fmt, ap); + + if (!dir) + dir = getDir(); + + if (path) + al_destroy_path(path); + + path = al_create_path(res); + al_rebase_path(dir, path); + return al_path_cstr(path, '/'); +} + + +bool loadResources(void) +{ + ResourceManager& rm = ResourceManager::getInstance(); + if (!rm.add(new DisplayResource())) { + printf("Failed to create display.\n"); + return false; + } + + /* For some reason dsound needs a window... */ + if (!al_install_audio()) { + printf("Failed to install audio.\n"); + /* Continue anyway. */ + } + else { + al_reserve_samples(16); + } + + if (!rm.add(new Player(), false)) { + printf("Failed to create player.\n"); + return false; + } + if (!rm.add(new Input())) { + printf("Failed initializing input.\n"); + return false; + } + + // Load fonts + if (!rm.add(new FontResource(getResource("gfx/large_font.png")))) + return false; + if (!rm.add(new FontResource(getResource("gfx/small_font.png")))) + return false; + + for (int i = 0; BMP_NAMES[i]; i++) { + if (!rm.add(new BitmapResource(getResource(BMP_NAMES[i])))) { + printf("Failed to load %s\n", getResource(BMP_NAMES[i])); + return false; + } + } + + for (int i = 0; SAMPLE_NAMES[i]; i++) { + if (!rm.add(new SampleResource(getResource(SAMPLE_NAMES[i])))) { + /* Continue anyway. */ + } + } + + for (int i = 0; STREAM_NAMES[i]; i++) { + if (!rm.add(new StreamResource(getResource(STREAM_NAMES[i])))) { + /* Continue anyway. */ + } + } + + joypad_start(); + + return true; +} + +bool init(void) +{ + srand(time(NULL)); + if (!al_init()) { + debug_message("Error initialising Allegro.\n"); + return false; + } + al_set_org_name("Allegro"); + al_set_app_name("Cosmic Protector"); + al_init_image_addon(); + al_init_font_addon(); + al_init_acodec_addon(); + al_init_primitives_addon(); +#ifdef ALLEGRO_ANDROID + al_android_set_apk_file_interface(); +#endif + + if (!loadResources()) { + debug_message("Error loading resources.\n"); + return false; + } + + return true; +} + +void done(void) +{ + // Free resources + al_stop_samples(); + ResourceManager& rm = ResourceManager::getInstance(); + for (int i = RES_STREAM_START; i < RES_STREAM_END; i++) { + ALLEGRO_AUDIO_STREAM *s = (ALLEGRO_AUDIO_STREAM *)rm.getData(i); + if (s) + al_set_audio_stream_playing(s, false); + } + + ResourceManager::getInstance().destroy(); +} + +// Returns a random number between lo and hi +float randf(float lo, float hi) +{ + float range = hi - lo; + int n = rand() % 10000; + float f = range * n / 10000.0f; + return lo + f; +} + diff --git a/allegro/demos/cosmic_protector/src/Input.cpp b/allegro/demos/cosmic_protector/src/Input.cpp new file mode 100644 index 00000000..71e65733 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Input.cpp @@ -0,0 +1,330 @@ +#include "cosmic_protector.hpp" +#include "joypad_c.h" + +#ifdef ALLEGRO_IPHONE +#include <allegro5/allegro_iphone.h> +#endif + +#ifdef ALLEGRO_MSVC +/* "forcing value to bool 'true' or 'false' (performance warning)" */ +#pragma warning( disable : 4800 ) +#endif + +Input::Input() : + joystick(0) +{ + memset(&kbdstate, 0, sizeof(ALLEGRO_KEYBOARD_STATE)); + memset(&joystate, 0, sizeof(ALLEGRO_JOYSTICK_STATE)); +#ifdef ALLEGRO_IPHONE + joyaxis0 = 0.0f; + joyaxis1 = 0.0f; + joyaxis2 = 0.0f; +#endif +} + +Input::~Input() +{ +} + +#ifdef ALLEGRO_IPHONE +void Input::draw(void) +{ + if (is_joypad_connected()) + return; + + int y = controls_at_top ? 0 : BB_H-size; + int ymid = y + size/2; + int ybot = y + size; + int thick = 35; + + ALLEGRO_COLOR tri_color = al_map_rgba_f(0.4, 0.4, 0.4, 0.4); + ALLEGRO_COLOR fire_color = al_map_rgba_f(0.4, 0.1, 0.1, 0.4); + + al_draw_triangle(thick, ymid, size-thick, y+thick, size-thick, ybot-thick, tri_color, thick/4); + al_draw_triangle(size*2-thick, ymid, size+thick, y+thick, size+thick, ybot-thick, tri_color, thick/4); + + al_draw_filled_circle(BB_W-size/2, ymid, (size-thick)/2, fire_color); +} + +bool Input::button_pressed(int x, int y, int w, int h, bool check_if_controls_at_top) +{ + ResourceManager& rm = ResourceManager::getInstance(); + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)rm.getData(RES_DISPLAY); + + if (al_get_display_width(display) < 960) { + x /= 2; + y /= 2; + w /= 2; + h /= 2; + } + + if (check_if_controls_at_top) { + if (controls_at_top) { + y -= (BB_H-size); + } + } + + #define COLL(xx, yy) (xx >= x && xx <= x+w && yy >= y && yy <= y+h) + + for (size_t i = 0; i < touches.size(); i++) { + if (COLL(touches[i].x, touches[i].y)) { + return true; + } + } + + return false; +} +#endif + +void Input::poll(void) +{ + if (is_joypad_connected()) { + get_joypad_state(&joypad_u, &joypad_d, &joypad_l, &joypad_r, &joypad_b, &joypad_esc); + return; + } + +#ifdef ALLEGRO_IPHONE + while (!al_event_queue_is_empty(input_queue)) { + ALLEGRO_EVENT e; + al_get_next_event(input_queue, &e); + if (e.type == ALLEGRO_EVENT_TOUCH_BEGIN) { + Touch t; + t.id = e.touch.id; + t.x = e.touch.x; + t.y = e.touch.y; + int xx = t.x; + int yy = t.y; + ResourceManager& rm = ResourceManager::getInstance(); + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)rm.getData(RES_DISPLAY); + if (al_get_display_width(display) < 960) { + xx *= 2; + yy *= 2; + } + if (xx > (BB_W/5*2) && xx < (BB_W/5*3)) { + if (yy < BB_H / 3) { + controls_at_top = true; + } + else if (yy > BB_H*2/3) { + controls_at_top = false; + } + } + touches.push_back(t); + } + else if (e.type == ALLEGRO_EVENT_TOUCH_END) { + for (size_t i = 0; i < touches.size(); i++) { + if (touches[i].id == e.touch.id) { + touches.erase(touches.begin() + i); + break; + } + } + } + else if (e.type == ALLEGRO_EVENT_TOUCH_MOVE) { + for (size_t i = 0; i < touches.size(); i++) { + if (touches[i].id == e.touch.id) { + touches[i].x = e.touch.x; + touches[i].y = e.touch.y; + break; + } + } + } + else if (e.type == ALLEGRO_EVENT_JOYSTICK_AXIS) { + if (e.joystick.axis == 0) { + joyaxis0 = e.joystick.pos; + } + else if (e.joystick.axis == 1) { + joyaxis1 = e.joystick.pos; + } + else { + joyaxis2 = e.joystick.pos; + } + } + } +#else + while (!al_event_queue_is_empty(input_queue)) { + ALLEGRO_EVENT e; + al_get_next_event(input_queue, &e); + if (e.type == ALLEGRO_EVENT_JOYSTICK_CONFIGURATION) { + al_reconfigure_joysticks(); + if (al_get_num_joysticks() <= 0) { + joystick = NULL; + } + else { + joystick = al_get_joystick(0); + } + } + } + if (kb_installed) + al_get_keyboard_state(&kbdstate); + if (joystick) + al_get_joystick_state(joystick, &joystate); +#endif +} + +float Input::lr(void) +{ + if (is_joypad_connected()) { + if (joypad_l) return -1; + if (joypad_r) return 1; + return 0; + } + +#ifdef ALLEGRO_IPHONE + if (button_pressed(0, BB_H-size, size, size)) + return -1; + return button_pressed(size, BB_H-size, size, size) ? 1 : 0; +#else + if (al_key_down(&kbdstate, ALLEGRO_KEY_LEFT)) + return -1.0f; + else if (al_key_down(&kbdstate, ALLEGRO_KEY_RIGHT)) + return 1.0f; + else if (joystick) { + float pos = joystate.stick[0].axis[0]; + return fabs(pos) > 0.1 ? pos : 0; + } + else + return 0; +#endif +} + +float Input::ud(void) +{ + if (is_joypad_connected()) { + if (joypad_u) return -1; + if (joypad_d) return 1; + return 0; + } + +#ifdef ALLEGRO_IPHONE + float magnitude = fabs(joyaxis0) + fabs(joyaxis1); + if (magnitude < 0.3) return 0; + ResourceManager& rm = ResourceManager::getInstance(); + Player *player = (Player *)rm.getData(RES_PLAYER); + float player_a = player->getAngle(); + + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)rm.getData(RES_DISPLAY); + if (al_get_display_orientation(display) == ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES) + player_a = player_a - ALLEGRO_PI; + + while (player_a < 0) player_a += ALLEGRO_PI*2; + while (player_a > ALLEGRO_PI*2) player_a -= ALLEGRO_PI*2; + + float device_a = atan2(-joyaxis0, -joyaxis1); + if (device_a < 0) device_a += ALLEGRO_PI*2; + + float ab = fabs(player_a - device_a); + if (ab < ALLEGRO_PI/4) + return -1; + + // brake against velocity vector + float vel_a, dx, dy; + player->getSpeed(&dx, &dy); + vel_a = atan2(dy, dx); + vel_a -= ALLEGRO_PI; + if (al_get_display_orientation(display) == ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES) + vel_a = vel_a - ALLEGRO_PI; + + while (vel_a < 0) vel_a += ALLEGRO_PI*2; + while (vel_a > ALLEGRO_PI*2) vel_a -= ALLEGRO_PI*2; + + ab = fabs(vel_a - device_a); + if (ab < ALLEGRO_PI/4) + return 1; + + return 0; + +#else + if (al_key_down(&kbdstate, ALLEGRO_KEY_UP)) + return -1.0f; + else if (al_key_down(&kbdstate, ALLEGRO_KEY_DOWN)) + return 1.0f; + else if (joystick) { + float pos = joystate.stick[0].axis[1]; + return fabs(pos) > 0.1 ? pos : 0; + } + else + return 0; +#endif +} + +bool Input::esc(void) +{ + if (is_joypad_connected()) { + return joypad_esc; + } + + if (al_key_down(&kbdstate, ALLEGRO_KEY_ESCAPE)) + return true; + else if (joystick) + return joystate.button[1]; + else + return 0; +} + +bool Input::b1(void) +{ + if (is_joypad_connected()) { + return joypad_b; + } + +#ifdef ALLEGRO_IPHONE + return button_pressed(BB_W-size, BB_H-size, size, size) ? 1 : 0; +#else + if (al_key_down(&kbdstate, ALLEGRO_KEY_Z) || al_key_down(&kbdstate, ALLEGRO_KEY_Y)) + return true; + else if (joystick) + return joystate.button[0]; + else + return 0; +#endif +} + +bool Input::cheat(void) +{ + if (al_key_down(&kbdstate, ALLEGRO_KEY_LSHIFT) + && al_key_down(&kbdstate, ALLEGRO_KEY_EQUALS)) + return true; + else + return false; +} + +void Input::destroy(void) +{ +} + +bool Input::load(void) +{ + input_queue = al_create_event_queue(); +#ifdef ALLEGRO_IPHONE + al_install_touch_input(); + al_register_event_source(input_queue, al_get_touch_input_event_source()); + controls_at_top = false; + size = BB_W / 5; +#else + if (!kb_installed) + kb_installed = al_install_keyboard(); +#endif + if (!joy_installed) + joy_installed = al_install_joystick(); + + if (joy_installed && !joystick && al_get_num_joysticks()) { + joystick = al_get_joystick(0); + } + if (kb_installed) + debug_message("Keyboard driver installed.\n"); + if (joystick) + debug_message("Joystick found.\n"); + + if (joystick) + al_register_event_source(input_queue, al_get_joystick_event_source()); + +#ifdef ALLEGRO_IPHONE + return true; +#else + return kb_installed || joystick; +#endif +} + +void* Input::get(void) +{ + return this; +} diff --git a/allegro/demos/cosmic_protector/src/LargeAsteroid.cpp b/allegro/demos/cosmic_protector/src/LargeAsteroid.cpp new file mode 100644 index 00000000..b0317047 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/LargeAsteroid.cpp @@ -0,0 +1,39 @@ +#include "cosmic_protector.hpp" + +void LargeAsteroid::spawn(void) +{ + // Break into small fragments + for (int i = 0; i < 2; i++) { + float dx = randf(0.06f, 0.12f); + float dy = randf(0.04f, 0.08f); + float da = randf(0.001, 0.005); + if (rand() % 2) dx = -dx; + if (rand() % 2) dy = -dy; + if (rand() % 2) da = -da; + MediumAsteroid *ma = new MediumAsteroid(); + ma->init(x, y, dx, dy, da); + new_entities.push_back(ma); + } + + Entity::spawn(); +} + +LargeAsteroid::LargeAsteroid() : + Asteroid(32, RES_LARGEASTEROID) +{ + hp = 6; + points = 100; +} + +LargeAsteroid::LargeAsteroid(float x, float y, float speed_x, float speed_y, float da) : + Asteroid(32, RES_LARGEASTEROID) +{ + init(x, y, speed_x, speed_y, da); + hp = 6; + points = 100; +} + +LargeAsteroid::~LargeAsteroid() +{ +} + diff --git a/allegro/demos/cosmic_protector/src/LargeBullet.cpp b/allegro/demos/cosmic_protector/src/LargeBullet.cpp new file mode 100644 index 00000000..316eba33 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/LargeBullet.cpp @@ -0,0 +1,13 @@ +#include "cosmic_protector.hpp" + +void LargeBullet::render(int offx, int offy) +{ + al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, + angle+(ALLEGRO_PI/2), 0); +} + +LargeBullet::LargeBullet(float x, float y, float angle, Entity *shooter) : + Bullet(x, y, 6, 0.6f, angle, 600, 2, RES_LARGEBULLET, shooter) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/LargeSlowBullet.cpp b/allegro/demos/cosmic_protector/src/LargeSlowBullet.cpp new file mode 100644 index 00000000..34a56014 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/LargeSlowBullet.cpp @@ -0,0 +1,10 @@ +#include "cosmic_protector.hpp" + +LargeSlowBullet::LargeSlowBullet(float x, float y, float angle, Entity *shooter) : + LargeBullet(x, y, angle, shooter) +{ + speed = 0.20f; + lifetime += 1000; + playerOnly = true; +} + diff --git a/allegro/demos/cosmic_protector/src/MediumAsteroid.cpp b/allegro/demos/cosmic_protector/src/MediumAsteroid.cpp new file mode 100644 index 00000000..4e35cc43 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/MediumAsteroid.cpp @@ -0,0 +1,31 @@ +#include "cosmic_protector.hpp" + +void MediumAsteroid::spawn(void) +{ + // Break into small fragments + for (int i = 0; i < 3; i++) { + float dx = randf(0.06f, 0.12f); + float dy = randf(0.04f, 0.08f); + float da = randf(0.001, 0.005); + if (rand() % 2) dx = -dx; + if (rand() % 2) dy = -dy; + if (rand() % 2) da = -da; + SmallAsteroid *sa = new SmallAsteroid(); + sa->init(x, y, dx, dy, da); + new_entities.push_back(sa); + } + + Entity::spawn(); +} + +MediumAsteroid::MediumAsteroid() : + Asteroid(20, RES_MEDIUMASTEROID) +{ + hp = 4; + points = 50; +} + +MediumAsteroid::~MediumAsteroid() +{ +} + diff --git a/allegro/demos/cosmic_protector/src/Player.cpp b/allegro/demos/cosmic_protector/src/Player.cpp new file mode 100644 index 00000000..ed536b72 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Player.cpp @@ -0,0 +1,369 @@ +#include "cosmic_protector.hpp" + +const float Player::MAX_SPEED = 10.0f; +const float Player::MIN_SPEED = -10.0f; +const float Player::ACCEL = 0.006f; +const float Player::DECCEL = 0.001f; + +bool Player::logic(int step) +{ + if (!isDestructable && invincibleCount > 0) { + invincibleCount -= step; + if (invincibleCount <= 0) { + isDestructable = true; + if (lives <= 0) + return false; + } + } + + if (lives <= 0) + return true; + + ResourceManager& rm = ResourceManager::getInstance(); + Input *input = (Input *)rm.getData(RES_INPUT); + + if (input->lr() < 0.0f) { + angle -= 0.005f * step; + } + else if (input->lr() > 0.0f) { + angle += 0.005f * step; + } + + if (input->ud() < 0.0f) { + dx += ACCEL * step * cos(angle); + if (dx > MAX_SPEED) + dx = MAX_SPEED; + else if (dx < MIN_SPEED) + dx = MIN_SPEED; + dy += ACCEL * step * sin(angle); + if (dy > MAX_SPEED) + dy = MAX_SPEED; + else if (dy < MIN_SPEED) + dy = MIN_SPEED; + draw_trail = true; + } + else if (input->ud() > 0.0f) { + if (dx > 0) + dx -= ACCEL * step; + else if (dx < 0) + dx += ACCEL * step; + if (dx > -0.1f && dx < 0.1f) + dx = 0; + if (dy > 0) + dy -= ACCEL * step; + else if (dy < 0) + dy += ACCEL * step; + if (dy > -0.1f && dy < 0.1f) + dy = 0; + draw_trail = false; + } + else { + if (dx > 0) + dx -= DECCEL * step; + else if (dx < 0) + dx += DECCEL * step; + if (dx > -0.1f && dx < 0.1f) + dx = 0; + if (dy > 0) + dy -= DECCEL * step; + else if (dy < 0) + dy += DECCEL * step; + if (dy > -0.1f && dy < 0.1f) + dy = 0; + draw_trail = false; + } + + int shotRate; + switch (weapon) { + case WEAPON_SMALL: + shotRate = 300; + break; + case WEAPON_LARGE: + shotRate = 250; + break; + default: + shotRate = INT_MAX; + break; + } + + int now = (int) (al_get_time() * 1000.0); + if ((lastShot+shotRate) < now && input->b1()) { + lastShot = now; + float realAngle = angle; + float bx = x + radius * cos(realAngle); + float by = y + radius * sin(realAngle); + Bullet *b = 0; + int resourceID = RES_FIRESMALL; + switch (weapon) { + case WEAPON_SMALL: + b = new SmallBullet(bx, by, angle, this); + resourceID = RES_FIRESMALL; + break; + case WEAPON_LARGE: + b = new LargeBullet(bx, by, angle, this); + resourceID = RES_FIRELARGE; + break; + } + if (b) { + my_play_sample(resourceID); + new_entities.push_back(b); + } + } + + if (input->cheat()) { + al_rest(0.250); + std::list<Entity *>::iterator it; + for (it = entities.begin(); it != entities.end(); it++) { + Entity *e = *it; + delete e; + } + entities.clear(); + } + + Entity::wrap(); + + if (!Entity::logic(step)) + return false; + + return true; +} + +void Player::render_extra(void) +{ + ResourceManager& rm = ResourceManager::getInstance(); + + if (lives <= 0) { + int w = al_get_bitmap_width(highscoreBitmap); + int h = al_get_bitmap_height(highscoreBitmap); + al_draw_bitmap(highscoreBitmap, (BB_W-w)/2, (BB_H-h)/2, 0); + return; + } + + ALLEGRO_STATE st; + al_store_state(&st, ALLEGRO_STATE_BLENDER); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + al_draw_bitmap(icon, 1, 2, 0); + al_restore_state(&st); + ALLEGRO_FONT *small_font = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); + al_draw_textf(small_font, al_map_rgb(255, 255, 255), 20, 2, 0, "x%d", lives); + al_draw_textf(small_font, al_map_rgb(255, 255, 255), 2, 18, 0, "%d", score); +} + +void Player::render(int offx, int offy, ALLEGRO_COLOR tint) +{ + if (lives <= 0) + return; + + int rx = (int)(offx + x), ry = (int)(offy + y); + + if (!isDestructable) { + al_draw_tinted_rotated_bitmap(trans_bitmap, tint, + draw_radius, draw_radius, rx, ry, + angle+(ALLEGRO_PI/2.0f), 0); + } + else { + al_draw_tinted_rotated_bitmap(bitmap, + tint, draw_radius, draw_radius, rx, ry, + angle+(ALLEGRO_PI/2.0f), 0); + } + if (draw_trail) { + int tw = al_get_bitmap_width(trail_bitmap); + int th = al_get_bitmap_height(trail_bitmap); + float ca = (ALLEGRO_PI*2)+angle; + float a = ca + ((210.0f / 180.0f) * ALLEGRO_PI); + float tx = rx + 42.0f * cos(a); + float ty = ry + 42.0f * sin(a); + al_draw_tinted_rotated_bitmap(trail_bitmap, tint, tw, th/2, + tx, ty, a, 0); + a = ca + ((150.0f / 180.0f) * ALLEGRO_PI); + tx = rx + 42.0f * cos(a); + ty = ry + 42.0f * sin(a); + al_draw_tinted_rotated_bitmap(trail_bitmap, tint, tw, th/2, + tx, ty, a, 0); + } +} + +void Player::render(int offx, int offy) +{ + render(offx, offy, al_map_rgb(255, 255, 255)); +} + +bool Player::hit(int damage) +{ + Entity::hit(damage); + die(); + return true; +} + +Player::Player() : + weapon(WEAPON_SMALL), + lastShot(0), + score(0), + bitmap(0), + trans_bitmap(0), + trail_bitmap(0), + icon(0), + highscoreBitmap(0) +{ +} + +Player::~Player() +{ +} + +void Player::destroy(void) +{ + al_destroy_bitmap(bitmap); + al_destroy_bitmap(trans_bitmap); + al_destroy_bitmap(trail_bitmap); + al_destroy_bitmap(icon); + al_destroy_bitmap(highscoreBitmap); + bitmap = 0; + trans_bitmap = 0; + trail_bitmap = 0; + icon = 0; + highscoreBitmap = 0; +} + +bool Player::load(void) +{ + ALLEGRO_STATE state; + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); + + bitmap = al_load_bitmap(getResource("gfx/ship.png")); + if (!bitmap) { + debug_message("Error loading %s\n", getResource("gfx/ship.png")); + return false; + } + + trans_bitmap = al_create_bitmap(al_get_bitmap_width(bitmap), + al_get_bitmap_height(bitmap)); + if (!trans_bitmap) { + debug_message("Error loading %s\n", getResource("gfx/ship_trans.png")); + al_destroy_bitmap(bitmap); + return false; + } + + /* Make a translucent copy of the ship */ + al_set_target_bitmap(trans_bitmap); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_tinted_bitmap(bitmap, al_map_rgba(255, 255, 255, 160), + 0, 0, 0); + al_restore_state(&state); + + trail_bitmap = al_load_bitmap(getResource("gfx/trail.png")); + if (!trail_bitmap) { + debug_message("Error loading %s\n", getResource("gfx/trail.png")); + al_destroy_bitmap(bitmap); + al_destroy_bitmap(trans_bitmap); + return false; + } + + icon = al_load_bitmap(getResource("gfx/ship_icon.tga")); + if (!icon) { + debug_message("Error loading %s\n", getResource("gfx/ship_icon.tga")); + al_destroy_bitmap(bitmap); + al_destroy_bitmap(trans_bitmap); + al_destroy_bitmap(trail_bitmap); + return false; + } + + highscoreBitmap = al_create_bitmap(300, 200); + al_set_target_bitmap(highscoreBitmap); + al_clear_to_color(al_map_rgba(0, 0, 0, 0)); + + al_restore_state(&state); + + draw_radius = al_get_bitmap_width(bitmap)/2; + radius = draw_radius / 2; + + newGame(); + reset(); + + return true; +} + +void* Player::get(void) +{ + return this; +} + +void Player::newGame(void) +{ + lives = 5; + hp = 1; + score = 0; + isDestructable = true; +} + +void Player::reset(void) +{ + x = BB_W/2; + y = BB_H/2; + dx = 0; + dy = 0; + angle = -ALLEGRO_PI/2; + draw_trail = false; + weapon = WEAPON_SMALL; +} + +void Player::die(void) +{ + shake(); + reset(); + + lives--; + if (lives <= 0) { + // game over + isDestructable = false; + invincibleCount = 8000; + ALLEGRO_BITMAP *old_target = al_get_target_bitmap(); + al_set_target_bitmap(highscoreBitmap); + int w = al_get_bitmap_width(highscoreBitmap); + int h = al_get_bitmap_height(highscoreBitmap); + ResourceManager& rm = ResourceManager::getInstance(); + ALLEGRO_FONT *large_font = (ALLEGRO_FONT *)rm.getData(RES_LARGEFONT); + ALLEGRO_FONT *small_font = (ALLEGRO_FONT *)rm.getData(RES_SMALLFONT); + al_draw_textf(large_font, al_map_rgb(255, 255, 255), w/2, h/2-16, ALLEGRO_ALIGN_CENTRE, "GAME OVER"); + al_draw_textf(small_font, al_map_rgb(255, 255, 255), w/2, h/2+16, ALLEGRO_ALIGN_CENTRE, "%d Points", score); + al_set_target_bitmap(old_target); + } + else { + hp = 1; + isDestructable = false; + invincibleCount = 3000; + } +} + +void Player::givePowerUp(int type) +{ + switch (type) { + case POWERUP_LIFE: + lives++; + break; + case POWERUP_WEAPON: + weapon = WEAPON_LARGE; + break; + } +} + +void Player::addScore(int points) +{ + score += points; +} + +int Player::getScore(void) +{ + return score; +} + +float Player::getAngle(void) +{ + return angle; +} + +void Player::getSpeed(float *dx, float *dy) +{ + *dx = this->dx; + *dy = this->dy; +} diff --git a/allegro/demos/cosmic_protector/src/PowerUp.cpp b/allegro/demos/cosmic_protector/src/PowerUp.cpp new file mode 100644 index 00000000..683b6125 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/PowerUp.cpp @@ -0,0 +1,59 @@ +#include "cosmic_protector.hpp" + +bool PowerUp::logic(int step) +{ + angle += da * step; + + x += dx; + y += dy; + + if (x < -radius || x > BB_W+radius || y < -radius || y > BB_H+radius) { + return false; + } + + Player *p = (Player *)getPlayerCollision(); + if (p) { + p->givePowerUp(type); + my_play_sample(RES_POWERUP); + return false; + } + + if (!Entity::logic(step)) + return false; + + return true; +} + +void PowerUp::render(int offx, int offy) +{ + al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, angle, 0); +} + +PowerUp::PowerUp(float x, float y, int type) : + SPIN_SPEED(0.002f) +{ + this->x = x; + this->y = y; + this->type = type; + + dx = randf(0.5f, 1.2f); + dy = randf(0.5f, 1.2f); + radius = 16; + isDestructable = false; + hp = 1; + + da = (rand() % 2) ? -SPIN_SPEED : SPIN_SPEED; + + ResourceManager& rm = ResourceManager::getInstance(); + + switch (type) { + case POWERUP_LIFE: + bitmap = (ALLEGRO_BITMAP *)rm.getData(RES_LIFEPOWERUP); + break; + default: + type = POWERUP_WEAPON; + bitmap = (ALLEGRO_BITMAP *)rm.getData(RES_WEAPONPOWERUP); + break; + } +} + diff --git a/allegro/demos/cosmic_protector/src/Resource.cpp b/allegro/demos/cosmic_protector/src/Resource.cpp new file mode 100644 index 00000000..67fc4b35 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/Resource.cpp @@ -0,0 +1,44 @@ +#include "cosmic_protector.hpp" + +const char* BMP_NAMES[] = { + "gfx/large_asteroid.png", + "gfx/small_asteroid.png", + "gfx/background.jpg", + "gfx/small_bullet.png", + "gfx/large_explosion_0.png", + "gfx/large_explosion_1.png", + "gfx/large_explosion_2.png", + "gfx/large_explosion_3.png", + "gfx/large_explosion_4.png", + "gfx/small_explosion_0.png", + "gfx/small_explosion_1.png", + "gfx/small_explosion_2.png", + "gfx/small_explosion_3.png", + "gfx/small_explosion_4.png", + "gfx/medium_asteroid.png", + "gfx/large_bullet.png", + "gfx/weapon_powerup.png", + "gfx/life_powerup.png", + "gfx/ufo0.png", + "gfx/ufo1.png", + "gfx/ufo2.png", + "gfx/logo.png", + 0 +}; + +const char* SAMPLE_NAMES[] = { + "sfx/big_explosion.ogg", + "sfx/collision.ogg", + "sfx/fire_large.ogg", + "sfx/fire_small.ogg", + "sfx/small_explosion.ogg", + "sfx/powerup.ogg", + 0 +}; + +const char* STREAM_NAMES[] = { + "sfx/title_music.ogg", + "sfx/game_music.ogg", + 0 +}; + diff --git a/allegro/demos/cosmic_protector/src/ResourceManager.cpp b/allegro/demos/cosmic_protector/src/ResourceManager.cpp new file mode 100644 index 00000000..6577f916 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/ResourceManager.cpp @@ -0,0 +1,53 @@ +#include "cosmic_protector.hpp" + +ResourceManager* ResourceManager::rm = 0; + +ResourceManager& ResourceManager::getInstance(void) +{ + if (!rm) + rm = new ResourceManager(); + return *rm; +} + +void ResourceManager::destroy(void) +{ + std::vector<Resource*>::reverse_iterator it; + + for (it = resources.rbegin(); it != resources.rend(); it++) { + Resource* r = *it; + r->destroy(); + delete r; + } + + resources.clear(); + + delete rm; + rm = 0; +} + +bool ResourceManager::add(Resource* res, bool load) +{ + // We have to add the resource even if loading fails, if we want to be able + // to continue without the resource (e.g. samples). + resources.push_back(res); + if (load) { + if (!res->load()) + return false; + } + return true; +} + +Resource* ResourceManager::getResource(int index) +{ + return resources[index]; +} + +void* ResourceManager::getData(int index) +{ + return getResource(index)->get(); +} + +ResourceManager::ResourceManager(void) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/SampleResource.cpp b/allegro/demos/cosmic_protector/src/SampleResource.cpp new file mode 100644 index 00000000..16bf8a3c --- /dev/null +++ b/allegro/demos/cosmic_protector/src/SampleResource.cpp @@ -0,0 +1,35 @@ +#include "cosmic_protector.hpp" + +void SampleResource::destroy(void) +{ + al_destroy_sample(sample_data); + sample_data = 0; +} + +bool SampleResource::load(void) +{ + if (!al_is_audio_installed()) { + debug_message("Skipped loading sample %s\n", filename.c_str()); + return true; + } + + sample_data = al_load_sample(filename.c_str()); + if (!sample_data) { + debug_message("Error loading sample %s\n", filename.c_str()); + return false; + } + + return true; +} + +void* SampleResource::get(void) +{ + return sample_data; +} + +SampleResource::SampleResource(const char* filename) : + sample_data(0), + filename(filename) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/SmallAsteroid.cpp b/allegro/demos/cosmic_protector/src/SmallAsteroid.cpp new file mode 100644 index 00000000..c7d67ad0 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/SmallAsteroid.cpp @@ -0,0 +1,12 @@ +#include "cosmic_protector.hpp" + +SmallAsteroid::SmallAsteroid() : + Asteroid(10, RES_SMALLASTEROID) +{ + points = 10; +} + +SmallAsteroid::~SmallAsteroid() +{ +} + diff --git a/allegro/demos/cosmic_protector/src/SmallBullet.cpp b/allegro/demos/cosmic_protector/src/SmallBullet.cpp new file mode 100644 index 00000000..555c82bf --- /dev/null +++ b/allegro/demos/cosmic_protector/src/SmallBullet.cpp @@ -0,0 +1,12 @@ +#include "cosmic_protector.hpp" + +void SmallBullet::render(int offx, int offy) +{ + al_draw_rotated_bitmap(bitmap, radius, radius, offx + x, offy + y, 0.0f, 0); +} + +SmallBullet::SmallBullet(float x, float y, float angle, Entity *shooter) : + Bullet(x, y, 4, 0.5f, angle, 600, 1, RES_SMALLBULLET, shooter) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/StreamResource.cpp b/allegro/demos/cosmic_protector/src/StreamResource.cpp new file mode 100644 index 00000000..c5f45f7d --- /dev/null +++ b/allegro/demos/cosmic_protector/src/StreamResource.cpp @@ -0,0 +1,41 @@ +#include "cosmic_protector.hpp" + +void StreamResource::destroy(void) +{ + if (!stream) + return; + al_destroy_audio_stream(stream); + stream = 0; +} + +bool StreamResource::load(void) +{ + if (!al_is_audio_installed()) { + debug_message("Skipped loading stream %s\n", filename.c_str()); + return true; + } + + stream = al_load_audio_stream(filename.c_str(), 4, 1024); + if (!stream) { + debug_message("Error creating stream\n"); + return false; + } + + al_set_audio_stream_playing(stream, false); + al_set_audio_stream_playmode(stream, ALLEGRO_PLAYMODE_LOOP); + al_attach_audio_stream_to_mixer(stream, al_get_default_mixer()); + + return true; +} + +void* StreamResource::get(void) +{ + return stream; +} + +StreamResource::StreamResource(const char* filename) : + stream(0), + filename(filename) +{ +} + diff --git a/allegro/demos/cosmic_protector/src/UFO.cpp b/allegro/demos/cosmic_protector/src/UFO.cpp new file mode 100644 index 00000000..d7563535 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/UFO.cpp @@ -0,0 +1,83 @@ +#include "cosmic_protector.hpp" + +bool UFO::logic(int step) +{ + Player *p = (Player *)getPlayerCollision(); + if (p) { + explode(); + p->hit(1); + p->die(); + my_play_sample(RES_COLLISION); + return false; + } + + int now = (int) (al_get_time() * 1000.0); + if (now > nextShot) { + nextShot = now + SHOT_SPEED; + ResourceManager& rm = ResourceManager::getInstance(); + Player *p = (Player *)rm.getData(RES_PLAYER); + float px = p->getX(); + float py = p->getY(); + float shot_angle = atan2(py-y, px-x); + LargeSlowBullet *b = new LargeSlowBullet(x, y, shot_angle, this); + new_entities.push_back(b); + my_play_sample(RES_FIRELARGE); + } + + bitmapFrameCount -= step; + if (bitmapFrameCount <= 0) { + bitmapFrameCount = ANIMATION_SPEED; + bitmapFrame++; + bitmapFrame %= 3; // loop + } + + dx = speed_x * step; + dy = speed_y * step; + + Entity::wrap(); + + if (!Entity::logic(step)) + return false; + + return true; +} + +void UFO::render(int offx, int offy) +{ + render(offx, offy, al_map_rgb(255, 255, 255)); +} + +void UFO::render(int offx, int offy, ALLEGRO_COLOR tint) +{ + al_draw_tinted_rotated_bitmap(bitmaps[bitmapFrame], tint, + radius, radius, offx + x, offy + y, 0.0f, 0); +} + +UFO::UFO(float x, float y, float speed_x, float speed_y) : + SHOT_SPEED(3000), + ANIMATION_SPEED(150) +{ + this->x = x; + this->y = y; + this->speed_x = speed_x; + this->speed_y = speed_y; + + radius = 32; + hp = 8; + points = 500; + ufo = true; + + nextShot = (int)(al_get_time() * 1000.0) + SHOT_SPEED; + + ResourceManager& rm = ResourceManager::getInstance(); + bitmaps[0] = (ALLEGRO_BITMAP *)rm.getData(RES_UFO0); + bitmaps[1] = (ALLEGRO_BITMAP *)rm.getData(RES_UFO1); + bitmaps[2] = (ALLEGRO_BITMAP *)rm.getData(RES_UFO2); + bitmapFrame = 0; + bitmapFrameCount = ANIMATION_SPEED; +} + +UFO::~UFO() +{ +} + diff --git a/allegro/demos/cosmic_protector/src/collision.cpp b/allegro/demos/cosmic_protector/src/collision.cpp new file mode 100644 index 00000000..cb0f7d8e --- /dev/null +++ b/allegro/demos/cosmic_protector/src/collision.cpp @@ -0,0 +1,11 @@ +#include "cosmic_protector.hpp" + +bool checkCircleCollision(float x1, float y1, float r1, + float x2, float y2, float r2) +{ + float dx = x1-x2; + float dy = y1-y2; + float dist = sqrt(dx*dx + dy*dy); + return dist < (r1+r2); +} + diff --git a/allegro/demos/cosmic_protector/src/cosmic_protector.cpp b/allegro/demos/cosmic_protector/src/cosmic_protector.cpp new file mode 100644 index 00000000..5715a6aa --- /dev/null +++ b/allegro/demos/cosmic_protector/src/cosmic_protector.cpp @@ -0,0 +1,146 @@ +#include "cosmic_protector.hpp" +#include "joypad_c.h" + +ALLEGRO_VOICE *voice; +ALLEGRO_MIXER *mixer; + +#ifdef ALLEGRO_IPHONE +#include "cosmic_protector_objc.h" +#endif + +bool switched_out; + +static int check_arg(int argc, char **argv, const char *arg) +{ + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], arg)) + return true; + } + return false; +} + +static void game_loop() +{ + lastUFO = -1; + canUFO = true; + + Wave wave; + + int step = 0; + long start = (long) (al_get_time() * 1000); + + for (;;) { + if (entities.size() <= 0) { + if (!wave.next()) { + // Won. + break; + } + } + + if (!logic(step)) + break; + render(step); + al_rest(1.0/60.0); + long end = (long) (al_get_time() * 1000); + step = end - start; + start = end; + + if (step > 50) step = 50; + } + + std::list<Entity *>::iterator it; + for (it = entities.begin(); it != entities.end(); it++) { + Entity *e = *it; + delete e; + } + entities.clear(); +} + +int main(int argc, char **argv) +{ + if (check_arg(argc, argv, "-fullscreen")) + useFullScreenMode = true; + if (!init()) { + debug_message("Error in initialization.\n"); + return 1; + } + + ResourceManager& rm = ResourceManager::getInstance(); + Player *player = (Player *)rm.getData(RES_PLAYER); + + ALLEGRO_AUDIO_STREAM *title_music = (ALLEGRO_AUDIO_STREAM *)rm.getData(RES_TITLE_MUSIC); + ALLEGRO_AUDIO_STREAM *game_music = (ALLEGRO_AUDIO_STREAM *)rm.getData(RES_GAME_MUSIC); + + for (;;) { + if (title_music) { + al_set_audio_stream_playing(title_music, true); + } + + joypad_find(); + + while (true) { + int result = do_menu(); + al_rest(0.250); + if (result == 1) { + do_highscores(INT_MIN); + continue; + } + else if (result == 2 || result == -1) { + done(); + return 0; + } + break; + } + + if (title_music) { + al_drain_audio_stream(title_music); + al_rewind_audio_stream(title_music); + } + + joypad_stop_finding(); + + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)rm.getData(RES_DISPLAY); + int o = al_get_display_orientation(display); + al_set_display_option(display, ALLEGRO_SUPPORTED_ORIENTATIONS, o); + + if (game_music) { + al_set_audio_stream_playing(game_music, true); + } + + player->load(); + game_loop(); + do_highscores(player->getScore()); + player->destroy(); + + if (game_music) { + al_drain_audio_stream(game_music); + al_rewind_audio_stream(game_music); + } + + al_set_display_option(display, ALLEGRO_SUPPORTED_ORIENTATIONS, ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE); + + } + + return 0; +} + +#ifdef ALLEGRO_IPHONE +void switch_game_out(bool halt) +{ + if (!isMultitaskingSupported()) { + exit(0); + } + if (halt) { + ResourceManager& rm = ResourceManager::getInstance(); + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)rm.getData(RES_DISPLAY); + al_acknowledge_drawing_halt(display); + } + switched_out = true; +} + +void switch_game_in(void) +{ + switched_out = false; +} +#endif + diff --git a/allegro/demos/cosmic_protector/src/cosmic_protector_objc.m b/allegro/demos/cosmic_protector/src/cosmic_protector_objc.m new file mode 100644 index 00000000..cc01725d --- /dev/null +++ b/allegro/demos/cosmic_protector/src/cosmic_protector_objc.m @@ -0,0 +1,22 @@ +#include <allegro5/allegro.h> + +#ifdef ALLEGRO_IPHONE + +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +#include "cosmic_protector_objc.h" + +bool isMultitaskingSupported(void) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + char buf[100]; + strcpy(buf, [[[UIDevice currentDevice] systemVersion] UTF8String]); + if (atof(buf) < 4.0) return false; + + [pool drain]; + + return [[UIDevice currentDevice] isMultitaskingSupported]; +} +#endif diff --git a/allegro/demos/cosmic_protector/src/joypad_dummy.cpp b/allegro/demos/cosmic_protector/src/joypad_dummy.cpp new file mode 100644 index 00000000..aa0f6111 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/joypad_dummy.cpp @@ -0,0 +1,34 @@ +#include "joypad_c.h" + +/* Joypad is some iOS/MacOS X API. + * This file is just a stub for when it isn't being used. + * The real implementation is in joypad_handler.m. + * Most platforms use the regular Allegro joystick API. + */ +#if !defined(USE_JOYPAD) + +void joypad_start(void) +{ +} + +void joypad_find(void) +{ +} + +void joypad_stop_finding(void) +{ +} + +void get_joypad_state(bool *u, bool *d, bool *l, bool *r, bool *b, bool *esc) +{ + *u = *d = *l = *r = *b = *esc = false; +} + +bool is_joypad_connected(void) +{ + return false; +} + +#endif /* !USE_JOYPAD */ + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/demos/cosmic_protector/src/joypad_handler.m b/allegro/demos/cosmic_protector/src/joypad_handler.m new file mode 100644 index 00000000..e30cb3d7 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/joypad_handler.m @@ -0,0 +1,214 @@ +#import "joypad_handler.h" + +#ifdef USE_JOYPAD + +#import "JoypadSDK.h" + +static joypad_handler *joypad; + +@implementation joypad_handler + +- (id)init +{ + self = [super init]; + if (self) { + } + + return self; +} + +-(void)start +{ + finding = false; + joypadManager = [[JoypadManager alloc] init]; + [joypadManager setDelegate:self]; + + JoypadControllerLayout *layout = [JoypadControllerLayout snesLayout]; + [layout setName:@"cosmic_protector"]; + [joypadManager setControllerLayout:layout]; + + [joypadManager setMaxPlayerCount:1]; + + connected = left = right = up = down = ba = bb = bx = by = bl = br = false; +} + +-(void)find_devices +{ + finding = true; + if (connected) return; + [joypadManager stopFindingDevices]; + [joypadManager startFindingDevices]; +} + +-(void)stop_finding_devices +{ + finding = false; + [joypadManager stopFindingDevices]; +} + +-(void)joypadManager:(JoypadManager *)manager didFindDevice:(JoypadDevice *)device previouslyConnected:(BOOL)prev +{ + [manager stopFindingDevices]; + [manager connectToDevice:device asPlayer:1]; +} + +-(void)joypadManager:(JoypadManager *)manager didLoseDevice:(JoypadDevice *)device; +{ +} + +-(void)joypadManager:(JoypadManager *)manager deviceDidConnect:(JoypadDevice *)device player:(unsigned int)player +{ + [device setDelegate:self]; + connected = true; +} + +-(void)joypadManager:(JoypadManager *)manager deviceDidDisconnect:(JoypadDevice *)device player:(unsigned int)player +{ + connected = false; + left = right = up = down = ba = bb = bx = by = bl = br = false; + if (finding) [self find_devices]; +} + +-(void)joypadDevice:(JoypadDevice *)device didAccelerate:(JoypadAcceleration)accel +{ +} + +-(void)joypadDevice:(JoypadDevice *)device dPad:(JoyInputIdentifier)dpad buttonUp:(JoyDpadButton)dpadButton +{ + if (dpadButton == kJoyDpadButtonUp) + { + up = false; + } + else if (dpadButton == kJoyDpadButtonDown) + { + down = false; + } + else if (dpadButton == kJoyDpadButtonLeft) + { + left = false; + } + else if (dpadButton == kJoyDpadButtonRight) + { + right = false; + } +} + +-(void)joypadDevice:(JoypadDevice *)device dPad:(JoyInputIdentifier)dpad buttonDown:(JoyDpadButton)dpadButton +{ + if (dpadButton == kJoyDpadButtonUp) + { + up = true; + } + else if (dpadButton == kJoyDpadButtonDown) + { + down = true; + } + else if (dpadButton == kJoyDpadButtonLeft) + { + left = true; + } + else if (dpadButton == kJoyDpadButtonRight) + { + right = true; + } +} + +-(void)joypadDevice:(JoypadDevice *)device buttonUp:(JoyInputIdentifier)button +{ + if (button == kJoyInputAButton) + { + ba = false; + } + else if (button == kJoyInputBButton) + { + bb = false; + } + else if (button == kJoyInputXButton) + { + bx = false; + } + else if (button == kJoyInputYButton) + { + by = false; + } + else if (button == kJoyInputLButton) + { + bl = false; + } + else if (button == kJoyInputRButton) + { + br = false; + } +} + +-(void)joypadDevice:(JoypadDevice *)device buttonDown:(JoyInputIdentifier)button +{ + if (button == kJoyInputAButton) + { + ba = true; + } + else if (button == kJoyInputBButton) + { + bb = true; + } + else if (button == kJoyInputXButton) + { + bx = true; + } + else if (button == kJoyInputYButton) + { + by = true; + } + else if (button == kJoyInputLButton) + { + bl = true; + } + else if (button == kJoyInputRButton) + { + br = true; + } +} + +-(void)joypadDevice:(JoypadDevice *)device analogStick:(JoyInputIdentifier)stick didMove:(JoypadStickPosition)newPosition +{ +} + +@end + +void joypad_start(void) +{ + joypad = [[joypad_handler alloc] init]; + [joypad performSelectorOnMainThread: @selector(start) withObject:nil waitUntilDone:YES]; +} + +void joypad_find(void) +{ + [joypad performSelectorOnMainThread: @selector(find_devices) withObject:nil waitUntilDone:YES]; +} + +void joypad_stop_finding(void) +{ + [joypad performSelectorOnMainThread: @selector(stop_finding_devices) withObject:nil waitUntilDone:YES]; +} + +void get_joypad_state(bool *u, bool *d, bool *l, bool *r, bool *b, bool *esc) +{ + if (!joypad || !joypad->connected) { + *u = *d = *l = *r = *b = *esc = false; + return; + } + + *u = joypad->up; + *d = joypad->down; + *l = joypad->left; + *r = joypad->right; + *b = joypad->bb; + *esc = joypad->bx; +} + +bool is_joypad_connected(void) +{ + return joypad && joypad->connected; +} + +#endif // USE_JOYPAD diff --git a/allegro/demos/cosmic_protector/src/logic.cpp b/allegro/demos/cosmic_protector/src/logic.cpp new file mode 100644 index 00000000..6c420d1a --- /dev/null +++ b/allegro/demos/cosmic_protector/src/logic.cpp @@ -0,0 +1,94 @@ +#include "cosmic_protector.hpp" + +std::list<Entity *> entities; +std::list<Entity *> new_entities; + +long lastUFO = -1; +bool canUFO = true; +const int MIN_UFO_TIME = 10000; +const int MAX_UFO_TIME = 50000; + +bool logic(int step) +{ + const long now = (long) (al_get_time() * 1000.0); + + if (lastUFO < 0) + lastUFO = now; + + if (canUFO && (now > (lastUFO+MIN_UFO_TIME))) { + int r = rand() % (MAX_UFO_TIME-MIN_UFO_TIME); + if (r <= step || (now > (lastUFO+MAX_UFO_TIME))) { + canUFO = false; + UFO *ufo; + float x, y, dx, dy; + if (rand() % 2) { + x = -32; + y = randf(32.0f, 75.0f); + dx = 0.1f; + dy = 0.0f; + } + else { + x = BB_W+32; + y = randf(BB_H-75, BB_H-32); + dx = -0.1f; + dy = 0.0f; + } + ufo = new UFO(x, y, dx, dy); + entities.push_back(ufo); + } + } + + ResourceManager& rm = ResourceManager::getInstance(); + + Player *player = (Player *)rm.getData(RES_PLAYER); + + Input *input = (Input *)rm.getData(RES_INPUT); + input->poll(); + + if (input->esc()) + return false; + + /* Catch close button presses */ + ALLEGRO_EVENT_QUEUE *events = ((DisplayResource *)rm.getResource(RES_DISPLAY))->getEventQueue(); + while (!al_is_event_queue_empty(events)) { + ALLEGRO_EVENT event; + al_get_next_event(events, &event); +#ifdef ALLEGRO_IPHONE + if (event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING || event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) { + switch_game_out(event.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING); + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING || event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN) { + switch_game_in(); + } +#else + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + exit(0); +#endif + } + + std::list<Entity *>::iterator it = entities.begin(); + while (it != entities.end()) { + Entity *e = *it; + if (!e->logic(step)) { + if (e->isUFO()) { + lastUFO = now; + canUFO = true; + } + delete e; + it = entities.erase(it); + } + else + it++; + } + + for (it = new_entities.begin(); it != new_entities.end(); it++) { + entities.push_back(*it); + } + new_entities.clear(); + + if (!player->logic(step)) + return false; + + return true; +} + diff --git a/allegro/demos/cosmic_protector/src/render.cpp b/allegro/demos/cosmic_protector/src/render.cpp new file mode 100644 index 00000000..b0d74e2c --- /dev/null +++ b/allegro/demos/cosmic_protector/src/render.cpp @@ -0,0 +1,142 @@ +#include "cosmic_protector.hpp" + +#include <ctime> + +static float waveAngle = 0.0f; +static ALLEGRO_BITMAP *waveBitmap = 0; +static float bgx = 0; +static float bgy = 0; +static int shakeUpdateCount = 0; +static int shakeCount = 0; +const int SHAKE_TIME = 100; +const int SHAKE_TIMES = 10; + +static void renderWave(void) +{ + int w = al_get_bitmap_width(waveBitmap); + int h = al_get_bitmap_height(waveBitmap); + + float a = waveAngle + ALLEGRO_PI/2; + + int x = (int)(BB_W/2 + 64*cos(a)); + int y = (int)(BB_H/2 + 64*sin(a)); + + al_draw_rotated_bitmap(waveBitmap, w/2, h, + x, y, waveAngle, 0); +} + +static void stopWave(void) +{ + waveAngle = 0.0f; + al_destroy_bitmap(waveBitmap); + waveBitmap = 0; +} + +void showWave(int num) +{ + if (waveBitmap) + stopWave(); + + ResourceManager& rm = ResourceManager::getInstance(); + + ALLEGRO_FONT *myfont = (ALLEGRO_FONT *)rm.getData(RES_LARGEFONT); + + char text[20]; + sprintf(text, "WAVE %d", num); + + int w = al_get_text_width(myfont, text); + int h = al_get_font_line_height(myfont); + + waveBitmap = al_create_bitmap(w, h); + ALLEGRO_BITMAP *old_target = al_get_target_bitmap(); + al_set_target_bitmap(waveBitmap); + al_clear_to_color(al_map_rgba(0, 0, 0, 0)); + al_draw_textf(myfont, al_map_rgb(255, 255, 255), 0, 0, 0, "%s", text); + al_set_target_bitmap(old_target); + + waveAngle = (ALLEGRO_PI*2); +} + +void shake(void) +{ + shakeUpdateCount = SHAKE_TIME; + bgx = randf(0.0f, 8.0f); + bgy = randf(0.0f, 8.0f); + if (rand() % 2) bgx = -bgx; + if (rand() % 2) bgy = -bgy; +} + +void render(int step) +{ +#ifdef ALLEGRO_IPHONE + if (switched_out) + return; +#endif + + ResourceManager& rm = ResourceManager::getInstance(); + + ALLEGRO_BITMAP *bg = (ALLEGRO_BITMAP *)rm.getData(RES_BACKGROUND); + + if (shakeUpdateCount > 0) { + shakeUpdateCount -= step; + if (shakeUpdateCount <= 0) { + shakeCount++; + if (shakeCount >= SHAKE_TIMES) { + shakeCount = 0; + shakeUpdateCount = 0; + bgx = bgy = 0; + } + else { + bgx = randf(0.0f, 8.0f); + bgy = randf(0.0f, 8.0f); + if (rand() % 2) bgx = -bgx; + if (rand() % 2) bgy = -bgy; + shakeUpdateCount = SHAKE_TIME; + } + } + } + + al_clear_to_color(al_map_rgb(0, 0, 0)); + + float h = al_get_bitmap_height(bg); + float w = al_get_bitmap_width(bg); + al_draw_bitmap(bg, (BB_W-w)/2+bgx, (BB_H-h)/2+bgy, 0); + + std::list<Entity *>::iterator it; + for (it = entities.begin(); it != entities.end(); it++) { + Entity *e = *it; + e->render_four(al_map_rgb(255, 255, 255)); + if (e->isHighlighted()) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE); + e->render_four(al_map_rgb(150, 150, 150)); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + } + } + + Player *player = (Player *)rm.getData(RES_PLAYER); + player->render_four(al_map_rgb(255, 255, 255)); + player->render_extra(); + + if (waveAngle > 0.0f) { + renderWave(); + waveAngle -= 0.003f * step; + if (waveAngle <= 0.0f) { + stopWave(); + } + } + +#ifdef ALLEGRO_IPHONE + Input *input = (Input *)rm.getData(RES_INPUT); + input->draw(); + + int xx = BB_W-30; + int yy = 30; + + al_draw_line(xx-10, yy-10, xx+10, yy+10, al_map_rgb(255, 255, 255), 4); + al_draw_line(xx-10, yy+10, xx+10, yy-10, al_map_rgb(255, 255, 255), 4); + al_draw_circle(xx, yy, 20, al_map_rgb(255, 255, 255), 4); +#endif + + al_flip_display(); +} + diff --git a/allegro/demos/cosmic_protector/src/sound.cpp b/allegro/demos/cosmic_protector/src/sound.cpp new file mode 100644 index 00000000..9f510ec4 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/sound.cpp @@ -0,0 +1,12 @@ +#include "cosmic_protector.hpp" + + +void my_play_sample(int resourceID) +{ + ResourceManager &rm = ResourceManager::getInstance(); + ALLEGRO_SAMPLE *s = (ALLEGRO_SAMPLE *)rm.getData(resourceID); + if (s) { + al_play_sample(s, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); + } +} + diff --git a/allegro/demos/cosmic_protector/src/wave.cpp b/allegro/demos/cosmic_protector/src/wave.cpp new file mode 100644 index 00000000..e0bdd2c8 --- /dev/null +++ b/allegro/demos/cosmic_protector/src/wave.cpp @@ -0,0 +1,43 @@ +#include "cosmic_protector.hpp" + +Wave::Wave() : + rippleNum(0) +{ +} + +bool Wave::next(void) +{ + rippleNum++; + + showWave(rippleNum); + + for (int i = 0; i < rippleNum+1; i++) { + float x, y, dx, dy, da; + if (rand() % 2) { + x = -randf(32.0f, 100.0f); + } + else { + x = BB_W+randf(32.0f, 100.0f); + } + if (rand() % 2) { + y = -randf(32.0f, 70.0f); + } + else { + y = BB_H+randf(32.0f, 70.0f); + } + dx = randf(0.06f, 0.12f); + dy = randf(0.04f, 0.08f); + da = randf(0.001f, 0.005f); + if (rand() % 2) dx = -dx; + if (rand() % 2) dy = -dy; + if (rand() % 2) da = -da; + LargeAsteroid *la = new LargeAsteroid(x, y, dx, dy, da); + if ((rand() % 3) == 0) { + la->setPowerUp(rand() % 2); + } + entities.push_back(la); + } + + return true; +} + diff --git a/allegro/demos/skater/CMakeLists.txt b/allegro/demos/skater/CMakeLists.txt new file mode 100644 index 00000000..bf1115da --- /dev/null +++ b/allegro/demos/skater/CMakeLists.txt @@ -0,0 +1,147 @@ +if(SUPPORT_FONT AND SUPPORT_AUDIO AND SUPPORT_ACODEC) +else() + message(STATUS "Not building skater demo") + return() +endif() + +include_directories( + ${PROJECT_SOURCE_DIR}/addons/acodec + ${PROJECT_SOURCE_DIR}/addons/audio + ${PROJECT_SOURCE_DIR}/addons/font + ${PROJECT_SOURCE_DIR}/addons/image + ${PROJECT_SOURCE_DIR}/addons/main + ${PROJECT_SOURCE_DIR}/addons/primitives + ) + +set(DEMO_SRCS + src/anim.c + src/background_scroller.c + src/credits.c + src/fps.c + src/framework.c + src/game.c + src/gamepad.c + src/global.c + src/intro.c + src/keyboard.c + src/level_alloc.c + src/level.c + src/level_file.c + src/level_state.c + src/menu_about.c + src/menu.c + src/menu_controls.c + src/menu_graphics.c + src/menu_main.c + src/menu_misc.c + src/menu_options.c + src/menu_sound.c + src/menu_success.c + src/mouse.c + src/music.c + src/physics.c + src/quadtree.c + src/screenshot.c + src/skater.c + src/token.c + src/transition.c + src/vcontroller.c + ) + +file(GLOB SKATER_GRAPHICS data/graphics/*.png) +file(GLOB SKATER_AUDIO data/audio/*) +file(GLOB SKATER_MENU data/menu/*) +file(GLOB SKATER_LEVEL data/*.txt) + +set(SKATER_DATA + ${SKATER_GRAPHICS} + ${SKATER_AUDIO} + ${SKATER_MENU} + ${SKATER_LEVEL} + ${SKATER_FONTS} + ) + +set(SKATER_REL_DATA) +foreach(data ${SKATER_DATA}) + file(RELATIVE_PATH relpath "${CMAKE_CURRENT_SOURCE_DIR}" "${data}") + list(APPEND SKATER_REL_DATA "${relpath}") +endforeach(data) + +if(ANDROID) + add_copy_commands( + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}/skater.project/app/src/main/assets" + ASSETS + "${SKATER_REL_DATA}" + ) + add_android_app(skater + "${DEMO_SRCS};${ASSETS}" + ) + return() +endif() + +if(APPLE) + set(DEMO_EXECUTABLE_TYPE MACOSX_BUNDLE) +else(APPLE) + set(DEMO_EXECUTABLE_TYPE "${EXECUTABLE_TYPE}") +endif(APPLE) + +add_executable(skater + ${DEMO_EXECUTABLE_TYPE} + ${DEMO_SRCS} + ${SKATER_DATA} + ) + +fix_executable(skater) + +if(WANT_MONOLITH) + target_link_libraries(skater + ${ALLEGRO_MONOLITH_LINK_WITH} + ) +else(WANT_MONOLITH) + target_link_libraries(skater + ${ACODEC_LINK_WITH} + ${AUDIO_LINK_WITH} + ${FONT_LINK_WITH} + ${IMAGE_LINK_WITH} + ${ALLEGRO_MAIN_LINK_WITH} + ${PRIMITIVES_LINK_WITH} + ) +endif(WANT_MONOLITH) + +if(NOT BUILD_SHARED_LIBS) + set_target_properties(skater PROPERTIES COMPILE_FLAGS "-DALLEGRO_STATICLINK") +endif(NOT BUILD_SHARED_LIBS) + +# Mac OS X bundle support. +set_target_properties(skater PROPERTIES + MACOSX_BUNDLE_COPYRIGHT "Copyright 2010 Allegro Developers" + #MACOSX_BUNDLE_ICON_FILE "Icon.icns" + MACOSX_BUNDLE_INFO_STRING "5.1, Copyright 2010 Allegro Developers" + MACOSX_BUNDLE_SHORT_VERSION_STRING "5.1" + MACOSX_BUNDLE_LONG_VERSION_STRING "Allegro Skater Demo v5.1" + MACOSX_BUNDLE_GUI_IDENTIFIER "org.liballeg.skater" + ) + +set_source_files_properties(${SKATER_GRAPHICS} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources/data/graphics" + ) +set_source_files_properties(${SKATER_AUDIO} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources/data/audio" + ) +set_source_files_properties(${SKATER_MENU} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources/data/menu" + ) +set_source_files_properties(${SKATER_LEVEL} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources/data" + ) + +copy_data_dir_to_build(copy_skater_data + "${CMAKE_CURRENT_SOURCE_DIR}/data" + "${CMAKE_CURRENT_BINARY_DIR}/data" + ) + +add_dependencies(skater copy_skater_data copy_example_data) + +#-----------------------------------------------------------------------------# +# vi: set ts=8 sts=4 sw=4 et: diff --git a/allegro/demos/skater/blender/ademo_export.py b/allegro/demos/skater/blender/ademo_export.py new file mode 100644 index 00000000..dcd17660 --- /dev/null +++ b/allegro/demos/skater/blender/ademo_export.py @@ -0,0 +1,445 @@ +#!BPY +# Version 9: Modified "top", so upper edges means all on the upper side of the +# mesh, not any edges facing up. Took as long as all the rest of this +# script. +# +# Friction is now sum of R, G, B components of material color. +# Version 8: added the "top" property, and an error message +# Version 7: "foreground" meshes and objects now possible +# friction can now be set for materials (using color components) +# Version 6: merge object types, round numbers to integer +# Version 5: objects +# Version 4: read edge_height property +# Version 3: process geometry into clockwise triangles +# Version 2: materials +# Version 1: only mesh geometry + +""" +Name: 'Allegro Demo Game Level (.txt)...' +Blender: 249 +Group: 'Export' +Tooltip: 'Export Allegro Demo Game Level (.txt)' +""" + +__bpydoc__ = """\ +All mesh objects are exported as triangles. Coordinates are scaled by a factor +of 10, so something at Blender coordinate x=10 will be x=100 in the game. And the +y axis is flipped, since in the game, positive y is downwards. + +Every mesh must have a material assigned for each of its faces. You can do this +by just giving a material to the mesh object, or also by applying per-face +materials. + +A material must have texture slot 0 and 1 filled in and set to Image textures, +where the first texture's image is the base texture, and the second the edge +texture. +The sum of the R,G,B components of the material color is used as friction. +All other material settings are ignored. + +Mesh object understand the following properties: + +"edge_height" - The edge height for all faces in the mesh. +"foreground" - All edges are marked foreground. +"background" - No edge is marked collidable. +"top" - Only upper edges of the mesh are marked as edges. Selected are all those +edges part of the outer contour of the mesh, which are lying between the leftmost +and rightmost vertex of that contour, in clockwise order. + +Objects are inserted as Blender "Empties". Each object has the following +properties: + +"bitmap" - Name of the bitmap to use. +"sound" - Name of the sound to play. +"bonus" - If 1, this object does not count towards the number of needed fruits. + (So if a level has 30 fruits, and 10 are marked "bonus", only 20 need + to be collected. It doesn't matter at all which out of the 30 though.) +"foreground" - This is a foreground object. +"deco" - This object is not collidable. + +There are some reserved names. Empties whose name starts with "player" or +"Player" mark the player starting position. Empties whose name starts with +"exit" or "Exit" mark the level exit position. + +All other objects (cameras, lamps, ...) are ignored. + +Currently, there is no sanity checking done, so be sure to: +- Assign materials to meshes/faces. +- Make only 2D meshes. Blender will happily twist your meshes around, but the + exported level simply will crash. Only a planar mesh is allowed. +- Don't forget the Empties for the player and exit positions, and set at least + one other collectible. +""" + +import Blender, meshtools, sys, time + +# scaling factor when exporting vertex coordinates from blender +SCALE_X = 10 +SCALE_Y = -10 + +COMMENTS = False # Set to True to enable additional comments in the output + +# can be modified on a per-mesh basis via the "edge_height" property +DEFAULT_EDGE_HEIGHT = 2 + +message_string = "?" + +def message_draw(): + # clearing screen + Blender.BGL.glClearColor(0.5, 0.5, 0.5, 1) + Blender.BGL.glColor3f(1.,1.,1.) + Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT) + + # Buttons + Blender.Draw.Button("Oh oh", 1, 10, 40, 100, 25) + + #Text + Blender.BGL.glColor3f(1, 1, 1) + Blender.BGL.glRasterPos2d(10, 310) + Blender.Draw.Text(message_string) + +def message_event(evt, val): + if evt == Blender.Draw.ESCKEY and not val: Blender.Draw.Exit() + +def message_bevent(evt): + + if evt == 1: Blender.Draw.Exit() + +class MessageException(Exception): pass + +def message(str): + global message_string + message_string = str + Blender.Draw.Register(message_draw, message_event, message_bevent) + raise MessageException + +def transform(matrix, vector): + """ + Given a matrix and a vector, return the result of transforming the vector by + the matrix. + matrix = [[0, 0, 0, 0], [0, 0, 0, 0]] + vector = [0, 0, 0, 0] + return = [0, 0] + """ + vout = [] + for j in range(2): + x = 0 + for i in range(4): + x += matrix[i][j] * vector[i] + vout += [x] + return vout + + +def direction(tri): + """ + Given a triangle, determine if it is counterclockwise or not. + tri = [i, i, i], + where i is a global vertex index. + """ + v1 = (V[tri[1]][0] - V[tri[0]][0], V[tri[1]][1] - V[tri[0]][1]) + v2 = (V[tri[2]][0] - V[tri[1]][0], V[tri[2]][1] - V[tri[1]][1]) + v = v1[0] * v2[1] - v1[1] * v2[0] + return v + +def upper(i1, i2): + """ + Given two vertex ids, determine if the edge is an upper face. + """ + v = V[i2][0] - V[i1][0] + return v + +def get_prop(ob, name, val): + try: + prop = ob.getProperty(name) + v = prop.getData() + except (AttributeError, RuntimeError): + v = val + return v + +def make_contour(ob, base_i): + """ + ob # the Blender mesh object + + Returns a pair (edges, upper_contour). + edges = {v: n} # maps vertex to sucessor + upper_contour = {v: 1} # set of vertices in the upper mesh outline + """ + mesh = ob.getData() + # count how often each edge is present in the mesh + boundaries = {} + for f in mesh.faces: + prev = f.v[-1] + for v in f.v: + vs = [prev.index, v.index] + vs.sort() + vs = tuple(vs) + if vs in boundaries: + boundaries[vs] += 1 + else: + boundaries[vs] = 1 + prev = v + + # map each vertex to its connected vertex + topmost = None + edges = {} + for f in mesh.faces: + prev = f.v[-1] + for v in f.v: + vs = [prev.index, v.index] + vs.sort() + vs = tuple(vs) + if vs in boundaries and boundaries[vs] == 1: + if not base_i + prev.index in edges: edges[base_i + prev.index] = {} + if not base_i + v.index in edges: edges[base_i + v.index] = {} + edges[base_i + prev.index][base_i + v.index] = 1 + edges[base_i + v.index][base_i + prev.index] = 1 + if not topmost or V[base_i + prev.index][1] > V[topmost][1]: + topmost = base_i + prev.index + prev = v + + # Build the contour list. We start by picking the topmost vertex, then + # finding its contour neighbour so we are facing a clockwise direction. + cv = topmost # pick topmost contour vertex + next = list(edges[cv])[0] # next one + ok = False + # find the face this edge is part of + edge = (cv, next) + for f in mesh.faces: + for i in range(len(f.v)): + if (base_i + f.v[i - 1].index, base_i + f.v[i].index) == edge or\ + (base_i + f.v[i].index, base_i + f.v[i - 1].index) == edge: + j = base_i + f.v[(i + 1) % len(f.v)].index + if direction([cv, next, j]) < 0: + ok = True + break + if ok: break + if not ok: + next = list(edges[cv])[1] + + full_contour = [cv] # a list of vertex indices, representing the mesh outline + prev = cv + while next != cv: + full_contour += [next] + v = list(edges[next])[0] + if v == prev: v = list(edges[next])[1] + prev = next + next = v + + leftmost = None + rightmost = None + if COMMENTS: print "\t# contour:", + for vi in range(len(full_contour)): + v = full_contour[vi] + if COMMENTS: print "%d" % v, + if leftmost == None or V[v][0] < V[full_contour[leftmost]][0]: + leftmost = vi + if rightmost == None or V[v][0] > V[full_contour[rightmost]][0]: + rightmost = vi + if COMMENTS: print + + if COMMENTS: print "\t# left: %d right: %d" % (full_contour[leftmost], + full_contour[rightmost]) + + upper_contour = {} + for v in range(len(full_contour)): + if rightmost > leftmost: + if v >= leftmost and v < rightmost: + upper_contour[full_contour[v]] = 1 + else: + if v >= leftmost or v < rightmost: + upper_contour[full_contour[v]] = 1 + return (edges, upper_contour) + +def write(filename): + global V + file = open(filename, "wb") + stdout = sys.stdout + sys.stdout=file + + print "# Exported from Blender %s" % Blender.Get("version") + print "# on %s (%s)" % (time.ctime(), time.tzname[0]) + print "# do not edit, edit %s instead" % Blender.Get("filename") + print + + # Retrieve a list of all mesh objects in Blender. + meshobs = [ob for ob in Blender.Object.Get() if ob.getType() == "Mesh"] + + # Export all current Blender materials. + mnum = 0 + materials = {} + print "# Materials" + print "{" + for m in Blender.Material.Get(): + t = [] + for tex in m.getTextures()[:2]: + if tex and tex.tex.getImage(): + t += [tex.tex.getImage().name.split(".")[0]] + else: + t += [""] + print """\t{"%s", "%s", %f} # %d \"%s\"""" % (t[0], t[1], + m.R + m.G + m.B, mnum, m.getName()) + materials[m.name] = mnum + mnum += 1 + print "}" + print + + # Export all vertices of all mesh objects. + V = {} + print "# Vertices" + print "{" + i = 0 + for ob in meshobs: + print "\t# Mesh \"%s\"" % ob.name + matrix = ob.matrix + mesh = ob.getData() + for v in mesh.verts: + pos = transform(matrix, [v.co.x, v.co.y, v.co.z, 1]) + V[i] = pos + print "\t{%d, %d} # %d" % (round(pos[0] * SCALE_X), + round(pos[1] * SCALE_Y), i) + i += 1 + print "}" + print + + # Export all faces of all mesh objects (split into triangles). + print "# Triangles" + print "{" + + base_i = 0 + for ob in meshobs: + print "\t# Mesh \"%s\"" % ob.name + + mesh = ob.getData() + + meshmaterials = mesh.getMaterials(1) + + edge_height = get_prop(ob, "edge_height", DEFAULT_EDGE_HEIGHT) + foreground = get_prop(ob, "foreground", 0) + background = get_prop(ob, "background", 0) + top = get_prop(ob, "top", 0) + + edges, upper_contour = make_contour(ob, base_i) + + for f in mesh.faces: + # First triangle. + tri1 = [base_i + f.v[2].index, base_i + f.v[1].index, base_i + + f.v[0].index] + if direction(tri1) > 0: + tri1.reverse() + tris = [tri1] + + # If the face has 4 vertices, add another triangle. + if len(f.v) > 3: + tri2 = [tri1[2], base_i + f.v[3].index, tri1[0]] + if direction(tri2) > 0: + tri2.reverse() + tris += [tri2] + + for tri in tris: + # Handle one triangle. + print "\t{" + for i in range(3): + v = tri[i] + if i == 2: + next = tri[0] + else: + next = tri[i + 1] + flags = "" + edge_ok = False + if v in edges and next in edges[v]: edge_ok = True + if top and not v in upper_contour: edge_ok = False + if edge_ok: + flags += " \"edge\"" + if background == 0 and foreground == 0: + flags += " \"collidable\"" + if foreground != 0: + flags += " \"foreground\"" + if flags != "": + flags = ", " + flags + print "\t\t{%d, %d%s}," % (v, edge_height, flags) + + try: + print "\t\t%d" % materials[meshmaterials[f.mat].name] + except IndexError: + message("You forgot to assign a material to mesh %s (or \ +one of its faces)" % ob.name) + print "\t}" + base_i += len(mesh.verts) + print "}" + print + + # Retrieve a list of all empty objects in Blender. + gameobs = [ob for ob in Blender.Object.Get() if ob.getType() == "Empty"] + + obtypes = {} + n = 0 + + print "# Object types" + print "{" + for ob in gameobs: + if ob.name.lower().startswith("player"): + continue + if ob.name.lower().startswith("exit"): + continue + bitmap = get_prop(ob, "bitmap", "") + sound = get_prop(ob, "sound", "") + + if not (bitmap, sound) in obtypes: + print "\t{ \"%s\", \"%s\" } # %d" % (bitmap, sound, n) + obtypes[(bitmap, sound)] = n + n += 1 + print "}" + print + + collectibles_count = 0 + print "# Objects" + print "{" + for ob in gameobs: + if ob.name.lower().startswith("player"): + continue + x, y, z = ob.getLocation() + anglex, angley, anglez = ob.getEuler() + deco = get_prop(ob, "deco", 0) + if ob.name.lower().startswith("exit"): + type = -1 + else: + bitmap = get_prop(ob, "bitmap", "") + sound = get_prop(ob, "sound", "") + type = obtypes[(bitmap, sound)] + bonus = get_prop(ob, "bonus", 0) + if bonus == 0 and deco == 0: collectibles_count += 1 + foreground = get_prop(ob, "foreground", 0) + flags = "" + if deco == 0: flags += "\"collidable\"" + if foreground != 0: flags += "\"foreground\"" + if flags != "": + flags = ", " + flags + + print "\t{ %d, %d, %d, %d%s } # \"%s\"" % (round(x * SCALE_X), round(y * SCALE_Y), + round(anglez), type, flags, ob.name) + print "}" + print + + print "# Level" + print "{" + for ob in gameobs: + if ob.name.lower().startswith("player"): + x, y, z = ob.getLocation() + print "\t%d, %d, %d" % (round(x * SCALE_X), round(y * SCALE_Y), + collectibles_count) + break + print "}" + + sys.stdout = stdout + +def fs_callback(filename): + # Mesh access is better done outside edit mode I believe. + editmode = Blender.Window.EditMode() + if editmode: Blender.Window.EditMode(0) + try: + write(filename) + except MessageException: + pass + if editmode: Blender.Window.EditMode(1) + +Blender.Window.FileSelector(fs_callback, "Export Allegro Demo Game Level", + "mylevel.txt") diff --git a/allegro/demos/skater/blender/level.blend.gz b/allegro/demos/skater/blender/level.blend.gz new file mode 100644 index 00000000..74e654b8 Binary files /dev/null and b/allegro/demos/skater/blender/level.blend.gz differ diff --git a/allegro/demos/skater/blender/readme.txt b/allegro/demos/skater/blender/readme.txt new file mode 100644 index 00000000..de311e0b --- /dev/null +++ b/allegro/demos/skater/blender/readme.txt @@ -0,0 +1,28 @@ +To edit the level data of the Allegro demo game, we use the free and open source +tool Blender. You can obtain it here: + +http://blender.org + +Instructions: + +1) Place the file ademo_export.py into your Blender scripts folder. It is the +export script which will convert from .blend format to the .txt format used by +the demo game. Under unix, the path will be: + +~/.blender/scripts/ademo_export.py + +2) Load the .blend file in blender. Under unix, type this from the directory with +the level.blend file: + +blender level.blend + +3) Edit the level. In the menu, under + +Help -> Scripts Help Browser -> Export -> Allegro Demo Game Level + +you will find some useful tips. + +4) Save the file (use compression before committing). Export it as .txt from the +export menu, choosing Allegro Demo Game Level. + +5) The new level.txt should appear in the game. diff --git a/allegro/demos/skater/data/audio/ding.ogg b/allegro/demos/skater/data/audio/ding.ogg new file mode 100644 index 00000000..ccbdc74a Binary files /dev/null and b/allegro/demos/skater/data/audio/ding.ogg differ diff --git a/allegro/demos/skater/data/audio/dooropen.ogg b/allegro/demos/skater/data/audio/dooropen.ogg new file mode 100644 index 00000000..2fc3d08f Binary files /dev/null and b/allegro/demos/skater/data/audio/dooropen.ogg differ diff --git a/allegro/demos/skater/data/audio/pop.ogg b/allegro/demos/skater/data/audio/pop.ogg new file mode 100644 index 00000000..c6c5f8d4 Binary files /dev/null and b/allegro/demos/skater/data/audio/pop.ogg differ diff --git a/allegro/demos/skater/data/audio/skating.ogg b/allegro/demos/skater/data/audio/skating.ogg new file mode 100644 index 00000000..70f42bcc Binary files /dev/null and b/allegro/demos/skater/data/audio/skating.ogg differ diff --git a/allegro/demos/skater/data/audio/wave.ogg b/allegro/demos/skater/data/audio/wave.ogg new file mode 100644 index 00000000..08c8942a Binary files /dev/null and b/allegro/demos/skater/data/audio/wave.ogg differ diff --git a/allegro/demos/skater/data/graphics/bananas.png b/allegro/demos/skater/data/graphics/bananas.png new file mode 100644 index 00000000..f0da74ab Binary files /dev/null and b/allegro/demos/skater/data/graphics/bananas.png differ diff --git a/allegro/demos/skater/data/graphics/cherries.png b/allegro/demos/skater/data/graphics/cherries.png new file mode 100644 index 00000000..5e730c4d Binary files /dev/null and b/allegro/demos/skater/data/graphics/cherries.png differ diff --git a/allegro/demos/skater/data/graphics/cloud.png b/allegro/demos/skater/data/graphics/cloud.png new file mode 100644 index 00000000..25a8fc54 Binary files /dev/null and b/allegro/demos/skater/data/graphics/cloud.png differ diff --git a/allegro/demos/skater/data/graphics/dooropen.png b/allegro/demos/skater/data/graphics/dooropen.png new file mode 100644 index 00000000..19a2f9f6 Binary files /dev/null and b/allegro/demos/skater/data/graphics/dooropen.png differ diff --git a/allegro/demos/skater/data/graphics/doorshut.png b/allegro/demos/skater/data/graphics/doorshut.png new file mode 100644 index 00000000..93f59114 Binary files /dev/null and b/allegro/demos/skater/data/graphics/doorshut.png differ diff --git a/allegro/demos/skater/data/graphics/exitsign.png b/allegro/demos/skater/data/graphics/exitsign.png new file mode 100644 index 00000000..e13ab1cf Binary files /dev/null and b/allegro/demos/skater/data/graphics/exitsign.png differ diff --git a/allegro/demos/skater/data/graphics/grass.png b/allegro/demos/skater/data/graphics/grass.png new file mode 100644 index 00000000..751f7388 Binary files /dev/null and b/allegro/demos/skater/data/graphics/grass.png differ diff --git a/allegro/demos/skater/data/graphics/ice.png b/allegro/demos/skater/data/graphics/ice.png new file mode 100644 index 00000000..b0618af2 Binary files /dev/null and b/allegro/demos/skater/data/graphics/ice.png differ diff --git a/allegro/demos/skater/data/graphics/icecream.png b/allegro/demos/skater/data/graphics/icecream.png new file mode 100644 index 00000000..588e89d9 Binary files /dev/null and b/allegro/demos/skater/data/graphics/icecream.png differ diff --git a/allegro/demos/skater/data/graphics/icetip.png b/allegro/demos/skater/data/graphics/icetip.png new file mode 100644 index 00000000..e17e83c2 Binary files /dev/null and b/allegro/demos/skater/data/graphics/icetip.png differ diff --git a/allegro/demos/skater/data/graphics/orange.png b/allegro/demos/skater/data/graphics/orange.png new file mode 100644 index 00000000..94f83779 Binary files /dev/null and b/allegro/demos/skater/data/graphics/orange.png differ diff --git a/allegro/demos/skater/data/graphics/skatefast.png b/allegro/demos/skater/data/graphics/skatefast.png new file mode 100644 index 00000000..435b4d7c Binary files /dev/null and b/allegro/demos/skater/data/graphics/skatefast.png differ diff --git a/allegro/demos/skater/data/graphics/skatemed.png b/allegro/demos/skater/data/graphics/skatemed.png new file mode 100644 index 00000000..b5f4babc Binary files /dev/null and b/allegro/demos/skater/data/graphics/skatemed.png differ diff --git a/allegro/demos/skater/data/graphics/skater1.png b/allegro/demos/skater/data/graphics/skater1.png new file mode 100644 index 00000000..530c9d0e Binary files /dev/null and b/allegro/demos/skater/data/graphics/skater1.png differ diff --git a/allegro/demos/skater/data/graphics/skater2.png b/allegro/demos/skater/data/graphics/skater2.png new file mode 100644 index 00000000..dd65c7e2 Binary files /dev/null and b/allegro/demos/skater/data/graphics/skater2.png differ diff --git a/allegro/demos/skater/data/graphics/skater3.png b/allegro/demos/skater/data/graphics/skater3.png new file mode 100644 index 00000000..44363c54 Binary files /dev/null and b/allegro/demos/skater/data/graphics/skater3.png differ diff --git a/allegro/demos/skater/data/graphics/skater4.png b/allegro/demos/skater/data/graphics/skater4.png new file mode 100644 index 00000000..7730497d Binary files /dev/null and b/allegro/demos/skater/data/graphics/skater4.png differ diff --git a/allegro/demos/skater/data/graphics/skateslow.png b/allegro/demos/skater/data/graphics/skateslow.png new file mode 100644 index 00000000..21af40b1 Binary files /dev/null and b/allegro/demos/skater/data/graphics/skateslow.png differ diff --git a/allegro/demos/skater/data/graphics/soil.png b/allegro/demos/skater/data/graphics/soil.png new file mode 100644 index 00000000..0ca02877 Binary files /dev/null and b/allegro/demos/skater/data/graphics/soil.png differ diff --git a/allegro/demos/skater/data/graphics/sweet.png b/allegro/demos/skater/data/graphics/sweet.png new file mode 100644 index 00000000..592b02ad Binary files /dev/null and b/allegro/demos/skater/data/graphics/sweet.png differ diff --git a/allegro/demos/skater/data/graphics/water.png b/allegro/demos/skater/data/graphics/water.png new file mode 100644 index 00000000..23b55cc2 Binary files /dev/null and b/allegro/demos/skater/data/graphics/water.png differ diff --git a/allegro/demos/skater/data/level.txt b/allegro/demos/skater/data/level.txt new file mode 100644 index 00000000..c6679574 --- /dev/null +++ b/allegro/demos/skater/data/level.txt @@ -0,0 +1,15379 @@ +# Exported from Blender 249 +# on Thu Oct 28 23:51:16 2010 (CET) +# do not edit, edit /home/elias/prog/allegro/git/demos/skater/blender/level.blend instead + +# Materials +{ + {"soil", "grass", 1.000000} # 0 "Hill" + {"ice", "icetip", 0.131010} # 1 "Ice" + {"soil", "icetip", 0.400275} # 2 "IcyGrass" + {"soil", "grass", 2.000000} # 3 "Platform" +} + +# Vertices +{ + # Mesh "Curve" + {-7976, -4842} # 0 + {-7896, -4837} # 1 + {-7833, -4848} # 2 + {-7820, -4855} # 3 + {-7809, -4860} # 4 + {-7798, -4863} # 5 + {-7785, -4864} # 6 + {-7775, -4861} # 7 + {-7764, -4856} # 8 + {-7752, -4852} # 9 + {-7739, -4847} # 10 + {-7726, -4842} # 11 + {-7713, -4838} # 12 + {-7700, -4833} # 13 + {-7686, -4829} # 14 + {-7671, -4825} # 15 + {-7657, -4820} # 16 + {-7642, -4816} # 17 + {-7626, -4812} # 18 + {-7610, -4807} # 19 + {-7594, -4803} # 20 + {-7578, -4799} # 21 + {-7561, -4795} # 22 + {-7544, -4791} # 23 + {-7526, -4787} # 24 + {-7508, -4783} # 25 + {-7490, -4780} # 26 + {-7471, -4776} # 27 + {-7452, -4772} # 28 + {-7432, -4769} # 29 + {-7412, -4765} # 30 + {-7392, -4762} # 31 + {-7372, -4758} # 32 + {-7351, -4755} # 33 + {-7329, -4752} # 34 + {-7308, -4749} # 35 + {-7286, -4746} # 36 + {-7263, -4743} # 37 + {-7240, -4740} # 38 + {-7208, -4730} # 39 + {-7950, -4927} # 40 + {-7831, -4904} # 41 + {-7821, -4899} # 42 + {-7811, -4895} # 43 + {-7801, -4890} # 44 + {-7790, -4885} # 45 + {-7779, -4881} # 46 + {-7768, -4876} # 47 + {-7756, -4871} # 48 + {-7744, -4867} # 49 + {-7732, -4862} # 50 + {-7719, -4858} # 51 + {-7706, -4853} # 52 + {-7692, -4849} # 53 + {-7678, -4844} # 54 + {-7664, -4840} # 55 + {-7649, -4835} # 56 + {-7634, -4831} # 57 + {-7619, -4827} # 58 + {-7603, -4823} # 59 + {-7587, -4818} # 60 + {-7570, -4814} # 61 + {-7553, -4810} # 62 + {-7536, -4806} # 63 + {-7518, -4802} # 64 + {-7500, -4799} # 65 + {-7482, -4795} # 66 + {-7463, -4791} # 67 + {-7444, -4787} # 68 + {-7425, -4784} # 69 + {-7405, -4780} # 70 + {-7385, -4777} # 71 + {-7364, -4774} # 72 + {-7343, -4770} # 73 + {-7322, -4767} # 74 + {-7300, -4764} # 75 + {-7278, -4761} # 76 + {-7256, -4758} # 77 + {-7233, -4755} # 78 + {-7221, -4751} # 79 + # Mesh "Curve.001" + {-9671, -4205} # 80 + {-9804, -4116} # 81 + {7868, -869} # 82 + {-9920, -4028} # 83 + {6579, -1099} # 84 + {-9986, -3965} # 85 + {-8177, -3372} # 86 + {-10004, -3934} # 87 + {-10008, -3916} # 88 + {-10003, -3902} # 89 + {-9987, -3888} # 90 + {3821, -1480} # 91 + {-9942, -3877} # 92 + {7135, -1287} # 93 + {-9856, -3873} # 94 + {-5276, -2731} # 95 + {-7939, -3522} # 96 + {942, -1796} # 97 + {8242, -252} # 98 + {-9618, -3881} # 99 + {5428, -1221} # 100 + {5153, -952} # 101 + {89, -2120} # 102 + {-9517, -3880} # 103 + {522, -2130} # 104 + {-9446, -3874} # 105 + {-9668, -3811} # 106 + {-9384, -3863} # 107 + {-2265, -1535} # 108 + {-9332, -3846} # 109 + {6627, -1078} # 110 + {-9292, -3823} # 111 + {5889, -1772} # 112 + {-9269, -3801} # 113 + {-9251, -3776} # 114 + {7481, -1568} # 115 + {-9237, -3737} # 116 + {6947, -1134} # 117 + {-9232, -3694} # 118 + {9111, -54} # 119 + {-9236, -3626} # 120 + {2408, -1713} # 121 + {4219, -1683} # 122 + {-838, -1565} # 123 + {-9255, -3527} # 124 + {-5511, -2724} # 125 + {6825, -973} # 126 + {8425, -14} # 127 + {-9295, -3368} # 128 + {3222, -1395} # 129 + {5864, -1650} # 130 + {3406, -1141} # 131 + {3797, -1358} # 132 + {-9316, -3266} # 133 + {-8574, -2991} # 134 + {5703, -1686} # 135 + {-10232, -3837} # 136 + {-9324, -3172} # 137 + {-4825, -3035} # 138 + {3370, -1268} # 139 + {-5750, -2850} # 140 + {-9317, -3113} # 141 + {-9411, -3217} # 142 + {-9307, -3076} # 143 + {-10234, -3874} # 144 + {-9286, -3036} # 145 + {9608, -307} # 146 + {5560, -1505} # 147 + {-9257, -3004} # 148 + {5141, -1065} # 149 + {-9228, -2984} # 150 + {5927, -1764} # 151 + {-9193, -2968} # 152 + {5281, -1035} # 153 + {-9154, -2957} # 154 + {-8868, -2784} # 155 + {-9111, -2950} # 156 + {9820, -716} # 157 + {-9041, -2949} # 158 + {-5823, -2889} # 159 + {-155, -1985} # 160 + {7446, -1554} # 161 + {-8937, -2964} # 162 + {2705, -1820} # 163 + {7959, -471} # 164 + {-2144, -1463} # 165 + {-8827, -2995} # 166 + {9645, -367} # 167 + {-6542, -2744} # 168 + {9779, -274} # 169 + {-8713, -3030} # 170 + {-10198, -3816} # 171 + {9585, -68} # 172 + {9834, -638} # 173 + {-8590, -3090} # 174 + {3241, -1214} # 175 + {-2722, -1883} # 176 + {1580, -1461} # 177 + {-8462, -3173} # 178 + {5965, -1748} # 179 + {1647, -1459} # 180 + {4873, -1240} # 181 + {8188, -302} # 182 + {7822, -775} # 183 + {-8065, -3484} # 184 + {-8253, -3383} # 185 + {7410, -1430} # 186 + {797, -1928} # 187 + {5757, -1731} # 188 + {8655, -62} # 189 + {-8156, -3477} # 190 + {8351, -52} # 191 + {1417, -1493} # 192 + {-8065, -3561} # 193 + {4195, -1783} # 194 + {5902, -1642} # 195 + {-3806, -2563} # 196 + {-7946, -3632} # 197 + {4802, -1338} # 198 + {-7046, -2617} # 199 + {-7746, -3506} # 200 + {-7865, -3673} # 201 + {7136, -1184} # 202 + {-7785, -3704} # 203 + {9299, -100} # 204 + {-7723, -3710} # 205 + {-9143, -2731} # 206 + {-7674, -3702} # 207 + {-5460, -2712} # 208 + {-7614, -3684} # 209 + {5770, -1631} # 210 + {3315, -1293} # 211 + {-5644, -2786} # 212 + {-7550, -3634} # 213 + {-3714, -2492} # 214 + {6461, -1041} # 215 + {4556, -1681} # 216 + {-7482, -3544} # 217 + {-690, -1647} # 218 + {7045, -1207} # 219 + {9545, -239} # 220 + {-7414, -3385} # 221 + {9766, -886} # 222 + {-3618, -2428} # 223 + {3324, -1154} # 224 + {9471, -182} # 225 + {-7339, -3129} # 226 + {9802, -324} # 227 + {-10219, -3825} # 228 + {3497, -1273} # 229 + {8428, -134} # 230 + {-7261, -2977} # 231 + {2525, -1765} # 232 + {4307, -1696} # 233 + {-6109, -2931} # 234 + {-7187, -2877} # 235 + {-5195, -2769} # 236 + {4342, -1816} # 237 + {-4444, -3126} # 238 + {-7118, -2819} # 239 + {-6295, -2871} # 240 + {-7073, -2792} # 241 + {-10238, -3853} # 242 + {-7026, -2768} # 243 + {8921, -39} # 244 + {-6980, -2758} # 245 + {-9332, -2771} # 246 + {-6935, -2757} # 247 + {-9366, -2795} # 248 + {-6886, -2753} # 249 + {-8996, -2748} # 250 + {-6837, -2755} # 251 + {-7990, -3511} # 252 + {-6786, -2762} # 253 + {-6955, -2612} # 254 + {-6712, -2780} # 255 + {-4560, -3143} # 256 + {4310, -1818} # 257 + {3567, -1301} # 258 + {-6611, -2819} # 259 + {-5113, -2820} # 260 + {9388, -136} # 261 + {6675, -1066} # 262 + {-6517, -2865} # 263 + {4971, -992} # 264 + {-991, -1491} # 265 + {9493, -17} # 266 + {-6368, -2944} # 267 + {7639, -1504} # 268 + {6602, -957} # 269 + {4008, -1546} # 270 + {5190, -967} # 271 + {-6271, -2992} # 272 + {3279, -1180} # 273 + {-4482, -3137} # 274 + {1817, -1476} # 275 + {-6176, -3030} # 276 + {-6636, -2697} # 277 + {5305, -1157} # 278 + {-7128, -2663} # 279 + {-6085, -3053} # 280 + {-3206, -2202} # 281 + {4261, -1810} # 282 + {-4004, -2745} # 283 + {-6019, -3059} # 284 + {-7699, -3485} # 285 + {-5956, -3057} # 286 + {-4600, -3138} # 287 + {9394, 23} # 288 + {-4139, -2866} # 289 + {-5875, -3040} # 290 + {6153, -1415} # 291 + {9798, -799} # 292 + {-1300, -1377} # 293 + {-5798, -3010} # 294 + {5536, -1384} # 295 + {6440, -1204} # 296 + {-9337, -3595} # 297 + {-5725, -2971} # 298 + {4399, -1670} # 299 + {-5034, -2877} # 300 + {5604, -1480} # 301 + {-5899, -2919} # 302 + {-5620, -2907} # 303 + {7544, -1573} # 304 + {-10219, -3899} # 305 + {4531, -1560} # 306 + {-5552, -2871} # 307 + {2093, -1564} # 308 + {-9454, -3772} # 309 + {1148, -1628} # 310 + {-5480, -2843} # 311 + {-6044, -2938} # 312 + {4622, -1599} # 313 + {9701, -629} # 314 + {-5406, -2830} # 315 + {-4742, -3086} # 316 + {-9292, -2753} # 317 + {4170, -1662} # 318 + {-5330, -2833} # 319 + {-5355, -2711} # 320 + {3717, -1395} # 321 + {9290, 53} # 322 + {-5252, -2853} # 323 + {7515, -1472} # 324 + {4424, -1791} # 325 + {-3894, -2639} # 326 + {-5171, -2890} # 327 + {5452, -1343} # 328 + {5678, -1564} # 329 + {-9364, -3402} # 330 + {-5088, -2941} # 331 + {2751, -1824} # 332 + {7992, -576} # 333 + {3373, -1142} # 334 + {-5006, -3001} # 335 + {5732, -1609} # 336 + {-2017, -1404} # 337 + {8049, -478} # 338 + {7682, -1328} # 339 + {-4881, -3098} # 340 + {9185, 74} # 341 + {-14, -2068} # 342 + {-5980, -2936} # 343 + {-4801, -3156} # 344 + {4489, -1746} # 345 + {-9442, -2968} # 346 + {7482, -1465} # 347 + {-4717, -3208} # 348 + {345, -2178} # 349 + {-6737, -2658} # 350 + {-1453, -1345} # 351 + {-4635, -3245} # 352 + {8499, -104} # 353 + {1715, -1462} # 354 + {8678, 66} # 355 + {-4575, -3260} # 356 + {401, -2171} # 357 + {-4536, -3264} # 358 + {8003, -397} # 359 + {-4496, -3264} # 360 + {-10193, -3930} # 361 + {-4457, -3259} # 362 + {-9436, -2921} # 363 + {-4419, -3248} # 364 + {-6800, -2637} # 365 + {-4363, -3224} # 366 + {2879, -1802} # 367 + {7641, -1401} # 368 + {7272, -1315} # 369 + {-4288, -3175} # 370 + {-9344, -3646} # 371 + {5379, -1241} # 372 + {612, -2077} # 373 + {-4215, -3111} # 374 + {2833, -1818} # 375 + {8362, -168} # 376 + {-496, -1764} # 377 + {-4141, -3037} # 378 + {8050, -327} # 379 + {6003, -1724} # 380 + {8588, 45} # 381 + {7735, -1291} # 382 + {-3975, -2862} # 383 + {-9360, -3691} # 384 + {5178, -1073} # 385 + {8102, -262} # 386 + {9683, -764} # 387 + {6017, -1570} # 388 + {703, -2009} # 389 + {5068, -1074} # 390 + {-3870, -2760} # 391 + {5126, -945} # 392 + {5629, -1601} # 393 + {5842, -1769} # 394 + {-3782, -2684} # 395 + {3692, -1274} # 396 + {8740, -48} # 397 + {3450, -1146} # 398 + {-3689, -2614} # 399 + {4033, -1668} # 400 + {-10136, -3983} # 401 + {3562, -1190} # 402 + {-3593, -2549} # 403 + {8157, -201} # 404 + {9695, -695} # 405 + {4254, -1692} # 406 + {-3461, -2471} # 407 + {4919, -1037} # 408 + {-9586, -3805} # 409 + {6554, -977} # 410 + {457, -2156} # 411 + {7865, -666} # 412 + {3617, -1221} # 413 + {6763, -960} # 414 + {-3182, -2324} # 415 + {-9085, -2735} # 416 + {9646, -114} # 417 + {9820, -377} # 418 + {-9407, -3745} # 419 + {4944, -1159} # 420 + {6532, -1127} # 421 + {4102, -1620} # 422 + {-3018, -2228} # 423 + {4351, -1689} # 424 + {7409, -1533} # 425 + {-7652, -3458} # 426 + {9206, -73} # 427 + {-2870, -2131} # 428 + {-4909, -2974} # 429 + {4690, -1504} # 430 + {5044, -953} # 431 + {-7890, -3528} # 432 + {9682, -460} # 433 + {-2698, -2004} # 434 + {5817, -1648} # 435 + {-9380, -3719} # 436 + {6416, -1082} # 437 + {6297, -1373} # 438 + {-7585, -3409} # 439 + {5940, -1626} # 440 + {6948, -1031} # 441 + {-2396, -1766} # 442 + {7582, -1458} # 443 + {-9514, -3792} # 444 + {8575, -80} # 445 + {5105, -1066} # 446 + {3171, -1490} # 447 + {-6861, -2622} # 448 + {9685, -148} # 449 + {3513, -1166} # 450 + {-2241, -1656} # 451 + {1956, -1513} # 452 + {6377, -1272} # 453 + {-2120, -1584} # 454 + {6875, -992} # 455 + {-10001, -4085} # 456 + {7615, -1431} # 457 + {-1993, -1525} # 458 + {7355, -1389} # 459 + {-7417, -3073} # 460 + {9694, -512} # 461 + {-1860, -1482} # 462 + {-9424, -2879} # 463 + {-1602, -1331} # 464 + {-1756, -1463} # 465 + {9700, -569} # 466 + {-1685, -1455} # 467 + {-9847, -4188} # 468 + {-1577, -1452} # 469 + {9841, -566} # 470 + {4375, -1810} # 471 + {-1428, -1466} # 472 + {-4521, -3143} # 473 + {7664, -1363} # 474 + {1264, -1556} # 475 + {-1276, -1499} # 476 + {-1710, -1334} # 477 + {7918, -548} # 478 + {4597, -1478} # 479 + {-1121, -1548} # 480 + {278, -2177} # 481 + {-1885, -1361} # 482 + {9016, -43} # 483 + {-966, -1612} # 484 + {8282, -96} # 485 + {6486, -1162} # 486 + {1354, -1515} # 487 + {-814, -1687} # 488 + {-1781, -1341} # 489 + {7353, -1492} # 490 + {3197, -1273} # 491 + {-666, -1768} # 492 + {2633, -1804} # 493 + {-10161, -3808} # 494 + {6042, -1691} # 495 + {-472, -1886} # 496 + {9079, 87} # 497 + {-4313, -3053} # 498 + {1039, -1712} # 499 + {7580, -1561} # 500 + {8217, -146} # 501 + {-7841, -3527} # 502 + {9752, -228} # 503 + {3642, -1343} # 504 + {-130, -2106} # 505 + {9720, -186} # 506 + {5007, -969} # 507 + {8772, 81} # 508 + {6273, -1251} # 509 + {-7227, -2754} # 510 + {5083, -944} # 511 + {11, -2190} # 512 + {3146, -1369} # 513 + {-3042, -2106} # 514 + {2949, -1753} # 515 + {113, -2242} # 516 + {4127, -1741} # 517 + {-9342, -3516} # 518 + {7546, -1470} # 519 + {210, -2279} # 520 + {5354, -1119} # 521 + {-2895, -2010} # 522 + {-4660, -3123} # 523 + {303, -2298} # 524 + {4465, -1625} # 525 + {5252, -1111} # 526 + {370, -2299} # 527 + {8092, -415} # 528 + {426, -2293} # 529 + {6177, -1536} # 530 + {8973, 92} # 531 + {481, -2278} # 532 + {186, -2157} # 533 + {547, -2251} # 534 + {8871, 89} # 535 + {6774, -1065} # 536 + {6724, -1061} # 537 + {636, -2199} # 538 + {-1146, -1427} # 539 + {7270, -1418} # 540 + {7663, -1466} # 541 + {727, -2131} # 542 + {6098, -1635} # 543 + {-7508, -3320} # 544 + {6352, -1151} # 545 + {822, -2050} # 546 + {-2420, -1645} # 547 + {7447, -1451} # 548 + {-6201, -2908} # 549 + {6507, -1006} # 550 + {967, -1918} # 551 + {9840, -498} # 552 + {7047, -1104} # 553 + {5979, -1602} # 554 + {1064, -1833} # 555 + {3032, -1634} # 556 + {7513, -1575} # 557 + {4848, -1119} # 558 + {1172, -1750} # 559 + {5227, -990} # 560 + {2987, -1708} # 561 + {1288, -1678} # 562 + {-9247, -2740} # 563 + {5032, -1090} # 564 + {8138, -356} # 565 + {1379, -1636} # 566 + {4665, -1383} # 567 + {1442, -1614} # 568 + {-9197, -2733} # 569 + {1522, -1594} # 570 + {-9443, -3019} # 571 + {5215, -1088} # 572 + {1605, -1583} # 573 + {-9435, -3099} # 574 + {1672, -1580} # 575 + {-10061, -3803} # 576 + {1740, -1583} # 577 + {8829, -41} # 578 + {1842, -1597} # 579 + {2218, -1621} # 580 + {3266, -1336} # 581 + {2794, -1824} # 582 + {1980, -1634} # 583 + {-5577, -2750} # 584 + {-5422, -2708} # 585 + {3430, -1262} # 586 + {2117, -1686} # 587 + {6651, -944} # 588 + {7925, -719} # 589 + {7751, -1042} # 590 + {2243, -1742} # 591 + {8504, 18} # 592 + {4777, -1217} # 593 + {7695, -1399} # 594 + {2432, -1834} # 595 + {9636, -920} # 596 + {6711, -940} # 597 + {6074, -1513} # 598 + {9666, -412} # 599 + {2550, -1887} # 600 + {3071, -1550} # 601 + {6874, -1095} # 602 + {9833, -435} # 603 + {2658, -1925} # 604 + {-7324, -2860} # 605 + {-4240, -2990} # 606 + {1497, -1472} # 607 + {2730, -1941} # 608 + {9663, -839} # 609 + {2776, -1946} # 610 + {-6393, -2823} # 611 + {2819, -1945} # 612 + {5795, -1753} # 613 + {2858, -1939} # 614 + {7614, -1534} # 615 + {2903, -1924} # 616 + {4996, -1114} # 617 + {2919, -1778} # 618 + {2944, -1899} # 619 + {-9400, -2833} # 620 + {2973, -1874} # 621 + {-7793, -3520} # 622 + {3012, -1830} # 623 + {6823, -1076} # 624 + {-4388, -3102} # 625 + {8601, -2092} # 626 + {3057, -1756} # 627 + {-3486, -2350} # 628 + {-9785, -3813} # 629 + {8300, -208} # 630 + {3096, -1672} # 631 + {8938, -1583} # 632 + {9424, -1181} # 633 + {8734, -1822} # 634 + {9547, -1068} # 635 + {9177, -1328} # 636 + {8650, -1950} # 637 + {8842, -1705} # 638 + {8787, -1764} # 639 + {8894, -1646} # 640 + {9492, -1124} # 641 + {9603, -998} # 642 + {9315, -1241} # 643 + {9029, -1468} # 644 + {8687, -1884} # 645 + {8625, -2021} # 646 + {8985, -1902} # 647 + {8938, -1964} # 648 + {8902, -2030} # 649 + {9308, -1412} # 650 + {9412, -1329} # 651 + {9485, -1281} # 652 + {9057, -1774} # 653 + {9091, -1715} # 654 + {9139, -1641} # 655 + {9024, -1832} # 656 + {9598, -1171} # 657 + {9549, -1228} # 658 + {9213, -1521} # 659 + {8379, -3204} # 660 + {8655, -2585} # 661 + {-4258, -3139} # 662 + {-4179, -3071} # 663 + {-4060, -2952} # 664 + {-4099, -2990} # 665 + {-4024, -2911} # 666 + {-3943, -2832} # 667 + {-4171, -3038} # 668 + {-4020, -2869} # 669 + {-4248, -3109} # 670 + {-4284, -3141} # 671 + {-4208, -3075} # 672 + {-4091, -2955} # 673 + {-4131, -2997} # 674 + {-4053, -2915} # 675 + {-3972, -2833} # 676 + {10071, -3541} # 677 + {10347, -2921} # 678 + {-10350, -4354} # 679 + {-10526, -4338} # 680 + {-8340, -3297} # 681 + {-8357, -3157} # 682 + # Mesh "CurveCircle" + {8795, -42} # 683 + {8796, -63} # 684 + {8799, -76} # 685 + {8803, -89} # 686 + {8809, -101} # 687 + {8816, -112} # 688 + {8825, -122} # 689 + {8835, -130} # 690 + {8846, -138} # 691 + {8858, -144} # 692 + {8870, -148} # 693 + {8884, -151} # 694 + {8898, -152} # 695 + {8912, -151} # 696 + {8925, -148} # 697 + {8938, -144} # 698 + {8950, -138} # 699 + {8960, -130} # 700 + {8970, -122} # 701 + {8979, -112} # 702 + {8986, -101} # 703 + {8992, -89} # 704 + {8997, -76} # 705 + {8999, -63} # 706 + {9001, -41} # 707 + {8879, -170} # 708 + {8898, -171} # 709 + {8916, -170} # 710 + {8861, -166} # 711 + {8934, -166} # 712 + {8844, -160} # 713 + {8951, -160} # 714 + {8828, -153} # 715 + {8967, -153} # 716 + {8814, -143} # 717 + {8981, -143} # 718 + {8801, -131} # 719 + {8994, -131} # 720 + {8789, -118} # 721 + {9006, -118} # 722 + {8779, -103} # 723 + {9016, -103} # 724 + {8771, -88} # 725 + {9024, -88} # 726 + {8765, -71} # 727 + {9030, -71} # 728 + {8762, -53} # 729 + {9033, -53} # 730 + {8762, -45} # 731 + {9034, -44} # 732 + # Mesh "Font.001" + {2890, -2260} # 733 + {2874, -2268} # 734 + {1770, -2158} # 735 + {2773, -2201} # 736 + {2681, -2173} # 737 + {2438, -2114} # 738 + {2166, -2051} # 739 + {2844, -2266} # 740 + {2236, -2143} # 741 + {1508, -2234} # 742 + {1686, -2105} # 743 + {2833, -2249} # 744 + {2132, -2013} # 745 + {2837, -2231} # 746 + {2314, -2088} # 747 + {2311, -2071} # 748 + {2874, -2201} # 749 + {1664, -2190} # 750 + {2535, -2189} # 751 + {2484, -2156} # 752 + {2395, -2173} # 753 + {1353, -2255} # 754 + {2860, -2191} # 755 + {2745, -2268} # 756 + {2037, -2091} # 757 + {2506, -2208} # 758 + {2831, -2202} # 759 + {2590, -2214} # 760 + {1923, -2095} # 761 + {2765, -2260} # 762 + {2629, -2184} # 763 + {2829, -2185} # 764 + {1640, -2229} # 765 + {2474, -2170} # 766 + {2505, -2153} # 767 + {2864, -2175} # 768 + {2187, -2092} # 769 + {1643, -2213} # 770 + {1539, -2194} # 771 + {2193, -2054} # 772 + {2883, -2184} # 773 + {1479, -2337} # 774 + {2891, -2202} # 775 + {2113, -2014} # 776 + {1603, -2275} # 777 + {2553, -2174} # 778 + {2883, -2218} # 779 + {1575, -2237} # 780 + {1898, -2093} # 781 + {2310, -2136} # 782 + {2851, -2242} # 783 + {1933, -2012} # 784 + {1604, -2309} # 785 + {2488, -2226} # 786 + {1627, -2131} # 787 + {2433, -2182} # 788 + {2855, -2254} # 789 + {2219, -2139} # 790 + {1734, -2156} # 791 + {1336, -2266} # 792 + {2767, -2180} # 793 + {2453, -2187} # 794 + {2618, -2162} # 795 + {2887, -2245} # 796 + {1883, -2118} # 797 + {2305, -2114} # 798 + {2180, -2127} # 799 + {2376, -2074} # 800 + {653, -2528} # 801 + {641, -2521} # 802 + {656, -2373} # 803 + {673, -2382} # 804 + {669, -2426} # 805 + {720, -2454} # 806 + {755, -2427} # 807 + {773, -2437} # 808 + {661, -2498} # 809 + {704, -2465} # 810 + {667, -2445} # 811 + {764, -2567} # 812 + {747, -2561} # 813 + {790, -2431} # 814 + {806, -2437} # 815 + {817, -2579} # 816 + {800, -2575} # 817 + {832, -2443} # 818 + {849, -2447} # 819 + {943, -2485} # 820 + {1705, -2101} # 821 + {2315, -2150} # 822 + {2113, -2073} # 823 + {2581, -2249} # 824 + {913, -2474} # 825 + {1804, -2039} # 826 + {1564, -2172} # 827 + {2166, -2065} # 828 + {889, -2479} # 829 + {1685, -2192} # 830 + {2188, -2083} # 831 + {881, -2494} # 832 + {944, -2504} # 833 + {932, -2537} # 834 + {1570, -2308} # 835 + {1717, -2098} # 836 + {1865, -2112} # 837 + {904, -2547} # 838 + {2334, -2050} # 839 + {876, -2538} # 840 + {2280, -2130} # 841 + {1751, -2065} # 842 + {863, -2514} # 843 + {1728, -2178} # 844 + {868, -2476} # 845 + {2113, -2091} # 846 + {1662, -2216} # 847 + {2421, -2109} # 848 + {905, -2452} # 849 + {2389, -2192} # 850 + {2418, -2205} # 851 + {1462, -2347} # 852 + {2601, -2237} # 853 + {947, -2469} # 854 + {2706, -2272} # 855 + {2392, -2078} # 856 + {2810, -2193} # 857 + {879, -2510} # 858 + {2358, -2123} # 859 + {2389, -2060} # 860 + {2313, -2049} # 861 + {897, -2531} # 862 + {2359, -2182} # 863 + {1562, -2203} # 864 + {2748, -2216} # 865 + {918, -2527} # 866 + {1753, -2167} # 867 + {1652, -2277} # 868 + {1860, -2032} # 869 + {924, -2513} # 870 + {1045, -2541} # 871 + {988, -2541} # 872 + {1329, -2327} # 873 + {2808, -2209} # 874 + {2213, -2053} # 875 + {967, -2520} # 876 + {2674, -2210} # 877 + {1549, -2217} # 878 + {2372, -2187} # 879 + {2226, -2050} # 880 + {971, -2495} # 881 + {2800, -2263} # 882 + {2579, -2153} # 883 + {1612, -2141} # 884 + {1672, -2153} # 885 + {2503, -2132} # 886 + {1656, -2145} # 887 + {984, -2484} # 888 + {2367, -2057} # 889 + {2133, -2150} # 890 + {2561, -2157} # 891 + {1659, -2112} # 892 + {2730, -2245} # 893 + {2543, -2154} # 894 + {2518, -2220} # 895 + {971, -2468} # 896 + {2246, -2115} # 897 + {1421, -2372} # 898 + {1512, -2202} # 899 + {2320, -2108} # 900 + {2260, -2057} # 901 + {1932, -2081} # 902 + {975, -2459} # 903 + {1330, -2403} # 904 + {1529, -2212} # 905 + {1900, -2114} # 906 + {956, -2437} # 907 + {1916, -2017} # 908 + {1542, -2313} # 909 + {2224, -2059} # 910 + {967, -2415} # 911 + {2293, -2136} # 912 + {1717, -2163} # 913 + {1005, -2405} # 914 + {1305, -2359} # 915 + {1415, -2317} # 916 + {2537, -2170} # 917 + {1033, -2416} # 918 + {2037, -2150} # 919 + {1041, -2432} # 920 + {2514, -2195} # 921 + {2037, -2073} # 922 + {1033, -2453} # 923 + {1490, -2232} # 924 + {1534, -2286} # 925 + {2360, -2153} # 926 + {2464, -2150} # 927 + {989, -2468} # 928 + {2687, -2268} # 929 + {1677, -2141} # 930 + {2592, -2205} # 931 + {2243, -2052} # 932 + {2571, -2186} # 933 + {992, -2477} # 934 + {2366, -2041} # 935 + {2791, -2239} # 936 + {1025, -2486} # 937 + {2267, -2154} # 938 + {2036, -2014} # 939 + {1713, -2154} # 940 + {2572, -2173} # 941 + {1036, -2513} # 942 + {2558, -2191} # 943 + {2199, -2114} # 944 + {1325, -2345} # 945 + {2584, -2230} # 946 + {1824, -2132} # 947 + {2330, -2156} # 948 + {1882, -2104} # 949 + {1026, -2528} # 950 + {1044, -2527} # 951 + {1915, -2110} # 952 + {1364, -2381} # 953 + {2640, -2259} # 954 + {1008, -2495} # 955 + {2363, -2169} # 956 + {1621, -2228} # 957 + {1702, -2193} # 958 + {989, -2498} # 959 + {1950, -2080} # 960 + {2786, -2254} # 961 + {1568, -2327} # 962 + {983, -2514} # 963 + {1618, -2219} # 964 + {2463, -2213} # 965 + {2017, -2150} # 966 + {992, -2521} # 967 + {2321, -2122} # 968 + {2113, -2150} # 969 + {1009, -2525} # 970 + {2341, -2126} # 971 + {1554, -2234} # 972 + {2345, -2163} # 973 + {1020, -2511} # 974 + {2346, -2145} # 975 + {1023, -2430} # 976 + {2326, -2064} # 977 + {2632, -2174} # 978 + {1011, -2421} # 979 + {2331, -2095} # 980 + {2377, -2095} # 981 + {1768, -2099} # 982 + {978, -2425} # 983 + {2305, -2163} # 984 + {1700, -2177} # 985 + {2584, -2171} # 986 + {1673, -2119} # 987 + {975, -2441} # 988 + {2405, -2163} # 989 + {1404, -2383} # 990 + {1705, -2139} # 991 + {990, -2449} # 992 + {2326, -2085} # 993 + {2745, -2239} # 994 + {2484, -2209} # 995 + {1019, -2443} # 996 + {1877, -2027} # 997 + {1805, -2109} # 998 + {2602, -2167} # 999 + {1073, -2530} # 1000 + {1074, -2431} # 1001 + {1092, -2431} # 1002 + {1093, -2490} # 1003 + {1578, -2162} # 1004 + {1351, -2400} # 1005 + {2327, -2037} # 1006 + {1108, -2509} # 1007 + {2177, -2046} # 1008 + {1350, -2350} # 1009 + {2285, -2148} # 1010 + {2809, -2229} # 1011 + {1812, -2138} # 1012 + {2142, -2091} # 1013 + {1124, -2496} # 1014 + {2552, -2241} # 1015 + {1136, -2509} # 1016 + {1122, -2523} # 1017 + {2599, -2177} # 1018 + {2171, -2032} # 1019 + {2437, -2199} # 1020 + {1614, -2292} # 1021 + {2242, -2124} # 1022 + {1897, -2102} # 1023 + {1102, -2521} # 1024 + {2150, -2121} # 1025 + {2621, -2256} # 1026 + {2211, -2038} # 1027 + {1087, -2506} # 1028 + {2181, -2108} # 1029 + {1090, -2527} # 1030 + {1180, -2499} # 1031 + {1668, -2130} # 1032 + {1820, -2074} # 1033 + {1693, -2091} # 1034 + {1141, -2473} # 1035 + {1647, -2197} # 1036 + {1940, -2104} # 1037 + {1649, -2127} # 1038 + {1139, -2435} # 1039 + {1690, -2115} # 1040 + {1157, -2411} # 1041 + {1504, -2254} # 1042 + {2260, -2136} # 1043 + {1197, -2403} # 1044 + {1396, -2305} # 1045 + {2338, -2077} # 1046 + {1231, -2429} # 1047 + {1357, -2333} # 1048 + {2546, -2210} # 1049 + {2732, -2206} # 1050 + {1227, -2477} # 1051 + {1712, -2090} # 1052 + {1369, -2409} # 1053 + {2413, -2186} # 1054 + {1206, -2474} # 1055 + {2147, -2054} # 1056 + {2562, -2227} # 1057 + {2017, -2014} # 1058 + {1216, -2450} # 1059 + {2541, -2227} # 1060 + {2154, -2037} # 1061 + {1200, -2420} # 1062 + {2402, -2192} # 1063 + {1338, -2418} # 1064 + {1383, -2372} # 1065 + {2138, -2109} # 1066 + {1163, -2426} # 1067 + {2154, -2071} # 1068 + {1589, -2298} # 1069 + {2160, -2107} # 1070 + {1155, -2447} # 1071 + {2249, -2143} # 1072 + {1162, -2472} # 1073 + {2773, -2275} # 1074 + {1552, -2296} # 1075 + {2189, -2042} # 1076 + {2619, -2177} # 1077 + {1362, -2463} # 1078 + {1346, -2472} # 1079 + {1283, -2356} # 1080 + {1298, -2341} # 1081 + {1676, -2176} # 1082 + {2469, -2185} # 1083 + {2330, -2104} # 1084 + {1637, -2287} # 1085 + # Mesh "Mesh.001" + {5150, -2933} # 1086 + {4451, -3076} # 1087 + {6162, -2416} # 1088 + {6442, -2299} # 1089 + {4211, -3369} # 1090 + {4386, -3203} # 1091 + {5637, -2540} # 1092 + {4079, -3456} # 1093 + {4106, -3524} # 1094 + {4160, -3495} # 1095 + {5780, -2526} # 1096 + {4181, -3401} # 1097 + {6442, -2375} # 1098 + {3210, -3964} # 1099 + {4333, -3266} # 1100 + {3743, -3509} # 1101 + {3914, -3469} # 1102 + {3702, -3530} # 1103 + {4079, -3532} # 1104 + {3393, -3859} # 1105 + {3863, -3474} # 1106 + {4416, -3176} # 1107 + {3702, -3606} # 1108 + {3210, -3888} # 1109 + {6311, -2316} # 1110 + {3563, -3709} # 1111 + {5376, -2811} # 1112 + {4614, -3096} # 1113 + {4303, -3232} # 1114 + {5850, -2497} # 1115 + {3784, -3493} # 1116 + {3563, -3633} # 1117 + {5496, -2696} # 1118 + {5150, -3008} # 1119 + {5289, -2869} # 1120 + {5605, -2646} # 1121 + {4358, -3158} # 1122 + {3824, -3557} # 1123 + {4303, -3308} # 1124 + {4358, -3234} # 1125 + {3393, -3783} # 1126 + {4106, -3448} # 1127 + {3304, -3846} # 1128 + {3784, -3569} # 1129 + {5780, -2450} # 1130 + {3914, -3545} # 1131 + {3349, -3817} # 1132 + {4484, -3134} # 1133 + {5935, -2393} # 1134 + {5723, -2555} # 1135 + {3133, -3967} # 1136 + {3304, -3922} # 1137 + {3824, -3481} # 1138 + {3450, -3812} # 1139 + {5079, -2956} # 1140 + {5221, -2979} # 1141 + {3257, -3870} # 1142 + {5337, -2838} # 1143 + {5605, -2570} # 1144 + {5289, -2944} # 1145 + {3450, -3736} # 1146 + {4248, -3393} # 1147 + {4614, -3020} # 1148 + {5565, -2612} # 1149 + {4010, -3541} # 1150 + {4520, -3043} # 1151 + {4846, -2998} # 1152 + {5496, -2772} # 1153 + {5412, -2857} # 1154 + {4484, -3058} # 1155 + {3172, -3971} # 1156 + {3257, -3946} # 1157 + {5008, -3049} # 1158 + {4134, -3436} # 1159 + {3863, -3550} # 1160 + {3620, -3586} # 1161 + {3743, -3585} # 1162 + {5676, -2510} # 1163 + {3620, -3662} # 1164 + {4565, -3030} # 1165 + {6162, -2340} # 1166 + {6038, -2366} # 1167 + {4939, -2986} # 1168 + {3112, -3902} # 1169 + {5337, -2914} # 1170 + {6311, -2392} # 1171 + {5565, -2688} # 1172 + {5451, -2820} # 1173 + {4333, -3190} # 1174 + {4451, -3152} # 1175 + {4010, -3465} # 1176 + {5079, -3032} # 1177 + {4050, -3537} # 1178 + {4846, -3074} # 1179 + {4939, -3062} # 1180 + {5412, -2781} # 1181 + {4386, -3128} # 1182 + {5850, -2421} # 1183 + {4416, -3100} # 1184 + {5723, -2480} # 1185 + {6038, -2441} # 1186 + {4050, -3461} # 1187 + {3661, -3632} # 1188 + {4683, -3011} # 1189 + {4160, -3419} # 1190 + {5376, -2887} # 1191 + {5637, -2615} # 1192 + {4520, -3119} # 1193 + {5935, -2468} # 1194 + {4683, -3087} # 1195 + {4181, -3477} # 1196 + {4211, -3445} # 1197 + {4565, -3105} # 1198 + {5451, -2745} # 1199 + {5676, -2585} # 1200 + {3349, -3892} # 1201 + {3661, -3556} # 1202 + {3161, -3899} # 1203 + {4134, -3512} # 1204 + {5221, -2904} # 1205 + {4248, -3318} # 1206 + {5008, -2973} # 1207 + {3113, -3961} # 1208 + {3097, -3901} # 1209 + {3098, -3939} # 1210 + # Mesh "Mesh.002" + {-8913, -4174} # 1211 + {-8700, -4273} # 1212 + {-8547, -4340} # 1213 + {-8408, -4397} # 1214 + {-8913, -4099} # 1215 + {-8282, -4446} # 1216 + {-8168, -4488} # 1217 + {-8014, -4538} # 1218 + {-3073, -4596} # 1219 + {-7839, -4587} # 1220 + {-8547, -4264} # 1221 + {-7689, -4622} # 1222 + {-4225, -4690} # 1223 + {-7559, -4645} # 1224 + {-7443, -4662} # 1225 + {-7336, -4673} # 1226 + {-7232, -4681} # 1227 + {-7145, -4683} # 1228 + {-7073, -4679} # 1229 + {-7008, -4672} # 1230 + {-2768, -4699} # 1231 + {-6947, -4663} # 1232 + {-6883, -4648} # 1233 + {-6801, -4623} # 1234 + {-6596, -4478} # 1235 + {-6659, -4571} # 1236 + {-7008, -4597} # 1237 + {-6596, -4554} # 1238 + {-6416, -4493} # 1239 + {-3114, -4601} # 1240 + {-6548, -4547} # 1241 + {-6192, -4633} # 1242 + {-7443, -4586} # 1243 + {-6507, -4547} # 1244 + {-6465, -4554} # 1245 + {-6416, -4569} # 1246 + {-4037, -4764} # 1247 + {-6367, -4592} # 1248 + {-4098, -4736} # 1249 + {-5749, -4738} # 1250 + {-6317, -4621} # 1251 + {-4287, -4677} # 1252 + {-7559, -4569} # 1253 + {-6267, -4655} # 1254 + {-4901, -4738} # 1255 + {-6190, -4710} # 1256 + {-6139, -4744} # 1257 + {-6084, -4776} # 1258 + {-3621, -4886} # 1259 + {-6028, -4802} # 1260 + {-5478, -4660} # 1261 + {-5971, -4820} # 1262 + {-8282, -4370} # 1263 + {-5920, -4829} # 1264 + {-5868, -4831} # 1265 + {-8168, -4412} # 1266 + {-5809, -4826} # 1267 + {-6947, -4587} # 1268 + {-4961, -4726} # 1269 + {-5749, -4814} # 1270 + {-7153, -4606} # 1271 + {-5689, -4797} # 1272 + {-5868, -4755} # 1273 + {-5599, -4768} # 1274 + {-3031, -4596} # 1275 + {-3655, -4890} # 1276 + {-5541, -4751} # 1277 + {-6507, -4472} # 1278 + {-5478, -4736} # 1279 + {-5406, -4725} # 1280 + {-5809, -4750} # 1281 + {-5350, -4723} # 1282 + {-5302, -4725} # 1283 + {-3405, -4774} # 1284 + {-4406, -4674} # 1285 + {-5238, -4732} # 1286 + {-5174, -4745} # 1287 + {-2630, -4786} # 1288 + {-5115, -4760} # 1289 + {-3206, -4633} # 1290 + {-5022, -4786} # 1291 + {-5350, -4647} # 1292 + {-6028, -4726} # 1293 + {-7073, -4603} # 1294 + {-4961, -4802} # 1295 + {-4901, -4814} # 1296 + {-4841, -4821} # 1297 + {-4782, -4822} # 1298 + {-3698, -4890} # 1299 + {-4724, -4818} # 1300 + {-4668, -4809} # 1301 + {-4521, -4695} # 1302 + {-4611, -4795} # 1303 + {-5174, -4669} # 1304 + {-4521, -4771} # 1305 + {-4464, -4758} # 1306 + {-4406, -4750} # 1307 + {-5689, -4721} # 1308 + {-4347, -4747} # 1309 + {-6465, -4478} # 1310 + {-4287, -4753} # 1311 + {-4225, -4766} # 1312 + {-2983, -4603} # 1313 + {-4161, -4786} # 1314 + {-4098, -4812} # 1315 + {-4037, -4840} # 1316 + {-3943, -4887} # 1317 + {-2836, -4660} # 1318 + {-3880, -4916} # 1319 + {-3817, -4940} # 1320 + {-3756, -4957} # 1321 + {-8014, -4462} # 1322 + {-3698, -4966} # 1323 + {-3655, -4965} # 1324 + {-3621, -4962} # 1325 + {-3587, -4954} # 1326 + {-3548, -4940} # 1327 + {-8700, -4197} # 1328 + {-3498, -4915} # 1329 + {-3548, -4864} # 1330 + {-3451, -4884} # 1331 + {-3817, -4864} # 1332 + {-3405, -4850} # 1333 + {-4161, -4710} # 1334 + {-3310, -4775} # 1335 + {-2885, -4636} # 1336 + {-4724, -4742} # 1337 + {-3251, -4734} # 1338 + {-5302, -4649} # 1339 + {-3206, -4709} # 1340 + {-3160, -4689} # 1341 + {-5022, -4710} # 1342 + {-4668, -4733} # 1343 + {-3114, -4677} # 1344 + {-5920, -4753} # 1345 + {-6301, -4556} # 1346 + {-3073, -4672} # 1347 + {-5238, -4657} # 1348 + {-3031, -4672} # 1349 + {-5541, -4675} # 1350 + {-2983, -4679} # 1351 + {-4611, -4719} # 1352 + {-4347, -4672} # 1353 + {-2934, -4692} # 1354 + {-2885, -4712} # 1355 + {-7839, -4512} # 1356 + {-2836, -4736} # 1357 + {-2768, -4775} # 1358 + {-3251, -4659} # 1359 + {-6139, -4668} # 1360 + {-3943, -4811} # 1361 + {-2630, -4861} # 1362 + {-6084, -4701} # 1363 + {-6367, -4516} # 1364 + {-2563, -4899} # 1365 + {-3310, -4699} # 1366 + {-7689, -4546} # 1367 + {-2511, -4924} # 1368 + {-6801, -4548} # 1369 + {-2458, -4943} # 1370 + {-6548, -4471} # 1371 + {-2416, -4931} # 1372 + {-6659, -4495} # 1373 + {-5599, -4692} # 1374 + {-5971, -4745} # 1375 + {-2511, -4848} # 1376 + {-3498, -4839} # 1377 + {-8408, -4321} # 1378 + {-3880, -4840} # 1379 + {-5406, -4650} # 1380 + {-3160, -4614} # 1381 + {-3587, -4878} # 1382 + {-7240, -4604} # 1383 + {-2934, -4617} # 1384 + {-4782, -4746} # 1385 + {-2458, -4867} # 1386 + {-3756, -4882} # 1387 + {-5115, -4684} # 1388 + {-7336, -4597} # 1389 + {-4464, -4682} # 1390 + {-4841, -4745} # 1391 + {-6883, -4572} # 1392 + {-2563, -4823} # 1393 + {-3451, -4808} # 1394 + {-2405, -4878} # 1395 + # Mesh "Mesh.003" + {868, -4128} # 1396 + {-1919, -4607} # 1397 + {2514, -3604} # 1398 + {2998, -3936} # 1399 + {-461, -4430} # 1400 + {-665, -4381} # 1401 + {2334, -3510} # 1402 + {2365, -3576} # 1403 + {2116, -3719} # 1404 + {2286, -3535} # 1405 + {43, -4343} # 1406 + {-1979, -4670} # 1407 + {2917, -3914} # 1408 + {-2310, -4877} # 1409 + {1080, -4152} # 1410 + {-1045, -4051} # 1411 + {-1334, -4013} # 1412 + {2475, -3587} # 1413 + {2863, -3802} # 1414 + {617, -4133} # 1415 + {2334, -3585} # 1416 + {1790, -4084} # 1417 + {428, -4145} # 1418 + {2205, -3606} # 1419 + {504, -4181} # 1420 + {2160, -3735} # 1421 + {-513, -4501} # 1422 + {1298, -4197} # 1423 + {-1182, -3985} # 1424 + {-1263, -3988} # 1425 + {2787, -3820} # 1426 + {2448, -3579} # 1427 + {-2156, -4816} # 1428 + {2310, -3596} # 1429 + {-1581, -4221} # 1430 + {1919, -4050} # 1431 + {1790, -4160} # 1432 + {-622, -4400} # 1433 + {-1455, -4097} # 1434 + {2160, -3660} # 1435 + {1873, -4020} # 1436 + {562, -4154} # 1437 + {1694, -4133} # 1438 + {-2212, -4847} # 1439 + {428, -4220} # 1440 + {2422, -3575} # 1441 + {-702, -4362} # 1442 + {1419, -4192} # 1443 + {2567, -3637} # 1444 + {1521, -4179} # 1445 + {-408, -4507} # 1446 + {-88, -4386} # 1447 + {-356, -4506} # 1448 + {1252, -4194} # 1449 + {2863, -3878} # 1450 + {-303, -4426} # 1451 + {-565, -4492} # 1452 + {1346, -4196} # 1453 + {1832, -4130} # 1454 + {2251, -3637} # 1455 + {-356, -4430} # 1456 + {2286, -3610} # 1457 + {1644, -4226} # 1458 + {1163, -4180} # 1459 + {1521, -4255} # 1460 + {2116, -3795} # 1461 + {-2268, -4868} # 1462 + {-999, -4091} # 1463 + {-2351, -4881} # 1464 + {1163, -4255} # 1465 + {149, -4296} # 1466 + {2448, -3503} # 1467 + {671, -4042} # 1468 + {1028, -4205} # 1469 + {2251, -3561} # 1470 + {868, -4052} # 1471 + {-956, -4134} # 1472 + {1919, -3974} # 1473 + {1965, -3922} # 1474 + {922, -4150} # 1475 + {1873, -4096} # 1476 + {2917, -3838} # 1477 + {-750, -4330} # 1478 + {1121, -4167} # 1479 + {1207, -4189} # 1480 + {2475, -3511} # 1481 + {728, -4109} # 1482 + {1346, -4272} # 1483 + {-861, -4233} # 1484 + {781, -4033} # 1485 + {-2098, -4776} # 1486 + {263, -4312} # 1487 + {43, -4419} # 1488 + {2422, -3499} # 1489 + {-1835, -4513} # 1490 + {-1517, -4155} # 1491 + {1965, -3998} # 1492 + {825, -4116} # 1493 + {1832, -4055} # 1494 + {1694, -4209} # 1495 + {922, -4074} # 1496 + {1419, -4268} # 1497 + {-88, -4462} # 1498 + {2637, -3690} # 1499 + {2567, -3561} # 1500 + {504, -4105} # 1501 + {2365, -3501} # 1502 + {-1130, -3999} # 1503 + {2310, -3521} # 1504 + {-513, -4426} # 1505 + {-1156, -3990} # 1506 + {-142, -4400} # 1507 + {-1394, -4049} # 1508 + {3023, -3888} # 1509 + {781, -4109} # 1510 + {2023, -3848} # 1511 + {-1235, -3983} # 1512 + {2397, -3573} # 1513 + {-1291, -3996} # 1514 + {-565, -4417} # 1515 + {1595, -4164} # 1516 + {263, -4236} # 1517 + {-303, -4501} # 1518 + {2514, -3528} # 1519 + {-1093, -4017} # 1520 + {2787, -3744} # 1521 + {1080, -4228} # 1522 + {1742, -4111} # 1523 + {-798, -4292} # 1524 + {-408, -4432} # 1525 + {-2345, -4947} # 1526 + {1595, -4239} # 1527 + {-2310, -4953} # 1528 + {-1663, -4313} # 1529 + {-2268, -4944} # 1530 + {-2212, -4923} # 1531 + {-142, -4475} # 1532 + {1742, -4187} # 1533 + {-2156, -4892} # 1534 + {-2098, -4852} # 1535 + {1207, -4264} # 1536 + {1121, -4243} # 1537 + {-2039, -4803} # 1538 + {2205, -3682} # 1539 + {-2039, -4727} # 1540 + {-1979, -4746} # 1541 + {-1208, -3982} # 1542 + {-1919, -4683} # 1543 + {-1835, -4589} # 1544 + {1644, -4150} # 1545 + {562, -4079} # 1546 + {-1663, -4388} # 1547 + {2970, -3867} # 1548 + {-1581, -4296} # 1549 + {671, -4118} # 1550 + {728, -4033} # 1551 + {-1517, -4231} # 1552 + {-1455, -4173} # 1553 + {-622, -4476} # 1554 + {-1394, -4125} # 1555 + {-34, -4446} # 1556 + {-1350, -4098} # 1557 + {-1320, -4083} # 1558 + {-1291, -4071} # 1559 + {-1263, -4063} # 1560 + {1298, -4272} # 1561 + {-1235, -4059} # 1562 + {-1208, -4058} # 1563 + {-1182, -4060} # 1564 + {617, -4057} # 1565 + {-1156, -4066} # 1566 + {-1130, -4075} # 1567 + {-1093, -4093} # 1568 + {-222, -4491} # 1569 + {-1045, -4126} # 1570 + {2397, -3498} # 1571 + {-999, -4167} # 1572 + {149, -4372} # 1573 + {1028, -4129} # 1574 + {-956, -4210} # 1575 + {-861, -4309} # 1576 + {2637, -3614} # 1577 + {2023, -3923} # 1578 + {-461, -4506} # 1579 + {825, -4040} # 1580 + {-798, -4368} # 1581 + {1252, -4270} # 1582 + {2946, -3934} # 1583 + {-750, -4406} # 1584 + {-702, -4438} # 1585 + {-222, -4415} # 1586 + {-34, -4370} # 1587 + {-665, -4457} # 1588 + {2975, -3940} # 1589 + {3016, -3921} # 1590 + # Mesh "Plane" + {8378, -1867} # 1591 + {8241, -1852} # 1592 + {8231, -1867} # 1593 + {8304, -1850} # 1594 + {8335, -1851} # 1595 + {8273, -1843} # 1596 + {8330, -1852} # 1597 + {8353, -1836} # 1598 + {8286, -1850} # 1599 + {8247, -1852} # 1600 + {8297, -1844} # 1601 + {8276, -1852} # 1602 + {8356, -1852} # 1603 + {8350, -1851} # 1604 + {8313, -1852} # 1605 + {8332, -1841} # 1606 + {8244, -1843} # 1607 + {8270, -1852} # 1608 + {8236, -1859} # 1609 + {8372, -1857} # 1610 + # Mesh "Plane.001" + {8277, -1902} # 1611 + {8140, -1887} # 1612 + {8130, -1902} # 1613 + {8203, -1885} # 1614 + {8234, -1886} # 1615 + {8172, -1878} # 1616 + {8229, -1887} # 1617 + {8252, -1871} # 1618 + {8185, -1885} # 1619 + {8146, -1887} # 1620 + {8197, -1879} # 1621 + {8175, -1887} # 1622 + {8256, -1887} # 1623 + {8249, -1886} # 1624 + {8212, -1887} # 1625 + {8231, -1876} # 1626 + {8143, -1878} # 1627 + {8169, -1887} # 1628 + {8135, -1894} # 1629 + {8271, -1892} # 1630 + # Mesh "Plane.006" + {8202, -1954} # 1631 + {8066, -1940} # 1632 + {8056, -1954} # 1633 + {8129, -1937} # 1634 + {8160, -1939} # 1635 + {8097, -1931} # 1636 + {8155, -1940} # 1637 + {8178, -1924} # 1638 + {8110, -1937} # 1639 + {8072, -1939} # 1640 + {8122, -1932} # 1641 + {8101, -1939} # 1642 + {8181, -1940} # 1643 + {8174, -1939} # 1644 + {8138, -1939} # 1645 + {8157, -1929} # 1646 + {8068, -1930} # 1647 + {8095, -1939} # 1648 + {8061, -1947} # 1649 + {8196, -1944} # 1650 + # Mesh "Plane.007" + {8071, -1994} # 1651 + {7934, -1979} # 1652 + {7924, -1994} # 1653 + {7997, -1977} # 1654 + {8028, -1978} # 1655 + {7966, -1970} # 1656 + {8023, -1979} # 1657 + {8046, -1963} # 1658 + {7979, -1977} # 1659 + {7940, -1979} # 1660 + {7991, -1971} # 1661 + {7969, -1979} # 1662 + {8050, -1979} # 1663 + {8043, -1978} # 1664 + {8006, -1979} # 1665 + {8025, -1968} # 1666 + {7937, -1970} # 1667 + {7963, -1979} # 1668 + {7929, -1986} # 1669 + {8065, -1984} # 1670 + # Mesh "Plane.008" + {8614, -1556} # 1671 + {8478, -1541} # 1672 + {8467, -1556} # 1673 + {8541, -1539} # 1674 + {8572, -1541} # 1675 + {8509, -1532} # 1676 + {8566, -1542} # 1677 + {8590, -1526} # 1678 + {8522, -1539} # 1679 + {8484, -1541} # 1680 + {8534, -1533} # 1681 + {8513, -1541} # 1682 + {8593, -1541} # 1683 + {8586, -1540} # 1684 + {8549, -1541} # 1685 + {8568, -1530} # 1686 + {8480, -1532} # 1687 + {8507, -1541} # 1688 + {8473, -1549} # 1689 + {8608, -1546} # 1690 + # Mesh "Plane.009" + {8567, -1607} # 1691 + {8430, -1592} # 1692 + {8420, -1607} # 1693 + {8493, -1590} # 1694 + {8524, -1592} # 1695 + {8462, -1583} # 1696 + {8519, -1593} # 1697 + {8542, -1577} # 1698 + {8475, -1590} # 1699 + {8436, -1592} # 1700 + {8486, -1584} # 1701 + {8465, -1592} # 1702 + {8545, -1592} # 1703 + {8539, -1591} # 1704 + {8502, -1592} # 1705 + {8521, -1582} # 1706 + {8433, -1583} # 1707 + {8459, -1592} # 1708 + {8425, -1600} # 1709 + {8561, -1597} # 1710 + # Mesh "Plane.010" + {8528, -1672} # 1711 + {8391, -1657} # 1712 + {8381, -1672} # 1713 + {8454, -1655} # 1714 + {8485, -1657} # 1715 + {8423, -1649} # 1716 + {8480, -1658} # 1717 + {8504, -1642} # 1718 + {8436, -1655} # 1719 + {8397, -1657} # 1720 + {8448, -1650} # 1721 + {8426, -1657} # 1722 + {8507, -1657} # 1723 + {8500, -1657} # 1724 + {8463, -1657} # 1725 + {8482, -1647} # 1726 + {8394, -1648} # 1727 + {8420, -1657} # 1728 + {8386, -1665} # 1729 + {8522, -1662} # 1730 + # Mesh "Plane.011" + {8747, -1466} # 1731 + {8738, -1451} # 1732 + {8611, -1452} # 1733 + {8600, -1466} # 1734 + # Mesh "Plane.012" + {8799, -1414} # 1735 + {8790, -1399} # 1736 + {8662, -1399} # 1737 + {8652, -1414} # 1738 + # Mesh "Plane.013" + {8856, -1363} # 1739 + {8847, -1348} # 1740 + {8719, -1348} # 1741 + {8709, -1363} # 1742 + # Mesh "Plane.014" + {8935, -1315} # 1743 + {8926, -1300} # 1744 + {8799, -1300} # 1745 + {8788, -1315} # 1746 + # Mesh "Plane.015" + {9004, -1261} # 1747 + {8994, -1246} # 1748 + {8867, -1247} # 1749 + {8857, -1261} # 1750 + # Mesh "Plane.016" + {9131, -1160} # 1751 + {9122, -1145} # 1752 + {8995, -1145} # 1753 + {8985, -1160} # 1754 + # Mesh "Plane.017" + {9232, -1107} # 1755 + {9222, -1092} # 1756 + {9095, -1092} # 1757 + {9085, -1107} # 1758 + # Mesh "Plane.018" + {9304, -1057} # 1759 + {9295, -1042} # 1760 + {9168, -1042} # 1761 + {9157, -1057} # 1762 + # Mesh "Plane.019" + {9377, -1016} # 1763 + {9367, -1001} # 1764 + {9240, -1001} # 1765 + {9230, -1016} # 1766 + # Mesh "Plane.020" + {9453, -970} # 1767 + {9444, -955} # 1768 + {9316, -955} # 1769 + {9306, -970} # 1770 + # Mesh "Plane.024" + {8470, -1714} # 1771 + {8333, -1700} # 1772 + {8323, -1714} # 1773 + {8396, -1698} # 1774 + {8427, -1699} # 1775 + {8365, -1691} # 1776 + {8422, -1700} # 1777 + {8445, -1684} # 1778 + {8378, -1698} # 1779 + {8339, -1700} # 1780 + {8390, -1692} # 1781 + {8368, -1700} # 1782 + {8449, -1700} # 1783 + {8442, -1699} # 1784 + {8405, -1700} # 1785 + {8424, -1689} # 1786 + {8336, -1691} # 1787 + {8362, -1699} # 1788 + {8328, -1707} # 1789 + {8464, -1704} # 1790 + # Mesh "Plane.025" + {8458, -1769} # 1791 + {8321, -1754} # 1792 + {8311, -1769} # 1793 + {8384, -1752} # 1794 + {8415, -1754} # 1795 + {8353, -1745} # 1796 + {8410, -1755} # 1797 + {8433, -1739} # 1798 + {8366, -1752} # 1799 + {8327, -1754} # 1800 + {8377, -1747} # 1801 + {8356, -1754} # 1802 + {8436, -1754} # 1803 + {8430, -1754} # 1804 + {8393, -1754} # 1805 + {8412, -1744} # 1806 + {8324, -1745} # 1807 + {8350, -1754} # 1808 + {8316, -1762} # 1809 + {8452, -1759} # 1810 + # Mesh "Plane.026" + {8444, -1818} # 1811 + {8307, -1804} # 1812 + {8297, -1818} # 1813 + {8370, -1802} # 1814 + {8401, -1803} # 1815 + {8338, -1795} # 1816 + {8396, -1804} # 1817 + {8419, -1788} # 1818 + {8352, -1802} # 1819 + {8313, -1804} # 1820 + {8363, -1796} # 1821 + {8342, -1804} # 1822 + {8422, -1804} # 1823 + {8416, -1803} # 1824 + {8379, -1803} # 1825 + {8398, -1793} # 1826 + {8310, -1795} # 1827 + {8336, -1803} # 1828 + {8302, -1811} # 1829 + {8437, -1808} # 1830 + # Mesh "Plane.028" + {9061, -1202} # 1831 + {9052, -1187} # 1832 + {8924, -1188} # 1833 + {8914, -1202} # 1834 + # Mesh "Plane.029" + {9000, -1542} # 1835 + {9018, -1495} # 1836 + {8998, -1032} # 1837 + {8974, -1545} # 1838 + # Mesh "Plane.030" + {8880, -1727} # 1839 + {8912, -1645} # 1840 + {8877, -845} # 1841 + {8835, -1732} # 1842 + # Mesh "Plane.031" + {8709, -1921} # 1843 + {8728, -1873} # 1844 + {8708, -1411} # 1845 + {8683, -1924} # 1846 + # Mesh "Plane.034" + {9208, -1334} # 1847 + {9226, -1286} # 1848 + {9206, -824} # 1849 + {9182, -1337} # 1850 + # Mesh "Plane.035" + {8757, -1826} # 1851 + {8775, -1778} # 1852 + {8755, -1316} # 1853 + {8731, -1829} # 1854 + # Mesh "Plane.036" + {8810, -1772} # 1855 + {8832, -1714} # 1856 + {8808, -1154} # 1857 + {8778, -1775} # 1858 + # Mesh "Plane.037" + {8947, -1592} # 1859 + {8965, -1545} # 1860 + {8945, -1082} # 1861 + {8921, -1595} # 1862 + # Mesh "Plane.038" + {9053, -1464} # 1863 + {9071, -1417} # 1864 + {9051, -954} # 1865 + {9027, -1467} # 1866 + # Mesh "Plane.039" + {9126, -1399} # 1867 + {9144, -1351} # 1868 + {9124, -888} # 1869 + {9100, -1402} # 1870 + # Mesh "Plane.040" + {8662, -1503} # 1871 + {8525, -1488} # 1872 + {8515, -1503} # 1873 + {8588, -1486} # 1874 + {8619, -1488} # 1875 + {8557, -1479} # 1876 + {8614, -1489} # 1877 + {8637, -1473} # 1878 + {8570, -1486} # 1879 + {8531, -1488} # 1880 + {8582, -1481} # 1881 + {8560, -1488} # 1882 + {8640, -1488} # 1883 + {8634, -1488} # 1884 + {8597, -1488} # 1885 + {8616, -1478} # 1886 + {8528, -1479} # 1887 + {8554, -1488} # 1888 + {8520, -1496} # 1889 + {8656, -1493} # 1890 + # Mesh "Font" + {-4141, -4926} # 1891 + {-4152, -4925} # 1892 + {-4161, -4921} # 1893 + {-4169, -4915} # 1894 + {-4175, -4907} # 1895 + {-4179, -4898} # 1896 + {-4180, -4888} # 1897 + {-4179, -4877} # 1898 + {-4175, -4868} # 1899 + {-4169, -4860} # 1900 + {-4161, -4854} # 1901 + {-4152, -4850} # 1902 + {-4141, -4848} # 1903 + {-4130, -4850} # 1904 + {-4120, -4853} # 1905 + {-4112, -4859} # 1906 + {-4106, -4867} # 1907 + {-4102, -4877} # 1908 + {-4101, -4888} # 1909 + {-4102, -4898} # 1910 + {-4106, -4908} # 1911 + {-4112, -4915} # 1912 + {-4120, -4921} # 1913 + {-4130, -4925} # 1914 + {-4141, -4913} # 1915 + {-4134, -4912} # 1916 + {-4128, -4909} # 1917 + {-4123, -4906} # 1918 + {-4119, -4901} # 1919 + {-4117, -4895} # 1920 + {-4116, -4888} # 1921 + {-4117, -4880} # 1922 + {-4119, -4874} # 1923 + {-4123, -4869} # 1924 + {-4128, -4865} # 1925 + {-4134, -4863} # 1926 + {-4141, -4862} # 1927 + {-4148, -4863} # 1928 + {-4154, -4865} # 1929 + {-4158, -4869} # 1930 + {-4162, -4874} # 1931 + {-4164, -4881} # 1932 + {-4165, -4888} # 1933 + {-4164, -4895} # 1934 + {-4162, -4901} # 1935 + {-4158, -4906} # 1936 + {-4154, -4909} # 1937 + {-4148, -4912} # 1938 + {-4525, -4964} # 1939 + {-4537, -4964} # 1940 + {-4585, -4850} # 1941 + {-4569, -4850} # 1942 + {-4555, -4883} # 1943 + {-4507, -4883} # 1944 + {-4491, -4850} # 1945 + {-4475, -4850} # 1946 + {-4531, -4939} # 1947 + {-4513, -4898} # 1948 + {-4548, -4898} # 1949 + {-4449, -4963} # 1950 + {-4464, -4963} # 1951 + {-4467, -4850} # 1952 + {-4451, -4849} # 1953 + {-4413, -4963} # 1954 + {-4428, -4963} # 1955 + {-4426, -4849} # 1956 + {-4410, -4851} # 1957 + {-4330, -4872} # 1958 + {-4334, -4869} # 1959 + {-4338, -4867} # 1960 + {-4342, -4865} # 1961 + {-4347, -4864} # 1962 + {-4351, -4863} # 1963 + {-4356, -4863} # 1964 + {-4362, -4863} # 1965 + {-4368, -4865} # 1966 + {-4373, -4868} # 1967 + {-4376, -4873} # 1968 + {-4379, -4878} # 1969 + {-4381, -4885} # 1970 + {-4328, -4885} # 1971 + {-4329, -4898} # 1972 + {-4332, -4908} # 1973 + {-4337, -4916} # 1974 + {-4343, -4921} # 1975 + {-4351, -4925} # 1976 + {-4361, -4926} # 1977 + {-4370, -4925} # 1978 + {-4379, -4921} # 1979 + {-4386, -4915} # 1980 + {-4391, -4908} # 1981 + {-4394, -4899} # 1982 + {-4395, -4888} # 1983 + {-4394, -4878} # 1984 + {-4391, -4869} # 1985 + {-4386, -4861} # 1986 + {-4379, -4854} # 1987 + {-4370, -4850} # 1988 + {-4359, -4848} # 1989 + {-4353, -4849} # 1990 + {-4348, -4849} # 1991 + {-4343, -4851} # 1992 + {-4338, -4852} # 1993 + {-4334, -4855} # 1994 + {-4330, -4857} # 1995 + {-4380, -4895} # 1996 + {-4379, -4900} # 1997 + {-4377, -4905} # 1998 + {-4374, -4908} # 1999 + {-4370, -4911} # 2000 + {-4365, -4913} # 2001 + {-4360, -4913} # 2002 + {-4355, -4913} # 2003 + {-4351, -4911} # 2004 + {-4348, -4908} # 2005 + {-4345, -4905} # 2006 + {-4344, -4900} # 2007 + {-4343, -4895} # 2008 + {-4253, -4924} # 2009 + {-4284, -4924} # 2010 + {-4293, -4924} # 2011 + {-4301, -4921} # 2012 + {-4307, -4918} # 2013 + {-4312, -4912} # 2014 + {-4315, -4906} # 2015 + {-4316, -4899} # 2016 + {-4316, -4896} # 2017 + {-4316, -4894} # 2018 + {-4315, -4891} # 2019 + {-4314, -4889} # 2020 + {-4313, -4887} # 2021 + {-4312, -4885} # 2022 + {-4311, -4883} # 2023 + {-4309, -4881} # 2024 + {-4307, -4879} # 2025 + {-4305, -4878} # 2026 + {-4302, -4877} # 2027 + {-4300, -4875} # 2028 + {-4300, -4875} # 2029 + {-4303, -4874} # 2030 + {-4306, -4873} # 2031 + {-4308, -4871} # 2032 + {-4310, -4869} # 2033 + {-4311, -4867} # 2034 + {-4311, -4864} # 2035 + {-4311, -4863} # 2036 + {-4311, -4861} # 2037 + {-4310, -4860} # 2038 + {-4308, -4858} # 2039 + {-4306, -4856} # 2040 + {-4304, -4855} # 2041 + {-4310, -4853} # 2042 + {-4315, -4851} # 2043 + {-4318, -4848} # 2044 + {-4321, -4844} # 2045 + {-4322, -4839} # 2046 + {-4323, -4834} # 2047 + {-4322, -4828} # 2048 + {-4318, -4823} # 2049 + {-4313, -4818} # 2050 + {-4306, -4815} # 2051 + {-4298, -4813} # 2052 + {-4288, -4812} # 2053 + {-4278, -4813} # 2054 + {-4269, -4815} # 2055 + {-4263, -4818} # 2056 + {-4257, -4823} # 2057 + {-4254, -4829} # 2058 + {-4253, -4836} # 2059 + {-4254, -4840} # 2060 + {-4255, -4844} # 2061 + {-4258, -4848} # 2062 + {-4262, -4852} # 2063 + {-4268, -4854} # 2064 + {-4275, -4856} # 2065 + {-4282, -4858} # 2066 + {-4287, -4859} # 2067 + {-4292, -4861} # 2068 + {-4295, -4862} # 2069 + {-4297, -4864} # 2070 + {-4298, -4866} # 2071 + {-4296, -4869} # 2072 + {-4292, -4871} # 2073 + {-4286, -4872} # 2074 + {-4280, -4874} # 2075 + {-4273, -4876} # 2076 + {-4267, -4880} # 2077 + {-4266, -4882} # 2078 + {-4264, -4884} # 2079 + {-4263, -4887} # 2080 + {-4261, -4890} # 2081 + {-4261, -4894} # 2082 + {-4260, -4897} # 2083 + {-4261, -4900} # 2084 + {-4261, -4902} # 2085 + {-4262, -4905} # 2086 + {-4264, -4908} # 2087 + {-4266, -4910} # 2088 + {-4268, -4913} # 2089 + {-4253, -4913} # 2090 + {-4274, -4899} # 2091 + {-4274, -4895} # 2092 + {-4275, -4891} # 2093 + {-4278, -4889} # 2094 + {-4281, -4886} # 2095 + {-4284, -4885} # 2096 + {-4288, -4885} # 2097 + {-4292, -4885} # 2098 + {-4296, -4886} # 2099 + {-4299, -4888} # 2100 + {-4301, -4891} # 2101 + {-4302, -4894} # 2102 + {-4303, -4898} # 2103 + {-4302, -4902} # 2104 + {-4301, -4905} # 2105 + {-4299, -4908} # 2106 + {-4296, -4910} # 2107 + {-4292, -4911} # 2108 + {-4288, -4912} # 2109 + {-4284, -4911} # 2110 + {-4281, -4910} # 2111 + {-4278, -4908} # 2112 + {-4276, -4905} # 2113 + {-4274, -4902} # 2114 + {-4268, -4834} # 2115 + {-4268, -4831} # 2116 + {-4270, -4829} # 2117 + {-4273, -4826} # 2118 + {-4277, -4825} # 2119 + {-4282, -4824} # 2120 + {-4288, -4824} # 2121 + {-4294, -4824} # 2122 + {-4299, -4825} # 2123 + {-4303, -4826} # 2124 + {-4306, -4829} # 2125 + {-4308, -4832} # 2126 + {-4309, -4835} # 2127 + {-4308, -4838} # 2128 + {-4307, -4841} # 2129 + {-4304, -4843} # 2130 + {-4301, -4845} # 2131 + {-4297, -4846} # 2132 + {-4292, -4846} # 2133 + {-4287, -4846} # 2134 + {-4282, -4845} # 2135 + {-4276, -4844} # 2136 + {-4272, -4842} # 2137 + {-4269, -4839} # 2138 + {-4240, -4924} # 2139 + {-4240, -4850} # 2140 + {-4226, -4850} # 2141 + {-4226, -4889} # 2142 + {-4225, -4895} # 2143 + {-4223, -4901} # 2144 + {-4220, -4905} # 2145 + {-4217, -4909} # 2146 + {-4212, -4911} # 2147 + {-4208, -4912} # 2148 + {-4206, -4912} # 2149 + {-4203, -4911} # 2150 + {-4201, -4910} # 2151 + {-4199, -4908} # 2152 + {-4196, -4907} # 2153 + {-4194, -4905} # 2154 + {-4186, -4917} # 2155 + {-4189, -4920} # 2156 + {-4192, -4922} # 2157 + {-4195, -4924} # 2158 + {-4198, -4925} # 2159 + {-4201, -4926} # 2160 + {-4204, -4926} # 2161 + {-4207, -4925} # 2162 + {-4211, -4924} # 2163 + {-4214, -4922} # 2164 + {-4218, -4918} # 2165 + {-4222, -4913} # 2166 + {-4225, -4907} # 2167 + {-4226, -4907} # 2168 + {-4226, -4924} # 2169 + # Mesh "Circle" + {7703, -2077} # 2170 + {7767, -2028} # 2171 + {7835, -2021} # 2172 + {7872, -2000} # 2173 + {7488, -2074} # 2174 + {7217, -2113} # 2175 + {6700, -2274} # 2176 + {7084, -2173} # 2177 + {7632, -1970} # 2178 + {7535, -2025} # 2179 + {7436, -2011} # 2180 + {7309, -2075} # 2181 + {7188, -2063} # 2182 + {7545, -2112} # 2183 + {6942, -2199} # 2184 + {6832, -2240} # 2185 + {7048, -2236} # 2186 + {6659, -2269} # 2187 + {7457, -2056} # 2188 + {6496, -2375} # 2189 + {7760, -1976} # 2190 + {7126, -2226} # 2191 + {7200, -2198} # 2192 + {7440, -2137} # 2193 + {6694, -2184} # 2194 + {6906, -2254} # 2195 + {7337, -2099} # 2196 + {7795, -2004} # 2197 + {7255, -2195} # 2198 + {7380, -2164} # 2199 + {7494, -2134} # 2200 + {7590, -2105} # 2201 + {7252, -2133} # 2202 + {7134, -2159} # 2203 + {7695, -2032} # 2204 + {6637, -2324} # 2205 + {7863, -1994} # 2206 + {7373, -2103} # 2207 + {7722, -2026} # 2208 + {7666, -2023} # 2209 + {7647, -2084} # 2210 + {6852, -2283} # 2211 + {6970, -2261} # 2212 + {6763, -2301} # 2213 + {7322, -2173} # 2214 + {6983, -2195} # 2215 + {6899, -2127} # 2216 + {6762, -2262} # 2217 + {7589, -2046} # 2218 + {7559, -2046} # 2219 + {6726, -2237} # 2220 + {6617, -2309} # 2221 + {7037, -2140} # 2222 + {6496, -2373} # 2223 +} + +# Triangles +{ + # Mesh "Curve" + { + {1, 2, "edge" "collidable"}, + {0, 2, "edge" "collidable"}, + {40, 2}, + 1 + } + { + {40, 2, "edge" "collidable"}, + {41, 2}, + {1, 2}, + 1 + } + { + {2, 2, "edge" "collidable"}, + {1, 2}, + {41, 2}, + 1 + } + { + {41, 2, "edge" "collidable"}, + {42, 2}, + {2, 2}, + 1 + } + { + {3, 2, "edge" "collidable"}, + {2, 2}, + {42, 2}, + 1 + } + { + {42, 2, "edge" "collidable"}, + {43, 2}, + {3, 2}, + 1 + } + { + {4, 2, "edge" "collidable"}, + {3, 2}, + {43, 2}, + 1 + } + { + {43, 2, "edge" "collidable"}, + {44, 2}, + {4, 2}, + 1 + } + { + {5, 2, "edge" "collidable"}, + {4, 2}, + {44, 2}, + 1 + } + { + {44, 2, "edge" "collidable"}, + {45, 2}, + {5, 2}, + 1 + } + { + {6, 2, "edge" "collidable"}, + {5, 2}, + {45, 2}, + 1 + } + { + {45, 2, "edge" "collidable"}, + {46, 2}, + {6, 2}, + 1 + } + { + {7, 2, "edge" "collidable"}, + {6, 2}, + {46, 2}, + 1 + } + { + {46, 2, "edge" "collidable"}, + {47, 2}, + {7, 2}, + 1 + } + { + {8, 2, "edge" "collidable"}, + {7, 2}, + {47, 2}, + 1 + } + { + {47, 2, "edge" "collidable"}, + {48, 2}, + {8, 2}, + 1 + } + { + {9, 2, "edge" "collidable"}, + {8, 2}, + {48, 2}, + 1 + } + { + {48, 2, "edge" "collidable"}, + {49, 2}, + {9, 2}, + 1 + } + { + {10, 2, "edge" "collidable"}, + {9, 2}, + {49, 2}, + 1 + } + { + {49, 2, "edge" "collidable"}, + {50, 2}, + {10, 2}, + 1 + } + { + {11, 2, "edge" "collidable"}, + {10, 2}, + {50, 2}, + 1 + } + { + {50, 2, "edge" "collidable"}, + {51, 2}, + {11, 2}, + 1 + } + { + {12, 2, "edge" "collidable"}, + {11, 2}, + {51, 2}, + 1 + } + { + {51, 2, "edge" "collidable"}, + {52, 2}, + {12, 2}, + 1 + } + { + {13, 2, "edge" "collidable"}, + {12, 2}, + {52, 2}, + 1 + } + { + {52, 2, "edge" "collidable"}, + {53, 2}, + {13, 2}, + 1 + } + { + {14, 2, "edge" "collidable"}, + {13, 2}, + {53, 2}, + 1 + } + { + {53, 2, "edge" "collidable"}, + {54, 2}, + {14, 2}, + 1 + } + { + {15, 2, "edge" "collidable"}, + {14, 2}, + {54, 2}, + 1 + } + { + {54, 2, "edge" "collidable"}, + {55, 2}, + {15, 2}, + 1 + } + { + {16, 2, "edge" "collidable"}, + {15, 2}, + {55, 2}, + 1 + } + { + {55, 2, "edge" "collidable"}, + {56, 2}, + {16, 2}, + 1 + } + { + {17, 2, "edge" "collidable"}, + {16, 2}, + {56, 2}, + 1 + } + { + {56, 2, "edge" "collidable"}, + {57, 2}, + {17, 2}, + 1 + } + { + {18, 2, "edge" "collidable"}, + {17, 2}, + {57, 2}, + 1 + } + { + {57, 2, "edge" "collidable"}, + {58, 2}, + {18, 2}, + 1 + } + { + {19, 2, "edge" "collidable"}, + {18, 2}, + {58, 2}, + 1 + } + { + {58, 2, "edge" "collidable"}, + {59, 2}, + {19, 2}, + 1 + } + { + {20, 2, "edge" "collidable"}, + {19, 2}, + {59, 2}, + 1 + } + { + {59, 2, "edge" "collidable"}, + {60, 2}, + {20, 2}, + 1 + } + { + {21, 2, "edge" "collidable"}, + {20, 2}, + {60, 2}, + 1 + } + { + {60, 2, "edge" "collidable"}, + {61, 2}, + {21, 2}, + 1 + } + { + {22, 2, "edge" "collidable"}, + {21, 2}, + {61, 2}, + 1 + } + { + {61, 2, "edge" "collidable"}, + {62, 2}, + {22, 2}, + 1 + } + { + {23, 2, "edge" "collidable"}, + {22, 2}, + {62, 2}, + 1 + } + { + {62, 2, "edge" "collidable"}, + {63, 2}, + {23, 2}, + 1 + } + { + {24, 2, "edge" "collidable"}, + {23, 2}, + {63, 2}, + 1 + } + { + {63, 2, "edge" "collidable"}, + {64, 2}, + {24, 2}, + 1 + } + { + {25, 2, "edge" "collidable"}, + {24, 2}, + {64, 2}, + 1 + } + { + {64, 2, "edge" "collidable"}, + {65, 2}, + {25, 2}, + 1 + } + { + {26, 2, "edge" "collidable"}, + {25, 2}, + {65, 2}, + 1 + } + { + {65, 2, "edge" "collidable"}, + {66, 2}, + {26, 2}, + 1 + } + { + {27, 2, "edge" "collidable"}, + {26, 2}, + {66, 2}, + 1 + } + { + {66, 2, "edge" "collidable"}, + {67, 2}, + {27, 2}, + 1 + } + { + {28, 2, "edge" "collidable"}, + {27, 2}, + {67, 2}, + 1 + } + { + {67, 2, "edge" "collidable"}, + {68, 2}, + {28, 2}, + 1 + } + { + {29, 2, "edge" "collidable"}, + {28, 2}, + {68, 2}, + 1 + } + { + {68, 2, "edge" "collidable"}, + {69, 2}, + {29, 2}, + 1 + } + { + {30, 2, "edge" "collidable"}, + {29, 2}, + {69, 2}, + 1 + } + { + {69, 2, "edge" "collidable"}, + {70, 2}, + {30, 2}, + 1 + } + { + {31, 2, "edge" "collidable"}, + {30, 2}, + {70, 2}, + 1 + } + { + {70, 2, "edge" "collidable"}, + {71, 2}, + {31, 2}, + 1 + } + { + {32, 2, "edge" "collidable"}, + {31, 2}, + {71, 2}, + 1 + } + { + {71, 2, "edge" "collidable"}, + {72, 2}, + {32, 2}, + 1 + } + { + {33, 2, "edge" "collidable"}, + {32, 2}, + {72, 2}, + 1 + } + { + {72, 2, "edge" "collidable"}, + {73, 2}, + {33, 2}, + 1 + } + { + {34, 2, "edge" "collidable"}, + {33, 2}, + {73, 2}, + 1 + } + { + {73, 2, "edge" "collidable"}, + {74, 2}, + {34, 2}, + 1 + } + { + {35, 2, "edge" "collidable"}, + {34, 2}, + {74, 2}, + 1 + } + { + {74, 2, "edge" "collidable"}, + {75, 2}, + {35, 2}, + 1 + } + { + {36, 2, "edge" "collidable"}, + {35, 2}, + {75, 2}, + 1 + } + { + {75, 2, "edge" "collidable"}, + {76, 2}, + {36, 2}, + 1 + } + { + {37, 2, "edge" "collidable"}, + {36, 2}, + {76, 2}, + 1 + } + { + {76, 2, "edge" "collidable"}, + {77, 2}, + {37, 2}, + 1 + } + { + {38, 2, "edge" "collidable"}, + {37, 2}, + {77, 2}, + 1 + } + { + {77, 2, "edge" "collidable"}, + {78, 2}, + {38, 2}, + 1 + } + { + {39, 2, "edge" "collidable"}, + {38, 2}, + {78, 2}, + 1 + } + { + {78, 2, "edge" "collidable"}, + {79, 2, "edge" "collidable"}, + {39, 2}, + 1 + } + # Mesh "Curve.001" + { + {560, 2}, + {526, 2, "edge" "collidable"}, + {278, 2}, + 0 + } + { + {456, 2}, + {468, 2}, + {81, 2}, + 0 + } + { + {468, 2}, + {80, 2, "edge" "collidable"}, + {81, 2}, + 0 + } + { + {347, 2}, + {548, 2}, + {115, 2}, + 0 + } + { + {232, 2}, + {121, 2}, + {600, 2}, + 0 + } + { + {401, 2}, + {456, 2}, + {83, 2}, + 0 + } + { + {456, 2}, + {81, 2, "edge" "collidable"}, + {83, 2}, + 0 + } + { + {592, 2}, + {127, 2}, + {353, 2}, + 0 + } + { + {522, 2}, + {514, 2}, + {428, 2}, + 0 + } + { + {361, 2}, + {401, 2}, + {85, 2}, + 0 + } + { + {401, 2}, + {83, 2, "edge" "collidable"}, + {85, 2}, + 0 + } + { + {305, 2}, + {361, 2}, + {85, 2}, + 0 + } + { + {519, 2}, + {304, 2, "edge" "collidable"}, + {500, 2}, + 0 + } + { + {144, 2}, + {305, 2}, + {87, 2}, + 0 + } + { + {305, 2}, + {85, 2, "edge" "collidable"}, + {87, 2}, + 0 + } + { + {242, 2}, + {144, 2}, + {88, 2}, + 0 + } + { + {144, 2}, + {87, 2, "edge" "collidable"}, + {88, 2}, + 0 + } + { + {136, 2}, + {242, 2}, + {89, 2}, + 0 + } + { + {242, 2}, + {88, 2, "edge" "collidable"}, + {89, 2}, + 0 + } + { + {228, 2}, + {136, 2}, + {90, 2}, + 0 + } + { + {136, 2}, + {89, 2, "edge" "collidable"}, + {90, 2}, + 0 + } + { + {171, 2}, + {228, 2}, + {90, 2}, + 0 + } + { + {183, 2}, + {82, 2, "edge" "collidable"}, + {589, 2}, + 0 + } + { + {494, 2}, + {171, 2}, + {92, 2}, + 0 + } + { + {171, 2}, + {90, 2, "edge" "collidable"}, + {92, 2}, + 0 + } + { + {266, 2}, + {261, 2, "edge" "collidable"}, + {225, 2}, + 0 + } + { + {381, 2}, + {592, 2}, + {445, 2}, + 0 + } + { + {576, 2}, + {494, 2}, + {94, 2}, + 0 + } + { + {494, 2}, + {92, 2, "edge" "collidable"}, + {94, 2}, + 0 + } + { + {202, 2}, + {553, 2}, + {93, 2}, + 0 + } + { + {274, 2}, + {362, 2, "edge" "collidable"}, + {364, 2}, + 0 + } + { + {342, 2}, + {512, 2, "edge" "collidable"}, + {516, 2}, + 0 + } + { + {539, 2}, + {293, 2}, + {480, 2}, + 0 + } + { + {440, 2}, + {179, 2, "edge" "collidable"}, + {380, 2}, + 0 + } + { + {341, 2}, + {119, 2, "edge" "collidable"}, + {427, 2}, + 0 + } + { + {191, 2}, + {376, 2, "edge" "collidable"}, + {230, 2}, + 0 + } + { + {590, 2}, + {382, 2, "edge" "collidable"}, + {82, 2}, + 0 + } + { + {629, 2}, + {576, 2}, + {99, 2}, + 0 + } + { + {576, 2}, + {94, 2, "edge" "collidable"}, + {99, 2}, + 0 + } + { + {519, 2}, + {324, 2}, + {304, 2}, + 0 + } + { + {341, 2}, + {497, 2}, + {119, 2}, + 0 + } + { + {489, 2}, + {465, 2, "edge" "collidable"}, + {467, 2}, + 0 + } + { + {336, 2}, + {188, 2, "edge" "collidable"}, + {613, 2}, + 0 + } + { + {104, 2}, + {411, 2}, + {534, 2}, + 0 + } + { + {169, 2}, + {503, 2}, + {167, 2}, + 0 + } + { + {106, 2}, + {629, 2}, + {103, 2}, + 0 + } + { + {629, 2}, + {99, 2, "edge" "collidable"}, + {103, 2}, + 0 + } + { + {177, 2}, + {607, 2}, + {573, 2}, + 0 + } + { + {618, 2}, + {367, 2}, + {619, 2}, + 0 + } + { + {409, 2}, + {106, 2}, + {105, 2}, + 0 + } + { + {106, 2}, + {103, 2, "edge" "collidable"}, + {105, 2}, + 0 + } + { + {160, 2}, + {377, 2}, + {505, 2}, + 0 + } + { + {318, 2}, + {194, 2, "edge" "collidable"}, + {282, 2}, + 0 + } + { + {444, 2}, + {409, 2}, + {107, 2}, + 0 + } + { + {409, 2}, + {105, 2, "edge" "collidable"}, + {107, 2}, + 0 + } + { + {477, 2}, + {489, 2}, + {467, 2}, + 0 + } + { + {560, 2}, + {271, 2}, + {526, 2}, + 0 + } + { + {309, 2}, + {444, 2}, + {109, 2}, + 0 + } + { + {444, 2}, + {107, 2, "edge" "collidable"}, + {109, 2}, + 0 + } + { + {176, 2}, + {434, 2, "edge" "collidable"}, + {442, 2}, + 0 + } + { + {224, 2}, + {211, 2, "edge" "collidable"}, + {139, 2}, + 0 + } + { + {419, 2}, + {309, 2}, + {111, 2}, + 0 + } + { + {309, 2}, + {109, 2, "edge" "collidable"}, + {111, 2}, + 0 + } + { + {440, 2}, + {195, 2}, + {179, 2}, + 0 + } + { + {223, 2}, + {403, 2, "edge" "collidable"}, + {407, 2}, + 0 + } + { + {436, 2}, + {419, 2}, + {113, 2}, + 0 + } + { + {419, 2}, + {111, 2, "edge" "collidable"}, + {113, 2}, + 0 + } + { + {384, 2}, + {436, 2}, + {114, 2}, + 0 + } + { + {436, 2}, + {113, 2, "edge" "collidable"}, + {114, 2}, + 0 + } + { + {288, 2}, + {322, 2}, + {204, 2}, + 0 + } + { + {100, 2}, + {521, 2}, + {328, 2}, + 0 + } + { + {371, 2}, + {384, 2}, + {116, 2}, + 0 + } + { + {384, 2}, + {114, 2, "edge" "collidable"}, + {116, 2}, + 0 + } + { + {547, 2}, + {442, 2, "edge" "collidable"}, + {451, 2}, + 0 + } + { + {238, 2}, + {364, 2, "edge" "collidable"}, + {366, 2}, + 0 + } + { + {297, 2}, + {371, 2}, + {118, 2}, + 0 + } + { + {371, 2}, + {116, 2, "edge" "collidable"}, + {118, 2}, + 0 + } + { + {293, 2}, + {476, 2, "edge" "collidable"}, + {480, 2}, + 0 + } + { + {232, 2}, + {600, 2, "edge" "collidable"}, + {604, 2}, + 0 + } + { + {518, 2}, + {297, 2}, + {120, 2}, + 0 + } + { + {297, 2}, + {118, 2, "edge" "collidable"}, + {120, 2}, + 0 + } + { + {187, 2}, + {546, 2, "edge" "collidable"}, + {551, 2}, + 0 + } + { + {238, 2}, + {274, 2}, + {364, 2}, + 0 + } + { + {607, 2}, + {570, 2, "edge" "collidable"}, + {573, 2}, + 0 + } + { + {326, 2}, + {283, 2}, + {391, 2}, + 0 + } + { + {580, 2}, + {591, 2, "edge" "collidable"}, + {595, 2}, + 0 + } + { + {417, 2}, + {172, 2}, + {220, 2}, + 0 + } + { + {330, 2}, + {518, 2}, + {124, 2}, + 0 + } + { + {518, 2}, + {120, 2, "edge" "collidable"}, + {124, 2}, + 0 + } + { + {121, 2}, + {595, 2, "edge" "collidable"}, + {600, 2}, + 0 + } + { + {437, 2}, + {545, 2}, + {296, 2}, + 0 + } + { + {389, 2}, + {542, 2, "edge" "collidable"}, + {546, 2}, + 0 + } + { + {396, 2}, + {413, 2}, + {321, 2}, + 0 + } + { + {233, 2}, + {237, 2, "edge" "collidable"}, + {471, 2}, + 0 + } + { + {224, 2}, + {139, 2}, + {334, 2}, + 0 + } + { + {142, 2}, + {330, 2}, + {128, 2}, + 0 + } + { + {330, 2}, + {124, 2, "edge" "collidable"}, + {128, 2}, + 0 + } + { + {195, 2}, + {151, 2, "edge" "collidable"}, + {179, 2}, + 0 + } + { + {292, 2}, + {157, 2}, + {609, 2}, + 0 + } + { + {531, 2}, + {244, 2, "edge" "collidable"}, + {483, 2}, + 0 + } + { + {172, 2}, + {225, 2, "edge" "collidable"}, + {220, 2}, + 0 + } + { + {102, 2}, + {342, 2}, + {516, 2}, + 0 + } + { + {187, 2}, + {389, 2}, + {546, 2}, + 0 + } + { + {349, 2}, + {481, 2}, + {527, 2}, + 0 + } + { + {402, 2}, + {450, 2}, + {258, 2}, + 0 + } + { + {574, 2}, + {142, 2}, + {133, 2}, + 0 + } + { + {142, 2}, + {128, 2, "edge" "collidable"}, + {133, 2}, + 0 + } + { + {515, 2}, + {618, 2}, + {621, 2}, + 0 + } + { + {521, 2}, + {372, 2, "edge" "collidable"}, + {328, 2}, + 0 + } + { + {192, 2}, + {487, 2}, + {568, 2}, + 0 + } + { + {292, 2}, + {609, 2, "edge" "collidable"}, + {596, 2}, + 0 + } + { + {163, 2}, + {493, 2}, + {608, 2}, + 0 + } + { + {571, 2}, + {574, 2}, + {137, 2}, + 0 + } + { + {574, 2}, + {133, 2, "edge" "collidable"}, + {137, 2}, + 0 + } + { + {561, 2}, + {623, 2, "edge" "collidable"}, + {627, 2}, + 0 + } + { + {522, 2}, + {428, 2, "edge" "collidable"}, + {434, 2}, + 0 + } + { + {346, 2}, + {571, 2}, + {137, 2}, + 0 + } + { + {271, 2}, + {101, 2}, + {572, 2}, + 0 + } + { + {264, 2}, + {617, 2, "edge" "collidable"}, + {564, 2}, + 0 + } + { + {628, 2}, + {223, 2}, + {407, 2}, + 0 + } + { + {363, 2}, + {346, 2}, + {141, 2}, + 0 + } + { + {346, 2}, + {137, 2, "edge" "collidable"}, + {141, 2}, + 0 + } + { + {322, 2}, + {427, 2, "edge" "collidable"}, + {204, 2}, + 0 + } + { + {481, 2}, + {533, 2}, + {524, 2}, + 0 + } + { + {463, 2}, + {363, 2}, + {143, 2}, + 0 + } + { + {363, 2}, + {141, 2, "edge" "collidable"}, + {143, 2}, + 0 + } + { + {487, 2}, + {566, 2, "edge" "collidable"}, + {568, 2}, + 0 + } + { + {306, 2}, + {216, 2, "edge" "collidable"}, + {313, 2}, + 0 + } + { + {620, 2}, + {463, 2}, + {145, 2}, + 0 + } + { + {463, 2}, + {143, 2, "edge" "collidable"}, + {145, 2}, + 0 + } + { + {122, 2}, + {318, 2}, + {282, 2}, + 0 + } + { + {497, 2}, + {483, 2, "edge" "collidable"}, + {119, 2}, + 0 + } + { + {97, 2}, + {551, 2, "edge" "collidable"}, + {555, 2}, + 0 + } + { + {521, 2}, + {153, 2}, + {372, 2}, + 0 + } + { + {248, 2}, + {620, 2}, + {148, 2}, + 0 + } + { + {620, 2}, + {145, 2, "edge" "collidable"}, + {148, 2}, + 0 + } + { + {108, 2}, + {547, 2}, + {451, 2}, + 0 + } + { + {355, 2}, + {381, 2}, + {189, 2}, + 0 + } + { + {246, 2}, + {248, 2}, + {150, 2}, + 0 + } + { + {248, 2}, + {148, 2, "edge" "collidable"}, + {150, 2}, + 0 + } + { + {489, 2}, + {482, 2}, + {465, 2}, + 0 + } + { + {418, 2}, + {433, 2, "edge" "collidable"}, + {461, 2}, + 0 + } + { + {317, 2}, + {246, 2}, + {152, 2}, + 0 + } + { + {246, 2}, + {150, 2, "edge" "collidable"}, + {152, 2}, + 0 + } + { + {470, 2}, + {314, 2, "edge" "collidable"}, + {405, 2}, + 0 + } + { + {160, 2}, + {505, 2, "edge" "collidable"}, + {512, 2}, + 0 + } + { + {563, 2}, + {317, 2}, + {154, 2}, + 0 + } + { + {317, 2}, + {152, 2, "edge" "collidable"}, + {154, 2}, + 0 + } + { + {481, 2}, + {524, 2, "edge" "collidable"}, + {527, 2}, + 0 + } + { + {475, 2}, + {310, 2}, + {562, 2}, + 0 + } + { + {569, 2}, + {563, 2}, + {156, 2}, + 0 + } + { + {563, 2}, + {154, 2, "edge" "collidable"}, + {156, 2}, + 0 + } + { + {601, 2}, + {631, 2, "edge" "collidable"}, + {447, 2}, + 0 + } + { + {388, 2}, + {554, 2}, + {495, 2}, + 0 + } + { + {206, 2}, + {569, 2}, + {158, 2}, + 0 + } + { + {569, 2}, + {156, 2, "edge" "collidable"}, + {158, 2}, + 0 + } + { + {354, 2}, + {180, 2}, + {577, 2}, + 0 + } + { + {556, 2}, + {561, 2}, + {627, 2}, + 0 + } + { + {416, 2}, + {206, 2}, + {158, 2}, + 0 + } + { + {511, 2}, + {149, 2}, + {392, 2}, + 0 + } + { + {493, 2}, + {604, 2, "edge" "collidable"}, + {608, 2}, + 0 + } + { + {342, 2}, + {160, 2}, + {512, 2}, + 0 + } + { + {250, 2}, + {416, 2}, + {162, 2}, + 0 + } + { + {416, 2}, + {158, 2, "edge" "collidable"}, + {162, 2}, + 0 + } + { + {329, 2}, + {135, 2, "edge" "collidable"}, + {188, 2}, + 0 + } + { + {324, 2}, + {347, 2}, + {557, 2}, + 0 + } + { + {424, 2}, + {233, 2}, + {471, 2}, + 0 + } + { + {127, 2}, + {230, 2, "edge" "collidable"}, + {353, 2}, + 0 + } + { + {322, 2}, + {341, 2}, + {427, 2}, + 0 + } + { + {177, 2}, + {573, 2, "edge" "collidable"}, + {575, 2}, + 0 + } + { + {155, 2}, + {250, 2}, + {166, 2}, + 0 + } + { + {250, 2}, + {162, 2, "edge" "collidable"}, + {166, 2}, + 0 + } + { + {406, 2}, + {282, 2}, + {233, 2}, + 0 + } + { + {281, 2}, + {415, 2, "edge" "collidable"}, + {423, 2}, + 0 + } + { + {310, 2}, + {499, 2}, + {559, 2}, + 0 + } + { + {357, 2}, + {529, 2, "edge" "collidable"}, + {532, 2}, + 0 + } + { + {561, 2}, + {515, 2}, + {623, 2}, + 0 + } + { + {597, 2}, + {588, 2}, + {537, 2}, + 0 + } + { + {134, 2}, + {155, 2}, + {170, 2}, + 0 + } + { + {155, 2}, + {166, 2, "edge" "collidable"}, + {170, 2}, + 0 + } + { + {367, 2}, + {616, 2, "edge" "collidable"}, + {619, 2}, + 0 + } + { + {418, 2}, + {227, 2}, + {433, 2}, + 0 + } + { + {275, 2}, + {354, 2}, + {579, 2}, + 0 + } + { + {101, 2}, + {385, 2, "edge" "collidable"}, + {572, 2}, + 0 + } + { + {359, 2}, + {338, 2, "edge" "collidable"}, + {528, 2}, + 0 + } + { + {134, 2}, + {170, 2, "edge" "collidable"}, + {174, 2}, + 0 + } + { + {100, 2}, + {328, 2, "edge" "collidable"}, + {147, 2}, + 0 + } + { + {265, 2}, + {484, 2, "edge" "collidable"}, + {488, 2}, + 0 + } + { + {299, 2}, + {424, 2}, + {325, 2}, + 0 + } + { + {470, 2}, + {552, 2}, + {314, 2}, + 0 + } + { + {554, 2}, + {440, 2}, + {380, 2}, + 0 + } + { + {545, 2}, + {509, 2}, + {453, 2}, + 0 + } + { + {134, 2}, + {174, 2, "edge" "collidable"}, + {178, 2}, + 0 + } + { + {487, 2}, + {475, 2}, + {566, 2}, + 0 + } + { + {588, 2}, + {262, 2, "edge" "collidable"}, + {537, 2}, + 0 + } + { + {455, 2}, + {602, 2, "edge" "collidable"}, + {117, 2}, + 0 + } + { + {379, 2}, + {528, 2, "edge" "collidable"}, + {565, 2}, + 0 + } + { + {127, 2}, + {191, 2}, + {230, 2}, + 0 + } + { + {102, 2}, + {516, 2, "edge" "collidable"}, + {520, 2}, + 0 + } + { + {293, 2}, + {351, 2}, + {476, 2}, + 0 + } + { + {274, 2}, + {473, 2}, + {362, 2}, + 0 + } + { + {157, 2}, + {387, 2, "edge" "collidable"}, + {609, 2}, + 0 + } + { + {452, 2}, + {275, 2}, + {583, 2}, + 0 + } + { + {210, 2}, + {613, 2, "edge" "collidable"}, + {394, 2}, + 0 + } + { + {291, 2}, + {530, 2, "edge" "collidable"}, + {438, 2}, + 0 + } + { + {218, 2}, + {492, 2, "edge" "collidable"}, + {496, 2}, + 0 + } + { + {514, 2}, + {423, 2, "edge" "collidable"}, + {428, 2}, + 0 + } + { + {588, 2}, + {269, 2}, + {262, 2}, + 0 + } + { + {511, 2}, + {446, 2, "edge" "collidable"}, + {149, 2}, + 0 + } + { + {332, 2}, + {163, 2}, + {610, 2}, + 0 + } + { + {553, 2}, + {219, 2, "edge" "collidable"}, + {93, 2}, + 0 + } + { + {196, 2}, + {326, 2}, + {395, 2}, + 0 + } + { + {422, 2}, + {517, 2, "edge" "collidable"}, + {194, 2}, + 0 + } + { + {164, 2}, + {478, 2}, + {333, 2}, + 0 + } + { + {508, 2}, + {397, 2, "edge" "collidable"}, + {578, 2}, + 0 + } + { + {388, 2}, + {495, 2, "edge" "collidable"}, + {543, 2}, + 0 + } + { + {215, 2}, + {437, 2}, + {486, 2}, + 0 + } + { + {435, 2}, + {210, 2}, + {394, 2}, + 0 + } + { + {191, 2}, + {485, 2}, + {376, 2}, + 0 + } + { + {295, 2}, + {100, 2}, + {147, 2}, + 0 + } + { + {192, 2}, + {568, 2, "edge" "collidable"}, + {570, 2}, + 0 + } + { + {184, 2}, + {86, 2}, + {193, 2}, + 0 + } + { + {86, 2}, + {190, 2, "edge" "collidable"}, + {193, 2}, + 0 + } + { + {326, 2}, + {391, 2, "edge" "collidable"}, + {395, 2}, + 0 + } + { + {449, 2}, + {417, 2}, + {220, 2}, + 0 + } + { + {163, 2}, + {608, 2, "edge" "collidable"}, + {610, 2}, + 0 + } + { + {548, 2}, + {161, 2, "edge" "collidable"}, + {115, 2}, + 0 + } + { + {452, 2}, + {583, 2, "edge" "collidable"}, + {587, 2}, + 0 + } + { + {222, 2}, + {292, 2}, + {596, 2}, + 0 + } + { + {252, 2}, + {184, 2}, + {197, 2}, + 0 + } + { + {184, 2}, + {193, 2, "edge" "collidable"}, + {197, 2}, + 0 + } + { + {180, 2}, + {177, 2}, + {575, 2}, + 0 + } + { + {132, 2}, + {91, 2, "edge" "collidable"}, + {400, 2}, + 0 + } + { + {96, 2}, + {252, 2}, + {197, 2}, + 0 + } + { + {525, 2}, + {299, 2}, + {345, 2}, + 0 + } + { + {459, 2}, + {490, 2, "edge" "collidable"}, + {425, 2}, + 0 + } + { + {329, 2}, + {301, 2}, + {135, 2}, + 0 + } + { + {432, 2}, + {96, 2}, + {201, 2}, + 0 + } + { + {96, 2}, + {197, 2, "edge" "collidable"}, + {201, 2}, + 0 + } + { + {411, 2}, + {357, 2}, + {532, 2}, + 0 + } + { + {175, 2}, + {581, 2, "edge" "collidable"}, + {211, 2}, + 0 + } + { + {502, 2}, + {432, 2}, + {203, 2}, + 0 + } + { + {432, 2}, + {201, 2, "edge" "collidable"}, + {203, 2}, + 0 + } + { + {273, 2}, + {211, 2}, + {224, 2}, + 0 + } + { + {339, 2}, + {594, 2, "edge" "collidable"}, + {382, 2}, + 0 + } + { + {622, 2}, + {502, 2}, + {205, 2}, + 0 + } + { + {502, 2}, + {203, 2, "edge" "collidable"}, + {205, 2}, + 0 + } + { + {431, 2}, + {507, 2}, + {390, 2}, + 0 + } + { + {499, 2}, + {555, 2, "edge" "collidable"}, + {559, 2}, + 0 + } + { + {200, 2}, + {622, 2}, + {207, 2}, + 0 + } + { + {622, 2}, + {205, 2, "edge" "collidable"}, + {207, 2}, + 0 + } + { + {491, 2}, + {129, 2, "edge" "collidable"}, + {581, 2}, + 0 + } + { + {475, 2}, + {562, 2, "edge" "collidable"}, + {566, 2}, + 0 + } + { + {285, 2}, + {200, 2}, + {209, 2}, + 0 + } + { + {200, 2}, + {207, 2, "edge" "collidable"}, + {209, 2}, + 0 + } + { + {218, 2}, + {123, 2}, + {492, 2}, + 0 + } + { + {554, 2}, + {380, 2, "edge" "collidable"}, + {495, 2}, + 0 + } + { + {426, 2}, + {285, 2}, + {209, 2}, + 0 + } + { + {402, 2}, + {258, 2, "edge" "collidable"}, + {504, 2}, + 0 + } + { + {354, 2}, + {577, 2, "edge" "collidable"}, + {579, 2}, + 0 + } + { + {556, 2}, + {627, 2, "edge" "collidable"}, + {631, 2}, + 0 + } + { + {439, 2}, + {426, 2}, + {213, 2}, + 0 + } + { + {426, 2}, + {209, 2, "edge" "collidable"}, + {213, 2}, + 0 + } + { + {308, 2}, + {587, 2, "edge" "collidable"}, + {591, 2}, + 0 + } + { + {214, 2}, + {196, 2}, + {399, 2}, + 0 + } + { + {491, 2}, + {513, 2}, + {129, 2}, + 0 + } + { + {295, 2}, + {147, 2, "edge" "collidable"}, + {393, 2}, + 0 + } + { + {514, 2}, + {281, 2}, + {423, 2}, + 0 + } + { + {479, 2}, + {313, 2, "edge" "collidable"}, + {430, 2}, + 0 + } + { + {544, 2}, + {439, 2}, + {217, 2}, + 0 + } + { + {439, 2}, + {213, 2, "edge" "collidable"}, + {217, 2}, + 0 + } + { + {625, 2}, + {366, 2, "edge" "collidable"}, + {370, 2}, + 0 + } + { + {153, 2}, + {278, 2, "edge" "collidable"}, + {372, 2}, + 0 + } + { + {507, 2}, + {264, 2}, + {564, 2}, + 0 + } + { + {547, 2}, + {176, 2}, + {442, 2}, + 0 + } + { + {233, 2}, + {257, 2, "edge" "collidable"}, + {237, 2}, + 0 + } + { + {291, 2}, + {598, 2}, + {530, 2}, + 0 + } + { + {460, 2}, + {544, 2}, + {221, 2}, + 0 + } + { + {544, 2}, + {217, 2, "edge" "collidable"}, + {221, 2}, + 0 + } + { + {351, 2}, + {464, 2}, + {472, 2}, + 0 + } + { + {485, 2}, + {501, 2}, + {630, 2}, + 0 + } + { + {441, 2}, + {117, 2, "edge" "collidable"}, + {219, 2}, + 0 + } + { + {153, 2}, + {560, 2}, + {278, 2}, + 0 + } + { + {172, 2}, + {266, 2}, + {225, 2}, + 0 + } + { + {603, 2}, + {418, 2}, + {461, 2}, + 0 + } + { + {443, 2}, + {519, 2}, + {500, 2}, + 0 + } + { + {457, 2}, + {443, 2}, + {615, 2}, + 0 + } + { + {605, 2}, + {460, 2}, + {226, 2}, + 0 + } + { + {460, 2}, + {221, 2, "edge" "collidable"}, + {226, 2}, + 0 + } + { + {552, 2}, + {603, 2}, + {466, 2}, + 0 + } + { + {377, 2}, + {218, 2}, + {496, 2}, + 0 + } + { + {485, 2}, + {630, 2, "edge" "collidable"}, + {376, 2}, + 0 + } + { + {215, 2}, + {486, 2, "edge" "collidable"}, + {421, 2}, + 0 + } + { + {533, 2}, + {102, 2}, + {520, 2}, + 0 + } + { + {97, 2}, + {187, 2}, + {551, 2}, + 0 + } + { + {533, 2}, + {520, 2, "edge" "collidable"}, + {524, 2}, + 0 + } + { + {478, 2}, + {412, 2}, + {333, 2}, + 0 + } + { + {510, 2}, + {605, 2}, + {231, 2}, + 0 + } + { + {605, 2}, + {226, 2, "edge" "collidable"}, + {231, 2}, + 0 + } + { + {404, 2}, + {386, 2}, + {182, 2}, + 0 + } + { + {210, 2}, + {336, 2}, + {613, 2}, + 0 + } + { + {501, 2}, + {404, 2}, + {98, 2}, + 0 + } + { + {108, 2}, + {451, 2, "edge" "collidable"}, + {454, 2}, + 0 + } + { + {165, 2}, + {108, 2}, + {454, 2}, + 0 + } + { + {408, 2}, + {420, 2, "edge" "collidable"}, + {617, 2}, + 0 + } + { + {279, 2}, + {510, 2}, + {235, 2}, + 0 + } + { + {510, 2}, + {231, 2, "edge" "collidable"}, + {235, 2}, + 0 + } + { + {450, 2}, + {229, 2, "edge" "collidable"}, + {258, 2}, + 0 + } + { + {273, 2}, + {175, 2}, + {211, 2}, + 0 + } + { + {606, 2}, + {668, 2, "edge" "collidable"}, + {378, 2}, + 0 + } + { + {337, 2}, + {458, 2, "edge" "collidable"}, + {462, 2}, + 0 + } + { + {592, 2}, + {353, 2, "edge" "collidable"}, + {445, 2}, + 0 + } + { + {398, 2}, + {586, 2, "edge" "collidable"}, + {229, 2}, + 0 + } + { + {199, 2}, + {279, 2}, + {239, 2}, + 0 + } + { + {279, 2}, + {235, 2, "edge" "collidable"}, + {239, 2}, + 0 + } + { + {121, 2}, + {580, 2}, + {595, 2}, + 0 + } + { + {367, 2}, + {375, 2}, + {616, 2}, + 0 + } + { + {199, 2}, + {239, 2, "edge" "collidable"}, + {241, 2}, + 0 + } + { + {373, 2}, + {538, 2, "edge" "collidable"}, + {542, 2}, + 0 + } + { + {413, 2}, + {504, 2, "edge" "collidable"}, + {321, 2}, + 0 + } + { + {357, 2}, + {349, 2}, + {529, 2}, + 0 + } + { + {310, 2}, + {559, 2, "edge" "collidable"}, + {562, 2}, + 0 + } + { + {270, 2}, + {400, 2, "edge" "collidable"}, + {517, 2}, + 0 + } + { + {422, 2}, + {270, 2}, + {517, 2}, + 0 + } + { + {628, 2}, + {407, 2, "edge" "collidable"}, + {415, 2}, + 0 + } + { + {281, 2}, + {628, 2}, + {415, 2}, + 0 + } + { + {448, 2}, + {254, 2}, + {251, 2}, + 0 + } + { + {254, 2}, + {249, 2, "edge" "collidable"}, + {251, 2}, + 0 + } + { + {531, 2}, + {535, 2}, + {244, 2}, + 0 + } + { + {180, 2}, + {575, 2, "edge" "collidable"}, + {577, 2}, + 0 + } + { + {365, 2}, + {448, 2}, + {253, 2}, + 0 + } + { + {448, 2}, + {251, 2, "edge" "collidable"}, + {253, 2}, + 0 + } + { + {410, 2}, + {550, 2}, + {84, 2}, + 0 + } + { + {332, 2}, + {610, 2, "edge" "collidable"}, + {612, 2}, + 0 + } + { + {350, 2}, + {365, 2}, + {255, 2}, + 0 + } + { + {365, 2}, + {253, 2, "edge" "collidable"}, + {255, 2}, + 0 + } + { + {601, 2}, + {556, 2}, + {631, 2}, + 0 + } + { + {104, 2}, + {534, 2, "edge" "collidable"}, + {538, 2}, + 0 + } + { + {196, 2}, + {395, 2, "edge" "collidable"}, + {399, 2}, + 0 + } + { + {509, 2}, + {438, 2, "edge" "collidable"}, + {453, 2}, + 0 + } + { + {351, 2}, + {472, 2, "edge" "collidable"}, + {476, 2}, + 0 + } + { + {406, 2}, + {122, 2}, + {282, 2}, + 0 + } + { + {277, 2}, + {350, 2}, + {259, 2}, + 0 + } + { + {350, 2}, + {255, 2, "edge" "collidable"}, + {259, 2}, + 0 + } + { + {507, 2}, + {564, 2, "edge" "collidable"}, + {390, 2}, + 0 + } + { + {339, 2}, + {382, 2}, + {590, 2}, + 0 + } + { + {165, 2}, + {454, 2, "edge" "collidable"}, + {458, 2}, + 0 + } + { + {339, 2}, + {474, 2}, + {594, 2}, + 0 + } + { + {389, 2}, + {373, 2}, + {542, 2}, + 0 + } + { + {271, 2}, + {572, 2, "edge" "collidable"}, + {526, 2}, + 0 + } + { + {168, 2}, + {277, 2}, + {263, 2}, + 0 + } + { + {277, 2}, + {259, 2, "edge" "collidable"}, + {263, 2}, + 0 + } + { + {324, 2}, + {557, 2, "edge" "collidable"}, + {304, 2}, + 0 + } + { + {412, 2}, + {183, 2}, + {589, 2}, + 0 + } + { + {567, 2}, + {479, 2}, + {430, 2}, + 0 + } + { + {164, 2}, + {333, 2, "edge" "collidable"}, + {338, 2}, + 0 + } + { + {186, 2}, + {425, 2, "edge" "collidable"}, + {161, 2}, + 0 + } + { + {381, 2}, + {445, 2, "edge" "collidable"}, + {189, 2}, + 0 + } + { + {611, 2}, + {168, 2}, + {267, 2}, + 0 + } + { + {168, 2}, + {263, 2, "edge" "collidable"}, + {267, 2}, + 0 + } + { + {537, 2, "edge" "collidable"}, + {536, 2}, + {414, 2}, + 0 + } + { + {459, 2}, + {369, 2}, + {490, 2}, + 0 + } + { + {126, 2}, + {624, 2, "edge" "collidable"}, + {602, 2}, + 0 + } + { + {455, 2}, + {126, 2}, + {602, 2}, + 0 + } + { + {474, 2}, + {368, 2}, + {541, 2}, + 0 + } + { + {513, 2}, + {447, 2, "edge" "collidable"}, + {129, 2}, + 0 + } + { + {508, 2}, + {355, 2}, + {397, 2}, + 0 + } + { + {355, 2}, + {189, 2, "edge" "collidable"}, + {397, 2}, + 0 + } + { + {240, 2}, + {611, 2}, + {272, 2}, + 0 + } + { + {611, 2}, + {267, 2, "edge" "collidable"}, + {272, 2}, + 0 + } + { + {202, 2}, + {93, 2, "edge" "collidable"}, + {540, 2}, + 0 + } + { + {369, 2}, + {202, 2}, + {540, 2}, + 0 + } + { + {464, 2}, + {477, 2}, + {469, 2}, + 0 + } + { + {477, 2}, + {467, 2, "edge" "collidable"}, + {469, 2}, + 0 + } + { + {301, 2}, + {295, 2}, + {393, 2}, + 0 + } + { + {379, 2}, + {359, 2}, + {528, 2}, + 0 + } + { + {549, 2}, + {240, 2}, + {276, 2}, + 0 + } + { + {240, 2}, + {272, 2, "edge" "collidable"}, + {276, 2}, + 0 + } + { + {264, 2}, + {408, 2}, + {617, 2}, + 0 + } + { + {618, 2}, + {619, 2, "edge" "collidable"}, + {621, 2}, + 0 + } + { + {593, 2}, + {198, 2, "edge" "collidable"}, + {181, 2}, + 0 + } + { + {558, 2}, + {593, 2}, + {181, 2}, + 0 + } + { + {414, 2}, + {536, 2, "edge" "collidable"}, + {624, 2}, + 0 + } + { + {368, 2}, + {268, 2, "edge" "collidable"}, + {541, 2}, + 0 + } + { + {234, 2}, + {549, 2}, + {280, 2}, + 0 + } + { + {549, 2}, + {276, 2, "edge" "collidable"}, + {280, 2}, + 0 + } + { + {506, 2}, + {449, 2}, + {146, 2}, + 0 + } + { + {449, 2}, + {220, 2, "edge" "collidable"}, + {146, 2}, + 0 + } + { + {175, 2}, + {491, 2}, + {581, 2}, + 0 + } + { + {513, 2}, + {601, 2}, + {447, 2}, + 0 + } + { + {308, 2}, + {452, 2}, + {587, 2}, + 0 + } + { + {349, 2}, + {527, 2, "edge" "collidable"}, + {529, 2}, + 0 + } + { + {312, 2}, + {234, 2}, + {284, 2}, + 0 + } + { + {234, 2}, + {280, 2, "edge" "collidable"}, + {284, 2}, + 0 + } + { + {289, 2}, + {606, 2}, + {378, 2}, + 0 + } + { + {398, 2}, + {131, 2}, + {586, 2}, + 0 + } + { + {343, 2}, + {312, 2}, + {286, 2}, + 0 + } + { + {312, 2}, + {284, 2, "edge" "collidable"}, + {286, 2}, + 0 + } + { + {131, 2}, + {334, 2}, + {586, 2}, + 0 + } + { + {334, 2}, + {139, 2, "edge" "collidable"}, + {586, 2}, + 0 + } + { + {553, 2}, + {441, 2}, + {219, 2}, + 0 + } + { + {535, 2}, + {578, 2, "edge" "collidable"}, + {244, 2}, + 0 + } + { + {457, 2}, + {615, 2, "edge" "collidable"}, + {268, 2}, + 0 + } + { + {368, 2}, + {457, 2}, + {268, 2}, + 0 + } + { + {302, 2}, + {343, 2}, + {290, 2}, + 0 + } + { + {343, 2}, + {286, 2, "edge" "collidable"}, + {290, 2}, + 0 + } + { + {301, 2}, + {393, 2, "edge" "collidable"}, + {135, 2}, + 0 + } + { + {550, 2}, + {215, 2}, + {421, 2}, + 0 + } + { + {437, 2}, + {296, 2, "edge" "collidable"}, + {486, 2}, + 0 + } + { + {386, 2}, + {565, 2, "edge" "collidable"}, + {182, 2}, + 0 + } + { + {479, 2}, + {306, 2}, + {313, 2}, + 0 + } + { + {227, 2}, + {169, 2}, + {599, 2}, + 0 + } + { + {159, 2}, + {302, 2}, + {294, 2}, + 0 + } + { + {302, 2}, + {290, 2, "edge" "collidable"}, + {294, 2}, + 0 + } + { + {392, 2}, + {149, 2, "edge" "collidable"}, + {385, 2}, + 0 + } + { + {431, 2}, + {390, 2, "edge" "collidable"}, + {446, 2}, + 0 + } + { + {413, 2}, + {402, 2}, + {504, 2}, + 0 + } + { + {545, 2}, + {453, 2, "edge" "collidable"}, + {296, 2}, + 0 + } + { + {130, 2}, + {435, 2}, + {112, 2}, + 0 + } + { + {435, 2}, + {394, 2, "edge" "collidable"}, + {112, 2}, + 0 + } + { + {140, 2}, + {159, 2}, + {298, 2}, + 0 + } + { + {159, 2}, + {294, 2, "edge" "collidable"}, + {298, 2}, + 0 + } + { + {582, 2}, + {612, 2, "edge" "collidable"}, + {614, 2}, + 0 + } + { + {411, 2}, + {532, 2, "edge" "collidable"}, + {534, 2}, + 0 + } + { + {511, 2}, + {431, 2}, + {446, 2}, + 0 + } + { + {509, 2}, + {291, 2}, + {438, 2}, + 0 + } + { + {377, 2}, + {496, 2, "edge" "collidable"}, + {505, 2}, + 0 + } + { + {283, 2}, + {667, 2, "edge" "collidable"}, + {391, 2}, + 0 + } + { + {125, 2}, + {311, 2, "edge" "collidable"}, + {315, 2}, + 0 + } + { + {125, 2}, + {315, 2}, + {208, 2}, + 0 + } + { + {212, 2}, + {140, 2}, + {303, 2}, + 0 + } + { + {140, 2}, + {298, 2, "edge" "collidable"}, + {303, 2}, + 0 + } + { + {404, 2}, + {182, 2, "edge" "collidable"}, + {98, 2}, + 0 + } + { + {493, 2}, + {232, 2}, + {604, 2}, + 0 + } + { + {597, 2}, + {537, 2}, + {414, 2}, + 0 + } + { + {270, 2}, + {132, 2}, + {400, 2}, + 0 + } + { + {499, 2}, + {97, 2}, + {555, 2}, + 0 + } + { + {535, 2}, + {508, 2}, + {578, 2}, + 0 + } + { + {584, 2}, + {212, 2}, + {307, 2}, + 0 + } + { + {212, 2}, + {303, 2, "edge" "collidable"}, + {307, 2}, + 0 + } + { + {130, 2}, + {112, 2, "edge" "collidable"}, + {151, 2}, + 0 + } + { + {195, 2}, + {130, 2}, + {151, 2}, + 0 + } + { + {548, 2}, + {186, 2}, + {161, 2}, + 0 + } + { + {337, 2}, + {165, 2}, + {458, 2}, + 0 + } + { + {474, 2}, + {541, 2, "edge" "collidable"}, + {594, 2}, + 0 + } + { + {176, 2}, + {522, 2}, + {434, 2}, + 0 + } + { + {125, 2}, + {584, 2}, + {311, 2}, + 0 + } + { + {584, 2}, + {307, 2, "edge" "collidable"}, + {311, 2}, + 0 + } + { + {525, 2}, + {345, 2, "edge" "collidable"}, + {216, 2}, + 0 + } + { + {306, 2}, + {525, 2}, + {216, 2}, + 0 + } + { + {625, 2}, + {238, 2}, + {366, 2}, + 0 + } + { + {282, 2, "edge" "collidable"}, + {257, 2}, + {233, 2}, + 0 + } + { + {585, 2}, + {208, 2}, + {315, 2}, + 0 + } + { + {336, 2}, + {329, 2}, + {188, 2}, + 0 + } + { + {582, 2}, + {332, 2}, + {612, 2}, + 0 + } + { + {580, 2}, + {308, 2}, + {591, 2}, + 0 + } + { + {373, 2}, + {104, 2}, + {538, 2}, + 0 + } + { + {473, 2}, + {360, 2, "edge" "collidable"}, + {362, 2}, + 0 + } + { + {320, 2}, + {585, 2}, + {319, 2}, + 0 + } + { + {585, 2}, + {315, 2, "edge" "collidable"}, + {319, 2}, + 0 + } + { + {173, 2}, + {470, 2}, + {405, 2}, + 0 + } + { + {552, 2}, + {466, 2, "edge" "collidable"}, + {314, 2}, + 0 + } + { + {289, 2}, + {669, 2, "edge" "collidable"}, + {383, 2}, + 0 + } + { + {283, 2}, + {289, 2}, + {383, 2}, + 0 + } + { + {157, 2}, + {173, 2}, + {387, 2}, + 0 + } + { + {498, 2}, + {670, 2, "edge" "collidable"}, + {374, 2}, + 0 + } + { + {95, 2}, + {320, 2}, + {323, 2}, + 0 + } + { + {320, 2}, + {319, 2, "edge" "collidable"}, + {323, 2}, + 0 + } + { + {396, 2}, + {321, 2, "edge" "collidable"}, + {91, 2}, + 0 + } + { + {132, 2}, + {396, 2}, + {91, 2}, + 0 + } + { + {214, 2}, + {399, 2, "edge" "collidable"}, + {403, 2}, + 0 + } + { + {223, 2}, + {214, 2}, + {403, 2}, + 0 + } + { + {173, 2}, + {405, 2, "edge" "collidable"}, + {387, 2}, + 0 + } + { + {318, 2}, + {422, 2}, + {194, 2}, + 0 + } + { + {236, 2}, + {95, 2}, + {327, 2}, + 0 + } + { + {95, 2}, + {323, 2, "edge" "collidable"}, + {327, 2}, + 0 + } + { + {567, 2}, + {430, 2, "edge" "collidable"}, + {198, 2}, + 0 + } + { + {593, 2}, + {567, 2}, + {198, 2}, + 0 + } + { + {169, 2}, + {167, 2, "edge" "collidable"}, + {599, 2}, + 0 + } + { + {607, 2}, + {192, 2}, + {570, 2}, + 0 + } + { + {227, 2}, + {599, 2, "edge" "collidable"}, + {433, 2}, + 0 + } + { + {299, 2}, + {325, 2, "edge" "collidable"}, + {345, 2}, + 0 + } + { + {260, 2}, + {236, 2}, + {331, 2}, + 0 + } + { + {236, 2}, + {327, 2, "edge" "collidable"}, + {331, 2}, + 0 + } + { + {424, 2}, + {471, 2, "edge" "collidable"}, + {325, 2}, + 0 + } + { + {606, 2}, + {498, 2}, + {374, 2}, + 0 + } + { + {123, 2}, + {488, 2, "edge" "collidable"}, + {492, 2}, + 0 + } + { + {441, 2}, + {455, 2}, + {117, 2}, + 0 + } + { + {347, 2}, + {115, 2, "edge" "collidable"}, + {557, 2}, + 0 + } + { + {183, 2}, + {590, 2}, + {82, 2}, + 0 + } + { + {300, 2}, + {260, 2}, + {335, 2}, + 0 + } + { + {260, 2}, + {331, 2, "edge" "collidable"}, + {335, 2}, + 0 + } + { + {288, 2}, + {204, 2, "edge" "collidable"}, + {261, 2}, + 0 + } + { + {443, 2}, + {500, 2, "edge" "collidable"}, + {615, 2}, + 0 + } + { + {558, 2}, + {181, 2, "edge" "collidable"}, + {420, 2}, + 0 + } + { + {598, 2}, + {388, 2}, + {543, 2}, + 0 + } + { + {598, 2}, + {543, 2, "edge" "collidable"}, + {530, 2}, + 0 + } + { + {369, 2}, + {540, 2, "edge" "collidable"}, + {490, 2}, + 0 + } + { + {429, 2}, + {300, 2}, + {335, 2}, + 0 + } + { + {503, 2}, + {506, 2}, + {146, 2}, + 0 + } + { + {429, 2}, + {335, 2, "edge" "collidable"}, + {340, 2}, + 0 + } + { + {359, 2}, + {164, 2}, + {338, 2}, + 0 + } + { + {186, 2}, + {459, 2}, + {425, 2}, + 0 + } + { + {482, 2}, + {337, 2}, + {462, 2}, + 0 + } + { + {408, 2}, + {558, 2}, + {420, 2}, + 0 + } + { + {266, 2}, + {288, 2}, + {261, 2}, + 0 + } + { + {482, 2}, + {462, 2, "edge" "collidable"}, + {465, 2}, + 0 + } + { + {138, 2}, + {429, 2}, + {344, 2}, + 0 + } + { + {429, 2}, + {340, 2, "edge" "collidable"}, + {344, 2}, + 0 + } + { + {269, 2}, + {410, 2}, + {110, 2}, + 0 + } + { + {410, 2}, + {84, 2, "edge" "collidable"}, + {110, 2}, + 0 + } + { + {265, 2}, + {539, 2}, + {484, 2}, + 0 + } + { + {539, 2}, + {480, 2, "edge" "collidable"}, + {484, 2}, + 0 + } + { + {464, 2}, + {469, 2, "edge" "collidable"}, + {472, 2}, + 0 + } + { + {497, 2}, + {531, 2}, + {483, 2}, + 0 + } + { + {316, 2}, + {138, 2}, + {348, 2}, + 0 + } + { + {138, 2}, + {344, 2, "edge" "collidable"}, + {348, 2}, + 0 + } + { + {498, 2}, + {625, 2}, + {370, 2}, + 0 + } + { + {101, 2}, + {392, 2}, + {385, 2}, + 0 + } + { + {501, 2}, + {98, 2, "edge" "collidable"}, + {630, 2}, + 0 + } + { + {375, 2}, + {614, 2, "edge" "collidable"}, + {616, 2}, + 0 + } + { + {126, 2}, + {414, 2}, + {624, 2}, + 0 + } + { + {603, 2}, + {461, 2, "edge" "collidable"}, + {466, 2}, + 0 + } + { + {523, 2}, + {316, 2}, + {352, 2}, + 0 + } + { + {316, 2}, + {348, 2, "edge" "collidable"}, + {352, 2}, + 0 + } + { + {398, 2}, + {229, 2}, + {450, 2}, + 0 + } + { + {123, 2}, + {265, 2}, + {488, 2}, + 0 + } + { + {269, 2}, + {110, 2, "edge" "collidable"}, + {262, 2}, + 0 + } + { + {503, 2}, + {146, 2, "edge" "collidable"}, + {167, 2}, + 0 + } + { + {386, 2}, + {379, 2}, + {565, 2}, + 0 + } + { + {275, 2}, + {579, 2, "edge" "collidable"}, + {583, 2}, + 0 + } + { + {287, 2}, + {523, 2}, + {356, 2}, + 0 + } + { + {523, 2}, + {352, 2, "edge" "collidable"}, + {356, 2}, + 0 + } + { + {550, 2}, + {421, 2, "edge" "collidable"}, + {84, 2}, + 0 + } + { + {375, 2}, + {582, 2}, + {614, 2}, + 0 + } + { + {256, 2}, + {287, 2}, + {358, 2}, + 0 + } + { + {287, 2}, + {356, 2, "edge" "collidable"}, + {358, 2}, + 0 + } + { + {412, 2}, + {589, 2, "edge" "collidable"}, + {333, 2}, + 0 + } + { + {515, 2}, + {621, 2, "edge" "collidable"}, + {623, 2}, + 0 + } + { + {473, 2}, + {256, 2}, + {360, 2}, + 0 + } + { + {256, 2}, + {358, 2, "edge" "collidable"}, + {360, 2}, + 0 + } + { + {222, 2}, + {642, 2, "edge" "collidable"}, + {635, 2}, + 0 + } + { + {222, 2}, + {596, 2, "edge" "collidable"}, + {642, 2}, + 0 + } + { + {634, 2, "edge" "collidable"}, + {645, 2}, + {648, 2}, + 0 + } + { + {648, 2}, + {647, 2}, + {634, 2}, + 0 + } + { + {645, 2, "edge" "collidable"}, + {637, 2}, + {649, 2}, + 0 + } + { + {649, 2}, + {648, 2}, + {645, 2}, + 0 + } + { + {643, 2, "edge" "collidable"}, + {636, 2}, + {650, 2}, + 0 + } + { + {650, 2}, + {651, 2}, + {643, 2}, + 0 + } + { + {633, 2, "edge" "collidable"}, + {643, 2}, + {651, 2}, + 0 + } + { + {651, 2}, + {652, 2}, + {633, 2}, + 0 + } + { + {640, 2, "edge" "collidable"}, + {638, 2}, + {653, 2}, + 0 + } + { + {653, 2}, + {654, 2}, + {640, 2}, + 0 + } + { + {632, 2, "edge" "collidable"}, + {640, 2}, + {654, 2}, + 0 + } + { + {654, 2}, + {655, 2}, + {632, 2}, + 0 + } + { + {639, 2, "edge" "collidable"}, + {634, 2}, + {647, 2}, + 0 + } + { + {647, 2}, + {656, 2}, + {639, 2}, + 0 + } + { + {638, 2, "edge" "collidable"}, + {639, 2}, + {656, 2}, + 0 + } + { + {656, 2}, + {653, 2}, + {638, 2}, + 0 + } + { + {635, 2, "edge" "collidable"}, + {641, 2}, + {658, 2}, + 0 + } + { + {658, 2}, + {657, 2}, + {635, 2}, + 0 + } + { + {641, 2, "edge" "collidable"}, + {633, 2}, + {652, 2}, + 0 + } + { + {652, 2}, + {658, 2}, + {641, 2}, + 0 + } + { + {636, 2, "edge" "collidable"}, + {644, 2}, + {659, 2}, + 0 + } + { + {659, 2}, + {650, 2}, + {636, 2}, + 0 + } + { + {644, 2, "edge" "collidable"}, + {632, 2}, + {655, 2}, + 0 + } + { + {655, 2}, + {659, 2}, + {644, 2}, + 0 + } + { + {646, 2, "edge" "collidable"}, + {626, 2, "edge" "collidable"}, + {660, 2}, + 0 + } + { + {660, 2}, + {661, 2}, + {646, 2}, + 0 + } + { + {637, 2, "edge" "collidable"}, + {646, 2}, + {661, 2}, + 0 + } + { + {661, 2}, + {649, 2}, + {637, 2}, + 0 + } + { + {657, 2}, + {222, 2}, + {635, 2}, + 0 + } + { + {498, 2}, + {671, 2, "edge" "collidable"}, + {662, 2}, + 0 + } + { + {606, 2}, + {672, 2, "edge" "collidable"}, + {663, 2}, + 0 + } + { + {289, 2}, + {673, 2, "edge" "collidable"}, + {664, 2}, + 0 + } + { + {289, 2}, + {674, 2, "edge" "collidable"}, + {665, 2}, + 0 + } + { + {289, 2}, + {675, 2, "edge" "collidable"}, + {666, 2}, + 0 + } + { + {283, 2}, + {676, 2, "edge" "collidable"}, + {667, 2}, + 0 + } + { + {283, 2}, + {383, 2, "edge" "collidable"}, + {676, 2}, + 0 + } + { + {289, 2}, + {664, 2, "edge" "collidable"}, + {675, 2}, + 0 + } + { + {289, 2}, + {378, 2, "edge" "collidable"}, + {674, 2}, + 0 + } + { + {289, 2}, + {665, 2, "edge" "collidable"}, + {673, 2}, + 0 + } + { + {606, 2}, + {374, 2, "edge" "collidable"}, + {672, 2}, + 0 + } + { + {498, 2}, + {370, 2, "edge" "collidable"}, + {671, 2}, + 0 + } + { + {498, 2}, + {662, 2, "edge" "collidable"}, + {670, 2}, + 0 + } + { + {289, 2}, + {666, 2, "edge" "collidable"}, + {669, 2}, + 0 + } + { + {606, 2}, + {663, 2, "edge" "collidable"}, + {668, 2}, + 0 + } + { + {241, 2, "edge" "collidable"}, + {243, 2}, + {199, 2}, + 0 + } + { + {249, 2}, + {254, 2}, + {247, 2, "edge" "collidable"}, + 0 + } + { + {243, 2, "edge" "collidable"}, + {245, 2}, + {199, 2}, + 0 + } + { + {247, 2}, + {254, 2}, + {245, 2, "edge" "collidable"}, + 0 + } + { + {245, 2}, + {254, 2}, + {199, 2}, + 0 + } + { + {661, 2}, + {660, 2, "edge" "collidable"}, + {677, 2}, + 0 + } + { + {677, 2, "edge" "collidable"}, + {678, 2}, + {661, 2}, + 0 + } + { + {679, 2, "edge" "collidable"}, + {80, 2}, + {468, 2}, + 0 + } + { + {468, 2}, + {680, 2, "edge" "collidable"}, + {679, 2}, + 0 + } + { + {185, 2, "edge" "collidable"}, + {190, 2}, + {86, 2}, + 0 + } + { + {681, 2, "edge" "collidable"}, + {185, 2}, + {86, 2}, + 0 + } + { + {681, 2}, + {86, 2}, + {682, 2}, + 0 + } + { + {178, 2, "edge" "collidable"}, + {681, 2}, + {682, 2}, + 0 + } + { + {134, 2}, + {178, 2}, + {682, 2}, + 0 + } + # Mesh "CurveCircle" + { + {695, 2, "edge"}, + {694, 2}, + {708, 2}, + 0 + } + { + {708, 2, "edge"}, + {709, 2}, + {695, 2}, + 0 + } + { + {696, 2, "edge"}, + {695, 2}, + {709, 2}, + 0 + } + { + {709, 2, "edge"}, + {710, 2}, + {696, 2}, + 0 + } + { + {694, 2, "edge"}, + {693, 2}, + {711, 2}, + 0 + } + { + {711, 2, "edge"}, + {708, 2}, + {694, 2}, + 0 + } + { + {697, 2, "edge"}, + {696, 2}, + {710, 2}, + 0 + } + { + {710, 2, "edge"}, + {712, 2}, + {697, 2}, + 0 + } + { + {693, 2, "edge"}, + {692, 2}, + {713, 2}, + 0 + } + { + {713, 2, "edge"}, + {711, 2}, + {693, 2}, + 0 + } + { + {698, 2, "edge"}, + {697, 2}, + {712, 2}, + 0 + } + { + {712, 2, "edge"}, + {714, 2}, + {698, 2}, + 0 + } + { + {692, 2, "edge"}, + {691, 2}, + {715, 2}, + 0 + } + { + {715, 2, "edge"}, + {713, 2}, + {692, 2}, + 0 + } + { + {699, 2, "edge"}, + {698, 2}, + {714, 2}, + 0 + } + { + {714, 2, "edge"}, + {716, 2}, + {699, 2}, + 0 + } + { + {691, 2, "edge"}, + {690, 2}, + {717, 2}, + 0 + } + { + {717, 2, "edge"}, + {715, 2}, + {691, 2}, + 0 + } + { + {700, 2, "edge"}, + {699, 2}, + {716, 2}, + 0 + } + { + {716, 2, "edge"}, + {718, 2}, + {700, 2}, + 0 + } + { + {690, 2, "edge"}, + {689, 2}, + {719, 2}, + 0 + } + { + {719, 2, "edge"}, + {717, 2}, + {690, 2}, + 0 + } + { + {701, 2, "edge"}, + {700, 2}, + {718, 2}, + 0 + } + { + {718, 2, "edge"}, + {720, 2}, + {701, 2}, + 0 + } + { + {689, 2, "edge"}, + {688, 2}, + {721, 2}, + 0 + } + { + {721, 2, "edge"}, + {719, 2}, + {689, 2}, + 0 + } + { + {702, 2, "edge"}, + {701, 2}, + {720, 2}, + 0 + } + { + {720, 2, "edge"}, + {722, 2}, + {702, 2}, + 0 + } + { + {688, 2, "edge"}, + {687, 2}, + {723, 2}, + 0 + } + { + {723, 2, "edge"}, + {721, 2}, + {688, 2}, + 0 + } + { + {703, 2, "edge"}, + {702, 2}, + {722, 2}, + 0 + } + { + {722, 2, "edge"}, + {724, 2}, + {703, 2}, + 0 + } + { + {687, 2, "edge"}, + {686, 2}, + {725, 2}, + 0 + } + { + {725, 2, "edge"}, + {723, 2}, + {687, 2}, + 0 + } + { + {704, 2, "edge"}, + {703, 2}, + {724, 2}, + 0 + } + { + {724, 2, "edge"}, + {726, 2}, + {704, 2}, + 0 + } + { + {686, 2, "edge"}, + {685, 2}, + {727, 2}, + 0 + } + { + {727, 2, "edge"}, + {725, 2}, + {686, 2}, + 0 + } + { + {705, 2, "edge"}, + {704, 2}, + {726, 2}, + 0 + } + { + {726, 2, "edge"}, + {728, 2}, + {705, 2}, + 0 + } + { + {685, 2, "edge"}, + {684, 2}, + {729, 2}, + 0 + } + { + {729, 2, "edge"}, + {727, 2}, + {685, 2}, + 0 + } + { + {706, 2, "edge"}, + {705, 2}, + {728, 2}, + 0 + } + { + {728, 2, "edge"}, + {730, 2}, + {706, 2}, + 0 + } + { + {684, 2, "edge"}, + {683, 2, "edge"}, + {731, 2}, + 0 + } + { + {731, 2, "edge"}, + {729, 2}, + {684, 2}, + 0 + } + { + {707, 2, "edge"}, + {706, 2}, + {730, 2}, + 0 + } + { + {730, 2, "edge"}, + {732, 2, "edge"}, + {707, 2}, + 0 + } + # Mesh "Font.001" + { + {817, 2, "edge" "collidable"}, + {816, 2, "edge" "collidable"}, + {819, 2}, + 3 + } + { + {818, 2, "edge" "collidable"}, + {817, 2}, + {819, 2, "edge" "collidable"}, + 3 + } + { + {813, 2, "edge" "collidable"}, + {812, 2, "edge" "collidable"}, + {815, 2}, + 3 + } + { + {814, 2, "edge" "collidable"}, + {813, 2}, + {815, 2, "edge" "collidable"}, + 3 + } + { + {802, 2, "edge" "collidable"}, + {801, 2, "edge" "collidable"}, + {808, 2}, + 3 + } + { + {803, 2, "edge" "collidable"}, + {802, 2}, + {809, 2}, + 3 + } + { + {809, 2}, + {802, 2}, + {808, 2}, + 3 + } + { + {803, 2}, + {809, 2, "edge" "collidable"}, + {811, 2}, + 3 + } + { + {810, 2, "edge" "collidable"}, + {809, 2}, + {808, 2}, + 3 + } + { + {811, 2, "edge" "collidable"}, + {810, 2}, + {806, 2}, + 3 + } + { + {806, 2}, + {810, 2}, + {808, 2}, + 3 + } + { + {811, 2}, + {806, 2, "edge" "collidable"}, + {805, 2}, + 3 + } + { + {807, 2, "edge" "collidable"}, + {806, 2}, + {808, 2, "edge" "collidable"}, + 3 + } + { + {803, 2}, + {811, 2}, + {805, 2}, + 3 + } + { + {803, 2}, + {805, 2, "edge" "collidable"}, + {804, 2, "edge" "collidable"}, + 3 + } + { + {1022, 2}, + {1043, 2, "edge" "collidable"}, + {897, 2}, + 3 + } + { + {840, 2, "edge" "collidable"}, + {838, 2, "edge" "collidable"}, + {834, 2}, + 3 + } + { + {846, 2, "edge" "collidable"}, + {969, 2}, + {745, 2}, + 3 + } + { + {1082, 2, "edge" "collidable"}, + {830, 2}, + {844, 2}, + 3 + } + { + {1069, 2, "edge" "collidable"}, + {835, 2}, + {785, 2}, + 3 + } + { + {1066, 2}, + {944, 2}, + {1029, 2}, + 3 + } + { + {748, 2, "edge" "collidable"}, + {1046, 2, "edge" "collidable"}, + {977, 2}, + 3 + } + { + {862, 2}, + {840, 2}, + {834, 2}, + 3 + } + { + {862, 2}, + {834, 2}, + {866, 2, "edge" "collidable"}, + 3 + } + { + {1034, 2}, + {821, 2, "edge" "collidable"}, + {836, 2}, + 3 + } + { + {869, 2, "edge" "collidable"}, + {797, 2}, + {949, 2}, + 3 + } + { + {905, 2, "edge" "collidable"}, + {878, 2}, + {864, 2}, + 3 + } + { + {1038, 2}, + {930, 2, "edge" "collidable"}, + {1032, 2}, + 3 + } + { + {998, 2}, + {947, 2, "edge" "collidable"}, + {1033, 2}, + 3 + } + { + {843, 2, "edge" "collidable"}, + {840, 2}, + {862, 2}, + 3 + } + { + {843, 2}, + {862, 2, "edge" "collidable"}, + {858, 2}, + 3 + } + { + {984, 2}, + {973, 2, "edge" "collidable"}, + {926, 2}, + 3 + } + { + {823, 2}, + {846, 2}, + {745, 2}, + 3 + } + { + {866, 2}, + {834, 2, "edge" "collidable"}, + {833, 2}, + 3 + } + { + {870, 2, "edge" "collidable"}, + {866, 2}, + {833, 2}, + 3 + } + { + {902, 2, "edge" "collidable"}, + {761, 2}, + {960, 2}, + 3 + } + { + {1069, 2}, + {785, 2, "edge" "collidable"}, + {1021, 2}, + 3 + } + { + {858, 2, "edge" "collidable"}, + {870, 2}, + {833, 2}, + 3 + } + { + {1023, 2, "edge" "collidable"}, + {952, 2, "edge" "collidable"}, + {1037, 2}, + 3 + } + { + {858, 2}, + {833, 2, "edge" "collidable"}, + {832, 2}, + 3 + } + { + {845, 2, "edge" "collidable"}, + {843, 2}, + {858, 2}, + 3 + } + { + {845, 2}, + {858, 2}, + {832, 2}, + 3 + } + { + {845, 2}, + {832, 2, "edge" "collidable"}, + {829, 2}, + 3 + } + { + {927, 2}, + {766, 2, "edge" "collidable"}, + {752, 2}, + 3 + } + { + {1018, 2}, + {978, 2, "edge" "collidable"}, + {795, 2}, + 3 + } + { + {946, 2}, + {853, 2, "edge" "collidable"}, + {1077, 2}, + 3 + } + { + {1058, 2}, + {757, 2}, + {922, 2}, + 3 + } + { + {949, 2}, + {906, 2, "edge" "collidable"}, + {1023, 2}, + 3 + } + { + {930, 2}, + {887, 2}, + {991, 2, "edge" "collidable"}, + 3 + } + { + {1034, 2}, + {836, 2, "edge" "collidable"}, + {1052, 2, "edge" "collidable"}, + 3 + } + { + {755, 2, "edge" "collidable"}, + {749, 2}, + {773, 2}, + 3 + } + { + {825, 2, "edge" "collidable"}, + {820, 2, "edge" "collidable"}, + {854, 2}, + 3 + } + { + {845, 2}, + {829, 2, "edge" "collidable"}, + {825, 2}, + 3 + } + { + {966, 2, "edge" "collidable"}, + {919, 2, "edge" "collidable"}, + {757, 2}, + 3 + } + { + {736, 2, "edge" "collidable"}, + {874, 2, "edge" "collidable"}, + {857, 2}, + 3 + } + { + {1043, 2}, + {1072, 2}, + {841, 2, "edge" "collidable"}, + 3 + } + { + {984, 2}, + {956, 2, "edge" "collidable"}, + {973, 2}, + 3 + } + { + {845, 2}, + {825, 2}, + {854, 2}, + 3 + } + { + {965, 2}, + {995, 2, "edge" "collidable"}, + {1083, 2}, + 3 + } + { + {912, 2}, + {822, 2, "edge" "collidable"}, + {782, 2}, + 3 + } + { + {893, 2}, + {762, 2, "edge" "collidable"}, + {994, 2}, + 3 + } + { + {849, 2, "edge" "collidable"}, + {845, 2}, + {854, 2, "edge" "collidable"}, + 3 + } + { + {925, 2}, + {835, 2, "edge" "collidable"}, + {1075, 2}, + 3 + } + { + {869, 2}, + {949, 2}, + {1023, 2}, + 3 + } + { + {984, 2}, + {948, 2, "edge" "collidable"}, + {822, 2}, + 3 + } + { + {892, 2, "edge" "collidable"}, + {1038, 2}, + {987, 2}, + 3 + } + { + {872, 2, "edge" "collidable"}, + {871, 2, "edge" "collidable"}, + {951, 2}, + 3 + } + { + {1015, 2, "edge" "collidable"}, + {824, 2, "edge" "collidable"}, + {853, 2}, + 3 + } + { + {1034, 2, "edge" "collidable"}, + {743, 2}, + {821, 2}, + 3 + } + { + {1072, 2, "edge" "collidable"}, + {938, 2, "edge" "collidable"}, + {1010, 2}, + 3 + } + { + {876, 2, "edge" "collidable"}, + {872, 2}, + {950, 2}, + 3 + } + { + {950, 2}, + {872, 2}, + {951, 2, "edge" "collidable"}, + 3 + } + { + {876, 2}, + {950, 2}, + {970, 2}, + 3 + } + { + {970, 2}, + {950, 2, "edge" "collidable"}, + {942, 2}, + 3 + } + { + {1013, 2, "edge" "collidable"}, + {1066, 2}, + {1070, 2, "edge" "collidable"}, + 3 + } + { + {967, 2}, + {876, 2}, + {970, 2, "edge" "collidable"}, + 3 + } + { + {839, 2, "edge" "collidable"}, + {889, 2}, + {935, 2}, + 3 + } + { + {982, 2, "edge" "collidable"}, + {1012, 2, "edge" "collidable"}, + {947, 2}, + 3 + } + { + {842, 2, "edge" "collidable"}, + {867, 2, "edge" "collidable"}, + {735, 2}, + 3 + } + { + {936, 2}, + {882, 2, "edge" "collidable"}, + {1011, 2}, + 3 + } + { + {936, 2, "edge" "collidable"}, + {961, 2}, + {882, 2}, + 3 + } + { + {887, 2, "edge" "collidable"}, + {885, 2, "edge" "collidable"}, + {940, 2}, + 3 + } + { + {995, 2}, + {895, 2}, + {758, 2, "edge" "collidable"}, + 3 + } + { + {974, 2, "edge" "collidable"}, + {970, 2}, + {942, 2}, + 3 + } + { + {876, 2}, + {967, 2, "edge" "collidable"}, + {963, 2}, + 3 + } + { + {1018, 2, "edge" "collidable"}, + {931, 2}, + {1077, 2}, + 3 + } + { + {900, 2}, + {1084, 2, "edge" "collidable"}, + {980, 2}, + 3 + } + { + {1036, 2, "edge" "collidable"}, + {770, 2}, + {847, 2}, + 3 + } + { + {889, 2, "edge" "collidable"}, + {800, 2}, + {860, 2}, + 3 + } + { + {908, 2, "edge" "collidable"}, + {902, 2}, + {960, 2}, + 3 + } + { + {961, 2, "edge" "collidable"}, + {762, 2}, + {882, 2}, + 3 + } + { + {1040, 2, "edge" "collidable"}, + {991, 2}, + {821, 2}, + 3 + } + { + {889, 2}, + {860, 2, "edge" "collidable"}, + {935, 2}, + 3 + } + { + {932, 2, "edge" "collidable"}, + {790, 2}, + {1022, 2}, + 3 + } + { + {964, 2}, + {957, 2}, + {847, 2}, + 3 + } + { + {993, 2}, + {856, 2}, + {800, 2, "edge" "collidable"}, + 3 + } + { + {971, 2, "edge" "collidable"}, + {975, 2}, + {859, 2}, + 3 + } + { + {749, 2}, + {779, 2, "edge" "collidable"}, + {775, 2}, + 3 + } + { + {1068, 2, "edge" "collidable"}, + {769, 2}, + {831, 2}, + 3 + } + { + {1022, 2, "edge" "collidable"}, + {1072, 2}, + {1043, 2}, + 3 + } + { + {876, 2}, + {963, 2, "edge" "collidable"}, + {959, 2}, + 3 + } + { + {881, 2, "edge" "collidable"}, + {876, 2}, + {959, 2}, + 3 + } + { + {955, 2, "edge" "collidable"}, + {974, 2}, + {942, 2}, + 3 + } + { + {955, 2}, + {942, 2, "edge" "collidable"}, + {937, 2}, + 3 + } + { + {972, 2, "edge" "collidable"}, + {925, 2}, + {780, 2}, + 3 + } + { + {772, 2, "edge" "collidable"}, + {831, 2}, + {875, 2}, + 3 + } + { + {748, 2}, + {977, 2, "edge" "collidable"}, + {839, 2}, + 3 + } + { + {747, 2}, + {980, 2, "edge" "collidable"}, + {981, 2}, + 3 + } + { + {747, 2}, + {981, 2, "edge" "collidable"}, + {856, 2}, + 3 + } + { + {1038, 2}, + {1032, 2, "edge" "collidable"}, + {987, 2}, + 3 + } + { + {781, 2}, + {1023, 2}, + {761, 2, "edge" "collidable"}, + 3 + } + { + {909, 2, "edge" "collidable"}, + {962, 2, "edge" "collidable"}, + {785, 2}, + 3 + } + { + {744, 2}, + {789, 2, "edge" "collidable"}, + {783, 2}, + 3 + } + { + {1066, 2, "edge" "collidable"}, + {1025, 2}, + {944, 2}, + 3 + } + { + {875, 2, "edge" "collidable"}, + {910, 2, "edge" "collidable"}, + {880, 2}, + 3 + } + { + {881, 2}, + {959, 2, "edge" "collidable"}, + {955, 2}, + 3 + } + { + {881, 2}, + {955, 2}, + {937, 2}, + 3 + } + { + {943, 2, "edge" "collidable"}, + {760, 2}, + {931, 2}, + 3 + } + { + {922, 2}, + {757, 2}, + {823, 2, "edge" "collidable"}, + 3 + } + { + {740, 2}, + {733, 2}, + {789, 2}, + 3 + } + { + {749, 2, "edge" "collidable"}, + {746, 2}, + {779, 2}, + 3 + } + { + {767, 2, "edge" "collidable"}, + {917, 2, "edge" "collidable"}, + {894, 2}, + 3 + } + { + {888, 2, "edge" "collidable"}, + {881, 2}, + {937, 2}, + 3 + } + { + {982, 2}, + {998, 2, "edge" "collidable"}, + {842, 2}, + 3 + } + { + {869, 2}, + {1023, 2}, + {781, 2}, + 3 + } + { + {746, 2, "edge" "collidable"}, + {744, 2}, + {783, 2}, + 3 + } + { + {887, 2}, + {791, 2}, + {991, 2}, + 3 + } + { + {827, 2, "edge" "collidable"}, + {1085, 2, "edge" "collidable"}, + {868, 2}, + 3 + } + { + {888, 2}, + {937, 2, "edge" "collidable"}, + {934, 2}, + 3 + } + { + {891, 2, "edge" "collidable"}, + {778, 2}, + {999, 2}, + 3 + } + { + {932, 2}, + {1022, 2}, + {897, 2}, + 3 + } + { + {909, 2}, + {785, 2}, + {835, 2}, + 3 + } + { + {931, 2}, + {760, 2}, + {1077, 2}, + 3 + } + { + {888, 2}, + {934, 2, "edge" "collidable"}, + {928, 2}, + 3 + } + { + {896, 2, "edge" "collidable"}, + {888, 2}, + {928, 2}, + 3 + } + { + {734, 2, "edge" "collidable"}, + {733, 2}, + {740, 2, "edge" "collidable"}, + 3 + } + { + {975, 2, "edge" "collidable"}, + {948, 2}, + {926, 2}, + 3 + } + { + {925, 2, "edge" "collidable"}, + {909, 2}, + {835, 2}, + 3 + } + { + {1036, 2}, + {847, 2, "edge" "collidable"}, + {750, 2}, + 3 + } + { + {1082, 2}, + {844, 2}, + {985, 2, "edge" "collidable"}, + 3 + } + { + {778, 2, "edge" "collidable"}, + {943, 2}, + {933, 2}, + 3 + } + { + {830, 2, "edge" "collidable"}, + {958, 2, "edge" "collidable"}, + {844, 2}, + 3 + } + { + {1084, 2}, + {798, 2, "edge" "collidable"}, + {900, 2}, + 3 + } + { + {789, 2}, + {733, 2, "edge" "collidable"}, + {796, 2, "edge" "collidable"}, + 3 + } + { + {1056, 2, "edge" "collidable"}, + {1068, 2}, + {828, 2}, + 3 + } + { + {896, 2}, + {928, 2, "edge" "collidable"}, + {923, 2}, + 3 + } + { + {925, 2}, + {1075, 2, "edge" "collidable"}, + {780, 2}, + 3 + } + { + {1033, 2}, + {949, 2, "edge" "collidable"}, + {826, 2}, + 3 + } + { + {903, 2, "edge" "collidable"}, + {896, 2}, + {923, 2}, + 3 + } + { + {760, 2, "edge" "collidable"}, + {946, 2}, + {1077, 2}, + 3 + } + { + {790, 2, "edge" "collidable"}, + {741, 2, "edge" "collidable"}, + {1022, 2}, + 3 + } + { + {778, 2}, + {986, 2}, + {999, 2}, + 3 + } + { + {1077, 2, "edge" "collidable"}, + {763, 2, "edge" "collidable"}, + {978, 2}, + 3 + } + { + {1006, 2, "edge" "collidable"}, + {861, 2}, + {935, 2, "edge" "collidable"}, + 3 + } + { + {903, 2}, + {923, 2}, + {992, 2}, + 3 + } + { + {932, 2}, + {897, 2, "edge" "collidable"}, + {901, 2, "edge" "collidable"}, + 3 + } + { + {1029, 2}, + {944, 2, "edge" "collidable"}, + {875, 2}, + 3 + } + { + {907, 2, "edge" "collidable"}, + {903, 2}, + {992, 2}, + 3 + } + { + {996, 2, "edge" "collidable"}, + {992, 2}, + {923, 2}, + 3 + } + { + {1018, 2}, + {1077, 2}, + {978, 2}, + 3 + } + { + {1033, 2, "edge" "collidable"}, + {837, 2, "edge" "collidable"}, + {949, 2}, + 3 + } + { + {996, 2}, + {923, 2, "edge" "collidable"}, + {920, 2}, + 3 + } + { + {907, 2}, + {992, 2, "edge" "collidable"}, + {988, 2}, + 3 + } + { + {800, 2}, + {856, 2, "edge" "collidable"}, + {860, 2}, + 3 + } + { + {957, 2, "edge" "collidable"}, + {765, 2, "edge" "collidable"}, + {847, 2}, + 3 + } + { + {912, 2}, + {782, 2, "edge" "collidable"}, + {968, 2}, + 3 + } + { + {1061, 2, "edge" "collidable"}, + {1056, 2}, + {739, 2}, + 3 + } + { + {743, 2, "edge" "collidable"}, + {892, 2}, + {821, 2}, + 3 + } + { + {761, 2}, + {1023, 2}, + {1037, 2}, + 3 + } + { + {976, 2, "edge" "collidable"}, + {996, 2}, + {920, 2}, + 3 + } + { + {831, 2}, + {769, 2}, + {875, 2}, + 3 + } + { + {948, 2}, + {984, 2}, + {926, 2}, + 3 + } + { + {892, 2}, + {987, 2, "edge" "collidable"}, + {1040, 2}, + 3 + } + { + {982, 2}, + {947, 2}, + {998, 2}, + 3 + } + { + {907, 2}, + {988, 2, "edge" "collidable"}, + {983, 2}, + 3 + } + { + {1068, 2}, + {831, 2, "edge" "collidable"}, + {828, 2}, + 3 + } + { + {1038, 2, "edge" "collidable"}, + {887, 2}, + {930, 2}, + 3 + } + { + {908, 2}, + {960, 2, "edge" "collidable"}, + {784, 2, "edge" "collidable"}, + 3 + } + { + {976, 2}, + {920, 2, "edge" "collidable"}, + {918, 2}, + 3 + } + { + {979, 2, "edge" "collidable"}, + {976, 2}, + {918, 2}, + 3 + } + { + {772, 2}, + {875, 2}, + {880, 2}, + 3 + } + { + {911, 2, "edge" "collidable"}, + {907, 2}, + {983, 2}, + 3 + } + { + {1063, 2, "edge" "collidable"}, + {851, 2}, + {788, 2}, + 3 + } + { + {994, 2, "edge" "collidable"}, + {936, 2}, + {1011, 2}, + 3 + } + { + {1050, 2, "edge" "collidable"}, + {893, 2}, + {994, 2}, + 3 + } + { + {899, 2}, + {864, 2, "edge" "collidable"}, + {771, 2, "edge" "collidable"}, + 3 + } + { + {1072, 2}, + {1010, 2, "edge" "collidable"}, + {841, 2}, + 3 + } + { + {911, 2}, + {983, 2, "edge" "collidable"}, + {979, 2}, + 3 + } + { + {769, 2, "edge" "collidable"}, + {1029, 2}, + {875, 2}, + 3 + } + { + {911, 2}, + {979, 2}, + {918, 2}, + 3 + } + { + {1083, 2, "edge" "collidable"}, + {921, 2}, + {751, 2}, + 3 + } + { + {911, 2}, + {918, 2, "edge" "collidable"}, + {914, 2, "edge" "collidable"}, + 3 + } + { + {762, 2}, + {756, 2}, + {882, 2}, + 3 + } + { + {986, 2, "edge" "collidable"}, + {1018, 2}, + {999, 2}, + 3 + } + { + {827, 2}, + {957, 2}, + {964, 2}, + 3 + } + { + {993, 2, "edge" "collidable"}, + {747, 2}, + {856, 2}, + 3 + } + { + {1001, 2, "edge" "collidable"}, + {1000, 2, "edge" "collidable"}, + {1030, 2}, + 3 + } + { + {1028, 2, "edge" "collidable"}, + {1030, 2}, + {1001, 2}, + 3 + } + { + {1058, 2}, + {922, 2, "edge" "collidable"}, + {939, 2, "edge" "collidable"}, + 3 + } + { + {943, 2}, + {931, 2, "edge" "collidable"}, + {933, 2}, + 3 + } + { + {878, 2}, + {780, 2, "edge" "collidable"}, + {864, 2}, + 3 + } + { + {1083, 2}, + {751, 2, "edge" "collidable"}, + {766, 2}, + 3 + } + { + {927, 2}, + {767, 2}, + {894, 2}, + 3 + } + { + {798, 2}, + {859, 2, "edge" "collidable"}, + {1084, 2}, + 3 + } + { + {1061, 2}, + {739, 2, "edge" "collidable"}, + {1008, 2}, + 3 + } + { + {848, 2}, + {989, 2, "edge" "collidable"}, + {738, 2, "edge" "collidable"}, + 3 + } + { + {758, 2}, + {895, 2, "edge" "collidable"}, + {751, 2}, + 3 + } + { + {1024, 2, "edge" "collidable"}, + {1017, 2, "edge" "collidable"}, + {1016, 2}, + 3 + } + { + {1028, 2, "edge" "collidable"}, + {1024, 2}, + {1007, 2}, + 3 + } + { + {1007, 2}, + {1024, 2}, + {1016, 2}, + 3 + } + { + {1049, 2, "edge" "collidable"}, + {1060, 2}, + {1057, 2, "edge" "collidable"}, + 3 + } + { + {878, 2, "edge" "collidable"}, + {972, 2}, + {780, 2}, + 3 + } + { + {827, 2}, + {868, 2, "edge" "collidable"}, + {957, 2}, + 3 + } + { + {1050, 2}, + {865, 2, "edge" "collidable"}, + {736, 2}, + 3 + } + { + {827, 2}, + {964, 2, "edge" "collidable"}, + {1004, 2, "edge" "collidable"}, + 3 + } + { + {1007, 2}, + {1016, 2, "edge" "collidable"}, + {1014, 2, "edge" "collidable"}, + 3 + } + { + {984, 2, "edge" "collidable"}, + {863, 2, "edge" "collidable"}, + {956, 2}, + 3 + } + { + {848, 2, "edge" "collidable"}, + {879, 2}, + {753, 2}, + 3 + } + { + {1028, 2}, + {1007, 2, "edge" "collidable"}, + {1003, 2}, + 3 + } + { + {893, 2, "edge" "collidable"}, + {756, 2}, + {762, 2}, + 3 + } + { + {1001, 2}, + {1028, 2}, + {1003, 2}, + 3 + } + { + {778, 2}, + {941, 2, "edge" "collidable"}, + {986, 2}, + 3 + } + { + {991, 2}, + {791, 2, "edge" "collidable"}, + {821, 2}, + 3 + } + { + {842, 2}, + {735, 2, "edge" "collidable"}, + {982, 2}, + 3 + } + { + {1001, 2}, + {1003, 2, "edge" "collidable"}, + {1002, 2, "edge" "collidable"}, + 3 + } + { + {1058, 2, "edge" "collidable"}, + {966, 2}, + {757, 2}, + 3 + } + { + {776, 2, "edge" "collidable"}, + {823, 2}, + {745, 2, "edge" "collidable"}, + 3 + } + { + {793, 2, "edge" "collidable"}, + {1050, 2}, + {857, 2, "edge" "collidable"}, + 3 + } + { + {1035, 2, "edge" "collidable"}, + {1031, 2, "edge" "collidable"}, + {1051, 2}, + 3 + } + { + {757, 2, "edge" "collidable"}, + {846, 2}, + {823, 2}, + 3 + } + { + {969, 2, "edge" "collidable"}, + {890, 2, "edge" "collidable"}, + {745, 2}, + 3 + } + { + {968, 2, "edge" "collidable"}, + {971, 2}, + {859, 2}, + 3 + } + { + {1026, 2, "edge" "collidable"}, + {954, 2, "edge" "collidable"}, + {877, 2}, + 3 + } + { + {965, 2}, + {895, 2}, + {995, 2}, + 3 + } + { + {975, 2}, + {926, 2, "edge" "collidable"}, + {859, 2}, + 3 + } + { + {851, 2, "edge" "collidable"}, + {1020, 2, "edge" "collidable"}, + {788, 2}, + 3 + } + { + {927, 2}, + {894, 2, "edge" "collidable"}, + {886, 2, "edge" "collidable"}, + 3 + } + { + {747, 2, "edge" "collidable"}, + {900, 2}, + {980, 2}, + 3 + } + { + {921, 2, "edge" "collidable"}, + {758, 2}, + {751, 2}, + 3 + } + { + {794, 2}, + {1083, 2}, + {766, 2}, + 3 + } + { + {1059, 2, "edge" "collidable"}, + {1055, 2}, + {1051, 2}, + 3 + } + { + {848, 2}, + {753, 2}, + {989, 2}, + 3 + } + { + {1059, 2}, + {1051, 2, "edge" "collidable"}, + {1047, 2}, + 3 + } + { + {770, 2, "edge" "collidable"}, + {964, 2}, + {847, 2}, + 3 + } + { + {892, 2}, + {1040, 2}, + {821, 2}, + 3 + } + { + {1035, 2}, + {1073, 2, "edge" "collidable"}, + {1071, 2}, + 3 + } + { + {744, 2, "edge" "collidable"}, + {740, 2}, + {789, 2}, + 3 + } + { + {778, 2}, + {933, 2, "edge" "collidable"}, + {941, 2}, + 3 + } + { + {1039, 2, "edge" "collidable"}, + {1035, 2}, + {1071, 2}, + 3 + } + { + {891, 2}, + {999, 2, "edge" "collidable"}, + {883, 2, "edge" "collidable"}, + 3 + } + { + {1062, 2, "edge" "collidable"}, + {1059, 2}, + {1047, 2}, + 3 + } + { + {1039, 2}, + {1071, 2, "edge" "collidable"}, + {1067, 2}, + 3 + } + { + {764, 2}, + {773, 2, "edge" "collidable"}, + {768, 2, "edge" "collidable"}, + 3 + } + { + {877, 2, "edge" "collidable"}, + {929, 2}, + {737, 2}, + 3 + } + { + {1008, 2, "edge" "collidable"}, + {772, 2}, + {1027, 2}, + 3 + } + { + {749, 2}, + {775, 2, "edge" "collidable"}, + {773, 2}, + 3 + } + { + {924, 2}, + {742, 2, "edge" "collidable"}, + {905, 2}, + 3 + } + { + {794, 2, "edge" "collidable"}, + {965, 2}, + {1083, 2}, + 3 + } + { + {1041, 2, "edge" "collidable"}, + {1039, 2}, + {1067, 2}, + 3 + } + { + {826, 2, "edge" "collidable"}, + {998, 2}, + {1033, 2}, + 3 + } + { + {1061, 2}, + {1008, 2}, + {1076, 2}, + 3 + } + { + {913, 2}, + {844, 2, "edge" "collidable"}, + {791, 2}, + 3 + } + { + {1041, 2}, + {1067, 2, "edge" "collidable"}, + {1062, 2}, + 3 + } + { + {772, 2}, + {880, 2, "edge" "collidable"}, + {1027, 2}, + 3 + } + { + {1047, 2}, + {1062, 2}, + {1041, 2}, + 3 + } + { + {899, 2, "edge" "collidable"}, + {924, 2}, + {905, 2}, + 3 + } + { + {1041, 2}, + {1047, 2, "edge" "collidable"}, + {1044, 2, "edge" "collidable"}, + 3 + } + { + {869, 2}, + {781, 2, "edge" "collidable"}, + {997, 2, "edge" "collidable"}, + 3 + } + { + {879, 2, "edge" "collidable"}, + {850, 2, "edge" "collidable"}, + {753, 2}, + 3 + } + { + {1080, 2, "edge" "collidable"}, + {1079, 2, "edge" "collidable"}, + {1078, 2}, + 3 + } + { + {1080, 2}, + {1078, 2, "edge" "collidable"}, + {1064, 2}, + 3 + } + { + {1015, 2}, + {853, 2}, + {946, 2}, + 3 + } + { + {1025, 2, "edge" "collidable"}, + {799, 2, "edge" "collidable"}, + {944, 2}, + 3 + } + { + {1056, 2}, + {828, 2, "edge" "collidable"}, + {739, 2}, + 3 + } + { + {1080, 2}, + {1064, 2}, + {904, 2}, + 3 + } + { + {913, 2, "edge" "collidable"}, + {985, 2}, + {844, 2}, + 3 + } + { + {865, 2}, + {994, 2}, + {1011, 2, "edge" "collidable"}, + 3 + } + { + {904, 2}, + {1064, 2, "edge" "collidable"}, + {1053, 2}, + 3 + } + { + {761, 2}, + {1037, 2, "edge" "collidable"}, + {960, 2}, + 3 + } + { + {861, 2, "edge" "collidable"}, + {748, 2}, + {839, 2}, + 3 + } + { + {924, 2, "edge" "collidable"}, + {1042, 2, "edge" "collidable"}, + {742, 2}, + 3 + } + { + {949, 2}, + {797, 2, "edge" "collidable"}, + {906, 2}, + 3 + } + { + {904, 2}, + {1053, 2}, + {1005, 2, "edge" "collidable"}, + 3 + } + { + {927, 2, "edge" "collidable"}, + {794, 2}, + {766, 2}, + 3 + } + { + {746, 2}, + {783, 2, "edge" "collidable"}, + {779, 2}, + 3 + } + { + {1080, 2}, + {904, 2, "edge" "collidable"}, + {915, 2}, + 3 + } + { + {1060, 2}, + {946, 2, "edge" "collidable"}, + {1057, 2}, + 3 + } + { + {1005, 2}, + {1053, 2, "edge" "collidable"}, + {1065, 2}, + 3 + } + { + {953, 2, "edge" "collidable"}, + {1005, 2}, + {1065, 2}, + 3 + } + { + {1061, 2}, + {1076, 2, "edge" "collidable"}, + {1019, 2, "edge" "collidable"}, + 3 + } + { + {1060, 2, "edge" "collidable"}, + {1015, 2}, + {946, 2}, + 3 + } + { + {1045, 2, "edge" "collidable"}, + {990, 2, "edge" "collidable"}, + {898, 2}, + 3 + } + { + {999, 2}, + {1018, 2}, + {795, 2, "edge" "collidable"}, + 3 + } + { + {884, 2, "edge" "collidable"}, + {1036, 2}, + {750, 2}, + 3 + } + { + {1069, 2}, + {1021, 2, "edge" "collidable"}, + {777, 2, "edge" "collidable"}, + 3 + } + { + {1045, 2}, + {898, 2, "edge" "collidable"}, + {916, 2}, + 3 + } + { + {1009, 2, "edge" "collidable"}, + {953, 2}, + {1065, 2}, + 3 + } + { + {737, 2, "edge" "collidable"}, + {1026, 2}, + {877, 2}, + 3 + } + { + {861, 2}, + {839, 2}, + {935, 2}, + 3 + } + { + {764, 2}, + {755, 2}, + {773, 2}, + 3 + } + { + {1009, 2}, + {1065, 2, "edge" "collidable"}, + {1048, 2}, + 3 + } + { + {1066, 2}, + {1029, 2, "edge" "collidable"}, + {1070, 2}, + 3 + } + { + {916, 2, "edge" "collidable"}, + {852, 2, "edge" "collidable"}, + {774, 2}, + 3 + } + { + {929, 2, "edge" "collidable"}, + {855, 2, "edge" "collidable"}, + {737, 2}, + 3 + } + { + {927, 2}, + {752, 2, "edge" "collidable"}, + {767, 2}, + 3 + } + { + {1081, 2, "edge" "collidable"}, + {1080, 2}, + {915, 2}, + 3 + } + { + {1081, 2}, + {915, 2, "edge" "collidable"}, + {945, 2}, + 3 + } + { + {764, 2, "edge" "collidable"}, + {759, 2, "edge" "collidable"}, + {755, 2}, + 3 + } + { + {1054, 2}, + {1063, 2}, + {788, 2, "edge" "collidable"}, + 3 + } + { + {1050, 2}, + {736, 2}, + {857, 2}, + 3 + } + { + {756, 2, "edge" "collidable"}, + {1074, 2, "edge" "collidable"}, + {882, 2}, + 3 + } + { + {887, 2}, + {940, 2}, + {791, 2}, + 3 + } + { + {945, 2, "edge" "collidable"}, + {1009, 2}, + {1048, 2}, + 3 + } + { + {753, 2, "edge" "collidable"}, + {1063, 2}, + {1054, 2}, + 3 + } + { + {916, 2}, + {774, 2, "edge" "collidable"}, + {754, 2}, + 3 + } + { + {884, 2}, + {750, 2, "edge" "collidable"}, + {787, 2, "edge" "collidable"}, + 3 + } + { + {1081, 2}, + {945, 2}, + {1048, 2}, + 3 + } + { + {753, 2}, + {1054, 2, "edge" "collidable"}, + {989, 2}, + 3 + } + { + {912, 2, "edge" "collidable"}, + {984, 2}, + {822, 2}, + 3 + } + { + {940, 2, "edge" "collidable"}, + {913, 2}, + {791, 2}, + 3 + } + { + {1076, 2}, + {1008, 2}, + {1027, 2, "edge" "collidable"}, + 3 + } + { + {899, 2}, + {905, 2}, + {864, 2}, + 3 + } + { + {873, 2, "edge" "collidable"}, + {1081, 2}, + {1048, 2, "edge" "collidable"}, + 3 + } + { + {965, 2, "edge" "collidable"}, + {786, 2, "edge" "collidable"}, + {895, 2}, + 3 + } + { + {1045, 2}, + {916, 2}, + {754, 2}, + 3 + } + { + {792, 2, "edge" "collidable"}, + {1045, 2}, + {754, 2, "edge" "collidable"}, + 3 + } + { + {1055, 2, "edge" "collidable"}, + {1073, 2}, + {1035, 2}, + 3 + } + { + {1035, 2}, + {1051, 2}, + {1055, 2}, + 3 + } + { + {865, 2}, + {1050, 2}, + {994, 2}, + 3 + } + { + {912, 2}, + {968, 2}, + {798, 2, "edge" "collidable"}, + 3 + } + { + {968, 2}, + {859, 2}, + {798, 2}, + 3 + } + # Mesh "Mesh.001" + { + {1190, 2}, + {1095, 2, "edge" "collidable"}, + {1196, 2}, + 0 + } + { + {1097, 2, "edge" "collidable"}, + {1190, 2}, + {1196, 2}, + 0 + } + { + {1167, 2, "edge" "collidable"}, + {1134, 2}, + {1186, 2}, + 0 + } + { + {1134, 2}, + {1194, 2, "edge" "collidable"}, + {1186, 2}, + 0 + } + { + {1146, 2, "edge" "collidable"}, + {1126, 2}, + {1139, 2}, + 0 + } + { + {1092, 2, "edge" "collidable"}, + {1144, 2}, + {1192, 2}, + 0 + } + { + {1114, 2, "edge" "collidable"}, + {1206, 2}, + {1124, 2}, + 0 + } + { + {1206, 2}, + {1147, 2, "edge" "collidable"}, + {1124, 2}, + 0 + } + { + {1116, 2, "edge" "collidable"}, + {1101, 2}, + {1129, 2}, + 0 + } + { + {1184, 2, "edge" "collidable"}, + {1182, 2}, + {1107, 2}, + 0 + } + { + {1144, 2}, + {1121, 2, "edge" "collidable"}, + {1192, 2}, + 0 + } + { + {1187, 2}, + {1178, 2, "edge" "collidable"}, + {1104, 2}, + 0 + } + { + {1093, 2, "edge" "collidable"}, + {1187, 2}, + {1104, 2}, + 0 + } + { + {1203, 2}, + {1156, 2, "edge" "collidable"}, + {1099, 2}, + 0 + } + { + {1109, 2, "edge" "collidable"}, + {1203, 2}, + {1099, 2}, + 0 + } + { + {1128, 2}, + {1137, 2, "edge" "collidable"}, + {1201, 2}, + 0 + } + { + {1132, 2, "edge" "collidable"}, + {1128, 2}, + {1201, 2}, + 0 + } + { + {1182, 2, "edge" "collidable"}, + {1122, 2}, + {1091, 2}, + 0 + } + { + {1166, 2, "edge" "collidable"}, + {1167, 2}, + {1088, 2}, + 0 + } + { + {1168, 2, "edge" "collidable"}, + {1152, 2}, + {1180, 2}, + 0 + } + { + {1152, 2}, + {1179, 2, "edge" "collidable"}, + {1180, 2}, + 0 + } + { + {1163, 2}, + {1200, 2, "edge" "collidable"}, + {1135, 2}, + 0 + } + { + {1185, 2, "edge" "collidable"}, + {1163, 2}, + {1135, 2}, + 0 + } + { + {1176, 2}, + {1150, 2, "edge" "collidable"}, + {1178, 2}, + 0 + } + { + {1112, 2}, + {1191, 2, "edge" "collidable"}, + {1154, 2}, + 0 + } + { + {1090, 2, "edge" "collidable"}, + {1097, 2}, + {1197, 2}, + 0 + } + { + {1097, 2}, + {1196, 2, "edge" "collidable"}, + {1197, 2}, + 0 + } + { + {1138, 2}, + {1123, 2, "edge" "collidable"}, + {1160, 2}, + 0 + } + { + {1106, 2, "edge" "collidable"}, + {1138, 2}, + {1160, 2}, + 0 + } + { + {1130, 2, "edge" "collidable"}, + {1185, 2}, + {1096, 2}, + 0 + } + { + {1185, 2}, + {1135, 2, "edge" "collidable"}, + {1096, 2}, + 0 + } + { + {1101, 2, "edge" "collidable"}, + {1103, 2}, + {1162, 2}, + 0 + } + { + {1103, 2}, + {1108, 2, "edge" "collidable"}, + {1162, 2}, + 0 + } + { + {1205, 2, "edge" "collidable"}, + {1086, 2}, + {1141, 2}, + 0 + } + { + {1119, 2}, + {1086, 2, "edge" "collidable"}, + {1140, 2}, + 0 + } + { + {1165, 2, "edge" "collidable"}, + {1151, 2}, + {1198, 2}, + 0 + } + { + {1126, 2}, + {1105, 2, "edge" "collidable"}, + {1139, 2}, + 0 + } + { + {1176, 2, "edge" "collidable"}, + {1102, 2}, + {1150, 2}, + 0 + } + { + {1102, 2}, + {1131, 2, "edge" "collidable"}, + {1150, 2}, + 0 + } + { + {1169, 2}, + {1136, 2, "edge" "collidable"}, + {1156, 2}, + 0 + } + { + {1149, 2, "edge" "collidable"}, + {1118, 2}, + {1172, 2}, + 0 + } + { + {1134, 2, "edge" "collidable"}, + {1183, 2}, + {1194, 2}, + 0 + } + { + {1183, 2}, + {1115, 2, "edge" "collidable"}, + {1194, 2}, + 0 + } + { + {1102, 2, "edge" "collidable"}, + {1106, 2}, + {1131, 2}, + 0 + } + { + {1106, 2}, + {1160, 2, "edge" "collidable"}, + {1131, 2}, + 0 + } + { + {1114, 2}, + {1124, 2, "edge" "collidable"}, + {1100, 2}, + 0 + } + { + {1174, 2}, + {1100, 2, "edge" "collidable"}, + {1125, 2}, + 0 + } + { + {1092, 2}, + {1192, 2, "edge" "collidable"}, + {1200, 2}, + 0 + } + { + {1140, 2}, + {1177, 2, "edge" "collidable"}, + {1119, 2}, + 0 + } + { + {1089, 2, "edge" "collidable"}, + {1110, 2}, + {1098, 2, "edge" "collidable"}, + 0 + } + { + {1110, 2}, + {1171, 2, "edge" "collidable"}, + {1098, 2}, + 0 + } + { + {1140, 2, "edge" "collidable"}, + {1207, 2}, + {1177, 2}, + 0 + } + { + {1187, 2, "edge" "collidable"}, + {1176, 2}, + {1178, 2}, + 0 + } + { + {1155, 2, "edge" "collidable"}, + {1087, 2}, + {1133, 2}, + 0 + } + { + {1152, 2, "edge" "collidable"}, + {1189, 2}, + {1179, 2}, + 0 + } + { + {1189, 2}, + {1195, 2, "edge" "collidable"}, + {1179, 2}, + 0 + } + { + {1101, 2}, + {1162, 2, "edge" "collidable"}, + {1129, 2}, + 0 + } + { + {1203, 2, "edge" "collidable"}, + {1169, 2}, + {1156, 2}, + 0 + } + { + {1161, 2, "edge" "collidable"}, + {1117, 2}, + {1164, 2}, + 0 + } + { + {1117, 2}, + {1111, 2, "edge" "collidable"}, + {1164, 2}, + 0 + } + { + {1151, 2, "edge" "collidable"}, + {1155, 2}, + {1193, 2}, + 0 + } + { + {1155, 2}, + {1133, 2, "edge" "collidable"}, + {1193, 2}, + 0 + } + { + {1138, 2, "edge" "collidable"}, + {1116, 2}, + {1123, 2}, + 0 + } + { + {1116, 2}, + {1129, 2, "edge" "collidable"}, + {1123, 2}, + 0 + } + { + {1199, 2, "edge" "collidable"}, + {1181, 2}, + {1173, 2}, + 0 + } + { + {1181, 2}, + {1154, 2, "edge" "collidable"}, + {1173, 2}, + 0 + } + { + {1128, 2, "edge" "collidable"}, + {1142, 2}, + {1137, 2}, + 0 + } + { + {1142, 2}, + {1157, 2, "edge" "collidable"}, + {1137, 2}, + 0 + } + { + {1205, 2}, + {1141, 2, "edge" "collidable"}, + {1145, 2}, + 0 + } + { + {1087, 2}, + {1175, 2, "edge" "collidable"}, + {1133, 2}, + 0 + } + { + {1174, 2, "edge" "collidable"}, + {1114, 2}, + {1100, 2}, + 0 + } + { + {1151, 2}, + {1193, 2, "edge" "collidable"}, + {1198, 2}, + 0 + } + { + {1132, 2}, + {1201, 2, "edge" "collidable"}, + {1105, 2}, + 0 + } + { + {1126, 2, "edge" "collidable"}, + {1132, 2}, + {1105, 2}, + 0 + } + { + {1130, 2}, + {1096, 2, "edge" "collidable"}, + {1115, 2}, + 0 + } + { + {1183, 2, "edge" "collidable"}, + {1130, 2}, + {1115, 2}, + 0 + } + { + {1141, 2}, + {1086, 2}, + {1119, 2, "edge" "collidable"}, + 0 + } + { + {1163, 2, "edge" "collidable"}, + {1092, 2}, + {1200, 2}, + 0 + } + { + {1167, 2}, + {1186, 2, "edge" "collidable"}, + {1088, 2}, + 0 + } + { + {1090, 2}, + {1197, 2, "edge" "collidable"}, + {1147, 2}, + 0 + } + { + {1148, 2}, + {1113, 2, "edge" "collidable"}, + {1195, 2}, + 0 + } + { + {1189, 2, "edge" "collidable"}, + {1148, 2}, + {1195, 2}, + 0 + } + { + {1120, 2, "edge" "collidable"}, + {1205, 2}, + {1145, 2}, + 0 + } + { + {1209, 2, "edge" "collidable"}, + {1210, 2, "edge" "collidable"}, + {1208, 2}, + 0 + } + { + {1209, 2}, + {1208, 2, "edge" "collidable"}, + {1136, 2}, + 0 + } + { + {1136, 2}, + {1169, 2, "edge" "collidable"}, + {1209, 2}, + 0 + } + { + {1117, 2, "edge" "collidable"}, + {1146, 2}, + {1111, 2}, + 0 + } + { + {1146, 2}, + {1139, 2, "edge" "collidable"}, + {1111, 2}, + 0 + } + { + {1184, 2}, + {1107, 2, "edge" "collidable"}, + {1175, 2}, + 0 + } + { + {1159, 2}, + {1204, 2, "edge" "collidable"}, + {1095, 2}, + 0 + } + { + {1112, 2, "edge" "collidable"}, + {1143, 2}, + {1191, 2}, + 0 + } + { + {1190, 2, "edge" "collidable"}, + {1159, 2}, + {1095, 2}, + 0 + } + { + {1143, 2}, + {1170, 2, "edge" "collidable"}, + {1191, 2}, + 0 + } + { + {1087, 2, "edge" "collidable"}, + {1184, 2}, + {1175, 2}, + 0 + } + { + {1093, 2}, + {1104, 2, "edge" "collidable"}, + {1094, 2}, + 0 + } + { + {1127, 2, "edge" "collidable"}, + {1093, 2}, + {1094, 2}, + 0 + } + { + {1202, 2}, + {1188, 2, "edge" "collidable"}, + {1108, 2}, + 0 + } + { + {1103, 2, "edge" "collidable"}, + {1202, 2}, + {1108, 2}, + 0 + } + { + {1122, 2, "edge" "collidable"}, + {1174, 2}, + {1125, 2}, + 0 + } + { + {1127, 2}, + {1094, 2, "edge" "collidable"}, + {1204, 2}, + 0 + } + { + {1159, 2, "edge" "collidable"}, + {1127, 2}, + {1204, 2}, + 0 + } + { + {1110, 2, "edge" "collidable"}, + {1166, 2}, + {1171, 2}, + 0 + } + { + {1166, 2}, + {1088, 2, "edge" "collidable"}, + {1171, 2}, + 0 + } + { + {1149, 2}, + {1172, 2, "edge" "collidable"}, + {1121, 2}, + 0 + } + { + {1144, 2, "edge" "collidable"}, + {1149, 2}, + {1121, 2}, + 0 + } + { + {1181, 2, "edge" "collidable"}, + {1112, 2}, + {1154, 2}, + 0 + } + { + {1207, 2}, + {1158, 2, "edge" "collidable"}, + {1177, 2}, + 0 + } + { + {1142, 2, "edge" "collidable"}, + {1109, 2}, + {1157, 2}, + 0 + } + { + {1109, 2}, + {1099, 2, "edge" "collidable"}, + {1157, 2}, + 0 + } + { + {1182, 2}, + {1091, 2, "edge" "collidable"}, + {1107, 2}, + 0 + } + { + {1148, 2, "edge" "collidable"}, + {1165, 2}, + {1113, 2}, + 0 + } + { + {1165, 2}, + {1198, 2, "edge" "collidable"}, + {1113, 2}, + 0 + } + { + {1143, 2, "edge" "collidable"}, + {1120, 2}, + {1170, 2}, + 0 + } + { + {1168, 2}, + {1180, 2, "edge" "collidable"}, + {1158, 2}, + 0 + } + { + {1207, 2, "edge" "collidable"}, + {1168, 2}, + {1158, 2}, + 0 + } + { + {1120, 2}, + {1145, 2, "edge" "collidable"}, + {1170, 2}, + 0 + } + { + {1206, 2, "edge" "collidable"}, + {1090, 2}, + {1147, 2}, + 0 + } + { + {1122, 2}, + {1125, 2, "edge" "collidable"}, + {1091, 2}, + 0 + } + { + {1118, 2}, + {1153, 2, "edge" "collidable"}, + {1172, 2}, + 0 + } + { + {1118, 2, "edge" "collidable"}, + {1199, 2}, + {1153, 2}, + 0 + } + { + {1199, 2}, + {1173, 2, "edge" "collidable"}, + {1153, 2}, + 0 + } + { + {1202, 2, "edge" "collidable"}, + {1161, 2}, + {1188, 2}, + 0 + } + { + {1161, 2}, + {1164, 2, "edge" "collidable"}, + {1188, 2}, + 0 + } + # Mesh "Mesh.002" + { + {1328, 2, "edge" "collidable"}, + {1215, 2}, + {1212, 2}, + 1 + } + { + {1215, 2, "edge" "collidable"}, + {1211, 2, "edge" "collidable"}, + {1212, 2}, + 1 + } + { + {1221, 2, "edge" "collidable"}, + {1328, 2}, + {1213, 2}, + 1 + } + { + {1328, 2}, + {1212, 2, "edge" "collidable"}, + {1213, 2}, + 1 + } + { + {1378, 2, "edge" "collidable"}, + {1221, 2}, + {1214, 2}, + 1 + } + { + {1221, 2}, + {1213, 2, "edge" "collidable"}, + {1214, 2}, + 1 + } + { + {1263, 2, "edge" "collidable"}, + {1378, 2}, + {1216, 2}, + 1 + } + { + {1378, 2}, + {1214, 2, "edge" "collidable"}, + {1216, 2}, + 1 + } + { + {1266, 2, "edge" "collidable"}, + {1263, 2}, + {1217, 2}, + 1 + } + { + {1263, 2}, + {1216, 2, "edge" "collidable"}, + {1217, 2}, + 1 + } + { + {1322, 2, "edge" "collidable"}, + {1266, 2}, + {1218, 2}, + 1 + } + { + {1266, 2}, + {1217, 2, "edge" "collidable"}, + {1218, 2}, + 1 + } + { + {1356, 2, "edge" "collidable"}, + {1322, 2}, + {1220, 2}, + 1 + } + { + {1322, 2}, + {1218, 2, "edge" "collidable"}, + {1220, 2}, + 1 + } + { + {1382, 2}, + {1326, 2, "edge" "collidable"}, + {1327, 2}, + 1 + } + { + {1330, 2, "edge" "collidable"}, + {1382, 2}, + {1327, 2}, + 1 + } + { + {1367, 2, "edge" "collidable"}, + {1356, 2}, + {1222, 2}, + 1 + } + { + {1356, 2}, + {1220, 2, "edge" "collidable"}, + {1222, 2}, + 1 + } + { + {1381, 2, "edge" "collidable"}, + {1290, 2}, + {1341, 2}, + 1 + } + { + {1290, 2}, + {1340, 2, "edge" "collidable"}, + {1341, 2}, + 1 + } + { + {1393, 2}, + {1365, 2, "edge" "collidable"}, + {1368, 2}, + 1 + } + { + {1253, 2, "edge" "collidable"}, + {1367, 2}, + {1224, 2}, + 1 + } + { + {1367, 2}, + {1222, 2, "edge" "collidable"}, + {1224, 2}, + 1 + } + { + {1243, 2, "edge" "collidable"}, + {1253, 2}, + {1225, 2}, + 1 + } + { + {1253, 2}, + {1224, 2, "edge" "collidable"}, + {1225, 2}, + 1 + } + { + {1247, 2}, + {1316, 2, "edge" "collidable"}, + {1317, 2}, + 1 + } + { + {1389, 2, "edge" "collidable"}, + {1243, 2}, + {1226, 2}, + 1 + } + { + {1243, 2}, + {1225, 2, "edge" "collidable"}, + {1226, 2}, + 1 + } + { + {1383, 2, "edge" "collidable"}, + {1389, 2}, + {1227, 2}, + 1 + } + { + {1389, 2}, + {1226, 2, "edge" "collidable"}, + {1227, 2}, + 1 + } + { + {1271, 2, "edge" "collidable"}, + {1383, 2}, + {1228, 2}, + 1 + } + { + {1383, 2}, + {1227, 2, "edge" "collidable"}, + {1228, 2}, + 1 + } + { + {1386, 2}, + {1370, 2, "edge" "collidable"}, + {1372, 2}, + 1 + } + { + {1395, 2, "edge" "collidable"}, + {1386, 2}, + {1372, 2, "edge" "collidable"}, + 1 + } + { + {1294, 2, "edge" "collidable"}, + {1271, 2}, + {1229, 2}, + 1 + } + { + {1271, 2}, + {1228, 2, "edge" "collidable"}, + {1229, 2}, + 1 + } + { + {1394, 2, "edge" "collidable"}, + {1377, 2}, + {1331, 2}, + 1 + } + { + {1377, 2}, + {1329, 2, "edge" "collidable"}, + {1331, 2}, + 1 + } + { + {1237, 2, "edge" "collidable"}, + {1294, 2}, + {1230, 2}, + 1 + } + { + {1294, 2}, + {1229, 2, "edge" "collidable"}, + {1230, 2}, + 1 + } + { + {1268, 2, "edge" "collidable"}, + {1237, 2}, + {1232, 2}, + 1 + } + { + {1237, 2}, + {1230, 2, "edge" "collidable"}, + {1232, 2}, + 1 + } + { + {1376, 2}, + {1368, 2, "edge" "collidable"}, + {1370, 2}, + 1 + } + { + {1386, 2, "edge" "collidable"}, + {1376, 2}, + {1370, 2}, + 1 + } + { + {1290, 2, "edge" "collidable"}, + {1359, 2}, + {1340, 2}, + 1 + } + { + {1359, 2}, + {1338, 2, "edge" "collidable"}, + {1340, 2}, + 1 + } + { + {1392, 2, "edge" "collidable"}, + {1268, 2}, + {1233, 2}, + 1 + } + { + {1268, 2}, + {1232, 2, "edge" "collidable"}, + {1233, 2}, + 1 + } + { + {1284, 2, "edge" "collidable"}, + {1394, 2}, + {1333, 2}, + 1 + } + { + {1394, 2}, + {1331, 2, "edge" "collidable"}, + {1333, 2}, + 1 + } + { + {1369, 2, "edge" "collidable"}, + {1392, 2}, + {1234, 2}, + 1 + } + { + {1392, 2}, + {1233, 2, "edge" "collidable"}, + {1234, 2}, + 1 + } + { + {1361, 2}, + {1317, 2, "edge" "collidable"}, + {1319, 2}, + 1 + } + { + {1379, 2, "edge" "collidable"}, + {1361, 2}, + {1319, 2}, + 1 + } + { + {1299, 2}, + {1323, 2, "edge" "collidable"}, + {1324, 2}, + 1 + } + { + {1276, 2, "edge" "collidable"}, + {1299, 2}, + {1324, 2}, + 1 + } + { + {1373, 2, "edge" "collidable"}, + {1369, 2}, + {1236, 2}, + 1 + } + { + {1369, 2}, + {1234, 2, "edge" "collidable"}, + {1236, 2}, + 1 + } + { + {1235, 2, "edge" "collidable"}, + {1373, 2}, + {1238, 2}, + 1 + } + { + {1373, 2}, + {1236, 2, "edge" "collidable"}, + {1238, 2}, + 1 + } + { + {1275, 2}, + {1349, 2, "edge" "collidable"}, + {1351, 2}, + 1 + } + { + {1313, 2, "edge" "collidable"}, + {1275, 2}, + {1351, 2}, + 1 + } + { + {1371, 2, "edge" "collidable"}, + {1235, 2}, + {1241, 2}, + 1 + } + { + {1235, 2}, + {1238, 2, "edge" "collidable"}, + {1241, 2}, + 1 + } + { + {1278, 2, "edge" "collidable"}, + {1371, 2}, + {1244, 2}, + 1 + } + { + {1371, 2}, + {1241, 2, "edge" "collidable"}, + {1244, 2}, + 1 + } + { + {1310, 2, "edge" "collidable"}, + {1278, 2}, + {1245, 2}, + 1 + } + { + {1278, 2}, + {1244, 2, "edge" "collidable"}, + {1245, 2}, + 1 + } + { + {1377, 2, "edge" "collidable"}, + {1330, 2}, + {1329, 2}, + 1 + } + { + {1330, 2}, + {1327, 2, "edge" "collidable"}, + {1329, 2}, + 1 + } + { + {1336, 2, "edge" "collidable"}, + {1384, 2}, + {1355, 2}, + 1 + } + { + {1384, 2}, + {1354, 2, "edge" "collidable"}, + {1355, 2}, + 1 + } + { + {1239, 2, "edge" "collidable"}, + {1310, 2}, + {1246, 2}, + 1 + } + { + {1310, 2}, + {1245, 2, "edge" "collidable"}, + {1246, 2}, + 1 + } + { + {1387, 2, "edge" "collidable"}, + {1332, 2}, + {1321, 2}, + 1 + } + { + {1364, 2, "edge" "collidable"}, + {1239, 2}, + {1248, 2}, + 1 + } + { + {1239, 2}, + {1246, 2, "edge" "collidable"}, + {1248, 2}, + 1 + } + { + {1346, 2, "edge" "collidable"}, + {1364, 2}, + {1251, 2}, + 1 + } + { + {1364, 2}, + {1248, 2, "edge" "collidable"}, + {1251, 2}, + 1 + } + { + {1346, 2}, + {1251, 2, "edge" "collidable"}, + {1254, 2}, + 1 + } + { + {1242, 2, "edge" "collidable"}, + {1346, 2}, + {1254, 2}, + 1 + } + { + {1242, 2}, + {1254, 2, "edge" "collidable"}, + {1256, 2}, + 1 + } + { + {1360, 2, "edge" "collidable"}, + {1242, 2}, + {1257, 2}, + 1 + } + { + {1242, 2}, + {1256, 2, "edge" "collidable"}, + {1257, 2}, + 1 + } + { + {1219, 2}, + {1347, 2, "edge" "collidable"}, + {1349, 2}, + 1 + } + { + {1366, 2, "edge" "collidable"}, + {1284, 2}, + {1335, 2}, + 1 + } + { + {1363, 2, "edge" "collidable"}, + {1360, 2}, + {1258, 2}, + 1 + } + { + {1360, 2}, + {1257, 2, "edge" "collidable"}, + {1258, 2}, + 1 + } + { + {1293, 2, "edge" "collidable"}, + {1363, 2}, + {1260, 2}, + 1 + } + { + {1363, 2}, + {1258, 2, "edge" "collidable"}, + {1260, 2}, + 1 + } + { + {1299, 2, "edge" "collidable"}, + {1387, 2}, + {1323, 2}, + 1 + } + { + {1387, 2}, + {1321, 2, "edge" "collidable"}, + {1323, 2}, + 1 + } + { + {1276, 2}, + {1324, 2, "edge" "collidable"}, + {1325, 2}, + 1 + } + { + {1259, 2, "edge" "collidable"}, + {1276, 2}, + {1325, 2}, + 1 + } + { + {1375, 2, "edge" "collidable"}, + {1293, 2}, + {1262, 2}, + 1 + } + { + {1293, 2}, + {1260, 2, "edge" "collidable"}, + {1262, 2}, + 1 + } + { + {1345, 2, "edge" "collidable"}, + {1375, 2}, + {1264, 2}, + 1 + } + { + {1375, 2}, + {1262, 2, "edge" "collidable"}, + {1264, 2}, + 1 + } + { + {1273, 2, "edge" "collidable"}, + {1345, 2}, + {1265, 2}, + 1 + } + { + {1345, 2}, + {1264, 2, "edge" "collidable"}, + {1265, 2}, + 1 + } + { + {1281, 2, "edge" "collidable"}, + {1273, 2}, + {1267, 2}, + 1 + } + { + {1273, 2}, + {1265, 2, "edge" "collidable"}, + {1267, 2}, + 1 + } + { + {1250, 2, "edge" "collidable"}, + {1281, 2}, + {1270, 2}, + 1 + } + { + {1281, 2}, + {1267, 2, "edge" "collidable"}, + {1270, 2}, + 1 + } + { + {1284, 2}, + {1333, 2, "edge" "collidable"}, + {1335, 2}, + 1 + } + { + {1308, 2, "edge" "collidable"}, + {1250, 2}, + {1272, 2}, + 1 + } + { + {1250, 2}, + {1270, 2, "edge" "collidable"}, + {1272, 2}, + 1 + } + { + {1374, 2, "edge" "collidable"}, + {1308, 2}, + {1274, 2}, + 1 + } + { + {1308, 2}, + {1272, 2, "edge" "collidable"}, + {1274, 2}, + 1 + } + { + {1350, 2, "edge" "collidable"}, + {1374, 2}, + {1277, 2}, + 1 + } + { + {1374, 2}, + {1274, 2, "edge" "collidable"}, + {1277, 2}, + 1 + } + { + {1384, 2, "edge" "collidable"}, + {1313, 2}, + {1354, 2}, + 1 + } + { + {1313, 2}, + {1351, 2, "edge" "collidable"}, + {1354, 2}, + 1 + } + { + {1261, 2, "edge" "collidable"}, + {1350, 2}, + {1279, 2}, + 1 + } + { + {1350, 2}, + {1277, 2, "edge" "collidable"}, + {1279, 2}, + 1 + } + { + {1288, 2, "edge" "collidable"}, + {1231, 2}, + {1362, 2}, + 1 + } + { + {1231, 2}, + {1358, 2, "edge" "collidable"}, + {1362, 2}, + 1 + } + { + {1380, 2, "edge" "collidable"}, + {1261, 2}, + {1280, 2}, + 1 + } + { + {1261, 2}, + {1279, 2, "edge" "collidable"}, + {1280, 2}, + 1 + } + { + {1292, 2, "edge" "collidable"}, + {1380, 2}, + {1282, 2}, + 1 + } + { + {1380, 2}, + {1280, 2, "edge" "collidable"}, + {1282, 2}, + 1 + } + { + {1339, 2, "edge" "collidable"}, + {1292, 2}, + {1283, 2}, + 1 + } + { + {1292, 2}, + {1282, 2, "edge" "collidable"}, + {1283, 2}, + 1 + } + { + {1219, 2, "edge" "collidable"}, + {1240, 2}, + {1347, 2}, + 1 + } + { + {1240, 2}, + {1344, 2, "edge" "collidable"}, + {1347, 2}, + 1 + } + { + {1348, 2, "edge" "collidable"}, + {1339, 2}, + {1286, 2}, + 1 + } + { + {1339, 2}, + {1283, 2, "edge" "collidable"}, + {1286, 2}, + 1 + } + { + {1304, 2, "edge" "collidable"}, + {1348, 2}, + {1287, 2}, + 1 + } + { + {1348, 2}, + {1286, 2, "edge" "collidable"}, + {1287, 2}, + 1 + } + { + {1388, 2, "edge" "collidable"}, + {1304, 2}, + {1289, 2}, + 1 + } + { + {1304, 2}, + {1287, 2, "edge" "collidable"}, + {1289, 2}, + 1 + } + { + {1342, 2, "edge" "collidable"}, + {1388, 2}, + {1291, 2}, + 1 + } + { + {1388, 2}, + {1289, 2, "edge" "collidable"}, + {1291, 2}, + 1 + } + { + {1359, 2, "edge" "collidable"}, + {1366, 2}, + {1338, 2}, + 1 + } + { + {1366, 2}, + {1335, 2, "edge" "collidable"}, + {1338, 2}, + 1 + } + { + {1288, 2}, + {1362, 2, "edge" "collidable"}, + {1365, 2}, + 1 + } + { + {1393, 2, "edge" "collidable"}, + {1288, 2}, + {1365, 2}, + 1 + } + { + {1269, 2, "edge" "collidable"}, + {1342, 2}, + {1295, 2}, + 1 + } + { + {1342, 2}, + {1291, 2, "edge" "collidable"}, + {1295, 2}, + 1 + } + { + {1318, 2}, + {1357, 2, "edge" "collidable"}, + {1358, 2}, + 1 + } + { + {1231, 2, "edge" "collidable"}, + {1318, 2}, + {1358, 2}, + 1 + } + { + {1255, 2, "edge" "collidable"}, + {1269, 2}, + {1296, 2}, + 1 + } + { + {1269, 2}, + {1295, 2, "edge" "collidable"}, + {1296, 2}, + 1 + } + { + {1391, 2, "edge" "collidable"}, + {1255, 2}, + {1297, 2}, + 1 + } + { + {1255, 2}, + {1296, 2, "edge" "collidable"}, + {1297, 2}, + 1 + } + { + {1385, 2, "edge" "collidable"}, + {1391, 2}, + {1298, 2}, + 1 + } + { + {1391, 2}, + {1297, 2, "edge" "collidable"}, + {1298, 2}, + 1 + } + { + {1337, 2, "edge" "collidable"}, + {1385, 2}, + {1300, 2}, + 1 + } + { + {1385, 2}, + {1298, 2, "edge" "collidable"}, + {1300, 2}, + 1 + } + { + {1343, 2, "edge" "collidable"}, + {1337, 2}, + {1301, 2}, + 1 + } + { + {1337, 2}, + {1300, 2, "edge" "collidable"}, + {1301, 2}, + 1 + } + { + {1352, 2, "edge" "collidable"}, + {1343, 2}, + {1303, 2}, + 1 + } + { + {1343, 2}, + {1301, 2, "edge" "collidable"}, + {1303, 2}, + 1 + } + { + {1332, 2, "edge" "collidable"}, + {1379, 2}, + {1320, 2}, + 1 + } + { + {1379, 2}, + {1319, 2, "edge" "collidable"}, + {1320, 2}, + 1 + } + { + {1275, 2, "edge" "collidable"}, + {1219, 2}, + {1349, 2}, + 1 + } + { + {1302, 2, "edge" "collidable"}, + {1352, 2}, + {1305, 2}, + 1 + } + { + {1352, 2}, + {1303, 2, "edge" "collidable"}, + {1305, 2}, + 1 + } + { + {1390, 2, "edge" "collidable"}, + {1302, 2}, + {1306, 2}, + 1 + } + { + {1302, 2}, + {1305, 2, "edge" "collidable"}, + {1306, 2}, + 1 + } + { + {1376, 2, "edge" "collidable"}, + {1393, 2}, + {1368, 2}, + 1 + } + { + {1285, 2, "edge" "collidable"}, + {1390, 2}, + {1307, 2}, + 1 + } + { + {1390, 2}, + {1306, 2, "edge" "collidable"}, + {1307, 2}, + 1 + } + { + {1336, 2}, + {1355, 2, "edge" "collidable"}, + {1357, 2}, + 1 + } + { + {1318, 2, "edge" "collidable"}, + {1336, 2}, + {1357, 2}, + 1 + } + { + {1353, 2, "edge" "collidable"}, + {1285, 2}, + {1309, 2}, + 1 + } + { + {1285, 2}, + {1307, 2, "edge" "collidable"}, + {1309, 2}, + 1 + } + { + {1240, 2, "edge" "collidable"}, + {1381, 2}, + {1344, 2}, + 1 + } + { + {1381, 2}, + {1341, 2, "edge" "collidable"}, + {1344, 2}, + 1 + } + { + {1252, 2, "edge" "collidable"}, + {1353, 2}, + {1311, 2}, + 1 + } + { + {1353, 2}, + {1309, 2, "edge" "collidable"}, + {1311, 2}, + 1 + } + { + {1223, 2, "edge" "collidable"}, + {1252, 2}, + {1312, 2}, + 1 + } + { + {1252, 2}, + {1311, 2, "edge" "collidable"}, + {1312, 2}, + 1 + } + { + {1361, 2, "edge" "collidable"}, + {1247, 2}, + {1317, 2}, + 1 + } + { + {1334, 2, "edge" "collidable"}, + {1223, 2}, + {1314, 2}, + 1 + } + { + {1223, 2}, + {1312, 2, "edge" "collidable"}, + {1314, 2}, + 1 + } + { + {1332, 2}, + {1320, 2, "edge" "collidable"}, + {1321, 2}, + 1 + } + { + {1249, 2, "edge" "collidable"}, + {1334, 2}, + {1315, 2}, + 1 + } + { + {1334, 2}, + {1314, 2, "edge" "collidable"}, + {1315, 2}, + 1 + } + { + {1259, 2}, + {1325, 2, "edge" "collidable"}, + {1326, 2}, + 1 + } + { + {1382, 2, "edge" "collidable"}, + {1259, 2}, + {1326, 2}, + 1 + } + { + {1247, 2, "edge" "collidable"}, + {1249, 2}, + {1316, 2}, + 1 + } + { + {1249, 2}, + {1315, 2, "edge" "collidable"}, + {1316, 2}, + 1 + } + # Mesh "Mesh.003" + { + {1515, 2, "edge" "collidable"}, + {1433, 2}, + {1452, 2}, + 0 + } + { + {1433, 2}, + {1554, 2, "edge" "collidable"}, + {1452, 2}, + 0 + } + { + {1425, 2}, + {1560, 2, "edge" "collidable"}, + {1562, 2}, + 0 + } + { + {1512, 2, "edge" "collidable"}, + {1425, 2}, + {1562, 2}, + 0 + } + { + {1463, 2}, + {1572, 2, "edge" "collidable"}, + {1575, 2}, + 0 + } + { + {1472, 2, "edge" "collidable"}, + {1463, 2}, + {1575, 2}, + 0 + } + { + {1520, 2}, + {1568, 2, "edge" "collidable"}, + {1570, 2}, + 0 + } + { + {1411, 2, "edge" "collidable"}, + {1520, 2}, + {1570, 2}, + 0 + } + { + {1524, 2}, + {1581, 2, "edge" "collidable"}, + {1584, 2}, + 0 + } + { + {1478, 2, "edge" "collidable"}, + {1524, 2}, + {1584, 2}, + 0 + } + { + {1542, 2}, + {1563, 2, "edge" "collidable"}, + {1564, 2}, + 0 + } + { + {1551, 2, "edge" "collidable"}, + {1468, 2}, + {1482, 2}, + 0 + } + { + {1400, 2, "edge" "collidable"}, + {1505, 2}, + {1579, 2}, + 0 + } + { + {1505, 2}, + {1422, 2, "edge" "collidable"}, + {1579, 2}, + 0 + } + { + {1486, 2}, + {1535, 2, "edge" "collidable"}, + {1538, 2}, + 0 + } + { + {1506, 2, "edge" "collidable"}, + {1424, 2}, + {1566, 2}, + 0 + } + { + {1424, 2}, + {1564, 2, "edge" "collidable"}, + {1566, 2}, + 0 + } + { + {1519, 2, "edge" "collidable"}, + {1481, 2}, + {1398, 2}, + 0 + } + { + {1502, 2}, + {1403, 2, "edge" "collidable"}, + {1513, 2}, + 0 + } + { + {1571, 2, "edge" "collidable"}, + {1502, 2}, + {1513, 2}, + 0 + } + { + {1574, 2}, + {1469, 2, "edge" "collidable"}, + {1522, 2}, + 0 + } + { + {1409, 2, "edge" "collidable"}, + {1464, 2}, + {1528, 2}, + 0 + } + { + {1464, 2, "edge" "collidable"}, + {1526, 2, "edge" "collidable"}, + {1528, 2}, + 0 + } + { + {1449, 2}, + {1582, 2, "edge" "collidable"}, + {1561, 2}, + 0 + } + { + {1548, 2}, + {1589, 2, "edge" "collidable"}, + {1399, 2}, + 0 + } + { + {1509, 2, "edge" "collidable"}, + {1548, 2}, + {1590, 2, "edge" "collidable"}, + 0 + } + { + {1406, 2, "edge" "collidable"}, + {1587, 2}, + {1488, 2}, + 0 + } + { + {1577, 2, "edge" "collidable"}, + {1500, 2}, + {1499, 2}, + 0 + } + { + {1502, 2, "edge" "collidable"}, + {1402, 2}, + {1403, 2}, + 0 + } + { + {1456, 2}, + {1448, 2, "edge" "collidable"}, + {1518, 2}, + 0 + } + { + {1451, 2, "edge" "collidable"}, + {1456, 2}, + {1518, 2}, + 0 + } + { + {1494, 2}, + {1454, 2, "edge" "collidable"}, + {1476, 2}, + 0 + } + { + {1463, 2, "edge" "collidable"}, + {1411, 2}, + {1572, 2}, + 0 + } + { + {1411, 2}, + {1570, 2, "edge" "collidable"}, + {1572, 2}, + 0 + } + { + {1436, 2}, + {1476, 2, "edge" "collidable"}, + {1431, 2}, + 0 + } + { + {1473, 2, "edge" "collidable"}, + {1436, 2}, + {1431, 2}, + 0 + } + { + {1486, 2, "edge" "collidable"}, + {1428, 2}, + {1535, 2}, + 0 + } + { + {1519, 2}, + {1398, 2, "edge" "collidable"}, + {1444, 2}, + 0 + } + { + {1500, 2, "edge" "collidable"}, + {1519, 2}, + {1444, 2}, + 0 + } + { + {1423, 2}, + {1561, 2, "edge" "collidable"}, + {1483, 2}, + 0 + } + { + {1507, 2}, + {1532, 2, "edge" "collidable"}, + {1498, 2}, + 0 + } + { + {1466, 2}, + {1573, 2, "edge" "collidable"}, + {1487, 2}, + 0 + } + { + {1517, 2, "edge" "collidable"}, + {1466, 2}, + {1487, 2}, + 0 + } + { + {1480, 2, "edge" "collidable"}, + {1459, 2}, + {1536, 2}, + 0 + } + { + {1485, 2}, + {1510, 2, "edge" "collidable"}, + {1493, 2}, + 0 + } + { + {1401, 2}, + {1588, 2, "edge" "collidable"}, + {1554, 2}, + 0 + } + { + {1489, 2, "edge" "collidable"}, + {1571, 2}, + {1441, 2}, + 0 + } + { + {1412, 2}, + {1558, 2, "edge" "collidable"}, + {1559, 2}, + 0 + } + { + {1514, 2, "edge" "collidable"}, + {1412, 2}, + {1559, 2}, + 0 + } + { + {1503, 2}, + {1567, 2, "edge" "collidable"}, + {1568, 2}, + 0 + } + { + {1520, 2, "edge" "collidable"}, + {1503, 2}, + {1568, 2}, + 0 + } + { + {1417, 2}, + {1432, 2, "edge" "collidable"}, + {1454, 2}, + 0 + } + { + {1494, 2, "edge" "collidable"}, + {1417, 2}, + {1454, 2}, + 0 + } + { + {1434, 2, "edge" "collidable"}, + {1491, 2}, + {1553, 2}, + 0 + } + { + {1548, 2, "edge" "collidable"}, + {1477, 2}, + {1583, 2}, + 0 + } + { + {1477, 2}, + {1408, 2, "edge" "collidable"}, + {1583, 2}, + 0 + } + { + {1471, 2}, + {1396, 2, "edge" "collidable"}, + {1475, 2}, + 0 + } + { + {1456, 2, "edge" "collidable"}, + {1525, 2}, + {1448, 2}, + 0 + } + { + {1525, 2}, + {1446, 2, "edge" "collidable"}, + {1448, 2}, + 0 + } + { + {1443, 2}, + {1497, 2, "edge" "collidable"}, + {1460, 2}, + 0 + } + { + {1546, 2}, + {1437, 2, "edge" "collidable"}, + {1415, 2}, + 0 + } + { + {1466, 2, "edge" "collidable"}, + {1406, 2}, + {1573, 2}, + 0 + } + { + {1406, 2}, + {1488, 2, "edge" "collidable"}, + {1573, 2}, + 0 + } + { + {1462, 2, "edge" "collidable"}, + {1409, 2}, + {1530, 2}, + 0 + } + { + {1409, 2}, + {1528, 2, "edge" "collidable"}, + {1530, 2}, + 0 + } + { + {1587, 2, "edge" "collidable"}, + {1447, 2}, + {1556, 2}, + 0 + } + { + {1447, 2}, + {1498, 2, "edge" "collidable"}, + {1556, 2}, + 0 + } + { + {1517, 2}, + {1487, 2, "edge" "collidable"}, + {1440, 2}, + 0 + } + { + {1418, 2, "edge" "collidable"}, + {1517, 2}, + {1440, 2}, + 0 + } + { + {1425, 2, "edge" "collidable"}, + {1514, 2}, + {1560, 2}, + 0 + } + { + {1580, 2, "edge" "collidable"}, + {1485, 2}, + {1493, 2}, + 0 + } + { + {1462, 2}, + {1530, 2, "edge" "collidable"}, + {1531, 2}, + 0 + } + { + {1511, 2, "edge" "collidable"}, + {1474, 2}, + {1578, 2}, + 0 + } + { + {1474, 2}, + {1492, 2, "edge" "collidable"}, + {1578, 2}, + 0 + } + { + {1503, 2, "edge" "collidable"}, + {1506, 2}, + {1567, 2}, + 0 + } + { + {1506, 2}, + {1566, 2, "edge" "collidable"}, + {1567, 2}, + 0 + } + { + {1442, 2, "edge" "collidable"}, + {1478, 2}, + {1585, 2}, + 0 + } + { + {1478, 2}, + {1584, 2, "edge" "collidable"}, + {1585, 2}, + 0 + } + { + {1496, 2, "edge" "collidable"}, + {1471, 2}, + {1475, 2}, + 0 + } + { + {1516, 2}, + {1527, 2, "edge" "collidable"}, + {1458, 2}, + 0 + } + { + {1430, 2, "edge" "collidable"}, + {1529, 2}, + {1549, 2}, + 0 + } + { + {1439, 2, "edge" "collidable"}, + {1462, 2}, + {1531, 2}, + 0 + } + { + {1468, 2, "edge" "collidable"}, + {1565, 2}, + {1550, 2}, + 0 + } + { + {1459, 2, "edge" "collidable"}, + {1479, 2}, + {1465, 2}, + 0 + } + { + {1524, 2, "edge" "collidable"}, + {1484, 2}, + {1581, 2}, + 0 + } + { + {1484, 2}, + {1576, 2, "edge" "collidable"}, + {1581, 2}, + 0 + } + { + {1445, 2, "edge" "collidable"}, + {1443, 2}, + {1460, 2}, + 0 + } + { + {1508, 2, "edge" "collidable"}, + {1434, 2}, + {1555, 2}, + 0 + } + { + {1434, 2}, + {1553, 2, "edge" "collidable"}, + {1555, 2}, + 0 + } + { + {1540, 2, "edge" "collidable"}, + {1486, 2}, + {1538, 2}, + 0 + } + { + {1540, 2}, + {1538, 2, "edge" "collidable"}, + {1541, 2}, + 0 + } + { + {1407, 2, "edge" "collidable"}, + {1540, 2}, + {1541, 2}, + 0 + } + { + {1580, 2}, + {1493, 2, "edge" "collidable"}, + {1396, 2}, + 0 + } + { + {1571, 2}, + {1513, 2, "edge" "collidable"}, + {1441, 2}, + 0 + } + { + {1586, 2, "edge" "collidable"}, + {1451, 2}, + {1569, 2}, + 0 + } + { + {1451, 2}, + {1518, 2, "edge" "collidable"}, + {1569, 2}, + 0 + } + { + {1501, 2, "edge" "collidable"}, + {1418, 2}, + {1420, 2}, + 0 + } + { + {1418, 2}, + {1440, 2, "edge" "collidable"}, + {1420, 2}, + 0 + } + { + {1542, 2, "edge" "collidable"}, + {1512, 2}, + {1563, 2}, + 0 + } + { + {1512, 2}, + {1562, 2, "edge" "collidable"}, + {1563, 2}, + 0 + } + { + {1397, 2, "edge" "collidable"}, + {1407, 2}, + {1543, 2}, + 0 + } + { + {1491, 2}, + {1552, 2, "edge" "collidable"}, + {1553, 2}, + 0 + } + { + {1565, 2, "edge" "collidable"}, + {1546, 2}, + {1415, 2}, + 0 + } + { + {1447, 2, "edge" "collidable"}, + {1507, 2}, + {1498, 2}, + 0 + } + { + {1515, 2}, + {1452, 2, "edge" "collidable"}, + {1422, 2}, + 0 + } + { + {1505, 2, "edge" "collidable"}, + {1515, 2}, + {1422, 2}, + 0 + } + { + {1428, 2}, + {1534, 2, "edge" "collidable"}, + {1535, 2}, + 0 + } + { + {1438, 2}, + {1495, 2, "edge" "collidable"}, + {1533, 2}, + 0 + } + { + {1523, 2}, + {1533, 2, "edge" "collidable"}, + {1432, 2}, + 0 + } + { + {1417, 2, "edge" "collidable"}, + {1523, 2}, + {1432, 2}, + 0 + } + { + {1459, 2}, + {1465, 2, "edge" "collidable"}, + {1536, 2}, + 0 + } + { + {1400, 2}, + {1579, 2, "edge" "collidable"}, + {1446, 2}, + 0 + } + { + {1525, 2, "edge" "collidable"}, + {1400, 2}, + {1446, 2}, + 0 + } + { + {1586, 2}, + {1569, 2, "edge" "collidable"}, + {1532, 2}, + 0 + } + { + {1507, 2, "edge" "collidable"}, + {1586, 2}, + {1532, 2}, + 0 + } + { + {1577, 2}, + {1499, 2, "edge" "collidable"}, + {1426, 2}, + 0 + } + { + {1565, 2}, + {1415, 2, "edge" "collidable"}, + {1550, 2}, + 0 + } + { + {1419, 2, "edge" "collidable"}, + {1435, 2}, + {1539, 2}, + 0 + } + { + {1435, 2}, + {1421, 2, "edge" "collidable"}, + {1539, 2}, + 0 + } + { + {1477, 2, "edge" "collidable"}, + {1414, 2}, + {1408, 2}, + 0 + } + { + {1414, 2}, + {1450, 2, "edge" "collidable"}, + {1408, 2}, + 0 + } + { + {1412, 2}, + {1557, 2, "edge" "collidable"}, + {1558, 2}, + 0 + } + { + {1404, 2, "edge" "collidable"}, + {1511, 2}, + {1461, 2}, + 0 + } + { + {1511, 2}, + {1578, 2, "edge" "collidable"}, + {1461, 2}, + 0 + } + { + {1514, 2}, + {1559, 2, "edge" "collidable"}, + {1560, 2}, + 0 + } + { + {1412, 2, "edge" "collidable"}, + {1508, 2}, + {1557, 2}, + 0 + } + { + {1508, 2}, + {1555, 2, "edge" "collidable"}, + {1557, 2}, + 0 + } + { + {1521, 2, "edge" "collidable"}, + {1577, 2}, + {1426, 2}, + 0 + } + { + {1496, 2}, + {1475, 2, "edge" "collidable"}, + {1469, 2}, + 0 + } + { + {1574, 2, "edge" "collidable"}, + {1496, 2}, + {1469, 2}, + 0 + } + { + {1587, 2}, + {1556, 2, "edge" "collidable"}, + {1488, 2}, + 0 + } + { + {1479, 2}, + {1537, 2, "edge" "collidable"}, + {1465, 2}, + 0 + } + { + {1407, 2}, + {1541, 2, "edge" "collidable"}, + {1543, 2}, + 0 + } + { + {1529, 2, "edge" "collidable"}, + {1490, 2}, + {1547, 2}, + 0 + } + { + {1490, 2}, + {1544, 2, "edge" "collidable"}, + {1547, 2}, + 0 + } + { + {1521, 2}, + {1426, 2, "edge" "collidable"}, + {1450, 2}, + 0 + } + { + {1414, 2, "edge" "collidable"}, + {1521, 2}, + {1450, 2}, + 0 + } + { + {1551, 2}, + {1482, 2, "edge" "collidable"}, + {1510, 2}, + 0 + } + { + {1471, 2, "edge" "collidable"}, + {1580, 2}, + {1396, 2}, + 0 + } + { + {1523, 2, "edge" "collidable"}, + {1438, 2}, + {1533, 2}, + 0 + } + { + {1473, 2}, + {1431, 2, "edge" "collidable"}, + {1492, 2}, + 0 + } + { + {1474, 2, "edge" "collidable"}, + {1473, 2}, + {1492, 2}, + 0 + } + { + {1472, 2}, + {1575, 2, "edge" "collidable"}, + {1576, 2}, + 0 + } + { + {1484, 2, "edge" "collidable"}, + {1472, 2}, + {1576, 2}, + 0 + } + { + {1404, 2}, + {1461, 2, "edge" "collidable"}, + {1421, 2}, + 0 + } + { + {1435, 2, "edge" "collidable"}, + {1404, 2}, + {1421, 2}, + 0 + } + { + {1500, 2}, + {1444, 2, "edge" "collidable"}, + {1499, 2}, + 0 + } + { + {1491, 2, "edge" "collidable"}, + {1430, 2}, + {1552, 2}, + 0 + } + { + {1430, 2}, + {1549, 2, "edge" "collidable"}, + {1552, 2}, + 0 + } + { + {1504, 2}, + {1429, 2, "edge" "collidable"}, + {1416, 2}, + 0 + } + { + {1402, 2, "edge" "collidable"}, + {1504, 2}, + {1416, 2}, + 0 + } + { + {1439, 2}, + {1531, 2, "edge" "collidable"}, + {1534, 2}, + 0 + } + { + {1428, 2, "edge" "collidable"}, + {1439, 2}, + {1534, 2}, + 0 + } + { + {1401, 2, "edge" "collidable"}, + {1442, 2}, + {1588, 2}, + 0 + } + { + {1442, 2}, + {1585, 2, "edge" "collidable"}, + {1588, 2}, + 0 + } + { + {1433, 2, "edge" "collidable"}, + {1401, 2}, + {1554, 2}, + 0 + } + { + {1397, 2}, + {1543, 2, "edge" "collidable"}, + {1544, 2}, + 0 + } + { + {1490, 2, "edge" "collidable"}, + {1397, 2}, + {1544, 2}, + 0 + } + { + {1467, 2}, + {1427, 2, "edge" "collidable"}, + {1413, 2}, + 0 + } + { + {1402, 2}, + {1416, 2, "edge" "collidable"}, + {1403, 2}, + 0 + } + { + {1436, 2, "edge" "collidable"}, + {1494, 2}, + {1476, 2}, + 0 + } + { + {1516, 2, "edge" "collidable"}, + {1445, 2}, + {1527, 2}, + 0 + } + { + {1545, 2}, + {1458, 2, "edge" "collidable"}, + {1495, 2}, + 0 + } + { + {1438, 2, "edge" "collidable"}, + {1545, 2}, + {1495, 2}, + 0 + } + { + {1419, 2}, + {1539, 2, "edge" "collidable"}, + {1455, 2}, + 0 + } + { + {1470, 2, "edge" "collidable"}, + {1419, 2}, + {1455, 2}, + 0 + } + { + {1504, 2, "edge" "collidable"}, + {1405, 2}, + {1429, 2}, + 0 + } + { + {1405, 2}, + {1457, 2, "edge" "collidable"}, + {1429, 2}, + 0 + } + { + {1489, 2}, + {1441, 2, "edge" "collidable"}, + {1427, 2}, + 0 + } + { + {1467, 2, "edge" "collidable"}, + {1489, 2}, + {1427, 2}, + 0 + } + { + {1453, 2, "edge" "collidable"}, + {1423, 2}, + {1483, 2}, + 0 + } + { + {1443, 2, "edge" "collidable"}, + {1453, 2}, + {1497, 2}, + 0 + } + { + {1481, 2, "edge" "collidable"}, + {1467, 2}, + {1413, 2}, + 0 + } + { + {1480, 2}, + {1536, 2, "edge" "collidable"}, + {1582, 2}, + 0 + } + { + {1410, 2, "edge" "collidable"}, + {1574, 2}, + {1522, 2}, + 0 + } + { + {1545, 2, "edge" "collidable"}, + {1516, 2}, + {1458, 2}, + 0 + } + { + {1470, 2}, + {1455, 2, "edge" "collidable"}, + {1457, 2}, + 0 + } + { + {1405, 2, "edge" "collidable"}, + {1470, 2}, + {1457, 2}, + 0 + } + { + {1449, 2, "edge" "collidable"}, + {1480, 2}, + {1582, 2}, + 0 + } + { + {1485, 2, "edge" "collidable"}, + {1551, 2}, + {1510, 2}, + 0 + } + { + {1546, 2, "edge" "collidable"}, + {1501, 2}, + {1437, 2}, + 0 + } + { + {1501, 2}, + {1420, 2, "edge" "collidable"}, + {1437, 2}, + 0 + } + { + {1529, 2}, + {1547, 2, "edge" "collidable"}, + {1549, 2}, + 0 + } + { + {1410, 2}, + {1522, 2, "edge" "collidable"}, + {1537, 2}, + 0 + } + { + {1479, 2, "edge" "collidable"}, + {1410, 2}, + {1537, 2}, + 0 + } + { + {1481, 2}, + {1413, 2, "edge" "collidable"}, + {1398, 2}, + 0 + } + { + {1445, 2}, + {1460, 2, "edge" "collidable"}, + {1527, 2}, + 0 + } + { + {1424, 2, "edge" "collidable"}, + {1542, 2}, + {1564, 2}, + 0 + } + { + {1453, 2}, + {1483, 2, "edge" "collidable"}, + {1497, 2}, + 0 + } + { + {1423, 2, "edge" "collidable"}, + {1449, 2}, + {1561, 2}, + 0 + } + { + {1468, 2}, + {1550, 2, "edge" "collidable"}, + {1482, 2}, + 0 + } + { + {1548, 2}, + {1399, 2, "edge" "collidable"}, + {1590, 2}, + 0 + } + { + {1548, 2}, + {1583, 2, "edge" "collidable"}, + {1589, 2}, + 0 + } + # Mesh "Plane" + { + {1609, 2}, + {1593, 2, "edge" "collidable"}, + {1591, 2}, + 2 + } + { + {1609, 2}, + {1591, 2}, + {1610, 2}, + 2 + } + { + {1592, 2}, + {1609, 2}, + {1610, 2}, + 2 + } + { + {1592, 2}, + {1610, 2}, + {1597, 2}, + 2 + } + { + {1597, 2}, + {1610, 2}, + {1603, 2}, + 2 + } + { + {1592, 2}, + {1597, 2}, + {1605, 2}, + 2 + } + { + {1606, 2}, + {1597, 2}, + {1595, 2}, + 2 + } + { + {1595, 2}, + {1597, 2}, + {1603, 2}, + 2 + } + { + {1595, 2}, + {1603, 2}, + {1604, 2}, + 2 + } + { + {1604, 2}, + {1603, 2}, + {1598, 2}, + 2 + } + { + {1607, 2}, + {1592, 2}, + {1600, 2}, + 2 + } + { + {1600, 2}, + {1592, 2}, + {1602, 2}, + 2 + } + { + {1602, 2}, + {1592, 2}, + {1605, 2}, + 2 + } + { + {1608, 2}, + {1600, 2}, + {1602, 2}, + 2 + } + { + {1608, 2}, + {1602, 2}, + {1596, 2}, + 2 + } + { + {1599, 2}, + {1602, 2}, + {1605, 2}, + 2 + } + { + {1599, 2}, + {1605, 2}, + {1594, 2}, + 2 + } + { + {1601, 2}, + {1599, 2}, + {1594, 2}, + 2 + } + # Mesh "Plane.001" + { + {1629, 2}, + {1613, 2, "edge" "collidable"}, + {1611, 2}, + 2 + } + { + {1629, 2}, + {1611, 2}, + {1630, 2}, + 2 + } + { + {1612, 2}, + {1629, 2}, + {1630, 2}, + 2 + } + { + {1612, 2}, + {1630, 2}, + {1617, 2}, + 2 + } + { + {1617, 2}, + {1630, 2}, + {1623, 2}, + 2 + } + { + {1612, 2}, + {1617, 2}, + {1625, 2}, + 2 + } + { + {1626, 2}, + {1617, 2}, + {1615, 2}, + 2 + } + { + {1615, 2}, + {1617, 2}, + {1623, 2}, + 2 + } + { + {1615, 2}, + {1623, 2}, + {1624, 2}, + 2 + } + { + {1624, 2}, + {1623, 2}, + {1618, 2}, + 2 + } + { + {1627, 2}, + {1612, 2}, + {1620, 2}, + 2 + } + { + {1620, 2}, + {1612, 2}, + {1622, 2}, + 2 + } + { + {1622, 2}, + {1612, 2}, + {1625, 2}, + 2 + } + { + {1628, 2}, + {1620, 2}, + {1622, 2}, + 2 + } + { + {1628, 2}, + {1622, 2}, + {1616, 2}, + 2 + } + { + {1619, 2}, + {1622, 2}, + {1625, 2}, + 2 + } + { + {1619, 2}, + {1625, 2}, + {1614, 2}, + 2 + } + { + {1621, 2}, + {1619, 2}, + {1614, 2}, + 2 + } + # Mesh "Plane.006" + { + {1649, 2}, + {1633, 2, "edge" "collidable"}, + {1631, 2}, + 2 + } + { + {1649, 2}, + {1631, 2}, + {1650, 2}, + 2 + } + { + {1632, 2}, + {1649, 2}, + {1650, 2}, + 2 + } + { + {1632, 2}, + {1650, 2}, + {1637, 2}, + 2 + } + { + {1637, 2}, + {1650, 2}, + {1643, 2}, + 2 + } + { + {1632, 2}, + {1637, 2}, + {1645, 2}, + 2 + } + { + {1646, 2}, + {1637, 2}, + {1635, 2}, + 2 + } + { + {1635, 2}, + {1637, 2}, + {1643, 2}, + 2 + } + { + {1635, 2}, + {1643, 2}, + {1644, 2}, + 2 + } + { + {1644, 2}, + {1643, 2}, + {1638, 2}, + 2 + } + { + {1647, 2}, + {1632, 2}, + {1640, 2}, + 2 + } + { + {1640, 2}, + {1632, 2}, + {1642, 2}, + 2 + } + { + {1642, 2}, + {1632, 2}, + {1645, 2}, + 2 + } + { + {1648, 2}, + {1640, 2}, + {1642, 2}, + 2 + } + { + {1648, 2}, + {1642, 2}, + {1636, 2}, + 2 + } + { + {1639, 2}, + {1642, 2}, + {1645, 2}, + 2 + } + { + {1639, 2}, + {1645, 2}, + {1634, 2}, + 2 + } + { + {1641, 2}, + {1639, 2}, + {1634, 2}, + 2 + } + # Mesh "Plane.007" + { + {1669, 2}, + {1653, 2, "edge" "collidable"}, + {1651, 2}, + 2 + } + { + {1669, 2}, + {1651, 2}, + {1670, 2}, + 2 + } + { + {1652, 2}, + {1669, 2}, + {1670, 2}, + 2 + } + { + {1652, 2}, + {1670, 2}, + {1657, 2}, + 2 + } + { + {1657, 2}, + {1670, 2}, + {1663, 2}, + 2 + } + { + {1652, 2}, + {1657, 2}, + {1665, 2}, + 2 + } + { + {1666, 2}, + {1657, 2}, + {1655, 2}, + 2 + } + { + {1655, 2}, + {1657, 2}, + {1663, 2}, + 2 + } + { + {1655, 2}, + {1663, 2}, + {1664, 2}, + 2 + } + { + {1664, 2}, + {1663, 2}, + {1658, 2}, + 2 + } + { + {1667, 2}, + {1652, 2}, + {1660, 2}, + 2 + } + { + {1660, 2}, + {1652, 2}, + {1662, 2}, + 2 + } + { + {1662, 2}, + {1652, 2}, + {1665, 2}, + 2 + } + { + {1668, 2}, + {1660, 2}, + {1662, 2}, + 2 + } + { + {1668, 2}, + {1662, 2}, + {1656, 2}, + 2 + } + { + {1659, 2}, + {1662, 2}, + {1665, 2}, + 2 + } + { + {1659, 2}, + {1665, 2}, + {1654, 2}, + 2 + } + { + {1661, 2}, + {1659, 2}, + {1654, 2}, + 2 + } + # Mesh "Plane.008" + { + {1689, 2}, + {1673, 2, "edge" "collidable"}, + {1671, 2}, + 2 + } + { + {1689, 2}, + {1671, 2}, + {1690, 2}, + 2 + } + { + {1672, 2}, + {1689, 2}, + {1690, 2}, + 2 + } + { + {1672, 2}, + {1690, 2}, + {1677, 2}, + 2 + } + { + {1677, 2}, + {1690, 2}, + {1683, 2}, + 2 + } + { + {1672, 2}, + {1677, 2}, + {1685, 2}, + 2 + } + { + {1686, 2}, + {1677, 2}, + {1675, 2}, + 2 + } + { + {1675, 2}, + {1677, 2}, + {1683, 2}, + 2 + } + { + {1675, 2}, + {1683, 2}, + {1684, 2}, + 2 + } + { + {1684, 2}, + {1683, 2}, + {1678, 2}, + 2 + } + { + {1687, 2}, + {1672, 2}, + {1680, 2}, + 2 + } + { + {1680, 2}, + {1672, 2}, + {1682, 2}, + 2 + } + { + {1682, 2}, + {1672, 2}, + {1685, 2}, + 2 + } + { + {1688, 2}, + {1680, 2}, + {1682, 2}, + 2 + } + { + {1688, 2}, + {1682, 2}, + {1676, 2}, + 2 + } + { + {1679, 2}, + {1682, 2}, + {1685, 2}, + 2 + } + { + {1679, 2}, + {1685, 2}, + {1674, 2}, + 2 + } + { + {1681, 2}, + {1679, 2}, + {1674, 2}, + 2 + } + # Mesh "Plane.009" + { + {1709, 2}, + {1693, 2, "edge" "collidable"}, + {1691, 2}, + 2 + } + { + {1709, 2}, + {1691, 2}, + {1710, 2}, + 2 + } + { + {1692, 2}, + {1709, 2}, + {1710, 2}, + 2 + } + { + {1692, 2}, + {1710, 2}, + {1697, 2}, + 2 + } + { + {1697, 2}, + {1710, 2}, + {1703, 2}, + 2 + } + { + {1692, 2}, + {1697, 2}, + {1705, 2}, + 2 + } + { + {1706, 2}, + {1697, 2}, + {1695, 2}, + 2 + } + { + {1695, 2}, + {1697, 2}, + {1703, 2}, + 2 + } + { + {1695, 2}, + {1703, 2}, + {1704, 2}, + 2 + } + { + {1704, 2}, + {1703, 2}, + {1698, 2}, + 2 + } + { + {1707, 2}, + {1692, 2}, + {1700, 2}, + 2 + } + { + {1700, 2}, + {1692, 2}, + {1702, 2}, + 2 + } + { + {1702, 2}, + {1692, 2}, + {1705, 2}, + 2 + } + { + {1708, 2}, + {1700, 2}, + {1702, 2}, + 2 + } + { + {1708, 2}, + {1702, 2}, + {1696, 2}, + 2 + } + { + {1699, 2}, + {1702, 2}, + {1705, 2}, + 2 + } + { + {1699, 2}, + {1705, 2}, + {1694, 2}, + 2 + } + { + {1701, 2}, + {1699, 2}, + {1694, 2}, + 2 + } + # Mesh "Plane.010" + { + {1729, 2}, + {1713, 2, "edge" "collidable"}, + {1711, 2}, + 2 + } + { + {1729, 2}, + {1711, 2}, + {1730, 2}, + 2 + } + { + {1712, 2}, + {1729, 2}, + {1730, 2}, + 2 + } + { + {1712, 2}, + {1730, 2}, + {1717, 2}, + 2 + } + { + {1717, 2}, + {1730, 2}, + {1723, 2}, + 2 + } + { + {1712, 2}, + {1717, 2}, + {1725, 2}, + 2 + } + { + {1726, 2}, + {1717, 2}, + {1715, 2}, + 2 + } + { + {1715, 2}, + {1717, 2}, + {1723, 2}, + 2 + } + { + {1715, 2}, + {1723, 2}, + {1724, 2}, + 2 + } + { + {1724, 2}, + {1723, 2}, + {1718, 2}, + 2 + } + { + {1727, 2}, + {1712, 2}, + {1720, 2}, + 2 + } + { + {1720, 2}, + {1712, 2}, + {1722, 2}, + 2 + } + { + {1722, 2}, + {1712, 2}, + {1725, 2}, + 2 + } + { + {1728, 2}, + {1720, 2}, + {1722, 2}, + 2 + } + { + {1728, 2}, + {1722, 2}, + {1716, 2}, + 2 + } + { + {1719, 2}, + {1722, 2}, + {1725, 2}, + 2 + } + { + {1719, 2}, + {1725, 2}, + {1714, 2}, + 2 + } + { + {1721, 2}, + {1719, 2}, + {1714, 2}, + 2 + } + # Mesh "Plane.011" + { + {1733, 2}, + {1734, 2, "edge" "collidable"}, + {1731, 2}, + 3 + } + { + {1731, 2}, + {1732, 2}, + {1733, 2}, + 3 + } + # Mesh "Plane.012" + { + {1737, 2}, + {1738, 2, "edge" "collidable"}, + {1735, 2}, + 3 + } + { + {1735, 2}, + {1736, 2}, + {1737, 2}, + 3 + } + # Mesh "Plane.013" + { + {1741, 2}, + {1742, 2, "edge" "collidable"}, + {1739, 2}, + 3 + } + { + {1739, 2}, + {1740, 2}, + {1741, 2}, + 3 + } + # Mesh "Plane.014" + { + {1745, 2}, + {1746, 2, "edge" "collidable"}, + {1743, 2}, + 3 + } + { + {1743, 2}, + {1744, 2}, + {1745, 2}, + 3 + } + # Mesh "Plane.015" + { + {1749, 2}, + {1750, 2, "edge" "collidable"}, + {1747, 2}, + 3 + } + { + {1747, 2}, + {1748, 2}, + {1749, 2}, + 3 + } + # Mesh "Plane.016" + { + {1753, 2}, + {1754, 2, "edge" "collidable"}, + {1751, 2}, + 3 + } + { + {1751, 2}, + {1752, 2}, + {1753, 2}, + 3 + } + # Mesh "Plane.017" + { + {1757, 2}, + {1758, 2, "edge" "collidable"}, + {1755, 2}, + 3 + } + { + {1755, 2}, + {1756, 2}, + {1757, 2}, + 3 + } + # Mesh "Plane.018" + { + {1761, 2}, + {1762, 2, "edge" "collidable"}, + {1759, 2}, + 3 + } + { + {1759, 2}, + {1760, 2}, + {1761, 2}, + 3 + } + # Mesh "Plane.019" + { + {1765, 2}, + {1766, 2, "edge" "collidable"}, + {1763, 2}, + 3 + } + { + {1763, 2}, + {1764, 2}, + {1765, 2}, + 3 + } + # Mesh "Plane.020" + { + {1769, 2}, + {1770, 2, "edge" "collidable"}, + {1767, 2}, + 3 + } + { + {1767, 2}, + {1768, 2}, + {1769, 2}, + 3 + } + # Mesh "Plane.024" + { + {1789, 2}, + {1773, 2, "edge" "collidable"}, + {1771, 2}, + 2 + } + { + {1789, 2}, + {1771, 2}, + {1790, 2}, + 2 + } + { + {1772, 2}, + {1789, 2}, + {1790, 2}, + 2 + } + { + {1772, 2}, + {1790, 2}, + {1777, 2}, + 2 + } + { + {1777, 2}, + {1790, 2}, + {1783, 2}, + 2 + } + { + {1772, 2}, + {1777, 2}, + {1785, 2}, + 2 + } + { + {1786, 2}, + {1777, 2}, + {1775, 2}, + 2 + } + { + {1775, 2}, + {1777, 2}, + {1783, 2}, + 2 + } + { + {1775, 2}, + {1783, 2}, + {1784, 2}, + 2 + } + { + {1784, 2}, + {1783, 2}, + {1778, 2}, + 2 + } + { + {1787, 2}, + {1772, 2}, + {1780, 2}, + 2 + } + { + {1780, 2}, + {1772, 2}, + {1782, 2}, + 2 + } + { + {1782, 2}, + {1772, 2}, + {1785, 2}, + 2 + } + { + {1788, 2}, + {1780, 2}, + {1782, 2}, + 2 + } + { + {1788, 2}, + {1782, 2}, + {1776, 2}, + 2 + } + { + {1779, 2}, + {1782, 2}, + {1785, 2}, + 2 + } + { + {1779, 2}, + {1785, 2}, + {1774, 2}, + 2 + } + { + {1781, 2}, + {1779, 2}, + {1774, 2}, + 2 + } + # Mesh "Plane.025" + { + {1809, 2}, + {1793, 2, "edge" "collidable"}, + {1791, 2}, + 2 + } + { + {1809, 2}, + {1791, 2}, + {1810, 2}, + 2 + } + { + {1792, 2}, + {1809, 2}, + {1810, 2}, + 2 + } + { + {1792, 2}, + {1810, 2}, + {1797, 2}, + 2 + } + { + {1797, 2}, + {1810, 2}, + {1803, 2}, + 2 + } + { + {1792, 2}, + {1797, 2}, + {1805, 2}, + 2 + } + { + {1806, 2}, + {1797, 2}, + {1795, 2}, + 2 + } + { + {1795, 2}, + {1797, 2}, + {1803, 2}, + 2 + } + { + {1795, 2}, + {1803, 2}, + {1804, 2}, + 2 + } + { + {1804, 2}, + {1803, 2}, + {1798, 2}, + 2 + } + { + {1807, 2}, + {1792, 2}, + {1800, 2}, + 2 + } + { + {1800, 2}, + {1792, 2}, + {1802, 2}, + 2 + } + { + {1802, 2}, + {1792, 2}, + {1805, 2}, + 2 + } + { + {1808, 2}, + {1800, 2}, + {1802, 2}, + 2 + } + { + {1808, 2}, + {1802, 2}, + {1796, 2}, + 2 + } + { + {1799, 2}, + {1802, 2}, + {1805, 2}, + 2 + } + { + {1799, 2}, + {1805, 2}, + {1794, 2}, + 2 + } + { + {1801, 2}, + {1799, 2}, + {1794, 2}, + 2 + } + # Mesh "Plane.026" + { + {1829, 2}, + {1813, 2, "edge" "collidable"}, + {1811, 2}, + 2 + } + { + {1829, 2}, + {1811, 2}, + {1830, 2}, + 2 + } + { + {1812, 2}, + {1829, 2}, + {1830, 2}, + 2 + } + { + {1812, 2}, + {1830, 2}, + {1817, 2}, + 2 + } + { + {1817, 2}, + {1830, 2}, + {1823, 2}, + 2 + } + { + {1812, 2}, + {1817, 2}, + {1825, 2}, + 2 + } + { + {1826, 2}, + {1817, 2}, + {1815, 2}, + 2 + } + { + {1815, 2}, + {1817, 2}, + {1823, 2}, + 2 + } + { + {1815, 2}, + {1823, 2}, + {1824, 2}, + 2 + } + { + {1824, 2}, + {1823, 2}, + {1818, 2}, + 2 + } + { + {1827, 2}, + {1812, 2}, + {1820, 2}, + 2 + } + { + {1820, 2}, + {1812, 2}, + {1822, 2}, + 2 + } + { + {1822, 2}, + {1812, 2}, + {1825, 2}, + 2 + } + { + {1828, 2}, + {1820, 2}, + {1822, 2}, + 2 + } + { + {1828, 2}, + {1822, 2}, + {1816, 2}, + 2 + } + { + {1819, 2}, + {1822, 2}, + {1825, 2}, + 2 + } + { + {1819, 2}, + {1825, 2}, + {1814, 2}, + 2 + } + { + {1821, 2}, + {1819, 2}, + {1814, 2}, + 2 + } + # Mesh "Plane.028" + { + {1833, 2}, + {1834, 2, "edge" "collidable"}, + {1831, 2}, + 3 + } + { + {1831, 2}, + {1832, 2}, + {1833, 2}, + 3 + } + # Mesh "Plane.029" + { + {1837, 2, "edge" "foreground"}, + {1838, 2, "edge" "foreground"}, + {1835, 2, "foreground"}, + 1 + } + { + {1835, 2, "edge" "foreground"}, + {1836, 2, "edge" "foreground"}, + {1837, 2, "foreground"}, + 1 + } + # Mesh "Plane.030" + { + {1841, 2, "edge" "foreground"}, + {1842, 2, "edge" "foreground"}, + {1839, 2, "foreground"}, + 1 + } + { + {1839, 2, "edge" "foreground"}, + {1840, 2, "edge" "foreground"}, + {1841, 2, "foreground"}, + 1 + } + # Mesh "Plane.031" + { + {1845, 2, "edge" "foreground"}, + {1846, 2, "edge" "foreground"}, + {1843, 2, "foreground"}, + 1 + } + { + {1843, 2, "edge" "foreground"}, + {1844, 2, "edge" "foreground"}, + {1845, 2, "foreground"}, + 1 + } + # Mesh "Plane.034" + { + {1849, 2, "edge" "foreground"}, + {1850, 2, "edge" "foreground"}, + {1847, 2, "foreground"}, + 1 + } + { + {1847, 2, "edge" "foreground"}, + {1848, 2, "edge" "foreground"}, + {1849, 2, "foreground"}, + 1 + } + # Mesh "Plane.035" + { + {1853, 2, "edge" "foreground"}, + {1854, 2, "edge" "foreground"}, + {1851, 2, "foreground"}, + 1 + } + { + {1851, 2, "edge" "foreground"}, + {1852, 2, "edge" "foreground"}, + {1853, 2, "foreground"}, + 1 + } + # Mesh "Plane.036" + { + {1857, 2, "edge" "foreground"}, + {1858, 2, "edge" "foreground"}, + {1855, 2, "foreground"}, + 1 + } + { + {1855, 2, "edge" "foreground"}, + {1856, 2, "edge" "foreground"}, + {1857, 2, "foreground"}, + 1 + } + # Mesh "Plane.037" + { + {1861, 2, "edge" "foreground"}, + {1862, 2, "edge" "foreground"}, + {1859, 2, "foreground"}, + 1 + } + { + {1859, 2, "edge" "foreground"}, + {1860, 2, "edge" "foreground"}, + {1861, 2, "foreground"}, + 1 + } + # Mesh "Plane.038" + { + {1865, 2, "edge" "foreground"}, + {1866, 2, "edge" "foreground"}, + {1863, 2, "foreground"}, + 1 + } + { + {1863, 2, "edge" "foreground"}, + {1864, 2, "edge" "foreground"}, + {1865, 2, "foreground"}, + 1 + } + # Mesh "Plane.039" + { + {1869, 2, "edge" "foreground"}, + {1870, 2, "edge" "foreground"}, + {1867, 2, "foreground"}, + 1 + } + { + {1867, 2, "edge" "foreground"}, + {1868, 2, "edge" "foreground"}, + {1869, 2, "foreground"}, + 1 + } + # Mesh "Plane.040" + { + {1889, 2}, + {1873, 2, "edge" "collidable"}, + {1871, 2}, + 2 + } + { + {1889, 2}, + {1871, 2}, + {1890, 2}, + 2 + } + { + {1872, 2}, + {1889, 2}, + {1890, 2}, + 2 + } + { + {1872, 2}, + {1890, 2}, + {1877, 2}, + 2 + } + { + {1877, 2}, + {1890, 2}, + {1883, 2}, + 2 + } + { + {1872, 2}, + {1877, 2}, + {1885, 2}, + 2 + } + { + {1886, 2}, + {1877, 2}, + {1875, 2}, + 2 + } + { + {1875, 2}, + {1877, 2}, + {1883, 2}, + 2 + } + { + {1875, 2}, + {1883, 2}, + {1884, 2}, + 2 + } + { + {1884, 2}, + {1883, 2}, + {1878, 2}, + 2 + } + { + {1887, 2}, + {1872, 2}, + {1880, 2}, + 2 + } + { + {1880, 2}, + {1872, 2}, + {1882, 2}, + 2 + } + { + {1882, 2}, + {1872, 2}, + {1885, 2}, + 2 + } + { + {1888, 2}, + {1880, 2}, + {1882, 2}, + 2 + } + { + {1888, 2}, + {1882, 2}, + {1876, 2}, + 2 + } + { + {1879, 2}, + {1882, 2}, + {1885, 2}, + 2 + } + { + {1879, 2}, + {1885, 2}, + {1874, 2}, + 2 + } + { + {1881, 2}, + {1879, 2}, + {1874, 2}, + 2 + } + # Mesh "Font" + { + {1941, 2, "edge" "collidable"}, + {1940, 2, "edge" "collidable"}, + {1939, 2}, + 1 + } + { + {1941, 2}, + {1939, 2}, + {1947, 2}, + 1 + } + { + {1947, 2}, + {1939, 2, "edge" "collidable"}, + {1946, 2}, + 1 + } + { + {1941, 2}, + {1947, 2, "edge" "collidable"}, + {1949, 2}, + 1 + } + { + {1948, 2, "edge" "collidable"}, + {1947, 2}, + {1946, 2}, + 1 + } + { + {1941, 2}, + {1949, 2}, + {1943, 2}, + 1 + } + { + {1943, 2}, + {1949, 2, "edge" "collidable"}, + {1948, 2}, + 1 + } + { + {1943, 2}, + {1948, 2}, + {1944, 2, "edge" "collidable"}, + 1 + } + { + {1944, 2}, + {1948, 2}, + {1946, 2}, + 1 + } + { + {1941, 2}, + {1943, 2, "edge" "collidable"}, + {1942, 2, "edge" "collidable"}, + 1 + } + { + {1945, 2, "edge" "collidable"}, + {1944, 2}, + {1946, 2, "edge" "collidable"}, + 1 + } + { + {1952, 2, "edge" "collidable"}, + {1951, 2, "edge" "collidable"}, + {1950, 2}, + 1 + } + { + {1952, 2}, + {1950, 2, "edge" "collidable"}, + {1953, 2, "edge" "collidable"}, + 1 + } + { + {1956, 2, "edge" "collidable"}, + {1955, 2, "edge" "collidable"}, + {1954, 2}, + 1 + } + { + {1956, 2}, + {1954, 2, "edge" "collidable"}, + {1957, 2, "edge" "collidable"}, + 1 + } + { + {1978, 2, "edge" "collidable"}, + {1977, 2, "edge" "collidable"}, + {1976, 2}, + 1 + } + { + {1978, 2}, + {1976, 2, "edge" "collidable"}, + {1975, 2}, + 1 + } + { + {1979, 2, "edge" "collidable"}, + {1978, 2}, + {1975, 2}, + 1 + } + { + {1979, 2}, + {1975, 2, "edge" "collidable"}, + {1974, 2}, + 1 + } + { + {1980, 2, "edge" "collidable"}, + {1979, 2}, + {1974, 2}, + 1 + } + { + {1980, 2}, + {1974, 2}, + {2002, 2}, + 1 + } + { + {2002, 2}, + {1974, 2}, + {2003, 2, "edge" "collidable"}, + 1 + } + { + {2003, 2}, + {1974, 2, "edge" "collidable"}, + {1973, 2}, + 1 + } + { + {1981, 2, "edge" "collidable"}, + {1980, 2}, + {2001, 2}, + 1 + } + { + {2001, 2}, + {1980, 2}, + {2002, 2, "edge" "collidable"}, + 1 + } + { + {1981, 2}, + {2001, 2, "edge" "collidable"}, + {2000, 2}, + 1 + } + { + {2004, 2, "edge" "collidable"}, + {2003, 2}, + {1973, 2}, + 1 + } + { + {1981, 2}, + {2000, 2, "edge" "collidable"}, + {1999, 2}, + 1 + } + { + {2005, 2, "edge" "collidable"}, + {2004, 2}, + {1973, 2}, + 1 + } + { + {1981, 2}, + {1999, 2, "edge" "collidable"}, + {1998, 2}, + 1 + } + { + {2006, 2, "edge" "collidable"}, + {2005, 2}, + {1973, 2}, + 1 + } + { + {1982, 2, "edge" "collidable"}, + {1981, 2}, + {1998, 2}, + 1 + } + { + {2006, 2}, + {1973, 2, "edge" "collidable"}, + {1972, 2}, + 1 + } + { + {1982, 2}, + {1998, 2, "edge" "collidable"}, + {1997, 2}, + 1 + } + { + {2007, 2, "edge" "collidable"}, + {2006, 2}, + {1972, 2}, + 1 + } + { + {1982, 2}, + {1997, 2, "edge" "collidable"}, + {1996, 2}, + 1 + } + { + {2008, 2, "edge" "collidable"}, + {2007, 2}, + {1972, 2}, + 1 + } + { + {1983, 2, "edge" "collidable"}, + {1982, 2}, + {1996, 2}, + 1 + } + { + {2008, 2}, + {1972, 2, "edge" "collidable"}, + {1971, 2}, + 1 + } + { + {1983, 2}, + {1996, 2, "edge" "collidable"}, + {2008, 2}, + 1 + } + { + {1983, 2}, + {2008, 2}, + {1971, 2}, + 1 + } + { + {1984, 2, "edge" "collidable"}, + {1983, 2}, + {1970, 2}, + 1 + } + { + {1970, 2}, + {1983, 2}, + {1971, 2, "edge" "collidable"}, + 1 + } + { + {1984, 2}, + {1970, 2, "edge" "collidable"}, + {1969, 2}, + 1 + } + { + {1984, 2}, + {1969, 2, "edge" "collidable"}, + {1968, 2}, + 1 + } + { + {1985, 2, "edge" "collidable"}, + {1984, 2}, + {1968, 2}, + 1 + } + { + {1985, 2}, + {1968, 2, "edge" "collidable"}, + {1967, 2}, + 1 + } + { + {1959, 2, "edge" "collidable"}, + {1958, 2, "edge" "collidable"}, + {1995, 2}, + 1 + } + { + {1960, 2, "edge" "collidable"}, + {1959, 2}, + {1995, 2}, + 1 + } + { + {1986, 2, "edge" "collidable"}, + {1985, 2}, + {1967, 2}, + 1 + } + { + {1986, 2}, + {1967, 2, "edge" "collidable"}, + {1966, 2}, + 1 + } + { + {1961, 2, "edge" "collidable"}, + {1960, 2}, + {1995, 2}, + 1 + } + { + {1986, 2}, + {1966, 2, "edge" "collidable"}, + {1965, 2}, + 1 + } + { + {1962, 2, "edge" "collidable"}, + {1961, 2}, + {1995, 2}, + 1 + } + { + {1963, 2, "edge" "collidable"}, + {1962, 2}, + {1995, 2}, + 1 + } + { + {1986, 2}, + {1965, 2, "edge" "collidable"}, + {1964, 2}, + 1 + } + { + {1964, 2, "edge" "collidable"}, + {1963, 2}, + {1995, 2}, + 1 + } + { + {1986, 2}, + {1964, 2}, + {1995, 2}, + 1 + } + { + {1987, 2, "edge" "collidable"}, + {1986, 2}, + {1995, 2}, + 1 + } + { + {1987, 2}, + {1995, 2, "edge" "collidable"}, + {1994, 2}, + 1 + } + { + {1987, 2}, + {1994, 2, "edge" "collidable"}, + {1993, 2}, + 1 + } + { + {1988, 2, "edge" "collidable"}, + {1987, 2}, + {1993, 2}, + 1 + } + { + {1988, 2}, + {1993, 2, "edge" "collidable"}, + {1992, 2}, + 1 + } + { + {1988, 2}, + {1992, 2, "edge" "collidable"}, + {1991, 2}, + 1 + } + { + {1989, 2, "edge" "collidable"}, + {1988, 2}, + {1991, 2}, + 1 + } + { + {1989, 2}, + {1991, 2, "edge" "collidable"}, + {1990, 2, "edge" "collidable"}, + 1 + } + { + {2011, 2, "edge" "collidable"}, + {2010, 2, "edge" "collidable"}, + {2009, 2}, + 1 + } + { + {2011, 2}, + {2009, 2, "edge" "collidable"}, + {2090, 2}, + 1 + } + { + {2012, 2, "edge" "collidable"}, + {2011, 2}, + {2090, 2}, + 1 + } + { + {2013, 2, "edge" "collidable"}, + {2012, 2}, + {2090, 2}, + 1 + } + { + {2014, 2, "edge" "collidable"}, + {2013, 2}, + {2089, 2}, + 1 + } + { + {2089, 2}, + {2013, 2}, + {2090, 2, "edge" "collidable"}, + 1 + } + { + {2014, 2}, + {2089, 2}, + {2109, 2}, + 1 + } + { + {2109, 2}, + {2089, 2, "edge" "collidable"}, + {2088, 2}, + 1 + } + { + {2015, 2, "edge" "collidable"}, + {2014, 2}, + {2108, 2}, + 1 + } + { + {2108, 2}, + {2014, 2}, + {2109, 2, "edge" "collidable"}, + 1 + } + { + {2110, 2, "edge" "collidable"}, + {2109, 2}, + {2088, 2}, + 1 + } + { + {2111, 2, "edge" "collidable"}, + {2110, 2}, + {2088, 2}, + 1 + } + { + {2015, 2}, + {2108, 2, "edge" "collidable"}, + {2107, 2}, + 1 + } + { + {2111, 2}, + {2088, 2, "edge" "collidable"}, + {2087, 2}, + 1 + } + { + {2112, 2, "edge" "collidable"}, + {2111, 2}, + {2087, 2}, + 1 + } + { + {2015, 2}, + {2107, 2, "edge" "collidable"}, + {2106, 2}, + 1 + } + { + {2113, 2, "edge" "collidable"}, + {2112, 2}, + {2087, 2}, + 1 + } + { + {2015, 2}, + {2106, 2, "edge" "collidable"}, + {2105, 2}, + 1 + } + { + {2113, 2}, + {2087, 2, "edge" "collidable"}, + {2086, 2}, + 1 + } + { + {2016, 2, "edge" "collidable"}, + {2015, 2}, + {2105, 2}, + 1 + } + { + {2114, 2, "edge" "collidable"}, + {2113, 2}, + {2086, 2}, + 1 + } + { + {2114, 2}, + {2086, 2, "edge" "collidable"}, + {2085, 2}, + 1 + } + { + {2016, 2}, + {2105, 2, "edge" "collidable"}, + {2104, 2}, + 1 + } + { + {2114, 2}, + {2085, 2, "edge" "collidable"}, + {2084, 2}, + 1 + } + { + {2091, 2, "edge" "collidable"}, + {2114, 2}, + {2084, 2}, + 1 + } + { + {2016, 2}, + {2104, 2, "edge" "collidable"}, + {2103, 2}, + 1 + } + { + {2091, 2}, + {2084, 2, "edge" "collidable"}, + {2083, 2}, + 1 + } + { + {2017, 2, "edge" "collidable"}, + {2016, 2}, + {2103, 2}, + 1 + } + { + {2092, 2, "edge" "collidable"}, + {2091, 2}, + {2083, 2}, + 1 + } + { + {2017, 2}, + {2103, 2, "edge" "collidable"}, + {2102, 2}, + 1 + } + { + {2092, 2}, + {2083, 2, "edge" "collidable"}, + {2082, 2}, + 1 + } + { + {2018, 2, "edge" "collidable"}, + {2017, 2}, + {2102, 2}, + 1 + } + { + {2093, 2, "edge" "collidable"}, + {2092, 2}, + {2082, 2}, + 1 + } + { + {2018, 2}, + {2102, 2, "edge" "collidable"}, + {2101, 2}, + 1 + } + { + {2093, 2}, + {2082, 2, "edge" "collidable"}, + {2081, 2}, + 1 + } + { + {2019, 2, "edge" "collidable"}, + {2018, 2}, + {2101, 2}, + 1 + } + { + {2094, 2, "edge" "collidable"}, + {2093, 2}, + {2081, 2}, + 1 + } + { + {2020, 2, "edge" "collidable"}, + {2019, 2}, + {2101, 2}, + 1 + } + { + {2020, 2}, + {2101, 2, "edge" "collidable"}, + {2100, 2}, + 1 + } + { + {2094, 2}, + {2081, 2, "edge" "collidable"}, + {2080, 2}, + 1 + } + { + {2021, 2, "edge" "collidable"}, + {2020, 2}, + {2100, 2}, + 1 + } + { + {2095, 2, "edge" "collidable"}, + {2094, 2}, + {2080, 2}, + 1 + } + { + {2021, 2}, + {2100, 2, "edge" "collidable"}, + {2099, 2}, + 1 + } + { + {2095, 2}, + {2080, 2, "edge" "collidable"}, + {2079, 2}, + 1 + } + { + {2022, 2, "edge" "collidable"}, + {2021, 2}, + {2099, 2}, + 1 + } + { + {2096, 2, "edge" "collidable"}, + {2095, 2}, + {2079, 2}, + 1 + } + { + {2022, 2}, + {2099, 2, "edge" "collidable"}, + {2098, 2}, + 1 + } + { + {2097, 2, "edge" "collidable"}, + {2096, 2}, + {2079, 2}, + 1 + } + { + {2022, 2}, + {2098, 2, "edge" "collidable"}, + {2097, 2}, + 1 + } + { + {2023, 2, "edge" "collidable"}, + {2022, 2}, + {2097, 2}, + 1 + } + { + {2023, 2}, + {2097, 2}, + {2079, 2}, + 1 + } + { + {2023, 2}, + {2079, 2, "edge" "collidable"}, + {2078, 2}, + 1 + } + { + {2024, 2, "edge" "collidable"}, + {2023, 2}, + {2078, 2}, + 1 + } + { + {2024, 2}, + {2078, 2, "edge" "collidable"}, + {2077, 2}, + 1 + } + { + {2025, 2, "edge" "collidable"}, + {2024, 2}, + {2077, 2}, + 1 + } + { + {2025, 2}, + {2077, 2, "edge" "collidable"}, + {2076, 2}, + 1 + } + { + {2026, 2, "edge" "collidable"}, + {2025, 2}, + {2076, 2}, + 1 + } + { + {2027, 2, "edge" "collidable"}, + {2026, 2}, + {2076, 2}, + 1 + } + { + {2028, 2, "edge" "collidable"}, + {2027, 2}, + {2076, 2}, + 1 + } + { + {2028, 2}, + {2076, 2, "edge" "collidable"}, + {2075, 2}, + 1 + } + { + {2029, 2, "edge" "collidable"}, + {2028, 2}, + {2075, 2}, + 1 + } + { + {2030, 2, "edge" "collidable"}, + {2029, 2}, + {2075, 2}, + 1 + } + { + {2031, 2, "edge" "collidable"}, + {2030, 2}, + {2075, 2}, + 1 + } + { + {2031, 2}, + {2075, 2, "edge" "collidable"}, + {2074, 2}, + 1 + } + { + {2032, 2, "edge" "collidable"}, + {2031, 2}, + {2074, 2}, + 1 + } + { + {2032, 2}, + {2074, 2, "edge" "collidable"}, + {2073, 2}, + 1 + } + { + {2032, 2}, + {2073, 2, "edge" "collidable"}, + {2072, 2}, + 1 + } + { + {2033, 2, "edge" "collidable"}, + {2032, 2}, + {2072, 2}, + 1 + } + { + {2033, 2}, + {2072, 2, "edge" "collidable"}, + {2071, 2}, + 1 + } + { + {2034, 2, "edge" "collidable"}, + {2033, 2}, + {2071, 2}, + 1 + } + { + {2035, 2, "edge" "collidable"}, + {2034, 2}, + {2071, 2}, + 1 + } + { + {2035, 2}, + {2071, 2, "edge" "collidable"}, + {2070, 2}, + 1 + } + { + {2036, 2, "edge" "collidable"}, + {2035, 2}, + {2070, 2}, + 1 + } + { + {2036, 2}, + {2070, 2, "edge" "collidable"}, + {2069, 2}, + 1 + } + { + {2037, 2, "edge" "collidable"}, + {2036, 2}, + {2069, 2}, + 1 + } + { + {2037, 2}, + {2069, 2, "edge" "collidable"}, + {2068, 2}, + 1 + } + { + {2038, 2, "edge" "collidable"}, + {2037, 2}, + {2068, 2}, + 1 + } + { + {2038, 2}, + {2068, 2, "edge" "collidable"}, + {2067, 2}, + 1 + } + { + {2039, 2, "edge" "collidable"}, + {2038, 2}, + {2067, 2}, + 1 + } + { + {2039, 2}, + {2067, 2, "edge" "collidable"}, + {2066, 2}, + 1 + } + { + {2040, 2, "edge" "collidable"}, + {2039, 2}, + {2066, 2}, + 1 + } + { + {2040, 2}, + {2066, 2, "edge" "collidable"}, + {2065, 2}, + 1 + } + { + {2041, 2, "edge" "collidable"}, + {2040, 2}, + {2065, 2}, + 1 + } + { + {2041, 2}, + {2065, 2, "edge" "collidable"}, + {2064, 2}, + 1 + } + { + {2042, 2, "edge" "collidable"}, + {2041, 2}, + {2064, 2}, + 1 + } + { + {2042, 2}, + {2064, 2, "edge" "collidable"}, + {2063, 2}, + 1 + } + { + {2043, 2, "edge" "collidable"}, + {2042, 2}, + {2063, 2}, + 1 + } + { + {2043, 2}, + {2063, 2, "edge" "collidable"}, + {2062, 2}, + 1 + } + { + {2044, 2, "edge" "collidable"}, + {2043, 2}, + {2062, 2}, + 1 + } + { + {2044, 2}, + {2062, 2}, + {2133, 2}, + 1 + } + { + {2133, 2}, + {2062, 2}, + {2134, 2, "edge" "collidable"}, + 1 + } + { + {2134, 2}, + {2062, 2, "edge" "collidable"}, + {2061, 2}, + 1 + } + { + {2045, 2, "edge" "collidable"}, + {2044, 2}, + {2132, 2}, + 1 + } + { + {2132, 2}, + {2044, 2}, + {2133, 2, "edge" "collidable"}, + 1 + } + { + {2135, 2, "edge" "collidable"}, + {2134, 2}, + {2061, 2}, + 1 + } + { + {2045, 2}, + {2132, 2, "edge" "collidable"}, + {2131, 2}, + 1 + } + { + {2136, 2, "edge" "collidable"}, + {2135, 2}, + {2061, 2}, + 1 + } + { + {2045, 2}, + {2131, 2, "edge" "collidable"}, + {2130, 2}, + 1 + } + { + {2136, 2}, + {2061, 2, "edge" "collidable"}, + {2060, 2}, + 1 + } + { + {2137, 2, "edge" "collidable"}, + {2136, 2}, + {2060, 2}, + 1 + } + { + {2046, 2, "edge" "collidable"}, + {2045, 2}, + {2130, 2}, + 1 + } + { + {2046, 2}, + {2130, 2, "edge" "collidable"}, + {2129, 2}, + 1 + } + { + {2138, 2, "edge" "collidable"}, + {2137, 2}, + {2060, 2}, + 1 + } + { + {2046, 2}, + {2129, 2, "edge" "collidable"}, + {2128, 2}, + 1 + } + { + {2138, 2}, + {2060, 2, "edge" "collidable"}, + {2059, 2}, + 1 + } + { + {2047, 2, "edge" "collidable"}, + {2046, 2}, + {2128, 2}, + 1 + } + { + {2115, 2, "edge" "collidable"}, + {2138, 2}, + {2059, 2}, + 1 + } + { + {2047, 2}, + {2128, 2, "edge" "collidable"}, + {2127, 2}, + 1 + } + { + {2115, 2}, + {2059, 2, "edge" "collidable"}, + {2058, 2}, + 1 + } + { + {2047, 2}, + {2127, 2, "edge" "collidable"}, + {2126, 2}, + 1 + } + { + {2048, 2, "edge" "collidable"}, + {2047, 2}, + {2126, 2}, + 1 + } + { + {2116, 2, "edge" "collidable"}, + {2115, 2}, + {2058, 2}, + 1 + } + { + {2048, 2}, + {2126, 2, "edge" "collidable"}, + {2125, 2}, + 1 + } + { + {2117, 2, "edge" "collidable"}, + {2116, 2}, + {2058, 2}, + 1 + } + { + {2048, 2}, + {2125, 2, "edge" "collidable"}, + {2124, 2}, + 1 + } + { + {2117, 2}, + {2058, 2, "edge" "collidable"}, + {2057, 2}, + 1 + } + { + {2118, 2, "edge" "collidable"}, + {2117, 2}, + {2057, 2}, + 1 + } + { + {2049, 2, "edge" "collidable"}, + {2048, 2}, + {2124, 2}, + 1 + } + { + {2049, 2}, + {2124, 2, "edge" "collidable"}, + {2123, 2}, + 1 + } + { + {2119, 2, "edge" "collidable"}, + {2118, 2}, + {2057, 2}, + 1 + } + { + {2049, 2}, + {2123, 2, "edge" "collidable"}, + {2122, 2}, + 1 + } + { + {2120, 2, "edge" "collidable"}, + {2119, 2}, + {2057, 2}, + 1 + } + { + {2049, 2}, + {2122, 2, "edge" "collidable"}, + {2121, 2}, + 1 + } + { + {2121, 2, "edge" "collidable"}, + {2120, 2}, + {2057, 2}, + 1 + } + { + {2049, 2}, + {2121, 2}, + {2057, 2}, + 1 + } + { + {2049, 2}, + {2057, 2, "edge" "collidable"}, + {2056, 2}, + 1 + } + { + {2050, 2, "edge" "collidable"}, + {2049, 2}, + {2056, 2}, + 1 + } + { + {2051, 2, "edge" "collidable"}, + {2050, 2}, + {2056, 2}, + 1 + } + { + {2051, 2}, + {2056, 2, "edge" "collidable"}, + {2055, 2}, + 1 + } + { + {2052, 2, "edge" "collidable"}, + {2051, 2}, + {2055, 2}, + 1 + } + { + {2052, 2}, + {2055, 2, "edge" "collidable"}, + {2054, 2}, + 1 + } + { + {2053, 2, "edge" "collidable"}, + {2052, 2}, + {2054, 2, "edge" "collidable"}, + 1 + } + { + {2162, 2, "edge" "collidable"}, + {2161, 2, "edge" "collidable"}, + {2160, 2}, + 1 + } + { + {2162, 2}, + {2160, 2, "edge" "collidable"}, + {2159, 2}, + 1 + } + { + {2163, 2, "edge" "collidable"}, + {2162, 2}, + {2159, 2}, + 1 + } + { + {2163, 2}, + {2159, 2, "edge" "collidable"}, + {2158, 2}, + 1 + } + { + {2140, 2, "edge" "collidable"}, + {2139, 2, "edge" "collidable"}, + {2169, 2}, + 1 + } + { + {2140, 2}, + {2169, 2, "edge" "collidable"}, + {2168, 2}, + 1 + } + { + {2164, 2, "edge" "collidable"}, + {2163, 2}, + {2158, 2}, + 1 + } + { + {2164, 2}, + {2158, 2, "edge" "collidable"}, + {2157, 2}, + 1 + } + { + {2164, 2}, + {2157, 2, "edge" "collidable"}, + {2156, 2}, + 1 + } + { + {2165, 2, "edge" "collidable"}, + {2164, 2}, + {2156, 2}, + 1 + } + { + {2165, 2}, + {2156, 2, "edge" "collidable"}, + {2155, 2}, + 1 + } + { + {2166, 2, "edge" "collidable"}, + {2165, 2}, + {2155, 2}, + 1 + } + { + {2166, 2}, + {2155, 2}, + {2148, 2}, + 1 + } + { + {2148, 2}, + {2155, 2}, + {2149, 2, "edge" "collidable"}, + 1 + } + { + {2149, 2}, + {2155, 2}, + {2150, 2, "edge" "collidable"}, + 1 + } + { + {2150, 2}, + {2155, 2}, + {2151, 2, "edge" "collidable"}, + 1 + } + { + {2151, 2}, + {2155, 2}, + {2152, 2, "edge" "collidable"}, + 1 + } + { + {2152, 2}, + {2155, 2}, + {2153, 2, "edge" "collidable"}, + 1 + } + { + {2153, 2}, + {2155, 2, "edge" "collidable"}, + {2154, 2, "edge" "collidable"}, + 1 + } + { + {2167, 2, "edge" "collidable"}, + {2166, 2}, + {2147, 2}, + 1 + } + { + {2147, 2}, + {2166, 2}, + {2148, 2, "edge" "collidable"}, + 1 + } + { + {2167, 2}, + {2147, 2, "edge" "collidable"}, + {2146, 2}, + 1 + } + { + {2167, 2}, + {2146, 2, "edge" "collidable"}, + {2145, 2}, + 1 + } + { + {2140, 2}, + {2168, 2, "edge" "collidable"}, + {2167, 2}, + 1 + } + { + {2140, 2}, + {2167, 2}, + {2144, 2}, + 1 + } + { + {2144, 2}, + {2167, 2}, + {2145, 2, "edge" "collidable"}, + 1 + } + { + {2140, 2}, + {2144, 2, "edge" "collidable"}, + {2143, 2}, + 1 + } + { + {2140, 2}, + {2143, 2, "edge" "collidable"}, + {2142, 2}, + 1 + } + { + {2140, 2}, + {2142, 2, "edge" "collidable"}, + {2141, 2, "edge" "collidable"}, + 1 + } + { + {1892, 2, "edge" "collidable"}, + {1891, 2, "edge" "collidable"}, + {1914, 2}, + 1 + } + { + {1892, 2}, + {1914, 2, "edge" "collidable"}, + {1913, 2}, + 1 + } + { + {1893, 2, "edge" "collidable"}, + {1892, 2}, + {1913, 2}, + 1 + } + { + {1893, 2}, + {1913, 2, "edge" "collidable"}, + {1912, 2}, + 1 + } + { + {1894, 2, "edge" "collidable"}, + {1893, 2}, + {1912, 2}, + 1 + } + { + {1894, 2}, + {1912, 2}, + {1915, 2}, + 1 + } + { + {1915, 2}, + {1912, 2}, + {1916, 2, "edge" "collidable"}, + 1 + } + { + {1916, 2}, + {1912, 2, "edge" "collidable"}, + {1911, 2}, + 1 + } + { + {1895, 2, "edge" "collidable"}, + {1894, 2}, + {1938, 2}, + 1 + } + { + {1938, 2}, + {1894, 2}, + {1915, 2, "edge" "collidable"}, + 1 + } + { + {1895, 2}, + {1938, 2, "edge" "collidable"}, + {1937, 2}, + 1 + } + { + {1917, 2, "edge" "collidable"}, + {1916, 2}, + {1911, 2}, + 1 + } + { + {1895, 2}, + {1937, 2, "edge" "collidable"}, + {1936, 2}, + 1 + } + { + {1918, 2, "edge" "collidable"}, + {1917, 2}, + {1911, 2}, + 1 + } + { + {1918, 2}, + {1911, 2, "edge" "collidable"}, + {1910, 2}, + 1 + } + { + {1896, 2, "edge" "collidable"}, + {1895, 2}, + {1936, 2}, + 1 + } + { + {1896, 2}, + {1936, 2, "edge" "collidable"}, + {1935, 2}, + 1 + } + { + {1919, 2, "edge" "collidable"}, + {1918, 2}, + {1910, 2}, + 1 + } + { + {1896, 2}, + {1935, 2, "edge" "collidable"}, + {1934, 2}, + 1 + } + { + {1920, 2, "edge" "collidable"}, + {1919, 2}, + {1910, 2}, + 1 + } + { + {1920, 2}, + {1910, 2, "edge" "collidable"}, + {1909, 2}, + 1 + } + { + {1897, 2, "edge" "collidable"}, + {1896, 2}, + {1934, 2}, + 1 + } + { + {1897, 2}, + {1934, 2, "edge" "collidable"}, + {1933, 2}, + 1 + } + { + {1921, 2, "edge" "collidable"}, + {1920, 2}, + {1909, 2}, + 1 + } + { + {1898, 2, "edge" "collidable"}, + {1897, 2}, + {1933, 2}, + 1 + } + { + {1898, 2}, + {1933, 2, "edge" "collidable"}, + {1932, 2}, + 1 + } + { + {1921, 2}, + {1909, 2, "edge" "collidable"}, + {1908, 2}, + 1 + } + { + {1922, 2, "edge" "collidable"}, + {1921, 2}, + {1908, 2}, + 1 + } + { + {1898, 2}, + {1932, 2, "edge" "collidable"}, + {1931, 2}, + 1 + } + { + {1923, 2, "edge" "collidable"}, + {1922, 2}, + {1908, 2}, + 1 + } + { + {1899, 2, "edge" "collidable"}, + {1898, 2}, + {1931, 2}, + 1 + } + { + {1923, 2}, + {1908, 2, "edge" "collidable"}, + {1907, 2}, + 1 + } + { + {1899, 2}, + {1931, 2, "edge" "collidable"}, + {1930, 2}, + 1 + } + { + {1924, 2, "edge" "collidable"}, + {1923, 2}, + {1907, 2}, + 1 + } + { + {1899, 2}, + {1930, 2, "edge" "collidable"}, + {1929, 2}, + 1 + } + { + {1925, 2, "edge" "collidable"}, + {1924, 2}, + {1907, 2}, + 1 + } + { + {1900, 2, "edge" "collidable"}, + {1899, 2}, + {1929, 2}, + 1 + } + { + {1925, 2}, + {1907, 2, "edge" "collidable"}, + {1906, 2}, + 1 + } + { + {1900, 2}, + {1929, 2, "edge" "collidable"}, + {1928, 2}, + 1 + } + { + {1926, 2, "edge" "collidable"}, + {1925, 2}, + {1906, 2}, + 1 + } + { + {1900, 2}, + {1928, 2, "edge" "collidable"}, + {1927, 2}, + 1 + } + { + {1927, 2, "edge" "collidable"}, + {1926, 2}, + {1906, 2}, + 1 + } + { + {1900, 2}, + {1927, 2}, + {1906, 2}, + 1 + } + { + {1901, 2, "edge" "collidable"}, + {1900, 2}, + {1906, 2}, + 1 + } + { + {1901, 2}, + {1906, 2, "edge" "collidable"}, + {1905, 2}, + 1 + } + { + {1902, 2, "edge" "collidable"}, + {1901, 2}, + {1905, 2}, + 1 + } + { + {1902, 2}, + {1905, 2, "edge" "collidable"}, + {1904, 2}, + 1 + } + { + {1903, 2, "edge" "collidable"}, + {1902, 2}, + {1904, 2, "edge" "collidable"}, + 1 + } + # Mesh "Circle" + { + {2208, 2}, + {2172, 2}, + {2197, 2}, + 2 + } + { + {2215, 2}, + {2192, 2, "edge" "collidable"}, + {2198, 2}, + 2 + } + { + {2190, 2, "edge" "collidable"}, + {2208, 2}, + {2197, 2, "edge" "collidable"}, + 2 + } + { + {2204, 2}, + {2218, 2}, + {2171, 2}, + 2 + } + { + {2215, 2}, + {2198, 2, "edge" "collidable"}, + {2214, 2}, + 2 + } + { + {2184, 2}, + {2192, 2}, + {2215, 2, "edge" "collidable"}, + 2 + } + { + {2182, 2, "edge" "collidable"}, + {2203, 2}, + {2175, 2, "edge" "collidable"}, + 2 + } + { + {2180, 2, "edge" "collidable"}, + {2207, 2}, + {2188, 2, "edge" "collidable"}, + 2 + } + { + {2177, 2}, + {2215, 2}, + {2214, 2}, + 2 + } + { + {2223, 2, "edge" "collidable"}, + {2189, 2, "edge" "collidable"}, + {2205, 2}, + 2 + } + { + {2174, 2}, + {2210, 2, "edge" "collidable"}, + {2170, 2}, + 2 + } + { + {2218, 2}, + {2204, 2, "edge" "collidable"}, + {2209, 2}, + 2 + } + { + {2197, 2}, + {2173, 2, "edge" "collidable"}, + {2206, 2, "edge" "collidable"}, + 2 + } + { + {2203, 2}, + {2199, 2, "edge" "collidable"}, + {2193, 2}, + 2 + } + { + {2197, 2}, + {2172, 2, "edge" "collidable"}, + {2173, 2}, + 2 + } + { + {2202, 2}, + {2200, 2, "edge" "collidable"}, + {2183, 2}, + 2 + } + { + {2207, 2}, + {2183, 2, "edge" "collidable"}, + {2201, 2}, + 2 + } + { + {2221, 2}, + {2205, 2, "edge" "collidable"}, + {2176, 2}, + 2 + } + { + {2219, 2}, + {2174, 2}, + {2218, 2, "edge" "collidable"}, + 2 + } + { + {2187, 2, "edge" "collidable"}, + {2221, 2}, + {2176, 2}, + 2 + } + { + {2207, 2}, + {2210, 2}, + {2174, 2}, + 2 + } + { + {2218, 2}, + {2174, 2}, + {2171, 2}, + 2 + } + { + {2203, 2}, + {2193, 2}, + {2202, 2}, + 2 + } + { + {2176, 2, "edge" "collidable"}, + {2213, 2, "edge" "collidable"}, + {2211, 2}, + 2 + } + { + {2203, 2, "edge" "collidable"}, + {2177, 2}, + {2214, 2}, + 2 + } + { + {2207, 2}, + {2202, 2}, + {2183, 2}, + 2 + } + { + {2203, 2}, + {2202, 2, "edge" "collidable"}, + {2175, 2}, + 2 + } + { + {2176, 2}, + {2211, 2, "edge" "collidable"}, + {2195, 2}, + 2 + } + { + {2174, 2}, + {2170, 2, "edge" "collidable"}, + {2171, 2}, + 2 + } + { + {2187, 2}, + {2176, 2}, + {2195, 2}, + 2 + } + { + {2187, 2}, + {2195, 2}, + {2217, 2}, + 2 + } + { + {2203, 2}, + {2214, 2, "edge" "collidable"}, + {2199, 2}, + 2 + } + { + {2178, 2, "edge" "collidable"}, + {2218, 2}, + {2209, 2, "edge" "collidable"}, + 2 + } + { + {2222, 2, "edge" "collidable"}, + {2215, 2}, + {2177, 2, "edge" "collidable"}, + 2 + } + { + {2207, 2}, + {2174, 2, "edge" "collidable"}, + {2188, 2}, + 2 + } + { + {2207, 2}, + {2201, 2, "edge" "collidable"}, + {2210, 2}, + 2 + } + { + {2208, 2, "edge" "collidable"}, + {2204, 2}, + {2171, 2}, + 2 + } + { + {2187, 2}, + {2217, 2, "edge" "collidable"}, + {2220, 2}, + 2 + } + { + {2195, 2, "edge" "collidable"}, + {2212, 2, "edge" "collidable"}, + {2186, 2}, + 2 + } + { + {2217, 2}, + {2195, 2}, + {2186, 2}, + 2 + } + { + {2185, 2, "edge" "collidable"}, + {2217, 2}, + {2186, 2}, + 2 + } + { + {2179, 2, "edge" "collidable"}, + {2174, 2}, + {2219, 2, "edge" "collidable"}, + 2 + } + { + {2196, 2}, + {2202, 2}, + {2207, 2, "edge" "collidable"}, + 2 + } + { + {2202, 2}, + {2193, 2, "edge" "collidable"}, + {2200, 2}, + 2 + } + { + {2185, 2}, + {2186, 2, "edge" "collidable"}, + {2191, 2}, + 2 + } + { + {2208, 2}, + {2171, 2, "edge" "collidable"}, + {2172, 2}, + 2 + } + { + {2194, 2, "edge" "collidable"}, + {2187, 2}, + {2220, 2, "edge" "collidable"}, + 2 + } + { + {2216, 2, "edge" "collidable"}, + {2185, 2}, + {2184, 2, "edge" "collidable"}, + 2 + } + { + {2184, 2}, + {2185, 2}, + {2191, 2}, + 2 + } + { + {2181, 2, "edge" "collidable"}, + {2202, 2}, + {2196, 2, "edge" "collidable"}, + 2 + } + { + {2184, 2}, + {2191, 2, "edge" "collidable"}, + {2192, 2}, + 2 + } + { + {2205, 2}, + {2221, 2, "edge" "collidable"}, + {2223, 2}, + 2 + } +} + +# Object types +{ + { "bananas", "ding" } # 0 + { "cherries", "ding" } # 1 + { "icecream", "pop" } # 2 + { "orange", "pop" } # 3 + { "sweet", "pop" } # 4 +} + +# Objects +{ + { -8622, -4349, 0, 0, "collidable" } # "Bananas" + { -8388, -3290, 0, 0, "collidable" } # "Bananas.001" + { -8388, -3334, 0, 0, "collidable" } # "Bananas.002" + { -8388, -3378, 0, 0, "collidable" } # "Bananas.003" + { -6756, -2912, 0, 0, "collidable" } # "Bananas.004" + { -6756, -2868, 0, 0, "collidable" } # "Bananas.005" + { -6756, -2823, 0, 0, "collidable" } # "Bananas.006" + { -5545, -2912, 0, 0, "collidable" } # "Bananas.007" + { -5545, -2956, 0, 0, "collidable" } # "Bananas.008" + { -5545, -3000, 0, 0, "collidable" } # "Bananas.009" + { -3993, -2991, 0, 0, "collidable" } # "Bananas.010" + { -3993, -2947, 0, 0, "collidable" } # "Bananas.011" + { -3993, -2903, 0, 0, "collidable" } # "Bananas.012" + { -4138, -3075, 0, 0, "collidable" } # "Bananas.013" + { -4138, -3119, 0, 0, "collidable" } # "Bananas.014" + { -4138, -3163, 0, 0, "collidable" } # "Bananas.015" + { -2794, -2116, 0, 0, "collidable" } # "Bananas.016" + { -2840, -2193, 0, 0, "collidable" } # "Bananas.017" + { -2840, -2149, 0, 0, "collidable" } # "Bananas.018" + { -1129, -1615, 0, 0, "collidable" } # "Bananas.019" + { -1129, -1659, 0, 0, "collidable" } # "Bananas.020" + { -1129, -1567, 0, 0, "collidable" } # "Bananas.021" + { -65, -2182, 0, 0, "collidable" } # "Bananas.022" + { -57, -2274, 0, 0, "collidable" } # "Bananas.023" + { -57, -2230, 0, 0, "collidable" } # "Bananas.024" + { 5433, -1393, 0, 0, "collidable" } # "Bananas.025" + { 5433, -1437, 0, 0, "collidable" } # "Bananas.026" + { 5433, -1481, 0, 0, "collidable" } # "Bananas.027" + { 7865, -1026, 0, 0, "collidable" } # "Bananas.028" + { 7865, -982, 0, 0, "collidable" } # "Bananas.029" + { 7865, -938, 0, 0, "collidable" } # "Bananas.030" + { 5052, -3061, 0, 0, "collidable" } # "Bananas.031" + { 5052, -3105, 0, 0, "collidable" } # "Bananas.032" + { 4997, -3119, 0, 0, "collidable" } # "Bananas.033" + { 3038, -3965, 0, 0, "collidable" } # "Bananas.034" + { 3043, -4068, 0, 0, "collidable" } # "Bananas.035" + { 3043, -4023, 0, 0, "collidable" } # "Bananas.036" + { -1218, -4107, 0, 0, "collidable" } # "Bananas.037" + { -1218, -4151, 0, 0, "collidable" } # "Bananas.038" + { -1183, -4138, 0, 0, "collidable" } # "Bananas.039" + { 219, -4386, 0, 0, "collidable" } # "Bananas.040" + { 165, -4406, 0, 0, "collidable" } # "Bananas.041" + { 147, -4452, 0, 0, "collidable" } # "Bananas.042" + { -3568, -4964, 0, 0, "collidable" } # "Bananas.043" + { -3462, -4961, 0, 0, "collidable" } # "Bananas.044" + { -3634, -4978, 0, 0, "collidable" } # "Bananas.045" + { -5712, -4828, 0, 0, "collidable" } # "Bananas.046" + { -5768, -4851, 0, 0, "collidable" } # "Bananas.047" + { -5721, -4876, 0, 0, "collidable" } # "Bananas.048" + { -7525, -4703, 0, 0, "collidable" } # "Bananas.049" + { -7463, -4712, 0, 0, "collidable" } # "Bananas.050" + { -7398, -4737, 0, 0, "collidable" } # "Bananas.051" + { -9245, -3451, 0, 0, "collidable" } # "Bananas.052" + { -9263, -3411, 0, 0, "collidable" } # "Bananas.053" + { -9266, -3375, 0, 0, "collidable" } # "Bananas.054" + { -7911, -4944, 0, 0, "collidable" } # "Bananas.055" + { -7875, -4937, 0, 0, "collidable" } # "Bananas.056" + { -7838, -4930, 0, 0, "collidable" } # "Bananas.057" + { -7798, -4910, 0, 0, "collidable" } # "Bananas.058" + { -7764, -4900, 0, 0, "collidable" } # "Bananas.059" + { -7728, -4884, 0, 0, "collidable" } # "Bananas.060" + { -7691, -4864, 0, 0, "collidable" } # "Bananas.061" + { 3251, -1892, 0, 0, "collidable" } # "Bananas.062" + { 3324, -1872, 0, 0, "collidable" } # "Bananas.063" + { 3376, -1809, 0, 0, "collidable" } # "Bananas.064" + { 3439, -1736, 0, 0, "collidable" } # "Bananas.065" + { 8187, -1235, 0, 0, "collidable" } # "Bananas.066" + { 8388, -1071, 0, 0, "collidable" } # "Bananas.067" + { 8606, -852, 0, 0, "collidable" } # "Bananas.068" + { 7941, -1381, 0, 0, "collidable" } # "Bananas.069" + { 8105, -1982, 0, 0, "collidable" } # "Bananas.070" + { 8278, -1891, 0, 0, "collidable" } # "Bananas.071" + { 8479, -1727, 0, 0, "collidable" } # "Bananas.072" + { 9518, -1007, 0, 0, "collidable" } # "Bananas.073" + { 9552, -959, 0, 0, "collidable" } # "Bananas.074" + { 9586, -897, 0, 0, "collidable" } # "Bananas.075" + { 9604, -842, 0, 0, "collidable" } # "Bananas.076" + { 9617, -795, 0, 0, "collidable" } # "Bananas.077" + { 9638, -740, 0, 0, "collidable" } # "Bananas.078" + { 9645, -685, 0, 0, "collidable" } # "Bananas.079" + { 9645, -630, 0, 0, "collidable" } # "Bananas.080" + { 9652, -575, 0, 0, "collidable" } # "Bananas.081" + { 9316, -1083, 0, 0, "collidable" } # "Bananas.082" + { 9371, -1083, 0, 0, "collidable" } # "Bananas.083" + { 9434, -1065, 0, 0, "collidable" } # "Bananas.084" + { 9470, -1046, 0, 0, "collidable" } # "Bananas.085" + { -8694, -4308, 0, 1, "collidable" } # "Cherries" + { -6612, -2855, 0, 1, "collidable" } # "Cherries.001" + { -6589, -2900, 0, 1, "collidable" } # "Cherries.002" + { -6557, -2937, 0, 1, "collidable" } # "Cherries.003" + { -6513, -2951, 0, 1, "collidable" } # "Cherries.004" + { -6465, -2951, 0, 1, "collidable" } # "Cherries.005" + { -6447, -2933, 0, 1, "collidable" } # "Cherries.006" + { -4801, -3173, 0, 1, "collidable" } # "Cherries.007" + { -4844, -3147, 0, 1, "collidable" } # "Cherries.008" + { -4891, -3147, 0, 1, "collidable" } # "Cherries.009" + { -4935, -3133, 0, 1, "collidable" } # "Cherries.010" + { -4968, -3096, 0, 1, "collidable" } # "Cherries.011" + { -4991, -3051, 0, 1, "collidable" } # "Cherries.012" + { -807, -1730, 0, 1, "collidable" } # "Cherries.013" + { -784, -1776, 0, 1, "collidable" } # "Cherries.014" + { -751, -1812, 0, 1, "collidable" } # "Cherries.015" + { -707, -1827, 0, 1, "collidable" } # "Cherries.016" + { -660, -1827, 0, 1, "collidable" } # "Cherries.017" + { -642, -1809, 0, 1, "collidable" } # "Cherries.018" + { 2300, -1795, 0, 1, "collidable" } # "Cherries.019" + { 2282, -1814, 0, 1, "collidable" } # "Cherries.020" + { 2235, -1814, 0, 1, "collidable" } # "Cherries.021" + { 2191, -1799, 0, 1, "collidable" } # "Cherries.022" + { 2158, -1763, 0, 1, "collidable" } # "Cherries.023" + { 2135, -1717, 0, 1, "collidable" } # "Cherries.024" + { 3861, -1592, 0, 1, "collidable" } # "Cherries.025" + { 3884, -1637, 0, 1, "collidable" } # "Cherries.026" + { 3917, -1674, 0, 1, "collidable" } # "Cherries.027" + { 3961, -1688, 0, 1, "collidable" } # "Cherries.028" + { 4008, -1688, 0, 1, "collidable" } # "Cherries.029" + { 4033, -1689, 0, 1, "collidable" } # "Cherries.030" + { 5777, -1783, 0, 1, "collidable" } # "Cherries.031" + { 5759, -1801, 0, 1, "collidable" } # "Cherries.032" + { 5712, -1801, 0, 1, "collidable" } # "Cherries.033" + { 5668, -1787, 0, 1, "collidable" } # "Cherries.034" + { 5635, -1750, 0, 1, "collidable" } # "Cherries.035" + { 5612, -1705, 0, 1, "collidable" } # "Cherries.036" + { 7250, -1460, 0, 1, "collidable" } # "Cherries.037" + { 7273, -1505, 0, 1, "collidable" } # "Cherries.038" + { 7306, -1542, 0, 1, "collidable" } # "Cherries.039" + { 7350, -1556, 0, 1, "collidable" } # "Cherries.040" + { 7397, -1556, 0, 1, "collidable" } # "Cherries.041" + { 7441, -1576, 0, 1, "collidable" } # "Cherries.042" + { 1089, -4249, 0, 1, "collidable" } # "Cherries.043" + { 1071, -4268, 0, 1, "collidable" } # "Cherries.044" + { 1023, -4268, 0, 1, "collidable" } # "Cherries.045" + { 980, -4253, 0, 1, "collidable" } # "Cherries.046" + { 947, -4217, 0, 1, "collidable" } # "Cherries.047" + { 924, -4171, 0, 1, "collidable" } # "Cherries.048" + { -921, -4303, 0, 1, "collidable" } # "Cherries.049" + { -899, -4348, 0, 1, "collidable" } # "Cherries.050" + { -866, -4385, 0, 1, "collidable" } # "Cherries.051" + { -822, -4400, 0, 1, "collidable" } # "Cherries.052" + { -774, -4400, 0, 1, "collidable" } # "Cherries.053" + { -756, -4381, 0, 1, "collidable" } # "Cherries.054" + { -2488, -4946, 0, 1, "collidable" } # "Cherries.055" + { -2507, -4964, 0, 1, "collidable" } # "Cherries.056" + { -2554, -4964, 0, 1, "collidable" } # "Cherries.057" + { -2598, -4950, 0, 1, "collidable" } # "Cherries.058" + { -2631, -4913, 0, 1, "collidable" } # "Cherries.059" + { -2653, -4868, 0, 1, "collidable" } # "Cherries.060" + { -6231, -4736, 0, 1, "collidable" } # "Cherries.061" + { -6208, -4781, 0, 1, "collidable" } # "Cherries.062" + { -6175, -4818, 0, 1, "collidable" } # "Cherries.063" + { -6132, -4833, 0, 1, "collidable" } # "Cherries.064" + { -6084, -4833, 0, 1, "collidable" } # "Cherries.065" + { -6066, -4814, 0, 1, "collidable" } # "Cherries.066" + { 8897, -68, 0, -1, "collidable" } # "Exit" + { -8793, -4272, 0, 2, "collidable" } # "Icecream" + { -9275, -3077, 0, 2, "collidable" } # "Icecream.001" + { -9237, -3039, 0, 2, "collidable" } # "Icecream.002" + { -7236, -3039, 0, 2, "collidable" } # "Icecream.003" + { -7274, -3077, 0, 2, "collidable" } # "Icecream.004" + { -3703, -2685, 0, 2, "collidable" } # "Icecream.005" + { -3665, -2648, 0, 2, "collidable" } # "Icecream.006" + { -2265, -1771, 0, 2, "collidable" } # "Icecream.007" + { -2303, -1809, 0, 2, "collidable" } # "Icecream.008" + { 1116, -1999, 0, 2, "collidable" } # "Icecream.009" + { 1154, -1961, 0, 2, "collidable" } # "Icecream.010" + { 4898, -1472, 0, 2, "collidable" } # "Icecream.011" + { 4860, -1510, 0, 2, "collidable" } # "Icecream.012" + { 6407, -1429, 0, 2, "collidable" } # "Icecream.013" + { 6445, -1391, 0, 2, "collidable" } # "Icecream.014" + { 8224, -357, 0, 2, "collidable" } # "Icecream.015" + { 8186, -395, 0, 2, "collidable" } # "Icecream.016" + { -9126, -2986, 0, 2, "collidable" } # "Icecream.017" + { -9185, -2998, 0, 2, "collidable" } # "Icecream.018" + { -7131, -2887, 0, 2, "collidable" } # "Icecream.019" + { -7072, -2876, 0, 2, "collidable" } # "Icecream.020" + { -7182, -2928, 0, 2, "collidable" } # "Icecream.021" + { -7220, -2966, 0, 2, "collidable" } # "Icecream.022" + { -3603, -2603, 0, 2, "collidable" } # "Icecream.023" + { -3565, -2565, 0, 2, "collidable" } # "Icecream.024" + { -3455, -2513, 0, 2, "collidable" } # "Icecream.025" + { -3514, -2524, 0, 2, "collidable" } # "Icecream.026" + { -1978, -1556, 0, 2, "collidable" } # "Icecream.027" + { -1919, -1544, 0, 2, "collidable" } # "Icecream.028" + { -2029, -1597, 0, 2, "collidable" } # "Icecream.029" + { -2067, -1635, 0, 2, "collidable" } # "Icecream.030" + { 785, -2142, 0, 2, "collidable" } # "Icecream.031" + { 823, -2104, 0, 2, "collidable" } # "Icecream.032" + { 933, -2051, 0, 2, "collidable" } # "Icecream.033" + { 875, -2063, 0, 2, "collidable" } # "Icecream.034" + { 1465, -1639, 0, 2, "collidable" } # "Icecream.035" + { 1524, -1627, 0, 2, "collidable" } # "Icecream.036" + { 1413, -1680, 0, 2, "collidable" } # "Icecream.037" + { 1375, -1718, 0, 2, "collidable" } # "Icecream.038" + { 3252, -1438, 0, 2, "collidable" } # "Icecream.039" + { 3290, -1400, 0, 2, "collidable" } # "Icecream.040" + { 3400, -1347, 0, 2, "collidable" } # "Icecream.041" + { 3341, -1359, 0, 2, "collidable" } # "Icecream.042" + { 5006, -1276, 0, 2, "collidable" } # "Icecream.043" + { 5065, -1264, 0, 2, "collidable" } # "Icecream.044" + { 4954, -1317, 0, 2, "collidable" } # "Icecream.045" + { 4917, -1355, 0, 2, "collidable" } # "Icecream.046" + { 6524, -1300, 0, 2, "collidable" } # "Icecream.047" + { 6562, -1262, 0, 2, "collidable" } # "Icecream.048" + { 6672, -1210, 0, 2, "collidable" } # "Icecream.049" + { 6613, -1221, 0, 2, "collidable" } # "Icecream.050" + { 8429, -195, 0, 2, "collidable" } # "Icecream.051" + { 8488, -184, 0, 2, "collidable" } # "Icecream.052" + { 8378, -236, 0, 2, "collidable" } # "Icecream.053" + { 8340, -274, 0, 2, "collidable" } # "Icecream.054" + { 5605, -2726, 0, 2, "collidable" } # "Icecream.055" + { 5643, -2688, 0, 2, "collidable" } # "Icecream.056" + { 5753, -2635, 0, 2, "collidable" } # "Icecream.057" + { 5694, -2647, 0, 2, "collidable" } # "Icecream.058" + { 4485, -3203, 0, 2, "collidable" } # "Icecream.059" + { 4544, -3191, 0, 2, "collidable" } # "Icecream.060" + { 4433, -3244, 0, 2, "collidable" } # "Icecream.061" + { 4395, -3281, 0, 2, "collidable" } # "Icecream.062" + { 3618, -3703, 0, 2, "collidable" } # "Icecream.063" + { 3656, -3665, 0, 2, "collidable" } # "Icecream.064" + { 3766, -3612, 0, 2, "collidable" } # "Icecream.065" + { 3707, -3624, 0, 2, "collidable" } # "Icecream.066" + { 2306, -3671, 0, 2, "collidable" } # "Icecream.067" + { 2364, -3659, 0, 2, "collidable" } # "Icecream.068" + { 2254, -3712, 0, 2, "collidable" } # "Icecream.069" + { 2216, -3750, 0, 2, "collidable" } # "Icecream.070" + { -9564, -3898, 0, 2, "collidable" } # "Icecream.071" + { -9495, -3901, 0, 2, "collidable" } # "Icecream.072" + { -9418, -3890, 0, 2, "collidable" } # "Icecream.073" + { -9364, -3883, 0, 2, "collidable" } # "Icecream.074" + { -9302, -3865, 0, 2, "collidable" } # "Icecream.075" + { -9262, -3836, 0, 2, "collidable" } # "Icecream.076" + { -9229, -3799, 0, 2, "collidable" } # "Icecream.077" + { -9204, -3752, 0, 2, "collidable" } # "Icecream.078" + { -9182, -3705, 0, 2, "collidable" } # "Icecream.079" + { -9153, -3639, 0, 2, "collidable" } # "Icecream.080" + { -8534, -4389, 0, 3, "collidable" } # "Orange" + { -4627, -4845, 0, 3, "collidable" } # "Orange.001" + { -4652, -4882, 0, 3, "collidable" } # "Orange.002" + { -4650, -4921, 0, 3, "collidable" } # "Orange.003" + { -4634, -4959, 0, 3, "collidable" } # "Orange.004" + { -4600, -4994, 0, 3, "collidable" } # "Orange.005" + { -4535, -5020, 0, 3, "collidable" } # "Orange.006" + { -4474, -5028, 0, 3, "collidable" } # "Orange.007" + { -4421, -5033, 0, 3, "collidable" } # "Orange.008" + { -4364, -5035, 0, 3, "collidable" } # "Orange.009" + { -4313, -5032, 0, 3, "collidable" } # "Orange.010" + { -4262, -5024, 0, 3, "collidable" } # "Orange.011" + { -4214, -5013, 0, 3, "collidable" } # "Orange.012" + { -4170, -4999, 0, 3, "collidable" } # "Orange.013" + { -4138, -4978, 0, 3, "collidable" } # "Orange.014" + { -4106, -4957, 0, 3, "collidable" } # "Orange.015" + { -4083, -4931, 0, 3, "collidable" } # "Orange.016" + { -4077, -4900, 0, 3, "collidable" } # "Orange.017" + { -4081, -4870, 0, 3, "collidable" } # "Orange.018" + { -3914, -3223, 0, 3, "collidable" } # "Orange.019" + { 1133, -2347, 0, 3, "collidable" } # "Orange.020" + { 4788, -1814, 0, 3, "collidable" } # "Orange.021" + { 8109, -1294, 0, 3, "collidable" } # "Orange.022" + { 8290, -1181, 0, 3, "collidable" } # "Orange.023" + { 8493, -978, 0, 3, "collidable" } # "Orange.024" + { 8651, -684, 0, 3, "collidable" } # "Orange.025" + { 2055, -4186, 0, 3, "collidable" } # "Orange.026" + { 1607, -2356, 0, 3, "collidable" } # "Orange.027" + { 2026, -2203, 0, 3, "collidable" } # "Orange.028" + { 2109, -2195, 0, 3, "collidable" } # "Orange.029" + { 2914, -2330, 0, 3, "collidable" } # "Orange.030" + { 1209, -2575, 0, 3, "collidable" } # "Orange.031" + { 1270, -2570, 0, 3, "collidable" } # "Orange.032" + { 1357, -2557, 0, 3, "collidable" } # "Orange.033" + { 1410, -2536, 0, 3, "collidable" } # "Orange.034" + { 1467, -2487, 0, 3, "collidable" } # "Orange.035" + { 1532, -2444, 0, 3, "collidable" } # "Orange.036" + { 1707, -2326, 0, 3, "collidable" } # "Orange.037" + { 1795, -2282, 0, 3, "collidable" } # "Orange.038" + { 1921, -2225, 0, 3, "collidable" } # "Orange.039" + { 2197, -2225, 0, 3, "collidable" } # "Orange.040" + { 2324, -2256, 0, 3, "collidable" } # "Orange.041" + { 2446, -2308, 0, 3, "collidable" } # "Orange.042" + { 2560, -2326, 0, 3, "collidable" } # "Orange.043" + { 2664, -2343, 0, 3, "collidable" } # "Orange.044" + { 2787, -2348, 0, 3, "collidable" } # "Orange.045" + { 658, -2605, 0, 3, "collidable" } # "Orange.046" + { 741, -2645, 0, 3, "collidable" } # "Orange.047" + { 837, -2658, 0, 3, "collidable" } # "Orange.048" + { 920, -2645, 0, 3, "collidable" } # "Orange.049" + { 986, -2627, 0, 3, "collidable" } # "Orange.050" + { 1060, -2619, 0, 3, "collidable" } # "Orange.051" + { 1130, -2601, 0, 3, "collidable" } # "Orange.052" + { -8875, -4233, 0, 4, "collidable" } # "Sweet" + { -9173, -3799, 0, 4, "collidable" } # "Sweet.001" + { -7503, -3681, 0, 4, "collidable" } # "Sweet.002" + { -5776, -3113, 0, 4, "collidable" } # "Sweet.003" + { -4285, -3257, 0, 4, "collidable" } # "Sweet.004" + { 758, -2330, 0, 4, "collidable" } # "Sweet.005" + { 3154, -1946, 0, 4, "collidable" } # "Sweet.006" + { 4579, -1810, 0, 4, "collidable" } # "Sweet.007" + { 6162, -1765, 0, 4, "collidable" } # "Sweet.008" + { 7812, -1448, 0, 4, "collidable" } # "Sweet.009" + { -6975, -2850, 0, 4, "collidable" } # "Sweet.010" + { -5302, -2918, 0, 4, "collidable" } # "Sweet.011" + { -1748, -1546, 0, 4, "collidable" } # "Sweet.012" + { 1730, -1674, 0, 4, "collidable" } # "Sweet.013" + { 3539, -1358, 0, 4, "collidable" } # "Sweet.014" + { 5144, -1177, 0, 4, "collidable" } # "Sweet.015" + { 6795, -1154, 0, 4, "collidable" } # "Sweet.016" + { 9372, -182, 0, 4, "collidable" } # "Sweet.017" +} + +# Level +{ + -9865, -3957, 221 +} diff --git a/allegro/demos/skater/data/menu/back.png b/allegro/demos/skater/data/menu/back.png new file mode 100644 index 00000000..e4afd374 Binary files /dev/null and b/allegro/demos/skater/data/menu/back.png differ diff --git a/allegro/demos/skater/data/menu/button.ogg b/allegro/demos/skater/data/menu/button.ogg new file mode 100644 index 00000000..5f3b4881 Binary files /dev/null and b/allegro/demos/skater/data/menu/button.ogg differ diff --git a/allegro/demos/skater/data/menu/cancunsmall.png b/allegro/demos/skater/data/menu/cancunsmall.png new file mode 100644 index 00000000..023a3c99 Binary files /dev/null and b/allegro/demos/skater/data/menu/cancunsmall.png differ diff --git a/allegro/demos/skater/data/menu/endoflevel.ogg b/allegro/demos/skater/data/menu/endoflevel.ogg new file mode 100644 index 00000000..c44f1f3d Binary files /dev/null and b/allegro/demos/skater/data/menu/endoflevel.ogg differ diff --git a/allegro/demos/skater/data/menu/intro_music.ogg b/allegro/demos/skater/data/menu/intro_music.ogg new file mode 100644 index 00000000..67f5943d Binary files /dev/null and b/allegro/demos/skater/data/menu/intro_music.ogg differ diff --git a/allegro/demos/skater/data/menu/logofont.png b/allegro/demos/skater/data/menu/logofont.png new file mode 100644 index 00000000..13f1d4c0 Binary files /dev/null and b/allegro/demos/skater/data/menu/logofont.png differ diff --git a/allegro/demos/skater/data/menu/menu_music.ogg b/allegro/demos/skater/data/menu/menu_music.ogg new file mode 100644 index 00000000..4e1d3b55 Binary files /dev/null and b/allegro/demos/skater/data/menu/menu_music.ogg differ diff --git a/allegro/demos/skater/data/menu/skate2.ogg b/allegro/demos/skater/data/menu/skate2.ogg new file mode 100644 index 00000000..5ce69115 Binary files /dev/null and b/allegro/demos/skater/data/menu/skate2.ogg differ diff --git a/allegro/demos/skater/data/menu/welcome.ogg b/allegro/demos/skater/data/menu/welcome.ogg new file mode 100644 index 00000000..c843a0eb Binary files /dev/null and b/allegro/demos/skater/data/menu/welcome.ogg differ diff --git a/allegro/demos/skater/data/readme.txt b/allegro/demos/skater/data/readme.txt new file mode 100644 index 00000000..00eaa98f --- /dev/null +++ b/allegro/demos/skater/data/readme.txt @@ -0,0 +1,21 @@ += Introduction + + Allegro is a cross-platform library intended for use in computer games + and other types of multimedia programming. It was initially conceived on + the Atari ST, but that platform sadly died during childbirth. After a + brief stay with Borland C, it was adopted by the fantastic djgpp + compiler, where it grew to maturity. In the fullness of time it gave + birth to children of its own, who went to live in such exotic locations + as DirectX and the X Server, but the entire family is now back together + again, living in harmony as a single portable entity. How about that for + a mixture of metaphors? :-) + + A wide range of extension packages and add-on modules are also available, + which can be found in the "Library Extensions" section of the Allegro.cc + website, http://www.allegro.cc/. + + According to the Oxford Companion to Music, Allegro is the Italian for + "quick, lively, bright". It is also a recursive acronym which stands for + "Allegro Low Level Game Routines". + + diff --git a/allegro/demos/skater/data/thanks.txt b/allegro/demos/skater/data/thanks.txt new file mode 100644 index 00000000..fabac8fd --- /dev/null +++ b/allegro/demos/skater/data/thanks.txt @@ -0,0 +1,1150 @@ +Contributors + + Acho A. Tang (<email>acho@telus.net</a>).<br> + Added a Sidewinder Precision Pro joystick driver to the DOS port. + + Adrian Oboroc (<email>doba@corefx.com</a>).<br> + Wrote the LBM loader. + + aj.<br> + Reported many problems, suggested a lot of improvements to the + documentation, added AMD64/IA64/SSE3 detection code, added DirectX 8 and 9 + detection to the Windows port, added MSVC7 specific options to the makefile, + cleaned up a C99-ism in makedoc, fixed a beep when alt+character was pressed + in windowed mode in Windows and made TARGET_ARCH_EXCL also work with MSVC. + + Alex Demko (<email>alex_demko@mbnet.mb.ca</a>).<br> + Suggested lots of improvements to the datafile system and provided code + for handling the 8x16 BIOS font format. + + Alessandro Monopoli (<email>almonopo@tin.it</a>).<br> + Added the Italian translation of the system messages. + + Andreas Kluge (<email>bitland@aol.com</a>).<br> + Wrote the Ensoniq Soundscape driver and fixed division bugs in the fix + class. + + Andrei Ellman (<email>ae-a-alleg2@wacko.wackonet.net</a>).<br> + Contributed the polygon_z_normal() function, suggested some additions to + the docs, updated the Cygwin section in docs/build/mingw32.txt, got + Allegro for MSVC to build with Cygwin, improved the performance of the + hsv_to_rgb() function, corrected a rounding issue in hsv_to_rgb(), + improved the exrgbhsv example and the Windows screensaver, fixed problems + in the MSVC makefile when using Cygwin and did plenty of other things too. + + Andrew Cottrell (<email>andrewc@dbworld.net.au</a>).<br> + Changed the grabber to use a more robust (locale-independent) date format. + + Andrew Ellem (<email>krand@ican.net</a>).<br> + Wrote the original version of the digital audio streaming code. + + Andrew Geers (<email>andy@geerswj.clara.net</a>).<br> + Added the -ppassword and -nosound options to the grabber, scrolling + support in the image viewer and the flipped rotated sprite routines. + + Andy Goth (<email>unununium@openverse.com</a>).<br> + Made the gfx_card config variable more flexible, added the 256x256 tweaked + VGA mode, wrote the d_text_list_proc() dialog object and fixed the + constructor support in dat2s on Unix. + + Angelo Mottola (<email>a.mottola@libero.it</a>).<br> + Added the BeOS joystick, MIDI and windowed graphics drivers, added mouse + wheel, display switching and close button support for BeOS, wrote the + DGA2 driver and close button support for X, contributed the bfixicon + utility, added triple buffering support, a BWindow-based windowed driver + and a fullscreen overlay driver to the BeOS port and reorganized its gfx + subsystem. And, oh, contributed the QNX and MacOS X ports too. + + Annie Testes (<email>annie@kezako.net</a>).<br> + Added font_height, render_char, char_length hooks to FONT_VTABLE, fixed + several glitches in the unicode support, added a pack_fdopen() function, + caught a misordering in the X system shutdown, fixed some device name + strings, lifted several hardcoded length limitations in the configuration + routines, added a mouse driver based on the event interface (EVDEV) to the + Linux port, fixed numerous bugs and did plenty of other things too. + + Anthony 'Timorg' Cassidy.<br> + Made d_menu_proc fill up its assigned area with the gui_bg_color, updated + required cygwin package list. + + Antoine Mathys (<email>mmathys@bluewin.ch</a>).<br> + Added the Swiss keyboard mapping. + + Anton Ragnarsson (<email>anton.ragnarsson@swipnet.se</a>).<br> + Contributed the Swedish keyboard mapping table. + + Antti Haapala (<email>ztane@lyseo.edu.ouka.fi</a>).<br> + Fixed the setup program to display the right frequency list for each + type of soundcard and contributed the Finnish translation of the system + messages. + + Antti Koskipaa (<email>antti.koskipaa@nic.fi</a>).<br> + Wrote the DOS driver for WSS (Windows Sound System) cards. + + Arne Steinarson (<email>arst@ludd.luth.se</a>).<br> + The fixed point square root routine came from his fix-float library. + + Arthur Huillet (email unknown).<br> + Fixed a typo in the docs. + + Attila Szilagyi (<email>attilabox@hotmail.com</a>).<br> + Fixed SVGAlib horizontal scrolling. + + Ben Chauveau (<email>bendomc@worldnet.fr</a>).<br> + Added support for Tseng ET6000 cards (now available as part of the + FreeBE/AF project). + + Ben Darnell (<email>bdarnell@vnet.net</a>).<br> + Put together the 2.11 release of Allegro while I was away from the net + and wrote the original version of the Allegro FAQ. + + Ben Davis (<email>entheh@users.sf.net</a>).<br> + Added set_volume_per_voice(), made silent voices continue playing, + fixed other minor bugs in the mixer, fixed a bug in create_rgb_table(), + adapted polygon functions to handle two coincident vertices, added the + set_window_close_button() and set_window_close_hook() framework, added + support for timers with parameters under Windows, corrected several + compilation warnings and documented the behaviour of pack_feof(). + + Benjamin Joel Stover (<email>stovertech@intellisys.net</a>).<br> + Wrote the initial version of the fullscreen X-Windows graphics driver. + + Benny Colyn (email unknown).<br> + Added a Dutch translation. + + Bertrand Coconnier (<email>bcoconni@club-internet.fr</a>).<br> + Modified 3D polygones routines for subpixel and subtexel accuracy, made + speed enhancements in these routines, fixed blending in C version of + atex_lit scanline functions, added scanline subdivisions in C scanline + functions and Z-buffer polygon functions and merged in Calin Andrian's + P3D library. + + 8L45T3R (<email>o8l45t3ro@users.sf.net</a>).<br> + Fixed a bug in arc() where small arcs would be drawn as circles. + + Bobby Ferris (<email>baf@bafsoft.com</a>).<br> + Added the SciTE API output format to makedoc and temporarily hosted + Allegro's SVN repository while SourceForge's SVN was in beta. + + Burton Radons (<email>loth@gec.net</a>).<br> + Optimised the truecolor pixel blending function, converted the blenders + to the new single-handler format, and added the range of + Photoshop-compatible blender functions. + + Calin Andrian (<email>calin@ibd.dbio.ro</a>).<br> + Wrote the truecolor, MMX, 3DNow!, masked lit mode, translucent and + Z-buffered polygon rendering routines, the clip3d_f() function and also + the scanline sorting functions for 3D scene rendering, and his P3D + addon library was merged in. + + Calvin French (<email>frenchc@home.com</a>).<br> + Added the -w (always update) switch to dat.exe. + + Carsten Schmidt (email unknown).<br> + Wrote the the initial version of the Linux GGI driver. + + Carsten Sorensen (<email>csorensen@ea.com</a>).<br> + Wrote the the ESS AudioDrive soundcard driver. + + Catatonic Porpoise (<email><graue@oceanbase.org></a>).<br> + Added OpenBSD detection, fixed an issue with executable rights not set + on the memory for the i386 stretcher on UNIX systems, and fixed the + documentation for stretch_sprite. + + Cloud Wu (<email>cloudwu@263.net</a>).<br> + Optimised the truecolor pixel blending functions. + + Charles Bilyue (<email>Esaelon@aol.com</a>).<br> + Optimized the i386 blitters and suggested to not force yielding timeslice + with non-blocking menus. + + Charles Wardlaw (<email>kattkieru@yahoo.com</a>).<br> + Fixed warnings with gcc 4 on MacOS X and helped resolve a problem with + setAppleMenu under Tiger. + + Chris Graham (<email>chris_graham@postmark.net</a>).<br> + Suggested to add a new flag for Windows NTFS compressed files. + + Chris Jones (<email>cj@jibblers.plus.com</a>).<br> + Fixed a bug with 16-bit samples loading, worked around a problem with DOS + file attributes under Win2k, let the MIDI player pass controller events to + the raw player by default, made the MIDI player handle the 'All Sound Off' + controller message, added support for the bitfield compressed BMP image + format, fixed the behavior of numeric keys when NumLock is on, and fixed + loading of certain .wav files. + + Chris La Mantia (<email>celamantia@home.com</a>).<br> + Wrote the d_radio_proc(), d_icon_proc(), and d_slider_proc() dialog + objects, added the D_DISABLED flag, improved the GUI handling of + different font heights, and added the right aligned text functions. + + Chris Roberts.<br> + Updated CMake build for BeOS/Haiku. + + Chris Robinson (<email>crobin_99@yahoo.com</a>).<br> + Wrote the fixed point clip3d() function, improved the performance of the + DIGMID driver, implemented the digmid_set_pan function, rewrote part of + the Allegro mixer, made the Allegro mixer the default one in Windows, + improved the threaded UNIX timer code, helped improve responsiveness under + X11, tweaked tests/play.c, added drawing primitives and video bitmap locking + to the X11 port and did plenty of other things too. + + Christer Sandberg (<email>christer.sandberg@mdh.se</a>).<br> + Made dat2c work better with ISO C90 compilers, made dat2c correctly detect + the native line ending, fixed a problem with the include guard generated + by dat2c, fixed a bug in the 24-bit graphics code of fixup_datafile(), + fixed a memory leak with datedit_exit, fixed a problem with Electric Fence. + + Christian Schueler (<email>cschueler@gmx.de</a>).<br> + Changed the optimisation settings for better performance. + + Daniel Nilsson (<email>daniel7@algonet.se</a>).<br> + Enlarged the starfield in exstars, and fixed an incorrect range in + exlights. + + Daniel Schlyder (<email>daniel@bitblaze.com</a>).<br> + Fixed problems with get_executable_name() under Windows, another one with + set_window_title() under BeOS, potentially unsafe constructs in the + Windows code, the installall makefile target under Windows, added + set_allegro_resource_path(), fixed make uninstall with mingw make, + added ALLEGRO_LIB_BUILD flag for gcc variants not using configure, + fixed a bunch of warnings in MinGW and did plenty of other things too. + + Daniel Verkamp (<email>i_am_drv@users.sourceforge.net</a>).<br> + Added a MIDI input driver to the Windows port and added support for .rmi + MIDI files to the MIDI loader. + + Dark Nation (email unknown).<br> + Restored support for old-style encrypted packfiles, which had been removed + in 4.1.18. + + David A. Capello (<email>dacap@users.sourceforge.net</a>).<br> + Made dotted_rect() avoid bank switches, fixed a problem with lost GUI + mouse clicks, made d_menu_proc() steal/return focus when activated then + deactivated, fixed a problem with submenus, fixed a bug with FLI frames + containing odd-sized chunks, made makedoc write sub-section headings + for .txt output, made override_config_file also be used for writing to + the config file and did plenty of other things too. + + David Kuhling (<email>dkuelhin@hell1og.be.schule.de</a>).<br> + Optimised the fsqrt() routine, and added fhypot(). + + Dave Physics.<br> + Some documentation fixes. + + Dave Thomson (<email>gameskitchen@geocities.com</a>).<br> + Added the RGB <-> HSV conversion routines, the autocrop function to + the grabber and wrote the 3d starfield example program (exstars.exe). + + David Calvin (<email>calvid@rpi.edu</a>).<br> + Wrote the original version of the sound setup utility. + + David Cullen (<email>dcullen7@bellsouth.net</a>).<br> + Added multiple bullets and extra lives to the demo game. + + Deepak T (<email>coolbool@gmx.net</a>).<br> + Fixed clipping in three C sprite drawing routines. + + Dennis Busch (email unknown).<br> + Fixed a bug in d_clear_proc, fixed a Unicode bug in the mode selector, + and fixed the short description of add_clip_rect. + + Dmitriy Kazimirow (<email>mariann@mail.ru</a>).<br> + Provided the Russian keyboard mapping and message translation files. + + Dominique Biesmans (<email>Dominique.Biesmans@ping.be</a>).<br> + Wrote the mode-X version of draw_sprite() and the mode-X <-> linear + blitting functions. + + Doug Eleveld (<email>D.J.Eleveld@anest.azg.nl</a>).<br> + Wrote the d_textbox_proc() dialog object and the new grabber help system. + + Dustin Dettmer (<email>dustin@mize.org</a>).<br> + Spotted a typo in save_bitmap. + + Edgar Reynaldo.<br> + Helped fixing several problems with gfx_mode_select_filter(), pointed out + two warnings, fixed two warnings in a loadpng example, provided + mouse_on_screen(), get_gfx_mode_type() and get_gfx_mode() functions. + + Eduard Bloch (<email>edi@gmx.de</a>).<br> + Fixed a freeze caused by the ESD detection code, fixed a bad behaviour + of the config routines and suggested better ways to find the path to + the executable on Unix. + + Edward Boone (<email>Lucien.Boone@ping.be</a>).<br> + Provided scancode mapping tables for the AZERTY keyboard layout. + + Elias Pschernig (<email>elias@users.sf.net</a>).<br> + Added a COLORCONV_KEEP_TRANS mode, contributed the wfixicon utility, + contributed several enhancements to the grabber, fixed menu dimensions in + the GUI engine, fixed the get_camera_matrix*() functions, added support + for the CHM and Devhelp documentation formats, fixed a bug in midi_seek(), + made load_datafile_object() load the object properties, made the GUI code + scare the mouse more intelligently and did plenty of other things too. + + Eric Botcazou (<email>ebotcazou@libertysurf.fr</a>).<br> + Made the DGA driver work better in 8bpp and 32bpp modes, improved the + DirectX windowed driver and Windows graphics subsystem, partially + revamped the Unicode API and added uszprintf(), added file_select_ex(), + the unified al_find*() interface, an Unicode example, a new filetest, + rewrote the fixdll script, revamped the Borland C++ build process, fixed + lots of bugs and did plenty of other things too. + + Erik Sandberg (<email>eriksandberg@geocities.com</a>).<br> + Optimised the 8 bit draw_sprite() and draw_trans_sprite() functions and + helped with the Swedish message translation. + + Erno Schwetter.<br> + Fixed some bugs in the Linux console port and fixed a long-standing bug in + the polygon() routine. + + Etienne Vouga.<br> + Fixed a bug with the reset_controllers MIDI command. + + Ettore Perazzoli (<email>ettore@comm2000.it</a>).<br> + Optimised the linear -> mode-X blitting function. + + Evert Glebbeek (<email>eglebbk@dds.nl</a>).<br> + Put set_gfx_mode on a diet, added a config entry for specifying the card + to be used for GFX_AUTODETECT_WINDOWED, added a '-fullscreen' switch to + the grabber, cleaned up the grabber/plugins code, added various commands + to the grabber, added the detection of SunOS/Solaris, added configure + options for x86 processor optimisations on Unix systems, added the support + for relative filenames and did plenty of other things too. + + EvilTypeGuy (<email>eviltypeguy@icculus.org</a>).<br> + Cleaned up and fixed the RPM spec file for RedHat 9. + + Fabian Nunez (<email>faybs@iafrica.com</a>).<br> + Added support for the CH Flightstick Pro and Logitech Wingman Extreme + joysticks, 3-button mice, and the extended keys on a Microsoft keyboard. + + Fabrizio Gennari (<email>faybs@iafrica.com</a>).<br> + Contributed the DB9 and TurboGraFXoystick drivers. + + Francis Devereux.<br> + Helped out with build issues on Mac OS X. + + Francisco Pires (<email>fmlvp@hotmail.com</a>).<br> + Added an FPS counter and an option to disable vsync to the excamera + example. + + Francois Charton (<email>deef@pobox.oleane.com</a>).<br> + Wrote the Paradise graphics driver (now available as part of the + FreeBE/AF project), improved the VGA palette setting code and helped + with the TexInfo conversion of the docs. + + Frodo Baggins (<email>l41273@alfa.ist.utl.pt</a>).<br> + Made the Portuguese keyboard mapping. + + Garret Thomson (<email>g@sirsonic.com</a>).<br> + Wrote the music used in the demo game. + + George Foot (<email>gfoot@users.sourceforge.net</a>).<br> + Did a great deal of work on the Linux console version, wrote the AWE32 + driver, added the MIDI pause/seek functions, provided the basis of the + SoundFont reader used in the pat2dat utility, fixed the C fceil() + function, added the ffloor() function and added non-FM support to the + OSS MIDI driver. + + Gorka Olaizola (<email>olsago@jet.es</a>).<br> + Added the Redhat RPM .spec file. + + Grady Martin (<email>shadygrady@budweiser.com</a>).<br> + Fixed a bug in the handling of %n in the printf style text functions, added + a move command to the grabber and standardised some of the grabber dialog + boxes. + + Greg Hackmann (<email>hacker@ididitmyway.com</a>).<br> + Contributed the Borland C++ Builder port. + + Greg Lee (<email>greg@ling.lll.hawaii.edu</a>).<br> + Pointed out that Linux joystick driver should read all events. + + Grzegorz Adam Hankiewicz (<email>gradha@users.sourceforge.net</a>).<br> + Wrote several of the example programs, suggested the "compress" makefile + target, translated the docs and system error messages into Spanish, + suggested the idea of embedding the setup utility into other programs, + wrote some documentation and corrected the .texi generation to improve + texi2dvi output, improved the makedoc utility and contributed a new doc + format, added reload_config_texts() and did plenty of other things too. + + Grzegorz Godlewski (email unknown).<br> + Contributed a Polish localization patch, and added support for lower and + upper altgr tables. + + Grzegorz Ludorowski (<email>pajonk@ajax.umcs.lublin.pl</a>).<br> + Wrote several of the example programs, and made the intro animation and + graphics for the demo game. + + Guilherme Silveira (<email>thedarkage@geocities.com</a>).<br> + Modified the file selector to only list valid drive letters. + + Gunter Ladwig (<email>gladwig@iname.com</a>).<br> + Wrote the OS/2 detection routines and added the three-button mouse + emulation. + + Hans de Goede.<be> + Fixed a problem with dynamically generated stretcher code not being + properly marked as executable on Linux, fixed a busy wait in the X11 vsync + simulation, added a fullscreen driver for X11 which does not need XVidMode + extension, fixed a problem where switching to fullscreen mode under X11, + made digmid work with absolute pathes in patches.cfg, and fixed a problem + with the Alsa driver on big endian systems. + + Harshavardhana Reddy N (<email>nharsha@gmail.com</a>).<br> + Added a Kannada greeting to exunicod. + + Haruhiko Okumura (email unknown).<br> + Wrote the original version of the LZSS compression code. + 12-2-404 Green Heights, 580 Nagasawa, Yokosuka 239, JP. + + Hein Zelle (<email>hein@icce.rug.nl</a>).<br> + Revamped the cross-compilation section of docs/build/mingw32.txt, + clarified a requirement when cross-compiling from Linux, reworked the + paragraph on the location of shared libraries under Unix in the docs and + added a FAQ entry on the same subject. + + Henrik Schmidt (<email>hbs@ks.informatik.uni-kiel.de</a>).<br> + Found a workaround for the switching problem under Windows, made gcc pass + '-h' instead of '-soname' to the linker and replaced '-L' by '-h' in shell + comparisons so as not to break on Solaris. + + Henrik Stokseth (<email>hensto@online.no</a>).<br> + Contributed a native Mingw32 port which can also be built with a + cross-compiler and the Cygwin compiler, much improved OS detection, added + get_gfx_mode_list() and methods for querying the VGA, Mode-X, Xtended, + VESA, VBE/AF and DirectX drivers for a list of possible GFX modes, + rewrote the mode-selector to use get_gfx_mode_list(), reworked the build + system many times and did plenty of other things too. + + Hrvoje Ban (<email>spoofer255@gmail.com</a>).<br> + Pointed out a bug in the mode selector, fixed several double ;'s, fixed + ASSERT() in Windows, helped write a documentation section about common + pitfalls, and added the create_datafile_index function. + + Igor Gnip (<email>gnipi@mindnever.org</a>).<br> + Removed the requirements for fileutils on DOS/Windows platforms and added + the detection of MSYS to the MingW32 port. + + Isaac Cruz (<email>icruzbal@teleline.es</a>).<br> + Fixed a bug with accelerated drawing onto sub bitmaps of DirectDraw + surfaces, added the GFX_DIRECTX_WIN driver, fixed a Windows sub bitmap + locking bug, added Windows desktop_color_depth and yield_timeslice + routines, and made extensive modifications to other aspects of the + Windows code. + + Ivan Baldo (<email>lubaldo@adinet.com.uy</a>).<br> + Wrote the 15/16 bit dithering code and optimised the sprite rotation + routines. + + Jaime Moreno (<email>daviangel@hotmail.com</a>).<br> + Helped track down a problem with dependency generation in MacOS X. + + Jakub Wasilewski (<email>krajzega@meditech.pl</a>).<br> + Fixed a bug when loading greyscale TGA images and contributed to the skater + demo. + + James Arthur (<email>jaa@arfa.clara.net</a>).<br> + Documented the Photoshop-style truecolor blender routines. + + James Hyman (<email>frooge@mindless.com</a>).<br> + Added support for quoted strings in the get_config_argv() function and + the dithering code for paletted images. + + James Lohr (email unknown).<br> + Fixed a problem with mouse acceleration in fullscreen modes under Windows. + + James Ponder (<email>james@squish.net</a>).<br> + Suggested to remove the DJGPP makefile from the Unix tar archive and + clarified a requirement when cross-compiling from Linux. + + Jan Bruun Andersen (<email>jba-dk@users.sourceforge.net</a>).<br> + Fixed a compilation problem with Cygwin. + + Jan Hubicka (<email>hubicka@horac.ta.jcu.cz</a>).<br> + Vastly improved the speed of the create_rgb_table() function. + + Jason Wilkins (<email>fenix@io.com</a>).<br> + Wrote the quaternion math routines and contributed the BeOS port. + + Javier Gonzalez (<email>xaviergonz@hotmail.com</a>).<br> + Corrected mouse movement speed, made allegro_message() use title from + set_window_title(), added close button hook support and improved + switching in Windows, fixed bad clearing of subbitmaps, made bug + reports and suggestions for improvement, contributed bidirectional + looping support, backward playing support and bugfixes for the + DirectSound driver and did plenty of other things too. + + Jeff Mitchell (email unknown).<br> + Fixed the location of grabber.txt in the spec file. + + Jeremiah Blanchard (<email>squirminworm@yahoo.com</a>).<br> + Contributed modifications in order for Allegro to build on Darwin/MacOS X + and updated the build instructions for this new port afterwards. + + Jim Flynn (<email>jflynn@pacbell.net</a>).<br> + Removed floating point calculations from the AWE32 MIDI driver. + + Jim Grainger (<email>Grainger_Jim/world_europe_samuro_WYN-CTV@samsung.co.kr</a>).<br> + Spotted a broken link in the docs and updated it. + + Jiri Gabriel (email unknown).<br> + fixed loading of multiple ranges in a single bitmap with txt fonts and helped + fix an off-by-one mistake for the last glyph in extract_font_range. + + Joaquin Hierro Diaz (<email>Joaquin.Hierro.Diaz@fresno.csic.es</a>).<br> + Made the mapping table for Spanish keyboards. + + Joerg Rueppel (<email>sharky-x@gmx.net</a>).<br> + Added more flexible wildcard matching for object names in dat.exe and + the find_datafile_object() function. + + Johan Peitz (<email>d98peitz@dtek.chalmers.se</a>).<br> + Fixed and enhanced the Win32 joystick driver, and contributed the 'Alex + the Allegator' icon. + + Johan Venter (<email>leonjventer@bigpond.com</a>).<br> + Fixed some problems with the RSXNT and Mingw32 makefiles. + + John Holden (<email>johnh@psych.usyd.edu.au</a>).<br> + Fixed a bug in load_wav(). + + John Utz (<email>Johnut01@noa.nintendo.com</a>).<br> + Corrected a wrong assumption about the VRAM layout in the Linux + framebuffer console driver. + + Jon Rafkind (<email>workmin@ccs.neu.edu</a>).<br> + Added more ASSERTs to the code, implemented the Cohen-Sutherland clipping + algorithm for the line() function and supplied an m4 macro for allegro. + Also fixed a problem with allegro-config. Implemented draw_sprite_ex() + function. + + Jonas Petersen (<email>joXonoX@berlin.snafu.de</a>).<br> + Added the save_bmp() function and support for the OS/2 BMP format. + + Jonathan Tarbox (<email>jonattar@rocketmail.com</a>).<br> + Wrote the mode-X setup code, the FLI/FLC player and contributed parts of + the joystick handler. + + Jorrit Rouwe (<email>j.rouwe@cpedu.rug.nl</a>).<br> + Provided a new and much cooler set of FM instrument definitions for the + Adlib MIDI driver. + + Jose Antonio Luque (<email>skylord@LatinMail.com</a>).<br> + Improved the Windows joystick driver, and optimised the 16-bit blit() and + masked_blit() functions. + + Joshua Heyer (<email>joshua_heyer@yahoo.com</a>).<br> + Wrote the original version of the OSS sound driver. + + J. P. Morris (email unknown).<br> + Fixed a bug rest_callback under unix. + + Julien Cugnire (<email>jcugniere@free.fr</a>).<br> + Improved the support for non-blocking menus, fixed a bug related to the + retrieval of the inital volume when no primary buffer was present under + Windows, fixed the crash on exit with the aRts sound driver, added an + X11 message box for allegro_message under X11 and fixed a crash in the GUI + when a dialog was opened while a menu was still open. + + Kalle Toivonen (<email>allegro@korpiq.iki.fi</a>).<br> + Fixed a bug in _parallelogram_map(). + + Keith Gerdes (<email>kwg@softhome.net</a>).<br> + Fixed the DirectDraw overlay mode driver. + + Kerry High (<email>khigh01@umr.edu</a>).<br> + Contributed the SNES joypad driver. + + Kester Maddock (<email>dmaddock@xtra.co.nz</a>).<br> + Wrote the Wingman Warrior joystick driver. + + Knut Pape (<email>Knut_Pape@t-online.de</a>).<br> + Improved the Mingw32 readme file. + + Kronoman X (<email>kronoman_x@hotmail.com</a>).<br> + Added a FAQ entry about the conflict between Allegro headers and the C++ + 'using' directive. + + Krzysztof Krzyzaniak (<email>eloy@arrakis.cs.put.poznan.pl</a>).<br> + Wrote the load_voc() function. + + Laurence Withers (<email>lwithers@users.sf.net</a>).<br> + Added destroy hook to font structure, worked on const-correctness + throughout the library, implemented the new FONT structure, made + some modules avoid linking dependencies, contributed the dat2c + utility, added two fixed point ratios for converting to and from + radians, added a '-windowed' switch to the grabber, added a new text + API and did plenty of other things too. + + Lee Killough (email unknown).<br> + Added the low-level hook routine to the keyboard handler and fixed a + couple of bugs. + + Lennart Rolland (<email>chimeni@hotmail.com</a>).<br> + Contributed the Norwegian message translation. + + Lennart Steinke (<email>lst@steinke.net</a>).<br> + Added the exconfig example, contributed keyboard layout detection code + for Windows and suggested the true colour font rendering. + + Lisa Parratt (<email>lisa@thecommune.org.uk</a>).<br> + Contributed the SGI Audio Library sound driver, spotted a BSDism that + IRIX doesn't like at all, added IRIX detection and improved the + performances of the SGI audio driver + + Lorenzo Petrone (<email>looris@gmail.com</a>).<br> + Contributed the gfxinfo utility, added two FAQ entries, added a + xwin_set_window_name() function to the X11 port, added support for + switch callbacks under X11 and refactored the display switching code. + + Lucas Vignoli Reis (<email>lucasvr@bestway.com.br</a>).<br> + Added the Portuguese (Brazil) message translation and keyboard mapping. + + Magnus Henoch (<email>mange@freemail.hu</a>).<br> + Made the gfx mode selector keep the current selection as much as possible + and fixed a problem when compiling without 8bpp support. + + Maiolino Carmelo (<email>cmaiolino@ctonline.it</a>).<br> + Added the Italian keyboard mapping table. + + Manni Heumann (<email>manfred.heumann@uni-bielefeld.de</a>).<br> + Fixed some problems with the German keyboard mapping table. + + Marcel de Kogel (<email>m.dekogel@student.utwente.nl</a>).<br> + Not content with fixing my broken MPU-401 driver, Marcel went on to + provide a set of vastly improved drum sounds for the OPL driver, to help + me sort out some problems with reentrant interrupts, to supply the half + of the joystick code that didn't come from Jonathan and to locate a + stupid mistake in my VESA linear framebuffer code. + + Marcel Smit (<email>marcel.athlon@hccnet.nl</a>).<br> + Corrected a bug that caused errors when drawing persp. correct polygons + facing the screen, corrected an error in the packfile format write-up and + made the show_video_bitmap() method of the Windows windowed driver wait + for a vsync. + + Mrcio Fialho (<email>maaf1980@yahoo.com.br</a>).<br> + Fixed several issues with the DJGPP port and the VBE/AF driver and fixed + some bugs related to author credits. + + Marco Campinoti (<email>marco@etruscan.li.it</a>).<br> + Added 15 and 24 bit support to the native Tseng ET4000 driver (now + available as part of the FreeBE/AF project). + + Marco Marmulla (<email>Viper005@usa.net</a>).<br> + Added 16 bit support to the load_voc() routine. + + Marian Dvorsky (<email>marian@step.sk</a>).<br> + Wrote the Windows GDI interface routines. + + Marius Fodor (<email>iceman@teleport.com</a>).<br> + Added support for the Sidewinder and Gravis GamePad Pro. + + Marek Habersack (<email>grendel@ananke.amu.edu.pl</a>).<br> + Did the original Linux console port (brave man: this was the first ever + work done on porting Allegro away from DOS), which is the basis of the + code we are still using today and added support for the more recent + Trident chipsets (now available as part of the FreeBE/AF project). + + Mark Keller.<br> + Reported two minor mistakes in the manual. + + Mark Wodrich (<email>mwodric@eleceng.uct.ac.za</a>).<br> + The brain behind sub-bitmaps, flicker-free mouse pointers, and the + ability to import GRX .FNT files into the grabber. + + Markus F.X.J. Oberhumer (<email>markus.oberhumer@jk.uni-linz.ac.at</a>).<br> + Fixed the Video-7 scrolling function (now available as part of the + FreeBE/AF project), optimised the color mapping routines, and made many + useful suggestions like the addition of a vid_phys_base field to the + graphics driver structure. + + Martijn Van Lersel (<email>amarillion@yahoo.com</a>).<br> + Fixed an overflow in create_light_table(). + + Martijn Versteegh (<email>m.versteegh@hccnet.nl</a>).<br> + Added the config hook extension mechanism. + + Mathieu Lafon (<email>mlafon@ifhamy.insa-lyon.fr</a>).<br> + Added the French keyboard mapping, support for the Pause/PrtScr keys and + changed the key[] table to a normal/extended bitfield. + + Matt Witherspoon (<email>spoon@vt.edu</a>).<br> + Fixed a bug in the scroll() method of the Linux SVGAlib driver. + + Matthew Bowie (<email>catcat@nmt.edu</a>).<br> + Added support for 4-button joysticks. + + Matthew Leverton (<email>matthew@allegro.cc</a>).<br> + Fixed a bug with mouse mickeys in windowed mode under Windows, fixed a + problem with al_find*() and NTFS partitions under Windows, added missing + header files to be installed by the Windows binary distribution, made the + DOS/Windows makefiles use 'copy /B' instead of 'copy', added the detection + of left-hand mouse configuration under Windows, fixed a bug with + pack_fgets(), made an online diff generator and did lots of other things too. + + Matthew Smith.<br> + Fix a bug in C locking code in GDI. + + Maxime Carey (<email>werfu@users.sourceforge.net</a>).<br> + Contributed the Canada (French) keyboard mapping file. + + Michael Bevin (<email>michael.bevin@stonebow.otago.ac.nz</a>).<br> + Optimised the create_trans_table() function. + + Michael Bukin (<email>M.A.Bukin@inp.nsk.su</a>).<br> + Ported the whole thing to Unix/X, and contributed a _lot_ of patches to + improve the portability, robustness, and performance of pretty much the + entire library. + + Michael Faerber.<br> + Pointed out a mistake in the documentation for text_height(). + + Michael Jensen.<br> + Fixed a mistake in the documentation for is_compatible_font. + + Michael Rickmann (<email>mrickma@gwdg.de</a>).<br> + Ported the Windows code to Mingw32. + + Michael Tanczos (<email>webmaster@logic-gate.com</a>).<br> + Fixed some bugs in the FLIC player. + + Michal Mertl (<email>mime@eunet.cz</a>).<br> + Wrote all the 24 bit graphics code, the optimised palette generation + function and a fair amount of the other truecolor stuff too (bitmap + scaling, image loading, etc). + + Michal Molhanec (<email>molhanec@seznam.cz</a>).<br> + Simplified the build instructions for Dev-C++, replaced all occurences + of MingW32 by MinGW in the docs, added an faq section about the giftware + license, fixed problems with long filenames when building for MSVC, + corrected a problem with the Watcom port, added MSVC7 options to the + makefile, fixed a linker problem with the MSVC port, fixed some const + warnings in the grabber code and did plenty of other things too. + + Michail Pishchagin (<email>mblsha@users.sourceforge.net</a>).<br> + Contributed the ustrnicmp() function. + + Milan Mimica (<email>milan.mimica1@pu.htnet.hr</a>).<br> + Fixed bugs in the keyconf utility, the alsa 9 volume settings and + extract_font_range(), helped fix an off-by-one mistake for the last glyph + in extract_font_range, fixed a bug where a font would be converted to 8 + bit, a bug with is_color_font, made the Linux console driver more robust, + fixed some spin loops in the test program, and added the get_volume and + get_hardware_volume functions, and did plenty of other things too. + + Miran Amon (<email>miran.amon@gmail.com</a>).<br> + Fixed an undocumented arbitrary limit in get_config_argv() and contributed + to the skater demo. + + Nathan Albury, aka Rubicant (<email>gt4558a@prism.gatech.edu</a>).<br> + Improved the fire routine in examples/exflame.c (my original version + didn't really look very much like flames :-) and gave me some extremely + useful ideas about how to implement translucency. + + Nathan Smith (<email>white_door@dread.nl</a>).<br> + Implemented the recursive handling of directories for the dat utility. + + Neil Townsend (<email>neil@robots.ox.ac.uk</a>).<br> + Improved the accuracy of the timer routines and added the callback + parameters. + + Neil Roy (<email>neilroy@cogeco.ca</a>).<br> + Suggested many improvements to the documentation. + + Neil Walker.<br> + Implemented a hardware accelerated stretch_blit() for the Windows DX port, + and fixed a bug with draw_sprite and sub-bitmaps. + + Nicholas Davies (<email>master_goodbytes@hotmail.com</a>).<br> + Made the fix class not trigger warnings with gcc -Weffc++ and contributed + to the skater demo. + + Nick Kochakian (<email>nickk@worldnet.att.net</a>).<br> + Wrote the DirectSound input driver. + + Ole Laursen (<email>98zOLaw@aalborghus.dk</a>).<br> + Contributed the Danish keyboard mapping table and system message + translation, and made the Unicode utolower() and utoupper() functions + understand the entire 16 bit character set. + + Olivier Blin (<email>oblin@mandriva.com</a>).<br> + Fixed compilation problems for the ModeX driver. + + Olly Betts (<email>olly@muscat.co.uk</a>).<br> + Modified the djgpp makefile to support cross-compiling on a Linux machine. + + Omar Cornut (<email>cornut@noos.fr</a>).<br> + Spotted an asm locking bug under Windows, bumped the maximum number of + buttons per joystick to 32, fixed the Windows joystick driver to handle a + weird peculiarity of the DirectInput API and improved the handling of + KEY_COLON2 on Japanese keyboards. + + Oscar Giner (<email>O_giner@hotmail.com</a>).<br> + Added the Catalan translation, corrected the Spanish translation, fixed a + bug with binary data exporting in the grabber and fixed a conflict between + the magic main and the MFC. + + Owen Embury (<email>owen@gememail.demon.co.uk</a>).<br> + Wrote part of the translucency/lighting code. + + Owen Rudge (<email>alleg@orudge.freeuk.com</a>).<br> + Contributed a DLL version resource script and the mkdata.bat script. + + Ove Kaaven (<email>ovek@arcticnet.no</a>).<br> + Fixed a bug in the ATI mach64 driver (now available as part of the + FreeBE/AF project), added native truecolor and linear framebuffer support + to the ATI driver, contributed the Norwegian keyboard mapping, and added + MIDI and sample input features to the MPU and SB drivers respectively. + + Paavo Ahola (email unknown).<br> + Helped fix a problem with BCC and the C implementations of fixmul. + + Patrick Hogan (<email>patter@iname.com</a>).<br> + Wrote the draw_gouraud_sprite() function, and made Windows audiostreams + work properly. + + Paul Bartrum (<email>bartrum@xtra.co.nz</a>).<br> + Contributed the ellipse drawing functions. + + Paul Eipper.<br> + Reported a bug where libdir from autotools was not used for the modules path. + + Paul Furber (<email>paul@sprintlink.co.za</a>).<br> + Provided the floating point apply_matrix_f() function. + + Paul Hampson (<email>Paul.Hampson@Pobox.Com</a>).<br> + Improved and fixed some problems in the SNES gamepad driver. + + Paul Pinault (<email>diskaleg@infonie.fr</a>).<br> + Translated the system error messages into French. + + Pavlos Touboulidis (<email>gtoub@otenet.gr</a>).<br> + Made file_select() able to include or exclude files based on their + attributes. + + Pedro Cardoso (<email>pcardoso@viriato.ipv.pt</a>).<br> + Contributed the tweaked 80x80 VGA mode. + + Peter Cech (<email>7cech@nw.fmph.uniba.sk</a>).<br> + Added grabber support for the 8x8 BIOS font format, support for + hot-swapping between a custom keyboard layout and the standard US + mapping, optimised the alpha sprite blending routines and added non-ASCII + space recognition to uisspace(). + + Peter De Wachter.<br> + Made the ALSA driver work for hardware which does not support unsigned + samples. + + Peter Hull (<email>peterhull90@users.sourceforge.net</a>).<br> + Made the file selector work with directories that have more than 2048 + files, solved some compiling issues on MacOS X, fixed a bug in rest() + that caused it to wait too long on that platform, fixed several problems + with the hardware mouse cursor, fixed a deadlock in the software mouse + updating code, fixed compilation problems under MacOS X tiger, added a + MacOS X helpfile and did plenty of other things too. + + Peter Johansson (email unknown).<br> + Reported a problem with system cursors not working in Windows. + + Peter Monks (<email>pmonks@iname.com</a>).<br> + Wrote the Video-7 graphics driver (now available as part of the FreeBE/AF + project) and showed me how to set up the unchained 640x400 mode. + + Peter Palotas (<email>blizzar@hem1.passagen.se</a>).<br> + Added the keyboard callback routine. + + Peter Pavlovic (<email>Peter.Pavlovic@st.fmph.uniba.sk</a>).<br> + Added the Slovak keyboard mapping and message translation, stopped the + DOS file selector from listing virtual drives, did the same for the + Windows file selector, improved the support for accented character maps in + the keyboard driver and made aesthetic modifications to the GUI menu + system. + + Peter Puck (<email>zaqhaq@netscape.net</a>).<br> + Helped with the Mingw32 native build. + + Peter Wang (<email>tjaden@users.sourceforge.net</a>).<br> + Added the mouse_z wheel input support to the Linux code, fixed problems + with the ESD sound driver, wrote the ALSA sound driver, wrote the BeOS + sound driver, added OSS MIDI and sample input support, added banked mode + support to the SVGAlib driver, wrote the X DGA mode switching code, + improved the Linux joystick driver, X11 fullscreen, DGA2 and DGA driver, + added pthread timers under Linux/Unix and did loads of other things too. + + Phil Frisbie, Jr. (<email>pfrisbie@geocities.com</a>).<br> + Wrote the CPU type detection code. + + Phil Krylov.<br> + Fixed a bug in load_bios_font(). + + Phil Shenk (email unknown).<br> + Improved the MSVC build instructions. + + Philipp Thomas (<email>pthomas@suse.de</a>).<br> + Fixed all comparisons between signed and unsigned types, fixed compilation + on x86-64, fixed all function prototypes, converted the configure + machinery to autoconf 2.53 or later and added multi-arch support, DESTDIR + support and the German translation to the RPM spec file. + + Przemek Podsiadly (<email>ppodsiad@elka.pw.edu.pl</a>).<br> + Added hicolor versions of the 3d polygon code. + + Revin Guillen (<email>revin@phylo.com</a>).<br> + Added the position_dialog() function. + + Richard Davies (<email>richard@debaser.force9.co.uk</a>).<br> + Added support for PSX and N64 joypads. + + Richard Mitton (<email>100740.1271@compuserve.com</a>).<br> + Added support for 6-button joysticks, and wrote the 12-bit color example + program (ex12bit.c). + + Richard Reeve (<email>r.e.reeve@stir.ac.uk</a>).<br> + Fixed a silly mistake with gcc 3.0.x detection. + + Rikard Peterson.<br> + Fixed a small problem with the Mac OS X joystick driver. + + Robert J. Ragno (<email>rjr@mit.edu</a>).<br> + Wrote the Gravis GrIP driver, made some improvements to the Wingman, PSX + and throttle input code. + + Robert J. Ohannessian (<email>voidstar@ifrance.com</a>).<br> + Added MMX optimisation for the 8 and 16-bit clear() functions, fixed bad + clearing of subbitmaps, added SSE detection and optimised some masked + blits with SSE instructions, added some routines to the unified color + convertor and made some of them more robust, fixed the docs for + pivot_scaled_sprite_v_flip(), revamped the retrieval mechanism of CPU + capabilities, separated the CSS file and did plenty of other things too. + + Robert Riebisch.<br> + Fixed some warnings from gcc 4.x on VESA and VBE/AF drivers. + + Roberto Alfonso (<email>rpgrca@labint.frba.utn.edu.ar</a>).<br> + Fixed a couple of memory problems in the dat2c utility, added an + srand() call in the demo game, made the MSVC port call `link /lib' + rather than `lib', fixed several warnings with GCC 4 under DJGPP and + fixed a grabber crash when importing a font range in an existing font. + + Robin Burrows (<email>rburrows@bigfoot.com</a>).<br> + Provided a new page flipping code for the DirectDraw subsytem, added a + Windows sound driver using the Allegro mixer and another using waveOut, + fixed two glitches in the DirectDraw code. + + Romano Signorelli (<email>romanos@bigfoot.com</a>).<br> + Added an arc plotting routine. + + Ron Novy<br> + Made several improvements to the test program. + + Ronaldo Hideki Yamada (<email>r.yamada@uol.com.br</a>).<br> + Contributed the MacOS 9 port of Allegro. + + Ryan Patterson.<br> + Made various documentation fixes and fixed a crash in free_config_entries. + + S.Sakamaki (<email>emt@geocities.co.jp</a>).<br> + Added the VESA 3.0 refresh rate control code. + + S.Suzuki (<email>s-suz@sunfield.ne.jp</a>).<br> + Wrote the IF-SEGA /PCI, /PCI2, and /ISA joystick interface drivers. + + Salvador Eduardo Tropea (<email>salvador@inti.edu.ar</a>).<br> + Improved the keyboard routines (better handling of extended scancodes, + keyboard LED support, capslock and numlock, and alt+numpad input), + contributed the 320x100 VGA graphics mode, added support for proper 16 + bit sample mixing, fixed compilation on gcc 3.x and made numerous other + useful suggestions, contributions and bugfixes. + + Sam Hocevar (<email>sam@zoy.org</a>).<br> + Fixed a Bashism in fix.sh that makes Solaris' sh choke, a race + condition in the mixer under Unix w/ threads, Windows, BeOS and MacOS X, + a crash in makedoc, made it possible to put functions from .s sources + in a shared library under Unix and removed deprecated use of several + functions. + + Santeri Saarimaa (<email>gridle@mbnet.fi</a>).<br> + Made the Finnish keyboard mapping. + + Sask Allegro (<email>sask_allegro@iespana.es</a>).<br> + Added support for more than two joysticks in the Windows port. + + Scott Harrison (<email>scotth@calderauk.com</a>).<br> + Added the OpenDOS detection code. + + Sean Gugler (<email>sean@epal.com</a>).<br> + Added the set_leds() function. + + Seunghwan Ji (email unknown).<br> + Made makedoc output correct html and rtf files for Korean. + + Serge Semashko (<email>serge@lxnt.info</a>).<br> + Fixed a bug with the letter P in the Russian keyboard configuration + file, added Enter as a fire key to the demo game, fixed some + problems with Allegro working on Nokia 770, and fixed a crash in + _linear_draw_trans_rgba_rle_sprite24. + + Seymour Shlien (<email>seymour@dgbt.doc.ca</a>).<br> + Contributed the Windows BMP file reader, bezier spline drawer, and + justified text plotting function. + + Shawn Hargreaves (<email>shawn@talula.demon.co.uk</a>).<br> + Progenitor. Wrote everything that wasn't written by somebody else. + + Shawn Walker (<email>binarycrusader@gmail.com</a>).<br> + Several fixes to the .spec file, made get_executable_name use getexecname() + under Solaris, fixed a bug in the keyboard driver that caused crashes on + the same system, worked around errors with some versions of GNU AS and fixed + errors in the configure script when not using GCC + + StApostol (<email>stapostol@gmail.com</a>).<br> + Fixed a bug in the exflame example and updated the FAQ to use rest(0) instead + of yield_timeslice(). + + Stefan Eilert (<email>seilert@rz.Uni-Osnabrueck.DE</a>).<br> + Added support for a second joystick. + + Stefan Schimanski (<email>1Stein@gmx.de</a>).<br> + Wrote the original Windows version pretty much single-handedly. + + Stefan T. Boettner (<email>virtual.man@t-online.de</a>).<br> + Wrote the Linux SVGAlib driver. + + Stepan Roh (<email>src@srnet.cz</a>).<br> + Added a Czech keyboard mapping and system message translation, the Latin + Extended-A characters in the default font, the codepage support in the + textconv utility, fixed some problems with the ESD sound driver, helped + make Allegro build better on some Unix platforms, fixed const related + problems in C versions of routines and added support for a automake-style + DESTDIR variable in the Unix makefile. + + Stephan Brauss (<email>sbrauss@optronic.ch</a>).<br> + Made a few fixes to let the Linux port compile again on Linux 2.2.x, + corrected a few nits in the Swiss keyboard configuration file and added + new keysyms to the X11-to-BIOS conversion table in order to catch missing + keycodes for the keypad when NumLock is on. + + Stephen Kittelson (<email>stickman2000@juno.com</a>).<br> + Made bugfixes and tweaks to the keyboard system. + + Stijn Wolters.<br> + Clarified the documentation of init_dialog. + + Sveinung Kvilhaugsvik(email unknown).<br> + Pointed out that Allegro should respect DESTDIR under MacOS X. + + Sven Sandberg (<email>svens@it.uu.se</a>).<br> + Fixed a problem with save_bitmap() rounding the image widths, optimised + the create_light_table() function, optimised the fixed point trigonometric + routines, provided the Swedish message translations, improved the file + selector sorting algorithm, optimised the spline routines, added + ustrrchr(), improved the usprintf() handling of floats, changed the + Z-buffer API, and did plenty of other things too. + + TBD/FeR (<email>tbd@usa.net</a>).<br> + Added the 320x600 and 360x600 resolutions to the mode-X driver. + + Teijo Hakala (<email>teijo.hakala@imnetti.fi</a>).<br> + Added wheel support to the Windows mouse driver. + + Tero Parvinen (<email>Tero.Parvinen@hut.fi</a>).<br> + Designed most of the new sound API. + + Theuzifan Sumachingun (<email>uzi@simauria.upv.es</a>).<br> + Improved the cpu detection for Cyrix chips and made the file selector + only list valid drive letters. + + Thomas Fjellstrom (<email>tfjellstrom@home.com</a>).<br> + Wrote the ALSA 0.5.x MIDI driver and added support for ALSA 0.9.x. + + Thomas Harte (email unknown).<br> + Helped fix a bug in show_video_bitmap() on MacOS X, helped optimise + fixmul(), helped find many bugs in the MacOS X port, like better support + for user-supplied Nibs, implemented a hardware accelerated stretch_blit + under DirectX, fixed a bug with draw_sprite and sub-bitmaps and contributed + to the skater demo. + + Thomas Klausner (<email>wiz@danbala.ifoer.tuwien.ac.at</a>).<br> + Added NetBSD detection and fixed a problem with the allegro.m4 macro and + automake 1.8+. + + Thomas Wolf (<email>two@chello.at</a>).<br> + Corrected some errors in the German keyboard mapping and added the + German translation of the system messages. + + Tim Bird (<email>tbird@caldera.com</a>).<br> + Worked on the Linux console port. + + Tim Gunn (<email>timgunn@eastwind.com.au</a>).<br> + Wrote the TGA reading/writing routines. + + Timothy Terriberry (<email>sundance@sprintmail.com</a>).<br> + Fixed several bugs in the RGB <-> HSV conversion routines. + + Tobi Vollebregt (email unknown).<br> + Spotted a bug in ustrerror(), which was not returning a pointer to + a static buffer, reported a problem with shutdown_dialog() when a + menu was open, helped port the Windows keyboard driver to Windows 98 + and fixed a bug with hardware cursor detection in X11. + + Tobias Dammers.<br> + Fixed a problem with the DirectSound input driver. + + Tom Breton (<email>tob@world.std.com</a>).<br> + Added the functionality selection #ifndefs to allegro.h. + + Tom Novelli (<email>tnovelli@cyber3.servtech.com</a>).<br> + Wrote the original version of the digital MIDI driver. + + Tom St Denis (<email>tomstdenis@yahoo.com</a>).<br> + Fixed clipping of transparent objects. + + Tomohiko Sugiura (<email>tmsugi@d4.dion.ne.jp</a>).<br> + Added the KEY_ABNT_C1, KEY_YEN, KEY_KANA, KEY_CONVERT, KEY_NOCONVERT + and other keys to the input handler, organised getting the IF-SEGA + joystick drivers by S.Suzuki merged into my codebase and added a more + aggressive Sidewinder joystick driver. + + Tore Halse (<email>gnolam@gmail.com</a>).<br> + Made Allegro windows always popup centred in Windows and made fixes to the + documentation. + + torhu.<br> + Fixed an out-of-bounds error in akaitest. + + Trent Gamblin.<br> + Implemented set_mouse_speed under X11, fixed the C version of stretch_blit + and made the fullscreen DirectX driver save and restore the palette on + switching away. + + V Karthik Kumar (<email>karthikkumar@gmail.com</a>).<br> + Added a Tamil language greeting to exunicode, added switches to use + the Intel compiler in Windows and added a password option to the Windows + screensaver example. Also fixed a problem with allegro-config. + + Victor Williams Stafusa da Silva (<email>vwss1984@yahoo.com.br</a>).<br> + Changed a few occurences of "256" to PAL_SIZE and made OS type detection + handle Windows 2003 and Windows Vista. + + Ville Skytt (<email>scop@users.sourceforge.net</a>).<br> + Fixed a problem with make install libdir= and modules on Unix systems. + + Vincent Penquerc'h (<email>lyrian@kezako.net</a>).<br> + Added the D_DIRTY flag and mouse button press/release events to the GUI + system, optimised the 256 to truecolor blitting code to avoid repeated + conversions of the palette table, added scare_mouse_area(), added the + yield_timeslice() function, added the update selection function to the + grabber, added the XCRP and YCRP properties to datafiles in general, + implemented the big header split and did plenty of other things too. + + Vitaliy Chetverikov (email unknown).<br> + Fixed a bug in the GUI where the return value of MSG_IDLE was ignored. + + VolkerOth (<email>VolkerOth@aol.com</a>).<br> + Integrated the concepts of scrolling and edit_proc objects. + +Thanks! diff --git a/allegro/demos/skater/src/anim.c b/allegro/demos/skater/src/anim.c new file mode 100644 index 00000000..2ff483ea --- /dev/null +++ b/allegro/demos/skater/src/anim.c @@ -0,0 +1,132 @@ +#include <allegro5/allegro.h> +#include <math.h> +#include "anim.h" +#include "game.h" +#include "level.h" + + +double LastSpeedStore = 0, LastSpeed; +int OnLand; + +ALLEGRO_BITMAP *GetCurrentBitmap(struct Animation *Anim) +{ + LastSpeedStore = LastSpeed; + if (Anim->SkateVoice) { + if (LastSpeed >= 1.0f && OnLand) + al_set_sample_instance_gain(Anim->SkateVoice, 1.0 - (1.0 / LastSpeed)); + else + al_set_sample_instance_gain(Anim->SkateVoice, 0); + } + return Anim->CBitmap; +} + +void AdvanceAnimation(struct Animation *Anim, double Distance, int OnPlatform) +{ + Anim->TimeCount += Distance; + OnLand = OnPlatform; + + if (!OnPlatform) { + Anim->CBitmap = Anim->Fast; + } else { + /* obtain speed */ + LastSpeed = Distance = fabs(Distance); + + Anim->CBitmap = Anim->Fast; + if ((Distance < 12.0f) && (LastSpeedStore < 12.0f)) + Anim->CBitmap = Anim->Medium; + if ((Distance < 5.0f) && (LastSpeedStore < 5.0f)) + Anim->CBitmap = + (KeyFlags & (KEYFLAG_LEFT | KEYFLAG_RIGHT)) ? Anim-> + Animation[((unsigned int)Anim->TimeCount) % 3] : Anim->Slow; + } +} + +struct Animation *SeedPlayerAnimation(void) +{ + struct Animation *Anim = + (struct Animation *)malloc(sizeof(struct Animation)); + ALLEGRO_SAMPLE *Sound; + + Anim->Animation[0] = ObtainBitmap("skater2"); + Anim->Animation[1] = ObtainBitmap("skater3"); + Anim->Animation[2] = ObtainBitmap("skater4"); + + Anim->CBitmap = Anim->Still = ObtainBitmap("skater1"); + Anim->Slow = ObtainBitmap("skateslow"); + Anim->Medium = ObtainBitmap("skatemed"); + Anim->Fast = ObtainBitmap("skatefast"); + + if ((Sound = ObtainSample("skating"))) { + Anim->SkateVoice = al_create_sample_instance(Sound); + al_set_sample_instance_playmode(Anim->SkateVoice, ALLEGRO_PLAYMODE_BIDIR); + } else + Anim->SkateVoice = NULL; + + return Anim; +} + +void FreePlayerAnimation(struct Animation *Anim) +{ + if (Anim) { + + if (Anim->SkateVoice) { + al_stop_sample_instance(Anim->SkateVoice); + al_destroy_sample_instance(Anim->SkateVoice); + } + + free(Anim); + } +} + +void PauseAnimation(struct Animation *Anim) +{ + if (Anim->SkateVoice) + al_stop_sample_instance(Anim->SkateVoice); +} + +void UnpauseAnimation(struct Animation *Anim) +{ + if (Anim->SkateVoice) { + al_attach_sample_instance_to_mixer(Anim->SkateVoice, al_get_default_mixer()); + al_play_sample_instance(Anim->SkateVoice); + } +} + +/* +ALLEGRO_BITMAP *GetCurrentBitmap(struct Animation *Anim) +{ + return Anim->bmps[((int)Anim->TimeCount)&3]; +} + +void AdvanceAnimation(struct Animation *Anim, double Distance, int OnPlatform, int Forward) +{ + Anim->TimeCount += Distance*0.125f; +} + +struct Animation *SeedPlayerAnimation(void) +{ + struct Animation *Anim = (struct Animation *)malloc(sizeof(struct Animation)); + Anim->bmps = (ALLEGRO_BITMAP **)malloc(sizeof(ALLEGRO_BITMAP *)*4); + Anim->bmps[0] = load_bitmap("man-frame1.bmp", NULL); + Anim->bmps[1] = load_bitmap("man-frame2.bmp", NULL); + Anim->bmps[2] = load_bitmap("man-frame3.bmp", NULL); + Anim->bmps[3] = load_bitmap("man-frame4.bmp", NULL); + return Anim; +} + +void FreePlayerAnimation(struct Animation *Anim) +{ + if(Anim) + { + if(Anim->bmps) + { + al_destroy_bitmap(Anim->bmps[0]); + al_destroy_bitmap(Anim->bmps[1]); + al_destroy_bitmap(Anim->bmps[2]); + al_destroy_bitmap(Anim->bmps[3]); + free((void *)Anim->bmps); + } + free(Anim); + } +} +*/ diff --git a/allegro/demos/skater/src/anim.h b/allegro/demos/skater/src/anim.h new file mode 100644 index 00000000..f0aea45b --- /dev/null +++ b/allegro/demos/skater/src/anim.h @@ -0,0 +1,20 @@ +#ifndef __DEMO_ANIM_H__ +#define __DEMO_ANIM_H__ + +#include "global.h" + +struct Animation { + ALLEGRO_BITMAP *Animation[3], *Still, *Slow, *Medium, *Fast, *CBitmap; + ALLEGRO_SAMPLE_INSTANCE *SkateVoice; + double TimeCount; +}; + +extern ALLEGRO_BITMAP *GetCurrentBitmap(struct Animation *); +extern void AdvanceAnimation(struct Animation *, double Distance, + int OnPlatform); +extern struct Animation *SeedPlayerAnimation(void); +extern void FreePlayerAnimation(struct Animation *Anim); +extern void PauseAnimation(struct Animation *Anim); +extern void UnpauseAnimation(struct Animation *Anim); + +#endif diff --git a/allegro/demos/skater/src/background_scroller.c b/allegro/demos/skater/src/background_scroller.c new file mode 100644 index 00000000..375d0639 --- /dev/null +++ b/allegro/demos/skater/src/background_scroller.c @@ -0,0 +1,60 @@ +#include <allegro5/allegro.h> +#include <math.h> +#include "demodata.h" +#include "global.h" +#include "background_scroller.h" + +static int offx; +static int offy; + +static double current_time; +static double dt; + +static ALLEGRO_BITMAP *tile; + +void draw_background(void) +{ + int dx = al_get_bitmap_width(tile); + int dy = al_get_bitmap_height(tile); + int x, y; + + while (offx > 0) + offx -= dx; + while (offy > 0) + offy -= dy; + + for (y = offy; y < screen_height; y += dy) { + for (x = offx; x < screen_width; x += dx) { + al_draw_bitmap(tile, x, y, 0); + } + } +} + + +void init_background(void) +{ + offx = 0; + offy = 0; + + current_time = 0.0f; + dt = 1.0f / (float)logic_framerate; + + tile = demo_data[DEMO_BMP_BACK].dat; +} + + +void update_background(void) +{ + /* increase time */ + current_time += dt; + + /* calculate new offset from current current_time with some weird trig functions + change the constants arbitrarily and/or add sin/cos components to + get more complex animations */ + offx = + (int)(1.4f * al_get_bitmap_width(tile) * sin(0.9f * current_time + 0.2f) + + 0.3f * al_get_bitmap_width(tile) * cos(1.5f * current_time - 0.4f)); + offy = + (int)(0.6f * al_get_bitmap_height(tile) * sin(1.2f * current_time - 0.7f) - + 1.2f * al_get_bitmap_height(tile) * cos(0.2f * current_time + 1.1f)); +} diff --git a/allegro/demos/skater/src/background_scroller.h b/allegro/demos/skater/src/background_scroller.h new file mode 100644 index 00000000..e63b7e05 --- /dev/null +++ b/allegro/demos/skater/src/background_scroller.h @@ -0,0 +1,10 @@ +#ifndef __DEMO_BACK_SCROLLER__ +#define __DEMO_BACK_SCROLLER__ + +#include <allegro5/allegro.h> + +void init_background(void); +void update_background(void); +void draw_background(void); + +#endif /* __DEMO_BACK_SCROLLER__ */ diff --git a/allegro/demos/skater/src/credits.c b/allegro/demos/skater/src/credits.c new file mode 100644 index 00000000..a96765d8 --- /dev/null +++ b/allegro/demos/skater/src/credits.c @@ -0,0 +1,531 @@ +#include <allegro5/allegro.h> +#include <ctype.h> +#include <math.h> +#include <string.h> +#include <stdio.h> +#include "credits.h" +#include "global.h" + +/* for parsing readme.txt */ +typedef struct TEXT_LIST { + char *text; + struct TEXT_LIST *next; +} TEXT_LIST; + + +typedef struct README_SECTION { + TEXT_LIST *head; + TEXT_LIST *tail; + char *flat; + char *desc; +} README_SECTION; + + +/* for parsing thanks._tx and the various source files */ +typedef struct CREDIT_NAME { + char *name; + char *text; + struct CREDIT_NAME *next; +} CREDIT_NAME; + + +static CREDIT_NAME *credits = NULL; + +/* text messages (loaded from readme.txt) */ +static char *title_text; +static int title_size; +static int title_alloced; + +/* for the text scroller */ +static int text_char; +static int text_width; +static int text_pix; +static int text_scroll; + +/* for the credits display */ +static CREDIT_NAME *cred; +static int credit_width; +static int credit_scroll; +static int credit_age; +static int credit_speed; +static int credit_skip; + +/* formats a list of TEXT_LIST structure into a single string */ +static char *format_text(TEXT_LIST * head, char *eol, char *gap) +{ + TEXT_LIST *l; + int size = 0; + char *s; + + l = head; + while (l) { + if (l->text[0]) + size += strlen(l->text) + strlen(eol); + else + size += strlen(gap) + strlen(eol); + l = l->next; + } + + s = malloc(size + 1); + s[0] = 0; + + l = head; + while (l) { + if (l->text[0]) + strcat(s, l->text); + else + strcat(s, gap); + strcat(s, eol); + l = l->next; + } + + return s; +} + + + +/* ensures argument of isspace is within valid range */ +static bool safe_isspace(unsigned char c) +{ + return isspace(c); +} + + + +/* loads the scroller message from readme.txt */ +static void load_text(void) +{ + README_SECTION sect[] = { + {NULL, NULL, NULL, "Introduction"}, + }; + +#define SPLITTER " " + + static char intro_msg[] = + "Welcome to the Allegro demonstration game, by Miran Amon, Nick Davies, Elias Pschernig, Thomas Harte & Jakub Wasilewski." + SPLITTER + "Help skateboarding Ted collect various shop items - see \"About\" for more information!" + SPLITTER; + + static char splitter[] = SPLITTER; + static char marker[] = "--------"; + char buf[256]; + README_SECTION *sec = NULL; + TEXT_LIST *l, *p; + ALLEGRO_FILE *f; + int inblank = true; + char *s; + int i; + ALLEGRO_USTR *u = al_ustr_newf("%s/readme.txt", data_path); + f = al_fopen(al_cstr(u), "r"); + al_ustr_free(u); + if (!f) { + title_text = + "Can't find readme.txt, so this scroller is empty. "; + title_size = strlen(title_text); + title_alloced = false; + return; + } + + while (al_fgets(f, buf, sizeof(buf)) != 0) { + if (buf[0] == '=') { + s = strchr(buf, ' '); + if (s) { + for (i = strlen(s) - 1; (safe_isspace(s[i])) || (s[i] == '='); i--) + s[i] = 0; + + s++; + + sec = NULL; + inblank = true; + + for (i = 0; i < (int)(sizeof(sect) / sizeof(sect[0])); i++) { + if (my_stricmp(s, sect[i].desc) == 0) { + sec = §[i]; + break; + } + } + } + } else if (sec) { + s = buf; + + while ((*s) && (safe_isspace(*s))) + s++; + + for (i = strlen(s) - 1; (i >= 0) && (isspace(s[i])); i--) + s[i] = 0; + + if ((s[0]) || (!inblank)) { + l = malloc(sizeof(TEXT_LIST)); + l->next = NULL; + l->text = malloc(strlen(s) + 1); + strcpy(l->text, s); + + if (sec->tail) + sec->tail->next = l; + else + sec->head = l; + + sec->tail = l; + } + + inblank = (s[0] == 0); + } + } + + al_fclose(f); + + title_size = strlen(intro_msg); + + for (i = 0; i < (int)(sizeof(sect) / sizeof(sect[0])); i++) { + if (sect[i].head) { + sect[i].flat = format_text(sect[i].head, " ", splitter); + title_size += + strlen(sect[i].flat) + strlen(sect[i].desc) + + strlen(splitter) + strlen(marker) * 2 + 2; + } + } + + title_text = malloc(title_size + 1); + title_alloced = true; + + strcpy(title_text, intro_msg); + + for (i = 0; i < (int)(sizeof(sect) / sizeof(sect[0])); i++) { + if (sect[i].flat) { + strcat(title_text, marker); + strcat(title_text, " "); + strcat(title_text, sect[i].desc); + strcat(title_text, " "); + strcat(title_text, marker); + strcat(title_text, splitter); + strcat(title_text, sect[i].flat); + } + } + + for (i = 0; i < (int)(sizeof(sect) / sizeof(sect[0])); i++) { + l = sect[i].head; + while (l) { + free(l->text); + p = l; + l = l->next; + free(p); + } + if (sect[i].flat) + free(sect[i].flat); + } +} + + +/* sorts a list of credit strings */ +static void sort_credit_list(void) +{ + CREDIT_NAME **prev, *p; + int n, done; + + do { + done = true; + + prev = &credits; + p = credits; + + while ((p) && (p->next)) { + n = 0; + + if (n == 0) { + n = my_stricmp(p->name, p->next->name); + } + + if (n > 0) { + *prev = p->next; + p->next = p->next->next; + (*prev)->next = p; + p = *prev; + + done = false; + } + + prev = &p->next; + p = p->next; + } + } while (!done); +} + + +/* helper to open thanks._tx */ +static ALLEGRO_FILE *open_thanks(const char *s) +{ + ALLEGRO_FILE *f; + ALLEGRO_USTR *u = al_ustr_newf("%s/%s", data_path, s); + f = al_fopen(al_cstr(u), "r"); + al_ustr_free(u); + return f; +} + + +/* reads credit info from various places */ +static void load_credits(void) +{ + char buf[256], *p, *p2; + CREDIT_NAME *c = NULL; + ALLEGRO_FILE *f; + + /* parse thanks._tx, guessing at the relative location */ + if ((f = open_thanks("thanks.txt")) == NULL) { + return; + } + + while (al_fgets(f, buf, sizeof(buf))) { + if (my_stricmp(buf, "Thanks!") == 0) + break; + + while ((p = strstr(buf, "<")) != NULL) { + *p = '<'; + memmove(p + 1, p + 3, strlen(p + 2)); + } + + while ((p = strstr(buf, ">")) != NULL) { + *p = '>'; + memmove(p + 1, p + 3, strlen(p + 2)); + } + + p = buf; + + while ((*p) && (safe_isspace(*p))) + p++; + + p2 = p; + + while ((*p2) && ((!safe_isspace(*p2)) || (*(p2 + 1) != '('))) + p2++; + + if ((strncmp(p2, " (<email>", 9) == 0) || + (strncmp(p2, " (email", 7) == 0)) { + *p2 = 0; + + c = malloc(sizeof(CREDIT_NAME)); + + c->name = malloc(strlen(p) + 1); + strcpy(c->name, p); + + c->text = NULL; + + c->next = credits; + credits = c; + } else if (*p) { + if (c) { + p2 = p + strlen(p) - 1; + while ((p2 > p) && (safe_isspace(*p2))) + *(p2--) = 0; + + if (c->text) { + c->text = realloc(c->text, strlen(c->text) + strlen(p) + 2); + strcat(c->text, " "); + strcat(c->text, p); + } else { + c->text = malloc(strlen(p) + 1); + strcpy(c->text, p); + } + } + } else + c = NULL; + } + + al_fclose(f); + + /* sort the lists */ + sort_credit_list(); +} + + +static CREDIT_NAME *next_credit(CREDIT_NAME * cred) +{ + int max, i; + + if (!cred) { + cred = credits; + if (!cred) + return NULL; + } + + max = rand() % 1000; + for (i = 0; i < max; i++) { + if (cred->next) { + cred = cred->next; + } else { + cred = credits; + } + } + + return cred; +} + + +void init_credits(void) +{ + /* for the text scroller */ + text_char = 0xFFFF; + text_width = 0; + text_pix = 0; + text_scroll = 0; + + /* for the credits display */ + cred = NULL; + credit_width = 0; + credit_scroll = 0; + credit_age = 0; + credit_speed = 32; + credit_skip = 1; + + load_text(); + load_credits(); +} + + +void update_credits(void) +{ + /* move the scroller */ + text_scroll++; + + /* update the credits position */ + if (credit_scroll <= 0) { + cred = next_credit(cred); + + if (cred) { + credit_width = al_get_text_width(demo_font, cred->name) + 24; + + if (cred->text) { + credit_scroll = + al_get_text_width(plain_font, cred->text) + screen_width - credit_width; + } else { + credit_scroll = 256; + } + + credit_age = 0; + } + } else { + credit_scroll--; + credit_age++; + } +} + + +void draw_credits(void) +{ + int c, c2; + int y2; + ALLEGRO_COLOR col_back, col_font; + + /* for the text scroller */ + char buf[2] = " "; + + /* for the credits display */ + char cbuf[2] = " "; + char *p; + + col_back = al_map_rgb(222, 222, 222); + col_font = al_map_rgb(96, 96, 96); + + /* draw the text scroller */ + y2 = screen_height - al_get_font_line_height(demo_font); + text_pix = -(text_scroll / 1); + al_draw_line(0, y2 - 1.5, screen_width, y2 - 1.5, col_font, 1); + al_draw_line(0, y2 - 0.5, screen_width, y2 - 0.5, col_font, 1); + al_draw_filled_rectangle(0, y2, screen_width, screen_height, col_back); + for (text_char = 0; text_char < title_size; text_char++) { + buf[0] = title_text[text_char]; + c = al_get_text_width(demo_font, buf); + + if (text_pix + c > 0) { + demo_textout(demo_font, buf, text_pix, y2, col_font); + } + + text_pix += c; + + if (text_pix >= screen_width) { + break; + } + } + + /* draw author name/desc credits */ + y2 = al_get_font_line_height(demo_font); + al_draw_filled_rectangle(0, 0, screen_width, y2, col_back); + al_draw_line(0, y2 + 0.5, screen_width, y2 + 0.5, col_font, 1); + al_draw_line(0, y2 + 1.5, screen_width, y2 + 1.5, col_font, 1); + y2 = (al_get_font_line_height(demo_font) - 8) / 2; + + if (cred && cred->text) { + c = credit_scroll; + p = cred->text; + c2 = strlen(p); + + if (c > 0) { + if (c2 > c / 8) { + p += c2 - c / 8; + c &= 7; + } else { + c -= c2 * 8; + } + + c += credit_width; + + while ((*p) && (c < screen_width - 32)) { + if (c < credit_width + 96) { + c2 = 128 + (c - credit_width - 32) * 127 / 64; + } else if (c > screen_width - 96) { + c2 = 128 + (screen_width - 32 - c) * 127 / 64; + } else { + c2 = 255; + } + + if ((c2 > 128) && (c2 <= 255)) { + c2 = 255 - c2 + 64; + cbuf[0] = *p; + demo_textout(plain_font, cbuf, c, 0, al_map_rgb(c2, c2, c2)); + } + + p++; + c += 8; + } + } + } + + c = 4; + + if (credit_age < 100) { + c -= (100 - credit_age) * (100 - credit_age) * credit_width / 10000; + } + + if (credit_scroll < 150) { + c += (150 - credit_scroll) * (150 - credit_scroll) * screen_width / 22500; + } + + if (cred) + demo_textprintf(demo_font, c, 0, col_font, "%s:", cred->name); + else + demo_textprintf(demo_font, 0, 0, col_font, + "thanks._tx not found!"); +} + + +void destroy_credits(void) +{ + if ((title_text) && (title_alloced)) { + free(title_text); + } + + while (credits) { + cred = credits; + credits = cred->next; + + if (cred->name) { + free(cred->name); + } + + if (cred->text) { + free(cred->text); + } + + free(cred); + } +} diff --git a/allegro/demos/skater/src/credits.h b/allegro/demos/skater/src/credits.h new file mode 100644 index 00000000..9ed79bd8 --- /dev/null +++ b/allegro/demos/skater/src/credits.h @@ -0,0 +1,10 @@ +#ifndef __DEMO_CREDITS_H__ +#define __DEMO_CREDITS_H__ + +void init_credits(void); +void update_credits(void); +void draw_credits(void); +void destroy_credits(void); + + +#endif /* __DEMO_CREDITS_H__ */ diff --git a/allegro/demos/skater/src/defines.h b/allegro/demos/skater/src/defines.h new file mode 100644 index 00000000..725c9a4e --- /dev/null +++ b/allegro/demos/skater/src/defines.h @@ -0,0 +1,63 @@ +#ifndef __DEMO_DEFINES_H__ +#define __DEMO_DEFINES_H__ + +#include "demodata.h" + +/* Error codes. */ +#define DEMO_OK 0 +#define DEMO_ERROR_ALLEGRO 1 +#define DEMO_ERROR_GFX 2 +#define DEMO_ERROR_MEMORY 3 +#define DEMO_ERROR_VIDEOMEMORY 4 +#define DEMO_ERROR_TRIPLEBUFFER 5 +#define DEMO_ERROR_DATA 6 +#define DEMO_ERROR_GAMEDATA 7 + +/* Screen update driver IDs */ +#define DEMO_UPDATE_DIRECT 0 +#define DEMO_DOUBLE_BUFFER 1 +#define DEMO_PAGE_FLIPPING 2 +#define DEMO_TRIPLE_BUFFER 3 +#define DEMO_OGL_FLIPPING 4 + +/* Input controller IDs */ +#define DEMO_CONTROLLER_KEYBOARD 0 +#define DEMO_CONTROLLER_GAMEPAD 1 + +/* Virtual controller button IDs */ +#define DEMO_BUTTON_LEFT 0 +#define DEMO_BUTTON_RIGHT 1 +#define DEMO_BUTTON_JUMP 2 + +/* Game state/screen IDs. Each game state must have a unique ID. + DEMO_STATE_EXIT is a special state that doesn't relate to any + actual gamestate but represents the final state of the game + framework state machine. */ +#define DEMO_STATE_MAIN_MENU 0 +#define DEMO_STATE_NEW_GAME 1 +#define DEMO_STATE_OPTIONS 2 +#define DEMO_STATE_GFX 3 +#define DEMO_STATE_SOUND 4 +#define DEMO_STATE_CONTROLS 5 +#define DEMO_STATE_MISC 6 +#define DEMO_STATE_ABOUT 7 +#define DEMO_STATE_HELP 8 +#define DEMO_STATE_INTRO 9 +#define DEMO_STATE_CONTINUE_GAME 10 +#define DEMO_STATE_SUCCESS 11 +#define DEMO_STATE_EXIT -1 + +/* Size of the buffers containing absolute paths to various game files. */ +#define DEMO_PATH_LENGTH 1024 + +/* Size of the static array that holds the game states. */ +#define DEMO_MAX_GAMESTATES 64 + +/* Skater can use both AllegroGL and plain Allegro fonts. AllegroGL fonts + require somewhat more code but are much faster that Allegro fonts. */ +/* By defualt, use AllegroGL fonts if building in AllegroGL mode. */ +#ifdef DEMO_USE_ALLEGRO_GL + #define DEMO_USE_ALLEGRO_GL_FONT +#endif + +#endif /* __DEMO_DEFINES_H__ */ diff --git a/allegro/demos/skater/src/demodata.h b/allegro/demos/skater/src/demodata.h new file mode 100644 index 00000000..e56d27bb --- /dev/null +++ b/allegro/demos/skater/src/demodata.h @@ -0,0 +1,45 @@ +#ifndef __DEMODATA_H__ +#define __DEMODATA_H__ + +enum { + DEMO_BMP_BACK, + DEMO_FONT, + DEMO_FONT_LOGO, + DEMO_MIDI_INGAME, + DEMO_MIDI_INTRO, + DEMO_MIDI_MENU, + DEMO_MIDI_SUCCESS, + DEMO_SAMPLE_BUTTON, + DEMO_SAMPLE_WELCOME, + DEMO_SAMPLE_SKATING, + DEMO_SAMPLE_WAVE, + DEMO_SAMPLE_DING, + DEMO_SAMPLE_DOOROPEN, + DEMO_SAMPLE_POP, + + DEMO_BMP_BANANAS, + DEMO_BMP_CHERRIES, + DEMO_BMP_CLOUD, + DEMO_BMP_DOOROPEN, + DEMO_BMP_DOORSHUT, + DEMO_BMP_EXITSIGN, + DEMO_BMP_GRASS, + DEMO_BMP_ICECREAM, + DEMO_BMP_ICE, + DEMO_BMP_ICETIP, + DEMO_BMP_ORANGE, + DEMO_BMP_SKATEFAST, + DEMO_BMP_SKATEMED, + DEMO_BMP_SKATER1, + DEMO_BMP_SKATER2, + DEMO_BMP_SKATER3, + DEMO_BMP_SKATER4, + DEMO_BMP_SKATESLOW, + DEMO_BMP_SOIL, + DEMO_BMP_SWEET, + DEMO_BMP_WATER, + + DEMO_DATA_COUNT +}; + +#endif diff --git a/allegro/demos/skater/src/fps.c b/allegro/demos/skater/src/fps.c new file mode 100644 index 00000000..9c640a09 --- /dev/null +++ b/allegro/demos/skater/src/fps.c @@ -0,0 +1,66 @@ +/* Module for measuring FPS for Allegro games - implementation. + Written by Miran Amon. +*/ + +#include <allegro5/allegro.h> +#include "fps.h" +#include "global.h" + + +FPS *create_fps(int fps) +{ + int i; + FPS *ret = malloc(sizeof(FPS)); + + ret->nSamples = fps; + ret->samples = malloc(fps * sizeof(int)); + for (i = 0; i < fps; i++) { + ret->samples[i] = 1; + } + ret->curSample = 0; + ret->frameCounter = 0; + ret->framesPerSecond = fps; + return ret; +} + + +void destroy_fps(FPS * fps) +{ + free(fps->samples); + fps->samples = NULL; + fps->nSamples = 0; + fps->frameCounter = 0; + free(fps); + fps = NULL; +} + + +void fps_tick(FPS * fps) +{ + fps->curSample++; + fps->curSample %= fps->nSamples; + fps->framesPerSecond -= fps->samples[fps->curSample]; + fps->framesPerSecond += fps->frameCounter; + fps->samples[fps->curSample] = fps->frameCounter; + fps->frameCounter = 0; +} + + +void fps_frame(FPS * fps) +{ + ++(fps->frameCounter); +} + + +int get_fps(FPS * fps) +{ + return fps->framesPerSecond; +} + + +void draw_fps(FPS * fps, ALLEGRO_FONT *font, int x, int y, ALLEGRO_COLOR fg, + char *format) +{ + demo_textprintf_right(font, x, y, fg, format, + get_fps(fps)); +} diff --git a/allegro/demos/skater/src/fps.h b/allegro/demos/skater/src/fps.h new file mode 100644 index 00000000..22ba6768 --- /dev/null +++ b/allegro/demos/skater/src/fps.h @@ -0,0 +1,120 @@ +/* Module for measuring FPS for Allegro games. + Written by Miran Amon. + version: 1.02 + date: 27. June 2003 +*/ + +#ifndef __DEMO_FPS_H__ +#define __DEMO_FPS_H__ + +#include <allegro5/allegro.h> +#include <allegro5/allegro_font.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Underlaying structure for measuring FPS. The user should create an instance + of this structure with create_fps() and destroy it with destroy_fps(). + The user should not use the contents of the structure directly, + functions for manipulating with the FPS structure should be used instead. +*/ + typedef struct FPS { + int *samples; + int nSamples; + int curSample; + int frameCounter; + int framesPerSecond; + } FPS; + + +/* Creates an instance of the FPS structure and initializes it. The user + should call this function somewhere at the beginning of the program and + use the value it returns to access the current FPS. + + Parameters: + int fps - the frequency of the timer used to control the speed of the program + + Returns: + FPS *fps - an instance of the FPS structure +*/ + FPS *create_fps(int fps); + + +/* Destroys an FPS object. The user should call this function when he's + done measuring the FPS, i.e. at the end of the program. + + Parameters: + FPS *fps - a pointer to an FPS object + + Returns: + nothing +*/ + void destroy_fps(FPS * fps); + + +/* Updates the FPS measuring logic. The user should call this function exactly + fps times per second where fps is the speed of their timer. Usually this is + implemented in the logic code, i.e. in the while(timer_counter) loop or + an equivalent. + + Parameters: + FPS *fps - a pointer to an FPS object + + Returns: + nothing +*/ + void fps_tick(FPS * fps); + + +/* Counts the number of drawn frames. The user should call this function + every time they draw their frame. + + Parameters: + FPS *fps - a pointer to an FPS object + + Returns: + nothing +*/ + void fps_frame(FPS * fps); + + +/* Retreives the current frame rate in frames per second. This will actually + be the average frame rate over the last second. + + Parameters: + FPS *fps - a pointer to an FPS object + + Returns: + int fps - the average frame rate over the last second +*/ + int get_fps(FPS * fps); + + +/* Draws the current frame rate on the specified bitmap with the specified + parameters. + + Parameters: + FPS *fps - a pointer to an FPS object + ALLEGRO_BITMAP *bmp - destination bitmap + FONT *font - the font used for printing the fps + int x, y - position of the fps text on the destination bitmap + int color - the color of the fps text + char *format - the format of the text as you would pass to printf(); the + format should contain whatever text you wish to print and + a format sequence for outputting an integer; + + Returns: + nothing + + Example: + draw_fps(fps, screen, font, 100, 50, makecol(123,234,213), "FPS = %d"); +*/ + void draw_fps(FPS * fps, ALLEGRO_FONT * font, int x, int y, + ALLEGRO_COLOR color, char *format); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/allegro/demos/skater/src/framework.c b/allegro/demos/skater/src/framework.c new file mode 100644 index 00000000..43b4f5a7 --- /dev/null +++ b/allegro/demos/skater/src/framework.c @@ -0,0 +1,498 @@ +#include <allegro5/allegro.h> +#ifdef ALLEGRO_ANDROID +#include <allegro5/allegro_android.h> +#endif +#include "global.h" +#include "credits.h" +#include "fps.h" +#include "framework.h" +#include "game.h" +#include "gamepad.h" +#include "gamestate.h" +#include "keyboard.h" +#include "mouse.h" +#include "menus.h" +#include "screenshot.h" +#include "transition.h" + +static int closed = false; + +/* name of the configuration file for storing demo-specific settings. */ +#define DEMO_CFG "demo.cfg" + +static int timer = 0; + +/* Screenshot module; for taking screenshots. */ +static SCREENSHOT *screenshot = NULL; + +/* Status of the F12 key; used for taking screenshots. */ +static int F12 = 0; + +/* Framerate counter module. */ +static FPS *fps = NULL; + +/* + Static array of gamestates. Only state_count states are actually initialized. + The current_state variable points to the currently active state and + last_state points to the previous state. This required to do smooth + transitions between states. +*/ +static GAMESTATE state[DEMO_MAX_GAMESTATES]; +static int current_state = 0, last_state; +static int state_count = 0; + +ALLEGRO_EVENT_QUEUE *event_queue; + +/* + Module for performing smooth state transition animations. +*/ +static TRANSITION *transition = NULL; + + + +static void drop_build_config_dir(ALLEGRO_PATH *path) +{ + const char *s = al_get_path_tail(path); + if (s) { + if (0 == strcmp(s, "Debug") + || 0 == strcmp(s, "Release") + || 0 == strcmp(s, "RelWithDebInfo") + || 0 == strcmp(s, "Profile")) + { + al_drop_path_tail(path); + } + } +} + + +int init_framework(void) +{ + int error = DEMO_OK; + int c; + ALLEGRO_PATH *path; + + /* Attempt to initialize Allegro. */ + if (!al_init()) { + return DEMO_ERROR_ALLEGRO; + } + + al_init_image_addon(); + al_init_primitives_addon(); + al_init_font_addon(); + + /* Construct aboslute path for the configuration file. */ + al_set_app_name("Allegro Skater Demo"); + al_set_org_name(""); + path = al_get_standard_path(ALLEGRO_USER_SETTINGS_PATH); + al_make_directory(al_path_cstr(path, '/')); + al_set_path_filename(path, DEMO_CFG); + strncpy(config_path, al_path_cstr(path, '/'), DEMO_PATH_LENGTH); + al_destroy_path(path); + + /* Construct absolute path for the datafile containing game menu data. */ +#ifdef ALLEGRO_ANDROID + al_android_set_apk_file_interface(); + strncpy(data_path, "/data", DEMO_PATH_LENGTH); + (void)drop_build_config_dir; +#else + path = al_get_standard_path(ALLEGRO_RESOURCES_PATH); + al_set_path_filename(path, ""); + drop_build_config_dir(path); + al_append_path_component(path, "data"); + strncpy(data_path, al_path_cstr(path, '/'), DEMO_PATH_LENGTH); + al_destroy_path(path); +#endif + + /* Read configuration file. */ + read_global_config(config_path); + + /* Set window title and install close icon callback on platforms that + support this. */ + al_set_window_title(screen, "Allegro Demo Game"); + + /* Install the Allegro sound and music submodule. Note that this function + failing is not considered a fatal error so no error checking is + required. If this call fails, the game will still run, but with no + sound or music (or both). */ + al_install_audio(); + al_init_acodec_addon(); + al_reserve_samples(8); + + event_queue = al_create_event_queue(); + + /* Attempt to set the gfx mode. */ + if ((error = change_gfx_mode()) != DEMO_OK) { + fprintf(stderr, "Error: %s\n", demo_error(error)); + return error; + } + + /* Attempt to install the Allegro keyboard submodule. */ + if (!al_install_keyboard()) { + fprintf(stderr, "Error installing keyboard: %s\n", + demo_error(DEMO_ERROR_ALLEGRO)); + return DEMO_ERROR_ALLEGRO; + } + + /* Attempt to install the joystick submodule. Note: no need to check + the return value as joystick isn't really required! */ + al_install_joystick(); + + if (al_install_touch_input()) + al_register_event_source(event_queue, al_get_touch_input_event_source()); + + al_install_mouse(); + + al_register_event_source(event_queue, al_get_keyboard_event_source()); + al_register_event_source(event_queue, al_get_mouse_event_source()); + al_register_event_source(event_queue, al_get_joystick_event_source()); + + /* Create a timer. */ + { + ALLEGRO_TIMER *t = al_create_timer(1.0 / logic_framerate); + al_register_event_source(event_queue, al_get_timer_event_source(t)); + al_start_timer(t); + } + + /* Seed the random number generator. */ + srand((unsigned)time(NULL)); + + /* Create the screenshot module. Screenshots will be saved in TGA format + and named SHOTxxxx.TGA. */ + screenshot = create_screenshot("SHOT", "TGA"); + + /* Create the frame rate counter module. */ + fps = create_fps(logic_framerate); + + /* Initialize the game state array. */ + c = DEMO_MAX_GAMESTATES; + while (c--) { + state[c].deinit = state[c].init = NULL; + state[c].id = state[c].update = NULL; + state[c].draw = NULL; + } + + /* Create all the game states/screens/pages. New screens may be added + here as required. */ + create_main_menu(&state[0]); + create_options_menu(&state[1]); + create_gfx_menu(&state[2]); + create_sound_menu(&state[3]); + create_misc_menu(&state[4]); + create_controls_menu(&state[5]); + create_intro(&state[6]); + create_about_menu(&state[7]); + create_new_game(&state[8]); + create_continue_game(&state[9]); + create_success_menu(&state[10]); + + state_count = 11; /* demo game has 11 screens */ + current_state = 6; /* the game will start with screen #7 - the intro */ + + /* Create the keyboard and gamepad controller modules. */ + controller[DEMO_CONTROLLER_KEYBOARD] = + create_keyboard_controller(config_path); + controller[DEMO_CONTROLLER_GAMEPAD] = + create_gamepad_controller(config_path); + + /* Initialize the module for displaying credits. */ + init_credits(); + + return error; +} + + +/* + Draws the current state or transition animation to the backbuffer + and flips the page. + + Parameters: + none + + Returns: + none +*/ +static void draw_framework(void) +{ + + /* Draw either the current state or the transition animation if we're + in between states. */ + if (transition) { + draw_transition(transition); + } else { + /* DEMO_STATE_EXIT is a special case and doesn't eqate to and actual + state that can be drawn. */ + if (current_state != DEMO_STATE_EXIT) { + state[current_state].draw(); + } + } + + /* Draw the current framerate if required. */ + if (display_framerate) { + draw_fps(fps, plain_font, screen_width, 0, al_map_rgb(255, 255, 255), "%d FPS"); + } + + al_flip_display(); +} + + +void run_framework(void) +{ + int done = false; /* will become true when we're ready to close */ + int need_to_redraw = 1; /* do we need to draw the next frame? */ + int next_state = current_state; + int i; + bool background_mode = false; + bool paused = false; + + /* Initialize the first game screen. */ + state[current_state].init(); + + /* Create a transition animation so that the first screen doesn't just + pop up but comes in a nice animation that lasts 0.3 seconds. */ + transition = create_transition(NULL, &state[current_state], 0.3f); + + timer = 0; + + /* Do the main loop; until we're not done. */ + while (!done) { + + ALLEGRO_EVENT event; + + al_wait_for_event(event_queue, &event); + switch (event.type) { + + case ALLEGRO_EVENT_MOUSE_AXES: + mouse_handle_event(&event); + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + mouse_handle_event(&event); + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + mouse_handle_event(&event); + break; + + case ALLEGRO_EVENT_KEY_DOWN: + keyboard_event(&event); + break; + + case ALLEGRO_EVENT_KEY_CHAR: + keyboard_event(&event); + break; + + case ALLEGRO_EVENT_KEY_UP: + keyboard_event(&event); + break; + + case ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN: + gamepad_event(&event); + break; + + case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: + gamepad_event(&event); + break; + + case ALLEGRO_EVENT_JOYSTICK_AXIS: + gamepad_event(&event); + break; + + case ALLEGRO_EVENT_TOUCH_BEGIN: + gamepad_event(&event); + break; + case ALLEGRO_EVENT_TOUCH_END: + gamepad_event(&event); + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + closed = true; + break; + + case ALLEGRO_EVENT_TIMER: + if (!paused) + timer++; + break; + + case ALLEGRO_EVENT_DISPLAY_ORIENTATION: + if (event.display.orientation == ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES || + event.display.orientation == ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES) + screen_orientation = event.display.orientation; + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(screen); + screen_width = al_get_display_width(screen); + screen_height = al_get_display_height(screen); + if (fullscreen == 0) { + window_width = screen_width; + window_height = screen_height; + } + break; + + case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: + background_mode = true; + al_acknowledge_drawing_halt(screen); + break; + + case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: + background_mode = false; + break; + + case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: + paused = true; + break; + + case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: + paused = false; + break; + + } + + if (!al_is_event_queue_empty(event_queue)) continue; + + /* Check if the timer has ticked. */ + while (timer > 0) { + --timer; + + /* See if the user pressed F12 to see if the user wants to take + a screenshot. */ + if (key_pressed(ALLEGRO_KEY_F12)) { + /* See if the F12 key was already pressed before. */ + if (F12 == 0) { + /* The user just pressed F12 (it wasn't pressed before), so + remember this and take a screenshot! */ + F12 = 1; + take_screenshot(screenshot); + } + } else { + /* Remember for later that F12 is not pressed. */ + F12 = 0; + } + + /* Do one frame of logic. If we're in between states, then update + the transition animation module, otherwise update the current + game state. */ + if (transition) { + /* Advance the transition animation. If it returns non-zero, it + means the animation finished playing. */ + if (update_transition(transition) == 0) { + /* Destroy the animation, we're done with it. */ + destroy_transition(transition); + transition = NULL; + + /* Complete the transition to the new state by deiniting the + previous one. */ + if (state[last_state].deinit) { + state[last_state].deinit(); + } + + /* Stop the main loop if there is no more game screens. */ + if (current_state == DEMO_STATE_EXIT) { + done = true; + break; + } + } + } + /* We're not in between states, so update the current one. */ + else { + /* Update the current state. It returns the ID of the + next state. */ + + next_state = state[current_state].update(); + + /* Did the current state just close the game? */ + if (next_state == DEMO_STATE_EXIT) { + /* Create a transition so the game doesn't just close but + instead goes out in a nice animation. */ + transition = + create_transition(&state[current_state], NULL, 0.3f); + last_state = current_state; + current_state = next_state; + break; + } + /* If the next state is different then the current one, then + start a transition. */ + else if (next_state != state[current_state].id()) { + last_state = current_state; + + /* Find the index of the next state in the state array. + Note that ID of a state is not the same as its index in + the array! */ + for (i = 0; i < state_count; i++) { + /* Did we find it? */ + if (state[i].id() == next_state) { + /* We found the new state. Initialize it and start the + transition animation. */ + state[i].init(); + transition = + create_transition(&state[current_state], &state[i], + 0.3f); + current_state = i; + break; + } + } + } + } + + /* We just did one logic frame so we assume we will need to update + the visuals to reflect the changes this logic frame made. */ + need_to_redraw = 1; + + /* Let the framerate counter know that one logic frame was run. */ + fps_tick(fps); + + keyboard_tick(); + mouse_tick(); + } + + /* In case a frame of logic has just been run or the user wants + unlimited framerate, we must redraw the screen. */ + if (need_to_redraw == 1 && !background_mode) { + /* Actually do the drawing. */ + draw_framework(); + + /* Make sure we don't draw too many times. */ + need_to_redraw = 0; + + /* Let the framerate counter know that we just drew a frame. */ + fps_frame(fps); + } + + /* Check if the user pressed the close icon. */ + done = done || closed; + + } +} + + +void shutdown_framework(void) +{ + al_destroy_event_queue(event_queue); + + /* Save the configuration settings. */ + write_global_config(config_path); + + /* Destroy the screenshot module. */ + destroy_screenshot(screenshot); + + /* Destroy the framerate counter module. */ + destroy_fps(fps); + + /* Destroy controller modules. */ + destroy_vcontroller(controller[DEMO_CONTROLLER_KEYBOARD], config_path); + destroy_vcontroller(controller[DEMO_CONTROLLER_GAMEPAD], config_path); + + /* Destroy the game states/screens. */ + destroy_game(); + + /* Get rid of all the game data. */ + unload_data(); + + /* Destroy the credits module. */ + destroy_credits(); + + /* Destroy the transition module. */ + if (transition) { + destroy_transition(transition); + } +} diff --git a/allegro/demos/skater/src/framework.h b/allegro/demos/skater/src/framework.h new file mode 100644 index 00000000..a0cb8f91 --- /dev/null +++ b/allegro/demos/skater/src/framework.h @@ -0,0 +1,55 @@ +#ifndef __DEMO_FRAMEWORK_H__ +#define __DEMO_FRAMEWORK_H__ + +#include <allegro5/allegro.h> +#include "defines.h" + +extern ALLEGRO_EVENT_QUEUE *event_queue; + +/* + Initializes Allegro, loads configuration settings, installs all + required Allegro submodules, creates all game state objects, loads + all data and does all other framework initialization tasks. Each + successfull call to this function must be paired with a call to + shutdown_framework()! + + Parameters: + none + + Returns: + Error code: DEMO_OK if initialization was successfull, otherwise + the code of the error that caused the function to fail. See + defines.h for a list of possible error codes. +*/ +extern int init_framework(void); + +/* + Runs the framework main loop. The framework consists of user definable + game state objects, each representing one screen or page. The main + loop simply switches between these states according to internal and + user specified inputs. Note: init_framework() must have been successfully + called before this function may be used. + + Parameters: + none + + Returns: + nothing +*/ +extern void run_framework(void); + +/* + Destroys all game state object and other framework modules that were + initialized in init_framework(). + + Parameters: + none + + Returns: + nothing +*/ +extern void shutdown_framework(void); + +extern bool key_down(int k); + +#endif /* __DEMO_FRAMEWORK_H__ */ diff --git a/allegro/demos/skater/src/game.c b/allegro/demos/skater/src/game.c new file mode 100644 index 00000000..f77c4790 --- /dev/null +++ b/allegro/demos/skater/src/game.c @@ -0,0 +1,488 @@ +#include <allegro5/allegro.h> +#include <allegro5/allegro_primitives.h> +#include <math.h> +#include "defines.h" +#include "game.h" +#include "global.h" +#include "menus.h" +#include "music.h" +#include "physics.h" +#include "vcontroller.h" + +/* + + All variables relevant to player position and level / level status. Only + thing of note is that PlayerPos is a 3 element array - it contains + player position (in elements 0 and 1) and rotation (in element 2) + +*/ +int KeyFlags; +int RequiredObjectsLeft, TotalObjectsLeft; +double PlayerPos[3], PlayerVec[2]; +double ScrollPos[2]; +struct Animation *PlayerAnim = NULL; +struct Level *Lvl = NULL; +struct LevelState *LvlState = NULL; +double LeftWindow = -120, RightWindow = 120; +double Pusher = 0; +static ALLEGRO_COLOR cloud_color; + +#define PLAYER_STRENGTH 0.14f + +/* + + ID things, for GAMESTATE purposes. Note that two menu entries head this way - + "new game" and "continue game", so we have to IDs +*/ +static int _newid = DEMO_STATE_NEW_GAME; +static int newid(void) +{ + return _newid; +} + +static int _continueid = DEMO_STATE_CONTINUE_GAME; +static int continueid(void) +{ + return _continueid; +} + +int CurrentID; + +/* background stuff */ +ALLEGRO_BITMAP *water; +ALLEGRO_SAMPLE_INSTANCE *WaterVoice, *WaterVoice2; +ALLEGRO_SAMPLE *WaveNoise = NULL; + +ALLEGRO_BITMAP *cloud; +al_fixed *TanTable = NULL; +int CalibRes = 0; + +double TexX; +double WaveY; + +struct { + double x, y; +} Clouds[8]; +double CloudX; + +char *load_game_resources(const char *data_path) +{ + int c; + ALLEGRO_PATH *path; + + printf("load_game_resources\n"); + path = al_create_path_for_directory(data_path); + al_set_path_filename(path, "level.txt"); + Lvl = LoadLevel(al_path_cstr(path, '/'), 15); + al_destroy_path(path); + + if (!Lvl) + return GetLevelError(); + + ReturnState(Lvl, LvlState); + + PlayerAnim = SeedPlayerAnimation(); + cloud = ObtainBitmap("cloud"); + water = ObtainBitmap("water"); + + c = 480 << 2; + TanTable = (al_fixed *) malloc(sizeof(al_fixed) * c); + while (c--) + TanTable[c] = + al_ftofix(tan + ((3.141592654f / 2.0f - + atan2(0.75f * + (((float)(c * 2) / (float)(480 << 2)) - 1), 1) + ))); + + WaveNoise = ObtainSample("wave"); + + cloud_color = al_get_pixel(cloud, 0, 0); + + return NULL; +} + +void unload_game_resources(void) +{ + printf("unload_game_resources\n"); + FreePlayerAnimation(PlayerAnim); + PlayerAnim = NULL; + + FreeState(LvlState); + LvlState = BorrowState(Lvl); + FreeLevel(Lvl); + Lvl = NULL; + + if (TanTable) { + free(TanTable); + TanTable = NULL; + } +} + +static void DeInit(void) +{ + if (WaterVoice) { + al_stop_sample_instance(WaterVoice); + al_destroy_sample_instance(WaterVoice); + WaterVoice = NULL; + } + if (WaterVoice2) { + al_stop_sample_instance(WaterVoice2); + al_destroy_sample_instance(WaterVoice2); + WaterVoice2 = NULL; + } + PauseAnimation(PlayerAnim); +} + +static void GenericInit(void) +{ + int c; + + CloudX = 0; + Clouds[0].x = Clouds[0].y = 0; + for (c = 1; c < 8; c++) { + Clouds[c].x = + Clouds[c - 1].x + al_get_bitmap_width(cloud) + 8 + + rand() * (screen_width * 480 / screen_height / 8) / RAND_MAX; + Clouds[c].y = rand() * 0.5 * 480 / RAND_MAX; + } + + WaterVoice = al_create_sample_instance(WaveNoise); + al_set_sample_instance_playmode(WaterVoice, ALLEGRO_PLAYMODE_BIDIR); + al_set_sample_instance_gain(WaterVoice, 0.5); + al_attach_sample_instance_to_mixer(WaterVoice, al_get_default_mixer()); + al_play_sample_instance(WaterVoice); + + WaterVoice2 = al_create_sample_instance(WaveNoise); + al_set_sample_instance_playmode(WaterVoice2, + ALLEGRO_PLAYMODE_BIDIR); + al_set_sample_instance_gain(WaterVoice2, 0.25); + al_attach_sample_instance_to_mixer(WaterVoice2, al_get_default_mixer()); + al_play_sample_instance(WaterVoice2); + + play_music(DEMO_MIDI_INGAME, true); + UnpauseAnimation(PlayerAnim); +} + +static void ContinueInit(void) +{ + GenericInit(); + CurrentID = continueid(); +} + +static void GameInit(void) +{ + KeyFlags = 0; + enable_continue_game(); + + SetInitialState(Lvl); + ScrollPos[0] = PlayerPos[0] = Lvl->PlayerStartPos[0]; + ScrollPos[1] = PlayerPos[1] = Lvl->PlayerStartPos[1]; + PlayerVec[0] = PlayerVec[1] = 0; + RequiredObjectsLeft = Lvl->ObjectsRequired; + TotalObjectsLeft = Lvl->TotalObjects; + + GenericInit(); + CurrentID = newid(); +} + +static void DrawClouds(void) +{ + int c = 8; + double x1, y1, x2, y2, x; + + while (c--) { + x = Clouds[c].x + CloudX; + + x1 = (x - sin(x) * 1.4); + x2 = (x + al_get_bitmap_width(cloud) + sin(x) * 1.4); + y1 = (Clouds[c].y - cos(x) * 1.4); + y2 = (Clouds[c].y + al_get_bitmap_height(cloud) + cos(x) * 1.4); + + if (x2 < 0) { + Clouds[c].x = + Clouds[(c - 1) & 7].x + al_get_bitmap_width(cloud) + 8 + + (rand() * 32.0 / RAND_MAX); + Clouds[c].y = rand() * 0.5 * screen_height / RAND_MAX; + } + else { + al_draw_scaled_bitmap(cloud, 0, 0, al_get_bitmap_width(cloud), + al_get_bitmap_height(cloud), + x1, y1, x2 - x1, y2 - y1, 0); + } + } +} + +static void set_v(ALLEGRO_VERTEX *vt, double x, double y, double u, double v) +{ + vt->x = x; + vt->y = y; + vt->z = 0; + vt->u = u; + vt->v = v; + vt->color = al_map_rgb_f(1, 1, 1); +} + +static void GameDraw(void) +{ + ALLEGRO_BITMAP *ch; + double depth; + ALLEGRO_VERTEX Points[4]; + ALLEGRO_TRANSFORM transform; + int chw, chh; + float w; + + al_identity_transform(&transform); + al_scale_transform(&transform, screen_height / 480.0, screen_height / 480.0); + al_use_transform(&transform); + + w = screen_width * 480.0 / screen_height; + + /* draw background */ + { + int c = 480 * 4 - 1; + double y2, lowy = 480, y1, u; + double index; + + while (c > 480 * 2 + 15) { + + depth = al_fixtof(al_fixmul(TanTable[c], (int)((ScrollPos[1] - 240) * 4096.0f))); + + if (depth > -261 && depth < -5.0f) { + int d = ((int)(depth * 65536)) & (256 * 65536 - 1); + y1 = lowy; + index = (d / 65536.0 - 1.0) * ALLEGRO_PI * 2 * 8 / 128.0f; + + y2 = c / 4.0 - 125.0f * sin(index + WaveY) / depth; + + if (y2 < lowy) { + lowy = ceil(y2); + + u = 64 + ScrollPos[0] / 8 + TexX; + set_v(Points + 0, 0, y2, u + depth * 4, depth + 5); + set_v(Points + 1, w, y2, u - depth * 4, depth + 5); + set_v(Points + 2, w, y1, u - depth * 4, depth + 5); + set_v(Points + 3, 0, y1, u + depth * 4, depth + 5); + + al_draw_prim(Points, NULL, water, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); + } + } + c--; + } + + al_set_clipping_rectangle(0, 0, screen_width, lowy * screen_height / 480 + 1); + al_clear_to_color(cloud_color); + DrawClouds(); + al_set_clipping_rectangle(0, 0, screen_width, screen_height); + } + + /* draw interactable parts of level */ + DrawLevelBackground(Lvl, ScrollPos); + +#ifdef DEBUG_EDGES + solid_mode(); + struct Edge *E = Lvl->AllEdges; + + while (E) { + line(buffer, + E->EndPoints[0]->Normal[0] - x + (screen_width >> 1), + E->EndPoints[0]->Normal[1] - y + (screen_height >> 1), + E->EndPoints[1]->Normal[0] - x + (screen_width >> 1), + E->EndPoints[1]->Normal[1] - y + (screen_height >> 1), al_map_rgb(0, 0, + 0)); + E = E->Next; + } +#endif + +#ifdef DEBUG_OBJECTS + struct Object *O = Lvl->AllObjects; + + while (O) { + rect(buffer, + O->Bounder.TL.Pos[0] - x + (screen_width >> 1), + O->Bounder.TL.Pos[1] - y + (screen_height >> 1), + O->Bounder.BR.Pos[0] - x + (screen_width >> 1), + O->Bounder.BR.Pos[1] - y + (screen_height >> 1), al_map_rgb(0, 0, 0)); + circle(buffer, O->Pos[0] - x + (screen_width >> 1), + O->Pos[1] - y + (screen_height >> 1), O->ObjType->Radius, al_map_rgb(0, + 0, + 0)); + O = O->Next; + } +#endif + + /* add player sprite */ + ch = GetCurrentBitmap(PlayerAnim); + chw = al_get_bitmap_width(ch); + chh = al_get_bitmap_height(ch); + + al_draw_scaled_rotated_bitmap(ch, chw / 2.0, chh / 2.0, + (PlayerPos[0] - ScrollPos[0]) + w / 2, + (PlayerPos[1] - ScrollPos[1]) + 480.0 / 2, + 1, 1, PlayerPos[2], + KeyFlags & KEYFLAG_FLIP ? ALLEGRO_FLIP_HORIZONTAL : 0); + + DrawLevelForeground(Lvl); + + al_identity_transform(&transform); + al_use_transform(&transform); + + /* add status */ + demo_textprintf(demo_font, + screen_width - al_get_text_width(demo_font, + "Items Required: 1000"), 8, + al_map_rgb(255, 255, 255), "Items Required: %d", + RequiredObjectsLeft); + demo_textprintf(demo_font, + screen_width - al_get_text_width(demo_font, + "Items Remaining: 1000"), + 8 + al_get_font_line_height(demo_font), al_map_rgb(255, 255, 255), + "Items Remaining: %d", TotalObjectsLeft); +} + +static int GameUpdate(void) +{ + struct QuadTreeNode *CollTree; + struct Container *EPtr; + + if (RequiredObjectsLeft < 0) + return DEMO_STATE_SUCCESS; + + TexX += 0.3f; + WaveY -= 0.02f; + CloudX -= 0.125f; + + /* scrolling */ + if ((PlayerPos[0] - ScrollPos[0]) < LeftWindow) + ScrollPos[0] = PlayerPos[0] - LeftWindow; + if ((PlayerPos[0] - ScrollPos[0]) > RightWindow) + ScrollPos[0] = PlayerPos[0] - RightWindow; + if ((PlayerPos[1] - ScrollPos[1]) < -80) + ScrollPos[1] = PlayerPos[1] + 80; + if ((PlayerPos[1] - ScrollPos[1]) > 80) + ScrollPos[1] = PlayerPos[1] - 80; + + if ((KeyFlags & KEYFLAG_FLIP) ^ (((PlayerPos[2] < ALLEGRO_PI * 0.5f) + && (PlayerPos[2] > + -ALLEGRO_PI * 0.5f)) ? 0 : KEYFLAG_FLIP) + ) { + if (LeftWindow < 0) + LeftWindow++; + if (RightWindow < 120) + RightWindow++; + } else { + if (LeftWindow > -120) + LeftWindow--; + if (RightWindow > 0) + RightWindow--; + } + + /* update controls */ + controller[controller_id]->poll(controller[controller_id]); + if (controller[controller_id]->button[0]) { + if (KeyFlags & KEYFLAG_LEFT) { + Pusher += 0.005f; + if (Pusher >= PLAYER_STRENGTH) + Pusher = PLAYER_STRENGTH; + } else { + KeyFlags |= KEYFLAG_LEFT; + Pusher = 0; + } + } else + KeyFlags &= ~KEYFLAG_LEFT; + + if (controller[controller_id]->button[1]) { + if (KeyFlags & KEYFLAG_RIGHT) { + Pusher += 0.005f; + if (Pusher >= PLAYER_STRENGTH) + Pusher = PLAYER_STRENGTH; + } else { + KeyFlags |= KEYFLAG_RIGHT; + Pusher = 0; + } + } else + KeyFlags &= ~KEYFLAG_RIGHT; + + if (controller[controller_id]->button[2]) + KeyFlags |= KEYFLAG_JUMP; + else { + if ((KeyFlags & KEYFLAG_JUMPING) && PlayerVec[1] < -2.0f) + PlayerVec[1] = -2.0f; + KeyFlags &= ~(KEYFLAG_JUMP | KEYFLAG_JUMP_ISSUED); + } + + /* run physics */ + CollTree = RunPhysics(Lvl, PlayerPos, PlayerVec, 0.6f, PlayerAnim); + + /* check whether any objects are collected */ + EPtr = CollTree->Contents; + while (EPtr && EPtr->Type == OBJECT) { + if (EPtr->Content.O->Flags & OBJFLAGS_VISIBLE) { + double SqDistance, XDiff, YDiff; + + XDiff = PlayerPos[0] - EPtr->Content.O->Pos[0]; + YDiff = PlayerPos[1] - EPtr->Content.O->Pos[1]; + SqDistance = XDiff * XDiff + YDiff * YDiff; + + if (SqDistance <= + EPtr->Content.O->ObjType->Radius * + EPtr->Content.O->ObjType->Radius) { + /* collision! */ + if (EPtr->Content.O->Flags & OBJFLAGS_DOOR) { + if (!RequiredObjectsLeft) { + if (EPtr->Content.O->ObjType->CollectNoise) + play_sound(EPtr->Content.O->ObjType-> + CollectNoise, 255, 128, 1000, 0); + RequiredObjectsLeft = -1; + } + } else { + EPtr->Content.O->Flags &= ~OBJFLAGS_VISIBLE; + if (EPtr->Content.O->ObjType->CollectNoise) + play_sound(EPtr->Content.O->ObjType->CollectNoise, + 255, 128, 1000, 0); + + if (RequiredObjectsLeft > 0) { + RequiredObjectsLeft--; + if (!RequiredObjectsLeft) + SetDoorOpen(Lvl); + } + TotalObjectsLeft--; + } + } + } + + EPtr = EPtr->Next; + } + + return key_pressed(ALLEGRO_KEY_ESCAPE) ? DEMO_STATE_MAIN_MENU : CurrentID; +} + +void destroy_game() +{ + FreeState(LvlState); + LvlState = NULL; +} + +/* + + GAMESTATE generation things - see comments in gamestate.h for more + information + +*/ +void create_new_game(GAMESTATE * game) +{ + game->id = newid; + game->init = GameInit; + game->update = GameUpdate; + game->draw = GameDraw; + game->deinit = DeInit; +} + +void create_continue_game(GAMESTATE * game) +{ + game->id = continueid; + game->init = ContinueInit; + game->update = GameUpdate; + game->draw = GameDraw; + game->deinit = DeInit; +} diff --git a/allegro/demos/skater/src/game.h b/allegro/demos/skater/src/game.h new file mode 100644 index 00000000..51254599 --- /dev/null +++ b/allegro/demos/skater/src/game.h @@ -0,0 +1,24 @@ +#ifndef __GAME_H__ +#define __GAME_H__ + +/* functions for Miran's framework */ +#include "gamestate.h" /* gamestate.h */ +#include "global.h" +extern void create_new_game(GAMESTATE * state); +extern void create_continue_game(GAMESTATE * game); +extern void destroy_game(void); + +extern char *load_game_resources(const char *data_path); +extern void unload_game_resources(void); + +/* global game state defines and variables */ +#define KEYFLAG_LEFT 0x01 +#define KEYFLAG_RIGHT 0x02 +#define KEYFLAG_JUMP 0x04 +#define KEYFLAG_JUMP_ISSUED 0x08 +#define KEYFLAG_JUMPING 0x10 +#define KEYFLAG_FLIP 0x20 +extern int KeyFlags; +extern double Pusher; + +#endif diff --git a/allegro/demos/skater/src/gamepad.c b/allegro/demos/skater/src/gamepad.c new file mode 100644 index 00000000..473a5c4d --- /dev/null +++ b/allegro/demos/skater/src/gamepad.c @@ -0,0 +1,174 @@ +#include <allegro5/allegro.h> +#include <string.h> +#include <stdio.h> +#include "global.h" +#include "gamepad.h" + +static int button_down = 0; +static float axis[3]; + +static void read_config(VCONTROLLER * this, const char *config_path) +{ + int i; + char tmp[64]; + + ALLEGRO_CONFIG *c = al_load_config_file(config_path); + if (!c) c = al_create_config(); + + for (i = 0; i < 3; i++) { + snprintf(tmp, sizeof(tmp), "button%d", i); + ((int *)(this->private_data))[i] = get_config_int(c, "GAMEPAD", tmp, 0); + + if (((((int *)(this->private_data))[i] >> 8) & 255) >= al_get_num_joysticks()) + ((int *)(this->private_data))[i] = 0; + } + + al_destroy_config(c); +} + + +static void write_config(VCONTROLLER * this, const char *config_path) +{ + int i; + char tmp[64]; + + ALLEGRO_CONFIG *c = al_load_config_file(config_path); + if (!c) c = al_create_config(); + + for (i = 0; i < 3; i++) { + snprintf(tmp, sizeof(tmp), "button%d", i); + set_config_int(c, "GAMEPAD", tmp, ((int *)(this->private_data))[i]); + } + + al_save_config_file(config_path, c); + al_destroy_config(c); +} + +static float threshold = 0.1; +static void poll(VCONTROLLER * this) +{ + //printf("%f %f %f\n", axis[0], axis[1], axis[2]); + float a = axis[0]; + if (screen_orientation == ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES) + a = axis[1]; + if (screen_orientation == ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES) + a = -axis[0]; + if (screen_orientation == ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES) + a = -axis[1]; + this->button[0] = a < -threshold; + this->button[1] = a > threshold; + this->button[2] = button_down; +} + + +static int calibrate_button(VCONTROLLER * this, int i) +{ + (void)this; + (void)i; +// FIXME +#if 0 + int stickc, axisc, joyc, buttonc; + + poll_joystick(); + joyc = al_get_num_joysticks(); + while (joyc--) { + /* check axes */ + stickc = joy[joyc].num_sticks; + while (stickc--) { + axisc = joy[joyc].stick[stickc].num_axis; + while (axisc--) { + if (joy[joyc].stick[stickc].axis[axisc].d1) { + ((int *)(this->private_data))[i] = + 4 | 2 | (joyc << 8) | (stickc << 16) | (axisc << 24); + return 1; + } + + if (joy[joyc].stick[stickc].axis[axisc].d2) { + ((int *)(this->private_data))[i] = + 4 | (joyc << 8) | (stickc << 16) | (axisc << 24); + return 1; + } + } + } + + /* check buttons */ + buttonc = joy[joyc].num_buttons; + while (buttonc--) { + if (joy[joyc].button[buttonc].b) { + ((int *)(this->private_data))[i] = + 4 | 1 | (joyc << 8) | (buttonc << 16); + return 1; + } + } + } +#endif + return 0; +} + +static const char *get_button_description(VCONTROLLER * this, int i) +{ + int *private_data = (int *)(this->private_data); + static char RetMessage[1024]; + + if (!private_data[i]) + return "Unassigned"; + + if (private_data[i] & 1) { + snprintf(RetMessage, sizeof(RetMessage), "Pad %d Button %d", + (private_data[i] >> 8) & 255, private_data[i] >> 16); + return RetMessage; + } else { + snprintf(RetMessage, sizeof(RetMessage), + "Pad %d Stick %d Axis %d (%s)", + (private_data[i] >> 8) & 255, + (private_data[i] >> 16) & 255, private_data[i] >> 24, + (private_data[i] & 2) ? "-" : "+"); + return RetMessage; + } +} + + +VCONTROLLER *create_gamepad_controller(const char *config_path) +{ + int i; + VCONTROLLER *ret = malloc(sizeof(VCONTROLLER)); + + ret->private_data = malloc(3 * sizeof(int)); + for (i = 0; i < 3; i++) { + ret->button[i] = 0; + ((int *)(ret->private_data))[i] = 0; + } + ret->poll = poll; + ret->calibrate_button = calibrate_button; + ret->get_button_description = get_button_description; + ret->read_config = read_config; + ret->write_config = write_config; + + read_config(ret, config_path); + + return ret; +} + +void gamepad_event(ALLEGRO_EVENT *event) +{ + switch (event->type) { + case ALLEGRO_EVENT_TOUCH_BEGIN: + button_down = true; + break; + + case ALLEGRO_EVENT_TOUCH_END: + button_down = false; + break; + + case ALLEGRO_EVENT_JOYSTICK_AXIS: + if (event->joystick.axis < 3) + axis[event->joystick.axis] = event->joystick.pos; + break; + } +} + + +bool gamepad_button(void) +{ + return button_down != 0; +} diff --git a/allegro/demos/skater/src/gamepad.h b/allegro/demos/skater/src/gamepad.h new file mode 100644 index 00000000..823223ed --- /dev/null +++ b/allegro/demos/skater/src/gamepad.h @@ -0,0 +1,11 @@ +#ifndef __DEMO_GAMEPAD_H__ +#define __DEMO_GAMEPAD_H__ + +#include <allegro5/allegro.h> +#include "vcontroller.h" + +VCONTROLLER *create_gamepad_controller(const char *config_path); +void gamepad_event(ALLEGRO_EVENT *event); +bool gamepad_button(void); + +#endif /* __DEMO_GAMEPAD_H__ */ diff --git a/allegro/demos/skater/src/gamestate.h b/allegro/demos/skater/src/gamestate.h new file mode 100644 index 00000000..d42a0657 --- /dev/null +++ b/allegro/demos/skater/src/gamestate.h @@ -0,0 +1,40 @@ +#ifndef __DEMO_GAMESTATE_H__ +#define __DEMO_GAMESTATE_H__ + +/* + Structure that defines one game state/screen/page. Each screen is + basically just a bunch of functions that initialize the state, run + a frame of logic and draw it to the screen. Each actual state must + fill in the struct by setting the function pointers to point to + the functions that implement that particular state. Note that not + all functions are mandatory, but most are. +*/ +typedef struct GAMESTATE GAMESTATE; + +struct GAMESTATE { + /* Supposed to return the ID of the state. Each stat must have a + unique ID. Not: all actual IDs are defined in defines.h. */ + int (*id) (void); + + /* Initializes the gamestate. This may be setting some static + variables to their default values, generating game data, + randomizing the playing field, etc. */ + void (*init) (void); + + /* Destroys the gamestate. Note that a particular gamestate may + set this pointr to NULL if there's nothing to destroy. */ + void (*deinit) (void); + + /* Runs one frame of logic, for example gather input, update game + physics, enemy AI, do collision detection, etc. Must return ID + of the next state. Most of the time this should be the ID of + the state itself, but for example when ESC is pressed this + should be the ID of the main menu or something along those lines. */ + int (*update) (void); + + /* Draws the state to the given bitmap. Note that the state should + assume that the target bitmap is acquired and cleared. */ + void (*draw) (void); +}; + +#endif /* __DEMO_GAMESTATE_H__ */ diff --git a/allegro/demos/skater/src/global.c b/allegro/demos/skater/src/global.c new file mode 100644 index 00000000..4c1df68a --- /dev/null +++ b/allegro/demos/skater/src/global.c @@ -0,0 +1,451 @@ +#include <allegro5/allegro.h> +#include <stdio.h> +#include <ctype.h> +#include "background_scroller.h" +#include "demodata.h" +#include "game.h" +#include "global.h" +#include "music.h" +#include "framework.h" + +/* Default values of some config varables */ +#ifdef ALLEGRO_IPHONE +int fullscreen = 1; +int controller_id = 1; +#else +int fullscreen = 0; +int controller_id = 0; +#endif +int bit_depth = 32; +int screen_width = 640; +int screen_height = 480; +int screen_orientation = ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES; +int window_width = 640; +int window_height = 480; +int screen_samples = 1; +int use_vsync = 0; +int logic_framerate = 100; +int max_frame_skip = 5; +int limit_framerate = 1; +int display_framerate = 1; +int reduce_cpu_usage = 1; +int sound_volume = 8; +int music_volume = 8; + +int shadow_offset = 2; + +VCONTROLLER *controller[2]; + +char config_path[DEMO_PATH_LENGTH]; +char data_path[DEMO_PATH_LENGTH]; +DATA_ENTRY *demo_data; + +ALLEGRO_DISPLAY *screen; + +char *GameError; + +int load_data(void); + +const char *demo_error(int id) +{ + switch (id) { + case DEMO_ERROR_ALLEGRO: + return "Allegro error"; + case DEMO_ERROR_GFX: + return "can't find suitable screen update driver"; + case DEMO_ERROR_MEMORY: + return "ran out of memory"; + case DEMO_ERROR_VIDEOMEMORY: + return "not enough VRAM"; + case DEMO_ERROR_TRIPLEBUFFER: + return "triple buffering not supported"; + case DEMO_ERROR_DATA: + return "can't load menu data"; + case DEMO_ERROR_GAMEDATA: + return GameError; + case DEMO_OK: + return "OK"; + default: + return "unknown"; + }; +} + + +int get_config_int(const ALLEGRO_CONFIG *cfg, const char *section, + const char *name, int def) +{ + const char *v = al_get_config_value(cfg, section, name); + + return (v) ? atoi(v) : def; +} + + +void set_config_int(ALLEGRO_CONFIG *cfg, const char *section, const char *name, + int val) +{ + char buf[32]; + + sprintf(buf, "%d", val); + al_set_config_value(cfg, section, name, buf); +} + + +/* read_config: + * Load settings from the configuration file, providing default values + */ +void read_global_config(const char *config) +{ + ALLEGRO_CONFIG *c = al_load_config_file(config); + if (!c) c = al_create_config(); + + fullscreen = get_config_int(c, "GFX", "fullscreen", fullscreen); + bit_depth = get_config_int(c, "GFX", "bit_depth", bit_depth); + screen_width = get_config_int(c, "GFX", "screen_width", screen_width); + screen_height = get_config_int(c, "GFX", "screen_height", screen_height); + window_width = get_config_int(c, "GFX", "window_width", window_height); + window_height = get_config_int(c, "GFX", "window_height", screen_height); + screen_samples = get_config_int(c, "GFX", "samples", screen_samples); + use_vsync = get_config_int(c, "GFX", "vsync", use_vsync); + + logic_framerate = + get_config_int(c, "TIMING", "logic_framerate", logic_framerate); + limit_framerate = + get_config_int(c, "TIMING", "limit_framerate", limit_framerate); + max_frame_skip = + get_config_int(c, "TIMING", "max_frame_skip", max_frame_skip); + display_framerate = + get_config_int(c, "TIMING", "display_framerate", display_framerate); + reduce_cpu_usage = + get_config_int(c, "TIMING", "reduce_cpu_usage", reduce_cpu_usage); + + sound_volume = get_config_int(c, "SOUND", "sound_volume", sound_volume); + music_volume = get_config_int(c, "SOUND", "music_volume", music_volume); + + set_sound_volume(sound_volume / 10.0); + set_music_volume(music_volume / 10.0); + + controller_id = get_config_int(c, "CONTROLS", "controller_id", controller_id); + + al_destroy_config(c); +} + + +void write_global_config(const char *config) +{ + ALLEGRO_CONFIG *c = al_load_config_file(config); + if (!c) c = al_create_config(); + + set_config_int(c, "GFX", "fullscreen", fullscreen); + set_config_int(c, "GFX", "bit_depth", bit_depth); + set_config_int(c, "GFX", "screen_width", screen_width); + set_config_int(c, "GFX", "screen_height", screen_height); + set_config_int(c, "GFX", "window_width", window_width); + set_config_int(c, "GFX", "window_height", window_height); + set_config_int(c, "GFX", "samples", screen_samples); + set_config_int(c, "GFX", "vsync", use_vsync); + + set_config_int(c, "TIMING", "logic_framerate", logic_framerate); + set_config_int(c, "TIMING", "max_frame_skip", max_frame_skip); + set_config_int(c, "TIMING", "limit_framerate", limit_framerate); + set_config_int(c, "TIMING", "display_framerate", display_framerate); + set_config_int(c, "TIMING", "reduce_cpu_usage", reduce_cpu_usage); + + set_config_int(c, "SOUND", "sound_volume", sound_volume); + set_config_int(c, "SOUND", "music_volume", music_volume); + + set_config_int(c, "CONTROLS", "controller_id", controller_id); + + al_save_config_file(config, c); + al_destroy_config(c); +} + +static bool load(DATA_ENTRY *d, int id, char const *type, char const *path, + char const *subfolder, char const *name, char const *ext, int size) +{ + static char spath[1024]; + sprintf(spath, "%s/%s/%s.%s", path, subfolder, name, ext); + printf("Loading %s...\n", spath); + if (!strcmp(type, "font")) d[id].dat = al_load_font(spath, size, 0); + if (!strcmp(type, "bitmap")) d[id].dat = al_load_bitmap(spath); + if (!strcmp(type, "sample")) d[id].dat = al_load_sample(spath); + if (!strcmp(type, "music")) d[id].dat = al_load_audio_stream(spath, 2, 4096); + if (d[id].dat == NULL) { + printf("Failed loading %s.\n", name); + } + d[id].type = type; + d[id].path = strdup(path); + d[id].subfolder = strdup(subfolder); + d[id].name = strdup(name); + d[id].ext = strdup(ext); + d[id].size = size; + return d[id].dat != NULL; +} + +int change_gfx_mode(void) +{ + int ret = DEMO_OK; + int flags = 0; + + /* Select appropriate (fullscreen or windowed) gfx mode driver. */ + if (fullscreen == 0) { + flags |= ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE; + screen_width = window_width; + screen_height = window_height; + } else if (fullscreen == 1) { + flags |= ALLEGRO_FULLSCREEN_WINDOW; + } else { + flags |= ALLEGRO_FULLSCREEN; + } + + if (screen) { + al_destroy_display(screen); + } + + al_set_new_display_flags(flags); + + // May be a good idea, but need to add a border to textures for it. + // al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + + if (screen_samples > 1) { + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); + al_set_new_display_option(ALLEGRO_SAMPLES, screen_samples, ALLEGRO_SUGGEST); + } + else { + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 0, ALLEGRO_SUGGEST); + al_set_new_display_option(ALLEGRO_SAMPLES, 0, ALLEGRO_SUGGEST); + } + + al_set_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, + ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE, ALLEGRO_SUGGEST); + + /* Attempt to set the selected colour depth and gfx mode. */ + screen = al_create_display(screen_width, screen_height); + if (!screen) { + return DEMO_ERROR_ALLEGRO; + } + al_set_window_constraints(screen, 320, 320, 0, 0); + + screen_width = al_get_display_width(screen); + screen_height = al_get_display_height(screen); + screen_orientation = ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES; + + al_register_event_source(event_queue, al_get_display_event_source(screen)); + + /* blank display now, before doing any more complicated stuff */ + al_clear_to_color(al_map_rgb(0, 0, 0)); + + /* Attempt to load game data. */ + ret = load_data(); + + /* If loading was successful, initialize the background scroller module. */ + if (ret == DEMO_OK) { + init_background(); + } + + return ret; +} + +static DATA_ENTRY *load_data_entries(char const *path) +{ + DATA_ENTRY *d = calloc(DEMO_DATA_COUNT + 1, sizeof *d); + load(d, DEMO_BMP_BACK, "bitmap", path, "menu", "back", "png", 0); + load(d, DEMO_FONT, "font", path, "menu", "cancunsmall", "png", 0); + load(d, DEMO_FONT_LOGO, "font", path, "menu", "logofont", "png", 0); + load(d, DEMO_MIDI_INGAME, "music", path, "menu", "skate2", "ogg", 0); + load(d, DEMO_MIDI_INTRO, "music", path, "menu", "intro_music", "ogg", 0); + load(d, DEMO_MIDI_MENU, "music", path, "menu", "menu_music", "ogg", 0); + load(d, DEMO_MIDI_SUCCESS, "music", path, "menu", "endoflevel", "ogg", 0); + load(d, DEMO_SAMPLE_BUTTON, "sample", path, "menu", "button", "ogg", 0); + load(d, DEMO_SAMPLE_WELCOME, "sample", path, "menu", "welcome", "ogg", 0); + load(d, DEMO_SAMPLE_SKATING, "sample", path, "audio", "skating", "ogg", 0); + load(d, DEMO_SAMPLE_WAVE, "sample", path, "audio", "wave", "ogg", 0); + load(d, DEMO_SAMPLE_DING, "sample", path, "audio", "ding", "ogg", 0); + load(d, DEMO_SAMPLE_DOOROPEN, "sample", path, "audio", "dooropen", "ogg", 0); + load(d, DEMO_SAMPLE_POP, "sample", path, "audio", "pop", "ogg", 0); + + load(d, DEMO_BMP_BANANAS, "bitmap", path, "graphics", "bananas", "png", 0); + load(d, DEMO_BMP_CHERRIES, "bitmap", path, "graphics", "cherries", "png", 0); + load(d, DEMO_BMP_CLOUD, "bitmap", path, "graphics", "cloud", "png", 0); + load(d, DEMO_BMP_DOOROPEN, "bitmap", path, "graphics", "dooropen", "png", 0); + load(d, DEMO_BMP_DOORSHUT, "bitmap", path, "graphics", "doorshut", "png", 0); + load(d, DEMO_BMP_EXITSIGN, "bitmap", path, "graphics", "exitsign", "png", 0); + load(d, DEMO_BMP_GRASS, "bitmap", path, "graphics", "grass", "png", 0); + load(d, DEMO_BMP_ICECREAM, "bitmap", path, "graphics", "icecream", "png", 0); + load(d, DEMO_BMP_ICE, "bitmap", path, "graphics", "ice", "png", 0); + load(d, DEMO_BMP_ICETIP, "bitmap", path, "graphics", "icetip", "png", 0); + load(d, DEMO_BMP_ORANGE, "bitmap", path, "graphics", "orange", "png", 0); + load(d, DEMO_BMP_SKATEFAST, "bitmap", path, "graphics", "skatefast", "png", 0); + load(d, DEMO_BMP_SKATEMED, "bitmap", path, "graphics", "skatemed", "png", 0); + load(d, DEMO_BMP_SKATER1, "bitmap", path, "graphics", "skater1", "png", 0); + load(d, DEMO_BMP_SKATER2, "bitmap", path, "graphics", "skater2", "png", 0); + load(d, DEMO_BMP_SKATER3, "bitmap", path, "graphics", "skater3", "png", 0); + load(d, DEMO_BMP_SKATER4, "bitmap", path, "graphics", "skater4", "png", 0); + load(d, DEMO_BMP_SKATESLOW, "bitmap", path, "graphics", "skateslow", "png", 0); + load(d, DEMO_BMP_SOIL, "bitmap", path, "graphics", "soil", "png", 0); + load(d, DEMO_BMP_SWEET, "bitmap", path, "graphics", "sweet", "png", 0); + load(d, DEMO_BMP_WATER, "bitmap", path, "graphics", "water", "png", 0); + + return d; +} + +void unload_data_entries(DATA_ENTRY *data) +{ + while (data && data->dat) { + if (!strcmp(data->type, "bitmap")) al_destroy_bitmap(data->dat); + if (!strcmp(data->type, "font")) al_destroy_font(data->dat); + if (!strcmp(data->type, "sample")) al_destroy_sample(data->dat); + if (!strcmp(data->type, "music")) al_destroy_audio_stream(data->dat); + data++; + } +} + +int load_data(void) +{ + if (demo_data) + return DEMO_OK; + + /* Load the data for the game menus. */ + demo_data = load_data_entries(data_path); + if (demo_data == 0) { + return DEMO_ERROR_DATA; + } + + /* Load other game resources. */ + if ((GameError = load_game_resources(data_path))) + return DEMO_ERROR_GAMEDATA; + + return DEMO_OK; +} + + +void unload_data(void) +{ + if (demo_data != 0) { + unload_data_entries(demo_data); + unload_game_resources(); + demo_data = 0; + } +} + + +void demo_textout(const ALLEGRO_FONT *f, const char *s, int x, int y, + ALLEGRO_COLOR color) +{ + demo_textprintf(f, x, y, color, "%s", s); +} + + +void demo_textout_right(const ALLEGRO_FONT *f, const char *s, int x, int y, + ALLEGRO_COLOR color) +{ + demo_textprintf_right(f, x, y, color, "%s", s); +} + + +void demo_textout_centre(const ALLEGRO_FONT *f, const char *s, int x, int y, + ALLEGRO_COLOR color) +{ + demo_textprintf_centre(f, x, y, color, "%s", s); +} + + +void demo_textprintf_centre(const ALLEGRO_FONT *font, int x, int y, + ALLEGRO_COLOR col, const char *format, ...) +{ + char buf[512]; + + va_list ap; + + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + demo_textprintf_ex(font, x, y, col, 2, "%s", buf); +} + + +void demo_textprintf_right(const ALLEGRO_FONT *font, int x, int y, + ALLEGRO_COLOR col, const char *format, ...) +{ + char buf[512]; + + va_list ap; + + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + demo_textprintf_ex(font, x, y, col, 1, "%s", buf); +} + + +void demo_textprintf(const ALLEGRO_FONT *font, int x, int y, + ALLEGRO_COLOR col, const char *format, ...) +{ + char buf[512]; + + va_list ap; + + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + demo_textprintf_ex(font, x, y, col, 0, "%s", buf); +} + +void demo_textprintf_ex(const ALLEGRO_FONT *font, int x, int y, + ALLEGRO_COLOR col, int align, const char *format, ...) +{ + char buf[512]; + + va_list ap; + + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + switch (align) { + case 0: + al_draw_textf(font, col, x, y, ALLEGRO_ALIGN_LEFT, "%s", buf); + break; + case 1: + al_draw_textf(font, col, x, y, ALLEGRO_ALIGN_RIGHT, "%s", buf); + break; + case 2: + al_draw_textf(font, col, x, y, ALLEGRO_ALIGN_CENTRE, "%s", buf); + break; + }; + +} + + +void shadow_textprintf(ALLEGRO_FONT *font, int x, int y, + ALLEGRO_COLOR col, int align, const char *format, ...) +{ + char buf[512]; + + va_list ap; + + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + demo_textprintf_ex(font, x + shadow_offset, y + shadow_offset, al_map_rgba(0, 0, 0, 128), + align, "%s", buf); + demo_textprintf_ex(font, x, y, col, align, "%s", buf); +} + +int my_stricmp(const char *s1, const char *s2) +{ + char c1, c2; + int v; + + while(1) { + c1 = *s1++; + c2 = *s2++; + v = tolower(c1) - tolower(c2); + if (v != 0 || c1 == 0 || c2 == 0) break; + } + + return v; +} diff --git a/allegro/demos/skater/src/global.h b/allegro/demos/skater/src/global.h new file mode 100644 index 00000000..71d06453 --- /dev/null +++ b/allegro/demos/skater/src/global.h @@ -0,0 +1,210 @@ +#ifndef __DEMO_GLOBAL_H__ +#define __DEMO_GLOBAL_H__ + +#define mouse_event WIN32_mouse_event +#include <stdio.h> +#include <math.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_acodec.h> +#include <allegro5/allegro_audio.h> +#include <allegro5/allegro_font.h> +#include <allegro5/allegro_image.h> +#include <allegro5/allegro_primitives.h> +#undef mouse_event + +#include "defines.h" +#include "keyboard.h" + +#ifdef ALLEGRO_MSVC + #define snprintf _snprintf + #define vsnprintf _vsnprintf +#endif + +/* Some configuration settings. All of these variables are recorded + in the configuration file. */ +extern int fullscreen; /* selects fullscreen or windowed mode */ +extern int bit_depth; /* screen colour depth (15/16/24/32) + Note that this is ignored when in windowed + mode and the desktop colour depth can be + retrieved. */ +extern int screen_width; /* horizontal screen resolution */ +extern int screen_height; /* vertical screen resolution */ +extern int screen_orientation; +extern int window_width; /* remember last window width */ +extern int window_height; /* remember last window height */ +extern int screen_samples; /* super-sampling */ +extern int use_vsync; /* enables/disables vsync-ing */ +extern int logic_framerate; /* target logic framerate */ +extern int max_frame_skip; /* max number of skipped logic frames if + the CPU isn't fast enough */ +extern int limit_framerate; /* enables/disables unlimited framerate */ +extern int display_framerate; /* enables/disables FPS counter */ +extern int reduce_cpu_usage; /* enables/disables power saving by giving + up the CPU when not needed */ +extern int sound_volume; /* sound volume in range [0,10] */ +extern int music_volume; /* music volume in range [0,10] */ +extern int controller_id; /* ID of the selected input controller */ + +/* Offset of the text shadow in game menus as number of pixels. */ +extern int shadow_offset; + +/* Array of available input controllers. New controllers may be added + here in the future. */ +extern VCONTROLLER *controller[2]; + +/* Absolute path of the config file. */ +extern char config_path[DEMO_PATH_LENGTH]; + +/* Absolute path of the datafile. */ +extern char data_path[DEMO_PATH_LENGTH]; + +/* The main menu font (monochrome). */ +#define demo_font ((ALLEGRO_FONT *)demo_data[DEMO_FONT].dat) + +/* The big title font (coloured). */ +#define demo_font_logo ((ALLEGRO_FONT *)demo_data[DEMO_FONT_LOGO].dat) + +/* Font made of default allegro font (monochrome). */ +#define plain_font demo_font + +extern ALLEGRO_DISPLAY *screen; + + +/* + Converts an error code to an error description. + + Parameters: + int id - error code (see defines.h) + + Returns: + String containing the description of the error code. +*/ +extern const char *demo_error(int id); + + +/* + Switches the gfx mode to settings defined by the global variables + declared in this file and reloads all data if necessary. + + Parameters: + none + + Returns: + Error code: DEMO_OK on succes, otherwise the code of the error + that caused the function to fail. See defines.h for a list of + possible error codes. +*/ +extern int change_gfx_mode(void); + + +/* + Reads global configuration settings from a config file. + + Parameters: + char *config - Path to the config file. + + Returns: + nothing +*/ +extern void read_global_config(const char *config); + + +/* + Writes global configuration settings to a config file. + + Parameters: + char *config - Path to the config file. + + Returns: + nothing +*/ +extern void write_global_config(const char *config); + + +/* + Unloads all game data. Required before changing gfx mode and before + shutting down the framework. + + Parameters: + none + + Returns: + nothing +*/ +extern void unload_data(void); + + +/* + Facade for text output functions. Implements a common interface for text + output using Allegro's or AllegroGL's text output functions. + Text alignment is selected with a parameter. + + Parameters: + ALLEGRO_BITMAP *canvas, int x, int y, int col and char *format have + exactly the same meaning as in the equivalent Allegro built-in + text output functions. + FONT *font can be either plain Allegro font or a font converted with + AllegroGL's allegro_gl_convert_allegro_font_ex(). + int align - defines alignemnt: 0 = left, 1 = right, 2 = centre + + Returns: + nothing +*/ +extern void demo_textprintf_ex(const ALLEGRO_FONT * font, int x, int y, + ALLEGRO_COLOR col, int align, const char *format, ...); +extern void demo_textprintf(const ALLEGRO_FONT * font, int x, int y, + ALLEGRO_COLOR col, const char *format, ...); +extern void demo_textprintf_right(const ALLEGRO_FONT * font, int x, int y, + ALLEGRO_COLOR col, const char *format, ...); +extern void demo_textprintf_centre(const ALLEGRO_FONT * font, int x, int y, + ALLEGRO_COLOR col, const char *format, ...); +extern void demo_textout(const ALLEGRO_FONT *f, const char *s, int x, + int y, ALLEGRO_COLOR color); +extern void demo_textout_right(const ALLEGRO_FONT *f, const char *s, + int x, int y, ALLEGRO_COLOR color); +extern void demo_textout_centre(const ALLEGRO_FONT *f, const char *s, + int x, int y, ALLEGRO_COLOR color); + +/* + Custom text output function. Similar to the Allegro's built-in functions + except that text alignment is selected with a parameter and the text is + printed with a black shadow. Offset of the shadow is defined with the + shadow_offset variable. + + Parameters: + ALLEGRO_BITMAP *canvas, FONT *font, int x, int y, int col and char *text have + exactly the same meaning as in the equivalent Allegro built-in + text output functions. + int align - defines alignemnt: 0 = left, 1 = right, 2 = centre + + Returns: + nothing +*/ +extern void shadow_textprintf(ALLEGRO_FONT * font, int x, int y, + ALLEGRO_COLOR col, int align, const char *text, ...); + +typedef struct DATA_ENTRY { + int id; + char const *type; + char *path; + char *subfolder; + char *name; + char *ext; + int size; + void *dat; +} DATA_ENTRY; + +extern DATA_ENTRY *demo_data; + +void unload_data_entries(DATA_ENTRY *data); + +int get_config_int(const ALLEGRO_CONFIG *cfg, const char *section, + const char *name, int def); + +void set_config_int(ALLEGRO_CONFIG *cfg, const char *section, const char *name, + int val); + +int my_stricmp(const char *s1, const char *s2); + + +#endif /* __DEMO_GLOBAL_H__ */ diff --git a/allegro/demos/skater/src/intro.c b/allegro/demos/skater/src/intro.c new file mode 100644 index 00000000..e1d76a3d --- /dev/null +++ b/allegro/demos/skater/src/intro.c @@ -0,0 +1,105 @@ +#include "global.h" +#include "menus.h" +#include "defines.h" +#include "music.h" +#include "mouse.h" + + +static int _id = DEMO_STATE_INTRO; +static double duration; +static double progress; +static int already_played_midi; + +static int id(void) +{ + return _id; +} + + +static void init(void) +{ + duration = 4.0f; + progress = 0.0f; + already_played_midi = 0; +} + + +static int update(void) +{ + progress += 1.0f / logic_framerate; + + if (progress >= duration) { + return DEMO_STATE_MAIN_MENU; + } + + if (key_pressed(ALLEGRO_KEY_ESCAPE)) return DEMO_STATE_MAIN_MENU; + if (key_pressed(ALLEGRO_KEY_SPACE)) return DEMO_STATE_MAIN_MENU; + if (key_pressed(ALLEGRO_KEY_ENTER)) return DEMO_STATE_MAIN_MENU; + if (mouse_button_pressed(1)) return DEMO_STATE_MAIN_MENU; + + return id(); +} + + +static void draw(void) +{ + int x, y, offx, offy; + float c = 1; + static char logo_text1[] = "Allegro"; + static char logo_text2[] = ""; + /* XXX commented out because the font doesn't contain the characters for + * anything other than "Allegro 4.2" + */ + /* static char logo_text2[] = "5.0"; */ + + if (progress < 0.5f) { + c = progress / 0.5f; + al_clear_to_color(al_map_rgb_f(c, c, c)); + } else { + if (!already_played_midi) { + play_music(DEMO_MIDI_INTRO, 0); + already_played_midi = 1; + } + + c = 1; + al_clear_to_color(al_map_rgb_f(c, c, c)); + + x = screen_width / 2; + y = screen_height / 2 - 3 * al_get_font_line_height(demo_font_logo) / 2; + + offx = 0; + if (progress < 1.0f) { + offx = + (int)(al_get_text_width(demo_font_logo, logo_text1) * + (1.0f - 2.0f * (progress - 0.5f))); + } + + demo_textprintf_centre(demo_font_logo, x + 6 - offx, + y + 5, al_map_rgba_f(0.125, 0.125, 0.125, 0.25), logo_text1); + demo_textprintf_centre(demo_font_logo, x - offx, y, + al_map_rgba_f(1, 1, 1, 1), logo_text1); + + if (progress >= 1.5f) { + y += 3 * al_get_font_line_height(demo_font_logo) / 2; + offy = 0; + if (progress < 2.0f) { + offy = (int)((screen_height - y) * (1.0f - 2.0f * (progress - 1.5f))); + } + + demo_textprintf_centre(demo_font_logo, x + 6, + y + 5 + offy, al_map_rgba_f(0.125, 0.125, 0.125, 0.25), + logo_text2); + demo_textprintf_centre(demo_font_logo, x, y + offy, + al_map_rgba_f(1, 1, 1, 1), logo_text2); + } + } +} + + +void create_intro(GAMESTATE * state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} diff --git a/allegro/demos/skater/src/keyboard.c b/allegro/demos/skater/src/keyboard.c new file mode 100644 index 00000000..6b97b501 --- /dev/null +++ b/allegro/demos/skater/src/keyboard.c @@ -0,0 +1,180 @@ +#include <allegro5/allegro.h> +#include <stdio.h> +#include "global.h" +#include "keyboard.h" + +#define KEYBUF_SIZE 16 + +/* + * bit 0: key is down + * bit 1: key was pressed + * bit 2: key was released + */ +static int key_array[ALLEGRO_KEY_MAX]; +static int unicode_array[KEYBUF_SIZE]; +static int unicode_count; + +bool key_down(int k) +{ + return key_array[k] & 1; +} + +bool key_pressed(int k) +{ + return key_array[k] & 2; +} + +int unicode_char(bool remove) +{ + int u; + if (unicode_count == 0) return 0; + u = unicode_array[0]; + if (remove) { + memmove(unicode_array, unicode_array + 1, + (KEYBUF_SIZE - 1) * sizeof(int)); + } + return u; +} + +void keyboard_event(ALLEGRO_EVENT *event) +{ + switch (event->type) { + case ALLEGRO_EVENT_KEY_DOWN: + key_array[event->keyboard.keycode] |= (1 << 0); + key_array[event->keyboard.keycode] |= (1 << 1); + break; + + case ALLEGRO_EVENT_KEY_CHAR: + if (event->keyboard.unichar && unicode_count < KEYBUF_SIZE) { + unicode_array[unicode_count++] = event->keyboard.unichar; + } + break; + + case ALLEGRO_EVENT_KEY_UP: + key_array[event->keyboard.keycode] &= ~(1 << 0); + key_array[event->keyboard.keycode] |= (1 << 2); + break; + } +} + +void keyboard_tick(void) +{ + /* clear pressed/released bits */ + int i; + for (i = 0; i < ALLEGRO_KEY_MAX; i++) { + key_array[i] &= ~(1 << 1); + key_array[i] &= ~(1 << 2); + } + + unicode_count = 0; +} + +static void read_config(VCONTROLLER * this, const char *config_path) +{ + int i; + char tmp[64]; + int def[] = { + ALLEGRO_KEY_LEFT, + ALLEGRO_KEY_RIGHT, + ALLEGRO_KEY_SPACE + }; + + ALLEGRO_CONFIG *c = al_load_config_file(config_path); + if (!c) c = al_create_config(); + + for (i = 0; i < 3; i++) { + snprintf(tmp, sizeof(tmp), "button%d", i); + ((int *)(this->private_data))[i] = + get_config_int(c, "KEYBOARD", tmp, def[i]); + } + + al_destroy_config(c); +} + + + +static void write_config(VCONTROLLER * this, const char *config_path) +{ + int i; + char tmp[64]; + + ALLEGRO_CONFIG *c = al_load_config_file(config_path); + if (!c) c = al_create_config(); + + for (i = 0; i < 3; i++) { + snprintf(tmp, sizeof(tmp), "button%d", i); + set_config_int(c, "KEYBOARD", tmp, ((int *)(this->private_data))[i]); + } + + al_save_config_file(config_path, c); + al_destroy_config(c); +} + + + +static void poll(VCONTROLLER * this) +{ + int i; + + int *private_data = (int *)(this->private_data); + + for (i = 0; i < 3; i++) { + if (key_down(private_data[i])) { + this->button[i] = 1; + } else { + this->button[i] = 0; + } + } +} + + + +static int calibrate_button(VCONTROLLER * this, int i) +{ + int c; + + if (key_down(ALLEGRO_KEY_ESCAPE)) { + return 0; + } + + for (c = 1; c < ALLEGRO_KEY_MAX; c++) { + if (key_pressed(c)) { + ((int *)(this->private_data))[i] = c; + return 1; + } + } + + return 0; +} + + + +static const char *get_button_description(VCONTROLLER * this, int i) +{ + int *private_data = (int *)(this->private_data); + + return al_keycode_to_name(private_data[i]); +} + + + +VCONTROLLER *create_keyboard_controller(const char *config_path) +{ + int i; + VCONTROLLER *ret = malloc(sizeof(VCONTROLLER)); + + ret->private_data = malloc(3 * sizeof(int)); + for (i = 0; i < 3; i++) { + ret->button[i] = 0; + ((int *)(ret->private_data))[i] = 0; + } + ret->poll = poll; + ret->calibrate_button = calibrate_button; + ret->get_button_description = get_button_description; + ret->read_config = read_config; + ret->write_config = write_config; + + read_config(ret, config_path); + + return ret; +} diff --git a/allegro/demos/skater/src/keyboard.h b/allegro/demos/skater/src/keyboard.h new file mode 100644 index 00000000..b81a5f4e --- /dev/null +++ b/allegro/demos/skater/src/keyboard.h @@ -0,0 +1,15 @@ +#ifndef __DEMO_KEYBOARD_H__ +#define __DEMO_KEYBOARD_H__ + +#include <allegro5/allegro.h> +#include "vcontroller.h" + +VCONTROLLER *create_keyboard_controller(const char *config_path); + +bool key_down(int k); +bool key_pressed(int k); +void keyboard_event(ALLEGRO_EVENT *event); +void keyboard_tick(void); +int unicode_char(bool remove); + +#endif /* __DEMO_KEYBOARD_H__ */ diff --git a/allegro/demos/skater/src/level.c b/allegro/demos/skater/src/level.c new file mode 100644 index 00000000..f239f8c5 --- /dev/null +++ b/allegro/demos/skater/src/level.c @@ -0,0 +1,534 @@ +/* + + Level.c contains the code for loading levels (which are in an ASCII format + and parsed with a 'reasonable' degree of intelligence) and preprocessing + them for game use. + + It can also produce a condensed version of the current level state + (suitable for saving and loading of games, used elsewhere to retain state + when display resolution is changed) and includes the main hook for level + drawing - although this is passed on to quadtree.c as determining visibility + is really a quadtree function. + + Note that the graphical parts of the level are scaled for the current + display resolution but the collision / physics parts are never scaled. This + is so that game behaviour is identical regardless of the display resolution + and so that if the user changes resolution during a game they don't break + their game state. The rounding error adjustment algorithms (see Physics.c) + would not be very likely to survive a scaling of velocity and position and + the player would likely fall through any platform they may be resting on. + +*/ + +#include <allegro5/allegro.h> +#include <math.h> +#include <string.h> +#include "defines.h" +#include "game.h" +#include "level.h" +#include "level_alloc.h" +#include "level_file.h" +#include "token.h" + +/* + + Drawing stuff first. Framec is a count of the current frame number, which + is a required parameter to the drawing stuff in QuadTree.c - see that file + for comments on that. + + DispBox is the rectangle that the user expects to be displayed. Note that + (x, y) are parsed in the same units as the player moves so are scaled here + into screen co-ordinates. + +*/ + +int framec = 0; +struct BoundingBox DispBox; + +void DrawLevelBackground(struct Level *lev, double *pos) +{ + float w, h; + if (!lev) + return; + h = 480.0; + w = screen_width * 480 / screen_height; + framec++; + DispBox.TL.Pos[0] = pos[0] - w / 2; + DispBox.TL.Pos[1] = pos[1] - h / 2; + DispBox.BR.Pos[0] = DispBox.TL.Pos[0] + w; + DispBox.BR.Pos[1] = DispBox.TL.Pos[1] + h; + + BeginQuadTreeDraw(lev, &lev->DisplayTree, &DispBox, framec); +} + +void DrawLevelForeground(struct Level *lev) +{ + if (!lev) + return; + EndQuadTreeDraw(lev, &DispBox, framec); +} + + +ALLEGRO_BITMAP *ObtainBitmap(const char *name) +{ + DATA_ENTRY *data = demo_data; + while (data && data->name) { + if (!strcmp(data->type, "bitmap") && + !strcmp(data->name, name)) return data->dat; + data++; + } + return NULL; +} + +ALLEGRO_SAMPLE *ObtainSample(const char *name) +{ + DATA_ENTRY *data = demo_data; + while (data && data->name) { + if (!strcmp(data->type, "sample") && + !strcmp(data->name, name)) return data->dat; + data++; + } + return NULL; +} + +/* + + A couple of very standard functions - min(a,b) returns the minimum of a and + b, max(a,b) returns the maximum of a and b. Both have all the usual + disadvantages of preprocessor macros (e.g. consider what will happen with + min(a, b++)), but for this code it doesn't matter in the slightest. + +*/ + +#undef min +#undef max +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) + +/* + + The FreeLevel function and associated macros. Just runs through all the data + structures freeing anything that may have been allocated. Not really worthy + of extensive comment. + + This function does the freeing for all level related struct types - there is + no set of C++ equivalent deconstructors + +*/ +#define FreeList(name, type, sp) \ + while(lvl->name)\ + {\ + Next = (void *)lvl->name->Next;\ + sp(lvl->name);\ + free(lvl->name);\ + lvl->name = (struct type *)Next;\ + } + +#define NoAction(v) + +void FreeLevel(struct Level *lvl) +{ + void *Next; + + if (!lvl) + return; + + /* easy things first */ + FreeQuadTree(&lvl->DisplayTree); + FreeQuadTree(&lvl->CollisionTree); + + /* free the resource lists */ + FreeList(AllTris, Triangle, NoAction); + FreeList(AllEdges, Edge, NoAction); + + FreeList(AllMats, Material, NoAction); + FreeList(AllObjectTypes, ObjectType, NoAction); + + FreeList(AllVerts, Vertex, NoAction); + FreeList(AllObjects, Object, NoAction); + + /* finally, free the level structure itself */ + FreeState(lvl->InitialState); + free(lvl); +} + +/* 01234567890123456789012345678901234567890123456789012345678901234567890123456789 */ +static int CalcIntersection(struct Edge *e1, struct Edge *e2, double *Inter, + int radius) +{ + double d1, d2; + + d1 = + (e1->EndPoints[0]->Pos[0] + radius * e1->a) * e2->a + + (e1->EndPoints[0]->Pos[1] + radius * e1->b) * e2->b + e2->c; + d2 = + (e1->EndPoints[1]->Pos[0] + radius * e1->a) * e2->a + + (e1->EndPoints[1]->Pos[1] + radius * e1->b) * e2->b + e2->c; + + if (!(d1 - d2)) + return false; + + d1 /= (d1 - d2); + Inter[0] = + e1->EndPoints[0]->Pos[0] + radius * e1->a + + d1 * (e1->EndPoints[1]->Pos[0] - e1->EndPoints[0]->Pos[0]); + Inter[1] = + e1->EndPoints[0]->Pos[1] + radius * e1->b + + d1 * (e1->EndPoints[1]->Pos[1] - e1->EndPoints[0]->Pos[1]); + + return true; +} + +static void FixVerts(struct Level *NewLev, int radius) +{ + struct Vertex *v = NewLev->AllVerts; + + while (v) { + if (v->Edges[1]) { + /* position normal at intersection of two connected edges */ + if (!CalcIntersection(v->Edges[0], v->Edges[1], v->Normal, radius)) { + v->Normal[0] = v->Pos[0] + v->Edges[0]->a * radius; + v->Normal[1] = v->Pos[1] + v->Edges[0]->b * radius; + } + } else if (v->Edges[0]) { + /* position normal as a straight projection from v->Edges[0] */ + double Direction = -1.0f; + + if (v->Edges[0]->EndPoints[0] == v) + Direction = 1.0f; + + v->Normal[0] = + v->Pos[0] + v->Edges[0]->a * radius + + radius * Direction * v->Edges[0]->b; + v->Normal[1] = + v->Pos[1] + v->Edges[0]->b * radius - + radius * Direction * v->Edges[0]->a; + } + + v = v->Next; + } +} + +static int FixEdges(struct Level *NewLev, int radius) +{ + struct Edge **e = &NewLev->AllEdges; + int NotFinished = false, Failed; + struct Edge OldEdge, *EdgePtr; + + (void)radius; + + while (*e) { + /* check whether edge is now the wrong way around, and if so set NotFinished */ + OldEdge = **e; + Failed = + GetNormal(*e, (*e)->EndPoints[0]->Normal, + (*e)->EndPoints[1]->Normal); + + if (Failed || (((*e)->a * OldEdge.a + (*e)->b * OldEdge.b) < 0)) { + NotFinished = true; + + /* fix edge pointers */ + EdgePtr = + ((*e)->EndPoints[1]->Edges[0] == + (*e)) ? (*e)->EndPoints[1]->Edges[1] : (*e)->EndPoints[1]-> + Edges[0]; + + if ((*e)->EndPoints[0]->Edges[0] == (*e)) { + if (!EdgePtr) { + (*e)->EndPoints[0]->Edges[0] = (*e)->EndPoints[0]->Edges[1]; + (*e)->EndPoints[0]->Edges[1] = NULL; + } else + (*e)->EndPoints[0]->Edges[0] = EdgePtr; + } else + (*e)->EndPoints[0]->Edges[1] = EdgePtr; + + if (EdgePtr->EndPoints[0] == (*e)->EndPoints[1]) + EdgePtr->EndPoints[0] = (*e)->EndPoints[0]; + else + EdgePtr->EndPoints[1] = (*e)->EndPoints[0]; + + (*e)->EndPoints[1]->Edges[0] = (*e)->EndPoints[1]->Edges[1] = NULL; + + /* unlink & free */ + EdgePtr = *e; + (*e) = (*e)->Next; + free((void *)EdgePtr); + + if (!(*e)) + break; + } + + e = &((*e)->Next); + } + + return NotFinished; +} + +/* + + AddEdges calculates the axis aligned bounding boxes of all + edges and inserts them into the collision tree + +*/ +static void AddEdges(struct Level *NewLev) +{ + struct Edge *e = NewLev->AllEdges; + + while (e) { + /* calculate AABB for this edge */ + e->Bounder.TL.Pos[0] = + min(e->EndPoints[0]->Normal[0], e->EndPoints[1]->Normal[0]) - 0.05f; + e->Bounder.TL.Pos[1] = + min(e->EndPoints[0]->Normal[1], e->EndPoints[1]->Normal[1]) - 0.05f; + + e->Bounder.BR.Pos[0] = + max(e->EndPoints[0]->Normal[0], e->EndPoints[1]->Normal[0]) + 0.05f; + e->Bounder.BR.Pos[1] = + max(e->EndPoints[0]->Normal[1], e->EndPoints[1]->Normal[1]) + 0.05f; + + /* insert into quadtree */ + AddEdge(NewLev, e); + + e = e->Next; + } +} + +/* + + ScaleAndAddObjects calculates a collision box for the + object, adds it to the collision tree then scales the + box for the current display resolution before adding to + the display tree + +*/ +static void ScaleAndAddObjects(struct Level *Lvl) +{ + struct Object *O = Lvl->AllObjects; + //double Scaler = (float)screen_height / 480.0f; + + while (O) { + /* generate bounding box for collisions (i.e. no scaling yet) */ + O->Bounder.BR.Pos[0] = O->Pos[0] + O->ObjType->Radius; + O->Bounder.BR.Pos[1] = O->Pos[1] + O->ObjType->Radius; + O->Bounder.TL.Pos[0] = O->Pos[0] - O->ObjType->Radius; + O->Bounder.TL.Pos[1] = O->Pos[1] - O->ObjType->Radius; + + /* insert into collisions tree */ + AddObject(Lvl, O, false); + + /* scale bounding box to get visual position */ + /*O->Bounder.BR.Pos[0] *= Scaler; + O->Bounder.BR.Pos[1] *= Scaler; + O->Bounder.TL.Pos[0] *= Scaler; + O->Bounder.TL.Pos[1] *= Scaler;*/ + + /* insert into display tree */ + AddObject(Lvl, O, true); + + /* move along linked lists */ + O = O->Next; + } +} + +/* + + AddTriangles takes the now fully processed list of world + triangles, calculates their bounding boxes (allowing for any + edge trim) and inserts them into the display tree + +*/ +static void AddTriangles(struct Level *Lvl) +{ + struct Triangle *Tri = Lvl->AllTris; + + while (Tri) { + int c = 3; + + /* determine axis aligned bounding box */ + Tri->Bounder.TL.Pos[0] = Tri->Bounder.BR.Pos[0] = Tri->Edges[0]->Pos[0]; + Tri->Bounder.TL.Pos[1] = Tri->Bounder.BR.Pos[1] = Tri->Edges[0]->Pos[1]; + + while (c--) { + int lc = c - 1; + + if (lc < 0) + lc = 2; + + /* check if this x expands the bounding box either leftward or rightward */ + if (Tri->Edges[c]->Pos[0] < Tri->Bounder.TL.Pos[0]) + Tri->Bounder.TL.Pos[0] = Tri->Edges[c]->Pos[0]; + if (Tri->Edges[c]->Pos[0] > Tri->Bounder.BR.Pos[0]) + Tri->Bounder.BR.Pos[0] = Tri->Edges[c]->Pos[0]; + + /* check y */ + if ((Tri->EdgeFlags[c] & TRIFLAGS_EDGE) + || (Tri->EdgeFlags[lc] & TRIFLAGS_EDGE)) { + if (Tri->Edges[c]->Pos[1] - + (Tri->EdgeFlags[c] & TRIFLAGS_WIDTH) < Tri->Bounder.TL.Pos[1]) + Tri->Bounder.TL.Pos[1] = + Tri->Edges[c]->Pos[1] - + (Tri->EdgeFlags[c] & TRIFLAGS_WIDTH); + if (Tri->Edges[c]->Pos[1] + (Tri->EdgeFlags[c] & TRIFLAGS_WIDTH) > + Tri->Bounder.BR.Pos[1]) + Tri->Bounder.BR.Pos[1] = + Tri->Edges[c]->Pos[1] + + (Tri->EdgeFlags[c] & TRIFLAGS_WIDTH); + } else { + if (Tri->Edges[c]->Pos[1] < Tri->Bounder.TL.Pos[1]) + Tri->Bounder.TL.Pos[1] = Tri->Edges[c]->Pos[1]; + if (Tri->Edges[c]->Pos[1] > Tri->Bounder.BR.Pos[1]) + Tri->Bounder.BR.Pos[1] = Tri->Edges[c]->Pos[1]; + } + } + + /* insert into tree */ + AddTriangle(Lvl, Tri); + + /* move along linked list */ + Tri = Tri->Next; + } +} + +/* + + GetLevelError returns a textual description of any error + that has occurred. If no error has occurred it will + slightly confusingly return "Unspecified error at line + <line count for file>" + + Appends "Level load - " to the start of whatever text + may already have been provided + +*/ +char *GetLevelError(void) +{ + char *LocTemp; + + if (!strlen(ErrorText)) + snprintf(ErrorText, sizeof(ErrorText), "Unspecified error at line %d", + Lines); + + LocTemp = strdup(ErrorText); + snprintf(ErrorText, sizeof(ErrorText), "Level load - %s", LocTemp); + free((void *)LocTemp); + return ErrorText; +} + +/* + + LoadLevel is called by other parts of the program and returns + either a complete level structure or NULL indicating error, in + which case GetLevelError will return a textual description + of the error. + + Parameters are 'name' - the file name of the level and 'radius' + - the collision size of the player for collision tree building + +*/ +struct Level *LoadLevel(char const *name, int radius) +{ + ALLEGRO_FILE *file; + struct Level *NewLev = NULL; + + ErrorText[0] = '\0'; /* set ErrorText to be a zero length string + so that it will be obvious later if anything has set the error flag + but not produced a verbose explanation of the error */ + Error = 0; /* reset error flag as no error has occurred yet */ + Lines = 1; /* first line is line 1 */ + + /* attempt to open named level file */ + file = al_fopen(name, "r"); + input = file; + + if (!input) { + snprintf(ErrorText, sizeof(ErrorText), "Unable to load %s", name); + goto error; + } + + /* allocate and initially set up new level structure */ + NewLev = NewLevel(); + + /* load materials, vertices & triangles in that order */ + LoadMaterials(NewLev); + if (Error) { + goto error; + } + LoadVertices(NewLev); + if (Error) { + goto error; + } + LoadTriangles(NewLev, radius); + if (Error) { + goto error; + } + + /* do a repeat 'fix' of vertices and fix of edges until we have + no edge errors - see algorithm descriptions elsewhere in this + file */ + do + FixVerts(NewLev, radius); + while (FixEdges(NewLev, radius)); + + /* now that edges are al_fixed, add them to the collision tree */ + AddEdges(NewLev); + + /* load ordinary object types */ + LoadObjectTypes(NewLev, radius); + if (Error) { + goto error; + } + + /* load special case object: door */ + if (!(NewLev->DoorOpen = ObtainBitmap("dooropen"))) { + snprintf(ErrorText, sizeof(ErrorText), + "Unable to obtain dooropen sprite"); + goto error; + } + if (!(NewLev->DoorShut = ObtainBitmap("doorshut"))) { + snprintf(ErrorText, sizeof(ErrorText), + "Unable to obtain doorshut sprite"); + goto error; + } + NewLev->Door.Image = NewLev->DoorShut; + NewLev->Door.CollectNoise = ObtainSample("dooropen"); + NewLev->Door.Radius = 14 + radius; + + /* load objects */ + NewLev->TotalObjects = 0; + LoadObjects(NewLev); + if (Error) { + goto error; + } + + /* complete display tree additions */ + AddTriangles(NewLev); + ScaleAndAddObjects(NewLev); + + /* order things for drawing */ + SplitTree(&NewLev->DisplayTree); + OrderTree(&NewLev->DisplayTree, false); + OrderTree(&NewLev->DisplayTree, true); + OrderTree(&NewLev->CollisionTree, false); + + /* load static level stuff - player start pos, etc */ + LoadStats(NewLev); + if (Error) { + goto error; + } + + /* make a copy of the initial state */ + NewLev->InitialState = BorrowState(NewLev); + + /* return level */ + return NewLev; + +error: + /* close input file */ + if (file) + al_fclose(file); + + if (NewLev) + FreeLevel(NewLev); + + return NULL; +} diff --git a/allegro/demos/skater/src/level.h b/allegro/demos/skater/src/level.h new file mode 100644 index 00000000..d2f35ef7 --- /dev/null +++ b/allegro/demos/skater/src/level.h @@ -0,0 +1,32 @@ +#ifndef __LEVEL_H +#define __LEVEL_H + +#include <allegro5/allegro.h> +#include "quadtree.h" + +extern struct Level *LoadLevel(char const *name, int collradius); +extern void FreeLevel(struct Level *lvl); +extern char *GetLevelError(void); + +extern void SetInitialState(struct Level *lvl); + +extern void DrawLevelBackground(struct Level *lev, + double *pos); +extern void DrawLevelForeground(struct Level *lev); + +/* level state struct, which stores the current state of the level - perfect for any future implementation +of loading/saving games */ +struct LevelState { + int Length; + uint32_t *Data; + int DoorOpen; +}; +extern void SetDoorOpen(struct Level *Lvl); +extern struct LevelState *BorrowState(struct Level *); +extern void ReturnState(struct Level *, struct LevelState *); +extern void FreeState(struct LevelState *); + +extern ALLEGRO_BITMAP *ObtainBitmap(const char *name); +extern ALLEGRO_SAMPLE *ObtainSample(const char *name); + +#endif diff --git a/allegro/demos/skater/src/level_alloc.c b/allegro/demos/skater/src/level_alloc.c new file mode 100644 index 00000000..d925aab0 --- /dev/null +++ b/allegro/demos/skater/src/level_alloc.c @@ -0,0 +1,99 @@ +#include <allegro5/allegro.h> +#include "level_alloc.h" + +/* + + A whole bunch of functions for creating new instances of the various game + structs. For simplicity these are allocated one at a time by this code, + although this is likely to lead to very suboptimal memory usage on modern + operating systems. + + If this were a C++ program, these would be the struct constructors. + + The pattern is quite generic and not really worth too much attention. + All pointers that may later be the target of memory deallocation are + set to NULL and in some cases other members of interest are initiated. + +*/ + +struct Level *NewLevel() +{ + struct Level *l = (struct Level *)malloc(sizeof(struct Level)); + + if (l) { + l->AllTris = NULL; + l->AllEdges = NULL; + l->AllMats = NULL; + l->AllVerts = NULL; + l->AllObjects = NULL; + l->AllObjectTypes = NULL; + l->InitialState = NULL; + l->DoorOpen = l->DoorShut = NULL; + l->Door.CollectNoise = NULL; + + SetupQuadTree(&l->DisplayTree, -65536, -65536, 65536, 65536); + SetupQuadTree(&l->CollisionTree, -65536, -65536, 65536, 65536); + } + + return l; +} + +struct Material *NewMaterial() +{ + struct Material *r = (struct Material *)malloc(sizeof(struct Material)); + + r->Next = NULL; + r->Edge = r->Fill = NULL; + r->Friction = 0; + return r; +} + +struct ObjectType *NewObjectType() +{ + struct ObjectType *r = + (struct ObjectType *)malloc(sizeof(struct ObjectType)); + + r->Next = NULL; + r->Image = NULL; + r->CollectNoise = NULL; + return r; +} + +struct Triangle *NewTriangle() +{ + struct Triangle *r = (struct Triangle *)malloc(sizeof(struct Triangle)); + + r->Next = NULL; + r->Material = NULL; + r->LastFrame = 0; + return r; +} + +struct Object *NewObject() +{ + struct Object *r = (struct Object *)malloc(sizeof(struct Object)); + + r->Next = NULL; + r->Flags = OBJFLAGS_VISIBLE; + r->ObjType = NULL; + return r; +} + +struct Edge *NewEdge() +{ + struct Edge *r = (struct Edge *)malloc(sizeof(struct Edge)); + + r->Next = NULL; + r->Material = NULL; + return r; +} + +struct Vertex *NewVertex() +{ + struct Vertex *v = (struct Vertex *)malloc(sizeof(struct Vertex)); + + v->Next = NULL; + v->Pos[0] = v->Pos[1] = 0; + v->Edges[0] = v->Edges[1] = NULL; + return v; +} diff --git a/allegro/demos/skater/src/level_alloc.h b/allegro/demos/skater/src/level_alloc.h new file mode 100644 index 00000000..73279d02 --- /dev/null +++ b/allegro/demos/skater/src/level_alloc.h @@ -0,0 +1,14 @@ +#ifndef __LVLALLOC_H +#define __LVLALLOC_H + +#include "level.h" + +extern struct Level *NewLevel(void); +extern struct Material *NewMaterial(void); +extern struct ObjectType *NewObjectType(void); +extern struct Triangle *NewTriangle(void); +extern struct Object *NewObject(void); +extern struct Edge *NewEdge(void); +extern struct Vertex *NewVertex(void); + +#endif diff --git a/allegro/demos/skater/src/level_file.c b/allegro/demos/skater/src/level_file.c new file mode 100644 index 00000000..81058546 --- /dev/null +++ b/allegro/demos/skater/src/level_file.c @@ -0,0 +1,508 @@ +#include <allegro5/allegro.h> +#include "global.h" +#include <string.h> +#include <math.h> +#include "level_alloc.h" +#include "level_file.h" +#include "token.h" + +/* + + Routines related to the initial reading of level data - heavily connected to + tkeniser.c. Defines the grammar that level files should use. + + Also includes a simple function for obtaining the equation of a line and some + other bits to do with data initialisation that flows straight from level data + +*/ + + +/* + + LoadMaterials loads the list of materials according to the following grammar: + + fillname -> string + edgename -> string + materal -> { fillname, edgename } + material list -> { material* } + +*/ +void LoadMaterials(struct Level *NewLev) +{ + struct Material **NewMatPtr = &NewLev->AllMats; +#ifdef DEMO_USE_ALLEGRO_GL + ALLEGRO_BITMAP *TmpEdge; +#endif + + ExpectToken(TK_OPENBRACE); + while (1) { + GetToken(); + switch (Token.Type) { + case TK_CLOSEBRACE: + return; + case TK_OPENBRACE: + { + *NewMatPtr = NewMaterial(); + + ExpectToken(TK_STRING); + if (!((*NewMatPtr)->Fill = ObtainBitmap(Token.Text))) { + Error = 1; + snprintf(ErrorText, sizeof(ErrorText), + "Could not load material fill %s at line %d", + Token.Text, Lines); + return; + } + + ExpectToken(TK_COMMA); + ExpectToken(TK_STRING); +#ifdef DEMO_USE_ALLEGRO_GL + if (!(TmpEdge = ObtainBitmap(Token.Text))) { +#else + if (!((*NewMatPtr)->Edge = ObtainBitmap(Token.Text))) { +#endif + Error = 1; + snprintf(ErrorText, sizeof(ErrorText), + "Could not load material edge %s at line %d", + Token.Text, Lines); + return; + } + + ExpectToken(TK_COMMA); + ExpectToken(TK_NUMBER); + (*NewMatPtr)->Friction = Token.FQuantity; + + ExpectToken(TK_CLOSEBRACE); + NewMatPtr = &(*NewMatPtr)->Next; + } + break; + default: + Error = 1; + return; + } + } +} + +/* + + LoadVertices loads the list of vertices according to the following grammar: + + xpos -> number + ypos -> number + vertex -> { xpos, ypos } + vertex list -> { vertex* } + +*/ +void LoadVertices(struct Level *NewLev) +{ + struct Vertex **NewVertPtr = &NewLev->AllVerts; + + ExpectToken(TK_OPENBRACE); + while (1) { + GetToken(); + switch (Token.Type) { + case TK_CLOSEBRACE: + return; + case TK_OPENBRACE: + { + *NewVertPtr = NewVertex(); + + ExpectToken(TK_NUMBER); + (*NewVertPtr)->Pos[0] = Token.FQuantity; + + ExpectToken(TK_COMMA); + ExpectToken(TK_NUMBER); + (*NewVertPtr)->Pos[1] = Token.FQuantity; + + ExpectToken(TK_CLOSEBRACE); + NewVertPtr = &(*NewVertPtr)->Next; + } + break; + default: + Error = 1; + return; + } + } +} + +/* + + GetVert loads a single vertex reference as part of the LoadTriangles routine. + Grammar is: + + edge height -> number + reference -> number + flags -> "edge" | "collidable" | "foreground" + vertex reference -> { reference, edge height [, flags] } + +*/ +static void GetVert(struct Level *NewLev, struct Triangle *t, int c) +{ + ExpectToken(TK_OPENBRACE); + + ExpectToken(TK_NUMBER); + t->Edges[c] = NewLev->AllVerts; + while (t->Edges[c] && Token.IQuantity--) + t->Edges[c] = t->Edges[c]->Next; + + if (Token.IQuantity != -1) { + Error = 1; + snprintf(ErrorText, sizeof(ErrorText), + "Unknown vertex referenced at line %d", Lines); + return; + } + ExpectToken(TK_COMMA); + + ExpectToken(TK_NUMBER); + t->EdgeFlags[c] = (Token.IQuantity * screen_height) / 480; + + GetToken(); + switch (Token.Type) { + case TK_COMMA: + { + int Finished = false; + + while (!Finished) { + GetToken(); + switch (Token.Type) { + case TK_CLOSEBRACE: + Finished = true; + break; + case TK_STRING: + if (!strcmp(Token.Text, "edge")) + t->EdgeFlags[c] |= TRIFLAGS_EDGE; + if (!strcmp(Token.Text, "collidable")) + t->EdgeFlags[c] |= FLAGS_COLLIDABLE; + if (!strcmp(Token.Text, "foreground")) + t->EdgeFlags[c] |= FLAGS_FOREGROUND; + break; + default: + Error = 1; + return; + } + } + } + break; + case TK_CLOSEBRACE: + break; + default: + Error = 1; + return; + } +} + +/* + + GetNormal is a function that doesn't read anything from a file but calculates + an edge normal for 'e' based on end points 'v1' and 'v2' + +*/ +int GetNormal(struct Edge *e, double *v1, double *v2) +{ + /* get line normal */ + double length; + + e->a = v2[1] - v1[1]; + e->b = -(v2[0] - v1[0]); + + /* make line normal unit length */ + length = sqrt(e->a * e->a + e->b * e->b); + if (length < 1.0f) + return true; + e->a /= length; + e->b /= length; + + /* calculate distance of line from origin */ + e->c = -(v1[0] * e->a + v1[1] * e->b); + return false; +} + +/* + + InitEdge intialises edges, which means calculating the 'expanded' edge equation + (i.e. one moved away from the real edge by 'radius' units) and making a note at + both end vertices of the edge they meet + +*/ +static void InitEdge(struct Edge *e, int radius) +{ + /* get edge normal */ + GetNormal(e, e->EndPoints[0]->Pos, e->EndPoints[1]->Pos); + + /* calculate distance to line from origin */ + e->c -= radius * (e->a * e->a + e->b * e->b); + + /* link edge as necessary */ + if (!e->EndPoints[0]->Edges[0]) + e->EndPoints[0]->Edges[0] = e; + else + e->EndPoints[0]->Edges[1] = e; + if (!e->EndPoints[1]->Edges[0]) + e->EndPoints[1]->Edges[0] = e; + else + e->EndPoints[1]->Edges[1] = e; +} + +/* + + LoadTriangles loads a triangle list, using GetVert as required. Grammar is: + + vertex reference -> (see GetVert commentary) + material reference -> number + triangle -> { vertex reference, vertex reference, vertex reference, + material reference } + triangle list -> { triangle* } + +*/ +void LoadTriangles(struct Level *NewLev, int radius) +{ + struct Triangle *Tri; + struct Edge *NextEdge; + int c; + + ExpectToken(TK_OPENBRACE); + while (1) { + GetToken(); + switch (Token.Type) { + case TK_CLOSEBRACE: + return; + case TK_OPENBRACE: + { + Tri = NewTriangle(); + + /* read vertex pointers & edge flags */ + GetVert(NewLev, Tri, 0); + ExpectToken(TK_COMMA); + GetVert(NewLev, Tri, 1); + ExpectToken(TK_COMMA); + GetVert(NewLev, Tri, 2); + ExpectToken(TK_COMMA); + + /* read material reference and store correct pointer */ + ExpectToken(TK_NUMBER); + + Tri->Material = NewLev->AllMats; + while (Tri->Material && Token.IQuantity--) + Tri->Material = Tri->Material->Next; + if (Token.IQuantity != -1) { + Error = 1; + snprintf(ErrorText, sizeof(ErrorText), + "Unknown material referenced at line %d", Lines); + return; + } + + /* expect end of this triangle */ + ExpectToken(TK_CLOSEBRACE); + + /* insert new triangle into total level list */ + Tri->Next = NewLev->AllTris; + NewLev->AllTris = Tri; + + /* generate edges */ + c = 3; + while (c--) { + if (Tri->EdgeFlags[c] & FLAGS_COLLIDABLE) { + NextEdge = NewLev->AllEdges; + NewLev->AllEdges = NewEdge(); + NewLev->AllEdges->Material = Tri->Material; + NewLev->AllEdges->Next = NextEdge; + + NewLev->AllEdges->EndPoints[0] = Tri->Edges[c]; + NewLev->AllEdges->EndPoints[1] = Tri->Edges[(c + 1) % 3]; + + InitEdge(NewLev->AllEdges, radius); + } + } + } + break; + default: + Error = 1; + return; + } + } +} + +/* + + LoadObjectTypes loads a list of object types. Grammar is: + + image name -> string + collection noise -> string + object type -> { image name, collection noise } + object type list -> { object type* } + +*/ +void LoadObjectTypes(struct Level *NewLev, int radius) +{ + struct ObjectType **NewObjectPtr = &NewLev->AllObjectTypes; + int w, h; + + ExpectToken(TK_OPENBRACE); + while (1) { + GetToken(); + switch (Token.Type) { + case TK_CLOSEBRACE: + return; + case TK_OPENBRACE: + { + *NewObjectPtr = NewObjectType(); + + ExpectToken(TK_STRING); + if (!((*NewObjectPtr)->Image = ObtainBitmap(Token.Text))) { + Error = 1; + snprintf(ErrorText, sizeof(ErrorText), + "Could not load object image %s at line %d", + Token.Text, Lines); + return; + } + w = al_get_bitmap_width((*NewObjectPtr)->Image); + h = al_get_bitmap_height((*NewObjectPtr)->Image); + (*NewObjectPtr)->Radius = w > h ? w : h; + (*NewObjectPtr)->Radius += radius; + + ExpectToken(TK_COMMA); + ExpectToken(TK_STRING); + + /* this doesn't generate an error as it is permissible to have objects that don't make a noise when collected */ + (*NewObjectPtr)->CollectNoise = ObtainSample(Token.Text); + + ExpectToken(TK_CLOSEBRACE); + NewObjectPtr = &(*NewObjectPtr)->Next; + } + break; + default: + Error = 1; + return; + } + } +} + +/* + + LoadObjects loads a list of objects. Grammar is: + + object pos x -> number + object pos y -> number + object type -> number + flags -> "collidable" | "foreground" + object -> { object pos x, object pos y, object type [, flags] } + object list -> { object* } + +*/ +void LoadObjects(struct Level *NewLev) +{ + struct Object *Obj; + int Finished; + + ExpectToken(TK_OPENBRACE); + while (1) { + GetToken(); + switch (Token.Type) { + case TK_CLOSEBRACE: + return; + case TK_OPENBRACE: + { + Obj = NewObject(); + NewLev->TotalObjects++; + + /* read location */ + ExpectToken(TK_NUMBER); + Obj->Pos[0] = Token.FQuantity; + ExpectToken(TK_COMMA); + ExpectToken(TK_NUMBER); + Obj->Pos[1] = Token.FQuantity; + ExpectToken(TK_COMMA); + + /* read angle, convert into Allegro format */ + ExpectToken(TK_NUMBER); + Obj->Angle = Token.FQuantity; + ExpectToken(TK_COMMA); + + /* read object type, manipulate pointer */ + ExpectToken(TK_NUMBER); + if (Token.IQuantity >= 0) { + Obj->ObjType = NewLev->AllObjectTypes; + while (Obj->ObjType && Token.IQuantity--) + Obj->ObjType = Obj->ObjType->Next; + + if (Token.IQuantity != -1) { + Error = 1; + snprintf(ErrorText, sizeof(ErrorText), + "Unknown object referenced at line %d", Lines); + return; + } + } else { + /* this is the door - a hard coded type */ + Obj->ObjType = &NewLev->Door; + Obj->Flags |= OBJFLAGS_DOOR; + NewLev->TotalObjects--; + } + + /* parse any flags that may exist */ + GetToken(); + switch (Token.Type) { + case TK_COMMA: + { + Finished = false; + while (!Finished) { + GetToken(); + switch (Token.Type) { + case TK_CLOSEBRACE: + Finished = true; + break; + case TK_STRING: + if (!strcmp(Token.Text, "collidable")) + Obj->Flags |= FLAGS_COLLIDABLE; + if (!strcmp(Token.Text, "foreground")) + Obj->Flags |= FLAGS_FOREGROUND; + break; + default: + Error = 1; + return; + } + } + } + break; + case TK_CLOSEBRACE: + break; + default: + Error = 1; + return; + } + + /* thread into list */ + Obj->Next = NewLev->AllObjects; + NewLev->AllObjects = Obj; + } + break; + default: + Error = 1; + return; + } + } +} + +/* + + LoadStats loads some special variables. Grammar is: + + player start x -> number + player start y -> number + required number of objects -> number + stats -> { player start x, player start y, required number of objects } + +*/ +void LoadStats(struct Level *NewLev) +{ + ExpectToken(TK_OPENBRACE); + + ExpectToken(TK_NUMBER); + NewLev->PlayerStartPos[0] = Token.FQuantity; + ExpectToken(TK_COMMA); + ExpectToken(TK_NUMBER); + NewLev->PlayerStartPos[1] = Token.FQuantity; + ExpectToken(TK_COMMA); + + ExpectToken(TK_NUMBER); + NewLev->ObjectsRequired = Token.IQuantity; + ExpectToken(TK_CLOSEBRACE); +} diff --git a/allegro/demos/skater/src/level_file.h b/allegro/demos/skater/src/level_file.h new file mode 100644 index 00000000..8aef5a07 --- /dev/null +++ b/allegro/demos/skater/src/level_file.h @@ -0,0 +1,15 @@ +#ifndef __LVLFILE_H +#define __LVLFILE_H + +#include "level.h" + +void LoadMaterials(struct Level *NewLev); +void LoadVertices(struct Level *NewLev); +void LoadTriangles(struct Level *NewLev, int radius); +void LoadObjectTypes(struct Level *NewLev, int radius); +void LoadObjects(struct Level *NewLev); +void LoadStats(struct Level *NewLev); + +extern int GetNormal(struct Edge *e, double *v1, double *v2); + +#endif diff --git a/allegro/demos/skater/src/level_state.c b/allegro/demos/skater/src/level_state.c new file mode 100644 index 00000000..9cd2b922 --- /dev/null +++ b/allegro/demos/skater/src/level_state.c @@ -0,0 +1,74 @@ +#include <allegro5/allegro.h> +#include <string.h> +#include "level.h" + +struct LevelState *BorrowState(struct Level *NewLev) +{ + struct LevelState *St; + struct Object *O; + int ObjCount; + + if (!NewLev) { + return NULL; + } + + St = (struct LevelState *)malloc(sizeof(struct LevelState)); + St->Length = (NewLev->TotalObjects + 31) >> 5; + St->Data = (uint32_t *) malloc(sizeof(uint32_t) * St->Length); + memset(St->Data, 0, sizeof(uint32_t) * St->Length); + + ObjCount = 0; + O = NewLev->AllObjects; + while (O) { + if (O->Flags & OBJFLAGS_VISIBLE) + St->Data[ObjCount >> 5] |= 1 << (ObjCount & 31); + O = O->Next; + ObjCount++; + } + + St->DoorOpen = (NewLev->Door.Image == NewLev->DoorOpen); + + return St; +} + +void ReturnState(struct Level *NewLev, struct LevelState *State) +{ + struct Object *O; + int ObjCount; + + if (!State || !NewLev) + return; + + ObjCount = 0; + O = NewLev->AllObjects; + while (O) { + if (State->Data[ObjCount >> 5] & (1 << (ObjCount & 31))) + O->Flags |= OBJFLAGS_VISIBLE; + else + O->Flags &= ~OBJFLAGS_VISIBLE; + O = O->Next; + ObjCount++; + } + + if (State->DoorOpen) + SetDoorOpen(NewLev); +} + +void FreeState(struct LevelState *State) +{ + if (!State) + return; + + free((void *)State->Data); + free(State); +} + +void SetInitialState(struct Level *lvl) +{ + ReturnState(lvl, lvl->InitialState); +} + +void SetDoorOpen(struct Level *Lvl) +{ + Lvl->Door.Image = Lvl->DoorOpen; +} diff --git a/allegro/demos/skater/src/menu.c b/allegro/demos/skater/src/menu.c new file mode 100644 index 00000000..c5748b37 --- /dev/null +++ b/allegro/demos/skater/src/menu.c @@ -0,0 +1,652 @@ +#include "global.h" +#include "background_scroller.h" +#include "credits.h" +#include "menu.h" +#include "music.h" +#include "vcontroller.h" +#include "gamepad.h" +#include "mouse.h" + +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) + +static int selected_item; +static int item_count; +static int locked; +static int freq_variation = 100; + +void init_demo_menu(DEMO_MENU * menu, int PlayMusic) +{ + int i; + + selected_item = -1; + item_count = 0; + locked = 0; + + for (i = 0; menu[i].proc != NULL; i++) { + menu[i].proc(&menu[i], DEMO_MENU_MSG_INIT, 0); + } + item_count = i; + + for (i = 0; menu[i].proc != NULL; i++) { + if ((menu[i].flags & DEMO_MENU_SELECTED)) { + selected_item = i; + break; + } + } + + if (selected_item == -1) { + for (i = 0; menu[i].proc != NULL; i++) { + if ((menu[i].flags & DEMO_MENU_SELECTABLE)) { + selected_item = i; + menu[i].flags |= DEMO_MENU_SELECTED; + break; + } + } + } + + if (PlayMusic) + play_music(DEMO_MIDI_MENU, 1); +} + + +int update_demo_menu(DEMO_MENU * menu) +{ + int tmp, c; + + update_background(); + update_credits(); + + if (selected_item != -1) { + menu[selected_item].proc(&menu[selected_item], DEMO_MENU_MSG_KEY, 0); + } + + for (tmp = 0; menu[tmp].proc != 0; tmp++) { + if (menu[tmp].proc(&menu[tmp], DEMO_MENU_MSG_TICK, 0) == DEMO_MENU_LOCK) { + locked = 0; + return DEMO_MENU_CONTINUE; + } + } + + if (locked == 1) { + return DEMO_MENU_CONTINUE; + } + + if (key_pressed(ALLEGRO_KEY_ESCAPE)) { + return DEMO_MENU_BACK; + } + + /* If a mouse button is pressed, select the item under it and send a + * DEMO_MENU_MSG_CHAR with 13 to it (which is the same effect as hitting + * the return key). + */ + if (mouse_button_pressed(1)) { + int i; + for (i = 0; menu[i].proc != NULL; i++) { + if (mouse_x() >= menu[i].x && mouse_y() >= menu[i].y && + mouse_x() < menu[i].x + menu[i].w && + mouse_y() < menu[i].y + menu[i].h) { + if (menu[i].flags & DEMO_MENU_SELECTABLE) { + if (selected_item != -1) { + menu[selected_item].flags &= ~DEMO_MENU_SELECTED; + } + selected_item = i; + menu[i].flags |= DEMO_MENU_SELECTED; + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + return menu[i].proc(&menu[i], DEMO_MENU_MSG_CHAR, 13); + } + } + } + } + + if (key_pressed(ALLEGRO_KEY_UP)) { + if (selected_item != -1) { + tmp = selected_item; + + while (1) { + --selected_item; + if (selected_item < 0) { + selected_item = item_count - 1; + } + + if (menu[selected_item].flags & DEMO_MENU_SELECTABLE) { + break; + } + } + + if (tmp != selected_item) { + menu[tmp].flags &= ~DEMO_MENU_SELECTED; + menu[selected_item].flags |= DEMO_MENU_SELECTED; + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, + 0); + } + } + } + + if (key_pressed(ALLEGRO_KEY_DOWN)) { + if (selected_item != -1) { + tmp = selected_item; + + while (1) { + ++selected_item; + if (selected_item >= item_count) { + selected_item = 0; + } + + if (menu[selected_item].flags & DEMO_MENU_SELECTABLE) { + break; + } + } + + if (tmp != selected_item) { + menu[tmp].flags &= ~DEMO_MENU_SELECTED; + menu[selected_item].flags |= DEMO_MENU_SELECTED; + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, + 0); + } + } + } + + c = unicode_char(true); + if(gamepad_button()) { + c = 32; + } + + if (selected_item != -1 && c) { + tmp = menu[selected_item].proc(&menu[selected_item], + DEMO_MENU_MSG_CHAR, c); + if (tmp == DEMO_MENU_LOCK) { + locked = 1; + return DEMO_MENU_CONTINUE; + } else { + locked = 0; + return tmp; + } + } + + return DEMO_MENU_CONTINUE; +} + + +void draw_demo_menu(DEMO_MENU * menu) +{ + int i, x, y, h, w; + int tmp; + static char logo_text[] = "Demo Game"; + + draw_background(); + draw_credits(); + + x = screen_width / 2; + y = 1 * screen_height / 6 - al_get_font_line_height(demo_font_logo) / 2; + demo_textprintf_centre(demo_font_logo, x + 6, y + 5, + al_map_rgba_f(0.125, 0.125, 0.125, 0.25), logo_text); + demo_textprintf_centre(demo_font_logo, x, y, al_map_rgb_f(1, 1, 1), logo_text); + + /* calculate height of the whole menu and the starting y coordinate */ + h = 0; + for (i = 0, h = 0; menu[i].proc != NULL; i++) { + h += menu[i].proc(&menu[i], DEMO_MENU_MSG_HEIGHT, 0); + } + h += 2 * 8; + y = 3 * screen_height / 5 - h / 2; + + /* calculate the width of the whole menu */ + w = 0; + for (i = 0; menu[i].proc != NULL; i++) { + tmp = menu[i].proc(&menu[i], DEMO_MENU_MSG_WIDTH, 0); + menu[i].w = tmp; + menu[i].x = (screen_width - tmp) / 2; + if (tmp > w) { + w = tmp; + } + } + w += 2 * 8; + if (w < screen_width / 3) w = screen_width / 3; + if (w > screen_width) w = screen_width; + x = (screen_width - w) / 2; + + /* draw menu background */ + al_draw_filled_rectangle(x, y, x + w, y + h, + al_map_rgba_f(0.37 * 0.6, 0.42 * 0.6, 0.45 * 0.6, 0.6)); + al_draw_rectangle(x, y, x + w, y + h, al_map_rgb(0, 0, 0), 1); + + /* draw menu items */ + y += 8; + for (i = 0; menu[i].proc != NULL; i++) { + menu[i].proc(&menu[i], DEMO_MENU_MSG_DRAW, y); + menu[i].y = y; + tmp = menu[i].proc(&menu[i], DEMO_MENU_MSG_HEIGHT, 0); + menu[i].h = tmp; + y += tmp; + } +} + + +int demo_text_proc(DEMO_MENU * item, int msg, int extra) +{ + if (msg == DEMO_MENU_MSG_DRAW) { + shadow_textprintf(demo_font, screen_width / 2, + extra, al_map_rgb(210, 230, 255), 2, item->name); + } else if (msg == DEMO_MENU_MSG_WIDTH) { + return al_get_text_width(demo_font, item->name); + } else if (msg == DEMO_MENU_MSG_HEIGHT) { + return al_get_font_line_height(demo_font) + 8; + } + + return DEMO_MENU_CONTINUE; +} + + +int demo_edit_proc(DEMO_MENU * item, int msg, int extra) +{ + ALLEGRO_COLOR col; + int w, h, x; + int l, c; + + if (msg == DEMO_MENU_MSG_DRAW) { + if (item->flags & DEMO_MENU_SELECTED) { + col = al_map_rgb(255, 255, 0); + } else { + col = al_map_rgb(255, 255, 255); + } + + w = demo_edit_proc(item, DEMO_MENU_MSG_WIDTH, 0); + h = al_get_font_line_height(demo_font); + + al_draw_filled_rectangle((screen_width - w) / 2 - 2, extra - 2, + (screen_width + w) / 2 + 2, extra + h + 2, al_map_rgb(0, 0, 0)); + al_draw_rectangle((screen_width - w) / 2 - 2, extra - 2, + (screen_width + w) / 2 + 2, extra + h + 2, col, 1); + shadow_textprintf(demo_font, screen_width / 2, + extra, col, 2, item->name); + if (item->flags & DEMO_MENU_SELECTED) { + x = (screen_width + al_get_text_width(demo_font, item->name)) / 2 + 2; + al_draw_line(x + 0.5, extra + 2, x + 0.5, extra + h - 2, col, 1); + al_draw_line(x + 1.5, extra + 2, x + 1.5, extra + h - 2, col, 1); + } + } else if (msg == DEMO_MENU_MSG_CHAR) { + switch (extra) { + case 8: + l = strlen(item->name); + if (l > 0) { + item->name[l - 1] = 0; + + if (item->on_activate) { + item->on_activate(item); + } + + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + } + break; + + default: + l = strlen(item->name); + c = extra & 0xff; + if (l < item->extra && c >= 0x20 && c < 0x7f) { + item->name[l] = c; + + if (item->on_activate) { + item->on_activate(item); + } + + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + } + break; + } + } else if (msg == DEMO_MENU_MSG_WIDTH) { + return MAX(al_get_text_width(demo_font, item->name), + item->extra * al_get_text_width(demo_font, " ")); + } else if (msg == DEMO_MENU_MSG_HEIGHT) { + return al_get_font_line_height(demo_font) + 8; + } + + return DEMO_MENU_CONTINUE; +} + + +int demo_button_proc(DEMO_MENU * item, int msg, int extra) +{ + ALLEGRO_COLOR col; + + if (msg == DEMO_MENU_MSG_DRAW) { + if (item->flags & DEMO_MENU_SELECTED) { + col = al_map_rgb(255, 255, 0); + } else { + col = al_map_rgb(255, 255, 255); + } + + shadow_textprintf(demo_font, screen_width / 2, + extra, col, 2, item->name); + } else if (msg == DEMO_MENU_MSG_CHAR) { + switch (extra) { + case 13: + case 32: + if (item->on_activate) { + item->on_activate(item); + } + + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + return item->extra; + break; + } + } else if (msg == DEMO_MENU_MSG_WIDTH || msg == DEMO_MENU_MSG_HEIGHT) { + return demo_text_proc(item, msg, extra); + } + + return DEMO_MENU_CONTINUE; +} + + +int demo_choice_proc(DEMO_MENU * item, int msg, int extra) +{ + int x, cw, ch, dy, cx; + int choice_count = 0; + int slider_width = screen_width / 6; + int i, tmp; + ALLEGRO_COLOR col; + + /* count number of choices */ + for (; item->data[choice_count] != 0; choice_count++); + + if (msg == DEMO_MENU_MSG_DRAW) { + if (!choice_count) return DEMO_MENU_CONTINUE; + if (item->flags & DEMO_MENU_SELECTED) { + col = al_map_rgb(255, 255, 0); + } else { + col = al_map_rgb(255, 255, 255); + } + + /* starting position */ + x = (screen_width - slider_width) / 2; + + /* print name of the item */ + shadow_textprintf(demo_font, x - 8, extra, col, 1, + item->name); + + /* draw slider thingy */ + ch = al_get_font_line_height(demo_font) / 2; + ch = MAX(8, ch); + dy = (al_get_font_line_height(demo_font) - ch) / 2; + + /* shadow */ + al_draw_rectangle(x + shadow_offset, + extra + dy + shadow_offset, + x + slider_width + shadow_offset, extra + dy + ch + shadow_offset, + al_map_rgb(0, 0, 0), 1); + cw = (slider_width - 4) / choice_count; + cw = MAX(cw, 8); + cx = (slider_width - 4) * item->extra / choice_count; + if (cx + cw > slider_width - 4) { + cx = slider_width - 4 - cw; + } + if (item->extra == choice_count - 1) { + cw = slider_width - 4 - cx; + } + al_draw_filled_rectangle(x + 3 + cx, extra + dy + 3, + x + 3 + cx + cw, extra + dy + ch, al_map_rgb(0, 0, 0)); + + /* slider */ + al_draw_rectangle(x, extra + dy, x + slider_width, extra + dy + ch, + col, 1); + al_draw_filled_rectangle(x + 2 + cx, extra + dy + 2, x + 2 + cx + cw, + extra + dy + ch - 2, col); + + x += slider_width; + + /* print selected choice */ + shadow_textprintf(demo_font, x + 8, extra, col, + 0, (char *)(item->data)[item->extra]); + } else if (msg == DEMO_MENU_MSG_KEY) { + if (key_pressed(ALLEGRO_KEY_LEFT)) { + if (item->extra > 0) { + --item->extra; + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + + if (item->on_activate) { + item->on_activate(item); + } + } + } + + if (key_pressed(ALLEGRO_KEY_RIGHT)) { + if (item->extra < choice_count - 1) { + ++item->extra; + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + + if (item->on_activate) { + item->on_activate(item); + } + } + } + } else if (msg == DEMO_MENU_MSG_CHAR && extra == 13) { + if (mouse_button_pressed(1)) { + x = (screen_width - slider_width) / 2; + item->extra = (mouse_x() - x) * choice_count / slider_width; + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + if (item->on_activate) { + item->on_activate(item); + } + } + } else if (msg == DEMO_MENU_MSG_WIDTH) { + cw = al_get_text_width(demo_font, item->name); + for (i = 0; item->data[i] != 0; i++) { + tmp = al_get_text_width(demo_font, (char *)(item->data)[i]); + if (tmp > cw) { + cw = tmp; + } + } + + return MAX(al_get_text_width(demo_font, item->name), + cw) * 2 + slider_width + 2 * 8; + } else if (msg == DEMO_MENU_MSG_HEIGHT) { + return demo_text_proc(item, msg, extra); + } + + return DEMO_MENU_CONTINUE; +} + + + +int demo_key_proc(DEMO_MENU * item, int msg, int extra) +{ + ALLEGRO_COLOR col; + + if (msg == DEMO_MENU_MSG_DRAW) { + if (item->flags & DEMO_MENU_SELECTED) { + col = al_map_rgb(255, 255, 0); + } else { + col = al_map_rgb(255, 255, 255); + } + + shadow_textprintf(demo_font, screen_width / 2 - 16, + extra, col, 1, item->name); + + if (item->flags & DEMO_MENU_EXTRA) { + shadow_textprintf(demo_font, + screen_width / 2 + 16, extra, col, 0, "..."); + } else { + shadow_textprintf(demo_font, + screen_width / 2 + 16, extra, col, 0, + controller[controller_id]-> + get_button_description(controller + [controller_id], + item->extra)); + } + } else if (msg == DEMO_MENU_MSG_CHAR) { + switch (extra) { + case 13: + case 32: + item->flags |= DEMO_MENU_EXTRA; + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + return DEMO_MENU_LOCK; + break; + } + } else if (msg == DEMO_MENU_MSG_TICK) { + if (item->flags & DEMO_MENU_EXTRA) { + if (controller[controller_id]-> + calibrate_button(controller[controller_id], item->extra) == 1) { + item->flags &= ~DEMO_MENU_EXTRA; + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + if (item->on_activate) { + item->on_activate(item); + } + return DEMO_MENU_LOCK; + } else if (key_pressed(ALLEGRO_KEY_ESCAPE)) { + item->flags &= ~DEMO_MENU_EXTRA; + return DEMO_MENU_LOCK; + } + } + } else if (msg == DEMO_MENU_MSG_WIDTH) { + int w1 = al_get_text_width(demo_font, item->name); + int w2 = al_get_text_width(demo_font, + (item-> + flags & DEMO_MENU_EXTRA) ? "..." : + controller[controller_id]-> + get_button_description(controller[controller_id], + item->extra)); + + return 2 * (16 + ((w2 > w1) ? w2 : w1)); + } else if (msg == DEMO_MENU_MSG_HEIGHT) { + return demo_text_proc(item, msg, extra); + } + + return DEMO_MENU_CONTINUE; +} + + +int demo_color_proc(DEMO_MENU * item, int msg, int extra) +{ + int x, h, cw, cx, i, c; + ALLEGRO_COLOR col1, col2; + int rgb[3]; + static char buf[64]; + int changed = 0; + int slider_width = screen_width / 6; + + slider_width /= 3; + slider_width -= 4; + + if (msg == DEMO_MENU_MSG_DRAW) { + if (item->flags & DEMO_MENU_SELECTED) { + col1 = al_map_rgb(255, 255, 0); + col2 = al_map_rgb(255, 255, 255); + } else { + col1 = al_map_rgb(255, 255, 255); + col2 = al_map_rgb(255, 255, 255); + } + + x = screen_width / 2 - (slider_width + 4) * 3 / 2; + h = al_get_font_line_height(demo_font); + + shadow_textprintf(demo_font, x - 8, extra, col1, + 1, item->name); + + c = *(int *)(item->data); + rgb[0] = c & 255; + rgb[1] = (c >> 8) & 255; + rgb[2] = (c >> 16) & 255; + + for (i = 0; i < 3; i++) { + cw = 4; + cx = (slider_width - 4 - cw) * rgb[i] / 255; + + al_draw_rectangle(x + 2, extra + 5, + x + slider_width + 2, extra + h - 1, al_map_rgb(0, 0, 0), 1); + al_draw_filled_rectangle(x + 3 + cx, extra + 6, + x + 3 + cx + cw, extra + h - 4, al_map_rgb(0, 0, 0)); + + al_draw_rectangle(x, extra + 3, x + slider_width, + extra + h - 3, item->extra == i ? col1 : col2, 1); + al_draw_filled_rectangle(x + 2 + cx, extra + 5, + x + 2 + cx + cw, extra + h - 5, + item->extra == i ? col1 : col2); + + x += slider_width + 4; + } + + snprintf(buf, sizeof(buf), "%d,%d,%d", rgb[0], rgb[1], rgb[2]); + shadow_textprintf(demo_font, x + 8, extra, al_map_rgb(rgb[0], rgb[1], rgb[2]), 0, buf); + } else if (msg == DEMO_MENU_MSG_KEY) { + c = *(int *)(item->data); + + rgb[0] = (c >> 0) & 255; + rgb[1] = (c >> 8) & 255; + rgb[2] = (c >> 16) & 255; + + + + if (key_pressed(ALLEGRO_KEY_LEFT)) { + if (rgb[item->extra] > 0) { + if (key_down(ALLEGRO_KEY_LSHIFT) || key_down(ALLEGRO_KEY_RSHIFT)) { + --rgb[item->extra]; + } else { + rgb[item->extra] -= 16; + rgb[item->extra] = MAX(0, rgb[item->extra]); + } + + changed = 1; + } + } + + if (key_pressed(ALLEGRO_KEY_RIGHT)) { + if (rgb[item->extra] < 255) { + if (key_down(ALLEGRO_KEY_LSHIFT) || key_down(ALLEGRO_KEY_RSHIFT)) { + ++rgb[item->extra]; + } else { + rgb[item->extra] += 16; + rgb[item->extra] = MIN(255, rgb[item->extra]); + } + + changed = 1; + } + } + + if (key_pressed(ALLEGRO_KEY_TAB)) { + if (key_down(ALLEGRO_KEY_LSHIFT) || key_down(ALLEGRO_KEY_RSHIFT)) { + --item->extra; + if (item->extra < 0) { + item->extra += 3; + } + } else { + ++item->extra; + item->extra %= 3; + } + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + if (item->on_activate) { + item->on_activate(item); + } + } + + if (changed) { + *(int *)(item->data) = rgb[0] + (rgb[1] << 8) + (rgb[2] << 16); + + play_sound_id(DEMO_SAMPLE_BUTTON, 255, 128, -freq_variation, 0); + + if (item->on_activate) { + item->on_activate(item); + } + } + } else if (msg == DEMO_MENU_MSG_WIDTH) { + return MAX(al_get_text_width(demo_font, item->name) * 2 + 8 * 2 + + 3 * (slider_width + 4), + 8 * 2 + 3 * (slider_width + 4) + + 2 * al_get_text_width(demo_font, "255,255,255")); + } else if (msg == DEMO_MENU_MSG_HEIGHT) { + return al_get_font_line_height(demo_font); + } + + return DEMO_MENU_CONTINUE; +} + + +int demo_separator_proc(DEMO_MENU * item, int msg, int extra) +{ + if (msg == DEMO_MENU_MSG_WIDTH) { + return extra - extra; + } else if (msg == DEMO_MENU_MSG_HEIGHT) { + return item->extra; + } + + return DEMO_MENU_CONTINUE; +} diff --git a/allegro/demos/skater/src/menu.h b/allegro/demos/skater/src/menu.h new file mode 100644 index 00000000..91fd3dc2 --- /dev/null +++ b/allegro/demos/skater/src/menu.h @@ -0,0 +1,62 @@ +#ifndef __DEMO_MENU_H__ +#define __DEMO_MENU_H__ + +#include <allegro5/allegro.h> +#include "global.h" + +#define DEMO_MENU_CONTINUE 1000 +#define DEMO_MENU_BACK 1001 +#define DEMO_MENU_LOCK 1002 + +#define DEMO_MENU_SELECTABLE 1 +#define DEMO_MENU_SELECTED 2 +#define DEMO_MENU_EXIT 4 +#define DEMO_MENU_EXTRA 8 + +#define DEMO_MENU_MSG_INIT 0 +#define DEMO_MENU_MSG_DRAW 1 +#define DEMO_MENU_MSG_CHAR 2 +#define DEMO_MENU_MSG_KEY 3 +#define DEMO_MENU_MSG_WIDTH 4 +#define DEMO_MENU_MSG_HEIGHT 5 +#define DEMO_MENU_MSG_TICK 6 + +extern ALLEGRO_BITMAP *demo_menu_canvas; + +typedef struct DEMO_MENU DEMO_MENU; + +struct DEMO_MENU { + int (*proc) (DEMO_MENU *, int, int); + char *name; + int flags; + int extra; + void **data; + void (*on_activate) (DEMO_MENU *); + int x, y, w, h; +}; + +#define DEMO_MENU_ITEM2(proc, name) \ + {proc, name, 0, 0, 0, 0, 0, 0, 0, 0} + +#define DEMO_MENU_ITEM4(proc, name, flags, extra) \ + {proc, name, flags, extra, 0, 0, 0, 0, 0, 0} + +#define DEMO_MENU_ITEM6(proc, name, flags, extra, data, on_activate) \ + {proc, name, flags, extra, data, on_activate, 0, 0, 0, 0} + +#define DEMO_MENU_END \ + DEMO_MENU_ITEM2(0, 0) + +void init_demo_menu(DEMO_MENU * menu, int PlayMusic); +int update_demo_menu(DEMO_MENU * menu); +void draw_demo_menu(DEMO_MENU * menu); + +int demo_text_proc(DEMO_MENU * item, int msg, int key); +int demo_edit_proc(DEMO_MENU * item, int msg, int key); +int demo_button_proc(DEMO_MENU * item, int msg, int key); +int demo_choice_proc(DEMO_MENU * item, int msg, int key); +int demo_key_proc(DEMO_MENU * item, int msg, int key); +int demo_color_proc(DEMO_MENU * item, int msg, int extra); +int demo_separator_proc(DEMO_MENU * item, int msg, int extra); + +#endif /* __DEMO_MENU_H__ */ diff --git a/allegro/demos/skater/src/menu_about.c b/allegro/demos/skater/src/menu_about.c new file mode 100644 index 00000000..6076924f --- /dev/null +++ b/allegro/demos/skater/src/menu_about.c @@ -0,0 +1,75 @@ +#include <allegro5/allegro.h> +#include <stdio.h> +#include "defines.h" +#include "global.h" +#include "menu.h" +#include "menus.h" + + +static int _id = DEMO_STATE_ABOUT; + +static int id(void) +{ + return _id; +} + + +static DEMO_MENU menu[] = { + DEMO_MENU_ITEM2(demo_text_proc, "Looks like rain. And soon!"), + DEMO_MENU_ITEM2(demo_text_proc, " "), + DEMO_MENU_ITEM2(demo_text_proc, "Help coastal outdoor confectioner Ted collect the cherries,"), + DEMO_MENU_ITEM2(demo_text_proc, "bananas, sliced oranges, sweets and ice creams he has on display"), + DEMO_MENU_ITEM2(demo_text_proc, "before the rain begins!"), + DEMO_MENU_ITEM2(demo_text_proc, "Luckily he has a skateboard so it should be a breeze!"), + DEMO_MENU_ITEM2(demo_text_proc, " "), + DEMO_MENU_ITEM2(demo_text_proc, NULL), + DEMO_MENU_ITEM2(demo_text_proc, "by Shawn Hargreaves and many others"), + DEMO_MENU_ITEM2(demo_text_proc, " "), + DEMO_MENU_ITEM2(demo_text_proc, "Allegro Demo Game"), + DEMO_MENU_ITEM2(demo_text_proc, "By Miran Amon, Nick Davies, Elias Pschernig, Thomas Harte & Jakub Wasilewski"), + DEMO_MENU_ITEM2(demo_text_proc, " "), + DEMO_MENU_ITEM4(demo_button_proc, "Back", DEMO_MENU_SELECTABLE, DEMO_STATE_MAIN_MENU), + DEMO_MENU_END +}; + + +static void init(void) +{ + static char version[256]; + int v = al_get_allegro_version(); + menu[7].name = version; + sprintf(menu[7].name, "Allegro %d.%d.%d", (v >> 24), (v >> 16) & 255, (v >> 8) & 255); + init_demo_menu(menu, true); +} + + +static int update(void) +{ + int ret = update_demo_menu(menu); + + switch (ret) { + case DEMO_MENU_CONTINUE: + return id(); + + case DEMO_MENU_BACK: + return DEMO_STATE_MAIN_MENU; + + default: + return ret; + }; +} + + +static void draw(void) +{ + draw_demo_menu(menu); +} + + +void create_about_menu(GAMESTATE *state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} diff --git a/allegro/demos/skater/src/menu_controls.c b/allegro/demos/skater/src/menu_controls.c new file mode 100644 index 00000000..236c8521 --- /dev/null +++ b/allegro/demos/skater/src/menu_controls.c @@ -0,0 +1,76 @@ +#include <allegro5/allegro.h> +#include "defines.h" +#include "global.h" +#include "menu.h" +#include "menus.h" + + +static int _id = DEMO_STATE_CONTROLS; + +static int id(void) +{ + return _id; +} + + +static char *choice_controls[] = { "keyboard", "gamepad", 0 }; + + +static void on_controller(DEMO_MENU * item); + + +static DEMO_MENU menu[] = { + DEMO_MENU_ITEM2(demo_text_proc, "SETUP CONTROLS"), + DEMO_MENU_ITEM6(demo_choice_proc, "Controller", DEMO_MENU_SELECTABLE, 0, (void *)choice_controls, on_controller), + DEMO_MENU_ITEM4(demo_key_proc, "Left", DEMO_MENU_SELECTABLE, DEMO_BUTTON_LEFT), + DEMO_MENU_ITEM4(demo_key_proc, "Right", DEMO_MENU_SELECTABLE, DEMO_BUTTON_RIGHT), + DEMO_MENU_ITEM4(demo_key_proc, "Jump", DEMO_MENU_SELECTABLE, DEMO_BUTTON_JUMP), + DEMO_MENU_ITEM4(demo_button_proc, "Back", DEMO_MENU_SELECTABLE, DEMO_STATE_OPTIONS), + DEMO_MENU_END +}; + + +static void init(void) +{ + init_demo_menu(menu, true); + + menu[1].extra = controller_id; +} + + +static int update(void) +{ + int ret = update_demo_menu(menu); + + switch (ret) { + case DEMO_MENU_CONTINUE: + return id(); + + case DEMO_MENU_BACK: + return DEMO_STATE_OPTIONS; + + default: + return ret; + }; +} + + +static void draw(void) +{ + draw_demo_menu( menu); +} + + +void create_controls_menu(GAMESTATE * state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} + + +static void on_controller(DEMO_MENU * item) +{ + controller_id = item->extra; +} diff --git a/allegro/demos/skater/src/menu_graphics.c b/allegro/demos/skater/src/menu_graphics.c new file mode 100644 index 00000000..df901106 --- /dev/null +++ b/allegro/demos/skater/src/menu_graphics.c @@ -0,0 +1,167 @@ +#include <allegro5/allegro.h> +#include "defines.h" +#include "global.h" +#include "menu.h" +#include "menus.h" + + +static int _id = DEMO_STATE_GFX; + +static int id(void) +{ + return _id; +} + + +static char *choice_on_off[] = { "off", "on", 0 }; +static char *choice_bpp[] = { "15 bpp", "16 bpp", "24 bpp", "32 bpp", 0 }; +static char **choice_res; + +static char *choice_samples[] = + { "1x", "2x", "4x", "8x", 0 }; + +static char *choice_fullscreen[] = + { "window", "fullscreen window", "fullscreen", 0 }; + +static void apply(DEMO_MENU * item); + +static void on_fullscreen(DEMO_MENU *item); + +static void on_vsync(DEMO_MENU * item) +{ + use_vsync = item->extra; +} + +static DEMO_MENU menu[] = { + DEMO_MENU_ITEM2(demo_text_proc, "GFX SETTINGS"), + DEMO_MENU_ITEM6(demo_choice_proc, "Mode", DEMO_MENU_SELECTABLE, 0, (void *)choice_fullscreen, on_fullscreen), + DEMO_MENU_ITEM6(demo_choice_proc, "Bit Depth", DEMO_MENU_SELECTABLE, 0, (void *)choice_bpp, 0), + DEMO_MENU_ITEM6(demo_choice_proc, "Screen Size", DEMO_MENU_SELECTABLE, 0, NULL, 0), + DEMO_MENU_ITEM6(demo_choice_proc, "Supersampling", DEMO_MENU_SELECTABLE, 0, (void *)choice_samples, 0), + DEMO_MENU_ITEM6(demo_choice_proc, "Vsync", DEMO_MENU_SELECTABLE, 0, (void *)choice_on_off, on_vsync), + DEMO_MENU_ITEM6(demo_button_proc, "Apply", DEMO_MENU_SELECTABLE, DEMO_STATE_GFX, 0, apply), + DEMO_MENU_ITEM6(demo_button_proc, "Back", DEMO_MENU_SELECTABLE, DEMO_STATE_OPTIONS, 0, 0), + DEMO_MENU_END +}; + +static void on_fullscreen(DEMO_MENU *item) +{ + menu[3].flags = item->extra == 2 ? DEMO_MENU_SELECTABLE : 0; +} + +static bool already(char *mode) +{ + int i; + for (i = 0; choice_res[i]; i++) { + if (!strcmp(choice_res[i], mode)) return true; + } + return false; +} + +static void init(void) +{ + if (!choice_res) { + int i, n = al_get_num_display_modes(), j = 0; + choice_res = calloc(n + 1, sizeof *choice_res); + menu[3].data = (void *)choice_res; + for (i = 0; i < n; i++) { + ALLEGRO_DISPLAY_MODE m; + char str[100]; + al_get_display_mode(i, &m); + sprintf(str, "%dx%d", m.width, m.height); + if (!already(str)) { + if (m.width == screen_width && m.height == screen_height) { + menu[3].extra = j; + } + choice_res[j++] = strdup(str); + } + } + } + + init_demo_menu(menu, true); + + menu[1].extra = fullscreen; + + menu[5].extra = use_vsync; + + on_fullscreen(menu + 1); +} + + +static int update(void) +{ + int ret = update_demo_menu(menu); + + switch (ret) { + case DEMO_MENU_CONTINUE: + return id(); + + case DEMO_MENU_BACK: + return DEMO_STATE_OPTIONS; + + default: + return ret; + }; +} + + +static void draw(void) +{ + draw_demo_menu(menu); +} + + +void create_gfx_menu(GAMESTATE * state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} + + +static void apply(DEMO_MENU * item) +{ + int old_fullscreen = fullscreen; + int old_bit_depth = bit_depth; + int old_screen_width = screen_width; + int old_screen_height = screen_height; + int old_screen_samples = screen_samples; + int old_use_vsync = use_vsync; + char *p; + + (void)item; + + fullscreen = menu[1].extra; + + bit_depth = 0; + + p = choice_res[menu[3].extra]; + screen_width = strtol(p, &p, 10); + screen_height = strtol(p + 1, &p, 10); + + screen_samples = 1 << menu[4].extra; + + use_vsync = menu[5].extra; + + if (fullscreen == old_fullscreen && + bit_depth == old_bit_depth && + use_vsync == old_use_vsync && + screen_width == old_screen_width && + screen_height == old_screen_height && + screen_samples == old_screen_samples) { + return; + } + + if (change_gfx_mode() != DEMO_OK) { + fullscreen = old_fullscreen; + bit_depth = old_bit_depth; + screen_width = old_screen_width; + screen_height = old_screen_height; + screen_samples = old_screen_samples; + use_vsync = old_use_vsync; + change_gfx_mode(); + } + + init(); +} diff --git a/allegro/demos/skater/src/menu_main.c b/allegro/demos/skater/src/menu_main.c new file mode 100644 index 00000000..ca700234 --- /dev/null +++ b/allegro/demos/skater/src/menu_main.c @@ -0,0 +1,87 @@ +#include <allegro5/allegro.h> +#include "defines.h" +#include "global.h" +#include "menu.h" +#include "menus.h" +#include "music.h" + + +static int _id = DEMO_STATE_MAIN_MENU; +static int already_said_welcome = 0; + +static int id(void) +{ + return _id; +} + + +static DEMO_MENU menu[] = { + DEMO_MENU_ITEM4(demo_button_proc, "New Game", DEMO_MENU_SELECTABLE, DEMO_STATE_NEW_GAME), + DEMO_MENU_ITEM4(demo_text_proc, "Continue Game", 0, DEMO_STATE_CONTINUE_GAME), + DEMO_MENU_ITEM4(demo_button_proc, "Options", DEMO_MENU_SELECTABLE, DEMO_STATE_OPTIONS), + DEMO_MENU_ITEM4(demo_button_proc, "About", DEMO_MENU_SELECTABLE, DEMO_STATE_ABOUT), + DEMO_MENU_ITEM4(demo_button_proc, "Exit", DEMO_MENU_SELECTABLE, DEMO_STATE_EXIT), + DEMO_MENU_END +}; + +void enable_continue_game(void) +{ + menu[1].proc = demo_button_proc; + menu[1].flags |= DEMO_MENU_SELECTABLE; +} + + + +void disable_continue_game(void) +{ + menu[1].proc = demo_text_proc; + menu[1].flags &= ~DEMO_MENU_SELECTABLE; + + /* need to move 'cursor' if it was on continue game */ + if (menu[1].flags & DEMO_MENU_SELECTED) { + menu[1].flags &= ~DEMO_MENU_SELECTED; + menu[0].flags |= DEMO_MENU_SELECTED; + } +} + +static void init(void) +{ + init_demo_menu(menu, true); + + if (!already_said_welcome) { + play_sound(demo_data[DEMO_SAMPLE_WELCOME].dat, 255, 128, 1000, 0); + already_said_welcome = 1; + } +} + + +static int update(void) +{ + int ret = update_demo_menu(menu); + + switch (ret) { + case DEMO_MENU_CONTINUE: + return id(); + + case DEMO_MENU_BACK: + return DEMO_STATE_EXIT; + + default: + return ret; + }; +} + + +static void draw(void) +{ + draw_demo_menu(menu); +} + + +void create_main_menu(GAMESTATE * state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} diff --git a/allegro/demos/skater/src/menu_misc.c b/allegro/demos/skater/src/menu_misc.c new file mode 100644 index 00000000..4e8adc39 --- /dev/null +++ b/allegro/demos/skater/src/menu_misc.c @@ -0,0 +1,86 @@ +#include <allegro5/allegro.h> +#include "defines.h" +#include "global.h" +#include "menu.h" +#include "menus.h" + + +static int _id = DEMO_STATE_MISC; + +static int id(void) +{ + return _id; +} + + +static char *choice_yes_no[] = { "no", "yes", 0 }; + + +static void on_fps(DEMO_MENU * item) +{ + display_framerate = item->extra; +} + + +static void on_limit(DEMO_MENU * item) +{ + limit_framerate = item->extra; +} + + +static void on_yield(DEMO_MENU * item) +{ + reduce_cpu_usage = item->extra; +} + + +static DEMO_MENU menu[] = { + DEMO_MENU_ITEM2(demo_text_proc, "SYSTEM SETTINGS"), + DEMO_MENU_ITEM6(demo_choice_proc, "Show Framerate", DEMO_MENU_SELECTABLE, 0, (void *)choice_yes_no, on_fps), + DEMO_MENU_ITEM6(demo_choice_proc, "Cap Framerate", DEMO_MENU_SELECTABLE, 0, (void *)choice_yes_no, on_limit), + DEMO_MENU_ITEM6(demo_choice_proc, "Conserve Power", DEMO_MENU_SELECTABLE, 0, (void *)choice_yes_no, on_yield), + DEMO_MENU_ITEM4(demo_button_proc, "Back", DEMO_MENU_SELECTABLE, DEMO_STATE_OPTIONS), + DEMO_MENU_END +}; + + +static void init(void) +{ + init_demo_menu(menu, true); + + menu[1].extra = display_framerate; + menu[2].extra = limit_framerate; + menu[3].extra = reduce_cpu_usage; +} + + +static int update(void) +{ + int ret = update_demo_menu(menu); + + switch (ret) { + case DEMO_MENU_CONTINUE: + return id(); + + case DEMO_MENU_BACK: + return DEMO_STATE_OPTIONS; + + default: + return ret; + }; +} + + +static void draw(void) +{ + draw_demo_menu(menu); +} + + +void create_misc_menu(GAMESTATE * state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} diff --git a/allegro/demos/skater/src/menu_options.c b/allegro/demos/skater/src/menu_options.c new file mode 100644 index 00000000..73e05d6b --- /dev/null +++ b/allegro/demos/skater/src/menu_options.c @@ -0,0 +1,61 @@ +#include <allegro5/allegro.h> +#include "defines.h" +#include "menu.h" +#include "menus.h" + + +static int _id = DEMO_STATE_OPTIONS; + +static int id(void) +{ + return _id; +} + + +static DEMO_MENU menu[] = { + DEMO_MENU_ITEM2(demo_text_proc, "OPTIONS"), + DEMO_MENU_ITEM4(demo_button_proc, "Graphics", DEMO_MENU_SELECTABLE, DEMO_STATE_GFX), + DEMO_MENU_ITEM4(demo_button_proc, "Sound", DEMO_MENU_SELECTABLE, DEMO_STATE_SOUND), + DEMO_MENU_ITEM4(demo_button_proc, "Controls", DEMO_MENU_SELECTABLE, DEMO_STATE_CONTROLS), + DEMO_MENU_ITEM4(demo_button_proc, "System", DEMO_MENU_SELECTABLE, DEMO_STATE_MISC), + DEMO_MENU_ITEM4(demo_button_proc, "Back", DEMO_MENU_SELECTABLE, DEMO_STATE_MAIN_MENU), + DEMO_MENU_END +}; + + +static void init(void) +{ + init_demo_menu(menu, true); +} + + +static int update(void) +{ + int ret = update_demo_menu(menu); + + switch (ret) { + case DEMO_MENU_CONTINUE: + return id(); + + case DEMO_MENU_BACK: + return DEMO_STATE_MAIN_MENU; + + default: + return ret; + }; +} + + +static void draw(void) +{ + draw_demo_menu(menu); +} + + +void create_options_menu(GAMESTATE * state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} diff --git a/allegro/demos/skater/src/menu_sound.c b/allegro/demos/skater/src/menu_sound.c new file mode 100644 index 00000000..74f5b7df --- /dev/null +++ b/allegro/demos/skater/src/menu_sound.c @@ -0,0 +1,84 @@ +#include <allegro5/allegro.h> +#include "defines.h" +#include "global.h" +#include "menu.h" +#include "menus.h" +#include "music.h" + + +static int _id = DEMO_STATE_SOUND; + + +static int id(void) +{ + return _id; +} + + +static char *choice_volume[] = + { "0%%", "10%%", "20%%", "30%%", "40%%", "50%%", "60%%", "70%%", + "80%%", "90%%", "100%%", 0 +}; + + +static void on_sound(DEMO_MENU * item) +{ + sound_volume = item->extra; + set_sound_volume(sound_volume / 10.0); +} + + +static void on_music(DEMO_MENU * item) +{ + music_volume = item->extra; + set_music_volume(music_volume / 10.0); +} + + +static DEMO_MENU menu[] = { + DEMO_MENU_ITEM2(demo_text_proc, "SOUND LEVELS"), + DEMO_MENU_ITEM6(demo_choice_proc, "Sound", DEMO_MENU_SELECTABLE, 0, (void *)choice_volume, on_sound), + DEMO_MENU_ITEM6(demo_choice_proc, "Music", DEMO_MENU_SELECTABLE, 0, (void *)choice_volume, on_music), + DEMO_MENU_ITEM4(demo_button_proc, "Back", DEMO_MENU_SELECTABLE, DEMO_STATE_OPTIONS), + DEMO_MENU_END +}; + + +static void init(void) +{ + init_demo_menu(menu, true); + menu[1].extra = sound_volume; + menu[2].extra = music_volume; +} + + +static int update(void) +{ + int ret = update_demo_menu(menu); + + switch (ret) { + case DEMO_MENU_CONTINUE: + return id(); + + case DEMO_MENU_BACK: + return DEMO_STATE_OPTIONS; + + default: + return ret; + } +} + + +static void draw(void) +{ + draw_demo_menu(menu); +} + + +void create_sound_menu(GAMESTATE * state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} diff --git a/allegro/demos/skater/src/menu_success.c b/allegro/demos/skater/src/menu_success.c new file mode 100644 index 00000000..2e84e875 --- /dev/null +++ b/allegro/demos/skater/src/menu_success.c @@ -0,0 +1,67 @@ +#include <allegro5/allegro.h> +#include "defines.h" +#include "global.h" +#include "menu.h" +#include "menus.h" +#include "music.h" + +static int _id = DEMO_STATE_SUCCESS; + +static int id(void) +{ + return _id; +} + + +static DEMO_MENU menu[] = { + DEMO_MENU_ITEM2(demo_text_proc, "Well done! Ted's stock is saved!"), + DEMO_MENU_ITEM2(demo_text_proc, " "), + DEMO_MENU_ITEM2(demo_text_proc, "This demo has shown only a fraction"), + DEMO_MENU_ITEM2(demo_text_proc, "of Allegro's capabilities."), + DEMO_MENU_ITEM2(demo_text_proc, " "), + DEMO_MENU_ITEM2(demo_text_proc, "Now it's up to you to show the world the rest!"), + DEMO_MENU_ITEM2(demo_text_proc, "Get coding!"), + DEMO_MENU_ITEM2(demo_text_proc, " "), + DEMO_MENU_ITEM4(demo_button_proc, "Back", DEMO_MENU_SELECTABLE, DEMO_STATE_MAIN_MENU), + DEMO_MENU_END +}; + + +static void init(void) +{ + init_demo_menu(menu, false); + disable_continue_game(); + play_music(DEMO_MIDI_SUCCESS, false); +} + + +static int update(void) +{ + int ret = update_demo_menu(menu); + + switch (ret) { + case DEMO_MENU_CONTINUE: + return id(); + + case DEMO_MENU_BACK: + return DEMO_STATE_MAIN_MENU; + + default: + return ret; + }; +} + + +static void draw(void) +{ + draw_demo_menu(menu); +} + + +void create_success_menu(GAMESTATE * state) +{ + state->id = id; + state->init = init; + state->update = update; + state->draw = draw; +} diff --git a/allegro/demos/skater/src/menus.h b/allegro/demos/skater/src/menus.h new file mode 100644 index 00000000..a099002d --- /dev/null +++ b/allegro/demos/skater/src/menus.h @@ -0,0 +1,19 @@ +#ifndef __DEMO_GAME_MENUS_H__ +#define __DEMO_GAME_MENUS_H__ + +#include "gamestate.h" /* gamestate.h */ + +void create_main_menu(GAMESTATE * state); +void create_options_menu(GAMESTATE * state); +void create_gfx_menu(GAMESTATE * state); +void create_sound_menu(GAMESTATE * state); +void create_controls_menu(GAMESTATE * state); +void create_misc_menu(GAMESTATE * state); +void create_about_menu(GAMESTATE * state); +void create_success_menu(GAMESTATE * state); +void create_intro(GAMESTATE * state); + +void enable_continue_game(void); +void disable_continue_game(void); + +#endif /* __DEMO_GAME_MENUS_H__ */ diff --git a/allegro/demos/skater/src/mouse.c b/allegro/demos/skater/src/mouse.c new file mode 100644 index 00000000..e8918265 --- /dev/null +++ b/allegro/demos/skater/src/mouse.c @@ -0,0 +1,61 @@ +#include "mouse.h" + + +/* + * bit 0: key is down + * bit 1: key was pressed + * bit 2: key was released + */ +#define MOUSE_BUTTONS 10 +static int mouse_array[MOUSE_BUTTONS]; +static int mx, my; + +bool mouse_button_down(int b) +{ + return mouse_array[b] & 1; +} + +bool mouse_button_pressed(int b) +{ + return mouse_array[b] & 2; +} + +int mouse_x(void) +{ + return mx; +} + +int mouse_y(void) +{ + return my; +} + +void mouse_handle_event(ALLEGRO_EVENT *event) +{ + switch (event->type) { + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + mouse_array[event->mouse.button] |= (1 << 0); + mouse_array[event->mouse.button] |= (1 << 1); + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + mouse_array[event->mouse.button] &= ~(1 << 0); + mouse_array[event->mouse.button] |= (1 << 2); + break; + + case ALLEGRO_EVENT_MOUSE_AXES: + mx = event->mouse.x; + my = event->mouse.y; + break; + } +} + +void mouse_tick(void) +{ + /* clear pressed/released bits */ + int i; + for (i = 0; i < MOUSE_BUTTONS; i++) { + mouse_array[i] &= ~(1 << 1); + mouse_array[i] &= ~(1 << 2); + } +} diff --git a/allegro/demos/skater/src/mouse.h b/allegro/demos/skater/src/mouse.h new file mode 100644 index 00000000..fbf0e187 --- /dev/null +++ b/allegro/demos/skater/src/mouse.h @@ -0,0 +1,9 @@ +#include "global.h" + +bool mouse_button_down(int b); +bool mouse_button_pressed(int b); +int mouse_x(void); +int mouse_y(void); +/* 'mouse_event' conflicts with winuser.h */ +void mouse_handle_event(ALLEGRO_EVENT *event); +void mouse_tick(void); diff --git a/allegro/demos/skater/src/music.c b/allegro/demos/skater/src/music.c new file mode 100644 index 00000000..8309db8c --- /dev/null +++ b/allegro/demos/skater/src/music.c @@ -0,0 +1,68 @@ +#include <allegro5/allegro.h> +#include "defines.h" +#include "global.h" +#include "music.h" + +static int currently_playing = -1; +static double volume_music = 1, volume_sound = 1; + +void set_music_volume(double v) +{ + volume_music = v; + if (currently_playing == -1) return; + al_set_audio_stream_gain(demo_data[currently_playing].dat, volume_music); +} + +void set_sound_volume(double v) +{ + volume_sound = v; +} + +void play_music(int id, int loop) +{ + (void)loop; + if (!demo_data[id].dat) + return; + if (id == currently_playing) { + return; + } + stop_music(); + + al_set_audio_stream_playmode(demo_data[id].dat, + loop ? ALLEGRO_PLAYMODE_LOOP : ALLEGRO_PLAYMODE_ONCE); + + al_set_audio_stream_gain(demo_data[id].dat, volume_music); + + al_attach_audio_stream_to_mixer(demo_data[id].dat, + al_get_default_mixer()); + al_set_audio_stream_playing(demo_data[id].dat, true); + + currently_playing = id; +} + + +void stop_music(void) +{ + if (currently_playing == -1) return; + al_set_audio_stream_playing(demo_data[currently_playing].dat, false); + currently_playing = -1; +} + + +void play_sound(ALLEGRO_SAMPLE *s, int vol, int pan, int freq, int loop) +{ + int playmode = loop ? ALLEGRO_PLAYMODE_LOOP : ALLEGRO_PLAYMODE_ONCE; + if (!s) + return; + if (freq < 0) { + freq = 1000 + rand() % (-freq) + freq / 2; + } + + al_play_sample(s, volume_sound * vol / 255.0, + (pan - 128) / 128.0, freq / 1000.0, playmode, NULL); +} + +void play_sound_id(int id, int vol, int pan, int freq, int loop) +{ + play_sound(demo_data[id].dat, vol, pan, freq, loop); +} diff --git a/allegro/demos/skater/src/music.h b/allegro/demos/skater/src/music.h new file mode 100644 index 00000000..d88a9d65 --- /dev/null +++ b/allegro/demos/skater/src/music.h @@ -0,0 +1,13 @@ +#ifndef __DEMO_MUSIC_PLAYER_H__ +#define __DEMO_MUSIC_PLAYER_H__ + +#include "global.h" + +void play_music(int id, int loop); +void stop_music(void); +void play_sound(ALLEGRO_SAMPLE *s, int vol, int pan, int freq, int loop); +void play_sound_id(int id, int vol, int pan, int freq, int loop); +void set_music_volume(double v); +void set_sound_volume(double v); + +#endif /* __DEMO_MUSIC_PLAYER_H__ */ diff --git a/allegro/demos/skater/src/physics.c b/allegro/demos/skater/src/physics.c new file mode 100644 index 00000000..29ab2c40 --- /dev/null +++ b/allegro/demos/skater/src/physics.c @@ -0,0 +1,547 @@ +#include <allegro5/allegro.h> +#include <math.h> +#include "game.h" +#include "physics.h" + +/* + + FixUp is called when the player has collided with 'something' and takes + the current player's velocity and the vector normal of whatever has been + hit as arguments. + + It's job is primarily to remove whatever proportion of the velocity is + running into the surface. This means that the player's velocity ends + up running at a right angle to the normal. + + Think of a perfectly unbouncy ball falling onto a horizontal floor. + It's vertical velocity is instantly zero'd, but its horizontal velocity + is unaffected. + + FixUp does this same thing for surfaces that aren't horizontal using + the dot product. + + As a secondary function it returns the magnitude of force it has away, + which can be used to pick a 'thud' sound effect and also for friction + calculations + +*/ +static double FixUp(double *vec, double normalx, double normaly) +{ + double mul; + + if (KeyFlags & KEYFLAG_JUMPING) + KeyFlags &= ~(KEYFLAG_JUMPING | KEYFLAG_JUMP | KEYFLAG_JUMP_ISSUED); + + mul = vec[0] * normalx + vec[1] * normaly; + vec[0] -= mul * normalx; + vec[1] -= mul * normaly; + return mul; +} + +/* + + SetAngle takes a surface normal, player angle and JustDoIt flag and + decides how the player's interaction with that surface affects his + angle. + + If JustDoIt is set then the function just sets the player to be at + the angle of the normal, no questions asked. + + Otherwise the players angle is set if either: + + - the angle of the normal is close to vertical + - the angle of the normal is close to the player angle + + Note that the arguments to atan2 are adjusted so that we're thinking + in Allegro style angle measurements (i.e. 0 degrees = straight up, + increases go clockwise) rather than the usual mathematics meaning + (i.e. 0 degrees = right, increases go anticlockwise) + +*/ +static void SetAngle(double normalx, double normaly, double *a, int JustDoIt) +{ + double NewAng = atan2(normalx, -normaly); + + if (JustDoIt || ((NewAng < (ALLEGRO_PI * 0.25f)) && (NewAng >= 0)) || + ((NewAng > (-ALLEGRO_PI * 0.25f)) && (NewAng <= 0)) || + fabs(NewAng - *a) < (ALLEGRO_PI * 0.25f) + ) + *a = NewAng; +} + +/* + + DoFriction applies surface friction along an edge, taking the player's + intended direction of travel into account + + First of all it breaks movement into 'ForwardSpeed' and 'UpSpeed', both + relative to the edge - i.e. forward speed is motion parallel to the edge, + upward speed is motion perpendicular + + Then the two are adjusted according to surface friction and player input, + and finally put back together to reform the complete player velocity + +*/ +static void DoFriction(double r, struct Edge *E, double *vec) +{ + /* calculate how quickly we're currently moving parallel and perpendicular to this edge */ + double ForwardSpeed = + (vec[0] * E->b - vec[1] * E->a) / E->Material->Friction, + UpSpeed = vec[0] * E->a + vec[1] * E->b; + double FricLevel; + + (void)r; + + /* apply adjustments based on user controls */ + if (KeyFlags & KEYFLAG_LEFT) { + ForwardSpeed += Pusher; + KeyFlags |= KEYFLAG_FLIP; + } + if (KeyFlags & KEYFLAG_RIGHT) { + ForwardSpeed -= Pusher; + KeyFlags &= ~KEYFLAG_FLIP; + } + + /* apply friction as necessary */ + FricLevel = 0.05f * E->Material->Friction; + if (ForwardSpeed > 0) { + if (ForwardSpeed < FricLevel) + ForwardSpeed = 0; + else + ForwardSpeed -= FricLevel; + } else { + if (ForwardSpeed > -FricLevel) + ForwardSpeed = 0; + else + ForwardSpeed += FricLevel; + } + + /* add jump if requested */ + if ((KeyFlags & (KEYFLAG_JUMP | KEYFLAG_JUMP_ISSUED)) == KEYFLAG_JUMP) { + UpSpeed += 5.0f; + KeyFlags |= KEYFLAG_JUMP_ISSUED | KEYFLAG_JUMPING; + } + + /* put velocity back together */ + vec[0] = UpSpeed * E->a + ForwardSpeed * E->Material->Friction * E->b; + vec[1] = UpSpeed * E->b - ForwardSpeed * E->Material->Friction * E->a; +} + +/* + + RunPhysics is the centrepiece of the game simulation and is perhaps + misnamed in that it runs physics and game logic generally. + + The basic structure is: + + apply gravity and air resistance; + + while(some simulation time remains) + { + find first thing the player hits during the simulation time + + run time forward until that hit occurs + + adjust player velocity according to whatever he has hit + } + + Although some additional work needs to be done +*/ +#if 0 /* unused */ +struct QuadTreeNode *DoContinuousPhysics(struct Level *lvl, struct QuadTreeNode + *CollTree, double *pos, + double *vec, double TimeToGo, + struct Animation *PAnim) +{ + double MoveVec[2]; + double CollTime, NCollTime; + double End[2], ColPoint[2]; + void *CollPtr; + double d1, d2; + struct Edge *E; + double r; + int Contact; + struct Container *EPtr, *FirstEdge; + + /* save a small amount of time by finding the first edge here */ + CollTree = GetCollisionNode(lvl, pos, vec); + EPtr = CollTree->Contents; + while (EPtr && EPtr->Type != EDGE) + EPtr = EPtr->Next; + FirstEdge = EPtr; + + /* do collisions and reactions */ + do { + Contact = false; + + /* rounding error fixup */ + EPtr = FirstEdge; + while (EPtr) { + /* simple line test */ + d1 = + EPtr->Content.E->a * pos[0] + + EPtr->Content.E->b * pos[1] + EPtr->Content.E->c; + + if (d1 >= (-0.5f) && d1 <= 0.05f && + pos[0] >= EPtr->Content.E->Bounder.TL.Pos[0] + && pos[0] <= EPtr->Content.E->Bounder.BR.Pos[0] + && pos[1] >= EPtr->Content.E->Bounder.TL.Pos[1] + && pos[1] <= EPtr->Content.E->Bounder.BR.Pos[1] + ) { + pos[0] += EPtr->Content.E->a * (0.05f - d1); + pos[1] += EPtr->Content.E->b * (0.05f - d1); + Contact = true; + } + + EPtr = EPtr->Next; + } + + MoveVec[0] = TimeToGo * vec[0]; + MoveVec[1] = TimeToGo * vec[1]; + + CollTime = TimeToGo + 1.0f; + End[0] = pos[0] + MoveVec[0]; + End[1] = pos[1] + MoveVec[1]; + CollPtr = NULL; + + /* search for collisions */ + + /* test 1: do we hit the edge of this collision tree node? */ + if (End[0] > CollTree->Bounder.BR.Pos[0]) { + NCollTime = (End[0] - CollTree->Bounder.BR.Pos[0]) / MoveVec[0]; + if (NCollTime < CollTime) { + CollTime = NCollTime; + CollPtr = (void *)CollTree; + } + } + + if (End[0] < CollTree->Bounder.TL.Pos[0]) { + NCollTime = (End[0] - CollTree->Bounder.TL.Pos[0]) / MoveVec[0]; + if (NCollTime < CollTime) { + CollTime = NCollTime; + CollPtr = (void *)CollTree; + } + } + + if (End[1] > CollTree->Bounder.BR.Pos[1]) { + NCollTime = (End[1] - CollTree->Bounder.BR.Pos[1]) / MoveVec[1]; + if (NCollTime < CollTime) { + CollTime = NCollTime; + CollPtr = (void *)CollTree; + } + } + + if (End[1] < CollTree->Bounder.TL.Pos[1]) { + NCollTime = (End[1] - CollTree->Bounder.TL.Pos[1]) / MoveVec[1]; + if (NCollTime < CollTime) { + CollTime = NCollTime; + CollPtr = (void *)CollTree; + } + } + + /* test 2: do we hit any of the edges contained in the tree? */ + EPtr = FirstEdge; + while (EPtr) { + /* simple line test */ + d1 = + EPtr->Content.E->a * pos[0] + + EPtr->Content.E->b * pos[1] + EPtr->Content.E->c; + d2 = + EPtr->Content.E->a * End[0] + + EPtr->Content.E->b * End[1] + EPtr->Content.E->c; + if ((d1 >= (-0.05f)) && (d2 < 0)) { + NCollTime = d1 / (d1 - d2); + + ColPoint[0] = pos[0] + NCollTime * MoveVec[0]; + ColPoint[1] = pos[1] + NCollTime * MoveVec[1]; + if (ColPoint[0] >= EPtr->Content.E->Bounder.TL.Pos[0] + && ColPoint[0] <= EPtr->Content.E->Bounder.BR.Pos[0] + && ColPoint[1] >= EPtr->Content.E->Bounder.TL.Pos[1] + && ColPoint[1] <= EPtr->Content.E->Bounder.BR.Pos[1] + ) { + CollTime = NCollTime; + CollPtr = (void *)EPtr; + } + } + + /* move to next edge */ + EPtr = EPtr->Next; + } + + /* advance - apply motion and resulting friction here! */ + pos[0] += MoveVec[0] * CollTime; + pos[1] += MoveVec[1] * CollTime; + if (!Contact) + AdvanceAnimation(PAnim, 0, false); + + /* fix up */ + if (CollPtr) { + if (CollPtr == (void *)CollTree) { + CollTree = GetCollisionNode(lvl, pos, vec); + + /* find new first edge */ + EPtr = CollTree->Contents; + while (EPtr && EPtr->Type != EDGE) + EPtr = EPtr->Next; + FirstEdge = EPtr; + } else { + /* edge collision */ + E = ((struct Container *)CollPtr)->Content.E; + r = FixUp(vec, E->a, E->b); + + SetAngle(E->a, E->b, &pos[2], + (fabs(vec[0] * E->b - vec[1] * E->a) > 0.5f)); + AdvanceAnimation(PAnim, + (vec[0] * E->b - + vec[1] * E->a) * + ((KeyFlags & KEYFLAG_FLIP) ? 1.0f : -1.0f), + true); + + /* apply friction */ + DoFriction(r, E, vec); + } + } else if (!Contact) { + /* check if currently in contact with any surface. If not then do empty space movement */ + if (KeyFlags & KEYFLAG_LEFT) { + vec[0] -= 0.05f; + KeyFlags |= KEYFLAG_FLIP; + } + if (KeyFlags & KEYFLAG_RIGHT) { + vec[0] += 0.05f; + KeyFlags &= ~KEYFLAG_FLIP; + } + if (pos[2] > 0) { + pos[2] -= TimeToGo * CollTime * 0.03f; + if (pos[2] < 0) + pos[2] = 0; + } + if (pos[2] < 0) { + pos[2] += TimeToGo * CollTime * 0.03f; + if (pos[2] > 0) + pos[2] = 0; + } + } + + /* reduce time & continue */ + TimeToGo -= TimeToGo * CollTime; + } + while (TimeToGo > 0.01f); + + return CollTree; +} +#endif + +/*#define TIME_STEP 0.6f +struct QuadTreeNode *RunPhysics(struct Level *lvl, double *pos, double *vec, double TimeToGo, struct Animation *PAnim) +{ + struct QuadTreeNode *CollTree = GetCollisionNode(lvl, pos, vec); + static double TimeAccumulator = 0; + double Step; + + TimeAccumulator += TimeToGo; + + Step = fmod(TimeAccumulator, TIME_STEP); + if(Step >= 0.01f) + { + TimeAccumulator -= Step; + CollTree = DoContinuousPhysics(lvl, CollTree, pos, vec, Step, PAnim); + } + + while(TimeAccumulator > 0) + { + + vec[1] += 0.1f; + + vec[0] *= 0.997f; + vec[1] *= 0.997f; + + CollTree = DoContinuousPhysics(lvl, CollTree, pos, vec, TimeToGo, PAnim); + TimeAccumulator -= TIME_STEP; + } + + return CollTree; +}*/ +struct QuadTreeNode *RunPhysics(struct Level *lvl, double *pos, + double *vec, double TimeToGo, + struct Animation *PAnim) +{ + double MoveVec[2]; + struct QuadTreeNode *CollTree = GetCollisionNode(lvl, pos, vec); + double CollTime, NCollTime; + double End[2], ColPoint[2]; + void *CollPtr; + double d1, d2; + struct Edge *E; + double r; + int Contact; + struct Container *EPtr, *FirstEdge; + + /* Step 1: apply gravity */ + vec[1] += 0.1f; + + /* Step 2: apply atmoshperic resistance */ + vec[0] *= 0.997f; + vec[1] *= 0.997f; + + EPtr = CollTree->Contents; + while (EPtr && EPtr->Type != EDGE) + EPtr = EPtr->Next; + FirstEdge = EPtr; + + /* Step 2: do collisions and reactions */ + do { + Contact = false; + + /* rounding error fixup */ + EPtr = FirstEdge; + while (EPtr) { + /* simple line test */ + d1 = + EPtr->Content.E->a * pos[0] + + EPtr->Content.E->b * pos[1] + EPtr->Content.E->c; + + if (d1 >= (-0.5f) && d1 <= 0.05f && + pos[0] >= EPtr->Content.E->Bounder.TL.Pos[0] + && pos[0] <= EPtr->Content.E->Bounder.BR.Pos[0] + && pos[1] >= EPtr->Content.E->Bounder.TL.Pos[1] + && pos[1] <= EPtr->Content.E->Bounder.BR.Pos[1] + ) { + pos[0] += EPtr->Content.E->a * (0.05f - d1); + pos[1] += EPtr->Content.E->b * (0.05f - d1); + Contact = true; + } + + EPtr = EPtr->Next; + } + + MoveVec[0] = TimeToGo * vec[0]; + MoveVec[1] = TimeToGo * vec[1]; + + CollTime = 1.0f; + End[0] = pos[0] + MoveVec[0]; + End[1] = pos[1] + MoveVec[1]; + CollPtr = NULL; + + /* search for collisions here */ + + /* test 1: do we hit the edge of this collision tree node? */ + if (End[0] > CollTree->Bounder.BR.Pos[0]) { + NCollTime = (End[0] - CollTree->Bounder.BR.Pos[0]) / MoveVec[0]; + if (NCollTime < CollTime) { + CollTime = NCollTime; + CollPtr = (void *)CollTree; + } + } + + if (End[0] < CollTree->Bounder.TL.Pos[0]) { + NCollTime = (End[0] - CollTree->Bounder.TL.Pos[0]) / MoveVec[0]; + if (NCollTime < CollTime) { + CollTime = NCollTime; + CollPtr = (void *)CollTree; + } + } + + if (End[1] > CollTree->Bounder.BR.Pos[1]) { + NCollTime = (End[1] - CollTree->Bounder.BR.Pos[1]) / MoveVec[1]; + if (NCollTime < CollTime) { + CollTime = NCollTime; + CollPtr = (void *)CollTree; + } + } + + if (End[1] < CollTree->Bounder.TL.Pos[1]) { + NCollTime = (End[1] - CollTree->Bounder.TL.Pos[1]) / MoveVec[1]; + if (NCollTime < CollTime) { + CollTime = NCollTime; + CollPtr = (void *)CollTree; + } + } + + /* test 3: do we hit any of the edges contained in the tree? */ + EPtr = FirstEdge; + while (EPtr) { + /* simple line test */ + d1 = + EPtr->Content.E->a * pos[0] + + EPtr->Content.E->b * pos[1] + EPtr->Content.E->c; + d2 = + EPtr->Content.E->a * End[0] + + EPtr->Content.E->b * End[1] + EPtr->Content.E->c; + if ((d1 >= (-0.05f)) && (d2 < 0)) { + NCollTime = d1 / (d1 - d2); + + ColPoint[0] = pos[0] + NCollTime * MoveVec[0]; + ColPoint[1] = pos[1] + NCollTime * MoveVec[1]; + if (ColPoint[0] >= EPtr->Content.E->Bounder.TL.Pos[0] + && ColPoint[0] <= EPtr->Content.E->Bounder.BR.Pos[0] + && ColPoint[1] >= EPtr->Content.E->Bounder.TL.Pos[1] + && ColPoint[1] <= EPtr->Content.E->Bounder.BR.Pos[1] + ) { + CollTime = NCollTime; + CollPtr = (void *)EPtr; + } + } + + /* move to next edge */ + EPtr = EPtr->Next; + } + + /* advance - apply motion and resulting friction here! */ + pos[0] += MoveVec[0] * CollTime; + pos[1] += MoveVec[1] * CollTime; + if (!Contact) + AdvanceAnimation(PAnim, 0, false); + + /* fix up */ + if (CollPtr) { + if (CollPtr == (void *)CollTree) { + CollTree = GetCollisionNode(lvl, pos, vec); + EPtr = CollTree->Contents; + while (EPtr && EPtr->Type != EDGE) + EPtr = EPtr->Next; + FirstEdge = EPtr; + } else { + /* edge collision */ + E = ((struct Container *)CollPtr)->Content.E; + r = FixUp(vec, E->a, E->b); + + SetAngle(E->a, E->b, &pos[2], + (fabs(vec[0] * E->b - vec[1] * E->a) > 0.5f)); + AdvanceAnimation(PAnim, + (vec[0] * E->b - + vec[1] * E->a) * + ((KeyFlags & KEYFLAG_FLIP) ? 1.0f : -1.0f), + true); + + /* apply friction */ + DoFriction(r, E, vec); + } + } else if (!Contact) { + /* check if currently in contact with any surface. If not then do empty space movement */ + if (KeyFlags & KEYFLAG_LEFT) { + vec[0] -= 0.05f; + KeyFlags |= KEYFLAG_FLIP; + } + if (KeyFlags & KEYFLAG_RIGHT) { + vec[0] += 0.05f; + KeyFlags &= ~KEYFLAG_FLIP; + } + if (pos[2] > 0) { + pos[2] -= TimeToGo * CollTime * 0.03f; + if (pos[2] < 0) + pos[2] = 0; + } + if (pos[2] < 0) { + pos[2] += TimeToGo * CollTime * 0.03f; + if (pos[2] > 0) + pos[2] = 0; + } + } + + /* reduce time & continue */ + TimeToGo -= TimeToGo * CollTime; + } + while (TimeToGo > 0.01f); + + return CollTree; +} diff --git a/allegro/demos/skater/src/physics.h b/allegro/demos/skater/src/physics.h new file mode 100644 index 00000000..3843c3c3 --- /dev/null +++ b/allegro/demos/skater/src/physics.h @@ -0,0 +1,11 @@ +#ifndef __PHYSICS_H +#define __PHYSICS_H + +#include "anim.h" +#include "level.h" + +extern struct QuadTreeNode *RunPhysics(struct Level *lvl, double *pos, + double *vec, double TimeToGo, + struct Animation *PAnim); + +#endif diff --git a/allegro/demos/skater/src/quadtree.c b/allegro/demos/skater/src/quadtree.c new file mode 100644 index 00000000..066b5621 --- /dev/null +++ b/allegro/demos/skater/src/quadtree.c @@ -0,0 +1,764 @@ +/* + + QuadTree.c + ========== + + A quad tree is a hierarchical tree based structure. For further information + on quad trees see http://en.wikipedia.org/wiki/Quadtree + + In this code, every node has a pointer named 'Children' which is either NULL + or points to an array of four children. The children are indexed as follows: + + 0 - top left + 1 - top right + 2 - bottom left + 3 - bottom right + + This allows indexing according to a simple bitwise calculation: + + childnum = 0; + if(x > midpoint) childnum |= 1; + if(y > midpoint) childnum |= 2; + + The QuadTreeNode structs look like this: + + struct QuadTreeNode + { + struct BoundingBox Bounder; + + int NumContents; + struct Container *Contents; + + struct QuadTreeNode *Children; + }; + + BoundingBox is the axis aligned bounding box for the region of space + covered, NumContents is a count of the number of items contained in the + linked list 'Contents'. It is redundant but convenient. + + 'Children' is as explained above - NULL if this is a leaf node, otherwise + a pointer to an array of four QuadTreeNode structs that subdivide the area + of this node. +*/ + +#include <allegro5/allegro_primitives.h> +#include "level.h" +#include "global.h" + +/* + + CentreX and CentreY are macros that evaluate to the centre point of the + bounding box b + +*/ +#define CentreX(b) (((b)->TL.Pos[0]+(b)->BR.Pos[0]) * 0.5f) +#define CentreY(b) (((b)->TL.Pos[1]+(b)->BR.Pos[1]) * 0.5f) +#define ERROR_BOUNDARY 2 + +/* + + GetChild. Returns the child index for a point (qx, qy) in the bounding box + b. Uses the logic expressed in the comments at the top of this file + +*/ +static int GetChild(struct BoundingBox *b, double qx, double qy) +{ + int ret = 0; + + if (qx > CentreX(b)) + ret |= 1; + if (qy > CentreY(b)) + ret |= 2; + return ret; +} + +/* + + Get[X1/2]/[Y1/2] - if passed a child id and the bounding box of the parent, + these return the corresponding co-ordinate of the child + +*/ +static double GetX1(int child, struct BoundingBox *b) +{ + return (child & 1) ? CentreX(b) : b->TL.Pos[0]; +} +static double GetX2(int child, struct BoundingBox *b) +{ + return (child & 1) ? b->BR.Pos[0] : CentreX(b); +} +static double GetY1(int child, struct BoundingBox *b) +{ + return (child & 2) ? CentreY(b) : b->TL.Pos[1]; +} +static double GetY2(int child, struct BoundingBox *b) +{ + return (child & 2) ? b->BR.Pos[1] : CentreY(b); +} + +/* + + ToggleChildPtr[X/Y] relate to the way movement is handled by the physics + code. They use a continuous time method (see Physics.c for more details), + which means that they need to be able to calculate when a travelling point + will leave a quad tree node. + + Because there may be rounding errors close to the border, the function for + obtaining collision edges inspects velocity to determine which child a + point near the boundary is actually interested in. + + For that purpose, ToggleChildPtr[X/Y] affect which child is looked at + according to velocity. If the point is heading right it wants the right + hand side child, if it is heading down it wants the lower child, etc. + +*/ +static int ToggleChildPtrY(double yvec, int oldchild) +{ + if (((yvec > 0) && (oldchild & 2)) || ((yvec < 0) && !(oldchild & 2)) + ) + oldchild ^= 2; + return oldchild; +} + +static int ToggleChildPtrX(double xvec, int oldchild) +{ + if (((xvec > 0) && (oldchild & 1)) || ((xvec < 0) && !(oldchild & 1)) + ) + oldchild ^= 1; + return oldchild; +} + +/* + + Separated does a test on two bounding boxes to determine whether they + overlap - returning true if they don't and false if they do. + + It achieves this using the 'separating planes' algorithm, which is a general + case test that can be expressed very simply for boxes. If the leftmost point + of one box is to the right of the rightmost point of the other then they + must not overlap. + + Ditto for the topmost point of one versus the bottommost of the other and + all variations on those tests. + + These tests will catch all possible ways in which two boxes DO NOT + overlap. Therefore the only possible conclusion if they all fail is that the + boxes DO overlap. + + A small error boundary in which non-overlapping objects are returned as + overlapping anyway is coded here so that we don't get rounding problems + when doing collisions near the edge of a node + +*/ +static int Separated(struct BoundingBox *a, struct BoundingBox *b) +{ + if (a->TL.Pos[0] - ERROR_BOUNDARY > b->BR.Pos[0]) + return true; + if (a->TL.Pos[1] - ERROR_BOUNDARY > b->BR.Pos[1]) + return true; + + if (b->TL.Pos[0] - ERROR_BOUNDARY > a->BR.Pos[0]) + return true; + if (b->TL.Pos[1] - ERROR_BOUNDARY > a->BR.Pos[1]) + return true; + + return false; +} + +/* + + GENERIC QUAD TREE FUNCTIONS + +*/ + +/* + + SetupQuadTree just initiates a QuadTreeNode struct, filling its bounding + box appropriately and setting it up to have no contents and no children + +*/ +void SetupQuadTree(struct QuadTreeNode *Tree, int x1, int y1, int x2, int y2) +{ + Tree->Bounder.TL.Pos[0] = x1; + Tree->Bounder.TL.Pos[1] = y1; + Tree->Bounder.BR.Pos[0] = x2; + Tree->Bounder.BR.Pos[1] = y2; + + Tree->NumContents = 0; + Tree->Contents = Tree->PostContents = NULL; + Tree->Children = NULL; +} + +/* + + FreeQuadTree frees all the memory malloc'd to a QuadTree. It calls itself + recursively for any children + +*/ +void FreeQuadTree(struct QuadTreeNode *Tree) +{ + int c; + struct Container *CNext; + + /* + + if this node has children then free them + + */ + if (Tree->Children) { + c = 4; + while (c--) + FreeQuadTree(&Tree->Children[c]); + + free((void *)Tree->Children); + Tree->Children = NULL; + } + + /* free all edge containers stored here */ + while (Tree->Contents) { + CNext = Tree->Contents->Next; + free((void *)Tree->Contents); + Tree->Contents = CNext; + } +} + +/* + + AddContent adds new content to a QuadTreeNode. The basic steps are these: + + 1. does the new content fit into the space covered by this node? If not, + reject it + + 2. is this node subdivided? If so then pass the new content to the + children to deal with. If not then insert at this node + + 3. if inserted at this node, have we now hit the limit for items + storable at any node? If so, subdivide and pass all contents that were + stored here to the children + +*/ +static void AddContent(struct QuadTreeNode *Tree, struct Container *NewContent, + int divider) +{ + int c; + struct Container *CPtr, *Next; + + /* + + First check: does the refered new content actually overlap with this + node? If not, do nothing + + NB: this code explicitly checks the bounding box of an 'edge' held in + NewContent, even though it may hold an edge, triangle or object. This is + fine because we've set up our structs so that the bounding box + information is at the same location regardless + + */ + if (Separated(&NewContent->Content.E->Bounder, &Tree->Bounder)) + return; + + /* + + Second check: has this node been subdivided? If so, pass on for + children to deal with + + */ + if (Tree->Children) { + c = 4; + while (c--) + AddContent(&Tree->Children[c], NewContent, divider); + } else { + /* + + If we're here, then the edge really does need to be added to the + current node, so do that + + */ + Tree->NumContents++; + CPtr = Tree->Contents; + Tree->Contents = (struct Container *)malloc(sizeof(struct Container)); + Tree->Contents->Content = NewContent->Content; + Tree->Contents->Type = NewContent->Type; + Tree->Contents->Next = CPtr; + + /* + + Now check if we've hit the maximum content count for this node. If + so, subdivide + + */ + if ((Tree->NumContents == divider) + && ((Tree->Bounder.BR.Pos[0] - Tree->Bounder.TL.Pos[0]) > screen_width) + && ((Tree->Bounder.BR.Pos[1] - Tree->Bounder.TL.Pos[1]) > screen_height)) { + /* allocate new memory and set up structures */ + Tree->Children = + (struct QuadTreeNode *)malloc(sizeof(struct QuadTreeNode) + * 4); + c = 4; + while (c--) + SetupQuadTree(&Tree->Children[c], + GetX1(c, &Tree->Bounder), GetY1(c, + &Tree-> + Bounder), + GetX2(c, &Tree->Bounder), GetY2(c, &Tree->Bounder)); + + /* redistribute contents currently stored here */ + CPtr = Tree->Contents; + while (CPtr) { + Next = CPtr->Next; + + c = 4; + while (c--) + AddContent(&Tree->Children[c], CPtr, divider); + + free(CPtr); + CPtr = Next; + } + Tree->Contents = NULL; + } + } +} + +/* + + STUFF FOR DEALING WITH 'EDGES' + +*/ + + +/* + + GetNode returns the leaf node that a point is currently in from + the edge tree, for collisions & physics + +*/ +static struct QuadTreeNode *GetNode(struct QuadTreeNode *Ptr, double *pos, double *vec) +{ + int Child; + int MidX, MidY; + + /* continue moving down the tree if we aren't at a leaf */ + while (Ptr->Children) { + /* figure out which child we should prima facie be considering */ + Child = GetChild(&Ptr->Bounder, pos[0], pos[1]); + + /* toggle child according to velocity if sufficiently near the boundary */ + MidX = CentreX(&Ptr->Bounder); + MidY = CentreY(&Ptr->Bounder); + + if (abs((int)pos[0] - MidX) < ERROR_BOUNDARY) + Child = ToggleChildPtrX(vec[0], Child); + + if (abs((int)pos[1] - MidY) < ERROR_BOUNDARY) + Child = ToggleChildPtrY(vec[1], Child); + + /* and now move ourselves so that we are now looking at that child */ + Ptr = &Ptr->Children[Child]; + } + + /* return the leaf node found */ + return Ptr; +} + +struct QuadTreeNode *GetCollisionNode(struct Level *lvl, double *pos, + double *vec) +{ + return GetNode(&lvl->CollisionTree, pos, vec); +} + +/* + + STUFF FOR DEALING WITH 'TRIANGLES' + +*/ + +static void set_v(ALLEGRO_VERTEX *vt, double x, double y, double u, double v) +{ + vt->x = x; + vt->y = y; + vt->z = 0; + vt->u = u; + vt->v = v; + vt->color = al_map_rgb_f(1, 1, 1); +} + +/* + + DrawTriEdge is a drawing function that adds a textured edge to a triangle + +*/ +static void DrawTriEdge(struct Triangle *tri, struct BoundingBox *ScrBounder) +{ + ALLEGRO_VERTEX PolyEdges[4]; + int c, c2; + double x, y, w; + + /* quick bounding box check - if the triangle isn't on screen then we can + forget about it */ + if (Separated(&tri->Bounder, ScrBounder)) + return; + c = 3; + while (c--) { + c2 = (c + 1) % 3; + if (tri->EdgeFlags[c] & TRIFLAGS_EDGE) { + /* + + Texture u is determined according to world position so that + edges that should appear to meet up do. + + */ + x = tri->Edges[c]->Pos[0] - ScrBounder->TL.Pos[0]; + y = tri->Edges[c]->Pos[1] - ScrBounder->TL.Pos[1]; + w = tri->EdgeFlags[c] & TRIFLAGS_WIDTH; + set_v(PolyEdges + 0, x, y - w, tri->Edges[c]->Pos[0], 0); + set_v(PolyEdges + 3, x, y + w, tri->Edges[c]->Pos[0], al_get_bitmap_height(tri->Material->Edge)); + x = tri->Edges[c2]->Pos[0] - ScrBounder->TL.Pos[0] + 1; + y = tri->Edges[c2]->Pos[1] - ScrBounder->TL.Pos[1]; + w = tri->EdgeFlags[c2] & TRIFLAGS_WIDTH; + set_v(PolyEdges + 1, x, y - w, tri->Edges[c2]->Pos[0], 0); + set_v(PolyEdges + 2, x, y + w, tri->Edges[c2]->Pos[0], al_get_bitmap_height(tri->Material->Edge)); + + al_draw_prim(PolyEdges, NULL, tri->Material->Edge, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); + } + } +} + +static void setuv(ALLEGRO_VERTEX *v, struct BoundingBox *ScrBounder) +{ + v->u = v->x + ScrBounder->TL.Pos[0]; + v->v = v->y + ScrBounder->TL.Pos[1]; + + v->z = 0; + v->color = al_map_rgb_f(1, 1, 1); +} + +/* + + DrawTriangle is a drawing function that draws a triangle with a textured + fill + +*/ +static void DrawTriangle(struct Triangle *tri, + struct BoundingBox *ScrBounder) +{ + ALLEGRO_VERTEX v[3]; + + /* quick bounding box check - if the triangle isn't on screen then we can + forget about it */ + if (Separated(&tri->Bounder, ScrBounder)) + return; + + v[0].x = tri->Edges[0]->Pos[0] - ScrBounder->TL.Pos[0]; + v[0].y = tri->Edges[0]->Pos[1] - ScrBounder->TL.Pos[1]; + setuv(&v[0], ScrBounder); + v[1].x = tri->Edges[1]->Pos[0] - ScrBounder->TL.Pos[0]; + v[1].y = tri->Edges[1]->Pos[1] - ScrBounder->TL.Pos[1]; + setuv(&v[1], ScrBounder); + v[2].x = tri->Edges[2]->Pos[0] - ScrBounder->TL.Pos[0]; + v[2].y = tri->Edges[2]->Pos[1] - ScrBounder->TL.Pos[1]; + setuv(&v[2], ScrBounder); + + al_draw_prim(v, NULL, tri->Material->Fill, 0, 3, ALLEGRO_PRIM_TRIANGLE_STRIP); +} + +/* + + DrawObject is a drawing function that draws an object (!) + +*/ +static void DrawObject(struct Object *obj, + struct BoundingBox *ScrBounder) +{ + /* quick bounding box check - if the triangle isn't on screen then we can + forget about it */ + if (Separated(&obj->Bounder, ScrBounder)) + return; + + if (obj->Flags & OBJFLAGS_VISIBLE) + al_draw_scaled_rotated_bitmap(obj->ObjType->Image, 0, 0, + (int)(0.5f * + (obj->Bounder.TL.Pos[0] + + obj->Bounder.BR.Pos[0]) - + ScrBounder->TL.Pos[0]) - + (al_get_bitmap_width(obj->ObjType->Image) >> 1), + (int)(0.5f * + (obj->Bounder.TL.Pos[1] + + obj->Bounder.BR.Pos[1]) - + ScrBounder->TL.Pos[1]) - + (al_get_bitmap_height(obj->ObjType->Image) >> 1), + 1, 1, + obj->Angle, 0); +} + +/* + + DrawTriangleTree does the 'hard' work of actually drawing the contents of a + quad tree. If you've understood how the quad tree is made up and works from + all the other comments in this file then it is very straightforward and easy + to follow. + + The only point of interest here is 'framec' - an integer that identifies the + current frame. + + The problem that necessitates it is that a single screen may cover multiple + leaf nodes, and that some triangles may be present in more than one of those + nodes. We don't want to expend energy drawing those triangles twice. + + To resolve this, every triangle keeps a note of the frame in which it was + last drawn. If that frame is not this frame then it is drawn and that note + is updated. + + The 'clever' thing about this is that it kills the overdraw without any per + frame seeding of triangles. The disadvantage is that any triangle which + doesn't appear on screen for exactly as long as it takes the framec integer + to overflow then does will not be drawn for one frame. + + Assuming 100 fps and a 32bit CPU, this bug can in the unlikely situation + that it does occur, only happen after approximately 1.36 years of + continuous gameplay. It is therefore submitted that it shouldn't be of high + concern! + + Calculations: + + 2^32 = 4,294,967,296 + /100 = 4,294,967.296 seconds + /60 = 715,827.883 minutes + /60 = 11,930.465 hours + /24 = 497.103 days + /365.25 = 1.36 years + +*/ +static void GetQuadTreeVisibilityList(struct QuadTreeNode *TriTree, + struct Level *Lvl, + struct BoundingBox *ScrBounder) +{ + int c; + + /* + + if the view window doesn't overlap this node then do nothing + + */ + if (Separated(&TriTree->Bounder, ScrBounder)) + return; + + /* + + if this node has children, consider them instead + + */ + if (TriTree->Children) { + c = 4; + while (c--) + GetQuadTreeVisibilityList(&TriTree->Children[c], Lvl, ScrBounder); + } else { + /* + + otherwise, add to draw list + + */ + TriTree->Next = Lvl->VisibleList; + Lvl->VisibleList = TriTree; + } +} + +static void DrawQuadTreePart(struct Level *Lvl, + struct BoundingBox *ScrBounder, + unsigned int framec, int PostContents) +{ + struct Container *Thing, *TriStart; + struct QuadTreeNode *Visible; + + /* go through each node drawing background details - objects first, then polygons, finally edges */ + Visible = Lvl->VisibleList; + while (Visible) { + /* + + objects + + */ + Thing = PostContents ? Visible->PostContents : Visible->Contents; + while (Thing && Thing->Type == OBJECT) { + if (Thing->Content.O->LastFrame != framec) { + DrawObject(Thing->Content.O, ScrBounder); + Thing->Content.O->LastFrame = framec; + } + Thing = Thing->Next; + } + + TriStart = Thing; + while (Thing) { + if (Thing->Content.T->LastFrame != framec) + DrawTriangle(Thing->Content.T, ScrBounder); + Thing = Thing->Next; + } + + /* + + and add edges that haven't already been drawn this frame, this time + updating the note of the last frame in which this triangle was + drawn + + */ + Thing = TriStart; + while (Thing) { + if (Thing->Content.T->LastFrame != framec) { + DrawTriEdge(Thing->Content.T, ScrBounder); + Thing->Content.T->LastFrame = framec; + } + Thing = Thing->Next; + } + + Visible = Visible->Next; + } +} + +void BeginQuadTreeDraw(struct Level *Lvl, + struct QuadTreeNode *TriTree, + struct BoundingBox *ScrBounder, unsigned int framec) +{ + /* compile list of visible nodes */ + Lvl->VisibleList = NULL; + GetQuadTreeVisibilityList(TriTree, Lvl, ScrBounder); + DrawQuadTreePart(Lvl, ScrBounder, framec, false); +} + +void EndQuadTreeDraw(struct Level *Lvl, + struct BoundingBox *ScrBounder, unsigned int framec) +{ + DrawQuadTreePart(Lvl, ScrBounder, framec, true); +} + +/* + + FUNCTIONS FOR ADDING CONTENT + +*/ +#define MAX_COLL 200 +#define MAX_DISP 50 + +/* + + AddTriangle and AddEdge are both very similar indeed and just package the + new triangle or edge into a 'Container' so that the AddContent function + knows how to deal with them in a unified manner. + +*/ + +void AddTriangle(struct Level *level, struct Triangle *NewTri) +{ + struct Container Cont; + + Cont.Content.T = NewTri; + Cont.Type = TRIANGLE; + AddContent(&level->DisplayTree, &Cont, MAX_DISP); +} + +void AddEdge(struct Level *level, struct Edge *NewEdge) +{ + struct Container Cont; + + Cont.Content.E = NewEdge; + Cont.Type = EDGE; + AddContent(&level->CollisionTree, &Cont, MAX_COLL); +} + +void AddObject(struct Level *level, struct Object *NewObject, int DisplayTree) +{ + struct Container Cont; + + Cont.Content.O = NewObject; + Cont.Type = OBJECT; + + if (DisplayTree) { + if (NewObject->Flags & OBJFLAGS_VISIBLE) + AddContent(&level->DisplayTree, &Cont, MAX_DISP); + } else { + if (NewObject->Flags & FLAGS_COLLIDABLE) + AddContent(&level->CollisionTree, &Cont, MAX_COLL); + } +} + +/* + + OrderTree sorts the items stored within Tree so that their lists + consist of all their non-objects (i.e. triangles or edges) first + followed by all of their objects. + +*/ +void SplitTree(struct QuadTreeNode *Tree) +{ + struct Container *P, *PNext; + int c = 4; + + if (Tree->Children) { + while (c--) + SplitTree(&Tree->Children[c]); + } else if (Tree->Contents) { + P = Tree->Contents; + Tree->Contents = Tree->PostContents = NULL; + + while (P) { + PNext = P->Next; + + if (P->Type == OBJECT) { + if (P->Content.O->Flags & FLAGS_FOREGROUND) { + P->Next = Tree->PostContents; + Tree->PostContents = P; + } else { + P->Next = Tree->Contents; + Tree->Contents = P; + } + } else { + if ((P->Content.T->EdgeFlags[0] | P->Content.T-> + EdgeFlags[1] | P->Content.T->EdgeFlags[2]) + & FLAGS_FOREGROUND) { + P->Next = Tree->PostContents; + Tree->PostContents = P; + } else { + P->Next = Tree->Contents; + Tree->Contents = P; + } + } + + P = PNext; + } + } +} + +void OrderTree(struct QuadTreeNode *Tree, int PostTree) +{ + struct Container *Objects, *NonObjects, *P, *PNext, **ITree; + int c = 4; + + if (Tree->Children) { + while (c--) + OrderTree(&Tree->Children[c], PostTree); + } else { + ITree = PostTree ? &Tree->PostContents : &Tree->Contents; + + if (*ITree) { + /* separate object and non-oject lists */ + Objects = NonObjects = NULL; + P = *ITree; + while (P) { + PNext = P->Next; + + if (P->Type == OBJECT) { + P->Next = Objects; + Objects = P; + } else { + P->Next = NonObjects; + NonObjects = P; + } + + P = PNext; + } + + /* now reintegrate lists - objects then non-objects */ + *ITree = Objects; + while (*ITree) + ITree = &(*ITree)->Next; + *ITree = NonObjects; + } + } +} diff --git a/allegro/demos/skater/src/quadtree.h b/allegro/demos/skater/src/quadtree.h new file mode 100644 index 00000000..a164ad64 --- /dev/null +++ b/allegro/demos/skater/src/quadtree.h @@ -0,0 +1,148 @@ +#ifndef __QUADTREES_H +#define __QUADTREES_H + +#include "global.h" + +#define TRIFLAGS_WIDTH 0x07f +#define TRIFLAGS_EDGE 0x080 + +#define OBJFLAGS_VISIBLE 0x001 +#define OBJFLAGS_DOOR 0x002 + +#define FLAGS_COLLIDABLE 0x100 +#define FLAGS_FOREGROUND 0x200 + +struct Material { + ALLEGRO_BITMAP *Edge, *Fill; + double Friction; + struct Material *Next; +}; + +struct Vertex { + double Pos[2]; + double Normal[2]; + struct Edge *Edges[2]; + struct Vertex *Next; +}; + +struct SmallVertex { + double Pos[2]; +}; + +struct BoundingBox { + struct SmallVertex TL, BR; +}; + +struct Triangle { + struct BoundingBox Bounder; + struct Material *Material; + struct Triangle *Next; + + struct Vertex *Edges[3]; + unsigned int EdgeFlags[3]; + + unsigned int LastFrame; +}; + +struct ObjectType { + ALLEGRO_BITMAP *Image; + ALLEGRO_SAMPLE *CollectNoise; + int Radius; + + struct ObjectType *Next; +}; + +struct Object { + struct BoundingBox Bounder; + struct ObjectType *ObjType; + + double Pos[2]; + unsigned int Flags; + double Angle; + unsigned int LastFrame; + + struct Object *Next; +}; + +struct Edge { + struct BoundingBox Bounder; + struct Material *Material; + struct Edge *Next; + + /* equation of the edge, as in a*x + b*y + c = 0 */ + double a, b, c; + + /* pointers to the vertices that create this edge */ + struct Vertex *EndPoints[2]; +}; + +/* containers for the two previous elements, used to build lists at tree nodes */ +struct Container { + struct Container *Next; + + enum { TRIANGLE, OBJECT, EDGE } Type; + union { + struct Edge *E; + struct Triangle *T; + struct Object *O; + } Content; +}; + +/* quadtrees of containers */ +struct QuadTreeNode { + struct BoundingBox Bounder; + + int NumContents; + struct Container *Contents; + struct Container *PostContents; + + struct QuadTreeNode *Children; + + struct QuadTreeNode *Next; +}; + +/* level structure, connecting it all */ +struct Level { + struct QuadTreeNode DisplayTree, *VisibleList; + struct QuadTreeNode CollisionTree; + + double PlayerStartPos[2]; + int TotalObjects, ObjectsRequired; + struct LevelState *InitialState; + + struct ObjectType *AllObjectTypes, Door; + struct Material *AllMats; + + struct Vertex *AllVerts; + struct Edge *AllEdges; + + struct Triangle *AllTris; + struct Object *AllObjects; + + ALLEGRO_BITMAP *DoorOpen, *DoorShut; +}; + + +extern void SetupQuadTree(struct QuadTreeNode *Tree, int x1, int y1, + int x2, int y2); +extern void FreeQuadTree(struct QuadTreeNode *Tree); + +extern void BeginQuadTreeDraw(struct Level *Lvl, + struct QuadTreeNode *TriTree, + struct BoundingBox *ScrBounder, + unsigned int framec); +extern void EndQuadTreeDraw(struct Level *Lvl, + struct BoundingBox *ScrBounder, + unsigned int framec); +extern struct QuadTreeNode *GetCollisionNode(struct Level *lev, double *pos, + double *vec); + +extern void AddTriangle(struct Level *Level, struct Triangle *NewTri); +extern void AddEdge(struct Level *level, struct Edge *NewEdge); +extern void AddObject(struct Level *level, struct Object *NewObject, + int DisplayTree); + +extern void SplitTree(struct QuadTreeNode *Tree); +extern void OrderTree(struct QuadTreeNode *Tree, int PostTree); + +#endif diff --git a/allegro/demos/skater/src/screenshot.c b/allegro/demos/skater/src/screenshot.c new file mode 100644 index 00000000..4928ac57 --- /dev/null +++ b/allegro/demos/skater/src/screenshot.c @@ -0,0 +1,66 @@ +/* Module for taking screenshots for Allegro games - implementation. + Written by Miran Amon. +*/ + +#include <allegro5/allegro.h> +#include <stdio.h> +#include "global.h" +#include "screenshot.h" + +static void next_screenshot(SCREENSHOT * ss) +{ + char buf[64]; + + ss->counter++; + if (ss->counter >= 10000) { + ss->counter = 0; + return; + } + + snprintf(buf, sizeof(buf), "%s%04d.%s", ss->name, ss->counter, ss->ext); + if (al_filename_exists(buf)) { + next_screenshot(ss); + } +} + + +SCREENSHOT *create_screenshot(char *name, char *ext) +{ + SCREENSHOT *ret = (SCREENSHOT *) malloc(sizeof(SCREENSHOT)); + + ret->name = strdup(name); + ret->ext = strdup(ext); + ret->counter = -1; + next_screenshot(ret); + + return ret; +} + + +void destroy_screenshot(SCREENSHOT * ss) +{ + free(ss->name); + ss->name = NULL; + free(ss->ext); + ss->ext = NULL; + free(ss); + ss = NULL; +} + + +void take_screenshot(SCREENSHOT * ss) +{ + char buf[64]; + ALLEGRO_BITMAP *bmp2 = NULL; + + snprintf(buf, sizeof(buf), "%s%04d.%s", ss->name, ss->counter, ss->ext); + + bmp2 = al_create_bitmap(screen_width, screen_height); + al_set_target_bitmap(bmp2); + al_draw_bitmap(al_get_backbuffer(screen), 0, 0, 0); + al_set_target_backbuffer(screen); + al_save_bitmap(buf, bmp2); + al_destroy_bitmap(bmp2); + + next_screenshot(ss); +} diff --git a/allegro/demos/skater/src/screenshot.h b/allegro/demos/skater/src/screenshot.h new file mode 100644 index 00000000..d2c5ad6d --- /dev/null +++ b/allegro/demos/skater/src/screenshot.h @@ -0,0 +1,81 @@ +/* Module for taking screenshots for Allegro games. + Written by Miran Amon. + version: 1.01 + date: 27. June 2003 +*/ + +#ifndef SCREENSHOT_H +#define SCREENSHOT_H + +#include <allegro5/allegro.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/* The structure that actually takes screenshots and counts them. The user + should create an instance of this structure with create_screenshot() + and destroy it with destroy_screenshot(). The user should not use the + contents of the structure directly, the functions for manipulating with + the screenshot structure should be used instead. +*/ + typedef struct SCREENSHOT { + int counter; + char *name; + char *ext; + } SCREENSHOT; + + +/* Creates an instance of the screenshot structure and initializes it. The user + should call this function somewhere at the beginning of the program and + use the value it returns to take screenshots. This function makes sure + previously made screenshots will not be overwritten. + + Parameters: + char *name - the base of the name for the screenshots; actual names + will have their number appended to them; typically the name + should have no more than 4 characters (for compatibility) + char *ext - extension of the screenshot bitmaps; typically this should + be either bmp, pcx, tga or lbm, anything else will fail to + produce screenshots unless you have and addon library that + integrates itself with save_bitmap() + + Returns: + SCREENSHOT *ss - an instance of the SCREENSHOT structure +*/ + SCREENSHOT *create_screenshot(char *name, char *ext); + + +/* Destroys an SCREENSHOT object. The user should call this function + when he's done taking screenshots, i.e. at the end of the program. + + Parameters: + SCREENSHOT *ss - a pointer to an SCREENSHOT object + + Returns: + nothing +*/ + void destroy_screenshot(SCREENSHOT * ss); + + +/* Takes a screenshot and saves it to a file. + + Parameters: + SCREENSHOT *ss - a pointer to an SCREENSHOT object + ALLEGRO_BITMAP *buffer - the bitmap from which we take a screenshot; this can be + the screen bitmap but taking screenshots from video + bitmaps like the screen is a bit slower so if you use a + memory double buferring system you should pass your + buffer to this function instead + + Returns: + nothing +*/ + void take_screenshot(SCREENSHOT * ss); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/allegro/demos/skater/src/skater.c b/allegro/demos/skater/src/skater.c new file mode 100644 index 00000000..787954d2 --- /dev/null +++ b/allegro/demos/skater/src/skater.c @@ -0,0 +1,37 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Demo game. + * + * By Miran Amon, Nick Davies, Elias Pschernig, Thomas Harte, + * Jakub Wasilewski. + * + * See readme.txt for copyright information. + */ + +#include <allegro5/allegro.h> +#include "framework.h" + + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + if (init_framework() != DEMO_OK) { + return 1; + } + + run_framework(); + shutdown_framework(); + + return 0; +} + diff --git a/allegro/demos/skater/src/token.c b/allegro/demos/skater/src/token.c new file mode 100644 index 00000000..1307a3ad --- /dev/null +++ b/allegro/demos/skater/src/token.c @@ -0,0 +1,250 @@ +#include <allegro5/allegro.h> +#include <stdlib.h> +#include <string.h> +#include "token.h" + +/* declarations of these variables - see token.h for comments on their meaning */ +int Error, Lines; +char ErrorText[1024]; +struct Tok Token; +ALLEGRO_FILE *input = NULL; + +static int my_ungetc_c = -1; + +/* + + OVERARCHING NOTES ON THE LEVEL PARSER + ------------------------------------- + + We're using something a lot like a recursive descent parser here except that + it never actually needs to recurse. It is typified by knowing a bunch of + tokens (which are not necessarily individual characters but may be lumps of + characters that make sense together - e.g. 'a number' might be a recognised + token and 2345 is a number) and two functions: + + GetToken - reads a new token from the input. + + ExpectToken - calls GetToken, checks if the token is the one expected and + if not flags up an error. + + A bunch of other functions call these two to read the file input, according + to what it was decided it should look like. Suppose we want a C-style list + of numbers that looks like this: + + { 1, 2, 3, ... } + + Then we might write the function: + + ExpectToken( '{' ); + while(1) + { + ExpectToken( number ); + GetToken(); + switch(token) + { + default: flag an error; return; + case '}': return; + case ',': break; + } + } + +*/ + +/* + + Two macros - + + whitespace(v) evaluates to non-zero if 'v' is a character considered to + be whitespace (i.e. a space, newline, carriage return or tab) + + breaker(v) evaluates to non-zero if 'v' is a character that indicates + one of the longer tokens (e.g. a number) is over + +*/ +#define whitespace(v) ((v == ' ') || (v == '\r') || (v == '\n') || (v == '\t')) +#define breaker(v) (whitespace(v) || (v == '{') || (v == '}') || (v == ',')) + + +/* + + my_fgetc is a direct replacement for fgetc that takes the same parameters + and returns the same result but counts lines while it goes. + + There is a slight complication here because of the different line endings + used by different operating systems. The code will accept a newline or a + carriage return or both in either order. But if a series of alternating + new lines and carriage returns is found then they are bundled together + in pairs for line counting. + + E.g. + + \r - 1 line ending + \n - 1 line ending + \n\r - 1 line ending + \r\n\r\n - 2 line endings + \r\r - 2 line endings + +*/ +static int my_fgetc(ALLEGRO_FILE * f) +{ + static int LastChar = '\0'; + int r; + char TestChar; + + if (my_ungetc_c != -1) { + r = my_ungetc_c; + my_ungetc_c = -1; + } + else + r = al_fgetc(f); + + if (r == '\n' || r == '\r') { + TestChar = (r == '\n') ? '\r' : '\n'; + + if (LastChar != TestChar) { + Lines++; + LastChar = r; + } else + LastChar = '\0'; + } else + LastChar = r; + + return r; +} + +/* + Hackish way to ungetc a single character. +*/ +static void my_ungetc(int c) +{ + my_ungetc_c = c; +} + +/* + + GetTokenInner is the guts of GetToken - it reads characters from the input + file and tokenises them + +*/ + +static void GetTokenInner(void) +{ + char *Ptr = Token.Text; + + /* filter leading whitespace */ + do { + *Ptr = my_fgetc(input); + } while (whitespace(*Ptr)); + + /* check whether the token can be recognised from the first character alone. + This is possible if the token is any of the single character tokens (i.e. + { } and ,) a comment or a string (i.e. begins with a quote) */ + if (*Ptr == '{') { + Token.Type = TK_OPENBRACE; + return; + } + + if (*Ptr == '}') { + Token.Type = TK_CLOSEBRACE; + return; + } + + if (*Ptr == ',') { + Token.Type = TK_COMMA; + return; + } + + if (*Ptr == '\"') { + Token.Type = TK_STRING; + /* if this is a string then read until EOF or the next quote. In + ensuring that we don't overrun the available string storage in the + Tok struct an extra potential error condition is invoked */ + do { + *Ptr++ = my_fgetc(input); + } while (Ptr[-1] != '\"' && !al_feof(input) + && (Ptr - Token.Text) < 256); + Ptr[-1] = '\0'; + if (al_feof(input) || (strlen(Token.Text) == 255)) + Error = 1; + return; + } + + if (*Ptr == '#') { + Token.Type = TK_COMMENT; + /* comments run to end of line, so find the next \r or \n */ + do { + *Ptr++ = my_fgetc(input); + } while (Ptr[-1] != '\r' && Ptr[-1] != '\n'); + Ptr[-1] = '\0'; + return; + } + + Ptr++; + *Ptr = '\0'; + + /* if we're here, the token was not recognisable from the first character + alone, meaning it is either a number or ill formed */ + while (1) { + char newc = my_fgetc(input); /* read new character */ + + /* check if this is a terminator or we have hit end of file as in either + circumstance we should check if what we have makes a valid number */ + if (breaker(newc) || al_feof(input)) { + /* check first if we have a valid integer quantity. If so fill + IQuantity with that and cast to double for FQuantity */ + char *eptr; + + my_ungetc(newc); + Token.IQuantity = strtol(Token.Text, &eptr, 0); + if (!*eptr) { + Token.Type = TK_NUMBER; + Token.FQuantity = (float)Token.IQuantity; + return; + } + + /* if not, check if we have a valid floating point quantity. If + so, fill FQuantity with that and cast to int for IQuantity */ + Token.FQuantity = (float)strtod(Token.Text, &eptr); + if (!*eptr) { + Token.Type = TK_NUMBER; + Token.IQuantity = (int)Token.FQuantity; + return; + } + + /* if what we have doesn't make integer or floating point sense + then this section of the file appears not to be a valid token */ + Token.Type = TK_UNKNOWN; + return; + } + + *Ptr++ = newc; + *Ptr = '\0'; + } +} + +/* + + GetToken is a wrapper for GetTokenInner that discards comments + +*/ +void GetToken(void) +{ + while (1) { + GetTokenInner(); + if (Token.Type != TK_COMMENT) + return; + } +} + +/* + + ExpectToken calls GetToken and then compares to the specified type, setting + an error if the found token does not match the expected type + +*/ +void ExpectToken(enum TokenTypes Type) +{ + GetToken(); + if (Token.Type != Type) + Error = 1; +} diff --git a/allegro/demos/skater/src/token.h b/allegro/demos/skater/src/token.h new file mode 100644 index 00000000..c9dba1a7 --- /dev/null +++ b/allegro/demos/skater/src/token.h @@ -0,0 +1,87 @@ +/* + * tkeniser.h + * Allegro Demo Game + * + * Created by Thomas Harte on 18/07/2005. + * Copyright 2005 __MyCompanyName__. All rights reserved. + * + */ + +#ifndef __TOKENISER_H +#define __TOKENISER_H + +#include <stdio.h> + +/* + + Level loading related variables - + + Lines is a count of the number of lines of text that have been parsed from + the source level file. It is used for error reporting where necessary. + + Error is an error flag. If it is set to non-zero then some error occurred. + + ErrorText is a textual description of the error that has occurred in level + loading. It is set initially to be an empty string, and if an error is + flagged but an error string not provided then the user gets an "Unspecified + error" + +*/ +extern int Error, Lines; +extern char ErrorText[1024]; + +/* + + TokenTypes gives a complete list of all the tokens that the parser can + understand from a file. Most are self explanatory but nevertheless: + + TK_OPENBRACE - the { character + TK_CLOSEBRACE - the } character + TK_COMMA - the , character + + TK_STRING - a section of text enclosed in quotes, e.g. "hello" + TK_NUMBER - a number in any C standard format, integer or + floating point (e.g. 97, 012, 0x8 or 23.6f) + TK_COMMENT - a comment, which begins with a hash and then runs + to the end of line + + TK_UNKNOWN - something the parser didn't really understand + +*/ +enum TokenTypes { + TK_OPENBRACE, TK_CLOSEBRACE, TK_COMMA, + + TK_STRING, TK_NUMBER, TK_COMMENT, + + TK_UNKNOWN +}; + +/* + + struct Tok holds a Token. It is straightforward. + + 'Type' holds the token type. + + 'Text' holds the characters read from the file and taken to be the token + unless the token is taken to be a string, in which case the surrounding + quotes are removed + + In the case that a number is found, FQuantity holds a floating point value + and IQuantity holds an integer value + +*/ +struct Tok { + enum TokenTypes Type; + + char Text[256]; + double FQuantity; + int IQuantity; +}; + +extern struct Tok Token; +extern ALLEGRO_FILE *input; /* the file from which level input is read */ + +extern void GetToken(void); +extern void ExpectToken(enum TokenTypes Type); + +#endif diff --git a/allegro/demos/skater/src/transition.c b/allegro/demos/skater/src/transition.c new file mode 100644 index 00000000..1f489ed3 --- /dev/null +++ b/allegro/demos/skater/src/transition.c @@ -0,0 +1,74 @@ +#include <allegro5/allegro.h> +#include "global.h" +#include "transition.h" + + +TRANSITION *create_transition(GAMESTATE * from, GAMESTATE * to, + double duration) +{ + TRANSITION *t = malloc(sizeof(TRANSITION)); + + t->from = from; + t->to = to; + t->duration = duration; + t->progress = 0.0f; + + t->from_bmp = al_create_bitmap(screen_width, screen_height); + al_set_target_bitmap(t->from_bmp); + if (from) { + from->draw(); + } else { + al_clear_to_color(al_map_rgb(0, 0, 0)); + } + al_set_target_backbuffer(screen); + + t->to_bmp = al_create_bitmap(screen_width, screen_height); + al_set_target_bitmap(t->to_bmp); + + if (to) { + to->draw(); + } else { + al_clear_to_color(al_map_rgb(0, 0, 0)); + } + al_set_target_backbuffer(screen); + + return t; +} + + +void destroy_transition(TRANSITION * t) +{ + if (t->from_bmp) { + al_destroy_bitmap(t->from_bmp); + t->from_bmp = NULL; + } + + if (t->to_bmp) { + al_destroy_bitmap(t->to_bmp); + t->from_bmp = NULL; + } + + free(t); + t = NULL; +} + + +int update_transition(TRANSITION * t) +{ + t->progress += 1.0f / logic_framerate; + + if (t->progress >= t->duration) { + return 0; + } else { + return 1; + } +} + + +void draw_transition(TRANSITION * t) +{ + int y = (int)(t->progress * screen_height / t->duration); + + al_draw_bitmap_region(t->to_bmp, 0, screen_height - y, screen_width, y, 0, 0, 0); + al_draw_bitmap_region(t->from_bmp, 0, 0, screen_width, screen_height - y, 0, y, 0); +} diff --git a/allegro/demos/skater/src/transition.h b/allegro/demos/skater/src/transition.h new file mode 100644 index 00000000..17e8e213 --- /dev/null +++ b/allegro/demos/skater/src/transition.h @@ -0,0 +1,24 @@ +#ifndef __DEMO_TRANSITION_H__ +#define __DEMO_TRANSITION_H__ + +#include <allegro5/allegro.h> +#include "gamestate.h" /* gamestate.h */ + + +typedef struct TRANSITION { + GAMESTATE *from; + GAMESTATE *to; + double duration; + double progress; + ALLEGRO_BITMAP *from_bmp; + ALLEGRO_BITMAP *to_bmp; +} TRANSITION; + + +TRANSITION *create_transition(GAMESTATE * from, GAMESTATE * to, + double duration); +void destroy_transition(TRANSITION * t); +int update_transition(TRANSITION * t); +void draw_transition(TRANSITION * t); + +#endif /* __DEMO_TRANSITION_H__ */ diff --git a/allegro/demos/skater/src/vcontroller.c b/allegro/demos/skater/src/vcontroller.c new file mode 100644 index 00000000..2a295adc --- /dev/null +++ b/allegro/demos/skater/src/vcontroller.c @@ -0,0 +1,26 @@ +#include <allegro5/allegro.h> +#include <stdlib.h> +#include "vcontroller.h" + + +void destroy_vcontroller(VCONTROLLER * controller, const char *config_path) +{ + if (controller == 0) { + return; + } + + /* save assignments */ + if (controller->write_config != 0) { + controller->write_config(controller, config_path); + } + + /* free private data */ + if (controller->private_data != 0) { + free(controller->private_data); + controller->private_data = 0; + } + + /* free the actual pointer */ + free(controller); + controller = 0; +} diff --git a/allegro/demos/skater/src/vcontroller.h b/allegro/demos/skater/src/vcontroller.h new file mode 100644 index 00000000..07e159c5 --- /dev/null +++ b/allegro/demos/skater/src/vcontroller.h @@ -0,0 +1,65 @@ +#ifndef __DEMO_VCONTROLLER_H__ +#define __DEMO_VCONTROLLER_H__ + +/* + Structure that defines a virtual controller. A virtual controller is + an abstraction of physical controllers such as kyboards, mice, gamepads, + joysticks, etc. to make them more easily manageable. This particular + implementation supports up to 8 digital buttons, but can easily be + expanded to support analogue axes as well. Each implementation of an + actual controller should implement all the functions in this struct. + Each function is passed a pointer to the associated object, a bit + like the implicit this pointer in C++ classes. +*/ + +typedef struct VCONTROLLER VCONTROLLER; + +struct VCONTROLLER { + /* Status of each of the 8 virtual buttons. Virtual controllers should + update this array in the poll function and the user programmer + should read them in order to gather input. */ + int button[8]; + + /* Pointer to some private internal data that each controller may use. + Note: perhaps a cleaner implementation would be to let each controller + use static variables instead. */ + void *private_data; + + /* Polls the underlying physical controller and updates the + buttons array. */ + void (*poll) (VCONTROLLER *); + + /* Reads button assignments (and any other settings) from a config file. */ + void (*read_config) (VCONTROLLER *, const char *); + + /* Writes button assignments (and any other settings) to a config file. */ + void (*write_config) (VCONTROLLER *, const char *); + + /* Supposed to calibrate the specified button. Returns 0 if the button + has not been calibrated and non-zero as soon as it is. The user + programmer should call this function in a loop until it returns non + zero or button calibration has been canceled in some way. */ + int (*calibrate_button) (VCONTROLLER *, int); + + /* Returns a short description of the specified button that may be + used in the user interface (for example). */ + const char *(*get_button_description) (VCONTROLLER *, int); +}; + + +/* + Destroys the given controller, frees memory and writes button assignments + to the config file. + + Parameters: + VCONTROLLER *controller - The pointer to be destroyed. + char *config_path - Path to the config file where settings should + be written. + + Returns: + nothing +*/ +void destroy_vcontroller(VCONTROLLER * controller, + const char *config_path); + +#endif /* __DEMO_VCONTROLLER_H__ */ diff --git a/allegro/demos/speed/29.txt b/allegro/demos/speed/29.txt new file mode 100644 index 00000000..abdbb817 --- /dev/null +++ b/allegro/demos/speed/29.txt @@ -0,0 +1,36 @@ + +The competition rules state that I must "include the number '29' somewhere +in the program" (to commemorate it being Arron's birthday). But +unfortunately, although the number 29 is certainly a very fine thing to have +as the age for an Arron, it didn't strike me as a particularly useful or +numerologically significant thing to build into a computer game. + +However, since the rules do not specify which number base they are talking +about, it occurs to me that this could just as well be a reference to the +hexadecimal value 0x29, which is decimal 41. Admittedly, this number has +nothing to do with the age of the Arron, or at least won't do for another +dozen dozens of quartets of weeks, but the rules never actually spell out +that they are talking about the particular 29 which happens to be his +current age (they strongly imply that, but I decided to look the other way +and miss this hint :-) + +Now, 0x29, when mapped onto the ASCII character set, refers to the closing +bracket character, ')'. So in order to comply with the competition rules, I +have included several of these symbols in my program. In fact, as reported +by the command: + + sed -e "s/[^)]//g" *.[ch] | tr -d "\n" | wc -c + +there are currently no less than ONE THOUSAND AND EIGHTY TWO unique +occurrences of a twenty nine in this game! This figure is likely to have +increased even further by the time you get hold of the code, since I haven't +quite finished writing it yet. And there are four more just in this text +file, so if you included the documentation in the above search command, that +would get you up to a total of 1086 different ')' characters! (and since I +just typed another there, that makes it 1087 (and having opened a bracket to +interject this, I'm going to have to close it, which makes 1088 (and now +that I've opened a nested bracket, we are up to 1089 or something, I'm +losing count here))) (btw. I hope I got the right number of closes there). + +I'm tempted to say that this is all a joke :-) except that by doing so, I've +just bumped up the count one more... diff --git a/allegro/demos/speed/CMakeLists.txt b/allegro/demos/speed/CMakeLists.txt new file mode 100644 index 00000000..bf1850c4 --- /dev/null +++ b/allegro/demos/speed/CMakeLists.txt @@ -0,0 +1,68 @@ +# Prefer local headers to system directories. +include_directories( + ${PROJECT_SOURCE_DIR}/addons/main + ${PROJECT_SOURCE_DIR}/addons/audio + ${PROJECT_SOURCE_DIR}/addons/font + ${PROJECT_SOURCE_DIR}/addons/primitives + ) + +set(SPEED_SRCS + a4_aux.c + badguys.c + bullets.c + explode.c + hiscore.c + main.c + message.c + player.c + sound.c + title.c + view.c + ) + +if(NOT SUPPORT_AUDIO OR NOT SUPPORT_PRIMITIVES OR NOT SUPPORT_FONT) + message(STATUS "Not building SPEED") + return() +endif() + +if(COMPILER_GCC_OR_CLANG) + set(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} -Wno-strict-prototypes -Wno-missing-prototypes") +endif(COMPILER_GCC_OR_CLANG) + +if(ANDROID) + add_android_app(speed + "${SPEED_SRCS}" + ) + return() +endif(ANDROID) + +if(APPLE) + set(DEMO_EXECUTABLE_TYPE MACOSX_BUNDLE) +else(APPLE) + set(DEMO_EXECUTABLE_TYPE "${EXECUTABLE_TYPE}") +endif(APPLE) + +add_executable(speed ${DEMO_EXECUTABLE_TYPE} ${SPEED_SRCS}) + +fix_executable(speed) + +if(WANT_MONOLITH) + target_link_libraries(speed + ${ALLEGRO_MONOLITH_LINK_WITH} + ) +else(WANT_MONOLITH) + target_link_libraries(speed + ${ALLEGRO_MAIN_LINK_WITH} + ${AUDIO_LINK_WITH} + ${PRIMITIVES_LINK_WITH} + ${FONT_LINK_WITH} + ) +endif(WANT_MONOLITH) + +if(NOT BUILD_SHARED_LIBS) + set_target_properties(speed PROPERTIES COMPILE_FLAGS "-DALLEGRO_STATICLINK") +endif(NOT BUILD_SHARED_LIBS) + +#-----------------------------------------------------------------------------# +# vim: set ts=8 sts=4 sw=4 et: diff --git a/allegro/demos/speed/a4_aux.c b/allegro/demos/speed/a4_aux.c new file mode 100644 index 00000000..82af4777 --- /dev/null +++ b/allegro/demos/speed/a4_aux.c @@ -0,0 +1,624 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Allegro 5 port by Peter Wang, 2010 + * + * The functions in this file resemble Allegro 4 functions but do not + * necessarily emulate the behaviour precisely. + */ + +#include <math.h> +#include <stdio.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_audio.h> +#include <allegro5/allegro_font.h> +#include <allegro5/allegro_primitives.h> + +#include "a4_aux.h" + + + +/* + * Configuration files + */ + + + +/* emulate get_config_string() */ +const char *get_config_string(const ALLEGRO_CONFIG *cfg, const char *section, + const char *name, const char *def) +{ + const char *v = al_get_config_value(cfg, section, name); + + return (v) ? v : def; +} + + + +/* emulate get_config_int() */ +int get_config_int(const ALLEGRO_CONFIG *cfg, const char *section, + const char *name, int def) +{ + const char *v = al_get_config_value(cfg, section, name); + + return (v) ? atoi(v) : def; +} + + + +/* emulate set_config_int() */ +void set_config_int(ALLEGRO_CONFIG *cfg, const char *section, const char *name, + int val) +{ + char buf[32]; + + sprintf(buf, "%d", val); + al_set_config_value(cfg, section, name, buf); +} + + + +/* + * Input routines + */ + + +#define MAX_KEYBUF 16 + + +int key[ALLEGRO_KEY_MAX]; + +int joy_left; +int joy_right; +int joy_b1; + +static int keybuf[MAX_KEYBUF]; +static int keybuf_len = 0; +static ALLEGRO_MUTEX *keybuf_mutex; + +static ALLEGRO_EVENT_QUEUE *input_queue; + + + +/* initialises the input emulation */ +void init_input() +{ + ALLEGRO_JOYSTICK *joy; + + keybuf_len = 0; + keybuf_mutex = al_create_mutex(); + + input_queue = al_create_event_queue(); + al_register_event_source(input_queue, al_get_keyboard_event_source()); + al_register_event_source(input_queue, al_get_display_event_source(screen)); + + if (al_get_num_joysticks() > 0) { + joy = al_get_joystick(0); + if (joy) + al_register_event_source(input_queue, al_get_joystick_event_source()); + } +} + + + +/* closes down the input emulation */ +void shutdown_input() +{ + al_destroy_mutex(keybuf_mutex); + keybuf_mutex = NULL; + + al_destroy_event_queue(input_queue); + input_queue = NULL; +} + + + +/* helper function to add a keypress to a buffer */ +static void add_key(ALLEGRO_KEYBOARD_EVENT *event) +{ + if ((event->unichar == 0) || (event->unichar > 255)) + return; + + al_lock_mutex(keybuf_mutex); + + if (keybuf_len < MAX_KEYBUF) { + keybuf[keybuf_len] = event->unichar | ((event->keycode << 8) & 0xff00); + keybuf_len++; + } + + al_unlock_mutex(keybuf_mutex); +} + + + +/* emulate poll_keyboard() and poll_joystick() combined */ +void poll_input() +{ + ALLEGRO_EVENT event; + + while (al_get_next_event(input_queue, &event)) { + + switch (event.type) { + + case ALLEGRO_EVENT_KEY_DOWN: + key[event.keyboard.keycode] = 1; + break; + + case ALLEGRO_EVENT_KEY_UP: + key[event.keyboard.keycode] = 0; + break; + + case ALLEGRO_EVENT_KEY_CHAR: + add_key(&event.keyboard); + break; + + case ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN: + if (event.joystick.button == 0) + joy_b1 = 1; + break; + + case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: + if (event.joystick.button == 0) + joy_b1 = 0; + break; + + case ALLEGRO_EVENT_JOYSTICK_AXIS: + if (event.joystick.stick == 0 && event.joystick.axis == 0) { + float pos = event.joystick.pos; + joy_left = (pos < 0.0); + joy_right = (pos > 0.0); + } + break; + + case ALLEGRO_EVENT_TIMER: + /* retrace_count incremented */ + break; + + case ALLEGRO_EVENT_DISPLAY_EXPOSE: + break; + } + } +} + + + +/* blocking version of poll_input(), also wakes on retrace_count */ +void poll_input_wait() +{ + al_wait_for_event(input_queue, NULL); + poll_input(); +} + + + +/* emulate keypressed() */ +int keypressed() +{ + poll_input(); + + return keybuf_len > 0; +} + + + +/* emulate readkey(), except this version never blocks */ +int readkey() +{ + int c = 0; + + poll_input(); + + al_lock_mutex(keybuf_mutex); + + if (keybuf_len > 0) { + c = keybuf[0]; + keybuf_len--; + memmove(keybuf, keybuf + 1, sizeof(keybuf[0]) * keybuf_len); + } + + al_unlock_mutex(keybuf_mutex); + + return c; +} + + + +/* emulate clear_keybuf() */ +void clear_keybuf() +{ + al_lock_mutex(keybuf_mutex); + + keybuf_len = 0; + + al_unlock_mutex(keybuf_mutex); +} + + + +/* + * Graphics routines + */ + + +#define MAX_POLYGON_VERTICES 6 + + +ALLEGRO_DISPLAY *screen; +ALLEGRO_FONT *font; +ALLEGRO_FONT *font_video; + + + +/* like create_bitmap() */ +ALLEGRO_BITMAP *create_memory_bitmap(int w, int h) +{ + int oldflags; + int newflags; + ALLEGRO_BITMAP *bmp; + + oldflags = al_get_new_bitmap_flags(); + newflags = (oldflags &~ ALLEGRO_VIDEO_BITMAP) | ALLEGRO_MEMORY_BITMAP; + al_set_new_bitmap_flags(newflags); + bmp = al_create_bitmap(w, h); + al_set_new_bitmap_flags(oldflags); + return bmp; +} + + + +/* used to clone a video bitmap from a memory bitmap; no such function in A4 */ +ALLEGRO_BITMAP *replace_bitmap(ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_BITMAP *tmp = al_clone_bitmap(bmp); + al_destroy_bitmap(bmp); + return tmp; +} + + + +/* approximate solid_mode() function, but we we use alpha for transparent + * pixels instead of a mask color + */ +void solid_mode() +{ + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); +} + + + +/* emulate makecol() */ +ALLEGRO_COLOR makecol(int r, int g, int b) +{ + return al_map_rgb(r, g, b); +} + + + +/* emulate hline() */ +void hline(int x1, int y, int x2, ALLEGRO_COLOR c) +{ + al_draw_line(x1+0.5, y+0.5, x2+0.5, y+0.5, c, 1); +} + + + +/* emulate vline() */ +void vline(int x, int y1, int y2, ALLEGRO_COLOR c) +{ + al_draw_line(x+0.5, y1+0.5, x+0.5, y2+0.5, c, 1); +} + + + +/* emulate line() */ +void line(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color) +{ + al_draw_line(x1+0.5, y1+0.5, x2+0.5, y2+0.5, color, 1); +} + + + +/* emulate rectfill() */ +void rectfill(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color) +{ + al_draw_filled_rectangle(x1, y1, x2+1, y2+1, color); +} + + + +/* emulate circle() */ +void circle(int x, int y, int radius, ALLEGRO_COLOR color) +{ + al_draw_circle(x+0.5, y+0.5, radius, color, 1); +} + + + +/* emulate circlefill() */ +void circlefill(int x, int y, int radius, ALLEGRO_COLOR color) +{ + al_draw_filled_circle(x+0.5, y+0.5, radius, color); +} + + + +/* emulate stretch_sprite() */ +void stretch_sprite(ALLEGRO_BITMAP *bmp, ALLEGRO_BITMAP *sprite, + int x, int y, int w, int h) +{ + ALLEGRO_STATE state; + + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); + + al_set_target_bitmap(bmp); + al_draw_scaled_bitmap(sprite, + 0, 0, al_get_bitmap_width(sprite), al_get_bitmap_height(sprite), + x, y, w, h, 0); + + al_restore_state(&state); +} + + + +/* emulate polygon() for convex polygons only */ +void polygon(int vertices, const int *points, ALLEGRO_COLOR color) +{ + ALLEGRO_VERTEX vtxs[MAX_POLYGON_VERTICES + 2]; + int i; + + assert(vertices <= MAX_POLYGON_VERTICES); + + vtxs[0].x = 0.0; + vtxs[0].y = 0.0; + vtxs[0].z = 0.0; + vtxs[0].color = color; + vtxs[0].u = 0; + vtxs[0].v = 0; + + for (i = 0; i < vertices; i++) { + vtxs[0].x += points[i*2]; + vtxs[0].y += points[i*2 + 1]; + } + + vtxs[0].x /= vertices; + vtxs[0].y /= vertices; + + for (i = 1; i <= vertices; i++) { + vtxs[i].x = points[0]; + vtxs[i].y = points[1]; + vtxs[i].z = 0.0; + vtxs[i].color = color; + vtxs[i].u = 0; + vtxs[i].v = 0; + points += 2; + } + + vtxs[vertices + 1] = vtxs[1]; + + al_draw_prim(vtxs, NULL, NULL, 0, vertices + 2, ALLEGRO_PRIM_TRIANGLE_FAN); +} + + + +/* emulate textout() */ +void textout(const ALLEGRO_FONT *font, const char *s, int x, int y, ALLEGRO_COLOR c) +{ + al_draw_text(font, c, x, y, ALLEGRO_ALIGN_LEFT, s); +} + + + +/* emulate textout_centre() */ +void textout_centre(const ALLEGRO_FONT *font, const char *s, int x, int y, ALLEGRO_COLOR c) +{ + al_draw_text(font, c, x, y, ALLEGRO_ALIGN_CENTRE, s); +} + + + +/* emulate textprintf() */ +void textprintf(const ALLEGRO_FONT *f, int x, int y, ALLEGRO_COLOR color, const char *fmt, ...) +{ + va_list ap; + char buf[256]; + + va_start(ap, fmt); +#if defined(__WATCOMC__) || defined(_MSC_VER) + _vsnprintf(buf, sizeof(buf), fmt, ap); + buf[sizeof(buf)-1] = '\0'; +#else + vsnprintf(buf, sizeof(buf), fmt, ap); +#endif + va_end(ap); + + textout(f, buf, x, y, color); +} + + + +/* + * Matrix routines + */ + + + +static const MATRIX_f identity_matrix_f = +{ + { + /* 3x3 identity */ + { 1.0, 0.0, 0.0 }, + { 0.0, 1.0, 0.0 }, + { 0.0, 0.0, 1.0 }, + }, + + /* zero translation */ + { 0.0, 0.0, 0.0 } +}; + + + +/* get_scaling_matrix_f: + * Floating point version of get_scaling_matrix(). + */ +void get_scaling_matrix_f(MATRIX_f *m, float x, float y, float z) +{ + *m = identity_matrix_f; + + m->v[0][0] = x; + m->v[1][1] = y; + m->v[2][2] = z; +} + + + +/* get_z_rotate_matrix_f: + * Floating point version of get_z_rotate_matrix(). + */ +void get_z_rotate_matrix_f(MATRIX_f *m, float r) +{ + float c, s; + + s = sin(r * ALLEGRO_PI / 128.0); + c = cos(r * ALLEGRO_PI / 128.0); + *m = identity_matrix_f; + + m->v[0][0] = c; + m->v[0][1] = -s; + + m->v[1][0] = s; + m->v[1][1] = c; +} + + + +/* qtranslate_matrix_f: + * Floating point version of qtranslate_matrix(). + */ +void qtranslate_matrix_f(MATRIX_f *m, float x, float y, float z) +{ + m->t[0] += x; + m->t[1] += y; + m->t[2] += z; +} + + + +/* matrix_mul_f: + * Floating point version of matrix_mul(). + */ +void matrix_mul_f(const MATRIX_f *m1, const MATRIX_f *m2, MATRIX_f *out) +{ + MATRIX_f temp; + int i, j; + + if (m1 == out) { + temp = *m1; + m1 = &temp; + } + else if (m2 == out) { + temp = *m2; + m2 = &temp; + } + + for (i=0; i<3; i++) { + for (j=0; j<3; j++) { + out->v[i][j] = (m1->v[0][j] * m2->v[i][0]) + + (m1->v[1][j] * m2->v[i][1]) + + (m1->v[2][j] * m2->v[i][2]); + } + + out->t[i] = (m1->t[0] * m2->v[i][0]) + + (m1->t[1] * m2->v[i][1]) + + (m1->t[2] * m2->v[i][2]) + + m2->t[i]; + } +} + + + +/* apply_matrix_f: + * Floating point vector by matrix multiplication routine. + */ +void apply_matrix_f(const MATRIX_f *m, float x, float y, float z, + float *xout, float *yout, float *zout) +{ +#define CALC_ROW(n) (x * m->v[(n)][0] + y * m->v[(n)][1] + z * m->v[(n)][2] + m->t[(n)]) + *xout = CALC_ROW(0); + *yout = CALC_ROW(1); + *zout = CALC_ROW(2); +#undef CALC_ROW +} + + + +/* + * Timing routines + */ + + +static ALLEGRO_TIMER *retrace_counter = NULL; + + + +/* start incrementing retrace_count */ +void start_retrace_count() +{ + retrace_counter = al_create_timer(1/70.0); + al_register_event_source(input_queue, al_get_timer_event_source(retrace_counter)); + al_start_timer(retrace_counter); +} + + + +/* stop incrementing retrace_count */ +void stop_retrace_count() +{ + al_destroy_timer(retrace_counter); + retrace_counter = NULL; +} + + + +/* emulate 'retrace_count' variable */ +int64_t retrace_count() +{ + return al_get_timer_count(retrace_counter); +} + + + +/* emulate rest() */ +void rest(unsigned int time) +{ + al_rest(0.001 * time); +} + + + +/* + * Sound routines + */ + + + +/* emulate create_sample(), for unsigned 8-bit mono samples */ +ALLEGRO_SAMPLE *create_sample_u8(int freq, int len) +{ + char *buf = al_malloc(freq * len); + + return al_create_sample(buf, len, freq, ALLEGRO_AUDIO_DEPTH_UINT8, + ALLEGRO_CHANNEL_CONF_1, true); +} + + + +/* emulate play_sample() */ +void play_sample(ALLEGRO_SAMPLE *spl, int vol, int pan, int freq, int loop) +{ + int playmode = loop ? ALLEGRO_PLAYMODE_LOOP : ALLEGRO_PLAYMODE_ONCE; + + al_play_sample(spl, vol/255.0, (pan - 128)/128.0, freq/1000.0, + playmode, NULL); +} + + diff --git a/allegro/demos/speed/a4_aux.h b/allegro/demos/speed/a4_aux.h new file mode 100644 index 00000000..350de945 --- /dev/null +++ b/allegro/demos/speed/a4_aux.h @@ -0,0 +1,85 @@ +#ifndef __A4_AUX_H__ +#define __A4_AUX_H__ + + +#ifndef TRUE + #define TRUE -1 + #define FALSE 0 +#endif + +#undef MIN +#undef MAX +#undef MID + +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) + +#undef ABS +#define ABS(x) (((x) >= 0) ? (x) : (-(x))) + +#undef SGN +#define SGN(x) (((x) >= 0) ? 1 : -1) + + +typedef struct MATRIX_f /* transformation matrix (floating point) */ +{ + float v[3][3]; /* scaling and rotation */ + float t[3]; /* translation */ +} MATRIX_f; + + +/* global variables */ +extern int key[ALLEGRO_KEY_MAX]; +extern int joy_left; +extern int joy_right; +extern int joy_b1; +extern struct ALLEGRO_DISPLAY *screen; +extern struct ALLEGRO_FONT *font; +extern struct ALLEGRO_FONT *font_video; + + +const char *get_config_string(const ALLEGRO_CONFIG *cfg, const char *section, const char *name, const char *def); +int get_config_int(const ALLEGRO_CONFIG *cfg, const char *section, const char *name, int def); +void set_config_int(ALLEGRO_CONFIG *cfg, const char *section, const char *name, int val); + +void init_input(); +void shutdown_input(); +void poll_input(); +void poll_input_wait(); +int keypressed(); +int readkey(); +void clear_keybuf(); + +ALLEGRO_BITMAP *create_memory_bitmap(int w, int h); +ALLEGRO_BITMAP *replace_bitmap(ALLEGRO_BITMAP *bmp); +void solid_mode(); +ALLEGRO_COLOR makecol(int r, int g, int b); +void hline(int x1, int y, int x2, ALLEGRO_COLOR c); +void vline(int x, int y1, int y2, ALLEGRO_COLOR c); +void line(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color); +void rectfill(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color); +void circle(int x, int y, int radius, ALLEGRO_COLOR color); +void circlefill(int x, int y, int radius, ALLEGRO_COLOR color); +void stretch_sprite(ALLEGRO_BITMAP *bmp, ALLEGRO_BITMAP *sprite, int x, int y, int w, int h); +void polygon(int vertices, const int *points, ALLEGRO_COLOR color); +void textout(struct ALLEGRO_FONT const *font, const char *s, int x, int y, ALLEGRO_COLOR c); +void textout_centre(struct ALLEGRO_FONT const *font, const char *s, int x, int y, ALLEGRO_COLOR c); +void textprintf(struct ALLEGRO_FONT const *f, int x, int y, ALLEGRO_COLOR color, const char *fmt, ...); + +void get_scaling_matrix_f(MATRIX_f *m, float x, float y, float z); +void get_z_rotate_matrix_f(MATRIX_f *m, float r); +void qtranslate_matrix_f(MATRIX_f *m, float x, float y, float z); +void matrix_mul_f(const MATRIX_f *m1, const MATRIX_f *m2, MATRIX_f *out); +void apply_matrix_f(const MATRIX_f *m, float x, float y, float z, float *xout, float *yout, float *zout); + +void start_retrace_count(); +void stop_retrace_count(); +int64_t retrace_count(); +void rest(unsigned int time); + +struct ALLEGRO_SAMPLE *create_sample_u8(int freq, int len); +void play_sample(struct ALLEGRO_SAMPLE *spl, int vol, int pan, int freq, int loop); + + + +#endif /* __A4_AUX_H__ */ diff --git a/allegro/demos/speed/badguys.c b/allegro/demos/speed/badguys.c new file mode 100644 index 00000000..fc364977 --- /dev/null +++ b/allegro/demos/speed/badguys.c @@ -0,0 +1,430 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Enemy control routines (attack waves). + */ + +#include <math.h> +#include <allegro5/allegro.h> + +#include "speed.h" + + + +/* description of an attack wave */ +typedef struct WAVEINFO +{ + int count; /* how many to create */ + float delay; /* how long to delay them */ + float delay_rand; /* random delay factor */ + float speed; /* how fast they move */ + float speed_rand; /* speed random factor */ + float move; /* movement speed */ + float move_rand; /* movement random factor */ + float sin_depth; /* depth of sine wave motion */ + float sin_depth_rand; /* sine depth random factor */ + float sin_speed; /* speed of sine wave motion */ + float sin_speed_rand; /* sine speed random factor */ + int split; /* split into multiple dudes? */ + int aggro; /* attack the player? */ + int evade; /* evade the player? */ +} WAVEINFO; + + + +#define END_WAVEINFO { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + + + +/* attack wave #1 (straight downwards) */ +static WAVEINFO wave1[] = +{ + /* c del rnd speed r mv r dp r sd r sp ag ev */ + { 4, 0.0, 1.0, 0.0015, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, + { 2, 0.7, 0.0, 0.0055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, 0.5, 0.0, 0.0045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 0.0, 1.0, 0.0035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 0.0, 1.0, 0.0025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + END_WAVEINFO +}; + + + +/* attack wave #2 (diagonal motion) */ +static WAVEINFO wave2[] = +{ + /* c del rnd speed rnd move rnd dp r sd r sp ag ev */ + { 6, 2.0, 1.0, 0.0025, 0.002, 0.0000, 0.020, 0, 0, 0, 0, 0, 0, 0 }, + { 6, 1.2, 1.0, 0.0025, 0.001, 0.0000, 0.010, 0, 0, 0, 0, 0, 0, 0 }, + { 6, 0.5, 1.0, 0.0025, 0.000, 0.0000, 0.005, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 0.0, 1.0, 0.0025, 0.000, -0.0025, 0.000, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 0.0, 1.0, 0.0025, 0.000, 0.0025, 0.000, 0, 0, 0, 0, 0, 0, 0 }, + END_WAVEINFO +}; + + + +/* attack wave #3 (sine wave motion) */ +static WAVEINFO wave3[] = +{ + /* c del rnd speed rnd mv r sdepth rnd sspd rnd sp ag ev */ + { 4, 0.0, 2.0, 0.0020, 0.0000, 0, 0, 0.005, 0.000, 0.020, 0.00, 1, 0, 0 }, + { 4, 1.5, 1.0, 0.0016, 0.0024, 0, 0, 0.002, 0.006, 0.010, 0.03, 0, 0, 0 }, + { 4, 1.0, 1.0, 0.0019, 0.0016, 0, 0, 0.003, 0.004, 0.015, 0.02, 0, 0, 0 }, + { 4, 0.5, 1.0, 0.0022, 0.0008, 0, 0, 0.004, 0.002, 0.020, 0.01, 0, 0, 0 }, + { 4, 0.0, 1.0, 0.0025, 0.0000, 0, 0, 0.005, 0.000, 0.025, 0.00, 0, 0, 0 }, + END_WAVEINFO +}; + + + +/* attack wave #4 (evade you) */ +static WAVEINFO wave4[] = +{ + /* c del rnd speed rnd mv rnd dp r sd r sp ag ev */ + { 4, 0.0, 2.0, 0.0020, 0.0000, 0, 0.000, 0, 0, 0, 0, 1, 0, 1 }, + { 3, 1.5, 1.0, 0.0016, 0.0024, 0, 0.010, 0, 0, 0, 0, 0, 0, 1 }, + { 3, 1.0, 1.0, 0.0019, 0.0016, 0, 0.001, 0, 0, 0, 0, 0, 0, 1 }, + { 4, 0.5, 1.0, 0.0022, 0.0008, 0, 0.000, 0, 0, 0, 0, 0, 0, 1 }, + { 4, 0.0, 1.0, 0.0025, 0.0000, 0, 0.000, 0, 0, 0, 0, 0, 0, 1 }, + END_WAVEINFO +}; + + + +/* attack wave #5 (attack you) */ +static WAVEINFO wave5[] = +{ + /* c del rnd speed rnd mv rnd sd r sd r sp ag ev */ + { 4, 0.0, 2.0, 0.0010, 0.0000, 0, 0.000, 0, 0, 0, 0, 1, 1, 0 }, + { 3, 1.5, 1.0, 0.0016, 0.0024, 0, 0.010, 0, 0, 0, 0, 0, 1, 0 }, + { 3, 1.0, 1.0, 0.0019, 0.0016, 0, 0.001, 0, 0, 0, 0, 0, 1, 0 }, + { 3, 0.5, 1.0, 0.0022, 0.0008, 0, 0.000, 0, 0, 0, 0, 0, 1, 0 }, + { 4, 0.0, 1.0, 0.0025, 0.0000, 0, 0.000, 0, 0, 0, 0, 0, 1, 0 }, + END_WAVEINFO +}; + + + +/* attack wave #6 (the boss wave, muahaha) */ +static WAVEINFO wave6[] = +{ + /* c del rnd speed rnd mv rnd dp rnd sd rnd sp ag ev */ + { 8, 6.0, 2.0, 0.002, 0.001, 0, 0.00, 0, 0, 0, 0, 1, 1, 0 }, + { 8, 4.5, 2.0, 0.002, 0.001, 0, 0.00, 0, 0, 0, 0, 1, 0, 1 }, + { 8, 3.0, 2.0, 0.002, 0.001, 0, 0.00, 0, 0.006, 0, 0.03, 1, 0, 0 }, + { 8, 1.5, 2.0, 0.002, 0.001, 0, 0.01, 0, 0, 0, 0, 1, 0, 0 }, + { 8, 0.0, 2.0, 0.002, 0.001, 0, 0.00, 0, 0, 0, 0, 1, 0, 0 }, + END_WAVEINFO +}; + + + +/* list of available attack waves */ +static WAVEINFO *waveinfo[] = +{ + wave1+4, wave2+4, wave3+4, wave4+4, wave5+4, + wave1+3, wave2+3, wave3+3, wave4+3, wave5+3, + wave1+2, wave2+2, wave3+2, wave4+2, wave5+2, + wave1+1, wave2+1, wave3+1, wave4+1, wave5+1, + wave1+0, wave2+0, wave3+0, wave4+0, wave5+0, + wave6 +}; + + + +/* info about someone nasty */ +typedef struct BADGUY +{ + float x; /* x position */ + float y; /* y position */ + float speed; /* vertical speed */ + float move; /* horizontal motion */ + float sin_depth; /* depth of sine motion */ + float sin_speed; /* speed of sine motion */ + int split; /* whether to split ourselves */ + int aggro; /* whether to attack the player */ + int evade; /* whether to evade the player */ + float v; /* horizontal velocity */ + int t; /* integer counter */ + struct BADGUY *next; +} BADGUY; + + +static BADGUY *evildudes; + +static int finished_counter; + +static int wavenum; + + + +/* creates a new swarm of badguys */ +void lay_attack_wave(int reset) +{ + WAVEINFO *info; + BADGUY *b; + int i; + + if (reset) { + wavenum = 0; + } + else { + wavenum++; + if (wavenum >= (int)(sizeof(waveinfo)/sizeof(WAVEINFO *))) + wavenum = 0; + } + + info = waveinfo[wavenum]; + + while (info->count) { + for (i=0; i<info->count; i++) { + b = malloc(sizeof(BADGUY)); + + #define URAND ((float)(rand() & 255) / 255.0) + #define SRAND (((float)(rand() & 255) / 255.0) - 0.5) + + b->x = URAND; + b->y = -info->delay - URAND * info->delay_rand; + b->speed = info->speed + URAND * info->speed_rand; + b->move = info->move + SRAND * info->move_rand; + b->sin_depth = info->sin_depth + URAND * info->sin_depth_rand; + b->sin_speed = info->sin_speed + URAND * info->sin_speed_rand; + b->split = info->split; + b->aggro = info->aggro; + b->evade = info->evade; + b->v = 0; + b->t = rand() & 255; + + b->next = evildudes; + evildudes = b; + } + + info++; + } + + finished_counter = 0; +} + + + +/* initialises the badguy functions */ +void init_badguys() +{ + evildudes = NULL; + + lay_attack_wave(TRUE); +} + + + +/* closes down the badguys module */ +void shutdown_badguys() +{ + BADGUY *b; + + while (evildudes) { + b = evildudes; + evildudes = evildudes->next; + free(b); + } +} + + + +/* updates the badguy position */ +int update_badguys() +{ + BADGUY **p = &evildudes; + BADGUY *b = evildudes; + BADGUY *tmp1, *tmp2; + void *bullet; + float x, y, d; + int dead; + + /* testcode: enter clears the level */ + if ((cheat) && (key[ALLEGRO_KEY_ENTER])) { + shutdown_badguys(); + b = NULL; + + while (key[ALLEGRO_KEY_ENTER]) + poll_input_wait(); + } + + while (b) { + dead = FALSE; + + if (b->aggro) { + /* attack the player */ + d = player_pos() - b->x; + + if (d < -0.5) + d += 1; + else if (d > 0.5) + d -= 1; + + if (b->y < 0.5) + d = -d; + + b->v *= 0.99; + b->v += SGN(d) * 0.00025; + } + else if (b->evade) { + /* evade the player */ + if (b->y < 0.75) + d = player_pos() + 0.5; + else + d = b->x; + + if (b->move) + d += SGN(b->move) / 16.0; + + d = find_target(d) - b->x; + + if (d < -0.5) + d += 1; + else if (d > 0.5) + d -= 1; + + b->v *= 0.96; + b->v += SGN(d) * 0.0004; + } + + /* horizontal move */ + b->x += b->move + sin(b->t * b->sin_speed) * b->sin_depth + b->v; + + if (b->x < 0) + b->x += 1; + else if (b->x > 1) + b->x -= 1; + + /* vertical move */ + b->y += b->speed; + + if ((b->y > 0.5) && (b->y - b->speed <= 0.5) && (b->split)) { + /* split ourselves */ + tmp1 = malloc(sizeof(BADGUY)); + tmp2 = malloc(sizeof(BADGUY)); + + *tmp1 = *tmp2 = *b; + + tmp1->move -= 0.001; + tmp2->move += 0.001; + + b->speed += 0.001; + + tmp1->t = rand() & 255; + tmp2->t = rand() & 255; + + tmp1->next = tmp2; + tmp2->next = evildudes; + evildudes = tmp1; + } + + b->t++; + + if (b->y > 0) { + if (kill_player(b->x, b->y)) { + /* did we hit someone? */ + dead = TRUE; + } + else { + /* or did someone else hit us? */ + bullet = get_first_bullet(&x, &y); + + while (bullet) { + x = x - b->x; + + if (x < -0.5) + x += 1; + else if (x > 0.5) + x -= 1; + + x = ABS(x); + + y = ABS(y - b->y); + + if (x < y) + d = y/2 + x; + else + d = x/2 + y; + + if (d < 0.025) { + kill_bullet(bullet); + explode(b->x, b->y, 0); + sfx_explode_alien(); + dead = TRUE; + break; + } + + bullet = get_next_bullet(bullet, &x, &y); + } + } + } + + /* advance to the next dude */ + if (dead) { + *p = b->next; + tmp1 = b; + b = b->next; + free(tmp1); + } + else { + p = &b->next; + b = b->next; + } + } + + if ((!evildudes) && (!player_dying())) { + if (!finished_counter) { + message("Wave Complete"); + sfx_ping(0); + } + + finished_counter++; + + if (finished_counter > 64) + return TRUE; + } + + return FALSE; +} + + + +/* draws the badguys */ +void draw_badguys(int r, int g, int b, int (*project)(float *f, int *i, int c)) +{ + BADGUY *bad = evildudes; + ALLEGRO_COLOR c = makecol(r, g, b); + float shape[12]; + int ishape[12]; + + while (bad) { + if (bad->y > 0) { + shape[0] = bad->x - 0.02; + shape[1] = bad->y + 0.01; + + shape[2] = bad->x; + shape[3] = bad->y + 0.02; + + shape[4] = bad->x + 0.02; + shape[5] = bad->y + 0.01; + + shape[6] = bad->x + 0.01; + shape[7] = bad->y + 0.005; + + shape[8] = bad->x; + shape[9] = bad->y - 0.015; + + shape[10] = bad->x - 0.01; + shape[11] = bad->y + 0.005; + + if (project(shape, ishape, 12)) + polygon(6, ishape, c); + } + + bad = bad->next; + } +} + diff --git a/allegro/demos/speed/bullets.c b/allegro/demos/speed/bullets.c new file mode 100644 index 00000000..0135cff7 --- /dev/null +++ b/allegro/demos/speed/bullets.c @@ -0,0 +1,181 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Bullet animation and display routines. + */ + +#include <math.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_primitives.h> + +#include "speed.h" + + + +/* bullet info */ +typedef struct BULLET +{ + float x; + float y; + struct BULLET *next; +} BULLET; + + +static BULLET *bullets; + + + +/* interface for the aliens to query bullet positions */ +void *get_first_bullet(float *x, float *y) +{ + if (!bullets) + return NULL; + + *x = bullets->x; + *y = bullets->y; + + return bullets; +} + + + +/* interface for the aliens to query bullet positions */ +void *get_next_bullet(void *b, float *x, float *y) +{ + BULLET *bul = ((BULLET *)b)->next; + + if (!bul) + return NULL; + + *x = bul->x; + *y = bul->y; + + return bul; +} + + + +/* interface for the aliens to get rid of bullets when they explode */ +void kill_bullet(void *b) +{ + ((BULLET *)b)->y = -65536; +} + + + +/* initialises the bullets functions */ +void init_bullets() +{ + bullets = NULL; +} + + + +/* closes down the bullets module */ +void shutdown_bullets() +{ + BULLET *b; + + while (bullets) { + b = bullets; + bullets = bullets->next; + free(b); + } +} + + + +/* fires a new bullet */ +void fire_bullet() +{ + BULLET *b = malloc(sizeof(BULLET)); + + b->x = player_pos(); + b->y = 0.96; + + b->next = bullets; + bullets = b; + + sfx_shoot(); +} + + + +/* updates the bullets position */ +void update_bullets() +{ + BULLET **p = &bullets; + BULLET *b = bullets; + BULLET *tmp; + + while (b) { + b->y -= 0.025; + + if (b->y < 0) { + *p = b->next; + tmp = b; + b = b->next; + free(tmp); + } + else { + p = &b->next; + b = b->next; + } + } +} + + + +/* draws the bullets */ +void draw_bullets(int r, int g, int b, int (*project)(float *f, int *i, int c)) +{ + BULLET *bul = bullets; + ALLEGRO_COLOR c1 = makecol(128+r/2, 128+g/2, 128+b/2); + ALLEGRO_COLOR c2 = (g) ? makecol(r/5, g/5, b/5) : makecol(r/4, g/4, b/4); + float shape[6]; + int ishape[6]; + int i; + + while (bul) { + if (bul->y > 0) { + shape[0] = bul->x - 0.005; + shape[1] = bul->y + 0.01; + + shape[2] = bul->x + 0.005; + shape[3] = bul->y + 0.01; + + shape[4] = bul->x; + shape[5] = bul->y - 0.015; + + if (project(shape, ishape, 6)) { + polygon(3, ishape, c1); + + if (!low_detail) { + float cx = (ishape[0] + ishape[2] + ishape[4]) / 3; + float cy = (ishape[1] + ishape[3] + ishape[5]) / 3; + + float boxx[4] = { -1, -1, 1, 1 }; + float boxy[4] = { -1, 1, 1, -1 }; + + for (i=0; i<4; i++) { + float rot = ((int)(bul->x*256) & 1) ? bul->y : -bul->y; + + float tx = cos(rot)*boxx[i] + sin(rot)*boxy[i]; + float ty = sin(rot)*boxx[i] - cos(rot)*boxy[i]; + + boxx[i] = tx * bul->y * view_size() / 8; + boxy[i] = ty * bul->y * view_size() / 8; + } + + line(cx+boxx[0], cy+boxy[0], cx+boxx[1], cy+boxy[1], c2); + line(cx+boxx[1], cy+boxy[1], cx+boxx[2], cy+boxy[2], c2); + line(cx+boxx[2], cy+boxy[2], cx+boxx[3], cy+boxy[3], c2); + line(cx+boxx[3], cy+boxy[3], cx+boxx[0], cy+boxy[0], c2); + } + } + } + + bul = bul->next; + } +} + diff --git a/allegro/demos/speed/explode.c b/allegro/demos/speed/explode.c new file mode 100644 index 00000000..dadcd049 --- /dev/null +++ b/allegro/demos/speed/explode.c @@ -0,0 +1,139 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Explosion graphics effect. + */ + +#include <allegro5/allegro.h> +#include <allegro5/allegro_primitives.h> + +#include "speed.h" + + + +/* explosion info */ +typedef struct EXPLOSION +{ + float x; + float y; + int big; + float time; + struct EXPLOSION *next; +} EXPLOSION; + + +static EXPLOSION *explosions; + + + +/* initialises the explode functions */ +void init_explode() +{ + explosions = NULL; +} + + + +/* closes down the explode module */ +void shutdown_explode() +{ + EXPLOSION *e; + + while (explosions) { + e = explosions; + explosions = explosions->next; + free(e); + } +} + + + +/* triggers a new explosion */ +void explode(float x, float y, int big) +{ + EXPLOSION *e = malloc(sizeof(EXPLOSION)); + + e->x = x; + e->y = y; + + e->big = big; + + e->time = 0; + + e->next = explosions; + explosions = e; +} + + + +/* updates the explode position */ +void update_explode() +{ + EXPLOSION **p = &explosions; + EXPLOSION *e = explosions; + EXPLOSION *tmp; + + while (e) { + e->time += 1.0 / (e->big/2.0 + 1); + + if (e->time > 32) { + *p = e->next; + tmp = e; + e = e->next; + free(tmp); + } + else { + p = &e->next; + e = e->next; + } + } +} + + + +/* draws explosions */ +void draw_explode(int r, int g, int b, int (*project)(float *f, int *i, int c)) +{ + EXPLOSION *e = explosions; + float size = view_size(); + float pos[2]; + int ipos[2]; + int rr, gg, bb, c, s; + ALLEGRO_COLOR col; + + while (e) { + pos[0] = e->x; + pos[1] = e->y; + + if (project(pos, ipos, 2)) { + s = e->time * size / (512 / (e->big + 1)); + + if ((!low_detail) && (e->time < 24)) { + c = (24 - e->time) * 255 / 24; + col = makecol(c, c, c); + + circle(ipos[0], ipos[1], s*2, col); + circle(ipos[0], ipos[1], s*s/8, col); + } + + if (e->time < 32) { + rr = (32 - e->time) * r / 32; + gg = (32 - e->time) * g / 32; + bb = (32 - e->time) * b / 32; + + c = MAX((24 - e->time) * 255 / 24, 0); + + rr = MAX(rr, c); + gg = MAX(gg, c); + bb = MAX(bb, c); + + col = makecol(rr, gg, bb); + + circlefill(ipos[0], ipos[1], s, col); + } + } + + e = e->next; + } +} + diff --git a/allegro/demos/speed/hiscore.c b/allegro/demos/speed/hiscore.c new file mode 100644 index 00000000..a67edd4b --- /dev/null +++ b/allegro/demos/speed/hiscore.c @@ -0,0 +1,289 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Hiscore table. + */ + +#include <stdio.h> +#include <string.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_font.h> +#include <allegro5/allegro_primitives.h> + +#include "speed.h" + + + +#define NUM_SCORES 8 +#define MAX_NAME_LEN 24 + + +/* the score table */ +static int scores[NUM_SCORES] = +{ + 666, 512, 440, 256, 192, 128, 64, 42 +}; + +static char names[NUM_SCORES][MAX_NAME_LEN+1]; + +static char yourname[MAX_NAME_LEN+1] = ""; + + + +/* initialises the hiscore system */ +void init_hiscore() +{ + ALLEGRO_PATH *path; + ALLEGRO_CONFIG *cfg; + char buf1[256]; + int i; + + path = al_get_standard_path(ALLEGRO_USER_DATA_PATH); + if (!path) return; + al_make_directory(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); + + al_set_path_filename(path, "speed.rec"); + + cfg = al_load_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); + if (!cfg) + cfg = al_create_config(); + + for (i=0; i<NUM_SCORES; i++) { + sprintf(buf1, "score%d", i+1); + scores[i] = get_config_int(cfg, "hiscore", buf1, scores[i]); + + sprintf(buf1, "name%d", i+1); + strncpy(names[i], get_config_string(cfg, "hiscore", buf1, "Shawn Hargreaves"), MAX_NAME_LEN); + names[i][MAX_NAME_LEN] = 0; + } + + al_destroy_config(cfg); + al_destroy_path(path); +} + + + +/* shuts down the hiscore system */ +void shutdown_hiscore() +{ + ALLEGRO_PATH *path; + ALLEGRO_CONFIG *cfg; + char buf1[256]; + int i; + + path = al_get_standard_path(ALLEGRO_USER_DATA_PATH); + if (!path) return; + al_make_directory(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); + + al_set_path_filename(path, "speed.rec"); + + cfg = al_create_config(); + + for (i=0; i<NUM_SCORES; i++) { + sprintf(buf1, "score%d", i+1); + set_config_int(cfg, "hiscore", buf1, scores[i]); + + sprintf(buf1, "name%d", i+1); + al_set_config_value(cfg, "hiscore", buf1, names[i]); + } + + al_save_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP), cfg); + + al_destroy_config(cfg); + al_destroy_path(path); +} + + + +/* displays the text entry box */ +static void draw_entry_box(int which, int64_t retrace_count) +{ + const int w = MAX_NAME_LEN*8+16; + const int h = 16; + ALLEGRO_BITMAP *b; + ALLEGRO_BITMAP *screen; + int SCREEN_W, SCREEN_H; + int x; + + screen = al_get_target_bitmap(); + SCREEN_W = al_get_bitmap_width(screen); + SCREEN_H = al_get_bitmap_height(screen); + + b = create_memory_bitmap(w, h); + al_set_target_bitmap(b); + al_clear_to_color(makecol(0, 96, 0)); + hline(0, w, h-1, makecol(0, 32, 0)); + vline(0, w-1, h, makecol(0, 32, 0)); + + textprintf(font, 9, 5, makecol(0, 0, 0), "%s", yourname); + textprintf(font, 8, 4, makecol(255, 255, 255), "%s", yourname); + + if (retrace_count & 8) { + x = strlen(yourname)*8 + 8; + rectfill(x, 12, x+7, 14, makecol(0, 0, 0)); + } + + al_set_target_bitmap(screen); + al_draw_bitmap(b, SCREEN_W/2-56, SCREEN_H/2+(which-NUM_SCORES/2)*16-4, 0); + + al_destroy_bitmap(b); +} + + + +/* displays the score table */ +void score_table() +{ + int SCREEN_W = al_get_display_width(screen); + int SCREEN_H = al_get_display_height(screen); + ALLEGRO_BITMAP *bmp, *b; + ALLEGRO_COLOR col; + int c, i, j, x, y; + int myscore = -1; + + for (i=0; i<NUM_SCORES; i++) { + if (score > scores[i]) { + for (j=NUM_SCORES-1; j>i; j--) { + scores[j] = scores[j-1]; + strcpy(names[j], names[j-1]); + } + + scores[i] = score; + strcpy(names[i], yourname); + + myscore = i; + break; + } + } + + bmp = create_memory_bitmap(SCREEN_W, SCREEN_H); + al_set_target_bitmap(bmp); + + for (i=0; i<SCREEN_W/2; i++) { + vline(SCREEN_W/2-i-1, 0, SCREEN_H, makecol(0, i*255/(SCREEN_W/2), 0)); + vline(SCREEN_W/2+i, 0, SCREEN_H, makecol(0, i*255/(SCREEN_W/2), 0)); + } + + b = create_memory_bitmap(104, 8); + al_set_target_bitmap(b); + al_clear_to_color(al_map_rgba(0, 0, 0, 0)); + + textout(font, "HISCORE TABLE", 0, 0, makecol(0, 0, 0)); + stretch_sprite(bmp, b, SCREEN_W/64+4, SCREEN_H/64+4, SCREEN_W*31/32, SCREEN_H/8); + stretch_sprite(bmp, b, SCREEN_W/64+4, SCREEN_H*55/64+4, SCREEN_W*31/32, SCREEN_H/8); + + textout(font, "HISCORE TABLE", 0, 0, makecol(0, 64, 0)); + stretch_sprite(bmp, b, SCREEN_W/64, SCREEN_H/64, SCREEN_W*31/32, SCREEN_H/8); + stretch_sprite(bmp, b, SCREEN_W/64, SCREEN_H*55/64, SCREEN_W*31/32, SCREEN_H/8); + + al_destroy_bitmap(b); + al_set_target_bitmap(bmp); + + for (i=0; i<NUM_SCORES; i++) { + y = SCREEN_H/2 + (i-NUM_SCORES/2) * 16; + + textprintf(font, SCREEN_W/2-142, y+2, makecol(0, 0, 0), "#%d - %d", i+1, scores[i]); + textprintf(font, SCREEN_W/2-47, y+1, makecol(0, 0, 0), "%s", names[i]); + + if (i == myscore) + col = makecol(255, 0, 0); + else + col = makecol(255, 255, 255); + + textprintf(font, SCREEN_W/2-144, y, col, "#%d - %d", i+1, scores[i]); + textprintf(font, SCREEN_W/2-48, y, col, "%s", names[i]); + } + + if (myscore >= 0) + draw_entry_box(myscore, 0); + + bmp = replace_bitmap(bmp); + + al_set_target_bitmap(al_get_backbuffer(screen)); + + start_retrace_count(); + + for (i=0; i<=SCREEN_H/16; i++) { + al_clear_to_color(makecol(0, 0, 0)); + + for (j=0; j<=16; j++) { + x = j*(SCREEN_W/16); + al_draw_bitmap_region(bmp, x, 0, i, SCREEN_H, x, 0, 0); + + y = j*(SCREEN_H/16); + al_draw_bitmap_region(bmp, 0, y, SCREEN_W, i, 0, y, 0); + } + + al_flip_display(); + + do { + poll_input_wait(); + } while (retrace_count() < i*512/SCREEN_W); + } + + while (joy_b1 || key[ALLEGRO_KEY_SPACE] || key[ALLEGRO_KEY_ENTER] || key[ALLEGRO_KEY_ESCAPE]) + poll_input_wait(); + + if (myscore >= 0) { + clear_keybuf(); + + for (;;) { + poll_input_wait(); + + if ((joy_b1) && (yourname[0])) { + strcpy(names[myscore], yourname); + break; + } + + if (keypressed()) { + c = readkey(); + + if (((c >> 8) == ALLEGRO_KEY_ENTER) && (yourname[0])) { + strcpy(names[myscore], yourname); + sfx_explode_player(); + break; + } + else if (((c >> 8) == ALLEGRO_KEY_ESCAPE) && (names[myscore][0])) { + strcpy(yourname, names[myscore]); + sfx_ping(2); + break; + } + else if (((c >> 8) == ALLEGRO_KEY_BACKSPACE) && (strlen(yourname) > 0)) { + yourname[strlen(yourname)-1] = 0; + sfx_shoot(); + } + else if (((c & 0xFF) >= ' ') && ((c & 0xFF) <= '~') && (strlen(yourname) < MAX_NAME_LEN)) { + yourname[strlen(yourname)+1] = 0; + yourname[strlen(yourname)] = (c & 0xFF); + sfx_explode_alien(); + } + } + + al_draw_bitmap(bmp, 0, 0, 0); + draw_entry_box(myscore, retrace_count()); + al_flip_display(); + } + } + else { + while (!key[ALLEGRO_KEY_SPACE] && !key[ALLEGRO_KEY_ENTER] && !key[ALLEGRO_KEY_ESCAPE] && !joy_b1) { + poll_input_wait(); + al_draw_bitmap(bmp, 0, 0, 0); + al_flip_display(); + } + + sfx_ping(2); + } + + stop_retrace_count(); + + al_destroy_bitmap(bmp); +} + + + +/* returns the best score, for other modules to display */ +int get_hiscore() +{ + return scores[0]; +} + diff --git a/allegro/demos/speed/main.c b/allegro/demos/speed/main.c new file mode 100644 index 00000000..f0fc3fa6 --- /dev/null +++ b/allegro/demos/speed/main.c @@ -0,0 +1,341 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Main program body, setup code, action pump, etc. + */ + +#include <time.h> +#include <stdio.h> +#include <string.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_audio.h> +#include <allegro5/allegro_font.h> +#include <allegro5/allegro_primitives.h> + +#include "speed.h" + + + +/* are we cheating? */ +int cheat = FALSE; + + + +/* low detail mode? */ +int low_detail = FALSE; + + + +/* disable the grid? */ +int no_grid = FALSE; + + + +/* disable the music? */ +int no_music = FALSE; + + + +/* how many points did we get? */ +int score; + + + +/* the main game function */ +static int play_game() +{ + ALLEGRO_TIMER *inc_counter; + int gameover = 0; + int cyclenum = 0; + int redraw = 1; + + /* init */ + score = 0; + + init_view(); + init_player(); + init_badguys(); + init_bullets(); + init_explode(); + init_message(); + + #define TIMER_SPEED ALLEGRO_BPS_TO_SECS(30*(cyclenum+2)) + + inc_counter = al_create_timer(TIMER_SPEED); + al_start_timer(inc_counter); + + while (!gameover) { + + /* move everyone */ + while ((al_get_timer_count(inc_counter) > 0) && (!gameover)) { + update_view(); + update_bullets(); + update_explode(); + update_message(); + + if (update_badguys()) { + if (advance_view()) { + cyclenum++; + al_set_timer_count(inc_counter, 0); + lay_attack_wave(TRUE); + advance_player(TRUE); + } + else { + lay_attack_wave(FALSE); + advance_player(FALSE); + } + } + + gameover = update_player(); + + al_set_timer_count(inc_counter, al_get_timer_count(inc_counter)-1); + redraw = 1; + } + + /* take a screenshot? */ + if (key[ALLEGRO_KEY_PRINTSCREEN]) { + static int ss_count = 0; + + char fname[80]; + + sprintf(fname, "speed%03d.tga", ++ss_count); + + al_save_bitmap(fname, al_get_backbuffer(screen)); + + while (key[ALLEGRO_KEY_PRINTSCREEN]) + poll_input_wait(); + + al_set_timer_count(inc_counter, 0); + } + + /* toggle fullscreen window */ + if (key[ALLEGRO_KEY_F]) { + int flags = al_get_display_flags(screen); + al_set_display_flag(screen, ALLEGRO_FULLSCREEN_WINDOW, + !(flags & ALLEGRO_FULLSCREEN_WINDOW)); + + while (key[ALLEGRO_KEY_F]) + poll_input_wait(); + } + + /* draw everyone */ + if (redraw) { + draw_view(); + redraw = 0; + } + else { + rest(1); + } + } + + /* cleanup */ + al_destroy_timer(inc_counter); + + shutdown_view(); + shutdown_player(); + shutdown_badguys(); + shutdown_bullets(); + shutdown_explode(); + shutdown_message(); + + if (gameover < 0) { + sfx_ping(1); + return FALSE; + } + + return TRUE; +} + + + +/* display a commandline usage message */ +static void usage() +{ + printf( + "\n" + "SPEED - by Shawn Hargreaves, 1999\n" + "Allegro 5 port, 2010\n" + "\n" + "Usage: speed w h [options]\n" + "\n" + "The w and h values set your desired screen resolution.\n" + "What modes are available will depend on your hardware.\n" + "\n" + "Available options:\n" + "\n" + "\t-fullscreen enables full screen mode. (w and h are optional)\n" + "\t-cheat makes you invulnerable.\n" + "\t-simple turns off the more expensive graphics effects.\n" + "\t-nogrid turns off the wireframe background grid.\n" + "\t-nomusic turns off my most excellent background music.\n" + "\t-www invokes the built-in web browser.\n" + "\n" + "Example usage:\n" + "\n" + "\tspeed 640 480\n" + ); +} + + + +/* the main program body */ +int main(int argc, char *argv[]) +{ + int w = 0, h = 0; + int www = FALSE; + int i, n; + int display_flags = ALLEGRO_GENERATE_EXPOSE_EVENTS; + + srand(time(NULL)); + + al_set_org_name("liballeg.org"); + al_set_app_name("SPEED"); + + if (!al_init()) { + fprintf(stderr, "Could not initialise Allegro.\n"); + return 1; + } + al_init_primitives_addon(); + + /* parse the commandline */ + for (i=1; i<argc; i++) { + if (strcmp(argv[i], "-cheat") == 0) { + cheat = TRUE; + } + else if (strcmp(argv[i], "-simple") == 0) { + low_detail = TRUE; + } + else if (strcmp(argv[i], "-nogrid") == 0) { + no_grid = TRUE; + } + else if (strcmp(argv[i], "-nomusic") == 0) { + no_music = TRUE; + } + else if (strcmp(argv[i], "-www") == 0) { + www = TRUE; + } + else if (strcmp(argv[i], "-fullscreen") == 0) { + /* if no width is specified, assume fullscreen_window */ + display_flags |= w ? ALLEGRO_FULLSCREEN : ALLEGRO_FULLSCREEN_WINDOW; + } + else { + n = atoi(argv[i]); + + if (!n) { + usage(); + return 1; + } + + if (!w) { + w = n; + if (display_flags & ALLEGRO_FULLSCREEN_WINDOW) { + /* toggle from fullscreen_window to fullscreen */ + display_flags &= ~ALLEGRO_FULLSCREEN_WINDOW; + display_flags |= ALLEGRO_FULLSCREEN; + } + } + else if (!h) { + h = n; + } + else { + usage(); + return 1; + } + } + } + + /* it's a real shame that I had to take this out! */ + if (www) { + printf( + "\n" + "Unfortunately the built-in web browser feature had to be removed.\n" + "\n" + "I did get it more or less working as of Saturday evening (forms and\n" + "Java were unsupported, but tables and images were mostly rendering ok),\n" + "but the US Department of Justice felt that this was an unacceptable\n" + "monopolistic attempt to tie in web browsing functionality to an\n" + "unrelated product, so they threatened me with being sniped at from\n" + "the top of tall buildings by guys with high powered rifles unless I\n" + "agreed to disable this code.\n" + "\n" + "We apologise for any inconvenience that this may cause you.\n" + ); + + return 1; + } + + if (!w || !h) { + if (argc == 1 || (display_flags & ALLEGRO_FULLSCREEN_WINDOW)) { + w = 640; + h = 480; + } + else { + usage(); + return 1; + } + } + + /* set the screen mode */ + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); + al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); + + al_set_new_display_flags(display_flags); + screen = al_create_display(w, h); + if (!screen) { + fprintf(stderr, "Error setting %dx%d display mode\n", w, h); + return 1; + } + + /* To avoid performance problems on graphics drivers that don't support + * drawing to textures, we build up transition screens on memory bitmaps. + * We need a font loaded into a memory bitmap for those, then a font + * loaded into a video bitmap for the game view. Blech! + */ + al_init_font_addon(); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + font = al_create_builtin_font(); + if (!font) { + fprintf(stderr, "Error creating builtin font\n"); + return 1; + } + + al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); + font_video = al_create_builtin_font(); + if (!font_video) { + fprintf(stderr, "Error creating builtin font\n"); + return 1; + } + + /* set up everything else */ + al_install_keyboard(); + al_install_joystick(); + if (al_install_audio()) { + if (!al_reserve_samples(8)) + al_uninstall_audio(); + } + + init_input(); + init_sound(); + init_hiscore(); + + /* the main program body */ + while (title_screen()) { + if (play_game()) { + show_results(); + score_table(); + } + } + + /* time to go away now */ + shutdown_hiscore(); + shutdown_sound(); + + goodbye(); + + shutdown_input(); + + al_destroy_font(font); + al_destroy_font(font_video); + + return 0; +} diff --git a/allegro/demos/speed/message.c b/allegro/demos/speed/message.c new file mode 100644 index 00000000..4fb81b25 --- /dev/null +++ b/allegro/demos/speed/message.c @@ -0,0 +1,120 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Text message displaying functions. + */ + +#include <allegro5/allegro.h> +#include <allegro5/allegro_font.h> + +#include "speed.h" + + + +typedef struct MESSAGE +{ + char text[80]; + int time; + float x; + float y; + struct MESSAGE *next; +} MESSAGE; + + +static MESSAGE *msg; + + + +/* initialises the message functions */ +void init_message() +{ + msg = NULL; +} + + + +/* closes down the message module */ +void shutdown_message() +{ + MESSAGE *m; + + while (msg) { + m = msg; + msg = msg->next; + free(m); + } +} + + + +/* adds a new message to the display */ +void message(char *text) +{ + MESSAGE *m = malloc(sizeof(MESSAGE)); + + strcpy(m->text, text); + + m->time = 0; + + m->x = 0; + m->y = 0; + + m->next = msg; + msg = m; +} + + + +/* updates the message position */ +void update_message() +{ + int SCREEN_W = al_get_display_width(screen); + int SCREEN_H = al_get_display_height(screen); + MESSAGE **p = &msg; + MESSAGE *m = msg; + MESSAGE *tmp; + int y = SCREEN_H/2; + + while (m) { + if (m->time < 100) { + m->x *= 0.9; + m->x += (float)SCREEN_W * 0.05; + } + else { + m->x += (m->time - 100); + } + + m->y *= 0.9; + m->y += y * 0.1; + + m->time++; + + if (m->x > SCREEN_W + strlen(m->text)/4) { + *p = m->next; + tmp = m; + m = m->next; + free(tmp); + } + else { + p = &m->next; + m = m->next; + } + + y += 16; + } +} + + + +/* draws messages */ +void draw_message() +{ + MESSAGE *m = msg; + + while (m) { + textout_centre(font_video, m->text, m->x, m->y, makecol(255, 255, 255)); + m = m->next; + } +} + + diff --git a/allegro/demos/speed/player.c b/allegro/demos/speed/player.c new file mode 100644 index 00000000..34fb4f39 --- /dev/null +++ b/allegro/demos/speed/player.c @@ -0,0 +1,328 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Main player control functions. + */ + +#include <stdio.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_primitives.h> + +#include "speed.h" + + + +/* how many lives do we have left? */ +int lives; + + + +/* counters for various time delays */ +static int init_time; +static int die_time; +static int fire_time; + + + +/* current position and velocity */ +static float pos; +static float vel; + + + +/* which segments of health we currently possess */ +#define SEGMENTS 16 + +static int ganja[SEGMENTS]; + +/* Did you ever come across a DOS shareware game called "Ganja Farmer"? + * It is really very cool: you have to protect your crop from "Da Man", + * who is trying to bomb it, spray it with defoliants, etc. Superb + * reggae soundtrack, and the gameplay concept here is kind of similar, + * hence my variable names... + */ + + + +/* tell other people where we are */ +float player_pos() +{ + return pos; +} + + + +/* tell other people where to avoid us */ +float find_target(float x) +{ + int seg = (int)(x * SEGMENTS) % SEGMENTS; + int i, j; + + if (seg < 0) + seg += SEGMENTS; + + for (i=0; i<SEGMENTS/2; i++) { + j = (seg+i) % SEGMENTS; + + if (ganja[j]) + return (float)j / SEGMENTS + (0.5 / SEGMENTS); + + j = (seg-i) % SEGMENTS; + if (j < 0) + j += SEGMENTS; + + if (ganja[j]) + return (float)j / SEGMENTS + (0.5 / SEGMENTS); + } + + if (pos < 0.5) + return pos + 0.5; + else + return pos - 0.5; +} + + + +/* tell other people whether we are healthy */ +int player_dying() +{ + return ((die_time != 0) && (lives <= 1)); +} + + + +/* called by the badguys when they want to blow us up */ +int kill_player(float x, float y) +{ + int ret = FALSE; + + if (y >= 0.97) { + int seg = (int)(x * SEGMENTS) % SEGMENTS; + + if (ganja[seg]) { + ganja[seg] = FALSE; + explode(x, 0.98, 1); + sfx_explode_block(); + } + + ret = TRUE; + } + + if ((y >= 0.95) && (!init_time) && (!die_time) && (!cheat)) { + float d = pos - x; + + if (d < -0.5) + d += 1; + else if (d > 0.5) + d -= 1; + + if (ABS(d) < 0.06) { + die_time = 128; + + explode(x, 0.98, 2); + explode(x, 0.98, 4); + sfx_explode_player(); + + message("Ship Destroyed"); + + ret = TRUE; + } + } + + return ret; +} + + + +/* initialises the player functions */ +void init_player() +{ + int i; + + lives = 3; + + init_time = 128; + die_time = 0; + fire_time = 0; + + pos = 0.5; + vel = 0; + + for (i=0; i<SEGMENTS; i++) + ganja[i] = TRUE; +} + + + +/* closes down the player module */ +void shutdown_player() +{ +} + + + +/* advances the player to the next attack wave */ +void advance_player(int cycle) +{ + char buf[80]; + int bonus = 0; + int old_score = score; + int i; + + for (i=0; i<SEGMENTS; i++) { + if (ganja[i]) + bonus++; + else + ganja[i] = TRUE; + } + + if (bonus == SEGMENTS) { + message("Bonus: 100"); + score += 100; + } + + if (cycle) { + message("Bonus: 1000"); + score += 1000; + } + + sprintf(buf, "Score: %d", bonus); + message(buf); + + score += bonus; + + if ((get_hiscore() > 0) && (score > get_hiscore()) && (old_score <= get_hiscore())) { + message("New Record Score!"); + sfx_ping(3); + } + else if ((bonus == SEGMENTS) || (cycle)) { + sfx_ping(1); + } +} + + + +/* updates the player position */ +int update_player() +{ + poll_input(); + + /* quit game? */ + if (key[ALLEGRO_KEY_ESCAPE]) + return -1; + + /* safe period while initing */ + if (init_time) + init_time--; + + /* blown up? */ + if (die_time) { + die_time--; + + if (!die_time) { + lives--; + if (!lives) + return 1; + + init_time = 128; + pos = 0.5; + vel = 0; + + if (lives == 1) + message("This Is Your Final Life"); + else + message("One Life Remaining"); + } + } + + /* handle user left/right input */ + if (!die_time) { + if ((joy_left) || (key[ALLEGRO_KEY_LEFT])) + vel -= 0.005; + + if ((joy_right) || (key[ALLEGRO_KEY_RIGHT])) + vel += 0.005; + } + + /* move left and right */ + pos += vel; + + if (pos >= 1.0) + pos -= 1.0; + + if (pos < 0.0) + pos += 1.0; + + vel *= 0.67; + + /* fire bullets */ + if ((!die_time) && (!init_time) && (!fire_time)) { + if ((key[ALLEGRO_KEY_SPACE]) || (joy_b1)) { + fire_bullet(); + fire_time = 24; + } + } + + if (fire_time) + fire_time--; + + return 0; +} + + + +/* draws the player */ +void draw_player(int r, int g, int b, int (*project)(float *f, int *i, int c)) +{ + float shape[12]; + int ishape[12]; + int i; + + /* draw health segments */ + for (i=0; i<SEGMENTS; i++) { + if (ganja[i]) { + shape[0] = (float)i / SEGMENTS; + shape[1] = 0.98; + + shape[2] = (float)(i+1) / SEGMENTS; + shape[3] = 0.98; + + shape[4] = (float)(i+1) / SEGMENTS; + shape[5] = 1.0; + + shape[6] = (float)i / SEGMENTS; + shape[7] = 1.0; + + if (project(shape, ishape, 8)) + polygon(4, ishape, makecol(r/3, g/3, b/3)); + } + } + + /* flash on and off while initing, don't show while dead */ + if ((init_time & 4) || (die_time)) + return; + + /* draw the ship */ + shape[0] = pos - 0.04; + shape[1] = 0.98; + + shape[2] = pos - 0.02; + shape[3] = 0.97; + + shape[4] = pos; + shape[5] = 0.95; + + shape[6] = pos + 0.02; + shape[7] = 0.97; + + shape[8] = pos + 0.04; + shape[9] = 0.98; + + shape[10] = pos; + shape[11] = 0.98; + + if (project(shape, ishape, 12)) + polygon(6, ishape, makecol(r, g, b)); +} + + diff --git a/allegro/demos/speed/port.txt b/allegro/demos/speed/port.txt new file mode 100644 index 00000000..c6702d78 --- /dev/null +++ b/allegro/demos/speed/port.txt @@ -0,0 +1,30 @@ + + SPEED: Simultaneous Projections Employing an Ensemble of Displays. + + By Shawn Hargreaves, November 1999. + + Allegro 5 port by Peter Wang, April 2010 + + +This is a port of SPEED to Allegro 5. a4_aux.c contains a small +"compatibility" layer so that the original code did not need to be +disturbed too much. + +See speed.txt for the original information about the game. + +Have fun! + + + +User-visible changes from the original +-------------------------------------- + +- The game now defaults to a 640x480 screen resolution if you do not + supply any command line arguments. + +- The bpp (colour depth) command line option was removed. + +- The intersection points in the game grid only appear half as bright + as in the original. I'm not sure why, unless it was a bug in Allegro 4.x. + Admittedly the brighter pixels looked cooler. + diff --git a/allegro/demos/speed/sound.c b/allegro/demos/speed/sound.c new file mode 100644 index 00000000..cf926649 --- /dev/null +++ b/allegro/demos/speed/sound.c @@ -0,0 +1,1006 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * This file is quite possibly the most entirely pointless piece of + * code that I have ever written. I didn't want to include any external + * data, you see, so everything has to work entirely from C source, + * which means generating all the sounds from code. I don't know why + * I'm bothering, because this probably won't sound too good :-) + */ + +#include <math.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_audio.h> + +#include "speed.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + + + +/* generated sample waveforms */ +static ALLEGRO_SAMPLE *zap; +static ALLEGRO_SAMPLE *bang; +static ALLEGRO_SAMPLE *bigbang; +static ALLEGRO_SAMPLE *ping; +static ALLEGRO_SAMPLE *sine; +static ALLEGRO_SAMPLE *square; +static ALLEGRO_SAMPLE *saw; +static ALLEGRO_SAMPLE *bd; +static ALLEGRO_SAMPLE *snare; +static ALLEGRO_SAMPLE *hihat; + + + +#define RAND (((float)(rand() & 255) / 255.0) - 0.5) + + + +/* format: pitch, delay. Zero pitch = silence */ + + +static int part_1[] = +{ + /* tune A bass */ + + /* C */ 45, 6, 0, 2, + /* C */ 45, 6, 0, 10, + /* C */ 45, 6, 0, 2, + /* C */ 45, 8, 0, 4, + /* C */ 45, 8, 0, 4, + /* C */ 45, 6, 0, 2, + + /* F */ 50, 6, 0, 2, + /* F */ 50, 6, 0, 10, + /* F */ 50, 6, 0, 2, + /* F */ 50, 8, 0, 4, + /* F */ 50, 8, 0, 4, + /* F */ 50, 6, 0, 2, + + /* Ab */ 53, 6, 0, 2, + /* Ab */ 53, 6, 0, 10, + /* Ab */ 53, 6, 0, 2, + /* G */ 52, 8, 0, 4, + /* G */ 52, 8, 0, 4, + /* G */ 52, 6, 0, 2, + + /* C */ 45, 6, 0, 2, + /* C */ 45, 6, 0, 10, + /* C */ 45, 6, 0, 2, + /* C */ 45, 8, 0, 4, + /* C */ 45, 8, 0, 4, + /* C */ 45, 6, 0, 2, + + + /* tune A repeat bass */ + + /* C */ 45, 6, 0, 2, + /* C */ 45, 6, 0, 10, + /* C */ 45, 6, 0, 2, + /* C */ 45, 8, 0, 4, + /* C */ 45, 8, 0, 4, + /* C */ 45, 6, 0, 2, + + /* F */ 50, 6, 0, 2, + /* F */ 50, 6, 0, 10, + /* F */ 50, 6, 0, 2, + /* F */ 50, 8, 0, 4, + /* F */ 50, 8, 0, 4, + /* F */ 50, 6, 0, 2, + + /* Ab */ 53, 6, 0, 2, + /* Ab */ 53, 6, 0, 10, + /* Ab */ 53, 6, 0, 2, + /* G */ 52, 8, 0, 4, + /* G */ 52, 8, 0, 4, + /* G */ 52, 6, 0, 2, + + /* C */ 45, 6, 0, 2, + /* C */ 45, 6, 0, 10, + /* C */ 45, 6, 0, 2, + /* C */ 45, 8, 0, 4, + /* C */ 45, 8, 0, 4, + /* C */ 45, 6, 0, 2, + + + /* tune B bass */ + + /* C */ 45, 52, 0, 4, + /* C */ 45, 6, 0, 2, + + /* D */ 47, 52, 0, 4, + /* D */ 47, 6, 0, 2, + + /* Eb */ 48, 14, 0, 2, + /* F */ 50, 14, 0, 2, + /* G */ 52, 14, 0, 2, + /* Ab */ 53, 14, 0, 2, + + /* Bb */ 55, 6, 0, 2, + /* Bb */ 55, 6, 0, 10, + /* Bb */ 55, 6, 0, 2, + /* C */ 57, 14, 0, 2, + /* G */ 52, 14, 0, 2, + + + /* tune B repeat bass */ + + /* C */ 45, 6, 0, 2, + /* C */ 45, 6, 0, 10, + /* C */ 45, 6, 0, 2, + /* C */ 45, 8, 0, 4, + /* C */ 45, 8, 0, 4, + /* C */ 45, 6, 0, 2, + + /* D */ 47, 6, 0, 2, + /* D */ 47, 6, 0, 10, + /* D */ 47, 6, 0, 2, + /* D */ 47, 8, 0, 4, + /* D */ 47, 8, 0, 4, + /* D */ 47, 6, 0, 2, + + /* Eb */ 48, 14, 0, 2, + /* F */ 50, 14, 0, 2, + /* G */ 52, 14, 0, 2, + /* Ab */ 53, 14, 0, 2, + + /* Bb */ 55, 6, 0, 2, + /* Bb */ 55, 6, 0, 10, + /* Bb */ 55, 6, 0, 2, + /* C */ 57, 14, 0, 2, + /* G */ 52, 14, 0, 2, + + + 0, 0 +}; + + + +static int part_2[] = +{ + /* tune A harmony */ + + /* C */ 57, 30, 0, 2, + /* Eb */ 60, 14, 0, 2, + /* C */ 57, 14, 0, 2, + + /* F */ 62, 30, 0, 2, + /* Ab */ 65, 14, 0, 2, + /* F */ 62, 14, 0, 2, + + /* Ab */ 65, 30, 0, 2, + /* G */ 64, 14, 0, 2, + /* G */ 52, 14, 0, 2, + + /* C */ 57, 30, 0, 2, + /* Eb */ 60, 14, 0, 2, + /* Eb */ 60, 3, 0, 1, + /* D */ 59, 3, 0, 1, + /* Db */ 58, 3, 0, 1, + /* C */ 57, 3, 0, 1, + + + /* tune A repeat harmony */ + + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* C */ 69, 6, 0, 2, + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* C */ 69, 6, 0, 6, + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* C */ 69, 6, 0, 2, + + /* C */ 57, 3, 0, 1, + /* F */ 62, 3, 0, 1, + /* Ab */ 65, 3, 0, 1, + /* C */ 69, 6, 0, 2, + /* C */ 57, 3, 0, 1, + /* F */ 62, 3, 0, 1, + /* Ab */ 65, 3, 0, 1, + /* C */ 69, 6, 0, 6, + /* C */ 57, 3, 0, 1, + /* F */ 62, 3, 0, 1, + /* Ab */ 65, 3, 0, 1, + /* C */ 69, 6, 0, 2, + + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* Ab */ 65, 3, 0, 1, + /* C */ 69, 6, 0, 2, + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* Ab */ 65, 3, 0, 1, + /* C */ 69, 6, 0, 6, + /* C */ 57, 3, 0, 1, + /* D */ 59, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* D */ 71, 6, 0, 2, + + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* C */ 69, 6, 0, 2, + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* C */ 69, 6, 0, 6, + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* C */ 69, 6, 0, 2, + + + /* tune B melody */ + + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* F */ 62, 3, 0, 1, + /* G */ 64, 5, 0, 3, + /* Ab */ 65, 3, 0, 1, + /* F */ 62, 5, 0, 3, + /* G */ 64, 3, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* F */ 62, 3, 0, 1, + /* D */ 59, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + + /* D */ 59, 3, 0, 1, + /* F# */ 63, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* A */ 66, 5, 0, 3, + /* Bb */ 67, 3, 0, 1, + /* G */ 64, 5, 0, 3, + /* A */ 66, 3, 0, 1, + /* F# */ 63, 5, 0, 3, + /* G */ 64, 3, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* F# */ 63, 2, 0, 1, + /* Eb */ 60, 2, 0, 1, + /* D */ 59, 1, 0, 1, + + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* F */ 62, 3, 0, 1, + /* G */ 64, 5, 0, 3, + /* Ab */ 65, 3, 0, 1, + /* F */ 62, 5, 0, 3, + /* G */ 64, 3, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* F */ 62, 3, 0, 1, + /* D */ 59, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + + /* D */ 59, 3, 0, 1, + /* E */ 61, 3, 0, 1, + /* F# */ 63, 3, 0, 1, + /* Ab */ 65, 5, 0, 3, + /* F# */ 63, 3, 0, 1, + /* Ab */ 65, 3, 0, 1, + /* Bb */ 67, 3, 0, 1, + /* C */ 69, 8, 0, 24, + + + /* tune B repeat melody */ + + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* F */ 62, 3, 0, 1, + /* G */ 64, 5, 0, 3, + /* Ab */ 65, 3, 0, 1, + /* F */ 62, 5, 0, 3, + /* G */ 64, 3, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* F */ 62, 3, 0, 1, + /* D */ 59, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + + /* D */ 59, 3, 0, 1, + /* F# */ 63, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* A */ 66, 5, 0, 3, + /* Bb */ 67, 3, 0, 1, + /* G */ 64, 5, 0, 3, + /* A */ 66, 3, 0, 1, + /* F# */ 63, 5, 0, 3, + /* G */ 64, 3, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* F# */ 63, 2, 0, 1, + /* Eb */ 60, 2, 0, 1, + /* D */ 59, 1, 0, 1, + + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 3, 0, 1, + /* F */ 62, 3, 0, 1, + /* G */ 64, 5, 0, 3, + /* Ab */ 65, 3, 0, 1, + /* F */ 62, 5, 0, 3, + /* G */ 64, 3, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* F */ 62, 3, 0, 1, + /* D */ 59, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + + /* D */ 59, 3, 0, 1, + /* E */ 61, 3, 0, 1, + /* F# */ 63, 3, 0, 1, + /* Ab */ 65, 5, 0, 3, + /* F# */ 63, 3, 0, 1, + /* Ab */ 65, 3, 0, 1, + /* Bb */ 67, 3, 0, 1, + /* C */ 69, 8, 0, 24, + + + 0, 0 +}; + + + +static int part_3[] = +{ + /* tune A melody */ + + /* G */ 64, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* Bb */ 67, 3, 0, 1, + /* C */ 57, 5, 0, 3, + /* C */ 57, 3, 0, 1, + /* D */ 59, 3, 0, 1, + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + /* D */ 59, 4, 0, 1, + /* C */ 57, 4, 0, 1, + /* Bb */ 55, 5, 0, 5, + + /* G */ 64, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* Bb */ 67, 3, 0, 1, + /* C */ 57, 8, 0, 4, + /* D */ 59, 5, 0, 3, + /* C */ 57, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + /* Eb */ 60, 3, 0, 1, + /* D */ 59, 3, 0, 1, + /* C */ 57, 3, 0, 9, + + /* G */ 64, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* Bb */ 67, 3, 0, 1, + /* C */ 57, 5, 0, 3, + /* D */ 59, 5, 0, 3, + /* C */ 57, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + /* Eb */ 60, 3, 0, 1, + /* D */ 59, 3, 0, 1, + /* C */ 57, 3, 0, 1, + + /* G */ 64, 5, 0, 3, + /* G */ 64, 5, 0, 3, + /* Bb */ 67, 5, 0, 3, + /* C */ 57, 8, 0, 32, + + + /* tune A repeat melody */ + + /* G */ 64, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* Bb */ 67, 3, 0, 1, + /* C */ 57, 5, 0, 3, + /* C */ 57, 3, 0, 1, + /* D */ 59, 3, 0, 1, + /* C */ 57, 3, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + /* D */ 59, 4, 0, 1, + /* C */ 57, 4, 0, 1, + /* Bb */ 55, 5, 0, 5, + + /* G */ 64, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* Bb */ 67, 3, 0, 1, + /* C */ 57, 8, 0, 4, + /* D */ 59, 5, 0, 3, + /* C */ 57, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + /* Eb */ 60, 3, 0, 1, + /* D */ 59, 3, 0, 1, + /* C */ 57, 3, 0, 9, + + /* G */ 64, 3, 0, 1, + /* G */ 64, 3, 0, 1, + /* Bb */ 67, 3, 0, 1, + /* C */ 57, 5, 0, 3, + /* D */ 59, 5, 0, 3, + /* C */ 57, 5, 0, 3, + /* Eb */ 60, 5, 0, 3, + /* Eb */ 60, 3, 0, 1, + /* D */ 59, 3, 0, 1, + /* C */ 57, 3, 0, 1, + + /* G */ 64, 5, 0, 3, + /* G */ 64, 5, 0, 3, + /* Bb */ 67, 5, 0, 3, + /* C */ 57, 8, 0, 32, + + + /* tune B harmony */ + + /* C */ 57, 52, 0, 4, + /* C */ 57, 6, 0, 2, + + /* D */ 59, 52, 0, 4, + /* D */ 59, 6, 0, 2, + + /* Eb */ 60, 14, 0, 2, + /* F */ 62, 14, 0, 2, + /* G */ 64, 14, 0, 2, + /* Ab */ 65, 14, 0, 2, + + /* Bb */ 67, 6, 0, 2, + /* Bb */ 67, 6, 0, 10, + /* Bb */ 67, 6, 0, 2, + /* C */ 69, 14, 0, 2, + /* G */ 64, 2, + /* F# */ 63, 2, + /* G */ 64, 2, + /* Ab */ 65, 2, + /* G */ 64, 3, 0, 1, + /* D */ 59, 3, 0, 9, + + + /* tune B repeat harmony */ + + /* C */ 57, 11, 0, 1, + /* D */ 59, 4, 0, 8, + /* C */ 57, 11, 0, 1, + /* D */ 59, 5, 0, 3, + /* C */ 57, 7, 0, 1, + /* D */ 59, 3, 0, 9, + + /* D */ 59, 11, 0, 1, + /* Eb */ 60, 4, 0, 8, + /* D */ 59, 11, 0, 1, + /* Eb */ 60, 5, 0, 3, + /* D */ 59, 7, 0, 1, + /* Eb */ 60, 3, 0, 9, + + /* Eb */ 60, 11, 0, 1, + /* F */ 62, 5, 0, 7, + /* G */ 64, 11, 0, 1, + /* Ab */ 65, 10, 0, 2, + /* Bb */ 67, 7, 0, 9, + + /* Bb */ 67, 14, 0, 2, + /* Bb */ 67, 6, 0, 2, + /* C */ 69, 14, 0, 2, + /* G */ 64, 2, + /* F# */ 63, 2, + /* G */ 64, 2, + /* Ab */ 65, 2, + /* G */ 64, 3, 0, 1, + /* D */ 59, 3, 0, 1, + + + 0, 0 +}; + + + +static int part_4[] = +{ + /* tune A drums */ + + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 2, 4, 2, 4, 2, 2, 2, 2, + + + /* tune A repeat drums */ + + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 2, 4, 1, 4, 2, 2, 2, 2, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 2, 4, 1, 4, 2, 2, 2, 2, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 2, 4, 1, 4, 2, 2, 2, 2, + 1, 4, 3, 4, 2, 4, 3, 4, + 1, 4, 3, 4, 2, 4, 3, 4, + 2, 4, 1, 4, 1, 4, 2, 2, 2, 2, + 1, 4, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, + + + /* tune B drums */ + + 1, 16, 1, 8, 1, 8, + 1, 16, 1, 8, 1, 4, 1, 4, + 1, 16, 1, 8, 1, 8, + 1, 16, 1, 8, 1, 4, 1, 4, + 1, 16, 1, 16, 1, 16, 1, 8, 1, 8, + 1, 8, 1, 8, 1, 4, 1, 4, 1, 4, 1, 4, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 4, 2, 4, 2, 4, 2, 2, 2, 2, + + + /* tune B repeat drums */ + 1, 8, 2, 8, 1, 12, 1, 4, + 1, 16, 1, 4, 2, 4, 2, 4, 2, 2, 2, 2, + 1, 8, 2, 8, 1, 12, 1, 4, + 1, 16, 1, 4, 2, 4, 2, 4, 2, 2, 2, 2, + 1, 8, 2, 8, 1, 4, 1, 4, 2, 8, + 1, 8, 2, 8, 1, 4, 1, 4, 2, 8, + 1, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 1, 4, 2, 4, 1, 4, + 2, 8, 1, 8, 1, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, + + + 0, 0 +}; + + + +/* music player state */ +#define NUM_PARTS 4 + +static int *part_ptr[NUM_PARTS] = +{ + part_1, part_2, part_3, part_4 +}; + +static int *part_pos[NUM_PARTS]; +static int part_time[NUM_PARTS]; + +static int freq_table[256]; + +static ALLEGRO_SAMPLE_INSTANCE *part_voice[NUM_PARTS]; + +static ALLEGRO_TIMER *music_timer; + +#define PAN(x) (((x) - 128)/128.0) + + + +/* the main music player function */ +static void music_player() +{ + int i, note; + + for (i=0; i<NUM_PARTS; i++) { + if (part_time[i] <= 0) { + note = part_pos[i][0]; + part_time[i] = part_pos[i][1]; + + al_stop_sample_instance(part_voice[i]); + + if (i == 3) { + if (note == 1) { + al_set_sample(part_voice[i], bd); + al_set_sample_instance_pan(part_voice[i], PAN(128)); + } + else if (note == 2) { + al_set_sample(part_voice[i], snare); + al_set_sample_instance_pan(part_voice[i], PAN(160)); + } + else { + al_set_sample(part_voice[i], hihat); + al_set_sample_instance_pan(part_voice[i], PAN(96)); + } + + al_play_sample_instance(part_voice[i]); + } + else { + if (note > 0) { + al_set_sample_instance_speed(part_voice[i], freq_table[note]/22050.0); + al_play_sample_instance(part_voice[i]); + } + } + + part_pos[i] += 2; + if (!part_pos[i][1]) + part_pos[i] = part_ptr[i]; + } + + part_time[i]--; + } +} + + + +/* this code is sick */ +static void init_music() +{ + float vol, val; + char *p; + int i; + + if (!al_is_audio_installed()) + return; + + /* sine waves (one straight and one with oscillator sync) for the bass */ + sine = create_sample_u8(22050, 64); + p = (char *)al_get_sample_data(sine); + + for (i=0; i<64; i++) { + *p = 128 + (sin((float)i * M_PI / 32.0) + sin((float)i * M_PI / 12.0)) * 8.0; + p++; + } + + /* square wave for melody #1 */ + square = create_sample_u8(22050, 64); + p = (char *)al_get_sample_data(square); + + for (i=0; i<64; i++) { + *p = (i < 32) ? 120 : 136; + p++; + } + + /* saw wave for melody #2 */ + saw = create_sample_u8(22050, 64); + p = (char *)al_get_sample_data(saw); + + for (i=0; i<64; i++) { + *p = 120 + (i*4 & 255) / 16; + p++; + } + + /* bass drum */ + bd = create_sample_u8(22050, 1024); + p = (char *)al_get_sample_data(bd); + + for (i=0; i<1024; i++) { + vol = (float)(1024-i) / 16.0; + *p = 128 + (sin((float)i / 48.0) + sin((float)i / 32.0)) * vol; + p++; + } + + /* snare drum */ + snare = create_sample_u8(22050, 3072); + p = (char *)al_get_sample_data(snare); + + val = 0; + + for (i=0; i<3072; i++) { + vol = (float)(3072-i) / 24.0; + val = (val * 0.9) + (RAND * 0.1); + *p = 128 + val * vol; + p++; + } + + /* hihat */ + hihat = create_sample_u8(22050, 1024); + p = (char *)al_get_sample_data(hihat); + + for (i=0; i<1024; i++) { + vol = (float)(1024-i) / 192.0; + *p = 128 + (sin((float)i / 4.2) + RAND) * vol; + p++; + } + + /* start up the player */ + for (i=0; i<256; i++) + freq_table[i] = (int)(350.0 * pow(2.0, (float)i/12.0)); + + for (i=0; i<NUM_PARTS; i++) { + part_pos[i] = part_ptr[i]; + part_time[i] = 0; + } + + part_voice[0] = al_create_sample_instance(sine); + part_voice[1] = al_create_sample_instance(square); + part_voice[2] = al_create_sample_instance(saw); + part_voice[3] = al_create_sample_instance(bd); + + al_attach_sample_instance_to_mixer(part_voice[0], al_get_default_mixer()); + al_attach_sample_instance_to_mixer(part_voice[1], al_get_default_mixer()); + al_attach_sample_instance_to_mixer(part_voice[2], al_get_default_mixer()); + al_attach_sample_instance_to_mixer(part_voice[3], al_get_default_mixer()); + + al_set_sample_instance_playmode(part_voice[0], ALLEGRO_PLAYMODE_LOOP); + al_set_sample_instance_playmode(part_voice[1], ALLEGRO_PLAYMODE_LOOP); + al_set_sample_instance_playmode(part_voice[2], ALLEGRO_PLAYMODE_LOOP); + al_set_sample_instance_playmode(part_voice[3], ALLEGRO_PLAYMODE_ONCE); + + al_set_sample_instance_gain(part_voice[0], 192/255.0); + al_set_sample_instance_gain(part_voice[1], 192/255.0); + al_set_sample_instance_gain(part_voice[2], 192/255.0); + al_set_sample_instance_gain(part_voice[3], 255/255.0); + + al_set_sample_instance_pan(part_voice[0], PAN(128)); + al_set_sample_instance_pan(part_voice[1], PAN(224)); + al_set_sample_instance_pan(part_voice[2], PAN(32)); + al_set_sample_instance_pan(part_voice[3], PAN(128)); + + music_timer = al_create_timer(ALLEGRO_BPS_TO_SECS(22)); +} + + + +/* timer callback for playing ping samples */ +static int ping_vol; +static int ping_freq; +static int ping_count; +static ALLEGRO_TIMER *ping_timer; + + +static int ping_proc(void) +{ + ping_freq = ping_freq*4/3; + + play_sample(ping, ping_vol, 128, ping_freq, FALSE); + + if (!--ping_count) + return FALSE; + + return TRUE; +} + + + +/* thread to keep the music playing and the pings pinging */ +static ALLEGRO_THREAD *sound_update_thread; + + + +static void *sound_update_proc(ALLEGRO_THREAD *thread, void *arg) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + (void)arg; + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_timer_event_source(ping_timer)); + if (music_timer) + al_register_event_source(queue, al_get_timer_event_source(music_timer)); + + while (!al_get_thread_should_stop(thread)) { + if (!al_wait_for_event_timed(queue, &event, 0.25)) + continue; + + if (event.any.source == (void *)music_timer) + music_player(); + + if (event.any.source == (void *)ping_timer) { + if (!ping_proc()) + al_stop_timer(ping_timer); + } + } + + al_destroy_event_queue(queue); + + return NULL; +} + + + +/* initialises the sound system */ +void init_sound() +{ + float f, osc1, osc2, freq1, freq2, vol, val; + char *p; + int len; + int i; + + if (!al_is_audio_installed()) + return; + + /* zap (firing sound) consists of multiple falling saw waves */ + len = 8192; + zap = create_sample_u8(22050, len); + + p = (char *)al_get_sample_data(zap); + + osc1 = 0; + freq1 = 0.02; + + osc2 = 0; + freq2 = 0.025; + + for (i=0; i<len; i++) { + vol = (float)(len - i) / (float)len * 127; + + *p = 128 + (fmod(osc1, 1) + fmod(osc2, 1) - 1) * vol; + + osc1 += freq1; + freq1 -= 0.000001; + + osc2 += freq2; + freq2 -= 0.00000125; + + p++; + } + + /* bang (explosion) consists of filtered noise */ + len = 8192; + bang = create_sample_u8(22050, len); + + p = (char *)al_get_sample_data(bang); + + val = 0; + + for (i=0; i<len; i++) { + vol = (float)(len - i) / (float)len * 255; + val = (val * 0.75) + (RAND * 0.25); + *p = 128 + val * vol; + p++; + } + + /* big bang (explosion) consists of noise plus rumble */ + len = 24576; + bigbang = create_sample_u8(11025, len); + + p = (char *)al_get_sample_data(bigbang); + + val = 0; + + osc1 = 0; + osc2 = 0; + + for (i=0; i<len; i++) { + vol = (float)(len - i) / (float)len * 128; + + f = 0.5 + ((float)i / (float)len * 0.4); + val = (val * f) + (RAND * (1-f)); + + *p = 128 + (val + (sin(osc1) + sin(osc2)) / 4) * vol; + + osc1 += 0.03; + osc2 += 0.04; + + p++; + } + + /* ping consists of two sine waves */ + len = 8192; + ping = create_sample_u8(22050, len); + + p = (char *)al_get_sample_data(ping); + + osc1 = 0; + osc2 = 0; + + for (i=0; i<len; i++) { + vol = (float)(len - i) / (float)len * 31; + + *p = 128 + (sin(osc1) + sin(osc2) - 1) * vol; + + osc1 += 0.2; + osc2 += 0.3; + + p++; + } + + ping_timer = al_create_timer(0.3); + + /* set up my lurvely music player :-) */ + if (!no_music) { + init_music(); + al_start_timer(music_timer); + } + + sound_update_thread = al_create_thread(sound_update_proc, NULL); + al_start_thread(sound_update_thread); +} + + + +/* closes down the sound system */ +void shutdown_sound() +{ + if (!al_is_audio_installed()) + return; + + al_destroy_thread(sound_update_thread); + al_destroy_timer(ping_timer); + + al_stop_samples(); + + al_destroy_sample(zap); + al_destroy_sample(bang); + al_destroy_sample(bigbang); + al_destroy_sample(ping); + + if (!no_music) { + al_destroy_timer(music_timer); + + al_destroy_sample_instance(part_voice[0]); + al_destroy_sample_instance(part_voice[1]); + al_destroy_sample_instance(part_voice[2]); + al_destroy_sample_instance(part_voice[3]); + + al_destroy_sample(sine); + al_destroy_sample(square); + al_destroy_sample(saw); + al_destroy_sample(bd); + al_destroy_sample(snare); + al_destroy_sample(hihat); + } +} + + + +/* plays a shoot sound effect */ +void sfx_shoot() +{ + if (al_is_audio_installed()) + play_sample(zap, 64, 128, 1000, FALSE); +} + + + +/* plays an alien explosion sound effect */ +void sfx_explode_alien() +{ + if (al_is_audio_installed()) + play_sample(bang, 192, 128, 1000, FALSE); +} + + + +/* plays a block explosion sound effect */ +void sfx_explode_block() +{ + if (al_is_audio_installed()) + play_sample(bang, 224, 128, 400, FALSE); +} + + + +/* plays a player explosion sound effect */ +void sfx_explode_player() +{ + if (al_is_audio_installed()) + play_sample(bigbang, 255, 128, 1000, FALSE); +} + + + +/* plays a ping sound effect */ +void sfx_ping(int times) +{ + if (!al_is_audio_installed()) + return; + + if (times) { + if (times > 1) { + ping_vol = 255; + ping_freq = 500; + } + else { + ping_vol = 128; + ping_freq = 1000; + } + + ping_count = times; + + play_sample(ping, ping_vol, 128, ping_freq, FALSE); + + al_start_timer(ping_timer); + } + else + play_sample(ping, 255, 128, 500, FALSE); +} + diff --git a/allegro/demos/speed/speed.h b/allegro/demos/speed/speed.h new file mode 100644 index 00000000..43fb4867 --- /dev/null +++ b/allegro/demos/speed/speed.h @@ -0,0 +1,102 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Global defines. + */ + +#ifndef __SPEED_H__ +#define __SPEED_H__ + +#include "a4_aux.h" + + +/* global state variables */ +extern int cheat; +extern int low_detail; +extern int no_grid; +extern int no_music; +extern int lives; +extern int score; + + +/* from title.c */ +int title_screen(); +void show_results(); +void goodbye(); + + +/* from view.c */ +void init_view(); +void shutdown_view(); +int advance_view(); +void update_view(); +void draw_view(); +float view_size(); + + +/* from player.c */ +void init_player(); +void shutdown_player(); +void advance_player(int cycle); +int update_player(); +void draw_player(int r, int g, int b, int (*project)(float *f, int *i, int c)); +float player_pos(); +float find_target(float x); +int player_dying(); +int kill_player(float x, float y); + + +/* from badguys.c */ +void init_badguys(); +void shutdown_badguys(); +int update_badguys(); +void draw_badguys(int r, int g, int b, int (*project)(float *f, int *i, int c)); +void lay_attack_wave(int reset); + + +/* from bullets.c */ +void init_bullets(); +void shutdown_bullets(); +void update_bullets(); +void draw_bullets(int r, int g, int b, int (*project)(float *f, int *i, int c)); +void fire_bullet(); +void *get_first_bullet(float *x, float *y); +void *get_next_bullet(void *b, float *x, float *y); +void kill_bullet(void *b); + + +/* from explode.c */ +void init_explode(); +void shutdown_explode(); +void update_explode(); +void draw_explode(int r, int g, int b, int (*project)(float *f, int *i, int c)); +void explode(float x, float y, int big); + + +/* from message.c */ +void init_message(); +void shutdown_message(); +void update_message(); +void draw_message(); +void message(char *text); + + +/* from hiscore.c */ +void init_hiscore(); +void shutdown_hiscore(); +void score_table(); +int get_hiscore(); + + +/* from sound.c */ +void init_sound(); +void shutdown_sound(); +void sfx_shoot(); +void sfx_explode_alien(); +void sfx_explode_block(); +void sfx_explode_player(); +void sfx_ping(int times); + + + +#endif /* __SPEED_H__ */ diff --git a/allegro/demos/speed/speed.txt b/allegro/demos/speed/speed.txt new file mode 100644 index 00000000..75706c20 --- /dev/null +++ b/allegro/demos/speed/speed.txt @@ -0,0 +1,210 @@ + + SPEED: Simultaneous Projections Employing an Ensemble of Displays. + + Or alternatively: Stupid Pointless Effort at Establishing a Dumb Acronym. + + By Shawn Hargreaves, November 1999. + + +This program is my entry for the Allegro SpeedHack 1999, and was written +over the weekend of November 27/28. Many thanks to Arron Shutt for +organising this competition, and to the various musicians who kept me sane +(?) during it (notably Trent Reznor, Adrian Belew, Charles Mingus, Miles +Davis, Mike Keneally, and Robert Fripp). + +It should be pretty obvious how to play, as long as you know how to press +the spacebar and left/right arrow keys. The objective is to protect the +blocks underneath your ship: you get one point for each block left at the +end of an attack wave, and a hundred bonus points if you manage to preserve +all sixteen blocks. + +Hint: the later levels of this game are much easier to play if you view them +through tinted glasses, to filter out only one of the views :-) + +You gain very little from running it in a truecolor mode (the title screens +look a bit nicer, but game graphics are almost identical to in 8 bit color). +It does look very cramped in a 320x200 resolution, though, so I recommend +playing it in 640x480x8. + +This code is free: do with it as you will. + +The remainder of this file is a realtime log, with entries added +chronologically during the course of the hack. The numbered subdirectories +contain snapshots of the code taken at various times over the weekend. It is +unlikely that anything but the final version will compile on systems other +than Linux. + + + +10-26-1999, at 14:56 +-------------------- + +I've written myself a makefile, and a script which ought to be able to send +this message to the website automatically. If you see this text, then it +worked! + + + +10-26-1999, at 15:18 +-------------------- + +Design doc: + +Traditional Space Invaders type gameplay: aliens move down the screen, you +move across the bottom firing upwards. Three lives. Your goal is to protect +blocks underneath you, and you get score for having blocks left at the end +of each attack wave. Alien motion will be as complex as I have time for, +including Centipede style splitting. + +This 2d action will be rendered in four different psuedo-3d viewports: +normal flat mode, inside of a tube, outside of a large cylinder, and in +spherical coordinates. Early attack waves use only one viewpoint, later ones +tile multiple views of the same action, and toward the end of the sequence +the views are overlaid (additive color). If you complete the sequence, it +cycles but with vastly increased game speed. + +When changing attack waves, views will slide around to their new locations +(that should look pretty cool). + +Any color depth, any resolution. + +No time for drawing graphics, so everything will be simple vector art. + +Bullets are surrounded by spining wireframe square, flightsim targetting +style. + +Explosions are expanding XLU circlefill, plus more rapidly expanding single +circle shockwaves. + +Wow, I think that is the most detailed formal game design that I have ever +written! I don't have time for this, better get coding... + + + +10-26-1999, at 17:37 +-------------------- + +Basic game structure is in place: init code, commandline parsing, title +screen, stupid little music bit at the end. + + + +10-27-1999, at 10:21 +-------------------- + +10:30 AM on saturday morning: just got out of bed and am ready to start some +serious work. Title and ending screens are finished, so it is just the game +itself left to be written! + + + +10-27-1999, at 13:14 +-------------------- + +Lots of new source files added: 3d viewport system is in place (sliding +screen windows and all but one of the 3d projections). + + + +10-27-1999, at 14:04 +-------------------- + +Player movement is in, so you can see the different projections in action... + + + +10-27-1999, at 15:08 +-------------------- + +Added text messages (for status display, number of lives left, etc) that +float over the middle of the screen, and implemented the final 3d +projection mode, so all the different views are working now. + + + +10-27-1999, at 16:17 +-------------------- + +Bullet code is finished. + + + +10-27-1999, at 17:55 +-------------------- + +Enemies are in, and you can shoot them now. + +Still todo: more interesting enemy movememnt, you dying. + +This is going faster than I expected, so I should be able to get that +finished this evening, and then have tomorrow free either to relax, +or perhaps to add sound and a hiscore table... + + + +10-27-1999, at 19:18 +-------------------- + +You can die now, and the scoring mechanism is complete. + + + +10-27-1999, at 22:55 +-------------------- + +Enemy wave patterns are finished! It is a table-driven system, with a +cycle of 26 different attack patterns before the thing repeats. I've +just finished typing in all the tables, so the game can now be played +the whole way through, ie. the gameplay side of things is complete! + +All that remains is cosmetic tweaking (sound, hiscore, etc). + + + +10-28-1999, at 00:02 +-------------------- + +Various tweaks to get it working with djgpp, MSVC, and Watcom (I've been +developing in X up until now). + + + +10-28-1999, at 13:42 +-------------------- + +Scoretable is finished. + +Unfortunately this thing has reached the point where it is actually quite +fun to play, which is getting in the way of my actually finishing it :-) + + + +10-28-1999, at 15:40 +-------------------- + +Some (really cheesy old-skool arcade style :-) sound effects are in. + + + +10-28-1999, at 19:43 +-------------------- + +Music is finished! And that means, the whole thing is pretty much complete. +I just need to test that it still works in DOS/Windows, and take some +screenshots, and then I can upload it. Yippee! And it is still pretty +early on Sunday evening... + +The music is quite possibly even more crap than the sound effects, which +is quite an achievement! The goal was to avoid using any external resources +at all, which means that all graphics and sounds have to be written as +pure C code in a text editor. In other words, sound samples are generated +from basic waveforms, and I typed in all the music notes as data tables. +I haven't done that since the old days on my 8 bit Oric machine, but it +was quite satisfying. The results don't sound _quite_ up to what you +can do with more capable sound editing tools, but hey, for an arrangement +done entirely inside a text editor, I don't think this is too bad :-) + +Stay tuned for an upload of the final version... + +The End. + diff --git a/allegro/demos/speed/title.c b/allegro/demos/speed/title.c new file mode 100644 index 00000000..db9cb0a5 --- /dev/null +++ b/allegro/demos/speed/title.c @@ -0,0 +1,297 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Title screen and results display. + */ + +#include <math.h> +#include <stdio.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_audio.h> +#include <allegro5/allegro_font.h> +#include <allegro5/allegro_primitives.h> + +#include "speed.h" + + + +/* draws text with a dropshadow */ +static void textout_shadow(char *msg, int x, int y, ALLEGRO_COLOR c) +{ + textout_centre(font, msg, x+1, y+1, makecol(0, 0, 0)); + textout_centre(font, msg, x, y, c); +} + + + +/* display the title screen */ +int title_screen() +{ + int SCREEN_W = al_get_display_width(screen); + int SCREEN_H = al_get_display_height(screen); + ALLEGRO_BITMAP *bmp, *b; + ALLEGRO_COLOR white = makecol(255, 255, 255); + int i, j, y; + + bmp = create_memory_bitmap(SCREEN_W, SCREEN_H); + al_set_target_bitmap(bmp); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + for (i=0; i<SCREEN_H/2; i++) { + hline(0, i, SCREEN_W, makecol(0, 0, i*255/(SCREEN_H/2))); + hline(0, SCREEN_H-i-1, SCREEN_W, makecol(0, 0, i*255/(SCREEN_H/2))); + } + + solid_mode(); + + b = create_memory_bitmap(40, 8); + al_set_target_bitmap(b); + al_clear_to_color(al_map_rgba(0, 0, 0, 0)); + + textout(font, "SPEED", 0, 0, makecol(0, 0, 0)); + stretch_sprite(bmp, b, SCREEN_W/128+8, SCREEN_H/24+8, SCREEN_W, SCREEN_H); + + textout(font, "SPEED", 0, 0, makecol(0, 0, 64)); + stretch_sprite(bmp, b, SCREEN_W/128, SCREEN_H/24, SCREEN_W, SCREEN_H); + + al_set_target_bitmap(bmp); + + al_destroy_bitmap(b); + + textout_shadow("Simultaneous Projections", SCREEN_W/2, SCREEN_H/2-80, white); + textout_shadow("Employing an Ensemble of Displays", SCREEN_W/2, SCREEN_H/2-64, white); + + textout_shadow("Or alternatively: Stupid Pointless", SCREEN_W/2, SCREEN_H/2-32, white); + textout_shadow("Effort at Establishing a Dumb Acronym", SCREEN_W/2, SCREEN_H/2-16, white); + + textout_shadow("By Shawn Hargreaves, 1999", SCREEN_W/2, SCREEN_H/2+16, white); + textout_shadow("Written for the Allegro", SCREEN_W/2, SCREEN_H/2+48, white); + textout_shadow("SpeedHack competition", SCREEN_W/2, SCREEN_H/2+64, white); + + al_set_target_bitmap(al_get_backbuffer(screen)); + + bmp = replace_bitmap(bmp); + + start_retrace_count(); + + for (i=0; i<=SCREEN_H/16; i++) { + al_clear_to_color(makecol(0, 0, 0)); + + for (j=0; j<=16; j++) { + y = j*(SCREEN_H/16); + al_draw_bitmap_region(bmp, 0, y, SCREEN_W, i, 0, y, 0); + } + + al_flip_display(); + + do { + poll_input_wait(); + } while (retrace_count() < i*1024/SCREEN_W); + } + + stop_retrace_count(); + + while (joy_b1 || key[ALLEGRO_KEY_SPACE] || key[ALLEGRO_KEY_ENTER] || key[ALLEGRO_KEY_ESCAPE]) + poll_input_wait(); + + while (!key[ALLEGRO_KEY_SPACE] && !key[ALLEGRO_KEY_ENTER] && !key[ALLEGRO_KEY_ESCAPE] && !joy_b1) { + poll_input_wait(); + al_draw_bitmap(bmp, 0, 0, 0); + al_flip_display(); + } + + al_destroy_bitmap(bmp); + + if (key[ALLEGRO_KEY_ESCAPE]) + return FALSE; + + sfx_ping(2); + + return TRUE; +} + + + +/* display the results screen */ +void show_results() +{ + int SCREEN_W = al_get_display_width(screen); + int SCREEN_H = al_get_display_height(screen); + ALLEGRO_BITMAP *bmp, *b; + char buf[80]; + int i, j, x; + + bmp = create_memory_bitmap(SCREEN_W, SCREEN_H); + al_set_target_bitmap(bmp); + + for (i=0; i<SCREEN_H/2; i++) { + hline(0, SCREEN_H/2-i-1, SCREEN_W, makecol(i*255/(SCREEN_H/2), 0, 0)); + hline(0, SCREEN_H/2+i, SCREEN_W, makecol(i*255/(SCREEN_H/2), 0, 0)); + } + + b = create_memory_bitmap(72, 8); + al_set_target_bitmap(b); + al_clear_to_color(al_map_rgba(0, 0, 0, 0)); + + textout(font, "GAME OVER", 0, 0, makecol(0, 0, 0)); + stretch_sprite(bmp, b, 4, SCREEN_H/3+4, SCREEN_W, SCREEN_H/3); + + textout(font, "GAME OVER", 0, 0, makecol(64, 0, 0)); + stretch_sprite(bmp, b, 0, SCREEN_H/3, SCREEN_W, SCREEN_H/3); + + al_destroy_bitmap(b); + + al_set_target_bitmap(bmp); + sprintf(buf, "Score: %d", score); + textout_shadow(buf, SCREEN_W/2, SCREEN_H*3/4, makecol(255, 255, 255)); + + al_set_target_bitmap(al_get_backbuffer(screen)); + + bmp = replace_bitmap(bmp); + + start_retrace_count(); + + for (i=0; i<=SCREEN_W/16; i++) { + al_clear_to_color(makecol(0, 0, 0)); + + for (j=0; j<=16; j++) { + x = j*(SCREEN_W/16); + al_draw_bitmap_region(bmp, x, 0, i, SCREEN_H, x, 0, 0); + } + + al_flip_display(); + + do { + poll_input_wait(); + } while (retrace_count() < i*1024/SCREEN_W); + } + + stop_retrace_count(); + + while (joy_b1 || key[ALLEGRO_KEY_SPACE] || key[ALLEGRO_KEY_ENTER] || key[ALLEGRO_KEY_ESCAPE]) + poll_input_wait(); + + while (!key[ALLEGRO_KEY_SPACE] && !key[ALLEGRO_KEY_ENTER] && !key[ALLEGRO_KEY_ESCAPE] && !joy_b1) { + poll_input_wait(); + al_draw_bitmap(bmp, 0, 0, 0); + al_flip_display(); + } + + al_destroy_bitmap(bmp); + + sfx_ping(2); +} + + + +/* print the shutdown message */ +void goodbye() +{ + static int data1[] = + { + 0, 2, 0, 1, 2, 3, 0, 3, 5, 3, 4, 6, 0, 2, 0, 1, 2, + 3, 0, 3, 7, 3, 5, 6, 0, 2, 0, 1, 12, 3, 9, 3, 5, 3, + 4, 3, 2, 3, 10, 2, 10, 1, 9, 3, 5, 3, 7, 3, 5, 9 + + }; + + static int data2[] = + { + 12, 3, 7, 1, 6, 1, 7, 1, 8, 3, 7, 3 + }; + + ALLEGRO_SAMPLE *s1, *s2; + ALLEGRO_SAMPLE_ID id; + ALLEGRO_BITMAP *b; + ALLEGRO_BITMAP *screen_backbuffer; + char *sdata1, *sdata2; + int SCREEN_W, SCREEN_H; + int i; + + if (!al_is_audio_installed()) { + al_destroy_display(screen); + screen = NULL; + printf("Couldn't install a digital sound driver, so no closing tune is available.\n"); + return; + } + + s1 = create_sample_u8(44100, 256); + s2 = create_sample_u8(44100, 256); + + sdata1 = (char *)al_get_sample_data(s1); + sdata2 = (char *)al_get_sample_data(s2); + + for (i=0; i<256; i++) { + sdata1[i] = i; + sdata2[i] = (i < 128) ? 255 : 0; + } + + SCREEN_W = al_get_display_width(screen); + SCREEN_H = al_get_display_height(screen); + + rectfill(0, 0, SCREEN_W/2, SCREEN_H/2, makecol(255, 255, 0)); + rectfill(SCREEN_W/2, 0, SCREEN_W, SCREEN_H/2, makecol(0, 255, 0)); + rectfill(0, SCREEN_H/2, SCREEN_W/2, SCREEN_H, makecol(0, 0, 255)); + rectfill(SCREEN_W/2, SCREEN_H/2, SCREEN_W, SCREEN_H, makecol(255, 0, 0)); + + b = al_create_bitmap(168, 8); + al_set_target_bitmap(b); + al_clear_to_color(al_map_rgba(0, 0, 0, 0)); + + screen_backbuffer = al_get_backbuffer(screen); + + textout(font, "Happy birthday Arron!", 0, 0, makecol(0, 0, 0)); + stretch_sprite(screen_backbuffer, b, SCREEN_W/8+4, SCREEN_H*3/8+4, SCREEN_W*3/4, SCREEN_H/4); + + textout(font, "Happy birthday Arron!", 0, 0, makecol(255, 255, 255)); + stretch_sprite(screen_backbuffer, b, SCREEN_W/8, SCREEN_H*3/8, SCREEN_W*3/4, SCREEN_H/4); + + al_set_target_bitmap(screen_backbuffer); + al_destroy_bitmap(b); + + al_flip_display(); + + while (key[ALLEGRO_KEY_SPACE] || key[ALLEGRO_KEY_ENTER] || key[ALLEGRO_KEY_ESCAPE]) + poll_input_wait(); + + clear_keybuf(); + + for (i=0; i < (int)(sizeof(data1)/sizeof(int)); i += 2) { + al_play_sample(s1, 64/255.0, 0.0, pow(2.0, (float)data1[i]/12.0), + ALLEGRO_PLAYMODE_LOOP, &id); + rest(100*data1[i+1]); + al_stop_sample(&id); + rest(50*data1[i+1]); + + if (keypressed()) + return; + } + + rest(500); + + al_destroy_display(screen); + screen = NULL; + printf("\nAnd thanks for organising this most excellent competition...\n"); + + for (i=0; i < (int)(sizeof(data2)/sizeof(int)); i += 2) { + al_play_sample(s2, 64/255.0, 0.0, pow(2.0, (float)data2[i]/12.0), + ALLEGRO_PLAYMODE_LOOP, &id); + rest(75*data2[i+1]); + al_stop_sample(&id); + rest(25*data2[i+1]); + + if (keypressed()) + return; + } + + rest(300); + putchar('\007'); fflush(stdout); + rest(300); + putchar('\007'); fflush(stdout); + + al_stop_samples(); + + al_destroy_sample(s1); + al_destroy_sample(s2); +} + diff --git a/allegro/demos/speed/update.pl b/allegro/demos/speed/update.pl new file mode 100644 index 00000000..0c20ae56 --- /dev/null +++ b/allegro/demos/speed/update.pl @@ -0,0 +1,81 @@ +#! /usr/bin/perl -w +# +# Perl script for updating my progress info. When passed a block of +# comment text via stdin, it adds this to the end of speed.txt, +# makes a backup of the current code into a subdirectory named after +# the current date/time, and also uploads the progress message to +# http://www.allegro.cc/speedhack/ + + +# read the current time +(undef, $min, $hour, $mday, $mon, $year) = gmtime(time); + +$min = '0' . $min if ($min < 10); +$hour = '0' . $hour if ($hour < 10); + +$year += 1900; + + +# read the message text +$msg = join '', <>; +$msg =~ s/^[\r\n]+//; +$msg =~ s/[\r\n]+$//; + + +# clean the project +system("make clean"); + + +# add message to the readme +open FILE, ">> speed.txt"; + +$date = "$mon-$mday-$year, at $hour:$min"; + +print FILE "\n\n$date\n" . ('-' x length($date)) . "\n\n"; +print FILE $msg; +print FILE "\n\n"; + +close FILE; + + +# make a backup of the code +$dir = "$mon-$mday-$year-at-$hour-$min"; + +mkdir $dir, 0775; + +system("cp -v * $dir"); + + +# upload message to the website +open FILE, "| lwp-request 'http://www.allegro.cc/speedhack/update.taf?_section=update&_UserReference=D50262AC9D32184E383E8C75' -m POST -c application/x-www-form-data -d" or die "Can't open lwp-request\n"; + +print FILE <<EOF; +-----------------------------7cf2b210f30 +Content-Disposition: form-data; name="user_name" + +shawn +-----------------------------7cf2b210f30 +Content-Disposition: form-data; name="password" + +deadbeef +-----------------------------7cf2b210f30 +Content-Disposition: form-data; name="comment" + + +$msg + +-----------------------------7cf2b210f30 +Content-Disposition: form-data; name="image_name" + + +-----------------------------7cf2b210f30 +Content-Disposition: form-data; name="image"; filename="" +Content-Type: application/octet-stream + + +-----------------------------7cf2b210f30-- +EOF + +close FILE; + +print "All done!\n"; diff --git a/allegro/demos/speed/view.c b/allegro/demos/speed/view.c new file mode 100644 index 00000000..fed628f7 --- /dev/null +++ b/allegro/demos/speed/view.c @@ -0,0 +1,416 @@ +/* + * SPEED - by Shawn Hargreaves, 1999 + * + * Viewport functions (3d projection, wireframe guide rendering, etc). + */ + +#include <math.h> +#include <allegro5/allegro.h> +#include <allegro5/allegro_font.h> +#include <allegro5/allegro_primitives.h> + +#include "speed.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + + + +#define NUM_VIEWS 4 + + + +/* desired position of a viewport window */ +typedef struct +{ + float pos[4]; /* left, top, right, bottom */ +} VIEWPOS[NUM_VIEWS]; + + + +/* current status of a viewport window */ +typedef struct +{ + float pos[4]; /* left, top, right, bottom */ + float vel[4]; /* rate of change of the above */ +} VIEWINFO[NUM_VIEWS]; + + + +/* viewport positioning macros */ +#define OFF_TL {{ -0.1, -0.1, -0.1, -0.1 }} +#define OFF_TR {{ 1.1, -0.1, 1.1, -0.1 }} +#define OFF_BL {{ -0.1, 1.1, -0.1, 1.1 }} +#define OFF_BR {{ 1.1, 1.1, 1.1, 1.1 }} + +#define QTR_TL {{ 0, 0, 0.5, 0.5 }} +#define QTR_TR {{ 0.5, 0, 1.0, 0.5 }} +#define QTR_BL {{ 0, 0.5, 0.5, 1.0 }} +#define QTR_BR {{ 0.5, 0.5, 1.0, 1.0 }} + +#define BIG_TL {{ 0, 0, 0.7, 0.7 }} +#define BIG_TR {{ 0.3, 0, 1.0, 0.7 }} +#define BIG_BL {{ 0, 0.3, 0.7, 1.0 }} +#define BIG_BR {{ 0.3, 0.3, 1.0, 1.0 }} + +#define FULL {{ 0, 0, 1.0, 1.0 }} + + + +/* list of viewport window positions */ +static VIEWPOS viewpos[] = +{ + { FULL, OFF_TR, OFF_BL, OFF_BR }, /* 1 single */ + { OFF_TL, FULL, OFF_BL, OFF_BR }, /* 2 single */ + { BIG_TL, BIG_BR, OFF_BL, OFF_BR }, /* 12 multiple */ + { OFF_TL, OFF_TR, FULL, OFF_BR }, /* 3 single */ + { BIG_TL, OFF_TR, BIG_BR, OFF_BR }, /* 13 multiple */ + { OFF_TL, BIG_TR, BIG_BL, OFF_BR }, /* 23 multiple */ + { FULL, FULL, OFF_BL, OFF_BR }, /* 12 superimpose */ + { OFF_TL, OFF_TR, OFF_BL, FULL, }, /* 4 single */ + { BIG_TL, OFF_TR, OFF_BL, BIG_BR }, /* 14 multiple */ + { OFF_TL, FULL, FULL, OFF_BR }, /* 23 superimpose */ + { OFF_TL, BIG_TL, OFF_BL, BIG_BR }, /* 24 multiple */ + { OFF_TL, FULL, OFF_BL, FULL }, /* 24 superimpose */ + { QTR_TL, QTR_TR, QTR_BL, OFF_BR }, /* 123 multiple */ + { BIG_TL, OFF_TR, OFF_BL, BIG_BR }, /* 14 superimpose */ + { QTR_TL, OFF_TR, QTR_BL, QTR_BR }, /* 134 multiple */ + { FULL, OFF_TR, FULL, OFF_BR }, /* 13 superimpose */ + { OFF_TL, OFF_TR, BIG_TL, BIG_BR }, /* 34 multiple */ + { OFF_TL, QTR_TR, BIG_BL, QTR_BR }, /* 234 multiple */ + { OFF_TL, OFF_TR, FULL, FULL }, /* 34 superimpose */ + { FULL, QTR_TR, OFF_BL, QTR_BR }, /* 124 multiple */ + { FULL, FULL, OFF_BL, FULL }, /* 124 superimpose */ + { QTR_TL, QTR_TR, QTR_BL, QTR_BR }, /* 1234 multiple */ + { FULL, FULL, FULL, OFF_BR }, /* 123 superimpose */ + { FULL, OFF_TR, FULL, FULL }, /* 134 superimpose */ + { OFF_TL, FULL, FULL, FULL }, /* 234 superimpose */ + { FULL, FULL, FULL, FULL }, /* 1234 superimpose */ +}; + + + +/* current viewport state */ +static VIEWINFO viewinfo; + +static int viewnum; + +static float view_left, view_top, view_right, view_bottom; + + + +/* returns a scaling factor for 2d graphics effects */ +float view_size() +{ + return ((view_right - view_left) + (view_bottom - view_top)) / 2; +} + + + +/* initialises the view functions */ +void init_view() +{ + int i, j; + + viewnum = 0; + + for (i=0; i<4; i++) { + for (j=0; j<4; j++) { + viewinfo[i].pos[j] = 0; + viewinfo[i].vel[j] = 0; + } + } +} + + + +/* closes down the view module */ +void shutdown_view() +{ +} + + + +/* advances to the next view position */ +int advance_view() +{ + int cycled = FALSE; + + viewnum++; + + if (viewnum >= (int)(sizeof(viewpos)/sizeof(VIEWPOS))) { + viewnum = 0; + cycled = TRUE; + } + + return cycled; +} + + + +/* updates the view position */ +void update_view() +{ + float delta, vel; + int i, j; + + for (i=0; i<4; i++) { + for (j=0; j<4; j++) { + delta = viewpos[viewnum][i].pos[j] - viewinfo[i].pos[j]; + vel = viewinfo[i].vel[j]; + + vel *= 0.9; + delta = log(ABS(delta)+1.0) * SGN(delta) / 64.0; + vel += delta; + + if ((ABS(delta) < 0.00001) && (ABS(vel) < 0.00001)) { + viewinfo[i].pos[j] = viewpos[viewnum][i].pos[j]; + viewinfo[i].vel[j] = 0; + } + else { + viewinfo[i].pos[j] += vel; + viewinfo[i].vel[j] = vel; + } + } + } +} + + + +/* flat projection function */ +static int project_flat(float *f, int *i, int c) +{ + while (c > 0) { + i[0] = view_left + f[0] * (view_right - view_left); + i[1] = view_top + f[1] * (view_bottom - view_top); + + f += 2; + i += 2; + c -= 2; + } + + return TRUE; +} + + + +/* spherical coordinate projection function */ +static int project_spherical(float *f, int *i, int c) +{ + while (c > 0) { + float ang = f[0] * M_PI * 2.0; + + float xsize = view_right - view_left; + float ysize = view_bottom - view_top; + float size = MIN(xsize, ysize) / 2.0; + + float ff = (f[1] > 0.99) ? 0 : (1.0 - f[1] * 0.9); + + float dx = cos(ang) * ff * size; + float dy = sin(ang) * ff * size; + + i[0] = dx + (view_left + view_right) / 2.0; + i[1] = dy + (view_top + view_bottom) / 2.0; + + f += 2; + i += 2; + c -= 2; + } + + return TRUE; +} + + + +/* inside of tube projection function */ +static int project_tube(float *f, int *i, int c) +{ + while (c > 0) { + float ang = f[0] * M_PI * 2.0 + M_PI / 2.0; + + float xsize = view_right - view_left; + float ysize = view_bottom - view_top; + float size = MIN(xsize, ysize) / 2.0; + + float x = cos(ang); + float y = sin(ang); + + float z = 1.0 + (1.0 - f[1]) * 8.0; + + i[0] = x/z * size + (view_left + view_right) / 2.0; + i[1] = y/z * size + (view_top + view_bottom) / 2.0; + + f += 2; + i += 2; + c -= 2; + } + + return TRUE; +} + + + +/* outside of cylinder projection function */ +static int project_cylinder(float *f, int *i, int c) +{ + static MATRIX_f mtx; + static int virgin = TRUE; + + if (virgin) { + MATRIX_f m1, m2; + + get_z_rotate_matrix_f(&m1, -64); + qtranslate_matrix_f(&m1, 0, 1.75, 0); + get_scaling_matrix_f(&m2, 2.0, 1.0, 1.0); + matrix_mul_f(&m1, &m2, &mtx); + + virgin = FALSE; + } + + while (c > 0) { + float ang = (f[0] - player_pos()) * M_PI * 2.0; + + float xsize = view_right - view_left; + float ysize = view_bottom - view_top; + float size = MIN(xsize, ysize) / 2.0; + + float x = cos(ang); + float y = sin(ang); + float z = 1.0 + (1.0 - f[1]) * 4.0; + + float xout, yout, zout; + + apply_matrix_f(&mtx, x, y, z, &xout, &yout, &zout); + + if (yout > 1.5) + return FALSE; + + i[0] = xout/zout * size + (view_left + view_right) / 2.0; + i[1] = (yout/zout * 2 - 1) * size + (view_top + view_bottom) / 2.0; + + f += 2; + i += 2; + c -= 2; + } + + return TRUE; +} + + + +/* draws the entire view */ +void draw_view() +{ + int SCREEN_W = al_get_display_width(screen); + int SCREEN_H = al_get_display_height(screen); + int (*project)(float *f, int *i, int c); + int r, g, b; + ALLEGRO_COLOR c; + int i, n, x, y; + float point[6]; + int ipoint[6]; + + al_clear_to_color(makecol(0, 0, 0)); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + + for (i=0; i<4; i++) { + + view_left = viewinfo[i].pos[0] * SCREEN_W; + view_top = viewinfo[i].pos[1] * SCREEN_H; + view_right = viewinfo[i].pos[2] * SCREEN_W; + view_bottom = viewinfo[i].pos[3] * SCREEN_H; + + if ((view_right > view_left) && (view_bottom > view_top) && + (view_right > 0) && (view_bottom > 0) && + (view_left < SCREEN_W) && (view_top < SCREEN_H)) { + + switch (i) { + + case 0: + /* flat projection, green */ + project = project_flat; + + r = 0; + g = 255; + b = 0; + break; + + case 1: + /* spherical coordinates, yellow */ + project = project_spherical; + + r = 255; + g = 255; + b = 0; + break; + + case 2: + /* inside a tube, blue */ + project = project_tube; + + r = 0; + g = 0; + b = 255; + break; + + case 3: + /* surface of cylinder, red */ + project = project_cylinder; + + r = 255; + g = 0; + b = 0; + break; + + default: + /* oops! */ + assert(FALSE); + return; + } + + if (!no_grid) { + c = makecol(r/5, g/5, b/5); + + n = (low_detail) ? 8 : 16; + + for (x=0; x<=n; x++) { + for (y=0; y<=n; y++) { + point[0] = (float)x / n; + point[1] = (float)y / n; + point[2] = (float)(x+1) / n; + point[3] = (float)y / n; + point[4] = (float)x / n; + point[5] = (float)(y+1) / n; + + if (project(point, ipoint, 6)) { + if (x < n) + line(ipoint[0], ipoint[1], ipoint[2], ipoint[3], c); + + if ((y < n) && ((x < n) || (i == 0))) + line(ipoint[0], ipoint[1], ipoint[4], ipoint[5], c); + } + } + } + } + + draw_player(r, g, b, project); + draw_badguys(r, g, b, project); + draw_bullets(r, g, b, project); + draw_explode(r, g, b, project); + } + } + + solid_mode(); + + draw_message(); + + textprintf(font_video, 4, 4, makecol(128, 128, 128), "Lives: %d", lives); + textprintf(font_video, 4, 16, makecol(128, 128, 128), "Score: %d", score); + textprintf(font_video, 4, 28, makecol(128, 128, 128), "Hiscore: %d", get_hiscore()); + + al_flip_display(); +} + + diff --git a/allegro/docs/CMakeLists.txt b/allegro/docs/CMakeLists.txt new file mode 100644 index 00000000..a8a5d25f --- /dev/null +++ b/allegro/docs/CMakeLists.txt @@ -0,0 +1,177 @@ +find_program(MAKEINFO NAMES makeinfo) +mark_as_advanced(MAKEINFO) + +find_program(PANDOC NAMES pandoc) +mark_as_advanced(PANDOC) + +# sh is only used for a developer-only target. +find_program(SH NAMES ash dash sh) +mark_as_advanced(SH) + +find_package(LATEX) + +find_program(CTAGS NAMES ctags) +mark_as_advanced(CTAGS) + +#-----------------------------------------------------------------------------# + +set(DOC_GIT_REF "" CACHE STRING "Git ref to use for source links in the documentation. If empty, will query git for this.") + +set(REAL_DOC_GIT_REF "") +if(DOC_GIT_REF) + set(REAL_DOC_GIT_REF ${DOC_GIT_REF}) +else() + find_package(Git) + if(GIT_FOUND) + message(STATUS "Using git to determine git ref for documentation.") + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE GIT_RESULT + OUTPUT_VARIABLE GIT_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(GIT_RESULT EQUAL 0) + set(REAL_DOC_GIT_REF ${GIT_OUTPUT}) + endif() + endif() +endif() + +if(NOT REAL_DOC_GIT_REF) + set(REAL_DOC_GIT_REF master) +endif() + +message(STATUS "Using ${REAL_DOC_GIT_REF} as the git ref for source links in the documentation.") + +#-----------------------------------------------------------------------------# + +# Pandoc 1.10 changed handling of internal cross-references in Texinfo writer, +# and LaTeX writer thereabouts. +if(PANDOC) + message(STATUS "Checking Pandoc version") + execute_process( + COMMAND ${PANDOC} --version + OUTPUT_VARIABLE PANDOC_VERSION_TEXT + ERROR_VARIABLE PANDOC_VERSION_TEXT + ) + if(PANDOC_VERSION_TEXT MATCHES "pandoc(.exe)? (1[.]1[0-9]|1[.][2-9][0-9]|[2-9])") + # message(STATUS "Pandoc version is compatible") + else() + message(STATUS "Pandoc version is incompatible") + set(PANDOC 0) + endif() +endif() + +#-----------------------------------------------------------------------------# + +set(all_docs) + +macro(add_info n) + if(MAKEINFO) + makedoc(src/${n}._tx -texi texi/${n}.texi) + + set(abs_info ${CMAKE_CURRENT_BINARY_DIR}/info/${n}.info) + set(abs_texi ${CMAKE_CURRENT_BINARY_DIR}/texi/${n}.texi) + + list(APPEND all_docs ${abs_info}) + add_custom_command( + OUTPUT ${abs_info} + DEPENDS ${abs_texi} + COMMAND ${MAKEINFO} --no-split -o ${abs_info} ${abs_texi} + ) + endif(MAKEINFO) +endmacro(add_info) + +#-----------------------------------------------------------------------------# + +function(pandoc source output) # extraargs... + set(abs_source ${CMAKE_CURRENT_SOURCE_DIR}/${source}) + set(abs_output ${CMAKE_CURRENT_BINARY_DIR}/${output}) + + # Use native Windows syntax to avoid "c:/foo.txt" being treated as a + # remote URI by Pandoc 1.5 and 1.6. + file(TO_NATIVE_PATH ${abs_source} abs_source_native) + + list(APPEND all_docs ${abs_output}) + set(all_docs ${all_docs} PARENT_SCOPE) + + add_custom_command( + OUTPUT ${abs_output} + DEPENDS ${abs_source} + COMMAND ${PANDOC} ${abs_source_native} --from markdown --toc --standalone ${ARGN} + -o ${abs_output} + ) +endfunction(pandoc source output) + +function(texi2text source output) + # The source file is a generated Texinfo file. + set(abs_source ${CMAKE_CURRENT_BINARY_DIR}/${source}) + set(abs_output ${CMAKE_CURRENT_BINARY_DIR}/${output}) + + list(APPEND all_docs ${abs_output}) + set(all_docs ${all_docs} PARENT_SCOPE) + + # Writing to stdout suppresses the table of contents. + # To get the table of contents, use `makeinfo -o ${output}`. + add_custom_command( + OUTPUT ${abs_output} + DEPENDS ${abs_source} + COMMAND ${MAKEINFO} + --plaintext + --paragraph-indent 0 + --no-number-sections + ${abs_source} > ${abs_output} + ) +endfunction(texi2text) + +if(PANDOC) + pandoc(src/changes-5.0.txt html/changes-5.0.html -c pandoc.css) + pandoc(src/changes-5.1.txt html/changes-5.1.html -c pandoc.css) + pandoc(src/changes-5.2.txt html/changes-5.2.html -c pandoc.css) + + pandoc(src/changes-5.0.txt texi/changes-5.0.texi) + pandoc(src/changes-5.1.txt texi/changes-5.1.texi) + pandoc(src/changes-5.2.txt texi/changes-5.2.texi) + if(MAKEINFO) + texi2text(texi/changes-5.0.texi txt/changes-5.0.txt) + texi2text(texi/changes-5.1.texi txt/changes-5.1.txt) + texi2text(texi/changes-5.2.texi txt/changes-5.2.txt) + endif(MAKEINFO) +endif(PANDOC) + +add_custom_target(docs + ALL + DEPENDS ${all_docs} + ) + +#-----------------------------------------------------------------------------# + +make_directory(${CMAKE_CURRENT_BINARY_DIR}/html/refman) +make_directory(${CMAKE_CURRENT_BINARY_DIR}/txt) +make_directory(${CMAKE_CURRENT_BINARY_DIR}/texi) +make_directory(${CMAKE_CURRENT_BINARY_DIR}/latex) + +# Stick the ALLEGRO_VERSION into a file included by the latex template +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/refman/allegro_version.tex.cmake + ${CMAKE_CURRENT_BINARY_DIR}/latex/allegro_version.tex + @ONLY + ) + +# Copy CSS files. +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/pandoc.css + ${CMAKE_CURRENT_BINARY_DIR}/html/pandoc.css + COPYONLY + ) +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/pandoc.css + ${CMAKE_CURRENT_BINARY_DIR}/html/refman/pandoc.css + COPYONLY + ) + +if(PANDOC AND NOT CMAKE_CROSSCOMPILING) + include(Refman.cmake) +endif() + +#-----------------------------------------------------------------------------# +# vim: set sts=4 sw=4 et: diff --git a/allegro/docs/Refman.cmake b/allegro/docs/Refman.cmake new file mode 100644 index 00000000..f5fd01de --- /dev/null +++ b/allegro/docs/Refman.cmake @@ -0,0 +1,495 @@ +set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) +set(SRC_REFMAN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/refman) + +# Put these in the order that they should appear in the Info or PDF manual. +set(PAGES + getting_started + + config + display + events + file + fixed + fshook + fullscreen_mode + graphics + haptic + joystick + keyboard + memory + misc + monitor + mouse + path + state + system + threads + time + timer + touch + transformations + utf8 + + platform + direct3d + opengl + + audio + acodec + color + font + image + main + memfile + native_dialog + physfs + primitives + shader + video + ) + +set(PAGES_TXT) +foreach(page ${PAGES}) + list(APPEND PAGES_TXT ${SRC_REFMAN_DIR}/${page}.txt) +endforeach(page) + +set(TITLE_TXT ${SRC_REFMAN_DIR}/title.txt) + +set(IMAGES + primitives1 + primitives2 + LINE_CAP + LINE_JOIN + audio + ) + + +#-----------------------------------------------------------------------------# +# +# Paths +# +#-----------------------------------------------------------------------------# + +set(HTML_DIR ${CMAKE_CURRENT_BINARY_DIR}/html/refman) +set(MAN_DIR ${CMAKE_CURRENT_BINARY_DIR}/man) +set(INFO_DIR ${CMAKE_CURRENT_BINARY_DIR}/info) +set(TEXI_DIR ${CMAKE_CURRENT_BINARY_DIR}/texi) +set(LATEX_DIR ${CMAKE_CURRENT_BINARY_DIR}/latex) +set(PDF_DIR ${CMAKE_CURRENT_BINARY_DIR}/pdf) + +set(PROTOS ${CMAKE_CURRENT_BINARY_DIR}/protos) +set(API_EXAMPLES ${CMAKE_CURRENT_BINARY_DIR}/examples) +set(PROTOS_TIMESTAMP ${PROTOS}.timestamp) +set(EXAMPLES_DIR ${CMAKE_SOURCE_DIR}/examples) +set(HTML_REFS ${CMAKE_CURRENT_BINARY_DIR}/html_refs) +set(HTML_REFS_TIMESTAMP ${HTML_REFS}.timestamp) +set(INDEX_ALL ${CMAKE_CURRENT_BINARY_DIR}/index_all.txt) +set(SEARCH_INDEX_JS ${HTML_DIR}/search_index.js) + +set(SCRIPT_DIR ${CMAKE_SOURCE_DIR}/docs/scripts) +set(MAKE_PROTOS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_protos) +set(MAKE_HTML_REFS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_html_refs) +set(MAKE_INDEX ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_index) +set(SCAN_EXAMPLES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/scan_examples) +set(MAKE_DOC ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_doc + --pandoc "${PANDOC}" + --protos ${PROTOS} + --allegro5_cfg ${CMAKE_SOURCE_DIR}/allegro5.cfg + --git_ref ${REAL_DOC_GIT_REF}) +set(INSERT_TIMESTAMP ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/insert_timestamp) +set(MAKE_SEARCH_INDEX ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/make_search_index) + +set(DAWK_SOURCES scripts/aatree.c scripts/dawk.c scripts/trex.c) + +add_executable(make_protos scripts/make_protos.c ${DAWK_SOURCES}) +add_executable(make_html_refs scripts/make_html_refs.c ${DAWK_SOURCES}) +add_executable(make_index scripts/make_index.c ${DAWK_SOURCES}) +add_executable(make_doc + scripts/make_doc.c + scripts/make_man.c + scripts/make_single.c + ${DAWK_SOURCES}) +add_executable(insert_timestamp + scripts/insert_timestamp.c + ${DAWK_SOURCES}) +add_executable(make_search_index scripts/make_search_index.c ${DAWK_SOURCES}) +add_executable(scan_examples scripts/scan_examples.c ${DAWK_SOURCES}) + +#-----------------------------------------------------------------------------# +# +# Protos +# +#-----------------------------------------------------------------------------# + +# The protos file is a list of function prototypes and type declarations +# which can then be embedded into the documentation. + +# Rebuilding the documentation whenever a source file changes is irritating, +# especially as public prototypes rarely change. Thus we keep a second file +# called protos.timestamp which reflects the last time that the protos file +# changed. We declare _that_ file as the dependency of other targets. + +# We can get into a situation where the protos file is newer than the source +# files (up-to-date) but the protos.timestamp is older than the source files. +# If the protos and protos.timestamp files are identical then each time +# you run make, it will compare them and find them equal, so protos.timestamp +# won't be updated. However that check is instantaneous. + +# ALL_SRCS is split into multiple lists, otherwise the make_protos command +# line is too long for Windows >:-( We use relative paths for the same reason. +file(GLOB_RECURSE ALL_SRCS1 + ${CMAKE_SOURCE_DIR}/src/*.[chm] + ${CMAKE_SOURCE_DIR}/src/*.[ch]pp + ) +file(GLOB_RECURSE ALL_SRCS2 + ${CMAKE_SOURCE_DIR}/include/*.h + ${CMAKE_SOURCE_DIR}/include/*.inl + ) +file(GLOB_RECURSE ALL_SRCS3 + ${CMAKE_SOURCE_DIR}/addons/*.[chm] + ${CMAKE_SOURCE_DIR}/addons/*.[ch]pp + ) + +foreach(x ${ALL_SRCS1}) + file(RELATIVE_PATH xrel ${CMAKE_SOURCE_DIR} ${x}) + list(APPEND ALL_SRCS1_REL ${xrel}) +endforeach() +foreach(x ${ALL_SRCS2}) + file(RELATIVE_PATH xrel ${CMAKE_SOURCE_DIR} ${x}) + list(APPEND ALL_SRCS2_REL ${xrel}) +endforeach() +foreach(x ${ALL_SRCS3}) + file(RELATIVE_PATH xrel ${CMAKE_SOURCE_DIR} ${x}) + list(APPEND ALL_SRCS3_REL ${xrel}) +endforeach() + +add_custom_command( + OUTPUT ${PROTOS} + DEPENDS ${ALL_SRCS1} ${ALL_SRCS2} ${ALL_SRCS3} make_protos + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND ${MAKE_PROTOS} ${ALL_SRCS1_REL} > ${PROTOS} + COMMAND ${MAKE_PROTOS} ${ALL_SRCS2_REL} >> ${PROTOS} + COMMAND ${MAKE_PROTOS} ${ALL_SRCS3_REL} >> ${PROTOS} + ) + +add_custom_command( + OUTPUT ${PROTOS_TIMESTAMP} + DEPENDS ${PROTOS} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROTOS} ${PROTOS_TIMESTAMP} + ) + +# For testing (command line too long for Windows) +if(NOT WIN32) + add_custom_target(gen_protos DEPENDS ${PROTOS}) +endif() + +#-----------------------------------------------------------------------------# +# +# API Examples +# +#-----------------------------------------------------------------------------# + +# Build a list of all the API entries. Then cross-reference these against +# which of the example files make use of them. + +set(RESP ${CMAKE_CURRENT_BINARY_DIR}/ex_files) + +file(GLOB EXAMPLE_FILES + ${EXAMPLES_DIR}/*.c + ${EXAMPLES_DIR}/*.cpp) + +file(GLOB EXAMPLE_FILES_REL + RELATIVE ${CMAKE_SOURCE_DIR} + ${EXAMPLES_DIR}/*.c + ${EXAMPLES_DIR}/*.cpp) + +foreach(f IN LISTS EXAMPLE_FILES_REL) + string(APPEND multiline "${f}\n") +endforeach() + +file(WRITE ${RESP} "${multiline}") + +add_custom_command( + OUTPUT ${API_EXAMPLES} + DEPENDS ${PROTOS} + ${EXAMPLE_FILES} + ${SCAN_EXAMPLES} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND ${SCAN_EXAMPLES} --protos ${PROTOS} "@${RESP}" > ${API_EXAMPLES}.t + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${API_EXAMPLES}.t ${API_EXAMPLES}) + +#-----------------------------------------------------------------------------# +# +# HTML +# +#-----------------------------------------------------------------------------# + +# The html_refs file contains link definitions for each API entry. +# It's used to resolve references across HTML pages. +# The search_index.js file contains definitions for the autosuggest widget. + +add_custom_command( + OUTPUT ${HTML_REFS} + DEPENDS ${PAGES_TXT} make_html_refs + COMMAND ${MAKE_HTML_REFS} ${PAGES_TXT} > ${HTML_REFS} + ) + +add_custom_command( + OUTPUT ${HTML_REFS_TIMESTAMP} + DEPENDS ${HTML_REFS} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${HTML_REFS} ${HTML_REFS_TIMESTAMP} + ) + +add_custom_command( + OUTPUT ${INDEX_ALL} + DEPENDS ${HTML_REFS_TIMESTAMP} make_index + COMMAND ${MAKE_INDEX} ${HTML_REFS} > ${INDEX_ALL} + ) + +add_custom_command( + OUTPUT ${SEARCH_INDEX_JS} + DEPENDS ${HTML_REFS_TIMESTAMP} make_search_index + COMMAND ${MAKE_SEARCH_INDEX} ${HTML_REFS} > ${SEARCH_INDEX_JS} + ) + +if(WANT_DOCS_HTML) + foreach(inc inc.a inc.z) + add_custom_command( + OUTPUT ${inc}.html + DEPENDS ${SRC_REFMAN_DIR}/${inc}.txt + COMMAND ${PANDOC} ${SRC_REFMAN_DIR}/${inc}.txt --from markdown -o ${inc}.html + ) + endforeach(inc) + + set(HTML_PAGES) + foreach(page ${PAGES} index index_all) + if(page STREQUAL "index_all") + set(page_src ${INDEX_ALL}) + else() + set(page_src ${SRC_REFMAN_DIR}/${page}.txt) + endif() + add_custom_command( + OUTPUT ${HTML_DIR}/${page}.html + DEPENDS + ${PROTOS_TIMESTAMP} + ${HTML_REFS_TIMESTAMP} + ${page_src} + ${CMAKE_CURRENT_BINARY_DIR}/inc.a.html + ${CMAKE_CURRENT_BINARY_DIR}/inc.z.html + ${SEARCH_INDEX_JS} + ${API_EXAMPLES} + make_doc + insert_timestamp + COMMAND + ${INSERT_TIMESTAMP} ${CMAKE_SOURCE_DIR}/include/allegro5/base.h > inc.timestamp.html + COMMAND + ${MAKE_DOC} + --examples ${API_EXAMPLES} + --to html + --raise-sections + --include-before-body inc.a.html + --include-after-body inc.timestamp.html + --include-after-body inc.z.html + --css pandoc.css + --include-in-header ${SRC_DIR}/custom_header.html + --standalone + --toc + -- ${page_src} ${HTML_REFS} + > ${HTML_DIR}/${page}.html + ) + list(APPEND HTML_PAGES ${HTML_DIR}/${page}.html) + endforeach(page) + + set(HTML_IMAGES) + foreach(image ${IMAGES}) + add_custom_command( + OUTPUT ${HTML_DIR}/images/${image}.png + DEPENDS + ${SRC_REFMAN_DIR}/images/${image}.png + COMMAND + "${CMAKE_COMMAND}" -E copy + "${SRC_REFMAN_DIR}/images/${image}.png" "${HTML_DIR}/images/${image}.png" + ) + list(APPEND HTML_IMAGES ${HTML_DIR}/images/${image}.png) + endforeach(image) + + add_custom_target(html ALL DEPENDS ${HTML_PAGES} ${HTML_IMAGES}) + + foreach(file pandoc.css autosuggest.js) + configure_file( + ${SRC_DIR}/${file} + ${HTML_DIR}/${file} + COPYONLY) + endforeach(file) +endif(WANT_DOCS_HTML) + +#-----------------------------------------------------------------------------# +# +# Man pages +# +#-----------------------------------------------------------------------------# + +set(MANDIR "man" CACHE STRING "Install man pages into this directory") + +if(WANT_DOCS_MAN) + make_directory(${MAN_DIR}) + + set(MAN_PAGES) + foreach(page ${PAGES_TXT}) + # Figure out the man pages that would be generated from this file. + file(STRINGS ${page} lines REGEX "# API: ") + if(lines) + string(REGEX REPLACE "[#]* API: " ";" entries ${lines}) + + set(outputs) + foreach(entry ${entries}) + list(APPEND outputs ${MAN_DIR}/${entry}.3) + endforeach(entry) + + add_custom_command( + OUTPUT ${outputs} + DEPENDS ${PROTOS_TIMESTAMP} ${page} make_doc + COMMAND ${MAKE_DOC} --to man -- ${page} + WORKING_DIRECTORY ${MAN_DIR} + ) + + list(APPEND MAN_PAGES ${outputs}) + endif(lines) + endforeach(page) + + add_custom_target(man ALL DEPENDS ${MAN_PAGES}) + + install(FILES ${MAN_PAGES} + DESTINATION ${MANDIR}/man3 + ) +endif(WANT_DOCS_MAN) + +#-----------------------------------------------------------------------------# +# +# Info +# +#-----------------------------------------------------------------------------# + +if(WANT_DOCS_INFO AND MAKEINFO) + make_directory(${INFO_DIR}) + make_directory(${TEXI_DIR}) + + add_custom_target(info ALL DEPENDS ${INFO_DIR}/refman.info) + add_custom_command( + OUTPUT ${INFO_DIR}/refman.info + DEPENDS ${TEXI_DIR}/refman.texi + COMMAND ${MAKEINFO} + --paragraph-indent 0 + --no-split + ${TEXI_DIR}/refman.texi + -o ${INFO_DIR}/refman.info + ) + add_custom_command( + OUTPUT ${TEXI_DIR}/refman.texi + DEPENDS ${PROTOS_TIMESTAMP} ${TITLE_TXT} ${PAGES_TXT} + make_doc + COMMAND ${MAKE_DOC} + --to texinfo + --standalone + -- + ${TITLE_TXT} ${PAGES_TXT} + > ${TEXI_DIR}/refman.texi + ) +else() + if(WANT_DOCS_INFO) + message("Info documentation requires makeinfo") + endif(WANT_DOCS_INFO) +endif(WANT_DOCS_INFO AND MAKEINFO) + +#-----------------------------------------------------------------------------# +# +# LaTeX (PDF) +# +#-----------------------------------------------------------------------------# + +set(MAKE_PDF ${WANT_DOCS_PDF}) + +if(WANT_DOCS_PDF AND NOT PDFLATEX_COMPILER) + set(MAKE_PDF 0) + message("PDF generation requires pdflatex") +endif() + +if(MAKE_PDF) + add_custom_target(latex ALL DEPENDS ${LATEX_DIR}/refman.tex) + add_custom_command( + OUTPUT ${LATEX_DIR}/refman.tex + DEPENDS ${PROTOS_TIMESTAMP} + ${TITLE_TXT} + ${PAGES_TXT} + ${LATEX_DIR}/allegro_version.tex + ${SRC_REFMAN_DIR}/latex.template + make_doc + COMMAND ${MAKE_DOC} + --to latex + --chapters + --template ${SRC_REFMAN_DIR}/latex.template + --standalone + --toc + --number-sections + -- ${TITLE_TXT} ${PAGES_TXT} + > ${LATEX_DIR}/refman.tex + ) + set(PDF_IMAGES) + foreach(image ${IMAGES}) + add_custom_command( + OUTPUT ${LATEX_DIR}/images/${image}.png + DEPENDS ${SRC_REFMAN_DIR}/images/${image}.png + COMMAND "${CMAKE_COMMAND}" -E copy + "${SRC_REFMAN_DIR}/images/${image}.png" "${LATEX_DIR}/images/${image}.png" + ) + list(APPEND PDF_IMAGES ${LATEX_DIR}/images/${image}.png) + endforeach(image) + + make_directory(${PDF_DIR}) + add_custom_target(pdf ALL DEPENDS ${PDF_DIR}/refman.pdf) + add_custom_command( + OUTPUT ${PDF_DIR}/refman.pdf + DEPENDS ${LATEX_DIR}/refman.tex + DEPENDS ${PDF_IMAGES} + # Repeat three times to get cross references correct. + COMMAND "${CMAKE_COMMAND}" -E chdir ${LATEX_DIR} ${PDFLATEX_COMPILER} -interaction nonstopmode -output-directory ${PDF_DIR} ${LATEX_DIR}/refman.tex + COMMAND "${CMAKE_COMMAND}" -E chdir ${LATEX_DIR} ${PDFLATEX_COMPILER} -interaction nonstopmode -output-directory ${PDF_DIR} ${LATEX_DIR}/refman.tex + COMMAND "${CMAKE_COMMAND}" -E chdir ${LATEX_DIR} ${PDFLATEX_COMPILER} -interaction nonstopmode -output-directory ${PDF_DIR} ${LATEX_DIR}/refman.tex + ) +endif(MAKE_PDF) + +#-----------------------------------------------------------------------------# +# +# Tags file +# +#-----------------------------------------------------------------------------# + +if(CTAGS) + add_custom_target(gen_tags DEPENDS tags) + add_custom_command( + OUTPUT tags + DEPENDS ${PAGES_TXT} + COMMAND ${CTAGS} + --langdef=allegrodoc + --langmap=allegrodoc:.txt + "--regex-allegrodoc=/^#+ API: (.+)/\\1/" + ${PAGES_TXT} + VERBATIM + ) +endif(CTAGS) + +#-----------------------------------------------------------------------------# +# +# Consistency check +# +#-----------------------------------------------------------------------------# + +add_custom_target(check_consistency + DEPENDS ${PROTOS} + COMMAND ${SH} ${SCRIPT_DIR}/check_consistency --protos ${PROTOS} + ${PAGES_TXT} + ) + +#-----------------------------------------------------------------------------# +# vim: set sts=4 sw=4 et: diff --git a/allegro/docs/html/refman/acodec.html b/allegro/docs/html/refman/acodec.html new file mode 100644 index 00000000..c1b5ae76 --- /dev/null +++ b/allegro/docs/html/refman/acodec.html @@ -0,0 +1,212 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> +<head> + <meta charset="utf-8" /> + <meta name="generator" content="pandoc" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> + <title>Audio codecs addon + + + + + + + + +
+ + +
+

Audio codecs addon

+
+ +

These functions are declared in the following header file. Link with allegro_acodec.

+
 #include <allegro5/allegro_acodec.h>
+

al_init_acodec_addon

+
bool al_init_acodec_addon(void)
+

Source Code

+

This function registers all the known audio file type handlers for al_load_sample, al_save_sample, al_load_audio_stream, etc.

+

Depending on what libraries are available, the full set of recognised extensions is: .wav, .flac, .ogg, .opus, .it, .mod, .s3m, .xm, .voc.

+

Limitations:

+
    +
  • Saving is only supported for wav files.

  • +
  • The wav file loader currently only supports 8/16 bit little endian PCM files. 16 bits are used when saving wav files. Use flac files if more precision is required.

  • +
  • Module files (.it, .mod, .s3m, .xm) are often composed with streaming in mind, and sometimes cannot be easily rendered into a finite length sample. Therefore they cannot be loaded with al_load_sample/al_load_sample_f and must be streamed with al_load_audio_stream or al_load_audio_stream_f.

  • +
  • .voc file streaming is unimplemented.

  • +
+

Return true on success.

+

Examples:

+ +

al_is_acodec_addon_initialized

+
bool al_is_acodec_addon_initialized(void)
+

Source Code

+

Returns true if the acodec addon is initialized, otherwise returns false.

+

Since: 5.2.6

+

al_get_allegro_acodec_version

+
uint32_t al_get_allegro_acodec_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/audio.html b/allegro/docs/html/refman/audio.html new file mode 100644 index 00000000..31c511d0 --- /dev/null +++ b/allegro/docs/html/refman/audio.html @@ -0,0 +1,1942 @@ + + + + + + + Audio addon + + + + + + + + +
+ + +
+

Audio addon

+
+ +

These functions are declared in the following header file. Link with allegro_audio.

+
 #include <allegro5/allegro_audio.h>
+

In order to just play some samples, here’s how to quick start with Allegro’s audio addon: Call al_reserve_samples with the number of samples you’d like to be able to play simultaneously (don’t forget to call al_install_audio beforehand). If these succeed, you can now call al_play_sample, with data obtained by al_load_sample, for example (don’t forget to initialize the acodec addon). You don’t need to worry about voices, mixers or sample instances when using this approach. In order to stop samples, you can use the ALLEGRO_SAMPLE_ID that al_play_sample returns.

+

If you want to play large audio files (e.g. background music) without loading the whole file at once or if you want to output audio generated in real-time, you can use Allegro’s audio streams. The easiest way to setup an audio stream is to attach it to the default mixer (created for you by al_reserve_samples) using al_attach_audio_stream_to_mixer on the return value of al_get_default_mixer. Allegro will feed streams created from files using al_load_audio_stream automatically. However, you can also stream audio data you generate on the fly. In this case, audio streams will emit an event when it’s time to provide the next fragment (chunk) of audio data. You can control several playback parameters of audio streams (speed, gain, pan, playmode, played/paused; additionally position and loop points when streaming a file).

+

For more fine-grained control over audio output, here’s a short description of the basic concepts:

+

Voices represent audio devices on the system. Basically, every audio output chain that you want to be heard needs to end up in a voice. As voices are on the hardware/driver side of things, there is only limited control over their parameters (frequency, sample format, channel configuration). The number of available voices is limited as well. Typically, you will only use one voice and attach a mixer to it. Calling al_reserve_samples will do this for you by setting up a default voice and mixer; it can also be achieved by calling al_restore_default_mixer. Although you can attach sample instances and audio streams directly to a voice without using a mixer, it is, as of now, not recommended. In contrast to mixers, you can only attach a single object to a voice anyway.

+

Mixers mix several sample instances and/or audio streams into a single output buffer, converting sample data with differing formats according to their output parameters (frequency, depth, channels) in the process. In order to play several samples/streams at once reliably, you will need at least one mixer. A mixer that is not (indirectly) attached to a voice will remain silent. For most use cases, one (default) mixer attached to a single voice will be sufficient. You may attach mixers to other mixers in order to create complex audio chains.

+

Samples (ALLEGRO_SAMPLE) just represent “passive” buffers for sample data in memory. In order to play a sample, a sample instance (ALLEGRO_SAMPLE_INSTANCE) needs to be created and attached to a mixer (or voice). Sample instances control how the underlying samples are played. Several playback parameters (position, speed, gain, pan, playmode, playing/paused) can be adjusted. Particularly, multiple instances may be created from the same sample, e.g. with different parameters.

+

Audio streams (see above) are similar to sample instances insofar as they respond to the same playback parameters and have to be attached to mixers or voices. A single audio stream can only be played once simultaneously.

+

For example, consider the following configuration of the audio system.

+
ALLEGRO_VOICE* voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16,
+    ALLEGRO_CHANNEL_CONF_2);
+
+ALLEGRO_MIXER* mixer_1 = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32,
+    ALLEGRO_CHANNEL_CONF_2);
+ALLEGRO_MIXER* mixer_2 = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32,
+    ALLEGRO_CHANNEL_CONF_2);
+
+/* Load a stream, the stream starts in a playing state and just needs
+ * to be attached to actually output sound. */
+ALLEGRO_AUDIO_STREAM* stream = al_load_audio_stream("music.ogg", 4, 2048);
+
+/* The sample needs sample instances to output sound. */
+ALLEGRO_SAMPLE* sample = al_load_sample("sound.wav")
+ALLEGRO_SAMPLE_INSTANCE* instance_1 = al_create_sample_instance(sample);
+ALLEGRO_SAMPLE_INSTANCE* instance_2 = al_create_sample_instance(sample);
+
+/* Attach everything up (see diagram). */
+al_attach_mixer_to_voice(mixer_1, voice);
+al_attach_mixer_to_mixer(mixer_2, mixer_1);
+al_attach_audio_stream_to_mixer(stream, mixer_1);
+al_attach_sample_instance_to_mixer(instance_1, mixer_2);
+al_attach_sample_instance_to_mixer(instance_2, mixer_2);
+
+/* Play two copies of the sound simultaneously. */
+al_set_sample_instance_playing(instance_1, true);
+al_set_sample_instance_playing(instance_2, true);
+
+An example configuration of the audio system to play music and a sound. +
+

Since we have two mixers, with the sample instances connected to a different mixer than the audio stream, you can control the volume of all the instances independently from the music by setting the gain of the mixer / stream. Having two sample instances lets you play two copies of the sample simultaneously.

+

With this in mind, another look at al_reserve_samples and al_play_sample is due: What the former does internally is to create a specified number of sample instances that are “empty” at first, i.e. with no sample data set. When al_play_sample is called, it’ll use one of these internal sample instances that is not currently playing to play the requested sample. All of these sample instances will be attached to the default mixer, which can be changed via al_set_default_mixer.

+

See Audio recording for Allegro’s audio recording API, which is, as of now, still unstable and subject to change.

+

Audio types

+

Events sent by al_get_audio_stream_event_source or al_get_audio_recorder_event_source.

+

ALLEGRO_AUDIO_EVENT_TYPE

+
enum ALLEGRO_AUDIO_EVENT_TYPE
+

Source Code

+

ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT

+

Sent when a stream fragment is ready to be filled in. See al_get_audio_stream_fragment.

+

ALLEGRO_EVENT_AUDIO_STREAM_FINISHED

+

Sent when a stream is finished.

+

ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT

+

Sent after a user-specified number of samples have been recorded. Convert this to ALLEGRO_AUDIO_RECORDER_EVENT via al_get_audio_recorder_event.

+

You must always check the values for the buffer and samples as they are not guaranteed to be exactly what was originally specified.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

ALLEGRO_AUDIO_DEPTH

+
enum ALLEGRO_AUDIO_DEPTH
+

Source Code

+

Sample depth and type as well as signedness. Mixers only use 32-bit signed float (-1..+1), or 16-bit signed integers. Signedness is determined by an “unsigned” bit-flag applied to the depth value.

+
    +
  • ALLEGRO_AUDIO_DEPTH_INT8
  • +
  • ALLEGRO_AUDIO_DEPTH_INT16
  • +
  • ALLEGRO_AUDIO_DEPTH_INT24
  • +
  • ALLEGRO_AUDIO_DEPTH_FLOAT32
  • +
  • ALLEGRO_AUDIO_DEPTH_UNSIGNED
  • +
+

For convenience:

+
    +
  • ALLEGRO_AUDIO_DEPTH_UINT8
  • +
  • ALLEGRO_AUDIO_DEPTH_UINT16
  • +
  • ALLEGRO_AUDIO_DEPTH_UINT24
  • +
+

Examples:

+ +

ALLEGRO_AUDIO_PAN_NONE

+
#define ALLEGRO_AUDIO_PAN_NONE      (-1000.0f)
+

Source Code

+

A special value for the pan property of sample instances and audio streams. Use this value to disable panning on sample instances and audio streams, and play them without attentuation implied by panning support.

+

ALLEGRO_AUDIO_PAN_NONE is different from a pan value of 0.0 (centered) because, when panning is enabled, we try to maintain a constant sound power level as a sample is panned from left to right. A sound coming out of one speaker should sound as loud as it does when split over two speakers. As a consequence, a sample with pan value 0.0 will be 3 dB softer than the original level.

+

(Please correct us if this is wrong.)

+

Examples:

+ +

ALLEGRO_CHANNEL_CONF

+
enum ALLEGRO_CHANNEL_CONF
+

Source Code

+

Speaker configuration (mono, stereo, 2.1, etc).

+
    +
  • ALLEGRO_CHANNEL_CONF_1
  • +
  • ALLEGRO_CHANNEL_CONF_2
  • +
  • ALLEGRO_CHANNEL_CONF_3
  • +
  • ALLEGRO_CHANNEL_CONF_4
  • +
  • ALLEGRO_CHANNEL_CONF_5_1
  • +
  • ALLEGRO_CHANNEL_CONF_6_1
  • +
  • ALLEGRO_CHANNEL_CONF_7_1
  • +
+

Examples:

+ +

ALLEGRO_MIXER

+
typedef struct ALLEGRO_MIXER ALLEGRO_MIXER;
+

Source Code

+

A mixer mixes together attached streams into a single buffer. In the process, it converts channel configurations, sample frequencies and audio depths of the attached sample instances and audio streams accordingly. You can control the quality of this conversion using ALLEGRO_MIXER_QUALITY.

+

When going from mono to stereo (and above), the mixer reduces the volume of both channels by sqrt(2). When going from stereo (and above) to mono, the mixer reduces the volume of the left and right channels by sqrt(2) before adding them to the center channel (if present).

+

Examples:

+ +

ALLEGRO_MIXER_QUALITY

+
enum ALLEGRO_MIXER_QUALITY
+

Source Code

+
    +
  • ALLEGRO_MIXER_QUALITY_POINT - point sampling
  • +
  • ALLEGRO_MIXER_QUALITY_LINEAR - linear interpolation
  • +
  • ALLEGRO_MIXER_QUALITY_CUBIC - cubic interpolation (since: 5.0.8, 5.1.4)
  • +
+

ALLEGRO_PLAYMODE

+
enum ALLEGRO_PLAYMODE
+

Source Code

+

Sample and stream playback mode.

+
    +
  • ALLEGRO_PLAYMODE_ONCE - the sample/stream is played from start to finish an then it stops.
  • +
  • ALLEGRO_PLAYMODE_LOOP - the sample/stream is played from start to finish (or between the two loop points). When it reaches the end, it restarts from the beginning.
  • +
  • ALLEGRO_PLAYMODE_BIDIR - the sample is played from start to finish (or between the two loop points). When it reaches the end, it reverses the playback direction and plays until it reaches the beginning when it reverses the direction back to normal. This is mode is rarely supported for streams.
  • +
+

Examples:

+ +

ALLEGRO_SAMPLE_ID

+
typedef struct ALLEGRO_SAMPLE_ID ALLEGRO_SAMPLE_ID;
+

Source Code

+

An ALLEGRO_SAMPLE_ID represents a sample being played via al_play_sample. It can be used to later stop the sample with al_stop_sample. The underlying ALLEGRO_SAMPLE_INSTANCE can be extracted using al_lock_sample_id.

+

Examples:

+ +

ALLEGRO_SAMPLE

+
typedef struct ALLEGRO_SAMPLE ALLEGRO_SAMPLE;
+

Source Code

+

An ALLEGRO_SAMPLE object stores the data necessary for playing pre-defined digital audio. It holds a user-specified PCM data buffer and information about its format (data length, depth, frequency, channel configuration). You can have the same ALLEGRO_SAMPLE playing multiple times simultaneously.

+

See also: ALLEGRO_SAMPLE_INSTANCE

+

Examples:

+ +

ALLEGRO_SAMPLE_INSTANCE

+
typedef struct ALLEGRO_SAMPLE_INSTANCE ALLEGRO_SAMPLE_INSTANCE;
+

Source Code

+

An ALLEGRO_SAMPLE_INSTANCE object represents a playable instance of a predefined sound effect. It holds information about how the effect should be played: These playback parameters consist of the looping mode, loop start/end points, playing position, speed, gain, pan and the playmode. Whether a sample instance is currently playing or paused is also one of its properties.

+

An instance uses the data from an ALLEGRO_SAMPLE object. Multiple instances may be created from the same ALLEGRO_SAMPLE. An ALLEGRO_SAMPLE must not be destroyed while there are instances which reference it.

+

To actually produce audio output, an ALLEGRO_SAMPLE_INSTANCE must be attached to an ALLEGRO_MIXER which eventually reaches an ALLEGRO_VOICE object.

+

See also: ALLEGRO_SAMPLE

+

Examples:

+ +

ALLEGRO_AUDIO_STREAM

+
typedef struct ALLEGRO_AUDIO_STREAM ALLEGRO_AUDIO_STREAM;
+

Source Code

+

An ALLEGRO_AUDIO_STREAM object is used to stream generated audio to the sound device, in real-time. This is done by reading from a buffer, which is split into a number of fragments. Whenever a fragment has finished playing, the user can refill it with new data.

+

As with ALLEGRO_SAMPLE_INSTANCE objects, streams store information necessary for playback, so you may not play the same stream multiple times simultaneously. Streams also need to be attached to an ALLEGRO_MIXER, which, eventually, reaches an ALLEGRO_VOICE object.

+

While playing, you must periodically fill fragments with new audio data. To know when a new fragment is ready to be filled, you can either directly check with al_get_available_audio_stream_fragments, or listen to events from the stream.

+

You can register an audio stream event source to an event queue; see al_get_audio_stream_event_source. An ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event is generated whenever a new fragment is ready. When you receive an event, use al_get_audio_stream_fragment to obtain a pointer to the fragment to be filled. The size and format are determined by the parameters passed to al_create_audio_stream.

+

If you’re late with supplying new data, the stream will be silent until new data is provided. You must call al_drain_audio_stream when you’re finished with supplying data to the stream.

+

If the stream is created by al_load_audio_stream then it will also generate an ALLEGRO_EVENT_AUDIO_STREAM_FINISHED event if it reaches the end of the file and is not set to loop.

+

Examples:

+ +

ALLEGRO_VOICE

+
typedef struct ALLEGRO_VOICE ALLEGRO_VOICE;
+

Source Code

+

A voice represents an audio device on the system, which may be a real device, or an abstract device provided by the operating system. To play back audio, you would attach a mixer, sample instance or audio stream to a voice.

+

See also: ALLEGRO_MIXER, ALLEGRO_SAMPLE, ALLEGRO_AUDIO_STREAM

+

Examples:

+ +

Setting up audio

+

al_install_audio

+
bool al_install_audio(void)
+

Source Code

+

Install the audio subsystem.

+

Returns true on success, false on failure.

+
+

Note: most users will call al_reserve_samples and al_init_acodec_addon after this.

+
+

See also: al_reserve_samples, al_uninstall_audio, al_is_audio_installed, al_init_acodec_addon

+

Examples:

+ +

al_uninstall_audio

+
void al_uninstall_audio(void)
+

Source Code

+

Uninstalls the audio subsystem.

+

See also: al_install_audio

+

Examples:

+ +

al_is_audio_installed

+
bool al_is_audio_installed(void)
+

Source Code

+

Returns true if al_install_audio was called previously and returned successfully.

+

al_reserve_samples

+
bool al_reserve_samples(int reserve_samples)
+

Source Code

+

Reserves a number of sample instances, attaching them to the default mixer. If no default mixer is set when this function is called, then it will create one and attach it to the default voice. If no default voice has been set, it, too, will be created.

+

If you call this function a second time with a smaller number of samples, then the excess internal sample instances will be destroyed causing some sounds to stop and some instances returned by al_lock_sample_id to be invalidated.

+

This diagram illustrates the structures that are set up:

+
                                      sample instance 1
+                                    / sample instance 2
+default voice <-- default mixer <---         .
+                                    \        .
+                                      sample instance N
+

Returns true on success, false on error. al_install_audio must have been called first.

+

See also: al_set_default_mixer, al_play_sample

+

Examples:

+ +

Misc audio functions

+

al_get_allegro_audio_version

+
uint32_t al_get_allegro_audio_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

al_get_audio_depth_size

+
size_t al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH depth)
+

Source Code

+

Return the size of a sample, in bytes, for the given format. The format is one of the values listed under ALLEGRO_AUDIO_DEPTH.

+

Examples:

+ +

al_get_channel_count

+
size_t al_get_channel_count(ALLEGRO_CHANNEL_CONF conf)
+

Source Code

+

Return the number of channels for the given channel configuration, which is one of the values listed under ALLEGRO_CHANNEL_CONF.

+

Examples:

+ +

al_fill_silence

+
void al_fill_silence(void *buf, unsigned int samples,
+   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)
+

Source Code

+

Fill a buffer with silence, for the given format and channel configuration. The buffer must have enough space for the given number of samples, and be properly aligned.

+

Since: 5.1.8

+

Voice functions

+

al_create_voice

+
ALLEGRO_VOICE *al_create_voice(unsigned int freq,
+   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)
+

Source Code

+

Creates a voice structure and allocates a voice from the digital sound driver. The passed frequency (in Hz), sample format and channel configuration are used as a hint to what kind of data will be sent to the voice. However, the underlying sound driver is free to use non-matching values. For example, it may be the native format of the sound hardware.

+

If a mixer is attached to the voice, the mixer will handle the conversion of all its input streams to the voice format and care does not have to be taken for this. However if you access the voice directly, make sure to not rely on the parameters passed to this function, but instead query the returned voice for the actual settings.

+

See also: al_destroy_voice

+

Examples:

+ +

al_destroy_voice

+
void al_destroy_voice(ALLEGRO_VOICE *voice)
+

Source Code

+

Destroys the voice and deallocates it from the digital driver. Does nothing if the voice is NULL.

+

See also: al_create_voice

+

Examples:

+ +

al_detach_voice

+
void al_detach_voice(ALLEGRO_VOICE *voice)
+

Source Code

+

Detaches the mixer, sample instance or audio stream from the voice.

+

See also: al_attach_mixer_to_voice, al_attach_sample_instance_to_voice, al_attach_audio_stream_to_voice

+

al_attach_audio_stream_to_voice

+
bool al_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM *stream,
+   ALLEGRO_VOICE *voice)
+

Source Code

+

Attaches an audio stream to a voice. The same rules as al_attach_sample_instance_to_voice apply. This may fail if the driver can’t create a voice with the buffer count and buffer size the stream uses.

+

An audio stream attached directly to a voice has a number of limitations: The audio stream plays immediately and cannot be stopped. The stream position, speed, gain and panning cannot be changed. At this time, we don’t recommend attaching audio streams directly to voices. Use a mixer inbetween.

+

Returns true on success, false on failure.

+

See also: al_detach_voice

+

Examples:

+ +

al_attach_mixer_to_voice

+
bool al_attach_mixer_to_voice(ALLEGRO_MIXER *mixer, ALLEGRO_VOICE *voice)
+

Source Code

+

Attaches a mixer to a voice. It must have the same frequency and channel configuration, but the depth may be different.

+

Returns true on success, false on failure.

+

See also: al_detach_voice

+

Examples:

+ +

al_attach_sample_instance_to_voice

+
bool al_attach_sample_instance_to_voice(ALLEGRO_SAMPLE_INSTANCE *spl,
+   ALLEGRO_VOICE *voice)
+

Source Code

+

Attaches a sample instance to a voice, and allows it to play. The instance’s gain and loop mode will be ignored, and it must have the same frequency, channel configuration and depth (including signed-ness) as the voice. This function may fail if the selected driver doesn’t support preloading sample data.

+

At this time, we don’t recommend attaching sample instances directly to voices. Use a mixer inbetween.

+

Returns true on success, false on failure.

+

See also: al_detach_voice

+

Examples:

+ +

al_get_voice_frequency

+
unsigned int al_get_voice_frequency(const ALLEGRO_VOICE *voice)
+

Source Code

+

Return the frequency of the voice (in Hz), e.g. 44100.

+

al_get_voice_channels

+
ALLEGRO_CHANNEL_CONF al_get_voice_channels(const ALLEGRO_VOICE *voice)
+

Source Code

+

Return the channel configuration of the voice.

+

See also: ALLEGRO_CHANNEL_CONF.

+

al_get_voice_depth

+
ALLEGRO_AUDIO_DEPTH al_get_voice_depth(const ALLEGRO_VOICE *voice)
+

Source Code

+

Return the audio depth of the voice.

+

See also: ALLEGRO_AUDIO_DEPTH.

+

al_get_voice_playing

+
bool al_get_voice_playing(const ALLEGRO_VOICE *voice)
+

Source Code

+

Return true if the voice is currently playing.

+

See also: al_set_voice_playing

+

Examples:

+ +

al_set_voice_playing

+
bool al_set_voice_playing(ALLEGRO_VOICE *voice, bool val)
+

Source Code

+

Change whether a voice is playing or not. This can only work if the voice has a non-streaming object attached to it, e.g. a sample instance. On success the voice’s current sample position is reset.

+

Returns true on success, false on failure.

+

See also: al_get_voice_playing

+

Examples:

+ +

al_get_voice_position

+
unsigned int al_get_voice_position(const ALLEGRO_VOICE *voice)
+

Source Code

+

When the voice has a non-streaming object attached to it, e.g. a sample, returns the voice’s current sample position. Otherwise, returns zero.

+

See also: al_set_voice_position.

+

al_set_voice_position

+
bool al_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val)
+

Source Code

+

Set the voice position. This can only work if the voice has a non-streaming object attached to it, e.g. a sample instance.

+

Returns true on success, false on failure.

+

See also: al_get_voice_position.

+

Sample functions

+

al_create_sample

+
ALLEGRO_SAMPLE *al_create_sample(void *buf, unsigned int samples,
+   unsigned int freq, ALLEGRO_AUDIO_DEPTH depth,
+   ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf)
+

Source Code

+

Create a sample data structure from the supplied buffer. If free_buf is true then the buffer will be freed with al_free when the sample data structure is destroyed. For portability (especially Windows), the buffer should have been allocated with al_malloc. Otherwise you should free the sample data yourself.

+

A sample that is referred to by the samples parameter refers to a sequence channel intensities. E.g. if you’re making a stereo sample with the samples set to 4, then the layout of the data in buf will be:

+
LRLRLRLR
+

Where L and R are the intensities for the left and right channels respectively. A single sample, then, refers to the LR pair in this example.

+

To allocate a buffer of the correct size, you can use something like this:

+
int sample_size = al_get_channel_count(chan_conf)
+                  * al_get_audio_depth_size(depth);
+int bytes = samples * sample_size;
+void *buffer = al_malloc(bytes);
+

See also: al_destroy_sample, ALLEGRO_AUDIO_DEPTH, ALLEGRO_CHANNEL_CONF

+

Examples:

+ +

al_destroy_sample

+
void al_destroy_sample(ALLEGRO_SAMPLE *spl)
+

Source Code

+

Free the sample data structure. If it was created with the free_buf parameter set to true, then the buffer will be freed with al_free.

+

This function will stop any sample instances which may be playing the buffer referenced by the ALLEGRO_SAMPLE.

+

See also: al_destroy_sample_instance, al_stop_sample, al_stop_samples

+

Examples:

+ +

al_play_sample

+
bool al_play_sample(ALLEGRO_SAMPLE *spl, float gain, float pan, float speed,
+   ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id)
+

Source Code

+

Plays a sample on one of the sample instances created by al_reserve_samples. Returns true on success, false on failure. Playback may fail because all the reserved sample instances are currently used.

+

Parameters:

+
    +
  • gain - relative volume at which the sample is played; 1.0 is normal.
  • +
  • pan - 0.0 is centred, -1.0 is left, 1.0 is right, or ALLEGRO_AUDIO_PAN_NONE.
  • +
  • speed - relative speed at which the sample is played; 1.0 is normal.
  • +
  • loop - ALLEGRO_PLAYMODE_ONCE, ALLEGRO_PLAYMODE_LOOP, or ALLEGRO_PLAYMODE_BIDIR
  • +
  • ret_id - if non-NULL the variable which this points to will be assigned an id representing the sample being played. If al_play_sample returns false, then the contents of ret_id are invalid and must not be used as argument to other functions.
  • +
+

See also: ALLEGRO_PLAYMODE, ALLEGRO_AUDIO_PAN_NONE, ALLEGRO_SAMPLE_ID, al_stop_sample, al_stop_samples, al_lock_sample_id.

+

Examples:

+ +

al_stop_sample

+
void al_stop_sample(ALLEGRO_SAMPLE_ID *spl_id)
+

Source Code

+

Stop the sample started by al_play_sample.

+

See also: al_stop_samples

+

Examples:

+ +

al_lock_sample_id

+
ALLEGRO_SAMPLE_INSTANCE* al_lock_sample_id(ALLEGRO_SAMPLE_ID *spl_id)
+

Source Code

+

Locks a ALLEGRO_SAMPLE_ID, returning the underlying ALLEGRO_SAMPLE_INSTANCE. This allows you to adjust the various properties of the instance (such as volume, pan, etc) while the sound is playing.

+

This function will return NULL if the sound corresponding to the id is no longer playing.

+

While locked, ALLEGRO_SAMPLE_ID will be unavailable to additional calls to al_play_sample, even if the sound stops while locked. To put the ALLEGRO_SAMPLE_ID back into the pool for reuse, make sure to call al_unlock_sample_id when you’re done with the instance.

+

See also: al_play_sample, al_unlock_sample_id

+

Since: 5.2.3

+
+

Unstable API: New API.

+
+

Examples:

+ +

al_unlock_sample_id

+
void al_unlock_sample_id(ALLEGRO_SAMPLE_ID *spl_id)
+

Source Code

+

Unlocks a ALLEGRO_SAMPLE_ID, allowing future calls to al_play_sample to reuse it if possible. Note that after the id is unlocked, the ALLEGRO_SAMPLE_INSTANCE that was previously returned by al_lock_sample_id will possibly be playing a different sound, so you should only use it after locking the id again.

+

See also: al_play_sample, al_lock_sample_id

+

Since: 5.2.3

+
+

Unstable API: New API.

+
+

Examples:

+ +

al_stop_samples

+
void al_stop_samples(void)
+

Source Code

+

Stop all samples started by al_play_sample.

+

See also: al_stop_sample

+

Examples:

+ +

al_get_sample_channels

+
ALLEGRO_CHANNEL_CONF al_get_sample_channels(const ALLEGRO_SAMPLE *spl)
+

Source Code

+

Return the channel configuration of the sample.

+

See also: ALLEGRO_CHANNEL_CONF, al_get_sample_depth, al_get_sample_frequency, al_get_sample_length, al_get_sample_data

+

al_get_sample_depth

+
ALLEGRO_AUDIO_DEPTH al_get_sample_depth(const ALLEGRO_SAMPLE *spl)
+

Source Code

+

Return the audio depth of the sample.

+

See also: ALLEGRO_AUDIO_DEPTH, al_get_sample_channels, al_get_sample_frequency, al_get_sample_length, al_get_sample_data

+

al_get_sample_frequency

+
unsigned int al_get_sample_frequency(const ALLEGRO_SAMPLE *spl)
+

Source Code

+

Return the frequency (in Hz) of the sample.

+

See also: al_get_sample_channels, al_get_sample_depth, al_get_sample_length, al_get_sample_data

+

al_get_sample_length

+
unsigned int al_get_sample_length(const ALLEGRO_SAMPLE *spl)
+

Source Code

+

Return the length of the sample in sample values.

+

See also: al_get_sample_channels, al_get_sample_depth, al_get_sample_frequency, al_get_sample_data

+

al_get_sample_data

+
void *al_get_sample_data(const ALLEGRO_SAMPLE *spl)
+

Source Code

+

Return a pointer to the raw sample data.

+

See also: al_get_sample_channels, al_get_sample_depth, al_get_sample_frequency, al_get_sample_length

+

Examples:

+ +

Sample instance functions

+

al_create_sample_instance

+
ALLEGRO_SAMPLE_INSTANCE *al_create_sample_instance(ALLEGRO_SAMPLE *sample_data)
+

Source Code

+

Creates a sample instance, using the supplied sample data. The instance must be attached to a mixer (or voice) in order to actually produce output.

+

The argument may be NULL. You can then set the sample data later with al_set_sample.

+

See also: al_destroy_sample_instance

+

Examples:

+ +

al_destroy_sample_instance

+
void al_destroy_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Detaches the sample instance from anything it may be attached to and frees it (the sample data, i.e. its ALLEGRO_SAMPLE, is not freed!).

+

See also: al_create_sample_instance

+

Examples:

+ +

al_play_sample_instance

+
bool al_play_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Play the sample instance. Returns true on success, false on failure.

+

See also: al_stop_sample_instance

+

Examples:

+ +

al_stop_sample_instance

+
bool al_stop_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Stop an sample instance playing.

+

See also: al_play_sample_instance

+

Examples:

+ +

al_get_sample_instance_channels

+
ALLEGRO_CHANNEL_CONF al_get_sample_instance_channels(
+   const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the channel configuration of the sample instance’s sample data.

+

See also: ALLEGRO_CHANNEL_CONF.

+

Examples:

+ +

al_get_sample_instance_depth

+
ALLEGRO_AUDIO_DEPTH al_get_sample_instance_depth(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the audio depth of the sample instance’s sample data.

+

See also: ALLEGRO_AUDIO_DEPTH.

+

Examples:

+ +

al_get_sample_instance_frequency

+
unsigned int al_get_sample_instance_frequency(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the frequency (in Hz) of the sample instance’s sample data.

+

Examples:

+ +

al_get_sample_instance_length

+
unsigned int al_get_sample_instance_length(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the length of the sample instance in sample values. This property may differ from the length of the instance’s sample data.

+

See also: al_set_sample_instance_length, al_get_sample_instance_time

+

Examples:

+ +

al_set_sample_instance_length

+
bool al_set_sample_instance_length(ALLEGRO_SAMPLE_INSTANCE *spl,
+   unsigned int val)
+

Source Code

+

Set the length of the sample instance in sample values. This can be used to play only parts of the underlying sample. Be careful not to exceed the actual length of the sample data, though.

+

Return true on success, false on failure. Will fail if the sample instance is currently playing.

+

See also: al_get_sample_instance_length

+

Examples:

+ +

al_get_sample_instance_position

+
unsigned int al_get_sample_instance_position(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Get the playback position of a sample instance.

+

See also: al_set_sample_instance_position

+

Examples:

+ +

al_set_sample_instance_position

+
bool al_set_sample_instance_position(ALLEGRO_SAMPLE_INSTANCE *spl,
+   unsigned int val)
+

Source Code

+

Set the playback position of a sample instance.

+

Returns true on success, false on failure.

+

See also: al_get_sample_instance_position

+

Examples:

+ +

al_get_sample_instance_speed

+
float al_get_sample_instance_speed(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the relative playback speed of the sample instance.

+

See also: al_set_sample_instance_speed

+

al_set_sample_instance_speed

+
bool al_set_sample_instance_speed(ALLEGRO_SAMPLE_INSTANCE *spl, float val)
+

Source Code

+

Set the relative playback speed of the sample instance. 1.0 means normal speed.

+

Return true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

+

See also: al_get_sample_instance_speed

+

Examples:

+ +

al_get_sample_instance_gain

+
float al_get_sample_instance_gain(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the playback gain of the sample instance.

+

See also: al_set_sample_instance_gain

+

Examples:

+ +

al_set_sample_instance_gain

+
bool al_set_sample_instance_gain(ALLEGRO_SAMPLE_INSTANCE *spl, float val)
+

Source Code

+

Set the playback gain of the sample instance.

+

Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

+

See also: al_get_sample_instance_gain

+

Examples:

+ +

al_get_sample_instance_pan

+
float al_get_sample_instance_pan(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Get the pan value of the sample instance.

+

See also: al_set_sample_instance_pan.

+

al_set_sample_instance_pan

+
bool al_set_sample_instance_pan(ALLEGRO_SAMPLE_INSTANCE *spl, float val)
+

Source Code

+

Set the pan value on a sample instance. A value of -1.0 means to play the sample only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value ALLEGRO_AUDIO_PAN_NONE disables panning and plays the sample at its original level. This will be louder than a pan value of 0.0.

+
+

Note: panning samples with more than two channels doesn’t work yet.

+
+

Returns true on success, false on failure. Will fail if the sample instance is attached directly to a voice.

+

See also: al_get_sample_instance_pan, ALLEGRO_AUDIO_PAN_NONE

+

Examples:

+ +

al_get_sample_instance_time

+
float al_get_sample_instance_time(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the length of the sample instance in seconds, assuming a playback speed of 1.0.

+

See also: al_get_sample_instance_length

+

Examples:

+ +

al_get_sample_instance_playmode

+
ALLEGRO_PLAYMODE al_get_sample_instance_playmode(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the playback mode of the sample instance.

+

See also: ALLEGRO_PLAYMODE, al_set_sample_instance_playmode

+

al_set_sample_instance_playmode

+
bool al_set_sample_instance_playmode(ALLEGRO_SAMPLE_INSTANCE *spl,
+   ALLEGRO_PLAYMODE val)
+

Source Code

+

Set the playback mode of the sample instance.

+

Returns true on success, false on failure.

+

See also: ALLEGRO_PLAYMODE, al_get_sample_instance_playmode

+

Examples:

+ +

al_get_sample_instance_playing

+
bool al_get_sample_instance_playing(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return true if the sample instance is in the playing state. This may be true even if the instance is not attached to anything.

+

See also: al_set_sample_instance_playing

+

Examples:

+ +

al_set_sample_instance_playing

+
bool al_set_sample_instance_playing(ALLEGRO_SAMPLE_INSTANCE *spl, bool val)
+

Source Code

+

Change whether the sample instance is playing.

+

The instance does not need to be attached to anything (since: 5.1.8).

+

Returns true on success, false on failure.

+

See also: al_get_sample_instance_playing

+

Examples:

+ +

al_get_sample_instance_attached

+
bool al_get_sample_instance_attached(const ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return whether the sample instance is attached to something.

+

See also: al_attach_sample_instance_to_mixer, al_attach_sample_instance_to_voice, al_detach_sample_instance

+

al_detach_sample_instance

+
bool al_detach_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Detach the sample instance from whatever it’s attached to, if anything.

+

Returns true on success.

+

See also: al_attach_sample_instance_to_mixer, al_attach_sample_instance_to_voice, al_get_sample_instance_attached

+

Examples:

+ +

al_get_sample

+
ALLEGRO_SAMPLE *al_get_sample(ALLEGRO_SAMPLE_INSTANCE *spl)
+

Source Code

+

Return the sample data that the sample instance plays.

+

Note this returns a pointer to an internal structure, not the ALLEGRO_SAMPLE that you may have passed to al_set_sample. However, the sample buffer of the returned ALLEGRO_SAMPLE will be the same as the one that was used to create the sample (passed to al_create_sample). You can use al_get_sample_data on the return value to retrieve and compare it.

+

See also: al_set_sample

+

Examples:

+ +

al_set_sample

+
bool al_set_sample(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data)
+

Source Code

+

Change the sample data that a sample instance plays. This can be quite an involved process.

+

First, the sample is stopped if it is not already.

+

Next, if data is NULL, the sample is detached from its parent (if any).

+

If data is not NULL, the sample may be detached and reattached to its parent (if any). This is not necessary if the old sample data and new sample data have the same frequency, depth and channel configuration. Reattaching may not always succeed.

+

On success, the sample remains stopped. The playback position and loop end points are reset to their default values. The loop mode remains unchanged.

+

Returns true on success, false on failure. On failure, the sample will be stopped and detached from its parent.

+

See also: al_get_sample

+

Examples:

+ +

al_set_sample_instance_channel_matrix

+
bool al_set_sample_instance_channel_matrix(ALLEGRO_SAMPLE_INSTANCE *spl, const float *matrix)
+

Source Code

+

Set the matrix used to mix the channels coming from this instance into the mixer it is attached to. Normally Allegro derives the values of this matrix from the gain and pan settings, as well as the channel configurations of this instance and the mixer it is attached to, but this allows you override that default value. Note that if you do set gain or pan of this instance or the mixer it is attached to, you’ll need to call this function again.

+

The matrix has mixer channel rows and sample channel columns, and is row major. For example, if you have a stereo sample instance and want to mix it to a 5.1 mixer you could use this code:

+
float matrix[] = {
+    0.5, 0.0, /* Half left to front left */
+    0.0, 0.5, /* Half right to front right */
+    0.5, 0.0, /* Half left to rear left */
+    0.0, 0.5, /* Half right to rear right */
+    0.1, 0.1, /* Mix left and right for center */
+    0.1, 0.1, /* Mix left and right for center */
+};
+
+al_set_sample_instance_channel_matrix(instance, matrix);
+

Returns true on success, false on failure (e.g. if this is not attached to a mixer).

+

Since: 5.2.3

+
+

Unstable API: New API.

+
+

Examples:

+ +

Mixer functions

+

al_create_mixer

+
ALLEGRO_MIXER *al_create_mixer(unsigned int freq,
+   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)
+

Source Code

+

Creates a mixer to attach sample instances, audio streams, or other mixers to. It will mix into a buffer at the requested frequency (in Hz) and channel count.

+

The only supported audio depths are ALLEGRO_AUDIO_DEPTH_FLOAT32 and ALLEGRO_AUDIO_DEPTH_INT16 (not yet complete).

+

To actually produce any output, the mixer will have to be attached to a voice.

+

Returns true on success, false on error.

+

See also: al_destroy_mixer, ALLEGRO_AUDIO_DEPTH, ALLEGRO_CHANNEL_CONF

+

Examples:

+ +

al_destroy_mixer

+
void al_destroy_mixer(ALLEGRO_MIXER *mixer)
+

Source Code

+

Destroys the mixer.

+

See also: al_create_mixer

+

Examples:

+ +

al_get_default_mixer

+
ALLEGRO_MIXER *al_get_default_mixer(void)
+

Source Code

+

Return the default mixer, or NULL if one has not been set. Although different configurations of mixers and voices can be used, in most cases a single mixer attached to a voice is what you want. The default mixer is used by al_play_sample.

+

See also: al_reserve_samples, al_play_sample, al_set_default_mixer, al_restore_default_mixer

+

Examples:

+ +

al_set_default_mixer

+
bool al_set_default_mixer(ALLEGRO_MIXER *mixer)
+

Source Code

+

Sets the default mixer. All samples started with al_play_sample will be stopped and all sample instances returned by al_lock_sample_id will be invalidated. If you are using your own mixer, this should be called before al_reserve_samples.

+

Returns true on success, false on error.

+

See also: al_reserve_samples, al_play_sample, al_get_default_mixer, al_restore_default_mixer

+

al_restore_default_mixer

+
bool al_restore_default_mixer(void)
+

Source Code

+

Restores Allegro’s default mixer and attaches it to the default voice. If the default mixer hasn’t been created before, it will be created. If the default voice hasn’t been set via al_set_default_voice or created before, it will also be created. All samples started with al_play_sample will be stopped and all sample instances returned by al_lock_sample_id will be invalidated.

+

Returns true on success, false on error.

+

See also: al_get_default_mixer, al_set_default_mixer, al_reserve_samples.

+

al_get_default_voice

+
ALLEGRO_VOICE *al_get_default_voice(void)
+

Source Code

+

Returns the default voice or NULL if there is none.

+

Since: 5.1.13

+

See also: al_get_default_mixer

+

al_set_default_voice

+
void al_set_default_voice(ALLEGRO_VOICE *voice)
+

Source Code

+

You can call this before calling al_restore_default_mixer to provide the voice which should be used. Any previous voice will be destroyed. You can also pass NULL to destroy the current default voice.

+

Since: 5.1.13

+

See also: al_get_default_mixer

+

al_attach_mixer_to_mixer

+
bool al_attach_mixer_to_mixer(ALLEGRO_MIXER *stream, ALLEGRO_MIXER *mixer)
+

Source Code

+

Attaches the mixer passed as the first argument onto the mixer passed as the second argument. The first mixer (that is going to be attached) must not already be attached to anything. Both mixers must use the same frequency, audio depth and channel configuration.

+

Returns true on success, false on error.

+

It is invalid to attach a mixer to itself.

+

See also: al_detach_mixer.

+

Examples:

+ +

al_attach_sample_instance_to_mixer

+
bool al_attach_sample_instance_to_mixer(ALLEGRO_SAMPLE_INSTANCE *spl,
+   ALLEGRO_MIXER *mixer)
+

Source Code

+

Attach a sample instance to a mixer. The instance must not already be attached to anything.

+

Returns true on success, false on failure.

+

See also: al_detach_sample_instance.

+

Examples:

+ +

al_attach_audio_stream_to_mixer

+
bool al_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_MIXER *mixer)
+

Source Code

+

Attach an audio stream to a mixer. The stream must not already be attached to anything.

+

Returns true on success, false on failure.

+

See also: al_detach_audio_stream.

+

Examples:

+ +

al_get_mixer_frequency

+
unsigned int al_get_mixer_frequency(const ALLEGRO_MIXER *mixer)
+

Source Code

+

Return the mixer frequency (in Hz).

+

See also: al_set_mixer_frequency

+

al_set_mixer_frequency

+
bool al_set_mixer_frequency(ALLEGRO_MIXER *mixer, unsigned int val)
+

Source Code

+

Set the mixer frequency (in Hz). This will only work if the mixer is not attached to anything.

+

Returns true on success, false on failure.

+

See also: al_get_mixer_frequency

+

al_get_mixer_channels

+
ALLEGRO_CHANNEL_CONF al_get_mixer_channels(const ALLEGRO_MIXER *mixer)
+

Source Code

+

Return the mixer channel configuration.

+

See also: ALLEGRO_CHANNEL_CONF.

+

Examples:

+ +

al_get_mixer_depth

+
ALLEGRO_AUDIO_DEPTH al_get_mixer_depth(const ALLEGRO_MIXER *mixer)
+

Source Code

+

Return the mixer audio depth.

+

See also: ALLEGRO_AUDIO_DEPTH.

+

Examples:

+ +

al_get_mixer_gain

+
float al_get_mixer_gain(const ALLEGRO_MIXER *mixer)
+

Source Code

+

Return the mixer gain (amplification factor). The default is 1.0.

+

Since: 5.0.6, 5.1.0

+

See also: al_set_mixer_gain.

+

Examples:

+ +

al_set_mixer_gain

+
bool al_set_mixer_gain(ALLEGRO_MIXER *mixer, float new_gain)
+

Source Code

+

Set the mixer gain (amplification factor).

+

Returns true on success, false on failure.

+

Since: 5.0.6, 5.1.0

+

See also: al_get_mixer_gain

+

Examples:

+ +

al_get_mixer_quality

+
ALLEGRO_MIXER_QUALITY al_get_mixer_quality(const ALLEGRO_MIXER *mixer)
+

Source Code

+

Return the mixer quality.

+

See also: ALLEGRO_MIXER_QUALITY, al_set_mixer_quality

+

al_set_mixer_quality

+
bool al_set_mixer_quality(ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY new_quality)
+

Source Code

+

Set the mixer quality. This can only succeed if the mixer does not have anything attached to it.

+

Returns true on success, false on failure.

+

See also: ALLEGRO_MIXER_QUALITY, al_get_mixer_quality

+

al_get_mixer_playing

+
bool al_get_mixer_playing(const ALLEGRO_MIXER *mixer)
+

Source Code

+

Return true if the mixer is playing.

+

See also: al_set_mixer_playing.

+

Examples:

+ +

al_set_mixer_playing

+
bool al_set_mixer_playing(ALLEGRO_MIXER *mixer, bool val)
+

Source Code

+

Change whether the mixer is playing.

+

Returns true on success, false on failure.

+

See also: al_get_mixer_playing.

+

Examples:

+ +

al_get_mixer_attached

+
bool al_get_mixer_attached(const ALLEGRO_MIXER *mixer)
+

Source Code

+

Return true if the mixer is attached to something.

+

See also: al_attach_sample_instance_to_mixer, al_attach_audio_stream_to_mixer, al_attach_mixer_to_mixer, al_detach_mixer

+

al_detach_mixer

+
bool al_detach_mixer(ALLEGRO_MIXER *mixer)
+

Source Code

+

Detach the mixer from whatever it is attached to, if anything.

+

See also: al_attach_mixer_to_mixer.

+

Examples:

+ +

al_set_mixer_postprocess_callback

+
bool al_set_mixer_postprocess_callback(ALLEGRO_MIXER *mixer,
+   void (*pp_callback)(void *buf, unsigned int samples, void *data),
+   void *pp_callback_userdata)
+

Source Code

+

Sets a post-processing filter function that’s called after the attached streams have been mixed. The buffer’s format will be whatever the mixer was created with. The sample count and user-data pointer is also passed.

+
+

Note: The callback is called from a dedicated audio thread.

+
+

Examples:

+ +

Stream functions

+

al_create_audio_stream

+
ALLEGRO_AUDIO_STREAM *al_create_audio_stream(size_t fragment_count,
+   unsigned int frag_samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth,
+   ALLEGRO_CHANNEL_CONF chan_conf)
+

Source Code

+

Creates an ALLEGRO_AUDIO_STREAM. The stream will be set to play by default. It will feed audio data from a buffer, which is split into a number of fragments.

+

Parameters:

+
    +
  • fragment_count - How many fragments to use for the audio stream. Usually only two fragments are required - splitting the audio buffer in two halves. But it means that the only time when new data can be supplied is whenever one half has finished playing. When using many fragments, you usually will use fewer samples for one, so there always will be (small) fragments available to be filled with new data.

  • +
  • frag_samples - The size of a fragment in samples. See note and explanation below.

  • +
  • freq - The frequency, in Hertz.

  • +
  • depth - Must be one of the values listed for ALLEGRO_AUDIO_DEPTH.

  • +
  • chan_conf - Must be one of the values listed for ALLEGRO_CHANNEL_CONF.

  • +
+

A sample that is referred to by the frag_samples parameter refers to a sequence channel intensities. E.g. if you’re making a stereo stream with the frag_samples set to 4, then the layout of the data in the fragment will be:

+
LRLRLRLR
+

Where L and R are the intensities for the left and right channels respectively. A single sample, then, refers to the LR pair in this example.

+

The choice of fragment_count, frag_samples and freq directly influences the audio delay. The delay in seconds can be expressed as:

+
delay = fragment_count * frag_samples / freq
+

This is only the delay due to Allegro’s streaming, there may be additional delay caused by sound drivers and/or hardware.

+
+

Note: If you know the fragment size in bytes, you can get the size in samples like this:

+
sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth);
+samples = bytes_per_fragment / sample_size;
+

The size of the complete buffer is:

+
buffer_size = bytes_per_fragment * fragment_count
+
+
+

Note: Unlike many Allegro objects, audio streams are not implicitly destroyed when Allegro is shut down. You must destroy them manually with al_destroy_audio_stream before the audio system is shut down.

+
+

Examples:

+ +

al_destroy_audio_stream

+
void al_destroy_audio_stream(ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Destroy an audio stream which was created with al_create_audio_stream or al_load_audio_stream.

+
+

Note: If the stream is still attached to a mixer or voice, al_detach_audio_stream is automatically called on it first.

+
+

See also: al_drain_audio_stream.

+

Examples:

+ +

al_get_audio_stream_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_audio_stream_event_source(
+   ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Retrieve the associated event source.

+

See al_get_audio_stream_fragment for a description of the ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event that audio streams emit.

+

Examples:

+ +

al_drain_audio_stream

+
void al_drain_audio_stream(ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

You should call this to finalise an audio stream that you will no longer be feeding, to wait for all pending buffers to finish playing. The stream’s playing state will change to false.

+

See also: al_destroy_audio_stream

+

Examples:

+ +

al_rewind_audio_stream

+
bool al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Set the streaming file playing position to the beginning. Returns true on success. Currently this can only be called on streams created with al_load_audio_stream, al_load_audio_stream_f and the format-specific functions underlying those functions.

+

al_get_audio_stream_frequency

+
unsigned int al_get_audio_stream_frequency(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the stream frequency (in Hz).

+

al_get_audio_stream_channels

+
ALLEGRO_CHANNEL_CONF al_get_audio_stream_channels(
+   const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the stream channel configuration.

+

See also: ALLEGRO_CHANNEL_CONF.

+

al_get_audio_stream_depth

+
ALLEGRO_AUDIO_DEPTH al_get_audio_stream_depth(
+   const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the stream audio depth.

+

See also: ALLEGRO_AUDIO_DEPTH.

+

al_get_audio_stream_length

+
unsigned int al_get_audio_stream_length(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the stream length in samples.

+

Examples:

+ +

al_get_audio_stream_speed

+
float al_get_audio_stream_speed(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the relative playback speed of the stream.

+

See also: al_set_audio_stream_speed.

+

al_set_audio_stream_speed

+
bool al_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM *stream, float val)
+

Source Code

+

Set the relative playback speed of the stream. 1.0 means normal speed.

+

Return true on success, false on failure. Will fail if the audio stream is attached directly to a voice.

+

See also: al_get_audio_stream_speed.

+

al_get_audio_stream_gain

+
float al_get_audio_stream_gain(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the playback gain of the stream.

+

See also: al_set_audio_stream_gain.

+

Examples:

+ +

al_set_audio_stream_gain

+
bool al_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM *stream, float val)
+

Source Code

+

Set the playback gain of the stream.

+

Returns true on success, false on failure. Will fail if the audio stream is attached directly to a voice.

+

See also: al_get_audio_stream_gain.

+

Examples:

+ +

al_get_audio_stream_pan

+
float al_get_audio_stream_pan(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Get the pan value of the stream.

+

See also: al_set_audio_stream_pan.

+

al_set_audio_stream_pan

+
bool al_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM *stream, float val)
+

Source Code

+

Set the pan value on an audio stream. A value of -1.0 means to play the stream only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value ALLEGRO_AUDIO_PAN_NONE disables panning and plays the stream at its original level. This will be louder than a pan value of 0.0.

+

Returns true on success, false on failure. Will fail if the audio stream is attached directly to a voice.

+

See also: al_get_audio_stream_pan, ALLEGRO_AUDIO_PAN_NONE

+

Examples:

+ +

al_get_audio_stream_playing

+
bool al_get_audio_stream_playing(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return true if the stream is playing.

+

See also: al_set_audio_stream_playing.

+

Examples:

+ +

al_set_audio_stream_playing

+
bool al_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM *stream, bool val)
+

Source Code

+

Change whether the stream is playing.

+

Returns true on success, false on failure.

+

See also: al_get_audio_stream_playing

+

Examples:

+ +

al_get_audio_stream_playmode

+
ALLEGRO_PLAYMODE al_get_audio_stream_playmode(
+   const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the playback mode of the stream.

+

See also: ALLEGRO_PLAYMODE, al_set_audio_stream_playmode.

+

al_set_audio_stream_playmode

+
bool al_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM *stream,
+   ALLEGRO_PLAYMODE val)
+

Source Code

+

Set the playback mode of the stream.

+

Returns true on success, false on failure.

+

See also: ALLEGRO_PLAYMODE, al_get_audio_stream_playmode.

+

Examples:

+ +

al_get_audio_stream_attached

+
bool al_get_audio_stream_attached(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return whether the stream is attached to something.

+

See also: al_attach_audio_stream_to_mixer, al_attach_audio_stream_to_voice, al_detach_audio_stream.

+

al_detach_audio_stream

+
bool al_detach_audio_stream(ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Detach the stream from whatever it’s attached to, if anything.

+

See also: al_attach_audio_stream_to_mixer, al_attach_audio_stream_to_voice, al_get_audio_stream_attached.

+

Examples:

+ +

al_get_audio_stream_played_samples

+
uint64_t al_get_audio_stream_played_samples(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Get the number of samples consumed by the parent since the audio stream was started.

+

Since: 5.1.8

+

al_get_audio_stream_fragment

+
void *al_get_audio_stream_fragment(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

When using Allegro’s audio streaming, you will use this function to continuously provide new sample data to a stream.

+

If the stream is ready for new data, the function will return the address of an internal buffer to be filled with audio data. The length and format of the buffer are specified with al_create_audio_stream or can be queried with the various functions described here. Once the buffer is filled, you must signal this to Allegro by passing the buffer to al_set_audio_stream_fragment.

+

If the stream is not ready for new data, the function will return NULL.

+
+

Note: If you listen to events from the stream, an ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event will be generated whenever a new fragment is ready. However, getting an event is not a guarantee that al_get_audio_stream_fragment will not return NULL, so you still must check for it.

+
+

See also: al_set_audio_stream_fragment, al_get_audio_stream_event_source, al_get_audio_stream_frequency, al_get_audio_stream_channels, al_get_audio_stream_depth, al_get_audio_stream_length

+

Examples:

+ +

al_set_audio_stream_fragment

+
bool al_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM *stream, void *val)
+

Source Code

+

This function needs to be called for every successful call of al_get_audio_stream_fragment to indicate that the buffer (pointed to by val) is filled with new data.

+

See also: al_get_audio_stream_fragment

+

Examples:

+ +

al_get_audio_stream_fragments

+
unsigned int al_get_audio_stream_fragments(const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Returns the number of fragments this stream uses. This is the same value as passed to al_create_audio_stream when a new stream is created.

+

See also: al_get_available_audio_stream_fragments

+

al_get_available_audio_stream_fragments

+
unsigned int al_get_available_audio_stream_fragments(
+   const ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Returns the number of available fragments in the stream, that is, fragments which are not currently filled with data for playback.

+

See also: al_get_audio_stream_fragment, al_get_audio_stream_fragments

+

al_seek_audio_stream_secs

+
bool al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double time)
+

Source Code

+

Set the streaming file playing position to time. Returns true on success. Currently this can only be called on streams created with al_load_audio_stream, al_load_audio_stream_f and the format-specific functions underlying those functions.

+

See also: al_get_audio_stream_position_secs, al_get_audio_stream_length_secs

+

Examples:

+ +

al_get_audio_stream_position_secs

+
double al_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the position of the stream in seconds. Currently this can only be called on streams created with al_load_audio_stream.

+

See also: al_get_audio_stream_length_secs

+

Examples:

+ +

al_get_audio_stream_length_secs

+
double al_get_audio_stream_length_secs(ALLEGRO_AUDIO_STREAM *stream)
+

Source Code

+

Return the length of the stream in seconds, if known. Otherwise returns zero.

+

Currently this can only be called on streams created with al_load_audio_stream, al_load_audio_stream_f and the format-specific functions underlying those functions.

+

See also: al_get_audio_stream_position_secs

+

Examples:

+ +

al_set_audio_stream_loop_secs

+
bool al_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM *stream,
+   double start, double end)
+

Source Code

+

Sets the loop points for the stream in seconds. Currently this can only be called on streams created with al_load_audio_stream, al_load_audio_stream_f and the format-specific functions underlying those functions.

+

Examples:

+ +

al_set_audio_stream_channel_matrix

+

Source Code

+

Like al_set_sample_instance_channel_matrix but for streams.

+

Since: 5.2.3

+
+

Unstable API: New API.

+
+

Audio file I/O

+

al_register_sample_loader

+
bool al_register_sample_loader(const char *ext,
+   ALLEGRO_SAMPLE *(*loader)(const char *filename))
+

Source Code

+

Register a handler for al_load_sample. The given function will be used to handle the loading of sample files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The loader argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_sample_loader_f, al_register_sample_saver

+

al_register_sample_loader_f

+
bool al_register_sample_loader_f(const char *ext,
+   ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE* fp))
+

Source Code

+

Register a handler for al_load_sample_f. The given function will be used to handle the loading of sample files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The loader argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_sample_loader

+

al_register_sample_saver

+
bool al_register_sample_saver(const char *ext,
+   bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl))
+

Source Code

+

Register a handler for al_save_sample. The given function will be used to handle the saving of sample files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The saver argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_sample_saver_f, al_register_sample_loader

+

al_register_sample_saver_f

+
bool al_register_sample_saver_f(const char *ext,
+   bool (*saver)(ALLEGRO_FILE* fp, ALLEGRO_SAMPLE *spl))
+

Source Code

+

Register a handler for al_save_sample_f. The given function will be used to handle the saving of sample files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The saver argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_sample_saver

+

al_register_audio_stream_loader

+
bool al_register_audio_stream_loader(const char *ext,
+   ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename,
+      size_t buffer_count, unsigned int samples))
+

Source Code

+

Register a handler for al_load_audio_stream. The given function will be used to open streams from files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The stream_loader argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_audio_stream_loader_f

+

al_register_audio_stream_loader_f

+
bool al_register_audio_stream_loader_f(const char *ext,
+   ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE* fp,
+      size_t buffer_count, unsigned int samples))
+

Source Code

+

Register a handler for al_load_audio_stream_f. The given function will be used to open streams from files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The stream_loader argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_audio_stream_loader

+

al_load_sample

+
ALLEGRO_SAMPLE *al_load_sample(const char *filename)
+

Source Code

+

Loads a few different audio file formats based on their extension.

+

Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use al_load_audio_stream.

+

Returns the sample on success, NULL on failure.

+
+

Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

+
+

See also: al_register_sample_loader, al_init_acodec_addon

+

Examples:

+ +

al_load_sample_f

+
ALLEGRO_SAMPLE *al_load_sample_f(ALLEGRO_FILE* fp, const char *ident)
+

Source Code

+

Loads an audio file from an ALLEGRO_FILE stream into an ALLEGRO_SAMPLE. The file type is determined by the passed ‘ident’ parameter, which is a file name extension including the leading dot.

+

Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use al_load_audio_stream_f.

+

Returns the sample on success, NULL on failure. The file remains open afterwards.

+
+

Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

+
+

See also: al_register_sample_loader_f, al_init_acodec_addon

+

al_load_audio_stream

+
ALLEGRO_AUDIO_STREAM *al_load_audio_stream(const char *filename,
+   size_t buffer_count, unsigned int samples)
+

Source Code

+

Loads an audio file from disk as it is needed.

+

Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain buffer_count buffers with samples samples.

+

The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See ALLEGRO_AUDIO_STREAM for more details.

+

Returns the stream on success, NULL on failure.

+
+

Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

+
+

See also: al_load_audio_stream_f, al_register_audio_stream_loader, al_init_acodec_addon

+

Examples:

+ +

al_load_audio_stream_f

+
ALLEGRO_AUDIO_STREAM *al_load_audio_stream_f(ALLEGRO_FILE* fp, const char *ident,
+   size_t buffer_count, unsigned int samples)
+

Source Code

+

Loads an audio file from ALLEGRO_FILE stream as it is needed.

+

Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain buffer_count buffers with samples samples.

+

The file type is determined by the passed ‘ident’ parameter, which is a file name extension including the leading dot.

+

The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See ALLEGRO_AUDIO_STREAM for more details.

+

Returns the stream on success, NULL on failure. On success the file should be considered owned by the audio stream, and will be closed when the audio stream is destroyed. On failure the file will be closed.

+
+

Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

+
+

See also: al_load_audio_stream, al_register_audio_stream_loader_f, al_init_acodec_addon

+

al_save_sample

+
bool al_save_sample(const char *filename, ALLEGRO_SAMPLE *spl)
+

Source Code

+

Writes a sample into a file. Currently, wav is the only supported format, and the extension must be “.wav”.

+

Returns true on success, false on error.

+
+

Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

+
+

See also: al_save_sample_f, al_register_sample_saver, al_init_acodec_addon

+

al_save_sample_f

+
bool al_save_sample_f(ALLEGRO_FILE *fp, const char *ident, ALLEGRO_SAMPLE *spl)
+

Source Code

+

Writes a sample into a ALLEGRO_FILE filestream. Currently, wav is the only supported format, and the extension must be “.wav”.

+

Returns true on success, false on error. The file remains open afterwards.

+
+

Note: the allegro_audio library does not support any audio file formats by default. You must use the allegro_acodec addon, or register your own format handler.

+
+

See also: al_save_sample, al_register_sample_saver_f, al_init_acodec_addon

+

Audio recording

+

Allegro’s audio recording routines give you real-time access to raw, uncompressed audio input streams. Since Allegro hides all of the platform specific implementation details with its own buffering, it will add a small amount of latency. However, for most applications that small overhead will not adversely affect performance.

+

Recording is supported by the ALSA, AudioQueue, DirectSound8, and PulseAudio drivers. Enumerating or choosing other recording devices is not yet supported.

+

ALLEGRO_AUDIO_RECORDER

+
typedef struct ALLEGRO_AUDIO_RECORDER ALLEGRO_AUDIO_RECORDER;
+

Source Code

+

An opaque datatype that represents a recording device.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

Examples:

+ +

ALLEGRO_AUDIO_RECORDER_EVENT

+
typedef struct ALLEGRO_AUDIO_RECORDER_EVENT ALLEGRO_AUDIO_RECORDER_EVENT;
+

Source Code

+

Structure that holds the audio recorder event data. Every event type will contain:

+
    +
  • .source: pointer to the audio recorder
  • +
+

The following will be available depending on the event type:

+
    +
  • .buffer: pointer to buffer containing the audio samples
  • +
  • .samples: number of samples (not bytes) that are available
  • +
+

Since 5.1.1

+

See also: al_get_audio_recorder_event

+
+

Unstable API: The API may need a slight redesign.

+
+

Examples:

+ +

al_create_audio_recorder

+
ALLEGRO_AUDIO_RECORDER *al_create_audio_recorder(size_t fragment_count,
+   unsigned int samples, unsigned int frequency,
+   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)
+

Source Code

+

Creates an audio recorder using the system’s default recording device. (So if the returned device does not work, try updating the system’s default recording device.)

+

Allegro will internally buffer several seconds of captured audio with minimal latency. (XXX: These settings need to be exposed via config or API calls.) Audio will be copied out of that private buffer into a fragment buffer of the size specified by the samples parameter. Whenever a new fragment is ready an event will be generated.

+

The total size of the fragment buffer is fragment_count * samples * bytes_per_sample. It is treated as a circular, never ending buffer. If you do not process the information fast enough, it will be overrun. Because of that, even if you only ever need to process one small fragment at a time, you should still use a large enough value for fragment_count to hold a few seconds of audio.

+

frequency is the number of samples per second to record. Common values are:

+
    +
  • 8000 - telephone quality speech
  • +
  • 11025
  • +
  • 22050
  • +
  • 44100 - CD quality music (if 16-bit, stereo)
  • +
+

For maximum compatibility, use a depth of ALLEGRO_AUDIO_DEPTH_UINT8 or ALLEGRO_AUDIO_DEPTH_INT16, and a single (mono) channel.

+

The recorder will not record until you start it with al_start_audio_recorder.

+

On failure, returns NULL.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

Examples:

+ +

al_start_audio_recorder

+
bool al_start_audio_recorder(ALLEGRO_AUDIO_RECORDER *r)
+

Source Code

+

Begin recording into the fragment buffer. Once a complete fragment has been captured (as specified in al_create_audio_recorder), an ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT event will be triggered.

+

Returns true if it was able to begin recording.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

Examples:

+ +

al_stop_audio_recorder

+
void al_stop_audio_recorder(ALLEGRO_AUDIO_RECORDER *r)
+

Source Code

+

Stop capturing audio data. Note that the audio recorder is still active and consuming resources, so if you are finished recording you should destroy it with al_destroy_audio_recorder.

+

You may still receive a few events after you call this function as the device flushes the buffer.

+

If you restart the recorder, it will begin recording at the beginning of the next fragment buffer.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

al_is_audio_recorder_recording

+
bool al_is_audio_recorder_recording(ALLEGRO_AUDIO_RECORDER *r)
+

Source Code

+

Returns true if the audio recorder is currently capturing data and generating events.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

al_get_audio_recorder_event

+
ALLEGRO_AUDIO_RECORDER_EVENT *al_get_audio_recorder_event(ALLEGRO_EVENT *event)
+

Source Code

+

Returns the event as an ALLEGRO_AUDIO_RECORDER_EVENT.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

Examples:

+ +

al_get_audio_recorder_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_audio_recorder_event_source(ALLEGRO_AUDIO_RECORDER *r)
+

Source Code

+

Returns the event source for the recorder that generates the various recording events.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

Examples:

+ +

al_destroy_audio_recorder

+
void al_destroy_audio_recorder(ALLEGRO_AUDIO_RECORDER *r)
+

Source Code

+

Destroys the audio recorder and frees all resources associated with it. It is safe to destroy a recorder that is recording.

+

You may receive events after the recorder has been destroyed. They must be ignored, as the fragment buffer will no longer be valid.

+

Since: 5.1.1

+
+

Unstable API: The API may need a slight redesign.

+
+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/autosuggest.js b/allegro/docs/html/refman/autosuggest.js new file mode 100644 index 00000000..97f84491 --- /dev/null +++ b/allegro/docs/html/refman/autosuggest.js @@ -0,0 +1,1623 @@ +/* Auto-suggest control, modified for Allegro's purposes. + * + * The original copyright notice follows: + * + * Auto-suggest control, version 2.4, October 10th 2009. + * + * (c) 2007-2009 Dmitriy Khudorozhkov (dmitrykhudorozhkov@yahoo.com) + * + * Latest version download and documentation: + * http://www.codeproject.com/KB/scripting/AutoSuggestControl.aspx + * + * Based on "Auto-complete Control" by zichun: + * http://www.codeproject.com/KB/scripting/jsactb.aspx + * + * This software is provided "as-is", without any express or implied warranty. + * In no event will the author be held liable for any damages arising from the + * use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +var autosuggest_url = ""; // Global link to the server-side script, that gives you the suggestion list. + // Used for controls that do not define their own server script urls. + +function autosuggest(id, array, url, onSelect) +{ + var field = document.getElementById(id); + var exists = field.autosuggest; + + if(exists) return exists; + + // "Public" variables: + + this.time_out = 0; // autocomplete timeout, in milliseconds (0: autocomplete never times out) + this.response_time = 250; // time, in milliseconds, between the last char typed and the actual query + this.entry_limit = 10; // number of entries autocomplete will show at a time + + this.limit_start = false; // should the auto complete be limited to the beginning of keyword? + this.match_first = true; // if previous is false, should the exact matches be displayed first? + this.restrict_typing = false; // restrict to existing members of array + this.full_refresh = false; // should the script re-send the AJAX request after each typed character? + + this.use_iframe = true; // should the control use an IFrame element to fix suggestion list positioning (MS IE only)? + this.use_scroll = true; // should the control use a scroll bar (true) or a up/down arrow-buttons (false)? + this.use_mouse = true; // enable mouse support + this.no_default = false; // should the control omit selecting the 1st item in a suggestion list? + this.start_check = 0; // show widget only after this number of characters is typed in (effective if >1) + + this.text_delimiter = [";", ","]; // delimiter for multiple autocomplete entries. Set it to empty array ( [] ) for single autocomplete. + this.ajax_delimiter = "|"; // character that delimits entries in the string returned by AJAX call + this.item_delimiter = ","; // character that delimits key and value for the suggestion item in the string returned by AJAX call + + this.selectedIndex = -1; // index (zero-based) of the entry last selected + + this.min_results = 5; // minimum number of results to return + + // "Private" variables: + + this.suggest_url = url || (array ? "" : autosuggest_url); // URL the server-side script that gives you the suggestion list + this.msie = (document.all && !window.opera); + + this.displayed = false; + + this.delim_words = []; + this.current_word = 0; + this.delim_char = []; + + this.current = 0; + this.total = 0; + this.range_up = 0; + this.range_down = 0; + + this.previous = 0; + this.timer = 0; + this.rebuild = false; + this.evsetup = false; + + this.bool = []; + this.rows = []; + + this.onSelect = onSelect || null; + + this.cur_x = 0; + this.cur_y = 0; + this.cur_w = 0; + this.cur_h = 0; + + this.mouse_x = 0; + this.mouse_y = 0; + + this.mouse_on_list = 0; + this.caret_moved = false; + + this.field_id = id; + this.field = field; + this.lastterm = field.value; + + this.keywords = [], this.keywords_init = []; + this.values = [], this.values_init = []; + + return this.construct(array || []); +}; + +autosuggest.prototype = { + + construct: function(array) + { + function callLater(func, obj, param1, param2) { return function() { func.call(obj, param1 || null, param2 || null) }; } + + this.field.autosuggest = this; + + // Initialize the control from JS array, if any: + + this.bindArray(array); + + // Create event handlers: + + this.funcClick = this.mouseClick; + this.funcCheck = this.checkKey; + this.funcPress = this.keyPress; + + this.funcHighlight = this.highlightTable; + + this.funcClear = callLater(this.clearEvents, this); + + this.funcUp = callLater(this.scroll, this, true, 1); + this.funcDown = callLater(this.scroll, this, false, 1); + + this.funcFocus = callLater(this.focusTable, this); + this.funcUnfocus = callLater(this.unfocusTable, this); + + this.addEvent(this.field, "focus", callLater(this.setupEvents, this)); + this.addEvent(window, "resize", callLater(this.reposition, this)); + + var obj = this; + this.addEvent(document, "keypress", function(event) { obj.funcShortcut(obj, event); }); + this.addEvent(document, "keydown", function(event) { obj.funcShortcut(obj, event); }); + + return this; + }, + + funcShortcut: function(obj, event) + { + event = event || window.event; + + var s; + if("key" in event && typeof event.key != "undefined") + { + s = event.key; + } + else + { + var c = event.charCode || event.keyCode; + if(c == 27) + { + s = "Escape"; + } + else + { + s = String.fromCharCode(c); + } + } + switch(s) + { + case "Escape": + obj.field.blur(); + break; + case "s": + case "S": + if(!this.evsetup) + { + event.preventDefault(); + obj.field.focus(); + break; + } + } + }, + + bindArray: function(array) + { + if(!array || !array.length) return; + + this.suggest_url = ""; + + this.keywords = [], this.keywords_init = []; + this.values = [], this.values_init = []; + + for(var i = 0, cl = array.length; i < cl; i++) + { + var item = array[i]; + + if(item.constructor == Array) + { + this.keywords[i] = this.keywords_init[i] = item[0]; + this.values[i] = this.values_init[i] = item[1]; + } + else + { + this.keywords[i] = this.keywords_init[i] = item; + this.values[i] = this.values_init[i] = ""; + } + } + }, + + bindURL: function(url) + { + if(!url) + url = autosuggest_url; + + this.suggest_url = url; + }, + + setupEvents: function() + { + if(!this.evsetup) + { + this.evsetup = true; + + this.addEvent(document, "keydown", this.funcCheck); + this.addEvent(this.field, "blur", this.funcClear); + this.addEvent(document, "keypress", this.funcPress); + } + }, + + clearEvents: function() + { + // Removes an event handler: + function removeEvent(obj, event_name, func_ref) + { + if(obj.removeEventListener && !window.opera) + { + obj.removeEventListener(event_name, func_ref, true); + } + else if(obj.detachEvent) + { + obj.detachEvent("on" + event_name, func_ref); + } + else + { + obj["on" + event_name] = null; + } + } + + var event = window.event; + + if(event && this.cur_h) + { + var elem = event.srcElement || event.target; + + var x = this.mouse_x + (document.documentElement.scrollLeft || document.body.scrollLeft || 0); + var y = this.mouse_y + (document.documentElement.scrollTop || document.body.scrollTop || 0); + + if((elem.id == this.field_id) && (x > this.cur_x && x < (this.cur_x + this.cur_w)) && (y > this.cur_y && y < (this.cur_y + this.cur_h))) + { + this.field.focus(); + return; + } + } + + removeEvent(document, "keydown", this.funcCheck); + removeEvent(this.field, "blur", this.funcClear); + removeEvent(document, "keypress", this.funcPress); + + this.hide(); + this.evsetup = false; + }, + + parse: function(n, plen, re) + { + if(!n || !n.length) return ""; + if(!plen) return n; + + var tobuild = [], c = 0, p = n.search(re); + + // No match found because we're serving approximate results + if(p < 0) + { + tobuild[c++] = n; + } + else + { + tobuild[c++] = n.substr(0, p); + tobuild[c++] = ""; + tobuild[c++] = n.substring(p, plen + p); + tobuild[c++] = ""; + tobuild[c++] = n.substring(plen + p, n.length); + } + + return tobuild.join(""); + }, + + build: function() + { + if(this.total == 0) + { + this.displayed = false; + return; + } + + this.rows = []; + this.current = this.no_default ? -1 : 0; + + var that = this; + + this.addEvent(document, "mousemove", function(event) + { + event = event || window.event; + + that.mouse_x = event.x; + that.mouse_y = event.y; + }); + + var body = document.getElementById("suggest_table_" + this.field_id); + if(body) + { + this.displayed = false; + document.body.removeChild(body); + + var helper = document.getElementById("suggest_helper_" + this.field_id); + if(helper) + document.body.removeChild(helper); + } + + var bb = document.createElement("div"); + bb.id = "suggest_table_" + this.field_id; + bb.className = "autosuggest-body"; + + this.cur_y = this.curPos(this.field, "Top") + this.field.offsetHeight; + bb.style.top = this.cur_y + "px"; + + this.cur_x = this.curPos(this.field, "Left"); + bb.style.left = this.cur_x + "px"; + + this.cur_w = this.field.offsetWidth - (this.msie ? 2 : 6); + bb.style.width = this.cur_w + "px"; + + this.cur_h = 1; + bb.style.height = "1px"; + + var cc = null; + if(this.msie && this.use_iframe) + { + var cc = document.createElement("iframe"); + cc.id = "suggest_helper_" + this.field_id; + + cc.src = "javascript:\"\";"; + cc.scrolling = "no"; + cc.frameBorder = "no"; + } + + var that = this; + var showFull = (this.total > this.entry_limit); + + if(cc) + { + document.body.appendChild(cc); + + cc.style.top = this.cur_y + "px"; + cc.style.left = this.cur_x + "px"; + + cc.style.width = bb.offsetWidth + 2; + } + + document.body.appendChild(bb); + + var first = true, dispCount = showFull ? this.entry_limit : this.total; + var str = [], cn = 0; + + // cellspacing and cellpadding were not moved to css - IE doesn't understand border-spacing. + str[cn++] = ""; + + bb.innerHTML = str.join(""); + var table = bb.firstChild; + + if(this.use_mouse) + { + table.onmouseout = this.funcUnfocus; + table.onmouseover = this.funcFocus; + } + + var real_height = 0, real_width = 0; + + function createArrowRow(dir) + { + var row = table.insertRow(-1); + row.className = dir ? "up" : "down"; + + var cell = row.insertCell(0); + real_height += cell.offsetHeight + 1; + + return cell; + } + + if(!this.use_scroll && showFull) + createArrowRow(true).parentNode.className = "up-disabled"; + + var kl = this.keywords.length, counter = 0, j = 0; + + // For "parse" call: + var t, plen; + if(this.text_delimiter.length > 0) + { + var word = this.delim_words[this.current_word]; + + t = this.trim(this.addSlashes(word)); + plen = this.trim(word).length; + } + else + { + var word = this.field.value; + + t = this.addSlashes(word); + plen = word.length; + } + + var re = new RegExp((this.limit_start ? "^" : "") + t, "i"); + + function addSuggestion(index, _first) + { + var row = that.rows[j] = table.insertRow(-1); + row.className = (_first || (that.previous == index)) ? "selected" : ""; + + var cell = row.insertCell(0); + cell.innerHTML = that.parse(that.keywords[index], plen, re); + cell.setAttribute("pos", j++); + cell.autosuggest = that; + + if(that.use_mouse) + { + that.addEvent(cell, "click", that.funcClick); + cell.onmouseover = that.funcHighlight; + } + + return [row.offsetWidth, row.offsetHeight]; + } + + for(var i = 0; i < kl; i++) + { + if(this.bool[i]) + { + var dim = addSuggestion(i, (first && !this.no_default && !this.rebuild)); + first = false; + + if(counter <= this.entry_limit) + real_height += dim[1] + 1; + + if(real_width < dim[0]) + real_width = dim[0]; + + if(++counter == this.entry_limit) + { + ++i; + break; + } + } + } + + var last = i; + + if(showFull) + { + if(!this.use_scroll) + { + var cell = createArrowRow(false); + + if(this.use_mouse) + this.addEvent(cell, "click", this.funcDown); + } + else + { + bb.style.height = real_height + "px"; + bb.style.overflow = "auto"; + bb.style.overflowX = "hidden"; + } + } + + this.cur_h = real_height + 1; + bb.style.height = this.cur_h + "px"; + + this.cur_w = ((real_width > bb.offsetWidth) ? real_width : bb.offsetWidth) + (this.msie ? -2 : 2) + 100; + bb.style.width = this.cur_w + "px"; + + if(cc) + { + cc.style.height = this.cur_h + "px"; + cc.style.width = this.cur_w + "px"; + } + + this.range_up = 0; + this.range_down = j - 1; + this.displayed = true; + + if(this.use_scroll) + { + setTimeout(function() + { + counter = 0; + + for(var i = last; i < kl; i++) + { + if(!that.displayed) return; + + if(that.bool[i]) + { + addSuggestion(i); + + if(++counter == that.entry_limit) + { + ++i; + break; + } + } + } + + last = i; + + if(j < that.total) setTimeout(arguments.callee, 25); + }, + 25); + } + }, + + remake: function() + { + this.rows = []; + + var a = document.getElementById("suggest_table2_" + this.field_id); + var k = 0, first = true; + + function adjustArrow(obj, which, cond, handler) + { + var r = a.rows[k++]; + r.className = which ? (cond ? "up" : "up-disabled") : (cond ? "down" : "down-disabled"); + + var c = r.firstChild; + + if(cond && handler && obj.use_mouse) + obj.addEvent(c, "click", handler); + } + + if(this.total > this.entry_limit) + { + var b = (this.range_up > 0); + adjustArrow(this, true, b, this.funcUp); + } + + // For "parse" call: + var t, plen; + if(this.text_delimiter.length > 0) + { + var word = this.delim_words[this.current_word]; + + t = this.trim(this.addSlashes(word)); + plen = this.trim(word).length; + } + else + { + var word = this.field.value; + + t = this.addSlashes(word); + plen = word.length; + } + + var re = new RegExp((this.limit_start ? "^" : "") + t, "i"); + var kl = this.keywords.length, j = 0; + + for(var i = 0; i < kl; i++) + { + if(this.bool[i]) + { + if((j >= this.range_up) && (j <= this.range_down)) + { + var r = this.rows[j] = a.rows[k++]; + r.className = ""; + + var c = r.firstChild; + c.innerHTML = this.parse(this.keywords[i], plen, re); + c.setAttribute("pos", j); + } + + if(++j > this.range_down) break; + } + } + + if(kl > this.entry_limit) + { + var b = (j < this.total); + adjustArrow(this, false, b, this.funcDown); + } + + if(this.msie) + { + var helper = document.getElementById("suggest_helper_" + this.field_id); + if(helper) helper.style.width = a.parentNode.offsetWidth + 2; + } + }, + + reposition: function() + { + if(this.displayed) + { + this.cur_y = this.curPos(this.field, "Top") + this.field.offsetHeight; + this.cur_x = this.curPos(this.field, "Left"); + + var control = document.getElementById("suggest_table_" + this.field_id); + control.style.top = this.cur_y + "px"; + control.style.left = this.cur_x + "px"; + } + }, + + startTimer: function(on_list) + { + if(this.time_out > 0) + this.timer = setTimeout(function() { this.mouse_on_list = on_list; this.hide(); }, this.time_out); + }, + + stopTimer: function() + { + if(this.timer) + { + clearTimeout(this.timer); + this.timer = 0; + } + }, + + getRow: function(index) + { + if(typeof(index) == "undefined") index = this.current; + + return (this.rows[index] || null); + }, + + fixArrows: function(base) + { + if(this.total <= this.entry_limit) return; + + var table = base.firstChild, at_start = (this.current == 0), at_end = (this.current == (this.total - 1)); + + var row = table.rows[0]; + row.className = at_start ? "up-disabled" : "up"; + + row = table.rows[this.entry_limit + 1]; + row.className = at_end ? "down-disabled" : "down"; + }, + + scroll: function(direction, times) + { + if(!this.displayed) return; + + this.field.focus(); + if(this.current == (direction ? 0 : (this.total - 1))) return; + + if(!direction && (this.current < 0)) + { + this.current = -1; + } + else + { + var t = this.getRow(); + + if(t && t.style) + t.className = ""; + } + + this.current += times * (direction ? -1 : 1); + if(direction) + { + if(this.current < 0) + this.current = 0; + } + else + { + if(this.current >= this.total) + this.current = this.total - 1; + + if(this.use_scroll && (this.current >= this.rows.length)) + this.current = this.rows.length - 1; + } + + var t = this.getRow(), base = document.getElementById("suggest_table_" + this.field_id); + + if(this.use_scroll) + { + if(direction) + { + if(t.offsetTop < base.scrollTop) + base.scrollTop = t.offsetTop; + } + else + { + if((t.offsetTop + t.offsetHeight) > (base.scrollTop + base.offsetHeight)) + { + var ndx = this.current - this.entry_limit + 1; + if(ndx > 0) + base.scrollTop = this.getRow(ndx).offsetTop; + } + } + } + else + { + if(direction) + { + if(this.current < this.range_up) + { + this.range_up -= times; + if(this.range_up < 0) this.range_up = 0; + + this.range_down = this.range_up + this.entry_limit - 1; + + this.remake(); + } + else this.fixArrows(base); + } + else + { + if(this.current > this.range_down) + { + this.range_down += times; + if(this.range_down > (this.total - 1)) this.range_down = this.total - 1; + + this.range_up = this.range_down - this.entry_limit + 1; + + this.remake(); + } + else this.fixArrows(base); + } + + t = this.getRow(); + } + + if(t && t.style) + t.className = "selected"; + + this.stopTimer(); + this.startTimer(1); + + this.field.focus(); + }, + + mouseClick: function(event) + { + event = event || window.event; + var elem = event.srcElement || event.target; + + if(!elem.id) elem = elem.parentNode; + + var obj = elem.autosuggest; + + if(!obj) + { + var tag = elem.tagName.toLowerCase(); + elem = (tag == "tr") ? elem.firstChild : elem.parentNode; + + obj = elem.autosuggest; + } + + if(!obj || !obj.displayed) return; + + obj.mouse_on_list = 0; + obj.current = parseInt(elem.getAttribute("pos"), 10); + obj.choose(); + }, + + focusTable: function() + { + this.mouse_on_list = 1; + }, + + unfocusTable: function() + { + this.mouse_on_list = 0; + + this.stopTimer(); + this.startTimer(0) + }, + + highlightTable: function(event) + { + event = event || window.event; + var elem = event.srcElement || event.target; + + var obj = elem.autosuggest; + if(!obj) return; + + obj.mouse_on_list = 1; + + var row = obj.getRow(); + if(row && row.style) + row.className = ""; + + obj.current = parseInt(elem.getAttribute("pos"), 10); + + row = obj.getRow(); + if(row && row.style) + row.className = "selected"; + + obj.stopTimer(); + obj.startTimer(0); + }, + + choose: function() + { + if(!this.displayed) return; + if(this.current < 0) return; + + this.displayed = false; + + var kl = this.keywords.length; + + for(var i = 0, c = 0; i < kl; i++) + if(this.bool[i] && (c++ == this.current)) + break; + + this.selectedIndex = i; + this.insertWord(this.keywords[i]); + + if(this.onSelect) + this.onSelect(i, this); + }, + + insertWord: function(a) + { + // Sets the caret position to l in the object + function setCaretPos(obj, l) + { + obj.focus(); + + if(obj.setSelectionRange) + { + obj.setSelectionRange(l, l); + } + else if(obj.createTextRange) + { + var m = obj.createTextRange(); + m.moveStart("character", l); + m.collapse(); + m.select(); + } + } + + if(this.text_delimiter.length > 0) + { + var str = "", word = this.delim_words[this.current_word], wl = word.length, l = 0; + + for(var i = 0; i < this.delim_words.length; i++) + { + if(this.current_word == i) + { + var prespace = "", postspace = "", gotbreak = false; + + for(var j = 0; j < wl; ++j) + { + if(word.charAt(j) != " ") + { + gotbreak = true; + break; + } + + prespace += " "; + } + + for(j = wl - 1; j >= 0; --j) + { + if(word.charAt(j) != " ") + break; + + postspace += " "; + } + + str += prespace; + str += a; + l = str.length; + + if(gotbreak) str += postspace; + } + else + { + str += this.delim_words[i]; + } + + if(i != this.delim_words.length - 1) + str += this.delim_char[i]; + } + + this.field.value = str; + setCaretPos(this.field, l); + } + else + { + this.field.value = a; + } + + this.mouse_on_list = 0; + this.hide(); + }, + + hide: function() + { + if(this.mouse_on_list == 0) + { + this.displayed = false; + + var base = document.getElementById("suggest_table_" + this.field_id); + if(base) + { + var helper = document.getElementById("suggest_helper_" + this.field_id); + if(helper) + document.body.removeChild(helper); + + document.body.removeChild(base); + } + + this.stopTimer(); + + this.cur_x = 0; + this.cur_y = 0; + this.cur_w = 0; + this.cur_h = 0; + + this.rows = []; + } + }, + + keyPress: function(event) + { + // On firefox there is no way to distingish pressing shift-8 (asterix) + // from pressing 8 during the keyDown event, so we do restrict_typing + // whilest handling the keyPress event + + event = event || window.event; + + var code = window.event ? event.keyCode : event.charCode; + var obj = event.srcElement || event.target; + + obj = obj.autosuggest; + + if(obj.restrict_typing && !obj.suggest_url.length && (code >= 32)) + { + var caret_pos = obj.getCaretEnd(obj.field); + var new_term = obj.field.value.substr(0, caret_pos).toLowerCase(); + var isDelimiter = false; + + if(obj.text_delimiter.length > 0) + { + // check whether the pressed key is a delimiter key + var delim_split = ""; + for(var j = 0; j < obj.text_delimiter.length; j++) + { + delim_split += obj.text_delimiter[j]; + + if(obj.text_delimiter[j] == String.fromCharCode(code)) + isDelimiter = true; + } + + // only consider part of term after last delimiter + delim_split = obj.addSlashes(delim_split); + + var lastterm_rx = new RegExp(".*([" + delim_split + "])"); + new_term = new_term.replace(lastterm_rx, ''); + } + + var keyw_len = obj.keywords.length; + var i = 0; + + if(isDelimiter) + { + // pressed key is a delimiter: allow if current term is complete + for(i = 0; i < keyw_len; i++) + if(obj.keywords[i].toLowerCase() == new_term) + break; + } + else + { + new_term += String.fromCharCode(code).toLowerCase(); + for(i = 0; i < keyw_len; i++) + if(obj.keywords[i].toLowerCase().indexOf(new_term) != -1) + break; + } + + if(i == keyw_len) + { + obj.stopEvent(event); + return false; + } + } + + if(obj.caret_moved) obj.stopEvent(event); + return !obj.caret_moved; + }, + + checkKey: function(event) + { + event = event || window.event; + + var code = event.keyCode; + var obj = event.srcElement || event.target; + + obj = obj.autosuggest; + obj.caret_moved = 0; + + var term = ""; + + obj.stopTimer(); + + switch(code) + { + // Up arrow: + case 38: + if(obj.current <= 0) + { + obj.stopEvent(event); + obj.hide(); + } + else + { + obj.scroll(true, 1); + obj.caret_moved = 1; + obj.stopEvent(event); + } + return false; + + // Down arrow: + case 40: + if(!obj.displayed) + { + obj.timer = setTimeout(function() + { + obj.preSuggest(-1); + }, + 25); + } + else + { + obj.scroll(false, 1); + obj.caret_moved = 1; + } + return false; + + // Page up: + case 33: + if(obj.current == 0) + { + obj.caret_moved = 0; + return false; + } + + obj.scroll(true, (obj.use_scroll || (obj.getRow() == obj.rows[obj.range_up])) ? obj.entry_limit : (obj.current - obj.range_up)); + obj.caret_moved = 1; + break; + + // Page down: + case 34: + if(obj.current == (obj.total - 1)) + { + obj.caret_moved = 0; + return false; + } + + obj.scroll(false, (obj.use_scroll || (obj.getRow() == obj.rows[obj.range_down])) ? obj.entry_limit : (obj.range_down - obj.current)); + obj.caret_moved = 1; + break; + + // Home + case 36: + if(obj.current == 0) + { + obj.caret_moved = 0; + return false; + } + + obj.scroll(true, obj.total); + obj.caret_moved = 1; + break; + + // End + case 35: + if(obj.current == (obj.total - 1)) + { + obj.caret_moved = 0; + return false; + } + + obj.scroll(false, obj.total); + obj.caret_moved = 1; + break; + + // Esc: + case 27: + term = obj.field.value; + + obj.mouse_on_list = 0; + obj.hide(); + break; + + // Enter: + case 13: + if(obj.displayed) + { + obj.caret_moved = 1; + obj.choose(); + return false; + } + break; + + // Tab: + case 9: + if((obj.displayed && (obj.current >= 0)) || obj.timer) + { + obj.caret_moved = 1; + obj.choose(); + + setTimeout(function() { obj.field.focus(); }, 25); + return false; + } + break; + + case 16: //shift + break; + + default: + obj.caret_moved = 0; + obj.timer = setTimeout(function() + { + obj.preSuggest(code); + }, + (obj.response_time < 10 ? 10 : obj.response_time)); + } + + if(term.length) setTimeout(function() { obj.field.value = term; }, 25); + return true; + }, + + preSuggest: function(kc) + { + if(!this.timer) + return; + + this.stopTimer(); + + if(this.displayed && (this.lastterm == this.field.value)) return; + this.lastterm = this.field.value; + + if(kc == 38 || kc == 40 || kc == 13) return; + + var c = 0; + if(this.displayed && (this.current >= 0)) + { + for(var i = 0; i < this.keywords.length; i++) + { + if(this.bool[i]) ++c; + + if(c == this.current) + { + this.previous = i; + break; + } + } + } + else + { + this.previous = -1; + } + + if(!this.field.value.length && (kc != -1)) + { + this.mouse_on_list = 0; + this.hide(); + } + + var ot, t; + + if(this.text_delimiter.length > 0) + { + var caret_pos = this.getCaretEnd(this.field); + + var delim_split = ""; + for(var i = 0; i < this.text_delimiter.length; i++) + delim_split += this.text_delimiter[i]; + + delim_split = this.addSlashes(delim_split); + var delim_split_rx = new RegExp("([" + delim_split + "])"); + c = 0; + this.delim_words = []; + this.delim_words[0] = ""; + + for(var i = 0, j = this.field.value.length; i < this.field.value.length; i++, j--) + { + if(this.field.value.substr(i, j).search(delim_split_rx) == 0) + { + var ma = this.field.value.substr(i, j).match(delim_split_rx); + this.delim_char[c++] = ma[1]; + this.delim_words[c] = ""; + } + else + { + this.delim_words[c] += this.field.value.charAt(i); + } + } + + var l = 0; + this.current_word = -1; + + for(i = 0; i < this.delim_words.length; i++) + { + if((caret_pos >= l) && (caret_pos <= (l + this.delim_words[i].length))) + this.current_word = i; + + l += this.delim_words[i].length + 1; + } + + ot = this.trim(this.delim_words[this.current_word]); + t = this.trim(this.addSlashes(this.delim_words[this.current_word])); + } + else + { + ot = this.field.value; + t = this.addSlashes(ot); + } + + if(ot.length == 0 && (kc != -1)) + { + this.mouse_on_list = 0; + this.hide(); + } + else if((ot.length == 1) || this.full_refresh || + ((ot.length > 1) && !this.keywords.length) || + ((ot.length > 1) && (this.keywords[0].charAt(0).toLowerCase() != ot.charAt(0).toLowerCase()))) + { + var ot_ = ((ot.length > 1) && !this.full_refresh) ? ot.charAt(0) : ot; + + if(this.suggest_url.length) + { + + // create xmlhttprequest object: + var http = null; + if(typeof(XMLHttpRequest) != "undefined") + { + try + { + http = new XMLHttpRequest(); + } + catch (e) { http = null; } + } + else + { + try + { + http = new ActiveXObject("Msxml2.XMLHTTP") ; + } + catch (e) + { + try + { + http = new ActiveXObject("Microsoft.XMLHTTP") ; + } + catch (e) { http = null; } + } + } + + if(http) + { + // Uncomment for local debugging in Mozilla/Firefox: + // try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } catch (e) { } + + if(http.overrideMimeType) + http.overrideMimeType("text/xml"); + + http.open("GET", this.suggest_url + ot_, true); + + var that = this; + http.onreadystatechange = function(n) + { + if(http.readyState == 4) + { + if((http.status == 200) || (http.status == 0)) + { + var text = http.responseText; + + var index1 = text.indexOf(""); + var index2 = (index1 == -1) ? text.length : text.indexOf(" lcs) + { + lcs = table[i+1][j+1]; + } + } + else + { + table[i+1][j+1] = 0; + } + } + } + return lcs; + }, + + // A function to compute the Levenshtein distance between two strings + // Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported + // Full License can be found at http://creativecommons.org/licenses/by-sa/3.0/legalcode + // This code is an unmodified (aside from style) version of the code written by Marco de Wit + // and was found at http://stackoverflow.com/a/18514751/745719 + levenshtein: (function() + { + var row2 = []; + return function(s1, s2) + { + if(s1 === s2) + { + return 0; + } + else + { + var s1_len = s1.length, s2_len = s2.length; + if(s1_len && s2_len) + { + var i1 = 0, i2 = 0, a, b, c, c2, row = row2; + while(i1 < s1_len) + row[i1] = ++i1; + while(i2 < s2_len) + { + c2 = s2.charCodeAt(i2); + a = i2; + ++i2; + b = i2; + for(i1 = 0; i1 < s1_len; ++i1) + { + c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); + a = row[i1]; + b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); + row[i1] = b; + } + } + return b; + } + else + { + return s1_len + s2_len; + } + } + }; + })(), + + // Setup an event handler for the given event and DOM element + // event_name refers to the event trigger, without the "on", like click or mouseover + // func_name refers to the function callback that is invoked when event is triggered + addEvent: function(obj, event_name, func_ref) + { + if(obj.addEventListener && !window.opera) + { + obj.addEventListener(event_name, func_ref, true); + } + else if(obj.attachEvent) + { + obj.attachEvent("on" + event_name, func_ref) + } + else + { + obj["on" + event_name] = func_ref; + } + }, + + // Stop an event from bubbling up the event DOM + stopEvent: function(event) + { + event = event || window.event; + + if(event) + { + if(event.stopPropagation) event.stopPropagation(); + if(event.preventDefault) event.preventDefault(); + + if(typeof(event.cancelBubble) != "undefined") + { + event.cancelBubble = true; + event.returnValue = false; + } + } + + return false; + }, + + // Get the end position of the caret in the object. Note that the obj needs to be in focus first. + getCaretEnd: function(obj) + { + if(typeof(obj.selectionEnd) != "undefined") + { + return obj.selectionEnd; + } + else if(document.selection && document.selection.createRange) + { + var M = document.selection.createRange(), Lp; + + try + { + Lp = M.duplicate(); + Lp.moveToElementText(obj); + } + catch(e) + { + Lp = obj.createTextRange(); + } + + Lp.setEndPoint("EndToEnd", M); + var rb = Lp.text.length; + + if(rb > obj.value.length) + return -1; + + return rb; + } + + return -1; + }, + + // Get offset position from the top/left of the screen: + curPos: function(obj, what) + { + var coord = 0; + while(obj) + { + coord += obj["offset" + what]; + obj = obj.offsetParent; + } + + return coord; + }, + + // String functions: + + addSlashes: function(str) { return str.replace(/(["\\\.\|\[\]\^\*\+\?\$\(\)])/g, "\\$1"); }, + + trim: function(str) { return str.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"); } +}; diff --git a/allegro/docs/html/refman/color.html b/allegro/docs/html/refman/color.html new file mode 100644 index 00000000..1d5f67e4 --- /dev/null +++ b/allegro/docs/html/refman/color.html @@ -0,0 +1,588 @@ + + + + + + + Color addon + + + + + + + + +
+ + +
+

Color addon

+
+ +

These functions are declared in the following header file. Link with allegro_color.

+
 #include <allegro5/allegro_color.h>
+

When converting between certain color spaces, RGB colors are implicitly assumed to mean sRGB.

+

sRGB is a standard which maps RGB colors to absolute colors. sRGB is very close to RGB values on a monitor which has a gamma value of 2.2. For example when the red component of a color is 0.5, the monitor will use a brightness of pow(0.5, 2.2) or about 22% - and not 50%. The reason is that human eyes can distinguish better between dark colors than between bright colors, and so if a pixel of the monitor is lit up to 22% of its maximum power it already will appear at half brightness to a human eye.

+

sRGB improves upon simple gamma correction by taking differences between the three color channels into account as well. In general, most monitors nowadays try to be close to the sRGB specification. And so if in an Allegro game you display something with color

+

al_map_rgb_f(0.5, 0.5, 0,5)

+

then it will appear at about half brightness (even though the actual brightness output of the monitor will be less than half).

+

al_color_cmyk

+
ALLEGRO_COLOR al_color_cmyk(float c, float m, float y, float k)
+

Source Code

+

Return an ALLEGRO_COLOR structure from CMYK values (cyan, magenta, yellow, black).

+

See also: al_color_cmyk_to_rgb, al_color_rgb_to_cmyk

+

Examples:

+ +

al_color_cmyk_to_rgb

+
void al_color_cmyk_to_rgb(float cyan, float magenta, float yellow,
+    float key, float *red, float *green, float *blue)
+

Source Code

+

Convert CMYK values to RGB values.

+

See also: al_color_cmyk, al_color_rgb_to_cmyk

+

Examples:

+ +

al_color_hsl

+
ALLEGRO_COLOR al_color_hsl(float h, float s, float l)
+

Source Code

+

Return an ALLEGRO_COLOR structure from HSL (hue, saturation, lightness) values.

+

Parameters:

+
    +
  • hue - Color hue angle in the range 0..360
  • +
  • saturation - Color saturation in the range 0..1
  • +
  • lightness - Color lightness in the range 0..1
  • +
+

See also: al_color_hsl_to_rgb, al_color_hsv

+

Examples:

+ +

al_color_hsl_to_rgb

+
void al_color_hsl_to_rgb(float hue, float saturation, float lightness,
+   float *red, float *green, float *blue)
+

Source Code

+

Convert values in HSL color model to RGB color model.

+

Parameters:

+
    +
  • hue - Color hue angle in the range 0..360
  • +
  • saturation - Color saturation in the range 0..1
  • +
  • lightness - Color lightness in the range 0..1
  • +
  • red, green, blue - returned RGB values in the range 0..1
  • +
+

See also: al_color_rgb_to_hsl, al_color_hsl, al_color_hsv_to_rgb

+

Examples:

+ +

al_color_hsv

+
ALLEGRO_COLOR al_color_hsv(float h, float s, float v)
+

Source Code

+

Return an ALLEGRO_COLOR structure from HSV (hue, saturation, value) values.

+

Parameters:

+
    +
  • hue - Color hue angle in the range 0..360
  • +
  • saturation - Color saturation in the range 0..1
  • +
  • value - Color value in the range 0..1
  • +
+

See also: al_color_hsv_to_rgb, al_color_hsl

+

Examples:

+ +

al_color_hsv_to_rgb

+
void al_color_hsv_to_rgb(float hue, float saturation, float value,
+   float *red, float *green, float *blue)
+

Source Code

+

Convert values in HSV color model to RGB color model.

+

Parameters:

+
    +
  • hue - Color hue angle in the range 0..360
  • +
  • saturation - Color saturation in the range 0..1
  • +
  • value - Color value in the range 0..1
  • +
  • red, green, blue - returned RGB values in the range 0..1
  • +
+

See also: al_color_rgb_to_hsv, al_color_hsv, al_color_hsl_to_rgb

+

Examples:

+ +

al_color_html

+
ALLEGRO_COLOR al_color_html(char const *string)
+

Source Code

+

Interprets an HTML-style hex number (e.g. #00faff) as a color. The accepted format is the same as al_color_html_to_rgb.

+

Returns the interpreted color, or al_map_rgba(0, 0, 0, 0) if the string could not be parsed.

+
+

Note: the behaviour on invalid strings is different from Allegro 5.0.x.

+
+

See also: al_color_html_to_rgb, al_color_rgb_to_html

+

al_color_html_to_rgb

+
bool al_color_html_to_rgb(char const *string,
+   float *red, float *green, float *blue)
+

Source Code

+

Interprets an HTML-style hex number (e.g. #00faff) as a color. The only accepted formats are “#RRGGBB” and “RRGGBB” where R, G, B are hexadecimal digits [0-9A-Fa-f].

+

Returns true on success, false on failure. On failure all components are set to zero.

+
+

Note: the behaviour on invalid strings is different from Allegro 5.0.x.

+
+

See also: al_color_html, al_color_rgb_to_html

+

al_color_rgb_to_html

+
void al_color_rgb_to_html(float red, float green, float blue,
+    char *string)
+

Source Code

+

Create an HTML-style string representation of an ALLEGRO_COLOR, e.g. #00faff.

+

Parameters:

+
    +
  • red, green, blue - The color components in the range 0..1.
  • +
  • string - A pointer to a buffer of at least 8 bytes, into which the result will be written (including the NUL terminator).
  • +
+

Example:

+
char html[8];
+al_color_rgb_to_html(1, 0, 0, html);
+

Now html will contain “#ff0000”.

+

See also: al_color_html, al_color_html_to_rgb

+

Examples:

+ +

al_color_name

+
ALLEGRO_COLOR al_color_name(char const *name)
+

Source Code

+

Return an ALLEGRO_COLOR with the given name. If the color is not found then black is returned.

+

See al_color_name_to_rgb for the list of names.

+

Examples:

+ +

al_color_name_to_rgb

+
bool al_color_name_to_rgb(char const *name, float *r, float *g, float *b)
+

Source Code

+

Parameters:

+
    +
  • name - The (lowercase) name of the color.
  • +
  • r, g, b - If one of the recognized color names below is passed, the corresponding RGB values in the range 0..1 are written.
  • +
+

The 148 recognized names are:

+
+

aliceblue, antiquewhite, aqua, aquamarine, azure, beige, bisque, black, blanchedalmond, blue, blueviolet, brown, burlywood, cadetblue, chartreuse, chocolate, coral, cornflowerblue, cornsilk, crimson, cyan, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, darkviolet, deeppink, deepskyblue, dimgray, dodgerblue, firebrick, floralwhite, forestgreen, fuchsia, gainsboro, ghostwhite, goldenrod, gold, gray, green, greenyellow, honeydew, hotpink, indianred, indigo, ivory, khaki, lavenderblush, lavender, lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan, lightgoldenrodyellow, lightgreen, lightgrey, lightpink, lightsalmon, lightseagreen, lightskyblue, lightslategray, lightsteelblue, lightyellow, lime, limegreen, linen, magenta, maroon, mediumaquamarine, mediumblue, mediumorchid, mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, avajowhite, navy, oldlace, olive, olivedrab, orange, orangered, orchid, palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, peachpuff, peru, pink, plum, powderblue, purple, rebeccapurple, red, rosybrown, royalblue, saddlebrown, salmon, sandybrown, seagreen, seashell, sienna, silver, skyblue, slateblue, slategray, snow, springgreen, steelblue, tan, teal, thistle, tomato, turquoise, violet, wheat, white, whitesmoke, yellow, yellowgreen

+
+

They are taken from CSS: https://www.w3.org/TR/css-color-4/

+

Note that these 9 colors have two names and so there are only 139 distinct colors: aqua = cyan, darkgray = darkgrey, darkslategray = darkslategrey, dimgray = dimgrey, fuchsia = purple, gray = grey, lightgray = lightgrey, lightslategray = lightslategrey, slategray = slategrey

+

Returns: true if a name from the list above was passed, else false.

+

See also: al_color_name

+

al_color_rgb_to_cmyk

+
void al_color_rgb_to_cmyk(float red, float green, float blue,
+   float *cyan, float *magenta, float *yellow, float *key)
+

Source Code

+

Each RGB color can be represented in CMYK with a K component of 0 with the following formula:

+
C = 1 - R
+M = 1 - G
+Y = 1 - B
+K = 0
+

This function will instead find the representation with the maximal value for K and minimal color components.

+

See also: al_color_cmyk, al_color_cmyk_to_rgb

+

Examples:

+ +

al_color_rgb_to_hsl

+
void al_color_rgb_to_hsl(float red, float green, float blue,
+   float *hue, float *saturation, float *lightness)
+

Source Code

+

Given an RGB triplet with components in the range 0..1, return the hue in degrees from 0..360 and saturation and lightness in the range 0..1.

+

See also: al_color_hsl_to_rgb, al_color_hsl

+

Examples:

+ +

al_color_rgb_to_hsv

+
void al_color_rgb_to_hsv(float red, float green, float blue,
+   float *hue, float *saturation, float *value)
+

Source Code

+

Given an RGB triplet with components in the range 0..1, return the hue in degrees from 0..360 and saturation and value in the range 0..1.

+

See also: al_color_hsv_to_rgb, al_color_hsv

+

Examples:

+ +

al_color_rgb_to_name

+
char const *al_color_rgb_to_name(float r, float g, float b)
+

Source Code

+

Given an RGB triplet with components in the range 0..1, find a color name describing it approximately.

+

See also: al_color_name_to_rgb, al_color_name

+

Examples:

+ +

al_color_rgb_to_xyz

+
void al_color_rgb_to_xyz(float red, float green, float blue,
+   float *x, float *y, float *z)
+

Source Code

+

Convert RGB values to XYZ color space.

+

Since: 5.2.3

+

See also: al_color_xyz, al_color_xyz_to_rgb

+

al_color_xyz

+
ALLEGRO_COLOR al_color_xyz(float x, float y, float z)
+

Source Code

+

Return an ALLEGRO_COLOR structure from XYZ values. The CIE 1931 XYZ color space consists of three components in the range 0..1. The Y component corresponds to luminance and the X and Z components define the color.

+

RGB components are always assumed to be in sRGB space.

+
+

Note:

+

The XYZ color space can represent more colors than are visible in sRGB and therefore conversion may result in RGB values outside of the 0..1 range. You can check for that case with al_is_color_valid.

+
+

Since: 5.2.3

+

See also: al_color_xyz_to_rgb, al_color_rgb_to_xyz

+

al_color_xyz_to_rgb

+
void al_color_xyz_to_rgb(float x, float y, float z,
+    float *red, float *green, float *blue)
+

Source Code

+

Convert XYZ color values to RGB color space.

+

Since: 5.2.3

+

See also: al_color_xyz, al_color_rgb_to_xyz

+

al_color_rgb_to_xyy

+
void al_color_rgb_to_xyy(float red, float green, float blue,
+   float *x, float *y, float *y2)
+

Source Code

+

Convert RGB values to xyY color space.

+

Since: 5.2.3

+

See also: al_color_xyy, al_color_xyy_to_rgb

+

al_color_xyy

+
ALLEGRO_COLOR al_color_xyy(float x, float y, float y2)
+

Source Code

+

Return an ALLEGRO_COLOR structure from xyY values. The Y component in the xyY color space is the same as the Y in XYZ.

+

However the x and y values are computed from XYZ like this:

+
x = X / (X + Y + Z)
+y = Y / (X + Y + Z)
+

Since: 5.2.3

+

See also: al_color_xyy_to_rgb, al_color_rgb_to_xyy

+

al_color_xyy_to_rgb

+
void al_color_xyy_to_rgb(float x, float y, float y2,
+    float *red, float *green, float *blue)
+

Source Code

+

Convert xyY color values to RGB color space.

+

Since: 5.2.3

+

See also: al_color_xyy, al_color_rgb_to_xyy

+

al_color_rgb_to_lab

+
void al_color_rgb_to_lab(float red, float green, float blue,
+   float *l, float *a, float *b)
+

Source Code

+

Convert RGB values to L*a*b* color space.

+

Since: 5.2.3

+

See also: al_color_lab, al_color_lab_to_rgb

+

al_color_lab

+
ALLEGRO_COLOR al_color_lab(float l, float a, float b)
+

Source Code

+

Return an ALLEGRO_COLOR structure from CIE L*a*b* values. The L* component corresponds to luminance from 0..1. The a* and b* components are in the range -1..+1.

+
+

Note:

+

The L*a*b* color space can represent more colors than are visible in sRGB and therefore conversion may result in RGB values outside of the 0..1 range. You can check for that case with al_is_color_valid.

+
+
+

Note:

+

In some literature the range of L* is 0 to 100 and a* and b* are from -100 to +100. In that case divide all components by 100 before passing them to this function.

+
+

Since: 5.2.3

+

See also: al_color_lab_to_rgb, al_color_rgb_to_lab

+

Examples:

+ +

al_color_lab_to_rgb

+
void al_color_lab_to_rgb(float l, float a, float b,
+    float *red, float *green, float *blue)
+

Source Code

+

Convert CIE L*a*b* color values to RGB color space.

+

Since: 5.2.3

+

See also: al_color_lab, al_color_rgb_to_lab

+

Examples:

+ +

al_color_rgb_to_lch

+
void al_color_rgb_to_lch(float red, float green, float blue,
+   float *l, float *c, float *h)
+

Source Code

+

Convert RGB values to CIE LCH color space.

+

Since: 5.2.3

+

See also: al_color_lch, al_color_lch_to_rgb

+

Examples:

+ +

al_color_lch

+
ALLEGRO_COLOR al_color_lch(float l, float c, float h)
+

Source Code

+

Return an ALLEGRO_COLOR structure from CIE LCH values. LCH colors are very similar to HSL, with the same meaning of L and H and C corresponding to S. However LCH is more visually uniform. Furthermore, this function expects the angle for H in radians and not in degree.

+

The CIE LCH color space is a cylindrical representation of the L*a*b* color space. The L component is the same and C and H are computed like this:

+
C = sqrt(a * a + b * b)
+H = atan2(b, a)
+

Since: 5.2.3

+

See also: al_color_lch_to_rgb, al_color_rgb_to_lch

+

Examples:

+ +

al_color_lch_to_rgb

+
void al_color_lch_to_rgb(float l, float c, float h,
+    float *red, float *green, float *blue)
+

Source Code

+

Convert CIE LCH color values to RGB color space.

+

Since: 5.2.3

+

See also: al_color_lch, al_color_rgb_to_lch

+

Examples:

+ +

al_color_distance_ciede2000

+
double al_color_distance_ciede2000(ALLEGRO_COLOR color1,
+      ALLEGRO_COLOR color2) {
+

Source Code

+

This function computes the CIEDE2000 color difference between two RGB colors. This is a visually uniform color difference, unlike for example the RGB distance.

+

When using the RGB distance (Euklidean distance between two RGB triplets) there can be color pairs with the same distance, where the colors of one pair appear to be almost the same color, while the colors of the other pair look quite different. This is improved by using the L*a*b* color space which was designed with perceptual uniformity in mind. However it still is not completely uniform. The CIEDE2000 formula contains some additional transformations to fix that.

+

The returned color distance is roughly in the range 0 (identical color) to 1 (completely different color) - but values greater than one are possible.

+
+

Note: This function uses al_color_lab internally which defines the L component to be in the range 0..1 (and not 0..100 as is sometimes seen).

+
+

Since: 5.2.3

+

Examples:

+ +

al_color_rgb_to_yuv

+
void al_color_rgb_to_yuv(float red, float green, float blue,
+   float *y, float *u, float *v)
+

Source Code

+

Convert RGB values to YUV color space.

+

See also: al_color_yuv, al_color_yuv_to_rgb

+

Examples:

+ +

al_color_yuv

+
ALLEGRO_COLOR al_color_yuv(float y, float u, float v)
+

Source Code

+

Return an ALLEGRO_COLOR structure from YUV values.

+

See also: al_color_yuv_to_rgb, al_color_rgb_to_yuv

+

Examples:

+ +

al_color_yuv_to_rgb

+
void al_color_yuv_to_rgb(float y, float u, float v,
+    float *red, float *green, float *blue)
+

Source Code

+

Convert YUV color values to RGB color space.

+

See also: al_color_yuv, al_color_rgb_to_yuv

+

Examples:

+ +

al_get_allegro_color_version

+
uint32_t al_get_allegro_color_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

al_is_color_valid

+

Source Code

+

Checks if all components of the color are between 0 and 1. Some of the color conversions in this addon support color spaces with more colors than can be represented in sRGB and when converted to RGB will result in invalid color components outside the 0..1 range.

+

Since: 5.2.3

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:43 UTC +

+
+ + diff --git a/allegro/docs/html/refman/config.html b/allegro/docs/html/refman/config.html new file mode 100644 index 00000000..621b4ec9 --- /dev/null +++ b/allegro/docs/html/refman/config.html @@ -0,0 +1,413 @@ + + + + + + + Configuration files + + + + + + + + +
+ + +
+

Configuration files

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

Allegro supports reading and writing of configuration files with a simple, INI file-like format.

+

A configuration file consists of key-value pairs separated by newlines. Keys are separated from values by an equals sign (=). All whitespace before the key, after the value and immediately adjacent to the equals sign is ignored. Keys and values may have whitespace characters within them. Keys do not need to be unique, but all but the last one are ignored.

+

The hash (#) character is used a comment when it is the first non-whitespace character on the line. All characters following that character are ignored to the end of the line. The hash character anywhere else on the line has no special significance.

+

Key-value pairs can be optionally grouped into sections, which are declared by surrounding a section name with square brackets ([ and ]) on a single line. Whitespace before the opening bracket is ignored. All characters after the trailing bracket are also ignored.

+

All key-value pairs that follow a section declaration belong to the last declared section. Key-value pairs that don’t follow any section declarations belong to the global section. Sections do not nest.

+

Here is an example configuration file:

+
#  Monster description
+monster name = Allegro Developer
+
+[weapon 0]
+damage = 443
+
+[weapon 1]
+damage = 503
+

It can then be accessed like this (make sure to check for errors in an actual program):

+
ALLEGRO_CONFIG* cfg = al_load_config_file("test.cfg");
+printf("%s\n", al_get_config_value(cfg, "", "monster name")); /* Prints: Allegro Developer */
+printf("%s\n", al_get_config_value(cfg, "weapon 0", "damage")); /* Prints: 443 */
+printf("%s\n", al_get_config_value(cfg, "weapon 1", "damage")); /* Prints: 503 */
+al_destroy_config(cfg);
+

ALLEGRO_CONFIG

+
typedef struct ALLEGRO_CONFIG ALLEGRO_CONFIG;
+

Source Code

+

An abstract configuration structure.

+

Examples:

+ +

ALLEGRO_CONFIG_SECTION

+
typedef struct ALLEGRO_CONFIG_SECTION ALLEGRO_CONFIG_SECTION;
+

Source Code

+

An opaque structure used for iterating across sections in a configuration structure.

+

See also: al_get_first_config_section, al_get_next_config_section

+

Examples:

+ +

ALLEGRO_CONFIG_ENTRY

+
typedef struct ALLEGRO_CONFIG_ENTRY ALLEGRO_CONFIG_ENTRY;
+

Source Code

+

An opaque structure used for iterating across entries in a configuration section.

+

See also: al_get_first_config_entry, al_get_next_config_entry

+

Examples:

+ +

al_create_config

+
ALLEGRO_CONFIG *al_create_config(void)
+

Source Code

+

Create an empty configuration structure.

+

See also: al_load_config_file, al_destroy_config

+

Examples:

+ +

al_destroy_config

+
void al_destroy_config(ALLEGRO_CONFIG *config)
+

Source Code

+

Free the resources used by a configuration structure. Does nothing if passed NULL.

+

See also: al_create_config, al_load_config_file

+

Examples:

+ +

al_load_config_file

+
ALLEGRO_CONFIG *al_load_config_file(const char *filename)
+

Source Code

+

Read a configuration file from disk. Returns NULL on error. The configuration structure should be destroyed with al_destroy_config.

+

See also: al_load_config_file_f, al_save_config_file

+

Examples:

+ +

al_load_config_file_f

+
ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file)
+

Source Code

+

Read a configuration file from an already open file.

+

Returns NULL on error. The configuration structure should be destroyed with al_destroy_config. The file remains open afterwards.

+

See also: al_load_config_file

+

al_save_config_file

+
bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config)
+

Source Code

+

Write out a configuration file to disk. Returns true on success, false on error.

+

See also: al_save_config_file_f, al_load_config_file

+

Examples:

+ +

al_save_config_file_f

+
bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)
+

Source Code

+

Write out a configuration file to an already open file.

+

Returns true on success, false on error. The file remains open afterwards.

+

See also: al_save_config_file

+

al_add_config_section

+
void al_add_config_section(ALLEGRO_CONFIG *config, const char *name)
+

Source Code

+

Add a section to a configuration structure with the given name. If the section already exists then nothing happens.

+

al_remove_config_section

+
bool al_remove_config_section(ALLEGRO_CONFIG *config, char const *section)
+

Source Code

+

Remove a section of a configuration.

+

Returns true if the section was removed, or false if the section did not exist.

+

Since: 5.1.5

+

Examples:

+ +

al_add_config_comment

+
void al_add_config_comment(ALLEGRO_CONFIG *config,
+   const char *section, const char *comment)
+

Source Code

+

Add a comment in a section of a configuration. If the section doesn’t yet exist, it will be created. The section can be NULL or "" for the global section.

+

The comment may or may not begin with a hash character. Any newlines in the comment string will be replaced by space characters.

+

See also: al_add_config_section

+

al_get_config_value

+
const char *al_get_config_value(const ALLEGRO_CONFIG *config,
+   const char *section, const char *key)
+

Source Code

+

Gets a pointer to an internal character buffer that will only remain valid as long as the ALLEGRO_CONFIG structure is not destroyed. Copy the value if you need a copy. The section can be NULL or "" for the global section. Returns NULL if the section or key do not exist.

+

See also: al_set_config_value

+

Examples:

+ +

al_set_config_value

+
void al_set_config_value(ALLEGRO_CONFIG *config,
+   const char *section, const char *key, const char *value)
+

Source Code

+

Set a value in a section of a configuration. If the section doesn’t yet exist, it will be created. If a value already existed for the given key, it will be overwritten. The section can be NULL or "" for the global section.

+

For consistency with the on-disk format of config files, any leading and trailing whitespace will be stripped from the value. If you have significant whitespace you wish to preserve, you should add your own quote characters and remove them when reading the values back in.

+

See also: al_get_config_value

+

Examples:

+ +

al_remove_config_key

+
bool al_remove_config_key(ALLEGRO_CONFIG *config, char const *section,
+   char const *key)
+

Source Code

+

Remove a key and its associated value in a section of a configuration.

+

Returns true if the entry was removed, or false if the entry did not exist.

+

Since: 5.1.5

+

Examples:

+ +

al_get_first_config_section

+
char const *al_get_first_config_section(ALLEGRO_CONFIG const *config,
+   ALLEGRO_CONFIG_SECTION **iterator)
+

Source Code

+

Returns the name of the first section in the given config file. Usually this will return an empty string for the global section, even it contains no values. The iterator parameter will receive an opaque iterator which is used by al_get_next_config_section to iterate over the remaining sections.

+

The returned string and the iterator are only valid as long as no change is made to the passed ALLEGRO_CONFIG.

+

See also: al_get_next_config_section

+

Examples:

+ +

al_get_next_config_section

+
char const *al_get_next_config_section(ALLEGRO_CONFIG_SECTION **iterator)
+

Source Code

+

Returns the name of the next section in the given config file or NULL if there are no more sections. The iterator must have been obtained with al_get_first_config_section first.

+

See also: al_get_first_config_section

+

Examples:

+ +

al_get_first_config_entry

+
char const *al_get_first_config_entry(ALLEGRO_CONFIG const *config,
+   char const *section, ALLEGRO_CONFIG_ENTRY **iterator)
+

Source Code

+

Returns the name of the first key in the given section in the given config or NULL if the section is empty. The iterator works like the one for al_get_first_config_section.

+

The returned string and the iterator are only valid as long as no change is made to the passed ALLEGRO_CONFIG.

+

See also: al_get_next_config_entry

+

Examples:

+ +

al_get_next_config_entry

+
char const *al_get_next_config_entry(ALLEGRO_CONFIG_ENTRY **iterator)
+

Source Code

+

Returns the next key for the iterator obtained by al_get_first_config_entry. The iterator works like the one for al_get_next_config_section.

+

Examples:

+ +

al_merge_config

+
ALLEGRO_CONFIG *al_merge_config(const ALLEGRO_CONFIG *cfg1,
+    const ALLEGRO_CONFIG *cfg2)
+

Source Code

+

Merge two configuration structures, and return the result as a new configuration. Values in configuration ‘cfg2’ override those in ‘cfg1’. Neither of the input configuration structures are modified. Comments from ‘cfg2’ are not retained.

+

See also: al_merge_config_into

+

al_merge_config_into

+
void al_merge_config_into(ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add)
+

Source Code

+

Merge one configuration structure into another. Values in configuration ‘add’ override those in ‘master’. ‘master’ is modified. Comments from ‘add’ are not retained.

+

See also: al_merge_config

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/direct3d.html b/allegro/docs/html/refman/direct3d.html new file mode 100644 index 00000000..93580fa9 --- /dev/null +++ b/allegro/docs/html/refman/direct3d.html @@ -0,0 +1,260 @@ + + + + + + + Direct3D integration + + + + + + + + +
+ + +
+

Direct3D integration

+
+ +

These functions are declared in the following header file:

+
 #include <allegro5/allegro_direct3d.h>
+

al_get_d3d_device

+
LPDIRECT3DDEVICE9 al_get_d3d_device(ALLEGRO_DISPLAY *display)
+

Source Code

+

Returns the Direct3D device of the display. The return value is undefined if the display was not created with the Direct3D flag.

+

Returns: A pointer to the Direct3D device.

+

Examples:

+ +

al_get_d3d_system_texture

+
LPDIRECT3DTEXTURE9 al_get_d3d_system_texture(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns the system texture (stored with the D3DPOOL_SYSTEMMEM flags). This texture is used for the render-to-texture feature set.

+

Returns: A pointer to the Direct3D system texture.

+

al_get_d3d_video_texture

+
LPDIRECT3DTEXTURE9 al_get_d3d_video_texture(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns the video texture (stored with the D3DPOOL_DEFAULT or D3DPOOL_MANAGED flags depending on whether render-to-texture is enabled or disabled respectively).

+

Returns: A pointer to the Direct3D video texture.

+

al_have_d3d_non_pow2_texture_support

+
bool al_have_d3d_non_pow2_texture_support(void)
+

Source Code

+

Returns whether the Direct3D device supports textures whose dimensions are not powers of two.

+

Returns: True if device supports NPOT textures, false otherwise.

+

al_have_d3d_non_square_texture_support

+
bool al_have_d3d_non_square_texture_support(void)
+

Source Code

+

Returns whether the Direct3D device supports textures that are not square.

+

Returns: True if the Direct3D device supports non-square textures, false otherwise.

+

al_get_d3d_texture_size

+
bool al_get_d3d_texture_size(ALLEGRO_BITMAP *bitmap, int *width, int *height)
+

Source Code

+

Retrieves the size of the Direct3D texture used for the bitmap.

+

Returns true on success, false on failure. Zero width and height are returned if the bitmap is not a Direct3D bitmap.

+

Since: 5.1.0

+

See also: al_get_d3d_texture_position

+

al_get_d3d_texture_position

+
void al_get_d3d_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v)
+

Source Code

+

Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels.

+

Parameters:

+
    +
  • bitmap - ALLEGRO_BITMAP to examine
  • +
  • u - Will hold the returned u coordinate
  • +
  • v - Will hold the returned v coordinate
  • +
+

See also: al_get_d3d_texture_size

+

al_is_d3d_device_lost

+
bool al_is_d3d_device_lost(ALLEGRO_DISPLAY *display)
+

Source Code

+

Returns a boolean indicating whether or not the Direct3D device belonging to the given display is in a lost state.

+

Parameters:

+
    +
  • display - The display that the device you wish to check is attached to
  • +
+

al_set_d3d_device_release_callback

+
void al_set_d3d_device_release_callback(
+   void (*callback)(ALLEGRO_DISPLAY *display))
+

Source Code

+

The callback will be called whenever a D3D device is reset (minimize, toggle fullscreen window, etc). In the callback you should release any d3d resources you have created yourself. The callback receives the affected display as a parameter.

+

Pass NULL to disable the callback.

+

Since: 5.1.0

+

al_set_d3d_device_restore_callback

+
void al_set_d3d_device_restore_callback(
+   void (*callback)(ALLEGRO_DISPLAY *display))
+

Source Code

+

The callback will be called whenever a D3D device that has been reset is restored. In the callback you should restore any d3d resources you have created yourself. The callback receives the affected display as a parameter.

+

Pass NULL to disable the callback.

+

Since: 5.1.0

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/display.html b/allegro/docs/html/refman/display.html new file mode 100644 index 00000000..6864d8e3 --- /dev/null +++ b/allegro/docs/html/refman/display.html @@ -0,0 +1,890 @@ + + + + + + + Displays + + + + + + + + +
+ + +
+

Displays

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

All drawing operations end up being visible on a display which is the same as a window in windowed environments. Thus, before anything is displayed, a display needs to be created.

+

Before creating a display with al_create_display, flags and options can be set with al_set_new_display_flags and al_set_new_display_option. For example, you can enable the use of shaders or choose between the OpenGL and Direct3D backends (on platforms that support both) with al_set_new_display_flags. Display options are rather optional settings that do not affect Allegro itself, e.g. they allow you to specify whether you want a depth buffer or enable multisampling.

+

The actual properties of a display that has been successfully created can be queried via al_get_display_option, al_get_display_flags, al_get_display_width etc. Note that you can query some additional read-only properties such as the maximum allowed bitmap (i.e. texture) size via al_get_display_option.

+

Each display has a backbuffer associated to it which is the default target for any drawing operations. In order to make visible what has been drawn previously, you have to to call al_flip_display. Note that it is generally advisable to redraw the whole screen (or clear it in advance) to avoid artefacts of uninitialised memory becoming visible with some drivers.

+

You don’t have to use Allegro’s drawing routines, however: since creating a display implies the creation of an OpenGL context or Direct3D device respectively, you can use these APIs directly if you prefer to do so. Allegro provides integration for both (see the OpenGL / Direct3D sections), so you can retrieve the underlying textures of ALLEGRO_BITMAPs, for example.

+

In order to write a well-behaved application, it is necessary to remember that displays will also inform you about important events via their event sources.

+

Display creation

+

ALLEGRO_DISPLAY

+
typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY;
+

Source Code

+

An opaque type representing an open display or window.

+

Examples:

+ +

al_create_display

+
ALLEGRO_DISPLAY *al_create_display(int w, int h)
+

Source Code

+

Create a display, or window, with the specified dimensions. The parameters of the display are determined by the last calls to al_set_new_display_*. Default parameters are used if none are set explicitly. Creating a new display will automatically make it the active one, with the backbuffer selected for drawing.

+

Returns NULL on error.

+

Each display that uses OpenGL as a backend has a distinct OpenGL rendering context associated with it. See al_set_target_bitmap for the discussion about rendering contexts.

+

See also: al_set_new_display_flags, al_set_new_display_option, al_set_new_display_refresh_rate, al_set_new_display_adapter, al_set_new_window_title al_set_window_position

+

Examples:

+ +

al_destroy_display

+
void al_destroy_display(ALLEGRO_DISPLAY *display)
+

Source Code

+

Destroy a display.

+

If the target bitmap of the calling thread is tied to the display, then it implies a call to “al_set_target_bitmap(NULL);” before the display is destroyed.

+

That special case notwithstanding, you should make sure no threads are currently targeting a bitmap which is tied to the display before you destroy it.

+

See also: al_set_target_bitmap

+

Examples:

+ +

al_get_new_display_flags

+
int al_get_new_display_flags(void)
+

Source Code

+

Get the display flags to be used when creating new displays on the calling thread.

+

See also: al_set_new_display_flags, al_set_display_flag

+

al_set_new_display_flags

+
void al_set_new_display_flags(int flags)
+

Source Code

+

Sets various flags to be used when creating new displays on the calling thread. flags is a bitfield containing any reasonable combination of the following:

+
+
ALLEGRO_WINDOWED
+

Prefer a windowed mode.

+

Under multi-head X (not XRandR/TwinView), the use of more than one adapter is impossible due to bugs in X and GLX. al_create_display will fail if more than one adapter is attempted to be used.

+
+
ALLEGRO_FULLSCREEN_WINDOW
+

Make the window span the entire screen. Unlike ALLEGRO_FULLSCREEN this will never attempt to modify the screen resolution. Instead the pixel dimensions of the created display will be the same as the desktop.

+

The passed width and height are only used if the window is switched out of fullscreen mode later but will be ignored initially.

+

Under Windows and X11 a fullscreen display created with this flag will behave differently from one created with the ALLEGRO_FULLSCREEN flag - even if the ALLEGRO_FULLSCREEN display is passed the desktop dimensions. The exact difference is platform dependent, but some things which may be different is how alt-tab works, how fast you can toggle between fullscreen/windowed mode or how additional monitors behave while your display is in fullscreen mode.

+

Additionally under X, the use of more than one adapter in multi-head mode or with true Xinerama enabled is impossible due to bugs in X/GLX, creation will fail if more than one adapter is attempted to be used.

+
+
ALLEGRO_FULLSCREEN
+

Prefer a fullscreen mode.

+

Under X the use of more than one FULLSCREEN display when using multi-head X, or true Xinerama is not possible due to bugs in X and GLX, display creation will fail if more than one adapter is attempted to be used.

+
+

Note: Prefer using ALLEGRO_FULLSCREEN_WINDOW as it typically provides a better user experience as the monitor doesn’t change resolution and switching away from your game via Alt-Tab works smoothly. ALLEGRO_FULLSCREEN is typically less well supported compared to ALLEGRO_FULLSCREEN_WINDOW.

+
+
+
ALLEGRO_RESIZABLE
+
The display is resizable (only applicable if combined with ALLEGRO_WINDOWED). +
+
ALLEGRO_MAXIMIZED
+
The display window will be maximized (only applicable if combined with ALLEGRO_RESIZABLE). Since: 5.1.12 +
+
ALLEGRO_OPENGL
+
Require the driver to provide an initialized OpenGL context after returning successfully. +
+
ALLEGRO_OPENGL_3_0
+
Require the driver to provide an initialized OpenGL context compatible with OpenGL version 3.0. +
+
ALLEGRO_OPENGL_FORWARD_COMPATIBLE
+
If this flag is set, the OpenGL context created with ALLEGRO_OPENGL_3_0 will be forward compatible only, meaning that all of the OpenGL API declared deprecated in OpenGL 3.0 will not be supported. Currently, a display created with this flag will not be compatible with Allegro drawing routines; the display option ALLEGRO_COMPATIBLE_DISPLAY will be set to false. +
+
ALLEGRO_OPENGL_ES_PROFILE
+
Used together with ALLEGRO_OPENGL, requests that the OpenGL context uses the OpenGL ES profile. A specific version can be requested with al_set_new_display_option. Note: Currently this is only supported by the X11/GLX driver. Since: 5.1.13 +
+
ALLEGRO_OPENGL_CORE_PROFILE
+
Used together with ALLEGRO_OPENGL, requests that the OpenGL context uses the OpenGL Core profile. A specific version can be requested with al_set_new_display_option. Note: Currently this is only supported by the X11/GLX driver. Since: 5.2.7 +
+
ALLEGRO_DIRECT3D
+
Require the driver to do rendering with Direct3D and provide a Direct3D device. +
+
ALLEGRO_PROGRAMMABLE_PIPELINE
+
Require a programmable graphics pipeline. This flag is required to use ALLEGRO_SHADER objects. Since: 5.1.6 +
+
ALLEGRO_FRAMELESS
+
Try to create a window without a frame (i.e. no border or titlebar). This usually does nothing for fullscreen modes, and even in windowed modes it depends on the underlying platform whether it is supported or not. Since: 5.0.7, 5.1.2 +
+
ALLEGRO_NOFRAME
+
Original name for ALLEGRO_FRAMELESS. This works with older versions of Allegro. +
+
ALLEGRO_GENERATE_EXPOSE_EVENTS
+
Let the display generate expose events. +
+
ALLEGRO_GTK_TOPLEVEL
+
Create a GTK toplevel window for the display, on X. This flag is conditionally defined by the native dialog addon. You must call al_init_native_dialog_addon for it to succeed. ALLEGRO_GTK_TOPLEVEL is incompatible with ALLEGRO_FULLSCREEN. Since: 5.1.5 +
+
+

0 can be used for default values.

+

See also: al_set_new_display_option, al_get_display_option, al_set_display_option

+

Examples:

+ +

al_get_new_display_option

+
int al_get_new_display_option(int option, int *importance)
+

Source Code

+

Retrieve an extra display setting which was previously set with al_set_new_display_option.

+

al_set_new_display_option

+
void al_set_new_display_option(int option, int value, int importance)
+

Source Code

+

Set an extra display option, to be used when creating new displays on the calling thread. Display options differ from display flags, and specify some details of the context to be created within the window itself. These mainly have no effect on Allegro itself, but you may want to specify them, for example if you want to use multisampling.

+

The ‘importance’ parameter can be either:

+
    +
  • ALLEGRO_REQUIRE - The display will not be created if the setting can not be met.
  • +
  • ALLEGRO_SUGGEST - If the setting is not available, the display will be created anyway with a setting as close as possible to the requested one. You can query the actual value used in that case by calling al_get_display_option after the display has been created.
  • +
  • ALLEGRO_DONTCARE - If you added a display option with one of the above two settings before, it will be removed again. Else this does nothing.
  • +
+

The supported options are:

+
+
ALLEGRO_COLOR_SIZE
+
This can be used to ask for a specific bit depth. For example to force a 16-bit framebuffer set this to 16. +
+
ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE, ALLEGRO_ALPHA_SIZE
+
Individual color component size in bits. +
+
ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT, ALLEGRO_BLUE_SHIFT, ALLEGRO_ALPHA_SHIFT
+
Together with the previous settings these can be used to specify the exact pixel layout the display should use. Normally there is no reason to use these. +
+
ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE, ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE
+
This can be used to define the required accumulation buffer size. +
+
ALLEGRO_STEREO
+
Whether the display is a stereo display. +
+
ALLEGRO_AUX_BUFFERS
+
Number of auxiliary buffers the display should have. +
+
ALLEGRO_DEPTH_SIZE
+
How many depth buffer (z-buffer) bits to use. +
+
ALLEGRO_STENCIL_SIZE
+
How many bits to use for the stencil buffer. +
+
ALLEGRO_SAMPLE_BUFFERS
+
Whether to use multisampling (1) or not (0). +
+
ALLEGRO_SAMPLES
+
If the above is 1, the number of samples to use per pixel. Else 0. +
+
ALLEGRO_RENDER_METHOD:
+
0 if hardware acceleration is not used with this display. +
+
ALLEGRO_FLOAT_COLOR
+
Whether to use floating point color components. +
+
ALLEGRO_FLOAT_DEPTH
+
Whether to use a floating point depth buffer. +
+
ALLEGRO_SINGLE_BUFFER
+
Whether the display uses a single buffer (1) or another update method (0). +
+
ALLEGRO_SWAP_METHOD
+
If the above is 0, this is set to 1 to indicate the display is using a copying method to make the next buffer in the flip chain available, or to 2 to indicate a flipping or other method. +
+
ALLEGRO_COMPATIBLE_DISPLAY
+
Indicates if Allegro’s graphics functions can use this display. If you request a display not useable by Allegro, you can still use for example OpenGL to draw graphics. +
+
ALLEGRO_UPDATE_DISPLAY_REGION
+
Set to 1 if the display is capable of updating just a region, and 0 if calling al_update_display_region is equivalent to al_flip_display. +
+
ALLEGRO_VSYNC
+
Set to 1 to tell the driver to wait for vsync in al_flip_display, or to 2 to force vsync off. The default of 0 means that Allegro does not try to modify the vsync behavior so it may be on or off. Note that even in the case of 1 or 2 it is possible to override the vsync behavior in the graphics driver so you should not rely on it. +
+
ALLEGRO_MAX_BITMAP_SIZE
+
When queried this returns the maximum size (width as well as height) a bitmap can have for this display. Calls to al_create_bitmap or al_load_bitmap for bitmaps larger than this size will fail. It does not apply to memory bitmaps which always can have arbitrary size (but are slow for drawing). +
+
ALLEGRO_SUPPORT_NPOT_BITMAP
+
Set to 1 if textures used for bitmaps on this display can have a size which is not a power of two. This is mostly useful if you use Allegro to load textures as otherwise only power-of-two textures will be used internally as bitmap storage. +
+
ALLEGRO_CAN_DRAW_INTO_BITMAP
+
Set to 1 if you can use al_set_target_bitmap on bitmaps of this display to draw into them. If this is not the case software emulation will be used when drawing into display bitmaps (which can be very slow). +
+
ALLEGRO_SUPPORT_SEPARATE_ALPHA
+
This is set to 1 if the al_set_separate_blender function is supported. Otherwise the alpha parameters will be ignored. +
+
ALLEGRO_AUTO_CONVERT_BITMAPS
+

This is on by default. It causes any existing memory bitmaps with the ALLEGRO_CONVERT_BITMAP flag to be converted to a display bitmap of the newly created display with the option set.

+

Since: 5.1.0

+
+
ALLEGRO_SUPPORTED_ORIENTATIONS
+

This is a bit-combination of the orientations supported by the application. The orientations are the same as for al_get_display_orientation with the additional possibilities:

+
    +
  • ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_ALL
  • +
+

PORTRAIT means only the two portrait orientations are supported, LANDSCAPE means only the two landscape orientations and ALL allows all four orientations. When the orientation changes between a portrait and a landscape orientation the display needs to be resized. This is done by sending an ALLEGRO_EVENT_DISPLAY_RESIZE message which should be handled by calling al_acknowledge_resize.

+

Since: 5.1.0

+
+
ALLEGRO_OPENGL_MAJOR_VERSION
+

Request a specific OpenGL major version.

+

Since: 5.1.13

+
+
ALLEGRO_OPENGL_MINOR_VERSION
+

Request a specific OpenGL minor version.

+

Since: 5.1.13

+
+
+

See also: al_set_new_display_flags, al_get_display_option

+

Examples:

+ +

al_reset_new_display_options

+
void al_reset_new_display_options(void)
+

Source Code

+

This undoes any previous call to al_set_new_display_option on the calling thread.

+

al_get_new_window_position

+
void al_get_new_window_position(int *x, int *y)
+

Source Code

+

Get the position where new non-fullscreen displays created by the calling thread will be placed.

+

See also: al_set_new_window_position

+

al_set_new_window_position

+
void al_set_new_window_position(int x, int y)
+

Source Code

+

Sets where the top left pixel of the client area of newly created windows (non-fullscreen) will be on screen, for displays created by the calling thread. Negative values are allowed on some multihead systems.

+

To reset to the default behaviour, pass (INT_MAX, INT_MAX).

+

See also: al_get_new_window_position

+

Examples:

+ +

al_get_new_display_refresh_rate

+
int al_get_new_display_refresh_rate(void)
+

Source Code

+

Get the requested refresh rate to be used when creating new displays on the calling thread.

+

See also: al_set_new_display_refresh_rate

+

al_set_new_display_refresh_rate

+
void al_set_new_display_refresh_rate(int refresh_rate)
+

Source Code

+

Sets the refresh rate to use when creating new displays on the calling thread. If the refresh rate is not available, al_create_display will fail. A list of modes with refresh rates can be found with al_get_num_display_modes and al_get_display_mode.

+

The default setting is zero (don’t care).

+

See also: al_get_new_display_refresh_rate

+

Examples:

+ +

Display operations

+

al_get_display_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_display_event_source(ALLEGRO_DISPLAY *display)
+

Source Code

+

Retrieve the associated event source. See the documentation on events for a list of the events displays will generate.

+

Examples:

+ +

al_get_backbuffer

+
ALLEGRO_BITMAP *al_get_backbuffer(ALLEGRO_DISPLAY *display)
+

Source Code

+

Return a special bitmap representing the back-buffer of the display.

+

Care should be taken when using the backbuffer bitmap (and its sub-bitmaps) as the source bitmap (e.g as the bitmap argument to al_draw_bitmap). Only untransformed operations are hardware accelerated. These consist of al_draw_bitmap and al_draw_bitmap_region when the current transformation is the identity. If the transformation is not the identity, or some other drawing operation is used, the call will be routed through the memory bitmap routines, which are slow. If you need those operations to be accelerated, then first copy a region of the backbuffer into a temporary bitmap (via the al_draw_bitmap and al_draw_bitmap_region), and then use that temporary bitmap as the source bitmap.

+

Examples:

+ +

al_flip_display

+
void al_flip_display(void)
+

Source Code

+

Copies or updates the front and back buffers so that what has been drawn previously on the currently selected display becomes visible on screen. Pointers to the special back buffer bitmap remain valid and retain their semantics as the back buffer, although the contents may have changed.

+
+

Note: If not using the ALLEGRO_SINGLE_BUFFER option, you typically want to redraw every pixel of the backbuffer bitmap to avoid uninitialized memory artifacts.

+
+

Several display options change how this function behaves:

+
    +
  • With ALLEGRO_SINGLE_BUFFER, no flipping is done. You still have to call this function to display graphics, depending on how the used graphics system works.

  • +
  • The ALLEGRO_SWAP_METHOD option may have additional information about what kind of operation is used internally to flip the front and back buffers.

  • +
  • If ALLEGRO_VSYNC is 1, this function will force waiting for vsync. If ALLEGRO_VSYNC is 2, this function will not wait for vsync. With many drivers the vsync behavior is controlled by the user and not the application, and ALLEGRO_VSYNC will not be set; in this case al_flip_display will wait for vsync depending on the settings set in the system’s graphics preferences.

  • +
+

See also: al_set_new_display_flags, al_set_new_display_option

+

Examples:

+ +

al_update_display_region

+
void al_update_display_region(int x, int y, int width, int height)
+

Source Code

+

Does the same as al_flip_display, but tries to update only the specified region. With many drivers this is not possible, but for some it can improve performance. If this is not supported, this function falls back to the behavior of al_flip_display. You can query the support for this function using al_get_display_option(display, ALLEGRO_UPDATE_DISPLAY_REGION).

+

See also: al_flip_display, al_get_display_option

+

Examples:

+ +

al_wait_for_vsync

+
bool al_wait_for_vsync(void)
+

Source Code

+

Wait for the beginning of a vertical retrace. Some driver/card/monitor combinations may not be capable of this.

+

Note how al_flip_display usually already waits for the vertical retrace, so unless you are doing something special, there is no reason to call this function.

+

Returns false if not possible, true if successful.

+

See also: al_flip_display

+

Display size and position

+

al_get_display_width

+
int al_get_display_width(ALLEGRO_DISPLAY *display)
+

Source Code

+

Gets the width of the display. This is like SCREEN_W in Allegro 4.x.

+

See also: al_get_display_height

+

Examples:

+ +

al_get_display_height

+
int al_get_display_height(ALLEGRO_DISPLAY *display)
+

Source Code

+

Gets the height of the display. This is like SCREEN_H in Allegro 4.x.

+

See also: al_get_display_width

+

Examples:

+ +

al_resize_display

+
bool al_resize_display(ALLEGRO_DISPLAY *display, int width, int height)
+

Source Code

+

Resize the display. Returns true on success, or false on error. This works on both fullscreen and windowed displays, regardless of the ALLEGRO_RESIZABLE flag.

+

Adjusts the clipping rectangle to the full size of the backbuffer.

+

See also: al_acknowledge_resize

+

Examples:

+ +

al_acknowledge_resize

+
bool al_acknowledge_resize(ALLEGRO_DISPLAY *display)
+

Source Code

+

When the user receives a resize event from a resizable display, if they wish the display to be resized they must call this function to let the graphics driver know that it can now resize the display. Returns true on success.

+

Adjusts the clipping rectangle to the full size of the backbuffer. This also resets the backbuffers projection transform to default orthographic transform (see al_use_projection_transform).

+

Note that a resize event may be outdated by the time you acknowledge it; there could be further resize events generated in the meantime.

+

See also: al_resize_display, ALLEGRO_EVENT

+

Examples:

+ +

al_get_window_position

+
void al_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y)
+

Source Code

+

Gets the position of a non-fullscreen display.

+

See also: al_set_window_position

+

Examples:

+ +

al_set_window_position

+
void al_set_window_position(ALLEGRO_DISPLAY *display, int x, int y)
+

Source Code

+

Sets the position on screen of a non-fullscreen display.

+

See also: al_get_window_position

+

Examples:

+ +

al_get_window_constraints

+
bool al_get_window_constraints(ALLEGRO_DISPLAY *display,
+   int *min_w, int *min_h, int *max_w, int *max_h)
+

Source Code

+

Gets the constraints for a non-fullscreen resizable display.

+

Since: 5.1.0

+

See also: al_set_window_constraints

+

Examples:

+ +

al_set_window_constraints

+
bool al_set_window_constraints(ALLEGRO_DISPLAY *display,
+   int min_w, int min_h, int max_w, int max_h)
+

Source Code

+

Constrains a non-fullscreen resizable display. The constraints are a hint only, and are not necessarily respected by the window environment. A value of 0 for any of the parameters indicates no constraint for that parameter.

+

The constraints will be applied to a display only after the al_apply_window_constraints function call.

+

Since: 5.1.0

+

See also: al_apply_window_constraints, al_get_window_constraints

+

Examples:

+ +

al_apply_window_constraints

+
void al_apply_window_constraints(ALLEGRO_DISPLAY *display, bool onoff)
+

Source Code

+

Enable or disable previously set constraints by al_set_window_constraints function.

+

If enabled, the specified display will be automatically resized to new sizes to conform constraints in next cases:

+
    +
  • The specified display is resizable, not maximized and is not in fullscreen mode.
  • +
  • If the appropriate current display size (width or height) is less than the value of constraint. Applied to minimum constraints.
  • +
  • If the appropriate current display size (width or height) is greater than the value of constraint. Applied to maximum constraints.
  • +
+

Constrains are not applied when a display is toggle from windowed to maximized or fullscreen modes. When a display is toggle from maximized/fullscreen to windowed mode, then the display may be resized as described above. The later case is also possible when a user drags the maximized display via mouse.

+

If disabled, the specified display will stop using constraints.

+

See also: al_get_window_constraints, al_set_window_constraints

+

Examples:

+ +

Display settings

+

al_get_display_flags

+
int al_get_display_flags(ALLEGRO_DISPLAY *display)
+

Source Code

+

Gets the flags of the display.

+

In addition to the flags set for the display at creation time with al_set_new_display_flags it can also have the ALLEGRO_MINIMIZED flag set, indicating that the window is currently minimized. This flag is very platform-dependent as even a minimized application may still render a preview version so normally you should not care whether it is minimized or not.

+

See also: al_set_new_display_flags, al_set_display_flag

+

Examples:

+ +

al_set_display_flag

+
bool al_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)
+

Source Code

+

Enable or disable one of the display flags. The flags are the same as for al_set_new_display_flags. The only flags that can be changed after creation are:

+
    +
  • ALLEGRO_FULLSCREEN_WINDOW
  • +
  • ALLEGRO_FRAMELESS
  • +
  • ALLEGRO_MAXIMIZED
  • +
+

Returns true if the driver supports toggling the specified flag else false. You can use al_get_display_flags to query whether the given display property actually changed.

+

Since: 5.0.7, 5.1.2

+

See also: al_set_new_display_flags, al_get_display_flags

+

Examples:

+ +

al_get_display_option

+
int al_get_display_option(ALLEGRO_DISPLAY *display, int option)
+

Source Code

+

Return an extra display setting of the display.

+

See also: al_set_new_display_option

+

Examples:

+ +

al_set_display_option

+
void al_set_display_option(ALLEGRO_DISPLAY *display, int option, int value)
+

Source Code

+

Change an option that was previously set for a display. After displays are created, they take on the options set with al_set_new_display_option. Calling al_set_new_display_option subsequently only changes options for newly created displays, and doesn’t touch the options of already created displays. al_set_display_option allows changing some of these values. Not all display options can be changed or changing them will have no effect. Changing options other than those listed below is undefined.

+
    +
  • ALLEGRO_SUPPORTED_ORIENTATIONS - This can be changed to allow new or restrict previously enabled orientations of the screen/device. See al_set_new_display_option for more information on this option.
  • +
+

Since: 5.1.5

+

See also: al_set_new_display_option

+

al_get_display_format

+
int al_get_display_format(ALLEGRO_DISPLAY *display)
+

Source Code

+

Gets the pixel format of the display.

+

See also: ALLEGRO_PIXEL_FORMAT

+

Examples:

+ +

al_get_display_orientation

+
int al_get_display_orientation(ALLEGRO_DISPLAY* display)
+

Source Code

+

Return the display orientation, which can be one of the following:

+
    +
  • ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_FACE_UP
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN
  • +
+

Since: 5.1.0

+

al_get_display_refresh_rate

+
int al_get_display_refresh_rate(ALLEGRO_DISPLAY *display)
+

Source Code

+

Gets the refresh rate of the display.

+

See also: al_set_new_display_refresh_rate

+

al_set_window_title

+
void al_set_window_title(ALLEGRO_DISPLAY *display, const char *title)
+

Source Code

+

Set the title on a display.

+

See also: al_set_display_icon, al_set_display_icons

+

Examples:

+ +

al_set_new_window_title

+
void al_set_new_window_title(const char *title)
+

Source Code

+

Set the title that will be used when a new display is created. Allegro uses a static buffer of ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE to store this, so the length of the titme you set must be less than this.

+

See also: al_set_window_title, al_get_new_window_title, al_create_display, ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE

+

Since: 5.1.12

+

Examples:

+ +

ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE

+
#define ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE 255
+

Source Code

+

This is the maximum size of the title that can be set with al_set_new_window_title.

+

See also: al_set_new_window_title

+

Since: 5.1.12

+

al_get_new_window_title

+
const char *al_get_new_window_title(void)
+

Source Code

+

Returns the title that will be used when a new display is created. This returns the value that al_set_window_title was called with. If that function wasn’t called yet, the value of al_get_app_name is returned as a default. The current implementation returns a pointer to a static buffer of which you should make a copy if you want to modify it.

+

See also: al_set_window_title, al_set_new_window_title, al_create_display

+

Since: 5.1.12

+

Examples:

+ +

al_set_display_icon

+
void al_set_display_icon(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon)
+

Source Code

+

Changes the icon associated with the display (window). Same as al_set_display_icons with one icon.

+

See also: al_set_display_icons, al_set_window_title

+

Examples:

+ +

al_set_display_icons

+
void al_set_display_icons(ALLEGRO_DISPLAY *display,
+   int num_icons, ALLEGRO_BITMAP *icons[])
+

Source Code

+

Changes the icons associated with the display (window). Multiple icons can be provided for use in different contexts, e.g. window frame, taskbar, alt-tab popup. The number of icons must be at least one.

+
+

Note: If the underlying OS requires an icon of a size not provided then one of the bitmaps will be scaled up or down to the required size. The choice of bitmap is implementation dependent.

+
+

Since: 5.0.9, 5.1.5

+

See also: al_set_display_icon, al_set_window_title

+

Examples:

+ +

Drawing halts

+

al_acknowledge_drawing_halt

+
void al_acknowledge_drawing_halt(ALLEGRO_DISPLAY *display)
+

Source Code

+

Call this in response to the ALLEGRO_EVENT_DISPLAY_HALT_DRAWING event. This is currently necessary for Android and iOS as you are not allowed to draw to your display while it is not being shown. If you do not call this function to let the operating system know that you have stopped drawing or if you call it to late the application likely will be considered misbehaving and get terminated.

+

Since: 5.1.0

+

See also: ALLEGRO_EVENT_DISPLAY_HALT_DRAWING

+

Examples:

+ +

al_acknowledge_drawing_resume

+
void al_acknowledge_drawing_resume(ALLEGRO_DISPLAY *display)
+

Source Code

+

Call this in response to the ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING event.

+

Since: 5.1.1

+

See also: ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING

+

Examples:

+ +

Screensaver

+

al_inhibit_screensaver

+
bool al_inhibit_screensaver(bool inhibit)
+

Source Code

+

This function allows the user to stop the system screensaver from starting up if true is passed, or resets the system back to the default state (the state at program start) if false is passed. It returns true if the state was set successfully, otherwise false.

+

Examples:

+ +

Clipboard

+

With the clipboard API of Allegro, text can be copied from and to the clipboard. Currentlly, only UTF8 encoded text is supported. It currently works on Linux, Windows, OSX, Android and IOS.

+

al_get_clipboard_text

+
char *al_get_clipboard_text(ALLEGRO_DISPLAY *display)
+

Source Code

+

This function returns a pointer to a string, allocated with al_malloc with the text contents of the clipboard if available. If no text is available on the clipboard then this function returns NULL. You must call al_free on the returned pointer when you don’t need it anymore.

+

Beware that text on the clipboard on Windows may be in Windows format, that is, it may have carriage return newline combinations for the line endings instead of regular newlines for the line endings on Linux or OSX.

+

Since: 5.1.12

+

See also: al_set_clipboard_text, al_clipboard_has_text

+

Examples:

+ +

al_set_clipboard_text

+
bool al_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text)
+

Source Code

+

This function pastes the text given as an argument to the clipboard.

+

Since: 5.1.12

+

See also: al_get_clipboard_text, al_clipboard_has_text

+

Examples:

+ +

al_clipboard_has_text

+
bool al_clipboard_has_text(ALLEGRO_DISPLAY *display)
+

Source Code

+

This function returns true if and only if the clipboard has text available.

+

Since: 5.1.12

+

See also: al_set_clipboard_text, al_get_clipboard_text

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/events.html b/allegro/docs/html/refman/events.html new file mode 100644 index 00000000..0c6d8f72 --- /dev/null +++ b/allegro/docs/html/refman/events.html @@ -0,0 +1,986 @@ + + + + + + + Event system and events + + + + + + + + +
+ + +
+

Event system and events

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

Events are generated by event sources. Most notably, each of the input subsystems provides an event source, but also timers, displays, and audio streams will generate events.

+

Event sources are registered to event queues which aggregate events from multiple sources. A single event source can also be registered to multiple event queues.

+

Event queues can then be queried for events. In particular, it is possible to wait until events become available in order to save CPU time. You can combine this with timers to make your main-loop run at a specific speed without wasting CPU time or missing events.

+

In addition to the predefined event types, Allegro also allows for user-defined events that can be generated by user-defined event sources.

+

The appropriate reaction to an event is determined by examining the fields of the ALLEGRO_EVENT union according to the event type.

+

In addition to the events sent by Allegro core, there’s also events send by the addons, see ALLEGRO_AUDIO_EVENT_TYPE and ALLEGRO_VIDEO_EVENT_TYPE.

+

ALLEGRO_EVENT

+
typedef union ALLEGRO_EVENT ALLEGRO_EVENT;
+

Source Code

+

An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common:

+
+
type (ALLEGRO_EVENT_TYPE)
+
Indicates the type of event. +
+
any.source (ALLEGRO_EVENT_SOURCE *)
+
The event source which generated the event. +
+
any.timestamp (double)
+
When the event was generated. +
+
+

By examining the type field you can then access type-specific fields. The any.source field tells you which event source generated that particular event. The any.timestamp field tells you when the event was generated. The time is referenced to the same starting point as al_get_time.

+

Each event is of one of the following types, with the usable fields given.

+

Examples:

+ +

ALLEGRO_EVENT_JOYSTICK_AXIS

+

A joystick axis value changed.

+
+
joystick.id (ALLEGRO_JOYSTICK *)
+
The joystick which generated the event. This is not the same as the event source joystick.source. +
+
joystick.stick (int)
+
The stick number, counting from zero. Axes on a joystick are grouped into “sticks”. +
+
joystick.axis (int)
+
The axis number on the stick, counting from zero. +
+
joystick.pos (float)
+
The axis position, from -1.0 to +1.0. +
+
+

ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN

+

A joystick button was pressed.

+
+
joystick.id (ALLEGRO_JOYSTICK *)
+
The joystick which generated the event. +
+
joystick.button (int)
+
The button which was pressed, counting from zero. +
+
+

ALLEGRO_EVENT_JOYSTICK_BUTTON_UP

+

A joystick button was released.

+
+
joystick.id (ALLEGRO_JOYSTICK *)
+
The joystick which generated the event. +
+
joystick.button (int)
+
The button which was released, counting from zero. +
+
+

ALLEGRO_EVENT_JOYSTICK_CONFIGURATION

+

A joystick was plugged in or unplugged. See al_reconfigure_joysticks for details.

+

ALLEGRO_EVENT_KEY_DOWN

+

A keyboard key was pressed.

+
+
keyboard.keycode (int)
+
The code corresponding to the physical key which was pressed. See the Key codes section for the list of ALLEGRO_KEY_* constants. +
+
keyboard.display (ALLEGRO_DISPLAY *)
+
The display which had keyboard focus when the event occurred. +
+
+
+

Note: this event is about the physical keys being pressed on the keyboard. Look for ALLEGRO_EVENT_KEY_CHAR events for character input.

+
+

ALLEGRO_EVENT_KEY_UP

+

A keyboard key was released.

+
+
keyboard.keycode (int)
+
The code corresponding to the physical key which was released. See the Key codes section for the list of ALLEGRO_KEY_* constants. +
+
keyboard.display (ALLEGRO_DISPLAY *)
+
The display which had keyboard focus when the event occurred. +
+
+

ALLEGRO_EVENT_KEY_CHAR

+

A character was typed on the keyboard, or a character was auto-repeated.

+
+
keyboard.keycode (int)
+
The code corresponding to the physical key which was last pressed. See the Key codes section for the list of ALLEGRO_KEY_* constants. +
+
keyboard.unichar (int)
+

A Unicode code point (character). This may be zero or negative if the event was generated for a non-visible “character”, such as an arrow or Function key. In that case you can act upon the keycode field.

+

Some special keys will set the unichar field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the unichar field will have the values 1 to 26. For example Ctrl-A will set unichar to 1 and Ctrl-H will set it to 8.

+

As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the keycode field.

+
+
keyboard.modifiers (unsigned)
+
This is a bitfield of the modifier keys which were pressed when the event occurred. See “Keyboard modifier flags” for the constants. +
+
keyboard.repeat (bool)
+
Indicates if this is a repeated character. +
+
keyboard.display (ALLEGRO_DISPLAY *)
+
The display which had keyboard focus when the event occurred. +
+
+
+

Note: in many input methods, characters are not entered one-for-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce ‘é’. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases.

+
+

ALLEGRO_EVENT_MOUSE_AXES

+

One or more mouse axis values changed.

+
+
mouse.x (int)
+
x-coordinate +
+
mouse.y (int)
+
y-coordinate +
+
mouse.z (int)
+
z-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative. +
+
mouse.w (int)
+
w-coordinate. This usually means the horizontal axis of a mouse wheel. +
+
mouse.dx (int)
+
Change in the x-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. +
+
mouse.dy (int)
+
Change in the y-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. +
+
mouse.dz (int)
+
Change in the z-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. +
+
mouse.dw (int)
+
Change in the w-coordinate value since the previous ALLEGRO_EVENT_MOUSE_AXES event. +
+
mouse.pressure (float)
+
Pressure, ranging from 0.0 to 1.0. +
+
mouse.display (ALLEGRO_DISPLAY *)
+
The display which had mouse focus. +
+
+
+

Note: Calling al_set_mouse_xy also will result in a change of axis values, but such a change is reported with ALLEGRO_EVENT_MOUSE_WARPED events instead which are identical except for their type.

+
+
+

Note: currently mouse.display may be NULL if an event is generated in response to al_set_mouse_axis.

+
+

ALLEGRO_EVENT_MOUSE_BUTTON_DOWN

+

A mouse button was pressed.

+
+
mouse.x (int)
+
x-coordinate +
+
mouse.y (int)
+
y-coordinate +
+
mouse.z (int)
+
z-coordinate +
+
mouse.w (int)
+
w-coordinate +
+
mouse.button (unsigned)
+
The mouse button which was pressed, numbering from 1. +
+
mouse.pressure (float)
+
Pressure, ranging from 0.0 to 1.0. +
+
mouse.display (ALLEGRO_DISPLAY *)
+
The display which had mouse focus. +
+
+

ALLEGRO_EVENT_MOUSE_BUTTON_UP

+

A mouse button was released.

+
+
mouse.x (int)
+
x-coordinate +
+
mouse.y (int)
+
y-coordinate +
+
mouse.z (int)
+
z-coordinate +
+
mouse.w (int)
+
w-coordinate +
+
mouse.button (unsigned)
+
The mouse button which was released, numbering from 1. +
+
mouse.pressure (float)
+
Pressure, ranging from 0.0 to 1.0. +
+
mouse.display (ALLEGRO_DISPLAY *)
+
The display which had mouse focus. +
+
+

ALLEGRO_EVENT_MOUSE_WARPED

+

al_set_mouse_xy was called to move the mouse. This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise.

+

ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY

+

The mouse cursor entered a window opened by the program.

+
+
mouse.x (int)
+
x-coordinate +
+
mouse.y (int)
+
y-coordinate +
+
mouse.z (int)
+
z-coordinate +
+
mouse.w (int)
+
w-coordinate +
+
mouse.display (ALLEGRO_DISPLAY *)
+
The display which had mouse focus. +
+
+

ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY

+

The mouse cursor left the boundaries of a window opened by the program.

+
+
mouse.x (int)
+
x-coordinate +
+
mouse.y (int)
+
y-coordinate +
+
mouse.z (int)
+
z-coordinate +
+
mouse.w (int)
+
w-coordinate +
+
mouse.display (ALLEGRO_DISPLAY *)
+
The display which had mouse focus. +
+
+

ALLEGRO_EVENT_TOUCH_BEGIN

+

The touch input device registered a new touch.

+
+
touch.display (ALLEGRO_DISPLAY)
+
The display which was touched. +
+
touch.id (int)
+
An identifier for this touch. If supported by the device it will stay the same for events from the same finger until the touch ends. +
+
touch.x (float)
+
The x coordinate of the touch in pixels. +
+
touch.y (float)
+
The y coordinate of the touch in pixels. +
+
touch.dx (float)
+
Movement speed in pixels in x direction. +
+
touch.dy (float)
+
Movement speed in pixels in y direction. +
+
touch.primary (bool)
+
Whether this is the only/first touch or an additional touch. +
+
+

Since: 5.1.0

+

ALLEGRO_EVENT_TOUCH_END

+

A touch ended.

+

Has the same fields as ALLEGRO_EVENT_TOUCH_BEGIN.

+

Since: 5.1.0

+

ALLEGRO_EVENT_TOUCH_MOVE

+

The position of a touch changed.

+

Has the same fields as ALLEGRO_EVENT_TOUCH_BEGIN.

+

Since: 5.1.0

+

ALLEGRO_EVENT_TOUCH_CANCEL

+

A touch was cancelled. This is device specific but could for example mean that a finger moved off the border of the device or moved so fast that it could not be tracked any longer.

+

Has the same fields as ALLEGRO_EVENT_TOUCH_BEGIN.

+

Since: 5.1.0

+

ALLEGRO_EVENT_TIMER

+

A timer counter incremented.

+
+
timer.source (ALLEGRO_TIMER *)
+
The timer which generated the event. +
+
timer.count (int64_t)
+
The timer count value. +
+
+

ALLEGRO_EVENT_DISPLAY_EXPOSE

+

The display (or a portion thereof) has become visible.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was exposed. +
+
display.x (int)
+
The X position of the top-left corner of the rectangle which was exposed. +
+
display.y (int)
+
The Y position of the top-left corner of the rectangle which was exposed. +
+
display.width (int)
+
The width of the rectangle which was exposed. +
+
display.height (int)
+
The height of the rectangle which was exposed. +
+
+
+

Note: The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated.

+
+

ALLEGRO_EVENT_DISPLAY_RESIZE

+

The window has been resized.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was resized. +
+
display.x (int)
+
The X position of the top-left corner of the display. +
+
display.y (int)
+
The Y position of the top-left corner of the display. +
+
display.width (int)
+
The new width of the display. +
+
display.height (int)
+
The new height of the display. +
+
+

You should normally respond to these events by calling al_acknowledge_resize. Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information.

+

ALLEGRO_EVENT_DISPLAY_CLOSE

+

The close button of the window has been pressed.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was closed. +
+
+

ALLEGRO_EVENT_DISPLAY_LOST

+

When using Direct3D, displays can enter a “lost” state. In that state, drawing calls are ignored, and upon entering the state, bitmap’s pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see the ALLEGRO_NO_PRESERVE_TEXTURE flag) and restore them when the device is “found” (see ALLEGRO_EVENT_DISPLAY_FOUND). However, this is not 100% fool proof (see discussion in al_create_bitmap’s documentation).

+
+

Note: This event merely means that the display was lost, that is, DirectX suddenly lost the contents of all video bitmaps. In particular, you can keep calling drawing functions – they just most likely won’t do anything. If Allegro’s restoration of the bitmaps works well for you then no further action is required when you receive this event.

+
+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was lost. +
+
+

ALLEGRO_EVENT_DISPLAY_FOUND

+

Generated when a lost device is restored to operating state. See ALLEGRO_EVENT_DISPLAY_LOST.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was found. +
+
+

ALLEGRO_EVENT_DISPLAY_SWITCH_OUT

+

The window is no longer active, that is the user might have clicked into another window or “tabbed” away. In response to this event you might want to call al_clear_keyboard_state (possibly passing display.source as its argument) in order to prevent Allegro’s keyboard state from getting out of sync.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was switched out of. +
+
+

ALLEGRO_EVENT_DISPLAY_SWITCH_IN

+

The window is the active one again.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was switched into. +
+
+

ALLEGRO_EVENT_DISPLAY_ORIENTATION

+

Generated when the rotation or orientation of a display changes.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which generated the event. +
+
event.display.orientation
+

Contains one of the following values:

+
    +
  • ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_FACE_UP
  • +
  • ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN
  • +
+
+
+

ALLEGRO_EVENT_DISPLAY_HALT_DRAWING

+

When a display receives this event it should stop doing any drawing and then call al_acknowledge_drawing_halt immediately.

+

This is currently only relevant for Android and iOS. It will be sent when the application is switched to background mode, in addition to ALLEGRO_EVENT_DISPLAY_SWITCH_OUT. The latter may also be sent in situations where the application is not active but still should continue drawing, for example when a popup is displayed in front of it.

+
+

Note: This event means that the next time you call a drawing function, your program will crash. So you must stop drawing and you must immediately reply with al_acknowledge_drawing_halt. Allegro sends this event because it cannot handle this automatically. Your program might be doing the drawing in a different thread from the event handling, in which case the drawing thread needs to be signaled to stop drawing before acknowledging this event.

+
+
+

Note: Mobile devices usually never quit an application, so to prevent the battery from draining while your application is halted it can be a good idea to call al_stop_timer on all your timers, otherwise they will keep generating events. If you are using audio, you can also stop all audio voices (or pass NULL to al_set_default_voice if you use the default mixer), otherwise Allegro will keep streaming silence to the voice even if the stream or mixer are stopped or detached.

+
+

Since: 5.1.0

+

See also: ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING

+

ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING

+

When a display receives this event, it may resume drawing again, and it must call al_acknowledge_drawing_resume immediately.

+

This is currently only relevant for Android and iOS. The event will be sent when an application returns from background mode and is allowed to draw to the display again, in addition to ALLEGRO_EVENT_DISPLAY_SWITCH_IN. The latter event may also be sent in a situation where the application is already active, for example when a popup in front of it closes.

+
+

Note: Unlike ALLEGRO_EVENT_DISPLAY_FOUND it is not necessary to reload any bitmaps when you receive this event.

+
+

Since: 5.1.0

+

See also: ALLEGRO_EVENT_DISPLAY_HALT_DRAWING

+

ALLEGRO_EVENT_DISPLAY_CONNECTED

+

This event is sent when a physical display is connected to the device Allegro runs on. Currently, on most platforms, Allegro supports only a single physical display. However, on iOS, a secondary physical display is supported.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was connected. +
+
+

Since: 5.1.1

+

ALLEGRO_EVENT_DISPLAY_DISCONNECTED

+

This event is sent when a physical display is disconnected from the device Allegro runs on. Currently, on most platforms, Allegro supports only a single physical display. However, on iOS, a secondary physical display is supported.

+
+
display.source (ALLEGRO_DISPLAY *)
+
The display which was disconnected. +
+
+

ALLEGRO_USER_EVENT

+
typedef struct ALLEGRO_USER_EVENT ALLEGRO_USER_EVENT;
+

Source Code

+

An event structure that can be emitted by user event sources. These are the public fields:

+
    +
  • ALLEGRO_EVENT_SOURCE *source;
  • +
  • intptr_t data1;
  • +
  • intptr_t data2;
  • +
  • intptr_t data3;
  • +
  • intptr_t data4;
  • +
+

Like all other event types this structure is a part of the ALLEGRO_EVENT union. To access the fields in an ALLEGRO_EVENT variable ev, you would use:

+
    +
  • ev.user.source
  • +
  • ev.user.data1
  • +
  • ev.user.data2
  • +
  • ev.user.data3
  • +
  • ev.user.data4
  • +
+

To create a new user event you would do this:

+
ALLEGRO_EVENT_SOURCE my_event_source;
+ALLEGRO_EVENT my_event;
+float some_var;
+
+al_init_user_event_source(&my_event_source);
+
+my_event.user.type = ALLEGRO_GET_EVENT_TYPE('M','I','N','E');
+my_event.user.data1 = 1;
+my_event.user.data2 = &some_var;
+
+al_emit_user_event(&my_event_source, &my_event, NULL);
+

Event type identifiers for user events are assigned by the user. Please see the documentation for ALLEGRO_GET_EVENT_TYPE for the rules you should follow when assigning identifiers.

+

See also: al_emit_user_event, ALLEGRO_GET_EVENT_TYPE, al_init_user_event_source

+

Examples:

+ +

ALLEGRO_EVENT_QUEUE

+
typedef struct ALLEGRO_EVENT_QUEUE ALLEGRO_EVENT_QUEUE;
+

Source Code

+

An event queue holds events that have been generated by event sources that are registered with the queue. Events are stored in the order they are generated. Access is in a strictly FIFO (first-in-first-out) order.

+

See also: al_create_event_queue, al_destroy_event_queue

+

Examples:

+ +

ALLEGRO_EVENT_SOURCE

+
typedef struct ALLEGRO_EVENT_SOURCE ALLEGRO_EVENT_SOURCE;
+

Source Code

+

An event source is any object which can generate events. For example, an ALLEGRO_DISPLAY can generate events, and you can get the ALLEGRO_EVENT_SOURCE pointer from an ALLEGRO_DISPLAY with al_get_display_event_source.

+

You may create your own “user” event sources that emit custom events.

+

See also: ALLEGRO_EVENT, al_init_user_event_source, al_emit_user_event

+

Examples:

+ +

ALLEGRO_EVENT_TYPE

+
typedef unsigned int ALLEGRO_EVENT_TYPE;
+

Source Code

+

An integer used to distinguish between different types of events.

+

See also: ALLEGRO_EVENT, ALLEGRO_GET_EVENT_TYPE, ALLEGRO_EVENT_TYPE_IS_USER

+

ALLEGRO_GET_EVENT_TYPE

+
#define ALLEGRO_GET_EVENT_TYPE(a, b, c, d)   AL_ID(a, b, c, d)
+

Source Code

+

Make an event type identifier, which is a 32-bit integer. Usually, but not necessarily, this will be made from four 8-bit character codes, for example:

+
Examples:
+
+* [ex_user_events.c](https://github.com/liballeg/allegro5/blob/master/examples/ex_user_events.c#L10)
+* [ex_native_filechooser.c](https://github.com/liballeg/allegro5/blob/master/examples/ex_native_filechooser.c#L20)
+
+#defin  MY_EVENT_TYPE   ALLEGRO_GET_EVENT_TYPE('M','I','N','E')
+

IDs less than 1024 are reserved for Allegro or its addons. Don’t use anything lower than ALLEGRO_GET_EVENT_TYPE(0, 0, 4, 0).

+

You should try to make your IDs unique so they don’t clash with any 3rd party code you may be using. Be creative. Numbering from 1024 is not creative.

+

If you need multiple identifiers, you could define them like this:

+
#defin  BASE_EVENT   ALLEGRO_GET_EVENT_TYPE('M','I','N','E')
+#defin  BARK_EVENT   (BASE_EVENT + 0)
+#defin  MEOW_EVENT   (BASE_EVENT + 1)
+#defin  SQUAWK_EVENT (BASE_EVENT + 2)
+
+/* Alternatively */
+enum {
+   BARK_EVENT = ALLEGRO_GET_EVENT_TYPE('M','I','N','E'),
+   MEOW_EVENT,
+   SQUAWK_EVENT
+};
+

See also: ALLEGRO_EVENT, ALLEGRO_USER_EVENT, ALLEGRO_EVENT_TYPE_IS_USER

+

ALLEGRO_EVENT_TYPE_IS_USER

+
#define ALLEGRO_EVENT_TYPE_IS_USER(t)        ((t) >= 512)
+

Source Code

+

A macro which evaluates to true if the event type is not a builtin event type, i.e. one of those described in ALLEGRO_EVENT_TYPE.

+

al_create_event_queue

+
ALLEGRO_EVENT_QUEUE *al_create_event_queue(void)
+

Source Code

+

Create a new, empty event queue, returning a pointer to the newly created object if successful. Returns NULL on error.

+

See also: al_register_event_source, al_destroy_event_queue, ALLEGRO_EVENT_QUEUE

+

Examples:

+ +

al_destroy_event_queue

+
void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue)
+

Source Code

+

Destroy the event queue specified. All event sources currently registered with the queue will be automatically unregistered before the queue is destroyed.

+

See also: al_create_event_queue, ALLEGRO_EVENT_QUEUE

+

Examples:

+ +

al_register_event_source

+
void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue,
+   ALLEGRO_EVENT_SOURCE *source)
+

Source Code

+

Register the event source with the event queue specified. An event source may be registered with any number of event queues simultaneously, or none. Trying to register an event source with the same event queue more than once does nothing.

+

See also: al_unregister_event_source, ALLEGRO_EVENT_SOURCE

+

Examples:

+ +

al_unregister_event_source

+
void al_unregister_event_source(ALLEGRO_EVENT_QUEUE *queue,
+   ALLEGRO_EVENT_SOURCE *source)
+

Source Code

+

Unregister an event source with an event queue. If the event source is not actually registered with the event queue, nothing happens.

+

If the queue had any events in it which originated from the event source, they will no longer be in the queue after this call.

+

See also: al_register_event_source

+

Examples:

+ +

al_is_event_source_registered

+
bool al_is_event_source_registered(ALLEGRO_EVENT_QUEUE *queue, 
+      ALLEGRO_EVENT_SOURCE *source)
+

Source Code

+

Return true if the event source is registered.

+

See also: al_register_event_source

+

Since: 5.2.0

+

al_pause_event_queue

+
void al_pause_event_queue(ALLEGRO_EVENT_QUEUE *queue, bool pause)
+

Source Code

+

Pause or resume accepting new events into the event queue (to resume, pass false for pause). Events already in the queue are unaffected.

+

While a queue is paused, any events which would be entered into the queue are simply ignored. This is an alternative to unregistering then re-registering all event sources from the event queue, if you just need to prevent events piling up in the queue for a while.

+

See also: al_is_event_queue_paused

+

Since: 5.1.0

+

al_is_event_queue_paused

+
bool al_is_event_queue_paused(const ALLEGRO_EVENT_QUEUE *queue)
+

Source Code

+

Return true if the event queue is paused.

+

See also: al_pause_event_queue

+

Since: 5.1.0

+

al_is_event_queue_empty

+
bool al_is_event_queue_empty(ALLEGRO_EVENT_QUEUE *queue)
+

Source Code

+

Return true if the event queue specified is currently empty.

+

See also: al_get_next_event, al_peek_next_event

+

Examples:

+ +

al_get_next_event

+
bool al_get_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)
+

Source Code

+

Take the next event out of the event queue specified, and copy the contents into ret_event, returning true. The original event will be removed from the queue. If the event queue is empty, return false and the contents of ret_event are unspecified.

+

See also: ALLEGRO_EVENT, al_peek_next_event, al_wait_for_event

+

Examples:

+ +

al_peek_next_event

+
bool al_peek_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)
+

Source Code

+

Copy the contents of the next event in the event queue specified into ret_event and return true. The original event packet will remain at the head of the queue. If the event queue is actually empty, this function returns false and the contents of ret_event are unspecified.

+

See also: ALLEGRO_EVENT, al_get_next_event, al_drop_next_event

+

al_drop_next_event

+
bool al_drop_next_event(ALLEGRO_EVENT_QUEUE *queue)
+

Source Code

+

Drop (remove) the next event from the queue. If the queue is empty, nothing happens. Returns true if an event was dropped.

+

See also: al_flush_event_queue, al_is_event_queue_empty

+

al_flush_event_queue

+
void al_flush_event_queue(ALLEGRO_EVENT_QUEUE *queue)
+

Source Code

+

Drops all events, if any, from the queue.

+

See also: al_drop_next_event, al_is_event_queue_empty

+

Examples:

+ +

al_wait_for_event

+
void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)
+

Source Code

+

Wait until the event queue specified is non-empty. If ret_event is not NULL, the first event in the queue will be copied into ret_event and removed from the queue. If ret_event is NULL the first event is left at the head of the queue.

+

See also: ALLEGRO_EVENT, al_wait_for_event_timed, al_wait_for_event_until, al_get_next_event

+

Examples:

+ +

al_wait_for_event_timed

+
bool al_wait_for_event_timed(ALLEGRO_EVENT_QUEUE *queue,
+   ALLEGRO_EVENT *ret_event, float secs)
+

Source Code

+

Wait until the event queue specified is non-empty. If ret_event is not NULL, the first event in the queue will be copied into ret_event and removed from the queue. If ret_event is NULL the first event is left at the head of the queue.

+

secs determines approximately how many seconds to wait. If the call times out, false is returned. Otherwise, if an event ocurred, true is returned.

+

For compatibility with all platforms, secs must be 2,147,483.647 seconds or less.

+

See also: ALLEGRO_EVENT, al_wait_for_event, al_wait_for_event_until

+

Examples:

+ +

al_wait_for_event_until

+
bool al_wait_for_event_until(ALLEGRO_EVENT_QUEUE *queue,
+   ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout)
+

Source Code

+

Wait until the event queue specified is non-empty. If ret_event is not NULL, the first event in the queue will be copied into ret_event and removed from the queue. If ret_event is NULL the first event is left at the head of the queue.

+

timeout determines how long to wait. If the call times out, false is returned. Otherwise, if an event ocurred, true is returned.

+

For compatibility with all platforms, timeout must be 2,147,483.647 seconds or less.

+

See also: ALLEGRO_EVENT, ALLEGRO_TIMEOUT, al_init_timeout, al_wait_for_event, al_wait_for_event_timed

+

Examples:

+ +

al_init_user_event_source

+
void al_init_user_event_source(ALLEGRO_EVENT_SOURCE *src)
+

Source Code

+

Initialise an event source for emitting user events. The space for the event source must already have been allocated.

+

One possible way of creating custom event sources is to derive other structures with ALLEGRO_EVENT_SOURCE at the head, e.g.

+
typedef struct THING THING;
+
+struct THING {
+    ALLEGRO_EVENT_SOURCE event_source;
+    int field1;
+    int field2;
+    /* etc. */
+};
+
+THING *create_thing(void)
+{
+    THING *thing = malloc(sizeof(THING));
+
+    if (thing) {
+        al_init_user_event_source(&thing->event_source);
+        thing->field1 = 0;
+        thing->field2 = 0;
+    }
+
+    return thing;
+}
+

The advantage here is that the THING pointer will be the same as the ALLEGRO_EVENT_SOURCE pointer. Events emitted by the event source will have the event source pointer as the source field, from which you can get a pointer to a THING by a simple cast (after ensuring checking the event is of the correct type).

+

However, it is only one technique and you are not obliged to use it.

+

The user event source will never be destroyed automatically. You must destroy it manually with al_destroy_user_event_source.

+

See also: ALLEGRO_EVENT_SOURCE, al_destroy_user_event_source, al_emit_user_event, ALLEGRO_USER_EVENT

+

Examples:

+ +

al_destroy_user_event_source

+
void al_destroy_user_event_source(ALLEGRO_EVENT_SOURCE *src)
+

Source Code

+

Destroy an event source initialised with al_init_user_event_source.

+

This does not free the memory, as that was user allocated to begin with.

+

See also: ALLEGRO_EVENT_SOURCE

+

Examples:

+ +

al_emit_user_event

+
bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src,
+   ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *))
+

Source Code

+

Emit an event from a user event source. The event source must have been initialised with al_init_user_event_source. Returns false if the event source isn’t registered with any queues, hence the event wouldn’t have been delivered into any queues.

+

Events are copied in and out of event queues, so after this function returns the memory pointed to by event may be freed or reused. Some fields of the event being passed in may be modified by the function.

+

Reference counting will be performed if dtor is not NULL. Whenever a copy of the event is made, the reference count increases. You need to call al_unref_user_event to decrease the reference count once you are done with a user event that you have received from al_get_next_event, al_peek_next_event, al_wait_for_event, etc.

+

Once the reference count drops to zero dtor will be called with a copy of the event as an argument. It should free the resources associated with the event, but not the event itself (since it is just a copy).

+

If dtor is NULL then reference counting will not be performed. It is safe, but unnecessary, to call al_unref_user_event on non-reference counted user events.

+

You can use al_emit_user_event to emit both user and non-user events from your user event source. Note that emitting input events will not update the corresponding input device states. For example, you may emit an event of type ALLEGRO_EVENT_KEY_DOWN, but it will not update the ALLEGRO_KEYBOARD_STATE returned by al_get_keyboard_state.

+

See also: ALLEGRO_USER_EVENT, al_unref_user_event

+

Examples:

+ +

al_unref_user_event

+
void al_unref_user_event(ALLEGRO_USER_EVENT *event)
+

Source Code

+

Decrease the reference count of a user-defined event. This must be called on any user event that you get from al_get_next_event, al_peek_next_event, al_wait_for_event, etc. which is reference counted. This function does nothing if the event is not reference counted.

+

See also: al_emit_user_event, ALLEGRO_USER_EVENT

+

Examples:

+ +

al_get_event_source_data

+
intptr_t al_get_event_source_data(const ALLEGRO_EVENT_SOURCE *source)
+

Source Code

+

Returns the abstract user data associated with the event source. If no data was previously set, returns NULL.

+

See also: al_set_event_source_data

+

al_set_event_source_data

+
void al_set_event_source_data(ALLEGRO_EVENT_SOURCE *source, intptr_t data)
+

Source Code

+

Assign the abstract user data to the event source. Allegro does not use the data internally for anything; it is simply meant as a convenient way to associate your own data or objects with events.

+

See also: al_get_event_source_data

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/file.html b/allegro/docs/html/refman/file.html new file mode 100644 index 00000000..24adea4a --- /dev/null +++ b/allegro/docs/html/refman/file.html @@ -0,0 +1,647 @@ + + + + + + + File I/O + + + + + + + + +
+ + +
+

File I/O

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_FILE

+
typedef struct ALLEGRO_FILE ALLEGRO_FILE;
+

Source Code

+

An opaque object representing an open file. This could be a real file on disk or a virtual file.

+

Examples:

+ +

ALLEGRO_FILE_INTERFACE

+
typedef struct ALLEGRO_FILE_INTERFACE
+

Source Code

+

A structure containing function pointers to handle a type of “file”, real or virtual. See the full discussion in al_set_new_file_interface.

+

The fields are:

+
void*         (*fi_fopen)(const char *path, const char *mode);
+bool          (*fi_fclose)(ALLEGRO_FILE *f);
+size_t        (*fi_fread)(ALLEGRO_FILE *f, void *ptr, size_t size);
+size_t        (*fi_fwrite)(ALLEGRO_FILE *f, const void *ptr, size_t size);
+bool          (*fi_fflush)(ALLEGRO_FILE *f);
+int64_t       (*fi_ftell)(ALLEGRO_FILE *f);
+bool          (*fi_fseek)(ALLEGRO_FILE *f, int64_t offset, int whence);
+bool          (*fi_feof)(ALLEGRO_FILE *f);
+int           (*fi_ferror)(ALLEGRO_FILE *f);
+const char *  (*fi_ferrmsg)(ALLEGRO_FILE *f);
+void          (*fi_fclearerr)(ALLEGRO_FILE *f);
+int           (*fi_fungetc)(ALLEGRO_FILE *f, int c);
+off_t         (*fi_fsize)(ALLEGRO_FILE *f);
+

The fi_open function must allocate memory for whatever userdata structure it needs. The pointer to that memory must be returned; it will then be associated with the file. The other functions can access that data by calling al_get_file_userdata on the file handle. If fi_open returns NULL then al_fopen will also return NULL.

+

The fi_fclose function must clean up and free the userdata, but Allegro will free the ALLEGRO_FILE handle.

+

If fi_fungetc is NULL, then Allegro’s default implementation of a 16 char long buffer will be used.

+

Examples:

+ +

ALLEGRO_SEEK

+
typedef enum ALLEGRO_SEEK
+

Source Code

+
    +
  • ALLEGRO_SEEK_SET - seek relative to beginning of file
  • +
  • ALLEGRO_SEEK_CUR - seek relative to current file position
  • +
  • ALLEGRO_SEEK_END - seek relative to end of file
  • +
+

See also: al_fseek

+

Examples:

+ +

al_fopen

+
ALLEGRO_FILE *al_fopen(const char *path, const char *mode)
+

Source Code

+

Creates and opens a file (real or virtual) given the path and mode. The current file interface is used to open the file.

+

Parameters:

+
    +
  • path - path to the file to open
  • +
  • mode - access mode to open the file in (“r”, “w”, etc.)
  • +
+

Depending on the stream type and the mode string, files may be opened in “text” mode. The handling of newlines is particularly important. For example, using the default stdio-based streams on DOS and Windows platforms, where the native end-of-line terminators are CR+LF sequences, a call to al_fgetc may return just one character (‘\n’) where there were two bytes (CR+LF) in the file. When writing out ‘\n’, two bytes would be written instead. (As an aside, ‘\n’ is not defined to be equal to LF either.)

+

Newline translations can be useful for text files but is disastrous for binary files. To avoid this behaviour you need to open file streams in binary mode by using a mode argument containing a “b”, e.g. “rb”, “wb”.

+

Returns a file handle on success, or NULL on error.

+

See also: al_set_new_file_interface, al_fclose.

+

Examples:

+ +

al_fopen_interface

+
ALLEGRO_FILE *al_fopen_interface(const ALLEGRO_FILE_INTERFACE *drv,
+   const char *path, const char *mode)
+

Source Code

+

Opens a file using the specified interface, instead of the interface set with al_set_new_file_interface.

+

See also: al_fopen

+

al_fopen_slice

+
ALLEGRO_FILE *al_fopen_slice(ALLEGRO_FILE *fp, size_t initial_size, const char *mode)
+

Source Code

+

Opens a slice (subset) of an already open random access file as if it were a stand alone file. While the slice is open, the parent file handle must not be used in any way.

+

The slice is opened at the current location of the parent file, up through initial_size bytes. The initial_size may be any non-negative integer that will not exceed the bounds of the parent file.

+

Seeking with ALLEGRO_SEEK_SET will be relative to this starting location. ALLEGRO_SEEK_END will be relative to the starting location plus the size of the slice.

+

The mode can be any combination of:

+
    +
  • r: read access
  • +
  • w: write access
  • +
  • e: expandable
  • +
+

For example, a mode of “rw” indicates the file can be read and written. (Note that this is slightly different from the stdio modes.) Keep in mind that the parent file must support random access and be open in normal write mode (not append) for the slice to work in a well defined way.

+

If the slice is marked as expandable, then reads and writes can happen after the initial end point, and the slice will grow accordingly. Otherwise, all activity is restricted to the initial size of the slice.

+

A slice must be closed with al_fclose. The parent file will then be positioned immediately after the end of the slice.

+

Since: 5.0.6, 5.1.0

+

See also: al_fopen

+

Examples:

+ +

al_fclose

+
bool al_fclose(ALLEGRO_FILE *f)
+

Source Code

+

Close the given file, writing any buffered output data (if any).

+

Returns true on success, false on failure. errno is set to indicate the error.

+

Examples:

+ +

al_fread

+
size_t al_fread(ALLEGRO_FILE *f, void *ptr, size_t size)
+

Source Code

+

Read ‘size’ bytes into the buffer pointed to by ‘ptr’, from the given file.

+

Returns the number of bytes actually read. If an error occurs, or the end-of-file is reached, the return value is a short byte count (or zero).

+

al_fread() does not distinguish between EOF and other errors. Use al_feof and al_ferror to determine which occurred.

+

See also: al_fgetc, al_fread16be, al_fread16le, al_fread32be, al_fread32le

+

Examples:

+ +

al_fwrite

+
size_t al_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size)
+

Source Code

+

Write ‘size’ bytes from the buffer pointed to by ‘ptr’ into the given file.

+

Returns the number of bytes actually written. If an error occurs, the return value is a short byte count (or zero).

+

See also: al_fputc, al_fputs, al_fwrite16be, al_fwrite16le, al_fwrite32be, al_fwrite32le

+

Examples:

+ +

al_fflush

+
bool al_fflush(ALLEGRO_FILE *f)
+

Source Code

+

Flush any pending writes to the given file.

+

Returns true on success, false otherwise. errno is set to indicate the error.

+

See also: al_get_errno

+

al_ftell

+
int64_t al_ftell(ALLEGRO_FILE *f)
+

Source Code

+

Returns the current position in the given file, or -1 on error. errno is set to indicate the error.

+

On some platforms this function may not support large files.

+

See also: al_fseek, al_get_errno

+

Examples:

+ +

al_fseek

+
bool al_fseek(ALLEGRO_FILE *f, int64_t offset, int whence)
+

Source Code

+

Set the current position of the given file to a position relative to that specified by ‘whence’, plus ‘offset’ number of bytes.

+

‘whence’ can be:

+
    +
  • ALLEGRO_SEEK_SET - seek relative to beginning of file
  • +
  • ALLEGRO_SEEK_CUR - seek relative to current file position
  • +
  • ALLEGRO_SEEK_END - seek relative to end of file
  • +
+

Returns true on success, false on failure. errno is set to indicate the error.

+

After a successful seek, the end-of-file indicator is cleared and all pushback bytes are forgotten.

+

On some platforms this function may not support large files.

+

See also: al_ftell, al_get_errno

+

Examples:

+ +

al_feof

+
bool al_feof(ALLEGRO_FILE *f)
+

Source Code

+

Returns true if the end-of-file indicator has been set on the file, i.e. we have attempted to read past the end of the file.

+

This does not return true if we simply are at the end of the file. The following code correctly reads two bytes, even when the file contains exactly two bytes:

+
int b1 = al_fgetc(f);
+int b2 = al_fgetc(f);
+if (al_feof(f)) {
+   /* At least one byte was unsuccessfully read. */
+   report_error();
+}
+

See also: al_ferror, al_fclearerr

+

Examples:

+ +

al_ferror

+
int al_ferror(ALLEGRO_FILE *f)
+

Source Code

+

Returns non-zero if the error indicator is set on the given file, i.e. there was some sort of previous error. The error code may be system or file interface specific.

+

See also: al_feof, al_fclearerr, al_ferrmsg

+

Examples:

+ +

al_ferrmsg

+
const char *al_ferrmsg(ALLEGRO_FILE *f)
+

Source Code

+

Return a message string with details about the last error that occurred on the given file handle. The returned string is empty if there was no error, or if the file interface does not provide more information.

+

See also: al_fclearerr, al_ferror

+

al_fclearerr

+
void al_fclearerr(ALLEGRO_FILE *f)
+

Source Code

+

Clear the error indicator for the given file.

+

The standard I/O backend also clears the end-of-file indicator, and other backends should try to do this. However, they may not if it would require too much effort (e.g. PhysicsFS backend), so your code should not rely on it if you need your code to be portable to other backends.

+

See also: al_ferror, al_feof

+

al_fungetc

+
int al_fungetc(ALLEGRO_FILE *f, int c)
+

Source Code

+

Ungets a single byte from a file. Pushed-back bytes are not written to the file, only made available for subsequent reads, in reverse order.

+

The number of pushbacks depends on the backend. The standard I/O backend only guarantees a single pushback; this depends on the libc implementation.

+

For backends that follow the standard behavior, the pushback buffer will be cleared after any seeking or writing; also calls to al_fseek and al_ftell are relative to the number of pushbacks. If a pushback causes the position to become negative, the behavior of al_fseek and al_ftell are undefined.

+

See also: al_fgetc, al_get_errno

+

Examples:

+ +

al_fsize

+
int64_t al_fsize(ALLEGRO_FILE *f)
+

Source Code

+

Return the size of the file, if it can be determined, or -1 otherwise.

+

Examples:

+ +

al_fgetc

+
int al_fgetc(ALLEGRO_FILE *f)
+

Source Code

+

Read and return next byte in the given file. Returns EOF on end of file or if an error occurred.

+

See also: al_fungetc

+

Examples:

+ +

al_fputc

+
int al_fputc(ALLEGRO_FILE *f, int c)
+

Source Code

+

Write a single byte to the given file. The byte written is the value of c cast to an unsigned char.

+

Parameters:

+
    +
  • c - byte value to write
  • +
  • f - file to write to
  • +
+

Returns the written byte (cast back to an int) on success, or EOF on error.

+

al_fprintf

+
int al_fprintf(ALLEGRO_FILE *pfile, const char *format, ...)
+

Source Code

+

Writes to a file with stdio “printf”-like formatting. Returns the number of bytes written, or a negative number on error.

+

See also: al_vfprintf

+

al_vfprintf

+
int al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args)
+

Source Code

+

Like al_fprintf but takes a va_list. Useful for creating your own variations of formatted printing. Returns the number of bytes written, or a negative number on error.

+

See also: al_fprintf

+

al_fread16le

+
int16_t al_fread16le(ALLEGRO_FILE *f)
+

Source Code

+

Reads a 16-bit word in little-endian format (LSB first).

+

On success, returns the 16-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use al_feof to check if the end of the file was reached prematurely, or al_ferror to check if an error occurred.

+

See also: al_fread16be

+

al_fread16be

+
int16_t al_fread16be(ALLEGRO_FILE *f)
+

Source Code

+

Reads a 16-bit word in big-endian format (MSB first).

+

On success, returns the 16-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use al_feof to check if the end of the file was reached prematurely, or al_ferror to check if an error occurred.

+

See also: al_fread16le

+

al_fwrite16le

+
size_t al_fwrite16le(ALLEGRO_FILE *f, int16_t w)
+

Source Code

+

Writes a 16-bit word in little-endian format (LSB first).

+

Returns the number of bytes written: 2 on success, less than 2 on an error.

+

See also: al_fwrite16be

+

al_fwrite16be

+
size_t al_fwrite16be(ALLEGRO_FILE *f, int16_t w)
+

Source Code

+

Writes a 16-bit word in big-endian format (MSB first).

+

Returns the number of bytes written: 2 on success, less than 2 on an error.

+

See also: al_fwrite16le

+

al_fread32le

+
int32_t al_fread32le(ALLEGRO_FILE *f)
+

Source Code

+

Reads a 32-bit word in little-endian format (LSB first).

+

On success, returns the 32-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use al_feof to check if the end of the file was reached prematurely, or al_ferror to check if an error occurred.

+

See also: al_fread32be

+

Examples:

+ +

al_fread32be

+
int32_t al_fread32be(ALLEGRO_FILE *f)
+

Source Code

+

Read a 32-bit word in big-endian format (MSB first).

+

On success, returns the 32-bit word. On failure, returns EOF (-1). Since -1 is also a valid return value, use al_feof to check if the end of the file was reached prematurely, or al_ferror to check if an error occurred.

+

See also: al_fread32le

+

al_fwrite32le

+
size_t al_fwrite32le(ALLEGRO_FILE *f, int32_t l)
+

Source Code

+

Writes a 32-bit word in little-endian format (LSB first).

+

Returns the number of bytes written: 4 on success, less than 4 on an error.

+

See also: al_fwrite32be

+

Examples:

+ +

al_fwrite32be

+
size_t al_fwrite32be(ALLEGRO_FILE *f, int32_t l)
+

Source Code

+

Writes a 32-bit word in big-endian format (MSB first).

+

Returns the number of bytes written: 4 on success, less than 4 on an error.

+

See also: al_fwrite32le

+

al_fgets

+
char *al_fgets(ALLEGRO_FILE *f, char * const buf, size_t max)
+

Source Code

+

Read a string of bytes terminated with a newline or end-of-file into the buffer given. The line terminator(s), if any, are included in the returned string. A maximum of max-1 bytes are read, with one byte being reserved for a NUL terminator.

+

Parameters:

+
    +
  • f - file to read from
  • +
  • buf - buffer to fill
  • +
  • max - maximum size of buffer
  • +
+

Returns the pointer to buf on success. Returns NULL if an error occurred or if the end of file was reached without reading any bytes.

+

See al_fopen about translations of end-of-line characters.

+

See also: al_fget_ustr

+

Examples:

+ +

al_fget_ustr

+
ALLEGRO_USTR *al_fget_ustr(ALLEGRO_FILE *f)
+

Source Code

+

Read a string of bytes terminated with a newline or end-of-file. The line terminator(s), if any, are included in the returned string.

+

On success returns a pointer to a new ALLEGRO_USTR structure. This must be freed eventually with al_ustr_free. Returns NULL if an error occurred or if the end of file was reached without reading any bytes.

+

See al_fopen about translations of end-of-line characters.

+

See also: al_fgetc, al_fgets

+

al_fputs

+
int al_fputs(ALLEGRO_FILE *f, char const *p)
+

Source Code

+

Writes a string to file. Apart from the return value, this is equivalent to:

+
al_fwrite(f, p, strlen(p));
+

Parameters:

+
    +
  • f - file handle to write to
  • +
  • p - string to write
  • +
+

Returns a non-negative integer on success, EOF on error.

+

Note: depending on the stream type and the mode passed to al_fopen, newline characters in the string may or may not be automatically translated to native end-of-line sequences, e.g. CR/LF instead of LF.

+

See also: al_fwrite

+

Examples:

+ +

Standard I/O specific routines

+

al_fopen_fd

+
ALLEGRO_FILE *al_fopen_fd(int fd, const char *mode)
+

Source Code

+

Create an ALLEGRO_FILE object that operates on an open file descriptor using stdio routines. See the documentation of fdopen() for a description of the ‘mode’ argument.

+

Returns an ALLEGRO_FILE object on success or NULL on an error. On an error, the Allegro errno will be set and the file descriptor will not be closed.

+

The file descriptor will be closed by al_fclose so you should not call close() on it.

+

See also: al_fopen

+

al_make_temp_file

+
ALLEGRO_FILE *al_make_temp_file(const char *template, ALLEGRO_PATH **ret_path)
+

Source Code

+

Make a temporary randomly named file given a filename ‘template’.

+

‘template’ is a string giving the format of the generated filename and should include one or more capital Xs. The Xs are replaced with random alphanumeric characters, produced using a simple pseudo-random number generator only. There should be no path separators.

+

If ‘ret_path’ is not NULL, the address it points to will be set to point to a new path structure with the name of the temporary file.

+

Returns the opened ALLEGRO_FILE on success, NULL on failure.

+

Examples:

+ +

Alternative file streams

+

By default, the Allegro file I/O routines use the C library I/O routines, hence work with files on the local filesystem, but can be overridden so that you can read and write to other streams. For example, you can work with blocks of memory or sub-files inside .zip files.

+

There are two ways to get an ALLEGRO_FILE that doesn’t use stdio. An addon library may provide a function that returns a new ALLEGRO_FILE directly, after which, all al_f* calls on that object will use overridden functions for that type of stream. Alternatively, al_set_new_file_interface changes which function will handle the following al_fopen calls for the current thread.

+

al_set_new_file_interface

+
void al_set_new_file_interface(const ALLEGRO_FILE_INTERFACE *file_interface)
+

Source Code

+

Set the ALLEGRO_FILE_INTERFACE table for the calling thread. This will change the handler for later calls to al_fopen.

+

See also: al_set_standard_file_interface, al_store_state, al_restore_state.

+

Examples:

+ +

al_set_standard_file_interface

+
void al_set_standard_file_interface(void)
+

Source Code

+

Set the ALLEGRO_FILE_INTERFACE table to the default, for the calling thread. This will change the handler for later calls to al_fopen.

+

See also: al_set_new_file_interface

+

Examples:

+ +

al_get_new_file_interface

+
const ALLEGRO_FILE_INTERFACE *al_get_new_file_interface(void)
+

Source Code

+

Return a pointer to the ALLEGRO_FILE_INTERFACE table in effect for the calling thread.

+

See also: al_store_state, al_restore_state.

+

al_create_file_handle

+
ALLEGRO_FILE *al_create_file_handle(const ALLEGRO_FILE_INTERFACE *drv,
+   void *userdata)
+

Source Code

+

Creates an empty, opened file handle with some abstract user data. This allows custom interfaces to extend the ALLEGRO_FILE struct with their own data. You should close the handle with the standard al_fclose function when you are finished with it.

+

See also: al_fopen, al_fclose, al_set_new_file_interface

+

al_get_file_userdata

+
void *al_get_file_userdata(ALLEGRO_FILE *f)
+

Source Code

+

Returns a pointer to the custom userdata that is attached to the file handle. This is intended to be used by functions that extend ALLEGRO_FILE_INTERFACE.

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/fixed.html b/allegro/docs/html/refman/fixed.html new file mode 100644 index 00000000..dbaa8bb8 --- /dev/null +++ b/allegro/docs/html/refman/fixed.html @@ -0,0 +1,494 @@ + + + + + + + Fixed point math routines + + + + + + + + +
+ + +
+

Fixed point math routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

al_fixed

+
typedef int32_t al_fixed;
+

Source Code

+

A fixed point number.

+

Allegro provides some routines for working with fixed point numbers, and defines the type al_fixed to be a signed 32-bit integer. The high word is used for the integer part and the low word for the fraction, giving a range of -32768 to 32767 and an accuracy of about four or five decimal places. Fixed point numbers can be assigned, compared, added, subtracted, negated and shifted (for multiplying or dividing by powers of two) using the normal integer operators, but you should take care to use the appropriate conversion routines when mixing fixed point with integer or floating point values. Writing fixed_point_1 + fixed_point_2 is OK, but fixed_point + integer is not.

+

The only advantage of fixed point math routines is that you don’t require a floating point coprocessor to use them. This was great in the time period of i386 and i486 machines, but stopped being so useful with the coming of the Pentium class of processors. From Pentium onwards, CPUs have increased their strength in floating point operations, equaling or even surpassing integer math performance. However, many embedded processors have no FPUs so fixed point maths can still be useful there.

+

Depending on the type of operations your program may need, using floating point types may be faster than fixed types if you are targeting a specific machine class.

+

al_itofix

+
al_fixed al_itofix(int x);
+

Source Code

+

Converts an integer to fixed point. This is the same thing as x<<16. Remember that overflows (trying to convert an integer greater than 32767) and underflows (trying to convert an integer lesser than -32768) are not detected even in debug builds! The values simply “wrap around”.

+

Example:

+
al_fixed number;
+
+/* This conversion is OK. */
+number = al_itofix(100);
+assert(al_fixtoi(number) == 100);
+
+number = al_itofix(64000);
+
+/* This check will fail in debug builds. */
+assert(al_fixtoi(number) == 64000);
+

Return value: Returns the value of the integer converted to fixed point ignoring overflows.

+

See also: al_fixtoi, al_ftofix, al_fixtof.

+

al_fixtoi

+
int al_fixtoi(al_fixed x);
+

Source Code

+

Converts fixed point to integer, rounding as required to the nearest integer.

+

Example:

+
int result;
+
+/* This will put 33 into `result'. */
+result = al_fixtoi(al_itofix(100) / 3);
+
+/* But this will round up to 17. */
+result = al_fixtoi(al_itofix(100) / 6);
+

See also: al_itofix, al_ftofix, al_fixtof, al_fixfloor, al_fixceil.

+

al_fixfloor

+
int al_fixfloor(al_fixed x);
+

Source Code

+

Returns the greatest integer not greater than x. That is, it rounds towards negative infinity.

+

Example:

+
int result;
+
+/* This will put 33 into `result'. */
+result = al_fixfloor(al_itofix(100) / 3);
+
+/* And this will round down to 16. */
+result = al_fixfloor(al_itofix(100) / 6);
+

See also: al_fixtoi, al_fixceil.

+

al_fixceil

+
int al_fixceil(al_fixed x);
+

Source Code

+

Returns the smallest integer not less than x. That is, it rounds towards positive infinity.

+

Example:

+
int result;
+
+/* This will put 34 into `result'. */
+result = al_fixceil(al_itofix(100) / 3);
+
+/* This will round up to 17. */
+result = al_fixceil(al_itofix(100) / 6);
+

See also: al_fixtoi, al_fixfloor.

+

al_ftofix

+
al_fixed al_ftofix(double x);
+

Source Code

+

Converts a floating point value to fixed point. Unlike al_itofix, this function clamps values which could overflow the type conversion, setting Allegro’s errno to ERANGE in the process if this happens.

+

Example:

+
al_fixed number;
+
+number = al_itofix(-40000);
+assert(al_fixfloor(number) == -32768);
+
+number = al_itofix(64000);
+assert(al_fixfloor(number) == 32767);
+assert(!al_get_errno()); /* This will fail. */
+

Return value: Returns the value of the floating point value converted to fixed point clamping overflows (and setting Allegro’s errno).

+

See also: al_fixtof, al_itofix, al_fixtoi, al_get_errno

+

al_fixtof

+
double al_fixtof(al_fixed x);
+

Source Code

+

Converts fixed point to floating point.

+

Example:

+
float result;
+
+/* This will put 33.33333 into `result'. */
+result = al_fixtof(al_itofix(100) / 3);
+
+/* This will put 16.66666 into `result'. */
+result = al_fixtof(al_itofix(100) / 6);
+

See also: al_ftofix, al_itofix, al_fixtoi.

+

al_fixmul

+
al_fixed al_fixmul(al_fixed x, al_fixed y);
+

Source Code

+

A fixed point value can be multiplied or divided by an integer with the normal * and / operators. To multiply two fixed point values, though, you must use this function.

+

If an overflow occurs, Allegro’s errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful. This means that if you are going to test for overflow you should call al_set_errno(0) before calling al_fixmul.

+

Example:

+
al_fixed result;
+
+/* This will put 30000 into `result'. */
+result = al_fixmul(al_itofix(10), al_itofix(3000));
+
+/* But this overflows, and sets errno. */
+result = al_fixmul(al_itofix(100), al_itofix(3000));
+assert(!al_get_errno());
+

Return value: Returns the clamped result of multiplying x by y, setting Allegro’s errno to ERANGE if there was an overflow.

+

See also: al_fixadd, al_fixsub, al_fixdiv, al_get_errno.

+

al_fixdiv

+
al_fixed al_fixdiv(al_fixed x, al_fixed y);
+

Source Code

+

A fixed point value can be divided by an integer with the normal / operator. To divide two fixed point values, though, you must use this function. If a division by zero occurs, Allegro’s errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful. This means that if you are going to test for division by zero you should call al_set_errno(0) before calling al_fixdiv.

+

Example:

+
al_fixed result;
+
+/* This will put 0.06060 `result'. */
+result = al_fixdiv(al_itofix(2), al_itofix(33));
+
+/* This will put 0 into `result'. */
+result = al_fixdiv(0, al_itofix(-30));
+
+/* Sets errno and puts -32768 into `result'. */
+result = al_fixdiv(al_itofix(-100), al_itofix(0));
+assert(!al_get_errno()); /* This will fail. */
+

Return value: Returns the result of dividing x by y. If y is zero, returns the maximum possible fixed point value and sets Allegro’s errno to ERANGE.

+

See also: al_fixadd, al_fixsub, al_fixmul, al_get_errno.

+

al_fixadd

+
al_fixed al_fixadd(al_fixed x, al_fixed y);
+

Source Code

+

Although fixed point numbers can be added with the normal + integer operator, that doesn’t provide any protection against overflow. If overflow is a problem, you should use this function instead. It is slower than using integer operators, but if an overflow occurs it will set Allegro’s errno and clamp the result, rather than just letting it wrap.

+

Example:

+
al_fixed result;
+
+/* This will put 5035 into `result'. */
+result = al_fixadd(al_itofix(5000), al_itofix(35));
+
+/* Sets errno and puts -32768 into `result'. */
+result = al_fixadd(al_itofix(-31000), al_itofix(-3000));
+assert(!al_get_errno()); /* This will fail. */
+

Return value: Returns the clamped result of adding x to y, setting Allegro’s errno to ERANGE if there was an overflow.

+

See also: al_fixsub, al_fixmul, al_fixdiv.

+

al_fixsub

+
al_fixed al_fixsub(al_fixed x, al_fixed y);
+

Source Code

+

Although fixed point numbers can be subtracted with the normal - integer operator, that doesn’t provide any protection against overflow. If overflow is a problem, you should use this function instead. It is slower than using integer operators, but if an overflow occurs it will set Allegro’s errno and clamp the result, rather than just letting it wrap.

+

Example:

+
al_fixed result;
+
+/* This will put 4965 into `result'. */
+result = al_fixsub(al_itofix(5000), al_itofix(35));
+
+/* Sets errno and puts -32768 into `result'. */
+result = al_fixsub(al_itofix(-31000), al_itofix(3000));
+assert(!al_get_errno()); /* This will fail. */
+

Return value: Returns the clamped result of subtracting y from x, setting Allegro’s errno to ERANGE if there was an overflow.

+

See also: al_fixadd, al_fixmul, al_fixdiv, al_get_errno.

+

Fixed point trig

+

The fixed point square root, sin, cos, tan, inverse sin, and inverse cos functions are implemented using lookup tables, which are very fast but not particularly accurate. At the moment the inverse tan uses an iterative search on the tan table, so it is a lot slower than the others. On machines with good floating point processors using these functions could be slower Always profile your code.

+

Angles are represented in a binary format with 256 equal to a full circle, 64 being a right angle and so on. This has the advantage that a simple bitwise ‘and’ can be used to keep the angle within the range zero to a full circle.

+

al_fixtorad_r

+
const al_fixed al_fixtorad_r = (al_fixed)1608;
+

Source Code

+

This constant gives a ratio which can be used to convert a fixed point number in binary angle format to a fixed point number in radians.

+

Example:

+
al_fixed rad_angle, binary_angle;
+
+/* Set the binary angle to 90 degrees. */
+binary_angle = 64;
+
+/* Now convert to radians (about 1.57). */
+rad_angle = al_fixmul(binary_angle, al_fixtorad_r);
+

See also: al_fixmul, al_radtofix_r.

+

al_radtofix_r

+
const al_fixed al_radtofix_r = (al_fixed)2670177;
+

Source Code

+

This constant gives a ratio which can be used to convert a fixed point number in radians to a fixed point number in binary angle format.

+

Example:

+
    al_fixed rad_angle, binary_angle;
+    ...
+    binary_angle = al_fixmul(rad_angle, radtofix_r);
+

See also: al_fixmul, al_fixtorad_r.

+

al_fixsin

+
al_fixed al_fixsin(al_fixed x);
+

Source Code

+

This function finds the sine of a value using a lookup table. The input value must be a fixed point binary angle.

+

Example:

+
al_fixed angle;
+int result;
+
+/* Set the binary angle to 90 degrees. */
+angle = al_itofix(64);
+
+/* The sine of 90 degrees is one. */
+result = al_fixtoi(al_fixsin(angle));
+assert(result == 1);
+

Return value: Returns the sine of a fixed point binary format angle as a fixed point value.

+

al_fixcos

+
al_fixed al_fixcos(al_fixed x);
+

Source Code

+

This function finds the cosine of a value using a lookup table. The input value must be a fixed point binary angle.

+

Example:

+
al_fixed angle;
+float result;
+
+/* Set the binary angle to 45 degrees. */
+angle = al_itofix(32);
+
+/* The cosine of 45 degrees is about 0.7071. */
+result = al_fixtof(al_fixcos(angle));
+assert(result > 0.7 && result < 0.71);
+

Return value: Returns the cosine of a fixed point binary format angle as a fixed point value.

+

al_fixtan

+
al_fixed al_fixtan(al_fixed x);
+

Source Code

+

This function finds the tangent of a value using a lookup table. The input value must be a fixed point binary angle.

+

Example:

+
al_fixed angle, res_a, res_b;
+float dif;
+
+angle = al_itofix(37);
+/* Prove that tan(angle) == sin(angle) / cos(angle). */
+res_a = al_fixdiv(al_fixsin(angle), al_fixcos(angle));
+res_b = al_fixtan(angle);
+dif = al_fixtof(al_fixsub(res_a, res_b));
+printf("Precision error: %f\n", dif);
+

Return value: Returns the tangent of a fixed point binary format angle as a fixed point value.

+

al_fixasin

+
al_fixed al_fixasin(al_fixed x);
+

Source Code

+

This function finds the inverse sine of a value using a lookup table. The input value must be a fixed point value. The inverse sine is defined only in the domain from -1 to 1. Outside of this input range, the function will set Allegro’s errno to EDOM and return zero.

+

Example:

+
float angle;
+al_fixed val;
+
+/* Sets `val' to a right binary angle (64). */
+val = al_fixasin(al_itofix(1));
+
+/* Sets `angle' to 0.2405. */
+angle = al_fixtof(al_fixmul(al_fixasin(al_ftofix(0.238)), al_fixtorad_r));
+
+/* This will trigger the assert. */
+val = al_fixasin(al_ftofix(-1.09));
+assert(!al_get_errno());
+

Return value: Returns the inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of the range. All return values of this function will be in the range -64 to 64.

+

al_fixacos

+
al_fixed al_fixacos(al_fixed x);
+

Source Code

+

This function finds the inverse cosine of a value using a lookup table. The input must be a fixed point value. The inverse cosine is defined only in the domain from -1 to 1. Outside of this input range, the function will set Allegro’s errno to EDOM and return zero.

+

Example:

+
al_fixed result;
+
+/* Sets result to binary angle 128. */
+result = al_fixacos(al_itofix(-1));
+

Return value: Returns the inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of range. All return values of this function will be in the range 0 to 128.

+

al_fixatan

+
al_fixed al_fixatan(al_fixed x)
+

Source Code

+

This function finds the inverse tangent of a value using a lookup table. The input must be a fixed point value. The inverse tangent is the value whose tangent is x.

+

Example:

+
al_fixed result;
+
+/* Sets result to binary angle 13. */
+result = al_fixatan(al_ftofix(0.326));
+

Return value: Returns the inverse tangent of a fixed point value, measured as a fixed point binary format angle.

+

al_fixatan2

+
al_fixed al_fixatan2(al_fixed y, al_fixed x)
+

Source Code

+

This is a fixed point version of the libc atan2() routine. It computes the arc tangent of y / x, but the signs of both arguments are used to determine the quadrant of the result, and x is permitted to be zero. This function is useful to convert Cartesian coordinates to polar coordinates.

+

Example:

+
al_fixed result;
+
+/* Sets `result' to binary angle 64. */
+result = al_fixatan2(al_itofix(1), 0);
+
+/* Sets `result' to binary angle -109. */
+result = al_fixatan2(al_itofix(-1), al_itofix(-2));
+
+/* Fails the assert. */
+result = al_fixatan2(0, 0);
+assert(!al_get_errno());
+

Return value: Returns the arc tangent of y / x in fixed point binary format angle, from -128 to 128. If both x and y are zero, returns zero and sets Allegro’s errno to EDOM.

+

al_fixsqrt

+
al_fixed al_fixsqrt(al_fixed x)
+

Source Code

+

This finds out the non negative square root of x. If x is negative, Allegro’s errno is set to EDOM and the function returns zero.

+

al_fixhypot

+
al_fixed al_fixhypot(al_fixed x, al_fixed y)
+

Source Code

+

Fixed point hypotenuse (returns the square root of x*x + y*y). This should be better than calculating the formula yourself manually, since the error is much smaller.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/font.html b/allegro/docs/html/refman/font.html new file mode 100644 index 00000000..d83592c4 --- /dev/null +++ b/allegro/docs/html/refman/font.html @@ -0,0 +1,889 @@ + + + + + + + Font addons + + + + + + + + +
+ + +
+

Font addons

+
+ +

These functions are declared in the following header file. Link with allegro_font.

+
 #include <allegro5/allegro_font.h>
+

General font routines

+

ALLEGRO_FONT

+
typedef struct ALLEGRO_FONT ALLEGRO_FONT;
+

Source Code

+

A handle identifying any kind of font. Usually you will create it with al_load_font which supports loading all kinds of TrueType fonts supported by the FreeType library. If you instead pass the filename of a bitmap file, it will be loaded with al_load_bitmap and a font in Allegro’s bitmap font format will be created from it with al_grab_font_from_bitmap.

+

Examples:

+ +

ALLEGRO_GLYPH

+
typedef struct ALLEGRO_GLYPH ALLEGRO_GLYPH;
+

Source Code

+

A structure containing the properties of a character in a font.

+
typedef struct ALLEGRO_GLYPH {
+   ALLEGRO_BITMAP *bitmap;   // the bitmap the character is on
+   int x;                    // the x position of the glyph on bitmap
+   int y;                    // the y position of the glyph on bitmap
+   int w;                    // the width of the glyph in pixels
+   int h;                    // the height of the glyph in pixels
+   int kerning;              // pixels of kerning (see below)
+   int offset_x;             // x offset to draw the glyph at
+   int offset_y;             // y offset to draw the glyph at
+   int advance;              // number of pixels to advance after this character
+} ALLEGRO_GLYPH;
+

bitmap may be a sub-bitmap in the case of color fonts. Bitmap can also be NULL in which case nothing should be drawn (sometimes true for whitespace characters in TTF fonts).

+

kerning should be added to the x position you draw to if you want your text kerned and depends on which codepoints al_get_glyph was called with.

+

Glyphs are tightly packed onto the bitmap, so you need to add offset_x and offset_y to your draw position for the text to look right.

+

advance is the number of pixels to add to your x position to advance to the next character in a string and includes kerning.

+

Since: 5.2.1

+
+

Unstable API: This API is new and subject to refinement.

+
+

See also: al_get_glyph

+

Examples:

+ +

al_init_font_addon

+
bool al_init_font_addon(void)
+

Source Code

+

Initialise the font addon.

+

Note that if you intend to load bitmap fonts, you will need to initialise allegro_image separately (unless you are using another library to load images).

+

Similarly, if you wish to load truetype-fonts, do not forget to also call al_init_ttf_addon.

+

Returns true on success, false on failure. On the 5.0 branch, this function has no return value. You may wish to avoid checking the return value if your code needs to be compatible with Allegro 5.0. Currently, the function will never return false.

+

See also: al_init_image_addon, al_init_ttf_addon, al_shutdown_font_addon

+

Examples:

+ +

al_is_font_addon_initialized

+
bool al_is_font_addon_initialized(void)
+

Source Code

+

Returns true if the font addon is initialized, otherwise returns false.

+

Since: 5.2.6

+

See also: al_init_font_addon, al_shutdown_font_addon

+

al_shutdown_font_addon

+
void al_shutdown_font_addon(void)
+

Source Code

+

Shut down the font addon. This is done automatically at program exit, but can be called any time the user wishes as well.

+

See also: al_init_font_addon

+

al_load_font

+
ALLEGRO_FONT *al_load_font(char const *filename, int size, int flags)
+

Source Code

+

Loads a font from disk. This will use al_load_bitmap_font_flags if you pass the name of a known bitmap format, or else al_load_ttf_font.

+

The flags parameter is passed through to either of those functions. Bitmap and TTF fonts are also affected by the current bitmap flags at the time the font is loaded.

+

See also: al_destroy_font, al_init_font_addon, al_register_font_loader, al_load_bitmap_font_flags, al_load_ttf_font

+

Examples:

+ +

al_destroy_font

+
void al_destroy_font(ALLEGRO_FONT *f)
+

Source Code

+

Frees the memory being used by a font structure. Does nothing if passed NULL.

+

See also: al_load_font

+

Examples:

+ +

al_register_font_loader

+
bool al_register_font_loader(char const *extension,
+   ALLEGRO_FONT *(*load_font)(char const *filename, int size, int flags))
+

Source Code

+

Informs Allegro of a new font file type, telling it how to load files of this format.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The load_font argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_init_font_addon

+

al_get_font_line_height

+
int al_get_font_line_height(const ALLEGRO_FONT *f)
+

Source Code

+

Returns the usual height of a line of text in the specified font. For bitmap fonts this is simply the height of all glyph bitmaps. For truetype fonts it is whatever the font file specifies. In particular, some special glyphs may be higher than the height returned here.

+

If the X is the position you specify to draw text, the meaning of ascent and descent and the line height is like in the figure below.

+
X------------------------
+    /\         |        |
+   /  \        |        |
+  /____\       ascent   |
+ /      \      |        |
+/        \     |        height
+----------------        |
+               |        |
+               descent  |
+               |        |
+-------------------------
+

See also: al_get_text_width, al_get_text_dimensions

+

Examples:

+ +

al_get_font_ascent

+
int al_get_font_ascent(const ALLEGRO_FONT *f)
+

Source Code

+

Returns the ascent of the specified font.

+

See also: al_get_font_descent, al_get_font_line_height

+

Examples:

+ +

al_get_font_descent

+
int al_get_font_descent(const ALLEGRO_FONT *f)
+

Source Code

+

Returns the descent of the specified font.

+

See also: al_get_font_ascent, al_get_font_line_height

+

Examples:

+ +

al_get_text_width

+
int al_get_text_width(const ALLEGRO_FONT *f, const char *str)
+

Source Code

+

Calculates the length of a string in a particular font, in pixels.

+

See also: al_get_ustr_width, al_get_font_line_height, al_get_text_dimensions

+

Examples:

+ +

al_get_ustr_width

+
int al_get_ustr_width(const ALLEGRO_FONT *f, ALLEGRO_USTR const *ustr)
+

Source Code

+

Like al_get_text_width but expects an ALLEGRO_USTR.

+

See also: al_get_text_width, al_get_ustr_dimensions

+

Examples:

+ +

al_draw_text

+
void al_draw_text(const ALLEGRO_FONT *font,
+   ALLEGRO_COLOR color, float x, float y, int flags,
+   char const *text) 
+

Source Code

+

Writes the NUL-terminated string text onto the target bitmap at position x, y, using the specified font.

+

The flags parameter can be 0 or one of the following flags:

+
    +
  • ALLEGRO_ALIGN_LEFT - Draw the text left-aligned (same as 0).
  • +
  • ALLEGRO_ALIGN_CENTRE - Draw the text centered around the given position.
  • +
  • ALLEGRO_ALIGN_RIGHT - Draw the text right-aligned to the given position.
  • +
+

It can also be combined with this flag:

+
    +
  • ALLEGRO_ALIGN_INTEGER - Always draw text aligned to an integer pixel position. This was formerly the default behaviour. Since: 5.0.8, 5.1.4
  • +
+

This function does not support newline characters (\n), but you can use al_draw_multiline_text for multi line text output.

+

See also: al_draw_ustr, al_draw_textf, al_draw_justified_text, al_draw_multiline_text.

+

Examples:

+ +

al_draw_ustr

+
void al_draw_ustr(const ALLEGRO_FONT *font,
+   ALLEGRO_COLOR color, float x, float y, int flags,
+   const ALLEGRO_USTR *ustr) 
+

Source Code

+

Like al_draw_text, except the text is passed as an ALLEGRO_USTR instead of a NUL-terminated char array.

+

See also: al_draw_text, al_draw_justified_ustr, al_draw_multiline_ustr

+

Examples:

+ +

al_draw_justified_text

+
void al_draw_justified_text(const ALLEGRO_FONT *font,
+   ALLEGRO_COLOR color, float x1, float x2,
+   float y, float diff, int flags, const char *text)
+

Source Code

+

Like al_draw_text, but justifies the string to the region x1-x2.

+

The diff parameter is the maximum amount of horizontal space to allow between words. If justisfying the text would exceed diff pixels, or the string contains less than two words, then the string will be drawn left aligned.

+

The flags parameter can be 0 or one of the following flags:

+
    +
  • ALLEGRO_ALIGN_INTEGER - Draw text aligned to integer pixel positions. Since: 5.0.8, 5.1.5
  • +
+

See also: al_draw_justified_textf, al_draw_justified_ustr

+

Examples:

+ +

al_draw_justified_ustr

+
void al_draw_justified_ustr(const ALLEGRO_FONT *font,
+   ALLEGRO_COLOR color, float x1, float x2,
+   float y, float diff, int flags, const ALLEGRO_USTR *ustr)
+

Source Code

+

Like al_draw_justified_text, except the text is passed as an ALLEGRO_USTR instead of a NUL-terminated char array.

+

See also: al_draw_justified_text, al_draw_justified_textf.

+

al_draw_textf

+
void al_draw_textf(const ALLEGRO_FONT *font, ALLEGRO_COLOR color,
+   float x, float y, int flags,
+   const char *format, ...)
+

Source Code

+

Formatted text output, using a printf() style format string. All parameters have the same meaning as with al_draw_text otherwise.

+

See also: al_draw_text, al_draw_ustr

+

Examples:

+ +

al_draw_justified_textf

+
void al_draw_justified_textf(const ALLEGRO_FONT *f,
+   ALLEGRO_COLOR color, float x1, float x2, float y,
+   float diff, int flags, const char *format, ...)
+

Source Code

+

Formatted text output, using a printf() style format string. All parameters have the same meaning as with al_draw_justified_text otherwise.

+

See also: al_draw_justified_text, al_draw_justified_ustr.

+

al_get_text_dimensions

+
void al_get_text_dimensions(const ALLEGRO_FONT *f,
+   char const *text,
+   int *bbx, int *bby, int *bbw, int *bbh)
+

Source Code

+

Sometimes, the al_get_text_width and al_get_font_line_height functions are not enough for exact text placement, so this function returns some additional information.

+

Returned variables (all in pixels):

+
    +
  • x, y - Offset to upper left corner of bounding box.
  • +
  • w, h - Dimensions of bounding box.
  • +
+

Note that glyphs may go to the left and upwards of the X, in which case x and y will have negative values.

+

See also: al_get_text_width, al_get_font_line_height, al_get_ustr_dimensions

+

Examples:

+ +

al_get_ustr_dimensions

+
void al_get_ustr_dimensions(const ALLEGRO_FONT *f,
+   ALLEGRO_USTR const *ustr,
+   int *bbx, int *bby, int *bbw, int *bbh)
+

Source Code

+

Like al_get_text_dimensions, except the text is passed as an ALLEGRO_USTR instead of a NUL-terminated char array.

+

See also: al_get_text_dimensions

+

al_get_allegro_font_version

+
uint32_t al_get_allegro_font_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

al_get_font_ranges

+
int al_get_font_ranges(ALLEGRO_FONT *f, int ranges_count, int *ranges)
+

Source Code

+

Gets information about all glyphs contained in a font, as a list of ranges. Ranges have the same format as with al_grab_font_from_bitmap.

+

ranges_count is the maximum number of ranges that will be returned.

+

ranges should be an array with room for ranges_count * 2 elements. The even integers are the first unicode point in a range, the odd integers the last unicode point in a range.

+

Returns the number of ranges contained in the font (even if it is bigger than ranges_count).

+

Since: 5.1.4

+

See also: al_grab_font_from_bitmap

+

Examples:

+ +

al_set_fallback_font

+
void al_set_fallback_font(ALLEGRO_FONT *font, ALLEGRO_FONT *fallback)
+

Source Code

+

Sets a font which is used instead if a character is not present. Can be chained, but make sure there is no loop as that would crash the application! Pass NULL to remove a fallback font again.

+

Since: 5.1.12

+

See also: al_get_fallback_font, al_draw_glyph, al_draw_text

+

Examples:

+ +

al_get_fallback_font

+
ALLEGRO_FONT *al_get_fallback_font(ALLEGRO_FONT *font)
+

Source Code

+

Retrieves the fallback font for this font or NULL.

+

Since: 5.1.12

+

See also: al_set_fallback_font

+

Per glyph text handling

+

For some applications Allegro’s text drawing functions may not be sufficient. For example, you would like to give a different color to every letter in a word, or use different a font for a drop cap.

+

That is why Allegro supports drawing and getting the dimensions of the individual glyphs of a font. A glyph is a particular visual representation of a letter, character or symbol in a specific font.

+

And it’s also possible to get the kerning to use between two glyphs. These per glyph functions have less overhead than Allegro’s per string text drawing and dimensioning functions. So, with these functions you can write your own efficient and precise custom text drawing functions.

+

al_draw_glyph

+
void al_draw_glyph(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, float x, float y,
+   int codepoint)
+

Source Code

+

Draws the glyph that corresponds with codepoint in the given color using the given font. If font does not have such a glyph, nothing will be drawn.

+

To draw a string as left to right horizontal text you will need to use al_get_glyph_advance to determine the position of each glyph. For drawing strings in other directions, such as top to down, use al_get_glyph_dimensions to determine the size and position of each glyph.

+

If you have to draw many glyphs at the same time, use al_hold_bitmap_drawing with true as the parameter, before drawing the glyphs, and then call al_hold_bitmap_drawing again with false as a parameter when done drawing the glyphs to further enhance performance.

+

Since: 5.1.12

+

See also: al_get_glyph_width, al_get_glyph_dimensions, al_get_glyph_advance.

+

Examples:

+ +

al_get_glyph_width

+
int al_get_glyph_width(const ALLEGRO_FONT *f, int codepoint)
+

Source Code

+

This function returns the width in pixels of the glyph that corresponds with codepoint in the font font. Returns zero if the font does not have such a glyph.

+

Since: 5.1.12

+

See also: al_draw_glyph, al_get_glyph_dimensions, al_get_glyph_advance.

+

al_get_glyph_dimensions

+
bool al_get_glyph_dimensions(const ALLEGRO_FONT *f,
+   int codepoint, int *bbx, int *bby, int *bbw, int *bbh)
+

Source Code

+

Sometimes, the al_get_glyph_width or al_get_glyph_advance functions are not enough for exact glyph placement, so this function returns some additional information, particularly if you want to draw the font vertically.

+

The function itself returns true if the character was present in font and false if the character was not present in font.

+

Returned variables (all in pixel):

+
    +
  • bbx, bby - Offset to upper left corner of bounding box.
  • +
  • bbw, bbh - Dimensions of bounding box.
  • +
+

These values are the same as al_get_text_dimensions would return for a string of a single character equal to the glyph passed to this function. Note that glyphs may go to the left and upwards of the X, in which case x and y will have negative values.

+

If you want to draw a string verticallly, for Japanese or as a game effect, then you should leave bby + bbh space between the glyphs in the y direction for a regular placement.

+

If you want to draw a string horizontally in an extra compact way,
+then you should leave bbx + bbw space between the glyphs in the x direction for a compact placement.

+

In the figure below is an example of what bbx and bby may be like for a 2 glyph, and a g glyph of the same font compared to the result of al_get_glyph_width().

+
   al_get_glyph_width()     al_get_glyph_width()
+          __|___                   __|__
+         /      \                 /     \  
+     bbx    bbw                 bbx   bbw    
+    <-->+<------>+           <-->+<----->+   X baseline
+    ^   |        |           ^   |       |   
+bby |   |        |       bby |   |       |   
+    v   |        |           |   |       |   
+    +---+--------+           |   |       |
+    ^   | *****  |           |   |       |
+    |   |*    ** |           v   |       |
+bbh |   |    **  |       bbh +---+-------+
+    |   |  **    |           ^   | ***** |
+    v   |********|           |   |*     *|
+    +---+--------+           |   | ***** |
+                             |   |      *|
+                             |   | *    *|
+                             v   |  **** |
+                             +---+-------+
+

Since: 5.1.12

+

See also: al_draw_glyph, al_get_glyph_width, al_get_glyph_advance.

+

Examples:

+ +

al_get_glyph_advance

+
int al_get_glyph_advance(const ALLEGRO_FONT *f, int codepoint1, int codepoint2)
+

Source Code

+

This function returns by how much the x position should be advanced for left to right text drawing when the glyph that corresponds to codepoint1 has been drawn, and the glyph that corresponds to codepoint2 will be the next to be drawn. This takes into consideration the horizontal advance width of the glyph that corresponds with codepoint1 as well as the kerning between the glyphs of codepoint1 and codepoint2.

+

Kerning is the process of adjusting the spacing between glyphs in a font, to obtain a more visually pleasing result. Kerning adjusts the space between two individual glyphs with an offset determined by the author of the font.

+

If you pass ALLEGRO_NO_KERNING as codepoint1 then al_get_glyph_advance will return 0. this can be useful when drawing the first character of a string in a loop.

+

Pass ALLEGRO_NO_KERNING as codepoint2 to get the horizontal advance width of the glyph that corresponds to codepoint1 without taking any kerning into consideration. This can be used, for example, when drawing the last character of a string in a loop.

+

This function will return zero if the glyph of codepoint1 is not present in the font. If the glyph of codepoint2 is not present in the font, the horizontal advance width of the glyph that corresponds to codepoint1 without taking any kerning into consideration is returned.

+

When drawing a string one glyph at the time from the left to the right with kerning, the x position of the glyph should be incremented by the result of al_get_glyph_advance applied to the previous glyph drawn and the next glyph to draw.

+

Note that the return value of this function is a recommended advance for optimal readability for left to right text determined by the author of the font. However, if you like, you may want to draw the glyphs of the font narrower or wider to each other than what al_get_glyph_advance returns for style or effect.

+

In the figure below is an example of what the result of al_get_glyph_advance may be like for two glypphs A and l of the same font that has kerning for the “Al” pair, without and with the ALLEGRO_NO_KERNING flag.

+
al_get_glyph_advance(font, 'A', 'l')
+     ___|___                  
+    /       \  
+    -------------            
+        /\   -|  
+       /  \   |
+      /____\  |
+     /      \ |
+    /        \ \_             
+    -------------
+    
+    
+al_get_glyph_advance(font, 'A', ALLEGRO_NO_KERNING)
+     ____|____
+    /         \  
+    ---------------
+        /\     -|  
+       /  \     |
+      /____\    |
+     /      \   |
+    /        \   \_             
+    ---------------
+

Since: 5.1.12

+

See also: al_draw_glyph, al_get_glyph_width, al_get_glyph_dimensions.

+

Examples:

+ +

Multiline text drawing

+

al_draw_multiline_text

+
void al_draw_multiline_text(const ALLEGRO_FONT *font,
+     ALLEGRO_COLOR color, float x, float y, float max_width, float line_height,
+     int flags, const char *text)
+

Source Code

+

Like al_draw_text, but this function supports drawing multiple lines of text. It will break text in lines based on its contents and the max_width parameter. The lines are then layed out vertically depending on the line_height parameter and drawn each as if al_draw_text was called on them.

+

A newline \n in the text will cause a “hard” line break after its occurrence in the string. The text after a hard break is placed on a new line. Carriage return \r is not supported, will not cause a line break, and will likely be drawn as a square or a space depending on the font.

+

The max_width parameter controls the maximum desired width of the lines. This function will try to introduce a “soft” line break after the longest possible series of words that will fit in max_length when drawn with the given font. A “soft” line break can occur either on a space or tab (\t) character.

+

However, it is possible that max_width is too small, or the words in text are too long to fit max_width when drawn with font. In that case, the word that is too wide will simply be drawn completely on a line by itself. If you don’t want the text that overflows max_width to be visible, then use al_set_clipping_rectangle to clip it off and hide it.

+

The lines text was split into will each be drawn using the font, x, color and flags parameters, vertically starting at y and with a distance of line_height between them. If line_height is zero (0), the value returned by calling al_get_font_line_height on font will be used as a default instead.

+

The flags ALLEGRO_ALIGN_LEFT, ALLEGRO_ALIGN_CENTRE, ALLEGRO_ALIGN_RIGHT and ALLEGRO_ALIGN_INTEGER will be honoured by this function.

+

If you want to calculate the size of what this function will draw without actually drawing it, or if you need a complex and/or custom layout, you can use al_do_multiline_text.

+

Since: 5.1.9

+

See also: al_do_multiline_text, al_draw_multiline_ustr, al_draw_multiline_textf

+

Examples:

+ +

al_draw_multiline_ustr

+
void al_draw_multiline_ustr(const ALLEGRO_FONT *font,
+     ALLEGRO_COLOR color, float x, float y, float max_width, float line_height,
+     int flags, const ALLEGRO_USTR *ustr)
+

Source Code

+

Like al_draw_multiline_text, except the text is passed as an ALLEGRO_USTR instead of a NUL-terminated char array.

+

Since: 5.1.9

+

See also: al_draw_multiline_text, al_draw_multiline_textf, al_do_multiline_text

+

al_draw_multiline_textf

+
void al_draw_multiline_textf(const ALLEGRO_FONT *font,
+     ALLEGRO_COLOR color, float x, float y, float max_width, float line_height,
+     int flags, const char *format, ...)
+

Source Code

+

Formatted text output, using a printf() style format string. All parameters have the same meaning as with al_draw_multiline_text otherwise.

+

Since: 5.1.9

+

See also: al_draw_multiline_text, al_draw_multiline_ustr, al_do_multiline_text

+

Examples:

+ +

al_do_multiline_text

+
void al_do_multiline_text(const ALLEGRO_FONT *font,
+   float max_width, const char *text,
+   bool (*cb)(int line_num, const char *line, int size, void *extra),
+   void *extra)
+

Source Code

+

This function processes the text and splits it into lines as al_draw_multiline_text would, and then calls the callback cb once for every line. This is useful for custom drawing of multiline text, or for calculating the size of multiline text ahead of time. See the documentation on al_draw_multiline_text for an explanation of the splitting algorithm.

+

For every line that this function splits text into the callback cb will be called once with the following parameters:

+
    +
  • line_num - the number of the line starting from zero and counting up
  • +
  • line - a pointer to the beginning character of the line (see below)
  • +
  • size - the size of the line (0 for empty lines)
  • +
  • extra - the same pointer that was passed to al_do_multiline_text
  • +
+

Note that line is not guaranteed to be a NUL-terminated string, but will merely point to a character within text or to an empty string in case of an empty line. If you need a NUL-terminated string, you will have to copy line to a buffer and NUL-terminate it yourself. You will also have to make your own copy if you need the contents of line after cb has returned, as line is not guaranteed to be valid after that.

+

If the callback cb returns false, al_do_multiline_text will stop immediately, otherwise it will continue on to the next line.

+

Since: 5.1.9

+

See also: al_draw_multiline_text

+

Examples:

+ +

al_do_multiline_ustr

+
void al_do_multiline_ustr(const ALLEGRO_FONT *font, float max_width,
+   const ALLEGRO_USTR *ustr,
+   bool (*cb)(int line_num, const ALLEGRO_USTR * line, void *extra),
+   void *extra)
+

Source Code

+

Like al_do_multiline_text, but using ALLEGRO_USTR instead of a NUL-terminated char array for text.

+

Since: 5.1.9

+

See also: al_draw_multiline_ustr

+

Bitmap fonts

+

al_grab_font_from_bitmap

+
ALLEGRO_FONT *al_grab_font_from_bitmap(ALLEGRO_BITMAP *bmp,
+   int ranges_n, const int ranges[])
+

Source Code

+

Creates a new font from an Allegro bitmap. You can delete the bitmap after the function returns as the font will contain a copy for itself.

+

Parameters:

+
    +
  • bmp: The bitmap with the glyphs drawn onto it
  • +
  • n: Number of unicode ranges in the bitmap.
  • +
  • ranges: ‘n’ pairs of first and last unicode point to map glyphs to for each range.
  • +
+

The bitmap format is as in the following example, which contains three glyphs for 1, 2 and 3.

+
.............
+. 1 .222.333.
+. 1 .  2.  3.
+. 1 .222.333.
+. 1 .2  .  3.
+. 1 .222.333.
+.............
+

In the above illustration, the dot is for pixels having the background color. It is determined by the color of the top left pixel in the bitmap. There should be a border of at least 1 pixel with this color to the bitmap edge and between all glyphs.

+

Each glyph is inside a rectangle of pixels not containing the background color. The height of all glyph rectangles should be the same, but the width can vary.

+

The placement of the rectangles does not matter, except that glyphs are scanned from left to right and top to bottom to match them to the specified unicode codepoints.

+

The glyphs will simply be drawn using al_draw_bitmap, so usually you will want the rectangles filled with full transparency and the glyphs drawn in opaque white.

+

Examples:

+
int ranges[] = {32, 126};
+al_grab_font_from_bitmap(bitmap, 1, ranges)
+
+int ranges[] = {
+    0x0020, 0x007F,  /* ASCII */
+    0x00A1, 0x00FF,  /* Latin 1 */
+    0x0100, 0x017F,  /* Extended-A */
+    0x20AC, 0x20AC}; /* Euro */
+al_grab_font_from_bitmap(bitmap, 4, ranges)
+

The first example will grab glyphs for the 95 standard printable ASCII characters, beginning with the space character (32) and ending with the tilde character (126). The second example will map the first 96 glyphs found in the bitmap to ASCII range, the next 95 glyphs to Latin 1, the next 128 glyphs to Extended-A, and the last glyph to the Euro character. (This is just the characters found in the Allegro 4 font.)

+

See also: al_load_bitmap, al_grab_font_from_bitmap

+

Examples:

+ +

al_load_bitmap_font

+
ALLEGRO_FONT *al_load_bitmap_font(const char *fname)
+

Source Code

+

Load a bitmap font from a file. This is done by first calling al_load_bitmap_flags and then al_grab_font_from_bitmap.

+

If you wanted to load an old A4 font, for example, it would be better to load the bitmap yourself in order to call al_convert_mask_to_alpha on it before passing it to al_grab_font_from_bitmap.

+

See also: al_load_bitmap_font_flags, al_load_font, al_load_bitmap_flags

+

Examples:

+ +

al_load_bitmap_font_flags

+
ALLEGRO_FONT *al_load_bitmap_font_flags(const char *fname, int flags)
+

Source Code

+

Like al_load_bitmap_font but additionally takes a flags parameter which is a bitfield containing a combination of the following:

+
+
ALLEGRO_NO_PREMULTIPLIED_ALPHA
+
The same meaning as for al_load_bitmap_flags. +
+
+

See also: al_load_bitmap_font, al_load_bitmap_flags

+

al_create_builtin_font

+
ALLEGRO_FONT *al_create_builtin_font(void)
+

Source Code

+

Creates a monochrome bitmap font (8x8 pixels per character).

+

This font is primarily intended to be used for displaying information in environments or during early runtime states where no external font data is available or loaded (e.g. for debugging).

+

The builtin font contains the following unicode character ranges:

+
0x0020 to 0x007F (ASCII)
+0x00A1 to 0x00FF (Latin 1)
+0x0100 to 0x017F (Extended A)
+0x20AC to 0x20AC (euro currency symbol)
+

Returns NULL on an error.

+

The font memory must be freed the same way as for any other font, using al_destroy_font.

+

Since: 5.0.8, 5.1.3

+

See also: al_load_bitmap_font, al_destroy_font

+

Examples:

+ +

TTF fonts

+

These functions are declared in the following header file. Link with allegro_ttf.

+
 #include <allegro5/allegro_ttf.h>
+

al_init_ttf_addon

+
bool al_init_ttf_addon(void)
+

Source Code

+

Call this after al_init_font_addon to make al_load_font recognize “.ttf” and other formats supported by al_load_ttf_font.

+

Returns true on success, false on failure.

+

Examples:

+ +

al_is_ttf_addon_initialized

+
bool al_is_ttf_addon_initialized(void)
+

Source Code

+

Returns true if the TTF addon is initialized, otherwise returns false.

+

Since: 5.2.6

+

See also: al_init_ttf_addon, al_shutdown_ttf_addon

+

al_shutdown_ttf_addon

+
void al_shutdown_ttf_addon(void)
+

Source Code

+

Unloads the ttf addon again. You normally don’t need to call this.

+

al_load_ttf_font

+
ALLEGRO_FONT *al_load_ttf_font(char const *filename, int size, int flags)
+

Source Code

+

Loads a TrueType font from a file using the FreeType library. Quoting from the FreeType FAQ this means support for many different font formats:

+

TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and others

+

The size parameter determines the size the font will be rendered at, specified in pixels. The standard font size is measured in units per EM, if you instead want to specify the size as the total height of glyphs in pixels, pass it as a negative value.

+
+

Note: If you want to display text at multiple sizes, load the font multiple times with different size parameters.

+
+

The following flags are supported:

+
    +
  • ALLEGRO_TTF_NO_KERNING - Do not use any kerning even if the font file supports it.

  • +
  • ALLEGRO_TTF_MONOCHROME - Load as a monochrome font (which means no anti-aliasing of the font is done).

  • +
  • ALLEGRO_TTF_NO_AUTOHINT - Disable the Auto Hinter which is enabled by default in newer versions of FreeType. Since: 5.0.6, 5.1.2

  • +
+

See also: al_init_ttf_addon, al_load_ttf_font_f

+

Examples:

+ +

al_load_ttf_font_f

+
ALLEGRO_FONT *al_load_ttf_font_f(ALLEGRO_FILE *file,
+    char const *filename, int size, int flags)
+

Source Code

+

Like al_load_ttf_font, but the font is read from the file handle. The filename is only used to find possible additional files next to a font file.

+
+

Note: The file handle is owned by the returned ALLEGRO_FONT object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time.

+
+

al_load_ttf_font_stretch

+
ALLEGRO_FONT *al_load_ttf_font_stretch(char const *filename, int w, int h,
+   int flags)
+

Source Code

+

Like al_load_ttf_font, except it takes separate width and height parameters instead of a single size parameter.

+

If the height is a positive value, and the width zero or positive, then font will be stretched according to those parameters. The width must not be negative if the height is positive.

+

As with al_load_ttf_font, the height may be a negative value to specify the total height in pixels. Then the width must also be a negative value, or zero.

+

Returns NULL if the height is positive while width is negative, or if the height is negative while the width is positive.

+

Since: 5.0.6, 5.1.0

+

See also: al_load_ttf_font, al_load_ttf_font_stretch_f

+

al_load_ttf_font_stretch_f

+
ALLEGRO_FONT *al_load_ttf_font_stretch_f(ALLEGRO_FILE *file,
+    char const *filename, int w, int h, int flags)
+

Source Code

+

Like al_load_ttf_font_stretch, but the font is read from the file handle. The filename is only used to find possible additional files next to a font file.

+
+

Note: The file handle is owned by the returned ALLEGRO_FONT object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time.

+
+

Since: 5.0.6, 5.1.0

+

See also: al_load_ttf_font_stretch

+

al_get_allegro_ttf_version

+
uint32_t al_get_allegro_ttf_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

al_get_glyph

+
bool al_get_glyph(const ALLEGRO_FONT *f, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *glyph)
+

Source Code

+

Gets all the information about a glyph, including the bitmap, needed to draw it yourself. prev_codepoint is the codepoint in the string before the one you want to draw and is used for kerning. codepoint is the character you want to get info about. You should clear the ‘glyph’ structure to 0 with memset before passing it to this function for future compatibility.

+

Since: 5.2.1

+
+

Unstable API: This API is new and subject to refinement.

+
+

See also: ALLEGRO_GLYPH

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:43 UTC +

+
+ + diff --git a/allegro/docs/html/refman/fshook.html b/allegro/docs/html/refman/fshook.html new file mode 100644 index 00000000..db95b311 --- /dev/null +++ b/allegro/docs/html/refman/fshook.html @@ -0,0 +1,485 @@ + + + + + + + File system routines + + + + + + + + +
+ + +
+

File system routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

These functions allow access to the filesystem. This can either be the real filesystem like your harddrive, or a virtual filesystem like a .zip archive (or whatever else you or an addon makes it do).

+

ALLEGRO_FS_ENTRY

+
typedef struct ALLEGRO_FS_ENTRY ALLEGRO_FS_ENTRY;
+

Source Code

+

Opaque filesystem entry object. Represents a file or a directory (check with al_get_fs_entry_mode). There are no user accessible member variables.

+

Examples:

+ +

ALLEGRO_FILE_MODE

+
typedef enum ALLEGRO_FILE_MODE
+

Source Code

+

Filesystem modes/types

+
    +
  • ALLEGRO_FILEMODE_READ - Readable
  • +
  • ALLEGRO_FILEMODE_WRITE - Writable
  • +
  • ALLEGRO_FILEMODE_EXECUTE - Executable
  • +
  • ALLEGRO_FILEMODE_HIDDEN - Hidden
  • +
  • ALLEGRO_FILEMODE_ISFILE - Regular file
  • +
  • ALLEGRO_FILEMODE_ISDIR - Directory
  • +
+

al_create_fs_entry

+
ALLEGRO_FS_ENTRY *al_create_fs_entry(const char *path)
+

Source Code

+

Creates an ALLEGRO_FS_ENTRY object pointing to path on the filesystem. ‘path’ can be a file or a directory and must not be NULL.

+

Examples:

+ +

al_destroy_fs_entry

+
void al_destroy_fs_entry(ALLEGRO_FS_ENTRY *fh)
+

Source Code

+

Destroys a fs entry handle. The file or directory represented by it is not destroyed. If the entry was opened, it is closed before being destroyed.

+

Does nothing if passed NULL.

+

Examples:

+ +

al_get_fs_entry_name

+
const char *al_get_fs_entry_name(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Returns the entry’s filename path. Note that the filesystem encoding may not be known and the conversion to UTF-8 could in very rare cases cause this to return an invalid path. Therefore it’s always safest to access the file over its ALLEGRO_FS_ENTRY and not the path.

+

On success returns a read only string which you must not modify or destroy. Returns NULL on failure.

+
+

Note: prior to 5.1.5 it was written: “… the path will not be an absolute path if the entry wasn’t created from an absolute path”. This is no longer true.

+
+

Examples:

+ +

al_update_fs_entry

+
bool al_update_fs_entry(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Updates file status information for a filesystem entry. File status information is automatically updated when the entry is created, however you may update it again with this function, e.g. in case it changed.

+

Returns true on success, false on failure. Fills in errno to indicate the error.

+

See also: al_get_errno, al_get_fs_entry_atime, al_get_fs_entry_ctime, al_get_fs_entry_mode

+

al_get_fs_entry_mode

+
uint32_t al_get_fs_entry_mode(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Returns the entry’s mode flags, i.e. permissions and whether the entry refers to a file or directory.

+

See also: al_get_errno, ALLEGRO_FILE_MODE

+

Examples:

+ +

al_get_fs_entry_atime

+
time_t al_get_fs_entry_atime(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Returns the time in seconds since the epoch since the entry was last accessed.

+

Warning: some filesystems either don’t support this flag, or people turn it off to increase performance. It may not be valid in all circumstances.

+

See also: al_get_fs_entry_ctime, al_get_fs_entry_mtime, al_update_fs_entry

+

Examples:

+ +

al_get_fs_entry_ctime

+
time_t al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Returns the time in seconds since the epoch this entry was created on the filesystem.

+

See also: al_get_fs_entry_atime, al_get_fs_entry_mtime, al_update_fs_entry

+

Examples:

+ +

al_get_fs_entry_mtime

+
time_t al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Returns the time in seconds since the epoch since the entry was last modified.

+

See also: al_get_fs_entry_atime, al_get_fs_entry_ctime, al_update_fs_entry

+

Examples:

+ +

al_get_fs_entry_size

+
off_t al_get_fs_entry_size(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Returns the size, in bytes, of the given entry. May not return anything sensible for a directory entry.

+

See also: al_update_fs_entry

+

Examples:

+ +

al_fs_entry_exists

+
bool al_fs_entry_exists(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Check if the given entry exists on in the filesystem. Returns true if it does exist or false if it doesn’t exist, or an error occurred. Error is indicated in Allegro’s errno.

+

See also: al_filename_exists

+

al_remove_fs_entry

+
bool al_remove_fs_entry(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Delete this filesystem entry from the filesystem. Only files and empty directories may be deleted.

+

Returns true on success, and false on failure, error is indicated in Allegro’s errno.

+

See also: al_filename_exists

+

al_filename_exists

+
bool al_filename_exists(const char *path)
+

Source Code

+

Check if the path exists on the filesystem, without creating an ALLEGRO_FS_ENTRY object explicitly.

+

See also: al_fs_entry_exists

+

al_remove_filename

+
bool al_remove_filename(const char *path)
+

Source Code

+

Delete the given path from the filesystem, which may be a file or an empty directory. This is the same as al_remove_fs_entry, except it expects the path as a string.

+

Returns true on success, and false on failure. Allegro’s errno is filled in to indicate the error.

+

See also: al_remove_fs_entry

+

Examples:

+ +

Directory functions

+

al_open_directory

+
bool al_open_directory(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Opens a directory entry object. You must call this before using al_read_directory on an entry and you must call al_close_directory when you no longer need it.

+

Returns true on success.

+

See also: al_read_directory, al_close_directory

+

Examples:

+ +

al_read_directory

+
ALLEGRO_FS_ENTRY *al_read_directory(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Reads the next directory item and returns a filesystem entry for it.

+

Returns NULL if there are no more entries or if an error occurs. Call al_destroy_fs_entry on the returned entry when you are done with it.

+

This function will ignore any files or directories named . or .. which may exist on certain platforms and may signify the current and the parent directory.

+

See also: al_open_directory, al_close_directory

+

Examples:

+ +

al_close_directory

+
bool al_close_directory(ALLEGRO_FS_ENTRY *e)
+

Source Code

+

Closes a previously opened directory entry object.

+

Returns true on success, false on failure and fills in Allegro’s errno to indicate the error.

+

See also: al_open_directory, al_read_directory

+

Examples:

+ +

al_get_current_directory

+
char *al_get_current_directory(void)
+

Source Code

+

Returns the path to the current working directory, or NULL on failure. The returned path is dynamically allocated and must be destroyed with al_free.

+

Allegro’s errno is filled in to indicate the error if there is a failure. This function may not be implemented on some (virtual) filesystems.

+

See also: al_get_errno, al_free

+

al_change_directory

+
bool al_change_directory(const char *path)
+

Source Code

+

Changes the current working directory to ‘path’.

+

Returns true on success, false on error.

+

al_make_directory

+
bool al_make_directory(const char *path)
+

Source Code

+

Creates a new directory on the filesystem. This function also creates any parent directories as needed.

+

Returns true on success (including if the directory already exists), otherwise returns false on error. Fills in Allegro’s errno to indicate the error.

+

See also: al_get_errno

+

al_open_fs_entry

+
ALLEGRO_FILE *al_open_fs_entry(ALLEGRO_FS_ENTRY *e, const char *mode)
+

Source Code

+

Open an ALLEGRO_FILE handle to a filesystem entry, for the given access mode. This is like calling al_fopen with the name of the filesystem entry, but uses the appropriate file interface, not whatever was set with the latest call to al_set_new_file_interface.

+

Returns the handle on success, NULL on error.

+

See also: al_fopen

+

ALLEGRO_FOR_EACH_FS_ENTRY_RESULT

+
typedef enum ALLEGRO_FOR_EACH_FS_ENTRY_RESULT {
+

Source Code

+

Return values for the callbacks of al_for_each_fs_entry and for that function itself.

+
    +
  • ALLEGRO_FOR_EACH_FS_ENTRY_ERROR - An error ocurred.
  • +
  • ALLEGRO_FOR_EACH_FS_ENTRY_OK - Continue normally and recurse into directories.
  • +
  • ALLEGRO_FOR_EACH_FS_ENTRY_SKIP - Continue but do NOT recusively descend.
  • +
  • ALLEGRO_FOR_EACH_FS_ENTRY_STOP - Stop iterating and return.
  • +
+

See also: al_for_each_fs_entry

+

Since: 5.1.9

+

al_for_each_fs_entry

+
int al_for_each_fs_entry(ALLEGRO_FS_ENTRY *dir,
+                         int (*callback)(ALLEGRO_FS_ENTRY *dir, void *extra),
+                         void *extra)
+

Source Code

+

This function takes the ALLEGRO_FS_ENTRY dir, which should represent a directory, and looks for any other file system entries that are in it. This function will then call the callback function callback once for every filesystem entry in the directory dir.

+

The callback callback must be of type int callback(ALLEGRO_FS_ENTRY * entry, void * extra). The callback will be called with a pointer to an ALLEGRO_FS_ENTRY that matches one file or directory in dir, and the pointer passed in the extra parameter to al_for_each_fs_entry.

+

When callback returns ALLEGRO_FOR_EACH_FS_ENTRY_STOP or ALLEGRO_FOR_EACH_FS_ENTRY_ERROR, iteration will stop immediately and al_for_each_fs_entry will return the value the callback returned.

+

When callback returns ALLEGRO_FOR_EACH_FS_ENTRY_OK iteration will continue normally, and if the ALLEGRO_FS_ENTRY parameter of callback is a directory, al_for_each_fs_entry will call itself on that directory. Therefore the function will recusively descend into that directory.

+

However, when callback returns ALLEGRO_FOR_EACH_FS_ENTRY_SKIP iteration will continue, but al_for_each_fs_entry will NOT recurse into the ALLEGRO_FS_ENTRY parameter of callback even if it is a directory.

+

This function will skip any files or directories named . or .. which may exist on certain platforms and may signify the current and the parent directory. The callback will not be called for files or directories with such a name.

+

Returns ALLEGRO_FOR_EACH_FS_ENTRY_OK if successful, or ALLEGRO_FOR_EACH_FS_ENTRY_ERROR if something went wrong in processing the directory. In that case it will use al_set_errno to indicate the type of error which occurred. This function returns ALLEGRO_FOR_EACH_FS_ENTRY_STOP in case iteration was stopped by making callback return that value. In this case, al_set_errno will not be used.

+

See also: ALLEGRO_FOR_EACH_FS_ENTRY_RESULT

+

Since: 5.1.9

+

Examples:

+ +

Alternative filesystem functions

+

By default, Allegro uses platform specific filesystem functions for things like directory access. However if for example the files of your game are not in the local filesystem but inside some file archive, you can provide your own set of functions (or use an addon which does this for you, for example our physfs addon allows access to the most common archive formats).

+

ALLEGRO_FS_INTERFACE

+
typedef struct ALLEGRO_FS_INTERFACE ALLEGRO_FS_INTERFACE;
+

Source Code

+

The available functions you can provide for a filesystem. They are:

+
   ALLEGRO_FS_ENTRY *  fs_create_entry   (const char *path);
+   void                fs_destroy_entry  (ALLEGRO_FS_ENTRY *e);
+   const char *        fs_entry_name     (ALLEGRO_FS_ENTRY *e);
+   bool                fs_update_entry   (ALLEGRO_FS_ENTRY *e);
+   uint32_t            fs_entry_mode     (ALLEGRO_FS_ENTRY *e);
+   time_t              fs_entry_atime    (ALLEGRO_FS_ENTRY *e);
+   time_t              fs_entry_mtime    (ALLEGRO_FS_ENTRY *e);
+   time_t              fs_entry_ctime    (ALLEGRO_FS_ENTRY *e);
+   off_t               fs_entry_size     (ALLEGRO_FS_ENTRY *e);
+   bool                fs_entry_exists   (ALLEGRO_FS_ENTRY *e);
+   bool                fs_remove_entry   (ALLEGRO_FS_ENTRY *e);
+
+   bool                fs_open_directory (ALLEGRO_FS_ENTRY *e);
+   ALLEGRO_FS_ENTRY *  fs_read_directory (ALLEGRO_FS_ENTRY *e);
+   bool                fs_close_directory(ALLEGRO_FS_ENTRY *e);
+
+   bool                fs_filename_exists(const char *path);
+   bool                fs_remove_filename(const char *path);
+   char *              fs_get_current_directory(void);
+   bool                fs_change_directory(const char *path);
+   bool                fs_make_directory(const char *path);
+
+   ALLEGRO_FILE *      fs_open_file(ALLEGRO_FS_ENTRY *e);
+

al_set_fs_interface

+
void al_set_fs_interface(const ALLEGRO_FS_INTERFACE *fs_interface)
+

Source Code

+

Set the ALLEGRO_FS_INTERFACE table for the calling thread.

+

See also: al_set_standard_fs_interface, al_store_state, al_restore_state.

+

al_set_standard_fs_interface

+
void al_set_standard_fs_interface(void)
+

Source Code

+

Return the ALLEGRO_FS_INTERFACE table to the default, for the calling thread.

+

See also: al_set_fs_interface.

+

al_get_fs_interface

+
const ALLEGRO_FS_INTERFACE *al_get_fs_interface(void)
+

Source Code

+

Return a pointer to the ALLEGRO_FS_INTERFACE table in effect for the calling thread.

+

See also: al_store_state, al_restore_state.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/fullscreen_mode.html b/allegro/docs/html/refman/fullscreen_mode.html new file mode 100644 index 00000000..244d82df --- /dev/null +++ b/allegro/docs/html/refman/fullscreen_mode.html @@ -0,0 +1,222 @@ + + + + + + + Fullscreen modes + + + + + + + + +
+ + +
+

Fullscreen modes

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_DISPLAY_MODE

+
typedef struct ALLEGRO_DISPLAY_MODE
+

Source Code

+

Used for fullscreen mode queries. Contains information about a supported fullscreen modes.

+
typedef struct ALLEGRO_DISPLAY_MODE {
+   int width;          // Screen width
+   int height;         // Screen height
+   int format;         // The pixel format of the mode
+   int refresh_rate;   // The refresh rate of the mode
+} ALLEGRO_DISPLAY_MODE;
+

The refresh_rate may be zero if unknown.

+

For an explanation of what format means, see ALLEGRO_PIXEL_FORMAT.

+

See also: al_get_display_mode

+

Examples:

+ +

al_get_display_mode

+
ALLEGRO_DISPLAY_MODE *al_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode)
+

Source Code

+

Retrieves a fullscreen mode. Display parameters should not be changed between a call of al_get_num_display_modes and al_get_display_mode. index must be between 0 and the number returned from al_get_num_display_modes-1. mode must be an allocated ALLEGRO_DISPLAY_MODE structure. This function will return NULL on failure, and the mode parameter that was passed in on success.

+

See also: ALLEGRO_DISPLAY_MODE, al_get_num_display_modes

+

Examples:

+ +

al_get_num_display_modes

+
int al_get_num_display_modes(void)
+

Source Code

+

Get the number of available fullscreen display modes for the current set of display parameters. This will use the values set with al_set_new_display_refresh_rate, and al_set_new_display_flags to find the number of modes that match. Settings the new display parameters to zero will give a list of all modes for the default driver.

+

See also: al_get_display_mode

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/getting_started.html b/allegro/docs/html/refman/getting_started.html new file mode 100644 index 00000000..21dfea65 --- /dev/null +++ b/allegro/docs/html/refman/getting_started.html @@ -0,0 +1,198 @@ + + + + + + + Getting started guide + + + + + + + + +
+ + +
+

Getting started guide

+
+ +

Introduction

+

Welcome to Allegro 5!

+

This short guide should point you at the parts of the API that you’ll want to know about first. It’s not a tutorial, as there isn’t much discussion, only links into the manual. The rest you’ll have to discover for yourself. Read the examples, and ask questions at Allegro.cc.

+

There is an unofficial tutorial at the wiki. Be aware that, being on the wiki, it may be a little out of date, but the changes should be minor. Hopefully more will sprout when things stabilise, as they did for earlier versions of Allegro.

+

Structure of the library and its addons

+

Allegro 5.0 is divided into a core library and multiple addons. The addons are bundled together and built at the same time as the core, but they are distinct and kept in separate libraries. The core doesn’t depend on anything in the addons, but addons may depend on the core and other addons and additional third party libraries.

+

Here are the addons and their dependencies:

+
allegro_main -> allegro
+
+allegro_image -> allegro
+allegro_primitives -> allegro
+allegro_color -> allegro
+
+allegro_font -> allegro
+allegro_ttf -> allegro_font -> allegro
+
+allegro_audio -> allegro
+allegro_acodec -> allegro_audio -> allegro
+allegro_video -> allegro_audio -> allegro
+
+allegro_memfile -> allegro
+allegro_physfs -> allegro
+
+allegro_native_dialog -> allegro
+

The header file for the core library is allegro5/allegro.h. The header files for the addons are named allegro5/allegro_image.h, allegro5/allegro_font.h, etc. The allegro_main addon does not have a header file.

+

The main function

+

For the purposes of cross-platform compatibility Allegro puts some requirements on your main function. First, you must include the core header (allegro5/allegro.h) in the same file as your main function. Second, if your main function is inside a C++ file, then it must have this signature: int main(int argc, char **argv). Third, if you’re using C/C++ then you need to link with the allegro_main addon when building your program.

+

Initialisation

+

Before using Allegro you must call al_init. Some addons have their own initialisation, e.g. al_init_image_addon, al_init_font_addon, al_init_ttf_addon.

+

To receive input, you need to initialise some subsystems like al_install_keyboard, al_install_mouse, al_install_joystick.

+

Opening a window

+

al_create_display will open a window and return an ALLEGRO_DISPLAY.

+

To clear the display, call al_clear_to_color. Use al_map_rgba or al_map_rgba_f to obtain an ALLEGRO_COLOR parameter.

+

Drawing operations are performed on a backbuffer. To make the operations visible, call al_flip_display.

+

Display an image

+

To load an image from disk, you need to have initialised the image I/O addon with al_init_image_addon. Then use al_load_bitmap, which returns an ALLEGRO_BITMAP.

+

Use al_draw_bitmap, al_draw_scaled_bitmap or al_draw_scaled_rotated_bitmap to draw the image to the backbuffer. Remember to call al_flip_display.

+

Changing the drawing target

+

Notice that al_clear_to_color and al_draw_bitmap didn’t take destination parameters: the destination is implicit. Allegro remembers the current “target bitmap” for the current thread. To change the target bitmap, call al_set_target_bitmap.

+

The backbuffer of the display is also a bitmap. You can get it with al_get_backbuffer and then restore it as the target bitmap.

+

Other bitmaps can be created with al_create_bitmap, with options which can be adjusted with al_set_new_bitmap_flags and al_set_new_bitmap_format.

+

Event queues and input

+

Input comes from multiple sources: keyboard, mouse, joystick, timers, etc. Event queues aggregate events from all these sources, then you can query the queue for events.

+

Create an event queue with al_create_event_queue, then tell input sources to place new events into that queue using al_register_event_source. The usual input event sources can be retrieved with al_get_keyboard_event_source, al_get_mouse_event_source and al_get_joystick_event_source.

+

Events can be retrieved with al_wait_for_event or al_get_next_event. Check the event type and other fields of ALLEGRO_EVENT to react to the input.

+

Displays are also event sources, which emit events when they are resized. You’ll need to set the ALLEGRO_RESIZABLE flag with al_set_new_display_flags before creating the display, then register the display with an event queue. When you get a resize event, call al_acknowledge_resize.

+

Timers are event sources which “tick” periodically, causing an event to be inserted into the queues that the timer is registered with. Create some with al_create_timer.

+

al_get_time and al_rest are more direct ways to deal with time.

+

Displaying some text

+

To display some text, initialise the image and font addons with al_init_image_addon and al_init_font_addon, then load a bitmap font with al_load_font. Use al_draw_text or al_draw_textf.

+

For TrueType fonts, you’ll need to initialise the TTF font addon with al_init_ttf_addon and load a TTF font with al_load_ttf_font.

+

Drawing primitives

+

The primitives addon provides some handy routines to draw lines (al_draw_line), rectangles (al_draw_rectangle), circles (al_draw_circle), etc.

+

Blending

+

To draw translucent or tinted images or primitives, change the blender state with al_set_blender.

+

As with al_set_target_bitmap, this changes Allegro’s internal state (for the current thread). Often you’ll want to save some part of the state and restore it later. The functions al_store_state and al_restore_state provide a convenient way to do that.

+

Sound

+

Use al_install_audio to initialize sound. To load any sample formats, you will need to initialise the acodec addon with al_init_acodec_addon.

+

After that, you can simply use al_reserve_samples and pass the number of sound effects typically playing at the same time. Then load your sound effects with al_load_sample and play them with al_play_sample. To stream large pieces of music from disk, you can use al_load_audio_stream so the whole piece will not have to be pre-loaded into memory.

+

If the above sounds too simple and you can’t help but think about clipping and latency issues, don’t worry. Allegro gives you full control over how much or little you want its sound system to do. The al_reserve_samples function mentioned above only sets up a default mixer and a number of sample instances but you don’t need to use it.

+

Instead, to get a “direct connection” to the sound system you would use an ALLEGRO_VOICE (but depending on the platform only one such voice is guaranteed to be available and it might require a specific format of audio data). Therefore all sound can be first routed through an ALLEGRO_MIXER which is connected to such a voice (or another mixer) and will mix together all sample data fed to it.

+

You can then directly stream real-time sample data to a mixer or a voice using an ALLEGRO_AUDIO_STREAM or play complete sounds using an ALLEGRO_SAMPLE_INSTANCE. The latter simply points to an ALLEGRO_SAMPLE and will stream it for you.

+

Unstable API

+

Some of Allegro’s API is marked as unstable, which means that in future versions of Allegro it may change or even be removed entirely! If you want to experiment with the unstable API, define ALLEGRO_UNSTABLE macro before including Allegro’s headers.

+

Note that when you define that macro, the version check performed by al_install_system and al_init becomes more scrict. See documentation of those functions for details.

+

Not the end

+

There’s a heap of stuff we haven’t even mentioned yet.

+

Enjoy!

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/graphics.html b/allegro/docs/html/refman/graphics.html new file mode 100644 index 00000000..4a1ac1ac --- /dev/null +++ b/allegro/docs/html/refman/graphics.html @@ -0,0 +1,1895 @@ + + + + + + + Graphics routines + + + + + + + + +
+ + +
+

Graphics routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

Colors

+

ALLEGRO_COLOR

+
typedef struct ALLEGRO_COLOR ALLEGRO_COLOR;
+

Source Code

+

An ALLEGRO_COLOR structure describes a color in a device independent way. Use al_map_rgb et al. and al_unmap_rgb et al. to translate from and to various color representations.

+

Examples:

+ +

al_map_rgb

+
ALLEGRO_COLOR al_map_rgb(
+   unsigned char r, unsigned char g, unsigned char b)
+

Source Code

+

Convert r, g, b (ranging from 0-255) into an ALLEGRO_COLOR, using 255 for alpha.

+

This function can be called before Allegro is initialized.

+

See also: al_map_rgba, al_map_rgba_f, al_map_rgb_f

+

Examples:

+ +

al_map_rgb_f

+
ALLEGRO_COLOR al_map_rgb_f(float r, float g, float b)
+

Source Code

+

Convert r, g, b, (ranging from 0.0f-1.0f) into an ALLEGRO_COLOR, using 1.0f for alpha.

+

This function can be called before Allegro is initialized.

+

See also: al_map_rgba, al_map_rgb, al_map_rgba_f

+

Examples:

+ +

al_map_rgba

+
ALLEGRO_COLOR al_map_rgba(
+   unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+

Source Code

+

Convert r, g, b, a (ranging from 0-255) into an ALLEGRO_COLOR.

+

This function can be called before Allegro is initialized.

+

See also: al_map_rgb, al_premul_rgba, al_map_rgb_f

+

Examples:

+ +

al_premul_rgba

+
ALLEGRO_COLOR al_premul_rgba(
+   unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+

Source Code

+

This is a shortcut for al_map_rgba(r * a / 255, g * a / 255, b * a / 255, a).

+

By default Allegro uses pre-multiplied alpha for transparent blending of bitmaps and primitives (see al_load_bitmap_flags for a discussion of that feature). This means that if you want to tint a bitmap or primitive to be transparent you need to multiply the color components by the alpha components when you pass them to this function. For example:

+
int r = 255;
+int g = 0;
+int b = 0;
+int a = 127;
+ALLEGRO_COLOR c = al_premul_rgba(r, g, b, a);
+/* Draw the bitmap tinted red and half-transparent. */
+al_draw_tinted_bitmap(bmp, c, 0, 0, 0);
+

This function can be called before Allegro is initialized.

+

Since: 5.1.12

+

See also: al_map_rgba, al_premul_rgba_f

+

al_map_rgba_f

+
ALLEGRO_COLOR al_map_rgba_f(float r, float g, float b, float a)
+

Source Code

+

Convert r, g, b, a (ranging from 0.0f-1.0f) into an ALLEGRO_COLOR.

+

This function can be called before Allegro is initialized.

+

See also: al_map_rgba, al_premul_rgba_f, al_map_rgb_f

+

Examples:

+ +

al_premul_rgba_f

+
ALLEGRO_COLOR al_premul_rgba_f(float r, float g, float b, float a)
+

Source Code

+

This is a shortcut for al_map_rgba_f(r * a, g * a, b * a, a).

+

By default Allegro uses pre-multiplied alpha for transparent blending of bitmaps and primitives (see al_load_bitmap_flags for a discussion of that feature). This means that if you want to tint a bitmap or primitive to be transparent you need to multiply the color components by the alpha components when you pass them to this function. For example:

+
float r = 1;
+float g = 0;
+float b = 0;
+float a = 0.5;
+ALLEGRO_COLOR c = al_premul_rgba_f(r, g, b, a);
+/* Draw the bitmap tinted red and half-transparent. */
+al_draw_tinted_bitmap(bmp, c, 0, 0, 0);
+

This function can be called before Allegro is initialized.

+

Since: 5.1.12

+

See also: al_map_rgba_f, al_premul_rgba

+

al_unmap_rgb

+
void al_unmap_rgb(ALLEGRO_COLOR color,
+   unsigned char *r, unsigned char *g, unsigned char *b)
+

Source Code

+

Retrieves components of an ALLEGRO_COLOR, ignoring alpha. Components will range from 0-255.

+

This function can be called before Allegro is initialized.

+

See also: al_unmap_rgba, al_unmap_rgba_f, al_unmap_rgb_f

+

Examples:

+ +

al_unmap_rgb_f

+
void al_unmap_rgb_f(ALLEGRO_COLOR color, float *r, float *g, float *b)
+

Source Code

+

Retrieves components of an ALLEGRO_COLOR, ignoring alpha. Components will range from 0.0f-1.0f.

+

This function can be called before Allegro is initialized.

+

See also: al_unmap_rgba, al_unmap_rgb, al_unmap_rgba_f

+

Examples:

+ +

al_unmap_rgba

+
void al_unmap_rgba(ALLEGRO_COLOR color,
+   unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
+

Source Code

+

Retrieves components of an ALLEGRO_COLOR. Components will range from 0-255.

+

This function can be called before Allegro is initialized.

+

See also: al_unmap_rgb, al_unmap_rgba_f, al_unmap_rgb_f

+

Examples:

+ +

al_unmap_rgba_f

+
void al_unmap_rgba_f(ALLEGRO_COLOR color,
+   float *r, float *g, float *b, float *a)
+

Source Code

+

Retrieves components of an ALLEGRO_COLOR. Components will range from 0.0f-1.0f.

+

This function can be called before Allegro is initialized.

+

See also: al_unmap_rgba, al_unmap_rgb, al_unmap_rgb_f

+

Examples:

+ +

Locking and pixel formats

+

ALLEGRO_LOCKED_REGION

+
typedef struct ALLEGRO_LOCKED_REGION ALLEGRO_LOCKED_REGION;
+

Source Code

+

Users who wish to manually edit or read from a bitmap are required to lock it first. The ALLEGRO_LOCKED_REGION structure represents the locked region of the bitmap. This call will work with any bitmap, including memory bitmaps.

+
typedef struct ALLEGRO_LOCKED_REGION {
+   void *data;
+   int format;
+   int pitch;
+   int pixel_size;
+} ALLEGRO_LOCKED_REGION;
+
    +
  • data points to the leftmost pixel of the first row (row 0) of the locked region. For blocked formats, this points to the leftmost block of the first row of blocks.

  • +
  • format indicates the pixel format of the data.

  • +
  • pitch gives the size in bytes of a single row (also known as the stride). The pitch may be greater than width * pixel_size due to padding; this is not uncommon. It is also not uncommon for the pitch to be negative (the bitmap may be upside down). For blocked formats, ‘row’ refers to the row of blocks, not of pixels.

  • +
  • pixel_size is the number of bytes used to represent a single block of pixels for the pixel format of this locked region. For most formats (and historically, this used to be true for all formats), this is just the size of a single pixel, but for blocked pixel formats this value is different.

  • +
+

See also: al_lock_bitmap, al_lock_bitmap_region, al_unlock_bitmap, ALLEGRO_PIXEL_FORMAT

+

Examples:

+ +

ALLEGRO_PIXEL_FORMAT

+
typedef enum ALLEGRO_PIXEL_FORMAT
+

Source Code

+

Pixel formats. Each pixel format specifies the exact size and bit layout of a pixel in memory. Components are specified from high bits to low bits, so for example a fully opaque red pixel in ARGB_8888 format is 0xFFFF0000.

+
+

Note:

+

The pixel format is independent of endianness. That is, in the above example you can always get the red component with

+
(pixel & 0x00ff0000) >> 16
+

But you can not rely on this code:

+
*(pixel + 2)
+

It will return the red component on little endian systems, but the green component on big endian systems.

+
+

Also note that Allegro’s naming is different from OpenGL naming here, where a format of GL_RGBA8 merely defines the component order and the exact layout including endianness treatment is specified separately. Usually GL_RGBA8 will correspond to ALLEGRO_PIXEL_ABGR_8888 though on little endian systems, so care must be taken (note the reversal of RGBA <-> ABGR).

+

The only exception to this ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which will always have the components as 4 bytes corresponding to red, green, blue and alpha, in this order, independent of the endianness.

+

Some of the pixel formats represent compressed bitmap formats. Compressed bitmaps take up less space in the GPU memory than bitmaps with regular (uncompressed) pixel formats. This smaller footprint means that you can load more resources into GPU memory, and they will be drawn somewhat faster. The compression is lossy, however, so it is not appropriate for all graphical styles: it tends to work best for images with smooth color gradations. It is possible to compress bitmaps at runtime by passing the appropriate bitmap format in al_set_new_bitmap_format and then creating, loading, cloning or converting a non-compressed bitmap. This, however, is not recommended as the compression quality differs between different GPU drivers. It is recommended to compress these bitmaps ahead of time using external tools and then load them compressed.

+

Unlike regular pixel formats, compressed pixel formats are not laid out in memory one pixel row at a time. Instead, the bitmap is subdivided into rectangular blocks of pixels that are then laid out in block rows. This means that regular locking functions cannot use compressed pixel formats as the destination format. Instead, you can use the blocked versions of the bitmap locking functions which do support these formats.

+

It is not recommended to use compressed bitmaps as target bitmaps, as that operation cannot be hardware accelerated. Due to proprietary algorithms used, it is typically impossible to create compressed memory bitmaps.

+
    +
  • ALLEGRO_PIXEL_FORMAT_ANY - Let the driver choose a format. This is the default format at program start.
  • +
  • ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA - Let the driver choose a format without alpha.
  • +
  • ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA - Let the driver choose a format with alpha.
  • +
  • ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA - Let the driver choose a 15 bit format without alpha.
  • +
  • ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA - Let the driver choose a 16 bit format without alpha.
  • +
  • ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA - Let the driver choose a 16 bit format with alpha.
  • +
  • ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA - Let the driver choose a 24 bit format without alpha.
  • +
  • ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA - Let the driver choose a 32 bit format without alpha.
  • +
  • ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA - Let the driver choose a 32 bit format with alpha.
  • +
  • ALLEGRO_PIXEL_FORMAT_ARGB_8888 - 32 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_RGBA_8888 - 32 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_ARGB_4444 - 16 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_RGB_888 - 24 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_RGB_565 - 16 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_RGB_555 - 15 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_RGBA_5551 - 16 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_ARGB_1555 - 16 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_ABGR_8888 - 32 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_XBGR_8888 - 32 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_BGR_888 - 24 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_BGR_565 - 16 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_BGR_555 - 15 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_RGBX_8888 - 32 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_XRGB_8888 - 32 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_ABGR_F32 - 128 bit
  • +
  • ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE - Like the version without _LE, but the component order is guaranteed to be red, green, blue, alpha. This only makes a difference on big endian systems, on little endian it is just an alias.
  • +
  • ALLEGRO_PIXEL_FORMAT_RGBA_4444 - 16bit
  • +
  • ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 - A single 8-bit channel. A pixel value maps onto the red channel when displayed, but it is undefined how it maps onto green, blue and alpha channels. When drawing to bitmaps of this format, only the red channel is taken into account. Allegro may have to use fallback methods to render to bitmaps of this format. This pixel format is mainly intended for storing the color indices of an indexed (paletted) image, usually in conjunction with a pixel shader that maps indices to RGBA values. Since 5.1.2.
  • +
  • ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1 - Compressed using the DXT1 compression algorithm. Each 4x4 pixel block is encoded in 64 bytes, resulting in 6-8x compression ratio. Only a single bit of alpha per pixel is supported. Since 5.1.9.
  • +
  • ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3 - Compressed using the DXT3 compression algorithm. Each 4x4 pixel block is encoded in 128 bytes, resulting in 4x compression ratio. This format supports sharp alpha transitions. Since 5.1.9.
  • +
  • ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5 - Compressed using the DXT5 compression algorithm. Each 4x4 pixel block is encoded in 128 bytes, resulting in 4x compression ratio. This format supports smooth alpha transitions. Since 5.1.9.
  • +
+

See also: al_set_new_bitmap_format, al_get_bitmap_format

+

Examples:

+ +

al_get_pixel_size

+
int al_get_pixel_size(int format)
+

Source Code

+

Return the number of bytes that a pixel of the given format occupies. For blocked pixel formats (e.g. compressed formats), this returns 0.

+

See also: ALLEGRO_PIXEL_FORMAT, al_get_pixel_format_bits

+

al_get_pixel_format_bits

+
int al_get_pixel_format_bits(int format)
+

Source Code

+

Return the number of bits that a pixel of the given format occupies. For blocked pixel formats (e.g. compressed formats), this returns 0.

+

See also: ALLEGRO_PIXEL_FORMAT, al_get_pixel_size

+

al_get_pixel_block_size

+
int al_get_pixel_block_size(int format)
+

Source Code

+

Return the number of bytes that a block of pixels with this format occupies.

+

Since: 5.1.9.

+

See also: ALLEGRO_PIXEL_FORMAT, al_get_pixel_block_width, al_get_pixel_block_height

+

al_get_pixel_block_width

+
int al_get_pixel_block_width(int format)
+

Source Code

+

Return the width of the the pixel block for this format.

+

Since: 5.1.9.

+

See also: ALLEGRO_PIXEL_FORMAT, al_get_pixel_block_size, al_get_pixel_block_height

+

Examples:

+ +

al_get_pixel_block_height

+
int al_get_pixel_block_height(int format)
+

Source Code

+

Return the height of the the pixel block for this format.

+

Since: 5.1.9.

+

See also: ALLEGRO_PIXEL_FORMAT, al_get_pixel_block_size, al_get_pixel_block_width

+

Examples:

+ +

al_lock_bitmap

+
ALLEGRO_LOCKED_REGION *al_lock_bitmap(ALLEGRO_BITMAP *bitmap,
+   int format, int flags)
+

Source Code

+

Lock an entire bitmap for reading or writing. If the bitmap is a display bitmap it will be updated from system memory after the bitmap is unlocked (unless locked read only). Returns NULL if the bitmap cannot be locked, e.g. the bitmap was locked previously and not unlocked. This function also returns NULL if the format is a compressed format.

+

Flags are:

+
    +
  • ALLEGRO_LOCK_READONLY - The locked region will not be written to. This can be faster if the bitmap is a video texture, as it can be discarded after the lock instead of uploaded back to the card.

  • +
  • ALLEGRO_LOCK_WRITEONLY - The locked region will not be read from. This can be faster if the bitmap is a video texture, as no data need to be read from the video card. You are required to fill in all pixels before unlocking the bitmap again, so be careful when using this flag.

  • +
  • ALLEGRO_LOCK_READWRITE - The locked region can be written to and read from. Use this flag if a partial number of pixels need to be written to, even if reading is not needed.

  • +
+

format indicates the pixel format that the returned buffer will be in. To lock in the same format as the bitmap stores its data internally, call with al_get_bitmap_format(bitmap) as the format or use ALLEGRO_PIXEL_FORMAT_ANY. Locking in the native format will usually be faster. If the bitmap format is compressed, using ALLEGRO_PIXEL_FORMAT_ANY will choose an implementation defined non-compressed format.

+

On some platforms, Allegro automatically backs up the contents of video bitmaps because they may be occasionally lost (see discussion in al_create_bitmap’s documentation). If you’re completely recreating the bitmap contents often (e.g. every frame) then you will get much better performance by creating the target bitmap with ALLEGRO_NO_PRESERVE_TEXTURE flag.

+
+

Note: While a bitmap is locked, you can not use any drawing operations on it (with the sole exception of al_put_pixel and al_put_blended_pixel).

+
+

See also: ALLEGRO_LOCKED_REGION, ALLEGRO_PIXEL_FORMAT, al_unlock_bitmap, al_lock_bitmap_region, al_lock_bitmap_blocked, al_lock_bitmap_region_blocked

+

Examples:

+ +

al_lock_bitmap_region

+
ALLEGRO_LOCKED_REGION *al_lock_bitmap_region(ALLEGRO_BITMAP *bitmap,
+   int x, int y, int width, int height, int format, int flags)
+

Source Code

+

Like al_lock_bitmap, but only locks a specific area of the bitmap. If the bitmap is a video bitmap, only that area of the texture will be updated when it is unlocked. Locking only the region you indend to modify will be faster than locking the whole bitmap.

+
+

Note: Using the ALLEGRO_LOCK_WRITEONLY with a blocked pixel format (i.e. formats for which al_get_pixel_block_width or al_get_pixel_block_height do not return 1) requires you to have the region be aligned to the block width for optimal performance. If it is not, then the function will have to lock the region with the ALLEGRO_LOCK_READWRITE instead in order to pad this region with valid data.

+
+

See also: ALLEGRO_LOCKED_REGION, ALLEGRO_PIXEL_FORMAT, al_unlock_bitmap

+

Examples:

+ +

al_unlock_bitmap

+
void al_unlock_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Unlock a previously locked bitmap or bitmap region. If the bitmap is a video bitmap, the texture will be updated to match the system memory copy (unless it was locked read only).

+

See also: al_lock_bitmap, al_lock_bitmap_region, al_lock_bitmap_blocked, al_lock_bitmap_region_blocked

+

Examples:

+ +

al_lock_bitmap_blocked

+
ALLEGRO_LOCKED_REGION *al_lock_bitmap_blocked(ALLEGRO_BITMAP *bitmap,
+   int flags)
+

Source Code

+

Like al_lock_bitmap, but allows locking bitmaps with a blocked pixel format (i.e. a format for which al_get_pixel_block_width or al_get_pixel_block_height do not return 1) in that format. To that end, this function also does not allow format conversion. For bitmap formats with a block size of 1, this function is identical to calling al_lock_bitmap(bmp, al_get_bitmap_format(bmp), flags).

+
+

Note: Currently there are no drawing functions that work when the bitmap is locked with a compressed format. al_get_pixel will also not work.

+
+

Since: 5.1.9

+

See also: al_lock_bitmap, al_lock_bitmap_region_blocked

+

al_lock_bitmap_region_blocked

+
ALLEGRO_LOCKED_REGION *al_lock_bitmap_region_blocked(ALLEGRO_BITMAP *bitmap,
+   int x_block, int y_block, int width_block, int height_block, int flags)
+

Source Code

+

Like al_lock_bitmap_blocked, but allows locking a sub-region, for performance. Unlike al_lock_bitmap_region the region specified in terms of blocks and not pixels.

+

Since: 5.1.9

+

See also: al_lock_bitmap_region, al_lock_bitmap_blocked

+

Examples:

+ +

Bitmap creation

+

ALLEGRO_BITMAP

+
typedef struct ALLEGRO_BITMAP ALLEGRO_BITMAP;
+

Source Code

+

Abstract type representing a bitmap (2D image).

+

Examples:

+ +

al_create_bitmap

+
ALLEGRO_BITMAP *al_create_bitmap(int w, int h)
+

Source Code

+

Creates a new bitmap using the bitmap format and flags for the current thread. Blitting between bitmaps of differing formats, or blitting between memory bitmaps and display bitmaps may be slow.

+

Unless you set the ALLEGRO_MEMORY_BITMAP flag, the bitmap is created for the current display. Blitting to another display may be slow.

+

If a display bitmap is created, there may be limitations on the allowed dimensions. For example a DirectX or OpenGL backend usually has a maximum allowed texture size - so if bitmap creation fails for very large dimensions, you may want to re-try with a smaller bitmap. Some platforms also dictate a minimum texture size, which is relevant if you plan to use this bitmap with the primitives addon. If you try to create a bitmap smaller than this, this call will not fail but the returned bitmap will be a section of a larger bitmap with the minimum size. The minimum size that will work on all platforms is 32 by 32. There is an experimental switch to turns this padding off by editing the system configuration (see min_bitmap_size key in al_get_system_config).

+

Some platforms do not directly support display bitmaps whose dimensions are not powers of two. Allegro handles this by creating a larger bitmap that has dimensions that are powers of two and then returning a section of that bitmap with the dimensions you requested. This can be relevant if you plan to use this bitmap with the primitives addon but shouldn’t be an issue otherwise.

+

If you create a bitmap without ALLEGRO_MEMORY_BITMAP set but there is no current display, a temporary memory bitmap will be created instead. You can later convert all such bitmap to video bitmap and assign to a display by calling al_convert_memory_bitmaps.

+

On some platforms the contents of video bitmaps may be lost when your application loses focus. Allegro has an internal mechanism to restore the contents of these video bitmaps, but it is not foolproof (sometimes bitmap contents can get lost permanently) and has performance implications. If you are using a bitmap as an intermediate buffer this mechanism may be wasteful. In this case, if you do not want Allegro to manage the bitmap contents for you, you can disable this mechanism by creating the bitmap with the ALLEGRO_NO_PRESERVE_TEXTURE flag. The bitmap contents are lost when you get the ALLEGRO_EVENT_DISPLAY_LOST and ALLEGRO_EVENT_DISPLAY_HALT_DRAWING and a should be restored when you get the ALLEGRO_EVENT_DISPLAY_FOUND and when you call al_acknowledge_drawing_resume (after ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING event). You can use those events to implement your own bitmap content restoration mechanism if Allegro’s does not work well enough for you (for example, you can reload them all from disk).

+

Note: The contents of a newly created bitmap are undefined - you need to clear the bitmap or make sure all pixels get overwritten before drawing it.

+

When you are done with using the bitmap you must call al_destroy_bitmap on it to free any resources allocated for it.

+

See also: al_set_new_bitmap_format, al_set_new_bitmap_flags, al_clone_bitmap, al_create_sub_bitmap, al_convert_memory_bitmaps, al_destroy_bitmap

+

Examples:

+ +

al_create_sub_bitmap

+
ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent,
+   int x, int y, int w, int h)
+

Source Code

+

Creates a sub-bitmap of the parent, at the specified coordinates and of the specified size. A sub-bitmap is a bitmap that shares drawing memory with a pre-existing (parent) bitmap, but possibly with a different size and clipping settings.

+

The sub-bitmap may originate off or extend past the parent bitmap.

+

See the discussion in al_get_backbuffer about using sub-bitmaps of the backbuffer.

+

The parent bitmap’s clipping rectangles are ignored.

+

If a sub-bitmap was not or cannot be created then NULL is returned.

+

When you are done with using the sub-bitmap you must call al_destroy_bitmap on it to free any resources allocated for it.

+

Note that destroying parents of sub-bitmaps will not destroy the sub-bitmaps; instead the sub-bitmaps become invalid and should no longer be used for drawing - they still must be destroyed with al_destroy_bitmap however. It does not matter whether you destroy a sub-bitmap before or after its parent otherwise.

+

See also: al_create_bitmap

+

Examples:

+ +

al_clone_bitmap

+
ALLEGRO_BITMAP *al_clone_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Create a new bitmap with al_create_bitmap, and copy the pixel data from the old bitmap across. The newly created bitmap will be created with the current new bitmap flags, and not the ones that were used to create the original bitmap. If the new bitmap is a memory bitmap, its projection bitmap is reset to be orthographic.

+

See also: al_create_bitmap, al_set_new_bitmap_format, al_set_new_bitmap_flags, al_convert_bitmap

+

Examples:

+ +

al_convert_bitmap

+
void al_convert_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Converts the bitmap to the current bitmap flags and format. The bitmap will be as if it was created anew with al_create_bitmap but retain its contents. All of this bitmap’s sub-bitmaps are also converted. If the new bitmap type is memory, then the bitmap’s projection bitmap is reset to be orthographic.

+

If this bitmap is a sub-bitmap, then it, its parent and all the sibling sub-bitmaps are also converted.

+

Since: 5.1.0

+

See also: al_create_bitmap, al_set_new_bitmap_format, al_set_new_bitmap_flags, al_clone_bitmap

+

Examples:

+ +

al_convert_memory_bitmaps

+
void al_convert_memory_bitmaps(void)
+

Source Code

+

If you create a bitmap when there is no current display (for example because you have not called al_create_display in the current thread) and are using the ALLEGRO_CONVERT_BITMAP bitmap flag (which is set by default) then the bitmap will be created successfully, but as a memory bitmap. This function converts all such bitmaps to proper video bitmaps belonging to the current display.

+

Note that video bitmaps get automatically converted back to memory bitmaps when the last display is destroyed.

+

This operation will preserve all bitmap flags except ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP.

+

Since: 5.2.0

+

See also: al_convert_bitmap, al_create_bitmap

+

al_destroy_bitmap

+
void al_destroy_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Destroys the given bitmap, freeing all resources used by it. This function does nothing if the bitmap argument is NULL.

+

As a convenience, if the calling thread is currently targeting the bitmap then the bitmap will be untargeted first. The new target bitmap is unspecified. (since: 5.0.10, 5.1.6)

+

Otherwise, it is an error to destroy a bitmap while it (or a sub-bitmap) is the target bitmap of any thread.

+

See also: al_create_bitmap

+

Examples:

+ +

al_get_new_bitmap_flags

+
int al_get_new_bitmap_flags(void)
+

Source Code

+

Returns the flags used for newly created bitmaps.

+

See also: al_set_new_bitmap_flags

+

Examples:

+ +

al_get_new_bitmap_format

+
int al_get_new_bitmap_format(void)
+

Source Code

+

Returns the format used for newly created bitmaps.

+

See also: ALLEGRO_PIXEL_FORMAT, al_set_new_bitmap_format

+

al_set_new_bitmap_flags

+
void al_set_new_bitmap_flags(int flags)
+

Source Code

+

Sets the flags to use for newly created bitmaps. Valid flags are:

+
+
ALLEGRO_MEMORY_BITMAP
+

Create a bitmap residing in system memory. Operations on, and with, memory bitmaps will not be hardware accelerated. However, direct pixel access can be relatively quick compared to video bitmaps, which depend on the display driver in use.

+

Note: Allegro’s software rendering routines are currently somewhat unoptimised.

+

Note: Combining ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP flags is invalid.

+
+
ALLEGRO_VIDEO_BITMAP
+

Creates a bitmap that resides in the video card memory. These types of bitmaps receive the greatest benefit from hardware acceleration.

+

Note: Creating a video bitmap will fail if there is no current display or the current display driver cannot create the bitmap. The latter will happen if for example the format or dimensions are not supported.

+

Note: Bitmaps created with this flag will be converted to memory bitmaps when the last display is destroyed. In most cases it is therefore easier to use the ALLEGRO_CONVERT_BITMAP flag instead.

+

Note: Combining ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP flags is invalid.

+
+
ALLEGRO_CONVERT_BITMAP
+

This is the default. It will try to create a video bitmap and if that fails create a memory bitmap. Bitmaps created with this flag when there is no active display will be converted to video bitmaps next time a display is created. They also will remain video bitmaps if the last display is destroyed and then another is created again. Since 5.1.0.

+

Note: You can combine this flag with ALLEGRO_MEMORY_BITMAP or ALLEGRO_VIDEO_BITMAP to force the initial type (and fail in the latter case if no video bitmap can be created) - but usually neither of those combinations is very useful.

+

You can use the display option ALLEGRO_AUTO_CONVERT_BITMAPS to control which displays will try to auto-convert bitmaps.

+
+
ALLEGRO_FORCE_LOCKING
+
Does nothing since 5.1.8. Kept for backwards compatibility only. +
+
ALLEGRO_NO_PRESERVE_TEXTURE
+
Normally, every effort is taken to preserve the contents of bitmaps, since some platforms may forget them. This can take extra processing time. If you know it doesn’t matter if a bitmap keeps its pixel data, for example when it’s a temporary buffer, use this flag to tell Allegro not to attempt to preserve its contents. +
+
ALLEGRO_ALPHA_TEST
+
This is a driver hint only. It tells the graphics driver to do alpha testing instead of alpha blending on bitmaps created with this flag. Alpha testing is usually faster and preferred if your bitmaps have only one level of alpha (0). This flag is currently not widely implemented (i.e., only for memory bitmaps). +
+
ALLEGRO_MIN_LINEAR
+
When drawing a scaled down version of the bitmap, use linear filtering. This usually looks better. You can also combine it with the MIPMAP flag for even better quality. +
+
ALLEGRO_MAG_LINEAR
+

When drawing a magnified version of a bitmap, use linear filtering. This will cause the picture to get blurry instead of creating a big rectangle for each pixel. It depends on how you want things to look like whether you want to use this or not.

+
+
ALLEGRO_MIPMAP
+

This can only be used for bitmaps whose width and height is a power of two. In that case, it will generate mipmaps and use them when drawing scaled down versions. For example if the bitmap is 64x64, then extra bitmaps of sizes 32x32, 16x16, 8x8, 4x4, 2x2 and 1x1 will be created always containing a scaled down version of the original.

+
+
+

See also: al_get_new_bitmap_flags, al_get_bitmap_flags

+

Examples:

+ +

al_add_new_bitmap_flag

+
void al_add_new_bitmap_flag(int flag)
+

Source Code

+

A convenience function which does the same as

+
al_set_new_bitmap_flags(al_get_new_bitmap_flags() | flag);
+

See also: al_set_new_bitmap_flags, al_get_new_bitmap_flags, al_get_bitmap_flags

+

Examples:

+ +

al_set_new_bitmap_format

+
void al_set_new_bitmap_format(int format)
+

Source Code

+

Sets the pixel format (ALLEGRO_PIXEL_FORMAT) for newly created bitmaps. The default format is 0 and means the display driver will choose the best format.

+

See also: ALLEGRO_PIXEL_FORMAT, al_get_new_bitmap_format, al_get_bitmap_format

+

Examples:

+ +

al_set_new_bitmap_depth

+
void al_set_new_bitmap_depth(int depth)
+SETTER(new_bitmap_depth, depth)
+

Source Code

+

Sets the depthbuffer depth used by newly created bitmaps (on the current thread) if they are used with al_set_target_bitmap. 0 means no depth-buffer will be created when drawing into the bitmap, which is the default.

+

Since: 5.2.1

+
+

Unstable API: This is an experimental feature and currently only works for the OpenGL backend.

+
+

Examples:

+ +

al_get_new_bitmap_depth

+
int al_get_new_bitmap_depth(void)
+GETTER(new_bitmap_depth, 0)
+

Source Code

+

Returns the value currently set with al_set_new_bitmap_depth on the current thread or 0 if none was set.

+

Since: 5.2.1

+
+

Unstable API: This is an experimental feature and currently only works for the OpenGL backend.

+
+

al_set_new_bitmap_samples

+
void al_set_new_bitmap_samples(int samples)
+SETTER(new_bitmap_samples, samples)
+

Source Code

+

Sets the multi-sampling samples used by newly created bitmaps (on the current thread) if they are used with al_set_target_bitmap. 0 means multi-sampling will not be used when drawing into the bitmap, which is the default. 1 means multi-sampling will be used but only using a single sample per pixel (so usually there will be no visual difference to not using multi-sampling at all).

+
+

Note: Some platforms have restrictions on when the multi-sampling buffer for a bitmap is realized, i.e. down-scaled back to the actual bitmap dimensions. This may only happen after a call to al_set_target_bitmap. So for example:

+
+
al_set_target_bitmap(multisample);
+al_clear_to_color(blue);
+al_draw_line(0, 0, 100, 100, red, 1);
+al_lock_bitmap(multisample, ...)
+// ERROR: the contents of the bitmap will be undefined
+
+al_set_target_bitmap(backbuffer);
+al_lock_bitmap(multisample, ...)
+// CORRECT: at this point, the bitmap contents are updated and
+// there will be an anti-aliased line in it.
+

Since: 5.2.1

+
+

Unstable API: This is an experimental feature and currently only works for the OpenGL backend.

+
+

Examples:

+ +

al_get_new_bitmap_samples

+
int al_get_new_bitmap_samples(void)
+GETTER(new_bitmap_samples, 0)
+

Source Code

+

Returns the value currently set with al_set_new_bitmap_samples on the current thread or 0 if none was set.

+

Since: 5.2.1

+
+

Unstable API: This is an experimental feature and currently only works for the OpenGL backend.

+
+

Bitmap properties

+

al_get_bitmap_flags

+
int al_get_bitmap_flags(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Return the flags used to create the bitmap.

+

See also: al_set_new_bitmap_flags

+

Examples:

+ +

al_get_bitmap_format

+
int al_get_bitmap_format(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns the pixel format of a bitmap.

+

See also: ALLEGRO_PIXEL_FORMAT, al_set_new_bitmap_flags

+

Examples:

+ +

al_get_bitmap_height

+
int al_get_bitmap_height(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns the height of a bitmap in pixels.

+

Examples:

+ +

al_get_bitmap_width

+
int al_get_bitmap_width(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns the width of a bitmap in pixels.

+

Examples:

+ +

al_get_bitmap_depth

+
int al_get_bitmap_depth(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Return the depthbuffer depth used by this bitmap if it is used with al_set_target_bitmap.

+

Since: 5.2.1

+
+

Unstable API: This is an experimental feature and currently only works for the OpenGL backend.

+
+

al_get_bitmap_samples

+
int al_get_bitmap_samples(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Return the multi-sampling samples used by this bitmap if it is used with al_set_target_bitmap.

+

Since: 5.2.1

+
+

Unstable API: This is an experimental feature and currently only works for the OpenGL backend.

+
+

al_get_pixel

+
ALLEGRO_COLOR al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int y)
+

Source Code

+

Get a pixel’s color value from the specified bitmap. This operation is slow on non-memory bitmaps. Consider locking the bitmap if you are going to use this function multiple times on the same bitmap.

+

See also: ALLEGRO_COLOR, al_put_pixel, al_lock_bitmap

+

Examples:

+ +

al_is_bitmap_locked

+
bool al_is_bitmap_locked(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns whether or not a bitmap is already locked.

+

See also: al_lock_bitmap, al_lock_bitmap_region, al_unlock_bitmap

+

al_is_compatible_bitmap

+
bool al_is_compatible_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

D3D and OpenGL allow sharing a texture in a way so it can be used for multiple windows. Each ALLEGRO_BITMAP created with al_create_bitmap however is usually tied to a single ALLEGRO_DISPLAY. This function can be used to know if the bitmap is compatible with the given display, even if it is a different display to the one it was created with. It returns true if the bitmap is compatible (things like a cached texture version can be used) and false otherwise (blitting in the current display will be slow).

+

The only time this function is useful is if you are using multiple windows and need accelerated blitting of the same bitmaps to both.

+

Returns true if the bitmap is compatible with the current display, false otherwise. If there is no current display, false is returned.

+

al_is_sub_bitmap

+
bool al_is_sub_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns true if the specified bitmap is a sub-bitmap, false otherwise.

+

See also: al_create_sub_bitmap, al_get_parent_bitmap

+

al_get_parent_bitmap

+
ALLEGRO_BITMAP *al_get_parent_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns the bitmap this bitmap is a sub-bitmap of. Returns NULL if this bitmap is not a sub-bitmap. This function always returns the real bitmap, and never a sub-bitmap. This might NOT match what was passed to al_create_sub_bitmap. Consider this code, for instance:

+
ALLEGRO_BITMAP* a = al_create_bitmap(512, 512);
+ALLEGRO_BITMAP* b = al_create_sub_bitmap(a, 128, 128, 256, 256);
+ALLEGRO_BITMAP* c = al_create_sub_bitmap(b, 64, 64, 128, 128);
+ASSERT(al_get_parent_bitmap(b) == a && al_get_parent_bitmap(c) == a);
+

The assertion will pass because only a is a real bitmap, and both b and c are its sub-bitmaps.

+

Since: 5.0.6, 5.1.2

+

See also: al_create_sub_bitmap, al_is_sub_bitmap

+

al_get_bitmap_x

+
int al_get_bitmap_x(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

For a sub-bitmap, return it’s x position within the parent.

+

See also: al_create_sub_bitmap, al_get_parent_bitmap, al_get_bitmap_y

+

Since: 5.1.12

+

Examples:

+ +

al_get_bitmap_y

+
int al_get_bitmap_y(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

For a sub-bitmap, return it’s y position within the parent.

+

See also: al_create_sub_bitmap, al_get_parent_bitmap, al_get_bitmap_x

+

Since: 5.1.12

+

Examples:

+ +

al_reparent_bitmap

+
void al_reparent_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP *parent,
+   int x, int y, int w, int h)
+

Source Code

+

For a sub-bitmap, changes the parent, position and size. This is the same as destroying the bitmap and re-creating it with al_create_sub_bitmap - except the bitmap pointer stays the same. This has many uses, for example an animation player could return a single bitmap which can just be re-parented to different animation frames without having to re-draw the contents. Or a sprite atlas could re-arrange its sprites without having to invalidate all existing bitmaps.

+

See also: al_create_sub_bitmap, al_get_parent_bitmap

+

Since: 5.1.12

+

Examples:

+ +

al_get_bitmap_blender

+
void al_get_bitmap_blender(int *op, int *src, int *dst)
+

Source Code

+

Returns the current blender being used by the target bitmap. You can pass NULL for values you are not interested in.

+

Since: 5.2.5

+
+

Unstable API: New API.

+
+

See also: al_set_bitmap_blender, al_get_separate_bitmap_blender

+

al_get_separate_bitmap_blender

+
void al_get_separate_bitmap_blender(int *op, int *src, int *dst, int *alpha_op, int *alpha_src, int *alpha_dst)
+

Source Code

+

Returns the current blender being used by the target bitmap. You can pass NULL for values you are not interested in.

+

Since: 5.2.5

+
+

Unstable API: New API.

+
+

See also: al_set_separate_bitmap_blender, al_get_bitmap_blender

+

al_get_bitmap_blend_color

+
ALLEGRO_COLOR al_get_bitmap_blend_color(void)
+

Source Code

+

Returns the color currently used for constant color blending on the target bitmap.

+

Since: 5.2.5

+
+

Unstable API: New API.

+
+

See also: al_set_bitmap_blend_color

+

al_set_bitmap_blender

+
void al_set_bitmap_blender(int op, int src, int dest)
+

Source Code

+

Sets the function to use for blending when rendering to the target bitmap. If no blender is set for a given bitmap at draw time, the values set for al_set_blender/al_set_separate_blender are used instead.

+

To use separate functions for chroma (RGB) and alpha channels, use al_set_separate_bitmap_blender.

+

See al_set_blender for more information about how blending works.

+

See also: al_set_separate_bitmap_blender, al_reset_bitmap_blender

+

Since: 5.2.5

+
+

Unstable API: New API.

+
+

Examples:

+ +

al_set_separate_bitmap_blender

+
void al_set_separate_bitmap_blender(int op, int src, int dst, int alpha_op, int alpha_src, int alpha_dst)
+

Source Code

+

Like al_set_bitmap_blender, but allows specifying a separate blending operation for the alpha channel. This is useful if your target bitmap also has an alpha channel and the two alpha channels need to be combined in a different way than the color components.

+

Since: 5.2.5

+
+

Unstable API: New API.

+
+

See also: al_set_bitmap_blender, al_reset_bitmap_blender

+

al_set_bitmap_blend_color

+
void al_set_bitmap_blend_color(ALLEGRO_COLOR col)
+

Source Code

+

Sets the color to use for ALLEGRO_CONST_COLOR or ALLEGRO_INVERSE_CONST_COLOR blend operations.

+

Since: 5.2.5

+
+

Unstable API: New API.

+
+

See also: al_set_bitmap_blender, al_reset_bitmap_blender

+

Examples:

+ +

al_reset_bitmap_blender

+
void al_reset_bitmap_blender(void)
+

Source Code

+

Resets the blender for this bitmap to the default. After resetting the bitmap blender, the values set for al_set_bitmap_blender/al_set_separate_bitmap_blender will be used instead.

+

Since: 5.2.5

+
+

Unstable API: New API.

+
+

See also: al_set_bitmap_blender

+

Drawing operations

+

All drawing operations draw to the current “target bitmap” of the current thread. Initially, the target bitmap will be the backbuffer of the last display created in a thread.

+

al_clear_to_color

+
void al_clear_to_color(ALLEGRO_COLOR color)
+

Source Code

+

Clear the complete target bitmap, but confined by the clipping rectangle.

+

See also: ALLEGRO_COLOR, al_set_clipping_rectangle, al_clear_depth_buffer

+

Examples:

+ +

al_clear_depth_buffer

+
void al_clear_depth_buffer(float z)
+

Source Code

+

Clear the depth buffer (confined by the clipping rectangle) to the given value. A depth buffer is only available if it was requested with al_set_new_display_option and the requirement could be met by the al_create_display call creating the current display. Operations involving the depth buffer are also affected by al_set_render_state.

+

For example, if ALLEGRO_DEPTH_FUNCTION is set to ALLEGRO_RENDER_LESS then depth buffer value of 1 represents infinite distance, and thus is a good value to use when clearing the depth buffer.

+

Since: 5.1.2

+

See also: al_clear_to_color, al_set_clipping_rectangle, al_set_render_state, al_set_new_display_option

+

Examples:

+ +

al_draw_bitmap

+
void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags)
+

Source Code

+

Draws an unscaled, unrotated bitmap at the given position to the current target bitmap (see al_set_target_bitmap).

+

flags can be a combination of:

+
    +
  • ALLEGRO_FLIP_HORIZONTAL - flip the bitmap about the y-axis
  • +
  • ALLEGRO_FLIP_VERTICAL - flip the bitmap about the x-axis
  • +
+
+

Note: The current target bitmap must be a different bitmap. Drawing a bitmap to itself (or to a sub-bitmap of itself) or drawing a sub-bitmap to its parent (or another sub-bitmap of its parent) are not currently supported. To copy part of a bitmap into the same bitmap simply use a temporary bitmap instead.

+
+
+

Note: The backbuffer (or a sub-bitmap thereof) can not be transformed, blended or tinted. If you need to draw the backbuffer draw it to a temporary bitmap first with no active transformation (except translation). Blending and tinting settings/parameters will be ignored. This does not apply when drawing into a memory bitmap.

+
+

See also: al_draw_bitmap_region, al_draw_scaled_bitmap, al_draw_rotated_bitmap, al_draw_scaled_rotated_bitmap

+

Examples:

+ +

al_draw_tinted_bitmap

+
void al_draw_tinted_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint,
+   float dx, float dy, int flags)
+

Source Code

+

Like al_draw_bitmap but multiplies all colors in the bitmap with the given color. For example:

+
al_draw_tinted_bitmap(bitmap, al_map_rgba_f(0.5, 0.5, 0.5, 0.5), x, y, 0);
+

The above will draw the bitmap 50% transparently (r/g/b values need to be pre-multiplied with the alpha component with the default blend mode).

+
al_draw_tinted_bitmap(bitmap, al_map_rgba_f(1, 0, 0, 1), x, y, 0);
+

The above will only draw the red component of the bitmap.

+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_bitmap

+

Examples:

+ +

al_draw_bitmap_region

+
void al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
+   float sx, float sy, float sw, float sh, float dx, float dy, int flags)
+

Source Code

+

Draws a region of the given bitmap to the target bitmap.

+
    +
  • sx - source x
  • +
  • sy - source y
  • +
  • sw - source width (width of region to blit)
  • +
  • sh - source height (height of region to blit)
  • +
  • dx - destination x
  • +
  • dy - destination y
  • +
  • flags - same as for al_draw_bitmap
  • +
+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_bitmap, al_draw_scaled_bitmap, al_draw_rotated_bitmap, al_draw_scaled_rotated_bitmap

+

Examples:

+ +

al_draw_tinted_bitmap_region

+
void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap,
+   ALLEGRO_COLOR tint,
+   float sx, float sy, float sw, float sh, float dx, float dy,
+   int flags)
+

Source Code

+

Like al_draw_bitmap_region but multiplies all colors in the bitmap with the given color.

+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_tinted_bitmap

+

Examples:

+ +

al_draw_pixel

+
void al_draw_pixel(float x, float y, ALLEGRO_COLOR color)
+

Source Code

+

Draws a single pixel at x, y. This function, unlike al_put_pixel, does blending and, unlike al_put_blended_pixel, respects the transformations (that is, the pixel’s position is transformed, but its size is unaffected - it remains a pixel). This function can be slow if called often; if you need to draw a lot of pixels consider using al_draw_prim with ALLEGRO_PRIM_POINT_LIST from the primitives addon.

+
    +
  • x - destination x
  • +
  • y - destination y
  • +
  • color - color of the pixel
  • +
+
+

Note: This function may not draw exactly where you expect it to. See the pixel-precise output section on the primitives addon documentation for details on how to control exactly where the pixel is drawn.

+
+

See also: ALLEGRO_COLOR, al_put_pixel

+

Examples:

+ +

al_draw_rotated_bitmap

+
void al_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
+   float cx, float cy, float dx, float dy, float angle, int flags)
+

Source Code

+

Draws a rotated version of the given bitmap to the target bitmap. The bitmap is rotated by ‘angle’ radians clockwise.

+

The point at cx/cy relative to the upper left corner of the bitmap will be drawn at dx/dy and the bitmap is rotated around this point. If cx,cy is 0,0 the bitmap will rotate around its upper left corner.

+
    +
  • cx - center x (relative to the bitmap)
  • +
  • cy - center y (relative to the bitmap)
  • +
  • dx - destination x
  • +
  • dy - destination y
  • +
  • angle - angle by which to rotate (radians)
  • +
  • flags - same as for al_draw_bitmap
  • +
+

Example

+
float w = al_get_bitmap_width(bitmap);
+float h = al_get_bitmap_height(bitmap);
+al_draw_rotated_bitmap(bitmap, w / 2, h / 2, x, y, ALLEGRO_PI / 2, 0);
+

The above code draws the bitmap centered on x/y and rotates it 90° clockwise.

+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_bitmap, al_draw_bitmap_region, al_draw_scaled_bitmap, al_draw_scaled_rotated_bitmap

+

Examples:

+ +

al_draw_tinted_rotated_bitmap

+
void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
+   ALLEGRO_COLOR tint,
+   float cx, float cy, float dx, float dy, float angle, int flags)
+

Source Code

+

Like al_draw_rotated_bitmap but multiplies all colors in the bitmap with the given color.

+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_tinted_bitmap

+

Examples:

+ +

al_draw_scaled_rotated_bitmap

+
void al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
+   float cx, float cy, float dx, float dy, float xscale, float yscale,
+   float angle, int flags)
+

Source Code

+

Like al_draw_rotated_bitmap, but can also scale the bitmap.

+

The point at cx/cy in the bitmap will be drawn at dx/dy and the bitmap is rotated and scaled around this point.

+
    +
  • cx - center x
  • +
  • cy - center y
  • +
  • dx - destination x
  • +
  • dy - destination y
  • +
  • xscale - how much to scale on the x-axis (e.g. 2 for twice the size)
  • +
  • yscale - how much to scale on the y-axis
  • +
  • angle - angle by which to rotate (radians)
  • +
  • flags - same as for al_draw_bitmap
  • +
+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_bitmap, al_draw_bitmap_region, al_draw_scaled_bitmap, al_draw_rotated_bitmap

+

Examples:

+ +

al_draw_tinted_scaled_rotated_bitmap

+
void al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
+   ALLEGRO_COLOR tint,
+   float cx, float cy, float dx, float dy, float xscale, float yscale,
+   float angle, int flags)
+

Source Code

+

Like al_draw_scaled_rotated_bitmap but multiplies all colors in the bitmap with the given color.

+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_tinted_bitmap

+

Examples:

+ +

al_draw_tinted_scaled_rotated_bitmap_region

+
void al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP *bitmap,
+   float sx, float sy, float sw, float sh,
+   ALLEGRO_COLOR tint,
+   float cx, float cy, float dx, float dy, float xscale, float yscale,
+   float angle, int flags)
+

Source Code

+

Like al_draw_tinted_scaled_rotated_bitmap but you specify an area within the bitmap to be drawn.

+

You can get the same effect with a sub bitmap:

+
al_draw_tinted_scaled_rotated_bitmap(bitmap, sx, sy, sw, sh, tint,
+    cx, cy, dx, dy, xscale, yscale, angle, flags);
+
+/* This draws the same: */
+sub_bitmap = al_create_sub_bitmap(bitmap, sx, sy, sw, sh);
+al_draw_tinted_scaled_rotated_bitmap(sub_bitmap, tint, cx, cy,
+    dx, dy, xscale, yscale, angle, flags);
+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

Since: 5.0.6, 5.1.0

+

See also: al_draw_tinted_bitmap

+

al_draw_scaled_bitmap

+
void al_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
+   float sx, float sy, float sw, float sh,
+   float dx, float dy, float dw, float dh, int flags)
+

Source Code

+

Draws a scaled version of the given bitmap to the target bitmap.

+
    +
  • sx - source x
  • +
  • sy - source y
  • +
  • sw - source width
  • +
  • sh - source height
  • +
  • dx - destination x
  • +
  • dy - destination y
  • +
  • dw - destination width
  • +
  • dh - destination height
  • +
  • flags - same as for al_draw_bitmap
  • +
+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_bitmap, al_draw_bitmap_region, al_draw_rotated_bitmap, al_draw_scaled_rotated_bitmap,

+

Examples:

+ +

al_draw_tinted_scaled_bitmap

+
void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
+   ALLEGRO_COLOR tint,
+   float sx, float sy, float sw, float sh,
+   float dx, float dy, float dw, float dh, int flags)
+

Source Code

+

Like al_draw_scaled_bitmap but multiplies all colors in the bitmap with the given color.

+

See al_draw_bitmap for a note on restrictions on which bitmaps can be drawn where.

+

See also: al_draw_tinted_bitmap

+

Examples:

+ +

al_get_target_bitmap

+
ALLEGRO_BITMAP *al_get_target_bitmap(void)
+

Source Code

+

Return the target bitmap of the calling thread.

+

See also: al_set_target_bitmap

+

Examples:

+ +

al_put_pixel

+
void al_put_pixel(int x, int y, ALLEGRO_COLOR color)
+

Source Code

+

Draw a single pixel on the target bitmap. This operation is slow on non-memory bitmaps. Consider locking the bitmap if you are going to use this function multiple times on the same bitmap. This function is not affected by the transformations or the color blenders.

+

See also: ALLEGRO_COLOR, al_get_pixel, al_put_blended_pixel, al_lock_bitmap

+

Examples:

+ +

al_put_blended_pixel

+
void al_put_blended_pixel(int x, int y, ALLEGRO_COLOR color)
+

Source Code

+

Like al_put_pixel, but the pixel color is blended using the current blenders before being drawn.

+

See also: ALLEGRO_COLOR, al_put_pixel

+

Target bitmap

+

al_set_target_bitmap

+
void al_set_target_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

This function selects the bitmap to which all subsequent drawing operations in the calling thread will draw to. To return to drawing to a display, set the backbuffer of the display as the target bitmap, using al_get_backbuffer. As a convenience, you may also use al_set_target_backbuffer.

+

Each allegro bitmap maintains two transformation matrices associated with it for drawing onto the bitmap. There is a view matrix and a projection matrix. When you call al_set_target_bitmap, these will be made current for the bitmap, affecting global OpenGL and DirectX states depending on the driver in use.

+

Each video bitmap is tied to a display. When a video bitmap is set to as the target bitmap, the display that the bitmap belongs to is automatically made “current” for the calling thread (if it is not current already). Then drawing other bitmaps which are tied to the same display can be hardware accelerated.

+

A single display cannot be current for multiple threads simultaneously. If you need to release a display, so it is not current for the calling thread, call al_set_target_bitmap(NULL);

+

Setting a memory bitmap as the target bitmap will not change which display is current for the calling thread.

+

On some platforms, Allegro automatically backs up the contents of video bitmaps because they may be occasionally lost (see discussion in al_create_bitmap’s documentation). If you’re completely recreating the bitmap contents often (e.g. every frame) then you will get much better performance by creating the target bitmap with ALLEGRO_NO_PRESERVE_TEXTURE flag.

+

OpenGL note:

+

Framebuffer objects (FBOs) allow OpenGL to directly draw to a bitmap, which is very fast. When using an OpenGL display, if all of the following conditions are met an FBO will be created for use with the bitmap:

+
    +
  • The GL_EXT_framebuffer_object OpenGL extension is available.
  • +
  • The bitmap is not a memory bitmap.
  • +
  • The bitmap is not currently locked.
  • +
+

In Allegro 5.0.0, you had to be careful as an FBO would be kept around until the bitmap is destroyed or you explicitly called al_remove_opengl_fbo on the bitmap, wasting resources. In newer versions, FBOs will be freed automatically when the bitmap is no longer the target bitmap, unless you have called al_get_opengl_fbo to retrieve the FBO id.

+

In the following example, no FBO will be created:

+
lock = al_lock_bitmap(bitmap);
+al_set_target_bitmap(bitmap);
+al_put_pixel(x, y, color);
+al_unlock_bitmap(bitmap);
+

The above allows using al_put_pixel on a locked bitmap without creating an FBO.

+

In this example an FBO is created however:

+
al_set_target_bitmap(bitmap);
+al_draw_line(x1, y1, x2, y2, color, 0);
+

An OpenGL command will be used to directly draw the line into the bitmap’s associated texture.

+

See also: al_get_target_bitmap, al_set_target_backbuffer

+

Examples:

+ +

al_set_target_backbuffer

+
void al_set_target_backbuffer(ALLEGRO_DISPLAY *display)
+

Source Code

+

Same as al_set_target_bitmap(al_get_backbuffer(display));

+

See also: al_set_target_bitmap, al_get_backbuffer

+

Examples:

+ +

al_get_current_display

+
ALLEGRO_DISPLAY *al_get_current_display(void)
+

Source Code

+

Return the display that is “current” for the calling thread, or NULL if there is none.

+

See also: al_set_target_bitmap

+

Examples:

+ +

Blending modes

+

al_get_blender

+
void al_get_blender(int *op, int *src, int *dst)
+

Source Code

+

Returns the active blender for the current thread. You can pass NULL for values you are not interested in.

+

See also: al_set_blender, al_get_separate_blender

+

al_get_separate_blender

+
void al_get_separate_blender(int *op, int *src, int *dst,
+   int *alpha_op, int *alpha_src, int *alpha_dst)
+

Source Code

+

Returns the active blender for the current thread. You can pass NULL for values you are not interested in.

+

See also: al_set_separate_blender, al_get_blender

+

al_get_blend_color

+
ALLEGRO_COLOR al_get_blend_color(void)
+

Source Code

+

Returns the color currently used for constant color blending (white by default).

+

See also: al_set_blend_color, al_set_blender

+

Since: 5.1.12

+

al_set_blender

+
void al_set_blender(int op, int src, int dst)
+

Source Code

+

Sets the function to use for blending for the current thread.

+

Blending means, the source and destination colors are combined in drawing operations.

+

Assume the source color (e.g. color of a rectangle to draw, or pixel of a bitmap to draw) is given as its red/green/blue/alpha components (if the bitmap has no alpha it always is assumed to be fully opaque, so 255 for 8-bit or 1.0 for floating point): s = s.r, s.g, s.b, s.a. And this color is drawn to a destination, which already has a color: d = d.r, d.g, d.b, d.a.

+

The conceptional formula used by Allegro to draw any pixel then depends on the op parameter:

+
    +
  • ALLEGRO_ADD

    +
       r = d.r * df.r + s.r * sf.r
    +   g = d.g * df.g + s.g * sf.g
    +   b = d.b * df.b + s.b * sf.b
    +   a = d.a * df.a + s.a * sf.a
  • +
  • ALLEGRO_DEST_MINUS_SRC

    +
       r = d.r * df.r - s.r * sf.r
    +   g = d.g * df.g - s.g * sf.g
    +   b = d.b * df.b - s.b * sf.b
    +   a = d.a * df.a - s.a * sf.a
  • +
  • ALLEGRO_SRC_MINUS_DEST

    +
       r = s.r * sf.r - d.r * df.r
    +   g = s.g * sf.g - d.g * df.g
    +   b = s.b * sf.b - d.b * df.b
    +   a = s.a * sf.a - d.a * df.a
  • +
+

Valid values for the factors sf and df passed to this function are as follows, where s is the source color, d the destination color and cc the color set with al_set_blend_color (white by default)

+
    +
  • ALLEGRO_ZERO

    +
       f = 0, 0, 0, 0
  • +
  • ALLEGRO_ONE

    +
       f = 1, 1, 1, 1
  • +
  • ALLEGRO_ALPHA

    +
       f = s.a, s.a, s.a, s.a
  • +
  • ALLEGRO_INVERSE_ALPHA

    +
       f = 1 - s.a, 1 - s.a, 1 - s.a, 1 - s.a
  • +
  • ALLEGRO_SRC_COLOR (since: 5.0.10, 5.1.0)

    +
       f = s.r, s.g, s.b, s.a
  • +
  • ALLEGRO_DEST_COLOR (since: 5.0.10, 5.1.8)

    +
       f = d.r, d.g, d.b, d.a
  • +
  • ALLEGRO_INVERSE_SRC_COLOR (since: 5.0.10, 5.1.0)

    +
       f = 1 - s.r, 1 - s.g, 1 - s.b, 1 - s.a
  • +
  • ALLEGRO_INVERSE_DEST_COLOR (since: 5.0.10, 5.1.8)

    +
       f = 1 - d.r, 1 - d.g, 1 - d.b, 1 - d.a
  • +
  • ALLEGRO_CONST_COLOR (since: 5.1.12, not supported on OpenGLES 1.0)

    +
       f = cc.r, cc.g, cc.b, cc.a
  • +
  • ALLEGRO_INVERSE_CONST_COLOR (since: 5.1.12, not supported on OpenGLES 1.0)

    +
       f = 1 - cc.r, 1 - cc.g, 1 - cc.b, 1 - cc.a
  • +
+

Blending examples:

+

So for example, to restore the default of using premultiplied alpha blending, you would use:

+
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
+

As formula:

+
r = d.r * (1 - s.a) + s.r * 1
+g = d.g * (1 - s.a) + s.g * 1
+b = d.b * (1 - s.a) + s.b * 1
+a = d.a * (1 - s.a) + s.a * 1
+

If you are using non-pre-multiplied alpha, you could use

+
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
+

Additive blending would be achieved with

+
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
+

Copying the source to the destination (including alpha) unmodified

+
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
+

Multiplying source and destination components

+
al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_ZERO)
+

Tinting the source (like al_draw_tinted_bitmap)

+
al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_ONE);
+al_set_blend_color(al_map_rgb(0, 96, 255)); /* nice Chrysler blue */
+

Averaging source and destination pixels

+
al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR);
+al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 0.5));
+

As formula:

+
r = d.r * 0 + s.r * d.r
+g = d.g * 0 + s.g * d.g
+b = d.b * 0 + s.b * d.b
+a = d.a * 0 + s.a * d.a
+

See also: al_set_separate_blender, al_set_blend_color, al_get_blender

+

Examples:

+ +

al_set_separate_blender

+
void al_set_separate_blender(int op, int src, int dst,
+   int alpha_op, int alpha_src, int alpha_dst)
+

Source Code

+

Like al_set_blender, but allows specifying a separate blending operation for the alpha channel. This is useful if your target bitmap also has an alpha channel and the two alpha channels need to be combined in a different way than the color components.

+

See also: al_set_blender, al_get_blender, al_get_separate_blender

+

Examples:

+ +

al_set_blend_color

+
void al_set_blend_color(ALLEGRO_COLOR color)
+

Source Code

+

Sets the color to use for blending when using the ALLEGRO_CONST_COLOR or ALLEGRO_INVERSE_CONST_COLOR blend functions. See al_set_blender for more information.

+

See also: al_set_blender, al_get_blend_color

+

Since: 5.1.12

+

Examples:

+ +

Clipping

+

al_get_clipping_rectangle

+
void al_get_clipping_rectangle(int *x, int *y, int *w, int *h)
+

Source Code

+

Gets the clipping rectangle of the target bitmap.

+

See also: al_set_clipping_rectangle

+

Examples:

+ +

al_set_clipping_rectangle

+
void al_set_clipping_rectangle(int x, int y, int width, int height)
+

Source Code

+

Set the region of the target bitmap or display that pixels get clipped to. The default is to clip pixels to the entire bitmap.

+

See also: al_get_clipping_rectangle, al_reset_clipping_rectangle

+

Examples:

+ +

al_reset_clipping_rectangle

+
void al_reset_clipping_rectangle(void)
+

Source Code

+

Equivalent to calling `al_set_clipping_rectangle(0, 0, w, h)’ where w and h are the width and height of the target bitmap respectively.

+

Does nothing if there is no target bitmap.

+

See also: al_set_clipping_rectangle

+

Since: 5.0.6, 5.1.0

+

Graphics utility functions

+

al_convert_mask_to_alpha

+
void al_convert_mask_to_alpha(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color)
+

Source Code

+

Convert the given mask color to an alpha channel in the bitmap. Can be used to convert older 4.2-style bitmaps with magic pink to alpha-ready bitmaps.

+

See also: ALLEGRO_COLOR

+

Examples:

+ +

Deferred drawing

+

al_hold_bitmap_drawing

+
void al_hold_bitmap_drawing(bool hold)
+

Source Code

+

Enables or disables deferred bitmap drawing. This allows for efficient drawing of many bitmaps that share a parent bitmap, such as sub-bitmaps from a tilesheet or simply identical bitmaps. Drawing bitmaps that do not share a parent is less efficient, so it is advisable to stagger bitmap drawing calls such that the parent bitmap is the same for large number of those calls. While deferred bitmap drawing is enabled, the only functions that can be used are the bitmap drawing functions and font drawing functions. Changing the state such as the blending modes will result in undefined behaviour. One exception to this rule are the non-projection transformations. It is possible to set a new transformation while the drawing is held.

+

No drawing is guaranteed to take place until you disable the hold. Thus, the idiom of this function’s usage is to enable the deferred bitmap drawing, draw as many bitmaps as possible, taking care to stagger bitmaps that share parent bitmaps, and then disable deferred drawing. As mentioned above, this function also works with bitmap and truetype fonts, so if multiple lines of text need to be drawn, this function can speed things up.

+

See also: al_is_bitmap_drawing_held

+

Examples:

+ +

al_is_bitmap_drawing_held

+
bool al_is_bitmap_drawing_held(void)
+

Source Code

+

Returns whether the deferred bitmap drawing mode is turned on or off.

+

See also: al_hold_bitmap_drawing

+

Image I/O

+

al_register_bitmap_loader

+
bool al_register_bitmap_loader(const char *extension,
+   ALLEGRO_BITMAP *(*loader)(const char *filename, int flags))
+

Source Code

+

Register a handler for al_load_bitmap. The given function will be used to handle the loading of bitmaps files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The loader argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_bitmap_saver, al_register_bitmap_loader_f

+

al_register_bitmap_saver

+
bool al_register_bitmap_saver(const char *extension,
+   bool (*saver)(const char *filename, ALLEGRO_BITMAP *bmp))
+

Source Code

+

Register a handler for al_save_bitmap. The given function will be used to handle the saving of bitmaps files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The saver argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_bitmap_loader, al_register_bitmap_saver_f

+

al_register_bitmap_loader_f

+
bool al_register_bitmap_loader_f(const char *extension,
+   ALLEGRO_BITMAP *(*fs_loader)(ALLEGRO_FILE *fp, int flags))
+

Source Code

+

Register a handler for al_load_bitmap_f. The given function will be used to handle the loading of bitmaps files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The fs_loader argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_bitmap_loader

+

al_register_bitmap_saver_f

+
bool al_register_bitmap_saver_f(const char *extension,
+   bool (*fs_saver)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp))
+

Source Code

+

Register a handler for al_save_bitmap_f. The given function will be used to handle the saving of bitmaps files with the given extension.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The saver_f argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

See also: al_register_bitmap_saver

+

al_load_bitmap

+
ALLEGRO_BITMAP *al_load_bitmap(const char *filename)
+

Source Code

+

Loads an image file into a new ALLEGRO_BITMAP. The file type is determined by the extension, except if the file has no extension in which case al_identify_bitmap is used instead.

+

Returns NULL on error.

+

This is the same as calling al_load_bitmap_flags with a flags parameter of 0.

+
+

Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

+
+

See also: al_load_bitmap_flags, al_load_bitmap_f, al_register_bitmap_loader, al_set_new_bitmap_format, al_set_new_bitmap_flags, al_init_image_addon

+

Examples:

+ +

al_load_bitmap_flags

+
ALLEGRO_BITMAP *al_load_bitmap_flags(const char *filename, int flags)
+

Source Code

+

Loads an image file into a new ALLEGRO_BITMAP. The file type is determined by the extension, except if the file has no extension in which case al_identify_bitmap is used instead.

+

Returns NULL on error.

+

The flags parameter may be a combination of the following constants:

+
+
ALLEGRO_NO_PREMULTIPLIED_ALPHA
+

By default, Allegro pre-multiplies the alpha channel of an image with the images color data when it loads it. Typically that would look something like this:

+
r = get_float_byte();
+g = get_float_byte();
+b = get_float_byte();
+a = get_float_byte();
+
+r = r * a;
+g = g * a;
+b = b * a;
+
+set_image_pixel(x, y, r, g, b, a);
+

The reason for this can be seen in the Allegro example ex_premulalpha, ie, using pre-multiplied alpha gives more accurate color results in some cases. To use alpha blending with images loaded with pre-multiplied alpha, you would use the default blending mode, which is set with al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA).

+

The ALLEGRO_NO_PREMULTIPLIED_ALPHA flag being set will ensure that images are not loaded with alpha pre-multiplied, but are loaded with color values direct from the image. That looks like this:

+
r = get_float_byte();
+g = get_float_byte();
+b = get_float_byte();
+a = get_float_byte();
+
+set_image_pixel(x, y, r, g, b, a);
+

To draw such an image using regular alpha blending, you would use al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) to set the correct blender. This has some caveats. First, as mentioned above, drawing such an image can result in less accurate color blending (when drawing an image with linear filtering on, the edges will be darker than they should be). Second, the behaviour is somewhat confusing, which is explained in the example below.

+
// Load and create bitmaps with an alpha channel
+al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA);
+// Load some bitmap with alpha in it
+bmp = al_load_bitmap("some_alpha_bitmap.png");
+// We will draw to this buffer and then draw this buffer to the screen
+tmp_buffer = al_create_bitmap(SCREEN_W, SCREEN_H);
+// Set the buffer as the target and clear it
+al_set_target_bitmap(tmp_buffer);
+al_clear_to_color(al_map_rgba_f(0, 0, 0, 1));
+// Draw the bitmap to the temporary buffer
+al_draw_bitmap(bmp, 0, 0, 0);
+// Finally, draw the buffer to the screen
+// The output will look incorrect (may take close inspection
+// depending on the bitmap -- it may also be very obvious)
+al_set_target_bitmap(al_get_backbuffer(display));
+al_draw_bitmap(tmp_buffer, 0, 0, 0);
+

To explain further, if you have a pixel with 0.5 alpha, and you’re using (ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) for blending, the formula is:

+
a = da * dst + sa * src
+

Expands to:

+
result_a = dst_a * (1-0.5) + 0.5 * 0.5
+

So if you draw the image to the temporary buffer, it is blended once resulting in 0.75 alpha, then drawn again to the screen, blended in the same way, resulting in a pixel has 0.1875 as an alpha value.

+
+
ALLEGRO_KEEP_INDEX
+
Load the palette indices of 8-bit .bmp and .pcx files instead of the rgb colors. Since 5.1.0. +
+
ALLEGRO_KEEP_BITMAP_FORMAT
+

Force the resulting ALLEGRO_BITMAP to use the same format as the file.

+

This is not yet honoured.

+
+
+
+

Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

+
+

Since: 5.1.0

+

See also: al_load_bitmap

+

Examples:

+ +

al_load_bitmap_f

+
ALLEGRO_BITMAP *al_load_bitmap_f(ALLEGRO_FILE *fp, const char *ident)
+

Source Code

+

Loads an image from an ALLEGRO_FILE stream into a new ALLEGRO_BITMAP. The file type is determined by the passed ‘ident’ parameter, which is a file name extension including the leading dot. If (and only if) ‘ident’ is NULL, the file type is determined with al_identify_bitmap_f instead.

+

This is the same as calling al_load_bitmap_flags_f with 0 for the flags parameter.

+

Returns NULL on error. The file remains open afterwards.

+
+

Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

+
+

See also: al_load_bitmap_flags_f, al_load_bitmap, al_register_bitmap_loader_f, al_init_image_addon

+

Examples:

+ +

al_load_bitmap_flags_f

+
ALLEGRO_BITMAP *al_load_bitmap_flags_f(ALLEGRO_FILE *fp,
+   const char *ident, int flags)
+

Source Code

+

Loads an image from an ALLEGRO_FILE stream into a new ALLEGRO_BITMAP. The file type is determined by the passed ‘ident’ parameter, which is a file name extension including the leading dot. If (and only if) ‘ident’ is NULL, the file type is determined with al_identify_bitmap_f instead.

+

The flags parameter is the same as for al_load_bitmap_flags.

+

Returns NULL on error. The file remains open afterwards.

+
+

Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

+
+

Since: 5.1.0

+

See also: al_load_bitmap_f, al_load_bitmap_flags

+

al_save_bitmap

+
bool al_save_bitmap(const char *filename, ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Saves an ALLEGRO_BITMAP to an image file. The file type is determined by the extension.

+

Returns true on success, false on error.

+
+

Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

+
+

See also: al_save_bitmap_f, al_register_bitmap_saver, al_init_image_addon

+

Examples:

+ +

al_save_bitmap_f

+
bool al_save_bitmap_f(ALLEGRO_FILE *fp, const char *ident,
+   ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Saves an ALLEGRO_BITMAP to an ALLEGRO_FILE stream. The file type is determined by the passed ‘ident’ parameter, which is a file name extension including the leading dot.

+

Returns true on success, false on error. The file remains open afterwards.

+
+

Note: the core Allegro library does not support any image file formats by default. You must use the allegro_image addon, or register your own format handler.

+
+

See also: al_save_bitmap, al_register_bitmap_saver_f, al_init_image_addon

+

al_register_bitmap_identifier

+
bool al_register_bitmap_identifier(const char *extension,
+   bool (*identifier)(ALLEGRO_FILE *f))
+

Source Code

+

Register an identify handler for al_identify_bitmap. The given function will be used to detect files for the given extension. It will be called with a single argument of type ALLEGRO_FILE which is a file handle opened for reading and located at the first byte of the file. The handler should try to read as few bytes as possible to safely determine if the given file contents correspond to the type with the extension and return true in that case, false otherwise. The file handle must not be closed but there is no need to reset it to the beginning.

+

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

+

The identifier argument may be NULL to unregister an entry.

+

Returns true on success, false on error. Returns false if unregistering an entry that doesn’t exist.

+

Since: 5.1.12

+

See also: al_identify_bitmap

+

al_identify_bitmap

+
char const *al_identify_bitmap(char const *filename)
+

Source Code

+

This works exactly as al_identify_bitmap_f but you specify the filename of the file for which to detect the type and not a file handle. The extension, if any, of the passed filename is not taken into account - only the file contents.

+

Since: 5.1.12

+

See also: al_init_image_addon, al_identify_bitmap_f, al_register_bitmap_identifier

+

al_identify_bitmap_f

+
char const *al_identify_bitmap_f(ALLEGRO_FILE *fp)
+

Source Code

+

Tries to guess the bitmap file type of the open ALLEGRO_FILE by reading the first few bytes. By default Allegro cannot recognize any file types, but calling al_init_image_addon will add detection of (some of) the types it can read. You can also use al_register_bitmap_identifier to add identification for custom file types.

+

Returns a pointer to a static string with a file extension for the type, including the leading dot. For example “.png” or “.jpg”. Returns NULL if the bitmap type cannot be determined.

+

Since: 5.1.12

+

See also: al_init_image_addon, al_identify_bitmap, al_register_bitmap_identifier

+

Render State

+

ALLEGRO_RENDER_STATE

+
typedef enum ALLEGRO_RENDER_STATE {
+

Source Code

+

Possible render states which can be set with al_set_render_state:

+
+
ALLEGRO_ALPHA_TEST
+
If this is set to 1, the values of ALLEGRO_ALPHA_FUNCTION and ALLEGRO_ALPHA_TEST_VALUE define a comparison function which is performed on the alpha component of each pixel. Only if it evaluates to true the pixel is written. Otherwise no subsequent processing (like depth test or blending) is performed. This can be very useful, for example if a depth buffer is used but you do not want fully transparent pixels to modify it. +
+
ALLEGRO_ALPHA_FUNCTION
+
One of ALLEGRO_RENDER_FUNCTION, only used when ALLEGRO_ALPHA_TEST is 1. +
+
ALLEGRO_ALPHA_TEST_VALUE
+
Only used when ALLEGRO_ALPHA_TEST is 1. Should be a value of 0 - 255. +
+
ALLEGRO_WRITE_MASK
+
This determines how the framebuffer and depthbuffer are updated whenever a pixel is written (in case alpha and/or depth testing is enabled: after all such enabled tests succeed). Depth values are only written if ALLEGRO_DEPTH_TEST is 1, in addition to the write mask flag being set. +
+
ALLEGRO_DEPTH_TEST
+
If this is set to 1, compare the depth value of any newly written pixels with the depth value already in the buffer, according to ALLEGRO_DEPTH_FUNCTION. Allegro primitives with no explicit z coordinate will write a value of 0 into the depth buffer. +
+
ALLEGRO_DEPTH_FUNCTION
+
One of ALLEGRO_RENDER_FUNCTION, only used when ALLEGRO_DEPTH_TEST is 1. +
+
+

Since: 5.1.2

+

See also: al_set_render_state, ALLEGRO_RENDER_FUNCTION, ALLEGRO_WRITE_MASK_FLAGS

+

ALLEGRO_RENDER_FUNCTION

+
typedef enum ALLEGRO_RENDER_FUNCTION {
+

Source Code

+

Possible functions are:

+
    +
  • ALLEGRO_RENDER_NEVER
  • +
  • ALLEGRO_RENDER_ALWAYS
  • +
  • ALLEGRO_RENDER_LESS
  • +
  • ALLEGRO_RENDER_EQUAL
  • +
  • ALLEGRO_RENDER_LESS_EQUAL
    +
  • +
  • ALLEGRO_RENDER_GREATER
    +
  • +
  • ALLEGRO_RENDER_NOT_EQUAL
  • +
  • ALLEGRO_RENDER_GREATER_EQUAL
  • +
+

Since: 5.1.2

+

See also: al_set_render_state

+

ALLEGRO_WRITE_MASK_FLAGS

+
typedef enum ALLEGRO_WRITE_MASK_FLAGS {
+

Source Code

+

Each enabled bit means the corresponding value is written, a disabled bit means it is not.

+
    +
  • ALLEGRO_MASK_RED
  • +
  • ALLEGRO_MASK_GREEN
  • +
  • ALLEGRO_MASK_BLUE
  • +
  • ALLEGRO_MASK_ALPHA
  • +
  • ALLEGRO_MASK_DEPTH
  • +
  • ALLEGRO_MASK_RGB - Same as RED | GREEN | BLUE.
  • +
  • ALLEGRO_MASK_RGBA - Same as RGB | ALPHA.
  • +
+

Since: 5.1.2

+

See also: al_set_render_state

+

al_set_render_state

+
void al_set_render_state(ALLEGRO_RENDER_STATE state, int value)
+

Source Code

+

Set one of several render attributes; see ALLEGRO_RENDER_STATE for details.

+

This function does nothing if the target bitmap is a memory bitmap.

+

Since: 5.1.2

+

See also: ALLEGRO_RENDER_STATE, ALLEGRO_RENDER_FUNCTION, ALLEGRO_WRITE_MASK_FLAGS

+

Examples:

+ +

al_backup_dirty_bitmap

+
void al_backup_dirty_bitmap(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

On some platforms, notably Windows Direct3D and Android, textures may be lost at any time for events such as display resize or switching out of the app. On those platforms, bitmaps created without the ALLEGRO_NO_PRESERVE_TEXTURE flag automatically get backed up to system memory every time al_flip_display is called.

+

This function gives you more control over when your bitmaps get backed up. By calling this function after modifying a bitmap, you can make sure the bitmap is backed up right away instead of during the next flip.

+

Since: 5.2.1

+
+

Unstable API: This API is new and subject to refinement.

+
+

See also: al_backup_dirty_bitmaps, al_create_bitmap

+

al_backup_dirty_bitmaps

+
void al_backup_dirty_bitmaps(ALLEGRO_DISPLAY *display)
+

Source Code

+

Backs up all of a display’s bitmaps to system memory.

+

Since: 5.2.1

+
+

Unstable API: This API is new and subject to refinement.

+
+

See also: al_backup_dirty_bitmap

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/haptic.html b/allegro/docs/html/refman/haptic.html new file mode 100644 index 00000000..2d565f34 --- /dev/null +++ b/allegro/docs/html/refman/haptic.html @@ -0,0 +1,684 @@ + + + + + + + Haptic routines + + + + + + + + +
+ + +
+

Haptic routines

+
+ +

Haptic functions support force feedback and vibration on input devices. These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

Currently force feedback is fully supported on Linux and on Windows for DirectInput compatible devices. There is also minimal support for Android. It is not yet supported on OSX, iOS, or on Windows for XInput compatible devices.

+

ALLEGRO_HAPTIC

+
typedef struct ALLEGRO_HAPTIC ALLEGRO_HAPTIC;
+

Source Code

+

This is an abstract data type representing a haptic device that supports force feedback or vibration.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

See also: al_get_haptic_from_joystick

+

Examples:

+ +

ALLEGRO_HAPTIC_CONSTANTS

+
enum ALLEGRO_HAPTIC_CONSTANTS
+

Source Code

+

This enum contains flags that are used to define haptic effects and capabilities. If the flag is set in the return value of al_get_haptic_capabilities, it means the device supports the given effect. The value of these flags should be set into a ALLEGRO_HAPTIC_EFFECT struct to determine what kind of haptic effect should be played.

+
    +
  • ALLEGRO_HAPTIC_RUMBLE - simple vibration effects
  • +
  • ALLEGRO_HAPTIC_PERIODIC - periodic, wave-form effects
  • +
  • ALLEGRO_HAPTIC_CONSTANT - constant effects
  • +
  • ALLEGRO_HAPTIC_SPRING - spring effects
  • +
  • ALLEGRO_HAPTIC_FRICTION - friction effects
  • +
  • ALLEGRO_HAPTIC_DAMPER - damper effects
  • +
  • ALLEGRO_HAPTIC_INERTIA - inertia effects
  • +
  • ALLEGRO_HAPTIC_RAMP - ramp effects
  • +
  • ALLEGRO_HAPTIC_SQUARE - square wave periodic effect
  • +
  • ALLEGRO_HAPTIC_TRIANGLE - triangle wave periodic effect
  • +
  • ALLEGRO_HAPTIC_SINE - sine wave periodic effect
  • +
  • ALLEGRO_HAPTIC_SAW_UP - upwards saw wave periodic effect
  • +
  • ALLEGRO_HAPTIC_SAW_DOWN - downwards saw wave periodic effect
  • +
  • ALLEGRO_HAPTIC_CUSTOM - custom wave periodic effect
  • +
  • ALLEGRO_HAPTIC_GAIN - the haptic device supports gain setting
  • +
  • ALLEGRO_HAPTIC_ANGLE - the haptic device supports angle coordinates
  • +
  • ALLEGRO_HAPTIC_RADIUS - the haptic device supports radius coordinates
  • +
  • ALLEGRO_HAPTIC_AZIMUTH - the haptic device supports azimuth coordinates
  • +
  • ALLEGRO_HAPTIC_AUTOCENTER
  • +
+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

See also: al_get_haptic_capabilities, ALLEGRO_HAPTIC_EFFECT

+

ALLEGRO_HAPTIC_EFFECT

+
struct ALLEGRO_HAPTIC_EFFECT
+

Source Code

+

This struct models a particular haptic or vibration effect. It needs to be filled in correctly and uploaded to a haptic device before the device can play it back.

+

Fields:

+
+
type
+

The type of the haptic effect. May be one of the ALLEGRO_HAPTIC_CONSTANTS constants between or equal to ALLEGRO_HAPTIC_RUMBLE and ALLEGRO_HAPTIC_RAMP.

+
    +
  • If type is set to ALLEGRO_HAPTIC_RUMBLE, then the effect is a simple “rumble” or vibration effect that shakes the device. In some cases, such as on a mobile platform, the whole device may shake.

  • +
  • If type is set to ALLEGRO_HAPTIC_PERIODIC, the effect is a shake or vibration of which the intensity is a periodic wave form.

  • +
  • If type is set to ALLEGRO_HAPTIC_CONSTANT, the effect is a constant pressure, motion or push-back in a certain direction of the axes of the device.

  • +
  • If type is set to ALLEGRO_HAPTIC_SPRING, the effect is a springy kind of resistance against motion of the axes of the haptic device.

  • +
  • If type is set to ALLEGRO_HAPTIC_FRICTION, the effect is a friction kind of resistance against motion of the axes of the haptic device.

  • +
  • If type is set to ALLEGRO_HAPTIC_DAMPER, the effect is a damper kind of resistance against motion of the axes of the haptic device.

  • +
  • If type is set to ALLEGRO_HAPTIC_INERTIA, the effect causes inertia or slowness of motions on the axes of the haptic device.

  • +
  • If type is set to ALLEGRO_HAPTIC_RAMP, the effect causes a pressure or push-back that ramps up or down depending on the position of the axis.

  • +
+
+
direction
+

The direction of location in 3D space where the effect should be played. Allegro haptic devices model directions in 3D space using spherical coordinates. However, the haptic device may not support localized effects, or may not support all coordinate components.

+

In Allegro’s coordinate system, the value in direction.angle determines the planar angle between the effect and the direction of the user who holds the device, expressed in radians. This angle increases clockwise away from the user. So, an effect with an angle 0.0 takes place in the direction of the user of the haptic device, an angle of π/2 is to the left of the user, an angle of π means the direction away from the user, and an angle of 3π/2 means to the right of the user.

+

If al_get_haptic_capabilities has the flag ALLEGRO_HAPTIC_ANGLE set, then setting direction.angle is supported. Otherwise, it is unsupported, and you should set it to 0.

+

The value in direction.radius is a relative value between 0.0 and 1.0 that determines the relative distance from the center of the haptic device at which the effect will play back. A value of 0 means that the effect should play back at the center of the device. A value of 1.0 means that the effect should play back away from the center as far as is possible.

+

If al_get_haptic_capabilities has the flag ALLEGRO_HAPTIC_RADIUS set, then setting direction.radius is supported. Otherwise, it is unsupported, and you should set it to 0.

+

The value in direction.azimuth determines the elevation angle between the effect and the plane in which the user is holding the device, expressed in radians. An effect with an azimuth 0.0 plays back in the plane in which the user is holding the device, an azimuth +π/2 means the effect plays back vertically above the user plane, and an azimuth -π/2 means the effect plays back vertically below the user plane.

+

If al_get_haptic_capabilities has the flag ALLEGRO_HAPTIC_AZIMUTH set, then setting direction.azimuth is supported. Otherwise, it is unsupported, and you should set it to 0.

+
+
replay
+
Determines how the effect should be played back. replay.length is the duration in seconds of the effect, and replay.delay is the time in seconds that the effect playback should be delayed when playback is started with al_play_haptic_effect. +
+
data
+

Determines in detail the parameters of the haptic effect to play back.

+

If type is set to ALLEGRO_HAPTIC_RUMBLE, then data.rumble.strong_magnitude must be set to a relative magnitude between 0.0 and 1.0 to determine how intensely the “large” rumble motor of the haptic device will vibrate, and data.rumble.weak_magnitude must be set to relative magnitude between 0.0 and 1.0 to determine how intensely the “weak” ruble motor of the haptic device will vibrate. Not all devices have a “weak” motor, in which case the value set in data.rumble.weak_magnitude will be ignored.

+

If type is set to ALLEGRO_HAPTIC_PERIODIC, then data.periodic.waveform must be set to one of ALLEGRO_HAPTIC_SQUARE, ALLEGRO_HAPTIC_TRIANGLE, ALLEGRO_HAPTIC_SINE, ALLEGRO_HAPTIC_SAW_UP, ALLEGRO_HAPTIC_SAW_DOWN, ALLEGRO_HAPTIC_CUSTOM. This will then determine the wave form of the vibration effect that will be played on the haptic device.

+

In these cases, data.periodic.period must be set to the period in seconds of the wave form. The field data.periodic.magnitude must be set to the relative magnitude of intensity between -1.0 and 1.0 at which the wave form of the vibration will be played back. The field data.periodic.offset must be filled in with the offset from origin in seconds of the wave form of vibration, and the field data.periodic.phase is the phase of the wave form of vibration in seconds.

+

If data.periodic.waveform is set to ALLEGRO_HAPTIC_CUSTOM, then data.periodic.custom_data must point to an array of data.periodic.custom_len doubles, each with values between -1.0 and 1.0. This value array will determine the shape of the wave form of the haptic effect. ALLEGRO_HAPTIC_CUSTOM is not supported on some platforms, so use al_get_haptic_capabilities to check if it’s available. If it isn’t, you may want to play back a non-custom wave effect as a substitute instead.

+

If type is set to ALLEGRO_HAPTIC_CONSTANT, then data.constant.level must be set to a relative intensity value between 0.0 and 1.0 to determine the intensity of the effect.

+

If type is set to any of ALLEGRO_HAPTIC_SPRING, ALLEGRO_HAPTIC_FRICTION, ALLEGRO_HAPTIC_DAMPER, ALLEGRO_HAPTIC_INERTIA, ALLEGRO_HAPTIC_RAMP, then the data.condition struct should be filled in. To explain this better, it’s best to keep in mind that these kinds of effects are most useful for steering-wheel kind of devices, where resistance or inertia should be applied when turning the device’s wheel a certain distance to the left or right.

+

The field data.condition.right_saturation must be filled in with a relative magnitude between -1.0 and 1.0 to determine the intensity of resistance or inertia on the “right” side of the axis. Likewise, data.condition.left_saturation must be filled in with a relative magnitude between -1.0 and 1.0 to determine the intensity of resistance or inertia on the “left” side of the axis.

+

The field data.condition.deadband must be filled in with a relative value between 0.0 and 1.0 to determine the relative width of the “dead band” of the haptic effect. As long as the axis of the haptic device remains in the “dead band” area, the effect will not be applied. A value of 0.0 means there is no dead band, and a value of 1.0 means it applied over the whole range of the axis in question.

+

The field data.condition.center must be filled in with a relative value between -1.0 and 1.0 to determine the relative position of the “center” of the effect around which the dead band is centered. It should be set to 0.0 in case the center should not be shifted.

+

The field data.condition.right_coef and data.condition.right_left_coef must be filled in with a relative coefficient, that will determine how quickly the effect ramps up on the right and left side. If set to 1.0, then the effect will be immediately at full intensity when outside of the dead band. If set to 0.0 the effect will not be felt at all.

+

If type is set to ALLEGRO_HAPTIC_RAMP, then data.ramp.start_level should be set to a relative magnitude value between -1.0 and 1.0 to determine the initial intensity of the haptic effect. The field data.ramp.end_level should be set to a relative magnitude value between -1.0 and 1.0 to determine the final intensity of the haptic effect at the end of playback.

+

If type is set to any of ALLEGRO_HAPTIC_PERIODIC, ALLEGRO_HAPTIC_CONSTANT, ALLEGRO_HAPTIC_RAMP, then data.envelope determines the “envelope” of the effect. That is, it determines the duration and intensity for the ramp-up attack or “fade in” and the ramp-down or “fade out” of the effect.

+

In these cases the field data.envelope.attack_level must be set to a relative value between 0.0 and 1.0 that determines the intensity the effect should have when it starts playing (after replay.delay seconds have passed since the playback was started). The field data.envelope.attack_length must be set to the time in seconds that the effect should ramp up to the maximum intensity as set by the other parameters. If data.envelope.attack_length is 0, then the effect will play immediately at full intensity.

+

The field data.envelope.fade_level must be set to a relative value between 0.0 and 1.0 that determines the intensity the effect should have when it stops playing after replay.length + replay.delay seconds have passed since the playback of the effect started. The field data.envelope.fade_length must be set to the time in seconds that the effect should fade out before it finishes playing. If data.envelope.fade_length is 0, then the effect will not fade out.

+

If you don’t want to use an envelope, then set all four fields of data.envelope to 0.0. The effect will then play back at full intensity throughout its playback.

+
+
+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

ALLEGRO_HAPTIC_EFFECT_ID

+
typedef struct ALLEGRO_HAPTIC_EFFECT_ID ALLEGRO_HAPTIC_EFFECT_ID;
+

Source Code

+

This struct is used as a handle to control playback of a haptic effect and should be considered opaque. Its implementation is visible merely to allow allocation by the users of the Allegro library.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_install_haptic

+
bool al_install_haptic(void)
+

Source Code

+

Installs the haptic (force feedback) device subsystem. This must be called before using any other haptic-related functions. Returns true if the haptics subsystem could be initialized correctly, false in case of error.

+

For portability you should first open a display before calling al_install_haptic. On some platforms, such as DirectInput under Windows, al_install_haptic will only work if at least one active display is available. This display must stay available until al_uninstall_haptic is called.

+

If you need to close and reopen your active display for example, then you should call al_uninstall_haptic before closing the display, and al_install_haptic after opening it again.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_uninstall_haptic

+
void al_uninstall_haptic(void)
+

Source Code

+

Uninstalls the haptic device subsystem. This is useful since on some platforms haptic effects are bound to the active display.

+

If you need to close and reopen your active display for example, then you should call al_uninstall_haptic before closing the display, and al_install_haptic after opening it again.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_is_haptic_installed

+
bool al_is_haptic_installed(void)
+

Source Code

+

Returns true if the haptic device subsystem is installed, false if not.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_is_mouse_haptic

+
bool al_is_mouse_haptic(ALLEGRO_MOUSE *dev)
+

Source Code

+

Returns true if the mouse has haptic capabilities, false if not.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_is_keyboard_haptic

+
bool al_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev)
+

Source Code

+

Returns true if the keyboard has haptic capabilities, false if not.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_is_display_haptic

+
bool al_is_display_haptic(ALLEGRO_DISPLAY *dev)
+

Source Code

+

Returns true if the display has haptic capabilities, false if not. This mainly concerns force feedback that shakes a hand held device, such as a phone or a tablet.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_is_joystick_haptic

+
bool al_is_joystick_haptic(ALLEGRO_JOYSTICK *dev)
+

Source Code

+

Returns true if the joystick has haptic capabilities, false if not.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_is_touch_input_haptic

+
bool al_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev)
+

Source Code

+

Returns true if the touch input device has haptic capabilities, false if not.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_get_haptic_from_mouse

+
ALLEGRO_HAPTIC *al_get_haptic_from_mouse(ALLEGRO_MOUSE *dev)
+

Source Code

+

If the mouse has haptic capabilities, returns the associated haptic device handle. Otherwise returns NULL.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_get_haptic_from_keyboard

+
ALLEGRO_HAPTIC *al_get_haptic_from_keyboard(ALLEGRO_KEYBOARD *dev)
+

Source Code

+

If the keyboard has haptic capabilities, returns the associated haptic device handle. Otherwise returns NULL.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_get_haptic_from_display

+
ALLEGRO_HAPTIC *al_get_haptic_from_display(ALLEGRO_DISPLAY *dev)
+

Source Code

+

If the display has haptic capabilities, returns the associated haptic device handle. Otherwise returns NULL.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_get_haptic_from_joystick

+
ALLEGRO_HAPTIC *al_get_haptic_from_joystick(ALLEGRO_JOYSTICK *dev)
+

Source Code

+

If the joystick has haptic capabilities, returns the associated haptic device handle. Otherwise returns NULL. It’s necessary to call this again every time the joystick configuration changes, such as through hot plugging. In that case, the old haptic device must be released using al_release_haptic.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_get_haptic_from_touch_input

+
ALLEGRO_HAPTIC *al_get_haptic_from_touch_input(ALLEGRO_TOUCH_INPUT *dev)
+

Source Code

+

If the touch input device has haptic capabilities, returns the associated haptic device handle. Otherwise returns NULL.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_release_haptic

+
bool al_release_haptic(ALLEGRO_HAPTIC *haptic)
+

Source Code

+

Releases the haptic device and its resources when it’s not needed anymore. Should also be used in case the joystick configuration changed, such as when a joystick is hot plugged. This function also automatically releases all haptic effects that are still uploaded to the device and that have not been released manually using al_release_haptic_effect.

+

Returns true on success or false if the haptic device couldn’t be released for any reason, such as NULL being passed, the device not being active or failure in the driver.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_is_haptic_active

+
bool al_is_haptic_active(ALLEGRO_HAPTIC *hap)
+

Source Code

+

Returns true if the haptic device can currently be used, false if not.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_get_haptic_capabilities

+
int al_get_haptic_capabilities(ALLEGRO_HAPTIC *hap)
+

Source Code

+

Returns an integer with or’ed values from ALLEGRO_HAPTIC_CONSTANTS, which, if set, indicate that the haptic device supports the given feature.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_is_haptic_capable

+
bool al_is_haptic_capable(ALLEGRO_HAPTIC * hap, int query) {
+

Source Code

+

Returns true if the haptic device supports the feature indicated by the query parameter, false if the feature is not supported. The query parameter must be one of the values of ALLEGRO_HAPTIC_CONSTANTS.

+

Since: 5.1.9

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

See also: al_get_haptic_capabilities

+

al_set_haptic_gain

+
bool al_set_haptic_gain(ALLEGRO_HAPTIC *hap, double gain)
+

Source Code

+

Sets the gain of the haptic device if supported. Gain is much like volume for sound, it is as if every effect’s intensity is multiplied by it. Gain is a value between 0.0 and 1.0. Returns true if set successfully, false if not. Only works if al_get_haptic_capabilities returns a value that has ALLEGRO_HAPTIC_GAIN set. If not, this function returns false, and all effects will be played without any gain influence.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_get_haptic_gain

+
double al_get_haptic_gain(ALLEGRO_HAPTIC *hap)
+

Source Code

+

Returns the current gain of the device. Gain is much like volume for sound, it is as if every effect’s intensity is multiplied by it. Gain is a value between 0.0 and 1.0. Only works correctly if al_get_haptic_capabilities returns a value that has ALLEGRO_HAPTIC_GAIN set. If this is not set, this function will simply return 1.0 and all effects will be played without any gain influence.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_set_haptic_autocenter

+
bool al_set_haptic_autocenter(ALLEGRO_HAPTIC *hap, double intensity)
+

Source Code

+

Turns on or off the automatic centering feature of the haptic device if supported. Depending on the device automatic centering may ensure that the axes of the device are centered again automatically after playing a haptic effect. The intensity parameter should be passed with a value between 0.0 and 1.0. The value 0.0 means automatic centering is disabled, and 1.0 means full strength automatic centering. Any value in between those two extremes will result in partial automatic centering. Some platforms do not support partial automatic centering. If that is the case, a value of less than 0.5 will turn it off, while a value equal to or higher to 0.5 will turn it on. Returns true if set successfully, false if not. Can only work if al_get_haptic_capabilities returns a value that has ALLEGRO_HAPTIC_AUTOCENTER set. If not, this function returns false.

+

Since: 5.1.9

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_get_haptic_autocenter

+
double al_get_haptic_autocenter(ALLEGRO_HAPTIC *hap)
+

Source Code

+

Returns the current automatic centering intensity of the device. Depending on the device automatic centering may ensure that the axes of the device are centered again automatically after playing a haptic effect. The return value can be between 0.0 and 1.0. The value 0.0 means automatic centering is disabled, and 1.0 means automatic centering is enabled at full strength. Any value in between those two extremes means partial automatic centering is enabled. Some platforms do not support partial automatic centering. If that is the case, a value of less than 0.5 means it is turned off, while a value equal to or higher to 0.5 means it is turned on. Can only work if al_get_haptic_capabilities returns a value that has ALLEGRO_HAPTIC_AUTOCENTER set. If not, this function returns 0.0.

+

Since: 5.1.9

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_get_max_haptic_effects

+
int al_get_max_haptic_effects(ALLEGRO_HAPTIC *hap)
+

Source Code

+

Returns the maximum amount of haptic effects that can be uploaded to the device. This depends on the operating system, driver, platform and the device itself. This may return a value as low as 1.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_is_haptic_effect_ok

+
bool al_is_haptic_effect_ok(ALLEGRO_HAPTIC *hap, ALLEGRO_HAPTIC_EFFECT *effect)
+

Source Code

+

Returns true if the haptic device can play the haptic effect as given, false if not. The haptic effect must have been filled in completely and correctly.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_upload_haptic_effect

+
bool al_upload_haptic_effect(ALLEGRO_HAPTIC *hap,
+   ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id)
+

Source Code

+

Uploads the haptic effect to the device. The haptic effect must have been filled in completely and correctly. You must also pass in a pointer to a user allocated ALLEGRO_HAPTIC_EFFECT_ID. This id can be used to control playback of the effect. Returns true if the effect was successfully uploaded, false if not.

+

The function al_get_max_haptic_effects returns how many effects can be uploaded to the device at the same time.

+

The same haptic effect can be uploaded several times, as long as care is taken to pass in a different ALLEGRO_HAPTIC_EFFECT_ID.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_play_haptic_effect

+
bool al_play_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop)
+

Source Code

+

Plays back a previously uploaded haptic effect. The play_id must be a valid ALLEGRO_HAPTIC_EFFECT_ID obtained from al_upload_haptic_effect, al_upload_and_play_haptic_effect or al_rumble_haptic.

+

The haptic effect will be played back loop times in sequence. If loop is less than or equal to 1, then the effect will be played once only.

+

This function returns immediately and doesn’t wait for the playback to finish. It returns true if the playback was started successfully or false if not.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_upload_and_play_haptic_effect

+
bool al_upload_and_play_haptic_effect(ALLEGRO_HAPTIC *hap,
+   ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id, int loop)
+

Source Code

+

Uploads the haptic effect to the device and starts playback immediately. Returns true if the upload and playback were successful, false if either failed.

+

In case false is returned, the haptic effect will be automatically released as if al_release_haptic_effect had been called, so there is no need to call it again manually in this case. However, if true is returned, it is necessary to call al_release_haptic_effect when the effect isn’t needed anymore, to prevent the amount of available effects on the haptic devicefrom running out.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

See also: al_upload_haptic_effect, al_play_haptic_effect

+

Examples:

+ +

al_stop_haptic_effect

+
bool al_stop_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id)
+

Source Code

+

Stops playing a previously uploaded haptic effect. The play_id must be a valid ALLEGRO_HAPTIC_EFFECT_ID obtained from al_upload_haptic_effect, al_upload_and_play_haptic_effect or al_rumble_haptic.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_is_haptic_effect_playing

+
bool al_is_haptic_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id)
+

Source Code

+

Returns true if the haptic effect is currently playing. Returns false if the effect has been stopped or if it has already finished playing, or if it has not been played yet. The play_id must be a valid ALLEGRO_HAPTIC_EFFECT_ID obtained from al_upload_haptic_effect, al_upload_and_play_haptic_effect or al_rumble_haptic.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_get_haptic_effect_duration

+
double al_get_haptic_effect_duration(ALLEGRO_HAPTIC_EFFECT * effect)
+

Source Code

+

Returns the estimated duration in seconds of a single loop of the given haptic effect. The effect’s effect.replay must have been filled in correctly before using this function.

+

Since: 5.1.9

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

al_release_haptic_effect

+
bool al_release_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id)
+

Source Code

+

Releases a previously uploaded haptic effect from the device it has been uploaded to, allowing for other effects to be uploaded. The play_id must be a valid ALLEGRO_HAPTIC_EFFECT_ID obtained from al_upload_haptic_effect, al_upload_and_play_haptic_effect or al_rumble_haptic.

+

This function is called automatically when you call al_release_haptic on a ALLEGRO_HAPTIC for all effects that are still uploaded to the device. Therefore this function is most useful if you want to upload and release haptic effects dynamically, for example as a way to circumvent the limit imposed by al_get_max_haptic_effects.

+

Returns true on success, false if the effect couldn’t be released for any reason such as when NULL is passed, the effect is not active or failure to release the effect by the driver.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

Examples:

+ +

al_rumble_haptic

+
bool al_rumble_haptic(ALLEGRO_HAPTIC *hap,
+   double intensity, double duration, ALLEGRO_HAPTIC_EFFECT_ID *id)
+

Source Code

+

Uploads a simple rumble effect to the haptic device and starts playback immediately. The parameter intensity is a relative magnitude between 0.0 and 1.0 that determines the intensity of the rumble effect. The duration determines the duration of the effect in seconds.

+

You must also pass in a pointer to a user allocated ALLEGRO_HAPTIC_EFFECT_ID. It it is stored a reference to be used to control playback of the effect. Returns true if the rumble effect was successfully uploaded and started, false if not.

+

In case false is returned, the rumble effect will be automatically released as if al_release_haptic_effect had been called, so there is no need to call it again manually in this case. However, if true is returned, it is necessary to call al_release_haptic_effect when the effect isn’t needed anymore, to prevent the amount of available effects on the haptic device from running out.

+

Since: 5.1.8

+
+

Unstable API: Perhaps could be simplified due to limited support for all the exposed features across all of the platforms. Awaiting feedback from users.

+
+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/image.html b/allegro/docs/html/refman/image.html new file mode 100644 index 00000000..2011f1ad --- /dev/null +++ b/allegro/docs/html/refman/image.html @@ -0,0 +1,212 @@ + + + + + + + Image I/O addon + + + + + + + + +
+ + +
+

Image I/O addon

+
+ +

These functions are declared in the following header file. Link with allegro_image.

+
 #include <allegro5/allegro_image.h>
+

Some of the format handlers define configuration options for specifying things like compression level or gamma handling. Refer to al_get_system_config for their documentation.

+

al_init_image_addon

+
bool al_init_image_addon(void)
+

Source Code

+

Initializes the image addon. This registers bitmap format handlers for al_load_bitmap, al_load_bitmap_f, al_save_bitmap, al_save_bitmap_f.

+

The following types are built into the Allegro image addon and guaranteed to be available: BMP, DDS, PCX, TGA. Every platform also supports JPEG and PNG via external dependencies.

+

Other formats may be available depending on the operating system and installed libraries, but are not guaranteed and should not be assumed to be universally available.

+

The DDS format is only supported to load from, and only if the DDS file contains textures compressed in the DXT1, DXT3 and DXT5 formats. Note that when loading a DDS file, the created bitmap will always be a video bitmap and will have the pixel format matching the format in the file.

+

Examples:

+ +

al_is_image_addon_initialized

+
bool al_is_image_addon_initialized(void)
+

Source Code

+

Returns true if the image addon is initialized, otherwise returns false.

+

Since: 5.2.6

+

al_shutdown_image_addon

+
void al_shutdown_image_addon(void)
+

Source Code

+

Shut down the image addon. This is done automatically at program exit, but can be called any time the user wishes as well.

+

al_get_allegro_image_version

+
uint32_t al_get_allegro_image_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:43 UTC +

+
+ + diff --git a/allegro/docs/html/refman/images/LINE_CAP.png b/allegro/docs/html/refman/images/LINE_CAP.png new file mode 100644 index 00000000..c75329e3 Binary files /dev/null and b/allegro/docs/html/refman/images/LINE_CAP.png differ diff --git a/allegro/docs/html/refman/images/LINE_JOIN.png b/allegro/docs/html/refman/images/LINE_JOIN.png new file mode 100644 index 00000000..ee202906 Binary files /dev/null and b/allegro/docs/html/refman/images/LINE_JOIN.png differ diff --git a/allegro/docs/html/refman/images/audio.png b/allegro/docs/html/refman/images/audio.png new file mode 100644 index 00000000..9ad15946 Binary files /dev/null and b/allegro/docs/html/refman/images/audio.png differ diff --git a/allegro/docs/html/refman/images/primitives1.png b/allegro/docs/html/refman/images/primitives1.png new file mode 100644 index 00000000..61fe3667 Binary files /dev/null and b/allegro/docs/html/refman/images/primitives1.png differ diff --git a/allegro/docs/html/refman/images/primitives2.png b/allegro/docs/html/refman/images/primitives2.png new file mode 100644 index 00000000..7f5d2c1b Binary files /dev/null and b/allegro/docs/html/refman/images/primitives2.png differ diff --git a/allegro/docs/html/refman/index.html b/allegro/docs/html/refman/index.html new file mode 100644 index 00000000..3b356cd7 --- /dev/null +++ b/allegro/docs/html/refman/index.html @@ -0,0 +1,169 @@ + + + + + + + Allegro 5 reference manual + + + + + + + + + + + diff --git a/allegro/docs/html/refman/index_all.html b/allegro/docs/html/refman/index_all.html new file mode 100644 index 00000000..b887885b --- /dev/null +++ b/allegro/docs/html/refman/index_all.html @@ -0,0 +1,1303 @@ + + + + + + + Index + + + + + + + + +
+ + +
+

Index

+
+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:44 UTC +

+
+ + diff --git a/allegro/docs/html/refman/joystick.html b/allegro/docs/html/refman/joystick.html new file mode 100644 index 00000000..0fe8b4d4 --- /dev/null +++ b/allegro/docs/html/refman/joystick.html @@ -0,0 +1,411 @@ + + + + + + + Joystick routines + + + + + + + + +
+ + +
+

Joystick routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

On Windows there are two joystick drivers, a DirectInput one and an Xinput one. If support for XInput was compiled in, then it can be enabled by calling al_set_config_value(al_get_system_config(), “joystick”, “driver”, “xinput”) before calling al_install_joystick, or by setting the same option in the allegro5.cfg configuration file. The Xinput and DirectInput drivers are mutually exclusive. The haptics subsystem will use the same driver as the joystick system does.

+

ALLEGRO_JOYSTICK

+
typedef struct ALLEGRO_JOYSTICK ALLEGRO_JOYSTICK;
+

Source Code

+

This is an abstract data type representing a physical joystick.

+

See also: al_get_joystick

+

Examples:

+ +

ALLEGRO_JOYSTICK_STATE

+
typedef struct ALLEGRO_JOYSTICK_STATE ALLEGRO_JOYSTICK_STATE;
+

Source Code

+

This is a structure that is used to hold a “snapshot” of a joystick’s axes and buttons at a particular instant. All fields public and read-only.

+
struct {
+   float axis[num_axes];             // -1.0 to 1.0
+} stick[num_sticks];
+int button[num_buttons];             // 0 to 32767
+

See also: al_get_joystick_state

+

Examples:

+ +

ALLEGRO_JOYFLAGS

+
enum ALLEGRO_JOYFLAGS
+

Source Code

+
    +
  • ALLEGRO_JOYFLAG_DIGITAL - the stick provides digital input
  • +
  • ALLEGRO_JOYFLAG_ANALOGUE - the stick provides analogue input
  • +
+

(this enum is a holdover from the old API and may be removed)

+

See also: al_get_joystick_stick_flags

+

al_install_joystick

+
bool al_install_joystick(void)
+

Source Code

+

Install a joystick driver, returning true if successful. If a joystick driver was already installed, returns true immediately.

+

See also: al_uninstall_joystick

+

Examples:

+ +

al_uninstall_joystick

+
void al_uninstall_joystick(void)
+

Source Code

+

Uninstalls the active joystick driver. All outstanding ALLEGRO_JOYSTICK structures are invalidated. If no joystick driver was active, this function does nothing.

+

This function is automatically called when Allegro is shut down.

+

See also: al_install_joystick

+

al_is_joystick_installed

+
bool al_is_joystick_installed(void)
+

Source Code

+

Returns true if al_install_joystick was called successfully.

+

al_reconfigure_joysticks

+
bool al_reconfigure_joysticks(void)
+

Source Code

+

Allegro is able to cope with users connecting and disconnected joystick devices on-the-fly. On existing platforms, the joystick event source will generate an event of type ALLEGRO_EVENT_JOYSTICK_CONFIGURATION when a device is plugged in or unplugged. In response, you should call al_reconfigure_joysticks.

+

Afterwards, the number returned by al_get_num_joysticks may be different, and the handles returned by al_get_joystick may be different or be ordered differently.

+

All ALLEGRO_JOYSTICK handles remain valid, but handles for disconnected devices become inactive: their states will no longer update, and al_get_joystick will not return the handle. Handles for devices which remain connected will continue to represent the same devices. Previously inactive handles may become active again, being reused to represent newly connected devices.

+

Returns true if the joystick configuration changed, otherwise returns false.

+

It is possible that on some systems, Allegro won’t be able to generate ALLEGRO_EVENT_JOYSTICK_CONFIGURATION events. If your game has an input configuration screen or similar, you may wish to call al_reconfigure_joysticks when entering that screen.

+

See also: al_get_joystick_event_source, ALLEGRO_EVENT

+

Examples:

+ +

al_get_num_joysticks

+
int al_get_num_joysticks(void)
+

Source Code

+

Return the number of joysticks currently on the system (or potentially on the system). This number can change after al_reconfigure_joysticks is called, in order to support hotplugging.

+

Returns 0 if there is no joystick driver installed.

+

See also: al_get_joystick, al_get_joystick_active

+

Examples:

+ +

al_get_joystick

+
ALLEGRO_JOYSTICK * al_get_joystick(int num)
+

Source Code

+

Get a handle for a joystick on the system. The number may be from 0 to al_get_num_joysticks-1. If successful a pointer to a joystick object is returned, which represents a physical device. Otherwise NULL is returned.

+

The handle and the index are only incidentally linked. After al_reconfigure_joysticks is called, al_get_joystick may return handles in a different order, and handles which represent disconnected devices will not be returned.

+

See also: al_get_num_joysticks, al_reconfigure_joysticks, al_get_joystick_active

+

Examples:

+ +

al_release_joystick

+
void al_release_joystick(ALLEGRO_JOYSTICK *joy)
+

Source Code

+

This function currently does nothing.

+

See also: al_get_joystick

+

Examples:

+ +

al_get_joystick_active

+
bool al_get_joystick_active(ALLEGRO_JOYSTICK *joy)
+

Source Code

+

Return if the joystick handle is “active”, i.e. in the current configuration, the handle represents some physical device plugged into the system. al_get_joystick returns active handles. After reconfiguration, active handles may become inactive, and vice versa.

+

See also: al_reconfigure_joysticks

+

Examples:

+ +

al_get_joystick_name

+
const char *al_get_joystick_name(ALLEGRO_JOYSTICK *joy)
+

Source Code

+

Return the name of the given joystick.

+

See also: al_get_joystick_stick_name, al_get_joystick_axis_name, al_get_joystick_button_name

+

Examples:

+ +

al_get_joystick_stick_name

+
const char *al_get_joystick_stick_name(ALLEGRO_JOYSTICK *joy, int stick)
+

Source Code

+

Return the name of the given “stick”. If the stick doesn’t exist, NULL is returned.

+

See also: al_get_joystick_axis_name, al_get_joystick_num_sticks

+

Examples:

+ +

al_get_joystick_axis_name

+
const char *al_get_joystick_axis_name(ALLEGRO_JOYSTICK *joy, int stick, int axis)
+

Source Code

+

Return the name of the given axis. If the axis doesn’t exist, NULL is returned. Indices begin from 0.

+

See also: al_get_joystick_stick_name, al_get_joystick_num_axes

+

Examples:

+ +

al_get_joystick_button_name

+
const char *al_get_joystick_button_name(ALLEGRO_JOYSTICK *joy, int button)
+

Source Code

+

Return the name of the given button. If the button doesn’t exist, NULL is returned. Indices begin from 0.

+

See also: al_get_joystick_stick_name, al_get_joystick_axis_name, al_get_joystick_num_buttons

+

Examples:

+ +

al_get_joystick_stick_flags

+
int al_get_joystick_stick_flags(ALLEGRO_JOYSTICK *joy, int stick)
+

Source Code

+

Return the flags of the given “stick”. If the stick doesn’t exist, NULL is returned. Indices begin from 0.

+

See also: ALLEGRO_JOYFLAGS

+

al_get_joystick_num_sticks

+
int al_get_joystick_num_sticks(ALLEGRO_JOYSTICK *joy)
+

Source Code

+

Return the number of “sticks” on the given joystick. A stick has one or more axes.

+

See also: al_get_joystick_num_axes, al_get_joystick_num_buttons

+

Examples:

+ +

al_get_joystick_num_axes

+
int al_get_joystick_num_axes(ALLEGRO_JOYSTICK *joy, int stick)
+

Source Code

+

Return the number of axes on the given “stick”. If the stick doesn’t exist, 0 is returned.

+

See also: al_get_joystick_num_sticks

+

Examples:

+ +

al_get_joystick_num_buttons

+
int al_get_joystick_num_buttons(ALLEGRO_JOYSTICK *joy)
+

Source Code

+

Return the number of buttons on the joystick.

+

See also: al_get_joystick_num_sticks

+

Examples:

+ +

al_get_joystick_state

+
void al_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state)
+

Source Code

+

Get the current joystick state.

+

See also: ALLEGRO_JOYSTICK_STATE, al_get_joystick_num_buttons, al_get_joystick_num_axes

+

Examples:

+ +

al_get_joystick_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_joystick_event_source(void)
+

Source Code

+

Returns the global joystick event source. All joystick events are generated by this event source.

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:40 UTC +

+
+ + diff --git a/allegro/docs/html/refman/keyboard.html b/allegro/docs/html/refman/keyboard.html new file mode 100644 index 00000000..ad1f3949 --- /dev/null +++ b/allegro/docs/html/refman/keyboard.html @@ -0,0 +1,398 @@ + + + + + + + Keyboard routines + + + + + + + + +
+ + +
+

Keyboard routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_KEYBOARD_STATE

+
typedef struct ALLEGRO_KEYBOARD_STATE ALLEGRO_KEYBOARD_STATE;
+

Source Code

+

This is a structure that is used to hold a “snapshot” of a keyboard’s state at a particular instant. It contains the following publically readable fields:

+
    +
  • display - points to the display that had keyboard focus at the time the state was saved. If no display was focused, this points to NULL.
  • +
+

You cannot read the state of keys directly. Use the function al_key_down.

+

Examples:

+ +

Key codes

+

The constant ALLEGRO_KEY_MAX is always one higher than the highest key code. So if you want to use the key code as array index you can do something like this:

+
bool pressed_keys[ALLEGRO_KEY_MAX];
+//...
+pressed_keys[key_code] = true;
+

These are the list of key codes used by Allegro, which are returned in the event.keyboard.keycode field of the ALLEGRO_KEY_DOWN and ALLEGRO_KEY_UP events and which you can pass to al_key_down:

+
ALLEGRO_KEY_A ... ALLEGRO_KEY_Z
+ALLEGRO_KEY_0 ... ALLEGRO_KEY_9
+ALLEGRO_KEY_PAD_0 ... ALLEGRO_KEY_PAD_9
+ALLEGRO_KEY_F1 ... ALLEGRO_KEY_F12
+ALLEGRO_KEY_ESCAPE
+ALLEGRO_KEY_TILDE
+ALLEGRO_KEY_MINUS
+ALLEGRO_KEY_EQUALS
+ALLEGRO_KEY_BACKSPACE
+ALLEGRO_KEY_TAB
+ALLEGRO_KEY_OPENBRACE
+ALLEGRO_KEY_CLOSEBRACE
+ALLEGRO_KEY_ENTER
+ALLEGRO_KEY_SEMICOLON
+ALLEGRO_KEY_QUOTE
+ALLEGRO_KEY_BACKSLASH
+ALLEGRO_KEY_BACKSLASH2
+ALLEGRO_KEY_COMMA
+ALLEGRO_KEY_FULLSTOP
+ALLEGRO_KEY_SLASH
+ALLEGRO_KEY_SPACE
+ALLEGRO_KEY_INSERT
+ALLEGRO_KEY_DELETE
+ALLEGRO_KEY_HOME
+ALLEGRO_KEY_END
+ALLEGRO_KEY_PGUP
+ALLEGRO_KEY_PGDN
+ALLEGRO_KEY_LEFT
+ALLEGRO_KEY_RIGHT
+ALLEGRO_KEY_UP
+ALLEGRO_KEY_DOWN
+ALLEGRO_KEY_PAD_SLASH
+ALLEGRO_KEY_PAD_ASTERISK
+ALLEGRO_KEY_PAD_MINUS
+ALLEGRO_KEY_PAD_PLUS
+ALLEGRO_KEY_PAD_DELETE
+ALLEGRO_KEY_PAD_ENTER
+ALLEGRO_KEY_PRINTSCREEN
+ALLEGRO_KEY_PAUSE
+ALLEGRO_KEY_ABNT_C1
+ALLEGRO_KEY_YEN
+ALLEGRO_KEY_KANA
+ALLEGRO_KEY_CONVERT
+ALLEGRO_KEY_NOCONVERT
+ALLEGRO_KEY_AT
+ALLEGRO_KEY_CIRCUMFLEX
+ALLEGRO_KEY_COLON2
+ALLEGRO_KEY_KANJI
+ALLEGRO_KEY_LSHIFT
+ALLEGRO_KEY_RSHIFT
+ALLEGRO_KEY_LCTRL
+ALLEGRO_KEY_RCTRL
+ALLEGRO_KEY_ALT
+ALLEGRO_KEY_ALTGR
+ALLEGRO_KEY_LWIN
+ALLEGRO_KEY_RWIN
+ALLEGRO_KEY_MENU
+ALLEGRO_KEY_SCROLLLOCK
+ALLEGRO_KEY_NUMLOCK
+ALLEGRO_KEY_CAPSLOCK
+ALLEGRO_KEY_PAD_EQUALS
+ALLEGRO_KEY_BACKQUOTE
+ALLEGRO_KEY_SEMICOLON2
+ALLEGRO_KEY_COMMAND
+
+/* Since: 5.1.1 */
+/* Android only for now */
+ALLEGRO_KEY_BACK
+
+/* Since: 5.1.2 */
+/* Android only for now */
+ALLEGRO_KEY_VOLUME_UP
+ALLEGRO_KEY_VOLUME_DOWN
+
+/* Since: 5.1.6 */
+/* Android only for now */
+ALLEGRO_KEY_SEARCH
+ALLEGRO_KEY_DPAD_CENTER
+ALLEGRO_KEY_BUTTON_X
+ALLEGRO_KEY_BUTTON_Y
+ALLEGRO_KEY_DPAD_UP
+ALLEGRO_KEY_DPAD_DOWN
+ALLEGRO_KEY_DPAD_LEFT
+ALLEGRO_KEY_DPAD_RIGHT
+ALLEGRO_KEY_SELECT
+ALLEGRO_KEY_START
+ALLEGRO_KEY_L1
+ALLEGRO_KEY_R1
+

Keyboard modifier flags

+
ALLEGRO_KEYMOD_SHIFT
+ALLEGRO_KEYMOD_CTRL
+ALLEGRO_KEYMOD_ALT
+ALLEGRO_KEYMOD_LWIN
+ALLEGRO_KEYMOD_RWIN
+ALLEGRO_KEYMOD_MENU
+ALLEGRO_KEYMOD_ALTGR
+ALLEGRO_KEYMOD_COMMAND
+ALLEGRO_KEYMOD_SCROLLLOCK
+ALLEGRO_KEYMOD_NUMLOCK
+ALLEGRO_KEYMOD_CAPSLOCK
+ALLEGRO_KEYMOD_INALTSEQ
+ALLEGRO_KEYMOD_ACCENT1
+ALLEGRO_KEYMOD_ACCENT2
+ALLEGRO_KEYMOD_ACCENT3
+ALLEGRO_KEYMOD_ACCENT4
+

The event field ‘keyboard.modifiers’ is a bitfield composed of these constants. These indicate the modifier keys which were pressed at the time a character was typed.

+

al_install_keyboard

+
bool al_install_keyboard(void)
+

Source Code

+

Install a keyboard driver. Returns true if successful. If a driver was already installed, nothing happens and true is returned.

+

See also: al_uninstall_keyboard, al_is_keyboard_installed

+

Examples:

+ +

al_is_keyboard_installed

+
bool al_is_keyboard_installed(void)
+

Source Code

+

Returns true if al_install_keyboard was called successfully.

+

al_uninstall_keyboard

+
void al_uninstall_keyboard(void)
+

Source Code

+

Uninstalls the active keyboard driver, if any. This will automatically unregister the keyboard event source with any event queues.

+

This function is automatically called when Allegro is shut down.

+

See also: al_install_keyboard

+

al_get_keyboard_state

+
void al_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state)
+

Source Code

+

Save the state of the keyboard specified at the time the function is called into the structure pointed to by ret_state.

+

See also: al_key_down, al_clear_keyboard_state, ALLEGRO_KEYBOARD_STATE

+

Examples:

+ +

al_clear_keyboard_state

+
void al_clear_keyboard_state(ALLEGRO_DISPLAY *display)
+

Source Code

+

Clear the state of the keyboard, emitting ALLEGRO_EVENT_KEY_UP for each currently pressed key. The given display is regarded as the one which had the keyboard focus when the event occurred. In case display is NULL no event is emitted. For most keyboard drivers Allegro maintains its own state of the keyboard, which might get out of sync with the real one. This function is intended to remedy such situation by resetting Allegro’s keyboard state to a known default (no key pressed). This is particularly useful in response to ALLEGRO_EVENT_DISPLAY_SWITCH_OUT events.

+

See also: al_get_keyboard_state, ALLEGRO_KEYBOARD_STATE

+

Since: 5.2.3

+
+

Unstable API: This is a new feature and the exact semantics are still being decided upon.

+
+

Examples:

+ +

al_key_down

+
bool al_key_down(const ALLEGRO_KEYBOARD_STATE *state, int keycode)
+

Source Code

+

Return true if the key specified was held down in the state specified.

+

See also: ALLEGRO_KEYBOARD_STATE

+

Examples:

+ +

al_keycode_to_name

+
const char *al_keycode_to_name(int keycode)
+

Source Code

+

Converts the given keycode to a description of the key.

+

Examples:

+ +

al_set_keyboard_leds

+
bool al_set_keyboard_leds(int leds)
+

Source Code

+

Overrides the state of the keyboard LED indicators. Set leds to a combination of the keyboard modifier flags to enable the corresponding LED indicators (ALLEGRO_KEYMOD_NUMLOCK, ALLEGRO_KEYMOD_CAPSLOCK and ALLEGRO_KEYMOD_SCROLLLOCK are supported) or to -1 to return to default behavior. False is returned if the current keyboard driver cannot set LED indicators.

+

al_get_keyboard_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_keyboard_event_source(void)
+

Source Code

+

Retrieve the keyboard event source. All keyboard events are generated by this event source.

+

Returns NULL if the keyboard subsystem was not installed.

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:41 UTC +

+
+ + diff --git a/allegro/docs/html/refman/main.html b/allegro/docs/html/refman/main.html new file mode 100644 index 00000000..a8a48158 --- /dev/null +++ b/allegro/docs/html/refman/main.html @@ -0,0 +1,181 @@ + + + + + + + Main addon + + + + + + + + +
+ + +
+

Main addon

+
+

The main addon has no public API, but contains functionality to enable programs using Allegro to build and run without platform-specific changes.

+

On platforms that require this functionality (e.g. OSX) this addon contains a C main function that invokes al_run_main with the user’s own main function, where the user’s main function has had its name mangled to something else. The file that defines the user main function must include the header file allegro5/allegro.h; that header performs the name mangling using some macros.

+

If the user main function is defined in C++, then it must have the following signature for this addon to work:

+
int main(int argc, char **argv)
+

This addon does nothing on platforms that don’t require its functionality, but you should keep it in mind in case you need to port to platforms that do require it.

+

Link with allegro_main.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:43 UTC +

+
+ + diff --git a/allegro/docs/html/refman/memfile.html b/allegro/docs/html/refman/memfile.html new file mode 100644 index 00000000..24eb0f23 --- /dev/null +++ b/allegro/docs/html/refman/memfile.html @@ -0,0 +1,198 @@ + + + + + + + Memfile interface + + + + + + + + +
+ + +
+

Memfile interface

+
+ +

The memfile interface allows you to treat a fixed block of contiguous memory as a file that can be used with Allegro’s I/O functions.

+

These functions are declared in the following header file. Link with allegro_memfile.

+
 #include <allegro5/allegro_memfile.h>
+

al_open_memfile

+
ALLEGRO_FILE *al_open_memfile(void *mem, int64_t size, const char *mode)
+

Source Code

+

Returns a file handle to the block of memory. All read and write operations act upon the memory directly, so it must not be freed while the file remains open.

+

The mode can be any combination of “r” (readable) and “w” (writable). Regardless of the mode, the file always opens at position 0. The file size is fixed and cannot be expanded. The file is always read from/written to in binary mode, which means that no newline translation is performed.

+

It should be closed with al_fclose. After the file is closed, you are responsible for freeing the memory (if needed).

+

Examples:

+ +

al_get_allegro_memfile_version

+
uint32_t al_get_allegro_memfile_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:43 UTC +

+
+ + diff --git a/allegro/docs/html/refman/memory.html b/allegro/docs/html/refman/memory.html new file mode 100644 index 00000000..36d671a9 --- /dev/null +++ b/allegro/docs/html/refman/memory.html @@ -0,0 +1,276 @@ + + + + + + + Memory management routines + + + + + + + + +
+ + +
+

Memory management routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

al_malloc

+
#define al_malloc(n) \
+   (al_malloc_with_context((n), __LINE__, __FILE__, __func__))
+

Source Code

+

Like malloc() in the C standard library, but the implementation may be overridden.

+

This is a macro.

+

See also: al_free, al_realloc, al_calloc, al_malloc_with_context, al_set_memory_interface

+

Examples:

+ +

al_free

+
#define al_free(p) \
+   (al_free_with_context((p), __LINE__, __FILE__, __func__))
+

Source Code

+

Like free() in the C standard library, but the implementation may be overridden.

+

Additionally, on Windows, a memory block allocated by one DLL must be freed from the same DLL. In the few places where an Allegro function returns a pointer that must be freed, you must use al_free for portability to Windows.

+

This is a macro.

+

See also: al_malloc, al_free_with_context

+

Examples:

+ +

al_realloc

+
#define al_realloc(p, n) \
+   (al_realloc_with_context((p), (n), __LINE__, __FILE__, __func__))
+

Source Code

+

Like realloc() in the C standard library, but the implementation may be overridden.

+

This is a macro.

+

See also: al_malloc, al_realloc_with_context

+

al_calloc

+
#define al_calloc(c, n) \
+   (al_calloc_with_context((c), (n), __LINE__, __FILE__, __func__))
+

Source Code

+

Like calloc() in the C standard library, but the implementation may be overridden.

+

This is a macro.

+

See also: al_malloc, al_calloc_with_context

+

Examples:

+ +

al_malloc_with_context

+
void *al_malloc_with_context(size_t n,
+   int line, const char *file, const char *func)
+

Source Code

+

This calls malloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface,

+

Generally you should use the al_malloc macro.

+

al_free_with_context

+
void al_free_with_context(void *ptr,
+   int line, const char *file, const char *func)
+

Source Code

+

This calls free() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface.

+

Generally you should use the al_free macro.

+

al_realloc_with_context

+
void *al_realloc_with_context(void *ptr, size_t n,
+   int line, const char *file, const char *func)
+

Source Code

+

This calls realloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface,

+

Generally you should use the al_realloc macro.

+

al_calloc_with_context

+
void *al_calloc_with_context(size_t count, size_t n,
+   int line, const char *file, const char *func)
+

Source Code

+

This calls calloc() from the Allegro library (this matters on Windows), unless overridden with al_set_memory_interface,

+

Generally you should use the al_calloc macro.

+

ALLEGRO_MEMORY_INTERFACE

+
typedef struct ALLEGRO_MEMORY_INTERFACE ALLEGRO_MEMORY_INTERFACE;
+

Source Code

+

This structure has the following fields.

+
void *(*mi_malloc)(size_t n, int line, const char *file, const char *func);
+void (*mi_free)(void *ptr, int line, const char *file, const char *func);
+void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file,
+                    const char *func);
+void *(*mi_calloc)(size_t count, size_t n, int line, const char *file,
+                   const char *func);
+

See also: al_set_memory_interface

+

al_set_memory_interface

+
void al_set_memory_interface(ALLEGRO_MEMORY_INTERFACE *memory_interface)
+

Source Code

+

Override the memory management functions with implementations of al_malloc_with_context, al_free_with_context, al_realloc_with_context and al_calloc_with_context. The context arguments may be used for debugging. The new functions should be thread safe.

+

If the pointer is NULL, the default behaviour will be restored.

+

See also: ALLEGRO_MEMORY_INTERFACE

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:41 UTC +

+
+ + diff --git a/allegro/docs/html/refman/misc.html b/allegro/docs/html/refman/misc.html new file mode 100644 index 00000000..dcae8fb0 --- /dev/null +++ b/allegro/docs/html/refman/misc.html @@ -0,0 +1,198 @@ + + + + + + + Miscellaneous routines + + + + + + + + +
+ + +
+

Miscellaneous routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_PI

+
#define ALLEGRO_PI        3.14159265358979323846
+

Source Code

+

C99 compilers have no predefined value like M_PI for the constant π, but you can use this one instead.

+

Examples:

+ +

al_run_main

+
int al_run_main(int argc, char **argv, int (*user_main)(int, char **))
+

Source Code

+

This function is useful in cases where you don’t have a main() function but want to run Allegro (mostly useful in a wrapper library). Under Windows and Linux this is no problem because you simply can call al_install_system. But some other system (like OSX) don’t allow calling al_install_system in the main thread. al_run_main will know what to do in that case.

+

The passed argc and argv will simply be passed on to user_main and the return value of user_main will be returned.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:41 UTC +

+
+ + diff --git a/allegro/docs/html/refman/monitor.html b/allegro/docs/html/refman/monitor.html new file mode 100644 index 00000000..eeb84c77 --- /dev/null +++ b/allegro/docs/html/refman/monitor.html @@ -0,0 +1,267 @@ + + + + + + + Monitors + + + + + + + + +
+ + +
+

Monitors

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_MONITOR_INFO

+
typedef struct ALLEGRO_MONITOR_INFO
+

Source Code

+

Describes a monitor’s size and position relative to other monitors. x1, y1 will be 0, 0 on the primary display. Other monitors can have negative values if they are to the left or above the primary display. x2, y2 are the coordinates one beyond the bottom right pixel, so that x2-x1 gives the width and y2-y1 gives the height of the display.

+
typedef struct ALLEGRO_MONITOR_INFO
+{
+   int x1;
+   int y1;
+   int x2;
+   int y2;
+} ALLEGRO_MONITOR_INFO;
+

See also: al_get_monitor_info

+

Examples:

+ +

al_get_new_display_adapter

+
int al_get_new_display_adapter(void)
+

Source Code

+

Gets the video adapter index where new displays will be created by the calling thread, if previously set with al_set_new_display_adapter. Otherwise returns ALLEGRO_DEFAULT_DISPLAY_ADAPTER.

+

See also: al_set_new_display_adapter

+

al_set_new_display_adapter

+
void al_set_new_display_adapter(int adapter)
+

Source Code

+

Sets the adapter to use for new displays created by the calling thread. The adapter has a monitor attached to it. Information about the monitor can be gotten using al_get_num_video_adapters and al_get_monitor_info.

+

To return to the default behaviour, pass ALLEGRO_DEFAULT_DISPLAY_ADAPTER.

+

See also: al_get_num_video_adapters, al_get_monitor_info

+

Examples:

+ +

al_get_monitor_info

+
bool al_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info)
+

Source Code

+

Get information about a monitor’s position on the desktop. adapter is a number from 0 to al_get_num_video_adapters()-1.

+

On Windows, use al_set_new_display_flags to switch between Direct3D and OpenGL backends, which will often have different adapters available.

+

Returns true on success, false on failure.

+

See also: ALLEGRO_MONITOR_INFO, al_get_num_video_adapters

+

Examples:

+ +

al_get_monitor_dpi

+
int al_get_monitor_dpi(int adapter)
+

Source Code

+

Get the dots per inch of a monitor attached to the display adapter.

+

Since: 5.2.5

+

See also: al_get_num_video_adapters

+

Examples:

+ +

al_get_num_video_adapters

+
int al_get_num_video_adapters(void)
+

Source Code

+

Get the number of video “adapters” attached to the computer. Each video card attached to the computer counts as one or more adapters. An adapter is thus really a video port that can have a monitor connected to it.

+

On Windows, use al_set_new_display_flags to switch between Direct3D and OpenGL backends, which will often have different adapters available.

+

See also: al_get_monitor_info

+

Examples:

+ +

al_get_monitor_refresh_rate

+
int al_get_monitor_refresh_rate(int adapter)
+

Source Code

+

Returns the current refresh rate of a monitor attached to the display adapter.

+

Since: 5.2.6

+
+

Unstable API: This is an experimental feature and currently only works on Windows.

+
+

See also: al_get_monitor_info

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:41 UTC +

+
+ + diff --git a/allegro/docs/html/refman/mouse.html b/allegro/docs/html/refman/mouse.html new file mode 100644 index 00000000..ac870a01 --- /dev/null +++ b/allegro/docs/html/refman/mouse.html @@ -0,0 +1,487 @@ + + + + + + + Mouse routines + + + + + + + + +
+ + +
+

Mouse routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_MOUSE_STATE

+
typedef struct ALLEGRO_MOUSE_STATE ALLEGRO_MOUSE_STATE;
+

Source Code

+

Public fields (read only):

+
    +
  • x - mouse x position

  • +
  • y - mouse y position

  • +
  • w, z - mouse wheel position (2D ‘ball’)

  • +
  • buttons - mouse buttons bitfield

    +

    The zeroth bit is set if the primary mouse button is held down, the first bit is set if the secondary mouse button is held down, and so on.

  • +
  • pressure - pressure, ranging from 0.0 to 1.0

  • +
+

See also: al_get_mouse_state, al_get_mouse_state_axis, al_mouse_button_down

+

Examples:

+ +

al_install_mouse

+
bool al_install_mouse(void)
+

Source Code

+

Install a mouse driver.

+

Returns true if successful. If a driver was already installed, nothing happens and true is returned.

+

Examples:

+ +

al_is_mouse_installed

+
bool al_is_mouse_installed(void)
+

Source Code

+

Returns true if al_install_mouse was called successfully.

+

al_uninstall_mouse

+
void al_uninstall_mouse(void)
+

Source Code

+

Uninstalls the active mouse driver, if any. This will automatically unregister the mouse event source with any event queues.

+

This function is automatically called when Allegro is shut down.

+

al_get_mouse_num_axes

+
unsigned int al_get_mouse_num_axes(void)
+

Source Code

+

Return the number of axes on the mouse. The first axis is 0.

+

See also: al_get_mouse_num_buttons

+

al_get_mouse_num_buttons

+
unsigned int al_get_mouse_num_buttons(void)
+

Source Code

+

Return the number of buttons on the mouse. The first button is 1.

+

See also: al_get_mouse_num_axes

+

Examples:

+ +

al_get_mouse_state

+
void al_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state)
+

Source Code

+

Save the state of the mouse specified at the time the function is called into the given structure.

+

Example:

+
ALLEGRO_MOUSE_STATE state;
+
+al_get_mouse_state(&state);
+if (state.buttons & 1) {
+    /* Primary (e.g. left) mouse button is held. */
+    printf("Mouse position: (%d, %d)\n", state.x, state.y);
+}
+if (state.buttons & 2) {
+    /* Secondary (e.g. right) mouse button is held. */
+}
+if (state.buttons & 4) {
+    /* Tertiary (e.g. middle) mouse button is held. */
+}
+

See also: ALLEGRO_MOUSE_STATE, al_get_mouse_state_axis, al_mouse_button_down

+

Examples:

+ +

al_get_mouse_state_axis

+
int al_get_mouse_state_axis(const ALLEGRO_MOUSE_STATE *state, int axis)
+

Source Code

+

Extract the mouse axis value from the saved state. The axes are numbered from 0, in this order: x-axis, y-axis, z-axis, w-axis.

+

See also: ALLEGRO_MOUSE_STATE, al_get_mouse_state, al_mouse_button_down

+

al_mouse_button_down

+
bool al_mouse_button_down(const ALLEGRO_MOUSE_STATE *state, int button)
+

Source Code

+

Return true if the mouse button specified was held down in the state specified. Unlike most things, the first mouse button is numbered 1.

+

See also: ALLEGRO_MOUSE_STATE, al_get_mouse_state, al_get_mouse_state_axis

+

Examples:

+ +

al_set_mouse_xy

+
bool al_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y)
+

Source Code

+

Try to position the mouse at the given coordinates on the given display. The mouse movement resulting from a successful move will generate an ALLEGRO_EVENT_MOUSE_WARPED event.

+

Returns true on success, false on failure.

+

See also: al_set_mouse_z, al_set_mouse_w

+

Examples:

+ +

al_set_mouse_z

+
bool al_set_mouse_z(int z)
+

Source Code

+

Set the mouse wheel position to the given value.

+

Returns true on success, false on failure.

+

See also: al_set_mouse_w

+

al_set_mouse_w

+
bool al_set_mouse_w(int w)
+

Source Code

+

Set the second mouse wheel position to the given value.

+

Returns true on success, false on failure.

+

See also: al_set_mouse_z

+

Examples:

+ +

al_set_mouse_axis

+
bool al_set_mouse_axis(int which, int value)
+

Source Code

+

Set the given mouse axis to the given value.

+

The axis number must not be 0 or 1, which are the X and Y axes. Use al_set_mouse_xy for that.

+

Returns true on success, false on failure.

+

See also: al_set_mouse_xy, al_set_mouse_z, al_set_mouse_w

+

al_get_mouse_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_mouse_event_source(void)
+

Source Code

+

Retrieve the mouse event source. All mouse events are generated by this event source.

+

Returns NULL if the mouse subsystem was not installed.

+

Examples:

+ +

al_set_mouse_wheel_precision

+
void al_set_mouse_wheel_precision(int precision)
+

Source Code

+

Sets the precision of the mouse wheel (the z and w coordinates). This precision manifests itself as a multiplier on the dz and dw fields in mouse events. It also affects the z and w fields of events and ALLEGRO_MOUSE_STATE, but not in a simple way if you alter the precision often, so it is suggested to reset those axes to 0 when you change precision. Setting this to a high value allows you to detect small changes in those two axes for some high precision mice. A flexible way of using this precision is to set it to a high value (120 is likely sufficient for most, if not all, mice) and use a floating point dz and dw like so:

+
al_set_mouse_wheel_precision(120);
+
+ALLEGRO_EVENT event;
+al_wait_for_event(event_queue, &event);
+if (event.type == ALLEGRO_EVENT_MOUSE_AXES) {
+  double dz = (double)event.mouse.dz / al_get_mouse_wheel_precision();
+  /* Use dz in some way... */
+}
+

Precision is set to 1 by default. It is impossible to set it to a lower precision than that.

+

Since: 5.1.10

+

See also: al_get_mouse_wheel_precision

+

Examples:

+ +

al_get_mouse_wheel_precision

+
int al_get_mouse_wheel_precision(void)
+

Source Code

+

Gets the precision of the mouse wheel (the z and w coordinates).

+

Since: 5.1.10

+

See also: al_set_mouse_wheel_precision

+

Mouse cursors

+

al_create_mouse_cursor

+
ALLEGRO_MOUSE_CURSOR *al_create_mouse_cursor(ALLEGRO_BITMAP *bmp,
+   int x_focus, int y_focus)
+

Source Code

+

Create a mouse cursor from the bitmap provided. x_focus and y_focus describe the bit of the cursor that will represent the actual mouse position.

+

Returns a pointer to the cursor on success, or NULL on failure.

+

See also: al_set_mouse_cursor, al_destroy_mouse_cursor

+

Examples:

+ +

al_destroy_mouse_cursor

+
void al_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor)
+

Source Code

+

Free the memory used by the given cursor.

+

Has no effect if cursor is NULL.

+

See also: al_create_mouse_cursor

+

Examples:

+ +

al_set_mouse_cursor

+
bool al_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor)
+

Source Code

+

Set the given mouse cursor to be the current mouse cursor for the given display.

+

If the cursor is currently ‘shown’ (as opposed to ‘hidden’) the change is immediately visible.

+

Returns true on success, false on failure.

+

See also: al_set_system_mouse_cursor, al_show_mouse_cursor, al_hide_mouse_cursor

+

Examples:

+ +

al_set_system_mouse_cursor

+
bool al_set_system_mouse_cursor(ALLEGRO_DISPLAY *display,
+   ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id)
+

Source Code

+

Set the given system mouse cursor to be the current mouse cursor for the given display. If the cursor is currently ‘shown’ (as opposed to ‘hidden’) the change is immediately visible.

+

If the cursor doesn’t exist on the current platform another cursor will be silently be substituted.

+

The cursors are:

+
    +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT
  • +
  • ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE
  • +
+

Returns true on success, false on failure.

+

See also: al_set_mouse_cursor, al_show_mouse_cursor, al_hide_mouse_cursor

+

Examples:

+ +

al_get_mouse_cursor_position

+
bool al_get_mouse_cursor_position(int *ret_x, int *ret_y)
+

Source Code

+

On platforms where this information is available, this function returns the global location of the mouse cursor, relative to the desktop. You should not normally use this function, as the information is not useful except for special scenarios as moving a window.

+

Returns true on success, false on failure.

+

Examples:

+ +

al_hide_mouse_cursor

+
bool al_hide_mouse_cursor(ALLEGRO_DISPLAY *display)
+

Source Code

+

Hide the mouse cursor in the given display. This has no effect on what the current mouse cursor looks like; it just makes it disappear.

+

Returns true on success (or if the cursor already was hidden), false otherwise.

+

See also: al_show_mouse_cursor

+

Examples:

+ +

al_show_mouse_cursor

+
bool al_show_mouse_cursor(ALLEGRO_DISPLAY *display)
+

Source Code

+

Make a mouse cursor visible in the given display.

+

Returns true if a mouse cursor is shown as a result of the call (or one already was visible), false otherwise.

+

See also: al_hide_mouse_cursor

+

Examples:

+ +

al_grab_mouse

+
bool al_grab_mouse(ALLEGRO_DISPLAY *display)
+

Source Code

+

Confine the mouse cursor to the given display. The mouse cursor can only be confined to one display at a time.

+

Returns true if successful, otherwise returns false. Do not assume that the cursor will remain confined until you call al_ungrab_mouse. It may lose the confined status at any time for other reasons.

+
+

Note: not yet implemented on Mac OS X.

+
+

See also: al_ungrab_mouse

+

al_ungrab_mouse

+
bool al_ungrab_mouse(void)
+

Source Code

+

Stop confining the mouse cursor to any display belonging to the program.

+
+

Note: not yet implemented on Mac OS X.

+
+

See also: al_grab_mouse

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:41 UTC +

+
+ + diff --git a/allegro/docs/html/refman/native_dialog.html b/allegro/docs/html/refman/native_dialog.html new file mode 100644 index 00000000..954bdcaa --- /dev/null +++ b/allegro/docs/html/refman/native_dialog.html @@ -0,0 +1,800 @@ + + + + + + + Native dialogs support + + + + + + + + +
+ + +
+

Native dialogs support

+
+ +

These functions are declared in the following header file. Link with allegro_dialog.

+
 #include <allegro5/allegro_native_dialog.h>
+

ALLEGRO_FILECHOOSER

+
typedef struct ALLEGRO_FILECHOOSER ALLEGRO_FILECHOOSER;
+

Source Code

+

Opaque handle to a native file dialog.

+

Examples:

+ +

ALLEGRO_TEXTLOG

+
typedef struct ALLEGRO_TEXTLOG ALLEGRO_TEXTLOG;
+

Source Code

+

Opaque handle to a text log window.

+

Examples:

+ +

al_init_native_dialog_addon

+
bool al_init_native_dialog_addon(void)
+

Source Code

+

Initialise the native dialog addon.

+

Returns true on success, false on error.

+

Since: 5.0.9, 5.1.0

+
+

Note: Prior to Allegro 5.1.0 native dialog functions could be called without explicit initialisation, but that is now deprecated. Future functionality may require explicit initialisation. An exception is al_show_native_message_box, which may be useful to show an error message if Allegro fails to initialise.

+
+

See also: al_shutdown_native_dialog_addon

+

Examples:

+ +

al_is_native_dialog_addon_initialized

+
bool al_is_native_dialog_addon_initialized(void)
+

Source Code

+

Returns true if the native dialog addon is initialized, otherwise returns false.

+

Since: 5.2.6

+

al_shutdown_native_dialog_addon

+
void al_shutdown_native_dialog_addon(void)
+

Source Code

+

Shut down the native dialog addon.

+

Since: 5.0.9, 5.1.5

+

See also: al_init_native_dialog_addon

+

al_create_native_file_dialog

+
ALLEGRO_FILECHOOSER *al_create_native_file_dialog(
+   char const *initial_path,
+   char const *title,
+   char const *patterns,
+   int mode)
+

Source Code

+

Creates a new native file dialog. You should only have one such dialog opened at a time.

+

Parameters:

+
    +
  • initial_path: The initial search path and filename. Can be NULL. To start with a blank file name the string should end with a directory separator (this should be the common case).

  • +
  • title: Title of the dialog.

  • +
  • patterns: A list of semi-colon separated patterns to match. This should not contain any whitespace characters. If a pattern contains the ‘/’ character, then it is treated as a MIME type (e.g. ‘image/png’). Not all platforms support file patterns. If the native dialog does not provide support, this parameter is ignored.

  • +
  • mode: 0, or a combination of the following flags:

  • +
+
+
ALLEGRO_FILECHOOSER_FILE_MUST_EXIST
+
If supported by the native dialog, it will not allow entering new names, but just allow existing files to be selected. Else it is ignored. +
+
ALLEGRO_FILECHOOSER_SAVE
+
If the native dialog system has a different dialog for saving (for example one which allows creating new directories), it is used. Else it is ignored. +
+
ALLEGRO_FILECHOOSER_FOLDER
+
If there is support for a separate dialog to select a folder instead of a file, it will be used. +
+
ALLEGRO_FILECHOOSER_PICTURES
+
If a different dialog is available for selecting pictures, it is used. Else it is ignored. +
+
ALLEGRO_FILECHOOSER_SHOW_HIDDEN
+
If the platform supports it, also hidden files will be shown. +
+
ALLEGRO_FILECHOOSER_MULTIPLE
+
If supported, allow selecting multiple files. +
+
+

Returns:

+

A handle to the dialog which you can pass to al_show_native_file_dialog to display it, and from which you then can query the results using al_get_native_file_dialog_count and al_get_native_file_dialog_path. When you are done, call al_destroy_native_file_dialog on it.

+

If a dialog window could not be created then this function returns NULL.

+

Examples:

+ +

al_show_native_file_dialog

+
bool al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
+   ALLEGRO_FILECHOOSER *dialog)
+

Source Code

+

Show the dialog window. The display may be NULL, otherwise the given display is treated as the parent if possible.

+

This function blocks the calling thread until it returns, so you may want to spawn a thread with al_create_thread and call it from inside that thread.

+

Returns true on success, false on failure.

+

Examples:

+ +

al_get_native_file_dialog_count

+
int al_get_native_file_dialog_count(const ALLEGRO_FILECHOOSER *dialog)
+

Source Code

+

Returns the number of files selected, or 0 if the dialog was cancelled.

+

Examples:

+ +

al_get_native_file_dialog_path

+
const char *al_get_native_file_dialog_path(
+   const ALLEGRO_FILECHOOSER *dialog, size_t i)
+

Source Code

+

Returns one of the selected paths with index i. The index should range from 0 to the return value of al_get_native_file_dialog_count -1.

+

Examples:

+ +

al_destroy_native_file_dialog

+
void al_destroy_native_file_dialog(ALLEGRO_FILECHOOSER *dialog)
+

Source Code

+

Frees up all resources used by the file dialog.

+

Examples:

+ +

al_show_native_message_box

+
int al_show_native_message_box(ALLEGRO_DISPLAY *display,
+   char const *title, char const *heading, char const *text,
+   char const *buttons, int flags)
+

Source Code

+

Show a native GUI message box. This can be used for example to display an error message if creation of an initial display fails. The display may be NULL, otherwise the given display is treated as the parent if possible.

+

The message box will have a single “OK” button and use the style informative dialog boxes usually have on the native system. If the buttons parameter is not NULL, you can instead specify the button text in a string, with buttons separated by a vertical bar (|).

+
+

Note: buttons parameter is currently unimplemented on Windows.

+
+

The flags available are:

+
+
ALLEGRO_MESSAGEBOX_WARN
+
The message is a warning. This may cause a different icon (or other effects). +
+
ALLEGRO_MESSAGEBOX_ERROR
+
The message is an error. +
+
ALLEGRO_MESSAGEBOX_QUESTION
+
The message is a question. +
+
ALLEGRO_MESSAGEBOX_OK_CANCEL
+
Display a cancel button alongside the “OK” button. Ignored if buttons is not NULL. +
+
ALLEGRO_MESSAGEBOX_YES_NO
+
Display Yes/No buttons instead of the “OK” button. Ignored if buttons is not NULL. +
+
+

al_show_native_message_box may be called without Allegro being installed. This is useful to report an error during initialisation of Allegro itself.

+

Returns:

+
    +
  • 0 if the dialog window was closed without activating a button.
  • +
  • 1 if the OK or Yes button was pressed.
  • +
  • 2 if the Cancel or No button was pressed.
  • +
+

If buttons is not NULL, the number of the pressed button is returned, starting with 1.

+

All of the remaining parameters must not be NULL.

+

If a message box could not be created then this returns 0, as if the window was dismissed without activating a button.

+

Example:

+
int button = al_show_native_message_box(
+  display,
+  "Warning",
+  "Are you sure?",
+  "If you click yes then you are confirming that \"Yes\" "
+  "is your response to the query which you have "
+  "generated by the action you took to open this "
+  "message box.",
+  NULL,
+  ALLEGRO_MESSAGEBOX_YES_NO
+);
+

Examples:

+ +

al_open_native_text_log

+
ALLEGRO_TEXTLOG *al_open_native_text_log(char const *title, int flags)
+

Source Code

+

Opens a window to which you can append log messages with al_append_native_text_log. This can be useful for debugging if you don’t want to depend on a console being available.

+

Use al_close_native_text_log to close the window again.

+

The flags available are:

+
+
ALLEGRO_TEXTLOG_NO_CLOSE
+
Prevent the window from having a close button. Otherwise, if the close button is pressed, an event is generated; see al_get_native_text_log_event_source. +
+
ALLEGRO_TEXTLOG_MONOSPACE
+
Use a monospace font to display the text. +
+
+

Returns NULL if there was an error opening the window, or if text log windows are not implemented on the platform.

+

See also: al_append_native_text_log, al_close_native_text_log

+

Examples:

+ +

al_close_native_text_log

+
void al_close_native_text_log(ALLEGRO_TEXTLOG *textlog)
+

Source Code

+

Closes a message log window opened with al_open_native_text_log earlier.

+

Does nothing if passed NULL.

+

See also: al_open_native_text_log

+

Examples:

+ +

al_append_native_text_log

+
void al_append_native_text_log(ALLEGRO_TEXTLOG *textlog,
+   char const *format, ...)
+

Source Code

+

Appends a line of text to the message log window and scrolls to the bottom (if the line would not be visible otherwise). This works like printf. A line is continued until you add a newline character.

+

If the window is NULL then this function will fall back to calling printf. This makes it convenient to support logging to a window or a terminal.

+

Examples:

+ +

al_get_native_text_log_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_native_text_log_event_source(
+   ALLEGRO_TEXTLOG *textlog)
+

Source Code

+

Get an event source for a text log window. The possible events are:

+
+
ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE
+
The window was requested to be closed, either by pressing the close button or pressing Escape on the keyboard. The user.data1 field will hold a pointer to the ALLEGRO_TEXTLOG which generated the event. The user.data2 field will be 1 if the event was generated as a result of a key press; otherwise it will be zero. +
+
+

Examples:

+ +

al_get_allegro_native_dialog_version

+
uint32_t al_get_allegro_native_dialog_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

Menus

+

Menus are implemented on Windows, X and OS X. Menus on X are implemented with GTK, and have a special requirement: you must set the ALLEGRO_GTK_TOPLEVEL display flag prior to creating the display which will have menus attached.

+

A menu can be attached to a single display window or popped up as a context menu. If you wish to use the same menu on multiple displays or use a sub-menu as a context menu, you must make a copy via al_clone_menu or al_clone_menu_for_popup.

+

Top level items in a non-popup menu must have at least one sub-item, or the behavior is undefined.

+

Each menu item can be given an ID of any 16-bit integer greater than zero. When a user clicks on a menu item, an event will be generated only if it has an ID. This ID should be unique per menu; if you duplicate IDs, then there will be no way for you to determine exactly which item generated the event.

+

There are many functions that take pos as a parameter used for locating a particular menu item. In those cases, it represents one of two things: an ID or a zero-based index. Any value greater than zero will always be treated as an ID. Anything else (including zero) will be considered an index based on the absolute value. In other words, 0 is the first menu item, -1 is the second menu item, -2 is the third menu item, and so on.

+

The event type is ALLEGRO_EVENT_MENU_CLICK. It contains three fields:

+
event.user.data1 = id;
+event.user.data2 = (intptr_t) display;
+event.user.data3 = (intptr_t) menu;
+

The display and menu may be NULL if it was not possible to tell exactly which item generated the event.

+

A basic example:

+
 #define FILE_EXIT_ID 1
+
+ALLEGRO_MENU *menu = al_create_menu();
+ALLEGRO_MENU *file_menu = al_create_menu();
+al_append_menu_item(file_menu, "Exit", FILE_EXIT_ID, 0, NULL, NULL);
+al_append_menu_item(menu, "File", 0, 0, NULL, file_menu);
+al_set_display_menu(display, menu);
+
+al_register_event_source(queue, al_get_default_menu_event_source());
+al_wait_for_event(queue, &event);
+
+if (event.type == ALLEGRO_EVENT_MENU_CLICK) {
+   if (event.user.data1 == FILE_EXIT_ID) {
+      exit_program();
+   }
+}
+

Because there is no “DISPLAY_DESTROYED” event, you must call al_set_display_menu(display, NULL) before destroying any display with a menu attached, to avoid leaking resources.

+

ALLEGRO_MENU

+
typedef struct ALLEGRO_MENU ALLEGRO_MENU;
+

Source Code

+

An opaque data type that represents a menu that contains menu items. Each of the menu items may optionally include a sub-menu.

+

Examples:

+ +

ALLEGRO_MENU_INFO

+
typedef struct ALLEGRO_MENU_INFO {
+

Source Code

+

A structure that defines how to create a complete menu system. For standard menu items, the following format is used:

+
   { caption, id, flags, icon }
+

For special items, these macros are helpful:

+
ALLEGRO_START_OF_MENU(caption, id)
+ALLEGRO_MENU_SEPARATOR
+ALLEGRO_END_OF_MENU
+

A well-defined menu will begin with ALLEGRO_START_OF_MENU, contain one or more menu items, and end with ALLEGRO_END_OF_MENU. A menu may contain sub-menus. An example:

+
ALLEGRO_MENU_INFO menu_info[] = {
+   ALLEGRO_START_OF_MENU("&File", 1),
+      { "&Open", 2, 0, NULL },
+      ALLEGRO_START_OF_MENU("Open &Recent...", 3),
+         { "Recent 1", 4, 0, NULL },
+         { "Recent 2", 5, 0, NULL },
+         ALLEGRO_END_OF_MENU,
+      ALLEGRO_MENU_SEPARATOR,
+      { "E&xit", 6, 0, NULL },
+      ALLEGRO_END_OF_MENU,
+   ALLEGRO_START_OF_MENU("&Help", 7),
+      {"&About", 8, 0, NULL },
+      ALLEGRO_END_OF_MENU,
+   ALLEGRO_END_OF_MENU
+};
+
+ALLEGRO_MENU *menu = al_build_menu(menu_info);
+

If you prefer, you can build the menu without the structure by using al_create_menu and al_insert_menu_item.

+

See also: al_build_menu

+

Examples:

+ +

al_create_menu

+
ALLEGRO_MENU *al_create_menu(void)
+

Source Code

+

Creates a menu container that can hold menu items.

+

Returns NULL on failure.

+

Since: 5.1.0

+

See also: al_create_popup_menu, al_build_menu

+

al_create_popup_menu

+
ALLEGRO_MENU *al_create_popup_menu(void)
+

Source Code

+

Creates a menu container for popup menus. Only the root (outermost) menu should be created with this function. Sub menus of popups should be created with al_create_menu.

+

Returns NULL on failure.

+

Since: 5.1.0

+

See also: al_create_menu, al_build_menu

+

Examples:

+ +

al_build_menu

+
ALLEGRO_MENU *al_build_menu(ALLEGRO_MENU_INFO *info)
+

Source Code

+

Builds a menu based on the specifications of a sequence of ALLEGRO_MENU_INFO elements.

+

Returns a pointer to the root ALLEGRO_MENU, or NULL on failure. To gain access to the other menus and items, you will need to search for them using al_find_menu_item.

+

Since: 5.1.0

+

See also: ALLEGRO_MENU_INFO, al_create_menu, al_create_popup_menu

+

Examples:

+ +

al_append_menu_item

+
int al_append_menu_item(ALLEGRO_MENU *parent, char const *title, uint16_t id,
+   int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu)
+

Source Code

+

Appends a menu item to the end of the menu. See al_insert_menu_item for more information.

+

Since: 5.1.0

+

See also: al_insert_menu_item, al_remove_menu_item

+

Examples:

+ +

al_insert_menu_item

+
int al_insert_menu_item(ALLEGRO_MENU *parent, int pos, char const *title,
+   uint16_t id, int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu)
+

Source Code

+

Inserts a menu item at the spot specified. See the introductory text for a detailed explanation of how the pos parameter is interpreted.

+

The parent menu can be a popup menu or a regular menu. To underline one character in the title, prefix it with an ampersand.

+

The flags can be any combination of:

+
+
ALLEGRO_MENU_ITEM_DISABLED
+
The item is “grayed out” and cannot be selected. +
+
ALLEGRO_MENU_ITEM_CHECKBOX
+
The item is a check box. This flag can only be set at the time the menu is created. If a check box is clicked, it will automatically be toggled. +
+
ALLEGRO_MENU_ITEM_CHECKED
+
The item is checked. If set, ALLEGRO_MENU_ITEM_CHECKBOX will automatically be set as well. +
+
+

The icon is not yet supported.

+

The submenu parameter indicates that this item contains a child menu. The child menu must have previously been created with al_create_menu, and not be associated with any other menu.

+

Returns true on success.

+

Since: 5.1.0

+

See also: al_append_menu_item, al_remove_menu_item

+

al_remove_menu_item

+
bool al_remove_menu_item(ALLEGRO_MENU *menu, int pos)
+

Source Code

+

Removes the specified item from the menu and destroys it. If the item contains a sub-menu, it too is destroyed. Any references to it are invalidated. If you want to preserve that sub-menu, you should first make a copy with al_clone_menu.

+

This is safe to call on a menu that is currently being displayed.

+

Returns true if an item was removed.

+

Since: 5.1.0

+

See also: al_append_menu_item, al_insert_menu_item, al_destroy_menu

+

Examples:

+ +

al_clone_menu

+
ALLEGRO_MENU *al_clone_menu(ALLEGRO_MENU *menu)
+

Source Code

+

Makes a copy of a menu so that it can be reused on another display. The menu being cloned can be anything: a regular menu, a popup menu, or a sub-menu.

+

Returns the cloned menu.

+

Since: 5.1.0

+

See also: al_clone_menu_for_popup

+

Examples:

+ +

al_clone_menu_for_popup

+
ALLEGRO_MENU *al_clone_menu_for_popup(ALLEGRO_MENU *menu)
+

Source Code

+

Exactly like al_clone_menu, except that the copy is for a popup menu.

+

Since: 5.1.0

+

See also: al_clone_menu

+

Examples:

+ +

al_destroy_menu

+
void al_destroy_menu(ALLEGRO_MENU *menu)
+

Source Code

+

Destroys an entire menu, including its sub-menus. Any references to it or a sub-menu are no longer valid. It is safe to call this on a menu that is currently being displayed.

+

Since: 5.1.0

+

See also: al_remove_menu_item

+

Examples:

+ +

al_get_menu_item_caption

+
const char *al_get_menu_item_caption(ALLEGRO_MENU *menu, int pos)
+

Source Code

+

Returns the caption associated with the menu item. It is valid as long as the caption is not modified.

+

Returns NULL if the item was not found.

+

Since: 5.1.0

+

See also: al_set_menu_item_caption

+

al_set_menu_item_caption

+
void al_set_menu_item_caption(ALLEGRO_MENU *menu, int pos, const char *caption)
+

Source Code

+

Updates the menu item caption with the new caption. This will invalidate any previous calls to al_get_menu_item_caption.

+

Since: 5.1.0

+

See also: al_get_menu_item_caption

+

Examples:

+ +

al_get_menu_item_flags

+
int al_get_menu_item_flags(ALLEGRO_MENU *menu, int pos)
+

Source Code

+

Returns the currently set flags. See al_insert_menu_item for a description of the available flags.

+

Returns -1 if the item was not found.

+

Since: 5.1.0

+

See also: al_set_menu_item_flags, al_toggle_menu_item_flags

+

Examples:

+ +

al_set_menu_item_flags

+
void al_set_menu_item_flags(ALLEGRO_MENU *menu, int pos, int flags)
+

Source Code

+

Updates the menu item’s flags. See al_insert_menu_item for a description of the available flags.

+

Since: 5.1.0

+

See also: al_get_menu_item_flags, al_toggle_menu_item_flags

+

Examples:

+ +

al_toggle_menu_item_flags

+
int al_toggle_menu_item_flags(ALLEGRO_MENU *menu, int pos, int flags)
+

Source Code

+

Toggles the specified menu item’s flags. See al_insert_menu_item for a description of the available flags.

+

Returns a bitfield of only the specified flags that are set after the toggle. A flag that was not toggled will not be returned, even if it is set. Returns -1 if the id is invalid.

+

Since: 5.1.0

+
+

Unstable API: Redundant with al_get/set_menu_item_flags.

+
+

See also: al_get_menu_item_flags, al_set_menu_item_flags

+

al_get_menu_item_icon

+
ALLEGRO_BITMAP *al_get_menu_item_icon(ALLEGRO_MENU *menu, int pos)
+

Source Code

+

Returns the icon associated with the menu. It is safe to draw to the returned bitmap, but you must call al_set_menu_item_icon in order for the changes to be applied.

+

Returns NULL if the item was not found or if it has no icon.

+

Since: 5.1.0

+

See also: al_set_menu_item_icon

+

al_set_menu_item_icon

+
void al_set_menu_item_icon(ALLEGRO_MENU *menu, int pos, ALLEGRO_BITMAP *icon)
+

Source Code

+

Sets the icon for the specified menu item. The menu assumes ownership of the ALLEGRO_BITMAP and may invalidate the pointer, so you must clone it if you wish to continue using it.

+

If a video bitmap is passed, it will automatically be converted to a memory bitmap, so it is preferable to pass a memory bitmap.

+

Since: 5.1.0

+

See also: al_get_menu_item_icon, al_clone_bitmap

+

Examples:

+ +

al_find_menu

+
ALLEGRO_MENU *al_find_menu(ALLEGRO_MENU *haystack, uint16_t id)
+

Source Code

+

Searches in the haystack menu for any submenu with the given id. (Note that this only represents a literal ID, and cannot be used as an index.)

+

Returns the menu, if found. Otherwise returns NULL.

+

Since: 5.1.0

+

See also: al_find_menu_item

+

Examples:

+ +

al_find_menu_item

+
bool al_find_menu_item(ALLEGRO_MENU *haystack, uint16_t id, ALLEGRO_MENU **menu,
+   int *index)
+

Source Code

+

Searches in the haystack menu for an item with the given id. (Note that this only represents a literal ID, and cannot be used as an index.)

+

If menu and index are not NULL, they will be set as the parent menu containing the item and the zero-based (positive) index of the item. (If the menu item was not found, then their values are undefined.)

+

Returns true if the menu item was found.

+

Since: 5.1.0

+

See also: al_find_menu

+

al_get_default_menu_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_default_menu_event_source(void)
+

Source Code

+

Returns the default event source used for menu clicks. If a menu was not given its own event source via al_enable_menu_event_source, then it will use this default source.

+

Since: 5.1.0

+

See also: al_register_event_source, al_enable_menu_event_source, al_disable_menu_event_source

+

Examples:

+ +

al_enable_menu_event_source

+
ALLEGRO_EVENT_SOURCE *al_enable_menu_event_source(ALLEGRO_MENU *menu)
+

Source Code

+

Enables a unique event source for this menu. It and all of its sub-menus will use this event source. (It is safe to call this multiple times on the same menu.)

+

Returns the event source.

+

Since: 5.1.0

+

See also: al_register_event_source, al_get_default_menu_event_source, al_disable_menu_event_source

+

al_disable_menu_event_source

+
void al_disable_menu_event_source(ALLEGRO_MENU *menu)
+

Source Code

+

Disables a unique event source for the menu, causing it to use the default event source.

+

Since: 5.1.0

+

See also: al_get_default_menu_event_source, al_enable_menu_event_source

+

al_get_display_menu

+
ALLEGRO_MENU *al_get_display_menu(ALLEGRO_DISPLAY *display)
+

Source Code

+

Returns the menu associated with the display, or NULL if it does not have a menu.

+

Since: 5.1.0

+

See also: al_set_display_menu

+

al_set_display_menu

+
bool al_set_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu)
+

Source Code

+

Associates the menu with the display and shows it. If there was a previous menu associated with the display, it will be destroyed. If you don’t want that to happen, you should first remove the menu with al_remove_display_menu.

+

If the menu is already attached to a display, it will not be attached to the new display. If menu is NULL, the current menu will still be destroyed.

+
+

Note: Attaching a menu may cause the window as available to your application to be resized! You should listen for a resize event, check how much space was lost, and resize the window accordingly if you want to maintain your window’s prior size.

+
+

Returns true if successful.

+

Since: 5.1.0

+

See also: al_create_menu, al_remove_display_menu

+

Examples:

+ +

al_popup_menu

+
bool al_popup_menu(ALLEGRO_MENU *popup, ALLEGRO_DISPLAY *display)
+

Source Code

+

Displays a context menu next to the mouse cursor. The menu must have been created with al_create_popup_menu. It generates events just like a regular display menu does. It is possible that the menu will be canceled without any selection being made.

+

The display parameter indicates which window the menu is associated with (when you process the menu click event), but does not actually affect where the menu is located on the screen.

+

Returns true if the context menu was displayed.

+
+

Note: On Linux this function will fail if any of the mouse keys are held down. I.e. it will only reliably work if you handle it in ALLEGRO_MOUSE_BUTTON_UP events and even then only if that event corresponds to the final mouse button that was pressed.

+
+

Since: 5.1.0

+

See also: al_create_popup_menu

+

Examples:

+ +

al_remove_display_menu

+
ALLEGRO_MENU *al_remove_display_menu(ALLEGRO_DISPLAY *display)
+

Source Code

+

Detaches the menu associated with the display and returns it. The menu can then be used on a different display.

+

If you simply want to destroy the active menu, you can call al_set_display_menu with a NULL menu.

+

Since: 5.1.0

+

See also: al_set_display_menu

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:43 UTC +

+
+ + diff --git a/allegro/docs/html/refman/opengl.html b/allegro/docs/html/refman/opengl.html new file mode 100644 index 00000000..947a868b --- /dev/null +++ b/allegro/docs/html/refman/opengl.html @@ -0,0 +1,321 @@ + + + + + + + OpenGL integration + + + + + + + + +
+ + +
+

OpenGL integration

+
+ +

These functions are declared in the following header file:

+
 #include <allegro5/allegro_opengl.h>
+

al_get_opengl_extension_list

+
ALLEGRO_OGL_EXT_LIST *al_get_opengl_extension_list(void)
+

Source Code

+

Returns the list of OpenGL extensions supported by Allegro, for the given display.

+

Allegro will keep information about all extensions it knows about in a structure returned by al_get_opengl_extension_list.

+

For example:

+
if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multitexture) {
+   //use it
+}
+

The extension will be set to true if available for the given display and false otherwise. This means to use the definitions and functions from an OpenGL extension, all you need to do is to check for it as above at run time, after acquiring the OpenGL display from Allegro.

+

Under Windows, this will also work with WGL extensions, and under Unix with GLX extensions.

+

In case you want to manually check for extensions and load function pointers yourself (say, in case the Allegro developers did not include it yet), you can use the al_have_opengl_extension and al_get_opengl_proc_address functions instead.

+
+

Note: the exact extensions exposed depend on how Allegro was compiled. It is recommended to use al_have_opengl_extension and al_get_opengl_proc_address for the most stable experience.

+
+

Examples:

+ +

al_get_opengl_proc_address

+
void *al_get_opengl_proc_address(const char *name)
+

Source Code

+

Helper to get the address of an OpenGL symbol

+

Example:

+

How to get the function glMultiTexCoord3fARB that comes with ARB’s Multitexture extension:

+
// define the type of the function
+ALLEGRO_DEFINE_PROC_TYPE(void, MULTI_TEX_FUNC,
+                         (GLenum, GLfloat, GLfloat, GLfloat));
+// declare the function pointer
+MULTI_TEX_FUNC glMultiTexCoord3fARB;
+// get the address of the function
+glMultiTexCoord3fARB = (MULTI_TEX_FUNC) al_get_opengl_proc_address(
+                                                        "glMultiTexCoord3fARB");
+

If glMultiTexCoord3fARB is not NULL then it can be used as if it has been defined in the OpenGL core library.

+
+

Note: Under Windows, OpenGL functions may need a special calling convention, so it’s best to always use the ALLEGRO_DEFINE_PROC_TYPE macro when declaring function pointer types for OpenGL functions.

+
+

Parameters:

+

name - The name of the symbol you want to link to.

+

Return value:

+

A pointer to the symbol if available or NULL otherwise.

+

al_get_opengl_texture

+
GLuint al_get_opengl_texture(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns the OpenGL texture id internally used by the given bitmap if it uses one, else 0.

+

Example:

+
bitmap = al_load_bitmap("my_texture.png");
+texture = al_get_opengl_texture(bitmap);
+if (texture != 0)
+    glBindTexture(GL_TEXTURE_2D, texture);
+

Examples:

+ +

al_get_opengl_texture_size

+
bool al_get_opengl_texture_size(ALLEGRO_BITMAP *bitmap, int *w, int *h)
+

Source Code

+

Retrieves the size of the texture used for the bitmap. This can be different from the bitmap size if OpenGL only supports power-of-two sizes or if it is a sub-bitmap.

+

Returns true on success, false on failure. Zero width and height are returned if the bitmap is not an OpenGL bitmap.

+

See also: al_get_opengl_texture_position

+

al_get_opengl_texture_position

+
void al_get_opengl_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v)
+

Source Code

+

Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels.

+

See also: al_get_opengl_texture_size

+

al_get_opengl_program_object

+
GLuint al_get_opengl_program_object(ALLEGRO_SHADER *shader)
+

Source Code

+

Returns the OpenGL program object associated with this shader, if the platform is ALLEGRO_SHADER_GLSL. Otherwise, returns 0.

+

al_get_opengl_fbo

+
GLuint al_get_opengl_fbo(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Returns the OpenGL FBO id internally used by the given bitmap if it uses one, otherwise returns zero. No attempt will be made to create an FBO if the bitmap is not owned by the current display.

+

The FBO returned by this function will only be freed when the bitmap is destroyed, or if you call al_remove_opengl_fbo on the bitmap.

+
+

Note: In Allegro 5.0.0 this function only returned an FBO which had previously been created by calling al_set_target_bitmap. It would not attempt to create an FBO itself. This has since been changed.

+
+

See also: al_remove_opengl_fbo, al_set_target_bitmap

+

al_remove_opengl_fbo

+
void al_remove_opengl_fbo(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

Explicitly free an OpenGL FBO created for a bitmap, if it has one. Usually you do not need to worry about freeing FBOs, unless you use al_get_opengl_fbo.

+

See also: al_get_opengl_fbo, al_set_target_bitmap

+

al_have_opengl_extension

+
bool al_have_opengl_extension(const char *extension)
+

Source Code

+

This function is a helper to determine whether an OpenGL extension is available on the given display or not.

+

Example:

+
bool packedpixels = al_have_opengl_extension("GL_EXT_packed_pixels");
+

If packedpixels is true then you can safely use the constants related to the packed pixels extension.

+

Returns true if the extension is available; false otherwise.

+

Examples:

+ +

al_get_opengl_version

+
uint32_t al_get_opengl_version(void)
+

Source Code

+

Returns the OpenGL or OpenGL ES version number of the client (the computer the program is running on), for the current display. “1.0” is returned as 0x01000000, “1.2.1” is returned as 0x01020100, and “1.2.2” as 0x01020200, etc.

+

A valid OpenGL context must exist for this function to work, which means you may not call it before al_create_display.

+

See also: al_get_opengl_variant

+

al_get_opengl_variant

+
int al_get_opengl_variant(void)
+

Source Code

+

Returns the variant or type of OpenGL used on the running platform. This function can be called before creating a display or setting properties for new displays. Possible values are:

+
+
ALLEGRO_DESKTOP_OPENGL
+
Regular OpenGL as seen on desktop/laptop computers. +
+
ALLEGRO_OPENGL_ES
+
Trimmed down version of OpenGL used on many small consumer electronic devices such as handheld (and sometimes full size) consoles. +
+
+

See also: al_get_opengl_version

+

al_set_current_opengl_context

+
void al_set_current_opengl_context(ALLEGRO_DISPLAY *display)
+

Source Code

+

Make the OpenGL context associated with the given display current for the calling thread. If there is a current target bitmap which belongs to a different OpenGL context, the target bitmap will be changed to NULL.

+

Normally you do not need to use this function, as the context will be made current when you call al_set_target_bitmap or al_set_target_backbuffer. You might need it if you created an OpenGL “forward compatible” context. Then al_get_backbuffer only returns NULL, so it would not work to pass that to al_set_target_bitmap.

+

OpenGL configuration

+

You can disable the detection of any OpenGL extension by Allegro with a section like this in allegro5.cfg:

+
[opengl_disabled_extensions]
+GL_ARB_texture_non_power_of_two=0
+GL_EXT_framebuffer_object=0
+

Any extension which appears in the section is treated as not available (it does not matter if you set it to 0 or any other value).

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/pandoc.css b/allegro/docs/html/refman/pandoc.css new file mode 100644 index 00000000..ff4b4817 --- /dev/null +++ b/allegro/docs/html/refman/pandoc.css @@ -0,0 +1,255 @@ +/* We use this style sheet for HTML documents generated with Pandoc. */ + +body { + background-color: #fcfcfc; + padding-left: 0.1em; + color: #222; + font-family: sans-serif; +} + +pre { + border: 1px solid #ddd; + background-color: #f3f3f8; + padding: 0.6em; + padding-left: 0.8em; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +blockquote { + border: 1px solid #ddd; + background-color: #fff8e0; + padding: 0.6em; + padding-left: 0.8em; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +blockquote p { + padding: 0; + margin: 0; +} + +blockquote p em:first-child { + font-style: normal; + font-weight: bold; + color: #400000; +} + +code { + font-family: monospace; +} + +h1, h2, h3, h4, h5 { + color: #348; + margin-top: 2.5em; + border-top: 1px solid #eee; + padding-top: 0.8em; +} + +h1 { + font-size: 130%; +} + +h2 { + font-size: 110%; +} + +h3 { + font-size: 95%; +} + +h4 { + font-size: 90%; + font-style: italic; +} + +h5 { + font-size: 90%; + font-style: italic; +} + +h1.title { + font-size: 200%; + font-weight: bold; + margin-top: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + text-align: left; + border: none; +} + +a { + text-decoration: none; + color: #348; +} + +dl dt { + font-weight: bold; +} + +dt code { + font-weight: bold; +} + +dd p { + margin-top: 0; +} + +ul { + padding-left: 1.5em; +} + +table { + background-color: #f8f8fa; + border-top: 1px solid #e0e0e0; + border-bottom: 1px solid #e0e0e0; +} + +table th { + font-weight: bold; + border-bottom: 1px solid #e0e0e0; + padding: 0.5em; +} + +/* Side bar */ +div.sidebar { + background-color: #f0f0fa; + border: solid 1px #e0e0ea; + float: left; + width: 150px; + margin-right: 1em; + line-height: 110%; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.sidebar ul { + list-style-type: none; + padding: 0; + margin-left: 0.5em; + font-size: small; +} + +div.sidebar ul a:hover { + background: #fffff0; +} + +div.searchbox { + margin-left: 5px; + margin-right: 5px; + margin-bottom: 0.8em; + font-size: small; +} + +/* font-size isn't inherited (at least not in Firefox and Chrome) */ +input#q { + font-size: small; + width: 85%; +} + +/* Body of page */ +div.content { + margin-left: 165px; + max-width: 50em; + line-height: 135%; +} + +div#TOC { + display: table; + border: 1px solid #ddd; + background-color: #f3f3fa; + padding-right: 1em; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div#TOC ul { + padding-left: 1em; + list-style-type: none; +} + +p.timestamp { + margin-top: 3em; + border-top: solid 1px #eee; + padding: 0.7em; + padding-left: 0.3em; + color: #999; + text-align: left; +} + +/* Below is the autosuggest.css from autosuggest.js version 2.4. */ + +.autosuggest-body +{ + position: absolute; + border: 1px solid black; + z-index: 100; + font-size: small; +} + +.autosuggest-body iframe +{ + display: block; + position: absolute; + z-index: 999; + filter: alpha(opacity=0); +} + +.autosuggest-body table +{ + width: 100%; + background-color: #f3f3fa; +} + +.autosuggest-body tr +{ + cursor: hand; + cursor: pointer; + + color: black; + + text-align: left; +} + +.autosuggest-body tr.up +{ + height: 10px; + background: #656291 url("arrow-up.gif") center center no-repeat; +} + +.autosuggest-body tr.down +{ + height: 10px; + background: #656291 url("arrow-down.gif") center center no-repeat; +} + +.autosuggest-body tr.up-disabled +{ + height: 10px; + background: #656291 url("arrow-up-d.gif") center center no-repeat; + cursor: default; +} + +.autosuggest-body tr.down-disabled +{ + height: 10px; + background: #656291 url("arrow-down-d.gif") center center no-repeat; + cursor: default; +} + +.autosuggest-body tr.selected +{ + background-color: #D6D7E7; + color: red; +} + +.autosuggest-body td +{ + white-space: nowrap; +} + +.autosuggest-body span.match +{ + font-weight: bold; +} diff --git a/allegro/docs/html/refman/path.html b/allegro/docs/html/refman/path.html new file mode 100644 index 00000000..693b864a --- /dev/null +++ b/allegro/docs/html/refman/path.html @@ -0,0 +1,445 @@ + + + + + + + Path structures + + + + + + + + +
+ + +
+

Path structures

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

We define a path as an optional drive, followed by zero or more directory components, followed by an optional filename. The filename may be broken up into a basename and an extension, where the basename includes the start of the filename up to, but not including, the last dot (.) character. If no dot character exists the basename is the whole filename. The extension is everything from the last dot character to the end of the filename.

+

al_create_path

+
ALLEGRO_PATH *al_create_path(const char *str)
+

Source Code

+

Create a path structure from a string. The last component, if it is followed by a directory separator and is neither “.” nor “..”, is treated as the last directory name in the path. Otherwise the last component is treated as the filename. The string may be NULL for an empty path.

+

See also: al_create_path_for_directory, al_destroy_path

+

Examples:

+ +

al_create_path_for_directory

+
ALLEGRO_PATH *al_create_path_for_directory(const char *str)
+

Source Code

+

This is the same as al_create_path, but interprets the passed string as a directory path. The filename component of the returned path will always be empty.

+

See also: al_create_path, al_destroy_path

+

al_destroy_path

+
void al_destroy_path(ALLEGRO_PATH *path)
+

Source Code

+

Free a path structure. Does nothing if passed NULL.

+

See also: al_create_path, al_create_path_for_directory

+

Examples:

+ +

al_clone_path

+
ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path)
+

Source Code

+

Clones an ALLEGRO_PATH structure. Returns NULL on failure.

+

See also: al_destroy_path

+

Examples:

+ +

al_join_paths

+
bool al_join_paths(ALLEGRO_PATH *path, const ALLEGRO_PATH *tail)
+

Source Code

+

Concatenate two path structures. The first path structure is modified. If ‘tail’ is an absolute path, this function does nothing.

+

If ‘tail’ is a relative path, all of its directory components will be appended to ‘path’. tail’s filename will also overwrite path’s filename, even if it is just the empty string.

+

Tail’s drive is ignored.

+

Returns true if ‘tail’ was a relative path and so concatenated to ‘path’, otherwise returns false.

+

See also: al_rebase_path

+

Examples:

+ +

al_rebase_path

+
bool al_rebase_path(const ALLEGRO_PATH *head, ALLEGRO_PATH *tail)
+

Source Code

+

Concatenate two path structures, modifying the second path structure. If tail is an absolute path, this function does nothing. Otherwise, the drive and path components in head are inserted at the start of tail.

+

For example, if head is “/anchor/” and tail is “data/file.ext”, then after the call tail becomes “/anchor/data/file.ext”.

+

See also: al_join_paths

+

Examples:

+ +

al_get_path_drive

+
const char *al_get_path_drive(const ALLEGRO_PATH *path)
+

Source Code

+

Return the drive letter on a path, or the empty string if there is none.

+

The “drive letter” is only used on Windows, and is usually a string like “c:”, but may be something like “\\Computer Name” in the case of UNC (Uniform Naming Convention) syntax.

+

Examples:

+ +

al_get_path_num_components

+
int al_get_path_num_components(const ALLEGRO_PATH *path)
+

Source Code

+

Return the number of directory components in a path.

+

The directory components do not include the final part of a path (the filename).

+

See also: al_get_path_component

+

Examples:

+ +

al_get_path_component

+
const char *al_get_path_component(const ALLEGRO_PATH *path, int i)
+

Source Code

+

Return the i’th directory component of a path, counting from zero. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds.

+

See also: al_get_path_num_components, al_get_path_tail

+

Examples:

+ +

al_get_path_tail

+
const char *al_get_path_tail(const ALLEGRO_PATH *path)
+

Source Code

+

Returns the last directory component, or NULL if there are no directory components.

+

Examples:

+ +

al_get_path_filename

+
const char *al_get_path_filename(const ALLEGRO_PATH *path)
+

Source Code

+

Return the filename part of the path, or the empty string if there is none.

+

The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed.

+

See also: al_get_path_basename, al_get_path_extension, al_get_path_component

+

Examples:

+ +

al_get_path_basename

+
const char *al_get_path_basename(const ALLEGRO_PATH *path)
+

Source Code

+

Return the basename, i.e. filename with the extension removed. If the filename doesn’t have an extension, the whole filename is the basename. If there is no filename part then the empty string is returned.

+

The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed.

+

See also: al_get_path_filename, al_get_path_extension

+

Examples:

+ +

al_get_path_extension

+
const char *al_get_path_extension(const ALLEGRO_PATH *path)
+

Source Code

+

Return a pointer to the start of the extension of the filename, i.e. everything from the final dot (‘.’) character onwards. If no dot exists, returns an empty string.

+

The returned pointer is valid only until the filename part of the path is modified in any way, or until the path is destroyed.

+

See also: al_get_path_filename, al_get_path_basename

+

Examples:

+ +

al_set_path_drive

+
void al_set_path_drive(ALLEGRO_PATH *path, const char *drive)
+

Source Code

+

Set the drive string on a path. The drive may be NULL, which is equivalent to setting the drive string to the empty string.

+

See also: al_get_path_drive

+

Examples:

+ +

al_append_path_component

+
void al_append_path_component(ALLEGRO_PATH *path, const char *s)
+

Source Code

+

Append a directory component.

+

See also: al_insert_path_component

+

Examples:

+ +

al_insert_path_component

+
void al_insert_path_component(ALLEGRO_PATH *path, int i, const char *s)
+

Source Code

+

Insert a directory component at index i. If the index is negative then count from the right, i.e. -1 refers to the last path component.

+

It is an error to pass an index i which is not within these bounds: 0 <= i <= al_get_path_num_components(path).

+

See also: al_append_path_component, al_replace_path_component, al_remove_path_component

+

Examples:

+ +

al_replace_path_component

+
void al_replace_path_component(ALLEGRO_PATH *path, int i, const char *s)
+

Source Code

+

Replace the i’th directory component by another string. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds.

+

See also: al_insert_path_component, al_remove_path_component

+

Examples:

+ +

al_remove_path_component

+
void al_remove_path_component(ALLEGRO_PATH *path, int i)
+

Source Code

+

Delete the i’th directory component. If the index is negative then count from the right, i.e. -1 refers to the last path component. It is an error to pass an index which is out of bounds.

+

See also: al_insert_path_component, al_replace_path_component, al_drop_path_tail

+

Examples:

+ +

al_drop_path_tail

+
void al_drop_path_tail(ALLEGRO_PATH *path)
+

Source Code

+

Remove the last directory component, if any.

+

See also: al_remove_path_component

+

Examples:

+ +

al_set_path_filename

+
void al_set_path_filename(ALLEGRO_PATH *path, const char *filename)
+

Source Code

+

Set the optional filename part of the path. The filename may be NULL, which is equivalent to setting the filename to the empty string.

+

See also: al_set_path_extension, al_get_path_filename

+

Examples:

+ +

al_set_path_extension

+
bool al_set_path_extension(ALLEGRO_PATH *path, char const *extension)
+

Source Code

+

Replaces the extension of the path with the given one, i.e. replaces everything from the final dot (‘.’) character onwards, including the dot. If the filename of the path has no extension, the given one is appended. Usually the new extension you supply should include a leading dot.

+

Returns false if the path contains no filename part, i.e. the filename part is the empty string.

+

See also: al_set_path_filename, al_get_path_extension

+

Examples:

+ +

al_path_cstr

+
const char *al_path_cstr(const ALLEGRO_PATH *path, char delim)
+

Source Code

+

Convert a path to its string representation, i.e. optional drive, followed by directory components separated by ‘delim’, followed by an optional filename.

+

To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP for ‘delim’.

+

The returned pointer is valid only until the path is modified in any way, or until the path is destroyed. This returns a null-terminated string. If you need an ALLEGRO_USTR instead, use al_path_ustr.

+

See also: al_path_ustr

+

Examples:

+ +

al_path_ustr

+
const ALLEGRO_USTR *al_path_ustr(const ALLEGRO_PATH *path, char delim)
+

Source Code

+

Convert a path to its string representation, i.e. optional drive, followed by directory components separated by ‘delim’, followed by an optional filename.

+

To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP for ‘delim’.

+

The returned pointer is valid only until the path is modified in any way, or until the path is destroyed. This returns an ALLEGRO_USTR. If you need a null-terminated string instead, use al_path_cstr.

+

Since: 5.2.3

+

See also: al_path_cstr

+

al_make_path_canonical

+
bool al_make_path_canonical(ALLEGRO_PATH *path)
+

Source Code

+

Removes any leading ‘..’ directory components in absolute paths. Removes all ‘.’ directory components.

+

Note that this does not collapse “x/../y” sections into “y”. This is by design. If “/foo” on your system is a symlink to “/bar/baz”, then “/foo/../quux” is actually “/bar/quux”, not “/quux” as a naive removal of “..” components would give you.

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:41 UTC +

+
+ + diff --git a/allegro/docs/html/refman/physfs.html b/allegro/docs/html/refman/physfs.html new file mode 100644 index 00000000..69fee352 --- /dev/null +++ b/allegro/docs/html/refman/physfs.html @@ -0,0 +1,207 @@ + + + + + + + PhysicsFS integration + + + + + + + + +
+ + +
+

PhysicsFS integration

+
+ +

PhysicsFS is a library to provide abstract access to various archives. See http://icculus.org/physfs/ for more information.

+

This addon makes it possible to read and write files (on disk or inside archives) using PhysicsFS, through Allegro’s file I/O API. For example, that means you can use the Image I/O addon to load images from .zip files.

+

You must set up PhysicsFS through its own API. When you want to open an ALLEGRO_FILE using PhysicsFS, first call al_set_physfs_file_interface, then al_fopen or another function that calls al_fopen.

+

These functions are declared in the following header file. Link with allegro_physfs.

+
 #include <allegro5/allegro_physfs.h>
+

al_set_physfs_file_interface

+
void al_set_physfs_file_interface(void)
+

Source Code

+

This function sets both the ALLEGRO_FILE_INTERFACE and ALLEGRO_FS_INTERFACE for the calling thread.

+

Subsequent calls to al_fopen on the calling thread will be handled by PHYSFS_open(). Operations on the files returned by al_fopen will then be performed through PhysicsFS. Calls to the Allegro filesystem functions, such as al_read_directory or al_create_fs_entry, on the calling thread will be diverted to PhysicsFS.

+

To remember and restore another file I/O backend, you can use al_store_state/al_restore_state.

+
+

Note: due to an oversight, this function differs from al_set_new_file_interface and al_set_standard_file_interface which only alter the current ALLEGRO_FILE_INTERFACE.

+
+
+

Note: PhysFS does not support the text-mode reading and writing, which means that Windows-style newlines will not be preserved.

+
+

See also: al_set_new_file_interface.

+

Examples:

+ +

al_get_allegro_physfs_version

+
uint32_t al_get_allegro_physfs_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:43 UTC +

+
+ + diff --git a/allegro/docs/html/refman/platform.html b/allegro/docs/html/refman/platform.html new file mode 100644 index 00000000..48149f44 --- /dev/null +++ b/allegro/docs/html/refman/platform.html @@ -0,0 +1,347 @@ + + + + + + + Platform-specific functions + + + + + + + + +
+ + +
+

Platform-specific functions

+
+ +

Windows

+

These functions are declared in the following header file:

+
 #include <allegro5/allegro_windows.h>
+

al_get_win_window_handle

+
HWND al_get_win_window_handle(ALLEGRO_DISPLAY *display)
+

Source Code

+

Returns the handle to the window that the passed display is using.

+

Examples:

+ +

al_win_add_window_callback

+
bool al_win_add_window_callback(ALLEGRO_DISPLAY *display,
+   bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam,
+   LPARAM lparam, LRESULT *result, void *userdata), void *userdata)
+

Source Code

+

The specified callback function will intercept the window’s message before Allegro processes it. If the callback function consumes the event, then it should return true. In that case, Allegro will not do anything with the event.

+

Optionally, you may use result to customize what Allegro will return return in response to this event. By default, Allegro returns TRUE.

+

The userdata pointer can be used to supply additional context to the callback function.

+

The callbacks are executed in the same order they were added.

+

Returns true if the callback was added.

+

Since: 5.1.2

+

al_win_remove_window_callback

+
bool al_win_remove_window_callback(ALLEGRO_DISPLAY *display,
+   bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam,
+   LPARAM lparam, LRESULT *result, void *userdata), void *userdata)
+

Source Code

+

Removes the callback that was previously registered with al_win_add_window_callback. The userdata pointer must be the same as what was used during the registration of the callback.

+

Returns true if the callback was removed.

+

Since: 5.1.2

+

Mac OS X

+

These functions are declared in the following header file:

+
 #include <allegro5/allegro_osx.h>
+

al_osx_get_window

+
NSWindow* al_osx_get_window(ALLEGRO_DISPLAY *display)
+

Source Code

+

Retrieves the NSWindow handle associated with the Allegro display.

+

Since: 5.0.8, 5.1.3

+

iPhone

+

These functions are declared in the following header file:

+
 #include <allegro5/allegro_iphone.h>
+

al_iphone_set_statusbar_orientation

+
void al_iphone_set_statusbar_orientation(int o)
+

Source Code

+

Sets the orientation of the status bar, which can be one of the following:

+
    +
  • ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT
  • +
  • ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT_UPSIDE_DOWN
  • +
  • ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_RIGHT
  • +
  • ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_LEFT
  • +
+

Since: 5.1.0

+

al_iphone_get_view

+
UIView *al_iphone_get_view(ALLEGRO_DISPLAY *display)
+

Source Code

+

Retrieves the UIView* (EAGLView*) associated with the Allegro display.

+

Since: 5.1.0

+

al_iphone_get_window

+
UIWindow *al_iphone_get_window(ALLEGRO_DISPLAY *display)
+

Source Code

+

Retrieves the UIWindow* associated with the Allegro display.

+

Since: 5.1.0

+

Android

+

These functions are declared in the following header file:

+
 #include <allegro5/allegro_android.h>
+

al_android_set_apk_file_interface

+
void al_android_set_apk_file_interface(void)
+

Source Code

+

This function will set up a custom ALLEGRO_FILE_INTERFACE that makes all future calls of al_fopen read from the applicatons’s APK file.

+
+

Note: Currently, access to the APK file after calling this function is read only.

+
+

Since: 5.1.2

+

Examples:

+ +

al_android_set_apk_fs_interface

+
void al_android_set_apk_fs_interface(void)
+

Source Code

+

This function will set up a custom ALLEGRO_FS_INTERFACE which allows working within the APK filesystem. The filesystem root is your assets directory and there is read-only access to all files within.

+
+

Note: Some things like querying file size or attributes are not supported by this. You can always use the PhysFS addon to open the APK file (it is just a regular .zip file) and get more complete information.

+
+

Since: 5.1.13

+

Examples:

+ +

al_android_get_os_version

+
const char *al_android_get_os_version(void)
+

Source Code

+

Returns a pointer to a static buffer that contains the version string of the Android platform that the calling Allegro program is running on.

+

Since: 5.1.2

+

al_android_get_jni_env

+
JNIEnv *al_android_get_jni_env(void)
+

Source Code

+

Returns the Android JNI environment used by Allegro to call into Java. As a convenience this function provides it to the user so there is no need to obtain it yourself.

+

For example if you have a Java method “void send(String message)” in your activity class, you could call it like this from C code:

+
JNIEnv * env = al_android_get_jni_env();
+jclass class_id = (* env)->GetObjectClass(env, al_android_get_activity());
+jmethodID method_id = (* env)->GetMethodID(env, class_id, "send",
+    "(Ljava/lang/String;)V");
+jstring jdata = (* env)->NewStringUTF(env, "Hello Java!");
+(* env)->CallVoidMethod(env, al_android_get_activity(), method_id, jdata);
+(* env)->DeleteLocalRef(env, jdata);
+

Since: 5.2.2

+
+

Unstable API: This API is new and subject to refinement.

+
+

al_android_get_activity

+
jobject al_android_get_activity(void)
+

Source Code

+

Returns the Java Android activity used by Allegro. This is the same object created by Android from the class you specify in your manifest and either an instance of AllegroActivity or a derived class.

+

Since: 5.2.2

+
+

Unstable API: This API is new and subject to refinement.

+
+

X11

+

These functions are declared in the following header file:

+
 #include <allegro5/allegro_x.h>
+

al_get_x_window_id

+
XID al_get_x_window_id(ALLEGRO_DISPLAY *display)
+

Source Code

+

Retrieves the XID associated with the Allegro display.

+

Since: 5.1.12

+

al_x_set_initial_icon

+
bool al_x_set_initial_icon(ALLEGRO_BITMAP *bitmap)
+

Source Code

+

On some window managers (notably Ubuntu’s Unity) al_set_display_icon doesn’t work and you need to use a .desktop file. But with this function you can set an icon before calling al_create_display. This works by setting the icon before XMapWindow.

+

Since: 5.2.3

+
+

Unstable API: New API.

+
+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/primitives.html b/allegro/docs/html/refman/primitives.html new file mode 100644 index 00000000..3cce68a1 --- /dev/null +++ b/allegro/docs/html/refman/primitives.html @@ -0,0 +1,1326 @@ + + + + + + + Primitives addon + + + + + + + + +
+ + +
+

Primitives addon

+
+ +

These functions are declared in the following header file. Link with allegro_primitives.

+
 #include <allegro5/allegro_primitives.h>
+

General

+

al_get_allegro_primitives_version

+
uint32_t al_get_allegro_primitives_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

al_init_primitives_addon

+
bool al_init_primitives_addon(void)
+

Source Code

+

Initializes the primitives addon.

+

Returns: True on success, false on failure.

+

See also: al_shutdown_primitives_addon

+

Examples:

+ +

al_is_primitives_addon_initialized

+
bool al_is_primitives_addon_initialized(void)
+

Source Code

+

Returns true if the primitives addon is initialized, otherwise returns false.

+

Since: 5.2.6

+

See also: al_init_primitives_addon, al_shutdown_primitives_addon

+

al_shutdown_primitives_addon

+
void al_shutdown_primitives_addon(void)
+

Source Code

+

Shut down the primitives addon. This is done automatically at program exit, but can be called any time the user wishes as well.

+

See also: al_init_primitives_addon

+

High level drawing routines

+

High level drawing routines encompass the most common usage of this addon: to draw geometric primitives, both smooth (variations on the circle theme) and piecewise linear. Outlined primitives support the concept of thickness with two distinct modes of output: hairline lines and thick lines. Hairline lines are specifically designed to be exactly a pixel wide, and are commonly used for drawing outlined figures that need to be a pixel wide. Hairline thickness is designated as thickness less than or equal to 0. Unfortunately, the exact rasterization rules for drawing these hairline lines vary from one video card to another, and sometimes leave gaps where the lines meet. If that matters to you, then you should use thick lines. In many cases, having a thickness of 1 will produce 1 pixel wide lines that look better than hairline lines. Obviously, hairline lines cannot replicate thicknesses greater than 1. Thick lines grow symmetrically around the generating shape as thickness is increased.

+

Pixel-precise output

+

While normally you should not be too concerned with which pixels are displayed when the high level primitives are drawn, it is nevertheless possible to control that precisely by carefully picking the coordinates at which you draw those primitives.

+

To be able to do that, however, it is critical to understand how GPU cards convert shapes to pixels. Pixels are not the smallest unit that can be addressed by the GPU. Because the GPU deals with floating point coordinates, it can in fact assign different coordinates to different parts of a single pixel. To a GPU, thus, a screen is composed of a grid of squares that have width and length of 1. The top left corner of the top left pixel is located at (0, 0). Therefore, the center of that pixel is at (0.5, 0.5). The basic rule that determines which pixels are associated with which shape is then as follows: a pixel is treated to belong to a shape if the pixel’s center is located in that shape. The figure below illustrates the above concepts:

+
+Diagram showing a how pixel output is calculated by the GPU given the mathematical description of several shapes. +
+

This figure depicts three shapes drawn at the top left of the screen: an orange and green rectangles and a purple circle. On the left are the mathematical descriptions of pixels on the screen and the shapes to be drawn. On the right is the screen output. Only a single pixel has its center inside the circle, and therefore only a single pixel is drawn on the screen. Similarly, two pixels are drawn for the orange rectangle. Since there are no pixels that have their centers inside the green rectangle, the output image has no green pixels.

+

Here is a more practical example. The image below shows the output of this code:

+
/* blue vertical line */
+al_draw_line(0.5, 0, 0.5, 6, color_blue, 1);
+/* red horizontal line */
+al_draw_line(2, 1, 6, 1, color_red, 2);
+/* green filled rectangle */
+al_draw_filled_rectangle(3, 4, 5, 5, color_green);
+/* purple outlined rectangle */
+al_draw_rectangle(2.5, 3.5, 5.5, 5.5, color_purple, 1);
+
+Diagram showing a practical example of pixel output resulting from the invocation of several primitives addon functions. +
+

It can be seen that lines are generated by making a rectangle based on the dashed line between the two endpoints. The thickness causes the rectangle to grow symmetrically about that generating line, as can be seen by comparing the red and blue lines. Note that to get proper pixel coverage, the coordinates passed to the al_draw_line had to be offset by 0.5 in the appropriate dimensions.

+

Filled rectangles are generated by making a rectangle between the endpoints passed to the al_draw_filled_rectangle.

+

Outlined rectangles are generated by symmetrically expanding an outline of a rectangle. With a thickness of 1, as depicted in the diagram, this means that an offset of 0.5 is needed for both sets of endpoint coordinates to exactly line up with the pixels of the display raster.

+

The above rules only apply when multisampling is turned off. When multisampling is turned on, the area of a pixel that is covered by a shape is taken into account when choosing what color to draw there. This also means that shapes no longer have to contain the pixel’s center to affect its color. For example, the green rectangle in the first diagram may in fact be drawn as two (or one) semi-transparent pixels. The advantages of multisampling is that slanted shapes will look smoother because they will not have jagged edges. A disadvantage of multisampling is that it may make vertical and horizontal edges blurry. While the exact rules for multisampling are unspecified, and may vary from GPU to GPU, it is usually safe to assume that as long as a pixel is either completely covered by a shape or completely not covered, then the shape edges will be sharp. The offsets used in the second diagram were chosen so that this is the case: if you use those offsets, your shapes (if they are oriented the same way as they are on the diagram) should look the same whether multisampling is turned on or off.

+

al_draw_line

+
void al_draw_line(float x1, float y1, float x2, float y2,
+   ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws a line segment between two points.

+

Parameters:

+
    +
  • x1, y1, x2, y2 - Start and end points of the line
  • +
  • color - Color of the line
  • +
  • thickness - Thickness of the line, pass <= 0 to draw hairline lines
  • +
+

See also: al_draw_soft_line

+

Examples:

+ +

al_draw_triangle

+
void al_draw_triangle(float x1, float y1, float x2, float y2,
+   float x3, float y3, ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws an outlined triangle.

+

Parameters:

+
    +
  • x1, y1, x2, y2, x3, y3 - Three points of the triangle
  • +
  • color - Color of the triangle
  • +
  • thickness - Thickness of the lines, pass <= 0 to draw hairline lines
  • +
+

See also: al_draw_filled_triangle, al_draw_soft_triangle

+

Examples:

+ +

al_draw_filled_triangle

+
void al_draw_filled_triangle(float x1, float y1, float x2, float y2,
+   float x3, float y3, ALLEGRO_COLOR color)
+

Source Code

+

Draws a filled triangle.

+

Parameters:

+
    +
  • x1, y1, x2, y2, x3, y3 - Three points of the triangle
  • +
  • color - Color of the triangle
  • +
+

See also: al_draw_triangle

+

Examples:

+ +

al_draw_rectangle

+
void al_draw_rectangle(float x1, float y1, float x2, float y2,
+   ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws an outlined rectangle.

+

Parameters:

+
    +
  • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
  • +
  • color - Color of the rectangle
  • +
  • thickness - Thickness of the lines, pass <= 0 to draw hairline lines
  • +
+

See also: al_draw_filled_rectangle, al_draw_rounded_rectangle

+

Examples:

+ +

al_draw_filled_rectangle

+
void al_draw_filled_rectangle(float x1, float y1, float x2, float y2,
+   ALLEGRO_COLOR color)
+

Source Code

+

Draws a filled rectangle.

+

Parameters:

+
    +
  • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
  • +
  • color - Color of the rectangle
  • +
+

See also: al_draw_rectangle, al_draw_filled_rounded_rectangle

+

Examples:

+ +

al_draw_rounded_rectangle

+
void al_draw_rounded_rectangle(float x1, float y1, float x2, float y2,
+   float rx, float ry, ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws an outlined rounded rectangle.

+

Parameters:

+
    +
  • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
  • +
  • color - Color of the rectangle
  • +
  • rx, ry - The radii of the round
  • +
  • thickness - Thickness of the lines, pass <= 0 to draw hairline lines
  • +
+

See also: al_draw_filled_rounded_rectangle, al_draw_rectangle

+

Examples:

+ +

al_draw_filled_rounded_rectangle

+
void al_draw_filled_rounded_rectangle(float x1, float y1, float x2, float y2,
+   float rx, float ry, ALLEGRO_COLOR color)
+

Source Code

+

Draws an filled rounded rectangle.

+

Parameters:

+
    +
  • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
  • +
  • color - Color of the rectangle
  • +
  • rx, ry - The radii of the round
  • +
+

See also: al_draw_rounded_rectangle, al_draw_filled_rectangle

+

Examples:

+ +

al_calculate_arc

+
void al_calculate_arc(float* dest, int stride, float cx, float cy,
+   float rx, float ry, float start_theta, float delta_theta, float thickness,
+   int num_points)
+

Source Code

+

When thickness <= 0 this function computes positions of num_points regularly spaced points on an elliptical arc. When thickness > 0 this function computes two sets of points, obtained as follows: the first set is obtained by taking the points computed in the thickness <= 0 case and shifting them by thickness / 2 outward, in a direction perpendicular to the arc curve. The second set is the same, but shifted thickness / 2 inward relative to the arc. The two sets of points are interleaved in the destination buffer (i.e. the first pair of points will be collinear with the arc center, the first point of the pair will be farther from the center than the second point; the next pair will also be collinear, but at a different angle and so on).

+

The destination buffer dest is interpreted as a set of regularly spaced pairs of floats, each pair holding the coordinates of the corresponding point on the arc. The two floats in the pair are adjacent, and the distance (in bytes) between the addresses of the first float in two successive pairs is stride. For example, if you have a tightly packed array of floats with no spaces between pairs, then stride will be exactly 2 * sizeof(float).

+

Example with thickness <= 0:

+
const int num_points = 4;
+float points[num_points][2];
+al_calculate_arc(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 0, num_points);
+
+assert((int)points[0][0] == 10);
+assert((int)points[0][1] == 0);
+
+assert((int)points[num_points - 1][0] == 0);
+assert((int)points[num_points - 1][1] == 10);
+

Example with thickness > 0:

+
const int num_points = 4;
+float points[num_points * 2][2];
+al_calculate_arc(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 2, num_points);
+
+assert((int)points[0][0] == 11);
+assert((int)points[0][1] == 0);
+assert((int)points[1][0] == 9);
+assert((int)points[1][1] == 0);
+
+assert((int)points[(num_points - 1) * 2][0] == 0);
+assert((int)points[(num_points - 1) * 2][1] == 11);
+assert((int)points[(num_points - 1) * 2 + 1][0] == 0);
+assert((int)points[(num_points - 1) * 2 + 1][1] == 9);
+

Parameters:

+
    +
  • dest - The destination buffer
  • +
  • stride - Distance (in bytes) between starts of successive pairs of points
  • +
  • cx, cy - Center of the arc
  • +
  • rx, ry - Radii of the arc
  • +
  • start_theta - The initial angle from which the arc is calculated in radians
  • +
  • delta_theta - Angular span of the arc in radians (pass a negative number to switch direction)
  • +
  • thickness - Thickness of the arc
  • +
  • num_points - The number of points to calculate
  • +
+

See also: al_draw_arc, al_calculate_spline, al_calculate_ribbon

+

Examples:

+ +

al_draw_pieslice

+
void al_draw_pieslice(float cx, float cy, float r, float start_theta,
+   float delta_theta, ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws a pieslice (outlined circular sector).

+

Parameters:

+
    +
  • cx, cy - Center of the pieslice
  • +
  • r - Radius of the pieslice
  • +
  • color - Color of the pieslice
  • +
  • start_theta - The initial angle from which the pieslice is drawn in radians
  • +
  • delta_theta - Angular span of the pieslice in radians (pass a negative number to switch direction)
  • +
  • thickness - Thickness of the circle, pass <= 0 to draw hairline pieslice
  • +
+

Since: 5.0.6, 5.1.0

+

See also: al_draw_filled_pieslice

+

Examples:

+ +

al_draw_filled_pieslice

+
void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta,
+   float delta_theta, ALLEGRO_COLOR color)
+

Source Code

+

Draws a filled pieslice (filled circular sector).

+

Parameters:

+
    +
  • cx, cy - Center of the pieslice
  • +
  • r - Radius of the pieslice
  • +
  • color - Color of the pieslice
  • +
  • start_theta - The initial angle from which the pieslice is drawn in radians
  • +
  • delta_theta - Angular span of the pieslice in radians (pass a negative number to switch direction)
  • +
+

Since: 5.0.6, 5.1.0

+

See also: al_draw_pieslice

+

Examples:

+ +

al_draw_ellipse

+
void al_draw_ellipse(float cx, float cy, float rx, float ry,
+   ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws an outlined ellipse.

+

Parameters:

+
    +
  • cx, cy - Center of the ellipse
  • +
  • rx, ry - Radii of the ellipse
  • +
  • color - Color of the ellipse
  • +
  • thickness - Thickness of the ellipse, pass <= 0 to draw a hairline ellipse
  • +
+

See also: al_draw_filled_ellipse, al_draw_circle

+

Examples:

+ +

al_draw_filled_ellipse

+
void al_draw_filled_ellipse(float cx, float cy, float rx, float ry,
+   ALLEGRO_COLOR color)
+

Source Code

+

Draws a filled ellipse.

+

Parameters:

+
    +
  • cx, cy - Center of the ellipse
  • +
  • rx, ry - Radii of the ellipse
  • +
  • color - Color of the ellipse
  • +
+

See also: al_draw_ellipse, al_draw_filled_circle

+

Examples:

+ +

al_draw_circle

+
void al_draw_circle(float cx, float cy, float r, ALLEGRO_COLOR color,
+   float thickness)
+

Source Code

+

Draws an outlined circle.

+

Parameters:

+
    +
  • cx, cy - Center of the circle
  • +
  • r - Radius of the circle
  • +
  • color - Color of the circle
  • +
  • thickness - Thickness of the circle, pass <= 0 to draw a hairline circle
  • +
+

See also: al_draw_filled_circle, al_draw_ellipse

+

Examples:

+ +

al_draw_filled_circle

+
void al_draw_filled_circle(float cx, float cy, float r, ALLEGRO_COLOR color)
+

Source Code

+

Draws a filled circle.

+

Parameters:

+
    +
  • cx, cy - Center of the circle
  • +
  • r - Radius of the circle
  • +
  • color - Color of the circle
  • +
+

See also: al_draw_circle, al_draw_filled_ellipse

+

Examples:

+ +

al_draw_arc

+
void al_draw_arc(float cx, float cy, float r, float start_theta,
+   float delta_theta, ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws an arc.

+

Parameters:

+
    +
  • cx, cy - Center of the arc
  • +
  • r - Radius of the arc
  • +
  • color - Color of the arc
  • +
  • start_theta - The initial angle from which the arc is calculated in radians
  • +
  • delta_theta - Angular span of the arc in radians (pass a negative number to switch direction)
  • +
  • thickness - Thickness of the arc, pass <= 0 to draw hairline arc
  • +
+

See also: al_calculate_arc, al_draw_elliptical_arc

+

Examples:

+ +

al_draw_elliptical_arc

+
void al_draw_elliptical_arc(float cx, float cy, float rx, float ry, float start_theta,
+   float delta_theta, ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws an elliptical arc.

+

Parameters:

+
    +
  • cx, cy - Center of the arc
  • +
  • rx, ry - Radii of the arc
  • +
  • color - Color of the arc
  • +
  • start_theta - The initial angle from which the arc is calculated in radians
  • +
  • delta_theta - Angular span of the arc in radians (pass a negative number to switch direction)
  • +
  • thickness - Thickness of the arc, pass <= 0 to draw hairline arc
  • +
+

Since: 5.0.6, 5.1.0

+

See also: al_calculate_arc, al_draw_arc

+

Examples:

+ +

al_calculate_spline

+
void al_calculate_spline(float* dest, int stride, float points[8],
+   float thickness, int num_segments)
+

Source Code

+

Calculates a Bézier spline given 4 control points. If thickness <= 0, then num_segments of points are required in the destination, otherwise twice as many are needed. The destination buffer should consist of regularly spaced (by distance of stride bytes) doublets of floats, corresponding to x and y coordinates of the vertices.

+

Parameters:

+
    +
  • dest - The destination buffer
  • +
  • stride - Distance (in bytes) between starts of successive pairs of coordinates
  • +
  • points - An array of 4 pairs of coordinates of the 4 control points
  • +
  • thickness - Thickness of the spline ribbon
  • +
  • num_segments - The number of points to calculate
  • +
+

See also: al_draw_spline, al_calculate_arc, al_calculate_ribbon

+

al_draw_spline

+
void al_draw_spline(float points[8], ALLEGRO_COLOR color, float thickness)
+

Source Code

+

Draws a Bézier spline given 4 control points.

+

Parameters:

+
    +
  • points - An array of 4 pairs of coordinates of the 4 control points
  • +
  • color - Color of the spline
  • +
  • thickness - Thickness of the spline, pass <= 0 to draw a hairline spline
  • +
+

See also: al_calculate_spline

+

Examples:

+ +

al_calculate_ribbon

+
void al_calculate_ribbon(float* dest, int dest_stride, const float *points,
+   int points_stride, float thickness, int num_segments)
+

Source Code

+

Calculates a ribbon given an array of points. The ribbon will go through all of the passed points. If thickness <= 0, then num_segments of points are required in the destination buffer, otherwise twice as many are needed. The destination and the points buffer should consist of regularly spaced doublets of floats, corresponding to x and y coordinates of the vertices.

+

Parameters:

+
    +
  • dest - Pointer to the destination buffer
  • +
  • dest_stride - Distance (in bytes) between starts of successive pairs of coordinates in the destination buffer
  • +
  • points - An array of pairs of coordinates for each point
  • +
  • points_stride - Distance (in bytes) between starts of successive pairs of coordinates in the points buffer
  • +
  • thickness - Thickness of the spline ribbon
  • +
  • num_segments - The number of points to calculate
  • +
+

See also: al_draw_ribbon, al_calculate_arc, al_calculate_spline

+

al_draw_ribbon

+
void al_draw_ribbon(const float *points, int points_stride, ALLEGRO_COLOR color,
+   float thickness, int num_segments)
+

Source Code

+

Draws a ribbon given an array of points. The ribbon will go through all of the passed points. The points buffer should consist of regularly spaced doublets of floats, corresponding to x and y coordinates of the vertices.

+

Parameters:

+
    +
  • points - An array of coordinate pairs (x and y) for each point
  • +
  • points_stride - Distance (in bytes) between starts of successive pairs of coordinates in the points buffer
  • +
  • color - Color of the spline
  • +
  • thickness - Thickness of the spline, pass <= 0 to draw hairline spline
  • +
  • num_segments - The number of segments
  • +
+

See also: al_calculate_ribbon

+

Low level drawing routines

+

Low level drawing routines allow for more advanced usage of the addon, allowing you to pass arbitrary sequences of vertices to draw to the screen. These routines also support using textures on the primitives with the following restrictions:

+

For maximum portability, you should only use textures that have dimensions that are a power of two, as not every videocard supports textures of different sizes completely. This warning is relaxed, however, if the texture coordinates never exit the boundaries of a single bitmap (i.e. you are not having the texture repeat/tile). As long as that is the case, any texture can be used safely. Sub-bitmaps work as textures, but cannot be tiled.

+

Some platforms also dictate a minimum texture size, which means that textures smaller than that size will not tile properly. The minimum size that will work on all platforms is 32 by 32.

+

A note about pixel coordinates. In OpenGL the texture coordinate (0, 0) refers to the top left corner of the pixel. This confuses some drivers, because due to rounding errors the actual pixel sampled might be the pixel to the top and/or left of the (0, 0) pixel. To make this error less likely it is advisable to offset the texture coordinates you pass to the al_draw_prim by (0.5, 0.5) if you need precise pixel control. E.g. to refer to pixel (5, 10) you’d set the u and v to 5.5 and 10.5 respectively.

+

See also: Pixel-precise output

+

al_draw_prim

+
int al_draw_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
+   ALLEGRO_BITMAP* texture, int start, int end, int type)
+

Source Code

+

Draws a subset of the passed vertex array.

+

Parameters:

+
    +
  • texture - Texture to use, pass NULL to use only color shaded primitves
  • +
  • vtxs - Pointer to an array of vertices
  • +
  • decl - Pointer to a vertex declaration. If set to NULL, the vertices are assumed to be of the ALLEGRO_VERTEX type
  • +
  • start - Start index of the subset of the vertex array to draw
  • +
  • end - One past the last index of the subset of the vertex array to draw
  • +
  • type - A member of the ALLEGRO_PRIM_TYPE enumeration, specifying what kind of primitive to draw
  • +
+

Returns: Number of primitives drawn

+

For example to draw a textured triangle you could use:

+
ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1);
+ALLEGRO_VERTEX v[] = {
+   {.x = 128, .y = 0, .z = 0, .color = white, .u = 128, .v = 0},
+   {.x = 0, .y = 256, .z = 0, .color = white, .u = 0, .v = 256},
+   {.x = 256, .y = 256, .z = 0, .color = white, .u = 256, .v = 256}};
+al_draw_prim(v, NULL, texture, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST);
+

See also: ALLEGRO_VERTEX, ALLEGRO_PRIM_TYPE, ALLEGRO_VERTEX_DECL, al_draw_indexed_prim

+

Examples:

+ +

al_draw_indexed_prim

+
int al_draw_indexed_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
+   ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type)
+

Source Code

+

Draws a subset of the passed vertex array. This function uses an index array to specify which vertices to use.

+

Parameters:

+
    +
  • texture - Texture to use, pass NULL to use only color shaded primitves
  • +
  • vtxs - Pointer to an array of vertices
  • +
  • decl - Pointer to a vertex declaration. If set to NULL, the vtxs are assumed to be of the ALLEGRO_VERTEX type
  • +
  • indices - An array of indices into the vertex array
  • +
  • num_vtx - Number of indices from the indices array you want to draw
  • +
  • type - A member of the ALLEGRO_PRIM_TYPE enumeration, specifying what kind of primitive to draw
  • +
+

Returns: Number of primitives drawn

+

See also: ALLEGRO_VERTEX, ALLEGRO_PRIM_TYPE, ALLEGRO_VERTEX_DECL, al_draw_prim

+

Examples:

+ +

al_draw_vertex_buffer

+
int al_draw_vertex_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer,
+   ALLEGRO_BITMAP* texture, int start, int end, int type)
+

Source Code

+

Draws a subset of the passed vertex buffer. The vertex buffer must not be locked. Additionally, to draw onto memory bitmaps or with memory bitmap textures the vertex buffer must support reading (i.e.  it must be created with the ALLEGRO_PRIM_BUFFER_READWRITE).

+

Parameters:

+
    +
  • vertex_buffer - Vertex buffer to draw
  • +
  • texture - Texture to use, pass NULL to use only color shaded primitves
  • +
  • start - Start index of the subset of the vertex buffer to draw
  • +
  • end - One past the last index of the subset of the vertex buffer to draw
  • +
  • type - A member of the ALLEGRO_PRIM_TYPE enumeration, specifying what kind of primitive to draw
  • +
+

Returns: Number of primitives drawn

+

Since: 5.1.3

+

See also: ALLEGRO_VERTEX_BUFFER, ALLEGRO_PRIM_TYPE

+

Examples:

+ +

al_draw_indexed_buffer

+
int al_draw_indexed_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer,
+   ALLEGRO_BITMAP* texture, ALLEGRO_INDEX_BUFFER* index_buffer,
+   int start, int end, int type)
+

Source Code

+

Draws a subset of the passed vertex buffer. This function uses an index buffer to specify which vertices to use. Both buffers must not be locked. Additionally, to draw onto memory bitmaps or with memory bitmap textures both buffers must support reading (i.e. they must be created with the ALLEGRO_PRIM_BUFFER_READWRITE).

+

Parameters:

+
    +
  • vertex_buffer - Vertex buffer to draw
  • +
  • texture - Texture to use, pass NULL to use only color shaded primitves
  • +
  • index_buffer - Index buffer to use
  • +
  • start - Start index of the subset of the vertex buffer to draw
  • +
  • end - One past the last index of the subset of the vertex buffer to draw
  • +
  • type - A member of the ALLEGRO_PRIM_TYPE enumeration, specifying what kind of primitive to draw. Note that ALLEGRO_PRIM_LINE_LOOP and ALLEGRO_PRIM_POINT_LIST are not supported.
  • +
+

Returns: Number of primitives drawn

+

Since: 5.1.8

+

See also: ALLEGRO_VERTEX_BUFFER, ALLEGRO_INDEX_BUFFER, ALLEGRO_PRIM_TYPE

+

Examples:

+ +

al_draw_soft_triangle

+
void al_draw_soft_triangle(
+   ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state,
+   void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*),
+   void (*first)(uintptr_t, int, int, int, int),
+   void (*step)(uintptr_t, int),
+   void (*draw)(uintptr_t, int, int, int))
+

Source Code

+

Draws a triangle using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/tri_soft.c. The triangle is drawn in two segments, from top to bottom. The segments are deliniated by the vertically middle vertex of the triangle. One of the two segments may be absent if two vertices are horizontally collinear.

+

Parameters:

+
    +
  • v1, v2, v3 - The three vertices of the triangle
  • +
  • state - A pointer to a user supplied struct, this struct will be passed to all the pixel functions
  • +
  • init - Called once per call before any drawing is done. The three points passed to it may be altered by clipping.
  • +
  • first - Called twice per call, once per triangle segment. It is passed 4 parameters, the first two are the coordinates of the initial pixel drawn in the segment. The second two are the left minor and the left major steps, respectively. They represent the sizes of two steps taken by the rasterizer as it walks on the left side of the triangle. From then on, each step will either be classified as a minor or a major step, corresponding to the above values.
  • +
  • step - Called once per scanline. The last parameter is set to 1 if the step is a minor step, and 0 if it is a major step.
  • +
  • draw - Called once per scanline. The function is expected to draw the scanline starting with a point specified by the first two parameters (corresponding to x and y values) going to the right until it reaches the value of the third parameter (the x value of the end point). All coordinates are inclusive.
  • +
+

See also: al_draw_triangle

+

al_draw_soft_line

+
void al_draw_soft_line(ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state,
+   void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*),
+   void (*step)(uintptr_t, int),
+   void (*draw)(uintptr_t, int, int))
+

Source Code

+

Draws a line using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/line_soft.c. The line is drawn top to bottom.

+

Parameters:

+
    +
  • v1, v2 - The two vertices of the line
  • +
  • state - A pointer to a user supplied struct, this struct will be passed to all the pixel functions
  • +
  • first - Called before drawing the first pixel of the line. It is passed the coordinates of this pixel, as well as the two vertices above. The passed vertices may have been altered by clipping.
  • +
  • step - Called once per pixel. The second parameter is set to 1 if the step is a minor step, and 0 if this step is a major step. Minor steps are taken only either in x or y directions. Major steps are taken in both directions diagonally. In all cases, the absolute value of the change in coordinate is at most 1 in either direction.
  • +
  • draw - Called once per pixel. The function is expected to draw the pixel at the coordinates passed to it.
  • +
+

See also: al_draw_line

+

Custom vertex declaration routines

+

al_create_vertex_decl

+
ALLEGRO_VERTEX_DECL* al_create_vertex_decl(const ALLEGRO_VERTEX_ELEMENT* elements, int stride)
+

Source Code

+

Creates a vertex declaration, which describes a custom vertex format.

+

Parameters:

+ +

Returns: Newly created vertex declaration.

+

See also: ALLEGRO_VERTEX_ELEMENT, ALLEGRO_VERTEX_DECL, al_destroy_vertex_decl

+

Examples:

+ +

al_destroy_vertex_decl

+
void al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL* decl)
+

Source Code

+

Destroys a vertex declaration.

+

Parameters:

+
    +
  • decl - Vertex declaration to destroy
  • +
+

See also: ALLEGRO_VERTEX_ELEMENT, ALLEGRO_VERTEX_DECL, al_create_vertex_decl

+

Examples:

+ +

Vertex buffer routines

+

al_create_vertex_buffer

+
ALLEGRO_VERTEX_BUFFER* al_create_vertex_buffer(ALLEGRO_VERTEX_DECL* decl,
+   const void* initial_data, int num_vertices, int flags)
+

Source Code

+

Creates a vertex buffer. Can return NULL if the buffer could not be created (e.g. the system only supports write-only buffers).

+
+

Note:

+

This is an advanced feature, often unsupported on lower-end video cards. Be extra mindful of this function failing and make arrangements for fallback drawing functionality or a nice error message for users with such lower-end cards.

+
+

Parameters:

+
    +
  • decl - Vertex type that this buffer will hold. NULL implies that this buffer will hold ALLEGRO_VERTEX vertices
  • +
  • initial_data - Memory buffer to copy from to initialize the vertex buffer. Can be NULL, in which case the buffer is uninitialized.
  • +
  • num_vertices - Number of vertices the buffer will hold
  • +
  • flags - A combination of the ALLEGRO_PRIM_BUFFER_FLAGS flags specifying how this buffer will be created. Passing 0 is the same as passing ALLEGRO_PRIM_BUFFER_STATIC.
  • +
+

Since: 5.1.3

+

See also: ALLEGRO_VERTEX_BUFFER, al_destroy_vertex_buffer

+

Examples:

+ +

al_destroy_vertex_buffer

+
void al_destroy_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer)
+

Source Code

+

Destroys a vertex buffer. Does nothing if passed NULL.

+

Since: 5.1.3

+

See also: ALLEGRO_VERTEX_BUFFER, al_create_vertex_buffer

+

Examples:

+ +

al_lock_vertex_buffer

+
void* al_lock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer, int offset,
+   int length, int flags)
+

Source Code

+

Locks a vertex buffer so you can access its data. Will return NULL if the parameters are invalid, if reading is requested from a write only buffer, or if the buffer is already locked.

+

Parameters:

+
    +
  • buffer - Vertex buffer to lock
  • +
  • offset - Vertex index of the start of the locked range
  • +
  • length - How many vertices to lock
  • +
  • flags - ALLEGRO_LOCK_READONLY, ALLEGRO_LOCK_WRITEONLY or ALLEGRO_LOCK_READWRITE
  • +
+

Since: 5.1.3

+

See also: ALLEGRO_VERTEX_BUFFER, al_unlock_vertex_buffer

+

Examples:

+ +

al_unlock_vertex_buffer

+
void al_unlock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer)
+

Source Code

+

Unlocks a previously locked vertex buffer.

+

Since: 5.1.3

+

See also: ALLEGRO_VERTEX_BUFFER, al_lock_vertex_buffer

+

Examples:

+ +

al_get_vertex_buffer_size

+
int al_get_vertex_buffer_size(ALLEGRO_VERTEX_BUFFER* buffer)
+

Source Code

+

Returns the size of the vertex buffer

+

Since: 5.1.8

+

See also: ALLEGRO_VERTEX_BUFFER

+

Index buffer routines

+

al_create_index_buffer

+
ALLEGRO_INDEX_BUFFER* al_create_index_buffer(int index_size,
+    const void* initial_data, int num_indices, int flags)
+

Source Code

+

Creates a index buffer. Can return NULL if the buffer could not be created (e.g. the system only supports write-only buffers).

+
+

Note:

+

This is an advanced feature, often unsupported on lower-end video cards. Be extra mindful of this function failing and make arrangements for fallback drawing functionality or a nice error message for users with such lower-end cards.

+
+

Parameters:

+
    +
  • index_size - Size of the index in bytes. Supported sizes are 2 for short integers and 4 for integers
  • +
  • initial_data - Memory buffer to copy from to initialize the index buffer. Can be NULL, in which case the buffer is uninitialized.
  • +
  • num_indices - Number of indices the buffer will hold
  • +
  • flags - A combination of the ALLEGRO_PRIM_BUFFER_FLAGS flags specifying how this buffer will be created. Passing 0 is the same as passing ALLEGRO_PRIM_BUFFER_STATIC.
  • +
+

Since: 5.1.8

+

See also: ALLEGRO_INDEX_BUFFER, al_destroy_index_buffer

+

Examples:

+ +

al_destroy_index_buffer

+
void al_destroy_index_buffer(ALLEGRO_INDEX_BUFFER* buffer)
+

Source Code

+

Destroys a index buffer. Does nothing if passed NULL.

+

Since: 5.1.8

+

See also: ALLEGRO_INDEX_BUFFER, al_create_index_buffer

+

Examples:

+ +

al_lock_index_buffer

+
void* al_lock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer, int offset,
+    int length, int flags)
+

Source Code

+

Locks a index buffer so you can access its data. Will return NULL if the parameters are invalid, if reading is requested from a write only buffer and if the buffer is already locked.

+

Parameters:

+
    +
  • buffer - Index buffer to lock
  • +
  • offset - Element index of the start of the locked range
  • +
  • length - How many indices to lock
  • +
  • flags - ALLEGRO_LOCK_READONLY, ALLEGRO_LOCK_WRITEONLY or ALLEGRO_LOCK_READWRITE
  • +
+

Since: 5.1.8

+

See also: ALLEGRO_INDEX_BUFFER, al_unlock_index_buffer

+

Examples:

+ +

al_unlock_index_buffer

+
void al_unlock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer)
+

Source Code

+

Unlocks a previously locked index buffer.

+

Since: 5.1.8

+

See also: ALLEGRO_INDEX_BUFFER, al_lock_index_buffer

+

Examples:

+ +

al_get_index_buffer_size

+
int al_get_index_buffer_size(ALLEGRO_INDEX_BUFFER* buffer)
+

Source Code

+

Returns the size of the index buffer

+

Since: 5.1.8

+

See also: ALLEGRO_INDEX_BUFFER

+

Polygon routines

+

al_draw_polyline

+
void al_draw_polyline(const float* vertices, int vertex_stride,
+   int vertex_count, int join_style, int cap_style,
+   ALLEGRO_COLOR color, float thickness, float miter_limit)
+

Source Code

+

Draw a series of line segments.

+
    +
  • vertices - Interleaved array of (x, y) vertex coordinates
  • +
  • vertex_stride - the number of bytes between pairs of vertices (the stride)
  • +
  • vertex_count - Number of vertices in the array
  • +
  • join_style - Member of ALLEGRO_LINE_JOIN specifying how to render the joins between line segments
  • +
  • cap_style - Member of ALLEGRO_LINE_CAP specifying how to render the end caps
  • +
  • color - Color of the line
  • +
  • thickness - Thickness of the line, pass <= 0 to draw hairline lines
  • +
  • miter_limit - Parameter for miter join style
  • +
+

The stride is normally 2 * sizeof(float) but may be more if the vertex coordinates are in an array of some structure type, e.g.

+
struct VertexInfo {
+   float x;
+   float y;
+   int id;
+};
+
+void my_draw(struct VertexInfo verts[], int vertex_count, ALLEGRO_COLOR c)
+{
+   al_draw_polyline((float *)verts, sizeof(VertexInfo), vertex_count,
+      ALLEGRO_LINE_JOIN_NONE, ALLEGRO_LINE_CAP_NONE, c, 1.0, 1.0);
+}
+

The stride may also be negative if the vertices are stored in reverse order.

+

Since: 5.1.0

+

See also: al_draw_polygon, ALLEGRO_LINE_JOIN, ALLEGRO_LINE_CAP

+

Examples:

+ +

al_draw_polygon

+
void al_draw_polygon(const float *vertices, int vertex_count,
+   int join_style, ALLEGRO_COLOR color, float thickness, float miter_limit)
+

Source Code

+

Draw an unfilled polygon. This is the same as passing ALLEGRO_LINE_CAP_CLOSED to al_draw_polyline.

+
    +
  • vertex - Interleaved array of (x, y) vertex coordinates
  • +
  • vertex_count - Number of vertices in the array
  • +
  • join_style - Member of ALLEGRO_LINE_JOIN specifying how to render the joins between line segments
  • +
  • color - Color of the line
  • +
  • thickness - Thickness of the line, pass <= 0 to draw hairline lines
  • +
  • miter_limit - Parameter for miter join style
  • +
+

Since: 5.1.0

+

See also: al_draw_filled_polygon, al_draw_polyline, ALLEGRO_LINE_JOIN

+

Examples:

+ +

al_draw_filled_polygon

+
void al_draw_filled_polygon(const float *vertices, int vertex_count,
+   ALLEGRO_COLOR color)
+

Source Code

+

Draw a filled, simple polygon. Simple means it does not have to be convex but must not be self-overlapping.

+
    +
  • vertices - Interleaved array of (x, y) vertex coordinates
  • +
  • vertex_count - Number of vertices in the array
  • +
  • color - Color of the filled polygon
  • +
+

When the y-axis is facing downwards (the usual), the coordinates must be ordered anti-clockwise.

+

Since: 5.1.0

+

See also: al_draw_polygon, al_draw_filled_polygon_with_holes

+

Examples:

+ +

al_draw_filled_polygon_with_holes

+
void al_draw_filled_polygon_with_holes(const float *vertices,
+   const int *vertex_counts, ALLEGRO_COLOR color)
+

Source Code

+

Draws a filled simple polygon with zero or more other simple polygons subtracted from it - the holes. The holes cannot touch or intersect with the outline of the filled polygon.

+
    +
  • vertices - Interleaved array of (x, y) vertex coordinates for each of the polygons, including holes.
  • +
  • vertex_counts - Number of vertices for each polygon. The number of vertices in the filled polygon is given by vertex_counts[0] and must be at least three. Subsequent elements indicate the number of vertices in each hole. The array must be terminated with an element with value zero.
  • +
  • color - Color of the filled polygon
  • +
+

When the y-axis is facing downwards (the usual) the filled polygon coordinates must be ordered anti-clockwise. All hole vertices must use the opposite order (clockwise with y down). All hole vertices must be inside the main polygon and no hole may overlap the main polygon.

+

For example:

+
float vertices[] = {
+      0,   0, // filled polygon, upper left corner
+      0, 100, // filled polygon, lower left corner
+    100, 100, // filled polygon, lower right corner
+    100,   0, // filled polygon, upper right corner
+     10,  10, // hole, upper left
+     90,  10, // hole, upper right
+     90,  90  // hole, lower right
+};
+int vertex_counts[] = {
+   4, // number of vertices for filled polygon
+   3, // number of vertices for hole
+   0  // terminator
+};
+

There are 7 vertices: four for an outer square from (0, 0) to (100, 100) in anti-clockwise order, and three more for an inner triangle in clockwise order. The outer main polygon uses vertices 0 to 3 (inclusive) and the hole uses vertices 4 to 6 (inclusive).

+

Since: 5.1.0

+

See also: al_draw_filled_polygon, al_draw_filled_polygon_with_holes, al_triangulate_polygon

+

Examples:

+ +

al_triangulate_polygon

+
bool al_triangulate_polygon(
+   const float* vertices, size_t vertex_stride, const int* vertex_counts,
+   void (*emit_triangle)(int, int, int, void*), void* userdata)
+

Source Code

+

Divides a simple polygon into triangles, with zero or more other simple polygons subtracted from it - the holes. The holes cannot touch or intersect with the outline of the main polygon. Simple means the polygon does not have to be convex but must not be self-overlapping.

+

Parameters:

+
    +
  • vertices - Interleaved array of (x, y) vertex coordinates for each of the polygons, including holes.
  • +
  • vertex_stride - distance (in bytes) between successive pairs of vertices in the array.
  • +
  • vertex_counts - Number of vertices for each polygon. The number of vertices in the main polygon is given by vertex_counts[0] and must be at least three. Subsequent elements indicate the number of vertices in each hole. The array must be terminated with an element with value zero.
  • +
  • emit_triangle - a function to be called for every set of three points that form a triangle. The function is passed the indices of the points in vertices and userdata.
  • +
  • userdata - arbitrary data to be passed to emit_triangle.
  • +
+

Since: 5.1.0

+

See also: al_draw_filled_polygon_with_holes

+

Structures and types

+

ALLEGRO_VERTEX

+
typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX;
+

Source Code

+

Defines the generic vertex type, with a 3D position, color and texture coordinates for a single texture. Note that at this time, the software driver for this addon cannot render 3D primitives. If you want a 2D only primitive, set z to 0. Note that you must initialize all members of this struct when you’re using it. One exception to this rule are the u and v variables which can be left uninitialized when you are not using textures.

+

Fields:

+
    +
  • x, y, z - Position of the vertex (float)
  • +
  • u, v - Texture coordinates measured in pixels (float)
  • +
  • color - ALLEGRO_COLOR structure, storing the color of the vertex
  • +
+

See also: ALLEGRO_PRIM_ATTR

+

Examples:

+ +

ALLEGRO_VERTEX_DECL

+
typedef struct ALLEGRO_VERTEX_DECL ALLEGRO_VERTEX_DECL;
+

Source Code

+

A vertex declaration. This opaque structure is responsible for describing the format and layout of a user defined custom vertex. It is created and destroyed by specialized functions.

+

See also: al_create_vertex_decl, al_destroy_vertex_decl, ALLEGRO_VERTEX_ELEMENT

+

Examples:

+ +

ALLEGRO_VERTEX_ELEMENT

+
typedef struct ALLEGRO_VERTEX_ELEMENT ALLEGRO_VERTEX_ELEMENT;
+

Source Code

+

A small structure describing a certain element of a vertex. E.g. the position of the vertex, or its color. These structures are used by the al_create_vertex_decl function to create the vertex declaration. For that they generally occur in an array. The last element of such an array should have the attribute field equal to 0, to signify that it is the end of the array. Here is an example code that would create a declaration describing the ALLEGRO_VERTEX structure (passing this as vertex declaration to al_draw_prim would be identical to passing NULL):

+
/* On compilers without the offsetof keyword you need to obtain the
+ * offset with sizeof and make sure to account for packing.
+ */
+ALLEGRO_VERTEX_ELEMENT elems[] = {
+   {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX, x)},
+   {ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_FLOAT_2, offsetof(ALLEGRO_VERTEX, u)},
+   {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ALLEGRO_VERTEX, color)},
+   {0, 0, 0}
+};
+ALLEGRO_VERTEX_DECL* decl = al_create_vertex_decl(elems, sizeof(ALLEGRO_VERTEX));
+

Fields:

+
    +
  • attribute - A member of the ALLEGRO_PRIM_ATTR enumeration, specifying what this attribute signifies
  • +
  • storage - A member of the ALLEGRO_PRIM_STORAGE enumeration, specifying how this attribute is stored
  • +
  • offset - Offset in bytes from the beginning of the custom vertex structure. The C function offsetof is very useful here.
  • +
+

See also: al_create_vertex_decl, ALLEGRO_VERTEX_DECL, ALLEGRO_PRIM_ATTR, ALLEGRO_PRIM_STORAGE

+

Examples:

+ +

ALLEGRO_PRIM_TYPE

+
typedef enum ALLEGRO_PRIM_TYPE
+

Source Code

+

Enumerates the types of primitives this addon can draw.

+
    +
  • ALLEGRO_PRIM_POINT_LIST - A list of points, each vertex defines a point

  • +
  • ALLEGRO_PRIM_LINE_LIST - A list of lines, sequential pairs of vertices define disjointed lines

  • +
  • ALLEGRO_PRIM_LINE_STRIP - A strip of lines, sequential vertices define a strip of lines

  • +
  • ALLEGRO_PRIM_LINE_LOOP - Like a line strip, except at the end the first and the last vertices are also connected by a line

  • +
  • ALLEGRO_PRIM_TRIANGLE_LIST - A list of triangles, sequential triplets of vertices define disjointed triangles

  • +
  • ALLEGRO_PRIM_TRIANGLE_STRIP - A strip of triangles, sequential vertices define a strip of triangles

  • +
  • ALLEGRO_PRIM_TRIANGLE_FAN - A fan of triangles, all triangles share the first vertex

  • +
+

ALLEGRO_PRIM_ATTR

+
typedef enum ALLEGRO_PRIM_ATTR
+

Source Code

+

Enumerates the types of vertex attributes that a custom vertex may have.

+
    +
  • ALLEGRO_PRIM_POSITION - Position information, can be stored only in ALLEGRO_PRIM_SHORT_2, ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_FLOAT_3.

  • +
  • ALLEGRO_PRIM_COLOR_ATTR - Color information, stored in an ALLEGRO_COLOR. The storage field of ALLEGRO_VERTEX_ELEMENT is ignored

  • +
  • ALLEGRO_PRIM_TEX_COORD - Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are normalized by the width and height of the texture, meaning that the bottom-right corner has texture coordinates of (1, 1).

  • +
  • ALLEGRO_PRIM_TEX_COORD_PIXEL - Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are measured in pixels.

  • +
  • ALLEGRO_PRIM_USER_ATTR - A user specified attribute. You can use any storage for this attribute. You may have at most ALLEGRO_PRIM_MAX_USER_ATTR (currently 10) of these that you can specify by adding an index to the value of ALLEGRO_PRIM_USER_ATTR, e.g. the first user attribute is ALLEGRO_PRIM_USER_ATTR + 0, the second is ALLEGRO_PRIM_USER_ATTR + 1 and so on.

    +

    To access these custom attributes from GLSL shaders you need to declare attributes that follow this nomenclature: al_user_attr_# where # is the index of the attribute.

    +

    For example to have a position and a normal vector for each vertex you could declare it like this:

    +
    ALLEGRO_VERTEX_ELEMENT elements[3] = {
    +    {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, 0},
    +    {ALLEGRO_PRIM_USER_ATTR + 0, ALLEGRO_PRIM_FLOAT_3, 12},
    +    {0, 0, 0}};
    +

    And then in your vertex shader access it like this:

    +
    attribute vec3 al_pos; // ALLEGRO_PRIM_POSITION
    +attribute vec3 al_user_attr_0; // ALLEGRO_PRIM_USER_ATTR + 0
    +varying float light;
    +const vec3 light_direction = vec3(0, 0, 1);
    +void main() {
    +    light = dot(al_user_attr_0, light_direction);
    +    gl_Position = al_pos;
    +}
    +

    To access these custom attributes from HLSL you need to declare a parameter with the following semantics: TEXCOORD{# + 2} where # is the index of the attribute. E.g. the first attribute can be accessed via TEXCOORD2, second via TEXCOORD3 and so on.

    +

    Since: 5.1.6

  • +
+

See also: ALLEGRO_VERTEX_DECL, ALLEGRO_PRIM_STORAGE, al_attach_shader_source

+

ALLEGRO_PRIM_STORAGE

+
typedef enum ALLEGRO_PRIM_STORAGE
+

Source Code

+

Enumerates the types of storage an attribute of a custom vertex may be stored in. Many of these can only be used for ALLEGRO_PRIM_USER_ATTR attributes and can only be accessed via shaders. Usually no matter what the storage is specified the attribute gets converted to single precision floating point when the shader is run. Despite that, it may be advantageous to use more dense storage formats (e.g. ALLEGRO_PRIM_NORMALIZED_UBYTE_4 instead of ALLEGRO_PRIM_FLOAT_4) when bandwidth (amount of memory sent to the GPU) is an issue but precision is not.

+
    +
  • ALLEGRO_PRIM_FLOAT_1 - A single float

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_FLOAT_2 - A doublet of floats

  • +
  • ALLEGRO_PRIM_FLOAT_3 - A triplet of floats

  • +
  • ALLEGRO_PRIM_FLOAT_4 - A quad of floats

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_SHORT_2 - A doublet of shorts

  • +
  • ALLEGRO_PRIM_SHORT_4 - A quad of shorts

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_UBYTE_4 - A quad of unsigned bytes

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_NORMALIZED_SHORT_2 - A doublet of shorts. Before being sent to the shader, each component is divided by 32767. Each component of the resultant float doublet ranges between -1.0 and 1.0

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_NORMALIZED_SHORT_4 - A quad of shorts. Before being sent to the shader, each component is divided by 32767. Each component of the resultant float quad ranges between -1.0 and 1.0

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_NORMALIZED_UBYTE_4 - A quad of unsigned bytes. Before being sent to the shader, each component is divided by 255. Each component of the resultant float quad ranges between 0.0 and 1.0

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_NORMALIZED_USHORT_2 - A doublet of unsigned shorts. Before being sent to the shader, each component is divided by 65535. Each component of the resultant float doublet ranges between 0.0 and 1.0

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_NORMALIZED_USHORT_4 - A quad of unsigned shorts. Before being sent to the shader, each component is divided by 65535. Each component of the resultant float quad ranges between 0.0 and 1.0

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_HALF_FLOAT_2 - A doublet of half-precision floats. Note that this storage format is not supported on all platforms. al_create_vertex_decl will return NULL if you use it on those platforms

    +

    Since: 5.1.6

  • +
  • ALLEGRO_PRIM_HALF_FLOAT_4 - A quad of half-precision floats. Note that this storage format is not supported on all platforms. al_create_vertex_decl will return NULL if you use it on those platforms.

    +

    Since: 5.1.6

  • +
+

See also: ALLEGRO_PRIM_ATTR

+

ALLEGRO_VERTEX_CACHE_SIZE

+
#define ALLEGRO_VERTEX_CACHE_SIZE 256
+

Source Code

+

Defines the size of the transformation vertex cache for the software renderer. If you pass less than this many vertices to the primitive rendering functions you will get a speed boost. This also defines the size of the cache vertex buffer, used for the high-level primitives. This corresponds to the maximum number of line segments that will be used to form them.

+

ALLEGRO_PRIM_QUALITY

+
#define ALLEGRO_PRIM_QUALITY 10
+

Source Code

+

Controls the quality of the approximation of curved primitives (e.g. circles). Curved primitives are drawn by approximating them with a sequence of line segments. By default, this roughly corresponds to error of less than half of a pixel.

+

ALLEGRO_LINE_JOIN

+
typedef enum ALLEGRO_LINE_JOIN
+

Source Code

+
    +
  • ALLEGRO_LINE_JOIN_NONE
  • +
  • ALLEGRO_LINE_JOIN_BEVEL
  • +
  • ALLEGRO_LINE_JOIN_ROUND
  • +
  • ALLEGRO_LINE_JOIN_MITER
  • +
+
+ALLEGRO_LINE_JOIN styles +
+

See the picture for the difference.

+

The maximum miter length (relative to the line width) can be specified as parameter to the polygon functions.

+

Since: 5.1.0

+

See also: al_draw_polygon

+

Examples:

+ +

ALLEGRO_LINE_CAP

+
typedef enum ALLEGRO_LINE_CAP
+

Source Code

+
    +
  • ALLEGRO_LINE_CAP_NONE
  • +
  • ALLEGRO_LINE_CAP_SQUARE
  • +
  • ALLEGRO_LINE_CAP_ROUND
  • +
  • ALLEGRO_LINE_CAP_TRIANGLE
  • +
  • ALLEGRO_LINE_CAP_CLOSED
  • +
+
+ALLEGRO_LINE_CAP styles +
+

See the picture for the difference.

+

ALLEGRO_LINE_CAP_CLOSED is different from the others - it causes the polygon to have no caps. (And the ALLEGRO_LINE_JOIN style will determine how the vertex looks.)

+

Since: 5.1.0

+

See also: al_draw_polygon

+

Examples:

+ +

ALLEGRO_VERTEX_BUFFER

+
typedef struct ALLEGRO_VERTEX_BUFFER ALLEGRO_VERTEX_BUFFER;
+

Source Code

+

A GPU vertex buffer that you can use to store vertices on the GPU instead of uploading them afresh during every drawing operation.

+

Since: 5.1.3

+

See also: al_create_vertex_buffer, al_destroy_vertex_buffer

+

Examples:

+ +

ALLEGRO_INDEX_BUFFER

+
typedef struct ALLEGRO_INDEX_BUFFER ALLEGRO_INDEX_BUFFER;
+

Source Code

+

A GPU index buffer that you can use to store indices of vertices in a vertex buffer on the GPU instead of uploading them afresh during every drawing operation.

+

Since: 5.1.8

+

See also: al_create_index_buffer, al_destroy_index_buffer

+

Examples:

+ +

ALLEGRO_PRIM_BUFFER_FLAGS

+
typedef enum ALLEGRO_PRIM_BUFFER_FLAGS
+

Source Code

+

Flags to specify how to create a vertex or an index buffer.

+
    +
  • ALLEGRO_PRIM_BUFFER_STREAM - Hints to the driver that the buffer is written to often, but used only a few times per frame

  • +
  • ALLEGRO_PRIM_BUFFER_STATIC - Hints to the driver that the buffer is written to once and is used often

  • +
  • ALLEGRO_PRIM_BUFFER_DYNAMIC - Hints to the driver that the buffer is written to often and is used often

  • +
  • ALLEGRO_PRIM_BUFFER_READWRITE - Specifies that you want to be able read from this buffer. By default this is disabled for performance. Some platforms (like OpenGL ES) do not support reading from vertex buffers, so if you pass this flag to al_create_vertex_buffer or al_create_index_buffer the call will fail.

  • +
+

Since: 5.1.3

+

See also: al_create_vertex_buffer, al_create_index_buffer

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:43 UTC +

+
+ + diff --git a/allegro/docs/html/refman/search_index.js b/allegro/docs/html/refman/search_index.js new file mode 100644 index 00000000..40d5fa72 --- /dev/null +++ b/allegro/docs/html/refman/search_index.js @@ -0,0 +1,4 @@ +var search_index = [ +'Getting started guide','Introduction','Structure of the library and its addons','The main function','Initialisation','Opening a window','Display an image','Changing the drawing target','Event queues and input','Displaying some text','Drawing primitives','Blending','Sound','Unstable API','Not the end','Configuration files','Monster description','ALLEGRO_CONFIG','ALLEGRO_CONFIG_SECTION','ALLEGRO_CONFIG_ENTRY','al_create_config','al_destroy_config','al_load_config_file','al_load_config_file_f','al_save_config_file','al_save_config_file_f','al_add_config_section','al_remove_config_section','al_add_config_comment','al_get_config_value','al_set_config_value','al_remove_config_key','al_get_first_config_section','al_get_next_config_section','al_get_first_config_entry','al_get_next_config_entry','al_merge_config','al_merge_config_into','Displays','Display creation','ALLEGRO_DISPLAY','al_create_display','al_destroy_display','al_get_new_display_flags','al_set_new_display_flags','al_get_new_display_option','al_set_new_display_option','al_reset_new_display_options','al_get_new_window_position','al_set_new_window_position','al_get_new_display_refresh_rate','al_set_new_display_refresh_rate','Display operations','al_get_display_event_source','al_get_backbuffer','al_flip_display','al_update_display_region','al_wait_for_vsync','Display size and position','al_get_display_width','al_get_display_height','al_resize_display','al_acknowledge_resize','al_get_window_position','al_set_window_position','al_get_window_constraints','al_set_window_constraints','al_apply_window_constraints','Display settings','al_get_display_flags','al_set_display_flag','al_get_display_option','al_set_display_option','al_get_display_format','al_get_display_orientation','al_get_display_refresh_rate','al_set_window_title','al_set_new_window_title','ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE','al_get_new_window_title','al_set_display_icon','al_set_display_icons','Drawing halts','al_acknowledge_drawing_halt','al_acknowledge_drawing_resume','Screensaver','al_inhibit_screensaver','Clipboard','al_get_clipboard_text','al_set_clipboard_text','al_clipboard_has_text','Event system and events','ALLEGRO_EVENT','ALLEGRO_EVENT_JOYSTICK_AXIS','ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN','ALLEGRO_EVENT_JOYSTICK_BUTTON_UP','ALLEGRO_EVENT_JOYSTICK_CONFIGURATION','ALLEGRO_EVENT_KEY_DOWN','ALLEGRO_EVENT_KEY_UP','ALLEGRO_EVENT_KEY_CHAR','ALLEGRO_EVENT_MOUSE_AXES','ALLEGRO_EVENT_MOUSE_BUTTON_DOWN','ALLEGRO_EVENT_MOUSE_BUTTON_UP','ALLEGRO_EVENT_MOUSE_WARPED','ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY','ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY','ALLEGRO_EVENT_TOUCH_BEGIN','ALLEGRO_EVENT_TOUCH_END','ALLEGRO_EVENT_TOUCH_MOVE','ALLEGRO_EVENT_TOUCH_CANCEL','ALLEGRO_EVENT_TIMER','ALLEGRO_EVENT_DISPLAY_EXPOSE','ALLEGRO_EVENT_DISPLAY_RESIZE','ALLEGRO_EVENT_DISPLAY_CLOSE','ALLEGRO_EVENT_DISPLAY_LOST','ALLEGRO_EVENT_DISPLAY_FOUND','ALLEGRO_EVENT_DISPLAY_SWITCH_OUT','ALLEGRO_EVENT_DISPLAY_SWITCH_IN','ALLEGRO_EVENT_DISPLAY_ORIENTATION','ALLEGRO_EVENT_DISPLAY_HALT_DRAWING','ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING','ALLEGRO_EVENT_DISPLAY_CONNECTED','ALLEGRO_EVENT_DISPLAY_DISCONNECTED','ALLEGRO_USER_EVENT','ALLEGRO_EVENT_QUEUE','ALLEGRO_EVENT_SOURCE','ALLEGRO_EVENT_TYPE','ALLEGRO_GET_EVENT_TYPE','ALLEGRO_EVENT_TYPE_IS_USER','al_create_event_queue','al_destroy_event_queue','al_register_event_source','al_unregister_event_source','al_is_event_source_registered','al_pause_event_queue','al_is_event_queue_paused','al_is_event_queue_empty','al_get_next_event','al_peek_next_event','al_drop_next_event','al_flush_event_queue','al_wait_for_event','al_wait_for_event_timed','al_wait_for_event_until','al_init_user_event_source','al_destroy_user_event_source','al_emit_user_event','al_unref_user_event','al_get_event_source_data','al_set_event_source_data','File I/O','ALLEGRO_FILE','ALLEGRO_FILE_INTERFACE','ALLEGRO_SEEK','al_fopen','al_fopen_interface','al_fopen_slice','al_fclose','al_fread','al_fwrite','al_fflush','al_ftell','al_fseek','al_feof','al_ferror','al_ferrmsg','al_fclearerr','al_fungetc','al_fsize','al_fgetc','al_fputc','al_fprintf','al_vfprintf','al_fread16le','al_fread16be','al_fwrite16le','al_fwrite16be','al_fread32le','al_fread32be','al_fwrite32le','al_fwrite32be','al_fgets','al_fget_ustr','al_fputs','Standard I/O specific routines','al_fopen_fd','al_make_temp_file','Alternative file streams','al_set_new_file_interface','al_set_standard_file_interface','al_get_new_file_interface','al_create_file_handle','al_get_file_userdata','Fixed point math routines','al_fixed','al_itofix','al_fixtoi','al_fixfloor','al_fixceil','al_ftofix','al_fixtof','al_fixmul','al_fixdiv','al_fixadd','al_fixsub','Fixed point trig','al_fixtorad_r','al_radtofix_r','al_fixsin','al_fixcos','al_fixtan','al_fixasin','al_fixacos','al_fixatan','al_fixatan2','al_fixsqrt','al_fixhypot','File system routines','ALLEGRO_FS_ENTRY','ALLEGRO_FILE_MODE','al_create_fs_entry','al_destroy_fs_entry','al_get_fs_entry_name','al_update_fs_entry','al_get_fs_entry_mode','al_get_fs_entry_atime','al_get_fs_entry_ctime','al_get_fs_entry_mtime','al_get_fs_entry_size','al_fs_entry_exists','al_remove_fs_entry','al_filename_exists','al_remove_filename','Directory functions','al_open_directory','al_read_directory','al_close_directory','al_get_current_directory','al_change_directory','al_make_directory','al_open_fs_entry','ALLEGRO_FOR_EACH_FS_ENTRY_RESULT','al_for_each_fs_entry','Alternative filesystem functions','ALLEGRO_FS_INTERFACE','al_set_fs_interface','al_set_standard_fs_interface','al_get_fs_interface','Fullscreen modes','ALLEGRO_DISPLAY_MODE','al_get_display_mode','al_get_num_display_modes','Graphics routines','Colors','ALLEGRO_COLOR','al_map_rgb','al_map_rgb_f','al_map_rgba','al_premul_rgba','al_map_rgba_f','al_premul_rgba_f','al_unmap_rgb','al_unmap_rgb_f','al_unmap_rgba','al_unmap_rgba_f','Locking and pixel formats','ALLEGRO_LOCKED_REGION','ALLEGRO_PIXEL_FORMAT','al_get_pixel_size','al_get_pixel_format_bits','al_get_pixel_block_size','al_get_pixel_block_width','al_get_pixel_block_height','al_lock_bitmap','al_lock_bitmap_region','al_unlock_bitmap','al_lock_bitmap_blocked','al_lock_bitmap_region_blocked','Bitmap creation','ALLEGRO_BITMAP','al_create_bitmap','al_create_sub_bitmap','al_clone_bitmap','al_convert_bitmap','al_convert_memory_bitmaps','al_destroy_bitmap','al_get_new_bitmap_flags','al_get_new_bitmap_format','al_set_new_bitmap_flags','al_add_new_bitmap_flag','al_set_new_bitmap_format','al_set_new_bitmap_depth','al_get_new_bitmap_depth','al_set_new_bitmap_samples','al_get_new_bitmap_samples','Bitmap properties','al_get_bitmap_flags','al_get_bitmap_format','al_get_bitmap_height','al_get_bitmap_width','al_get_bitmap_depth','al_get_bitmap_samples','al_get_pixel','al_is_bitmap_locked','al_is_compatible_bitmap','al_is_sub_bitmap','al_get_parent_bitmap','al_get_bitmap_x','al_get_bitmap_y','al_reparent_bitmap','al_get_bitmap_blender','al_get_separate_bitmap_blender','al_get_bitmap_blend_color','al_set_bitmap_blender','al_set_separate_bitmap_blender','al_set_bitmap_blend_color','al_reset_bitmap_blender','Drawing operations','al_clear_to_color','al_clear_depth_buffer','al_draw_bitmap','al_draw_tinted_bitmap','al_draw_bitmap_region','al_draw_tinted_bitmap_region','al_draw_pixel','al_draw_rotated_bitmap','al_draw_tinted_rotated_bitmap','al_draw_scaled_rotated_bitmap','al_draw_tinted_scaled_rotated_bitmap','al_draw_tinted_scaled_rotated_bitmap_region','al_draw_scaled_bitmap','al_draw_tinted_scaled_bitmap','al_get_target_bitmap','al_put_pixel','al_put_blended_pixel','Target bitmap','al_set_target_bitmap','al_set_target_backbuffer','al_get_current_display','Blending modes','al_get_blender','al_get_separate_blender','al_get_blend_color','al_set_blender','al_set_separate_blender','al_set_blend_color','Clipping','al_get_clipping_rectangle','al_set_clipping_rectangle','al_reset_clipping_rectangle','Graphics utility functions','al_convert_mask_to_alpha','Deferred drawing','al_hold_bitmap_drawing','al_is_bitmap_drawing_held','Image I/O','al_register_bitmap_loader','al_register_bitmap_saver','al_register_bitmap_loader_f','al_register_bitmap_saver_f','al_load_bitmap','al_load_bitmap_flags','al_load_bitmap_f','al_load_bitmap_flags_f','al_save_bitmap','al_save_bitmap_f','al_register_bitmap_identifier','al_identify_bitmap','al_identify_bitmap_f','Render State','ALLEGRO_RENDER_STATE','ALLEGRO_RENDER_FUNCTION','ALLEGRO_WRITE_MASK_FLAGS','al_set_render_state','al_backup_dirty_bitmap','al_backup_dirty_bitmaps','Haptic routines','ALLEGRO_HAPTIC','ALLEGRO_HAPTIC_CONSTANTS','ALLEGRO_HAPTIC_EFFECT','ALLEGRO_HAPTIC_EFFECT_ID','al_install_haptic','al_uninstall_haptic','al_is_haptic_installed','al_is_mouse_haptic','al_is_keyboard_haptic','al_is_display_haptic','al_is_joystick_haptic','al_is_touch_input_haptic','al_get_haptic_from_mouse','al_get_haptic_from_keyboard','al_get_haptic_from_display','al_get_haptic_from_joystick','al_get_haptic_from_touch_input','al_release_haptic','al_is_haptic_active','al_get_haptic_capabilities','al_is_haptic_capable','al_set_haptic_gain','al_get_haptic_gain','al_set_haptic_autocenter','al_get_haptic_autocenter','al_get_max_haptic_effects','al_is_haptic_effect_ok','al_upload_haptic_effect','al_play_haptic_effect','al_upload_and_play_haptic_effect','al_stop_haptic_effect','al_is_haptic_effect_playing','al_get_haptic_effect_duration','al_release_haptic_effect','al_rumble_haptic','Joystick routines','ALLEGRO_JOYSTICK','ALLEGRO_JOYSTICK_STATE','ALLEGRO_JOYFLAGS','al_install_joystick','al_uninstall_joystick','al_is_joystick_installed','al_reconfigure_joysticks','al_get_num_joysticks','al_get_joystick','al_release_joystick','al_get_joystick_active','al_get_joystick_name','al_get_joystick_stick_name','al_get_joystick_axis_name','al_get_joystick_button_name','al_get_joystick_stick_flags','al_get_joystick_num_sticks','al_get_joystick_num_axes','al_get_joystick_num_buttons','al_get_joystick_state','al_get_joystick_event_source','Keyboard routines','ALLEGRO_KEYBOARD_STATE','Key codes','Keyboard modifier flags','al_install_keyboard','al_is_keyboard_installed','al_uninstall_keyboard','al_get_keyboard_state','al_clear_keyboard_state','al_key_down','al_keycode_to_name','al_set_keyboard_leds','al_get_keyboard_event_source','Memory management routines','al_malloc','al_free','al_realloc','al_calloc','al_malloc_with_context','al_free_with_context','al_realloc_with_context','al_calloc_with_context','ALLEGRO_MEMORY_INTERFACE','al_set_memory_interface','Miscellaneous routines','ALLEGRO_PI','al_run_main','Monitors','ALLEGRO_MONITOR_INFO','al_get_new_display_adapter','al_set_new_display_adapter','al_get_monitor_info','al_get_monitor_dpi','al_get_num_video_adapters','al_get_monitor_refresh_rate','Mouse routines','ALLEGRO_MOUSE_STATE','al_install_mouse','al_is_mouse_installed','al_uninstall_mouse','al_get_mouse_num_axes','al_get_mouse_num_buttons','al_get_mouse_state','al_get_mouse_state_axis','al_mouse_button_down','al_set_mouse_xy','al_set_mouse_z','al_set_mouse_w','al_set_mouse_axis','al_get_mouse_event_source','al_set_mouse_wheel_precision','al_get_mouse_wheel_precision','Mouse cursors','al_create_mouse_cursor','al_destroy_mouse_cursor','al_set_mouse_cursor','al_set_system_mouse_cursor','al_get_mouse_cursor_position','al_hide_mouse_cursor','al_show_mouse_cursor','al_grab_mouse','al_ungrab_mouse','Path structures','al_create_path','al_create_path_for_directory','al_destroy_path','al_clone_path','al_join_paths','al_rebase_path','al_get_path_drive','al_get_path_num_components','al_get_path_component','al_get_path_tail','al_get_path_filename','al_get_path_basename','al_get_path_extension','al_set_path_drive','al_append_path_component','al_insert_path_component','al_replace_path_component','al_remove_path_component','al_drop_path_tail','al_set_path_filename','al_set_path_extension','al_path_cstr','al_path_ustr','al_make_path_canonical','State','ALLEGRO_STATE','ALLEGRO_STATE_FLAGS','al_restore_state','al_store_state','al_get_errno','al_set_errno','System routines','al_install_system','al_init','al_uninstall_system','al_is_system_installed','al_get_allegro_version','al_get_standard_path','al_set_exe_name','al_set_app_name','al_set_org_name','al_get_app_name','al_get_org_name','al_get_system_config','al_get_system_id','al_register_assert_handler','al_register_trace_handler','al_get_cpu_count','al_get_ram_size','ALLEGRO_SYSTEM_ID','Threads','ALLEGRO_THREAD','ALLEGRO_MUTEX','ALLEGRO_COND','al_create_thread','al_create_thread_with_stacksize','al_start_thread','al_join_thread','al_set_thread_should_stop','al_get_thread_should_stop','al_destroy_thread','al_run_detached_thread','al_create_mutex','al_create_mutex_recursive','al_lock_mutex','al_unlock_mutex','al_destroy_mutex','al_create_cond','al_destroy_cond','al_wait_cond','al_wait_cond_until','al_broadcast_cond','al_signal_cond','Time routines','ALLEGRO_TIMEOUT','al_get_time','al_init_timeout','al_rest','Timer routines','ALLEGRO_TIMER','ALLEGRO_USECS_TO_SECS','ALLEGRO_MSECS_TO_SECS','ALLEGRO_BPS_TO_SECS','ALLEGRO_BPM_TO_SECS','al_create_timer','al_start_timer','al_resume_timer','al_stop_timer','al_get_timer_started','al_destroy_timer','al_get_timer_count','al_set_timer_count','al_add_timer_count','al_get_timer_speed','al_set_timer_speed','al_get_timer_event_source','Touch input','ALLEGRO_TOUCH_INPUT','ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT','ALLEGRO_TOUCH_STATE','ALLEGRO_TOUCH_INPUT_STATE','ALLEGRO_MOUSE_EMULATION_MODE','al_install_touch_input','al_uninstall_touch_input','al_is_touch_input_installed','al_get_touch_input_state','al_set_mouse_emulation_mode','al_get_mouse_emulation_mode','al_get_touch_input_event_source','al_get_touch_input_mouse_emulation_event_source','Transformations','ALLEGRO_TRANSFORM','al_copy_transform','al_use_transform','al_get_current_transform','al_use_projection_transform','al_get_current_projection_transform','al_get_current_inverse_transform','al_invert_transform','al_transpose_transform','al_check_inverse','al_identity_transform','al_build_transform','al_build_camera_transform','al_translate_transform','al_rotate_transform','al_scale_transform','al_transform_coordinates','al_transform_coordinates_3d','al_transform_coordinates_4d','al_transform_coordinates_3d_projective','al_compose_transform','al_orthographic_transform','al_perspective_transform','al_translate_transform_3d','al_scale_transform_3d','al_rotate_transform_3d','al_horizontal_shear_transform','al_vertical_shear_transform','UTF-8 string routines','About UTF-8 string routines','UTF-8 string types','ALLEGRO_USTR','ALLEGRO_USTR_INFO','Creating and destroying strings','al_ustr_new','al_ustr_new_from_buffer','al_ustr_newf','al_ustr_free','al_cstr','al_ustr_to_buffer','al_cstr_dup','al_ustr_dup','al_ustr_dup_substr','Predefined strings','al_ustr_empty_string','Creating strings by referencing other data','al_ref_cstr','al_ref_buffer','al_ref_ustr','Sizes and offsets','al_ustr_size','al_ustr_length','al_ustr_offset','al_ustr_next','al_ustr_prev','Getting code points','al_ustr_get','al_ustr_get_next','al_ustr_prev_get','Inserting into strings','al_ustr_insert','al_ustr_insert_cstr','al_ustr_insert_chr','Appending to strings','al_ustr_append','al_ustr_append_cstr','al_ustr_append_chr','al_ustr_appendf','al_ustr_vappendf','Removing parts of strings','al_ustr_remove_chr','al_ustr_remove_range','al_ustr_truncate','al_ustr_ltrim_ws','al_ustr_rtrim_ws','al_ustr_trim_ws','Assigning one string to another','al_ustr_assign','al_ustr_assign_substr','al_ustr_assign_cstr','Replacing parts of string','al_ustr_set_chr','al_ustr_replace_range','Searching','al_ustr_find_chr','al_ustr_rfind_chr','al_ustr_find_set','al_ustr_find_set_cstr','al_ustr_find_cset','al_ustr_find_cset_cstr','al_ustr_find_str','al_ustr_find_cstr','al_ustr_rfind_str','al_ustr_rfind_cstr','al_ustr_find_replace','al_ustr_find_replace_cstr','Comparing','al_ustr_equal','al_ustr_compare','al_ustr_ncompare','al_ustr_has_prefix','al_ustr_has_prefix_cstr','al_ustr_has_suffix','al_ustr_has_suffix_cstr','UTF-16 conversion','al_ustr_new_from_utf16','al_ustr_size_utf16','al_ustr_encode_utf16','Low-level UTF-8 routines','al_utf8_width','al_utf8_encode','Low-level UTF-16 routines','al_utf16_width','al_utf16_encode','Platform-specific functions','Windows','al_get_win_window_handle','al_win_add_window_callback','al_win_remove_window_callback','Mac OS X','al_osx_get_window','iPhone','al_iphone_set_statusbar_orientation','al_iphone_get_view','al_iphone_get_window','Android','al_android_set_apk_file_interface','al_android_set_apk_fs_interface','al_android_get_os_version','al_android_get_jni_env','al_android_get_activity','X11','al_get_x_window_id','al_x_set_initial_icon','Direct3D integration','al_get_d3d_device','al_get_d3d_system_texture','al_get_d3d_video_texture','al_have_d3d_non_pow2_texture_support','al_have_d3d_non_square_texture_support','al_get_d3d_texture_size','al_get_d3d_texture_position','al_is_d3d_device_lost','al_set_d3d_device_release_callback','al_set_d3d_device_restore_callback','OpenGL integration','al_get_opengl_extension_list','al_get_opengl_proc_address','al_get_opengl_texture','al_get_opengl_texture_size','al_get_opengl_texture_position','al_get_opengl_program_object','al_get_opengl_fbo','al_remove_opengl_fbo','al_have_opengl_extension','al_get_opengl_version','al_get_opengl_variant','al_set_current_opengl_context','OpenGL configuration','Audio addon','Audio types','ALLEGRO_AUDIO_EVENT_TYPE','ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT','ALLEGRO_EVENT_AUDIO_STREAM_FINISHED','ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT','ALLEGRO_AUDIO_DEPTH','ALLEGRO_AUDIO_PAN_NONE','ALLEGRO_CHANNEL_CONF','ALLEGRO_MIXER','ALLEGRO_MIXER_QUALITY','ALLEGRO_PLAYMODE','ALLEGRO_SAMPLE_ID','ALLEGRO_SAMPLE','ALLEGRO_SAMPLE_INSTANCE','ALLEGRO_AUDIO_STREAM','ALLEGRO_VOICE','Setting up audio','al_install_audio','al_uninstall_audio','al_is_audio_installed','al_reserve_samples','Misc audio functions','al_get_allegro_audio_version','al_get_audio_depth_size','al_get_channel_count','al_fill_silence','Voice functions','al_create_voice','al_destroy_voice','al_detach_voice','al_attach_audio_stream_to_voice','al_attach_mixer_to_voice','al_attach_sample_instance_to_voice','al_get_voice_frequency','al_get_voice_channels','al_get_voice_depth','al_get_voice_playing','al_set_voice_playing','al_get_voice_position','al_set_voice_position','Sample functions','al_create_sample','al_destroy_sample','al_play_sample','al_stop_sample','al_lock_sample_id','al_unlock_sample_id','al_stop_samples','al_get_sample_channels','al_get_sample_depth','al_get_sample_frequency','al_get_sample_length','al_get_sample_data','Sample instance functions','al_create_sample_instance','al_destroy_sample_instance','al_play_sample_instance','al_stop_sample_instance','al_get_sample_instance_channels','al_get_sample_instance_depth','al_get_sample_instance_frequency','al_get_sample_instance_length','al_set_sample_instance_length','al_get_sample_instance_position','al_set_sample_instance_position','al_get_sample_instance_speed','al_set_sample_instance_speed','al_get_sample_instance_gain','al_set_sample_instance_gain','al_get_sample_instance_pan','al_set_sample_instance_pan','al_get_sample_instance_time','al_get_sample_instance_playmode','al_set_sample_instance_playmode','al_get_sample_instance_playing','al_set_sample_instance_playing','al_get_sample_instance_attached','al_detach_sample_instance','al_get_sample','al_set_sample','al_set_sample_instance_channel_matrix','Mixer functions','al_create_mixer','al_destroy_mixer','al_get_default_mixer','al_set_default_mixer','al_restore_default_mixer','al_get_default_voice','al_set_default_voice','al_attach_mixer_to_mixer','al_attach_sample_instance_to_mixer','al_attach_audio_stream_to_mixer','al_get_mixer_frequency','al_set_mixer_frequency','al_get_mixer_channels','al_get_mixer_depth','al_get_mixer_gain','al_set_mixer_gain','al_get_mixer_quality','al_set_mixer_quality','al_get_mixer_playing','al_set_mixer_playing','al_get_mixer_attached','al_detach_mixer','al_set_mixer_postprocess_callback','Stream functions','al_create_audio_stream','al_destroy_audio_stream','al_get_audio_stream_event_source','al_drain_audio_stream','al_rewind_audio_stream','al_get_audio_stream_frequency','al_get_audio_stream_channels','al_get_audio_stream_depth','al_get_audio_stream_length','al_get_audio_stream_speed','al_set_audio_stream_speed','al_get_audio_stream_gain','al_set_audio_stream_gain','al_get_audio_stream_pan','al_set_audio_stream_pan','al_get_audio_stream_playing','al_set_audio_stream_playing','al_get_audio_stream_playmode','al_set_audio_stream_playmode','al_get_audio_stream_attached','al_detach_audio_stream','al_get_audio_stream_played_samples','al_get_audio_stream_fragment','al_set_audio_stream_fragment','al_get_audio_stream_fragments','al_get_available_audio_stream_fragments','al_seek_audio_stream_secs','al_get_audio_stream_position_secs','al_get_audio_stream_length_secs','al_set_audio_stream_loop_secs','al_set_audio_stream_channel_matrix','Audio file I/O','al_register_sample_loader','al_register_sample_loader_f','al_register_sample_saver','al_register_sample_saver_f','al_register_audio_stream_loader','al_register_audio_stream_loader_f','al_load_sample','al_load_sample_f','al_load_audio_stream','al_load_audio_stream_f','al_save_sample','al_save_sample_f','Audio recording','ALLEGRO_AUDIO_RECORDER','ALLEGRO_AUDIO_RECORDER_EVENT','al_create_audio_recorder','al_start_audio_recorder','al_stop_audio_recorder','al_is_audio_recorder_recording','al_get_audio_recorder_event','al_get_audio_recorder_event_source','al_destroy_audio_recorder','Audio codecs addon','al_init_acodec_addon','al_is_acodec_addon_initialized','al_get_allegro_acodec_version','Color addon','al_color_cmyk','al_color_cmyk_to_rgb','al_color_hsl','al_color_hsl_to_rgb','al_color_hsv','al_color_hsv_to_rgb','al_color_html','al_color_html_to_rgb','al_color_rgb_to_html','al_color_name','al_color_name_to_rgb','al_color_rgb_to_cmyk','al_color_rgb_to_hsl','al_color_rgb_to_hsv','al_color_rgb_to_name','al_color_rgb_to_xyz','al_color_xyz','al_color_xyz_to_rgb','al_color_rgb_to_xyy','al_color_xyy','al_color_xyy_to_rgb','al_color_rgb_to_lab','al_color_lab','al_color_lab_to_rgb','al_color_rgb_to_lch','al_color_lch','al_color_lch_to_rgb','al_color_distance_ciede2000','al_color_rgb_to_yuv','al_color_yuv','al_color_yuv_to_rgb','al_get_allegro_color_version','al_is_color_valid','Font addons','General font routines','ALLEGRO_FONT','ALLEGRO_GLYPH','al_init_font_addon','al_is_font_addon_initialized','al_shutdown_font_addon','al_load_font','al_destroy_font','al_register_font_loader','al_get_font_line_height','al_get_font_ascent','al_get_font_descent','al_get_text_width','al_get_ustr_width','al_draw_text','al_draw_ustr','al_draw_justified_text','al_draw_justified_ustr','al_draw_textf','al_draw_justified_textf','al_get_text_dimensions','al_get_ustr_dimensions','al_get_allegro_font_version','al_get_font_ranges','al_set_fallback_font','al_get_fallback_font','Per glyph text handling','al_draw_glyph','al_get_glyph_width','al_get_glyph_dimensions','al_get_glyph_advance','Multiline text drawing','al_draw_multiline_text','al_draw_multiline_ustr','al_draw_multiline_textf','al_do_multiline_text','al_do_multiline_ustr','Bitmap fonts','al_grab_font_from_bitmap','al_load_bitmap_font','al_load_bitmap_font_flags','al_create_builtin_font','TTF fonts','al_init_ttf_addon','al_is_ttf_addon_initialized','al_shutdown_ttf_addon','al_load_ttf_font','al_load_ttf_font_f','al_load_ttf_font_stretch','al_load_ttf_font_stretch_f','al_get_allegro_ttf_version','al_get_glyph','Image I/O addon','al_init_image_addon','al_is_image_addon_initialized','al_shutdown_image_addon','al_get_allegro_image_version','Main addon','Memfile interface','al_open_memfile','al_get_allegro_memfile_version','Native dialogs support','ALLEGRO_FILECHOOSER','ALLEGRO_TEXTLOG','al_init_native_dialog_addon','al_is_native_dialog_addon_initialized','al_shutdown_native_dialog_addon','al_create_native_file_dialog','al_show_native_file_dialog','al_get_native_file_dialog_count','al_get_native_file_dialog_path','al_destroy_native_file_dialog','al_show_native_message_box','al_open_native_text_log','al_close_native_text_log','al_append_native_text_log','al_get_native_text_log_event_source','al_get_allegro_native_dialog_version','Menus','ALLEGRO_MENU','ALLEGRO_MENU_INFO','al_create_menu','al_create_popup_menu','al_build_menu','al_append_menu_item','al_insert_menu_item','al_remove_menu_item','al_clone_menu','al_clone_menu_for_popup','al_destroy_menu','al_get_menu_item_caption','al_set_menu_item_caption','al_get_menu_item_flags','al_set_menu_item_flags','al_toggle_menu_item_flags','al_get_menu_item_icon','al_set_menu_item_icon','al_find_menu','al_find_menu_item','al_get_default_menu_event_source','al_enable_menu_event_source','al_disable_menu_event_source','al_get_display_menu','al_set_display_menu','al_popup_menu','al_remove_display_menu','PhysicsFS integration','al_set_physfs_file_interface','al_get_allegro_physfs_version','Primitives addon','General','al_get_allegro_primitives_version','al_init_primitives_addon','al_is_primitives_addon_initialized','al_shutdown_primitives_addon','High level drawing routines','Pixel-precise output','al_draw_line','al_draw_triangle','al_draw_filled_triangle','al_draw_rectangle','al_draw_filled_rectangle','al_draw_rounded_rectangle','al_draw_filled_rounded_rectangle','al_calculate_arc','al_draw_pieslice','al_draw_filled_pieslice','al_draw_ellipse','al_draw_filled_ellipse','al_draw_circle','al_draw_filled_circle','al_draw_arc','al_draw_elliptical_arc','al_calculate_spline','al_draw_spline','al_calculate_ribbon','al_draw_ribbon','Low level drawing routines','al_draw_prim','al_draw_indexed_prim','al_draw_vertex_buffer','al_draw_indexed_buffer','al_draw_soft_triangle','al_draw_soft_line','Custom vertex declaration routines','al_create_vertex_decl','al_destroy_vertex_decl','Vertex buffer routines','al_create_vertex_buffer','al_destroy_vertex_buffer','al_lock_vertex_buffer','al_unlock_vertex_buffer','al_get_vertex_buffer_size','Index buffer routines','al_create_index_buffer','al_destroy_index_buffer','al_lock_index_buffer','al_unlock_index_buffer','al_get_index_buffer_size','Polygon routines','al_draw_polyline','al_draw_polygon','al_draw_filled_polygon','al_draw_filled_polygon_with_holes','al_triangulate_polygon','Structures and types','ALLEGRO_VERTEX','ALLEGRO_VERTEX_DECL','ALLEGRO_VERTEX_ELEMENT','ALLEGRO_PRIM_TYPE','ALLEGRO_PRIM_ATTR','ALLEGRO_PRIM_STORAGE','ALLEGRO_VERTEX_CACHE_SIZE','ALLEGRO_PRIM_QUALITY','ALLEGRO_LINE_JOIN','ALLEGRO_LINE_CAP','ALLEGRO_VERTEX_BUFFER','ALLEGRO_INDEX_BUFFER','ALLEGRO_PRIM_BUFFER_FLAGS','Shader routines','ALLEGRO_SHADER','ALLEGRO_SHADER_TYPE','ALLEGRO_SHADER_PLATFORM','al_create_shader','al_attach_shader_source','al_attach_shader_source_file','al_build_shader','al_get_shader_log','al_get_shader_platform','al_use_shader','al_destroy_shader','al_set_shader_sampler','al_set_shader_matrix','al_set_shader_int','al_set_shader_float','al_set_shader_bool','al_set_shader_int_vector','al_set_shader_float_vector','al_get_default_shader_source','Video streaming addon','ALLEGRO_VIDEO_EVENT_TYPE','ALLEGRO_EVENT_VIDEO_FRAME_SHOW','ALLEGRO_EVENT_VIDEO_FINISHED','ALLEGRO_VIDEO_POSITION_TYPE','al_init_video_addon','al_is_video_addon_initialized','al_shutdown_video_addon','al_get_allegro_video_version','al_open_video','al_close_video','al_start_video','al_start_video_with_voice','al_get_video_event_source','al_set_video_playing','al_is_video_playing','al_get_video_audio_rate','al_get_video_fps','al_get_video_scaled_width','al_get_video_scaled_height','al_get_video_frame','al_get_video_position','al_seek_video',] +var search_urls = [ +'getting_started.html#getting-started-guide','getting_started.html#introduction','getting_started.html#structure-of-the-library-and-its-addons','getting_started.html#the-main-function','getting_started.html#initialisation','getting_started.html#opening-a-window','getting_started.html#display-an-image','getting_started.html#changing-the-drawing-target','getting_started.html#event-queues-and-input','getting_started.html#displaying-some-text','getting_started.html#drawing-primitives','getting_started.html#blending','getting_started.html#sound','getting_started.html#unstable-api','getting_started.html#not-the-end','config.html#configuration-files','config.html#monster-description','config.html#allegro_config','config.html#allegro_config_section','config.html#allegro_config_entry','config.html#al_create_config','config.html#al_destroy_config','config.html#al_load_config_file','config.html#al_load_config_file_f','config.html#al_save_config_file','config.html#al_save_config_file_f','config.html#al_add_config_section','config.html#al_remove_config_section','config.html#al_add_config_comment','config.html#al_get_config_value','config.html#al_set_config_value','config.html#al_remove_config_key','config.html#al_get_first_config_section','config.html#al_get_next_config_section','config.html#al_get_first_config_entry','config.html#al_get_next_config_entry','config.html#al_merge_config','config.html#al_merge_config_into','display.html#displays','display.html#display-creation','display.html#allegro_display','display.html#al_create_display','display.html#al_destroy_display','display.html#al_get_new_display_flags','display.html#al_set_new_display_flags','display.html#al_get_new_display_option','display.html#al_set_new_display_option','display.html#al_reset_new_display_options','display.html#al_get_new_window_position','display.html#al_set_new_window_position','display.html#al_get_new_display_refresh_rate','display.html#al_set_new_display_refresh_rate','display.html#display-operations','display.html#al_get_display_event_source','display.html#al_get_backbuffer','display.html#al_flip_display','display.html#al_update_display_region','display.html#al_wait_for_vsync','display.html#display-size-and-position','display.html#al_get_display_width','display.html#al_get_display_height','display.html#al_resize_display','display.html#al_acknowledge_resize','display.html#al_get_window_position','display.html#al_set_window_position','display.html#al_get_window_constraints','display.html#al_set_window_constraints','display.html#al_apply_window_constraints','display.html#display-settings','display.html#al_get_display_flags','display.html#al_set_display_flag','display.html#al_get_display_option','display.html#al_set_display_option','display.html#al_get_display_format','display.html#al_get_display_orientation','display.html#al_get_display_refresh_rate','display.html#al_set_window_title','display.html#al_set_new_window_title','display.html#allegro_new_window_title_max_size','display.html#al_get_new_window_title','display.html#al_set_display_icon','display.html#al_set_display_icons','display.html#drawing-halts','display.html#al_acknowledge_drawing_halt','display.html#al_acknowledge_drawing_resume','display.html#screensaver','display.html#al_inhibit_screensaver','display.html#clipboard','display.html#al_get_clipboard_text','display.html#al_set_clipboard_text','display.html#al_clipboard_has_text','events.html#event-system-and-events','events.html#allegro_event','events.html#allegro_event_joystick_axis','events.html#allegro_event_joystick_button_down','events.html#allegro_event_joystick_button_up','events.html#allegro_event_joystick_configuration','events.html#allegro_event_key_down','events.html#allegro_event_key_up','events.html#allegro_event_key_char','events.html#allegro_event_mouse_axes','events.html#allegro_event_mouse_button_down','events.html#allegro_event_mouse_button_up','events.html#allegro_event_mouse_warped','events.html#allegro_event_mouse_enter_display','events.html#allegro_event_mouse_leave_display','events.html#allegro_event_touch_begin','events.html#allegro_event_touch_end','events.html#allegro_event_touch_move','events.html#allegro_event_touch_cancel','events.html#allegro_event_timer','events.html#allegro_event_display_expose','events.html#allegro_event_display_resize','events.html#allegro_event_display_close','events.html#allegro_event_display_lost','events.html#allegro_event_display_found','events.html#allegro_event_display_switch_out','events.html#allegro_event_display_switch_in','events.html#allegro_event_display_orientation','events.html#allegro_event_display_halt_drawing','events.html#allegro_event_display_resume_drawing','events.html#allegro_event_display_connected','events.html#allegro_event_display_disconnected','events.html#allegro_user_event','events.html#allegro_event_queue','events.html#allegro_event_source','events.html#allegro_event_type','events.html#allegro_get_event_type','events.html#allegro_event_type_is_user','events.html#al_create_event_queue','events.html#al_destroy_event_queue','events.html#al_register_event_source','events.html#al_unregister_event_source','events.html#al_is_event_source_registered','events.html#al_pause_event_queue','events.html#al_is_event_queue_paused','events.html#al_is_event_queue_empty','events.html#al_get_next_event','events.html#al_peek_next_event','events.html#al_drop_next_event','events.html#al_flush_event_queue','events.html#al_wait_for_event','events.html#al_wait_for_event_timed','events.html#al_wait_for_event_until','events.html#al_init_user_event_source','events.html#al_destroy_user_event_source','events.html#al_emit_user_event','events.html#al_unref_user_event','events.html#al_get_event_source_data','events.html#al_set_event_source_data','file.html#file-i/o','file.html#allegro_file','file.html#allegro_file_interface','file.html#allegro_seek','file.html#al_fopen','file.html#al_fopen_interface','file.html#al_fopen_slice','file.html#al_fclose','file.html#al_fread','file.html#al_fwrite','file.html#al_fflush','file.html#al_ftell','file.html#al_fseek','file.html#al_feof','file.html#al_ferror','file.html#al_ferrmsg','file.html#al_fclearerr','file.html#al_fungetc','file.html#al_fsize','file.html#al_fgetc','file.html#al_fputc','file.html#al_fprintf','file.html#al_vfprintf','file.html#al_fread16le','file.html#al_fread16be','file.html#al_fwrite16le','file.html#al_fwrite16be','file.html#al_fread32le','file.html#al_fread32be','file.html#al_fwrite32le','file.html#al_fwrite32be','file.html#al_fgets','file.html#al_fget_ustr','file.html#al_fputs','file.html#standard-i/o-specific-routines','file.html#al_fopen_fd','file.html#al_make_temp_file','file.html#alternative-file-streams','file.html#al_set_new_file_interface','file.html#al_set_standard_file_interface','file.html#al_get_new_file_interface','file.html#al_create_file_handle','file.html#al_get_file_userdata','fixed.html#fixed-point-math-routines','fixed.html#al_fixed','fixed.html#al_itofix','fixed.html#al_fixtoi','fixed.html#al_fixfloor','fixed.html#al_fixceil','fixed.html#al_ftofix','fixed.html#al_fixtof','fixed.html#al_fixmul','fixed.html#al_fixdiv','fixed.html#al_fixadd','fixed.html#al_fixsub','fixed.html#fixed-point-trig','fixed.html#al_fixtorad_r','fixed.html#al_radtofix_r','fixed.html#al_fixsin','fixed.html#al_fixcos','fixed.html#al_fixtan','fixed.html#al_fixasin','fixed.html#al_fixacos','fixed.html#al_fixatan','fixed.html#al_fixatan2','fixed.html#al_fixsqrt','fixed.html#al_fixhypot','fshook.html#file-system-routines','fshook.html#allegro_fs_entry','fshook.html#allegro_file_mode','fshook.html#al_create_fs_entry','fshook.html#al_destroy_fs_entry','fshook.html#al_get_fs_entry_name','fshook.html#al_update_fs_entry','fshook.html#al_get_fs_entry_mode','fshook.html#al_get_fs_entry_atime','fshook.html#al_get_fs_entry_ctime','fshook.html#al_get_fs_entry_mtime','fshook.html#al_get_fs_entry_size','fshook.html#al_fs_entry_exists','fshook.html#al_remove_fs_entry','fshook.html#al_filename_exists','fshook.html#al_remove_filename','fshook.html#directory-functions','fshook.html#al_open_directory','fshook.html#al_read_directory','fshook.html#al_close_directory','fshook.html#al_get_current_directory','fshook.html#al_change_directory','fshook.html#al_make_directory','fshook.html#al_open_fs_entry','fshook.html#allegro_for_each_fs_entry_result','fshook.html#al_for_each_fs_entry','fshook.html#alternative-filesystem-functions','fshook.html#allegro_fs_interface','fshook.html#al_set_fs_interface','fshook.html#al_set_standard_fs_interface','fshook.html#al_get_fs_interface','fullscreen_mode.html#fullscreen-modes','fullscreen_mode.html#allegro_display_mode','fullscreen_mode.html#al_get_display_mode','fullscreen_mode.html#al_get_num_display_modes','graphics.html#graphics-routines','graphics.html#colors','graphics.html#allegro_color','graphics.html#al_map_rgb','graphics.html#al_map_rgb_f','graphics.html#al_map_rgba','graphics.html#al_premul_rgba','graphics.html#al_map_rgba_f','graphics.html#al_premul_rgba_f','graphics.html#al_unmap_rgb','graphics.html#al_unmap_rgb_f','graphics.html#al_unmap_rgba','graphics.html#al_unmap_rgba_f','graphics.html#locking-and-pixel-formats','graphics.html#allegro_locked_region','graphics.html#allegro_pixel_format','graphics.html#al_get_pixel_size','graphics.html#al_get_pixel_format_bits','graphics.html#al_get_pixel_block_size','graphics.html#al_get_pixel_block_width','graphics.html#al_get_pixel_block_height','graphics.html#al_lock_bitmap','graphics.html#al_lock_bitmap_region','graphics.html#al_unlock_bitmap','graphics.html#al_lock_bitmap_blocked','graphics.html#al_lock_bitmap_region_blocked','graphics.html#bitmap-creation','graphics.html#allegro_bitmap','graphics.html#al_create_bitmap','graphics.html#al_create_sub_bitmap','graphics.html#al_clone_bitmap','graphics.html#al_convert_bitmap','graphics.html#al_convert_memory_bitmaps','graphics.html#al_destroy_bitmap','graphics.html#al_get_new_bitmap_flags','graphics.html#al_get_new_bitmap_format','graphics.html#al_set_new_bitmap_flags','graphics.html#al_add_new_bitmap_flag','graphics.html#al_set_new_bitmap_format','graphics.html#al_set_new_bitmap_depth','graphics.html#al_get_new_bitmap_depth','graphics.html#al_set_new_bitmap_samples','graphics.html#al_get_new_bitmap_samples','graphics.html#bitmap-properties','graphics.html#al_get_bitmap_flags','graphics.html#al_get_bitmap_format','graphics.html#al_get_bitmap_height','graphics.html#al_get_bitmap_width','graphics.html#al_get_bitmap_depth','graphics.html#al_get_bitmap_samples','graphics.html#al_get_pixel','graphics.html#al_is_bitmap_locked','graphics.html#al_is_compatible_bitmap','graphics.html#al_is_sub_bitmap','graphics.html#al_get_parent_bitmap','graphics.html#al_get_bitmap_x','graphics.html#al_get_bitmap_y','graphics.html#al_reparent_bitmap','graphics.html#al_get_bitmap_blender','graphics.html#al_get_separate_bitmap_blender','graphics.html#al_get_bitmap_blend_color','graphics.html#al_set_bitmap_blender','graphics.html#al_set_separate_bitmap_blender','graphics.html#al_set_bitmap_blend_color','graphics.html#al_reset_bitmap_blender','graphics.html#drawing-operations','graphics.html#al_clear_to_color','graphics.html#al_clear_depth_buffer','graphics.html#al_draw_bitmap','graphics.html#al_draw_tinted_bitmap','graphics.html#al_draw_bitmap_region','graphics.html#al_draw_tinted_bitmap_region','graphics.html#al_draw_pixel','graphics.html#al_draw_rotated_bitmap','graphics.html#al_draw_tinted_rotated_bitmap','graphics.html#al_draw_scaled_rotated_bitmap','graphics.html#al_draw_tinted_scaled_rotated_bitmap','graphics.html#al_draw_tinted_scaled_rotated_bitmap_region','graphics.html#al_draw_scaled_bitmap','graphics.html#al_draw_tinted_scaled_bitmap','graphics.html#al_get_target_bitmap','graphics.html#al_put_pixel','graphics.html#al_put_blended_pixel','graphics.html#target-bitmap','graphics.html#al_set_target_bitmap','graphics.html#al_set_target_backbuffer','graphics.html#al_get_current_display','graphics.html#blending-modes','graphics.html#al_get_blender','graphics.html#al_get_separate_blender','graphics.html#al_get_blend_color','graphics.html#al_set_blender','graphics.html#al_set_separate_blender','graphics.html#al_set_blend_color','graphics.html#clipping','graphics.html#al_get_clipping_rectangle','graphics.html#al_set_clipping_rectangle','graphics.html#al_reset_clipping_rectangle','graphics.html#graphics-utility-functions','graphics.html#al_convert_mask_to_alpha','graphics.html#deferred-drawing','graphics.html#al_hold_bitmap_drawing','graphics.html#al_is_bitmap_drawing_held','graphics.html#image-i/o','graphics.html#al_register_bitmap_loader','graphics.html#al_register_bitmap_saver','graphics.html#al_register_bitmap_loader_f','graphics.html#al_register_bitmap_saver_f','graphics.html#al_load_bitmap','graphics.html#al_load_bitmap_flags','graphics.html#al_load_bitmap_f','graphics.html#al_load_bitmap_flags_f','graphics.html#al_save_bitmap','graphics.html#al_save_bitmap_f','graphics.html#al_register_bitmap_identifier','graphics.html#al_identify_bitmap','graphics.html#al_identify_bitmap_f','graphics.html#render-state','graphics.html#allegro_render_state','graphics.html#allegro_render_function','graphics.html#allegro_write_mask_flags','graphics.html#al_set_render_state','graphics.html#al_backup_dirty_bitmap','graphics.html#al_backup_dirty_bitmaps','haptic.html#haptic-routines','haptic.html#allegro_haptic','haptic.html#allegro_haptic_constants','haptic.html#allegro_haptic_effect','haptic.html#allegro_haptic_effect_id','haptic.html#al_install_haptic','haptic.html#al_uninstall_haptic','haptic.html#al_is_haptic_installed','haptic.html#al_is_mouse_haptic','haptic.html#al_is_keyboard_haptic','haptic.html#al_is_display_haptic','haptic.html#al_is_joystick_haptic','haptic.html#al_is_touch_input_haptic','haptic.html#al_get_haptic_from_mouse','haptic.html#al_get_haptic_from_keyboard','haptic.html#al_get_haptic_from_display','haptic.html#al_get_haptic_from_joystick','haptic.html#al_get_haptic_from_touch_input','haptic.html#al_release_haptic','haptic.html#al_is_haptic_active','haptic.html#al_get_haptic_capabilities','haptic.html#al_is_haptic_capable','haptic.html#al_set_haptic_gain','haptic.html#al_get_haptic_gain','haptic.html#al_set_haptic_autocenter','haptic.html#al_get_haptic_autocenter','haptic.html#al_get_max_haptic_effects','haptic.html#al_is_haptic_effect_ok','haptic.html#al_upload_haptic_effect','haptic.html#al_play_haptic_effect','haptic.html#al_upload_and_play_haptic_effect','haptic.html#al_stop_haptic_effect','haptic.html#al_is_haptic_effect_playing','haptic.html#al_get_haptic_effect_duration','haptic.html#al_release_haptic_effect','haptic.html#al_rumble_haptic','joystick.html#joystick-routines','joystick.html#allegro_joystick','joystick.html#allegro_joystick_state','joystick.html#allegro_joyflags','joystick.html#al_install_joystick','joystick.html#al_uninstall_joystick','joystick.html#al_is_joystick_installed','joystick.html#al_reconfigure_joysticks','joystick.html#al_get_num_joysticks','joystick.html#al_get_joystick','joystick.html#al_release_joystick','joystick.html#al_get_joystick_active','joystick.html#al_get_joystick_name','joystick.html#al_get_joystick_stick_name','joystick.html#al_get_joystick_axis_name','joystick.html#al_get_joystick_button_name','joystick.html#al_get_joystick_stick_flags','joystick.html#al_get_joystick_num_sticks','joystick.html#al_get_joystick_num_axes','joystick.html#al_get_joystick_num_buttons','joystick.html#al_get_joystick_state','joystick.html#al_get_joystick_event_source','keyboard.html#keyboard-routines','keyboard.html#allegro_keyboard_state','keyboard.html#key-codes','keyboard.html#keyboard-modifier-flags','keyboard.html#al_install_keyboard','keyboard.html#al_is_keyboard_installed','keyboard.html#al_uninstall_keyboard','keyboard.html#al_get_keyboard_state','keyboard.html#al_clear_keyboard_state','keyboard.html#al_key_down','keyboard.html#al_keycode_to_name','keyboard.html#al_set_keyboard_leds','keyboard.html#al_get_keyboard_event_source','memory.html#memory-management-routines','memory.html#al_malloc','memory.html#al_free','memory.html#al_realloc','memory.html#al_calloc','memory.html#al_malloc_with_context','memory.html#al_free_with_context','memory.html#al_realloc_with_context','memory.html#al_calloc_with_context','memory.html#allegro_memory_interface','memory.html#al_set_memory_interface','misc.html#miscellaneous-routines','misc.html#allegro_pi','misc.html#al_run_main','monitor.html#monitors','monitor.html#allegro_monitor_info','monitor.html#al_get_new_display_adapter','monitor.html#al_set_new_display_adapter','monitor.html#al_get_monitor_info','monitor.html#al_get_monitor_dpi','monitor.html#al_get_num_video_adapters','monitor.html#al_get_monitor_refresh_rate','mouse.html#mouse-routines','mouse.html#allegro_mouse_state','mouse.html#al_install_mouse','mouse.html#al_is_mouse_installed','mouse.html#al_uninstall_mouse','mouse.html#al_get_mouse_num_axes','mouse.html#al_get_mouse_num_buttons','mouse.html#al_get_mouse_state','mouse.html#al_get_mouse_state_axis','mouse.html#al_mouse_button_down','mouse.html#al_set_mouse_xy','mouse.html#al_set_mouse_z','mouse.html#al_set_mouse_w','mouse.html#al_set_mouse_axis','mouse.html#al_get_mouse_event_source','mouse.html#al_set_mouse_wheel_precision','mouse.html#al_get_mouse_wheel_precision','mouse.html#mouse-cursors','mouse.html#al_create_mouse_cursor','mouse.html#al_destroy_mouse_cursor','mouse.html#al_set_mouse_cursor','mouse.html#al_set_system_mouse_cursor','mouse.html#al_get_mouse_cursor_position','mouse.html#al_hide_mouse_cursor','mouse.html#al_show_mouse_cursor','mouse.html#al_grab_mouse','mouse.html#al_ungrab_mouse','path.html#path-structures','path.html#al_create_path','path.html#al_create_path_for_directory','path.html#al_destroy_path','path.html#al_clone_path','path.html#al_join_paths','path.html#al_rebase_path','path.html#al_get_path_drive','path.html#al_get_path_num_components','path.html#al_get_path_component','path.html#al_get_path_tail','path.html#al_get_path_filename','path.html#al_get_path_basename','path.html#al_get_path_extension','path.html#al_set_path_drive','path.html#al_append_path_component','path.html#al_insert_path_component','path.html#al_replace_path_component','path.html#al_remove_path_component','path.html#al_drop_path_tail','path.html#al_set_path_filename','path.html#al_set_path_extension','path.html#al_path_cstr','path.html#al_path_ustr','path.html#al_make_path_canonical','state.html#state','state.html#allegro_state','state.html#allegro_state_flags','state.html#al_restore_state','state.html#al_store_state','state.html#al_get_errno','state.html#al_set_errno','system.html#system-routines','system.html#al_install_system','system.html#al_init','system.html#al_uninstall_system','system.html#al_is_system_installed','system.html#al_get_allegro_version','system.html#al_get_standard_path','system.html#al_set_exe_name','system.html#al_set_app_name','system.html#al_set_org_name','system.html#al_get_app_name','system.html#al_get_org_name','system.html#al_get_system_config','system.html#al_get_system_id','system.html#al_register_assert_handler','system.html#al_register_trace_handler','system.html#al_get_cpu_count','system.html#al_get_ram_size','system.html#allegro_system_id','threads.html#threads','threads.html#allegro_thread','threads.html#allegro_mutex','threads.html#allegro_cond','threads.html#al_create_thread','threads.html#al_create_thread_with_stacksize','threads.html#al_start_thread','threads.html#al_join_thread','threads.html#al_set_thread_should_stop','threads.html#al_get_thread_should_stop','threads.html#al_destroy_thread','threads.html#al_run_detached_thread','threads.html#al_create_mutex','threads.html#al_create_mutex_recursive','threads.html#al_lock_mutex','threads.html#al_unlock_mutex','threads.html#al_destroy_mutex','threads.html#al_create_cond','threads.html#al_destroy_cond','threads.html#al_wait_cond','threads.html#al_wait_cond_until','threads.html#al_broadcast_cond','threads.html#al_signal_cond','time.html#time-routines','time.html#allegro_timeout','time.html#al_get_time','time.html#al_init_timeout','time.html#al_rest','timer.html#timer-routines','timer.html#allegro_timer','timer.html#allegro_usecs_to_secs','timer.html#allegro_msecs_to_secs','timer.html#allegro_bps_to_secs','timer.html#allegro_bpm_to_secs','timer.html#al_create_timer','timer.html#al_start_timer','timer.html#al_resume_timer','timer.html#al_stop_timer','timer.html#al_get_timer_started','timer.html#al_destroy_timer','timer.html#al_get_timer_count','timer.html#al_set_timer_count','timer.html#al_add_timer_count','timer.html#al_get_timer_speed','timer.html#al_set_timer_speed','timer.html#al_get_timer_event_source','touch.html#touch-input','touch.html#allegro_touch_input','touch.html#allegro_touch_input_max_touch_count','touch.html#allegro_touch_state','touch.html#allegro_touch_input_state','touch.html#allegro_mouse_emulation_mode','touch.html#al_install_touch_input','touch.html#al_uninstall_touch_input','touch.html#al_is_touch_input_installed','touch.html#al_get_touch_input_state','touch.html#al_set_mouse_emulation_mode','touch.html#al_get_mouse_emulation_mode','touch.html#al_get_touch_input_event_source','touch.html#al_get_touch_input_mouse_emulation_event_source','transformations.html#transformations','transformations.html#allegro_transform','transformations.html#al_copy_transform','transformations.html#al_use_transform','transformations.html#al_get_current_transform','transformations.html#al_use_projection_transform','transformations.html#al_get_current_projection_transform','transformations.html#al_get_current_inverse_transform','transformations.html#al_invert_transform','transformations.html#al_transpose_transform','transformations.html#al_check_inverse','transformations.html#al_identity_transform','transformations.html#al_build_transform','transformations.html#al_build_camera_transform','transformations.html#al_translate_transform','transformations.html#al_rotate_transform','transformations.html#al_scale_transform','transformations.html#al_transform_coordinates','transformations.html#al_transform_coordinates_3d','transformations.html#al_transform_coordinates_4d','transformations.html#al_transform_coordinates_3d_projective','transformations.html#al_compose_transform','transformations.html#al_orthographic_transform','transformations.html#al_perspective_transform','transformations.html#al_translate_transform_3d','transformations.html#al_scale_transform_3d','transformations.html#al_rotate_transform_3d','transformations.html#al_horizontal_shear_transform','transformations.html#al_vertical_shear_transform','utf8.html#utf-8-string-routines','utf8.html#about-utf-8-string-routines','utf8.html#utf-8-string-types','utf8.html#allegro_ustr','utf8.html#allegro_ustr_info','utf8.html#creating-and-destroying-strings','utf8.html#al_ustr_new','utf8.html#al_ustr_new_from_buffer','utf8.html#al_ustr_newf','utf8.html#al_ustr_free','utf8.html#al_cstr','utf8.html#al_ustr_to_buffer','utf8.html#al_cstr_dup','utf8.html#al_ustr_dup','utf8.html#al_ustr_dup_substr','utf8.html#predefined-strings','utf8.html#al_ustr_empty_string','utf8.html#creating-strings-by-referencing-other-data','utf8.html#al_ref_cstr','utf8.html#al_ref_buffer','utf8.html#al_ref_ustr','utf8.html#sizes-and-offsets','utf8.html#al_ustr_size','utf8.html#al_ustr_length','utf8.html#al_ustr_offset','utf8.html#al_ustr_next','utf8.html#al_ustr_prev','utf8.html#getting-code-points','utf8.html#al_ustr_get','utf8.html#al_ustr_get_next','utf8.html#al_ustr_prev_get','utf8.html#inserting-into-strings','utf8.html#al_ustr_insert','utf8.html#al_ustr_insert_cstr','utf8.html#al_ustr_insert_chr','utf8.html#appending-to-strings','utf8.html#al_ustr_append','utf8.html#al_ustr_append_cstr','utf8.html#al_ustr_append_chr','utf8.html#al_ustr_appendf','utf8.html#al_ustr_vappendf','utf8.html#removing-parts-of-strings','utf8.html#al_ustr_remove_chr','utf8.html#al_ustr_remove_range','utf8.html#al_ustr_truncate','utf8.html#al_ustr_ltrim_ws','utf8.html#al_ustr_rtrim_ws','utf8.html#al_ustr_trim_ws','utf8.html#assigning-one-string-to-another','utf8.html#al_ustr_assign','utf8.html#al_ustr_assign_substr','utf8.html#al_ustr_assign_cstr','utf8.html#replacing-parts-of-string','utf8.html#al_ustr_set_chr','utf8.html#al_ustr_replace_range','utf8.html#searching','utf8.html#al_ustr_find_chr','utf8.html#al_ustr_rfind_chr','utf8.html#al_ustr_find_set','utf8.html#al_ustr_find_set_cstr','utf8.html#al_ustr_find_cset','utf8.html#al_ustr_find_cset_cstr','utf8.html#al_ustr_find_str','utf8.html#al_ustr_find_cstr','utf8.html#al_ustr_rfind_str','utf8.html#al_ustr_rfind_cstr','utf8.html#al_ustr_find_replace','utf8.html#al_ustr_find_replace_cstr','utf8.html#comparing','utf8.html#al_ustr_equal','utf8.html#al_ustr_compare','utf8.html#al_ustr_ncompare','utf8.html#al_ustr_has_prefix','utf8.html#al_ustr_has_prefix_cstr','utf8.html#al_ustr_has_suffix','utf8.html#al_ustr_has_suffix_cstr','utf8.html#utf-16-conversion','utf8.html#al_ustr_new_from_utf16','utf8.html#al_ustr_size_utf16','utf8.html#al_ustr_encode_utf16','utf8.html#low-level-utf-8-routines','utf8.html#al_utf8_width','utf8.html#al_utf8_encode','utf8.html#low-level-utf-16-routines','utf8.html#al_utf16_width','utf8.html#al_utf16_encode','platform.html#platform-specific-functions','platform.html#windows','platform.html#al_get_win_window_handle','platform.html#al_win_add_window_callback','platform.html#al_win_remove_window_callback','platform.html#mac-os-x','platform.html#al_osx_get_window','platform.html#iphone','platform.html#al_iphone_set_statusbar_orientation','platform.html#al_iphone_get_view','platform.html#al_iphone_get_window','platform.html#android','platform.html#al_android_set_apk_file_interface','platform.html#al_android_set_apk_fs_interface','platform.html#al_android_get_os_version','platform.html#al_android_get_jni_env','platform.html#al_android_get_activity','platform.html#x11','platform.html#al_get_x_window_id','platform.html#al_x_set_initial_icon','direct3d.html#direct3d-integration','direct3d.html#al_get_d3d_device','direct3d.html#al_get_d3d_system_texture','direct3d.html#al_get_d3d_video_texture','direct3d.html#al_have_d3d_non_pow2_texture_support','direct3d.html#al_have_d3d_non_square_texture_support','direct3d.html#al_get_d3d_texture_size','direct3d.html#al_get_d3d_texture_position','direct3d.html#al_is_d3d_device_lost','direct3d.html#al_set_d3d_device_release_callback','direct3d.html#al_set_d3d_device_restore_callback','opengl.html#opengl-integration','opengl.html#al_get_opengl_extension_list','opengl.html#al_get_opengl_proc_address','opengl.html#al_get_opengl_texture','opengl.html#al_get_opengl_texture_size','opengl.html#al_get_opengl_texture_position','opengl.html#al_get_opengl_program_object','opengl.html#al_get_opengl_fbo','opengl.html#al_remove_opengl_fbo','opengl.html#al_have_opengl_extension','opengl.html#al_get_opengl_version','opengl.html#al_get_opengl_variant','opengl.html#al_set_current_opengl_context','opengl.html#opengl-configuration','audio.html#audio-addon','audio.html#audio-types','audio.html#allegro_audio_event_type','audio.html#allegro_event_audio_stream_fragment','audio.html#allegro_event_audio_stream_finished','audio.html#allegro_event_audio_recorder_fragment','audio.html#allegro_audio_depth','audio.html#allegro_audio_pan_none','audio.html#allegro_channel_conf','audio.html#allegro_mixer','audio.html#allegro_mixer_quality','audio.html#allegro_playmode','audio.html#allegro_sample_id','audio.html#allegro_sample','audio.html#allegro_sample_instance','audio.html#allegro_audio_stream','audio.html#allegro_voice','audio.html#setting-up-audio','audio.html#al_install_audio','audio.html#al_uninstall_audio','audio.html#al_is_audio_installed','audio.html#al_reserve_samples','audio.html#misc-audio-functions','audio.html#al_get_allegro_audio_version','audio.html#al_get_audio_depth_size','audio.html#al_get_channel_count','audio.html#al_fill_silence','audio.html#voice-functions','audio.html#al_create_voice','audio.html#al_destroy_voice','audio.html#al_detach_voice','audio.html#al_attach_audio_stream_to_voice','audio.html#al_attach_mixer_to_voice','audio.html#al_attach_sample_instance_to_voice','audio.html#al_get_voice_frequency','audio.html#al_get_voice_channels','audio.html#al_get_voice_depth','audio.html#al_get_voice_playing','audio.html#al_set_voice_playing','audio.html#al_get_voice_position','audio.html#al_set_voice_position','audio.html#sample-functions','audio.html#al_create_sample','audio.html#al_destroy_sample','audio.html#al_play_sample','audio.html#al_stop_sample','audio.html#al_lock_sample_id','audio.html#al_unlock_sample_id','audio.html#al_stop_samples','audio.html#al_get_sample_channels','audio.html#al_get_sample_depth','audio.html#al_get_sample_frequency','audio.html#al_get_sample_length','audio.html#al_get_sample_data','audio.html#sample-instance-functions','audio.html#al_create_sample_instance','audio.html#al_destroy_sample_instance','audio.html#al_play_sample_instance','audio.html#al_stop_sample_instance','audio.html#al_get_sample_instance_channels','audio.html#al_get_sample_instance_depth','audio.html#al_get_sample_instance_frequency','audio.html#al_get_sample_instance_length','audio.html#al_set_sample_instance_length','audio.html#al_get_sample_instance_position','audio.html#al_set_sample_instance_position','audio.html#al_get_sample_instance_speed','audio.html#al_set_sample_instance_speed','audio.html#al_get_sample_instance_gain','audio.html#al_set_sample_instance_gain','audio.html#al_get_sample_instance_pan','audio.html#al_set_sample_instance_pan','audio.html#al_get_sample_instance_time','audio.html#al_get_sample_instance_playmode','audio.html#al_set_sample_instance_playmode','audio.html#al_get_sample_instance_playing','audio.html#al_set_sample_instance_playing','audio.html#al_get_sample_instance_attached','audio.html#al_detach_sample_instance','audio.html#al_get_sample','audio.html#al_set_sample','audio.html#al_set_sample_instance_channel_matrix','audio.html#mixer-functions','audio.html#al_create_mixer','audio.html#al_destroy_mixer','audio.html#al_get_default_mixer','audio.html#al_set_default_mixer','audio.html#al_restore_default_mixer','audio.html#al_get_default_voice','audio.html#al_set_default_voice','audio.html#al_attach_mixer_to_mixer','audio.html#al_attach_sample_instance_to_mixer','audio.html#al_attach_audio_stream_to_mixer','audio.html#al_get_mixer_frequency','audio.html#al_set_mixer_frequency','audio.html#al_get_mixer_channels','audio.html#al_get_mixer_depth','audio.html#al_get_mixer_gain','audio.html#al_set_mixer_gain','audio.html#al_get_mixer_quality','audio.html#al_set_mixer_quality','audio.html#al_get_mixer_playing','audio.html#al_set_mixer_playing','audio.html#al_get_mixer_attached','audio.html#al_detach_mixer','audio.html#al_set_mixer_postprocess_callback','audio.html#stream-functions','audio.html#al_create_audio_stream','audio.html#al_destroy_audio_stream','audio.html#al_get_audio_stream_event_source','audio.html#al_drain_audio_stream','audio.html#al_rewind_audio_stream','audio.html#al_get_audio_stream_frequency','audio.html#al_get_audio_stream_channels','audio.html#al_get_audio_stream_depth','audio.html#al_get_audio_stream_length','audio.html#al_get_audio_stream_speed','audio.html#al_set_audio_stream_speed','audio.html#al_get_audio_stream_gain','audio.html#al_set_audio_stream_gain','audio.html#al_get_audio_stream_pan','audio.html#al_set_audio_stream_pan','audio.html#al_get_audio_stream_playing','audio.html#al_set_audio_stream_playing','audio.html#al_get_audio_stream_playmode','audio.html#al_set_audio_stream_playmode','audio.html#al_get_audio_stream_attached','audio.html#al_detach_audio_stream','audio.html#al_get_audio_stream_played_samples','audio.html#al_get_audio_stream_fragment','audio.html#al_set_audio_stream_fragment','audio.html#al_get_audio_stream_fragments','audio.html#al_get_available_audio_stream_fragments','audio.html#al_seek_audio_stream_secs','audio.html#al_get_audio_stream_position_secs','audio.html#al_get_audio_stream_length_secs','audio.html#al_set_audio_stream_loop_secs','audio.html#al_set_audio_stream_channel_matrix','audio.html#audio-file-i/o','audio.html#al_register_sample_loader','audio.html#al_register_sample_loader_f','audio.html#al_register_sample_saver','audio.html#al_register_sample_saver_f','audio.html#al_register_audio_stream_loader','audio.html#al_register_audio_stream_loader_f','audio.html#al_load_sample','audio.html#al_load_sample_f','audio.html#al_load_audio_stream','audio.html#al_load_audio_stream_f','audio.html#al_save_sample','audio.html#al_save_sample_f','audio.html#audio-recording','audio.html#allegro_audio_recorder','audio.html#allegro_audio_recorder_event','audio.html#al_create_audio_recorder','audio.html#al_start_audio_recorder','audio.html#al_stop_audio_recorder','audio.html#al_is_audio_recorder_recording','audio.html#al_get_audio_recorder_event','audio.html#al_get_audio_recorder_event_source','audio.html#al_destroy_audio_recorder','acodec.html#audio-codecs-addon','acodec.html#al_init_acodec_addon','acodec.html#al_is_acodec_addon_initialized','acodec.html#al_get_allegro_acodec_version','color.html#color-addon','color.html#al_color_cmyk','color.html#al_color_cmyk_to_rgb','color.html#al_color_hsl','color.html#al_color_hsl_to_rgb','color.html#al_color_hsv','color.html#al_color_hsv_to_rgb','color.html#al_color_html','color.html#al_color_html_to_rgb','color.html#al_color_rgb_to_html','color.html#al_color_name','color.html#al_color_name_to_rgb','color.html#al_color_rgb_to_cmyk','color.html#al_color_rgb_to_hsl','color.html#al_color_rgb_to_hsv','color.html#al_color_rgb_to_name','color.html#al_color_rgb_to_xyz','color.html#al_color_xyz','color.html#al_color_xyz_to_rgb','color.html#al_color_rgb_to_xyy','color.html#al_color_xyy','color.html#al_color_xyy_to_rgb','color.html#al_color_rgb_to_lab','color.html#al_color_lab','color.html#al_color_lab_to_rgb','color.html#al_color_rgb_to_lch','color.html#al_color_lch','color.html#al_color_lch_to_rgb','color.html#al_color_distance_ciede2000','color.html#al_color_rgb_to_yuv','color.html#al_color_yuv','color.html#al_color_yuv_to_rgb','color.html#al_get_allegro_color_version','color.html#al_is_color_valid','font.html#font-addons','font.html#general-font-routines','font.html#allegro_font','font.html#allegro_glyph','font.html#al_init_font_addon','font.html#al_is_font_addon_initialized','font.html#al_shutdown_font_addon','font.html#al_load_font','font.html#al_destroy_font','font.html#al_register_font_loader','font.html#al_get_font_line_height','font.html#al_get_font_ascent','font.html#al_get_font_descent','font.html#al_get_text_width','font.html#al_get_ustr_width','font.html#al_draw_text','font.html#al_draw_ustr','font.html#al_draw_justified_text','font.html#al_draw_justified_ustr','font.html#al_draw_textf','font.html#al_draw_justified_textf','font.html#al_get_text_dimensions','font.html#al_get_ustr_dimensions','font.html#al_get_allegro_font_version','font.html#al_get_font_ranges','font.html#al_set_fallback_font','font.html#al_get_fallback_font','font.html#per-glyph-text-handling','font.html#al_draw_glyph','font.html#al_get_glyph_width','font.html#al_get_glyph_dimensions','font.html#al_get_glyph_advance','font.html#multiline-text-drawing','font.html#al_draw_multiline_text','font.html#al_draw_multiline_ustr','font.html#al_draw_multiline_textf','font.html#al_do_multiline_text','font.html#al_do_multiline_ustr','font.html#bitmap-fonts','font.html#al_grab_font_from_bitmap','font.html#al_load_bitmap_font','font.html#al_load_bitmap_font_flags','font.html#al_create_builtin_font','font.html#ttf-fonts','font.html#al_init_ttf_addon','font.html#al_is_ttf_addon_initialized','font.html#al_shutdown_ttf_addon','font.html#al_load_ttf_font','font.html#al_load_ttf_font_f','font.html#al_load_ttf_font_stretch','font.html#al_load_ttf_font_stretch_f','font.html#al_get_allegro_ttf_version','font.html#al_get_glyph','image.html#image-i/o-addon','image.html#al_init_image_addon','image.html#al_is_image_addon_initialized','image.html#al_shutdown_image_addon','image.html#al_get_allegro_image_version','main.html#main-addon','memfile.html#memfile-interface','memfile.html#al_open_memfile','memfile.html#al_get_allegro_memfile_version','native_dialog.html#native-dialogs-support','native_dialog.html#allegro_filechooser','native_dialog.html#allegro_textlog','native_dialog.html#al_init_native_dialog_addon','native_dialog.html#al_is_native_dialog_addon_initialized','native_dialog.html#al_shutdown_native_dialog_addon','native_dialog.html#al_create_native_file_dialog','native_dialog.html#al_show_native_file_dialog','native_dialog.html#al_get_native_file_dialog_count','native_dialog.html#al_get_native_file_dialog_path','native_dialog.html#al_destroy_native_file_dialog','native_dialog.html#al_show_native_message_box','native_dialog.html#al_open_native_text_log','native_dialog.html#al_close_native_text_log','native_dialog.html#al_append_native_text_log','native_dialog.html#al_get_native_text_log_event_source','native_dialog.html#al_get_allegro_native_dialog_version','native_dialog.html#menus','native_dialog.html#allegro_menu','native_dialog.html#allegro_menu_info','native_dialog.html#al_create_menu','native_dialog.html#al_create_popup_menu','native_dialog.html#al_build_menu','native_dialog.html#al_append_menu_item','native_dialog.html#al_insert_menu_item','native_dialog.html#al_remove_menu_item','native_dialog.html#al_clone_menu','native_dialog.html#al_clone_menu_for_popup','native_dialog.html#al_destroy_menu','native_dialog.html#al_get_menu_item_caption','native_dialog.html#al_set_menu_item_caption','native_dialog.html#al_get_menu_item_flags','native_dialog.html#al_set_menu_item_flags','native_dialog.html#al_toggle_menu_item_flags','native_dialog.html#al_get_menu_item_icon','native_dialog.html#al_set_menu_item_icon','native_dialog.html#al_find_menu','native_dialog.html#al_find_menu_item','native_dialog.html#al_get_default_menu_event_source','native_dialog.html#al_enable_menu_event_source','native_dialog.html#al_disable_menu_event_source','native_dialog.html#al_get_display_menu','native_dialog.html#al_set_display_menu','native_dialog.html#al_popup_menu','native_dialog.html#al_remove_display_menu','physfs.html#physicsfs-integration','physfs.html#al_set_physfs_file_interface','physfs.html#al_get_allegro_physfs_version','primitives.html#primitives-addon','primitives.html#general','primitives.html#al_get_allegro_primitives_version','primitives.html#al_init_primitives_addon','primitives.html#al_is_primitives_addon_initialized','primitives.html#al_shutdown_primitives_addon','primitives.html#high-level-drawing-routines','primitives.html#pixel-precise-output','primitives.html#al_draw_line','primitives.html#al_draw_triangle','primitives.html#al_draw_filled_triangle','primitives.html#al_draw_rectangle','primitives.html#al_draw_filled_rectangle','primitives.html#al_draw_rounded_rectangle','primitives.html#al_draw_filled_rounded_rectangle','primitives.html#al_calculate_arc','primitives.html#al_draw_pieslice','primitives.html#al_draw_filled_pieslice','primitives.html#al_draw_ellipse','primitives.html#al_draw_filled_ellipse','primitives.html#al_draw_circle','primitives.html#al_draw_filled_circle','primitives.html#al_draw_arc','primitives.html#al_draw_elliptical_arc','primitives.html#al_calculate_spline','primitives.html#al_draw_spline','primitives.html#al_calculate_ribbon','primitives.html#al_draw_ribbon','primitives.html#low-level-drawing-routines','primitives.html#al_draw_prim','primitives.html#al_draw_indexed_prim','primitives.html#al_draw_vertex_buffer','primitives.html#al_draw_indexed_buffer','primitives.html#al_draw_soft_triangle','primitives.html#al_draw_soft_line','primitives.html#custom-vertex-declaration-routines','primitives.html#al_create_vertex_decl','primitives.html#al_destroy_vertex_decl','primitives.html#vertex-buffer-routines','primitives.html#al_create_vertex_buffer','primitives.html#al_destroy_vertex_buffer','primitives.html#al_lock_vertex_buffer','primitives.html#al_unlock_vertex_buffer','primitives.html#al_get_vertex_buffer_size','primitives.html#index-buffer-routines','primitives.html#al_create_index_buffer','primitives.html#al_destroy_index_buffer','primitives.html#al_lock_index_buffer','primitives.html#al_unlock_index_buffer','primitives.html#al_get_index_buffer_size','primitives.html#polygon-routines','primitives.html#al_draw_polyline','primitives.html#al_draw_polygon','primitives.html#al_draw_filled_polygon','primitives.html#al_draw_filled_polygon_with_holes','primitives.html#al_triangulate_polygon','primitives.html#structures-and-types','primitives.html#allegro_vertex','primitives.html#allegro_vertex_decl','primitives.html#allegro_vertex_element','primitives.html#allegro_prim_type','primitives.html#allegro_prim_attr','primitives.html#allegro_prim_storage','primitives.html#allegro_vertex_cache_size','primitives.html#allegro_prim_quality','primitives.html#allegro_line_join','primitives.html#allegro_line_cap','primitives.html#allegro_vertex_buffer','primitives.html#allegro_index_buffer','primitives.html#allegro_prim_buffer_flags','shader.html#shader-routines','shader.html#allegro_shader','shader.html#allegro_shader_type','shader.html#allegro_shader_platform','shader.html#al_create_shader','shader.html#al_attach_shader_source','shader.html#al_attach_shader_source_file','shader.html#al_build_shader','shader.html#al_get_shader_log','shader.html#al_get_shader_platform','shader.html#al_use_shader','shader.html#al_destroy_shader','shader.html#al_set_shader_sampler','shader.html#al_set_shader_matrix','shader.html#al_set_shader_int','shader.html#al_set_shader_float','shader.html#al_set_shader_bool','shader.html#al_set_shader_int_vector','shader.html#al_set_shader_float_vector','shader.html#al_get_default_shader_source','video.html#video-streaming-addon','video.html#allegro_video_event_type','video.html#allegro_event_video_frame_show','video.html#allegro_event_video_finished','video.html#allegro_video_position_type','video.html#al_init_video_addon','video.html#al_is_video_addon_initialized','video.html#al_shutdown_video_addon','video.html#al_get_allegro_video_version','video.html#al_open_video','video.html#al_close_video','video.html#al_start_video','video.html#al_start_video_with_voice','video.html#al_get_video_event_source','video.html#al_set_video_playing','video.html#al_is_video_playing','video.html#al_get_video_audio_rate','video.html#al_get_video_fps','video.html#al_get_video_scaled_width','video.html#al_get_video_scaled_height','video.html#al_get_video_frame','video.html#al_get_video_position','video.html#al_seek_video',] diff --git a/allegro/docs/html/refman/shader.html b/allegro/docs/html/refman/shader.html new file mode 100644 index 00000000..c6515d8f --- /dev/null +++ b/allegro/docs/html/refman/shader.html @@ -0,0 +1,521 @@ + + + + + + + Shader routines + + + + + + + + +
+ + +
+

Shader routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_SHADER

+
typedef struct ALLEGRO_SHADER ALLEGRO_SHADER;
+

Source Code

+

An ALLEGRO_SHADER is a program that runs on the GPU. It combines both a vertex and a pixel shader. (In OpenGL terms, an ALLEGRO_SHADER is actually a program which has one or more shaders attached. This can be confusing.)

+

The source code for the underlying vertex or pixel shader can be provided either as GLSL or HLSL, depending on the value of ALLEGRO_SHADER_PLATFORM used when creating it.

+

Since: 5.1.0

+

Examples:

+ +

ALLEGRO_SHADER_TYPE

+
typedef enum ALLEGRO_SHADER_TYPE ALLEGRO_SHADER_TYPE;
+

Source Code

+

Used with al_attach_shader_source and al_attach_shader_source_file to specify how to interpret the attached source.

+
+
ALLEGRO_VERTEX_SHADER
+

A vertex shader is executed for each vertex it is used with. The program will output exactly one vertex at a time.

+

When Allegro’s graphics are being used then in addition to all vertices of primitives from the primitives addon, each drawn bitmap also consists of four vertices.

+
+
ALLEGRO_PIXEL_SHADER
+

A pixel shader is executed for each pixel it is used with. The program will output exactly one pixel at a time - either in the backbuffer or in the current target bitmap.

+

With Allegro’s builtin graphics this means the shader is for example called for each destination pixel of the output of an al_draw_bitmap call.

+

A more accurate term for pixel shader would be fragment shader since one final pixel in the target bitmap is not necessarily composed of only a single output but of multiple fragments (for example when multi-sampling is being used).

+
+
+

Since: 5.1.0

+

ALLEGRO_SHADER_PLATFORM

+
typedef enum ALLEGRO_SHADER_PLATFORM ALLEGRO_SHADER_PLATFORM;
+

Source Code

+

The underlying platform which the ALLEGRO_SHADER is built on top of, which dictates the language used to program the shader.

+
    +
  • ALLEGRO_SHADER_AUTO
  • +
  • ALLEGRO_SHADER_GLSL - OpenGL Shading Language
  • +
  • ALLEGRO_SHADER_HLSL - High Level Shader Language (for Direct3D)
  • +
+

Since: 5.1.0

+

Examples:

+ +

al_create_shader

+
ALLEGRO_SHADER *al_create_shader(ALLEGRO_SHADER_PLATFORM platform)
+

Source Code

+

Create a shader object.

+

The platform argument is one of the ALLEGRO_SHADER_PLATFORM values, and specifies the type of shader object to create, and which language is used to program the shader.

+

The shader platform must be compatible with the type of display that you will use the shader with. For example, you cannot create and use a HLSL shader on an OpenGL display, nor a GLSL shader on a Direct3D display.

+

The ALLEGRO_SHADER_AUTO value automatically chooses the appropriate platform for the display currently targeted by the calling thread; there must be such a display. It will create a GLSL shader for an OpenGL display, and a HLSL shader for a Direct3D display.

+

Returns the shader object on success. Otherwise, returns NULL.

+

Since: 5.1.0

+

See also: al_attach_shader_source, al_attach_shader_source_file, al_build_shader, al_use_shader, al_destroy_shader, al_get_shader_platform

+

Examples:

+ +

al_attach_shader_source

+
bool al_attach_shader_source(ALLEGRO_SHADER *shader, ALLEGRO_SHADER_TYPE type,
+    const char *source)
+

Source Code

+

Attaches the shader’s source code to the shader object and compiles it. Passing NULL deletes the underlying (OpenGL or DirectX) shader. See also al_attach_shader_source_file if you prefer to obtain your shader source from an external file.

+

If you do not use ALLEGRO_PROGRAMMABLE_PIPELINE Allegro’s graphics functions will not use any shader specific functions themselves. In case of a system with no fixed function pipeline (like OpenGL ES 2 or OpenGL 3 or 4) this means Allegro’s drawing functions cannot be used.

+

TODO: Is ALLEGRO_PROGRAMMABLE_PIPELINE set automatically in this case?

+

When ALLEGRO_PROGRAMMABLE_PIPELINE is used the following shader uniforms are provided by Allegro and can be accessed in your shaders:

+
+
al_projview_matrix
+
matrix for Allegro’s orthographic projection multiplied by the al_use_transform matrix. The type is mat4 in GLSL, and float4x4 in HLSL. +
+
al_use_tex
+
whether or not to use the bound texture. The type is bool in both GLSL and HLSL. +
+
al_tex
+
the texture if one is bound. The type is sampler2D in GLSL and texture in HLSL. +
+
al_use_tex_matrix
+
whether or not to use a texture matrix (used by the primitives addon). The type is bool in both GLSL and HLSL. +
+
al_tex_matrix
+
the texture matrix (used by the primitives addon). Your shader should multiply the texture coordinates by this matrix. The type is mat4 in GLSL, and float4x4 in HLSL. +
+
+

With GLSL alpha testing is done in the shader and uses these additional uniforms:

+
+
al_alpha_test
+
Whether to do any alpha testing. If false, the shader should render the pixel, otherwise it should interpret the values of al_alpha_func and al_alpha_test_val. +
+
al_alpha_func
+
The alpha testing function used. One of the ALLEGRO_RENDER_FUNCTION values. The default is ALLEGRO_RENDER_ALWAYS which means all pixels (even completely transparent ones) are rendered. The type is int. See ALLEGRO_RENDER_STATE. +
+
al_alpha_test_val
+
If alpha testing is not ALLEGRO_RENDER_NEVER or ALLEGRO_RENDER_ALWAYS the alpha value to compare to for alpha testing. The type is float. +
+
+

For GLSL shaders the vertex attributes are passed using the following variables:

+
+
al_pos
+
vertex position attribute. Type is vec4. +
+
al_texcoord
+
vertex texture coordinate attribute. Type is vec2. +
+
al_color
+
vertex color attribute. Type is vec4. +
+
al_user_attr_0
+
The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR +
+
al_user_attr_1, …, al_user_attr_9
+
The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR + X where X is an integer from 1 to 9 +
+
+

For HLSL shaders the vertex attributes are passed using the following semantics:

+
+
POSITION0
+
vertex position attribute. Type is float4. +
+
TEXCOORD0
+
vertex texture coordinate attribute. Type is float2. +
+
TEXCOORD1
+
vertex color attribute. Type is float4. +
+
+

Also, each shader variable has a corresponding macro name that can be used when defining the shaders using string literals. Don’t use these macros with the other shader functions as that will lead to undefined behavior.

+
    +
  • ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX for “al_projview_matrix”
  • +
  • ALLEGRO_SHADER_VAR_POS for “al_pos”
  • +
  • ALLEGRO_SHADER_VAR_COLOR for “al_color”
  • +
  • ALLEGRO_SHADER_VAR_TEXCOORD for “al_texcoord”
  • +
  • ALLEGRO_SHADER_VAR_USE_TEX for “al_use_tex”
  • +
  • ALLEGRO_SHADER_VAR_TEX for “al_tex”
  • +
  • ALLEGRO_SHADER_VAR_USE_TEX_MATRIX for “al_use_tex_matrix”
  • +
  • ALLEGRO_SHADER_VAR_TEX_MATRIX for “al_tex_matrix”
  • +
  • ALLEGRO_SHADER_VAR_ALPHA_FUNCTION for “al_alpha_func”
  • +
  • ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE for “al_alpha_test_val”
  • +
+

Examine the output of al_get_default_shader_source for an example of how to use the above uniforms and attributes.

+

Returns true on success and false on error, in which case the error log is updated. The error log can be retrieved with al_get_shader_log.

+

Since: 5.1.0

+

See also: al_attach_shader_source_file, al_build_shader, al_get_default_shader_source, al_get_shader_log, ALLEGRO_PRIM_ATTR

+

Examples:

+ +

al_attach_shader_source_file

+
bool al_attach_shader_source_file(ALLEGRO_SHADER *shader,
+   ALLEGRO_SHADER_TYPE type, const char *filename)
+

Source Code

+

Like al_attach_shader_source but reads the source code for the shader from the named file.

+

Returns true on success and false on error, in which case the error log is updated. The error log can be retrieved with al_get_shader_log.

+

Since: 5.1.0

+

See also: al_attach_shader_source, al_build_shader, al_get_shader_log

+

Examples:

+ +

al_build_shader

+
bool al_build_shader(ALLEGRO_SHADER *shader)
+

Source Code

+

This is required before the shader can be used with al_use_shader. It should be called after successfully attaching the pixel and/or vertex shaders with al_attach_shader_source or al_attach_shader_source_file.

+

Returns true on success and false on error, in which case the error log is updated. The error log can be retrieved with al_get_shader_log.

+
+

Note: If you are using the ALLEGRO_PROGRAMMABLE_PIPELINE flag, then you must specify both a pixel and a vertex shader sources for anything to be rendered.

+
+

Since: 5.1.6

+

See also: al_use_shader, al_get_shader_log

+

Examples:

+ +

al_get_shader_log

+
const char *al_get_shader_log(ALLEGRO_SHADER *shader)
+

Source Code

+

Return a read-only string containing the information log for a shader program. The log is updated by certain functions, such as al_attach_shader_source or al_build_shader when there is an error.

+

This function never returns NULL.

+

Since: 5.1.0

+

See also: al_attach_shader_source, al_attach_shader_source_file, al_build_shader

+

Examples:

+ +

al_get_shader_platform

+
ALLEGRO_SHADER_PLATFORM al_get_shader_platform(ALLEGRO_SHADER *shader)
+

Source Code

+

Returns the platform the shader was created with (either ALLEGRO_SHADER_HLSL or ALLEGRO_SHADER_GLSL).

+

Since: 5.1.6

+

See also: al_create_shader

+

Examples:

+ +

al_use_shader

+
bool al_use_shader(ALLEGRO_SHADER *shader)
+

Source Code

+

Uses the shader for subsequent drawing operations on the current target bitmap. Pass NULL to stop using any shader on the current target bitmap.

+

Returns true on success. Otherwise returns false, e.g. because the shader is incompatible with the target bitmap.

+

Since: 5.1.6

+

See also: al_destroy_shader, al_set_shader_sampler, al_set_shader_matrix, al_set_shader_int, al_set_shader_float, al_set_shader_bool, al_set_shader_int_vector, al_set_shader_float_vector

+

Examples:

+ +

al_destroy_shader

+
void al_destroy_shader(ALLEGRO_SHADER *shader)
+

Source Code

+

Destroy a shader. Any bitmaps which currently use the shader will implicitly stop using the shader. In multi-threaded programs, be careful that no such bitmaps are being accessed by other threads at the time.

+

As a convenience, if the target bitmap of the calling thread is using the shader then the shader is implicitly unused before being destroyed.

+

This function does nothing if the shader argument is NULL.

+

Since: 5.1.0

+

See also: al_create_shader

+

Examples:

+ +

al_set_shader_sampler

+
bool al_set_shader_sampler(const char *name,
+   ALLEGRO_BITMAP *bitmap, int unit)
+

Source Code

+

Sets a texture sampler uniform and texture unit of the current target bitmap’s shader. The given bitmap must be a video bitmap.

+

Different samplers should use different units. The bitmap passed to Allegro’s drawing functions uses the 0th unit, so if you’re planning on using the al_tex variable in your pixel shader as well as another sampler, set the other sampler to use a unit different from 0. With the primitives addon, it is possible to free up the 0th unit by passing NULL as the texture argument to the relevant drawing functions. In this case, you may set a sampler to use the 0th unit and thus not use al_tex (the al_use_tex variable will be set to false).

+

Returns true on success. Otherwise returns false, e.g. if the uniform by that name does not exist in the shader.

+

Since: 5.1.0

+

See also: al_use_shader

+

Examples:

+ +

al_set_shader_matrix

+
bool al_set_shader_matrix(const char *name,
+   const ALLEGRO_TRANSFORM *matrix)
+

Source Code

+

Sets a matrix uniform of the current target bitmap’s shader.

+

Returns true on success. Otherwise returns false, e.g. if the uniform by that name does not exist in the shader.

+

Since: 5.1.0

+

See also: al_use_shader

+

al_set_shader_int

+
bool al_set_shader_int(const char *name, int i)
+

Source Code

+

Sets an integer uniform of the current target bitmap’s shader.

+

Returns true on success. Otherwise returns false, e.g. if the uniform by that name does not exist in the shader.

+

Since: 5.1.0

+

See also: al_use_shader

+

al_set_shader_float

+
bool al_set_shader_float(const char *name, float f)
+

Source Code

+

Sets a float uniform of the target bitmap’s shader.

+

Returns true on success. Otherwise returns false, e.g. if the uniform by that name does not exist in the shader.

+

Since: 5.1.0

+

See also: al_use_shader

+

Examples:

+ +

al_set_shader_bool

+
bool al_set_shader_bool(const char *name, bool b)
+

Source Code

+

Sets a boolean uniform of the target bitmap’s shader.

+

Returns true on success. Otherwise returns false, e.g. if the uniform by that name does not exist in the shader.

+

Since: 5.1.6

+

See also: al_use_shader

+

al_set_shader_int_vector

+
bool al_set_shader_int_vector(const char *name,
+   int num_components, const int *i, int num_elems)
+

Source Code

+

Sets an integer vector array uniform of the current target bitmap’s shader. The ‘num_components’ parameter can take one of the values 1, 2, 3 or 4. If it is 1 then an array of ‘num_elems’ integer elements is added. Otherwise each added array element is assumed to be a vector with 2, 3 or 4 components in it.

+

For example, if you have a GLSL uniform declared as uniform ivec3 flowers[4] or an HLSL uniform declared as uniform int3 flowers[4], then you’d use this function from your code like so:

+
int flowers[4][3] =
+{
+   {1, 2, 3},
+   {4, 5, 6},
+   {7, 8, 9},
+   {2, 5, 7}
+};
+
+al_set_shader_int_vector("flowers", 3, (int*)flowers, 4);
+

Returns true on success. Otherwise returns false, e.g. if the uniform by that name does not exist in the shader.

+

Since: 5.1.0

+

See also: al_set_shader_float_vector, al_use_shader

+

al_set_shader_float_vector

+
bool al_set_shader_float_vector(const char *name,
+   int num_components, const float *f, int num_elems)
+

Source Code

+

Same as al_set_shader_int_vector except all values are float instead of int.

+

Since: 5.1.0

+

See also: al_set_shader_int_vector, al_use_shader

+

Examples:

+ +

al_get_default_shader_source

+
char const *al_get_default_shader_source(ALLEGRO_SHADER_PLATFORM platform,
+   ALLEGRO_SHADER_TYPE type)
+

Source Code

+

Returns a string containing the source code to Allegro’s default vertex or pixel shader appropriate for the passed platform. The ALLEGRO_SHADER_AUTO value means GLSL is used if OpenGL is being used otherwise HLSL. ALLEGRO_SHADER_AUTO requires that there is a current display set on the calling thread. This function can return NULL if Allegro was built without support for shaders of the selected platform.

+

Since: 5.1.6

+

See also: al_attach_shader_source

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:44 UTC +

+
+ + diff --git a/allegro/docs/html/refman/state.html b/allegro/docs/html/refman/state.html new file mode 100644 index 00000000..8ebe2287 --- /dev/null +++ b/allegro/docs/html/refman/state.html @@ -0,0 +1,273 @@ + + + + + + + State + + + + + + + + +
+ + +
+

State

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_STATE

+
typedef struct ALLEGRO_STATE ALLEGRO_STATE;
+

Source Code

+

Opaque type which is passed to al_store_state/al_restore_state.

+

The various state kept internally by Allegro can be displayed like this:

+
  global
+      active system driver
+          current config
+  per thread
+      new bitmap params
+      new display params
+      active file interface
+      errno
+      current blending mode
+      current display
+          deferred drawing
+      current target bitmap
+          current transformation
+          current projection transformation
+          current clipping rectangle
+          bitmap locking
+          current shader
+

In general, the only real global state is the active system driver. All other global state is per-thread, so if your application has multiple separate threads they never will interfere with each other. (Except if there are objects accessed by multiple threads of course. Usually you want to minimize that though and for the remaining cases use synchronization primitives described in the threads section or events described in the events section to control inter-thread communication.)

+

Examples:

+ +

ALLEGRO_STATE_FLAGS

+
typedef enum ALLEGRO_STATE_FLAGS
+

Source Code

+

Flags which can be passed to al_store_state/al_restore_state as bit combinations. See al_store_state for the list of flags.

+

al_restore_state

+
void al_restore_state(ALLEGRO_STATE const *state)
+

Source Code

+

Restores part of the state of the current thread from the given ALLEGRO_STATE object.

+

See also: al_store_state, ALLEGRO_STATE_FLAGS

+

Examples:

+ +

al_store_state

+
void al_store_state(ALLEGRO_STATE *state, int flags)
+

Source Code

+

Stores part of the state of the current thread in the given ALLEGRO_STATE object. The flags parameter can take any bit-combination of these flags:

+
    +
  • ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS - new_display_format, new_display_refresh_rate, new_display_flags
  • +
  • ALLEGRO_STATE_NEW_BITMAP_PARAMETERS - new_bitmap_format, new_bitmap_flags
  • +
  • ALLEGRO_STATE_DISPLAY - current_display
  • +
  • ALLEGRO_STATE_TARGET_BITMAP - target_bitmap
  • +
  • ALLEGRO_STATE_BLENDER - blender
  • +
  • ALLEGRO_STATE_TRANSFORM - current_transformation
  • +
  • ALLEGRO_STATE_PROJECTION_TRANSFORM - current_projection_transformation
  • +
  • ALLEGRO_STATE_NEW_FILE_INTERFACE - new_file_interface
  • +
  • ALLEGRO_STATE_BITMAP - same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS and ALLEGRO_STATE_TARGET_BITMAP
  • +
  • ALLEGRO_STATE_ALL - all of the above
  • +
+

See also: al_restore_state, ALLEGRO_STATE

+

Examples:

+ +

al_get_errno

+
int al_get_errno(void)
+GETTER(allegro_errno, 0)
+

Source Code

+

Some Allegro functions will set an error number as well as returning an error code. Call this function to retrieve the last error number set for the calling thread.

+

Examples:

+ +

al_set_errno

+
void al_set_errno(int errnum)
+SETTER(allegro_errno, errnum)
+

Source Code

+

Set the error number for the calling thread.

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:41 UTC +

+
+ + diff --git a/allegro/docs/html/refman/system.html b/allegro/docs/html/refman/system.html new file mode 100644 index 00000000..1edda930 --- /dev/null +++ b/allegro/docs/html/refman/system.html @@ -0,0 +1,649 @@ + + + + + + + System routines + + + + + + + + +
+ + +
+

System routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

al_install_system

+
bool al_install_system(int version, int (*atexit_ptr)(void (*)(void)))
+

Source Code

+

Initialize the Allegro system. No other Allegro functions can be called before this (with one or two exceptions).

+

The version field should always be set to ALLEGRO_VERSION_INT.

+

If atexit_ptr is non-NULL, and if hasn’t been done already, al_uninstall_system will be registered as an atexit function.

+

Returns true if Allegro was successfully initialized by this function call (or already was initialized previously), false if Allegro cannot be used. A common reason for this function to fail is when the version of Allegro you compiled your game against is not compatible with the version of the shared libraries that were found on the system.

+

The version compatibility check works as follows. Let A = xa.ya.za.* be the version of Allegro you compiled with, and B = xb.yb.zb.* be the version of Allegro found in the system shared library.

+

If you defined ALLEGRO_UNSTABLE before including Allegro headers, then version A is compatible with B only if xa.ya.za = xb.yb.zb. Otherwise, A is compatible with B only if xa.ya = xb.yb.

+

See also: al_init

+

al_init

+
#define al_init()    (al_install_system(ALLEGRO_VERSION_INT, atexit))
+

Source Code

+

Like al_install_system, but automatically passes in the version and uses the atexit function visible in the current binary.

+
+

Note: It is typically wrong to call al_init anywhere except the final game binary. In particular, do not call it inside a shared library unless you know what you’re doing. In those cases, it is better to call al_install_system either with a NULL atexit_ptr, or with a pointer to atexit provided by the user of this shared library.

+
+

See also: al_install_system

+

Examples:

+ +

al_uninstall_system

+
void al_uninstall_system(void)
+

Source Code

+

Closes down the Allegro system.

+
+

Note: al_uninstall_system() can be called without a corresponding al_install_system call, e.g. from atexit().

+
+

Examples:

+ +

al_is_system_installed

+
bool al_is_system_installed(void)
+

Source Code

+

Returns true if Allegro is initialized, otherwise returns false.

+

Examples:

+ +

al_get_allegro_version

+
uint32_t al_get_allegro_version(void)
+

Source Code

+

Returns the (compiled) version of the Allegro library, packed into a single integer as groups of 8 bits in the form (major << 24) | (minor << 16) | (revision << 8) | release.

+

You can use code like this to extract them:

+
uint32_t version = al_get_allegro_version();
+int major = version >> 24;
+int minor = (version >> 16) & 255;
+int revision = (version >> 8) & 255;
+int release = version & 255;
+

The release number is 0 for an unofficial version and 1 or greater for an official release. For example “5.0.2[1]” would be the (first) official 5.0.2 release while “5.0.2[0]” would be a compile of a version from the “5.0.2” branch before the official release.

+

al_get_standard_path

+
ALLEGRO_PATH *al_get_standard_path(int id)
+

Source Code

+

Gets a system path, depending on the id parameter. Some of these paths may be affected by the organization and application name, so be sure to set those before calling this function.

+

The paths are not guaranteed to be unique (e.g., SETTINGS and DATA may be the same on some platforms), so you should be sure your filenames are unique if you need to avoid naming collisions. Also, a returned path may not actually exist on the file system.

+
+
ALLEGRO_RESOURCES_PATH
+

If you bundle data in a location relative to your executable, then you should use this path to locate that data. On most platforms, this is the directory that contains the executable file.

+

If called from an OS X app bundle, then this will point to the internal resource directory (<bundle.app>/Contents/Resources). To maintain consistency, if you put your resources into a directory called “data” beneath the executable on some other platform (like Windows), then you should also create a directory called “data” under the OS X app bundle’s resource folder.

+

You should not try to write to this path, as it is very likely read-only.

+

If you install your resources in some other system directory (e.g., in /usr/share or C:\ProgramData), then you are responsible for keeping track of that yourself.

+
+
ALLEGRO_TEMP_PATH
+
Path to the directory for temporary files. +
+
ALLEGRO_USER_HOME_PATH
+
This is the user’s home directory. You should not normally write files into this directory directly, or create any sub folders in it, without explicit permission from the user. One practical application of this path would be to use it as the starting place of a file selector in a GUI. +
+
ALLEGRO_USER_DOCUMENTS_PATH
+

This location is easily accessible by the user, and is the place to store documents and files that the user might want to later open with an external program or transfer to another place.

+

You should not save files here unless the user expects it, usually by explicit permission.

+
+
ALLEGRO_USER_DATA_PATH
+
If your program saves any data that the user doesn’t need to access externally, then you should place it here. This is generally the least intrusive place to store data. This path will usually not be present on the file system, so make sure to create it before writing to it. +
+
ALLEGRO_USER_SETTINGS_PATH
+
If you are saving configuration files (especially if the user may want to edit them outside of your program), then you should place them here. This path will usually not be present on the file system, so make sure to create it before writing to it. +
+
ALLEGRO_EXENAME_PATH
+
The full path to the executable. +
+
+

Returns NULL on failure. The returned path should be freed with al_destroy_path.

+

See also: al_set_app_name, al_set_org_name, al_destroy_path, al_set_exe_name

+

Examples:

+ +

al_set_exe_name

+
void al_set_exe_name(char const *path)
+

Source Code

+

This override the executable name used by al_get_standard_path for ALLEGRO_EXENAME_PATH and ALLEGRO_RESOURCES_PATH.

+

One possibility where changing this can be useful is if you use the Python wrapper. Allegro would then by default think that the system’s Python executable is the current executable - but you can set it to the .py file being executed instead.

+

Since: 5.0.6, 5.1.0

+

See also: al_get_standard_path

+

Examples:

+ +

al_set_app_name

+
void al_set_app_name(const char *app_name)
+

Source Code

+

Sets the global application name.

+

The application name is used by al_get_standard_path to build the full path to an application’s files.

+

This function may be called before al_init or al_install_system.

+

See also: al_get_app_name, al_set_org_name

+

Examples:

+ +

al_set_org_name

+
void al_set_org_name(const char *org_name)
+

Source Code

+

Sets the global organization name.

+

The organization name is used by al_get_standard_path to build the full path to an application’s files.

+

This function may be called before al_init or al_install_system.

+

See also: al_get_org_name, al_set_app_name

+

Examples:

+ +

al_get_app_name

+
const char *al_get_app_name(void)
+

Source Code

+

Returns the global application name string.

+

See also: al_set_app_name

+

al_get_org_name

+
const char *al_get_org_name(void)
+

Source Code

+

Returns the global organization name string.

+

See also: al_set_org_name

+

al_get_system_config

+
ALLEGRO_CONFIG *al_get_system_config(void)
+

Source Code

+

Returns the system configuration structure. The returned configuration should not be destroyed with al_destroy_config. This is mainly used for configuring Allegro and its addons. You may populate this configuration before Allegro is installed to control things like the logging levels and other features.

+

Allegro will try to populate this configuration by loading a configuration file from a few different locations, in this order:

+
    +
  • Unix only: /etc/allegro5rc

  • +
  • Unix only: $HOME/allegro5rc

  • +
  • Unix only: $HOME/.allegro5rc

  • +
  • allegro5.cfg next to the executable

  • +
+

If multiple copies are found, then they are merged using al_merge_config_into.

+

The contents of this file are documented inside a prototypical allegro5.cfg that you can find in the root directory of the source distributions of Allegro. They are also reproduced below.

+

Note that Allegro will not look into that file unless you make a copy of it and place it next to your executable!

+
#
+#  Configuration file for the Allegro 5 library.
+#
+#  This file should be either in the same directory as your program.
+#
+#  On Unix, this file may also be stored as ~/.allegro5rc or /etc/allegro5rc.
+#  If multiple files exist, they will be merged, with values from more specific
+#  files overriding the less specific files.
+
+[graphics]
+
+# Graphics driver.
+# Can be 'default', 'opengl' or 'direct3d' (Windows only).
+driver=default
+
+# Display configuration selection mode.
+#
+# Under Linux, it can be used to force the old GLX 1.2 way of choosing
+# display settings or the new FBConfig method introduced with GLX 1.3.
+#
+# Under Windows, when using the OpenGL driver, setting it to old will
+# use DescribePixelFormat and new will use wglGetPixelFormatAttribivARB
+# (provided by WGL_ARB_pixel_format extension).
+#
+# Can be 'old' and 'new'. Default is 'new'.
+config_selection=new
+
+# What method to use to detect legacy cards for the Direct3D backend of the
+# primitives addon. Can be 'default', which means it'll check that the pixel
+# shader version supported is below some value. 'force_legacy' will force it to
+# detect as a legacy card. 'force_modern' will force it to detect is as a modern
+# card.
+prim_d3d_legacy_detection=default
+
+# For compatibility reasons, video bitmaps smaller than this size are
+# backed by textures with this size. This is often no longer necessary
+# on more modern systems, and should be set to < 16 if you're creating
+# bitmaps smaller than this size. Note that on Android, this is ignored
+# if smaller than 32.
+min_bitmap_size=16
+
+[audio]
+
+# Driver can be 'default', 'openal', 'alsa', 'oss', 'pulseaudio' or 'directsound'
+# depending on platform.
+driver=default
+
+# Mixer quality can be 'linear' (default), 'cubic' (best), or 'point' (bad).
+# default_mixer_quality=linear
+
+# The frequency to use for the default voice/mixer. Default: 44100.
+# primary_voice_frequency=44100
+# primary_mixer_frequency=44100
+
+# Can be 'int16', otherwise defaults to float32.
+# primary_voice_depth=float32
+# primary_mixer_depth=float32
+
+[oss]
+
+# You can skip probing for OSS4 driver by setting this option to 'yes'.
+# Default is 'no'.
+force_ver3=no
+
+# When OSS3 is used, you can choose a sound device here.
+# Default is '/dev/dsp'.
+device=/dev/dsp
+
+[alsa]
+
+# Set the ALSA sound device.
+# Default is 'default'.
+device=default
+
+# Set the ALSA capture device, e.g. hw:0,0
+# Default is 'default'.
+capture_device=default
+
+# Set the period size (in samples)
+# Note that this is erroneously called 'buffer_size' for backwards
+# compatibility.
+buffer_size=32
+
+# Set the buffer size (in samples)
+buffer_size2=2048
+
+[pulseaudio]
+
+# Set the buffer size (in samples)
+buffer_size=1024
+
+[directsound]
+
+# Set the DirectSound buffer size (in samples)
+buffer_size = 8192
+
+# Which window to attach the device to. Can be 'desktop', or 'foreground'. Try
+# flipping this if there are issues initializing audio.
+window = desktop
+
+[opengl]
+
+# If you want to support old OpenGL versions, you can make Allegro
+# believe an older version than what you actually have is used with
+# this key. This is only for testing/debugging purposes.
+
+# force_opengl_version = 1.2
+
+[opengl_disabled_extensions]
+
+# Any OpenGL extensions can be listed here to make Allegro report them
+# as not available. The extensions used by Allegro itself if available
+# are shown below - uncommenting them would disable them:
+
+# GL_ARB_texture_non_power_of_two=0
+# GL_EXT_framebuffer_object=0
+
+[image]
+
+# Gamma handling of PNG files.
+# A value of 0.0 means: Don't do any gamma correction.
+# A value of -1.0 means: Use the value from the environment variable
+# SCREEN_GAMMA (if available), otherwise fallback to a value of 2.2
+# (a good guess for PC monitors, and the value for sRGB colourspace).
+# Otherwise, the value is taken as-is.
+png_screen_gamma = -1.0
+
+# Compression level for PNG files. Possible values: 0-9, "best", "fastest",
+# "none" or "default" (a sane compromise between size and speed).
+png_compression_level = default
+
+# Quality level for JPEG files. Possible values: 0-100
+jpeg_quality_level = 75
+
+# Quality level for WebP files. Possible values: 0-100 or "lossless"
+webp_quality_level = lossless
+
+[joystick]
+
+# Linux: Allegro normally searches for joystick device N at /dev/input/jsN.
+# You can override the device file path on a per-device basis, like this.
+
+# device0=/dev/input/by-id/usb-blahblah-joystick
+
+# Windows: You can choose between the XINPUT or DIRECTINPUT driver for
+# joysticks and force feedback joysticks. Xinput is the more modern 
+# system, but DirectInput has more force feedback capabilities for older 
+# joysticks.
+driver=XINPUT
+
+# Windows: Use this to force an XInput DLL version, example "3" forces
+# xinput1_3.dll. By default, the latest version is used.
+
+# force_xinput_version = 3
+
+[keyboard]
+
+# You can trap/untrap the mouse cursor within a window with a key combination
+# of your choice, e.g. "Ctrl-G", "Shift-Ctrl-G", "Ctrl-LShift", "RWin".
+# This feature currently only works on X11 and Windows.
+
+# toggle_mouse_grab_key = ScrollLock
+
+# By default, you can press Ctrl-Alt-Delete or Ctrl-Alt-End to quit Allegro
+# programs. Set this to false to disable this feature. This only works on
+# Linux.
+
+# enable_three_finger_exit = true
+
+# By default, pressing the LED toggling keys (e.g. CapsLock) will also toggle
+# the LED on the keyboard. Setting this to false disable that connection.
+# This can only be controled on non-X11 Linux.
+
+# enable_key_led_toggle = true
+
+
+[trace]
+# Comma-separated list of channels to log. Default is "all" which
+# disables channel filtering. Some possible channels are:
+# system,display,keyboard,opengl
+# Channel names can be prefixed with - to exclude only those channels.
+# Each addon and source-file can define additional channels though so
+# there are more.
+channels=all
+
+# Log-level. Can be one of debug, info, warn, error, none or empty.
+# In debug builds if it is empty or unset, then the level is set to debug.
+# In release builds if it is empty or unset, then the level is set to none.
+level=
+
+# Set to 0 to disable line numbers in log files.
+lines=1
+
+# Set to 0 to disable timestamps in log files.
+timestamps=1
+
+# Set to 0 to disable function names in log files.
+functions=1
+
+[x11]
+# Can be fullscreen_only, always, never
+bypass_compositor = fullscreen_only
+
+[xkeymap]
+# Override X11 keycode. The below example maps X11 code 52 (Y) to Allegro
+# code 26 (Z) and X11 code 29 (Z) to Allegro code 25 (Y).
+# 52=26
+# 29=25
+
+
+[shader]
+# If you want to support override version of the d3dx9_xx.dll library
+# define this value.
+# By default, latest installed version is used.
+
+# force_d3dx9_version = 36
+
+[ttf]
+
+# Set these to something other than 0 to override the default page sizes for TTF
+# glyphs.
+min_page_size = 0
+max_page_size = 0
+
+# This entry contains characters that will be pre-catched during font loading.
+# cache_text = a bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+
+# Uncomment if you want only the characters in the cache_text entry to ever be drawn
+# skip_cache_misses = true
+
+[compatibility]
+
+# Prior to 5.2.4 on Windows you had to manually resize the display when
+# showing the menu using the dialog addon. After 5.2.4 this is done
+# automatically, but may break old code that handled this eventuality.
+# Set this to false for such code.
+automatic_menu_display_resize = true
+

al_get_system_id

+
ALLEGRO_SYSTEM_ID al_get_system_id(void)
+

Source Code

+

Returns the platform that Allegro is running on.

+

Since: 5.2.5

+

See also: ALLEGRO_SYSTEM_ID

+

al_register_assert_handler

+
void al_register_assert_handler(void (*handler)(char const *expr,
+   char const *file, int line, char const *func))
+

Source Code

+

Register a function to be called when an internal Allegro assertion fails. Pass NULL to reset to the default behaviour, which is to do whatever the standard assert() macro does.

+

Since: 5.0.6, 5.1.0

+

al_register_trace_handler

+
void al_register_trace_handler(void (*handler)(char const *))
+

Source Code

+

Register a callback which is called whenever Allegro writes something to its log files. The default logging to allegro.log is disabled while this callback is active. Pass NULL to revert to the default logging.

+

This function may be called prior to al_install_system.

+

See the example allegro5.cfg for documentation on how to configure the used debug channels, logging levels and trace format.

+

Since: 5.1.5

+

al_get_cpu_count

+
int al_get_cpu_count(void)
+

Source Code

+

Returns the number of CPU cores that the system Allegro is running on has and which could be detected, or a negative number if detection failed. Even if a positive number is returned, it might be that it is not correct. For example, Allegro running on a virtual machine will return the amount of CPU’s of the VM, and not that of the underlying system.

+

Furthermore even if the number is correct, this only gives you information about the total CPU cores of the system Allegro runs on. The amount of cores available to your program may be less due to circumstances such as programs that are currently running.

+

Therefore, it’s best to use this for advisory purposes only. It is certainly a bad idea to make your program exclusive to systems for which this function returns a certain “desirable” number.

+

This function may be called prior to al_install_system or al_init.

+

Since: 5.1.12

+

Examples:

+ +

al_get_ram_size

+
int al_get_ram_size(void)
+

Source Code

+

Returns the size in MB of the random access memory that the system Allegro is running on has and which could be detected, or a negative number if detection failed. Even if a positive number is returned, it might be that it is not correct. For example, Allegro running on a virtual machine will return the amount of RAM of the VM, and not that of the underlying system.

+

Furthermore even if the number is correct, this only gives you information about the total physical memory of the system Allegro runs on. The memory available to your program may be less or more than what this function returns due to circumstances such as virtual memory, and other programs that are currently running.

+

Therefore, it’s best to use this for advisory purposes only. It is certainly a bad idea to make your program exclusive to systems for which this function returns a certain “desirable” number.

+

This function may be called prior to al_install_system or al_init.

+

Since: 5.1.12

+

Examples:

+ +

ALLEGRO_SYSTEM_ID

+
enum ALLEGRO_SYSTEM_ID {
+

Source Code

+

The system Allegro is running on.

+
    +
  • ALLEGRO_SYSTEM_ID_UNKNOWN - Unknown system.
  • +
  • ALLEGRO_SYSTEM_ID_XGLX - Xglx
  • +
  • ALLEGRO_SYSTEM_ID_WINDOWS - Windows
  • +
  • ALLEGRO_SYSTEM_ID_MACOSX - macOS
  • +
  • ALLEGRO_SYSTEM_ID_ANDROID - Android
  • +
  • ALLEGRO_SYSTEM_ID_IPHONE - iOS
  • +
  • ALLEGRO_SYSTEM_ID_GP2XWIZ - GP2XWIZ
  • +
  • ALLEGRO_SYSTEM_ID_RASPBERRYPI - Raspberry Pi
  • +
  • ALLEGRO_SYSTEM_ID_SDL - SDL
  • +
+

Since: 5.2.5

+

See also: al_get_system_id

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:41 UTC +

+
+ + diff --git a/allegro/docs/html/refman/threads.html b/allegro/docs/html/refman/threads.html new file mode 100644 index 00000000..c37d8f33 --- /dev/null +++ b/allegro/docs/html/refman/threads.html @@ -0,0 +1,423 @@ + + + + + + + Threads + + + + + + + + +
+ + +
+

Threads

+
+ +

Allegro includes a simple cross-platform threading interface. It is a thin layer on top of two threading APIs: Windows threads and POSIX Threads (pthreads). Enforcing a consistent semantics on all platforms would be difficult at best, hence the behaviour of the following functions will differ subtly on different platforms (more so than usual). Your best bet is to be aware of this and code to the intersection of the semantics and avoid edge cases.

+

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_THREAD

+
typedef struct ALLEGRO_THREAD ALLEGRO_THREAD;
+

Source Code

+

An opaque structure representing a thread.

+

Examples:

+ +

ALLEGRO_MUTEX

+
typedef struct ALLEGRO_MUTEX ALLEGRO_MUTEX;
+

Source Code

+

An opaque structure representing a mutex.

+

Examples:

+ +

ALLEGRO_COND

+
typedef struct ALLEGRO_COND ALLEGRO_COND;
+

Source Code

+

An opaque structure representing a condition variable.

+

Examples:

+ +

al_create_thread

+
ALLEGRO_THREAD *al_create_thread(
+   void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg)
+

Source Code

+

Spawn a new thread which begins executing proc. The new thread is passed its own thread handle and the value arg.

+

Returns a pointer to the thread on success. Otherwise, returns NULL if there was an error.

+

See also: al_start_thread, al_join_thread.

+

Examples:

+ +

al_create_thread_with_stacksize

+
ALLEGRO_THREAD *al_create_thread_with_stacksize(
+   void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg, size_t stacksize)
+

Source Code

+

Spawn a new thread with the give stacksize in bytes which begins executing proc. The new thread is passed its own thread handle and the value arg.

+

Returns a pointer to the thread on success. Otherwise, returns NULL if there was an error.

+

Since: 5.2.5

+
+

Unstable API: New API, may want a better way to specify thread options.

+
+

See also: al_start_thread, al_join_thread.

+

al_start_thread

+
void al_start_thread(ALLEGRO_THREAD *thread)
+

Source Code

+

When a thread is created, it is initially in a suspended state. Calling al_start_thread will start its actual execution.

+

Starting a thread which has already been started does nothing.

+

See also: al_create_thread.

+

Examples:

+ +

al_join_thread

+
void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value)
+

Source Code

+

Wait for the thread to finish executing. This implicitly calls al_set_thread_should_stop first.

+

If ret_value is non-NULL, the value returned by the thread function will be stored at the location pointed to by ret_value.

+

See also: al_set_thread_should_stop, al_get_thread_should_stop, al_destroy_thread.

+

Examples:

+ +

al_set_thread_should_stop

+
void al_set_thread_should_stop(ALLEGRO_THREAD *thread)
+

Source Code

+

Set the flag to indicate thread should stop. Returns immediately.

+

See also: al_join_thread, al_get_thread_should_stop.

+

Examples:

+ +

al_get_thread_should_stop

+
bool al_get_thread_should_stop(ALLEGRO_THREAD *thread)
+

Source Code

+

Check if another thread is waiting for thread to stop. Threads which run in a loop should check this periodically and act on it when convenient.

+

Returns true if another thread has called al_join_thread or al_set_thread_should_stop on this thread.

+

See also: al_join_thread, al_set_thread_should_stop.

+
+

Note: We don’t support forceful killing of threads.

+
+

Examples:

+ +

al_destroy_thread

+
void al_destroy_thread(ALLEGRO_THREAD *thread)
+

Source Code

+

Free the resources used by a thread. Implicitly performs al_join_thread on the thread if it hasn’t been done already.

+

Does nothing if thread is NULL.

+

See also: al_join_thread.

+

Examples:

+ +

al_run_detached_thread

+
void al_run_detached_thread(void *(*proc)(void *arg), void *arg)
+

Source Code

+

Runs the passed function in its own thread, with arg passed to it as only parameter. This is similar to calling al_create_thread, al_start_thread and (after the thread has finished) al_destroy_thread - but you don’t have the possibility of ever calling al_join_thread on the thread.

+

al_create_mutex

+
ALLEGRO_MUTEX *al_create_mutex(void)
+

Source Code

+

Create the mutex object (a mutual exclusion device). The mutex may or may not support “recursive” locking.

+

Returns the mutex on success or NULL on error.

+

See also: al_create_mutex_recursive.

+

Examples:

+ +

al_create_mutex_recursive

+
ALLEGRO_MUTEX *al_create_mutex_recursive(void)
+

Source Code

+

Create the mutex object (a mutual exclusion device), with support for “recursive” locking. That is, the mutex will count the number of times it has been locked by the same thread. If the caller tries to acquire a lock on the mutex when it already holds the lock then the count is incremented. The mutex is only unlocked when the thread releases the lock on the mutex an equal number of times, i.e. the count drops down to zero.

+

See also: al_create_mutex.

+

al_lock_mutex

+
void al_lock_mutex(ALLEGRO_MUTEX *mutex)
+

Source Code

+

Acquire the lock on mutex. If the mutex is already locked by another thread, the call will block until the mutex becomes available and locked.

+

If the mutex is already locked by the calling thread, then the behaviour depends on whether the mutex was created with al_create_mutex or al_create_mutex_recursive. In the former case, the behaviour is undefined; the most likely behaviour is deadlock. In the latter case, the count in the mutex will be incremented and the call will return immediately.

+

See also: al_unlock_mutex.

+

We don’t yet have al_mutex_trylock.

+

Examples:

+ +

al_unlock_mutex

+
void al_unlock_mutex(ALLEGRO_MUTEX *mutex)
+

Source Code

+

Release the lock on mutex if the calling thread holds the lock on it.

+

If the calling thread doesn’t hold the lock, or if the mutex is not locked, undefined behaviour results.

+

See also: al_lock_mutex.

+

Examples:

+ +

al_destroy_mutex

+
void al_destroy_mutex(ALLEGRO_MUTEX *mutex)
+

Source Code

+

Free the resources used by the mutex. The mutex should be unlocked. Destroying a locked mutex results in undefined behaviour.

+

Does nothing if mutex is NULL.

+

Examples:

+ +

al_create_cond

+
ALLEGRO_COND *al_create_cond(void)
+

Source Code

+

Create a condition variable.

+

Returns the condition value on success or NULL on error.

+

Examples:

+ +

al_destroy_cond

+
void al_destroy_cond(ALLEGRO_COND *cond)
+

Source Code

+

Destroy a condition variable.

+

Destroying a condition variable which has threads block on it results in undefined behaviour.

+

Does nothing if cond is NULL.

+

al_wait_cond

+
void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)
+

Source Code

+

On entering this function, mutex must be locked by the calling thread. The function will atomically release mutex and block on cond. The function will return when cond is “signalled”, acquiring the lock on the mutex in the process.

+

Example of proper use:

+
al_lock_mutex(mutex);
+while (something_not_true) {
+   al_wait_cond(cond, mutex);
+}
+do_something();
+al_unlock_mutex(mutex);
+

The mutex should be locked before checking the condition, and should be rechecked al_wait_cond returns. al_wait_cond can return for other reasons than the condition becoming true (e.g. the process was signalled). If multiple threads are blocked on the condition variable, the condition may no longer be true by the time the second and later threads are unblocked. Remember not to unlock the mutex prematurely.

+

See also: al_wait_cond_until, al_broadcast_cond, al_signal_cond.

+

Examples:

+ +

al_wait_cond_until

+
int al_wait_cond_until(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex,
+   const ALLEGRO_TIMEOUT *timeout)
+

Source Code

+

Like al_wait_cond but the call can return if the absolute time passes timeout before the condition is signalled.

+

Returns zero on success, non-zero if the call timed out.

+

See also: al_wait_cond

+

al_broadcast_cond

+
void al_broadcast_cond(ALLEGRO_COND *cond)
+

Source Code

+

Unblock all threads currently waiting on a condition variable. That is, broadcast that some condition which those threads were waiting for has become true.

+

See also: al_signal_cond.

+
+

Note: The pthreads spec says to lock the mutex associated with cond before signalling for predictable scheduling behaviour.

+
+

Examples:

+ +

al_signal_cond

+
void al_signal_cond(ALLEGRO_COND *cond)
+

Source Code

+

Unblock at least one thread waiting on a condition variable.

+

Generally you should use al_broadcast_cond but al_signal_cond may be more efficient when it’s applicable.

+

See also: al_broadcast_cond.

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/time.html b/allegro/docs/html/refman/time.html new file mode 100644 index 00000000..70f1f511 --- /dev/null +++ b/allegro/docs/html/refman/time.html @@ -0,0 +1,226 @@ + + + + + + + Time routines + + + + + + + + +
+ + +
+

Time routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_TIMEOUT

+
typedef struct ALLEGRO_TIMEOUT ALLEGRO_TIMEOUT;
+

Source Code

+

Represent a timeout value. The size of the structure is known so it can be statically allocated. The contents are private.

+

See also: al_init_timeout

+

Examples:

+ +

al_get_time

+
double al_get_time(void)
+

Source Code

+

Return the number of seconds since the Allegro library was initialised. The return value is undefined if Allegro is uninitialised. The resolution depends on the used driver, but typically can be in the order of microseconds.

+

Examples:

+ +

al_init_timeout

+
void al_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds)
+

Source Code

+

Set timeout value of some number of seconds after the function call.

+

For compatibility with all platforms, seconds must be 2,147,483.647 seconds or less.

+

See also: ALLEGRO_TIMEOUT, al_wait_for_event_until

+

Examples:

+ +

al_rest

+
void al_rest(double seconds)
+

Source Code

+

Waits for the specified number of seconds. This tells the system to pause the current thread for the given amount of time. With some operating systems, the accuracy can be in the order of 10ms. That is, even

+
al_rest(0.000001)
+

might pause for something like 10ms. Also see the section on Timer routines for easier ways to time your program without using up all CPU.

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/timer.html b/allegro/docs/html/refman/timer.html new file mode 100644 index 00000000..9793b80f --- /dev/null +++ b/allegro/docs/html/refman/timer.html @@ -0,0 +1,337 @@ + + + + + + + Timer routines + + + + + + + + +
+ + +
+

Timer routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_TIMER

+
typedef struct ALLEGRO_TIMER ALLEGRO_TIMER;
+

Source Code

+

This is an abstract data type representing a timer object.

+

Examples:

+ +

ALLEGRO_USECS_TO_SECS

+
#define ALLEGRO_USECS_TO_SECS(x)      ((x) / 1000000.0)
+

Source Code

+

Convert microseconds to seconds.

+

ALLEGRO_MSECS_TO_SECS

+
#define ALLEGRO_MSECS_TO_SECS(x)      ((x) / 1000.0)
+

Source Code

+

Convert milliseconds to seconds.

+

ALLEGRO_BPS_TO_SECS

+
#define ALLEGRO_BPS_TO_SECS(x)        (1.0 / (x))
+

Source Code

+

Convert beats per second to seconds.

+

Examples:

+ +

ALLEGRO_BPM_TO_SECS

+
#define ALLEGRO_BPM_TO_SECS(x)        (60.0 / (x))
+

Source Code

+

Convert beats per minute to seconds.

+

al_create_timer

+
ALLEGRO_TIMER *al_create_timer(double speed_secs)
+

Source Code

+

Allocates and initializes a timer. If successful, a pointer to a new timer object is returned, otherwise NULL is returned. speed_secs is in seconds per “tick”, and must be positive. The new timer is initially stopped.

+

Usage note: typical granularity is on the order of microseconds, but with some drivers might only be milliseconds.

+

See also: al_start_timer, al_destroy_timer

+

Examples:

+ +

al_start_timer

+
void al_start_timer(ALLEGRO_TIMER *timer)
+

Source Code

+

Start the timer specified. From then, the timer’s counter will increment at a constant rate, and it will begin generating events. Starting a timer that is already started does nothing. Starting a timer that was stopped will reset the timer’s counter, effectively restarting the timer from the beginning.

+

See also: al_stop_timer, al_get_timer_started, al_resume_timer

+

Examples:

+ +

al_resume_timer

+
void al_resume_timer(ALLEGRO_TIMER *timer)
+

Source Code

+

Resume the timer specified. From then, the timer’s counter will increment at a constant rate, and it will begin generating events. Resuming a timer that is already started does nothing. Resuming a stopped timer will not reset the timer’s counter (unlike al_start_timer).

+

See also: al_start_timer, al_stop_timer, al_get_timer_started

+

Examples:

+ +

al_stop_timer

+
void al_stop_timer(ALLEGRO_TIMER *timer)
+

Source Code

+

Stop the timer specified. The timer’s counter will stop incrementing and it will stop generating events. Stopping a timer that is already stopped does nothing.

+

See also: al_start_timer, al_get_timer_started, al_resume_timer

+

Examples:

+ +

al_get_timer_started

+
bool al_get_timer_started(const ALLEGRO_TIMER *timer)
+

Source Code

+

Return true if the timer specified is currently started.

+

al_destroy_timer

+
void al_destroy_timer(ALLEGRO_TIMER *timer)
+

Source Code

+

Uninstall the timer specified. If the timer is started, it will automatically be stopped before uninstallation. It will also automatically unregister the timer with any event queues.

+

Does nothing if passed the NULL pointer.

+

See also: al_create_timer

+

Examples:

+ +

al_get_timer_count

+
int64_t al_get_timer_count(const ALLEGRO_TIMER *timer)
+

Source Code

+

Return the timer’s counter value. The timer can be started or stopped.

+

See also: al_set_timer_count

+

Examples:

+ +

al_set_timer_count

+
void al_set_timer_count(ALLEGRO_TIMER *timer, int64_t new_count)
+

Source Code

+

Set the timer’s counter value. The timer can be started or stopped. The count value may be positive or negative, but will always be incremented by +1 at each tick.

+

See also: al_get_timer_count, al_add_timer_count

+

Examples:

+ +

al_add_timer_count

+
void al_add_timer_count(ALLEGRO_TIMER *timer, int64_t diff)
+

Source Code

+

Add diff to the timer’s counter value. This is similar to writing:

+
al_set_timer_count(timer, al_get_timer_count(timer) + diff);
+

except that the addition is performed atomically, so no ticks will be lost.

+

See also: al_set_timer_count

+

al_get_timer_speed

+
double al_get_timer_speed(const ALLEGRO_TIMER *timer)
+

Source Code

+

Return the timer’s speed, in seconds. (The same value passed to al_create_timer or al_set_timer_speed.)

+

See also: al_set_timer_speed

+

al_set_timer_speed

+
void al_set_timer_speed(ALLEGRO_TIMER *timer, double new_speed_secs)
+

Source Code

+

Set the timer’s speed, i.e. the rate at which its counter will be incremented when it is started. This can be done when the timer is started or stopped. If the timer is currently running, it is made to look as though the speed change occurred precisely at the last tick.

+

speed_secs has exactly the same meaning as with al_create_timer.

+

See also: al_get_timer_speed

+

Examples:

+ +

al_get_timer_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_timer_event_source(ALLEGRO_TIMER *timer)
+

Source Code

+

Retrieve the associated event source. Timers will generate events of type ALLEGRO_EVENT_TIMER.

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/touch.html b/allegro/docs/html/refman/touch.html new file mode 100644 index 00000000..89914b5c --- /dev/null +++ b/allegro/docs/html/refman/touch.html @@ -0,0 +1,337 @@ + + + + + + + Touch input + + + + + + + + +
+ + +
+

Touch input

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

ALLEGRO_TOUCH_INPUT

+
typedef struct ALLEGRO_TOUCH_INPUT ALLEGRO_TOUCH_INPUT;
+

Source Code

+

An abstract data type representing a physical touch screen or touch pad.

+

Since: 5.1.0

+

ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT

+
#define ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT        16
+

Source Code

+

The maximum amount of simultaneous touches that can be detected.

+

Since: 5.1.0

+

ALLEGRO_TOUCH_STATE

+
typedef struct ALLEGRO_TOUCH_STATE ALLEGRO_TOUCH_STATE;
+

Source Code

+

This is a structure that is used to hold a “snapshot” of a touch at a particular instant.

+

Public fields (read only):

+
    +
  • id - identifier of the touch. If the touch is valid, this is positive.
  • +
  • x - touch x position
  • +
  • y - touch y position
  • +
  • dx - touch relative x position
  • +
  • dy - touch relative y position
  • +
  • primary - TRUE if this touch is the primary one (usually the first one).
  • +
  • display - The ALLEGRO_DISPLAY that was touched.
  • +
+

Since: 5.1.0

+

ALLEGRO_TOUCH_INPUT_STATE

+
typedef struct ALLEGRO_TOUCH_INPUT_STATE ALLEGRO_TOUCH_INPUT_STATE;
+

Source Code

+

This is a structure that holds a snapshot of all simultaneous touches at a particular instant.

+

Public fields (read only):

+ +

Since: 5.1.0

+

ALLEGRO_MOUSE_EMULATION_MODE

+
typedef enum ALLEGRO_MOUSE_EMULATION_MODE
+

Source Code

+

Type of mouse emulation to apply.

+
+
ALLEGRO_MOUSE_EMULATION_NONE
+
Disables mouse emulation. +
+
ALLEGRO_MOUSE_EMULATION_TRANSPARENT
+
Enables transparent mouse emulation. +
+
ALLEGRO_MOUSE_EMULATION_INCLUSIVE
+
Enable inclusive mouse emulation. +
+
ALLEGRO_MOUSE_EMULATION_EXCLUSIVE
+
Enables exclusive mouse emulation. +
+
ALLEGRO_MOUSE_EMULATION_5_0_x
+
Enables mouse emulation that is backwards compatible with Allegro 5.0.x. +
+
+

Since: 5.1.0

+
+

Unstable API: Seems of limited value, as touch input tends to have different semantics compared to mouse input.

+
+

al_install_touch_input

+
bool al_install_touch_input(void)
+

Source Code

+

Install a touch input driver, returning true if successful. If a touch input driver was already installed, returns true immediately.

+

Since: 5.1.0

+

See also: al_uninstall_touch_input

+

Examples:

+ +

al_uninstall_touch_input

+
void al_uninstall_touch_input(void)
+

Source Code

+

Uninstalls the active touch input driver. If no touch input driver was active, this function does nothing.

+

This function is automatically called when Allegro is shut down.

+

Since: 5.1.0

+

See also: al_install_touch_input

+

al_is_touch_input_installed

+
bool al_is_touch_input_installed(void)
+

Source Code

+

Returns true if al_install_touch_input was called successfully.

+

Since: 5.1.0

+

Examples:

+ +

al_get_touch_input_state

+
void al_get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state)
+

Source Code

+

Gets the current touch input state. The touch information is copied into the ALLEGRO_TOUCH_INPUT_STATE you provide to this function.

+

Since: 5.1.0

+

al_set_mouse_emulation_mode

+
void al_set_mouse_emulation_mode(int mode)
+

Source Code

+

Sets the kind of mouse emulation for the touch input subsystem to perform.

+

Since: 5.1.0

+
+

Unstable API: Seems of limited value, as touch input tends to have different semantics compared to mouse input.

+
+

See also: ALLEGRO_MOUSE_EMULATION_MODE, al_get_mouse_emulation_mode.

+

Examples:

+ +

al_get_mouse_emulation_mode

+
int al_get_mouse_emulation_mode(void)
+

Source Code

+

Returns the kind of mouse emulation which the touch input subsystem is set to perform.

+

Since: 5.1.0

+
+

Unstable API: Seems of limited value, as touch input tends to have different semantics compared to mouse input.

+
+

See also: ALLEGRO_MOUSE_EMULATION_MODE, al_set_mouse_emulation_mode.

+

al_get_touch_input_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_touch_input_event_source(void)
+

Source Code

+

Returns the global touch input event source. This event source generates touch input events.

+

Since: 5.1.0

+

See also: ALLEGRO_EVENT_SOURCE, al_register_event_source

+

Examples:

+ +

al_get_touch_input_mouse_emulation_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_touch_input_mouse_emulation_event_source(void)
+

Source Code

+

Returns the global touch input event source for emulated mouse events. This event source generates emulated mouse events that are based on touch events.

+

See also: ALLEGRO_EVENT_SOURCE, al_register_event_source

+

Since: 5.1.0

+
+

Unstable API: Seems of limited value, as touch input tends to have different semantics compared to mouse input.

+
+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/transformations.html b/allegro/docs/html/refman/transformations.html new file mode 100644 index 00000000..c0362358 --- /dev/null +++ b/allegro/docs/html/refman/transformations.html @@ -0,0 +1,733 @@ + + + + + + + Transformations + + + + + + + + +
+ + +
+

Transformations

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

Transformations allow you to transform the coordinates you use for drawing operations without additional overhead. Scaling, rotating, translating, and combinations of these are possible as well as using custom transformations. There are two types of transformations that you can set, ‘regular’ transformations and projection transformations. The projection transform is rarely used in 2D games, but is common in 3D games to set up the projection from the 3D world to the 2D screen. Typically, you would use the regular transform for non-projective types of transformations (that is, translations, rotations, scales, skews… i.e. transformations that are linear), while the projection transform will be used for setting up perspective and possibly more advanced effects. It is possible to do everything with just using the projection transformation (that is, you’d compose the projection transformation with the non-projection transformations that, e.g., move the camera in the world), but it is more convenient to use both for two reasons:

+
    +
  • Regular transformations can be changed while the bitmap drawing is held (see al_hold_bitmap_drawing).

  • +
  • Regular transformations work with memory bitmaps.

  • +
+

As a result, if you’re making a 2D game, it’s best to leave the projection transformations at their default values.

+

Both types of transformations are set per target-bitmap, i.e. a change of the target bitmap will also change the active transformation.

+

Allegro provides convenience functions to construct transformations in 2D and 3D variants (the latter with a _3d suffix), so you don’t have to deal with the underlying matrix algebra yourself.

+

The transformations are combined in the order of the function invocations. Thus to create a transformation that first rotates a point and then translates it, you would (starting with an identity transformation) call al_rotate_transform and then al_translate_transform. This approach is opposite of what OpenGL uses but similar to what Direct3D uses.

+

For those who know the matrix algebra going behind the scenes, what the transformation functions in Allegro do is “pre-multiply” the successive transformations. So, for example, if you have code that does:

+
al_identity_transform(&T);
+
+al_compose_transform(&T, &T1);
+al_compose_transform(&T, &T2);
+al_compose_transform(&T, &T3);
+al_compose_transform(&T, &T4);
+

The resultant matrix multiplication expression will look like this:

+
T4 * T3 * T2 * T1
+

Since the point coordinate vector term will go on the right of that sequence of factors, the transformation that is called first, will also be applied first.

+

This means if you have code like this:

+
al_identity_transform(&T1);
+al_scale_transform(&T1, 2, 2);
+al_identity_transform(&T2);
+al_translate_transform(&T2, 100, 0);
+
+al_identity_transform(&T);
+
+al_compose_transform(&T, &T1);
+al_compose_transform(&T, &T2);
+
+al_use_transform(&T);
+

it does exactly the same as:

+
al_identity_transform(&T);
+al_scale_transform(&T, 2, 2);
+al_translate_transform(&T, 100, 0);
+al_use_transform(&T);
+

ALLEGRO_TRANSFORM

+
typedef struct ALLEGRO_TRANSFORM ALLEGRO_TRANSFORM;
+

Source Code

+

Defines the generic transformation type, a 4x4 matrix. 2D transforms use only a small subsection of this matrix, namely the top left 2x2 matrix, and the right most 2x1 matrix, for a total of 6 values.

+

Fields:

+
    +
  • m - A 4x4 float matrix
  • +
+

Examples:

+ +

al_copy_transform

+
void al_copy_transform(ALLEGRO_TRANSFORM *dest, const ALLEGRO_TRANSFORM *src)
+

Source Code

+

Makes a copy of a transformation.

+

Parameters:

+
    +
  • dest - Source transformation
  • +
  • src - Destination transformation
  • +
+

Examples:

+ +

al_use_transform

+
void al_use_transform(const ALLEGRO_TRANSFORM *trans)
+

Source Code

+

Sets the transformation to be used for the the drawing operations on the target bitmap (each bitmap maintains its own transformation). Every drawing operation after this call will be transformed using this transformation. Call this function with an identity transformation to return to the default behaviour.

+

This function does nothing if there is no target bitmap.

+

The parameter is passed by reference as an optimization to avoid the overhead of stack copying. The reference will not be stored in the Allegro library so it is safe to pass references to local variables.

+
void setup_my_transformation(void)
+{
+   ALLEGRO_TRANSFORM transform;
+   al_translate_transform(&transform, 5, 10);
+   al_use_transform(&transform);
+}
+

Parameters:

+
    +
  • trans - Transformation to use
  • +
+

See also: al_get_current_transform, al_transform_coordinates

+

Examples:

+ +

al_get_current_transform

+
const ALLEGRO_TRANSFORM *al_get_current_transform(void)
+

Source Code

+

Returns the transformation of the current target bitmap, as set by al_use_transform. If there is no target bitmap, this function returns NULL.

+

Returns: A pointer to the current transformation.

+

See also: al_get_current_projection_transform

+

Examples:

+ +

al_use_projection_transform

+
void al_use_projection_transform(const ALLEGRO_TRANSFORM *trans)
+

Source Code

+

Sets the projection transformation to be used for the drawing operations on the target bitmap (each bitmap maintains its own projection transformation). Every drawing operation after this call will be transformed using this transformation. To return default behavior, call this function with an orthographic transform like so:

+
ALLEGRO_TRANSFORM trans;
+al_identity_transform(&trans);
+al_orthographic_transform(&trans, 0, 0, -1.0, al_get_bitmap_width(bitmap),
+                          al_get_bitmap_height(bitmap), 1.0);
+
+al_set_target_bitmap(bitmap);
+al_use_projection_transform(&trans);
+

The orthographic transformation above is the default projection transform.

+

This function does nothing if there is no target bitmap. This function also does nothing if the bitmap is a memory bitmap (i.e. memory bitmaps always use an orthographic transform like the snippet above). Note that the projection transform will be reset to default if a video bitmap is converted to a memory bitmap. Additionally, if the bitmap in question is the backbuffer, it’s projection transformation will be reset to default if it is resized. Lastly, when you draw a memory bitmap to a video bitmap with a custom projection transform, this transformation will be ignored (i.e. it’ll be as if the projection transform of the target bitmap was temporarily reset to default).

+

The parameter is passed by reference as an optimization to avoid the overhead of stack copying. The reference will not be stored in the Allegro library so it is safe to pass references to local variables.

+

Since: 5.1.9

+

See also: al_get_current_projection_transform, al_perspective_transform, al_orthographic_transform

+

Examples:

+ +

al_get_current_projection_transform

+
const ALLEGRO_TRANSFORM *al_get_current_projection_transform(void)
+

Source Code

+

If there is no target bitmap, this function returns NULL.

+

Returns: A pointer to the current transformation.

+

Since: 5.1.9

+

See also: al_use_projection_transform

+

Examples:

+ +

al_get_current_inverse_transform

+
const ALLEGRO_TRANSFORM *al_get_current_inverse_transform(void)
+

Source Code

+

Returns the inverse of the current transformation of the target bitmap. If there is no target bitmap, this function returns NULL.

+

This is similar to calling al_invert_transform(al_get_current_transform()) but the result of this function is cached.

+
+

Note: Allegro’s transformation inversion functions work correctly only with 2D transformations.

+
+

Since: 5.1.0

+

al_invert_transform

+
void al_invert_transform(ALLEGRO_TRANSFORM *trans)
+

Source Code

+

Inverts the passed transformation. If the transformation is nearly singular (close to not having an inverse) then the returned transformation may be invalid. Use al_check_inverse to ascertain if the transformation has an inverse before inverting it if you are in doubt.

+

Parameters:

+
    +
  • trans - Transformation to invert
  • +
+
+

Note: Allegro’s transformation inversion functions work correctly only with 2D transformations.

+
+

See also: al_check_inverse

+

al_transpose_transform

+
void al_transpose_transform(ALLEGRO_TRANSFORM *trans)
+

Source Code

+

Transposes the matrix of the given transform. This can be used for inversing a rotation transform. For example:

+
al_build_camera_transform(camera, 0, 0, 0, x, y, z, xu, yu, zu)
+al_copy_transform(inverse, camera)
+al_transpose_transform(camera)
+// Now "inverse" will be a transformation rotating in the opposite
+// direction from "camera". Note that this only works if the camera
+// position is 0/0/0 as in the example.
+

Since: 5.2.5

+

al_check_inverse

+
int al_check_inverse(const ALLEGRO_TRANSFORM *trans, float tol)
+

Source Code

+

Checks if the transformation has an inverse using the supplied tolerance. Tolerance should be a small value between 0 and 1, with 1e-7 being sufficient for most applications.

+

In this function tolerance specifies how close the determinant can be to 0 (if the determinant is 0, the transformation has no inverse). Thus the smaller the tolerance you specify, the “worse” transformations will pass this test. Using a tolerance of 1e-7 will catch errors greater than 1/1000’s of a pixel, but let smaller errors pass. That means that if you transformed a point by a transformation and then transformed it again by the inverse transformation that passed this check, the resultant point should less than 1/1000’s of a pixel away from the original point.

+

Note that this check is superfluous most of the time if you never touched the transformation matrix values yourself. The only thing that would cause the transformation to not have an inverse is if you applied a 0 (or very small) scale to the transformation or you have a really large translation. As long as the scale is comfortably above 0, the transformation will be invertible.

+

Parameters:

+
    +
  • trans - Transformation to check
  • +
  • tol - Tolerance
  • +
+

Returns: 1 if the transformation is invertible, 0 otherwise

+
+

Note: Allegro’s transformation inversion functions work correctly only with 2D transformations.

+
+

See also: al_invert_transform

+

al_identity_transform

+
void al_identity_transform(ALLEGRO_TRANSFORM *trans)
+

Source Code

+

Sets the transformation to be the identity transformation. This is the default transformation. Use al_use_transform on an identity transformation to return to the default.

+
ALLEGRO_TRANSFORM t;
+al_identity_transform(&t);
+al_use_transform(&t);
+

Parameters:

+
    +
  • trans - Transformation to alter
  • +
+

See also: al_translate_transform, al_rotate_transform, al_scale_transform

+

Examples:

+ +

al_build_transform

+
void al_build_transform(ALLEGRO_TRANSFORM *trans, float x, float y,
+   float sx, float sy, float theta)
+

Source Code

+

Builds a transformation given some parameters. This call is equivalent to calling the transformations in this order: make identity, rotate, scale, translate. This method is faster, however, than actually calling those functions.

+

Parameters:

+
    +
  • trans - Transformation to alter
  • +
  • x, y - Translation
  • +
  • sx, sy - Scale
  • +
  • theta - Rotation angle in radians
  • +
+
+

Note: this function was previously documented to be equivalent to a different (and more useful) order of operations: identity, scale, rotate, translate.

+
+

See also: al_translate_transform, al_rotate_transform, al_scale_transform, al_compose_transform

+

Examples:

+ +

al_build_camera_transform

+
void al_build_camera_transform(ALLEGRO_TRANSFORM *trans,
+   float position_x, float position_y, float position_z,
+   float look_x, float look_y, float look_z,
+   float up_x, float up_y, float up_z)
+

Source Code

+

Builds a transformation which can be used to transform 3D coordinates in world space to camera space. This involves translation and a rotation. The function expects three coordinate triplets: The camera’s position, the position the camera is looking at and an up vector. The up vector does not need to be of unit length and also does not need to be perpendicular to the view direction - it can usually just be the world up direction (most commonly 0/1/0).

+

For example:

+
al_build_camera_transform(&t,
+    1, 1, 1,
+    5, 5, 5,
+    0, 1, 0);
+

This create a transformation for a camera standing at 1/1/1 and looking towards 5/5/5.

+
+

Note: If the position and look parameters are identical, or if the up direction is parallel to the view direction, an identity matrix is created.

+
+

Another example which will simply re-create the identity matrix:

+
al_build_camera_transform(&t,
+    0, 0, 0,
+    0, 0, -1,
+    0, 1, 0);
+

An example where the up vector will cause the camera to lean (roll) by 45 degrees:

+
al_build_camera_transform(&t,
+    1, 1, 1,
+    5, 5, 5,
+    1, 1, 0);
+

Since 5.1.9

+

See also: al_translate_transform_3d, al_rotate_transform_3d, al_scale_transform_3d, al_compose_transform, al_use_transform

+

Examples:

+ +

al_translate_transform

+
void al_translate_transform(ALLEGRO_TRANSFORM *trans, float x, float y)
+

Source Code

+

Apply a translation to a transformation.

+

Parameters:

+
    +
  • trans - Transformation to alter
  • +
  • x, y - Translation
  • +
+

See also: al_rotate_transform, al_scale_transform, al_build_transform

+

Examples:

+ +

al_rotate_transform

+
void al_rotate_transform(ALLEGRO_TRANSFORM *trans, float theta)
+

Source Code

+

Apply a rotation to a transformation.

+

Parameters:

+
    +
  • trans - Transformation to alter
  • +
  • theta - Rotation angle in radians
  • +
+

See also: al_translate_transform, al_scale_transform, al_build_transform

+

Examples:

+ +

al_scale_transform

+
void al_scale_transform(ALLEGRO_TRANSFORM *trans, float sx, float sy)
+

Source Code

+

Apply a scale to a transformation.

+

Parameters:

+
    +
  • trans - Transformation to alter
  • +
  • sx, sy - Scale
  • +
+

See also: al_translate_transform, al_rotate_transform, al_build_transform

+

Examples:

+ +

al_transform_coordinates

+
void al_transform_coordinates(const ALLEGRO_TRANSFORM *trans, float *x, float *y)
+

Source Code

+

Transform a pair of coordinates.

+

Parameters:

+
    +
  • trans - Transformation to use
  • +
  • x, y - Pointers to the coordinates
  • +
+

See also: al_use_transform, al_transform_coordinates_3d

+

Examples:

+ +

al_transform_coordinates_3d

+
void al_transform_coordinates_3d(const ALLEGRO_TRANSFORM *trans,
+   float *x, float *y, float *z)
+

Source Code

+

Transform x, y, z coordinates.

+

Parameters:

+
    +
  • trans - Transformation to use
  • +
  • x, y, z - Pointers to the coordinates
  • +
+

Note: If you are using a projection transform you most likely will want to use al_transform_coordinates_3d_projective instead.

+

Since 5.1.9

+

See also: al_use_transform, al_transform_coordinates

+

Examples:

+ +

al_transform_coordinates_4d

+
void al_transform_coordinates_4d(const ALLEGRO_TRANSFORM *trans,
+   float *x, float *y, float *z, float *w)
+

Source Code

+

Transform x, y, z, w coordinates.

+

Parameters:

+
    +
  • trans - Transformation to use
  • +
  • x, y, z, w - Pointers to the coordinates
  • +
+

Since 5.2.4

+

See also: al_use_transform, al_transform_coordinates, al_transform_coordinates_3d

+

al_transform_coordinates_3d_projective

+
void al_transform_coordinates_3d_projective(const ALLEGRO_TRANSFORM *trans,
+   float *x, float *y, float *z)
+

Source Code

+

Transform x, y, z as homogeneous coordinates. This is the same as using al_transform_coordinates_4d with the w coordinate set to 1, then dividing x, y, z by the resulting w. This will provide the same normalized coordinates Allegro will draw to when a projective transform is in effect as set with al_use_projection_transform. To get the actual pixel coordinates from those translate and scale like so (w and h would be the pixel dimensions of the target bitmap):

+
x = w / 2 + x * w / 2
+y = h / 2 - y * h / 2
+

Parameters:

+
    +
  • trans - Transformation to use
  • +
  • x, y, z - Pointers to the coordinates
  • +
+

Example:

+
ALLEGRO_TRANSFORM t2;
+al_copy_transform(&t2, al_get_current_transform());
+al_compose_transform(&t2, al_get_current_projection_transform());
+
+ALLEGRO_TRANSFORM t3;
+al_identity_transform(&t3);
+al_scale_transform(&t3, 0.5, -0.5);
+al_translate_transform(&t3, 0.5, 0.5);
+al_scale_transform(&t3, al_get_bitmap_width(al_get_target_bitmap()),
+                   al_get_bitmap_height(al_get_target_bitmap()));
+
+al_transform_coordinates_3d_projective(&t2, &x, &y, &z);
+// x, y now contain normalized coordinates
+al_transform_coordinates(&t3, &x, &y);
+// x, y now contain pixel coordinates
+

Since 5.2.4

+

See also: al_use_transform, al_transform_coordinates, al_transform_coordinates_3d, al_use_projection_transform

+

al_compose_transform

+
void al_compose_transform(ALLEGRO_TRANSFORM *trans, const ALLEGRO_TRANSFORM *other)
+

Source Code

+

Compose (combine) two transformations by a matrix multiplication.

+
trans := trans other
+

Note that the order of matrix multiplications is important. The effect of applying the combined transform will be as if first applying trans and then applying other and not the other way around.

+

Parameters:

+
    +
  • trans - Transformation to alter
  • +
  • other - Transformation used to transform trans
  • +
+

See also: al_translate_transform, al_rotate_transform, al_scale_transform

+

al_orthographic_transform

+
void al_orthographic_transform(ALLEGRO_TRANSFORM *trans,
+   float left, float top, float n,
+   float right, float bottom, float f)
+

Source Code

+

Combines the given transformation with an orthographic transformation which maps the screen rectangle to the given left/top and right/bottom coordinates.

+

near/far is the z range, coordinates outside of that range will get clipped. Normally -1/1 is fine because all 2D graphics will have a z coordinate of 0. However if you for example do al_draw_rectangle(0, 0, 100, 100) and rotate around the x axis (“towards the screen”) make sure your z range allows values from -100 to 100 or the rotated rectangle will get clipped.

+

Also, if you are using a depth buffer the z range decides the depth resolution. For example if you have a 16 bit depth buffer there are only 65536 discrete depth values. So if your near/far is set to -1000000/1000000 most of the z positions would not result in separate depth values which could lead to artifacts.

+

The result of applying this transformation to coordinates will be to normalize visible coordinates into the cube from -1/-1/-1 to 1/1/1. Such a transformation is mostly useful for passing it to al_use_projection_transform - see that function for an example use.

+

Since: 5.1.3

+

See also: al_use_projection_transform, al_perspective_transform

+

Examples:

+ +

al_perspective_transform

+
void al_perspective_transform(ALLEGRO_TRANSFORM *trans,
+   float left, float top, float n,
+   float right, float bottom, float f)
+

Source Code

+

Like al_orthographic_transform but honors perspective. If everything is at a z-position of -near it will look the same as with an orthographic transformation.

+

To use a specific horizontal field of view you can use the relation:

+
tan(hfov / 2) = (right - left) / 2 / near
+

and therefore

+
near = (right - left) / 2 / tan(hfov / 2)
+

Example 1:

+
   float w = 800, h = 450; // assume our display is 800 x 450
+   float fov = tan(90 * ALLEGRO_PI / 180 / 2); // 90 degree field of view
+
+   // Our projection goes from 0/0 to w/h with the near parameter set
+   // for a 90 degree horizontal viewing angle.
+   ALLEGRO_TRANSFORM projection;
+   al_identity_transform(&projection);
+   al_perspective_transform(&projection, 0, 0,
+    w / 2 / fov,
+    w, h,
+    2000);
+   al_use_projection_transform(&projection);
+
+   // Set the camera z to +400 (which is exactly the near distance)
+   ALLEGRO_TRANSFORM camera;
+   al_build_camera_transform(&camera, 0, 0, 400, 0, 0, 0, 0, 1, 0);
+   al_use_transform(&camera);
+
+   // This will draw two rectangles at the left and right edge of the
+   // screen and vertically centered. The x distance between them is 800
+   // units, but the camera transform moves them 400 along z, so with
+   // a 90° viewing angle both are visible.
+   al_draw_filled_rectangle(0, 200, 50, 250, red;
+   al_draw_filled_rectangle(750, 200, 800, 250, red);
+

Example 2:

+
   float w = 800, h = 450; // assume our display is 800 x 450
+   float fov = tan(90 * ALLEGRO_PI / 180 / 2); // 90 degree field of view
+   float aspect = h / w;
+   float zoom = 2; // enlarge x 2
+
+   // This projection is very different from the one in the first example.
+   // Here we map the left and right edge of the screen to -1 and +1. And
+   // the y axis goes from -1 at the bottom to +1 at the top, scaled by
+   // the aspect ratio. We also add a zoom parameter so we can control
+   // the visible portion of the scene independent of the field of view.
+   ALLEGRO_TRANSFORM projection;
+   al_identity_transform(&projection);
+   al_perspective_transform(&projection,
+      -1 / zoom, aspect / zoom,
+      1 / fov,
+      1 / zoom, -aspect / zoom,
+      2000);
+   al_use_projection_transform(&projection);
+
+   // Moves everything by -4 in the z direction.
+   ALLEGRO_TRANSFORM camera;
+   al_build_camera_transform(&camera, 0, 0, 4, 0, 0, 0, 0, 1, 0);
+   al_use_transform(&camera);
+
+   // At a z distance of 4 with a 90° hfov everything would be scaled
+   // down to 25%. However we also zoom 2-fold, so the final scaling is
+   // 50%. This rectangle therefore will appear at a size of 400 x 225
+   // pixel (assuming the display is 800 x 450).
+   al_draw_filled_rectangle(-1, -1, 1, 1, red);
+

Since: 5.1.3

+

See also: al_use_projection_transform, al_orthographic_transform

+

Examples:

+ +

al_translate_transform_3d

+
void al_translate_transform_3d(ALLEGRO_TRANSFORM *trans, float x, float y,
+    float z)
+

Source Code

+

Combines the given transformation with a transformation which translates coordinates by the given vector.

+

Since: 5.1.3

+

See also: al_use_projection_transform

+

Examples:

+ +

al_scale_transform_3d

+
void al_scale_transform_3d(ALLEGRO_TRANSFORM *trans, float sx, float sy,
+    float sz)
+

Source Code

+

Combines the given transformation with a transformation which scales coordinates by the given vector.

+

Since: 5.1.3

+

See also: al_use_projection_transform

+

al_rotate_transform_3d

+
void al_rotate_transform_3d(ALLEGRO_TRANSFORM *trans,
+   float x, float y, float z, float angle)
+

Source Code

+

Combines the given transformation with a transformation which rotates coordinates around the given vector by the given angle in radians.

+

Note: The vector is assumed to be of unit length (otherwise it will also incur a scale).

+

Since: 5.1.3

+

Examples:

+ +

al_horizontal_shear_transform

+
void al_horizontal_shear_transform(ALLEGRO_TRANSFORM* trans, float theta)
+

Source Code

+

Apply a horizontal shear to the transform

+

Parameters:

+
    +
  • trans - Transformation to alter
  • +
  • theta - Rotation angle in radians
  • +
+

Since: 5.1.7

+

See also: al_vertical_shear_transform

+

al_vertical_shear_transform

+
void al_vertical_shear_transform(ALLEGRO_TRANSFORM* trans, float theta)
+

Source Code

+

Apply a vertical shear to the transform

+

Parameters:

+
    +
  • trans - Transformation to alter
  • +
  • theta - Rotation angle in radians
  • +
+

Since: 5.1.7

+

See also: al_horizontal_shear_transform

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/utf8.html b/allegro/docs/html/refman/utf8.html new file mode 100644 index 00000000..1193ab0f --- /dev/null +++ b/allegro/docs/html/refman/utf8.html @@ -0,0 +1,1040 @@ + + + + + + + UTF-8 string routines + + + + + + + + +
+ + +
+

UTF-8 string routines

+
+ +

These functions are declared in the main Allegro header file:

+
 #include <allegro5/allegro.h>
+

About UTF-8 string routines

+

Some parts of the Allegro API, such as the font rountines, expect Unicode strings encoded in UTF-8. The following basic routines are provided to help you work with UTF-8 strings, however it does not mean you need to use them. You should consider another library (e.g. ICU) if you require more functionality.

+

Briefly, Unicode is a standard consisting of a large character set of over 100,000 characters, and rules, such as how to sort strings. A code point is the integer value of a character, but not all code points are characters, as some code points have other uses. Unlike legacy character sets, the set of code points is open ended and more are assigned with time.

+

Clearly it is impossible to represent each code point with a 8-bit byte (limited to 256 code points) or even a 16-bit integer (limited to 65536 code points). It is possible to store code points in a 32-bit integers but it is space inefficient, and not actually that useful (at least, when handling the full complexity of Unicode; Allegro only does the very basics). There exist different Unicode Transformation Formats for encoding code points into smaller code units. The most important transformation formats are UTF-8 and UTF-16.

+

UTF-8 is a variable-length encoding which encodes each code point to between one and four 8-bit bytes each. UTF-8 has many nice properties, but the main advantages are that it is backwards compatible with C strings, and ASCII characters (code points in the range 0-127) are encoded in UTF-8 exactly as they would be in ASCII.

+

UTF-16 is another variable-length encoding, but encodes each code point to one or two 16-bit words each. It is, of course, not compatible with traditional C strings. Allegro does not generally use UTF-16 strings.

+

Here is a diagram of the representation of the word “ål”, with a NUL terminator, in both UTF-8 and UTF-16.

+
                   ---------------- ---------------- --------------
+           String         å                l              NUL
+                   ---------------- ---------------- --------------
+      Code points    U+00E5 (229)     U+006C (108)     U+0000 (0)
+                   ---------------- ---------------- --------------
+      UTF-8 bytes     0xC3, 0xA5          0x6C            0x00
+                   ---------------- ---------------- --------------
+   UTF-16LE bytes     0xE5, 0x00       0x6C, 0x00      0x00, 0x00
+                   ---------------- ---------------- --------------
+

You can see the aforementioned properties of UTF-8. The first code point U+00E5 (“å”) is outside of the ASCII range (0-127) so is encoded to multiple code units – it requires two bytes. U+006C (“l”) and U+0000 (NUL) both exist in the ASCII range so take exactly one byte each, as in a pure ASCII string. A zero byte never appears except to represent the NUL character, so many functions which expect C-style strings will work with UTF-8 strings without modification.

+

On the other hand, UTF-16 represents each code point by either one or two 16-bit code units (two or four bytes). The representation of each 16-bit code unit depends on the byte order; here we have demonstrated little endian.

+

Both UTF-8 and UTF-16 are self-synchronising. Starting from any offset within a string, it is efficient to find the beginning of the previous or next code point.

+

Not all sequences of bytes or 16-bit words are valid UTF-8 and UTF-16 strings respectively. UTF-8 also has an additional problem of overlong forms, where a code point value is encoded using more bytes than is strictly necessary. This is invalid and needs to be guarded against.

+

In the following “ustr” functions, be careful whether a function takes code unit (byte) or code point indices. In general, all position parameters are in code unit offsets. This may be surprising, but if you think about it, it is required for good performance. (It also means some functions will work even if they do not contain UTF-8, since they only care about storing bytes, so you may actually store arbitrary data in the ALLEGRO_USTRs.)

+

For actual text processing, where you want to specify positions with code point indices, you should use al_ustr_offset to find the code unit offset position. However, most of the time you would probably just work with byte offsets.

+

UTF-8 string types

+

ALLEGRO_USTR

+
typedef struct _al_tagbstring ALLEGRO_USTR;
+

Source Code

+

An opaque type representing a string. ALLEGRO_USTRs normally contain UTF-8 encoded strings, but they may be used to hold any byte sequences, including NULs.

+

Examples:

+ +

ALLEGRO_USTR_INFO

+
typedef struct _al_tagbstring ALLEGRO_USTR_INFO;
+

Source Code

+

A type that holds additional information for an ALLEGRO_USTR that references an external memory buffer.

+

See also: al_ref_cstr, al_ref_buffer and al_ref_ustr.

+

Examples:

+ +

Creating and destroying strings

+

al_ustr_new

+
ALLEGRO_USTR *al_ustr_new(const char *s)
+

Source Code

+

Create a new string containing a copy of the C-style string s. The string must eventually be freed with al_ustr_free.

+

See also: al_ustr_new_from_buffer, al_ustr_newf, al_ustr_dup, al_ustr_new_from_utf16

+

Examples:

+ +

al_ustr_new_from_buffer

+
ALLEGRO_USTR *al_ustr_new_from_buffer(const char *s, size_t size)
+

Source Code

+

Create a new string containing a copy of the buffer pointed to by s of the given size in bytes. The string must eventually be freed with al_ustr_free.

+

See also: al_ustr_new

+

Examples:

+ +

al_ustr_newf

+
ALLEGRO_USTR *al_ustr_newf(const char *fmt, ...)
+

Source Code

+

Create a new string using a printf-style format string.

+

Notes:

+

The “%s” specifier takes C string arguments, not ALLEGRO_USTRs. Therefore to pass an ALLEGRO_USTR as a parameter you must use al_cstr, and it must be NUL terminated. If the string contains an embedded NUL byte everything from that byte onwards will be ignored.

+

The “%c” specifier outputs a single byte, not the UTF-8 encoding of a code point. Therefore it is only usable for ASCII characters (value <= 127) or if you really mean to output byte values from 128–255. To insert the UTF-8 encoding of a code point, encode it into a memory buffer using al_utf8_encode then use the “%s” specifier. Remember to NUL terminate the buffer.

+

See also: al_ustr_new, al_ustr_appendf

+

Examples:

+ +

al_ustr_free

+
void al_ustr_free(ALLEGRO_USTR *us)
+

Source Code

+

Free a previously allocated string. Does nothing if the argument is NULL.

+

See also: al_ustr_new, al_ustr_new_from_buffer, al_ustr_newf

+

Examples:

+ +

al_cstr

+
const char *al_cstr(const ALLEGRO_USTR *us)
+

Source Code

+

Get a char * pointer to the data in a string. This pointer will only be valid while the ALLEGRO_USTR object is not modified and not destroyed. The pointer may be passed to functions expecting C-style strings, with the following caveats:

+
    +
  • ALLEGRO_USTRs are allowed to contain embedded NUL ('\0') bytes. That means al_ustr_size(u) and strlen(al_cstr(u)) may not agree.

  • +
  • An ALLEGRO_USTR may be created in such a way that it is not NUL terminated. A string which is dynamically allocated will always be NUL terminated, but a string which references the middle of another string or region of memory will not be NUL terminated.

  • +
  • If the ALLEGRO_USTR references another string, the returned C string will point into the referenced string. Again, no NUL terminator will be added to the referenced string.

  • +
+

See also: al_ustr_to_buffer, al_cstr_dup

+

Examples:

+ +

al_ustr_to_buffer

+
void al_ustr_to_buffer(const ALLEGRO_USTR *us, char *buffer, int size)
+

Source Code

+

Write the contents of the string into a pre-allocated buffer of the given size in bytes. The result will always be NUL terminated, so a maximum of size - 1 bytes will be copied.

+

See also: al_cstr, al_cstr_dup

+

Examples:

+ +

al_cstr_dup

+
char *al_cstr_dup(const ALLEGRO_USTR *us)
+

Source Code

+

Create a NUL ('\0') terminated copy of the string. Any embedded NUL bytes will still be presented in the returned string. The new string must eventually be freed with al_free.

+

If an error occurs NULL is returned.

+

See also: al_cstr, al_ustr_to_buffer, al_free

+

Examples:

+ +

al_ustr_dup

+
ALLEGRO_USTR *al_ustr_dup(const ALLEGRO_USTR *us)
+

Source Code

+

Return a duplicate copy of a string. The new string will need to be freed with al_ustr_free.

+

See also: al_ustr_dup_substr, al_ustr_free

+

Examples:

+ +

al_ustr_dup_substr

+
ALLEGRO_USTR *al_ustr_dup_substr(const ALLEGRO_USTR *us, int start_pos,
+   int end_pos)
+

Source Code

+

Return a new copy of a string, containing its contents in the byte interval [start_pos, end_pos). The new string will be NUL terminated and will need to be freed with al_ustr_free.

+

If necessary, use al_ustr_offset to find the byte offsets for a given code point that you are interested in.

+

See also: al_ustr_dup, al_ustr_free

+

Examples:

+ +

Predefined strings

+

al_ustr_empty_string

+
const ALLEGRO_USTR *al_ustr_empty_string(void)
+

Source Code

+

Return a pointer to a static empty string. The string is read only and must not be freed.

+

Examples:

+ +

Creating strings by referencing other data

+

al_ref_cstr

+
const ALLEGRO_USTR *al_ref_cstr(ALLEGRO_USTR_INFO *info, const char *s)
+

Source Code

+

Create a string that references the storage of a C-style string. The information about the string (e.g. its size) is stored in the structure pointed to by the info parameter. The string will not have any other storage allocated of its own, so if you allocate the info structure on the stack then no explicit “free” operation is required.

+

The string is valid until the underlying C string disappears.

+

Example:

+
ALLEGRO_USTR_INFO info;
+ALLEGRO_USTR *us = al_ref_cstr(&info, "my string");
+

See also: al_ref_buffer, al_ref_ustr

+

Examples:

+ +

al_ref_buffer

+
const ALLEGRO_USTR *al_ref_buffer(ALLEGRO_USTR_INFO *info, const char *s, size_t size)
+

Source Code

+

Create a string that references the storage of an underlying buffer. The size of the buffer is given in bytes. You can use it to reference only part of a string or an arbitrary region of memory.

+

The string is valid while the underlying memory buffer is valid.

+

See also: al_ref_cstr, al_ref_ustr

+

Examples:

+ +

al_ref_ustr

+
const ALLEGRO_USTR *al_ref_ustr(ALLEGRO_USTR_INFO *info, const ALLEGRO_USTR *us,
+   int start_pos, int end_pos)
+

Source Code

+

Create a read-only string that references the storage of another ALLEGRO_USTR string. The information about the string (e.g. its size) is stored in the structure pointed to by the info parameter. The new string will not have any other storage allocated of its own, so if you allocate the info structure on the stack then no explicit “free” operation is required.

+

The referenced interval is [start_pos, end_pos). Both are byte offsets.

+

The string is valid until the underlying string is modified or destroyed.

+

If you need a range of code-points instead of bytes, use al_ustr_offset to find the byte offsets.

+

See also: al_ref_cstr, al_ref_buffer

+

Examples:

+ +

Sizes and offsets

+

al_ustr_size

+
size_t al_ustr_size(const ALLEGRO_USTR *us)
+

Source Code

+

Return the size of the string in bytes. This is equal to the number of code points in the string if the string is empty or contains only 7-bit ASCII characters.

+

See also: al_ustr_length

+

Examples:

+ +

al_ustr_length

+
size_t al_ustr_length(const ALLEGRO_USTR *us)
+

Source Code

+

Return the number of code points in the string.

+

See also: al_ustr_size, al_ustr_offset

+

Examples:

+ +

al_ustr_offset

+
int al_ustr_offset(const ALLEGRO_USTR *us, int index)
+

Source Code

+

Return the byte offset (from the start of the string) of the code point at the specified index in the string. A zero index parameter will return the first character of the string. If index is negative, it counts backward from the end of the string, so an index of -1 will return an offset to the last code point.

+

If the index is past the end of the string, returns the offset of the end of the string.

+

See also: al_ustr_length

+

Examples:

+ +

al_ustr_next

+
bool al_ustr_next(const ALLEGRO_USTR *us, int *pos)
+

Source Code

+

Find the byte offset of the next code point in string, beginning at *pos. *pos does not have to be at the beginning of a code point.

+

Returns true on success, and the value pointed to by pos will be updated to the found offset. Otherwise returns false if *pos was already at the end of the string, and *pos is unmodified.

+

This function just looks for an appropriate byte; it doesn’t check if found offset is the beginning of a valid code point. If you are working with possibly invalid UTF-8 strings then it could skip over some invalid bytes.

+

See also: al_ustr_prev

+

Examples:

+ +

al_ustr_prev

+
bool al_ustr_prev(const ALLEGRO_USTR *us, int *pos)
+

Source Code

+

Find the byte offset of the previous code point in string, before *pos. *pos does not have to be at the beginning of a code point. Returns true on success, and the value pointed to by pos will be updated to the found offset. Otherwise returns false if *pos was already at the end of the string, and *pos is unmodified.

+

This function just looks for an appropriate byte; it doesn’t check if found offset is the beginning of a valid code point. If you are working with possibly invalid UTF-8 strings then it could skip over some invalid bytes.

+

See also: al_ustr_next

+

Examples:

+ +

Getting code points

+

al_ustr_get

+
int32_t al_ustr_get(const ALLEGRO_USTR *ub, int pos)
+

Source Code

+

Return the code point in ub beginning at byte offset pos.

+

On success returns the code point value. If pos was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2.

+

See also: al_ustr_get_next, al_ustr_prev_get

+

Examples:

+ +

al_ustr_get_next

+
int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos)
+

Source Code

+

Find the code point in us beginning at byte offset *pos, then advance to the next code point.

+

On success return the code point value. If pos was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2. As with al_ustr_next, invalid byte sequences may be skipped while advancing.

+

See also: al_ustr_get, al_ustr_prev_get

+

Examples:

+ +

al_ustr_prev_get

+
int32_t al_ustr_prev_get(const ALLEGRO_USTR *us, int *pos)
+

Source Code

+

Find the beginning of a code point before byte offset *pos, then return it. Note this performs a pre-increment.

+

On success returns the code point value. If pos was out of bounds (e.g. past the end of the string), return -1. On an error, such as an invalid byte sequence, return -2. As with al_ustr_prev, invalid byte sequences may be skipped while advancing.

+

See also: al_ustr_get_next

+

Examples:

+ +

Inserting into strings

+

al_ustr_insert

+
bool al_ustr_insert(ALLEGRO_USTR *us1, int pos, const ALLEGRO_USTR *us2)
+

Source Code

+

Insert us2 into us1 beginning at byte offset pos. pos cannot be less than 0. If pos is past the end of us1 then the space between the end of the string and pos will be padded with NUL ('\0') bytes.

+

If required, use al_ustr_offset to find the byte offset for a given code point index.

+

Returns true on success, false on error.

+

See also: al_ustr_insert_cstr, al_ustr_insert_chr, al_ustr_append, al_ustr_offset

+

Examples:

+ +

al_ustr_insert_cstr

+
bool al_ustr_insert_cstr(ALLEGRO_USTR *us, int pos, const char *s)
+

Source Code

+

Like al_ustr_insert but inserts a C-style string at byte offset pos.

+

See also: al_ustr_insert, al_ustr_insert_chr

+

Examples:

+ +

al_ustr_insert_chr

+
size_t al_ustr_insert_chr(ALLEGRO_USTR *us, int pos, int32_t c)
+

Source Code

+

Insert a code point into us beginning at byte offset pos. pos cannot be less than 0. If pos is past the end of us then the space between the end of the string and pos will be padded with NUL ('\0') bytes.

+

Returns the number of bytes inserted, or 0 on error.

+

See also: al_ustr_insert, al_ustr_insert_cstr

+

Examples:

+ +

Appending to strings

+

al_ustr_append

+
bool al_ustr_append(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
+

Source Code

+

Append us2 to the end of us1.

+

Returns true on success, false on error.

+

This function can be used to append an arbitrary buffer:

+
  ALLEGRO_USTR_INFO info;
+  al_ustr_append(us, al_ref_buffer(&info, buf, size));
+

See also: al_ustr_append_cstr, al_ustr_append_chr, al_ustr_appendf, al_ustr_vappendf

+

Examples:

+ +

al_ustr_append_cstr

+
bool al_ustr_append_cstr(ALLEGRO_USTR *us, const char *s)
+

Source Code

+

Append C-style string s to the end of us.

+

Returns true on success, false on error.

+

See also: al_ustr_append

+

Examples:

+ +

al_ustr_append_chr

+
size_t al_ustr_append_chr(ALLEGRO_USTR *us, int32_t c)
+

Source Code

+

Append a code point to the end of us.

+

Returns the number of bytes added, or 0 on error.

+

See also: al_ustr_append

+

Examples:

+ +

al_ustr_appendf

+
bool al_ustr_appendf(ALLEGRO_USTR *us, const char *fmt, ...)
+

Source Code

+

This function appends formatted output to the string us. fmt is a printf-style format string. See al_ustr_newf about the “%s” and “%c” specifiers.

+

Returns true on success, false on error.

+

See also: al_ustr_vappendf, al_ustr_append

+

Examples:

+ +

al_ustr_vappendf

+
bool al_ustr_vappendf(ALLEGRO_USTR *us, const char *fmt, va_list ap)
+

Source Code

+

Like al_ustr_appendf but you pass the variable argument list directly, instead of the arguments themselves. See al_ustr_newf about the “%s” and “%c” specifiers.

+

Returns true on success, false on error.

+

See also: al_ustr_appendf, al_ustr_append

+

Examples:

+ +

Removing parts of strings

+

al_ustr_remove_chr

+
bool al_ustr_remove_chr(ALLEGRO_USTR *us, int pos)
+

Source Code

+

Remove the code point beginning at byte offset pos. Returns true on success. If pos is out of range or pos is not the beginning of a valid code point, returns false leaving the string unmodified.

+

Use al_ustr_offset to find the byte offset for a code-points offset.

+

See also: al_ustr_remove_range

+

Examples:

+ +

al_ustr_remove_range

+
bool al_ustr_remove_range(ALLEGRO_USTR *us, int start_pos, int end_pos)
+

Source Code

+

Remove the interval [start_pos, end_pos) from a string. start_pos and end_pos are byte offsets. Both may be past the end of the string but cannot be less than 0 (the start of the string).

+

Returns true on success, false on error.

+

See also: al_ustr_remove_chr, al_ustr_truncate

+

Examples:

+ +

al_ustr_truncate

+
bool al_ustr_truncate(ALLEGRO_USTR *us, int start_pos)
+

Source Code

+

Truncate a portion of a string from byte offset start_pos onwards. start_pos can be past the end of the string (has no effect) but cannot be less than 0.

+

Returns true on success, false on error.

+

See also: al_ustr_remove_range, al_ustr_ltrim_ws, al_ustr_rtrim_ws, al_ustr_trim_ws

+

Examples:

+ +

al_ustr_ltrim_ws

+
bool al_ustr_ltrim_ws(ALLEGRO_USTR *us)
+

Source Code

+

Remove leading whitespace characters from a string, as defined by the C function isspace().

+

Returns true on success, or false on error.

+

See also: al_ustr_rtrim_ws, al_ustr_trim_ws

+

Examples:

+ +

al_ustr_rtrim_ws

+
bool al_ustr_rtrim_ws(ALLEGRO_USTR *us)
+

Source Code

+

Remove trailing (“right”) whitespace characters from a string, as defined by the C function isspace().

+

Returns true on success, or false on error.

+

See also: al_ustr_ltrim_ws, al_ustr_trim_ws

+

Examples:

+ +

al_ustr_trim_ws

+
bool al_ustr_trim_ws(ALLEGRO_USTR *us)
+

Source Code

+

Remove both leading and trailing whitespace characters from a string.

+

Returns true on success, or false on error.

+

See also: al_ustr_ltrim_ws, al_ustr_rtrim_ws

+

Examples:

+ +

Assigning one string to another

+

al_ustr_assign

+
bool al_ustr_assign(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
+

Source Code

+

Overwrite the string us1 with another string us2. Returns true on success, false on error.

+

See also: al_ustr_assign_substr, al_ustr_assign_cstr

+

Examples:

+ +

al_ustr_assign_substr

+
bool al_ustr_assign_substr(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2,
+   int start_pos, int end_pos)
+

Source Code

+

Overwrite the string us1 with the contents of us2 in the byte interval [start_pos, end_pos). The end points will be clamped to the bounds of us2.

+

Usually you will first have to use al_ustr_offset to find the byte offsets.

+

Returns true on success, false on error.

+

See also: al_ustr_assign, al_ustr_assign_cstr

+

Examples:

+ +

al_ustr_assign_cstr

+
bool al_ustr_assign_cstr(ALLEGRO_USTR *us1, const char *s)
+

Source Code

+

Overwrite the string us1 with the contents of the C-style string s. Returns true on success, false on error.

+

See also: al_ustr_assign_substr, al_ustr_assign_cstr

+

Examples:

+ +

Replacing parts of string

+

al_ustr_set_chr

+
size_t al_ustr_set_chr(ALLEGRO_USTR *us, int start_pos, int32_t c)
+

Source Code

+

Replace the code point beginning at byte offset start_pos with c. start_pos cannot be less than 0. If start_pos is past the end of us then the space between the end of the string and start_pos will be padded with NUL ('\0') bytes. If start_pos is not the start of a valid code point, that is an error and the string will be unmodified.

+

On success, returns the number of bytes written, i.e. the offset to the following code point. On error, returns 0.

+

See also: al_ustr_replace_range

+

Examples:

+ +

al_ustr_replace_range

+
bool al_ustr_replace_range(ALLEGRO_USTR *us1, int start_pos1, int end_pos1,
+   const ALLEGRO_USTR *us2)
+

Source Code

+

Replace the part of us1 in the byte interval [start_pos1, end_pos1) with the contents of us2. start_pos1 cannot be less than 0. If start_pos1 is past the end of us1 then the space between the end of the string and start_pos1 will be padded with NUL ('\0') bytes.

+

Use al_ustr_offset to find the byte offsets.

+

Returns true on success, false on error.

+

See also: al_ustr_set_chr

+

Examples:

+ +

Searching

+

al_ustr_find_chr

+
int al_ustr_find_chr(const ALLEGRO_USTR *us, int start_pos, int32_t c)
+

Source Code

+

Search for the encoding of code point c in us from byte offset start_pos (inclusive).

+

Returns the position where it is found or -1 if it is not found.

+

See also: al_ustr_rfind_chr

+

Examples:

+ +

al_ustr_rfind_chr

+
int al_ustr_rfind_chr(const ALLEGRO_USTR *us, int end_pos, int32_t c)
+

Source Code

+

Search for the encoding of code point c in us backwards from byte offset end_pos (exclusive). Returns the position where it is found or -1 if it is not found.

+

See also: al_ustr_find_chr

+

Examples:

+ +

al_ustr_find_set

+
int al_ustr_find_set(const ALLEGRO_USTR *us, int start_pos,
+   const ALLEGRO_USTR *accept)
+

Source Code

+

This function finds the first code point in us, beginning from byte offset start_pos, that matches any code point in accept. Returns the position if a code point was found. Otherwise returns -1.

+

See also: al_ustr_find_set_cstr, al_ustr_find_cset

+

Examples:

+ +

al_ustr_find_set_cstr

+
int al_ustr_find_set_cstr(const ALLEGRO_USTR *us, int start_pos,
+   const char *accept)
+

Source Code

+

Like al_ustr_find_set but takes a C-style string for accept.

+

See also: al_ustr_find_set, al_ustr_find_cset_cstr

+

Examples:

+ +

al_ustr_find_cset

+
int al_ustr_find_cset(const ALLEGRO_USTR *us, int start_pos,
+   const ALLEGRO_USTR *reject)
+

Source Code

+

This function finds the first code point in us, beginning from byte offset start_pos, that does not match any code point in reject. In other words it finds a code point in the complementary set of reject. Returns the byte position of that code point, if any. Otherwise returns -1.

+

See also: al_ustr_find_cset_cstr, al_ustr_find_set

+

Examples:

+ +

al_ustr_find_cset_cstr

+
int al_ustr_find_cset_cstr(const ALLEGRO_USTR *us, int start_pos,
+   const char *reject)
+

Source Code

+

Like al_ustr_find_cset but takes a C-style string for reject.

+

See also: al_ustr_find_cset, al_ustr_find_set_cstr

+

Examples:

+ +

al_ustr_find_str

+
int al_ustr_find_str(const ALLEGRO_USTR *haystack, int start_pos,
+   const ALLEGRO_USTR *needle)
+

Source Code

+

Find the first occurrence of string needle in haystack, beginning from byte offset start_pos (inclusive). Return the byte offset of the occurrence if it is found, otherwise return -1.

+

See also: al_ustr_find_cstr, al_ustr_rfind_str, al_ustr_find_replace

+

Examples:

+ +

al_ustr_find_cstr

+
int al_ustr_find_cstr(const ALLEGRO_USTR *haystack, int start_pos,
+   const char *needle)
+

Source Code

+

Like al_ustr_find_str but takes a C-style string for needle.

+

See also: al_ustr_find_str, al_ustr_rfind_cstr

+

Examples:

+ +

al_ustr_rfind_str

+
int al_ustr_rfind_str(const ALLEGRO_USTR *haystack, int end_pos,
+   const ALLEGRO_USTR *needle)
+

Source Code

+

Find the last occurrence of string needle in haystack before byte offset end_pos (exclusive). Return the byte offset of the occurrence if it is found, otherwise return -1.

+

See also: al_ustr_rfind_cstr, al_ustr_find_str

+

Examples:

+ +

al_ustr_rfind_cstr

+
int al_ustr_rfind_cstr(const ALLEGRO_USTR *haystack, int end_pos,
+   const char *needle)
+

Source Code

+

Like al_ustr_rfind_str but takes a C-style string for needle.

+

See also: al_ustr_rfind_str, al_ustr_find_cstr

+

Examples:

+ +

al_ustr_find_replace

+
bool al_ustr_find_replace(ALLEGRO_USTR *us, int start_pos,
+   const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace)
+

Source Code

+

Replace all occurrences of find in us with replace, beginning at byte offset start_pos. The find string must be non-empty. Returns true on success, false on error.

+

See also: al_ustr_find_replace_cstr

+

Examples:

+ +

al_ustr_find_replace_cstr

+
bool al_ustr_find_replace_cstr(ALLEGRO_USTR *us, int start_pos,
+   const char *find, const char *replace)
+

Source Code

+

Like al_ustr_find_replace but takes C-style strings for find and replace.

+

Examples:

+ +

Comparing

+

al_ustr_equal

+
bool al_ustr_equal(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
+

Source Code

+

Return true iff the two strings are equal. This function is more efficient than al_ustr_compare so is preferable if ordering is not important.

+

See also: al_ustr_compare

+

Examples:

+ +

al_ustr_compare

+
int al_ustr_compare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
+

Source Code

+

This function compares us1 and us2 by code point values. Returns zero if the strings are equal, a positive number if us1 comes after us2, else a negative number.

+

This does not take into account locale-specific sorting rules. For that you will need to use another library.

+

See also: al_ustr_ncompare, al_ustr_equal

+

Examples:

+ +

al_ustr_ncompare

+
int al_ustr_ncompare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int n)
+

Source Code

+

Like al_ustr_compare but only compares up to the first n code points of both strings.

+

Returns zero if the strings are equal, a positive number if us1 comes after us2, else a negative number.

+

See also: al_ustr_compare, al_ustr_equal

+

Examples:

+ +

al_ustr_has_prefix

+
bool al_ustr_has_prefix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
+

Source Code

+

Returns true iff us1 begins with us2.

+

See also: al_ustr_has_prefix_cstr, al_ustr_has_suffix

+

Examples:

+ +

al_ustr_has_prefix_cstr

+
bool al_ustr_has_prefix_cstr(const ALLEGRO_USTR *us1, const char *s2)
+

Source Code

+

Returns true iff us1 begins with s2.

+

See also: al_ustr_has_prefix, al_ustr_has_suffix_cstr

+

Examples:

+ +

al_ustr_has_suffix

+
bool al_ustr_has_suffix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)
+

Source Code

+

Returns true iff us1 ends with us2.

+

See also: al_ustr_has_suffix_cstr, al_ustr_has_prefix

+

Examples:

+ +

al_ustr_has_suffix_cstr

+
bool al_ustr_has_suffix_cstr(const ALLEGRO_USTR *us1, const char *s2)
+

Source Code

+

Returns true iff us1 ends with s2.

+

See also: al_ustr_has_suffix, al_ustr_has_prefix_cstr

+

Examples:

+ +

UTF-16 conversion

+

al_ustr_new_from_utf16

+
ALLEGRO_USTR *al_ustr_new_from_utf16(uint16_t const *s)
+

Source Code

+

Create a new string containing a copy of the 0-terminated string s which must be encoded as UTF-16. The string must eventually be freed with al_ustr_free.

+

See also: al_ustr_new

+

Examples:

+ +

al_ustr_size_utf16

+
size_t al_ustr_size_utf16(const ALLEGRO_USTR *us)
+

Source Code

+

Returns the number of bytes required to encode the string in UTF-16 (including the terminating 0). Usually called before al_ustr_encode_utf16 to determine the size of the buffer to allocate.

+

See also: al_ustr_size

+

Examples:

+ +

al_ustr_encode_utf16

+
size_t al_ustr_encode_utf16(const ALLEGRO_USTR *us, uint16_t *s,
+   size_t n)
+

Source Code

+

Encode the string into the given buffer, in UTF-16. Returns the number of bytes written. There are never more than n bytes written. The minimum size to encode the complete string can be queried with al_ustr_size_utf16. If the n parameter is smaller than that, the string will be truncated but still always 0 terminated.

+

See also: al_ustr_size_utf16, al_utf16_encode

+

Examples:

+ +

Low-level UTF-8 routines

+

al_utf8_width

+
size_t al_utf8_width(int32_t c)
+

Source Code

+

Returns the number of bytes that would be occupied by the specified code point when encoded in UTF-8. This is between 1 and 4 bytes for legal code point values. Otherwise returns 0.

+

See also: al_utf8_encode, al_utf16_width

+

Examples:

+ +

al_utf8_encode

+
size_t al_utf8_encode(char s[], int32_t c)
+

Source Code

+

Encode the specified code point to UTF-8 into the buffer s. The buffer must have enough space to hold the encoding, which takes between 1 and 4 bytes. This routine will refuse to encode code points above 0x10FFFF.

+

Returns the number of bytes written, which is the same as that returned by al_utf8_width.

+

See also: al_utf16_encode

+

Examples:

+ +

Low-level UTF-16 routines

+

al_utf16_width

+
size_t al_utf16_width(int c)
+

Source Code

+

Returns the number of bytes that would be occupied by the specified code point when encoded in UTF-16. This is either 2 or 4 bytes for legal code point values. Otherwise returns 0.

+

See also: al_utf16_encode, al_utf8_width

+

al_utf16_encode

+
size_t al_utf16_encode(uint16_t s[], int32_t c)
+

Source Code

+

Encode the specified code point to UTF-16 into the buffer s. The buffer must have enough space to hold the encoding, which takes either 2 or 4 bytes. This routine will refuse to encode code points above 0x10FFFF.

+

Returns the number of bytes written, which is the same as that returned by al_utf16_width.

+

See also: al_utf8_encode, al_ustr_encode_utf16

+

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:42 UTC +

+
+ + diff --git a/allegro/docs/html/refman/video.html b/allegro/docs/html/refman/video.html new file mode 100644 index 00000000..ecd125ec --- /dev/null +++ b/allegro/docs/html/refman/video.html @@ -0,0 +1,393 @@ + + + + + + + Video streaming addon + + + + + + + + +
+ + +
+

Video streaming addon

+
+ +

These functions are declared in the following header file. Link with allegro_video.

+
 #include <allegro5/allegro_video.h>
+

Currently we have an Ogg backend (Theora + Vorbis). See http://xiph.org/ for installation instructions, licensing information and supported video formats.

+

ALLEGRO_VIDEO_EVENT_TYPE

+
enum ALLEGRO_VIDEO_EVENT_TYPE
+

Source Code

+

Events sent by al_get_video_event_source.

+

ALLEGRO_EVENT_VIDEO_FRAME_SHOW

+

This event is sent when it is time to show a new frame. Once you receive this event, you can draw the current frame (as returned by al_get_video_frame). al_get_video_frame will continue returning the same frame until the next ALLEGRO_EVENT_VIDEO_FRAME_SHOW is sent.

+
+
user.data1 (ALLEGRO_VIDEO *)
+
The video which generated the event. +
+
+

Since: 5.1.0

+

ALLEGRO_EVENT_VIDEO_FINISHED

+

This event is sent when the video is finished. Depending on the backend, it may be possible to seek to an earlier part of the video and set the video to play to resume playback.

+
+
user.data1 (ALLEGRO_VIDEO *)
+
The video which generated the event. +
+
+

Since: 5.1.0

+

ALLEGRO_VIDEO_POSITION_TYPE

+
typedef enum ALLEGRO_VIDEO_POSITION_TYPE ALLEGRO_VIDEO_POSITION_TYPE;
+

Source Code

+

Used with al_get_video_position to specify which position to retrieve. If these get out of sync, audio and video may be out of sync in the display of the video.

+
    +
  • ALLEGRO_VIDEO_POSITION_ACTUAL - The amount of time the video has been playing. If the video has audio then this value can be ahead of ALLEGRO_VIDEO_POSITION_VIDEO_DECODE when video decoding lags.

  • +
  • ALLEGRO_VIDEO_POSITION_VIDEO_DECODE - The amount of video that has been decoded. This may lag behind the “actual” and audio positions if decoding is slower than realtime.

  • +
  • ALLEGRO_VIDEO_POSITION_AUDIO_DECODE - The amount of audio that has been decoded. This may be the same as ALLEGRO_VIDEO_POSITION_ACTUAL if audio decode is driving the position, which is common to keep audio and video in sync.

  • +
+

Since: 5.1.11

+

al_init_video_addon

+
bool al_init_video_addon(void)
+

Source Code

+

Initializes the video addon.

+

Since: 5.1.12

+

Examples:

+ +

al_is_video_addon_initialized

+
bool al_is_video_addon_initialized(void)
+

Source Code

+

Returns true if the video addon is initialized, otherwise returns false.

+

Since: 5.2.6

+

al_shutdown_video_addon

+
void al_shutdown_video_addon(void)
+

Source Code

+

Shut down the video addon. This is done automatically at program exit, but can be called any time the user wishes as well.

+

Since: 5.1.12

+

al_get_allegro_video_version

+
uint32_t al_get_allegro_video_version(void)
+

Source Code

+

Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.

+

Since: 5.1.12

+

al_open_video

+
ALLEGRO_VIDEO *al_open_video(char const *filename)
+

Source Code

+

Reads a video file. This does not start streaming yet but reads the meta info so you can query e.g. the size or audio rate.

+

Since: 5.1.0

+

Examples:

+ +

al_close_video

+
void al_close_video(ALLEGRO_VIDEO *video)
+

Source Code

+

Closes the video and frees all allocated resources. The video pointer is invalid after the function returns.

+

Since: 5.1.0

+

Examples:

+ +

al_start_video

+
void al_start_video(ALLEGRO_VIDEO *video, ALLEGRO_MIXER *mixer)
+

Source Code

+

Starts streaming the video from the beginning.

+

Since: 5.1.0

+

Examples:

+ +

al_start_video_with_voice

+
void al_start_video_with_voice(ALLEGRO_VIDEO *video, ALLEGRO_VOICE *voice)
+

Source Code

+

Like al_start_video but audio is routed to the provided voice.

+

Since: 5.1.0

+

al_get_video_event_source

+
ALLEGRO_EVENT_SOURCE *al_get_video_event_source(ALLEGRO_VIDEO *video)
+

Source Code

+

Get an event source for the video. The possible events are described under ALLEGRO_VIDEO_EVENT_TYPE.

+

Since: 5.1.0

+

Examples:

+ +

al_set_video_playing

+
void al_set_video_playing(ALLEGRO_VIDEO *video, bool play)
+

Source Code

+

Paused or resumes playback.

+

Since: 5.1.12

+

Examples:

+ +

al_is_video_playing

+
bool al_is_video_playing(ALLEGRO_VIDEO *video)
+

Source Code

+

Returns true if the video is currently playing.

+

Since: 5.1.12

+

Examples:

+ +

al_get_video_audio_rate

+
double al_get_video_audio_rate(ALLEGRO_VIDEO *video)
+

Source Code

+

Returns the audio rate of the video, in Hz.

+

Since: 5.1.0

+

Examples:

+ +

al_get_video_fps

+
double al_get_video_fps(ALLEGRO_VIDEO *video)
+

Source Code

+

Returns the speed of the video in frames per second. Often this will not be an integer value.

+

Since: 5.1.0

+

Examples:

+ +

al_get_video_scaled_width

+
float al_get_video_scaled_width(ALLEGRO_VIDEO *video)
+

Source Code

+

Returns the width with which the video frame should be drawn. Videos often do not use square pixels, so this will may return a value larger than the width of the frame bitmap.

+

Since: 5.1.12

+

See also: al_get_video_frame

+

Examples:

+ +

al_get_video_scaled_height

+
float al_get_video_scaled_height(ALLEGRO_VIDEO *video)
+

Source Code

+

Returns the height with which the video frame should be drawn. Videos often do not use square pixels, so this will may return a value larger than the height of the frame bitmap.

+

See also: al_get_video_frame

+

Since: 5.1.12

+

Examples:

+ +

al_get_video_frame

+
ALLEGRO_BITMAP *al_get_video_frame(ALLEGRO_VIDEO *video)
+

Source Code

+

Returns the current video frame. The bitmap is owned by the video so do not attempt to free it. The bitmap will stay valid until the next call to al_get_video_frame.

+

Videos often do not use square pixels so the recommended way to draw a video frame would be using code like this:

+
float scale = 1.0; /* Adjust this to fit your target bitmap dimensions. */
+ALLEGRO_BITMAP* frame = al_get_video_frame(video);
+float sw = al_get_bitmap_width(frame);
+float sh = al_get_bitmap_height(frame);
+float dw = scale * al_get_video_scaled_width(video);
+float dh = scale * al_get_video_scaled_height(video);
+al_draw_scaled_bitmap(frame, 0, 0, sw, sh, 0, 0, dw, dh, 0);
+

Since: 5.1.0

+

See also: al_get_video_scaled_width, al_get_video_scaled_height

+

Examples:

+ +

al_get_video_position

+
double al_get_video_position(ALLEGRO_VIDEO *video, ALLEGRO_VIDEO_POSITION_TYPE which)
+

Source Code

+

Returns the current position of the video stream in seconds since the beginning. The parameter is one of the ALLEGRO_VIDEO_POSITION_TYPE constants.

+

Since: 5.1.0

+

Examples:

+ +

al_seek_video

+
bool al_seek_video(ALLEGRO_VIDEO *video, double pos_in_seconds)
+

Source Code

+

Seek to a different position in the video. Currently only seeking to the beginning of the video is supported.

+

Since: 5.1.0

+

Examples:

+ +

+Allegro version 5.2.7 + - Last updated: 2021-03-08 01:00:44 UTC +

+
+ + diff --git a/allegro/docs/man/ALLEGRO_AUDIO_DEPTH.3 b/allegro/docs/man/ALLEGRO_AUDIO_DEPTH.3 new file mode 100644 index 00000000..a3e690b5 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_AUDIO_DEPTH.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_AUDIO_DEPTH" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_AUDIO_DEPTH - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_AUDIO_DEPTH +\f[R] +.fi +.SH DESCRIPTION +.PP +Sample depth and type as well as signedness. +Mixers only use 32-bit signed float (-1..+1), or 16-bit signed integers. +Signedness is determined by an \[lq]unsigned\[rq] bit-flag applied to +the depth value. +.IP \[bu] 2 +ALLEGRO_AUDIO_DEPTH_INT8 +.IP \[bu] 2 +ALLEGRO_AUDIO_DEPTH_INT16 +.IP \[bu] 2 +ALLEGRO_AUDIO_DEPTH_INT24 +.IP \[bu] 2 +ALLEGRO_AUDIO_DEPTH_FLOAT32 +.IP \[bu] 2 +ALLEGRO_AUDIO_DEPTH_UNSIGNED +.PP +For convenience: +.IP \[bu] 2 +ALLEGRO_AUDIO_DEPTH_UINT8 +.IP \[bu] 2 +ALLEGRO_AUDIO_DEPTH_UINT16 +.IP \[bu] 2 +ALLEGRO_AUDIO_DEPTH_UINT24 diff --git a/allegro/docs/man/ALLEGRO_AUDIO_EVENT_TYPE.3 b/allegro/docs/man/ALLEGRO_AUDIO_EVENT_TYPE.3 new file mode 100644 index 00000000..c3f3add1 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_AUDIO_EVENT_TYPE.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_AUDIO_EVENT_TYPE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_AUDIO_EVENT_TYPE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_AUDIO_EVENT_TYPE +\f[R] +.fi +.SH DESCRIPTION +.SS ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT +.PP +Sent when a stream fragment is ready to be filled in. +See al_get_audio_stream_fragment(3). +.SS ALLEGRO_EVENT_AUDIO_STREAM_FINISHED +.PP +Sent when a stream is finished. +.SS ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT +.PP +Sent after a user-specified number of samples have been recorded. +Convert this to ALLEGRO_AUDIO_RECORDER_EVENT(3) via +al_get_audio_recorder_event(3). +.PP +You must always check the values for the buffer and samples as they are +not guaranteed to be exactly what was originally specified. +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/ALLEGRO_AUDIO_PAN_NONE.3 b/allegro/docs/man/ALLEGRO_AUDIO_PAN_NONE.3 new file mode 100644 index 00000000..87f804ea --- /dev/null +++ b/allegro/docs/man/ALLEGRO_AUDIO_PAN_NONE.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_AUDIO_PAN_NONE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_AUDIO_PAN_NONE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_AUDIO_PAN_NONE (-1000.0f) +\f[R] +.fi +.SH DESCRIPTION +.PP +A special value for the pan property of sample instances and audio +streams. +Use this value to disable panning on sample instances and audio streams, +and play them without attentuation implied by panning support. +.PP +ALLEGRO_AUDIO_PAN_NONE is different from a pan value of 0.0 (centered) +because, when panning is enabled, we try to maintain a constant sound +power level as a sample is panned from left to right. +A sound coming out of one speaker should sound as loud as it does when +split over two speakers. +As a consequence, a sample with pan value 0.0 will be 3 dB softer than +the original level. +.PP +(Please correct us if this is wrong.) diff --git a/allegro/docs/man/ALLEGRO_AUDIO_RECORDER.3 b/allegro/docs/man/ALLEGRO_AUDIO_RECORDER.3 new file mode 100644 index 00000000..66cea934 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_AUDIO_RECORDER.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_AUDIO_RECORDER" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_AUDIO_RECORDER - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_AUDIO_RECORDER ALLEGRO_AUDIO_RECORDER; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque datatype that represents a recording device. +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/ALLEGRO_AUDIO_RECORDER_EVENT.3 b/allegro/docs/man/ALLEGRO_AUDIO_RECORDER_EVENT.3 new file mode 100644 index 00000000..dba211e2 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_AUDIO_RECORDER_EVENT.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_AUDIO_RECORDER_EVENT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_AUDIO_RECORDER_EVENT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_AUDIO_RECORDER_EVENT ALLEGRO_AUDIO_RECORDER_EVENT; +\f[R] +.fi +.SH DESCRIPTION +.PP +Structure that holds the audio recorder event data. +Every event type will contain: +.IP \[bu] 2 +\&.source: pointer to the audio recorder +.PP +The following will be available depending on the event type: +.IP \[bu] 2 +\&.buffer: pointer to buffer containing the audio samples +.IP \[bu] 2 +\&.samples: number of samples (not bytes) that are available +.PP +Since 5.1.1 +.SH SEE ALSO +.PP +al_get_audio_recorder_event(3) +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/ALLEGRO_AUDIO_STREAM.3 b/allegro/docs/man/ALLEGRO_AUDIO_STREAM.3 new file mode 100644 index 00000000..8d8f05cd --- /dev/null +++ b/allegro/docs/man/ALLEGRO_AUDIO_STREAM.3 @@ -0,0 +1,53 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_AUDIO_STREAM" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_AUDIO_STREAM - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_AUDIO_STREAM ALLEGRO_AUDIO_STREAM; +\f[R] +.fi +.SH DESCRIPTION +.PP +An ALLEGRO_AUDIO_STREAM object is used to stream generated audio to the +sound device, in real-time. +This is done by reading from a buffer, which is split into a number of +fragments. +Whenever a fragment has finished playing, the user can refill it with +new data. +.PP +As with ALLEGRO_SAMPLE_INSTANCE(3) objects, streams store information +necessary for playback, so you may not play the same stream multiple +times simultaneously. +Streams also need to be attached to an ALLEGRO_MIXER(3), which, +eventually, reaches an ALLEGRO_VOICE(3) object. +.PP +While playing, you must periodically fill fragments with new audio data. +To know when a new fragment is ready to be filled, you can either +directly check with al_get_available_audio_stream_fragments(3), or +listen to events from the stream. +.PP +You can register an audio stream event source to an event queue; see +al_get_audio_stream_event_source(3). +An ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT(3) event is generated whenever a +new fragment is ready. +When you receive an event, use al_get_audio_stream_fragment(3) to obtain +a pointer to the fragment to be filled. +The size and format are determined by the parameters passed to +al_create_audio_stream(3). +.PP +If you\[cq]re late with supplying new data, the stream will be silent +until new data is provided. +You must call al_drain_audio_stream(3) when you\[cq]re finished with +supplying data to the stream. +.PP +If the stream is created by al_load_audio_stream(3) then it will also +generate an ALLEGRO_EVENT_AUDIO_STREAM_FINISHED(3) event if it reaches +the end of the file and is not set to loop. diff --git a/allegro/docs/man/ALLEGRO_BITMAP.3 b/allegro/docs/man/ALLEGRO_BITMAP.3 new file mode 100644 index 00000000..6e4108b6 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_BITMAP.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_BITMAP" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_BITMAP - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_BITMAP ALLEGRO_BITMAP; +\f[R] +.fi +.SH DESCRIPTION +.PP +Abstract type representing a bitmap (2D image). diff --git a/allegro/docs/man/ALLEGRO_BPM_TO_SECS.3 b/allegro/docs/man/ALLEGRO_BPM_TO_SECS.3 new file mode 100644 index 00000000..836612be --- /dev/null +++ b/allegro/docs/man/ALLEGRO_BPM_TO_SECS.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_BPM_TO_SECS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_BPM_TO_SECS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_BPM_TO_SECS(x) (60.0 / (x)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert beats per minute to seconds. diff --git a/allegro/docs/man/ALLEGRO_BPS_TO_SECS.3 b/allegro/docs/man/ALLEGRO_BPS_TO_SECS.3 new file mode 100644 index 00000000..b31ee5fb --- /dev/null +++ b/allegro/docs/man/ALLEGRO_BPS_TO_SECS.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_BPS_TO_SECS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_BPS_TO_SECS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_BPS_TO_SECS(x) (1.0 / (x)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert beats per second to seconds. diff --git a/allegro/docs/man/ALLEGRO_CHANNEL_CONF.3 b/allegro/docs/man/ALLEGRO_CHANNEL_CONF.3 new file mode 100644 index 00000000..c1e53ea5 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_CHANNEL_CONF.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_CHANNEL_CONF" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_CHANNEL_CONF - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_CHANNEL_CONF +\f[R] +.fi +.SH DESCRIPTION +.PP +Speaker configuration (mono, stereo, 2.1, etc). +.IP \[bu] 2 +ALLEGRO_CHANNEL_CONF_1 +.IP \[bu] 2 +ALLEGRO_CHANNEL_CONF_2 +.IP \[bu] 2 +ALLEGRO_CHANNEL_CONF_3 +.IP \[bu] 2 +ALLEGRO_CHANNEL_CONF_4 +.IP \[bu] 2 +ALLEGRO_CHANNEL_CONF_5_1 +.IP \[bu] 2 +ALLEGRO_CHANNEL_CONF_6_1 +.IP \[bu] 2 +ALLEGRO_CHANNEL_CONF_7_1 diff --git a/allegro/docs/man/ALLEGRO_COLOR.3 b/allegro/docs/man/ALLEGRO_COLOR.3 new file mode 100644 index 00000000..5ccb1fac --- /dev/null +++ b/allegro/docs/man/ALLEGRO_COLOR.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_COLOR" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_COLOR - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_COLOR ALLEGRO_COLOR; +\f[R] +.fi +.SH DESCRIPTION +.PP +An ALLEGRO_COLOR structure describes a color in a device independent +way. +Use al_map_rgb(3) et al.\ and al_unmap_rgb(3) et al.\ to translate from +and to various color representations. diff --git a/allegro/docs/man/ALLEGRO_COND.3 b/allegro/docs/man/ALLEGRO_COND.3 new file mode 100644 index 00000000..5c967c96 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_COND.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_COND" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_COND - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_COND ALLEGRO_COND; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque structure representing a condition variable. diff --git a/allegro/docs/man/ALLEGRO_CONFIG.3 b/allegro/docs/man/ALLEGRO_CONFIG.3 new file mode 100644 index 00000000..40481c02 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_CONFIG.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_CONFIG" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_CONFIG - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_CONFIG ALLEGRO_CONFIG; +\f[R] +.fi +.SH DESCRIPTION +.PP +An abstract configuration structure. diff --git a/allegro/docs/man/ALLEGRO_CONFIG_ENTRY.3 b/allegro/docs/man/ALLEGRO_CONFIG_ENTRY.3 new file mode 100644 index 00000000..3bb03188 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_CONFIG_ENTRY.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_CONFIG_ENTRY" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_CONFIG_ENTRY - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_CONFIG_ENTRY ALLEGRO_CONFIG_ENTRY; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque structure used for iterating across entries in a configuration +section. +.SH SEE ALSO +.PP +al_get_first_config_entry(3), al_get_next_config_entry(3) diff --git a/allegro/docs/man/ALLEGRO_CONFIG_SECTION.3 b/allegro/docs/man/ALLEGRO_CONFIG_SECTION.3 new file mode 100644 index 00000000..2d26197c --- /dev/null +++ b/allegro/docs/man/ALLEGRO_CONFIG_SECTION.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_CONFIG_SECTION" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_CONFIG_SECTION - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_CONFIG_SECTION ALLEGRO_CONFIG_SECTION; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque structure used for iterating across sections in a +configuration structure. +.SH SEE ALSO +.PP +al_get_first_config_section(3), al_get_next_config_section(3) diff --git a/allegro/docs/man/ALLEGRO_DISPLAY.3 b/allegro/docs/man/ALLEGRO_DISPLAY.3 new file mode 100644 index 00000000..253fcc9a --- /dev/null +++ b/allegro/docs/man/ALLEGRO_DISPLAY.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_DISPLAY" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_DISPLAY - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque type representing an open display or window. diff --git a/allegro/docs/man/ALLEGRO_DISPLAY_MODE.3 b/allegro/docs/man/ALLEGRO_DISPLAY_MODE.3 new file mode 100644 index 00000000..27315265 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_DISPLAY_MODE.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_DISPLAY_MODE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_DISPLAY_MODE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_DISPLAY_MODE +\f[R] +.fi +.SH DESCRIPTION +.PP +Used for fullscreen mode queries. +Contains information about a supported fullscreen modes. +.IP +.nf +\f[C] +typedef struct ALLEGRO_DISPLAY_MODE { + int width; // Screen width + int height; // Screen height + int format; // The pixel format of the mode + int refresh_rate; // The refresh rate of the mode +} ALLEGRO_DISPLAY_MODE; +\f[R] +.fi +.PP +The \f[C]refresh_rate\f[R] may be zero if unknown. +.PP +For an explanation of what \f[C]format\f[R] means, see +ALLEGRO_PIXEL_FORMAT(3). +.SH SEE ALSO +.PP +al_get_display_mode(3) diff --git a/allegro/docs/man/ALLEGRO_EVENT.3 b/allegro/docs/man/ALLEGRO_EVENT.3 new file mode 100644 index 00000000..f436da2a --- /dev/null +++ b/allegro/docs/man/ALLEGRO_EVENT.3 @@ -0,0 +1,564 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_EVENT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_EVENT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef union ALLEGRO_EVENT ALLEGRO_EVENT; +\f[R] +.fi +.SH DESCRIPTION +.PP +An ALLEGRO_EVENT is a union of all builtin event structures, i.e.\ it is +an object large enough to hold the data of any event type. +All events have the following fields in common: +.TP +type (ALLEGRO_EVENT_TYPE) +Indicates the type of event. +.TP +any.source (ALLEGRO_EVENT_SOURCE *) +The event source which generated the event. +.TP +any.timestamp (double) +When the event was generated. +.PP +By examining the \f[C]type\f[R] field you can then access type-specific +fields. +The \f[C]any.source\f[R] field tells you which event source generated +that particular event. +The \f[C]any.timestamp\f[R] field tells you when the event was +generated. +The time is referenced to the same starting point as al_get_time(3). +.PP +Each event is of one of the following types, with the usable fields +given. +.SS ALLEGRO_EVENT_JOYSTICK_AXIS +.PP +A joystick axis value changed. +.TP +joystick.id (ALLEGRO_JOYSTICK *) +The joystick which generated the event. +This is not the same as the event source \f[C]joystick.source\f[R]. +.TP +joystick.stick (int) +The stick number, counting from zero. +Axes on a joystick are grouped into \[lq]sticks\[rq]. +.TP +joystick.axis (int) +The axis number on the stick, counting from zero. +.TP +joystick.pos (float) +The axis position, from -1.0 to +1.0. +.SS ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN +.PP +A joystick button was pressed. +.TP +joystick.id (ALLEGRO_JOYSTICK *) +The joystick which generated the event. +.TP +joystick.button (int) +The button which was pressed, counting from zero. +.SS ALLEGRO_EVENT_JOYSTICK_BUTTON_UP +.PP +A joystick button was released. +.TP +joystick.id (ALLEGRO_JOYSTICK *) +The joystick which generated the event. +.TP +joystick.button (int) +The button which was released, counting from zero. +.SS ALLEGRO_EVENT_JOYSTICK_CONFIGURATION +.PP +A joystick was plugged in or unplugged. +See al_reconfigure_joysticks(3) for details. +.SS ALLEGRO_EVENT_KEY_DOWN +.PP +A keyboard key was pressed. +.TP +keyboard.keycode (int) +The code corresponding to the physical key which was pressed. +See the [Key codes] section for the list of ALLEGRO_KEY_* constants. +.TP +keyboard.display (ALLEGRO_DISPLAY *) +The display which had keyboard focus when the event occurred. +.RS +.PP +\f[I]Note:\f[R] this event is about the physical keys being pressed on +the keyboard. +Look for ALLEGRO_EVENT_KEY_CHAR events for character input. +.RE +.SS ALLEGRO_EVENT_KEY_UP +.PP +A keyboard key was released. +.TP +keyboard.keycode (int) +The code corresponding to the physical key which was released. +See the [Key codes] section for the list of ALLEGRO_KEY_* constants. +.TP +keyboard.display (ALLEGRO_DISPLAY *) +The display which had keyboard focus when the event occurred. +.SS ALLEGRO_EVENT_KEY_CHAR +.PP +A character was typed on the keyboard, or a character was auto-repeated. +.TP +keyboard.keycode (int) +The code corresponding to the physical key which was last pressed. +See the [Key codes] section for the list of ALLEGRO_KEY_* constants. +.TP +keyboard.unichar (int) +A Unicode code point (character). +This \f[I]may\f[R] be zero or negative if the event was generated for a +non-visible \[lq]character\[rq], such as an arrow or Function key. +In that case you can act upon the \f[C]keycode\f[R] field. +.RS +.PP +Some special keys will set the \f[C]unichar\f[R] field to their standard +ASCII values: Tab=9, Return=13, Escape=27. +In addition if you press the Control key together with A to Z the +\f[C]unichar\f[R] field will have the values 1 to 26. +For example Ctrl-A will set \f[C]unichar\f[R] to 1 and Ctrl-H will set +it to 8. +.PP +As of Allegro 5.0.2 there are some inconsistencies in the treatment of +Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. +These can be worked around by checking the \f[C]keycode\f[R] field. +.RE +.TP +keyboard.modifiers (unsigned) +This is a bitfield of the modifier keys which were pressed when the +event occurred. +See \[lq]Keyboard modifier flags\[rq] for the constants. +.TP +keyboard.repeat (bool) +Indicates if this is a repeated character. +.TP +keyboard.display (ALLEGRO_DISPLAY *) +The display which had keyboard focus when the event occurred. +.RS +.PP +\f[I]Note\f[R]: in many input methods, characters are \f[I]not\f[R] +entered one-for-one with physical key presses. +Multiple key presses can combine to generate a single character, +e.g.\ apostrophe + e may produce `\['e]'. +Fewer key presses can also generate more characters, e.g.\ macro +sequences expanding to common phrases. +.RE +.SS ALLEGRO_EVENT_MOUSE_AXES +.PP +One or more mouse axis values changed. +.TP +mouse.x (int) +x-coordinate +.TP +mouse.y (int) +y-coordinate +.TP +mouse.z (int) +z-coordinate. +This usually means the vertical axis of a mouse wheel, where up is +positive and down is negative. +.TP +mouse.w (int) +w-coordinate. +This usually means the horizontal axis of a mouse wheel. +.TP +mouse.dx (int) +Change in the x-coordinate value since the previous +ALLEGRO_EVENT_MOUSE_AXES event. +.TP +mouse.dy (int) +Change in the y-coordinate value since the previous +ALLEGRO_EVENT_MOUSE_AXES event. +.TP +mouse.dz (int) +Change in the z-coordinate value since the previous +ALLEGRO_EVENT_MOUSE_AXES event. +.TP +mouse.dw (int) +Change in the w-coordinate value since the previous +ALLEGRO_EVENT_MOUSE_AXES event. +.TP +mouse.pressure (float) +Pressure, ranging from \f[C]0.0\f[R] to \f[C]1.0\f[R]. +.TP +mouse.display (ALLEGRO_DISPLAY *) +The display which had mouse focus. +.RS +.PP +\f[I]Note:\f[R] Calling al_set_mouse_xy(3) also will result in a change +of axis values, but such a change is reported with +ALLEGRO_EVENT_MOUSE_WARPED(3) events instead which are identical except +for their type. +.RE +.RS +.PP +\f[I]Note:\f[R] currently mouse.display may be NULL if an event is +generated in response to al_set_mouse_axis(3). +.RE +.SS ALLEGRO_EVENT_MOUSE_BUTTON_DOWN +.PP +A mouse button was pressed. +.TP +mouse.x (int) +x-coordinate +.TP +mouse.y (int) +y-coordinate +.TP +mouse.z (int) +z-coordinate +.TP +mouse.w (int) +w-coordinate +.TP +mouse.button (unsigned) +The mouse button which was pressed, numbering from 1. +.TP +mouse.pressure (float) +Pressure, ranging from \f[C]0.0\f[R] to \f[C]1.0\f[R]. +.TP +mouse.display (ALLEGRO_DISPLAY *) +The display which had mouse focus. +.SS ALLEGRO_EVENT_MOUSE_BUTTON_UP +.PP +A mouse button was released. +.TP +mouse.x (int) +x-coordinate +.TP +mouse.y (int) +y-coordinate +.TP +mouse.z (int) +z-coordinate +.TP +mouse.w (int) +w-coordinate +.TP +mouse.button (unsigned) +The mouse button which was released, numbering from 1. +.TP +mouse.pressure (float) +Pressure, ranging from \f[C]0.0\f[R] to \f[C]1.0\f[R]. +.TP +mouse.display (ALLEGRO_DISPLAY *) +The display which had mouse focus. +.SS ALLEGRO_EVENT_MOUSE_WARPED +.PP +al_set_mouse_xy(3) was called to move the mouse. +This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. +.SS ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY +.PP +The mouse cursor entered a window opened by the program. +.TP +mouse.x (int) +x-coordinate +.TP +mouse.y (int) +y-coordinate +.TP +mouse.z (int) +z-coordinate +.TP +mouse.w (int) +w-coordinate +.TP +mouse.display (ALLEGRO_DISPLAY *) +The display which had mouse focus. +.SS ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY +.PP +The mouse cursor left the boundaries of a window opened by the program. +.TP +mouse.x (int) +x-coordinate +.TP +mouse.y (int) +y-coordinate +.TP +mouse.z (int) +z-coordinate +.TP +mouse.w (int) +w-coordinate +.TP +mouse.display (ALLEGRO_DISPLAY *) +The display which had mouse focus. +.SS ALLEGRO_EVENT_TOUCH_BEGIN +.PP +The touch input device registered a new touch. +.TP +touch.display (ALLEGRO_DISPLAY) +The display which was touched. +.TP +touch.id (int) +An identifier for this touch. +If supported by the device it will stay the same for events from the +same finger until the touch ends. +.TP +touch.x (float) +The x coordinate of the touch in pixels. +.TP +touch.y (float) +The y coordinate of the touch in pixels. +.TP +touch.dx (float) +Movement speed in pixels in x direction. +.TP +touch.dy (float) +Movement speed in pixels in y direction. +.TP +touch.primary (bool) +Whether this is the only/first touch or an additional touch. +.SH SINCE +.PP +5.1.0 +.SS ALLEGRO_EVENT_TOUCH_END +.PP +A touch ended. +.PP +Has the same fields as ALLEGRO_EVENT_TOUCH_BEGIN(3). +.SH SINCE +.PP +5.1.0 +.SS ALLEGRO_EVENT_TOUCH_MOVE +.PP +The position of a touch changed. +.PP +Has the same fields as ALLEGRO_EVENT_TOUCH_BEGIN(3). +.SH SINCE +.PP +5.1.0 +.SS ALLEGRO_EVENT_TOUCH_CANCEL +.PP +A touch was cancelled. +This is device specific but could for example mean that a finger moved +off the border of the device or moved so fast that it could not be +tracked any longer. +.PP +Has the same fields as ALLEGRO_EVENT_TOUCH_BEGIN(3). +.SH SINCE +.PP +5.1.0 +.SS ALLEGRO_EVENT_TIMER +.PP +A [timer]ALLEGRO_TIMER(3) counter incremented. +.TP +timer.source (ALLEGRO_TIMER *) +The timer which generated the event. +.TP +timer.count (int64_t) +The timer count value. +.SS ALLEGRO_EVENT_DISPLAY_EXPOSE +.PP +The display (or a portion thereof) has become visible. +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was exposed. +.TP +display.x (int) +The X position of the top-left corner of the rectangle which was +exposed. +.TP +display.y (int) +The Y position of the top-left corner of the rectangle which was +exposed. +.TP +display.width (int) +The width of the rectangle which was exposed. +.TP +display.height (int) +The height of the rectangle which was exposed. +.RS +.PP +\f[I]Note:\f[R] The display needs to be created with +ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be generated. +.RE +.SS ALLEGRO_EVENT_DISPLAY_RESIZE +.PP +The window has been resized. +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was resized. +.TP +display.x (int) +The X position of the top-left corner of the display. +.TP +display.y (int) +The Y position of the top-left corner of the display. +.TP +display.width (int) +The new width of the display. +.TP +display.height (int) +The new height of the display. +.PP +You should normally respond to these events by calling +al_acknowledge_resize(3). +Note that further resize events may be generated by the time you process +the event, so these fields may hold outdated information. +.SS ALLEGRO_EVENT_DISPLAY_CLOSE +.PP +The close button of the window has been pressed. +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was closed. +.SS ALLEGRO_EVENT_DISPLAY_LOST +.PP +When using Direct3D, displays can enter a \[lq]lost\[rq] state. +In that state, drawing calls are ignored, and upon entering the state, +bitmap\[cq]s pixel data can become undefined. +Allegro does its best to preserve the correct contents of bitmaps (see +the ALLEGRO_NO_PRESERVE_TEXTURE flag) and restore them when the device +is \[lq]found\[rq] (see ALLEGRO_EVENT_DISPLAY_FOUND(3)). +However, this is not 100% fool proof (see discussion in +al_create_bitmap(3)\[cq]s documentation). +.RS +.PP +\f[I]Note:\f[R] This event merely means that the display was lost, that +is, DirectX suddenly lost the contents of all video bitmaps. +In particular, you can keep calling drawing functions \[en] they just +most likely won\[cq]t do anything. +If Allegro\[cq]s restoration of the bitmaps works well for you then no +further action is required when you receive this event. +.RE +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was lost. +.SS ALLEGRO_EVENT_DISPLAY_FOUND +.PP +Generated when a lost device is restored to operating state. +See ALLEGRO_EVENT_DISPLAY_LOST(3). +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was found. +.SS ALLEGRO_EVENT_DISPLAY_SWITCH_OUT +.PP +The window is no longer active, that is the user might have clicked into +another window or \[lq]tabbed\[rq] away. +In response to this event you might want to call +al_clear_keyboard_state(3) (possibly passing display.source as its +argument) in order to prevent Allegro\[cq]s keyboard state from getting +out of sync. +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was switched out of. +.SS ALLEGRO_EVENT_DISPLAY_SWITCH_IN +.PP +The window is the active one again. +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was switched into. +.SS ALLEGRO_EVENT_DISPLAY_ORIENTATION +.PP +Generated when the rotation or orientation of a display changes. +.TP +display.source (ALLEGRO_DISPLAY *) +The display which generated the event. +.TP +event.display.orientation +Contains one of the following values: +.RS +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_FACE_UP +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN +.RE +.SS ALLEGRO_EVENT_DISPLAY_HALT_DRAWING +.PP +When a display receives this event it should stop doing any drawing and +then call al_acknowledge_drawing_halt(3) immediately. +.PP +This is currently only relevant for Android and iOS. +It will be sent when the application is switched to background mode, in +addition to ALLEGRO_EVENT_DISPLAY_SWITCH_OUT(3). +The latter may also be sent in situations where the application is not +active but still should continue drawing, for example when a popup is +displayed in front of it. +.RS +.PP +\f[I]Note:\f[R] This event means that the next time you call a drawing +function, your program will crash. +So you \f[I]must\f[R] stop drawing and you \f[I]must\f[R] immediately +reply with al_acknowledge_drawing_halt(3). +Allegro sends this event because it cannot handle this automatically. +Your program might be doing the drawing in a different thread from the +event handling, in which case the drawing thread needs to be signaled to +stop drawing before acknowledging this event. +.RE +.RS +.PP +\f[I]Note:\f[R] Mobile devices usually never quit an application, so to +prevent the battery from draining while your application is halted it +can be a good idea to call al_stop_timer(3) on all your timers, +otherwise they will keep generating events. +If you are using audio, you can also stop all audio voices (or pass NULL +to al_set_default_voice(3) if you use the default mixer), otherwise +Allegro will keep streaming silence to the voice even if the stream or +mixer are stopped or detached. +.RE +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING(3) +.SS ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING +.PP +When a display receives this event, it may resume drawing again, and it +must call al_acknowledge_drawing_resume(3) immediately. +.PP +This is currently only relevant for Android and iOS. +The event will be sent when an application returns from background mode +and is allowed to draw to the display again, in addition to +ALLEGRO_EVENT_DISPLAY_SWITCH_IN(3). +The latter event may also be sent in a situation where the application +is already active, for example when a popup in front of it closes. +.RS +.PP +\f[I]Note:\f[R] Unlike ALLEGRO_EVENT_DISPLAY_FOUND(3) it is not +necessary to reload any bitmaps when you receive this event. +.RE +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +ALLEGRO_EVENT_DISPLAY_HALT_DRAWING(3) +.SS ALLEGRO_EVENT_DISPLAY_CONNECTED +.PP +This event is sent when a physical display is connected to the device +Allegro runs on. +Currently, on most platforms, Allegro supports only a single physical +display. +However, on iOS, a secondary physical display is supported. +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was connected. +.SH SINCE +.PP +5.1.1 +.SS ALLEGRO_EVENT_DISPLAY_DISCONNECTED +.PP +This event is sent when a physical display is disconnected from the +device Allegro runs on. +Currently, on most platforms, Allegro supports only a single physical +display. +However, on iOS, a secondary physical display is supported. +.TP +display.source (ALLEGRO_DISPLAY *) +The display which was disconnected. diff --git a/allegro/docs/man/ALLEGRO_EVENT_QUEUE.3 b/allegro/docs/man/ALLEGRO_EVENT_QUEUE.3 new file mode 100644 index 00000000..e281bca7 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_EVENT_QUEUE.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_EVENT_QUEUE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_EVENT_QUEUE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_EVENT_QUEUE ALLEGRO_EVENT_QUEUE; +\f[R] +.fi +.SH DESCRIPTION +.PP +An event queue holds events that have been generated by event sources +that are registered with the queue. +Events are stored in the order they are generated. +Access is in a strictly FIFO (first-in-first-out) order. +.SH SEE ALSO +.PP +al_create_event_queue(3), al_destroy_event_queue(3) diff --git a/allegro/docs/man/ALLEGRO_EVENT_SOURCE.3 b/allegro/docs/man/ALLEGRO_EVENT_SOURCE.3 new file mode 100644 index 00000000..30bb82dc --- /dev/null +++ b/allegro/docs/man/ALLEGRO_EVENT_SOURCE.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_EVENT_SOURCE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_EVENT_SOURCE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_EVENT_SOURCE ALLEGRO_EVENT_SOURCE; +\f[R] +.fi +.SH DESCRIPTION +.PP +An event source is any object which can generate events. +For example, an ALLEGRO_DISPLAY can generate events, and you can get the +ALLEGRO_EVENT_SOURCE pointer from an ALLEGRO_DISPLAY with +al_get_display_event_source(3). +.PP +You may create your own \[lq]user\[rq] event sources that emit custom +events. +.SH SEE ALSO +.PP +ALLEGRO_EVENT(3), al_init_user_event_source(3), al_emit_user_event(3) diff --git a/allegro/docs/man/ALLEGRO_EVENT_TYPE.3 b/allegro/docs/man/ALLEGRO_EVENT_TYPE.3 new file mode 100644 index 00000000..fcac90dd --- /dev/null +++ b/allegro/docs/man/ALLEGRO_EVENT_TYPE.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_EVENT_TYPE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_EVENT_TYPE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef unsigned int ALLEGRO_EVENT_TYPE; +\f[R] +.fi +.SH DESCRIPTION +.PP +An integer used to distinguish between different types of events. +.SH SEE ALSO +.PP +ALLEGRO_EVENT(3), ALLEGRO_GET_EVENT_TYPE(3), +ALLEGRO_EVENT_TYPE_IS_USER(3) diff --git a/allegro/docs/man/ALLEGRO_EVENT_TYPE_IS_USER.3 b/allegro/docs/man/ALLEGRO_EVENT_TYPE_IS_USER.3 new file mode 100644 index 00000000..595782ac --- /dev/null +++ b/allegro/docs/man/ALLEGRO_EVENT_TYPE_IS_USER.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_EVENT_TYPE_IS_USER" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_EVENT_TYPE_IS_USER - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_EVENT_TYPE_IS_USER(t) ((t) >= 512) +\f[R] +.fi +.SH DESCRIPTION +.PP +A macro which evaluates to true if the event type is not a builtin event +type, i.e.\ one of those described in ALLEGRO_EVENT_TYPE(3). diff --git a/allegro/docs/man/ALLEGRO_FILE.3 b/allegro/docs/man/ALLEGRO_FILE.3 new file mode 100644 index 00000000..3649911c --- /dev/null +++ b/allegro/docs/man/ALLEGRO_FILE.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_FILE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_FILE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_FILE ALLEGRO_FILE; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque object representing an open file. +This could be a real file on disk or a virtual file. diff --git a/allegro/docs/man/ALLEGRO_FILECHOOSER.3 b/allegro/docs/man/ALLEGRO_FILECHOOSER.3 new file mode 100644 index 00000000..7c527f4f --- /dev/null +++ b/allegro/docs/man/ALLEGRO_FILECHOOSER.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_FILECHOOSER" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_FILECHOOSER - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_FILECHOOSER ALLEGRO_FILECHOOSER; +\f[R] +.fi +.SH DESCRIPTION +.PP +Opaque handle to a native file dialog. diff --git a/allegro/docs/man/ALLEGRO_FILE_INTERFACE.3 b/allegro/docs/man/ALLEGRO_FILE_INTERFACE.3 new file mode 100644 index 00000000..d5fa8730 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_FILE_INTERFACE.3 @@ -0,0 +1,55 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_FILE_INTERFACE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_FILE_INTERFACE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_FILE_INTERFACE +\f[R] +.fi +.SH DESCRIPTION +.PP +A structure containing function pointers to handle a type of +\[lq]file\[rq], real or virtual. +See the full discussion in al_set_new_file_interface(3). +.PP +The fields are: +.IP +.nf +\f[C] +void* (*fi_fopen)(const char *path, const char *mode); +bool (*fi_fclose)(ALLEGRO_FILE *f); +size_t (*fi_fread)(ALLEGRO_FILE *f, void *ptr, size_t size); +size_t (*fi_fwrite)(ALLEGRO_FILE *f, const void *ptr, size_t size); +bool (*fi_fflush)(ALLEGRO_FILE *f); +int64_t (*fi_ftell)(ALLEGRO_FILE *f); +bool (*fi_fseek)(ALLEGRO_FILE *f, int64_t offset, int whence); +bool (*fi_feof)(ALLEGRO_FILE *f); +int (*fi_ferror)(ALLEGRO_FILE *f); +const char * (*fi_ferrmsg)(ALLEGRO_FILE *f); +void (*fi_fclearerr)(ALLEGRO_FILE *f); +int (*fi_fungetc)(ALLEGRO_FILE *f, int c); +off_t (*fi_fsize)(ALLEGRO_FILE *f); +\f[R] +.fi +.PP +The fi_open function must allocate memory for whatever userdata +structure it needs. +The pointer to that memory must be returned; it will then be associated +with the file. +The other functions can access that data by calling +al_get_file_userdata(3) on the file handle. +If fi_open returns NULL then al_fopen(3) will also return NULL. +.PP +The fi_fclose function must clean up and free the userdata, but Allegro +will free the ALLEGRO_FILE(3) handle. +.PP +If fi_fungetc is NULL, then Allegro\[cq]s default implementation of a 16 +char long buffer will be used. diff --git a/allegro/docs/man/ALLEGRO_FILE_MODE.3 b/allegro/docs/man/ALLEGRO_FILE_MODE.3 new file mode 100644 index 00000000..8c50db54 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_FILE_MODE.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_FILE_MODE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_FILE_MODE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_FILE_MODE +\f[R] +.fi +.SH DESCRIPTION +.PP +Filesystem modes/types +.IP \[bu] 2 +ALLEGRO_FILEMODE_READ - Readable +.IP \[bu] 2 +ALLEGRO_FILEMODE_WRITE - Writable +.IP \[bu] 2 +ALLEGRO_FILEMODE_EXECUTE - Executable +.IP \[bu] 2 +ALLEGRO_FILEMODE_HIDDEN - Hidden +.IP \[bu] 2 +ALLEGRO_FILEMODE_ISFILE - Regular file +.IP \[bu] 2 +ALLEGRO_FILEMODE_ISDIR - Directory diff --git a/allegro/docs/man/ALLEGRO_FONT.3 b/allegro/docs/man/ALLEGRO_FONT.3 new file mode 100644 index 00000000..8a5e7612 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_FONT.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_FONT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_FONT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_FONT ALLEGRO_FONT; +\f[R] +.fi +.SH DESCRIPTION +.PP +A handle identifying any kind of font. +Usually you will create it with al_load_font(3) which supports loading +all kinds of TrueType fonts supported by the FreeType library. +If you instead pass the filename of a bitmap file, it will be loaded +with al_load_bitmap(3) and a font in Allegro\[cq]s bitmap font format +will be created from it with al_grab_font_from_bitmap(3). diff --git a/allegro/docs/man/ALLEGRO_FOR_EACH_FS_ENTRY_RESULT.3 b/allegro/docs/man/ALLEGRO_FOR_EACH_FS_ENTRY_RESULT.3 new file mode 100644 index 00000000..661115fd --- /dev/null +++ b/allegro/docs/man/ALLEGRO_FOR_EACH_FS_ENTRY_RESULT.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_FOR_EACH_FS_ENTRY_RESULT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_FOR_EACH_FS_ENTRY_RESULT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_FOR_EACH_FS_ENTRY_RESULT { +\f[R] +.fi +.SH DESCRIPTION +.PP +Return values for the callbacks of al_for_each_fs_entry(3) and for that +function itself. +.IP \[bu] 2 +ALLEGRO_FOR_EACH_FS_ENTRY_ERROR - An error ocurred. +.IP \[bu] 2 +ALLEGRO_FOR_EACH_FS_ENTRY_OK - Continue normally and recurse into +directories. +.IP \[bu] 2 +ALLEGRO_FOR_EACH_FS_ENTRY_SKIP - Continue but do NOT recusively descend. +.IP \[bu] 2 +ALLEGRO_FOR_EACH_FS_ENTRY_STOP - Stop iterating and return. +.SH SEE ALSO +.PP +al_for_each_fs_entry(3) +.SH SINCE +.PP +5.1.9 diff --git a/allegro/docs/man/ALLEGRO_FS_ENTRY.3 b/allegro/docs/man/ALLEGRO_FS_ENTRY.3 new file mode 100644 index 00000000..27de92b1 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_FS_ENTRY.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_FS_ENTRY" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_FS_ENTRY - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_FS_ENTRY ALLEGRO_FS_ENTRY; +\f[R] +.fi +.SH DESCRIPTION +.PP +Opaque filesystem entry object. +Represents a file or a directory (check with al_get_fs_entry_mode(3)). +There are no user accessible member variables. diff --git a/allegro/docs/man/ALLEGRO_FS_INTERFACE.3 b/allegro/docs/man/ALLEGRO_FS_INTERFACE.3 new file mode 100644 index 00000000..4def30d9 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_FS_INTERFACE.3 @@ -0,0 +1,48 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_FS_INTERFACE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_FS_INTERFACE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_FS_INTERFACE ALLEGRO_FS_INTERFACE; +\f[R] +.fi +.SH DESCRIPTION +.PP +The available functions you can provide for a filesystem. +They are: +.IP +.nf +\f[C] + ALLEGRO_FS_ENTRY * fs_create_entry (const char *path); + void fs_destroy_entry (ALLEGRO_FS_ENTRY *e); + const char * fs_entry_name (ALLEGRO_FS_ENTRY *e); + bool fs_update_entry (ALLEGRO_FS_ENTRY *e); + uint32_t fs_entry_mode (ALLEGRO_FS_ENTRY *e); + time_t fs_entry_atime (ALLEGRO_FS_ENTRY *e); + time_t fs_entry_mtime (ALLEGRO_FS_ENTRY *e); + time_t fs_entry_ctime (ALLEGRO_FS_ENTRY *e); + off_t fs_entry_size (ALLEGRO_FS_ENTRY *e); + bool fs_entry_exists (ALLEGRO_FS_ENTRY *e); + bool fs_remove_entry (ALLEGRO_FS_ENTRY *e); + + bool fs_open_directory (ALLEGRO_FS_ENTRY *e); + ALLEGRO_FS_ENTRY * fs_read_directory (ALLEGRO_FS_ENTRY *e); + bool fs_close_directory(ALLEGRO_FS_ENTRY *e); + + bool fs_filename_exists(const char *path); + bool fs_remove_filename(const char *path); + char * fs_get_current_directory(void); + bool fs_change_directory(const char *path); + bool fs_make_directory(const char *path); + + ALLEGRO_FILE * fs_open_file(ALLEGRO_FS_ENTRY *e); +\f[R] +.fi diff --git a/allegro/docs/man/ALLEGRO_GET_EVENT_TYPE.3 b/allegro/docs/man/ALLEGRO_GET_EVENT_TYPE.3 new file mode 100644 index 00000000..dc45869f --- /dev/null +++ b/allegro/docs/man/ALLEGRO_GET_EVENT_TYPE.3 @@ -0,0 +1,57 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_GET_EVENT_TYPE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_GET_EVENT_TYPE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_GET_EVENT_TYPE(a, b, c, d) AL_ID(a, b, c, d) +\f[R] +.fi +.SH DESCRIPTION +.PP +Make an event type identifier, which is a 32-bit integer. +Usually, but not necessarily, this will be made from four 8-bit +character codes, for example: +.IP +.nf +\f[C] +#define MY_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE(\[aq]M\[aq],\[aq]I\[aq],\[aq]N\[aq],\[aq]E\[aq]) +\f[R] +.fi +.PP +IDs less than 1024 are reserved for Allegro or its addons. +Don\[cq]t use anything lower than +\f[C]ALLEGRO_GET_EVENT_TYPE(0, 0, 4, 0)\f[R]. +.PP +You should try to make your IDs unique so they don\[cq]t clash with any +3rd party code you may be using. +Be creative. +Numbering from 1024 is not creative. +.PP +If you need multiple identifiers, you could define them like this: +.IP +.nf +\f[C] +#define BASE_EVENT ALLEGRO_GET_EVENT_TYPE(\[aq]M\[aq],\[aq]I\[aq],\[aq]N\[aq],\[aq]E\[aq]) +#define BARK_EVENT (BASE_EVENT + 0) +#define MEOW_EVENT (BASE_EVENT + 1) +#define SQUAWK_EVENT (BASE_EVENT + 2) + +/* Alternatively */ +enum { + BARK_EVENT = ALLEGRO_GET_EVENT_TYPE(\[aq]M\[aq],\[aq]I\[aq],\[aq]N\[aq],\[aq]E\[aq]), + MEOW_EVENT, + SQUAWK_EVENT +}; +\f[R] +.fi +.SH SEE ALSO +.PP +ALLEGRO_EVENT(3), ALLEGRO_USER_EVENT(3), ALLEGRO_EVENT_TYPE_IS_USER(3) diff --git a/allegro/docs/man/ALLEGRO_GLYPH.3 b/allegro/docs/man/ALLEGRO_GLYPH.3 new file mode 100644 index 00000000..16e8d136 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_GLYPH.3 @@ -0,0 +1,59 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_GLYPH" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_GLYPH - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_GLYPH ALLEGRO_GLYPH; +\f[R] +.fi +.SH DESCRIPTION +.PP +A structure containing the properties of a character in a font. +.IP +.nf +\f[C] +typedef struct ALLEGRO_GLYPH { + ALLEGRO_BITMAP *bitmap; // the bitmap the character is on + int x; // the x position of the glyph on bitmap + int y; // the y position of the glyph on bitmap + int w; // the width of the glyph in pixels + int h; // the height of the glyph in pixels + int kerning; // pixels of kerning (see below) + int offset_x; // x offset to draw the glyph at + int offset_y; // y offset to draw the glyph at + int advance; // number of pixels to advance after this character +} ALLEGRO_GLYPH; +\f[R] +.fi +.PP +bitmap may be a sub-bitmap in the case of color fonts. +Bitmap can also be NULL in which case nothing should be drawn (sometimes +true for whitespace characters in TTF fonts). +.PP +kerning should be added to the x position you draw to if you want your +text kerned and depends on which codepoints al_get_glyph(3) was called +with. +.PP +Glyphs are tightly packed onto the bitmap, so you need to add offset_x +and offset_y to your draw position for the text to look right. +.PP +advance is the number of pixels to add to your x position to advance to +the next character in a string and includes kerning. +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This API is new and subject to refinement. +.RE +.SH SEE ALSO +.PP +al_get_glyph(3) diff --git a/allegro/docs/man/ALLEGRO_HAPTIC.3 b/allegro/docs/man/ALLEGRO_HAPTIC.3 new file mode 100644 index 00000000..12472f62 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_HAPTIC.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_HAPTIC" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_HAPTIC - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_HAPTIC ALLEGRO_HAPTIC; +\f[R] +.fi +.SH DESCRIPTION +.PP +This is an abstract data type representing a haptic device that supports +force feedback or vibration. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE +.SH SEE ALSO +.PP +al_get_haptic_from_joystick(3) diff --git a/allegro/docs/man/ALLEGRO_HAPTIC_CONSTANTS.3 b/allegro/docs/man/ALLEGRO_HAPTIC_CONSTANTS.3 new file mode 100644 index 00000000..e260e4b1 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_HAPTIC_CONSTANTS.3 @@ -0,0 +1,74 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_HAPTIC_CONSTANTS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_HAPTIC_CONSTANTS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_HAPTIC_CONSTANTS +\f[R] +.fi +.SH DESCRIPTION +.PP +This enum contains flags that are used to define haptic effects and +capabilities. +If the flag is set in the return value of al_get_haptic_capabilities(3), +it means the device supports the given effect. +The value of these flags should be set into a ALLEGRO_HAPTIC_EFFECT(3) +struct to determine what kind of haptic effect should be played. +.IP \[bu] 2 +ALLEGRO_HAPTIC_RUMBLE - simple vibration effects +.IP \[bu] 2 +ALLEGRO_HAPTIC_PERIODIC - periodic, wave-form effects +.IP \[bu] 2 +ALLEGRO_HAPTIC_CONSTANT - constant effects +.IP \[bu] 2 +ALLEGRO_HAPTIC_SPRING - spring effects +.IP \[bu] 2 +ALLEGRO_HAPTIC_FRICTION - friction effects +.IP \[bu] 2 +ALLEGRO_HAPTIC_DAMPER - damper effects +.IP \[bu] 2 +ALLEGRO_HAPTIC_INERTIA - inertia effects +.IP \[bu] 2 +ALLEGRO_HAPTIC_RAMP - ramp effects +.IP \[bu] 2 +ALLEGRO_HAPTIC_SQUARE - square wave periodic effect +.IP \[bu] 2 +ALLEGRO_HAPTIC_TRIANGLE - triangle wave periodic effect +.IP \[bu] 2 +ALLEGRO_HAPTIC_SINE - sine wave periodic effect +.IP \[bu] 2 +ALLEGRO_HAPTIC_SAW_UP - upwards saw wave periodic effect +.IP \[bu] 2 +ALLEGRO_HAPTIC_SAW_DOWN - downwards saw wave periodic effect +.IP \[bu] 2 +ALLEGRO_HAPTIC_CUSTOM - custom wave periodic effect +.IP \[bu] 2 +ALLEGRO_HAPTIC_GAIN - the haptic device supports gain setting +.IP \[bu] 2 +ALLEGRO_HAPTIC_ANGLE - the haptic device supports angle coordinates +.IP \[bu] 2 +ALLEGRO_HAPTIC_RADIUS - the haptic device supports radius coordinates +.IP \[bu] 2 +ALLEGRO_HAPTIC_AZIMUTH - the haptic device supports azimuth coordinates +.IP \[bu] 2 +ALLEGRO_HAPTIC_AUTOCENTER +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE +.SH SEE ALSO +.PP +al_get_haptic_capabilities(3), ALLEGRO_HAPTIC_EFFECT(3) diff --git a/allegro/docs/man/ALLEGRO_HAPTIC_EFFECT.3 b/allegro/docs/man/ALLEGRO_HAPTIC_EFFECT.3 new file mode 100644 index 00000000..3780fde0 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_HAPTIC_EFFECT.3 @@ -0,0 +1,251 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_HAPTIC_EFFECT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_HAPTIC_EFFECT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +struct ALLEGRO_HAPTIC_EFFECT +\f[R] +.fi +.SH DESCRIPTION +.PP +This struct models a particular haptic or vibration effect. +It needs to be filled in correctly and uploaded to a haptic device +before the device can play it back. +.PP +\f[I]Fields:\f[R] +.TP +type +The type of the haptic effect. +May be one of the ALLEGRO_HAPTIC_CONSTANTS constants between or equal to +ALLEGRO_HAPTIC_RUMBLE and ALLEGRO_HAPTIC_RAMP. +.RS +.IP \[bu] 2 +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_RUMBLE, then the effect is a +simple \[lq]rumble\[rq] or vibration effect that shakes the device. +In some cases, such as on a mobile platform, the whole device may shake. +.IP \[bu] 2 +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_PERIODIC, the effect is a +shake or vibration of which the intensity is a periodic wave form. +.IP \[bu] 2 +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_CONSTANT, the effect is a +constant pressure, motion or push-back in a certain direction of the +axes of the device. +.IP \[bu] 2 +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_SPRING, the effect is a +springy kind of resistance against motion of the axes of the haptic +device. +.IP \[bu] 2 +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_FRICTION, the effect is a +friction kind of resistance against motion of the axes of the haptic +device. +.IP \[bu] 2 +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_DAMPER, the effect is a +damper kind of resistance against motion of the axes of the haptic +device. +.IP \[bu] 2 +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_INERTIA, the effect causes +inertia or slowness of motions on the axes of the haptic device. +.IP \[bu] 2 +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_RAMP, the effect causes a +pressure or push-back that ramps up or down depending on the position of +the axis. +.RE +.TP +direction +The direction of location in 3D space where the effect should be played. +Allegro haptic devices model directions in 3D space using spherical +coordinates. +However, the haptic device may not support localized effects, or may not +support all coordinate components. +.RS +.PP +In Allegro\[cq]s coordinate system, the value in +\f[C]direction.angle\f[R] determines the planar angle between the effect +and the direction of the user who holds the device, expressed in +radians. +This angle increases clockwise away from the user. +So, an effect with an angle 0.0 takes place in the direction of the user +of the haptic device, an angle of \[*p]/2 is to the left of the user, an +angle of \[*p] means the direction away from the user, and an angle of +3\[*p]/2 means to the right of the user. +.PP +If al_get_haptic_capabilities(3) has the flag ALLEGRO_HAPTIC_ANGLE set, +then setting \f[C]direction.angle\f[R] is supported. +Otherwise, it is unsupported, and you should set it to 0. +.PP +The value in \f[C]direction.radius\f[R] is a relative value between 0.0 +and 1.0 that determines the relative distance from the center of the +haptic device at which the effect will play back. +A value of 0 means that the effect should play back at the center of the +device. +A value of 1.0 means that the effect should play back away from the +center as far as is possible. +.PP +If al_get_haptic_capabilities(3) has the flag ALLEGRO_HAPTIC_RADIUS set, +then setting \f[C]direction.radius\f[R] is supported. +Otherwise, it is unsupported, and you should set it to 0. +.PP +The value in \f[C]direction.azimuth\f[R] determines the elevation angle +between the effect and the plane in which the user is holding the +device, expressed in radians. +An effect with an azimuth 0.0 plays back in the plane in which the user +is holding the device, an azimuth +\[*p]/2 means the effect plays back +vertically above the user plane, and an azimuth -\[*p]/2 means the +effect plays back vertically below the user plane. +.PP +If al_get_haptic_capabilities(3) has the flag ALLEGRO_HAPTIC_AZIMUTH +set, then setting \f[C]direction.azimuth\f[R] is supported. +Otherwise, it is unsupported, and you should set it to 0. +.RE +.TP +replay +Determines how the effect should be played back. +\f[C]replay.length\f[R] is the duration in seconds of the effect, and +\f[C]replay.delay\f[R] is the time in seconds that the effect playback +should be delayed when playback is started with +al_play_haptic_effect(3). +.TP +data +Determines in detail the parameters of the haptic effect to play back. +.RS +.PP +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_RUMBLE, then +\f[C]data.rumble.strong_magnitude\f[R] must be set to a relative +magnitude between 0.0 and 1.0 to determine how intensely the +\[lq]large\[rq] rumble motor of the haptic device will vibrate, and +\f[C]data.rumble.weak_magnitude\f[R] must be set to relative magnitude +between 0.0 and 1.0 to determine how intensely the \[lq]weak\[rq] ruble +motor of the haptic device will vibrate. +Not all devices have a \[lq]weak\[rq] motor, in which case the value set +in \f[C]data.rumble.weak_magnitude\f[R] will be ignored. +.PP +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_PERIODIC, then +data.periodic.waveform must be set to one of ALLEGRO_HAPTIC_SQUARE, +ALLEGRO_HAPTIC_TRIANGLE, ALLEGRO_HAPTIC_SINE, ALLEGRO_HAPTIC_SAW_UP, +ALLEGRO_HAPTIC_SAW_DOWN, ALLEGRO_HAPTIC_CUSTOM. +This will then determine the wave form of the vibration effect that will +be played on the haptic device. +.PP +In these cases, \f[C]data.periodic.period\f[R] must be set to the period +in seconds of the wave form. +The field \f[C]data.periodic.magnitude\f[R] must be set to the relative +magnitude of intensity between -1.0 and 1.0 at which the wave form of +the vibration will be played back. +The field \f[C]data.periodic.offset\f[R] must be filled in with the +offset from origin in seconds of the wave form of vibration, and the +field \f[C]data.periodic.phase\f[R] is the phase of the wave form of +vibration in seconds. +.PP +If \f[C]data.periodic.waveform\f[R] is set to ALLEGRO_HAPTIC_CUSTOM, +then \f[C]data.periodic.custom_data\f[R] must point to an array of +\f[C]data.periodic.custom_len\f[R] doubles, each with values between +-1.0 and 1.0. +This value array will determine the shape of the wave form of the haptic +effect. +ALLEGRO_HAPTIC_CUSTOM is not supported on some platforms, so use +al_get_haptic_capabilities(3) to check if it\[cq]s available. +If it isn\[cq]t, you may want to play back a non-custom wave effect as a +substitute instead. +.PP +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_CONSTANT, then +\f[C]data.constant.level\f[R] must be set to a relative intensity value +between 0.0 and 1.0 to determine the intensity of the effect. +.PP +If \f[C]type\f[R] is set to any of ALLEGRO_HAPTIC_SPRING, +ALLEGRO_HAPTIC_FRICTION, ALLEGRO_HAPTIC_DAMPER, ALLEGRO_HAPTIC_INERTIA, +ALLEGRO_HAPTIC_RAMP, then the \f[C]data.condition\f[R] struct should be +filled in. +To explain this better, it\[cq]s best to keep in mind that these kinds +of effects are most useful for steering-wheel kind of devices, where +resistance or inertia should be applied when turning the device\[cq]s +wheel a certain distance to the left or right. +.PP +The field \f[C]data.condition.right_saturation\f[R] must be filled in +with a relative magnitude between -1.0 and 1.0 to determine the +intensity of resistance or inertia on the \[lq]right\[rq] side of the +axis. +Likewise, \f[C]data.condition.left_saturation\f[R] must be filled in +with a relative magnitude between -1.0 and 1.0 to determine the +intensity of resistance or inertia on the \[lq]left\[rq] side of the +axis. +.PP +The field \f[C]data.condition.deadband\f[R] must be filled in with a +relative value between 0.0 and 1.0 to determine the relative width of +the \[lq]dead band\[rq] of the haptic effect. +As long as the axis of the haptic device remains in the \[lq]dead +band\[rq] area, the effect will not be applied. +A value of 0.0 means there is no dead band, and a value of 1.0 means it +applied over the whole range of the axis in question. +.PP +The field \f[C]data.condition.center\f[R] must be filled in with a +relative value between -1.0 and 1.0 to determine the relative position +of the \[lq]center\[rq] of the effect around which the dead band is +centered. +It should be set to 0.0 in case the center should not be shifted. +.PP +The field \f[C]data.condition.right_coef\f[R] and +\f[C]data.condition.right_left_coef\f[R] must be filled in with a +relative coefficient, that will determine how quickly the effect ramps +up on the right and left side. +If set to 1.0, then the effect will be immediately at full intensity +when outside of the dead band. +If set to 0.0 the effect will not be felt at all. +.PP +If \f[C]type\f[R] is set to ALLEGRO_HAPTIC_RAMP, then +\f[C]data.ramp.start_level\f[R] should be set to a relative magnitude +value between -1.0 and 1.0 to determine the initial intensity of the +haptic effect. +The field \f[C]data.ramp.end_level\f[R] should be set to a relative +magnitude value between -1.0 and 1.0 to determine the final intensity of +the haptic effect at the end of playback. +.PP +If \f[C]type\f[R] is set to any of ALLEGRO_HAPTIC_PERIODIC, +ALLEGRO_HAPTIC_CONSTANT, ALLEGRO_HAPTIC_RAMP, then +\f[C]data.envelope\f[R] determines the \[lq]envelope\[rq] of the effect. +That is, it determines the duration and intensity for the ramp-up attack +or \[lq]fade in\[rq] and the ramp-down or \[lq]fade out\[rq] of the +effect. +.PP +In these cases the field \f[C]data.envelope.attack_level\f[R] must be +set to a relative value between 0.0 and 1.0 that determines the +intensity the effect should have when it starts playing (after +\f[C]replay.delay\f[R] seconds have passed since the playback was +started). +The field \f[C]data.envelope.attack_length\f[R] must be set to the time +in seconds that the effect should ramp up to the maximum intensity as +set by the other parameters. +If \f[C]data.envelope.attack_length\f[R] is 0, then the effect will play +immediately at full intensity. +.PP +The field \f[C]data.envelope.fade_level\f[R] must be set to a relative +value between 0.0 and 1.0 that determines the intensity the effect +should have when it stops playing after +\f[C]replay.length + replay.delay\f[R] seconds have passed since the +playback of the effect started. +The field \f[C]data.envelope.fade_length\f[R] must be set to the time in +seconds that the effect should fade out before it finishes playing. +If \f[C]data.envelope.fade_length\f[R] is 0, then the effect will not +fade out. +.PP +If you don\[cq]t want to use an envelope, then set all four fields of +\f[C]data.envelope\f[R] to 0.0. +The effect will then play back at full intensity throughout its +playback. +.RE +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/ALLEGRO_HAPTIC_EFFECT_ID.3 b/allegro/docs/man/ALLEGRO_HAPTIC_EFFECT_ID.3 new file mode 100644 index 00000000..b6c04b33 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_HAPTIC_EFFECT_ID.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_HAPTIC_EFFECT_ID" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_HAPTIC_EFFECT_ID - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_HAPTIC_EFFECT_ID ALLEGRO_HAPTIC_EFFECT_ID; +\f[R] +.fi +.SH DESCRIPTION +.PP +This struct is used as a handle to control playback of a haptic effect +and should be considered opaque. +Its implementation is visible merely to allow allocation by the users of +the Allegro library. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/ALLEGRO_INDEX_BUFFER.3 b/allegro/docs/man/ALLEGRO_INDEX_BUFFER.3 new file mode 100644 index 00000000..7129338d --- /dev/null +++ b/allegro/docs/man/ALLEGRO_INDEX_BUFFER.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_INDEX_BUFFER" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_INDEX_BUFFER - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_INDEX_BUFFER ALLEGRO_INDEX_BUFFER; +\f[R] +.fi +.SH DESCRIPTION +.PP +A GPU index buffer that you can use to store indices of vertices in a +vertex buffer on the GPU instead of uploading them afresh during every +drawing operation. +.SH SINCE +.PP +5.1.8 +.SH SEE ALSO +.PP +al_create_index_buffer(3), al_destroy_index_buffer(3) diff --git a/allegro/docs/man/ALLEGRO_JOYFLAGS.3 b/allegro/docs/man/ALLEGRO_JOYFLAGS.3 new file mode 100644 index 00000000..060817a2 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_JOYFLAGS.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_JOYFLAGS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_JOYFLAGS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_JOYFLAGS +\f[R] +.fi +.SH DESCRIPTION +.IP \[bu] 2 +ALLEGRO_JOYFLAG_DIGITAL - the stick provides digital input +.IP \[bu] 2 +ALLEGRO_JOYFLAG_ANALOGUE - the stick provides analogue input +.PP +(this enum is a holdover from the old API and may be removed) +.SH SEE ALSO +.PP +al_get_joystick_stick_flags(3) diff --git a/allegro/docs/man/ALLEGRO_JOYSTICK.3 b/allegro/docs/man/ALLEGRO_JOYSTICK.3 new file mode 100644 index 00000000..b7fd0206 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_JOYSTICK.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_JOYSTICK" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_JOYSTICK - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_JOYSTICK ALLEGRO_JOYSTICK; +\f[R] +.fi +.SH DESCRIPTION +.PP +This is an abstract data type representing a physical joystick. +.SH SEE ALSO +.PP +al_get_joystick(3) diff --git a/allegro/docs/man/ALLEGRO_JOYSTICK_STATE.3 b/allegro/docs/man/ALLEGRO_JOYSTICK_STATE.3 new file mode 100644 index 00000000..440b1208 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_JOYSTICK_STATE.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_JOYSTICK_STATE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_JOYSTICK_STATE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_JOYSTICK_STATE ALLEGRO_JOYSTICK_STATE; +\f[R] +.fi +.SH DESCRIPTION +.PP +This is a structure that is used to hold a \[lq]snapshot\[rq] of a +joystick\[cq]s axes and buttons at a particular instant. +All fields public and read-only. +.IP +.nf +\f[C] +struct { + float axis[num_axes]; // -1.0 to 1.0 +} stick[num_sticks]; +int button[num_buttons]; // 0 to 32767 +\f[R] +.fi +.SH SEE ALSO +.PP +al_get_joystick_state(3) diff --git a/allegro/docs/man/ALLEGRO_KEYBOARD_STATE.3 b/allegro/docs/man/ALLEGRO_KEYBOARD_STATE.3 new file mode 100644 index 00000000..af41657f --- /dev/null +++ b/allegro/docs/man/ALLEGRO_KEYBOARD_STATE.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_KEYBOARD_STATE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_KEYBOARD_STATE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_KEYBOARD_STATE ALLEGRO_KEYBOARD_STATE; +\f[R] +.fi +.SH DESCRIPTION +.PP +This is a structure that is used to hold a \[lq]snapshot\[rq] of a +keyboard\[cq]s state at a particular instant. +It contains the following publically readable fields: +.IP \[bu] 2 +display - points to the display that had keyboard focus at the time the +state was saved. +If no display was focused, this points to NULL. +.PP +You cannot read the state of keys directly. +Use the function al_key_down(3). diff --git a/allegro/docs/man/ALLEGRO_LINE_CAP.3 b/allegro/docs/man/ALLEGRO_LINE_CAP.3 new file mode 100644 index 00000000..fae6d5da --- /dev/null +++ b/allegro/docs/man/ALLEGRO_LINE_CAP.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_LINE_CAP" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_LINE_CAP - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_LINE_CAP +\f[R] +.fi +.SH DESCRIPTION +.IP \[bu] 2 +ALLEGRO_LINE_CAP_NONE +.IP \[bu] 2 +ALLEGRO_LINE_CAP_SQUARE +.IP \[bu] 2 +ALLEGRO_LINE_CAP_ROUND +.IP \[bu] 2 +ALLEGRO_LINE_CAP_TRIANGLE +.IP \[bu] 2 +ALLEGRO_LINE_CAP_CLOSED +.PP +[IMAGE: \f[I]ALLEGRO_LINE_CAP styles\f[R]] +.PP +See the picture for the difference. +.PP +ALLEGRO_LINE_CAP_CLOSED is different from the others - it causes the +polygon to have no caps. +(And the ALLEGRO_LINE_JOIN(3) style will determine how the vertex +looks.) +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_draw_polygon(3) diff --git a/allegro/docs/man/ALLEGRO_LINE_JOIN.3 b/allegro/docs/man/ALLEGRO_LINE_JOIN.3 new file mode 100644 index 00000000..d3c9d915 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_LINE_JOIN.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_LINE_JOIN" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_LINE_JOIN - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_LINE_JOIN +\f[R] +.fi +.SH DESCRIPTION +.IP \[bu] 2 +ALLEGRO_LINE_JOIN_NONE +.IP \[bu] 2 +ALLEGRO_LINE_JOIN_BEVEL +.IP \[bu] 2 +ALLEGRO_LINE_JOIN_ROUND +.IP \[bu] 2 +ALLEGRO_LINE_JOIN_MITER +.PP +[IMAGE: \f[I]ALLEGRO_LINE_JOIN styles\f[R]] +.PP +See the picture for the difference. +.PP +The maximum miter length (relative to the line width) can be specified +as parameter to the polygon functions. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_draw_polygon(3) diff --git a/allegro/docs/man/ALLEGRO_LOCKED_REGION.3 b/allegro/docs/man/ALLEGRO_LOCKED_REGION.3 new file mode 100644 index 00000000..e1bfb920 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_LOCKED_REGION.3 @@ -0,0 +1,59 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_LOCKED_REGION" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_LOCKED_REGION - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_LOCKED_REGION ALLEGRO_LOCKED_REGION; +\f[R] +.fi +.SH DESCRIPTION +.PP +Users who wish to manually edit or read from a bitmap are required to +lock it first. +The ALLEGRO_LOCKED_REGION structure represents the locked region of the +bitmap. +This call will work with any bitmap, including memory bitmaps. +.IP +.nf +\f[C] +typedef struct ALLEGRO_LOCKED_REGION { + void *data; + int format; + int pitch; + int pixel_size; +} ALLEGRO_LOCKED_REGION; +\f[R] +.fi +.IP \[bu] 2 +\f[I]data\f[R] points to the leftmost pixel of the first row (row 0) of +the locked region. +For blocked formats, this points to the leftmost block of the first row +of blocks. +.IP \[bu] 2 +\f[I]format\f[R] indicates the pixel format of the data. +.IP \[bu] 2 +\f[I]pitch\f[R] gives the size in bytes of a single row (also known as +the stride). +The pitch may be greater than \f[C]width * pixel_size\f[R] due to +padding; this is not uncommon. +It is also \f[I]not\f[R] uncommon for the pitch to be negative (the +bitmap may be upside down). +For blocked formats, `row' refers to the row of blocks, not of pixels. +.IP \[bu] 2 +\f[I]pixel_size\f[R] is the number of bytes used to represent a single +block of pixels for the pixel format of this locked region. +For most formats (and historically, this used to be true for all +formats), this is just the size of a single pixel, but for blocked pixel +formats this value is different. +.SH SEE ALSO +.PP +al_lock_bitmap(3), al_lock_bitmap_region(3), al_unlock_bitmap(3), +ALLEGRO_PIXEL_FORMAT(3) diff --git a/allegro/docs/man/ALLEGRO_MEMORY_INTERFACE.3 b/allegro/docs/man/ALLEGRO_MEMORY_INTERFACE.3 new file mode 100644 index 00000000..df5ef56a --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MEMORY_INTERFACE.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MEMORY_INTERFACE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MEMORY_INTERFACE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_MEMORY_INTERFACE ALLEGRO_MEMORY_INTERFACE; +\f[R] +.fi +.SH DESCRIPTION +.PP +This structure has the following fields. +.IP +.nf +\f[C] +void *(*mi_malloc)(size_t n, int line, const char *file, const char *func); +void (*mi_free)(void *ptr, int line, const char *file, const char *func); +void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file, + const char *func); +void *(*mi_calloc)(size_t count, size_t n, int line, const char *file, + const char *func); +\f[R] +.fi +.SH SEE ALSO +.PP +al_set_memory_interface(3) diff --git a/allegro/docs/man/ALLEGRO_MENU.3 b/allegro/docs/man/ALLEGRO_MENU.3 new file mode 100644 index 00000000..edd78450 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MENU.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MENU" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MENU - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_MENU ALLEGRO_MENU; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque data type that represents a menu that contains menu items. +Each of the menu items may optionally include a sub-menu. diff --git a/allegro/docs/man/ALLEGRO_MENU_INFO.3 b/allegro/docs/man/ALLEGRO_MENU_INFO.3 new file mode 100644 index 00000000..7bbf57a0 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MENU_INFO.3 @@ -0,0 +1,70 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MENU_INFO" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MENU_INFO - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_MENU_INFO { +\f[R] +.fi +.SH DESCRIPTION +.PP +A structure that defines how to create a complete menu system. +For standard menu items, the following format is used: +.IP +.nf +\f[C] + { caption, id, flags, icon } +\f[R] +.fi +.PP +For special items, these macros are helpful: +.IP +.nf +\f[C] +ALLEGRO_START_OF_MENU(caption, id) +ALLEGRO_MENU_SEPARATOR +ALLEGRO_END_OF_MENU +\f[R] +.fi +.PP +A well-defined menu will begin with \f[C]ALLEGRO_START_OF_MENU\f[R], +contain one or more menu items, and end with +\f[C]ALLEGRO_END_OF_MENU\f[R]. +A menu may contain sub-menus. +An example: +.IP +.nf +\f[C] +ALLEGRO_MENU_INFO menu_info[] = { + ALLEGRO_START_OF_MENU(\[dq]&File\[dq], 1), + { \[dq]&Open\[dq], 2, 0, NULL }, + ALLEGRO_START_OF_MENU(\[dq]Open &Recent...\[dq], 3), + { \[dq]Recent 1\[dq], 4, 0, NULL }, + { \[dq]Recent 2\[dq], 5, 0, NULL }, + ALLEGRO_END_OF_MENU, + ALLEGRO_MENU_SEPARATOR, + { \[dq]E&xit\[dq], 6, 0, NULL }, + ALLEGRO_END_OF_MENU, + ALLEGRO_START_OF_MENU(\[dq]&Help\[dq], 7), + {\[dq]&About\[dq], 8, 0, NULL }, + ALLEGRO_END_OF_MENU, + ALLEGRO_END_OF_MENU +}; + +ALLEGRO_MENU *menu = al_build_menu(menu_info); +\f[R] +.fi +.PP +If you prefer, you can build the menu without the structure by using +al_create_menu(3) and al_insert_menu_item(3). +.SH SEE ALSO +.PP +al_build_menu(3) diff --git a/allegro/docs/man/ALLEGRO_MIXER.3 b/allegro/docs/man/ALLEGRO_MIXER.3 new file mode 100644 index 00000000..bcd225c7 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MIXER.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MIXER" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MIXER - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_MIXER ALLEGRO_MIXER; +\f[R] +.fi +.SH DESCRIPTION +.PP +A mixer mixes together attached streams into a single buffer. +In the process, it converts channel configurations, sample frequencies +and audio depths of the attached sample instances and audio streams +accordingly. +You can control the quality of this conversion using +ALLEGRO_MIXER_QUALITY. +.PP +When going from mono to stereo (and above), the mixer reduces the volume +of both channels by \f[C]sqrt(2)\f[R]. +When going from stereo (and above) to mono, the mixer reduces the volume +of the left and right channels by \f[C]sqrt(2)\f[R] before adding them +to the center channel (if present). diff --git a/allegro/docs/man/ALLEGRO_MIXER_QUALITY.3 b/allegro/docs/man/ALLEGRO_MIXER_QUALITY.3 new file mode 100644 index 00000000..7a47e353 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MIXER_QUALITY.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MIXER_QUALITY" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MIXER_QUALITY - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_MIXER_QUALITY +\f[R] +.fi +.SH DESCRIPTION +.IP \[bu] 2 +ALLEGRO_MIXER_QUALITY_POINT - point sampling +.IP \[bu] 2 +ALLEGRO_MIXER_QUALITY_LINEAR - linear interpolation +.IP \[bu] 2 +ALLEGRO_MIXER_QUALITY_CUBIC - cubic interpolation (since: 5.0.8, 5.1.4) diff --git a/allegro/docs/man/ALLEGRO_MONITOR_INFO.3 b/allegro/docs/man/ALLEGRO_MONITOR_INFO.3 new file mode 100644 index 00000000..44d78cd4 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MONITOR_INFO.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MONITOR_INFO" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MONITOR_INFO - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_MONITOR_INFO +\f[R] +.fi +.SH DESCRIPTION +.PP +Describes a monitor\[cq]s size and position relative to other monitors. +x1, y1 will be 0, 0 on the primary display. +Other monitors can have negative values if they are to the left or above +the primary display. +x2, y2 are the coordinates one beyond the bottom right pixel, so that +x2-x1 gives the width and y2-y1 gives the height of the display. +.IP +.nf +\f[C] +typedef struct ALLEGRO_MONITOR_INFO +{ + int x1; + int y1; + int x2; + int y2; +} ALLEGRO_MONITOR_INFO; +\f[R] +.fi +.SH SEE ALSO +.PP +al_get_monitor_info(3) diff --git a/allegro/docs/man/ALLEGRO_MOUSE_EMULATION_MODE.3 b/allegro/docs/man/ALLEGRO_MOUSE_EMULATION_MODE.3 new file mode 100644 index 00000000..5939cc17 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MOUSE_EMULATION_MODE.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MOUSE_EMULATION_MODE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MOUSE_EMULATION_MODE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_MOUSE_EMULATION_MODE +\f[R] +.fi +.SH DESCRIPTION +.PP +Type of mouse emulation to apply. +.TP +ALLEGRO_MOUSE_EMULATION_NONE +Disables mouse emulation. +.TP +ALLEGRO_MOUSE_EMULATION_TRANSPARENT +Enables transparent mouse emulation. +.TP +ALLEGRO_MOUSE_EMULATION_INCLUSIVE +Enable inclusive mouse emulation. +.TP +ALLEGRO_MOUSE_EMULATION_EXCLUSIVE +Enables exclusive mouse emulation. +.TP +ALLEGRO_MOUSE_EMULATION_5_0_x +Enables mouse emulation that is backwards compatible with Allegro 5.0.x. +.SH SINCE +.PP +5.1.0 +.RS +.PP +\f[I][Unstable API]:\f[R] Seems of limited value, as touch input tends +to have different semantics compared to mouse input. +.RE diff --git a/allegro/docs/man/ALLEGRO_MOUSE_STATE.3 b/allegro/docs/man/ALLEGRO_MOUSE_STATE.3 new file mode 100644 index 00000000..6701773b --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MOUSE_STATE.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MOUSE_STATE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MOUSE_STATE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_MOUSE_STATE ALLEGRO_MOUSE_STATE; +\f[R] +.fi +.SH DESCRIPTION +.PP +Public fields (read only): +.IP \[bu] 2 +x - mouse x position +.IP \[bu] 2 +y - mouse y position +.IP \[bu] 2 +w, z - mouse wheel position (2D `ball') +.IP \[bu] 2 +buttons - mouse buttons bitfield +.RS 2 +.PP +The zeroth bit is set if the primary mouse button is held down, the +first bit is set if the secondary mouse button is held down, and so on. +.RE +.IP \[bu] 2 +pressure - pressure, ranging from \f[C]0.0\f[R] to \f[C]1.0\f[R] +.SH SEE ALSO +.PP +al_get_mouse_state(3), al_get_mouse_state_axis(3), +al_mouse_button_down(3) diff --git a/allegro/docs/man/ALLEGRO_MSECS_TO_SECS.3 b/allegro/docs/man/ALLEGRO_MSECS_TO_SECS.3 new file mode 100644 index 00000000..60e61fe4 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MSECS_TO_SECS.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MSECS_TO_SECS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MSECS_TO_SECS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_MSECS_TO_SECS(x) ((x) / 1000.0) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert milliseconds to seconds. diff --git a/allegro/docs/man/ALLEGRO_MUTEX.3 b/allegro/docs/man/ALLEGRO_MUTEX.3 new file mode 100644 index 00000000..ef461973 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_MUTEX.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_MUTEX" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_MUTEX - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_MUTEX ALLEGRO_MUTEX; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque structure representing a mutex. diff --git a/allegro/docs/man/ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE.3 b/allegro/docs/man/ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE.3 new file mode 100644 index 00000000..15fa275b --- /dev/null +++ b/allegro/docs/man/ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE 255 +\f[R] +.fi +.SH DESCRIPTION +.PP +This is the maximum size of the title that can be set with +al_set_new_window_title(3). +.SH SEE ALSO +.PP +al_set_new_window_title(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/ALLEGRO_PI.3 b/allegro/docs/man/ALLEGRO_PI.3 new file mode 100644 index 00000000..876ce30d --- /dev/null +++ b/allegro/docs/man/ALLEGRO_PI.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_PI" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_PI - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_PI 3.14159265358979323846 +\f[R] +.fi +.SH DESCRIPTION +.PP +C99 compilers have no predefined value like M_PI for the constant \[*p], +but you can use this one instead. diff --git a/allegro/docs/man/ALLEGRO_PIXEL_FORMAT.3 b/allegro/docs/man/ALLEGRO_PIXEL_FORMAT.3 new file mode 100644 index 00000000..e7bfce38 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_PIXEL_FORMAT.3 @@ -0,0 +1,190 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_PIXEL_FORMAT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_PIXEL_FORMAT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_PIXEL_FORMAT +\f[R] +.fi +.SH DESCRIPTION +.PP +Pixel formats. +Each pixel format specifies the exact size and bit layout of a pixel in +memory. +Components are specified from high bits to low bits, so for example a +fully opaque red pixel in ARGB_8888 format is 0xFFFF0000. +.RS +.PP +\f[I]Note:\f[R] +.PP +The pixel format is independent of endianness. +That is, in the above example you can always get the red component with +.IP +.nf +\f[C] +(pixel & 0x00ff0000) >> 16 +\f[R] +.fi +.PP +But you can \f[I]not\f[R] rely on this code: +.IP +.nf +\f[C] +*(pixel + 2) +\f[R] +.fi +.PP +It will return the red component on little endian systems, but the green +component on big endian systems. +.RE +.PP +Also note that Allegro\[cq]s naming is different from OpenGL naming +here, where a format of GL_RGBA8 merely defines the component order and +the exact layout including endianness treatment is specified separately. +Usually GL_RGBA8 will correspond to ALLEGRO_PIXEL_ABGR_8888 though on +little endian systems, so care must be taken (note the reversal of RGBA +<-> ABGR). +.PP +The only exception to this ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which will +always have the components as 4 bytes corresponding to red, green, blue +and alpha, in this order, independent of the endianness. +.PP +Some of the pixel formats represent compressed bitmap formats. +Compressed bitmaps take up less space in the GPU memory than bitmaps +with regular (uncompressed) pixel formats. +This smaller footprint means that you can load more resources into GPU +memory, and they will be drawn somewhat faster. +The compression is lossy, however, so it is not appropriate for all +graphical styles: it tends to work best for images with smooth color +gradations. +It is possible to compress bitmaps at runtime by passing the appropriate +bitmap format in \f[C]al_set_new_bitmap_format\f[R] and then creating, +loading, cloning or converting a non-compressed bitmap. +This, however, is not recommended as the compression quality differs +between different GPU drivers. +It is recommended to compress these bitmaps ahead of time using external +tools and then load them compressed. +.PP +Unlike regular pixel formats, compressed pixel formats are not laid out +in memory one pixel row at a time. +Instead, the bitmap is subdivided into rectangular blocks of pixels that +are then laid out in block rows. +This means that regular locking functions cannot use compressed pixel +formats as the destination format. +Instead, you can use the blocked versions of the bitmap locking +functions which do support these formats. +.PP +It is not recommended to use compressed bitmaps as target bitmaps, as +that operation cannot be hardware accelerated. +Due to proprietary algorithms used, it is typically impossible to create +compressed memory bitmaps. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY - Let the driver choose a format. +This is the default format at program start. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA - Let the driver choose a format +without alpha. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA - Let the driver choose a format +with alpha. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA - Let the driver choose a 15 bit +format without alpha. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA - Let the driver choose a 16 bit +format without alpha. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA - Let the driver choose a 16 bit +format with alpha. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA - Let the driver choose a 24 bit +format without alpha. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA - Let the driver choose a 32 bit +format without alpha. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA - Let the driver choose a 32 bit +format with alpha. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ARGB_8888 - 32 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_RGBA_8888 - 32 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ARGB_4444 - 16 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_RGB_888 - 24 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_RGB_565 - 16 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_RGB_555 - 15 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_RGBA_5551 - 16 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ARGB_1555 - 16 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ABGR_8888 - 32 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_XBGR_8888 - 32 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_BGR_888 - 24 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_BGR_565 - 16 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_BGR_555 - 15 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_RGBX_8888 - 32 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_XRGB_8888 - 32 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ABGR_F32 - 128 bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE - Like the version without _LE, but +the component order is guaranteed to be red, green, blue, alpha. +This only makes a difference on big endian systems, on little endian it +is just an alias. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_RGBA_4444 - 16bit +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 - A single 8-bit channel. +A pixel value maps onto the red channel when displayed, but it is +undefined how it maps onto green, blue and alpha channels. +When drawing to bitmaps of this format, only the red channel is taken +into account. +Allegro may have to use fallback methods to render to bitmaps of this +format. +This pixel format is mainly intended for storing the color indices of an +indexed (paletted) image, usually in conjunction with a pixel shader +that maps indices to RGBA values. +Since 5.1.2. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1 - Compressed using the DXT1 +compression algorithm. +Each 4x4 pixel block is encoded in 64 bytes, resulting in 6-8x +compression ratio. +Only a single bit of alpha per pixel is supported. +Since 5.1.9. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3 - Compressed using the DXT3 +compression algorithm. +Each 4x4 pixel block is encoded in 128 bytes, resulting in 4x +compression ratio. +This format supports sharp alpha transitions. +Since 5.1.9. +.IP \[bu] 2 +ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5 - Compressed using the DXT5 +compression algorithm. +Each 4x4 pixel block is encoded in 128 bytes, resulting in 4x +compression ratio. +This format supports smooth alpha transitions. +Since 5.1.9. +.SH SEE ALSO +.PP +al_set_new_bitmap_format(3), al_get_bitmap_format(3) diff --git a/allegro/docs/man/ALLEGRO_PLAYMODE.3 b/allegro/docs/man/ALLEGRO_PLAYMODE.3 new file mode 100644 index 00000000..d7125b67 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_PLAYMODE.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_PLAYMODE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_PLAYMODE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_PLAYMODE +\f[R] +.fi +.SH DESCRIPTION +.PP +Sample and stream playback mode. +.IP \[bu] 2 +ALLEGRO_PLAYMODE_ONCE - the sample/stream is played from start to finish +an then it stops. +.IP \[bu] 2 +ALLEGRO_PLAYMODE_LOOP - the sample/stream is played from start to finish +(or between the two loop points). +When it reaches the end, it restarts from the beginning. +.IP \[bu] 2 +ALLEGRO_PLAYMODE_BIDIR - the sample is played from start to finish (or +between the two loop points). +When it reaches the end, it reverses the playback direction and plays +until it reaches the beginning when it reverses the direction back to +normal. +This is mode is rarely supported for streams. diff --git a/allegro/docs/man/ALLEGRO_PRIM_ATTR.3 b/allegro/docs/man/ALLEGRO_PRIM_ATTR.3 new file mode 100644 index 00000000..639637db --- /dev/null +++ b/allegro/docs/man/ALLEGRO_PRIM_ATTR.3 @@ -0,0 +1,89 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_PRIM_ATTR" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_PRIM_ATTR - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_PRIM_ATTR +\f[R] +.fi +.SH DESCRIPTION +.PP +Enumerates the types of vertex attributes that a custom vertex may have. +.IP \[bu] 2 +ALLEGRO_PRIM_POSITION - Position information, can be stored only in +ALLEGRO_PRIM_SHORT_2, ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_FLOAT_3. +.IP \[bu] 2 +ALLEGRO_PRIM_COLOR_ATTR - Color information, stored in an +ALLEGRO_COLOR(3). +The storage field of ALLEGRO_VERTEX_ELEMENT is ignored +.IP \[bu] 2 +ALLEGRO_PRIM_TEX_COORD - Texture coordinate information, can be stored +only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. +These coordinates are normalized by the width and height of the texture, +meaning that the bottom-right corner has texture coordinates of (1, 1). +.IP \[bu] 2 +ALLEGRO_PRIM_TEX_COORD_PIXEL - Texture coordinate information, can be +stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. +These coordinates are measured in pixels. +.IP \[bu] 2 +ALLEGRO_PRIM_USER_ATTR - A user specified attribute. +You can use any storage for this attribute. +You may have at most ALLEGRO_PRIM_MAX_USER_ATTR (currently 10) of these +that you can specify by adding an index to the value of +ALLEGRO_PRIM_USER_ATTR, e.g.\ the first user attribute is +\f[C]ALLEGRO_PRIM_USER_ATTR + 0\f[R], the second is +\f[C]ALLEGRO_PRIM_USER_ATTR + 1\f[R] and so on. +.RS 2 +.PP +To access these custom attributes from GLSL shaders you need to declare +attributes that follow this nomenclature: \f[C]al_user_attr_#\f[R] where +# is the index of the attribute. +.PP +For example to have a position and a normal vector for each vertex you +could declare it like this: +.IP +.nf +\f[C] +ALLEGRO_VERTEX_ELEMENT elements[3] = { + {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, 0}, + {ALLEGRO_PRIM_USER_ATTR + 0, ALLEGRO_PRIM_FLOAT_3, 12}, + {0, 0, 0}}; +\f[R] +.fi +.PP +And then in your vertex shader access it like this: +.IP +.nf +\f[C] +attribute vec3 al_pos; // ALLEGRO_PRIM_POSITION +attribute vec3 al_user_attr_0; // ALLEGRO_PRIM_USER_ATTR + 0 +varying float light; +const vec3 light_direction = vec3(0, 0, 1); +void main() { + light = dot(al_user_attr_0, light_direction); + gl_Position = al_pos; +} +\f[R] +.fi +.PP +To access these custom attributes from HLSL you need to declare a +parameter with the following semantics: \f[C]TEXCOORD{# + 2}\f[R] where +# is the index of the attribute. +E.g. +the first attribute can be accessed via \f[C]TEXCOORD2\f[R], second via +\f[C]TEXCOORD3\f[R] and so on. +.PP +Since: 5.1.6 +.RE +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_DECL(3), ALLEGRO_PRIM_STORAGE(3), +al_attach_shader_source(3) diff --git a/allegro/docs/man/ALLEGRO_PRIM_BUFFER_FLAGS.3 b/allegro/docs/man/ALLEGRO_PRIM_BUFFER_FLAGS.3 new file mode 100644 index 00000000..24fd67a7 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_PRIM_BUFFER_FLAGS.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_PRIM_BUFFER_FLAGS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_PRIM_BUFFER_FLAGS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_PRIM_BUFFER_FLAGS +\f[R] +.fi +.SH DESCRIPTION +.PP +Flags to specify how to create a vertex or an index buffer. +.IP \[bu] 2 +ALLEGRO_PRIM_BUFFER_STREAM - Hints to the driver that the buffer is +written to often, but used only a few times per frame +.IP \[bu] 2 +ALLEGRO_PRIM_BUFFER_STATIC - Hints to the driver that the buffer is +written to once and is used often +.IP \[bu] 2 +ALLEGRO_PRIM_BUFFER_DYNAMIC - Hints to the driver that the buffer is +written to often and is used often +.IP \[bu] 2 +ALLEGRO_PRIM_BUFFER_READWRITE - Specifies that you want to be able read +from this buffer. +By default this is disabled for performance. +Some platforms (like OpenGL ES) do not support reading from vertex +buffers, so if you pass this flag to \f[C]al_create_vertex_buffer\f[R] +or \f[C]al_create_index_buffer\f[R] the call will fail. +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +al_create_vertex_buffer(3), al_create_index_buffer(3) diff --git a/allegro/docs/man/ALLEGRO_PRIM_QUALITY.3 b/allegro/docs/man/ALLEGRO_PRIM_QUALITY.3 new file mode 100644 index 00000000..bfd788d7 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_PRIM_QUALITY.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_PRIM_QUALITY" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_PRIM_QUALITY - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_PRIM_QUALITY 10 +\f[R] +.fi +.SH DESCRIPTION +.PP +Controls the quality of the approximation of curved primitives +(e.g.\ circles). +Curved primitives are drawn by approximating them with a sequence of +line segments. +By default, this roughly corresponds to error of less than half of a +pixel. diff --git a/allegro/docs/man/ALLEGRO_PRIM_STORAGE.3 b/allegro/docs/man/ALLEGRO_PRIM_STORAGE.3 new file mode 100644 index 00000000..501041dc --- /dev/null +++ b/allegro/docs/man/ALLEGRO_PRIM_STORAGE.3 @@ -0,0 +1,120 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_PRIM_STORAGE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_PRIM_STORAGE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_PRIM_STORAGE +\f[R] +.fi +.SH DESCRIPTION +.PP +Enumerates the types of storage an attribute of a custom vertex may be +stored in. +Many of these can only be used for ALLEGRO_PRIM_USER_ATTR attributes and +can only be accessed via shaders. +Usually no matter what the storage is specified the attribute gets +converted to single precision floating point when the shader is run. +Despite that, it may be advantageous to use more dense storage formats +(e.g.\ ALLEGRO_PRIM_NORMALIZED_UBYTE_4 instead of ALLEGRO_PRIM_FLOAT_4) +when bandwidth (amount of memory sent to the GPU) is an issue but +precision is not. +.IP \[bu] 2 +ALLEGRO_PRIM_FLOAT_1 - A single float +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_FLOAT_2 - A doublet of floats +.IP \[bu] 2 +ALLEGRO_PRIM_FLOAT_3 - A triplet of floats +.IP \[bu] 2 +ALLEGRO_PRIM_FLOAT_4 - A quad of floats +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_SHORT_2 - A doublet of shorts +.IP \[bu] 2 +ALLEGRO_PRIM_SHORT_4 - A quad of shorts +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_UBYTE_4 - A quad of unsigned bytes +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_NORMALIZED_SHORT_2 - A doublet of shorts. +Before being sent to the shader, each component is divided by 32767. +Each component of the resultant float doublet ranges between -1.0 and +1.0 +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_NORMALIZED_SHORT_4 - A quad of shorts. +Before being sent to the shader, each component is divided by 32767. +Each component of the resultant float quad ranges between -1.0 and 1.0 +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_NORMALIZED_UBYTE_4 - A quad of unsigned bytes. +Before being sent to the shader, each component is divided by 255. +Each component of the resultant float quad ranges between 0.0 and 1.0 +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_NORMALIZED_USHORT_2 - A doublet of unsigned shorts. +Before being sent to the shader, each component is divided by 65535. +Each component of the resultant float doublet ranges between 0.0 and 1.0 +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_NORMALIZED_USHORT_4 - A quad of unsigned shorts. +Before being sent to the shader, each component is divided by 65535. +Each component of the resultant float quad ranges between 0.0 and 1.0 +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_HALF_FLOAT_2 - A doublet of half-precision floats. +Note that this storage format is not supported on all platforms. +al_create_vertex_decl(3) will return NULL if you use it on those +platforms +.RS 2 +.PP +Since: 5.1.6 +.RE +.IP \[bu] 2 +ALLEGRO_PRIM_HALF_FLOAT_4 - A quad of half-precision floats. +Note that this storage format is not supported on all platforms. +al_create_vertex_decl(3) will return NULL if you use it on those +platforms. +.RS 2 +.PP +Since: 5.1.6 +.RE +.SH SEE ALSO +.PP +ALLEGRO_PRIM_ATTR(3) diff --git a/allegro/docs/man/ALLEGRO_PRIM_TYPE.3 b/allegro/docs/man/ALLEGRO_PRIM_TYPE.3 new file mode 100644 index 00000000..19ae1a49 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_PRIM_TYPE.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_PRIM_TYPE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_PRIM_TYPE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_PRIM_TYPE +\f[R] +.fi +.SH DESCRIPTION +.PP +Enumerates the types of primitives this addon can draw. +.IP \[bu] 2 +ALLEGRO_PRIM_POINT_LIST - A list of points, each vertex defines a point +.IP \[bu] 2 +ALLEGRO_PRIM_LINE_LIST - A list of lines, sequential pairs of vertices +define disjointed lines +.IP \[bu] 2 +ALLEGRO_PRIM_LINE_STRIP - A strip of lines, sequential vertices define a +strip of lines +.IP \[bu] 2 +ALLEGRO_PRIM_LINE_LOOP - Like a line strip, except at the end the first +and the last vertices are also connected by a line +.IP \[bu] 2 +ALLEGRO_PRIM_TRIANGLE_LIST - A list of triangles, sequential triplets of +vertices define disjointed triangles +.IP \[bu] 2 +ALLEGRO_PRIM_TRIANGLE_STRIP - A strip of triangles, sequential vertices +define a strip of triangles +.IP \[bu] 2 +ALLEGRO_PRIM_TRIANGLE_FAN - A fan of triangles, all triangles share the +first vertex diff --git a/allegro/docs/man/ALLEGRO_RENDER_FUNCTION.3 b/allegro/docs/man/ALLEGRO_RENDER_FUNCTION.3 new file mode 100644 index 00000000..3edc743b --- /dev/null +++ b/allegro/docs/man/ALLEGRO_RENDER_FUNCTION.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_RENDER_FUNCTION" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_RENDER_FUNCTION - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_RENDER_FUNCTION { +\f[R] +.fi +.SH DESCRIPTION +.PP +Possible functions are: +.IP \[bu] 2 +ALLEGRO_RENDER_NEVER +.IP \[bu] 2 +ALLEGRO_RENDER_ALWAYS +.IP \[bu] 2 +ALLEGRO_RENDER_LESS +.IP \[bu] 2 +ALLEGRO_RENDER_EQUAL +.IP \[bu] 2 +ALLEGRO_RENDER_LESS_EQUAL +.PD 0 +.P +.PD +.IP \[bu] 2 +ALLEGRO_RENDER_GREATER +.PD 0 +.P +.PD +.IP \[bu] 2 +ALLEGRO_RENDER_NOT_EQUAL +.IP \[bu] 2 +ALLEGRO_RENDER_GREATER_EQUAL +.SH SINCE +.PP +5.1.2 +.SH SEE ALSO +.PP +al_set_render_state(3) diff --git a/allegro/docs/man/ALLEGRO_RENDER_STATE.3 b/allegro/docs/man/ALLEGRO_RENDER_STATE.3 new file mode 100644 index 00000000..50c2286f --- /dev/null +++ b/allegro/docs/man/ALLEGRO_RENDER_STATE.3 @@ -0,0 +1,62 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_RENDER_STATE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_RENDER_STATE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_RENDER_STATE { +\f[R] +.fi +.SH DESCRIPTION +.PP +Possible render states which can be set with al_set_render_state(3): +.TP +ALLEGRO_ALPHA_TEST +If this is set to 1, the values of ALLEGRO_ALPHA_FUNCTION and +ALLEGRO_ALPHA_TEST_VALUE define a comparison function which is performed +on the alpha component of each pixel. +Only if it evaluates to true the pixel is written. +Otherwise no subsequent processing (like depth test or blending) is +performed. +This can be very useful, for example if a depth buffer is used but you +do not want fully transparent pixels to modify it. +.TP +ALLEGRO_ALPHA_FUNCTION +One of ALLEGRO_RENDER_FUNCTION(3), only used when ALLEGRO_ALPHA_TEST is +1. +.TP +ALLEGRO_ALPHA_TEST_VALUE +Only used when ALLEGRO_ALPHA_TEST is 1. +Should be a value of 0 - 255. +.TP +ALLEGRO_WRITE_MASK +This determines how the framebuffer and depthbuffer are updated whenever +a pixel is written (in case alpha and/or depth testing is enabled: after +all such enabled tests succeed). +Depth values are only written if ALLEGRO_DEPTH_TEST is 1, in addition to +the write mask flag being set. +.TP +ALLEGRO_DEPTH_TEST +If this is set to 1, compare the depth value of any newly written pixels +with the depth value already in the buffer, according to +ALLEGRO_DEPTH_FUNCTION. +Allegro primitives with no explicit z coordinate will write a value of 0 +into the depth buffer. +.TP +ALLEGRO_DEPTH_FUNCTION +One of ALLEGRO_RENDER_FUNCTION(3), only used when ALLEGRO_DEPTH_TEST is +1. +.SH SINCE +.PP +5.1.2 +.SH SEE ALSO +.PP +al_set_render_state(3), ALLEGRO_RENDER_FUNCTION(3), +ALLEGRO_WRITE_MASK_FLAGS(3) diff --git a/allegro/docs/man/ALLEGRO_SAMPLE.3 b/allegro/docs/man/ALLEGRO_SAMPLE.3 new file mode 100644 index 00000000..7d610fd4 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_SAMPLE.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_SAMPLE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_SAMPLE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_SAMPLE ALLEGRO_SAMPLE; +\f[R] +.fi +.SH DESCRIPTION +.PP +An ALLEGRO_SAMPLE object stores the data necessary for playing +pre-defined digital audio. +It holds a user-specified PCM data buffer and information about its +format (data length, depth, frequency, channel configuration). +You can have the same ALLEGRO_SAMPLE playing multiple times +simultaneously. +.SH SEE ALSO +.PP +ALLEGRO_SAMPLE_INSTANCE(3) diff --git a/allegro/docs/man/ALLEGRO_SAMPLE_ID.3 b/allegro/docs/man/ALLEGRO_SAMPLE_ID.3 new file mode 100644 index 00000000..6d3075da --- /dev/null +++ b/allegro/docs/man/ALLEGRO_SAMPLE_ID.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_SAMPLE_ID" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_SAMPLE_ID - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_SAMPLE_ID ALLEGRO_SAMPLE_ID; +\f[R] +.fi +.SH DESCRIPTION +.PP +An ALLEGRO_SAMPLE_ID represents a sample being played via +al_play_sample(3). +It can be used to later stop the sample with al_stop_sample(3). +The underlying ALLEGRO_SAMPLE_INSTANCE can be extracted using +al_lock_sample_id(3). diff --git a/allegro/docs/man/ALLEGRO_SAMPLE_INSTANCE.3 b/allegro/docs/man/ALLEGRO_SAMPLE_INSTANCE.3 new file mode 100644 index 00000000..bf816961 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_SAMPLE_INSTANCE.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_SAMPLE_INSTANCE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_SAMPLE_INSTANCE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_SAMPLE_INSTANCE ALLEGRO_SAMPLE_INSTANCE; +\f[R] +.fi +.SH DESCRIPTION +.PP +An ALLEGRO_SAMPLE_INSTANCE object represents a playable instance of a +predefined sound effect. +It holds information about how the effect should be played: These +playback parameters consist of the looping mode, loop start/end points, +playing position, speed, gain, pan and the playmode. +Whether a sample instance is currently playing or paused is also one of +its properties. +.PP +An instance uses the data from an ALLEGRO_SAMPLE(3) object. +Multiple instances may be created from the same ALLEGRO_SAMPLE. +An ALLEGRO_SAMPLE must not be destroyed while there are instances which +reference it. +.PP +To actually produce audio output, an ALLEGRO_SAMPLE_INSTANCE must be +attached to an ALLEGRO_MIXER(3) which eventually reaches an +ALLEGRO_VOICE(3) object. +.SH SEE ALSO +.PP +ALLEGRO_SAMPLE(3) diff --git a/allegro/docs/man/ALLEGRO_SEEK.3 b/allegro/docs/man/ALLEGRO_SEEK.3 new file mode 100644 index 00000000..5ed4319b --- /dev/null +++ b/allegro/docs/man/ALLEGRO_SEEK.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_SEEK" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_SEEK - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_SEEK +\f[R] +.fi +.SH DESCRIPTION +.IP \[bu] 2 +ALLEGRO_SEEK_SET - seek relative to beginning of file +.IP \[bu] 2 +ALLEGRO_SEEK_CUR - seek relative to current file position +.IP \[bu] 2 +ALLEGRO_SEEK_END - seek relative to end of file +.SH SEE ALSO +.PP +al_fseek(3) diff --git a/allegro/docs/man/ALLEGRO_SHADER.3 b/allegro/docs/man/ALLEGRO_SHADER.3 new file mode 100644 index 00000000..9608e586 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_SHADER.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_SHADER" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_SHADER - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_SHADER ALLEGRO_SHADER; +\f[R] +.fi +.SH DESCRIPTION +.PP +An ALLEGRO_SHADER(3) is a program that runs on the GPU. +It combines both a vertex and a pixel shader. +(In OpenGL terms, an ALLEGRO_SHADER(3) is actually a \f[I]program\f[R] +which has one or more \f[I]shaders\f[R] attached. +This can be confusing.) +.PP +The source code for the underlying vertex or pixel shader can be +provided either as GLSL or HLSL, depending on the value of +ALLEGRO_SHADER_PLATFORM(3) used when creating it. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/ALLEGRO_SHADER_PLATFORM.3 b/allegro/docs/man/ALLEGRO_SHADER_PLATFORM.3 new file mode 100644 index 00000000..a793cdb5 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_SHADER_PLATFORM.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_SHADER_PLATFORM" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_SHADER_PLATFORM - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_SHADER_PLATFORM ALLEGRO_SHADER_PLATFORM; +\f[R] +.fi +.SH DESCRIPTION +.PP +The underlying platform which the ALLEGRO_SHADER(3) is built on top of, +which dictates the language used to program the shader. +.IP \[bu] 2 +ALLEGRO_SHADER_AUTO +.IP \[bu] 2 +ALLEGRO_SHADER_GLSL - OpenGL Shading Language +.IP \[bu] 2 +ALLEGRO_SHADER_HLSL - High Level Shader Language (for Direct3D) +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/ALLEGRO_SHADER_TYPE.3 b/allegro/docs/man/ALLEGRO_SHADER_TYPE.3 new file mode 100644 index 00000000..a2b362da --- /dev/null +++ b/allegro/docs/man/ALLEGRO_SHADER_TYPE.3 @@ -0,0 +1,49 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_SHADER_TYPE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_SHADER_TYPE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_SHADER_TYPE ALLEGRO_SHADER_TYPE; +\f[R] +.fi +.SH DESCRIPTION +.PP +Used with al_attach_shader_source(3) and al_attach_shader_source_file(3) +to specify how to interpret the attached source. +.TP +ALLEGRO_VERTEX_SHADER +A vertex shader is executed for each vertex it is used with. +The program will output exactly one vertex at a time. +.RS +.PP +When Allegro\[cq]s graphics are being used then in addition to all +vertices of primitives from the primitives addon, each drawn bitmap also +consists of four vertices. +.RE +.TP +ALLEGRO_PIXEL_SHADER +A pixel shader is executed for each pixel it is used with. +The program will output exactly one pixel at a time - either in the +backbuffer or in the current target bitmap. +.RS +.PP +With Allegro\[cq]s builtin graphics this means the shader is for example +called for each destination pixel of the output of an al_draw_bitmap(3) +call. +.PP +A more accurate term for pixel shader would be fragment shader since one +final pixel in the target bitmap is not necessarily composed of only a +single output but of multiple fragments (for example when multi-sampling +is being used). +.RE +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/ALLEGRO_STATE.3 b/allegro/docs/man/ALLEGRO_STATE.3 new file mode 100644 index 00000000..a5e20f0e --- /dev/null +++ b/allegro/docs/man/ALLEGRO_STATE.3 @@ -0,0 +1,50 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_STATE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_STATE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] + +typedef struct ALLEGRO_STATE ALLEGRO_STATE; +\f[R] +.fi +.SH DESCRIPTION +.PP +Opaque type which is passed to al_store_state(3)/al_restore_state(3). +.PP +The various state kept internally by Allegro can be displayed like this: +.IP +.nf +\f[C] + global + active system driver + current config + per thread + new bitmap params + new display params + active file interface + errno + current blending mode + current display + deferred drawing + current target bitmap + current transformation + current projection transformation + current clipping rectangle + bitmap locking + current shader +\f[R] +.fi +.PP +In general, the only real global state is the active system driver. +All other global state is per-thread, so if your application has +multiple separate threads they never will interfere with each other. +(Except if there are objects accessed by multiple threads of course. +Usually you want to minimize that though and for the remaining cases use +synchronization primitives described in the threads section or events +described in the events section to control inter-thread communication.) diff --git a/allegro/docs/man/ALLEGRO_STATE_FLAGS.3 b/allegro/docs/man/ALLEGRO_STATE_FLAGS.3 new file mode 100644 index 00000000..fac313ed --- /dev/null +++ b/allegro/docs/man/ALLEGRO_STATE_FLAGS.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_STATE_FLAGS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_STATE_FLAGS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] + +typedef enum ALLEGRO_STATE_FLAGS +\f[R] +.fi +.SH DESCRIPTION +.PP +Flags which can be passed to al_store_state(3)/al_restore_state(3) as +bit combinations. +See al_store_state(3) for the list of flags. diff --git a/allegro/docs/man/ALLEGRO_SYSTEM_ID.3 b/allegro/docs/man/ALLEGRO_SYSTEM_ID.3 new file mode 100644 index 00000000..241a4afe --- /dev/null +++ b/allegro/docs/man/ALLEGRO_SYSTEM_ID.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_SYSTEM_ID" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_SYSTEM_ID - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_SYSTEM_ID { +\f[R] +.fi +.SH DESCRIPTION +.PP +The system Allegro is running on. +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_UNKNOWN - Unknown system. +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_XGLX - Xglx +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_WINDOWS - Windows +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_MACOSX - macOS +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_ANDROID - Android +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_IPHONE - iOS +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_GP2XWIZ - GP2XWIZ +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_RASPBERRYPI - Raspberry Pi +.IP \[bu] 2 +ALLEGRO_SYSTEM_ID_SDL - SDL +.SH SINCE +.PP +5.2.5 +.SH SEE ALSO +.PP +al_get_system_id(3) diff --git a/allegro/docs/man/ALLEGRO_TEXTLOG.3 b/allegro/docs/man/ALLEGRO_TEXTLOG.3 new file mode 100644 index 00000000..db4ef6a4 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_TEXTLOG.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_TEXTLOG" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_TEXTLOG - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_TEXTLOG ALLEGRO_TEXTLOG; +\f[R] +.fi +.SH DESCRIPTION +.PP +Opaque handle to a text log window. diff --git a/allegro/docs/man/ALLEGRO_THREAD.3 b/allegro/docs/man/ALLEGRO_THREAD.3 new file mode 100644 index 00000000..99a790be --- /dev/null +++ b/allegro/docs/man/ALLEGRO_THREAD.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_THREAD" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_THREAD - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_THREAD ALLEGRO_THREAD; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque structure representing a thread. diff --git a/allegro/docs/man/ALLEGRO_TIMEOUT.3 b/allegro/docs/man/ALLEGRO_TIMEOUT.3 new file mode 100644 index 00000000..c8282a99 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_TIMEOUT.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_TIMEOUT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_TIMEOUT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_TIMEOUT ALLEGRO_TIMEOUT; +\f[R] +.fi +.SH DESCRIPTION +.PP +Represent a timeout value. +The size of the structure is known so it can be statically allocated. +The contents are private. +.SH SEE ALSO +.PP +al_init_timeout(3) diff --git a/allegro/docs/man/ALLEGRO_TIMER.3 b/allegro/docs/man/ALLEGRO_TIMER.3 new file mode 100644 index 00000000..fbea74c8 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_TIMER.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_TIMER" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_TIMER - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_TIMER ALLEGRO_TIMER; +\f[R] +.fi +.SH DESCRIPTION +.PP +This is an abstract data type representing a timer object. diff --git a/allegro/docs/man/ALLEGRO_TOUCH_INPUT.3 b/allegro/docs/man/ALLEGRO_TOUCH_INPUT.3 new file mode 100644 index 00000000..31341260 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_TOUCH_INPUT.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_TOUCH_INPUT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_TOUCH_INPUT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_TOUCH_INPUT ALLEGRO_TOUCH_INPUT; +\f[R] +.fi +.SH DESCRIPTION +.PP +An abstract data type representing a physical touch screen or touch pad. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT.3 b/allegro/docs/man/ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT.3 new file mode 100644 index 00000000..85f279cd --- /dev/null +++ b/allegro/docs/man/ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT 16 +\f[R] +.fi +.SH DESCRIPTION +.PP +The maximum amount of simultaneous touches that can be detected. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/ALLEGRO_TOUCH_INPUT_STATE.3 b/allegro/docs/man/ALLEGRO_TOUCH_INPUT_STATE.3 new file mode 100644 index 00000000..75458a6b --- /dev/null +++ b/allegro/docs/man/ALLEGRO_TOUCH_INPUT_STATE.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_TOUCH_INPUT_STATE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_TOUCH_INPUT_STATE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_TOUCH_INPUT_STATE ALLEGRO_TOUCH_INPUT_STATE; +\f[R] +.fi +.SH DESCRIPTION +.PP +This is a structure that holds a snapshot of all simultaneous touches at +a particular instant. +.PP +Public fields (read only): +.IP \[bu] 2 +touches - an array of ALLEGRO_TOUCH_STATE(3) +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/ALLEGRO_TOUCH_STATE.3 b/allegro/docs/man/ALLEGRO_TOUCH_STATE.3 new file mode 100644 index 00000000..8872a848 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_TOUCH_STATE.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_TOUCH_STATE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_TOUCH_STATE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_TOUCH_STATE ALLEGRO_TOUCH_STATE; +\f[R] +.fi +.SH DESCRIPTION +.PP +This is a structure that is used to hold a \[lq]snapshot\[rq] of a touch +at a particular instant. +.PP +Public fields (read only): +.IP \[bu] 2 +id - identifier of the touch. +If the touch is valid, this is positive. +.IP \[bu] 2 +x - touch x position +.IP \[bu] 2 +y - touch y position +.IP \[bu] 2 +dx - touch relative x position +.IP \[bu] 2 +dy - touch relative y position +.IP \[bu] 2 +primary - TRUE if this touch is the primary one (usually the first one). +.IP \[bu] 2 +display - The ALLEGRO_DISPLAY(3) that was touched. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/ALLEGRO_TRANSFORM.3 b/allegro/docs/man/ALLEGRO_TRANSFORM.3 new file mode 100644 index 00000000..80f92f42 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_TRANSFORM.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_TRANSFORM" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_TRANSFORM - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_TRANSFORM ALLEGRO_TRANSFORM; +\f[R] +.fi +.SH DESCRIPTION +.PP +Defines the generic transformation type, a 4x4 matrix. +2D transforms use only a small subsection of this matrix, namely the top +left 2x2 matrix, and the right most 2x1 matrix, for a total of 6 values. +.PP +\f[I]Fields:\f[R] +.IP \[bu] 2 +m - A 4x4 float matrix diff --git a/allegro/docs/man/ALLEGRO_USECS_TO_SECS.3 b/allegro/docs/man/ALLEGRO_USECS_TO_SECS.3 new file mode 100644 index 00000000..2ea4d178 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_USECS_TO_SECS.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_USECS_TO_SECS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_USECS_TO_SECS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_USECS_TO_SECS(x) ((x) / 1000000.0) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert microseconds to seconds. diff --git a/allegro/docs/man/ALLEGRO_USER_EVENT.3 b/allegro/docs/man/ALLEGRO_USER_EVENT.3 new file mode 100644 index 00000000..72555143 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_USER_EVENT.3 @@ -0,0 +1,71 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_USER_EVENT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_USER_EVENT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_USER_EVENT ALLEGRO_USER_EVENT; +\f[R] +.fi +.SH DESCRIPTION +.PP +An event structure that can be emitted by user event sources. +These are the public fields: +.IP \[bu] 2 +ALLEGRO_EVENT_SOURCE *source; +.IP \[bu] 2 +intptr_t data1; +.IP \[bu] 2 +intptr_t data2; +.IP \[bu] 2 +intptr_t data3; +.IP \[bu] 2 +intptr_t data4; +.PP +Like all other event types this structure is a part of the ALLEGRO_EVENT +union. +To access the fields in an ALLEGRO_EVENT variable \f[C]ev\f[R], you +would use: +.IP \[bu] 2 +ev.user.source +.IP \[bu] 2 +ev.user.data1 +.IP \[bu] 2 +ev.user.data2 +.IP \[bu] 2 +ev.user.data3 +.IP \[bu] 2 +ev.user.data4 +.PP +To create a new user event you would do this: +.IP +.nf +\f[C] +ALLEGRO_EVENT_SOURCE my_event_source; +ALLEGRO_EVENT my_event; +float some_var; + +al_init_user_event_source(&my_event_source); + +my_event.user.type = ALLEGRO_GET_EVENT_TYPE(\[aq]M\[aq],\[aq]I\[aq],\[aq]N\[aq],\[aq]E\[aq]); +my_event.user.data1 = 1; +my_event.user.data2 = &some_var; + +al_emit_user_event(&my_event_source, &my_event, NULL); +\f[R] +.fi +.PP +Event type identifiers for user events are assigned by the user. +Please see the documentation for ALLEGRO_GET_EVENT_TYPE(3) for the rules +you should follow when assigning identifiers. +.SH SEE ALSO +.PP +al_emit_user_event(3), ALLEGRO_GET_EVENT_TYPE(3), +al_init_user_event_source(3) diff --git a/allegro/docs/man/ALLEGRO_USTR.3 b/allegro/docs/man/ALLEGRO_USTR.3 new file mode 100644 index 00000000..4c75cbda --- /dev/null +++ b/allegro/docs/man/ALLEGRO_USTR.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_USTR" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_USTR - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct _al_tagbstring ALLEGRO_USTR; +\f[R] +.fi +.SH DESCRIPTION +.PP +An opaque type representing a string. +ALLEGRO_USTRs normally contain UTF-8 encoded strings, but they may be +used to hold any byte sequences, including NULs. diff --git a/allegro/docs/man/ALLEGRO_USTR_INFO.3 b/allegro/docs/man/ALLEGRO_USTR_INFO.3 new file mode 100644 index 00000000..08603d80 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_USTR_INFO.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_USTR_INFO" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_USTR_INFO - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct _al_tagbstring ALLEGRO_USTR_INFO; +\f[R] +.fi +.SH DESCRIPTION +.PP +A type that holds additional information for an ALLEGRO_USTR(3) that +references an external memory buffer. +.SH SEE ALSO +.PP +al_ref_cstr(3), al_ref_buffer(3) and al_ref_ustr(3). diff --git a/allegro/docs/man/ALLEGRO_VERTEX.3 b/allegro/docs/man/ALLEGRO_VERTEX.3 new file mode 100644 index 00000000..2c3ace88 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_VERTEX.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_VERTEX" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_VERTEX - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX; +\f[R] +.fi +.SH DESCRIPTION +.PP +Defines the generic vertex type, with a 3D position, color and texture +coordinates for a single texture. +Note that at this time, the software driver for this addon cannot render +3D primitives. +If you want a 2D only primitive, set z to 0. +Note that you must initialize all members of this struct when you\[cq]re +using it. +One exception to this rule are the u and v variables which can be left +uninitialized when you are not using textures. +.PP +\f[I]Fields:\f[R] +.IP \[bu] 2 +x, y, z - Position of the vertex (float) +.IP \[bu] 2 +u, v - Texture coordinates measured in pixels (float) +.IP \[bu] 2 +color - ALLEGRO_COLOR(3) structure, storing the color of the vertex +.SH SEE ALSO +.PP +ALLEGRO_PRIM_ATTR(3) diff --git a/allegro/docs/man/ALLEGRO_VERTEX_BUFFER.3 b/allegro/docs/man/ALLEGRO_VERTEX_BUFFER.3 new file mode 100644 index 00000000..98a29c1d --- /dev/null +++ b/allegro/docs/man/ALLEGRO_VERTEX_BUFFER.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_VERTEX_BUFFER" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_VERTEX_BUFFER - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_VERTEX_BUFFER ALLEGRO_VERTEX_BUFFER; +\f[R] +.fi +.SH DESCRIPTION +.PP +A GPU vertex buffer that you can use to store vertices on the GPU +instead of uploading them afresh during every drawing operation. +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +al_create_vertex_buffer(3), al_destroy_vertex_buffer(3) diff --git a/allegro/docs/man/ALLEGRO_VERTEX_CACHE_SIZE.3 b/allegro/docs/man/ALLEGRO_VERTEX_CACHE_SIZE.3 new file mode 100644 index 00000000..3266de05 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_VERTEX_CACHE_SIZE.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_VERTEX_CACHE_SIZE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_VERTEX_CACHE_SIZE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define ALLEGRO_VERTEX_CACHE_SIZE 256 +\f[R] +.fi +.SH DESCRIPTION +.PP +Defines the size of the transformation vertex cache for the software +renderer. +If you pass less than this many vertices to the primitive rendering +functions you will get a speed boost. +This also defines the size of the cache vertex buffer, used for the +high-level primitives. +This corresponds to the maximum number of line segments that will be +used to form them. diff --git a/allegro/docs/man/ALLEGRO_VERTEX_DECL.3 b/allegro/docs/man/ALLEGRO_VERTEX_DECL.3 new file mode 100644 index 00000000..1f87a07f --- /dev/null +++ b/allegro/docs/man/ALLEGRO_VERTEX_DECL.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_VERTEX_DECL" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_VERTEX_DECL - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_VERTEX_DECL ALLEGRO_VERTEX_DECL; +\f[R] +.fi +.SH DESCRIPTION +.PP +A vertex declaration. +This opaque structure is responsible for describing the format and +layout of a user defined custom vertex. +It is created and destroyed by specialized functions. +.SH SEE ALSO +.PP +al_create_vertex_decl(3), al_destroy_vertex_decl(3), +ALLEGRO_VERTEX_ELEMENT(3) diff --git a/allegro/docs/man/ALLEGRO_VERTEX_ELEMENT.3 b/allegro/docs/man/ALLEGRO_VERTEX_ELEMENT.3 new file mode 100644 index 00000000..34d5f3bd --- /dev/null +++ b/allegro/docs/man/ALLEGRO_VERTEX_ELEMENT.3 @@ -0,0 +1,60 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_VERTEX_ELEMENT" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_VERTEX_ELEMENT - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_VERTEX_ELEMENT ALLEGRO_VERTEX_ELEMENT; +\f[R] +.fi +.SH DESCRIPTION +.PP +A small structure describing a certain element of a vertex. +E.g. +the position of the vertex, or its color. +These structures are used by the al_create_vertex_decl(3) function to +create the vertex declaration. +For that they generally occur in an array. +The last element of such an array should have the attribute field equal +to 0, to signify that it is the end of the array. +Here is an example code that would create a declaration describing the +ALLEGRO_VERTEX(3) structure (passing this as vertex declaration to +al_draw_prim would be identical to passing NULL): +.IP +.nf +\f[C] +/* On compilers without the offsetof keyword you need to obtain the + * offset with sizeof and make sure to account for packing. + */ +ALLEGRO_VERTEX_ELEMENT elems[] = { + {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX, x)}, + {ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_FLOAT_2, offsetof(ALLEGRO_VERTEX, u)}, + {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ALLEGRO_VERTEX, color)}, + {0, 0, 0} +}; +ALLEGRO_VERTEX_DECL* decl = al_create_vertex_decl(elems, sizeof(ALLEGRO_VERTEX)); +\f[R] +.fi +.PP +\f[I]Fields:\f[R] +.IP \[bu] 2 +attribute - A member of the ALLEGRO_PRIM_ATTR(3) enumeration, specifying +what this attribute signifies +.IP \[bu] 2 +storage - A member of the ALLEGRO_PRIM_STORAGE(3) enumeration, +specifying how this attribute is stored +.IP \[bu] 2 +offset - Offset in bytes from the beginning of the custom vertex +structure. +The C function offsetof is very useful here. +.SH SEE ALSO +.PP +al_create_vertex_decl(3), ALLEGRO_VERTEX_DECL(3), ALLEGRO_PRIM_ATTR(3), +ALLEGRO_PRIM_STORAGE(3) diff --git a/allegro/docs/man/ALLEGRO_VIDEO_EVENT_TYPE.3 b/allegro/docs/man/ALLEGRO_VIDEO_EVENT_TYPE.3 new file mode 100644 index 00000000..87d0da03 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_VIDEO_EVENT_TYPE.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_VIDEO_EVENT_TYPE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_VIDEO_EVENT_TYPE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +enum ALLEGRO_VIDEO_EVENT_TYPE +\f[R] +.fi +.SH DESCRIPTION +.PP +Events sent by al_get_video_event_source(3). +.SS ALLEGRO_EVENT_VIDEO_FRAME_SHOW +.PP +This event is sent when it is time to show a new frame. +Once you receive this event, you can draw the current frame (as returned +by al_get_video_frame(3)). +al_get_video_frame(3) will continue returning the same frame until the +next ALLEGRO_EVENT_VIDEO_FRAME_SHOW is sent. +.TP +user.data1 (ALLEGRO_VIDEO *) +The video which generated the event. +.SH SINCE +.PP +5.1.0 +.SS ALLEGRO_EVENT_VIDEO_FINISHED +.PP +This event is sent when the video is finished. +Depending on the backend, it may be possible to seek to an earlier part +of the video and set the video to play to resume playback. +.TP +user.data1 (ALLEGRO_VIDEO *) +The video which generated the event. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/ALLEGRO_VIDEO_POSITION_TYPE.3 b/allegro/docs/man/ALLEGRO_VIDEO_POSITION_TYPE.3 new file mode 100644 index 00000000..f1eee117 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_VIDEO_POSITION_TYPE.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_VIDEO_POSITION_TYPE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_VIDEO_POSITION_TYPE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_VIDEO_POSITION_TYPE ALLEGRO_VIDEO_POSITION_TYPE; +\f[R] +.fi +.SH DESCRIPTION +.PP +Used with al_get_video_position(3) to specify which position to +retrieve. +If these get out of sync, audio and video may be out of sync in the +display of the video. +.IP \[bu] 2 +ALLEGRO_VIDEO_POSITION_ACTUAL - The amount of time the video has been +playing. +If the video has audio then this value can be ahead of +ALLEGRO_VIDEO_POSITION_VIDEO_DECODE when video decoding lags. +.IP \[bu] 2 +ALLEGRO_VIDEO_POSITION_VIDEO_DECODE - The amount of video that has been +decoded. +This may lag behind the \[lq]actual\[rq] and audio positions if decoding +is slower than realtime. +.IP \[bu] 2 +ALLEGRO_VIDEO_POSITION_AUDIO_DECODE - The amount of audio that has been +decoded. +This may be the same as ALLEGRO_VIDEO_POSITION_ACTUAL if audio decode is +driving the position, which is common to keep audio and video in sync. +.SH SINCE +.PP +5.1.11 diff --git a/allegro/docs/man/ALLEGRO_VOICE.3 b/allegro/docs/man/ALLEGRO_VOICE.3 new file mode 100644 index 00000000..05074409 --- /dev/null +++ b/allegro/docs/man/ALLEGRO_VOICE.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_VOICE" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_VOICE - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef struct ALLEGRO_VOICE ALLEGRO_VOICE; +\f[R] +.fi +.SH DESCRIPTION +.PP +A voice represents an audio device on the system, which may be a real +device, or an abstract device provided by the operating system. +To play back audio, you would attach a mixer, sample instance or audio +stream to a voice. +.SH SEE ALSO +.PP +ALLEGRO_MIXER(3), ALLEGRO_SAMPLE(3), ALLEGRO_AUDIO_STREAM(3) diff --git a/allegro/docs/man/ALLEGRO_WRITE_MASK_FLAGS.3 b/allegro/docs/man/ALLEGRO_WRITE_MASK_FLAGS.3 new file mode 100644 index 00000000..68dda1cf --- /dev/null +++ b/allegro/docs/man/ALLEGRO_WRITE_MASK_FLAGS.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "ALLEGRO_WRITE_MASK_FLAGS" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +ALLEGRO_WRITE_MASK_FLAGS - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef enum ALLEGRO_WRITE_MASK_FLAGS { +\f[R] +.fi +.SH DESCRIPTION +.PP +Each enabled bit means the corresponding value is written, a disabled +bit means it is not. +.IP \[bu] 2 +ALLEGRO_MASK_RED +.IP \[bu] 2 +ALLEGRO_MASK_GREEN +.IP \[bu] 2 +ALLEGRO_MASK_BLUE +.IP \[bu] 2 +ALLEGRO_MASK_ALPHA +.IP \[bu] 2 +ALLEGRO_MASK_DEPTH +.IP \[bu] 2 +ALLEGRO_MASK_RGB - Same as RED | GREEN | BLUE. +.IP \[bu] 2 +ALLEGRO_MASK_RGBA - Same as RGB | ALPHA. +.SH SINCE +.PP +5.1.2 +.SH SEE ALSO +.PP +al_set_render_state(3) diff --git a/allegro/docs/man/al_acknowledge_drawing_halt.3 b/allegro/docs/man/al_acknowledge_drawing_halt.3 new file mode 100644 index 00000000..37c49b5e --- /dev/null +++ b/allegro/docs/man/al_acknowledge_drawing_halt.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_acknowledge_drawing_halt" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_acknowledge_drawing_halt - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_acknowledge_drawing_halt(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Call this in response to the ALLEGRO_EVENT_DISPLAY_HALT_DRAWING(3) +event. +This is currently necessary for Android and iOS as you are not allowed +to draw to your display while it is not being shown. +If you do not call this function to let the operating system know that +you have stopped drawing or if you call it to late the application +likely will be considered misbehaving and get terminated. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +ALLEGRO_EVENT_DISPLAY_HALT_DRAWING(3) diff --git a/allegro/docs/man/al_acknowledge_drawing_resume.3 b/allegro/docs/man/al_acknowledge_drawing_resume.3 new file mode 100644 index 00000000..d0c7d23a --- /dev/null +++ b/allegro/docs/man/al_acknowledge_drawing_resume.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_acknowledge_drawing_resume" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_acknowledge_drawing_resume - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_acknowledge_drawing_resume(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Call this in response to the ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING(3) +event. +.SH SINCE +.PP +5.1.1 +.SH SEE ALSO +.PP +ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING(3) diff --git a/allegro/docs/man/al_acknowledge_resize.3 b/allegro/docs/man/al_acknowledge_resize.3 new file mode 100644 index 00000000..22bf8fbf --- /dev/null +++ b/allegro/docs/man/al_acknowledge_resize.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_acknowledge_resize" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_acknowledge_resize - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_acknowledge_resize(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +When the user receives a [resize event]ALLEGRO_EVENT_DISPLAY_RESIZE(3) +from a resizable display, if they wish the display to be resized they +must call this function to let the graphics driver know that it can now +resize the display. +Returns true on success. +.PP +Adjusts the clipping rectangle to the full size of the backbuffer. +This also resets the backbuffers projection transform to default +orthographic transform (see al_use_projection_transform(3)). +.PP +Note that a resize event may be outdated by the time you acknowledge it; +there could be further resize events generated in the meantime. +.SH SEE ALSO +.PP +al_resize_display(3), ALLEGRO_EVENT(3) diff --git a/allegro/docs/man/al_add_config_comment.3 b/allegro/docs/man/al_add_config_comment.3 new file mode 100644 index 00000000..59d6c281 --- /dev/null +++ b/allegro/docs/man/al_add_config_comment.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_add_config_comment" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_add_config_comment - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_add_config_comment(ALLEGRO_CONFIG *config, + const char *section, const char *comment) +\f[R] +.fi +.SH DESCRIPTION +.PP +Add a comment in a section of a configuration. +If the section doesn\[cq]t yet exist, it will be created. +The section can be NULL or \[dq]\[dq] for the global section. +.PP +The comment may or may not begin with a hash character. +Any newlines in the comment string will be replaced by space characters. +.SH SEE ALSO +.PP +al_add_config_section(3) diff --git a/allegro/docs/man/al_add_config_section.3 b/allegro/docs/man/al_add_config_section.3 new file mode 100644 index 00000000..fc647b53 --- /dev/null +++ b/allegro/docs/man/al_add_config_section.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_add_config_section" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_add_config_section - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_add_config_section(ALLEGRO_CONFIG *config, const char *name) +\f[R] +.fi +.SH DESCRIPTION +.PP +Add a section to a configuration structure with the given name. +If the section already exists then nothing happens. diff --git a/allegro/docs/man/al_add_new_bitmap_flag.3 b/allegro/docs/man/al_add_new_bitmap_flag.3 new file mode 100644 index 00000000..0ae25558 --- /dev/null +++ b/allegro/docs/man/al_add_new_bitmap_flag.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_add_new_bitmap_flag" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_add_new_bitmap_flag - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_add_new_bitmap_flag(int flag) +\f[R] +.fi +.SH DESCRIPTION +.PP +A convenience function which does the same as +.IP +.nf +\f[C] +al_set_new_bitmap_flags(al_get_new_bitmap_flags() | flag); +\f[R] +.fi +.SH SEE ALSO +.PP +al_set_new_bitmap_flags(3), al_get_new_bitmap_flags(3), +al_get_bitmap_flags(3) diff --git a/allegro/docs/man/al_add_timer_count.3 b/allegro/docs/man/al_add_timer_count.3 new file mode 100644 index 00000000..c6362aef --- /dev/null +++ b/allegro/docs/man/al_add_timer_count.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_add_timer_count" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_add_timer_count - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_add_timer_count(ALLEGRO_TIMER *timer, int64_t diff) +\f[R] +.fi +.SH DESCRIPTION +.PP +Add \f[I]diff\f[R] to the timer\[cq]s counter value. +This is similar to writing: +.IP +.nf +\f[C] +al_set_timer_count(timer, al_get_timer_count(timer) + diff); +\f[R] +.fi +.PP +except that the addition is performed atomically, so no ticks will be +lost. +.SH SEE ALSO +.PP +al_set_timer_count(3) diff --git a/allegro/docs/man/al_android_get_activity.3 b/allegro/docs/man/al_android_get_activity.3 new file mode 100644 index 00000000..ab34d82e --- /dev/null +++ b/allegro/docs/man/al_android_get_activity.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_android_get_activity" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_android_get_activity - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +jobject al_android_get_activity(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the Java Android activity used by Allegro. +This is the same object created by Android from the class you specify in +your manifest and either an instance of AllegroActivity or a derived +class. +.SH SINCE +.PP +5.2.2 +.RS +.PP +\f[I][Unstable API]:\f[R] This API is new and subject to refinement. +.RE diff --git a/allegro/docs/man/al_android_get_jni_env.3 b/allegro/docs/man/al_android_get_jni_env.3 new file mode 100644 index 00000000..b8e4de0d --- /dev/null +++ b/allegro/docs/man/al_android_get_jni_env.3 @@ -0,0 +1,44 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_android_get_jni_env" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_android_get_jni_env - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +JNIEnv *al_android_get_jni_env(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the Android JNI environment used by Allegro to call into Java. +As a convenience this function provides it to the user so there is no +need to obtain it yourself. +.PP +For example if you have a Java method \[lq]void send(String +message)\[rq] in your activity class, you could call it like this from C +code: +.IP +.nf +\f[C] +JNIEnv * env = al_android_get_jni_env(); +jclass class_id = (* env)->GetObjectClass(env, al_android_get_activity()); +jmethodID method_id = (* env)->GetMethodID(env, class_id, \[dq]send\[dq], + \[dq](Ljava/lang/String;)V\[dq]); +jstring jdata = (* env)->NewStringUTF(env, \[dq]Hello Java!\[dq]); +(* env)->CallVoidMethod(env, al_android_get_activity(), method_id, jdata); +(* env)->DeleteLocalRef(env, jdata); +\f[R] +.fi +.SH SINCE +.PP +5.2.2 +.RS +.PP +\f[I][Unstable API]:\f[R] This API is new and subject to refinement. +.RE diff --git a/allegro/docs/man/al_android_get_os_version.3 b/allegro/docs/man/al_android_get_os_version.3 new file mode 100644 index 00000000..a70d82d5 --- /dev/null +++ b/allegro/docs/man/al_android_get_os_version.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_android_get_os_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_android_get_os_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_android_get_os_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns a pointer to a static buffer that contains the version string of +the Android platform that the calling Allegro program is running on. +.SH SINCE +.PP +5.1.2 diff --git a/allegro/docs/man/al_android_set_apk_file_interface.3 b/allegro/docs/man/al_android_set_apk_file_interface.3 new file mode 100644 index 00000000..87d30008 --- /dev/null +++ b/allegro/docs/man/al_android_set_apk_file_interface.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_android_set_apk_file_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_android_set_apk_file_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_android_set_apk_file_interface(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function will set up a custom ALLEGRO_FILE_INTERFACE(3) that makes +all future calls of al_fopen(3) read from the applicatons\[cq]s APK +file. +.RS +.PP +\f[I]Note:\f[R] Currently, access to the APK file after calling this +function is read only. +.RE +.SH SINCE +.PP +5.1.2 diff --git a/allegro/docs/man/al_android_set_apk_fs_interface.3 b/allegro/docs/man/al_android_set_apk_fs_interface.3 new file mode 100644 index 00000000..7fdb56f9 --- /dev/null +++ b/allegro/docs/man/al_android_set_apk_fs_interface.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_android_set_apk_fs_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_android_set_apk_fs_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_android_set_apk_fs_interface(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function will set up a custom ALLEGRO_FS_INTERFACE(3) which allows +working within the APK filesystem. +The filesystem root is your assets directory and there is read-only +access to all files within. +.RS +.PP +\f[I]Note:\f[R] Some things like querying file size or attributes are +not supported by this. +You can always use the PhysFS addon to open the APK file (it is just a +regular .zip file) and get more complete information. +.RE +.SH SINCE +.PP +5.1.13 diff --git a/allegro/docs/man/al_append_menu_item.3 b/allegro/docs/man/al_append_menu_item.3 new file mode 100644 index 00000000..62990eca --- /dev/null +++ b/allegro/docs/man/al_append_menu_item.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_append_menu_item" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_append_menu_item - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_append_menu_item(ALLEGRO_MENU *parent, char const *title, uint16_t id, + int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu) +\f[R] +.fi +.SH DESCRIPTION +.PP +Appends a menu item to the end of the menu. +See al_insert_menu_item(3) for more information. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_insert_menu_item(3), al_remove_menu_item(3) diff --git a/allegro/docs/man/al_append_native_text_log.3 b/allegro/docs/man/al_append_native_text_log.3 new file mode 100644 index 00000000..6227593f --- /dev/null +++ b/allegro/docs/man/al_append_native_text_log.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_append_native_text_log" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_append_native_text_log - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_append_native_text_log(ALLEGRO_TEXTLOG *textlog, + char const *format, ...) +\f[R] +.fi +.SH DESCRIPTION +.PP +Appends a line of text to the message log window and scrolls to the +bottom (if the line would not be visible otherwise). +This works like printf. +A line is continued until you add a newline character. +.PP +If the window is NULL then this function will fall back to calling +printf. +This makes it convenient to support logging to a window or a terminal. diff --git a/allegro/docs/man/al_append_path_component.3 b/allegro/docs/man/al_append_path_component.3 new file mode 100644 index 00000000..48bd5a8a --- /dev/null +++ b/allegro/docs/man/al_append_path_component.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_append_path_component" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_append_path_component - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_append_path_component(ALLEGRO_PATH *path, const char *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Append a directory component. +.SH SEE ALSO +.PP +al_insert_path_component(3) diff --git a/allegro/docs/man/al_apply_window_constraints.3 b/allegro/docs/man/al_apply_window_constraints.3 new file mode 100644 index 00000000..0e608e67 --- /dev/null +++ b/allegro/docs/man/al_apply_window_constraints.3 @@ -0,0 +1,46 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_apply_window_constraints" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_apply_window_constraints - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_apply_window_constraints(ALLEGRO_DISPLAY *display, bool onoff) +\f[R] +.fi +.SH DESCRIPTION +.PP +Enable or disable previously set constraints by +al_set_window_constraints(3) function. +.PP +If enabled, the specified display will be automatically resized to new +sizes to conform constraints in next cases: +.IP \[bu] 2 +The specified display is resizable, not maximized and is not in +fullscreen mode. +.IP \[bu] 2 +If the appropriate current display size (width or height) is less than +the value of constraint. +Applied to minimum constraints. +.IP \[bu] 2 +If the appropriate current display size (width or height) is greater +than the value of constraint. +Applied to maximum constraints. +.PP +Constrains are not applied when a display is toggle from windowed to +maximized or fullscreen modes. +When a display is toggle from maximized/fullscreen to windowed mode, +then the display may be resized as described above. +The later case is also possible when a user drags the maximized display +via mouse. +.PP +If disabled, the specified display will stop using constraints. +.SH SEE ALSO +.PP +al_get_window_constraints(3), al_set_window_constraints(3) diff --git a/allegro/docs/man/al_attach_audio_stream_to_mixer.3 b/allegro/docs/man/al_attach_audio_stream_to_mixer.3 new file mode 100644 index 00000000..dabb9244 --- /dev/null +++ b/allegro/docs/man/al_attach_audio_stream_to_mixer.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_attach_audio_stream_to_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_attach_audio_stream_to_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Attach an audio stream to a mixer. +The stream must not already be attached to anything. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_detach_audio_stream(3). diff --git a/allegro/docs/man/al_attach_audio_stream_to_voice.3 b/allegro/docs/man/al_attach_audio_stream_to_voice.3 new file mode 100644 index 00000000..c69d192d --- /dev/null +++ b/allegro/docs/man/al_attach_audio_stream_to_voice.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_attach_audio_stream_to_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_attach_audio_stream_to_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM *stream, + ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Attaches an audio stream to a voice. +The same rules as al_attach_sample_instance_to_voice(3) apply. +This may fail if the driver can\[cq]t create a voice with the buffer +count and buffer size the stream uses. +.PP +An audio stream attached directly to a voice has a number of +limitations: The audio stream plays immediately and cannot be stopped. +The stream position, speed, gain and panning cannot be changed. +At this time, we don\[cq]t recommend attaching audio streams directly to +voices. +Use a mixer inbetween. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_detach_voice(3) diff --git a/allegro/docs/man/al_attach_mixer_to_mixer.3 b/allegro/docs/man/al_attach_mixer_to_mixer.3 new file mode 100644 index 00000000..91cd6a61 --- /dev/null +++ b/allegro/docs/man/al_attach_mixer_to_mixer.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_attach_mixer_to_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_attach_mixer_to_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_attach_mixer_to_mixer(ALLEGRO_MIXER *stream, ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Attaches the mixer passed as the first argument onto the mixer passed as +the second argument. +The first mixer (that is going to be attached) must not already be +attached to anything. +Both mixers must use the same frequency, audio depth and channel +configuration. +.PP +Returns true on success, false on error. +.PP +It is invalid to attach a mixer to itself. +.SH SEE ALSO +.PP +al_detach_mixer(3). diff --git a/allegro/docs/man/al_attach_mixer_to_voice.3 b/allegro/docs/man/al_attach_mixer_to_voice.3 new file mode 100644 index 00000000..58c3ca83 --- /dev/null +++ b/allegro/docs/man/al_attach_mixer_to_voice.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_attach_mixer_to_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_attach_mixer_to_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_attach_mixer_to_voice(ALLEGRO_MIXER *mixer, ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Attaches a mixer to a voice. +It must have the same frequency and channel configuration, but the depth +may be different. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_detach_voice(3) diff --git a/allegro/docs/man/al_attach_sample_instance_to_mixer.3 b/allegro/docs/man/al_attach_sample_instance_to_mixer.3 new file mode 100644 index 00000000..79e73969 --- /dev/null +++ b/allegro/docs/man/al_attach_sample_instance_to_mixer.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_attach_sample_instance_to_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_attach_sample_instance_to_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_attach_sample_instance_to_mixer(ALLEGRO_SAMPLE_INSTANCE *spl, + ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Attach a sample instance to a mixer. +The instance must not already be attached to anything. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_detach_sample_instance(3). diff --git a/allegro/docs/man/al_attach_sample_instance_to_voice.3 b/allegro/docs/man/al_attach_sample_instance_to_voice.3 new file mode 100644 index 00000000..23f45dac --- /dev/null +++ b/allegro/docs/man/al_attach_sample_instance_to_voice.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_attach_sample_instance_to_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_attach_sample_instance_to_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_attach_sample_instance_to_voice(ALLEGRO_SAMPLE_INSTANCE *spl, + ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Attaches a sample instance to a voice, and allows it to play. +The instance\[cq]s gain and loop mode will be ignored, and it must have +the same frequency, channel configuration and depth (including +signed-ness) as the voice. +This function may fail if the selected driver doesn\[cq]t support +preloading sample data. +.PP +At this time, we don\[cq]t recommend attaching sample instances directly +to voices. +Use a mixer inbetween. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_detach_voice(3) diff --git a/allegro/docs/man/al_attach_shader_source.3 b/allegro/docs/man/al_attach_shader_source.3 new file mode 100644 index 00000000..7df3db30 --- /dev/null +++ b/allegro/docs/man/al_attach_shader_source.3 @@ -0,0 +1,156 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_attach_shader_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_attach_shader_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_attach_shader_source(ALLEGRO_SHADER *shader, ALLEGRO_SHADER_TYPE type, + const char *source) +\f[R] +.fi +.SH DESCRIPTION +.PP +Attaches the shader\[cq]s source code to the shader object and compiles +it. +Passing NULL deletes the underlying (OpenGL or DirectX) shader. +See also al_attach_shader_source_file(3) if you prefer to obtain your +shader source from an external file. +.PP +If you do not use ALLEGRO_PROGRAMMABLE_PIPELINE Allegro\[cq]s graphics +functions will not use any shader specific functions themselves. +In case of a system with no fixed function pipeline (like OpenGL ES 2 or +OpenGL 3 or 4) this means Allegro\[cq]s drawing functions cannot be +used. +.PP +TODO: Is ALLEGRO_PROGRAMMABLE_PIPELINE set automatically in this case? +.PP +When ALLEGRO_PROGRAMMABLE_PIPELINE is used the following shader uniforms +are provided by Allegro and can be accessed in your shaders: +.TP +al_projview_matrix +matrix for Allegro\[cq]s orthographic projection multiplied by the +al_use_transform(3) matrix. +The type is \f[C]mat4\f[R] in GLSL, and \f[C]float4x4\f[R] in HLSL. +.TP +al_use_tex +whether or not to use the bound texture. +The type is \f[C]bool\f[R] in both GLSL and HLSL. +.TP +al_tex +the texture if one is bound. +The type is \f[C]sampler2D\f[R] in GLSL and \f[C]texture\f[R] in HLSL. +.TP +al_use_tex_matrix +whether or not to use a texture matrix (used by the primitives addon). +The type is \f[C]bool\f[R] in both GLSL and HLSL. +.TP +al_tex_matrix +the texture matrix (used by the primitives addon). +Your shader should multiply the texture coordinates by this matrix. +The type is \f[C]mat4\f[R] in GLSL, and \f[C]float4x4\f[R] in HLSL. +.PP +With GLSL alpha testing is done in the shader and uses these additional +uniforms: +.TP +al_alpha_test +Whether to do any alpha testing. +If false, the shader should render the pixel, otherwise it should +interpret the values of \f[C]al_alpha_func\f[R] and +\f[C]al_alpha_test_val\f[R]. +.TP +al_alpha_func +The alpha testing function used. +One of the ALLEGRO_RENDER_FUNCTION(3) values. +The default is ALLEGRO_RENDER_ALWAYS which means all pixels (even +completely transparent ones) are rendered. +The type is \f[C]int\f[R]. +See ALLEGRO_RENDER_STATE(3). +.TP +al_alpha_test_val +If alpha testing is not ALLEGRO_RENDER_NEVER or ALLEGRO_RENDER_ALWAYS +the alpha value to compare to for alpha testing. +The type is \f[C]float\f[R]. +.PP +For GLSL shaders the vertex attributes are passed using the following +variables: +.TP +al_pos +vertex position attribute. +Type is \f[C]vec4\f[R]. +.TP +al_texcoord +vertex texture coordinate attribute. +Type is \f[C]vec2\f[R]. +.TP +al_color +vertex color attribute. +Type is \f[C]vec4\f[R]. +.TP +al_user_attr_0 +The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR +.TP +al_user_attr_1, \&..., al_user_attr_9 +The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR + X where X is +an integer from 1 to 9 +.PP +For HLSL shaders the vertex attributes are passed using the following +semantics: +.TP +POSITION0 +vertex position attribute. +Type is \f[C]float4\f[R]. +.TP +TEXCOORD0 +vertex texture coordinate attribute. +Type is \f[C]float2\f[R]. +.TP +TEXCOORD1 +vertex color attribute. +Type is \f[C]float4\f[R]. +.PP +Also, each shader variable has a corresponding macro name that can be +used when defining the shaders using string literals. +Don\[cq]t use these macros with the other shader functions as that will +lead to undefined behavior. +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX for \[lq]al_projview_matrix\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_POS for \[lq]al_pos\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_COLOR for \[lq]al_color\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_TEXCOORD for \[lq]al_texcoord\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_USE_TEX for \[lq]al_use_tex\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_TEX for \[lq]al_tex\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_USE_TEX_MATRIX for \[lq]al_use_tex_matrix\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_TEX_MATRIX for \[lq]al_tex_matrix\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_ALPHA_FUNCTION for \[lq]al_alpha_func\[rq] +.IP \[bu] 2 +ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE for \[lq]al_alpha_test_val\[rq] +.PP +Examine the output of al_get_default_shader_source(3) for an example of +how to use the above uniforms and attributes. +.PP +Returns true on success and false on error, in which case the error log +is updated. +The error log can be retrieved with al_get_shader_log(3). +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_attach_shader_source_file(3), al_build_shader(3), +al_get_default_shader_source(3), al_get_shader_log(3), +ALLEGRO_PRIM_ATTR(3) diff --git a/allegro/docs/man/al_attach_shader_source_file.3 b/allegro/docs/man/al_attach_shader_source_file.3 new file mode 100644 index 00000000..6166c8f8 --- /dev/null +++ b/allegro/docs/man/al_attach_shader_source_file.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_attach_shader_source_file" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_attach_shader_source_file - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_attach_shader_source_file(ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *filename) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_attach_shader_source(3) but reads the source code for the shader +from the named file. +.PP +Returns true on success and false on error, in which case the error log +is updated. +The error log can be retrieved with al_get_shader_log(3). +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_attach_shader_source(3), al_build_shader(3), al_get_shader_log(3) diff --git a/allegro/docs/man/al_backup_dirty_bitmap.3 b/allegro/docs/man/al_backup_dirty_bitmap.3 new file mode 100644 index 00000000..a8db42de --- /dev/null +++ b/allegro/docs/man/al_backup_dirty_bitmap.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_backup_dirty_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_backup_dirty_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_backup_dirty_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +On some platforms, notably Windows Direct3D and Android, textures may be +lost at any time for events such as display resize or switching out of +the app. +On those platforms, bitmaps created without the +ALLEGRO_NO_PRESERVE_TEXTURE flag automatically get backed up to system +memory every time al_flip_display is called. +.PP +This function gives you more control over when your bitmaps get backed +up. +By calling this function after modifying a bitmap, you can make sure the +bitmap is backed up right away instead of during the next flip. +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This API is new and subject to refinement. +.RE +.SH SEE ALSO +.PP +al_backup_dirty_bitmaps(3), al_create_bitmap(3) diff --git a/allegro/docs/man/al_backup_dirty_bitmaps.3 b/allegro/docs/man/al_backup_dirty_bitmaps.3 new file mode 100644 index 00000000..ca9c5ea3 --- /dev/null +++ b/allegro/docs/man/al_backup_dirty_bitmaps.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_backup_dirty_bitmaps" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_backup_dirty_bitmaps - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_backup_dirty_bitmaps(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Backs up all of a display\[cq]s bitmaps to system memory. +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This API is new and subject to refinement. +.RE +.SH SEE ALSO +.PP +al_backup_dirty_bitmap(3) diff --git a/allegro/docs/man/al_broadcast_cond.3 b/allegro/docs/man/al_broadcast_cond.3 new file mode 100644 index 00000000..45508607 --- /dev/null +++ b/allegro/docs/man/al_broadcast_cond.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_broadcast_cond" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_broadcast_cond - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_broadcast_cond(ALLEGRO_COND *cond) +\f[R] +.fi +.SH DESCRIPTION +.PP +Unblock all threads currently waiting on a condition variable. +That is, broadcast that some condition which those threads were waiting +for has become true. +.SH SEE ALSO +.PP +al_signal_cond(3). +.RS +.PP +\f[I]Note:\f[R] The pthreads spec says to lock the mutex associated with +\f[C]cond\f[R] before signalling for predictable scheduling behaviour. +.RE diff --git a/allegro/docs/man/al_build_camera_transform.3 b/allegro/docs/man/al_build_camera_transform.3 new file mode 100644 index 00000000..c401f2bb --- /dev/null +++ b/allegro/docs/man/al_build_camera_transform.3 @@ -0,0 +1,78 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_build_camera_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_build_camera_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_build_camera_transform(ALLEGRO_TRANSFORM *trans, + float position_x, float position_y, float position_z, + float look_x, float look_y, float look_z, + float up_x, float up_y, float up_z) +\f[R] +.fi +.SH DESCRIPTION +.PP +Builds a transformation which can be used to transform 3D coordinates in +world space to camera space. +This involves translation and a rotation. +The function expects three coordinate triplets: The camera\[cq]s +position, the position the camera is looking at and an up vector. +The up vector does not need to be of unit length and also does not need +to be perpendicular to the view direction - it can usually just be the +world up direction (most commonly 0/1/0). +.PP +For example: +.IP +.nf +\f[C] +al_build_camera_transform(&t, + 1, 1, 1, + 5, 5, 5, + 0, 1, 0); +\f[R] +.fi +.PP +This create a transformation for a camera standing at 1/1/1 and looking +towards 5/5/5. +.RS +.PP +\f[I]Note\f[R]: If the \f[I]position\f[R] and \f[I]look\f[R] parameters +are identical, or if the \f[I]up\f[R] direction is parallel to the view +direction, an identity matrix is created. +.RE +.PP +Another example which will simply re-create the identity matrix: +.IP +.nf +\f[C] +al_build_camera_transform(&t, + 0, 0, 0, + 0, 0, -1, + 0, 1, 0); +\f[R] +.fi +.PP +An example where the up vector will cause the camera to lean (roll) by +45 degrees: +.IP +.nf +\f[C] +al_build_camera_transform(&t, + 1, 1, 1, + 5, 5, 5, + 1, 1, 0); +\f[R] +.fi +.PP +Since 5.1.9 +.SH SEE ALSO +.PP +al_translate_transform_3d(3), al_rotate_transform_3d(3), +al_scale_transform_3d(3), al_compose_transform(3), al_use_transform(3) diff --git a/allegro/docs/man/al_build_menu.3 b/allegro/docs/man/al_build_menu.3 new file mode 100644 index 00000000..10566459 --- /dev/null +++ b/allegro/docs/man/al_build_menu.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_build_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_build_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MENU *al_build_menu(ALLEGRO_MENU_INFO *info) +\f[R] +.fi +.SH DESCRIPTION +.PP +Builds a menu based on the specifications of a sequence of +\f[C]ALLEGRO_MENU_INFO\f[R] elements. +.PP +Returns a pointer to the root \f[C]ALLEGRO_MENU\f[R], or \f[C]NULL\f[R] +on failure. +To gain access to the other menus and items, you will need to search for +them using al_find_menu_item(3). +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +ALLEGRO_MENU_INFO(3), al_create_menu(3), al_create_popup_menu(3) diff --git a/allegro/docs/man/al_build_shader.3 b/allegro/docs/man/al_build_shader.3 new file mode 100644 index 00000000..d35f1d08 --- /dev/null +++ b/allegro/docs/man/al_build_shader.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_build_shader" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_build_shader - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_build_shader(ALLEGRO_SHADER *shader) +\f[R] +.fi +.SH DESCRIPTION +.PP +This is required before the shader can be used with al_use_shader(3). +It should be called after successfully attaching the pixel and/or vertex +shaders with al_attach_shader_source(3) or +al_attach_shader_source_file(3). +.PP +Returns true on success and false on error, in which case the error log +is updated. +The error log can be retrieved with al_get_shader_log(3). +.RS +.PP +\f[I]Note:\f[R] If you are using the ALLEGRO_PROGRAMMABLE_PIPELINE flag, +then you must specify both a pixel and a vertex shader sources for +anything to be rendered. +.RE +.SH SINCE +.PP +5.1.6 +.SH SEE ALSO +.PP +al_use_shader(3), al_get_shader_log(3) diff --git a/allegro/docs/man/al_build_transform.3 b/allegro/docs/man/al_build_transform.3 new file mode 100644 index 00000000..369ad124 --- /dev/null +++ b/allegro/docs/man/al_build_transform.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_build_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_build_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_build_transform(ALLEGRO_TRANSFORM *trans, float x, float y, + float sx, float sy, float theta) +\f[R] +.fi +.SH DESCRIPTION +.PP +Builds a transformation given some parameters. +This call is equivalent to calling the transformations in this order: +make identity, rotate, scale, translate. +This method is faster, however, than actually calling those functions. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to alter +.IP \[bu] 2 +x, y - Translation +.IP \[bu] 2 +sx, sy - Scale +.IP \[bu] 2 +theta - Rotation angle in radians +.RS +.PP +\f[I]Note\f[R]: this function was previously documented to be equivalent +to a different (and more useful) order of operations: identity, scale, +rotate, translate. +.RE +.SH SEE ALSO +.PP +al_translate_transform(3), al_rotate_transform(3), +al_scale_transform(3), al_compose_transform(3) diff --git a/allegro/docs/man/al_calculate_arc.3 b/allegro/docs/man/al_calculate_arc.3 new file mode 100644 index 00000000..00f06de8 --- /dev/null +++ b/allegro/docs/man/al_calculate_arc.3 @@ -0,0 +1,104 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_calculate_arc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_calculate_arc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_calculate_arc(float* dest, int stride, float cx, float cy, + float rx, float ry, float start_theta, float delta_theta, float thickness, + int num_points) +\f[R] +.fi +.SH DESCRIPTION +.PP +When \f[C]thickness <= 0\f[R] this function computes positions of +\f[C]num_points\f[R] regularly spaced points on an elliptical arc. +When \f[C]thickness > 0\f[R] this function computes two sets of points, +obtained as follows: the first set is obtained by taking the points +computed in the \f[C]thickness <= 0\f[R] case and shifting them by +\f[C]thickness / 2\f[R] outward, in a direction perpendicular to the arc +curve. +The second set is the same, but shifted \f[C]thickness / 2\f[R] inward +relative to the arc. +The two sets of points are interleaved in the destination buffer +(i.e.\ the first pair of points will be collinear with the arc center, +the first point of the pair will be farther from the center than the +second point; the next pair will also be collinear, but at a different +angle and so on). +.PP +The destination buffer \f[C]dest\f[R] is interpreted as a set of +regularly spaced pairs of floats, each pair holding the coordinates of +the corresponding point on the arc. +The two floats in the pair are adjacent, and the distance (in bytes) +between the addresses of the first float in two successive pairs is +\f[C]stride\f[R]. +For example, if you have a tightly packed array of floats with no spaces +between pairs, then \f[C]stride\f[R] will be exactly +\f[C]2 * sizeof(float)\f[R]. +.PP +Example with \f[C]thickness <= 0\f[R]: +.IP +.nf +\f[C] +const int num_points = 4; +float points[num_points][2]; +al_calculate_arc(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 0, num_points); + +assert((int)points[0][0] == 10); +assert((int)points[0][1] == 0); + +assert((int)points[num_points - 1][0] == 0); +assert((int)points[num_points - 1][1] == 10); +\f[R] +.fi +.PP +Example with \f[C]thickness > 0\f[R]: +.IP +.nf +\f[C] +const int num_points = 4; +float points[num_points * 2][2]; +al_calculate_arc(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 2, num_points); + +assert((int)points[0][0] == 11); +assert((int)points[0][1] == 0); +assert((int)points[1][0] == 9); +assert((int)points[1][1] == 0); + +assert((int)points[(num_points - 1) * 2][0] == 0); +assert((int)points[(num_points - 1) * 2][1] == 11); +assert((int)points[(num_points - 1) * 2 + 1][0] == 0); +assert((int)points[(num_points - 1) * 2 + 1][1] == 9); +\f[R] +.fi +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +dest - The destination buffer +.IP \[bu] 2 +stride - Distance (in bytes) between starts of successive pairs of +points +.IP \[bu] 2 +cx, cy - Center of the arc +.IP \[bu] 2 +rx, ry - Radii of the arc +.IP \[bu] 2 +start_theta - The initial angle from which the arc is calculated in +radians +.IP \[bu] 2 +delta_theta - Angular span of the arc in radians (pass a negative number +to switch direction) +.IP \[bu] 2 +thickness - Thickness of the arc +.IP \[bu] 2 +num_points - The number of points to calculate +.SH SEE ALSO +.PP +al_draw_arc(3), al_calculate_spline(3), al_calculate_ribbon(3) diff --git a/allegro/docs/man/al_calculate_ribbon.3 b/allegro/docs/man/al_calculate_ribbon.3 new file mode 100644 index 00000000..dadcecf3 --- /dev/null +++ b/allegro/docs/man/al_calculate_ribbon.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_calculate_ribbon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_calculate_ribbon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_calculate_ribbon(float* dest, int dest_stride, const float *points, + int points_stride, float thickness, int num_segments) +\f[R] +.fi +.SH DESCRIPTION +.PP +Calculates a ribbon given an array of points. +The ribbon will go through all of the passed points. +If \f[C]thickness <= 0\f[R], then \f[C]num_segments\f[R] of points are +required in the destination buffer, otherwise twice as many are needed. +The destination and the points buffer should consist of regularly spaced +doublets of floats, corresponding to x and y coordinates of the +vertices. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +dest - Pointer to the destination buffer +.IP \[bu] 2 +dest_stride - Distance (in bytes) between starts of successive pairs of +coordinates in the destination buffer +.IP \[bu] 2 +points - An array of pairs of coordinates for each point +.IP \[bu] 2 +points_stride - Distance (in bytes) between starts of successive pairs +of coordinates in the points buffer +.IP \[bu] 2 +thickness - Thickness of the spline ribbon +.IP \[bu] 2 +num_segments - The number of points to calculate +.SH SEE ALSO +.PP +al_draw_ribbon(3), al_calculate_arc(3), al_calculate_spline(3) diff --git a/allegro/docs/man/al_calculate_spline.3 b/allegro/docs/man/al_calculate_spline.3 new file mode 100644 index 00000000..433e835c --- /dev/null +++ b/allegro/docs/man/al_calculate_spline.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_calculate_spline" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_calculate_spline - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_calculate_spline(float* dest, int stride, float points[8], + float thickness, int num_segments) +\f[R] +.fi +.SH DESCRIPTION +.PP +Calculates a B\['e]zier spline given 4 control points. +If \f[C]thickness <= 0\f[R], then \f[C]num_segments\f[R] of points are +required in the destination, otherwise twice as many are needed. +The destination buffer should consist of regularly spaced (by distance +of stride bytes) doublets of floats, corresponding to x and y +coordinates of the vertices. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +dest - The destination buffer +.IP \[bu] 2 +stride - Distance (in bytes) between starts of successive pairs of +coordinates +.IP \[bu] 2 +points - An array of 4 pairs of coordinates of the 4 control points +.IP \[bu] 2 +thickness - Thickness of the spline ribbon +.IP \[bu] 2 +num_segments - The number of points to calculate +.SH SEE ALSO +.PP +al_draw_spline(3), al_calculate_arc(3), al_calculate_ribbon(3) diff --git a/allegro/docs/man/al_calloc.3 b/allegro/docs/man/al_calloc.3 new file mode 100644 index 00000000..dd9454e9 --- /dev/null +++ b/allegro/docs/man/al_calloc.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_calloc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_calloc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define al_calloc(c, n) \[rs] + (al_calloc_with_context((c), (n), __LINE__, __FILE__, __func__)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like calloc() in the C standard library, but the implementation may be +overridden. +.PP +This is a macro. +.SH SEE ALSO +.PP +al_malloc(3), al_calloc_with_context(3) diff --git a/allegro/docs/man/al_calloc_with_context.3 b/allegro/docs/man/al_calloc_with_context.3 new file mode 100644 index 00000000..9194ba3d --- /dev/null +++ b/allegro/docs/man/al_calloc_with_context.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_calloc_with_context" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_calloc_with_context - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void *al_calloc_with_context(size_t count, size_t n, + int line, const char *file, const char *func) +\f[R] +.fi +.SH DESCRIPTION +.PP +This calls calloc() from the Allegro library (this matters on Windows), +unless overridden with al_set_memory_interface(3), +.PP +Generally you should use the al_calloc(3) macro. diff --git a/allegro/docs/man/al_change_directory.3 b/allegro/docs/man/al_change_directory.3 new file mode 100644 index 00000000..18854abd --- /dev/null +++ b/allegro/docs/man/al_change_directory.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_change_directory" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_change_directory - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_change_directory(const char *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Changes the current working directory to `path'. +.PP +Returns true on success, false on error. diff --git a/allegro/docs/man/al_check_inverse.3 b/allegro/docs/man/al_check_inverse.3 new file mode 100644 index 00000000..b8044cf0 --- /dev/null +++ b/allegro/docs/man/al_check_inverse.3 @@ -0,0 +1,57 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_check_inverse" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_check_inverse - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_check_inverse(const ALLEGRO_TRANSFORM *trans, float tol) +\f[R] +.fi +.SH DESCRIPTION +.PP +Checks if the transformation has an inverse using the supplied +tolerance. +Tolerance should be a small value between 0 and 1, with 1e-7 being +sufficient for most applications. +.PP +In this function tolerance specifies how close the determinant can be to +0 (if the determinant is 0, the transformation has no inverse). +Thus the smaller the tolerance you specify, the \[lq]worse\[rq] +transformations will pass this test. +Using a tolerance of 1e-7 will catch errors greater than 1/1000\[cq]s of +a pixel, but let smaller errors pass. +That means that if you transformed a point by a transformation and then +transformed it again by the inverse transformation that passed this +check, the resultant point should less than 1/1000\[cq]s of a pixel away +from the original point. +.PP +Note that this check is superfluous most of the time if you never +touched the transformation matrix values yourself. +The only thing that would cause the transformation to not have an +inverse is if you applied a 0 (or very small) scale to the +transformation or you have a really large translation. +As long as the scale is comfortably above 0, the transformation will be +invertible. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to check +.IP \[bu] 2 +tol - Tolerance +.PP +\f[I]Returns:\f[R] 1 if the transformation is invertible, 0 otherwise +.RS +.PP +\f[I]Note\f[R]: Allegro\[cq]s transformation inversion functions work +correctly only with 2D transformations. +.RE +.SH SEE ALSO +.PP +al_invert_transform(3) diff --git a/allegro/docs/man/al_clear_depth_buffer.3 b/allegro/docs/man/al_clear_depth_buffer.3 new file mode 100644 index 00000000..f29ae101 --- /dev/null +++ b/allegro/docs/man/al_clear_depth_buffer.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_clear_depth_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_clear_depth_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_clear_depth_buffer(float z) +\f[R] +.fi +.SH DESCRIPTION +.PP +Clear the depth buffer (confined by the clipping rectangle) to the given +value. +A depth buffer is only available if it was requested with +al_set_new_display_option(3) and the requirement could be met by the +al_create_display(3) call creating the current display. +Operations involving the depth buffer are also affected by +al_set_render_state(3). +.PP +For example, if \f[C]ALLEGRO_DEPTH_FUNCTION\f[R] is set to +\f[C]ALLEGRO_RENDER_LESS\f[R] then depth buffer value of 1 represents +infinite distance, and thus is a good value to use when clearing the +depth buffer. +.SH SINCE +.PP +5.1.2 +.SH SEE ALSO +.PP +al_clear_to_color(3), al_set_clipping_rectangle(3), +al_set_render_state(3), al_set_new_display_option(3) diff --git a/allegro/docs/man/al_clear_keyboard_state.3 b/allegro/docs/man/al_clear_keyboard_state.3 new file mode 100644 index 00000000..8e7c8f60 --- /dev/null +++ b/allegro/docs/man/al_clear_keyboard_state.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_clear_keyboard_state" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_clear_keyboard_state - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_clear_keyboard_state(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Clear the state of the keyboard, emitting ALLEGRO_EVENT_KEY_UP(3) for +each currently pressed key. +The given display is regarded as the one which had the keyboard focus +when the event occurred. +In case display is NULL no event is emitted. +For most keyboard drivers Allegro maintains its own state of the +keyboard, which might get out of sync with the real one. +This function is intended to remedy such situation by resetting +Allegro\[cq]s keyboard state to a known default (no key pressed). +This is particularly useful in response to +ALLEGRO_EVENT_DISPLAY_SWITCH_OUT(3) events. +.SH SEE ALSO +.PP +al_get_keyboard_state(3), ALLEGRO_KEYBOARD_STATE(3) +.SH SINCE +.PP +5.2.3 +.RS +.PP +\f[I][Unstable API]:\f[R] This is a new feature and the exact semantics +are still being decided upon. +.RE diff --git a/allegro/docs/man/al_clear_to_color.3 b/allegro/docs/man/al_clear_to_color.3 new file mode 100644 index 00000000..ad2b8bfa --- /dev/null +++ b/allegro/docs/man/al_clear_to_color.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_clear_to_color" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_clear_to_color - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_clear_to_color(ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Clear the complete target bitmap, but confined by the clipping +rectangle. +.SH SEE ALSO +.PP +ALLEGRO_COLOR(3), al_set_clipping_rectangle(3), al_clear_depth_buffer(3) diff --git a/allegro/docs/man/al_clipboard_has_text.3 b/allegro/docs/man/al_clipboard_has_text.3 new file mode 100644 index 00000000..777a01f8 --- /dev/null +++ b/allegro/docs/man/al_clipboard_has_text.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_clipboard_has_text" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_clipboard_has_text - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_clipboard_has_text(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function returns true if and only if the clipboard has text +available. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_set_clipboard_text(3), al_get_clipboard_text(3) diff --git a/allegro/docs/man/al_clone_bitmap.3 b/allegro/docs/man/al_clone_bitmap.3 new file mode 100644 index 00000000..5eb87020 --- /dev/null +++ b/allegro/docs/man/al_clone_bitmap.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_clone_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_clone_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_clone_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a new bitmap with al_create_bitmap(3), and copy the pixel data +from the old bitmap across. +The newly created bitmap will be created with the current new bitmap +flags, and not the ones that were used to create the original bitmap. +If the new bitmap is a memory bitmap, its projection bitmap is reset to +be orthographic. +.SH SEE ALSO +.PP +al_create_bitmap(3), al_set_new_bitmap_format(3), +al_set_new_bitmap_flags(3), al_convert_bitmap(3) diff --git a/allegro/docs/man/al_clone_menu.3 b/allegro/docs/man/al_clone_menu.3 new file mode 100644 index 00000000..81c173f7 --- /dev/null +++ b/allegro/docs/man/al_clone_menu.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_clone_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_clone_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MENU *al_clone_menu(ALLEGRO_MENU *menu) +\f[R] +.fi +.SH DESCRIPTION +.PP +Makes a copy of a menu so that it can be reused on another display. +The menu being cloned can be anything: a regular menu, a popup menu, or +a sub-menu. +.PP +Returns the cloned menu. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_clone_menu_for_popup(3) diff --git a/allegro/docs/man/al_clone_menu_for_popup.3 b/allegro/docs/man/al_clone_menu_for_popup.3 new file mode 100644 index 00000000..3f3a5b85 --- /dev/null +++ b/allegro/docs/man/al_clone_menu_for_popup.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_clone_menu_for_popup" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_clone_menu_for_popup - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MENU *al_clone_menu_for_popup(ALLEGRO_MENU *menu) +\f[R] +.fi +.SH DESCRIPTION +.PP +Exactly like al_clone_menu(3), except that the copy is for a popup menu. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_clone_menu(3) diff --git a/allegro/docs/man/al_clone_path.3 b/allegro/docs/man/al_clone_path.3 new file mode 100644 index 00000000..c6500216 --- /dev/null +++ b/allegro/docs/man/al_clone_path.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_clone_path" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_clone_path - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Clones an ALLEGRO_PATH structure. +Returns NULL on failure. +.SH SEE ALSO +.PP +al_destroy_path(3) diff --git a/allegro/docs/man/al_close_directory.3 b/allegro/docs/man/al_close_directory.3 new file mode 100644 index 00000000..21f705c1 --- /dev/null +++ b/allegro/docs/man/al_close_directory.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_close_directory" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_close_directory - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_close_directory(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Closes a previously opened directory entry object. +.PP +Returns true on success, false on failure and fills in Allegro\[cq]s +errno to indicate the error. +.SH SEE ALSO +.PP +al_open_directory(3), al_read_directory(3) diff --git a/allegro/docs/man/al_close_native_text_log.3 b/allegro/docs/man/al_close_native_text_log.3 new file mode 100644 index 00000000..4b353d53 --- /dev/null +++ b/allegro/docs/man/al_close_native_text_log.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_close_native_text_log" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_close_native_text_log - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_close_native_text_log(ALLEGRO_TEXTLOG *textlog) +\f[R] +.fi +.SH DESCRIPTION +.PP +Closes a message log window opened with al_open_native_text_log(3) +earlier. +.PP +Does nothing if passed NULL. +.SH SEE ALSO +.PP +al_open_native_text_log(3) diff --git a/allegro/docs/man/al_close_video.3 b/allegro/docs/man/al_close_video.3 new file mode 100644 index 00000000..9cdb64e2 --- /dev/null +++ b/allegro/docs/man/al_close_video.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_close_video" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_close_video - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_close_video(ALLEGRO_VIDEO *video) +\f[R] +.fi +.SH DESCRIPTION +.PP +Closes the video and frees all allocated resources. +The video pointer is invalid after the function returns. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_color_cmyk.3 b/allegro/docs/man/al_color_cmyk.3 new file mode 100644 index 00000000..e4b95cff --- /dev/null +++ b/allegro/docs/man/al_color_cmyk.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_cmyk" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_cmyk - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_cmyk(float c, float m, float y, float k) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) structure from CMYK values (cyan, magenta, +yellow, black). +.SH SEE ALSO +.PP +al_color_cmyk_to_rgb(3), al_color_rgb_to_cmyk(3) diff --git a/allegro/docs/man/al_color_cmyk_to_rgb.3 b/allegro/docs/man/al_color_cmyk_to_rgb.3 new file mode 100644 index 00000000..cf67d4a1 --- /dev/null +++ b/allegro/docs/man/al_color_cmyk_to_rgb.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_cmyk_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_cmyk_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_cmyk_to_rgb(float cyan, float magenta, float yellow, + float key, float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert CMYK values to RGB values. +.SH SEE ALSO +.PP +al_color_cmyk(3), al_color_rgb_to_cmyk(3) diff --git a/allegro/docs/man/al_color_distance_ciede2000.3 b/allegro/docs/man/al_color_distance_ciede2000.3 new file mode 100644 index 00000000..9e5180c2 --- /dev/null +++ b/allegro/docs/man/al_color_distance_ciede2000.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_distance_ciede2000" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_distance_ciede2000 - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_color_distance_ciede2000(ALLEGRO_COLOR color1, + ALLEGRO_COLOR color2) { +\f[R] +.fi +.SH DESCRIPTION +.PP +This function computes the CIEDE2000 color difference between two RGB +colors. +This is a visually uniform color difference, unlike for example the RGB +distance. +.PP +When using the RGB distance (Euklidean distance between two RGB +triplets) there can be color pairs with the same distance, where the +colors of one pair appear to be almost the same color, while the colors +of the other pair look quite different. +This is improved by using the L*a*b* color space which was designed with +perceptual uniformity in mind. +However it still is not completely uniform. +The CIEDE2000 formula contains some additional transformations to fix +that. +.PP +The returned color distance is roughly in the range 0 (identical color) +to 1 (completely different color) - but values greater than one are +possible. +.RS +.PP +Note: This function uses al_color_lab(3) internally which defines the L +component to be in the range 0..1 (and not 0..100 as is sometimes seen). +.RE +.SH SINCE +.PP +5.2.3 diff --git a/allegro/docs/man/al_color_hsl.3 b/allegro/docs/man/al_color_hsl.3 new file mode 100644 index 00000000..34efdc36 --- /dev/null +++ b/allegro/docs/man/al_color_hsl.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_hsl" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_hsl - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_hsl(float h, float s, float l) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) structure from HSL (hue, saturation, +lightness) values. +.PP +Parameters: +.IP \[bu] 2 +hue - Color hue angle in the range 0..360 +.IP \[bu] 2 +saturation - Color saturation in the range 0..1 +.IP \[bu] 2 +lightness - Color lightness in the range 0..1 +.SH SEE ALSO +.PP +al_color_hsl_to_rgb(3), al_color_hsv(3) diff --git a/allegro/docs/man/al_color_hsl_to_rgb.3 b/allegro/docs/man/al_color_hsl_to_rgb.3 new file mode 100644 index 00000000..655eb32c --- /dev/null +++ b/allegro/docs/man/al_color_hsl_to_rgb.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_hsl_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_hsl_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_hsl_to_rgb(float hue, float saturation, float lightness, + float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert values in HSL color model to RGB color model. +.PP +Parameters: +.IP \[bu] 2 +hue - Color hue angle in the range 0..360 +.IP \[bu] 2 +saturation - Color saturation in the range 0..1 +.IP \[bu] 2 +lightness - Color lightness in the range 0..1 +.IP \[bu] 2 +red, green, blue - returned RGB values in the range 0..1 +.SH SEE ALSO +.PP +al_color_rgb_to_hsl(3), al_color_hsl(3), al_color_hsv_to_rgb(3) diff --git a/allegro/docs/man/al_color_hsv.3 b/allegro/docs/man/al_color_hsv.3 new file mode 100644 index 00000000..67813603 --- /dev/null +++ b/allegro/docs/man/al_color_hsv.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_hsv" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_hsv - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_hsv(float h, float s, float v) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) structure from HSV (hue, saturation, value) +values. +.PP +Parameters: +.IP \[bu] 2 +hue - Color hue angle in the range 0..360 +.IP \[bu] 2 +saturation - Color saturation in the range 0..1 +.IP \[bu] 2 +value - Color value in the range 0..1 +.SH SEE ALSO +.PP +al_color_hsv_to_rgb(3), al_color_hsl(3) diff --git a/allegro/docs/man/al_color_hsv_to_rgb.3 b/allegro/docs/man/al_color_hsv_to_rgb.3 new file mode 100644 index 00000000..db171803 --- /dev/null +++ b/allegro/docs/man/al_color_hsv_to_rgb.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_hsv_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_hsv_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_hsv_to_rgb(float hue, float saturation, float value, + float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert values in HSV color model to RGB color model. +.PP +Parameters: +.IP \[bu] 2 +hue - Color hue angle in the range 0..360 +.IP \[bu] 2 +saturation - Color saturation in the range 0..1 +.IP \[bu] 2 +value - Color value in the range 0..1 +.IP \[bu] 2 +red, green, blue - returned RGB values in the range 0..1 +.SH SEE ALSO +.PP +al_color_rgb_to_hsv(3), al_color_hsv(3), al_color_hsl_to_rgb(3) diff --git a/allegro/docs/man/al_color_html.3 b/allegro/docs/man/al_color_html.3 new file mode 100644 index 00000000..64016ee6 --- /dev/null +++ b/allegro/docs/man/al_color_html.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_html" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_html - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_html(char const *string) +\f[R] +.fi +.SH DESCRIPTION +.PP +Interprets an HTML-style hex number (e.g.\ #00faff) as a color. +The accepted format is the same as al_color_html_to_rgb(3). +.PP +Returns the interpreted color, or \f[C]al_map_rgba(0, 0, 0, 0)\f[R] if +the string could not be parsed. +.RS +.PP +\f[I]Note\f[R]: the behaviour on invalid strings is different from +Allegro 5.0.x. +.RE +.SH SEE ALSO +.PP +al_color_html_to_rgb(3), al_color_rgb_to_html(3) diff --git a/allegro/docs/man/al_color_html_to_rgb.3 b/allegro/docs/man/al_color_html_to_rgb.3 new file mode 100644 index 00000000..793fbc35 --- /dev/null +++ b/allegro/docs/man/al_color_html_to_rgb.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_html_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_html_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_color_html_to_rgb(char const *string, + float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Interprets an HTML-style hex number (e.g.\ #00faff) as a color. +The only accepted formats are \[lq]#RRGGBB\[rq] and \[lq]RRGGBB\[rq] +where R, G, B are hexadecimal digits [0-9A-Fa-f]. +.PP +Returns true on success, false on failure. +On failure all components are set to zero. +.RS +.PP +\f[I]Note\f[R]: the behaviour on invalid strings is different from +Allegro 5.0.x. +.RE +.SH SEE ALSO +.PP +al_color_html(3), al_color_rgb_to_html(3) diff --git a/allegro/docs/man/al_color_lab.3 b/allegro/docs/man/al_color_lab.3 new file mode 100644 index 00000000..ce3496a1 --- /dev/null +++ b/allegro/docs/man/al_color_lab.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_lab" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_lab - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_lab(float l, float a, float b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) structure from CIE L*a*b* values. +The L* component corresponds to luminance from 0..1. +The a* and b* components are in the range -1..+1. +.RS +.PP +\f[I]Note:\f[R] +.PP +The L*a*b* color space can represent more colors than are visible in +sRGB and therefore conversion may result in RGB values outside of the +0..1 range. +You can check for that case with al_is_color_valid(3). +.RE +.RS +.PP +\f[I]Note:\f[R] +.PP +In some literature the range of L* is 0 to 100 and a* and b* are from +-100 to +100. +In that case divide all components by 100 before passing them to this +function. +.RE +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_lab_to_rgb(3), al_color_rgb_to_lab(3) diff --git a/allegro/docs/man/al_color_lab_to_rgb.3 b/allegro/docs/man/al_color_lab_to_rgb.3 new file mode 100644 index 00000000..31b33358 --- /dev/null +++ b/allegro/docs/man/al_color_lab_to_rgb.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_lab_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_lab_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_lab_to_rgb(float l, float a, float b, + float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert CIE L*a*b* color values to RGB color space. +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_lab(3), al_color_rgb_to_lab(3) diff --git a/allegro/docs/man/al_color_lch.3 b/allegro/docs/man/al_color_lch.3 new file mode 100644 index 00000000..e4ee2922 --- /dev/null +++ b/allegro/docs/man/al_color_lch.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_lch" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_lch - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_lch(float l, float c, float h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) structure from CIE LCH values. +LCH colors are very similar to HSL, with the same meaning of L and H and +C corresponding to S. +However LCH is more visually uniform. +Furthermore, this function expects the angle for H in radians and not in +degree. +.PP +The CIE LCH color space is a cylindrical representation of the L*a*b* +color space. +The L component is the same and C and H are computed like this: +.IP +.nf +\f[C] +C = sqrt(a * a + b * b) +H = atan2(b, a) +\f[R] +.fi +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_lch_to_rgb(3), al_color_rgb_to_lch(3) diff --git a/allegro/docs/man/al_color_lch_to_rgb.3 b/allegro/docs/man/al_color_lch_to_rgb.3 new file mode 100644 index 00000000..9e383dc3 --- /dev/null +++ b/allegro/docs/man/al_color_lch_to_rgb.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_lch_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_lch_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_lch_to_rgb(float l, float c, float h, + float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert CIE LCH color values to RGB color space. +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_lch(3), al_color_rgb_to_lch(3) diff --git a/allegro/docs/man/al_color_name.3 b/allegro/docs/man/al_color_name.3 new file mode 100644 index 00000000..bf474aa2 --- /dev/null +++ b/allegro/docs/man/al_color_name.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_name(char const *name) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) with the given name. +If the color is not found then black is returned. +.PP +See al_color_name_to_rgb(3) for the list of names. diff --git a/allegro/docs/man/al_color_name_to_rgb.3 b/allegro/docs/man/al_color_name_to_rgb.3 new file mode 100644 index 00000000..a0db07c3 --- /dev/null +++ b/allegro/docs/man/al_color_name_to_rgb.3 @@ -0,0 +1,65 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_name_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_name_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_color_name_to_rgb(char const *name, float *r, float *g, float *b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Parameters: +.IP \[bu] 2 +name - The (lowercase) name of the color. +.IP \[bu] 2 +r, g, b - If one of the recognized color names below is passed, the +corresponding RGB values in the range 0..1 are written. +.PP +The 148 recognized names are: +.RS +.PP +aliceblue, antiquewhite, aqua, aquamarine, azure, beige, bisque, black, +blanchedalmond, blue, blueviolet, brown, burlywood, cadetblue, +chartreuse, chocolate, coral, cornflowerblue, cornsilk, crimson, cyan, +darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, darkkhaki, +darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, +darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, +darkviolet, deeppink, deepskyblue, dimgray, dodgerblue, firebrick, +floralwhite, forestgreen, fuchsia, gainsboro, ghostwhite, goldenrod, +gold, gray, green, greenyellow, honeydew, hotpink, indianred, indigo, +ivory, khaki, lavenderblush, lavender, lawngreen, lemonchiffon, +lightblue, lightcoral, lightcyan, lightgoldenrodyellow, lightgreen, +lightgrey, lightpink, lightsalmon, lightseagreen, lightskyblue, +lightslategray, lightsteelblue, lightyellow, lime, limegreen, linen, +magenta, maroon, mediumaquamarine, mediumblue, mediumorchid, +mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen, +mediumturquoise, mediumvioletred, midnightblue, mintcream, mistyrose, +moccasin, avajowhite, navy, oldlace, olive, olivedrab, orange, +orangered, orchid, palegoldenrod, palegreen, paleturquoise, +palevioletred, papayawhip, peachpuff, peru, pink, plum, powderblue, +purple, rebeccapurple, red, rosybrown, royalblue, saddlebrown, salmon, +sandybrown, seagreen, seashell, sienna, silver, skyblue, slateblue, +slategray, snow, springgreen, steelblue, tan, teal, thistle, tomato, +turquoise, violet, wheat, white, whitesmoke, yellow, yellowgreen +.RE +.PP +They are taken from CSS: +.PP +Note that these 9 colors have two names and so there are only 139 +distinct colors: aqua = cyan, darkgray = darkgrey, darkslategray = +darkslategrey, dimgray = dimgrey, fuchsia = purple, gray = grey, +lightgray = lightgrey, lightslategray = lightslategrey, slategray = +slategrey +.PP +Returns: true if a name from the list above was passed, else false. +.SH SEE ALSO +.PP +al_color_name(3) diff --git a/allegro/docs/man/al_color_rgb_to_cmyk.3 b/allegro/docs/man/al_color_rgb_to_cmyk.3 new file mode 100644 index 00000000..5c4f1534 --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_cmyk.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_cmyk" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_cmyk - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_cmyk(float red, float green, float blue, + float *cyan, float *magenta, float *yellow, float *key) +\f[R] +.fi +.SH DESCRIPTION +.PP +Each RGB color can be represented in CMYK with a K component of 0 with +the following formula: +.IP +.nf +\f[C] +C = 1 - R +M = 1 - G +Y = 1 - B +K = 0 +\f[R] +.fi +.PP +This function will instead find the representation with the maximal +value for K and minimal color components. +.SH SEE ALSO +.PP +al_color_cmyk(3), al_color_cmyk_to_rgb(3) diff --git a/allegro/docs/man/al_color_rgb_to_hsl.3 b/allegro/docs/man/al_color_rgb_to_hsl.3 new file mode 100644 index 00000000..620df743 --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_hsl.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_hsl" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_hsl - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_hsl(float red, float green, float blue, + float *hue, float *saturation, float *lightness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Given an RGB triplet with components in the range 0..1, return the hue +in degrees from 0..360 and saturation and lightness in the range 0..1. +.SH SEE ALSO +.PP +al_color_hsl_to_rgb(3), al_color_hsl(3) diff --git a/allegro/docs/man/al_color_rgb_to_hsv.3 b/allegro/docs/man/al_color_rgb_to_hsv.3 new file mode 100644 index 00000000..2246b1fb --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_hsv.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_hsv" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_hsv - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_hsv(float red, float green, float blue, + float *hue, float *saturation, float *value) +\f[R] +.fi +.SH DESCRIPTION +.PP +Given an RGB triplet with components in the range 0..1, return the hue +in degrees from 0..360 and saturation and value in the range 0..1. +.SH SEE ALSO +.PP +al_color_hsv_to_rgb(3), al_color_hsv(3) diff --git a/allegro/docs/man/al_color_rgb_to_html.3 b/allegro/docs/man/al_color_rgb_to_html.3 new file mode 100644 index 00000000..a84094f3 --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_html.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_html" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_html - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_html(float red, float green, float blue, + char *string) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create an HTML-style string representation of an ALLEGRO_COLOR(3), +e.g.\ #00faff. +.PP +Parameters: +.IP \[bu] 2 +red, green, blue - The color components in the range 0..1. +.IP \[bu] 2 +string - A pointer to a buffer of at least 8 bytes, into which the +result will be written (including the NUL terminator). +.PP +Example: +.IP +.nf +\f[C] +char html[8]; +al_color_rgb_to_html(1, 0, 0, html); +\f[R] +.fi +.PP +Now html will contain \[lq]#ff0000\[rq]. +.SH SEE ALSO +.PP +al_color_html(3), al_color_html_to_rgb(3) diff --git a/allegro/docs/man/al_color_rgb_to_lab.3 b/allegro/docs/man/al_color_rgb_to_lab.3 new file mode 100644 index 00000000..6283708b --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_lab.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_lab" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_lab - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_lab(float red, float green, float blue, + float *l, float *a, float *b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert RGB values to L*a*b* color space. +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_lab(3), al_color_lab_to_rgb(3) diff --git a/allegro/docs/man/al_color_rgb_to_lch.3 b/allegro/docs/man/al_color_rgb_to_lch.3 new file mode 100644 index 00000000..3f593e8b --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_lch.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_lch" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_lch - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_lch(float red, float green, float blue, + float *l, float *c, float *h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert RGB values to CIE LCH color space. +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_lch(3), al_color_lch_to_rgb(3) diff --git a/allegro/docs/man/al_color_rgb_to_name.3 b/allegro/docs/man/al_color_rgb_to_name.3 new file mode 100644 index 00000000..ed064edb --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_name.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char const *al_color_rgb_to_name(float r, float g, float b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Given an RGB triplet with components in the range 0..1, find a color +name describing it approximately. +.SH SEE ALSO +.PP +al_color_name_to_rgb(3), al_color_name(3) diff --git a/allegro/docs/man/al_color_rgb_to_xyy.3 b/allegro/docs/man/al_color_rgb_to_xyy.3 new file mode 100644 index 00000000..0ada2082 --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_xyy.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_xyy" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_xyy - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_xyy(float red, float green, float blue, + float *x, float *y, float *y2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert RGB values to xyY color space. +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_xyy(3), al_color_xyy_to_rgb(3) diff --git a/allegro/docs/man/al_color_rgb_to_xyz.3 b/allegro/docs/man/al_color_rgb_to_xyz.3 new file mode 100644 index 00000000..f570ae4f --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_xyz.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_xyz" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_xyz - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_xyz(float red, float green, float blue, + float *x, float *y, float *z) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert RGB values to XYZ color space. +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_xyz(3), al_color_xyz_to_rgb(3) diff --git a/allegro/docs/man/al_color_rgb_to_yuv.3 b/allegro/docs/man/al_color_rgb_to_yuv.3 new file mode 100644 index 00000000..13ac5574 --- /dev/null +++ b/allegro/docs/man/al_color_rgb_to_yuv.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_rgb_to_yuv" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_rgb_to_yuv - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_rgb_to_yuv(float red, float green, float blue, + float *y, float *u, float *v) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert RGB values to YUV color space. +.SH SEE ALSO +.PP +al_color_yuv(3), al_color_yuv_to_rgb(3) diff --git a/allegro/docs/man/al_color_xyy.3 b/allegro/docs/man/al_color_xyy.3 new file mode 100644 index 00000000..6543c41b --- /dev/null +++ b/allegro/docs/man/al_color_xyy.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_xyy" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_xyy - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_xyy(float x, float y, float y2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) structure from xyY values. +The Y component in the xyY color space is the same as the Y in XYZ. +.PP +However the x and y values are computed from XYZ like this: +.IP +.nf +\f[C] +x = X / (X + Y + Z) +y = Y / (X + Y + Z) +\f[R] +.fi +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_xyy_to_rgb(3), al_color_rgb_to_xyy(3) diff --git a/allegro/docs/man/al_color_xyy_to_rgb.3 b/allegro/docs/man/al_color_xyy_to_rgb.3 new file mode 100644 index 00000000..c610fc06 --- /dev/null +++ b/allegro/docs/man/al_color_xyy_to_rgb.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_xyy_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_xyy_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_xyy_to_rgb(float x, float y, float y2, + float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert xyY color values to RGB color space. +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_xyy(3), al_color_rgb_to_xyy(3) diff --git a/allegro/docs/man/al_color_xyz.3 b/allegro/docs/man/al_color_xyz.3 new file mode 100644 index 00000000..67bcee96 --- /dev/null +++ b/allegro/docs/man/al_color_xyz.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_xyz" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_xyz - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_xyz(float x, float y, float z) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) structure from XYZ values. +The CIE 1931 XYZ color space consists of three components in the range +0..1. +The Y component corresponds to luminance and the X and Z components +define the color. +.PP +RGB components are always assumed to be in sRGB space. +.RS +.PP +\f[I]Note:\f[R] +.PP +The XYZ color space can represent more colors than are visible in sRGB +and therefore conversion may result in RGB values outside of the 0..1 +range. +You can check for that case with al_is_color_valid(3). +.RE +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_xyz_to_rgb(3), al_color_rgb_to_xyz(3) diff --git a/allegro/docs/man/al_color_xyz_to_rgb.3 b/allegro/docs/man/al_color_xyz_to_rgb.3 new file mode 100644 index 00000000..d9b871f2 --- /dev/null +++ b/allegro/docs/man/al_color_xyz_to_rgb.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_xyz_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_xyz_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_xyz_to_rgb(float x, float y, float z, + float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert XYZ color values to RGB color space. +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_color_xyz(3), al_color_rgb_to_xyz(3) diff --git a/allegro/docs/man/al_color_yuv.3 b/allegro/docs/man/al_color_yuv.3 new file mode 100644 index 00000000..516ed17a --- /dev/null +++ b/allegro/docs/man/al_color_yuv.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_yuv" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_yuv - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_color_yuv(float y, float u, float v) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an ALLEGRO_COLOR(3) structure from YUV values. +.SH SEE ALSO +.PP +al_color_yuv_to_rgb(3), al_color_rgb_to_yuv(3) diff --git a/allegro/docs/man/al_color_yuv_to_rgb.3 b/allegro/docs/man/al_color_yuv_to_rgb.3 new file mode 100644 index 00000000..a78fc844 --- /dev/null +++ b/allegro/docs/man/al_color_yuv_to_rgb.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_color_yuv_to_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_color_yuv_to_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_color_yuv_to_rgb(float y, float u, float v, + float *red, float *green, float *blue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert YUV color values to RGB color space. +.SH SEE ALSO +.PP +al_color_yuv(3), al_color_rgb_to_yuv(3) diff --git a/allegro/docs/man/al_compose_transform.3 b/allegro/docs/man/al_compose_transform.3 new file mode 100644 index 00000000..7c5a48f1 --- /dev/null +++ b/allegro/docs/man/al_compose_transform.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_compose_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_compose_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_compose_transform(ALLEGRO_TRANSFORM *trans, const ALLEGRO_TRANSFORM *other) +\f[R] +.fi +.SH DESCRIPTION +.PP +Compose (combine) two transformations by a matrix multiplication. +.IP +.nf +\f[C] +trans := trans other +\f[R] +.fi +.PP +Note that the order of matrix multiplications is important. +The effect of applying the combined transform will be as if first +applying \f[C]trans\f[R] and then applying \f[C]other\f[R] and not the +other way around. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to alter +.IP \[bu] 2 +other - Transformation used to transform \f[C]trans\f[R] +.SH SEE ALSO +.PP +al_translate_transform(3), al_rotate_transform(3), al_scale_transform(3) diff --git a/allegro/docs/man/al_convert_bitmap.3 b/allegro/docs/man/al_convert_bitmap.3 new file mode 100644 index 00000000..c70b02f9 --- /dev/null +++ b/allegro/docs/man/al_convert_bitmap.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_convert_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_convert_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_convert_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Converts the bitmap to the current bitmap flags and format. +The bitmap will be as if it was created anew with al_create_bitmap(3) +but retain its contents. +All of this bitmap\[cq]s sub-bitmaps are also converted. +If the new bitmap type is memory, then the bitmap\[cq]s projection +bitmap is reset to be orthographic. +.PP +If this bitmap is a sub-bitmap, then it, its parent and all the sibling +sub-bitmaps are also converted. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_create_bitmap(3), al_set_new_bitmap_format(3), +al_set_new_bitmap_flags(3), al_clone_bitmap(3) diff --git a/allegro/docs/man/al_convert_mask_to_alpha.3 b/allegro/docs/man/al_convert_mask_to_alpha.3 new file mode 100644 index 00000000..6ce95ed1 --- /dev/null +++ b/allegro/docs/man/al_convert_mask_to_alpha.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_convert_mask_to_alpha" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_convert_mask_to_alpha - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_convert_mask_to_alpha(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert the given mask color to an alpha channel in the bitmap. +Can be used to convert older 4.2-style bitmaps with magic pink to +alpha-ready bitmaps. +.SH SEE ALSO +.PP +ALLEGRO_COLOR(3) diff --git a/allegro/docs/man/al_convert_memory_bitmaps.3 b/allegro/docs/man/al_convert_memory_bitmaps.3 new file mode 100644 index 00000000..221415d2 --- /dev/null +++ b/allegro/docs/man/al_convert_memory_bitmaps.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_convert_memory_bitmaps" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_convert_memory_bitmaps - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_convert_memory_bitmaps(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +If you create a bitmap when there is no current display (for example +because you have not called al_create_display(3) in the current thread) +and are using the ALLEGRO_CONVERT_BITMAP bitmap flag (which is set by +default) then the bitmap will be created successfully, but as a memory +bitmap. +This function converts all such bitmaps to proper video bitmaps +belonging to the current display. +.PP +Note that video bitmaps get automatically converted back to memory +bitmaps when the last display is destroyed. +.PP +This operation will preserve all bitmap flags except +ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP. +.SH SINCE +.PP +5.2.0 +.SH SEE ALSO +.PP +al_convert_bitmap(3), al_create_bitmap(3) diff --git a/allegro/docs/man/al_copy_transform.3 b/allegro/docs/man/al_copy_transform.3 new file mode 100644 index 00000000..b4c01bdf --- /dev/null +++ b/allegro/docs/man/al_copy_transform.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_copy_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_copy_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_copy_transform(ALLEGRO_TRANSFORM *dest, const ALLEGRO_TRANSFORM *src) +\f[R] +.fi +.SH DESCRIPTION +.PP +Makes a copy of a transformation. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +dest - Source transformation +.IP \[bu] 2 +src - Destination transformation diff --git a/allegro/docs/man/al_create_audio_recorder.3 b/allegro/docs/man/al_create_audio_recorder.3 new file mode 100644 index 00000000..8c925a7d --- /dev/null +++ b/allegro/docs/man/al_create_audio_recorder.3 @@ -0,0 +1,65 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_audio_recorder" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_audio_recorder - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_RECORDER *al_create_audio_recorder(size_t fragment_count, + unsigned int samples, unsigned int frequency, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates an audio recorder using the system\[cq]s default recording +device. +(So if the returned device does not work, try updating the system\[cq]s +default recording device.) +.PP +Allegro will internally buffer several seconds of captured audio with +minimal latency. +(XXX: These settings need to be exposed via config or API calls.) Audio +will be copied out of that private buffer into a fragment buffer of the +size specified by the samples parameter. +Whenever a new fragment is ready an event will be generated. +.PP +The total size of the fragment buffer is fragment_count * samples * +bytes_per_sample. +It is treated as a circular, never ending buffer. +If you do not process the information fast enough, it will be overrun. +Because of that, even if you only ever need to process one small +fragment at a time, you should still use a large enough value for +fragment_count to hold a few seconds of audio. +.PP +frequency is the number of samples per second to record. +Common values are: +.IP \[bu] 2 +8000 - telephone quality speech +.IP \[bu] 2 +11025 +.IP \[bu] 2 +22050 +.IP \[bu] 2 +44100 - CD quality music (if 16-bit, stereo) +.PP +For maximum compatibility, use a depth of ALLEGRO_AUDIO_DEPTH_UINT8 or +ALLEGRO_AUDIO_DEPTH_INT16, and a single (mono) channel. +.PP +The recorder will not record until you start it with +al_start_audio_recorder(3). +.PP +On failure, returns NULL. +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/al_create_audio_stream.3 b/allegro/docs/man/al_create_audio_stream.3 new file mode 100644 index 00000000..e696defe --- /dev/null +++ b/allegro/docs/man/al_create_audio_stream.3 @@ -0,0 +1,101 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_audio_stream" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_audio_stream - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_STREAM *al_create_audio_stream(size_t fragment_count, + unsigned int frag_samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, + ALLEGRO_CHANNEL_CONF chan_conf) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates an ALLEGRO_AUDIO_STREAM(3). +The stream will be set to play by default. +It will feed audio data from a buffer, which is split into a number of +fragments. +.PP +Parameters: +.IP \[bu] 2 +fragment_count - How many fragments to use for the audio stream. +Usually only two fragments are required - splitting the audio buffer in +two halves. +But it means that the only time when new data can be supplied is +whenever one half has finished playing. +When using many fragments, you usually will use fewer samples for one, +so there always will be (small) fragments available to be filled with +new data. +.IP \[bu] 2 +frag_samples - The size of a fragment in samples. +See note and explanation below. +.IP \[bu] 2 +freq - The frequency, in Hertz. +.IP \[bu] 2 +depth - Must be one of the values listed for ALLEGRO_AUDIO_DEPTH(3). +.IP \[bu] 2 +chan_conf - Must be one of the values listed for +ALLEGRO_CHANNEL_CONF(3). +.PP +A sample that is referred to by the \f[I]frag_samples\f[R] parameter +refers to a sequence channel intensities. +E.g. +if you\[cq]re making a stereo stream with the \f[I]frag_samples\f[R] set +to 4, then the layout of the data in the fragment will be: +.IP +.nf +\f[C] +LRLRLRLR +\f[R] +.fi +.PP +Where L and R are the intensities for the left and right channels +respectively. +A single sample, then, refers to the LR pair in this example. +.PP +The choice of \f[I]fragment_count\f[R], \f[I]frag_samples\f[R] and +\f[I]freq\f[R] directly influences the audio delay. +The delay in seconds can be expressed as: +.IP +.nf +\f[C] +delay = fragment_count * frag_samples / freq +\f[R] +.fi +.PP +This is only the delay due to Allegro\[cq]s streaming, there may be +additional delay caused by sound drivers and/or hardware. +.RS +.PP +\f[I]Note:\f[R] If you know the fragment size in bytes, you can get the +size in samples like this: +.IP +.nf +\f[C] +sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth); +samples = bytes_per_fragment / sample_size; +\f[R] +.fi +.PP +The size of the complete buffer is: +.IP +.nf +\f[C] +buffer_size = bytes_per_fragment * fragment_count +\f[R] +.fi +.RE +.RS +.PP +\f[I]Note:\f[R] Unlike many Allegro objects, audio streams are not +implicitly destroyed when Allegro is shut down. +You must destroy them manually with al_destroy_audio_stream(3) before +the audio system is shut down. +.RE diff --git a/allegro/docs/man/al_create_bitmap.3 b/allegro/docs/man/al_create_bitmap.3 new file mode 100644 index 00000000..a02e54e8 --- /dev/null +++ b/allegro/docs/man/al_create_bitmap.3 @@ -0,0 +1,85 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_create_bitmap(int w, int h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a new bitmap using the bitmap format and flags for the current +thread. +Blitting between bitmaps of differing formats, or blitting between +memory bitmaps and display bitmaps may be slow. +.PP +Unless you set the ALLEGRO_MEMORY_BITMAP flag, the bitmap is created for +the current display. +Blitting to another display may be slow. +.PP +If a display bitmap is created, there may be limitations on the allowed +dimensions. +For example a DirectX or OpenGL backend usually has a maximum allowed +texture size - so if bitmap creation fails for very large dimensions, +you may want to re-try with a smaller bitmap. +Some platforms also dictate a minimum texture size, which is relevant if +you plan to use this bitmap with the primitives addon. +If you try to create a bitmap smaller than this, this call will not fail +but the returned bitmap will be a section of a larger bitmap with the +minimum size. +The minimum size that will work on all platforms is 32 by 32. +There is an experimental switch to turns this padding off by editing the +system configuration (see \f[C]min_bitmap_size\f[R] key in +al_get_system_config(3)). +.PP +Some platforms do not directly support display bitmaps whose dimensions +are not powers of two. +Allegro handles this by creating a larger bitmap that has dimensions +that are powers of two and then returning a section of that bitmap with +the dimensions you requested. +This can be relevant if you plan to use this bitmap with the primitives +addon but shouldn\[cq]t be an issue otherwise. +.PP +If you create a bitmap without ALLEGRO_MEMORY_BITMAP set but there is no +current display, a temporary memory bitmap will be created instead. +You can later convert all such bitmap to video bitmap and assign to a +display by calling al_convert_memory_bitmaps(3). +.PP +On some platforms the contents of video bitmaps may be lost when your +application loses focus. +Allegro has an internal mechanism to restore the contents of these video +bitmaps, but it is not foolproof (sometimes bitmap contents can get lost +permanently) and has performance implications. +If you are using a bitmap as an intermediate buffer this mechanism may +be wasteful. +In this case, if you do not want Allegro to manage the bitmap contents +for you, you can disable this mechanism by creating the bitmap with the +ALLEGRO_NO_PRESERVE_TEXTURE flag. +The bitmap contents are lost when you get the ALLEGRO_EVENT_DISPLAY_LOST +and ALLEGRO_EVENT_DISPLAY_HALT_DRAWING and a should be restored when you +get the ALLEGRO_EVENT_DISPLAY_FOUND and when you call +al_acknowledge_drawing_resume(3) (after +ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING event). +You can use those events to implement your own bitmap content +restoration mechanism if Allegro\[cq]s does not work well enough for you +(for example, you can reload them all from disk). +.PP +\f[I]Note\f[R]: The contents of a newly created bitmap are undefined - +you need to clear the bitmap or make sure all pixels get overwritten +before drawing it. +.PP +When you are done with using the bitmap you must call +al_destroy_bitmap(3) on it to free any resources allocated for it. +.SH SEE ALSO +.PP +al_set_new_bitmap_format(3), al_set_new_bitmap_flags(3), +al_clone_bitmap(3), al_create_sub_bitmap(3), +al_convert_memory_bitmaps(3), al_destroy_bitmap(3) diff --git a/allegro/docs/man/al_create_builtin_font.3 b/allegro/docs/man/al_create_builtin_font.3 new file mode 100644 index 00000000..8f7c05c4 --- /dev/null +++ b/allegro/docs/man/al_create_builtin_font.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_builtin_font" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_builtin_font - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_create_builtin_font(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a monochrome bitmap font (8x8 pixels per character). +.PP +This font is primarily intended to be used for displaying information in +environments or during early runtime states where no external font data +is available or loaded (e.g.\ for debugging). +.PP +The builtin font contains the following unicode character ranges: +.IP +.nf +\f[C] +0x0020 to 0x007F (ASCII) +0x00A1 to 0x00FF (Latin 1) +0x0100 to 0x017F (Extended A) +0x20AC to 0x20AC (euro currency symbol) +\f[R] +.fi +.PP +Returns NULL on an error. +.PP +The font memory must be freed the same way as for any other font, using +al_destroy_font(3). +.SH SINCE +.PP +5.0.8, 5.1.3 +.SH SEE ALSO +.PP +al_load_bitmap_font(3), al_destroy_font(3) diff --git a/allegro/docs/man/al_create_cond.3 b/allegro/docs/man/al_create_cond.3 new file mode 100644 index 00000000..1e595797 --- /dev/null +++ b/allegro/docs/man/al_create_cond.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_cond" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_cond - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COND *al_create_cond(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a condition variable. +.PP +Returns the condition value on success or \f[C]NULL\f[R] on error. diff --git a/allegro/docs/man/al_create_config.3 b/allegro/docs/man/al_create_config.3 new file mode 100644 index 00000000..841147ad --- /dev/null +++ b/allegro/docs/man/al_create_config.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_config" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_config - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CONFIG *al_create_config(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create an empty configuration structure. +.SH SEE ALSO +.PP +al_load_config_file(3), al_destroy_config(3) diff --git a/allegro/docs/man/al_create_display.3 b/allegro/docs/man/al_create_display.3 new file mode 100644 index 00000000..8f191157 --- /dev/null +++ b/allegro/docs/man/al_create_display.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_display" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_display - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_DISPLAY *al_create_display(int w, int h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a display, or window, with the specified dimensions. +The parameters of the display are determined by the last calls to +al_set_new_display_*. +Default parameters are used if none are set explicitly. +Creating a new display will automatically make it the active one, with +the backbuffer selected for drawing. +.PP +Returns NULL on error. +.PP +Each display that uses OpenGL as a backend has a distinct OpenGL +rendering context associated with it. +See al_set_target_bitmap(3) for the discussion about rendering contexts. +.SH SEE ALSO +.PP +al_set_new_display_flags(3), al_set_new_display_option(3), +al_set_new_display_refresh_rate(3), al_set_new_display_adapter(3), +al_set_new_window_title(3) al_set_window_position(3) diff --git a/allegro/docs/man/al_create_event_queue.3 b/allegro/docs/man/al_create_event_queue.3 new file mode 100644 index 00000000..4e1542ef --- /dev/null +++ b/allegro/docs/man/al_create_event_queue.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_event_queue" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_event_queue - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_QUEUE *al_create_event_queue(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a new, empty event queue, returning a pointer to the newly +created object if successful. +Returns NULL on error. +.SH SEE ALSO +.PP +al_register_event_source(3), al_destroy_event_queue(3), +ALLEGRO_EVENT_QUEUE(3) diff --git a/allegro/docs/man/al_create_file_handle.3 b/allegro/docs/man/al_create_file_handle.3 new file mode 100644 index 00000000..e068a5d0 --- /dev/null +++ b/allegro/docs/man/al_create_file_handle.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_file_handle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_file_handle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILE *al_create_file_handle(const ALLEGRO_FILE_INTERFACE *drv, + void *userdata) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates an empty, opened file handle with some abstract user data. +This allows custom interfaces to extend the ALLEGRO_FILE(3) struct with +their own data. +You should close the handle with the standard al_fclose(3) function when +you are finished with it. +.SH SEE ALSO +.PP +al_fopen(3), al_fclose(3), al_set_new_file_interface(3) diff --git a/allegro/docs/man/al_create_fs_entry.3 b/allegro/docs/man/al_create_fs_entry.3 new file mode 100644 index 00000000..f2d5d46f --- /dev/null +++ b/allegro/docs/man/al_create_fs_entry.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_fs_entry" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_fs_entry - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FS_ENTRY *al_create_fs_entry(const char *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates an ALLEGRO_FS_ENTRY(3) object pointing to path on the +filesystem. +`path' can be a file or a directory and must not be NULL. diff --git a/allegro/docs/man/al_create_index_buffer.3 b/allegro/docs/man/al_create_index_buffer.3 new file mode 100644 index 00000000..da3540d8 --- /dev/null +++ b/allegro/docs/man/al_create_index_buffer.3 @@ -0,0 +1,52 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_index_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_index_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_INDEX_BUFFER* al_create_index_buffer(int index_size, + const void* initial_data, int num_indices, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a index buffer. +Can return NULL if the buffer could not be created (e.g.\ the system +only supports write-only buffers). +.RS +.PP +\f[I]Note:\f[R] +.PP +This is an advanced feature, often unsupported on lower-end video cards. +Be extra mindful of this function failing and make arrangements for +fallback drawing functionality or a nice error message for users with +such lower-end cards. +.RE +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +index_size - Size of the index in bytes. +Supported sizes are 2 for short integers and 4 for integers +.IP \[bu] 2 +initial_data - Memory buffer to copy from to initialize the index +buffer. +Can be \f[C]NULL\f[R], in which case the buffer is uninitialized. +.IP \[bu] 2 +num_indices - Number of indices the buffer will hold +.IP \[bu] 2 +flags - A combination of the ALLEGRO_PRIM_BUFFER_FLAGS(3) flags +specifying how this buffer will be created. +Passing 0 is the same as passing \f[C]ALLEGRO_PRIM_BUFFER_STATIC\f[R]. +.SH SINCE +.PP +5.1.8 +.SH SEE ALSO +.PP +ALLEGRO_INDEX_BUFFER(3), al_destroy_index_buffer(3) diff --git a/allegro/docs/man/al_create_menu.3 b/allegro/docs/man/al_create_menu.3 new file mode 100644 index 00000000..dcdb3948 --- /dev/null +++ b/allegro/docs/man/al_create_menu.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MENU *al_create_menu(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a menu container that can hold menu items. +.PP +Returns \f[C]NULL\f[R] on failure. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_create_popup_menu(3), al_build_menu(3) diff --git a/allegro/docs/man/al_create_mixer.3 b/allegro/docs/man/al_create_mixer.3 new file mode 100644 index 00000000..08e4e894 --- /dev/null +++ b/allegro/docs/man/al_create_mixer.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MIXER *al_create_mixer(unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a mixer to attach sample instances, audio streams, or other +mixers to. +It will mix into a buffer at the requested frequency (in Hz) and channel +count. +.PP +The only supported audio depths are ALLEGRO_AUDIO_DEPTH_FLOAT32 and +ALLEGRO_AUDIO_DEPTH_INT16 (not yet complete). +.PP +To actually produce any output, the mixer will have to be attached to a +voice. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_destroy_mixer(3), ALLEGRO_AUDIO_DEPTH(3), ALLEGRO_CHANNEL_CONF(3) diff --git a/allegro/docs/man/al_create_mouse_cursor.3 b/allegro/docs/man/al_create_mouse_cursor.3 new file mode 100644 index 00000000..67d6134e --- /dev/null +++ b/allegro/docs/man/al_create_mouse_cursor.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_mouse_cursor" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_mouse_cursor - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MOUSE_CURSOR *al_create_mouse_cursor(ALLEGRO_BITMAP *bmp, + int x_focus, int y_focus) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a mouse cursor from the bitmap provided. +\f[C]x_focus\f[R] and \f[C]y_focus\f[R] describe the bit of the cursor +that will represent the actual mouse position. +.PP +Returns a pointer to the cursor on success, or NULL on failure. +.SH SEE ALSO +.PP +al_set_mouse_cursor(3), al_destroy_mouse_cursor(3) diff --git a/allegro/docs/man/al_create_mutex.3 b/allegro/docs/man/al_create_mutex.3 new file mode 100644 index 00000000..6efa71ba --- /dev/null +++ b/allegro/docs/man/al_create_mutex.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_mutex" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_mutex - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MUTEX *al_create_mutex(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create the mutex object (a mutual exclusion device). +The mutex may or may not support \[lq]recursive\[rq] locking. +.PP +Returns the mutex on success or \f[C]NULL\f[R] on error. +.SH SEE ALSO +.PP +al_create_mutex_recursive(3). diff --git a/allegro/docs/man/al_create_mutex_recursive.3 b/allegro/docs/man/al_create_mutex_recursive.3 new file mode 100644 index 00000000..45f65627 --- /dev/null +++ b/allegro/docs/man/al_create_mutex_recursive.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_mutex_recursive" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_mutex_recursive - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MUTEX *al_create_mutex_recursive(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create the mutex object (a mutual exclusion device), with support for +\[lq]recursive\[rq] locking. +That is, the mutex will count the number of times it has been locked by +the same thread. +If the caller tries to acquire a lock on the mutex when it already holds +the lock then the count is incremented. +The mutex is only unlocked when the thread releases the lock on the +mutex an equal number of times, i.e.\ the count drops down to zero. +.SH SEE ALSO +.PP +al_create_mutex(3). diff --git a/allegro/docs/man/al_create_native_file_dialog.3 b/allegro/docs/man/al_create_native_file_dialog.3 new file mode 100644 index 00000000..c412a475 --- /dev/null +++ b/allegro/docs/man/al_create_native_file_dialog.3 @@ -0,0 +1,78 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_native_file_dialog" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_native_file_dialog - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILECHOOSER *al_create_native_file_dialog( + char const *initial_path, + char const *title, + char const *patterns, + int mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a new native file dialog. +You should only have one such dialog opened at a time. +.PP +Parameters: +.IP \[bu] 2 +\f[C]initial_path\f[R]: The initial search path and filename. +Can be NULL. +To start with a blank file name the string should end with a directory +separator (this should be the common case). +.IP \[bu] 2 +\f[C]title\f[R]: Title of the dialog. +.IP \[bu] 2 +\f[C]patterns\f[R]: A list of semi-colon separated patterns to match. +This should not contain any whitespace characters. +If a pattern contains the `/' character, then it is treated as a MIME +type (e.g. +`image/png'). +Not all platforms support file patterns. +If the native dialog does not provide support, this parameter is +ignored. +.IP \[bu] 2 +\f[C]mode\f[R]: 0, or a combination of the following flags: +.TP +ALLEGRO_FILECHOOSER_FILE_MUST_EXIST +If supported by the native dialog, it will not allow entering new names, +but just allow existing files to be selected. +Else it is ignored. +.TP +ALLEGRO_FILECHOOSER_SAVE +If the native dialog system has a different dialog for saving (for +example one which allows creating new directories), it is used. +Else it is ignored. +.TP +ALLEGRO_FILECHOOSER_FOLDER +If there is support for a separate dialog to select a folder instead of +a file, it will be used. +.TP +ALLEGRO_FILECHOOSER_PICTURES +If a different dialog is available for selecting pictures, it is used. +Else it is ignored. +.TP +ALLEGRO_FILECHOOSER_SHOW_HIDDEN +If the platform supports it, also hidden files will be shown. +.TP +ALLEGRO_FILECHOOSER_MULTIPLE +If supported, allow selecting multiple files. +.PP +Returns: +.PP +A handle to the dialog which you can pass to +al_show_native_file_dialog(3) to display it, and from which you then can +query the results using al_get_native_file_dialog_count(3) and +al_get_native_file_dialog_path(3). +When you are done, call al_destroy_native_file_dialog(3) on it. +.PP +If a dialog window could not be created then this function returns NULL. diff --git a/allegro/docs/man/al_create_path.3 b/allegro/docs/man/al_create_path.3 new file mode 100644 index 00000000..d81019e8 --- /dev/null +++ b/allegro/docs/man/al_create_path.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_path" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_path - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_PATH *al_create_path(const char *str) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a path structure from a string. +The last component, if it is followed by a directory separator and is +neither \[lq].\[rq] nor \[lq]..\[rq], is treated as the last directory +name in the path. +Otherwise the last component is treated as the filename. +The string may be NULL for an empty path. +.SH SEE ALSO +.PP +al_create_path_for_directory(3), al_destroy_path(3) diff --git a/allegro/docs/man/al_create_path_for_directory.3 b/allegro/docs/man/al_create_path_for_directory.3 new file mode 100644 index 00000000..561275fa --- /dev/null +++ b/allegro/docs/man/al_create_path_for_directory.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_path_for_directory" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_path_for_directory - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_PATH *al_create_path_for_directory(const char *str) +\f[R] +.fi +.SH DESCRIPTION +.PP +This is the same as al_create_path(3), but interprets the passed string +as a directory path. +The filename component of the returned path will always be empty. +.SH SEE ALSO +.PP +al_create_path(3), al_destroy_path(3) diff --git a/allegro/docs/man/al_create_popup_menu.3 b/allegro/docs/man/al_create_popup_menu.3 new file mode 100644 index 00000000..44cd3d09 --- /dev/null +++ b/allegro/docs/man/al_create_popup_menu.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_popup_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_popup_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MENU *al_create_popup_menu(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a menu container for popup menus. +Only the root (outermost) menu should be created with this function. +Sub menus of popups should be created with al_create_menu(3). +.PP +Returns \f[C]NULL\f[R] on failure. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_create_menu(3), al_build_menu(3) diff --git a/allegro/docs/man/al_create_sample.3 b/allegro/docs/man/al_create_sample.3 new file mode 100644 index 00000000..d501523e --- /dev/null +++ b/allegro/docs/man/al_create_sample.3 @@ -0,0 +1,57 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_sample" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_sample - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SAMPLE *al_create_sample(void *buf, unsigned int samples, + unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, + ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a sample data structure from the supplied buffer. +If \f[C]free_buf\f[R] is true then the buffer will be freed with +al_free(3) when the sample data structure is destroyed. +For portability (especially Windows), the buffer should have been +allocated with al_malloc(3). +Otherwise you should free the sample data yourself. +.PP +A sample that is referred to by the \f[C]samples\f[R] parameter refers +to a sequence channel intensities. +E.g. +if you\[cq]re making a stereo sample with the \f[C]samples\f[R] set to +4, then the layout of the data in \f[C]buf\f[R] will be: +.IP +.nf +\f[C] +LRLRLRLR +\f[R] +.fi +.PP +Where L and R are the intensities for the left and right channels +respectively. +A single sample, then, refers to the LR pair in this example. +.PP +To allocate a buffer of the correct size, you can use something like +this: +.IP +.nf +\f[C] +int sample_size = al_get_channel_count(chan_conf) + * al_get_audio_depth_size(depth); +int bytes = samples * sample_size; +void *buffer = al_malloc(bytes); +\f[R] +.fi +.SH SEE ALSO +.PP +al_destroy_sample(3), ALLEGRO_AUDIO_DEPTH(3), ALLEGRO_CHANNEL_CONF(3) diff --git a/allegro/docs/man/al_create_sample_instance.3 b/allegro/docs/man/al_create_sample_instance.3 new file mode 100644 index 00000000..1b023dcf --- /dev/null +++ b/allegro/docs/man/al_create_sample_instance.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_sample_instance" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_sample_instance - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SAMPLE_INSTANCE *al_create_sample_instance(ALLEGRO_SAMPLE *sample_data) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a sample instance, using the supplied sample data. +The instance must be attached to a mixer (or voice) in order to actually +produce output. +.PP +The argument may be NULL. +You can then set the sample data later with al_set_sample(3). +.SH SEE ALSO +.PP +al_destroy_sample_instance(3) diff --git a/allegro/docs/man/al_create_shader.3 b/allegro/docs/man/al_create_shader.3 new file mode 100644 index 00000000..997552ed --- /dev/null +++ b/allegro/docs/man/al_create_shader.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_shader" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_shader - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SHADER *al_create_shader(ALLEGRO_SHADER_PLATFORM platform) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a shader object. +.PP +The platform argument is one of the ALLEGRO_SHADER_PLATFORM(3) values, +and specifies the type of shader object to create, and which language is +used to program the shader. +.PP +The shader platform must be compatible with the type of display that you +will use the shader with. +For example, you cannot create and use a HLSL shader on an OpenGL +display, nor a GLSL shader on a Direct3D display. +.PP +The ALLEGRO_SHADER_AUTO value automatically chooses the appropriate +platform for the display currently targeted by the calling thread; there +must be such a display. +It will create a GLSL shader for an OpenGL display, and a HLSL shader +for a Direct3D display. +.PP +Returns the shader object on success. +Otherwise, returns NULL. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_attach_shader_source(3), al_attach_shader_source_file(3), +al_build_shader(3), al_use_shader(3), al_destroy_shader(3), +al_get_shader_platform(3) diff --git a/allegro/docs/man/al_create_sub_bitmap.3 b/allegro/docs/man/al_create_sub_bitmap.3 new file mode 100644 index 00000000..41d1500e --- /dev/null +++ b/allegro/docs/man/al_create_sub_bitmap.3 @@ -0,0 +1,46 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_sub_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_sub_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent, + int x, int y, int w, int h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a sub-bitmap of the parent, at the specified coordinates and of +the specified size. +A sub-bitmap is a bitmap that shares drawing memory with a pre-existing +(parent) bitmap, but possibly with a different size and clipping +settings. +.PP +The sub-bitmap may originate off or extend past the parent bitmap. +.PP +See the discussion in al_get_backbuffer(3) about using sub-bitmaps of +the backbuffer. +.PP +The parent bitmap\[cq]s clipping rectangles are ignored. +.PP +If a sub-bitmap was not or cannot be created then NULL is returned. +.PP +When you are done with using the sub-bitmap you must call +al_destroy_bitmap(3) on it to free any resources allocated for it. +.PP +Note that destroying parents of sub-bitmaps will not destroy the +sub-bitmaps; instead the sub-bitmaps become invalid and should no longer +be used for drawing - they still must be destroyed with +al_destroy_bitmap(3) however. +It does not matter whether you destroy a sub-bitmap before or after its +parent otherwise. +.SH SEE ALSO +.PP +al_create_bitmap(3) diff --git a/allegro/docs/man/al_create_thread.3 b/allegro/docs/man/al_create_thread.3 new file mode 100644 index 00000000..c60d0288 --- /dev/null +++ b/allegro/docs/man/al_create_thread.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_thread" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_thread - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_THREAD *al_create_thread( + void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg) +\f[R] +.fi +.SH DESCRIPTION +.PP +Spawn a new thread which begins executing \f[C]proc\f[R]. +The new thread is passed its own thread handle and the value +\f[C]arg\f[R]. +.PP +Returns a pointer to the thread on success. +Otherwise, returns NULL if there was an error. +.SH SEE ALSO +.PP +al_start_thread(3), al_join_thread(3). diff --git a/allegro/docs/man/al_create_thread_with_stacksize.3 b/allegro/docs/man/al_create_thread_with_stacksize.3 new file mode 100644 index 00000000..3843b169 --- /dev/null +++ b/allegro/docs/man/al_create_thread_with_stacksize.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_thread_with_stacksize" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_thread_with_stacksize - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_THREAD *al_create_thread_with_stacksize( + void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg, size_t stacksize) +\f[R] +.fi +.SH DESCRIPTION +.PP +Spawn a new thread with the give stacksize in bytes which begins +executing \f[C]proc\f[R]. +The new thread is passed its own thread handle and the value +\f[C]arg\f[R]. +.PP +Returns a pointer to the thread on success. +Otherwise, returns NULL if there was an error. +.SH SINCE +.PP +5.2.5 +.RS +.PP +\f[I][Unstable API]:\f[R] New API, may want a better way to specify +thread options. +.RE +.SH SEE ALSO +.PP +al_start_thread(3), al_join_thread(3). diff --git a/allegro/docs/man/al_create_timer.3 b/allegro/docs/man/al_create_timer.3 new file mode 100644 index 00000000..7759c84d --- /dev/null +++ b/allegro/docs/man/al_create_timer.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_timer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_timer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_TIMER *al_create_timer(double speed_secs) +\f[R] +.fi +.SH DESCRIPTION +.PP +Allocates and initializes a timer. +If successful, a pointer to a new timer object is returned, otherwise +NULL is returned. +\f[I]speed_secs\f[R] is in seconds per \[lq]tick\[rq], and must be +positive. +The new timer is initially stopped. +.PP +Usage note: typical granularity is on the order of microseconds, but +with some drivers might only be milliseconds. +.SH SEE ALSO +.PP +al_start_timer(3), al_destroy_timer(3) diff --git a/allegro/docs/man/al_create_vertex_buffer.3 b/allegro/docs/man/al_create_vertex_buffer.3 new file mode 100644 index 00000000..de0089be --- /dev/null +++ b/allegro/docs/man/al_create_vertex_buffer.3 @@ -0,0 +1,52 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_vertex_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_vertex_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_VERTEX_BUFFER* al_create_vertex_buffer(ALLEGRO_VERTEX_DECL* decl, + const void* initial_data, int num_vertices, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a vertex buffer. +Can return NULL if the buffer could not be created (e.g.\ the system +only supports write-only buffers). +.RS +.PP +\f[I]Note:\f[R] +.PP +This is an advanced feature, often unsupported on lower-end video cards. +Be extra mindful of this function failing and make arrangements for +fallback drawing functionality or a nice error message for users with +such lower-end cards. +.RE +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +decl - Vertex type that this buffer will hold. +NULL implies that this buffer will hold ALLEGRO_VERTEX(3) vertices +.IP \[bu] 2 +initial_data - Memory buffer to copy from to initialize the vertex +buffer. +Can be \f[C]NULL\f[R], in which case the buffer is uninitialized. +.IP \[bu] 2 +num_vertices - Number of vertices the buffer will hold +.IP \[bu] 2 +flags - A combination of the ALLEGRO_PRIM_BUFFER_FLAGS(3) flags +specifying how this buffer will be created. +Passing 0 is the same as passing \f[C]ALLEGRO_PRIM_BUFFER_STATIC\f[R]. +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_BUFFER(3), al_destroy_vertex_buffer(3) diff --git a/allegro/docs/man/al_create_vertex_decl.3 b/allegro/docs/man/al_create_vertex_decl.3 new file mode 100644 index 00000000..539e87cc --- /dev/null +++ b/allegro/docs/man/al_create_vertex_decl.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_vertex_decl" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_vertex_decl - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_VERTEX_DECL* al_create_vertex_decl(const ALLEGRO_VERTEX_ELEMENT* elements, int stride) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a vertex declaration, which describes a custom vertex format. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +elements - An array of ALLEGRO_VERTEX_ELEMENT(3) structures. +.IP \[bu] 2 +stride - Size of the custom vertex structure +.PP +\f[I]Returns:\f[R] Newly created vertex declaration. +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_ELEMENT(3), ALLEGRO_VERTEX_DECL(3), +al_destroy_vertex_decl(3) diff --git a/allegro/docs/man/al_create_voice.3 b/allegro/docs/man/al_create_voice.3 new file mode 100644 index 00000000..67be6de4 --- /dev/null +++ b/allegro/docs/man/al_create_voice.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_create_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_create_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_VOICE *al_create_voice(unsigned int freq, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a voice structure and allocates a voice from the digital sound +driver. +The passed frequency (in Hz), sample format and channel configuration +are used as a hint to what kind of data will be sent to the voice. +However, the underlying sound driver is free to use non-matching values. +For example, it may be the native format of the sound hardware. +.PP +If a mixer is attached to the voice, the mixer will handle the +conversion of all its input streams to the voice format and care does +not have to be taken for this. +However if you access the voice directly, make sure to not rely on the +parameters passed to this function, but instead query the returned voice +for the actual settings. +.SH SEE ALSO +.PP +al_destroy_voice(3) diff --git a/allegro/docs/man/al_cstr.3 b/allegro/docs/man/al_cstr.3 new file mode 100644 index 00000000..476a479a --- /dev/null +++ b/allegro/docs/man/al_cstr.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_cstr(const ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get a \f[C]char *\f[R] pointer to the data in a string. +This pointer will only be valid while the ALLEGRO_USTR(3) object is not +modified and not destroyed. +The pointer may be passed to functions expecting C-style strings, with +the following caveats: +.IP \[bu] 2 +ALLEGRO_USTRs are allowed to contain embedded NUL +(\f[C]\[aq]\[rs]0\[aq]\f[R]) bytes. +That means \f[C]al_ustr_size(u)\f[R] and \f[C]strlen(al_cstr(u))\f[R] +may not agree. +.IP \[bu] 2 +An ALLEGRO_USTR may be created in such a way that it is not NUL +terminated. +A string which is dynamically allocated will always be NUL terminated, +but a string which references the middle of another string or region of +memory will \f[I]not\f[R] be NUL terminated. +.IP \[bu] 2 +If the ALLEGRO_USTR references another string, the returned C string +will point into the referenced string. +Again, no NUL terminator will be added to the referenced string. +.SH SEE ALSO +.PP +al_ustr_to_buffer(3), al_cstr_dup(3) diff --git a/allegro/docs/man/al_cstr_dup.3 b/allegro/docs/man/al_cstr_dup.3 new file mode 100644 index 00000000..4806ef5b --- /dev/null +++ b/allegro/docs/man/al_cstr_dup.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_cstr_dup" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_cstr_dup - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char *al_cstr_dup(const ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a NUL (\f[C]\[aq]\[rs]0\[aq]\f[R]) terminated copy of the string. +Any embedded NUL bytes will still be presented in the returned string. +The new string must eventually be freed with al_free(3). +.PP +If an error occurs NULL is returned. +.SH SEE ALSO +.PP +al_cstr(3), al_ustr_to_buffer(3), al_free(3) diff --git a/allegro/docs/man/al_destroy_audio_recorder.3 b/allegro/docs/man/al_destroy_audio_recorder.3 new file mode 100644 index 00000000..f35e53d9 --- /dev/null +++ b/allegro/docs/man/al_destroy_audio_recorder.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_audio_recorder" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_audio_recorder - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_audio_recorder(ALLEGRO_AUDIO_RECORDER *r) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys the audio recorder and frees all resources associated with it. +It is safe to destroy a recorder that is recording. +.PP +You may receive events after the recorder has been destroyed. +They must be ignored, as the fragment buffer will no longer be valid. +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/al_destroy_audio_stream.3 b/allegro/docs/man/al_destroy_audio_stream.3 new file mode 100644 index 00000000..2f70596e --- /dev/null +++ b/allegro/docs/man/al_destroy_audio_stream.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_audio_stream" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_audio_stream - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_audio_stream(ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroy an audio stream which was created with al_create_audio_stream(3) +or al_load_audio_stream(3). +.RS +.PP +\f[I]Note:\f[R] If the stream is still attached to a mixer or voice, +al_detach_audio_stream(3) is automatically called on it first. +.RE +.SH SEE ALSO +.PP +al_drain_audio_stream(3). diff --git a/allegro/docs/man/al_destroy_bitmap.3 b/allegro/docs/man/al_destroy_bitmap.3 new file mode 100644 index 00000000..d6ba6cae --- /dev/null +++ b/allegro/docs/man/al_destroy_bitmap.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys the given bitmap, freeing all resources used by it. +This function does nothing if the bitmap argument is NULL. +.PP +As a convenience, if the calling thread is currently targeting the +bitmap then the bitmap will be untargeted first. +The new target bitmap is unspecified. +(since: 5.0.10, 5.1.6) +.PP +Otherwise, it is an error to destroy a bitmap while it (or a sub-bitmap) +is the target bitmap of any thread. +.SH SEE ALSO +.PP +al_create_bitmap(3) diff --git a/allegro/docs/man/al_destroy_cond.3 b/allegro/docs/man/al_destroy_cond.3 new file mode 100644 index 00000000..0f785afc --- /dev/null +++ b/allegro/docs/man/al_destroy_cond.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_cond" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_cond - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_cond(ALLEGRO_COND *cond) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroy a condition variable. +.PP +Destroying a condition variable which has threads block on it results in +undefined behaviour. +.PP +Does nothing if \f[C]cond\f[R] is \f[C]NULL\f[R]. diff --git a/allegro/docs/man/al_destroy_config.3 b/allegro/docs/man/al_destroy_config.3 new file mode 100644 index 00000000..06fbc3de --- /dev/null +++ b/allegro/docs/man/al_destroy_config.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_config" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_config - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_config(ALLEGRO_CONFIG *config) +\f[R] +.fi +.SH DESCRIPTION +.PP +Free the resources used by a configuration structure. +Does nothing if passed NULL. +.SH SEE ALSO +.PP +al_create_config(3), al_load_config_file(3) diff --git a/allegro/docs/man/al_destroy_display.3 b/allegro/docs/man/al_destroy_display.3 new file mode 100644 index 00000000..4320bea2 --- /dev/null +++ b/allegro/docs/man/al_destroy_display.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_display" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_display - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_display(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroy a display. +.PP +If the target bitmap of the calling thread is tied to the display, then +it implies a call to \[lq]al_set_target_bitmap(NULL);\[rq] before the +display is destroyed. +.PP +That special case notwithstanding, you should make sure no threads are +currently targeting a bitmap which is tied to the display before you +destroy it. +.SH SEE ALSO +.PP +al_set_target_bitmap(3) diff --git a/allegro/docs/man/al_destroy_event_queue.3 b/allegro/docs/man/al_destroy_event_queue.3 new file mode 100644 index 00000000..91283b59 --- /dev/null +++ b/allegro/docs/man/al_destroy_event_queue.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_event_queue" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_event_queue - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroy the event queue specified. +All event sources currently registered with the queue will be +automatically unregistered before the queue is destroyed. +.SH SEE ALSO +.PP +al_create_event_queue(3), ALLEGRO_EVENT_QUEUE(3) diff --git a/allegro/docs/man/al_destroy_font.3 b/allegro/docs/man/al_destroy_font.3 new file mode 100644 index 00000000..4ebb11e8 --- /dev/null +++ b/allegro/docs/man/al_destroy_font.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_font" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_font - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_font(ALLEGRO_FONT *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Frees the memory being used by a font structure. +Does nothing if passed NULL. +.SH SEE ALSO +.PP +al_load_font(3) diff --git a/allegro/docs/man/al_destroy_fs_entry.3 b/allegro/docs/man/al_destroy_fs_entry.3 new file mode 100644 index 00000000..bb6e179e --- /dev/null +++ b/allegro/docs/man/al_destroy_fs_entry.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_fs_entry" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_fs_entry - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_fs_entry(ALLEGRO_FS_ENTRY *fh) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys a fs entry handle. +The file or directory represented by it is not destroyed. +If the entry was opened, it is closed before being destroyed. +.PP +Does nothing if passed NULL. diff --git a/allegro/docs/man/al_destroy_index_buffer.3 b/allegro/docs/man/al_destroy_index_buffer.3 new file mode 100644 index 00000000..528de40a --- /dev/null +++ b/allegro/docs/man/al_destroy_index_buffer.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_index_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_index_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_index_buffer(ALLEGRO_INDEX_BUFFER* buffer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys a index buffer. +Does nothing if passed NULL. +.SH SINCE +.PP +5.1.8 +.SH SEE ALSO +.PP +ALLEGRO_INDEX_BUFFER(3), al_create_index_buffer(3) diff --git a/allegro/docs/man/al_destroy_menu.3 b/allegro/docs/man/al_destroy_menu.3 new file mode 100644 index 00000000..cde4f433 --- /dev/null +++ b/allegro/docs/man/al_destroy_menu.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_menu(ALLEGRO_MENU *menu) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys an entire menu, including its sub-menus. +Any references to it or a sub-menu are no longer valid. +It is safe to call this on a menu that is currently being displayed. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_remove_menu_item(3) diff --git a/allegro/docs/man/al_destroy_mixer.3 b/allegro/docs/man/al_destroy_mixer.3 new file mode 100644 index 00000000..ad438034 --- /dev/null +++ b/allegro/docs/man/al_destroy_mixer.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_mixer(ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys the mixer. +.SH SEE ALSO +.PP +al_create_mixer(3) diff --git a/allegro/docs/man/al_destroy_mouse_cursor.3 b/allegro/docs/man/al_destroy_mouse_cursor.3 new file mode 100644 index 00000000..a4299d2d --- /dev/null +++ b/allegro/docs/man/al_destroy_mouse_cursor.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_mouse_cursor" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_mouse_cursor - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) +\f[R] +.fi +.SH DESCRIPTION +.PP +Free the memory used by the given cursor. +.PP +Has no effect if \f[C]cursor\f[R] is NULL. +.SH SEE ALSO +.PP +al_create_mouse_cursor(3) diff --git a/allegro/docs/man/al_destroy_mutex.3 b/allegro/docs/man/al_destroy_mutex.3 new file mode 100644 index 00000000..d8ead719 --- /dev/null +++ b/allegro/docs/man/al_destroy_mutex.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_mutex" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_mutex - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_mutex(ALLEGRO_MUTEX *mutex) +\f[R] +.fi +.SH DESCRIPTION +.PP +Free the resources used by the mutex. +The mutex should be unlocked. +Destroying a locked mutex results in undefined behaviour. +.PP +Does nothing if \f[C]mutex\f[R] is \f[C]NULL\f[R]. diff --git a/allegro/docs/man/al_destroy_native_file_dialog.3 b/allegro/docs/man/al_destroy_native_file_dialog.3 new file mode 100644 index 00000000..2c1b8123 --- /dev/null +++ b/allegro/docs/man/al_destroy_native_file_dialog.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_native_file_dialog" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_native_file_dialog - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_native_file_dialog(ALLEGRO_FILECHOOSER *dialog) +\f[R] +.fi +.SH DESCRIPTION +.PP +Frees up all resources used by the file dialog. diff --git a/allegro/docs/man/al_destroy_path.3 b/allegro/docs/man/al_destroy_path.3 new file mode 100644 index 00000000..7175cd36 --- /dev/null +++ b/allegro/docs/man/al_destroy_path.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_path" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_path - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_path(ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Free a path structure. +Does nothing if passed NULL. +.SH SEE ALSO +.PP +al_create_path(3), al_create_path_for_directory(3) diff --git a/allegro/docs/man/al_destroy_sample.3 b/allegro/docs/man/al_destroy_sample.3 new file mode 100644 index 00000000..c5039f1f --- /dev/null +++ b/allegro/docs/man/al_destroy_sample.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_sample" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_sample - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_sample(ALLEGRO_SAMPLE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Free the sample data structure. +If it was created with the \f[C]free_buf\f[R] parameter set to true, +then the buffer will be freed with al_free(3). +.PP +This function will stop any sample instances which may be playing the +buffer referenced by the ALLEGRO_SAMPLE(3). +.SH SEE ALSO +.PP +al_destroy_sample_instance(3), al_stop_sample(3), al_stop_samples(3) diff --git a/allegro/docs/man/al_destroy_sample_instance.3 b/allegro/docs/man/al_destroy_sample_instance.3 new file mode 100644 index 00000000..aac7676c --- /dev/null +++ b/allegro/docs/man/al_destroy_sample_instance.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_sample_instance" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_sample_instance - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Detaches the sample instance from anything it may be attached to and +frees it (the sample data, i.e.\ its ALLEGRO_SAMPLE, is \f[I]not\f[R] +freed!). +.SH SEE ALSO +.PP +al_create_sample_instance(3) diff --git a/allegro/docs/man/al_destroy_shader.3 b/allegro/docs/man/al_destroy_shader.3 new file mode 100644 index 00000000..ebd9caa8 --- /dev/null +++ b/allegro/docs/man/al_destroy_shader.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_shader" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_shader - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_shader(ALLEGRO_SHADER *shader) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroy a shader. +Any bitmaps which currently use the shader will implicitly stop using +the shader. +In multi-threaded programs, be careful that no such bitmaps are being +accessed by other threads at the time. +.PP +As a convenience, if the target bitmap of the calling thread is using +the shader then the shader is implicitly unused before being destroyed. +.PP +This function does nothing if the shader argument is NULL. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_create_shader(3) diff --git a/allegro/docs/man/al_destroy_thread.3 b/allegro/docs/man/al_destroy_thread.3 new file mode 100644 index 00000000..fe79f7bd --- /dev/null +++ b/allegro/docs/man/al_destroy_thread.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_thread" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_thread - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_thread(ALLEGRO_THREAD *thread) +\f[R] +.fi +.SH DESCRIPTION +.PP +Free the resources used by a thread. +Implicitly performs al_join_thread(3) on the thread if it hasn\[cq]t +been done already. +.PP +Does nothing if \f[C]thread\f[R] is NULL. +.SH SEE ALSO +.PP +al_join_thread(3). diff --git a/allegro/docs/man/al_destroy_timer.3 b/allegro/docs/man/al_destroy_timer.3 new file mode 100644 index 00000000..671d8c19 --- /dev/null +++ b/allegro/docs/man/al_destroy_timer.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_timer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_timer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_timer(ALLEGRO_TIMER *timer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uninstall the timer specified. +If the timer is started, it will automatically be stopped before +uninstallation. +It will also automatically unregister the timer with any event queues. +.PP +Does nothing if passed the NULL pointer. +.SH SEE ALSO +.PP +al_create_timer(3) diff --git a/allegro/docs/man/al_destroy_user_event_source.3 b/allegro/docs/man/al_destroy_user_event_source.3 new file mode 100644 index 00000000..768f2c2e --- /dev/null +++ b/allegro/docs/man/al_destroy_user_event_source.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_user_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_user_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_user_event_source(ALLEGRO_EVENT_SOURCE *src) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroy an event source initialised with al_init_user_event_source(3). +.PP +This does not free the memory, as that was user allocated to begin with. +.SH SEE ALSO +.PP +ALLEGRO_EVENT_SOURCE(3) diff --git a/allegro/docs/man/al_destroy_vertex_buffer.3 b/allegro/docs/man/al_destroy_vertex_buffer.3 new file mode 100644 index 00000000..fcb49883 --- /dev/null +++ b/allegro/docs/man/al_destroy_vertex_buffer.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_vertex_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_vertex_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys a vertex buffer. +Does nothing if passed NULL. +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_BUFFER(3), al_create_vertex_buffer(3) diff --git a/allegro/docs/man/al_destroy_vertex_decl.3 b/allegro/docs/man/al_destroy_vertex_decl.3 new file mode 100644 index 00000000..5487feec --- /dev/null +++ b/allegro/docs/man/al_destroy_vertex_decl.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_vertex_decl" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_vertex_decl - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL* decl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys a vertex declaration. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +decl - Vertex declaration to destroy +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_ELEMENT(3), ALLEGRO_VERTEX_DECL(3), +al_create_vertex_decl(3) diff --git a/allegro/docs/man/al_destroy_voice.3 b/allegro/docs/man/al_destroy_voice.3 new file mode 100644 index 00000000..4242ef63 --- /dev/null +++ b/allegro/docs/man/al_destroy_voice.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_destroy_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_destroy_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_destroy_voice(ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Destroys the voice and deallocates it from the digital driver. +Does nothing if the voice is NULL. +.SH SEE ALSO +.PP +al_create_voice(3) diff --git a/allegro/docs/man/al_detach_audio_stream.3 b/allegro/docs/man/al_detach_audio_stream.3 new file mode 100644 index 00000000..f90cd02e --- /dev/null +++ b/allegro/docs/man/al_detach_audio_stream.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_detach_audio_stream" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_detach_audio_stream - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_detach_audio_stream(ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Detach the stream from whatever it\[cq]s attached to, if anything. +.SH SEE ALSO +.PP +al_attach_audio_stream_to_mixer(3), al_attach_audio_stream_to_voice(3), +al_get_audio_stream_attached(3). diff --git a/allegro/docs/man/al_detach_mixer.3 b/allegro/docs/man/al_detach_mixer.3 new file mode 100644 index 00000000..800ef3d7 --- /dev/null +++ b/allegro/docs/man/al_detach_mixer.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_detach_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_detach_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_detach_mixer(ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Detach the mixer from whatever it is attached to, if anything. +.SH SEE ALSO +.PP +al_attach_mixer_to_mixer(3). diff --git a/allegro/docs/man/al_detach_sample_instance.3 b/allegro/docs/man/al_detach_sample_instance.3 new file mode 100644 index 00000000..a3a16489 --- /dev/null +++ b/allegro/docs/man/al_detach_sample_instance.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_detach_sample_instance" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_detach_sample_instance - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_detach_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Detach the sample instance from whatever it\[cq]s attached to, if +anything. +.PP +Returns true on success. +.SH SEE ALSO +.PP +al_attach_sample_instance_to_mixer(3), +al_attach_sample_instance_to_voice(3), +al_get_sample_instance_attached(3) diff --git a/allegro/docs/man/al_detach_voice.3 b/allegro/docs/man/al_detach_voice.3 new file mode 100644 index 00000000..6f9727f7 --- /dev/null +++ b/allegro/docs/man/al_detach_voice.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_detach_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_detach_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_detach_voice(ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Detaches the mixer, sample instance or audio stream from the voice. +.SH SEE ALSO +.PP +al_attach_mixer_to_voice(3), al_attach_sample_instance_to_voice(3), +al_attach_audio_stream_to_voice(3) diff --git a/allegro/docs/man/al_disable_menu_event_source.3 b/allegro/docs/man/al_disable_menu_event_source.3 new file mode 100644 index 00000000..0a2d0879 --- /dev/null +++ b/allegro/docs/man/al_disable_menu_event_source.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_disable_menu_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_disable_menu_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_disable_menu_event_source(ALLEGRO_MENU *menu) +\f[R] +.fi +.SH DESCRIPTION +.PP +Disables a unique event source for the menu, causing it to use the +default event source. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_get_default_menu_event_source(3), al_enable_menu_event_source(3) diff --git a/allegro/docs/man/al_do_multiline_text.3 b/allegro/docs/man/al_do_multiline_text.3 new file mode 100644 index 00000000..c49ccc14 --- /dev/null +++ b/allegro/docs/man/al_do_multiline_text.3 @@ -0,0 +1,60 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_do_multiline_text" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_do_multiline_text - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_do_multiline_text(const ALLEGRO_FONT *font, + float max_width, const char *text, + bool (*cb)(int line_num, const char *line, int size, void *extra), + void *extra) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function processes the \f[C]text\f[R] and splits it into lines as +al_draw_multiline_text(3) would, and then calls the callback +\f[C]cb\f[R] once for every line. +This is useful for custom drawing of multiline text, or for calculating +the size of multiline text ahead of time. +See the documentation on al_draw_multiline_text(3) for an explanation of +the splitting algorithm. +.PP +For every line that this function splits \f[C]text\f[R] into the +callback \f[C]cb\f[R] will be called once with the following parameters: +.IP \[bu] 2 +\f[C]line_num\f[R] - the number of the line starting from zero and +counting up +.IP \[bu] 2 +\f[C]line\f[R] - a pointer to the beginning character of the line (see +below) +.IP \[bu] 2 +\f[C]size\f[R] - the size of the line (0 for empty lines) +.IP \[bu] 2 +\f[C]extra\f[R] - the same pointer that was passed to +al_do_multiline_text +.PP +Note that \f[C]line\f[R] is \f[I]not\f[R] guaranteed to be a +NUL-terminated string, but will merely point to a character within +\f[C]text\f[R] or to an empty string in case of an empty line. +If you need a NUL-terminated string, you will have to copy +\f[C]line\f[R] to a buffer and NUL-terminate it yourself. +You will also have to make your own copy if you need the contents of +\f[C]line\f[R] after \f[C]cb\f[R] has returned, as \f[C]line\f[R] is +\f[I]not\f[R] guaranteed to be valid after that. +.PP +If the callback \f[C]cb\f[R] returns false, al_do_multiline_text will +stop immediately, otherwise it will continue on to the next line. +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_draw_multiline_text(3) diff --git a/allegro/docs/man/al_do_multiline_ustr.3 b/allegro/docs/man/al_do_multiline_ustr.3 new file mode 100644 index 00000000..a019fce6 --- /dev/null +++ b/allegro/docs/man/al_do_multiline_ustr.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_do_multiline_ustr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_do_multiline_ustr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_do_multiline_ustr(const ALLEGRO_FONT *font, float max_width, + const ALLEGRO_USTR *ustr, + bool (*cb)(int line_num, const ALLEGRO_USTR * line, void *extra), + void *extra) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_do_multiline_text(3), but using ALLEGRO_USTR instead of a +NUL-terminated char array for text. +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_draw_multiline_ustr(3) diff --git a/allegro/docs/man/al_drain_audio_stream.3 b/allegro/docs/man/al_drain_audio_stream.3 new file mode 100644 index 00000000..e3a55471 --- /dev/null +++ b/allegro/docs/man/al_drain_audio_stream.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_drain_audio_stream" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_drain_audio_stream - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_drain_audio_stream(ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +You should call this to finalise an audio stream that you will no longer +be feeding, to wait for all pending buffers to finish playing. +The stream\[cq]s playing state will change to false. +.SH SEE ALSO +.PP +al_destroy_audio_stream(3) diff --git a/allegro/docs/man/al_draw_arc.3 b/allegro/docs/man/al_draw_arc.3 new file mode 100644 index 00000000..16886f29 --- /dev/null +++ b/allegro/docs/man/al_draw_arc.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_arc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_arc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_arc(float cx, float cy, float r, float start_theta, + float delta_theta, ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an arc. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +cx, cy - Center of the arc +.IP \[bu] 2 +r - Radius of the arc +.IP \[bu] 2 +color - Color of the arc +.IP \[bu] 2 +start_theta - The initial angle from which the arc is calculated in +radians +.IP \[bu] 2 +delta_theta - Angular span of the arc in radians (pass a negative number +to switch direction) +.IP \[bu] 2 +thickness - Thickness of the arc, pass \f[C]<= 0\f[R] to draw hairline +arc +.SH SEE ALSO +.PP +al_calculate_arc(3), al_draw_elliptical_arc(3) diff --git a/allegro/docs/man/al_draw_bitmap.3 b/allegro/docs/man/al_draw_bitmap.3 new file mode 100644 index 00000000..51767a59 --- /dev/null +++ b/allegro/docs/man/al_draw_bitmap.3 @@ -0,0 +1,48 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an unscaled, unrotated bitmap at the given position to the current +target bitmap (see al_set_target_bitmap(3)). +.PP +\f[C]flags\f[R] can be a combination of: +.IP \[bu] 2 +ALLEGRO_FLIP_HORIZONTAL - flip the bitmap about the y-axis +.IP \[bu] 2 +ALLEGRO_FLIP_VERTICAL - flip the bitmap about the x-axis +.RS +.PP +\f[I]Note:\f[R] The current target bitmap must be a different bitmap. +Drawing a bitmap to itself (or to a sub-bitmap of itself) or drawing a +sub-bitmap to its parent (or another sub-bitmap of its parent) are not +currently supported. +To copy part of a bitmap into the same bitmap simply use a temporary +bitmap instead. +.RE +.RS +.PP +\f[I]Note:\f[R] The backbuffer (or a sub-bitmap thereof) can not be +transformed, blended or tinted. +If you need to draw the backbuffer draw it to a temporary bitmap first +with no active transformation (except translation). +Blending and tinting settings/parameters will be ignored. +This does not apply when drawing into a memory bitmap. +.RE +.SH SEE ALSO +.PP +al_draw_bitmap_region(3), al_draw_scaled_bitmap(3), +al_draw_rotated_bitmap(3), al_draw_scaled_rotated_bitmap(3) diff --git a/allegro/docs/man/al_draw_bitmap_region.3 b/allegro/docs/man/al_draw_bitmap_region.3 new file mode 100644 index 00000000..a1542fd2 --- /dev/null +++ b/allegro/docs/man/al_draw_bitmap_region.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_bitmap_region" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_bitmap_region - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, float dx, float dy, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a region of the given bitmap to the target bitmap. +.IP \[bu] 2 +sx - source x +.IP \[bu] 2 +sy - source y +.IP \[bu] 2 +sw - source width (width of region to blit) +.IP \[bu] 2 +sh - source height (height of region to blit) +.IP \[bu] 2 +dx - destination x +.IP \[bu] 2 +dy - destination y +.IP \[bu] 2 +flags - same as for al_draw_bitmap(3) +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_bitmap(3), al_draw_scaled_bitmap(3), al_draw_rotated_bitmap(3), +al_draw_scaled_rotated_bitmap(3) diff --git a/allegro/docs/man/al_draw_circle.3 b/allegro/docs/man/al_draw_circle.3 new file mode 100644 index 00000000..7cc3dff9 --- /dev/null +++ b/allegro/docs/man/al_draw_circle.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_circle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_circle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_circle(float cx, float cy, float r, ALLEGRO_COLOR color, + float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an outlined circle. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +cx, cy - Center of the circle +.IP \[bu] 2 +r - Radius of the circle +.IP \[bu] 2 +color - Color of the circle +.IP \[bu] 2 +thickness - Thickness of the circle, pass \f[C]<= 0\f[R] to draw a +hairline circle +.SH SEE ALSO +.PP +al_draw_filled_circle(3), al_draw_ellipse(3) diff --git a/allegro/docs/man/al_draw_ellipse.3 b/allegro/docs/man/al_draw_ellipse.3 new file mode 100644 index 00000000..d0033063 --- /dev/null +++ b/allegro/docs/man/al_draw_ellipse.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_ellipse" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_ellipse - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_ellipse(float cx, float cy, float rx, float ry, + ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an outlined ellipse. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +cx, cy - Center of the ellipse +.IP \[bu] 2 +rx, ry - Radii of the ellipse +.IP \[bu] 2 +color - Color of the ellipse +.IP \[bu] 2 +thickness - Thickness of the ellipse, pass \f[C]<= 0\f[R] to draw a +hairline ellipse +.SH SEE ALSO +.PP +al_draw_filled_ellipse(3), al_draw_circle(3) diff --git a/allegro/docs/man/al_draw_elliptical_arc.3 b/allegro/docs/man/al_draw_elliptical_arc.3 new file mode 100644 index 00000000..e934d04f --- /dev/null +++ b/allegro/docs/man/al_draw_elliptical_arc.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_elliptical_arc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_elliptical_arc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_elliptical_arc(float cx, float cy, float rx, float ry, float start_theta, + float delta_theta, ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an elliptical arc. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +cx, cy - Center of the arc +.IP \[bu] 2 +rx, ry - Radii of the arc +.IP \[bu] 2 +color - Color of the arc +.IP \[bu] 2 +start_theta - The initial angle from which the arc is calculated in +radians +.IP \[bu] 2 +delta_theta - Angular span of the arc in radians (pass a negative number +to switch direction) +.IP \[bu] 2 +thickness - Thickness of the arc, pass \f[C]<= 0\f[R] to draw hairline +arc +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_calculate_arc(3), al_draw_arc(3) diff --git a/allegro/docs/man/al_draw_filled_circle.3 b/allegro/docs/man/al_draw_filled_circle.3 new file mode 100644 index 00000000..48d40f75 --- /dev/null +++ b/allegro/docs/man/al_draw_filled_circle.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_filled_circle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_filled_circle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_filled_circle(float cx, float cy, float r, ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a filled circle. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +cx, cy - Center of the circle +.IP \[bu] 2 +r - Radius of the circle +.IP \[bu] 2 +color - Color of the circle +.SH SEE ALSO +.PP +al_draw_circle(3), al_draw_filled_ellipse(3) diff --git a/allegro/docs/man/al_draw_filled_ellipse.3 b/allegro/docs/man/al_draw_filled_ellipse.3 new file mode 100644 index 00000000..fcabaf78 --- /dev/null +++ b/allegro/docs/man/al_draw_filled_ellipse.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_filled_ellipse" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_filled_ellipse - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_filled_ellipse(float cx, float cy, float rx, float ry, + ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a filled ellipse. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +cx, cy - Center of the ellipse +.IP \[bu] 2 +rx, ry - Radii of the ellipse +.IP \[bu] 2 +color - Color of the ellipse +.SH SEE ALSO +.PP +al_draw_ellipse(3), al_draw_filled_circle(3) diff --git a/allegro/docs/man/al_draw_filled_pieslice.3 b/allegro/docs/man/al_draw_filled_pieslice.3 new file mode 100644 index 00000000..31e8abad --- /dev/null +++ b/allegro/docs/man/al_draw_filled_pieslice.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_filled_pieslice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_filled_pieslice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta, + float delta_theta, ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a filled pieslice (filled circular sector). +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +cx, cy - Center of the pieslice +.IP \[bu] 2 +r - Radius of the pieslice +.IP \[bu] 2 +color - Color of the pieslice +.IP \[bu] 2 +start_theta - The initial angle from which the pieslice is drawn in +radians +.IP \[bu] 2 +delta_theta - Angular span of the pieslice in radians (pass a negative +number to switch direction) +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_draw_pieslice(3) diff --git a/allegro/docs/man/al_draw_filled_polygon.3 b/allegro/docs/man/al_draw_filled_polygon.3 new file mode 100644 index 00000000..6b9e93e1 --- /dev/null +++ b/allegro/docs/man/al_draw_filled_polygon.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_filled_polygon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_filled_polygon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_filled_polygon(const float *vertices, int vertex_count, + ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draw a filled, simple polygon. +Simple means it does not have to be convex but must not be +self-overlapping. +.IP \[bu] 2 +vertices - Interleaved array of (x, y) vertex coordinates +.IP \[bu] 2 +vertex_count - Number of vertices in the array +.IP \[bu] 2 +color - Color of the filled polygon +.PP +When the y-axis is facing downwards (the usual), the coordinates must be +ordered anti-clockwise. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_draw_polygon(3), al_draw_filled_polygon_with_holes(3) diff --git a/allegro/docs/man/al_draw_filled_polygon_with_holes.3 b/allegro/docs/man/al_draw_filled_polygon_with_holes.3 new file mode 100644 index 00000000..b15bb05b --- /dev/null +++ b/allegro/docs/man/al_draw_filled_polygon_with_holes.3 @@ -0,0 +1,74 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_filled_polygon_with_holes" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_filled_polygon_with_holes - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_filled_polygon_with_holes(const float *vertices, + const int *vertex_counts, ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a filled simple polygon with zero or more other simple polygons +subtracted from it - the holes. +The holes cannot touch or intersect with the outline of the filled +polygon. +.IP \[bu] 2 +vertices - Interleaved array of (x, y) vertex coordinates for each of +the polygons, including holes. +.IP \[bu] 2 +vertex_counts - Number of vertices for each polygon. +The number of vertices in the filled polygon is given by +vertex_counts[0] and must be at least three. +Subsequent elements indicate the number of vertices in each hole. +The array must be terminated with an element with value zero. +.IP \[bu] 2 +color - Color of the filled polygon +.PP +When the y-axis is facing downwards (the usual) the filled polygon +coordinates must be ordered anti-clockwise. +All hole vertices must use the opposite order (clockwise with y down). +All hole vertices must be inside the main polygon and no hole may +overlap the main polygon. +.PP +For example: +.IP +.nf +\f[C] +float vertices[] = { + 0, 0, // filled polygon, upper left corner + 0, 100, // filled polygon, lower left corner + 100, 100, // filled polygon, lower right corner + 100, 0, // filled polygon, upper right corner + 10, 10, // hole, upper left + 90, 10, // hole, upper right + 90, 90 // hole, lower right +}; +int vertex_counts[] = { + 4, // number of vertices for filled polygon + 3, // number of vertices for hole + 0 // terminator +}; +\f[R] +.fi +.PP +There are 7 vertices: four for an outer square from (0, 0) to (100, 100) +in anti-clockwise order, and three more for an inner triangle in +clockwise order. +The outer main polygon uses vertices 0 to 3 (inclusive) and the hole +uses vertices 4 to 6 (inclusive). +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_draw_filled_polygon(3), al_draw_filled_polygon_with_holes(3), +al_triangulate_polygon(3) diff --git a/allegro/docs/man/al_draw_filled_rectangle.3 b/allegro/docs/man/al_draw_filled_rectangle.3 new file mode 100644 index 00000000..8fb46f9e --- /dev/null +++ b/allegro/docs/man/al_draw_filled_rectangle.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_filled_rectangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_filled_rectangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_filled_rectangle(float x1, float y1, float x2, float y2, + ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a filled rectangle. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +x1, y1, x2, y2 - Upper left and lower right points of the rectangle +.IP \[bu] 2 +color - Color of the rectangle +.SH SEE ALSO +.PP +al_draw_rectangle(3), al_draw_filled_rounded_rectangle(3) diff --git a/allegro/docs/man/al_draw_filled_rounded_rectangle.3 b/allegro/docs/man/al_draw_filled_rounded_rectangle.3 new file mode 100644 index 00000000..b1aa7614 --- /dev/null +++ b/allegro/docs/man/al_draw_filled_rounded_rectangle.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_filled_rounded_rectangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_filled_rounded_rectangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_filled_rounded_rectangle(float x1, float y1, float x2, float y2, + float rx, float ry, ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an filled rounded rectangle. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +x1, y1, x2, y2 - Upper left and lower right points of the rectangle +.IP \[bu] 2 +color - Color of the rectangle +.IP \[bu] 2 +rx, ry - The radii of the round +.SH SEE ALSO +.PP +al_draw_rounded_rectangle(3), al_draw_filled_rectangle(3) diff --git a/allegro/docs/man/al_draw_filled_triangle.3 b/allegro/docs/man/al_draw_filled_triangle.3 new file mode 100644 index 00000000..b74b30d7 --- /dev/null +++ b/allegro/docs/man/al_draw_filled_triangle.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_filled_triangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_filled_triangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_filled_triangle(float x1, float y1, float x2, float y2, + float x3, float y3, ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a filled triangle. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +x1, y1, x2, y2, x3, y3 - Three points of the triangle +.IP \[bu] 2 +color - Color of the triangle +.SH SEE ALSO +.PP +al_draw_triangle(3) diff --git a/allegro/docs/man/al_draw_glyph.3 b/allegro/docs/man/al_draw_glyph.3 new file mode 100644 index 00000000..b029aa60 --- /dev/null +++ b/allegro/docs/man/al_draw_glyph.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_glyph" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_glyph - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_glyph(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, float x, float y, + int codepoint) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws the glyph that corresponds with \f[C]codepoint\f[R] in the given +\f[C]color\f[R] using the given \f[C]font\f[R]. +If \f[C]font\f[R] does not have such a glyph, nothing will be drawn. +.PP +To draw a string as left to right horizontal text you will need to use +al_get_glyph_advance(3) to determine the position of each glyph. +For drawing strings in other directions, such as top to down, use +al_get_glyph_dimensions(3) to determine the size and position of each +glyph. +.PP +If you have to draw many glyphs at the same time, use +al_hold_bitmap_drawing(3) with true as the parameter, before drawing the +glyphs, and then call al_hold_bitmap_drawing(3) again with false as a +parameter when done drawing the glyphs to further enhance performance. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_get_glyph_width(3), al_get_glyph_dimensions(3), +al_get_glyph_advance(3). diff --git a/allegro/docs/man/al_draw_indexed_buffer.3 b/allegro/docs/man/al_draw_indexed_buffer.3 new file mode 100644 index 00000000..421a5d36 --- /dev/null +++ b/allegro/docs/man/al_draw_indexed_buffer.3 @@ -0,0 +1,51 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_indexed_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_indexed_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_draw_indexed_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer, + ALLEGRO_BITMAP* texture, ALLEGRO_INDEX_BUFFER* index_buffer, + int start, int end, int type) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a subset of the passed vertex buffer. +This function uses an index buffer to specify which vertices to use. +Both buffers must not be locked. +Additionally, to draw onto memory bitmaps or with memory bitmap textures +both buffers must support reading (i.e.\ they must be created with the +\f[C]ALLEGRO_PRIM_BUFFER_READWRITE\f[R]). +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +vertex_buffer - Vertex buffer to draw +.IP \[bu] 2 +texture - Texture to use, pass NULL to use only color shaded primitves +.IP \[bu] 2 +index_buffer - Index buffer to use +.IP \[bu] 2 +start - Start index of the subset of the vertex buffer to draw +.IP \[bu] 2 +end - One past the last index of the subset of the vertex buffer to draw +.IP \[bu] 2 +type - A member of the ALLEGRO_PRIM_TYPE(3) enumeration, specifying what +kind of primitive to draw. +Note that ALLEGRO_PRIM_LINE_LOOP and ALLEGRO_PRIM_POINT_LIST are not +supported. +.PP +\f[I]Returns:\f[R] Number of primitives drawn +.SH SINCE +.PP +5.1.8 +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_BUFFER(3), ALLEGRO_INDEX_BUFFER(3), ALLEGRO_PRIM_TYPE(3) diff --git a/allegro/docs/man/al_draw_indexed_prim.3 b/allegro/docs/man/al_draw_indexed_prim.3 new file mode 100644 index 00000000..17cf7687 --- /dev/null +++ b/allegro/docs/man/al_draw_indexed_prim.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_indexed_prim" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_indexed_prim - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_draw_indexed_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, + ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a subset of the passed vertex array. +This function uses an index array to specify which vertices to use. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +texture - Texture to use, pass NULL to use only color shaded primitves +.IP \[bu] 2 +vtxs - Pointer to an array of vertices +.IP \[bu] 2 +decl - Pointer to a vertex declaration. +If set to NULL, the vtxs are assumed to be of the ALLEGRO_VERTEX type +.IP \[bu] 2 +indices - An array of indices into the vertex array +.IP \[bu] 2 +num_vtx - Number of indices from the indices array you want to draw +.IP \[bu] 2 +type - A member of the ALLEGRO_PRIM_TYPE(3) enumeration, specifying what +kind of primitive to draw +.PP +\f[I]Returns:\f[R] Number of primitives drawn +.SH SEE ALSO +.PP +ALLEGRO_VERTEX(3), ALLEGRO_PRIM_TYPE(3), ALLEGRO_VERTEX_DECL(3), +al_draw_prim(3) diff --git a/allegro/docs/man/al_draw_justified_text.3 b/allegro/docs/man/al_draw_justified_text.3 new file mode 100644 index 00000000..f9870f9c --- /dev/null +++ b/allegro/docs/man/al_draw_justified_text.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_justified_text" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_justified_text - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_justified_text(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x1, float x2, + float y, float diff, int flags, const char *text) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_text(3), but justifies the string to the region x1-x2. +.PP +The \f[C]diff\f[R] parameter is the maximum amount of horizontal space +to allow between words. +If justisfying the text would exceed \f[C]diff\f[R] pixels, or the +string contains less than two words, then the string will be drawn left +aligned. +.PP +The \f[C]flags\f[R] parameter can be 0 or one of the following flags: +.IP \[bu] 2 +ALLEGRO_ALIGN_INTEGER - Draw text aligned to integer pixel positions. +Since: 5.0.8, 5.1.5 +.SH SEE ALSO +.PP +al_draw_justified_textf(3), al_draw_justified_ustr(3) diff --git a/allegro/docs/man/al_draw_justified_textf.3 b/allegro/docs/man/al_draw_justified_textf.3 new file mode 100644 index 00000000..4ad010e5 --- /dev/null +++ b/allegro/docs/man/al_draw_justified_textf.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_justified_textf" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_justified_textf - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_justified_textf(const ALLEGRO_FONT *f, + ALLEGRO_COLOR color, float x1, float x2, float y, + float diff, int flags, const char *format, ...) +\f[R] +.fi +.SH DESCRIPTION +.PP +Formatted text output, using a printf() style format string. +All parameters have the same meaning as with al_draw_justified_text(3) +otherwise. +.SH SEE ALSO +.PP +al_draw_justified_text(3), al_draw_justified_ustr(3). diff --git a/allegro/docs/man/al_draw_justified_ustr.3 b/allegro/docs/man/al_draw_justified_ustr.3 new file mode 100644 index 00000000..0c379d32 --- /dev/null +++ b/allegro/docs/man/al_draw_justified_ustr.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_justified_ustr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_justified_ustr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_justified_ustr(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x1, float x2, + float y, float diff, int flags, const ALLEGRO_USTR *ustr) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_justified_text(3), except the text is passed as an +ALLEGRO_USTR instead of a NUL-terminated char array. +.SH SEE ALSO +.PP +al_draw_justified_text(3), al_draw_justified_textf(3). diff --git a/allegro/docs/man/al_draw_line.3 b/allegro/docs/man/al_draw_line.3 new file mode 100644 index 00000000..69f23d5d --- /dev/null +++ b/allegro/docs/man/al_draw_line.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_line" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_line - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_line(float x1, float y1, float x2, float y2, + ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a line segment between two points. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +x1, y1, x2, y2 - Start and end points of the line +.IP \[bu] 2 +color - Color of the line +.IP \[bu] 2 +thickness - Thickness of the line, pass \f[C]<= 0\f[R] to draw hairline +lines +.SH SEE ALSO +.PP +al_draw_soft_line(3) diff --git a/allegro/docs/man/al_draw_multiline_text.3 b/allegro/docs/man/al_draw_multiline_text.3 new file mode 100644 index 00000000..9f457a13 --- /dev/null +++ b/allegro/docs/man/al_draw_multiline_text.3 @@ -0,0 +1,74 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_multiline_text" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_multiline_text - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_multiline_text(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, + int flags, const char *text) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_text(3), but this function supports drawing multiple lines +of text. +It will break \f[C]text\f[R] in lines based on its contents and the +\f[C]max_width\f[R] parameter. +The lines are then layed out vertically depending on the +\f[C]line_height\f[R] parameter and drawn each as if al_draw_text(3) was +called on them. +.PP +A newline \f[C]\[rs]n\f[R] in the \f[C]text\f[R] will cause a +\[lq]hard\[rq] line break after its occurrence in the string. +The text after a hard break is placed on a new line. +Carriage return \f[C]\[rs]r\f[R] is not supported, will not cause a line +break, and will likely be drawn as a square or a space depending on the +font. +.PP +The \f[C]max_width\f[R] parameter controls the maximum desired width of +the lines. +This function will try to introduce a \[lq]soft\[rq] line break after +the longest possible series of words that will fit in +\f[C]max_length\f[R] when drawn with the given \f[C]font\f[R]. +A \[lq]soft\[rq] line break can occur either on a space or tab +(\f[C]\[rs]t\f[R]) character. +.PP +However, it is possible that \f[C]max_width\f[R] is too small, or the +words in \f[C]text\f[R] are too long to fit \f[C]max_width\f[R] when +drawn with \f[C]font\f[R]. +In that case, the word that is too wide will simply be drawn completely +on a line by itself. +If you don\[cq]t want the text that overflows \f[C]max_width\f[R] to be +visible, then use al_set_clipping_rectangle(3) to clip it off and hide +it. +.PP +The lines \f[C]text\f[R] was split into will each be drawn using the +\f[C]font\f[R], \f[C]x\f[R], \f[C]color\f[R] and \f[C]flags\f[R] +parameters, vertically starting at \f[C]y\f[R] and with a distance of +\f[C]line_height\f[R] between them. +If \f[C]line_height\f[R] is zero (\f[C]0\f[R]), the value returned by +calling al_get_font_line_height(3) on \f[C]font\f[R] will be used as a +default instead. +.PP +The \f[C]flags\f[R] ALLEGRO_ALIGN_LEFT, ALLEGRO_ALIGN_CENTRE, +ALLEGRO_ALIGN_RIGHT and ALLEGRO_ALIGN_INTEGER will be honoured by this +function. +.PP +If you want to calculate the size of what this function will draw +without actually drawing it, or if you need a complex and/or custom +layout, you can use al_do_multiline_text(3). +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_do_multiline_text(3), al_draw_multiline_ustr(3), +al_draw_multiline_textf(3) diff --git a/allegro/docs/man/al_draw_multiline_textf.3 b/allegro/docs/man/al_draw_multiline_textf.3 new file mode 100644 index 00000000..10ed4a7a --- /dev/null +++ b/allegro/docs/man/al_draw_multiline_textf.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_multiline_textf" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_multiline_textf - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_multiline_textf(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, + int flags, const char *format, ...) +\f[R] +.fi +.SH DESCRIPTION +.PP +Formatted text output, using a printf() style format string. +All parameters have the same meaning as with al_draw_multiline_text(3) +otherwise. +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_draw_multiline_text(3), al_draw_multiline_ustr(3), +al_do_multiline_text(3) diff --git a/allegro/docs/man/al_draw_multiline_ustr.3 b/allegro/docs/man/al_draw_multiline_ustr.3 new file mode 100644 index 00000000..62386d1e --- /dev/null +++ b/allegro/docs/man/al_draw_multiline_ustr.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_multiline_ustr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_multiline_ustr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_multiline_ustr(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, float max_width, float line_height, + int flags, const ALLEGRO_USTR *ustr) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_multiline_text(3), except the text is passed as an +ALLEGRO_USTR instead of a NUL-terminated char array. +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_draw_multiline_text(3), al_draw_multiline_textf(3), +al_do_multiline_text(3) diff --git a/allegro/docs/man/al_draw_pieslice.3 b/allegro/docs/man/al_draw_pieslice.3 new file mode 100644 index 00000000..e45a1dca --- /dev/null +++ b/allegro/docs/man/al_draw_pieslice.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_pieslice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_pieslice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_pieslice(float cx, float cy, float r, float start_theta, + float delta_theta, ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a pieslice (outlined circular sector). +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +cx, cy - Center of the pieslice +.IP \[bu] 2 +r - Radius of the pieslice +.IP \[bu] 2 +color - Color of the pieslice +.IP \[bu] 2 +start_theta - The initial angle from which the pieslice is drawn in +radians +.IP \[bu] 2 +delta_theta - Angular span of the pieslice in radians (pass a negative +number to switch direction) +.IP \[bu] 2 +thickness - Thickness of the circle, pass \f[C]<= 0\f[R] to draw +hairline pieslice +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_draw_filled_pieslice(3) diff --git a/allegro/docs/man/al_draw_pixel.3 b/allegro/docs/man/al_draw_pixel.3 new file mode 100644 index 00000000..699397e8 --- /dev/null +++ b/allegro/docs/man/al_draw_pixel.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_pixel" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_pixel - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_pixel(float x, float y, ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a single pixel at x, y. +This function, unlike al_put_pixel(3), does blending and, unlike +al_put_blended_pixel(3), respects the transformations (that is, the +pixel\[cq]s position is transformed, but its size is unaffected - it +remains a pixel). +This function can be slow if called often; if you need to draw a lot of +pixels consider using al_draw_prim(3) with ALLEGRO_PRIM_POINT_LIST from +the primitives addon. +.IP \[bu] 2 +x - destination x +.IP \[bu] 2 +y - destination y +.IP \[bu] 2 +color - color of the pixel +.RS +.PP +\f[I]Note:\f[R] This function may not draw exactly where you expect it +to. +See the pixel-precise output section on the primitives addon +documentation for details on how to control exactly where the pixel is +drawn. +.RE +.SH SEE ALSO +.PP +ALLEGRO_COLOR(3), al_put_pixel(3) diff --git a/allegro/docs/man/al_draw_polygon.3 b/allegro/docs/man/al_draw_polygon.3 new file mode 100644 index 00000000..2984242a --- /dev/null +++ b/allegro/docs/man/al_draw_polygon.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_polygon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_polygon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_polygon(const float *vertices, int vertex_count, + int join_style, ALLEGRO_COLOR color, float thickness, float miter_limit) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draw an unfilled polygon. +This is the same as passing \f[C]ALLEGRO_LINE_CAP_CLOSED\f[R] to +al_draw_polyline(3). +.IP \[bu] 2 +vertex - Interleaved array of (x, y) vertex coordinates +.IP \[bu] 2 +vertex_count - Number of vertices in the array +.IP \[bu] 2 +join_style - Member of ALLEGRO_LINE_JOIN(3) specifying how to render the +joins between line segments +.IP \[bu] 2 +color - Color of the line +.IP \[bu] 2 +thickness - Thickness of the line, pass \f[C]<= 0\f[R] to draw hairline +lines +.IP \[bu] 2 +miter_limit - Parameter for miter join style +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_draw_filled_polygon(3), al_draw_polyline(3), ALLEGRO_LINE_JOIN(3) diff --git a/allegro/docs/man/al_draw_polyline.3 b/allegro/docs/man/al_draw_polyline.3 new file mode 100644 index 00000000..75bb328e --- /dev/null +++ b/allegro/docs/man/al_draw_polyline.3 @@ -0,0 +1,69 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_polyline" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_polyline - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_polyline(const float* vertices, int vertex_stride, + int vertex_count, int join_style, int cap_style, + ALLEGRO_COLOR color, float thickness, float miter_limit) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draw a series of line segments. +.IP \[bu] 2 +vertices - Interleaved array of (x, y) vertex coordinates +.IP \[bu] 2 +vertex_stride - the number of bytes between pairs of vertices (the +stride) +.IP \[bu] 2 +vertex_count - Number of vertices in the array +.IP \[bu] 2 +join_style - Member of ALLEGRO_LINE_JOIN(3) specifying how to render the +joins between line segments +.IP \[bu] 2 +cap_style - Member of ALLEGRO_LINE_CAP(3) specifying how to render the +end caps +.IP \[bu] 2 +color - Color of the line +.IP \[bu] 2 +thickness - Thickness of the line, pass \f[C]<= 0\f[R] to draw hairline +lines +.IP \[bu] 2 +miter_limit - Parameter for miter join style +.PP +The stride is normally \f[C]2 * sizeof(float)\f[R] but may be more if +the vertex coordinates are in an array of some structure type, e.g. +.IP +.nf +\f[C] +struct VertexInfo { + float x; + float y; + int id; +}; + +void my_draw(struct VertexInfo verts[], int vertex_count, ALLEGRO_COLOR c) +{ + al_draw_polyline((float *)verts, sizeof(VertexInfo), vertex_count, + ALLEGRO_LINE_JOIN_NONE, ALLEGRO_LINE_CAP_NONE, c, 1.0, 1.0); +} +\f[R] +.fi +.PP +The stride may also be negative if the vertices are stored in reverse +order. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_draw_polygon(3), ALLEGRO_LINE_JOIN(3), ALLEGRO_LINE_CAP(3) diff --git a/allegro/docs/man/al_draw_prim.3 b/allegro/docs/man/al_draw_prim.3 new file mode 100644 index 00000000..28ccc0f7 --- /dev/null +++ b/allegro/docs/man/al_draw_prim.3 @@ -0,0 +1,56 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_prim" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_prim - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_draw_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, + ALLEGRO_BITMAP* texture, int start, int end, int type) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a subset of the passed vertex array. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +texture - Texture to use, pass NULL to use only color shaded primitves +.IP \[bu] 2 +vtxs - Pointer to an array of vertices +.IP \[bu] 2 +decl - Pointer to a [vertex declaration]al_create_vertex_decl(3). +If set to NULL, the vertices are assumed to be of the ALLEGRO_VERTEX(3) +type +.IP \[bu] 2 +start - Start index of the subset of the vertex array to draw +.IP \[bu] 2 +end - One past the last index of the subset of the vertex array to draw +.IP \[bu] 2 +type - A member of the ALLEGRO_PRIM_TYPE(3) enumeration, specifying what +kind of primitive to draw +.PP +\f[I]Returns:\f[R] Number of primitives drawn +.PP +For example to draw a textured triangle you could use: +.IP +.nf +\f[C] +ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1); +ALLEGRO_VERTEX v[] = { + {.x = 128, .y = 0, .z = 0, .color = white, .u = 128, .v = 0}, + {.x = 0, .y = 256, .z = 0, .color = white, .u = 0, .v = 256}, + {.x = 256, .y = 256, .z = 0, .color = white, .u = 256, .v = 256}}; +al_draw_prim(v, NULL, texture, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST); +\f[R] +.fi +.SH SEE ALSO +.PP +ALLEGRO_VERTEX(3), ALLEGRO_PRIM_TYPE(3), ALLEGRO_VERTEX_DECL(3), +al_draw_indexed_prim(3) diff --git a/allegro/docs/man/al_draw_rectangle.3 b/allegro/docs/man/al_draw_rectangle.3 new file mode 100644 index 00000000..e7cb17a3 --- /dev/null +++ b/allegro/docs/man/al_draw_rectangle.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_rectangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_rectangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_rectangle(float x1, float y1, float x2, float y2, + ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an outlined rectangle. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +x1, y1, x2, y2 - Upper left and lower right points of the rectangle +.IP \[bu] 2 +color - Color of the rectangle +.IP \[bu] 2 +thickness - Thickness of the lines, pass \f[C]<= 0\f[R] to draw hairline +lines +.SH SEE ALSO +.PP +al_draw_filled_rectangle(3), al_draw_rounded_rectangle(3) diff --git a/allegro/docs/man/al_draw_ribbon.3 b/allegro/docs/man/al_draw_ribbon.3 new file mode 100644 index 00000000..9154abc0 --- /dev/null +++ b/allegro/docs/man/al_draw_ribbon.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_ribbon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_ribbon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_ribbon(const float *points, int points_stride, ALLEGRO_COLOR color, + float thickness, int num_segments) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a ribbon given an array of points. +The ribbon will go through all of the passed points. +The points buffer should consist of regularly spaced doublets of floats, +corresponding to x and y coordinates of the vertices. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +points - An array of coordinate pairs (x and y) for each point +.IP \[bu] 2 +points_stride - Distance (in bytes) between starts of successive pairs +of coordinates in the points buffer +.IP \[bu] 2 +color - Color of the spline +.IP \[bu] 2 +thickness - Thickness of the spline, pass \f[C]<= 0\f[R] to draw +hairline spline +.IP \[bu] 2 +num_segments - The number of segments +.SH SEE ALSO +.PP +al_calculate_ribbon(3) diff --git a/allegro/docs/man/al_draw_rotated_bitmap.3 b/allegro/docs/man/al_draw_rotated_bitmap.3 new file mode 100644 index 00000000..46ff0201 --- /dev/null +++ b/allegro/docs/man/al_draw_rotated_bitmap.3 @@ -0,0 +1,57 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_rotated_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_rotated_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap, + float cx, float cy, float dx, float dy, float angle, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a rotated version of the given bitmap to the target bitmap. +The bitmap is rotated by `angle' radians clockwise. +.PP +The point at cx/cy relative to the upper left corner of the bitmap will +be drawn at dx/dy and the bitmap is rotated around this point. +If cx,cy is 0,0 the bitmap will rotate around its upper left corner. +.IP \[bu] 2 +cx - center x (relative to the bitmap) +.IP \[bu] 2 +cy - center y (relative to the bitmap) +.IP \[bu] 2 +dx - destination x +.IP \[bu] 2 +dy - destination y +.IP \[bu] 2 +angle - angle by which to rotate (radians) +.IP \[bu] 2 +flags - same as for al_draw_bitmap(3) +.PP +Example +.IP +.nf +\f[C] +float w = al_get_bitmap_width(bitmap); +float h = al_get_bitmap_height(bitmap); +al_draw_rotated_bitmap(bitmap, w / 2, h / 2, x, y, ALLEGRO_PI / 2, 0); +\f[R] +.fi +.PP +The above code draws the bitmap centered on x/y and rotates it 90\[de] +clockwise. +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_bitmap(3), al_draw_bitmap_region(3), al_draw_scaled_bitmap(3), +al_draw_scaled_rotated_bitmap(3) diff --git a/allegro/docs/man/al_draw_rounded_rectangle.3 b/allegro/docs/man/al_draw_rounded_rectangle.3 new file mode 100644 index 00000000..3ffd1c21 --- /dev/null +++ b/allegro/docs/man/al_draw_rounded_rectangle.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_rounded_rectangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_rounded_rectangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_rounded_rectangle(float x1, float y1, float x2, float y2, + float rx, float ry, ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an outlined rounded rectangle. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +x1, y1, x2, y2 - Upper left and lower right points of the rectangle +.IP \[bu] 2 +color - Color of the rectangle +.IP \[bu] 2 +rx, ry - The radii of the round +.IP \[bu] 2 +thickness - Thickness of the lines, pass \f[C]<= 0\f[R] to draw hairline +lines +.SH SEE ALSO +.PP +al_draw_filled_rounded_rectangle(3), al_draw_rectangle(3) diff --git a/allegro/docs/man/al_draw_scaled_bitmap.3 b/allegro/docs/man/al_draw_scaled_bitmap.3 new file mode 100644 index 00000000..4c029310 --- /dev/null +++ b/allegro/docs/man/al_draw_scaled_bitmap.3 @@ -0,0 +1,46 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_scaled_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_scaled_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, + float dx, float dy, float dw, float dh, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a scaled version of the given bitmap to the target bitmap. +.IP \[bu] 2 +sx - source x +.IP \[bu] 2 +sy - source y +.IP \[bu] 2 +sw - source width +.IP \[bu] 2 +sh - source height +.IP \[bu] 2 +dx - destination x +.IP \[bu] 2 +dy - destination y +.IP \[bu] 2 +dw - destination width +.IP \[bu] 2 +dh - destination height +.IP \[bu] 2 +flags - same as for al_draw_bitmap(3) +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_bitmap(3), al_draw_bitmap_region(3), al_draw_rotated_bitmap(3), +al_draw_scaled_rotated_bitmap(3), diff --git a/allegro/docs/man/al_draw_scaled_rotated_bitmap.3 b/allegro/docs/man/al_draw_scaled_rotated_bitmap.3 new file mode 100644 index 00000000..e64ad021 --- /dev/null +++ b/allegro/docs/man/al_draw_scaled_rotated_bitmap.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_scaled_rotated_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_scaled_rotated_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap, + float cx, float cy, float dx, float dy, float xscale, float yscale, + float angle, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_rotated_bitmap(3), but can also scale the bitmap. +.PP +The point at cx/cy in the bitmap will be drawn at dx/dy and the bitmap +is rotated and scaled around this point. +.IP \[bu] 2 +cx - center x +.IP \[bu] 2 +cy - center y +.IP \[bu] 2 +dx - destination x +.IP \[bu] 2 +dy - destination y +.IP \[bu] 2 +xscale - how much to scale on the x-axis (e.g.\ 2 for twice the size) +.IP \[bu] 2 +yscale - how much to scale on the y-axis +.IP \[bu] 2 +angle - angle by which to rotate (radians) +.IP \[bu] 2 +flags - same as for al_draw_bitmap(3) +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_bitmap(3), al_draw_bitmap_region(3), al_draw_scaled_bitmap(3), +al_draw_rotated_bitmap(3) diff --git a/allegro/docs/man/al_draw_soft_line.3 b/allegro/docs/man/al_draw_soft_line.3 new file mode 100644 index 00000000..888da062 --- /dev/null +++ b/allegro/docs/man/al_draw_soft_line.3 @@ -0,0 +1,54 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_soft_line" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_soft_line - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_soft_line(ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state, + void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a line using the software rasterizer and user supplied pixel +functions. +For help in understanding what these functions do, see the +implementation of the various shading routines in +addons/primitives/line_soft.c. +The line is drawn top to bottom. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +v1, v2 - The two vertices of the line +.IP \[bu] 2 +state - A pointer to a user supplied struct, this struct will be passed +to all the pixel functions +.IP \[bu] 2 +first - Called before drawing the first pixel of the line. +It is passed the coordinates of this pixel, as well as the two vertices +above. +The passed vertices may have been altered by clipping. +.IP \[bu] 2 +step - Called once per pixel. +The second parameter is set to 1 if the step is a minor step, and 0 if +this step is a major step. +Minor steps are taken only either in x or y directions. +Major steps are taken in both directions diagonally. +In all cases, the absolute value of the change in coordinate is at most +1 in either direction. +.IP \[bu] 2 +draw - Called once per pixel. +The function is expected to draw the pixel at the coordinates passed to +it. +.SH SEE ALSO +.PP +al_draw_line(3) diff --git a/allegro/docs/man/al_draw_soft_triangle.3 b/allegro/docs/man/al_draw_soft_triangle.3 new file mode 100644 index 00000000..ae6b203a --- /dev/null +++ b/allegro/docs/man/al_draw_soft_triangle.3 @@ -0,0 +1,67 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_soft_triangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_soft_triangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_soft_triangle( + ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, + void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*first)(uintptr_t, int, int, int, int), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int, int)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a triangle using the software rasterizer and user supplied pixel +functions. +For help in understanding what these functions do, see the +implementation of the various shading routines in +addons/primitives/tri_soft.c. +The triangle is drawn in two segments, from top to bottom. +The segments are deliniated by the vertically middle vertex of the +triangle. +One of the two segments may be absent if two vertices are horizontally +collinear. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +v1, v2, v3 - The three vertices of the triangle +.IP \[bu] 2 +state - A pointer to a user supplied struct, this struct will be passed +to all the pixel functions +.IP \[bu] 2 +init - Called once per call before any drawing is done. +The three points passed to it may be altered by clipping. +.IP \[bu] 2 +first - Called twice per call, once per triangle segment. +It is passed 4 parameters, the first two are the coordinates of the +initial pixel drawn in the segment. +The second two are the left minor and the left major steps, +respectively. +They represent the sizes of two steps taken by the rasterizer as it +walks on the left side of the triangle. +From then on, each step will either be classified as a minor or a major +step, corresponding to the above values. +.IP \[bu] 2 +step - Called once per scanline. +The last parameter is set to 1 if the step is a minor step, and 0 if it +is a major step. +.IP \[bu] 2 +draw - Called once per scanline. +The function is expected to draw the scanline starting with a point +specified by the first two parameters (corresponding to x and y values) +going to the right until it reaches the value of the third parameter +(the x value of the end point). +All coordinates are inclusive. +.SH SEE ALSO +.PP +al_draw_triangle(3) diff --git a/allegro/docs/man/al_draw_spline.3 b/allegro/docs/man/al_draw_spline.3 new file mode 100644 index 00000000..6fab4518 --- /dev/null +++ b/allegro/docs/man/al_draw_spline.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_spline" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_spline - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_spline(float points[8], ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a B\['e]zier spline given 4 control points. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +points - An array of 4 pairs of coordinates of the 4 control points +.IP \[bu] 2 +color - Color of the spline +.IP \[bu] 2 +thickness - Thickness of the spline, pass \f[C]<= 0\f[R] to draw a +hairline spline +.SH SEE ALSO +.PP +al_calculate_spline(3) diff --git a/allegro/docs/man/al_draw_text.3 b/allegro/docs/man/al_draw_text.3 new file mode 100644 index 00000000..d255c6f4 --- /dev/null +++ b/allegro/docs/man/al_draw_text.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_text" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_text - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_text(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, int flags, + char const *text) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes the NUL-terminated string \f[C]text\f[R] onto the target bitmap +at position \f[C]x\f[R], \f[C]y\f[R], using the specified +\f[C]font\f[R]. +.PP +The \f[C]flags\f[R] parameter can be 0 or one of the following flags: +.IP \[bu] 2 +ALLEGRO_ALIGN_LEFT - Draw the text left-aligned (same as 0). +.IP \[bu] 2 +ALLEGRO_ALIGN_CENTRE - Draw the text centered around the given position. +.IP \[bu] 2 +ALLEGRO_ALIGN_RIGHT - Draw the text right-aligned to the given position. +.PP +It can also be combined with this flag: +.IP \[bu] 2 +ALLEGRO_ALIGN_INTEGER - Always draw text aligned to an integer pixel +position. +This was formerly the default behaviour. +Since: 5.0.8, 5.1.4 +.PP +This function does not support newline characters (\f[C]\[rs]n\f[R]), +but you can use al_draw_multiline_text(3) for multi line text output. +.SH SEE ALSO +.PP +al_draw_ustr(3), al_draw_textf(3), al_draw_justified_text(3), +al_draw_multiline_text(3). diff --git a/allegro/docs/man/al_draw_textf.3 b/allegro/docs/man/al_draw_textf.3 new file mode 100644 index 00000000..2aa4e0dd --- /dev/null +++ b/allegro/docs/man/al_draw_textf.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_textf" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_textf - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_textf(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, + float x, float y, int flags, + const char *format, ...) +\f[R] +.fi +.SH DESCRIPTION +.PP +Formatted text output, using a printf() style format string. +All parameters have the same meaning as with al_draw_text(3) otherwise. +.SH SEE ALSO +.PP +al_draw_text(3), al_draw_ustr(3) diff --git a/allegro/docs/man/al_draw_tinted_bitmap.3 b/allegro/docs/man/al_draw_tinted_bitmap.3 new file mode 100644 index 00000000..b31903d0 --- /dev/null +++ b/allegro/docs/man/al_draw_tinted_bitmap.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_tinted_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_tinted_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_tinted_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, + float dx, float dy, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_bitmap(3) but multiplies all colors in the bitmap with the +given color. +For example: +.IP +.nf +\f[C] +al_draw_tinted_bitmap(bitmap, al_map_rgba_f(0.5, 0.5, 0.5, 0.5), x, y, 0); +\f[R] +.fi +.PP +The above will draw the bitmap 50% transparently (r/g/b values need to +be pre-multiplied with the alpha component with the default blend mode). +.IP +.nf +\f[C] +al_draw_tinted_bitmap(bitmap, al_map_rgba_f(1, 0, 0, 1), x, y, 0); +\f[R] +.fi +.PP +The above will only draw the red component of the bitmap. +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_bitmap(3) diff --git a/allegro/docs/man/al_draw_tinted_bitmap_region.3 b/allegro/docs/man/al_draw_tinted_bitmap_region.3 new file mode 100644 index 00000000..4b3003bc --- /dev/null +++ b/allegro/docs/man/al_draw_tinted_bitmap_region.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_tinted_bitmap_region" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_tinted_bitmap_region - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float sx, float sy, float sw, float sh, float dx, float dy, + int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_bitmap_region(3) but multiplies all colors in the bitmap +with the given color. +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_tinted_bitmap(3) diff --git a/allegro/docs/man/al_draw_tinted_rotated_bitmap.3 b/allegro/docs/man/al_draw_tinted_rotated_bitmap.3 new file mode 100644 index 00000000..4381ec66 --- /dev/null +++ b/allegro/docs/man/al_draw_tinted_rotated_bitmap.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_tinted_rotated_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_tinted_rotated_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float cx, float cy, float dx, float dy, float angle, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_rotated_bitmap(3) but multiplies all colors in the bitmap +with the given color. +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_tinted_bitmap(3) diff --git a/allegro/docs/man/al_draw_tinted_scaled_bitmap.3 b/allegro/docs/man/al_draw_tinted_scaled_bitmap.3 new file mode 100644 index 00000000..1a937988 --- /dev/null +++ b/allegro/docs/man/al_draw_tinted_scaled_bitmap.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_tinted_scaled_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_tinted_scaled_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float sx, float sy, float sw, float sh, + float dx, float dy, float dw, float dh, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_scaled_bitmap(3) but multiplies all colors in the bitmap +with the given color. +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_tinted_bitmap(3) diff --git a/allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap.3 b/allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap.3 new file mode 100644 index 00000000..9d68b06d --- /dev/null +++ b/allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_tinted_scaled_rotated_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_tinted_scaled_rotated_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float cx, float cy, float dx, float dy, float xscale, float yscale, + float angle, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_scaled_rotated_bitmap(3) but multiplies all colors in the +bitmap with the given color. +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SEE ALSO +.PP +al_draw_tinted_bitmap(3) diff --git a/allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap_region.3 b/allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap_region.3 new file mode 100644 index 00000000..a6f65666 --- /dev/null +++ b/allegro/docs/man/al_draw_tinted_scaled_rotated_bitmap_region.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_tinted_scaled_rotated_bitmap_region" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_tinted_scaled_rotated_bitmap_region - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, + ALLEGRO_COLOR tint, + float cx, float cy, float dx, float dy, float xscale, float yscale, + float angle, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_tinted_scaled_rotated_bitmap(3) but you specify an area +within the bitmap to be drawn. +.PP +You can get the same effect with a sub bitmap: +.IP +.nf +\f[C] +al_draw_tinted_scaled_rotated_bitmap(bitmap, sx, sy, sw, sh, tint, + cx, cy, dx, dy, xscale, yscale, angle, flags); + +/* This draws the same: */ +sub_bitmap = al_create_sub_bitmap(bitmap, sx, sy, sw, sh); +al_draw_tinted_scaled_rotated_bitmap(sub_bitmap, tint, cx, cy, + dx, dy, xscale, yscale, angle, flags); +\f[R] +.fi +.PP +See al_draw_bitmap(3) for a note on restrictions on which bitmaps can be +drawn where. +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_draw_tinted_bitmap(3) diff --git a/allegro/docs/man/al_draw_triangle.3 b/allegro/docs/man/al_draw_triangle.3 new file mode 100644 index 00000000..03c83098 --- /dev/null +++ b/allegro/docs/man/al_draw_triangle.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_triangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_triangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_triangle(float x1, float y1, float x2, float y2, + float x3, float y3, ALLEGRO_COLOR color, float thickness) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws an outlined triangle. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +x1, y1, x2, y2, x3, y3 - Three points of the triangle +.IP \[bu] 2 +color - Color of the triangle +.IP \[bu] 2 +thickness - Thickness of the lines, pass \f[C]<= 0\f[R] to draw hairline +lines +.SH SEE ALSO +.PP +al_draw_filled_triangle(3), al_draw_soft_triangle(3) diff --git a/allegro/docs/man/al_draw_ustr.3 b/allegro/docs/man/al_draw_ustr.3 new file mode 100644 index 00000000..592234da --- /dev/null +++ b/allegro/docs/man/al_draw_ustr.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_ustr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_ustr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_draw_ustr(const ALLEGRO_FONT *font, + ALLEGRO_COLOR color, float x, float y, int flags, + const ALLEGRO_USTR *ustr) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_draw_text(3), except the text is passed as an ALLEGRO_USTR +instead of a NUL-terminated char array. +.SH SEE ALSO +.PP +al_draw_text(3), al_draw_justified_ustr(3), al_draw_multiline_ustr(3) diff --git a/allegro/docs/man/al_draw_vertex_buffer.3 b/allegro/docs/man/al_draw_vertex_buffer.3 new file mode 100644 index 00000000..97c67611 --- /dev/null +++ b/allegro/docs/man/al_draw_vertex_buffer.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_draw_vertex_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_draw_vertex_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_draw_vertex_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer, + ALLEGRO_BITMAP* texture, int start, int end, int type) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draws a subset of the passed vertex buffer. +The vertex buffer must not be locked. +Additionally, to draw onto memory bitmaps or with memory bitmap textures +the vertex buffer must support reading (i.e.\ it must be created with +the \f[C]ALLEGRO_PRIM_BUFFER_READWRITE\f[R]). +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +vertex_buffer - Vertex buffer to draw +.IP \[bu] 2 +texture - Texture to use, pass NULL to use only color shaded primitves +.IP \[bu] 2 +start - Start index of the subset of the vertex buffer to draw +.IP \[bu] 2 +end - One past the last index of the subset of the vertex buffer to draw +.IP \[bu] 2 +type - A member of the ALLEGRO_PRIM_TYPE(3) enumeration, specifying what +kind of primitive to draw +.PP +\f[I]Returns:\f[R] Number of primitives drawn +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_BUFFER(3), ALLEGRO_PRIM_TYPE(3) diff --git a/allegro/docs/man/al_drop_next_event.3 b/allegro/docs/man/al_drop_next_event.3 new file mode 100644 index 00000000..3d909ed5 --- /dev/null +++ b/allegro/docs/man/al_drop_next_event.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_drop_next_event" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_drop_next_event - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_drop_next_event(ALLEGRO_EVENT_QUEUE *queue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Drop (remove) the next event from the queue. +If the queue is empty, nothing happens. +Returns true if an event was dropped. +.SH SEE ALSO +.PP +al_flush_event_queue(3), al_is_event_queue_empty(3) diff --git a/allegro/docs/man/al_drop_path_tail.3 b/allegro/docs/man/al_drop_path_tail.3 new file mode 100644 index 00000000..e0228bde --- /dev/null +++ b/allegro/docs/man/al_drop_path_tail.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_drop_path_tail" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_drop_path_tail - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_drop_path_tail(ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Remove the last directory component, if any. +.SH SEE ALSO +.PP +al_remove_path_component(3) diff --git a/allegro/docs/man/al_emit_user_event.3 b/allegro/docs/man/al_emit_user_event.3 new file mode 100644 index 00000000..38ee499d --- /dev/null +++ b/allegro/docs/man/al_emit_user_event.3 @@ -0,0 +1,57 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_emit_user_event" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_emit_user_event - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src, + ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Emit an event from a user event source. +The event source must have been initialised with +al_init_user_event_source(3). +Returns \f[C]false\f[R] if the event source isn\[cq]t registered with +any queues, hence the event wouldn\[cq]t have been delivered into any +queues. +.PP +Events are \f[I]copied\f[R] in and out of event queues, so after this +function returns the memory pointed to by \f[C]event\f[R] may be freed +or reused. +Some fields of the event being passed in may be modified by the +function. +.PP +Reference counting will be performed if \f[C]dtor\f[R] is not NULL. +Whenever a copy of the event is made, the reference count increases. +You need to call al_unref_user_event(3) to decrease the reference count +once you are done with a user event that you have received from +al_get_next_event(3), al_peek_next_event(3), al_wait_for_event(3), etc. +.PP +Once the reference count drops to zero \f[C]dtor\f[R] will be called +with a copy of the event as an argument. +It should free the resources associated with the event, but +\f[I]not\f[R] the event itself (since it is just a copy). +.PP +If \f[C]dtor\f[R] is NULL then reference counting will not be performed. +It is safe, but unnecessary, to call al_unref_user_event(3) on +non-reference counted user events. +.PP +You can use al_emit_user_event to emit both user and non-user events +from your user event source. +Note that emitting input events will not update the corresponding input +device states. +For example, you may emit an event of type ALLEGRO_EVENT_KEY_DOWN(3), +but it will not update the ALLEGRO_KEYBOARD_STATE(3) returned by +al_get_keyboard_state(3). +.SH SEE ALSO +.PP +ALLEGRO_USER_EVENT(3), al_unref_user_event(3) diff --git a/allegro/docs/man/al_enable_menu_event_source.3 b/allegro/docs/man/al_enable_menu_event_source.3 new file mode 100644 index 00000000..5fd4d30d --- /dev/null +++ b/allegro/docs/man/al_enable_menu_event_source.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_enable_menu_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_enable_menu_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_enable_menu_event_source(ALLEGRO_MENU *menu) +\f[R] +.fi +.SH DESCRIPTION +.PP +Enables a unique event source for this menu. +It and all of its sub-menus will use this event source. +(It is safe to call this multiple times on the same menu.) +.PP +Returns the event source. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_register_event_source(3), al_get_default_menu_event_source(3), +al_disable_menu_event_source(3) diff --git a/allegro/docs/man/al_fclearerr.3 b/allegro/docs/man/al_fclearerr.3 new file mode 100644 index 00000000..458bf988 --- /dev/null +++ b/allegro/docs/man/al_fclearerr.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fclearerr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fclearerr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_fclearerr(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Clear the error indicator for the given file. +.PP +The standard I/O backend also clears the end-of-file indicator, and +other backends \f[I]should\f[R] try to do this. +However, they may not if it would require too much effort +(e.g.\ PhysicsFS backend), so your code should not rely on it if you +need your code to be portable to other backends. +.SH SEE ALSO +.PP +al_ferror(3), al_feof(3) diff --git a/allegro/docs/man/al_fclose.3 b/allegro/docs/man/al_fclose.3 new file mode 100644 index 00000000..cf921799 --- /dev/null +++ b/allegro/docs/man/al_fclose.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fclose" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fclose - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_fclose(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Close the given file, writing any buffered output data (if any). +.PP +Returns true on success, false on failure. +errno is set to indicate the error. diff --git a/allegro/docs/man/al_feof.3 b/allegro/docs/man/al_feof.3 new file mode 100644 index 00000000..cb19c3c8 --- /dev/null +++ b/allegro/docs/man/al_feof.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_feof" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_feof - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_feof(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the end-of-file indicator has been set on the file, +i.e.\ we have attempted to read \f[I]past\f[R] the end of the file. +.PP +This does \f[I]not\f[R] return true if we simply are at the end of the +file. +The following code correctly reads two bytes, even when the file +contains exactly two bytes: +.IP +.nf +\f[C] +int b1 = al_fgetc(f); +int b2 = al_fgetc(f); +if (al_feof(f)) { + /* At least one byte was unsuccessfully read. */ + report_error(); +} +\f[R] +.fi +.SH SEE ALSO +.PP +al_ferror(3), al_fclearerr(3) diff --git a/allegro/docs/man/al_ferrmsg.3 b/allegro/docs/man/al_ferrmsg.3 new file mode 100644 index 00000000..318f85e9 --- /dev/null +++ b/allegro/docs/man/al_ferrmsg.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ferrmsg" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ferrmsg - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_ferrmsg(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a message string with details about the last error that occurred +on the given file handle. +The returned string is empty if there was no error, or if the file +interface does not provide more information. +.SH SEE ALSO +.PP +al_fclearerr(3), al_ferror(3) diff --git a/allegro/docs/man/al_ferror.3 b/allegro/docs/man/al_ferror.3 new file mode 100644 index 00000000..3fe46f3d --- /dev/null +++ b/allegro/docs/man/al_ferror.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ferror" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ferror - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ferror(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns non-zero if the error indicator is set on the given file, +i.e.\ there was some sort of previous error. +The error code may be system or file interface specific. +.SH SEE ALSO +.PP +al_feof(3), al_fclearerr(3), al_ferrmsg(3) diff --git a/allegro/docs/man/al_fflush.3 b/allegro/docs/man/al_fflush.3 new file mode 100644 index 00000000..321dda69 --- /dev/null +++ b/allegro/docs/man/al_fflush.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fflush" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fflush - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_fflush(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Flush any pending writes to the given file. +.PP +Returns true on success, false otherwise. +errno is set to indicate the error. +.SH SEE ALSO +.PP +al_get_errno(3) diff --git a/allegro/docs/man/al_fget_ustr.3 b/allegro/docs/man/al_fget_ustr.3 new file mode 100644 index 00000000..8e2f8e37 --- /dev/null +++ b/allegro/docs/man/al_fget_ustr.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fget_ustr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fget_ustr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_USTR *al_fget_ustr(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Read a string of bytes terminated with a newline or end-of-file. +The line terminator(s), if any, are included in the returned string. +.PP +On success returns a pointer to a new ALLEGRO_USTR structure. +This must be freed eventually with al_ustr_free(3). +Returns NULL if an error occurred or if the end of file was reached +without reading any bytes. +.PP +See al_fopen(3) about translations of end-of-line characters. +.SH SEE ALSO +.PP +al_fgetc(3), al_fgets(3) diff --git a/allegro/docs/man/al_fgetc.3 b/allegro/docs/man/al_fgetc.3 new file mode 100644 index 00000000..af4d5351 --- /dev/null +++ b/allegro/docs/man/al_fgetc.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fgetc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fgetc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_fgetc(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Read and return next byte in the given file. +Returns EOF on end of file or if an error occurred. +.SH SEE ALSO +.PP +al_fungetc(3) diff --git a/allegro/docs/man/al_fgets.3 b/allegro/docs/man/al_fgets.3 new file mode 100644 index 00000000..6cf77c61 --- /dev/null +++ b/allegro/docs/man/al_fgets.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fgets" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fgets - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char *al_fgets(ALLEGRO_FILE *f, char * const buf, size_t max) +\f[R] +.fi +.SH DESCRIPTION +.PP +Read a string of bytes terminated with a newline or end-of-file into the +buffer given. +The line terminator(s), if any, are included in the returned string. +A maximum of max-1 bytes are read, with one byte being reserved for a +NUL terminator. +.PP +Parameters: +.IP \[bu] 2 +f - file to read from +.IP \[bu] 2 +buf - buffer to fill +.IP \[bu] 2 +max - maximum size of buffer +.PP +Returns the pointer to buf on success. +Returns NULL if an error occurred or if the end of file was reached +without reading any bytes. +.PP +See al_fopen(3) about translations of end-of-line characters. +.SH SEE ALSO +.PP +al_fget_ustr(3) diff --git a/allegro/docs/man/al_filename_exists.3 b/allegro/docs/man/al_filename_exists.3 new file mode 100644 index 00000000..f8cdfa40 --- /dev/null +++ b/allegro/docs/man/al_filename_exists.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_filename_exists" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_filename_exists - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_filename_exists(const char *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Check if the path exists on the filesystem, without creating an +ALLEGRO_FS_ENTRY(3) object explicitly. +.SH SEE ALSO +.PP +al_fs_entry_exists(3) diff --git a/allegro/docs/man/al_fill_silence.3 b/allegro/docs/man/al_fill_silence.3 new file mode 100644 index 00000000..e1d70548 --- /dev/null +++ b/allegro/docs/man/al_fill_silence.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fill_silence" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fill_silence - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_fill_silence(void *buf, unsigned int samples, + ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) +\f[R] +.fi +.SH DESCRIPTION +.PP +Fill a buffer with silence, for the given format and channel +configuration. +The buffer must have enough space for the given number of samples, and +be properly aligned. +.SH SINCE +.PP +5.1.8 diff --git a/allegro/docs/man/al_find_menu.3 b/allegro/docs/man/al_find_menu.3 new file mode 100644 index 00000000..d12f4436 --- /dev/null +++ b/allegro/docs/man/al_find_menu.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_find_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_find_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MENU *al_find_menu(ALLEGRO_MENU *haystack, uint16_t id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Searches in the \f[C]haystack\f[R] menu for any submenu with the given +\f[C]id\f[R]. +(Note that this only represents a literal ID, and cannot be used as an +index.) +.PP +Returns the menu, if found. +Otherwise returns \f[C]NULL\f[R]. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_find_menu_item(3) diff --git a/allegro/docs/man/al_find_menu_item.3 b/allegro/docs/man/al_find_menu_item.3 new file mode 100644 index 00000000..e4dcbbe4 --- /dev/null +++ b/allegro/docs/man/al_find_menu_item.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_find_menu_item" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_find_menu_item - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_find_menu_item(ALLEGRO_MENU *haystack, uint16_t id, ALLEGRO_MENU **menu, + int *index) +\f[R] +.fi +.SH DESCRIPTION +.PP +Searches in the \f[C]haystack\f[R] menu for an item with the given +\f[C]id\f[R]. +(Note that this only represents a literal ID, and cannot be used as an +index.) +.PP +If \f[C]menu\f[R] and \f[C]index\f[R] are not \f[C]NULL\f[R], they will +be set as the parent menu containing the item and the zero-based +(positive) index of the item. +(If the menu item was not found, then their values are undefined.) +.PP +Returns true if the menu item was found. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_find_menu(3) diff --git a/allegro/docs/man/al_fixacos.3 b/allegro/docs/man/al_fixacos.3 new file mode 100644 index 00000000..dbc9b6ab --- /dev/null +++ b/allegro/docs/man/al_fixacos.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixacos" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixacos - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixacos(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +This function finds the inverse cosine of a value using a lookup table. +The input must be a fixed point value. +The inverse cosine is defined only in the domain from -1 to 1. +Outside of this input range, the function will set Allegro\[cq]s errno +to EDOM and return zero. +.PP +Example: +.IP +.nf +\f[C] +al_fixed result; + +/* Sets result to binary angle 128. */ +result = al_fixacos(al_itofix(-1)); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the inverse sine of a fixed point value, measured as fixed point +binary format angle, or zero if the input was out of range. +All return values of this function will be in the range 0 to 128. diff --git a/allegro/docs/man/al_fixadd.3 b/allegro/docs/man/al_fixadd.3 new file mode 100644 index 00000000..211973a9 --- /dev/null +++ b/allegro/docs/man/al_fixadd.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixadd" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixadd - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixadd(al_fixed x, al_fixed y); +\f[R] +.fi +.SH DESCRIPTION +.PP +Although fixed point numbers can be added with the normal \f[C]+\f[R] +integer operator, that doesn\[cq]t provide any protection against +overflow. +If overflow is a problem, you should use this function instead. +It is slower than using integer operators, but if an overflow occurs it +will set Allegro\[cq]s errno and clamp the result, rather than just +letting it wrap. +.PP +Example: +.IP +.nf +\f[C] +al_fixed result; + +/* This will put 5035 into \[ga]result\[aq]. */ +result = al_fixadd(al_itofix(5000), al_itofix(35)); + +/* Sets errno and puts -32768 into \[ga]result\[aq]. */ +result = al_fixadd(al_itofix(-31000), al_itofix(-3000)); +assert(!al_get_errno()); /* This will fail. */ +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the clamped result of adding \f[C]x\f[R] to \f[C]y\f[R], setting +Allegro\[cq]s errno to ERANGE if there was an overflow. +.SH SEE ALSO +.PP +al_fixsub(3), al_fixmul(3), al_fixdiv(3). diff --git a/allegro/docs/man/al_fixasin.3 b/allegro/docs/man/al_fixasin.3 new file mode 100644 index 00000000..26c3c1f3 --- /dev/null +++ b/allegro/docs/man/al_fixasin.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixasin" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixasin - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixasin(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +This function finds the inverse sine of a value using a lookup table. +The input value must be a fixed point value. +The inverse sine is defined only in the domain from -1 to 1. +Outside of this input range, the function will set Allegro\[cq]s errno +to EDOM and return zero. +.PP +Example: +.IP +.nf +\f[C] +float angle; +al_fixed val; + +/* Sets \[ga]val\[aq] to a right binary angle (64). */ +val = al_fixasin(al_itofix(1)); + +/* Sets \[ga]angle\[aq] to 0.2405. */ +angle = al_fixtof(al_fixmul(al_fixasin(al_ftofix(0.238)), al_fixtorad_r)); + +/* This will trigger the assert. */ +val = al_fixasin(al_ftofix(-1.09)); +assert(!al_get_errno()); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the inverse sine of a fixed point value, measured as fixed point +binary format angle, or zero if the input was out of the range. +All return values of this function will be in the range -64 to 64. diff --git a/allegro/docs/man/al_fixatan.3 b/allegro/docs/man/al_fixatan.3 new file mode 100644 index 00000000..520f52c4 --- /dev/null +++ b/allegro/docs/man/al_fixatan.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixatan" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixatan - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixatan(al_fixed x) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function finds the inverse tangent of a value using a lookup table. +The input must be a fixed point value. +The inverse tangent is the value whose tangent is \f[C]x\f[R]. +.PP +Example: +.IP +.nf +\f[C] +al_fixed result; + +/* Sets result to binary angle 13. */ +result = al_fixatan(al_ftofix(0.326)); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the inverse tangent of a fixed point value, measured as a fixed +point binary format angle. diff --git a/allegro/docs/man/al_fixatan2.3 b/allegro/docs/man/al_fixatan2.3 new file mode 100644 index 00000000..93431a91 --- /dev/null +++ b/allegro/docs/man/al_fixatan2.3 @@ -0,0 +1,48 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixatan2" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixatan2 - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixatan2(al_fixed y, al_fixed x) +\f[R] +.fi +.SH DESCRIPTION +.PP +This is a fixed point version of the libc atan2() routine. +It computes the arc tangent of \f[C]y / x\f[R], but the signs of both +arguments are used to determine the quadrant of the result, and +\f[C]x\f[R] is permitted to be zero. +This function is useful to convert Cartesian coordinates to polar +coordinates. +.PP +Example: +.IP +.nf +\f[C] +al_fixed result; + +/* Sets \[ga]result\[aq] to binary angle 64. */ +result = al_fixatan2(al_itofix(1), 0); + +/* Sets \[ga]result\[aq] to binary angle -109. */ +result = al_fixatan2(al_itofix(-1), al_itofix(-2)); + +/* Fails the assert. */ +result = al_fixatan2(0, 0); +assert(!al_get_errno()); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the arc tangent of \f[C]y / x\f[R] in fixed point binary format +angle, from -128 to 128. +If both \f[C]x\f[R] and \f[C]y\f[R] are zero, returns zero and sets +Allegro\[cq]s errno to EDOM. diff --git a/allegro/docs/man/al_fixceil.3 b/allegro/docs/man/al_fixceil.3 new file mode 100644 index 00000000..90e52539 --- /dev/null +++ b/allegro/docs/man/al_fixceil.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixceil" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixceil - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_fixceil(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the smallest integer not less than x. +That is, it rounds towards positive infinity. +.PP +Example: +.IP +.nf +\f[C] +int result; + +/* This will put 34 into \[ga]result\[aq]. */ +result = al_fixceil(al_itofix(100) / 3); + +/* This will round up to 17. */ +result = al_fixceil(al_itofix(100) / 6); +\f[R] +.fi +.SH SEE ALSO +.PP +al_fixtoi(3), al_fixfloor(3). diff --git a/allegro/docs/man/al_fixcos.3 b/allegro/docs/man/al_fixcos.3 new file mode 100644 index 00000000..4278b1e5 --- /dev/null +++ b/allegro/docs/man/al_fixcos.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixcos" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixcos - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixcos(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +This function finds the cosine of a value using a lookup table. +The input value must be a fixed point binary angle. +.PP +Example: +.IP +.nf +\f[C] +al_fixed angle; +float result; + +/* Set the binary angle to 45 degrees. */ +angle = al_itofix(32); + +/* The cosine of 45 degrees is about 0.7071. */ +result = al_fixtof(al_fixcos(angle)); +assert(result > 0.7 && result < 0.71); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the cosine of a fixed point binary format angle as a fixed point +value. diff --git a/allegro/docs/man/al_fixdiv.3 b/allegro/docs/man/al_fixdiv.3 new file mode 100644 index 00000000..dda90deb --- /dev/null +++ b/allegro/docs/man/al_fixdiv.3 @@ -0,0 +1,52 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixdiv" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixdiv - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixdiv(al_fixed x, al_fixed y); +\f[R] +.fi +.SH DESCRIPTION +.PP +A fixed point value can be divided by an integer with the normal +\f[C]/\f[R] operator. +To divide two fixed point values, though, you must use this function. +If a division by zero occurs, Allegro\[cq]s errno will be set and the +maximum possible value will be returned, but errno is not cleared if the +operation is successful. +This means that if you are going to test for division by zero you should +call \f[C]al_set_errno(0)\f[R] before calling al_fixdiv(3). +.PP +Example: +.IP +.nf +\f[C] +al_fixed result; + +/* This will put 0.06060 \[ga]result\[aq]. */ +result = al_fixdiv(al_itofix(2), al_itofix(33)); + +/* This will put 0 into \[ga]result\[aq]. */ +result = al_fixdiv(0, al_itofix(-30)); + +/* Sets errno and puts -32768 into \[ga]result\[aq]. */ +result = al_fixdiv(al_itofix(-100), al_itofix(0)); +assert(!al_get_errno()); /* This will fail. */ +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the result of dividing \f[C]x\f[R] by \f[C]y\f[R]. +If \f[C]y\f[R] is zero, returns the maximum possible fixed point value +and sets Allegro\[cq]s errno to ERANGE. +.SH SEE ALSO +.PP +al_fixadd(3), al_fixsub(3), al_fixmul(3), al_get_errno(3). diff --git a/allegro/docs/man/al_fixed.3 b/allegro/docs/man/al_fixed.3 new file mode 100644 index 00000000..3b2c4506 --- /dev/null +++ b/allegro/docs/man/al_fixed.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +typedef int32_t al_fixed; +\f[R] +.fi +.SH DESCRIPTION +.PP +A fixed point number. +.PP +Allegro provides some routines for working with fixed point numbers, and +defines the type \f[C]al_fixed\f[R] to be a signed 32-bit integer. +The high word is used for the integer part and the low word for the +fraction, giving a range of -32768 to 32767 and an accuracy of about +four or five decimal places. +Fixed point numbers can be assigned, compared, added, subtracted, +negated and shifted (for multiplying or dividing by powers of two) using +the normal integer operators, but you should take care to use the +appropriate conversion routines when mixing fixed point with integer or +floating point values. +Writing \f[C]fixed_point_1 + fixed_point_2\f[R] is OK, but +\f[C]fixed_point + integer\f[R] is not. +.PP +The only advantage of fixed point math routines is that you don\[cq]t +require a floating point coprocessor to use them. +This was great in the time period of i386 and i486 machines, but stopped +being so useful with the coming of the Pentium class of processors. +From Pentium onwards, CPUs have increased their strength in floating +point operations, equaling or even surpassing integer math performance. +However, many embedded processors have no FPUs so fixed point maths can +still be useful there. +.PP +Depending on the type of operations your program may need, using +floating point types may be faster than fixed types if you are targeting +a specific machine class. diff --git a/allegro/docs/man/al_fixfloor.3 b/allegro/docs/man/al_fixfloor.3 new file mode 100644 index 00000000..12c5d44f --- /dev/null +++ b/allegro/docs/man/al_fixfloor.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixfloor" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixfloor - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_fixfloor(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the greatest integer not greater than x. +That is, it rounds towards negative infinity. +.PP +Example: +.IP +.nf +\f[C] +int result; + +/* This will put 33 into \[ga]result\[aq]. */ +result = al_fixfloor(al_itofix(100) / 3); + +/* And this will round down to 16. */ +result = al_fixfloor(al_itofix(100) / 6); +\f[R] +.fi +.SH SEE ALSO +.PP +al_fixtoi(3), al_fixceil(3). diff --git a/allegro/docs/man/al_fixhypot.3 b/allegro/docs/man/al_fixhypot.3 new file mode 100644 index 00000000..b8fd754d --- /dev/null +++ b/allegro/docs/man/al_fixhypot.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixhypot" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixhypot - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixhypot(al_fixed x, al_fixed y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Fixed point hypotenuse (returns the square root of \f[C]x*x + y*y\f[R]). +This should be better than calculating the formula yourself manually, +since the error is much smaller. diff --git a/allegro/docs/man/al_fixmul.3 b/allegro/docs/man/al_fixmul.3 new file mode 100644 index 00000000..98c7400a --- /dev/null +++ b/allegro/docs/man/al_fixmul.3 @@ -0,0 +1,49 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixmul" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixmul - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixmul(al_fixed x, al_fixed y); +\f[R] +.fi +.SH DESCRIPTION +.PP +A fixed point value can be multiplied or divided by an integer with the +normal \f[C]*\f[R] and \f[C]/\f[R] operators. +To multiply two fixed point values, though, you must use this function. +.PP +If an overflow occurs, Allegro\[cq]s errno will be set and the maximum +possible value will be returned, but errno is not cleared if the +operation is successful. +This means that if you are going to test for overflow you should call +\f[C]al_set_errno(0)\f[R] before calling al_fixmul(3). +.PP +Example: +.IP +.nf +\f[C] +al_fixed result; + +/* This will put 30000 into \[ga]result\[aq]. */ +result = al_fixmul(al_itofix(10), al_itofix(3000)); + +/* But this overflows, and sets errno. */ +result = al_fixmul(al_itofix(100), al_itofix(3000)); +assert(!al_get_errno()); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the clamped result of multiplying \f[C]x\f[R] by \f[C]y\f[R], +setting Allegro\[cq]s errno to ERANGE if there was an overflow. +.SH SEE ALSO +.PP +al_fixadd(3), al_fixsub(3), al_fixdiv(3), al_get_errno(3). diff --git a/allegro/docs/man/al_fixsin.3 b/allegro/docs/man/al_fixsin.3 new file mode 100644 index 00000000..61aa4e83 --- /dev/null +++ b/allegro/docs/man/al_fixsin.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixsin" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixsin - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixsin(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +This function finds the sine of a value using a lookup table. +The input value must be a fixed point binary angle. +.PP +Example: +.IP +.nf +\f[C] +al_fixed angle; +int result; + +/* Set the binary angle to 90 degrees. */ +angle = al_itofix(64); + +/* The sine of 90 degrees is one. */ +result = al_fixtoi(al_fixsin(angle)); +assert(result == 1); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the sine of a fixed point binary format angle as a fixed point +value. diff --git a/allegro/docs/man/al_fixsqrt.3 b/allegro/docs/man/al_fixsqrt.3 new file mode 100644 index 00000000..c8f181ac --- /dev/null +++ b/allegro/docs/man/al_fixsqrt.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixsqrt" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixsqrt - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixsqrt(al_fixed x) +\f[R] +.fi +.SH DESCRIPTION +.PP +This finds out the non negative square root of \f[C]x\f[R]. +If \f[C]x\f[R] is negative, Allegro\[cq]s errno is set to EDOM and the +function returns zero. diff --git a/allegro/docs/man/al_fixsub.3 b/allegro/docs/man/al_fixsub.3 new file mode 100644 index 00000000..7674b03e --- /dev/null +++ b/allegro/docs/man/al_fixsub.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixsub" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixsub - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixsub(al_fixed x, al_fixed y); +\f[R] +.fi +.SH DESCRIPTION +.PP +Although fixed point numbers can be subtracted with the normal +\f[C]-\f[R] integer operator, that doesn\[cq]t provide any protection +against overflow. +If overflow is a problem, you should use this function instead. +It is slower than using integer operators, but if an overflow occurs it +will set Allegro\[cq]s errno and clamp the result, rather than just +letting it wrap. +.PP +Example: +.IP +.nf +\f[C] +al_fixed result; + +/* This will put 4965 into \[ga]result\[aq]. */ +result = al_fixsub(al_itofix(5000), al_itofix(35)); + +/* Sets errno and puts -32768 into \[ga]result\[aq]. */ +result = al_fixsub(al_itofix(-31000), al_itofix(3000)); +assert(!al_get_errno()); /* This will fail. */ +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the clamped result of subtracting \f[C]y\f[R] from \f[C]x\f[R], +setting Allegro\[cq]s errno to ERANGE if there was an overflow. +.SH SEE ALSO +.PP +al_fixadd(3), al_fixmul(3), al_fixdiv(3), al_get_errno(3). diff --git a/allegro/docs/man/al_fixtan.3 b/allegro/docs/man/al_fixtan.3 new file mode 100644 index 00000000..65f3d314 --- /dev/null +++ b/allegro/docs/man/al_fixtan.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixtan" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixtan - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_fixtan(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +This function finds the tangent of a value using a lookup table. +The input value must be a fixed point binary angle. +.PP +Example: +.IP +.nf +\f[C] +al_fixed angle, res_a, res_b; +float dif; + +angle = al_itofix(37); +/* Prove that tan(angle) == sin(angle) / cos(angle). */ +res_a = al_fixdiv(al_fixsin(angle), al_fixcos(angle)); +res_b = al_fixtan(angle); +dif = al_fixtof(al_fixsub(res_a, res_b)); +printf(\[dq]Precision error: %f\[rs]n\[dq], dif); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the tangent of a fixed point binary format angle as a fixed +point value. diff --git a/allegro/docs/man/al_fixtof.3 b/allegro/docs/man/al_fixtof.3 new file mode 100644 index 00000000..e3b7fd82 --- /dev/null +++ b/allegro/docs/man/al_fixtof.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixtof" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixtof - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_fixtof(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +Converts fixed point to floating point. +.PP +Example: +.IP +.nf +\f[C] +float result; + +/* This will put 33.33333 into \[ga]result\[aq]. */ +result = al_fixtof(al_itofix(100) / 3); + +/* This will put 16.66666 into \[ga]result\[aq]. */ +result = al_fixtof(al_itofix(100) / 6); +\f[R] +.fi +.SH SEE ALSO +.PP +al_ftofix(3), al_itofix(3), al_fixtoi(3). diff --git a/allegro/docs/man/al_fixtoi.3 b/allegro/docs/man/al_fixtoi.3 new file mode 100644 index 00000000..c40eea9f --- /dev/null +++ b/allegro/docs/man/al_fixtoi.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixtoi" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixtoi - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_fixtoi(al_fixed x); +\f[R] +.fi +.SH DESCRIPTION +.PP +Converts fixed point to integer, rounding as required to the nearest +integer. +.PP +Example: +.IP +.nf +\f[C] +int result; + +/* This will put 33 into \[ga]result\[aq]. */ +result = al_fixtoi(al_itofix(100) / 3); + +/* But this will round up to 17. */ +result = al_fixtoi(al_itofix(100) / 6); +\f[R] +.fi +.SH SEE ALSO +.PP +al_itofix(3), al_ftofix(3), al_fixtof(3), al_fixfloor(3), al_fixceil(3). diff --git a/allegro/docs/man/al_fixtorad_r.3 b/allegro/docs/man/al_fixtorad_r.3 new file mode 100644 index 00000000..bdb59741 --- /dev/null +++ b/allegro/docs/man/al_fixtorad_r.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fixtorad_r" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fixtorad_r - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const al_fixed al_fixtorad_r = (al_fixed)1608; +\f[R] +.fi +.SH DESCRIPTION +.PP +This constant gives a ratio which can be used to convert a fixed point +number in binary angle format to a fixed point number in radians. +.PP +Example: +.IP +.nf +\f[C] +al_fixed rad_angle, binary_angle; + +/* Set the binary angle to 90 degrees. */ +binary_angle = 64; + +/* Now convert to radians (about 1.57). */ +rad_angle = al_fixmul(binary_angle, al_fixtorad_r); +\f[R] +.fi +.SH SEE ALSO +.PP +al_fixmul(3), al_radtofix_r(3). diff --git a/allegro/docs/man/al_flip_display.3 b/allegro/docs/man/al_flip_display.3 new file mode 100644 index 00000000..ffc339a7 --- /dev/null +++ b/allegro/docs/man/al_flip_display.3 @@ -0,0 +1,48 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_flip_display" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_flip_display - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_flip_display(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Copies or updates the front and back buffers so that what has been drawn +previously on the currently selected display becomes visible on screen. +Pointers to the special back buffer bitmap remain valid and retain their +semantics as the back buffer, although the contents may have changed. +.RS +.PP +\f[I]Note:\f[R] If not using the ALLEGRO_SINGLE_BUFFER option, you +typically want to redraw every pixel of the backbuffer bitmap to avoid +uninitialized memory artifacts. +.RE +.PP +Several display options change how this function behaves: +.IP \[bu] 2 +With ALLEGRO_SINGLE_BUFFER, no flipping is done. +You still have to call this function to display graphics, depending on +how the used graphics system works. +.IP \[bu] 2 +The ALLEGRO_SWAP_METHOD option may have additional information about +what kind of operation is used internally to flip the front and back +buffers. +.IP \[bu] 2 +If ALLEGRO_VSYNC is 1, this function will force waiting for vsync. +If ALLEGRO_VSYNC is 2, this function will not wait for vsync. +With many drivers the vsync behavior is controlled by the user and not +the application, and ALLEGRO_VSYNC will not be set; in this case +al_flip_display(3) will wait for vsync depending on the settings set in +the system\[cq]s graphics preferences. +.SH SEE ALSO +.PP +al_set_new_display_flags(3), al_set_new_display_option(3) diff --git a/allegro/docs/man/al_flush_event_queue.3 b/allegro/docs/man/al_flush_event_queue.3 new file mode 100644 index 00000000..784a58db --- /dev/null +++ b/allegro/docs/man/al_flush_event_queue.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_flush_event_queue" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_flush_event_queue - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_flush_event_queue(ALLEGRO_EVENT_QUEUE *queue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Drops all events, if any, from the queue. +.SH SEE ALSO +.PP +al_drop_next_event(3), al_is_event_queue_empty(3) diff --git a/allegro/docs/man/al_fopen.3 b/allegro/docs/man/al_fopen.3 new file mode 100644 index 00000000..b5f6480b --- /dev/null +++ b/allegro/docs/man/al_fopen.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fopen" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fopen - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILE *al_fopen(const char *path, const char *mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates and opens a file (real or virtual) given the path and mode. +The current file interface is used to open the file. +.PP +Parameters: +.IP \[bu] 2 +path - path to the file to open +.IP \[bu] 2 +mode - access mode to open the file in (\[lq]r\[rq], \[lq]w\[rq], etc.) +.PP +Depending on the stream type and the mode string, files may be opened in +\[lq]text\[rq] mode. +The handling of newlines is particularly important. +For example, using the default stdio-based streams on DOS and Windows +platforms, where the native end-of-line terminators are CR+LF sequences, +a call to al_fgetc(3) may return just one character (`\[rs]n') where +there were two bytes (CR+LF) in the file. +When writing out `\[rs]n', two bytes would be written instead. +(As an aside, `\[rs]n' is not defined to be equal to LF either.) +.PP +Newline translations can be useful for text files but is disastrous for +binary files. +To avoid this behaviour you need to open file streams in binary mode by +using a mode argument containing a \[lq]b\[rq], e.g.\ \[lq]rb\[rq], +\[lq]wb\[rq]. +.PP +Returns a file handle on success, or NULL on error. +.SH SEE ALSO +.PP +al_set_new_file_interface(3), al_fclose(3). diff --git a/allegro/docs/man/al_fopen_fd.3 b/allegro/docs/man/al_fopen_fd.3 new file mode 100644 index 00000000..8bec590b --- /dev/null +++ b/allegro/docs/man/al_fopen_fd.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fopen_fd" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fopen_fd - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILE *al_fopen_fd(int fd, const char *mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create an ALLEGRO_FILE(3) object that operates on an open file +descriptor using stdio routines. +See the documentation of fdopen() for a description of the `mode' +argument. +.PP +Returns an ALLEGRO_FILE object on success or NULL on an error. +On an error, the Allegro errno will be set and the file descriptor will +not be closed. +.PP +The file descriptor will be closed by al_fclose(3) so you should not +call close() on it. +.SH SEE ALSO +.PP +al_fopen(3) diff --git a/allegro/docs/man/al_fopen_interface.3 b/allegro/docs/man/al_fopen_interface.3 new file mode 100644 index 00000000..76da9e9d --- /dev/null +++ b/allegro/docs/man/al_fopen_interface.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fopen_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fopen_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILE *al_fopen_interface(const ALLEGRO_FILE_INTERFACE *drv, + const char *path, const char *mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Opens a file using the specified interface, instead of the interface set +with al_set_new_file_interface(3). +.SH SEE ALSO +.PP +al_fopen(3) diff --git a/allegro/docs/man/al_fopen_slice.3 b/allegro/docs/man/al_fopen_slice.3 new file mode 100644 index 00000000..5f52efae --- /dev/null +++ b/allegro/docs/man/al_fopen_slice.3 @@ -0,0 +1,61 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fopen_slice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fopen_slice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILE *al_fopen_slice(ALLEGRO_FILE *fp, size_t initial_size, const char *mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Opens a slice (subset) of an already open random access file as if it +were a stand alone file. +While the slice is open, the parent file handle must not be used in any +way. +.PP +The slice is opened at the current location of the parent file, up +through \f[C]initial_size\f[R] bytes. +The \f[C]initial_size\f[R] may be any non-negative integer that will not +exceed the bounds of the parent file. +.PP +Seeking with \f[C]ALLEGRO_SEEK_SET\f[R] will be relative to this +starting location. +\f[C]ALLEGRO_SEEK_END\f[R] will be relative to the starting location +plus the size of the slice. +.PP +The mode can be any combination of: +.IP \[bu] 2 +r: read access +.IP \[bu] 2 +w: write access +.IP \[bu] 2 +e: expandable +.PP +For example, a mode of \[lq]rw\[rq] indicates the file can be read and +written. +(Note that this is slightly different from the stdio modes.) Keep in +mind that the parent file must support random access and be open in +normal write mode (not append) for the slice to work in a well defined +way. +.PP +If the slice is marked as expandable, then reads and writes can happen +after the initial end point, and the slice will grow accordingly. +Otherwise, all activity is restricted to the initial size of the slice. +.PP +A slice must be closed with al_fclose(3). +The parent file will then be positioned immediately after the end of the +slice. +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_fopen(3) diff --git a/allegro/docs/man/al_for_each_fs_entry.3 b/allegro/docs/man/al_for_each_fs_entry.3 new file mode 100644 index 00000000..b761f636 --- /dev/null +++ b/allegro/docs/man/al_for_each_fs_entry.3 @@ -0,0 +1,69 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_for_each_fs_entry" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_for_each_fs_entry - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_for_each_fs_entry(ALLEGRO_FS_ENTRY *dir, + int (*callback)(ALLEGRO_FS_ENTRY *dir, void *extra), + void *extra) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function takes the ALLEGRO_FS_ENTRY(3) \f[C]dir\f[R], which should +represent a directory, and looks for any other file system entries that +are in it. +This function will then call the callback function \f[C]callback\f[R] +once for every filesystem entry in the directory \f[C]dir\f[R]. +.PP +The callback \f[C]callback\f[R] must be of type +\f[C]int callback(ALLEGRO_FS_ENTRY * entry, void * extra)\f[R]. +The \f[C]callback\f[R] will be called with a pointer to an +ALLEGRO_FS_ENTRY(3) that matches one file or directory in \f[C]dir\f[R], +and the pointer passed in the \f[C]extra\f[R] parameter to +al_for_each_fs_entry(3). +.PP +When \f[C]callback\f[R] returns \f[C]ALLEGRO_FOR_EACH_FS_ENTRY_STOP\f[R] +or \f[C]ALLEGRO_FOR_EACH_FS_ENTRY_ERROR\f[R], iteration will stop +immediately and al_for_each_fs_entry(3) will return the value the +\f[C]callback\f[R] returned. +.PP +When \f[C]callback\f[R] returns \f[C]ALLEGRO_FOR_EACH_FS_ENTRY_OK\f[R] +iteration will continue normally, and if the ALLEGRO_FS_ENTRY(3) +parameter of \f[C]callback\f[R] is a directory, al_for_each_fs_entry(3) +will call itself on that directory. +Therefore the function will recusively descend into that directory. +.PP +However, when \f[C]callback\f[R] returns +\f[C]ALLEGRO_FOR_EACH_FS_ENTRY_SKIP\f[R] iteration will continue, but +al_for_each_fs_entry(3) will NOT recurse into the ALLEGRO_FS_ENTRY(3) +parameter of \f[C]callback\f[R] even if it is a directory. +.PP +This function will skip any files or directories named \f[C].\f[R] or +\f[C]..\f[R] which may exist on certain platforms and may signify the +current and the parent directory. +The \f[C]callback\f[R] will not be called for files or directories with +such a name. +.PP +Returns ALLEGRO_FOR_EACH_FS_ENTRY_OK if successful, or +ALLEGRO_FOR_EACH_FS_ENTRY_ERROR if something went wrong in processing +the directory. +In that case it will use al_set_errno(3) to indicate the type of error +which occurred. +This function returns ALLEGRO_FOR_EACH_FS_ENTRY_STOP in case iteration +was stopped by making \f[C]callback\f[R] return that value. +In this case, al_set_errno(3) will not be used. +.SH SEE ALSO +.PP +ALLEGRO_FOR_EACH_FS_ENTRY_RESULT(3) +.SH SINCE +.PP +5.1.9 diff --git a/allegro/docs/man/al_fprintf.3 b/allegro/docs/man/al_fprintf.3 new file mode 100644 index 00000000..c2a9881d --- /dev/null +++ b/allegro/docs/man/al_fprintf.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fprintf" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fprintf - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_fprintf(ALLEGRO_FILE *pfile, const char *format, ...) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes to a file with stdio \[lq]printf\[rq]-like formatting. +Returns the number of bytes written, or a negative number on error. +.SH SEE ALSO +.PP +al_vfprintf(3) diff --git a/allegro/docs/man/al_fputc.3 b/allegro/docs/man/al_fputc.3 new file mode 100644 index 00000000..eed31010 --- /dev/null +++ b/allegro/docs/man/al_fputc.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fputc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fputc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_fputc(ALLEGRO_FILE *f, int c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Write a single byte to the given file. +The byte written is the value of c cast to an unsigned char. +.PP +Parameters: +.IP \[bu] 2 +c - byte value to write +.IP \[bu] 2 +f - file to write to +.PP +Returns the written byte (cast back to an int) on success, or EOF on +error. diff --git a/allegro/docs/man/al_fputs.3 b/allegro/docs/man/al_fputs.3 new file mode 100644 index 00000000..e99a9dd8 --- /dev/null +++ b/allegro/docs/man/al_fputs.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fputs" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fputs - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_fputs(ALLEGRO_FILE *f, char const *p) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes a string to file. +Apart from the return value, this is equivalent to: +.IP +.nf +\f[C] +al_fwrite(f, p, strlen(p)); +\f[R] +.fi +.PP +Parameters: +.IP \[bu] 2 +f - file handle to write to +.IP \[bu] 2 +p - string to write +.PP +Returns a non-negative integer on success, EOF on error. +.PP +Note: depending on the stream type and the mode passed to al_fopen(3), +newline characters in the string may or may not be automatically +translated to native end-of-line sequences, e.g.\ CR/LF instead of LF. +.SH SEE ALSO +.PP +al_fwrite(3) diff --git a/allegro/docs/man/al_fread.3 b/allegro/docs/man/al_fread.3 new file mode 100644 index 00000000..9f902b0e --- /dev/null +++ b/allegro/docs/man/al_fread.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fread" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fread - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_fread(ALLEGRO_FILE *f, void *ptr, size_t size) +\f[R] +.fi +.SH DESCRIPTION +.PP +Read `size' bytes into the buffer pointed to by `ptr', from the given +file. +.PP +Returns the number of bytes actually read. +If an error occurs, or the end-of-file is reached, the return value is a +short byte count (or zero). +.PP +al_fread() does not distinguish between EOF and other errors. +Use al_feof(3) and al_ferror(3) to determine which occurred. +.SH SEE ALSO +.PP +al_fgetc(3), al_fread16be(3), al_fread16le(3), al_fread32be(3), +al_fread32le(3) diff --git a/allegro/docs/man/al_fread16be.3 b/allegro/docs/man/al_fread16be.3 new file mode 100644 index 00000000..35db3fe8 --- /dev/null +++ b/allegro/docs/man/al_fread16be.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fread16be" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fread16be - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int16_t al_fread16be(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Reads a 16-bit word in big-endian format (MSB first). +.PP +On success, returns the 16-bit word. +On failure, returns EOF (-1). +Since -1 is also a valid return value, use al_feof(3) to check if the +end of the file was reached prematurely, or al_ferror(3) to check if an +error occurred. +.SH SEE ALSO +.PP +al_fread16le(3) diff --git a/allegro/docs/man/al_fread16le.3 b/allegro/docs/man/al_fread16le.3 new file mode 100644 index 00000000..fefabac1 --- /dev/null +++ b/allegro/docs/man/al_fread16le.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fread16le" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fread16le - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int16_t al_fread16le(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Reads a 16-bit word in little-endian format (LSB first). +.PP +On success, returns the 16-bit word. +On failure, returns EOF (-1). +Since -1 is also a valid return value, use al_feof(3) to check if the +end of the file was reached prematurely, or al_ferror(3) to check if an +error occurred. +.SH SEE ALSO +.PP +al_fread16be(3) diff --git a/allegro/docs/man/al_fread32be.3 b/allegro/docs/man/al_fread32be.3 new file mode 100644 index 00000000..1bb360f2 --- /dev/null +++ b/allegro/docs/man/al_fread32be.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fread32be" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fread32be - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int32_t al_fread32be(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Read a 32-bit word in big-endian format (MSB first). +.PP +On success, returns the 32-bit word. +On failure, returns EOF (-1). +Since -1 is also a valid return value, use al_feof(3) to check if the +end of the file was reached prematurely, or al_ferror(3) to check if an +error occurred. +.SH SEE ALSO +.PP +al_fread32le(3) diff --git a/allegro/docs/man/al_fread32le.3 b/allegro/docs/man/al_fread32le.3 new file mode 100644 index 00000000..e436ecef --- /dev/null +++ b/allegro/docs/man/al_fread32le.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fread32le" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fread32le - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int32_t al_fread32le(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Reads a 32-bit word in little-endian format (LSB first). +.PP +On success, returns the 32-bit word. +On failure, returns EOF (-1). +Since -1 is also a valid return value, use al_feof(3) to check if the +end of the file was reached prematurely, or al_ferror(3) to check if an +error occurred. +.SH SEE ALSO +.PP +al_fread32be(3) diff --git a/allegro/docs/man/al_free.3 b/allegro/docs/man/al_free.3 new file mode 100644 index 00000000..e00a7bd0 --- /dev/null +++ b/allegro/docs/man/al_free.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_free" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_free - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define al_free(p) \[rs] + (al_free_with_context((p), __LINE__, __FILE__, __func__)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like free() in the C standard library, but the implementation may be +overridden. +.PP +Additionally, on Windows, a memory block allocated by one DLL must be +freed from the same DLL. +In the few places where an Allegro function returns a pointer that must +be freed, you must use al_free(3) for portability to Windows. +.PP +This is a macro. +.SH SEE ALSO +.PP +al_malloc(3), al_free_with_context(3) diff --git a/allegro/docs/man/al_free_with_context.3 b/allegro/docs/man/al_free_with_context.3 new file mode 100644 index 00000000..adb59b4e --- /dev/null +++ b/allegro/docs/man/al_free_with_context.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_free_with_context" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_free_with_context - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_free_with_context(void *ptr, + int line, const char *file, const char *func) +\f[R] +.fi +.SH DESCRIPTION +.PP +This calls free() from the Allegro library (this matters on Windows), +unless overridden with al_set_memory_interface(3). +.PP +Generally you should use the al_free(3) macro. diff --git a/allegro/docs/man/al_fs_entry_exists.3 b/allegro/docs/man/al_fs_entry_exists.3 new file mode 100644 index 00000000..29ffcf49 --- /dev/null +++ b/allegro/docs/man/al_fs_entry_exists.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fs_entry_exists" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fs_entry_exists - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_fs_entry_exists(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Check if the given entry exists on in the filesystem. +Returns true if it does exist or false if it doesn\[cq]t exist, or an +error occurred. +Error is indicated in Allegro\[cq]s errno. +.SH SEE ALSO +.PP +al_filename_exists(3) diff --git a/allegro/docs/man/al_fseek.3 b/allegro/docs/man/al_fseek.3 new file mode 100644 index 00000000..c5cba4bd --- /dev/null +++ b/allegro/docs/man/al_fseek.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fseek" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fseek - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the current position of the given file to a position relative to +that specified by `whence', plus `offset' number of bytes. +.PP +`whence' can be: +.IP \[bu] 2 +ALLEGRO_SEEK_SET - seek relative to beginning of file +.IP \[bu] 2 +ALLEGRO_SEEK_CUR - seek relative to current file position +.IP \[bu] 2 +ALLEGRO_SEEK_END - seek relative to end of file +.PP +Returns true on success, false on failure. +errno is set to indicate the error. +.PP +After a successful seek, the end-of-file indicator is cleared and all +pushback bytes are forgotten. +.PP +On some platforms this function may not support large files. +.SH SEE ALSO +.PP +al_ftell(3), al_get_errno(3) diff --git a/allegro/docs/man/al_fsize.3 b/allegro/docs/man/al_fsize.3 new file mode 100644 index 00000000..fb2bd7ef --- /dev/null +++ b/allegro/docs/man/al_fsize.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fsize" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fsize - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int64_t al_fsize(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the size of the file, if it can be determined, or -1 otherwise. diff --git a/allegro/docs/man/al_ftell.3 b/allegro/docs/man/al_ftell.3 new file mode 100644 index 00000000..8ab40f84 --- /dev/null +++ b/allegro/docs/man/al_ftell.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ftell" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ftell - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int64_t al_ftell(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the current position in the given file, or -1 on error. +errno is set to indicate the error. +.PP +On some platforms this function may not support large files. +.SH SEE ALSO +.PP +al_fseek(3), al_get_errno(3) diff --git a/allegro/docs/man/al_ftofix.3 b/allegro/docs/man/al_ftofix.3 new file mode 100644 index 00000000..f19f670d --- /dev/null +++ b/allegro/docs/man/al_ftofix.3 @@ -0,0 +1,44 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ftofix" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ftofix - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_ftofix(double x); +\f[R] +.fi +.SH DESCRIPTION +.PP +Converts a floating point value to fixed point. +Unlike al_itofix(3), this function clamps values which could overflow +the type conversion, setting Allegro\[cq]s errno to ERANGE in the +process if this happens. +.PP +Example: +.IP +.nf +\f[C] +al_fixed number; + +number = al_itofix(-40000); +assert(al_fixfloor(number) == -32768); + +number = al_itofix(64000); +assert(al_fixfloor(number) == 32767); +assert(!al_get_errno()); /* This will fail. */ +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the value of the floating point value converted to fixed point +clamping overflows (and setting Allegro\[cq]s errno). +.SH SEE ALSO +.PP +al_fixtof(3), al_itofix(3), al_fixtoi(3), al_get_errno(3) diff --git a/allegro/docs/man/al_fungetc.3 b/allegro/docs/man/al_fungetc.3 new file mode 100644 index 00000000..0cc6d7e7 --- /dev/null +++ b/allegro/docs/man/al_fungetc.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fungetc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fungetc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_fungetc(ALLEGRO_FILE *f, int c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Ungets a single byte from a file. +Pushed-back bytes are not written to the file, only made available for +subsequent reads, in reverse order. +.PP +The number of pushbacks depends on the backend. +The standard I/O backend only guarantees a single pushback; this depends +on the libc implementation. +.PP +For backends that follow the standard behavior, the pushback buffer will +be cleared after any seeking or writing; also calls to al_fseek(3) and +al_ftell(3) are relative to the number of pushbacks. +If a pushback causes the position to become negative, the behavior of +al_fseek(3) and al_ftell(3) are undefined. +.SH SEE ALSO +.PP +al_fgetc(3), al_get_errno(3) diff --git a/allegro/docs/man/al_fwrite.3 b/allegro/docs/man/al_fwrite.3 new file mode 100644 index 00000000..452bbcba --- /dev/null +++ b/allegro/docs/man/al_fwrite.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fwrite" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fwrite - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) +\f[R] +.fi +.SH DESCRIPTION +.PP +Write `size' bytes from the buffer pointed to by `ptr' into the given +file. +.PP +Returns the number of bytes actually written. +If an error occurs, the return value is a short byte count (or zero). +.SH SEE ALSO +.PP +al_fputc(3), al_fputs(3), al_fwrite16be(3), al_fwrite16le(3), +al_fwrite32be(3), al_fwrite32le(3) diff --git a/allegro/docs/man/al_fwrite16be.3 b/allegro/docs/man/al_fwrite16be.3 new file mode 100644 index 00000000..d0c8db8c --- /dev/null +++ b/allegro/docs/man/al_fwrite16be.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fwrite16be" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fwrite16be - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_fwrite16be(ALLEGRO_FILE *f, int16_t w) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes a 16-bit word in big-endian format (MSB first). +.PP +Returns the number of bytes written: 2 on success, less than 2 on an +error. +.SH SEE ALSO +.PP +al_fwrite16le(3) diff --git a/allegro/docs/man/al_fwrite16le.3 b/allegro/docs/man/al_fwrite16le.3 new file mode 100644 index 00000000..af4107e7 --- /dev/null +++ b/allegro/docs/man/al_fwrite16le.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fwrite16le" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fwrite16le - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_fwrite16le(ALLEGRO_FILE *f, int16_t w) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes a 16-bit word in little-endian format (LSB first). +.PP +Returns the number of bytes written: 2 on success, less than 2 on an +error. +.SH SEE ALSO +.PP +al_fwrite16be(3) diff --git a/allegro/docs/man/al_fwrite32be.3 b/allegro/docs/man/al_fwrite32be.3 new file mode 100644 index 00000000..b22a5040 --- /dev/null +++ b/allegro/docs/man/al_fwrite32be.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fwrite32be" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fwrite32be - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_fwrite32be(ALLEGRO_FILE *f, int32_t l) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes a 32-bit word in big-endian format (MSB first). +.PP +Returns the number of bytes written: 4 on success, less than 4 on an +error. +.SH SEE ALSO +.PP +al_fwrite32le(3) diff --git a/allegro/docs/man/al_fwrite32le.3 b/allegro/docs/man/al_fwrite32le.3 new file mode 100644 index 00000000..4ebd4fce --- /dev/null +++ b/allegro/docs/man/al_fwrite32le.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_fwrite32le" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_fwrite32le - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_fwrite32le(ALLEGRO_FILE *f, int32_t l) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes a 32-bit word in little-endian format (LSB first). +.PP +Returns the number of bytes written: 4 on success, less than 4 on an +error. +.SH SEE ALSO +.PP +al_fwrite32be(3) diff --git a/allegro/docs/man/al_get_allegro_acodec_version.3 b/allegro/docs/man/al_get_allegro_acodec_version.3 new file mode 100644 index 00000000..18512e70 --- /dev/null +++ b/allegro/docs/man/al_get_allegro_acodec_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_acodec_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_acodec_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_acodec_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_audio_version.3 b/allegro/docs/man/al_get_allegro_audio_version.3 new file mode 100644 index 00000000..0f6f390b --- /dev/null +++ b/allegro/docs/man/al_get_allegro_audio_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_audio_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_audio_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_audio_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_color_version.3 b/allegro/docs/man/al_get_allegro_color_version.3 new file mode 100644 index 00000000..8401272f --- /dev/null +++ b/allegro/docs/man/al_get_allegro_color_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_color_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_color_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_color_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_font_version.3 b/allegro/docs/man/al_get_allegro_font_version.3 new file mode 100644 index 00000000..8f3a6f01 --- /dev/null +++ b/allegro/docs/man/al_get_allegro_font_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_font_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_font_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_font_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_image_version.3 b/allegro/docs/man/al_get_allegro_image_version.3 new file mode 100644 index 00000000..d57aa750 --- /dev/null +++ b/allegro/docs/man/al_get_allegro_image_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_image_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_image_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_image_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_memfile_version.3 b/allegro/docs/man/al_get_allegro_memfile_version.3 new file mode 100644 index 00000000..c61d7038 --- /dev/null +++ b/allegro/docs/man/al_get_allegro_memfile_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_memfile_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_memfile_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_memfile_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_native_dialog_version.3 b/allegro/docs/man/al_get_allegro_native_dialog_version.3 new file mode 100644 index 00000000..12c07c49 --- /dev/null +++ b/allegro/docs/man/al_get_allegro_native_dialog_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_native_dialog_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_native_dialog_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_native_dialog_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_physfs_version.3 b/allegro/docs/man/al_get_allegro_physfs_version.3 new file mode 100644 index 00000000..cb24d1ef --- /dev/null +++ b/allegro/docs/man/al_get_allegro_physfs_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_physfs_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_physfs_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_physfs_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_primitives_version.3 b/allegro/docs/man/al_get_allegro_primitives_version.3 new file mode 100644 index 00000000..2f7c539c --- /dev/null +++ b/allegro/docs/man/al_get_allegro_primitives_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_primitives_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_primitives_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_primitives_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_ttf_version.3 b/allegro/docs/man/al_get_allegro_ttf_version.3 new file mode 100644 index 00000000..eaf8aa2d --- /dev/null +++ b/allegro/docs/man/al_get_allegro_ttf_version.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_ttf_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_ttf_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_ttf_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). diff --git a/allegro/docs/man/al_get_allegro_version.3 b/allegro/docs/man/al_get_allegro_version.3 new file mode 100644 index 00000000..7a740c50 --- /dev/null +++ b/allegro/docs/man/al_get_allegro_version.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the Allegro library, packed into a +single integer as groups of 8 bits in the form +\f[C](major << 24) | (minor << 16) | (revision << 8) | release\f[R]. +.PP +You can use code like this to extract them: +.IP +.nf +\f[C] +uint32_t version = al_get_allegro_version(); +int major = version >> 24; +int minor = (version >> 16) & 255; +int revision = (version >> 8) & 255; +int release = version & 255; +\f[R] +.fi +.PP +The \f[C]release\f[R] number is 0 for an unofficial version and 1 or +greater for an official release. +For example \[lq]5.0.2[1]\[rq] would be the (first) official 5.0.2 +release while \[lq]5.0.2[0]\[rq] would be a compile of a version from +the \[lq]5.0.2\[rq] branch before the official release. diff --git a/allegro/docs/man/al_get_allegro_video_version.3 b/allegro/docs/man/al_get_allegro_video_version.3 new file mode 100644 index 00000000..57d306b9 --- /dev/null +++ b/allegro/docs/man/al_get_allegro_video_version.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_allegro_video_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_allegro_video_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_allegro_video_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the (compiled) version of the addon, in the same format as +al_get_allegro_version(3). +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_get_app_name.3 b/allegro/docs/man/al_get_app_name.3 new file mode 100644 index 00000000..5d4246a4 --- /dev/null +++ b/allegro/docs/man/al_get_app_name.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_app_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_app_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_app_name(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the global application name string. +.SH SEE ALSO +.PP +al_set_app_name(3) diff --git a/allegro/docs/man/al_get_audio_depth_size.3 b/allegro/docs/man/al_get_audio_depth_size.3 new file mode 100644 index 00000000..f22a9b64 --- /dev/null +++ b/allegro/docs/man/al_get_audio_depth_size.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_depth_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_depth_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH depth) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the size of a sample, in bytes, for the given format. +The format is one of the values listed under ALLEGRO_AUDIO_DEPTH(3). diff --git a/allegro/docs/man/al_get_audio_recorder_event.3 b/allegro/docs/man/al_get_audio_recorder_event.3 new file mode 100644 index 00000000..9b68c204 --- /dev/null +++ b/allegro/docs/man/al_get_audio_recorder_event.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_recorder_event" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_recorder_event - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_RECORDER_EVENT *al_get_audio_recorder_event(ALLEGRO_EVENT *event) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the event as an ALLEGRO_AUDIO_RECORDER_EVENT(3). +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/al_get_audio_recorder_event_source.3 b/allegro/docs/man/al_get_audio_recorder_event_source.3 new file mode 100644 index 00000000..724fc659 --- /dev/null +++ b/allegro/docs/man/al_get_audio_recorder_event_source.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_recorder_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_recorder_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_audio_recorder_event_source(ALLEGRO_AUDIO_RECORDER *r) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the event source for the recorder that generates the various +recording events. +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/al_get_audio_stream_attached.3 b/allegro/docs/man/al_get_audio_stream_attached.3 new file mode 100644 index 00000000..2a5a8881 --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_attached.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_attached" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_attached - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_audio_stream_attached(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return whether the stream is attached to something. +.SH SEE ALSO +.PP +al_attach_audio_stream_to_mixer(3), al_attach_audio_stream_to_voice(3), +al_detach_audio_stream(3). diff --git a/allegro/docs/man/al_get_audio_stream_channels.3 b/allegro/docs/man/al_get_audio_stream_channels.3 new file mode 100644 index 00000000..9441cedb --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_channels.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_channels" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_channels - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CHANNEL_CONF al_get_audio_stream_channels( + const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the stream channel configuration. +.SH SEE ALSO +.PP +ALLEGRO_CHANNEL_CONF(3). diff --git a/allegro/docs/man/al_get_audio_stream_depth.3 b/allegro/docs/man/al_get_audio_stream_depth.3 new file mode 100644 index 00000000..6a70a85e --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_depth.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_depth" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_depth - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_DEPTH al_get_audio_stream_depth( + const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the stream audio depth. +.SH SEE ALSO +.PP +ALLEGRO_AUDIO_DEPTH(3). diff --git a/allegro/docs/man/al_get_audio_stream_event_source.3 b/allegro/docs/man/al_get_audio_stream_event_source.3 new file mode 100644 index 00000000..0be1543a --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_event_source.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_audio_stream_event_source( + ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieve the associated event source. +.PP +See al_get_audio_stream_fragment(3) for a description of the +ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT(3) event that audio streams emit. diff --git a/allegro/docs/man/al_get_audio_stream_fragment.3 b/allegro/docs/man/al_get_audio_stream_fragment.3 new file mode 100644 index 00000000..3adee484 --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_fragment.3 @@ -0,0 +1,44 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_fragment" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_fragment - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void *al_get_audio_stream_fragment(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +When using Allegro\[cq]s audio streaming, you will use this function to +continuously provide new sample data to a stream. +.PP +If the stream is ready for new data, the function will return the +address of an internal buffer to be filled with audio data. +The length and format of the buffer are specified with +al_create_audio_stream(3) or can be queried with the various functions +described here. +Once the buffer is filled, you must signal this to Allegro by passing +the buffer to al_set_audio_stream_fragment(3). +.PP +If the stream is not ready for new data, the function will return NULL. +.RS +.PP +\f[I]Note:\f[R] If you listen to events from the stream, an +ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT(3) event will be generated whenever +a new fragment is ready. +However, getting an event is \f[I]not\f[R] a guarantee that +al_get_audio_stream_fragment(3) will not return NULL, so you still must +check for it. +.RE +.SH SEE ALSO +.PP +al_set_audio_stream_fragment(3), al_get_audio_stream_event_source(3), +al_get_audio_stream_frequency(3), al_get_audio_stream_channels(3), +al_get_audio_stream_depth(3), al_get_audio_stream_length(3) diff --git a/allegro/docs/man/al_get_audio_stream_fragments.3 b/allegro/docs/man/al_get_audio_stream_fragments.3 new file mode 100644 index 00000000..59926486 --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_fragments.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_fragments" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_fragments - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_audio_stream_fragments(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the number of fragments this stream uses. +This is the same value as passed to al_create_audio_stream(3) when a new +stream is created. +.SH SEE ALSO +.PP +al_get_available_audio_stream_fragments(3) diff --git a/allegro/docs/man/al_get_audio_stream_frequency.3 b/allegro/docs/man/al_get_audio_stream_frequency.3 new file mode 100644 index 00000000..3653c020 --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_frequency.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_frequency" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_frequency - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_audio_stream_frequency(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the stream frequency (in Hz). diff --git a/allegro/docs/man/al_get_audio_stream_gain.3 b/allegro/docs/man/al_get_audio_stream_gain.3 new file mode 100644 index 00000000..14a3d123 --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_gain.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_gain" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_gain - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_audio_stream_gain(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the playback gain of the stream. +.SH SEE ALSO +.PP +al_set_audio_stream_gain(3). diff --git a/allegro/docs/man/al_get_audio_stream_length.3 b/allegro/docs/man/al_get_audio_stream_length.3 new file mode 100644 index 00000000..73dda1bd --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_length.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_length" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_length - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_audio_stream_length(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the stream length in samples. diff --git a/allegro/docs/man/al_get_audio_stream_length_secs.3 b/allegro/docs/man/al_get_audio_stream_length_secs.3 new file mode 100644 index 00000000..f38a0694 --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_length_secs.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_length_secs" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_length_secs - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_audio_stream_length_secs(ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the length of the stream in seconds, if known. +Otherwise returns zero. +.PP +Currently this can only be called on streams created with +al_load_audio_stream(3), al_load_audio_stream_f(3) and the +format-specific functions underlying those functions. +.SH SEE ALSO +.PP +al_get_audio_stream_position_secs(3) diff --git a/allegro/docs/man/al_get_audio_stream_pan.3 b/allegro/docs/man/al_get_audio_stream_pan.3 new file mode 100644 index 00000000..5bf7cd0b --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_pan.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_pan" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_pan - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_audio_stream_pan(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the pan value of the stream. +.SH SEE ALSO +.PP +al_set_audio_stream_pan(3). diff --git a/allegro/docs/man/al_get_audio_stream_played_samples.3 b/allegro/docs/man/al_get_audio_stream_played_samples.3 new file mode 100644 index 00000000..a4e3f8aa --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_played_samples.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_played_samples" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_played_samples - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint64_t al_get_audio_stream_played_samples(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the number of samples consumed by the parent since the audio stream +was started. +.SH SINCE +.PP +5.1.8 diff --git a/allegro/docs/man/al_get_audio_stream_playing.3 b/allegro/docs/man/al_get_audio_stream_playing.3 new file mode 100644 index 00000000..41dbb438 --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_playing.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_audio_stream_playing(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the stream is playing. +.SH SEE ALSO +.PP +al_set_audio_stream_playing(3). diff --git a/allegro/docs/man/al_get_audio_stream_playmode.3 b/allegro/docs/man/al_get_audio_stream_playmode.3 new file mode 100644 index 00000000..28d078fc --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_playmode.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_playmode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_playmode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_PLAYMODE al_get_audio_stream_playmode( + const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the playback mode of the stream. +.SH SEE ALSO +.PP +ALLEGRO_PLAYMODE(3), al_set_audio_stream_playmode(3). diff --git a/allegro/docs/man/al_get_audio_stream_position_secs.3 b/allegro/docs/man/al_get_audio_stream_position_secs.3 new file mode 100644 index 00000000..52c7503e --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_position_secs.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_position_secs" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_position_secs - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the position of the stream in seconds. +Currently this can only be called on streams created with +al_load_audio_stream(3). +.SH SEE ALSO +.PP +al_get_audio_stream_length_secs(3) diff --git a/allegro/docs/man/al_get_audio_stream_speed.3 b/allegro/docs/man/al_get_audio_stream_speed.3 new file mode 100644 index 00000000..f50b1bbb --- /dev/null +++ b/allegro/docs/man/al_get_audio_stream_speed.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_audio_stream_speed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_audio_stream_speed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_audio_stream_speed(const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the relative playback speed of the stream. +.SH SEE ALSO +.PP +al_set_audio_stream_speed(3). diff --git a/allegro/docs/man/al_get_available_audio_stream_fragments.3 b/allegro/docs/man/al_get_available_audio_stream_fragments.3 new file mode 100644 index 00000000..636de7dd --- /dev/null +++ b/allegro/docs/man/al_get_available_audio_stream_fragments.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_available_audio_stream_fragments" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_available_audio_stream_fragments - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_available_audio_stream_fragments( + const ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the number of available fragments in the stream, that is, +fragments which are not currently filled with data for playback. +.SH SEE ALSO +.PP +al_get_audio_stream_fragment(3), al_get_audio_stream_fragments(3) diff --git a/allegro/docs/man/al_get_backbuffer.3 b/allegro/docs/man/al_get_backbuffer.3 new file mode 100644 index 00000000..2e19e574 --- /dev/null +++ b/allegro/docs/man/al_get_backbuffer.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_backbuffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_backbuffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_get_backbuffer(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a special bitmap representing the back-buffer of the display. +.PP +Care should be taken when using the backbuffer bitmap (and its +sub-bitmaps) as the source bitmap (e.g as the bitmap argument to +al_draw_bitmap(3)). +Only untransformed operations are hardware accelerated. +These consist of al_draw_bitmap(3) and al_draw_bitmap_region(3) when the +current transformation is the identity. +If the transformation is not the identity, or some other drawing +operation is used, the call will be routed through the memory bitmap +routines, which are slow. +If you need those operations to be accelerated, then first copy a region +of the backbuffer into a temporary bitmap (via the al_draw_bitmap(3) and +al_draw_bitmap_region(3)), and then use that temporary bitmap as the +source bitmap. diff --git a/allegro/docs/man/al_get_bitmap_blend_color.3 b/allegro/docs/man/al_get_bitmap_blend_color.3 new file mode 100644 index 00000000..1efd64eb --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_blend_color.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_blend_color" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_blend_color - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_get_bitmap_blend_color(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the color currently used for constant color blending on the +target bitmap. +.SH SINCE +.PP +5.2.5 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE +.SH SEE ALSO +.PP +al_set_bitmap_blend_color(3) diff --git a/allegro/docs/man/al_get_bitmap_blender.3 b/allegro/docs/man/al_get_bitmap_blender.3 new file mode 100644 index 00000000..5f8dd199 --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_blender.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_bitmap_blender(int *op, int *src, int *dst) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the current blender being used by the target bitmap. +You can pass NULL for values you are not interested in. +.SH SINCE +.PP +5.2.5 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE +.SH SEE ALSO +.PP +al_set_bitmap_blender(3), al_get_separate_bitmap_blender(3) diff --git a/allegro/docs/man/al_get_bitmap_depth.3 b/allegro/docs/man/al_get_bitmap_depth.3 new file mode 100644 index 00000000..89ec71ae --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_depth.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_depth" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_depth - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_bitmap_depth(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the depthbuffer depth used by this bitmap if it is used with +al_set_target_bitmap(3). +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This is an experimental feature and currently +only works for the OpenGL backend. +.RE diff --git a/allegro/docs/man/al_get_bitmap_flags.3 b/allegro/docs/man/al_get_bitmap_flags.3 new file mode 100644 index 00000000..2a6a28eb --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_flags.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_bitmap_flags(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the flags used to create the bitmap. +.SH SEE ALSO +.PP +al_set_new_bitmap_flags(3) diff --git a/allegro/docs/man/al_get_bitmap_format.3 b/allegro/docs/man/al_get_bitmap_format.3 new file mode 100644 index 00000000..47fdc246 --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_format.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_format" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_format - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_bitmap_format(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the pixel format of a bitmap. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3), al_set_new_bitmap_flags(3) diff --git a/allegro/docs/man/al_get_bitmap_height.3 b/allegro/docs/man/al_get_bitmap_height.3 new file mode 100644 index 00000000..b9690d33 --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_height.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_height" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_height - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_bitmap_height(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the height of a bitmap in pixels. diff --git a/allegro/docs/man/al_get_bitmap_samples.3 b/allegro/docs/man/al_get_bitmap_samples.3 new file mode 100644 index 00000000..02eb5247 --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_samples.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_samples" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_samples - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_bitmap_samples(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the multi-sampling samples used by this bitmap if it is used with +al_set_target_bitmap(3). +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This is an experimental feature and currently +only works for the OpenGL backend. +.RE diff --git a/allegro/docs/man/al_get_bitmap_width.3 b/allegro/docs/man/al_get_bitmap_width.3 new file mode 100644 index 00000000..b4b22f19 --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_width.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_bitmap_width(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the width of a bitmap in pixels. diff --git a/allegro/docs/man/al_get_bitmap_x.3 b/allegro/docs/man/al_get_bitmap_x.3 new file mode 100644 index 00000000..dbf33eb7 --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_x.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_x" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_x - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_bitmap_x(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +For a sub-bitmap, return it\[cq]s x position within the parent. +.SH SEE ALSO +.PP +al_create_sub_bitmap(3), al_get_parent_bitmap(3), al_get_bitmap_y(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_get_bitmap_y.3 b/allegro/docs/man/al_get_bitmap_y.3 new file mode 100644 index 00000000..9e717ca4 --- /dev/null +++ b/allegro/docs/man/al_get_bitmap_y.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_bitmap_y" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_bitmap_y - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_bitmap_y(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +For a sub-bitmap, return it\[cq]s y position within the parent. +.SH SEE ALSO +.PP +al_create_sub_bitmap(3), al_get_parent_bitmap(3), al_get_bitmap_x(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_get_blend_color.3 b/allegro/docs/man/al_get_blend_color.3 new file mode 100644 index 00000000..22d9d64b --- /dev/null +++ b/allegro/docs/man/al_get_blend_color.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_blend_color" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_blend_color - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_get_blend_color(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the color currently used for constant color blending (white by +default). +.SH SEE ALSO +.PP +al_set_blend_color(3), al_set_blender(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_get_blender.3 b/allegro/docs/man/al_get_blender.3 new file mode 100644 index 00000000..ec612a7f --- /dev/null +++ b/allegro/docs/man/al_get_blender.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_blender(int *op, int *src, int *dst) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the active blender for the current thread. +You can pass NULL for values you are not interested in. +.SH SEE ALSO +.PP +al_set_blender(3), al_get_separate_blender(3) diff --git a/allegro/docs/man/al_get_channel_count.3 b/allegro/docs/man/al_get_channel_count.3 new file mode 100644 index 00000000..ddf7edcd --- /dev/null +++ b/allegro/docs/man/al_get_channel_count.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_channel_count" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_channel_count - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_get_channel_count(ALLEGRO_CHANNEL_CONF conf) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of channels for the given channel configuration, which +is one of the values listed under ALLEGRO_CHANNEL_CONF(3). diff --git a/allegro/docs/man/al_get_clipboard_text.3 b/allegro/docs/man/al_get_clipboard_text.3 new file mode 100644 index 00000000..f5fe5cc3 --- /dev/null +++ b/allegro/docs/man/al_get_clipboard_text.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_clipboard_text" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_clipboard_text - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char *al_get_clipboard_text(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function returns a pointer to a string, allocated with al_malloc(3) +with the text contents of the clipboard if available. +If no text is available on the clipboard then this function returns +NULL. +You must call al_free(3) on the returned pointer when you don\[cq]t need +it anymore. +.PP +Beware that text on the clipboard on Windows may be in Windows format, +that is, it may have carriage return newline combinations for the line +endings instead of regular newlines for the line endings on Linux or +OSX. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_set_clipboard_text(3), al_clipboard_has_text(3) diff --git a/allegro/docs/man/al_get_clipping_rectangle.3 b/allegro/docs/man/al_get_clipping_rectangle.3 new file mode 100644 index 00000000..3fb91730 --- /dev/null +++ b/allegro/docs/man/al_get_clipping_rectangle.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_clipping_rectangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_clipping_rectangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_clipping_rectangle(int *x, int *y, int *w, int *h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the clipping rectangle of the target bitmap. +.SH SEE ALSO +.PP +al_set_clipping_rectangle(3) diff --git a/allegro/docs/man/al_get_config_value.3 b/allegro/docs/man/al_get_config_value.3 new file mode 100644 index 00000000..f8f0c6bf --- /dev/null +++ b/allegro/docs/man/al_get_config_value.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_config_value" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_config_value - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_config_value(const ALLEGRO_CONFIG *config, + const char *section, const char *key) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets a pointer to an internal character buffer that will only remain +valid as long as the ALLEGRO_CONFIG structure is not destroyed. +Copy the value if you need a copy. +The section can be NULL or \[dq]\[dq] for the global section. +Returns NULL if the section or key do not exist. +.SH SEE ALSO +.PP +al_set_config_value(3) diff --git a/allegro/docs/man/al_get_cpu_count.3 b/allegro/docs/man/al_get_cpu_count.3 new file mode 100644 index 00000000..c94b8ff9 --- /dev/null +++ b/allegro/docs/man/al_get_cpu_count.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_cpu_count" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_cpu_count - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_cpu_count(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the number of CPU cores that the system Allegro is running on +has and which could be detected, or a negative number if detection +failed. +Even if a positive number is returned, it might be that it is not +correct. +For example, Allegro running on a virtual machine will return the amount +of CPU\[cq]s of the VM, and not that of the underlying system. +.PP +Furthermore even if the number is correct, this only gives you +information about the total CPU cores of the system Allegro runs on. +The amount of cores available to your program may be less due to +circumstances such as programs that are currently running. +.PP +Therefore, it\[cq]s best to use this for advisory purposes only. +It is certainly a bad idea to make your program exclusive to systems for +which this function returns a certain \[lq]desirable\[rq] number. +.PP +This function may be called prior to al_install_system(3) or al_init(3). +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_get_current_directory.3 b/allegro/docs/man/al_get_current_directory.3 new file mode 100644 index 00000000..98facce7 --- /dev/null +++ b/allegro/docs/man/al_get_current_directory.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_current_directory" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_current_directory - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char *al_get_current_directory(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the path to the current working directory, or NULL on failure. +The returned path is dynamically allocated and must be destroyed with +al_free(3). +.PP +Allegro\[cq]s errno is filled in to indicate the error if there is a +failure. +This function may not be implemented on some (virtual) filesystems. +.SH SEE ALSO +.PP +al_get_errno(3), al_free(3) diff --git a/allegro/docs/man/al_get_current_display.3 b/allegro/docs/man/al_get_current_display.3 new file mode 100644 index 00000000..9b3fb138 --- /dev/null +++ b/allegro/docs/man/al_get_current_display.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_current_display" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_current_display - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_DISPLAY *al_get_current_display(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the display that is \[lq]current\[rq] for the calling thread, or +NULL if there is none. +.SH SEE ALSO +.PP +al_set_target_bitmap(3) diff --git a/allegro/docs/man/al_get_current_inverse_transform.3 b/allegro/docs/man/al_get_current_inverse_transform.3 new file mode 100644 index 00000000..166bef90 --- /dev/null +++ b/allegro/docs/man/al_get_current_inverse_transform.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_current_inverse_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_current_inverse_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_TRANSFORM *al_get_current_inverse_transform(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the inverse of the current transformation of the target bitmap. +If there is no target bitmap, this function returns NULL. +.PP +This is similar to calling +\f[C]al_invert_transform(al_get_current_transform())\f[R] but the result +of this function is cached. +.RS +.PP +\f[I]Note\f[R]: Allegro\[cq]s transformation inversion functions work +correctly only with 2D transformations. +.RE +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_get_current_projection_transform.3 b/allegro/docs/man/al_get_current_projection_transform.3 new file mode 100644 index 00000000..9e2c8018 --- /dev/null +++ b/allegro/docs/man/al_get_current_projection_transform.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_current_projection_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_current_projection_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_TRANSFORM *al_get_current_projection_transform(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +If there is no target bitmap, this function returns NULL. +.PP +\f[I]Returns:\f[R] A pointer to the current transformation. +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_use_projection_transform(3) diff --git a/allegro/docs/man/al_get_current_transform.3 b/allegro/docs/man/al_get_current_transform.3 new file mode 100644 index 00000000..5683141d --- /dev/null +++ b/allegro/docs/man/al_get_current_transform.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_current_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_current_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_TRANSFORM *al_get_current_transform(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the transformation of the current target bitmap, as set by +al_use_transform(3). +If there is no target bitmap, this function returns NULL. +.PP +\f[I]Returns:\f[R] A pointer to the current transformation. +.SH SEE ALSO +.PP +al_get_current_projection_transform(3) diff --git a/allegro/docs/man/al_get_d3d_device.3 b/allegro/docs/man/al_get_d3d_device.3 new file mode 100644 index 00000000..cfa9fd9c --- /dev/null +++ b/allegro/docs/man/al_get_d3d_device.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_d3d_device" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_d3d_device - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +LPDIRECT3DDEVICE9 al_get_d3d_device(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the Direct3D device of the display. +The return value is undefined if the display was not created with the +Direct3D flag. +.PP +\f[I]Returns:\f[R] A pointer to the Direct3D device. diff --git a/allegro/docs/man/al_get_d3d_system_texture.3 b/allegro/docs/man/al_get_d3d_system_texture.3 new file mode 100644 index 00000000..918c4561 --- /dev/null +++ b/allegro/docs/man/al_get_d3d_system_texture.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_d3d_system_texture" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_d3d_system_texture - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +LPDIRECT3DTEXTURE9 al_get_d3d_system_texture(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the system texture (stored with the D3DPOOL_SYSTEMMEM flags). +This texture is used for the render-to-texture feature set. +.PP +\f[I]Returns:\f[R] A pointer to the Direct3D system texture. diff --git a/allegro/docs/man/al_get_d3d_texture_position.3 b/allegro/docs/man/al_get_d3d_texture_position.3 new file mode 100644 index 00000000..445df57d --- /dev/null +++ b/allegro/docs/man/al_get_d3d_texture_position.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_d3d_texture_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_d3d_texture_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_d3d_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the u/v coordinates for the top/left corner of the bitmap within +the used texture, in pixels. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +bitmap - ALLEGRO_BITMAP to examine +.IP \[bu] 2 +u - Will hold the returned u coordinate +.IP \[bu] 2 +v - Will hold the returned v coordinate +.SH SEE ALSO +.PP +al_get_d3d_texture_size(3) diff --git a/allegro/docs/man/al_get_d3d_texture_size.3 b/allegro/docs/man/al_get_d3d_texture_size.3 new file mode 100644 index 00000000..054fb913 --- /dev/null +++ b/allegro/docs/man/al_get_d3d_texture_size.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_d3d_texture_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_d3d_texture_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_d3d_texture_size(ALLEGRO_BITMAP *bitmap, int *width, int *height) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves the size of the Direct3D texture used for the bitmap. +.PP +Returns true on success, false on failure. +Zero width and height are returned if the bitmap is not a Direct3D +bitmap. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_get_d3d_texture_position(3) diff --git a/allegro/docs/man/al_get_d3d_video_texture.3 b/allegro/docs/man/al_get_d3d_video_texture.3 new file mode 100644 index 00000000..e05629d5 --- /dev/null +++ b/allegro/docs/man/al_get_d3d_video_texture.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_d3d_video_texture" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_d3d_video_texture - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +LPDIRECT3DTEXTURE9 al_get_d3d_video_texture(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the video texture (stored with the D3DPOOL_DEFAULT or +D3DPOOL_MANAGED flags depending on whether render-to-texture is enabled +or disabled respectively). +.PP +\f[I]Returns:\f[R] A pointer to the Direct3D video texture. diff --git a/allegro/docs/man/al_get_default_menu_event_source.3 b/allegro/docs/man/al_get_default_menu_event_source.3 new file mode 100644 index 00000000..6b3bb5f0 --- /dev/null +++ b/allegro/docs/man/al_get_default_menu_event_source.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_default_menu_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_default_menu_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_default_menu_event_source(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the default event source used for menu clicks. +If a menu was not given its own event source via +al_enable_menu_event_source(3), then it will use this default source. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_register_event_source(3), al_enable_menu_event_source(3), +al_disable_menu_event_source(3) diff --git a/allegro/docs/man/al_get_default_mixer.3 b/allegro/docs/man/al_get_default_mixer.3 new file mode 100644 index 00000000..c16d80dc --- /dev/null +++ b/allegro/docs/man/al_get_default_mixer.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_default_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_default_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MIXER *al_get_default_mixer(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the default mixer, or NULL if one has not been set. +Although different configurations of mixers and voices can be used, in +most cases a single mixer attached to a voice is what you want. +The default mixer is used by al_play_sample(3). +.SH SEE ALSO +.PP +al_reserve_samples(3), al_play_sample(3), al_set_default_mixer(3), +al_restore_default_mixer(3) diff --git a/allegro/docs/man/al_get_default_shader_source.3 b/allegro/docs/man/al_get_default_shader_source.3 new file mode 100644 index 00000000..ed0a3899 --- /dev/null +++ b/allegro/docs/man/al_get_default_shader_source.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_default_shader_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_default_shader_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char const *al_get_default_shader_source(ALLEGRO_SHADER_PLATFORM platform, + ALLEGRO_SHADER_TYPE type) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns a string containing the source code to Allegro\[cq]s default +vertex or pixel shader appropriate for the passed platform. +The ALLEGRO_SHADER_AUTO value means GLSL is used if OpenGL is being used +otherwise HLSL. +ALLEGRO_SHADER_AUTO requires that there is a current display set on the +calling thread. +This function can return NULL if Allegro was built without support for +shaders of the selected platform. +.SH SINCE +.PP +5.1.6 +.SH SEE ALSO +.PP +al_attach_shader_source(3) diff --git a/allegro/docs/man/al_get_default_voice.3 b/allegro/docs/man/al_get_default_voice.3 new file mode 100644 index 00000000..f770b39f --- /dev/null +++ b/allegro/docs/man/al_get_default_voice.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_default_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_default_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_VOICE *al_get_default_voice(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the default voice or NULL if there is none. +.SH SINCE +.PP +5.1.13 +.SH SEE ALSO +.PP +al_get_default_mixer(3) diff --git a/allegro/docs/man/al_get_display_event_source.3 b/allegro/docs/man/al_get_display_event_source.3 new file mode 100644 index 00000000..417a975c --- /dev/null +++ b/allegro/docs/man/al_get_display_event_source.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_display_event_source(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieve the associated event source. +See the [documentation on events]ALLEGRO_EVENT_DISPLAY_EXPOSE(3) for a +list of the events displays will generate. diff --git a/allegro/docs/man/al_get_display_flags.3 b/allegro/docs/man/al_get_display_flags.3 new file mode 100644 index 00000000..0f85d302 --- /dev/null +++ b/allegro/docs/man/al_get_display_flags.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_display_flags(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the flags of the display. +.PP +In addition to the flags set for the display at creation time with +al_set_new_display_flags(3) it can also have the ALLEGRO_MINIMIZED flag +set, indicating that the window is currently minimized. +This flag is very platform-dependent as even a minimized application may +still render a preview version so normally you should not care whether +it is minimized or not. +.SH SEE ALSO +.PP +al_set_new_display_flags(3), al_set_display_flag(3) diff --git a/allegro/docs/man/al_get_display_format.3 b/allegro/docs/man/al_get_display_format.3 new file mode 100644 index 00000000..c0b8d0e5 --- /dev/null +++ b/allegro/docs/man/al_get_display_format.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_format" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_format - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_display_format(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the pixel format of the display. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3) diff --git a/allegro/docs/man/al_get_display_height.3 b/allegro/docs/man/al_get_display_height.3 new file mode 100644 index 00000000..5ad91d55 --- /dev/null +++ b/allegro/docs/man/al_get_display_height.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_height" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_height - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_display_height(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the height of the display. +This is like SCREEN_H in Allegro 4.x. +.SH SEE ALSO +.PP +al_get_display_width(3) diff --git a/allegro/docs/man/al_get_display_menu.3 b/allegro/docs/man/al_get_display_menu.3 new file mode 100644 index 00000000..bc9577a7 --- /dev/null +++ b/allegro/docs/man/al_get_display_menu.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MENU *al_get_display_menu(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the menu associated with the \f[C]display\f[R], or +\f[C]NULL\f[R] if it does not have a menu. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_set_display_menu(3) diff --git a/allegro/docs/man/al_get_display_mode.3 b/allegro/docs/man/al_get_display_mode.3 new file mode 100644 index 00000000..036aab8a --- /dev/null +++ b/allegro/docs/man/al_get_display_mode.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_mode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_mode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_DISPLAY_MODE *al_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves a fullscreen mode. +Display parameters should not be changed between a call of +al_get_num_display_modes(3) and al_get_display_mode(3). +index must be between 0 and the number returned from +al_get_num_display_modes-1. +mode must be an allocated ALLEGRO_DISPLAY_MODE structure. +This function will return NULL on failure, and the mode parameter that +was passed in on success. +.SH SEE ALSO +.PP +ALLEGRO_DISPLAY_MODE(3), al_get_num_display_modes(3) diff --git a/allegro/docs/man/al_get_display_option.3 b/allegro/docs/man/al_get_display_option.3 new file mode 100644 index 00000000..e9f0e350 --- /dev/null +++ b/allegro/docs/man/al_get_display_option.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_option" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_option - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_display_option(ALLEGRO_DISPLAY *display, int option) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return an extra display setting of the display. +.SH SEE ALSO +.PP +al_set_new_display_option(3) diff --git a/allegro/docs/man/al_get_display_orientation.3 b/allegro/docs/man/al_get_display_orientation.3 new file mode 100644 index 00000000..20d12c6f --- /dev/null +++ b/allegro/docs/man/al_get_display_orientation.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_orientation" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_orientation - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_display_orientation(ALLEGRO_DISPLAY* display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the display orientation, which can be one of the following: +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_FACE_UP +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_get_display_refresh_rate.3 b/allegro/docs/man/al_get_display_refresh_rate.3 new file mode 100644 index 00000000..89358db7 --- /dev/null +++ b/allegro/docs/man/al_get_display_refresh_rate.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_refresh_rate" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_refresh_rate - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_display_refresh_rate(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the refresh rate of the display. +.SH SEE ALSO +.PP +al_set_new_display_refresh_rate(3) diff --git a/allegro/docs/man/al_get_display_width.3 b/allegro/docs/man/al_get_display_width.3 new file mode 100644 index 00000000..d409f74b --- /dev/null +++ b/allegro/docs/man/al_get_display_width.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_display_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_display_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_display_width(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the width of the display. +This is like SCREEN_W in Allegro 4.x. +.SH SEE ALSO +.PP +al_get_display_height(3) diff --git a/allegro/docs/man/al_get_errno.3 b/allegro/docs/man/al_get_errno.3 new file mode 100644 index 00000000..ec40899d --- /dev/null +++ b/allegro/docs/man/al_get_errno.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_errno" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_errno - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] + +int al_get_errno(void) +GETTER(allegro_errno, 0) +\f[R] +.fi +.SH DESCRIPTION +.PP +Some Allegro functions will set an error number as well as returning an +error code. +Call this function to retrieve the last error number set for the calling +thread. diff --git a/allegro/docs/man/al_get_event_source_data.3 b/allegro/docs/man/al_get_event_source_data.3 new file mode 100644 index 00000000..38d94bbb --- /dev/null +++ b/allegro/docs/man/al_get_event_source_data.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_event_source_data" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_event_source_data - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +intptr_t al_get_event_source_data(const ALLEGRO_EVENT_SOURCE *source) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the abstract user data associated with the event source. +If no data was previously set, returns NULL. +.SH SEE ALSO +.PP +al_set_event_source_data(3) diff --git a/allegro/docs/man/al_get_fallback_font.3 b/allegro/docs/man/al_get_fallback_font.3 new file mode 100644 index 00000000..4f76a30d --- /dev/null +++ b/allegro/docs/man/al_get_fallback_font.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_fallback_font" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_fallback_font - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_get_fallback_font(ALLEGRO_FONT *font) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves the fallback font for this font or NULL. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_set_fallback_font(3) diff --git a/allegro/docs/man/al_get_file_userdata.3 b/allegro/docs/man/al_get_file_userdata.3 new file mode 100644 index 00000000..b70a9693 --- /dev/null +++ b/allegro/docs/man/al_get_file_userdata.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_file_userdata" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_file_userdata - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void *al_get_file_userdata(ALLEGRO_FILE *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns a pointer to the custom userdata that is attached to the file +handle. +This is intended to be used by functions that extend +ALLEGRO_FILE_INTERFACE(3). diff --git a/allegro/docs/man/al_get_first_config_entry.3 b/allegro/docs/man/al_get_first_config_entry.3 new file mode 100644 index 00000000..358eebed --- /dev/null +++ b/allegro/docs/man/al_get_first_config_entry.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_first_config_entry" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_first_config_entry - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char const *al_get_first_config_entry(ALLEGRO_CONFIG const *config, + char const *section, ALLEGRO_CONFIG_ENTRY **iterator) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the name of the first key in the given section in the given +config or NULL if the section is empty. +The \f[C]iterator\f[R] works like the one for +al_get_first_config_section(3). +.PP +The returned string and the iterator are only valid as long as no change +is made to the passed ALLEGRO_CONFIG(3). +.SH SEE ALSO +.PP +al_get_next_config_entry(3) diff --git a/allegro/docs/man/al_get_first_config_section.3 b/allegro/docs/man/al_get_first_config_section.3 new file mode 100644 index 00000000..8296fba3 --- /dev/null +++ b/allegro/docs/man/al_get_first_config_section.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_first_config_section" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_first_config_section - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char const *al_get_first_config_section(ALLEGRO_CONFIG const *config, + ALLEGRO_CONFIG_SECTION **iterator) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the name of the first section in the given config file. +Usually this will return an empty string for the global section, even it +contains no values. +The \f[C]iterator\f[R] parameter will receive an opaque iterator which +is used by al_get_next_config_section(3) to iterate over the remaining +sections. +.PP +The returned string and the iterator are only valid as long as no change +is made to the passed ALLEGRO_CONFIG. +.SH SEE ALSO +.PP +al_get_next_config_section(3) diff --git a/allegro/docs/man/al_get_font_ascent.3 b/allegro/docs/man/al_get_font_ascent.3 new file mode 100644 index 00000000..2af053f5 --- /dev/null +++ b/allegro/docs/man/al_get_font_ascent.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_font_ascent" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_font_ascent - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_font_ascent(const ALLEGRO_FONT *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the ascent of the specified font. +.SH SEE ALSO +.PP +al_get_font_descent(3), al_get_font_line_height(3) diff --git a/allegro/docs/man/al_get_font_descent.3 b/allegro/docs/man/al_get_font_descent.3 new file mode 100644 index 00000000..72be7e23 --- /dev/null +++ b/allegro/docs/man/al_get_font_descent.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_font_descent" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_font_descent - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_font_descent(const ALLEGRO_FONT *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the descent of the specified font. +.SH SEE ALSO +.PP +al_get_font_ascent(3), al_get_font_line_height(3) diff --git a/allegro/docs/man/al_get_font_line_height.3 b/allegro/docs/man/al_get_font_line_height.3 new file mode 100644 index 00000000..e49ddbb6 --- /dev/null +++ b/allegro/docs/man/al_get_font_line_height.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_font_line_height" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_font_line_height - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_font_line_height(const ALLEGRO_FONT *f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the usual height of a line of text in the specified font. +For bitmap fonts this is simply the height of all glyph bitmaps. +For truetype fonts it is whatever the font file specifies. +In particular, some special glyphs may be higher than the height +returned here. +.PP +If the X is the position you specify to draw text, the meaning of ascent +and descent and the line height is like in the figure below. +.IP +.nf +\f[C] +X------------------------ + /\[rs] | | + / \[rs] | | + /____\[rs] ascent | + / \[rs] | | +/ \[rs] | height +---------------- | + | | + descent | + | | +------------------------- +\f[R] +.fi +.SH SEE ALSO +.PP +al_get_text_width(3), al_get_text_dimensions(3) diff --git a/allegro/docs/man/al_get_font_ranges.3 b/allegro/docs/man/al_get_font_ranges.3 new file mode 100644 index 00000000..8a179e51 --- /dev/null +++ b/allegro/docs/man/al_get_font_ranges.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_font_ranges" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_font_ranges - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_font_ranges(ALLEGRO_FONT *f, int ranges_count, int *ranges) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets information about all glyphs contained in a font, as a list of +ranges. +Ranges have the same format as with al_grab_font_from_bitmap(3). +.PP +\f[C]ranges_count\f[R] is the maximum number of ranges that will be +returned. +.PP +\f[C]ranges\f[R] should be an array with room for \f[C]ranges_count\f[R] +* 2 elements. +The even integers are the first unicode point in a range, the odd +integers the last unicode point in a range. +.PP +Returns the number of ranges contained in the font (even if it is bigger +than \f[C]ranges_count\f[R]). +.SH SINCE +.PP +5.1.4 +.SH SEE ALSO +.PP +al_grab_font_from_bitmap(3) diff --git a/allegro/docs/man/al_get_fs_entry_atime.3 b/allegro/docs/man/al_get_fs_entry_atime.3 new file mode 100644 index 00000000..a93cf65b --- /dev/null +++ b/allegro/docs/man/al_get_fs_entry_atime.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_fs_entry_atime" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_fs_entry_atime - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +time_t al_get_fs_entry_atime(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the time in seconds since the epoch since the entry was last +accessed. +.PP +Warning: some filesystems either don\[cq]t support this flag, or people +turn it off to increase performance. +It may not be valid in all circumstances. +.SH SEE ALSO +.PP +al_get_fs_entry_ctime(3), al_get_fs_entry_mtime(3), +al_update_fs_entry(3) diff --git a/allegro/docs/man/al_get_fs_entry_ctime.3 b/allegro/docs/man/al_get_fs_entry_ctime.3 new file mode 100644 index 00000000..1b9f3537 --- /dev/null +++ b/allegro/docs/man/al_get_fs_entry_ctime.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_fs_entry_ctime" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_fs_entry_ctime - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +time_t al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the time in seconds since the epoch this entry was created on +the filesystem. +.SH SEE ALSO +.PP +al_get_fs_entry_atime(3), al_get_fs_entry_mtime(3), +al_update_fs_entry(3) diff --git a/allegro/docs/man/al_get_fs_entry_mode.3 b/allegro/docs/man/al_get_fs_entry_mode.3 new file mode 100644 index 00000000..ba8d010e --- /dev/null +++ b/allegro/docs/man/al_get_fs_entry_mode.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_fs_entry_mode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_fs_entry_mode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_fs_entry_mode(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the entry\[cq]s mode flags, i.e.\ permissions and whether the +entry refers to a file or directory. +.SH SEE ALSO +.PP +al_get_errno(3), ALLEGRO_FILE_MODE(3) diff --git a/allegro/docs/man/al_get_fs_entry_mtime.3 b/allegro/docs/man/al_get_fs_entry_mtime.3 new file mode 100644 index 00000000..e0500c04 --- /dev/null +++ b/allegro/docs/man/al_get_fs_entry_mtime.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_fs_entry_mtime" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_fs_entry_mtime - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +time_t al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the time in seconds since the epoch since the entry was last +modified. +.SH SEE ALSO +.PP +al_get_fs_entry_atime(3), al_get_fs_entry_ctime(3), +al_update_fs_entry(3) diff --git a/allegro/docs/man/al_get_fs_entry_name.3 b/allegro/docs/man/al_get_fs_entry_name.3 new file mode 100644 index 00000000..3e13f75b --- /dev/null +++ b/allegro/docs/man/al_get_fs_entry_name.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_fs_entry_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_fs_entry_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_fs_entry_name(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the entry\[cq]s filename path. +Note that the filesystem encoding may not be known and the conversion to +UTF-8 could in very rare cases cause this to return an invalid path. +Therefore it\[cq]s always safest to access the file over its +ALLEGRO_FS_ENTRY(3) and not the path. +.PP +On success returns a read only string which you must not modify or +destroy. +Returns NULL on failure. +.RS +.PP +Note: prior to 5.1.5 it was written: \[lq]\&... the path will not be an +absolute path if the entry wasn\[cq]t created from an absolute +path\[rq]. +This is no longer true. +.RE diff --git a/allegro/docs/man/al_get_fs_entry_size.3 b/allegro/docs/man/al_get_fs_entry_size.3 new file mode 100644 index 00000000..002c4244 --- /dev/null +++ b/allegro/docs/man/al_get_fs_entry_size.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_fs_entry_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_fs_entry_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +off_t al_get_fs_entry_size(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the size, in bytes, of the given entry. +May not return anything sensible for a directory entry. +.SH SEE ALSO +.PP +al_update_fs_entry(3) diff --git a/allegro/docs/man/al_get_fs_interface.3 b/allegro/docs/man/al_get_fs_interface.3 new file mode 100644 index 00000000..814c7f0e --- /dev/null +++ b/allegro/docs/man/al_get_fs_interface.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_fs_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_fs_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_FS_INTERFACE *al_get_fs_interface(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a pointer to the ALLEGRO_FS_INTERFACE(3) table in effect for the +calling thread. +.SH SEE ALSO +.PP +al_store_state(3), al_restore_state(3). diff --git a/allegro/docs/man/al_get_glyph.3 b/allegro/docs/man/al_get_glyph.3 new file mode 100644 index 00000000..47ce78b1 --- /dev/null +++ b/allegro/docs/man/al_get_glyph.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_glyph" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_glyph - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_glyph(const ALLEGRO_FONT *f, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *glyph) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets all the information about a glyph, including the bitmap, needed to +draw it yourself. +prev_codepoint is the codepoint in the string before the one you want to +draw and is used for kerning. +codepoint is the character you want to get info about. +You should clear the `glyph' structure to 0 with memset before passing +it to this function for future compatibility. +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This API is new and subject to refinement. +.RE +.SH SEE ALSO +.PP +ALLEGRO_GLYPH(3) diff --git a/allegro/docs/man/al_get_glyph_advance.3 b/allegro/docs/man/al_get_glyph_advance.3 new file mode 100644 index 00000000..c4ea5f03 --- /dev/null +++ b/allegro/docs/man/al_get_glyph_advance.3 @@ -0,0 +1,97 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_glyph_advance" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_glyph_advance - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_glyph_advance(const ALLEGRO_FONT *f, int codepoint1, int codepoint2) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function returns by how much the x position should be advanced for +left to right text drawing when the glyph that corresponds to codepoint1 +has been drawn, and the glyph that corresponds to codepoint2 will be the +next to be drawn. +This takes into consideration the horizontal advance width of the glyph +that corresponds with codepoint1 as well as the kerning between the +glyphs of codepoint1 and codepoint2. +.PP +Kerning is the process of adjusting the spacing between glyphs in a +font, to obtain a more visually pleasing result. +Kerning adjusts the space between two individual glyphs with an offset +determined by the author of the font. +.PP +If you pass ALLEGRO_NO_KERNING as codepoint1 then al_get_glyph_advance +will return 0. +this can be useful when drawing the first character of a string in a +loop. +.PP +Pass ALLEGRO_NO_KERNING as codepoint2 to get the horizontal advance +width of the glyph that corresponds to codepoint1 without taking any +kerning into consideration. +This can be used, for example, when drawing the last character of a +string in a loop. +.PP +This function will return zero if the glyph of codepoint1 is not present +in the \f[C]font\f[R]. +If the glyph of codepoint2 is not present in the font, the horizontal +advance width of the glyph that corresponds to codepoint1 without taking +any kerning into consideration is returned. +.PP +When drawing a string one glyph at the time from the left to the right +with kerning, the x position of the glyph should be incremented by the +result of al_get_glyph_advance(3) applied to the previous glyph drawn +and the next glyph to draw. +.PP +Note that the return value of this function is a recommended advance for +optimal readability for left to right text determined by the author of +the font. +However, if you like, you may want to draw the glyphs of the font +narrower or wider to each other than what al_get_glyph_advance(3) +returns for style or effect. +.PP +In the figure below is an example of what the result of +al_get_glyph_advance may be like for two glypphs \f[C]A\f[R] and +\f[C]l\f[R] of the same font that has kerning for the \[lq]Al\[rq] pair, +without and with the ALLEGRO_NO_KERNING flag. +.IP +.nf +\f[C] +al_get_glyph_advance(font, \[aq]A\[aq], \[aq]l\[aq]) + ___|___ + / \[rs] + ------------- + /\[rs] -| + / \[rs] | + /____\[rs] | + / \[rs] | + / \[rs] \[rs]_ + ------------- + + +al_get_glyph_advance(font, \[aq]A\[aq], ALLEGRO_NO_KERNING) + ____|____ + / \[rs] + --------------- + /\[rs] -| + / \[rs] | + /____\[rs] | + / \[rs] | + / \[rs] \[rs]_ + --------------- +\f[R] +.fi +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_draw_glyph(3), al_get_glyph_width(3), al_get_glyph_dimensions(3). diff --git a/allegro/docs/man/al_get_glyph_dimensions.3 b/allegro/docs/man/al_get_glyph_dimensions.3 new file mode 100644 index 00000000..25d40f5d --- /dev/null +++ b/allegro/docs/man/al_get_glyph_dimensions.3 @@ -0,0 +1,84 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_glyph_dimensions" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_glyph_dimensions - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_glyph_dimensions(const ALLEGRO_FONT *f, + int codepoint, int *bbx, int *bby, int *bbw, int *bbh) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sometimes, the al_get_glyph_width(3) or al_get_glyph_advance(3) +functions are not enough for exact glyph placement, so this function +returns some additional information, particularly if you want to draw +the font vertically. +.PP +The function itself returns true if the character was present in +\f[C]font\f[R] and false if the character was not present in +\f[C]font\f[R]. +.PP +Returned variables (all in pixel): +.IP \[bu] 2 +bbx, bby - Offset to upper left corner of bounding box. +.IP \[bu] 2 +bbw, bbh - Dimensions of bounding box. +.PP +These values are the same as al_get_text_dimensions(3) would return for +a string of a single character equal to the glyph passed to this +function. +Note that glyphs may go to the left and upwards of the X, in which case +x and y will have negative values. +.PP +If you want to draw a string verticallly, for Japanese or as a game +effect, then you should leave bby + bbh space between the glyphs in the +y direction for a regular placement. +.PP +If you want to draw a string horizontally in an extra compact way, +.PD 0 +.P +.PD +then you should leave bbx + bbw space between the glyphs in the x +direction for a compact placement. +.PP +In the figure below is an example of what bbx and bby may be like for a +\f[C]2\f[R] glyph, and a \f[C]g\f[R] glyph of the same font compared to +the result of al_get_glyph_width(). +.IP +.nf +\f[C] + al_get_glyph_width() al_get_glyph_width() + __|___ __|__ + / \[rs] / \[rs] + bbx bbw bbx bbw + <-->+<------>+ <-->+<----->+ X baseline + \[ha] | | \[ha] | | +bby | | | bby | | | + v | | | | | + +---+--------+ | | | + \[ha] | ***** | | | | + | |* ** | v | | +bbh | | ** | bbh +---+-------+ + | | ** | \[ha] | ***** | + v |********| | |* *| + +---+--------+ | | ***** | + | | *| + | | * *| + v | **** | + +---+-------+ +\f[R] +.fi +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_draw_glyph(3), al_get_glyph_width(3), al_get_glyph_advance(3). diff --git a/allegro/docs/man/al_get_glyph_width.3 b/allegro/docs/man/al_get_glyph_width.3 new file mode 100644 index 00000000..1a9666ec --- /dev/null +++ b/allegro/docs/man/al_get_glyph_width.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_glyph_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_glyph_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_glyph_width(const ALLEGRO_FONT *f, int codepoint) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function returns the width in pixels of the glyph that corresponds +with \f[C]codepoint\f[R] in the font \f[C]font\f[R]. +Returns zero if the font does not have such a glyph. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_draw_glyph(3), al_get_glyph_dimensions(3), al_get_glyph_advance(3). diff --git a/allegro/docs/man/al_get_haptic_autocenter.3 b/allegro/docs/man/al_get_haptic_autocenter.3 new file mode 100644 index 00000000..50a724cb --- /dev/null +++ b/allegro/docs/man/al_get_haptic_autocenter.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_autocenter" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_autocenter - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_haptic_autocenter(ALLEGRO_HAPTIC *hap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the current automatic centering intensity of the device. +Depending on the device automatic centering may ensure that the axes of +the device are centered again automatically after playing a haptic +effect. +The return value can be between 0.0 and 1.0. +The value 0.0 means automatic centering is disabled, and 1.0 means +automatic centering is enabled at full strength. +Any value in between those two extremes means partial automatic +centering is enabled. +Some platforms do not support partial automatic centering. +If that is the case, a value of less than 0.5 means it is turned off, +while a value equal to or higher to 0.5 means it is turned on. +Can only work if al_get_haptic_capabilities(3) returns a value that has +ALLEGRO_HAPTIC_AUTOCENTER(3)ALLEGRO_HAPTIC_CONSTANTS(3) set. +If not, this function returns 0.0. +.SH SINCE +.PP +5.1.9 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_haptic_capabilities.3 b/allegro/docs/man/al_get_haptic_capabilities.3 new file mode 100644 index 00000000..1993ab1b --- /dev/null +++ b/allegro/docs/man/al_get_haptic_capabilities.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_capabilities" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_capabilities - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_haptic_capabilities(ALLEGRO_HAPTIC *hap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns an integer with or\[cq]ed values from +ALLEGRO_HAPTIC_CONSTANTS(3), which, if set, indicate that the haptic +device supports the given feature. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_haptic_effect_duration.3 b/allegro/docs/man/al_get_haptic_effect_duration.3 new file mode 100644 index 00000000..24e731e7 --- /dev/null +++ b/allegro/docs/man/al_get_haptic_effect_duration.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_effect_duration" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_effect_duration - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_haptic_effect_duration(ALLEGRO_HAPTIC_EFFECT * effect) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the estimated duration in seconds of a single loop of the given +haptic effect. +The effect\[cq]s \f[C]effect.replay\f[R] must have been filled in +correctly before using this function. +.SH SINCE +.PP +5.1.9 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_haptic_from_display.3 b/allegro/docs/man/al_get_haptic_from_display.3 new file mode 100644 index 00000000..895276e3 --- /dev/null +++ b/allegro/docs/man/al_get_haptic_from_display.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_from_display" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_from_display - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_HAPTIC *al_get_haptic_from_display(ALLEGRO_DISPLAY *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +If the display has haptic capabilities, returns the associated haptic +device handle. +Otherwise returns NULL. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_haptic_from_joystick.3 b/allegro/docs/man/al_get_haptic_from_joystick.3 new file mode 100644 index 00000000..cf8ccd4d --- /dev/null +++ b/allegro/docs/man/al_get_haptic_from_joystick.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_from_joystick" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_from_joystick - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_HAPTIC *al_get_haptic_from_joystick(ALLEGRO_JOYSTICK *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +If the joystick has haptic capabilities, returns the associated haptic +device handle. +Otherwise returns NULL. +It\[cq]s necessary to call this again every time the joystick +configuration changes, such as through hot plugging. +In that case, the old haptic device must be released using +al_release_haptic(3). +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_haptic_from_keyboard.3 b/allegro/docs/man/al_get_haptic_from_keyboard.3 new file mode 100644 index 00000000..ebfb074a --- /dev/null +++ b/allegro/docs/man/al_get_haptic_from_keyboard.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_from_keyboard" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_from_keyboard - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_HAPTIC *al_get_haptic_from_keyboard(ALLEGRO_KEYBOARD *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +If the keyboard has haptic capabilities, returns the associated haptic +device handle. +Otherwise returns NULL. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_haptic_from_mouse.3 b/allegro/docs/man/al_get_haptic_from_mouse.3 new file mode 100644 index 00000000..f9858b01 --- /dev/null +++ b/allegro/docs/man/al_get_haptic_from_mouse.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_from_mouse" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_from_mouse - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_HAPTIC *al_get_haptic_from_mouse(ALLEGRO_MOUSE *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +If the mouse has haptic capabilities, returns the associated haptic +device handle. +Otherwise returns NULL. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_haptic_from_touch_input.3 b/allegro/docs/man/al_get_haptic_from_touch_input.3 new file mode 100644 index 00000000..7e553b4f --- /dev/null +++ b/allegro/docs/man/al_get_haptic_from_touch_input.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_from_touch_input" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_from_touch_input - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_HAPTIC *al_get_haptic_from_touch_input(ALLEGRO_TOUCH_INPUT *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +If the touch input device has haptic capabilities, returns the +associated haptic device handle. +Otherwise returns NULL. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_haptic_gain.3 b/allegro/docs/man/al_get_haptic_gain.3 new file mode 100644 index 00000000..e19e4019 --- /dev/null +++ b/allegro/docs/man/al_get_haptic_gain.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_haptic_gain" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_haptic_gain - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_haptic_gain(ALLEGRO_HAPTIC *hap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the current gain of the device. +Gain is much like volume for sound, it is as if every effect\[cq]s +intensity is multiplied by it. +Gain is a value between 0.0 and 1.0. +Only works correctly if al_get_haptic_capabilities(3) returns a value +that has ALLEGRO_HAPTIC_GAIN(3)ALLEGRO_HAPTIC_CONSTANTS(3) set. +If this is not set, this function will simply return 1.0 and all effects +will be played without any gain influence. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_index_buffer_size.3 b/allegro/docs/man/al_get_index_buffer_size.3 new file mode 100644 index 00000000..c6a67bad --- /dev/null +++ b/allegro/docs/man/al_get_index_buffer_size.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_index_buffer_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_index_buffer_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_index_buffer_size(ALLEGRO_INDEX_BUFFER* buffer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the size of the index buffer +.SH SINCE +.PP +5.1.8 +.SH SEE ALSO +.PP +ALLEGRO_INDEX_BUFFER(3) diff --git a/allegro/docs/man/al_get_joystick.3 b/allegro/docs/man/al_get_joystick.3 new file mode 100644 index 00000000..1f3a80ca --- /dev/null +++ b/allegro/docs/man/al_get_joystick.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_JOYSTICK * al_get_joystick(int num) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get a handle for a joystick on the system. +The number may be from 0 to al_get_num_joysticks(3)-1. +If successful a pointer to a joystick object is returned, which +represents a physical device. +Otherwise NULL is returned. +.PP +The handle and the index are only incidentally linked. +After al_reconfigure_joysticks(3) is called, al_get_joystick(3) may +return handles in a different order, and handles which represent +disconnected devices will not be returned. +.SH SEE ALSO +.PP +al_get_num_joysticks(3), al_reconfigure_joysticks(3), +al_get_joystick_active(3) diff --git a/allegro/docs/man/al_get_joystick_active.3 b/allegro/docs/man/al_get_joystick_active.3 new file mode 100644 index 00000000..299b426a --- /dev/null +++ b/allegro/docs/man/al_get_joystick_active.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_active" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_active - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_joystick_active(ALLEGRO_JOYSTICK *joy) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return if the joystick handle is \[lq]active\[rq], i.e.\ in the current +configuration, the handle represents some physical device plugged into +the system. +al_get_joystick(3) returns active handles. +After reconfiguration, active handles may become inactive, and vice +versa. +.SH SEE ALSO +.PP +al_reconfigure_joysticks(3) diff --git a/allegro/docs/man/al_get_joystick_axis_name.3 b/allegro/docs/man/al_get_joystick_axis_name.3 new file mode 100644 index 00000000..fa4e4f9d --- /dev/null +++ b/allegro/docs/man/al_get_joystick_axis_name.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_axis_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_axis_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_joystick_axis_name(ALLEGRO_JOYSTICK *joy, int stick, int axis) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the name of the given axis. +If the axis doesn\[cq]t exist, NULL is returned. +Indices begin from 0. +.SH SEE ALSO +.PP +al_get_joystick_stick_name(3), al_get_joystick_num_axes(3) diff --git a/allegro/docs/man/al_get_joystick_button_name.3 b/allegro/docs/man/al_get_joystick_button_name.3 new file mode 100644 index 00000000..59165ba6 --- /dev/null +++ b/allegro/docs/man/al_get_joystick_button_name.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_button_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_button_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_joystick_button_name(ALLEGRO_JOYSTICK *joy, int button) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the name of the given button. +If the button doesn\[cq]t exist, NULL is returned. +Indices begin from 0. +.SH SEE ALSO +.PP +al_get_joystick_stick_name(3), al_get_joystick_axis_name(3), +al_get_joystick_num_buttons(3) diff --git a/allegro/docs/man/al_get_joystick_event_source.3 b/allegro/docs/man/al_get_joystick_event_source.3 new file mode 100644 index 00000000..ac444b80 --- /dev/null +++ b/allegro/docs/man/al_get_joystick_event_source.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_joystick_event_source(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the global joystick event source. +All [joystick events]ALLEGRO_EVENT_JOYSTICK_AXIS(3) are generated by +this event source. diff --git a/allegro/docs/man/al_get_joystick_name.3 b/allegro/docs/man/al_get_joystick_name.3 new file mode 100644 index 00000000..6e945fb5 --- /dev/null +++ b/allegro/docs/man/al_get_joystick_name.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_joystick_name(ALLEGRO_JOYSTICK *joy) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the name of the given joystick. +.SH SEE ALSO +.PP +al_get_joystick_stick_name(3), al_get_joystick_axis_name(3), +al_get_joystick_button_name(3) diff --git a/allegro/docs/man/al_get_joystick_num_axes.3 b/allegro/docs/man/al_get_joystick_num_axes.3 new file mode 100644 index 00000000..9247c865 --- /dev/null +++ b/allegro/docs/man/al_get_joystick_num_axes.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_num_axes" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_num_axes - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_joystick_num_axes(ALLEGRO_JOYSTICK *joy, int stick) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of axes on the given \[lq]stick\[rq]. +If the stick doesn\[cq]t exist, 0 is returned. +.SH SEE ALSO +.PP +al_get_joystick_num_sticks(3) diff --git a/allegro/docs/man/al_get_joystick_num_buttons.3 b/allegro/docs/man/al_get_joystick_num_buttons.3 new file mode 100644 index 00000000..166b4b48 --- /dev/null +++ b/allegro/docs/man/al_get_joystick_num_buttons.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_num_buttons" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_num_buttons - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_joystick_num_buttons(ALLEGRO_JOYSTICK *joy) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of buttons on the joystick. +.SH SEE ALSO +.PP +al_get_joystick_num_sticks(3) diff --git a/allegro/docs/man/al_get_joystick_num_sticks.3 b/allegro/docs/man/al_get_joystick_num_sticks.3 new file mode 100644 index 00000000..d6d46dc3 --- /dev/null +++ b/allegro/docs/man/al_get_joystick_num_sticks.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_num_sticks" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_num_sticks - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_joystick_num_sticks(ALLEGRO_JOYSTICK *joy) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of \[lq]sticks\[rq] on the given joystick. +A stick has one or more axes. +.SH SEE ALSO +.PP +al_get_joystick_num_axes(3), al_get_joystick_num_buttons(3) diff --git a/allegro/docs/man/al_get_joystick_state.3 b/allegro/docs/man/al_get_joystick_state.3 new file mode 100644 index 00000000..3bbdbedb --- /dev/null +++ b/allegro/docs/man/al_get_joystick_state.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_state" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_state - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the current joystick state. +.SH SEE ALSO +.PP +ALLEGRO_JOYSTICK_STATE(3), al_get_joystick_num_buttons(3), +al_get_joystick_num_axes(3) diff --git a/allegro/docs/man/al_get_joystick_stick_flags.3 b/allegro/docs/man/al_get_joystick_stick_flags.3 new file mode 100644 index 00000000..df27dc66 --- /dev/null +++ b/allegro/docs/man/al_get_joystick_stick_flags.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_stick_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_stick_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_joystick_stick_flags(ALLEGRO_JOYSTICK *joy, int stick) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the flags of the given \[lq]stick\[rq]. +If the stick doesn\[cq]t exist, NULL is returned. +Indices begin from 0. +.SH SEE ALSO +.PP +ALLEGRO_JOYFLAGS(3) diff --git a/allegro/docs/man/al_get_joystick_stick_name.3 b/allegro/docs/man/al_get_joystick_stick_name.3 new file mode 100644 index 00000000..ba7d0598 --- /dev/null +++ b/allegro/docs/man/al_get_joystick_stick_name.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_joystick_stick_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_joystick_stick_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_joystick_stick_name(ALLEGRO_JOYSTICK *joy, int stick) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the name of the given \[lq]stick\[rq]. +If the stick doesn\[cq]t exist, NULL is returned. +.SH SEE ALSO +.PP +al_get_joystick_axis_name(3), al_get_joystick_num_sticks(3) diff --git a/allegro/docs/man/al_get_keyboard_event_source.3 b/allegro/docs/man/al_get_keyboard_event_source.3 new file mode 100644 index 00000000..f17ab3a8 --- /dev/null +++ b/allegro/docs/man/al_get_keyboard_event_source.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_keyboard_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_keyboard_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_keyboard_event_source(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieve the keyboard event source. +All [keyboard events]ALLEGRO_EVENT_KEY_DOWN(3) are generated by this +event source. +.PP +Returns NULL if the keyboard subsystem was not installed. diff --git a/allegro/docs/man/al_get_keyboard_state.3 b/allegro/docs/man/al_get_keyboard_state.3 new file mode 100644 index 00000000..07bec913 --- /dev/null +++ b/allegro/docs/man/al_get_keyboard_state.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_keyboard_state" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_keyboard_state - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) +\f[R] +.fi +.SH DESCRIPTION +.PP +Save the state of the keyboard specified at the time the function is +called into the structure pointed to by \f[I]ret_state\f[R]. +.SH SEE ALSO +.PP +al_key_down(3), al_clear_keyboard_state(3), ALLEGRO_KEYBOARD_STATE(3) diff --git a/allegro/docs/man/al_get_max_haptic_effects.3 b/allegro/docs/man/al_get_max_haptic_effects.3 new file mode 100644 index 00000000..89c57d40 --- /dev/null +++ b/allegro/docs/man/al_get_max_haptic_effects.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_max_haptic_effects" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_max_haptic_effects - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_max_haptic_effects(ALLEGRO_HAPTIC *hap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the maximum amount of haptic effects that can be uploaded to the +device. +This depends on the operating system, driver, platform and the device +itself. +This may return a value as low as 1. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_get_menu_item_caption.3 b/allegro/docs/man/al_get_menu_item_caption.3 new file mode 100644 index 00000000..0888ddcd --- /dev/null +++ b/allegro/docs/man/al_get_menu_item_caption.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_menu_item_caption" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_menu_item_caption - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_menu_item_caption(ALLEGRO_MENU *menu, int pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the caption associated with the menu item. +It is valid as long as the caption is not modified. +.PP +Returns \f[C]NULL\f[R] if the item was not found. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_set_menu_item_caption(3) diff --git a/allegro/docs/man/al_get_menu_item_flags.3 b/allegro/docs/man/al_get_menu_item_flags.3 new file mode 100644 index 00000000..f3e36d5a --- /dev/null +++ b/allegro/docs/man/al_get_menu_item_flags.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_menu_item_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_menu_item_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_menu_item_flags(ALLEGRO_MENU *menu, int pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the currently set flags. +See al_insert_menu_item(3) for a description of the available flags. +.PP +Returns -1 if the item was not found. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_set_menu_item_flags(3), al_toggle_menu_item_flags(3) diff --git a/allegro/docs/man/al_get_menu_item_icon.3 b/allegro/docs/man/al_get_menu_item_icon.3 new file mode 100644 index 00000000..4a79d399 --- /dev/null +++ b/allegro/docs/man/al_get_menu_item_icon.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_menu_item_icon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_menu_item_icon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_get_menu_item_icon(ALLEGRO_MENU *menu, int pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the icon associated with the menu. +It is safe to draw to the returned bitmap, but you must call +al_set_menu_item_icon(3) in order for the changes to be applied. +.PP +Returns \f[C]NULL\f[R] if the item was not found or if it has no icon. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_set_menu_item_icon(3) diff --git a/allegro/docs/man/al_get_mixer_attached.3 b/allegro/docs/man/al_get_mixer_attached.3 new file mode 100644 index 00000000..44e39c4c --- /dev/null +++ b/allegro/docs/man/al_get_mixer_attached.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mixer_attached" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mixer_attached - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_mixer_attached(const ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the mixer is attached to something. +.SH SEE ALSO +.PP +al_attach_sample_instance_to_mixer(3), +al_attach_audio_stream_to_mixer(3), al_attach_mixer_to_mixer(3), +al_detach_mixer(3) diff --git a/allegro/docs/man/al_get_mixer_channels.3 b/allegro/docs/man/al_get_mixer_channels.3 new file mode 100644 index 00000000..f48a8331 --- /dev/null +++ b/allegro/docs/man/al_get_mixer_channels.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mixer_channels" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mixer_channels - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CHANNEL_CONF al_get_mixer_channels(const ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the mixer channel configuration. +.SH SEE ALSO +.PP +ALLEGRO_CHANNEL_CONF(3). diff --git a/allegro/docs/man/al_get_mixer_depth.3 b/allegro/docs/man/al_get_mixer_depth.3 new file mode 100644 index 00000000..c3269849 --- /dev/null +++ b/allegro/docs/man/al_get_mixer_depth.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mixer_depth" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mixer_depth - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_DEPTH al_get_mixer_depth(const ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the mixer audio depth. +.SH SEE ALSO +.PP +ALLEGRO_AUDIO_DEPTH(3). diff --git a/allegro/docs/man/al_get_mixer_frequency.3 b/allegro/docs/man/al_get_mixer_frequency.3 new file mode 100644 index 00000000..17db2f4b --- /dev/null +++ b/allegro/docs/man/al_get_mixer_frequency.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mixer_frequency" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mixer_frequency - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_mixer_frequency(const ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the mixer frequency (in Hz). +.SH SEE ALSO +.PP +al_set_mixer_frequency(3) diff --git a/allegro/docs/man/al_get_mixer_gain.3 b/allegro/docs/man/al_get_mixer_gain.3 new file mode 100644 index 00000000..0700232a --- /dev/null +++ b/allegro/docs/man/al_get_mixer_gain.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mixer_gain" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mixer_gain - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_mixer_gain(const ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the mixer gain (amplification factor). +The default is 1.0. +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_set_mixer_gain(3). diff --git a/allegro/docs/man/al_get_mixer_playing.3 b/allegro/docs/man/al_get_mixer_playing.3 new file mode 100644 index 00000000..8fc7e1dd --- /dev/null +++ b/allegro/docs/man/al_get_mixer_playing.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mixer_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mixer_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_mixer_playing(const ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the mixer is playing. +.SH SEE ALSO +.PP +al_set_mixer_playing(3). diff --git a/allegro/docs/man/al_get_mixer_quality.3 b/allegro/docs/man/al_get_mixer_quality.3 new file mode 100644 index 00000000..ec2f8201 --- /dev/null +++ b/allegro/docs/man/al_get_mixer_quality.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mixer_quality" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mixer_quality - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MIXER_QUALITY al_get_mixer_quality(const ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the mixer quality. +.SH SEE ALSO +.PP +ALLEGRO_MIXER_QUALITY(3), al_set_mixer_quality(3) diff --git a/allegro/docs/man/al_get_monitor_dpi.3 b/allegro/docs/man/al_get_monitor_dpi.3 new file mode 100644 index 00000000..3923dd54 --- /dev/null +++ b/allegro/docs/man/al_get_monitor_dpi.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_monitor_dpi" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_monitor_dpi - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_monitor_dpi(int adapter) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the dots per inch of a monitor attached to the display adapter. +.SH SINCE +.PP +5.2.5 +.SH SEE ALSO +.PP +al_get_num_video_adapters(3) diff --git a/allegro/docs/man/al_get_monitor_info.3 b/allegro/docs/man/al_get_monitor_info.3 new file mode 100644 index 00000000..f893a907 --- /dev/null +++ b/allegro/docs/man/al_get_monitor_info.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_monitor_info" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_monitor_info - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get information about a monitor\[cq]s position on the desktop. +adapter is a number from 0 to al_get_num_video_adapters()-1. +.PP +On Windows, use al_set_new_display_flags(3) to switch between Direct3D +and OpenGL backends, which will often have different adapters available. +.PP +Returns \f[C]true\f[R] on success, \f[C]false\f[R] on failure. +.SH SEE ALSO +.PP +ALLEGRO_MONITOR_INFO(3), al_get_num_video_adapters(3) diff --git a/allegro/docs/man/al_get_monitor_refresh_rate.3 b/allegro/docs/man/al_get_monitor_refresh_rate.3 new file mode 100644 index 00000000..eee720de --- /dev/null +++ b/allegro/docs/man/al_get_monitor_refresh_rate.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_monitor_refresh_rate" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_monitor_refresh_rate - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_monitor_refresh_rate(int adapter) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the current refresh rate of a monitor attached to the display +adapter. +.SH SINCE +.PP +5.2.6 +.RS +.PP +\f[I][Unstable API]:\f[R] This is an experimental feature and currently +only works on Windows. +.RE +.SH SEE ALSO +.PP +al_get_monitor_info(3) diff --git a/allegro/docs/man/al_get_mouse_cursor_position.3 b/allegro/docs/man/al_get_mouse_cursor_position.3 new file mode 100644 index 00000000..606a959b --- /dev/null +++ b/allegro/docs/man/al_get_mouse_cursor_position.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mouse_cursor_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mouse_cursor_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_mouse_cursor_position(int *ret_x, int *ret_y) +\f[R] +.fi +.SH DESCRIPTION +.PP +On platforms where this information is available, this function returns +the global location of the mouse cursor, relative to the desktop. +You should not normally use this function, as the information is not +useful except for special scenarios as moving a window. +.PP +Returns true on success, false on failure. diff --git a/allegro/docs/man/al_get_mouse_emulation_mode.3 b/allegro/docs/man/al_get_mouse_emulation_mode.3 new file mode 100644 index 00000000..9d8be28c --- /dev/null +++ b/allegro/docs/man/al_get_mouse_emulation_mode.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mouse_emulation_mode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mouse_emulation_mode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_mouse_emulation_mode(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the kind of mouse emulation which the touch input subsystem is +set to perform. +.SH SINCE +.PP +5.1.0 +.RS +.PP +\f[I][Unstable API]:\f[R] Seems of limited value, as touch input tends +to have different semantics compared to mouse input. +.RE +.SH SEE ALSO +.PP +ALLEGRO_MOUSE_EMULATION_MODE(3), al_set_mouse_emulation_mode(3). diff --git a/allegro/docs/man/al_get_mouse_event_source.3 b/allegro/docs/man/al_get_mouse_event_source.3 new file mode 100644 index 00000000..a6ad7459 --- /dev/null +++ b/allegro/docs/man/al_get_mouse_event_source.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mouse_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mouse_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_mouse_event_source(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieve the mouse event source. +All [mouse events]ALLEGRO_EVENT_MOUSE_AXES(3) are generated by this +event source. +.PP +Returns NULL if the mouse subsystem was not installed. diff --git a/allegro/docs/man/al_get_mouse_num_axes.3 b/allegro/docs/man/al_get_mouse_num_axes.3 new file mode 100644 index 00000000..78ea8613 --- /dev/null +++ b/allegro/docs/man/al_get_mouse_num_axes.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mouse_num_axes" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mouse_num_axes - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_mouse_num_axes(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of axes on the mouse. +The first axis is 0. +.SH SEE ALSO +.PP +al_get_mouse_num_buttons(3) diff --git a/allegro/docs/man/al_get_mouse_num_buttons.3 b/allegro/docs/man/al_get_mouse_num_buttons.3 new file mode 100644 index 00000000..a1217f23 --- /dev/null +++ b/allegro/docs/man/al_get_mouse_num_buttons.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mouse_num_buttons" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mouse_num_buttons - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_mouse_num_buttons(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of buttons on the mouse. +The first button is 1. +.SH SEE ALSO +.PP +al_get_mouse_num_axes(3) diff --git a/allegro/docs/man/al_get_mouse_state.3 b/allegro/docs/man/al_get_mouse_state.3 new file mode 100644 index 00000000..e8ae2873 --- /dev/null +++ b/allegro/docs/man/al_get_mouse_state.3 @@ -0,0 +1,44 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mouse_state" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mouse_state - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state) +\f[R] +.fi +.SH DESCRIPTION +.PP +Save the state of the mouse specified at the time the function is called +into the given structure. +.PP +Example: +.IP +.nf +\f[C] +ALLEGRO_MOUSE_STATE state; + +al_get_mouse_state(&state); +if (state.buttons & 1) { + /* Primary (e.g. left) mouse button is held. */ + printf(\[dq]Mouse position: (%d, %d)\[rs]n\[dq], state.x, state.y); +} +if (state.buttons & 2) { + /* Secondary (e.g. right) mouse button is held. */ +} +if (state.buttons & 4) { + /* Tertiary (e.g. middle) mouse button is held. */ +} +\f[R] +.fi +.SH SEE ALSO +.PP +ALLEGRO_MOUSE_STATE(3), al_get_mouse_state_axis(3), +al_mouse_button_down(3) diff --git a/allegro/docs/man/al_get_mouse_state_axis.3 b/allegro/docs/man/al_get_mouse_state_axis.3 new file mode 100644 index 00000000..ccc11eac --- /dev/null +++ b/allegro/docs/man/al_get_mouse_state_axis.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mouse_state_axis" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mouse_state_axis - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_mouse_state_axis(const ALLEGRO_MOUSE_STATE *state, int axis) +\f[R] +.fi +.SH DESCRIPTION +.PP +Extract the mouse axis value from the saved state. +The axes are numbered from 0, in this order: x-axis, y-axis, z-axis, +w-axis. +.SH SEE ALSO +.PP +ALLEGRO_MOUSE_STATE(3), al_get_mouse_state(3), al_mouse_button_down(3) diff --git a/allegro/docs/man/al_get_mouse_wheel_precision.3 b/allegro/docs/man/al_get_mouse_wheel_precision.3 new file mode 100644 index 00000000..93eb3974 --- /dev/null +++ b/allegro/docs/man/al_get_mouse_wheel_precision.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_mouse_wheel_precision" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_mouse_wheel_precision - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_mouse_wheel_precision(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the precision of the mouse wheel (the z and w coordinates). +.SH SINCE +.PP +5.1.10 +.SH SEE ALSO +.PP +al_set_mouse_wheel_precision(3) diff --git a/allegro/docs/man/al_get_native_file_dialog_count.3 b/allegro/docs/man/al_get_native_file_dialog_count.3 new file mode 100644 index 00000000..4c579968 --- /dev/null +++ b/allegro/docs/man/al_get_native_file_dialog_count.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_native_file_dialog_count" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_native_file_dialog_count - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_native_file_dialog_count(const ALLEGRO_FILECHOOSER *dialog) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the number of files selected, or 0 if the dialog was cancelled. diff --git a/allegro/docs/man/al_get_native_file_dialog_path.3 b/allegro/docs/man/al_get_native_file_dialog_path.3 new file mode 100644 index 00000000..d65f3060 --- /dev/null +++ b/allegro/docs/man/al_get_native_file_dialog_path.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_native_file_dialog_path" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_native_file_dialog_path - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_native_file_dialog_path( + const ALLEGRO_FILECHOOSER *dialog, size_t i) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns one of the selected paths with index \f[C]i\f[R]. +The index should range from \f[C]0\f[R] to the return value of +al_get_native_file_dialog_count(3) \f[C]-1\f[R]. diff --git a/allegro/docs/man/al_get_native_text_log_event_source.3 b/allegro/docs/man/al_get_native_text_log_event_source.3 new file mode 100644 index 00000000..ad15367a --- /dev/null +++ b/allegro/docs/man/al_get_native_text_log_event_source.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_native_text_log_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_native_text_log_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_native_text_log_event_source( + ALLEGRO_TEXTLOG *textlog) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get an event source for a text log window. +The possible events are: +.TP +ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE +The window was requested to be closed, either by pressing the close +button or pressing Escape on the keyboard. +The user.data1 field will hold a pointer to the ALLEGRO_TEXTLOG(3) which +generated the event. +The user.data2 field will be 1 if the event was generated as a result of +a key press; otherwise it will be zero. diff --git a/allegro/docs/man/al_get_new_bitmap_depth.3 b/allegro/docs/man/al_get_new_bitmap_depth.3 new file mode 100644 index 00000000..93752ed2 --- /dev/null +++ b/allegro/docs/man/al_get_new_bitmap_depth.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_bitmap_depth" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_bitmap_depth - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_new_bitmap_depth(void) +GETTER(new_bitmap_depth, 0) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the value currently set with al_set_new_bitmap_depth(3) on the +current thread or 0 if none was set. +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This is an experimental feature and currently +only works for the OpenGL backend. +.RE diff --git a/allegro/docs/man/al_get_new_bitmap_flags.3 b/allegro/docs/man/al_get_new_bitmap_flags.3 new file mode 100644 index 00000000..bcb22d61 --- /dev/null +++ b/allegro/docs/man/al_get_new_bitmap_flags.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_bitmap_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_bitmap_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_new_bitmap_flags(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the flags used for newly created bitmaps. +.SH SEE ALSO +.PP +al_set_new_bitmap_flags(3) diff --git a/allegro/docs/man/al_get_new_bitmap_format.3 b/allegro/docs/man/al_get_new_bitmap_format.3 new file mode 100644 index 00000000..568f7a20 --- /dev/null +++ b/allegro/docs/man/al_get_new_bitmap_format.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_bitmap_format" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_bitmap_format - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_new_bitmap_format(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the format used for newly created bitmaps. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3), al_set_new_bitmap_format(3) diff --git a/allegro/docs/man/al_get_new_bitmap_samples.3 b/allegro/docs/man/al_get_new_bitmap_samples.3 new file mode 100644 index 00000000..f42cc938 --- /dev/null +++ b/allegro/docs/man/al_get_new_bitmap_samples.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_bitmap_samples" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_bitmap_samples - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_new_bitmap_samples(void) +GETTER(new_bitmap_samples, 0) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the value currently set with al_set_new_bitmap_samples(3) on the +current thread or 0 if none was set. +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This is an experimental feature and currently +only works for the OpenGL backend. +.RE diff --git a/allegro/docs/man/al_get_new_display_adapter.3 b/allegro/docs/man/al_get_new_display_adapter.3 new file mode 100644 index 00000000..8409785a --- /dev/null +++ b/allegro/docs/man/al_get_new_display_adapter.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_display_adapter" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_display_adapter - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_new_display_adapter(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the video adapter index where new displays will be created by the +calling thread, if previously set with al_set_new_display_adapter(3). +Otherwise returns \f[C]ALLEGRO_DEFAULT_DISPLAY_ADAPTER\f[R]. +.SH SEE ALSO +.PP +al_set_new_display_adapter(3) diff --git a/allegro/docs/man/al_get_new_display_flags.3 b/allegro/docs/man/al_get_new_display_flags.3 new file mode 100644 index 00000000..94ddf21f --- /dev/null +++ b/allegro/docs/man/al_get_new_display_flags.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_display_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_display_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_new_display_flags(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the display flags to be used when creating new displays on the +calling thread. +.SH SEE ALSO +.PP +al_set_new_display_flags(3), al_set_display_flag(3) diff --git a/allegro/docs/man/al_get_new_display_option.3 b/allegro/docs/man/al_get_new_display_option.3 new file mode 100644 index 00000000..93aaf5cf --- /dev/null +++ b/allegro/docs/man/al_get_new_display_option.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_display_option" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_display_option - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_new_display_option(int option, int *importance) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieve an extra display setting which was previously set with +al_set_new_display_option(3). diff --git a/allegro/docs/man/al_get_new_display_refresh_rate.3 b/allegro/docs/man/al_get_new_display_refresh_rate.3 new file mode 100644 index 00000000..104d952d --- /dev/null +++ b/allegro/docs/man/al_get_new_display_refresh_rate.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_display_refresh_rate" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_display_refresh_rate - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_new_display_refresh_rate(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the requested refresh rate to be used when creating new displays on +the calling thread. +.SH SEE ALSO +.PP +al_set_new_display_refresh_rate(3) diff --git a/allegro/docs/man/al_get_new_file_interface.3 b/allegro/docs/man/al_get_new_file_interface.3 new file mode 100644 index 00000000..decda409 --- /dev/null +++ b/allegro/docs/man/al_get_new_file_interface.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_file_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_file_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_FILE_INTERFACE *al_get_new_file_interface(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a pointer to the ALLEGRO_FILE_INTERFACE(3) table in effect for +the calling thread. +.SH SEE ALSO +.PP +al_store_state(3), al_restore_state(3). diff --git a/allegro/docs/man/al_get_new_window_position.3 b/allegro/docs/man/al_get_new_window_position.3 new file mode 100644 index 00000000..004ce108 --- /dev/null +++ b/allegro/docs/man/al_get_new_window_position.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_window_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_window_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_new_window_position(int *x, int *y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the position where new non-fullscreen displays created by the +calling thread will be placed. +.SH SEE ALSO +.PP +al_set_new_window_position(3) diff --git a/allegro/docs/man/al_get_new_window_title.3 b/allegro/docs/man/al_get_new_window_title.3 new file mode 100644 index 00000000..f69d5f6b --- /dev/null +++ b/allegro/docs/man/al_get_new_window_title.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_new_window_title" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_new_window_title - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_new_window_title(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the title that will be used when a new display is created. +This returns the value that al_set_window_title(3) was called with. +If that function wasn\[cq]t called yet, the value of al_get_app_name(3) +is returned as a default. +The current implementation returns a pointer to a static buffer of which +you should make a copy if you want to modify it. +.SH SEE ALSO +.PP +al_set_window_title(3), al_set_new_window_title(3), al_create_display(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_get_next_config_entry.3 b/allegro/docs/man/al_get_next_config_entry.3 new file mode 100644 index 00000000..30dd2be7 --- /dev/null +++ b/allegro/docs/man/al_get_next_config_entry.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_next_config_entry" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_next_config_entry - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char const *al_get_next_config_entry(ALLEGRO_CONFIG_ENTRY **iterator) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the next key for the iterator obtained by +al_get_first_config_entry(3). +The \f[C]iterator\f[R] works like the one for +al_get_next_config_section(3). diff --git a/allegro/docs/man/al_get_next_config_section.3 b/allegro/docs/man/al_get_next_config_section.3 new file mode 100644 index 00000000..0c2f3a39 --- /dev/null +++ b/allegro/docs/man/al_get_next_config_section.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_next_config_section" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_next_config_section - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char const *al_get_next_config_section(ALLEGRO_CONFIG_SECTION **iterator) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the name of the next section in the given config file or NULL if +there are no more sections. +The \f[C]iterator\f[R] must have been obtained with +al_get_first_config_section(3) first. +.SH SEE ALSO +.PP +al_get_first_config_section(3) diff --git a/allegro/docs/man/al_get_next_event.3 b/allegro/docs/man/al_get_next_event.3 new file mode 100644 index 00000000..ecf11a35 --- /dev/null +++ b/allegro/docs/man/al_get_next_event.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_next_event" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_next_event - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) +\f[R] +.fi +.SH DESCRIPTION +.PP +Take the next event out of the event queue specified, and copy the +contents into \f[C]ret_event\f[R], returning true. +The original event will be removed from the queue. +If the event queue is empty, return false and the contents of +\f[C]ret_event\f[R] are unspecified. +.SH SEE ALSO +.PP +ALLEGRO_EVENT(3), al_peek_next_event(3), al_wait_for_event(3) diff --git a/allegro/docs/man/al_get_num_display_modes.3 b/allegro/docs/man/al_get_num_display_modes.3 new file mode 100644 index 00000000..d366ed07 --- /dev/null +++ b/allegro/docs/man/al_get_num_display_modes.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_num_display_modes" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_num_display_modes - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_num_display_modes(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the number of available fullscreen display modes for the current set +of display parameters. +This will use the values set with al_set_new_display_refresh_rate(3), +and al_set_new_display_flags(3) to find the number of modes that match. +Settings the new display parameters to zero will give a list of all +modes for the default driver. +.SH SEE ALSO +.PP +al_get_display_mode(3) diff --git a/allegro/docs/man/al_get_num_joysticks.3 b/allegro/docs/man/al_get_num_joysticks.3 new file mode 100644 index 00000000..c02ed6df --- /dev/null +++ b/allegro/docs/man/al_get_num_joysticks.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_num_joysticks" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_num_joysticks - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_num_joysticks(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of joysticks currently on the system (or potentially +on the system). +This number can change after al_reconfigure_joysticks(3) is called, in +order to support hotplugging. +.PP +Returns 0 if there is no joystick driver installed. +.SH SEE ALSO +.PP +al_get_joystick(3), al_get_joystick_active(3) diff --git a/allegro/docs/man/al_get_num_video_adapters.3 b/allegro/docs/man/al_get_num_video_adapters.3 new file mode 100644 index 00000000..0fff4036 --- /dev/null +++ b/allegro/docs/man/al_get_num_video_adapters.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_num_video_adapters" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_num_video_adapters - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_num_video_adapters(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the number of video \[lq]adapters\[rq] attached to the computer. +Each video card attached to the computer counts as one or more adapters. +An adapter is thus really a video port that can have a monitor connected +to it. +.PP +On Windows, use al_set_new_display_flags(3) to switch between Direct3D +and OpenGL backends, which will often have different adapters available. +.SH SEE ALSO +.PP +al_get_monitor_info(3) diff --git a/allegro/docs/man/al_get_opengl_extension_list.3 b/allegro/docs/man/al_get_opengl_extension_list.3 new file mode 100644 index 00000000..920f0329 --- /dev/null +++ b/allegro/docs/man/al_get_opengl_extension_list.3 @@ -0,0 +1,54 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_extension_list" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_extension_list - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_OGL_EXT_LIST *al_get_opengl_extension_list(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the list of OpenGL extensions supported by Allegro, for the +given display. +.PP +Allegro will keep information about all extensions it knows about in a +structure returned by \f[C]al_get_opengl_extension_list\f[R]. +.PP +For example: +.IP +.nf +\f[C] +if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multitexture) { + //use it +} +\f[R] +.fi +.PP +The extension will be set to true if available for the given display and +false otherwise. +This means to use the definitions and functions from an OpenGL +extension, all you need to do is to check for it as above at run time, +after acquiring the OpenGL display from Allegro. +.PP +Under Windows, this will also work with WGL extensions, and under Unix +with GLX extensions. +.PP +In case you want to manually check for extensions and load function +pointers yourself (say, in case the Allegro developers did not include +it yet), you can use the al_have_opengl_extension(3) and +al_get_opengl_proc_address(3) functions instead. +.RS +.PP +\f[I]Note:\f[R] the exact extensions exposed depend on how Allegro was +compiled. +It is recommended to use al_have_opengl_extension(3) and +al_get_opengl_proc_address(3) for the most stable experience. +.RE diff --git a/allegro/docs/man/al_get_opengl_fbo.3 b/allegro/docs/man/al_get_opengl_fbo.3 new file mode 100644 index 00000000..d7a8ac70 --- /dev/null +++ b/allegro/docs/man/al_get_opengl_fbo.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_fbo" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_fbo - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +GLuint al_get_opengl_fbo(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the OpenGL FBO id internally used by the given bitmap if it uses +one, otherwise returns zero. +No attempt will be made to create an FBO if the bitmap is not owned by +the current display. +.PP +The FBO returned by this function will only be freed when the bitmap is +destroyed, or if you call al_remove_opengl_fbo(3) on the bitmap. +.RS +.PP +\f[I]Note:\f[R] In Allegro 5.0.0 this function only returned an FBO +which had previously been created by calling al_set_target_bitmap(3). +It would not attempt to create an FBO itself. +This has since been changed. +.RE +.SH SEE ALSO +.PP +al_remove_opengl_fbo(3), al_set_target_bitmap(3) diff --git a/allegro/docs/man/al_get_opengl_proc_address.3 b/allegro/docs/man/al_get_opengl_proc_address.3 new file mode 100644 index 00000000..908dc08f --- /dev/null +++ b/allegro/docs/man/al_get_opengl_proc_address.3 @@ -0,0 +1,54 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_proc_address" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_proc_address - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void *al_get_opengl_proc_address(const char *name) +\f[R] +.fi +.SH DESCRIPTION +.PP +Helper to get the address of an OpenGL symbol +.PP +Example: +.PP +How to get the function \f[I]glMultiTexCoord3fARB\f[R] that comes with +ARB\[cq]s Multitexture extension: +.IP +.nf +\f[C] +// define the type of the function +ALLEGRO_DEFINE_PROC_TYPE(void, MULTI_TEX_FUNC, + (GLenum, GLfloat, GLfloat, GLfloat)); +// declare the function pointer +MULTI_TEX_FUNC glMultiTexCoord3fARB; +// get the address of the function +glMultiTexCoord3fARB = (MULTI_TEX_FUNC) al_get_opengl_proc_address( + \[dq]glMultiTexCoord3fARB\[dq]); +\f[R] +.fi +.PP +If \f[I]glMultiTexCoord3fARB\f[R] is not NULL then it can be used as if +it has been defined in the OpenGL core library. +.RS +.PP +\f[I]Note:\f[R] Under Windows, OpenGL functions may need a special +calling convention, so it\[cq]s best to always use the +ALLEGRO_DEFINE_PROC_TYPE macro when declaring function pointer types for +OpenGL functions. +.RE +.PP +Parameters: +.PP +name - The name of the symbol you want to link to. +.SH RETURN VALUE +.PP +A pointer to the symbol if available or NULL otherwise. diff --git a/allegro/docs/man/al_get_opengl_program_object.3 b/allegro/docs/man/al_get_opengl_program_object.3 new file mode 100644 index 00000000..6c78b9da --- /dev/null +++ b/allegro/docs/man/al_get_opengl_program_object.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_program_object" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_program_object - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +GLuint al_get_opengl_program_object(ALLEGRO_SHADER *shader) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the OpenGL program object associated with this shader, if the +platform is \f[C]ALLEGRO_SHADER_GLSL\f[R]. +Otherwise, returns 0. diff --git a/allegro/docs/man/al_get_opengl_texture.3 b/allegro/docs/man/al_get_opengl_texture.3 new file mode 100644 index 00000000..e097d879 --- /dev/null +++ b/allegro/docs/man/al_get_opengl_texture.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_texture" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_texture - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +GLuint al_get_opengl_texture(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the OpenGL texture id internally used by the given bitmap if it +uses one, else 0. +.PP +Example: +.IP +.nf +\f[C] +bitmap = al_load_bitmap(\[dq]my_texture.png\[dq]); +texture = al_get_opengl_texture(bitmap); +if (texture != 0) + glBindTexture(GL_TEXTURE_2D, texture); +\f[R] +.fi diff --git a/allegro/docs/man/al_get_opengl_texture_position.3 b/allegro/docs/man/al_get_opengl_texture_position.3 new file mode 100644 index 00000000..fb15b6e8 --- /dev/null +++ b/allegro/docs/man/al_get_opengl_texture_position.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_texture_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_texture_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_opengl_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the u/v coordinates for the top/left corner of the bitmap within +the used texture, in pixels. +.SH SEE ALSO +.PP +al_get_opengl_texture_size(3) diff --git a/allegro/docs/man/al_get_opengl_texture_size.3 b/allegro/docs/man/al_get_opengl_texture_size.3 new file mode 100644 index 00000000..4876bd40 --- /dev/null +++ b/allegro/docs/man/al_get_opengl_texture_size.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_texture_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_texture_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_opengl_texture_size(ALLEGRO_BITMAP *bitmap, int *w, int *h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves the size of the texture used for the bitmap. +This can be different from the bitmap size if OpenGL only supports +power-of-two sizes or if it is a sub-bitmap. +.PP +Returns true on success, false on failure. +Zero width and height are returned if the bitmap is not an OpenGL +bitmap. +.SH SEE ALSO +.PP +al_get_opengl_texture_position(3) diff --git a/allegro/docs/man/al_get_opengl_variant.3 b/allegro/docs/man/al_get_opengl_variant.3 new file mode 100644 index 00000000..cd073911 --- /dev/null +++ b/allegro/docs/man/al_get_opengl_variant.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_variant" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_variant - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_opengl_variant(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the variant or type of OpenGL used on the running platform. +This function can be called before creating a display or setting +properties for new displays. +Possible values are: +.TP +ALLEGRO_DESKTOP_OPENGL +Regular OpenGL as seen on desktop/laptop computers. +.TP +ALLEGRO_OPENGL_ES +Trimmed down version of OpenGL used on many small consumer electronic +devices such as handheld (and sometimes full size) consoles. +.SH SEE ALSO +.PP +al_get_opengl_version(3) diff --git a/allegro/docs/man/al_get_opengl_version.3 b/allegro/docs/man/al_get_opengl_version.3 new file mode 100644 index 00000000..9497dd21 --- /dev/null +++ b/allegro/docs/man/al_get_opengl_version.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_opengl_version" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_opengl_version - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +uint32_t al_get_opengl_version(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the OpenGL or OpenGL ES version number of the client (the +computer the program is running on), for the current display. +\[lq]1.0\[rq] is returned as 0x01000000, \[lq]1.2.1\[rq] is returned as +0x01020100, and \[lq]1.2.2\[rq] as 0x01020200, etc. +.PP +A valid OpenGL context must exist for this function to work, which means +you may \f[I]not\f[R] call it before al_create_display(3). +.SH SEE ALSO +.PP +al_get_opengl_variant(3) diff --git a/allegro/docs/man/al_get_org_name.3 b/allegro/docs/man/al_get_org_name.3 new file mode 100644 index 00000000..0952bb19 --- /dev/null +++ b/allegro/docs/man/al_get_org_name.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_org_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_org_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_org_name(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the global organization name string. +.SH SEE ALSO +.PP +al_set_org_name(3) diff --git a/allegro/docs/man/al_get_parent_bitmap.3 b/allegro/docs/man/al_get_parent_bitmap.3 new file mode 100644 index 00000000..545e20b7 --- /dev/null +++ b/allegro/docs/man/al_get_parent_bitmap.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_parent_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_parent_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_get_parent_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the bitmap this bitmap is a sub-bitmap of. +Returns NULL if this bitmap is not a sub-bitmap. +This function always returns the real bitmap, and never a sub-bitmap. +This might NOT match what was passed to al_create_sub_bitmap(3). +Consider this code, for instance: +.IP +.nf +\f[C] +ALLEGRO_BITMAP* a = al_create_bitmap(512, 512); +ALLEGRO_BITMAP* b = al_create_sub_bitmap(a, 128, 128, 256, 256); +ALLEGRO_BITMAP* c = al_create_sub_bitmap(b, 64, 64, 128, 128); +ASSERT(al_get_parent_bitmap(b) == a && al_get_parent_bitmap(c) == a); +\f[R] +.fi +.PP +The assertion will pass because only \f[C]a\f[R] is a real bitmap, and +both \f[C]b\f[R] and \f[C]c\f[R] are its sub-bitmaps. +.SH SINCE +.PP +5.0.6, 5.1.2 +.SH SEE ALSO +.PP +al_create_sub_bitmap(3), al_is_sub_bitmap(3) diff --git a/allegro/docs/man/al_get_path_basename.3 b/allegro/docs/man/al_get_path_basename.3 new file mode 100644 index 00000000..ecb30150 --- /dev/null +++ b/allegro/docs/man/al_get_path_basename.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_path_basename" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_path_basename - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_path_basename(const ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the basename, i.e.\ filename with the extension removed. +If the filename doesn\[cq]t have an extension, the whole filename is the +basename. +If there is no filename part then the empty string is returned. +.PP +The returned pointer is valid only until the filename part of the path +is modified in any way, or until the path is destroyed. +.SH SEE ALSO +.PP +al_get_path_filename(3), al_get_path_extension(3) diff --git a/allegro/docs/man/al_get_path_component.3 b/allegro/docs/man/al_get_path_component.3 new file mode 100644 index 00000000..71ba5f15 --- /dev/null +++ b/allegro/docs/man/al_get_path_component.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_path_component" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_path_component - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_path_component(const ALLEGRO_PATH *path, int i) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the i\[cq]th directory component of a path, counting from zero. +If the index is negative then count from the right, i.e.\ -1 refers to +the last path component. +It is an error to pass an index which is out of bounds. +.SH SEE ALSO +.PP +al_get_path_num_components(3), al_get_path_tail(3) diff --git a/allegro/docs/man/al_get_path_drive.3 b/allegro/docs/man/al_get_path_drive.3 new file mode 100644 index 00000000..6c49bde7 --- /dev/null +++ b/allegro/docs/man/al_get_path_drive.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_path_drive" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_path_drive - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_path_drive(const ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the drive letter on a path, or the empty string if there is none. +.PP +The \[lq]drive letter\[rq] is only used on Windows, and is usually a +string like \[lq]c:\[rq], but may be something like +\[lq]\[rs]\[rs]Computer Name\[rq] in the case of UNC (Uniform Naming +Convention) syntax. diff --git a/allegro/docs/man/al_get_path_extension.3 b/allegro/docs/man/al_get_path_extension.3 new file mode 100644 index 00000000..09eedbee --- /dev/null +++ b/allegro/docs/man/al_get_path_extension.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_path_extension" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_path_extension - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_path_extension(const ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a pointer to the start of the extension of the filename, +i.e.\ everything from the final dot (`.') character onwards. +If no dot exists, returns an empty string. +.PP +The returned pointer is valid only until the filename part of the path +is modified in any way, or until the path is destroyed. +.SH SEE ALSO +.PP +al_get_path_filename(3), al_get_path_basename(3) diff --git a/allegro/docs/man/al_get_path_filename.3 b/allegro/docs/man/al_get_path_filename.3 new file mode 100644 index 00000000..6ef860e0 --- /dev/null +++ b/allegro/docs/man/al_get_path_filename.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_path_filename" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_path_filename - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_path_filename(const ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the filename part of the path, or the empty string if there is +none. +.PP +The returned pointer is valid only until the filename part of the path +is modified in any way, or until the path is destroyed. +.SH SEE ALSO +.PP +al_get_path_basename(3), al_get_path_extension(3), +al_get_path_component(3) diff --git a/allegro/docs/man/al_get_path_num_components.3 b/allegro/docs/man/al_get_path_num_components.3 new file mode 100644 index 00000000..7f7f407a --- /dev/null +++ b/allegro/docs/man/al_get_path_num_components.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_path_num_components" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_path_num_components - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_path_num_components(const ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of directory components in a path. +.PP +The directory components do not include the final part of a path (the +filename). +.SH SEE ALSO +.PP +al_get_path_component(3) diff --git a/allegro/docs/man/al_get_path_tail.3 b/allegro/docs/man/al_get_path_tail.3 new file mode 100644 index 00000000..9c31249f --- /dev/null +++ b/allegro/docs/man/al_get_path_tail.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_path_tail" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_path_tail - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_path_tail(const ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the last directory component, or NULL if there are no directory +components. diff --git a/allegro/docs/man/al_get_pixel.3 b/allegro/docs/man/al_get_pixel.3 new file mode 100644 index 00000000..1354fbcf --- /dev/null +++ b/allegro/docs/man/al_get_pixel.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_pixel" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_pixel - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get a pixel\[cq]s color value from the specified bitmap. +This operation is slow on non-memory bitmaps. +Consider locking the bitmap if you are going to use this function +multiple times on the same bitmap. +.SH SEE ALSO +.PP +ALLEGRO_COLOR(3), al_put_pixel(3), al_lock_bitmap(3) diff --git a/allegro/docs/man/al_get_pixel_block_height.3 b/allegro/docs/man/al_get_pixel_block_height.3 new file mode 100644 index 00000000..7243e1aa --- /dev/null +++ b/allegro/docs/man/al_get_pixel_block_height.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_pixel_block_height" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_pixel_block_height - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_pixel_block_height(int format) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the height of the the pixel block for this format. +.SH SINCE +.PP +5.1.9. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3), al_get_pixel_block_size(3), +al_get_pixel_block_width(3) diff --git a/allegro/docs/man/al_get_pixel_block_size.3 b/allegro/docs/man/al_get_pixel_block_size.3 new file mode 100644 index 00000000..4f6fea3c --- /dev/null +++ b/allegro/docs/man/al_get_pixel_block_size.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_pixel_block_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_pixel_block_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_pixel_block_size(int format) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of bytes that a block of pixels with this format +occupies. +.SH SINCE +.PP +5.1.9. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3), al_get_pixel_block_width(3), +al_get_pixel_block_height(3) diff --git a/allegro/docs/man/al_get_pixel_block_width.3 b/allegro/docs/man/al_get_pixel_block_width.3 new file mode 100644 index 00000000..6cd3868a --- /dev/null +++ b/allegro/docs/man/al_get_pixel_block_width.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_pixel_block_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_pixel_block_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_pixel_block_width(int format) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the width of the the pixel block for this format. +.SH SINCE +.PP +5.1.9. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3), al_get_pixel_block_size(3), +al_get_pixel_block_height(3) diff --git a/allegro/docs/man/al_get_pixel_format_bits.3 b/allegro/docs/man/al_get_pixel_format_bits.3 new file mode 100644 index 00000000..cb939e5c --- /dev/null +++ b/allegro/docs/man/al_get_pixel_format_bits.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_pixel_format_bits" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_pixel_format_bits - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_pixel_format_bits(int format) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of bits that a pixel of the given format occupies. +For blocked pixel formats (e.g.\ compressed formats), this returns 0. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3), al_get_pixel_size(3) diff --git a/allegro/docs/man/al_get_pixel_size.3 b/allegro/docs/man/al_get_pixel_size.3 new file mode 100644 index 00000000..513a3698 --- /dev/null +++ b/allegro/docs/man/al_get_pixel_size.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_pixel_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_pixel_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_pixel_size(int format) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of bytes that a pixel of the given format occupies. +For blocked pixel formats (e.g.\ compressed formats), this returns 0. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3), al_get_pixel_format_bits(3) diff --git a/allegro/docs/man/al_get_ram_size.3 b/allegro/docs/man/al_get_ram_size.3 new file mode 100644 index 00000000..24e35a30 --- /dev/null +++ b/allegro/docs/man/al_get_ram_size.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_ram_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_ram_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_ram_size(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the size in MB of the random access memory that the system +Allegro is running on has and which could be detected, or a negative +number if detection failed. +Even if a positive number is returned, it might be that it is not +correct. +For example, Allegro running on a virtual machine will return the amount +of RAM of the VM, and not that of the underlying system. +.PP +Furthermore even if the number is correct, this only gives you +information about the total physical memory of the system Allegro runs +on. +The memory available to your program may be less or more than what this +function returns due to circumstances such as virtual memory, and other +programs that are currently running. +.PP +Therefore, it\[cq]s best to use this for advisory purposes only. +It is certainly a bad idea to make your program exclusive to systems for +which this function returns a certain \[lq]desirable\[rq] number. +.PP +This function may be called prior to al_install_system(3) or al_init(3). +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_get_sample.3 b/allegro/docs/man/al_get_sample.3 new file mode 100644 index 00000000..77d1d0c8 --- /dev/null +++ b/allegro/docs/man/al_get_sample.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SAMPLE *al_get_sample(ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the sample data that the sample instance plays. +.PP +Note this returns a pointer to an internal structure, \f[I]not\f[R] the +ALLEGRO_SAMPLE(3) that you may have passed to al_set_sample(3). +However, the sample buffer of the returned ALLEGRO_SAMPLE will be the +same as the one that was used to create the sample (passed to +al_create_sample(3)). +You can use al_get_sample_data(3) on the return value to retrieve and +compare it. +.SH SEE ALSO +.PP +al_set_sample(3) diff --git a/allegro/docs/man/al_get_sample_channels.3 b/allegro/docs/man/al_get_sample_channels.3 new file mode 100644 index 00000000..23fdf9b6 --- /dev/null +++ b/allegro/docs/man/al_get_sample_channels.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_channels" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_channels - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CHANNEL_CONF al_get_sample_channels(const ALLEGRO_SAMPLE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the channel configuration of the sample. +.SH SEE ALSO +.PP +ALLEGRO_CHANNEL_CONF(3), al_get_sample_depth(3), +al_get_sample_frequency(3), al_get_sample_length(3), +al_get_sample_data(3) diff --git a/allegro/docs/man/al_get_sample_data.3 b/allegro/docs/man/al_get_sample_data.3 new file mode 100644 index 00000000..d1564715 --- /dev/null +++ b/allegro/docs/man/al_get_sample_data.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_data" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_data - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void *al_get_sample_data(const ALLEGRO_SAMPLE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a pointer to the raw sample data. +.SH SEE ALSO +.PP +al_get_sample_channels(3), al_get_sample_depth(3), +al_get_sample_frequency(3), al_get_sample_length(3) diff --git a/allegro/docs/man/al_get_sample_depth.3 b/allegro/docs/man/al_get_sample_depth.3 new file mode 100644 index 00000000..f38f7c5b --- /dev/null +++ b/allegro/docs/man/al_get_sample_depth.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_depth" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_depth - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_DEPTH al_get_sample_depth(const ALLEGRO_SAMPLE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the audio depth of the sample. +.SH SEE ALSO +.PP +ALLEGRO_AUDIO_DEPTH(3), al_get_sample_channels(3), +al_get_sample_frequency(3), al_get_sample_length(3), +al_get_sample_data(3) diff --git a/allegro/docs/man/al_get_sample_frequency.3 b/allegro/docs/man/al_get_sample_frequency.3 new file mode 100644 index 00000000..3cdd8f93 --- /dev/null +++ b/allegro/docs/man/al_get_sample_frequency.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_frequency" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_frequency - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_sample_frequency(const ALLEGRO_SAMPLE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the frequency (in Hz) of the sample. +.SH SEE ALSO +.PP +al_get_sample_channels(3), al_get_sample_depth(3), +al_get_sample_length(3), al_get_sample_data(3) diff --git a/allegro/docs/man/al_get_sample_instance_attached.3 b/allegro/docs/man/al_get_sample_instance_attached.3 new file mode 100644 index 00000000..bae338c5 --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_attached.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_attached" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_attached - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_sample_instance_attached(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return whether the sample instance is attached to something. +.SH SEE ALSO +.PP +al_attach_sample_instance_to_mixer(3), +al_attach_sample_instance_to_voice(3), al_detach_sample_instance(3) diff --git a/allegro/docs/man/al_get_sample_instance_channels.3 b/allegro/docs/man/al_get_sample_instance_channels.3 new file mode 100644 index 00000000..707cbdfa --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_channels.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_channels" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_channels - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CHANNEL_CONF al_get_sample_instance_channels( + const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the channel configuration of the sample instance\[cq]s sample +data. +.SH SEE ALSO +.PP +ALLEGRO_CHANNEL_CONF(3). diff --git a/allegro/docs/man/al_get_sample_instance_depth.3 b/allegro/docs/man/al_get_sample_instance_depth.3 new file mode 100644 index 00000000..606e7a80 --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_depth.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_depth" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_depth - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_DEPTH al_get_sample_instance_depth(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the audio depth of the sample instance\[cq]s sample data. +.SH SEE ALSO +.PP +ALLEGRO_AUDIO_DEPTH(3). diff --git a/allegro/docs/man/al_get_sample_instance_frequency.3 b/allegro/docs/man/al_get_sample_instance_frequency.3 new file mode 100644 index 00000000..1987ce11 --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_frequency.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_frequency" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_frequency - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_sample_instance_frequency(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the frequency (in Hz) of the sample instance\[cq]s sample data. diff --git a/allegro/docs/man/al_get_sample_instance_gain.3 b/allegro/docs/man/al_get_sample_instance_gain.3 new file mode 100644 index 00000000..54bc765b --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_gain.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_gain" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_gain - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_sample_instance_gain(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the playback gain of the sample instance. +.SH SEE ALSO +.PP +al_set_sample_instance_gain(3) diff --git a/allegro/docs/man/al_get_sample_instance_length.3 b/allegro/docs/man/al_get_sample_instance_length.3 new file mode 100644 index 00000000..b007042a --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_length.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_length" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_length - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_sample_instance_length(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the length of the sample instance in sample values. +This property may differ from the length of the instance\[cq]s sample +data. +.SH SEE ALSO +.PP +al_set_sample_instance_length(3), al_get_sample_instance_time(3) diff --git a/allegro/docs/man/al_get_sample_instance_pan.3 b/allegro/docs/man/al_get_sample_instance_pan.3 new file mode 100644 index 00000000..fdafbce1 --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_pan.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_pan" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_pan - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_sample_instance_pan(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the pan value of the sample instance. +.SH SEE ALSO +.PP +al_set_sample_instance_pan(3). diff --git a/allegro/docs/man/al_get_sample_instance_playing.3 b/allegro/docs/man/al_get_sample_instance_playing.3 new file mode 100644 index 00000000..74815c3e --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_playing.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_sample_instance_playing(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the sample instance is in the playing state. +This may be true even if the instance is not attached to anything. +.SH SEE ALSO +.PP +al_set_sample_instance_playing(3) diff --git a/allegro/docs/man/al_get_sample_instance_playmode.3 b/allegro/docs/man/al_get_sample_instance_playmode.3 new file mode 100644 index 00000000..f63651aa --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_playmode.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_playmode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_playmode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_PLAYMODE al_get_sample_instance_playmode(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the playback mode of the sample instance. +.SH SEE ALSO +.PP +ALLEGRO_PLAYMODE(3), al_set_sample_instance_playmode(3) diff --git a/allegro/docs/man/al_get_sample_instance_position.3 b/allegro/docs/man/al_get_sample_instance_position.3 new file mode 100644 index 00000000..edd40225 --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_position.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_sample_instance_position(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get the playback position of a sample instance. +.SH SEE ALSO +.PP +al_set_sample_instance_position(3) diff --git a/allegro/docs/man/al_get_sample_instance_speed.3 b/allegro/docs/man/al_get_sample_instance_speed.3 new file mode 100644 index 00000000..2d7ed820 --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_speed.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_speed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_speed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_sample_instance_speed(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the relative playback speed of the sample instance. +.SH SEE ALSO +.PP +al_set_sample_instance_speed(3) diff --git a/allegro/docs/man/al_get_sample_instance_time.3 b/allegro/docs/man/al_get_sample_instance_time.3 new file mode 100644 index 00000000..25dd0570 --- /dev/null +++ b/allegro/docs/man/al_get_sample_instance_time.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_instance_time" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_instance_time - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_sample_instance_time(const ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the length of the sample instance in seconds, assuming a playback +speed of 1.0. +.SH SEE ALSO +.PP +al_get_sample_instance_length(3) diff --git a/allegro/docs/man/al_get_sample_length.3 b/allegro/docs/man/al_get_sample_length.3 new file mode 100644 index 00000000..2f9b31f7 --- /dev/null +++ b/allegro/docs/man/al_get_sample_length.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_sample_length" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_sample_length - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_sample_length(const ALLEGRO_SAMPLE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the length of the sample in sample values. +.SH SEE ALSO +.PP +al_get_sample_channels(3), al_get_sample_depth(3), +al_get_sample_frequency(3), al_get_sample_data(3) diff --git a/allegro/docs/man/al_get_separate_bitmap_blender.3 b/allegro/docs/man/al_get_separate_bitmap_blender.3 new file mode 100644 index 00000000..c34fe4c0 --- /dev/null +++ b/allegro/docs/man/al_get_separate_bitmap_blender.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_separate_bitmap_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_separate_bitmap_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_separate_bitmap_blender(int *op, int *src, int *dst, int *alpha_op, int *alpha_src, int *alpha_dst) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the current blender being used by the target bitmap. +You can pass NULL for values you are not interested in. +.SH SINCE +.PP +5.2.5 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE +.SH SEE ALSO +.PP +al_set_separate_bitmap_blender(3), al_get_bitmap_blender(3) diff --git a/allegro/docs/man/al_get_separate_blender.3 b/allegro/docs/man/al_get_separate_blender.3 new file mode 100644 index 00000000..5a1c0805 --- /dev/null +++ b/allegro/docs/man/al_get_separate_blender.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_separate_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_separate_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_separate_blender(int *op, int *src, int *dst, + int *alpha_op, int *alpha_src, int *alpha_dst) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the active blender for the current thread. +You can pass NULL for values you are not interested in. +.SH SEE ALSO +.PP +al_set_separate_blender(3), al_get_blender(3) diff --git a/allegro/docs/man/al_get_shader_log.3 b/allegro/docs/man/al_get_shader_log.3 new file mode 100644 index 00000000..2b1fabed --- /dev/null +++ b/allegro/docs/man/al_get_shader_log.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_shader_log" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_shader_log - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_get_shader_log(ALLEGRO_SHADER *shader) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a read-only string containing the information log for a shader +program. +The log is updated by certain functions, such as +al_attach_shader_source(3) or al_build_shader(3) when there is an error. +.PP +This function never returns NULL. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_attach_shader_source(3), al_attach_shader_source_file(3), +al_build_shader(3) diff --git a/allegro/docs/man/al_get_shader_platform.3 b/allegro/docs/man/al_get_shader_platform.3 new file mode 100644 index 00000000..9ff0e739 --- /dev/null +++ b/allegro/docs/man/al_get_shader_platform.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_shader_platform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_shader_platform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SHADER_PLATFORM al_get_shader_platform(ALLEGRO_SHADER *shader) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the platform the shader was created with (either +ALLEGRO_SHADER_HLSL or ALLEGRO_SHADER_GLSL). +.SH SINCE +.PP +5.1.6 +.SH SEE ALSO +.PP +al_create_shader(3) diff --git a/allegro/docs/man/al_get_standard_path.3 b/allegro/docs/man/al_get_standard_path.3 new file mode 100644 index 00000000..63a0b018 --- /dev/null +++ b/allegro/docs/man/al_get_standard_path.3 @@ -0,0 +1,91 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_standard_path" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_standard_path - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_PATH *al_get_standard_path(int id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets a system path, depending on the \f[C]id\f[R] parameter. +Some of these paths may be affected by the organization and application +name, so be sure to set those before calling this function. +.PP +The paths are not guaranteed to be unique (e.g., SETTINGS and DATA may +be the same on some platforms), so you should be sure your filenames are +unique if you need to avoid naming collisions. +Also, a returned path may not actually exist on the file system. +.TP +ALLEGRO_RESOURCES_PATH +If you bundle data in a location relative to your executable, then you +should use this path to locate that data. +On most platforms, this is the directory that contains the executable +file. +.RS +.PP +If called from an OS X app bundle, then this will point to the internal +resource directory (/Contents/Resources). +To maintain consistency, if you put your resources into a directory +called \[lq]data\[rq] beneath the executable on some other platform +(like Windows), then you should also create a directory called +\[lq]data\[rq] under the OS X app bundle\[cq]s resource folder. +.PP +You should not try to write to this path, as it is very likely +read-only. +.PP +If you install your resources in some other system directory (e.g., in +/usr/share or C:\[rs]ProgramData), then you are responsible for keeping +track of that yourself. +.RE +.TP +ALLEGRO_TEMP_PATH +Path to the directory for temporary files. +.TP +ALLEGRO_USER_HOME_PATH +This is the user\[cq]s home directory. +You should not normally write files into this directory directly, or +create any sub folders in it, without explicit permission from the user. +One practical application of this path would be to use it as the +starting place of a file selector in a GUI. +.TP +ALLEGRO_USER_DOCUMENTS_PATH +This location is easily accessible by the user, and is the place to +store documents and files that the user might want to later open with an +external program or transfer to another place. +.RS +.PP +You should not save files here unless the user expects it, usually by +explicit permission. +.RE +.TP +ALLEGRO_USER_DATA_PATH +If your program saves any data that the user doesn\[cq]t need to access +externally, then you should place it here. +This is generally the least intrusive place to store data. +This path will usually not be present on the file system, so make sure +to create it before writing to it. +.TP +ALLEGRO_USER_SETTINGS_PATH +If you are saving configuration files (especially if the user may want +to edit them outside of your program), then you should place them here. +This path will usually not be present on the file system, so make sure +to create it before writing to it. +.TP +ALLEGRO_EXENAME_PATH +The full path to the executable. +.PP +Returns NULL on failure. +The returned path should be freed with al_destroy_path(3). +.SH SEE ALSO +.PP +al_set_app_name(3), al_set_org_name(3), al_destroy_path(3), +al_set_exe_name(3) diff --git a/allegro/docs/man/al_get_system_config.3 b/allegro/docs/man/al_get_system_config.3 new file mode 100644 index 00000000..4a2590c0 --- /dev/null +++ b/allegro/docs/man/al_get_system_config.3 @@ -0,0 +1,52 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_system_config" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_system_config - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CONFIG *al_get_system_config(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the system configuration structure. +The returned configuration should not be destroyed with +al_destroy_config(3). +This is mainly used for configuring Allegro and its addons. +You may populate this configuration before Allegro is installed to +control things like the logging levels and other features. +.PP +Allegro will try to populate this configuration by loading a +configuration file from a few different locations, in this order: +.IP \[bu] 2 +\f[I]Unix only:\f[R] /etc/allegro5rc +.IP \[bu] 2 +\f[I]Unix only:\f[R] $HOME/allegro5rc +.IP \[bu] 2 +\f[I]Unix only:\f[R] $HOME/.allegro5rc +.IP \[bu] 2 +allegro5.cfg next to the executable +.PP +If multiple copies are found, then they are merged using +al_merge_config_into(3). +.PP +The contents of this file are documented inside a prototypical +\f[C]allegro5.cfg\f[R] that you can find in the root directory of the +source distributions of Allegro. +They are also reproduced below. +.PP +Note that Allegro will not look into that file unless you make a copy of +it and place it next to your executable! +.IP +.nf +\f[C] +__ALLEGRO_5_CFG +\f[R] +.fi diff --git a/allegro/docs/man/al_get_system_id.3 b/allegro/docs/man/al_get_system_id.3 new file mode 100644 index 00000000..3ebab425 --- /dev/null +++ b/allegro/docs/man/al_get_system_id.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_system_id" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_system_id - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SYSTEM_ID al_get_system_id(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the platform that Allegro is running on. +.SH SINCE +.PP +5.2.5 +.SH SEE ALSO +.PP +ALLEGRO_SYSTEM_ID(3) diff --git a/allegro/docs/man/al_get_target_bitmap.3 b/allegro/docs/man/al_get_target_bitmap.3 new file mode 100644 index 00000000..708ca850 --- /dev/null +++ b/allegro/docs/man/al_get_target_bitmap.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_target_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_target_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_get_target_bitmap(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the target bitmap of the calling thread. +.SH SEE ALSO +.PP +al_set_target_bitmap(3) diff --git a/allegro/docs/man/al_get_text_dimensions.3 b/allegro/docs/man/al_get_text_dimensions.3 new file mode 100644 index 00000000..f6c6f7fa --- /dev/null +++ b/allegro/docs/man/al_get_text_dimensions.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_text_dimensions" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_text_dimensions - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_text_dimensions(const ALLEGRO_FONT *f, + char const *text, + int *bbx, int *bby, int *bbw, int *bbh) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sometimes, the al_get_text_width(3) and al_get_font_line_height(3) +functions are not enough for exact text placement, so this function +returns some additional information. +.PP +Returned variables (all in pixels): +.IP \[bu] 2 +x, y - Offset to upper left corner of bounding box. +.IP \[bu] 2 +w, h - Dimensions of bounding box. +.PP +Note that glyphs may go to the left and upwards of the X, in which case +x and y will have negative values. +.SH SEE ALSO +.PP +al_get_text_width(3), al_get_font_line_height(3), +al_get_ustr_dimensions(3) diff --git a/allegro/docs/man/al_get_text_width.3 b/allegro/docs/man/al_get_text_width.3 new file mode 100644 index 00000000..40faf59d --- /dev/null +++ b/allegro/docs/man/al_get_text_width.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_text_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_text_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_text_width(const ALLEGRO_FONT *f, const char *str) +\f[R] +.fi +.SH DESCRIPTION +.PP +Calculates the length of a string in a particular font, in pixels. +.SH SEE ALSO +.PP +al_get_ustr_width(3), al_get_font_line_height(3), +al_get_text_dimensions(3) diff --git a/allegro/docs/man/al_get_thread_should_stop.3 b/allegro/docs/man/al_get_thread_should_stop.3 new file mode 100644 index 00000000..c1469087 --- /dev/null +++ b/allegro/docs/man/al_get_thread_should_stop.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_thread_should_stop" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_thread_should_stop - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_thread_should_stop(ALLEGRO_THREAD *thread) +\f[R] +.fi +.SH DESCRIPTION +.PP +Check if another thread is waiting for \f[C]thread\f[R] to stop. +Threads which run in a loop should check this periodically and act on it +when convenient. +.PP +Returns true if another thread has called al_join_thread(3) or +al_set_thread_should_stop(3) on this thread. +.SH SEE ALSO +.PP +al_join_thread(3), al_set_thread_should_stop(3). +.RS +.PP +\f[I]Note:\f[R] We don\[cq]t support forceful killing of threads. +.RE diff --git a/allegro/docs/man/al_get_time.3 b/allegro/docs/man/al_get_time.3 new file mode 100644 index 00000000..80def1ae --- /dev/null +++ b/allegro/docs/man/al_get_time.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_time" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_time - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_time(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of seconds since the Allegro library was initialised. +The return value is undefined if Allegro is uninitialised. +The resolution depends on the used driver, but typically can be in the +order of microseconds. diff --git a/allegro/docs/man/al_get_timer_count.3 b/allegro/docs/man/al_get_timer_count.3 new file mode 100644 index 00000000..8e5d3a10 --- /dev/null +++ b/allegro/docs/man/al_get_timer_count.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_timer_count" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_timer_count - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int64_t al_get_timer_count(const ALLEGRO_TIMER *timer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the timer\[cq]s counter value. +The timer can be started or stopped. +.SH SEE ALSO +.PP +al_set_timer_count(3) diff --git a/allegro/docs/man/al_get_timer_event_source.3 b/allegro/docs/man/al_get_timer_event_source.3 new file mode 100644 index 00000000..34e2459d --- /dev/null +++ b/allegro/docs/man/al_get_timer_event_source.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_timer_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_timer_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_timer_event_source(ALLEGRO_TIMER *timer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieve the associated event source. +Timers will generate events of type ALLEGRO_EVENT_TIMER(3). diff --git a/allegro/docs/man/al_get_timer_speed.3 b/allegro/docs/man/al_get_timer_speed.3 new file mode 100644 index 00000000..5fbc1c75 --- /dev/null +++ b/allegro/docs/man/al_get_timer_speed.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_timer_speed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_timer_speed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_timer_speed(const ALLEGRO_TIMER *timer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the timer\[cq]s speed, in seconds. +(The same value passed to al_create_timer(3) or al_set_timer_speed(3).) +.SH SEE ALSO +.PP +al_set_timer_speed(3) diff --git a/allegro/docs/man/al_get_timer_started.3 b/allegro/docs/man/al_get_timer_started.3 new file mode 100644 index 00000000..4f8e9587 --- /dev/null +++ b/allegro/docs/man/al_get_timer_started.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_timer_started" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_timer_started - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_timer_started(const ALLEGRO_TIMER *timer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the timer specified is currently started. diff --git a/allegro/docs/man/al_get_touch_input_event_source.3 b/allegro/docs/man/al_get_touch_input_event_source.3 new file mode 100644 index 00000000..e8045757 --- /dev/null +++ b/allegro/docs/man/al_get_touch_input_event_source.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_touch_input_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_touch_input_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_touch_input_event_source(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the global touch input event source. +This event source generates [touch input +events]ALLEGRO_EVENT_TOUCH_BEGIN(3). +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +ALLEGRO_EVENT_SOURCE(3), al_register_event_source(3) diff --git a/allegro/docs/man/al_get_touch_input_mouse_emulation_event_source.3 b/allegro/docs/man/al_get_touch_input_mouse_emulation_event_source.3 new file mode 100644 index 00000000..adcb1156 --- /dev/null +++ b/allegro/docs/man/al_get_touch_input_mouse_emulation_event_source.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_touch_input_mouse_emulation_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_touch_input_mouse_emulation_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_touch_input_mouse_emulation_event_source(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the global touch input event source for emulated mouse events. +This event source generates [emulated mouse +events]ALLEGRO_EVENT_MOUSE_AXES(3) that are based on touch events. +.SH SEE ALSO +.PP +ALLEGRO_EVENT_SOURCE(3), al_register_event_source(3) +.SH SINCE +.PP +5.1.0 +.RS +.PP +\f[I][Unstable API]:\f[R] Seems of limited value, as touch input tends +to have different semantics compared to mouse input. +.RE diff --git a/allegro/docs/man/al_get_touch_input_state.3 b/allegro/docs/man/al_get_touch_input_state.3 new file mode 100644 index 00000000..47670a1d --- /dev/null +++ b/allegro/docs/man/al_get_touch_input_state.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_touch_input_state" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_touch_input_state - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the current touch input state. +The touch information is copied into the ALLEGRO_TOUCH_INPUT_STATE(3) +you provide to this function. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_get_ustr_dimensions.3 b/allegro/docs/man/al_get_ustr_dimensions.3 new file mode 100644 index 00000000..b864234f --- /dev/null +++ b/allegro/docs/man/al_get_ustr_dimensions.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_ustr_dimensions" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_ustr_dimensions - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_ustr_dimensions(const ALLEGRO_FONT *f, + ALLEGRO_USTR const *ustr, + int *bbx, int *bby, int *bbw, int *bbh) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_get_text_dimensions(3), except the text is passed as an +ALLEGRO_USTR instead of a NUL-terminated char array. +.SH SEE ALSO +.PP +al_get_text_dimensions(3) diff --git a/allegro/docs/man/al_get_ustr_width.3 b/allegro/docs/man/al_get_ustr_width.3 new file mode 100644 index 00000000..0f3ea5ff --- /dev/null +++ b/allegro/docs/man/al_get_ustr_width.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_ustr_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_ustr_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_ustr_width(const ALLEGRO_FONT *f, ALLEGRO_USTR const *ustr) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_get_text_width(3) but expects an ALLEGRO_USTR. +.SH SEE ALSO +.PP +al_get_text_width(3), al_get_ustr_dimensions(3) diff --git a/allegro/docs/man/al_get_vertex_buffer_size.3 b/allegro/docs/man/al_get_vertex_buffer_size.3 new file mode 100644 index 00000000..e539bfe0 --- /dev/null +++ b/allegro/docs/man/al_get_vertex_buffer_size.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_vertex_buffer_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_vertex_buffer_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_get_vertex_buffer_size(ALLEGRO_VERTEX_BUFFER* buffer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the size of the vertex buffer +.SH SINCE +.PP +5.1.8 +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_BUFFER(3) diff --git a/allegro/docs/man/al_get_video_audio_rate.3 b/allegro/docs/man/al_get_video_audio_rate.3 new file mode 100644 index 00000000..15c82b9c --- /dev/null +++ b/allegro/docs/man/al_get_video_audio_rate.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_video_audio_rate" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_video_audio_rate - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_video_audio_rate(ALLEGRO_VIDEO *video) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the audio rate of the video, in Hz. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_get_video_event_source.3 b/allegro/docs/man/al_get_video_event_source.3 new file mode 100644 index 00000000..f05f480f --- /dev/null +++ b/allegro/docs/man/al_get_video_event_source.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_video_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_video_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_EVENT_SOURCE *al_get_video_event_source(ALLEGRO_VIDEO *video) +\f[R] +.fi +.SH DESCRIPTION +.PP +Get an event source for the video. +The possible events are described under ALLEGRO_VIDEO_EVENT_TYPE(3). +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_get_video_fps.3 b/allegro/docs/man/al_get_video_fps.3 new file mode 100644 index 00000000..3e2cd9a0 --- /dev/null +++ b/allegro/docs/man/al_get_video_fps.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_video_fps" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_video_fps - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_video_fps(ALLEGRO_VIDEO *video) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the speed of the video in frames per second. +Often this will not be an integer value. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_get_video_frame.3 b/allegro/docs/man/al_get_video_frame.3 new file mode 100644 index 00000000..7479a400 --- /dev/null +++ b/allegro/docs/man/al_get_video_frame.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_video_frame" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_video_frame - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_get_video_frame(ALLEGRO_VIDEO *video) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the current video frame. +The bitmap is owned by the video so do not attempt to free it. +The bitmap will stay valid until the next call to al_get_video_frame. +.PP +Videos often do not use square pixels so the recommended way to draw a +video frame would be using code like this: +.IP +.nf +\f[C] +float scale = 1.0; /* Adjust this to fit your target bitmap dimensions. */ +ALLEGRO_BITMAP* frame = al_get_video_frame(video); +float sw = al_get_bitmap_width(frame); +float sh = al_get_bitmap_height(frame); +float dw = scale * al_get_video_scaled_width(video); +float dh = scale * al_get_video_scaled_height(video); +al_draw_scaled_bitmap(frame, 0, 0, sw, sh, 0, 0, dw, dh, 0); +\f[R] +.fi +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_get_video_scaled_width(3), al_get_video_scaled_height(3) diff --git a/allegro/docs/man/al_get_video_position.3 b/allegro/docs/man/al_get_video_position.3 new file mode 100644 index 00000000..049661f7 --- /dev/null +++ b/allegro/docs/man/al_get_video_position.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_video_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_video_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +double al_get_video_position(ALLEGRO_VIDEO *video, ALLEGRO_VIDEO_POSITION_TYPE which) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the current position of the video stream in seconds since the +beginning. +The parameter is one of the ALLEGRO_VIDEO_POSITION_TYPE(3) constants. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_get_video_scaled_height.3 b/allegro/docs/man/al_get_video_scaled_height.3 new file mode 100644 index 00000000..7477967a --- /dev/null +++ b/allegro/docs/man/al_get_video_scaled_height.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_video_scaled_height" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_video_scaled_height - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_video_scaled_height(ALLEGRO_VIDEO *video) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the height with which the video frame should be drawn. +Videos often do not use square pixels, so this will may return a value +larger than the height of the frame bitmap. +.SH SEE ALSO +.PP +al_get_video_frame(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_get_video_scaled_width.3 b/allegro/docs/man/al_get_video_scaled_width.3 new file mode 100644 index 00000000..94d8cd68 --- /dev/null +++ b/allegro/docs/man/al_get_video_scaled_width.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_video_scaled_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_video_scaled_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +float al_get_video_scaled_width(ALLEGRO_VIDEO *video) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the width with which the video frame should be drawn. +Videos often do not use square pixels, so this will may return a value +larger than the width of the frame bitmap. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_get_video_frame(3) diff --git a/allegro/docs/man/al_get_voice_channels.3 b/allegro/docs/man/al_get_voice_channels.3 new file mode 100644 index 00000000..f0e46ee1 --- /dev/null +++ b/allegro/docs/man/al_get_voice_channels.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_voice_channels" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_voice_channels - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CHANNEL_CONF al_get_voice_channels(const ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the channel configuration of the voice. +.SH SEE ALSO +.PP +ALLEGRO_CHANNEL_CONF(3). diff --git a/allegro/docs/man/al_get_voice_depth.3 b/allegro/docs/man/al_get_voice_depth.3 new file mode 100644 index 00000000..78c48979 --- /dev/null +++ b/allegro/docs/man/al_get_voice_depth.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_voice_depth" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_voice_depth - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_DEPTH al_get_voice_depth(const ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the audio depth of the voice. +.SH SEE ALSO +.PP +ALLEGRO_AUDIO_DEPTH(3). diff --git a/allegro/docs/man/al_get_voice_frequency.3 b/allegro/docs/man/al_get_voice_frequency.3 new file mode 100644 index 00000000..a51e5a66 --- /dev/null +++ b/allegro/docs/man/al_get_voice_frequency.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_voice_frequency" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_voice_frequency - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_voice_frequency(const ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the frequency of the voice (in Hz), e.g.\ 44100. diff --git a/allegro/docs/man/al_get_voice_playing.3 b/allegro/docs/man/al_get_voice_playing.3 new file mode 100644 index 00000000..94c300cd --- /dev/null +++ b/allegro/docs/man/al_get_voice_playing.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_voice_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_voice_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_voice_playing(const ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the voice is currently playing. +.SH SEE ALSO +.PP +al_set_voice_playing(3) diff --git a/allegro/docs/man/al_get_voice_position.3 b/allegro/docs/man/al_get_voice_position.3 new file mode 100644 index 00000000..59d37aae --- /dev/null +++ b/allegro/docs/man/al_get_voice_position.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_voice_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_voice_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +unsigned int al_get_voice_position(const ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +When the voice has a non-streaming object attached to it, e.g.\ a +sample, returns the voice\[cq]s current sample position. +Otherwise, returns zero. +.SH SEE ALSO +.PP +al_set_voice_position(3). diff --git a/allegro/docs/man/al_get_win_window_handle.3 b/allegro/docs/man/al_get_win_window_handle.3 new file mode 100644 index 00000000..88075411 --- /dev/null +++ b/allegro/docs/man/al_get_win_window_handle.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_win_window_handle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_win_window_handle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +HWND al_get_win_window_handle(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the handle to the window that the passed display is using. diff --git a/allegro/docs/man/al_get_window_constraints.3 b/allegro/docs/man/al_get_window_constraints.3 new file mode 100644 index 00000000..c82415da --- /dev/null +++ b/allegro/docs/man/al_get_window_constraints.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_window_constraints" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_window_constraints - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_get_window_constraints(ALLEGRO_DISPLAY *display, + int *min_w, int *min_h, int *max_w, int *max_h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the constraints for a non-fullscreen resizable display. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_set_window_constraints(3) diff --git a/allegro/docs/man/al_get_window_position.3 b/allegro/docs/man/al_get_window_position.3 new file mode 100644 index 00000000..d97e46b3 --- /dev/null +++ b/allegro/docs/man/al_get_window_position.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_window_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_window_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Gets the position of a non-fullscreen display. +.SH SEE ALSO +.PP +al_set_window_position(3) diff --git a/allegro/docs/man/al_get_x_window_id.3 b/allegro/docs/man/al_get_x_window_id.3 new file mode 100644 index 00000000..ad17d217 --- /dev/null +++ b/allegro/docs/man/al_get_x_window_id.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_get_x_window_id" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_get_x_window_id - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +XID al_get_x_window_id(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves the XID associated with the Allegro display. +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_grab_font_from_bitmap.3 b/allegro/docs/man/al_grab_font_from_bitmap.3 new file mode 100644 index 00000000..d037be5c --- /dev/null +++ b/allegro/docs/man/al_grab_font_from_bitmap.3 @@ -0,0 +1,92 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_grab_font_from_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_grab_font_from_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_grab_font_from_bitmap(ALLEGRO_BITMAP *bmp, + int ranges_n, const int ranges[]) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a new font from an Allegro bitmap. +You can delete the bitmap after the function returns as the font will +contain a copy for itself. +.PP +Parameters: +.IP \[bu] 2 +bmp: The bitmap with the glyphs drawn onto it +.IP \[bu] 2 +n: Number of unicode ranges in the bitmap. +.IP \[bu] 2 +ranges: `n' pairs of first and last unicode point to map glyphs to for +each range. +.PP +The bitmap format is as in the following example, which contains three +glyphs for 1, 2 and 3. +.IP +.nf +\f[C] +\&............. +\&. 1 .222.333. +\&. 1 . 2. 3. +\&. 1 .222.333. +\&. 1 .2 . 3. +\&. 1 .222.333. +\&............. +\f[R] +.fi +.PP +In the above illustration, the dot is for pixels having the background +color. +It is determined by the color of the top left pixel in the bitmap. +There should be a border of at least 1 pixel with this color to the +bitmap edge and between all glyphs. +.PP +Each glyph is inside a rectangle of pixels not containing the background +color. +The height of all glyph rectangles should be the same, but the width can +vary. +.PP +The placement of the rectangles does not matter, except that glyphs are +scanned from left to right and top to bottom to match them to the +specified unicode codepoints. +.PP +The glyphs will simply be drawn using al_draw_bitmap(3), so usually you +will want the rectangles filled with full transparency and the glyphs +drawn in opaque white. +.PP +Examples: +.IP +.nf +\f[C] +int ranges[] = {32, 126}; +al_grab_font_from_bitmap(bitmap, 1, ranges) + +int ranges[] = { + 0x0020, 0x007F, /* ASCII */ + 0x00A1, 0x00FF, /* Latin 1 */ + 0x0100, 0x017F, /* Extended-A */ + 0x20AC, 0x20AC}; /* Euro */ +al_grab_font_from_bitmap(bitmap, 4, ranges) +\f[R] +.fi +.PP +The first example will grab glyphs for the 95 standard printable ASCII +characters, beginning with the space character (32) and ending with the +tilde character (126). +The second example will map the first 96 glyphs found in the bitmap to +ASCII range, the next 95 glyphs to Latin 1, the next 128 glyphs to +Extended-A, and the last glyph to the Euro character. +(This is just the characters found in the Allegro 4 font.) +.SH SEE ALSO +.PP +al_load_bitmap(3), al_grab_font_from_bitmap(3) diff --git a/allegro/docs/man/al_grab_mouse.3 b/allegro/docs/man/al_grab_mouse.3 new file mode 100644 index 00000000..7b06936b --- /dev/null +++ b/allegro/docs/man/al_grab_mouse.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_grab_mouse" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_grab_mouse - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_grab_mouse(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Confine the mouse cursor to the given display. +The mouse cursor can only be confined to one display at a time. +.PP +Returns true if successful, otherwise returns false. +Do not assume that the cursor will remain confined until you call +al_ungrab_mouse(3). +It may lose the confined status at any time for other reasons. +.RS +.PP +\f[I]Note:\f[R] not yet implemented on Mac OS X. +.RE +.SH SEE ALSO +.PP +al_ungrab_mouse(3) diff --git a/allegro/docs/man/al_have_d3d_non_pow2_texture_support.3 b/allegro/docs/man/al_have_d3d_non_pow2_texture_support.3 new file mode 100644 index 00000000..b47cd965 --- /dev/null +++ b/allegro/docs/man/al_have_d3d_non_pow2_texture_support.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_have_d3d_non_pow2_texture_support" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_have_d3d_non_pow2_texture_support - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_have_d3d_non_pow2_texture_support(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns whether the Direct3D device supports textures whose dimensions +are not powers of two. +.PP +\f[I]Returns:\f[R] True if device supports NPOT textures, false +otherwise. diff --git a/allegro/docs/man/al_have_d3d_non_square_texture_support.3 b/allegro/docs/man/al_have_d3d_non_square_texture_support.3 new file mode 100644 index 00000000..b5651190 --- /dev/null +++ b/allegro/docs/man/al_have_d3d_non_square_texture_support.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_have_d3d_non_square_texture_support" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_have_d3d_non_square_texture_support - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_have_d3d_non_square_texture_support(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns whether the Direct3D device supports textures that are not +square. +.PP +\f[I]Returns:\f[R] True if the Direct3D device supports non-square +textures, false otherwise. diff --git a/allegro/docs/man/al_have_opengl_extension.3 b/allegro/docs/man/al_have_opengl_extension.3 new file mode 100644 index 00000000..a34be97f --- /dev/null +++ b/allegro/docs/man/al_have_opengl_extension.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_have_opengl_extension" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_have_opengl_extension - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_have_opengl_extension(const char *extension) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function is a helper to determine whether an OpenGL extension is +available on the given display or not. +.PP +Example: +.IP +.nf +\f[C] +bool packedpixels = al_have_opengl_extension(\[dq]GL_EXT_packed_pixels\[dq]); +\f[R] +.fi +.PP +If \f[I]packedpixels\f[R] is true then you can safely use the constants +related to the packed pixels extension. +.PP +Returns true if the extension is available; false otherwise. diff --git a/allegro/docs/man/al_hide_mouse_cursor.3 b/allegro/docs/man/al_hide_mouse_cursor.3 new file mode 100644 index 00000000..fbaa8059 --- /dev/null +++ b/allegro/docs/man/al_hide_mouse_cursor.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_hide_mouse_cursor" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_hide_mouse_cursor - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_hide_mouse_cursor(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Hide the mouse cursor in the given display. +This has no effect on what the current mouse cursor looks like; it just +makes it disappear. +.PP +Returns true on success (or if the cursor already was hidden), false +otherwise. +.SH SEE ALSO +.PP +al_show_mouse_cursor(3) diff --git a/allegro/docs/man/al_hold_bitmap_drawing.3 b/allegro/docs/man/al_hold_bitmap_drawing.3 new file mode 100644 index 00000000..d75a4321 --- /dev/null +++ b/allegro/docs/man/al_hold_bitmap_drawing.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_hold_bitmap_drawing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_hold_bitmap_drawing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_hold_bitmap_drawing(bool hold) +\f[R] +.fi +.SH DESCRIPTION +.PP +Enables or disables deferred bitmap drawing. +This allows for efficient drawing of many bitmaps that share a parent +bitmap, such as sub-bitmaps from a tilesheet or simply identical +bitmaps. +Drawing bitmaps that do not share a parent is less efficient, so it is +advisable to stagger bitmap drawing calls such that the parent bitmap is +the same for large number of those calls. +While deferred bitmap drawing is enabled, the only functions that can be +used are the bitmap drawing functions and font drawing functions. +Changing the state such as the blending modes will result in undefined +behaviour. +One exception to this rule are the non-projection transformations. +It is possible to set a new transformation while the drawing is held. +.PP +No drawing is guaranteed to take place until you disable the hold. +Thus, the idiom of this function\[cq]s usage is to enable the deferred +bitmap drawing, draw as many bitmaps as possible, taking care to stagger +bitmaps that share parent bitmaps, and then disable deferred drawing. +As mentioned above, this function also works with bitmap and truetype +fonts, so if multiple lines of text need to be drawn, this function can +speed things up. +.SH SEE ALSO +.PP +al_is_bitmap_drawing_held(3) diff --git a/allegro/docs/man/al_horizontal_shear_transform.3 b/allegro/docs/man/al_horizontal_shear_transform.3 new file mode 100644 index 00000000..99cd0b01 --- /dev/null +++ b/allegro/docs/man/al_horizontal_shear_transform.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_horizontal_shear_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_horizontal_shear_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_horizontal_shear_transform(ALLEGRO_TRANSFORM* trans, float theta) +\f[R] +.fi +.SH DESCRIPTION +.PP +Apply a horizontal shear to the transform +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to alter +.IP \[bu] 2 +theta - Rotation angle in radians +.SH SINCE +.PP +5.1.7 +.SH SEE ALSO +.PP +al_vertical_shear_transform(3) diff --git a/allegro/docs/man/al_identify_bitmap.3 b/allegro/docs/man/al_identify_bitmap.3 new file mode 100644 index 00000000..1868ba02 --- /dev/null +++ b/allegro/docs/man/al_identify_bitmap.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_identify_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_identify_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char const *al_identify_bitmap(char const *filename) +\f[R] +.fi +.SH DESCRIPTION +.PP +This works exactly as al_identify_bitmap_f(3) but you specify the +filename of the file for which to detect the type and not a file handle. +The extension, if any, of the passed filename is not taken into account +- only the file contents. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_init_image_addon(3), al_identify_bitmap_f(3), +al_register_bitmap_identifier(3) diff --git a/allegro/docs/man/al_identify_bitmap_f.3 b/allegro/docs/man/al_identify_bitmap_f.3 new file mode 100644 index 00000000..99596701 --- /dev/null +++ b/allegro/docs/man/al_identify_bitmap_f.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_identify_bitmap_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_identify_bitmap_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +char const *al_identify_bitmap_f(ALLEGRO_FILE *fp) +\f[R] +.fi +.SH DESCRIPTION +.PP +Tries to guess the bitmap file type of the open ALLEGRO_FILE by reading +the first few bytes. +By default Allegro cannot recognize any file types, but calling +al_init_image_addon(3) will add detection of (some of) the types it can +read. +You can also use al_register_bitmap_identifier(3) to add identification +for custom file types. +.PP +Returns a pointer to a static string with a file extension for the type, +including the leading dot. +For example \[lq].png\[rq] or \[lq].jpg\[rq]. +Returns NULL if the bitmap type cannot be determined. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_init_image_addon(3), al_identify_bitmap(3), +al_register_bitmap_identifier(3) diff --git a/allegro/docs/man/al_identity_transform.3 b/allegro/docs/man/al_identity_transform.3 new file mode 100644 index 00000000..8d61cfa9 --- /dev/null +++ b/allegro/docs/man/al_identity_transform.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_identity_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_identity_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_identity_transform(ALLEGRO_TRANSFORM *trans) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the transformation to be the identity transformation. +This is the default transformation. +Use al_use_transform(3) on an identity transformation to return to the +default. +.IP +.nf +\f[C] +ALLEGRO_TRANSFORM t; +al_identity_transform(&t); +al_use_transform(&t); +\f[R] +.fi +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to alter +.SH SEE ALSO +.PP +al_translate_transform(3), al_rotate_transform(3), al_scale_transform(3) diff --git a/allegro/docs/man/al_inhibit_screensaver.3 b/allegro/docs/man/al_inhibit_screensaver.3 new file mode 100644 index 00000000..3b6c2169 --- /dev/null +++ b/allegro/docs/man/al_inhibit_screensaver.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_inhibit_screensaver" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_inhibit_screensaver - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_inhibit_screensaver(bool inhibit) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function allows the user to stop the system screensaver from +starting up if true is passed, or resets the system back to the default +state (the state at program start) if false is passed. +It returns true if the state was set successfully, otherwise false. diff --git a/allegro/docs/man/al_init.3 b/allegro/docs/man/al_init.3 new file mode 100644 index 00000000..e38427ec --- /dev/null +++ b/allegro/docs/man/al_init.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define al_init() (al_install_system(ALLEGRO_VERSION_INT, atexit)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_install_system(3), but automatically passes in the version and +uses the atexit function visible in the current binary. +.RS +.PP +Note: It is typically wrong to call al_init anywhere except the final +game binary. +In particular, do not call it inside a shared library unless you know +what you\[cq]re doing. +In those cases, it is better to call al_install_system either with a +\f[C]NULL\f[R] atexit_ptr, or with a pointer to atexit provided by the +user of this shared library. +.RE +.SH SEE ALSO +.PP +al_install_system(3) diff --git a/allegro/docs/man/al_init_acodec_addon.3 b/allegro/docs/man/al_init_acodec_addon.3 new file mode 100644 index 00000000..4f05c526 --- /dev/null +++ b/allegro/docs/man/al_init_acodec_addon.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_acodec_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_acodec_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_init_acodec_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function registers all the known audio file type handlers for +al_load_sample(3), al_save_sample(3), al_load_audio_stream(3), etc. +.PP +Depending on what libraries are available, the full set of recognised +extensions is: .wav, .flac, .ogg, .opus, .it, .mod, .s3m, .xm, .voc. +.PP +\f[I]Limitations:\f[R] +.IP \[bu] 2 +Saving is only supported for wav files. +.IP \[bu] 2 +The wav file loader currently only supports 8/16 bit little endian PCM +files. +16 bits are used when saving wav files. +Use flac files if more precision is required. +.IP \[bu] 2 +Module files (.it, .mod, .s3m, .xm) are often composed with streaming in +mind, and sometimes cannot be easily rendered into a finite length +sample. +Therefore they cannot be loaded with +al_load_sample(3)/al_load_sample_f(3) and must be streamed with +al_load_audio_stream(3) or al_load_audio_stream_f(3). +.IP \[bu] 2 +\&.voc file streaming is unimplemented. +.PP +Return true on success. diff --git a/allegro/docs/man/al_init_font_addon.3 b/allegro/docs/man/al_init_font_addon.3 new file mode 100644 index 00000000..68685954 --- /dev/null +++ b/allegro/docs/man/al_init_font_addon.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_font_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_font_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_init_font_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Initialise the font addon. +.PP +Note that if you intend to load bitmap fonts, you will need to +initialise allegro_image separately (unless you are using another +library to load images). +.PP +Similarly, if you wish to load truetype-fonts, do not forget to also +call al_init_ttf_addon(3). +.PP +Returns true on success, false on failure. +On the 5.0 branch, this function has no return value. +You may wish to avoid checking the return value if your code needs to be +compatible with Allegro 5.0. +Currently, the function will never return false. +.SH SEE ALSO +.PP +al_init_image_addon(3), al_init_ttf_addon(3), al_shutdown_font_addon(3) diff --git a/allegro/docs/man/al_init_image_addon.3 b/allegro/docs/man/al_init_image_addon.3 new file mode 100644 index 00000000..030fbdfe --- /dev/null +++ b/allegro/docs/man/al_init_image_addon.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_image_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_image_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_init_image_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Initializes the image addon. +This registers bitmap format handlers for al_load_bitmap(3), +al_load_bitmap_f(3), al_save_bitmap(3), al_save_bitmap_f(3). +.PP +The following types are built into the Allegro image addon and +guaranteed to be available: BMP, DDS, PCX, TGA. +Every platform also supports JPEG and PNG via external dependencies. +.PP +Other formats may be available depending on the operating system and +installed libraries, but are not guaranteed and should not be assumed to +be universally available. +.PP +The DDS format is only supported to load from, and only if the DDS file +contains textures compressed in the DXT1, DXT3 and DXT5 formats. +Note that when loading a DDS file, the created bitmap will always be a +video bitmap and will have the pixel format matching the format in the +file. diff --git a/allegro/docs/man/al_init_native_dialog_addon.3 b/allegro/docs/man/al_init_native_dialog_addon.3 new file mode 100644 index 00000000..2f3215a4 --- /dev/null +++ b/allegro/docs/man/al_init_native_dialog_addon.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_native_dialog_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_native_dialog_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_init_native_dialog_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Initialise the native dialog addon. +.PP +Returns true on success, false on error. +.SH SINCE +.PP +5.0.9, 5.1.0 +.RS +.PP +\f[I]Note:\f[R] Prior to Allegro 5.1.0 native dialog functions could be +called without explicit initialisation, but that is now deprecated. +Future functionality may require explicit initialisation. +An exception is al_show_native_message_box(3), which may be useful to +show an error message if Allegro fails to initialise. +.RE +.SH SEE ALSO +.PP +al_shutdown_native_dialog_addon(3) diff --git a/allegro/docs/man/al_init_primitives_addon.3 b/allegro/docs/man/al_init_primitives_addon.3 new file mode 100644 index 00000000..a0548a9e --- /dev/null +++ b/allegro/docs/man/al_init_primitives_addon.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_primitives_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_primitives_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_init_primitives_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Initializes the primitives addon. +.PP +\f[I]Returns:\f[R] True on success, false on failure. +.SH SEE ALSO +.PP +al_shutdown_primitives_addon(3) diff --git a/allegro/docs/man/al_init_timeout.3 b/allegro/docs/man/al_init_timeout.3 new file mode 100644 index 00000000..945fded0 --- /dev/null +++ b/allegro/docs/man/al_init_timeout.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_timeout" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_timeout - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set timeout value of some number of seconds after the function call. +.PP +For compatibility with all platforms, \f[C]seconds\f[R] must be +2,147,483.647 seconds or less. +.SH SEE ALSO +.PP +ALLEGRO_TIMEOUT(3), al_wait_for_event_until(3) diff --git a/allegro/docs/man/al_init_ttf_addon.3 b/allegro/docs/man/al_init_ttf_addon.3 new file mode 100644 index 00000000..cb32f1e8 --- /dev/null +++ b/allegro/docs/man/al_init_ttf_addon.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_ttf_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_ttf_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_init_ttf_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Call this after al_init_font_addon(3) to make al_load_font(3) recognize +\[lq].ttf\[rq] and other formats supported by al_load_ttf_font(3). +.PP +Returns true on success, false on failure. diff --git a/allegro/docs/man/al_init_user_event_source.3 b/allegro/docs/man/al_init_user_event_source.3 new file mode 100644 index 00000000..31368cea --- /dev/null +++ b/allegro/docs/man/al_init_user_event_source.3 @@ -0,0 +1,65 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_user_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_user_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_init_user_event_source(ALLEGRO_EVENT_SOURCE *src) +\f[R] +.fi +.SH DESCRIPTION +.PP +Initialise an event source for emitting user events. +The space for the event source must already have been allocated. +.PP +One possible way of creating custom event sources is to derive other +structures with ALLEGRO_EVENT_SOURCE at the head, e.g. +.IP +.nf +\f[C] +typedef struct THING THING; + +struct THING { + ALLEGRO_EVENT_SOURCE event_source; + int field1; + int field2; + /* etc. */ +}; + +THING *create_thing(void) +{ + THING *thing = malloc(sizeof(THING)); + + if (thing) { + al_init_user_event_source(&thing->event_source); + thing->field1 = 0; + thing->field2 = 0; + } + + return thing; +} +\f[R] +.fi +.PP +The advantage here is that the THING pointer will be the same as the +ALLEGRO_EVENT_SOURCE pointer. +Events emitted by the event source will have the event source pointer as +the \f[C]source\f[R] field, from which you can get a pointer to a THING +by a simple cast (after ensuring checking the event is of the correct +type). +.PP +However, it is only one technique and you are not obliged to use it. +.PP +The user event source will never be destroyed automatically. +You must destroy it manually with al_destroy_user_event_source(3). +.SH SEE ALSO +.PP +ALLEGRO_EVENT_SOURCE(3), al_destroy_user_event_source(3), +al_emit_user_event(3), ALLEGRO_USER_EVENT(3) diff --git a/allegro/docs/man/al_init_video_addon.3 b/allegro/docs/man/al_init_video_addon.3 new file mode 100644 index 00000000..61144d50 --- /dev/null +++ b/allegro/docs/man/al_init_video_addon.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_init_video_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_init_video_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_init_video_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Initializes the video addon. +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_insert_menu_item.3 b/allegro/docs/man/al_insert_menu_item.3 new file mode 100644 index 00000000..57dd4f51 --- /dev/null +++ b/allegro/docs/man/al_insert_menu_item.3 @@ -0,0 +1,55 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_insert_menu_item" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_insert_menu_item - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_insert_menu_item(ALLEGRO_MENU *parent, int pos, char const *title, + uint16_t id, int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu) +\f[R] +.fi +.SH DESCRIPTION +.PP +Inserts a menu item at the spot specified. +See the introductory text for a detailed explanation of how the +\f[C]pos\f[R] parameter is interpreted. +.PP +The \f[C]parent\f[R] menu can be a popup menu or a regular menu. +To underline one character in the \f[C]title\f[R], prefix it with an +ampersand. +.PP +The \f[C]flags\f[R] can be any combination of: +.TP +ALLEGRO_MENU_ITEM_DISABLED +The item is \[lq]grayed out\[rq] and cannot be selected. +.TP +ALLEGRO_MENU_ITEM_CHECKBOX +The item is a check box. +This flag can only be set at the time the menu is created. +If a check box is clicked, it will automatically be toggled. +.TP +ALLEGRO_MENU_ITEM_CHECKED +The item is checked. +If set, ALLEGRO_MENU_ITEM_CHECKBOX will automatically be set as well. +.PP +The \f[C]icon\f[R] is not yet supported. +.PP +The \f[C]submenu\f[R] parameter indicates that this item contains a +child menu. +The child menu must have previously been created with +\f[C]al_create_menu\f[R], and not be associated with any other menu. +.PP +Returns \f[C]true\f[R] on success. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_append_menu_item(3), al_remove_menu_item(3) diff --git a/allegro/docs/man/al_insert_path_component.3 b/allegro/docs/man/al_insert_path_component.3 new file mode 100644 index 00000000..6aed8c80 --- /dev/null +++ b/allegro/docs/man/al_insert_path_component.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_insert_path_component" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_insert_path_component - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_insert_path_component(ALLEGRO_PATH *path, int i, const char *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Insert a directory component at index i. +If the index is negative then count from the right, i.e.\ -1 refers to +the last path component. +.PP +It is an error to pass an index i which is not within these bounds: 0 <= +i <= al_get_path_num_components(path). +.SH SEE ALSO +.PP +al_append_path_component(3), al_replace_path_component(3), +al_remove_path_component(3) diff --git a/allegro/docs/man/al_install_audio.3 b/allegro/docs/man/al_install_audio.3 new file mode 100644 index 00000000..a0d7f2be --- /dev/null +++ b/allegro/docs/man/al_install_audio.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_install_audio" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_install_audio - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_install_audio(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Install the audio subsystem. +.PP +Returns true on success, false on failure. +.RS +.PP +Note: most users will call al_reserve_samples(3) and +al_init_acodec_addon(3) after this. +.RE +.SH SEE ALSO +.PP +al_reserve_samples(3), al_uninstall_audio(3), al_is_audio_installed(3), +al_init_acodec_addon(3) diff --git a/allegro/docs/man/al_install_haptic.3 b/allegro/docs/man/al_install_haptic.3 new file mode 100644 index 00000000..43cc9329 --- /dev/null +++ b/allegro/docs/man/al_install_haptic.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_install_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_install_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_install_haptic(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Installs the haptic (force feedback) device subsystem. +This must be called before using any other haptic-related functions. +Returns true if the haptics subsystem could be initialized correctly, +false in case of error. +.PP +For portability you should first open a display before calling +al_install_haptic(3). +On some platforms, such as DirectInput under Windows, +al_install_haptic(3) will only work if at least one active display is +available. +This display must stay available until al_uninstall_haptic(3) is called. +.PP +If you need to close and reopen your active display for example, then +you should call al_uninstall_haptic(3) before closing the display, and +al_install_haptic(3) after opening it again. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_install_joystick.3 b/allegro/docs/man/al_install_joystick.3 new file mode 100644 index 00000000..40720084 --- /dev/null +++ b/allegro/docs/man/al_install_joystick.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_install_joystick" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_install_joystick - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_install_joystick(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Install a joystick driver, returning true if successful. +If a joystick driver was already installed, returns true immediately. +.SH SEE ALSO +.PP +al_uninstall_joystick(3) diff --git a/allegro/docs/man/al_install_keyboard.3 b/allegro/docs/man/al_install_keyboard.3 new file mode 100644 index 00000000..98088d4f --- /dev/null +++ b/allegro/docs/man/al_install_keyboard.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_install_keyboard" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_install_keyboard - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_install_keyboard(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Install a keyboard driver. +Returns true if successful. +If a driver was already installed, nothing happens and true is returned. +.SH SEE ALSO +.PP +al_uninstall_keyboard(3), al_is_keyboard_installed(3) diff --git a/allegro/docs/man/al_install_mouse.3 b/allegro/docs/man/al_install_mouse.3 new file mode 100644 index 00000000..1d0ed9b2 --- /dev/null +++ b/allegro/docs/man/al_install_mouse.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_install_mouse" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_install_mouse - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_install_mouse(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Install a mouse driver. +.PP +Returns true if successful. +If a driver was already installed, nothing happens and true is returned. diff --git a/allegro/docs/man/al_install_system.3 b/allegro/docs/man/al_install_system.3 new file mode 100644 index 00000000..1495dc2a --- /dev/null +++ b/allegro/docs/man/al_install_system.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_install_system" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_install_system - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_install_system(int version, int (*atexit_ptr)(void (*)(void))) +\f[R] +.fi +.SH DESCRIPTION +.PP +Initialize the Allegro system. +No other Allegro functions can be called before this (with one or two +exceptions). +.PP +The version field should always be set to ALLEGRO_VERSION_INT. +.PP +If atexit_ptr is non-NULL, and if hasn\[cq]t been done already, +al_uninstall_system(3) will be registered as an atexit function. +.PP +Returns true if Allegro was successfully initialized by this function +call (or already was initialized previously), false if Allegro cannot be +used. +A common reason for this function to fail is when the version of Allegro +you compiled your game against is not compatible with the version of the +shared libraries that were found on the system. +.PP +The version compatibility check works as follows. +Let A = xa.ya.za.* be the version of Allegro you compiled with, and B = +xb.yb.zb.* be the version of Allegro found in the system shared library. +.PP +If you defined \f[C]ALLEGRO_UNSTABLE\f[R] before including Allegro +headers, then version A is compatible with B only if xa.ya.za = +xb.yb.zb. +Otherwise, A is compatible with B only if xa.ya = xb.yb. +.SH SEE ALSO +.PP +al_init(3) diff --git a/allegro/docs/man/al_install_touch_input.3 b/allegro/docs/man/al_install_touch_input.3 new file mode 100644 index 00000000..84057d98 --- /dev/null +++ b/allegro/docs/man/al_install_touch_input.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_install_touch_input" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_install_touch_input - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_install_touch_input(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Install a touch input driver, returning true if successful. +If a touch input driver was already installed, returns true immediately. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_uninstall_touch_input(3) diff --git a/allegro/docs/man/al_invert_transform.3 b/allegro/docs/man/al_invert_transform.3 new file mode 100644 index 00000000..e05bf2f0 --- /dev/null +++ b/allegro/docs/man/al_invert_transform.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_invert_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_invert_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_invert_transform(ALLEGRO_TRANSFORM *trans) +\f[R] +.fi +.SH DESCRIPTION +.PP +Inverts the passed transformation. +If the transformation is nearly singular (close to not having an +inverse) then the returned transformation may be invalid. +Use al_check_inverse(3) to ascertain if the transformation has an +inverse before inverting it if you are in doubt. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to invert +.RS +.PP +\f[I]Note\f[R]: Allegro\[cq]s transformation inversion functions work +correctly only with 2D transformations. +.RE +.SH SEE ALSO +.PP +al_check_inverse(3) diff --git a/allegro/docs/man/al_iphone_get_view.3 b/allegro/docs/man/al_iphone_get_view.3 new file mode 100644 index 00000000..b16ce57f --- /dev/null +++ b/allegro/docs/man/al_iphone_get_view.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_iphone_get_view" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_iphone_get_view - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +UIView *al_iphone_get_view(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves the UIView* (EAGLView*) associated with the Allegro display. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_iphone_get_window.3 b/allegro/docs/man/al_iphone_get_window.3 new file mode 100644 index 00000000..e8e920d9 --- /dev/null +++ b/allegro/docs/man/al_iphone_get_window.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_iphone_get_window" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_iphone_get_window - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +UIWindow *al_iphone_get_window(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves the UIWindow* associated with the Allegro display. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_iphone_set_statusbar_orientation.3 b/allegro/docs/man/al_iphone_set_statusbar_orientation.3 new file mode 100644 index 00000000..681d1bc4 --- /dev/null +++ b/allegro/docs/man/al_iphone_set_statusbar_orientation.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_iphone_set_statusbar_orientation" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_iphone_set_statusbar_orientation - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_iphone_set_statusbar_orientation(int o) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the orientation of the status bar, which can be one of the +following: +.IP \[bu] 2 +ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT +.IP \[bu] 2 +ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT_UPSIDE_DOWN +.IP \[bu] 2 +ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_RIGHT +.IP \[bu] 2 +ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_LEFT +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_is_acodec_addon_initialized.3 b/allegro/docs/man/al_is_acodec_addon_initialized.3 new file mode 100644 index 00000000..e13bd131 --- /dev/null +++ b/allegro/docs/man/al_is_acodec_addon_initialized.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_acodec_addon_initialized" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_acodec_addon_initialized - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_acodec_addon_initialized(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the acodec addon is initialized, otherwise returns +false. +.SH SINCE +.PP +5.2.6 diff --git a/allegro/docs/man/al_is_audio_installed.3 b/allegro/docs/man/al_is_audio_installed.3 new file mode 100644 index 00000000..ef309695 --- /dev/null +++ b/allegro/docs/man/al_is_audio_installed.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_audio_installed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_audio_installed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_audio_installed(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if al_install_audio(3) was called previously and returned +successfully. diff --git a/allegro/docs/man/al_is_audio_recorder_recording.3 b/allegro/docs/man/al_is_audio_recorder_recording.3 new file mode 100644 index 00000000..26a95517 --- /dev/null +++ b/allegro/docs/man/al_is_audio_recorder_recording.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_audio_recorder_recording" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_audio_recorder_recording - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_audio_recorder_recording(ALLEGRO_AUDIO_RECORDER *r) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the audio recorder is currently capturing data and +generating events. +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/al_is_bitmap_drawing_held.3 b/allegro/docs/man/al_is_bitmap_drawing_held.3 new file mode 100644 index 00000000..9ff5e644 --- /dev/null +++ b/allegro/docs/man/al_is_bitmap_drawing_held.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_bitmap_drawing_held" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_bitmap_drawing_held - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_bitmap_drawing_held(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns whether the deferred bitmap drawing mode is turned on or off. +.SH SEE ALSO +.PP +al_hold_bitmap_drawing(3) diff --git a/allegro/docs/man/al_is_bitmap_locked.3 b/allegro/docs/man/al_is_bitmap_locked.3 new file mode 100644 index 00000000..ae4b4867 --- /dev/null +++ b/allegro/docs/man/al_is_bitmap_locked.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_bitmap_locked" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_bitmap_locked - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_bitmap_locked(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns whether or not a bitmap is already locked. +.SH SEE ALSO +.PP +al_lock_bitmap(3), al_lock_bitmap_region(3), al_unlock_bitmap(3) diff --git a/allegro/docs/man/al_is_color_valid.3 b/allegro/docs/man/al_is_color_valid.3 new file mode 100644 index 00000000..47f68670 --- /dev/null +++ b/allegro/docs/man/al_is_color_valid.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_color_valid" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_color_valid - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include +\f[R] +.fi +.SH DESCRIPTION +.PP +Checks if all components of the color are between 0 and 1. +Some of the color conversions in this addon support color spaces with +more colors than can be represented in sRGB and when converted to RGB +will result in invalid color components outside the 0..1 range. +.SH SINCE +.PP +5.2.3 diff --git a/allegro/docs/man/al_is_compatible_bitmap.3 b/allegro/docs/man/al_is_compatible_bitmap.3 new file mode 100644 index 00000000..bb1454f2 --- /dev/null +++ b/allegro/docs/man/al_is_compatible_bitmap.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_compatible_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_compatible_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_compatible_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +D3D and OpenGL allow sharing a texture in a way so it can be used for +multiple windows. +Each ALLEGRO_BITMAP(3) created with al_create_bitmap(3) however is +usually tied to a single ALLEGRO_DISPLAY. +This function can be used to know if the bitmap is compatible with the +given display, even if it is a different display to the one it was +created with. +It returns true if the bitmap is compatible (things like a cached +texture version can be used) and false otherwise (blitting in the +current display will be slow). +.PP +The only time this function is useful is if you are using multiple +windows and need accelerated blitting of the same bitmaps to both. +.PP +Returns true if the bitmap is compatible with the current display, false +otherwise. +If there is no current display, false is returned. diff --git a/allegro/docs/man/al_is_d3d_device_lost.3 b/allegro/docs/man/al_is_d3d_device_lost.3 new file mode 100644 index 00000000..fbe6adc7 --- /dev/null +++ b/allegro/docs/man/al_is_d3d_device_lost.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_d3d_device_lost" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_d3d_device_lost - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_d3d_device_lost(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns a boolean indicating whether or not the Direct3D device +belonging to the given display is in a lost state. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +display - The display that the device you wish to check is attached to diff --git a/allegro/docs/man/al_is_display_haptic.3 b/allegro/docs/man/al_is_display_haptic.3 new file mode 100644 index 00000000..20e32a9c --- /dev/null +++ b/allegro/docs/man/al_is_display_haptic.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_display_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_display_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_display_haptic(ALLEGRO_DISPLAY *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the display has haptic capabilities, false if not. +This mainly concerns force feedback that shakes a hand held device, such +as a phone or a tablet. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_event_queue_empty.3 b/allegro/docs/man/al_is_event_queue_empty.3 new file mode 100644 index 00000000..f9598422 --- /dev/null +++ b/allegro/docs/man/al_is_event_queue_empty.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_event_queue_empty" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_event_queue_empty - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_event_queue_empty(ALLEGRO_EVENT_QUEUE *queue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the event queue specified is currently empty. +.SH SEE ALSO +.PP +al_get_next_event(3), al_peek_next_event(3) diff --git a/allegro/docs/man/al_is_event_queue_paused.3 b/allegro/docs/man/al_is_event_queue_paused.3 new file mode 100644 index 00000000..af27a8e8 --- /dev/null +++ b/allegro/docs/man/al_is_event_queue_paused.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_event_queue_paused" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_event_queue_paused - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_event_queue_paused(const ALLEGRO_EVENT_QUEUE *queue) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the event queue is paused. +.SH SEE ALSO +.PP +al_pause_event_queue(3) +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_is_event_source_registered.3 b/allegro/docs/man/al_is_event_source_registered.3 new file mode 100644 index 00000000..3759a6f0 --- /dev/null +++ b/allegro/docs/man/al_is_event_source_registered.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_event_source_registered" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_event_source_registered - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_event_source_registered(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT_SOURCE *source) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the event source is registered. +.SH SEE ALSO +.PP +al_register_event_source(3) +.SH SINCE +.PP +5.2.0 diff --git a/allegro/docs/man/al_is_font_addon_initialized.3 b/allegro/docs/man/al_is_font_addon_initialized.3 new file mode 100644 index 00000000..c2551e8a --- /dev/null +++ b/allegro/docs/man/al_is_font_addon_initialized.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_font_addon_initialized" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_font_addon_initialized - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_font_addon_initialized(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the font addon is initialized, otherwise returns false. +.SH SINCE +.PP +5.2.6 +.SH SEE ALSO +.PP +al_init_font_addon(3), al_shutdown_font_addon(3) diff --git a/allegro/docs/man/al_is_haptic_active.3 b/allegro/docs/man/al_is_haptic_active.3 new file mode 100644 index 00000000..e7bb25bf --- /dev/null +++ b/allegro/docs/man/al_is_haptic_active.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_haptic_active" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_haptic_active - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_haptic_active(ALLEGRO_HAPTIC *hap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the haptic device can currently be used, false if not. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_haptic_capable.3 b/allegro/docs/man/al_is_haptic_capable.3 new file mode 100644 index 00000000..a4a63c12 --- /dev/null +++ b/allegro/docs/man/al_is_haptic_capable.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_haptic_capable" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_haptic_capable - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_haptic_capable(ALLEGRO_HAPTIC * hap, int query) { +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the haptic device supports the feature indicated by the +query parameter, false if the feature is not supported. +The query parameter must be one of the values of +ALLEGRO_HAPTIC_CONSTANTS(3). +.SH SINCE +.PP +5.1.9 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE +.SH SEE ALSO +.PP +al_get_haptic_capabilities(3) diff --git a/allegro/docs/man/al_is_haptic_effect_ok.3 b/allegro/docs/man/al_is_haptic_effect_ok.3 new file mode 100644 index 00000000..6d152f6d --- /dev/null +++ b/allegro/docs/man/al_is_haptic_effect_ok.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_haptic_effect_ok" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_haptic_effect_ok - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_haptic_effect_ok(ALLEGRO_HAPTIC *hap, ALLEGRO_HAPTIC_EFFECT *effect) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the haptic device can play the haptic effect as given, +false if not. +The haptic effect must have been filled in completely and correctly. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_haptic_effect_playing.3 b/allegro/docs/man/al_is_haptic_effect_playing.3 new file mode 100644 index 00000000..5a0d8f26 --- /dev/null +++ b/allegro/docs/man/al_is_haptic_effect_playing.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_haptic_effect_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_haptic_effect_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_haptic_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the haptic effect is currently playing. +Returns false if the effect has been stopped or if it has already +finished playing, or if it has not been played yet. +The play_id must be a valid ALLEGRO_HAPTIC_EFFECT_ID(3) obtained from +al_upload_haptic_effect(3), al_upload_and_play_haptic_effect(3) or +al_rumble_haptic(3). +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_haptic_installed.3 b/allegro/docs/man/al_is_haptic_installed.3 new file mode 100644 index 00000000..44c152ce --- /dev/null +++ b/allegro/docs/man/al_is_haptic_installed.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_haptic_installed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_haptic_installed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_haptic_installed(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the haptic device subsystem is installed, false if not. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_image_addon_initialized.3 b/allegro/docs/man/al_is_image_addon_initialized.3 new file mode 100644 index 00000000..c720d5a9 --- /dev/null +++ b/allegro/docs/man/al_is_image_addon_initialized.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_image_addon_initialized" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_image_addon_initialized - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_image_addon_initialized(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the image addon is initialized, otherwise returns false. +.SH SINCE +.PP +5.2.6 diff --git a/allegro/docs/man/al_is_joystick_haptic.3 b/allegro/docs/man/al_is_joystick_haptic.3 new file mode 100644 index 00000000..55a50892 --- /dev/null +++ b/allegro/docs/man/al_is_joystick_haptic.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_joystick_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_joystick_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_joystick_haptic(ALLEGRO_JOYSTICK *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the joystick has haptic capabilities, false if not. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_joystick_installed.3 b/allegro/docs/man/al_is_joystick_installed.3 new file mode 100644 index 00000000..a9d4c219 --- /dev/null +++ b/allegro/docs/man/al_is_joystick_installed.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_joystick_installed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_joystick_installed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_joystick_installed(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if al_install_joystick(3) was called successfully. diff --git a/allegro/docs/man/al_is_keyboard_haptic.3 b/allegro/docs/man/al_is_keyboard_haptic.3 new file mode 100644 index 00000000..03529a4d --- /dev/null +++ b/allegro/docs/man/al_is_keyboard_haptic.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_keyboard_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_keyboard_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the keyboard has haptic capabilities, false if not. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_keyboard_installed.3 b/allegro/docs/man/al_is_keyboard_installed.3 new file mode 100644 index 00000000..e130726e --- /dev/null +++ b/allegro/docs/man/al_is_keyboard_installed.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_keyboard_installed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_keyboard_installed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_keyboard_installed(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if al_install_keyboard(3) was called successfully. diff --git a/allegro/docs/man/al_is_mouse_haptic.3 b/allegro/docs/man/al_is_mouse_haptic.3 new file mode 100644 index 00000000..5e12f81f --- /dev/null +++ b/allegro/docs/man/al_is_mouse_haptic.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_mouse_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_mouse_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_mouse_haptic(ALLEGRO_MOUSE *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the mouse has haptic capabilities, false if not. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_mouse_installed.3 b/allegro/docs/man/al_is_mouse_installed.3 new file mode 100644 index 00000000..a32986a9 --- /dev/null +++ b/allegro/docs/man/al_is_mouse_installed.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_mouse_installed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_mouse_installed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_mouse_installed(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if al_install_mouse(3) was called successfully. diff --git a/allegro/docs/man/al_is_native_dialog_addon_initialized.3 b/allegro/docs/man/al_is_native_dialog_addon_initialized.3 new file mode 100644 index 00000000..24bbbb92 --- /dev/null +++ b/allegro/docs/man/al_is_native_dialog_addon_initialized.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_native_dialog_addon_initialized" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_native_dialog_addon_initialized - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_native_dialog_addon_initialized(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the native dialog addon is initialized, otherwise +returns false. +.SH SINCE +.PP +5.2.6 diff --git a/allegro/docs/man/al_is_primitives_addon_initialized.3 b/allegro/docs/man/al_is_primitives_addon_initialized.3 new file mode 100644 index 00000000..44a9a174 --- /dev/null +++ b/allegro/docs/man/al_is_primitives_addon_initialized.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_primitives_addon_initialized" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_primitives_addon_initialized - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_primitives_addon_initialized(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the primitives addon is initialized, otherwise returns +false. +.SH SINCE +.PP +5.2.6 +.SH SEE ALSO +.PP +al_init_primitives_addon(3), al_shutdown_primitives_addon(3) diff --git a/allegro/docs/man/al_is_sub_bitmap.3 b/allegro/docs/man/al_is_sub_bitmap.3 new file mode 100644 index 00000000..31407237 --- /dev/null +++ b/allegro/docs/man/al_is_sub_bitmap.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_sub_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_sub_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_sub_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the specified bitmap is a sub-bitmap, false otherwise. +.SH SEE ALSO +.PP +al_create_sub_bitmap(3), al_get_parent_bitmap(3) diff --git a/allegro/docs/man/al_is_system_installed.3 b/allegro/docs/man/al_is_system_installed.3 new file mode 100644 index 00000000..7d550f8c --- /dev/null +++ b/allegro/docs/man/al_is_system_installed.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_system_installed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_system_installed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_system_installed(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if Allegro is initialized, otherwise returns false. diff --git a/allegro/docs/man/al_is_touch_input_haptic.3 b/allegro/docs/man/al_is_touch_input_haptic.3 new file mode 100644 index 00000000..cba74fdd --- /dev/null +++ b/allegro/docs/man/al_is_touch_input_haptic.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_touch_input_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_touch_input_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the touch input device has haptic capabilities, false if +not. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_is_touch_input_installed.3 b/allegro/docs/man/al_is_touch_input_installed.3 new file mode 100644 index 00000000..525a0561 --- /dev/null +++ b/allegro/docs/man/al_is_touch_input_installed.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_touch_input_installed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_touch_input_installed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_touch_input_installed(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if al_install_touch_input(3) was called successfully. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_is_ttf_addon_initialized.3 b/allegro/docs/man/al_is_ttf_addon_initialized.3 new file mode 100644 index 00000000..022a4360 --- /dev/null +++ b/allegro/docs/man/al_is_ttf_addon_initialized.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_ttf_addon_initialized" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_ttf_addon_initialized - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_ttf_addon_initialized(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the TTF addon is initialized, otherwise returns false. +.SH SINCE +.PP +5.2.6 +.SH SEE ALSO +.PP +al_init_ttf_addon(3), al_shutdown_ttf_addon(3) diff --git a/allegro/docs/man/al_is_video_addon_initialized.3 b/allegro/docs/man/al_is_video_addon_initialized.3 new file mode 100644 index 00000000..432b2f58 --- /dev/null +++ b/allegro/docs/man/al_is_video_addon_initialized.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_video_addon_initialized" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_video_addon_initialized - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_video_addon_initialized(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the video addon is initialized, otherwise returns false. +.SH SINCE +.PP +5.2.6 diff --git a/allegro/docs/man/al_is_video_playing.3 b/allegro/docs/man/al_is_video_playing.3 new file mode 100644 index 00000000..bddee45e --- /dev/null +++ b/allegro/docs/man/al_is_video_playing.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_is_video_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_is_video_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_is_video_playing(ALLEGRO_VIDEO *video) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true if the video is currently playing. +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_itofix.3 b/allegro/docs/man/al_itofix.3 new file mode 100644 index 00000000..05642856 --- /dev/null +++ b/allegro/docs/man/al_itofix.3 @@ -0,0 +1,48 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_itofix" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_itofix - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +al_fixed al_itofix(int x); +\f[R] +.fi +.SH DESCRIPTION +.PP +Converts an integer to fixed point. +This is the same thing as x<<16. +Remember that overflows (trying to convert an integer greater than +32767) and underflows (trying to convert an integer lesser than -32768) +are not detected even in debug builds! The values simply \[lq]wrap +around\[rq]. +.PP +Example: +.IP +.nf +\f[C] +al_fixed number; + +/* This conversion is OK. */ +number = al_itofix(100); +assert(al_fixtoi(number) == 100); + +number = al_itofix(64000); + +/* This check will fail in debug builds. */ +assert(al_fixtoi(number) == 64000); +\f[R] +.fi +.SH RETURN VALUE +.PP +Returns the value of the integer converted to fixed point ignoring +overflows. +.SH SEE ALSO +.PP +al_fixtoi(3), al_ftofix(3), al_fixtof(3). diff --git a/allegro/docs/man/al_join_paths.3 b/allegro/docs/man/al_join_paths.3 new file mode 100644 index 00000000..3ff5d04b --- /dev/null +++ b/allegro/docs/man/al_join_paths.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_join_paths" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_join_paths - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_join_paths(ALLEGRO_PATH *path, const ALLEGRO_PATH *tail) +\f[R] +.fi +.SH DESCRIPTION +.PP +Concatenate two path structures. +The first path structure is modified. +If `tail' is an absolute path, this function does nothing. +.PP +If `tail' is a relative path, all of its directory components will be +appended to `path'. +tail\[cq]s filename will also overwrite path\[cq]s filename, even if it +is just the empty string. +.PP +Tail\[cq]s drive is ignored. +.PP +Returns true if `tail' was a relative path and so concatenated to +`path', otherwise returns false. +.SH SEE ALSO +.PP +al_rebase_path(3) diff --git a/allegro/docs/man/al_join_thread.3 b/allegro/docs/man/al_join_thread.3 new file mode 100644 index 00000000..8a60dec1 --- /dev/null +++ b/allegro/docs/man/al_join_thread.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_join_thread" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_join_thread - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value) +\f[R] +.fi +.SH DESCRIPTION +.PP +Wait for the thread to finish executing. +This implicitly calls al_set_thread_should_stop(3) first. +.PP +If \f[C]ret_value\f[R] is non-\f[C]NULL\f[R], the value returned by the +thread function will be stored at the location pointed to by +\f[C]ret_value\f[R]. +.SH SEE ALSO +.PP +al_set_thread_should_stop(3), al_get_thread_should_stop(3), +al_destroy_thread(3). diff --git a/allegro/docs/man/al_key_down.3 b/allegro/docs/man/al_key_down.3 new file mode 100644 index 00000000..aab58bf7 --- /dev/null +++ b/allegro/docs/man/al_key_down.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_key_down" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_key_down - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_key_down(const ALLEGRO_KEYBOARD_STATE *state, int keycode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the key specified was held down in the state specified. +.SH SEE ALSO +.PP +ALLEGRO_KEYBOARD_STATE(3) diff --git a/allegro/docs/man/al_keycode_to_name.3 b/allegro/docs/man/al_keycode_to_name.3 new file mode 100644 index 00000000..ce79c0a1 --- /dev/null +++ b/allegro/docs/man/al_keycode_to_name.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_keycode_to_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_keycode_to_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_keycode_to_name(int keycode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Converts the given keycode to a description of the key. diff --git a/allegro/docs/man/al_load_audio_stream.3 b/allegro/docs/man/al_load_audio_stream.3 new file mode 100644 index 00000000..8c7ff423 --- /dev/null +++ b/allegro/docs/man/al_load_audio_stream.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_audio_stream" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_audio_stream - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_STREAM *al_load_audio_stream(const char *filename, + size_t buffer_count, unsigned int samples) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads an audio file from disk as it is needed. +.PP +Unlike regular streams, the one returned by this function need not be +fed by the user; the library will automatically read more of the file as +it is needed. +The stream will contain \f[I]buffer_count\f[R] buffers with +\f[I]samples\f[R] samples. +.PP +The audio stream will start in the playing state. +It should be attached to a voice or mixer to generate any output. +See ALLEGRO_AUDIO_STREAM(3) for more details. +.PP +Returns the stream on success, NULL on failure. +.RS +.PP +\f[I]Note:\f[R] the allegro_audio library does not support any audio +file formats by default. +You must use the allegro_acodec addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_load_audio_stream_f(3), al_register_audio_stream_loader(3), +al_init_acodec_addon(3) diff --git a/allegro/docs/man/al_load_audio_stream_f.3 b/allegro/docs/man/al_load_audio_stream_f.3 new file mode 100644 index 00000000..bcfb0f20 --- /dev/null +++ b/allegro/docs/man/al_load_audio_stream_f.3 @@ -0,0 +1,49 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_audio_stream_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_audio_stream_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_AUDIO_STREAM *al_load_audio_stream_f(ALLEGRO_FILE* fp, const char *ident, + size_t buffer_count, unsigned int samples) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads an audio file from ALLEGRO_FILE(3) stream as it is needed. +.PP +Unlike regular streams, the one returned by this function need not be +fed by the user; the library will automatically read more of the file as +it is needed. +The stream will contain \f[I]buffer_count\f[R] buffers with +\f[I]samples\f[R] samples. +.PP +The file type is determined by the passed `ident' parameter, which is a +file name extension including the leading dot. +.PP +The audio stream will start in the playing state. +It should be attached to a voice or mixer to generate any output. +See ALLEGRO_AUDIO_STREAM(3) for more details. +.PP +Returns the stream on success, NULL on failure. +On success the file should be considered owned by the audio stream, and +will be closed when the audio stream is destroyed. +On failure the file will be closed. +.RS +.PP +\f[I]Note:\f[R] the allegro_audio library does not support any audio +file formats by default. +You must use the allegro_acodec addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_load_audio_stream(3), al_register_audio_stream_loader_f(3), +al_init_acodec_addon(3) diff --git a/allegro/docs/man/al_load_bitmap.3 b/allegro/docs/man/al_load_bitmap.3 new file mode 100644 index 00000000..dd8c09a2 --- /dev/null +++ b/allegro/docs/man/al_load_bitmap.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_load_bitmap(const char *filename) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads an image file into a new ALLEGRO_BITMAP(3). +The file type is determined by the extension, except if the file has no +extension in which case al_identify_bitmap(3) is used instead. +.PP +Returns NULL on error. +.PP +This is the same as calling al_load_bitmap_flags(3) with a flags +parameter of 0. +.RS +.PP +\f[I]Note:\f[R] the core Allegro library does not support any image file +formats by default. +You must use the allegro_image addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_load_bitmap_flags(3), al_load_bitmap_f(3), +al_register_bitmap_loader(3), al_set_new_bitmap_format(3), +al_set_new_bitmap_flags(3), al_init_image_addon(3) diff --git a/allegro/docs/man/al_load_bitmap_f.3 b/allegro/docs/man/al_load_bitmap_f.3 new file mode 100644 index 00000000..7b18d5ca --- /dev/null +++ b/allegro/docs/man/al_load_bitmap_f.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_bitmap_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_bitmap_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_load_bitmap_f(ALLEGRO_FILE *fp, const char *ident) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads an image from an ALLEGRO_FILE(3) stream into a new +ALLEGRO_BITMAP(3). +The file type is determined by the passed `ident' parameter, which is a +file name extension including the leading dot. +If (and only if) `ident' is NULL, the file type is determined with +al_identify_bitmap_f(3) instead. +.PP +This is the same as calling al_load_bitmap_flags_f(3) with 0 for the +flags parameter. +.PP +Returns NULL on error. +The file remains open afterwards. +.RS +.PP +\f[I]Note:\f[R] the core Allegro library does not support any image file +formats by default. +You must use the allegro_image addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_load_bitmap_flags_f(3), al_load_bitmap(3), +al_register_bitmap_loader_f(3), al_init_image_addon(3) diff --git a/allegro/docs/man/al_load_bitmap_flags.3 b/allegro/docs/man/al_load_bitmap_flags.3 new file mode 100644 index 00000000..763cc4ed --- /dev/null +++ b/allegro/docs/man/al_load_bitmap_flags.3 @@ -0,0 +1,149 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_bitmap_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_bitmap_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_load_bitmap_flags(const char *filename, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads an image file into a new ALLEGRO_BITMAP(3). +The file type is determined by the extension, except if the file has no +extension in which case al_identify_bitmap(3) is used instead. +.PP +Returns NULL on error. +.PP +The flags parameter may be a combination of the following constants: +.TP +ALLEGRO_NO_PREMULTIPLIED_ALPHA +By default, Allegro pre-multiplies the alpha channel of an image with +the images color data when it loads it. +Typically that would look something like this: +.RS +.IP +.nf +\f[C] +r = get_float_byte(); +g = get_float_byte(); +b = get_float_byte(); +a = get_float_byte(); + +r = r * a; +g = g * a; +b = b * a; + +set_image_pixel(x, y, r, g, b, a); +\f[R] +.fi +.PP +The reason for this can be seen in the Allegro example ex_premulalpha, +ie, using pre-multiplied alpha gives more accurate color results in some +cases. +To use alpha blending with images loaded with pre-multiplied alpha, you +would use the default blending mode, which is set with +al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA). +.PP +The ALLEGRO_NO_PREMULTIPLIED_ALPHA flag being set will ensure that +images are not loaded with alpha pre-multiplied, but are loaded with +color values direct from the image. +That looks like this: +.IP +.nf +\f[C] +r = get_float_byte(); +g = get_float_byte(); +b = get_float_byte(); +a = get_float_byte(); + +set_image_pixel(x, y, r, g, b, a); +\f[R] +.fi +.PP +To draw such an image using regular alpha blending, you would use +al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) to set +the correct blender. +This has some caveats. +First, as mentioned above, drawing such an image can result in less +accurate color blending (when drawing an image with linear filtering on, +the edges will be darker than they should be). +Second, the behaviour is somewhat confusing, which is explained in the +example below. +.IP +.nf +\f[C] +// Load and create bitmaps with an alpha channel +al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA); +// Load some bitmap with alpha in it +bmp = al_load_bitmap(\[dq]some_alpha_bitmap.png\[dq]); +// We will draw to this buffer and then draw this buffer to the screen +tmp_buffer = al_create_bitmap(SCREEN_W, SCREEN_H); +// Set the buffer as the target and clear it +al_set_target_bitmap(tmp_buffer); +al_clear_to_color(al_map_rgba_f(0, 0, 0, 1)); +// Draw the bitmap to the temporary buffer +al_draw_bitmap(bmp, 0, 0, 0); +// Finally, draw the buffer to the screen +// The output will look incorrect (may take close inspection +// depending on the bitmap -- it may also be very obvious) +al_set_target_bitmap(al_get_backbuffer(display)); +al_draw_bitmap(tmp_buffer, 0, 0, 0); +\f[R] +.fi +.PP +To explain further, if you have a pixel with 0.5 alpha, and you\[cq]re +using (ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) for blending, +the formula is: +.IP +.nf +\f[C] +a = da * dst + sa * src +\f[R] +.fi +.PP +Expands to: +.IP +.nf +\f[C] +result_a = dst_a * (1-0.5) + 0.5 * 0.5 +\f[R] +.fi +.PP +So if you draw the image to the temporary buffer, it is blended once +resulting in 0.75 alpha, then drawn again to the screen, blended in the +same way, resulting in a pixel has 0.1875 as an alpha value. +.RE +.TP +ALLEGRO_KEEP_INDEX +Load the palette indices of 8-bit .bmp and .pcx files instead of the rgb +colors. +Since 5.1.0. +.TP +ALLEGRO_KEEP_BITMAP_FORMAT +Force the resulting ALLEGRO_BITMAP(3) to use the same format as the +file. +.RS +.PP +\f[I]This is not yet honoured.\f[R] +.RE +.RS +.PP +\f[I]Note:\f[R] the core Allegro library does not support any image file +formats by default. +You must use the allegro_image addon, or register your own format +handler. +.RE +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_load_bitmap(3) diff --git a/allegro/docs/man/al_load_bitmap_flags_f.3 b/allegro/docs/man/al_load_bitmap_flags_f.3 new file mode 100644 index 00000000..f7ac4bce --- /dev/null +++ b/allegro/docs/man/al_load_bitmap_flags_f.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_bitmap_flags_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_bitmap_flags_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_BITMAP *al_load_bitmap_flags_f(ALLEGRO_FILE *fp, + const char *ident, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads an image from an ALLEGRO_FILE(3) stream into a new +ALLEGRO_BITMAP(3). +The file type is determined by the passed `ident' parameter, which is a +file name extension including the leading dot. +If (and only if) `ident' is NULL, the file type is determined with +al_identify_bitmap_f(3) instead. +.PP +The flags parameter is the same as for al_load_bitmap_flags(3). +.PP +Returns NULL on error. +The file remains open afterwards. +.RS +.PP +\f[I]Note:\f[R] the core Allegro library does not support any image file +formats by default. +You must use the allegro_image addon, or register your own format +handler. +.RE +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_load_bitmap_f(3), al_load_bitmap_flags(3) diff --git a/allegro/docs/man/al_load_bitmap_font.3 b/allegro/docs/man/al_load_bitmap_font.3 new file mode 100644 index 00000000..56ba6b50 --- /dev/null +++ b/allegro/docs/man/al_load_bitmap_font.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_bitmap_font" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_bitmap_font - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_load_bitmap_font(const char *fname) +\f[R] +.fi +.SH DESCRIPTION +.PP +Load a bitmap font from a file. +This is done by first calling al_load_bitmap_flags(3) and then +al_grab_font_from_bitmap(3). +.PP +If you wanted to load an old A4 font, for example, it would be better to +load the bitmap yourself in order to call al_convert_mask_to_alpha(3) on +it before passing it to al_grab_font_from_bitmap(3). +.SH SEE ALSO +.PP +al_load_bitmap_font_flags(3), al_load_font(3), al_load_bitmap_flags(3) diff --git a/allegro/docs/man/al_load_bitmap_font_flags.3 b/allegro/docs/man/al_load_bitmap_font_flags.3 new file mode 100644 index 00000000..fb5f99c3 --- /dev/null +++ b/allegro/docs/man/al_load_bitmap_font_flags.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_bitmap_font_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_bitmap_font_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_load_bitmap_font_flags(const char *fname, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_load_bitmap_font(3) but additionally takes a flags parameter +which is a bitfield containing a combination of the following: +.TP +ALLEGRO_NO_PREMULTIPLIED_ALPHA +The same meaning as for al_load_bitmap_flags(3). +.SH SEE ALSO +.PP +al_load_bitmap_font(3), al_load_bitmap_flags(3) diff --git a/allegro/docs/man/al_load_config_file.3 b/allegro/docs/man/al_load_config_file.3 new file mode 100644 index 00000000..4f4dd638 --- /dev/null +++ b/allegro/docs/man/al_load_config_file.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_config_file" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_config_file - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CONFIG *al_load_config_file(const char *filename) +\f[R] +.fi +.SH DESCRIPTION +.PP +Read a configuration file from disk. +Returns NULL on error. +The configuration structure should be destroyed with +al_destroy_config(3). +.SH SEE ALSO +.PP +al_load_config_file_f(3), al_save_config_file(3) diff --git a/allegro/docs/man/al_load_config_file_f.3 b/allegro/docs/man/al_load_config_file_f.3 new file mode 100644 index 00000000..04399584 --- /dev/null +++ b/allegro/docs/man/al_load_config_file_f.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_config_file_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_config_file_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file) +\f[R] +.fi +.SH DESCRIPTION +.PP +Read a configuration file from an already open file. +.PP +Returns NULL on error. +The configuration structure should be destroyed with +al_destroy_config(3). +The file remains open afterwards. +.SH SEE ALSO +.PP +al_load_config_file(3) diff --git a/allegro/docs/man/al_load_font.3 b/allegro/docs/man/al_load_font.3 new file mode 100644 index 00000000..0c111b27 --- /dev/null +++ b/allegro/docs/man/al_load_font.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_font" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_font - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_load_font(char const *filename, int size, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads a font from disk. +This will use al_load_bitmap_font_flags(3) if you pass the name of a +known bitmap format, or else al_load_ttf_font(3). +.PP +The flags parameter is passed through to either of those functions. +Bitmap and TTF fonts are also affected by the current [bitmap +flags]al_set_new_bitmap_flags(3) at the time the font is loaded. +.SH SEE ALSO +.PP +al_destroy_font(3), al_init_font_addon(3), al_register_font_loader(3), +al_load_bitmap_font_flags(3), al_load_ttf_font(3) diff --git a/allegro/docs/man/al_load_sample.3 b/allegro/docs/man/al_load_sample.3 new file mode 100644 index 00000000..e490faeb --- /dev/null +++ b/allegro/docs/man/al_load_sample.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_sample" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_sample - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SAMPLE *al_load_sample(const char *filename) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads a few different audio file formats based on their extension. +.PP +Note that this stores the entire file in memory at once, which may be +time consuming. +To read the file as it is needed, use al_load_audio_stream(3). +.PP +Returns the sample on success, NULL on failure. +.RS +.PP +\f[I]Note:\f[R] the allegro_audio library does not support any audio +file formats by default. +You must use the allegro_acodec addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_register_sample_loader(3), al_init_acodec_addon(3) diff --git a/allegro/docs/man/al_load_sample_f.3 b/allegro/docs/man/al_load_sample_f.3 new file mode 100644 index 00000000..1c17b0bb --- /dev/null +++ b/allegro/docs/man/al_load_sample_f.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_sample_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_sample_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SAMPLE *al_load_sample_f(ALLEGRO_FILE* fp, const char *ident) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads an audio file from an ALLEGRO_FILE(3) stream into an +ALLEGRO_SAMPLE(3). +The file type is determined by the passed `ident' parameter, which is a +file name extension including the leading dot. +.PP +Note that this stores the entire file in memory at once, which may be +time consuming. +To read the file as it is needed, use al_load_audio_stream_f(3). +.PP +Returns the sample on success, NULL on failure. +The file remains open afterwards. +.RS +.PP +\f[I]Note:\f[R] the allegro_audio library does not support any audio +file formats by default. +You must use the allegro_acodec addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_register_sample_loader_f(3), al_init_acodec_addon(3) diff --git a/allegro/docs/man/al_load_ttf_font.3 b/allegro/docs/man/al_load_ttf_font.3 new file mode 100644 index 00000000..0c76dbb8 --- /dev/null +++ b/allegro/docs/man/al_load_ttf_font.3 @@ -0,0 +1,50 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_ttf_font" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_ttf_font - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_load_ttf_font(char const *filename, int size, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Loads a TrueType font from a file using the FreeType library. +Quoting from the FreeType FAQ this means support for many different font +formats: +.PP +\f[I]TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and +others\f[R] +.PP +The \f[C]size\f[R] parameter determines the size the font will be +rendered at, specified in pixels. +The standard font size is measured in \f[I]units per EM\f[R], if you +instead want to specify the size as the total height of glyphs in +pixels, pass it as a negative value. +.RS +.PP +\f[I]Note:\f[R] If you want to display text at multiple sizes, load the +font multiple times with different size parameters. +.RE +.PP +The following flags are supported: +.IP \[bu] 2 +ALLEGRO_TTF_NO_KERNING - Do not use any kerning even if the font file +supports it. +.IP \[bu] 2 +ALLEGRO_TTF_MONOCHROME - Load as a monochrome font (which means no +anti-aliasing of the font is done). +.IP \[bu] 2 +ALLEGRO_TTF_NO_AUTOHINT - Disable the Auto Hinter which is enabled by +default in newer versions of FreeType. +Since: 5.0.6, 5.1.2 +.SH SEE ALSO +.PP +al_init_ttf_addon(3), al_load_ttf_font_f(3) diff --git a/allegro/docs/man/al_load_ttf_font_f.3 b/allegro/docs/man/al_load_ttf_font_f.3 new file mode 100644 index 00000000..00d85a3f --- /dev/null +++ b/allegro/docs/man/al_load_ttf_font_f.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_ttf_font_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_ttf_font_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_load_ttf_font_f(ALLEGRO_FILE *file, + char const *filename, int size, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_load_ttf_font(3), but the font is read from the file handle. +The filename is only used to find possible additional files next to a +font file. +.RS +.PP +\f[I]Note:\f[R] The file handle is owned by the returned ALLEGRO_FONT +object and must not be freed by the caller, as FreeType expects to be +able to read from it at a later time. +.RE diff --git a/allegro/docs/man/al_load_ttf_font_stretch.3 b/allegro/docs/man/al_load_ttf_font_stretch.3 new file mode 100644 index 00000000..65818203 --- /dev/null +++ b/allegro/docs/man/al_load_ttf_font_stretch.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_ttf_font_stretch" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_ttf_font_stretch - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_load_ttf_font_stretch(char const *filename, int w, int h, + int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_load_ttf_font(3), except it takes separate width and height +parameters instead of a single size parameter. +.PP +If the height is a positive value, and the width zero or positive, then +font will be stretched according to those parameters. +The width must not be negative if the height is positive. +.PP +As with al_load_ttf_font(3), the height may be a negative value to +specify the total height in pixels. +Then the width must also be a negative value, or zero. +.PP +Returns \f[C]NULL\f[R] if the height is positive while width is +negative, or if the height is negative while the width is positive. +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_load_ttf_font(3), al_load_ttf_font_stretch_f(3) diff --git a/allegro/docs/man/al_load_ttf_font_stretch_f.3 b/allegro/docs/man/al_load_ttf_font_stretch_f.3 new file mode 100644 index 00000000..53afd0a0 --- /dev/null +++ b/allegro/docs/man/al_load_ttf_font_stretch_f.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_load_ttf_font_stretch_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_load_ttf_font_stretch_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FONT *al_load_ttf_font_stretch_f(ALLEGRO_FILE *file, + char const *filename, int w, int h, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_load_ttf_font_stretch(3), but the font is read from the file +handle. +The filename is only used to find possible additional files next to a +font file. +.RS +.PP +\f[I]Note:\f[R] The file handle is owned by the returned ALLEGRO_FONT +object and must not be freed by the caller, as FreeType expects to be +able to read from it at a later time. +.RE +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_load_ttf_font_stretch(3) diff --git a/allegro/docs/man/al_lock_bitmap.3 b/allegro/docs/man/al_lock_bitmap.3 new file mode 100644 index 00000000..afc711d7 --- /dev/null +++ b/allegro/docs/man/al_lock_bitmap.3 @@ -0,0 +1,70 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_lock_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_lock_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_LOCKED_REGION *al_lock_bitmap(ALLEGRO_BITMAP *bitmap, + int format, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Lock an entire bitmap for reading or writing. +If the bitmap is a display bitmap it will be updated from system memory +after the bitmap is unlocked (unless locked read only). +Returns NULL if the bitmap cannot be locked, e.g.\ the bitmap was locked +previously and not unlocked. +This function also returns NULL if the \f[C]format\f[R] is a compressed +format. +.PP +Flags are: +.IP \[bu] 2 +ALLEGRO_LOCK_READONLY - The locked region will not be written to. +This can be faster if the bitmap is a video texture, as it can be +discarded after the lock instead of uploaded back to the card. +.IP \[bu] 2 +ALLEGRO_LOCK_WRITEONLY - The locked region will not be read from. +This can be faster if the bitmap is a video texture, as no data need to +be read from the video card. +You are required to fill in all pixels before unlocking the bitmap +again, so be careful when using this flag. +.IP \[bu] 2 +ALLEGRO_LOCK_READWRITE - The locked region can be written to and read +from. +Use this flag if a partial number of pixels need to be written to, even +if reading is not needed. +.PP +\f[C]format\f[R] indicates the pixel format that the returned buffer +will be in. +To lock in the same format as the bitmap stores its data internally, +call with \f[C]al_get_bitmap_format(bitmap)\f[R] as the format or use +ALLEGRO_PIXEL_FORMAT_ANY. +Locking in the native format will usually be faster. +If the bitmap format is compressed, using ALLEGRO_PIXEL_FORMAT_ANY will +choose an implementation defined non-compressed format. +.PP +On some platforms, Allegro automatically backs up the contents of video +bitmaps because they may be occasionally lost (see discussion in +al_create_bitmap(3)\[cq]s documentation). +If you\[cq]re completely recreating the bitmap contents often (e.g. +every frame) then you will get much better performance by creating the +target bitmap with ALLEGRO_NO_PRESERVE_TEXTURE flag. +.RS +.PP +\f[I]Note:\f[R] While a bitmap is locked, you can not use any drawing +operations on it (with the sole exception of al_put_pixel(3) and +al_put_blended_pixel(3)). +.RE +.SH SEE ALSO +.PP +ALLEGRO_LOCKED_REGION(3), ALLEGRO_PIXEL_FORMAT(3), al_unlock_bitmap(3), +al_lock_bitmap_region(3), al_lock_bitmap_blocked(3), +al_lock_bitmap_region_blocked(3) diff --git a/allegro/docs/man/al_lock_bitmap_blocked.3 b/allegro/docs/man/al_lock_bitmap_blocked.3 new file mode 100644 index 00000000..f3943d43 --- /dev/null +++ b/allegro/docs/man/al_lock_bitmap_blocked.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_lock_bitmap_blocked" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_lock_bitmap_blocked - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_LOCKED_REGION *al_lock_bitmap_blocked(ALLEGRO_BITMAP *bitmap, + int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_lock_bitmap(3), but allows locking bitmaps with a blocked pixel +format (i.e.\ a format for which al_get_pixel_block_width(3) or +al_get_pixel_block_height(3) do not return 1) in that format. +To that end, this function also does not allow format conversion. +For bitmap formats with a block size of 1, this function is identical to +calling \f[C]al_lock_bitmap(bmp, al_get_bitmap_format(bmp), flags)\f[R]. +.RS +.PP +\f[I]Note:\f[R] Currently there are no drawing functions that work when +the bitmap is locked with a compressed format. +al_get_pixel(3) will also not work. +.RE +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_lock_bitmap(3), al_lock_bitmap_region_blocked(3) diff --git a/allegro/docs/man/al_lock_bitmap_region.3 b/allegro/docs/man/al_lock_bitmap_region.3 new file mode 100644 index 00000000..54772095 --- /dev/null +++ b/allegro/docs/man/al_lock_bitmap_region.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_lock_bitmap_region" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_lock_bitmap_region - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_LOCKED_REGION *al_lock_bitmap_region(ALLEGRO_BITMAP *bitmap, + int x, int y, int width, int height, int format, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_lock_bitmap(3), but only locks a specific area of the bitmap. +If the bitmap is a video bitmap, only that area of the texture will be +updated when it is unlocked. +Locking only the region you indend to modify will be faster than locking +the whole bitmap. +.RS +.PP +\f[I]Note:\f[R] Using the ALLEGRO_LOCK_WRITEONLY with a blocked pixel +format (i.e.\ formats for which al_get_pixel_block_width(3) or +al_get_pixel_block_height(3) do not return 1) requires you to have the +region be aligned to the block width for optimal performance. +If it is not, then the function will have to lock the region with the +ALLEGRO_LOCK_READWRITE instead in order to pad this region with valid +data. +.RE +.SH SEE ALSO +.PP +ALLEGRO_LOCKED_REGION(3), ALLEGRO_PIXEL_FORMAT(3), al_unlock_bitmap(3) diff --git a/allegro/docs/man/al_lock_bitmap_region_blocked.3 b/allegro/docs/man/al_lock_bitmap_region_blocked.3 new file mode 100644 index 00000000..e4c84814 --- /dev/null +++ b/allegro/docs/man/al_lock_bitmap_region_blocked.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_lock_bitmap_region_blocked" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_lock_bitmap_region_blocked - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_LOCKED_REGION *al_lock_bitmap_region_blocked(ALLEGRO_BITMAP *bitmap, + int x_block, int y_block, int width_block, int height_block, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_lock_bitmap_blocked(3), but allows locking a sub-region, for +performance. +Unlike al_lock_bitmap_region(3) the region specified in terms of blocks +and not pixels. +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_lock_bitmap_region(3), al_lock_bitmap_blocked(3) diff --git a/allegro/docs/man/al_lock_index_buffer.3 b/allegro/docs/man/al_lock_index_buffer.3 new file mode 100644 index 00000000..b9039261 --- /dev/null +++ b/allegro/docs/man/al_lock_index_buffer.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_lock_index_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_lock_index_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void* al_lock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer, int offset, + int length, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Locks a index buffer so you can access its data. +Will return NULL if the parameters are invalid, if reading is requested +from a write only buffer and if the buffer is already locked. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +buffer - Index buffer to lock +.IP \[bu] 2 +offset - Element index of the start of the locked range +.IP \[bu] 2 +length - How many indices to lock +.IP \[bu] 2 +flags - ALLEGRO_LOCK_READONLY, ALLEGRO_LOCK_WRITEONLY or +ALLEGRO_LOCK_READWRITE +.SH SINCE +.PP +5.1.8 +.SH SEE ALSO +.PP +ALLEGRO_INDEX_BUFFER(3), al_unlock_index_buffer(3) diff --git a/allegro/docs/man/al_lock_mutex.3 b/allegro/docs/man/al_lock_mutex.3 new file mode 100644 index 00000000..91ecc9c4 --- /dev/null +++ b/allegro/docs/man/al_lock_mutex.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_lock_mutex" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_lock_mutex - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_lock_mutex(ALLEGRO_MUTEX *mutex) +\f[R] +.fi +.SH DESCRIPTION +.PP +Acquire the lock on \f[C]mutex\f[R]. +If the mutex is already locked by another thread, the call will block +until the mutex becomes available and locked. +.PP +If the mutex is already locked by the calling thread, then the behaviour +depends on whether the mutex was created with al_create_mutex(3) or +al_create_mutex_recursive(3). +In the former case, the behaviour is undefined; the most likely +behaviour is deadlock. +In the latter case, the count in the mutex will be incremented and the +call will return immediately. +.SH SEE ALSO +.PP +al_unlock_mutex(3). +.PP +\f[B]We don\[cq]t yet have al_mutex_trylock.\f[R] diff --git a/allegro/docs/man/al_lock_sample_id.3 b/allegro/docs/man/al_lock_sample_id.3 new file mode 100644 index 00000000..c960eb70 --- /dev/null +++ b/allegro/docs/man/al_lock_sample_id.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_lock_sample_id" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_lock_sample_id - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_SAMPLE_INSTANCE* al_lock_sample_id(ALLEGRO_SAMPLE_ID *spl_id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Locks a ALLEGRO_SAMPLE_ID(3), returning the underlying +ALLEGRO_SAMPLE_INSTANCE(3). +This allows you to adjust the various properties of the instance (such +as volume, pan, etc) while the sound is playing. +.PP +This function will return \f[C]NULL\f[R] if the sound corresponding to +the id is no longer playing. +.PP +While locked, \f[C]ALLEGRO_SAMPLE_ID\f[R] will be unavailable to +additional calls to al_play_sample(3), even if the sound stops while +locked. +To put the \f[C]ALLEGRO_SAMPLE_ID\f[R] back into the pool for reuse, +make sure to call \f[C]al_unlock_sample_id\f[R] when you\[cq]re done +with the instance. +.SH SEE ALSO +.PP +al_play_sample(3), al_unlock_sample_id(3) +.SH SINCE +.PP +5.2.3 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE diff --git a/allegro/docs/man/al_lock_vertex_buffer.3 b/allegro/docs/man/al_lock_vertex_buffer.3 new file mode 100644 index 00000000..4d1dc55e --- /dev/null +++ b/allegro/docs/man/al_lock_vertex_buffer.3 @@ -0,0 +1,39 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_lock_vertex_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_lock_vertex_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void* al_lock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer, int offset, + int length, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Locks a vertex buffer so you can access its data. +Will return NULL if the parameters are invalid, if reading is requested +from a write only buffer, or if the buffer is already locked. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +buffer - Vertex buffer to lock +.IP \[bu] 2 +offset - Vertex index of the start of the locked range +.IP \[bu] 2 +length - How many vertices to lock +.IP \[bu] 2 +flags - ALLEGRO_LOCK_READONLY, ALLEGRO_LOCK_WRITEONLY or +ALLEGRO_LOCK_READWRITE +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_BUFFER(3), al_unlock_vertex_buffer(3) diff --git a/allegro/docs/man/al_make_directory.3 b/allegro/docs/man/al_make_directory.3 new file mode 100644 index 00000000..af05a4e0 --- /dev/null +++ b/allegro/docs/man/al_make_directory.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_make_directory" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_make_directory - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_make_directory(const char *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Creates a new directory on the filesystem. +This function also creates any parent directories as needed. +.PP +Returns true on success (including if the directory already exists), +otherwise returns false on error. +Fills in Allegro\[cq]s errno to indicate the error. +.SH SEE ALSO +.PP +al_get_errno(3) diff --git a/allegro/docs/man/al_make_path_canonical.3 b/allegro/docs/man/al_make_path_canonical.3 new file mode 100644 index 00000000..29006109 --- /dev/null +++ b/allegro/docs/man/al_make_path_canonical.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_make_path_canonical" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_make_path_canonical - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_make_path_canonical(ALLEGRO_PATH *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Removes any leading `..' directory components in absolute paths. +Removes all `.' directory components. +.PP +Note that this does \f[I]not\f[R] collapse \[lq]x/../y\[rq] sections +into \[lq]y\[rq]. +This is by design. +If \[lq]/foo\[rq] on your system is a symlink to \[lq]/bar/baz\[rq], +then \[lq]/foo/../quux\[rq] is actually \[lq]/bar/quux\[rq], not +\[lq]/quux\[rq] as a naive removal of \[lq]..\[rq] components would give +you. diff --git a/allegro/docs/man/al_make_temp_file.3 b/allegro/docs/man/al_make_temp_file.3 new file mode 100644 index 00000000..7f029d15 --- /dev/null +++ b/allegro/docs/man/al_make_temp_file.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_make_temp_file" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_make_temp_file - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILE *al_make_temp_file(const char *template, ALLEGRO_PATH **ret_path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Make a temporary randomly named file given a filename `template'. +.PP +`template' is a string giving the format of the generated filename and +should include one or more capital Xs. +The Xs are replaced with random alphanumeric characters, produced using +a simple pseudo-random number generator only. +There should be no path separators. +.PP +If `ret_path' is not NULL, the address it points to will be set to point +to a new path structure with the name of the temporary file. +.PP +Returns the opened ALLEGRO_FILE(3) on success, NULL on failure. diff --git a/allegro/docs/man/al_malloc.3 b/allegro/docs/man/al_malloc.3 new file mode 100644 index 00000000..c2ce6d75 --- /dev/null +++ b/allegro/docs/man/al_malloc.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_malloc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_malloc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define al_malloc(n) \[rs] + (al_malloc_with_context((n), __LINE__, __FILE__, __func__)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like malloc() in the C standard library, but the implementation may be +overridden. +.PP +This is a macro. +.SH SEE ALSO +.PP +al_free(3), al_realloc(3), al_calloc(3), al_malloc_with_context(3), +al_set_memory_interface(3) diff --git a/allegro/docs/man/al_malloc_with_context.3 b/allegro/docs/man/al_malloc_with_context.3 new file mode 100644 index 00000000..522c9bd1 --- /dev/null +++ b/allegro/docs/man/al_malloc_with_context.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_malloc_with_context" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_malloc_with_context - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void *al_malloc_with_context(size_t n, + int line, const char *file, const char *func) +\f[R] +.fi +.SH DESCRIPTION +.PP +This calls malloc() from the Allegro library (this matters on Windows), +unless overridden with al_set_memory_interface(3), +.PP +Generally you should use the al_malloc(3) macro. diff --git a/allegro/docs/man/al_map_rgb.3 b/allegro/docs/man/al_map_rgb.3 new file mode 100644 index 00000000..034bd929 --- /dev/null +++ b/allegro/docs/man/al_map_rgb.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_map_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_map_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_map_rgb( + unsigned char r, unsigned char g, unsigned char b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert r, g, b (ranging from 0-255) into an ALLEGRO_COLOR(3), using 255 +for alpha. +.PP +This function can be called before Allegro is initialized. +.SH SEE ALSO +.PP +al_map_rgba(3), al_map_rgba_f(3), al_map_rgb_f(3) diff --git a/allegro/docs/man/al_map_rgb_f.3 b/allegro/docs/man/al_map_rgb_f.3 new file mode 100644 index 00000000..4fef8d35 --- /dev/null +++ b/allegro/docs/man/al_map_rgb_f.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_map_rgb_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_map_rgb_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_map_rgb_f(float r, float g, float b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert r, g, b, (ranging from 0.0f-1.0f) into an ALLEGRO_COLOR(3), +using 1.0f for alpha. +.PP +This function can be called before Allegro is initialized. +.SH SEE ALSO +.PP +al_map_rgba(3), al_map_rgb(3), al_map_rgba_f(3) diff --git a/allegro/docs/man/al_map_rgba.3 b/allegro/docs/man/al_map_rgba.3 new file mode 100644 index 00000000..bc92fb94 --- /dev/null +++ b/allegro/docs/man/al_map_rgba.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_map_rgba" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_map_rgba - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_map_rgba( + unsigned char r, unsigned char g, unsigned char b, unsigned char a) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert r, g, b, a (ranging from 0-255) into an ALLEGRO_COLOR(3). +.PP +This function can be called before Allegro is initialized. +.SH SEE ALSO +.PP +al_map_rgb(3), al_premul_rgba(3), al_map_rgb_f(3) diff --git a/allegro/docs/man/al_map_rgba_f.3 b/allegro/docs/man/al_map_rgba_f.3 new file mode 100644 index 00000000..4cb91903 --- /dev/null +++ b/allegro/docs/man/al_map_rgba_f.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_map_rgba_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_map_rgba_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_map_rgba_f(float r, float g, float b, float a) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert r, g, b, a (ranging from 0.0f-1.0f) into an ALLEGRO_COLOR(3). +.PP +This function can be called before Allegro is initialized. +.SH SEE ALSO +.PP +al_map_rgba(3), al_premul_rgba_f(3), al_map_rgb_f(3) diff --git a/allegro/docs/man/al_merge_config.3 b/allegro/docs/man/al_merge_config.3 new file mode 100644 index 00000000..16e29524 --- /dev/null +++ b/allegro/docs/man/al_merge_config.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_merge_config" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_merge_config - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_CONFIG *al_merge_config(const ALLEGRO_CONFIG *cfg1, + const ALLEGRO_CONFIG *cfg2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Merge two configuration structures, and return the result as a new +configuration. +Values in configuration `cfg2' override those in `cfg1'. +Neither of the input configuration structures are modified. +Comments from `cfg2' are not retained. +.SH SEE ALSO +.PP +al_merge_config_into(3) diff --git a/allegro/docs/man/al_merge_config_into.3 b/allegro/docs/man/al_merge_config_into.3 new file mode 100644 index 00000000..02158427 --- /dev/null +++ b/allegro/docs/man/al_merge_config_into.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_merge_config_into" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_merge_config_into - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_merge_config_into(ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add) +\f[R] +.fi +.SH DESCRIPTION +.PP +Merge one configuration structure into another. +Values in configuration `add' override those in `master'. +`master' is modified. +Comments from `add' are not retained. +.SH SEE ALSO +.PP +al_merge_config(3) diff --git a/allegro/docs/man/al_mouse_button_down.3 b/allegro/docs/man/al_mouse_button_down.3 new file mode 100644 index 00000000..2bf7cffc --- /dev/null +++ b/allegro/docs/man/al_mouse_button_down.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_mouse_button_down" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_mouse_button_down - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_mouse_button_down(const ALLEGRO_MOUSE_STATE *state, int button) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true if the mouse button specified was held down in the state +specified. +Unlike most things, the first mouse button is numbered 1. +.SH SEE ALSO +.PP +ALLEGRO_MOUSE_STATE(3), al_get_mouse_state(3), +al_get_mouse_state_axis(3) diff --git a/allegro/docs/man/al_open_directory.3 b/allegro/docs/man/al_open_directory.3 new file mode 100644 index 00000000..8a855cfd --- /dev/null +++ b/allegro/docs/man/al_open_directory.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_open_directory" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_open_directory - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_open_directory(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Opens a directory entry object. +You must call this before using al_read_directory(3) on an entry and you +must call al_close_directory(3) when you no longer need it. +.PP +Returns true on success. +.SH SEE ALSO +.PP +al_read_directory(3), al_close_directory(3) diff --git a/allegro/docs/man/al_open_fs_entry.3 b/allegro/docs/man/al_open_fs_entry.3 new file mode 100644 index 00000000..d2ddabc8 --- /dev/null +++ b/allegro/docs/man/al_open_fs_entry.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_open_fs_entry" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_open_fs_entry - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILE *al_open_fs_entry(ALLEGRO_FS_ENTRY *e, const char *mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Open an ALLEGRO_FILE(3) handle to a filesystem entry, for the given +access mode. +This is like calling al_fopen(3) with the name of the filesystem entry, +but uses the appropriate file interface, not whatever was set with the +latest call to al_set_new_file_interface(3). +.PP +Returns the handle on success, NULL on error. +.SH SEE ALSO +.PP +al_fopen(3) diff --git a/allegro/docs/man/al_open_memfile.3 b/allegro/docs/man/al_open_memfile.3 new file mode 100644 index 00000000..198112e0 --- /dev/null +++ b/allegro/docs/man/al_open_memfile.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_open_memfile" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_open_memfile - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FILE *al_open_memfile(void *mem, int64_t size, const char *mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns a file handle to the block of memory. +All read and write operations act upon the memory directly, so it must +not be freed while the file remains open. +.PP +The mode can be any combination of \[lq]r\[rq] (readable) and +\[lq]w\[rq] (writable). +Regardless of the mode, the file always opens at position 0. +The file size is fixed and cannot be expanded. +The file is always read from/written to in binary mode, which means that +no newline translation is performed. +.PP +It should be closed with al_fclose(3). +After the file is closed, you are responsible for freeing the memory (if +needed). diff --git a/allegro/docs/man/al_open_native_text_log.3 b/allegro/docs/man/al_open_native_text_log.3 new file mode 100644 index 00000000..66795c68 --- /dev/null +++ b/allegro/docs/man/al_open_native_text_log.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_open_native_text_log" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_open_native_text_log - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_TEXTLOG *al_open_native_text_log(char const *title, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Opens a window to which you can append log messages with +al_append_native_text_log(3). +This can be useful for debugging if you don\[cq]t want to depend on a +console being available. +.PP +Use al_close_native_text_log(3) to close the window again. +.PP +The flags available are: +.TP +ALLEGRO_TEXTLOG_NO_CLOSE +Prevent the window from having a close button. +Otherwise, if the close button is pressed, an event is generated; see +al_get_native_text_log_event_source(3). +.TP +ALLEGRO_TEXTLOG_MONOSPACE +Use a monospace font to display the text. +.PP +Returns NULL if there was an error opening the window, or if text log +windows are not implemented on the platform. +.SH SEE ALSO +.PP +al_append_native_text_log(3), al_close_native_text_log(3) diff --git a/allegro/docs/man/al_open_video.3 b/allegro/docs/man/al_open_video.3 new file mode 100644 index 00000000..312f38d4 --- /dev/null +++ b/allegro/docs/man/al_open_video.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_open_video" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_open_video - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_VIDEO *al_open_video(char const *filename) +\f[R] +.fi +.SH DESCRIPTION +.PP +Reads a video file. +This does not start streaming yet but reads the meta info so you can +query e.g.\ the size or audio rate. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_orthographic_transform.3 b/allegro/docs/man/al_orthographic_transform.3 new file mode 100644 index 00000000..be83f136 --- /dev/null +++ b/allegro/docs/man/al_orthographic_transform.3 @@ -0,0 +1,50 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_orthographic_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_orthographic_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_orthographic_transform(ALLEGRO_TRANSFORM *trans, + float left, float top, float n, + float right, float bottom, float f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Combines the given transformation with an orthographic transformation +which maps the screen rectangle to the given left/top and right/bottom +coordinates. +.PP +near/far is the z range, coordinates outside of that range will get +clipped. +Normally -1/1 is fine because all 2D graphics will have a z coordinate +of 0. +However if you for example do al_draw_rectangle(0, 0, 100, 100) and +rotate around the x axis (\[lq]towards the screen\[rq]) make sure your z +range allows values from -100 to 100 or the rotated rectangle will get +clipped. +.PP +Also, if you are using a depth buffer the z range decides the depth +resolution. +For example if you have a 16 bit depth buffer there are only 65536 +discrete depth values. +So if your near/far is set to -1000000/1000000 most of the z positions +would not result in separate depth values which could lead to artifacts. +.PP +The result of applying this transformation to coordinates will be to +normalize visible coordinates into the cube from -1/-1/-1 to 1/1/1. +Such a transformation is mostly useful for passing it to +al_use_projection_transform(3) - see that function for an example use. +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +al_use_projection_transform(3), al_perspective_transform(3) diff --git a/allegro/docs/man/al_osx_get_window.3 b/allegro/docs/man/al_osx_get_window.3 new file mode 100644 index 00000000..aeb7a74a --- /dev/null +++ b/allegro/docs/man/al_osx_get_window.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_osx_get_window" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_osx_get_window - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +NSWindow* al_osx_get_window(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves the NSWindow handle associated with the Allegro display. +.SH SINCE +.PP +5.0.8, 5.1.3 diff --git a/allegro/docs/man/al_path_cstr.3 b/allegro/docs/man/al_path_cstr.3 new file mode 100644 index 00000000..c6a03ada --- /dev/null +++ b/allegro/docs/man/al_path_cstr.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_path_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_path_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const char *al_path_cstr(const ALLEGRO_PATH *path, char delim) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert a path to its string representation, i.e.\ optional drive, +followed by directory components separated by `delim', followed by an +optional filename. +.PP +To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP +for `delim'. +.PP +The returned pointer is valid only until the path is modified in any +way, or until the path is destroyed. +This returns a null-terminated string. +If you need an ALLEGRO_USTR instead, use al_path_ustr(3). +.SH SEE ALSO +.PP +al_path_ustr(3) diff --git a/allegro/docs/man/al_path_ustr.3 b/allegro/docs/man/al_path_ustr.3 new file mode 100644 index 00000000..3b37d185 --- /dev/null +++ b/allegro/docs/man/al_path_ustr.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_path_ustr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_path_ustr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_USTR *al_path_ustr(const ALLEGRO_PATH *path, char delim) +\f[R] +.fi +.SH DESCRIPTION +.PP +Convert a path to its string representation, i.e.\ optional drive, +followed by directory components separated by `delim', followed by an +optional filename. +.PP +To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP +for `delim'. +.PP +The returned pointer is valid only until the path is modified in any +way, or until the path is destroyed. +This returns an ALLEGRO_USTR. +If you need a null-terminated string instead, use al_path_cstr(3). +.SH SINCE +.PP +5.2.3 +.SH SEE ALSO +.PP +al_path_cstr(3) diff --git a/allegro/docs/man/al_pause_event_queue.3 b/allegro/docs/man/al_pause_event_queue.3 new file mode 100644 index 00000000..3a5935ba --- /dev/null +++ b/allegro/docs/man/al_pause_event_queue.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_pause_event_queue" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_pause_event_queue - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_pause_event_queue(ALLEGRO_EVENT_QUEUE *queue, bool pause) +\f[R] +.fi +.SH DESCRIPTION +.PP +Pause or resume accepting new events into the event queue (to resume, +pass false for \f[C]pause\f[R]). +Events already in the queue are unaffected. +.PP +While a queue is paused, any events which would be entered into the +queue are simply ignored. +This is an alternative to unregistering then re-registering all event +sources from the event queue, if you just need to prevent events piling +up in the queue for a while. +.SH SEE ALSO +.PP +al_is_event_queue_paused(3) +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_peek_next_event.3 b/allegro/docs/man/al_peek_next_event.3 new file mode 100644 index 00000000..1a30c98b --- /dev/null +++ b/allegro/docs/man/al_peek_next_event.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_peek_next_event" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_peek_next_event - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_peek_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) +\f[R] +.fi +.SH DESCRIPTION +.PP +Copy the contents of the next event in the event queue specified into +\f[C]ret_event\f[R] and return true. +The original event packet will remain at the head of the queue. +If the event queue is actually empty, this function returns false and +the contents of \f[C]ret_event\f[R] are unspecified. +.SH SEE ALSO +.PP +ALLEGRO_EVENT(3), al_get_next_event(3), al_drop_next_event(3) diff --git a/allegro/docs/man/al_perspective_transform.3 b/allegro/docs/man/al_perspective_transform.3 new file mode 100644 index 00000000..54dddec4 --- /dev/null +++ b/allegro/docs/man/al_perspective_transform.3 @@ -0,0 +1,112 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_perspective_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_perspective_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_perspective_transform(ALLEGRO_TRANSFORM *trans, + float left, float top, float n, + float right, float bottom, float f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_orthographic_transform(3) but honors perspective. +If everything is at a z-position of -near it will look the same as with +an orthographic transformation. +.PP +To use a specific horizontal field of view you can use the relation: +.IP +.nf +\f[C] +tan(hfov / 2) = (right - left) / 2 / near +\f[R] +.fi +.PP +and therefore +.IP +.nf +\f[C] +near = (right - left) / 2 / tan(hfov / 2) +\f[R] +.fi +.PP +Example 1: +.IP +.nf +\f[C] + float w = 800, h = 450; // assume our display is 800 x 450 + float fov = tan(90 * ALLEGRO_PI / 180 / 2); // 90 degree field of view + + // Our projection goes from 0/0 to w/h with the near parameter set + // for a 90 degree horizontal viewing angle. + ALLEGRO_TRANSFORM projection; + al_identity_transform(&projection); + al_perspective_transform(&projection, 0, 0, + w / 2 / fov, + w, h, + 2000); + al_use_projection_transform(&projection); + + // Set the camera z to +400 (which is exactly the near distance) + ALLEGRO_TRANSFORM camera; + al_build_camera_transform(&camera, 0, 0, 400, 0, 0, 0, 0, 1, 0); + al_use_transform(&camera); + + // This will draw two rectangles at the left and right edge of the + // screen and vertically centered. The x distance between them is 800 + // units, but the camera transform moves them 400 along z, so with + // a 90\[de] viewing angle both are visible. + al_draw_filled_rectangle(0, 200, 50, 250, red; + al_draw_filled_rectangle(750, 200, 800, 250, red); +\f[R] +.fi +.PP +Example 2: +.IP +.nf +\f[C] + float w = 800, h = 450; // assume our display is 800 x 450 + float fov = tan(90 * ALLEGRO_PI / 180 / 2); // 90 degree field of view + float aspect = h / w; + float zoom = 2; // enlarge x 2 + + // This projection is very different from the one in the first example. + // Here we map the left and right edge of the screen to -1 and +1. And + // the y axis goes from -1 at the bottom to +1 at the top, scaled by + // the aspect ratio. We also add a zoom parameter so we can control + // the visible portion of the scene independent of the field of view. + ALLEGRO_TRANSFORM projection; + al_identity_transform(&projection); + al_perspective_transform(&projection, + -1 / zoom, aspect / zoom, + 1 / fov, + 1 / zoom, -aspect / zoom, + 2000); + al_use_projection_transform(&projection); + + // Moves everything by -4 in the z direction. + ALLEGRO_TRANSFORM camera; + al_build_camera_transform(&camera, 0, 0, 4, 0, 0, 0, 0, 1, 0); + al_use_transform(&camera); + + // At a z distance of 4 with a 90\[de] hfov everything would be scaled + // down to 25%. However we also zoom 2-fold, so the final scaling is + // 50%. This rectangle therefore will appear at a size of 400 x 225 + // pixel (assuming the display is 800 x 450). + al_draw_filled_rectangle(-1, -1, 1, 1, red); +\f[R] +.fi +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +al_use_projection_transform(3), al_orthographic_transform(3) diff --git a/allegro/docs/man/al_play_haptic_effect.3 b/allegro/docs/man/al_play_haptic_effect.3 new file mode 100644 index 00000000..39c9434f --- /dev/null +++ b/allegro/docs/man/al_play_haptic_effect.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_play_haptic_effect" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_play_haptic_effect - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_play_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop) +\f[R] +.fi +.SH DESCRIPTION +.PP +Plays back a previously uploaded haptic effect. +The play_id must be a valid ALLEGRO_HAPTIC_EFFECT_ID(3) obtained from +al_upload_haptic_effect(3), al_upload_and_play_haptic_effect(3) or +al_rumble_haptic(3). +.PP +The haptic effect will be played back loop times in sequence. +If loop is less than or equal to 1, then the effect will be played once +only. +.PP +This function returns immediately and doesn\[cq]t wait for the playback +to finish. +It returns true if the playback was started successfully or false if +not. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_play_sample.3 b/allegro/docs/man/al_play_sample.3 new file mode 100644 index 00000000..539198a8 --- /dev/null +++ b/allegro/docs/man/al_play_sample.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_play_sample" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_play_sample - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_play_sample(ALLEGRO_SAMPLE *spl, float gain, float pan, float speed, + ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Plays a sample on one of the sample instances created by +al_reserve_samples(3). +Returns true on success, false on failure. +Playback may fail because all the reserved sample instances are +currently used. +.PP +Parameters: +.IP \[bu] 2 +gain - relative volume at which the sample is played; 1.0 is normal. +.IP \[bu] 2 +pan - 0.0 is centred, -1.0 is left, 1.0 is right, or +ALLEGRO_AUDIO_PAN_NONE. +.IP \[bu] 2 +speed - relative speed at which the sample is played; 1.0 is normal. +.IP \[bu] 2 +loop - ALLEGRO_PLAYMODE_ONCE, ALLEGRO_PLAYMODE_LOOP, or +ALLEGRO_PLAYMODE_BIDIR +.IP \[bu] 2 +ret_id - if non-NULL the variable which this points to will be assigned +an id representing the sample being played. +If al_play_sample(3) returns \f[C]false\f[R], then the contents of +ret_id are invalid and must not be used as argument to other functions. +.SH SEE ALSO +.PP +ALLEGRO_PLAYMODE(3), ALLEGRO_AUDIO_PAN_NONE(3), ALLEGRO_SAMPLE_ID(3), +al_stop_sample(3), al_stop_samples(3), al_lock_sample_id(3). diff --git a/allegro/docs/man/al_play_sample_instance.3 b/allegro/docs/man/al_play_sample_instance.3 new file mode 100644 index 00000000..0b48405c --- /dev/null +++ b/allegro/docs/man/al_play_sample_instance.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_play_sample_instance" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_play_sample_instance - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_play_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Play the sample instance. +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_stop_sample_instance(3) diff --git a/allegro/docs/man/al_popup_menu.3 b/allegro/docs/man/al_popup_menu.3 new file mode 100644 index 00000000..c427e59f --- /dev/null +++ b/allegro/docs/man/al_popup_menu.3 @@ -0,0 +1,44 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_popup_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_popup_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_popup_menu(ALLEGRO_MENU *popup, ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Displays a context menu next to the mouse cursor. +The menu must have been created with al_create_popup_menu(3). +It generates events just like a regular display menu does. +It is possible that the menu will be canceled without any selection +being made. +.PP +The \f[C]display\f[R] parameter indicates which window the menu is +associated with (when you process the menu click event), but does not +actually affect where the menu is located on the screen. +.PP +Returns \f[C]true\f[R] if the context menu was displayed. +.RS +.PP +\f[I]Note:\f[R] On Linux this function will fail if any of the mouse +keys are held down. +I.e. +it will only reliably work if you handle it in +\f[C]ALLEGRO_MOUSE_BUTTON_UP\f[R] events and even then only if that +event corresponds to the final mouse button that was pressed. +.RE +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_create_popup_menu(3) diff --git a/allegro/docs/man/al_premul_rgba.3 b/allegro/docs/man/al_premul_rgba.3 new file mode 100644 index 00000000..db845c20 --- /dev/null +++ b/allegro/docs/man/al_premul_rgba.3 @@ -0,0 +1,49 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_premul_rgba" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_premul_rgba - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_premul_rgba( + unsigned char r, unsigned char g, unsigned char b, unsigned char a) +\f[R] +.fi +.SH DESCRIPTION +.PP +This is a shortcut for al_map_rgba(3)(r * a / 255, g * a / 255, b * a / +255, a). +.PP +By default Allegro uses pre-multiplied alpha for transparent blending of +bitmaps and primitives (see al_load_bitmap_flags(3) for a discussion of +that feature). +This means that if you want to tint a bitmap or primitive to be +transparent you need to multiply the color components by the alpha +components when you pass them to this function. +For example: +.IP +.nf +\f[C] +int r = 255; +int g = 0; +int b = 0; +int a = 127; +ALLEGRO_COLOR c = al_premul_rgba(r, g, b, a); +/* Draw the bitmap tinted red and half-transparent. */ +al_draw_tinted_bitmap(bmp, c, 0, 0, 0); +\f[R] +.fi +.PP +This function can be called before Allegro is initialized. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_map_rgba(3), al_premul_rgba_f(3) diff --git a/allegro/docs/man/al_premul_rgba_f.3 b/allegro/docs/man/al_premul_rgba_f.3 new file mode 100644 index 00000000..f648dda2 --- /dev/null +++ b/allegro/docs/man/al_premul_rgba_f.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_premul_rgba_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_premul_rgba_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_COLOR al_premul_rgba_f(float r, float g, float b, float a) +\f[R] +.fi +.SH DESCRIPTION +.PP +This is a shortcut for al_map_rgba_f(3)(r * a, g * a, b * a, a). +.PP +By default Allegro uses pre-multiplied alpha for transparent blending of +bitmaps and primitives (see al_load_bitmap_flags(3) for a discussion of +that feature). +This means that if you want to tint a bitmap or primitive to be +transparent you need to multiply the color components by the alpha +components when you pass them to this function. +For example: +.IP +.nf +\f[C] +float r = 1; +float g = 0; +float b = 0; +float a = 0.5; +ALLEGRO_COLOR c = al_premul_rgba_f(r, g, b, a); +/* Draw the bitmap tinted red and half-transparent. */ +al_draw_tinted_bitmap(bmp, c, 0, 0, 0); +\f[R] +.fi +.PP +This function can be called before Allegro is initialized. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_map_rgba_f(3), al_premul_rgba(3) diff --git a/allegro/docs/man/al_put_blended_pixel.3 b/allegro/docs/man/al_put_blended_pixel.3 new file mode 100644 index 00000000..87a5eace --- /dev/null +++ b/allegro/docs/man/al_put_blended_pixel.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_put_blended_pixel" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_put_blended_pixel - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_put_blended_pixel(int x, int y, ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_put_pixel(3), but the pixel color is blended using the current +blenders before being drawn. +.SH SEE ALSO +.PP +ALLEGRO_COLOR(3), al_put_pixel(3) diff --git a/allegro/docs/man/al_put_pixel.3 b/allegro/docs/man/al_put_pixel.3 new file mode 100644 index 00000000..0d2be801 --- /dev/null +++ b/allegro/docs/man/al_put_pixel.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_put_pixel" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_put_pixel - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_put_pixel(int x, int y, ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Draw a single pixel on the target bitmap. +This operation is slow on non-memory bitmaps. +Consider locking the bitmap if you are going to use this function +multiple times on the same bitmap. +This function is not affected by the transformations or the color +blenders. +.SH SEE ALSO +.PP +ALLEGRO_COLOR(3), al_get_pixel(3), al_put_blended_pixel(3), +al_lock_bitmap(3) diff --git a/allegro/docs/man/al_radtofix_r.3 b/allegro/docs/man/al_radtofix_r.3 new file mode 100644 index 00000000..731fbac8 --- /dev/null +++ b/allegro/docs/man/al_radtofix_r.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_radtofix_r" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_radtofix_r - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const al_fixed al_radtofix_r = (al_fixed)2670177; +\f[R] +.fi +.SH DESCRIPTION +.PP +This constant gives a ratio which can be used to convert a fixed point +number in radians to a fixed point number in binary angle format. +.PP +Example: +.IP +.nf +\f[C] + al_fixed rad_angle, binary_angle; + ... + binary_angle = al_fixmul(rad_angle, radtofix_r); +\f[R] +.fi +.SH SEE ALSO +.PP +al_fixmul(3), al_fixtorad_r(3). diff --git a/allegro/docs/man/al_read_directory.3 b/allegro/docs/man/al_read_directory.3 new file mode 100644 index 00000000..40ae6f32 --- /dev/null +++ b/allegro/docs/man/al_read_directory.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_read_directory" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_read_directory - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_FS_ENTRY *al_read_directory(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Reads the next directory item and returns a filesystem entry for it. +.PP +Returns NULL if there are no more entries or if an error occurs. +Call al_destroy_fs_entry(3) on the returned entry when you are done with +it. +.PP +This function will ignore any files or directories named \f[C].\f[R] or +\f[C]..\f[R] which may exist on certain platforms and may signify the +current and the parent directory. +.SH SEE ALSO +.PP +al_open_directory(3), al_close_directory(3) diff --git a/allegro/docs/man/al_realloc.3 b/allegro/docs/man/al_realloc.3 new file mode 100644 index 00000000..2207cf46 --- /dev/null +++ b/allegro/docs/man/al_realloc.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_realloc" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_realloc - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +#define al_realloc(p, n) \[rs] + (al_realloc_with_context((p), (n), __LINE__, __FILE__, __func__)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like realloc() in the C standard library, but the implementation may be +overridden. +.PP +This is a macro. +.SH SEE ALSO +.PP +al_malloc(3), al_realloc_with_context(3) diff --git a/allegro/docs/man/al_realloc_with_context.3 b/allegro/docs/man/al_realloc_with_context.3 new file mode 100644 index 00000000..1b2f3ec4 --- /dev/null +++ b/allegro/docs/man/al_realloc_with_context.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_realloc_with_context" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_realloc_with_context - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void *al_realloc_with_context(void *ptr, size_t n, + int line, const char *file, const char *func) +\f[R] +.fi +.SH DESCRIPTION +.PP +This calls realloc() from the Allegro library (this matters on Windows), +unless overridden with al_set_memory_interface(3), +.PP +Generally you should use the al_realloc(3) macro. diff --git a/allegro/docs/man/al_rebase_path.3 b/allegro/docs/man/al_rebase_path.3 new file mode 100644 index 00000000..c9d5e86a --- /dev/null +++ b/allegro/docs/man/al_rebase_path.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_rebase_path" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_rebase_path - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_rebase_path(const ALLEGRO_PATH *head, ALLEGRO_PATH *tail) +\f[R] +.fi +.SH DESCRIPTION +.PP +Concatenate two path structures, modifying the second path structure. +If \f[I]tail\f[R] is an absolute path, this function does nothing. +Otherwise, the drive and path components in \f[I]head\f[R] are inserted +at the start of \f[I]tail\f[R]. +.PP +For example, if \f[I]head\f[R] is \[lq]/anchor/\[rq] and \f[I]tail\f[R] +is \[lq]data/file.ext\[rq], then after the call \f[I]tail\f[R] becomes +\[lq]/anchor/data/file.ext\[rq]. +.SH SEE ALSO +.PP +al_join_paths(3) diff --git a/allegro/docs/man/al_reconfigure_joysticks.3 b/allegro/docs/man/al_reconfigure_joysticks.3 new file mode 100644 index 00000000..03a1d076 --- /dev/null +++ b/allegro/docs/man/al_reconfigure_joysticks.3 @@ -0,0 +1,47 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_reconfigure_joysticks" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_reconfigure_joysticks - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_reconfigure_joysticks(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Allegro is able to cope with users connecting and disconnected joystick +devices on-the-fly. +On existing platforms, the joystick event source will generate an event +of type \f[C]ALLEGRO_EVENT_JOYSTICK_CONFIGURATION\f[R] when a device is +plugged in or unplugged. +In response, you should call al_reconfigure_joysticks(3). +.PP +Afterwards, the number returned by al_get_num_joysticks(3) may be +different, and the handles returned by al_get_joystick(3) may be +different or be ordered differently. +.PP +All ALLEGRO_JOYSTICK(3) handles remain valid, but handles for +disconnected devices become inactive: their states will no longer +update, and al_get_joystick(3) will not return the handle. +Handles for devices which remain connected will continue to represent +the same devices. +Previously inactive handles may become active again, being reused to +represent newly connected devices. +.PP +Returns true if the joystick configuration changed, otherwise returns +false. +.PP +It is possible that on some systems, Allegro won\[cq]t be able to +generate \f[C]ALLEGRO_EVENT_JOYSTICK_CONFIGURATION\f[R] events. +If your game has an input configuration screen or similar, you may wish +to call al_reconfigure_joysticks(3) when entering that screen. +.SH SEE ALSO +.PP +al_get_joystick_event_source(3), ALLEGRO_EVENT(3) diff --git a/allegro/docs/man/al_ref_buffer.3 b/allegro/docs/man/al_ref_buffer.3 new file mode 100644 index 00000000..fcf38d65 --- /dev/null +++ b/allegro/docs/man/al_ref_buffer.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ref_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ref_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_USTR *al_ref_buffer(ALLEGRO_USTR_INFO *info, const char *s, size_t size) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a string that references the storage of an underlying buffer. +The size of the buffer is given in bytes. +You can use it to reference only part of a string or an arbitrary region +of memory. +.PP +The string is valid while the underlying memory buffer is valid. +.SH SEE ALSO +.PP +al_ref_cstr(3), al_ref_ustr(3) diff --git a/allegro/docs/man/al_ref_cstr.3 b/allegro/docs/man/al_ref_cstr.3 new file mode 100644 index 00000000..729004c4 --- /dev/null +++ b/allegro/docs/man/al_ref_cstr.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ref_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ref_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_USTR *al_ref_cstr(ALLEGRO_USTR_INFO *info, const char *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a string that references the storage of a C-style string. +The information about the string (e.g.\ its size) is stored in the +structure pointed to by the \f[C]info\f[R] parameter. +The string will not have any other storage allocated of its own, so if +you allocate the \f[C]info\f[R] structure on the stack then no explicit +\[lq]free\[rq] operation is required. +.PP +The string is valid until the underlying C string disappears. +.PP +Example: +.IP +.nf +\f[C] +ALLEGRO_USTR_INFO info; +ALLEGRO_USTR *us = al_ref_cstr(&info, \[dq]my string\[dq]); +\f[R] +.fi +.SH SEE ALSO +.PP +al_ref_buffer(3), al_ref_ustr(3) diff --git a/allegro/docs/man/al_ref_ustr.3 b/allegro/docs/man/al_ref_ustr.3 new file mode 100644 index 00000000..d0650ad3 --- /dev/null +++ b/allegro/docs/man/al_ref_ustr.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ref_ustr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ref_ustr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_USTR *al_ref_ustr(ALLEGRO_USTR_INFO *info, const ALLEGRO_USTR *us, + int start_pos, int end_pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a read-only string that references the storage of another +ALLEGRO_USTR(3) string. +The information about the string (e.g.\ its size) is stored in the +structure pointed to by the \f[C]info\f[R] parameter. +The new string will not have any other storage allocated of its own, so +if you allocate the \f[C]info\f[R] structure on the stack then no +explicit \[lq]free\[rq] operation is required. +.PP +The referenced interval is [\f[C]start_pos\f[R], \f[C]end_pos\f[R]). +Both are byte offsets. +.PP +The string is valid until the underlying string is modified or +destroyed. +.PP +If you need a range of code-points instead of bytes, use +al_ustr_offset(3) to find the byte offsets. +.SH SEE ALSO +.PP +al_ref_cstr(3), al_ref_buffer(3) diff --git a/allegro/docs/man/al_register_assert_handler.3 b/allegro/docs/man/al_register_assert_handler.3 new file mode 100644 index 00000000..040c5038 --- /dev/null +++ b/allegro/docs/man/al_register_assert_handler.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_assert_handler" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_assert_handler - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_register_assert_handler(void (*handler)(char const *expr, + char const *file, int line, char const *func)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a function to be called when an internal Allegro assertion +fails. +Pass NULL to reset to the default behaviour, which is to do whatever the +standard \f[C]assert()\f[R] macro does. +.SH SINCE +.PP +5.0.6, 5.1.0 diff --git a/allegro/docs/man/al_register_audio_stream_loader.3 b/allegro/docs/man/al_register_audio_stream_loader.3 new file mode 100644 index 00000000..dc505066 --- /dev/null +++ b/allegro/docs/man/al_register_audio_stream_loader.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_audio_stream_loader" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_audio_stream_loader - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_audio_stream_loader(const char *ext, + ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename, + size_t buffer_count, unsigned int samples)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_load_audio_stream(3). +The given function will be used to open streams from files with the +given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]stream_loader\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_audio_stream_loader_f(3) diff --git a/allegro/docs/man/al_register_audio_stream_loader_f.3 b/allegro/docs/man/al_register_audio_stream_loader_f.3 new file mode 100644 index 00000000..84e6de94 --- /dev/null +++ b/allegro/docs/man/al_register_audio_stream_loader_f.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_audio_stream_loader_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_audio_stream_loader_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_audio_stream_loader_f(const char *ext, + ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE* fp, + size_t buffer_count, unsigned int samples)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_load_audio_stream_f(3). +The given function will be used to open streams from files with the +given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]stream_loader\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_audio_stream_loader(3) diff --git a/allegro/docs/man/al_register_bitmap_identifier.3 b/allegro/docs/man/al_register_bitmap_identifier.3 new file mode 100644 index 00000000..9f9ca7ab --- /dev/null +++ b/allegro/docs/man/al_register_bitmap_identifier.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_bitmap_identifier" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_bitmap_identifier - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_bitmap_identifier(const char *extension, + bool (*identifier)(ALLEGRO_FILE *f)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register an identify handler for al_identify_bitmap(3). +The given function will be used to detect files for the given extension. +It will be called with a single argument of type ALLEGRO_FILE(3) which +is a file handle opened for reading and located at the first byte of the +file. +The handler should try to read as few bytes as possible to safely +determine if the given file contents correspond to the type with the +extension and return true in that case, false otherwise. +The file handle must not be closed but there is no need to reset it to +the beginning. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]identifier\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_identify_bitmap(3) diff --git a/allegro/docs/man/al_register_bitmap_loader.3 b/allegro/docs/man/al_register_bitmap_loader.3 new file mode 100644 index 00000000..a7bd11dd --- /dev/null +++ b/allegro/docs/man/al_register_bitmap_loader.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_bitmap_loader" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_bitmap_loader - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_bitmap_loader(const char *extension, + ALLEGRO_BITMAP *(*loader)(const char *filename, int flags)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_load_bitmap(3). +The given function will be used to handle the loading of bitmaps files +with the given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]loader\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_bitmap_saver(3), al_register_bitmap_loader_f(3) diff --git a/allegro/docs/man/al_register_bitmap_loader_f.3 b/allegro/docs/man/al_register_bitmap_loader_f.3 new file mode 100644 index 00000000..71d56088 --- /dev/null +++ b/allegro/docs/man/al_register_bitmap_loader_f.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_bitmap_loader_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_bitmap_loader_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_bitmap_loader_f(const char *extension, + ALLEGRO_BITMAP *(*fs_loader)(ALLEGRO_FILE *fp, int flags)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_load_bitmap_f(3). +The given function will be used to handle the loading of bitmaps files +with the given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]fs_loader\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_bitmap_loader(3) diff --git a/allegro/docs/man/al_register_bitmap_saver.3 b/allegro/docs/man/al_register_bitmap_saver.3 new file mode 100644 index 00000000..46647a53 --- /dev/null +++ b/allegro/docs/man/al_register_bitmap_saver.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_bitmap_saver" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_bitmap_saver - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_bitmap_saver(const char *extension, + bool (*saver)(const char *filename, ALLEGRO_BITMAP *bmp)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_save_bitmap(3). +The given function will be used to handle the saving of bitmaps files +with the given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]saver\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_bitmap_loader(3), al_register_bitmap_saver_f(3) diff --git a/allegro/docs/man/al_register_bitmap_saver_f.3 b/allegro/docs/man/al_register_bitmap_saver_f.3 new file mode 100644 index 00000000..4e482633 --- /dev/null +++ b/allegro/docs/man/al_register_bitmap_saver_f.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_bitmap_saver_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_bitmap_saver_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_bitmap_saver_f(const char *extension, + bool (*fs_saver)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_save_bitmap_f(3). +The given function will be used to handle the saving of bitmaps files +with the given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]saver_f\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_bitmap_saver(3) diff --git a/allegro/docs/man/al_register_event_source.3 b/allegro/docs/man/al_register_event_source.3 new file mode 100644 index 00000000..5e11a50f --- /dev/null +++ b/allegro/docs/man/al_register_event_source.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT_SOURCE *source) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register the event source with the event queue specified. +An event source may be registered with any number of event queues +simultaneously, or none. +Trying to register an event source with the same event queue more than +once does nothing. +.SH SEE ALSO +.PP +al_unregister_event_source(3), ALLEGRO_EVENT_SOURCE(3) diff --git a/allegro/docs/man/al_register_font_loader.3 b/allegro/docs/man/al_register_font_loader.3 new file mode 100644 index 00000000..6a1e3b4b --- /dev/null +++ b/allegro/docs/man/al_register_font_loader.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_font_loader" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_font_loader - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_font_loader(char const *extension, + ALLEGRO_FONT *(*load_font)(char const *filename, int size, int flags)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Informs Allegro of a new font file type, telling it how to load files of +this format. +.PP +The \f[C]extension\f[R] should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]load_font\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_init_font_addon(3) diff --git a/allegro/docs/man/al_register_sample_loader.3 b/allegro/docs/man/al_register_sample_loader.3 new file mode 100644 index 00000000..a8850e43 --- /dev/null +++ b/allegro/docs/man/al_register_sample_loader.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_sample_loader" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_sample_loader - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_sample_loader(const char *ext, + ALLEGRO_SAMPLE *(*loader)(const char *filename)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_load_sample(3). +The given function will be used to handle the loading of sample files +with the given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]loader\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_sample_loader_f(3), al_register_sample_saver(3) diff --git a/allegro/docs/man/al_register_sample_loader_f.3 b/allegro/docs/man/al_register_sample_loader_f.3 new file mode 100644 index 00000000..16ae89cd --- /dev/null +++ b/allegro/docs/man/al_register_sample_loader_f.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_sample_loader_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_sample_loader_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_sample_loader_f(const char *ext, + ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE* fp)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_load_sample_f(3). +The given function will be used to handle the loading of sample files +with the given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]loader\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_sample_loader(3) diff --git a/allegro/docs/man/al_register_sample_saver.3 b/allegro/docs/man/al_register_sample_saver.3 new file mode 100644 index 00000000..5021c487 --- /dev/null +++ b/allegro/docs/man/al_register_sample_saver.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_sample_saver" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_sample_saver - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_sample_saver(const char *ext, + bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_save_sample(3). +The given function will be used to handle the saving of sample files +with the given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]saver\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_sample_saver_f(3), al_register_sample_loader(3) diff --git a/allegro/docs/man/al_register_sample_saver_f.3 b/allegro/docs/man/al_register_sample_saver_f.3 new file mode 100644 index 00000000..23e0220b --- /dev/null +++ b/allegro/docs/man/al_register_sample_saver_f.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_sample_saver_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_sample_saver_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_register_sample_saver_f(const char *ext, + bool (*saver)(ALLEGRO_FILE* fp, ALLEGRO_SAMPLE *spl)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a handler for al_save_sample_f(3). +The given function will be used to handle the saving of sample files +with the given extension. +.PP +The extension should include the leading dot (`.') character. +It will be matched case-insensitively. +.PP +The \f[C]saver\f[R] argument may be NULL to unregister an entry. +.PP +Returns true on success, false on error. +Returns false if unregistering an entry that doesn\[cq]t exist. +.SH SEE ALSO +.PP +al_register_sample_saver(3) diff --git a/allegro/docs/man/al_register_trace_handler.3 b/allegro/docs/man/al_register_trace_handler.3 new file mode 100644 index 00000000..c3f70b20 --- /dev/null +++ b/allegro/docs/man/al_register_trace_handler.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_register_trace_handler" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_register_trace_handler - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_register_trace_handler(void (*handler)(char const *)) +\f[R] +.fi +.SH DESCRIPTION +.PP +Register a callback which is called whenever Allegro writes something to +its log files. +The default logging to allegro.log is disabled while this callback is +active. +Pass NULL to revert to the default logging. +.PP +This function may be called prior to al_install_system. +.PP +See the example allegro5.cfg for documentation on how to configure the +used debug channels, logging levels and trace format. +.SH SINCE +.PP +5.1.5 diff --git a/allegro/docs/man/al_release_haptic.3 b/allegro/docs/man/al_release_haptic.3 new file mode 100644 index 00000000..322019f2 --- /dev/null +++ b/allegro/docs/man/al_release_haptic.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_release_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_release_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_release_haptic(ALLEGRO_HAPTIC *haptic) +\f[R] +.fi +.SH DESCRIPTION +.PP +Releases the haptic device and its resources when it\[cq]s not needed +anymore. +Should also be used in case the joystick configuration changed, such as +when a joystick is hot plugged. +This function also automatically releases all haptic effects that are +still uploaded to the device and that have not been released manually +using al_release_haptic_effect(3). +.PP +Returns true on success or false if the haptic device couldn\[cq]t be +released for any reason, such as NULL being passed, the device not being +active or failure in the driver. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_release_haptic_effect.3 b/allegro/docs/man/al_release_haptic_effect.3 new file mode 100644 index 00000000..f88e3a38 --- /dev/null +++ b/allegro/docs/man/al_release_haptic_effect.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_release_haptic_effect" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_release_haptic_effect - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_release_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Releases a previously uploaded haptic effect from the device it has been +uploaded to, allowing for other effects to be uploaded. +The play_id must be a valid ALLEGRO_HAPTIC_EFFECT_ID(3) obtained from +al_upload_haptic_effect(3), al_upload_and_play_haptic_effect(3) or +al_rumble_haptic(3). +.PP +This function is called automatically when you call al_release_haptic(3) +on a ALLEGRO_HAPTIC(3) for all effects that are still uploaded to the +device. +Therefore this function is most useful if you want to upload and release +haptic effects dynamically, for example as a way to circumvent the limit +imposed by al_get_max_haptic_effects(3). +.PP +Returns true on success, false if the effect couldn\[cq]t be released +for any reason such as when NULL is passed, the effect is not active or +failure to release the effect by the driver. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_release_joystick.3 b/allegro/docs/man/al_release_joystick.3 new file mode 100644 index 00000000..8952b819 --- /dev/null +++ b/allegro/docs/man/al_release_joystick.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_release_joystick" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_release_joystick - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_release_joystick(ALLEGRO_JOYSTICK *joy) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function currently does nothing. +.SH SEE ALSO +.PP +al_get_joystick(3) diff --git a/allegro/docs/man/al_remove_config_key.3 b/allegro/docs/man/al_remove_config_key.3 new file mode 100644 index 00000000..c2935055 --- /dev/null +++ b/allegro/docs/man/al_remove_config_key.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_remove_config_key" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_remove_config_key - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_remove_config_key(ALLEGRO_CONFIG *config, char const *section, + char const *key) +\f[R] +.fi +.SH DESCRIPTION +.PP +Remove a key and its associated value in a section of a configuration. +.PP +Returns true if the entry was removed, or false if the entry did not +exist. +.SH SINCE +.PP +5.1.5 diff --git a/allegro/docs/man/al_remove_config_section.3 b/allegro/docs/man/al_remove_config_section.3 new file mode 100644 index 00000000..73222d2f --- /dev/null +++ b/allegro/docs/man/al_remove_config_section.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_remove_config_section" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_remove_config_section - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_remove_config_section(ALLEGRO_CONFIG *config, char const *section) +\f[R] +.fi +.SH DESCRIPTION +.PP +Remove a section of a configuration. +.PP +Returns true if the section was removed, or false if the section did not +exist. +.SH SINCE +.PP +5.1.5 diff --git a/allegro/docs/man/al_remove_display_menu.3 b/allegro/docs/man/al_remove_display_menu.3 new file mode 100644 index 00000000..f2782800 --- /dev/null +++ b/allegro/docs/man/al_remove_display_menu.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_remove_display_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_remove_display_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_MENU *al_remove_display_menu(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Detaches the menu associated with the display and returns it. +The menu can then be used on a different display. +.PP +If you simply want to destroy the active menu, you can call +al_set_display_menu(3) with a \f[C]NULL\f[R] menu. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_set_display_menu(3) diff --git a/allegro/docs/man/al_remove_filename.3 b/allegro/docs/man/al_remove_filename.3 new file mode 100644 index 00000000..40c7dbc0 --- /dev/null +++ b/allegro/docs/man/al_remove_filename.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_remove_filename" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_remove_filename - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_remove_filename(const char *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +Delete the given path from the filesystem, which may be a file or an +empty directory. +This is the same as al_remove_fs_entry(3), except it expects the path as +a string. +.PP +Returns true on success, and false on failure. +Allegro\[cq]s errno is filled in to indicate the error. +.SH SEE ALSO +.PP +al_remove_fs_entry(3) diff --git a/allegro/docs/man/al_remove_fs_entry.3 b/allegro/docs/man/al_remove_fs_entry.3 new file mode 100644 index 00000000..c0de0eba --- /dev/null +++ b/allegro/docs/man/al_remove_fs_entry.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_remove_fs_entry" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_remove_fs_entry - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_remove_fs_entry(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Delete this filesystem entry from the filesystem. +Only files and empty directories may be deleted. +.PP +Returns true on success, and false on failure, error is indicated in +Allegro\[cq]s errno. +.SH SEE ALSO +.PP +al_filename_exists(3) diff --git a/allegro/docs/man/al_remove_menu_item.3 b/allegro/docs/man/al_remove_menu_item.3 new file mode 100644 index 00000000..2a533908 --- /dev/null +++ b/allegro/docs/man/al_remove_menu_item.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_remove_menu_item" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_remove_menu_item - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_remove_menu_item(ALLEGRO_MENU *menu, int pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Removes the specified item from the menu and destroys it. +If the item contains a sub-menu, it too is destroyed. +Any references to it are invalidated. +If you want to preserve that sub-menu, you should first make a copy with +al_clone_menu(3). +.PP +This is safe to call on a menu that is currently being displayed. +.PP +Returns \f[C]true\f[R] if an item was removed. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_append_menu_item(3), al_insert_menu_item(3), al_destroy_menu(3) diff --git a/allegro/docs/man/al_remove_opengl_fbo.3 b/allegro/docs/man/al_remove_opengl_fbo.3 new file mode 100644 index 00000000..c167c7a3 --- /dev/null +++ b/allegro/docs/man/al_remove_opengl_fbo.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_remove_opengl_fbo" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_remove_opengl_fbo - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_remove_opengl_fbo(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Explicitly free an OpenGL FBO created for a bitmap, if it has one. +Usually you do not need to worry about freeing FBOs, unless you use +al_get_opengl_fbo(3). +.SH SEE ALSO +.PP +al_get_opengl_fbo(3), al_set_target_bitmap(3) diff --git a/allegro/docs/man/al_remove_path_component.3 b/allegro/docs/man/al_remove_path_component.3 new file mode 100644 index 00000000..e530e358 --- /dev/null +++ b/allegro/docs/man/al_remove_path_component.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_remove_path_component" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_remove_path_component - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_remove_path_component(ALLEGRO_PATH *path, int i) +\f[R] +.fi +.SH DESCRIPTION +.PP +Delete the i\[cq]th directory component. +If the index is negative then count from the right, i.e.\ -1 refers to +the last path component. +It is an error to pass an index which is out of bounds. +.SH SEE ALSO +.PP +al_insert_path_component(3), al_replace_path_component(3), +al_drop_path_tail(3) diff --git a/allegro/docs/man/al_reparent_bitmap.3 b/allegro/docs/man/al_reparent_bitmap.3 new file mode 100644 index 00000000..ccda9dbd --- /dev/null +++ b/allegro/docs/man/al_reparent_bitmap.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_reparent_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_reparent_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_reparent_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP *parent, + int x, int y, int w, int h) +\f[R] +.fi +.SH DESCRIPTION +.PP +For a sub-bitmap, changes the parent, position and size. +This is the same as destroying the bitmap and re-creating it with +al_create_sub_bitmap(3) - except the bitmap pointer stays the same. +This has many uses, for example an animation player could return a +single bitmap which can just be re-parented to different animation +frames without having to re-draw the contents. +Or a sprite atlas could re-arrange its sprites without having to +invalidate all existing bitmaps. +.SH SEE ALSO +.PP +al_create_sub_bitmap(3), al_get_parent_bitmap(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_replace_path_component.3 b/allegro/docs/man/al_replace_path_component.3 new file mode 100644 index 00000000..f25cd66f --- /dev/null +++ b/allegro/docs/man/al_replace_path_component.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_replace_path_component" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_replace_path_component - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_replace_path_component(ALLEGRO_PATH *path, int i, const char *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Replace the i\[cq]th directory component by another string. +If the index is negative then count from the right, i.e.\ -1 refers to +the last path component. +It is an error to pass an index which is out of bounds. +.SH SEE ALSO +.PP +al_insert_path_component(3), al_remove_path_component(3) diff --git a/allegro/docs/man/al_reserve_samples.3 b/allegro/docs/man/al_reserve_samples.3 new file mode 100644 index 00000000..f7d61171 --- /dev/null +++ b/allegro/docs/man/al_reserve_samples.3 @@ -0,0 +1,46 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_reserve_samples" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_reserve_samples - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_reserve_samples(int reserve_samples) +\f[R] +.fi +.SH DESCRIPTION +.PP +Reserves a number of sample instances, attaching them to the default +mixer. +If no default mixer is set when this function is called, then it will +create one and attach it to the default voice. +If no default voice has been set, it, too, will be created. +.PP +If you call this function a second time with a smaller number of +samples, then the excess internal sample instances will be destroyed +causing some sounds to stop and some instances returned by +al_lock_sample_id(3) to be invalidated. +.PP +This diagram illustrates the structures that are set up: +.IP +.nf +\f[C] + sample instance 1 + / sample instance 2 +default voice <-- default mixer <--- . + \[rs] . + sample instance N +\f[R] +.fi +.PP +Returns true on success, false on error. +al_install_audio(3) must have been called first. +.SH SEE ALSO +.PP +al_set_default_mixer(3), al_play_sample(3) diff --git a/allegro/docs/man/al_reset_bitmap_blender.3 b/allegro/docs/man/al_reset_bitmap_blender.3 new file mode 100644 index 00000000..b96b21af --- /dev/null +++ b/allegro/docs/man/al_reset_bitmap_blender.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_reset_bitmap_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_reset_bitmap_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_reset_bitmap_blender(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Resets the blender for this bitmap to the default. +After resetting the bitmap blender, the values set for +al_set_bitmap_blender(3)/al_set_separate_bitmap_blender(3) will be used +instead. +.SH SINCE +.PP +5.2.5 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE +.SH SEE ALSO +.PP +al_set_bitmap_blender(3) diff --git a/allegro/docs/man/al_reset_clipping_rectangle.3 b/allegro/docs/man/al_reset_clipping_rectangle.3 new file mode 100644 index 00000000..f7593b54 --- /dev/null +++ b/allegro/docs/man/al_reset_clipping_rectangle.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_reset_clipping_rectangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_reset_clipping_rectangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_reset_clipping_rectangle(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Equivalent to calling \[ga]al_set_clipping_rectangle(0, 0, w, h)\[cq] +where \f[I]w\f[R] and \f[I]h\f[R] are the width and height of the target +bitmap respectively. +.PP +Does nothing if there is no target bitmap. +.SH SEE ALSO +.PP +al_set_clipping_rectangle(3) +.SH SINCE +.PP +5.0.6, 5.1.0 diff --git a/allegro/docs/man/al_reset_new_display_options.3 b/allegro/docs/man/al_reset_new_display_options.3 new file mode 100644 index 00000000..03bb8634 --- /dev/null +++ b/allegro/docs/man/al_reset_new_display_options.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_reset_new_display_options" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_reset_new_display_options - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_reset_new_display_options(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +This undoes any previous call to al_set_new_display_option(3) on the +calling thread. diff --git a/allegro/docs/man/al_resize_display.3 b/allegro/docs/man/al_resize_display.3 new file mode 100644 index 00000000..e0ff5492 --- /dev/null +++ b/allegro/docs/man/al_resize_display.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_resize_display" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_resize_display - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_resize_display(ALLEGRO_DISPLAY *display, int width, int height) +\f[R] +.fi +.SH DESCRIPTION +.PP +Resize the display. +Returns true on success, or false on error. +This works on both fullscreen and windowed displays, regardless of the +ALLEGRO_RESIZABLE flag. +.PP +Adjusts the clipping rectangle to the full size of the backbuffer. +.SH SEE ALSO +.PP +al_acknowledge_resize(3) diff --git a/allegro/docs/man/al_rest.3 b/allegro/docs/man/al_rest.3 new file mode 100644 index 00000000..50aaa9c0 --- /dev/null +++ b/allegro/docs/man/al_rest.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_rest" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_rest - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_rest(double seconds) +\f[R] +.fi +.SH DESCRIPTION +.PP +Waits for the specified number of seconds. +This tells the system to pause the current thread for the given amount +of time. +With some operating systems, the accuracy can be in the order of 10ms. +That is, even +.IP +.nf +\f[C] +al_rest(0.000001) +\f[R] +.fi +.PP +might pause for something like 10ms. +Also see the section on Timer routines for easier ways to time your +program without using up all CPU. diff --git a/allegro/docs/man/al_restore_default_mixer.3 b/allegro/docs/man/al_restore_default_mixer.3 new file mode 100644 index 00000000..a65d0386 --- /dev/null +++ b/allegro/docs/man/al_restore_default_mixer.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_restore_default_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_restore_default_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_restore_default_mixer(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Restores Allegro\[cq]s default mixer and attaches it to the default +voice. +If the default mixer hasn\[cq]t been created before, it will be created. +If the default voice hasn\[cq]t been set via al_set_default_voice(3) or +created before, it will also be created. +All samples started with al_play_sample(3) will be stopped and all +sample instances returned by al_lock_sample_id(3) will be invalidated. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_get_default_mixer(3), al_set_default_mixer(3), al_reserve_samples(3). diff --git a/allegro/docs/man/al_restore_state.3 b/allegro/docs/man/al_restore_state.3 new file mode 100644 index 00000000..5bac0468 --- /dev/null +++ b/allegro/docs/man/al_restore_state.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_restore_state" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_restore_state - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] + +void al_restore_state(ALLEGRO_STATE const *state) +\f[R] +.fi +.SH DESCRIPTION +.PP +Restores part of the state of the current thread from the given +ALLEGRO_STATE(3) object. +.SH SEE ALSO +.PP +al_store_state(3), ALLEGRO_STATE_FLAGS(3) diff --git a/allegro/docs/man/al_resume_timer.3 b/allegro/docs/man/al_resume_timer.3 new file mode 100644 index 00000000..64b1821f --- /dev/null +++ b/allegro/docs/man/al_resume_timer.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_resume_timer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_resume_timer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_resume_timer(ALLEGRO_TIMER *timer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Resume the timer specified. +From then, the timer\[cq]s counter will increment at a constant rate, +and it will begin generating events. +Resuming a timer that is already started does nothing. +Resuming a stopped timer will not reset the timer\[cq]s counter (unlike +al_start_timer). +.SH SEE ALSO +.PP +al_start_timer(3), al_stop_timer(3), al_get_timer_started(3) diff --git a/allegro/docs/man/al_rewind_audio_stream.3 b/allegro/docs/man/al_rewind_audio_stream.3 new file mode 100644 index 00000000..a69169a9 --- /dev/null +++ b/allegro/docs/man/al_rewind_audio_stream.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_rewind_audio_stream" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_rewind_audio_stream - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the streaming file playing position to the beginning. +Returns true on success. +Currently this can only be called on streams created with +al_load_audio_stream(3), al_load_audio_stream_f(3) and the +format-specific functions underlying those functions. diff --git a/allegro/docs/man/al_rotate_transform.3 b/allegro/docs/man/al_rotate_transform.3 new file mode 100644 index 00000000..957f3f6a --- /dev/null +++ b/allegro/docs/man/al_rotate_transform.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_rotate_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_rotate_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_rotate_transform(ALLEGRO_TRANSFORM *trans, float theta) +\f[R] +.fi +.SH DESCRIPTION +.PP +Apply a rotation to a transformation. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to alter +.IP \[bu] 2 +theta - Rotation angle in radians +.SH SEE ALSO +.PP +al_translate_transform(3), al_scale_transform(3), al_build_transform(3) diff --git a/allegro/docs/man/al_rotate_transform_3d.3 b/allegro/docs/man/al_rotate_transform_3d.3 new file mode 100644 index 00000000..e7d10da3 --- /dev/null +++ b/allegro/docs/man/al_rotate_transform_3d.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_rotate_transform_3d" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_rotate_transform_3d - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_rotate_transform_3d(ALLEGRO_TRANSFORM *trans, + float x, float y, float z, float angle) +\f[R] +.fi +.SH DESCRIPTION +.PP +Combines the given transformation with a transformation which rotates +coordinates around the given vector by the given angle in radians. +.PP +Note: The vector is assumed to be of unit length (otherwise it will also +incur a scale). +.SH SINCE +.PP +5.1.3 diff --git a/allegro/docs/man/al_rumble_haptic.3 b/allegro/docs/man/al_rumble_haptic.3 new file mode 100644 index 00000000..f1a590c9 --- /dev/null +++ b/allegro/docs/man/al_rumble_haptic.3 @@ -0,0 +1,48 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_rumble_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_rumble_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_rumble_haptic(ALLEGRO_HAPTIC *hap, + double intensity, double duration, ALLEGRO_HAPTIC_EFFECT_ID *id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uploads a simple rumble effect to the haptic device and starts playback +immediately. +The parameter \f[C]intensity\f[R] is a relative magnitude between 0.0 +and 1.0 that determines the intensity of the rumble effect. +The \f[C]duration\f[R] determines the duration of the effect in seconds. +.PP +You must also pass in a pointer to a user allocated +ALLEGRO_HAPTIC_EFFECT_ID(3). +It it is stored a reference to be used to control playback of the +effect. +Returns true if the rumble effect was successfully uploaded and started, +false if not. +.PP +In case false is returned, the rumble effect will be automatically +released as if al_release_haptic_effect(3) had been called, so there is +no need to call it again manually in this case. +However, if true is returned, it is necessary to call +al_release_haptic_effect(3) when the effect isn\[cq]t needed anymore, to +prevent the amount of available effects on the haptic device from +running out. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_run_detached_thread.3 b/allegro/docs/man/al_run_detached_thread.3 new file mode 100644 index 00000000..89aec910 --- /dev/null +++ b/allegro/docs/man/al_run_detached_thread.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_run_detached_thread" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_run_detached_thread - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_run_detached_thread(void *(*proc)(void *arg), void *arg) +\f[R] +.fi +.SH DESCRIPTION +.PP +Runs the passed function in its own thread, with \f[C]arg\f[R] passed to +it as only parameter. +This is similar to calling al_create_thread(3), al_start_thread(3) and +(after the thread has finished) al_destroy_thread(3) - but you don\[cq]t +have the possibility of ever calling al_join_thread(3) on the thread. diff --git a/allegro/docs/man/al_run_main.3 b/allegro/docs/man/al_run_main.3 new file mode 100644 index 00000000..112878c4 --- /dev/null +++ b/allegro/docs/man/al_run_main.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_run_main" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_run_main - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_run_main(int argc, char **argv, int (*user_main)(int, char **)) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function is useful in cases where you don\[cq]t have a main() +function but want to run Allegro (mostly useful in a wrapper library). +Under Windows and Linux this is no problem because you simply can call +al_install_system(3). +But some other system (like OSX) don\[cq]t allow calling +al_install_system(3) in the main thread. +al_run_main will know what to do in that case. +.PP +The passed argc and argv will simply be passed on to user_main and the +return value of user_main will be returned. diff --git a/allegro/docs/man/al_save_bitmap.3 b/allegro/docs/man/al_save_bitmap.3 new file mode 100644 index 00000000..f5935cb8 --- /dev/null +++ b/allegro/docs/man/al_save_bitmap.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_save_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_save_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_save_bitmap(const char *filename, ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Saves an ALLEGRO_BITMAP(3) to an image file. +The file type is determined by the extension. +.PP +Returns true on success, false on error. +.RS +.PP +\f[I]Note:\f[R] the core Allegro library does not support any image file +formats by default. +You must use the allegro_image addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_save_bitmap_f(3), al_register_bitmap_saver(3), al_init_image_addon(3) diff --git a/allegro/docs/man/al_save_bitmap_f.3 b/allegro/docs/man/al_save_bitmap_f.3 new file mode 100644 index 00000000..58a3fccc --- /dev/null +++ b/allegro/docs/man/al_save_bitmap_f.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_save_bitmap_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_save_bitmap_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_save_bitmap_f(ALLEGRO_FILE *fp, const char *ident, + ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Saves an ALLEGRO_BITMAP(3) to an ALLEGRO_FILE(3) stream. +The file type is determined by the passed `ident' parameter, which is a +file name extension including the leading dot. +.PP +Returns true on success, false on error. +The file remains open afterwards. +.RS +.PP +\f[I]Note:\f[R] the core Allegro library does not support any image file +formats by default. +You must use the allegro_image addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_save_bitmap(3), al_register_bitmap_saver_f(3), al_init_image_addon(3) diff --git a/allegro/docs/man/al_save_config_file.3 b/allegro/docs/man/al_save_config_file.3 new file mode 100644 index 00000000..00f8d7ef --- /dev/null +++ b/allegro/docs/man/al_save_config_file.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_save_config_file" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_save_config_file - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config) +\f[R] +.fi +.SH DESCRIPTION +.PP +Write out a configuration file to disk. +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_save_config_file_f(3), al_load_config_file(3) diff --git a/allegro/docs/man/al_save_config_file_f.3 b/allegro/docs/man/al_save_config_file_f.3 new file mode 100644 index 00000000..899901bc --- /dev/null +++ b/allegro/docs/man/al_save_config_file_f.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_save_config_file_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_save_config_file_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config) +\f[R] +.fi +.SH DESCRIPTION +.PP +Write out a configuration file to an already open file. +.PP +Returns true on success, false on error. +The file remains open afterwards. +.SH SEE ALSO +.PP +al_save_config_file(3) diff --git a/allegro/docs/man/al_save_sample.3 b/allegro/docs/man/al_save_sample.3 new file mode 100644 index 00000000..5d04fe6b --- /dev/null +++ b/allegro/docs/man/al_save_sample.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_save_sample" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_save_sample - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_save_sample(const char *filename, ALLEGRO_SAMPLE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes a sample into a file. +Currently, wav is the only supported format, and the extension must be +\[lq].wav\[rq]. +.PP +Returns true on success, false on error. +.RS +.PP +\f[I]Note:\f[R] the allegro_audio library does not support any audio +file formats by default. +You must use the allegro_acodec addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_save_sample_f(3), al_register_sample_saver(3), +al_init_acodec_addon(3) diff --git a/allegro/docs/man/al_save_sample_f.3 b/allegro/docs/man/al_save_sample_f.3 new file mode 100644 index 00000000..f99e5d2d --- /dev/null +++ b/allegro/docs/man/al_save_sample_f.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_save_sample_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_save_sample_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_save_sample_f(ALLEGRO_FILE *fp, const char *ident, ALLEGRO_SAMPLE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Writes a sample into a ALLEGRO_FILE(3) filestream. +Currently, wav is the only supported format, and the extension must be +\[lq].wav\[rq]. +.PP +Returns true on success, false on error. +The file remains open afterwards. +.RS +.PP +\f[I]Note:\f[R] the allegro_audio library does not support any audio +file formats by default. +You must use the allegro_acodec addon, or register your own format +handler. +.RE +.SH SEE ALSO +.PP +al_save_sample(3), al_register_sample_saver_f(3), +al_init_acodec_addon(3) diff --git a/allegro/docs/man/al_scale_transform.3 b/allegro/docs/man/al_scale_transform.3 new file mode 100644 index 00000000..bc3326e6 --- /dev/null +++ b/allegro/docs/man/al_scale_transform.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_scale_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_scale_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_scale_transform(ALLEGRO_TRANSFORM *trans, float sx, float sy) +\f[R] +.fi +.SH DESCRIPTION +.PP +Apply a scale to a transformation. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to alter +.IP \[bu] 2 +sx, sy - Scale +.SH SEE ALSO +.PP +al_translate_transform(3), al_rotate_transform(3), al_build_transform(3) diff --git a/allegro/docs/man/al_scale_transform_3d.3 b/allegro/docs/man/al_scale_transform_3d.3 new file mode 100644 index 00000000..2ab31f40 --- /dev/null +++ b/allegro/docs/man/al_scale_transform_3d.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_scale_transform_3d" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_scale_transform_3d - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_scale_transform_3d(ALLEGRO_TRANSFORM *trans, float sx, float sy, + float sz) +\f[R] +.fi +.SH DESCRIPTION +.PP +Combines the given transformation with a transformation which scales +coordinates by the given vector. +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +al_use_projection_transform(3) diff --git a/allegro/docs/man/al_seek_audio_stream_secs.3 b/allegro/docs/man/al_seek_audio_stream_secs.3 new file mode 100644 index 00000000..b915468d --- /dev/null +++ b/allegro/docs/man/al_seek_audio_stream_secs.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_seek_audio_stream_secs" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_seek_audio_stream_secs - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double time) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the streaming file playing position to time. +Returns true on success. +Currently this can only be called on streams created with +al_load_audio_stream(3), al_load_audio_stream_f(3) and the +format-specific functions underlying those functions. +.SH SEE ALSO +.PP +al_get_audio_stream_position_secs(3), al_get_audio_stream_length_secs(3) diff --git a/allegro/docs/man/al_seek_video.3 b/allegro/docs/man/al_seek_video.3 new file mode 100644 index 00000000..82d26a69 --- /dev/null +++ b/allegro/docs/man/al_seek_video.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_seek_video" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_seek_video - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_seek_video(ALLEGRO_VIDEO *video, double pos_in_seconds) +\f[R] +.fi +.SH DESCRIPTION +.PP +Seek to a different position in the video. +Currently only seeking to the beginning of the video is supported. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_set_app_name.3 b/allegro/docs/man/al_set_app_name.3 new file mode 100644 index 00000000..9aada1c3 --- /dev/null +++ b/allegro/docs/man/al_set_app_name.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_app_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_app_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_app_name(const char *app_name) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the global application name. +.PP +The application name is used by al_get_standard_path(3) to build the +full path to an application\[cq]s files. +.PP +This function may be called before al_init(3) or al_install_system(3). +.SH SEE ALSO +.PP +al_get_app_name(3), al_set_org_name(3) diff --git a/allegro/docs/man/al_set_audio_stream_channel_matrix.3 b/allegro/docs/man/al_set_audio_stream_channel_matrix.3 new file mode 100644 index 00000000..58f56e39 --- /dev/null +++ b/allegro/docs/man/al_set_audio_stream_channel_matrix.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_audio_stream_channel_matrix" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_audio_stream_channel_matrix - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_set_sample_instance_channel_matrix(3) but for streams. +.SH SINCE +.PP +5.2.3 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE diff --git a/allegro/docs/man/al_set_audio_stream_fragment.3 b/allegro/docs/man/al_set_audio_stream_fragment.3 new file mode 100644 index 00000000..1a8c0529 --- /dev/null +++ b/allegro/docs/man/al_set_audio_stream_fragment.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_audio_stream_fragment" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_audio_stream_fragment - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM *stream, void *val) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function needs to be called for every successful call of +al_get_audio_stream_fragment(3) to indicate that the buffer (pointed to +by \f[C]val\f[R]) is filled with new data. +.SH SEE ALSO +.PP +al_get_audio_stream_fragment(3) diff --git a/allegro/docs/man/al_set_audio_stream_gain.3 b/allegro/docs/man/al_set_audio_stream_gain.3 new file mode 100644 index 00000000..785b4ae5 --- /dev/null +++ b/allegro/docs/man/al_set_audio_stream_gain.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_audio_stream_gain" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_audio_stream_gain - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM *stream, float val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the playback gain of the stream. +.PP +Returns true on success, false on failure. +Will fail if the audio stream is attached directly to a voice. +.SH SEE ALSO +.PP +al_get_audio_stream_gain(3). diff --git a/allegro/docs/man/al_set_audio_stream_loop_secs.3 b/allegro/docs/man/al_set_audio_stream_loop_secs.3 new file mode 100644 index 00000000..0f218c31 --- /dev/null +++ b/allegro/docs/man/al_set_audio_stream_loop_secs.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_audio_stream_loop_secs" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_audio_stream_loop_secs - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM *stream, + double start, double end) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the loop points for the stream in seconds. +Currently this can only be called on streams created with +al_load_audio_stream(3), al_load_audio_stream_f(3) and the +format-specific functions underlying those functions. diff --git a/allegro/docs/man/al_set_audio_stream_pan.3 b/allegro/docs/man/al_set_audio_stream_pan.3 new file mode 100644 index 00000000..21d7f5c4 --- /dev/null +++ b/allegro/docs/man/al_set_audio_stream_pan.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_audio_stream_pan" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_audio_stream_pan - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM *stream, float val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the pan value on an audio stream. +A value of -1.0 means to play the stream only through the left speaker; ++1.0 means only through the right speaker; 0.0 means the sample is +centre balanced. +A special value ALLEGRO_AUDIO_PAN_NONE(3) disables panning and plays the +stream at its original level. +This will be louder than a pan value of 0.0. +.PP +Returns true on success, false on failure. +Will fail if the audio stream is attached directly to a voice. +.SH SEE ALSO +.PP +al_get_audio_stream_pan(3), ALLEGRO_AUDIO_PAN_NONE(3) diff --git a/allegro/docs/man/al_set_audio_stream_playing.3 b/allegro/docs/man/al_set_audio_stream_playing.3 new file mode 100644 index 00000000..7637dcca --- /dev/null +++ b/allegro/docs/man/al_set_audio_stream_playing.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_audio_stream_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_audio_stream_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM *stream, bool val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Change whether the stream is playing. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_get_audio_stream_playing(3) diff --git a/allegro/docs/man/al_set_audio_stream_playmode.3 b/allegro/docs/man/al_set_audio_stream_playmode.3 new file mode 100644 index 00000000..0a0f1d41 --- /dev/null +++ b/allegro/docs/man/al_set_audio_stream_playmode.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_audio_stream_playmode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_audio_stream_playmode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM *stream, + ALLEGRO_PLAYMODE val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the playback mode of the stream. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +ALLEGRO_PLAYMODE(3), al_get_audio_stream_playmode(3). diff --git a/allegro/docs/man/al_set_audio_stream_speed.3 b/allegro/docs/man/al_set_audio_stream_speed.3 new file mode 100644 index 00000000..d1b8ec8f --- /dev/null +++ b/allegro/docs/man/al_set_audio_stream_speed.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_audio_stream_speed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_audio_stream_speed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM *stream, float val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the relative playback speed of the stream. +1.0 means normal speed. +.PP +Return true on success, false on failure. +Will fail if the audio stream is attached directly to a voice. +.SH SEE ALSO +.PP +al_get_audio_stream_speed(3). diff --git a/allegro/docs/man/al_set_bitmap_blend_color.3 b/allegro/docs/man/al_set_bitmap_blend_color.3 new file mode 100644 index 00000000..ce70919e --- /dev/null +++ b/allegro/docs/man/al_set_bitmap_blend_color.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_bitmap_blend_color" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_bitmap_blend_color - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_bitmap_blend_color(ALLEGRO_COLOR col) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the color to use for \f[C]ALLEGRO_CONST_COLOR\f[R] or +\f[C]ALLEGRO_INVERSE_CONST_COLOR\f[R] blend operations. +.SH SINCE +.PP +5.2.5 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE +.SH SEE ALSO +.PP +al_set_bitmap_blender(3), al_reset_bitmap_blender(3) diff --git a/allegro/docs/man/al_set_bitmap_blender.3 b/allegro/docs/man/al_set_bitmap_blender.3 new file mode 100644 index 00000000..20177ddc --- /dev/null +++ b/allegro/docs/man/al_set_bitmap_blender.3 @@ -0,0 +1,37 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_bitmap_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_bitmap_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_bitmap_blender(int op, int src, int dest) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the function to use for blending when rendering to the target +bitmap. +If no blender is set for a given bitmap at draw time, the values set for +al_set_blender(3)/al_set_separate_blender(3) are used instead. +.PP +To use separate functions for chroma (RGB) and alpha channels, use +al_set_separate_bitmap_blender(3). +.PP +See al_set_blender(3) for more information about how blending works. +.SH SEE ALSO +.PP +al_set_separate_bitmap_blender(3), al_reset_bitmap_blender(3) +.SH SINCE +.PP +5.2.5 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE diff --git a/allegro/docs/man/al_set_blend_color.3 b/allegro/docs/man/al_set_blend_color.3 new file mode 100644 index 00000000..dcac65c1 --- /dev/null +++ b/allegro/docs/man/al_set_blend_color.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_blend_color" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_blend_color - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_blend_color(ALLEGRO_COLOR color) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the color to use for blending when using the ALLEGRO_CONST_COLOR or +ALLEGRO_INVERSE_CONST_COLOR blend functions. +See al_set_blender(3) for more information. +.SH SEE ALSO +.PP +al_set_blender(3), al_get_blend_color(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_set_blender.3 b/allegro/docs/man/al_set_blender.3 new file mode 100644 index 00000000..44e88f5d --- /dev/null +++ b/allegro/docs/man/al_set_blender.3 @@ -0,0 +1,263 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_blender(int op, int src, int dst) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the function to use for blending for the current thread. +.PP +Blending means, the source and destination colors are combined in +drawing operations. +.PP +Assume the source color (e.g.\ color of a rectangle to draw, or pixel of +a bitmap to draw) is given as its red/green/blue/alpha components (if +the bitmap has no alpha it always is assumed to be fully opaque, so 255 +for 8-bit or 1.0 for floating point): \f[I]s = s.r, s.g, s.b, s.a\f[R]. +And this color is drawn to a destination, which already has a color: +\f[I]d = d.r, d.g, d.b, d.a\f[R]. +.PP +The conceptional formula used by Allegro to draw any pixel then depends +on the \f[C]op\f[R] parameter: +.IP \[bu] 2 +ALLEGRO_ADD +.RS 2 +.IP +.nf +\f[C] + r = d.r * df.r + s.r * sf.r + g = d.g * df.g + s.g * sf.g + b = d.b * df.b + s.b * sf.b + a = d.a * df.a + s.a * sf.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_DEST_MINUS_SRC +.RS 2 +.IP +.nf +\f[C] + r = d.r * df.r - s.r * sf.r + g = d.g * df.g - s.g * sf.g + b = d.b * df.b - s.b * sf.b + a = d.a * df.a - s.a * sf.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_SRC_MINUS_DEST +.RS 2 +.IP +.nf +\f[C] + r = s.r * sf.r - d.r * df.r + g = s.g * sf.g - d.g * df.g + b = s.b * sf.b - d.b * df.b + a = s.a * sf.a - d.a * df.a +\f[R] +.fi +.RE +.PP +Valid values for the factors \f[C]sf\f[R] and \f[C]df\f[R] passed to +this function are as follows, where \f[C]s\f[R] is the source color, +\f[C]d\f[R] the destination color and \f[C]cc\f[R] the color set with +al_set_blend_color(3) (white by default) +.IP \[bu] 2 +ALLEGRO_ZERO +.RS 2 +.IP +.nf +\f[C] + f = 0, 0, 0, 0 +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_ONE +.RS 2 +.IP +.nf +\f[C] + f = 1, 1, 1, 1 +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_ALPHA +.RS 2 +.IP +.nf +\f[C] + f = s.a, s.a, s.a, s.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_INVERSE_ALPHA +.RS 2 +.IP +.nf +\f[C] + f = 1 - s.a, 1 - s.a, 1 - s.a, 1 - s.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_SRC_COLOR (since: 5.0.10, 5.1.0) +.RS 2 +.IP +.nf +\f[C] + f = s.r, s.g, s.b, s.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_DEST_COLOR (since: 5.0.10, 5.1.8) +.RS 2 +.IP +.nf +\f[C] + f = d.r, d.g, d.b, d.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_INVERSE_SRC_COLOR (since: 5.0.10, 5.1.0) +.RS 2 +.IP +.nf +\f[C] + f = 1 - s.r, 1 - s.g, 1 - s.b, 1 - s.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_INVERSE_DEST_COLOR (since: 5.0.10, 5.1.8) +.RS 2 +.IP +.nf +\f[C] + f = 1 - d.r, 1 - d.g, 1 - d.b, 1 - d.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_CONST_COLOR (since: 5.1.12, not supported on OpenGLES 1.0) +.RS 2 +.IP +.nf +\f[C] + f = cc.r, cc.g, cc.b, cc.a +\f[R] +.fi +.RE +.IP \[bu] 2 +ALLEGRO_INVERSE_CONST_COLOR (since: 5.1.12, not supported on OpenGLES +1.0) +.RS 2 +.IP +.nf +\f[C] + f = 1 - cc.r, 1 - cc.g, 1 - cc.b, 1 - cc.a +\f[R] +.fi +.RE +.PP +Blending examples: +.PP +So for example, to restore the default of using premultiplied alpha +blending, you would use: +.IP +.nf +\f[C] +al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); +\f[R] +.fi +.PP +As formula: +.IP +.nf +\f[C] +r = d.r * (1 - s.a) + s.r * 1 +g = d.g * (1 - s.a) + s.g * 1 +b = d.b * (1 - s.a) + s.b * 1 +a = d.a * (1 - s.a) + s.a * 1 +\f[R] +.fi +.PP +If you are using non-pre-multiplied alpha, you could use +.IP +.nf +\f[C] +al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); +\f[R] +.fi +.PP +Additive blending would be achieved with +.IP +.nf +\f[C] +al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); +\f[R] +.fi +.PP +Copying the source to the destination (including alpha) unmodified +.IP +.nf +\f[C] +al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); +\f[R] +.fi +.PP +Multiplying source and destination components +.IP +.nf +\f[C] +al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_ZERO) +\f[R] +.fi +.PP +Tinting the source (like al_draw_tinted_bitmap(3)) +.IP +.nf +\f[C] +al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_ONE); +al_set_blend_color(al_map_rgb(0, 96, 255)); /* nice Chrysler blue */ +\f[R] +.fi +.PP +Averaging source and destination pixels +.IP +.nf +\f[C] +al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR); +al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 0.5)); +\f[R] +.fi +.PP +As formula: +.IP +.nf +\f[C] +r = d.r * 0 + s.r * d.r +g = d.g * 0 + s.g * d.g +b = d.b * 0 + s.b * d.b +a = d.a * 0 + s.a * d.a +\f[R] +.fi +.SH SEE ALSO +.PP +al_set_separate_blender(3), al_set_blend_color(3), al_get_blender(3) diff --git a/allegro/docs/man/al_set_clipboard_text.3 b/allegro/docs/man/al_set_clipboard_text.3 new file mode 100644 index 00000000..3ebeae57 --- /dev/null +++ b/allegro/docs/man/al_set_clipboard_text.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_clipboard_text" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_clipboard_text - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function pastes the text given as an argument to the clipboard. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_get_clipboard_text(3), al_clipboard_has_text(3) diff --git a/allegro/docs/man/al_set_clipping_rectangle.3 b/allegro/docs/man/al_set_clipping_rectangle.3 new file mode 100644 index 00000000..3b41bc73 --- /dev/null +++ b/allegro/docs/man/al_set_clipping_rectangle.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_clipping_rectangle" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_clipping_rectangle - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_clipping_rectangle(int x, int y, int width, int height) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the region of the target bitmap or display that pixels get clipped +to. +The default is to clip pixels to the entire bitmap. +.SH SEE ALSO +.PP +al_get_clipping_rectangle(3), al_reset_clipping_rectangle(3) diff --git a/allegro/docs/man/al_set_config_value.3 b/allegro/docs/man/al_set_config_value.3 new file mode 100644 index 00000000..343780bd --- /dev/null +++ b/allegro/docs/man/al_set_config_value.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_config_value" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_config_value - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_config_value(ALLEGRO_CONFIG *config, + const char *section, const char *key, const char *value) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set a value in a section of a configuration. +If the section doesn\[cq]t yet exist, it will be created. +If a value already existed for the given key, it will be overwritten. +The section can be NULL or \[dq]\[dq] for the global section. +.PP +For consistency with the on-disk format of config files, any leading and +trailing whitespace will be stripped from the value. +If you have significant whitespace you wish to preserve, you should add +your own quote characters and remove them when reading the values back +in. +.SH SEE ALSO +.PP +al_get_config_value(3) diff --git a/allegro/docs/man/al_set_current_opengl_context.3 b/allegro/docs/man/al_set_current_opengl_context.3 new file mode 100644 index 00000000..fc42924e --- /dev/null +++ b/allegro/docs/man/al_set_current_opengl_context.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_current_opengl_context" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_current_opengl_context - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_current_opengl_context(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Make the OpenGL context associated with the given display current for +the calling thread. +If there is a current target bitmap which belongs to a different OpenGL +context, the target bitmap will be changed to NULL. +.PP +Normally you do not need to use this function, as the context will be +made current when you call al_set_target_bitmap(3) or +al_set_target_backbuffer(3). +You might need it if you created an OpenGL \[lq]forward compatible\[rq] +context. +Then al_get_backbuffer(3) only returns NULL, so it would not work to +pass that to al_set_target_bitmap(3). diff --git a/allegro/docs/man/al_set_d3d_device_release_callback.3 b/allegro/docs/man/al_set_d3d_device_release_callback.3 new file mode 100644 index 00000000..11069543 --- /dev/null +++ b/allegro/docs/man/al_set_d3d_device_release_callback.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_d3d_device_release_callback" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_d3d_device_release_callback - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_d3d_device_release_callback( + void (*callback)(ALLEGRO_DISPLAY *display)) +\f[R] +.fi +.SH DESCRIPTION +.PP +The callback will be called whenever a D3D device is reset (minimize, +toggle fullscreen window, etc). +In the callback you should release any d3d resources you have created +yourself. +The callback receives the affected display as a parameter. +.PP +Pass NULL to disable the callback. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_set_d3d_device_restore_callback.3 b/allegro/docs/man/al_set_d3d_device_restore_callback.3 new file mode 100644 index 00000000..ff0e80cd --- /dev/null +++ b/allegro/docs/man/al_set_d3d_device_restore_callback.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_d3d_device_restore_callback" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_d3d_device_restore_callback - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_d3d_device_restore_callback( + void (*callback)(ALLEGRO_DISPLAY *display)) +\f[R] +.fi +.SH DESCRIPTION +.PP +The callback will be called whenever a D3D device that has been reset is +restored. +In the callback you should restore any d3d resources you have created +yourself. +The callback receives the affected display as a parameter. +.PP +Pass NULL to disable the callback. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_set_default_mixer.3 b/allegro/docs/man/al_set_default_mixer.3 new file mode 100644 index 00000000..77c2c7ff --- /dev/null +++ b/allegro/docs/man/al_set_default_mixer.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_default_mixer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_default_mixer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_default_mixer(ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the default mixer. +All samples started with al_play_sample(3) will be stopped and all +sample instances returned by al_lock_sample_id(3) will be invalidated. +If you are using your own mixer, this should be called before +al_reserve_samples(3). +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_reserve_samples(3), al_play_sample(3), al_get_default_mixer(3), +al_restore_default_mixer(3) diff --git a/allegro/docs/man/al_set_default_voice.3 b/allegro/docs/man/al_set_default_voice.3 new file mode 100644 index 00000000..6d31aa5b --- /dev/null +++ b/allegro/docs/man/al_set_default_voice.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_default_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_default_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_default_voice(ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +You can call this before calling al_restore_default_mixer to provide the +voice which should be used. +Any previous voice will be destroyed. +You can also pass NULL to destroy the current default voice. +.SH SINCE +.PP +5.1.13 +.SH SEE ALSO +.PP +al_get_default_mixer(3) diff --git a/allegro/docs/man/al_set_display_flag.3 b/allegro/docs/man/al_set_display_flag.3 new file mode 100644 index 00000000..78b02203 --- /dev/null +++ b/allegro/docs/man/al_set_display_flag.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_display_flag" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_display_flag - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) +\f[R] +.fi +.SH DESCRIPTION +.PP +Enable or disable one of the display flags. +The flags are the same as for al_set_new_display_flags(3). +The only flags that can be changed after creation are: +.IP \[bu] 2 +ALLEGRO_FULLSCREEN_WINDOW +.IP \[bu] 2 +ALLEGRO_FRAMELESS +.IP \[bu] 2 +ALLEGRO_MAXIMIZED +.PP +Returns true if the driver supports toggling the specified flag else +false. +You can use al_get_display_flags(3) to query whether the given display +property actually changed. +.SH SINCE +.PP +5.0.7, 5.1.2 +.SH SEE ALSO +.PP +al_set_new_display_flags(3), al_get_display_flags(3) diff --git a/allegro/docs/man/al_set_display_icon.3 b/allegro/docs/man/al_set_display_icon.3 new file mode 100644 index 00000000..ba777900 --- /dev/null +++ b/allegro/docs/man/al_set_display_icon.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_display_icon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_display_icon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_display_icon(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon) +\f[R] +.fi +.SH DESCRIPTION +.PP +Changes the icon associated with the display (window). +Same as al_set_display_icons(3) with one icon. +.SH SEE ALSO +.PP +al_set_display_icons(3), al_set_window_title(3) diff --git a/allegro/docs/man/al_set_display_icons.3 b/allegro/docs/man/al_set_display_icons.3 new file mode 100644 index 00000000..50b82de6 --- /dev/null +++ b/allegro/docs/man/al_set_display_icons.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_display_icons" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_display_icons - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_display_icons(ALLEGRO_DISPLAY *display, + int num_icons, ALLEGRO_BITMAP *icons[]) +\f[R] +.fi +.SH DESCRIPTION +.PP +Changes the icons associated with the display (window). +Multiple icons can be provided for use in different contexts, +e.g.\ window frame, taskbar, alt-tab popup. +The number of icons must be at least one. +.RS +.PP +\f[I]Note:\f[R] If the underlying OS requires an icon of a size not +provided then one of the bitmaps will be scaled up or down to the +required size. +The choice of bitmap is implementation dependent. +.RE +.SH SINCE +.PP +5.0.9, 5.1.5 +.SH SEE ALSO +.PP +al_set_display_icon(3), al_set_window_title(3) diff --git a/allegro/docs/man/al_set_display_menu.3 b/allegro/docs/man/al_set_display_menu.3 new file mode 100644 index 00000000..cf4a9bdd --- /dev/null +++ b/allegro/docs/man/al_set_display_menu.3 @@ -0,0 +1,43 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_display_menu" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_display_menu - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu) +\f[R] +.fi +.SH DESCRIPTION +.PP +Associates the \f[C]menu\f[R] with the \f[C]display\f[R] and shows it. +If there was a previous menu associated with the display, it will be +destroyed. +If you don\[cq]t want that to happen, you should first remove the menu +with al_remove_display_menu(3). +.PP +If the menu is already attached to a display, it will not be attached to +the new display. +If \f[C]menu\f[R] is \f[C]NULL\f[R], the current menu will still be +destroyed. +.RS +.PP +\f[I]Note:\f[R] Attaching a menu may cause the window as available to +your application to be resized! You should listen for a resize event, +check how much space was lost, and resize the window accordingly if you +want to maintain your window\[cq]s prior size. +.RE +.PP +Returns true if successful. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_create_menu(3), al_remove_display_menu(3) diff --git a/allegro/docs/man/al_set_display_option.3 b/allegro/docs/man/al_set_display_option.3 new file mode 100644 index 00000000..12714515 --- /dev/null +++ b/allegro/docs/man/al_set_display_option.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_display_option" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_display_option - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_display_option(ALLEGRO_DISPLAY *display, int option, int value) +\f[R] +.fi +.SH DESCRIPTION +.PP +Change an option that was previously set for a display. +After displays are created, they take on the options set with +al_set_new_display_option(3). +Calling al_set_new_display_option(3) subsequently only changes options +for newly created displays, and doesn\[cq]t touch the options of already +created displays. +al_set_display_option(3) allows changing some of these values. +Not all display options can be changed or changing them will have no +effect. +Changing options other than those listed below is undefined. +.IP \[bu] 2 +ALLEGRO_SUPPORTED_ORIENTATIONS - This can be changed to allow new or +restrict previously enabled orientations of the screen/device. +See al_set_new_display_option(3) for more information on this option. +.SH SINCE +.PP +5.1.5 +.SH SEE ALSO +.PP +al_set_new_display_option(3) diff --git a/allegro/docs/man/al_set_errno.3 b/allegro/docs/man/al_set_errno.3 new file mode 100644 index 00000000..01ba36f6 --- /dev/null +++ b/allegro/docs/man/al_set_errno.3 @@ -0,0 +1,19 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_errno" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_errno - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] + +void al_set_errno(int errnum) +SETTER(allegro_errno, errnum) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the error number for the calling thread. diff --git a/allegro/docs/man/al_set_event_source_data.3 b/allegro/docs/man/al_set_event_source_data.3 new file mode 100644 index 00000000..6533cec1 --- /dev/null +++ b/allegro/docs/man/al_set_event_source_data.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_event_source_data" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_event_source_data - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_event_source_data(ALLEGRO_EVENT_SOURCE *source, intptr_t data) +\f[R] +.fi +.SH DESCRIPTION +.PP +Assign the abstract user data to the event source. +Allegro does not use the data internally for anything; it is simply +meant as a convenient way to associate your own data or objects with +events. +.SH SEE ALSO +.PP +al_get_event_source_data(3) diff --git a/allegro/docs/man/al_set_exe_name.3 b/allegro/docs/man/al_set_exe_name.3 new file mode 100644 index 00000000..fc6c027e --- /dev/null +++ b/allegro/docs/man/al_set_exe_name.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_exe_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_exe_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_exe_name(char const *path) +\f[R] +.fi +.SH DESCRIPTION +.PP +This override the executable name used by al_get_standard_path(3) for +ALLEGRO_EXENAME_PATH and ALLEGRO_RESOURCES_PATH. +.PP +One possibility where changing this can be useful is if you use the +Python wrapper. +Allegro would then by default think that the system\[cq]s Python +executable is the current executable - but you can set it to the .py +file being executed instead. +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_get_standard_path(3) diff --git a/allegro/docs/man/al_set_fallback_font.3 b/allegro/docs/man/al_set_fallback_font.3 new file mode 100644 index 00000000..40093d92 --- /dev/null +++ b/allegro/docs/man/al_set_fallback_font.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_fallback_font" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_fallback_font - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_fallback_font(ALLEGRO_FONT *font, ALLEGRO_FONT *fallback) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets a font which is used instead if a character is not present. +Can be chained, but make sure there is no loop as that would crash the +application! Pass NULL to remove a fallback font again. +.SH SINCE +.PP +5.1.12 +.SH SEE ALSO +.PP +al_get_fallback_font(3), al_draw_glyph(3), al_draw_text(3) diff --git a/allegro/docs/man/al_set_fs_interface.3 b/allegro/docs/man/al_set_fs_interface.3 new file mode 100644 index 00000000..2fa5d72e --- /dev/null +++ b/allegro/docs/man/al_set_fs_interface.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_fs_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_fs_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_fs_interface(const ALLEGRO_FS_INTERFACE *fs_interface) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the ALLEGRO_FS_INTERFACE(3) table for the calling thread. +.SH SEE ALSO +.PP +al_set_standard_fs_interface(3), al_store_state(3), al_restore_state(3). diff --git a/allegro/docs/man/al_set_haptic_autocenter.3 b/allegro/docs/man/al_set_haptic_autocenter.3 new file mode 100644 index 00000000..100e07d0 --- /dev/null +++ b/allegro/docs/man/al_set_haptic_autocenter.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_haptic_autocenter" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_haptic_autocenter - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_haptic_autocenter(ALLEGRO_HAPTIC *hap, double intensity) +\f[R] +.fi +.SH DESCRIPTION +.PP +Turns on or off the automatic centering feature of the haptic device if +supported. +Depending on the device automatic centering may ensure that the axes of +the device are centered again automatically after playing a haptic +effect. +The intensity parameter should be passed with a value between 0.0 and +1.0. +The value 0.0 means automatic centering is disabled, and 1.0 means full +strength automatic centering. +Any value in between those two extremes will result in partial automatic +centering. +Some platforms do not support partial automatic centering. +If that is the case, a value of less than 0.5 will turn it off, while a +value equal to or higher to 0.5 will turn it on. +Returns true if set successfully, false if not. +Can only work if al_get_haptic_capabilities(3) returns a value that has +ALLEGRO_HAPTIC_AUTOCENTER(3)ALLEGRO_HAPTIC_CONSTANTS(3) set. +If not, this function returns false. +.SH SINCE +.PP +5.1.9 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_set_haptic_gain.3 b/allegro/docs/man/al_set_haptic_gain.3 new file mode 100644 index 00000000..9d7b4d7f --- /dev/null +++ b/allegro/docs/man/al_set_haptic_gain.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_haptic_gain" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_haptic_gain - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_haptic_gain(ALLEGRO_HAPTIC *hap, double gain) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the gain of the haptic device if supported. +Gain is much like volume for sound, it is as if every effect\[cq]s +intensity is multiplied by it. +Gain is a value between 0.0 and 1.0. +Returns true if set successfully, false if not. +Only works if al_get_haptic_capabilities(3) returns a value that has +ALLEGRO_HAPTIC_GAIN(3)ALLEGRO_HAPTIC_CONSTANTS(3) set. +If not, this function returns false, and all effects will be played +without any gain influence. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_set_keyboard_leds.3 b/allegro/docs/man/al_set_keyboard_leds.3 new file mode 100644 index 00000000..aa6c5f5c --- /dev/null +++ b/allegro/docs/man/al_set_keyboard_leds.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_keyboard_leds" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_keyboard_leds - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_keyboard_leds(int leds) +\f[R] +.fi +.SH DESCRIPTION +.PP +Overrides the state of the keyboard LED indicators. +Set \f[C]leds\f[R] to a combination of the keyboard modifier flags to +enable the corresponding LED indicators +(\f[C]ALLEGRO_KEYMOD_NUMLOCK\f[R], \f[C]ALLEGRO_KEYMOD_CAPSLOCK\f[R] and +\f[C]ALLEGRO_KEYMOD_SCROLLLOCK\f[R] are supported) or to -1 to return to +default behavior. +False is returned if the current keyboard driver cannot set LED +indicators. diff --git a/allegro/docs/man/al_set_memory_interface.3 b/allegro/docs/man/al_set_memory_interface.3 new file mode 100644 index 00000000..c6d10544 --- /dev/null +++ b/allegro/docs/man/al_set_memory_interface.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_memory_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_memory_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_memory_interface(ALLEGRO_MEMORY_INTERFACE *memory_interface) +\f[R] +.fi +.SH DESCRIPTION +.PP +Override the memory management functions with implementations of +al_malloc_with_context(3), al_free_with_context(3), +al_realloc_with_context(3) and al_calloc_with_context(3). +The context arguments may be used for debugging. +The new functions should be thread safe. +.PP +If the pointer is NULL, the default behaviour will be restored. +.SH SEE ALSO +.PP +ALLEGRO_MEMORY_INTERFACE(3) diff --git a/allegro/docs/man/al_set_menu_item_caption.3 b/allegro/docs/man/al_set_menu_item_caption.3 new file mode 100644 index 00000000..91c762e6 --- /dev/null +++ b/allegro/docs/man/al_set_menu_item_caption.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_menu_item_caption" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_menu_item_caption - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_menu_item_caption(ALLEGRO_MENU *menu, int pos, const char *caption) +\f[R] +.fi +.SH DESCRIPTION +.PP +Updates the menu item caption with the new \f[C]caption\f[R]. +This will invalidate any previous calls to al_get_menu_item_caption(3). +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_get_menu_item_caption(3) diff --git a/allegro/docs/man/al_set_menu_item_flags.3 b/allegro/docs/man/al_set_menu_item_flags.3 new file mode 100644 index 00000000..16379f06 --- /dev/null +++ b/allegro/docs/man/al_set_menu_item_flags.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_menu_item_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_menu_item_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_menu_item_flags(ALLEGRO_MENU *menu, int pos, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Updates the menu item\[cq]s flags. +See al_insert_menu_item(3) for a description of the available flags. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_get_menu_item_flags(3), al_toggle_menu_item_flags(3) diff --git a/allegro/docs/man/al_set_menu_item_icon.3 b/allegro/docs/man/al_set_menu_item_icon.3 new file mode 100644 index 00000000..59eda3d2 --- /dev/null +++ b/allegro/docs/man/al_set_menu_item_icon.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_menu_item_icon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_menu_item_icon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_menu_item_icon(ALLEGRO_MENU *menu, int pos, ALLEGRO_BITMAP *icon) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the icon for the specified menu item. +The menu assumes ownership of the \f[C]ALLEGRO_BITMAP\f[R] and may +invalidate the pointer, so you must clone it if you wish to continue +using it. +.PP +If a video bitmap is passed, it will automatically be converted to a +memory bitmap, so it is preferable to pass a memory bitmap. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_get_menu_item_icon(3), al_clone_bitmap(3) diff --git a/allegro/docs/man/al_set_mixer_frequency.3 b/allegro/docs/man/al_set_mixer_frequency.3 new file mode 100644 index 00000000..004eb801 --- /dev/null +++ b/allegro/docs/man/al_set_mixer_frequency.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mixer_frequency" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mixer_frequency - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mixer_frequency(ALLEGRO_MIXER *mixer, unsigned int val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the mixer frequency (in Hz). +This will only work if the mixer is not attached to anything. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_get_mixer_frequency(3) diff --git a/allegro/docs/man/al_set_mixer_gain.3 b/allegro/docs/man/al_set_mixer_gain.3 new file mode 100644 index 00000000..05e31557 --- /dev/null +++ b/allegro/docs/man/al_set_mixer_gain.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mixer_gain" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mixer_gain - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mixer_gain(ALLEGRO_MIXER *mixer, float new_gain) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the mixer gain (amplification factor). +.PP +Returns true on success, false on failure. +.SH SINCE +.PP +5.0.6, 5.1.0 +.SH SEE ALSO +.PP +al_get_mixer_gain(3) diff --git a/allegro/docs/man/al_set_mixer_playing.3 b/allegro/docs/man/al_set_mixer_playing.3 new file mode 100644 index 00000000..5ffa4333 --- /dev/null +++ b/allegro/docs/man/al_set_mixer_playing.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mixer_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mixer_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mixer_playing(ALLEGRO_MIXER *mixer, bool val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Change whether the mixer is playing. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_get_mixer_playing(3). diff --git a/allegro/docs/man/al_set_mixer_postprocess_callback.3 b/allegro/docs/man/al_set_mixer_postprocess_callback.3 new file mode 100644 index 00000000..7fcd31e3 --- /dev/null +++ b/allegro/docs/man/al_set_mixer_postprocess_callback.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mixer_postprocess_callback" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mixer_postprocess_callback - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mixer_postprocess_callback(ALLEGRO_MIXER *mixer, + void (*pp_callback)(void *buf, unsigned int samples, void *data), + void *pp_callback_userdata) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets a post-processing filter function that\[cq]s called after the +attached streams have been mixed. +The buffer\[cq]s format will be whatever the mixer was created with. +The sample count and user-data pointer is also passed. +.RS +.PP +\f[I]Note:\f[R] The callback is called from a dedicated audio thread. +.RE diff --git a/allegro/docs/man/al_set_mixer_quality.3 b/allegro/docs/man/al_set_mixer_quality.3 new file mode 100644 index 00000000..e60c8eb8 --- /dev/null +++ b/allegro/docs/man/al_set_mixer_quality.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mixer_quality" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mixer_quality - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mixer_quality(ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY new_quality) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the mixer quality. +This can only succeed if the mixer does not have anything attached to +it. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +ALLEGRO_MIXER_QUALITY(3), al_get_mixer_quality(3) diff --git a/allegro/docs/man/al_set_mouse_axis.3 b/allegro/docs/man/al_set_mouse_axis.3 new file mode 100644 index 00000000..24fef620 --- /dev/null +++ b/allegro/docs/man/al_set_mouse_axis.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mouse_axis" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mouse_axis - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mouse_axis(int which, int value) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the given mouse axis to the given value. +.PP +The axis number must not be 0 or 1, which are the X and Y axes. +Use al_set_mouse_xy(3) for that. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_set_mouse_xy(3), al_set_mouse_z(3), al_set_mouse_w(3) diff --git a/allegro/docs/man/al_set_mouse_cursor.3 b/allegro/docs/man/al_set_mouse_cursor.3 new file mode 100644 index 00000000..50f549ae --- /dev/null +++ b/allegro/docs/man/al_set_mouse_cursor.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mouse_cursor" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mouse_cursor - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the given mouse cursor to be the current mouse cursor for the given +display. +.PP +If the cursor is currently `shown' (as opposed to `hidden') the change +is immediately visible. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_set_system_mouse_cursor(3), al_show_mouse_cursor(3), +al_hide_mouse_cursor(3) diff --git a/allegro/docs/man/al_set_mouse_emulation_mode.3 b/allegro/docs/man/al_set_mouse_emulation_mode.3 new file mode 100644 index 00000000..04b8bec9 --- /dev/null +++ b/allegro/docs/man/al_set_mouse_emulation_mode.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mouse_emulation_mode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mouse_emulation_mode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_mouse_emulation_mode(int mode) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the kind of mouse emulation for the touch input subsystem to +perform. +.SH SINCE +.PP +5.1.0 +.RS +.PP +\f[I][Unstable API]:\f[R] Seems of limited value, as touch input tends +to have different semantics compared to mouse input. +.RE +.SH SEE ALSO +.PP +ALLEGRO_MOUSE_EMULATION_MODE(3), al_get_mouse_emulation_mode(3). diff --git a/allegro/docs/man/al_set_mouse_w.3 b/allegro/docs/man/al_set_mouse_w.3 new file mode 100644 index 00000000..c3cf844c --- /dev/null +++ b/allegro/docs/man/al_set_mouse_w.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mouse_w" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mouse_w - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mouse_w(int w) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the second mouse wheel position to the given value. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_set_mouse_z(3) diff --git a/allegro/docs/man/al_set_mouse_wheel_precision.3 b/allegro/docs/man/al_set_mouse_wheel_precision.3 new file mode 100644 index 00000000..3036f804 --- /dev/null +++ b/allegro/docs/man/al_set_mouse_wheel_precision.3 @@ -0,0 +1,52 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mouse_wheel_precision" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mouse_wheel_precision - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_mouse_wheel_precision(int precision) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the precision of the mouse wheel (the z and w coordinates). +This precision manifests itself as a multiplier on the \f[C]dz\f[R] and +\f[C]dw\f[R] fields in mouse events. +It also affects the \f[C]z\f[R] and \f[C]w\f[R] fields of events and +ALLEGRO_MOUSE_STATE(3), but not in a simple way if you alter the +precision often, so it is suggested to reset those axes to 0 when you +change precision. +Setting this to a high value allows you to detect small changes in those +two axes for some high precision mice. +A flexible way of using this precision is to set it to a high value (120 +is likely sufficient for most, if not all, mice) and use a floating +point \f[C]dz\f[R] and \f[C]dw\f[R] like so: +.IP +.nf +\f[C] +al_set_mouse_wheel_precision(120); + +ALLEGRO_EVENT event; +al_wait_for_event(event_queue, &event); +if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + double dz = (double)event.mouse.dz / al_get_mouse_wheel_precision(); + /* Use dz in some way... */ +} +\f[R] +.fi +.PP +Precision is set to 1 by default. +It is impossible to set it to a lower precision than that. +.SH SINCE +.PP +5.1.10 +.SH SEE ALSO +.PP +al_get_mouse_wheel_precision(3) diff --git a/allegro/docs/man/al_set_mouse_xy.3 b/allegro/docs/man/al_set_mouse_xy.3 new file mode 100644 index 00000000..b486a032 --- /dev/null +++ b/allegro/docs/man/al_set_mouse_xy.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mouse_xy" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mouse_xy - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Try to position the mouse at the given coordinates on the given display. +The mouse movement resulting from a successful move will generate an +ALLEGRO_EVENT_MOUSE_WARPED(3) event. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_set_mouse_z(3), al_set_mouse_w(3) diff --git a/allegro/docs/man/al_set_mouse_z.3 b/allegro/docs/man/al_set_mouse_z.3 new file mode 100644 index 00000000..b903713a --- /dev/null +++ b/allegro/docs/man/al_set_mouse_z.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_mouse_z" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_mouse_z - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_mouse_z(int z) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the mouse wheel position to the given value. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_set_mouse_w(3) diff --git a/allegro/docs/man/al_set_new_bitmap_depth.3 b/allegro/docs/man/al_set_new_bitmap_depth.3 new file mode 100644 index 00000000..46e74354 --- /dev/null +++ b/allegro/docs/man/al_set_new_bitmap_depth.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_bitmap_depth" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_bitmap_depth - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_bitmap_depth(int depth) +SETTER(new_bitmap_depth, depth) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the depthbuffer depth used by newly created bitmaps (on the current +thread) if they are used with al_set_target_bitmap(3). +0 means no depth-buffer will be created when drawing into the bitmap, +which is the default. +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This is an experimental feature and currently +only works for the OpenGL backend. +.RE diff --git a/allegro/docs/man/al_set_new_bitmap_flags.3 b/allegro/docs/man/al_set_new_bitmap_flags.3 new file mode 100644 index 00000000..4c156797 --- /dev/null +++ b/allegro/docs/man/al_set_new_bitmap_flags.3 @@ -0,0 +1,120 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_bitmap_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_bitmap_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_bitmap_flags(int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the flags to use for newly created bitmaps. +Valid flags are: +.TP +ALLEGRO_MEMORY_BITMAP +Create a bitmap residing in system memory. +Operations on, and with, memory bitmaps will not be hardware +accelerated. +However, direct pixel access can be relatively quick compared to video +bitmaps, which depend on the display driver in use. +.RS +.PP +\f[I]Note\f[R]: Allegro\[cq]s software rendering routines are currently +somewhat unoptimised. +.PP +\f[I]Note:\f[R] Combining ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP +flags is invalid. +.RE +.TP +ALLEGRO_VIDEO_BITMAP +Creates a bitmap that resides in the video card memory. +These types of bitmaps receive the greatest benefit from hardware +acceleration. +.RS +.PP +\f[I]Note\f[R]: Creating a video bitmap will fail if there is no current +display or the current display driver cannot create the bitmap. +The latter will happen if for example the format or dimensions are not +supported. +.PP +\f[I]Note:\f[R] Bitmaps created with this flag will be converted to +memory bitmaps when the last display is destroyed. +In most cases it is therefore easier to use the ALLEGRO_CONVERT_BITMAP +flag instead. +.PP +\f[I]Note:\f[R] Combining ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP +flags is invalid. +.RE +.TP +ALLEGRO_CONVERT_BITMAP +This is the default. +It will try to create a video bitmap and if that fails create a memory +bitmap. +Bitmaps created with this flag when there is no active display will be +converted to video bitmaps next time a display is created. +They also will remain video bitmaps if the last display is destroyed and +then another is created again. +Since 5.1.0. +.RS +.PP +\f[I]Note:\f[R] You can combine this flag with ALLEGRO_MEMORY_BITMAP or +ALLEGRO_VIDEO_BITMAP to force the initial type (and fail in the latter +case if no video bitmap can be created) - but usually neither of those +combinations is very useful. +.PP +You can use the display option ALLEGRO_AUTO_CONVERT_BITMAPS to control +which displays will try to auto-convert bitmaps. +.RE +.TP +ALLEGRO_FORCE_LOCKING +Does nothing since 5.1.8. +Kept for backwards compatibility only. +.TP +ALLEGRO_NO_PRESERVE_TEXTURE +Normally, every effort is taken to preserve the contents of bitmaps, +since some platforms may forget them. +This can take extra processing time. +If you know it doesn\[cq]t matter if a bitmap keeps its pixel data, for +example when it\[cq]s a temporary buffer, use this flag to tell Allegro +not to attempt to preserve its contents. +.TP +ALLEGRO_ALPHA_TEST +This is a driver hint only. +It tells the graphics driver to do alpha testing instead of alpha +blending on bitmaps created with this flag. +Alpha testing is usually faster and preferred if your bitmaps have only +one level of alpha (0). +This flag is currently not widely implemented (i.e., only for memory +bitmaps). +.TP +ALLEGRO_MIN_LINEAR +When drawing a scaled down version of the bitmap, use linear filtering. +This usually looks better. +You can also combine it with the MIPMAP flag for even better quality. +.TP +ALLEGRO_MAG_LINEAR +When drawing a magnified version of a bitmap, use linear filtering. +This will cause the picture to get blurry instead of creating a big +rectangle for each pixel. +It depends on how you want things to look like whether you want to use +this or not. +.TP +ALLEGRO_MIPMAP +This can only be used for bitmaps whose width and height is a power of +two. +In that case, it will generate mipmaps and use them when drawing scaled +down versions. +For example if the bitmap is 64x64, then extra bitmaps of sizes 32x32, +16x16, 8x8, 4x4, 2x2 and 1x1 will be created always containing a scaled +down version of the original. +.SH SEE ALSO +.PP +al_get_new_bitmap_flags(3), al_get_bitmap_flags(3) diff --git a/allegro/docs/man/al_set_new_bitmap_format.3 b/allegro/docs/man/al_set_new_bitmap_format.3 new file mode 100644 index 00000000..9d007438 --- /dev/null +++ b/allegro/docs/man/al_set_new_bitmap_format.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_bitmap_format" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_bitmap_format - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_bitmap_format(int format) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the pixel format (ALLEGRO_PIXEL_FORMAT(3)) for newly created +bitmaps. +The default format is 0 and means the display driver will choose the +best format. +.SH SEE ALSO +.PP +ALLEGRO_PIXEL_FORMAT(3), al_get_new_bitmap_format(3), +al_get_bitmap_format(3) diff --git a/allegro/docs/man/al_set_new_bitmap_samples.3 b/allegro/docs/man/al_set_new_bitmap_samples.3 new file mode 100644 index 00000000..1434ac7e --- /dev/null +++ b/allegro/docs/man/al_set_new_bitmap_samples.3 @@ -0,0 +1,57 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_bitmap_samples" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_bitmap_samples - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_bitmap_samples(int samples) +SETTER(new_bitmap_samples, samples) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the multi-sampling samples used by newly created bitmaps (on the +current thread) if they are used with al_set_target_bitmap(3). +0 means multi-sampling will not be used when drawing into the bitmap, +which is the default. +1 means multi-sampling will be used but only using a single sample per +pixel (so usually there will be no visual difference to not using +multi-sampling at all). +.RS +.PP +\f[I]Note:\f[R] Some platforms have restrictions on when the +multi-sampling buffer for a bitmap is realized, i.e.\ down-scaled back +to the actual bitmap dimensions. +This may only happen after a call to al_set_target_bitmap(3). +So for example: +.RE +.IP +.nf +\f[C] +al_set_target_bitmap(multisample); +al_clear_to_color(blue); +al_draw_line(0, 0, 100, 100, red, 1); +al_lock_bitmap(multisample, ...) +// ERROR: the contents of the bitmap will be undefined + +al_set_target_bitmap(backbuffer); +al_lock_bitmap(multisample, ...) +// CORRECT: at this point, the bitmap contents are updated and +// there will be an anti-aliased line in it. +\f[R] +.fi +.SH SINCE +.PP +5.2.1 +.RS +.PP +\f[I][Unstable API]:\f[R] This is an experimental feature and currently +only works for the OpenGL backend. +.RE diff --git a/allegro/docs/man/al_set_new_display_adapter.3 b/allegro/docs/man/al_set_new_display_adapter.3 new file mode 100644 index 00000000..d8729a72 --- /dev/null +++ b/allegro/docs/man/al_set_new_display_adapter.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_display_adapter" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_display_adapter - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_display_adapter(int adapter) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the adapter to use for new displays created by the calling thread. +The adapter has a monitor attached to it. +Information about the monitor can be gotten using +al_get_num_video_adapters(3) and al_get_monitor_info(3). +.PP +To return to the default behaviour, pass +\f[C]ALLEGRO_DEFAULT_DISPLAY_ADAPTER\f[R]. +.SH SEE ALSO +.PP +al_get_num_video_adapters(3), al_get_monitor_info(3) diff --git a/allegro/docs/man/al_set_new_display_flags.3 b/allegro/docs/man/al_set_new_display_flags.3 new file mode 100644 index 00000000..09b4c37b --- /dev/null +++ b/allegro/docs/man/al_set_new_display_flags.3 @@ -0,0 +1,149 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_display_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_display_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_display_flags(int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets various flags to be used when creating new displays on the calling +thread. +flags is a bitfield containing any reasonable combination of the +following: +.TP +ALLEGRO_WINDOWED +Prefer a windowed mode. +.RS +.PP +Under multi-head X (not XRandR/TwinView), the use of more than one +adapter is impossible due to bugs in X and GLX. +al_create_display(3) will fail if more than one adapter is attempted to +be used. +.RE +.TP +ALLEGRO_FULLSCREEN_WINDOW +Make the window span the entire screen. +Unlike ALLEGRO_FULLSCREEN this will never attempt to modify the screen +resolution. +Instead the pixel dimensions of the created display will be the same as +the desktop. +.RS +.PP +The passed width and height are only used if the window is switched out +of fullscreen mode later but will be ignored initially. +.PP +Under Windows and X11 a fullscreen display created with this flag will +behave differently from one created with the ALLEGRO_FULLSCREEN flag - +even if the ALLEGRO_FULLSCREEN display is passed the desktop dimensions. +The exact difference is platform dependent, but some things which may be +different is how alt-tab works, how fast you can toggle between +fullscreen/windowed mode or how additional monitors behave while your +display is in fullscreen mode. +.PP +Additionally under X, the use of more than one adapter in multi-head +mode or with true Xinerama enabled is impossible due to bugs in X/GLX, +creation will fail if more than one adapter is attempted to be used. +.RE +.TP +ALLEGRO_FULLSCREEN +Prefer a fullscreen mode. +.RS +.PP +Under X the use of more than one FULLSCREEN display when using +multi-head X, or true Xinerama is not possible due to bugs in X and GLX, +display creation will fail if more than one adapter is attempted to be +used. +.RS +.PP +\f[I]Note:\f[R] Prefer using ALLEGRO_FULLSCREEN_WINDOW as it typically +provides a better user experience as the monitor doesn\[cq]t change +resolution and switching away from your game via Alt-Tab works smoothly. +ALLEGRO_FULLSCREEN is typically less well supported compared to +ALLEGRO_FULLSCREEN_WINDOW. +.RE +.RE +.TP +ALLEGRO_RESIZABLE +The display is resizable (only applicable if combined with +ALLEGRO_WINDOWED). +.TP +ALLEGRO_MAXIMIZED +The display window will be maximized (only applicable if combined with +ALLEGRO_RESIZABLE). +Since: 5.1.12 +.TP +ALLEGRO_OPENGL +Require the driver to provide an initialized OpenGL context after +returning successfully. +.TP +ALLEGRO_OPENGL_3_0 +Require the driver to provide an initialized OpenGL context compatible +with OpenGL version 3.0. +.TP +ALLEGRO_OPENGL_FORWARD_COMPATIBLE +If this flag is set, the OpenGL context created with ALLEGRO_OPENGL_3_0 +will be forward compatible \f[I]only\f[R], meaning that all of the +OpenGL API declared deprecated in OpenGL 3.0 will not be supported. +Currently, a display created with this flag will \f[I]not\f[R] be +compatible with Allegro drawing routines; the display option +ALLEGRO_COMPATIBLE_DISPLAY will be set to false. +.TP +ALLEGRO_OPENGL_ES_PROFILE +Used together with ALLEGRO_OPENGL, requests that the OpenGL context uses +the OpenGL ES profile. +A specific version can be requested with al_set_new_display_option(3). +Note: Currently this is only supported by the X11/GLX driver. +Since: 5.1.13 +.TP +ALLEGRO_OPENGL_CORE_PROFILE +Used together with ALLEGRO_OPENGL, requests that the OpenGL context uses +the OpenGL Core profile. +A specific version can be requested with al_set_new_display_option(3). +Note: Currently this is only supported by the X11/GLX driver. +Since: 5.2.7 +.TP +ALLEGRO_DIRECT3D +Require the driver to do rendering with Direct3D and provide a Direct3D +device. +.TP +ALLEGRO_PROGRAMMABLE_PIPELINE +Require a programmable graphics pipeline. +This flag is required to use ALLEGRO_SHADER(3) objects. +Since: 5.1.6 +.TP +ALLEGRO_FRAMELESS +Try to create a window without a frame (i.e.\ no border or titlebar). +This usually does nothing for fullscreen modes, and even in windowed +modes it depends on the underlying platform whether it is supported or +not. +Since: 5.0.7, 5.1.2 +.TP +ALLEGRO_NOFRAME +Original name for ALLEGRO_FRAMELESS. +This works with older versions of Allegro. +.TP +ALLEGRO_GENERATE_EXPOSE_EVENTS +Let the display generate expose events. +.TP +ALLEGRO_GTK_TOPLEVEL +Create a GTK toplevel window for the display, on X. +This flag is conditionally defined by the native dialog addon. +You must call al_init_native_dialog_addon(3) for it to succeed. +ALLEGRO_GTK_TOPLEVEL is incompatible with ALLEGRO_FULLSCREEN. +Since: 5.1.5 +.PP +0 can be used for default values. +.SH SEE ALSO +.PP +al_set_new_display_option(3), al_get_display_option(3), +al_set_display_option(3) diff --git a/allegro/docs/man/al_set_new_display_option.3 b/allegro/docs/man/al_set_new_display_option.3 new file mode 100644 index 00000000..6ea43867 --- /dev/null +++ b/allegro/docs/man/al_set_new_display_option.3 @@ -0,0 +1,185 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_display_option" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_display_option - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_display_option(int option, int value, int importance) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set an extra display option, to be used when creating new displays on +the calling thread. +Display options differ from display flags, and specify some details of +the context to be created within the window itself. +These mainly have no effect on Allegro itself, but you may want to +specify them, for example if you want to use multisampling. +.PP +The `importance' parameter can be either: +.IP \[bu] 2 +ALLEGRO_REQUIRE - The display will not be created if the setting can not +be met. +.IP \[bu] 2 +ALLEGRO_SUGGEST - If the setting is not available, the display will be +created anyway with a setting as close as possible to the requested one. +You can query the actual value used in that case by calling +al_get_display_option(3) after the display has been created. +.IP \[bu] 2 +ALLEGRO_DONTCARE - If you added a display option with one of the above +two settings before, it will be removed again. +Else this does nothing. +.PP +The supported options are: +.TP +ALLEGRO_COLOR_SIZE +This can be used to ask for a specific bit depth. +For example to force a 16-bit framebuffer set this to 16. +.TP +ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE, ALLEGRO_ALPHA_SIZE +Individual color component size in bits. +.TP +ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT, ALLEGRO_BLUE_SHIFT, ALLEGRO_ALPHA_SHIFT +Together with the previous settings these can be used to specify the +exact pixel layout the display should use. +Normally there is no reason to use these. +.TP +ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE, ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE +This can be used to define the required accumulation buffer size. +.TP +ALLEGRO_STEREO +Whether the display is a stereo display. +.TP +ALLEGRO_AUX_BUFFERS +Number of auxiliary buffers the display should have. +.TP +ALLEGRO_DEPTH_SIZE +How many depth buffer (z-buffer) bits to use. +.TP +ALLEGRO_STENCIL_SIZE +How many bits to use for the stencil buffer. +.TP +ALLEGRO_SAMPLE_BUFFERS +Whether to use multisampling (1) or not (0). +.TP +ALLEGRO_SAMPLES +If the above is 1, the number of samples to use per pixel. +Else 0. +.TP +ALLEGRO_RENDER_METHOD: +0 if hardware acceleration is not used with this display. +.TP +ALLEGRO_FLOAT_COLOR +Whether to use floating point color components. +.TP +ALLEGRO_FLOAT_DEPTH +Whether to use a floating point depth buffer. +.TP +ALLEGRO_SINGLE_BUFFER +Whether the display uses a single buffer (1) or another update method +(0). +.TP +ALLEGRO_SWAP_METHOD +If the above is 0, this is set to 1 to indicate the display is using a +copying method to make the next buffer in the flip chain available, or +to 2 to indicate a flipping or other method. +.TP +ALLEGRO_COMPATIBLE_DISPLAY +Indicates if Allegro\[cq]s graphics functions can use this display. +If you request a display not useable by Allegro, you can still use for +example OpenGL to draw graphics. +.TP +ALLEGRO_UPDATE_DISPLAY_REGION +Set to 1 if the display is capable of updating just a region, and 0 if +calling al_update_display_region(3) is equivalent to al_flip_display(3). +.TP +ALLEGRO_VSYNC +Set to 1 to tell the driver to wait for vsync in al_flip_display(3), or +to 2 to force vsync off. +The default of 0 means that Allegro does not try to modify the vsync +behavior so it may be on or off. +Note that even in the case of 1 or 2 it is possible to override the +vsync behavior in the graphics driver so you should not rely on it. +.TP +ALLEGRO_MAX_BITMAP_SIZE +When queried this returns the maximum size (width as well as height) a +bitmap can have for this display. +Calls to al_create_bitmap(3) or al_load_bitmap(3) for bitmaps larger +than this size will fail. +It does not apply to memory bitmaps which always can have arbitrary size +(but are slow for drawing). +.TP +ALLEGRO_SUPPORT_NPOT_BITMAP +Set to 1 if textures used for bitmaps on this display can have a size +which is not a power of two. +This is mostly useful if you use Allegro to load textures as otherwise +only power-of-two textures will be used internally as bitmap storage. +.TP +ALLEGRO_CAN_DRAW_INTO_BITMAP +Set to 1 if you can use al_set_target_bitmap(3) on bitmaps of this +display to draw into them. +If this is not the case software emulation will be used when drawing +into display bitmaps (which can be very slow). +.TP +ALLEGRO_SUPPORT_SEPARATE_ALPHA +This is set to 1 if the al_set_separate_blender(3) function is +supported. +Otherwise the alpha parameters will be ignored. +.TP +ALLEGRO_AUTO_CONVERT_BITMAPS +This is on by default. +It causes any existing memory bitmaps with the ALLEGRO_CONVERT_BITMAP +flag to be converted to a display bitmap of the newly created display +with the option set. +.RS +.PP +Since: 5.1.0 +.RE +.TP +ALLEGRO_SUPPORTED_ORIENTATIONS +This is a bit-combination of the orientations supported by the +application. +The orientations are the same as for al_get_display_orientation(3) with +the additional possibilities: +.RS +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE +.IP \[bu] 2 +ALLEGRO_DISPLAY_ORIENTATION_ALL +.PP +PORTRAIT means only the two portrait orientations are supported, +LANDSCAPE means only the two landscape orientations and ALL allows all +four orientations. +When the orientation changes between a portrait and a landscape +orientation the display needs to be resized. +This is done by sending an ALLEGRO_EVENT_DISPLAY_RESIZE(3) message which +should be handled by calling al_acknowledge_resize(3). +.PP +Since: 5.1.0 +.RE +.TP +ALLEGRO_OPENGL_MAJOR_VERSION +Request a specific OpenGL major version. +.RS +.PP +Since: 5.1.13 +.RE +.TP +ALLEGRO_OPENGL_MINOR_VERSION +Request a specific OpenGL minor version. +.RS +.PP +Since: 5.1.13 +.RE +.SH SEE ALSO +.PP +al_set_new_display_flags(3), al_get_display_option(3) diff --git a/allegro/docs/man/al_set_new_display_refresh_rate.3 b/allegro/docs/man/al_set_new_display_refresh_rate.3 new file mode 100644 index 00000000..ae4c93ca --- /dev/null +++ b/allegro/docs/man/al_set_new_display_refresh_rate.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_display_refresh_rate" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_display_refresh_rate - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_display_refresh_rate(int refresh_rate) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the refresh rate to use when creating new displays on the calling +thread. +If the refresh rate is not available, al_create_display(3) will fail. +A list of modes with refresh rates can be found with +al_get_num_display_modes(3) and al_get_display_mode(3). +.PP +The default setting is zero (don\[cq]t care). +.SH SEE ALSO +.PP +al_get_new_display_refresh_rate(3) diff --git a/allegro/docs/man/al_set_new_file_interface.3 b/allegro/docs/man/al_set_new_file_interface.3 new file mode 100644 index 00000000..adcf3a7f --- /dev/null +++ b/allegro/docs/man/al_set_new_file_interface.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_file_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_file_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_file_interface(const ALLEGRO_FILE_INTERFACE *file_interface) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the ALLEGRO_FILE_INTERFACE(3) table for the calling thread. +This will change the handler for later calls to al_fopen(3). +.SH SEE ALSO +.PP +al_set_standard_file_interface(3), al_store_state(3), +al_restore_state(3). diff --git a/allegro/docs/man/al_set_new_window_position.3 b/allegro/docs/man/al_set_new_window_position.3 new file mode 100644 index 00000000..10941c32 --- /dev/null +++ b/allegro/docs/man/al_set_new_window_position.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_window_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_window_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_window_position(int x, int y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets where the top left pixel of the client area of newly created +windows (non-fullscreen) will be on screen, for displays created by the +calling thread. +Negative values are allowed on some multihead systems. +.PP +To reset to the default behaviour, pass (INT_MAX, INT_MAX). +.SH SEE ALSO +.PP +al_get_new_window_position(3) diff --git a/allegro/docs/man/al_set_new_window_title.3 b/allegro/docs/man/al_set_new_window_title.3 new file mode 100644 index 00000000..02b218ae --- /dev/null +++ b/allegro/docs/man/al_set_new_window_title.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_new_window_title" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_new_window_title - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_new_window_title(const char *title) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the title that will be used when a new display is created. +Allegro uses a static buffer of ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE(3) to +store this, so the length of the titme you set must be less than this. +.SH SEE ALSO +.PP +al_set_window_title(3), al_get_new_window_title(3), +al_create_display(3), ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE(3) +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_set_org_name.3 b/allegro/docs/man/al_set_org_name.3 new file mode 100644 index 00000000..5f67cb59 --- /dev/null +++ b/allegro/docs/man/al_set_org_name.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_org_name" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_org_name - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_org_name(const char *org_name) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the global organization name. +.PP +The organization name is used by al_get_standard_path(3) to build the +full path to an application\[cq]s files. +.PP +This function may be called before al_init(3) or al_install_system(3). +.SH SEE ALSO +.PP +al_get_org_name(3), al_set_app_name(3) diff --git a/allegro/docs/man/al_set_path_drive.3 b/allegro/docs/man/al_set_path_drive.3 new file mode 100644 index 00000000..9c02c945 --- /dev/null +++ b/allegro/docs/man/al_set_path_drive.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_path_drive" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_path_drive - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_path_drive(ALLEGRO_PATH *path, const char *drive) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the drive string on a path. +The drive may be NULL, which is equivalent to setting the drive string +to the empty string. +.SH SEE ALSO +.PP +al_get_path_drive(3) diff --git a/allegro/docs/man/al_set_path_extension.3 b/allegro/docs/man/al_set_path_extension.3 new file mode 100644 index 00000000..145a42d2 --- /dev/null +++ b/allegro/docs/man/al_set_path_extension.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_path_extension" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_path_extension - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_path_extension(ALLEGRO_PATH *path, char const *extension) +\f[R] +.fi +.SH DESCRIPTION +.PP +Replaces the extension of the path with the given one, i.e.\ replaces +everything from the final dot (`.') character onwards, including the +dot. +If the filename of the path has no extension, the given one is appended. +Usually the new extension you supply should include a leading dot. +.PP +Returns false if the path contains no filename part, i.e.\ the filename +part is the empty string. +.SH SEE ALSO +.PP +al_set_path_filename(3), al_get_path_extension(3) diff --git a/allegro/docs/man/al_set_path_filename.3 b/allegro/docs/man/al_set_path_filename.3 new file mode 100644 index 00000000..ca4c581f --- /dev/null +++ b/allegro/docs/man/al_set_path_filename.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_path_filename" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_path_filename - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_path_filename(ALLEGRO_PATH *path, const char *filename) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the optional filename part of the path. +The filename may be NULL, which is equivalent to setting the filename to +the empty string. +.SH SEE ALSO +.PP +al_set_path_extension(3), al_get_path_filename(3) diff --git a/allegro/docs/man/al_set_physfs_file_interface.3 b/allegro/docs/man/al_set_physfs_file_interface.3 new file mode 100644 index 00000000..776e7d43 --- /dev/null +++ b/allegro/docs/man/al_set_physfs_file_interface.3 @@ -0,0 +1,45 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_physfs_file_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_physfs_file_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_physfs_file_interface(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function sets \f[I]both\f[R] the ALLEGRO_FILE_INTERFACE(3) and +ALLEGRO_FS_INTERFACE(3) for the calling thread. +.PP +Subsequent calls to al_fopen(3) on the calling thread will be handled by +PHYSFS_open(). +Operations on the files returned by al_fopen(3) will then be performed +through PhysicsFS. +Calls to the Allegro filesystem functions, such as al_read_directory(3) +or al_create_fs_entry(3), on the calling thread will be diverted to +PhysicsFS. +.PP +To remember and restore another file I/O backend, you can use +al_store_state(3)/al_restore_state(3). +.RS +.PP +\f[I]Note:\f[R] due to an oversight, this function differs from +al_set_new_file_interface(3) and al_set_standard_file_interface(3) which +only alter the current ALLEGRO_FILE_INTERFACE(3). +.RE +.RS +.PP +\f[I]Note:\f[R] PhysFS does not support the text-mode reading and +writing, which means that Windows-style newlines will not be preserved. +.RE +.SH SEE ALSO +.PP +al_set_new_file_interface(3). diff --git a/allegro/docs/man/al_set_render_state.3 b/allegro/docs/man/al_set_render_state.3 new file mode 100644 index 00000000..7a0fa5e4 --- /dev/null +++ b/allegro/docs/man/al_set_render_state.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_render_state" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_render_state - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_render_state(ALLEGRO_RENDER_STATE state, int value) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set one of several render attributes; see ALLEGRO_RENDER_STATE(3) for +details. +.PP +This function does nothing if the target bitmap is a memory bitmap. +.SH SINCE +.PP +5.1.2 +.SH SEE ALSO +.PP +ALLEGRO_RENDER_STATE(3), ALLEGRO_RENDER_FUNCTION(3), +ALLEGRO_WRITE_MASK_FLAGS(3) diff --git a/allegro/docs/man/al_set_sample.3 b/allegro/docs/man/al_set_sample.3 new file mode 100644 index 00000000..4d67f1ee --- /dev/null +++ b/allegro/docs/man/al_set_sample.3 @@ -0,0 +1,41 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data) +\f[R] +.fi +.SH DESCRIPTION +.PP +Change the sample data that a sample instance plays. +This can be quite an involved process. +.PP +First, the sample is stopped if it is not already. +.PP +Next, if data is NULL, the sample is detached from its parent (if any). +.PP +If data is not NULL, the sample may be detached and reattached to its +parent (if any). +This is not necessary if the old sample data and new sample data have +the same frequency, depth and channel configuration. +Reattaching may not always succeed. +.PP +On success, the sample remains stopped. +The playback position and loop end points are reset to their default +values. +The loop mode remains unchanged. +.PP +Returns true on success, false on failure. +On failure, the sample will be stopped and detached from its parent. +.SH SEE ALSO +.PP +al_get_sample(3) diff --git a/allegro/docs/man/al_set_sample_instance_channel_matrix.3 b/allegro/docs/man/al_set_sample_instance_channel_matrix.3 new file mode 100644 index 00000000..3ca5fb39 --- /dev/null +++ b/allegro/docs/man/al_set_sample_instance_channel_matrix.3 @@ -0,0 +1,56 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample_instance_channel_matrix" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample_instance_channel_matrix - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample_instance_channel_matrix(ALLEGRO_SAMPLE_INSTANCE *spl, const float *matrix) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the matrix used to mix the channels coming from this instance into +the mixer it is attached to. +Normally Allegro derives the values of this matrix from the gain and pan +settings, as well as the channel configurations of this instance and the +mixer it is attached to, but this allows you override that default +value. +Note that if you do set gain or pan of this instance or the mixer it is +attached to, you\[cq]ll need to call this function again. +.PP +The matrix has mixer channel rows and sample channel columns, and is row +major. +For example, if you have a stereo sample instance and want to mix it to +a 5.1 mixer you could use this code: +.IP +.nf +\f[C] +float matrix[] = { + 0.5, 0.0, /* Half left to front left */ + 0.0, 0.5, /* Half right to front right */ + 0.5, 0.0, /* Half left to rear left */ + 0.0, 0.5, /* Half right to rear right */ + 0.1, 0.1, /* Mix left and right for center */ + 0.1, 0.1, /* Mix left and right for center */ +}; + +al_set_sample_instance_channel_matrix(instance, matrix); +\f[R] +.fi +.PP +Returns true on success, false on failure (e.g.\ if this is not attached +to a mixer). +.SH SINCE +.PP +5.2.3 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE diff --git a/allegro/docs/man/al_set_sample_instance_gain.3 b/allegro/docs/man/al_set_sample_instance_gain.3 new file mode 100644 index 00000000..32ab8d12 --- /dev/null +++ b/allegro/docs/man/al_set_sample_instance_gain.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample_instance_gain" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample_instance_gain - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample_instance_gain(ALLEGRO_SAMPLE_INSTANCE *spl, float val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the playback gain of the sample instance. +.PP +Returns true on success, false on failure. +Will fail if the sample instance is attached directly to a voice. +.SH SEE ALSO +.PP +al_get_sample_instance_gain(3) diff --git a/allegro/docs/man/al_set_sample_instance_length.3 b/allegro/docs/man/al_set_sample_instance_length.3 new file mode 100644 index 00000000..dcb1d6f3 --- /dev/null +++ b/allegro/docs/man/al_set_sample_instance_length.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample_instance_length" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample_instance_length - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample_instance_length(ALLEGRO_SAMPLE_INSTANCE *spl, + unsigned int val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the length of the sample instance in sample values. +This can be used to play only parts of the underlying sample. +Be careful not to exceed the actual length of the sample data, though. +.PP +Return true on success, false on failure. +Will fail if the sample instance is currently playing. +.SH SEE ALSO +.PP +al_get_sample_instance_length(3) diff --git a/allegro/docs/man/al_set_sample_instance_pan.3 b/allegro/docs/man/al_set_sample_instance_pan.3 new file mode 100644 index 00000000..c377cc5a --- /dev/null +++ b/allegro/docs/man/al_set_sample_instance_pan.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample_instance_pan" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample_instance_pan - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample_instance_pan(ALLEGRO_SAMPLE_INSTANCE *spl, float val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the pan value on a sample instance. +A value of -1.0 means to play the sample only through the left speaker; ++1.0 means only through the right speaker; 0.0 means the sample is +centre balanced. +A special value ALLEGRO_AUDIO_PAN_NONE(3) disables panning and plays the +sample at its original level. +This will be louder than a pan value of 0.0. +.RS +.PP +Note: panning samples with more than two channels doesn\[cq]t work yet. +.RE +.PP +Returns true on success, false on failure. +Will fail if the sample instance is attached directly to a voice. +.SH SEE ALSO +.PP +al_get_sample_instance_pan(3), ALLEGRO_AUDIO_PAN_NONE(3) diff --git a/allegro/docs/man/al_set_sample_instance_playing.3 b/allegro/docs/man/al_set_sample_instance_playing.3 new file mode 100644 index 00000000..754b2426 --- /dev/null +++ b/allegro/docs/man/al_set_sample_instance_playing.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample_instance_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample_instance_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample_instance_playing(ALLEGRO_SAMPLE_INSTANCE *spl, bool val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Change whether the sample instance is playing. +.PP +The instance does not need to be attached to anything (since: 5.1.8). +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_get_sample_instance_playing(3) diff --git a/allegro/docs/man/al_set_sample_instance_playmode.3 b/allegro/docs/man/al_set_sample_instance_playmode.3 new file mode 100644 index 00000000..0f4843e7 --- /dev/null +++ b/allegro/docs/man/al_set_sample_instance_playmode.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample_instance_playmode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample_instance_playmode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample_instance_playmode(ALLEGRO_SAMPLE_INSTANCE *spl, + ALLEGRO_PLAYMODE val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the playback mode of the sample instance. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +ALLEGRO_PLAYMODE(3), al_get_sample_instance_playmode(3) diff --git a/allegro/docs/man/al_set_sample_instance_position.3 b/allegro/docs/man/al_set_sample_instance_position.3 new file mode 100644 index 00000000..e329edc8 --- /dev/null +++ b/allegro/docs/man/al_set_sample_instance_position.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample_instance_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample_instance_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample_instance_position(ALLEGRO_SAMPLE_INSTANCE *spl, + unsigned int val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the playback position of a sample instance. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_get_sample_instance_position(3) diff --git a/allegro/docs/man/al_set_sample_instance_speed.3 b/allegro/docs/man/al_set_sample_instance_speed.3 new file mode 100644 index 00000000..8c358c3f --- /dev/null +++ b/allegro/docs/man/al_set_sample_instance_speed.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_sample_instance_speed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_sample_instance_speed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_sample_instance_speed(ALLEGRO_SAMPLE_INSTANCE *spl, float val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the relative playback speed of the sample instance. +1.0 means normal speed. +.PP +Return true on success, false on failure. +Will fail if the sample instance is attached directly to a voice. +.SH SEE ALSO +.PP +al_get_sample_instance_speed(3) diff --git a/allegro/docs/man/al_set_separate_bitmap_blender.3 b/allegro/docs/man/al_set_separate_bitmap_blender.3 new file mode 100644 index 00000000..b4f9f005 --- /dev/null +++ b/allegro/docs/man/al_set_separate_bitmap_blender.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_separate_bitmap_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_separate_bitmap_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_separate_bitmap_blender(int op, int src, int dst, int alpha_op, int alpha_src, int alpha_dst) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_set_bitmap_blender(3), but allows specifying a separate blending +operation for the alpha channel. +This is useful if your target bitmap also has an alpha channel and the +two alpha channels need to be combined in a different way than the color +components. +.SH SINCE +.PP +5.2.5 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE +.SH SEE ALSO +.PP +al_set_bitmap_blender(3), al_reset_bitmap_blender(3) diff --git a/allegro/docs/man/al_set_separate_blender.3 b/allegro/docs/man/al_set_separate_blender.3 new file mode 100644 index 00000000..19f360ed --- /dev/null +++ b/allegro/docs/man/al_set_separate_blender.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_separate_blender" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_separate_blender - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_separate_blender(int op, int src, int dst, + int alpha_op, int alpha_src, int alpha_dst) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_set_blender(3), but allows specifying a separate blending +operation for the alpha channel. +This is useful if your target bitmap also has an alpha channel and the +two alpha channels need to be combined in a different way than the color +components. +.SH SEE ALSO +.PP +al_set_blender(3), al_get_blender(3), al_get_separate_blender(3) diff --git a/allegro/docs/man/al_set_shader_bool.3 b/allegro/docs/man/al_set_shader_bool.3 new file mode 100644 index 00000000..c85e2a32 --- /dev/null +++ b/allegro/docs/man/al_set_shader_bool.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_shader_bool" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_shader_bool - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_shader_bool(const char *name, bool b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets a boolean uniform of the target bitmap\[cq]s shader. +.PP +Returns true on success. +Otherwise returns false, e.g.\ if the uniform by that name does not +exist in the shader. +.SH SINCE +.PP +5.1.6 +.SH SEE ALSO +.PP +al_use_shader(3) diff --git a/allegro/docs/man/al_set_shader_float.3 b/allegro/docs/man/al_set_shader_float.3 new file mode 100644 index 00000000..67748c10 --- /dev/null +++ b/allegro/docs/man/al_set_shader_float.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_shader_float" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_shader_float - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_shader_float(const char *name, float f) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets a float uniform of the target bitmap\[cq]s shader. +.PP +Returns true on success. +Otherwise returns false, e.g.\ if the uniform by that name does not +exist in the shader. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_use_shader(3) diff --git a/allegro/docs/man/al_set_shader_float_vector.3 b/allegro/docs/man/al_set_shader_float_vector.3 new file mode 100644 index 00000000..3b667892 --- /dev/null +++ b/allegro/docs/man/al_set_shader_float_vector.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_shader_float_vector" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_shader_float_vector - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_shader_float_vector(const char *name, + int num_components, const float *f, int num_elems) +\f[R] +.fi +.SH DESCRIPTION +.PP +Same as al_set_shader_int_vector(3) except all values are float instead +of int. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_set_shader_int_vector(3), al_use_shader(3) diff --git a/allegro/docs/man/al_set_shader_int.3 b/allegro/docs/man/al_set_shader_int.3 new file mode 100644 index 00000000..fa20cceb --- /dev/null +++ b/allegro/docs/man/al_set_shader_int.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_shader_int" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_shader_int - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_shader_int(const char *name, int i) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets an integer uniform of the current target bitmap\[cq]s shader. +.PP +Returns true on success. +Otherwise returns false, e.g.\ if the uniform by that name does not +exist in the shader. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_use_shader(3) diff --git a/allegro/docs/man/al_set_shader_int_vector.3 b/allegro/docs/man/al_set_shader_int_vector.3 new file mode 100644 index 00000000..1f30b566 --- /dev/null +++ b/allegro/docs/man/al_set_shader_int_vector.3 @@ -0,0 +1,54 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_shader_int_vector" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_shader_int_vector - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_shader_int_vector(const char *name, + int num_components, const int *i, int num_elems) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets an integer vector array uniform of the current target bitmap\[cq]s +shader. +The `num_components' parameter can take one of the values 1, 2, 3 or 4. +If it is 1 then an array of `num_elems' integer elements is added. +Otherwise each added array element is assumed to be a vector with 2, 3 +or 4 components in it. +.PP +For example, if you have a GLSL uniform declared as +\f[C]uniform ivec3 flowers[4]\f[R] or an HLSL uniform declared as +\f[C]uniform int3 flowers[4]\f[R], then you\[cq]d use this function from +your code like so: +.IP +.nf +\f[C] +int flowers[4][3] = +{ + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9}, + {2, 5, 7} +}; + +al_set_shader_int_vector(\[dq]flowers\[dq], 3, (int*)flowers, 4); +\f[R] +.fi +.PP +Returns true on success. +Otherwise returns false, e.g.\ if the uniform by that name does not +exist in the shader. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_set_shader_float_vector(3), al_use_shader(3) diff --git a/allegro/docs/man/al_set_shader_matrix.3 b/allegro/docs/man/al_set_shader_matrix.3 new file mode 100644 index 00000000..dd94e042 --- /dev/null +++ b/allegro/docs/man/al_set_shader_matrix.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_shader_matrix" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_shader_matrix - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_shader_matrix(const char *name, + const ALLEGRO_TRANSFORM *matrix) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets a matrix uniform of the current target bitmap\[cq]s shader. +.PP +Returns true on success. +Otherwise returns false, e.g.\ if the uniform by that name does not +exist in the shader. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_use_shader(3) diff --git a/allegro/docs/man/al_set_shader_sampler.3 b/allegro/docs/man/al_set_shader_sampler.3 new file mode 100644 index 00000000..a26ac06e --- /dev/null +++ b/allegro/docs/man/al_set_shader_sampler.3 @@ -0,0 +1,44 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_shader_sampler" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_shader_sampler - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_shader_sampler(const char *name, + ALLEGRO_BITMAP *bitmap, int unit) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets a texture sampler uniform and texture unit of the current target +bitmap\[cq]s shader. +The given bitmap must be a video bitmap. +.PP +Different samplers should use different units. +The bitmap passed to Allegro\[cq]s drawing functions uses the 0th unit, +so if you\[cq]re planning on using the \f[C]al_tex\f[R] variable in your +pixel shader as well as another sampler, set the other sampler to use a +unit different from 0. +With the primitives addon, it is possible to free up the 0th unit by +passing \f[C]NULL\f[R] as the texture argument to the relevant drawing +functions. +In this case, you may set a sampler to use the 0th unit and thus not use +\f[C]al_tex\f[R] (the \f[C]al_use_tex\f[R] variable will be set to +\f[C]false\f[R]). +.PP +Returns true on success. +Otherwise returns false, e.g.\ if the uniform by that name does not +exist in the shader. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_use_shader(3) diff --git a/allegro/docs/man/al_set_standard_file_interface.3 b/allegro/docs/man/al_set_standard_file_interface.3 new file mode 100644 index 00000000..abea28ab --- /dev/null +++ b/allegro/docs/man/al_set_standard_file_interface.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_standard_file_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_standard_file_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_standard_file_interface(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the ALLEGRO_FILE_INTERFACE(3) table to the default, for the calling +thread. +This will change the handler for later calls to al_fopen(3). +.SH SEE ALSO +.PP +al_set_new_file_interface(3) diff --git a/allegro/docs/man/al_set_standard_fs_interface.3 b/allegro/docs/man/al_set_standard_fs_interface.3 new file mode 100644 index 00000000..42348b03 --- /dev/null +++ b/allegro/docs/man/al_set_standard_fs_interface.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_standard_fs_interface" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_standard_fs_interface - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_standard_fs_interface(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the ALLEGRO_FS_INTERFACE(3) table to the default, for the calling +thread. +.SH SEE ALSO +.PP +al_set_fs_interface(3). diff --git a/allegro/docs/man/al_set_system_mouse_cursor.3 b/allegro/docs/man/al_set_system_mouse_cursor.3 new file mode 100644 index 00000000..c69fc6d9 --- /dev/null +++ b/allegro/docs/man/al_set_system_mouse_cursor.3 @@ -0,0 +1,71 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_system_mouse_cursor" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_system_mouse_cursor - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the given system mouse cursor to be the current mouse cursor for the +given display. +If the cursor is currently `shown' (as opposed to `hidden') the change +is immediately visible. +.PP +If the cursor doesn\[cq]t exist on the current platform another cursor +will be silently be substituted. +.PP +The cursors are: +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT +.IP \[bu] 2 +ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_set_mouse_cursor(3), al_show_mouse_cursor(3), al_hide_mouse_cursor(3) diff --git a/allegro/docs/man/al_set_target_backbuffer.3 b/allegro/docs/man/al_set_target_backbuffer.3 new file mode 100644 index 00000000..70febfa2 --- /dev/null +++ b/allegro/docs/man/al_set_target_backbuffer.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_target_backbuffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_target_backbuffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_target_backbuffer(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Same as \f[C]al_set_target_bitmap(al_get_backbuffer(display));\f[R] +.SH SEE ALSO +.PP +al_set_target_bitmap(3), al_get_backbuffer(3) diff --git a/allegro/docs/man/al_set_target_bitmap.3 b/allegro/docs/man/al_set_target_bitmap.3 new file mode 100644 index 00000000..20cd710e --- /dev/null +++ b/allegro/docs/man/al_set_target_bitmap.3 @@ -0,0 +1,100 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_target_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_target_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_target_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function selects the bitmap to which all subsequent drawing +operations in the calling thread will draw to. +To return to drawing to a display, set the backbuffer of the display as +the target bitmap, using al_get_backbuffer(3). +As a convenience, you may also use al_set_target_backbuffer(3). +.PP +Each allegro bitmap maintains two transformation matrices associated +with it for drawing onto the bitmap. +There is a view matrix and a projection matrix. +When you call al_set_target_bitmap, these will be made current for the +bitmap, affecting global OpenGL and DirectX states depending on the +driver in use. +.PP +Each video bitmap is tied to a display. +When a video bitmap is set to as the target bitmap, the display that the +bitmap belongs to is automatically made \[lq]current\[rq] for the +calling thread (if it is not current already). +Then drawing other bitmaps which are tied to the same display can be +hardware accelerated. +.PP +A single display cannot be current for multiple threads simultaneously. +If you need to release a display, so it is not current for the calling +thread, call \f[C]al_set_target_bitmap(NULL);\f[R] +.PP +Setting a memory bitmap as the target bitmap will not change which +display is current for the calling thread. +.PP +On some platforms, Allegro automatically backs up the contents of video +bitmaps because they may be occasionally lost (see discussion in +al_create_bitmap(3)\[cq]s documentation). +If you\[cq]re completely recreating the bitmap contents often (e.g. +every frame) then you will get much better performance by creating the +target bitmap with ALLEGRO_NO_PRESERVE_TEXTURE flag. +.PP +OpenGL note: +.PP +Framebuffer objects (FBOs) allow OpenGL to directly draw to a bitmap, +which is very fast. +When using an OpenGL display, if all of the following conditions are met +an FBO will be created for use with the bitmap: +.IP \[bu] 2 +The GL_EXT_framebuffer_object OpenGL extension is available. +.IP \[bu] 2 +The bitmap is not a memory bitmap. +.IP \[bu] 2 +The bitmap is not currently locked. +.PP +In Allegro 5.0.0, you had to be careful as an FBO would be kept around +until the bitmap is destroyed or you explicitly called +al_remove_opengl_fbo(3) on the bitmap, wasting resources. +In newer versions, FBOs will be freed automatically when the bitmap is +no longer the target bitmap, \f[I]unless\f[R] you have called +al_get_opengl_fbo(3) to retrieve the FBO id. +.PP +In the following example, no FBO will be created: +.IP +.nf +\f[C] +lock = al_lock_bitmap(bitmap); +al_set_target_bitmap(bitmap); +al_put_pixel(x, y, color); +al_unlock_bitmap(bitmap); +\f[R] +.fi +.PP +The above allows using al_put_pixel(3) on a locked bitmap without +creating an FBO. +.PP +In this example an FBO is created however: +.IP +.nf +\f[C] +al_set_target_bitmap(bitmap); +al_draw_line(x1, y1, x2, y2, color, 0); +\f[R] +.fi +.PP +An OpenGL command will be used to directly draw the line into the +bitmap\[cq]s associated texture. +.SH SEE ALSO +.PP +al_get_target_bitmap(3), al_set_target_backbuffer(3) diff --git a/allegro/docs/man/al_set_thread_should_stop.3 b/allegro/docs/man/al_set_thread_should_stop.3 new file mode 100644 index 00000000..821f62b5 --- /dev/null +++ b/allegro/docs/man/al_set_thread_should_stop.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_thread_should_stop" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_thread_should_stop - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_thread_should_stop(ALLEGRO_THREAD *thread) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the flag to indicate \f[C]thread\f[R] should stop. +Returns immediately. +.SH SEE ALSO +.PP +al_join_thread(3), al_get_thread_should_stop(3). diff --git a/allegro/docs/man/al_set_timer_count.3 b/allegro/docs/man/al_set_timer_count.3 new file mode 100644 index 00000000..bddf6453 --- /dev/null +++ b/allegro/docs/man/al_set_timer_count.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_timer_count" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_timer_count - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_timer_count(ALLEGRO_TIMER *timer, int64_t new_count) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the timer\[cq]s counter value. +The timer can be started or stopped. +The count value may be positive or negative, but will always be +incremented by +1 at each tick. +.SH SEE ALSO +.PP +al_get_timer_count(3), al_add_timer_count(3) diff --git a/allegro/docs/man/al_set_timer_speed.3 b/allegro/docs/man/al_set_timer_speed.3 new file mode 100644 index 00000000..2d850674 --- /dev/null +++ b/allegro/docs/man/al_set_timer_speed.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_timer_speed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_timer_speed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_timer_speed(ALLEGRO_TIMER *timer, double new_speed_secs) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the timer\[cq]s speed, i.e.\ the rate at which its counter will be +incremented when it is started. +This can be done when the timer is started or stopped. +If the timer is currently running, it is made to look as though the +speed change occurred precisely at the last tick. +.PP +\f[I]speed_secs\f[R] has exactly the same meaning as with +al_create_timer(3). +.SH SEE ALSO +.PP +al_get_timer_speed(3) diff --git a/allegro/docs/man/al_set_video_playing.3 b/allegro/docs/man/al_set_video_playing.3 new file mode 100644 index 00000000..fc04b684 --- /dev/null +++ b/allegro/docs/man/al_set_video_playing.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_video_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_video_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_video_playing(ALLEGRO_VIDEO *video, bool play) +\f[R] +.fi +.SH DESCRIPTION +.PP +Paused or resumes playback. +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_set_voice_playing.3 b/allegro/docs/man/al_set_voice_playing.3 new file mode 100644 index 00000000..81e29963 --- /dev/null +++ b/allegro/docs/man/al_set_voice_playing.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_voice_playing" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_voice_playing - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_voice_playing(ALLEGRO_VOICE *voice, bool val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Change whether a voice is playing or not. +This can only work if the voice has a non-streaming object attached to +it, e.g.\ a sample instance. +On success the voice\[cq]s current sample position is reset. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_get_voice_playing(3) diff --git a/allegro/docs/man/al_set_voice_position.3 b/allegro/docs/man/al_set_voice_position.3 new file mode 100644 index 00000000..86b7ea0d --- /dev/null +++ b/allegro/docs/man/al_set_voice_position.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_voice_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_voice_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the voice position. +This can only work if the voice has a non-streaming object attached to +it, e.g.\ a sample instance. +.PP +Returns true on success, false on failure. +.SH SEE ALSO +.PP +al_get_voice_position(3). diff --git a/allegro/docs/man/al_set_window_constraints.3 b/allegro/docs/man/al_set_window_constraints.3 new file mode 100644 index 00000000..96edcc14 --- /dev/null +++ b/allegro/docs/man/al_set_window_constraints.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_window_constraints" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_window_constraints - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_set_window_constraints(ALLEGRO_DISPLAY *display, + int min_w, int min_h, int max_w, int max_h) +\f[R] +.fi +.SH DESCRIPTION +.PP +Constrains a non-fullscreen resizable display. +The constraints are a hint only, and are not necessarily respected by +the window environment. +A value of 0 for any of the parameters indicates no constraint for that +parameter. +.PP +The constraints will be applied to a display only after the +al_apply_window_constraints(3) function call. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_apply_window_constraints(3), al_get_window_constraints(3) diff --git a/allegro/docs/man/al_set_window_position.3 b/allegro/docs/man/al_set_window_position.3 new file mode 100644 index 00000000..ef574e6f --- /dev/null +++ b/allegro/docs/man/al_set_window_position.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_window_position" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_window_position - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the position on screen of a non-fullscreen display. +.SH SEE ALSO +.PP +al_get_window_position(3) diff --git a/allegro/docs/man/al_set_window_title.3 b/allegro/docs/man/al_set_window_title.3 new file mode 100644 index 00000000..9051bca7 --- /dev/null +++ b/allegro/docs/man/al_set_window_title.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_set_window_title" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_set_window_title - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_set_window_title(ALLEGRO_DISPLAY *display, const char *title) +\f[R] +.fi +.SH DESCRIPTION +.PP +Set the title on a display. +.SH SEE ALSO +.PP +al_set_display_icon(3), al_set_display_icons(3) diff --git a/allegro/docs/man/al_show_mouse_cursor.3 b/allegro/docs/man/al_show_mouse_cursor.3 new file mode 100644 index 00000000..bbe129a4 --- /dev/null +++ b/allegro/docs/man/al_show_mouse_cursor.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_show_mouse_cursor" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_show_mouse_cursor - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_show_mouse_cursor(ALLEGRO_DISPLAY *display) +\f[R] +.fi +.SH DESCRIPTION +.PP +Make a mouse cursor visible in the given display. +.PP +Returns true if a mouse cursor is shown as a result of the call (or one +already was visible), false otherwise. +.SH SEE ALSO +.PP +al_hide_mouse_cursor(3) diff --git a/allegro/docs/man/al_show_native_file_dialog.3 b/allegro/docs/man/al_show_native_file_dialog.3 new file mode 100644 index 00000000..56e39430 --- /dev/null +++ b/allegro/docs/man/al_show_native_file_dialog.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_show_native_file_dialog" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_show_native_file_dialog - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_show_native_file_dialog(ALLEGRO_DISPLAY *display, + ALLEGRO_FILECHOOSER *dialog) +\f[R] +.fi +.SH DESCRIPTION +.PP +Show the dialog window. +The display may be NULL, otherwise the given display is treated as the +parent if possible. +.PP +This function blocks the calling thread until it returns, so you may +want to spawn a thread with al_create_thread(3) and call it from inside +that thread. +.PP +Returns true on success, false on failure. diff --git a/allegro/docs/man/al_show_native_message_box.3 b/allegro/docs/man/al_show_native_message_box.3 new file mode 100644 index 00000000..b359972a --- /dev/null +++ b/allegro/docs/man/al_show_native_message_box.3 @@ -0,0 +1,95 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_show_native_message_box" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_show_native_message_box - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_show_native_message_box(ALLEGRO_DISPLAY *display, + char const *title, char const *heading, char const *text, + char const *buttons, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Show a native GUI message box. +This can be used for example to display an error message if creation of +an initial display fails. +The display may be NULL, otherwise the given display is treated as the +parent if possible. +.PP +The message box will have a single \[lq]OK\[rq] button and use the style +informative dialog boxes usually have on the native system. +If the \f[C]buttons\f[R] parameter is not NULL, you can instead specify +the button text in a string, with buttons separated by a vertical bar +(|). +.RS +.PP +\f[I]Note:\f[R] \f[C]buttons\f[R] parameter is currently unimplemented +on Windows. +.RE +.PP +The flags available are: +.TP +ALLEGRO_MESSAGEBOX_WARN +The message is a warning. +This may cause a different icon (or other effects). +.TP +ALLEGRO_MESSAGEBOX_ERROR +The message is an error. +.TP +ALLEGRO_MESSAGEBOX_QUESTION +The message is a question. +.TP +ALLEGRO_MESSAGEBOX_OK_CANCEL +Display a cancel button alongside the \[lq]OK\[rq] button. +Ignored if \f[C]buttons\f[R] is not NULL. +.TP +ALLEGRO_MESSAGEBOX_YES_NO +Display Yes/No buttons instead of the \[lq]OK\[rq] button. +Ignored if \f[C]buttons\f[R] is not NULL. +.PP +al_show_native_message_box(3) may be called without Allegro being +installed. +This is useful to report an error during initialisation of Allegro +itself. +.PP +Returns: +.IP \[bu] 2 +0 if the dialog window was closed without activating a button. +.IP \[bu] 2 +1 if the OK or Yes button was pressed. +.IP \[bu] 2 +2 if the Cancel or No button was pressed. +.PP +If \f[C]buttons\f[R] is not NULL, the number of the pressed button is +returned, starting with 1. +.PP +All of the remaining parameters must not be NULL. +.PP +If a message box could not be created then this returns 0, as if the +window was dismissed without activating a button. +.PP +Example: +.IP +.nf +\f[C] +int button = al_show_native_message_box( + display, + \[dq]Warning\[dq], + \[dq]Are you sure?\[dq], + \[dq]If you click yes then you are confirming that \[rs]\[dq]Yes\[rs]\[dq] \[dq] + \[dq]is your response to the query which you have \[dq] + \[dq]generated by the action you took to open this \[dq] + \[dq]message box.\[dq], + NULL, + ALLEGRO_MESSAGEBOX_YES_NO +); +\f[R] +.fi diff --git a/allegro/docs/man/al_shutdown_font_addon.3 b/allegro/docs/man/al_shutdown_font_addon.3 new file mode 100644 index 00000000..8d7d8bdb --- /dev/null +++ b/allegro/docs/man/al_shutdown_font_addon.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_shutdown_font_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_shutdown_font_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_shutdown_font_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Shut down the font addon. +This is done automatically at program exit, but can be called any time +the user wishes as well. +.SH SEE ALSO +.PP +al_init_font_addon(3) diff --git a/allegro/docs/man/al_shutdown_image_addon.3 b/allegro/docs/man/al_shutdown_image_addon.3 new file mode 100644 index 00000000..cfa1eace --- /dev/null +++ b/allegro/docs/man/al_shutdown_image_addon.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_shutdown_image_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_shutdown_image_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_shutdown_image_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Shut down the image addon. +This is done automatically at program exit, but can be called any time +the user wishes as well. diff --git a/allegro/docs/man/al_shutdown_native_dialog_addon.3 b/allegro/docs/man/al_shutdown_native_dialog_addon.3 new file mode 100644 index 00000000..0714884c --- /dev/null +++ b/allegro/docs/man/al_shutdown_native_dialog_addon.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_shutdown_native_dialog_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_shutdown_native_dialog_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_shutdown_native_dialog_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Shut down the native dialog addon. +.SH SINCE +.PP +5.0.9, 5.1.5 +.SH SEE ALSO +.PP +al_init_native_dialog_addon(3) diff --git a/allegro/docs/man/al_shutdown_primitives_addon.3 b/allegro/docs/man/al_shutdown_primitives_addon.3 new file mode 100644 index 00000000..fc7d3a11 --- /dev/null +++ b/allegro/docs/man/al_shutdown_primitives_addon.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_shutdown_primitives_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_shutdown_primitives_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_shutdown_primitives_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Shut down the primitives addon. +This is done automatically at program exit, but can be called any time +the user wishes as well. +.SH SEE ALSO +.PP +al_init_primitives_addon(3) diff --git a/allegro/docs/man/al_shutdown_ttf_addon.3 b/allegro/docs/man/al_shutdown_ttf_addon.3 new file mode 100644 index 00000000..40456960 --- /dev/null +++ b/allegro/docs/man/al_shutdown_ttf_addon.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_shutdown_ttf_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_shutdown_ttf_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_shutdown_ttf_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Unloads the ttf addon again. +You normally don\[cq]t need to call this. diff --git a/allegro/docs/man/al_shutdown_video_addon.3 b/allegro/docs/man/al_shutdown_video_addon.3 new file mode 100644 index 00000000..86a3234d --- /dev/null +++ b/allegro/docs/man/al_shutdown_video_addon.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_shutdown_video_addon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_shutdown_video_addon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_shutdown_video_addon(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Shut down the video addon. +This is done automatically at program exit, but can be called any time +the user wishes as well. +.SH SINCE +.PP +5.1.12 diff --git a/allegro/docs/man/al_signal_cond.3 b/allegro/docs/man/al_signal_cond.3 new file mode 100644 index 00000000..2a53b81e --- /dev/null +++ b/allegro/docs/man/al_signal_cond.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_signal_cond" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_signal_cond - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_signal_cond(ALLEGRO_COND *cond) +\f[R] +.fi +.SH DESCRIPTION +.PP +Unblock at least one thread waiting on a condition variable. +.PP +Generally you should use al_broadcast_cond(3) but al_signal_cond(3) may +be more efficient when it\[cq]s applicable. +.SH SEE ALSO +.PP +al_broadcast_cond(3). diff --git a/allegro/docs/man/al_start_audio_recorder.3 b/allegro/docs/man/al_start_audio_recorder.3 new file mode 100644 index 00000000..9e6385d5 --- /dev/null +++ b/allegro/docs/man/al_start_audio_recorder.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_start_audio_recorder" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_start_audio_recorder - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_start_audio_recorder(ALLEGRO_AUDIO_RECORDER *r) +\f[R] +.fi +.SH DESCRIPTION +.PP +Begin recording into the fragment buffer. +Once a complete fragment has been captured (as specified in +al_create_audio_recorder(3)), an +ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT(3) event will be triggered. +.PP +Returns true if it was able to begin recording. +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/al_start_thread.3 b/allegro/docs/man/al_start_thread.3 new file mode 100644 index 00000000..d6440a0a --- /dev/null +++ b/allegro/docs/man/al_start_thread.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_start_thread" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_start_thread - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_start_thread(ALLEGRO_THREAD *thread) +\f[R] +.fi +.SH DESCRIPTION +.PP +When a thread is created, it is initially in a suspended state. +Calling al_start_thread(3) will start its actual execution. +.PP +Starting a thread which has already been started does nothing. +.SH SEE ALSO +.PP +al_create_thread(3). diff --git a/allegro/docs/man/al_start_timer.3 b/allegro/docs/man/al_start_timer.3 new file mode 100644 index 00000000..f71a2e8f --- /dev/null +++ b/allegro/docs/man/al_start_timer.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_start_timer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_start_timer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_start_timer(ALLEGRO_TIMER *timer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Start the timer specified. +From then, the timer\[cq]s counter will increment at a constant rate, +and it will begin generating events. +Starting a timer that is already started does nothing. +Starting a timer that was stopped will reset the timer\[cq]s counter, +effectively restarting the timer from the beginning. +.SH SEE ALSO +.PP +al_stop_timer(3), al_get_timer_started(3), al_resume_timer(3) diff --git a/allegro/docs/man/al_start_video.3 b/allegro/docs/man/al_start_video.3 new file mode 100644 index 00000000..312a9257 --- /dev/null +++ b/allegro/docs/man/al_start_video.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_start_video" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_start_video - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_start_video(ALLEGRO_VIDEO *video, ALLEGRO_MIXER *mixer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Starts streaming the video from the beginning. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_start_video_with_voice.3 b/allegro/docs/man/al_start_video_with_voice.3 new file mode 100644 index 00000000..805c280b --- /dev/null +++ b/allegro/docs/man/al_start_video_with_voice.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_start_video_with_voice" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_start_video_with_voice - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_start_video_with_voice(ALLEGRO_VIDEO *video, ALLEGRO_VOICE *voice) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_start_video(3) but audio is routed to the provided voice. +.SH SINCE +.PP +5.1.0 diff --git a/allegro/docs/man/al_stop_audio_recorder.3 b/allegro/docs/man/al_stop_audio_recorder.3 new file mode 100644 index 00000000..ddf2e80b --- /dev/null +++ b/allegro/docs/man/al_stop_audio_recorder.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_stop_audio_recorder" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_stop_audio_recorder - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_stop_audio_recorder(ALLEGRO_AUDIO_RECORDER *r) +\f[R] +.fi +.SH DESCRIPTION +.PP +Stop capturing audio data. +Note that the audio recorder is still active and consuming resources, so +if you are finished recording you should destroy it with +al_destroy_audio_recorder(3). +.PP +You may still receive a few events after you call this function as the +device flushes the buffer. +.PP +If you restart the recorder, it will begin recording at the beginning of +the next fragment buffer. +.SH SINCE +.PP +5.1.1 +.RS +.PP +\f[I][Unstable API]:\f[R] The API may need a slight redesign. +.RE diff --git a/allegro/docs/man/al_stop_haptic_effect.3 b/allegro/docs/man/al_stop_haptic_effect.3 new file mode 100644 index 00000000..d4ba2a83 --- /dev/null +++ b/allegro/docs/man/al_stop_haptic_effect.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_stop_haptic_effect" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_stop_haptic_effect - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_stop_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Stops playing a previously uploaded haptic effect. +The play_id must be a valid ALLEGRO_HAPTIC_EFFECT_ID(3) obtained from +al_upload_haptic_effect(3), al_upload_and_play_haptic_effect(3) or +al_rumble_haptic(3). +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_stop_sample.3 b/allegro/docs/man/al_stop_sample.3 new file mode 100644 index 00000000..dc591668 --- /dev/null +++ b/allegro/docs/man/al_stop_sample.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_stop_sample" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_stop_sample - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_stop_sample(ALLEGRO_SAMPLE_ID *spl_id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Stop the sample started by al_play_sample(3). +.SH SEE ALSO +.PP +al_stop_samples(3) diff --git a/allegro/docs/man/al_stop_sample_instance.3 b/allegro/docs/man/al_stop_sample_instance.3 new file mode 100644 index 00000000..15ce3617 --- /dev/null +++ b/allegro/docs/man/al_stop_sample_instance.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_stop_sample_instance" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_stop_sample_instance - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_stop_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl) +\f[R] +.fi +.SH DESCRIPTION +.PP +Stop an sample instance playing. +.SH SEE ALSO +.PP +al_play_sample_instance(3) diff --git a/allegro/docs/man/al_stop_samples.3 b/allegro/docs/man/al_stop_samples.3 new file mode 100644 index 00000000..5548a18d --- /dev/null +++ b/allegro/docs/man/al_stop_samples.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_stop_samples" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_stop_samples - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_stop_samples(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Stop all samples started by al_play_sample(3). +.SH SEE ALSO +.PP +al_stop_sample(3) diff --git a/allegro/docs/man/al_stop_timer.3 b/allegro/docs/man/al_stop_timer.3 new file mode 100644 index 00000000..73c6ca49 --- /dev/null +++ b/allegro/docs/man/al_stop_timer.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_stop_timer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_stop_timer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_stop_timer(ALLEGRO_TIMER *timer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Stop the timer specified. +The timer\[cq]s counter will stop incrementing and it will stop +generating events. +Stopping a timer that is already stopped does nothing. +.SH SEE ALSO +.PP +al_start_timer(3), al_get_timer_started(3), al_resume_timer(3) diff --git a/allegro/docs/man/al_store_state.3 b/allegro/docs/man/al_store_state.3 new file mode 100644 index 00000000..751839f7 --- /dev/null +++ b/allegro/docs/man/al_store_state.3 @@ -0,0 +1,46 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_store_state" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_store_state - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] + +void al_store_state(ALLEGRO_STATE *state, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Stores part of the state of the current thread in the given +ALLEGRO_STATE(3) object. +The flags parameter can take any bit-combination of these flags: +.IP \[bu] 2 +ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS - new_display_format, +new_display_refresh_rate, new_display_flags +.IP \[bu] 2 +ALLEGRO_STATE_NEW_BITMAP_PARAMETERS - new_bitmap_format, +new_bitmap_flags +.IP \[bu] 2 +ALLEGRO_STATE_DISPLAY - current_display +.IP \[bu] 2 +ALLEGRO_STATE_TARGET_BITMAP - target_bitmap +.IP \[bu] 2 +ALLEGRO_STATE_BLENDER - blender +.IP \[bu] 2 +ALLEGRO_STATE_TRANSFORM - current_transformation +.IP \[bu] 2 +ALLEGRO_STATE_PROJECTION_TRANSFORM - current_projection_transformation +.IP \[bu] 2 +ALLEGRO_STATE_NEW_FILE_INTERFACE - new_file_interface +.IP \[bu] 2 +ALLEGRO_STATE_BITMAP - same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS and +ALLEGRO_STATE_TARGET_BITMAP +.IP \[bu] 2 +ALLEGRO_STATE_ALL - all of the above +.SH SEE ALSO +.PP +al_restore_state(3), ALLEGRO_STATE(3) diff --git a/allegro/docs/man/al_toggle_menu_item_flags.3 b/allegro/docs/man/al_toggle_menu_item_flags.3 new file mode 100644 index 00000000..b5e9ee3b --- /dev/null +++ b/allegro/docs/man/al_toggle_menu_item_flags.3 @@ -0,0 +1,36 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_toggle_menu_item_flags" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_toggle_menu_item_flags - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_toggle_menu_item_flags(ALLEGRO_MENU *menu, int pos, int flags) +\f[R] +.fi +.SH DESCRIPTION +.PP +Toggles the specified menu item\[cq]s flags. +See al_insert_menu_item(3) for a description of the available flags. +.PP +Returns a bitfield of only the specified flags that are set after the +toggle. +A flag that was not toggled will not be returned, even if it is set. +Returns -1 if the id is invalid. +.SH SINCE +.PP +5.1.0 +.RS +.PP +\f[I][Unstable API]:\f[R] Redundant with +\f[C]al_get/set_menu_item_flags\f[R]. +.RE +.SH SEE ALSO +.PP +al_get_menu_item_flags(3), al_set_menu_item_flags(3) diff --git a/allegro/docs/man/al_transform_coordinates.3 b/allegro/docs/man/al_transform_coordinates.3 new file mode 100644 index 00000000..b96b8fe8 --- /dev/null +++ b/allegro/docs/man/al_transform_coordinates.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_transform_coordinates" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_transform_coordinates - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_transform_coordinates(const ALLEGRO_TRANSFORM *trans, float *x, float *y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Transform a pair of coordinates. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to use +.IP \[bu] 2 +x, y - Pointers to the coordinates +.SH SEE ALSO +.PP +al_use_transform(3), al_transform_coordinates_3d(3) diff --git a/allegro/docs/man/al_transform_coordinates_3d.3 b/allegro/docs/man/al_transform_coordinates_3d.3 new file mode 100644 index 00000000..406fd4b6 --- /dev/null +++ b/allegro/docs/man/al_transform_coordinates_3d.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_transform_coordinates_3d" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_transform_coordinates_3d - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_transform_coordinates_3d(const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z) +\f[R] +.fi +.SH DESCRIPTION +.PP +Transform x, y, z coordinates. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to use +.IP \[bu] 2 +x, y, z - Pointers to the coordinates +.PP +Note: If you are using a projection transform you most likely will want +to use al_transform_coordinates_3d_projective(3) instead. +.PP +Since 5.1.9 +.SH SEE ALSO +.PP +al_use_transform(3), al_transform_coordinates(3) diff --git a/allegro/docs/man/al_transform_coordinates_3d_projective.3 b/allegro/docs/man/al_transform_coordinates_3d_projective.3 new file mode 100644 index 00000000..5255dd40 --- /dev/null +++ b/allegro/docs/man/al_transform_coordinates_3d_projective.3 @@ -0,0 +1,68 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_transform_coordinates_3d_projective" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_transform_coordinates_3d_projective - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_transform_coordinates_3d_projective(const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z) +\f[R] +.fi +.SH DESCRIPTION +.PP +Transform x, y, z as homogeneous coordinates. +This is the same as using al_transform_coordinates_4d(3) with the w +coordinate set to 1, then dividing x, y, z by the resulting w. +This will provide the same normalized coordinates Allegro will draw to +when a projective transform is in effect as set with +al_use_projection_transform(3). +To get the actual pixel coordinates from those translate and scale like +so (w and h would be the pixel dimensions of the target bitmap): +.IP +.nf +\f[C] +x = w / 2 + x * w / 2 +y = h / 2 - y * h / 2 +\f[R] +.fi +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to use +.IP \[bu] 2 +x, y, z - Pointers to the coordinates +.PP +Example: +.IP +.nf +\f[C] +ALLEGRO_TRANSFORM t2; +al_copy_transform(&t2, al_get_current_transform()); +al_compose_transform(&t2, al_get_current_projection_transform()); + +ALLEGRO_TRANSFORM t3; +al_identity_transform(&t3); +al_scale_transform(&t3, 0.5, -0.5); +al_translate_transform(&t3, 0.5, 0.5); +al_scale_transform(&t3, al_get_bitmap_width(al_get_target_bitmap()), + al_get_bitmap_height(al_get_target_bitmap())); + +al_transform_coordinates_3d_projective(&t2, &x, &y, &z); +// x, y now contain normalized coordinates +al_transform_coordinates(&t3, &x, &y); +// x, y now contain pixel coordinates +\f[R] +.fi +.PP +Since 5.2.4 +.SH SEE ALSO +.PP +al_use_transform(3), al_transform_coordinates(3), +al_transform_coordinates_3d(3), al_use_projection_transform(3) diff --git a/allegro/docs/man/al_transform_coordinates_4d.3 b/allegro/docs/man/al_transform_coordinates_4d.3 new file mode 100644 index 00000000..5675d09a --- /dev/null +++ b/allegro/docs/man/al_transform_coordinates_4d.3 @@ -0,0 +1,32 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_transform_coordinates_4d" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_transform_coordinates_4d - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_transform_coordinates_4d(const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z, float *w) +\f[R] +.fi +.SH DESCRIPTION +.PP +Transform x, y, z, w coordinates. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to use +.IP \[bu] 2 +x, y, z, w - Pointers to the coordinates +.PP +Since 5.2.4 +.SH SEE ALSO +.PP +al_use_transform(3), al_transform_coordinates(3), +al_transform_coordinates_3d(3) diff --git a/allegro/docs/man/al_translate_transform.3 b/allegro/docs/man/al_translate_transform.3 new file mode 100644 index 00000000..4bff2232 --- /dev/null +++ b/allegro/docs/man/al_translate_transform.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_translate_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_translate_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_translate_transform(ALLEGRO_TRANSFORM *trans, float x, float y) +\f[R] +.fi +.SH DESCRIPTION +.PP +Apply a translation to a transformation. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to alter +.IP \[bu] 2 +x, y - Translation +.SH SEE ALSO +.PP +al_rotate_transform(3), al_scale_transform(3), al_build_transform(3) diff --git a/allegro/docs/man/al_translate_transform_3d.3 b/allegro/docs/man/al_translate_transform_3d.3 new file mode 100644 index 00000000..ccd2788e --- /dev/null +++ b/allegro/docs/man/al_translate_transform_3d.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_translate_transform_3d" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_translate_transform_3d - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_translate_transform_3d(ALLEGRO_TRANSFORM *trans, float x, float y, + float z) +\f[R] +.fi +.SH DESCRIPTION +.PP +Combines the given transformation with a transformation which translates +coordinates by the given vector. +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +al_use_projection_transform(3) diff --git a/allegro/docs/man/al_transpose_transform.3 b/allegro/docs/man/al_transpose_transform.3 new file mode 100644 index 00000000..9bd11fb9 --- /dev/null +++ b/allegro/docs/man/al_transpose_transform.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_transpose_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_transpose_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_transpose_transform(ALLEGRO_TRANSFORM *trans) +\f[R] +.fi +.SH DESCRIPTION +.PP +Transposes the matrix of the given transform. +This can be used for inversing a rotation transform. +For example: +.IP +.nf +\f[C] +al_build_camera_transform(camera, 0, 0, 0, x, y, z, xu, yu, zu) +al_copy_transform(inverse, camera) +al_transpose_transform(camera) +// Now \[dq]inverse\[dq] will be a transformation rotating in the opposite +// direction from \[dq]camera\[dq]. Note that this only works if the camera +// position is 0/0/0 as in the example. +\f[R] +.fi +.SH SINCE +.PP +5.2.5 diff --git a/allegro/docs/man/al_triangulate_polygon.3 b/allegro/docs/man/al_triangulate_polygon.3 new file mode 100644 index 00000000..7e551791 --- /dev/null +++ b/allegro/docs/man/al_triangulate_polygon.3 @@ -0,0 +1,53 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_triangulate_polygon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_triangulate_polygon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_triangulate_polygon( + const float* vertices, size_t vertex_stride, const int* vertex_counts, + void (*emit_triangle)(int, int, int, void*), void* userdata) +\f[R] +.fi +.SH DESCRIPTION +.PP +Divides a simple polygon into triangles, with zero or more other simple +polygons subtracted from it - the holes. +The holes cannot touch or intersect with the outline of the main +polygon. +Simple means the polygon does not have to be convex but must not be +self-overlapping. +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +vertices - Interleaved array of (x, y) vertex coordinates for each of +the polygons, including holes. +.IP \[bu] 2 +vertex_stride - distance (in bytes) between successive pairs of vertices +in the array. +.IP \[bu] 2 +vertex_counts - Number of vertices for each polygon. +The number of vertices in the main polygon is given by vertex_counts[0] +and must be at least three. +Subsequent elements indicate the number of vertices in each hole. +The array must be terminated with an element with value zero. +.IP \[bu] 2 +emit_triangle - a function to be called for every set of three points +that form a triangle. +The function is passed the indices of the points in \f[C]vertices\f[R] +and \f[C]userdata\f[R]. +.IP \[bu] 2 +userdata - arbitrary data to be passed to emit_triangle. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_draw_filled_polygon_with_holes(3) diff --git a/allegro/docs/man/al_ungrab_mouse.3 b/allegro/docs/man/al_ungrab_mouse.3 new file mode 100644 index 00000000..d50ba328 --- /dev/null +++ b/allegro/docs/man/al_ungrab_mouse.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ungrab_mouse" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ungrab_mouse - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ungrab_mouse(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Stop confining the mouse cursor to any display belonging to the program. +.RS +.PP +\f[I]Note:\f[R] not yet implemented on Mac OS X. +.RE +.SH SEE ALSO +.PP +al_grab_mouse(3) diff --git a/allegro/docs/man/al_uninstall_audio.3 b/allegro/docs/man/al_uninstall_audio.3 new file mode 100644 index 00000000..a0d8d090 --- /dev/null +++ b/allegro/docs/man/al_uninstall_audio.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_uninstall_audio" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_uninstall_audio - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_uninstall_audio(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uninstalls the audio subsystem. +.SH SEE ALSO +.PP +al_install_audio(3) diff --git a/allegro/docs/man/al_uninstall_haptic.3 b/allegro/docs/man/al_uninstall_haptic.3 new file mode 100644 index 00000000..cce20989 --- /dev/null +++ b/allegro/docs/man/al_uninstall_haptic.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_uninstall_haptic" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_uninstall_haptic - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_uninstall_haptic(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uninstalls the haptic device subsystem. +This is useful since on some platforms haptic effects are bound to the +active display. +.PP +If you need to close and reopen your active display for example, then +you should call al_uninstall_haptic(3) before closing the display, and +al_install_haptic(3) after opening it again. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_uninstall_joystick.3 b/allegro/docs/man/al_uninstall_joystick.3 new file mode 100644 index 00000000..10686ba3 --- /dev/null +++ b/allegro/docs/man/al_uninstall_joystick.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_uninstall_joystick" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_uninstall_joystick - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_uninstall_joystick(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uninstalls the active joystick driver. +All outstanding ALLEGRO_JOYSTICK(3) structures are invalidated. +If no joystick driver was active, this function does nothing. +.PP +This function is automatically called when Allegro is shut down. +.SH SEE ALSO +.PP +al_install_joystick(3) diff --git a/allegro/docs/man/al_uninstall_keyboard.3 b/allegro/docs/man/al_uninstall_keyboard.3 new file mode 100644 index 00000000..a622b688 --- /dev/null +++ b/allegro/docs/man/al_uninstall_keyboard.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_uninstall_keyboard" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_uninstall_keyboard - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_uninstall_keyboard(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uninstalls the active keyboard driver, if any. +This will automatically unregister the keyboard event source with any +event queues. +.PP +This function is automatically called when Allegro is shut down. +.SH SEE ALSO +.PP +al_install_keyboard(3) diff --git a/allegro/docs/man/al_uninstall_mouse.3 b/allegro/docs/man/al_uninstall_mouse.3 new file mode 100644 index 00000000..8999f5dd --- /dev/null +++ b/allegro/docs/man/al_uninstall_mouse.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_uninstall_mouse" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_uninstall_mouse - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_uninstall_mouse(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uninstalls the active mouse driver, if any. +This will automatically unregister the mouse event source with any event +queues. +.PP +This function is automatically called when Allegro is shut down. diff --git a/allegro/docs/man/al_uninstall_system.3 b/allegro/docs/man/al_uninstall_system.3 new file mode 100644 index 00000000..1d039a45 --- /dev/null +++ b/allegro/docs/man/al_uninstall_system.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_uninstall_system" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_uninstall_system - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_uninstall_system(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Closes down the Allegro system. +.RS +.PP +Note: al_uninstall_system() can be called without a corresponding +al_install_system(3) call, e.g.\ from atexit(). +.RE diff --git a/allegro/docs/man/al_uninstall_touch_input.3 b/allegro/docs/man/al_uninstall_touch_input.3 new file mode 100644 index 00000000..1dfe0720 --- /dev/null +++ b/allegro/docs/man/al_uninstall_touch_input.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_uninstall_touch_input" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_uninstall_touch_input - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_uninstall_touch_input(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uninstalls the active touch input driver. +If no touch input driver was active, this function does nothing. +.PP +This function is automatically called when Allegro is shut down. +.SH SINCE +.PP +5.1.0 +.SH SEE ALSO +.PP +al_install_touch_input(3) diff --git a/allegro/docs/man/al_unlock_bitmap.3 b/allegro/docs/man/al_unlock_bitmap.3 new file mode 100644 index 00000000..196ddf71 --- /dev/null +++ b/allegro/docs/man/al_unlock_bitmap.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unlock_bitmap" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unlock_bitmap - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unlock_bitmap(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Unlock a previously locked bitmap or bitmap region. +If the bitmap is a video bitmap, the texture will be updated to match +the system memory copy (unless it was locked read only). +.SH SEE ALSO +.PP +al_lock_bitmap(3), al_lock_bitmap_region(3), al_lock_bitmap_blocked(3), +al_lock_bitmap_region_blocked(3) diff --git a/allegro/docs/man/al_unlock_index_buffer.3 b/allegro/docs/man/al_unlock_index_buffer.3 new file mode 100644 index 00000000..a2c08e39 --- /dev/null +++ b/allegro/docs/man/al_unlock_index_buffer.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unlock_index_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unlock_index_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unlock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Unlocks a previously locked index buffer. +.SH SINCE +.PP +5.1.8 +.SH SEE ALSO +.PP +ALLEGRO_INDEX_BUFFER(3), al_lock_index_buffer(3) diff --git a/allegro/docs/man/al_unlock_mutex.3 b/allegro/docs/man/al_unlock_mutex.3 new file mode 100644 index 00000000..bcca323e --- /dev/null +++ b/allegro/docs/man/al_unlock_mutex.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unlock_mutex" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unlock_mutex - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unlock_mutex(ALLEGRO_MUTEX *mutex) +\f[R] +.fi +.SH DESCRIPTION +.PP +Release the lock on \f[C]mutex\f[R] if the calling thread holds the lock +on it. +.PP +If the calling thread doesn\[cq]t hold the lock, or if the mutex is not +locked, undefined behaviour results. +.SH SEE ALSO +.PP +al_lock_mutex(3). diff --git a/allegro/docs/man/al_unlock_sample_id.3 b/allegro/docs/man/al_unlock_sample_id.3 new file mode 100644 index 00000000..6a82dea1 --- /dev/null +++ b/allegro/docs/man/al_unlock_sample_id.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unlock_sample_id" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unlock_sample_id - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unlock_sample_id(ALLEGRO_SAMPLE_ID *spl_id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Unlocks a ALLEGRO_SAMPLE_ID(3), allowing future calls to +al_play_sample(3) to reuse it if possible. +Note that after the id is unlocked, the ALLEGRO_SAMPLE_INSTANCE(3) that +was previously returned by al_lock_sample_id(3) will possibly be playing +a different sound, so you should only use it after locking the id again. +.SH SEE ALSO +.PP +al_play_sample(3), al_lock_sample_id(3) +.SH SINCE +.PP +5.2.3 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE diff --git a/allegro/docs/man/al_unlock_vertex_buffer.3 b/allegro/docs/man/al_unlock_vertex_buffer.3 new file mode 100644 index 00000000..92f4b41e --- /dev/null +++ b/allegro/docs/man/al_unlock_vertex_buffer.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unlock_vertex_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unlock_vertex_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unlock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer) +\f[R] +.fi +.SH DESCRIPTION +.PP +Unlocks a previously locked vertex buffer. +.SH SINCE +.PP +5.1.3 +.SH SEE ALSO +.PP +ALLEGRO_VERTEX_BUFFER(3), al_lock_vertex_buffer(3) diff --git a/allegro/docs/man/al_unmap_rgb.3 b/allegro/docs/man/al_unmap_rgb.3 new file mode 100644 index 00000000..70c7a49b --- /dev/null +++ b/allegro/docs/man/al_unmap_rgb.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unmap_rgb" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unmap_rgb - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unmap_rgb(ALLEGRO_COLOR color, + unsigned char *r, unsigned char *g, unsigned char *b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves components of an ALLEGRO_COLOR, ignoring alpha. +Components will range from 0-255. +.PP +This function can be called before Allegro is initialized. +.SH SEE ALSO +.PP +al_unmap_rgba(3), al_unmap_rgba_f(3), al_unmap_rgb_f(3) diff --git a/allegro/docs/man/al_unmap_rgb_f.3 b/allegro/docs/man/al_unmap_rgb_f.3 new file mode 100644 index 00000000..24f010d3 --- /dev/null +++ b/allegro/docs/man/al_unmap_rgb_f.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unmap_rgb_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unmap_rgb_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unmap_rgb_f(ALLEGRO_COLOR color, float *r, float *g, float *b) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves components of an ALLEGRO_COLOR(3), ignoring alpha. +Components will range from 0.0f-1.0f. +.PP +This function can be called before Allegro is initialized. +.SH SEE ALSO +.PP +al_unmap_rgba(3), al_unmap_rgb(3), al_unmap_rgba_f(3) diff --git a/allegro/docs/man/al_unmap_rgba.3 b/allegro/docs/man/al_unmap_rgba.3 new file mode 100644 index 00000000..a0596636 --- /dev/null +++ b/allegro/docs/man/al_unmap_rgba.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unmap_rgba" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unmap_rgba - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unmap_rgba(ALLEGRO_COLOR color, + unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves components of an ALLEGRO_COLOR(3). +Components will range from 0-255. +.PP +This function can be called before Allegro is initialized. +.SH SEE ALSO +.PP +al_unmap_rgb(3), al_unmap_rgba_f(3), al_unmap_rgb_f(3) diff --git a/allegro/docs/man/al_unmap_rgba_f.3 b/allegro/docs/man/al_unmap_rgba_f.3 new file mode 100644 index 00000000..6fac6828 --- /dev/null +++ b/allegro/docs/man/al_unmap_rgba_f.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unmap_rgba_f" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unmap_rgba_f - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unmap_rgba_f(ALLEGRO_COLOR color, + float *r, float *g, float *b, float *a) +\f[R] +.fi +.SH DESCRIPTION +.PP +Retrieves components of an ALLEGRO_COLOR(3). +Components will range from 0.0f-1.0f. +.PP +This function can be called before Allegro is initialized. +.SH SEE ALSO +.PP +al_unmap_rgba(3), al_unmap_rgb(3), al_unmap_rgb_f(3) diff --git a/allegro/docs/man/al_unref_user_event.3 b/allegro/docs/man/al_unref_user_event.3 new file mode 100644 index 00000000..432a820a --- /dev/null +++ b/allegro/docs/man/al_unref_user_event.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unref_user_event" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unref_user_event - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unref_user_event(ALLEGRO_USER_EVENT *event) +\f[R] +.fi +.SH DESCRIPTION +.PP +Decrease the reference count of a user-defined event. +This must be called on any user event that you get from +al_get_next_event(3), al_peek_next_event(3), al_wait_for_event(3), etc. +which is reference counted. +This function does nothing if the event is not reference counted. +.SH SEE ALSO +.PP +al_emit_user_event(3), ALLEGRO_USER_EVENT(3) diff --git a/allegro/docs/man/al_unregister_event_source.3 b/allegro/docs/man/al_unregister_event_source.3 new file mode 100644 index 00000000..9c713358 --- /dev/null +++ b/allegro/docs/man/al_unregister_event_source.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_unregister_event_source" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_unregister_event_source - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_unregister_event_source(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT_SOURCE *source) +\f[R] +.fi +.SH DESCRIPTION +.PP +Unregister an event source with an event queue. +If the event source is not actually registered with the event queue, +nothing happens. +.PP +If the queue had any events in it which originated from the event +source, they will no longer be in the queue after this call. +.SH SEE ALSO +.PP +al_register_event_source(3) diff --git a/allegro/docs/man/al_update_display_region.3 b/allegro/docs/man/al_update_display_region.3 new file mode 100644 index 00000000..d4e7ea53 --- /dev/null +++ b/allegro/docs/man/al_update_display_region.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_update_display_region" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_update_display_region - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_update_display_region(int x, int y, int width, int height) +\f[R] +.fi +.SH DESCRIPTION +.PP +Does the same as al_flip_display(3), but tries to update only the +specified region. +With many drivers this is not possible, but for some it can improve +performance. +If this is not supported, this function falls back to the behavior of +al_flip_display(3). +You can query the support for this function using +\f[C]al_get_display_option(display, ALLEGRO_UPDATE_DISPLAY_REGION)\f[R]. +.SH SEE ALSO +.PP +al_flip_display(3), al_get_display_option(3) diff --git a/allegro/docs/man/al_update_fs_entry.3 b/allegro/docs/man/al_update_fs_entry.3 new file mode 100644 index 00000000..7dbb6494 --- /dev/null +++ b/allegro/docs/man/al_update_fs_entry.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_update_fs_entry" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_update_fs_entry - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_update_fs_entry(ALLEGRO_FS_ENTRY *e) +\f[R] +.fi +.SH DESCRIPTION +.PP +Updates file status information for a filesystem entry. +File status information is automatically updated when the entry is +created, however you may update it again with this function, e.g.\ in +case it changed. +.PP +Returns true on success, false on failure. +Fills in errno to indicate the error. +.SH SEE ALSO +.PP +al_get_errno(3), al_get_fs_entry_atime(3), al_get_fs_entry_ctime(3), +al_get_fs_entry_mode(3) diff --git a/allegro/docs/man/al_upload_and_play_haptic_effect.3 b/allegro/docs/man/al_upload_and_play_haptic_effect.3 new file mode 100644 index 00000000..0febd6fe --- /dev/null +++ b/allegro/docs/man/al_upload_and_play_haptic_effect.3 @@ -0,0 +1,42 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_upload_and_play_haptic_effect" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_upload_and_play_haptic_effect - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_upload_and_play_haptic_effect(ALLEGRO_HAPTIC *hap, + ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id, int loop) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uploads the haptic effect to the device and starts playback immediately. +Returns true if the upload and playback were successful, false if either +failed. +.PP +In case false is returned, the haptic effect will be automatically +released as if al_release_haptic_effect(3) had been called, so there is +no need to call it again manually in this case. +However, if true is returned, it is necessary to call +al_release_haptic_effect(3) when the effect isn\[cq]t needed anymore, to +prevent the amount of available effects on the haptic devicefrom running +out. +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE +.SH SEE ALSO +.PP +al_upload_haptic_effect(3), al_play_haptic_effect(3) diff --git a/allegro/docs/man/al_upload_haptic_effect.3 b/allegro/docs/man/al_upload_haptic_effect.3 new file mode 100644 index 00000000..0ce159f5 --- /dev/null +++ b/allegro/docs/man/al_upload_haptic_effect.3 @@ -0,0 +1,40 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_upload_haptic_effect" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_upload_haptic_effect - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_upload_haptic_effect(ALLEGRO_HAPTIC *hap, + ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uploads the haptic effect to the device. +The haptic effect must have been filled in completely and correctly. +You must also pass in a pointer to a user allocated +ALLEGRO_HAPTIC_EFFECT_ID(3). +This \f[C]id\f[R] can be used to control playback of the effect. +Returns true if the effect was successfully uploaded, false if not. +.PP +The function al_get_max_haptic_effects(3) returns how many effects can +be uploaded to the device at the same time. +.PP +The same haptic effect can be uploaded several times, as long as care is +taken to pass in a different ALLEGRO_HAPTIC_EFFECT_ID(3). +.SH SINCE +.PP +5.1.8 +.RS +.PP +\f[I][Unstable API]:\f[R] Perhaps could be simplified due to limited +support for all the exposed features across all of the platforms. +Awaiting feedback from users. +.RE diff --git a/allegro/docs/man/al_use_projection_transform.3 b/allegro/docs/man/al_use_projection_transform.3 new file mode 100644 index 00000000..9e25e988 --- /dev/null +++ b/allegro/docs/man/al_use_projection_transform.3 @@ -0,0 +1,65 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_use_projection_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_use_projection_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_use_projection_transform(const ALLEGRO_TRANSFORM *trans) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the projection transformation to be used for the drawing operations +on the target bitmap (each bitmap maintains its own projection +transformation). +Every drawing operation after this call will be transformed using this +transformation. +To return default behavior, call this function with an orthographic +transform like so: +.IP +.nf +\f[C] +ALLEGRO_TRANSFORM trans; +al_identity_transform(&trans); +al_orthographic_transform(&trans, 0, 0, -1.0, al_get_bitmap_width(bitmap), + al_get_bitmap_height(bitmap), 1.0); + +al_set_target_bitmap(bitmap); +al_use_projection_transform(&trans); +\f[R] +.fi +.PP +The orthographic transformation above is the default projection +transform. +.PP +This function does nothing if there is no target bitmap. +This function also does nothing if the bitmap is a memory bitmap +(i.e.\ memory bitmaps always use an orthographic transform like the +snippet above). +Note that the projection transform will be reset to default if a video +bitmap is converted to a memory bitmap. +Additionally, if the bitmap in question is the backbuffer, it\[cq]s +projection transformation will be reset to default if it is resized. +Lastly, when you draw a memory bitmap to a video bitmap with a custom +projection transform, this transformation will be ignored +(i.e.\ it\[cq]ll be as if the projection transform of the target bitmap +was temporarily reset to default). +.PP +The parameter is passed by reference as an optimization to avoid the +overhead of stack copying. +The reference will not be stored in the Allegro library so it is safe to +pass references to local variables. +.SH SINCE +.PP +5.1.9 +.SH SEE ALSO +.PP +al_get_current_projection_transform(3), al_perspective_transform(3), +al_orthographic_transform(3) diff --git a/allegro/docs/man/al_use_shader.3 b/allegro/docs/man/al_use_shader.3 new file mode 100644 index 00000000..12db24a0 --- /dev/null +++ b/allegro/docs/man/al_use_shader.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_use_shader" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_use_shader - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_use_shader(ALLEGRO_SHADER *shader) +\f[R] +.fi +.SH DESCRIPTION +.PP +Uses the shader for subsequent drawing operations on the current target +bitmap. +Pass NULL to stop using any shader on the current target bitmap. +.PP +Returns true on success. +Otherwise returns false, e.g.\ because the shader is incompatible with +the target bitmap. +.SH SINCE +.PP +5.1.6 +.SH SEE ALSO +.PP +al_destroy_shader(3), al_set_shader_sampler(3), al_set_shader_matrix(3), +al_set_shader_int(3), al_set_shader_float(3), al_set_shader_bool(3), +al_set_shader_int_vector(3), al_set_shader_float_vector(3) diff --git a/allegro/docs/man/al_use_transform.3 b/allegro/docs/man/al_use_transform.3 new file mode 100644 index 00000000..558b8554 --- /dev/null +++ b/allegro/docs/man/al_use_transform.3 @@ -0,0 +1,49 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_use_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_use_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_use_transform(const ALLEGRO_TRANSFORM *trans) +\f[R] +.fi +.SH DESCRIPTION +.PP +Sets the transformation to be used for the the drawing operations on the +target bitmap (each bitmap maintains its own transformation). +Every drawing operation after this call will be transformed using this +transformation. +Call this function with an identity transformation to return to the +default behaviour. +.PP +This function does nothing if there is no target bitmap. +.PP +The parameter is passed by reference as an optimization to avoid the +overhead of stack copying. +The reference will not be stored in the Allegro library so it is safe to +pass references to local variables. +.IP +.nf +\f[C] +void setup_my_transformation(void) +{ + ALLEGRO_TRANSFORM transform; + al_translate_transform(&transform, 5, 10); + al_use_transform(&transform); +} +\f[R] +.fi +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to use +.SH SEE ALSO +.PP +al_get_current_transform(3), al_transform_coordinates(3) diff --git a/allegro/docs/man/al_ustr_append.3 b/allegro/docs/man/al_ustr_append.3 new file mode 100644 index 00000000..8083d443 --- /dev/null +++ b/allegro/docs/man/al_ustr_append.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_append" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_append - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_append(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Append \f[C]us2\f[R] to the end of \f[C]us1\f[R]. +.PP +Returns true on success, false on error. +.PP +This function can be used to append an arbitrary buffer: +.IP +.nf +\f[C] + ALLEGRO_USTR_INFO info; + al_ustr_append(us, al_ref_buffer(&info, buf, size)); +\f[R] +.fi +.SH SEE ALSO +.PP +al_ustr_append_cstr(3), al_ustr_append_chr(3), al_ustr_appendf(3), +al_ustr_vappendf(3) diff --git a/allegro/docs/man/al_ustr_append_chr.3 b/allegro/docs/man/al_ustr_append_chr.3 new file mode 100644 index 00000000..49edb845 --- /dev/null +++ b/allegro/docs/man/al_ustr_append_chr.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_append_chr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_append_chr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_ustr_append_chr(ALLEGRO_USTR *us, int32_t c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Append a code point to the end of \f[C]us\f[R]. +.PP +Returns the number of bytes added, or 0 on error. +.SH SEE ALSO +.PP +al_ustr_append(3) diff --git a/allegro/docs/man/al_ustr_append_cstr.3 b/allegro/docs/man/al_ustr_append_cstr.3 new file mode 100644 index 00000000..5a1ff406 --- /dev/null +++ b/allegro/docs/man/al_ustr_append_cstr.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_append_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_append_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_append_cstr(ALLEGRO_USTR *us, const char *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Append C-style string \f[C]s\f[R] to the end of \f[C]us\f[R]. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_append(3) diff --git a/allegro/docs/man/al_ustr_appendf.3 b/allegro/docs/man/al_ustr_appendf.3 new file mode 100644 index 00000000..2492b9ee --- /dev/null +++ b/allegro/docs/man/al_ustr_appendf.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_appendf" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_appendf - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_appendf(ALLEGRO_USTR *us, const char *fmt, ...) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function appends formatted output to the string \f[C]us\f[R]. +\f[C]fmt\f[R] is a printf-style format string. +See al_ustr_newf(3) about the \[lq]%s\[rq] and \[lq]%c\[rq] specifiers. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_vappendf(3), al_ustr_append(3) diff --git a/allegro/docs/man/al_ustr_assign.3 b/allegro/docs/man/al_ustr_assign.3 new file mode 100644 index 00000000..a3093e91 --- /dev/null +++ b/allegro/docs/man/al_ustr_assign.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_assign" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_assign - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_assign(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Overwrite the string \f[C]us1\f[R] with another string \f[C]us2\f[R]. +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_assign_substr(3), al_ustr_assign_cstr(3) diff --git a/allegro/docs/man/al_ustr_assign_cstr.3 b/allegro/docs/man/al_ustr_assign_cstr.3 new file mode 100644 index 00000000..b3f856ae --- /dev/null +++ b/allegro/docs/man/al_ustr_assign_cstr.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_assign_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_assign_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_assign_cstr(ALLEGRO_USTR *us1, const char *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Overwrite the string \f[C]us1\f[R] with the contents of the C-style +string \f[C]s\f[R]. +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_assign_substr(3), al_ustr_assign_cstr(3) diff --git a/allegro/docs/man/al_ustr_assign_substr.3 b/allegro/docs/man/al_ustr_assign_substr.3 new file mode 100644 index 00000000..5069b906 --- /dev/null +++ b/allegro/docs/man/al_ustr_assign_substr.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_assign_substr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_assign_substr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_assign_substr(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, + int start_pos, int end_pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Overwrite the string \f[C]us1\f[R] with the contents of \f[C]us2\f[R] in +the byte interval [\f[C]start_pos\f[R], \f[C]end_pos\f[R]). +The end points will be clamped to the bounds of \f[C]us2\f[R]. +.PP +Usually you will first have to use al_ustr_offset(3) to find the byte +offsets. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_assign(3), al_ustr_assign_cstr(3) diff --git a/allegro/docs/man/al_ustr_compare.3 b/allegro/docs/man/al_ustr_compare.3 new file mode 100644 index 00000000..92b46552 --- /dev/null +++ b/allegro/docs/man/al_ustr_compare.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_compare" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_compare - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_compare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function compares \f[C]us1\f[R] and \f[C]us2\f[R] by code point +values. +Returns zero if the strings are equal, a positive number if +\f[C]us1\f[R] comes after \f[C]us2\f[R], else a negative number. +.PP +This does \f[I]not\f[R] take into account locale-specific sorting rules. +For that you will need to use another library. +.SH SEE ALSO +.PP +al_ustr_ncompare(3), al_ustr_equal(3) diff --git a/allegro/docs/man/al_ustr_dup.3 b/allegro/docs/man/al_ustr_dup.3 new file mode 100644 index 00000000..58340c66 --- /dev/null +++ b/allegro/docs/man/al_ustr_dup.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_dup" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_dup - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_USTR *al_ustr_dup(const ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a duplicate copy of a string. +The new string will need to be freed with al_ustr_free(3). +.SH SEE ALSO +.PP +al_ustr_dup_substr(3), al_ustr_free(3) diff --git a/allegro/docs/man/al_ustr_dup_substr.3 b/allegro/docs/man/al_ustr_dup_substr.3 new file mode 100644 index 00000000..49ddf479 --- /dev/null +++ b/allegro/docs/man/al_ustr_dup_substr.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_dup_substr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_dup_substr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_USTR *al_ustr_dup_substr(const ALLEGRO_USTR *us, int start_pos, + int end_pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a new copy of a string, containing its contents in the byte +interval [\f[C]start_pos\f[R], \f[C]end_pos\f[R]). +The new string will be NUL terminated and will need to be freed with +al_ustr_free(3). +.PP +If necessary, use al_ustr_offset(3) to find the byte offsets for a given +code point that you are interested in. +.SH SEE ALSO +.PP +al_ustr_dup(3), al_ustr_free(3) diff --git a/allegro/docs/man/al_ustr_empty_string.3 b/allegro/docs/man/al_ustr_empty_string.3 new file mode 100644 index 00000000..08144b17 --- /dev/null +++ b/allegro/docs/man/al_ustr_empty_string.3 @@ -0,0 +1,20 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_empty_string" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_empty_string - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +const ALLEGRO_USTR *al_ustr_empty_string(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return a pointer to a static empty string. +The string is read only and must not be freed. diff --git a/allegro/docs/man/al_ustr_encode_utf16.3 b/allegro/docs/man/al_ustr_encode_utf16.3 new file mode 100644 index 00000000..1d06d914 --- /dev/null +++ b/allegro/docs/man/al_ustr_encode_utf16.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_encode_utf16" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_encode_utf16 - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_ustr_encode_utf16(const ALLEGRO_USTR *us, uint16_t *s, + size_t n) +\f[R] +.fi +.SH DESCRIPTION +.PP +Encode the string into the given buffer, in UTF-16. +Returns the number of bytes written. +There are never more than \f[C]n\f[R] bytes written. +The minimum size to encode the complete string can be queried with +al_ustr_size_utf16(3). +If the \f[C]n\f[R] parameter is smaller than that, the string will be +truncated but still always 0 terminated. +.SH SEE ALSO +.PP +al_ustr_size_utf16(3), al_utf16_encode(3) diff --git a/allegro/docs/man/al_ustr_equal.3 b/allegro/docs/man/al_ustr_equal.3 new file mode 100644 index 00000000..6b955d70 --- /dev/null +++ b/allegro/docs/man/al_ustr_equal.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_equal" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_equal - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_equal(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return true iff the two strings are equal. +This function is more efficient than al_ustr_compare(3) so is preferable +if ordering is not important. +.SH SEE ALSO +.PP +al_ustr_compare(3) diff --git a/allegro/docs/man/al_ustr_find_chr.3 b/allegro/docs/man/al_ustr_find_chr.3 new file mode 100644 index 00000000..c18aa109 --- /dev/null +++ b/allegro/docs/man/al_ustr_find_chr.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_chr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_chr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_find_chr(const ALLEGRO_USTR *us, int start_pos, int32_t c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Search for the encoding of code point \f[C]c\f[R] in \f[C]us\f[R] from +byte offset \f[C]start_pos\f[R] (inclusive). +.PP +Returns the position where it is found or -1 if it is not found. +.SH SEE ALSO +.PP +al_ustr_rfind_chr(3) diff --git a/allegro/docs/man/al_ustr_find_cset.3 b/allegro/docs/man/al_ustr_find_cset.3 new file mode 100644 index 00000000..b1936b1c --- /dev/null +++ b/allegro/docs/man/al_ustr_find_cset.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_cset" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_cset - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_find_cset(const ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *reject) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function finds the first code point in \f[C]us\f[R], beginning from +byte offset \f[C]start_pos\f[R], that does \f[I]not\f[R] match any code +point in \f[C]reject\f[R]. +In other words it finds a code point in the complementary set of +\f[C]reject\f[R]. +Returns the byte position of that code point, if any. +Otherwise returns -1. +.SH SEE ALSO +.PP +al_ustr_find_cset_cstr(3), al_ustr_find_set(3) diff --git a/allegro/docs/man/al_ustr_find_cset_cstr.3 b/allegro/docs/man/al_ustr_find_cset_cstr.3 new file mode 100644 index 00000000..7718f8d8 --- /dev/null +++ b/allegro/docs/man/al_ustr_find_cset_cstr.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_cset_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_cset_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_find_cset_cstr(const ALLEGRO_USTR *us, int start_pos, + const char *reject) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_ustr_find_cset(3) but takes a C-style string for +\f[C]reject\f[R]. +.SH SEE ALSO +.PP +al_ustr_find_cset(3), al_ustr_find_set_cstr(3) diff --git a/allegro/docs/man/al_ustr_find_cstr.3 b/allegro/docs/man/al_ustr_find_cstr.3 new file mode 100644 index 00000000..bc82e2e2 --- /dev/null +++ b/allegro/docs/man/al_ustr_find_cstr.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_find_cstr(const ALLEGRO_USTR *haystack, int start_pos, + const char *needle) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_ustr_find_str(3) but takes a C-style string for +\f[C]needle\f[R]. +.SH SEE ALSO +.PP +al_ustr_find_str(3), al_ustr_rfind_cstr(3) diff --git a/allegro/docs/man/al_ustr_find_replace.3 b/allegro/docs/man/al_ustr_find_replace.3 new file mode 100644 index 00000000..1f474ac7 --- /dev/null +++ b/allegro/docs/man/al_ustr_find_replace.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_replace" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_replace - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_find_replace(ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace) +\f[R] +.fi +.SH DESCRIPTION +.PP +Replace all occurrences of \f[C]find\f[R] in \f[C]us\f[R] with +\f[C]replace\f[R], beginning at byte offset \f[C]start_pos\f[R]. +The \f[C]find\f[R] string must be non-empty. +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_find_replace_cstr(3) diff --git a/allegro/docs/man/al_ustr_find_replace_cstr.3 b/allegro/docs/man/al_ustr_find_replace_cstr.3 new file mode 100644 index 00000000..421f7119 --- /dev/null +++ b/allegro/docs/man/al_ustr_find_replace_cstr.3 @@ -0,0 +1,21 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_replace_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_replace_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_find_replace_cstr(ALLEGRO_USTR *us, int start_pos, + const char *find, const char *replace) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_ustr_find_replace(3) but takes C-style strings for +\f[C]find\f[R] and \f[C]replace\f[R]. diff --git a/allegro/docs/man/al_ustr_find_set.3 b/allegro/docs/man/al_ustr_find_set.3 new file mode 100644 index 00000000..fa5bbfb4 --- /dev/null +++ b/allegro/docs/man/al_ustr_find_set.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_set" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_set - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_find_set(const ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *accept) +\f[R] +.fi +.SH DESCRIPTION +.PP +This function finds the first code point in \f[C]us\f[R], beginning from +byte offset \f[C]start_pos\f[R], that matches any code point in +\f[C]accept\f[R]. +Returns the position if a code point was found. +Otherwise returns -1. +.SH SEE ALSO +.PP +al_ustr_find_set_cstr(3), al_ustr_find_cset(3) diff --git a/allegro/docs/man/al_ustr_find_set_cstr.3 b/allegro/docs/man/al_ustr_find_set_cstr.3 new file mode 100644 index 00000000..23117ab8 --- /dev/null +++ b/allegro/docs/man/al_ustr_find_set_cstr.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_set_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_set_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_find_set_cstr(const ALLEGRO_USTR *us, int start_pos, + const char *accept) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_ustr_find_set(3) but takes a C-style string for +\f[C]accept\f[R]. +.SH SEE ALSO +.PP +al_ustr_find_set(3), al_ustr_find_cset_cstr(3) diff --git a/allegro/docs/man/al_ustr_find_str.3 b/allegro/docs/man/al_ustr_find_str.3 new file mode 100644 index 00000000..fa3f77c9 --- /dev/null +++ b/allegro/docs/man/al_ustr_find_str.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_find_str" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_find_str - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_find_str(const ALLEGRO_USTR *haystack, int start_pos, + const ALLEGRO_USTR *needle) +\f[R] +.fi +.SH DESCRIPTION +.PP +Find the first occurrence of string \f[C]needle\f[R] in +\f[C]haystack\f[R], beginning from byte offset \f[C]start_pos\f[R] +(inclusive). +Return the byte offset of the occurrence if it is found, otherwise +return -1. +.SH SEE ALSO +.PP +al_ustr_find_cstr(3), al_ustr_rfind_str(3), al_ustr_find_replace(3) diff --git a/allegro/docs/man/al_ustr_free.3 b/allegro/docs/man/al_ustr_free.3 new file mode 100644 index 00000000..0e595607 --- /dev/null +++ b/allegro/docs/man/al_ustr_free.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_free" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_free - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_ustr_free(ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Free a previously allocated string. +Does nothing if the argument is NULL. +.SH SEE ALSO +.PP +al_ustr_new(3), al_ustr_new_from_buffer(3), al_ustr_newf(3) diff --git a/allegro/docs/man/al_ustr_get.3 b/allegro/docs/man/al_ustr_get.3 new file mode 100644 index 00000000..f950466a --- /dev/null +++ b/allegro/docs/man/al_ustr_get.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_get" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_get - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int32_t al_ustr_get(const ALLEGRO_USTR *ub, int pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the code point in \f[C]ub\f[R] beginning at byte offset +\f[C]pos\f[R]. +.PP +On success returns the code point value. +If \f[C]pos\f[R] was out of bounds (e.g.\ past the end of the string), +return -1. +On an error, such as an invalid byte sequence, return -2. +.SH SEE ALSO +.PP +al_ustr_get_next(3), al_ustr_prev_get(3) diff --git a/allegro/docs/man/al_ustr_get_next.3 b/allegro/docs/man/al_ustr_get_next.3 new file mode 100644 index 00000000..9235377f --- /dev/null +++ b/allegro/docs/man/al_ustr_get_next.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_get_next" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_get_next - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Find the code point in \f[C]us\f[R] beginning at byte offset +\f[C]*pos\f[R], then advance to the next code point. +.PP +On success return the code point value. +If \f[C]pos\f[R] was out of bounds (e.g.\ past the end of the string), +return -1. +On an error, such as an invalid byte sequence, return -2. +As with al_ustr_next(3), invalid byte sequences may be skipped while +advancing. +.SH SEE ALSO +.PP +al_ustr_get(3), al_ustr_prev_get(3) diff --git a/allegro/docs/man/al_ustr_has_prefix.3 b/allegro/docs/man/al_ustr_has_prefix.3 new file mode 100644 index 00000000..8dffd06d --- /dev/null +++ b/allegro/docs/man/al_ustr_has_prefix.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_has_prefix" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_has_prefix - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_has_prefix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true iff \f[C]us1\f[R] begins with \f[C]us2\f[R]. +.SH SEE ALSO +.PP +al_ustr_has_prefix_cstr(3), al_ustr_has_suffix(3) diff --git a/allegro/docs/man/al_ustr_has_prefix_cstr.3 b/allegro/docs/man/al_ustr_has_prefix_cstr.3 new file mode 100644 index 00000000..ddc88134 --- /dev/null +++ b/allegro/docs/man/al_ustr_has_prefix_cstr.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_has_prefix_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_has_prefix_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_has_prefix_cstr(const ALLEGRO_USTR *us1, const char *s2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true iff \f[C]us1\f[R] begins with \f[C]s2\f[R]. +.SH SEE ALSO +.PP +al_ustr_has_prefix(3), al_ustr_has_suffix_cstr(3) diff --git a/allegro/docs/man/al_ustr_has_suffix.3 b/allegro/docs/man/al_ustr_has_suffix.3 new file mode 100644 index 00000000..6eb7a382 --- /dev/null +++ b/allegro/docs/man/al_ustr_has_suffix.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_has_suffix" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_has_suffix - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_has_suffix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true iff \f[C]us1\f[R] ends with \f[C]us2\f[R]. +.SH SEE ALSO +.PP +al_ustr_has_suffix_cstr(3), al_ustr_has_prefix(3) diff --git a/allegro/docs/man/al_ustr_has_suffix_cstr.3 b/allegro/docs/man/al_ustr_has_suffix_cstr.3 new file mode 100644 index 00000000..34f6e681 --- /dev/null +++ b/allegro/docs/man/al_ustr_has_suffix_cstr.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_has_suffix_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_has_suffix_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_has_suffix_cstr(const ALLEGRO_USTR *us1, const char *s2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns true iff \f[C]us1\f[R] ends with \f[C]s2\f[R]. +.SH SEE ALSO +.PP +al_ustr_has_suffix(3), al_ustr_has_prefix_cstr(3) diff --git a/allegro/docs/man/al_ustr_insert.3 b/allegro/docs/man/al_ustr_insert.3 new file mode 100644 index 00000000..50adac71 --- /dev/null +++ b/allegro/docs/man/al_ustr_insert.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_insert" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_insert - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_insert(ALLEGRO_USTR *us1, int pos, const ALLEGRO_USTR *us2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Insert \f[C]us2\f[R] into \f[C]us1\f[R] beginning at byte offset +\f[C]pos\f[R]. +\f[C]pos\f[R] cannot be less than 0. +If \f[C]pos\f[R] is past the end of \f[C]us1\f[R] then the space between +the end of the string and \f[C]pos\f[R] will be padded with NUL +(\f[C]\[aq]\[rs]0\[aq]\f[R]) bytes. +.PP +If required, use al_ustr_offset(3) to find the byte offset for a given +code point index. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_insert_cstr(3), al_ustr_insert_chr(3), al_ustr_append(3), +al_ustr_offset(3) diff --git a/allegro/docs/man/al_ustr_insert_chr.3 b/allegro/docs/man/al_ustr_insert_chr.3 new file mode 100644 index 00000000..69eaa87c --- /dev/null +++ b/allegro/docs/man/al_ustr_insert_chr.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_insert_chr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_insert_chr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_ustr_insert_chr(ALLEGRO_USTR *us, int pos, int32_t c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Insert a code point into \f[C]us\f[R] beginning at byte offset +\f[C]pos\f[R]. +\f[C]pos\f[R] cannot be less than 0. +If \f[C]pos\f[R] is past the end of \f[C]us\f[R] then the space between +the end of the string and \f[C]pos\f[R] will be padded with NUL +(\f[C]\[aq]\[rs]0\[aq]\f[R]) bytes. +.PP +Returns the number of bytes inserted, or 0 on error. +.SH SEE ALSO +.PP +al_ustr_insert(3), al_ustr_insert_cstr(3) diff --git a/allegro/docs/man/al_ustr_insert_cstr.3 b/allegro/docs/man/al_ustr_insert_cstr.3 new file mode 100644 index 00000000..2f6c0fab --- /dev/null +++ b/allegro/docs/man/al_ustr_insert_cstr.3 @@ -0,0 +1,23 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_insert_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_insert_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_insert_cstr(ALLEGRO_USTR *us, int pos, const char *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_ustr_insert(3) but inserts a C-style string at byte offset +\f[C]pos\f[R]. +.SH SEE ALSO +.PP +al_ustr_insert(3), al_ustr_insert_chr(3) diff --git a/allegro/docs/man/al_ustr_length.3 b/allegro/docs/man/al_ustr_length.3 new file mode 100644 index 00000000..c128ef5d --- /dev/null +++ b/allegro/docs/man/al_ustr_length.3 @@ -0,0 +1,22 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_length" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_length - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_ustr_length(const ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the number of code points in the string. +.SH SEE ALSO +.PP +al_ustr_size(3), al_ustr_offset(3) diff --git a/allegro/docs/man/al_ustr_ltrim_ws.3 b/allegro/docs/man/al_ustr_ltrim_ws.3 new file mode 100644 index 00000000..607febe1 --- /dev/null +++ b/allegro/docs/man/al_ustr_ltrim_ws.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_ltrim_ws" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_ltrim_ws - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_ltrim_ws(ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Remove leading whitespace characters from a string, as defined by the C +function \f[C]isspace()\f[R]. +.PP +Returns true on success, or false on error. +.SH SEE ALSO +.PP +al_ustr_rtrim_ws(3), al_ustr_trim_ws(3) diff --git a/allegro/docs/man/al_ustr_ncompare.3 b/allegro/docs/man/al_ustr_ncompare.3 new file mode 100644 index 00000000..e43f4934 --- /dev/null +++ b/allegro/docs/man/al_ustr_ncompare.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_ncompare" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_ncompare - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_ncompare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int n) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_ustr_compare(3) but only compares up to the first \f[C]n\f[R] +code points of both strings. +.PP +Returns zero if the strings are equal, a positive number if +\f[C]us1\f[R] comes after \f[C]us2\f[R], else a negative number. +.SH SEE ALSO +.PP +al_ustr_compare(3), al_ustr_equal(3) diff --git a/allegro/docs/man/al_ustr_new.3 b/allegro/docs/man/al_ustr_new.3 new file mode 100644 index 00000000..73945d0b --- /dev/null +++ b/allegro/docs/man/al_ustr_new.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_new" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_new - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_USTR *al_ustr_new(const char *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a new string containing a copy of the C-style string \f[C]s\f[R]. +The string must eventually be freed with al_ustr_free(3). +.SH SEE ALSO +.PP +al_ustr_new_from_buffer(3), al_ustr_newf(3), al_ustr_dup(3), +al_ustr_new_from_utf16(3) diff --git a/allegro/docs/man/al_ustr_new_from_buffer.3 b/allegro/docs/man/al_ustr_new_from_buffer.3 new file mode 100644 index 00000000..659250c4 --- /dev/null +++ b/allegro/docs/man/al_ustr_new_from_buffer.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_new_from_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_new_from_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_USTR *al_ustr_new_from_buffer(const char *s, size_t size) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a new string containing a copy of the buffer pointed to by +\f[C]s\f[R] of the given \f[C]size\f[R] in bytes. +The string must eventually be freed with al_ustr_free(3). +.SH SEE ALSO +.PP +al_ustr_new(3) diff --git a/allegro/docs/man/al_ustr_new_from_utf16.3 b/allegro/docs/man/al_ustr_new_from_utf16.3 new file mode 100644 index 00000000..e73b8fd0 --- /dev/null +++ b/allegro/docs/man/al_ustr_new_from_utf16.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_new_from_utf16" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_new_from_utf16 - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_USTR *al_ustr_new_from_utf16(uint16_t const *s) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a new string containing a copy of the 0-terminated string +\f[C]s\f[R] which must be encoded as UTF-16. +The string must eventually be freed with al_ustr_free(3). +.SH SEE ALSO +.PP +al_ustr_new(3) diff --git a/allegro/docs/man/al_ustr_newf.3 b/allegro/docs/man/al_ustr_newf.3 new file mode 100644 index 00000000..6c006688 --- /dev/null +++ b/allegro/docs/man/al_ustr_newf.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_newf" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_newf - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +ALLEGRO_USTR *al_ustr_newf(const char *fmt, ...) +\f[R] +.fi +.SH DESCRIPTION +.PP +Create a new string using a printf-style format string. +.PP +\f[I]Notes:\f[R] +.PP +The \[lq]%s\[rq] specifier takes C string arguments, not ALLEGRO_USTRs. +Therefore to pass an ALLEGRO_USTR as a parameter you must use +al_cstr(3), and it must be NUL terminated. +If the string contains an embedded NUL byte everything from that byte +onwards will be ignored. +.PP +The \[lq]%c\[rq] specifier outputs a single byte, not the UTF-8 encoding +of a code point. +Therefore it is only usable for ASCII characters (value <= 127) or if +you really mean to output byte values from 128\[en]255. +To insert the UTF-8 encoding of a code point, encode it into a memory +buffer using al_utf8_encode(3) then use the \[lq]%s\[rq] specifier. +Remember to NUL terminate the buffer. +.SH SEE ALSO +.PP +al_ustr_new(3), al_ustr_appendf(3) diff --git a/allegro/docs/man/al_ustr_next.3 b/allegro/docs/man/al_ustr_next.3 new file mode 100644 index 00000000..9736b20b --- /dev/null +++ b/allegro/docs/man/al_ustr_next.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_next" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_next - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_next(const ALLEGRO_USTR *us, int *pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Find the byte offset of the next code point in string, beginning at +\f[C]*pos\f[R]. +\f[C]*pos\f[R] does not have to be at the beginning of a code point. +.PP +Returns true on success, and the value pointed to by \f[C]pos\f[R] will +be updated to the found offset. +Otherwise returns false if \f[C]*pos\f[R] was already at the end of the +string, and \f[C]*pos\f[R] is unmodified. +.PP +This function just looks for an appropriate byte; it doesn\[cq]t check +if found offset is the beginning of a valid code point. +If you are working with possibly invalid UTF-8 strings then it could +skip over some invalid bytes. +.SH SEE ALSO +.PP +al_ustr_prev(3) diff --git a/allegro/docs/man/al_ustr_offset.3 b/allegro/docs/man/al_ustr_offset.3 new file mode 100644 index 00000000..e98fb6fb --- /dev/null +++ b/allegro/docs/man/al_ustr_offset.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_offset" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_offset - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_offset(const ALLEGRO_USTR *us, int index) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the byte offset (from the start of the string) of the code point +at the specified index in the string. +A zero index parameter will return the first character of the string. +If index is negative, it counts backward from the end of the string, so +an index of -1 will return an offset to the last code point. +.PP +If the index is past the end of the string, returns the offset of the +end of the string. +.SH SEE ALSO +.PP +al_ustr_length(3) diff --git a/allegro/docs/man/al_ustr_prev.3 b/allegro/docs/man/al_ustr_prev.3 new file mode 100644 index 00000000..f85c1064 --- /dev/null +++ b/allegro/docs/man/al_ustr_prev.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_prev" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_prev - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_prev(const ALLEGRO_USTR *us, int *pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Find the byte offset of the previous code point in string, before +\f[C]*pos\f[R]. +\f[C]*pos\f[R] does not have to be at the beginning of a code point. +Returns true on success, and the value pointed to by \f[C]pos\f[R] will +be updated to the found offset. +Otherwise returns false if \f[C]*pos\f[R] was already at the end of the +string, and \f[C]*pos\f[R] is unmodified. +.PP +This function just looks for an appropriate byte; it doesn\[cq]t check +if found offset is the beginning of a valid code point. +If you are working with possibly invalid UTF-8 strings then it could +skip over some invalid bytes. +.SH SEE ALSO +.PP +al_ustr_next(3) diff --git a/allegro/docs/man/al_ustr_prev_get.3 b/allegro/docs/man/al_ustr_prev_get.3 new file mode 100644 index 00000000..c117c8ff --- /dev/null +++ b/allegro/docs/man/al_ustr_prev_get.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_prev_get" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_prev_get - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int32_t al_ustr_prev_get(const ALLEGRO_USTR *us, int *pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Find the beginning of a code point before byte offset \f[C]*pos\f[R], +then return it. +Note this performs a \f[I]pre-increment\f[R]. +.PP +On success returns the code point value. +If \f[C]pos\f[R] was out of bounds (e.g.\ past the end of the string), +return -1. +On an error, such as an invalid byte sequence, return -2. +As with al_ustr_prev(3), invalid byte sequences may be skipped while +advancing. +.SH SEE ALSO +.PP +al_ustr_get_next(3) diff --git a/allegro/docs/man/al_ustr_remove_chr.3 b/allegro/docs/man/al_ustr_remove_chr.3 new file mode 100644 index 00000000..231b957d --- /dev/null +++ b/allegro/docs/man/al_ustr_remove_chr.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_remove_chr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_remove_chr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_remove_chr(ALLEGRO_USTR *us, int pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Remove the code point beginning at byte offset \f[C]pos\f[R]. +Returns true on success. +If \f[C]pos\f[R] is out of range or \f[C]pos\f[R] is not the beginning +of a valid code point, returns false leaving the string unmodified. +.PP +Use al_ustr_offset(3) to find the byte offset for a code-points offset. +.SH SEE ALSO +.PP +al_ustr_remove_range(3) diff --git a/allegro/docs/man/al_ustr_remove_range.3 b/allegro/docs/man/al_ustr_remove_range.3 new file mode 100644 index 00000000..1efaefcf --- /dev/null +++ b/allegro/docs/man/al_ustr_remove_range.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_remove_range" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_remove_range - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_remove_range(ALLEGRO_USTR *us, int start_pos, int end_pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Remove the interval [\f[C]start_pos\f[R], \f[C]end_pos\f[R]) from a +string. +\f[C]start_pos\f[R] and \f[C]end_pos\f[R] are byte offsets. +Both may be past the end of the string but cannot be less than 0 (the +start of the string). +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_remove_chr(3), al_ustr_truncate(3) diff --git a/allegro/docs/man/al_ustr_replace_range.3 b/allegro/docs/man/al_ustr_replace_range.3 new file mode 100644 index 00000000..372702b7 --- /dev/null +++ b/allegro/docs/man/al_ustr_replace_range.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_replace_range" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_replace_range - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_replace_range(ALLEGRO_USTR *us1, int start_pos1, int end_pos1, + const ALLEGRO_USTR *us2) +\f[R] +.fi +.SH DESCRIPTION +.PP +Replace the part of \f[C]us1\f[R] in the byte interval +[\f[C]start_pos1\f[R], \f[C]end_pos1\f[R]) with the contents of +\f[C]us2\f[R]. +\f[C]start_pos1\f[R] cannot be less than 0. +If \f[C]start_pos1\f[R] is past the end of \f[C]us1\f[R] then the space +between the end of the string and \f[C]start_pos1\f[R] will be padded +with NUL (\f[C]\[aq]\[rs]0\[aq]\f[R]) bytes. +.PP +Use al_ustr_offset(3) to find the byte offsets. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_set_chr(3) diff --git a/allegro/docs/man/al_ustr_rfind_chr.3 b/allegro/docs/man/al_ustr_rfind_chr.3 new file mode 100644 index 00000000..f7eecde8 --- /dev/null +++ b/allegro/docs/man/al_ustr_rfind_chr.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_rfind_chr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_rfind_chr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_rfind_chr(const ALLEGRO_USTR *us, int end_pos, int32_t c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Search for the encoding of code point \f[C]c\f[R] in \f[C]us\f[R] +backwards from byte offset \f[C]end_pos\f[R] (exclusive). +Returns the position where it is found or -1 if it is not found. +.SH SEE ALSO +.PP +al_ustr_find_chr(3) diff --git a/allegro/docs/man/al_ustr_rfind_cstr.3 b/allegro/docs/man/al_ustr_rfind_cstr.3 new file mode 100644 index 00000000..32b5f330 --- /dev/null +++ b/allegro/docs/man/al_ustr_rfind_cstr.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_rfind_cstr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_rfind_cstr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_rfind_cstr(const ALLEGRO_USTR *haystack, int end_pos, + const char *needle) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_ustr_rfind_str(3) but takes a C-style string for +\f[C]needle\f[R]. +.SH SEE ALSO +.PP +al_ustr_rfind_str(3), al_ustr_find_cstr(3) diff --git a/allegro/docs/man/al_ustr_rfind_str.3 b/allegro/docs/man/al_ustr_rfind_str.3 new file mode 100644 index 00000000..1df835fb --- /dev/null +++ b/allegro/docs/man/al_ustr_rfind_str.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_rfind_str" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_rfind_str - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_ustr_rfind_str(const ALLEGRO_USTR *haystack, int end_pos, + const ALLEGRO_USTR *needle) +\f[R] +.fi +.SH DESCRIPTION +.PP +Find the last occurrence of string \f[C]needle\f[R] in +\f[C]haystack\f[R] before byte offset \f[C]end_pos\f[R] (exclusive). +Return the byte offset of the occurrence if it is found, otherwise +return -1. +.SH SEE ALSO +.PP +al_ustr_rfind_cstr(3), al_ustr_find_str(3) diff --git a/allegro/docs/man/al_ustr_rtrim_ws.3 b/allegro/docs/man/al_ustr_rtrim_ws.3 new file mode 100644 index 00000000..5c87bd39 --- /dev/null +++ b/allegro/docs/man/al_ustr_rtrim_ws.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_rtrim_ws" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_rtrim_ws - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_rtrim_ws(ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Remove trailing (\[lq]right\[rq]) whitespace characters from a string, +as defined by the C function \f[C]isspace()\f[R]. +.PP +Returns true on success, or false on error. +.SH SEE ALSO +.PP +al_ustr_ltrim_ws(3), al_ustr_trim_ws(3) diff --git a/allegro/docs/man/al_ustr_set_chr.3 b/allegro/docs/man/al_ustr_set_chr.3 new file mode 100644 index 00000000..0da704a6 --- /dev/null +++ b/allegro/docs/man/al_ustr_set_chr.3 @@ -0,0 +1,33 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_set_chr" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_set_chr - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_ustr_set_chr(ALLEGRO_USTR *us, int start_pos, int32_t c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Replace the code point beginning at byte offset \f[C]start_pos\f[R] with +\f[C]c\f[R]. +\f[C]start_pos\f[R] cannot be less than 0. +If \f[C]start_pos\f[R] is past the end of \f[C]us\f[R] then the space +between the end of the string and \f[C]start_pos\f[R] will be padded +with NUL (\f[C]\[aq]\[rs]0\[aq]\f[R]) bytes. +If \f[C]start_pos\f[R] is not the start of a valid code point, that is +an error and the string will be unmodified. +.PP +On success, returns the number of bytes written, i.e.\ the offset to the +following code point. +On error, returns 0. +.SH SEE ALSO +.PP +al_ustr_replace_range(3) diff --git a/allegro/docs/man/al_ustr_size.3 b/allegro/docs/man/al_ustr_size.3 new file mode 100644 index 00000000..0c69a698 --- /dev/null +++ b/allegro/docs/man/al_ustr_size.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_size" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_size - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_ustr_size(const ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Return the size of the string in bytes. +This is equal to the number of code points in the string if the string +is empty or contains only 7-bit ASCII characters. +.SH SEE ALSO +.PP +al_ustr_length(3) diff --git a/allegro/docs/man/al_ustr_size_utf16.3 b/allegro/docs/man/al_ustr_size_utf16.3 new file mode 100644 index 00000000..d09bbe13 --- /dev/null +++ b/allegro/docs/man/al_ustr_size_utf16.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_size_utf16" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_size_utf16 - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_ustr_size_utf16(const ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the number of bytes required to encode the string in UTF-16 +(including the terminating 0). +Usually called before al_ustr_encode_utf16(3) to determine the size of +the buffer to allocate. +.SH SEE ALSO +.PP +al_ustr_size(3) diff --git a/allegro/docs/man/al_ustr_to_buffer.3 b/allegro/docs/man/al_ustr_to_buffer.3 new file mode 100644 index 00000000..812d1e72 --- /dev/null +++ b/allegro/docs/man/al_ustr_to_buffer.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_to_buffer" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_to_buffer - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_ustr_to_buffer(const ALLEGRO_USTR *us, char *buffer, int size) +\f[R] +.fi +.SH DESCRIPTION +.PP +Write the contents of the string into a pre-allocated buffer of the +given size in bytes. +The result will always be NUL terminated, so a maximum of +\f[C]size - 1\f[R] bytes will be copied. +.SH SEE ALSO +.PP +al_cstr(3), al_cstr_dup(3) diff --git a/allegro/docs/man/al_ustr_trim_ws.3 b/allegro/docs/man/al_ustr_trim_ws.3 new file mode 100644 index 00000000..2f923cf2 --- /dev/null +++ b/allegro/docs/man/al_ustr_trim_ws.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_trim_ws" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_trim_ws - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_trim_ws(ALLEGRO_USTR *us) +\f[R] +.fi +.SH DESCRIPTION +.PP +Remove both leading and trailing whitespace characters from a string. +.PP +Returns true on success, or false on error. +.SH SEE ALSO +.PP +al_ustr_ltrim_ws(3), al_ustr_rtrim_ws(3) diff --git a/allegro/docs/man/al_ustr_truncate.3 b/allegro/docs/man/al_ustr_truncate.3 new file mode 100644 index 00000000..a7ba8f8a --- /dev/null +++ b/allegro/docs/man/al_ustr_truncate.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_truncate" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_truncate - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_truncate(ALLEGRO_USTR *us, int start_pos) +\f[R] +.fi +.SH DESCRIPTION +.PP +Truncate a portion of a string from byte offset \f[C]start_pos\f[R] +onwards. +\f[C]start_pos\f[R] can be past the end of the string (has no effect) +but cannot be less than 0. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_remove_range(3), al_ustr_ltrim_ws(3), al_ustr_rtrim_ws(3), +al_ustr_trim_ws(3) diff --git a/allegro/docs/man/al_ustr_vappendf.3 b/allegro/docs/man/al_ustr_vappendf.3 new file mode 100644 index 00000000..eaaf9a75 --- /dev/null +++ b/allegro/docs/man/al_ustr_vappendf.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_ustr_vappendf" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_ustr_vappendf - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_ustr_vappendf(ALLEGRO_USTR *us, const char *fmt, va_list ap) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_ustr_appendf(3) but you pass the variable argument list +directly, instead of the arguments themselves. +See al_ustr_newf(3) about the \[lq]%s\[rq] and \[lq]%c\[rq] specifiers. +.PP +Returns true on success, false on error. +.SH SEE ALSO +.PP +al_ustr_appendf(3), al_ustr_append(3) diff --git a/allegro/docs/man/al_utf16_encode.3 b/allegro/docs/man/al_utf16_encode.3 new file mode 100644 index 00000000..45557d5c --- /dev/null +++ b/allegro/docs/man/al_utf16_encode.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_utf16_encode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_utf16_encode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_utf16_encode(uint16_t s[], int32_t c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Encode the specified code point to UTF-16 into the buffer \f[C]s\f[R]. +The buffer must have enough space to hold the encoding, which takes +either 2 or 4 bytes. +This routine will refuse to encode code points above 0x10FFFF. +.PP +Returns the number of bytes written, which is the same as that returned +by al_utf16_width(3). +.SH SEE ALSO +.PP +al_utf8_encode(3), al_ustr_encode_utf16(3) diff --git a/allegro/docs/man/al_utf16_width.3 b/allegro/docs/man/al_utf16_width.3 new file mode 100644 index 00000000..e9ad3ad1 --- /dev/null +++ b/allegro/docs/man/al_utf16_width.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_utf16_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_utf16_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_utf16_width(int c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the number of bytes that would be occupied by the specified code +point when encoded in UTF-16. +This is either 2 or 4 bytes for legal code point values. +Otherwise returns 0. +.SH SEE ALSO +.PP +al_utf16_encode(3), al_utf8_width(3) diff --git a/allegro/docs/man/al_utf8_encode.3 b/allegro/docs/man/al_utf8_encode.3 new file mode 100644 index 00000000..9fc44f46 --- /dev/null +++ b/allegro/docs/man/al_utf8_encode.3 @@ -0,0 +1,28 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_utf8_encode" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_utf8_encode - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_utf8_encode(char s[], int32_t c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Encode the specified code point to UTF-8 into the buffer \f[C]s\f[R]. +The buffer must have enough space to hold the encoding, which takes +between 1 and 4 bytes. +This routine will refuse to encode code points above 0x10FFFF. +.PP +Returns the number of bytes written, which is the same as that returned +by al_utf8_width(3). +.SH SEE ALSO +.PP +al_utf16_encode(3) diff --git a/allegro/docs/man/al_utf8_width.3 b/allegro/docs/man/al_utf8_width.3 new file mode 100644 index 00000000..46e92e23 --- /dev/null +++ b/allegro/docs/man/al_utf8_width.3 @@ -0,0 +1,25 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_utf8_width" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_utf8_width - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +size_t al_utf8_width(int32_t c) +\f[R] +.fi +.SH DESCRIPTION +.PP +Returns the number of bytes that would be occupied by the specified code +point when encoded in UTF-8. +This is between 1 and 4 bytes for legal code point values. +Otherwise returns 0. +.SH SEE ALSO +.PP +al_utf8_encode(3), al_utf16_width(3) diff --git a/allegro/docs/man/al_vertical_shear_transform.3 b/allegro/docs/man/al_vertical_shear_transform.3 new file mode 100644 index 00000000..e53229a4 --- /dev/null +++ b/allegro/docs/man/al_vertical_shear_transform.3 @@ -0,0 +1,31 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_vertical_shear_transform" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_vertical_shear_transform - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_vertical_shear_transform(ALLEGRO_TRANSFORM* trans, float theta) +\f[R] +.fi +.SH DESCRIPTION +.PP +Apply a vertical shear to the transform +.PP +\f[I]Parameters:\f[R] +.IP \[bu] 2 +trans - Transformation to alter +.IP \[bu] 2 +theta - Rotation angle in radians +.SH SINCE +.PP +5.1.7 +.SH SEE ALSO +.PP +al_horizontal_shear_transform(3) diff --git a/allegro/docs/man/al_vfprintf.3 b/allegro/docs/man/al_vfprintf.3 new file mode 100644 index 00000000..a3cc716f --- /dev/null +++ b/allegro/docs/man/al_vfprintf.3 @@ -0,0 +1,24 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_vfprintf" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_vfprintf - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_fprintf but takes a va_list. +Useful for creating your own variations of formatted printing. +Returns the number of bytes written, or a negative number on error. +.SH SEE ALSO +.PP +al_fprintf(3) diff --git a/allegro/docs/man/al_wait_cond.3 b/allegro/docs/man/al_wait_cond.3 new file mode 100644 index 00000000..de3e0281 --- /dev/null +++ b/allegro/docs/man/al_wait_cond.3 @@ -0,0 +1,49 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_wait_cond" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_wait_cond - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex) +\f[R] +.fi +.SH DESCRIPTION +.PP +On entering this function, \f[C]mutex\f[R] must be locked by the calling +thread. +The function will atomically release \f[C]mutex\f[R] and block on +\f[C]cond\f[R]. +The function will return when \f[C]cond\f[R] is \[lq]signalled\[rq], +acquiring the lock on the mutex in the process. +.PP +Example of proper use: +.IP +.nf +\f[C] +al_lock_mutex(mutex); +while (something_not_true) { + al_wait_cond(cond, mutex); +} +do_something(); +al_unlock_mutex(mutex); +\f[R] +.fi +.PP +The mutex should be locked before checking the condition, and should be +rechecked al_wait_cond(3) returns. +al_wait_cond(3) can return for other reasons than the condition becoming +true (e.g.\ the process was signalled). +If multiple threads are blocked on the condition variable, the condition +may no longer be true by the time the second and later threads are +unblocked. +Remember not to unlock the mutex prematurely. +.SH SEE ALSO +.PP +al_wait_cond_until(3), al_broadcast_cond(3), al_signal_cond(3). diff --git a/allegro/docs/man/al_wait_cond_until.3 b/allegro/docs/man/al_wait_cond_until.3 new file mode 100644 index 00000000..01ef4b32 --- /dev/null +++ b/allegro/docs/man/al_wait_cond_until.3 @@ -0,0 +1,26 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_wait_cond_until" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_wait_cond_until - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +int al_wait_cond_until(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex, + const ALLEGRO_TIMEOUT *timeout) +\f[R] +.fi +.SH DESCRIPTION +.PP +Like al_wait_cond(3) but the call can return if the absolute time passes +\f[C]timeout\f[R] before the condition is signalled. +.PP +Returns zero on success, non-zero if the call timed out. +.SH SEE ALSO +.PP +al_wait_cond(3) diff --git a/allegro/docs/man/al_wait_for_event.3 b/allegro/docs/man/al_wait_for_event.3 new file mode 100644 index 00000000..f513f3f2 --- /dev/null +++ b/allegro/docs/man/al_wait_for_event.3 @@ -0,0 +1,27 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_wait_for_event" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_wait_for_event - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) +\f[R] +.fi +.SH DESCRIPTION +.PP +Wait until the event queue specified is non-empty. +If \f[C]ret_event\f[R] is not NULL, the first event in the queue will be +copied into \f[C]ret_event\f[R] and removed from the queue. +If \f[C]ret_event\f[R] is NULL the first event is left at the head of +the queue. +.SH SEE ALSO +.PP +ALLEGRO_EVENT(3), al_wait_for_event_timed(3), +al_wait_for_event_until(3), al_get_next_event(3) diff --git a/allegro/docs/man/al_wait_for_event_timed.3 b/allegro/docs/man/al_wait_for_event_timed.3 new file mode 100644 index 00000000..ab66b050 --- /dev/null +++ b/allegro/docs/man/al_wait_for_event_timed.3 @@ -0,0 +1,34 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_wait_for_event_timed" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_wait_for_event_timed - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_wait_for_event_timed(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT *ret_event, float secs) +\f[R] +.fi +.SH DESCRIPTION +.PP +Wait until the event queue specified is non-empty. +If \f[C]ret_event\f[R] is not NULL, the first event in the queue will be +copied into \f[C]ret_event\f[R] and removed from the queue. +If \f[C]ret_event\f[R] is NULL the first event is left at the head of +the queue. +.PP +\f[C]secs\f[R] determines approximately how many seconds to wait. +If the call times out, false is returned. +Otherwise, if an event ocurred, true is returned. +.PP +For compatibility with all platforms, \f[C]secs\f[R] must be +2,147,483.647 seconds or less. +.SH SEE ALSO +.PP +ALLEGRO_EVENT(3), al_wait_for_event(3), al_wait_for_event_until(3) diff --git a/allegro/docs/man/al_wait_for_event_until.3 b/allegro/docs/man/al_wait_for_event_until.3 new file mode 100644 index 00000000..47e11918 --- /dev/null +++ b/allegro/docs/man/al_wait_for_event_until.3 @@ -0,0 +1,35 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_wait_for_event_until" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_wait_for_event_until - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_wait_for_event_until(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout) +\f[R] +.fi +.SH DESCRIPTION +.PP +Wait until the event queue specified is non-empty. +If \f[C]ret_event\f[R] is not NULL, the first event in the queue will be +copied into \f[C]ret_event\f[R] and removed from the queue. +If \f[C]ret_event\f[R] is NULL the first event is left at the head of +the queue. +.PP +\f[C]timeout\f[R] determines how long to wait. +If the call times out, false is returned. +Otherwise, if an event ocurred, true is returned. +.PP +For compatibility with all platforms, \f[C]timeout\f[R] must be +2,147,483.647 seconds or less. +.SH SEE ALSO +.PP +ALLEGRO_EVENT(3), ALLEGRO_TIMEOUT(3), al_init_timeout(3), +al_wait_for_event(3), al_wait_for_event_timed(3) diff --git a/allegro/docs/man/al_wait_for_vsync.3 b/allegro/docs/man/al_wait_for_vsync.3 new file mode 100644 index 00000000..417245b6 --- /dev/null +++ b/allegro/docs/man/al_wait_for_vsync.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_wait_for_vsync" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_wait_for_vsync - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_wait_for_vsync(void) +\f[R] +.fi +.SH DESCRIPTION +.PP +Wait for the beginning of a vertical retrace. +Some driver/card/monitor combinations may not be capable of this. +.PP +Note how al_flip_display(3) usually already waits for the vertical +retrace, so unless you are doing something special, there is no reason +to call this function. +.PP +Returns false if not possible, true if successful. +.SH SEE ALSO +.PP +al_flip_display(3) diff --git a/allegro/docs/man/al_win_add_window_callback.3 b/allegro/docs/man/al_win_add_window_callback.3 new file mode 100644 index 00000000..49eb2dcf --- /dev/null +++ b/allegro/docs/man/al_win_add_window_callback.3 @@ -0,0 +1,38 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_win_add_window_callback" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_win_add_window_callback - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_win_add_window_callback(ALLEGRO_DISPLAY *display, + bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam, + LPARAM lparam, LRESULT *result, void *userdata), void *userdata) +\f[R] +.fi +.SH DESCRIPTION +.PP +The specified callback function will intercept the window\[cq]s message +before Allegro processes it. +If the callback function consumes the event, then it should return true. +In that case, Allegro will not do anything with the event. +.PP +Optionally, you may use \f[C]result\f[R] to customize what Allegro will +return return in response to this event. +By default, Allegro returns \f[C]TRUE\f[R]. +.PP +The \f[C]userdata\f[R] pointer can be used to supply additional context +to the callback function. +.PP +The callbacks are executed in the same order they were added. +.PP +Returns true if the callback was added. +.SH SINCE +.PP +5.1.2 diff --git a/allegro/docs/man/al_win_remove_window_callback.3 b/allegro/docs/man/al_win_remove_window_callback.3 new file mode 100644 index 00000000..021d4759 --- /dev/null +++ b/allegro/docs/man/al_win_remove_window_callback.3 @@ -0,0 +1,29 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_win_remove_window_callback" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_win_remove_window_callback - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_win_remove_window_callback(ALLEGRO_DISPLAY *display, + bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam, + LPARAM lparam, LRESULT *result, void *userdata), void *userdata) +\f[R] +.fi +.SH DESCRIPTION +.PP +Removes the callback that was previously registered with +al_win_add_window_callback(3). +The \f[C]userdata\f[R] pointer must be the same as what was used during +the registration of the callback. +.PP +Returns true if the callback was removed. +.SH SINCE +.PP +5.1.2 diff --git a/allegro/docs/man/al_x_set_initial_icon.3 b/allegro/docs/man/al_x_set_initial_icon.3 new file mode 100644 index 00000000..c44914f0 --- /dev/null +++ b/allegro/docs/man/al_x_set_initial_icon.3 @@ -0,0 +1,30 @@ +.\" Automatically generated by Pandoc 2.11.4 +.\" +.TH "al_x_set_initial_icon" "3" "" "Allegro reference manual" "" +.hy +.SH NAME +.PP +al_x_set_initial_icon - Allegro 5 API +.SH SYNOPSIS +.IP +.nf +\f[C] +#include + +bool al_x_set_initial_icon(ALLEGRO_BITMAP *bitmap) +\f[R] +.fi +.SH DESCRIPTION +.PP +On some window managers (notably Ubuntu\[cq]s Unity) al_set_display_icon +doesn\[cq]t work and you need to use a .desktop file. +But with this function you can set an icon before calling +al_create_display. +This works by setting the icon before XMapWindow. +.SH SINCE +.PP +5.2.3 +.RS +.PP +\f[I][Unstable API]:\f[R] New API. +.RE diff --git a/allegro/docs/scripts/aatree.c b/allegro/docs/scripts/aatree.c new file mode 100644 index 00000000..8803dd51 --- /dev/null +++ b/allegro/docs/scripts/aatree.c @@ -0,0 +1,104 @@ +/* + * AA tree, a type of self-balancing search tree. + * + * A. Andersson. "Balanced search trees made simple." + * In Proc. Workshop on Algorithms and Data Structures, pages 60--71. + * Springer Verlag, 1993. + */ + +#include +#include +#include "aatree.h" + +Aatree aa_nil = { 0, &aa_nil, &aa_nil, "", "" }; + +static char *xstrdup(const char *s) +{ + size_t n = strlen(s); + char *p = malloc(n + 1); + memcpy(p, s, n); + p[n] = '\0'; + return p; +} + +static Aatree *skew(Aatree *T) +{ + if (T == &aa_nil) + return T; + if (T->left->level == T->level) { + Aatree *L = T->left; + T->left = L->right; + L->right = T; + return L; + } + return T; +} + +static Aatree *split(Aatree *T) +{ + if (T == &aa_nil) + return T; + if (T->level == T->right->right->level) { + Aatree *R = T->right; + T->right = R->left; + R->left = T; + R->level = R->level + 1; + return R; + } + return T; +} + +Aatree *aa_singleton(const char *key, const char *value) +{ + Aatree *T = malloc(sizeof(Aatree)); + T->level = 1; + T->left = &aa_nil; + T->right = &aa_nil; + T->key = xstrdup(key); + T->value = xstrdup(value); + return T; +} + +Aatree *aa_insert(Aatree *T, const char *key, const char *value) +{ + int cmp; + if (T == &aa_nil) { + return aa_singleton(key, value); + } + cmp = strcmp(key, T->key); + if (cmp < 0) { + T->left = aa_insert(T->left, key, value); + } else if (cmp > 0) { + T->right = aa_insert(T->right, key, value); + } else { + free(T->value); + T->value = xstrdup(value); + } + T = skew(T); + T = split(T); + return T; +} + +const char *aa_search(const Aatree *T, const char *key) +{ + while (T != &aa_nil) { + int cmp = strcmp(key, T->key); + if (cmp == 0) + return T->value; + T = (cmp < 0) ? T->left : T->right; + } + return NULL; +} + +void aa_destroy(Aatree *T) +{ + if (T != &aa_nil) { + aa_destroy(T->left); + aa_destroy(T->right); + free(T->key); + free(T->value); + free(T); + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/aatree.h b/allegro/docs/scripts/aatree.h new file mode 100644 index 00000000..ecf3ba07 --- /dev/null +++ b/allegro/docs/scripts/aatree.h @@ -0,0 +1,22 @@ +#ifndef __included_aatree_h +#define __included_aatree_h + +typedef struct Aatree Aatree; +struct Aatree { + int level; + Aatree *left; + Aatree *right; + char *key; + char *value; +}; + +extern Aatree aa_nil; + +Aatree *aa_singleton(const char *key, const char *value); +Aatree *aa_insert(Aatree *T, const char *key, const char *value); +const char *aa_search(const Aatree *T, const char *key); +void aa_destroy(Aatree *T); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/check_consistency b/allegro/docs/scripts/check_consistency new file mode 100644 index 00000000..f49967e3 --- /dev/null +++ b/allegro/docs/scripts/check_consistency @@ -0,0 +1,58 @@ +#!/bin/sh -e +# +# SYNOPSIS +# +# check_consistency [OPTION...] DOC-FILE... +# +# OPTION +# +# --protos FILE +# +# DESCRIPTION +# +# Check that functions and types marked in source code have corresponding +# entries in the documentation, and vice versa. The protos file must be +# present. +# +# ENVIRONMENT VARIABLES +# +# - PROTOS +# + +export LC_ALL=C + +PROTOS=${PROTOS:-protos} + +case $1 in + --protos) + PROTOS=$2 + shift 2 + ;; +esac + +if test ! -f "$PROTOS" +then + echo "check_consistency: missing protos file: $PROTOS" 1>&2 + exit 1 +fi + +TEMP_SRC=check_consistency.tmp1.$$ +TEMP_DOC=check_consistency.tmp2.$$ +trap 'rm -f $TEMP_SRC $TEMP_DOC' 0 1 2 3 13 15 + +cut -d':' -f1 "$PROTOS" | sort | uniq > $TEMP_SRC +grep -h '# API: ' "$@" | cut -d' ' -f 3- | sort | uniq > $TEMP_DOC + +diff $TEMP_SRC $TEMP_DOC | while read -r marker name +do + case $marker in + '>') + echo "$name not in source (or missing Function: marker)" + ;; + '<') + echo "$name not documented" + ;; + esac +done + +# vim: set et: diff --git a/allegro/docs/scripts/dawk.c b/allegro/docs/scripts/dawk.c new file mode 100644 index 00000000..58a49ad7 --- /dev/null +++ b/allegro/docs/scripts/dawk.c @@ -0,0 +1,322 @@ +/* Support for awk-style processing in C. */ + +#include +#include +#include +#include +#include + +/* I'd prefer to use the POSIX regexp interface, but for portability we need a + * fallback, and supporting two regexp implementations is asking for trouble. + * T-Rex is small and quick enough so we use it everywhere. However it + * doesn't seem to behave properly on some expressions (which we can work + * around when the regexps are fixed) so I couldn't recommend it in general. + */ +#include "dawk.h" +#include "trex.h" + +typedef struct { + const char *regex; + TRex *reg; +} re_cache_t; + +void (*d_cleanup)(void); + +static int d_argc; +static char **d_argv; +static int d_file_num; + +static FILE *d_file; +dstr d_filename; +int d_line_num; + +FILE *d_stdout; +#define D_STDOUT (d_stdout ? d_stdout : stdout) + +#define MAX_RE_CACHE 16 +static re_cache_t d_regex_cache[MAX_RE_CACHE]; +static dstr d_submatches[MAX_MATCH]; +dstr d_before_match; +dstr d_after_match; + + +/* Abort with an error message. */ +void d_doabort(const char *filename, int line, const char *msg1, + const char *msg2) +{ + fprintf(stderr, "%s:%d: %s%s\n", filename, line, msg1, msg2); + if (d_cleanup) { + d_cleanup(); + } + exit(EXIT_FAILURE); +} + + +/* Prepare to read input from the files listed in argv. */ +void d_init(int argc, char *argv[]) +{ + d_argc = argc; + d_argv = argv; + d_file_num = 0; + d_close_input(); +} + + +/* Open a single file for reading. */ +void d_open_input(const char *filename) +{ + if (d_file) { + fclose(d_file); + } + d_file = fopen(filename, "r"); + if (!d_file) { + d_abort("could not open file for reading: ", filename); + } + d_assign(d_filename, filename); + d_line_num = 0; + d_file_num = -1; +} + + +/* Close input file. */ +void d_close_input(void) +{ + if (d_file) { + fclose(d_file); + } + d_file = NULL; + d_assign(d_filename, ""); +} + + +/* Read the next line from the current input file(s). */ +bool d_getline(dstr var) +{ + char *p = var; + int c; + + /* Open the next file if necessary. */ + if (!d_file) { + if (d_file_num == -1 || d_file_num + 1 >= d_argc) { + return false; + } + d_file_num++; + d_file = fopen(d_argv[d_file_num], "r"); + if (!d_file) { + d_abort("could not open file for reading: ", d_argv[d_file_num]); + } + d_assign(d_filename, d_argv[d_file_num]); + d_line_num = 0; + } + + for (;;) { + c = fgetc(d_file); + if (c == EOF || c == '\n') { + break; + } + *p++ = c; + if (p - var >= MAX_STRING - 1) { + fprintf(stderr, "dawk: string length limit reached\n"); + break; + } + } + *p = '\0'; + + if (c == EOF) { + fclose(d_file); + d_file = NULL; + if (p == var) { + return d_getline(var); + } + } + else if (c == '\n') { + d_line_num++; + /* Remove trailing CR if present. */ + if (p > var && p[-1] == '\r') { + p[-1] = '\0'; + } + } + + return true; +} + + +/* Open a file for writing. */ +void d_open_output(const char *filename) +{ + FILE *f; + + d_close_output(); + f = fopen(filename, "w"); + if (!f) { + d_abort("error opening file for writing: ", filename); + } + d_stdout = f; +} + + +/* Close the output file, reverting to standard output. */ +void d_close_output(void) +{ + if (d_stdout && d_stdout != stdout) { + fclose(d_stdout); + } + d_stdout = NULL; +} + + +/* Print a line to the output file, with newline. */ +void d_print(const char *s) +{ + fprintf(D_STDOUT, "%s\n", s); +} + + +/* Print formatted output to the output file. */ +void d_printf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + vfprintf(D_STDOUT, format, ap); + va_end(ap); +} + + +/* Assign a string. */ +void d_assign(dstr to, const dstr from) +{ + /* Might be overlapping. */ + memmove(to, from, strlen(from) + 1); +} + + +/* Assign a length-delimited string. */ +void d_assignn(dstr to, const dstr from, size_t n) +{ + /* Might be overlapping. */ + memmove(to, from, n); + to[n] = '\0'; +} + + +static re_cache_t *compile_regex(const char *regex) +{ + re_cache_t *re; + int i; + + for (i = 0; i < MAX_RE_CACHE; i++) { + re = &d_regex_cache[i]; + if (re->regex == NULL) { + re->regex = regex; + re->reg = trex_compile(regex, NULL); + if (re->reg == NULL) { + d_abort("error compiling regular expression: ", regex); + } + } + if (re->regex == regex) { + return re; + } + } + + d_abort("too many regular expressions", ""); + return NULL; +} + + +/* Match a string against the given regular expression. + * Returns true on a successful match. + */ +bool d_match(dstr line, const char *regex) +{ + re_cache_t *re; + TRexMatch match; + int i; + + re = compile_regex(regex); + + if (!trex_search(re->reg, line, NULL, NULL)) { + return false; + } + + trex_getsubexp(re->reg, 0, &match); + d_assignn(d_before_match, line, match.begin - line); + d_assign(d_after_match, match.begin + match.len); + + for (i = 0; i < MAX_MATCH; i++) { + if (trex_getsubexp(re->reg, i, &match)) { + strncpy(d_submatches[i], match.begin, match.len); + d_submatches[i][match.len] = '\0'; + } + else { + d_submatches[i][0] = '\0'; + } + } + + return true; +} + + +/* Return a submatch from the previous d_match call. */ +const char *d_submatch(int i) +{ + return d_submatches[i]; +} + + +static const char *strrchr2(const char *s, char c1, char c2) +{ + const char *p = s + strlen(s); + for (; p >= s; p--) { + if (*p == c1 || *p == c2) + return p; + } + return NULL; +} + + +void d_basename(const char *filename, const char *newext, dstr output) +{ + const char *start; + char *dot; + + start = strrchr2(filename, '/', '\\'); + if (start) + strcpy(output, start + 1); + else + strcpy(output, filename); + + if (newext) { + dot = strrchr(output, '.'); + if (dot) + strcpy(dot, newext); + else + strcat(output, newext); + } +} + + +void d_tolower(const dstr src, dstr dest) +{ + const char *s = src; + char *d = dest; + for (; *s; s++, d++) { + *d = tolower(*s); + } + *d = '\0'; +} + + +void d_delchr(dstr str, char c) +{ + const char *r = str; + char *w = str; + for (; *r; r++) { + if (*r != c) { + *w = *r; + w++; + } + } + *w = '\0'; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/dawk.h b/allegro/docs/scripts/dawk.h new file mode 100644 index 00000000..d07a9b91 --- /dev/null +++ b/allegro/docs/scripts/dawk.h @@ -0,0 +1,54 @@ +#ifndef __included_dawk_h +#define __included_dawk_h + +#ifdef _MSC_VER + #define bool int + #define true 1 + #define false 0 +#else + #include +#endif +#include + +#define MAX_STRING 3000 +#define MAX_MATCH 8 + +typedef char dstr[MAX_STRING]; + +extern void (*d_cleanup)(void); +extern dstr d_filename; +extern int d_line_num; +extern FILE *d_stdout; +extern dstr d_before_match; +extern dstr d_after_match; + +#define D_STDOUT (d_stdout ? d_stdout : stdout) + +#define d_abort(msg1, msg2) (d_doabort(__FILE__, __LINE__, (msg1), (msg2))) + +extern void d_doabort(const char *filename, int line, const char *msg1, + const char *msg2); + +extern void d_init(int argc, char *argv[]); +extern void d_open_input(const char *filename); +extern void d_close_input(void); +extern bool d_getline(dstr var); + +extern void d_open_output(const char *filename); +extern void d_close_output(void); +extern void d_print(const char *s); +extern void d_printf(const char *format, ...); + +extern void d_assign(dstr to, const dstr from); +extern void d_assignn(dstr to, const dstr from, size_t n); + +extern bool d_match(dstr line, const char *regex); +extern const char *d_submatch(int i); + +extern void d_basename(const char *filename, const char *newext, dstr output); +extern void d_tolower(const dstr src, dstr dest); +extern void d_delchr(dstr str, char c); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/insert_timestamp.c b/allegro/docs/scripts/insert_timestamp.c new file mode 100644 index 00000000..aaeb414b --- /dev/null +++ b/allegro/docs/scripts/insert_timestamp.c @@ -0,0 +1,43 @@ +/* + * Generate an fragment to be inserted at the bottom of HTML pages. + * The timestamp follows RFC 3339. + * We use UTC. + */ + +#include +#include +#include +#include "dawk.h" + +int main(int argc, char **argv) +{ + time_t now; + char buf[64]; + char const *version = "unknown"; + + time(&now); + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S UTC", gmtime(&now)); + + if (argc > 1) { + dstr line; + + d_open_input(argv[1]); + + while (d_getline(line)) { + if (d_match(line, "#define ALLEGRO_VERSION_STR *\"([^\"]*)\"")) { + version = d_submatch(1); + break; + } + } + + d_close_input(); + } + + printf("

\n"); + printf("Allegro version %s\n", version); + printf(" - Last updated: %s\n", buf); + printf("

\n"); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/make_doc.c b/allegro/docs/scripts/make_doc.c new file mode 100644 index 00000000..011a0830 --- /dev/null +++ b/allegro/docs/scripts/make_doc.c @@ -0,0 +1,312 @@ +/* + * make_doc OPTIONS... [--] DOC-FILES + * + * Options are: + * + * --pandoc PANDOC + * --protos PROTOS-FILE + * --examples EXAMPLES-FILE + * --to FORMAT (html, man, latex, texinfo, etc.) + * --raise-sections + * + * Unknown options are passed through to Pandoc. + */ + +#include +#include +#include +#include +#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || (_XOPEN_SOURCE >= 500) || defined(__APPLE__) + #include + #define USE_MKSTEMP 1 +#elif defined(_MSC_VER) + #define TEMPNAM(d, p) (_tempnam((d), (p))) +#else + #define TEMPNAM(d, p) (tempnam((d), (p))) +#endif + +#include "aatree.h" +#include "dawk.h" +#include "make_doc.h" + + +dstr pandoc = "pandoc"; +dstr pandoc_options = ""; +dstr protos_file = "protos"; +dstr examples_file = ""; +dstr to_format = "html"; +dstr allegro5_cfg_filename = ""; +bool raise_sections = false; +dstr tmp_preprocess_output; +dstr tmp_pandoc_output; +dstr git_ref = "master"; + +static Aatree *protos = &aa_nil; +static Aatree *examples = &aa_nil; +static Aatree *sources = &aa_nil; + + +static int process_options(int argc, char *argv[]); +static void load_prototypes(const char *filename); +static void load_examples(const char *filename); +static void generate_temp_file(char *filename); +static void remove_temp_files(void); + + +int main(int argc, char *argv[]) +{ + argc = process_options(argc, argv); + load_prototypes(protos_file); + load_examples(examples_file); + + generate_temp_file(tmp_preprocess_output); + generate_temp_file(tmp_pandoc_output); + d_cleanup = remove_temp_files; + + if (0 == strcmp(to_format, "man")) + make_man_pages(argc, argv); + else + make_single_doc(argc, argv); + + d_cleanup(); + return 0; +} + + +static int process_options(int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; ) { + if (streq(argv[i], "--")) { + i++; + break; + } + if (argv[i][0] != '-') { + break; + } + if (streq(argv[i], "--pandoc")) { + d_assign(pandoc, argv[i + 1]); + i += 2; + } + else if (streq(argv[i], "--protos")) { + d_assign(protos_file, argv[i + 1]); + i += 2; + } + else if (streq(argv[i], "--examples")) { + d_assign(examples_file, argv[i + 1]); + i += 2; + } + else if (streq(argv[i], "--to")) { + d_assign(to_format, argv[i + 1]); + i += 2; + } + else if (streq(argv[i], "--allegro5_cfg")) { + d_assign(allegro5_cfg_filename, argv[i + 1]); + i += 2; + } + else if (streq(argv[i], "--git_ref")) { + d_assign(git_ref, argv[i + 1]); + i += 2; + } + else if (streq(argv[i], "--raise-sections")) { + raise_sections = true; + i++; + } + else { + /* Other options are assumed to be Pandoc options. */ + strcat(pandoc_options, " "); + strcat(pandoc_options, argv[i]); + i++; + if (i < argc && argv[i][0] != '-') { + strcat(pandoc_options, " "); + strcat(pandoc_options, argv[i]); + i++; + } + } + } + + /* Shift arguments, including sentinel, but not the command name. */ + memmove(argv + 1, argv + i, (argc - i + 1) * sizeof(char *)); + return argc - (i - 1); +} + + +static void load_prototypes(const char *filename) +{ + dstr line; + const char *name; + const char *newtext; + const char *file_name; + const char *line_number; + dstr text; + + d_open_input(filename); + + while (d_getline(line)) { + if (d_match(line, "([^:]*): ([^:]*):([^:]*):([^:]*)")) { + name = d_submatch(1); + newtext = d_submatch(2); + file_name = d_submatch(3); + line_number = d_submatch(4); + + d_assign(text, lookup_prototype(name)); + strcat(text, "\n"); + strcat(text, newtext); + protos = aa_insert(protos, name, text); + + d_assign(text, lookup_source(name)); + if (strlen(text) == 0) { + sprintf(text, "https://github.com/liballeg/allegro5/blob/%s/%s#L%s", + git_ref, file_name, line_number); + sources = aa_insert(sources, name, text); + } + } + } + + d_close_input(); +} + +static void load_examples(const char *filename) +{ + dstr line; + const char *name; + const char *files; + + if (filename == NULL || *filename == '\0') { + return; + } + + d_open_input(filename); + + while (d_getline(line)) { + if (d_match(line, "([^:]*): ")) { + name = d_submatch(1); + files = d_after_match; + examples = aa_insert(examples, name, files); + } + } + + d_close_input(); +} + +const char* example_source(dstr buffer, const char *file_name, const char *line_number) { + sprintf(buffer, "https://github.com/liballeg/allegro5/blob/%s/%s#L%s", + git_ref, file_name, line_number); + return buffer; +} + + +char *load_allegro5_cfg(void) +{ + FILE *f = fopen(allegro5_cfg_filename, "rb"); + if (!f) { + d_abort("could not open file for reading: ", allegro5_cfg_filename); + } + + if (fseek(f, 0, SEEK_END)) { + d_abort("could not seek to end: ", allegro5_cfg_filename); + } + + long length = ftell(f); + if (length == -1) { + d_abort("could not tell length of file: ", allegro5_cfg_filename); + } + + if (fseek(f, 0, SEEK_SET)) { + d_abort("could not seek back to beginning: ", allegro5_cfg_filename); + } + char *ret = malloc(length + 1); + size_t read_bytes = fread(ret, 1, length, f); + if (read_bytes != (size_t)length) { + d_abort("could not read file: ", allegro5_cfg_filename); + } + fclose(f); + + ret[length] = '\0'; + return ret; +} + + +const char *lookup_prototype(const char *name) +{ + const char *r = aa_search(protos, name); + return (r) ? r : ""; +} + + +const char *lookup_source(const char *name) +{ + const char *r = aa_search(sources, name); + return (r) ? r : ""; +} + +const char *lookup_example(const char *name) +{ + return aa_search(examples, name); +} + +void generate_temp_file(char *filename) +{ + /* gcc won't shut up if we use tmpnam() so we'll use mkstemp() if it is + * likely to be available. + */ +#ifdef USE_MKSTEMP + int fd; + d_assign(filename, "make_doc_tmp.XXXXXX"); + fd = mkstemp(filename); + if (fd == -1) { + d_abort("could not generate temporary file name", ""); + } + close(fd); +#else + char *name = TEMPNAM(NULL, "make_doc_tmp."); + if (!name) { + d_abort("could not generate temporary file name", ""); + } + d_assign(filename, name); + free(name); +#endif +} + + +static void remove_temp_files(void) +{ + remove(tmp_preprocess_output); + remove(tmp_pandoc_output); +} + + +void call_pandoc(const char *input, const char *output, + const char *extra_options) +{ + dstr cmd; + dstr input_native; + char *p; + + strcpy(input_native, input); + + /* Use native Windows syntax to avoid "c:/foo.txt" being treated as a + * remote URI by Pandoc 1.5 and 1.6. + */ + if (strlen(input_native) > 2 + && isalpha(input_native[0]) + && input_native[1] == ':') { + for (p = input_native; *p != '\0'; p++) { + if (*p == '/') + *p = '\\'; + } + } + + sprintf(cmd, "\"%s\" %s %s %s --from markdown --to %s --output %s", + pandoc, input_native, pandoc_options, extra_options, to_format, output); + if (system(cmd) != 0) { + d_abort("system call failed: ", cmd); + } +} + +/* Local Variables: */ +/* c-basic-offset: 3 */ +/* End: */ + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/make_doc.h b/allegro/docs/scripts/make_doc.h new file mode 100644 index 00000000..dcd51586 --- /dev/null +++ b/allegro/docs/scripts/make_doc.h @@ -0,0 +1,28 @@ +#ifndef __included_make_doc_h +#define __included_make_doc_h + +#include "dawk.h" + +extern dstr pandoc; +extern dstr pandoc_options; +extern dstr protos_file; +extern dstr to_format; +extern bool raise_sections; +extern dstr tmp_preprocess_output; +extern dstr tmp_pandoc_output; + +#define streq(a, b) (0 == strcmp((a), (b))) + +const char *lookup_prototype(const char *name); +const char *lookup_source(const char *name); +const char *lookup_example(const char *name); +const char* example_source(dstr buffer, const char *file_name, const char *line_number); +extern void call_pandoc(const char *input, const char *output, + const char *extra_options); +extern void make_single_doc(int argc, char *argv[]); +extern void make_man_pages(int argc, char *argv[]); +char *load_allegro5_cfg(void); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/make_html_refs.c b/allegro/docs/scripts/make_html_refs.c new file mode 100644 index 00000000..875a077c --- /dev/null +++ b/allegro/docs/scripts/make_html_refs.c @@ -0,0 +1,46 @@ +/* + * make_html_refs DOC-FILE... + * + * Generate a file containing (HTML-specific) link definitions for each API + * entry found. e.g. if foo.txt contains "# API: bar" then we generate: + * + * [bar]: foo.html#bar + */ + +#include +#include "dawk.h" + +/* Replicate pandoc's function to create a label anchor from the section + * name. + */ +static void replace_spaces(char *s) +{ + while (*s) { + if (*s == ' ') *s = '-'; + s++; + } +} + +int main(int argc, char *argv[]) +{ + dstr line; + dstr file; + const char *name; + dstr sec_id; + + d_init(argc, argv); + + while (d_getline(line)) { + if (d_match(line, "^#+( API:| ) *")) { + d_basename(d_filename, ".html", file); + name = d_after_match; + d_tolower(name, sec_id); + replace_spaces(sec_id); + d_printf("[%s]: %s#%s\n", name, file, sec_id); + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/make_index.c b/allegro/docs/scripts/make_index.c new file mode 100644 index 00000000..7d50f504 --- /dev/null +++ b/allegro/docs/scripts/make_index.c @@ -0,0 +1,67 @@ +/* + * make_index HTML-REFS-FILE... + * + * Generate a file containing a list of links to all API entries. + * The links are sorted using strcmp. + */ + +#include +#include +#include "dawk.h" +#include "aatree.h" + +static char *xstrdup(const char *s) +{ + size_t n = strlen(s); + char *p = malloc(n + 1); + memcpy(p, s, n); + p[n] = '\0'; + return p; +} + +static void print_link(const char *value) +{ + d_printf("* [%s]\n", value); + + /* Work around Pandoc issue #182. */ + d_printf("\n"); +} + +static void pre_order_traversal(Aatree *node, void (*doit)(const char *)) +{ + if (node->left != &aa_nil) { + pre_order_traversal(node->left, doit); + } + + doit(node->value); + + if (node->right != &aa_nil) { + pre_order_traversal(node->right, doit); + } +} + +int main(int argc, char *argv[]) +{ + dstr line; + Aatree * root = &aa_nil; + + d_init(argc, argv); + + d_printf("# Index\n"); + + while ((d_getline(line))) { + if (d_match(line, "^\\[([^\\]]*)")) { + const char *ref = d_submatch(1); + char *s = xstrdup(ref); + root = aa_insert(root, s, s); + } + } + + pre_order_traversal(root, print_link); + + aa_destroy(root); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/make_man.c b/allegro/docs/scripts/make_man.c new file mode 100644 index 00000000..654a8191 --- /dev/null +++ b/allegro/docs/scripts/make_man.c @@ -0,0 +1,122 @@ +#include +#include +#include "aatree.h" +#include "dawk.h" +#include "make_doc.h" + +#define MAX_NAMES 64 + +static const char *SECTION = "3"; +static const char *MANUAL = "Allegro reference manual"; +static const char *SUFFIX = "Allegro 5 API"; +static dstr last_header; +static dstr names[MAX_NAMES]; + +static void man_page_header(const char *name) +{ + d_printf("%% %s(%s) %s\n", name, SECTION, MANUAL); + d_print("# NAME"); + d_print(name); + d_printf(" \\- %s\n\n", SUFFIX); + d_print("# SYNOPSIS"); + d_print("~~~~c"); + d_print(last_header); + d_print(lookup_prototype(name)); + d_print("~~~~"); + d_print("# DESCRIPTION"); +} + +static void call_pandoc_for_man(const char *input, int name_count) +{ + dstr output_filename; + int i; + + for (i = 0; i < name_count; i++) { + sprintf(output_filename, "%s.%s", names[i], SECTION); + call_pandoc(input, output_filename, "--standalone"); + } +} + +void make_man_pages(int argc, char *argv[]) +{ + int output_level = 0; + int name_count = 0; + dstr line; + + d_init(argc, argv); + + while (d_getline(line)) { + /* Stop outputting the current man page at the first line beginning with + * the same or few number of hashes, i.e. at the same level or above. + */ + if (d_match(line, "^(#+) ") && output_level > 0) { + int n = strlen(d_submatch(1)); + if (n <= output_level) { + d_close_output(); + call_pandoc_for_man(tmp_preprocess_output, name_count); + name_count = 0; + output_level = 0; + } + } + + if (d_match(line, "^ *(#include.*)") && output_level == 0) { + d_assign(last_header, d_submatch(1)); + continue; + } + + if (d_match(line, "^(#+) API: *(.*)")) { + const char *hashes = d_submatch(1); + const char *name = d_submatch(2); + + if (output_level == 0) { + output_level = strlen(hashes); + d_open_output(tmp_preprocess_output); + man_page_header(name); + } + else { + d_printf("%s %s\n", hashes, name); + } + if (name_count < MAX_NAMES) { + d_assign(names[name_count], name); + name_count++; + } + continue; + } + + if (!output_level) { + continue; + } + + if (d_match(line, "^\\*?Return [Vv]alue:\\*?")) { + d_print("# RETURN VALUE"); + d_assign(line, d_after_match); + } + + if (d_match(line, "^\\*?Since:\\*?")) { + d_print("# SINCE"); + d_assign(line, d_after_match); + } + + if (d_match(line, "^\\*?See [Aa]lso:\\*?")) { + d_print("# SEE ALSO"); + d_assign(line, d_after_match); + } + + /* Replace [al_foo] and [ALLEGRO_foo] by al_foo(3) and ALLEGRO_foo(3). */ + while (d_match(line, "\\[((al_|ALLEGRO_)[^\\]]*)\\]")) { + d_printf("%s", d_before_match); + d_printf("%s(%s)", d_submatch(1), SECTION); + d_assign(line, d_after_match); + } + d_print(line); + } + + if (output_level > 0) { + d_close_output(); + call_pandoc_for_man(tmp_preprocess_output, name_count); + name_count = 0; + output_level = 0; + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/make_protos.c b/allegro/docs/scripts/make_protos.c new file mode 100644 index 00000000..7755fde6 --- /dev/null +++ b/allegro/docs/scripts/make_protos.c @@ -0,0 +1,53 @@ +/* + * make_protos SOURCE-FILE... + * + * Extract all the function prototypes and type/enum declarations which have + * Natural Docs tags Function: Type: Enum: and print them to standard output. + */ + +#include "dawk.h" + +int main(int argc, char *argv[]) +{ + bool found_tag = false; + bool do_print = false; + dstr line = ""; + dstr prefix = ""; + + d_init(argc, argv); + + while (d_getline(line)) { + if (d_match(line, "/[*] (Function|Type|Enum): (.*)")) { + found_tag = true; + do_print = false; + d_assign(prefix, d_submatch(2)); + continue; + } + if (found_tag && d_match(line, "^ ?\\*/")) { + found_tag = false; + do_print = true; + continue; + } + if (d_match(line, "^\\{|^$")) { + do_print = false; + continue; + } + /* Prototype ends on blank line. */ + /* TODO: Should the above regexp match it? If so it doesn't here... */ + if (line[0] == 0) { + do_print = false; + continue; + } + if (do_print) { + printf("%s: %s:%s:%d\n", prefix, line, d_filename, + d_line_num); + } + if (d_match(line, "\\{ *$|; *$")) { + do_print = false; + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/make_search_index.c b/allegro/docs/scripts/make_search_index.c new file mode 100644 index 00000000..314534da --- /dev/null +++ b/allegro/docs/scripts/make_search_index.c @@ -0,0 +1,52 @@ +/* + * make_search_index html_refs > search_index.js + * + * Read html_refs and convert it to a Javascript index for autosuggest.js. + */ + +#include +#include +#include "dawk.h" + +dstr *names; +dstr *urls; +int num_entries = 0; + +static int add_entry(void) { + int i = num_entries++; + names = realloc(names, num_entries * sizeof *names); + urls = realloc(urls, num_entries * sizeof *urls); + return i; +} + +int main(int argc, char *argv[]) +{ + dstr line; + int i; + + d_init(argc, argv); + + while (d_getline(line)) { + if (d_match(line, "^\\[(.*)\\]: (.*)")) { + int i = add_entry(); + strcpy(names[i], d_submatch(1)); + strcpy(urls[i], d_submatch(2)); + } + } + + printf("var search_index = [\n"); + for (i = 0; i < num_entries; i++) { + printf("'%s',", names[i]); + } + printf("]\n"); + + printf("var search_urls = [\n"); + for (i = 0; i < num_entries; i++) { + printf("'%s',", urls[i]); + } + printf("]\n"); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/make_single.c b/allegro/docs/scripts/make_single.c new file mode 100644 index 00000000..4ddb9033 --- /dev/null +++ b/allegro/docs/scripts/make_single.c @@ -0,0 +1,182 @@ +#include +#include +#include "dawk.h" +#include "make_doc.h" + +static void preprocess(void); +static void postprocess_latex(void); +static void cat(void); +static void print_sans_backslashes(const char *p); + +static void insert_examples(void); +static char current_api[64]; + +void make_single_doc(int argc, char *argv[]) +{ + d_init(argc, argv); + + /* Hidden format for debugging. */ + if (streq(to_format, "preprocess")) { + preprocess(); + return; + } + + d_open_output(tmp_preprocess_output); + preprocess(); + d_close_output(); + + call_pandoc(tmp_preprocess_output, tmp_pandoc_output, ""); + + d_open_input(tmp_pandoc_output); + if (streq(to_format, "latex")) + postprocess_latex(); + else + cat(); + d_close_input(); +} + +static void preprocess(void) +{ + dstr line; + + while (d_getline(line)) { + /* If this is a heading, a new section is about to start. + Insert the pending code examples (if any) beforehand. */ + if (line[0] == '#') { + insert_examples(); + } + + /* Raise sections by one level. Top-most becomes the document title. */ + if (line[0] == '#' && raise_sections) { + if (line[1] == ' ') { + line[0] = '%'; + } + else { + char *p = strchr(line, ' '); + if (p) { + p[-1] = ' '; + } + } + } + + /* Make sure there is a blank line between input files so paragraphs + * across files don't get merged. But don't break document titles which + * must be on the first line. + */ + if (d_line_num == 1 && line[0] != '%') { + d_print(""); + } + + if (d_match(line, "^(#+) +API: *")) { + const char *hashes = d_submatch(1); + const char *name = d_after_match; + const char *text = lookup_prototype(name); + const char *source = lookup_source(name); + + d_printf("%s %s\n", hashes, name); + if (strcmp(text, "") != 0) { + d_printf("~~~~c"); + d_print(text); + d_printf("~~~~"); + } + d_printf("\n[Source Code](%s)\n", source); + strcpy(current_api, name); + } + else if (d_match(line, "^__ALLEGRO_5_CFG")) { + char *allegro5_cfg = load_allegro5_cfg(); + d_print(allegro5_cfg); + free(allegro5_cfg); + } + else { + d_print(line); + } + } + /* Finally insert any examples for the last section */ + insert_examples(); +} + +static void postprocess_latex(void) +{ + dstr line; + + while (d_getline(line)) { + /* Insert \label{id} for all sections which are probably API entries. + * T-Rex doesn't seem to backtrack properly if we write "(sub)*". + */ + if (d_match(line, + "\\\\(sub)?(sub)?(sub)?(sub)?section\\{((al|ALLEGRO)[^}]+)")) { + d_print(line); + d_printf("\\label{"); + print_sans_backslashes(d_submatch(5)); + d_printf("}\n"); + continue; + } + + /* Replace `verbatim' environment by `Verbatim' from fancyvrb, + * which gives us some flexibility over the formatting. + */ + if (d_match(line, "\\\\begin\\{verbatim\\}$")) { + d_printf("%s", d_before_match); + d_print("\\begin{Verbatim}"); + continue; + } + if (d_match(line, "\\\\end\\{verbatim\\}$")) { + d_printf("%s", d_before_match); + d_print("\\end{Verbatim}"); + continue; + } + + d_print(line); + } +} + +static void cat(void) +{ + dstr line; + while (d_getline(line)) + d_print(line); +} + +static void print_sans_backslashes(const char *p) +{ + for (; *p; p++) { + if (*p != '\\') + fputc(*p, D_STDOUT); + } +} + +static void insert_examples(void) { + if (*current_api) { + const char* exs = lookup_example(current_api); + if (exs) { + /* This will be of the form "FILE:LINE FILE:LINE FILE:LINE " */ + dstr items; + char* pitem = strcpy(items, exs); + d_print("Examples:\n"); + char* item; + for (item = strtok(pitem, " "); item; item = strtok(NULL, " ")) { + dstr buffer; + char* colon = strchr(item, ':'); + if (colon) { + char* filename = item; + char* line = colon + 1; + *colon = '\0'; + dstr base; + d_basename(filename, NULL, base); + d_printf("* [%s](%s)\n", + base, + example_source(buffer, filename, line)); + } + } + d_print(""); + } + strcpy(current_api, ""); + } +} + +/* Local Variables: */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/scan_examples.c b/allegro/docs/scripts/scan_examples.c new file mode 100644 index 00000000..e090ea13 --- /dev/null +++ b/allegro/docs/scripts/scan_examples.c @@ -0,0 +1,239 @@ +/* + * scan_examples OPTIONS EXAMPLE-FILES + * + * Load a prototypes file containing API elements + * and scan files for examples using those elements + * Output is to standard output and comprises lines + * of the form "API: FILE:LINE FILE:LINE FILE:LINE" + * No more than 3 examples will be output for each + * API. + * + * Options are: + * --protos PROTOS-FILE + * + * It is possible to use a response file to specify + * options or files. Including @FILENAME on the + * command line will read that file line-by-line + * and insert each line as if it were specified on + * the command line. This is to avoid very long + * command lines. + */ +#include +#include +#include +#include "dawk.h" + +#define SL_INITIAL_CAPACITY 64 +#define EXAMPLES_PER_API 3 + +static dstr protos; + +typedef struct { + char **items; + int count; + int capacity; +} slist_t; + +static void sl_init(slist_t *); +static void sl_free(slist_t *); +static void sl_clear(slist_t *); +static void sl_append(slist_t *, const char *); + +static void cleanup(void); +static void load_api_list(void); +static slist_t apis; + +static char **responsefile(int* pargc, char **argv); + + +/* Table of which APIs are in which examples */ +static int *table; +/* Lookup to index the best examples */ +typedef struct { + /* Index into table */ + int index; + /* How many APIs are used in each example */ + int count; +} lookup_t; +static lookup_t *lookup; +static int compare(const void *pa, const void *pb) { + return ((const lookup_t *) pa)->count - ((const lookup_t *) pb)->count; +} + +int main(int argc, char* argv[]) +{ + dstr line; + int i, j; + argv = responsefile(&argc, argv); + /* Handle --protos flag */ + if (argc >=3 && strcmp(argv[1], "--protos") == 0) { + strcpy(protos, argv[2]); + argc -= 2; + memmove(&argv[1], &argv[3], argc * sizeof(char*)); + } else { + strcpy(protos, "protos"); + } + d_cleanup = cleanup; + sl_init(&apis); + load_api_list(); + table = calloc(apis.count * argc, sizeof(int)); + + lookup = calloc(argc, sizeof(lookup_t)); + for (j = 0; j < argc; ++j) { + lookup[j].index = j; + } + + + for (j = 1; j < argc; ++j) { + d_open_input(argv[j]); + while (d_getline(line)) { + for (i = 0; i < apis.count; ++i) { + if (strstr(line, apis.items[i])) { + int *ptr = &table[i + j * apis.count]; + if (*ptr == 0) { + *ptr = d_line_num; + ++lookup[j].count; + } + } + } + } + d_close_input(); + } + /* Sort the files */ + qsort(lookup, argc, sizeof(lookup_t), compare); + /* Output the EXAMPLES_PER_API (three) 'best' examples. + * + * The 'best' is defined as the probability of having a usage of an API in + * the set of all other API usages in the example. Effectively, this means + * that examples with fewer other APIs showcased get selected. + */ + for (i = 0; i < apis.count; ++i) { + int found = 0; + for (j = 0; j < argc && found < EXAMPLES_PER_API; ++j) { + int index = lookup[j].index; + int line_num = table[i + index * apis.count]; + if (line_num != 0) { + if (found == 0) { + d_printf("%s: ", apis.items[i]); + } + ++found; + d_printf("%s:%d ", argv[index], line_num); + } + } + if (found > 0) { + d_print("\n"); + } + } + d_cleanup(); + return 0; +} + +void cleanup(void) +{ + free(table); + free(lookup); + sl_free(&apis); +} + +void sl_init(slist_t* s) +{ + s->items = NULL; + s->count = s->capacity = 0; +} + +void sl_append(slist_t *s, const char *item) +{ + if (s->count == s->capacity) { + int capacity = s->capacity == 0 ? SL_INITIAL_CAPACITY : (s->capacity * 2); + s->items = realloc(s->items, capacity * sizeof(char*)); + s->capacity = capacity; + } + s->items[s->count++] = strcpy(malloc(1+strlen(item)), item); +} + +void sl_free(slist_t *s) +{ + sl_clear(s); + free(s->items); + s->items = NULL; + s->capacity = 0; +} + +void sl_clear(slist_t *s) +{ + int i; + for (i = 0; i < s->count; ++i) { + free(s->items[i]); + } + s->count = 0; +} + +void load_api_list(void) +{ + dstr line; + d_open_input(protos); + while (d_getline(line)) { + int i; + bool found = false; + char *ptr = strchr(line, ':'); + if (ptr) { + *ptr = '\0'; + for (i = apis.count - 1; i >=0; --i) { + if (strcmp(line, apis.items[i]) == 0) { + found = true; + break; + } + } + } + if (!found) { + sl_append(&apis, line); + } + } + d_close_input(); +} + +/* Re-process the command line args by loading any response files */ +char **responsefile(int *pargc, char **argv) +{ + static slist_t args; + static char** new_argv; + int argc = *pargc; + int i; + bool found_at = false; + for (i = 1; i < argc; ++i) { + if (*argv[i] == '@') { + found_at = true; + break; + } + } + if (!found_at) { + /* Nothing to do */ + return argv; + } + sl_clear(&args); + for (i = 0; i < argc; ++i) { + if (*argv[i] == '@') { + d_open_input(argv[i] + 1); + dstr line; + while (d_getline(line)) { + sl_append(&args, line); + } + d_close_input(); + } else { + sl_append(&args, argv[i]); + } + } + /* Make a copy because code might alter the argv array */ + new_argv = realloc(new_argv, args.count * sizeof(char*)); + memcpy(new_argv, args.items, args.count * sizeof(char*)); + *pargc = args.count; + return new_argv; +} + + + +/* Local Variables: */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/docs/scripts/trex.c b/allegro/docs/scripts/trex.c new file mode 100644 index 00000000..0594b313 --- /dev/null +++ b/allegro/docs/scripts/trex.c @@ -0,0 +1,649 @@ +/* see copyright notice in trex.h */ +/* This copy contains minor changes by Allegro developers to prevent some + * compiler warnings. One change makes trex_compile non-reentrant. + */ +#include +#include +#include +#include +#include "trex.h" + +#ifdef _UINCODE +#define scisprint iswprint +#define scstrlen wcslen +#define scprintf wprintf +#define _SC(x) L(x) +#else +#define scisprint isprint +#define scstrlen strlen +#define scprintf printf +#define _SC(x) (x) +#endif + +#ifdef TREX_DEBUG +#include + +static const TRexChar *g_nnames[] = +{ + _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), + _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), + _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") +}; + +#endif +#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} +#define OP_OR (MAX_CHAR+2) +#define OP_EXPR (MAX_CHAR+3) //parentesis () +#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) +#define OP_DOT (MAX_CHAR+5) +#define OP_CLASS (MAX_CHAR+6) +#define OP_CCLASS (MAX_CHAR+7) +#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ +#define OP_RANGE (MAX_CHAR+9) +#define OP_CHAR (MAX_CHAR+10) +#define OP_EOL (MAX_CHAR+11) +#define OP_BOL (MAX_CHAR+12) +#define OP_WB (MAX_CHAR+13) + +#define TREX_SYMBOL_ANY_CHAR ('.') +#define TREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') +#define TREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') +#define TREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') +#define TREX_SYMBOL_BRANCH ('|') +#define TREX_SYMBOL_END_OF_STRING ('$') +#define TREX_SYMBOL_BEGINNING_OF_STRING ('^') +#define TREX_SYMBOL_ESCAPE_CHAR ('\\') + + +typedef int TRexNodeType; + +typedef struct tagTRexNode{ + TRexNodeType type; + int left; + int right; + int next; +}TRexNode; + +struct TRex{ + const TRexChar *_eol; + const TRexChar *_bol; + const TRexChar *_p; + int _first; + int _op; + TRexNode *_nodes; + int _nallocated; + int _nsize; + int _nsubexpr; + TRexMatch *_matches; + int _currsubexp; + void *_jmpbuf; + const TRexChar **_error; +}; + +static int trex_list(TRex *exp); + +static int trex_newnode(TRex *exp, TRexNodeType type) +{ + TRexNode n; + int newid; + n.type = type; + n.next = n.right = n.left = -1; + if(type == OP_EXPR) + n.right = exp->_nsubexpr++; + if(exp->_nallocated < (exp->_nsize + 1)) { + /* int oldsize = exp->_nallocated; */ + exp->_nallocated *= 2; + exp->_nodes = (TRexNode *)realloc(exp->_nodes, exp->_nallocated * sizeof(TRexNode)); + } + exp->_nodes[exp->_nsize++] = n; + newid = exp->_nsize - 1; + return (int)newid; +} + +static void trex_error(TRex *exp,const TRexChar *error) +{ + if(exp->_error) *exp->_error = error; + longjmp(*((jmp_buf*)exp->_jmpbuf),-1); +} + +static void trex_expect(TRex *exp, int n){ + if((*exp->_p) != n) + trex_error(exp, _SC("expected paren")); + exp->_p++; +} + +static TRexChar trex_escapechar(TRex *exp) +{ + if(*exp->_p == TREX_SYMBOL_ESCAPE_CHAR){ + exp->_p++; + switch(*exp->_p) { + case 'v': exp->_p++; return '\v'; + case 'n': exp->_p++; return '\n'; + case 't': exp->_p++; return '\t'; + case 'r': exp->_p++; return '\r'; + case 'f': exp->_p++; return '\f'; + default: return (*exp->_p++); + } + } else if(!scisprint(*exp->_p)) trex_error(exp,_SC("letter expected")); + return (*exp->_p++); +} + +static int trex_charclass(TRex *exp,int classid) +{ + int n = trex_newnode(exp,OP_CCLASS); + exp->_nodes[n].left = classid; + return n; +} + +static int trex_charnode(TRex *exp,TRexBool isclass) +{ + TRexChar t; + if(*exp->_p == TREX_SYMBOL_ESCAPE_CHAR) { + exp->_p++; + switch(*exp->_p) { + case 'n': exp->_p++; return trex_newnode(exp,'\n'); + case 't': exp->_p++; return trex_newnode(exp,'\t'); + case 'r': exp->_p++; return trex_newnode(exp,'\r'); + case 'f': exp->_p++; return trex_newnode(exp,'\f'); + case 'v': exp->_p++; return trex_newnode(exp,'\v'); + case 'a': case 'A': case 'w': case 'W': case 's': case 'S': + case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': + case 'p': case 'P': case 'l': case 'u': + { + t = *exp->_p; exp->_p++; + return trex_charclass(exp,t); + } + case 'b': + case 'B': + if(!isclass) { + int node = trex_newnode(exp,OP_WB); + exp->_nodes[node].left = *exp->_p; + exp->_p++; + return node; + } //else default + /* Intentional fallthrough */ + default: + t = *exp->_p; exp->_p++; + return trex_newnode(exp,t); + } + } + else if(!scisprint(*exp->_p)) { + + trex_error(exp,_SC("letter expected")); + } + t = *exp->_p; exp->_p++; + return trex_newnode(exp,t); +} +static int trex_class(TRex *exp) +{ + int ret = -1; + int first = -1,chain; + if(*exp->_p == TREX_SYMBOL_BEGINNING_OF_STRING){ + ret = trex_newnode(exp,OP_NCLASS); + exp->_p++; + }else ret = trex_newnode(exp,OP_CLASS); + + if(*exp->_p == ']') trex_error(exp,_SC("empty class")); + chain = ret; + while(*exp->_p != ']' && exp->_p != exp->_eol) { + if(*exp->_p == '-' && first != -1){ + int r,t; + if(*exp->_p++ == ']') trex_error(exp,_SC("unfinished range")); + r = trex_newnode(exp,OP_RANGE); + if(first>*exp->_p) trex_error(exp,_SC("invalid range")); + if(exp->_nodes[first].type == OP_CCLASS) trex_error(exp,_SC("cannot use character classes in ranges")); + exp->_nodes[r].left = exp->_nodes[first].type; + t = trex_escapechar(exp); + exp->_nodes[r].right = t; + exp->_nodes[chain].next = r; + chain = r; + first = -1; + } + else{ + if(first!=-1){ + int c = first; + exp->_nodes[chain].next = c; + chain = c; + first = trex_charnode(exp,TRex_True); + } + else{ + first = trex_charnode(exp,TRex_True); + } + } + } + if(first!=-1){ + int c = first; + exp->_nodes[chain].next = c; + chain = c; + first = -1; + } + /* hack? */ + exp->_nodes[ret].left = exp->_nodes[ret].next; + exp->_nodes[ret].next = -1; + return ret; +} + +static int trex_parsenumber(TRex *exp) +{ + int ret = *exp->_p-'0'; + int positions = 10; + exp->_p++; + while(isdigit(*exp->_p)) { + ret = ret*10+(*exp->_p++-'0'); + if(positions==1000000000) trex_error(exp,_SC("overflow in numeric constant")); + positions *= 10; + }; + return ret; +} + +static int trex_element(TRex *exp) +{ + int ret = -1; + switch(*exp->_p) + { + case '(': { + int expr,newn; + exp->_p++; + + + if(*exp->_p =='?') { + exp->_p++; + trex_expect(exp,':'); + expr = trex_newnode(exp,OP_NOCAPEXPR); + } + else + expr = trex_newnode(exp,OP_EXPR); + newn = trex_list(exp); + exp->_nodes[expr].left = newn; + ret = expr; + trex_expect(exp,')'); + } + break; + case '[': + exp->_p++; + ret = trex_class(exp); + trex_expect(exp,']'); + break; + case TREX_SYMBOL_END_OF_STRING: exp->_p++; ret = trex_newnode(exp,OP_EOL);break; + case TREX_SYMBOL_ANY_CHAR: exp->_p++; ret = trex_newnode(exp,OP_DOT);break; + default: + ret = trex_charnode(exp,TRex_False); + break; + } + + { + TRexBool isgreedy = TRex_False; + unsigned short p0 = 0, p1 = 0; + switch(*exp->_p){ + case TREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = TRex_True; break; + case TREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = TRex_True; break; + case TREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = TRex_True; break; + case '{': + exp->_p++; + if(!isdigit(*exp->_p)) trex_error(exp,_SC("number expected")); + p0 = (unsigned short)trex_parsenumber(exp); + /*******************************/ + switch(*exp->_p) { + case '}': + p1 = p0; exp->_p++; + break; + case ',': + exp->_p++; + p1 = 0xFFFF; + if(isdigit(*exp->_p)){ + p1 = (unsigned short)trex_parsenumber(exp); + } + trex_expect(exp,'}'); + break; + default: + trex_error(exp,_SC(", or } expected")); + } + /*******************************/ + isgreedy = TRex_True; + break; + + } + if(isgreedy) { + int nnode = trex_newnode(exp,OP_GREEDY); + exp->_nodes[nnode].left = ret; + exp->_nodes[nnode].right = ((p0)<<16)|p1; + ret = nnode; + } + } + if((*exp->_p != TREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != TREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != TREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { + int nnode = trex_element(exp); + exp->_nodes[ret].next = nnode; + } + + return ret; +} + +static int trex_list(TRex *exp) +{ + int ret=-1,e; + if(*exp->_p == TREX_SYMBOL_BEGINNING_OF_STRING) { + exp->_p++; + ret = trex_newnode(exp,OP_BOL); + } + e = trex_element(exp); + if(ret != -1) { + exp->_nodes[ret].next = e; + } + else ret = e; + + if(*exp->_p == TREX_SYMBOL_BRANCH) { + int temp,tright; + exp->_p++; + temp = trex_newnode(exp,OP_OR); + exp->_nodes[temp].left = ret; + tright = trex_list(exp); + exp->_nodes[temp].right = tright; + ret = temp; + } + return ret; +} + +static TRexBool trex_matchcclass(int cclass,TRexChar c) +{ + switch(cclass) { + case 'a': return isalpha(c)?TRex_True:TRex_False; + case 'A': return !isalpha(c)?TRex_True:TRex_False; + case 'w': return (isalnum(c) || c == '_')?TRex_True:TRex_False; + case 'W': return (!isalnum(c) && c != '_')?TRex_True:TRex_False; + case 's': return isspace(c)?TRex_True:TRex_False; + case 'S': return !isspace(c)?TRex_True:TRex_False; + case 'd': return isdigit(c)?TRex_True:TRex_False; + case 'D': return !isdigit(c)?TRex_True:TRex_False; + case 'x': return isxdigit(c)?TRex_True:TRex_False; + case 'X': return !isxdigit(c)?TRex_True:TRex_False; + case 'c': return iscntrl(c)?TRex_True:TRex_False; + case 'C': return !iscntrl(c)?TRex_True:TRex_False; + case 'p': return ispunct(c)?TRex_True:TRex_False; + case 'P': return !ispunct(c)?TRex_True:TRex_False; + case 'l': return islower(c)?TRex_True:TRex_False; + case 'u': return isupper(c)?TRex_True:TRex_False; + } + return TRex_False; /*cannot happen*/ +} + +static TRexBool trex_matchclass(TRex* exp,TRexNode *node,TRexChar c) +{ + do { + switch(node->type) { + case OP_RANGE: + if(c >= node->left && c <= node->right) return TRex_True; + break; + case OP_CCLASS: + if(trex_matchcclass(node->left,c)) return TRex_True; + break; + default: + if(c == node->type)return TRex_True; + } + } while((node->next != -1) && (node = &exp->_nodes[node->next])); + return TRex_False; +} + +static const TRexChar *trex_matchnode(TRex* exp,TRexNode *node,const TRexChar *str,TRexNode *next) +{ + + TRexNodeType type = node->type; + switch(type) { + case OP_GREEDY: { + //TRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; + TRexNode *greedystop = NULL; + int p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; + const TRexChar *s=str, *good = str; + + if(node->next != -1) { + greedystop = &exp->_nodes[node->next]; + } + else { + greedystop = next; + } + + while((nmaches == 0xFFFF || nmaches < p1)) { + + const TRexChar *stop; + if(!(s = trex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) + break; + nmaches++; + good=s; + if(greedystop) { + //checks that 0 matches satisfy the expression(if so skips) + //if not would always stop(for instance if is a '?') + if(greedystop->type != OP_GREEDY || + (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) + { + TRexNode *gnext = NULL; + if(greedystop->next != -1) { + gnext = &exp->_nodes[greedystop->next]; + }else if(next && next->next != -1){ + gnext = &exp->_nodes[next->next]; + } + stop = trex_matchnode(exp,greedystop,s,gnext); + if(stop) { + //if satisfied stop it + if(p0 == p1 && p0 == nmaches) break; + else if(nmaches >= p0 && p1 == 0xFFFF) break; + else if(nmaches >= p0 && nmaches <= p1) break; + } + } + } + + if(s >= exp->_eol) + break; + } + if(p0 == p1 && p0 == nmaches) return good; + else if(nmaches >= p0 && p1 == 0xFFFF) return good; + else if(nmaches >= p0 && nmaches <= p1) return good; + return NULL; + } + case OP_OR: { + const TRexChar *asd = str; + TRexNode *temp=&exp->_nodes[node->left]; + while( (asd = trex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + asd = str; + temp = &exp->_nodes[node->right]; + while( (asd = trex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + return NULL; + break; + } + case OP_EXPR: + case OP_NOCAPEXPR:{ + TRexNode *n = &exp->_nodes[node->left]; + const TRexChar *cur = str; + int capture = -1; + if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { + capture = exp->_currsubexp; + exp->_matches[capture].begin = cur; + exp->_currsubexp++; + } + + do { + TRexNode *subnext = NULL; + if(n->next != -1) { + subnext = &exp->_nodes[n->next]; + }else { + subnext = next; + } + if(!(cur = trex_matchnode(exp,n,cur,subnext))) { + if(capture != -1){ + exp->_matches[capture].begin = 0; + exp->_matches[capture].len = 0; + } + return NULL; + } + } while((n->next != -1) && (n = &exp->_nodes[n->next])); + + if(capture != -1) + exp->_matches[capture].len = cur - exp->_matches[capture].begin; + return cur; + } + case OP_WB: + if((str == exp->_bol && !isspace(*str)) + || (str == exp->_eol && !isspace(*(str-1))) + || (!isspace(*str) && isspace(*(str+1))) + || (isspace(*str) && !isspace(*(str+1))) ) { + return (node->left == 'b')?str:NULL; + } + return (node->left == 'b')?NULL:str; + case OP_BOL: + if(str == exp->_bol) return str; + return NULL; + case OP_EOL: + if(str == exp->_eol) return str; + return NULL; + case OP_DOT:{ + str++; + } + return str; + case OP_NCLASS: + case OP_CLASS: + if(trex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?TRex_True:TRex_False):(type == OP_NCLASS?TRex_True:TRex_False)) { + str++; + return str; + } + return NULL; + case OP_CCLASS: + if(trex_matchcclass(node->left,*str)) { + str++; + return str; + } + return NULL; + default: /* char */ + if(*str != node->type) return NULL; + str++; + return str; + } + return NULL; +} + +/* public api */ +TRex *trex_compile(const TRexChar *pattern,const TRexChar **error) +{ + /* Prevent warnings about variables being lost across setjmp. Of course + * this makes the code non-reentrant but make_doc doesn't mind. --pw + */ + static TRex *exp; + exp = (TRex *)malloc(sizeof(TRex)); + exp->_eol = exp->_bol = NULL; + exp->_p = pattern; + exp->_nallocated = (int)scstrlen(pattern) * sizeof(TRexChar); + exp->_nodes = (TRexNode *)malloc(exp->_nallocated * sizeof(TRexNode)); + exp->_nsize = 0; + exp->_matches = 0; + exp->_nsubexpr = 0; + exp->_first = trex_newnode(exp,OP_EXPR); + exp->_error = error; + exp->_jmpbuf = malloc(sizeof(jmp_buf)); + if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { + int res = trex_list(exp); + exp->_nodes[exp->_first].left = res; + if(*exp->_p!='\0') + trex_error(exp,_SC("unexpected character")); +#ifdef TREX_DEBUG + { + int nsize,i; + TRexNode *t; + nsize = exp->_nsize; + t = &exp->_nodes[0]; + scprintf(_SC("\n")); + for(i = 0;i < nsize; i++) { + if(exp->_nodes[i].type>MAX_CHAR) + scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); + else + scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); + scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); + } + scprintf(_SC("\n")); + } +#endif + exp->_matches = (TRexMatch *) malloc(exp->_nsubexpr * sizeof(TRexMatch)); + memset(exp->_matches,0,exp->_nsubexpr * sizeof(TRexMatch)); + } + else{ + trex_free(exp); + return NULL; + } + return exp; +} + +void trex_free(TRex *exp) +{ + if(exp) { + if(exp->_nodes) free(exp->_nodes); + if(exp->_jmpbuf) free(exp->_jmpbuf); + if(exp->_matches) free(exp->_matches); + free(exp); + } +} + +TRexBool trex_match(TRex* exp,const TRexChar* text) +{ + const TRexChar* res = NULL; + exp->_bol = text; + exp->_eol = text + scstrlen(text); + exp->_currsubexp = 0; + res = trex_matchnode(exp,exp->_nodes,text,NULL); + if(res == NULL || res != exp->_eol) + return TRex_False; + return TRex_True; +} + +TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end) +{ + const TRexChar *cur = NULL; + int node = exp->_first; + if(text_begin >= text_end) return TRex_False; + exp->_bol = text_begin; + exp->_eol = text_end; + do { + cur = text_begin; + while(node != -1) { + exp->_currsubexp = 0; + cur = trex_matchnode(exp,&exp->_nodes[node],cur,NULL); + if(!cur) + break; + node = exp->_nodes[node].next; + } + text_begin++; + } while(cur == NULL && text_begin != text_end); + + if(cur == NULL) + return TRex_False; + + --text_begin; + + if(out_begin) *out_begin = text_begin; + if(out_end) *out_end = cur; + return TRex_True; +} + +TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end) +{ + return trex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); +} + +int trex_getsubexpcount(TRex* exp) +{ + return exp->_nsubexpr; +} + +TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp) +{ + if( n<0 || n >= exp->_nsubexpr) return TRex_False; + *subexp = exp->_matches[n]; + return TRex_True; +} + diff --git a/allegro/docs/scripts/trex.h b/allegro/docs/scripts/trex.h new file mode 100644 index 00000000..12d419de --- /dev/null +++ b/allegro/docs/scripts/trex.h @@ -0,0 +1,67 @@ +#ifndef _TREX_H_ +#define _TREX_H_ +/*************************************************************** + T-Rex a tiny regular expression library + + Copyright (C) 2003-2006 Alberto Demichelis + + This software is provided 'as-is', without any express + or implied warranty. In no event will the authors be held + liable for any damages arising from the use of this software. + + Permission is granted to anyone to use this software for + any purpose, including commercial applications, and to alter + it and redistribute it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but + is not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any + source distribution. + +****************************************************************/ + +#ifdef _UNICODE +#define TRexChar unsigned short +#define MAX_CHAR 0xFFFF +#define _TREXC(c) L##c +#define trex_strlen wcslen +#define trex_printf wprintf +#else +#define TRexChar char +#define MAX_CHAR 0xFF +#define _TREXC(c) (c) +#define trex_strlen strlen +#define trex_printf printf +#endif + +#ifndef TREX_API +#define TREX_API extern +#endif + +#define TRex_True 1 +#define TRex_False 0 + +typedef unsigned int TRexBool; +typedef struct TRex TRex; + +typedef struct { + const TRexChar *begin; + int len; +} TRexMatch; + +TREX_API TRex *trex_compile(const TRexChar *pattern,const TRexChar **error); +TREX_API void trex_free(TRex *exp); +TREX_API TRexBool trex_match(TRex* exp,const TRexChar* text); +TREX_API TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end); +TREX_API TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end); +TREX_API int trex_getsubexpcount(TRex* exp); +TREX_API TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp); + +#endif diff --git a/allegro/docs/scripts/trex.txt b/allegro/docs/scripts/trex.txt new file mode 100644 index 00000000..65ee00fe --- /dev/null +++ b/allegro/docs/scripts/trex.txt @@ -0,0 +1,171 @@ +T-REX 1.3 http://tiny-rex.sourceforge.net +---------------------------------------------------------------------- + T-Rex a tiny regular expression library + + Copyright (C) 2003-2006 Alberto Demichelis + + This software is provided 'as-is', without any express + or implied warranty. In no event will the authors be held + liable for any damages arising from the use of this software. + + Permission is granted to anyone to use this software for + any purpose, including commercial applications, and to alter + it and redistribute it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but + is not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any + source distribution. + +---------------------------------------------------------------------- +TRex implements the following expressions + +\ Quote the next metacharacter +^ Match the beginning of the string +. Match any character +$ Match the end of the string +| Alternation +() Grouping (creates a capture) +[] Character class + +==GREEDY CLOSURES== +* Match 0 or more times ++ Match 1 or more times +? Match 1 or 0 times +{n} Match exactly n times +{n,} Match at least n times +{n,m} Match at least n but not more than m times + +==ESCAPE CHARACTERS== +\t tab (HT, TAB) +\n newline (LF, NL) +\r return (CR) +\f form feed (FF) + +==PREDEFINED CLASSES== +\l lowercase next char +\u uppercase next char +\a letters +\A non letters +\w alphanimeric [0-9a-zA-Z] +\W non alphanimeric +\s space +\S non space +\d digits +\D non nondigits +\x exadecimal digits +\X non exadecimal digits +\c control charactrs +\C non control charactrs +\p punctation +\P non punctation +\b word boundary +\B non word boundary + +---------------------------------------------------------------------- +API DOC +---------------------------------------------------------------------- +TRex *trex_compile(const TRexChar *pattern,const TRexChar **error); + +compiles an expression and returns a pointer to the compiled version. +in case of failure returns NULL.The returned object has to be deleted +through the function trex_free(). + +pattern + a pointer to a zero terminated string containing the pattern that + has to be compiled. +error + apointer to a string pointer that will be set with an error string + in case of failure. + +---------------------------------------------------------------------- +void trex_free(TRex *exp) + +deletes a expression structure created with trex_compile() + +exp + the expression structure that has to be deleted + +---------------------------------------------------------------------- +TRexBool trex_match(TRex* exp,const TRexChar* text) + +returns TRex_True if the string specified in the parameter text is an +exact match of the expression, otherwise returns TRex_False. + +exp + the compiled expression +text + the string that has to be tested + +---------------------------------------------------------------------- +TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end) + +searches the first match of the expressin in the string specified in the parameter text. +if the match is found returns TRex_True and the sets out_begin to the beginning of the +match and out_end at the end of the match; otherwise returns TRex_False. + +exp + the compiled expression +text + the string that has to be tested +out_begin + a pointer to a string pointer that will be set with the beginning of the match +out_end + a pointer to a string pointer that will be set with the end of the match + +---------------------------------------------------------------------- +TREX_API TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end) + +searches the first match of the expressin in the string delimited +by the parameter text_begin and text_end. +if the match is found returns TRex_True and the sets out_begin to the beginning of the +match and out_end at the end of the match; otherwise returns TRex_False. + +exp + the compiled expression +text_begin + a pointer to the beginnning of the string that has to be tested +text_end + a pointer to the end of the string that has to be tested +out_begin + a pointer to a string pointer that will be set with the beginning of the match +out_end + a pointer to a string pointer that will be set with the end of the match + +---------------------------------------------------------------------- +int trex_getsubexpcount(TRex* exp) + +returns the number of sub expressions matched by the expression + +exp + the compiled expression + +--------------------------------------------------------------------- +TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *submatch) + +retrieve the begin and and pointer to the length of the sub expression indexed +by n. The result is passed trhough the struct TRexMatch: + +typedef struct { + const TRexChar *begin; + int len; +} TRexMatch; + +the function returns TRex_True if n is valid index otherwise TRex_False. + +exp + the compiled expression +n + the index of the submatch +submatch + a pointer to structure that will store the result + +this function works also after a match operation has been performend. + diff --git a/allegro/docs/src/autosuggest.js b/allegro/docs/src/autosuggest.js new file mode 100644 index 00000000..97f84491 --- /dev/null +++ b/allegro/docs/src/autosuggest.js @@ -0,0 +1,1623 @@ +/* Auto-suggest control, modified for Allegro's purposes. + * + * The original copyright notice follows: + * + * Auto-suggest control, version 2.4, October 10th 2009. + * + * (c) 2007-2009 Dmitriy Khudorozhkov (dmitrykhudorozhkov@yahoo.com) + * + * Latest version download and documentation: + * http://www.codeproject.com/KB/scripting/AutoSuggestControl.aspx + * + * Based on "Auto-complete Control" by zichun: + * http://www.codeproject.com/KB/scripting/jsactb.aspx + * + * This software is provided "as-is", without any express or implied warranty. + * In no event will the author be held liable for any damages arising from the + * use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +var autosuggest_url = ""; // Global link to the server-side script, that gives you the suggestion list. + // Used for controls that do not define their own server script urls. + +function autosuggest(id, array, url, onSelect) +{ + var field = document.getElementById(id); + var exists = field.autosuggest; + + if(exists) return exists; + + // "Public" variables: + + this.time_out = 0; // autocomplete timeout, in milliseconds (0: autocomplete never times out) + this.response_time = 250; // time, in milliseconds, between the last char typed and the actual query + this.entry_limit = 10; // number of entries autocomplete will show at a time + + this.limit_start = false; // should the auto complete be limited to the beginning of keyword? + this.match_first = true; // if previous is false, should the exact matches be displayed first? + this.restrict_typing = false; // restrict to existing members of array + this.full_refresh = false; // should the script re-send the AJAX request after each typed character? + + this.use_iframe = true; // should the control use an IFrame element to fix suggestion list positioning (MS IE only)? + this.use_scroll = true; // should the control use a scroll bar (true) or a up/down arrow-buttons (false)? + this.use_mouse = true; // enable mouse support + this.no_default = false; // should the control omit selecting the 1st item in a suggestion list? + this.start_check = 0; // show widget only after this number of characters is typed in (effective if >1) + + this.text_delimiter = [";", ","]; // delimiter for multiple autocomplete entries. Set it to empty array ( [] ) for single autocomplete. + this.ajax_delimiter = "|"; // character that delimits entries in the string returned by AJAX call + this.item_delimiter = ","; // character that delimits key and value for the suggestion item in the string returned by AJAX call + + this.selectedIndex = -1; // index (zero-based) of the entry last selected + + this.min_results = 5; // minimum number of results to return + + // "Private" variables: + + this.suggest_url = url || (array ? "" : autosuggest_url); // URL the server-side script that gives you the suggestion list + this.msie = (document.all && !window.opera); + + this.displayed = false; + + this.delim_words = []; + this.current_word = 0; + this.delim_char = []; + + this.current = 0; + this.total = 0; + this.range_up = 0; + this.range_down = 0; + + this.previous = 0; + this.timer = 0; + this.rebuild = false; + this.evsetup = false; + + this.bool = []; + this.rows = []; + + this.onSelect = onSelect || null; + + this.cur_x = 0; + this.cur_y = 0; + this.cur_w = 0; + this.cur_h = 0; + + this.mouse_x = 0; + this.mouse_y = 0; + + this.mouse_on_list = 0; + this.caret_moved = false; + + this.field_id = id; + this.field = field; + this.lastterm = field.value; + + this.keywords = [], this.keywords_init = []; + this.values = [], this.values_init = []; + + return this.construct(array || []); +}; + +autosuggest.prototype = { + + construct: function(array) + { + function callLater(func, obj, param1, param2) { return function() { func.call(obj, param1 || null, param2 || null) }; } + + this.field.autosuggest = this; + + // Initialize the control from JS array, if any: + + this.bindArray(array); + + // Create event handlers: + + this.funcClick = this.mouseClick; + this.funcCheck = this.checkKey; + this.funcPress = this.keyPress; + + this.funcHighlight = this.highlightTable; + + this.funcClear = callLater(this.clearEvents, this); + + this.funcUp = callLater(this.scroll, this, true, 1); + this.funcDown = callLater(this.scroll, this, false, 1); + + this.funcFocus = callLater(this.focusTable, this); + this.funcUnfocus = callLater(this.unfocusTable, this); + + this.addEvent(this.field, "focus", callLater(this.setupEvents, this)); + this.addEvent(window, "resize", callLater(this.reposition, this)); + + var obj = this; + this.addEvent(document, "keypress", function(event) { obj.funcShortcut(obj, event); }); + this.addEvent(document, "keydown", function(event) { obj.funcShortcut(obj, event); }); + + return this; + }, + + funcShortcut: function(obj, event) + { + event = event || window.event; + + var s; + if("key" in event && typeof event.key != "undefined") + { + s = event.key; + } + else + { + var c = event.charCode || event.keyCode; + if(c == 27) + { + s = "Escape"; + } + else + { + s = String.fromCharCode(c); + } + } + switch(s) + { + case "Escape": + obj.field.blur(); + break; + case "s": + case "S": + if(!this.evsetup) + { + event.preventDefault(); + obj.field.focus(); + break; + } + } + }, + + bindArray: function(array) + { + if(!array || !array.length) return; + + this.suggest_url = ""; + + this.keywords = [], this.keywords_init = []; + this.values = [], this.values_init = []; + + for(var i = 0, cl = array.length; i < cl; i++) + { + var item = array[i]; + + if(item.constructor == Array) + { + this.keywords[i] = this.keywords_init[i] = item[0]; + this.values[i] = this.values_init[i] = item[1]; + } + else + { + this.keywords[i] = this.keywords_init[i] = item; + this.values[i] = this.values_init[i] = ""; + } + } + }, + + bindURL: function(url) + { + if(!url) + url = autosuggest_url; + + this.suggest_url = url; + }, + + setupEvents: function() + { + if(!this.evsetup) + { + this.evsetup = true; + + this.addEvent(document, "keydown", this.funcCheck); + this.addEvent(this.field, "blur", this.funcClear); + this.addEvent(document, "keypress", this.funcPress); + } + }, + + clearEvents: function() + { + // Removes an event handler: + function removeEvent(obj, event_name, func_ref) + { + if(obj.removeEventListener && !window.opera) + { + obj.removeEventListener(event_name, func_ref, true); + } + else if(obj.detachEvent) + { + obj.detachEvent("on" + event_name, func_ref); + } + else + { + obj["on" + event_name] = null; + } + } + + var event = window.event; + + if(event && this.cur_h) + { + var elem = event.srcElement || event.target; + + var x = this.mouse_x + (document.documentElement.scrollLeft || document.body.scrollLeft || 0); + var y = this.mouse_y + (document.documentElement.scrollTop || document.body.scrollTop || 0); + + if((elem.id == this.field_id) && (x > this.cur_x && x < (this.cur_x + this.cur_w)) && (y > this.cur_y && y < (this.cur_y + this.cur_h))) + { + this.field.focus(); + return; + } + } + + removeEvent(document, "keydown", this.funcCheck); + removeEvent(this.field, "blur", this.funcClear); + removeEvent(document, "keypress", this.funcPress); + + this.hide(); + this.evsetup = false; + }, + + parse: function(n, plen, re) + { + if(!n || !n.length) return ""; + if(!plen) return n; + + var tobuild = [], c = 0, p = n.search(re); + + // No match found because we're serving approximate results + if(p < 0) + { + tobuild[c++] = n; + } + else + { + tobuild[c++] = n.substr(0, p); + tobuild[c++] = ""; + tobuild[c++] = n.substring(p, plen + p); + tobuild[c++] = ""; + tobuild[c++] = n.substring(plen + p, n.length); + } + + return tobuild.join(""); + }, + + build: function() + { + if(this.total == 0) + { + this.displayed = false; + return; + } + + this.rows = []; + this.current = this.no_default ? -1 : 0; + + var that = this; + + this.addEvent(document, "mousemove", function(event) + { + event = event || window.event; + + that.mouse_x = event.x; + that.mouse_y = event.y; + }); + + var body = document.getElementById("suggest_table_" + this.field_id); + if(body) + { + this.displayed = false; + document.body.removeChild(body); + + var helper = document.getElementById("suggest_helper_" + this.field_id); + if(helper) + document.body.removeChild(helper); + } + + var bb = document.createElement("div"); + bb.id = "suggest_table_" + this.field_id; + bb.className = "autosuggest-body"; + + this.cur_y = this.curPos(this.field, "Top") + this.field.offsetHeight; + bb.style.top = this.cur_y + "px"; + + this.cur_x = this.curPos(this.field, "Left"); + bb.style.left = this.cur_x + "px"; + + this.cur_w = this.field.offsetWidth - (this.msie ? 2 : 6); + bb.style.width = this.cur_w + "px"; + + this.cur_h = 1; + bb.style.height = "1px"; + + var cc = null; + if(this.msie && this.use_iframe) + { + var cc = document.createElement("iframe"); + cc.id = "suggest_helper_" + this.field_id; + + cc.src = "javascript:\"\";"; + cc.scrolling = "no"; + cc.frameBorder = "no"; + } + + var that = this; + var showFull = (this.total > this.entry_limit); + + if(cc) + { + document.body.appendChild(cc); + + cc.style.top = this.cur_y + "px"; + cc.style.left = this.cur_x + "px"; + + cc.style.width = bb.offsetWidth + 2; + } + + document.body.appendChild(bb); + + var first = true, dispCount = showFull ? this.entry_limit : this.total; + var str = [], cn = 0; + + // cellspacing and cellpadding were not moved to css - IE doesn't understand border-spacing. + str[cn++] = "
"; + + bb.innerHTML = str.join(""); + var table = bb.firstChild; + + if(this.use_mouse) + { + table.onmouseout = this.funcUnfocus; + table.onmouseover = this.funcFocus; + } + + var real_height = 0, real_width = 0; + + function createArrowRow(dir) + { + var row = table.insertRow(-1); + row.className = dir ? "up" : "down"; + + var cell = row.insertCell(0); + real_height += cell.offsetHeight + 1; + + return cell; + } + + if(!this.use_scroll && showFull) + createArrowRow(true).parentNode.className = "up-disabled"; + + var kl = this.keywords.length, counter = 0, j = 0; + + // For "parse" call: + var t, plen; + if(this.text_delimiter.length > 0) + { + var word = this.delim_words[this.current_word]; + + t = this.trim(this.addSlashes(word)); + plen = this.trim(word).length; + } + else + { + var word = this.field.value; + + t = this.addSlashes(word); + plen = word.length; + } + + var re = new RegExp((this.limit_start ? "^" : "") + t, "i"); + + function addSuggestion(index, _first) + { + var row = that.rows[j] = table.insertRow(-1); + row.className = (_first || (that.previous == index)) ? "selected" : ""; + + var cell = row.insertCell(0); + cell.innerHTML = that.parse(that.keywords[index], plen, re); + cell.setAttribute("pos", j++); + cell.autosuggest = that; + + if(that.use_mouse) + { + that.addEvent(cell, "click", that.funcClick); + cell.onmouseover = that.funcHighlight; + } + + return [row.offsetWidth, row.offsetHeight]; + } + + for(var i = 0; i < kl; i++) + { + if(this.bool[i]) + { + var dim = addSuggestion(i, (first && !this.no_default && !this.rebuild)); + first = false; + + if(counter <= this.entry_limit) + real_height += dim[1] + 1; + + if(real_width < dim[0]) + real_width = dim[0]; + + if(++counter == this.entry_limit) + { + ++i; + break; + } + } + } + + var last = i; + + if(showFull) + { + if(!this.use_scroll) + { + var cell = createArrowRow(false); + + if(this.use_mouse) + this.addEvent(cell, "click", this.funcDown); + } + else + { + bb.style.height = real_height + "px"; + bb.style.overflow = "auto"; + bb.style.overflowX = "hidden"; + } + } + + this.cur_h = real_height + 1; + bb.style.height = this.cur_h + "px"; + + this.cur_w = ((real_width > bb.offsetWidth) ? real_width : bb.offsetWidth) + (this.msie ? -2 : 2) + 100; + bb.style.width = this.cur_w + "px"; + + if(cc) + { + cc.style.height = this.cur_h + "px"; + cc.style.width = this.cur_w + "px"; + } + + this.range_up = 0; + this.range_down = j - 1; + this.displayed = true; + + if(this.use_scroll) + { + setTimeout(function() + { + counter = 0; + + for(var i = last; i < kl; i++) + { + if(!that.displayed) return; + + if(that.bool[i]) + { + addSuggestion(i); + + if(++counter == that.entry_limit) + { + ++i; + break; + } + } + } + + last = i; + + if(j < that.total) setTimeout(arguments.callee, 25); + }, + 25); + } + }, + + remake: function() + { + this.rows = []; + + var a = document.getElementById("suggest_table2_" + this.field_id); + var k = 0, first = true; + + function adjustArrow(obj, which, cond, handler) + { + var r = a.rows[k++]; + r.className = which ? (cond ? "up" : "up-disabled") : (cond ? "down" : "down-disabled"); + + var c = r.firstChild; + + if(cond && handler && obj.use_mouse) + obj.addEvent(c, "click", handler); + } + + if(this.total > this.entry_limit) + { + var b = (this.range_up > 0); + adjustArrow(this, true, b, this.funcUp); + } + + // For "parse" call: + var t, plen; + if(this.text_delimiter.length > 0) + { + var word = this.delim_words[this.current_word]; + + t = this.trim(this.addSlashes(word)); + plen = this.trim(word).length; + } + else + { + var word = this.field.value; + + t = this.addSlashes(word); + plen = word.length; + } + + var re = new RegExp((this.limit_start ? "^" : "") + t, "i"); + var kl = this.keywords.length, j = 0; + + for(var i = 0; i < kl; i++) + { + if(this.bool[i]) + { + if((j >= this.range_up) && (j <= this.range_down)) + { + var r = this.rows[j] = a.rows[k++]; + r.className = ""; + + var c = r.firstChild; + c.innerHTML = this.parse(this.keywords[i], plen, re); + c.setAttribute("pos", j); + } + + if(++j > this.range_down) break; + } + } + + if(kl > this.entry_limit) + { + var b = (j < this.total); + adjustArrow(this, false, b, this.funcDown); + } + + if(this.msie) + { + var helper = document.getElementById("suggest_helper_" + this.field_id); + if(helper) helper.style.width = a.parentNode.offsetWidth + 2; + } + }, + + reposition: function() + { + if(this.displayed) + { + this.cur_y = this.curPos(this.field, "Top") + this.field.offsetHeight; + this.cur_x = this.curPos(this.field, "Left"); + + var control = document.getElementById("suggest_table_" + this.field_id); + control.style.top = this.cur_y + "px"; + control.style.left = this.cur_x + "px"; + } + }, + + startTimer: function(on_list) + { + if(this.time_out > 0) + this.timer = setTimeout(function() { this.mouse_on_list = on_list; this.hide(); }, this.time_out); + }, + + stopTimer: function() + { + if(this.timer) + { + clearTimeout(this.timer); + this.timer = 0; + } + }, + + getRow: function(index) + { + if(typeof(index) == "undefined") index = this.current; + + return (this.rows[index] || null); + }, + + fixArrows: function(base) + { + if(this.total <= this.entry_limit) return; + + var table = base.firstChild, at_start = (this.current == 0), at_end = (this.current == (this.total - 1)); + + var row = table.rows[0]; + row.className = at_start ? "up-disabled" : "up"; + + row = table.rows[this.entry_limit + 1]; + row.className = at_end ? "down-disabled" : "down"; + }, + + scroll: function(direction, times) + { + if(!this.displayed) return; + + this.field.focus(); + if(this.current == (direction ? 0 : (this.total - 1))) return; + + if(!direction && (this.current < 0)) + { + this.current = -1; + } + else + { + var t = this.getRow(); + + if(t && t.style) + t.className = ""; + } + + this.current += times * (direction ? -1 : 1); + if(direction) + { + if(this.current < 0) + this.current = 0; + } + else + { + if(this.current >= this.total) + this.current = this.total - 1; + + if(this.use_scroll && (this.current >= this.rows.length)) + this.current = this.rows.length - 1; + } + + var t = this.getRow(), base = document.getElementById("suggest_table_" + this.field_id); + + if(this.use_scroll) + { + if(direction) + { + if(t.offsetTop < base.scrollTop) + base.scrollTop = t.offsetTop; + } + else + { + if((t.offsetTop + t.offsetHeight) > (base.scrollTop + base.offsetHeight)) + { + var ndx = this.current - this.entry_limit + 1; + if(ndx > 0) + base.scrollTop = this.getRow(ndx).offsetTop; + } + } + } + else + { + if(direction) + { + if(this.current < this.range_up) + { + this.range_up -= times; + if(this.range_up < 0) this.range_up = 0; + + this.range_down = this.range_up + this.entry_limit - 1; + + this.remake(); + } + else this.fixArrows(base); + } + else + { + if(this.current > this.range_down) + { + this.range_down += times; + if(this.range_down > (this.total - 1)) this.range_down = this.total - 1; + + this.range_up = this.range_down - this.entry_limit + 1; + + this.remake(); + } + else this.fixArrows(base); + } + + t = this.getRow(); + } + + if(t && t.style) + t.className = "selected"; + + this.stopTimer(); + this.startTimer(1); + + this.field.focus(); + }, + + mouseClick: function(event) + { + event = event || window.event; + var elem = event.srcElement || event.target; + + if(!elem.id) elem = elem.parentNode; + + var obj = elem.autosuggest; + + if(!obj) + { + var tag = elem.tagName.toLowerCase(); + elem = (tag == "tr") ? elem.firstChild : elem.parentNode; + + obj = elem.autosuggest; + } + + if(!obj || !obj.displayed) return; + + obj.mouse_on_list = 0; + obj.current = parseInt(elem.getAttribute("pos"), 10); + obj.choose(); + }, + + focusTable: function() + { + this.mouse_on_list = 1; + }, + + unfocusTable: function() + { + this.mouse_on_list = 0; + + this.stopTimer(); + this.startTimer(0) + }, + + highlightTable: function(event) + { + event = event || window.event; + var elem = event.srcElement || event.target; + + var obj = elem.autosuggest; + if(!obj) return; + + obj.mouse_on_list = 1; + + var row = obj.getRow(); + if(row && row.style) + row.className = ""; + + obj.current = parseInt(elem.getAttribute("pos"), 10); + + row = obj.getRow(); + if(row && row.style) + row.className = "selected"; + + obj.stopTimer(); + obj.startTimer(0); + }, + + choose: function() + { + if(!this.displayed) return; + if(this.current < 0) return; + + this.displayed = false; + + var kl = this.keywords.length; + + for(var i = 0, c = 0; i < kl; i++) + if(this.bool[i] && (c++ == this.current)) + break; + + this.selectedIndex = i; + this.insertWord(this.keywords[i]); + + if(this.onSelect) + this.onSelect(i, this); + }, + + insertWord: function(a) + { + // Sets the caret position to l in the object + function setCaretPos(obj, l) + { + obj.focus(); + + if(obj.setSelectionRange) + { + obj.setSelectionRange(l, l); + } + else if(obj.createTextRange) + { + var m = obj.createTextRange(); + m.moveStart("character", l); + m.collapse(); + m.select(); + } + } + + if(this.text_delimiter.length > 0) + { + var str = "", word = this.delim_words[this.current_word], wl = word.length, l = 0; + + for(var i = 0; i < this.delim_words.length; i++) + { + if(this.current_word == i) + { + var prespace = "", postspace = "", gotbreak = false; + + for(var j = 0; j < wl; ++j) + { + if(word.charAt(j) != " ") + { + gotbreak = true; + break; + } + + prespace += " "; + } + + for(j = wl - 1; j >= 0; --j) + { + if(word.charAt(j) != " ") + break; + + postspace += " "; + } + + str += prespace; + str += a; + l = str.length; + + if(gotbreak) str += postspace; + } + else + { + str += this.delim_words[i]; + } + + if(i != this.delim_words.length - 1) + str += this.delim_char[i]; + } + + this.field.value = str; + setCaretPos(this.field, l); + } + else + { + this.field.value = a; + } + + this.mouse_on_list = 0; + this.hide(); + }, + + hide: function() + { + if(this.mouse_on_list == 0) + { + this.displayed = false; + + var base = document.getElementById("suggest_table_" + this.field_id); + if(base) + { + var helper = document.getElementById("suggest_helper_" + this.field_id); + if(helper) + document.body.removeChild(helper); + + document.body.removeChild(base); + } + + this.stopTimer(); + + this.cur_x = 0; + this.cur_y = 0; + this.cur_w = 0; + this.cur_h = 0; + + this.rows = []; + } + }, + + keyPress: function(event) + { + // On firefox there is no way to distingish pressing shift-8 (asterix) + // from pressing 8 during the keyDown event, so we do restrict_typing + // whilest handling the keyPress event + + event = event || window.event; + + var code = window.event ? event.keyCode : event.charCode; + var obj = event.srcElement || event.target; + + obj = obj.autosuggest; + + if(obj.restrict_typing && !obj.suggest_url.length && (code >= 32)) + { + var caret_pos = obj.getCaretEnd(obj.field); + var new_term = obj.field.value.substr(0, caret_pos).toLowerCase(); + var isDelimiter = false; + + if(obj.text_delimiter.length > 0) + { + // check whether the pressed key is a delimiter key + var delim_split = ""; + for(var j = 0; j < obj.text_delimiter.length; j++) + { + delim_split += obj.text_delimiter[j]; + + if(obj.text_delimiter[j] == String.fromCharCode(code)) + isDelimiter = true; + } + + // only consider part of term after last delimiter + delim_split = obj.addSlashes(delim_split); + + var lastterm_rx = new RegExp(".*([" + delim_split + "])"); + new_term = new_term.replace(lastterm_rx, ''); + } + + var keyw_len = obj.keywords.length; + var i = 0; + + if(isDelimiter) + { + // pressed key is a delimiter: allow if current term is complete + for(i = 0; i < keyw_len; i++) + if(obj.keywords[i].toLowerCase() == new_term) + break; + } + else + { + new_term += String.fromCharCode(code).toLowerCase(); + for(i = 0; i < keyw_len; i++) + if(obj.keywords[i].toLowerCase().indexOf(new_term) != -1) + break; + } + + if(i == keyw_len) + { + obj.stopEvent(event); + return false; + } + } + + if(obj.caret_moved) obj.stopEvent(event); + return !obj.caret_moved; + }, + + checkKey: function(event) + { + event = event || window.event; + + var code = event.keyCode; + var obj = event.srcElement || event.target; + + obj = obj.autosuggest; + obj.caret_moved = 0; + + var term = ""; + + obj.stopTimer(); + + switch(code) + { + // Up arrow: + case 38: + if(obj.current <= 0) + { + obj.stopEvent(event); + obj.hide(); + } + else + { + obj.scroll(true, 1); + obj.caret_moved = 1; + obj.stopEvent(event); + } + return false; + + // Down arrow: + case 40: + if(!obj.displayed) + { + obj.timer = setTimeout(function() + { + obj.preSuggest(-1); + }, + 25); + } + else + { + obj.scroll(false, 1); + obj.caret_moved = 1; + } + return false; + + // Page up: + case 33: + if(obj.current == 0) + { + obj.caret_moved = 0; + return false; + } + + obj.scroll(true, (obj.use_scroll || (obj.getRow() == obj.rows[obj.range_up])) ? obj.entry_limit : (obj.current - obj.range_up)); + obj.caret_moved = 1; + break; + + // Page down: + case 34: + if(obj.current == (obj.total - 1)) + { + obj.caret_moved = 0; + return false; + } + + obj.scroll(false, (obj.use_scroll || (obj.getRow() == obj.rows[obj.range_down])) ? obj.entry_limit : (obj.range_down - obj.current)); + obj.caret_moved = 1; + break; + + // Home + case 36: + if(obj.current == 0) + { + obj.caret_moved = 0; + return false; + } + + obj.scroll(true, obj.total); + obj.caret_moved = 1; + break; + + // End + case 35: + if(obj.current == (obj.total - 1)) + { + obj.caret_moved = 0; + return false; + } + + obj.scroll(false, obj.total); + obj.caret_moved = 1; + break; + + // Esc: + case 27: + term = obj.field.value; + + obj.mouse_on_list = 0; + obj.hide(); + break; + + // Enter: + case 13: + if(obj.displayed) + { + obj.caret_moved = 1; + obj.choose(); + return false; + } + break; + + // Tab: + case 9: + if((obj.displayed && (obj.current >= 0)) || obj.timer) + { + obj.caret_moved = 1; + obj.choose(); + + setTimeout(function() { obj.field.focus(); }, 25); + return false; + } + break; + + case 16: //shift + break; + + default: + obj.caret_moved = 0; + obj.timer = setTimeout(function() + { + obj.preSuggest(code); + }, + (obj.response_time < 10 ? 10 : obj.response_time)); + } + + if(term.length) setTimeout(function() { obj.field.value = term; }, 25); + return true; + }, + + preSuggest: function(kc) + { + if(!this.timer) + return; + + this.stopTimer(); + + if(this.displayed && (this.lastterm == this.field.value)) return; + this.lastterm = this.field.value; + + if(kc == 38 || kc == 40 || kc == 13) return; + + var c = 0; + if(this.displayed && (this.current >= 0)) + { + for(var i = 0; i < this.keywords.length; i++) + { + if(this.bool[i]) ++c; + + if(c == this.current) + { + this.previous = i; + break; + } + } + } + else + { + this.previous = -1; + } + + if(!this.field.value.length && (kc != -1)) + { + this.mouse_on_list = 0; + this.hide(); + } + + var ot, t; + + if(this.text_delimiter.length > 0) + { + var caret_pos = this.getCaretEnd(this.field); + + var delim_split = ""; + for(var i = 0; i < this.text_delimiter.length; i++) + delim_split += this.text_delimiter[i]; + + delim_split = this.addSlashes(delim_split); + var delim_split_rx = new RegExp("([" + delim_split + "])"); + c = 0; + this.delim_words = []; + this.delim_words[0] = ""; + + for(var i = 0, j = this.field.value.length; i < this.field.value.length; i++, j--) + { + if(this.field.value.substr(i, j).search(delim_split_rx) == 0) + { + var ma = this.field.value.substr(i, j).match(delim_split_rx); + this.delim_char[c++] = ma[1]; + this.delim_words[c] = ""; + } + else + { + this.delim_words[c] += this.field.value.charAt(i); + } + } + + var l = 0; + this.current_word = -1; + + for(i = 0; i < this.delim_words.length; i++) + { + if((caret_pos >= l) && (caret_pos <= (l + this.delim_words[i].length))) + this.current_word = i; + + l += this.delim_words[i].length + 1; + } + + ot = this.trim(this.delim_words[this.current_word]); + t = this.trim(this.addSlashes(this.delim_words[this.current_word])); + } + else + { + ot = this.field.value; + t = this.addSlashes(ot); + } + + if(ot.length == 0 && (kc != -1)) + { + this.mouse_on_list = 0; + this.hide(); + } + else if((ot.length == 1) || this.full_refresh || + ((ot.length > 1) && !this.keywords.length) || + ((ot.length > 1) && (this.keywords[0].charAt(0).toLowerCase() != ot.charAt(0).toLowerCase()))) + { + var ot_ = ((ot.length > 1) && !this.full_refresh) ? ot.charAt(0) : ot; + + if(this.suggest_url.length) + { + + // create xmlhttprequest object: + var http = null; + if(typeof(XMLHttpRequest) != "undefined") + { + try + { + http = new XMLHttpRequest(); + } + catch (e) { http = null; } + } + else + { + try + { + http = new ActiveXObject("Msxml2.XMLHTTP") ; + } + catch (e) + { + try + { + http = new ActiveXObject("Microsoft.XMLHTTP") ; + } + catch (e) { http = null; } + } + } + + if(http) + { + // Uncomment for local debugging in Mozilla/Firefox: + // try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } catch (e) { } + + if(http.overrideMimeType) + http.overrideMimeType("text/xml"); + + http.open("GET", this.suggest_url + ot_, true); + + var that = this; + http.onreadystatechange = function(n) + { + if(http.readyState == 4) + { + if((http.status == 200) || (http.status == 0)) + { + var text = http.responseText; + + var index1 = text.indexOf(""); + var index2 = (index1 == -1) ? text.length : text.indexOf(" lcs) + { + lcs = table[i+1][j+1]; + } + } + else + { + table[i+1][j+1] = 0; + } + } + } + return lcs; + }, + + // A function to compute the Levenshtein distance between two strings + // Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported + // Full License can be found at http://creativecommons.org/licenses/by-sa/3.0/legalcode + // This code is an unmodified (aside from style) version of the code written by Marco de Wit + // and was found at http://stackoverflow.com/a/18514751/745719 + levenshtein: (function() + { + var row2 = []; + return function(s1, s2) + { + if(s1 === s2) + { + return 0; + } + else + { + var s1_len = s1.length, s2_len = s2.length; + if(s1_len && s2_len) + { + var i1 = 0, i2 = 0, a, b, c, c2, row = row2; + while(i1 < s1_len) + row[i1] = ++i1; + while(i2 < s2_len) + { + c2 = s2.charCodeAt(i2); + a = i2; + ++i2; + b = i2; + for(i1 = 0; i1 < s1_len; ++i1) + { + c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); + a = row[i1]; + b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); + row[i1] = b; + } + } + return b; + } + else + { + return s1_len + s2_len; + } + } + }; + })(), + + // Setup an event handler for the given event and DOM element + // event_name refers to the event trigger, without the "on", like click or mouseover + // func_name refers to the function callback that is invoked when event is triggered + addEvent: function(obj, event_name, func_ref) + { + if(obj.addEventListener && !window.opera) + { + obj.addEventListener(event_name, func_ref, true); + } + else if(obj.attachEvent) + { + obj.attachEvent("on" + event_name, func_ref) + } + else + { + obj["on" + event_name] = func_ref; + } + }, + + // Stop an event from bubbling up the event DOM + stopEvent: function(event) + { + event = event || window.event; + + if(event) + { + if(event.stopPropagation) event.stopPropagation(); + if(event.preventDefault) event.preventDefault(); + + if(typeof(event.cancelBubble) != "undefined") + { + event.cancelBubble = true; + event.returnValue = false; + } + } + + return false; + }, + + // Get the end position of the caret in the object. Note that the obj needs to be in focus first. + getCaretEnd: function(obj) + { + if(typeof(obj.selectionEnd) != "undefined") + { + return obj.selectionEnd; + } + else if(document.selection && document.selection.createRange) + { + var M = document.selection.createRange(), Lp; + + try + { + Lp = M.duplicate(); + Lp.moveToElementText(obj); + } + catch(e) + { + Lp = obj.createTextRange(); + } + + Lp.setEndPoint("EndToEnd", M); + var rb = Lp.text.length; + + if(rb > obj.value.length) + return -1; + + return rb; + } + + return -1; + }, + + // Get offset position from the top/left of the screen: + curPos: function(obj, what) + { + var coord = 0; + while(obj) + { + coord += obj["offset" + what]; + obj = obj.offsetParent; + } + + return coord; + }, + + // String functions: + + addSlashes: function(str) { return str.replace(/(["\\\.\|\[\]\^\*\+\?\$\(\)])/g, "\\$1"); }, + + trim: function(str) { return str.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"); } +}; diff --git a/allegro/docs/src/changes-5.0.txt b/allegro/docs/src/changes-5.0.txt new file mode 100644 index 00000000..8b4ef8a1 --- /dev/null +++ b/allegro/docs/src/changes-5.0.txt @@ -0,0 +1,4530 @@ +% Allegro changelog for 5.0.x series + +See `changes._tx` for changes in earlier versions of Allegro. These lists +serve as summaries; the full histories are in the git repository. + + +Changes from 5.0.10 to 5.0.11 (January 2015) +=========================================== + +The main developers this time were: SiegeLord and Peter Wang. + +Core: + + - Fix OSX backend on OSX 10.10 (lordnoriyuki). + +Audio addon: + + - Fix/avoid all sound examples freezing on OSX with the aqueue driver (Elias Pschernig). + + - Fix a deadlock in Pulseaudio driver. + +Other: + + - Fix build warnings. + + - Improve documentation (syntax highlighting). + + + +Changes from 5.0.9 to 5.0.10 (June 2013) +======================================== + +The main developers this time were: Trent Gamblin, Paul Suntsov, Peter Wang. + +Core: + + - Register system interface even if no display driver available on Windows. + +Displays: + + - Don't crash in al_create_display if there is no display driver. + + - Don't crash at shutdown if there is no display driver (Windows). + + - Don't fail init if both D3D, GL drivers unavailable (Windows). + + - Run fullscreen toggle on main thread (OS X). + + - Destroy the backbuffer bitmap when destroying the display (OS X). + + - Switch to new NSTrackingArea API (OS X). + + - Check availability of fullscreen button on window frame at run-time (OS X). + +Graphics: + + - Add ALLEGRO_SRC_COLOR, ALLEGRO_DEST_COLOR, ALLEGRO_INVERSE_SRC_COLOR, + ALLEGRO_INVERSE_DEST_COLOR blending modes (initially by Jon Rafkind and + Elias Pschernig). + + - Let al_destroy_bitmap implicitly untarget the bitmap on the calling + thread. + + - Use memory bitmap drawing when either bitmap is locked (OpenGL). + + - Add const qualifiers to glUniform*v() functions (Aaron Bolyard). + +Input: + + - al_set_mouse_xy on Windows resulted in the mouse getting set to the wrong + position in windowed modes. + + - Scale the user supplied mouse cursor if it's too big (Windows). + + - Fix mouse warping on OS X. + + - Fix mouse warping in Linux evdev mouse driver. + +Audio addon: + + - pulseaudio: Use smaller buffer size by default, and make it configurable. + + - pulseaudio: Clean up state transitions. + + - Fix looping in Ogg Vorbis stream (Todd Cope). + + - Enable the use of the unpatched DirectX SDK to build Allegro with MinGW. + +Color addon: + + - Fix al_color_rgb_to_html blue component (Jeff Bernard). + +Font addons: + + - Make al_init_ttf_addon return true for subsequent calls. + +Primitives addon: + + - Disallow 3 component vectors for ALLEGRO_PRIM_TEX_COORD. + + - Check that the vertex declaration is valid before creating it. + + - Respect filter settings of textures in the D3D backend. + +Build system: + + - Do not install most internal header files. + + - Do not search for and link with unneeded X libraries. + +Examples: + + - ex_audio_timer: New example. + +Other: + + - Minor fixes. + + - Various documentation updates. + + - A lot of code refactoring. + + + +Changes from 5.0.8 to 5.0.9 (February 2013) +=========================================== + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Peter Wang. + +Core: + +- Clean up logging subsystem at shutdown (muhkuh). + +- Fix a problem with creating a display after Allegro is shut down + then re-initialised on X11. + +- Fix use of clobbered return value from setlocale() on X11. + +- Fix use of double math functions for float arguments (Nick Trout). + +Displays: + +- Fix al_set/get_window position on Windows so getting/setting to the + same position continuosly doesn't move the window. (Michael Swiger) + +- Add al_set_display_icons (plural). Implemented on X11 and Windows. + +- Made al_get_display_mode return the closest thing to a pixel format + possible with the WGL driver (tobing). + +- Move WGL context destruction out of the message pump thread and into + the user/main thread. + +- Allow command-tab to work in fullscreen window mode on OS X. + +Graphics: + +- Avoid null pointer dereference when setting a target bitmap after + its video_texture has already been released (D3D). + +- Make d3d_lock_region fail immediately if _al_d3d_sync_bitmap + failed, likely because the device was lost. + +- Set device_lost flag immediately when d3d_display_thread_proc + finds the device is lost. + +- Sync bitmaps before resizing display to prevent changes being lost + after the resize (D3D). + +- Revert a faulty FBO rebinding optimisation in al_set_target_bitmap. + +- Fix OpenGL extensions being completely ignored on OS X. + +- Support stencil buffer on iOS. + +Input: + +- Partially fix mouse buttons "sticking" on Mac, e.g. holding the + mouse and toggling fullscreen window. + +Filesystem: + +- Keep absolute path in ALLEGRO_FS_ENTRYs so that later changes to the + working directory do not affect the interpretation of the path. + +- Set ALLEGRO_FILEMODE_HIDDEN properly on Unix. + +- Make sure stat mode bits are cleared in default implementation of + al_update_fs_entry. + +- Support Unicode paths on Windows. + +- Change description of al_get_fs_entry_name about not returning absolute + path if created from relative path; no longer true for either the default + or Physfs implementations. + +Audio addons: + +- Shut down threads properly when when destroying FLAC and modaudio streams. + +- Fix PulseAudio driver trying to connect to a non-existent server forever. + +Image I/O addon: + +- Fixed loading interlaced .png files with libpng. + +- Use Allegro built-in loaders in preference to OS X loaders for BMP/TGA/PCX. + The OS X TGA loader doesn't support alpha and this is also more consistent. + +- Restored ability of the native OSX image loader to load grayscale pictures. + +Native dialog addon: + +- Add al_init_native_dialog_addon and al_shutdown_native_dialog_addon. + +Build system: + +- Rename allegro\*-5.0.pc files to allegro\*-5.pc. The old names are + deprecated but retained on the 5.0 branch for backwards compatibility. + +- Only generate and install pkg-config files for libraries that we build. + +- Install iPhone internals headers (Nick Trout). + +Examples: + +- ex_icon2: New example. + +- speed: Use builtin font. + +Other: + +- Documentation updates. + +- A lot of code refactoring. + + + +Changes from 5.0.7 to 5.0.8 (November 2012) +=========================================== + +The main developers this time were: Dennis Busch, Trent Gamblin, +Elias Pschernig, Paul Suntsov, Peter Wang. + +Core: + +- Added alternate spelling: ALLEGRO_ALIGN_CENTER. + +Displays: + +- Rewrite D3D display format listing code, which was broken. This should + re-enable multi-sampling and fix ex_depth_mask being slow with D3D. + +- Fixed a case where changing fullscreen mode in D3D via al_resize_display + caused a crash and loss of loaded bitmaps information. + +- Fixed a case where changing fullscreen mode in OpenGL (on Windows) via + al_resize_display cause nothing to be rendered after the mode change. + +- Fix crashes when resizing a WGL fullscreen window. + +- Fixed missing/incorrect resize events under Windows. + +- Fix al_set_new_display_adapter on OS X. + +- Fix use of invalidated pointers in D3D driver when the first format fails. + +- Fix bug where setting the mouse cursor had no effect when + the mouse was captured (mouse button held down). + +- Fix windows not having a minimise button when set to + windowed state from fullscreen window state. + +- Respect ALLEGRO_FRAMELESS flag properly when toggling from + fullscreen window state to windowed state (Windows). + +- Don't generate DISPLAY_LOST events when resizing a fullscreen display. + +- Scale window icon to sizes returned by GetSystemMetrics (Windows). + +- Fixed ALLEGRO_FULLSCREEN_WINDOW under OS X. + +- Added al_osx_get_window function (Dennis Gooden). + +Graphics: + +- al_draw_pixel was crashing when drawn on sub-bitmaps on OpenGL. + +- Fix a potential crash when drawing the screen to a bitmap with D3D. + +- Avoid null pointer dereference when setting a target bitmap after + its video_texture has already been released (D3D). + +- Lock bitmap to prevent slowness when creating a cursor from a non-memory + bitmap on Windows. + +- Conditionally lock bitmap when creating cursor on X11 (previously it did + so even if already locked). + +- Don't use NSOpenGLPFAAccelerated unnecessarily (OS X). + +Input: + +- Fix incorrect keyboard modifier flags after leaving and re-entering a window + (Windows). + +- Fixed a bug with mouse enter/leave events for resized windows under OSX + (Dennis Gooden). + +- Temporary fix for delay after mouse warp on OS X. + +File I/O: + +- Fix al_fputc on big-endian. Reported by Andreas Rönnquist and + Tobias Hansen. + +- Make al_fputc return value like fputc when out of range. + +- Fix al_read_directory crash on 64-bit Windows (simast). + +Image addon: + +- Don't include native image loader source files in builds with the native + image loaders disabled (OSX, iOS). + +- Added a missing autorelease-pool to the OSX bitmap saving function + (sleepywind). + +- Fix OSX native image loader for loading not-premultiplied RGB data. + Previously the data was "de-multiplied", with possibly all information lost. + +- Fix OSX native image loader for loading bitmaps without an alpha channel. + They appeared completely black previously. + +Font addons: + +- Add builtin font creation function. + +- Added ALLEGRO_ALIGN_INTEGER text drawing flag (Todd Cope). + +- Made TTF addon include padding on the top and left edges of pages + (Todd Cope). + +Audio addon: + +- Use programmatically generated interpolators. They cover an additional + case which was missed and should be slightly more efficient. + +- Support linear interpolation for 16-bit mixers. + +- Add cubic interpolation for mixers (off by default). + +- Fix potential deadlock in stop_voice for OpenAL. + +- Fix potential deadlock in stop_voice for DirectSound. + +- Improve buffer filling behaviour for DirectSound, reducing pops and + crackles significantly on slower machines. + +- Increase default buffer size for DirectSound to 8192 samples. + +- Fix setting the speed of an audio stream after it was attached to the mixer. + +Native dialogs addon: + +- Do not unload of rich edit module when closing one text log window while + another exists. Reported by URB753. + +- Use default colours for Windows text log implementation, avoiding problems + when the previous custom colours failed, leading to black text on a + nearly black background. + +Build system: + +- Install pkg-config files when cross-compiling on Unix. + +Examples: + +- ex_synth: Add button to save waveform to a file. + +- ex_multisample: Demonstrate using moving bitmaps. + +- speed: Avoid poor performance due to needless redraws. + +- Renamed a5teroids to Cosmic Protector + +Other: + +- Many minor bug fixes. + +- Various documentation updates. + + +Changes from 5.0.6 to 5.0.7 (June 2012) +======================================= + +The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. + +Core: + +- Fix ALLEGRO_STATIC_ASSERT collisions from different files included in the + same translation unit. Reported by tobing. + +- Make al_ref_cstr, al_ref_ustr and al_ref_buffer return const ALLEGRO_USTR* + instead of just an ALLEGRO_USTR* (Paul Suntsov). + +- Make al_ustr_empty_string const correct. + +- Fix many memory leak/warnings on MacOS X (Pär Arvidsson). + +- Fix typo preventing get_executable_name from using System V procfs + correctly. Reported by Max Savenkov. + +Displays: + +- Add ALLEGRO_FRAMELESS as a preferred synonym for the confusing + ALLEGRO_NOFRAME flag. + +- Rename al_toggle_display_flag to al_set_display_flag, retaining + the older name for compatibility. + +- Set WM_NAME for some window managers (X11). + +Graphics: + +- Force al_create_bitmap to not create oversized bitmaps, to mitigate + integer overflow problems. + +- Removed initial black frame on all Allegro programs. + +OpenGL: + +- Texture should be 'complete' (min/mag and wrap set) before glTexImage2D. + +- Fixed a bug in al_unlock_bitmap where the pixel alignment mistakenly was + used as row length. + +- Fixed typo in names of some OpenGL extension functions. + +- Display list of OpenGL extensions in allegro.log also for OpenGL 3.0. + +Direct3D: + +- Fixed a bug in the D3D driver where separate alpha blending was being + tested for when it shouldn't have been (Max Savenkov). + +Input: + +- Monitor /dev/input instead of /dev on Linux for hotplugging joysticks + (Jon Rafkind). + +- Do not permanently change the locale for the X11 keyboard driver. + Set LC_CTYPE only, not LC_ALL. + +Audio addon: + +- Fix desychronization due to inaccurate sample positions when resampling. + Thanks to _Bnu for discovering the issue and Paul Suntsov for devising the + correct solution. + +- Fix linear interpolation across audio stream buffer fragments. + +- Fix two minor memory leaks in the PulseAudio driver. + +Image I/O addon: + +- Improve compatibility of BMP loader. In particular, support bitmaps with + V2-V5 headers and certain alpha bit masks. + +- Fix TGA loader using more memory than necessary. Reported by Max Savenkov. + +Font addon: + +- Use user set pixel format for fonts. + +Native dialogs addon: + +- Clear mouse state after dialogs or else it gets messed up (OSX). + +- Fix some warnings in gtk_dialog.c. + +- Wrap use of NSAlert so it can be run on the main thread with return value. + +Examples: + +- Add ex_resample_test. + +- ex_audio_props: Add bidir button. + +- ex_joystick_events: Support hotplugging and fix display of 3-axis sticks. + +- Add test_driver --no-display flag. (Tobias Hansen) + +Other: + +- Various documentation updates. + +- Other minor bug fixes. + +- Fix whatis entries of man pages. (Tobias Hansen) + + + +Changes from 5.0.5 to 5.0.6 (March 2012) +======================================== + +The main developers this time were: Trent Gamblin, Matthew Leverton, +Elias Pschernig, Paul Suntsov, Peter Wang. + +Core: + +- Added al_register_assert_handler. + +Graphics: + +- Added al_draw_tinted_scaled_rotated_bitmap_region. + +- Added al_reset_clipping_rectangle convenience function. + +- Added al_get_parent_bitmap. + +- Fixed a bug in the OpenGL driver when drawing the backbuffer outside the + clipping rectangle of the target bitmap. + +- Make blitting from backbuffer work when using multisampling on Windows/D3D. + +Displays: + +- Set ALLEGRO_MINIMIZED display flag on Windows (Zac Evans). + +- Don't generate bogus resize events after restoring minimised window on + Windows. + +- Fixed bug on Windows where two SWITCH_IN events were fired when window was + minimized/restored (Michael Swiger). + +- Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic under Windows + as well as a bug where repeatedly setting the flag to on would make the + window grow bigger and bigger (Michael Swiger). + +- Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic in X11. + +- Prevent a deadlock during display creation on X. + +- Fallback to the 'old' visual selection method on X instead of crashing + if the 'new' visual selection doesn't work. + +Input: + +- Use the same logic in set_mouse_xy for FULLSCREEN_WINDOW as was used for + FULLSCREEN. (Max OS X) + +Filesystem: + +- Added al_fopen_slice. + +- Added al_set_exe_name which allows overriding Allegro's idea of the path + to the current executable. + +- Make al_get_standard_path(ALLEGRO_TEMP_PATH) treat the value of TMPDIR + et al. as a directory name even without a trailing slash. (Unix) + +- Make stdio al_fopen implementation set proper errno on failure. + +Audio addons: + +- Add mixer gain property and functions. + +- Improve code to check that DLL symbols are loaded in the acodec addon. + The old method was hacky and broke under -O2 using GCC 4.6.1. + +Image I/O addon: + +- Improved accuracy of un-alpha-premultiplying in the native OSX bitmap + loader. + +Primitives addon: + +- Added al_draw_filled_pieslice and al_draw_pieslice. + +- Added al_draw_elliptical_arc. + +TTF addon: + +- Added al_load_ttf_font_stretch functions (tobing). + +- Added ALLEGRO_TTF_NO_AUTOHINT font loading flag to disable the Auto Hinter + which is enabled by default in newer version of FreeType (Michał Cichoń). + +- Clear locked region so pixel borders aren't random garbage that can be seen + sometimes with linear filtering on. + +- Unlock glyph cache page at end of text_length and get_text_dimensions + (jmasterx). + +Examples: + +- Added new examples: ex_audio_chain, ex_display_events, ex_file_slice. + +- ex_ogre3d: Make it work under Windows (AMCerasoli). + +- a5teroids: Support gamepads that report small non-zero values for sticks + that are at rest. + +Other: + +- Added index to HTML version of the reference manual (Jon Rafkind). + +- Various documentation updates. + +- Other minor bug fixes. + + + +Changes from 5.0.4 to 5.0.5 (November 2011) +=========================================== + +The main developers this time were: Elias Pschernig and Trent Gamblin. + +Graphics: + +- Fixed several instances of windows being positioned wrong on Windows: + regular windows, WGL FULLSCREEN_WINDOW, and ALLEGRO_NOFRAME windows. + +- Don't re-bind the FBO in al_set_target_bitmap if the new target + bitmap shares the parent bitmap with the new target bitmap (Paul Suntsov). + +- Zero out fake refresh rate information from the nvidia proprietary driver + on X11 (Peter Wang). + +- Implemented the ALLEGRO_FULLSCREEN_WINDOW flag for iOS. + +Input: + +- Make al_set_mouse_xy work in fullscreen on Windows. + +- Fixed a race condition in al_init_joystick. + +- Fixed problem on OS X where having two identical gamepads attached would + cause joystick initialization to hang (Thanks to Todd Cope for pointing it + out.) + +- Fixed iphone joystick events (it assumed a call to al_get_joystick but + that's not required when using events). + +TTF fonts: + +- Save new bitmap flags and bitmap format at time of loading font and use them + when creating pages. + +Primitives addon: + +- Very thin arcs/pieslices were not drawn due to an overzealous check + (Paul Suntsov). + +Native dialogs addon: + +- Implemented al_show_native_message_box for iOS. + +Other: + +- Use .../Library/Application Support for ALLEGRO_USER_SETTINGS_PATH and + ALLEGRO_USER_DATA_PATH on iOS. + +- Listen for applicationDidBecomeActive and applicationWillResignActive + instead of applicationWillEnterForeground and applicationDidEnterBackground + on iOS. This makes all of the common situations where you want to pause your + game work, such as the lock button. + +- Fix some memory leaks on iOS. + +Documentation: + +- Various documentation updates. + +- Generate multiple copies of a man page for all the API entries that it + documents. + + + +Changes from 5.0.3 to 5.0.4 (August 2011) +========================================= + +The main developers this time were: Trent Gamblin, Matthew Leverton, +Elias Pschernig, Jon Rafkind, Paul Suntsov, Peter Wang and torhu. + +Core: + +- Restore searching of directories on PATH for DLLs to load on Windows. + +- Fix crash on shutdown in headless Unix environment (no X11 display). + +- Change all instances of al_malloc + memset(0) to al_calloc. + +Graphics: + +- Save memory in OpenGL case by freeing bitmap memory after uploading a + texture. Use a temporary buffer when converting lock buffer back to native + texture format. + +- Don't release or refresh memory or sub-bitmaps when D3D device gets + lost/found. + +- Do not set D3D sub bitmaps to modified when first creating them. This can + cause major slowdowns when creating a lot of sub-bitmaps and is likely + responsible for slow font performance/startup when using D3D. + +- Fix incorrect number of display formats in D3D (tobing). + +- Honor ALLEGRO_VSYNC in the WGL driver. + +- Make titlebar icons the right size on Windows. + +- Fix typo causing weird results of al_get_monitor_info on X. + +- Don't setup FBO for a sub-bitmap whose parent is locked. + +- Specialise ADD/ONE/INVERSE_ALPHA blend mode software scanline drawers. + +- Toggle ALLEGRO_VIDEO_BITMAP flag off when creating a memory bitmap (both + bits were previously on). + +- Add null bitmap assertion to al_clone_bitmap. + +Input: + +- New system for mapping extended keys in Windows keyboard driver. + Mainly for getting the same keycode for numpad keys independently of the + state of Num Lock. + +- More reliable updating of the toggle modifiers in Windows keyboard driver + (Num Lock, Caps Lock, and Scroll Lock). + +Timers: + +- Fix race conditions when starting timers from different threads. + +Audio addons: + +- Don't mix into a global temporary sample buffer, causing noise when two + separate mixers are trying to run in parallel. + +- Make it possible to start/stop an audio stream which is attached to a voice. + +- ALSA voices could not be resumed after being stopped, because the + update threads quit as soon as a voice is stopped. + +- OpenAL backend did not handle the case where _al_voice_update returns less + than a full buffer. + +- Attempt to load FLAC and Vorbis DLLs only once to avoid Windows popping up + too many error windows. + +Native dialogs addon: + +- al_show_native_messagebox() on Windows: add UTF-8 support; show heading; + show information icon by default. + +TTF addon: + +- Reduce memory usage. + +- Don't make multiple passes over strings when computing text dimensions. + +Build system: + +- Make sure static builds on Windows never use DLL_TLS (Zac Evans). + +- Made compilation possible with different combinations of Xinerama, + XF86VidMode, or Randr being present. + +- cmake: Use find_path HINTS instead of PATHS in our DirectX SDK scripts. + +- cmake: Search for D3DX9 once instead of multiple times (John-Kim Murphy). + +- cmake: Find FLAC/Ogg/Vorbis libraries under the names generated by the + official MSVC project files. + +- Include zlib.h explicitly for libpng 1.5. + +Examples: + +- Add multisampling to SPEED example. Change examples to use ALLEGRO_SUGGEST + for multisampling. + +- Include the font for speed.app under OSX within the bundle so it can be run + by double clicking. + +- Use default blending/pre-multiplied alpha in ex_blend2. + +Other: + +- Various documentation updates. + +- Fix minor memory leaks. + +Bindings: + +- Better way to make the Python wrapper work with both Python 2 and 3. + +- Include Windows-specific functions in the Python wrapper. + + + +Changes from 5.0.2.1 to 5.0.3 (May 2011) +======================================== + +Input: + +- Fixed keyboard repeat for extended keys on Windows. + Added ALLEGRO_KEY_MENU. (torhu) + +- Make Delete key in Windows send KEY_CHAR event with unichar code 127 + (Peter Wang). + +Filesystem: + +- al_remove_filename returned false even if successful (reported by xpolife). + +Graphics: + +- On OpenGL ES 1.1, glReadPixels can only read 4 byte pixels (Trent Gamblin). + +Font addon: + +- Fix a small memory leak when unregistering a handler with + al_register_font_loader (Trent Gamblin). + +Primitives addon: + +- Fix assertion failures when drawing al_draw_ellipse, al_draw_arc, + al_draw_rounded_rectangle, al_draw_filled_rounded_rectangle at very + small scales (reported by Carl Olsson). + +Native dialogs addon: + +- gtk: Fix truncated string if the final button contained a non-ASCII + character (Peter Wang). + +Other: + +- Minor build fixes and documentation updates. + + + +Changes from 5.0.2 to 5.0.2.1 (April 2011) +========================================== + +- Fix regression on Windows where the keyboard state was not updated + unless the keyboard event source is registered to an event queue. + + + +Changes from 5.0.1 to 5.0.2 (April 2011) +======================================== + +Input: + +- Fix inverted mouse wheel on X11. + +- Make unicode field in KEY_CHAR events zero for Fn, arrow keys, etc. + for OS X (jmasterx, Peter Hull). + +- Support ALLEGRO_KEY_PAD_ENTER and detect left/right Alt and Ctrl + keys independently on Windows (torhu, Matthew Leverton). + + + +Changes from 5.0.0 to 5.0.1 (March 2011) +======================================== + +The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. +Other contributions noted in-line. + +Graphics: + +- Automatically destroy framebuffer objects (FBOs) created for non-memory + bitmaps after a while. This solves the problem of running out of resources + if you set many different target bitmaps. + +- Make al_get_opengl_fbo attempt to create an FBO if one doesn't exist. + +- Avoid very small textures in Direct3D. + +- Do not sync from memory when first creating/uploading a bitmap (D3D). + +- Try to fix the problem of the taskbar appearing above fullscreen windows + on Windows. + +- Center the window after toggling fullscreen on Windows. + +Input: + +- Support 4-way mouse-wheel and up to 32 mouse buttons in X11. + +Audio addons: + +- Avoid buffer overrun while reading from vorbis files. + +- Added optional support for Tremor in place of libvorbis on any platform. + +- Do not prefer DirectSound with OpenAL. This can cause problems and also + will override user config. + +- Play silence where needed in DirectSound driver. + +TTF addon: + +- Do not hold bitmap drawing when changing target bitmap, which is invalid + and caused transformations to be misapplied. + +- Remove FBO for a cache bitmap once we are no longer adding glyphs to it. + +Build system: + +- Force "default" visibility of _al_mangled_main on OS X, otherwise the + dynamic linker cannot find the symbol if building with XCode4 + (Owen Anderson and Peter Hull). + +- Generated pkg-config files should take into account LIB_SUFFIX variable + (Cristian Morales Vega). + +- Update allegro_font pkg-config file to not require allegro_primitives. + +Documentation: + +- Various documentation updates. + +- Add copy of DejaVu font licence. + +Bindings: + +- Add allegro_main addon to the Python wrapper. Make the wrapper work with + Python 3, which has a different string representation. Add parameter type + checking for custom types. + + + +Changes from 5.0.0 RC5 to 5.0.0 (February 2011) +=============================================== + +Color addon: + +- Use colour names from CSS. This is the same as the previous list but + with all grey/gray alternatives. + +Documentation: + +- Minor documentation updates. + + + +Changes from 5.0.0 RC4 to 5.0.0 RC5 (February 2011) +=================================================== + +The main developers this time were: Thomas Fjellstrom, Trent Gamblin, +Peter Hull, Matthew Leverton and Peter Wang. Other contributions noted +in-line. + +System: + +- Load allegro5.cfg from the directory containing the executable, not the + initial working directory. + +Graphics: + +- Make al_get_monitor_info return success code. + +- Replace al_set_new_display_adaptor(-1) with a named constant + ALLEGRO_DEFAULT_DISPLAY_ADAPTER. + +- Fix numerous bugs in X mode setting and multi monitor related code, and + introduce new xrandr code. + +- Generate ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY when mouse leaves OS X window + (Evert Glebbeek). + +- Hide OS X window during exiting fullscreen window mode, to prevent the + hideous misaligned animation from showing. + +- Fix erroneous assertions in OpenGL backend. + +- Added a hack which makes OpenGL mode work under Wine for me + (Elias Pschernig). + +- Add support for some al_get_display_options in D3D port. + +Keyboard: + +- Don't send KEY_CHAR events for modifier and dead keys + (with contributions from torhu). + +- Don't send KEY_DOWN events for non-physical key events. + +- osx: Allow unicode entry (single keypresses only). + +- x11: Set the keycode field in KEY_CHAR events to the code of the last key + pressed, as stated in the documentation, even if the char is due to a + compose sequence. + +- x11: Get rid of historic behaviour where the unicode field is always zero + when Alt is held down. + +- Rename ALLEGRO_KEY_EQUALS_PAD to ALLEGRO_KEY_PAD_EQUALS for consistency. + +Mouse: + +- Add al_grab_mouse and al_ungrab_mouse. Implemented on X11 and Windows. + +- Allow the user configure a key binding to toggle mouse grabbing on a window. + +- Support horizontal mouse wheel on Windows (jmasterx). + +- Calculate Y position for al_set_mouse_xy correctly in OS X windowed mode + (X-G). + +- Use more appropriate CURSOR_LINK cursor on OS X (X-G). + +- Assign different button IDs for separate touches on iPhone (Michał Cichoń). + +- iphone: Remove fake mouse move events as they're unncessary and can cause + problems with user input tracking. + +Filesystem: + +- Clean up al_get_standard_path(): remove SYSTEM_DATA, SYSTEM_SETTINGS, + PROGRAM paths; add RESOURCES and USER_DOCUMENTS paths. + Use system API calls if possible. + +- Implement ALLEGRO_USER_DATA_PATH under Linux. Honor XDG_DATA/CONFIG_HOME + environment variables. + +- Fix al_make_directory on Windows due to problems with calls to stat() with + trailing slashes. + +Native dialogs addon: + +- Use string arguments to al_create_native_file_dialog() and + al_get_native_file_dialog_path() instead of ALLEGRO_PATH. + +- Enhance the Windows file selector (initial patch by Todd Cope): + + - Use Windows' folder selector for ALLEGRO_FILECHOOSER_FOLDER. + + - Implement patterns. + + - Display the title of the dialog that the user specified. + +Primitives addon: + +- Fix changing the D3D blender state without updating the cached state. + +TTF addon: + +- Align glyphs in ttf font sheets so as to work around problems with forced + S3TC compression with some OpenGL drivers (Elias Pschernig). + +Examples: + +- SPEED: add full screen flag, use standard paths for highscores and data. + +Build system: + +- Check PulseAudio backend will compile before enabling support. + +- Give a louder warning if FLAC/Vorbis/DUMB compile tests fail. + +Other: + +- Many leaks fixed on OS X. + +- Minor bug fixes and documentation updates. + + + +Changes from 5.0.0 RC3 to 5.0.0 RC4 (December 2010) +=================================================== + +The main developers this time were: Trent Gamblin, Matthew Leverton, +Elias Pschernig, Peter Wang. + +Graphics: + +- d3d: Don't generate intermediate resize events during modal resize loop. + +- Optimize D3D9 driver by caching blender state and scissor rectangle so + redundant calls to D3D9 functions are avoided (Michał Cichoń). + +- gl: Use glGenerateMipmapEXT to generate mipmaps when FBOs are used. + +- x11: Don't restore display mode if another fullscreen display is active. + +Input: + +- iphone: Reverse button/axis events that were swapped at some point. + +File I/O: + +- Change the way user code implements new ALLEGRO_FILE structures. + This adds al_create_file_handle and al_get_file_userdata. + +- Implement default ungetc behavior - used if the interface does not supply + its own. + +- Add al_fopen_interface. + +Memfile addon: + +- Implement ungetc. + +- Add rw file modes. + +- Rename header to allegro_memfile.h. + +- Add documentation. + +Image I/O addon: + +- Fix endian issues in TGA and Mac OS X image loaders. + +Other: + +- Use _NSGetExecutablePath for al_get_standard_path(ALLEGRO_EXENAME_PATH) on + OS X (Jeff Connelly). + +- Minor bug fixes and documentation updates. + + + +Changes from 5.0.0 RC2 to 5.0.0 RC3 (December 2010) +=================================================== + +The main developers this time were: Michał Cichoń, Trent Gamblin, Peter Wang. + +Graphics: + +- Honour subbitmap clipping rectangle under OpenGL (Elias Pschernig). + +- Fix an error in the Direct3D primitives blending. + +- al_set_new_window_position() did not have an effect for resizable + windows on X11. + +- Fix windows only showing up on first monitor on X11 (Thomas Fjellstrom). + +- Implement al_get_monitor_info() for iDevices. + +Input: + +- Separate character inputs from physical key down events. This removes + unichar and modifiers fields from ALLEGRO_EVENT_KEY_DOWN, and replaces + ALLEGRO_EVENT_KEY_REPEAT by ALLEGRO_EVENT_KEY_CHAR. We decided this design + flaw was better fixed now than later. + +- Make Mac OS X keyboard driver properly distinguish key down and key repeat + events. + +TTF addon: + +- Respect ALLEGRO_NO_PREMULTIPLIED_ALPHA flag when loading TTF fonts. + +Other: + +- Fix returning a garbage pointer in maybe_load_library_at_cwd + (Vadik Mironov). + +- Remove dependency on dxguid. + +- Minor compilation fixes and documentation updates. + + + +Changes from 5.0.0 RC1 to 5.0.0 RC2 (December 2010) +=================================================== + +The developers this time were: Trent Gamblin, Elias Pschernig and Peter Wang. + +System: + +- Add al_is_system_installed and hide al_get_system_driver. + +- Prevent 'DLL hijacking' security issue on Windows. + +Graphics: + +- Change to using premultiplied alpha by default. The new bitmap flag + ALLEGRO_NO_PREMULTIPLIED_ALPHA was added. + +- Change the value of ALLEGRO_VIDEO_BITMAP to non-zero. + +- Change al_get_opengl_version to return a packed integer. + +- Made al_get_opengl_version return an OpenGL ES version (if using OpenGL ES) + rather than an attempted estimate at a desktop GL version. + +- Added function al_get_opengl_variant that returns either + ALLEGRO_DESKTOP_OPENGL or ALLEGRO_OPENGL_ES. + +- Make al_have_opengl_extension return bool. + +- Fix OpenGL graphics mode height value on Windows. + +- Only try to create one Direct3D display at a time. + +- Make screensaver activate on Windows Vista and above unless inhibited. + +- Avoid potential divide-by-zeroes when computing the refresh rate in X11 + video modes. + +Events: + +- Delete an incorrect mutex destroy in al_unregister_event_source. + +Input: + +- Revert the joystick driver used on OS X 10.4 to the pre-hotplugging version, + rather than one which contained an earlier attempt at implementing + hotplugging. Select the 10.4 or greater joystick driver at runtime. + +iPhone: + +- Added two iPhone-specific functions: al_iphone_override_screen_scale and + al_iphone_program_has_halted. + +Image I/O addon: + +- Made the iPhone and OSX image loaders not try and correct colors to some + arbitrary color space, but instead use the values directly from the image. + +Native dialogs addon: + +- Tolerate null display in al_show_native_file_dialog on Windows. + +- Make GTK native dialog implementation only call GTK from a single thread. + +- Define al_show_native_message_box to be usable without installing Allegro. + +Primitives addon: + +- Make primitives addon compilable again without OpenGL. + +Examples: + +- ex_ttf: Test the monochrome flag. + +- Work around problems with MSVC and UTF-8 string literals. + ex_utf8 is now not built under MSVC. + +- Don't use WIN32 executable type on examples that require the console + (David Capello). + +Other: + +- Minor bug fixes and documentation updates. + + + +Changes from 4.9.22 to 5.0.0 RC1 (November 2010) +================================================ + +The developers this time were: Trent Gamblin, Evert Glebbeek, Elias Pschernig, +Paul Suntsov, Peter Wang. + +Graphics: + +- Make al_resize_display keep the original resolution (or change back) if it + can't set the users request, on Windows. + +- Do not emit ALLEGRO_DISPLAY_RESIZE events from the Windows and X11 display + drivers when using al_resize_display. + +- [X11] Make al_get_num_display_modes and al_get_display_mode work if the + adapter is set to default. Right now there was no way to query the modes of + the default monitor. + +- [X11] Use _NET_WM_STATE_FULLSCREEN hint for "true" fullscreen displays. + Enable mouse grabbing in fullscreen modes. + +- Added ALLEGRO_EVENT_DISPLAY_ORIENTATION and implement it on iOS. + +- Dennis Busch fixed a problem with displays not showing up on the + primary display by default in some dual head setups, on Windows. + +- Increase the precision of texture coordinate deltas in the software triangle + renderer, from floats to doubles. + +- Remove al_get_frontbuffer(). It wasn't implemented anywhere. + +- Implement min/mag filter and mipmap flags for Direct3D. + +Input: + +- Report correct initial mouse position if a display is created with the mouse + pointer inside, or if the mouse routines are installed after a display is + created (X11, Windows). + +- John Murphy fixed improperly mapped axes on the Windows joystick driver. + +Events: + +- Do not register user event sources with the destructor system as it cannot + work reliably. User event sources must be destroyed manually. + +Filesystem: + +- Make al_get_fs_entry_name and al_get_current_directory return strings + instead of ALLEGRO_PATH. + +- Make al_make_directory create parent directories as needed. + +- Fix al_create_fs_entry to not trim the root path "/" down to the empty + string with the stdio backend. + +Path routines: + +- Remove al_make_path_absolute and replace it by al_rebase_path. + +- Remove undocumented behavior of setting a default organization name of + "allegro" for all apps. + +- Correctly return standard paths as directories on OS X. + +Threads: + +- Rename al_wait_cond_timed to al_wait_cond_until to match al_wait_cond_until. + +Config routines: + +- Add a blank line between sections when writing out a config file. + +Other core: + +- Move the Windows event loops back into the same thread as the D3D event + loop. It's a requirement of D3D, else you can get crashes as I was when + resetting the device (like tabbing away from a fullscreen app). + +- Add some missing standard entries to the OS X menu bar (the "hide", "hide + others" and the window list, mainly). + +Audio addon: + +- Automatically stop sample instances which point to a buffer of a sample + which is about to be destroyed with al_destroy_sample. + +- alsa: Resume properly after suspending. + +Image I/O addon: + +- Make GDI+ support compile cleanly with the headers that come with MinGW + package w32api-3.15. + +- Speed up PNG and BMP saving, and NSImageFromAllegroBitmap loading. + +TTF addon: + +- Add a flag for loading TTFs without anti-aliasing (ALLEGRO_TTF_MONOCHROME). + +Primitives addon: + +- Fix several failed sub-bitmap related unit tests on Windows. + +- Made thick outlined triangles look nicer when the triangles are very thin. + +- Add a debug-only check for primitives addon initialization to aid in code + portability. + +Examples: + +- Added example demonstrating the effect of premultiplied alpha. + +- Make 'F' toggle fullscreen window in SPEED (in-game). + +- Minor improvements to the a5teroids demo. + +Documentation: + +- Many documentation updates. + +- Add list of contributors and a readme for packagers. + +- Make make_doc tool build cleanly on MSVC, and work around a problem with + recent version of Pandoc on Windows. + +- Improve styling of PDF output. + +- Add generated man pages to archives. + +Bindings: + +- Implemented array types in the Python wrapper. + + + +Changes from 4.9.21 to 4.9.22 (September 2010) +============================================== + +The developers this time included: Michał Cichoń, Trent Gamblin, +Evert Glebbeek, Angelo Mottola, Elias Pschernig, Paul Suntsov and Peter Wang. + +System: + +- Allow the X11 port to initialise without an X server connection. + +Graphics: + +- Fix many bugs with bitmap locking. + +- Fix many bugs to do with transformations, flipping and clipping. + +- Fix many bugs to do with sub-bitmaps as source and destination. + +- Renamed al\_draw\_[tinted\_]rotated_scaled_bitmap to + al\_draw\_[tinted\_]scaled_rotated_bitmap to match the parameter order. + +- Reimplemented bitmap software rendering routines using newly optimised + software triangle renderer, formerly in the primitives addon. + +- Add pixel_size field to ALLEGRO_LOCKED_REGION. + +- Fix bugs to do with pixel alignment on OpenGL. + +- Fix OpenGL pixel transfer of 15 bpp formats, where Allegro does not Allegro + does not care whether the unused bit is set or not, but when transferring to + OpenGL it will be interpreted as an alpha bit. + +- Disabled support for drawing a bitmap into itself. + +- Changed specification of al\_draw_*bitmap to not allow transformation and + ignore blending/tinting when the screen itself is being drawn (except when + drawn into a memory bitmap). + +- Allow bitmap regions to be outside the bitmap area in drawing routines. + +- Added al_add_new_bitmap_flag convenience function. + +- Added three new bitmaps flags ALLEGRO_MAG_LINEAR, ALLEGRO_MIN_LINEAR, + ALLEGRO_MIPMAP. Removed the config settings for linear/anisotropic min/mag + filtering. DirectX side not yet updated. + +- Register destructors for bitmaps, so they will be implicitly destroyed when + Allegro is shut down. This was only true for some bitmaps previously. + +- Don't allocate memory buffers for video bitmaps when using OpenGL. + +- Make al_get_opengl_extension_list() return NULL if called on a non-GL display. + +- Fix al_create_display for OpenGL forward compatible contexts. + +- Add al_set_current_opengl_context as an explicit way to set the OpenGL + context. + +- Rename al_is_opengl_extension_supported to al_have_opengl_extension. + +- Produce more accurate/correct color when going from less to more bits per + component. + +- Fix al_set_new_window_position() everywhere. + +- Avoid potential deadlock if resizing window to the same size on X11. + +- Fixed turning off vsync in X11. + +- Added al_is_d3d_device_lost function. + +- Dynamically load dinput and d3d DLLs on Windows. + +- Replaced PeekMessage with GetMessage in window event loops for the D3D and + WGL drivers (David Capello). + +Input: + +- Added hotplugging support for joysticks on Linux, Windows and OS X. + +- Added al_reconfigure_joysticks function. + +- Merged all joystick devices under a single joystick event source. + +- Removed al_get_joystick_number. + +- Add al_is_joystick_installed. + +- The OS X joystick driver was rewritten; it requires OS X 10.5. + The older driver still exists for OS X 10.4 and earlier but is in a + semi-updated state with regards to hotplugging. + +- Allow user to override joystick device paths in the config file (Linux). + +- Fix iphone touch input and clipping for modes other than w=768,h=1024. + +- Fixed missing mouse movement messages on IPhone on touch-up/down. Also + changed how mouse buttons are reported - always as button 1 now. + +Config: + +- Give config iterators proper types instead of void *. + +- Make al_get_system_config() always return non-NULL if a system driver is + installed. + +Events: + +- Rename al_event_queue_is_empty to al_is_event_queue_empty + (with compatibility define). + +Timers: + +- Add al_add_timer_count function. + +- Rename al_timer_is_started to al_get_timer_started. + +- Rename al_current_time to al_get_time (with compatibility define). + +File I/O: + +- Add al_open_fs_entry to open a file handle from an FS_ENTRY. + +- Add al_fclearerr. + +- Set ALLEGRO_FILEMODE_HIDDEN flag on entries for file names beginning with + dot (OS X). + +- Remove al_is_path_present, al_fs_entry_is_directory, al_fs_entry_is_file + (all trivial). + +Primitives addon: + +- Optimised most of the software rendering routines by a lot. + +- Triangle drawer was skipping pixels in very thin triangles. + +- Handle lost d3d devices better. + +- Fix some bugs found during testing. + +Image I/O addon: + +- Fix native image loader on Mac OS X: images that were not 72 dpi would be + rescaled to a smaller size. + +- Added native bitmap saving support for OSX. + +- Fix jpeg saving when locked region has negative pitch. + +Native dialogs addon: + +- Add Windows and OS X text log implementations. + +- Add ALLEGRO_FILECHOOSER and ALLEGRO_TEXTLOG types instead of conflating + them into ALLEGRO_NATIVE_DIALOG. + +- Fix race condition in al_open_native_text_log. + +- Rename al_destroy_native_dialog to al_destroy_native_file_dialog. + +- Rename al_get_native_dialog_event_source to + al_get_native_text_log_event_source. + +- Speed up text log appending by making the reader/writers asynchronous. + +- Register destructors for file chooser and text log dialogs. + +- Fix file chooser on Windows returning multiple selections with slashes + appended to filenames. If an initial path was specified then the dialog + wouldn't open at all; fixed. + +- Let native dialog functions fail gracefully. + +Audio addons: + +- Init destructors even if audio driver fails to install. + +- Dynamically load dsound DLL on Windows. + +Font addons: + +- Added al_shutdown_ttf_addon. + +- Prevent SIGSEGV for double-closing a file in the TTF addon if it is not a + valid font file. + +- Make al_grab_font_from_bitmap not cause a segmentation fault if the bitmap + is garbage. + +- Some TTF fonts would not render right at small sizes; fixed. + +- Make al_destroy_font ignore NULL. + +Tests: + +- Added a test suite (finally). + +- Add a shell script to produce test coverage results using lcov. + +Examples: + +- Add ex_haiku, an example based on Mark Oates's Haiku game. + Mark generously agreed to let us include it as an Allegro example. + +- Added a new example ex_joystick_hotplugging. + +- Added a new example ex_filter. + +- Make ex_fs_window work on MSVC. + +- Allow a5teroids to run without audio, or if audio data doesn't load. + +Build system: + +- Re-added CMake option that allows forced static linking of libFLAC. + +- Replaced the old iphone xcode project with a cmake iphone toolchain. + +Documentation: + +- Many updates to the reference manual. + +Bindings: + +- Added a workaround to the Python wrapper for a Mingw bug. + + + +Changes from 4.9.20 to 4.9.21 (July 2010) +========================================= + +The main developers this time were: Trent Gamblin, Matthew Leverton, +Elias Pschernig, Paul Suntsov, Peter Wang. + +Graphics: + +- Fixed the mis-termed "blend color". There is no more color state. + + - al_set*_blender functions lose the color parameter. + + - Added 5 new bitmap drawing functions al_draw_tinted*_bitmap with a color + parameter. The parameter is used just like the "blend color" before. + + - All text drawing functions gain a color parameter and use it like they + used the "blend color" before. + + - Primitive drawing functions previously sometimes (and sometimes not) used + the "blend color". Not any longer. + +- Make the current blending mode thread-local state instead of per-display + state. + +- Add explicit display arguments to functions which require a display, + but don't require the rendering context to be current. + +- Make al_set_target_bitmap change the current display as necessary. + al_set_target_bitmap(NULL) releases the rendering context. + +- Add al_set_target_backbuffer as a convenience. + +- Remove al_set_current_display. + +- Give each bitmap its own transformation, i.e. every bitmap has a + transformation, which is in effect when that bitmap is the target. + +- Remove sub-bitmap clip-to-parent restriction on create. Add out-of-bounds + blitting support to memory bitmaps. + +- Merge sub-bitmap and parent bitmap clipping; clip source bitmap to + (0,0)-(w,h); fix flipping to/from clipped bitmaps. + +- Made mouse cursors independent of displays. You may create cursors without + a display, and you may use a cursor with any display. + +- Rename al_{set,get}_current_video_adapter to *new_display_adapter for + consistency. + +- Move the new display video adapter and new window position to thread-local + state, like other new display parameters. Make al_store_state also save + those parameters with ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS. + +- Rename al_transform_transform to al_compose_transform. Switched the order + of parameters in al_compose_transform and al_copy_transform to match the + rest of the transform functions. + +- Made memory bitmap manipulation without a display possible (again?). + +- Fixed window resizing in D3D driver. Simplify resize-postponing on Windows. + +- Make al_create_display abort early when the new_display_adapter is + greater than the screen count (X11). + +- Added ALLEGRO_MINIMIZED flag to the X11 port. + +- Fixed OpenGL version string parsing (bug #3016654). + +Other core: + +- Renamed al_install_timer to al_create_timer, and al_uninstall_timer to + al_destroy_timer. + +- Rename al\_{get,set}\_{appname,orgname} to \*app_name and \*org_name. + +- Fix assertion failure in al_create_mutex_recursive on Windows (spoofle). + +Primitives addon: + +- Made the D3D driver of the primitives addon work with multiple displays. + Also made it handle the display being destroyed properly. + +- Simplified shader recreating on thread destruction when using the primitives + addon with D3D. + +- Avoid double free when shutting down the primitives addon multiple times. + +- Older Intel cards don't implement DrawIndexedPrimitiveUP correctly. + Altered the D3D code to work around that. + +Audio addon: + +- Allow setting the DirectSound buffer size via allegro5.cfg. + +Image addon: + +- Make GDI+ image loader work with MinGW. + +Font addon: + +- Nicolas Martyanoff added al_get_font_descent/ascent functions which query + per-font properties. Previously it was necessary to call + al_get_text_dimensions (which now just reports the text dimensions as it + should). + +Native dialogs addon: + +- Add text log window functions (GTK only for now). + +Documentation: + +- Many updates to the reference manual. + +- Improve styling and add Allegro version to HTML pages. + +- Separated readme_a5.txt into multiple files, and hopefully improve them. + +Build system: + +- Remove INSTALL_PREFIX. Windows users can now use CMAKE_INSTALL_PREFIX to + set the install path. + +- Allow the user to place dependencies in a subdirectory "deps", which will + be automatically searched. + +Examples: + +- Use text log windows in many examples. + +- Add ex_noframe: test bitmap manipulation without a display. + +Bindings: + +- Update Python bindings. + + + +Changes from 4.9.19 to 4.9.20 (May 2010) +======================================== + +The developers this time were: Thomas Fjellstrom, Evert Glebbeek, +Matthew Leverton, Milan Mimica, Paul Suntsov, Trent Gamblin, Elias Pschernig, +Peter Wang. With significant contributions from Michał Cichoń. + +Core: + +- Add al_malloc, al_free, et al. These are now used consistently throughout + Allegro and its addons. + +- Replace al_set_memory_management_functions by a simpler function, + al_set_memory_interface. + +- Renamed some D3D/Windows specific functions to follow the al_{verb}_{stuff} + convention. + +Graphics: + +- Move image I/O framework to core, i.e. al_load_bitmap, al_save_bitmap and + bitmap file type registration. Image codecs remain in allegro_image. + +- Added a simple display capabilities querying capability to + al_get_display_option: ALLEGRO_MAX_BITMAP_SIZE, ALLEGRO_SUPPORT_NPOT_BITMAP, + ALLEGRO_CAN_DRAW_INTO_BITMAP, ALLEGRO_SUPPORT_SEPARATE_ALPHA. + (OpenGL only for now) + +- Fix in OpenGL 3.0 context creation. + +- Make the extensions mechanism compatible with OpenGL version >= 3. + Declared symbols needed by OpenGL 3.2 and 3.3 and brought OpenGL extensions + up to date. + +- Fix an assertion in _al_draw_bitmap_region_memory so it does not trigger + when source and destination are the same bitmap. + +- Fix some locking issues by setting GL_PACK_ALIGNMENT and GL_UNPACK_ALIGNMENT + before reading/writing pixels. + +- Partial implementation of ALLEGRO_FULLSCREEN_WINDOW on OS X (Snow Leopard, + probably Leopard). + +- Started X11 fullscreen support (resolution switching). + +- Fix handling of X11 size hints. + +- Fixed a deadlock related to fullscreen windows under X11 caused by using a + nested lock for a condition variable. + +- Use _NET_WM_ICON to set icon on X11 instead of XSetWMHints. + +- Get the iPhone OpenGL version more properly. Only use separate blending on + iPhone with OpenGL ES 2.0+. + +- Release the splash view and windows on iPhone, which makes backgrounding + Allegro apps on OS 4.0 work. + +- Updated iphone port for IPad (only tested in the simulator). + +Input: + +- Disabled Raw Input code in Windows. Mouse events now reflect system cursor + movements even in fullscreen mode. + +- Prevent late WM_MOUSELEAVE notifications from overriding mouse state display + field (Windows). + +- Update pollable mouse state with axes events as well as button events on + iPhone. + +Filesystem: + +- Made the filesystem entry functions work under Windows even if the name + passed to al_create_fs_entry has a trailing slash or backslash. + +Config routines: + +- Add al_{load,save}_config_file_f. + +- Reorder al_save_config_file* arguments to match al_save_bitmap and + al_save_sample. + +- Optimise config routines to work well for thousands of keys/sections. + +Image addon: + +- Added a GDI+ implementation of the image codecs, which will be used in + favour of libjpeg/libpng if Allegro is compiled with MSVC. Then + allegro_image will not require JPEG/PNG DLLs at runtime. + +- Removed format specific image functions. + +- Fixed bug in native png loader on iphone: was using the source color space + instead of the target color space which made it fail whenever they differed + (alpha-less paletted pictures). + +- Add an autorelease pool around iphone native image loading to stop memory + leaks. + +Font addons: + +- Sever the tie between allegro_font and allegro_image. + The user needs to initialise the image addon separately now. + +- Rename al_load_ttf_font_entry to al_load_ttf_font_f. + +- Fixed problem with glyph precision after applying transformations in the ttf + addon. + +Primitives addon: + +- Added al_init_primitives addon function. This is now required. + +- Removed ALLEGRO_PRIM_COLOR; ALLEGRO_COLOR can now be used where it was + required. + +- v textures coordinates were off for OpenGL non-power-of-two textures. + +- Free the vertex cache in al_destroy_display on X11. + +- Added the dummy vertex shader support to D3D driver of the primitives addon. + Without this, custom vertices either resulted in warnings or outright + crashes on some systems. + +- Bring D3D driver up to speed a little bit: transformations now work properly + with sub-bitmap targets; the half-pixel offset now properly interacts with + transformations; al_set_target_bitmap does not clear the transformation; the + proper transformation is set at display creation. + +- Cull the primitives that are completely outside the clipping region. + +- Scale the numbers of vertices for the curvy primitives with the scale of the + current transformation. + +Audio addon: + +- Remove driver parameter from al_install_audio. + +- Rename al_get_depth_size to al_get_audio_depth_size. + +- Rename al_get_audio_stream_buffer to al_get_audio_stream_fragment. + +- Many improvements to AQueue driver. + +Audio codecs: + +- Add MOD/S3M/XM/IT file support, using the DUMB library. + +- Revert to a monolithic allegro_acodec addon, i.e. remove separate + allegro_flac, allegro_vorbis addons. WAV file support is in allegro_acodec. + +- Implement DLL loading for FLAC/Vorbis/DUMB on Windows. allegro_acodec will + load the DLL at runtime to enable support for that format. If your program + does not require said format, you don't need to distribute the DLL. + +- Remove format-specific loader/saver audio codec functions. + +- Make acodec loaders have consistent file closing behaviour. + +- Optimised wave file loading. + +Examples: + +- Make SPEED port run acceptably on graphics drivers without FBOs. + +Documentation: + +- Added documentation for the public Direct3D specific functions. + +- Documented ALLEGRO_OPENGL_3_0 and ALLEGRO_OPENGL_FORWARD_COMPATIBLE. + +Other: + +- Many bug and documentation fixes. + + + +Changes from 4.9.18 to 4.9.19 (April 2010) +========================================== + +The main developers this time were: Milan Mimica, Trent Gamblin, Paul Suntsov, +Peter Wang. Other contributions from: Evert Glebbeek and Shawn Hargreaves. + +Graphics: + +- Implemented support for transformations for memory bitmaps. + +- Transformations now work properly when the target bitmap is a sub-bitmap in + OpenGL (still broken in D3D). Also fixed OpenGL bitmap drawing in the same + scenario (it used to always revert to software drawing). + +- Use the memory drawers when the source bitmap is the backbuffer with the + rotated/scaled bitmaps. + +- Make al_put_pixel clip even if the bitmap is locked, which was the reason + why software primitives were not clipping. + +- Added al_put_blended_pixel, the blended version of al_put_pixel. + +- Sub bitmaps of sub bitmaps must be clipped to the first parent. + +- Don't clear the transformation when setting the target bitmap in OpenGL. + +- Implemented ALLEGRO_NOFRAME and ALLEGRO_FULLSCREEN_WINDOW in WGL. + +- Set the ALLEGRO_DISPLAY->refresh_rate variable for fullscreen modes under D3D. + +- Make d3d_clear return immediately if the display is in a lost state. + +- Rewrote the function that reads the OpenGL version so it works for + previously unrecognised versions, and future versions. + +- Check for framebuffer extension on iPhone properly. + +- Fixed locking bugs on iPhone. allegro_ttf works now. + +Input: + +- Removed al_set_mouse_range. + +- Don't call al_get_mouse_state if the mouse driver isn't installed (Windows). + +- Send events even when the mouse cursor leaves the window, while any buttons + are held down (Windows and Mac OS X; X11 already did this). + +- Allow mouse presses and accelerometer data simultaneously. (iPhone) + +File I/O: + +- Optimise al_fread{16,32}* by using only one call to al_fread each. + +- Optimise al_fgetc() for stdio backend. + +Path: + +- Fix an infinite loop in _find_executable_file when searching for the + executable on the PATH (Alan Coopersmith). + +Primitives addon: + +- Made the software driver for the primitives addon check for blending + properly. Also, fixed two line shaders. + +- Made the D3D driver thread-safe. The whole addon should be thread-safe now. + +- The addon now officially supports 3D vertices, even though the software + component can't draw them yet. + +- Changed the way the primitives addon handles the OpenGL state (fixes a few + bugs and makes life easier for raw-OpenGL people) + +Image addon: + +- Optimised BMP, PCX, TGA loaders. + +- Fix loading 16-bit BMP files. + +- Fix loading grayscale TGA images. + +- Nial Giacomelli fixed a bug where images could be corrupt using the native + Apple image loader (iPhone). + +Audio addon: + +- Add al_is_audio_installed. + +- Fix al_attach_sample_instance_to_mixer for int16 mixers. + +- Implement attaching an INT16 mixer to another INT16 mixer. + +- Handle conversion when an INT16 mixer is attached to a UINT16 voice. + +Build system: + +- Add an option to disable Apple native image loader (iPhone and OS X). + +- Add ttf addon target to iPhone xcode project. + +Examples: + +- Special contribution from Shawn "the Progenitor" Hargreaves. + + + +Changes from 4.9.17 to 4.9.18 (March 2010) +========================================== + +The main developers this time were: Trent Gamblin, Elias Pschernig, Evert +Glebbeek, Peter Wang. Other contributions from: Milan Mimica, Paul Suntsov, +Peter Hull. + +Graphics: + +- Fixed broken drawing into memory bitmaps as access to the global + transformation required an active display. Now both transformation and + current blending mode are stored in the display but provisions are made for + them to also work if the current thread has no display. + +- Fixed a bunch of clipping problems with OpenGL, especially with sub-bitmaps. + +- Fix bug in OpenGL FBO setup when the target bitmap is the sub-bitmap of a + bitmap with an FBO. + +- Fixed crash in al_get_num_display_modes under OSX 10.5. + +- Fixed some problems in _al_convert_to_display_bitmap that caused problems in + WGL FS display resize. + +- Fixed al_set_current_display(NULL) on WGL. + +- Added subtractive blending. al_set_blender() takes another parameter. + +- Added ALLEGRO_FULLSCREEN_WINDOW display flag (X11 and D3D for now). + +- Allow changing ALLEGRO_FULLSCREEN_WINDOW with al_toggle_display_flag. + +- Figured out how to switch display modes using Carbon on OS X 10.6. + +- Stop the OpenGL driver on iPhone from changing the currently bound FBO + behind our back when locking a bitmap. + +- Prevent screen flicker at app startup by simulating the splash screen + (iPhone). + +Input: + +- Added "pressure" field to the mouse event struct and mouse state, which can + be used with pressure sensitive pointing devices, i.e. tablets/stylus + (currently OS X only). + +- Report scroll ball "w" position in mouse event struct, on OS X. + +- Removed OS X 10.1 specific code from mouse driver. We don't support OS X + 10.1 any more. + +- Fix building of Linux joystick driver on some systems. + +Threads: + +- Fix a problem when al_join_thread() is called immediately after + al_start_thread(). The thread could be joined before the user's thread + function starts at all. + +- Fix a possible deadlock with al_join_thread() on Windows (thanks to Michał + Cichoń for the report). + +- Fix some error messages running threading examples on OS X. + +Other core: + +- Added version check to al_install_system. + +- Rename al_free_path to al_destroy_path for consistency. + +- Make it possible to have an empty organization name with al_set_org_name(). + +- Changed implementation of AL_ASSERT to use POSIX-standard assert instead. + +- Removed al_register_assert_handler. + +- Fix timer macros which did not parenthesize their arguments. + +- Make stricmp, strlwr, strupr macros conditionally defined. + +Audio addon: + +- Rename al_attach_sample_to_mixer to al_attach_sample_instance_to_mixer. + +- Fix a premature free() when detaching samples and other audio objects. + +- Fix mixers attaching to mixers. + +- Pass correct number of samples to mixer postprocess callback. + +- AudioQueue code was not compiled even though version requirements may have + been met (OS X). + +Primitives addon: + +- Make high-level primitives functions thread safe. (note: the DirectX driver + is not yet thread safe) + +- Fix a bug causing crashes on Windows 7 when using the primitives addon and + Direct3D (Invalid vertex declarations were being used). + +- Fixed another issue with primitives drawing to memory bitmaps. + +- Hopefully fix the bitmap clipping bugs, and make the D3D and OGL/Software + outputs to be near-identical again. + +Image addon: + +- Added a "native loader" for MacOS X that uses the NSImage bitmap loading + functions. In addition to .png and .jpg, this allows us to read a whole zoo + of image formats (listed in allegro.log). + +- Add native support for tif, jpg, gif, png, BMPf, ico, cur, xbm formats to + under IPhone. + +- Fixed an over-zealous ASSERT() that disallowed passing NULL to + al_register_bitmap_loader() despite this being an allowed value. + +- Avoid using a field which is deprecated in libpng 1.4. + +Color addon: + +- Make al_color_name_to_rgb return a bool. + +Native dialogs addon: + +- Fixed some erratic behaviour and crashes on OS X. + +Build system: + +- Set VERSION and SOVERSION properties on targets to give Unix shared + libraries proper sonames. + e.g. liballegro[_addon].so.4.9, liballegro[_addon].4.9.dylib + +- Static libraries are now named without version number suffixes + to minimise the differences with the shared libraries, which no longer + have the versions in their base names. + e.g. liballegro[_addon]-static.a, allegro[_addon]-static.lib + +- Windows import libraries are also named without version suffixes, e.g. + liballegro[_addon].a, allegro[_addon].lib + +- DLLs are named with a short version suffix, not the full version. + e.g. allegro-4.9.dll instead of allegro-4.9.18.dll + +- Add support for Mac OS X frameworks (untested), which are enabled with + WANT_FRAMEWORKS and WANT_EMBED. There is one framework per addon. + +- Search for static OGG/Vorbis libraries built with MSVC named + libogg_static.lib, etc. + +- Updated iPhone XCode project. + +Examples: + +- ex_mixer_pp: New example to test mixer postprocessing callbacks. + +- ex_threads: Make it more visually interesting and test out per-display + transformations. + +- ex_ogre3d: New example demonstrating use of Ogre graphics rendering + alongside Allegro (currently GLX only). Commented out in the build system + for now. + +- ex_fs_window: New example to test ALLEGRO_FULLSCREEN_WINDOW flag and + al_toggle_display_flag. + +- ex_blend2: Updated to test subtractive blending, including scaled/rotated + blits and the primitives addon. + +- ex_mouse_events: Show "w" field. + +- ex_prim: Added possibility to click the mouse to advance screens (for iPhone). + +- ex_vsync: Display config parameters and warning. + +- ex_gldepth: Make the textures appear again though we're not sure why they + disappeared. + +Documentation: + +- Many documentation updates. + +- Add which header file and which library to link with for each page of the + reference manual. + +- Minor improvements to HTML styling and man page output. + + + +Changes from 4.9.16 to 4.9.17 (February 2010) +============================================= + +The main developers this time were: Trent Gamblin, Elias Pschernig, Evert +Glebbeek, Paul Suntsov, Peter Wang. + +Core: + +- Removed END_OF_MAIN() everywhere. + + For MSVC, we pass a linker option through a #pragma. + + On Mac OS X, we rename main() and call it from a real main() function in + the allegro-main addon. The prototype for main() for C++ applications + should be "int main(int, char **)", or the code will not compile on OS X. + For C, either of the normal ANSI forms is fine. + + \#define ALLEGRO_NO_MAGIC_MAIN disables the \#pragma or name mangling, so + you can write a WinMain() or use al_run_main() yourself. + +Graphics: + +- Fixed a bug in the OpenGL driver where al_draw_bitmap() wouldn't handle + blitting from the back buffer. + +- Changing the blending color now works with deferred drawing (Todd Cope). + +- Avoid some problems with window resizing in Windows/D3D. + +- Added al_get_d3d_texture_position. + +- Fixed bug under X11 where al_create_display() would always use the display + options from the first al_create_display() call. + +- Properly implemented osx_get_opengl_pixelformat_attributes(). + +- Fixed automatic detection of colour depth on OS X. + +- Fixed al_get_num_display_modes() on Mac OS X 10.6. + +- Removed al_get_num_display_formats, al_get_display_format_option, + al_set_new_display_format functions as they can't be implemented on + OSX/iPhone/GPX ports (and were awkward to use). + +- Replaced al_toggle_window_frame function with a new function + al_toggle_display_flags. + +- al_load_bitmap() and al_convert_mask_to_alpha() no longer reset the current + transformation. + +- Add a minimize button to all non-resizable windows on Windows. + +- The wgl display switch-in/out vtable entries were swapped (Milan Mimica). + +Input: + +- Some keycodes were out of order in src/win/wkeyboard.c + +- Fixed mouse range after resizing window on Windows. + +- Fixed (or worked around) a joystick axis detection problem on Mac OS X. + +- Change timer counts from 'long' to 'int64_t'. + +File I/O: + +- Remove `ret_success' arguments from al_fread32be/le. + +allegro-main addon: + +- Added an "allegro-main" addon to hold the main() function that is required + on Mac OS X. This way the user can opt out of it. + +Primitives addon: + +- Added support for sub-bitmap textures in OpenGL driver. + +- Added support for sub-bitmap textures in D3D driver. + Made D3D sub-bitmaps work better with user D3D code. + +Audio addons: + +- Changed the _stream suffix to _f in the audio loading functions. + +- Added the stream versions of loading functions for wav, ogg and flac. + +- Rename audio I/O functions to al_load_{format}, al_save_{format}, + al_load_{format}_f and al_save_{format}_f. + +- Added al_load_sample_f, al_save_sample_f, al_load_audio_stream_f and the + related functions. + +- Fixed a bug where al_save_sample was improperly handling the extension. + +- al_drain_audio_stream would hang on an audio stream in the 'playing' state + (the default) which wasn't attached to anything. + +- Fixed a potential deadlock on destroying audio streams by shutting down the + audio driver. + +- Comment out PA_SINK_SUSPENDED check, which breaks the PulseAudio driver, at + least on Ubuntu 9.10. + +- Replace unnecessary uses of `long' in audio interfaces. + +Image addons: + +- Fixed return values of al_save_bmp_f and al_save_pcx_f being ignored. + +- Changed the _stream suffix to _f in the image loading functions. + +TTF addon: + +- Drawing TTF fonts no longer resets the current transformation. + +Build system: + +- Add the CMake option FLAC_STATIC, required when using MSVC with a static + FLAC library. + +- Link with zlib if linking with PhysicsFS is not enough. + +- Updated iPhone project files. + +Documentation: + +- Many documentation updates. + +Examples: + +- ex_display_options: Added mouse support, query current display settings, + display error if a mode can't be set. + +Bindings: + +- Made the Python wrapper work under OSX. + +- Added a CMake option to build the Python wrapper. + +- Added al_run_main() mainly to support the Python wrapper on OSX. + + + +Changes from 4.9.15.1 to 4.9.16 (November 2009) +=============================================== + +The main developers this time were: Trent Gamblin and Paul Suntsov. + +Graphics: + +- Fixed clipping of the right/bottom edges for the software primitives. + +- Enable sub-pixel accuracy for rotated blitting in software. + +- Made the D3D output look closer to the OGL/Software output. + +- OpenGL driver now respects the 'linear' texture filtering configuration + option. Anisotropic is interpreted as linear at this time. + +- Added deferred bitmap drawing (al_hold_bitmap_drawing). + +- Made the font addons use deferred bitmap drawing instead of the primitives + addon, removing the link between the two addons. + +- Changed al_transform_vertex to al_transform_coordinates to make the + function more versatile. + +- Transfered transformations from the primitives addon into the core. + Added documentation for that, as well as a new example, ex_transform. + Transformations work for hardware accelerated bitmap drawing (including + fonts) but the software component is not implemented as of yet. + Also fixed some bugs inside the code of the transformations. + +- Increase performance of screen->bitmap blitting in the D3D driver. + +- Fixed a strange bug with textured primitives (u/v repeat flags were being + ignored on occasion). + +- Added ALLEGRO_VIDEO_BITMAP for consistency. + +Input: + +- Work around a memory leak in iPhone OS that occurs when the accelerometer + is on during touch input. + +Other core: + +- Don't #define true/false/bool macros in C++. + +Audio addon: + +- Some minor cleanups to the Audio Queue driver. + + + +Changes from 4.9.15 to 4.9.15.1 (October 2009) +============================================== + +- Fixed a problem building on MinGW (dodgy dinput.h). + + + +Changes from 4.9.14 to 4.9.15 (October 2009) +============================================ + +The main developers this time were: Trent Gamblin, Elias Pschernig, Matthew +Leverton, Paul Suntsov, Peter Wang. + +Core: + +- Set the initial title of new windows to the app name. + +- Add al_set/get_event_source_data. + +- Make locking work on bitmaps that didn't have an FBO prior to the call on + iPhone. + +- Make al_get_opengl_fbo work on iPhone. + +- Made iPhone port properly choose a visual (so depth buffer creation works). + +Font addon: + +- Improved drawing speed for longish strings. The font addon now depends on + the primitives addon. + +Primitives addon: + +- Made the ribbon drawer handle the case of extremely sharp corners more + gracefully. + +- Make al_draw_pixel use blend color in the D3D driver. + +- Added POINT_LIST to the primitive types. + +- Various fixes for the D3D driver: fixed line loop drawing; made the indexed + primitives a little faster; added workabouts for people with old/Intel + graphics cards. + +- Fall back to software if given a memory bitmap as a texture. + +- Removed OpenGL state saving code, it was causing massive slowdown when + drawing. Also removed glFlush for the same reason. + +Audio addon: + +- Added PulseAudio driver. + +- Support AudioQueue driver on Mac OS X. + +- Add al_uninstall_audio exit function. + +- Added ALLEGRO_EVENT_AUDIO_STREAM_FINISHED event to signify when non-looping + streams made with al_load_audio_stream reach the end of the file. + +- Fixed a deadlock when destroying voices. + +- Handle underruns in the r/w ALSA updater. + +- Minor change to the ALSA driver to improve compatibility with PulseAudio. + +Documentation: + +- Replaced awk/sh documentation scripts with C programs. + + + +Changes from 4.9.13 to 4.9.14 (September 2009) +============================================== + +The main developers this time were: Trent Gamblin, Elias Pschernig, Paul +Suntsov, Peter Wang. Other contributions from: Evert Glebbeek, Matthew +Leverton. + +Ports: + +- Elias Pschernig and Trent Gamblin started a iPhone port. + +Graphics: + +- Added al_get_opengl_texture_size and al_get_opengl_texture_position + functions. + +- Try to take into account GL_PACK_ALIGNMENT, GL_UNPACK_ALIGNMENT when + locking OpenGL bitmaps. + +- Fixed all (hopefully) conversion mistakes in the color conversion macros. + +- Sped up memory blitting, which was using conversion even with identical + formats (in some cases). + +- Make al_set_current_display(NULL); unset the current display. + +- Added ALLEGRO_LOCK_READWRITE flag for al_lock_bitmap (in place of 0). + +- Fixed window titles which contain non-ASCII characters in X11. + +- Added OES_framebuffer_object extension. + +Input: + +- Added a lot more system mouse cursors. + +- Renamed al_get_cursor_position to al_get_mouse_cursor_position. + +- Prevent Windows from intercepting ALT for system menus. + +Filesystem: + +- Make the path returned by al_get_entry_name() owned by the filesystem entry + so the user doesn't need to free it manually. + +- Renamed the filesystem entry functions, mainly to include "fs_entry" in + their names instead of just "entry". + +- Reordered and renamed ALLEGRO_FS_INTERFACE members. + +- Make al_read_directory() not return . and .. directory entries. + +- Renamed al_create_path_for_dir to al_create_path_for_directory. + +- Added al_set_standard_file_interface, al_set_standard_fs_interface. + +Events: + +- Exported ALLEGRO_EVENT_TYPE_IS_USER. + +Threads: + +- Added a new function al_run_detached_thread. + +Other core: + +- Put prefixes on register_assert_handler, register_trace_handler. + +- Added functions to return the compiled Allegro version and addon versions. + +- Added al_ prefix to fixed point routines and document them. + +- Added al_get_system_config(). + +- Renamed al_system_driver() to al_get_system_driver(). + +- Added 64-bit intptr_t detection for Windows. + +- Added work-around to make OS X port compile in 64 bit mode. + +Addons: + +- Renamed addons from a5\_\* to allegro_*. + +Image addon: + +- Renamed the IIO addon to "allegro_image". + +- Renamed \*\_entry functions that take ALLEGRO_FILE * arguments to *_stream. + +- Fixed off-by-one error in greyscale JPEG loader. + +Audio addons: + +- Renamed the kcm_audio addon to "allegro_audio". + +- Renamed ALLEGRO_STREAM and stream functions to ALLEGRO\_AUDIO\_STREAM + and al\_\*audio_stream\*. + +- Renamed al_stream_from_file to al_load_audio_stream + +- Added int16 mixing and configurable frequency and depth for default + mixer/voice (see configuration file). + +- Fixed FLAC decoding and added FLAC streaming support. + +- Changed the function signature of al_get_stream_fragment() to be more + straightforward. + +- Fixed bug in kcm audio that caused data to be deleted that was still used. + +- Made ALSA audio driver work when the driver does not support mmap (commonly + because the ALSA really is PulseAudio). + +- Removed al_is_channel_conf function. + +Font addons: + +- Optimized font loading by converting the mask color on a memory copy instead + of have to lock a texture. + +- Made the ttf addon read from file streams. + +Primitives addon: + +- Fixed the direction of the last segment in software line loop, and fixed + the offsets in the line drawer. + +- Fixed the thick ribbon code in the primitives addon, was broken for + straight segments. + +- Various fixes/hacks for the D3D driver of the primitives addon: hack to + make the indexed primitives work and a fix for the textured primitives. + +- Various enhancements to the transformations API: const correctness, + transformation inverses and getting the current transformation. + +- Added support for custom vertex formats. + +- Flipped the v axis of texture coordinates for primitives. Now (u=0, v=0) + correspond to (x=0, y=0) on the texture bitmap. + +- Added a way to use texture coordinates measured in pixels. Changed + ALLEGRO_VERTEX to use them by default. + +PhysicsFS: + +- PhysFS readdir didn't prepend the parent directory name to the returned + entry's path. + +- Set execute bit on PhysFS directory entries. + +Examples: + +- Made examples report errors using the native dialogs addon if + WANT_POPUP_EXAMPLES is enabled in CMake (default). + +- Added new example ex_draw_bitmap, which simply measures FPS when drawing a + bunch of bitmaps (similar to exaccel in A4). + +Documentation: + +- Many documentation updates and clarifications. + +- Fixed up Info and PDF documentation. + +Bindings: + +- Added a script to generate a 1:1 Python wrapper (see `python` directory). + + + +Changes from 4.9.12 to 4.9.13 (August 2009) +=========================================== + +The main developers this time were: Trent Gamblin, Elias Pschernig, Paul +Suntsov, Peter Wang. Other contributions from: Todd Cope, Evert Glebbeek, +Michael Harrington, Matthew Leverton. + +Ports: + +- Trent Gamblin started a port to the GP2X Wiz handheld console. + +Graphics: + +- Some OpenGL bitmap routines were not checking whether the target bitmap was + locked. + +- Scaled bitmap drawer was not setting the blend mode. + +- Fixed a bug where al_map_rgb followed by al_unmap_rgb would return + different values. + +- Fixed problems with sub-sub-bitmaps. + +- Fixed window placement on OS X, which did not properly translate the + coordinates specified by the user with al_set_new_window_position(). + +- Made is_wgl_extension_supported() fail gracefuly. + +- Added ALLEGRO_ALPHA_TEST bitmap flag. + +- Minor optimizations in some memory blitting routines. + +Input: + +- Replaced (ALLEGRO_EVENT_SOURCE *) casting with type-safe functions, namely + al_get_keyboard_event_source, al_get_mouse_event_source, + al_get_joystick_event_source, al_get_display_event_source, + al_get_timer_event_source, etc. + +- Made it so that users can derive their own structures from + ALLEGRO_EVENT_SOURCE. al_create_user_event_source() is replaced by + al_init_user_event_source(). + +- Fixed a problem on Windows where the joystick never regains focus when + tabbing away from a window. + +- Fixed a problem with missing key repeat with broken X.Org drivers. + +- Implemented ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY, + ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY for X11. + +Image I/O addon: + +- Changed return type of al_save_bitmap() to bool. + +- Separated al_add_image_handler into al_register_bitmap_loader, + al_register_bitmap_saver, etc. + +- Made JPEG and PNG loaders handle al_create_bitmap() failing. + +- Speed up JPEG loading and saving. + +- Fixed a reinitialisation issue in iio. + +Audio addons: + +- Moved basic sample loading/saving routines to kcm_audio from acodec + and added file type registration functions. + +- Moved WAV support into kcm_audio. + +- Made WAV loader not choke on extra chunks in the wave. + +- Separated acodec into a5_flac, a5_vorbis addons. You need to initialise + them explicitly. Removed sndfile support. + +- Renamed al\_\*\_oggvorbis to al\_\*\_ogg\_vorbis. + +- Changed argument order in al_save_sample and al_stream_from_file. + +- Reordered parameters in al\_attach\_* functions to follow the word order. + +- Renamed a few streaming functions to refer to fragments/buffers + as fragments consistently. + +- Added missing getters for ALLEGRO_SAMPLE fields. + +- Fixed mutex locking problems with kcm_audio objects. + +- Avoid underfilling a stream when it is fed with a short looping stream. + +Other addons: + +- Added glyph advance caching for the TTF addon. + +- Renamed al_register_font_extension to al_register_font_loader. + Match the file name extension case insensitively. + +Documentation: + +- Lots of documentation updates. + +- Added a short "Getting started guide" to the reference manual. + +Examples: + +- Added another example for kcm_audio streaming: ex_synth. + +Build system: + +- Fix pkg-config .pc files generated for static linking. + +- DLL symbols are now exported by name, not ordinals. + + + +Changes from 4.9.11 to 4.9.12 (July 2009) +========================================= + +- Fixed bugs in Windows keyboard driver (Todd Cope). + +- Fixed problems with ALLEGRO_MOUSE_STATE buttons on Windows (Milan Mimica). + +- Fixed problems with PhysicsFS addon DLL on MSVC (Peter Wang). + +- Set the D3D texture address mode to CLAMP (Todd Cope). + +- Fixed hang if Allegro was initialized more than once on Windows + (Michael Harrington). + +- Added a CMake option to force the use of DllMain style TLS on Windows, + for use with C# bindings (Michael Harrington). + +- Fixed a bug where drawing circles with a small radius would crash + (Elias Pschernig). + +- Fixed several memory leaks throughout the libraries (Trent Gamblin). + +- Fixed some compilation warnings on Mac OS X (Evert Glebbeek). + +- Small documentation updates. + + + +Changes from 4.9.10.1 to 4.9.11 (June 2009) +=========================================== + +The main developers this time were: Trent Gamblin, Milan Mimica, Elias +Pschernig, Paul Suntsov, Peter Wang. Other contributions from: Christopher +Bludau, David Capello, Todd Cope, Evert Glebbeek, Peter Hull. + +Graphics: + +- Changed rotation direction in memory blitting routines to match D3D/OpenGL + routines. + +- Made al_set_target_bitmap not create an FBO if the bitmap is locked. + +- Added explicit FBO handling functions al_get_opengl_fbo and + al_remove_opengl_fbo in case we weren't quite clever enough above and the + user has to intervene manually. + +- Added OpenGL 3.1 support and a bunch of new OpenGL extensions. + +- Fixed al_inhibit_screensaver on Windows + +- Fixed selection of X pixel formats with WGL if a new bitmap has alpha. + +- Made X11 icon work regardless of the backbuffer format. + +Input: + +- Ditched DirectInput keyboard driver and replaced it with WinAPI. + Fixes several issues the old driver had. + +- Rewrote Windows mouse driver to use WinAPI instad of DirectInput. + +- Added al_get_joystick_number. + +Filesystem: + +- Merged ALLEGRO_FS_HOOK_ENTRY_INTERFACE into ALLEGRO_FS_INTERFACE + and made ALLEGRO_FS_INTERFACE public. + +- Added al_set_fs_interface and al_get_fs_interface. + +- Made al_opendir take an ALLEGRO_FS_ENTRY. + +- Removed functions which are obsolete or probably have no use. + +- Made al_get_standard_path(ALLEGRO_PROGRAM_PATH) return a path + with an empty filename. + +Path routines: + +- Renamed functions to follow conventions. + +File I/O: + +- Fix al_fgets() returning wrong pointer value on success. + +Primitives addon: + +- Added support for textured primitives in software. + +- Introduced ALLEGRO_PRIM_COLOR, removed ALLEGRO_VBUFFER. + +- Exposed the software line and triangle drawers to the user. + +- Added rounded rectangles. + +- Fix an extraneous pixel bug in the triangle drawer. + +Audio addon: + +- Change from using generic get/set audio property functions to specific + getter/setter functions. + +- Change return types on many functions to return true on success instead + of zero. (Watch out when porting your code, the C compiler won't help.) + +Native dialogs: + +- Added a Windows implementation. + +- Added a title to al_show_native_message_box(). + +Other addons: + +- Implemented the filesystem interface for PhysicsFS and demonstrate its use + in ex_physfs. + +- Fixed al_color_html_to_rgb. + +Examples: + +- Added an OpenGL pixel shader example. + +Build system: + +- Output separate pkg-config .pc files for static linking. + + + +Changes from 4.9.10 to 4.9.10.1 (May 2009) +========================================== + +- Fixed uses of snprintf on MSVC. + +- Disabled ex_curl on Windows as it requires Winsock. + + + +Changes from 4.9.9.1 to 4.9.10 (May 2009) +========================================= + +The main developers this time were: Trent Gamblin, Evert Glebbeek, Milan +Mimica, Elias Pschernig, Peter Wang. Other contributions from: Peter Hull, +Paul Suntsov. + +Graphics: + +- Renamed al_clear() to al_clear_to_color(). + +- Renamed al_opengl_version() to al_get_opengl_version(). + +- Changed the direction of rotation for al_draw_rotated* from + counter-clockwise to clockwise. + +- Added new pixel format ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which guanrantees + component ordering. + +- Added ALLEGRO_NO_PRESERVE_TEXTURE flag. + +- Fixed horizontal flipping in plain software blitting routines. + +- Fixed some blending bugs in the OpenGL driver. + +- Made OpenGL driver fall back to software rendering if separate alpha + blending is requested but not supported. + +- Added a config option which allows pretending a lower OpenGL version. + +- Implemented al_get_num_display_formats(), al_get_display_format_option() + and al_set_new_display_format() for WGL. + +- Fixed bug in al_get_display_format_option() with the GLX driver. + +- Fixed a bug in the D3D driver that made display creation crash if the first + scored mode failed. + +- Made the OpenGL driver prefer the backbuffer format for new bitmaps. + +- Defer FBO creation to when first setting a bitmap as target bitmap. + +Input: + +- Renamed some joystick functions. + +- Account for caps lock state in OS X keyboard driver. + +- Made UTF-8 input work on X11. + +File I/O: + +- Separated part of fshook API into a distinct file I/O API (actually + generic streams). + +- Make the file I/O API match stdio more closely and account for corner + cases. (incomplete) + +- Made it possible to set a stream vtable on a per-thread basis, which + affects al_fopen() for that thread. + +- Added al_fget_ustr() to read a line conveniently. + +- Change al_fputs() not to do its own CR insertion. + +- Add al_fopen_fd() to create an ALLEGRO_FILE from an existing file + descriptor. + +Filesystem: + +- Changed al_getcwd, al_get_entry_name to return ALLEGRO_PATHs. + +- Renamed al_get_path to al_get_standard_path, and to return an ALLEGRO_PATH. + +- Changed al_readdir to return an ALLEGRO_FS_ENTRY. + +- Added al_path_create_dir. + +- Removed some filesystem querying functions which take string paths + (ALLEGRO_FS_ENTRY versions will do). + +Config routines: + +- Added functions to traverse configurations structures. + +- Change al_save_config_file() return type to bool. + +- Removed an arbitrary limit on the length of config values. + +- Renamed configuration files to allegro5.cfg and allegro5rc. + +String routines: + +- Allegro 4-era string routines removed. + +- Added al_ustr_to_buffer(). + +Other core: + +- Renamed al_thread_should_stop to al_get_thread_should_stop. + +- Added a new internal logging mechanism with configurable debug "channels", + verbosity levels and output formatting. + +- Cleaned up ASSERT namespace pollution. + +Font addons: + +- Renamed font and TTF addon functions to conform to conventions. + +- Added al_init_ttf_addon. + +- Implemented slightly nicer text drawing API: + + - functions are called "draw_text" instead of "textout" + - centre/right alignment handled by a flag instead of functions + - functions accepting ALLEGRO_USTR arguments provided + - substring support is removed so 'count' arguments not needed in usual + case, however ALLEGRO_USTR functions provide similar thing. + +- Removed al_font_is_compatible_font. + +- Sped up al_grab_font_from_bitmap() by five times. + +- ttf: Fixed a possible bug with kerning of unicode code points > 127. + +Image I/O addon: + +- Renamed everything in the IIO addon. + +- Exposed al_load_bmp/al_save_bmp etc. + +Audio addon: + +- Renamed al_mixer_set_postprocess_callback. + +- Added two config options to OSS driver. + +- Made ALSA read config settings from [alsa] section. + +Native dialogs: + +- Added al_show_native_message_box() which works like allegro_message() in A4. + Implemented for GTK and OS X. + +PhysicsFS addon: + +- Added PhysicsFS addon. + +Primitives addon: + +- Removed global state flags. + +- Removed normals from ALLEGRO_VERTEX. + +- Removed read/write flags from vertex buffers. + +Examples: + +- Added an example that tests al_get_display_format_option(). + +- Added an example which shows playing a sample directly to a voice. + +- Added an example for PhysicsFS addon. + +- Added a (silly) example that loads an image off the network using libcurl. + +- Added ex_dir which demonstrates the use of al_readdir and + al_get_entry_name. + +Other: + +- Many bug and documentation fixes. + + + +Changes from 4.9.9 to 4.9.9.1 (March 2009) +========================================== + +- Made it compile and work with MSVC and MinGW 3.4.5. + +- Enabled SSE instruction set in MSVC. + +- Fixed X11 XIM keyboard input (partially?). + +- Fall back on the reference (software) rasterizer in D3D. + + + +Changes from 4.9.8 to 4.9.9 (March 2009) +======================================== + +The main developers this time were: Trent Gamblin, Evert Glebbeek, Milan +Mimica, Elias Pschernig, Paul Suntsov, Peter Wang. Other contributions +from: Todd Cope, Angelo Mottola, Trezker. + +Graphics: + +- Added display options API and scoring, based on AllegroGL, for finer + control over display creation. + +- Added API to query possible display formats (implemented on X, Mac OS X). + +- Changed the bitmap locking mechanism. The caller can choose a pixel + format. + +- Added support for multisampling. + +- Simplified the semantics of al_update_display_region(). + +- Optimised software blitting routines. + +- Optimised al_map_rgb/al_map_rgba. + +- Replaced al_draw_rectangle() and al_draw_line() from core library with + al_draw_rectangle_ex() and al_draw_line_ex() from the primitives addon. + +- Implemented al_wait_for_vsync() everywhere except WGL. + +- Fixed problems with sub-bitmaps with the OpenGL driver. + +- Fixed bugs in software scaled/rotated blit routines. + +- Added a new pixel format ALLEGRO_PIXEL_FORMAT_ABGR_F32. + Removed ALLEGRO_PIXEL_FORMAT_ANY_15_WITH_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_24_WITH_ALPHA. + +- Added support for creating OpenGL 3.0 contexts (untested; only WGL/GLX for + now). Relevant display flags are ALLEGRO_OPENGL_3_0 and + ALLEGRO_OPENGL_FORWARD_COMPATIBLE. + +- Allow disabling any OpenGL extensions from allegro.cfg to + test alternative rendering paths. + +- Fixed problem with windows only activating on title bar clicks (Windows). + +- Fixed a minimize/restore bug in D3D (with the help of Christopher Bludau). + +Input: + +- Implemented al_set_mouse_xy under X11. + +- Added ALLEGRO_EVENT_MOUSE_WARPED event for al_set_mouse_xy(). + +Path routines: + +- Made al_path_get_drive/filename return the empty string instead of NULL + if the drive or filename is missing. + +- Changed al_path_set_extension/al_path_get_extension to include the leading + dot. + +- Made al_path_get_extension(), al_path_get_basename(), al_path_to_string() + return pointers to internal strings. + +Unicode: + +- Changed type of ALLEGRO_USTR; now you should use pointers to ALLEGRO_USTRs. + +- Added UTF-16 conversion routines. + +Other core: + +- Added ALLEGRO_GET_EVENT_TYPE for constructing integers for event type IDs. + +- Renamed configuration function names to conform to conventions. + +- Removed public MIN/MAX/ABS/MID/SGN/CLAMP/TRUE/FALSE macros. + +- Replaced AL_PI by ALLEGRO_PI and documented it as part of public API. + +Audio addons: + +- Added stream seeking and stream start/end loop points. + +- Add panning support for kcm_audio (stereo only). + +Font addons: + +- Made al_font_grab_font_from_bitmap() accept code point ranges. + +- Made font routines use new UTF-8 routines; lifted some arbitrary limits. + +- Fixed artefacts in bitmap font and TTF rendering. + +Image I/O addon: + +- Made the capability to load/save images from/to ALLEGRO_FS_ENTRYs public. + +- Added missing locking to .png save function. + +Other addons: + +- Added native_dialog addon, with file selector dialogs. + +- Fixed many bugs in the primitives addon. + +- Made hsv/hsl color functions accept angles outside the 0..360° range. + +- Fixed a bug in al_color_name_to_rgb. + +Examples: + +- New programs: ex_audio_props, ex_blend_bench, ex_blend_test, ex_blit, + ex_clip, ex_draw, ex_font_justify, ex_gl_depth, ex_logo, ex_multisample, + ex_native_filechooser, ex_path_test, ex_rotate, ex_stream_seek, ex_vsync, + ex_warp_mouse. + (ex_draw demonstrated known bugs currently.) + +- Updated programs: ex_joystick_events, ex_monitorinfo ex_pixelformat, + ex_scale, ex_subbitmap. + +Build system: + +- Added pkg-config support. .pc files are generated and installed on Unix. + +- Allowed gcc to generate SSE instructions on x86 by default. For Pentium 2 + (or lower) compatibility you must uncheck a CMake option before building + Allegro. + +Other: + +- Many other bug fixes. + + + +Changes from 4.9.7.1 to 4.9.8 (February 2009) +============================================= + +The main developers this time were: Thomas Fjellstrom, Trent Gamblin, +Evert Glebbeek, Matthew Leverton, Milan Mimica, Elias Pschernig, Paul Suntsov, +Peter Wang. + +General: + +- Lots of bug fixes. + +File system hooks: + +- Rationalised file system hook functions. Failure reasons can be retrieved + with al_get_errno(). + +- Enable large file support on 32-bit systems. + +- Converted the library and addons to use file system hook functions. + +Path functions: + +- Added al_path_clone(), al_path_make_canonical(), al_path_make_absolute(), + al_path_set\_extension(), al\_{get,set}\_org_name, al\_{get,set}_app_name} + functions. + +- Made al_path_get_extension() not include the leading "." of the extension, + +- Add AL_EXENAME_PATH, AL_USER_SETTINGS_PATH, AL_SYSTEM_SETTINGS_PATH enums + for al_get_path(). + +String routines: + +- Added a new, dynamically allocating UTF-8 string API. This uses bstrlib + internally, which is distributed under a BSD licence. Allegro 5 will + expect all strings to be either ASCII compatible, or in UTF-8 encoding. + +- Removed many old Unicode string functions. (Eventually they will all be + removed.) + +Config routines: + +- Clarified behaviour of al_config_add_comment, al_config_set_value with + regards to whitespace and leading comment marks. + +Graphics: + +- Bug fixes on Windows and Mac OS X for resizing, switching away, setting full + screens, multi-monitor, etc. + +- Added an al_get_opengl_texture() convenience function. + +- Added separate alpha blending. + +- Added ALLEGRO_PIXEL_FORMAT_ANY. + +- Honour al_set_new_window_position() in X11 port. + +- Made the X11 port fail to set a full screen mode if the requested resolution + cannot be set rather than falling back to a windowed mode. + +Input: + +- Added a field to the mouse state struct to indicate the display the mouse is + currently on. + +- Made DirectX enumerate all joysticks/gamepads properly by using a device + type new to DirectInput 8. + +- Fixed a bug in wmouse.c where y was not changed in al_set_mouse_xy. + +- Support ALLEGRO_EVENT_MOUSE_ENTER/LEAVE_DISPLAY events in Windows. + +Addons: + +- Added a primitives addon. + +- Revamp interface for kcm_audio addon to make simple cases easier. + +- Added native .wav support and save sample routines to acodec addon. + +- Added a colors addon. + +- Added memory file addon and example. + +TTF addon: + +- Added al_ttf_get_text_dimensions() function. + +- Allow specifying the font size more precisely by passing a negative font + size. + +- Guess the filenames of kerning info for Type1 fonts. + +Documentation: + +- Added a new documentation system using Pandoc. Now we can generate HTML, + man, Info and PDF formats. + +- Added and fixed lots of documentation. + +Examples: + +- Added ex_prim, ex_mouse_focus examples. + +- Made ex_blend2 more comprehensive. + +- Updated ex_get_path example. + +- Made ex_ttf accept the TTF file name on the command line. + +Build system: + +- Use official CMAKE_BUILD_TYPE method of selecting which build configuration. + This should work better for non-make builds, however, it's no longer + possible to build multiple configurations with a single configuration step + as we could previously. + +Removals: + +- Remove outdated A4 tools. + +- Remove icodec addon. + +- SCons build was unmaintained and not working. + + + +Changes from 4.9.7 to 4.9.7.1 (December 2008) +============================================= + +- Scan aintern_dtor.h for export symbols, needed for MSVC. + + + +Changes from 4.9.6 to 4.9.7 (December 2008) +=========================================== + +The main developers this time were: Trent Gamblin, Evert Glebbeek, Peter Hull, +Milan Mimica, Peter Wang. + +Graphics: + +- Fixed a bug where the "display" field of a bitmap was not correctly reset + when it was transfered to another display on OS X. + +- Made al_create_display() respect al_set_new_window_position() on OS X. + +- Fixed the bug that caused input focus to be lost in OS X when a + window was resized. + +- Made resizable Allegro windows respond properly to the green "+" button at + the top of the screen on OS X. + +- Properly implemented fullscreen resize in WGL. + +- Made the memory blenders work the same as the hardware ones. + +- Made al_get_pixel()/al_draw_pixel() handle sub bitmaps in case the bitmap + was locked. + +- In the OpenGL driver, if the bitmap is locked by the user, use memory + drawing on the locked region. + +- Added implementations of al_inhibit_screensaver() for the X and Mac OS X + ports. + +- Added multi-monitor support to Mac OS X port (untested!). + +- Other fixes. + +Input: + +- Made al_get_keyboard_state() return structures with the `display' field + correctly set. + +- Made keyboard event member 'unichar' uppercase when Shift/CapsLock is on, + in Windows. + +- Made mouse cursor show/hide work with Mac OS X full screen. + +Config routines: + +- Preserve comment and empty lines in config files when writing. + +Addons: + +- Add a simple interface layer for kcm_audio. + +- Made kcm_audio objects automatically be destroyed when it is shut down. + +- Renamed functions in kcm_audio to conform better with the rest of the + library. + +- Made the TTF addon aggregate glyph cache bitmaps into larger bitmaps for + faster glyph rendering (less source bitmap switching). + +Examples: + +- Add an example to test the ALLEGRO_KEYBOARD_STATE `display' field. + +- Add an example for testing config routines. + +- Add an example for checking software blending routines against hardware + blending. + +- Add an example for the simple interface for kcm_audio. + + + +Changes from 4.9.5 to 4.9.6 (November 2008) +=========================================== + +The core developers this time were: Thomas Fjellstrom, Trent Gamblin, Evert +Glebbeek, Peter Hull, Milan Mimica, Jon Rafkind, Peter Wang. + +Allegro 4.9.6 and onwards are licensed under the zlib licence (see +LICENSE.txt). This is a simple permissive free software licence, close in +spirit to the 'giftware' licence, but is clearer and more well-known. + +General: + +- Added filesystem hook (fshook) and path API functions. + +- Many minor bug fixes. + +Graphics: + +- Added allegro5/a5_opengl.h, which has to be included by programs + to use OpenGL specifics. ALLEGRO_EXCLUDE_GLX and ALLEGRO_EXCLUDE_WGL can + be #defined to exclude GLX and WGL OpenGL extensions respectively. + +- Added allegro/a5_direct3d.h, which has to be included by programs + to use D3D specifics. + +- Fixed some drawing from and onto sub-bitmaps. + +- Fixed blending with the wrong color in case of sub-bitmaps. + +- Fixed a bug in the D3D driver where the transformation matrix was not + reset after drawing a bitmap. + +- Added draw pixel to OpenGL driver. + +- Added more OpenGL extensions. + +- Added function to inhibit screen saver (currently Windows only). + +Config routines: + +- Added al_config_create(). + +- Deleted al_config_set_global(). Made empty section name equivalent to + the global section. + +- Read system wide and home directory config files on Unix + (Ryan Patterson). + +Events: + +- Added support for injecting user-defined events into event queues. + +Audio addon: + +- Made the ALSA driver read the device name from the config file (Ryan + Patterson). + +Examples: + +- Added ex_subbitmap example. + +- Added ex_disable_screensaver example. + +Build system: + +- Rationalised library names and made CMake and SCons build systems + agree on the names. + + + +Changes from 4.9.4 to 4.9.5 (October 2008) +========================================== + +The core developers this time were: Trent Gamblin, Evert Glebbeek, Peter Hull, +Milan Mimica, Elias Pschernig, Jon Rafkind, Peter Wang. + +Graphics: + +- Added fullscreen support on Mac OS X. + +- Added support for resizable windows on Mac OS X. + +- Made frameless windows respond to events on Mac OS X. + +- Fixed a problem with D3D blending. + +- Made D3D driver work on systems without hardware vertex processing. + +- Made WGL driver fail more gracefully. + +- Implemented sprite flipping for OpenGL drivers (Steven Wallace). + +- Added al_is_sub_bitmap() function. + +Input: + +- Fixed input with multiple windows on Windows. + +- Fixed keyboard autorepeat events in X11. + +- Added al_is_keyboard_installed(). + +- Fixed key shifts on Windows (ported from 4.2). + +- Fixed mouse button reporting on Mac OS X. + +- Implemented system mouse cursors on MacOS X. + +- Fixed mouse cursors with alpha channels on X11. + +- Some work on Mac OS X joystick support (incomplete). + +Events: + +- Simplified internals of events system further. At the same time, + this change happens to also allow event queues to grow unboundedly. + (You should still avoid letting them get too big, of course.) + +Audio addons: + +- Made ALLEGRO_STREAM objects emit events for empty fragments that need + to be refilled. + +- Added a possiblity to drain a stream created by al_stream_from_file(). + +- Added a function to rewind a stream. + +- Added gain support to ALLEGRO_STREAM and ALLEGRO_SAMPLE objects. + +- Made it possible to attach a sample to a mixer that isn't already attached + to something. + +- Fixed Ogg Vorbis loader on big-endian systems. + +- Made the OpenAL driver the least preferred driver, as it doesn't play + stereo samples properly. + +Image addons: + +- Added JPEG support to iio addon, using libjpeg. + +- Fixed TGA loader on big-endian systems. + +- Fixed image loading in icodec addon. + +Font addon: + +- Fixed count-restricted text output functions calculations on non-ASCII + strings. + +- Made al_textout* functions always a 'count' parameter. + +- Renamed al_font_text_length* to al_font_text_width*. + +- Harmonised the order of al_font_textout* and al_font_textprintf* arguments. + +Examples: + +- Added ex_bitmap_flip example (Steven Wallace). + +- Added ex_mixer_chain example. + +- Split ex_events into smaller examples. + +- Made the demo use ALLEGRO_STREAM to play music. + +- Build an app bundle from the demo, on Mac OS X. + +Build system: + +- Improved detection of external dependencies in CMake build. + +- Guess compiler locations for MinGW and MSVC (CMake). + +- Many improvements to scons build, including install support. + +General: + +- Many other bug fixes. + + + +Changes from 4.9.3 to 4.9.4 (September 2008) +============================================ + +The core developers this time were: Trent Gamblin, Peter Hull, Milan Mimica, +Elias Pschernig and Peter Wang. Ryan Dickie and Jon Rafkind also contributed. + +General: + +- Many bug fixes all around. + +- Added a public threads API. + +- Added a basic configuration API. + +- Added al_store_state/al_restore_state functions. + +- Added al_get_errno/al_set_errno (not used much yet). + +- Renamed some functions/structures to be more consistent. + +- Code formatting improvements. + +- Added more debugging messages. + +- Removed a lot of A4 code that is no longer used. + +Graphics: + +- Added support for some new OpenGL extensions. + +- Multihead support on Windows (preliminary support on OSX and Linux). + +- Many enhancements to all drivers. + +- Merged common parts of WGL and D3D drivers. + +- Borderless windows, setting window positions and titles. + +- Fullscreen support on OSX and Linux. + +- Do not clear bitmaps when they are created. + +- Improved compile times and DLL sizes by simplifying "memblit" functions. + +- Added EXPOSE, SWITCH_IN and SWITCH_OUT display events. + +Build system: + +- Many bug fixes and enhancements to SCons and CMake build systems. + +- Support for Turbo C++ 2006. + +- Support for cross-compiling on Linux to MinGW (CMake). + +Events: + +- Filled in a display field for all relevant events. + +- Added al_wait_for_event_until. + +Addons: + +- Added an ImageMagick addon + +- Added iio (Image IO) addon + + - Supports BMP, PCX, TGA. + + - Supports PNG support with libpng. + +- Added new audio addon, kcm_audio. (The 'audio' addon was taken in a new + direction between the 4.9.3 and 4.9.4 releases, but we decided against + that, so actually it's actually a continuation of the old audio addon.) + + - Added audio streaming functionality. + + - Added OSS, ALSA, DirectSound drivers. + + - A lot of reorganisation, internally and externally. + +- Added TTF font addon, using FreeType. + +- Made all addons use "al_" prefix. + +Examples: + +- Lots of new examples. + +- Wait for keypress in some examples instead of arbitrary delay. + +- Clean up files when done in some examples. + + + +Changes from 4.9.2 to 4.9.3 (April 2008) +======================================== + +Graphics: + +- Milan Mimica did lots of work on the OpenGL drivers, such as adding an + OpenGL driver for Windows and making the OpenGL code shared between + platforms. + +- Peter Hull added an OpenGL graphics driver for Mac OS X. + +- Milan Mimica made the OpenGL driver share contexts between displays. + +- Peter Wang and Milan Mimica made the OpenGL driver work with cards that + don't support non-power-of-two (NPOT) textures. + +- Trent Gamblin added support for NPOT textures in the Direct3D driver. + +- Trent Gamblin fixed blending in memory drawing functions. + +- Trent Gamblin added al_draw_pixel() which obeys blending. + +- Trent Gamblin made al_clear() not affected by blending in D3D. + +- Milan Mimica added the following functions to the public API: + al_opengl_version(), al_is_opengl_extension_supported(), + al_get_opengl_proc_address(), al_get_opengl_extension_list(). + +- Milan Mimica added sub-bitmaps support for memory bitmaps and in the + OpenGL display driver. + +- Milan Mimica made displays keep a list of bitmaps. When destroying a + display its bitmaps will be managed properly, e.g. converted to memory + bitmaps if necessary. All display bitmaps will be automatically destroyed + on exit. + +- Peter Wang made X window resizing work without GLX 1.3. + +- Trent Gamblin fixed a bug in the Direct3D driver when windows were + minimized (thanks to David McCallum). + +- Trent Gamblin fixed the coordinates of Direct3D primitives to match OpenGL + style. + +- Peter Hull fixed some logic in bitmap drawing and al_load_bitmap(). + +Fonts: + +- Milan Mimica made font drawing faster, by making glyphs sub-bitmaps of a + larger glyph sheet. + +- Milan Mimica and Peter Wang made font loading faster. + +- Trent Gamblin added versions of text output functions which take as an + explicit argument the length of the strings. + +Audio: + +- A new audio API implementation, originally by Chris Robinson, was added + (currently as an addon only). It has received additional work in the past + from Milan Mimica and recently much work from Ryan Dickie. + +- Ryan Dickie also added an acodec addon, which has loaders for FLAC, Wave + and Ogg Vorbis files, using other libraries. + +Timers: + +- Ryan Dickie changed the type of timestamps throughout the API from int + expressed in milliseconds to double expressed in seconds and improved + timer resolution on Windows. + +- Ryan Dickie added an 'error' field to the timer event, and added error + and overhead statistics to exnew_timer. + +- Trent Gamblin made the Windows timer use QueryPerformanceCounter. + +- Peter Wang split al_wait_for_event() into two functions, a version that + takes a timeout and a version that doesn't. + +- Trent Gamblin merged the Windows and Unix timer source files. + +Input: + +- Peter Wang renamed some joystick and timer functions to adhere to the + `al__` convention. + +- Peter Wang made al_num_joysticks() more lenient if there is no joystick + driver installed. + +Other: + +- David Capello added support for various different BMPs. + +- Elias Pschernig fixed compilation of the X port in case the XVidMode + extension is unavailable (thanks to Thomas Fjellstrom). + +- Elias Pschernig added a exnew_timer example. + +- Trent Gamblin added exnew_multiwin and exnew_drawpixels. + +- Peter Wang added exnew_timedwait and exnew_scale. + +- Jon Rafkind and Elias Pschernig updated the SCons build. + +- Jon Rafkind added a `_s` suffix to static libraries in the SCons build. + +- Elias Pschernig did some work on cross-compilation with SCons and MinGW. + +- Milan Mimica made the CMake build work with MSVC project solutions + and made the library build with MSVC 8. + +- Jacod Dawid added a nicer spaceship graphic for a5teroids demo. + +- Many more bug fixes and documentation updates. + + + +Changes from 4.9.1 to 4.9.2 (November 2007) +=========================================== + +*This list is still to be summarised.* + +- Trent Gamblin made the mouse cursor always hide when the user + calls al_hide_mouse_cursor in fullscreen (D3D). + +- Trent Gamblin fixed some signedness warnings and implemented + show/hide_mouse in the display vtable for D3D. + +- Elias Pschernig made show/hide cursor use the display driver instead of + the 4.2 gfx_driver. + +- Elias Pschernig fixed missing keyboard events in exnew_mouse_events + example. + +- Elias Pschernig wired the X11 mouse driver to the XGLX system driver. + +- Jon Rafkind made various fixes to get the OSX build to compile + +- Trent Gamblin added exnew_mouse_events. + +- Trent Gamblin added exnew_mouse. + +- Jon Rafkind made the scons build get the library name dynamically. + +- Jon Rafkind made the scons build link Allegro using -l instead of + using the full path. + +- Trent Gamblin added a note about MINGDIR in readme_a5.txt. + +- Trent Gamblin removed -lalleg_unsharable from allegro-config.in, + since assembly is not used anymore. + +- Jon Rafkind fixed up allegro-config. + +- Trent Gamblin added some documentation on ALLEGRO_MSESTATE. + +- Trent Gamblin listed the examples in readme_a5.txt. + +- Trent Gamblin improved some inline documentation. + +- Jon Rafkind removed /lib from install path in unix.scons. + +- Jon Rafkind added the new demo to the scons build and allowed + addons to be built statically or shared. + +- Trent Gamblin made the glx line drawing function use blending. + +- Trent Gamblin added cmake instructions to readme_a5.txt. + +- Elias Pschernig added readme_a5.txt. + +- Trent Gamblin fixed warnings in the demo. + +- Trent Gamblin fixed a crash-on-exit bug in tls.c. + +- Trent Gamblin replaced the old demo with a temporary one. + +- Peter Wang fixed gcc string warnings. + +- Peter Wang added some assertions to display_new.c. + +- Peter Wang merged changes from the 4.2 branch. + +- Elias Pschernig removed an unnecessary import from the + naturaldocs upload script. + +- Elias Pschernig added a script to automatically upload the + naturaldocs generated documentation to the website. + +- Peter Wang fixed missed renamings from AL_ to ALLEGRO_ in the + Linux and X code. + +- Elias Pschernig merged 4.9-newgfx back to 4.9. + +- Peter Wang fixed a "ALLEGRO__JOYSTICK" typo. + +- Trent Gamblin renamed AL_ to ALLEGRO_ in input, events, and timer + code. + +- Elias Pschernig implemented outline flag and blending for + draw_rectangle in the GLX driver. + +- Elias Pschernig added another mysha.pcx for the font example. + +- Elias Pschernig re-added GLX checked to scons build which went + missing in the merge. + +- Elias Pschernig added icon.xpm which went missing in the merge. + +- Peter Wang replaced _al_draw_bitmap_region_memory_fast with + _al_draw_bitmap_region_memory. + +- Trent Gamblin made memblit.c compile a little faster in debug + mode. + +- Peter Wang mergedd changes in r7948:10859 on 4.9 branch to + 4.9-newgfx branch. + +- Peter Wang enabled WANT_D3D by default. Only set ALLEGRO_D3D + on Windows. + +- Trent Gamblin made al_acknowledge_resize take the display as a + parameter. + +- Trent Gamblin fixed some warnings and made the MinGW build compilable + statically with gcc 4.2.1. + +- Peter Wang fixed a bug in ALLEGRO_CONVERT_BGR_565_TO_ARGB_4444. + +- Peter Wang renamed al_memory_management_functions() to + al_set_memory_management_functions() and added some extra + documenation for it. + +- Peter Wang removed NaturalDocs markup for Allegro 4.x display + functions. + +- Peter Wang made OpenGL libraries link if building with X11 support. + +- Peter Wang fixed a signedness warning. + +- Peter Wang made al_destroy_bitmap return immediately when passed a + null pointer instead of segfaulting. + +- Elias Pschernig made some cosmetic improvements to the code. + +- Elias Pschernig removed a bad optimization. + +- Elias Pschernig removed > GLX 1.1 specific code. + +- Trent Gamblin fixed several of the floating point unmapping functions + that were doing integer division. + +- Elias Pschernig implemented blending in the GLX driver. + +- Elias Pschernig fixed GLX rotation to use radians and allow negative + angles. + +- Elias Pschernig implemented rotated blitting in the GLX driver. + +- Jon Rafkind made scons install addons/font. + +- Jon Rafkind added a scons file for addons. + +- Jon Rafkind used target_scanner to find makedoc instead of using + Depends. + +- Jon Rafkind forced makedoc to be a dependancy of the docs. + +- Trent Gamblin made 60hz the default refresh rate of the D3D driver. + +- Trent Gamblin changed al_create_mouse_cursor to accept + ALLEGRO_BITMAP structures. + +- Trent Gamblin renamed __al_unmap_rgba to al_unmap_rgba_ex in the + glx driver. + +- Trent Gamblin made al_(map|unmap)_rgb(a)_*_ex public. + +- Trent Gamblin made D3D windows show the resize cursor when resizing + windows. + +- Jon Rafkind added allegro includes for asmdef. + +- Jon Rafkind erased older build demo target. + +- Jon Rafkind added the demo to the scons build. + +- Jon Rafkind made it so assembly files can be built statically. + +- Jon Rafkind made scons always build asmdef. + +- Trent Gamblin made al_acknowledge_resize and al_resize_display + adjust clipping in the D3D driver. Mad eal_set_current_display + +- Trent Gamblin used higher compatibility flags to Direct3DCreate9, + made D3D driver die more gracefully on unsupported configurations, + removed flags from draw_line, and did more error checking. + +- Trent Gamblin turned al_init macros into an inline function. + +- Trent Gamblin commented out a TRACE line that was causing the entire + log to be overwritten. + +- Peter Wang fixed an incorrect call to _al_vector_find_and_delete. + +- Peter Wang made various formatting fixes. + +- Peter Wang converted CR/LF line endings to LF. + +- Trent Gamblin added NaturalDocs for the graphics api. + +- Trent Gamblin fixed an instance where a variable could have been + used uninitialized. + +- Trent Gamblin fixed texture coordinates in the D3D driver. + +- Trent Gamblin fixed formatting and an improper assertion. + +- Trent Gamblin removed a redundant call to al_set_target_bitmap. + +- Trent Gamblin fixed a bug in the DX joystick code that caused it to + assert when it shouldn't. + +- Trent Gamblin made al_create_display call al_flip_display + so the window is cleared. + +- Trent Gamblin made the D3D driver work where render-to-texture + is not supported. + +- Trent Gamblin removed masking support completely. + +- Elias Pschernig got the font example working with the GLX driver. + +- Elias Pschernig renamed the font addon in the scons build. + +- Jon Rafkind made scons build modules in a separate directory. + +- Jon Rafkind bumped the version to match cmake. + +- Jon Rafkind fixed esd to be like the other unix modules. + +- Trent Gamblin changed color map and unmap functions to use the target + bitmap. + +- Trent Gamblin added the font example to the cmake build process. + +- Elias Pschernig added the font example to the scons build process. + +- Elias Pschernig removed special handling of "src" dir, and made various + cosmetic changes. + +- Trent Gamblin made cmake install to MINGDIR. + +- Trent Gamblin added a better font and example for the bitmap + font addon. + +- Trent Gamblin removed unix header from install on other platforms. + +- Trent Gamblin added a bitmap font addon. + +- Trent Gamblin fixed a locking bug in the D3D driver. + +- Elias Pschernig removed masking from the GLX driver. + +- Trent Gamblin implemented blending for memory bitmaps + (very slow unless the blend mode is ALLEGRO_ONE,ALLEGRO_ZERO with a + pure white blend color). + +- Trent Gamblin implemented blending for the D3D driver. + +- Trent Gamblin added + ALLEGRO_PIXEL_FORMAT_ANY_(15|16|24|32)_(WITH_ALPHA|NO_ALPHA) + formats, used ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA in locking + examples, and ixed some formatting. + +- Trent Gamblin added al_clone_bitmap which makes an exact copy of the + color-data of a bitmap. + +- Trent Gamblin added a ALLEGRO_KEEP_BITMAP_FORMAT flag that forces + Allegro to use the same format as the disk file when loading bitmaps. + +- Elias Pschernig implemented video bitmap masking for the GLX driver (by + converting to alpha textures and drawing with alpha blending). + +- Elias Pschernig fixed clipping in the GLX driver. + +- Trent Gamblin removed ALLEGRO_MASK_SOURCE flag in favor of + ALLEGRO_USE_MASKING. Mask color is now a bitmap property. Removed + ALLEGRO_NO_ALPHA flag and changed the meaning of + ALLEGRO_USE_ALPHA to mean do alpha blending or not. Added + al_set/get_bitmap_mask_color and removed al_set/get_mask_color. + New masking example added (exnew_masking). + +- Trent Gamblin added proper clipping to al_put_pixel. + +- Trent Gamblin renamed graphics stuff from AL_ to ALLEGRO_ and removed + patterned drawing. + +- Elias Pschernig implemented clipping for the X11 GLX driver (only for + screen so far). + +- Trent Gamblin removed unused set_bitmap_clip entry from the bitmap vtable. + +- Trent Gamblin made clipping always enabled and made the clipping functions + operate on the current target bitamp. + +- Trent Gamblin removed src/compat/coblit.c. + +- Trent Gamblin renamed scroll_display to scroll_screen in display.c + +- Trent Gamblin Removed commented code from src/display.c. Removed + include/allegro/display.h and src/compat/cogfx.c + +- Elias Pschernig renamed XDUMMY driver to XGLX. + +- Elias Pschernig made some cosmetic changes. + +- Elias Pschernig made exblend work over the compatibility screen. + +- Elias Pschernig implemented upload_compat_screen method in the GLX + driver. + +- Elias Pschernig optimized al_lock_bitmap/al_unlock_bitmap slightly. + +- Elias Pschernig added a flags parameter to the drawing primitives methods. + +- Trent Gamblin added flags to primitives in display vtable and renamed + draw_filled_rectangle vtable entry to draw_rectangle. + +- Elias Pschernig implemented AL_SINGLEBUFFER flag and fixed bug with + AL_FULLSCREEN in the GLX driver. + +- Trent Gamblin added a mode parameter to al_set_drawing_pattern. + +- Trent Gamblin added AL_OUTLINED flag that is the default for primitives. + +- Trent Gamblin added al_set_drawing_pattern and al_get_drawing_pattern, + added a flags parameters to all the primitive drawing functions that + can be: AL_FILLED, AL_PATTERNED, and added hline and vline functions + for memory bitmaps. + +- Trent Gamblin ifdefed d3d stuff in win/wnewsys.c. + +- Trent Gamblin removed d3dx9 library from CMakeLists.txt. + +- Trent Gamblin ifdefed Direct3D stuff in display.c. + +- Jon Rafkind made scons read win32 files from cmake file list. + +- Trent Gamblin added al_wait_for_vsync and made it work with the D3D driver. + +- Elias Pschernig implemented immediate-resize for al_resize_display, and + implemented fullscreen resizing. + +- Trent Gamblin added al_enable_bitmap_clip and al_is_bitmap_clip_enabled, + added al_create_sub_bitmap, and made it work with D3D and memory + bitmaps. + +- Elias Pschernig improved fullscreen handling. + +- Elias Pschernig added shutdown_system vtable entry to the system driver, + and automatically call it on program exit. This allows unsetting + fullscreen modes in the X11 driver. + +- Trent Gamblin added al_set_bitmap_clip and al_get_bitmap_clip, and made + them work with D3D and memory bitmaps. + +- Elias Pschernig added XF86Vidmode fullscreen modes. + +- Elias Pschernig added xdummy files to cmake files list. + +- Elias Pschernig made al_resize_display work on non-resizable windows. + +- Elias Pschernig fixed opengl setup being issued in wrong thread. + +- Elias Pschernig moved src/misc/colconv.c from windows sources to general + sources. + +- Elias Pschernig uncommented accidentally commented out line. + +- Elias Pschernig made scons read the list of source files from + cmake/FileList.cmake, so there's only one place to add new files. + +- Trent Gamblin made _al_get_pixel_value faster. + +- Trent Gamblin made al_unmap_rgba_i use a table instead of relying on + al_unmap_rgba_f. + +- Peter Wang changed #includes to use file names from the root of the include + hierarchy, i.e. #include "allegro/internal/foo.h" instead of #include + "internal/foo.h" and likewise for allegro/platform/foo.h. + +- Peter Wang removed some stray CR characters. + +- Trent Gamblin added al_get_bitmap_width, al_get_bitmap_height, + al_get_bitmap_format, and al_get_bitmap_flags. + +- Trent Gamblin made al_draw_rotated_(scaled_)bitmap only lock the region of + the destination is needs to for memory bitmaps. + +- Trent Gamblin made al_draw_scaled_bitmap use the AL_FLIP_* flags. + +- Trent Gamblin added an example of resizing a fullscreen display. + +- Elias Pschernig updated xdummy driver and implemented al_resize_display + for it. + +- Elias Pschernig added another testcase. + +- Trent Gamblin added al_get_display_width and al_get_display_height, made + al_get_display_* work on the current display, and renamed + al_notify_resize to al_acknowledge_resize. + +- Trent Gamblin uncommented everything in cogfx.c (removing the display + parameter). + +- Trent Gamblin made exnew_lockscreen use pitch. + +- Trent Gamblin fixed scaled conversion macros (4444, 555, 565), added + XRGB_8888 pixel format, made windowed mode default, moved + get_num_display_modes and get_display_mode into the system + vtable. + +- Trent Gamblin made exnew_lockbitmap use pitch. + +- Trent Gamblin fixed D3D unlocking bug, and used desktop format in windowed + mode if not specified. + +- Elias Pschernig fixed a bug where events reported the wrong source display + under X11. + +- Elias Pschernig added three simple test cases. + +- Elias Pschernig fixed al_lock_bitmap and al_unlock_bitmap implementation + in the xdummy driver (for now it works in a slow way). + +- Trent Gamblin made al_notify_resize return success/failure and added + al_resize_display to resize the display from code. + +- Elias Pschernig started implementing lock_region and unlock_region for the + xdummy driver. + +- Elias Pschernig split xdraw.c out of xdisplay.c, + used _AL_THREAD instead of pthreads in the xdummy driver, + added a lock to the xdummy driver, in order to implement + al_destroy_display, used the correct format. + +- Elias Pschernig fixed a comment typo. + +- Elias Pschernig fixed a typo in AL_CONVERT_PALETTE_8_TO_ABGR_8888. + +- Trent Gamblin improved D3D line drawing, added al_get_num_display_modes and + al_get_display_mode, and cleaned up & organized some code. + +- Trent Gamblin removed _al_win_delete_from_vector. + +- Trent Gamblin added draw_memory_bitmap_region vtable hook to AL_DISPLAY. + +- Elias Pschernig implemented enough of the xdummy driver to run exnewap + (doesn't display correctly yet though). + +- Elias Pschernig updated scons build files. + +- Elias Pschernig Removed windows specific includes from exnewapi.c. + +- Elias Pschernig added missing al_convert_mask_to_alpha prototype. + +- Peter Wang fixed src/tls.c to compile under Linux (not tested). + +- Trent Gamblin put TLS support back in for MSVC and UNIX. + +- Trent Gamblin cleaned up some code, added headers to new source files, + grouped thread local variables into one structure (UNIX support is + broken for now), and made mask color thread local. + +- Trent Gamblin added clear, filled rectangle, and line for memory bitmaps. + +- Trent Gamblin made it so the system driver is no longer hard coded, + added switch_out method to display vtable, made the D3D window and system + driver code generic. + +- Trent Gamblin merged 4.9-elias and 4.9-trentg into 4.9-newgfx. + +- Elias Pschernig adjusted prototype of _al_init to implementation. + +- Elias Pschernig fixed a bogus cast. + +- Elias Pschernig fixed typo in al_get_new_diplay_format for non-mingw. + +- Trent Gamblin made display and bitmap parameters local to the calling + thread. + +- Trent Gamblin added al_draw_rotated_bitmap and + al_draw_rotated_scaled_bitmap for memory bitmaps using Allegro's + software rotation code as a base. + +- Trent Gamblin ported a stretch blit fix from 4.2, made al_init + call allegro_init, made al_draw_bitmap(_region) much faster on + memory bitmaps, and added al_draw_scaled_bitmap for memory bitmaps. + +- Trent Gamblin renamed AL_LOCKED_RECTANGLE to AL_LOCKED_REGION, and + started on memory bitmaps (al_draw_bitmap and al_draw_bitmap region work). + +- Trent Gamblin made seperate functions for getting/setting display/bitmap + parameters, made backbuffer-as-source bitmap work in D3D, and changed + parameter ordering of some functions. + +- Trent Gamblin added al_is_compatible_bitmap removed dependancy on + Allegro's 3D math functions from the D3D driver. + +- Trent Gamblin added al_convert_mask_to_alpha, made put/get_pixel + faster if the bitmap is locked ahead of time, and brought back + AL_MASK_SOURCE. + +- Trent Gamblin committed various bugfixes, implemented the RGB + mapping/unmapping functions from Bob's API. + +- Trent Gamblin removed the D3DX library dependancy. + +- Trent Gamblin committed various bugfixes and got all of the examples + working with the D3D driver. + +- Trent Gamblin fixed some of the compatibility conversions. + +- Trent Gamblin changed the examples back to autodetecting the graphics + driver. + +- Trent Gamblin made fullscreen mode work with the D3D driver, and + non-resizable windows. + +- Trent Gamblin finished bitmap conversion functions, improved locking, + implemented get/put pixel, and made some speed improvements. + +- Trent Gamblin added a bitmap conversion function. + +- Trent Gamblin got the demo game running in D3D. + +- Trent Gamblin removed an unnecessary bitmap copy. + +- Trent Gamblin added a skeleton D3D driver. + +- Peter Wang fixed the generation of allegro-config under Mac OS. + +- Michael Jensen fixed a mistake in the documenation for + is_compatible_font. + +- Peter Wang fixed wrong variable in example code for load_font(); + +- Trent Gamblin fixed some problems with the cmake build on Windows. + +- Peter Wang removed the second parameter in a call to + _al_event_source_needs_to_generate_event() which was missed + earlier. + +- Peter Wang exposed some internal documentation on destructors, + events and event sources to NaturalDocs. + +- Peter Wang changed al_wait_for_event() so that a timeout value of "0" + means to not wait at all. To wait an indefinite amount of time the + caller should pass the AL_WAIT_FOREVER constant. + +- Peter Wang removed the declarations of al_event_source_set_mask + and al_event_source_mask which were missed in the previous change. + +- Peter Wang removed event masking abilities, that is, for + the user to prevent an event source from generating particular + event types. This was implemented using bitfields which limited the + number of event types to 32. Although the limit could be raised + event masking was probably not very useful anyway. In all, the + functions removed are: al_event_source_mask, al_event_source_set_mask, + al_wait_for_specific_event. The al_wait_for_specific_event() API also + required event types to be bitfields. + +- Peter Wang fixed some spelling mistakes in the examples. + +- Peter Wang bumped the version to 4.9.2. + +- Peter Wang moved allegro/branches/4.3 to allegro/branches/4.9. + +- Ryan Patterson clarified the documentation of stop_sample(). + +- Peter Wang and Trent Gamblin fixed some issues with the CMake build. + The allegro-config script was not generated properly and + liballeg_unsharable wasn't being installed. + +- Matthew Leverton changed an instance of long long to LONG_LONG + and an LL suffix into a (LONG_LONG) cast, both for MSVC 6. + +- Matthew Leverton submitted a fix for MSVC 6 regarding MSVC's + lack of a \_\_FUNCTION\_\_ macro. + +- orz, Matthew Leverton, and Peter Wang made the ALLEGRO_USE_C=1 + option to work under MinGW and MSVC. + +- Anthony Cassidy fixed a typo. + +- Peter Wang removed the 'msvc' target from the fix.sh help message as it + should not be used by users any more. Added a comment that it is used by + zipup.sh. + +- Anthony 'Timorg' Cassidy made d_menu_proc fill up its assigned + area with the gui_bg_color. + + + +Changes from 4.9.0 to 4.9.1 (March 2007) +======================================== + +*Note that 4.9.1 was called 4.3.1 when it was originally released.* + +- Added a new mouse and cursor API. The new functions are: + + al_install_mouse, al_uninstall_mouse, al_get_mouse, + al_get_mouse_num_buttons, al_get_mouse_num_axes, al_set_mouse_xy, + al_set_mouse_z, al_set_mouse_w, al_set_mouse_axis, al_set_mouse_range, + al_get_mouse_state, al_mouse_button_down, al_mouse_state_axis + + al_create_mouse_cursor, al_destroy_mouse_cursor, al_set_mouse_cursor, + al_set_system_mouse_cursor, al_show_mouse_cursor, al_hide_mouse_cursor + +- Added documentation for some parts of the 4.9 API using the NaturalDocs + generation system. The documentation is nowhere near as good as a proper + manual, but it's still better than nothing. + +- Added a commented example demonstating the new API (exnew_events.c). + +- Added CMake and SCons build systems. These are mainly for use by Allegro + developers at present. + +- Various bug fixes and minor changes. + + + +Changes from 4.2 series to 4.9.0 (July 2006) +============================================ + +*Note that 4.9.0 was called 4.3.0 when it was originally released.* + +Basically we're just wrapping up what we have in version control up to +now. See the commit logs if you want details. + +This release introduces a few new subsystems. We have an event system, a +new keyboard API, a new joystick API, a new timer API, and the start of a +new graphics API. All of these are subject to change, as is usual for +a WIP. + +We are maintaining a certain level of source compatibility with the 4.2 +API. If it's easy to maintain compatibility then we do it, otherwise +compatibility is dropped. Obscure features are more likely to be dropped. + +This release has had minimal testing on Linux/x86, Windows/x86 (MinGW) and +Windows/x86 (MSVC). It seems to work on some Linux/x86-64 machines also. +Other ports are broken or untested. + +The new functions are as follows (in no particular order). No real +documentation exists at the moment but interesting header files +are: altime.h, display.h, draw.h, events.h, joystick.h, keyboard.h, +timer.h. + +- al_current_time al_rest + +- al_create_video_bitmap al_create_system_bitmap al_scroll_display + al_request_scroll al_poll_scroll al_show_video_bitmap + al_request_video_bitmap al_enable_triple_buffer al_create_display + al_set_update_method al_destroy_display al_flip_display al_get_buffer + al_get_update_method al_enable_vsync al_disable_vsync al_toggle_vsync + al_vsync_is_enabled al_blit al_blit_region al_blit_scaled + +- al_event_source_set_mask al_event_source_mask + +- al_create_event_queue al_destroy_event_queue al_register_event_source + al_unregister_event_source al_event_queue_is_empty al_get_next_event + al_peek_next_event al_drop_next_event al_flush_event_queue + al_wait_for_event al_wait_for_specific_event + +- al_install_joystick al_uninstall_joystick al_num_joysticks + al_get_joystick al_release_joystick al_joystick_name + al_joystick_num_sticks al_joystick_stick_flags al_joystick_stick_name + al_joystick_num_axes al_joystick_axis_name al_joystick_button_name + al_get_joystick_state + +- al_install_keyboard al_uninstall_keyboard al_get_keyboard + al_set_keyboard_leds al_keycode_to_name al_get_keyboard_state al_key_down + +- al_install_timer al_uninstall_timer al_start_timer al_stop_timer + al_timer_is_started al_timer_get_speed al_timer_set_speed + al_timer_get_count al_timer_set_count + + + + diff --git a/allegro/docs/src/changes-5.1.txt b/allegro/docs/src/changes-5.1.txt new file mode 100644 index 00000000..e6eabc00 --- /dev/null +++ b/allegro/docs/src/changes-5.1.txt @@ -0,0 +1,2024 @@ +% Allegro changelog for 5.1.x series + +See `changes-5.0.txt` for changes in Allegro 5.0.x. These lists +serve as summaries; the full histories are in the git repository. + + +Changes from 5.1.13 to 5.1.13.1 (February 2016) +============================================ + +The main developers this time were: SiegeLord. + +Image addon: + + - Fix regression in bitmap loading when compiled under MSVC. + + +Changes from 5.1.12 to 5.1.13 (January 2016) +============================================ + +The main developers this time were: Julian Smythe, Elias Pschernig and +Peter Hull. + +Graphics: + + - Add `al_get_opengl_program_object` (SiegeLord). + +Input: + + - Fix spurious triggering of the mouse grab key when it wasn't otherwise set + (SiegeLord). + +Android port: + + - Avoid multiple HALT/RESUME events on Android (Max Savenkov). + + - Implement `al_get_monitor_info` for Android (Reuben Bell). + + - Fix Android crash on file access. + + - Implement ALLEGRO_FULLSCREEN_WINDOW on Android. + + - Fix crash if display is destroyed while the app is switched out. + + - Add support for x86_64 Android. + + - Add `al_android_set_apk_fs_interface`. + +Linux port: + + - Allow using OpenGL ES in X11. + + - Fix the initial display size not being correct sometimes (SiegeLord). + + - Fix a race condition in the XInput joystick driver (Trent Gamblin). + +OSX port: + + - Fix various memory leaks. + + - Fix `al_set_window_title`. + + - Fix a lot of decrepid and deprecated code. + + - Fix single buffer flip display (SiegeLord). + +Windows port: + + - Fix Windows UNC path handling. + + - Fix clipboard nul-termination issues (Trent Gamblin). + + - Set the window title immediately upon window creation (SiegeLord). + +Build system: + + - Define CMAKE_FIND_ROOT_PATH for i686-w64-mingw32 cross compiler + (Martijn van Iersel). + + - Allow building with older CMakes again (SiegeLord). + + - Do not catche compile tests' failure (Bruce Pascoe). + + - Add a way to statically link the runtime with MinGW (SiegeLord). + + - Don't link the MSVC C runtime at all when requesting a static runtime and + building a static library (SiegeLord). + +Documentation: + + - Add links to the source code of the definitions of the most API entries. + + - Fix sidebar generation with modern Pandoc (Boris Carvajal). + +Python: + + - Fix ordering issue for HAPTIC* structs. + + - Fix missing ALLEGRO_PRIM_ATTR_NUM. + +Other: + + - Add a 'none' debug level to turn off logging entirely in debug builds + (SiegeLord). + + - Reconfigure logging after the configuration files are loaded (SiegeLord). + + - Fix al_set_new_window_title() off-by-1 (Bruce Pascoe). + + - Don't call al_get_time() before system is installed (SiegeLord). + +Audio addon: + + - Add `al_get_default_voice` and `al_set_default_voice`. + + - Flush the pulse audio stream rather than draining it, fixing some audio + breaks (SiegeLord). + + - Fill audio stream fragments with silence in the audio addon rather than in + the acodec addon, fixing some garbage output (SiegeLord). + + - Fix possible deadlock when destroying audio streams (SiegeLord). + +Acodec addon: + + - Don't read past the audio chunk's end when streaming wav files (SiegeLord). + + - Turn off allegro_acodec dynamic loading by default, fixing a common footgun (Bruce Pascoe). + +Image addon: + + - An enormous amount of work supporting reading of esoteric (and not) BMP + format variants (palletted, GIMP-style, etc). New tests were added using the + manual bmp suites. + +Native dialog addon: + + - Update code to work with modern OSX versions. + + - Clean up menu handling on OSX. + + +Changes from 5.1.11 to 5.1.12 (September 2015) +============================================== + +The main developers this time were: Bruce Pascoe, Beoran, Elias Pschernig, +SiegeLord, Trent Gamblin. + +Graphics: + + - Add `al_set_blend_color` and `al_set_blender`, for additional blending modes. + + - Add `ALLEGRO_MAXIMIZED` display flag. + + - Add `al_reparent_bitmap`, `al_get_bitmap_x/y`. This allows changing the + offset of a sub-bitmap. + + - Make `ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA` actually pick a format without an + alpha channel. + + - Add `al_premul_rgba` and `al_premul_rgba_f` convenience functions for + dealing with pre-multiplied alpha blending mode. + +Input: + + - Fix key auto-repeat on modern X11 versions. + + - Fix mis-detection of some joysticks on Android. + +Android port: + + - Fix a crash when minimizing the app before Allegro has been initialized. + +iOS port: + +Linux port: + + - Add `al_get_x_window_id` (Robert MacGregor) + +OSX port: + + - Fix some deprecated API usage. + +Windows port: + + - Fix a dangling pointer issue resulting in crashes when resizing on Windows + 10. + +Build system: + + - Build with multiple processors when using MSVC. + + - Make XInput2/touch input optional on Linux. + +Documentation: + + - Various documentation improvements. + + - Fix some badly formatted flags (Rodolfo Lam). + +Other: + + - Allow injecting Allegro events into event queses using + `al_emit_user_event` (Ryan Roden-Corrent) + + - Add `al_set_new_window_title` and `al_get_new_window_title`. + + - Add `al_get_clipboard_text`, `al_set_clipboard_text` and + `al_clipboard_has_text`. + + - Add `al_resume_timer` (Ryan Roden-Corrent). + + - Add `al_get_cpu_count` and `al_get_ram_size`. + +Audio addon: + + - Add multiple voice support for the AQueue driver. + + - Fix a bug when `al_restore_default_mixer` was called multiple times. + +Color addon: + +Font addon: + + - Add `al_draw_glyph`, `al_get_glyph_width`, `al_get_glyph_dimensions` and + `al_get_glyph_advance`. These functions are useful when additional control + is needed when drawing text. + + - Add `al_set_fallback_font`. + +Image addon: + + - Add `al_register_bitmap_identifier`, `al_identify_bitmap` and + `al_identify_bitmap_f`. This allows detecting the bitmap type by looking at + the initial few bytes in the file rather than relying solely on the + extension. + + - Allow saving bitmaps with uppercase extensions (Daniel). + +Native dialog addon: + + - Fix crashes when creating menus with sub-menus (Todd Cope). + +Video addon: + + - Allow using both Ffmpeg and Theora backends simultaneously. + + - Reduce latency of `al_get_video_frame` for the Theora backend. + + - Make the Theora backend send the `ALLEGRO_VIDEO_FRAME_SHOW` events. + + - Rename `al_get_video_width/height` to `al_get_video_scaled_width/height` + which now return the aspect corrected size of the video frame. + + - Rename `al_pause_video/al_is_video_paused` to `al_get/set_video_playing`. + + - Add `ALLEGRO_EVENT_VIDEO_FINISHED` event. + + - Remove `ALLEGRO_EVENT_VIDEO_FRAME_ALLOC` event. + + - Remove `al_get_video_aspect_ratio`. + +Examples: + + - New examples: ex_reparent, ex_inject_events, ex_clipboard, ex_cpu, + ex_timer_pause. + + +Changes from 5.1.10 to 5.1.11 (June 2015) +=========================================== + +The main developers this time were: SiegeLord, Trent Gamblin. + +Input: + + - Rename `al_get_haptic_active` to `al_is_haptic_active` for consistency. + + - Rename `al_get_num_haptic_effects` to `al_get_max_haptic_effects`. + + - Implement the missing `al_is_touch_input_haptic` function. + + - Move the loops parameter of `al_upload_and_play_haptic_effect` after the id + to be consistent with `al_play_haptic_effect`. + +OSX port: + + - Fix mouse warping in OSX. + + - Add retina display support to OSX. + +Windows port: + + - Fix querying display modes before creating a display. + + - Make the Windows joystick implementation more fault tolerant. + + - Initialize display callbacks when creating faux fullscreen (Edgar Reynaldo). + +Build system: + + - Fix the conditional compilation of sal.h (Edgar Reynaldo). + + - Don't look at WinSDK when we're not on MSVC, fixing MinGW builds when MSVC + is installed as well. + + - Fix the static FLAC compile tests on Android and Windows. + + - Make the OSX frameworks install in the proper location again. + + - Add `WANT_STATIC_RUNTIME` CMake build option (currently MSVC-only). + +Documentation: + + - Various documentation improvements. + +Other: + + - Return a valid configuration from `al_get_system_config` before Allegro is + installed. This allows you to override the various configuration options + without using an on-disk `allegro5.cfg`. + + - Compile in the logging support in release modes by default. Now logging can + be turned on in release builds without recompiling the program by editing + the system configuration. + + - Detect file-overruns when saving configuration files (Bruce Pascoe). + +Color addon: + + - When converting from YUV to RGB, clamp the returned values between 0 and 1. + +Video addon: + + - Use an enum in place of magic numbers for `al_get_video_position` constants. + + + +Changes from 5.1.9 to 5.1.10 (May 2015) +=========================================== + +The main developers this time were: SiegeLord, Elias Pschernig, Trent Gamblin, +Polybios. + +Input: + + - Add `al_set_mouse_wheel_precision` and `al_get_mouse_wheel_precision`. + +Graphics: + + - Added `al_transform_coordinates_3d`. + + - Added `al_build_camera_transform`. + + - Make the projection transform a bitmap local state. This removes + `al_set_projection_transform` and `al_get_projection_transform`, and replaces + them with `al_use_projection_transform` and + `al_get_current_projection_transform` with similar semantics to the regular + transforms. + +OSX port: + + - Improved joystick axis layouts on Mac OS X, and added support for some + dpards (Max Savenkov). + +X11 port: + + - Fix some memory leaks (ElectricSolstice). + + - Make the XInput2 check more accurate (we require a specific version). + +Windows port: + + - Remove taskbar hiding on Windows. + + - Fix high precision mice on Windows. + + - Fix some D3D conflicts with the OpenGL backend. + + - Remove the prohibition of building OpenGL-only DLLs. + + - Added LRESULT argument to WindowProc callback, fixing + `al_win_add_window_callback` for some event types (Aaron Bolyard). + +Android port: + + - Fix some memory leaks. + + - Make it possible to specify the Android target during building. + +iOS port: + + - Add an XCode project to help build Allegro when CMake support fails. + + - Restore the CMake support. + + - Makes the examples run on the iOS simulator out of the box. + + - Various small fixes (Trent Gamblin, jmasterx). + + - Remove `al_iphone_get_last_shake_time` and a`l_iphone_get_battery_level`. + + - Hack around iOS not creating mipmaps (jmasterx). + + - If the supported orientation is `ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN`, + default to supporting all orientations. + + - Get Cosmic Protector to compile again. + +Build system: + + - Revamp the detection of DirectX dependencies. Now it should work out of the + box for at least MSVC and mingw-w64. + + - Fix GDIPlus finding script (pkrcel). + + - Bump the minimum version of CMake to 2.8.5. + +Documentation: + + - Many documentation improvements, as always (special thanks to Polybios). + + - Make the PDF output prettier with better fonts and an up-to-date version + number. + + - Make the Javascript search for online documentation support partial matches. + + - Make [section] links work in HTML. + + - Allow the docs to have more than 1024 entries (Allegro is getting huge!). + +Other: + + - Make the test driver a little more resistant to failure. + + - Various fixes to the experimental SDL backend. + + - Update the CONTRIBUTORS.txt. + +Audio addon: + + - Fix deadlock when destroying an audio stream soon after its creation. + + - Add VOC file support (pkrcel). + + - Disable processing of the XM zero-speed event. + + - Disable processing of module loop points if `ALLEGRO_PLAYMODE_ONCE` is set. + + - Fix a buffer overflow bug. + +Image addon: + + - Fix loading of indexed + transparent PNGs with the libpng backend. + +Dialog addon: + + - Fix some style issues with the Windows file dialog. + + - Fix a bug with multiple filenames with the Windows file dialog. + + - Change the semantics of the patterns in `al_create_native_file_dialog` to + support future expansion of the patterns to support both AND and OR style + filtering. + + - Make the GTK file selection dialog look like it's from 2004 (as opposed to + mid-1990s). + +TTF addon: + + - Fix some warnings. + + - Make the page size dynamic, allowing for fonts with up to 8192x8192 glyphs + by default. + +Examples: + + - New examples: ex_camera, ex_projection2. + + + +Changes from 5.1.8 to 5.1.9 (January 2015) +=========================================== + +The main developers this time were: Trent Gamblin, SiegeLord, Elias Pschernig. + +Core: + + - Fix OSX backend on OSX 10.10 (lordnoriyuki). + + - Simplify how sub-bitmaps interact with their parent bitmaps. You can now + destroy a sub-bitmap at any time (not only before the parent is destroyed). + Additionally, when the parent is converted using `al_convert_bitmap`, all + the sub-bitmaps are also automatically converted. + + - Switch to using unicode Win32 (e.g. this fixes using `al_set_window_title` + with unicode strings). + + - Add some Linux WM hints so make Allegro windows work more smoothly + (especially with Unity). + +Filesystem: + + - Add `al_fprintf` (DanielH and Tobias Scheuer). + + - Add `al_for_each_fs_entry`, a convenience function that helps enumerating + the contents of a directory more easily using a callback function (Beoran). + + - Fix for `al_get_standard_path` with Unicode (vkensou). + +Input: + + - Add X11 touch driver (Ryan Gumbs). + + - Emulate mouse pressure for backends that don't support pressure. + + - Added Windows haptics driver, XInput joystick driver (Beoran). + + - Fix OSX joystick deinitialization. + +Graphics: + + - Add block compression pixel formats + (ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1/DXT3/DXT5) for compressed video + bitmaps. This includes an API to fetch compressed block size + (`al_get_pixel_block_width/height/size`) as well as API to load and unload + compressed bitmap data without paying a runtime compression cost + (`al_lock_bitmap_blocked`). Unfortunately, due to patent concerns this last + feature is disabled for OpenGL (if you thinks those concerns don't apply to + you, you can enable it by passing `-DWANT_OPENGL_S3TC_LOCKING=1` to cmake). + + - Make real fullscreen modes work on OS X again. May not be perfect still. + (thanks to SDL). + +Shaders: + + - Don't clobber the 0'th texture unit in OpenGL and Direct3D. This simplifies + working with shaders. + +Android port: + + - Bump minimum Android API level from 10 to 12 (aka version 3.1). + + - Add controller support to the Android port. An accelerometer 'joystick' + is still the first joystick. Supports two analog sticks and 10 buttons (A B + X Y L1 R1 DPAD_L DPAD_R DPAD_U DPAD_D). Supports hotplugging and + theoretically multiple joysticks (needs testing). + + - Set correct orientation at startup on Android (thanks to Aikei_c). + +Build system: + + - Various CMake fixes. + +Other: + + - Add Travis and AppVeyor continuous integration support. + + - Fix a lot of memory leaks. + + - Many documentation improvements. + +Audio addon: + + - Disallow attaching a mixer to itself. + + - Fix uni- and bi-directional looping of zero-length samples. + + - Fix/avoid all sound examples freezing on OSX with the aqueue driver. + +Image addon: + + - Add functionality to load Direct Draw Surface files (.dds). Only + compressed pixel formats are supported (DXT1, DXT3 and DXT5). + +Dialog addon: + + - Fix native file dialog default paths on Windows (Edgar Reynaldo). + + - Fix unintended behaviour in `al_set_menu_item_flags` (Malcolm Harrow). + + - Fix some bugs with native menus in OSX. + +Video addon: + + - Fix for now undefined AVCODEC_MAX_AUDIO_FRAME_SIZE (Dennis Busch). + +TTF addon: + + - Fix a crashing bug in the TTF addon. + + - Make `al_load_ttf_font_stretch` return NULL if invalid width/height are + passed. + +Font addon: + + - Add multi line text output for the font addon (`al_draw_multiline_text`, + `al_draw_multiline_textf` and `al_draw_multiline_ustr`). + +Primitives addon: + + - Fix some sharp-angle polyline drawing bugs. + +Examples: + + - New examples: ex_compressed, ex_font_multiline. + + - ex_dir: demonstrate `al_for_each_fs_entry`. + + - ex_haptic2: demonstrate hotplugging. + + + +Changes from 5.1.7 to 5.1.8 (January 2014) +========================================== + +The main developers this time were: Beoran, SiegeLord, Trent Gamblin, +Markus Henschel, Peter Wang. + +Core: + + - Allow MSVC to use DLL TLS but disable DLL TLS by default. + + - Do not include windows.h via allegro.h. + + - Fix some memory leaks on X11. + +Graphics: + + - Spell ALLEGRO_DST_COLOR, ALLEGRO_INVERSE_DST_COLOR with "DEST" + (with compatibility defines). + + - Fix bug which meant ALLEGRO_INVERSE_SRC_COLOR and + ALLEGRO_INVERSE_DEST_COLOR never actually worked on D3D. + + - Fix horizontal and vertical shears which were not composing with + translations correctly. + + - Optimise al_restore_state if saved target display/bitmap are unchanged. + + - Fix _al_display_settings_sorter ordering of indexes when scores are equal. + + - Use a minimum 16x16 texture workaround even on desktop OpenGL. + + - Propagate errors up OpenGL lock bitmap implementations. + + - Use proxy bitmap when locking writable backbuffer regions on GLES. + + - Clean up FBO creation during bitmap locking. + + - Move the half-pixel shift in D3D into the projection matrix. + Use the texture dimensions to compute the half-pixel shift. + + - Fix al_get_d3d_texture_size returning zeros. + + - Remove ALLEGRO_FORCE_LOCKING flag. + + - Setup GL viewport and projection in al_acknowledge_resize on Android. + + - Improve implementation of display options on Android: use the same display + setting scoring code as other ports; handle SUGGEST display options + properly; map ALLEGRO_COLOR_SIZE to EGL_BUFFER_SIZE attributes. + +Filesystem: + + - Add al_ferror and al_ferror. Initial patch by Tobias Scheuer. + + - Make al_fclose have a return value. + + - Check al_fclose return value in saving routines. + + - Make al_fopen_fd not leak a FILE handle in a failure path. + + - Make al_make_temp_file allocate temporary buffer to match the template. + + - android: Interpret the path to APK asset as AssetManager doesn't. + + - android: Correctly return -1 for APK asset file size if it can't be + determined. A side-effect is that FreeType (via the TTF addon) can now + load TTFs stored compressed in APK assets. + + - android: Support ungetc on APK file streams. + + - android: Fix EOF handling in AllegroInputStream. + +Input: + + - Initial haptics API, only implemented on Linux to begin with. + + - Use Linux input API for joystick driver instead of deprecated joystick API. + + - Use Linux joystick driver on Android if OUYA model detected + (Jonathan Lilliemarck). + + - Use thread for hotplugging joysticks on Linux instead of timerfd + (due to Android). + + - Report unichar in KEY_CHAR events on Android. (Todd Cope) + + - Added some Android gaming key codes. + + - iOS touch coordinates need to be multiplied by contentScaleFactor. + + - Android touch input id 0 was incorrectly treated as invalid. + (Max Savenkov) + +Shaders: + + - Automatically call OnLostDevice and OnResetDevice on HLSL shaders. + + - Remove #version specifier from all shaders. + +Audio addon: + + - Remove generic audio event source and AudioQueue events. + + - Don't queue silent fragments at start of new audio streams. + + - Make stream_read return correct number of filled samples when no data is + available (zero). + + - A DirectSound voice could not be restarted once it has been stopped. + + - Fix crash when attaching empty stream to dsound voice. + + - Reset buffer position in stop instead of play in dsound voice. + + - Fix calculation of current sample position in dsound voice. + + - Reset audio stream when al_set_audio_stream_playing to false for voice and + mixer cases, and make all fragments available for refill. + + - Emit stream fragment events when a stream is started. + + - Remove unnecessary reallocation of the channel matrix. + + - Add al_fill_silence. + + - Add al_get_audio_stream_played_samples. + + - Fix deadlock in Pulseaudio driver. Reported by Bluebird. + + - Let al_set_sample_instance_playing work for unattached instances + and sample instances with no data set. Reported by Bluebird. + + - Enable the use of the unpatched DirectX SDK to build. + +Audio codec addon: + + - Fix looping in Ogg Vorbis stream. (Todd Cope) + + - Seeking in wavs would always have returned success. + +Image addon: + + - Fix many problems in Android native image loader, including: + supporting ALLEGRO_NO_PREMULTIPLIED_ALPHA, respecting the new bitmap + format, working for non-APK assets, not crashing on failure. + +Native dialogs addon: + + - Change native menu ids from int to uint16_t due to limitation with + Windows. (Matthew Leverton) + +Primitives addon: + + - Rename the primitives buffer flags. + + - Simplify the prim buffer hints. + + - Simplify the al_create_vertex_buffer API. + + - Actually implement uninitialized vertex buffers. + + - Add indexed buffer API. + + - Polylines with ALLEGRO_LINE_CAP_CLOSED cap style did not draw correctly + with thickness == 0. + + - Take into account the projection matrix when computing the scale of the + high level primitives. + + - Replace enum arguments for al_draw_polyline and al_draw_polygon with + integers to reduce chance of ABI issues. + +TTF addon: + + - Fix a bug where some glyphs would be blank. + + - Allow glyph allocation to fail without crashing. + +Android port: + + - Separate Allegro library Java code from the original example project for + Android (Jonathan Lilliemarck). + + - Build Allegro library as a JAR. + + - Rename Java package to org.liballeg.android. + + - Change how the application shared library is specified. Override the + AllegroActivity constructor instead of specifying in AndroidManifest.xml. + + - Add a method to tell if the user exited main in the Android Java code. + + - Add a fix for the case of launching another activity from your game on + Android and then returning to the game after it finishes. + + - Refactoring and clean up. + +iOS port: + + - Remove al_iphone_get/set_screen_scale as not really needed and confusing. + +Build system: + + - Integrate Android port into build system, including building and launching + examples for debugging. + + - Detect OpenGLES/2 libraries on Android. + + - Let clang use same options as gcc in build system. + +Python: + + - Made the C-parser used in the Python API generator understand more type + constructs. (Elias Pschernig) + +Examples: + + - Make demos and most examples run (somewhat) on Android. + + - Add touch input support to various examples. + + - New examples: ex_file, ex_haptic, ex_haptic2, ex_touch_input. + + - ex_prim: Demonstrate indexed buffers. + +Other: + + - More more minor bug fixes and changes. + + - Documentation updates. + + - Syntax highlight the C source examples and prototypes in the documentation. + + + +Changes from 5.1.6 to 5.1.7 (May 2013) +====================================== + +The main developers this time were: Peter Wang, Trent Gamblin. + +Graphics: + + - Added al_horizontal_shear_transform, al_vertical_shear_transform + (Jeff Bernard). + + - Make al_destroy_bitmap maintain the current display when untargeting + the bitmap to be destroyed. + + - Delete al_create_custom_bitmap. + + - Delete al_ortho_transform compatibility macro. + + - Make al_get_d3d_texture_size fail instead of crash if passed a non-D3D + bitmap. + + - Make al_get_opengl_texture_size return success code to match D3D. + + - Rename al_d3d_set_release/restore_callback to be consistent with existing + naming, and pass the display as an argument. + + - Check availability of fullscreen button on window frame at run-time (OS X). + +Input: + + - Fix mouse warping on OS X. + + - Fix mouse warping in Linux evdev mouse driver. + +Audio addon: + + - pulseaudio: Use smaller buffer size by default, and make it configurable. + + - pulseaudio: Clean up state transitions. + +Color addon: + + - Fix al_color_rgb_to_html blue component (Jeff Bernard). + + - Implement al_color_html_to_rgb and al_color_html more strictly. + +Primitives addon: + + - Delete al_draw_polygon_with_holes. + + - Delete stride-less version of al_draw_polyline*. + + - Simplify interface of al_triangulate_polygon and + al_draw_filled_polygon_with_holes. + +Video addon: + + - Make al_seek_video return a result. + + - Fix crash when unable to open a Ogg video. + + - Don't scan to end of headers of unknown stream for Ogg video. + + - Stop reading at end of Ogg video. + + - Try to account for audio buffers in positioning of Ogg video. + + - Implement seek to beginning of file (only) in Ogg backend. + + - Replace deprecated av_find_stream_info() call (Nick Black). + +Android port: + + - Fix some Android switch in/out and exit issues. + +Build system: + + - Do not install most internal header files. + + - Do not search for and link with unneeded X libraries. + +Examples: + + - ex_audio_timer: New example. + + - Revise and comment the ex_prim_shader example and shaders (Paul Suntsov). + +Other: + + - Various documentation updates. + + - Minor fixes and much code refactoring. + + + +Changes from 5.1.5 to 5.1.6 (March 2013) +======================================== + +The main developers this time were: Trent Gamblin, Paul Suntsov, Peter Wang. + +Core: + + - Fix use of clobbered return value from setlocale() on X11. + + - Register system interface even if no display driver available on Windows. + + - Fix use of double math functions for float arguments (Nick Trout). + +Shaders: + + - Revamped shader API. The shader API is now part of the core library, + and the shader addon removed. + + - Shaders are now a per-bitmap property, set with al_use_shader. + A bitmap without a set shader uses a default shader internally, + that allows Allegro drawing functions to work as in non-programmable + pipeline mode. + + - Shader variable setters operate on the shader of the target bitmap. + + - Rename ALLEGRO_USE_PROGRAMMABLE_PIPELINE to ALLEGRO_PROGRAMMABLE_PIPELINE. + + - Rename al_link_shader to al_build_shader. + + - Remove al_set_shader. + + - Remove the al_set_shader_*_array functions. These functions cannot + be easily (or at all) implemented with the D3D backend. + + - Add al_get_shader_platform and al_get_default_shader_source. + + - Remove al_get_opengl_program_object, al_set_opengl_program_object, + al_get_direct3d_effect, al_set_direct3d_effect. + + - Remove Cg shader backend. + + - Add macros for shader variable names (Jon Rafkind). + +Displays: + + - Made al_get_display_mode return the closest thing to a pixel format + possible with the WGL driver (tobing). + + - Move WGL context destruction out of the message pump thread and into + the user/main thread. + + - Allow command-tab to work in fullscreen window mode on OS X. + + - Remove "user_reload" parameter from al_acknowledge_drawing_resume. + + - Don't crash in al_create_display if there is no display driver. + + - Don't crash at shutdown if there is no display driver (Windows). + + - Don't fail init if both D3D, GL drivers unavailable (Windows). + + - Sync bitmaps before resizing display to prevent changes being lost + after the resize (D3D). + + - Load the D3D9X module during display creation and unload it when the + D3D system shuts down. + + - Run fullscreen toggle on main thread (OS X). + + - Destroy the backbuffer bitmap when destroying the display (OS X). + + - Switch to new NSTrackingArea API (OS X). + + - Set ALLEGRO_NO_PRESERVE_TEXTURE on backbuffer (OpenGL). + +Graphics: + + - Let al_destroy_bitmap implicitly untarget the bitmap on the calling + thread. + + - Fix a bug where bitmap locking may change the target bitmap but + not restore it back to NULL (OpenGL). + + - Use memory bitmap drawing when either bitmap is locked (OpenGL). + + - Fix a crash in D3D destroying sub-bitmaps. + + - Add const qualifiers to glUniform*v() functions (Aaron Bolyard). + +Input: + + - Partially fix mouse buttons "sticking" on Mac, e.g. holding the + mouse and toggling fullscreen window. + + - al_set_mouse_xy on Windows resulted in the mouse getting set to the wrong + position in windowed modes + + - Scale the user supplied mouse cursor if it's too big (Windows). + + - Add key constants for some Android keys, those that are used in Xperia + Play controls. + +Audio addons: + + - Fix PulseAudio driver trying to connect to a non-existent server forever. + + - Avoid memory leaks with audio event source. + + - Use smaller buffer size for OpenSL. + +Image addon: + + - Use Allegro built-in loaders in preference to OS X loaders for BMP/TGA/PCX. + The OS X TGA loader doesn't support alpha and this is also more consistent. + +Font addons: + + - Make al_init_font_addon return success value. + + - Make al_init_ttf_addon return true for subsequent calls. + +Native dialogs addon: + + - Fix a crash on iOS due to threading/TLS issues geting the display + (Nick Trout). + +Primitives addon: + + - Speed up al_triangulate_polygon_with_holes. + + - Speed up drawing of the rounds for polylines. + + - Add custom vertex attributes to the primitives addon. + + - Replace vertex shader binary generated by vsa.exe (removed from DirectX + SDKs for a while now) by that generated by fxc.exe. + + - A minor revamp of the HLSL default shader system in the primitives addon. + + - Fix a few incorrect usages of al_lock_vertex_buffer + + - Disallow 3 component vectors for ALLEGRO_PRIM_TEX_COORD. + + - Add a whole bunch of new ALLEGRO_PRIM_STORAGE values. + + - Primitives addon was ignoring the filter settings of textures in the D3D + backend. + +Android port: + + - Generate KEY_CHAR on Android. + + - Add key constants for Android. + + - Set target bitmap to display backuffer after program is resumed. + + - Use different functions for OpenGL ES 1 and OpenGL ES 2 on Android. + +iOS port: + + - Support stencil buffer on iOS. + + - Remove unnecessary autorelease pools. There was a crash when using + Airplay that goes away without the pools. + + - Make Airplay work the standard way most apps do unless the + Allegro user explicitly creates a display on the second screen. + + - Don't autorotate displays other than device. + + - Fix some threading and memory issues. + +Raspberry Pi port: + + - Allow for color size, depth and stencil sizes. + + - Support al_show_mouse_cursor and al_hide_mouse_cursor. + Disabled as it sometimes ends up stuck on the screen until reboot. + +Examples: + + - New examples: ex_prim_shader, ex_shader_target. + +Other: + + - Various documentation updates. + + - Minor fixes and code refactoring. + + + +Changes from 5.1.4 to 5.1.5 (January 2013) +========================================== + +The main developers this time were: Trent Gamblin, Elias Pschernig, +Jon Rafkind, Peter Wang. + +Ports: + +- Initial port to Raspberry Pi by Trent Gamblin. + +Core: + +- Added an al_register_trace_handler function. + +- Clean up logging subsystem at shutdown (muhkuh). + +- Fix a problem with creating a display after Allegro is shut down + then re-initialised on X11. + +Displays: + +- Fix crashes when resizing a WGL fullscreen window. + +- Fix use of invalidated pointers in D3D driver when the first format fails. + +- Fix bug where setting the mouse cursor had no effect when + the mouse was captured (mouse button held down). + +- Fix windows not having a minimise button when set to + windowed state from fullscreen window state. + +- Respect ALLEGRO_FRAMELESS flag properly when toggling from + fullscreen window state to windowed state (Windows). + +- Don't generate DISPLAY_LOST events when resizing a fullscreen display. + +- Fix al_set/get_window position on Windows so getting/setting + to the same position continuosly doesn't move the window. + (Michael Swiger) + +- Rename al_change_display_option to al_set_display_option. + +- Add al_set_display_icons (plural), implemented for X11 and Windows. + +- Add ALLEGRO_GTK_TOPLEVEL display flag for X11. + +- Fix window resizing when using shaders (X11). + +Graphics: + +- Avoid null pointer dereference when setting a target bitmap after + its video_texture has already been released (D3D). + +- Make d3d_lock_region fail immediately if _al_d3d_sync_bitmap + failed, likely because the device was lost. + +- Set device_lost flag immediately when d3d_display_thread_proc + finds the device is lost. + +- Fix OpenGL extensions being completely ignored on OS X. + +- Added a quick hack to fix bitmap locking on desktop OpenGL when using + shaders. + +Config: + +- Added al_remove_config_key and al_remove_config_section functions. + +File I/O: + +- Fix al_read_directory crash on 64-bit Windows (simast). + +Filesystem: + +- Keep absolute path in ALLEGRO_FS_ENTRYs so that later changes to the + current working directory do not affect the interpretation of the path. + +- Set ALLEGRO_FILEMODE_HIDDEN properly on Unix. + +- Make sure stat mode bits are cleared in default implementation of + al_update_fs_entry. + +- Support Unicode paths on Windows. + +- Change description of al_get_fs_entry_name about not returning absolute + path if created from relative path; no longer true for either the default + or Physfs implementations. + +Audio addons: + +- Fix setting the speed of an audio stream after it was attached to the mixer + (Paul Suntsov). + +- Shut down threads properly when when destroying FLAC and modaudio streams. + +Font addon: + +- Avoid making x offset non-integral for ALLEGRO_ALIGN_CENTRE. + +- Make al_draw_justified_* respect ALLEGRO_ALIGN_INTEGER. + +TTF addon: + +- Don't save the projection transform if no display is set. + +Image addon: + +- Added a missing autorelease-pool to the OSX bitmap saving function + (sleepywind). + +- Fix OSX native image loader for loading not-premultiplied RGB data. + Previously the data was "de-multiplied", with possibly all information lost. + +- Fix OSX native image loader for loading bitmaps without an alpha channel. + They appeared completely black previously. + +- Fixed loading interlaced .png files with libpng. + +Native dialogs addon: + +- Do not unload of rich edit module when closing one text log window while + another exists. Reported by URB753. + +- Use default colours for Windows text log implementation, avoiding problems + when the previous custom colours failed, leading to black text on a + nearly black background. + +- Add al_shutdown_native_dialog_addon. + +- Add native menu support on X11 (requires ALLEGRO_GTK_TOPLEVEL). + +- Add native menu support on OS X. + +PhysicsFS addon: + +- Implement al_change_directory semantics (Todd Cope). + +Primitives addon: + +- Fixed textured primitives when using shaders (OpenGL). + +Shader addon: + +- Add dynamic loading of d3dx9_xx.dll (Michał Cichoń). + +- Add dynamic loading of Cg DLLs (Michał Cichoń). + +- Started implementing default shaders. Only GLSL so far. + +- Fix null pointer dereference in al_create_shader if backend init fails. + +Android port: + +- Fix setting the current display on Android. + +- Don't set the backbuffer when setting up the OpenGL view. + +Build system: + +- Rename allegro\*-5.1.pc files to allegro\*-5.pc. + The new names will be available in future 5.0.x releases. + +- Generate and install allegro_shader pkg-config file. + +- Only generate and install pkg-config files for libraries that we build. + +Examples: + +- ex_icon2: New example. + +- ex_shader_multitex: New example. + +- ex_shader: Choose shader platform on command-line; external shader sources. + +- ex_menu: Various changes. + +- speed: Avoid poor performance due to needless redraws. + +Other: + +- Documentation updates, many thanks to beoran. + +- A lot of code refactoring. + + + +Changes from 5.1.3 to 5.1.4 (October 2012) +========================================== + +The main developers this time were: Trent Gamblin, Elias Pschernig, Peter Wang. + +Graphics: + +- Fixed al_convert_bitmap using the target instead of the source format when + converting its data. + +- Fix a crash in Direct3D in al_set_target_bitmap when switching from a memory + target. + +- Fix a potential crash when drawing the screen to a bitmap with D3D. + +- WGL shouldn't need to preserve bitmaps. + +- Update the projection transform when setting up the OpenGL context + on X11 (SiegeLord). + +- Lock bitmap to prevent slowness when creating a cursor from a non-memory + bitmap on Windows. + +- Conditionally lock bitmap when creating cursor on X11 (previously it did + so even if already locked). + +Input: + +- Make al_install_touch_input fail under Windows if there is no touch device. + +- Temporary fix for delay after mouse warp on OS X. + +File I/O: + +- Fix al_fputc on big-endian. Reported by Andreas Rönnquist and + Tobias Hansen. + +- Make al_fputc return value like fputc when out of range. + +Image addon: + +- gdiplus: Only preserve indexed images with KEEP_INDEX flag on. + +Font addons: + +- Added ALLEGRO_ALIGN_INTEGER text drawing flag (Todd Cope). + +- Added a new al_get_font_ranges function. + +- Made TTF addon include padding on the top and left edges of pages + (Todd Cope). + +Audio addon: + +- Use programmatically generated interpolators. They cover an additional + case which was missed and should be slightly more efficient. + +- Support linear interpolation for 16-bit mixers. + +- Add cubic interpolation for mixers (off by default). + +- Fix potential deadlock in stop_voice for OpenAL. + +- Fix potential deadlock in stop_voice for DirectSound. + +- Improve buffer filling behaviour for DirectSound, reducing pops and + crackles significantly on slower machines. + +- Increase default buffer size for DirectSound to 8192 samples. + +Android port: + +- Support ALLEGRO_KEYBOARD_STATE. + +- Fix return type of APK_tell (Todd Cope). + +- Allow use of OpenGL ES 2 under Android. + +iOS port: + +- Make orientation changes work on iOS with SDK 6. + +Build system: + +- Rename native dialog library back to allegro_dialog to match 5.0. + +- Install pkg-config files when cross-compiling on Unix. + +Python: + +- Make the Python wrapper also check for the monolith DLL. + +Examples: + +- ex_synth: Add button to save waveform to a file. + +- ex_multisample: Demonstrate using moving bitmaps. + +- Renamed a5teroids to Cosmic Protector + +Other: + +- Minor bug fixes and documentation updates. + + + +Changes from 5.1.2 to 5.1.3 (August 2012) +========================================= + +The main developers this time were: Dennis Busch, Trent Gamblin, +Elias Pschernig, Jon Rafkind, Paul Suntsov, Peter Wang. + +Displays: + +- Rewrite D3D display format listing code, which was broken. This should + re-enable multi-sampling and fix ex_depth_mask being slow with D3D. + +- Fixed a case where changing fullscreen mode in D3D via al_resize_display + caused a crash and loss of loaded bitmaps information. + +- Fixed a case where changing fullscreen mode in OpenGL (on Windows) via + al_resize_display cause nothing to be rendered after the mode change. + +- Fixed OpenGL (Windows) bitmap preservation between fullscreen mode changes. + +- Fixed missing/incorrect resize events under Windows. + +- Fixed ALLEGRO_FULLSCREEN_WINDOW under OS X. + +- Fix al_set_new_display_adapter on OS X. + +- Enable fullscreen icon on resizable windows on OS X 10.7 and up. + +- Added al_osx_get_window function (Dennis Gooden). + +Graphics: + +- Rename al_ortho_transform to al_orthographic_transform + and give it a more consistent parameter order. + +- Add al_perspective_transform and al_translate|scale|rotate_transform_3d. + +- al_draw_pixel was crashing when drawn on sub-bitmaps on OpenGL. + +- Make ogl_flush_vertex_cache disable GL_TEXTURE_2D state. + +- Don't use NSOpenGLPFAAccelerated unnecessarily (OS X). + +Input: + +- Fix incorrect keyboard modifier flags after leaving and re-entering a window + (Windows). + +- Fixed a bug with mouse enter/leave events for resized windows under OSX + (Dennis Gooden). + +Audio addon: + +- Add OpenSL ES driver for Android. + +Font addons: + +- Add builtin font creation function. + +- Preserve projection transformation when caching glyphs in the TTF addon. + +Image addon: + +- Don't include native image loader source files when the native image loaders + are disabled. + +Primitives addon: + +- Add vertex buffer API. + +Native dialogs addon: + +- Run NSAlert on the main thread (OS X). + +Android port: + +- Many bug and compatibility fixes. + +- Support al_inhibit_screensaver on Android. + +- Generate SWITCH_IN/OUT events on Android similar to iOS. + +- Support render state API on Android. + +- Make al_acknowledge_drawing_resume take a user callback parameter for + interdependant textures. + +- Support building Android port for x86. + +- Add an ANDROID_APP_NAME CMake variable which will replace all + org/liballeg/app and org_liballeg_app with your own app name + +Build system: + +- Make the monolith dll under Windows use proper dll exports with MSVC. + +- Properly include the main addon in the monolith build. + +- Add Physfs and Cg include directories. + +Examples: + +- Added new examples: ex_projection, ex_vertex_buffer. + +Other: + +- Documented the allegro_main addon. + +- Various minor bug fixes and cleanups. + + + +Changes from 5.1.1 to 5.1.2 (May 2012) +====================================== + +The main developers this time were: Thomas Fjellstrom, Trent Gamblin, +Elias Pschernig, Peter Wang. + +Core: + +- Add userdata to Windows window callbacks and rename the functions + (Matthew Leverton). + +- Fix ALLEGRO_STATIC_ASSERT collisions from different files included in the + same translation unit. Reported by tobing. + +- Make al_ustr_empty_string const correct. + +- Fix many memory leak/warnings on MacOS X (Pär Arvidsson). + +Filesystem: + +- Make stdio al_fopen implementation set proper errno on failure. + +- Make al_get_standard_path(ALLEGRO_TEMP_PATH) treat environment values + as directory names even without a trailing slash on Unix. + +- Fix typo preventing get_executable_name from using System V procfs + correctly. Reported by Max Savenkov. + +Displays: + +- Fixed bug on Windows where two SWITCH_IN events were fired when window was + minimized/restored (Michael Swiger). + +- Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic under Windows + as well as a bug where repeatedly setting the flag to on would make the + window grow bigger and bigger (Michael Swiger). + +- Fixed inverted al_toggle_display_flag(ALLEGRO_NOFRAME) logic in X11. + +- Rename al_toggle_display_flag to al_set_display_flag, retaining + the older name for compatibility. + +- Add ALLEGRO_FRAMELESS as a preferred synonym for the confusing + ALLEGRO_NOFRAME flag. + +- Set WM_NAME for some window managers (X11). + +- Disable the idle timer on iOS (screen lock) when entering airplay mode. + +- Make al_destroy_display handle display disconnection properly. + The user will need to clean up then call al_destroy_display after receiving + ALLEGRO_EVENT_DISPLAY_DISCONNECTED (iOS). + +Graphics: + +- Added al_get_parent_bitmap (Paul Suntsov). + +- Make blitting from backbuffer work when using multisampling on Windows/D3D. + +- Redefine pixel format LUMINANCE_8 as SINGLE_CHANNEL_8. + +- Map SINGLE_CHANNEL_8 to red channel only. Fix some software pixel format + conversion bugs previously present with the LUMINANCE_8 format. + +- Added al_create_custom_bitmap. + +- Remove ALLEGRO_PRESERVE_TEXTURE flag. The idea is to always preserve + textures unless directed otherwise by the user with + ALLEGRO_NO_PRESERVE_TEXTURE. + +- Added al_clear_depth_buffer and al_set_render_state functions. + +- Force al_create_bitmap to not create oversized bitmaps, to mitigate + integer overflow problems. + +- Removed initial black frame on all Allegro programs. + +OpenGL: + +- Fix null pointer dereference if backbuffer creation fails. + Reported by Max Savenkov. + +- Made the ALLEGRO_OPENGL_FORWARD_COMPATIBLE flag work with al_draw_bitmap. + +- Texture should be 'complete' (min/mag and wrap set) before glTexImage2D. + +- Restore matrix manipulation code for unlocking backbuffer in GL <1.4 case. + +- Fixed a bug in al_unlock_bitmap where the pixel alignment mistakenly was + used as row length. + +- Never set the projection when using programmable pipeline mode unless a + program object is bound. + +- Do not preserve bound texture state. + +- Disable GL_NORMAL_ARRAY in non-programmable pipeline mode. + +- Fixed typo in names of some OpenGL extension functions. + +- Display list of OpenGL extensions in allegro.log also for OpenGL 3.0. + +- Check for OES_texture_npot as well for non-power-of-two support. + +- Fix loading of some textures on iOS. + +Direct3D: + +- Fixed a bug in the D3D driver where separate alpha blending was being + tested for when it shouldn't have been (Max Savenkov). + +- Do not manage depth stencil surface. + +- Arrange code so that sleep and hibernate work using the release and restore + callbacks. + +- Fix device reset problem in D3D. + +- Make sub-bitmap restore properly on lost device. + +Input: + +- Increase max number of joystick "sticks". Due to analogue buttons being + mapped to axes, the number of sticks on a single device may be much higher + than expected. + +- Monitor /dev/input instead of /dev on Linux for hotplugging joysticks + (Jon Rafkind). + +- Do not permanently change the locale for the X11 keyboard driver. + Set LC_CTYPE only, not LC_ALL. + +- Update ALLEGRO_MOUSE_STATE even if mouse emulation event source isn't + attached to an event queue (Android and iOS). + +- Don't report shakes at program start accidentally (iOS). + +Android port: + +- Many graphics-related changes (too many to list). + +- Make Android port always choose a double buffered graphics mode. + +- Don't force 16-bit mode if no COLOR_SIZE specified. + +- Go fullscreen (no title/status bar). + +- Generate ALLEGRO_EVENT_DISPLAY_HALT_DRAWING, RESUME_DRAWING events instead + of SWITCH_IN/OUT. + +- Add an APK file driver for reading assets directly from Android app bundles. + +- Additions and fixes to accelerometer and orientation code. + +- Support for volume keys. + +- Added a dummy mouse driver, enough to get al_get_mouse_state working. + +- Improve compatibility of touch input emulation driver with iOS touch input + emulation. + +- Add al_android_get_os_version(). + +- Fix linking problem on Android 2.2 and below. + +- Update and clean up sample project. + +Audio addon: + +- Fix desychronization due to inaccurate sample positions when resampling. + Thanks to _Bnu for discovering the issue and Paul Suntsov for devising the + correct solution. + +- Fix linear interpolation across audio stream buffer fragments. + +- Add stub OpenSL driver (Jon Rafkind). + +Image addon: + +- Improved accuracy of un-alpha-premultiplying in the native OSX bitmap loader. + +- Improve compatibility of BMP loader. In particular, support bitmaps with + V2-V5 headers and certain alpha bit masks. + +- Improve robustness of BMP loader against some corrupt files. + +- Fix TGA loader using more memory than necessary. Reported by Max Savenkov. + +- Image loading in Android now works. + +Font addon: + +- Use user set pixel format for fonts. + +TTF addon: + +- Added ALLEGRO_TTF_NO_AUTOHINT font loading flag to disable the Auto Hinter + which is enabled by default in newer version of FreeType (Michał Cichoń). + +- Unlock glyph cache page at end of text_length and get_text_dimensions + (jmasterx). + +Primitives addon: + +- Use GL_REPEAT so textures can be tiled again. + +- Always set the texture due to missing glGetInteger on some GLES 1.0/1.1 + devices. + +Native dialogs addon: + +- Only call SetMenu from within the window thread (Matthew Leverton). + +- Clear mouse state after dialogs or else it gets messed up (OSX). + +- Fix some warnings in gtk_dialog.c. + +Build system: + +- Added OSX Framework support for the monolith library. + +- Make examples build with monolith build. + +- Add WANT_ANDROID_LEGACY to allow compiling for older Android platforms. + +Examples: + +- a5teroids: Added high scores and other improvements. + New graphics by Tony Huisman. + +- Add ex_file_slice. + +- Add ex_resample_test. + +- Add ex_depth_mask. + +- ex_audio_props: Add bidir button. + +- ex_joystick_events: Support hotplugging and fix display of 3-axis sticks. + +- ex_polygon: Test al_draw_filled_polygon_with_holes. + +- ex_get_path: Test al_set_exe_name. + +- Made the skater demo run from within xcode. + +- Add test_driver --no-display flag. (Tobias Hansen) + +- Add test_driver --force-opengl-2.0 option. + +- Make .png and .tga loading tests to not require a backbuffer with an alpha + channel. + +Other: + +- Many minor bug fixes. + +- Many documentation updates. + +- Fix whatis entries of man pages. (Tobias Hansen) + + + +Changes from 5.1.0 to 5.1.1 (February 2012) +=========================================== + +The main developers were: Thomas Fjellstrom, Trent Gamblin, Matthew Leverton, +Elias Pschernig, Jon Rafkind, Peter Wang. + +Ports: + +- Thomas Fjellstrom started an Android port. Displays, keys and touch events + work. + +Core: + +- Make al_ref_cstr, al_ref_ustr and al_ref_buffer return const ALLEGRO_USTR* + instead of just an ALLEGRO_USTR* (Paul Suntsov). + +Graphics: + +- Fixed a bug in the OpenGL driver when drawing the backbuffer outside the + clipping rectangle of the target bitmap. + +Displays: + +- Fixed a problem with wrong window size when restoring a minimised window, in + code that was added to support window constraints (jmasterx). + +- Set ALLEGRO_MINIMIZED display flag on Windows (Zac Evans). + +- Prevent a deadlock during display creation on X. + +- Fallback to the 'old' visual selection method on X instead of crashing + if the 'new' visual selection doesn't work. + +- Implement XEmbed protocol. + +- Add hot plug display support on iOS (Airplay and wired.) + +Input: + +- Use the same logic in set_mouse_xy for FULLSCREEN_WINDOW as was used for + FULLSCREEN. (Max OS X) + +Audio addons: + +- Add audio recording API with implementations for ALSA, AudioQueue, + DirectSound8 and PulseAudio. + +- Improve code to check that DLL symbols are loaded in the acodec addon. + The old method was hacky and broke under -O2 using GCC 4.6.1. (Paul Suntsov) + +Image addon: + +- Some initial Android support. + +- Write libjpeg errors to Allegro log. + +TTF addon: + +- Clear locked region so pixel borders aren't random garbage that can be seen + sometimes with linear filtering on. + +Video addon: + +- Added Ogg Theora/Vorbis backend. + +- Fixed a few warnings with ffmpeg version 0.7/0.8. + +Build system: + +- Add monolith library option. + +- Detect the new MinGW cross-compiler in Ubuntu. + +Examples: + +- Added new examples: ex_record, ex_record_name, ex_display_events. + +- ex_ogre3d: Make it work under Windows (AMCerasoli). + +- skater: small bug fixes, mouse support, add missing files for scrollers. + +- a5teroids: Support gamepads that report small non-zero values for sticks + that are at rest. + +- Added pong example in Python. + +Other: + +- Added index to HTML version of the reference manual. + +- Various documentation updates. + +- Other minor bug fixes. + + + +Changes from 5.0.x to 5.1.0 (November 2011) +=========================================== + +The main developers were: Michał Cichoń, Trent Gamblin, Matthew Leverton, +Elias Pschernig, Paul Suntsov, Peter Wang. + +Core: + +- Added al_register_assert_handler. + +- Added API for registering callbacks to intercept window messages on Windows. + +Graphics: + +- Added bitmap conversion API: al_convert_bitmap, al_convert_bitmaps, with + bitmap flag ALLEGRO_CONVERT_BITMAP and display option + ALLEGRO_AUTO_CONVERT_BITMAPS. Automatic bitmap conversion is enabled by + default. + +- Added al_draw_tinted_scaled_rotated_bitmap_region. + +- Added new ALLEGRO_PIXEL_FORMAT_LUMINANCE_8 format. + +- Added a new bitmap flag ALLEGRO_KEEP_INDEX. + +- Separate bitmap loader flags from bitmap flags. This adds three functions: + al_load_bitmap_flags, al_load_bitmap_flags_f and al_load_bitmap_font_flags. + +- Add ALLEGRO_SRC_COLOR, ALLEGRO_DST_COLOR blending modes (Jon Rafkind). + +- Add ALLEGRO_INVERSE_SRC_COLOR and ALLEGRO_INVERSE_DST_COLOR blending modes. + +- Made al_compose_transform do a full 3d multiply. + +- Added al_get_current_inverse_transform, al_ortho_transform, + al_get_projection_transform, al_set_projection_transform. + +- Added al_reset_clipping_rectangle convenience function. + +- Added al_get_d3d_texture_size. + +- Added al_d3d_set_release_callback and al_d3d_set_restore_callback for + release/restoring user d3d objects. + +Displays: + +- Added al_get_display_orientation. + +- Added a new display option ALLEGRO_SUPPORTED_ORIENTATIONS to specify the + supported orientations (default is just portrait as before). + +- Added al_change_display_option function, initially only for + ALLEGRO_SUPPORTED_ORIENTATIONS. + +- Add two new display events (only implemented on iOS right now). + ALLEGRO_EVENT_DISPLAY_HALT_DRAWING tells the app to stop all drawing and + ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING tells it it can start drawing again. + SWITCH_OUT/IN on iOS were redefined from "going into/out of background" to + "going active/inactive". + +- Added the function al_acknowledge_drawing_halt. + +- Added window size constraint functions (jmasterx). + +Input: + +- Add API related to touch input. The implementation covers iDevices and + Windows 7 drivers for touch input. A number of mouse emulation modes + are provided. + +Events: + +- Add al_pause_event_queue, al_is_event_queue_paused. + +Filesystem: + +- Added al_fopen_slice. + +- Added al_set_exe_name which allows overriding Allegro's idea of the path + to the current executable. + +Audio addon: + +- Add mixer gain property and functions. + +- Add a 'global' audio event source, generating some audio events from the + Audio Queues driver: AUDIO_ROUTE_CHANGE, AUDIO_INTERRUPTION, + AUDIO_END_INTERRUPTION. + +Native dialogs addon: + +- Add menus to native dialogs (Windows and GTK). + +Primitives addon: + +- Add simple polygon triangulator and polygon drawing routines. + +- Added al_draw_polyline and al_draw_polyline_ex. + +- Added al_draw_filled_pieslice and al_draw_pieslice. + +- Added al_draw_elliptical_arc. + +TTF addon: + +- Added al_load_ttf_font_stretch functions (tobing). + +Shader addon: + +- Added a shader addon and programmable pipeline support. + +Video addon: + +- Added a video player addon, currently using ffmpeg. + +iOS port: + +- Added al_iphone_override_screen_scale, al_iphone_get_screen_scale, + al_iphone_set_statusbar_orientation, al_iphone_get_last_shake_time, + al_iphone_get_battery_level, al_iphone_get_window, al_iphone_get_view. + +Examples: + +- Added new example programs: ex_audio_chain, ex_loading_thread, ex_menu, + ex_palette, ex_polygon, ex_shader, ex_window_constraints, ex_video. + +- Added skater demo ported from Allegro 4.4. + + + + diff --git a/allegro/docs/src/changes-5.2.txt b/allegro/docs/src/changes-5.2.txt new file mode 100644 index 00000000..a5dbd1d6 --- /dev/null +++ b/allegro/docs/src/changes-5.2.txt @@ -0,0 +1,953 @@ +% Allegro changelog for 5.2.x series + +These lists serve as summaries; the full histories are in the git repository. + +Changes from 5.2.6 to 5.2.7 (March 2021) +======================================== + +The main developers this time were: SiegeLord, Peter Hull, Elias Pschernig, +Aldrik Ramaekers, Andreas Rönnquist. + +Build system: + +- Allow generating projects with a suffix (lorry-lee). + +- Fix build under Clang-CL in Visual Studio. + +Core: + +- Avoid some undefined behavior errors. + +- Return key modifiers in `ALLEGRO_EVENT_KEY_UP` and `ALLEGRO_EVENT_KEY_DOWN`. + +- Allow calling `al_map_*` color functions before Allegro is initialized. + +- Allow minimum bitmap size to be something other than 16 on non-Android + platforms (controlled via `allegro5.cfg`). + +- Add `al_get_monitor_refresh_rate` (only implemented on Windows for now). + +Graphics: + +- Fix `ALLEGRO_KEEP_INDEX` flag for bitmaps. + +- Add `ALLEGRO_OPENGL_CORE_PROFILE` display flag. + +Emscripten: + +- The experimental Emscripten support (via the SDL backend) is now documented + in `README_sdl.txt`. + +OSX: + +- Move more Cocoa operations to the main thread. + +- Explicitly link CoreVideo to fix the static build. + +Windows: + +- Issue #1125: Speed up OpenGL extension detection (Tobias Scheuer). + +- Use Unicode APIs when enumerating joysticks. + +- Use `WM_DEVICECHANGE` rather than polling to detect joystick hotlugging, + reducing input drops and lags (Todd Cope). + +- Fix joystick polling period. + +- Restore WinXP compatibility by using slightly older API when loading shared + libraries (Julian Smythe). + +- Fix build with HLSL disabled (Julian Smythe). + +- Raise DirectInput `MAX_JOYSTICKS` to 32 and `DEVICE_BUFFER_SIZE` to 128. + +SDL: + +- Issue #1224: Fix bug in SDL voice driver. + +Audio addon: + +- Allows playing sounds in reverse by specifying a negative speed. + +Acodec addon: + +- Fix edge-case looping in Ogg Vorbis stream (Cody Licorish) + +Audio addon: + +- Use more sensible values for PulseAudio's playback buffer, potentially + resolving some crashes and high CPU usage. + +Native Dialog Addon: + +- Migrate from GTK2 to GTK3. Sadly, we lose menu icons as GTK3 dropped support + for them. + +TTF addon: + +- Allow initializing TTF addon before the Font addon. + +- Shut-down the TTF addon automatically in `al_uninstall_system`. + +PhysFS addon: + +- Fix handling of native path separators. + +- Stop using deprecated PhysFS API. + +Primitives addon: + +- Fix segfault in `al_draw_ribbon` when `num_segments > 128` (Rodolfo Borges). + +- Issue 1215: Correctly handle small scales when determining subdivision level + for high level primitives (Robin Heydon). + +Documentation: + +- Fix LaTeX errors in the generation of the reference manual PDF. + +- Add links to examples into the reference manual. + +- Allow pressing 'S' to focus the search bar in the docs. + +- Assorted documentation improvements. + +Misc: + +- Add a security policy and an associated private security mailing list - + allegro-security@lists.liballeg.org. + +- Add Emscripten-powered examples to https://liballeg.org/examples_demos.html. + +Examples: + +- `ex_audio_simple` now displays instructions and supports bidirectional looping. + +- Add default files to some audio examples. + + +Changes from 5.2.5 to 5.2.6 (February 2020) +========================================== + +The main developers this time were: SiegeLord, Peter Hull, +Karthik Kumar Viswanathan, Elias Pschernig, Sebastian Krzyszkowiak, +Doug Thompson, PmProg, RmBeer. + +Core: + + - Fix timestamps being clamped to ints on touch inputs with X11. + + - Fix al_utf8_width argument type mismatch on platforms where + `sizeof(int) != 4`. + + - Fix building for GNU/Linux without GNU extensions enabled + + - Some refactoring to simplify adding new drivers. + +Graphics: + + - Fix for OpenGL version selection and reporting on Windows and X + (Edgar Reynaldo). + + - Report OpenGL version in display options on Android, iOS and Raspberry Pi. + + - Fix creation of the bitmap depth buffer for non-square bitmaps + (Kevin Wellwood). + + - Fix `ALLEGRO_ALPHA_TEST_VALUE` not being interpreted correctly. + + - Fix reported bitshifts for `ARGB_4444` and `RGBA_4444` pixel formats. + + - Fix alpha test with the GLSL version. + +Android: + + - Do not build Android examples outside of Android. + + - Use the cmake toolchain provided by the Android NDK. + + - Use FLAG_KEEP_SCREEN_ON instead of a wakelock for screensaver inhibition. + + - Use DisplayListener to listen to orientation changes. + + - Implement `ALLEGRO_FRAMELESS` on Android. This hides the navigation buttons + and the bar on top. + +Linux: + + - Fix `al_inhibit_screensaver` function. + +OSX: + + - Ensure system calls happen on the main thread. + + - Make things work on Catalina. + +Hurd: + + - Fix pthreads (Andreas Rönnquist). + +Windows: + + - Implement Windows version check using non-deprecated functions. + + - Abstract UNICODE vs ANSI string handling, switch to using UNICODE by + default. + + - Enable debug window for `DEBUGMODE` on Windows. + +SDL: + + - Fix requesting GLES profile on GL Allegro. + + - Add audio recorder implementation. + + - Don't link with dl, it's unnecessary. + +Addons: + + - Add a whole bunch of `al_is_*_initialized` functions (Mark Oates). + +Acodec addon: + + - Add MP3 support via the MiniMP3 library. + +Audio addon: + + - Allow calling `al_destroy_audio_recorder` on NULL. + + - Fix some stream garbage audio issues for high playback speeds. + +Image addon: + + - Add support for FreeImage library. + + - Always prefer non-system image loaders. + + +Python wrapper: + + - Fix a number of bugs (zachs18 and others). + +Misc: + + - Add an `.editorconfig` file. + + - Convert our internal Python scripts to Python 3. + +Examples: + + - `ex_draw_bitmap` - Add more options. + + +Changes from 5.2.4 to 5.2.5 (February 2019) +========================================== + +The main developers this time were: Sebastian Krzyszkowiak, SiegeLord, +Elias Pschernig, Bruce Pascoe, Aldrik Ramaekers, Firat Salgur. + +Core: + + - Try to identify bitmap format for unknown extensions. + + - Add some missing OpenGL 4.3 functions. + + - Add `al_create_thread_with_stacksize` to create threads with a custom stack + size. (Aldrik Ramaekers) + + - Add `al_get_system_id` function, letting you disambiguate platforms at + runtime. + +Graphics: + + - Add `al_get_monitor_dpi` to query the DPI of a monitor. + + - Add new API for making blender a bitmap-local state (like transformations), + which can simplify some code. See `al_set_bitmap_blender` and the related + APIs. Also see the `ex_blend_target` example. + + - Added `al_transpose_transform`. This is useful for rotation transformations. + + - Rework internal GLES support for better portability. + + - Don't force POT bitmaps on GLES. + + - Fix repeated bitmap locking on OpenGL. + +Android: + + - Various documentation and other improvements (Christian Mauduit). + + - Fix OpenGL version reporting after display creation. + +iOS: + + - Fix OpenGL version reporting after display creation. + +Linux: + + - Improve linux joystick detections. + + - Fix a number of memory leaks/crashes in the audio addon when using + pulseaudio/alsa. (Julian Smythe) + + - Fix compilation with Mesa 18.2.5 and later. + + - Fix OpenGL version reporting after display creation (Edgar Reynaldo). + + - Fix requesting specific OpenGL versions via display options + (Edgar Reynaldo). + +OSX: + + - Make `al_get_monitor_info` return the correct values for Retina displays. + + - Fix vsync on OSX 10.14+. + +RaspberryPi: + + - Fix OpenGL version reporting after display creation. + +Windows: + + - Fix toggling of menu checkboxes by id. + + - Fix `al_draw_indexed_primitive` while using Direct3D. + + - Fix crash when passing `NULL` display to `al_show_native_file_dialog` while + using `ALLEGRO_FILECHOOSER_FOLDER`. + + - Fix OpenGL version reporting after display creation (Edgar Reynaldo). + + - Fix requesting specific OpenGL versions via display options + (Edgar Reynaldo). + +SDL: + + - Sebastian Krzyszkowiak has spent a lot of effort to making the SDL backend + usable as a nearly fully featured Allegro backend. You can use it on + platforms native Allegro implementations do not support (such as + emscripten, etc.). + +Addons: + + - Better logging when failing to load a resource. + + - Fix a memory leak when destroying a mixer with attached streams. + + - Fix a memory leak in the audio destroying a mixer with attached streams. + +Acodec addon: + + - Allow modules to loop properly when the user hasn't specified loop points. + (Todd Cope) + +Audio addon: + + - Better support for big endian. (Douglas Mencken) + +TTF addon: + + - Added support of HarfBuzz in FreeType (Arves100). + +Documentation: + + - Source links now point to the correct commit on GitHub. + + - General improvements and clarifications. + +Examples: + + - Add `ex_blend_target`. + + +Changes from 5.2.3 to 5.2.4 (February 2018) +========================================== + +The main developers this time were: Sebastian Krzyszkowiak, Elias Pschernig, +SiegeLord + +Core: + + - Fix errors when reading/writing 0 byte buffers (Bruce Pascoe). + + - Re-initialize TLS when Allegro is installed (Issue #865). + + - Add `al_transform_coordinates_4d`. + + - Don't initialize the trace mutex multiple times (Issue #874). + + - Fix 3D (non-projection) transforms with `al_hold_bitmap_drawing`. + +Raspberry Pi port: + + - Fix compilation on RPI. + +Android port: + + - Remove limit on the working directory length. + + - Fix `ALLEGRO_MAXIMIZED` flag. + + - Fix build with older Android NDKs. + + - Remove `glClear` hack for Android 2.1. + +Linux port: + + - Make compositor bypass configurable in X11, and bypass only when fullscreen + by default. + +OSX port: + + - Fix a few OSX retina scaling issues (Issue #851). + +Audio addon: + + - Fix ALSA lag. + + - Add an option to use the desktop window when initializing DirectSound + (Issue #877). + +Font addon: + + - Add support for bmfont format. + +Native dialog addon: + + - Resize the display on Windows when hiding/showing the menu (Issue #860). + + - Detect when `al_popup_menu` fails to actually work under GTK (Issue #808). + + - Don't clear the top-level menu when destroying the popup menu. + +Build system: + + - Don't link in libm on MSVC for DUMB (Issue #847). + + - Don't use the LOCATION property (Issue #847). + + - Don't use SYSTEM for DirectX includes. + + - Add hints for mingw-w64 path locations for DirectX includes/libs. + +Python binding: + + - Fix the Python code-generation scripts to run under Python 2. + +Lua binding: + + - Add script to generate LuaJIT C API for Allegro 5 (BQ). + +Documentation: + + - Many improvements (Andreas Rönnquist, others) + +Examples: + + - Add a texture to the skybox in `ex_camera`. + +Changes from 5.2.2 to 5.2.3 (October 2017) +========================================== + +The main developers this time were: Elias Pschernig, SiegeLord, Sebastian +Krzyszkowiak, Vitaliy V. Tokarev, Simon Naarmann, Bruno Félix Rezende Ribeiro, +Trent Gamblin). + +Core: + + - Add `al_path_ustr` (Bruce Pascoe). + + - Handle NULL sections more gracefully with the config API. + + - Add missing `glStencilMaskSeparate prototype` (Aaron Bolyard). + + - Add `al_clear_keyboard_state`. + + - Don't add blank lines before config sections when writing them out. + + - Fix `fs_stdio_read_directory` appending an extra slash. + + - Fix `al_set_window_constraints` when the flag ALLEGRO_MAXIMIZED is set. + + - Fix `al_set_clipping_rectangle` when out-of-bounds (Bruce Pascoe). + + - Enable blocked locking of S3TC formats unconditionally. + +Raspberry Pi port: + + - Set default file interface when attempting to read /boot/config.txt. + +Android port: + + - Replace the old build system that used deprecated tools with a new + Gradle-based system. + + - Work around crashes on some Androids when an FBO is bound during + `egl_SwapBuffers`. + + - Fix LocalRef leak when opening files using APK interface. + + - Remove -Wno-psabi switches from Toolchain-android.cmake. + +Linux port: + + - Make three finger salute and LED toggle configurable. + + - Fix KEY_CHAR events under X11 with compose key enabled. + + - Fix clearing the `ALLEGRO_MAXIMIZED` flag under X11. + + - Add `al_x_set_initial_icon`. + + - Free wm_hints in `set_initial_icon`. + + - Read Allegro system config from ~/.allegro5rc on Unix. + +Windows port: + + - Make bitmap contents persist again after device loss. + + - Add large file support for MSVC. + + - Only test cooperative lavel if device is known to be lost. + + - Don't leak the `D3DEffect` when attaching multiple sources. + + - Fix `al_get_monitor_info` (Tobias Scheuer). + +OSX port: + + - Various fixes for OSX 10.6. + + - Fix some Bluetooth mice on OS X (Tom Bass). + + - Fixed deprecation warning when starting OSX console app (Tom Bass). + + - Fix OSX magic main with the LTO switch (Evert Glebbeek). + +Audio addon: + + - Allow setting the buffer size for ALSA. + + - Don't apply gain twice for sample instances and streams when pan is not + `ALLEGRO_PAN_NONE`. + + - Disallow attaching mixers with different channel configurations. + + - Add `al_set_sample_instance_channel_matrix` and + `al_set_audio_stream_channel_matrix`. + + - Don't free the extra pointer in DirectSound if voice fails to play for some + reason. + + - Add `al_lock_sample_id` and `al_unlock_sample_id`. + + - For OpenAL, detach from buffers before deleting. + + - Return true when seeking mod audio streams. + +Acodec addon: + + - Free audio stream buffer in flac_stream_close. + + - Add DUMB 2.0 support. + +Color addon: + + - Add XYZ, xyY, Lab and LCH color spaces. + + - Remove "purwablue" named color, add "rebeccablue". + +Native dialog addon: + + - Improve save dialogs under GTK driver. + + - Improved path behavior in GTK native file dialog ([bk]door.maus). + + - Enable `ALLEGRO_FILECHOOSER_FOLDER` On Linux (Todd Cope). + + - Use unique ids to identify menu items internally, fixing their event + sources. + + - Make the native message box return 2 on Windows when cancel is pressed. + +Image addon: + + - Set compression level to `Z_DEFAULT_COMPRESSION` in png saver by default. + + - Make PNG, JPEG compression level configurable. + + - Make PNG gamma value configurable. + + - Add WebP support with libwebp. + +Video addon: + + - Allow calling `al_init_video_addon` after `al_shutdown_video_addon` was + called. + +Build system: + + - Detect and link optional FreeType dependencies. + + - Add a CMake option to prefer static dependencies. + + - Fix SDL platform build. + +Python binding: + + - Fix some corrupted regexps in the generation script (verderten). + +Documentation: + + - Lots of improvements as usual (Edgar Reynaldo, Mark Oates, twobit). + +Examples: + + - Fix various issues with `ex_curl`. + + - Fix memory leak in `ex_audio_simple` (Rm Beer). + + +Changes from 5.2.1.1 to 5.2.2 (December 2016) +======================================= + +The main developers this time were: Trent Gamblin, SiegeLord, Elias Pschernig. + +Core: + + - Don't accumulate time in the timer while it is stopped. + + - Use dynamic OpenGL ES checks, so binaries produced on newer platforms + don't crash on older ones. + + - Destabilize the OpenGL extensions API (BREAKING CHANGE!). + +Raspberry Pi port: + + - Add various optimizations. + + - Fix `al_set_mouse_xy` under X. + +Android port: + + - Fix buffer overrun and memory leak in the clipboard support. + + - Add WANT_GLES3 to disable some of the newer features on platforms where they + aren't supported. + + - Fix build in Android versions below 3.1. + + - Fix a crash when activity is destroyed/paused. + + - Allow building for android mips, arm64 and mips64. + + - Add `al_android_get_jni_env` and `al_android_get_activity` utility + functions. + + - Update manifest files for newer Android versions. + +Windows port: + + - Handle keyboard input properly when Ctrl is pressed (Tobias Scheuer). + +Hurd port: + + - Define a fallback PATH_MAX (Andreas Rönnquist). + +OSX port: + + - Clear window to black when going in/out of fullscreen. + + - Fix window centering when going out of FULLSCREEN_WINDOW mode. + + - Fix OSX 10.12 build. + + - Allow 32 bit builds on OSX (MarcusCalhoun-Lopez). + +Build system: + + - Fix issues with building on GCC6 on Windows. + + - Fix source directory littering while configuring the Android build. + +Python binding: + + - Add support Python 3 (Gabriel Queiroz). + +Documentation: + + - Document the behavior of `al_set_target_bitmap` with respect to + transformations (Edgar Reynaldo). + + - Fix typo in `al_use_transform` docs (Ryan Roden-Corrent). + +Examples: + + - Add kerning to the `al_get_glyph` example in ex_ttf. + + - Various fixes in ex_camera (Erich Erstu). + + +Changes from 5.2.1 to 5.2.1.1 (August 2016) +======================================= + +The main developers this time were: Trent Gamblin, SiegeLord. + +Core: + + - Enforce backwards compatibility in the version check, rather than + erroneously allowing forwards compatiblity. + + - Temporarily remove new extensions in ALLEGRO_OGL_EXT_LIST as that broke ABI + compatibility. + +OSX port: + + - Temporarily revert changes in joystick detection, as it did not interact + well with some joysticks. + +Windows port: + + - Fix the clear display to black right away to avoid an ugly white flash + change. + + +Changes from 5.2.0 to 5.2.1 (July 2016) +======================================= + +The main developers this time were: Elias Pschernig, Trent Gamblin, SiegeLord, +Ryan Roden-Corrent, Boris Carvajal and Peter Hull. + +Core: + + - Optimize bitmap holding a bit (Bruce Pascoe). + + - Add `al_get/set_depth/samples` (OpenGL only for now). + + - Optimize destruction performance when you have thousands of objects + (e.g. sub-bitmaps). + + - Use low floating point precision for the OpenGL fragment shaders, which + helps performance a lot on mobile platforms. + + - Don't stop and join the timer thread when stopping the last timer (prevents + unnecessary delay in this situation on some platforms). + + - Add `al_backup_dirty_bitmap` and `al_backup_dirty_bitmaps` to more finely + control when bitmap context backup is performed. + +Android port: + + - Fix Android app issues when woken up during sleep. + + - Specify the Android toolchain file on the command line now. + ANDROID_NDK_TOOLCHAIN_ROOT now has to be specified in an environment + variable. + +OSX port: + + - Improve joystick enumeration (Todd Cope). + + - Make `al_set_new_window_title` work correctly. + + - Don't send duplicate mouse move events. + + - Fix mouse warping behavior. + + - Exit fullscreen mode if ALLEGRO_FULLSCREEN_WINDOW is set when destroying a + display (otherwise if you destroy and recreate display without terminating + the program, a white window kicks around). + +iOS port: + + - Make it compile again. + + - Don't backup textures as it is unnecessary. + + - Update minimum iOS to version to 6.1. + + - Disable the native png loader in favor of libpng, as it is broken on + Apple's end. + + - Create library when creating the archive. + +Windows port: + + - Fix the D3D target bitmap bug. + + - Clear display to black right away to avoid an ugly white flash. + +Raspberry Pi port: + + - Fix system cursor support. + +Linux port: + + - Make `al_set_new_window_title` work correctly. + +Build system: + + - Use PROJECT_SOURCE_DIR and PROJECT_BINARY_DIR instead of CMAKE_SOURCE_DIR + and CMAKE_BINARY_DIR. This lets you use Allegro as a sub-project in your + CMake project. + + - Fix GDIPlus finding in cmake-gui (Bruce Pascoe). + + - Add .gitignore and ignore build/ dir (Mark Oates). + + - Fix building examples with non-Allegro dependencies with the monolith build. + +Documentation: + + - Various documentation updates (Daniel Johnson and others). + +Other: + + - Add more `#include` statements in Allegro headers, so it's easier to use + them in isolation (Jordan Woehr). + + - Allow marking tests as being hardware only. + + - Prefix some private Allegro macros and types to not pollute the namespace. + + - Make set_shader_uniform api const-correct (Bruce Pascoe). + +Audio addon: + + - Adjust loop end position when calling `al_set_sample_instance_length`. + +Acodec addon: + + - Allow file-backed audio streams to be restarted after they finish. + + - Add Opus codec support. + +Image addon: + + - Fail gracefully if not built with PNG/JPG loaders. + +Native dialog addon: + +Font addon: + + - Make `al_get_text_dimensions` and `al_get_glyph_dimensions` return exact + bounding boxes (koro). + + - Add `ALLEGRO_GLYPH` structure and `al_get_glyph`, allowing for some + additional optimization when drawing fonts. + +Examples: + + - Add more controls to `ex_audio_props`. + + - Add an example of using Enet with Allegro. + + + +Changes from 5.1.13.1 to 5.2.0 (April 2016) +============================================ + +The main developers this time were: SiegeLord, Polybios, Mark Oates, +Elias Pschernig and Jonathan Seeley. + +Core: + + - Add `al_is_event_source_registered` (koro). + + - Make destructors log messages more meaningful. + + - Mouse emulation API for touch devices is now unstable. + + - Rename `al_convert_bitmaps` to `al_convert_memory_bitmaps`. + +Input: + + - Haptic API is now unstable. + +Android port: + + - Fixed bogus display destruction on Android which previously caused + zombie states. + +OSX port: + + - Fix OSX mouse state position scaling. + + - Fix other various scaling issues. + + - Make toggling ALLEGRO_FRAMELESS work. + + - Fix an issue where fullscreen windows would occasionally leave empty space + for the titlebar. + + - Fix incorrect debug assert in the audio addon. + +Windows port: + + - Make Allegro apps DPI-aware by default, which means that they won't be + scaled by the OS. + + - Fix compilation for the CPU detection code on some compilers. + + - Don't sync the D3D bitmap when locking with WRITE_ONLY. + + - Remove dsound.dll runtime loading. + + - Don't link xinput and d3dx9 libraries (they are still required at runtime + though if you're using the relevant features). + + - Fix a bug where al_wait_for_event_timed can block despite 0 timeout + (Aldo Nunez). + +Build system: + + - Install PDB files when building with MSVC. + +Documentation: + + - Fix source links for API entries with multi-line prototypes. + + - Make the readme look prettier on GitHub. + + - Tons of assorted documentation improvements, especially for the audio addon. + +Other: + + - Add a stability system where some unstable APIs need to be opted into by + defining `ALLEGRO_UNSTABLE` before including Allegro headers. + +Audio addon: + + - Fix sporadic deadlocks + + - Recorder API is now unstable. + +Native dialog addon: + + - `al_toggle_menu_item_flags` is now unstable. + +TTF addon: + + - Add an option to pre-cache the glyphs, useful for platforms where the + current algorithm is buggy (typically some Android devices). + +Video addon: + + - Temporarily remove FFmpeg backend, as it was too buggy, didn't build and was + too hard to fix. + +Examples: + + - Make `ex_vsync` less likely cause a seizure. + + - Make `ex_draw_bitmap` and `ex_touch_input` switch in/out on Android. + + - Add documentation to `ex_bitmap` (Daniel Johnson). + + - Improve `ex_logo` text entry experience. + + + diff --git a/allegro/docs/src/custom_header.html b/allegro/docs/src/custom_header.html new file mode 100644 index 00000000..027edbf0 --- /dev/null +++ b/allegro/docs/src/custom_header.html @@ -0,0 +1,2 @@ + + diff --git a/allegro/docs/src/pandoc.css b/allegro/docs/src/pandoc.css new file mode 100644 index 00000000..ff4b4817 --- /dev/null +++ b/allegro/docs/src/pandoc.css @@ -0,0 +1,255 @@ +/* We use this style sheet for HTML documents generated with Pandoc. */ + +body { + background-color: #fcfcfc; + padding-left: 0.1em; + color: #222; + font-family: sans-serif; +} + +pre { + border: 1px solid #ddd; + background-color: #f3f3f8; + padding: 0.6em; + padding-left: 0.8em; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +blockquote { + border: 1px solid #ddd; + background-color: #fff8e0; + padding: 0.6em; + padding-left: 0.8em; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +blockquote p { + padding: 0; + margin: 0; +} + +blockquote p em:first-child { + font-style: normal; + font-weight: bold; + color: #400000; +} + +code { + font-family: monospace; +} + +h1, h2, h3, h4, h5 { + color: #348; + margin-top: 2.5em; + border-top: 1px solid #eee; + padding-top: 0.8em; +} + +h1 { + font-size: 130%; +} + +h2 { + font-size: 110%; +} + +h3 { + font-size: 95%; +} + +h4 { + font-size: 90%; + font-style: italic; +} + +h5 { + font-size: 90%; + font-style: italic; +} + +h1.title { + font-size: 200%; + font-weight: bold; + margin-top: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + text-align: left; + border: none; +} + +a { + text-decoration: none; + color: #348; +} + +dl dt { + font-weight: bold; +} + +dt code { + font-weight: bold; +} + +dd p { + margin-top: 0; +} + +ul { + padding-left: 1.5em; +} + +table { + background-color: #f8f8fa; + border-top: 1px solid #e0e0e0; + border-bottom: 1px solid #e0e0e0; +} + +table th { + font-weight: bold; + border-bottom: 1px solid #e0e0e0; + padding: 0.5em; +} + +/* Side bar */ +div.sidebar { + background-color: #f0f0fa; + border: solid 1px #e0e0ea; + float: left; + width: 150px; + margin-right: 1em; + line-height: 110%; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.sidebar ul { + list-style-type: none; + padding: 0; + margin-left: 0.5em; + font-size: small; +} + +div.sidebar ul a:hover { + background: #fffff0; +} + +div.searchbox { + margin-left: 5px; + margin-right: 5px; + margin-bottom: 0.8em; + font-size: small; +} + +/* font-size isn't inherited (at least not in Firefox and Chrome) */ +input#q { + font-size: small; + width: 85%; +} + +/* Body of page */ +div.content { + margin-left: 165px; + max-width: 50em; + line-height: 135%; +} + +div#TOC { + display: table; + border: 1px solid #ddd; + background-color: #f3f3fa; + padding-right: 1em; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div#TOC ul { + padding-left: 1em; + list-style-type: none; +} + +p.timestamp { + margin-top: 3em; + border-top: solid 1px #eee; + padding: 0.7em; + padding-left: 0.3em; + color: #999; + text-align: left; +} + +/* Below is the autosuggest.css from autosuggest.js version 2.4. */ + +.autosuggest-body +{ + position: absolute; + border: 1px solid black; + z-index: 100; + font-size: small; +} + +.autosuggest-body iframe +{ + display: block; + position: absolute; + z-index: 999; + filter: alpha(opacity=0); +} + +.autosuggest-body table +{ + width: 100%; + background-color: #f3f3fa; +} + +.autosuggest-body tr +{ + cursor: hand; + cursor: pointer; + + color: black; + + text-align: left; +} + +.autosuggest-body tr.up +{ + height: 10px; + background: #656291 url("arrow-up.gif") center center no-repeat; +} + +.autosuggest-body tr.down +{ + height: 10px; + background: #656291 url("arrow-down.gif") center center no-repeat; +} + +.autosuggest-body tr.up-disabled +{ + height: 10px; + background: #656291 url("arrow-up-d.gif") center center no-repeat; + cursor: default; +} + +.autosuggest-body tr.down-disabled +{ + height: 10px; + background: #656291 url("arrow-down-d.gif") center center no-repeat; + cursor: default; +} + +.autosuggest-body tr.selected +{ + background-color: #D6D7E7; + color: red; +} + +.autosuggest-body td +{ + white-space: nowrap; +} + +.autosuggest-body span.match +{ + font-weight: bold; +} diff --git a/allegro/docs/src/refman/acodec.txt b/allegro/docs/src/refman/acodec.txt new file mode 100644 index 00000000..9eb1ce44 --- /dev/null +++ b/allegro/docs/src/refman/acodec.txt @@ -0,0 +1,45 @@ +# Audio codecs addon + +These functions are declared in the following header file. +Link with allegro_acodec. + +~~~~c + #include +~~~~ + +## API: al_init_acodec_addon + +This function registers all the known audio file type handlers for +[al_load_sample], [al_save_sample], [al_load_audio_stream], etc. + +Depending on what libraries are available, the full set of recognised +extensions is: .wav, .flac, .ogg, .opus, .it, .mod, .s3m, .xm, .voc. + +*Limitations:* + +- Saving is only supported for wav files. + +- The wav file loader currently only supports 8/16 bit little endian PCM files. +16 bits are used when saving wav files. Use flac files if more precision is +required. + +- Module files (.it, .mod, .s3m, .xm) are often composed with streaming in mind, +and sometimes cannot be easily rendered into a finite length sample. Therefore +they cannot be loaded with [al_load_sample]/[al_load_sample_f] and must be +streamed with [al_load_audio_stream] or [al_load_audio_stream_f]. + +- .voc file streaming is unimplemented. + +Return true on success. + +## API: al_is_acodec_addon_initialized + +Returns true if the acodec addon is initialized, otherwise returns false. + +Since: 5.2.6 + +## API: al_get_allegro_acodec_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. + diff --git a/allegro/docs/src/refman/allegro_version.tex.cmake b/allegro/docs/src/refman/allegro_version.tex.cmake new file mode 100644 index 00000000..339bb2c1 --- /dev/null +++ b/allegro/docs/src/refman/allegro_version.tex.cmake @@ -0,0 +1 @@ +@ALLEGRO_VERSION@ diff --git a/allegro/docs/src/refman/audio.txt b/allegro/docs/src/refman/audio.txt new file mode 100644 index 00000000..4942ad63 --- /dev/null +++ b/allegro/docs/src/refman/audio.txt @@ -0,0 +1,1742 @@ +# Audio addon + +These functions are declared in the following header file. +Link with allegro_audio. + +~~~~c + #include +~~~~ + +In order to just play some samples, here's how to quick start with Allegro's audio +addon: Call [al_reserve_samples] with the number of samples you'd like to be able +to play simultaneously (don't forget to call [al_install_audio] beforehand). +If these succeed, you can now call [al_play_sample], with data obtained by +[al_load_sample], for example (don't forget to +[initialize the acodec addon][al_init_acodec_addon]). You don't need to worry +about voices, mixers or sample instances when using this approach. In order to +stop samples, you can use the [ALLEGRO_SAMPLE_ID] that al_play_sample returns. + +If you want to play large audio files (e.g. background music) without loading the +whole file at once or if you want to output audio generated in real-time, you can +use Allegro's audio streams. +The easiest way to setup an [audio stream][ALLEGRO_AUDIO_STREAM] is to attach it +to the default mixer (created for you by [al_reserve_samples]) using +[al_attach_audio_stream_to_mixer] on the return value of [al_get_default_mixer]. +Allegro will feed streams created from files using [al_load_audio_stream] +automatically. However, you can also stream audio data you generate on the fly. +In this case, audio streams will emit an event when it's time to +[provide the next fragment (chunk) of audio data][al_get_audio_stream_fragment]. +You can control several playback parameters of audio streams (speed, gain, pan, +playmode, played/paused; additionally position and loop points when streaming a +file). + +For more fine-grained control over audio output, here's a short description of +the basic concepts: + +Voices represent audio devices on the system. Basically, every audio output chain +that you want to be heard needs to end up in a voice. As voices are on the +hardware/driver side of things, there is only limited control over their parameters +(frequency, sample format, channel configuration). The number of available voices +is limited as well. Typically, you will only use one voice and attach a mixer to +it. Calling [al_reserve_samples] will do this for you by setting up a default +voice and mixer; it can also be achieved by calling [al_restore_default_mixer]. +Although you *can* attach sample instances and audio streams directly to a voice +without using a mixer, it is, as of now, not recommended. In contrast to mixers, +you can only attach a single object to a voice anyway. + +Mixers mix several sample instances and/or audio streams into a single output +buffer, converting sample data with differing formats according to their output +parameters (frequency, depth, channels) in the process. In order to play several +samples/streams at once reliably, you will need at least one mixer. A mixer that +is not (indirectly) attached to a voice will remain silent. For most use cases, +one (default) mixer attached to a single voice will be sufficient. You may attach +mixers to other mixers in order to create complex audio chains. + +Samples ([ALLEGRO_SAMPLE]) just represent "passive" buffers for sample data in +memory. In order to play a sample, a sample instance ([ALLEGRO_SAMPLE_INSTANCE]) +needs to be created and attached to a mixer (or voice). Sample instances control +*how* the underlying samples are played. Several playback parameters (position, +speed, gain, pan, playmode, playing/paused) can be adjusted. +Particularly, multiple instances may be created from the same sample, e.g. with +different parameters. + +Audio streams (see above) are similar to sample instances insofar as they respond +to the same playback parameters and have to be attached to mixers or voices. +A single audio stream can only be played once simultaneously. + +For example, consider the following configuration of the audio system. + +~~~~c +ALLEGRO_VOICE* voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, + ALLEGRO_CHANNEL_CONF_2); + +ALLEGRO_MIXER* mixer_1 = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); +ALLEGRO_MIXER* mixer_2 = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); + +/* Load a stream, the stream starts in a playing state and just needs + * to be attached to actually output sound. */ +ALLEGRO_AUDIO_STREAM* stream = al_load_audio_stream("music.ogg", 4, 2048); + +/* The sample needs sample instances to output sound. */ +ALLEGRO_SAMPLE* sample = al_load_sample("sound.wav") +ALLEGRO_SAMPLE_INSTANCE* instance_1 = al_create_sample_instance(sample); +ALLEGRO_SAMPLE_INSTANCE* instance_2 = al_create_sample_instance(sample); + +/* Attach everything up (see diagram). */ +al_attach_mixer_to_voice(mixer_1, voice); +al_attach_mixer_to_mixer(mixer_2, mixer_1); +al_attach_audio_stream_to_mixer(stream, mixer_1); +al_attach_sample_instance_to_mixer(instance_1, mixer_2); +al_attach_sample_instance_to_mixer(instance_2, mixer_2); + +/* Play two copies of the sound simultaneously. */ +al_set_sample_instance_playing(instance_1, true); +al_set_sample_instance_playing(instance_2, true); +~~~~ + +![*An example configuration of the audio system to play music and a +sound.*](images/audio.png) + +Since we have two mixers, with the sample instances connected to a different +mixer than the audio stream, you can control the volume of all the instances +independently from the music by setting the gain of the mixer / stream. Having +two sample instances lets you play two copies of the sample simultaneously. + +With this in mind, another look at [al_reserve_samples] and [al_play_sample] is +due: What the former does internally is to create a specified number of sample +instances that are "empty" at first, i.e. with no sample data set. When +al_play_sample is called, it'll use one of these internal sample instances that +is not currently playing to play the requested sample. All of these sample +instances will be attached to the default mixer, which can be changed via +[al_set_default_mixer]. + +See [Audio recording] for Allegro's audio recording API, which is, as of now, +still unstable and subject to change. + + +## Audio types + +Events sent by [al_get_audio_stream_event_source] or [al_get_audio_recorder_event_source]. + +### API: ALLEGRO_AUDIO_EVENT_TYPE + +#### ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT + +Sent when a stream fragment is ready to be filled in. See [al_get_audio_stream_fragment]. + +#### ALLEGRO_EVENT_AUDIO_STREAM_FINISHED + +Sent when a stream is finished. + +#### ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT + +Sent after a user-specified number of samples have been recorded. Convert this to +[ALLEGRO_AUDIO_RECORDER_EVENT] via [al_get_audio_recorder_event]. + +You must always check the values for the buffer and samples as they +are not guaranteed to be exactly what was originally specified. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. + +### API: ALLEGRO_AUDIO_DEPTH + +Sample depth and type as well as signedness. Mixers only use 32-bit signed +float (-1..+1), or 16-bit signed integers. +Signedness is determined by an "unsigned" bit-flag applied to the depth value. + +* ALLEGRO_AUDIO_DEPTH_INT8 +* ALLEGRO_AUDIO_DEPTH_INT16 +* ALLEGRO_AUDIO_DEPTH_INT24 +* ALLEGRO_AUDIO_DEPTH_FLOAT32 +* ALLEGRO_AUDIO_DEPTH_UNSIGNED + +For convenience: + +* ALLEGRO_AUDIO_DEPTH_UINT8 +* ALLEGRO_AUDIO_DEPTH_UINT16 +* ALLEGRO_AUDIO_DEPTH_UINT24 + +### API: ALLEGRO_AUDIO_PAN_NONE + +A special value for the pan property of sample instances and audio streams. +Use this value to disable panning on sample instances and audio streams, and play +them without attentuation implied by panning support. + +ALLEGRO_AUDIO_PAN_NONE is different from a pan value of 0.0 (centered) because, +when panning is enabled, we try to maintain a constant sound power level as a +sample is panned from left to right. A sound coming out of one speaker +should sound as loud as it does when split over two speakers. +As a consequence, a sample with pan value 0.0 will be 3 dB softer than the +original level. + +(Please correct us if this is wrong.) + +### API: ALLEGRO_CHANNEL_CONF + +Speaker configuration (mono, stereo, 2.1, etc). + +* ALLEGRO_CHANNEL_CONF_1 +* ALLEGRO_CHANNEL_CONF_2 +* ALLEGRO_CHANNEL_CONF_3 +* ALLEGRO_CHANNEL_CONF_4 +* ALLEGRO_CHANNEL_CONF_5_1 +* ALLEGRO_CHANNEL_CONF_6_1 +* ALLEGRO_CHANNEL_CONF_7_1 + +### API: ALLEGRO_MIXER + +A mixer mixes together attached streams into a single buffer. In the process, +it converts channel configurations, sample frequencies and audio depths of the +attached sample instances and audio streams accordingly. You can control the +quality of this conversion using ALLEGRO_MIXER_QUALITY. + +When going from mono to stereo (and above), the mixer reduces the volume of +both channels by `sqrt(2)`. When going from stereo (and above) to mono, the +mixer reduces the volume of the left and right channels by `sqrt(2)` before +adding them to the center channel (if present). + +### API: ALLEGRO_MIXER_QUALITY + +* ALLEGRO_MIXER_QUALITY_POINT - point sampling +* ALLEGRO_MIXER_QUALITY_LINEAR - linear interpolation +* ALLEGRO_MIXER_QUALITY_CUBIC - cubic interpolation (since: 5.0.8, 5.1.4) + +### API: ALLEGRO_PLAYMODE + +Sample and stream playback mode. + +* ALLEGRO_PLAYMODE_ONCE - the sample/stream is played from start to finish an + then it stops. +* ALLEGRO_PLAYMODE_LOOP - the sample/stream is played from start to finish (or + between the two loop points). When it reaches the end, it restarts from the + beginning. +* ALLEGRO_PLAYMODE_BIDIR - the sample is played from start to finish (or + between the two loop points). When it reaches the end, it reverses the + playback direction and plays until it reaches the beginning when it + reverses the direction back to normal. This is mode is rarely supported for + streams. + +### API: ALLEGRO_SAMPLE_ID + +An ALLEGRO_SAMPLE_ID represents a sample being played via [al_play_sample]. +It can be used to later stop the sample with [al_stop_sample]. The underlying +ALLEGRO_SAMPLE_INSTANCE can be extracted using [al_lock_sample_id]. + +### API: ALLEGRO_SAMPLE + +An ALLEGRO_SAMPLE object stores the data necessary for playing pre-defined +digital audio. It holds a user-specified PCM data buffer and information about +its format (data length, depth, frequency, channel configuration). You can have +the same ALLEGRO_SAMPLE playing multiple times simultaneously. + +See also: [ALLEGRO_SAMPLE_INSTANCE] + +### API: ALLEGRO_SAMPLE_INSTANCE + +An ALLEGRO_SAMPLE_INSTANCE object represents a playable instance of a predefined +sound effect. +It holds information about how the effect should be played: These playback +parameters consist of the looping mode, loop start/end points, playing position, +speed, gain, pan and the playmode. Whether a sample instance is currently playing +or paused is also one of its properties. + +An instance uses the data from an [ALLEGRO_SAMPLE] object. Multiple instances may +be created from the same ALLEGRO_SAMPLE. An ALLEGRO_SAMPLE must not be +destroyed while there are instances which reference it. + +To actually produce audio output, an ALLEGRO_SAMPLE_INSTANCE must be attached to an +[ALLEGRO_MIXER] which eventually reaches an [ALLEGRO_VOICE] object. + +See also: [ALLEGRO_SAMPLE] + +### API: ALLEGRO_AUDIO_STREAM + +An ALLEGRO_AUDIO_STREAM object is used to stream generated audio to the sound +device, in real-time. This is done by reading from a buffer, which is split +into a number of fragments. Whenever a fragment has finished playing, the +user can refill it with new data. + +As with [ALLEGRO_SAMPLE_INSTANCE] objects, streams store information necessary +for playback, so you may not play the same stream multiple times simultaneously. +Streams also need to be attached to an [ALLEGRO_MIXER], which, eventually, reaches +an [ALLEGRO_VOICE] object. + +While playing, you must periodically fill fragments with new audio data. To +know when a new fragment is ready to be filled, you can either directly check +with [al_get_available_audio_stream_fragments], or listen to events from the +stream. + +You can register an audio stream event source to an event queue; see +[al_get_audio_stream_event_source]. An [ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT] +event is generated whenever a new fragment is ready. When you receive an +event, use [al_get_audio_stream_fragment] to obtain a pointer to the fragment +to be filled. The size and format are determined by the parameters passed to +[al_create_audio_stream]. + +If you're late with supplying new data, the stream will be silent until new data +is provided. You must call [al_drain_audio_stream] when you're finished with +supplying data to the stream. + +If the stream is created by [al_load_audio_stream] then it will also generate an +[ALLEGRO_EVENT_AUDIO_STREAM_FINISHED] event if it reaches the end of the file and +is not set to loop. + +### API: ALLEGRO_VOICE + +A voice represents an audio device on the system, which may be a real device, +or an abstract device provided by the operating system. +To play back audio, you would attach a mixer, sample instance or audio stream to +a voice. + +See also: [ALLEGRO_MIXER], [ALLEGRO_SAMPLE], [ALLEGRO_AUDIO_STREAM] + + +## Setting up audio + +### API: al_install_audio + +Install the audio subsystem. + +Returns true on success, false on failure. + +> Note: most users will call [al_reserve_samples] and [al_init_acodec_addon] +after this. + +See also: [al_reserve_samples], [al_uninstall_audio], [al_is_audio_installed], +[al_init_acodec_addon] + +### API: al_uninstall_audio + +Uninstalls the audio subsystem. + +See also: [al_install_audio] + +### API: al_is_audio_installed + +Returns true if [al_install_audio] was called previously and returned +successfully. + +### API: al_reserve_samples + +Reserves a number of sample instances, attaching them to the default mixer. +If no default mixer is set when this function is called, then it will create one +and attach it to the default voice. If no default voice has been set, it, too, +will be created. + +If you call this function a second time with a smaller number of samples, then +the excess internal sample instances will be destroyed causing some sounds to +stop and some instances returned by [al_lock_sample_id] to be invalidated. + +This diagram illustrates the structures that are set up: + + sample instance 1 + / sample instance 2 + default voice <-- default mixer <--- . + \ . + sample instance N + +Returns true on success, false on error. +[al_install_audio] must have been called first. + +See also: [al_set_default_mixer], [al_play_sample] + + +## Misc audio functions + +### API: al_get_allegro_audio_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. + +### API: al_get_audio_depth_size + +Return the size of a sample, in bytes, for the given format. The format is one +of the values listed under [ALLEGRO_AUDIO_DEPTH]. + +### API: al_get_channel_count + +Return the number of channels for the given channel configuration, which is one +of the values listed under [ALLEGRO_CHANNEL_CONF]. + +### API: al_fill_silence + +Fill a buffer with silence, for the given format and channel configuration. +The buffer must have enough space for the given number of samples, +and be properly aligned. + +Since: 5.1.8 + + +## Voice functions + +### API: al_create_voice + +Creates a voice structure and allocates a voice from the digital sound driver. +The passed frequency (in Hz), sample format and channel configuration are used +as a hint to what kind of data will be sent to the voice. However, the +underlying sound driver is free to use non-matching values. For example, it may +be the native format of the sound hardware. + +If a mixer is attached to the voice, the mixer will handle the conversion of +all its input streams to the voice format and care does not have to be taken +for this. However if you access the voice directly, make sure to not rely on the +parameters passed to this function, but instead query the returned voice for +the actual settings. + +See also: [al_destroy_voice] + +### API: al_destroy_voice + +Destroys the voice and deallocates it from the digital driver. +Does nothing if the voice is NULL. + +See also: [al_create_voice] + +### API: al_detach_voice + +Detaches the mixer, sample instance or audio stream from the voice. + +See also: [al_attach_mixer_to_voice], [al_attach_sample_instance_to_voice], +[al_attach_audio_stream_to_voice] + +### API: al_attach_audio_stream_to_voice + +Attaches an audio stream to a voice. The same rules as +[al_attach_sample_instance_to_voice] apply. This may fail if the driver can't create +a voice with the buffer count and buffer size the stream uses. + +An audio stream attached directly to a voice has a number of limitations: The +audio stream plays immediately and cannot be stopped. The stream position, +speed, gain and panning cannot be changed. At this time, we don't recommend +attaching audio streams directly to voices. Use a mixer inbetween. + +Returns true on success, false on failure. + +See also: [al_detach_voice] + +### API: al_attach_mixer_to_voice + +Attaches a mixer to a voice. It must have the same frequency and channel configuration, +but the depth may be different. + +Returns true on success, false on failure. + +See also: [al_detach_voice] + +### API: al_attach_sample_instance_to_voice + +Attaches a sample instance to a voice, and allows it to play. The instance's gain +and loop mode will be ignored, and it must have the same frequency, channel +configuration and depth (including signed-ness) as the voice. This function may +fail if the selected driver doesn't support preloading sample data. + +At this time, we don't recommend attaching sample instances directly to voices. +Use a mixer inbetween. + +Returns true on success, false on failure. + +See also: [al_detach_voice] + +### API: al_get_voice_frequency + +Return the frequency of the voice (in Hz), e.g. 44100. + +### API: al_get_voice_channels + +Return the channel configuration of the voice. + +See also: [ALLEGRO_CHANNEL_CONF]. + +### API: al_get_voice_depth + +Return the audio depth of the voice. + +See also: [ALLEGRO_AUDIO_DEPTH]. + +### API: al_get_voice_playing + +Return true if the voice is currently playing. + +See also: [al_set_voice_playing] + +### API: al_set_voice_playing + +Change whether a voice is playing or not. +This can only work if the voice has a non-streaming +object attached to it, e.g. a sample instance. +On success the voice's current sample position is reset. + +Returns true on success, false on failure. + +See also: [al_get_voice_playing] + +### API: al_get_voice_position + +When the voice has a non-streaming object attached to it, e.g. a sample, +returns the voice's current sample position. +Otherwise, returns zero. + +See also: [al_set_voice_position]. + +### API: al_set_voice_position + +Set the voice position. This can only work if the voice has a non-streaming +object attached to it, e.g. a sample instance. + +Returns true on success, false on failure. + +See also: [al_get_voice_position]. + + +## Sample functions + +### API: al_create_sample + +Create a sample data structure from the supplied buffer. +If `free_buf` is true then the buffer will be freed with [al_free] when the +sample data structure is destroyed. For portability (especially Windows), +the buffer should have been allocated with [al_malloc]. Otherwise you should +free the sample data yourself. + +A sample that is referred to by the `samples` parameter refers to a sequence +channel intensities. E.g. if you're making a stereo sample with the `samples` +set to 4, then the layout of the data in `buf` will be: + +~~~~ +LRLRLRLR +~~~~ + +Where L and R are the intensities for the left and right channels respectively. +A single sample, then, refers to the LR pair in this example. + +To allocate a buffer of the correct size, you can use something like this: + +~~~~c +int sample_size = al_get_channel_count(chan_conf) + * al_get_audio_depth_size(depth); +int bytes = samples * sample_size; +void *buffer = al_malloc(bytes); +~~~~ + +See also: [al_destroy_sample], [ALLEGRO_AUDIO_DEPTH], [ALLEGRO_CHANNEL_CONF] + +### API: al_destroy_sample + +Free the sample data structure. If it was created with the `free_buf` +parameter set to true, then the buffer will be freed with [al_free]. + +This function will stop any sample instances which may be playing the +buffer referenced by the [ALLEGRO_SAMPLE]. + +See also: [al_destroy_sample_instance], [al_stop_sample], [al_stop_samples] + +### API: al_play_sample + +Plays a sample on one of the sample instances created by [al_reserve_samples]. +Returns true on success, false on failure. +Playback may fail because all the reserved sample instances are currently used. + +Parameters: + +* gain - relative volume at which the sample is played; 1.0 is normal. +* pan - 0.0 is centred, -1.0 is left, 1.0 is right, or ALLEGRO_AUDIO_PAN_NONE. +* speed - relative speed at which the sample is played; 1.0 is normal. +* loop - ALLEGRO_PLAYMODE_ONCE, ALLEGRO_PLAYMODE_LOOP, or ALLEGRO_PLAYMODE_BIDIR +* ret_id - if non-NULL the variable which this points to will be assigned + an id representing the sample being played. If [al_play_sample] returns `false`, + then the contents of ret_id are invalid and must not be used as argument to + other functions. + +See also: [ALLEGRO_PLAYMODE], [ALLEGRO_AUDIO_PAN_NONE], [ALLEGRO_SAMPLE_ID], +[al_stop_sample], [al_stop_samples], [al_lock_sample_id]. + +### API: al_stop_sample + +Stop the sample started by [al_play_sample]. + +See also: [al_stop_samples] + +### API: al_lock_sample_id + +Locks a [ALLEGRO_SAMPLE_ID], returning the underlying [ALLEGRO_SAMPLE_INSTANCE]. +This allows you to adjust the various properties of the instance (such as +volume, pan, etc) while the sound is playing. + +This function will return `NULL` if the sound corresponding to the id is no +longer playing. + +While locked, `ALLEGRO_SAMPLE_ID` will be unavailable to additional calls to +[al_play_sample], even if the sound stops while locked. To put the +`ALLEGRO_SAMPLE_ID` back into the pool for reuse, make sure to call +`al_unlock_sample_id` when you're done with the instance. + +See also: [al_play_sample], [al_unlock_sample_id] + +Since: 5.2.3 + +> *[Unstable API]:* New API. + +### API: al_unlock_sample_id + +Unlocks a [ALLEGRO_SAMPLE_ID], allowing future calls to [al_play_sample] to +reuse it if possible. Note that after the id is unlocked, the +[ALLEGRO_SAMPLE_INSTANCE] that was previously returned by [al_lock_sample_id] +will possibly be playing a different sound, so you should only use it after +locking the id again. + +See also: [al_play_sample], [al_lock_sample_id] + +Since: 5.2.3 + +> *[Unstable API]:* New API. + +### API: al_stop_samples + +Stop all samples started by [al_play_sample]. + +See also: [al_stop_sample] + +### API: al_get_sample_channels + +Return the channel configuration of the sample. + +See also: [ALLEGRO_CHANNEL_CONF], [al_get_sample_depth], +[al_get_sample_frequency], [al_get_sample_length], [al_get_sample_data] + +### API: al_get_sample_depth + +Return the audio depth of the sample. + +See also: [ALLEGRO_AUDIO_DEPTH], [al_get_sample_channels], +[al_get_sample_frequency], [al_get_sample_length], [al_get_sample_data] + +### API: al_get_sample_frequency + +Return the frequency (in Hz) of the sample. + +See also: [al_get_sample_channels], [al_get_sample_depth], +[al_get_sample_length], [al_get_sample_data] + +### API: al_get_sample_length + +Return the length of the sample in sample values. + +See also: [al_get_sample_channels], [al_get_sample_depth], +[al_get_sample_frequency], [al_get_sample_data] + +### API: al_get_sample_data + +Return a pointer to the raw sample data. + +See also: [al_get_sample_channels], [al_get_sample_depth], +[al_get_sample_frequency], [al_get_sample_length] + + +## Sample instance functions + +### API: al_create_sample_instance + +Creates a sample instance, using the supplied sample data. The instance must be +attached to a mixer (or voice) in order to actually produce output. + +The argument may be NULL. You can then set the sample data later with +[al_set_sample]. + +See also: [al_destroy_sample_instance] + +### API: al_destroy_sample_instance + +Detaches the sample instance from anything it may be attached to and frees +it (the sample data, i.e. its ALLEGRO_SAMPLE, is *not* freed!). + +See also: [al_create_sample_instance] + +### API: al_play_sample_instance + +Play the sample instance. +Returns true on success, false on failure. + +See also: [al_stop_sample_instance] + +### API: al_stop_sample_instance + +Stop an sample instance playing. + +See also: [al_play_sample_instance] + +### API: al_get_sample_instance_channels + +Return the channel configuration of the sample instance's sample data. + +See also: [ALLEGRO_CHANNEL_CONF]. + +### API: al_get_sample_instance_depth + +Return the audio depth of the sample instance's sample data. + +See also: [ALLEGRO_AUDIO_DEPTH]. + +### API: al_get_sample_instance_frequency + +Return the frequency (in Hz) of the sample instance's sample data. + +### API: al_get_sample_instance_length + +Return the length of the sample instance in sample values. This property may +differ from the length of the instance's sample data. + +See also: [al_set_sample_instance_length], [al_get_sample_instance_time] + +### API: al_set_sample_instance_length + +Set the length of the sample instance in sample values. This can be used to play +only parts of the underlying sample. Be careful not to exceed the actual length +of the sample data, though. + +Return true on success, false on failure. Will fail if the sample instance is +currently playing. + +See also: [al_get_sample_instance_length] + +### API: al_get_sample_instance_position + +Get the playback position of a sample instance. + +See also: [al_set_sample_instance_position] + +### API: al_set_sample_instance_position + +Set the playback position of a sample instance. + +Returns true on success, false on failure. + +See also: [al_get_sample_instance_position] + +### API: al_get_sample_instance_speed + +Return the relative playback speed of the sample instance. + +See also: [al_set_sample_instance_speed] + +### API: al_set_sample_instance_speed + +Set the relative playback speed of the sample instance. 1.0 means normal speed. + +Return true on success, false on failure. Will fail if the sample instance is +attached directly to a voice. + +See also: [al_get_sample_instance_speed] + +### API: al_get_sample_instance_gain + +Return the playback gain of the sample instance. + +See also: [al_set_sample_instance_gain] + +### API: al_set_sample_instance_gain + +Set the playback gain of the sample instance. + +Returns true on success, false on failure. Will fail if the sample instance +is attached directly to a voice. + +See also: [al_get_sample_instance_gain] + +### API: al_get_sample_instance_pan + +Get the pan value of the sample instance. + +See also: [al_set_sample_instance_pan]. + +### API: al_set_sample_instance_pan + +Set the pan value on a sample instance. A value of -1.0 means to play the +sample only through the left speaker; +1.0 means only through the right +speaker; 0.0 means the sample is centre balanced. +A special value [ALLEGRO_AUDIO_PAN_NONE] disables panning and plays the +sample at its original level. This will be louder than a pan value of 0.0. + +> Note: panning samples with more than two channels doesn't work yet. + +Returns true on success, false on failure. +Will fail if the sample instance is attached directly to a voice. + +See also: [al_get_sample_instance_pan], [ALLEGRO_AUDIO_PAN_NONE] + +### API: al_get_sample_instance_time + +Return the length of the sample instance in seconds, +assuming a playback speed of 1.0. + +See also: [al_get_sample_instance_length] + +### API: al_get_sample_instance_playmode + +Return the playback mode of the sample instance. + +See also: [ALLEGRO_PLAYMODE], [al_set_sample_instance_playmode] + +### API: al_set_sample_instance_playmode + +Set the playback mode of the sample instance. + +Returns true on success, false on failure. + +See also: [ALLEGRO_PLAYMODE], [al_get_sample_instance_playmode] + +### API: al_get_sample_instance_playing + +Return true if the sample instance is in the playing state. +This may be true even if the instance is not attached to anything. + +See also: [al_set_sample_instance_playing] + +### API: al_set_sample_instance_playing + +Change whether the sample instance is playing. + +The instance does not need to be attached to anything (since: 5.1.8). + +Returns true on success, false on failure. + +See also: [al_get_sample_instance_playing] + +### API: al_get_sample_instance_attached + +Return whether the sample instance is attached to something. + +See also: [al_attach_sample_instance_to_mixer], +[al_attach_sample_instance_to_voice], [al_detach_sample_instance] + +### API: al_detach_sample_instance + +Detach the sample instance from whatever it's attached to, +if anything. + +Returns true on success. + +See also: [al_attach_sample_instance_to_mixer], +[al_attach_sample_instance_to_voice], [al_get_sample_instance_attached] + +### API: al_get_sample + +Return the sample data that the sample instance plays. + +Note this returns a pointer to an internal structure, *not* the +[ALLEGRO_SAMPLE] that you may have passed to [al_set_sample]. +However, the sample buffer of the returned ALLEGRO_SAMPLE will be the same as +the one that was used to create the sample (passed to [al_create_sample]). You +can use [al_get_sample_data] on the return value to retrieve and compare it. + +See also: [al_set_sample] + +### API: al_set_sample + +Change the sample data that a sample instance plays. This can be quite an +involved process. + +First, the sample is stopped if it is not already. + +Next, if data is NULL, the sample is detached from its parent (if any). + +If data is not NULL, the sample may be detached and reattached to its +parent (if any). This is not necessary if the old sample data and new +sample data have the same frequency, depth and channel configuration. +Reattaching may not always succeed. + +On success, the sample remains stopped. The playback position and loop +end points are reset to their default values. The loop mode remains +unchanged. + +Returns true on success, false on failure. On failure, the sample will +be stopped and detached from its parent. + +See also: [al_get_sample] + +### API: al_set_sample_instance_channel_matrix + +Set the matrix used to mix the channels coming from this instance into the +mixer it is attached to. Normally Allegro derives the values of this matrix +from the gain and pan settings, as well as the channel configurations of this +instance and the mixer it is attached to, but this allows you override that +default value. Note that if you do set gain or pan of this instance or the +mixer it is attached to, you'll need to call this function again. + +The matrix has mixer channel rows and sample channel columns, and is row major. +For example, if you have a stereo sample instance and want to mix it to a 5.1 +mixer you could use this code: + +~~~~c +float matrix[] = { + 0.5, 0.0, /* Half left to front left */ + 0.0, 0.5, /* Half right to front right */ + 0.5, 0.0, /* Half left to rear left */ + 0.0, 0.5, /* Half right to rear right */ + 0.1, 0.1, /* Mix left and right for center */ + 0.1, 0.1, /* Mix left and right for center */ +}; + +al_set_sample_instance_channel_matrix(instance, matrix); +~~~~ + +Returns true on success, false on failure (e.g. if this is not attached to a +mixer). + +Since: 5.2.3 + +> *[Unstable API]:* New API. + + +## Mixer functions + +### API: al_create_mixer + +Creates a mixer to attach sample instances, audio streams, or other mixers to. +It will mix into a buffer at the requested frequency (in Hz) and channel count. + +The only supported audio depths are ALLEGRO_AUDIO_DEPTH_FLOAT32 +and ALLEGRO_AUDIO_DEPTH_INT16 (not yet complete). + +To actually produce any output, the mixer will have to be attached to a voice. + +Returns true on success, false on error. + +See also: [al_destroy_mixer], [ALLEGRO_AUDIO_DEPTH], [ALLEGRO_CHANNEL_CONF] + +### API: al_destroy_mixer + +Destroys the mixer. + +See also: [al_create_mixer] + +### API: al_get_default_mixer + +Return the default mixer, or NULL if one has not been set. +Although different configurations of mixers and voices can be used, in +most cases a single mixer attached to a voice is what you want. +The default mixer is used by [al_play_sample]. + +See also: [al_reserve_samples], [al_play_sample], [al_set_default_mixer], +[al_restore_default_mixer] + +### API: al_set_default_mixer + +Sets the default mixer. All samples started with [al_play_sample] +will be stopped and all sample instances returned by [al_lock_sample_id] will be +invalidated. If you are using your own mixer, this should be called before +[al_reserve_samples]. + +Returns true on success, false on error. + +See also: [al_reserve_samples], [al_play_sample], [al_get_default_mixer], +[al_restore_default_mixer] + +### API: al_restore_default_mixer + +Restores Allegro's default mixer and attaches it to the default voice. If the default +mixer hasn't been created before, it will be created. +If the default voice hasn't been set via [al_set_default_voice] or created before, +it will also be created. All samples started with [al_play_sample] will be stopped +and all sample instances returned by [al_lock_sample_id] will be invalidated. + +Returns true on success, false on error. + +See also: [al_get_default_mixer], [al_set_default_mixer], [al_reserve_samples]. + +### API: al_get_default_voice + +Returns the default voice or NULL if there is none. + +Since: 5.1.13 + +See also: [al_get_default_mixer] + +### API: al_set_default_voice + +You can call this before calling al_restore_default_mixer to provide the +voice which should be used. Any previous voice will be destroyed. You +can also pass NULL to destroy the current default voice. + +Since: 5.1.13 + +See also: [al_get_default_mixer] + +### API: al_attach_mixer_to_mixer + +Attaches the mixer passed as the first argument onto the mixer passed as the +second argument. The first mixer (that is going to be attached) must not already +be attached to anything. Both mixers must use the same frequency, audio depth +and channel configuration. + +Returns true on success, false on error. + +It is invalid to attach a mixer to itself. + +See also: [al_detach_mixer]. + +### API: al_attach_sample_instance_to_mixer + +Attach a sample instance to a mixer. The instance must not already be attached +to anything. + +Returns true on success, false on failure. + +See also: [al_detach_sample_instance]. + +### API: al_attach_audio_stream_to_mixer + +Attach an audio stream to a mixer. The stream must not already be attached +to anything. + +Returns true on success, false on failure. + +See also: [al_detach_audio_stream]. + +### API: al_get_mixer_frequency + +Return the mixer frequency (in Hz). + +See also: [al_set_mixer_frequency] + +### API: al_set_mixer_frequency + +Set the mixer frequency (in Hz). This will only work if the mixer is not +attached to anything. + +Returns true on success, false on failure. + +See also: [al_get_mixer_frequency] + +### API: al_get_mixer_channels + +Return the mixer channel configuration. + +See also: [ALLEGRO_CHANNEL_CONF]. + +### API: al_get_mixer_depth + +Return the mixer audio depth. + +See also: [ALLEGRO_AUDIO_DEPTH]. + +### API: al_get_mixer_gain + +Return the mixer gain (amplification factor). The default is 1.0. + +Since: 5.0.6, 5.1.0 + +See also: [al_set_mixer_gain]. + +### API: al_set_mixer_gain + +Set the mixer gain (amplification factor). + +Returns true on success, false on failure. + +Since: 5.0.6, 5.1.0 + +See also: [al_get_mixer_gain] + +### API: al_get_mixer_quality + +Return the mixer quality. + +See also: [ALLEGRO_MIXER_QUALITY], [al_set_mixer_quality] + +### API: al_set_mixer_quality + +Set the mixer quality. This can only succeed if the mixer does not have +anything attached to it. + +Returns true on success, false on failure. + +See also: [ALLEGRO_MIXER_QUALITY], [al_get_mixer_quality] + +### API: al_get_mixer_playing + +Return true if the mixer is playing. + +See also: [al_set_mixer_playing]. + +### API: al_set_mixer_playing + +Change whether the mixer is playing. + +Returns true on success, false on failure. + +See also: [al_get_mixer_playing]. + +### API: al_get_mixer_attached + +Return true if the mixer is attached to something. + +See also: [al_attach_sample_instance_to_mixer], [al_attach_audio_stream_to_mixer], +[al_attach_mixer_to_mixer], [al_detach_mixer] + +### API: al_detach_mixer + +Detach the mixer from whatever it is attached to, if anything. + +See also: [al_attach_mixer_to_mixer]. + +### API: al_set_mixer_postprocess_callback + +Sets a post-processing filter function that's called after the attached +streams have been mixed. The buffer's format will be whatever the mixer +was created with. The sample count and user-data pointer is also passed. + +> *Note:* The callback is called from a dedicated audio thread. + + + +## Stream functions + +### API: al_create_audio_stream + +Creates an [ALLEGRO_AUDIO_STREAM]. The stream will be set to play by default. +It will feed audio data from a buffer, which is split into a number of +fragments. + +Parameters: + +* fragment_count - How many fragments to use for the audio stream. + Usually only two fragments are required - splitting the audio buffer in + two halves. But it means that the only time when new data can be supplied + is whenever one half has finished playing. When using many fragments, + you usually will use fewer samples for one, so there always will be + (small) fragments available to be filled with new data. + +* frag_samples - The size of a fragment in samples. See note and explanation + below. + +* freq - The frequency, in Hertz. + +* depth - Must be one of the values listed for [ALLEGRO_AUDIO_DEPTH]. + +* chan_conf - Must be one of the values listed for [ALLEGRO_CHANNEL_CONF]. + +A sample that is referred to by the *frag_samples* parameter refers to a +sequence channel intensities. E.g. if you're making a stereo stream with the +*frag_samples* set to 4, then the layout of the data in the fragment will be: + +~~~~ +LRLRLRLR +~~~~ + +Where L and R are the intensities for the left and right channels respectively. +A single sample, then, refers to the LR pair in this example. + +The choice of *fragment_count*, *frag_samples* and *freq* directly influences +the audio delay. The delay in seconds can be expressed as: + + delay = fragment_count * frag_samples / freq + +This is only the delay due to Allegro's streaming, there may be additional +delay caused by sound drivers and/or hardware. + +> *Note:* If you know the fragment size in bytes, you can get the size in samples +> like this: +> +> sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth); +> samples = bytes_per_fragment / sample_size; +> +> The size of the complete buffer is: +> +> buffer_size = bytes_per_fragment * fragment_count + +> *Note:* Unlike many Allegro objects, audio streams are not implicitly destroyed +when Allegro is shut down. You must destroy them manually with +[al_destroy_audio_stream] before the audio system is shut down. + +### API: al_destroy_audio_stream + +Destroy an audio stream which was created with [al_create_audio_stream] +or [al_load_audio_stream]. + +> *Note:* If the stream is still attached to a mixer or voice, +[al_detach_audio_stream] is automatically called on it first. + +See also: [al_drain_audio_stream]. + +### API: al_get_audio_stream_event_source + +Retrieve the associated event source. + +See [al_get_audio_stream_fragment] for a description of the +[ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT] event that audio streams emit. + +### API: al_drain_audio_stream + +You should call this to finalise an audio stream that you will no longer +be feeding, to wait for all pending buffers to finish playing. +The stream's playing state will change to false. + +See also: [al_destroy_audio_stream] + +### API: al_rewind_audio_stream + +Set the streaming file playing position to the beginning. Returns true on +success. Currently this can only be called on streams created with +[al_load_audio_stream], [al_load_audio_stream_f] and the format-specific +functions underlying those functions. + +### API: al_get_audio_stream_frequency + +Return the stream frequency (in Hz). + +### API: al_get_audio_stream_channels + +Return the stream channel configuration. + +See also: [ALLEGRO_CHANNEL_CONF]. + +### API: al_get_audio_stream_depth + +Return the stream audio depth. + +See also: [ALLEGRO_AUDIO_DEPTH]. + +### API: al_get_audio_stream_length + +Return the stream length in samples. + +### API: al_get_audio_stream_speed + +Return the relative playback speed of the stream. + +See also: [al_set_audio_stream_speed]. + +### API: al_set_audio_stream_speed + +Set the relative playback speed of the stream. 1.0 means normal speed. + +Return true on success, false on failure. Will fail if the audio stream is +attached directly to a voice. + +See also: [al_get_audio_stream_speed]. + +### API: al_get_audio_stream_gain + +Return the playback gain of the stream. + +See also: [al_set_audio_stream_gain]. + +### API: al_set_audio_stream_gain + +Set the playback gain of the stream. + +Returns true on success, false on failure. Will fail if the audio stream +is attached directly to a voice. + +See also: [al_get_audio_stream_gain]. + +### API: al_get_audio_stream_pan + +Get the pan value of the stream. + +See also: [al_set_audio_stream_pan]. + +### API: al_set_audio_stream_pan + +Set the pan value on an audio stream. A value of -1.0 means to play the +stream only through the left speaker; +1.0 means only through the right +speaker; 0.0 means the sample is centre balanced. +A special value [ALLEGRO_AUDIO_PAN_NONE] disables panning and plays the +stream at its original level. This will be louder than a pan value of 0.0. + +Returns true on success, false on failure. +Will fail if the audio stream is attached directly to a voice. + +See also: [al_get_audio_stream_pan], [ALLEGRO_AUDIO_PAN_NONE] + +### API: al_get_audio_stream_playing + +Return true if the stream is playing. + +See also: [al_set_audio_stream_playing]. + +### API: al_set_audio_stream_playing + +Change whether the stream is playing. + +Returns true on success, false on failure. + +See also: [al_get_audio_stream_playing] + +### API: al_get_audio_stream_playmode + +Return the playback mode of the stream. + +See also: [ALLEGRO_PLAYMODE], [al_set_audio_stream_playmode]. + +### API: al_set_audio_stream_playmode + +Set the playback mode of the stream. + +Returns true on success, false on failure. + +See also: [ALLEGRO_PLAYMODE], [al_get_audio_stream_playmode]. + +### API: al_get_audio_stream_attached + +Return whether the stream is attached to something. + +See also: [al_attach_audio_stream_to_mixer], [al_attach_audio_stream_to_voice], +[al_detach_audio_stream]. + +### API: al_detach_audio_stream + +Detach the stream from whatever it's attached to, +if anything. + +See also: [al_attach_audio_stream_to_mixer], [al_attach_audio_stream_to_voice], +[al_get_audio_stream_attached]. + +### API: al_get_audio_stream_played_samples + +Get the number of samples consumed by the parent since the audio stream was +started. + +Since: 5.1.8 + +### API: al_get_audio_stream_fragment + +When using Allegro's audio streaming, you will use this function to continuously +provide new sample data to a stream. + +If the stream is ready for new data, the function will return the address +of an internal buffer to be filled with audio data. +The length and format of the buffer are specified with [al_create_audio_stream] +or can be queried with the various functions described here. +Once the buffer is filled, you must signal this to Allegro by passing the +buffer to [al_set_audio_stream_fragment]. + +If the stream is not ready for new data, the function will return NULL. + +> *Note:* If you listen to events from the stream, an +[ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT] event will be generated whenever a new +fragment is ready. However, getting an event is *not* a guarantee that +[al_get_audio_stream_fragment] will not return NULL, so you still must check for it. + +See also: [al_set_audio_stream_fragment], [al_get_audio_stream_event_source], +[al_get_audio_stream_frequency], [al_get_audio_stream_channels], +[al_get_audio_stream_depth], [al_get_audio_stream_length] + +### API: al_set_audio_stream_fragment + +This function needs to be called for every successful call of +[al_get_audio_stream_fragment] to indicate that the buffer (pointed to by `val`) is +filled with new data. + +See also: [al_get_audio_stream_fragment] + +### API: al_get_audio_stream_fragments + +Returns the number of fragments this stream uses. This is the same value as +passed to [al_create_audio_stream] when a new stream is created. + +See also: [al_get_available_audio_stream_fragments] + +### API: al_get_available_audio_stream_fragments + +Returns the number of available fragments in the stream, that is, fragments +which are not currently filled with data for playback. + +See also: [al_get_audio_stream_fragment], [al_get_audio_stream_fragments] + +### API: al_seek_audio_stream_secs + +Set the streaming file playing position to time. Returns true on success. +Currently this can only be called on streams created with +[al_load_audio_stream], [al_load_audio_stream_f] and the format-specific +functions underlying those functions. + +See also: [al_get_audio_stream_position_secs], +[al_get_audio_stream_length_secs] + +### API: al_get_audio_stream_position_secs + +Return the position of the stream in seconds. +Currently this can only be called on streams created with +[al_load_audio_stream]. + +See also: [al_get_audio_stream_length_secs] + +### API: al_get_audio_stream_length_secs + +Return the length of the stream in seconds, if known. +Otherwise returns zero. + +Currently this can only be called on streams created with +[al_load_audio_stream], [al_load_audio_stream_f] and the format-specific +functions underlying those functions. + +See also: [al_get_audio_stream_position_secs] + +### API: al_set_audio_stream_loop_secs + +Sets the loop points for the stream in seconds. +Currently this can only be called on streams created with +[al_load_audio_stream], [al_load_audio_stream_f] and the format-specific +functions underlying those functions. + +### API: al_set_audio_stream_channel_matrix + +Like [al_set_sample_instance_channel_matrix] but for streams. + +Since: 5.2.3 + +> *[Unstable API]:* New API. + +## Audio file I/O + +### API: al_register_sample_loader + +Register a handler for [al_load_sample]. The given function will be used to +handle the loading of sample files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `loader` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_sample_loader_f], [al_register_sample_saver] + +### API: al_register_sample_loader_f + +Register a handler for [al_load_sample_f]. The given function will be used to +handle the loading of sample files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `loader` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_sample_loader] + +### API: al_register_sample_saver + +Register a handler for [al_save_sample]. The given function will be used to +handle the saving of sample files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `saver` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_sample_saver_f], [al_register_sample_loader] + +### API: al_register_sample_saver_f + +Register a handler for [al_save_sample_f]. The given function will be used to +handle the saving of sample files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `saver` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_sample_saver] + +### API: al_register_audio_stream_loader + +Register a handler for [al_load_audio_stream]. The given function will be +used to open streams from files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `stream_loader` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_audio_stream_loader_f] + +### API: al_register_audio_stream_loader_f + +Register a handler for [al_load_audio_stream_f]. The given function will be +used to open streams from files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `stream_loader` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_audio_stream_loader] + +### API: al_load_sample + +Loads a few different audio file formats based on their extension. + +Note that this stores the entire file in memory at once, which +may be time consuming. To read the file as it is needed, +use [al_load_audio_stream]. + +Returns the sample on success, NULL on failure. + +> *Note:* the allegro_audio library does not support any audio file formats by +default. You must use the allegro_acodec addon, or register your own format +handler. + +See also: [al_register_sample_loader], [al_init_acodec_addon] + +### API: al_load_sample_f + +Loads an audio file from an [ALLEGRO_FILE] stream into an [ALLEGRO_SAMPLE]. +The file type is determined by the passed 'ident' parameter, which is a file +name extension including the leading dot. + +Note that this stores the entire file in memory at once, which +may be time consuming. To read the file as it is needed, +use [al_load_audio_stream_f]. + +Returns the sample on success, NULL on failure. +The file remains open afterwards. + +> *Note:* the allegro_audio library does not support any audio file formats by +default. You must use the allegro_acodec addon, or register your own format +handler. + +See also: [al_register_sample_loader_f], [al_init_acodec_addon] + +### API: al_load_audio_stream + +Loads an audio file from disk as it is needed. + +Unlike regular streams, the one returned by this function +need not be fed by the user; the library will automatically +read more of the file as it is needed. The stream will +contain *buffer_count* buffers with *samples* samples. + +The audio stream will start in the playing state. +It should be attached to a voice or mixer to generate any output. +See [ALLEGRO_AUDIO_STREAM] for more details. + +Returns the stream on success, NULL on failure. + +> *Note:* the allegro_audio library does not support any audio file formats by +default. You must use the allegro_acodec addon, or register your own format +handler. + +See also: [al_load_audio_stream_f], [al_register_audio_stream_loader], +[al_init_acodec_addon] + +### API: al_load_audio_stream_f + +Loads an audio file from [ALLEGRO_FILE] stream as it is needed. + +Unlike regular streams, the one returned by this function +need not be fed by the user; the library will automatically +read more of the file as it is needed. The stream will +contain *buffer_count* buffers with *samples* samples. + +The file type is determined by the passed 'ident' parameter, which is a file +name extension including the leading dot. + +The audio stream will start in the playing state. +It should be attached to a voice or mixer to generate any output. +See [ALLEGRO_AUDIO_STREAM] for more details. + +Returns the stream on success, NULL on failure. +On success the file should be considered owned by the audio stream, +and will be closed when the audio stream is destroyed. +On failure the file will be closed. + +> *Note:* the allegro_audio library does not support any audio file formats by +default. You must use the allegro_acodec addon, or register your own format +handler. + +See also: [al_load_audio_stream], [al_register_audio_stream_loader_f], +[al_init_acodec_addon] + +### API: al_save_sample + +Writes a sample into a file. Currently, wav is +the only supported format, and the extension +must be ".wav". + +Returns true on success, false on error. + +> *Note:* the allegro_audio library does not support any audio file formats by +default. You must use the allegro_acodec addon, or register your own format +handler. + +See also: [al_save_sample_f], [al_register_sample_saver], +[al_init_acodec_addon] + +### API: al_save_sample_f + +Writes a sample into a [ALLEGRO_FILE] filestream. Currently, wav is +the only supported format, and the extension +must be ".wav". + +Returns true on success, false on error. +The file remains open afterwards. + +> *Note:* the allegro_audio library does not support any audio file formats by +default. You must use the allegro_acodec addon, or register your own format +handler. + +See also: [al_save_sample], [al_register_sample_saver_f], +[al_init_acodec_addon] + + +## Audio recording + +Allegro's audio recording routines give you real-time access to raw, +uncompressed audio input streams. Since Allegro hides all of the +platform specific implementation details with its own buffering, it will +add a small amount of latency. However, for most applications that small +overhead will not adversely affect performance. + +Recording is supported by the ALSA, AudioQueue, DirectSound8, and +PulseAudio drivers. Enumerating or choosing other recording devices is not +yet supported. + +### API: ALLEGRO_AUDIO_RECORDER + +An opaque datatype that represents a recording device. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. + +### API: ALLEGRO_AUDIO_RECORDER_EVENT + +Structure that holds the audio recorder event data. Every event type +will contain: + +* .source: pointer to the audio recorder + +The following will be available depending on the event type: + +* .buffer: pointer to buffer containing the audio samples +* .samples: number of samples (not bytes) that are available + +Since 5.1.1 + +See also: [al_get_audio_recorder_event] + +> *[Unstable API]:* The API may need a slight redesign. + +### API: al_create_audio_recorder + +Creates an audio recorder using the system's default recording device. +(So if the returned device does not work, try updating the system's default +recording device.) + +Allegro will internally buffer several seconds of captured audio with minimal +latency. (XXX: These settings need to be exposed via config or API calls.) +Audio will be copied out of that private buffer into a fragment buffer +of the size specified by the samples parameter. Whenever a new fragment is +ready an event will be generated. + +The total size of the fragment buffer is fragment_count * samples * bytes_per_sample. +It is treated as a circular, never ending buffer. If you do not process the information +fast enough, it will be overrun. Because of that, even if you only ever need to +process one small fragment at a time, you should still use a large enough value for +fragment_count to hold a few seconds of audio. + +frequency is the number of samples per second to record. Common values are: + +* 8000 - telephone quality speech +* 11025 +* 22050 +* 44100 - CD quality music (if 16-bit, stereo) + +For maximum compatibility, use a depth of ALLEGRO_AUDIO_DEPTH_UINT8 or +ALLEGRO_AUDIO_DEPTH_INT16, and a single (mono) channel. + +The recorder will not record until you start it with [al_start_audio_recorder]. + +On failure, returns NULL. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. + +### API: al_start_audio_recorder + +Begin recording into the fragment buffer. Once a complete fragment has been +captured (as specified in [al_create_audio_recorder]), an +[ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT] event will be triggered. + +Returns true if it was able to begin recording. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. + +### API: al_stop_audio_recorder + +Stop capturing audio data. Note that the audio recorder is still active +and consuming resources, so if you are finished recording you should destroy +it with [al_destroy_audio_recorder]. + +You may still receive a few events after you call this function as the device +flushes the buffer. + +If you restart the recorder, it will begin recording at the beginning of the +next fragment buffer. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. + +### API: al_is_audio_recorder_recording + +Returns true if the audio recorder is currently capturing data and generating +events. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. + +### API: al_get_audio_recorder_event + +Returns the event as an [ALLEGRO_AUDIO_RECORDER_EVENT]. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. + +### API: al_get_audio_recorder_event_source + +Returns the event source for the recorder that generates the various recording +events. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. + +### API: al_destroy_audio_recorder + +Destroys the audio recorder and frees all resources associated with it. It +is safe to destroy a recorder that is recording. + +You may receive events after the recorder has been destroyed. They must be +ignored, as the fragment buffer will no longer be valid. + +Since: 5.1.1 + +> *[Unstable API]:* The API may need a slight redesign. diff --git a/allegro/docs/src/refman/color.txt b/allegro/docs/src/refman/color.txt new file mode 100644 index 00000000..d7076045 --- /dev/null +++ b/allegro/docs/src/refman/color.txt @@ -0,0 +1,466 @@ +# Color addon + +These functions are declared in the following header file. +Link with allegro_color. + +~~~~c + #include +~~~~ + +When converting between certain color spaces, RGB colors are implicitly +assumed to mean sRGB. + +sRGB is a standard which maps RGB colors to absolute colors. sRGB is +very close to RGB values on a monitor which has a gamma value of 2.2. +For example when the red component of a color is 0.5, the monitor will +use a brightness of pow(0.5, 2.2) or about 22% - and not 50%. The reason +is that human eyes can distinguish better between dark colors than +between bright colors, and so if a pixel of the monitor is lit up to +22% of its maximum power it already will appear at half brightness to a +human eye. + +sRGB improves upon simple gamma correction by taking differences +between the three color channels into account as well. In general, most +monitors nowadays try to be close to the sRGB specification. And so if +in an Allegro game you display something with color + +al_map_rgb_f(0.5, 0.5, 0,5) + +then it will appear at about half brightness (even though the actual +brightness output of the monitor will be less than half). + + +## API: al_color_cmyk + +Return an [ALLEGRO_COLOR] structure from CMYK values (cyan, magenta, yellow, +black). + +See also: [al_color_cmyk_to_rgb], [al_color_rgb_to_cmyk] + + +## API: al_color_cmyk_to_rgb + +Convert CMYK values to RGB values. + +See also: [al_color_cmyk], [al_color_rgb_to_cmyk] + + +## API: al_color_hsl + +Return an [ALLEGRO_COLOR] structure from HSL (hue, saturation, lightness) +values. + +Parameters: + +* hue - Color hue angle in the range 0..360 +* saturation - Color saturation in the range 0..1 +* lightness - Color lightness in the range 0..1 + +See also: [al_color_hsl_to_rgb], [al_color_hsv] + + +## API: al_color_hsl_to_rgb + +Convert values in HSL color model to RGB color model. + +Parameters: + +* hue - Color hue angle in the range 0..360 +* saturation - Color saturation in the range 0..1 +* lightness - Color lightness in the range 0..1 +* red, green, blue - returned RGB values in the range 0..1 + +See also: [al_color_rgb_to_hsl], [al_color_hsl], [al_color_hsv_to_rgb] + + +## API: al_color_hsv + +Return an [ALLEGRO_COLOR] structure from HSV (hue, saturation, value) +values. + +Parameters: + +* hue - Color hue angle in the range 0..360 +* saturation - Color saturation in the range 0..1 +* value - Color value in the range 0..1 + +See also: [al_color_hsv_to_rgb], [al_color_hsl] + + +## API: al_color_hsv_to_rgb + +Convert values in HSV color model to RGB color model. + +Parameters: + +* hue - Color hue angle in the range 0..360 +* saturation - Color saturation in the range 0..1 +* value - Color value in the range 0..1 +* red, green, blue - returned RGB values in the range 0..1 + +See also: [al_color_rgb_to_hsv], [al_color_hsv], [al_color_hsl_to_rgb] + + +## API: al_color_html + +Interprets an HTML-style hex number (e.g. #00faff) as a color. +The accepted format is the same as [al_color_html_to_rgb]. + +Returns the interpreted color, or `al_map_rgba(0, 0, 0, 0)` if the string +could not be parsed. + +> *Note*: the behaviour on invalid strings is different from Allegro 5.0.x. + +See also: [al_color_html_to_rgb], [al_color_rgb_to_html] + + +## API: al_color_html_to_rgb + +Interprets an HTML-style hex number (e.g. #00faff) as a color. +The only accepted formats are "#RRGGBB" and "RRGGBB" where R, G, B are +hexadecimal digits [0-9A-Fa-f]. + +Returns true on success, false on failure. +On failure all components are set to zero. + +> *Note*: the behaviour on invalid strings is different from Allegro 5.0.x. + +See also: [al_color_html], [al_color_rgb_to_html] + + +## API: al_color_rgb_to_html + +Create an HTML-style string representation of an [ALLEGRO_COLOR], +e.g. #00faff. + +Parameters: + +* red, green, blue - The color components in the range 0..1. +* string - A pointer to a buffer of at least 8 bytes, into which the result + will be written (including the NUL terminator). + +Example: + +~~~~c +char html[8]; +al_color_rgb_to_html(1, 0, 0, html); +~~~~ + +Now html will contain "#ff0000". + +See also: [al_color_html], [al_color_html_to_rgb] + + +## API: al_color_name + +Return an [ALLEGRO_COLOR] with the given name. If the color is not found then +black is returned. + +See [al_color_name_to_rgb] for the list of names. + + +## API: al_color_name_to_rgb + +Parameters: + +* name - The (lowercase) name of the color. +* r, g, b - If one of the recognized color names below is passed, + the corresponding RGB values in the range 0..1 are written. + +The 148 recognized names are: + +> aliceblue, antiquewhite, aqua, aquamarine, azure, beige, bisque, +black, blanchedalmond, blue, blueviolet, brown, burlywood, cadetblue, +chartreuse, chocolate, coral, cornflowerblue, cornsilk, crimson, +cyan, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, +darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, +darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, +darkturquoise, darkviolet, deeppink, deepskyblue, dimgray, +dodgerblue, firebrick, floralwhite, forestgreen, fuchsia, gainsboro, +ghostwhite, goldenrod, gold, gray, green, greenyellow, honeydew, +hotpink, indianred, indigo, ivory, khaki, lavenderblush, lavender, +lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan, +lightgoldenrodyellow, lightgreen, lightgrey, lightpink, +lightsalmon, lightseagreen, lightskyblue, lightslategray, +lightsteelblue, lightyellow, lime, limegreen, linen, magenta, maroon, +mediumaquamarine, mediumblue, mediumorchid, mediumpurple, +mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, +mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, +avajowhite, navy, oldlace, olive, olivedrab, orange, orangered, +orchid, palegoldenrod, palegreen, paleturquoise, palevioletred, +papayawhip, peachpuff, peru, pink, plum, powderblue, purple, +rebeccapurple, red, rosybrown, royalblue, saddlebrown, salmon, +sandybrown, seagreen, seashell, sienna, silver, skyblue, slateblue, +slategray, snow, springgreen, steelblue, tan, teal, thistle, tomato, +turquoise, violet, wheat, white, whitesmoke, yellow, yellowgreen + +They are taken from CSS: + +Note that these 9 colors have two names and so there are only 139 +distinct colors: aqua = cyan, darkgray = darkgrey, darkslategray = +darkslategrey, dimgray = dimgrey, fuchsia = purple, gray = grey, +lightgray = lightgrey, lightslategray = lightslategrey, slategray = +slategrey + +Returns: +true if a name from the list above was passed, else false. + +See also: [al_color_name] + + +## API: al_color_rgb_to_cmyk + +Each RGB color can be represented in CMYK with a K component of 0 +with the following formula: + + C = 1 - R + M = 1 - G + Y = 1 - B + K = 0 + +This function will instead find the representation with the maximal +value for K and minimal color components. + +See also: [al_color_cmyk], [al_color_cmyk_to_rgb] + + +## API: al_color_rgb_to_hsl + +Given an RGB triplet with components in the range 0..1, return +the hue in degrees from 0..360 and saturation and lightness in the +range 0..1. + +See also: [al_color_hsl_to_rgb], [al_color_hsl] + + +## API: al_color_rgb_to_hsv + +Given an RGB triplet with components in the range 0..1, return +the hue in degrees from 0..360 and saturation and value in the +range 0..1. + +See also: [al_color_hsv_to_rgb], [al_color_hsv] + + +## API: al_color_rgb_to_name + +Given an RGB triplet with components in the range 0..1, find a color +name describing it approximately. + +See also: [al_color_name_to_rgb], [al_color_name] + + +## API: al_color_rgb_to_xyz + +Convert RGB values to XYZ color space. + +Since: 5.2.3 + +See also: [al_color_xyz], [al_color_xyz_to_rgb] + + +## API: al_color_xyz + +Return an [ALLEGRO_COLOR] structure from XYZ values. The CIE 1931 XYZ +color space consists of three components in the range 0..1. The Y +component corresponds to luminance and the X and Z components define +the color. + +RGB components are always assumed to be in sRGB space. + +> *Note:* +> +> The XYZ color space can represent more colors than are +> visible in sRGB and therefore conversion may result in RGB values +> outside of the 0..1 range. You can check for that case with +> [al_is_color_valid]. + +Since: 5.2.3 + +See also: [al_color_xyz_to_rgb], [al_color_rgb_to_xyz] + + +## API: al_color_xyz_to_rgb + +Convert XYZ color values to RGB color space. + +Since: 5.2.3 + +See also: [al_color_xyz], [al_color_rgb_to_xyz] + + +## API: al_color_rgb_to_xyy + +Convert RGB values to xyY color space. + +Since: 5.2.3 + +See also: [al_color_xyy], [al_color_xyy_to_rgb] + + +## API: al_color_xyy + +Return an [ALLEGRO_COLOR] structure from xyY values. The Y component +in the xyY color space is the same as the Y in XYZ. + +However the x and y values are computed from XYZ like this: + +~~~~c +x = X / (X + Y + Z) +y = Y / (X + Y + Z) +~~~~ + +Since: 5.2.3 + +See also: [al_color_xyy_to_rgb], [al_color_rgb_to_xyy] + + +## API: al_color_xyy_to_rgb + +Convert xyY color values to RGB color space. + +Since: 5.2.3 + +See also: [al_color_xyy], [al_color_rgb_to_xyy] + + +## API: al_color_rgb_to_lab + +Convert RGB values to L\*a\*b\* color space. + +Since: 5.2.3 + +See also: [al_color_lab], [al_color_lab_to_rgb] + + +## API: al_color_lab + +Return an [ALLEGRO_COLOR] structure from CIE L\*a\*b\* values. The L\* +component corresponds to luminance from 0..1. The a\* and b\* components +are in the range -1..+1. + +> *Note:* +> +> The L\*a\*b\* color space can represent more colors than are +> visible in sRGB and therefore conversion may result in RGB values +> outside of the 0..1 range. You can check for that case with +> [al_is_color_valid]. + +> *Note:* +> +> In some literature the range of L* is 0 to 100 and a* and b* are from +> -100 to +100. In that case divide all components by 100 before passing +> them to this function. + +Since: 5.2.3 + +See also: [al_color_lab_to_rgb], [al_color_rgb_to_lab] + + +## API: al_color_lab_to_rgb + +Convert CIE L\*a\*b\* color values to RGB color space. + +Since: 5.2.3 + +See also: [al_color_lab], [al_color_rgb_to_lab] + + +## API: al_color_rgb_to_lch + +Convert RGB values to CIE LCH color space. + +Since: 5.2.3 + +See also: [al_color_lch], [al_color_lch_to_rgb] + + +## API: al_color_lch + +Return an [ALLEGRO_COLOR] structure from CIE LCH values. LCH colors are +very similar to HSL, with the same meaning of L and H and C +corresponding to S. However LCH is more visually uniform. Furthermore, +this function expects the angle for H in radians and not in degree. + +The CIE LCH color space is a cylindrical representation of the L\*a\*b\* +color space. The L component is the same and C and H are computed like +this: + +~~~~c +C = sqrt(a * a + b * b) +H = atan2(b, a) +~~~~ + +Since: 5.2.3 + +See also: [al_color_lch_to_rgb], [al_color_rgb_to_lch] + + +## API: al_color_lch_to_rgb + +Convert CIE LCH color values to RGB color space. + +Since: 5.2.3 + +See also: [al_color_lch], [al_color_rgb_to_lch] + + +## API: al_color_distance_ciede2000 + +This function computes the CIEDE2000 color difference between two +RGB colors. This is a visually uniform color difference, unlike for +example the RGB distance. + +When using the RGB distance (Euklidean distance between two RGB +triplets) there can be color pairs with the same distance, where the +colors of one pair appear to be almost the same color, while the colors +of the other pair look quite different. This is improved by using the +L\*a\*b\* color space which was designed with perceptual uniformity in +mind. However it still is not completely uniform. The CIEDE2000 +formula contains some additional transformations to fix that. + +The returned color distance is roughly in the range 0 (identical +color) to 1 (completely different color) - but values greater than one +are possible. + +> Note: This function uses [al_color_lab] internally which +> defines the L component to be in the range 0..1 (and not 0..100 as is +> sometimes seen). + +Since: 5.2.3 + +## API: al_color_rgb_to_yuv + +Convert RGB values to YUV color space. + +See also: [al_color_yuv], [al_color_yuv_to_rgb] + + +## API: al_color_yuv + +Return an [ALLEGRO_COLOR] structure from YUV values. + +See also: [al_color_yuv_to_rgb], [al_color_rgb_to_yuv] + + +## API: al_color_yuv_to_rgb + +Convert YUV color values to RGB color space. + +See also: [al_color_yuv], [al_color_rgb_to_yuv] + + +## API: al_get_allegro_color_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. + + +## API: al_is_color_valid + +Checks if all components of the color are between 0 and 1. Some of the +color conversions in this addon support color spaces with more colors +than can be represented in sRGB and when converted to RGB will result +in invalid color components outside the 0..1 range. + +Since: 5.2.3 diff --git a/allegro/docs/src/refman/config.txt b/allegro/docs/src/refman/config.txt new file mode 100644 index 00000000..bf8d1279 --- /dev/null +++ b/allegro/docs/src/refman/config.txt @@ -0,0 +1,232 @@ +# Configuration files + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +Allegro supports reading and writing of configuration files with a +simple, INI file-like format. + +A configuration file consists of key-value pairs separated by newlines. +Keys are separated from values by an equals sign (`=`). All whitespace +before the key, after the value and immediately adjacent to the equals +sign is ignored. Keys and values may have whitespace characters within +them. Keys do not need to be unique, but all but the last one are ignored. + +The hash (`#`) character is used a comment when it is the first +non-whitespace character on the line. All characters following that +character are ignored to the end of the line. The hash character anywhere +else on the line has no special significance. + +Key-value pairs can be optionally grouped into sections, which are +declared by surrounding a section name with square brackets (`[` and `]`) on +a single line. Whitespace before the opening bracket is ignored. All +characters after the trailing bracket are also ignored. + +All key-value pairs that follow a section declaration belong to the last +declared section. Key-value pairs that don't follow any section +declarations belong to the global section. Sections do not nest. + +Here is an example configuration file: + +~~~ini +## Monster description +monster name = Allegro Developer + +[weapon 0] +damage = 443 + +[weapon 1] +damage = 503 +~~~~ + +It can then be accessed like this (make sure to check for errors in +an actual program): + +~~~~c +ALLEGRO_CONFIG* cfg = al_load_config_file("test.cfg"); +printf("%s\n", al_get_config_value(cfg, "", "monster name")); /* Prints: Allegro Developer */ +printf("%s\n", al_get_config_value(cfg, "weapon 0", "damage")); /* Prints: 443 */ +printf("%s\n", al_get_config_value(cfg, "weapon 1", "damage")); /* Prints: 503 */ +al_destroy_config(cfg); +~~~~ + +## API: ALLEGRO_CONFIG + +An abstract configuration structure. + +## API: ALLEGRO_CONFIG_SECTION + +An opaque structure used for iterating across sections in a configuration +structure. + +See also: [al_get_first_config_section], [al_get_next_config_section] + +## API: ALLEGRO_CONFIG_ENTRY + +An opaque structure used for iterating across entries in a configuration +section. + +See also: [al_get_first_config_entry], [al_get_next_config_entry] + +## API: al_create_config + +Create an empty configuration structure. + +See also: [al_load_config_file], [al_destroy_config] + +## API: al_destroy_config + +Free the resources used by a configuration structure. +Does nothing if passed NULL. + +See also: [al_create_config], [al_load_config_file] + +## API: al_load_config_file + +Read a configuration file from disk. +Returns NULL on error. The configuration structure should be destroyed +with [al_destroy_config]. + +See also: [al_load_config_file_f], [al_save_config_file] + +## API: al_load_config_file_f + +Read a configuration file from an already open file. + +Returns NULL on error. The configuration structure should be destroyed +with [al_destroy_config]. The file remains open afterwards. + +See also: [al_load_config_file] + +## API: al_save_config_file + +Write out a configuration file to disk. +Returns true on success, false on error. + +See also: [al_save_config_file_f], [al_load_config_file] + +## API: al_save_config_file_f + +Write out a configuration file to an already open file. + +Returns true on success, false on error. +The file remains open afterwards. + +See also: [al_save_config_file] + +## API: al_add_config_section + +Add a section to a configuration structure with the given name. +If the section already exists then nothing happens. + +## API: al_remove_config_section + +Remove a section of a configuration. + +Returns true if the section was removed, or false if the section did not +exist. + +Since: 5.1.5 + +## API: al_add_config_comment + +Add a comment in a section of a configuration. If the section doesn't yet +exist, it will be created. +The section can be NULL or "" for the global section. + +The comment may or may not begin with a hash character. +Any newlines in the comment string will be replaced by space characters. + +See also: [al_add_config_section] + +## API: al_get_config_value + +Gets a pointer to an internal character buffer that will only remain valid +as long as the ALLEGRO_CONFIG structure is not destroyed. Copy the value +if you need a copy. +The section can be NULL or "" for the global section. +Returns NULL if the section or key do not exist. + +See also: [al_set_config_value] + +## API: al_set_config_value + +Set a value in a section of a configuration. If the section doesn't yet +exist, it will be created. If a value already existed for the given key, +it will be overwritten. +The section can be NULL or "" for the global section. + +For consistency with the on-disk format of config files, any leading and +trailing whitespace will be stripped from the value. If you have significant +whitespace you wish to preserve, you should add your own quote characters +and remove them when reading the values back in. + +See also: [al_get_config_value] + +## API: al_remove_config_key + +Remove a key and its associated value in a section of a configuration. + +Returns true if the entry was removed, or false if the entry did not exist. + +Since: 5.1.5 + +## API: al_get_first_config_section + +Returns the name of the first section in the given config file. Usually +this will return an empty string for the global section, even it contains no +values. The `iterator` parameter will receive an opaque iterator which is used +by [al_get_next_config_section] to iterate over the remaining sections. + +The returned string and the iterator are only valid as long as no +change is made to the passed ALLEGRO_CONFIG. + +See also: [al_get_next_config_section] + +## API: al_get_next_config_section + +Returns the name of the next section in the given config file or NULL if +there are no more sections. The `iterator` must have been obtained with +[al_get_first_config_section] first. + +See also: [al_get_first_config_section] + +## API: al_get_first_config_entry + +Returns the name of the first key in the given section in the given +config or NULL if the section is empty. The `iterator` works like the one for +[al_get_first_config_section]. + +The returned string and the iterator are only valid as long as no +change is made to the passed [ALLEGRO_CONFIG]. + +See also: [al_get_next_config_entry] + +## API: al_get_next_config_entry + +Returns the next key for the iterator obtained by +[al_get_first_config_entry]. The `iterator` works like the one for +[al_get_next_config_section]. + +## API: al_merge_config + +Merge two configuration structures, and return the result as a new +configuration. Values in configuration 'cfg2' override those in 'cfg1'. +Neither of the input configuration structures are +modified. +Comments from 'cfg2' are not retained. + +See also: [al_merge_config_into] + +## API: al_merge_config_into + +Merge one configuration structure into another. +Values in configuration 'add' override those in 'master'. +'master' is modified. +Comments from 'add' are not retained. + +See also: [al_merge_config] + diff --git a/allegro/docs/src/refman/direct3d.txt b/allegro/docs/src/refman/direct3d.txt new file mode 100644 index 00000000..d13a2ab6 --- /dev/null +++ b/allegro/docs/src/refman/direct3d.txt @@ -0,0 +1,101 @@ +# Direct3D integration + +These functions are declared in the following header file: + +~~~~c + #include +~~~~ + +## API: al_get_d3d_device + +Returns the Direct3D device of the display. The return value is +undefined if the display was not created with the Direct3D flag. + +*Returns:* +A pointer to the Direct3D device. + +## API: al_get_d3d_system_texture + +Returns the system texture (stored with the D3DPOOL_SYSTEMMEM flags). This +texture is used for the render-to-texture feature set. + +*Returns:* +A pointer to the Direct3D system texture. + +## API: al_get_d3d_video_texture + +Returns the video texture (stored with the D3DPOOL_DEFAULT or D3DPOOL_MANAGED +flags depending on whether render-to-texture is enabled or disabled +respectively). + +*Returns:* +A pointer to the Direct3D video texture. + +## API: al_have_d3d_non_pow2_texture_support + +Returns whether the Direct3D device supports textures whose dimensions are not +powers of two. + +*Returns:* +True if device supports NPOT textures, false otherwise. + +## API: al_have_d3d_non_square_texture_support + +Returns whether the Direct3D device supports textures that are not square. + +*Returns:* +True if the Direct3D device supports non-square textures, false otherwise. + +## API: al_get_d3d_texture_size + +Retrieves the size of the Direct3D texture used for the bitmap. + +Returns true on success, false on failure. +Zero width and height are returned if the bitmap is not a Direct3D bitmap. + +Since: 5.1.0 + +See also: [al_get_d3d_texture_position] + +## API: al_get_d3d_texture_position + +Returns the u/v coordinates for the top/left corner of the bitmap within the +used texture, in pixels. + +*Parameters:* + +* bitmap - ALLEGRO_BITMAP to examine +* u - Will hold the returned u coordinate +* v - Will hold the returned v coordinate + +See also: [al_get_d3d_texture_size] + +## API: al_is_d3d_device_lost + +Returns a boolean indicating whether or not the Direct3D device +belonging to the given display is in a lost state. + +*Parameters:* + +* display - The display that the device you wish to check is attached to + +## API: al_set_d3d_device_release_callback + +The callback will be called whenever a D3D device is reset (minimize, toggle +fullscreen window, etc). In the callback you should release any d3d +resources you have created yourself. The callback receives the affected +display as a parameter. + +Pass NULL to disable the callback. + +Since: 5.1.0 + +## API: al_set_d3d_device_restore_callback + +The callback will be called whenever a D3D device that has been reset is +restored. In the callback you should restore any d3d resources you have +created yourself. The callback receives the affected display as a parameter. + +Pass NULL to disable the callback. + +Since: 5.1.0 diff --git a/allegro/docs/src/refman/display.txt b/allegro/docs/src/refman/display.txt new file mode 100644 index 00000000..b0c36c67 --- /dev/null +++ b/allegro/docs/src/refman/display.txt @@ -0,0 +1,818 @@ +# Displays + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +All drawing operations end up being visible on a display which is the same as +a window in windowed environments. Thus, before anything is displayed, +a display needs to be created. + +Before creating a display with [al_create_display], flags and options can be set +with [al_set_new_display_flags] and [al_set_new_display_option]. For example, you +can enable the use of shaders or choose between the OpenGL and Direct3D backends +(on platforms that support both) with [al_set_new_display_flags]. Display options +are rather optional settings that do not affect Allegro itself, e.g. they allow +you to specify whether you want a depth buffer or enable multisampling. + +The actual properties of a display that has been successfully created can be queried +via [al_get_display_option], [al_get_display_flags], [al_get_display_width] etc. +Note that you can query some additional read-only properties such as the maximum +allowed bitmap (i.e. texture) size via [al_get_display_option]. + +Each display has a backbuffer associated to it which is the default target for any +drawing operations. In order to make visible what has been drawn previously, you +have to to call [al_flip_display]. Note that it is generally advisable to redraw +the whole screen (or [clear][al_clear_to_color] it in advance) to avoid artefacts +of uninitialised memory becoming visible with some drivers. + +You don't have to use Allegro's drawing routines, however: since creating a display +implies the creation of an OpenGL context or Direct3D device respectively, you can +use these APIs directly if you prefer to do so. Allegro provides integration for +both (see the OpenGL / Direct3D sections), so you can retrieve the underlying +textures of [ALLEGRO_BITMAP]s, for example. + +In order to write a well-behaved application, it is necessary to remember that +displays will also inform you about important [events][ALLEGRO_EVENT_DISPLAY_EXPOSE] +via their [event sources][al_get_display_event_source]. + +## Display creation + +### API: ALLEGRO_DISPLAY + +An opaque type representing an open display or window. + +### API: al_create_display + +Create a display, or window, with the specified dimensions. +The parameters of the display are determined by the last calls to +al_set_new_display\_\*. Default parameters are used if none are set +explicitly. +Creating a new display will automatically make it the active one, with the +backbuffer selected for drawing. + +Returns NULL on error. + +Each display that uses OpenGL as a backend has a distinct OpenGL rendering context +associated with it. See [al_set_target_bitmap] for the discussion about rendering contexts. + +See also: [al_set_new_display_flags], [al_set_new_display_option], +[al_set_new_display_refresh_rate], [al_set_new_display_adapter], [al_set_new_window_title] +[al_set_window_position] + +### API: al_destroy_display + +Destroy a display. + +If the target bitmap of the calling thread is tied to the display, then it +implies a call to "al_set_target_bitmap(NULL);" before the display is +destroyed. + +That special case notwithstanding, you should make sure no threads are +currently targeting a bitmap which is tied to the display before you destroy +it. + +See also: [al_set_target_bitmap] + +### API: al_get_new_display_flags + +Get the display flags to be used when creating new displays on the calling +thread. + +See also: [al_set_new_display_flags], [al_set_display_flag] + +### API: al_set_new_display_flags + +Sets various flags to be used when creating new displays on the calling thread. +flags is a bitfield containing any reasonable combination of the following: + +ALLEGRO_WINDOWED +: Prefer a windowed mode. + + Under multi-head X (not XRandR/TwinView), the use of more than one adapter is + impossible due to bugs in X and GLX. [al_create_display] will fail if more than one + adapter is attempted to be used. + +ALLEGRO_FULLSCREEN_WINDOW +: Make the window span the entire screen. Unlike ALLEGRO_FULLSCREEN this + will never attempt to modify the screen resolution. Instead the pixel + dimensions of the created display will be the same as the desktop. + + The passed width and height are only used if the window is switched + out of fullscreen mode later but will be ignored initially. + + Under Windows and X11 a fullscreen display created with this flag + will behave differently from one created with the ALLEGRO_FULLSCREEN + flag - even if the ALLEGRO_FULLSCREEN display is passed the desktop + dimensions. The exact difference is platform dependent, but some + things which may be different is how alt-tab works, how fast you can + toggle between fullscreen/windowed mode or how additional monitors + behave while your display is in fullscreen mode. + + Additionally under X, the use of more than one adapter in multi-head mode + or with true Xinerama enabled is impossible due to bugs in X/GLX, + creation will fail if more than one adapter is attempted to be used. + +ALLEGRO_FULLSCREEN +: Prefer a fullscreen mode. + + Under X the use of more than one FULLSCREEN display when using multi-head X, + or true Xinerama is not possible due to bugs in X and GLX, + display creation will fail if more than one adapter is attempted to be used. + + > *Note:* Prefer using ALLEGRO_FULLSCREEN_WINDOW as it typically provides a + better user experience as the monitor doesn't change resolution and + switching away from your game via Alt-Tab works smoothly. + ALLEGRO_FULLSCREEN is typically less well supported compared to + ALLEGRO_FULLSCREEN_WINDOW. + +ALLEGRO_RESIZABLE +: The display is resizable (only applicable if combined with + ALLEGRO_WINDOWED). + +ALLEGRO_MAXIMIZED +: The display window will be maximized (only applicable if combined + with ALLEGRO_RESIZABLE). + Since: 5.1.12 + +ALLEGRO_OPENGL +: Require the driver to provide an initialized OpenGL context after returning + successfully. + +ALLEGRO_OPENGL_3_0 +: Require the driver to provide an initialized OpenGL + context compatible with OpenGL version 3.0. + +ALLEGRO_OPENGL_FORWARD_COMPATIBLE +: If this flag is set, the OpenGL + context created with ALLEGRO_OPENGL_3_0 will be forward compatible *only*, + meaning that all of the OpenGL API declared deprecated in OpenGL 3.0 will not + be supported. Currently, a display created with this flag will *not* be + compatible with Allegro drawing routines; the display option + ALLEGRO_COMPATIBLE_DISPLAY will be set to false. + +ALLEGRO_OPENGL_ES_PROFILE +: Used together with ALLEGRO_OPENGL, requests that the OpenGL context + uses the OpenGL ES profile. A specific version can be requested + with [al_set_new_display_option]. + Note: Currently this is only supported by the X11/GLX driver. + Since: 5.1.13 + +ALLEGRO_OPENGL_CORE_PROFILE +: Used together with ALLEGRO_OPENGL, requests that the OpenGL context + uses the OpenGL Core profile. A specific version can be requested + with [al_set_new_display_option]. + Note: Currently this is only supported by the X11/GLX driver. + Since: 5.2.7 + +ALLEGRO_DIRECT3D +: Require the driver to do rendering with Direct3D and + provide a Direct3D device. + +ALLEGRO_PROGRAMMABLE_PIPELINE +: Require a programmable graphics pipeline. + This flag is required to use [ALLEGRO_SHADER] objects. + Since: 5.1.6 + +ALLEGRO_FRAMELESS +: Try to create a window without a frame (i.e. no border or titlebar). + This usually does nothing for fullscreen modes, and even in windowed modes + it depends on the underlying platform whether it is supported or not. + Since: 5.0.7, 5.1.2 + +ALLEGRO_NOFRAME +: Original name for ALLEGRO_FRAMELESS. + This works with older versions of Allegro. + +ALLEGRO_GENERATE_EXPOSE_EVENTS +: Let the display generate expose events. + +ALLEGRO_GTK_TOPLEVEL +: Create a GTK toplevel window for the display, on X. + This flag is conditionally defined by the native dialog addon. + You must call [al_init_native_dialog_addon] for it to succeed. + ALLEGRO_GTK_TOPLEVEL is incompatible with ALLEGRO_FULLSCREEN. + Since: 5.1.5 + +0 can be used for default values. + +See also: [al_set_new_display_option], [al_get_display_option], [al_set_display_option] + +### API: al_get_new_display_option + +Retrieve an extra display setting which was previously set with +[al_set_new_display_option]. + +### API: al_set_new_display_option + +Set an extra display option, to be used when creating new displays on the +calling thread. Display options differ from display flags, and specify some +details of the context to be created within the window itself. +These mainly have no effect on Allegro itself, but you may want to specify +them, for example if you want to use multisampling. + +The 'importance' parameter can be either: + +* ALLEGRO_REQUIRE - The display will not be created if the setting can + not be met. +* ALLEGRO_SUGGEST - If the setting is not available, the display will + be created anyway with a setting as close as possible to the + requested one. + You can query the actual value used in that case by calling + [al_get_display_option] after the display has been created. +* ALLEGRO_DONTCARE - If you added a display option with one of the above + two settings before, it will be removed again. Else this does + nothing. + +The supported options are: + +ALLEGRO_COLOR_SIZE +: This can be used to ask for a specific bit depth. For example to + force a 16-bit framebuffer set this to 16. + +ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE, ALLEGRO_ALPHA_SIZE +: Individual color component size in bits. + +ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT, ALLEGRO_BLUE_SHIFT, ALLEGRO_ALPHA_SHIFT +: Together with the previous settings these can be used to specify the + exact pixel layout the display should use. Normally there is no reason to use these. + +ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE, ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE +: This can be used to define the required accumulation buffer size. + +ALLEGRO_STEREO +: Whether the display is a stereo display. + +ALLEGRO_AUX_BUFFERS +: Number of auxiliary buffers the display should + have. + +ALLEGRO_DEPTH_SIZE +: How many depth buffer (z-buffer) bits to use. + +ALLEGRO_STENCIL_SIZE +: How many bits to use for the stencil buffer. + +ALLEGRO_SAMPLE_BUFFERS +: Whether to use multisampling (1) or not (0). + +ALLEGRO_SAMPLES +: If the above is 1, the number of samples to use + per pixel. Else 0. + +ALLEGRO_RENDER_METHOD: +: 0 if hardware acceleration is not used with this display. + +ALLEGRO_FLOAT_COLOR +: Whether to use floating point color components. + +ALLEGRO_FLOAT_DEPTH +: Whether to use a floating point depth buffer. + +ALLEGRO_SINGLE_BUFFER +: Whether the display uses a single buffer (1) + or another update method (0). + +ALLEGRO_SWAP_METHOD +: If the above is 0, this is set to 1 to indicate + the display is using a copying method to make the next buffer in + the flip chain available, or to 2 to indicate a flipping or other + method. + +ALLEGRO_COMPATIBLE_DISPLAY +: Indicates if Allegro's graphics + functions can use this display. If you request a display not + useable by Allegro, you can still use for example OpenGL to draw + graphics. + +ALLEGRO_UPDATE_DISPLAY_REGION +: Set to 1 if the display is + capable of updating just a region, and 0 if calling + [al_update_display_region] is equivalent to [al_flip_display]. + +ALLEGRO_VSYNC +: Set to 1 to tell the driver to wait for vsync + in [al_flip_display], or to 2 to force vsync off. The default of + 0 means that Allegro does not try to modify the vsync behavior so + it may be on or off. + Note that even in the case of 1 or 2 it is possible to override + the vsync behavior in the graphics driver so you should not rely + on it. + +ALLEGRO_MAX_BITMAP_SIZE +: When queried this returns the maximum + size (width as well as height) a bitmap can have for this + display. Calls to [al_create_bitmap] or [al_load_bitmap] for + bitmaps larger than this size will fail. It does not apply to memory + bitmaps which always can have arbitrary size (but are slow for + drawing). + +ALLEGRO_SUPPORT_NPOT_BITMAP +: Set to 1 if textures used for bitmaps + on this display can have a size which is not a power of two. This + is mostly useful if you use Allegro to load textures as otherwise + only power-of-two textures will be used internally as bitmap + storage. + +ALLEGRO_CAN_DRAW_INTO_BITMAP +: Set to 1 if you can use + [al_set_target_bitmap] on bitmaps of this display to draw into them. + If this is not the case software emulation will be used when drawing + into display bitmaps (which can be very slow). + +ALLEGRO_SUPPORT_SEPARATE_ALPHA +: This is set to 1 if the + [al_set_separate_blender] function is supported. Otherwise the + alpha parameters will be ignored. + +ALLEGRO_AUTO_CONVERT_BITMAPS +: This is on by default. It causes any + existing memory bitmaps with the ALLEGRO_CONVERT_BITMAP flag to be + converted to a display bitmap of the newly created display with + the option set. + + Since: 5.1.0 + +ALLEGRO_SUPPORTED_ORIENTATIONS +: This is a bit-combination of the + orientations supported by the application. The orientations are + the same as for [al_get_display_orientation] with the additional + possibilities: + + * ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT + * ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE + * ALLEGRO_DISPLAY_ORIENTATION_ALL + + PORTRAIT means only the two portrait orientations are supported, + LANDSCAPE means only the two landscape orientations and ALL allows + all four orientations. When the orientation changes between a + portrait and a landscape orientation the display needs to be + resized. This is done by sending an [ALLEGRO_EVENT_DISPLAY_RESIZE] + message which should be handled by calling [al_acknowledge_resize]. + + Since: 5.1.0 + +ALLEGRO_OPENGL_MAJOR_VERSION +: Request a specific OpenGL major version. + + Since: 5.1.13 + +ALLEGRO_OPENGL_MINOR_VERSION +: Request a specific OpenGL minor version. + + Since: 5.1.13 + + + +See also: [al_set_new_display_flags], [al_get_display_option] + +### API: al_reset_new_display_options + +This undoes any previous call to [al_set_new_display_option] +on the calling thread. + +### API: al_get_new_window_position + +Get the position where new non-fullscreen displays created by the calling +thread will be placed. + +See also: [al_set_new_window_position] + +### API: al_set_new_window_position + +Sets where the top left pixel of the client area of newly +created windows (non-fullscreen) will be on screen, +for displays created by the calling thread. +Negative values are allowed on some multihead systems. + +To reset to the default behaviour, pass (INT_MAX, INT_MAX). + +See also: [al_get_new_window_position] + +### API: al_get_new_display_refresh_rate + +Get the requested refresh rate to be used when creating new displays on the +calling thread. + +See also: [al_set_new_display_refresh_rate] + +### API: al_set_new_display_refresh_rate + +Sets the refresh rate to use when creating new displays on the calling thread. +If the refresh rate is not available, [al_create_display] will fail. +A list of modes with refresh rates can be found with [al_get_num_display_modes] +and [al_get_display_mode]. + +The default setting is zero (don't care). + +See also: [al_get_new_display_refresh_rate] + + + +## Display operations + +### API: al_get_display_event_source + +Retrieve the associated event source. See the +[documentation on events][ALLEGRO_EVENT_DISPLAY_EXPOSE] +for a list of the events displays will generate. + +### API: al_get_backbuffer + +Return a special bitmap representing the back-buffer of the +display. + +Care should be taken when using the backbuffer bitmap (and its +sub-bitmaps) as the source bitmap (e.g as the bitmap argument to +[al_draw_bitmap]). Only untransformed operations are hardware +accelerated. These consist of [al_draw_bitmap] and +[al_draw_bitmap_region] when the current transformation is the identity. +If the transformation is not the identity, or some other drawing +operation is used, the call will be routed through the memory bitmap +routines, which are slow. If you need those operations to be accelerated, +then first copy a region of the backbuffer into a temporary bitmap (via +the [al_draw_bitmap] and [al_draw_bitmap_region]), and then use that +temporary bitmap as the source bitmap. + +### API: al_flip_display + +Copies or updates the front and back buffers so that what has +been drawn previously on the currently selected display becomes +visible on screen. Pointers to the special back buffer +bitmap remain valid and retain their semantics as the back buffer, +although the contents may have changed. + +> *Note:* If not using the ALLEGRO_SINGLE_BUFFER option, you typically want to +redraw every pixel of the backbuffer bitmap to avoid uninitialized memory +artifacts. + +Several display options change how this function behaves: + +- With ALLEGRO_SINGLE_BUFFER, no flipping is done. You still have to +call this function to display graphics, depending on how the used +graphics system works. + +- The ALLEGRO_SWAP_METHOD option may have additional information about what +kind of operation is used internally to flip the front and back buffers. + +- If ALLEGRO_VSYNC is 1, this function will force waiting for vsync. If +ALLEGRO_VSYNC is 2, this function will not wait for vsync. With many +drivers the vsync behavior is controlled by the user and not the +application, and ALLEGRO_VSYNC will not be set; in this case +[al_flip_display] will wait for vsync depending on the settings set +in the system's graphics preferences. + +See also: [al_set_new_display_flags], [al_set_new_display_option] + +### API: al_update_display_region + +Does the same as [al_flip_display], but tries to update only the +specified region. With many drivers this is not possible, but for +some it can improve performance. If this is not supported, this function falls +back to the behavior of [al_flip_display]. You can query the support for this +function using `al_get_display_option(display, ALLEGRO_UPDATE_DISPLAY_REGION)`. + +See also: [al_flip_display], [al_get_display_option] + +### API: al_wait_for_vsync + +Wait for the beginning of a vertical retrace. Some +driver/card/monitor combinations may not be capable +of this. + +Note how [al_flip_display] usually already waits for the vertical +retrace, so unless you are doing something special, there is no reason +to call this function. + +Returns false if not possible, true if successful. + +See also: [al_flip_display] + + + +## Display size and position + +### API: al_get_display_width + +Gets the width of the display. This is like SCREEN_W in Allegro 4.x. + +See also: [al_get_display_height] + +### API: al_get_display_height + +Gets the height of the display. This is like SCREEN_H in Allegro 4.x. + +See also: [al_get_display_width] + +### API: al_resize_display + +Resize the display. Returns true on success, or false on error. +This works on both fullscreen and windowed displays, regardless of the +ALLEGRO_RESIZABLE flag. + +Adjusts the clipping rectangle to the full size of the backbuffer. + +See also: [al_acknowledge_resize] + +### API: al_acknowledge_resize + +When the user receives a [resize event][ALLEGRO_EVENT_DISPLAY_RESIZE] +from a resizable display, if they wish the display to be resized they +must call this function to let the graphics driver know that it can now +resize the display. Returns true on success. + +Adjusts the clipping rectangle to the full size of the backbuffer. This also +resets the backbuffers projection transform to default orthographic transform +(see [al_use_projection_transform]). + +Note that a resize event may be outdated by the time you acknowledge it; +there could be further resize events generated in the meantime. + +See also: [al_resize_display], [ALLEGRO_EVENT] + +### API: al_get_window_position + +Gets the position of a non-fullscreen display. + +See also: [al_set_window_position] + +### API: al_set_window_position + +Sets the position on screen of a non-fullscreen display. + +See also: [al_get_window_position] + +### API: al_get_window_constraints + +Gets the constraints for a non-fullscreen resizable display. + +Since: 5.1.0 + +See also: [al_set_window_constraints] + +### API: al_set_window_constraints + +Constrains a non-fullscreen resizable display. +The constraints are a hint only, and are not necessarily respected +by the window environment. +A value of 0 for any of the parameters indicates no constraint +for that parameter. + +The constraints will be applied to a display only after the +[al_apply_window_constraints] function call. + +Since: 5.1.0 + +See also: [al_apply_window_constraints], [al_get_window_constraints] + +### API: al_apply_window_constraints + +Enable or disable previously set constraints by +[al_set_window_constraints] function. + +If enabled, the specified display will be automatically resized +to new sizes to conform constraints in next cases: + +* The specified display is resizable, not maximized and is not + in fullscreen mode. +* If the appropriate current display size (width or height) is less + than the value of constraint. Applied to minimum constraints. +* If the appropriate current display size (width or height) is greater + than the value of constraint. Applied to maximum constraints. + +Constrains are not applied when a display is toggle from +windowed to maximized or fullscreen modes. +When a display is toggle from maximized/fullscreen to windowed +mode, then the display may be resized as described above. +The later case is also possible when a user drags the maximized +display via mouse. + +If disabled, the specified display will stop using constraints. + +See also: [al_get_window_constraints], [al_set_window_constraints] + + + +## Display settings + +### API: al_get_display_flags + +Gets the flags of the display. + +In addition to the flags set for the display at creation time with +[al_set_new_display_flags] it can also have the ALLEGRO_MINIMIZED flag +set, indicating that the window is currently minimized. This flag +is very platform-dependent as even a minimized application may still +render a preview version so normally you should not care whether it +is minimized or not. + +See also: [al_set_new_display_flags], [al_set_display_flag] + +### API: al_set_display_flag + +Enable or disable one of the display flags. The flags are the same +as for [al_set_new_display_flags]. The only flags that can be changed +after creation are: + +- ALLEGRO_FULLSCREEN_WINDOW +- ALLEGRO_FRAMELESS +- ALLEGRO_MAXIMIZED + +Returns true if the driver supports toggling the specified flag else +false. You can use [al_get_display_flags] to query whether the given +display property actually changed. + +Since: 5.0.7, 5.1.2 + +See also: [al_set_new_display_flags], [al_get_display_flags] + +### API: al_get_display_option + +Return an extra display setting of the display. + +See also: [al_set_new_display_option] + +### API: al_set_display_option + +Change an option that was previously set for a display. After displays are +created, they take on the options set with [al_set_new_display_option]. Calling +[al_set_new_display_option] subsequently only changes options for newly created +displays, and doesn't touch the options of already created displays. +[al_set_display_option] allows changing some of these values. Not all +display options can be changed or changing them will have no effect. Changing +options other than those listed below is undefined. + +* ALLEGRO_SUPPORTED_ORIENTATIONS - This can be changed to allow new or restrict + previously enabled orientations of the screen/device. See + [al_set_new_display_option] for more information on this option. + +Since: 5.1.5 + +See also: [al_set_new_display_option] + +### API: al_get_display_format + +Gets the pixel format of the display. + +See also: [ALLEGRO_PIXEL_FORMAT] + +### API: al_get_display_orientation + +Return the display orientation, which can be one of the following: + +- ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN +- ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES +- ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES +- ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES +- ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES +- ALLEGRO_DISPLAY_ORIENTATION_FACE_UP +- ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN + +Since: 5.1.0 + +### API: al_get_display_refresh_rate + +Gets the refresh rate of the display. + +See also: [al_set_new_display_refresh_rate] + +### API: al_set_window_title + +Set the title on a display. + +See also: [al_set_display_icon], [al_set_display_icons] + + +### API: al_set_new_window_title + +Set the title that will be used when a new display is created. +Allegro uses a static buffer of [ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE] to +store this, so the length of the titme you set must be less than this. + +See also: [al_set_window_title], [al_get_new_window_title], [al_create_display], + [ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE] + +Since: 5.1.12 + +### API: ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE + +This is the maximum size of the title that can be set with +[al_set_new_window_title]. + +See also: [al_set_new_window_title] + +Since: 5.1.12 + +### API: al_get_new_window_title + +Returns the title that will be used when a new display is created. This +returns the value that [al_set_window_title] was called with. If that function +wasn't called yet, the value of [al_get_app_name] is returned as a default. +The current implementation returns a pointer to a static buffer of which you +should make a copy if you want to modify it. + +See also: [al_set_window_title], [al_set_new_window_title], [al_create_display] + +Since: 5.1.12 + + +### API: al_set_display_icon + +Changes the icon associated with the display (window). +Same as [al_set_display_icons] with one icon. + +See also: [al_set_display_icons], [al_set_window_title] + +### API: al_set_display_icons + +Changes the icons associated with the display (window). +Multiple icons can be provided for use in different contexts, e.g. window +frame, taskbar, alt-tab popup. The number of icons must be at least one. + +> *Note:* If the underlying OS requires an icon of a size not provided +then one of the bitmaps will be scaled up or down to the required size. +The choice of bitmap is implementation dependent. + +Since: 5.0.9, 5.1.5 + +See also: [al_set_display_icon], [al_set_window_title] + + + +## Drawing halts + +### API: al_acknowledge_drawing_halt + +Call this in response to the [ALLEGRO_EVENT_DISPLAY_HALT_DRAWING] event. +This is currently necessary for Android and iOS as you are not allowed to draw +to your display while it is not being shown. If you do not call this +function to let the operating system know that you have stopped +drawing or if you call it to late the application likely will be +considered misbehaving and get terminated. + +Since: 5.1.0 + +See also: [ALLEGRO_EVENT_DISPLAY_HALT_DRAWING] + +### API: al_acknowledge_drawing_resume + +Call this in response to the [ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING] event. + +Since: 5.1.1 + +See also: [ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING] + +## Screensaver + +### API: al_inhibit_screensaver + +This function allows the user to stop the system +screensaver from starting up if true is passed, +or resets the system back to the default state +(the state at program start) if false is passed. +It returns true if the state was set successfully, +otherwise false. + + + +## Clipboard + +With the clipboard API of Allegro, text can be copied from and to the clipboard. +Currentlly, only UTF8 encoded text is supported. It currently works on Linux, +Windows, OSX, Android and IOS. + + +### API: al_get_clipboard_text + +This function returns a pointer to a string, allocated with [al_malloc] with +the text contents of the clipboard if available. If no text is available on the +clipboard then this function returns NULL. You must call [al_free] on the +returned pointer when you don't need it anymore. + +Beware that text on the clipboard on Windows may be in Windows format, that is, +it may have carriage return newline combinations for the line endings instead +of regular newlines for the line endings on Linux or OSX. + +Since: 5.1.12 + +See also: [al_set_clipboard_text], [al_clipboard_has_text] + +### API: al_set_clipboard_text + +This function pastes the text given as an argument to the clipboard. + +Since: 5.1.12 + +See also: [al_get_clipboard_text], [al_clipboard_has_text] + + +### API: al_clipboard_has_text + +This function returns true if and only if the clipboard has text available. + +Since: 5.1.12 + +See also: [al_set_clipboard_text], [al_get_clipboard_text] + diff --git a/allegro/docs/src/refman/events.txt b/allegro/docs/src/refman/events.txt new file mode 100644 index 00000000..ea6251f3 --- /dev/null +++ b/allegro/docs/src/refman/events.txt @@ -0,0 +1,910 @@ +# Event system and events + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +Events are generated by event sources. Most notably, each of the input +subsystems provides an event source, but also timers, displays, and audio +streams will generate events. + +Event sources are registered to event queues which aggregate events from +multiple sources. A single event source can also be registered to multiple +event queues. + +Event queues can then be queried for events. In particular, it is possible +to wait until events become available in order to save CPU time. You can combine +this with [timers][ALLEGRO_TIMER] to make your main-loop run at a specific speed +without wasting CPU time or missing events. + +In addition to the predefined event types, Allegro also allows for user-defined +events that can be generated by user-defined event sources. + +The appropriate reaction to an event is determined by examining the fields of +the [ALLEGRO_EVENT] union according to the event type. + +In addition to the events sent by Allegro core, there's also events send by the addons, +see [ALLEGRO_AUDIO_EVENT_TYPE] and [ALLEGRO_VIDEO_EVENT_TYPE]. + +## API: ALLEGRO_EVENT + +An ALLEGRO_EVENT is a union of all builtin event structures, i.e. it is an +object large enough to hold the data of any event type. All events +have the following fields in common: + +type (ALLEGRO_EVENT_TYPE) +: Indicates the type of event. + +any.source (ALLEGRO_EVENT_SOURCE *) +: The event source which generated the event. + +any.timestamp (double) +: When the event was generated. + +By examining the `type` field you can then access type-specific fields. The +`any.source` field tells you which event source generated that particular +event. The `any.timestamp` field tells you when the event was generated. The +time is referenced to the same starting point as [al_get_time]. + +Each event is of one of the following types, with the usable fields given. + +### ALLEGRO_EVENT_JOYSTICK_AXIS + +A joystick axis value changed. + +joystick.id (ALLEGRO_JOYSTICK *) +: The joystick which generated the event. This is not the same as the event + source `joystick.source`. + +joystick.stick (int) +: The stick number, counting from zero. + Axes on a joystick are grouped into "sticks". + +joystick.axis (int) +: The axis number on the stick, counting from zero. + +joystick.pos (float) +: The axis position, from -1.0 to +1.0. + +### ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN + +A joystick button was pressed. + +joystick.id (ALLEGRO_JOYSTICK *) +: The joystick which generated the event. + +joystick.button (int) +: The button which was pressed, counting from zero. + +### ALLEGRO_EVENT_JOYSTICK_BUTTON_UP + +A joystick button was released. + +joystick.id (ALLEGRO_JOYSTICK *) +: The joystick which generated the event. + +joystick.button (int) +: The button which was released, counting from zero. + +### ALLEGRO_EVENT_JOYSTICK_CONFIGURATION + +A joystick was plugged in or unplugged. +See [al_reconfigure_joysticks] for details. + +### ALLEGRO_EVENT_KEY_DOWN + +A keyboard key was pressed. + +keyboard.keycode (int) +: The code corresponding to the physical key which was pressed. + See the [Key codes] section for the list of ALLEGRO\_KEY\_\* constants. + +keyboard.display (ALLEGRO_DISPLAY *) +: The display which had keyboard focus when the event occurred. + +> *Note:* this event is about the physical keys being pressed on the keyboard. +Look for ALLEGRO_EVENT_KEY_CHAR events for character input. + +### ALLEGRO_EVENT_KEY_UP + +A keyboard key was released. + +keyboard.keycode (int) +: The code corresponding to the physical key which was released. + See the [Key codes] section for the list of ALLEGRO\_KEY\_\* constants. + +keyboard.display (ALLEGRO_DISPLAY *) +: The display which had keyboard focus when the event occurred. + +### ALLEGRO_EVENT_KEY_CHAR + +A character was typed on the keyboard, or a character was auto-repeated. + +keyboard.keycode (int) +: The code corresponding to the physical key which was last pressed. + See the [Key codes] section for the list of ALLEGRO\_KEY\_\* constants. + +keyboard.unichar (int) +: A Unicode code point (character). This *may* be zero or negative if the + event was generated for a non-visible "character", such as an arrow or + Function key. In that case you can act upon the `keycode` field. + + Some special keys will set the `unichar` field to their standard ASCII + values: Tab=9, Return=13, Escape=27. In addition if you press the Control + key together with A to Z the `unichar` field will have the values 1 to 26. + For example Ctrl-A will set `unichar` to 1 and Ctrl-H will set it to 8. + + As of Allegro 5.0.2 there are some inconsistencies in the treatment of + Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. + These can be worked around by checking the `keycode` field. + +keyboard.modifiers (unsigned) +: This is a bitfield of the modifier keys which were pressed when the event + occurred. See "Keyboard modifier flags" for the constants. + +keyboard.repeat (bool) +: Indicates if this is a repeated character. + +keyboard.display (ALLEGRO_DISPLAY *) +: The display which had keyboard focus when the event occurred. + +> *Note*: in many input methods, characters are *not* entered one-for-one with +physical key presses. Multiple key presses can combine to generate a single +character, e.g. apostrophe + e may produce 'é'. Fewer key presses can also +generate more characters, e.g. macro sequences expanding to common phrases. + +### ALLEGRO_EVENT_MOUSE_AXES + +One or more mouse axis values changed. + +mouse.x (int) +: x-coordinate + +mouse.y (int) +: y-coordinate + +mouse.z (int) +: z-coordinate. This usually means the vertical axis of a mouse wheel, + where up is positive and down is negative. + +mouse.w (int) +: w-coordinate. This usually means the horizontal axis of a mouse wheel. + +mouse.dx (int) +: Change in the x-coordinate value since the previous + ALLEGRO_EVENT_MOUSE_AXES event. + +mouse.dy (int) +: Change in the y-coordinate value since the previous + ALLEGRO_EVENT_MOUSE_AXES event. + +mouse.dz (int) +: Change in the z-coordinate value since the previous + ALLEGRO_EVENT_MOUSE_AXES event. + +mouse.dw (int) +: Change in the w-coordinate value since the previous + ALLEGRO_EVENT_MOUSE_AXES event. + +mouse.pressure (float) +: Pressure, ranging from `0.0` to `1.0`. + +mouse.display (ALLEGRO_DISPLAY *) +: The display which had mouse focus. + +> *Note:* Calling [al_set_mouse_xy] also will result in a change of axis +values, but such a change is reported with [ALLEGRO_EVENT_MOUSE_WARPED] +events instead which are identical except for their type. + +> *Note:* currently mouse.display may be NULL if an event is generated in +response to [al_set_mouse_axis]. + +### ALLEGRO_EVENT_MOUSE_BUTTON_DOWN + +A mouse button was pressed. + +mouse.x (int) +: x-coordinate + +mouse.y (int) +: y-coordinate + +mouse.z (int) +: z-coordinate + +mouse.w (int) +: w-coordinate + +mouse.button (unsigned) +: The mouse button which was pressed, numbering from 1. + +mouse.pressure (float) +: Pressure, ranging from `0.0` to `1.0`. + +mouse.display (ALLEGRO_DISPLAY *) +: The display which had mouse focus. + +### ALLEGRO_EVENT_MOUSE_BUTTON_UP + +A mouse button was released. + +mouse.x (int) +: x-coordinate + +mouse.y (int) +: y-coordinate + +mouse.z (int) +: z-coordinate + +mouse.w (int) +: w-coordinate + +mouse.button (unsigned) +: The mouse button which was released, numbering from 1. + +mouse.pressure (float) +: Pressure, ranging from `0.0` to `1.0`. + +mouse.display (ALLEGRO_DISPLAY *) +: The display which had mouse focus. + +### ALLEGRO_EVENT_MOUSE_WARPED + +[al_set_mouse_xy] was called to move the mouse. +This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise. + +### ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY + +The mouse cursor entered a window opened by the program. + +mouse.x (int) +: x-coordinate + +mouse.y (int) +: y-coordinate + +mouse.z (int) +: z-coordinate + +mouse.w (int) +: w-coordinate + +mouse.display (ALLEGRO_DISPLAY *) +: The display which had mouse focus. + +### ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY + +The mouse cursor left the boundaries of a window opened by the program. + +mouse.x (int) +: x-coordinate + +mouse.y (int) +: y-coordinate + +mouse.z (int) +: z-coordinate + +mouse.w (int) +: w-coordinate + +mouse.display (ALLEGRO_DISPLAY *) +: The display which had mouse focus. + +### ALLEGRO_EVENT_TOUCH_BEGIN + +The touch input device registered a new touch. + +touch.display (ALLEGRO_DISPLAY) +: The display which was touched. + +touch.id (int) +: An identifier for this touch. If supported by the device it will + stay the same for events from the same finger until the touch + ends. + +touch.x (float) +: The x coordinate of the touch in pixels. + +touch.y (float) +: The y coordinate of the touch in pixels. + +touch.dx (float) +: Movement speed in pixels in x direction. + +touch.dy (float) +: Movement speed in pixels in y direction. + +touch.primary (bool) +: Whether this is the only/first touch or an additional touch. + +Since: 5.1.0 + +### ALLEGRO_EVENT_TOUCH_END + +A touch ended. + +Has the same fields as [ALLEGRO_EVENT_TOUCH_BEGIN]. + +Since: 5.1.0 + +### ALLEGRO_EVENT_TOUCH_MOVE + +The position of a touch changed. + +Has the same fields as [ALLEGRO_EVENT_TOUCH_BEGIN]. + +Since: 5.1.0 + +### ALLEGRO_EVENT_TOUCH_CANCEL + +A touch was cancelled. This is device specific but could for example +mean that a finger moved off the border of the device or moved so +fast that it could not be tracked any longer. + +Has the same fields as [ALLEGRO_EVENT_TOUCH_BEGIN]. + +Since: 5.1.0 + +### ALLEGRO_EVENT_TIMER + +A [timer][ALLEGRO_TIMER] counter incremented. + +timer.source (ALLEGRO_TIMER *) +: The timer which generated the event. + +timer.count (int64_t) +: The timer count value. + +### ALLEGRO_EVENT_DISPLAY_EXPOSE + +The display (or a portion thereof) has become visible. + +display.source (ALLEGRO_DISPLAY *) +: The display which was exposed. + +display.x (int) +: The X position of the top-left corner of the rectangle which was exposed. + +display.y (int) +: The Y position of the top-left corner of the rectangle which was exposed. + +display.width (int) +: The width of the rectangle which was exposed. + +display.height (int) +: The height of the rectangle which was exposed. + +> *Note:* The display needs to be created with ALLEGRO_GENERATE_EXPOSE_EVENTS +flag for these events to be generated. + +### ALLEGRO_EVENT_DISPLAY_RESIZE + +The window has been resized. + +display.source (ALLEGRO_DISPLAY *) +: The display which was resized. + +display.x (int) +: The X position of the top-left corner of the display. + +display.y (int) +: The Y position of the top-left corner of the display. + +display.width (int) +: The new width of the display. + +display.height (int) +: The new height of the display. + +You should normally respond to these events by calling [al_acknowledge_resize]. +Note that further resize events may be generated by the time you process the +event, so these fields may hold outdated information. + +### ALLEGRO_EVENT_DISPLAY_CLOSE + +The close button of the window has been pressed. + +display.source (ALLEGRO_DISPLAY *) +: The display which was closed. + +### ALLEGRO_EVENT_DISPLAY_LOST + +When using Direct3D, displays can enter +a "lost" state. In that state, drawing calls are ignored, and upon +entering the state, bitmap's pixel data can become undefined. Allegro +does its best to preserve the correct contents of bitmaps (see the +ALLEGRO_NO_PRESERVE_TEXTURE flag) and restore them when the device is +"found" (see [ALLEGRO_EVENT_DISPLAY_FOUND]). However, this is not 100% +fool proof (see discussion in [al_create_bitmap]'s documentation). + +> *Note:* This event merely means that the display was lost, that is, +DirectX suddenly lost the contents of all video bitmaps. In particular, +you can keep calling drawing functions -- they just most likely won't +do anything. If Allegro's restoration of the bitmaps works well for you +then no further action is required when you receive this event. + +display.source (ALLEGRO_DISPLAY *) +: The display which was lost. + +### ALLEGRO_EVENT_DISPLAY_FOUND + +Generated when a lost device is restored to operating state. +See [ALLEGRO_EVENT_DISPLAY_LOST]. + +display.source (ALLEGRO_DISPLAY *) +: The display which was found. + +### ALLEGRO_EVENT_DISPLAY_SWITCH_OUT + +The window is no longer active, that is the user might have clicked +into another window or "tabbed" away. In response to this event you +might want to call [al_clear_keyboard_state] (possibly passing +display.source as its argument) in order to prevent Allegro's keyboard +state from getting out of sync. + +display.source (ALLEGRO_DISPLAY *) +: The display which was switched out of. + +### ALLEGRO_EVENT_DISPLAY_SWITCH_IN + +The window is the active one again. + +display.source (ALLEGRO_DISPLAY *) +: The display which was switched into. + +### ALLEGRO_EVENT_DISPLAY_ORIENTATION + +Generated when the rotation or orientation of a display changes. + +display.source (ALLEGRO_DISPLAY *) +: The display which generated the event. + +event.display.orientation +: Contains one of the following values: + + - ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES + - ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES + - ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES + - ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES + - ALLEGRO_DISPLAY_ORIENTATION_FACE_UP + - ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN + +### ALLEGRO_EVENT_DISPLAY_HALT_DRAWING + +When a display receives this event it should stop doing any drawing +and then call [al_acknowledge_drawing_halt] immediately. + +This is currently only relevant for Android and iOS. It will be sent when the +application is switched to background mode, in addition to +[ALLEGRO_EVENT_DISPLAY_SWITCH_OUT]. The latter may also be sent in +situations where the application is not active but still should continue +drawing, for example when a popup is displayed in front of it. + +> *Note:* This event means that the next time you call a drawing function, your +program will crash. So you *must* stop drawing and you *must* immediately reply +with [al_acknowledge_drawing_halt]. Allegro sends this event because it cannot +handle this automatically. Your program might be doing the drawing in a +different thread from the event handling, in which case the drawing thread +needs to be signaled to stop drawing before acknowledging this event. + +> *Note:* Mobile devices usually never quit an application, so to +prevent the battery from draining while your application is halted it +can be a good idea to call [al_stop_timer] on all your timers, otherwise +they will keep generating events. If you are using audio, you can also +stop all audio voices (or pass NULL to [al_set_default_voice] if you use +the default mixer), otherwise Allegro will keep streaming silence to the +voice even if the stream or mixer are stopped or detached. + +Since: 5.1.0 + +See also: [ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING] + +### ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING + +When a display receives this event, it may resume drawing again, and it must +call [al_acknowledge_drawing_resume] immediately. + +This is currently only relevant for Android and iOS. The event will be sent +when an application returns from background mode and is allowed to draw to the +display again, in addition to [ALLEGRO_EVENT_DISPLAY_SWITCH_IN]. The latter +event may also be sent in a situation where the application is already active, +for example when a popup in front of it closes. + +> *Note:* Unlike [ALLEGRO_EVENT_DISPLAY_FOUND] it is not necessary to reload +any bitmaps when you receive this event. + +Since: 5.1.0 + +See also: [ALLEGRO_EVENT_DISPLAY_HALT_DRAWING] + +### ALLEGRO_EVENT_DISPLAY_CONNECTED + +This event is sent when a physical display is connected to the device +Allegro runs on. Currently, on most platforms, Allegro supports only a single +physical display. However, on iOS, a secondary physical display is supported. + +display.source (ALLEGRO_DISPLAY *) +: The display which was connected. + +Since: 5.1.1 + +### ALLEGRO_EVENT_DISPLAY_DISCONNECTED + +This event is sent when a physical display is disconnected from the device +Allegro runs on. Currently, on most platforms, Allegro supports only a single +physical display. However, on iOS, a secondary physical display is supported. + +display.source (ALLEGRO_DISPLAY *) +: The display which was disconnected. + +## API: ALLEGRO_USER_EVENT + +An event structure that can be emitted by user event sources. +These are the public fields: + +- ALLEGRO_EVENT_SOURCE *source; +- intptr_t data1; +- intptr_t data2; +- intptr_t data3; +- intptr_t data4; + +Like all other event types this structure is a part of the ALLEGRO_EVENT union. +To access the fields in an ALLEGRO_EVENT variable `ev`, you would use: + +- ev.user.source +- ev.user.data1 +- ev.user.data2 +- ev.user.data3 +- ev.user.data4 + +To create a new user event you would do this: + +~~~~c +ALLEGRO_EVENT_SOURCE my_event_source; +ALLEGRO_EVENT my_event; +float some_var; + +al_init_user_event_source(&my_event_source); + +my_event.user.type = ALLEGRO_GET_EVENT_TYPE('M','I','N','E'); +my_event.user.data1 = 1; +my_event.user.data2 = &some_var; + +al_emit_user_event(&my_event_source, &my_event, NULL); +~~~~ + +Event type identifiers for user events are assigned by the user. +Please see the documentation for [ALLEGRO_GET_EVENT_TYPE] for the rules you +should follow when assigning identifiers. + +See also: [al_emit_user_event], [ALLEGRO_GET_EVENT_TYPE], [al_init_user_event_source] + +## API: ALLEGRO_EVENT_QUEUE + +An event queue holds events that have been generated by event sources +that are registered with the queue. Events are stored in the order +they are generated. Access is in a strictly FIFO (first-in-first-out) order. + +See also: [al_create_event_queue], [al_destroy_event_queue] + +## API: ALLEGRO_EVENT_SOURCE + +An event source is any object which can generate events. +For example, an ALLEGRO_DISPLAY can generate events, and you can get the +ALLEGRO_EVENT_SOURCE pointer from an ALLEGRO_DISPLAY with +[al_get_display_event_source]. + +You may create your own "user" event sources that emit custom events. + +See also: [ALLEGRO_EVENT], [al_init_user_event_source], [al_emit_user_event] + +## API: ALLEGRO_EVENT_TYPE + +An integer used to distinguish between different types of events. + +See also: [ALLEGRO_EVENT], [ALLEGRO_GET_EVENT_TYPE], +[ALLEGRO_EVENT_TYPE_IS_USER] + +## API: ALLEGRO_GET_EVENT_TYPE + +Make an event type identifier, which is a 32-bit integer. +Usually, but not necessarily, this will be made from four 8-bit character +codes, for example: + +~~~~c +#define MY_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE('M','I','N','E') +~~~~ + +IDs less than 1024 are reserved for Allegro or its addons. +Don't use anything lower than `ALLEGRO_GET_EVENT_TYPE(0, 0, 4, 0)`. + +You should try to make your IDs unique so they don't clash with any 3rd party +code you may be using. Be creative. Numbering from 1024 is not creative. + +If you need multiple identifiers, you could define them like this: + +~~~~c +#define BASE_EVENT ALLEGRO_GET_EVENT_TYPE('M','I','N','E') +#define BARK_EVENT (BASE_EVENT + 0) +#define MEOW_EVENT (BASE_EVENT + 1) +#define SQUAWK_EVENT (BASE_EVENT + 2) + +/* Alternatively */ +enum { + BARK_EVENT = ALLEGRO_GET_EVENT_TYPE('M','I','N','E'), + MEOW_EVENT, + SQUAWK_EVENT +}; +~~~~ + +See also: [ALLEGRO_EVENT], [ALLEGRO_USER_EVENT], [ALLEGRO_EVENT_TYPE_IS_USER] + +## API: ALLEGRO_EVENT_TYPE_IS_USER + +A macro which evaluates to true if the event type is not a builtin event +type, i.e. one of those described in [ALLEGRO_EVENT_TYPE]. + +## API: al_create_event_queue + +Create a new, empty event queue, returning a pointer to the newly created +object if successful. Returns NULL on error. + +See also: [al_register_event_source], [al_destroy_event_queue], +[ALLEGRO_EVENT_QUEUE] + +## API: al_destroy_event_queue + +Destroy the event queue specified. All event sources currently +registered with the queue will be automatically unregistered before +the queue is destroyed. + +See also: [al_create_event_queue], [ALLEGRO_EVENT_QUEUE] + +## API: al_register_event_source + +Register the event source with the event queue specified. An +event source may be registered with any number of event queues +simultaneously, or none. Trying to register an event source with +the same event queue more than once does nothing. + +See also: [al_unregister_event_source], [ALLEGRO_EVENT_SOURCE] + +## API: al_unregister_event_source + +Unregister an event source with an event queue. If the event +source is not actually registered with the event queue, nothing +happens. + +If the queue had any events in it which originated from the event +source, they will no longer be in the queue after this call. + +See also: [al_register_event_source] + +## API: al_is_event_source_registered + +Return true if the event source is registered. + +See also: [al_register_event_source] + +Since: 5.2.0 + +## API: al_pause_event_queue + +Pause or resume accepting new events into the event queue (to resume, pass false +for `pause`). Events already in the queue are unaffected. + +While a queue is paused, any events which would be entered into the +queue are simply ignored. +This is an alternative to unregistering then re-registering all event +sources from the event queue, if you just need to prevent events piling +up in the queue for a while. + +See also: [al_is_event_queue_paused] + +Since: 5.1.0 + +## API: al_is_event_queue_paused + +Return true if the event queue is paused. + +See also: [al_pause_event_queue] + +Since: 5.1.0 + +## API: al_is_event_queue_empty + +Return true if the event queue specified is currently empty. + +See also: [al_get_next_event], [al_peek_next_event] + +## API: al_get_next_event + +Take the next event out of the event queue specified, and +copy the contents into `ret_event`, returning true. The original +event will be removed from the queue. If the event queue is +empty, return false and the contents of `ret_event` are unspecified. + +See also: [ALLEGRO_EVENT], [al_peek_next_event], [al_wait_for_event] + +## API: al_peek_next_event + +Copy the contents of the next event in the event queue +specified into `ret_event` and return true. The original event +packet will remain at the head of the queue. If the event queue is +actually empty, this function returns false and the contents of +`ret_event` are unspecified. + +See also: [ALLEGRO_EVENT], [al_get_next_event], [al_drop_next_event] + +## API: al_drop_next_event + +Drop (remove) the next event from the queue. If the queue is empty, +nothing happens. +Returns true if an event was dropped. + +See also: [al_flush_event_queue], [al_is_event_queue_empty] + +## API: al_flush_event_queue + +Drops all events, if any, from the queue. + +See also: [al_drop_next_event], [al_is_event_queue_empty] + +## API: al_wait_for_event + +Wait until the event queue specified is non-empty. If `ret_event` +is not NULL, the first event in the queue will be copied +into `ret_event` and removed from the queue. If `ret_event` is NULL +the first event is left at the head of the queue. + +See also: [ALLEGRO_EVENT], [al_wait_for_event_timed], +[al_wait_for_event_until], [al_get_next_event] + +## API: al_wait_for_event_timed + +Wait until the event queue specified is non-empty. If `ret_event` +is not NULL, the first event in the queue will be copied +into `ret_event` and removed from the queue. If `ret_event` is NULL +the first event is left at the head of the queue. + +`secs` determines approximately how many seconds to wait. If the call times +out, false is returned. Otherwise, if an event ocurred, true is returned. + +For compatibility with all platforms, `secs` must be 2,147,483.647 seconds or less. + +See also: [ALLEGRO_EVENT], [al_wait_for_event], [al_wait_for_event_until] + +## API: al_wait_for_event_until + +Wait until the event queue specified is non-empty. If `ret_event` +is not NULL, the first event in the queue will be copied +into `ret_event` and removed from the queue. If `ret_event` is NULL +the first event is left at the head of the queue. + +`timeout` determines how long to wait. If the call times out, false is +returned. Otherwise, if an event ocurred, true is returned. + +For compatibility with all platforms, `timeout` must be 2,147,483.647 seconds or less. + +See also: [ALLEGRO_EVENT], [ALLEGRO_TIMEOUT], [al_init_timeout], +[al_wait_for_event], [al_wait_for_event_timed] + + + +## API: al_init_user_event_source + +Initialise an event source for emitting user events. +The space for the event source must already have been allocated. + +One possible way of creating custom event sources is to derive other +structures with ALLEGRO_EVENT_SOURCE at the head, e.g. + +~~~~c +typedef struct THING THING; + +struct THING { + ALLEGRO_EVENT_SOURCE event_source; + int field1; + int field2; + /* etc. */ +}; + +THING *create_thing(void) +{ + THING *thing = malloc(sizeof(THING)); + + if (thing) { + al_init_user_event_source(&thing->event_source); + thing->field1 = 0; + thing->field2 = 0; + } + + return thing; +} +~~~~ + +The advantage here is that the THING pointer will be the same as the +ALLEGRO_EVENT_SOURCE pointer. Events emitted by the event source will have the +event source pointer as the `source` field, from which you can get a pointer to +a THING by a simple cast (after ensuring checking the event is of the correct +type). + +However, it is only one technique and you are not obliged to use it. + +The user event source will never be destroyed automatically. +You must destroy it manually with [al_destroy_user_event_source]. + +See also: [ALLEGRO_EVENT_SOURCE], [al_destroy_user_event_source], +[al_emit_user_event], [ALLEGRO_USER_EVENT] + +## API: al_destroy_user_event_source + +Destroy an event source initialised with [al_init_user_event_source]. + +This does not free the memory, as that was user allocated to begin with. + +See also: [ALLEGRO_EVENT_SOURCE] + +## API: al_emit_user_event + +Emit an event from a user event source. +The event source must have been initialised with [al_init_user_event_source]. +Returns `false` if the event source isn't registered with any queues, +hence the event wouldn't have been delivered into any queues. + +Events are *copied* in and out of event queues, so after this function +returns the memory pointed to by `event` may be freed or reused. +Some fields of the event being passed in may be modified by the function. + +Reference counting will be performed if `dtor` is not NULL. +Whenever a copy of the event is made, the reference count increases. +You need to call [al_unref_user_event] to decrease the reference count +once you are done with a user event that you have received from +[al_get_next_event], [al_peek_next_event], [al_wait_for_event], etc. + +Once the reference count drops to zero `dtor` will be called with a copy of +the event as an argument. It should free the resources associated with +the event, but *not* the event itself (since it is just a copy). + +If `dtor` is NULL then reference counting will not be performed. +It is safe, but unnecessary, to call [al_unref_user_event] on non-reference +counted user events. + +You can use al_emit_user_event to emit both user and non-user events from your +user event source. Note that emitting input events will not update the +corresponding input device states. For example, you may emit an event of type +[ALLEGRO_EVENT_KEY_DOWN], but it will not update the [ALLEGRO_KEYBOARD_STATE] +returned by [al_get_keyboard_state]. + +See also: [ALLEGRO_USER_EVENT], [al_unref_user_event] + +## API: al_unref_user_event + +Decrease the reference count of a user-defined event. +This must be called on any user event +that you get from [al_get_next_event], [al_peek_next_event], +[al_wait_for_event], etc. which is reference counted. +This function does nothing if the event is not reference counted. + +See also: [al_emit_user_event], [ALLEGRO_USER_EVENT] + + + +## API: al_get_event_source_data + +Returns the abstract user data associated with the event source. If no +data was previously set, returns NULL. + +See also: [al_set_event_source_data] + +## API: al_set_event_source_data + +Assign the abstract user data to the event source. Allegro does +not use the data internally for anything; it is simply meant as a +convenient way to associate your own data or objects with events. + +See also: [al_get_event_source_data] diff --git a/allegro/docs/src/refman/file.txt b/allegro/docs/src/refman/file.txt new file mode 100644 index 00000000..24bc2e76 --- /dev/null +++ b/allegro/docs/src/refman/file.txt @@ -0,0 +1,508 @@ +# File I/O + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_FILE + +An opaque object representing an open file. This could be a +real file on disk or a virtual file. + +## API: ALLEGRO_FILE_INTERFACE + +A structure containing function pointers to handle a type of "file", +real or virtual. See the full discussion in [al_set_new_file_interface]. + +The fields are: + +~~~~c +void* (*fi_fopen)(const char *path, const char *mode); +bool (*fi_fclose)(ALLEGRO_FILE *f); +size_t (*fi_fread)(ALLEGRO_FILE *f, void *ptr, size_t size); +size_t (*fi_fwrite)(ALLEGRO_FILE *f, const void *ptr, size_t size); +bool (*fi_fflush)(ALLEGRO_FILE *f); +int64_t (*fi_ftell)(ALLEGRO_FILE *f); +bool (*fi_fseek)(ALLEGRO_FILE *f, int64_t offset, int whence); +bool (*fi_feof)(ALLEGRO_FILE *f); +int (*fi_ferror)(ALLEGRO_FILE *f); +const char * (*fi_ferrmsg)(ALLEGRO_FILE *f); +void (*fi_fclearerr)(ALLEGRO_FILE *f); +int (*fi_fungetc)(ALLEGRO_FILE *f, int c); +off_t (*fi_fsize)(ALLEGRO_FILE *f); +~~~~ + +The fi_open function must allocate memory for whatever userdata structure it needs. +The pointer to that memory must be returned; it will then be associated with the +file. The other functions can access that data by calling [al_get_file_userdata] +on the file handle. If fi_open returns NULL then [al_fopen] will also return NULL. + +The fi_fclose function must clean up and free the userdata, but Allegro will +free the [ALLEGRO_FILE] handle. + +If fi_fungetc is NULL, then Allegro's default implementation of a 16 char long +buffer will be used. + +## API: ALLEGRO_SEEK + +* ALLEGRO_SEEK_SET - seek relative to beginning of file +* ALLEGRO_SEEK_CUR - seek relative to current file position +* ALLEGRO_SEEK_END - seek relative to end of file + +See also: [al_fseek] + +## API: al_fopen + +Creates and opens a file (real or virtual) given the path and mode. +The current file interface is used to open the file. + +Parameters: + +* path - path to the file to open +* mode - access mode to open the file in ("r", "w", etc.) + +Depending on the stream type and the mode string, files may be opened in +"text" mode. The handling of newlines is particularly important. For example, +using the default stdio-based streams on DOS and Windows platforms, where the +native end-of-line terminators are CR+LF sequences, a call to [al_fgetc] may +return just one character ('\\n') where there were two bytes (CR+LF) in the +file. When writing out '\\n', two bytes would be written instead. +(As an aside, '\\n' is not defined to be equal to LF either.) + +Newline translations can be useful for text files but is disastrous for binary +files. To avoid this behaviour you need to open file streams in binary mode +by using a mode argument containing a "b", e.g. "rb", "wb". + +Returns a file handle on success, or NULL on error. + +See also: [al_set_new_file_interface], [al_fclose]. + +## API: al_fopen_interface + +Opens a file using the specified interface, instead of the interface +set with [al_set_new_file_interface]. + +See also: [al_fopen] + +## API: al_fopen_slice + +Opens a slice (subset) of an already open random access file as if it were +a stand alone file. While the slice is open, the parent file handle must +not be used in any way. + +The slice is opened at the current location of the parent file, up through +`initial_size` bytes. The `initial_size` may be any non-negative integer +that will not exceed the bounds of the parent file. + +Seeking with `ALLEGRO_SEEK_SET` will be relative to this starting location. +`ALLEGRO_SEEK_END` will be relative to the starting location plus the +size of the slice. + +The mode can be any combination of: + +* r: read access +* w: write access +* e: expandable + +For example, a mode of "rw" indicates the file can be read and written. +(Note that this is slightly different from the stdio modes.) Keep in mind +that the parent file must support random access and be open in normal +write mode (not append) for the slice to work in a well defined way. + +If the slice is marked as expandable, then reads and writes can happen +after the initial end point, and the slice will grow accordingly. Otherwise, +all activity is restricted to the initial size of the slice. + +A slice must be closed with [al_fclose]. The parent file will then be +positioned immediately after the end of the slice. + +Since: 5.0.6, 5.1.0 + +See also: [al_fopen] + +## API: al_fclose + +Close the given file, writing any buffered output data (if any). + +Returns true on success, false on failure. +errno is set to indicate the error. + +## API: al_fread + +Read 'size' bytes into the buffer pointed to by 'ptr', from the given file. + +Returns the number of bytes actually read. +If an error occurs, or the end-of-file is reached, the return value is a +short byte count (or zero). + +al_fread() does not distinguish between EOF and other errors. +Use [al_feof] and [al_ferror] to determine which occurred. + +See also: [al_fgetc], [al_fread16be], [al_fread16le], [al_fread32be], +[al_fread32le] + +## API: al_fwrite + +Write 'size' bytes from the buffer pointed to by 'ptr' into the given file. + +Returns the number of bytes actually written. +If an error occurs, the return value is a short byte count (or zero). + +See also: [al_fputc], [al_fputs], [al_fwrite16be], [al_fwrite16le], +[al_fwrite32be], [al_fwrite32le] + +## API: al_fflush + +Flush any pending writes to the given file. + +Returns true on success, false otherwise. +errno is set to indicate the error. + +See also: [al_get_errno] + +## API: al_ftell + +Returns the current position in the given file, or -1 on error. +errno is set to indicate the error. + +On some platforms this function may not support large files. + +See also: [al_fseek], [al_get_errno] + +## API: al_fseek + +Set the current position of the given file to a position relative +to that specified by 'whence', plus 'offset' number of bytes. + +'whence' can be: + +* ALLEGRO_SEEK_SET - seek relative to beginning of file +* ALLEGRO_SEEK_CUR - seek relative to current file position +* ALLEGRO_SEEK_END - seek relative to end of file + +Returns true on success, false on failure. +errno is set to indicate the error. + +After a successful seek, the end-of-file indicator is cleared +and all pushback bytes are forgotten. + +On some platforms this function may not support large files. + +See also: [al_ftell], [al_get_errno] + +## API: al_feof + +Returns true if the end-of-file indicator has been set on the file, +i.e. we have attempted to read *past* the end of the file. + +This does *not* return true if we simply are at the end of the file. +The following code correctly reads two bytes, even when the file +contains exactly two bytes: + +~~~~c +int b1 = al_fgetc(f); +int b2 = al_fgetc(f); +if (al_feof(f)) { + /* At least one byte was unsuccessfully read. */ + report_error(); +} +~~~~ + +See also: [al_ferror], [al_fclearerr] + +## API: al_ferror + +Returns non-zero if the error indicator is set on the given file, +i.e. there was some sort of previous error. +The error code may be system or file interface specific. + +See also: [al_feof], [al_fclearerr], [al_ferrmsg] + +## API: al_ferrmsg + +Return a message string with details about the last error that occurred on +the given file handle. The returned string is empty if there was no error, +or if the file interface does not provide more information. + +See also: [al_fclearerr], [al_ferror] + +## API: al_fclearerr + +Clear the error indicator for the given file. + +The standard I/O backend also clears the end-of-file indicator, and other +backends *should* try to do this. However, they may not if it would require +too much effort (e.g. PhysicsFS backend), so your code should not rely on it +if you need your code to be portable to other backends. + +See also: [al_ferror], [al_feof] + +## API: al_fungetc + +Ungets a single byte from a file. +Pushed-back bytes are not written to the file, only made available for +subsequent reads, in reverse order. + +The number of pushbacks depends on the backend. The standard I/O backend only +guarantees a single pushback; this depends on the libc implementation. + +For backends that follow the standard behavior, the pushback buffer will +be cleared after any seeking or writing; also calls to [al_fseek] and [al_ftell] +are relative to the number of pushbacks. If a pushback causes the position to +become negative, the behavior of [al_fseek] and [al_ftell] are undefined. + +See also: [al_fgetc], [al_get_errno] + +## API: al_fsize + +Return the size of the file, if it can be determined, or -1 otherwise. + +## API: al_fgetc + +Read and return next byte in the given file. +Returns EOF on end of file or if an error occurred. + +See also: [al_fungetc] + +## API: al_fputc + +Write a single byte to the given file. +The byte written is the value of c cast to an unsigned char. + +Parameters: + +* c - byte value to write +* f - file to write to + +Returns the written byte (cast back to an int) on success, +or EOF on error. + +## API: al_fprintf + +Writes to a file with stdio "printf"-like formatting. +Returns the number of bytes written, or a negative number +on error. + +See also: [al_vfprintf] + +## API: al_vfprintf + +Like al_fprintf but takes a va_list. Useful for creating your own +variations of formatted printing. +Returns the number of bytes written, or a negative number +on error. + +See also: [al_fprintf] + +## API: al_fread16le + +Reads a 16-bit word in little-endian format (LSB first). + +On success, returns the 16-bit word. On failure, returns EOF (-1). Since -1 +is also a valid return value, use [al_feof] to check if the end of the file was +reached prematurely, or [al_ferror] to check if an error occurred. + +See also: [al_fread16be] + +## API: al_fread16be + +Reads a 16-bit word in big-endian format (MSB first). + +On success, returns the 16-bit word. On failure, returns EOF (-1). Since -1 +is also a valid return value, use [al_feof] to check if the end of the file was +reached prematurely, or [al_ferror] to check if an error occurred. + +See also: [al_fread16le] + +## API: al_fwrite16le + +Writes a 16-bit word in little-endian format (LSB first). + +Returns the number of bytes written: 2 on success, less than 2 on an error. + +See also: [al_fwrite16be] + +## API: al_fwrite16be + +Writes a 16-bit word in big-endian format (MSB first). + +Returns the number of bytes written: 2 on success, less than 2 on an error. + +See also: [al_fwrite16le] + +## API: al_fread32le + +Reads a 32-bit word in little-endian format (LSB first). + +On success, returns the 32-bit word. On failure, returns EOF (-1). Since -1 +is also a valid return value, use [al_feof] to check if the end of the file was +reached prematurely, or [al_ferror] to check if an error occurred. + +See also: [al_fread32be] + +## API: al_fread32be + +Read a 32-bit word in big-endian format (MSB first). + +On success, returns the 32-bit word. On failure, returns EOF (-1). Since -1 +is also a valid return value, use [al_feof] to check if the end of the file was +reached prematurely, or [al_ferror] to check if an error occurred. + +See also: [al_fread32le] + +## API: al_fwrite32le + +Writes a 32-bit word in little-endian format (LSB first). + +Returns the number of bytes written: 4 on success, less than 4 on an error. + +See also: [al_fwrite32be] + +## API: al_fwrite32be + +Writes a 32-bit word in big-endian format (MSB first). + +Returns the number of bytes written: 4 on success, less than 4 on an error. + +See also: [al_fwrite32le] + +## API: al_fgets + +Read a string of bytes terminated with a newline or end-of-file +into the buffer given. The line terminator(s), if any, are included in the +returned string. A maximum of max-1 bytes are read, with one byte being +reserved for a NUL terminator. + +Parameters: + +* f - file to read from +* buf - buffer to fill +* max - maximum size of buffer + +Returns the pointer to buf on success. Returns NULL if an error occurred or +if the end of file was reached without reading any bytes. + +See [al_fopen] about translations of end-of-line characters. + +See also: [al_fget_ustr] + +## API: al_fget_ustr + +Read a string of bytes terminated with a newline or end-of-file. +The line terminator(s), if any, are included in the returned string. + +On success returns a pointer to a new ALLEGRO_USTR structure. +This must be freed eventually with [al_ustr_free]. +Returns NULL if an error occurred or if the end of file was reached without +reading any bytes. + +See [al_fopen] about translations of end-of-line characters. + +See also: [al_fgetc], [al_fgets] + +## API: al_fputs + +Writes a string to file. Apart from the return value, +this is equivalent to: + +~~~~c +al_fwrite(f, p, strlen(p)); +~~~~ + +Parameters: + +* f - file handle to write to +* p - string to write + +Returns a non-negative integer on success, EOF on error. + +Note: depending on the stream type and the mode passed to [al_fopen], newline +characters in the string may or may not be automatically translated to +native end-of-line sequences, e.g. CR/LF instead of LF. + +See also: [al_fwrite] + +## Standard I/O specific routines + +### API: al_fopen_fd + +Create an [ALLEGRO_FILE] object that operates on an open file descriptor using +stdio routines. See the documentation of fdopen() for a description of the +'mode' argument. + +Returns an ALLEGRO_FILE object on success or NULL on an error. +On an error, the Allegro errno will be set and the file descriptor will +not be closed. + +The file descriptor will be closed by [al_fclose] so you should not +call close() on it. + +See also: [al_fopen] + +### API: al_make_temp_file + +Make a temporary randomly named file given a filename 'template'. + +'template' is a string giving the format of the generated filename and +should include one or more capital Xs. The Xs are replaced with random +alphanumeric characters, produced using a simple pseudo-random +number generator only. There should be no path separators. + +If 'ret_path' is not NULL, the address it points to will be set +to point to a new path structure with the name of the temporary file. + +Returns the opened [ALLEGRO_FILE] on success, NULL on failure. + +## Alternative file streams + +By default, the Allegro file I/O routines use the C library I/O routines, +hence work with files on the local filesystem, but can be overridden so that +you can read and write to other streams. For example, you can work with blocks +of memory or sub-files inside .zip files. + +There are two ways to get an [ALLEGRO_FILE] that doesn't use stdio. +An addon library may provide a function that returns a new ALLEGRO_FILE +directly, after which, all al_f* calls on that object will use +overridden functions for that type of stream. +Alternatively, [al_set_new_file_interface] changes which function will handle +the following [al_fopen] calls for the current thread. + +### API: al_set_new_file_interface + +Set the [ALLEGRO_FILE_INTERFACE] table for the calling thread. +This will change the handler for later calls to [al_fopen]. + +See also: [al_set_standard_file_interface], [al_store_state], +[al_restore_state]. + +### API: al_set_standard_file_interface + +Set the [ALLEGRO_FILE_INTERFACE] table to the default, for the calling thread. +This will change the handler for later calls to [al_fopen]. + +See also: [al_set_new_file_interface] + +### API: al_get_new_file_interface + +Return a pointer to the [ALLEGRO_FILE_INTERFACE] table in effect +for the calling thread. + +See also: [al_store_state], [al_restore_state]. + +### API: al_create_file_handle + +Creates an empty, opened file handle with some abstract user data. +This allows custom interfaces to extend the [ALLEGRO_FILE] struct +with their own data. You should close the handle with the standard +[al_fclose] function when you are finished with it. + +See also: [al_fopen], [al_fclose], [al_set_new_file_interface] + +### API: al_get_file_userdata + +Returns a pointer to the custom userdata that is attached to the +file handle. This is intended to be used by functions that extend +[ALLEGRO_FILE_INTERFACE]. + diff --git a/allegro/docs/src/refman/fixed.txt b/allegro/docs/src/refman/fixed.txt new file mode 100644 index 00000000..aa42a810 --- /dev/null +++ b/allegro/docs/src/refman/fixed.txt @@ -0,0 +1,499 @@ +# Fixed point math routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: al_fixed + +A fixed point number. + +Allegro provides some routines for working with fixed point numbers, and +defines the type `al_fixed` to be a signed 32-bit integer. The high word is +used for the integer part and the low word for the fraction, giving a range +of -32768 to 32767 and an accuracy of about four or five decimal places. +Fixed point numbers can be assigned, compared, added, subtracted, negated and +shifted (for multiplying or dividing by powers of two) using the normal +integer operators, but you should take care to use the appropriate conversion +routines when mixing fixed point with integer or floating point values. +Writing `fixed_point_1 + fixed_point_2` is OK, but `fixed_point + integer` is +not. + +The only advantage of fixed point math routines is that you don't require a +floating point coprocessor to use them. This was great in the time period of +i386 and i486 machines, but stopped being so useful with the coming of the +Pentium class of processors. From Pentium onwards, CPUs have increased their +strength in floating point operations, equaling or even surpassing integer +math performance. However, many embedded processors have no FPUs so fixed +point maths can still be useful there. + +Depending on the type of operations your program may need, using floating +point types may be faster than fixed types if you are targeting a specific +machine class. + +## API: al_itofix + +Converts an integer to fixed point. This is the same thing as x<<16. Remember +that overflows (trying to convert an integer greater than 32767) and +underflows (trying to convert an integer lesser than -32768) are not detected +even in debug builds! The values simply "wrap around". + +Example: + +~~~~c +al_fixed number; + +/* This conversion is OK. */ +number = al_itofix(100); +assert(al_fixtoi(number) == 100); + +number = al_itofix(64000); + +/* This check will fail in debug builds. */ +assert(al_fixtoi(number) == 64000); +~~~~ + +Return value: +Returns the value of the integer converted to fixed point ignoring overflows. + +See also: [al_fixtoi], [al_ftofix], [al_fixtof]. + +## API: al_fixtoi + +Converts fixed point to integer, rounding as required to the nearest integer. + +Example: + +~~~~c +int result; + +/* This will put 33 into `result'. */ +result = al_fixtoi(al_itofix(100) / 3); + +/* But this will round up to 17. */ +result = al_fixtoi(al_itofix(100) / 6); +~~~~ + +See also: [al_itofix], [al_ftofix], [al_fixtof], [al_fixfloor], [al_fixceil]. + +## API: al_fixfloor + +Returns the greatest integer not greater than x. That is, it rounds towards +negative infinity. + +Example: + +~~~~c +int result; + +/* This will put 33 into `result'. */ +result = al_fixfloor(al_itofix(100) / 3); + +/* And this will round down to 16. */ +result = al_fixfloor(al_itofix(100) / 6); +~~~~ + +See also: [al_fixtoi], [al_fixceil]. + +## API: al_fixceil + +Returns the smallest integer not less than x. That is, it rounds towards +positive infinity. + +Example: + +~~~~c +int result; + +/* This will put 34 into `result'. */ +result = al_fixceil(al_itofix(100) / 3); + +/* This will round up to 17. */ +result = al_fixceil(al_itofix(100) / 6); +~~~~ + +See also: [al_fixtoi], [al_fixfloor]. + +## API: al_ftofix + +Converts a floating point value to fixed point. Unlike [al_itofix], this +function clamps values which could overflow the type conversion, setting +Allegro's errno to ERANGE in the process if this happens. + +Example: + +~~~~c +al_fixed number; + +number = al_itofix(-40000); +assert(al_fixfloor(number) == -32768); + +number = al_itofix(64000); +assert(al_fixfloor(number) == 32767); +assert(!al_get_errno()); /* This will fail. */ +~~~~ + +Return value: +Returns the value of the floating point value converted to fixed point +clamping overflows (and setting Allegro's errno). + +See also: [al_fixtof], [al_itofix], [al_fixtoi], [al_get_errno] + +## API: al_fixtof + +Converts fixed point to floating point. + +Example: + +~~~~c +float result; + +/* This will put 33.33333 into `result'. */ +result = al_fixtof(al_itofix(100) / 3); + +/* This will put 16.66666 into `result'. */ +result = al_fixtof(al_itofix(100) / 6); +~~~~ + +See also: [al_ftofix], [al_itofix], [al_fixtoi]. + +## API: al_fixmul + +A fixed point value can be multiplied or divided by an integer with the +normal `*` and `/` operators. To multiply two fixed point values, though, you +must use this function. + +If an overflow occurs, Allegro's errno will be set and the maximum possible +value will be returned, but errno is not cleared if the operation is +successful. This means that if you are going to test for overflow you should +call `al_set_errno(0)` before calling [al_fixmul]. + +Example: + +~~~~c +al_fixed result; + +/* This will put 30000 into `result'. */ +result = al_fixmul(al_itofix(10), al_itofix(3000)); + +/* But this overflows, and sets errno. */ +result = al_fixmul(al_itofix(100), al_itofix(3000)); +assert(!al_get_errno()); +~~~~ + +Return value: +Returns the clamped result of multiplying `x` by `y`, setting Allegro's errno +to ERANGE if there was an overflow. + +See also: [al_fixadd], [al_fixsub], [al_fixdiv], [al_get_errno]. + +## API: al_fixdiv + +A fixed point value can be divided by an integer with the normal `/` +operator. To divide two fixed point values, though, you must use this +function. If a division by zero occurs, Allegro's errno will be set and the +maximum possible value will be returned, but errno is not cleared if the +operation is successful. This means that if you are going to test for +division by zero you should call `al_set_errno(0)` before calling +[al_fixdiv]. + +Example: + +~~~~c +al_fixed result; + +/* This will put 0.06060 `result'. */ +result = al_fixdiv(al_itofix(2), al_itofix(33)); + +/* This will put 0 into `result'. */ +result = al_fixdiv(0, al_itofix(-30)); + +/* Sets errno and puts -32768 into `result'. */ +result = al_fixdiv(al_itofix(-100), al_itofix(0)); +assert(!al_get_errno()); /* This will fail. */ +~~~~ + +Return value: +Returns the result of dividing `x` by `y`. If `y` is zero, returns the maximum +possible fixed point value and sets Allegro's errno to ERANGE. + +See also: [al_fixadd], [al_fixsub], [al_fixmul], [al_get_errno]. + +## API: al_fixadd + +Although fixed point numbers can be added with the normal `+` integer +operator, that doesn't provide any protection against overflow. If overflow +is a problem, you should use this function instead. It is slower than using +integer operators, but if an overflow occurs it will set Allegro's errno and +clamp the result, rather than just letting it wrap. + +Example: + +~~~~c +al_fixed result; + +/* This will put 5035 into `result'. */ +result = al_fixadd(al_itofix(5000), al_itofix(35)); + +/* Sets errno and puts -32768 into `result'. */ +result = al_fixadd(al_itofix(-31000), al_itofix(-3000)); +assert(!al_get_errno()); /* This will fail. */ +~~~~ + +Return value: +Returns the clamped result of adding `x` to `y`, setting Allegro's errno to +ERANGE if there was an overflow. + +See also: [al_fixsub], [al_fixmul], [al_fixdiv]. + +## API: al_fixsub + +Although fixed point numbers can be subtracted with the normal `-` integer +operator, that doesn't provide any protection against overflow. If overflow +is a problem, you should use this function instead. It is slower than using +integer operators, but if an overflow occurs it will set Allegro's errno +and clamp the result, rather than just letting it wrap. + +Example: + +~~~~c +al_fixed result; + +/* This will put 4965 into `result'. */ +result = al_fixsub(al_itofix(5000), al_itofix(35)); + +/* Sets errno and puts -32768 into `result'. */ +result = al_fixsub(al_itofix(-31000), al_itofix(3000)); +assert(!al_get_errno()); /* This will fail. */ +~~~~ + +Return value: +Returns the clamped result of subtracting `y` from `x`, setting Allegro's +errno to ERANGE if there was an overflow. + +See also: [al_fixadd], [al_fixmul], [al_fixdiv], [al_get_errno]. + + +## Fixed point trig + +The fixed point square root, sin, cos, tan, inverse sin, and inverse cos +functions are implemented using lookup tables, which are very fast but not +particularly accurate. At the moment the inverse tan uses an iterative search +on the tan table, so it is a lot slower than the others. On machines with +good floating point processors using these functions could be slower Always +profile your code. + +Angles are represented in a binary format with 256 equal to a full circle, 64 +being a right angle and so on. This has the advantage that a simple bitwise +'and' can be used to keep the angle within the range zero to a full circle. + +### API: al_fixtorad_r + +This constant gives a ratio which can be used to convert a fixed point number +in binary angle format to a fixed point number in radians. + +Example: + +~~~~c +al_fixed rad_angle, binary_angle; + +/* Set the binary angle to 90 degrees. */ +binary_angle = 64; + +/* Now convert to radians (about 1.57). */ +rad_angle = al_fixmul(binary_angle, al_fixtorad_r); +~~~~ + +See also: [al_fixmul], [al_radtofix_r]. + +### API: al_radtofix_r + +This constant gives a ratio which can be used to convert a fixed point number +in radians to a fixed point number in binary angle format. + +Example: + +~~~~ + al_fixed rad_angle, binary_angle; + ... + binary_angle = al_fixmul(rad_angle, radtofix_r); +~~~~ + +See also: [al_fixmul], [al_fixtorad_r]. + +### API: al_fixsin + +This function finds the sine of a value using a lookup table. The input value +must be a fixed point binary angle. + +Example: + +~~~~c +al_fixed angle; +int result; + +/* Set the binary angle to 90 degrees. */ +angle = al_itofix(64); + +/* The sine of 90 degrees is one. */ +result = al_fixtoi(al_fixsin(angle)); +assert(result == 1); +~~~~ + +Return value: +Returns the sine of a fixed point binary format angle as a fixed point value. + +### API: al_fixcos + +This function finds the cosine of a value using a lookup table. The input +value must be a fixed point binary angle. + +Example: + +~~~~c +al_fixed angle; +float result; + +/* Set the binary angle to 45 degrees. */ +angle = al_itofix(32); + +/* The cosine of 45 degrees is about 0.7071. */ +result = al_fixtof(al_fixcos(angle)); +assert(result > 0.7 && result < 0.71); +~~~~ + +Return value: +Returns the cosine of a fixed point binary format angle as a fixed point value. + +### API: al_fixtan + +This function finds the tangent of a value using a lookup table. The input +value must be a fixed point binary angle. + +Example: + +~~~~c +al_fixed angle, res_a, res_b; +float dif; + +angle = al_itofix(37); +/* Prove that tan(angle) == sin(angle) / cos(angle). */ +res_a = al_fixdiv(al_fixsin(angle), al_fixcos(angle)); +res_b = al_fixtan(angle); +dif = al_fixtof(al_fixsub(res_a, res_b)); +printf("Precision error: %f\n", dif); +~~~~ + +Return value: +Returns the tangent of a fixed point binary format angle as a fixed point value. + +### API: al_fixasin + +This function finds the inverse sine of a value using a lookup table. The +input value must be a fixed point value. The inverse sine is defined only in +the domain from -1 to 1. Outside of this input range, the function will +set Allegro's errno to EDOM and return zero. + +Example: + +~~~~c +float angle; +al_fixed val; + +/* Sets `val' to a right binary angle (64). */ +val = al_fixasin(al_itofix(1)); + +/* Sets `angle' to 0.2405. */ +angle = al_fixtof(al_fixmul(al_fixasin(al_ftofix(0.238)), al_fixtorad_r)); + +/* This will trigger the assert. */ +val = al_fixasin(al_ftofix(-1.09)); +assert(!al_get_errno()); +~~~~ + +Return value: +Returns the inverse sine of a fixed point value, measured as fixed point +binary format angle, or zero if the input was out of the range. +All return values of this function will be in the range -64 to 64. + +### API: al_fixacos + +This function finds the inverse cosine of a value using a lookup table. The +input must be a fixed point value. The inverse cosine is defined only in the +domain from -1 to 1. Outside of this input range, the function will set +Allegro's errno to EDOM and return zero. + +Example: + +~~~~c +al_fixed result; + +/* Sets result to binary angle 128. */ +result = al_fixacos(al_itofix(-1)); +~~~~ + +Return value: +Returns the inverse sine of a fixed point value, measured as fixed point +binary format angle, or zero if the input was out of range. All +return values of this function will be in the range 0 to 128. + +### API: al_fixatan + +This function finds the inverse tangent of a value using a lookup table. The +input must be a fixed point value. The inverse tangent is the value whose +tangent is `x`. + +Example: + +~~~~c +al_fixed result; + +/* Sets result to binary angle 13. */ +result = al_fixatan(al_ftofix(0.326)); +~~~~ + +Return value: +Returns the inverse tangent of a fixed point value, measured as a fixed point +binary format angle. + +### API: al_fixatan2 + +This is a fixed point version of the libc atan2() routine. It computes the +arc tangent of `y / x`, but the signs of both arguments are used to determine +the quadrant of the result, and `x` is permitted to be zero. This function is +useful to convert Cartesian coordinates to polar coordinates. + +Example: + +~~~~c +al_fixed result; + +/* Sets `result' to binary angle 64. */ +result = al_fixatan2(al_itofix(1), 0); + +/* Sets `result' to binary angle -109. */ +result = al_fixatan2(al_itofix(-1), al_itofix(-2)); + +/* Fails the assert. */ +result = al_fixatan2(0, 0); +assert(!al_get_errno()); +~~~~ + +Return value: +Returns the arc tangent of `y / x` in fixed point binary format angle, from +-128 to 128. If both `x` and `y` are zero, returns zero and sets Allegro's +errno to EDOM. + +### API: al_fixsqrt + +This finds out the non negative square root of `x`. If `x` is negative, +Allegro's errno is set to EDOM and the function returns zero. + +### API: al_fixhypot + +Fixed point hypotenuse (returns the square root of `x*x + y*y`). This should +be better than calculating the formula yourself manually, since the error is +much smaller. + diff --git a/allegro/docs/src/refman/font.txt b/allegro/docs/src/refman/font.txt new file mode 100644 index 00000000..9b46ed86 --- /dev/null +++ b/allegro/docs/src/refman/font.txt @@ -0,0 +1,808 @@ +# Font addons + +These functions are declared in the following header file. +Link with allegro_font. + +~~~~c + #include +~~~~ + +## General font routines + +### API: ALLEGRO_FONT + +A handle identifying any kind of font. Usually you will create it with +[al_load_font] which supports loading all kinds of TrueType fonts supported by +the FreeType library. If you instead pass the filename of a bitmap file, it will +be loaded with [al_load_bitmap] and a font in Allegro's bitmap font format will +be created from it with [al_grab_font_from_bitmap]. + +### API: ALLEGRO_GLYPH + +A structure containing the properties of a character in a font. + +~~~~c +typedef struct ALLEGRO_GLYPH { + ALLEGRO_BITMAP *bitmap; // the bitmap the character is on + int x; // the x position of the glyph on bitmap + int y; // the y position of the glyph on bitmap + int w; // the width of the glyph in pixels + int h; // the height of the glyph in pixels + int kerning; // pixels of kerning (see below) + int offset_x; // x offset to draw the glyph at + int offset_y; // y offset to draw the glyph at + int advance; // number of pixels to advance after this character +} ALLEGRO_GLYPH; +~~~~ + +bitmap may be a sub-bitmap in the case of color fonts. Bitmap can also be NULL +in which case nothing should be drawn (sometimes true for whitespace characters +in TTF fonts). + +kerning should be added to the x position you draw to if you want your text +kerned and depends on which codepoints [al_get_glyph] was called with. + +Glyphs are tightly packed onto the bitmap, so you need to add offset_x and +offset_y to your draw position for the text to look right. + +advance is the number of pixels to add to your x position to advance to the +next character in a string and includes kerning. + +Since: 5.2.1 + +> *[Unstable API]:* This API is new and subject to refinement. + +See also: [al_get_glyph] + +### API: al_init_font_addon + +Initialise the font addon. + +Note that if you intend to load bitmap fonts, you will need to initialise +allegro_image separately (unless you are using another library to load images). + +Similarly, if you wish to load truetype-fonts, do not forget to also call +[al_init_ttf_addon]. + +Returns true on success, false on failure. +On the 5.0 branch, this function has no return value. You may wish to avoid +checking the return value if your code needs to be compatible with Allegro +5.0. Currently, the function will never return false. + +See also: [al_init_image_addon], [al_init_ttf_addon], [al_shutdown_font_addon] + +### API: al_is_font_addon_initialized + +Returns true if the font addon is initialized, otherwise returns false. + +Since: 5.2.6 + +See also: [al_init_font_addon], [al_shutdown_font_addon] + +### API: al_shutdown_font_addon + +Shut down the font addon. This is done automatically at program exit, +but can be called any time the user wishes as well. + +See also: [al_init_font_addon] + +### API: al_load_font + +Loads a font from disk. This will use [al_load_bitmap_font_flags] if you pass +the name of a known bitmap format, or else [al_load_ttf_font]. + +The flags parameter is passed through to either of those functions. +Bitmap and TTF fonts are also affected by the current +[bitmap flags][al_set_new_bitmap_flags] at the time the font is loaded. + +See also: [al_destroy_font], [al_init_font_addon], [al_register_font_loader], +[al_load_bitmap_font_flags], [al_load_ttf_font] + +### API: al_destroy_font + +Frees the memory being used by a font structure. +Does nothing if passed NULL. + +See also: [al_load_font] + +### API: al_register_font_loader + +Informs Allegro of a new font file type, telling it how to load files of +this format. + +The `extension` should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `load_font` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_init_font_addon] + +### API: al_get_font_line_height + +Returns the usual height of a line of text in the specified font. For bitmap +fonts this is simply the height of all glyph bitmaps. For truetype fonts it +is whatever the font file specifies. In particular, some special glyphs may be +higher than the height returned here. + +If the X is the position you specify to draw text, the meaning of +ascent and descent and the line height is like in the figure below. + + X------------------------ + /\ | | + / \ | | + /____\ ascent | + / \ | | + / \ | height + ---------------- | + | | + descent | + | | + ------------------------- + +See also: [al_get_text_width], [al_get_text_dimensions] + +### API: al_get_font_ascent + +Returns the ascent of the specified font. + +See also: [al_get_font_descent], [al_get_font_line_height] + +### API: al_get_font_descent + +Returns the descent of the specified font. + +See also: [al_get_font_ascent], [al_get_font_line_height] + +### API: al_get_text_width + +Calculates the length of a string in a particular font, in pixels. + +See also: [al_get_ustr_width], [al_get_font_line_height], +[al_get_text_dimensions] + +### API: al_get_ustr_width + +Like [al_get_text_width] but expects an ALLEGRO_USTR. + +See also: [al_get_text_width], [al_get_ustr_dimensions] + +### API: al_draw_text + +Writes the NUL-terminated string `text` onto the target bitmap at position `x`, +`y`, using the specified `font`. + +The `flags` parameter can be 0 or one of the following flags: + +- ALLEGRO_ALIGN_LEFT - Draw the text left-aligned (same as 0). +- ALLEGRO_ALIGN_CENTRE - Draw the text centered around the given position. +- ALLEGRO_ALIGN_RIGHT - Draw the text right-aligned to the given position. + +It can also be combined with this flag: + +- ALLEGRO_ALIGN_INTEGER - Always draw text aligned to an integer pixel + position. This was formerly the default behaviour. Since: 5.0.8, 5.1.4 + +This function does not support newline characters (`\n`), +but you can use [al_draw_multiline_text] for multi line text output. + +See also: [al_draw_ustr], [al_draw_textf], [al_draw_justified_text], +[al_draw_multiline_text]. + +### API: al_draw_ustr + +Like [al_draw_text], except the text is passed as an ALLEGRO_USTR instead of +a NUL-terminated char array. + +See also: [al_draw_text], [al_draw_justified_ustr], [al_draw_multiline_ustr] + +### API: al_draw_justified_text + +Like [al_draw_text], but justifies the string to the region x1-x2. + +The `diff` parameter is the maximum amount of horizontal space to +allow between words. If justisfying the text would exceed `diff` pixels, +or the string contains less than two words, then the string will be drawn +left aligned. + +The `flags` parameter can be 0 or one of the following flags: + +- ALLEGRO_ALIGN_INTEGER - Draw text aligned to integer pixel positions. + Since: 5.0.8, 5.1.5 + +See also: [al_draw_justified_textf], [al_draw_justified_ustr] + +### API: al_draw_justified_ustr + +Like [al_draw_justified_text], except the text is passed as an ALLEGRO_USTR +instead of a NUL-terminated char array. + +See also: [al_draw_justified_text], [al_draw_justified_textf]. + +### API: al_draw_textf + +Formatted text output, using a printf() style format string. +All parameters have the same meaning as with [al_draw_text] otherwise. + +See also: [al_draw_text], [al_draw_ustr] + +### API: al_draw_justified_textf + +Formatted text output, using a printf() style format string. +All parameters have the same meaning as with [al_draw_justified_text] +otherwise. + +See also: [al_draw_justified_text], [al_draw_justified_ustr]. + +### API: al_get_text_dimensions + +Sometimes, the [al_get_text_width] and [al_get_font_line_height] +functions are not enough for exact text placement, so this function +returns some additional information. + +Returned variables (all in pixels): + +- x, y - Offset to upper left corner of bounding box. +- w, h - Dimensions of bounding box. + +Note that glyphs may go to the left and upwards of the X, in which +case x and y will have negative values. + +See also: [al_get_text_width], [al_get_font_line_height], +[al_get_ustr_dimensions] + +### API: al_get_ustr_dimensions + +Like [al_get_text_dimensions], except the text is passed as an ALLEGRO_USTR +instead of a NUL-terminated char array. + +See also: [al_get_text_dimensions] + +### API: al_get_allegro_font_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. + +### API: al_get_font_ranges + +Gets information about all glyphs contained in a font, as a list of ranges. +Ranges have the same format as with [al_grab_font_from_bitmap]. + +`ranges_count` is the maximum number of ranges that will be returned. + +`ranges` should be an array with room for `ranges_count` * 2 elements. The +even integers are the first unicode point in a range, the odd integers the +last unicode point in a range. + +Returns the number of ranges contained in the font (even if it is bigger +than `ranges_count`). + +Since: 5.1.4 + +See also: [al_grab_font_from_bitmap] + +### API: al_set_fallback_font + +Sets a font which is used instead if a character is not present. Can be +chained, but make sure there is no loop as that would crash the +application! Pass NULL to remove a fallback font again. + +Since: 5.1.12 + +See also: [al_get_fallback_font], [al_draw_glyph], [al_draw_text] + +### API: al_get_fallback_font + +Retrieves the fallback font for this font or NULL. + +Since: 5.1.12 + +See also: [al_set_fallback_font] + +## Per glyph text handling + +For some applications Allegro's text drawing functions may not be sufficient. +For example, you would like to give a different color to every letter in a word, +or use different a font for a drop cap. + +That is why Allegro supports drawing and getting the dimensions of the +individual glyphs of a font. A glyph is a particular visual representation of +a letter, character or symbol in a specific font. + +And it's also possible to get the kerning to use between two glyphs. These per +glyph functions have less overhead than Allegro's per string text drawing and +dimensioning functions. So, with these functions you can write your own +efficient and precise custom text drawing functions. + +### API: al_draw_glyph + +Draws the glyph that corresponds with `codepoint` in the given `color` +using the given `font`. If `font` does not have such a glyph, nothing +will be drawn. + +To draw a string as left to right horizontal text you will need to use +[al_get_glyph_advance] to determine the position of each glyph. +For drawing strings in other directions, such as top to down, use +[al_get_glyph_dimensions] to determine the size and position of each glyph. + +If you have to draw many glyphs at the same time, use [al_hold_bitmap_drawing] +with true as the parameter, before drawing the glyphs, and then call +[al_hold_bitmap_drawing] again with false as a parameter when done drawing the +glyphs to further enhance performance. + +Since: 5.1.12 + +See also: [al_get_glyph_width], [al_get_glyph_dimensions], +[al_get_glyph_advance]. + +### API: al_get_glyph_width + +This function returns the width in pixels of the glyph that corresponds with +`codepoint` in the font `font`. Returns zero if the font does not have such +a glyph. + +Since: 5.1.12 + +See also: [al_draw_glyph], [al_get_glyph_dimensions], [al_get_glyph_advance]. + +### API: al_get_glyph_dimensions + +Sometimes, the [al_get_glyph_width] or [al_get_glyph_advance] functions are +not enough for exact glyph placement, so this function returns some additional +information, particularly if you want to draw the font vertically. + +The function itself returns true if the character was present in `font` +and false if the character was not present in `font`. + +Returned variables (all in pixel): + +- bbx, bby - Offset to upper left corner of bounding box. +- bbw, bbh - Dimensions of bounding box. + +These values are the same as [al_get_text_dimensions] would return for +a string of a single character equal to the glyph passed to this function. +Note that glyphs may go to the left and upwards of the X, in which +case x and y will have negative values. + +If you want to draw a string verticallly, for Japanese or as a game effect, +then you should leave bby + bbh space between the glyphs in the y direction +for a regular placement. + +If you want to draw a string horizontally in an extra compact way, +then you should leave bbx + bbw space between the glyphs in the x direction +for a compact placement. + +In the figure below is an example of what bbx and bby may be like for a `2` +glyph, and a `g` glyph of the same font compared to the result of +al_get_glyph_width(). + + + al_get_glyph_width() al_get_glyph_width() + __|___ __|__ + / \ / \ + bbx bbw bbx bbw + <-->+<------>+ <-->+<----->+ X baseline + ^ | | ^ | | + bby | | | bby | | | + v | | | | | + +---+--------+ | | | + ^ | ***** | | | | + | |* ** | v | | + bbh | | ** | bbh +---+-------+ + | | ** | ^ | ***** | + v |********| | |* *| + +---+--------+ | | ***** | + | | *| + | | * *| + v | **** | + +---+-------+ + + +Since: 5.1.12 + +See also: [al_draw_glyph], [al_get_glyph_width], [al_get_glyph_advance]. + +### API: al_get_glyph_advance + +This function returns by how much the x position should be advanced +for left to right text drawing when the glyph that corresponds to codepoint1 +has been drawn, and the glyph that corresponds to codepoint2 will be the next +to be drawn. This takes into consideration the horizontal advance width of the +glyph that corresponds with codepoint1 as well as the kerning between the +glyphs of codepoint1 and codepoint2. + +Kerning is the process of adjusting the spacing between glyphs in a font, +to obtain a more visually pleasing result. Kerning adjusts the space between +two individual glyphs with an offset determined by the author of the font. + +If you pass ALLEGRO_NO_KERNING as codepoint1 then al_get_glyph_advance +will return 0. this can be useful when drawing the first character of a string +in a loop. + +Pass ALLEGRO_NO_KERNING as codepoint2 to get the horizontal advance width +of the glyph that corresponds to codepoint1 without taking any kerning into +consideration. This can be used, for example, when drawing the last character +of a string in a loop. + +This function will return zero if the glyph of codepoint1 is not present +in the `font`. If the glyph of codepoint2 is not present in the font, +the horizontal advance width of the glyph that corresponds to codepoint1 +without taking any kerning into consideration is returned. + +When drawing a string one glyph at the time from the left to the right +with kerning, the x position of the glyph should be incremented by the result +of [al_get_glyph_advance] applied to the previous glyph drawn and +the next glyph to draw. + +Note that the return value of this function is a recommended advance for +optimal readability for left to right text determined by the author of the font. +However, if you like, you may want to draw the glyphs of the font narrower +or wider to each other than what [al_get_glyph_advance] returns for style +or effect. + +In the figure below is an example of what the result of al_get_glyph_advance +may be like for two glypphs `A` and `l` of the same font that has kerning for +the "Al" pair, without and with the ALLEGRO_NO_KERNING flag. + + + al_get_glyph_advance(font, 'A', 'l') + ___|___ + / \ + ------------- + /\ -| + / \ | + /____\ | + / \ | + / \ \_ + ------------- + + + al_get_glyph_advance(font, 'A', ALLEGRO_NO_KERNING) + ____|____ + / \ + --------------- + /\ -| + / \ | + /____\ | + / \ | + / \ \_ + --------------- + + +Since: 5.1.12 + +See also: [al_draw_glyph], [al_get_glyph_width], [al_get_glyph_dimensions]. + +## Multiline text drawing + +### API: al_draw_multiline_text + +Like [al_draw_text], but this function supports drawing multiple lines of text. +It will break `text` in lines based on its contents and the `max_width` +parameter. The lines are then layed out vertically depending on the +`line_height` parameter and drawn each as if [al_draw_text] was called +on them. + +A newline `\n` in the `text` will cause a "hard" line break after its +occurrence in the string. The text after a hard break is placed on a new line. +Carriage return `\r` is not supported, will not cause a line break, and will +likely be drawn as a square or a space depending on the font. + +The `max_width` parameter controls the maximum desired width of the lines. +This function will try to introduce a "soft" line break after the longest +possible series of words that will fit in `max_length` when drawn +with the given `font`. A "soft" line break can occur either on a space or +tab (`\t`) character. + +However, it is possible that `max_width` is too small, or the words in `text` +are too long to fit `max_width` when drawn with `font`. In that case, the word +that is too wide will simply be drawn completely on a line by itself. If you +don't want the text that overflows `max_width` to be visible, then use +[al_set_clipping_rectangle] to clip it off and hide it. + +The lines `text` was split into will each be drawn using the `font`, `x`, `color` +and `flags` parameters, vertically starting at `y` and with a distance of +`line_height` between them. If `line_height` is zero (`0`), the value returned by +calling [al_get_font_line_height] on `font` will be used as a default instead. + +The `flags` ALLEGRO_ALIGN_LEFT, ALLEGRO_ALIGN_CENTRE, ALLEGRO_ALIGN_RIGHT +and ALLEGRO_ALIGN_INTEGER will be honoured by this function. + +If you want to calculate the size of what this function will draw without actually +drawing it, or if you need a complex and/or custom layout, you can use [al_do_multiline_text]. + +Since: 5.1.9 + +See also: [al_do_multiline_text], [al_draw_multiline_ustr], +[al_draw_multiline_textf] + +### API: al_draw_multiline_ustr + +Like [al_draw_multiline_text], except the text is passed as an ALLEGRO_USTR +instead of a NUL-terminated char array. + +Since: 5.1.9 + +See also: [al_draw_multiline_text], [al_draw_multiline_textf], +[al_do_multiline_text] + +### API: al_draw_multiline_textf + +Formatted text output, using a printf() style format string. +All parameters have the same meaning as with [al_draw_multiline_text] otherwise. + +Since: 5.1.9 + +See also: [al_draw_multiline_text], [al_draw_multiline_ustr], +[al_do_multiline_text] + +### API: al_do_multiline_text + +This function processes the `text` and splits it into lines as +[al_draw_multiline_text] would, and then calls the callback `cb` once +for every line. This is useful for custom drawing of multiline text, +or for calculating the size of multiline text ahead of time. See the +documentation on [al_draw_multiline_text] for an explanation of the splitting +algorithm. + +For every line that this function splits `text` into the callback `cb` +will be called once with the following parameters: + +- `line_num` - the number of the line starting from zero and counting up +- `line` - a pointer to the beginning character of the line (see below) +- `size` - the size of the line (0 for empty lines) +- `extra` - the same pointer that was passed to al_do_multiline_text + +Note that `line` is *not* guaranteed to be a NUL-terminated string, but will merely +point to a character within `text` or to an empty string in case of an empty line. +If you need a NUL-terminated string, you will have to copy `line` to a buffer +and NUL-terminate it yourself. You will also have to make your own copy if you need +the contents of `line` after `cb` has returned, as `line` is *not* guaranteed to be +valid after that. + +If the callback `cb` returns false, al_do_multiline_text will stop immediately, otherwise +it will continue on to the next line. + +Since: 5.1.9 + +See also: [al_draw_multiline_text] + +### API: al_do_multiline_ustr + +Like [al_do_multiline_text], but using ALLEGRO_USTR instead of a +NUL-terminated char array for text. + +Since: 5.1.9 + +See also: [al_draw_multiline_ustr] + +## Bitmap fonts + +### API: al_grab_font_from_bitmap + +Creates a new font from an Allegro bitmap. You can delete the bitmap after the +function returns as the font will contain a copy for itself. + +Parameters: + +- bmp: The bitmap with the glyphs drawn onto it +- n: Number of unicode ranges in the bitmap. +- ranges: 'n' pairs of first and last unicode point to map glyphs to for + each range. + +The bitmap format is as in the following example, which contains three glyphs +for 1, 2 and 3. + + ............. + . 1 .222.333. + . 1 . 2. 3. + . 1 .222.333. + . 1 .2 . 3. + . 1 .222.333. + ............. + +In the above illustration, the dot is for pixels having the background color. It +is determined by the color of the top left pixel in the bitmap. There should be +a border of at least 1 pixel with this color to the bitmap edge and between all +glyphs. + +Each glyph is inside a rectangle of pixels not containing the background +color. The height of all glyph rectangles should be the same, but the width +can vary. + +The placement of the rectangles does not matter, except that glyphs are scanned +from left to right and top to bottom to match them to the specified unicode +codepoints. + +The glyphs will simply be drawn using [al_draw_bitmap], so usually you will want +the rectangles filled with full transparency and the glyphs drawn in opaque +white. + +Examples: + +~~~~c +int ranges[] = {32, 126}; +al_grab_font_from_bitmap(bitmap, 1, ranges) + +int ranges[] = { + 0x0020, 0x007F, /* ASCII */ + 0x00A1, 0x00FF, /* Latin 1 */ + 0x0100, 0x017F, /* Extended-A */ + 0x20AC, 0x20AC}; /* Euro */ +al_grab_font_from_bitmap(bitmap, 4, ranges) +~~~~ + +The first example will grab glyphs for the 95 standard printable ASCII +characters, beginning with the space character (32) and ending with the +tilde character (126). The second example will map the first 96 glyphs +found in the bitmap to ASCII range, the next 95 glyphs to Latin 1, the +next 128 glyphs to Extended-A, and the last glyph to the Euro character. +(This is just the characters found in the Allegro 4 font.) + +See also: [al_load_bitmap], [al_grab_font_from_bitmap] + +### API: al_load_bitmap_font + +Load a bitmap font from a file. This is done by first calling +[al_load_bitmap_flags] and then [al_grab_font_from_bitmap]. + +If you wanted to load an old A4 font, for example, it would be better to +load the bitmap yourself in order to call [al_convert_mask_to_alpha] on it +before passing it to [al_grab_font_from_bitmap]. + +See also: [al_load_bitmap_font_flags], [al_load_font], [al_load_bitmap_flags] + +### API: al_load_bitmap_font_flags + +Like [al_load_bitmap_font] but additionally takes a flags parameter +which is a bitfield containing a combination of the following: + +ALLEGRO_NO_PREMULTIPLIED_ALPHA +: The same meaning as for [al_load_bitmap_flags]. + +See also: [al_load_bitmap_font], [al_load_bitmap_flags] + +### API: al_create_builtin_font + +Creates a monochrome bitmap font (8x8 pixels per character). + +This font is primarily intended to be used for displaying information in +environments or during early runtime states where no external font data is +available or loaded (e.g. for debugging). + +The builtin font contains the following unicode character ranges: + + 0x0020 to 0x007F (ASCII) + 0x00A1 to 0x00FF (Latin 1) + 0x0100 to 0x017F (Extended A) + 0x20AC to 0x20AC (euro currency symbol) + +Returns NULL on an error. + +The font memory must be freed the same way as for any other font, +using [al_destroy_font]. + +Since: 5.0.8, 5.1.3 + +See also: [al_load_bitmap_font], [al_destroy_font] + +## TTF fonts + +These functions are declared in the following header file. +Link with allegro_ttf. + +~~~~c + #include +~~~~ + +### API: al_init_ttf_addon + +Call this after [al_init_font_addon] to make [al_load_font] recognize +".ttf" and other formats supported by [al_load_ttf_font]. + +Returns true on success, false on failure. + +### API: al_is_ttf_addon_initialized + +Returns true if the TTF addon is initialized, otherwise returns false. + +Since: 5.2.6 + +See also: [al_init_ttf_addon], [al_shutdown_ttf_addon] + +### API: al_shutdown_ttf_addon + +Unloads the ttf addon again. You normally don't need to call this. + +### API: al_load_ttf_font + +Loads a TrueType font from a file using the FreeType library. Quoting +from the FreeType FAQ this means support for many different font +formats: + +*TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and +others* + +The `size` parameter determines the size the font will be rendered at, +specified in pixels. The standard font size is measured in *units per +EM*, if you instead want to specify the size as the total height of +glyphs in pixels, pass it as a negative value. + +> *Note:* If you want to display text at multiple sizes, load the font +multiple times with different size parameters. + +The following flags are supported: + +* ALLEGRO_TTF_NO_KERNING - Do not use any kerning even if the font file + supports it. + +* ALLEGRO_TTF_MONOCHROME - Load as a monochrome font (which means no + anti-aliasing of the font is done). + +* ALLEGRO_TTF_NO_AUTOHINT - Disable the Auto Hinter which is enabled by default + in newer versions of FreeType. Since: 5.0.6, 5.1.2 + +See also: [al_init_ttf_addon], [al_load_ttf_font_f] + +### API: al_load_ttf_font_f + +Like [al_load_ttf_font], but the font is read from the file handle. The filename +is only used to find possible additional files next to a font file. + +> *Note:* The file handle is owned by the returned ALLEGRO_FONT object and must not +be freed by the caller, as FreeType expects to be able to read from it at a +later time. + +### API: al_load_ttf_font_stretch + +Like [al_load_ttf_font], except it takes separate width and height +parameters instead of a single size parameter. + +If the height is a positive value, and the width zero or positive, then font +will be stretched according to those parameters. The width must not be negative +if the height is positive. + +As with [al_load_ttf_font], the height may be a negative value to specify +the total height in pixels. Then the width must also be a negative value, or +zero. + +Returns `NULL` if the height is positive while width is negative, or if the +height is negative while the width is positive. + +Since: 5.0.6, 5.1.0 + +See also: [al_load_ttf_font], [al_load_ttf_font_stretch_f] + +### API: al_load_ttf_font_stretch_f + +Like [al_load_ttf_font_stretch], but the font is read from the file handle. The +filename is only used to find possible additional files next to a font file. + +> *Note:* The file handle is owned by the returned ALLEGRO_FONT object and must not +be freed by the caller, as FreeType expects to be able to read from it at a +later time. + +Since: 5.0.6, 5.1.0 + +See also: [al_load_ttf_font_stretch] + +### API: al_get_allegro_ttf_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. + +### API: al_get_glyph + +Gets all the information about a glyph, including the bitmap, needed to draw it +yourself. prev_codepoint is the codepoint in the string before the one you want +to draw and is used for kerning. codepoint is the character you want to get info +about. You should clear the 'glyph' structure to 0 with memset before passing it +to this function for future compatibility. + +Since: 5.2.1 + +> *[Unstable API]:* This API is new and subject to refinement. + +See also: [ALLEGRO_GLYPH] diff --git a/allegro/docs/src/refman/fshook.txt b/allegro/docs/src/refman/fshook.txt new file mode 100644 index 00000000..e1415909 --- /dev/null +++ b/allegro/docs/src/refman/fshook.txt @@ -0,0 +1,330 @@ +# File system routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +These functions allow access to the filesystem. This can either be the real +filesystem like your harddrive, or a virtual filesystem like a .zip archive (or +whatever else you or an addon makes it do). + +## API: ALLEGRO_FS_ENTRY + +Opaque filesystem entry object. +Represents a file or a directory (check with [al_get_fs_entry_mode]). +There are no user accessible member variables. + +## API: ALLEGRO_FILE_MODE + +Filesystem modes/types + +* ALLEGRO_FILEMODE_READ - Readable +* ALLEGRO_FILEMODE_WRITE - Writable +* ALLEGRO_FILEMODE_EXECUTE - Executable +* ALLEGRO_FILEMODE_HIDDEN - Hidden +* ALLEGRO_FILEMODE_ISFILE - Regular file +* ALLEGRO_FILEMODE_ISDIR - Directory + +## API: al_create_fs_entry + +Creates an [ALLEGRO_FS_ENTRY] object pointing to path on the filesystem. +'path' can be a file or a directory and must not be NULL. + +## API: al_destroy_fs_entry + +Destroys a fs entry handle. The file or directory represented by it is not +destroyed. If the entry was opened, it is closed before being destroyed. + +Does nothing if passed NULL. + +## API: al_get_fs_entry_name + +Returns the entry's filename path. +Note that the filesystem encoding may not be known and the conversion to UTF-8 +could in very rare cases cause this to return an invalid path. Therefore it's +always safest to access the file over its [ALLEGRO_FS_ENTRY] and not the path. + +On success returns a read only string which you must not modify or +destroy. Returns NULL on failure. + +> Note: prior to 5.1.5 it was written: "... the path will not be an absolute +path if the entry wasn't created from an absolute path". This is no longer +true. + +## API: al_update_fs_entry + +Updates file status information for a filesystem entry. +File status information is automatically updated when the entry is created, +however you may update it again with this function, e.g. in case it changed. + +Returns true on success, false on failure. +Fills in errno to indicate the error. + +See also: [al_get_errno], [al_get_fs_entry_atime], [al_get_fs_entry_ctime], +[al_get_fs_entry_mode] + +## API: al_get_fs_entry_mode + +Returns the entry's mode flags, i.e. permissions and whether the entry +refers to a file or directory. + +See also: [al_get_errno], [ALLEGRO_FILE_MODE] + +## API: al_get_fs_entry_atime + +Returns the time in seconds since the epoch since the entry was last +accessed. + +Warning: some filesystems either don't support this flag, or people turn it +off to increase performance. +It may not be valid in all circumstances. + +See also: [al_get_fs_entry_ctime], [al_get_fs_entry_mtime], +[al_update_fs_entry] + +## API: al_get_fs_entry_ctime + +Returns the time in seconds since the epoch this entry was created on the +filesystem. + +See also: [al_get_fs_entry_atime], [al_get_fs_entry_mtime], +[al_update_fs_entry] + +## API: al_get_fs_entry_mtime + +Returns the time in seconds since the epoch since the entry was last +modified. + +See also: [al_get_fs_entry_atime], [al_get_fs_entry_ctime], +[al_update_fs_entry] + +## API: al_get_fs_entry_size + +Returns the size, in bytes, of the given entry. +May not return anything sensible for a directory entry. + +See also: [al_update_fs_entry] + +## API: al_fs_entry_exists + +Check if the given entry exists on in the filesystem. +Returns true if it does exist or false if it doesn't exist, or an error occurred. +Error is indicated in Allegro's errno. + +See also: [al_filename_exists] + +## API: al_remove_fs_entry + +Delete this filesystem entry from the filesystem. Only files and empty +directories may be deleted. + +Returns true on success, and false on failure, error is indicated in Allegro's +errno. + +See also: [al_filename_exists] + +## API: al_filename_exists + +Check if the path exists on the filesystem, without creating an +[ALLEGRO_FS_ENTRY] object explicitly. + +See also: [al_fs_entry_exists] + +## API: al_remove_filename + +Delete the given path from the filesystem, which may be a file or an empty +directory. This is the same as [al_remove_fs_entry], except it expects the +path as a string. + +Returns true on success, and false on failure. +Allegro's errno is filled in to indicate the error. + +See also: [al_remove_fs_entry] + +## Directory functions + +### API: al_open_directory + +Opens a directory entry object. You must call this before using [al_read_directory] +on an entry and you must call [al_close_directory] when you no longer need it. + +Returns true on success. + +See also: [al_read_directory], [al_close_directory] + +### API: al_read_directory + +Reads the next directory item and returns a filesystem entry for it. + +Returns NULL if there are no more entries or if an error occurs. Call +[al_destroy_fs_entry] on the returned entry when you are done with it. + +This function will ignore any files or directories named `.` or `..` which may +exist on certain platforms and may signify the current and the parent directory. + +See also: [al_open_directory], [al_close_directory] + +### API: al_close_directory + +Closes a previously opened directory entry object. + +Returns true on success, false on failure and fills in Allegro's errno to +indicate the error. + +See also: [al_open_directory], [al_read_directory] + +### API: al_get_current_directory + +Returns the path to the current working directory, or NULL on failure. +The returned path is dynamically allocated and must be destroyed with +[al_free]. + +Allegro's errno is filled in to indicate the error if there is a failure. +This function may not be implemented on some (virtual) filesystems. + +See also: [al_get_errno], [al_free] + +### API: al_change_directory + +Changes the current working directory to 'path'. + +Returns true on success, false on error. + +### API: al_make_directory + +Creates a new directory on the filesystem. This function also creates any +parent directories as needed. + +Returns true on success (including if the directory already exists), otherwise +returns false on error. Fills in Allegro's errno to indicate the error. + +See also: [al_get_errno] + +### API: al_open_fs_entry + +Open an [ALLEGRO_FILE] handle to a filesystem entry, for the given access mode. +This is like calling [al_fopen] with the name of the filesystem entry, but uses +the appropriate file interface, not whatever was set with the latest call to +[al_set_new_file_interface]. + +Returns the handle on success, NULL on error. + +See also: [al_fopen] + +### API: ALLEGRO_FOR_EACH_FS_ENTRY_RESULT + +Return values for the callbacks of [al_for_each_fs_entry] and +for that function itself. + +* ALLEGRO_FOR_EACH_FS_ENTRY_ERROR - An error ocurred. +* ALLEGRO_FOR_EACH_FS_ENTRY_OK - Continue normally and recurse into directories. +* ALLEGRO_FOR_EACH_FS_ENTRY_SKIP - Continue but do NOT recusively descend. +* ALLEGRO_FOR_EACH_FS_ENTRY_STOP - Stop iterating and return. + +See also: [al_for_each_fs_entry] + +Since: 5.1.9 + +### API: al_for_each_fs_entry + +This function takes the [ALLEGRO_FS_ENTRY] `dir`, which should +represent a directory, and looks for any other file system entries +that are in it. This function will then call the callback function `callback` +once for every filesystem entry in the directory `dir`. + +The callback `callback` must be of type `int callback(ALLEGRO_FS_ENTRY * +entry, void * extra)`. The `callback` will be called with a pointer +to an [ALLEGRO_FS_ENTRY] that matches one file or directory in `dir`, +and the pointer passed in the `extra` parameter to [al_for_each_fs_entry]. + +When `callback` returns `ALLEGRO_FOR_EACH_FS_ENTRY_STOP` or +`ALLEGRO_FOR_EACH_FS_ENTRY_ERROR`, iteration will stop immediately +and [al_for_each_fs_entry] will return the value the `callback` returned. + +When `callback` returns `ALLEGRO_FOR_EACH_FS_ENTRY_OK` iteration will continue +normally, and if the [ALLEGRO_FS_ENTRY] parameter of `callback` +is a directory, [al_for_each_fs_entry] will call itself +on that directory. Therefore the function will recusively descend into that +directory. + +However, when `callback` returns `ALLEGRO_FOR_EACH_FS_ENTRY_SKIP` iteration +will continue, but [al_for_each_fs_entry] will NOT recurse into the +[ALLEGRO_FS_ENTRY] parameter of `callback` even if it is a directory. + +This function will skip any files or directories named `.` or `..` +which may exist on certain platforms and may signify the current and the +parent directory. The `callback` will not be called for files +or directories with such a name. + +Returns ALLEGRO_FOR_EACH_FS_ENTRY_OK if successful, or +ALLEGRO_FOR_EACH_FS_ENTRY_ERROR if something went wrong in +processing the directory. In that case it will use [al_set_errno] to indicate +the type of error which occurred. This function returns +ALLEGRO_FOR_EACH_FS_ENTRY_STOP in case iteration was stopped by making +`callback` return that value. In this case, [al_set_errno] will not be used. + +See also: [ALLEGRO_FOR_EACH_FS_ENTRY_RESULT] + +Since: 5.1.9 + +## Alternative filesystem functions + +By default, Allegro uses platform specific filesystem functions for things like +directory access. However if for example the files of your game are not in +the local filesystem but inside some file archive, you can provide your own +set of functions (or use an addon which does this for you, for example our +physfs addon allows access to the most common archive formats). + +### API: ALLEGRO_FS_INTERFACE + +The available functions you can provide for a filesystem. They are: + +~~~ + ALLEGRO_FS_ENTRY * fs_create_entry (const char *path); + void fs_destroy_entry (ALLEGRO_FS_ENTRY *e); + const char * fs_entry_name (ALLEGRO_FS_ENTRY *e); + bool fs_update_entry (ALLEGRO_FS_ENTRY *e); + uint32_t fs_entry_mode (ALLEGRO_FS_ENTRY *e); + time_t fs_entry_atime (ALLEGRO_FS_ENTRY *e); + time_t fs_entry_mtime (ALLEGRO_FS_ENTRY *e); + time_t fs_entry_ctime (ALLEGRO_FS_ENTRY *e); + off_t fs_entry_size (ALLEGRO_FS_ENTRY *e); + bool fs_entry_exists (ALLEGRO_FS_ENTRY *e); + bool fs_remove_entry (ALLEGRO_FS_ENTRY *e); + + bool fs_open_directory (ALLEGRO_FS_ENTRY *e); + ALLEGRO_FS_ENTRY * fs_read_directory (ALLEGRO_FS_ENTRY *e); + bool fs_close_directory(ALLEGRO_FS_ENTRY *e); + + bool fs_filename_exists(const char *path); + bool fs_remove_filename(const char *path); + char * fs_get_current_directory(void); + bool fs_change_directory(const char *path); + bool fs_make_directory(const char *path); + + ALLEGRO_FILE * fs_open_file(ALLEGRO_FS_ENTRY *e); +~~~ + +### API: al_set_fs_interface + +Set the [ALLEGRO_FS_INTERFACE] table for the calling thread. + +See also: [al_set_standard_fs_interface], [al_store_state], +[al_restore_state]. + +### API: al_set_standard_fs_interface + +Return the [ALLEGRO_FS_INTERFACE] table to the default, for the calling +thread. + +See also: [al_set_fs_interface]. + +### API: al_get_fs_interface + +Return a pointer to the [ALLEGRO_FS_INTERFACE] table in effect +for the calling thread. + +See also: [al_store_state], [al_restore_state]. + diff --git a/allegro/docs/src/refman/fullscreen_mode.txt b/allegro/docs/src/refman/fullscreen_mode.txt new file mode 100644 index 00000000..9a0d7dd0 --- /dev/null +++ b/allegro/docs/src/refman/fullscreen_mode.txt @@ -0,0 +1,50 @@ +# Fullscreen modes + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_DISPLAY_MODE + +Used for fullscreen mode queries. Contains information +about a supported fullscreen modes. + +~~~~c +typedef struct ALLEGRO_DISPLAY_MODE { + int width; // Screen width + int height; // Screen height + int format; // The pixel format of the mode + int refresh_rate; // The refresh rate of the mode +} ALLEGRO_DISPLAY_MODE; +~~~~ + +The `refresh_rate` may be zero if unknown. + +For an explanation of what `format` means, see [ALLEGRO_PIXEL_FORMAT]. + +See also: [al_get_display_mode] + +## API: al_get_display_mode + +Retrieves a fullscreen mode. Display parameters should not be +changed between a call of [al_get_num_display_modes] and +[al_get_display_mode]. index must be between 0 and the number +returned from al_get_num_display_modes-1. mode must be an +allocated ALLEGRO_DISPLAY_MODE structure. This function will +return NULL on failure, and the mode parameter that was passed +in on success. + +See also: [ALLEGRO_DISPLAY_MODE], [al_get_num_display_modes] + +## API: al_get_num_display_modes + +Get the number of available fullscreen display modes +for the current set of display parameters. This will +use the values set with [al_set_new_display_refresh_rate], +and [al_set_new_display_flags] to find the number of modes +that match. Settings the new display parameters to zero will +give a list of all modes for the default driver. + +See also: [al_get_display_mode] diff --git a/allegro/docs/src/refman/getting_started.txt b/allegro/docs/src/refman/getting_started.txt new file mode 100644 index 00000000..59db7aa8 --- /dev/null +++ b/allegro/docs/src/refman/getting_started.txt @@ -0,0 +1,196 @@ +# Getting started guide + +## Introduction + +Welcome to Allegro 5! + +This short guide should point you at the parts of the API that you'll +want to know about first. It's not a tutorial, as there isn't much +discussion, only links into the manual. The rest you'll have to discover for +yourself. Read the examples, and ask questions at [Allegro.cc]. + +There is an unofficial tutorial at [the wiki]. Be aware that, being on +the wiki, it may be a little out of date, but the changes should be +minor. Hopefully more will sprout when things stabilise, as they did for +earlier versions of Allegro. + +## Structure of the library and its addons + +Allegro 5.0 is divided into a core library and multiple addons. The addons +are bundled together and built at the same time as the core, but they are +distinct and kept in separate libraries. The core doesn't depend on anything +in the addons, but addons may depend on the core and other addons and +additional third party libraries. + +Here are the addons and their dependencies: + + allegro_main -> allegro + + allegro_image -> allegro + allegro_primitives -> allegro + allegro_color -> allegro + + allegro_font -> allegro + allegro_ttf -> allegro_font -> allegro + + allegro_audio -> allegro + allegro_acodec -> allegro_audio -> allegro + allegro_video -> allegro_audio -> allegro + + allegro_memfile -> allegro + allegro_physfs -> allegro + + allegro_native_dialog -> allegro + +The header file for the core library is `allegro5/allegro.h`. The header +files for the addons are named `allegro5/allegro_image.h`, `allegro5/allegro_font.h`, +etc. The allegro_main addon does not have a header file. + +## The main function + +For the purposes of cross-platform compatibility Allegro puts some requirements +on your main function. First, you must include the core header +(`allegro5/allegro.h`) in the same file as your main function. Second, if your +main function is inside a C++ file, then it must have this signature: +`int main(int argc, char **argv)`. Third, if you're using C/C++ then you need +to link with the allegro_main addon when building your program. + +## Initialisation + +Before using Allegro you must call [al_init]. Some addons have their own +initialisation, e.g. [al_init_image_addon], [al_init_font_addon], +[al_init_ttf_addon]. + +To receive input, you need to initialise some subsystems like +[al_install_keyboard], [al_install_mouse], [al_install_joystick]. + +## Opening a window + +[al_create_display] will open a window and return an [ALLEGRO_DISPLAY]. + +To clear the display, call [al_clear_to_color]. Use [al_map_rgba] or +[al_map_rgba_f] to obtain an [ALLEGRO_COLOR] parameter. + +Drawing operations are performed on a backbuffer. To make the operations +visible, call [al_flip_display]. + +## Display an image + +To load an image from disk, you need to have initialised the image I/O +addon with [al_init_image_addon]. Then use [al_load_bitmap], which returns an +[ALLEGRO_BITMAP]. + +Use [al_draw_bitmap], [al_draw_scaled_bitmap] or +[al_draw_scaled_rotated_bitmap] to draw the image to the backbuffer. +Remember to call [al_flip_display]. + +## Changing the drawing target + +Notice that [al_clear_to_color] and [al_draw_bitmap] didn't take destination +parameters: the destination is implicit. Allegro remembers the current +"target bitmap" for the current thread. To change the target bitmap, call +[al_set_target_bitmap]. + +The backbuffer of the display is also a bitmap. You can get it with +[al_get_backbuffer] and then restore it as the target bitmap. + +Other bitmaps can be created with [al_create_bitmap], with options which can +be adjusted with [al_set_new_bitmap_flags] and [al_set_new_bitmap_format]. + +## Event queues and input + +Input comes from multiple sources: keyboard, mouse, joystick, timers, etc. +Event queues aggregate events from all these sources, then you can query +the queue for events. + +Create an event queue with [al_create_event_queue], then tell input sources +to place new events into that queue using [al_register_event_source]. The +usual input event sources can be retrieved with [al_get_keyboard_event_source], +[al_get_mouse_event_source] and [al_get_joystick_event_source]. + +Events can be retrieved with [al_wait_for_event] or [al_get_next_event]. +Check the event type and other fields of [ALLEGRO_EVENT] to react to the +input. + +Displays are also event sources, which emit events when they are resized. +You'll need to set the ALLEGRO_RESIZABLE flag with [al_set_new_display_flags] +before creating the display, then register the display with an event queue. +When you get a resize event, call [al_acknowledge_resize]. + +Timers are event sources which "tick" periodically, causing an event to be +inserted into the queues that the timer is registered with. Create some with +[al_create_timer]. + +[al_get_time] and [al_rest] are more direct ways to deal with time. + +## Displaying some text + +To display some text, initialise the image and font addons with +[al_init_image_addon] and [al_init_font_addon], then load a bitmap font with +[al_load_font]. Use [al_draw_text] or [al_draw_textf]. + +For TrueType fonts, you'll need to initialise the TTF font addon with +[al_init_ttf_addon] and load a TTF font with [al_load_ttf_font]. + +## Drawing primitives + +The primitives addon provides some handy routines to draw lines +([al_draw_line]), rectangles ([al_draw_rectangle]), circles +([al_draw_circle]), etc. + +## Blending + +To draw translucent or tinted images or primitives, change the blender state +with [al_set_blender]. + +As with [al_set_target_bitmap], this changes Allegro's internal state (for +the current thread). Often you'll want to save some part of the state and +restore it later. The functions [al_store_state] and [al_restore_state] +provide a convenient way to do that. + +## Sound + +Use [al_install_audio] to initialize sound. To load any sample formats, you +will need to initialise the acodec addon with [al_init_acodec_addon]. + +After that, you can simply use [al_reserve_samples] and pass the number of +sound effects typically playing at the same time. Then load your sound effects +with [al_load_sample] and play them with [al_play_sample]. To stream large +pieces of music from disk, you can use [al_load_audio_stream] so the whole piece +will not have to be pre-loaded into memory. + +If the above sounds too simple and you can't help but think about clipping and +latency issues, don't worry. Allegro gives you full control over how much or +little you want its sound system to do. The [al_reserve_samples] function +mentioned above only sets up a default mixer and a number of sample instances +but you don't need to use it. + +Instead, to get a "direct connection" to the sound system you would use an +[ALLEGRO_VOICE] (but depending on the platform only one such voice is guaranteed +to be available and it might require a specific format of audio data). Therefore +all sound can be first routed through an [ALLEGRO_MIXER] which is connected to +such a voice (or another mixer) and will mix together all sample data fed to it. + +You can then directly stream real-time sample data to a mixer or a voice using +an [ALLEGRO_AUDIO_STREAM] or play complete sounds using an [ALLEGRO_SAMPLE_INSTANCE]. +The latter simply points to an [ALLEGRO_SAMPLE] and will stream it for you. + +## Unstable API + +Some of Allegro's API is marked as unstable, which means that in future versions +of Allegro it may change or even be removed entirely! If you want to experiment +with the unstable API, define `ALLEGRO_UNSTABLE` macro before including Allegro's +headers. + +Note that when you define that macro, the version check performed by +[al_install_system] and [al_init] becomes more scrict. See documentation of +those functions for details. + +## Not the end + +There's a heap of stuff we haven't even mentioned yet. + +Enjoy! + +[Allegro.cc]: http://www.allegro.cc/forums/ +[the wiki]: http://wiki.allegro.cc/ diff --git a/allegro/docs/src/refman/graphics.txt b/allegro/docs/src/refman/graphics.txt new file mode 100644 index 00000000..d1b9e0ce --- /dev/null +++ b/allegro/docs/src/refman/graphics.txt @@ -0,0 +1,2037 @@ +# Graphics routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## Colors + +### API: ALLEGRO_COLOR + +An ALLEGRO_COLOR structure describes a color in a device +independent way. Use [al_map_rgb] et al. and [al_unmap_rgb] et al. to +translate from and to various color representations. + +### API: al_map_rgb + +Convert r, g, b (ranging from 0-255) into an [ALLEGRO_COLOR], +using 255 for alpha. + +This function can be called before Allegro is initialized. + +See also: [al_map_rgba], [al_map_rgba_f], [al_map_rgb_f] + +### API: al_map_rgb_f + +Convert r, g, b, (ranging from 0.0f-1.0f) into an [ALLEGRO_COLOR], +using 1.0f for alpha. + +This function can be called before Allegro is initialized. + +See also: [al_map_rgba], [al_map_rgb], [al_map_rgba_f] + +### API: al_map_rgba + +Convert r, g, b, a (ranging from 0-255) into an [ALLEGRO_COLOR]. + +This function can be called before Allegro is initialized. + +See also: [al_map_rgb], [al_premul_rgba], [al_map_rgb_f] + +### API: al_premul_rgba + +This is a shortcut for [al_map_rgba]\(r * a / 255, g * a / 255, b * a / 255, a). + +By default Allegro uses pre-multiplied alpha for transparent blending of +bitmaps and primitives (see [al_load_bitmap_flags] for a discussion of that +feature). This means that if you want to tint a bitmap or primitive to be +transparent you need to multiply the color components by the alpha components +when you pass them to this function. For example: + +~~~~c +int r = 255; +int g = 0; +int b = 0; +int a = 127; +ALLEGRO_COLOR c = al_premul_rgba(r, g, b, a); +/* Draw the bitmap tinted red and half-transparent. */ +al_draw_tinted_bitmap(bmp, c, 0, 0, 0); +~~~~ + +This function can be called before Allegro is initialized. + +Since: 5.1.12 + +See also: [al_map_rgba], [al_premul_rgba_f] + +### API: al_map_rgba_f + +Convert r, g, b, a (ranging from 0.0f-1.0f) into an [ALLEGRO_COLOR]. + +This function can be called before Allegro is initialized. + +See also: [al_map_rgba], [al_premul_rgba_f], [al_map_rgb_f] + +### API: al_premul_rgba_f + +This is a shortcut for [al_map_rgba_f]\(r * a, g * a, b * a, a). + +By default Allegro uses pre-multiplied alpha for transparent blending of +bitmaps and primitives (see [al_load_bitmap_flags] for a discussion of that +feature). This means that if you want to tint a bitmap or primitive to be +transparent you need to multiply the color components by the alpha components +when you pass them to this function. For example: + +~~~~c +float r = 1; +float g = 0; +float b = 0; +float a = 0.5; +ALLEGRO_COLOR c = al_premul_rgba_f(r, g, b, a); +/* Draw the bitmap tinted red and half-transparent. */ +al_draw_tinted_bitmap(bmp, c, 0, 0, 0); +~~~~ + +This function can be called before Allegro is initialized. + +Since: 5.1.12 + +See also: [al_map_rgba_f], [al_premul_rgba] + +### API: al_unmap_rgb + +Retrieves components of an ALLEGRO_COLOR, ignoring alpha. +Components will range from 0-255. + +This function can be called before Allegro is initialized. + +See also: [al_unmap_rgba], [al_unmap_rgba_f], [al_unmap_rgb_f] + +### API: al_unmap_rgb_f + +Retrieves components of an [ALLEGRO_COLOR], ignoring alpha. +Components will range from 0.0f-1.0f. + +This function can be called before Allegro is initialized. + +See also: [al_unmap_rgba], [al_unmap_rgb], [al_unmap_rgba_f] + +### API: al_unmap_rgba + +Retrieves components of an [ALLEGRO_COLOR]. +Components will range from 0-255. + +This function can be called before Allegro is initialized. + +See also: [al_unmap_rgb], [al_unmap_rgba_f], [al_unmap_rgb_f] + +### API: al_unmap_rgba_f + +Retrieves components of an [ALLEGRO_COLOR]. +Components will range from 0.0f-1.0f. + +This function can be called before Allegro is initialized. + +See also: [al_unmap_rgba], [al_unmap_rgb], [al_unmap_rgb_f] + + + +## Locking and pixel formats + +### API: ALLEGRO_LOCKED_REGION + +Users who wish to manually edit or read from a bitmap +are required to lock it first. The ALLEGRO_LOCKED_REGION +structure represents the locked region of the bitmap. This +call will work with any bitmap, including memory bitmaps. + +~~~~c +typedef struct ALLEGRO_LOCKED_REGION { + void *data; + int format; + int pitch; + int pixel_size; +} ALLEGRO_LOCKED_REGION; +~~~~ + +- *data* points to the leftmost pixel of the first row (row 0) of the locked + region. For blocked formats, this points to the leftmost block of the first + row of blocks. + +- *format* indicates the pixel format of the data. + +- *pitch* gives the size in bytes of a single row (also known as the stride). + The pitch may be greater than `width * pixel_size` due to padding; this is + not uncommon. It is also *not* uncommon for the pitch to be negative (the + bitmap may be upside down). For blocked formats, 'row' refers to the row of + blocks, not of pixels. + +- *pixel_size* is the number of bytes used to represent a single block of + pixels for the pixel format of this locked region. For most formats (and + historically, this used to be true for all formats), this is just the size of + a single pixel, but for blocked pixel formats this value is different. + +See also: [al_lock_bitmap], [al_lock_bitmap_region], [al_unlock_bitmap], +[ALLEGRO_PIXEL_FORMAT] + +### API: ALLEGRO_PIXEL_FORMAT + +Pixel formats. Each pixel format specifies the exact size and bit +layout of a pixel in memory. Components are specified from high bits +to low bits, so for example a fully opaque red pixel in ARGB_8888 format +is 0xFFFF0000. + +> *Note:* +> +> The pixel format is independent of endianness. That is, in the above +> example you can always get the red component with +> +> ~~~~c +> (pixel & 0x00ff0000) >> 16 +> ~~~~ +> +> But you can *not* rely on this code: +> +> ~~~~c +> *(pixel + 2) +> ~~~~ +> +> It will return the red component on little endian systems, but the +> green component on big endian systems. + +Also note that Allegro's naming is different from OpenGL naming here, +where a format of GL_RGBA8 merely defines the component order and the +exact layout including endianness treatment is specified separately. +Usually GL_RGBA8 will correspond to ALLEGRO_PIXEL_ABGR_8888 though on +little endian systems, so care must be taken (note the reversal of +RGBA <-> ABGR). + +The only exception to this ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE which will always +have the components as 4 bytes corresponding to red, green, blue and alpha, +in this order, independent of the endianness. + +Some of the pixel formats represent compressed bitmap formats. Compressed +bitmaps take up less space in the GPU memory than bitmaps with regular +(uncompressed) pixel formats. This smaller footprint means that you can load +more resources into GPU memory, and they will be drawn somewhat faster. The +compression is lossy, however, so it is not appropriate for all graphical +styles: it tends to work best for images with smooth color gradations. It is +possible to compress bitmaps at runtime by passing the appropriate bitmap +format in `al_set_new_bitmap_format` and then creating, loading, cloning or +converting a non-compressed bitmap. This, however, is not recommended as the +compression quality differs between different GPU drivers. It is recommended to +compress these bitmaps ahead of time using external tools and then load them +compressed. + +Unlike regular pixel formats, compressed pixel formats are not laid out in +memory one pixel row at a time. Instead, the bitmap is subdivided into rectangular +blocks of pixels that are then laid out in block rows. This means that regular +locking functions cannot use compressed pixel formats as the destination +format. Instead, you can use the blocked versions of the bitmap locking +functions which do support these formats. + +It is not recommended to use compressed bitmaps as target bitmaps, as that +operation cannot be hardware accelerated. Due to proprietary algorithms used, it +is typically impossible to create compressed memory bitmaps. + +* ALLEGRO_PIXEL_FORMAT_ANY - + Let the driver choose a format. This is the default format at program start. +* ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA - + Let the driver choose a format without alpha. +* ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA - + Let the driver choose a format with alpha. +* ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA - + Let the driver choose a 15 bit format without alpha. +* ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA - + Let the driver choose a 16 bit format without alpha. +* ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA - + Let the driver choose a 16 bit format with alpha. +* ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA - + Let the driver choose a 24 bit format without alpha. +* ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA - + Let the driver choose a 32 bit format without alpha. +* ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA - + Let the driver choose a 32 bit format with alpha. +* ALLEGRO_PIXEL_FORMAT_ARGB_8888 - 32 bit +* ALLEGRO_PIXEL_FORMAT_RGBA_8888 - 32 bit +* ALLEGRO_PIXEL_FORMAT_ARGB_4444 - 16 bit +* ALLEGRO_PIXEL_FORMAT_RGB_888 - 24 bit +* ALLEGRO_PIXEL_FORMAT_RGB_565 - 16 bit +* ALLEGRO_PIXEL_FORMAT_RGB_555 - 15 bit +* ALLEGRO_PIXEL_FORMAT_RGBA_5551 - 16 bit +* ALLEGRO_PIXEL_FORMAT_ARGB_1555 - 16 bit +* ALLEGRO_PIXEL_FORMAT_ABGR_8888 - 32 bit +* ALLEGRO_PIXEL_FORMAT_XBGR_8888 - 32 bit +* ALLEGRO_PIXEL_FORMAT_BGR_888 - 24 bit +* ALLEGRO_PIXEL_FORMAT_BGR_565 - 16 bit +* ALLEGRO_PIXEL_FORMAT_BGR_555 - 15 bit +* ALLEGRO_PIXEL_FORMAT_RGBX_8888 - 32 bit +* ALLEGRO_PIXEL_FORMAT_XRGB_8888 - 32 bit +* ALLEGRO_PIXEL_FORMAT_ABGR_F32 - 128 bit +* ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE - + Like the version without _LE, but the component order is guaranteed to be + red, green, blue, alpha. This only makes a difference on big endian + systems, on little endian it is just an alias. +* ALLEGRO_PIXEL_FORMAT_RGBA_4444 - 16bit +* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 - + A single 8-bit channel. A pixel value maps onto the red channel when + displayed, but it is undefined how it maps onto green, blue and alpha + channels. When drawing to bitmaps of this format, only the red channel is + taken into account. Allegro may have to use fallback methods to render to + bitmaps of this format. This pixel format is mainly intended for storing + the color indices of an indexed (paletted) image, usually in conjunction + with a pixel shader that maps indices to RGBA values. Since 5.1.2. +* ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1 - + Compressed using the DXT1 compression algorithm. Each 4x4 pixel block is + encoded in 64 bytes, resulting in 6-8x compression ratio. Only a single bit + of alpha per pixel is supported. Since 5.1.9. +* ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3 - + Compressed using the DXT3 compression algorithm. Each 4x4 pixel block is + encoded in 128 bytes, resulting in 4x compression ratio. This format + supports sharp alpha transitions. Since 5.1.9. +* ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5 - + Compressed using the DXT5 compression algorithm. Each 4x4 pixel block is + encoded in 128 bytes, resulting in 4x compression ratio. This format + supports smooth alpha transitions. Since 5.1.9. + +See also: [al_set_new_bitmap_format], [al_get_bitmap_format] + +### API: al_get_pixel_size + +Return the number of bytes that a pixel of the given format occupies. For +blocked pixel formats (e.g. compressed formats), this returns 0. + +See also: [ALLEGRO_PIXEL_FORMAT], [al_get_pixel_format_bits] + +### API: al_get_pixel_format_bits + +Return the number of bits that a pixel of the given format occupies. For +blocked pixel formats (e.g. compressed formats), this returns 0. + +See also: [ALLEGRO_PIXEL_FORMAT], [al_get_pixel_size] + +### API: al_get_pixel_block_size + +Return the number of bytes that a block of pixels with this format occupies. + +Since: 5.1.9. + +See also: [ALLEGRO_PIXEL_FORMAT], [al_get_pixel_block_width], [al_get_pixel_block_height] + +### API: al_get_pixel_block_width + +Return the width of the the pixel block for this format. + +Since: 5.1.9. + +See also: [ALLEGRO_PIXEL_FORMAT], [al_get_pixel_block_size], [al_get_pixel_block_height] + +### API: al_get_pixel_block_height + +Return the height of the the pixel block for this format. + +Since: 5.1.9. + +See also: [ALLEGRO_PIXEL_FORMAT], [al_get_pixel_block_size], [al_get_pixel_block_width] + +### API: al_lock_bitmap + +Lock an entire bitmap for reading or writing. If the bitmap is a +display bitmap it will be updated from system memory after the bitmap +is unlocked (unless locked read only). Returns NULL if the bitmap cannot +be locked, e.g. the bitmap was locked previously and not unlocked. This +function also returns NULL if the `format` is a compressed format. + +Flags are: + +* ALLEGRO_LOCK_READONLY - The locked region will not be written to. This can +be faster if the bitmap is a video texture, as it can be discarded after +the lock instead of uploaded back to the card. + +* ALLEGRO_LOCK_WRITEONLY - The locked region will not be read from. This can +be faster if the bitmap is a video texture, as no data need to be read +from the video card. You are required to fill in all pixels before +unlocking the bitmap again, so be careful when using this flag. + +* ALLEGRO_LOCK_READWRITE - The locked region can be written to and read from. +Use this flag if a partial number of pixels need to be written to, even if +reading is not needed. + +`format` indicates the pixel format that the returned buffer will be in. +To lock in the same format as the bitmap stores its data internally, +call with `al_get_bitmap_format(bitmap)` as the format or use +ALLEGRO_PIXEL_FORMAT_ANY. Locking in the native format will usually be faster. +If the bitmap format is compressed, using ALLEGRO_PIXEL_FORMAT_ANY will choose +an implementation defined non-compressed format. + +On some platforms, Allegro automatically backs up the contents of video bitmaps +because they may be occasionally lost (see discussion in [al_create_bitmap]'s +documentation). If you're completely recreating the bitmap contents often (e.g. +every frame) then you will get much better performance by creating the target +bitmap with ALLEGRO_NO_PRESERVE_TEXTURE flag. + +> *Note:* While a bitmap is locked, you can not use any drawing operations +on it (with the sole exception of [al_put_pixel] and +[al_put_blended_pixel]). + +See also: [ALLEGRO_LOCKED_REGION], [ALLEGRO_PIXEL_FORMAT], +[al_unlock_bitmap], [al_lock_bitmap_region], [al_lock_bitmap_blocked], +[al_lock_bitmap_region_blocked] + +### API: al_lock_bitmap_region + +Like [al_lock_bitmap], but only locks a specific area of the bitmap. +If the bitmap is a video bitmap, only that area of the texture will +be updated when it is unlocked. Locking only the region you indend to +modify will be faster than locking the whole bitmap. + +> *Note:* Using the ALLEGRO_LOCK_WRITEONLY with a blocked pixel format +(i.e. formats for which [al_get_pixel_block_width] or +[al_get_pixel_block_height] do not return 1) requires you to have the +region be aligned to the block width for optimal performance. If it is +not, then the function will have to lock the region with the +ALLEGRO_LOCK_READWRITE instead in order to pad this region with valid +data. + +See also: [ALLEGRO_LOCKED_REGION], [ALLEGRO_PIXEL_FORMAT], [al_unlock_bitmap] + +### API: al_unlock_bitmap + +Unlock a previously locked bitmap or bitmap region. If the bitmap +is a video bitmap, the texture will be updated to match the system +memory copy (unless it was locked read only). + +See also: [al_lock_bitmap], [al_lock_bitmap_region], [al_lock_bitmap_blocked], +[al_lock_bitmap_region_blocked] + +### API: al_lock_bitmap_blocked + +Like [al_lock_bitmap], but allows locking bitmaps with a blocked pixel +format (i.e. a format for which [al_get_pixel_block_width] or +[al_get_pixel_block_height] do not return 1) in that format. To that +end, this function also does not allow format conversion. For bitmap +formats with a block size of 1, this function is identical to calling +`al_lock_bitmap(bmp, al_get_bitmap_format(bmp), flags)`. + +> *Note:* Currently there are no drawing functions that work when the bitmap is +locked with a compressed format. [al_get_pixel] will also not work. + +Since: 5.1.9 + +See also: [al_lock_bitmap], [al_lock_bitmap_region_blocked] + +### API: al_lock_bitmap_region_blocked + +Like [al_lock_bitmap_blocked], but allows locking a sub-region, for performance. +Unlike [al_lock_bitmap_region] the region specified in terms of blocks and not +pixels. + +Since: 5.1.9 + +See also: [al_lock_bitmap_region], [al_lock_bitmap_blocked] + +## Bitmap creation + +### API: ALLEGRO_BITMAP + +Abstract type representing a bitmap (2D image). + +### API: al_create_bitmap + +Creates a new bitmap using the bitmap format and flags for the current +thread. Blitting between bitmaps of differing formats, or blitting +between memory bitmaps and display bitmaps may be slow. + +Unless you set the ALLEGRO_MEMORY_BITMAP flag, the bitmap is created +for the current display. Blitting to another display may be slow. + +If a display bitmap is created, there may be limitations on the +allowed dimensions. For example a DirectX or OpenGL backend usually +has a maximum allowed texture size - so if bitmap creation fails +for very large dimensions, you may want to re-try with a smaller +bitmap. Some platforms also dictate a minimum texture size, which is +relevant if you plan to use this bitmap with the primitives addon. If +you try to create a bitmap smaller than this, this call will not fail +but the returned bitmap will be a section of a larger bitmap with the +minimum size. The minimum size that will work on all platforms is 32 by +32. There is an experimental switch to turns this padding off by editing +the system configuration (see `min_bitmap_size` key in +[al_get_system_config]). + +Some platforms do not directly support display bitmaps whose dimensions +are not powers of two. Allegro handles this by creating a larger bitmap +that has dimensions that are powers of two and then returning a section +of that bitmap with the dimensions you requested. This can be relevant +if you plan to use this bitmap with the primitives addon but shouldn't +be an issue otherwise. + +If you create a bitmap without ALLEGRO_MEMORY_BITMAP set but there is +no current display, a temporary memory bitmap will be created instead. +You can later convert all such bitmap to video bitmap and assign to a +display by calling [al_convert_memory_bitmaps]. + +On some platforms the contents of video bitmaps may be lost when your +application loses focus. Allegro has an internal mechanism to restore the +contents of these video bitmaps, but it is not foolproof (sometimes bitmap +contents can get lost permanently) and has performance implications. If you are +using a bitmap as an intermediate buffer this mechanism may be wasteful. In +this case, if you do not want Allegro to manage the bitmap contents for you, +you can disable this mechanism by creating the bitmap with the +ALLEGRO_NO_PRESERVE_TEXTURE flag. The bitmap contents are lost when you get the +ALLEGRO_EVENT_DISPLAY_LOST and ALLEGRO_EVENT_DISPLAY_HALT_DRAWING and a should +be restored when you get the ALLEGRO_EVENT_DISPLAY_FOUND and when you call +[al_acknowledge_drawing_resume] (after ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING +event). You can use those events to implement your own bitmap content +restoration mechanism if Allegro's does not work well enough for you (for +example, you can reload them all from disk). + + *Note*: The contents of a newly created bitmap are undefined - you need to +clear the bitmap or make sure all pixels get overwritten before drawing +it. + +When you are done with using the bitmap you must call +[al_destroy_bitmap] on it to free any resources allocated for it. + +See also: [al_set_new_bitmap_format], [al_set_new_bitmap_flags], +[al_clone_bitmap], [al_create_sub_bitmap], +[al_convert_memory_bitmaps], [al_destroy_bitmap] + +### API: al_create_sub_bitmap + +Creates a sub-bitmap of the parent, at the specified coordinates and of the +specified size. A sub-bitmap is a bitmap that shares drawing memory with a +pre-existing (parent) bitmap, but possibly with a different size and +clipping settings. + +The sub-bitmap may originate off or extend past the parent bitmap. + +See the discussion in [al_get_backbuffer] about using sub-bitmaps of +the backbuffer. + +The parent bitmap's clipping rectangles are ignored. + +If a sub-bitmap was not or cannot be created then NULL is returned. + +When you are done with using the sub-bitmap you must call +[al_destroy_bitmap] on it to free any resources allocated for it. + +Note that destroying parents of sub-bitmaps will not destroy the +sub-bitmaps; instead the sub-bitmaps become invalid and should no +longer be used for drawing - they still must be destroyed with +[al_destroy_bitmap] however. It does not matter whether you destroy +a sub-bitmap before or after its parent otherwise. + +See also: [al_create_bitmap] + +### API: al_clone_bitmap + +Create a new bitmap with [al_create_bitmap], and copy the pixel data from the +old bitmap across. The newly created bitmap will be created with the current +new bitmap flags, and not the ones that were used to create the original +bitmap. If the new bitmap is a memory bitmap, its projection bitmap is reset +to be orthographic. + +See also: [al_create_bitmap], [al_set_new_bitmap_format], +[al_set_new_bitmap_flags], [al_convert_bitmap] + +### API: al_convert_bitmap + +Converts the bitmap to the current bitmap flags and format. The bitmap will be +as if it was created anew with [al_create_bitmap] but retain its contents. All +of this bitmap's sub-bitmaps are also converted. If the new bitmap type is +memory, then the bitmap's projection bitmap is reset to be orthographic. + +If this bitmap is a sub-bitmap, then it, its parent and all the sibling +sub-bitmaps are also converted. + +Since: 5.1.0 + +See also: [al_create_bitmap], [al_set_new_bitmap_format], +[al_set_new_bitmap_flags], [al_clone_bitmap] + +### API: al_convert_memory_bitmaps + +If you create a bitmap when there is no current display (for example +because you have not called [al_create_display] in the current +thread) and are using the ALLEGRO_CONVERT_BITMAP bitmap flag (which is +set by default) then the bitmap will be created successfully, but as a +memory bitmap. This function converts all such bitmaps to proper video +bitmaps belonging to the current display. + +Note that video bitmaps get automatically converted back to memory +bitmaps when the last display is destroyed. + +This operation will preserve all bitmap flags except ALLEGRO_VIDEO_BITMAP and +ALLEGRO_MEMORY_BITMAP. + +Since: 5.2.0 + +See also: [al_convert_bitmap], [al_create_bitmap] + +### API: al_destroy_bitmap + +Destroys the given bitmap, freeing all resources used by it. +This function does nothing if the bitmap argument is NULL. + +As a convenience, if the calling thread is currently targeting the +bitmap then the bitmap will be untargeted first. +The new target bitmap is unspecified. (since: 5.0.10, 5.1.6) + +Otherwise, it is an error to destroy a bitmap while it (or a sub-bitmap) +is the target bitmap of any thread. + +See also: [al_create_bitmap] + +### API: al_get_new_bitmap_flags + +Returns the flags used for newly created bitmaps. + +See also: [al_set_new_bitmap_flags] + +### API: al_get_new_bitmap_format + +Returns the format used for newly created bitmaps. + +See also: [ALLEGRO_PIXEL_FORMAT], [al_set_new_bitmap_format] + +### API: al_set_new_bitmap_flags + +Sets the flags to use for newly created bitmaps. +Valid flags are: + +ALLEGRO_MEMORY_BITMAP +: Create a bitmap residing in system memory. + Operations on, and with, memory bitmaps will not be hardware accelerated. + However, direct pixel access can be relatively quick compared to video bitmaps, + which depend on the display driver in use. + + *Note*: Allegro's software rendering routines are currently somewhat + unoptimised. + + *Note:* Combining ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP flags is + invalid. + +ALLEGRO_VIDEO_BITMAP +: Creates a bitmap that resides in the video card memory. These types of + bitmaps receive the greatest benefit from hardware acceleration. + + *Note*: Creating a video bitmap will fail if there is no current + display or the current display driver cannot create the bitmap. The + latter will happen if for example the format or dimensions are not + supported. + + *Note:* Bitmaps created with this flag will be converted to memory + bitmaps when the last display is destroyed. In most cases it is + therefore easier to use the ALLEGRO_CONVERT_BITMAP flag instead. + + *Note:* Combining ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP flags is + invalid. + +ALLEGRO_CONVERT_BITMAP +: This is the default. It will try to create a video bitmap and if + that fails create a memory bitmap. Bitmaps created with this flag + when there is no active display will be converted to video bitmaps + next time a display is created. They also will remain video bitmaps + if the last display is destroyed and then another is created again. + Since 5.1.0. + + *Note:* You can combine this flag with ALLEGRO_MEMORY_BITMAP or + ALLEGRO_VIDEO_BITMAP to force the initial type (and fail in the + latter case if no video bitmap can be created) - but usually neither + of those combinations is very useful. + + You can use the display option ALLEGRO_AUTO_CONVERT_BITMAPS to + control which displays will try to auto-convert bitmaps. + +ALLEGRO_FORCE_LOCKING +: Does nothing since 5.1.8. Kept for backwards compatibility only. + +ALLEGRO_NO_PRESERVE_TEXTURE +: Normally, every effort is taken to preserve + the contents of bitmaps, since some platforms may forget them. This can + take extra processing time. If you know it doesn't matter if a bitmap keeps + its pixel data, for example when it's a temporary buffer, use this flag to + tell Allegro not to attempt to preserve its contents. + +ALLEGRO_ALPHA_TEST +: This is a driver hint only. It tells the graphics + driver to do alpha testing instead of alpha blending on bitmaps + created with this flag. Alpha testing is usually faster and + preferred if your bitmaps have only one level of alpha (0). This + flag is currently not widely implemented (i.e., only for memory + bitmaps). + +ALLEGRO_MIN_LINEAR +: When drawing a scaled down version of the bitmap, use linear + filtering. This usually looks better. You can also combine it with + the MIPMAP flag for even better quality. + +ALLEGRO_MAG_LINEAR + +: When drawing a magnified version of a bitmap, use linear filtering. + This will cause the picture to get blurry instead of creating a big + rectangle for each pixel. It depends on how you want things to look + like whether you want to use this or not. + +ALLEGRO_MIPMAP + +: This can only be used for bitmaps whose width and height is a power + of two. In that case, it will generate mipmaps and use them when + drawing scaled down versions. For example if the bitmap is 64x64, + then extra bitmaps of sizes 32x32, 16x16, 8x8, 4x4, 2x2 and 1x1 will + be created always containing a scaled down version of the original. + +See also: [al_get_new_bitmap_flags], [al_get_bitmap_flags] + +### API: al_add_new_bitmap_flag + +A convenience function which does the same as + +~~~~c +al_set_new_bitmap_flags(al_get_new_bitmap_flags() | flag); +~~~~ + +See also: [al_set_new_bitmap_flags], [al_get_new_bitmap_flags], [al_get_bitmap_flags] + +### API: al_set_new_bitmap_format + +Sets the pixel format ([ALLEGRO_PIXEL_FORMAT]) for newly created bitmaps. +The default format is 0 and means the display driver will choose +the best format. + +See also: [ALLEGRO_PIXEL_FORMAT], [al_get_new_bitmap_format], +[al_get_bitmap_format] + +### API: al_set_new_bitmap_depth + +Sets the depthbuffer depth used by newly created bitmaps (on the current +thread) if they are used with [al_set_target_bitmap]. 0 means no +depth-buffer will be created when drawing into the bitmap, which is the +default. + +Since: 5.2.1 + +> *[Unstable API]:* This is an experimental feature and currently only works for +the OpenGL backend. + +### API: al_get_new_bitmap_depth + +Returns the value currently set with [al_set_new_bitmap_depth] on +the current thread or 0 if none was set. + +Since: 5.2.1 + +> *[Unstable API]:* This is an experimental feature and currently only works for +the OpenGL backend. + +### API: al_set_new_bitmap_samples + +Sets the multi-sampling samples used by newly created bitmaps (on the +current thread) if they are used with [al_set_target_bitmap]. 0 means +multi-sampling will not be used when drawing into the bitmap, which is +the default. 1 means multi-sampling will be used but only using a single +sample per pixel (so usually there will be no visual difference to not +using multi-sampling at all). + +> *Note:* Some platforms have restrictions on when the multi-sampling +buffer for a bitmap is realized, i.e. down-scaled back to the actual +bitmap dimensions. This may only happen after a call to +[al_set_target_bitmap]. So for example: + + al_set_target_bitmap(multisample); + al_clear_to_color(blue); + al_draw_line(0, 0, 100, 100, red, 1); + al_lock_bitmap(multisample, ...) + // ERROR: the contents of the bitmap will be undefined + + al_set_target_bitmap(backbuffer); + al_lock_bitmap(multisample, ...) + // CORRECT: at this point, the bitmap contents are updated and + // there will be an anti-aliased line in it. + +Since: 5.2.1 + +> *[Unstable API]:* This is an experimental feature and currently only works for +the OpenGL backend. + +### API: al_get_new_bitmap_samples + +Returns the value currently set with [al_set_new_bitmap_samples] on +the current thread or 0 if none was set. + +Since: 5.2.1 + +> *[Unstable API]:* This is an experimental feature and currently only works for +the OpenGL backend. + +## Bitmap properties + +### API: al_get_bitmap_flags + +Return the flags used to create the bitmap. + +See also: [al_set_new_bitmap_flags] + +### API: al_get_bitmap_format + +Returns the pixel format of a bitmap. + +See also: [ALLEGRO_PIXEL_FORMAT], [al_set_new_bitmap_flags] + +### API: al_get_bitmap_height + +Returns the height of a bitmap in pixels. + +### API: al_get_bitmap_width + +Returns the width of a bitmap in pixels. + +### API: al_get_bitmap_depth + +Return the depthbuffer depth used by this bitmap if it is used with +[al_set_target_bitmap]. + +Since: 5.2.1 + +> *[Unstable API]:* This is an experimental feature and currently only works for +the OpenGL backend. + +### API: al_get_bitmap_samples + +Return the multi-sampling samples used by this bitmap if it is used with +[al_set_target_bitmap]. + +Since: 5.2.1 + +> *[Unstable API]:* This is an experimental feature and currently only works for +the OpenGL backend. + +### API: al_get_pixel + +Get a pixel's color value from the specified bitmap. This operation is slow +on non-memory bitmaps. Consider locking the bitmap if you are going to use this +function multiple times on the same bitmap. + +See also: [ALLEGRO_COLOR], [al_put_pixel], [al_lock_bitmap] + +### API: al_is_bitmap_locked + +Returns whether or not a bitmap is already locked. + +See also: [al_lock_bitmap], [al_lock_bitmap_region], [al_unlock_bitmap] + +### API: al_is_compatible_bitmap + +D3D and OpenGL allow sharing a texture in a way so it can be used for +multiple windows. Each [ALLEGRO_BITMAP] created with [al_create_bitmap] +however is usually tied to a single ALLEGRO_DISPLAY. This function can +be used to know if the bitmap is compatible with the given display, +even if it is a different display to the one it was created with. It +returns true if the bitmap is compatible (things like a cached texture +version can be used) and false otherwise (blitting in the current +display will be slow). + +The only time this function is useful is if you +are using multiple windows and need accelerated blitting of the same +bitmaps to both. + +Returns true if the bitmap is compatible with the current display, +false otherwise. If there is no current display, false is returned. + +### API: al_is_sub_bitmap + +Returns true if the specified bitmap is a sub-bitmap, false otherwise. + +See also: [al_create_sub_bitmap], [al_get_parent_bitmap] + +### API: al_get_parent_bitmap + +Returns the bitmap this bitmap is a sub-bitmap of. Returns NULL if this +bitmap is not a sub-bitmap. This function always returns the real bitmap, +and never a sub-bitmap. This might NOT match what was passed to +[al_create_sub_bitmap]. Consider this code, for instance: + +~~~~c +ALLEGRO_BITMAP* a = al_create_bitmap(512, 512); +ALLEGRO_BITMAP* b = al_create_sub_bitmap(a, 128, 128, 256, 256); +ALLEGRO_BITMAP* c = al_create_sub_bitmap(b, 64, 64, 128, 128); +ASSERT(al_get_parent_bitmap(b) == a && al_get_parent_bitmap(c) == a); +~~~~ + +The assertion will pass because only `a` is a real bitmap, and both `b` and `c` +are its sub-bitmaps. + +Since: 5.0.6, 5.1.2 + +See also: [al_create_sub_bitmap], [al_is_sub_bitmap] + +### API: al_get_bitmap_x + +For a sub-bitmap, return it's x position within the parent. + +See also: [al_create_sub_bitmap], [al_get_parent_bitmap], [al_get_bitmap_y] + +Since: 5.1.12 + +### API: al_get_bitmap_y + +For a sub-bitmap, return it's y position within the parent. + +See also: [al_create_sub_bitmap], [al_get_parent_bitmap], [al_get_bitmap_x] + +Since: 5.1.12 + +### API: al_reparent_bitmap + +For a sub-bitmap, changes the parent, position and size. This is the +same as destroying the bitmap and re-creating it with +[al_create_sub_bitmap] - except the bitmap pointer stays the same. This +has many uses, for example an animation player could return a single +bitmap which can just be re-parented to different animation frames +without having to re-draw the contents. Or a sprite atlas could +re-arrange its sprites without having to invalidate all existing +bitmaps. + +See also: [al_create_sub_bitmap], [al_get_parent_bitmap] + +Since: 5.1.12 + +### API: al_get_bitmap_blender + +Returns the current blender being used by the target bitmap. You can pass NULL +for values you are not interested in. + +Since: 5.2.5 + +> *[Unstable API]:* New API. + +See also: [al_set_bitmap_blender], [al_get_separate_bitmap_blender] + +### API: al_get_separate_bitmap_blender + +Returns the current blender being used by the target bitmap. You can pass NULL +for values you are not interested in. + +Since: 5.2.5 + +> *[Unstable API]:* New API. + +See also: [al_set_separate_bitmap_blender], [al_get_bitmap_blender] + +### API: al_get_bitmap_blend_color + +Returns the color currently used for constant color blending on the target +bitmap. + +Since: 5.2.5 + +> *[Unstable API]:* New API. + +See also: [al_set_bitmap_blend_color] + +### API: al_set_bitmap_blender + +Sets the function to use for blending when rendering to the target bitmap. If +no blender is set for a given bitmap at draw time, the values set for +[al_set_blender]/[al_set_separate_blender] are used instead. + +To use separate functions for chroma (RGB) and alpha channels, use +[al_set_separate_bitmap_blender]. + +See [al_set_blender] for more information about how blending works. + +See also: [al_set_separate_bitmap_blender], [al_reset_bitmap_blender] + +Since: 5.2.5 + +> *[Unstable API]:* New API. + +### API: al_set_separate_bitmap_blender + +Like [al_set_bitmap_blender], but allows specifying a separate blending +operation for the alpha channel. This is useful if your target bitmap also has +an alpha channel and the two alpha channels need to be combined in a different +way than the color components. + +Since: 5.2.5 + +> *[Unstable API]:* New API. + +See also: [al_set_bitmap_blender], [al_reset_bitmap_blender] + +### API: al_set_bitmap_blend_color + +Sets the color to use for `ALLEGRO_CONST_COLOR` or `ALLEGRO_INVERSE_CONST_COLOR` +blend operations. + +Since: 5.2.5 + +> *[Unstable API]:* New API. + +See also: [al_set_bitmap_blender], [al_reset_bitmap_blender] + +### API: al_reset_bitmap_blender + +Resets the blender for this bitmap to the default. After resetting the +bitmap blender, the values set for +[al_set_bitmap_blender]/[al_set_separate_bitmap_blender] will be used instead. + +Since: 5.2.5 + +> *[Unstable API]:* New API. + +See also: [al_set_bitmap_blender] + +## Drawing operations + +All drawing operations draw to the current "target bitmap" of the +current thread. Initially, the target bitmap will be the backbuffer of +the last display created in a thread. + +### API: al_clear_to_color + +Clear the complete target bitmap, but confined by the clipping rectangle. + +See also: [ALLEGRO_COLOR], [al_set_clipping_rectangle], [al_clear_depth_buffer] + +### API: al_clear_depth_buffer + +Clear the depth buffer (confined by the clipping rectangle) to the given +value. A depth buffer is only available if it was requested with +[al_set_new_display_option] and the requirement could be met by the +[al_create_display] call creating the current display. Operations involving the +depth buffer are also affected by [al_set_render_state]. + +For example, if `ALLEGRO_DEPTH_FUNCTION` is set to `ALLEGRO_RENDER_LESS` then +depth buffer value of 1 represents infinite distance, and thus is a good value +to use when clearing the depth buffer. + +Since: 5.1.2 + +See also: [al_clear_to_color], [al_set_clipping_rectangle], +[al_set_render_state], [al_set_new_display_option] + +### API: al_draw_bitmap + +Draws an unscaled, unrotated bitmap at the given position +to the current target bitmap (see [al_set_target_bitmap]). + +`flags` can be a combination of: + +* ALLEGRO_FLIP_HORIZONTAL - flip the bitmap about the y-axis +* ALLEGRO_FLIP_VERTICAL - flip the bitmap about the x-axis + +> *Note:* The current target bitmap must be a different bitmap. +Drawing a bitmap to itself (or to a sub-bitmap of itself) or +drawing a sub-bitmap to its parent (or another sub-bitmap of its +parent) are not currently supported. +To copy part of a bitmap into the same bitmap simply use a +temporary bitmap instead. + +> *Note:* The backbuffer (or a sub-bitmap thereof) can not be +transformed, blended or tinted. If you need to draw the backbuffer draw +it to a temporary bitmap first with no active transformation (except +translation). Blending and tinting settings/parameters will be +ignored. This does not apply when drawing into a memory bitmap. + +See also: [al_draw_bitmap_region], [al_draw_scaled_bitmap], +[al_draw_rotated_bitmap], [al_draw_scaled_rotated_bitmap] + +### API: al_draw_tinted_bitmap + +Like [al_draw_bitmap] but multiplies all colors in the bitmap with +the given color. For example: + +~~~~c +al_draw_tinted_bitmap(bitmap, al_map_rgba_f(0.5, 0.5, 0.5, 0.5), x, y, 0); +~~~~ + +The above will draw the bitmap 50% transparently (r/g/b values need +to be pre-multiplied with the alpha component with the default blend mode). + +~~~~c +al_draw_tinted_bitmap(bitmap, al_map_rgba_f(1, 0, 0, 1), x, y, 0); +~~~~ + +The above will only draw the red component of the bitmap. + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_bitmap] + +### API: al_draw_bitmap_region + +Draws a region of the given bitmap to the target bitmap. + +* sx - source x +* sy - source y +* sw - source width (width of region to blit) +* sh - source height (height of region to blit) +* dx - destination x +* dy - destination y +* flags - same as for [al_draw_bitmap] + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_bitmap], [al_draw_scaled_bitmap], +[al_draw_rotated_bitmap], [al_draw_scaled_rotated_bitmap] + +### API: al_draw_tinted_bitmap_region + +Like [al_draw_bitmap_region] but multiplies all colors in the bitmap +with the given color. + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_tinted_bitmap] + +### API: al_draw_pixel + +Draws a single pixel at x, y. This function, unlike [al_put_pixel], does +blending and, unlike [al_put_blended_pixel], respects the transformations (that +is, the pixel's position is transformed, but its size is unaffected - it +remains a pixel). This function can be slow if called often; if you need to +draw a lot of pixels consider using [al_draw_prim] with ALLEGRO_PRIM_POINT_LIST +from the primitives addon. + +* x - destination x +* y - destination y +* color - color of the pixel + +> *Note:* This function may not draw exactly where you expect it to. See the +pixel-precise output section on the +primitives addon documentation for details on how to control exactly where the +pixel is drawn. + +See also: [ALLEGRO_COLOR], [al_put_pixel] + +### API: al_draw_rotated_bitmap + +Draws a rotated version of the given bitmap to the target bitmap. +The bitmap is rotated by 'angle' radians clockwise. + +The point at cx/cy relative to the upper left corner of the bitmap will be drawn at dx/dy and the +bitmap is rotated around this point. If cx,cy is 0,0 the bitmap will rotate around its upper left corner. + +* cx - center x (relative to the bitmap) +* cy - center y (relative to the bitmap) +* dx - destination x +* dy - destination y +* angle - angle by which to rotate (radians) +* flags - same as for [al_draw_bitmap] + +Example + +~~~~c +float w = al_get_bitmap_width(bitmap); +float h = al_get_bitmap_height(bitmap); +al_draw_rotated_bitmap(bitmap, w / 2, h / 2, x, y, ALLEGRO_PI / 2, 0); +~~~~ + +The above code draws the bitmap centered on x/y and rotates it 90° clockwise. + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_bitmap], [al_draw_bitmap_region], +[al_draw_scaled_bitmap], [al_draw_scaled_rotated_bitmap] + +### API: al_draw_tinted_rotated_bitmap + +Like [al_draw_rotated_bitmap] but multiplies all colors in the bitmap +with the given color. + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_tinted_bitmap] + +### API: al_draw_scaled_rotated_bitmap + +Like [al_draw_rotated_bitmap], but can also scale the bitmap. + +The point at cx/cy in the bitmap will be drawn at dx/dy and the bitmap is +rotated and scaled around this point. + +* cx - center x +* cy - center y +* dx - destination x +* dy - destination y +* xscale - how much to scale on the x-axis (e.g. 2 for twice the size) +* yscale - how much to scale on the y-axis +* angle - angle by which to rotate (radians) +* flags - same as for [al_draw_bitmap] + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_bitmap], [al_draw_bitmap_region], [al_draw_scaled_bitmap], +[al_draw_rotated_bitmap] + +### API: al_draw_tinted_scaled_rotated_bitmap + +Like [al_draw_scaled_rotated_bitmap] but multiplies all colors in the +bitmap with the given color. + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_tinted_bitmap] + +### API: al_draw_tinted_scaled_rotated_bitmap_region + +Like [al_draw_tinted_scaled_rotated_bitmap] but you specify an area +within the bitmap to be drawn. + +You can get the same effect with a sub bitmap: + +~~~~c +al_draw_tinted_scaled_rotated_bitmap(bitmap, sx, sy, sw, sh, tint, + cx, cy, dx, dy, xscale, yscale, angle, flags); + +/* This draws the same: */ +sub_bitmap = al_create_sub_bitmap(bitmap, sx, sy, sw, sh); +al_draw_tinted_scaled_rotated_bitmap(sub_bitmap, tint, cx, cy, + dx, dy, xscale, yscale, angle, flags); +~~~~ + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +Since: 5.0.6, 5.1.0 + +See also: [al_draw_tinted_bitmap] + +### API: al_draw_scaled_bitmap + +Draws a scaled version of the given bitmap to the target bitmap. + +* sx - source x +* sy - source y +* sw - source width +* sh - source height +* dx - destination x +* dy - destination y +* dw - destination width +* dh - destination height +* flags - same as for [al_draw_bitmap] + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_bitmap], [al_draw_bitmap_region], [al_draw_rotated_bitmap], +[al_draw_scaled_rotated_bitmap], + +### API: al_draw_tinted_scaled_bitmap + +Like [al_draw_scaled_bitmap] but multiplies all colors in the bitmap +with the given color. + +See [al_draw_bitmap] for a note on restrictions on which bitmaps can be drawn +where. + +See also: [al_draw_tinted_bitmap] + +### API: al_get_target_bitmap + +Return the target bitmap of the calling thread. + +See also: [al_set_target_bitmap] + +### API: al_put_pixel + +Draw a single pixel on the target bitmap. This operation is slow on non-memory +bitmaps. Consider locking the bitmap if you are going to use this function +multiple times on the same bitmap. This function is not affected by the +transformations or the color blenders. + +See also: [ALLEGRO_COLOR], [al_get_pixel], [al_put_blended_pixel], [al_lock_bitmap] + +### API: al_put_blended_pixel + +Like [al_put_pixel], but the pixel color is blended using the current blenders +before being drawn. + +See also: [ALLEGRO_COLOR], [al_put_pixel] + +## Target bitmap + +### API: al_set_target_bitmap + +This function selects the bitmap to which all subsequent drawing operations in +the calling thread will draw to. +To return to drawing to a display, set the backbuffer of the display as the +target bitmap, using [al_get_backbuffer]. As a convenience, you may also use +[al_set_target_backbuffer]. + +Each allegro bitmap maintains two transformation matrices associated with it for +drawing onto the bitmap. There is a view matrix and a projection matrix. When you +call al_set_target_bitmap, these will be made current for the bitmap, affecting +global OpenGL and DirectX states depending on the driver in use. + +Each video bitmap is tied to a display. When a video bitmap is set to as the +target bitmap, the display that the bitmap belongs to is automatically made +"current" for the calling thread (if it is not current already). Then drawing +other bitmaps which are tied to the same display can be hardware accelerated. + +A single display cannot be current for multiple threads simultaneously. If you +need to release a display, so it is not current for the calling thread, call +`al_set_target_bitmap(NULL);` + +Setting a memory bitmap as the target bitmap will not change which display +is current for the calling thread. + +On some platforms, Allegro automatically backs up the contents of video bitmaps +because they may be occasionally lost (see discussion in [al_create_bitmap]'s +documentation). If you're completely recreating the bitmap contents often (e.g. +every frame) then you will get much better performance by creating the target +bitmap with ALLEGRO_NO_PRESERVE_TEXTURE flag. + +OpenGL note: + +Framebuffer objects (FBOs) allow OpenGL to directly draw to a bitmap, which is +very fast. When using an OpenGL display, if all of the following conditions +are met an FBO will be created for use with the bitmap: + +* The GL_EXT_framebuffer_object OpenGL extension is available. +* The bitmap is not a memory bitmap. +* The bitmap is not currently locked. + +In Allegro 5.0.0, you had to be careful as an FBO would be kept around until +the bitmap is destroyed or you explicitly called [al_remove_opengl_fbo] on the +bitmap, wasting resources. In newer versions, FBOs will be freed automatically +when the bitmap is no longer the target bitmap, *unless* you have called +[al_get_opengl_fbo] to retrieve the FBO id. + +In the following example, no FBO will be created: + +~~~~c +lock = al_lock_bitmap(bitmap); +al_set_target_bitmap(bitmap); +al_put_pixel(x, y, color); +al_unlock_bitmap(bitmap); +~~~~ + +The above allows using [al_put_pixel] on a locked bitmap without creating an +FBO. + +In this example an FBO is created however: + +~~~~c +al_set_target_bitmap(bitmap); +al_draw_line(x1, y1, x2, y2, color, 0); +~~~~ + +An OpenGL command will be used to directly draw the line into the bitmap's +associated texture. + +See also: [al_get_target_bitmap], [al_set_target_backbuffer] + +### API: al_set_target_backbuffer + +Same as `al_set_target_bitmap(al_get_backbuffer(display));` + +See also: [al_set_target_bitmap], [al_get_backbuffer] + +### API: al_get_current_display + +Return the display that is "current" for the calling thread, or NULL if there +is none. + +See also: [al_set_target_bitmap] + + + +## Blending modes + +### API: al_get_blender + +Returns the active blender for the current thread. You can pass +NULL for values you are not interested in. + +See also: [al_set_blender], [al_get_separate_blender] + +### API: al_get_separate_blender + +Returns the active blender for the current thread. You can pass +NULL for values you are not interested in. + +See also: [al_set_separate_blender], [al_get_blender] + +### API: al_get_blend_color + +Returns the color currently used for constant color blending (white by +default). + +See also: [al_set_blend_color], [al_set_blender] + +Since: 5.1.12 + +### API: al_set_blender + +Sets the function to use for blending for the current thread. + +Blending means, the source and destination colors are combined in +drawing operations. + +Assume the source color (e.g. color of a rectangle to draw, or pixel +of a bitmap to draw) is given as its red/green/blue/alpha +components (if the bitmap has no alpha it always is assumed to be +fully opaque, so 255 for 8-bit or 1.0 for floating point): +*s = s.r, s.g, s.b, s.a*. +And this color is drawn to a destination, which already has a color: +*d = d.r, d.g, d.b, d.a*. + +The conceptional formula used by Allegro to draw any pixel then depends +on the `op` parameter: + +* ALLEGRO_ADD + + r = d.r * df.r + s.r * sf.r + g = d.g * df.g + s.g * sf.g + b = d.b * df.b + s.b * sf.b + a = d.a * df.a + s.a * sf.a + +* ALLEGRO_DEST_MINUS_SRC + + r = d.r * df.r - s.r * sf.r + g = d.g * df.g - s.g * sf.g + b = d.b * df.b - s.b * sf.b + a = d.a * df.a - s.a * sf.a + +* ALLEGRO_SRC_MINUS_DEST + + r = s.r * sf.r - d.r * df.r + g = s.g * sf.g - d.g * df.g + b = s.b * sf.b - d.b * df.b + a = s.a * sf.a - d.a * df.a + +Valid values for the factors `sf` and `df` passed to this function are as +follows, where `s` is the source color, `d` the destination color and `cc` +the color set with [al_set_blend_color] (white by default) + +* ALLEGRO_ZERO + + f = 0, 0, 0, 0 + +* ALLEGRO_ONE + + f = 1, 1, 1, 1 + +* ALLEGRO_ALPHA + + f = s.a, s.a, s.a, s.a + +* ALLEGRO_INVERSE_ALPHA + + f = 1 - s.a, 1 - s.a, 1 - s.a, 1 - s.a + +* ALLEGRO_SRC_COLOR (since: 5.0.10, 5.1.0) + + f = s.r, s.g, s.b, s.a + +* ALLEGRO_DEST_COLOR (since: 5.0.10, 5.1.8) + + f = d.r, d.g, d.b, d.a + +* ALLEGRO_INVERSE_SRC_COLOR (since: 5.0.10, 5.1.0) + + f = 1 - s.r, 1 - s.g, 1 - s.b, 1 - s.a + +* ALLEGRO_INVERSE_DEST_COLOR (since: 5.0.10, 5.1.8) + + f = 1 - d.r, 1 - d.g, 1 - d.b, 1 - d.a + +* ALLEGRO_CONST_COLOR (since: 5.1.12, not supported on OpenGLES 1.0) + + f = cc.r, cc.g, cc.b, cc.a + +* ALLEGRO_INVERSE_CONST_COLOR (since: 5.1.12, not supported on OpenGLES 1.0) + + f = 1 - cc.r, 1 - cc.g, 1 - cc.b, 1 - cc.a + +Blending examples: + +So for example, to restore the default of using premultiplied alpha +blending, you would use: + +~~~~c +al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); +~~~~ + +As formula: + + r = d.r * (1 - s.a) + s.r * 1 + g = d.g * (1 - s.a) + s.g * 1 + b = d.b * (1 - s.a) + s.b * 1 + a = d.a * (1 - s.a) + s.a * 1 + +If you are using non-pre-multiplied alpha, you could use + +~~~~c +al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); +~~~~ + +Additive blending would be achieved with + +~~~~c +al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); +~~~~ + +Copying the source to the destination (including alpha) unmodified + +~~~~c +al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); +~~~~ + +Multiplying source and destination components + +~~~~c +al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_ZERO) +~~~~ + +Tinting the source (like [al_draw_tinted_bitmap]) + +~~~~c +al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_ONE); +al_set_blend_color(al_map_rgb(0, 96, 255)); /* nice Chrysler blue */ +~~~~ + +Averaging source and destination pixels + +~~~~c +al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR); +al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 0.5)); +~~~~ + +As formula: + + r = d.r * 0 + s.r * d.r + g = d.g * 0 + s.g * d.g + b = d.b * 0 + s.b * d.b + a = d.a * 0 + s.a * d.a + +See also: [al_set_separate_blender], [al_set_blend_color], [al_get_blender] + +### API: al_set_separate_blender + +Like [al_set_blender], but allows specifying a separate blending +operation for the alpha channel. This is useful if your target +bitmap also has an alpha channel and the two alpha channels need +to be combined in a different way than the color components. + +See also: [al_set_blender], [al_get_blender], [al_get_separate_blender] + +### API: al_set_blend_color + +Sets the color to use for blending when using the ALLEGRO_CONST_COLOR +or ALLEGRO_INVERSE_CONST_COLOR blend functions. See [al_set_blender] for +more information. + +See also: [al_set_blender], [al_get_blend_color] + +Since: 5.1.12 + + +## Clipping + +### API: al_get_clipping_rectangle + +Gets the clipping rectangle of the target bitmap. + +See also: [al_set_clipping_rectangle] + +### API: al_set_clipping_rectangle + +Set the region of the target bitmap or display that +pixels get clipped to. The default is to clip pixels +to the entire bitmap. + +See also: [al_get_clipping_rectangle], [al_reset_clipping_rectangle] + +### API: al_reset_clipping_rectangle + +Equivalent to calling `al_set_clipping_rectangle(0, 0, w, h)' +where *w* and *h* are the width and height of the target bitmap +respectively. + +Does nothing if there is no target bitmap. + +See also: [al_set_clipping_rectangle] + +Since: 5.0.6, 5.1.0 + + + +## Graphics utility functions + +### API: al_convert_mask_to_alpha + +Convert the given mask color to an alpha channel in the bitmap. +Can be used to convert older 4.2-style bitmaps with magic pink +to alpha-ready bitmaps. + +See also: [ALLEGRO_COLOR] + +## Deferred drawing + +### API: al_hold_bitmap_drawing + +Enables or disables deferred bitmap drawing. This allows for efficient drawing +of many bitmaps that share a parent bitmap, such as sub-bitmaps from a +tilesheet or simply identical bitmaps. Drawing bitmaps that do not share a +parent is less efficient, so it is advisable to stagger bitmap drawing calls +such that the parent bitmap is the same for large number of those calls. While +deferred bitmap drawing is enabled, the only functions that can be used are the +bitmap drawing functions and font drawing functions. Changing the state such as +the blending modes will result in undefined behaviour. One exception to this +rule are the non-projection transformations. It is possible to set a new +transformation while the drawing is held. + +No drawing is guaranteed to take place until you disable the hold. Thus, the +idiom of this function's usage is to enable the deferred bitmap drawing, draw as +many bitmaps as possible, taking care to stagger bitmaps that share parent +bitmaps, and then disable deferred drawing. As mentioned above, this function +also works with bitmap and truetype fonts, so if multiple lines of text need to +be drawn, this function can speed things up. + +See also: [al_is_bitmap_drawing_held] + +### API: al_is_bitmap_drawing_held + +Returns whether the deferred bitmap drawing mode is turned on or off. + +See also: [al_hold_bitmap_drawing] + + + +## Image I/O + +### API: al_register_bitmap_loader + +Register a handler for [al_load_bitmap]. The given function will be used to +handle the loading of bitmaps files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `loader` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_bitmap_saver], [al_register_bitmap_loader_f] + +### API: al_register_bitmap_saver + +Register a handler for [al_save_bitmap]. The given function will be used to +handle the saving of bitmaps files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `saver` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_bitmap_loader], [al_register_bitmap_saver_f] + +### API: al_register_bitmap_loader_f + +Register a handler for [al_load_bitmap_f]. The given function will be +used to handle the loading of bitmaps files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `fs_loader` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_bitmap_loader] + +### API: al_register_bitmap_saver_f + +Register a handler for [al_save_bitmap_f]. The given function will be +used to handle the saving of bitmaps files with the given extension. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `saver_f` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +See also: [al_register_bitmap_saver] + +### API: al_load_bitmap + +Loads an image file into a new [ALLEGRO_BITMAP]. +The file type is determined by the extension, except if the file has +no extension in which case [al_identify_bitmap] is used instead. + +Returns NULL on error. + +This is the same as calling [al_load_bitmap_flags] with a flags parameter of 0. + +> *Note:* the core Allegro library does not support any image file formats by +default. You must use the allegro_image addon, or register your own format +handler. + +See also: [al_load_bitmap_flags], [al_load_bitmap_f], +[al_register_bitmap_loader], [al_set_new_bitmap_format], +[al_set_new_bitmap_flags], [al_init_image_addon] + +### API: al_load_bitmap_flags + +Loads an image file into a new [ALLEGRO_BITMAP]. +The file type is determined by the extension, except if the file has +no extension in which case [al_identify_bitmap] is used instead. + +Returns NULL on error. + +The flags parameter may be a combination of the following constants: + +ALLEGRO_NO_PREMULTIPLIED_ALPHA +: By default, Allegro pre-multiplies the alpha channel of an image with + the images color data when it loads it. Typically that would look + something like this: + + ~~~~c + r = get_float_byte(); + g = get_float_byte(); + b = get_float_byte(); + a = get_float_byte(); + + r = r * a; + g = g * a; + b = b * a; + + set_image_pixel(x, y, r, g, b, a); + ~~~~ + + The reason for this can be seen in the Allegro example + ex_premulalpha, ie, using pre-multiplied alpha gives more accurate + color results in some cases. To use alpha blending with images loaded + with pre-multiplied alpha, you would use the default blending mode, + which is set with al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, + ALLEGRO_INVERSE_ALPHA). + + The ALLEGRO_NO_PREMULTIPLIED_ALPHA flag being set will ensure that + images are not loaded with alpha pre-multiplied, but are loaded with + color values direct from the image. That looks like this: + + ~~~~c + r = get_float_byte(); + g = get_float_byte(); + b = get_float_byte(); + a = get_float_byte(); + + set_image_pixel(x, y, r, g, b, a); + ~~~~ + + To draw such an image using regular alpha blending, you would use + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) + to set the correct blender. This has some caveats. First, as mentioned + above, drawing such an image can result in less accurate color blending + (when drawing an image with linear filtering on, the edges will + be darker than they should be). Second, the behaviour is somewhat confusing, + which is explained in the example below. + + ~~~~c + // Load and create bitmaps with an alpha channel + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA); + // Load some bitmap with alpha in it + bmp = al_load_bitmap("some_alpha_bitmap.png"); + // We will draw to this buffer and then draw this buffer to the screen + tmp_buffer = al_create_bitmap(SCREEN_W, SCREEN_H); + // Set the buffer as the target and clear it + al_set_target_bitmap(tmp_buffer); + al_clear_to_color(al_map_rgba_f(0, 0, 0, 1)); + // Draw the bitmap to the temporary buffer + al_draw_bitmap(bmp, 0, 0, 0); + // Finally, draw the buffer to the screen + // The output will look incorrect (may take close inspection + // depending on the bitmap -- it may also be very obvious) + al_set_target_bitmap(al_get_backbuffer(display)); + al_draw_bitmap(tmp_buffer, 0, 0, 0); + ~~~~ + + To explain further, if you have a pixel with 0.5 alpha, and you're using + (ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) for blending, the + formula is: + + a = da * dst + sa * src + + Expands to: + + result_a = dst_a * (1-0.5) + 0.5 * 0.5 + + So if you draw the image to the temporary buffer, it is blended once resulting + in 0.75 alpha, then drawn again to the screen, blended in the same way, + resulting in a pixel has 0.1875 as an alpha value. + +ALLEGRO_KEEP_INDEX +: Load the palette indices of 8-bit .bmp and .pcx files instead of the rgb colors. + Since 5.1.0. + +ALLEGRO_KEEP_BITMAP_FORMAT +: Force the resulting [ALLEGRO_BITMAP] to use the same format as the file. + + *This is not yet honoured.* + +> *Note:* the core Allegro library does not support any image file formats by +default. You must use the allegro_image addon, or register your own format +handler. + +Since: 5.1.0 + +See also: [al_load_bitmap] + +### API: al_load_bitmap_f + +Loads an image from an [ALLEGRO_FILE] stream into a new [ALLEGRO_BITMAP]. +The file type is determined by the passed 'ident' parameter, which is a file +name extension including the leading dot. If (and only if) 'ident' is +NULL, the file type is determined with [al_identify_bitmap_f] instead. + +This is the same as calling [al_load_bitmap_flags_f] with 0 for the flags +parameter. + +Returns NULL on error. +The file remains open afterwards. + +> *Note:* the core Allegro library does not support any image file formats by +default. You must use the allegro_image addon, or register your own format +handler. + +See also: [al_load_bitmap_flags_f], [al_load_bitmap], +[al_register_bitmap_loader_f], [al_init_image_addon] + +### API: al_load_bitmap_flags_f + +Loads an image from an [ALLEGRO_FILE] stream into a new [ALLEGRO_BITMAP]. +The file type is determined by the passed 'ident' parameter, which is a file +name extension including the leading dot. If (and only if) 'ident' is +NULL, the file type is determined with [al_identify_bitmap_f] instead. + +The flags parameter is the same as for [al_load_bitmap_flags]. + +Returns NULL on error. +The file remains open afterwards. + +> *Note:* the core Allegro library does not support any image file formats by +default. You must use the allegro_image addon, or register your own format +handler. + +Since: 5.1.0 + +See also: [al_load_bitmap_f], [al_load_bitmap_flags] + +### API: al_save_bitmap + +Saves an [ALLEGRO_BITMAP] to an image file. +The file type is determined by the extension. + +Returns true on success, false on error. + +> *Note:* the core Allegro library does not support any image file formats by +default. You must use the allegro_image addon, or register your own format +handler. + +See also: [al_save_bitmap_f], [al_register_bitmap_saver], [al_init_image_addon] + +### API: al_save_bitmap_f + +Saves an [ALLEGRO_BITMAP] to an [ALLEGRO_FILE] stream. +The file type is determined by the passed 'ident' parameter, which is a file +name extension including the leading dot. + +Returns true on success, false on error. +The file remains open afterwards. + +> *Note:* the core Allegro library does not support any image file formats by +default. You must use the allegro_image addon, or register your own format +handler. + +See also: [al_save_bitmap], [al_register_bitmap_saver_f], [al_init_image_addon] + +### API: al_register_bitmap_identifier + +Register an identify handler for [al_identify_bitmap]. The given +function will be used to detect files for the given extension. It will +be called with a single argument of type [ALLEGRO_FILE] which is a +file handle opened for reading and located at the first byte of the +file. The handler should try to read as few bytes as possible to +safely determine if the given file contents correspond to the type +with the extension and return true in that case, false otherwise. +The file handle must not be closed but there is no need to reset it +to the beginning. + +The extension should include the leading dot ('.') character. +It will be matched case-insensitively. + +The `identifier` argument may be NULL to unregister an entry. + +Returns true on success, false on error. +Returns false if unregistering an entry that doesn't exist. + +Since: 5.1.12 + +See also: [al_identify_bitmap] + +### API: al_identify_bitmap + +This works exactly as [al_identify_bitmap_f] but you specify the +filename of the file for which to detect the type and not a file +handle. The extension, if any, of the passed filename is not taken +into account - only the file contents. + +Since: 5.1.12 + +See also: [al_init_image_addon], [al_identify_bitmap_f], +[al_register_bitmap_identifier] + +### API: al_identify_bitmap_f + +Tries to guess the bitmap file type of the open ALLEGRO_FILE by +reading the first few bytes. By default Allegro cannot recognize any +file types, but calling [al_init_image_addon] will add detection of +(some of) the types it can read. You can also use +[al_register_bitmap_identifier] to add identification for custom +file types. + +Returns a pointer to a static string with a file extension for the +type, including the leading dot. For example ".png" or ".jpg". Returns +NULL if the bitmap type cannot be determined. + +Since: 5.1.12 + +See also: [al_init_image_addon], [al_identify_bitmap], +[al_register_bitmap_identifier] + +## Render State + +### API: ALLEGRO_RENDER_STATE + +Possible render states which can be set with [al_set_render_state]: + +ALLEGRO_ALPHA_TEST +: If this is set to 1, the values of ALLEGRO_ALPHA_FUNCTION and + ALLEGRO_ALPHA_TEST_VALUE define a comparison function which is performed + on the alpha component of each pixel. Only if it evaluates to true + the pixel is written. Otherwise no subsequent processing (like depth + test or blending) is performed. + This can be very useful, for example if a depth buffer is used but + you do not want fully transparent pixels to modify it. + +ALLEGRO_ALPHA_FUNCTION +: One of [ALLEGRO_RENDER_FUNCTION], only used when ALLEGRO_ALPHA_TEST is 1. + +ALLEGRO_ALPHA_TEST_VALUE +: Only used when ALLEGRO_ALPHA_TEST is 1. Should be a value of 0 - 255. + +ALLEGRO_WRITE_MASK +: This determines how the framebuffer and depthbuffer are updated whenever a + pixel is written (in case alpha and/or depth testing is enabled: after all + such enabled tests succeed). Depth values are only written if + ALLEGRO_DEPTH_TEST is 1, in addition to the write mask flag being set. + +ALLEGRO_DEPTH_TEST +: If this is set to 1, compare the depth value of any newly written pixels with + the depth value already in the buffer, according to ALLEGRO_DEPTH_FUNCTION. + Allegro primitives with no explicit z coordinate will write a value of 0 into + the depth buffer. + +ALLEGRO_DEPTH_FUNCTION +: One of [ALLEGRO_RENDER_FUNCTION], only used when ALLEGRO_DEPTH_TEST is 1. + +Since: 5.1.2 + +See also: [al_set_render_state], [ALLEGRO_RENDER_FUNCTION], +[ALLEGRO_WRITE_MASK_FLAGS] + +### API: ALLEGRO_RENDER_FUNCTION + +Possible functions are: + +- ALLEGRO_RENDER_NEVER +- ALLEGRO_RENDER_ALWAYS +- ALLEGRO_RENDER_LESS +- ALLEGRO_RENDER_EQUAL +- ALLEGRO_RENDER_LESS_EQUAL +- ALLEGRO_RENDER_GREATER +- ALLEGRO_RENDER_NOT_EQUAL +- ALLEGRO_RENDER_GREATER_EQUAL + +Since: 5.1.2 + +See also: [al_set_render_state] + +### API: ALLEGRO_WRITE_MASK_FLAGS + +Each enabled bit means the corresponding value is written, a disabled bit +means it is not. + +- ALLEGRO_MASK_RED +- ALLEGRO_MASK_GREEN +- ALLEGRO_MASK_BLUE +- ALLEGRO_MASK_ALPHA +- ALLEGRO_MASK_DEPTH +- ALLEGRO_MASK_RGB - Same as RED | GREEN | BLUE. +- ALLEGRO_MASK_RGBA - Same as RGB | ALPHA. + +Since: 5.1.2 + +See also: [al_set_render_state] + +### API: al_set_render_state + +Set one of several render attributes; see [ALLEGRO_RENDER_STATE] +for details. + +This function does nothing if the target bitmap is a memory bitmap. + +Since: 5.1.2 + +See also: [ALLEGRO_RENDER_STATE], [ALLEGRO_RENDER_FUNCTION], +[ALLEGRO_WRITE_MASK_FLAGS] + + +### API: al_backup_dirty_bitmap + +On some platforms, notably Windows Direct3D and Android, textures may be +lost at any time for events such as display resize or switching out of the +app. On those platforms, bitmaps created without the ALLEGRO_NO_PRESERVE_TEXTURE +flag automatically get backed up to system memory every time +al_flip_display is called. + +This function gives you more control over when your bitmaps get backed up. +By calling this function after modifying a bitmap, you can make sure the +bitmap is backed up right away instead of during the next flip. + +Since: 5.2.1 + +> *[Unstable API]:* This API is new and subject to refinement. + +See also: [al_backup_dirty_bitmaps], [al_create_bitmap] + + +### API: al_backup_dirty_bitmaps + +Backs up all of a display's bitmaps to system memory. + +Since: 5.2.1 + +> *[Unstable API]:* This API is new and subject to refinement. + +See also: [al_backup_dirty_bitmap] + diff --git a/allegro/docs/src/refman/haptic.txt b/allegro/docs/src/refman/haptic.txt new file mode 100644 index 00000000..f96f4e10 --- /dev/null +++ b/allegro/docs/src/refman/haptic.txt @@ -0,0 +1,693 @@ +# Haptic routines + +Haptic functions support force feedback and vibration on input devices. +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +Currently force feedback is fully supported on Linux and on Windows for +DirectInput compatible devices. There is also minimal support for +Android. It is not yet supported on OSX, iOS, or on Windows for XInput +compatible devices. + +## API: ALLEGRO_HAPTIC + +This is an abstract data type representing a haptic device that supports +force feedback or vibration. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +See also: [al_get_haptic_from_joystick] + +## API: ALLEGRO_HAPTIC_CONSTANTS + +This enum contains flags that are used to define haptic effects and +capabilities. If the flag is set in the return value of +[al_get_haptic_capabilities], it means the device supports the given effect. +The value of these flags should be set into a [ALLEGRO_HAPTIC_EFFECT] struct +to determine what kind of haptic effect should be played. + +* ALLEGRO_HAPTIC_RUMBLE - simple vibration effects +* ALLEGRO_HAPTIC_PERIODIC - periodic, wave-form effects +* ALLEGRO_HAPTIC_CONSTANT - constant effects +* ALLEGRO_HAPTIC_SPRING - spring effects +* ALLEGRO_HAPTIC_FRICTION - friction effects +* ALLEGRO_HAPTIC_DAMPER - damper effects +* ALLEGRO_HAPTIC_INERTIA - inertia effects +* ALLEGRO_HAPTIC_RAMP - ramp effects +* ALLEGRO_HAPTIC_SQUARE - square wave periodic effect +* ALLEGRO_HAPTIC_TRIANGLE - triangle wave periodic effect +* ALLEGRO_HAPTIC_SINE - sine wave periodic effect +* ALLEGRO_HAPTIC_SAW_UP - upwards saw wave periodic effect +* ALLEGRO_HAPTIC_SAW_DOWN - downwards saw wave periodic effect +* ALLEGRO_HAPTIC_CUSTOM - custom wave periodic effect +* ALLEGRO_HAPTIC_GAIN - the haptic device supports gain setting +* ALLEGRO_HAPTIC_ANGLE - the haptic device supports angle coordinates +* ALLEGRO_HAPTIC_RADIUS - the haptic device supports radius coordinates +* ALLEGRO_HAPTIC_AZIMUTH - the haptic device supports azimuth coordinates +* ALLEGRO_HAPTIC_AUTOCENTER + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +See also: [al_get_haptic_capabilities], [ALLEGRO_HAPTIC_EFFECT] + +## API: ALLEGRO_HAPTIC_EFFECT + +This struct models a particular haptic or vibration effect. It needs to be +filled in correctly and uploaded to a haptic device before the device can +play it back. + +*Fields:* + +type +: The type of the haptic effect. May be one of the ALLEGRO_HAPTIC_CONSTANTS + constants between or equal to ALLEGRO_HAPTIC_RUMBLE and + ALLEGRO_HAPTIC_RAMP. + + * If `type` is set to ALLEGRO_HAPTIC_RUMBLE, then the effect is a simple + "rumble" or vibration effect that shakes the device. In some cases, + such as on a mobile platform, the whole device may shake. + + * If `type` is set to ALLEGRO_HAPTIC_PERIODIC, the effect is a shake or + vibration of which the intensity is a periodic wave form. + + * If `type` is set to ALLEGRO_HAPTIC_CONSTANT, the effect is a constant + pressure, motion or push-back in a certain direction of the axes of + the device. + + * If `type` is set to ALLEGRO_HAPTIC_SPRING, the effect is a springy kind + of resistance against motion of the axes of the haptic device. + + * If `type` is set to ALLEGRO_HAPTIC_FRICTION, the effect is a friction + kind of resistance against motion of the axes of the haptic device. + + * If `type` is set to ALLEGRO_HAPTIC_DAMPER, the effect is a damper kind + of resistance against motion of the axes of the haptic device. + + * If `type` is set to ALLEGRO_HAPTIC_INERTIA, the effect causes inertia + or slowness of motions on the axes of the haptic device. + + * If `type` is set to ALLEGRO_HAPTIC_RAMP, the effect causes a pressure + or push-back that ramps up or down depending on the position of the + axis. + +direction +: The direction of location in 3D space where the effect should + be played. Allegro haptic devices model directions in 3D space using + spherical coordinates. However, the haptic device may not support + localized effects, or may not support all coordinate components. + + In Allegro's coordinate system, the value in `direction.angle` determines + the planar angle between the effect and the direction of the user who + holds the device, expressed in radians. This angle increases clockwise + away from the user. So, an effect with an angle 0.0 takes place in the + direction of the user of the haptic device, an angle of π/2 is + to the left of the user, an angle of π means the direction away from + the user, and an angle of 3π/2 means to the right of the user. + + If [al_get_haptic_capabilities] has the flag ALLEGRO_HAPTIC_ANGLE set, + then setting `direction.angle` is supported. Otherwise, it is + unsupported, and you should set it to 0. + + The value in `direction.radius` is a relative value between 0.0 and 1.0 + that determines the relative distance from the center of the haptic + device at which the effect will play back. A value of 0 means that the + effect should play back at the center of the device. A value of 1.0 means + that the effect should play back away from the center as far as is + possible. + + If [al_get_haptic_capabilities] has the flag ALLEGRO_HAPTIC_RADIUS set, + then setting `direction.radius` is supported. Otherwise, it is + unsupported, and you should set it to 0. + + The value in `direction.azimuth` determines the elevation angle between + the effect and the plane in which the user is holding the device, + expressed in radians. An effect with an azimuth 0.0 plays back in the + plane in which the user is holding the device, an azimuth +π/2 means + the effect plays back vertically above the user plane, and an azimuth + -π/2 means the effect plays back vertically below the user plane. + + If [al_get_haptic_capabilities] has the flag ALLEGRO_HAPTIC_AZIMUTH set, + then setting `direction.azimuth` is supported. Otherwise, it is + unsupported, and you should set it to 0. + +replay +: Determines how the effect should be played back. `replay.length` is the + duration in seconds of the effect, and `replay.delay` is the time in + seconds that the effect playback should be delayed when playback is + started with [al_play_haptic_effect]. + +data +: Determines in detail the parameters of the haptic effect to play back. + + If `type` is set to ALLEGRO_HAPTIC_RUMBLE, then + `data.rumble.strong_magnitude` must be set to a relative magnitude + between 0.0 and 1.0 to determine how intensely the "large" rumble motor + of the haptic device will vibrate, and `data.rumble.weak_magnitude` must + be set to relative magnitude between 0.0 and 1.0 to determine how + intensely the "weak" ruble motor of the haptic device will vibrate. + Not all devices have a "weak" motor, in which case the value set in + `data.rumble.weak_magnitude` will be ignored. + + If `type` is set to ALLEGRO_HAPTIC_PERIODIC, then + data.periodic.waveform must be set to one of ALLEGRO_HAPTIC_SQUARE, + ALLEGRO_HAPTIC_TRIANGLE, ALLEGRO_HAPTIC_SINE, ALLEGRO_HAPTIC_SAW_UP, + ALLEGRO_HAPTIC_SAW_DOWN, ALLEGRO_HAPTIC_CUSTOM. This will then determine + the wave form of the vibration effect that will be played on the haptic + device. + + In these cases, `data.periodic.period` must be set to the period in + seconds of the wave form. The field `data.periodic.magnitude` must be set + to the relative magnitude of intensity between -1.0 and 1.0 at which the + wave form of the vibration will be played back. The field + `data.periodic.offset` must be filled in with the offset from origin in + seconds of the wave form of vibration, and the field + `data.periodic.phase` is the phase of the wave form of vibration in + seconds. + + If `data.periodic.waveform` is set to ALLEGRO_HAPTIC_CUSTOM, then + `data.periodic.custom_data` must point to an array of + `data.periodic.custom_len` doubles, each with values between -1.0 and + 1.0. This value array will determine the shape of the wave form of the + haptic effect. ALLEGRO_HAPTIC_CUSTOM is not supported on some platforms, + so use [al_get_haptic_capabilities] to check if it's available. If it isn't, + you may want to play back a non-custom wave effect as a substitute instead. + + If `type` is set to ALLEGRO_HAPTIC_CONSTANT, then `data.constant.level` + must be set to a relative intensity value between 0.0 and 1.0 to + determine the intensity of the effect. + + If `type` is set to any of ALLEGRO_HAPTIC_SPRING, + ALLEGRO_HAPTIC_FRICTION, ALLEGRO_HAPTIC_DAMPER, ALLEGRO_HAPTIC_INERTIA, + ALLEGRO_HAPTIC_RAMP, then the `data.condition` struct should be filled in. + To explain this better, it's best to keep in mind that these kinds of + effects are most useful for steering-wheel kind of devices, where + resistance or inertia should be applied when turning the device's wheel a + certain distance to the left or right. + + The field `data.condition.right_saturation` must be filled in with a + relative magnitude between -1.0 and 1.0 to determine the intensity of + resistance or inertia on the "right" side of the axis. Likewise, + `data.condition.left_saturation` must be filled in with a relative + magnitude between -1.0 and 1.0 to determine the intensity of + resistance or inertia on the "left" side of the axis. + + The field `data.condition.deadband` must be filled in with a relative + value between 0.0 and 1.0 to determine the relative width of the "dead + band" of the haptic effect. As long as the axis of the haptic device + remains in the "dead band" area, the effect will not be applied. A value + of 0.0 means there is no dead band, and a value of 1.0 means it applied + over the whole range of the axis in question. + + The field `data.condition.center` must be filled in with a relative value + between -1.0 and 1.0 to determine the relative position of the "center" + of the effect around which the dead band is centered. It should be set to + 0.0 in case the center should not be shifted. + + The field `data.condition.right_coef` and + `data.condition.right_left_coef` must be filled in with a relative + coefficient, that will determine how quickly the effect ramps up on the + right and left side. If set to 1.0, then the effect will be immediately + at full intensity when outside of the dead band. If set to 0.0 the effect + will not be felt at all. + + If `type` is set to ALLEGRO_HAPTIC_RAMP, then `data.ramp.start_level` + should be set to a relative magnitude value between -1.0 and 1.0 to + determine the initial intensity of the haptic effect. The field + `data.ramp.end_level` should be set to a relative magnitude value between + -1.0 and 1.0 to determine the final intensity of the haptic effect at the + end of playback. + + If `type` is set to any of ALLEGRO_HAPTIC_PERIODIC, + ALLEGRO_HAPTIC_CONSTANT, ALLEGRO_HAPTIC_RAMP, then `data.envelope` + determines the "envelope" of the effect. That is, it determines the + duration and intensity for the ramp-up attack or "fade in" and the + ramp-down or "fade out" of the effect. + + In these cases the field `data.envelope.attack_level` must be set to a + relative value between 0.0 and 1.0 that determines the intensity the + effect should have when it starts playing (after `replay.delay` seconds + have passed since the playback was started). The field + `data.envelope.attack_length` must be set to the time in seconds that the + effect should ramp up to the maximum intensity as set by the other + parameters. If `data.envelope.attack_length` is 0, then the + effect will play immediately at full intensity. + + The field `data.envelope.fade_level` must be set to a relative value + between 0.0 and 1.0 that determines the intensity the effect should have + when it stops playing after `replay.length + replay.delay` seconds have + passed since the playback of the effect started. The field + `data.envelope.fade_length` must be set to the time in seconds that the + effect should fade out before it finishes playing. If + `data.envelope.fade_length` is 0, then the effect will not fade out. + + If you don't want to use an envelope, then set all four fields of + `data.envelope` to 0.0. The effect will then play back at full intensity + throughout its playback. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: ALLEGRO_HAPTIC_EFFECT_ID + +This struct is used as a handle to control playback of a haptic effect and should +be considered opaque. Its implementation is visible merely to allow allocation +by the users of the Allegro library. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_install_haptic + +Installs the haptic (force feedback) device subsystem. This must be called +before using any other haptic-related functions. Returns true if the haptics +subsystem could be initialized correctly, false in case of error. + +For portability you should first open a display before calling +[al_install_haptic]. On some platforms, such as DirectInput under +Windows, [al_install_haptic] will only work if at least one active +display is available. This display must stay available until +[al_uninstall_haptic] is called. + +If you need to close and reopen your active display for example, then you should +call [al_uninstall_haptic] before closing the display, and +[al_install_haptic] after opening it again. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_uninstall_haptic + +Uninstalls the haptic device subsystem. This is useful since on some +platforms haptic effects are bound to the active display. + +If you need to close and reopen your active display for example, then you should +call [al_uninstall_haptic] before closing the display, and +[al_install_haptic] after opening it again. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_haptic_installed + +Returns true if the haptic device subsystem is installed, false if not. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_mouse_haptic + +Returns true if the mouse has haptic capabilities, false if not. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_keyboard_haptic + +Returns true if the keyboard has haptic capabilities, false if not. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_display_haptic + +Returns true if the display has haptic capabilities, false if not. This +mainly concerns force feedback that shakes a hand held device, such as +a phone or a tablet. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_joystick_haptic + +Returns true if the joystick has haptic capabilities, false if not. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_touch_input_haptic + +Returns true if the touch input device has haptic capabilities, false if not. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_from_mouse + +If the mouse has haptic capabilities, returns the associated haptic device +handle. Otherwise returns NULL. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_from_keyboard + +If the keyboard has haptic capabilities, returns the associated haptic device +handle. Otherwise returns NULL. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_from_display + +If the display has haptic capabilities, returns the associated haptic device +handle. Otherwise returns NULL. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_from_joystick + +If the joystick has haptic capabilities, returns the associated haptic device +handle. Otherwise returns NULL. It's necessary to call this again every time +the joystick configuration changes, such as through hot plugging. In that case, +the old haptic device must be released using [al_release_haptic]. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_from_touch_input + +If the touch input device has haptic capabilities, returns the associated +haptic device handle. Otherwise returns NULL. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_release_haptic + +Releases the haptic device and its resources when it's not needed anymore. +Should also be used in case the joystick configuration changed, such as when +a joystick is hot plugged. This function also automatically releases all +haptic effects that are still uploaded to the device and that have not been +released manually using [al_release_haptic_effect]. + +Returns true on success or false if the haptic device couldn't be released +for any reason, such as NULL being passed, the device not being active or +failure in the driver. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_haptic_active + +Returns true if the haptic device can currently be used, false if not. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_capabilities + +Returns an integer with or'ed values from [ALLEGRO_HAPTIC_CONSTANTS], which, +if set, indicate that the haptic device supports the given feature. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_haptic_capable + +Returns true if the haptic device supports the feature indicated by +the query parameter, false if the feature is not supported. +The query parameter must be one of the values of [ALLEGRO_HAPTIC_CONSTANTS]. + +Since: 5.1.9 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +See also: [al_get_haptic_capabilities] + +## API: al_set_haptic_gain + +Sets the gain of the haptic device if supported. Gain is much like volume for +sound, it is as if every effect's intensity is multiplied by it. Gain is a +value between 0.0 and 1.0. Returns true if set successfully, false if not. +Only works if [al_get_haptic_capabilities] returns a value that has +[ALLEGRO_HAPTIC_GAIN][ALLEGRO_HAPTIC_CONSTANTS] set. If not, this +function returns false, and all +effects will be played without any gain influence. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_gain + +Returns the current gain of the device. Gain is much like volume for sound, +it is as if every effect's intensity is multiplied by it. Gain is a value +between 0.0 and 1.0. Only works correctly if [al_get_haptic_capabilities] +returns a value that has [ALLEGRO_HAPTIC_GAIN][ALLEGRO_HAPTIC_CONSTANTS] + set. If this is not set, this +function will simply return 1.0 and all effects will be played without any +gain influence. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_set_haptic_autocenter + +Turns on or off the automatic centering feature of the haptic device if +supported. Depending on the device automatic centering may ensure that the +axes of the device are centered again automatically after playing +a haptic effect. The intensity parameter should be passed with a value +between 0.0 and 1.0. The value 0.0 means automatic centering is +disabled, and 1.0 means full strength automatic centering. Any value +in between those two extremes will result in partial automatic +centering. Some platforms do not support partial automatic +centering. If that is the case, a value of less than 0.5 will turn +it off, while a value equal to or higher to 0.5 will turn it on. +Returns true if set successfully, false if not. +Can only work if [al_get_haptic_capabilities] returns a value that has +[ALLEGRO_HAPTIC_AUTOCENTER][ALLEGRO_HAPTIC_CONSTANTS] set. If not, this +function returns false. + +Since: 5.1.9 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_autocenter + +Returns the current automatic centering intensity of the device. +Depending on the device automatic centering may ensure that the +axes of the device are centered again automatically after playing +a haptic effect. The return value can be between 0.0 and 1.0. +The value 0.0 means automatic centering is disabled, and 1.0 means +automatic centering is enabled at full strength. Any value +in between those two extremes means partial automatic +centering is enabled. Some platforms do not support partial automatic +centering. If that is the case, a value of less than 0.5 means it is turned +off, while a value equal to or higher to 0.5 means it is turned on. +Can only work if [al_get_haptic_capabilities] returns a +value that has [ALLEGRO_HAPTIC_AUTOCENTER][ALLEGRO_HAPTIC_CONSTANTS] +set. If not, this function returns 0.0. + +Since: 5.1.9 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_max_haptic_effects + +Returns the maximum amount of haptic effects that can be uploaded to the +device. This depends on the operating system, driver, platform and the +device itself. This may return a value as low as 1. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_haptic_effect_ok + +Returns true if the haptic device can play the haptic effect as given, false +if not. The haptic effect must have been filled in completely and correctly. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_upload_haptic_effect + +Uploads the haptic effect to the device. The haptic effect must have been +filled in completely and correctly. You must also pass in a pointer to a +user allocated [ALLEGRO_HAPTIC_EFFECT_ID]. This `id` can be used to control +playback of the effect. Returns true if the effect was successfully uploaded, +false if not. + +The function [al_get_max_haptic_effects] returns how many effects can +be uploaded to the device at the same time. + +The same haptic effect can be uploaded several times, as long as care is +taken to pass in a different [ALLEGRO_HAPTIC_EFFECT_ID]. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_play_haptic_effect + +Plays back a previously uploaded haptic effect. The play_id must be a valid +[ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect], +[al_upload_and_play_haptic_effect] or [al_rumble_haptic]. + +The haptic effect will be played back loop times in sequence. If loop is less +than or equal to 1, then the effect will be played once only. + +This function returns immediately and doesn't wait for the playback to +finish. It returns true if the playback was started successfully or false if +not. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_upload_and_play_haptic_effect + +Uploads the haptic effect to the device and starts playback immediately. Returns +true if the upload and playback were successful, false if either failed. + +In case false is returned, the haptic effect will be automatically +released as if [al_release_haptic_effect] had been called, so there +is no need to call it again manually in this case. However, +if true is returned, it is necessary to call [al_release_haptic_effect] +when the effect isn't needed anymore, to prevent the amount of available +effects on the haptic devicefrom running out. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +See also: [al_upload_haptic_effect], [al_play_haptic_effect] + +## API: al_stop_haptic_effect + +Stops playing a previously uploaded haptic effect. The play_id must be a +valid [ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect], +[al_upload_and_play_haptic_effect] or [al_rumble_haptic]. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_is_haptic_effect_playing + +Returns true if the haptic effect is currently playing. Returns false if the +effect has been stopped or if it has already finished playing, or if it has not been +played yet. The play_id must be a valid [ALLEGRO_HAPTIC_EFFECT_ID] obtained +from [al_upload_haptic_effect], [al_upload_and_play_haptic_effect] or +[al_rumble_haptic]. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_get_haptic_effect_duration + +Returns the estimated duration in seconds of a single loop of the given haptic +effect. The effect's `effect.replay` must have been filled in correctly +before using this function. + +Since: 5.1.9 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_release_haptic_effect + +Releases a previously uploaded haptic effect from the device it has been +uploaded to, allowing for other effects to be uploaded. The play_id must be +a valid [ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect], +[al_upload_and_play_haptic_effect] or [al_rumble_haptic]. + +This function is called automatically when you call [al_release_haptic] +on a [ALLEGRO_HAPTIC] for all effects that are still uploaded to the device. +Therefore this function is most useful if you want to upload and release +haptic effects dynamically, for example as a way to circumvent the limit +imposed by [al_get_max_haptic_effects]. + +Returns true on success, false if the effect couldn't be released for any +reason such as when NULL is passed, the effect is not active or failure +to release the effect by the driver. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. + +## API: al_rumble_haptic + +Uploads a simple rumble effect to the haptic device and starts playback +immediately. The parameter `intensity` is a relative magnitude between 0.0 +and 1.0 that determines the intensity of the rumble effect. The `duration` +determines the duration of the effect in seconds. + +You must also pass in a pointer to a user allocated +[ALLEGRO_HAPTIC_EFFECT_ID]. It it is stored a reference to be used to +control playback of the effect. Returns true if the rumble effect was +successfully uploaded and started, false if not. + +In case false is returned, the rumble effect will be automatically +released as if [al_release_haptic_effect] had been called, so there +is no need to call it again manually in this case. However, +if true is returned, it is necessary to call [al_release_haptic_effect] +when the effect isn't needed anymore, to prevent the amount of available +effects on the haptic device from running out. + +Since: 5.1.8 + +> *[Unstable API]:* Perhaps could be simplified due to limited support for all the +exposed features across all of the platforms. Awaiting feedback from users. diff --git a/allegro/docs/src/refman/image.txt b/allegro/docs/src/refman/image.txt new file mode 100644 index 00000000..4786994e --- /dev/null +++ b/allegro/docs/src/refman/image.txt @@ -0,0 +1,46 @@ +# Image I/O addon + +These functions are declared in the following header file. +Link with allegro_image. + +~~~~c + #include +~~~~ + +Some of the format handlers define configuration options for specifying things +like compression level or gamma handling. Refer to [al_get_system_config] for +their documentation. + +## API: al_init_image_addon + +Initializes the image addon. This registers bitmap format handlers for +[al_load_bitmap], [al_load_bitmap_f], [al_save_bitmap], [al_save_bitmap_f]. + +The following types are built into the Allegro image addon and guaranteed to be +available: BMP, DDS, PCX, TGA. Every platform also supports JPEG and PNG +via external dependencies. + +Other formats may be available depending on the operating system and +installed libraries, but are not guaranteed and should not be assumed to +be universally available. + +The DDS format is only supported to load from, and only if the DDS file +contains textures compressed in the DXT1, DXT3 and DXT5 formats. Note that when +loading a DDS file, the created bitmap will always be a video bitmap and will +have the pixel format matching the format in the file. + +## API: al_is_image_addon_initialized + +Returns true if the image addon is initialized, otherwise returns false. + +Since: 5.2.6 + +## API: al_shutdown_image_addon + +Shut down the image addon. This is done automatically at program exit, +but can be called any time the user wishes as well. + +## API: al_get_allegro_image_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. diff --git a/allegro/docs/src/refman/images/LINE_CAP.png b/allegro/docs/src/refman/images/LINE_CAP.png new file mode 100644 index 00000000..c75329e3 Binary files /dev/null and b/allegro/docs/src/refman/images/LINE_CAP.png differ diff --git a/allegro/docs/src/refman/images/LINE_CAP.svg b/allegro/docs/src/refman/images/LINE_CAP.svg new file mode 100644 index 00000000..6c7b37ee --- /dev/null +++ b/allegro/docs/src/refman/images/LINE_CAP.svg @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + NONE + SQUARE + ROUND + TRIANGLE + + + + + + + + + + + + + + diff --git a/allegro/docs/src/refman/images/LINE_JOIN.png b/allegro/docs/src/refman/images/LINE_JOIN.png new file mode 100644 index 00000000..ee202906 Binary files /dev/null and b/allegro/docs/src/refman/images/LINE_JOIN.png differ diff --git a/allegro/docs/src/refman/images/LINE_JOIN.svg b/allegro/docs/src/refman/images/LINE_JOIN.svg new file mode 100644 index 00000000..e0365222 --- /dev/null +++ b/allegro/docs/src/refman/images/LINE_JOIN.svg @@ -0,0 +1,183 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + NONE + BEVEL + ROUND + MITER 4 + + + + + + + + + + diff --git a/allegro/docs/src/refman/images/audio.png b/allegro/docs/src/refman/images/audio.png new file mode 100644 index 00000000..9ad15946 Binary files /dev/null and b/allegro/docs/src/refman/images/audio.png differ diff --git a/allegro/docs/src/refman/images/audio.svg b/allegro/docs/src/refman/images/audio.svg new file mode 100644 index 00000000..9bc7d3ca --- /dev/null +++ b/allegro/docs/src/refman/images/audio.svg @@ -0,0 +1,651 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + ALLEGRO_AUDIO_STREAM + + ALLEGRO_MIXER + + ALLEGRO_MIXER + + ALLEGRO_VOICE + + ALLEGRO_SAMPLE_INSTANCE + + ALLEGRO_SAMPLE + + + + + Speakers / headphones + + + + + sound.wav + + music.ogg + + ALLEGRO_SAMPLE_INSTANCE + + + diff --git a/allegro/docs/src/refman/images/primitives1.png b/allegro/docs/src/refman/images/primitives1.png new file mode 100644 index 00000000..61fe3667 Binary files /dev/null and b/allegro/docs/src/refman/images/primitives1.png differ diff --git a/allegro/docs/src/refman/images/primitives1.svg b/allegro/docs/src/refman/images/primitives1.svg new file mode 100644 index 00000000..4371e8cf --- /dev/null +++ b/allegro/docs/src/refman/images/primitives1.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + x + y + 0 + 1 + 2 + 3 + 0 + 1 + 2 + 3 + (0.5, 0.5) + + + + + + + + + + + + + + + x + y + 0 + 1 + 2 + 3 + 0 + 1 + 2 + 3 + + + + + + + diff --git a/allegro/docs/src/refman/images/primitives2.png b/allegro/docs/src/refman/images/primitives2.png new file mode 100644 index 00000000..7f5d2c1b Binary files /dev/null and b/allegro/docs/src/refman/images/primitives2.png differ diff --git a/allegro/docs/src/refman/images/primitives2.svg b/allegro/docs/src/refman/images/primitives2.svg new file mode 100644 index 00000000..41cb6414 --- /dev/null +++ b/allegro/docs/src/refman/images/primitives2.svg @@ -0,0 +1,1524 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + x + y + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 2 + 4 + 6 + 0 + 2 + 4 + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + x + y + + + + + + + + + + + + + 0 + 2 + 4 + 6 + 0 + 2 + 4 + 6 + + + + + diff --git a/allegro/docs/src/refman/inc.a.txt b/allegro/docs/src/refman/inc.a.txt new file mode 100644 index 00000000..f1bb4c72 --- /dev/null +++ b/allegro/docs/src/refman/inc.a.txt @@ -0,0 +1,81 @@ + + +
+ diff --git a/allegro/docs/src/refman/inc.z.txt b/allegro/docs/src/refman/inc.z.txt new file mode 100644 index 00000000..04f5b844 --- /dev/null +++ b/allegro/docs/src/refman/inc.z.txt @@ -0,0 +1 @@ +
diff --git a/allegro/docs/src/refman/index.txt b/allegro/docs/src/refman/index.txt new file mode 100644 index 00000000..e88c8c3b --- /dev/null +++ b/allegro/docs/src/refman/index.txt @@ -0,0 +1,54 @@ +% Allegro 5 reference manual + + + + +* [Getting started guide](getting_started.html) + +Core API +=== + +* [Configuration files](config.html) +* [Displays](display.html) +* [Events](events.html) +* [File I/O](file.html) +* [Filesystem](fshook.html) +* [Fixed point math](fixed.html) +* [Fullscreen modes](fullscreen_mode.html) +* [Graphics routines](graphics.html) +* [Haptic routines](haptic.html) +* [Joystick routines](joystick.html) +* [Keyboard routines](keyboard.html) +* [Memory management](memory.html) +* [Monitors](monitor.html) +* [Mouse routines](mouse.html) +* [Path structures](path.html) +* [Shader](shader.html) +* [State](state.html) +* [System routines](system.html) +* [Threads](threads.html) +* [Time](time.html) +* [Timer](timer.html) +* [Touch input](touch.html) +* [Transformations](transformations.html) +* [UTF-8 string routines](utf8.html) +* [Miscellaneous](misc.html) +* [Platform-specific](platform.html) +* [Direct3D integration](direct3d.html) +* [OpenGL integration](opengl.html) + +Addons +====== + +* [Audio addon](audio.html) +* [Audio codecs](acodec.html) +* [Color addon](color.html) +* [Font addons](font.html) +* [Image I/O addon](image.html) +* [Main addon](main.html) +* [Memfile addon](memfile.html) +* [Native dialogs addon](native_dialog.html) +* [PhysicsFS addon](physfs.html) +* [Primitives addon](primitives.html) +* [Video streaming addon](video.html) + diff --git a/allegro/docs/src/refman/joystick.txt b/allegro/docs/src/refman/joystick.txt new file mode 100644 index 00000000..2a0398a4 --- /dev/null +++ b/allegro/docs/src/refman/joystick.txt @@ -0,0 +1,204 @@ +# Joystick routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +On Windows there are two joystick drivers, a DirectInput one and an Xinput +one. If support for XInput was compiled in, then it can be enabled by +calling al_set_config_value(al_get_system_config(), "joystick", "driver", +"xinput") before calling al_install_joystick, or by setting the same +option in the allegro5.cfg configuration file. The Xinput and DirectInput +drivers are mutually exclusive. The haptics subsystem will use the +same driver as the joystick system does. + +## API: ALLEGRO_JOYSTICK + +This is an abstract data type representing a physical joystick. + +See also: [al_get_joystick] + +## API: ALLEGRO_JOYSTICK_STATE + +This is a structure that is used to hold a "snapshot" of a +joystick's axes and buttons at a particular instant. +All fields public and read-only. + +~~~~c +struct { + float axis[num_axes]; // -1.0 to 1.0 +} stick[num_sticks]; +int button[num_buttons]; // 0 to 32767 +~~~~ + +See also: [al_get_joystick_state] + +## API: ALLEGRO_JOYFLAGS + +* ALLEGRO_JOYFLAG_DIGITAL - the stick provides digital input +* ALLEGRO_JOYFLAG_ANALOGUE - the stick provides analogue input + +(this enum is a holdover from the old API and may be removed) + +See also: [al_get_joystick_stick_flags] + +## API: al_install_joystick + +Install a joystick driver, returning true if successful. If a +joystick driver was already installed, returns true immediately. + +See also: [al_uninstall_joystick] + +## API: al_uninstall_joystick + +Uninstalls the active joystick driver. All outstanding [ALLEGRO_JOYSTICK] +structures are invalidated. If no joystick driver +was active, this function does nothing. + +This function is automatically called when Allegro is shut down. + +See also: [al_install_joystick] + +## API: al_is_joystick_installed + +Returns true if [al_install_joystick] was called successfully. + +## API: al_reconfigure_joysticks + +Allegro is able to cope with users connecting and disconnected joystick devices +on-the-fly. On existing platforms, the joystick event source will generate an +event of type `ALLEGRO_EVENT_JOYSTICK_CONFIGURATION` when a device is plugged +in or unplugged. In response, you should call [al_reconfigure_joysticks]. + +Afterwards, the number returned by [al_get_num_joysticks] may be different, +and the handles returned by [al_get_joystick] may be different or be ordered +differently. + +All [ALLEGRO_JOYSTICK] handles remain valid, but handles for disconnected +devices become inactive: their states will no longer update, and +[al_get_joystick] will not return the handle. Handles for devices which remain +connected will continue to represent the same devices. Previously inactive +handles may become active again, being reused to represent newly connected +devices. + +Returns true if the joystick configuration changed, otherwise returns false. + +It is possible that on some systems, Allegro won't be able to generate +`ALLEGRO_EVENT_JOYSTICK_CONFIGURATION` events. If your game has an input +configuration screen or similar, you may wish to call +[al_reconfigure_joysticks] when entering that screen. + +See also: [al_get_joystick_event_source], [ALLEGRO_EVENT] + +## API: al_get_num_joysticks + +Return the number of joysticks currently on the system (or potentially on the +system). This number can change after [al_reconfigure_joysticks] is called, in +order to support hotplugging. + +Returns 0 if there is no joystick driver installed. + +See also: [al_get_joystick], [al_get_joystick_active] + +## API: al_get_joystick + +Get a handle for a joystick on the system. The number may be from 0 to +[al_get_num_joysticks]-1. If successful a pointer to a joystick object is +returned, which represents a physical device. Otherwise NULL is returned. + +The handle and the index are only incidentally linked. After +[al_reconfigure_joysticks] is called, [al_get_joystick] may return handles in a +different order, and handles which represent disconnected devices will not be +returned. + +See also: [al_get_num_joysticks], [al_reconfigure_joysticks], +[al_get_joystick_active] + +## API: al_release_joystick + +This function currently does nothing. + +See also: [al_get_joystick] + +## API: al_get_joystick_active + +Return if the joystick handle is "active", i.e. in the current configuration, +the handle represents some physical device plugged into the system. +[al_get_joystick] returns active handles. After reconfiguration, active +handles may become inactive, and vice versa. + +See also: [al_reconfigure_joysticks] + +## API: al_get_joystick_name + +Return the name of the given joystick. + +See also: [al_get_joystick_stick_name], [al_get_joystick_axis_name], +[al_get_joystick_button_name] + +## API: al_get_joystick_stick_name + +Return the name of the given "stick". If the stick doesn't +exist, NULL is returned. + +See also: [al_get_joystick_axis_name], [al_get_joystick_num_sticks] + +## API: al_get_joystick_axis_name + +Return the name of the given axis. If the axis doesn't exist, +NULL is returned. +Indices begin from 0. + +See also: [al_get_joystick_stick_name], [al_get_joystick_num_axes] + +## API: al_get_joystick_button_name + +Return the name of the given button. If the button doesn't exist, +NULL is returned. +Indices begin from 0. + +See also: [al_get_joystick_stick_name], [al_get_joystick_axis_name], +[al_get_joystick_num_buttons] + +## API: al_get_joystick_stick_flags + +Return the flags of the given "stick". If the stick doesn't +exist, NULL is returned. +Indices begin from 0. + +See also: [ALLEGRO_JOYFLAGS] + +## API: al_get_joystick_num_sticks + +Return the number of "sticks" on the given joystick. +A stick has one or more axes. + +See also: [al_get_joystick_num_axes], [al_get_joystick_num_buttons] + +## API: al_get_joystick_num_axes + +Return the number of axes on the given "stick". If the stick +doesn't exist, 0 is returned. + +See also: [al_get_joystick_num_sticks] + +## API: al_get_joystick_num_buttons + +Return the number of buttons on the joystick. + +See also: [al_get_joystick_num_sticks] + +## API: al_get_joystick_state + +Get the current joystick state. + +See also: [ALLEGRO_JOYSTICK_STATE], [al_get_joystick_num_buttons], +[al_get_joystick_num_axes] + +## API: al_get_joystick_event_source + +Returns the global joystick event source. All +[joystick events][ALLEGRO_EVENT_JOYSTICK_AXIS] are generated by +this event source. diff --git a/allegro/docs/src/refman/keyboard.txt b/allegro/docs/src/refman/keyboard.txt new file mode 100644 index 00000000..69ebdf58 --- /dev/null +++ b/allegro/docs/src/refman/keyboard.txt @@ -0,0 +1,222 @@ +# Keyboard routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_KEYBOARD_STATE + +This is a structure that is used to hold a "snapshot" of a keyboard's +state at a particular instant. It contains the following publically +readable fields: + +* display - points to the display that had keyboard focus at the time +the state was saved. If no display was focused, this points +to NULL. + +You cannot read the state of keys directly. Use the function +[al_key_down]. + +## Key codes + +The constant ALLEGRO_KEY_MAX is always one higher than +the highest key code. So if you want to use the key code as array index +you can do something like this: + +~~~~c +bool pressed_keys[ALLEGRO_KEY_MAX]; +//... +pressed_keys[key_code] = true; +~~~~ + +These are the list of key codes used by Allegro, which are returned in +the event.keyboard.keycode field of the ALLEGRO_KEY_DOWN and +ALLEGRO_KEY_UP events and which you can pass to [al_key_down]: + + ALLEGRO_KEY_A ... ALLEGRO_KEY_Z + ALLEGRO_KEY_0 ... ALLEGRO_KEY_9 + ALLEGRO_KEY_PAD_0 ... ALLEGRO_KEY_PAD_9 + ALLEGRO_KEY_F1 ... ALLEGRO_KEY_F12 + ALLEGRO_KEY_ESCAPE + ALLEGRO_KEY_TILDE + ALLEGRO_KEY_MINUS + ALLEGRO_KEY_EQUALS + ALLEGRO_KEY_BACKSPACE + ALLEGRO_KEY_TAB + ALLEGRO_KEY_OPENBRACE + ALLEGRO_KEY_CLOSEBRACE + ALLEGRO_KEY_ENTER + ALLEGRO_KEY_SEMICOLON + ALLEGRO_KEY_QUOTE + ALLEGRO_KEY_BACKSLASH + ALLEGRO_KEY_BACKSLASH2 + ALLEGRO_KEY_COMMA + ALLEGRO_KEY_FULLSTOP + ALLEGRO_KEY_SLASH + ALLEGRO_KEY_SPACE + ALLEGRO_KEY_INSERT + ALLEGRO_KEY_DELETE + ALLEGRO_KEY_HOME + ALLEGRO_KEY_END + ALLEGRO_KEY_PGUP + ALLEGRO_KEY_PGDN + ALLEGRO_KEY_LEFT + ALLEGRO_KEY_RIGHT + ALLEGRO_KEY_UP + ALLEGRO_KEY_DOWN + ALLEGRO_KEY_PAD_SLASH + ALLEGRO_KEY_PAD_ASTERISK + ALLEGRO_KEY_PAD_MINUS + ALLEGRO_KEY_PAD_PLUS + ALLEGRO_KEY_PAD_DELETE + ALLEGRO_KEY_PAD_ENTER + ALLEGRO_KEY_PRINTSCREEN + ALLEGRO_KEY_PAUSE + ALLEGRO_KEY_ABNT_C1 + ALLEGRO_KEY_YEN + ALLEGRO_KEY_KANA + ALLEGRO_KEY_CONVERT + ALLEGRO_KEY_NOCONVERT + ALLEGRO_KEY_AT + ALLEGRO_KEY_CIRCUMFLEX + ALLEGRO_KEY_COLON2 + ALLEGRO_KEY_KANJI + ALLEGRO_KEY_LSHIFT + ALLEGRO_KEY_RSHIFT + ALLEGRO_KEY_LCTRL + ALLEGRO_KEY_RCTRL + ALLEGRO_KEY_ALT + ALLEGRO_KEY_ALTGR + ALLEGRO_KEY_LWIN + ALLEGRO_KEY_RWIN + ALLEGRO_KEY_MENU + ALLEGRO_KEY_SCROLLLOCK + ALLEGRO_KEY_NUMLOCK + ALLEGRO_KEY_CAPSLOCK + ALLEGRO_KEY_PAD_EQUALS + ALLEGRO_KEY_BACKQUOTE + ALLEGRO_KEY_SEMICOLON2 + ALLEGRO_KEY_COMMAND + + /* Since: 5.1.1 */ + /* Android only for now */ + ALLEGRO_KEY_BACK + + /* Since: 5.1.2 */ + /* Android only for now */ + ALLEGRO_KEY_VOLUME_UP + ALLEGRO_KEY_VOLUME_DOWN + + /* Since: 5.1.6 */ + /* Android only for now */ + ALLEGRO_KEY_SEARCH + ALLEGRO_KEY_DPAD_CENTER + ALLEGRO_KEY_BUTTON_X + ALLEGRO_KEY_BUTTON_Y + ALLEGRO_KEY_DPAD_UP + ALLEGRO_KEY_DPAD_DOWN + ALLEGRO_KEY_DPAD_LEFT + ALLEGRO_KEY_DPAD_RIGHT + ALLEGRO_KEY_SELECT + ALLEGRO_KEY_START + ALLEGRO_KEY_L1 + ALLEGRO_KEY_R1 + +## Keyboard modifier flags + + ALLEGRO_KEYMOD_SHIFT + ALLEGRO_KEYMOD_CTRL + ALLEGRO_KEYMOD_ALT + ALLEGRO_KEYMOD_LWIN + ALLEGRO_KEYMOD_RWIN + ALLEGRO_KEYMOD_MENU + ALLEGRO_KEYMOD_ALTGR + ALLEGRO_KEYMOD_COMMAND + ALLEGRO_KEYMOD_SCROLLLOCK + ALLEGRO_KEYMOD_NUMLOCK + ALLEGRO_KEYMOD_CAPSLOCK + ALLEGRO_KEYMOD_INALTSEQ + ALLEGRO_KEYMOD_ACCENT1 + ALLEGRO_KEYMOD_ACCENT2 + ALLEGRO_KEYMOD_ACCENT3 + ALLEGRO_KEYMOD_ACCENT4 + +The event field 'keyboard.modifiers' is a bitfield composed of these constants. +These indicate the modifier keys which were pressed at the time a character was +typed. + +## API: al_install_keyboard + +Install a keyboard driver. Returns true if successful. If a driver +was already installed, nothing happens and true is returned. + +See also: [al_uninstall_keyboard], [al_is_keyboard_installed] + +## API: al_is_keyboard_installed + +Returns true if [al_install_keyboard] was called successfully. + +## API: al_uninstall_keyboard + +Uninstalls the active keyboard driver, if any. This will +automatically unregister the keyboard event source with any event +queues. + +This function is automatically called when Allegro is shut down. + +See also: [al_install_keyboard] + +## API: al_get_keyboard_state + +Save the state of the keyboard specified at the time the function +is called into the structure pointed to by *ret_state*. + +See also: [al_key_down], [al_clear_keyboard_state], [ALLEGRO_KEYBOARD_STATE] + +## API: al_clear_keyboard_state + +Clear the state of the keyboard, emitting [ALLEGRO_EVENT_KEY_UP] for +each currently pressed key. The given display is regarded as the one +which had the keyboard focus when the event occurred. In case display +is NULL no event is emitted. For most keyboard drivers Allegro +maintains its own state of the keyboard, which might get out of sync +with the real one. This function is intended to remedy such situation +by resetting Allegro's keyboard state to a known default (no key +pressed). This is particularly useful in response to +[ALLEGRO_EVENT_DISPLAY_SWITCH_OUT] events. + +See also: [al_get_keyboard_state], [ALLEGRO_KEYBOARD_STATE] + +Since: 5.2.3 + +> *[Unstable API]:* This is a new feature and the exact semantics are still +being decided upon. + +## API: al_key_down + +Return true if the key specified was held down in the state +specified. + +See also: [ALLEGRO_KEYBOARD_STATE] + +## API: al_keycode_to_name + +Converts the given keycode to a description of the key. + +## API: al_set_keyboard_leds + +Overrides the state of the keyboard LED indicators. Set `leds` to a +combination of the keyboard modifier flags to enable the corresponding LED +indicators (`ALLEGRO_KEYMOD_NUMLOCK`, `ALLEGRO_KEYMOD_CAPSLOCK` and +`ALLEGRO_KEYMOD_SCROLLLOCK` are supported) or to -1 to return to default +behavior. False is returned if the current keyboard driver cannot set LED +indicators. + +## API: al_get_keyboard_event_source + +Retrieve the keyboard event source. All [keyboard events][ALLEGRO_EVENT_KEY_DOWN] +are generated by this event source. + +Returns NULL if the keyboard subsystem was not installed. diff --git a/allegro/docs/src/refman/latex.template b/allegro/docs/src/refman/latex.template new file mode 100644 index 00000000..473a2a12 --- /dev/null +++ b/allegro/docs/src/refman/latex.template @@ -0,0 +1,210 @@ +%% This template is a modified version of the default pandoc latex template. +%% Changes are marked with double-%% comments. +%% Most of it was "inspired" by the Memoir manual. + +$if(legacy-header)$ +$legacy-header$ +$else$ +%% Replacement for the book document class. +\documentclass[a4paper]{memoir} + +%% The default layout looks too wasteful to me. +\usepackage[a4paper,hmargin=2.6cm,top=2.4cm,bottom=3cm,footskip=1cm,centering]{geometry} + +%% ToC down to subsections +\settocdepth{subsection} +%% Numbering down to subsections as well +\setsecnumdepth{subsection} + +%% Choose a nice looking chapter style. +\chapterstyle{ell} +%\chapterstyle{ger} + +%% Choose a nice font. +\usepackage[T1]{fontenc} +%\usepackage{mathpazo} % roman=Palatino +%\usepackage{mathptmx} % roman=Times +%\usepackage{newcent} % roman=New Century Schoolbook +\usepackage{lmodern} % sansserif=Latin Modern Sans +\usepackage{charter} % roman=Charter +\usepackage{inconsolata} % typewriter=Inconsolata +% TODO: I don't like the sans serif fonts much. + +%% Does this help with overlongs? +\midsloppy + +%% The long identifiers make justified text look quite ugly. +\raggedright + +%% In definition lists, start the description on the next line. +\usepackage{enumitem} +\setdescription{style=nextline} + +\usepackage{amssymb,amsmath} +$if(xetex)$ +\usepackage{ifxetex} +\ifxetex + \usepackage{fontspec,xltxtra,xunicode} + \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase} +\else + \usepackage[mathletters]{ucs} + \usepackage[utf8x]{inputenc} +\fi +$else$ +\usepackage[mathletters]{ucs} +\usepackage[utf8x]{inputenc} +$endif$ +$if(lhs)$ +\usepackage{listings} +\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} +$endif$ +$endif$ + +%% Use `Verbatim' environments so we can offset them slightly. +\usepackage{fancyvrb} +\fvset{xleftmargin=8pt} + +$if(fancy-enums)$ +% Redefine labelwidth for lists; otherwise, the enumerate package will cause +% markers to extend beyond the left margin. +\makeatletter\AtBeginDocument{% + \renewcommand{\@listi} + {\setlength{\labelwidth}{4em}} +}\makeatother +\usepackage{enumerate} +$endif$ +$if(tables)$ +\usepackage{array} +% This is needed because raggedright in table elements redefines \\: +\newcommand{\PreserveBackslash}[1]{\let\temp=\\#1\let\\=\temp} +\let\PBS=\PreserveBackslash +$endif$ +$if(strikeout)$ +\usepackage[normalem]{ulem} +$endif$ +$if(subscript)$ +\newcommand{\textsubscr}[1]{\ensuremath{_{\scriptsize\textrm{#1}}}} +$endif$ +$if(url)$ +\usepackage{url} +$endif$ +$if(graphics)$ +\usepackage{graphicx} +% We will generate all images so they have a width \maxwidth. This means +% that they will get their normal width if they fit onto the page, but +% are scaled down if they would overflow the margins. +\makeatletter +\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth +\else\Gin@nat@width\fi} +\makeatother +\let\Oldincludegraphics\includegraphics +\renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=\maxwidth]{#1}} +$endif$ +\usepackage[breaklinks=true,unicode=true]{hyperref} + +%% Nice coloured links. +\usepackage{color} +\definecolor{linkcolor}{rgb}{0.2,0.2,0.45} +\hypersetup{ + colorlinks=true, + linkcolor=linkcolor, + citecolor=linkcolor, + filecolor=linkcolor, + urlcolor=linkcolor +} + +\setlength{\parindent}{0pt} +\setlength{\parskip}{6pt plus 2pt minus 1pt} +$if(numbersections)$ +$else$ +\setcounter{secnumdepth}{0} +$endif$ +$if(verbatim-in-note)$ +\VerbatimFootnotes % allows verbatim text in footnotes +$endif$ +$for(header-includes)$ +$header-includes$ +$endfor$ + +$if(title)$ +\title{$title$} +$endif$ +$if(author)$ +\author{$for(author)$$author$$sep$\\$endfor$} +$endif$ +$if(date)$ +\date{$date$} +$endif$ + +\begin{document} + +%% Make a nice title page. +\frontmatter +\pagestyle{empty} % no page numbers, etc. +\vspace*{\fill} +\begin{center} +\HUGE\textsf{The Allegro 5 Library}\par +\end{center} +\begin{center} +\HUGE\textsf{Reference Manual}\par +\end{center} +\begin{center} +\vspace*{10pt} +\LARGE\textsf{Version \input{allegro_version.tex}}\par +\end{center} +\begin{center} +\vspace*{\fill} +\LARGE{\textcopyright{} 2008 --- 2015} +\end{center} +\cleardoublepage +\pagestyle{ruled} + +%% Fiddle with the spacing in table of contents. +\setlength\cftsectionindent{1.5em} +\setlength\cftsubsectionindent{1.5em} +\setlength\cftchapternumwidth{2em} +\setlength\cftsectionnumwidth{3.7em} +\setlength\cftsubsectionnumwidth{4.7em} + +%% For syntax highlighting +\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} +\newenvironment{Shaded}{}{} +\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} +\newcommand{\ImportTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} +\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} +\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} +\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}} +\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} +\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} +\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} +\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} +\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} +\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} +\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}} +\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} +\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} +\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}} +\newcommand{\RegionMarkerTok}[1]{{#1}} +\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} +\newcommand{\NormalTok}[1]{{#1}} + +$for(include-before)$ +$include-before$ + +$endfor$ +$if(toc)$ +\tableofcontents + +$endif$ + +%% This enables page numbers, etc. +\mainmatter + +$body$ +$for(include-after)$ + +$include-after$ +$endfor$ + +\end{document} +%% vim: set ft=tex et: diff --git a/allegro/docs/src/refman/main.txt b/allegro/docs/src/refman/main.txt new file mode 100644 index 00000000..469b1092 --- /dev/null +++ b/allegro/docs/src/refman/main.txt @@ -0,0 +1,24 @@ +# Main addon + +The `main` addon has no public API, but contains functionality to enable +programs using Allegro to build and run without platform-specific changes. + +On platforms that require this functionality (e.g. OSX) this addon contains a +C `main` function that invokes [al_run_main] with the user's own `main` +function, where the user's `main` function has had its name mangled to +something else. The file that defines the user `main` function must include +the header file `allegro5/allegro.h`; that header performs the name mangling +using some macros. + +If the user `main` function is defined in C++, then it must have the +following signature for this addon to work: + +~~~~c +int main(int argc, char **argv) +~~~~ + +This addon does nothing on platforms that don't require its functionality, but +you should keep it in mind in case you need to port to platforms that do +require it. + +Link with allegro_main. diff --git a/allegro/docs/src/refman/memfile.txt b/allegro/docs/src/refman/memfile.txt new file mode 100644 index 00000000..dc5f077e --- /dev/null +++ b/allegro/docs/src/refman/memfile.txt @@ -0,0 +1,30 @@ +# Memfile interface + +The memfile interface allows you to treat a fixed block of contiguous +memory as a file that can be used with Allegro's I/O functions. + +These functions are declared in the following header file. +Link with allegro_memfile. + +~~~~c + #include +~~~~ + +## API: al_open_memfile + +Returns a file handle to the block of memory. All read and write operations +act upon the memory directly, so it must not be freed while the file remains +open. + +The mode can be any combination of "r" (readable) and "w" (writable). +Regardless of the mode, the file always opens at position 0. The file size +is fixed and cannot be expanded. The file is always read from/written to in +binary mode, which means that no newline translation is performed. + +It should be closed with [al_fclose]. After the file is closed, you are +responsible for freeing the memory (if needed). + +## API: al_get_allegro_memfile_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. diff --git a/allegro/docs/src/refman/memory.txt b/allegro/docs/src/refman/memory.txt new file mode 100644 index 00000000..bfc36bb0 --- /dev/null +++ b/allegro/docs/src/refman/memory.txt @@ -0,0 +1,103 @@ +# Memory management routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: al_malloc + +Like malloc() in the C standard library, but the implementation may be +overridden. + +This is a macro. + +See also: [al_free], [al_realloc], [al_calloc], [al_malloc_with_context], +[al_set_memory_interface] + +## API: al_free + +Like free() in the C standard library, but the implementation may be +overridden. + +Additionally, on Windows, a memory block allocated by one DLL must be freed +from the same DLL. In the few places where an Allegro function returns a +pointer that must be freed, you must use [al_free] for portability to Windows. + +This is a macro. + +See also: [al_malloc], [al_free_with_context] + +## API: al_realloc + +Like realloc() in the C standard library, but the implementation may be +overridden. + +This is a macro. + +See also: [al_malloc], [al_realloc_with_context] + +## API: al_calloc + +Like calloc() in the C standard library, but the implementation may be +overridden. + +This is a macro. + +See also: [al_malloc], [al_calloc_with_context] + +## API: al_malloc_with_context + +This calls malloc() from the Allegro library (this matters on Windows), +unless overridden with [al_set_memory_interface], + +Generally you should use the [al_malloc] macro. + +## API: al_free_with_context + +This calls free() from the Allegro library (this matters on Windows), +unless overridden with [al_set_memory_interface]. + +Generally you should use the [al_free] macro. + +## API: al_realloc_with_context + +This calls realloc() from the Allegro library (this matters on Windows), +unless overridden with [al_set_memory_interface], + +Generally you should use the [al_realloc] macro. + +## API: al_calloc_with_context + +This calls calloc() from the Allegro library (this matters on Windows), +unless overridden with [al_set_memory_interface], + +Generally you should use the [al_calloc] macro. + +## API: ALLEGRO_MEMORY_INTERFACE + +This structure has the following fields. + +~~~~c +void *(*mi_malloc)(size_t n, int line, const char *file, const char *func); +void (*mi_free)(void *ptr, int line, const char *file, const char *func); +void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file, + const char *func); +void *(*mi_calloc)(size_t count, size_t n, int line, const char *file, + const char *func); +~~~~ + +See also: [al_set_memory_interface] + +## API: al_set_memory_interface + +Override the memory management functions with implementations of +[al_malloc_with_context], [al_free_with_context], [al_realloc_with_context] and +[al_calloc_with_context]. The context arguments may be used for debugging. The +new functions should be thread safe. + +If the pointer is NULL, the default behaviour will be restored. + +See also: [ALLEGRO_MEMORY_INTERFACE] + diff --git a/allegro/docs/src/refman/misc.txt b/allegro/docs/src/refman/misc.txt new file mode 100644 index 00000000..4bb6524f --- /dev/null +++ b/allegro/docs/src/refman/misc.txt @@ -0,0 +1,23 @@ +# Miscellaneous routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_PI + +C99 compilers have no predefined value like M_PI for the constant π, but +you can use this one instead. + +## API: al_run_main + +This function is useful in cases where you don't have a main() function but +want to run Allegro (mostly useful in a wrapper library). Under Windows and +Linux this is no problem because you simply can call [al_install_system]. But +some other system (like OSX) don't allow calling [al_install_system] in the main +thread. al_run_main will know what to do in that case. + +The passed argc and argv will simply be passed on to user_main and the return +value of user_main will be returned. diff --git a/allegro/docs/src/refman/monitor.txt b/allegro/docs/src/refman/monitor.txt new file mode 100644 index 00000000..5f911e89 --- /dev/null +++ b/allegro/docs/src/refman/monitor.txt @@ -0,0 +1,91 @@ +# Monitors + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_MONITOR_INFO + +Describes a monitor's size and position relative to other +monitors. x1, y1 will be 0, 0 on the primary display. +Other monitors can have negative values if they are to the +left or above the primary display. x2, y2 are the +coordinates one beyond the bottom right pixel, so that +x2-x1 gives the width and y2-y1 gives the height of the +display. + +~~~~c +typedef struct ALLEGRO_MONITOR_INFO +{ + int x1; + int y1; + int x2; + int y2; +} ALLEGRO_MONITOR_INFO; +~~~~ + +See also: [al_get_monitor_info] + +## API: al_get_new_display_adapter + +Gets the video adapter index where new displays +will be created by the calling thread, if previously set with +[al_set_new_display_adapter]. +Otherwise returns `ALLEGRO_DEFAULT_DISPLAY_ADAPTER`. + +See also: [al_set_new_display_adapter] + +## API: al_set_new_display_adapter + +Sets the adapter to use for new displays created by the calling thread. +The adapter has a monitor attached to it. Information +about the monitor can be gotten using [al_get_num_video_adapters] +and [al_get_monitor_info]. + +To return to the default behaviour, pass `ALLEGRO_DEFAULT_DISPLAY_ADAPTER`. + +See also: [al_get_num_video_adapters], [al_get_monitor_info] + +## API: al_get_monitor_info + +Get information about a monitor's position on the desktop. +adapter is a number from 0 to al_get_num_video_adapters()-1. + +On Windows, use [al_set_new_display_flags] to switch between Direct3D and +OpenGL backends, which will often have different adapters available. + +Returns `true` on success, `false` on failure. + +See also: [ALLEGRO_MONITOR_INFO], [al_get_num_video_adapters] + +## API: al_get_monitor_dpi + +Get the dots per inch of a monitor attached to the display adapter. + +Since: 5.2.5 + +See also: [al_get_num_video_adapters] + +## API: al_get_num_video_adapters + +Get the number of video "adapters" attached to the computer. Each +video card attached to the computer counts as one or more adapters. +An adapter is thus really a video port that can have a monitor connected +to it. + +On Windows, use [al_set_new_display_flags] to switch between Direct3D and +OpenGL backends, which will often have different adapters available. + +See also: [al_get_monitor_info] + +## API: al_get_monitor_refresh_rate + +Returns the current refresh rate of a monitor attached to the display adapter. + +Since: 5.2.6 + +> *[Unstable API]:* This is an experimental feature and currently only works on Windows. + +See also: [al_get_monitor_info] diff --git a/allegro/docs/src/refman/mouse.txt b/allegro/docs/src/refman/mouse.txt new file mode 100644 index 00000000..823d3872 --- /dev/null +++ b/allegro/docs/src/refman/mouse.txt @@ -0,0 +1,299 @@ +# Mouse routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_MOUSE_STATE + +Public fields (read only): + +* x - mouse x position +* y - mouse y position +* w, z - mouse wheel position (2D 'ball') +* buttons - mouse buttons bitfield + + The zeroth bit is set if the primary mouse button is held down, + the first bit is set if the secondary mouse button is held down, + and so on. + +* pressure - pressure, ranging from `0.0` to `1.0` + +See also: [al_get_mouse_state], [al_get_mouse_state_axis], [al_mouse_button_down] + +## API: al_install_mouse + +Install a mouse driver. + +Returns true if successful. If a driver was already installed, nothing +happens and true is returned. + +## API: al_is_mouse_installed + +Returns true if [al_install_mouse] was called successfully. + +## API: al_uninstall_mouse + +Uninstalls the active mouse driver, if any. This will +automatically unregister the mouse event source with any event +queues. + +This function is automatically called when Allegro is shut down. + +## API: al_get_mouse_num_axes + +Return the number of axes on the mouse. +The first axis is 0. + +See also: [al_get_mouse_num_buttons] + +## API: al_get_mouse_num_buttons + +Return the number of buttons on the mouse. +The first button is 1. + +See also: [al_get_mouse_num_axes] + +## API: al_get_mouse_state + +Save the state of the mouse specified at the time the function +is called into the given structure. + +Example: + +~~~~c +ALLEGRO_MOUSE_STATE state; + +al_get_mouse_state(&state); +if (state.buttons & 1) { + /* Primary (e.g. left) mouse button is held. */ + printf("Mouse position: (%d, %d)\n", state.x, state.y); +} +if (state.buttons & 2) { + /* Secondary (e.g. right) mouse button is held. */ +} +if (state.buttons & 4) { + /* Tertiary (e.g. middle) mouse button is held. */ +} +~~~~ + +See also: [ALLEGRO_MOUSE_STATE], [al_get_mouse_state_axis], +[al_mouse_button_down] + +## API: al_get_mouse_state_axis + +Extract the mouse axis value from the saved state. +The axes are numbered from 0, in this order: +x-axis, y-axis, z-axis, w-axis. + +See also: [ALLEGRO_MOUSE_STATE], [al_get_mouse_state], [al_mouse_button_down] + +## API: al_mouse_button_down + +Return true if the mouse button specified was held down in the state +specified. Unlike most things, the first mouse button is numbered 1. + +See also: [ALLEGRO_MOUSE_STATE], [al_get_mouse_state], [al_get_mouse_state_axis] + +## API: al_set_mouse_xy + +Try to position the mouse at the given coordinates on the given display. +The mouse movement resulting from a successful move will generate an +[ALLEGRO_EVENT_MOUSE_WARPED] event. + +Returns true on success, false on failure. + +See also: [al_set_mouse_z], [al_set_mouse_w] + +## API: al_set_mouse_z + +Set the mouse wheel position to the given value. + +Returns true on success, false on failure. + +See also: [al_set_mouse_w] + +## API: al_set_mouse_w + +Set the second mouse wheel position to the given value. + +Returns true on success, false on failure. + +See also: [al_set_mouse_z] + +## API: al_set_mouse_axis + +Set the given mouse axis to the given value. + +The axis number must not be 0 or 1, which are the X and Y axes. +Use [al_set_mouse_xy] for that. + +Returns true on success, false on failure. + +See also: [al_set_mouse_xy], [al_set_mouse_z], [al_set_mouse_w] + +## API: al_get_mouse_event_source + +Retrieve the mouse event source. All [mouse events][ALLEGRO_EVENT_MOUSE_AXES] +are generated by this event source. + +Returns NULL if the mouse subsystem was not installed. + + +## API: al_set_mouse_wheel_precision + +Sets the precision of the mouse wheel (the z and w coordinates). This precision +manifests itself as a multiplier on the `dz` and `dw` fields in mouse events. +It also affects the `z` and `w` fields of events and [ALLEGRO_MOUSE_STATE], but +not in a simple way if you alter the precision often, so it is suggested to +reset those axes to 0 when you change precision. Setting this to a high value +allows you to detect small changes in those two axes for some high precision +mice. A flexible way of using this precision is to set it to a high value (120 +is likely sufficient for most, if not all, mice) and use a floating point `dz` +and `dw` like so: + +~~~~c +al_set_mouse_wheel_precision(120); + +ALLEGRO_EVENT event; +al_wait_for_event(event_queue, &event); +if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + double dz = (double)event.mouse.dz / al_get_mouse_wheel_precision(); + /* Use dz in some way... */ +} +~~~~ + +Precision is set to 1 by default. It is impossible to set it to a lower +precision than that. + +Since: 5.1.10 + +See also: [al_get_mouse_wheel_precision] + +## API: al_get_mouse_wheel_precision + +Gets the precision of the mouse wheel (the z and w coordinates). + +Since: 5.1.10 + +See also: [al_set_mouse_wheel_precision] + + +## Mouse cursors + +### API: al_create_mouse_cursor + +Create a mouse cursor from the bitmap provided. `x_focus` and `y_focus` +describe the bit of the cursor that will represent the actual mouse position. + +Returns a pointer to the cursor on success, or NULL on failure. + +See also: [al_set_mouse_cursor], [al_destroy_mouse_cursor] + +### API: al_destroy_mouse_cursor + +Free the memory used by the given cursor. + +Has no effect if `cursor` is NULL. + +See also: [al_create_mouse_cursor] + +### API: al_set_mouse_cursor + +Set the given mouse cursor to be the current mouse cursor for the given +display. + +If the cursor is currently 'shown' (as opposed to 'hidden') the change is +immediately visible. + +Returns true on success, false on failure. + +See also: [al_set_system_mouse_cursor], [al_show_mouse_cursor], +[al_hide_mouse_cursor] + +### API: al_set_system_mouse_cursor + +Set the given system mouse cursor to be the current mouse cursor +for the given display. If the cursor is currently 'shown' (as opposed +to 'hidden') the change is immediately visible. + +If the cursor doesn't exist on the current platform another cursor will be +silently be substituted. + +The cursors are: + +* ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT +* ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW +* ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY +* ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION +* ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT +* ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE +* ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N +* ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W +* ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S +* ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E +* ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW +* ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW +* ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE +* ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE +* ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS +* ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION +* ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK +* ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT +* ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE + +Returns true on success, false on failure. + +See also: [al_set_mouse_cursor], [al_show_mouse_cursor], [al_hide_mouse_cursor] + +### API: al_get_mouse_cursor_position + +On platforms where this information is available, this function returns the +global location of the mouse cursor, relative to the desktop. You should +not normally use this function, as the information is not useful except +for special scenarios as moving a window. + +Returns true on success, false on failure. + +### API: al_hide_mouse_cursor + +Hide the mouse cursor in the given display. This has no effect on what the +current mouse cursor looks like; it just makes it disappear. + +Returns true on success (or if the cursor already was hidden), false +otherwise. + +See also: [al_show_mouse_cursor] + +### API: al_show_mouse_cursor + +Make a mouse cursor visible in the given display. + +Returns true if a mouse cursor is shown as a result of the call (or one +already was visible), false otherwise. + +See also: [al_hide_mouse_cursor] + +### API: al_grab_mouse + +Confine the mouse cursor to the given display. The mouse cursor can only be +confined to one display at a time. + +Returns true if successful, otherwise returns false. +Do not assume that the cursor will remain confined until you call +[al_ungrab_mouse]. It may lose the confined status at any time for other +reasons. + +> *Note:* not yet implemented on Mac OS X. + +See also: [al_ungrab_mouse] + +### API: al_ungrab_mouse + +Stop confining the mouse cursor to any display belonging to the program. + +> *Note:* not yet implemented on Mac OS X. + +See also: [al_grab_mouse] diff --git a/allegro/docs/src/refman/native_dialog.txt b/allegro/docs/src/refman/native_dialog.txt new file mode 100644 index 00000000..130402ad --- /dev/null +++ b/allegro/docs/src/refman/native_dialog.txt @@ -0,0 +1,684 @@ +# Native dialogs support + +These functions are declared in the following header file. +Link with allegro_dialog. + +~~~~c + #include +~~~~ + +## API: ALLEGRO_FILECHOOSER + +Opaque handle to a native file dialog. + +## API: ALLEGRO_TEXTLOG + +Opaque handle to a text log window. + +## API: al_init_native_dialog_addon + +Initialise the native dialog addon. + +Returns true on success, false on error. + +Since: 5.0.9, 5.1.0 + +> *Note:* Prior to Allegro 5.1.0 native dialog functions could be called +without explicit initialisation, but that is now deprecated. +Future functionality may require explicit initialisation. +An exception is [al_show_native_message_box], which may be useful to show +an error message if Allegro fails to initialise. + +See also: [al_shutdown_native_dialog_addon] + +## API: al_is_native_dialog_addon_initialized + +Returns true if the native dialog addon is initialized, otherwise returns false. + +Since: 5.2.6 + +## API: al_shutdown_native_dialog_addon + +Shut down the native dialog addon. + +Since: 5.0.9, 5.1.5 + +See also: [al_init_native_dialog_addon] + +## API: al_create_native_file_dialog + +Creates a new native file dialog. You should only have one such dialog opened +at a time. + +Parameters: + +- `initial_path`: The initial search path and filename. Can be NULL. + To start with a blank file name the string should end with a directory + separator (this should be the common case). + +- `title`: Title of the dialog. + +- `patterns`: A list of semi-colon separated patterns to match. This + should not contain any whitespace characters. If a pattern + contains the '/' character, then it is treated as a MIME type (e.g. + 'image/png'). Not all platforms support file patterns. If the native dialog + does not provide support, this parameter is ignored. + +- `mode`: 0, or a combination of the following flags: + +ALLEGRO_FILECHOOSER_FILE_MUST_EXIST +: If supported by the native dialog, it will not allow entering new names, + but just allow existing files to be selected. Else it is ignored. + +ALLEGRO_FILECHOOSER_SAVE +: If the native dialog system has a different dialog for saving (for example + one which allows creating new directories), it is used. Else it is ignored. + +ALLEGRO_FILECHOOSER_FOLDER +: If there is support for a separate dialog to select a folder instead of a + file, it will be used. + +ALLEGRO_FILECHOOSER_PICTURES +: If a different dialog is available for selecting pictures, it is used. Else + it is ignored. + +ALLEGRO_FILECHOOSER_SHOW_HIDDEN +: If the platform supports it, also hidden files will be shown. + +ALLEGRO_FILECHOOSER_MULTIPLE +: If supported, allow selecting multiple files. + +Returns: + +A handle to the dialog which you can pass to +[al_show_native_file_dialog] to display it, and from which you then can +query the results using [al_get_native_file_dialog_count] and +[al_get_native_file_dialog_path]. When you are done, call +[al_destroy_native_file_dialog] on it. + +If a dialog window could not be created then this function returns NULL. + +## API: al_show_native_file_dialog + +Show the dialog window. The display may be NULL, otherwise the given display +is treated as the parent if possible. + +This function blocks the calling thread until it returns, +so you may want to spawn a thread with [al_create_thread] and +call it from inside that thread. + +Returns true on success, false on failure. + +## API: al_get_native_file_dialog_count + +Returns the number of files selected, or 0 if the dialog was cancelled. + +## API: al_get_native_file_dialog_path + +Returns one of the selected paths with index `i`. The index should range +from `0` to the return value of [al_get_native_file_dialog_count] `-1`. + +## API: al_destroy_native_file_dialog + +Frees up all resources used by the file dialog. + +## API: al_show_native_message_box + +Show a native GUI message box. This can be used for example to display an error +message if creation of an initial display fails. The display may be NULL, +otherwise the given display is treated as the parent if possible. + +The message box will have a single "OK" button and use the style informative +dialog boxes usually have on the native system. If the `buttons` parameter is +not NULL, you can instead specify the button text in a string, with buttons +separated by a vertical bar (|). + +> *Note:* `buttons` parameter is currently unimplemented on Windows. + +The flags available are: + +ALLEGRO_MESSAGEBOX_WARN +: The message is a warning. + This may cause a different icon (or other effects). + +ALLEGRO_MESSAGEBOX_ERROR +: The message is an error. + +ALLEGRO_MESSAGEBOX_QUESTION +: The message is a question. + +ALLEGRO_MESSAGEBOX_OK_CANCEL +: Display a cancel button alongside the "OK" button. + Ignored if `buttons` is not NULL. + +ALLEGRO_MESSAGEBOX_YES_NO +: Display Yes/No buttons instead of the "OK" button. + Ignored if `buttons` is not NULL. + +[al_show_native_message_box] may be called without Allegro being installed. +This is useful to report an error during initialisation of Allegro itself. + +Returns: + +- 0 if the dialog window was closed without activating a button. +- 1 if the OK or Yes button was pressed. +- 2 if the Cancel or No button was pressed. + +If `buttons` is not NULL, the number of the pressed button is returned, starting +with 1. + +All of the remaining parameters must not be NULL. + +If a message box could not be created then this returns 0, as if the window +was dismissed without activating a button. + +Example: + +~~~~c +int button = al_show_native_message_box( + display, + "Warning", + "Are you sure?", + "If you click yes then you are confirming that \"Yes\" " + "is your response to the query which you have " + "generated by the action you took to open this " + "message box.", + NULL, + ALLEGRO_MESSAGEBOX_YES_NO +); +~~~~ + +## API: al_open_native_text_log + +Opens a window to which you can append log messages with +[al_append_native_text_log]. This can be useful for debugging if you don't +want to depend on a console being available. + +Use [al_close_native_text_log] to close the window again. + +The flags available are: + +ALLEGRO_TEXTLOG_NO_CLOSE +: Prevent the window from having a close button. Otherwise, if the close + button is pressed, an event is generated; see + [al_get_native_text_log_event_source]. + +ALLEGRO_TEXTLOG_MONOSPACE +: Use a monospace font to display the text. + +Returns NULL if there was an error opening the window, or if text log windows +are not implemented on the platform. + +See also: [al_append_native_text_log], [al_close_native_text_log] + +## API: al_close_native_text_log + +Closes a message log window opened with [al_open_native_text_log] +earlier. + +Does nothing if passed NULL. + +See also: [al_open_native_text_log] + +## API: al_append_native_text_log + +Appends a line of text to the message log window and scrolls to the +bottom (if the line would not be visible otherwise). This works like +printf. A line is continued until you add a newline character. + +If the window is NULL then this function will fall back to calling +printf. This makes it convenient to support logging to a window or +a terminal. + +## API: al_get_native_text_log_event_source + +Get an event source for a text log window. The possible events are: + +ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE +: The window was requested to be closed, either by pressing the close button + or pressing Escape on the keyboard. + The user.data1 field will hold a pointer to the [ALLEGRO_TEXTLOG] + which generated the event. + The user.data2 field will be 1 if the event was generated as a result of a + key press; otherwise it will be zero. + +## API: al_get_allegro_native_dialog_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. + +## Menus + +Menus are implemented on Windows, X and OS X. +Menus on X are implemented with GTK, and have a special requirement: you must +set the ALLEGRO_GTK_TOPLEVEL display flag prior to creating the display +which will have menus attached. + +A menu can be attached to a single display window or popped up as a context +menu. If you wish to use the same menu on multiple displays or use a sub-menu +as a context menu, you must make a copy via [al_clone_menu] or +[al_clone_menu_for_popup]. + +Top level items in a non-popup menu must have at least one sub-item, or the +behavior is undefined. + +Each menu item can be given an ID of any 16-bit integer greater than zero. When +a user clicks on a menu item, an event will be generated only if it has an ID. +This ID should be unique per menu; if you duplicate IDs, then there will be no +way for you to determine exactly which item generated the event. + +There are many functions that take `pos` as a parameter used for locating a +particular menu item. In those cases, it represents one of two things: an ID +or a zero-based index. Any value greater than zero will always be treated as an ID. +Anything else (including zero) will be considered an index based on the absolute +value. In other words, 0 is the first menu item, -1 is the second menu item, -2 +is the third menu item, and so on. + +The event type is `ALLEGRO_EVENT_MENU_CLICK`. It contains three fields: + +~~~~c +event.user.data1 = id; +event.user.data2 = (intptr_t) display; +event.user.data3 = (intptr_t) menu; +~~~~ + +The `display` and `menu` may be NULL if it was not possible to tell exactly +which item generated the event. + +A basic example: + +~~~~c + #define FILE_EXIT_ID 1 + +ALLEGRO_MENU *menu = al_create_menu(); +ALLEGRO_MENU *file_menu = al_create_menu(); +al_append_menu_item(file_menu, "Exit", FILE_EXIT_ID, 0, NULL, NULL); +al_append_menu_item(menu, "File", 0, 0, NULL, file_menu); +al_set_display_menu(display, menu); + +al_register_event_source(queue, al_get_default_menu_event_source()); +al_wait_for_event(queue, &event); + +if (event.type == ALLEGRO_EVENT_MENU_CLICK) { + if (event.user.data1 == FILE_EXIT_ID) { + exit_program(); + } +} +~~~~ + +Because there is no "DISPLAY_DESTROYED" event, you must call +al_set_display_menu(display, NULL) before destroying any display with a +menu attached, to avoid leaking resources. + +### API: ALLEGRO_MENU + +An opaque data type that represents a menu that contains menu items. +Each of the menu items may optionally include a sub-menu. + +### API: ALLEGRO_MENU_INFO + +A structure that defines how to create a complete menu system. For +standard menu items, the following format is used: + + { caption, id, flags, icon } + +For special items, these macros are helpful: + +~~~~c +ALLEGRO_START_OF_MENU(caption, id) +ALLEGRO_MENU_SEPARATOR +ALLEGRO_END_OF_MENU +~~~~ + +A well-defined menu will begin with `ALLEGRO_START_OF_MENU`, contain +one or more menu items, and end with `ALLEGRO_END_OF_MENU`. A menu +may contain sub-menus. An example: + +~~~~c +ALLEGRO_MENU_INFO menu_info[] = { + ALLEGRO_START_OF_MENU("&File", 1), + { "&Open", 2, 0, NULL }, + ALLEGRO_START_OF_MENU("Open &Recent...", 3), + { "Recent 1", 4, 0, NULL }, + { "Recent 2", 5, 0, NULL }, + ALLEGRO_END_OF_MENU, + ALLEGRO_MENU_SEPARATOR, + { "E&xit", 6, 0, NULL }, + ALLEGRO_END_OF_MENU, + ALLEGRO_START_OF_MENU("&Help", 7), + {"&About", 8, 0, NULL }, + ALLEGRO_END_OF_MENU, + ALLEGRO_END_OF_MENU +}; + +ALLEGRO_MENU *menu = al_build_menu(menu_info); +~~~~ + +If you prefer, you can build the menu without the structure +by using [al_create_menu] and [al_insert_menu_item]. + +See also: [al_build_menu] + +### API: al_create_menu + +Creates a menu container that can hold menu items. + +Returns `NULL` on failure. + +Since: 5.1.0 + +See also: [al_create_popup_menu], [al_build_menu] + +### API: al_create_popup_menu + +Creates a menu container for popup menus. Only the root (outermost) +menu should be created with this function. Sub menus of popups should +be created with [al_create_menu]. + +Returns `NULL` on failure. + +Since: 5.1.0 + +See also: [al_create_menu], [al_build_menu] + +### API: al_build_menu + +Builds a menu based on the specifications of a sequence of +`ALLEGRO_MENU_INFO` elements. + +Returns a pointer to the root `ALLEGRO_MENU`, or `NULL` on failure. +To gain access to the other menus and items, you will need to +search for them using [al_find_menu_item]. + +Since: 5.1.0 + +See also: [ALLEGRO_MENU_INFO], [al_create_menu], [al_create_popup_menu] + +### API: al_append_menu_item + +Appends a menu item to the end of the menu. See [al_insert_menu_item] +for more information. + +Since: 5.1.0 + +See also: [al_insert_menu_item], [al_remove_menu_item] + +### API: al_insert_menu_item + +Inserts a menu item at the spot specified. See the introductory text for a +detailed explanation of how the `pos` parameter is interpreted. + +The `parent` menu can be a popup menu or a regular menu. To underline +one character in the `title`, prefix it with an ampersand. + +The `flags` can be any combination of: + +ALLEGRO_MENU_ITEM_DISABLED +: The item is "grayed out" and cannot be selected. + +ALLEGRO_MENU_ITEM_CHECKBOX +: The item is a check box. This flag can only be set at the time the + menu is created. If a check box is clicked, it will automatically be + toggled. + +ALLEGRO_MENU_ITEM_CHECKED +: The item is checked. If set, ALLEGRO_MENU_ITEM_CHECKBOX will automatically + be set as well. + +The `icon` is not yet supported. + +The `submenu` parameter indicates that this item contains a child menu. +The child menu must have previously been created with `al_create_menu`, +and not be associated with any other menu. + +Returns `true` on success. + +Since: 5.1.0 + +See also: [al_append_menu_item], [al_remove_menu_item] + +### API: al_remove_menu_item + +Removes the specified item from the menu and destroys it. If the item +contains a sub-menu, it too is destroyed. Any references to it are invalidated. +If you want to preserve that sub-menu, you should first make a copy with [al_clone_menu]. + +This is safe to call on a menu that is currently being displayed. + +Returns `true` if an item was removed. + +Since: 5.1.0 + +See also: [al_append_menu_item], [al_insert_menu_item], [al_destroy_menu] + +### API: al_clone_menu + +Makes a copy of a menu so that it can be reused on another display. The +menu being cloned can be anything: a regular menu, a popup menu, or a +sub-menu. + +Returns the cloned menu. + +Since: 5.1.0 + +See also: [al_clone_menu_for_popup] + +### API: al_clone_menu_for_popup + +Exactly like [al_clone_menu], except that the copy is for a popup menu. + +Since: 5.1.0 + +See also: [al_clone_menu] + +### API: al_destroy_menu + +Destroys an entire menu, including its sub-menus. Any references to it or +a sub-menu are no longer valid. It is safe to call this on a menu that is +currently being displayed. + +Since: 5.1.0 + +See also: [al_remove_menu_item] + +### API: al_get_menu_item_caption + +Returns the caption associated with the menu item. It is valid as long +as the caption is not modified. + +Returns `NULL` if the item was not found. + +Since: 5.1.0 + +See also: [al_set_menu_item_caption] + +### API: al_set_menu_item_caption + +Updates the menu item caption with the new `caption`. This will invalidate +any previous calls to [al_get_menu_item_caption]. + +Since: 5.1.0 + +See also: [al_get_menu_item_caption] + +### API: al_get_menu_item_flags + +Returns the currently set flags. See [al_insert_menu_item] for a description +of the available flags. + +Returns -1 if the item was not found. + +Since: 5.1.0 + +See also: [al_set_menu_item_flags], [al_toggle_menu_item_flags] + +### API: al_set_menu_item_flags + +Updates the menu item's flags. See [al_insert_menu_item] for a description +of the available flags. + +Since: 5.1.0 + +See also: [al_get_menu_item_flags], [al_toggle_menu_item_flags] + +### API: al_toggle_menu_item_flags + +Toggles the specified menu item's flags. See [al_insert_menu_item] for a +description of the available flags. + +Returns a bitfield of only the specified flags that are set after the toggle. +A flag that was not toggled will not be returned, even if it is set. +Returns -1 if the id is invalid. + +Since: 5.1.0 + +> *[Unstable API]:* Redundant with `al_get/set_menu_item_flags`. + +See also: [al_get_menu_item_flags], [al_set_menu_item_flags] + +### API: al_get_menu_item_icon + +Returns the icon associated with the menu. It is safe to draw to the returned +bitmap, but you must call [al_set_menu_item_icon] in order for the changes to +be applied. + +Returns `NULL` if the item was not found or if it has no icon. + +Since: 5.1.0 + +See also: [al_set_menu_item_icon] + +### API: al_set_menu_item_icon + +Sets the icon for the specified menu item. The menu assumes ownership of the +`ALLEGRO_BITMAP` and may invalidate the pointer, so you must clone it if you +wish to continue using it. + +If a video bitmap is passed, it will automatically be converted to a memory +bitmap, so it is preferable to pass a memory bitmap. + +Since: 5.1.0 + +See also: [al_get_menu_item_icon], [al_clone_bitmap] + +### API: al_find_menu + +Searches in the `haystack` menu for any submenu with the given `id`. (Note +that this only represents a literal ID, and cannot be used as an index.) + +Returns the menu, if found. Otherwise returns `NULL`. + +Since: 5.1.0 + +See also: [al_find_menu_item] + +### API: al_find_menu_item + +Searches in the `haystack` menu for an item with the given `id`. (Note that +this only represents a literal ID, and cannot be used as an index.) + +If `menu` and `index` are not `NULL`, they will be set as the parent menu +containing the item and the zero-based (positive) index of the item. (If the menu item +was not found, then their values are undefined.) + +Returns true if the menu item was found. + +Since: 5.1.0 + +See also: [al_find_menu] + +### API: al_get_default_menu_event_source + +Returns the default event source used for menu clicks. If a menu was not +given its own event source via [al_enable_menu_event_source], then +it will use this default source. + +Since: 5.1.0 + +See also: [al_register_event_source], [al_enable_menu_event_source], +[al_disable_menu_event_source] + +### API: al_enable_menu_event_source + +Enables a unique event source for this menu. It and all of its sub-menus +will use this event source. (It is safe to call this multiple times on the +same menu.) + +Returns the event source. + +Since: 5.1.0 + +See also: [al_register_event_source], [al_get_default_menu_event_source], +[al_disable_menu_event_source] + +### API: al_disable_menu_event_source + +Disables a unique event source for the menu, causing it to use the +default event source. + +Since: 5.1.0 + +See also: [al_get_default_menu_event_source], [al_enable_menu_event_source] + +### API: al_get_display_menu + +Returns the menu associated with the `display`, or `NULL` if it does not have +a menu. + +Since: 5.1.0 + +See also: [al_set_display_menu] + +### API: al_set_display_menu + +Associates the `menu` with the `display` and shows it. If there was a previous +menu associated with the display, it will be destroyed. If you don't want that +to happen, you should first remove the menu with [al_remove_display_menu]. + +If the menu is already attached to a display, it will not be attached to the +new display. If `menu` is `NULL`, the current menu will still be destroyed. + +> *Note:* Attaching a menu may cause the window as available to your application +to be resized! You should listen for a resize event, check how much space was +lost, and resize the window accordingly if you want to maintain your window's +prior size. + +Returns true if successful. + +Since: 5.1.0 + +See also: [al_create_menu], [al_remove_display_menu] + +### API: al_popup_menu + +Displays a context menu next to the mouse cursor. The menu must have been +created with [al_create_popup_menu]. It generates events just like a regular +display menu does. It is possible that the menu will be canceled without any +selection being made. + +The `display` parameter indicates which window the menu is associated with +(when you process the menu click event), but does not actually affect where +the menu is located on the screen. + +Returns `true` if the context menu was displayed. + +> *Note:* On Linux this function will fail if any of the mouse keys are held +down. I.e. it will only reliably work if you handle it in +`ALLEGRO_MOUSE_BUTTON_UP` events and even then only if that event corresponds +to the final mouse button that was pressed. + +Since: 5.1.0 + +See also: [al_create_popup_menu] + +### API: al_remove_display_menu + +Detaches the menu associated with the display and returns it. The menu +can then be used on a different display. + +If you simply want to destroy the active menu, you can call +[al_set_display_menu] with a `NULL` menu. + +Since: 5.1.0 + +See also: [al_set_display_menu] diff --git a/allegro/docs/src/refman/opengl.txt b/allegro/docs/src/refman/opengl.txt new file mode 100644 index 00000000..5d89a7fe --- /dev/null +++ b/allegro/docs/src/refman/opengl.txt @@ -0,0 +1,204 @@ +# OpenGL integration + +These functions are declared in the following header file: + +~~~~c + #include +~~~~ + +## API: al_get_opengl_extension_list + +Returns the list of OpenGL extensions supported by Allegro, for +the given display. + +Allegro will keep information about all extensions it knows about in a +structure returned by `al_get_opengl_extension_list`. + +For example: + +~~~~c +if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multitexture) { + //use it +} +~~~~ + +The extension will be set to true if available for the given display and +false otherwise. This means to use the definitions and functions from an +OpenGL extension, all you need to do is to check for it as above at +run time, after acquiring the OpenGL display from Allegro. + +Under Windows, this will also work with WGL extensions, and under Unix +with GLX extensions. + +In case you want to manually check for extensions and load function pointers +yourself (say, in case the Allegro developers did not include it yet), you +can use the [al_have_opengl_extension] and +[al_get_opengl_proc_address] functions instead. + +> *Note:* the exact extensions exposed depend on how Allegro was compiled. It +is recommended to use [al_have_opengl_extension] and +[al_get_opengl_proc_address] for the most stable experience. + +## API: al_get_opengl_proc_address + +Helper to get the address of an OpenGL symbol + +Example: + +How to get the function _glMultiTexCoord3fARB_ that comes +with ARB's Multitexture extension: + +~~~~c +// define the type of the function +ALLEGRO_DEFINE_PROC_TYPE(void, MULTI_TEX_FUNC, + (GLenum, GLfloat, GLfloat, GLfloat)); +// declare the function pointer +MULTI_TEX_FUNC glMultiTexCoord3fARB; +// get the address of the function +glMultiTexCoord3fARB = (MULTI_TEX_FUNC) al_get_opengl_proc_address( + "glMultiTexCoord3fARB"); +~~~~ + +If _glMultiTexCoord3fARB_ is not NULL then it can be used as if it has +been defined in the OpenGL core library. + +> *Note:* Under Windows, OpenGL functions may need a special calling +convention, so it's best to always use the ALLEGRO_DEFINE_PROC_TYPE +macro when declaring function pointer types for OpenGL functions. + +Parameters: + +name - The name of the symbol you want to link to. + +*Return value:* + +A pointer to the symbol if available or NULL otherwise. + +## API: al_get_opengl_texture + +Returns the OpenGL texture id internally used by the given bitmap if +it uses one, else 0. + +Example: + +~~~~c +bitmap = al_load_bitmap("my_texture.png"); +texture = al_get_opengl_texture(bitmap); +if (texture != 0) + glBindTexture(GL_TEXTURE_2D, texture); +~~~~ + +## API: al_get_opengl_texture_size + +Retrieves the size of the texture used for the bitmap. This can be different +from the bitmap size if OpenGL only supports power-of-two sizes or if it is +a sub-bitmap. + +Returns true on success, false on failure. +Zero width and height are returned if the bitmap is not an OpenGL bitmap. + +See also: [al_get_opengl_texture_position] + +## API: al_get_opengl_texture_position + +Returns the u/v coordinates for the top/left corner of the bitmap within the +used texture, in pixels. + +See also: [al_get_opengl_texture_size] + +## API: al_get_opengl_program_object + +Returns the OpenGL program object associated with this shader, if the platform +is `ALLEGRO_SHADER_GLSL`. Otherwise, returns 0. + +## API: al_get_opengl_fbo + +Returns the OpenGL FBO id internally used by the given bitmap if it uses one, +otherwise returns zero. No attempt will be made to create an FBO if the +bitmap is not owned by the current display. + +The FBO returned by this function will only be freed when the bitmap is +destroyed, or if you call [al_remove_opengl_fbo] on the bitmap. + +> *Note:* In Allegro 5.0.0 this function only returned an FBO which had +previously been created by calling [al_set_target_bitmap]. It would not +attempt to create an FBO itself. This has since been changed. + +See also: [al_remove_opengl_fbo], [al_set_target_bitmap] + +## API: al_remove_opengl_fbo + +Explicitly free an OpenGL FBO created for a bitmap, if it has one. +Usually you do not need to worry about freeing FBOs, unless you use +[al_get_opengl_fbo]. + +See also: [al_get_opengl_fbo], [al_set_target_bitmap] + +## API: al_have_opengl_extension + +This function is a helper to determine whether an OpenGL extension is +available on the given display or not. + +Example: + +~~~~c +bool packedpixels = al_have_opengl_extension("GL_EXT_packed_pixels"); +~~~~ + +If _packedpixels_ is true then you can safely use the constants related +to the packed pixels extension. + +Returns true if the extension is available; false otherwise. + +## API: al_get_opengl_version + +Returns the OpenGL or OpenGL ES version number of the client +(the computer the program is running on), for the current display. +"1.0" is returned as 0x01000000, "1.2.1" is returned as 0x01020100, +and "1.2.2" as 0x01020200, etc. + +A valid OpenGL context must exist for this function to work, which +means you may *not* call it before [al_create_display]. + +See also: [al_get_opengl_variant] + +## API: al_get_opengl_variant + +Returns the variant or type of OpenGL used on the running platform. This +function can be called before creating a display or setting properties for +new displays. Possible values are: + +ALLEGRO_DESKTOP_OPENGL +: Regular OpenGL as seen on desktop/laptop computers. + +ALLEGRO_OPENGL_ES +: Trimmed down version of OpenGL used on many small consumer electronic + devices such as handheld (and sometimes full size) consoles. + +See also: [al_get_opengl_version] + +## API: al_set_current_opengl_context + +Make the OpenGL context associated with the given display current for the +calling thread. If there is a current target bitmap which belongs to a +different OpenGL context, the target bitmap will be changed to NULL. + +Normally you do not need to use this function, as the context will be made +current when you call [al_set_target_bitmap] or [al_set_target_backbuffer]. +You might need it if you created an OpenGL "forward compatible" context. +Then [al_get_backbuffer] only returns NULL, so it would not work to pass that +to [al_set_target_bitmap]. + +## OpenGL configuration + +You can disable the detection of any OpenGL extension by Allegro with +a section like this in allegro5.cfg: + +~~~~ini +[opengl_disabled_extensions] +GL_ARB_texture_non_power_of_two=0 +GL_EXT_framebuffer_object=0 +~~~~ + +Any extension which appears in the section is treated as not available +(it does not matter if you set it to 0 or any other value). diff --git a/allegro/docs/src/refman/path.txt b/allegro/docs/src/refman/path.txt new file mode 100644 index 00000000..8bc048db --- /dev/null +++ b/allegro/docs/src/refman/path.txt @@ -0,0 +1,252 @@ +# Path structures + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +We define a path as an optional *drive*, followed by zero or more *directory +components*, followed by an optional *filename*. The filename may be broken +up into a *basename* and an *extension*, where the basename includes the start +of the filename up to, but not including, the last dot (.) character. +If no dot character exists the basename is the whole filename. +The extension is everything from the last dot character to the end of the +filename. + +## API: al_create_path + +Create a path structure from a string. The last component, if it is followed +by a directory separator and is neither "." nor "..", is treated as the last +directory name in the path. Otherwise the last component is treated as the +filename. +The string may be NULL for an empty path. + +See also: [al_create_path_for_directory], [al_destroy_path] + +## API: al_create_path_for_directory + +This is the same as [al_create_path], but interprets the passed string +as a directory path. The filename component of the returned path will +always be empty. + +See also: [al_create_path], [al_destroy_path] + +## API: al_destroy_path + +Free a path structure. +Does nothing if passed NULL. + +See also: [al_create_path], [al_create_path_for_directory] + +## API: al_clone_path + +Clones an ALLEGRO_PATH structure. +Returns NULL on failure. + +See also: [al_destroy_path] + +## API: al_join_paths + +Concatenate two path structures. The first path structure is +modified. If 'tail' is an absolute path, this function does nothing. + +If 'tail' is a relative path, all of its directory components will be +appended to 'path'. tail's filename will also overwrite path's filename, +even if it is just the empty string. + +Tail's drive is ignored. + +Returns true if 'tail' was a relative path and so concatenated to 'path', +otherwise returns false. + +See also: [al_rebase_path] + +## API: al_rebase_path + +Concatenate two path structures, modifying the second path structure. +If *tail* is an absolute path, this function does nothing. +Otherwise, the drive and path components in *head* are inserted +at the start of *tail*. + +For example, if *head* is "/anchor/" and *tail* is "data/file.ext", then +after the call *tail* becomes "/anchor/data/file.ext". + +See also: [al_join_paths] + +## API: al_get_path_drive + +Return the drive letter on a path, or the empty string if there is none. + +The "drive letter" is only used on Windows, and is usually a string like +"c:", but may be something like "\\\\Computer Name" in the case of UNC +(Uniform Naming Convention) syntax. + +## API: al_get_path_num_components + +Return the number of directory components in a path. + +The directory components do not include the final part of a path +(the filename). + +See also: [al_get_path_component] + +## API: al_get_path_component + +Return the i'th directory component of a path, counting from zero. +If the index is negative then count from the right, i.e. -1 refers to +the last path component. +It is an error to pass an index which is out of bounds. + +See also: [al_get_path_num_components], [al_get_path_tail] + +## API: al_get_path_tail + +Returns the last directory component, or NULL if there are no directory +components. + +## API: al_get_path_filename + +Return the filename part of the path, or the empty string if there is none. + +The returned pointer is valid only until the filename part of the path +is modified in any way, or until the path is destroyed. + +See also: [al_get_path_basename], [al_get_path_extension], +[al_get_path_component] + +## API: al_get_path_basename + +Return the basename, i.e. filename with the extension removed. +If the filename doesn't have an extension, the whole filename is the basename. +If there is no filename part then the empty string is returned. + +The returned pointer is valid only until the filename part of the path +is modified in any way, or until the path is destroyed. + +See also: [al_get_path_filename], [al_get_path_extension] + +## API: al_get_path_extension + +Return a pointer to the start of the extension of the filename, +i.e. everything from the final dot ('.') character onwards. +If no dot exists, returns an empty string. + +The returned pointer is valid only until the filename part of the path +is modified in any way, or until the path is destroyed. + +See also: [al_get_path_filename], [al_get_path_basename] + +## API: al_set_path_drive + +Set the drive string on a path. +The drive may be NULL, which is equivalent to setting the drive +string to the empty string. + +See also: [al_get_path_drive] + +## API: al_append_path_component + +Append a directory component. + +See also: [al_insert_path_component] + +## API: al_insert_path_component + +Insert a directory component at index i. +If the index is negative then count from the right, i.e. -1 refers to +the last path component. + +It is an error to pass an index i which is not within these bounds: +0 <= i <= al_get_path_num_components(path). + +See also: [al_append_path_component], [al_replace_path_component], +[al_remove_path_component] + +## API: al_replace_path_component + +Replace the i'th directory component by another string. +If the index is negative then count from the right, i.e. -1 refers to +the last path component. +It is an error to pass an index which is out of bounds. + +See also: [al_insert_path_component], [al_remove_path_component] + +## API: al_remove_path_component + +Delete the i'th directory component. +If the index is negative then count from the right, i.e. -1 refers to +the last path component. +It is an error to pass an index which is out of bounds. + +See also: [al_insert_path_component], [al_replace_path_component], +[al_drop_path_tail] + +## API: al_drop_path_tail + +Remove the last directory component, if any. + +See also: [al_remove_path_component] + +## API: al_set_path_filename + +Set the optional filename part of the path. +The filename may be NULL, which is equivalent to setting the +filename to the empty string. + +See also: [al_set_path_extension], [al_get_path_filename] + +## API: al_set_path_extension + +Replaces the extension of the path with the given one, i.e. replaces +everything from the final dot ('.') character onwards, including the dot. +If the filename of the path has no extension, the given one is appended. +Usually the new extension you supply should include a leading dot. + +Returns false if the path contains no filename part, +i.e. the filename part is the empty string. + +See also: [al_set_path_filename], [al_get_path_extension] + +## API: al_path_cstr + +Convert a path to its string representation, i.e. optional drive, +followed by directory components separated by 'delim', +followed by an optional filename. + +To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP +for 'delim'. + +The returned pointer is valid only until the path is modified in any way, +or until the path is destroyed. This returns a null-terminated string. If you +need an ALLEGRO_USTR instead, use [al_path_ustr]. + +See also: [al_path_ustr] + +## API: al_path_ustr + +Convert a path to its string representation, i.e. optional drive, +followed by directory components separated by 'delim', +followed by an optional filename. + +To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP +for 'delim'. + +The returned pointer is valid only until the path is modified in any way, +or until the path is destroyed. This returns an ALLEGRO_USTR. If you need +a null-terminated string instead, use [al_path_cstr]. + +Since: 5.2.3 + +See also: [al_path_cstr] + +## API: al_make_path_canonical + +Removes any leading '..' directory components in absolute paths. +Removes all '.' directory components. + +Note that this does *not* collapse "x/../y" sections into "y". +This is by design. If "/foo" on your system is a symlink to "/bar/baz", +then "/foo/../quux" is actually "/bar/quux", +not "/quux" as a naive removal of ".." components would give you. + diff --git a/allegro/docs/src/refman/physfs.txt b/allegro/docs/src/refman/physfs.txt new file mode 100644 index 00000000..f8f678e0 --- /dev/null +++ b/allegro/docs/src/refman/physfs.txt @@ -0,0 +1,49 @@ +# PhysicsFS integration + +PhysicsFS is a library to provide abstract access to various archives. +See for more information. + +This addon makes it possible to read and write files (on disk or inside +archives) using PhysicsFS, through Allegro's file I/O API. +For example, that means you can use the Image I/O addon to load +images from .zip files. + +You must set up PhysicsFS through its own API. When you want to open an +ALLEGRO_FILE using PhysicsFS, first call [al_set_physfs_file_interface], +then [al_fopen] or another function that calls [al_fopen]. + + +These functions are declared in the following header file. +Link with allegro_physfs. + +~~~~c + #include +~~~~ + +## API: al_set_physfs_file_interface + +This function sets *both* the [ALLEGRO_FILE_INTERFACE] and +[ALLEGRO_FS_INTERFACE] for the calling thread. + +Subsequent calls to [al_fopen] on the calling thread will be handled by +PHYSFS_open(). Operations on the files returned by [al_fopen] will then be +performed through PhysicsFS. +Calls to the Allegro filesystem functions, such as [al_read_directory] or +[al_create_fs_entry], on the calling thread will be diverted to PhysicsFS. + +To remember and restore another file I/O backend, you can use +[al_store_state]/[al_restore_state]. + +> *Note:* due to an oversight, this function differs from +[al_set_new_file_interface] and [al_set_standard_file_interface] +which only alter the current [ALLEGRO_FILE_INTERFACE]. + +> *Note:* PhysFS does not support the text-mode reading and writing, which means +that Windows-style newlines will not be preserved. + +See also: [al_set_new_file_interface]. + +## API: al_get_allegro_physfs_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. diff --git a/allegro/docs/src/refman/platform.txt b/allegro/docs/src/refman/platform.txt new file mode 100644 index 00000000..6920d519 --- /dev/null +++ b/allegro/docs/src/refman/platform.txt @@ -0,0 +1,182 @@ +# Platform-specific functions + +## Windows + +These functions are declared in the following header file: + +~~~~c + #include +~~~~ + +### API: al_get_win_window_handle + +Returns the handle to the window that the passed display is using. + +### API: al_win_add_window_callback + +The specified callback function will intercept the window's message +before Allegro processes it. If the callback function consumes the event, +then it should return true. In that case, Allegro will not do anything +with the event. + +Optionally, you may use `result` to customize what Allegro will return +return in response to this event. By default, Allegro returns `TRUE`. + +The `userdata` pointer can be used to supply additional context to the +callback function. + +The callbacks are executed in the same order they were added. + +Returns true if the callback was added. + +Since: 5.1.2 + +### API: al_win_remove_window_callback + +Removes the callback that was previously registered with +[al_win_add_window_callback]. The `userdata` pointer must be the same as +what was used during the registration of the callback. + +Returns true if the callback was removed. + +Since: 5.1.2 + +## Mac OS X + +These functions are declared in the following header file: + +~~~~c + #include +~~~~ + +### API: al_osx_get_window + +Retrieves the NSWindow handle associated with the Allegro display. + +Since: 5.0.8, 5.1.3 + +## iPhone + +These functions are declared in the following header file: + +~~~~c + #include +~~~~ + +### API: al_iphone_set_statusbar_orientation + +Sets the orientation of the status bar, which can be one of the following: + +- ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT +- ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT_UPSIDE_DOWN +- ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_RIGHT +- ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_LEFT + +Since: 5.1.0 + +### API: al_iphone_get_view + +Retrieves the UIView* (EAGLView*) associated with the Allegro display. + +Since: 5.1.0 + +### API: al_iphone_get_window + +Retrieves the UIWindow* associated with the Allegro display. + +Since: 5.1.0 + +## Android + +These functions are declared in the following header file: + +~~~~c + #include +~~~~ + +### API: al_android_set_apk_file_interface + +This function will set up a custom [ALLEGRO_FILE_INTERFACE] that makes all +future calls of [al_fopen] read from the applicatons's APK file. + +> *Note:* Currently, access to the APK file after calling this function is read +only. + +Since: 5.1.2 + +### API: al_android_set_apk_fs_interface + +This function will set up a custom [ALLEGRO_FS_INTERFACE] which allows +working within the APK filesystem. The filesystem root is your assets +directory and there is read-only access to all files within. + +> *Note:* Some things like querying file size or attributes are not +supported by this. You can always use the PhysFS addon to open the APK +file (it is just a regular .zip file) and get more complete information. + +Since: 5.1.13 + +### API: al_android_get_os_version + +Returns a pointer to a static buffer that contains the version string of the +Android platform that the calling Allegro program is running on. + +Since: 5.1.2 + +### API: al_android_get_jni_env + +Returns the Android JNI environment used by Allegro to call into Java. +As a convenience this function provides it to the user so there is no +need to obtain it yourself. + +For example if you have a Java method "void send(String message)" in +your activity class, you could call it like this from C code: + +~~~~c +JNIEnv * env = al_android_get_jni_env(); +jclass class_id = (* env)->GetObjectClass(env, al_android_get_activity()); +jmethodID method_id = (* env)->GetMethodID(env, class_id, "send", + "(Ljava/lang/String;)V"); +jstring jdata = (* env)->NewStringUTF(env, "Hello Java!"); +(* env)->CallVoidMethod(env, al_android_get_activity(), method_id, jdata); +(* env)->DeleteLocalRef(env, jdata); +~~~~ + +Since: 5.2.2 + +> *[Unstable API]:* This API is new and subject to refinement. + +### API: al_android_get_activity + +Returns the Java Android activity used by Allegro. This is the same +object created by Android from the class you specify in your manifest +and either an instance of AllegroActivity or a derived class. + +Since: 5.2.2 + +> *[Unstable API]:* This API is new and subject to refinement. + +## X11 + +These functions are declared in the following header file: + +~~~~c + #include +~~~~ + +### API: al_get_x_window_id + +Retrieves the XID associated with the Allegro display. + +Since: 5.1.12 + +### API: al_x_set_initial_icon + +On some window managers (notably Ubuntu's Unity) al_set_display_icon +doesn't work and you need to use a .desktop file. But with this function +you can set an icon before calling al_create_display. This works +by setting the icon before XMapWindow. + +Since: 5.2.3 + +> *[Unstable API]:* New API. diff --git a/allegro/docs/src/refman/primitives.txt b/allegro/docs/src/refman/primitives.txt new file mode 100644 index 00000000..e72723e9 --- /dev/null +++ b/allegro/docs/src/refman/primitives.txt @@ -0,0 +1,1293 @@ +# Primitives addon + +These functions are declared in the following header file. +Link with allegro_primitives. + +~~~~c + #include +~~~~ + +## General + +### API: al_get_allegro_primitives_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. + +### API: al_init_primitives_addon + +Initializes the primitives addon. + +*Returns:* +True on success, false on failure. + +See also: [al_shutdown_primitives_addon] + +### API: al_is_primitives_addon_initialized + +Returns true if the primitives addon is initialized, otherwise returns false. + +Since: 5.2.6 + +See also: [al_init_primitives_addon], [al_shutdown_primitives_addon] + +### API: al_shutdown_primitives_addon + +Shut down the primitives addon. This is done automatically at program exit, +but can be called any time the user wishes as well. + +See also: [al_init_primitives_addon] + +## High level drawing routines + +High level drawing routines encompass the most common usage of this addon: to +draw geometric primitives, both smooth (variations on the circle theme) and +piecewise linear. Outlined primitives support the concept of thickness with two +distinct modes of output: hairline lines and thick lines. Hairline lines are +specifically designed to be exactly a pixel wide, and are commonly used for +drawing outlined figures that need to be a pixel wide. Hairline thickness is +designated as thickness less than or equal to 0. Unfortunately, the exact +rasterization rules for drawing these hairline lines vary from one video card +to another, and sometimes leave gaps where the lines meet. If that matters to +you, then you should use thick lines. In many cases, having a thickness of 1 +will produce 1 pixel wide lines that look better than hairline lines. Obviously, +hairline lines cannot replicate thicknesses greater than 1. Thick lines grow +symmetrically around the generating shape as thickness is increased. + +### Pixel-precise output + +While normally you should not be too concerned with which pixels are displayed +when the high level primitives are drawn, it is nevertheless possible to +control that precisely by carefully picking the coordinates at which you draw +those primitives. + +To be able to do that, however, it is critical to understand how GPU cards +convert shapes to pixels. Pixels are not the smallest unit that can be +addressed by the GPU. Because the GPU deals with floating point coordinates, +it can in fact assign different coordinates to different parts of a single +pixel. To a GPU, thus, a screen is composed of a grid of squares that have width +and length of 1. The top left corner of the top left pixel is located at (0, 0). +Therefore, the center of that pixel is at (0.5, 0.5). The basic rule that +determines which pixels are associated with which shape is then as follows: +a pixel is treated to belong to a shape if the pixel's center is located in that +shape. The figure below illustrates the above concepts: + +![*Diagram showing a how pixel output is calculated by the GPU given the +mathematical description of several shapes.*](images/primitives1.png) + +This figure depicts three shapes drawn at the top left of the screen: an orange +and green rectangles and a purple circle. On the left are the mathematical +descriptions of pixels on the screen and the shapes to be drawn. On the right is +the screen output. Only a single pixel has its center inside the circle, and +therefore only a single pixel is drawn on the screen. Similarly, two pixels are +drawn for the orange rectangle. Since there are no pixels that have their +centers inside the green rectangle, the output image has no green pixels. + +Here is a more practical example. The image below shows the output of this code: + +~~~~c +/* blue vertical line */ +al_draw_line(0.5, 0, 0.5, 6, color_blue, 1); +/* red horizontal line */ +al_draw_line(2, 1, 6, 1, color_red, 2); +/* green filled rectangle */ +al_draw_filled_rectangle(3, 4, 5, 5, color_green); +/* purple outlined rectangle */ +al_draw_rectangle(2.5, 3.5, 5.5, 5.5, color_purple, 1); +~~~~ + +![*Diagram showing a practical example of pixel output resulting from the +invocation of several primitives addon functions.*](images/primitives2.png) + +It can be seen that lines are generated by making a rectangle based on the +dashed line between the two endpoints. The thickness causes the rectangle to +grow symmetrically about that generating line, as can be seen by comparing the +red and blue lines. Note that to get proper pixel coverage, the coordinates +passed to the `al_draw_line` had to be offset by 0.5 in the appropriate +dimensions. + +Filled rectangles are generated by making a rectangle between the endpoints +passed to the `al_draw_filled_rectangle`. + +Outlined rectangles are generated by symmetrically expanding an outline of a +rectangle. With a thickness of 1, as depicted in the diagram, this means that an +offset of 0.5 is needed for both sets of endpoint coordinates to exactly line +up with the pixels of the display raster. + +The above rules only apply when multisampling is turned off. When multisampling +is turned on, the area of a pixel that is covered by a shape is taken into +account when choosing what color to draw there. This also means that shapes no +longer have to contain the pixel's center to affect its color. For example, +the green rectangle in the first diagram may in fact be drawn as two (or one) +semi-transparent pixels. The advantages of multisampling is that slanted shapes +will look smoother because they will not have jagged edges. A disadvantage of +multisampling is that it may make vertical and horizontal edges blurry. While +the exact rules for multisampling are unspecified, and may vary from GPU to +GPU, it is usually safe to assume that as long as a pixel is either completely +covered by a shape or completely not covered, then the shape edges will be +sharp. The offsets used in the second diagram were chosen so that this is the +case: if you use those offsets, your shapes (if they are oriented the same way +as they are on the diagram) should look the same whether multisampling is +turned on or off. + +### API: al_draw_line + +Draws a line segment between two points. + +*Parameters:* + +* x1, y1, x2, y2 - Start and end points of the line +* color - Color of the line +* thickness - Thickness of the line, pass `<= 0` to draw hairline lines + +See also: [al_draw_soft_line] + +### API: al_draw_triangle + +Draws an outlined triangle. + +*Parameters:* + +* x1, y1, x2, y2, x3, y3 - Three points of the triangle +* color - Color of the triangle +* thickness - Thickness of the lines, pass `<= 0` to draw hairline lines + +See also: [al_draw_filled_triangle], [al_draw_soft_triangle] + +### API: al_draw_filled_triangle + +Draws a filled triangle. + +*Parameters:* + +* x1, y1, x2, y2, x3, y3 - Three points of the triangle +* color - Color of the triangle + +See also: [al_draw_triangle] + +### API: al_draw_rectangle + +Draws an outlined rectangle. + +*Parameters:* + +* x1, y1, x2, y2 - Upper left and lower right points of the rectangle +* color - Color of the rectangle +* thickness - Thickness of the lines, pass `<= 0` to draw hairline lines + +See also: [al_draw_filled_rectangle], [al_draw_rounded_rectangle] + +### API: al_draw_filled_rectangle + +Draws a filled rectangle. + +*Parameters:* + +* x1, y1, x2, y2 - Upper left and lower right points of the rectangle +* color - Color of the rectangle + +See also: [al_draw_rectangle], [al_draw_filled_rounded_rectangle] + +### API: al_draw_rounded_rectangle + +Draws an outlined rounded rectangle. + +*Parameters:* + +* x1, y1, x2, y2 - Upper left and lower right points of the rectangle +* color - Color of the rectangle +* rx, ry - The radii of the round +* thickness - Thickness of the lines, pass `<= 0` to draw hairline lines + +See also: [al_draw_filled_rounded_rectangle], [al_draw_rectangle] + +### API: al_draw_filled_rounded_rectangle + +Draws an filled rounded rectangle. + +*Parameters:* + +* x1, y1, x2, y2 - Upper left and lower right points of the rectangle +* color - Color of the rectangle +* rx, ry - The radii of the round + +See also: [al_draw_rounded_rectangle], [al_draw_filled_rectangle] + +### API: al_calculate_arc + +When `thickness <= 0` this function computes positions of `num_points` +regularly spaced points on an elliptical arc. When `thickness > 0` this +function computes two sets of points, obtained as follows: the first set is +obtained by taking the points computed in the `thickness <= 0` case and +shifting them by `thickness / 2` outward, in a direction perpendicular to the +arc curve. The second set is the same, but shifted `thickness / 2` inward +relative to the arc. The two sets of points are interleaved in the destination +buffer (i.e. the first pair of points will be collinear with the arc center, +the first point of the pair will be farther from the center than the second +point; the next pair will also be collinear, but at a different angle and so +on). + +The destination buffer `dest` is interpreted as a set of regularly spaced pairs +of floats, each pair holding the coordinates of the corresponding point on the +arc. The two floats in the pair are adjacent, and the distance (in bytes) +between the addresses of the first float in two successive pairs is `stride`. +For example, if you have a tightly packed array of floats with no spaces +between pairs, then `stride` will be exactly `2 * sizeof(float)`. + +Example with `thickness <= 0`: + +~~~~c +const int num_points = 4; +float points[num_points][2]; +al_calculate_arc(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 0, num_points); + +assert((int)points[0][0] == 10); +assert((int)points[0][1] == 0); + +assert((int)points[num_points - 1][0] == 0); +assert((int)points[num_points - 1][1] == 10); +~~~~ + +Example with `thickness > 0`: + +~~~~c +const int num_points = 4; +float points[num_points * 2][2]; +al_calculate_arc(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 2, num_points); + +assert((int)points[0][0] == 11); +assert((int)points[0][1] == 0); +assert((int)points[1][0] == 9); +assert((int)points[1][1] == 0); + +assert((int)points[(num_points - 1) * 2][0] == 0); +assert((int)points[(num_points - 1) * 2][1] == 11); +assert((int)points[(num_points - 1) * 2 + 1][0] == 0); +assert((int)points[(num_points - 1) * 2 + 1][1] == 9); +~~~~ + +*Parameters:* + +* dest - The destination buffer +* stride - Distance (in bytes) between starts of successive pairs of points +* cx, cy - Center of the arc +* rx, ry - Radii of the arc +* start_theta - The initial angle from which the arc is calculated in radians +* delta_theta - Angular span of the arc in radians (pass a negative number to switch + direction) +* thickness - Thickness of the arc +* num_points - The number of points to calculate + +See also: [al_draw_arc], [al_calculate_spline], [al_calculate_ribbon] + +### API: al_draw_pieslice + +Draws a pieslice (outlined circular sector). + +*Parameters:* + +* cx, cy - Center of the pieslice +* r - Radius of the pieslice +* color - Color of the pieslice +* start_theta - The initial angle from which the pieslice is drawn in radians +* delta_theta - Angular span of the pieslice in radians (pass a negative number to switch + direction) +* thickness - Thickness of the circle, pass `<= 0` to draw hairline pieslice + +Since: 5.0.6, 5.1.0 + +See also: [al_draw_filled_pieslice] + +### API: al_draw_filled_pieslice + +Draws a filled pieslice (filled circular sector). + +*Parameters:* + +* cx, cy - Center of the pieslice +* r - Radius of the pieslice +* color - Color of the pieslice +* start_theta - The initial angle from which the pieslice is drawn in radians +* delta_theta - Angular span of the pieslice in radians (pass a negative number to switch + direction) + +Since: 5.0.6, 5.1.0 + +See also: [al_draw_pieslice] + +### API: al_draw_ellipse + +Draws an outlined ellipse. + +*Parameters:* + +* cx, cy - Center of the ellipse +* rx, ry - Radii of the ellipse +* color - Color of the ellipse +* thickness - Thickness of the ellipse, pass `<= 0` to draw a hairline ellipse + +See also: [al_draw_filled_ellipse], [al_draw_circle] + +### API: al_draw_filled_ellipse + +Draws a filled ellipse. + +*Parameters:* + +* cx, cy - Center of the ellipse +* rx, ry - Radii of the ellipse +* color - Color of the ellipse + +See also: [al_draw_ellipse], [al_draw_filled_circle] + +### API: al_draw_circle + +Draws an outlined circle. + +*Parameters:* + +* cx, cy - Center of the circle +* r - Radius of the circle +* color - Color of the circle +* thickness - Thickness of the circle, pass `<= 0` to draw a hairline circle + +See also: [al_draw_filled_circle], [al_draw_ellipse] + +### API: al_draw_filled_circle + +Draws a filled circle. + +*Parameters:* + +* cx, cy - Center of the circle +* r - Radius of the circle +* color - Color of the circle + +See also: [al_draw_circle], [al_draw_filled_ellipse] + +### API: al_draw_arc + +Draws an arc. + +*Parameters:* + +* cx, cy - Center of the arc +* r - Radius of the arc +* color - Color of the arc +* start_theta - The initial angle from which the arc is calculated in radians +* delta_theta - Angular span of the arc in radians (pass a negative number to switch + direction) +* thickness - Thickness of the arc, pass `<= 0` to draw hairline arc + +See also: [al_calculate_arc], [al_draw_elliptical_arc] + +### API: al_draw_elliptical_arc + +Draws an elliptical arc. + +*Parameters:* + +* cx, cy - Center of the arc +* rx, ry - Radii of the arc +* color - Color of the arc +* start_theta - The initial angle from which the arc is calculated in radians +* delta_theta - Angular span of the arc in radians (pass a negative number to switch + direction) +* thickness - Thickness of the arc, pass `<= 0` to draw hairline arc + +Since: 5.0.6, 5.1.0 + +See also: [al_calculate_arc], [al_draw_arc] + + +### API: al_calculate_spline + +Calculates a Bézier spline given 4 control points. If `thickness <= 0`, then +`num_segments` of points are required in the destination, otherwise twice as +many are needed. The destination buffer should consist of regularly spaced (by +distance of stride bytes) doublets of floats, corresponding to x and y +coordinates of the vertices. + +*Parameters:* + +* dest - The destination buffer +* stride - Distance (in bytes) between starts of successive pairs of coordinates +* points - An array of 4 pairs of coordinates of the 4 control points +* thickness - Thickness of the spline ribbon +* num_segments - The number of points to calculate + +See also: [al_draw_spline], [al_calculate_arc], [al_calculate_ribbon] + +### API: al_draw_spline + +Draws a Bézier spline given 4 control points. + +*Parameters:* + +* points - An array of 4 pairs of coordinates of the 4 control points +* color - Color of the spline +* thickness - Thickness of the spline, pass `<= 0` to draw a hairline spline + +See also: [al_calculate_spline] + +### API: al_calculate_ribbon + +Calculates a ribbon given an array of points. The ribbon will go through all of +the passed points. If `thickness <= 0`, then `num_segments` of points are +required in the destination buffer, otherwise twice as many are needed. +The destination and the points buffer should consist of regularly spaced +doublets of floats, corresponding to x and y coordinates of the vertices. + +*Parameters:* + +* dest - Pointer to the destination buffer +* dest_stride - Distance (in bytes) between starts of successive pairs of + coordinates in the destination buffer +* points - An array of pairs of coordinates for each point +* points_stride - Distance (in bytes) between starts of successive pairs of + coordinates in the points buffer +* thickness - Thickness of the spline ribbon +* num_segments - The number of points to calculate + +See also: [al_draw_ribbon], [al_calculate_arc], [al_calculate_spline] + +### API: al_draw_ribbon + +Draws a ribbon given an array of points. The ribbon will go through all of +the passed points. The points buffer should consist of regularly spaced +doublets of floats, corresponding to x and y coordinates of the vertices. + +*Parameters:* + +* points - An array of coordinate pairs (x and y) for each point +* points_stride - Distance (in bytes) between starts of successive pairs of + coordinates in the points buffer +* color - Color of the spline +* thickness - Thickness of the spline, pass `<= 0` to draw hairline spline +* num_segments - The number of segments + +See also: [al_calculate_ribbon] + +## Low level drawing routines + +Low level drawing routines allow for more advanced usage of the addon, allowing +you to pass arbitrary sequences of vertices to draw to the screen. These +routines also support using textures on the primitives with the following +restrictions: + +For maximum portability, you should only use textures that have dimensions that +are a power of two, as not every videocard supports textures of different sizes +completely. This warning is relaxed, however, if the texture coordinates +never exit the boundaries of a single bitmap (i.e. you are not having the texture +repeat/tile). As long as that is the case, any texture can be used safely. +Sub-bitmaps work as textures, but cannot be tiled. + +Some platforms also dictate a minimum texture size, which means that textures +smaller than that size will not tile properly. The minimum size that will work +on all platforms is 32 by 32. + +A note about pixel coordinates. In OpenGL the texture coordinate (0, 0) refers +to the top left corner of the pixel. This confuses some drivers, because due to +rounding errors the actual pixel sampled might be the pixel to the top and/or +left of the (0, 0) pixel. To make this error less likely it is advisable to +offset the texture coordinates you pass to the al_draw_prim by (0.5, 0.5) if you +need precise pixel control. E.g. to refer to pixel (5, 10) you'd set the u and v +to 5.5 and 10.5 respectively. + +See also: [Pixel-precise output] + +### API: al_draw_prim + +Draws a subset of the passed vertex array. + +*Parameters:* + +* texture - Texture to use, pass NULL to use only color shaded primitves +* vtxs - Pointer to an array of vertices +* decl - Pointer to a [vertex declaration][al_create_vertex_decl]. If set to NULL, + the vertices are assumed to be of the [ALLEGRO_VERTEX] type +* start - Start index of the subset of the vertex array to draw +* end - One past the last index of the subset of the vertex array to draw +* type - A member of the [ALLEGRO_PRIM_TYPE] enumeration, specifying what kind + of primitive to draw + +*Returns:* +Number of primitives drawn + +For example to draw a textured triangle you could use: + +~~~~c +ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1); +ALLEGRO_VERTEX v[] = { + {.x = 128, .y = 0, .z = 0, .color = white, .u = 128, .v = 0}, + {.x = 0, .y = 256, .z = 0, .color = white, .u = 0, .v = 256}, + {.x = 256, .y = 256, .z = 0, .color = white, .u = 256, .v = 256}}; +al_draw_prim(v, NULL, texture, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST); +~~~~ + +See also: +[ALLEGRO_VERTEX], [ALLEGRO_PRIM_TYPE], [ALLEGRO_VERTEX_DECL], +[al_draw_indexed_prim] + +### API: al_draw_indexed_prim + +Draws a subset of the passed vertex array. This function uses an index array +to specify which vertices to use. + +*Parameters:* + +* texture - Texture to use, pass NULL to use only color shaded primitves +* vtxs - Pointer to an array of vertices +* decl - Pointer to a vertex declaration. If set to NULL, the vtxs are assumed + to be of the ALLEGRO_VERTEX type +* indices - An array of indices into the vertex array +* num_vtx - Number of indices from the indices array you want to draw +* type - A member of the [ALLEGRO_PRIM_TYPE] enumeration, specifying what kind + of primitive to draw + +*Returns:* +Number of primitives drawn + +See also: +[ALLEGRO_VERTEX], [ALLEGRO_PRIM_TYPE], [ALLEGRO_VERTEX_DECL], [al_draw_prim] + +### API: al_draw_vertex_buffer + +Draws a subset of the passed vertex buffer. The vertex buffer must +not be locked. Additionally, to draw onto memory bitmaps or with +memory bitmap textures the vertex buffer must support reading (i.e. +it must be created with the `ALLEGRO_PRIM_BUFFER_READWRITE`). + +*Parameters:* + +* vertex_buffer - Vertex buffer to draw +* texture - Texture to use, pass NULL to use only color shaded primitves +* start - Start index of the subset of the vertex buffer to draw +* end - One past the last index of the subset of the vertex buffer to draw +* type - A member of the [ALLEGRO_PRIM_TYPE] enumeration, specifying what kind + of primitive to draw + +*Returns:* +Number of primitives drawn + +Since: 5.1.3 + +See also: +[ALLEGRO_VERTEX_BUFFER], [ALLEGRO_PRIM_TYPE] + +### API: al_draw_indexed_buffer + +Draws a subset of the passed vertex buffer. This function uses an +index buffer to specify which vertices to use. Both buffers must not +be locked. Additionally, to draw onto memory bitmaps or with memory +bitmap textures both buffers must support reading (i.e. they must be +created with the `ALLEGRO_PRIM_BUFFER_READWRITE`). + +*Parameters:* + +* vertex_buffer - Vertex buffer to draw +* texture - Texture to use, pass NULL to use only color shaded primitves +* index_buffer - Index buffer to use +* start - Start index of the subset of the vertex buffer to draw +* end - One past the last index of the subset of the vertex buffer to draw +* type - A member of the [ALLEGRO_PRIM_TYPE] enumeration, specifying + what kind of primitive to draw. Note that ALLEGRO_PRIM_LINE_LOOP and + ALLEGRO_PRIM_POINT_LIST are not supported. + +*Returns:* +Number of primitives drawn + +Since: 5.1.8 + +See also: +[ALLEGRO_VERTEX_BUFFER], [ALLEGRO_INDEX_BUFFER], [ALLEGRO_PRIM_TYPE] + +### API: al_draw_soft_triangle + +Draws a triangle using the software rasterizer and user supplied pixel +functions. For help in understanding what these functions do, see the +implementation of the various shading routines in addons/primitives/tri_soft.c. +The triangle is drawn in two segments, from top to bottom. The segments are +deliniated by the vertically middle vertex of the triangle. One of the two +segments may be absent if two vertices are horizontally collinear. + +*Parameters:* + +* v1, v2, v3 - The three vertices of the triangle +* state - A pointer to a user supplied struct, this struct will be passed to + all the pixel functions +* init - Called once per call before any drawing is done. The three + points passed to it may be altered by clipping. +* first - Called twice per call, once per triangle segment. It is + passed 4 parameters, the first two are the coordinates of the initial pixel + drawn in the segment. + The second two are the left minor and the left major steps, respectively. + They represent the sizes of two steps taken by the rasterizer as it walks + on the left side of the triangle. From then on, each step will either + be classified as a minor or a major step, corresponding to the above + values. +* step - Called once per scanline. The last parameter is set to 1 if the step + is a minor step, and 0 if it is a major step. +* draw - Called once per scanline. The function is expected to draw the + scanline starting with a point specified by the first two parameters + (corresponding to x and y values) going to the right until it reaches the + value of the third parameter (the x value of the end point). All coordinates + are inclusive. + +See also: [al_draw_triangle] + +### API: al_draw_soft_line + +Draws a line using the software rasterizer and user supplied pixel functions. +For help in understanding what these functions do, see the implementation of +the various shading routines in addons/primitives/line_soft.c. +The line is drawn top to bottom. + +*Parameters:* + +* v1, v2 - The two vertices of the line +* state - A pointer to a user supplied struct, this struct will be passed to + all the pixel functions +* first - Called before drawing the first pixel of the line. It + is passed the coordinates of this pixel, as well as the two vertices above. + The passed vertices may have been altered by clipping. +* step - Called once per pixel. The second parameter is set to 1 if the step is + a minor step, and 0 if this step is a major step. Minor steps are taken only + either in x or y directions. + Major steps are taken in both directions diagonally. In all cases, the + absolute value of the change in coordinate is at most 1 in either direction. +* draw - Called once per pixel. The function is expected to draw the pixel at + the coordinates passed to it. + +See also: [al_draw_line] + +## Custom vertex declaration routines + +### API: al_create_vertex_decl + +Creates a vertex declaration, which describes a custom vertex format. + +*Parameters:* + +* elements - An array of [ALLEGRO_VERTEX_ELEMENT] structures. +* stride - Size of the custom vertex structure + +*Returns:* +Newly created vertex declaration. + +See also: +[ALLEGRO_VERTEX_ELEMENT], [ALLEGRO_VERTEX_DECL], [al_destroy_vertex_decl] + +### API: al_destroy_vertex_decl + +Destroys a vertex declaration. + +*Parameters:* + +* decl - Vertex declaration to destroy + +See also: +[ALLEGRO_VERTEX_ELEMENT], [ALLEGRO_VERTEX_DECL], [al_create_vertex_decl] + +## Vertex buffer routines + +### API: al_create_vertex_buffer + +Creates a vertex buffer. Can return NULL if the buffer could not be +created (e.g. the system only supports write-only buffers). + +> *Note:* +> +> This is an advanced feature, often unsupported on lower-end video cards. +> Be extra mindful of this function failing and make arrangements for +> fallback drawing functionality or a nice error message for users with +> such lower-end cards. + +*Parameters:* + +* decl - Vertex type that this buffer will hold. NULL implies that this buffer will + hold [ALLEGRO_VERTEX] vertices +* initial_data - Memory buffer to copy from to initialize the vertex buffer. Can + be `NULL`, in which case the buffer is uninitialized. +* num_vertices - Number of vertices the buffer will hold +* flags - A combination of the [ALLEGRO_PRIM_BUFFER_FLAGS] flags + specifying how this buffer will be created. Passing 0 is the same + as passing `ALLEGRO_PRIM_BUFFER_STATIC`. + +Since: 5.1.3 + +See also: [ALLEGRO_VERTEX_BUFFER], [al_destroy_vertex_buffer] + +### API: al_destroy_vertex_buffer + +Destroys a vertex buffer. Does nothing if passed NULL. + +Since: 5.1.3 + +See also: [ALLEGRO_VERTEX_BUFFER], [al_create_vertex_buffer] + +### API: al_lock_vertex_buffer + +Locks a vertex buffer so you can access its data. Will return NULL if the +parameters are invalid, if reading is requested from a write only buffer, or +if the buffer is already locked. + +*Parameters:* + +* buffer - Vertex buffer to lock +* offset - Vertex index of the start of the locked range +* length - How many vertices to lock +* flags - ALLEGRO_LOCK_READONLY, ALLEGRO_LOCK_WRITEONLY or ALLEGRO_LOCK_READWRITE + +Since: 5.1.3 + +See also: [ALLEGRO_VERTEX_BUFFER], [al_unlock_vertex_buffer] + +### API: al_unlock_vertex_buffer + +Unlocks a previously locked vertex buffer. + +Since: 5.1.3 + +See also: [ALLEGRO_VERTEX_BUFFER], [al_lock_vertex_buffer] + +### API: al_get_vertex_buffer_size + +Returns the size of the vertex buffer + +Since: 5.1.8 + +See also: [ALLEGRO_VERTEX_BUFFER] + +## Index buffer routines + +### API: al_create_index_buffer + +Creates a index buffer. Can return NULL if the buffer could not be +created (e.g. the system only supports write-only buffers). + +> *Note:* +> +> This is an advanced feature, often unsupported on lower-end video cards. +> Be extra mindful of this function failing and make arrangements for +> fallback drawing functionality or a nice error message for users with +> such lower-end cards. + +*Parameters:* + +* index_size - Size of the index in bytes. Supported sizes are 2 + for short integers and 4 for integers +* initial_data - Memory buffer to copy from to initialize the index + buffer. Can be `NULL`, in which case the buffer is uninitialized. +* num_indices - Number of indices the buffer will hold +* flags - A combination of the [ALLEGRO_PRIM_BUFFER_FLAGS] flags + specifying how this buffer will be created. Passing 0 is the same + as passing `ALLEGRO_PRIM_BUFFER_STATIC`. + +Since: 5.1.8 + +See also: [ALLEGRO_INDEX_BUFFER], [al_destroy_index_buffer] + +### API: al_destroy_index_buffer + +Destroys a index buffer. Does nothing if passed NULL. + +Since: 5.1.8 + +See also: [ALLEGRO_INDEX_BUFFER], [al_create_index_buffer] + +### API: al_lock_index_buffer + +Locks a index buffer so you can access its data. Will return NULL if the +parameters are invalid, if reading is requested from a write only buffer and +if the buffer is already locked. + +*Parameters:* + +* buffer - Index buffer to lock +* offset - Element index of the start of the locked range +* length - How many indices to lock +* flags - ALLEGRO_LOCK_READONLY, ALLEGRO_LOCK_WRITEONLY or ALLEGRO_LOCK_READWRITE + +Since: 5.1.8 + +See also: [ALLEGRO_INDEX_BUFFER], [al_unlock_index_buffer] + +### API: al_unlock_index_buffer + +Unlocks a previously locked index buffer. + +Since: 5.1.8 + +See also: [ALLEGRO_INDEX_BUFFER], [al_lock_index_buffer] + +### API: al_get_index_buffer_size + +Returns the size of the index buffer + +Since: 5.1.8 + +See also: [ALLEGRO_INDEX_BUFFER] + +## Polygon routines + +### API: al_draw_polyline + +Draw a series of line segments. + +* vertices - Interleaved array of (x, y) vertex coordinates +* vertex_stride - the number of bytes between pairs of vertices (the stride) +* vertex_count - Number of vertices in the array +* join_style - Member of [ALLEGRO_LINE_JOIN] specifying how to render the +joins between line segments +* cap_style - Member of [ALLEGRO_LINE_CAP] specifying how to render the end +caps +* color - Color of the line +* thickness - Thickness of the line, pass `<= 0` to draw hairline lines +* miter_limit - Parameter for miter join style + +The stride is normally `2 * sizeof(float)` but may be more if the vertex +coordinates are in an array of some structure type, e.g. + +~~~~c +struct VertexInfo { + float x; + float y; + int id; +}; + +void my_draw(struct VertexInfo verts[], int vertex_count, ALLEGRO_COLOR c) +{ + al_draw_polyline((float *)verts, sizeof(VertexInfo), vertex_count, + ALLEGRO_LINE_JOIN_NONE, ALLEGRO_LINE_CAP_NONE, c, 1.0, 1.0); +} +~~~~ + +The stride may also be negative if the vertices are stored in reverse order. + +Since: 5.1.0 + +See also: [al_draw_polygon], [ALLEGRO_LINE_JOIN], [ALLEGRO_LINE_CAP] + +### API: al_draw_polygon + +Draw an unfilled polygon. This is the same as passing +`ALLEGRO_LINE_CAP_CLOSED` to [al_draw_polyline]. + +* vertex - Interleaved array of (x, y) vertex coordinates +* vertex_count - Number of vertices in the array +* join_style - Member of [ALLEGRO_LINE_JOIN] specifying how to render the +joins between line segments +* color - Color of the line +* thickness - Thickness of the line, pass `<= 0` to draw hairline lines +* miter_limit - Parameter for miter join style + +Since: 5.1.0 + +See also: [al_draw_filled_polygon], [al_draw_polyline], [ALLEGRO_LINE_JOIN] + +### API: al_draw_filled_polygon + +Draw a filled, simple polygon. Simple means it does not have to be convex but +must not be self-overlapping. + +* vertices - Interleaved array of (x, y) vertex coordinates +* vertex_count - Number of vertices in the array +* color - Color of the filled polygon + +When the y-axis is facing downwards (the usual), the coordinates must be +ordered anti-clockwise. + +Since: 5.1.0 + +See also: [al_draw_polygon], [al_draw_filled_polygon_with_holes] + +### API: al_draw_filled_polygon_with_holes + +Draws a filled simple polygon with zero or more other simple polygons +subtracted from it - the holes. The holes cannot touch or intersect with the +outline of the filled polygon. + +* vertices - Interleaved array of (x, y) vertex coordinates for each of the + polygons, including holes. +* vertex_counts - Number of vertices for each polygon. + The number of vertices in the filled polygon is given by vertex_counts[0] and + must be at least three. Subsequent elements indicate the number of vertices + in each hole. The array must be terminated with an element with value zero. +* color - Color of the filled polygon + +When the y-axis is facing downwards (the usual) the filled polygon coordinates +must be ordered anti-clockwise. All hole vertices must use the opposite order +(clockwise with y down). All hole vertices must be inside the main polygon and +no hole may overlap the main polygon. + +For example: + +~~~~c +float vertices[] = { + 0, 0, // filled polygon, upper left corner + 0, 100, // filled polygon, lower left corner + 100, 100, // filled polygon, lower right corner + 100, 0, // filled polygon, upper right corner + 10, 10, // hole, upper left + 90, 10, // hole, upper right + 90, 90 // hole, lower right +}; +int vertex_counts[] = { + 4, // number of vertices for filled polygon + 3, // number of vertices for hole + 0 // terminator +}; +~~~~ + +There are 7 vertices: four for an outer square from (0, 0) to (100, 100) in +anti-clockwise order, and three more for an inner triangle in clockwise order. +The outer main polygon uses vertices 0 to 3 (inclusive) and the hole uses +vertices 4 to 6 (inclusive). + +Since: 5.1.0 + +See also: [al_draw_filled_polygon], [al_draw_filled_polygon_with_holes], +[al_triangulate_polygon] + +### API: al_triangulate_polygon + +Divides a simple polygon into triangles, with zero or more other simple +polygons subtracted from it - the holes. The holes cannot touch or intersect +with the outline of the main polygon. Simple means the polygon does not have +to be convex but must not be self-overlapping. + +*Parameters:* + +* vertices - Interleaved array of (x, y) vertex coordinates for each of the + polygons, including holes. +* vertex_stride - distance (in bytes) between successive pairs of vertices in + the array. +* vertex_counts - Number of vertices for each polygon. + The number of vertices in the main polygon is given by vertex_counts[0] and + must be at least three. Subsequent elements indicate the number of vertices + in each hole. The array must be terminated with an element with value zero. +* emit_triangle - + a function to be called for every set of three points that form a triangle. + The function is passed the indices of the points in `vertices` and `userdata`. +* userdata - arbitrary data to be passed to emit_triangle. + +Since: 5.1.0 + +See also: [al_draw_filled_polygon_with_holes] + +## Structures and types + +### API: ALLEGRO_VERTEX + +Defines the generic vertex type, with a 3D position, color and texture +coordinates for a single texture. Note that at this time, the software driver +for this addon cannot render 3D primitives. If you want a 2D only primitive, +set z to 0. Note that you must initialize all members of this struct when +you're using it. One exception to this rule are the u and v variables which can +be left uninitialized when you are not using textures. + +*Fields:* + +* x, y, z - Position of the vertex (float) +* u, v - Texture coordinates measured in pixels (float) +* color - [ALLEGRO_COLOR] structure, storing the color of the vertex + +See also: +[ALLEGRO_PRIM_ATTR] + +### API: ALLEGRO_VERTEX_DECL + +A vertex declaration. This opaque structure is responsible for describing +the format and layout of a user defined custom vertex. It is created and +destroyed by specialized functions. + +See also: +[al_create_vertex_decl], [al_destroy_vertex_decl], [ALLEGRO_VERTEX_ELEMENT] + +### API: ALLEGRO_VERTEX_ELEMENT + +A small structure describing a certain element of a vertex. E.g. the +position of the vertex, or its color. These structures are used by the +[al_create_vertex_decl] function to create the vertex declaration. For that they +generally occur in an array. The last element of such an array should have the +attribute field equal to 0, to signify that it is the end of the array. +Here is an example code that would create a declaration describing the +[ALLEGRO_VERTEX] structure (passing this as vertex declaration to +al_draw_prim would be identical to passing NULL): + +~~~~c +/* On compilers without the offsetof keyword you need to obtain the + * offset with sizeof and make sure to account for packing. + */ +ALLEGRO_VERTEX_ELEMENT elems[] = { + {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX, x)}, + {ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_FLOAT_2, offsetof(ALLEGRO_VERTEX, u)}, + {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ALLEGRO_VERTEX, color)}, + {0, 0, 0} +}; +ALLEGRO_VERTEX_DECL* decl = al_create_vertex_decl(elems, sizeof(ALLEGRO_VERTEX)); +~~~~ + +*Fields:* + +* attribute - A member of the [ALLEGRO_PRIM_ATTR] enumeration, specifying what + this attribute signifies +* storage - A member of the [ALLEGRO_PRIM_STORAGE] enumeration, specifying how + this attribute is stored +* offset - Offset in bytes from the beginning of the custom vertex structure. The C + function offsetof is very useful here. + +See also: +[al_create_vertex_decl], [ALLEGRO_VERTEX_DECL], [ALLEGRO_PRIM_ATTR], +[ALLEGRO_PRIM_STORAGE] + +### API: ALLEGRO_PRIM_TYPE + +Enumerates the types of primitives this addon can draw. + +* ALLEGRO_PRIM_POINT_LIST - A list of points, each vertex defines a point + +* ALLEGRO_PRIM_LINE_LIST - A list of lines, sequential pairs of vertices define + disjointed lines + +* ALLEGRO_PRIM_LINE_STRIP - A strip of lines, sequential vertices define a + strip of lines + +* ALLEGRO_PRIM_LINE_LOOP - Like a line strip, except at the end the first and + the last vertices are also connected by a line + +* ALLEGRO_PRIM_TRIANGLE_LIST - A list of triangles, sequential triplets of + vertices define disjointed triangles + +* ALLEGRO_PRIM_TRIANGLE_STRIP - A strip of triangles, sequential vertices + define a strip of triangles + +* ALLEGRO_PRIM_TRIANGLE_FAN - A fan of triangles, all triangles share the first + vertex + +### API: ALLEGRO_PRIM_ATTR + +Enumerates the types of vertex attributes that a custom vertex may have. + +* ALLEGRO_PRIM_POSITION - Position information, can be stored only in + ALLEGRO_PRIM_SHORT_2, ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_FLOAT_3. + +* ALLEGRO_PRIM_COLOR_ATTR - Color information, stored in an [ALLEGRO_COLOR]. + The storage field of ALLEGRO_VERTEX_ELEMENT is ignored + +* ALLEGRO_PRIM_TEX_COORD - Texture coordinate information, can be stored only in + ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are + normalized by the width and height of the texture, meaning that the + bottom-right corner has texture coordinates of (1, 1). + +* ALLEGRO_PRIM_TEX_COORD_PIXEL - Texture coordinate information, can be stored + only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are + measured in pixels. + +* ALLEGRO_PRIM_USER_ATTR - A user specified attribute. You can use any storage + for this attribute. You may have at most ALLEGRO_PRIM_MAX_USER_ATTR + (currently 10) of these that you can specify by adding an index to the + value of ALLEGRO_PRIM_USER_ATTR, e.g. the first user attribute is + `ALLEGRO_PRIM_USER_ATTR + 0`, the second is + `ALLEGRO_PRIM_USER_ATTR + 1` and so on. + + To access these custom attributes from GLSL shaders you need to declare + attributes that follow this nomenclature: `al_user_attr_#` where # is the index + of the attribute. + + For example to have a position and a normal vector for each vertex + you could declare it like this: + + ~~~~c + ALLEGRO_VERTEX_ELEMENT elements[3] = { + {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, 0}, + {ALLEGRO_PRIM_USER_ATTR + 0, ALLEGRO_PRIM_FLOAT_3, 12}, + {0, 0, 0}}; + ~~~~ + + And then in your vertex shader access it like this: + + ~~~~c + attribute vec3 al_pos; // ALLEGRO_PRIM_POSITION + attribute vec3 al_user_attr_0; // ALLEGRO_PRIM_USER_ATTR + 0 + varying float light; + const vec3 light_direction = vec3(0, 0, 1); + void main() { + light = dot(al_user_attr_0, light_direction); + gl_Position = al_pos; + } + ~~~~ + + To access these custom attributes from HLSL you need to declare a parameter + with the following semantics: `TEXCOORD{# + 2}` where # is the index of the + attribute. E.g. the first attribute can be accessed via `TEXCOORD2`, second + via `TEXCOORD3` and so on. + + Since: 5.1.6 + +See also: +[ALLEGRO_VERTEX_DECL], [ALLEGRO_PRIM_STORAGE], [al_attach_shader_source] + +### API: ALLEGRO_PRIM_STORAGE + +Enumerates the types of storage an attribute of a custom vertex may be stored +in. Many of these can only be used for ALLEGRO_PRIM_USER_ATTR attributes and +can only be accessed via shaders. Usually no matter what the storage is +specified the attribute gets converted to single precision floating point when +the shader is run. Despite that, it may be advantageous to use more dense +storage formats (e.g. ALLEGRO_PRIM_NORMALIZED_UBYTE_4 instead of +ALLEGRO_PRIM_FLOAT_4) when bandwidth (amount of memory sent to the GPU) is an +issue but precision is not. + +* ALLEGRO_PRIM_FLOAT_1 - A single float + + Since: 5.1.6 +* ALLEGRO_PRIM_FLOAT_2 - A doublet of floats + +* ALLEGRO_PRIM_FLOAT_3 - A triplet of floats + +* ALLEGRO_PRIM_FLOAT_4 - A quad of floats + + Since: 5.1.6 +* ALLEGRO_PRIM_SHORT_2 - A doublet of shorts + +* ALLEGRO_PRIM_SHORT_4 - A quad of shorts + + Since: 5.1.6 +* ALLEGRO_PRIM_UBYTE_4 - A quad of unsigned bytes + + Since: 5.1.6 +* ALLEGRO_PRIM_NORMALIZED_SHORT_2 - A doublet of shorts. Before being sent to + the shader, each component is divided by 32767. Each component of the + resultant float doublet ranges between -1.0 and 1.0 + + Since: 5.1.6 +* ALLEGRO_PRIM_NORMALIZED_SHORT_4 - A quad of shorts. Before being sent to + the shader, each component is divided by 32767. Each component of the + resultant float quad ranges between -1.0 and 1.0 + + Since: 5.1.6 +* ALLEGRO_PRIM_NORMALIZED_UBYTE_4 - A quad of unsigned bytes. Before being sent + to the shader, each component is divided by 255. Each component of the + resultant float quad ranges between 0.0 and 1.0 + + Since: 5.1.6 +* ALLEGRO_PRIM_NORMALIZED_USHORT_2 - A doublet of unsigned shorts. Before being + sent to the shader, each component is divided by 65535. Each component of + the resultant float doublet ranges between 0.0 and 1.0 + + Since: 5.1.6 +* ALLEGRO_PRIM_NORMALIZED_USHORT_4 - A quad of unsigned shorts. Before being + sent to the shader, each component is divided by 65535. Each component of + the resultant float quad ranges between 0.0 and 1.0 + + Since: 5.1.6 +* ALLEGRO_PRIM_HALF_FLOAT_2 - A doublet of half-precision floats. Note that this + storage format is not supported on all platforms. [al_create_vertex_decl] + will return NULL if you use it on those platforms + + Since: 5.1.6 +* ALLEGRO_PRIM_HALF_FLOAT_4 - A quad of half-precision floats. Note that this + storage format is not supported on all platforms. [al_create_vertex_decl] + will return NULL if you use it on those platforms. + + Since: 5.1.6 + +See also: +[ALLEGRO_PRIM_ATTR] + +### API: ALLEGRO_VERTEX_CACHE_SIZE + +Defines the size of the transformation vertex cache for the software renderer. +If you pass less than this many vertices to the primitive rendering functions +you will get a speed boost. This also defines the size of the cache vertex +buffer, used for the high-level primitives. This corresponds to the maximum +number of line segments that will be used to form them. + +### API: ALLEGRO_PRIM_QUALITY + +Controls the quality of the approximation of curved primitives (e.g. circles). +Curved primitives are drawn by approximating them with a sequence of line +segments. By default, this roughly corresponds to error of less than half of a +pixel. + +### API: ALLEGRO_LINE_JOIN + +* ALLEGRO_LINE_JOIN_NONE +* ALLEGRO_LINE_JOIN_BEVEL +* ALLEGRO_LINE_JOIN_ROUND +* ALLEGRO_LINE_JOIN_MITER + +![*ALLEGRO_LINE_JOIN styles*](images/LINE_JOIN.png) + +See the picture for the difference. + +The maximum miter length (relative to the line width) can be specified as +parameter to the polygon functions. + +Since: 5.1.0 + +See also: [al_draw_polygon] + +### API: ALLEGRO_LINE_CAP + +* ALLEGRO_LINE_CAP_NONE +* ALLEGRO_LINE_CAP_SQUARE +* ALLEGRO_LINE_CAP_ROUND +* ALLEGRO_LINE_CAP_TRIANGLE +* ALLEGRO_LINE_CAP_CLOSED + +![*ALLEGRO_LINE_CAP styles*](images/LINE_CAP.png) + +See the picture for the difference. + +ALLEGRO_LINE_CAP_CLOSED is different from the others - it causes the polygon +to have no caps. (And the [ALLEGRO_LINE_JOIN] style will determine how the +vertex looks.) + +Since: 5.1.0 + +See also: [al_draw_polygon] + +### API: ALLEGRO_VERTEX_BUFFER + +A GPU vertex buffer that you can use to store vertices on the GPU instead of +uploading them afresh during every drawing operation. + +Since: 5.1.3 + +See also: [al_create_vertex_buffer], [al_destroy_vertex_buffer] + +### API: ALLEGRO_INDEX_BUFFER + +A GPU index buffer that you can use to store indices of vertices in +a vertex buffer on the GPU instead of uploading them afresh during +every drawing operation. + +Since: 5.1.8 + +See also: [al_create_index_buffer], [al_destroy_index_buffer] + +### API: ALLEGRO_PRIM_BUFFER_FLAGS + +Flags to specify how to create a vertex or an index buffer. + +* ALLEGRO_PRIM_BUFFER_STREAM - Hints to the driver that the buffer + is written to often, but used only a few times per frame + +* ALLEGRO_PRIM_BUFFER_STATIC - Hints to the driver that the buffer + is written to once and is used often + +* ALLEGRO_PRIM_BUFFER_DYNAMIC - Hints to the driver that the buffer + is written to often and is used often + +* ALLEGRO_PRIM_BUFFER_READWRITE - Specifies that you want to be able + read from this buffer. By default this is disabled for performance. + Some platforms (like OpenGL ES) do not support reading from vertex + buffers, so if you pass this flag to `al_create_vertex_buffer` or + `al_create_index_buffer` the call will fail. + +Since: 5.1.3 + +See also: [al_create_vertex_buffer], [al_create_index_buffer] diff --git a/allegro/docs/src/refman/shader.txt b/allegro/docs/src/refman/shader.txt new file mode 100644 index 00000000..19f34e14 --- /dev/null +++ b/allegro/docs/src/refman/shader.txt @@ -0,0 +1,392 @@ +# Shader routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_SHADER + +An [ALLEGRO_SHADER] is a program that runs on the GPU. +It combines both a vertex and a pixel shader. +(In OpenGL terms, an [ALLEGRO_SHADER] is actually a *program* +which has one or more *shaders* attached. This can be confusing.) + +The source code for the underlying vertex or pixel shader can be provided +either as GLSL or HLSL, depending on the value of [ALLEGRO_SHADER_PLATFORM] +used when creating it. + +Since: 5.1.0 + +## API: ALLEGRO_SHADER_TYPE + +Used with [al_attach_shader_source] and [al_attach_shader_source_file] to +specify how to interpret the attached source. + +ALLEGRO_VERTEX_SHADER +: A vertex shader is executed for each vertex it is + used with. The program will output exactly one vertex at a time. + + When Allegro's graphics are being used then in addition to all vertices of + primitives from the primitives addon, each drawn bitmap also consists of + four vertices. + +ALLEGRO_PIXEL_SHADER +: A pixel shader is executed for each pixel it is used + with. The program will output exactly one pixel at a time - either in the + backbuffer or in the current target bitmap. + + With Allegro's builtin graphics this means the shader is for example called + for each destination pixel of the output of an [al_draw_bitmap] call. + + A more accurate term for pixel shader would be fragment shader since one + final pixel in the target bitmap is not necessarily composed of only a + single output but of multiple fragments (for example when multi-sampling is + being used). + +Since: 5.1.0 + +## API: ALLEGRO_SHADER_PLATFORM + +The underlying platform which the [ALLEGRO_SHADER] is built on top of, +which dictates the language used to program the shader. + +* ALLEGRO_SHADER_AUTO +* ALLEGRO_SHADER_GLSL - OpenGL Shading Language +* ALLEGRO_SHADER_HLSL - High Level Shader Language (for Direct3D) + +Since: 5.1.0 + +## API: al_create_shader + +Create a shader object. + +The platform argument is one of the [ALLEGRO_SHADER_PLATFORM] values, +and specifies the type of shader object to create, and which language is +used to program the shader. + +The shader platform must be compatible with the type of display that you will +use the shader with. For example, you cannot create and use a HLSL shader on +an OpenGL display, nor a GLSL shader on a Direct3D display. + +The ALLEGRO_SHADER_AUTO value automatically chooses the appropriate platform +for the display currently targeted by the calling thread; there must be such a +display. It will create a GLSL shader for an OpenGL display, and a HLSL shader +for a Direct3D display. + +Returns the shader object on success. Otherwise, returns NULL. + +Since: 5.1.0 + +See also: [al_attach_shader_source], [al_attach_shader_source_file], +[al_build_shader], [al_use_shader], [al_destroy_shader], +[al_get_shader_platform] + +## API: al_attach_shader_source + +Attaches the shader's source code to the shader object and compiles it. Passing +NULL deletes the underlying (OpenGL or DirectX) shader. See also +[al_attach_shader_source_file] if you prefer to obtain your shader source from +an external file. + +If you do not use ALLEGRO_PROGRAMMABLE_PIPELINE Allegro's graphics functions +will not use any shader specific functions themselves. In case of a system +with no fixed function pipeline (like OpenGL ES 2 or OpenGL 3 or 4) this means +Allegro's drawing functions cannot be used. + +TODO: Is ALLEGRO_PROGRAMMABLE_PIPELINE set automatically in this case? + +When ALLEGRO_PROGRAMMABLE_PIPELINE is used the following shader uniforms +are provided by Allegro and can be accessed in your shaders: + +al_projview_matrix +: matrix for Allegro's orthographic projection multiplied by the + [al_use_transform] matrix. The type is `mat4` in GLSL, and `float4x4` in + HLSL. + +al_use_tex +: whether or not to use the bound texture. The type is `bool` in + both GLSL and HLSL. + +al_tex +: the texture if one is bound. The type is `sampler2D` in GLSL and + `texture` in HLSL. + +al_use_tex_matrix +: whether or not to use a texture matrix (used by the primitives addon). + The type is `bool` in both GLSL and HLSL. + +al_tex_matrix +: the texture matrix (used by the primitives addon). Your shader should + multiply the texture coordinates by this matrix. The type is `mat4` in + GLSL, and `float4x4` in HLSL. + +With GLSL alpha testing is done in the shader and uses these additional +uniforms: + +al_alpha_test +: Whether to do any alpha testing. If false, the shader should render the + pixel, otherwise it should interpret the values of `al_alpha_func` and + `al_alpha_test_val`. + +al_alpha_func +: The alpha testing function used. One of the [ALLEGRO_RENDER_FUNCTION] + values. The default is ALLEGRO_RENDER_ALWAYS which means all pixels + (even completely transparent ones) are rendered. The type is `int`. + See [ALLEGRO_RENDER_STATE]. + +al_alpha_test_val +: If alpha testing is not ALLEGRO_RENDER_NEVER or ALLEGRO_RENDER_ALWAYS + the alpha value to compare to for alpha testing. The type is `float`. + +For GLSL shaders the vertex attributes are passed using the following variables: + +al_pos +: vertex position attribute. Type is `vec4`. + +al_texcoord +: vertex texture coordinate attribute. Type is `vec2`. + +al_color +: vertex color attribute. Type is `vec4`. + +al_user_attr_0 +: The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR + +al_user_attr_1, ..., al_user_attr_9 +: The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR + X where X is an integer from 1 to 9 + + +For HLSL shaders the vertex attributes are passed using the following semantics: + +POSITION0 +: vertex position attribute. Type is `float4`. + +TEXCOORD0 +: vertex texture coordinate attribute. Type is `float2`. + +TEXCOORD1 +: vertex color attribute. Type is `float4`. + +Also, each shader variable has a corresponding macro name that can be used when +defining the shaders using string literals. Don't use these macros with the +other shader functions as that will lead to undefined behavior. + +* ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX for "al_projview_matrix" +* ALLEGRO_SHADER_VAR_POS for "al_pos" +* ALLEGRO_SHADER_VAR_COLOR for "al_color" +* ALLEGRO_SHADER_VAR_TEXCOORD for "al_texcoord" +* ALLEGRO_SHADER_VAR_USE_TEX for "al_use_tex" +* ALLEGRO_SHADER_VAR_TEX for "al_tex" +* ALLEGRO_SHADER_VAR_USE_TEX_MATRIX for "al_use_tex_matrix" +* ALLEGRO_SHADER_VAR_TEX_MATRIX for "al_tex_matrix" +* ALLEGRO_SHADER_VAR_ALPHA_FUNCTION for "al_alpha_func" +* ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE for "al_alpha_test_val" + +Examine the output of [al_get_default_shader_source] for an example of how to +use the above uniforms and attributes. + +Returns true on success and false on error, in which case the error log is +updated. The error log can be retrieved with [al_get_shader_log]. + +Since: 5.1.0 + +See also: [al_attach_shader_source_file], [al_build_shader], +[al_get_default_shader_source], [al_get_shader_log], [ALLEGRO_PRIM_ATTR] + +## API: al_attach_shader_source_file + +Like [al_attach_shader_source] but reads the source code for the shader from +the named file. + +Returns true on success and false on error, in which case the error log is +updated. The error log can be retrieved with [al_get_shader_log]. + +Since: 5.1.0 + +See also: [al_attach_shader_source], [al_build_shader], [al_get_shader_log] + +## API: al_build_shader + +This is required before the shader can be used with [al_use_shader]. It should +be called after successfully attaching the pixel and/or vertex shaders with +[al_attach_shader_source] or [al_attach_shader_source_file]. + +Returns true on success and false on error, in which case the error log is +updated. The error log can be retrieved with [al_get_shader_log]. + +> *Note:* If you are using the ALLEGRO_PROGRAMMABLE_PIPELINE flag, then you +must specify both a pixel and a vertex shader sources for anything to be +rendered. + +Since: 5.1.6 + +See also: [al_use_shader], [al_get_shader_log] + +## API: al_get_shader_log + +Return a read-only string containing the information log for a shader program. +The log is updated by certain functions, such as [al_attach_shader_source] +or [al_build_shader] when there is an error. + +This function never returns NULL. + +Since: 5.1.0 + +See also: [al_attach_shader_source], [al_attach_shader_source_file], +[al_build_shader] + +## API: al_get_shader_platform + +Returns the platform the shader was created with (either +ALLEGRO_SHADER_HLSL or ALLEGRO_SHADER_GLSL). + +Since: 5.1.6 + +See also: [al_create_shader] + +## API: al_use_shader + +Uses the shader for subsequent drawing operations on the current target +bitmap. Pass NULL to stop using any shader on the current target bitmap. + +Returns true on success. Otherwise returns false, e.g. because the shader +is incompatible with the target bitmap. + +Since: 5.1.6 + +See also: [al_destroy_shader], [al_set_shader_sampler], [al_set_shader_matrix], +[al_set_shader_int], [al_set_shader_float], [al_set_shader_bool], +[al_set_shader_int_vector], [al_set_shader_float_vector] + +## API: al_destroy_shader + +Destroy a shader. Any bitmaps which currently use the shader will implicitly +stop using the shader. In multi-threaded programs, be careful that no such +bitmaps are being accessed by other threads at the time. + +As a convenience, if the target bitmap of the calling thread is using the +shader then the shader is implicitly unused before being destroyed. + +This function does nothing if the shader argument is NULL. + +Since: 5.1.0 + +See also: [al_create_shader] + +## API: al_set_shader_sampler + +Sets a texture sampler uniform and texture unit of the current target bitmap's +shader. The given bitmap must be a video bitmap. + +Different samplers should use different units. The bitmap passed to Allegro's +drawing functions uses the 0th unit, so if you're planning on using the +`al_tex` variable in your pixel shader as well as another sampler, set the +other sampler to use a unit different from 0. With the primitives addon, it is +possible to free up the 0th unit by passing `NULL` as the texture argument to +the relevant drawing functions. In this case, you may set a sampler to use the +0th unit and thus not use `al_tex` (the `al_use_tex` variable will be set to +`false`). + +Returns true on success. Otherwise returns false, e.g. if the uniform by that +name does not exist in the shader. + +Since: 5.1.0 + +See also: [al_use_shader] + +## API: al_set_shader_matrix + +Sets a matrix uniform of the current target bitmap's shader. + +Returns true on success. Otherwise returns false, e.g. if the uniform by that +name does not exist in the shader. + +Since: 5.1.0 + +See also: [al_use_shader] + +## API: al_set_shader_int + +Sets an integer uniform of the current target bitmap's shader. + +Returns true on success. Otherwise returns false, e.g. if the uniform by that +name does not exist in the shader. + +Since: 5.1.0 + +See also: [al_use_shader] + +## API: al_set_shader_float + +Sets a float uniform of the target bitmap's shader. + +Returns true on success. Otherwise returns false, e.g. if the uniform by that +name does not exist in the shader. + +Since: 5.1.0 + +See also: [al_use_shader] + +## API: al_set_shader_bool + +Sets a boolean uniform of the target bitmap's shader. + +Returns true on success. Otherwise returns false, e.g. if the uniform by that +name does not exist in the shader. + +Since: 5.1.6 + +See also: [al_use_shader] + +## API: al_set_shader_int_vector + +Sets an integer vector array uniform of the current target bitmap's shader. The +'num_components' parameter can take one of the values 1, 2, 3 or 4. If it is 1 +then an array of 'num_elems' integer elements is added. Otherwise each added +array element is assumed to be a vector with 2, 3 or 4 components in it. + +For example, if you have a GLSL uniform declared as `uniform ivec3 flowers[4]` +or an HLSL uniform declared as `uniform int3 flowers[4]`, then you'd use this +function from your code like so: + +~~~~c +int flowers[4][3] = +{ + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9}, + {2, 5, 7} +}; + +al_set_shader_int_vector("flowers", 3, (int*)flowers, 4); +~~~~ + +Returns true on success. Otherwise returns false, e.g. if the uniform by that +name does not exist in the shader. + +Since: 5.1.0 + +See also: [al_set_shader_float_vector], [al_use_shader] + +## API: al_set_shader_float_vector + +Same as [al_set_shader_int_vector] except all values are float instead of int. + +Since: 5.1.0 + +See also: [al_set_shader_int_vector], [al_use_shader] + +## API: al_get_default_shader_source + +Returns a string containing the source code to Allegro's default vertex or pixel +shader appropriate for the passed platform. The ALLEGRO_SHADER_AUTO value means +GLSL is used if OpenGL is being used otherwise HLSL. ALLEGRO_SHADER_AUTO +requires that there is a current display set on the calling thread. This +function can return NULL if Allegro was built without support for shaders of the +selected platform. + +Since: 5.1.6 + +See also: [al_attach_shader_source] diff --git a/allegro/docs/src/refman/state.txt b/allegro/docs/src/refman/state.txt new file mode 100644 index 00000000..7bda0192 --- /dev/null +++ b/allegro/docs/src/refman/state.txt @@ -0,0 +1,80 @@ +# State + +These functions are declared in the main Allegro header file: + + #include + +## API: ALLEGRO_STATE + +Opaque type which is passed to [al_store_state]/[al_restore_state]. + +The various state kept internally by Allegro can be displayed like this: + + global + active system driver + current config + per thread + new bitmap params + new display params + active file interface + errno + current blending mode + current display + deferred drawing + current target bitmap + current transformation + current projection transformation + current clipping rectangle + bitmap locking + current shader + +In general, the only real global state is the active system driver. All +other global state is per-thread, so if your application has multiple +separate threads they never will interfere with each other. (Except if +there are objects accessed by multiple threads of course. Usually you +want to minimize that though and for the remaining cases use +synchronization primitives described in the threads section or events +described in the events section to control inter-thread communication.) + +## API: ALLEGRO_STATE_FLAGS + +Flags which can be passed to [al_store_state]/[al_restore_state] as bit +combinations. See [al_store_state] for the list of flags. + +## API: al_restore_state + +Restores part of the state of the current thread from the given +[ALLEGRO_STATE] object. + +See also: [al_store_state], [ALLEGRO_STATE_FLAGS] + +## API: al_store_state + +Stores part of the state of the current thread in the given [ALLEGRO_STATE] +object. The flags parameter can take any bit-combination of these flags: + +* ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS - new_display_format, + new_display_refresh_rate, new_display_flags +* ALLEGRO_STATE_NEW_BITMAP_PARAMETERS - new_bitmap_format, new_bitmap_flags +* ALLEGRO_STATE_DISPLAY - current_display +* ALLEGRO_STATE_TARGET_BITMAP - target_bitmap +* ALLEGRO_STATE_BLENDER - blender +* ALLEGRO_STATE_TRANSFORM - current_transformation +* ALLEGRO_STATE_PROJECTION_TRANSFORM - current_projection_transformation +* ALLEGRO_STATE_NEW_FILE_INTERFACE - new_file_interface +* ALLEGRO_STATE_BITMAP - same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS and + ALLEGRO_STATE_TARGET_BITMAP +* ALLEGRO_STATE_ALL - all of the above + +See also: [al_restore_state], [ALLEGRO_STATE] + +## API: al_get_errno + +Some Allegro functions will set an error number as well as returning an +error code. Call this function to retrieve the last error number set +for the calling thread. + +## API: al_set_errno + +Set the error number for the calling thread. + diff --git a/allegro/docs/src/refman/system.txt b/allegro/docs/src/refman/system.txt new file mode 100644 index 00000000..2cb79deb --- /dev/null +++ b/allegro/docs/src/refman/system.txt @@ -0,0 +1,315 @@ +# System routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: al_install_system + +Initialize the Allegro system. No other Allegro functions can be called +before this (with one or two exceptions). + +The version field should always be set to ALLEGRO_VERSION_INT. + +If atexit_ptr is non-NULL, and if hasn't been done already, +[al_uninstall_system] will be registered as an atexit +function. + +Returns true if Allegro was successfully initialized by this function +call (or already was initialized previously), false if Allegro cannot +be used. A common reason for this function to fail is when the version of +Allegro you compiled your game against is not compatible with the version of +the shared libraries that were found on the system. + +The version compatibility check works as follows. Let A = xa.ya.za.* be the +version of Allegro you compiled with, and B = xb.yb.zb.* be the version of +Allegro found in the system shared library. + +If you defined `ALLEGRO_UNSTABLE` before including Allegro headers, then +version A is compatible with B only if xa.ya.za = xb.yb.zb. Otherwise, A is +compatible with B only if xa.ya = xb.yb. + +See also: [al_init] + +## API: al_init + +Like [al_install_system], but automatically passes in the version and uses the +atexit function visible in the current binary. + +> Note: It is typically wrong to call al_init anywhere except the final game +binary. In particular, do not call it inside a shared library unless you know +what you're doing. In those cases, it is better to call al_install_system +either with a `NULL` atexit_ptr, or with a pointer to atexit provided by the +user of this shared library. + +See also: [al_install_system] + +## API: al_uninstall_system + +Closes down the Allegro system. + +> Note: al_uninstall_system() can be called without a corresponding +[al_install_system] call, e.g. from atexit(). + +## API: al_is_system_installed + +Returns true if Allegro is initialized, otherwise returns false. + +## API: al_get_allegro_version + +Returns the (compiled) version of the Allegro library, packed into a single +integer as groups of 8 bits in the form +`(major << 24) | (minor << 16) | (revision << 8) | release`. + +You can use code like this to extract them: + +~~~~c +uint32_t version = al_get_allegro_version(); +int major = version >> 24; +int minor = (version >> 16) & 255; +int revision = (version >> 8) & 255; +int release = version & 255; +~~~~ + +The `release` number is 0 for an unofficial version and 1 or greater for +an official release. For example "5.0.2[1]" would be the (first) official +5.0.2 release while "5.0.2[0]" would be a compile of a version from the +"5.0.2" branch before the official release. + +## API: al_get_standard_path + +Gets a system path, depending on the `id` parameter. Some of these paths +may be affected by the organization and application name, so be sure to +set those before calling this function. + +The paths are not guaranteed to be unique (e.g., SETTINGS and DATA may be +the same on some platforms), so you should be sure your filenames are unique +if you need to avoid naming collisions. Also, a returned path may not actually +exist on the file system. + +ALLEGRO_RESOURCES_PATH +: If you bundle data in a location relative to your executable, then you + should use this path to locate that data. On most platforms, this is the + directory that contains the executable file. + + If called from an OS X app bundle, then this will point to the internal + resource directory (/Contents/Resources). To maintain + consistency, if you put your resources into a directory called "data" + beneath the executable on some other platform (like Windows), then + you should also create a directory called "data" under the OS X app + bundle's resource folder. + + You should not try to write to this path, as it is very likely read-only. + + If you install your resources in some other system directory (e.g., in + /usr/share or C:\\ProgramData), then you are responsible for keeping track + of that yourself. + +ALLEGRO_TEMP_PATH +: Path to the directory for temporary files. + +ALLEGRO_USER_HOME_PATH +: This is the user's home directory. You should not normally write files into + this directory directly, or create any sub folders in it, without explicit + permission from the user. One practical application of this path + would be to use it as the starting place of a file selector in a GUI. + +ALLEGRO_USER_DOCUMENTS_PATH +: This location is easily accessible by the user, and is the place + to store documents and files that the user might want to later open with + an external program or transfer to another place. + + You should not save files here unless the user expects it, usually by + explicit permission. + +ALLEGRO_USER_DATA_PATH +: If your program saves any data that the user doesn't need to access + externally, then you should place it here. This is generally the least + intrusive place to store data. This path will usually not be present on the + file system, so make sure to create it before writing to it. + +ALLEGRO_USER_SETTINGS_PATH +: If you are saving configuration files (especially if the user may want to + edit them outside of your program), then you should place them here. This + path will usually not be present on the file system, so make sure to create + it before writing to it. + +ALLEGRO_EXENAME_PATH +: The full path to the executable. + +Returns NULL on failure. The returned path should be freed with +[al_destroy_path]. + +See also: [al_set_app_name], [al_set_org_name], [al_destroy_path], [al_set_exe_name] + +## API: al_set_exe_name + +This override the executable name used by [al_get_standard_path] for +ALLEGRO_EXENAME_PATH and ALLEGRO_RESOURCES_PATH. + +One possibility where changing this can be useful is if you use the +Python wrapper. Allegro would then by default think that the system's +Python executable is the current executable - but you can set it to +the .py file being executed instead. + +Since: 5.0.6, 5.1.0 + +See also: [al_get_standard_path] + +## API: al_set_app_name + +Sets the global application name. + +The application name is used by [al_get_standard_path] to build the full path to +an application's files. + +This function may be called before [al_init] or [al_install_system]. + +See also: [al_get_app_name], [al_set_org_name] + +## API: al_set_org_name + +Sets the global organization name. + +The organization name is used by [al_get_standard_path] to build the full path to +an application's files. + +This function may be called before [al_init] or [al_install_system]. + +See also: [al_get_org_name], [al_set_app_name] + +## API: al_get_app_name + +Returns the global application name string. + +See also: [al_set_app_name] + +## API: al_get_org_name + +Returns the global organization name string. + +See also: [al_set_org_name] + +## API: al_get_system_config + +Returns the system configuration structure. The returned configuration should +not be destroyed with [al_destroy_config]. This is mainly used for configuring +Allegro and its addons. You may populate this configuration before Allegro is +installed to control things like the logging levels and other features. + +Allegro will try to populate this configuration by loading a configuration file +from a few different locations, in this order: + +- *Unix only:* /etc/allegro5rc + +- *Unix only:* $HOME/allegro5rc + +- *Unix only:* $HOME/.allegro5rc + +- allegro5.cfg next to the executable + +If multiple copies are found, then they are merged using [al_merge_config_into]. + +The contents of this file are documented inside a prototypical `allegro5.cfg` +that you can find in the root directory of the source distributions of Allegro. +They are also reproduced below. + +Note that Allegro will not look into that file unless you make a copy of it and +place it next to your executable! + +~~~~ini +__ALLEGRO_5_CFG +~~~~ + +## API: al_get_system_id + +Returns the platform that Allegro is running on. + +Since: 5.2.5 + +See also: [ALLEGRO_SYSTEM_ID] + +## API: al_register_assert_handler + +Register a function to be called when an internal Allegro assertion fails. +Pass NULL to reset to the default behaviour, which is to do whatever the +standard `assert()` macro does. + +Since: 5.0.6, 5.1.0 + +## API: al_register_trace_handler + +Register a callback which is called whenever Allegro writes something to its +log files. The default logging to allegro.log is disabled while this callback +is active. Pass NULL to revert to the default logging. + +This function may be called prior to al_install_system. + +See the example allegro5.cfg for documentation on how to configure the used +debug channels, logging levels and trace format. + +Since: 5.1.5 + +## API: al_get_cpu_count + +Returns the number of CPU cores that the system Allegro is running on +has and which could be detected, or a negative number if detection failed. +Even if a positive number is returned, it might be that it is not correct. +For example, Allegro running on a virtual machine will return the amount of +CPU's of the VM, and not that of the underlying system. + +Furthermore even if the number is correct, this only gives you information about +the total CPU cores of the system Allegro runs on. The amount of cores available +to your program may be less due to circumstances such as programs that are +currently running. + + +Therefore, it's best to use this for advisory purposes only. It is certainly a +bad idea to make your program exclusive to systems for which this function +returns a certain "desirable" number. + +This function may be called prior to [al_install_system] or [al_init]. + +Since: 5.1.12 + +## API: al_get_ram_size + +Returns the size in MB of the random access memory that the system Allegro is +running on has and which could be detected, or a negative number if detection +failed. Even if a positive number is returned, it might be that it is not +correct. For example, Allegro running on a virtual machine will return +the amount of RAM of the VM, and not that of the underlying system. + +Furthermore even if the number is correct, this only gives you information about +the total physical memory of the system Allegro runs on. The memory available +to your program may be less or more than what this function returns due to +circumstances such as virtual memory, and other programs that are currently +running. + +Therefore, it's best to use this for advisory purposes only. It is certainly a +bad idea to make your program exclusive to systems for which this function +returns a certain "desirable" number. + +This function may be called prior to [al_install_system] or [al_init]. + +Since: 5.1.12 + +## API: ALLEGRO_SYSTEM_ID + +The system Allegro is running on. + +* ALLEGRO_SYSTEM_ID_UNKNOWN - Unknown system. +* ALLEGRO_SYSTEM_ID_XGLX - Xglx +* ALLEGRO_SYSTEM_ID_WINDOWS - Windows +* ALLEGRO_SYSTEM_ID_MACOSX - macOS +* ALLEGRO_SYSTEM_ID_ANDROID - Android +* ALLEGRO_SYSTEM_ID_IPHONE - iOS +* ALLEGRO_SYSTEM_ID_GP2XWIZ - GP2XWIZ +* ALLEGRO_SYSTEM_ID_RASPBERRYPI - Raspberry Pi +* ALLEGRO_SYSTEM_ID_SDL - SDL + +Since: 5.2.5 + +See also: [al_get_system_id] diff --git a/allegro/docs/src/refman/threads.txt b/allegro/docs/src/refman/threads.txt new file mode 100644 index 00000000..05e5fc7e --- /dev/null +++ b/allegro/docs/src/refman/threads.txt @@ -0,0 +1,271 @@ +# Threads + +Allegro includes a simple cross-platform threading interface. +It is a thin layer on top of two threading APIs: Windows threads +and POSIX Threads (pthreads). Enforcing a consistent semantics on all +platforms would be difficult at best, hence the behaviour of the following +functions will differ subtly on different platforms (more so than usual). +Your best bet is to be aware of this and code to the intersection of the +semantics and avoid edge cases. + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + + +## API: ALLEGRO_THREAD + +An opaque structure representing a thread. + + + +## API: ALLEGRO_MUTEX + +An opaque structure representing a mutex. + + + +## API: ALLEGRO_COND + +An opaque structure representing a condition variable. + + + +## API: al_create_thread + +Spawn a new thread which begins executing `proc`. The new thread is passed +its own thread handle and the value `arg`. + +Returns a pointer to the thread on success. +Otherwise, returns NULL if there was an error. + +See also: [al_start_thread], [al_join_thread]. + + + + +## API: al_create_thread_with_stacksize + +Spawn a new thread with the give stacksize in bytes which begins executing +`proc`. The new thread is passed its own thread handle and the value `arg`. + +Returns a pointer to the thread on success. +Otherwise, returns NULL if there was an error. + +Since: 5.2.5 + +> *[Unstable API]:* New API, may want a better way to specify thread options. + +See also: [al_start_thread], [al_join_thread]. + + + +## API: al_start_thread + +When a thread is created, it is initially in a suspended state. +Calling [al_start_thread] will start its actual execution. + +Starting a thread which has already been started does nothing. + +See also: [al_create_thread]. + + + +## API: al_join_thread + +Wait for the thread to finish executing. This implicitly calls +[al_set_thread_should_stop] first. + +If `ret_value` is non-`NULL`, the value returned by the thread function +will be stored at the location pointed to by `ret_value`. + +See also: [al_set_thread_should_stop], [al_get_thread_should_stop], +[al_destroy_thread]. + + + +## API: al_set_thread_should_stop + +Set the flag to indicate `thread` should stop. Returns immediately. + +See also: [al_join_thread], [al_get_thread_should_stop]. + + + +## API: al_get_thread_should_stop + +Check if another thread is waiting for `thread` to stop. Threads which run +in a loop should check this periodically and act on it when convenient. + +Returns true if another thread has called [al_join_thread] or +[al_set_thread_should_stop] on this thread. + +See also: [al_join_thread], [al_set_thread_should_stop]. + +> *Note:* +We don't support forceful killing of threads. + + + +## API: al_destroy_thread + +Free the resources used by a thread. Implicitly performs [al_join_thread] +on the thread if it hasn't been done already. + +Does nothing if `thread` is NULL. + +See also: [al_join_thread]. + + +## API: al_run_detached_thread + +Runs the passed function in its own thread, with `arg` passed to it as only +parameter. This is similar to calling [al_create_thread], [al_start_thread] +and (after the thread has finished) [al_destroy_thread] - but you don't have +the possibility of ever calling [al_join_thread] on the thread. + + +## API: al_create_mutex + +Create the mutex object (a mutual exclusion device). The mutex may or +may not support "recursive" locking. + +Returns the mutex on success or `NULL` on error. + +See also: [al_create_mutex_recursive]. + + + +## API: al_create_mutex_recursive + +Create the mutex object (a mutual exclusion device), with support for +"recursive" locking. That is, the mutex will count the number of times it +has been locked by the same thread. If the caller tries to acquire a lock +on the mutex when it already holds the lock then the count is incremented. +The mutex is only unlocked when the thread releases the lock on the mutex an +equal number of times, i.e. the count drops down to zero. + +See also: [al_create_mutex]. + + + +## API: al_lock_mutex + +Acquire the lock on `mutex`. If the mutex is already locked by another +thread, the call will block until the mutex becomes available and locked. + +If the mutex is already locked by the calling thread, then the behaviour +depends on whether the mutex was created with [al_create_mutex] or +[al_create_mutex_recursive]. In the former case, the behaviour is undefined; +the most likely behaviour is deadlock. In the latter case, the count in the +mutex will be incremented and the call will return immediately. + +See also: [al_unlock_mutex]. + +**We don't yet have al_mutex_trylock.** + + + +## API: al_unlock_mutex + +Release the lock on `mutex` if the calling thread holds the lock on it. + +If the calling thread doesn't hold the lock, or if the mutex is not locked, +undefined behaviour results. + +See also: [al_lock_mutex]. + + + +## API: al_destroy_mutex + +Free the resources used by the mutex. The mutex should be unlocked. +Destroying a locked mutex results in undefined behaviour. + +Does nothing if `mutex` is `NULL`. + + + +## API: al_create_cond + +Create a condition variable. + +Returns the condition value on success or `NULL` on error. + + + +## API: al_destroy_cond + +Destroy a condition variable. + +Destroying a condition variable which has threads block on it results in +undefined behaviour. + +Does nothing if `cond` is `NULL`. + + + +## API: al_wait_cond + +On entering this function, `mutex` must be locked by the calling thread. +The function will atomically release `mutex` and block on `cond`. The +function will return when `cond` is "signalled", acquiring the lock on the +mutex in the process. + +Example of proper use: + +~~~~c +al_lock_mutex(mutex); +while (something_not_true) { + al_wait_cond(cond, mutex); +} +do_something(); +al_unlock_mutex(mutex); +~~~~ + +The mutex should be locked before checking the condition, and should be +rechecked [al_wait_cond] returns. [al_wait_cond] can return for other +reasons than the condition becoming true (e.g. the process was signalled). +If multiple threads are blocked on the condition variable, the condition may +no longer be true by the time the second and later threads are unblocked. +Remember not to unlock the mutex prematurely. + +See also: [al_wait_cond_until], [al_broadcast_cond], [al_signal_cond]. + + + +## API: al_wait_cond_until + +Like [al_wait_cond] but the call can return if the absolute time passes +`timeout` before the condition is signalled. + +Returns zero on success, non-zero if the call timed out. + +See also: [al_wait_cond] + + + +## API: al_broadcast_cond + +Unblock all threads currently waiting on a condition variable. That is, +broadcast that some condition which those threads were waiting for has +become true. + +See also: [al_signal_cond]. + +> *Note:* +The pthreads spec says to lock the mutex associated with `cond` before +signalling for predictable scheduling behaviour. + + + +## API: al_signal_cond + +Unblock at least one thread waiting on a condition variable. + +Generally you should use [al_broadcast_cond] but [al_signal_cond] may be +more efficient when it's applicable. + +See also: [al_broadcast_cond]. diff --git a/allegro/docs/src/refman/time.txt b/allegro/docs/src/refman/time.txt new file mode 100644 index 00000000..ab55a399 --- /dev/null +++ b/allegro/docs/src/refman/time.txt @@ -0,0 +1,43 @@ +# Time routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_TIMEOUT + +Represent a timeout value. The size of the structure is known so it can be +statically allocated. The contents are private. + +See also: [al_init_timeout] + +## API: al_get_time + +Return the number of seconds since the Allegro library was +initialised. The return value is undefined if Allegro is uninitialised. +The resolution depends on the used driver, but typically can be in the +order of microseconds. + +## API: al_init_timeout + +Set timeout value of some number of seconds after the function call. + +For compatibility with all platforms, `seconds` must be 2,147,483.647 seconds or less. + +See also: [ALLEGRO_TIMEOUT], [al_wait_for_event_until] + +## API: al_rest + +Waits for the specified number of seconds. This tells the system to pause +the current thread for the given amount of time. With some operating +systems, the accuracy can be in the order of 10ms. That is, even + +~~~~c +al_rest(0.000001) +~~~~ + +might pause for something like 10ms. Also see the section on Timer routines +for easier ways to time your program without using up all CPU. + diff --git a/allegro/docs/src/refman/timer.txt b/allegro/docs/src/refman/timer.txt new file mode 100644 index 00000000..8ab6291b --- /dev/null +++ b/allegro/docs/src/refman/timer.txt @@ -0,0 +1,128 @@ +# Timer routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_TIMER + +This is an abstract data type representing a timer object. + +## API: ALLEGRO_USECS_TO_SECS + +Convert microseconds to seconds. + +## API: ALLEGRO_MSECS_TO_SECS + +Convert milliseconds to seconds. + +## API: ALLEGRO_BPS_TO_SECS + +Convert beats per second to seconds. + +## API: ALLEGRO_BPM_TO_SECS + +Convert beats per minute to seconds. + +## API: al_create_timer + +Allocates and initializes a timer. If successful, a pointer to a new timer +object is returned, otherwise NULL is returned. *speed_secs* is in seconds per +"tick", and must be positive. The new timer is initially stopped. + +Usage note: typical granularity is on the order of microseconds, but with +some drivers might only be milliseconds. + +See also: [al_start_timer], [al_destroy_timer] + +## API: al_start_timer + +Start the timer specified. From then, the timer's counter will increment +at a constant rate, and it will begin generating events. Starting a +timer that is already started does nothing. Starting a timer that was stopped +will reset the timer's counter, effectively restarting the timer from the +beginning. + +See also: [al_stop_timer], [al_get_timer_started], [al_resume_timer] + +## API: al_resume_timer + +Resume the timer specified. From then, the timer's counter will increment +at a constant rate, and it will begin generating events. Resuming a +timer that is already started does nothing. Resuming a stopped timer will not +reset the timer's counter (unlike al_start_timer). + +See also: [al_start_timer], [al_stop_timer], [al_get_timer_started] + +## API: al_stop_timer + +Stop the timer specified. The timer's counter will stop incrementing and +it will stop generating events. Stopping a timer that is already stopped +does nothing. + +See also: [al_start_timer], [al_get_timer_started], [al_resume_timer] + +## API: al_get_timer_started + +Return true if the timer specified is currently started. + +## API: al_destroy_timer + +Uninstall the timer specified. If the timer is started, it will +automatically be stopped before uninstallation. It will also +automatically unregister the timer with any event queues. + +Does nothing if passed the NULL pointer. + +See also: [al_create_timer] + +## API: al_get_timer_count + +Return the timer's counter value. The timer can be started or stopped. + +See also: [al_set_timer_count] + +## API: al_set_timer_count + +Set the timer's counter value. The timer can be started or stopped. +The count value may be positive or negative, but will always be incremented +by +1 at each tick. + +See also: [al_get_timer_count], [al_add_timer_count] + +## API: al_add_timer_count + +Add *diff* to the timer's counter value. This is similar to writing: + +~~~~c +al_set_timer_count(timer, al_get_timer_count(timer) + diff); +~~~~ + +except that the addition is performed atomically, so no ticks will be lost. + +See also: [al_set_timer_count] + +## API: al_get_timer_speed + +Return the timer's speed, in seconds. (The same value passed to +[al_create_timer] or [al_set_timer_speed].) + +See also: [al_set_timer_speed] + +## API: al_set_timer_speed + +Set the timer's speed, i.e. the rate at which its counter will be +incremented when it is started. This can be done when the timer is +started or stopped. If the timer is currently running, it is made to +look as though the speed change occurred precisely at the last tick. + +*speed_secs* has exactly the same meaning as with [al_create_timer]. + +See also: [al_get_timer_speed] + +## API: al_get_timer_event_source + +Retrieve the associated event source. Timers will generate events of +type [ALLEGRO_EVENT_TIMER]. diff --git a/allegro/docs/src/refman/title.txt b/allegro/docs/src/refman/title.txt new file mode 100644 index 00000000..b049cb9d --- /dev/null +++ b/allegro/docs/src/refman/title.txt @@ -0,0 +1 @@ +% Allegro 5 reference manual diff --git a/allegro/docs/src/refman/touch.txt b/allegro/docs/src/refman/touch.txt new file mode 100644 index 00000000..950a25b4 --- /dev/null +++ b/allegro/docs/src/refman/touch.txt @@ -0,0 +1,149 @@ +# Touch input + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## API: ALLEGRO_TOUCH_INPUT + +An abstract data type representing a physical touch screen or touch pad. + +Since: 5.1.0 + +## API: ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT + +The maximum amount of simultaneous touches that can be detected. + +Since: 5.1.0 + +## API: ALLEGRO_TOUCH_STATE + +This is a structure that is used to hold a "snapshot" of a touch at +a particular instant. + +Public fields (read only): + +* id - identifier of the touch. If the touch is valid, this is positive. +* x - touch x position +* y - touch y position +* dx - touch relative x position +* dy - touch relative y position +* primary - TRUE if this touch is the primary one (usually the first one). +* display - The [ALLEGRO_DISPLAY] that was touched. + +Since: 5.1.0 + +## API: ALLEGRO_TOUCH_INPUT_STATE + +This is a structure that holds a snapshot of all simultaneous touches at a +particular instant. + +Public fields (read only): + +* touches - an array of [ALLEGRO_TOUCH_STATE] + +Since: 5.1.0 + +## API: ALLEGRO_MOUSE_EMULATION_MODE + +Type of mouse emulation to apply. + +ALLEGRO_MOUSE_EMULATION_NONE +: Disables mouse emulation. + +ALLEGRO_MOUSE_EMULATION_TRANSPARENT +: Enables transparent mouse emulation. + +ALLEGRO_MOUSE_EMULATION_INCLUSIVE +: Enable inclusive mouse emulation. + +ALLEGRO_MOUSE_EMULATION_EXCLUSIVE +: Enables exclusive mouse emulation. + +ALLEGRO_MOUSE_EMULATION_5_0_x +: Enables mouse emulation that is backwards compatible with Allegro 5.0.x. + +Since: 5.1.0 + +> *[Unstable API]:* Seems of limited value, as touch input tends to have different +semantics compared to mouse input. + +## API: al_install_touch_input + +Install a touch input driver, returning true if successful. If a +touch input driver was already installed, returns true immediately. + +Since: 5.1.0 + +See also: [al_uninstall_touch_input] + +## API: al_uninstall_touch_input + +Uninstalls the active touch input driver. If no touch input driver was active, +this function does nothing. + +This function is automatically called when Allegro is shut down. + +Since: 5.1.0 + +See also: [al_install_touch_input] + +## API: al_is_touch_input_installed + +Returns true if [al_install_touch_input] was called successfully. + +Since: 5.1.0 + +## API: al_get_touch_input_state + +Gets the current touch input state. The touch information is copied into the +[ALLEGRO_TOUCH_INPUT_STATE] you provide to this function. + +Since: 5.1.0 + +## API: al_set_mouse_emulation_mode + +Sets the kind of mouse emulation for the touch input subsystem to perform. + +Since: 5.1.0 + +> *[Unstable API]:* Seems of limited value, as touch input tends to have different +semantics compared to mouse input. + +See also: [ALLEGRO_MOUSE_EMULATION_MODE], [al_get_mouse_emulation_mode]. + +## API: al_get_mouse_emulation_mode + +Returns the kind of mouse emulation which the touch input subsystem is +set to perform. + +Since: 5.1.0 + +> *[Unstable API]:* Seems of limited value, as touch input tends to have different +semantics compared to mouse input. + +See also: [ALLEGRO_MOUSE_EMULATION_MODE], [al_set_mouse_emulation_mode]. + +## API: al_get_touch_input_event_source + +Returns the global touch input event source. This event source generates +[touch input events][ALLEGRO_EVENT_TOUCH_BEGIN]. + +Since: 5.1.0 + +See also: [ALLEGRO_EVENT_SOURCE], [al_register_event_source] + +## API: al_get_touch_input_mouse_emulation_event_source + +Returns the global touch input event source for emulated mouse events. +This event source generates [emulated mouse events][ALLEGRO_EVENT_MOUSE_AXES] +that are based on touch events. + +See also: [ALLEGRO_EVENT_SOURCE], [al_register_event_source] + +Since: 5.1.0 + +> *[Unstable API]:* Seems of limited value, as touch input tends to have different +semantics compared to mouse input. diff --git a/allegro/docs/src/refman/transformations.txt b/allegro/docs/src/refman/transformations.txt new file mode 100644 index 00000000..39e8e986 --- /dev/null +++ b/allegro/docs/src/refman/transformations.txt @@ -0,0 +1,656 @@ +# Transformations + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +Transformations allow you to transform the coordinates you use for drawing +operations without additional overhead. Scaling, rotating, translating, and +combinations of these are possible as well as using custom transformations. +There are two types of transformations that you can set, 'regular' +transformations and projection transformations. The projection transform is +rarely used in 2D games, but is common in 3D games to set up the projection +from the 3D world to the 2D screen. Typically, you would use the regular +transform for non-projective types of transformations (that is, translations, +rotations, scales, skews... i.e. transformations that are linear), while the +projection transform will be used for setting up perspective and possibly more +advanced effects. It is possible to do everything with just using the +projection transformation (that is, you'd compose the projection transformation +with the non-projection transformations that, e.g., move the camera in the +world), but it is more convenient to use both for two reasons: + +- Regular transformations can be changed while the bitmap drawing is held (see + [al_hold_bitmap_drawing]). + +- Regular transformations work with memory bitmaps. + +As a result, if you're making a 2D game, it's best to leave the projection +transformations at their default values. + +Both types of transformations are set per target-bitmap, i.e. a change of the +target bitmap will also change the active transformation. + +Allegro provides convenience functions to construct transformations in 2D and 3D +variants (the latter with a `_3d` suffix), so you don't have to deal with the +underlying matrix algebra yourself. + +The transformations are combined in the order of the function invocations. Thus +to create a transformation that first rotates a point and then translates it, +you would (starting with an identity transformation) call [al_rotate_transform] +and then [al_translate_transform]. This approach is opposite of what OpenGL uses +but similar to what Direct3D uses. + +For those who know the matrix algebra going behind the scenes, what the +transformation functions in Allegro do is "pre-multiply" the successive +transformations. So, for example, if you have code that does: + +~~~~c +al_identity_transform(&T); + +al_compose_transform(&T, &T1); +al_compose_transform(&T, &T2); +al_compose_transform(&T, &T3); +al_compose_transform(&T, &T4); +~~~~ + +The resultant matrix multiplication expression will look like this: + + T4 * T3 * T2 * T1 + +Since the point coordinate vector term will go on the right of that sequence of +factors, the transformation that is called first, will also be applied first. + +This means if you have code like this: + +~~~~c +al_identity_transform(&T1); +al_scale_transform(&T1, 2, 2); +al_identity_transform(&T2); +al_translate_transform(&T2, 100, 0); + +al_identity_transform(&T); + +al_compose_transform(&T, &T1); +al_compose_transform(&T, &T2); + +al_use_transform(&T); +~~~~ + +it does exactly the same as: + +~~~~c +al_identity_transform(&T); +al_scale_transform(&T, 2, 2); +al_translate_transform(&T, 100, 0); +al_use_transform(&T); +~~~~ + +## API: ALLEGRO_TRANSFORM + +Defines the generic transformation type, a 4x4 matrix. 2D transforms use only +a small subsection of this matrix, namely the top left 2x2 matrix, and the +right most 2x1 matrix, for a total of 6 values. + +*Fields:* + +* m - A 4x4 float matrix + +## API: al_copy_transform + +Makes a copy of a transformation. + +*Parameters:* + +* dest - Source transformation +* src - Destination transformation + +## API: al_use_transform + +Sets the transformation to be used for the the drawing operations on the target +bitmap (each bitmap maintains its own transformation). +Every drawing operation after this call will be transformed using this +transformation. Call this function with an identity transformation to return +to the default behaviour. + +This function does nothing if there is no target bitmap. + +The parameter is passed by reference as an optimization to avoid the overhead of +stack copying. The reference will not be stored in the Allegro library so it is +safe to pass references to local variables. + +~~~~c +void setup_my_transformation(void) +{ + ALLEGRO_TRANSFORM transform; + al_translate_transform(&transform, 5, 10); + al_use_transform(&transform); +} +~~~~ + +*Parameters:* + +* trans - Transformation to use + +See also: [al_get_current_transform], [al_transform_coordinates] + +## API: al_get_current_transform + +Returns the transformation of the current target bitmap, as set by +[al_use_transform]. If there is no target bitmap, this function returns NULL. + +*Returns:* +A pointer to the current transformation. + +See also: [al_get_current_projection_transform] + +## API: al_use_projection_transform + +Sets the projection transformation to be used for the drawing operations on +the target bitmap (each bitmap maintains its own projection transformation). +Every drawing operation after this call will be transformed using this +transformation. To return default behavior, call this function with an +orthographic transform like so: + +~~~~c +ALLEGRO_TRANSFORM trans; +al_identity_transform(&trans); +al_orthographic_transform(&trans, 0, 0, -1.0, al_get_bitmap_width(bitmap), + al_get_bitmap_height(bitmap), 1.0); + +al_set_target_bitmap(bitmap); +al_use_projection_transform(&trans); +~~~~ + +The orthographic transformation above is the default projection transform. + +This function does nothing if there is no target bitmap. This function also +does nothing if the bitmap is a memory bitmap (i.e. memory bitmaps always use +an orthographic transform like the snippet above). Note that the projection +transform will be reset to default if a video bitmap is converted to a memory +bitmap. Additionally, if the bitmap in question is the backbuffer, it's +projection transformation will be reset to default if it is resized. Lastly, +when you draw a memory bitmap to a video bitmap with a custom projection +transform, this transformation will be ignored (i.e. it'll be as if the +projection transform of the target bitmap was temporarily reset to default). + +The parameter is passed by reference as an optimization to avoid the overhead of +stack copying. The reference will not be stored in the Allegro library so it is +safe to pass references to local variables. + +Since: 5.1.9 + +See also: [al_get_current_projection_transform], [al_perspective_transform], [al_orthographic_transform] + +## API: al_get_current_projection_transform + +If there is no target bitmap, this function returns NULL. + +*Returns:* +A pointer to the current transformation. + +Since: 5.1.9 + +See also: [al_use_projection_transform] + +## API: al_get_current_inverse_transform + +Returns the inverse of the current transformation of the target bitmap. +If there is no target bitmap, this function returns NULL. + +This is similar to calling `al_invert_transform(al_get_current_transform())` +but the result of this function is cached. + +> *Note*: Allegro's transformation inversion functions work correctly only +with 2D transformations. + +Since: 5.1.0 + +## API: al_invert_transform + +Inverts the passed transformation. If the transformation is nearly singular +(close to not having an inverse) then the returned transformation may be +invalid. Use [al_check_inverse] to ascertain if the transformation has an +inverse before inverting it if you are in doubt. + +*Parameters:* + +* trans - Transformation to invert + +> *Note*: Allegro's transformation inversion functions work correctly only +with 2D transformations. + +See also: [al_check_inverse] + +## API: al_transpose_transform + +Transposes the matrix of the given transform. This can be used for +inversing a rotation transform. For example: + +~~~~c +al_build_camera_transform(camera, 0, 0, 0, x, y, z, xu, yu, zu) +al_copy_transform(inverse, camera) +al_transpose_transform(camera) +// Now "inverse" will be a transformation rotating in the opposite +// direction from "camera". Note that this only works if the camera +// position is 0/0/0 as in the example. +~~~~ + +Since: 5.2.5 + +## API: al_check_inverse + +Checks if the transformation has an inverse using the supplied tolerance. +Tolerance should be a small value between 0 and 1, with 1e-7 being sufficient +for most applications. + +In this function tolerance specifies how close the determinant can be to +0 (if the determinant is 0, the transformation has no inverse). Thus +the smaller the tolerance you specify, the "worse" transformations will +pass this test. Using a tolerance of 1e-7 will catch errors greater +than 1/1000's of a pixel, but let smaller errors pass. That means that +if you transformed a point by a transformation and then transformed it +again by the inverse transformation that passed this check, the resultant +point should less than 1/1000's of a pixel away from the original point. + +Note that this check is superfluous most of the time if +you never touched the transformation matrix values yourself. The only +thing that would cause the transformation to not have an inverse is if +you applied a 0 (or very small) scale to the transformation or you have +a really large translation. As long as the scale is comfortably above 0, +the transformation will be invertible. + +*Parameters:* + +* trans - Transformation to check +* tol - Tolerance + +*Returns:* +1 if the transformation is invertible, 0 otherwise + +> *Note*: Allegro's transformation inversion functions work correctly only +with 2D transformations. + +See also: [al_invert_transform] + +## API: al_identity_transform + +Sets the transformation to be the identity transformation. This is the default +transformation. Use [al_use_transform] on an identity transformation to return +to the default. + +~~~~c +ALLEGRO_TRANSFORM t; +al_identity_transform(&t); +al_use_transform(&t); +~~~~ + +*Parameters:* + +* trans - Transformation to alter + +See also: [al_translate_transform], [al_rotate_transform], [al_scale_transform] + +## API: al_build_transform + +Builds a transformation given some parameters. This call is equivalent to +calling the transformations in this order: make identity, rotate, scale, +translate. This method is faster, however, than actually calling those +functions. + +*Parameters:* + +* trans - Transformation to alter +* x, y - Translation +* sx, sy - Scale +* theta - Rotation angle in radians + +> *Note*: this function was previously documented to be equivalent to a +different (and more useful) order of operations: identity, scale, rotate, +translate. + +See also: [al_translate_transform], [al_rotate_transform], +[al_scale_transform], [al_compose_transform] + +## API: al_build_camera_transform + +Builds a transformation which can be used to transform 3D coordinates in world +space to camera space. This involves translation and a rotation. The function +expects three coordinate triplets: The camera's position, the position the +camera is looking at and an up vector. The up vector does not need to be of +unit length and also does not need to be perpendicular to the view direction - +it can usually just be the world up direction (most commonly 0/1/0). + +For example: + +~~~~c +al_build_camera_transform(&t, + 1, 1, 1, + 5, 5, 5, + 0, 1, 0); +~~~~ + +This create a transformation for a camera standing at 1/1/1 and looking towards +5/5/5. + +> *Note*: If the *position* and *look* parameters are identical, or if the +*up* direction is parallel to the view direction, an identity matrix is created. + +Another example which will simply re-create the identity matrix: + +~~~~c +al_build_camera_transform(&t, + 0, 0, 0, + 0, 0, -1, + 0, 1, 0); +~~~~ + +An example where the up vector will cause the camera to lean (roll) by 45 +degrees: + +~~~~c +al_build_camera_transform(&t, + 1, 1, 1, + 5, 5, 5, + 1, 1, 0); +~~~~ + +Since 5.1.9 + +See also: [al_translate_transform_3d], [al_rotate_transform_3d], +[al_scale_transform_3d], [al_compose_transform], [al_use_transform] + +## API: al_translate_transform + +Apply a translation to a transformation. + +*Parameters:* + +* trans - Transformation to alter +* x, y - Translation + +See also: [al_rotate_transform], [al_scale_transform], [al_build_transform] + +## API: al_rotate_transform + +Apply a rotation to a transformation. + +*Parameters:* + +* trans - Transformation to alter +* theta - Rotation angle in radians + +See also: [al_translate_transform], [al_scale_transform], [al_build_transform] + +## API: al_scale_transform + +Apply a scale to a transformation. + +*Parameters:* + +* trans - Transformation to alter +* sx, sy - Scale + +See also: [al_translate_transform], [al_rotate_transform], [al_build_transform] + +## API: al_transform_coordinates + +Transform a pair of coordinates. + +*Parameters:* + +* trans - Transformation to use +* x, y - Pointers to the coordinates + +See also: [al_use_transform], [al_transform_coordinates_3d] + +## API: al_transform_coordinates_3d + +Transform x, y, z coordinates. + +*Parameters:* + +* trans - Transformation to use +* x, y, z - Pointers to the coordinates + +Note: If you are using a projection transform you most likely will want +to use [al_transform_coordinates_3d_projective] instead. + +Since 5.1.9 + +See also: [al_use_transform], [al_transform_coordinates] + +## API: al_transform_coordinates_4d + +Transform x, y, z, w coordinates. + +*Parameters:* + +* trans - Transformation to use +* x, y, z, w - Pointers to the coordinates + +Since 5.2.4 + +See also: [al_use_transform], [al_transform_coordinates], [al_transform_coordinates_3d] + +## API: al_transform_coordinates_3d_projective + +Transform x, y, z as homogeneous coordinates. This is the same as using +[al_transform_coordinates_4d] with the w coordinate set to 1, then +dividing x, y, z by the resulting w. This will provide the same +normalized coordinates Allegro will draw to when a projective transform is in +effect as set with [al_use_projection_transform]. To get the actual +pixel coordinates from those translate and scale like so (w and h would +be the pixel dimensions of the target bitmap): + +~~~~c +x = w / 2 + x * w / 2 +y = h / 2 - y * h / 2 +~~~~ + +*Parameters:* + +* trans - Transformation to use +* x, y, z - Pointers to the coordinates + +Example: + +~~~~c +ALLEGRO_TRANSFORM t2; +al_copy_transform(&t2, al_get_current_transform()); +al_compose_transform(&t2, al_get_current_projection_transform()); + +ALLEGRO_TRANSFORM t3; +al_identity_transform(&t3); +al_scale_transform(&t3, 0.5, -0.5); +al_translate_transform(&t3, 0.5, 0.5); +al_scale_transform(&t3, al_get_bitmap_width(al_get_target_bitmap()), + al_get_bitmap_height(al_get_target_bitmap())); + +al_transform_coordinates_3d_projective(&t2, &x, &y, &z); +// x, y now contain normalized coordinates +al_transform_coordinates(&t3, &x, &y); +// x, y now contain pixel coordinates +~~~~ + +Since 5.2.4 + +See also: [al_use_transform], [al_transform_coordinates], [al_transform_coordinates_3d], [al_use_projection_transform] + +## API: al_compose_transform + +Compose (combine) two transformations by a matrix multiplication. + + trans := trans other + +Note that the order of matrix multiplications is important. The effect +of applying the combined transform will be as if first applying `trans` +and then applying `other` and not the other way around. + +*Parameters:* + +* trans - Transformation to alter +* other - Transformation used to transform `trans` + +See also: [al_translate_transform], [al_rotate_transform], [al_scale_transform] + +## API: al_orthographic_transform + +Combines the given transformation with an orthographic transformation which +maps the screen rectangle to the given left/top and right/bottom coordinates. + +near/far is the z range, coordinates outside of that range will get clipped. +Normally -1/1 is fine because all 2D graphics will have a z coordinate of 0. +However if you for example do al_draw_rectangle(0, 0, 100, 100) and rotate +around the x axis ("towards the screen") make sure your z range allows values +from -100 to 100 or the rotated rectangle will get clipped. + +Also, if you are using a depth buffer the z range decides the depth +resolution. For example if you have a 16 bit depth buffer there are only +65536 discrete depth values. So if your near/far is set to -1000000/1000000 +most of the z positions would not result in separate depth values which +could lead to artifacts. + +The result of applying this transformation to coordinates will be to +normalize visible coordinates into the cube from -1/-1/-1 to 1/1/1. Such +a transformation is mostly useful for passing it to +[al_use_projection_transform] - see that function for an example use. + +Since: 5.1.3 + +See also: [al_use_projection_transform], [al_perspective_transform] + +## API: al_perspective_transform + +Like [al_orthographic_transform] but honors perspective. If everything is at +a z-position of -near it will look the same as with an orthographic +transformation. + +To use a specific horizontal field of view you can use the relation: + + tan(hfov / 2) = (right - left) / 2 / near + +and therefore + + near = (right - left) / 2 / tan(hfov / 2) + +Example 1: + +~~~~c + float w = 800, h = 450; // assume our display is 800 x 450 + float fov = tan(90 * ALLEGRO_PI / 180 / 2); // 90 degree field of view + + // Our projection goes from 0/0 to w/h with the near parameter set + // for a 90 degree horizontal viewing angle. + ALLEGRO_TRANSFORM projection; + al_identity_transform(&projection); + al_perspective_transform(&projection, 0, 0, + w / 2 / fov, + w, h, + 2000); + al_use_projection_transform(&projection); + + // Set the camera z to +400 (which is exactly the near distance) + ALLEGRO_TRANSFORM camera; + al_build_camera_transform(&camera, 0, 0, 400, 0, 0, 0, 0, 1, 0); + al_use_transform(&camera); + + // This will draw two rectangles at the left and right edge of the + // screen and vertically centered. The x distance between them is 800 + // units, but the camera transform moves them 400 along z, so with + // a 90° viewing angle both are visible. + al_draw_filled_rectangle(0, 200, 50, 250, red; + al_draw_filled_rectangle(750, 200, 800, 250, red); +~~~~ +Example 2: + +~~~~c + float w = 800, h = 450; // assume our display is 800 x 450 + float fov = tan(90 * ALLEGRO_PI / 180 / 2); // 90 degree field of view + float aspect = h / w; + float zoom = 2; // enlarge x 2 + + // This projection is very different from the one in the first example. + // Here we map the left and right edge of the screen to -1 and +1. And + // the y axis goes from -1 at the bottom to +1 at the top, scaled by + // the aspect ratio. We also add a zoom parameter so we can control + // the visible portion of the scene independent of the field of view. + ALLEGRO_TRANSFORM projection; + al_identity_transform(&projection); + al_perspective_transform(&projection, + -1 / zoom, aspect / zoom, + 1 / fov, + 1 / zoom, -aspect / zoom, + 2000); + al_use_projection_transform(&projection); + + // Moves everything by -4 in the z direction. + ALLEGRO_TRANSFORM camera; + al_build_camera_transform(&camera, 0, 0, 4, 0, 0, 0, 0, 1, 0); + al_use_transform(&camera); + + // At a z distance of 4 with a 90° hfov everything would be scaled + // down to 25%. However we also zoom 2-fold, so the final scaling is + // 50%. This rectangle therefore will appear at a size of 400 x 225 + // pixel (assuming the display is 800 x 450). + al_draw_filled_rectangle(-1, -1, 1, 1, red); +~~~~ + +Since: 5.1.3 + +See also: [al_use_projection_transform], [al_orthographic_transform] + +## API: al_translate_transform_3d + +Combines the given transformation with a transformation which translates +coordinates by the given vector. + +Since: 5.1.3 + +See also: [al_use_projection_transform] + +## API: al_scale_transform_3d + +Combines the given transformation with a transformation which scales +coordinates by the given vector. + +Since: 5.1.3 + +See also: [al_use_projection_transform] + +## API: al_rotate_transform_3d + +Combines the given transformation with a transformation which rotates +coordinates around the given vector by the given angle in radians. + +Note: The vector is assumed to be of unit length (otherwise it will +also incur a scale). + +Since: 5.1.3 + +## API: al_horizontal_shear_transform + +Apply a horizontal shear to the transform + +*Parameters:* + +* trans - Transformation to alter +* theta - Rotation angle in radians + +Since: 5.1.7 + +See also: [al_vertical_shear_transform] + +## API: al_vertical_shear_transform + +Apply a vertical shear to the transform + +*Parameters:* + +* trans - Transformation to alter +* theta - Rotation angle in radians + +Since: 5.1.7 + +See also: [al_horizontal_shear_transform] diff --git a/allegro/docs/src/refman/utf8.txt b/allegro/docs/src/refman/utf8.txt new file mode 100644 index 00000000..b600f024 --- /dev/null +++ b/allegro/docs/src/refman/utf8.txt @@ -0,0 +1,788 @@ +# UTF-8 string routines + +These functions are declared in the main Allegro header file: + +~~~~c + #include +~~~~ + +## About UTF-8 string routines + +Some parts of the Allegro API, such as the font rountines, expect Unicode +strings encoded in UTF-8. The following basic routines are provided to help +you work with UTF-8 strings, however it does *not* mean you need to use them. +You should consider another library (e.g. ICU) if you require more +functionality. + +Briefly, Unicode is a standard consisting of a large character +set of over 100,000 characters, and rules, such as how to sort strings. +A *code point* is the integer value of a character, but not all code points are +characters, as some code points have other uses. Unlike legacy character +sets, the set of code points is open ended and more are assigned with time. + +Clearly it is impossible to represent each code point with a 8-bit byte (limited +to 256 code points) or even a 16-bit integer (limited to 65536 code points). +It is possible to store code points in a 32-bit integers but it is space +inefficient, and not actually that useful (at least, when handling the full +complexity of Unicode; Allegro only does the very basics). +There exist different Unicode Transformation Formats for encoding code points +into smaller *code units*. The most important transformation formats are +UTF-8 and UTF-16. + +UTF-8 is a *variable-length encoding* which encodes each code point to +between one and four 8-bit bytes each. UTF-8 has many nice properties, but +the main advantages are that it is backwards compatible with C strings, and +ASCII characters (code points in the range 0-127) are encoded in UTF-8 +exactly as they would be in ASCII. + +UTF-16 is another variable-length encoding, but encodes each code point to +one or two 16-bit words each. It is, of course, not compatible with +traditional C strings. Allegro does not generally use UTF-16 strings. + +Here is a diagram of the representation of the word "ål", with a NUL +terminator, in both UTF-8 and UTF-16. + + ---------------- ---------------- -------------- + String å l NUL + ---------------- ---------------- -------------- + Code points U+00E5 (229) U+006C (108) U+0000 (0) + ---------------- ---------------- -------------- + UTF-8 bytes 0xC3, 0xA5 0x6C 0x00 + ---------------- ---------------- -------------- + UTF-16LE bytes 0xE5, 0x00 0x6C, 0x00 0x00, 0x00 + ---------------- ---------------- -------------- + +You can see the aforementioned properties of UTF-8. The first code point +U+00E5 ("å") is outside of the ASCII range (0-127) so is encoded to multiple +code units -- it requires two bytes. U+006C ("l") and U+0000 (NUL) both +exist in the ASCII range so take exactly one byte each, as in a pure ASCII +string. A zero byte never appears except to represent the NUL character, so +many functions which expect C-style strings will work with UTF-8 strings +without modification. + +On the other hand, UTF-16 represents each code point by either one or two +16-bit code units (two or four bytes). The representation of each 16-bit +code unit depends on the byte order; here we have demonstrated little endian. + +Both UTF-8 and UTF-16 are self-synchronising. Starting from any offset +within a string, it is efficient to find the beginning of the previous or +next code point. + +Not all sequences of bytes or 16-bit words are valid UTF-8 and UTF-16 strings +respectively. UTF-8 also has an additional problem of overlong forms, where +a code point value is encoded using more bytes than is strictly necessary. +This is invalid and needs to be guarded against. + +In the following "ustr" functions, be careful whether a function takes code +unit (byte) or code point indices. In general, all position parameters are +in code unit offsets. This may be surprising, but if you think about it, it is +required for good performance. (It also means some functions will work even +if they do not contain UTF-8, since they only care about storing bytes, so +you may actually store arbitrary data in the ALLEGRO_USTRs.) + +For actual text processing, where you want to specify positions with code point +indices, you should use [al_ustr_offset] to find the code unit offset position. +However, most of the time you would probably just work with byte offsets. + + +## UTF-8 string types + +### API: ALLEGRO_USTR + +An opaque type representing a string. ALLEGRO_USTRs normally contain UTF-8 +encoded strings, but they may be used to hold any byte sequences, including +NULs. + + +### API: ALLEGRO_USTR_INFO + +A type that holds additional information for an [ALLEGRO_USTR] that references +an external memory buffer. + +See also: [al_ref_cstr], [al_ref_buffer] and [al_ref_ustr]. + + +## Creating and destroying strings + +### API: al_ustr_new + +Create a new string containing a copy of the C-style string `s`. +The string must eventually be freed with [al_ustr_free]. + +See also: [al_ustr_new_from_buffer], [al_ustr_newf], [al_ustr_dup], +[al_ustr_new_from_utf16] + + +### API: al_ustr_new_from_buffer + +Create a new string containing a copy of the buffer pointed to by `s` of the +given `size` in bytes. The string must eventually be freed with [al_ustr_free]. + +See also: [al_ustr_new] + + +### API: al_ustr_newf + +Create a new string using a printf-style format string. + +*Notes:* + +The "%s" specifier takes C string arguments, not ALLEGRO_USTRs. Therefore to +pass an ALLEGRO_USTR as a parameter you must use [al_cstr], and it must be NUL +terminated. If the string contains an embedded NUL byte everything from that +byte onwards will be ignored. + +The "%c" specifier outputs a single byte, not the UTF-8 encoding of a code +point. Therefore it is only usable for ASCII characters (value <= 127) or if +you really mean to output byte values from 128--255. To insert the UTF-8 +encoding of a code point, encode it into a memory buffer using +[al_utf8_encode] then use the "%s" specifier. Remember to NUL terminate the +buffer. + +See also: [al_ustr_new], [al_ustr_appendf] + + +### API: al_ustr_free + +Free a previously allocated string. Does nothing if the argument is NULL. + +See also: [al_ustr_new], [al_ustr_new_from_buffer], [al_ustr_newf] + + +### API: al_cstr + +Get a `char *` pointer to the data in a string. This pointer will only be +valid while the [ALLEGRO_USTR] object is not modified and not destroyed. +The pointer may be passed to functions expecting C-style strings, +with the following caveats: + +* ALLEGRO_USTRs are allowed to contain embedded NUL (`'\0'`) bytes. + That means `al_ustr_size(u)` and `strlen(al_cstr(u))` may not agree. + +* An ALLEGRO_USTR may be created in such a way that it is not NUL terminated. + A string which is dynamically allocated will always be NUL terminated, + but a string which references the middle of another string or region + of memory will *not* be NUL terminated. + +* If the ALLEGRO_USTR references another string, the returned C string will + point into the referenced string. Again, no NUL terminator will be added + to the referenced string. + +See also: [al_ustr_to_buffer], [al_cstr_dup] + +### API: al_ustr_to_buffer + +Write the contents of the string into a pre-allocated buffer of the given size +in bytes. The result will always be NUL terminated, so a maximum of `size - 1` +bytes will be copied. + +See also: [al_cstr], [al_cstr_dup] + +### API: al_cstr_dup + +Create a NUL (`'\0'`) terminated copy of the string. Any embedded NUL +bytes will still be presented in the returned string. +The new string must eventually be freed with [al_free]. + +If an error occurs NULL is returned. + +See also: [al_cstr], [al_ustr_to_buffer], [al_free] + + +### API: al_ustr_dup + +Return a duplicate copy of a string. +The new string will need to be freed with [al_ustr_free]. + +See also: [al_ustr_dup_substr], [al_ustr_free] + + +### API: al_ustr_dup_substr + +Return a new copy of a string, containing its contents in the byte interval +\[`start_pos`, `end_pos`). The new string will be NUL terminated and will +need to be freed with [al_ustr_free]. + +If necessary, use [al_ustr_offset] to find the byte offsets for a given code +point that you are interested in. + +See also: [al_ustr_dup], [al_ustr_free] + + +## Predefined strings + +### API: al_ustr_empty_string + +Return a pointer to a static empty string. The string is read only +and must not be freed. + + +## Creating strings by referencing other data + +### API: al_ref_cstr + +Create a string that references the storage of a C-style string. The +information about the string (e.g. its size) is stored in the structure +pointed to by the `info` parameter. The string will not have any other +storage allocated of its own, so if you allocate the `info` structure on the +stack then no explicit "free" operation is required. + +The string is valid until the underlying C string disappears. + +Example: + +~~~~c +ALLEGRO_USTR_INFO info; +ALLEGRO_USTR *us = al_ref_cstr(&info, "my string"); +~~~~ + +See also: [al_ref_buffer], [al_ref_ustr] + + +### API: al_ref_buffer + +Create a string that references the storage of an underlying buffer. +The size of the buffer is given in bytes. You can use it to reference only +part of a string or an arbitrary region of memory. + +The string is valid while the underlying memory buffer is valid. + +See also: [al_ref_cstr], [al_ref_ustr] + + +### API: al_ref_ustr + +Create a read-only string that references the storage of another +[ALLEGRO_USTR] string. +The information about the string (e.g. its size) is stored in the structure +pointed to by the `info` parameter. The new string will not have any other +storage allocated of its own, so if you allocate the `info` structure on the +stack then no explicit "free" operation is required. + +The referenced interval is \[`start_pos`, `end_pos`). Both are byte offsets. + +The string is valid until the underlying string is modified or destroyed. + +If you need a range of code-points instead of bytes, use [al_ustr_offset] +to find the byte offsets. + +See also: [al_ref_cstr], [al_ref_buffer] + + +## Sizes and offsets + +### API: al_ustr_size + +Return the size of the string in bytes. This is equal to the number of code +points in the string if the string is empty or contains only 7-bit ASCII +characters. + +See also: [al_ustr_length] + +### API: al_ustr_length + +Return the number of code points in the string. + +See also: [al_ustr_size], [al_ustr_offset] + +### API: al_ustr_offset + +Return the byte offset (from the start of the string) of the code point at +the specified index in the string. A zero index parameter will return the first +character of the string. If index is negative, it counts backward from the end +of the string, so an index of -1 will return an offset to the last code point. + +If the index is past the end of the string, returns the offset of the end of +the string. + +See also: [al_ustr_length] + +### API: al_ustr_next + +Find the byte offset of the next code point in string, beginning at `*pos`. +`*pos` does not have to be at the beginning of a code point. + +Returns true on success, and the value pointed to by `pos` will be updated to +the found offset. Otherwise returns false if `*pos` was already at the end +of the string, and `*pos` is unmodified. + +This function just looks for an appropriate byte; it doesn't check if found +offset is the beginning of a valid code point. If you are working with +possibly invalid UTF-8 strings then it could skip over some invalid bytes. + +See also: [al_ustr_prev] + +### API: al_ustr_prev + +Find the byte offset of the previous code point in string, before `*pos`. +`*pos` does not have to be at the beginning of a code point. +Returns true on success, and the value pointed to by `pos` will be updated to the +found offset. Otherwise returns false if `*pos` was already at the end of +the string, and `*pos` is unmodified. + +This function just looks for an appropriate byte; it doesn't check if found +offset is the beginning of a valid code point. If you are working with +possibly invalid UTF-8 strings then it could skip over some invalid bytes. + +See also: [al_ustr_next] + + +## Getting code points + +### API: al_ustr_get + +Return the code point in `ub` beginning at byte offset `pos`. + +On success returns the code point value. +If `pos` was out of bounds (e.g. past the end of the string), return -1. +On an error, such as an invalid byte sequence, return -2. + +See also: [al_ustr_get_next], [al_ustr_prev_get] + +### API: al_ustr_get_next + +Find the code point in `us` beginning at byte offset `*pos`, then advance to +the next code point. + +On success return the code point value. +If `pos` was out of bounds (e.g. past the end of the string), return -1. +On an error, such as an invalid byte sequence, return -2. +As with [al_ustr_next], invalid byte sequences may be skipped while advancing. + +See also: [al_ustr_get], [al_ustr_prev_get] + +### API: al_ustr_prev_get + +Find the beginning of a code point before byte offset `*pos`, then return it. +Note this performs a *pre-increment*. + +On success returns the code point value. +If `pos` was out of bounds (e.g. past the end of the string), return -1. +On an error, such as an invalid byte sequence, return -2. +As with [al_ustr_prev], invalid byte sequences may be skipped while advancing. + +See also: [al_ustr_get_next] + + +## Inserting into strings + +### API: al_ustr_insert + +Insert `us2` into `us1` beginning at byte offset `pos`. `pos` cannot be less +than 0. If `pos` is past the end of `us1` then the space between the end of +the string and `pos` will be padded with NUL (`'\0'`) bytes. + +If required, use [al_ustr_offset] to find the byte offset for a given +code point index. + +Returns true on success, false on error. + +See also: [al_ustr_insert_cstr], [al_ustr_insert_chr], [al_ustr_append], +[al_ustr_offset] + +### API: al_ustr_insert_cstr + +Like [al_ustr_insert] but inserts a C-style string at byte offset `pos`. + +See also: [al_ustr_insert], [al_ustr_insert_chr] + +### API: al_ustr_insert_chr + +Insert a code point into `us` beginning at byte offset `pos`. `pos` cannot be +less than 0. If `pos` is past the end of `us` then the space between the end of +the string and `pos` will be padded with NUL (`'\0'`) bytes. + +Returns the number of bytes inserted, or 0 on error. + +See also: [al_ustr_insert], [al_ustr_insert_cstr] + + +## Appending to strings + +### API: al_ustr_append + +Append `us2` to the end of `us1`. + +Returns true on success, false on error. + +This function can be used to append an arbitrary buffer: + +~~~~c + ALLEGRO_USTR_INFO info; + al_ustr_append(us, al_ref_buffer(&info, buf, size)); +~~~~ + +See also: [al_ustr_append_cstr], [al_ustr_append_chr], [al_ustr_appendf], +[al_ustr_vappendf] + +### API: al_ustr_append_cstr + +Append C-style string `s` to the end of `us`. + +Returns true on success, false on error. + +See also: [al_ustr_append] + +### API: al_ustr_append_chr + +Append a code point to the end of `us`. + +Returns the number of bytes added, or 0 on error. + +See also: [al_ustr_append] + +### API: al_ustr_appendf + +This function appends formatted output to the string `us`. `fmt` is a +printf-style format string. +See [al_ustr_newf] about the "%s" and "%c" specifiers. + +Returns true on success, false on error. + +See also: [al_ustr_vappendf], [al_ustr_append] + +### API: al_ustr_vappendf + +Like [al_ustr_appendf] but you pass the variable argument list directly, +instead of the arguments themselves. +See [al_ustr_newf] about the "%s" and "%c" specifiers. + +Returns true on success, false on error. + +See also: [al_ustr_appendf], [al_ustr_append] + + +## Removing parts of strings + +### API: al_ustr_remove_chr + +Remove the code point beginning at byte offset `pos`. Returns true on success. +If `pos` is out of range or `pos` is not the beginning of a valid code point, +returns false leaving the string unmodified. + +Use [al_ustr_offset] to find the byte offset for a code-points offset. + +See also: [al_ustr_remove_range] + +### API: al_ustr_remove_range + +Remove the interval \[`start_pos`, `end_pos`) from a string. +`start_pos` and `end_pos` are byte offsets. +Both may be past the end of the string +but cannot be less than 0 (the start of the string). + +Returns true on success, false on error. + +See also: [al_ustr_remove_chr], [al_ustr_truncate] + +### API: al_ustr_truncate + +Truncate a portion of a string from byte offset `start_pos` onwards. +`start_pos` can be past the end of the string (has no effect) +but cannot be less than 0. + +Returns true on success, false on error. + +See also: [al_ustr_remove_range], [al_ustr_ltrim_ws], [al_ustr_rtrim_ws], +[al_ustr_trim_ws] + +### API: al_ustr_ltrim_ws + +Remove leading whitespace characters from a string, as defined by the C +function `isspace()`. + +Returns true on success, or false on error. + +See also: [al_ustr_rtrim_ws], [al_ustr_trim_ws] + +### API: al_ustr_rtrim_ws + +Remove trailing ("right") whitespace characters from a string, as defined by +the C function `isspace()`. + +Returns true on success, or false on error. + +See also: [al_ustr_ltrim_ws], [al_ustr_trim_ws] + +### API: al_ustr_trim_ws + +Remove both leading and trailing whitespace characters from a string. + +Returns true on success, or false on error. + +See also: [al_ustr_ltrim_ws], [al_ustr_rtrim_ws] + + +## Assigning one string to another + +### API: al_ustr_assign + +Overwrite the string `us1` with another string `us2`. +Returns true on success, false on error. + +See also: [al_ustr_assign_substr], [al_ustr_assign_cstr] + +### API: al_ustr_assign_substr + +Overwrite the string `us1` with the contents of `us2` in the byte interval +\[`start_pos`, `end_pos`). The end points will be clamped to the bounds of `us2`. + +Usually you will first have to use [al_ustr_offset] to find the byte offsets. + +Returns true on success, false on error. + +See also: [al_ustr_assign], [al_ustr_assign_cstr] + +### API: al_ustr_assign_cstr + +Overwrite the string `us1` with the contents of the C-style string `s`. +Returns true on success, false on error. + +See also: [al_ustr_assign_substr], [al_ustr_assign_cstr] + + +## Replacing parts of string + +### API: al_ustr_set_chr + +Replace the code point beginning at byte offset `start_pos` with `c`. +`start_pos` cannot be less than 0. If `start_pos` is past the end of `us` then the space +between the end of the string and `start_pos` will be padded with NUL (`'\0'`) bytes. +If `start_pos` is not the start of a valid code point, that is an error and +the string will be unmodified. + +On success, returns the number of bytes written, i.e. the offset to the +following code point. On error, returns 0. + +See also: [al_ustr_replace_range] + +### API: al_ustr_replace_range + +Replace the part of `us1` in the byte interval \[`start_pos1`, `end_pos1`) with the +contents of `us2`. `start_pos1` cannot be less than 0. If `start_pos1` is past +the end of `us1` then the space between the end of the string and `start_pos1` +will be padded with NUL (`'\0'`) bytes. + +Use [al_ustr_offset] to find the byte offsets. + +Returns true on success, false on error. + +See also: [al_ustr_set_chr] + + +## Searching + +### API: al_ustr_find_chr + +Search for the encoding of code point `c` in `us` from byte offset `start_pos` +(inclusive). + +Returns the position where it is found or -1 if it is not found. + +See also: [al_ustr_rfind_chr] + +### API: al_ustr_rfind_chr + +Search for the encoding of code point `c` in `us` backwards from byte offset +`end_pos` (exclusive). +Returns the position where it is found or -1 if it is not found. + +See also: [al_ustr_find_chr] + +### API: al_ustr_find_set + +This function finds the first code point in `us`, beginning from byte offset +`start_pos`, that matches any code point in `accept`. Returns the position if +a code point was found. Otherwise returns -1. + +See also: [al_ustr_find_set_cstr], [al_ustr_find_cset] + +### API: al_ustr_find_set_cstr + +Like [al_ustr_find_set] but takes a C-style string for `accept`. + +See also: [al_ustr_find_set], [al_ustr_find_cset_cstr] + +### API: al_ustr_find_cset + +This function finds the first code point in `us`, beginning from byte offset +`start_pos`, that does *not* match any code point in `reject`. In other words +it finds a code point in the complementary set of `reject`. +Returns the byte position of that code point, if any. Otherwise returns -1. + +See also: [al_ustr_find_cset_cstr], [al_ustr_find_set] + +### API: al_ustr_find_cset_cstr + +Like [al_ustr_find_cset] but takes a C-style string for `reject`. + +See also: [al_ustr_find_cset], [al_ustr_find_set_cstr] + +### API: al_ustr_find_str + +Find the first occurrence of string `needle` in `haystack`, beginning from byte +offset `start_pos` (inclusive). Return the byte offset of the occurrence if it is +found, otherwise return -1. + +See also: [al_ustr_find_cstr], [al_ustr_rfind_str], [al_ustr_find_replace] + +### API: al_ustr_find_cstr + +Like [al_ustr_find_str] but takes a C-style string for `needle`. + +See also: [al_ustr_find_str], [al_ustr_rfind_cstr] + +### API: al_ustr_rfind_str + +Find the last occurrence of string `needle` in `haystack` before byte offset +`end_pos` (exclusive). Return the byte offset of the occurrence if it is found, +otherwise return -1. + +See also: [al_ustr_rfind_cstr], [al_ustr_find_str] + +### API: al_ustr_rfind_cstr + +Like [al_ustr_rfind_str] but takes a C-style string for `needle`. + +See also: [al_ustr_rfind_str], [al_ustr_find_cstr] + +### API: al_ustr_find_replace + +Replace all occurrences of `find` in `us` with `replace`, beginning at byte +offset `start_pos`. The `find` string must be non-empty. +Returns true on success, false on error. + +See also: [al_ustr_find_replace_cstr] + +### API: al_ustr_find_replace_cstr + +Like [al_ustr_find_replace] but takes C-style strings for `find` and `replace`. + + +## Comparing + +### API: al_ustr_equal + +Return true iff the two strings are equal. This function is more efficient +than [al_ustr_compare] so is preferable if ordering is not important. + +See also: [al_ustr_compare] + +### API: al_ustr_compare + +This function compares `us1` and `us2` by code point values. +Returns zero if the strings are equal, a positive number if `us1` comes after +`us2`, else a negative number. + +This does *not* take into account locale-specific sorting rules. +For that you will need to use another library. + +See also: [al_ustr_ncompare], [al_ustr_equal] + +### API: al_ustr_ncompare + +Like [al_ustr_compare] but only compares up to the first `n` code points +of both strings. + +Returns zero if the strings are equal, a positive number if `us1` comes after +`us2`, else a negative number. + +See also: [al_ustr_compare], [al_ustr_equal] + +### API: al_ustr_has_prefix + +Returns true iff `us1` begins with `us2`. + +See also: [al_ustr_has_prefix_cstr], [al_ustr_has_suffix] + +### API: al_ustr_has_prefix_cstr + +Returns true iff `us1` begins with `s2`. + +See also: [al_ustr_has_prefix], [al_ustr_has_suffix_cstr] + +### API: al_ustr_has_suffix + +Returns true iff `us1` ends with `us2`. + +See also: [al_ustr_has_suffix_cstr], [al_ustr_has_prefix] + +### API: al_ustr_has_suffix_cstr + +Returns true iff `us1` ends with `s2`. + +See also: [al_ustr_has_suffix], [al_ustr_has_prefix_cstr] + + +## UTF-16 conversion + +### API: al_ustr_new_from_utf16 + +Create a new string containing a copy of the 0-terminated string `s` +which must be encoded as UTF-16. +The string must eventually be freed with [al_ustr_free]. + +See also: [al_ustr_new] + +### API: al_ustr_size_utf16 + +Returns the number of bytes required to encode the string in UTF-16 +(including the terminating 0). Usually called before +[al_ustr_encode_utf16] to determine the size of the buffer to allocate. + +See also: [al_ustr_size] + +### API: al_ustr_encode_utf16 + +Encode the string into the given buffer, in UTF-16. Returns the number +of bytes written. There are never more than `n` bytes written. The +minimum size to encode the complete string can be queried with +[al_ustr_size_utf16]. If the `n` parameter is smaller than that, the +string will be truncated but still always 0 terminated. + +See also: [al_ustr_size_utf16], [al_utf16_encode] + + +## Low-level UTF-8 routines + +### API: al_utf8_width + +Returns the number of bytes that would be occupied by the specified code point +when encoded in UTF-8. This is between 1 and 4 bytes for legal code point +values. Otherwise returns 0. + +See also: [al_utf8_encode], [al_utf16_width] + +### API: al_utf8_encode + +Encode the specified code point to UTF-8 into the buffer `s`. The buffer +must have enough space to hold the encoding, which takes between 1 and 4 +bytes. This routine will refuse to encode code points above 0x10FFFF. + +Returns the number of bytes written, which is the same as that returned +by [al_utf8_width]. + +See also: [al_utf16_encode] + + +## Low-level UTF-16 routines + +### API: al_utf16_width + +Returns the number of bytes that would be occupied by the specified code +point when encoded in UTF-16. This is either 2 or 4 bytes for legal code +point values. Otherwise returns 0. + +See also: [al_utf16_encode], [al_utf8_width] + +### API: al_utf16_encode + +Encode the specified code point to UTF-16 into the buffer `s`. The buffer +must have enough space to hold the encoding, which takes either 2 or 4 +bytes. This routine will refuse to encode code points above 0x10FFFF. + +Returns the number of bytes written, which is the same as that returned +by [al_utf16_width]. + +See also: [al_utf8_encode], [al_ustr_encode_utf16] + diff --git a/allegro/docs/src/refman/video.txt b/allegro/docs/src/refman/video.txt new file mode 100644 index 00000000..cd4af6d7 --- /dev/null +++ b/allegro/docs/src/refman/video.txt @@ -0,0 +1,202 @@ +# Video streaming addon + +These functions are declared in the following header file. +Link with allegro_video. + +~~~~c + #include +~~~~ + +Currently we have an Ogg backend (Theora + Vorbis). See for +installation instructions, licensing information and supported video formats. + +## API: ALLEGRO_VIDEO_EVENT_TYPE + +Events sent by [al_get_video_event_source]. + +### ALLEGRO_EVENT_VIDEO_FRAME_SHOW + +This event is sent when it is time to show a new frame. Once you receive this +event, you can draw the current frame (as returned by [al_get_video_frame]). +[al_get_video_frame] will continue returning the same frame until the next +ALLEGRO_EVENT_VIDEO_FRAME_SHOW is sent. + +user.data1 (ALLEGRO_VIDEO *) +: The video which generated the event. + +Since: 5.1.0 + +### ALLEGRO_EVENT_VIDEO_FINISHED + +This event is sent when the video is finished. Depending on the backend, it may +be possible to seek to an earlier part of the video and set the video to play +to resume playback. + +user.data1 (ALLEGRO_VIDEO *) +: The video which generated the event. + +Since: 5.1.0 + +## API: ALLEGRO_VIDEO_POSITION_TYPE + +Used with [al_get_video_position] to specify which position to retrieve. If +these get out of sync, audio and video may be out of sync in the display of +the video. + +* ALLEGRO_VIDEO_POSITION_ACTUAL - +The amount of time the video has been playing. If the video has audio then +this value can be ahead of ALLEGRO_VIDEO_POSITION_VIDEO_DECODE when video +decoding lags. + +* ALLEGRO_VIDEO_POSITION_VIDEO_DECODE - +The amount of video that has been decoded. This may lag behind the "actual" +and audio positions if decoding is slower than realtime. + +* ALLEGRO_VIDEO_POSITION_AUDIO_DECODE - +The amount of audio that has been decoded. This may be the same as +ALLEGRO_VIDEO_POSITION_ACTUAL if audio decode is driving the position, +which is common to keep audio and video in sync. + +Since: 5.1.11 + +## API: al_init_video_addon + +Initializes the video addon. + +Since: 5.1.12 + +## API: al_is_video_addon_initialized + +Returns true if the video addon is initialized, otherwise returns false. + +Since: 5.2.6 + +## API: al_shutdown_video_addon + +Shut down the video addon. This is done automatically at program exit, +but can be called any time the user wishes as well. + +Since: 5.1.12 + +## API: al_get_allegro_video_version + +Returns the (compiled) version of the addon, in the same format as +[al_get_allegro_version]. + +Since: 5.1.12 + +## API: al_open_video + +Reads a video file. This does not start streaming yet but reads the +meta info so you can query e.g. the size or audio rate. + +Since: 5.1.0 + +## API: al_close_video + +Closes the video and frees all allocated resources. The video pointer +is invalid after the function returns. + +Since: 5.1.0 + +## API: al_start_video + +Starts streaming the video from the beginning. + +Since: 5.1.0 + +## API: al_start_video_with_voice + +Like [al_start_video] but audio is routed to the provided voice. + +Since: 5.1.0 + +## API: al_get_video_event_source + +Get an event source for the video. The possible events are described +under [ALLEGRO_VIDEO_EVENT_TYPE]. + +Since: 5.1.0 + +## API: al_set_video_playing + +Paused or resumes playback. + +Since: 5.1.12 + +## API: al_is_video_playing + +Returns true if the video is currently playing. + +Since: 5.1.12 + +## API: al_get_video_audio_rate + +Returns the audio rate of the video, in Hz. + +Since: 5.1.0 + +## API: al_get_video_fps + +Returns the speed of the video in frames per second. Often this will +not be an integer value. + +Since: 5.1.0 + +## API: al_get_video_scaled_width + +Returns the width with which the video frame should be drawn. Videos often do +not use square pixels, so this will may return a value larger than the width of +the frame bitmap. + +Since: 5.1.12 + +See also: [al_get_video_frame] + +## API: al_get_video_scaled_height + +Returns the height with which the video frame should be drawn. Videos often do +not use square pixels, so this will may return a value larger than the height of +the frame bitmap. + +See also: [al_get_video_frame] + +Since: 5.1.12 + +## API: al_get_video_frame + +Returns the current video frame. The bitmap is owned by the video so +do not attempt to free it. The bitmap will stay valid until the next +call to al_get_video_frame. + +Videos often do not use square pixels so the recommended way to draw a video +frame would be using code like this: + +~~~~c +float scale = 1.0; /* Adjust this to fit your target bitmap dimensions. */ +ALLEGRO_BITMAP* frame = al_get_video_frame(video); +float sw = al_get_bitmap_width(frame); +float sh = al_get_bitmap_height(frame); +float dw = scale * al_get_video_scaled_width(video); +float dh = scale * al_get_video_scaled_height(video); +al_draw_scaled_bitmap(frame, 0, 0, sw, sh, 0, 0, dw, dh, 0); +~~~~ + +Since: 5.1.0 + +See also: [al_get_video_scaled_width], [al_get_video_scaled_height] + +## API: al_get_video_position + +Returns the current position of the video stream in seconds since the +beginning. The parameter is one of the [ALLEGRO_VIDEO_POSITION_TYPE] +constants. + +Since: 5.1.0 + +## API: al_seek_video + +Seek to a different position in the video. Currently only seeking to the +beginning of the video is supported. + +Since: 5.1.0 diff --git a/allegro/examples/CMakeLists.txt b/allegro/examples/CMakeLists.txt new file mode 100644 index 00000000..a514d524 --- /dev/null +++ b/allegro/examples/CMakeLists.txt @@ -0,0 +1,278 @@ +include_directories( + ../addons/acodec + ../addons/audio + ../addons/color + ../addons/font + ../addons/image + ../addons/main + ../addons/memfile + ../addons/native_dialog + ../addons/physfs + ../addons/primitives + ../addons/shader + ../addons/ttf + ../addons/video + ) + +if(SUPPORT_PHYSFS) + # The physfs example directly includes physfs.h + include_directories(${PHYSFS_INCLUDE_DIR}) +endif() + +#-----------------------------------------------------------------------------# + +# List dependencies explicitly for loading by Android APKs. + +set(AUDIO x${AUDIO_LINK_WITH}) +set(ACODEC ${AUDIO} x${ACODEC_LINK_WITH}) +set(COLOR x${COLOR_LINK_WITH}) +set(DIALOG x${NATIVE_DIALOG_LINK_WITH}) +set(FONT x${FONT_LINK_WITH}) +set(IMAGE x${IMAGE_LINK_WITH}) +set(MEMFILE x${MEMFILE_LINK_WITH}) +set(PHYSFS x${PHYSFS_LINK_WITH}) +set(PRIM x${PRIMITIVES_LINK_WITH}) +set(TTF ${FONT} x${TTF_LINK_WITH}) +set(VIDEO x${VIDEO_LINK_WITH}) +set(NIHGUI nihgui.cpp ${FONT} ${PRIM}) + +include(Helper.cmake) + +#-----------------------------------------------------------------------------# + +# Lists of data files to add to Android APKs, to appear after the DATA keyword. +# DATA_IMAGES is a special case that includes the DATA keyword. +# Examples don't necessarily use every file in the list. + +set(DATA_IMAGES + DATA + a4_font.tga + alexlogo.bmp + alexlogo.png + allegro.pcx + bkg.png + bmpfont.tga + cursor.tga + fakeamp.bmp + fixed_font.tga + font.tga + gradient1.bmp + haiku/air_effect.png + icon.tga + mysha.pcx + mysha256x256.png + obp.jpg + texture.tga + ) + +set(DATA_TTF + DejaVuSans.ttf + a4_font.fnt + ) + +set(DATA_AUDIO + welcome.wav + welcome.voc + ) + +set(DATA_SHADERS + ex_prim_shader_pixel.glsl + ex_prim_shader_pixel.hlsl + ex_prim_shader_vertex.glsl + ex_prim_shader_vertex.hlsl + ex_shader_multitex_pixel.glsl + ex_shader_multitex_pixel.hlsl + ex_shader_pixel.glsl + ex_shader_pixel.hlsl + ex_shader_vertex.glsl + ex_shader_vertex.hlsl + ) + +file(GLOB DATA_HAIKU RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/data data/haiku/*) +set(DATA_HAIKU ${DATA_HAIKU}) + +#-----------------------------------------------------------------------------# + +example(ex_config DATA sample.cfg) +example(ex_dir ${DATA_IMAGES}) +example(ex_file CONSOLE ${DATA_IMAGES}) +example(ex_file_slice CONSOLE) +example(ex_get_path) +example(ex_memfile CONSOLE ${MEMFILE}) +example(ex_monitorinfo) +example(ex_path) +example(ex_path_test) +example(ex_user_events) +example(ex_inject_events) + +if(NOT MSVC) + # UTF-8 strings are problematic under MSVC. + example(ex_utf8) +endif(NOT MSVC) + +if(ANDROID) + example(ex_android ${IMAGE} ${PRIM} ${DATA_IMAGES}) +endif(ANDROID) + +example(ex_bitmap ${IMAGE} ${DATA_IMAGES}) +example(ex_bitmap_file ${IMAGE} ${DATA_IMAGES}) +example(ex_bitmap_flip ${IMAGE} ${FONT} ${DATA_IMAGES}) +example(ex_blend ${FONT} ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_blend2 ex_blend2.cpp ${NIHGUI} ${IMAGE} ${DATA_IMAGES}) +example(ex_blend_bench ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_blend_test ${PRIM}) +example(ex_blend_target ${IMAGE} ${DATA_IMAGES}) +example(ex_blit ${FONT} ${IMAGE} ${COLOR} ${DATA_IMAGES}) +example(ex_clip ${FONT} ${COLOR}) +example(ex_clipboard ${IMAGE} ${FONT} ${DATA_IMAGES}) +example(ex_color ex_color.cpp ${NIHGUI} ${TTF} ${COLOR} DATA ${DATA_TTF}) +example(ex_color2 ex_color2.c ${FONT} ${COLOR} ${PRIM}) +example(ex_compressed ${IMAGE} ${FONT} ${DATA_IMAGES}) +example(ex_convert CONSOLE ${IMAGE}) +example(ex_cpu ${FONT}) +example(ex_depth_mask ${IMAGE} ${TTF} ${DATA_IMAGES} ${DATA_TTF}) +example(ex_depth_target ${IMAGE} ${FONT} ${COLOR} ${PRIM}) +example(ex_disable_screensaver ${FONT}) +example(ex_display_events ${FONT} ${PRIM}) +example(ex_display_options ${FONT} ${PRIM}) +example(ex_draw ${FONT} ${IMAGE} ${COLOR} ${PRIM} ${DATA_IMAGES}) +example(ex_draw_bitmap ${IMAGE} ${FONT} ${DATA_IMAGES}) +example(ex_drawpixels) +example(ex_dualies ${IMAGE}) +example(ex_expose ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_filter ${FONT} ${IMAGE} ${COLOR} ${DATA_IMAGES}) +example(ex_fs_resize ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_fs_window ${IMAGE} ${PRIM} ${FONT} ${DATA_IMAGES}) +example(ex_icon ${IMAGE} ${DATA_IMAGES}) +example(ex_icon2 ${IMAGE} ${DATA_IMAGES}) +example(ex_haptic ${PRIM}) +example(ex_haptic2 ex_haptic2.cpp ${NIHGUI} ${TTF} DATA ${DATA_TTF}) +example(ex_joystick_events ${PRIM} ${FONT}) +example(ex_joystick_hotplugging ${PRIM}) +example(ex_keyboard_events) +example(ex_keyboard_focus) +example(ex_lines ${PRIM}) +example(ex_loading_thread ${IMAGE} ${FONT} ${PRIM} ${DATA_IMAGES}) +example(ex_lockbitmap) +example(ex_membmp ${FONT} ${IMAGE} ${DATA_IMAGES}) +example(ex_mouse ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_mouse_cursor ${FONT} ${IMAGE} ${DATA_IMAGES}) +example(ex_mouse_events ${FONT} ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_mouse_focus) +example(ex_mouse_warp ${FONT} ${PRIM}) +example(ex_multisample ${FONT} ${COLOR} ${PRIM}) +example(ex_multisample_target ${IMAGE} ${FONT} ${COLOR} ${PRIM}) +example(ex_multiwin ${IMAGE}) +example(ex_nodisplay ${IMAGE} ${DATA_IMAGES}) +example(ex_noframe ${IMAGE} ${DATA_IMAGES}) +example(ex_physfs ${PHYSFS} ${IMAGE} ${DATA_IMAGES}) +example(ex_pixelformat ex_pixelformat.cpp ${NIHGUI} ${IMAGE} ${DATA_IMAGES}) +example(ex_polygon ${FONT} ${PRIM}) +example(ex_premulalpha ${FONT}) +example(ex_prim ${FONT} ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_prim_shader ${PRIM} DATA ${DATA_SHADERS}) +example(ex_reparent ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_resize ${PRIM}) +example(ex_resize2 ${IMAGE} ${FONT}) +example(ex_rotate ${IMAGE} ${DATA_IMAGES}) +example(ex_scale ${IMAGE} ${DATA_IMAGES}) +example(ex_shader ex_shader.cpp ${IMAGE} ${DATA_IMAGES} ${DATA_SHADERS}) +example(ex_shader_multitex ${IMAGE} ${DATA_IMAGES} ${DATA_SHADERS}) +example(ex_shader_target ${IMAGE} ${DATA_IMAGES} ${DATA_SHADERS}) +example(ex_subbitmap ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_threads ${PRIM}) +example(ex_threads2) +example(ex_timedwait) +example(ex_timer ${FONT} ${PRIM}) +example(ex_timer_pause) +example(ex_touch_input ${PRIM}) +example(ex_transform ${FONT} ${IMAGE} ${PRIM} ${DATA_IMAGES}) +example(ex_vertex_buffer ${FONT} ${PRIM}) +example(ex_vsync ${FONT} ${IMAGE} ${PRIM}) +example(ex_windows ${FONT} ${IMAGE}) +example(ex_window_constraints ${FONT} ${IMAGE}) +example(ex_window_maximized ${FONT} ${IMAGE} ${PRIM} ${DIALOG}) +example(ex_window_title ${IMAGE} ${FONT} ${DATA_IMAGES}) +example(ex_winfull) +example(ex_video ${AUDIO} ${FONT} ${PRIM} ${VIDEO}) + +if(WANT_D3D AND D3DX9_FOUND) + example(ex_d3d ex_d3d.cpp EXTRA_LIBS ${D3DX9_LIBRARY}) +endif() + +if(SUPPORT_OPENGL AND NOT SUPPORT_OPENGLES) + example(ex_gldepth ${FONT} ${IMAGE}) + example(ex_glext) + example(ex_opengl) + example(ex_opengl_pixel_shader ${IMAGE}) +endif() +if(SUPPORT_OPENGL AND NOT IPHONE AND NOT ALLEGRO_RASPBERRYPI) + example(ex_palette ${IMAGE} ${COLOR} ${DATA_IMAGES}) +endif() + +example(ex_font ${FONT} ${IMAGE} ${DATA_IMAGES}) +example(ex_font_justify ex_font_justify.cpp ${NIHGUI} ${IMAGE} ${TTF} ${DATA_IMAGES} ${DATA_TTF}) +example(ex_font_multiline ex_font_multiline.cpp ${NIHGUI} ${IMAGE} ${TTF} ${COLOR} ${DATA_IMAGES} ${DATA_TTF}) +example(ex_logo ${FONT} ${TTF} ${IMAGE} ${PRIM} DATA ${DATA_TTF}) +example(ex_projection ${TTF} ${IMAGE} ${DATA_IMAGES} ${DATA_TTF}) +example(ex_projection2 ${PRIM} ${FONT} ${IMAGE} ${DATA_IMAGES}) +example(ex_camera ${FONT} ${COLOR} ${PRIM} ${IMAGE}) +example(ex_ttf ${TTF} ${PRIM} ${IMAGE} DATA ${DATA_TTF} ex_ttf.ini) + +example(ex_acodec CONSOLE ${AUDIO} ${ACODEC}) +example(ex_acodec_multi CONSOLE ${AUDIO} ${ACODEC}) +example(ex_audio_chain ex_audio_chain.cpp ${AUDIO} ${ACODEC} ${PRIM} ${FONT} ${TTF} DATA ${DATA_TTF} ${DATA_HAIKU}) +example(ex_audio_props ex_audio_props.cpp ${NIHGUI} ${ACODEC} DATA ${DATA_AUDIO}) +example(ex_audio_simple CONSOLE ${AUDIO} ${ACODEC} ${FONT}) +example(ex_audio_timer ${AUDIO} ${FONT}) +example(ex_haiku ${AUDIO} ${ACODEC} ${IMAGE} ${DATA_IMAGES} ${DATA_HAIKU}) +example(ex_kcm_direct CONSOLE ${AUDIO} ${ACODEC}) +example(ex_mixer_chain CONSOLE ${AUDIO} ${ACODEC}) +example(ex_mixer_pp ${AUDIO} ${ACODEC} ${PRIM} ${IMAGE} ${DATA_IMAGES} ${DATA_AUDIO}) +example(ex_record ${AUDIO} ${ACODEC} ${PRIM}) +example(ex_record_name ${AUDIO} ${ACODEC} ${PRIM} ${IMAGE} ${FONT}) +example(ex_resample_test ${AUDIO}) +example(ex_saw ${AUDIO}) +example(ex_stream_file CONSOLE ${AUDIO} ${ACODEC}) +example(ex_stream_seek ${AUDIO} ${ACODEC} ${PRIM} ${FONT} ${IMAGE} ${DATA_IMAGES} ${DATA_AUDIO}) +example(ex_synth ex_synth.cpp ${NIHGUI} ${AUDIO} ${TTF} DATA ${DATA_TTF}) + +example(ex_native_filechooser ${DIALOG} ${FONT} ${IMAGE} ${COLOR}) +example(ex_menu ${DIALOG} ${IMAGE}) + +# In some configurations CURL pulls in dependencies which we don't check for. +# This example isn't important so it's disabled by default to prevent problems. +option(WANT_CURL_EXAMPLE "Build ex_curl example" off) +if(WANT_CURL_EXAMPLE) + find_package(CURL) + if(CURL_FOUND) + if(WIN32) + # select() is in the Winsock library. + example(ex_curl ${IMAGE} EXTRA_LIBS ${CURL_LIBRARIES} ws2_32) + else(WIN32) + example(ex_curl ${IMAGE} EXTRA_LIBS ${CURL_LIBRARIES}) + endif(WIN32) + endif(CURL_FOUND) +endif(WANT_CURL_EXAMPLE) + +# Only build the enet examples if libenet is installed +find_package(ENet) +if(ENET_FOUND) + example(ex_enet_client ${PRIM} EXTRA_LIBS ${ENET_LIBRARIES}) + example(ex_enet_server EXTRA_LIBS ${ENET_LIBRARIES}) +endif() + +# example(ex_ogre3d ex_ogre3d.cpp) +# include_directories(/usr/include/OGRE) +# target_link_libraries(ex_ogre3d OgreMain) + +copy_data_dir_to_build(copy_example_data + "${CMAKE_CURRENT_SOURCE_DIR}/data" + "${CMAKE_CURRENT_BINARY_DIR}/data" + ) + +# This is useful for developers to add temporary test programs. +include(${CMAKE_CURRENT_SOURCE_DIR}/local_examples.cmake OPTIONAL) + +#-----------------------------------------------------------------------------# +# vim: set ts=8 sts=4 sw=4 et: diff --git a/allegro/examples/Helper.cmake b/allegro/examples/Helper.cmake new file mode 100644 index 00000000..c143ec9c --- /dev/null +++ b/allegro/examples/Helper.cmake @@ -0,0 +1,96 @@ +# Conditionally build an example program. If any of its arguments is the exact +# string "x", do nothing. Otherwise strip off the "x" prefixes on arguments +# and link to that target. +function(example name) + # Use cmake_parse_arguments first. + set(flags CONSOLE) + set(single_args) # none + set(accum_args DATA EXTRA_LIBS) + cmake_parse_arguments(MYOPTS "${flags}" "${single_args}" "${accum_args}" + ${ARGN}) + + # Parse what remains of the argument list manually. + set(sources) + set(libs) + foreach(arg ${MYOPTS_UNPARSED_ARGUMENTS}) + if(arg STREQUAL "x") + message(STATUS "Not building ${name}") + return() + endif() + if(arg MATCHES "[.]c$") + list(APPEND sources ${arg}) + elseif(arg MATCHES "[.]cpp$") + list(APPEND sources ${arg}) + else() + string(REGEX REPLACE "^x" "" arg ${arg}) + list(APPEND libs ${arg}) + endif() + endforeach() + + # If no sources are listed assume a single C source file. + if(NOT sources) + set(sources "${name}.c") + endif() + + # Prepend the base libraries. + if(ANDROID) + set(libs ${ALLEGRO_LINK_WITH} ${libs}) + else() + set(libs ${ALLEGRO_LINK_WITH} ${ALLEGRO_MAIN_LINK_WITH} ${libs}) + endif() + + # Popup error messages. + if(WANT_POPUP_EXAMPLES AND SUPPORT_NATIVE_DIALOG) + list(APPEND libs ${NATIVE_DIALOG_LINK_WITH}) + endif() + + # Monolith contains all other libraries which were enabled. + if(WANT_MONOLITH) + set(libs ${ALLEGRO_MONOLITH_LINK_WITH}) + endif() + + # Append the extra, non-Allegro libraries. + foreach(lib ${MYOPTS_EXTRA_LIBS}) + list(APPEND libs ${lib}) + endforeach() + + list(REMOVE_DUPLICATES libs) + + if(WIN32) + if(MYOPTS_CONSOLE) + # We need stdout and stderr available from cmd.exe, + # so we must not use WIN32 here. + set(EXECUTABLE_TYPE) + else() + set(EXECUTABLE_TYPE "WIN32") + endif() + endif(WIN32) + + if(IPHONE) + set(EXECUTABLE_TYPE MACOSX_BUNDLE) + endif(IPHONE) + + if(ANDROID) + if(MYOPTS_CONSOLE) + message(STATUS "Not building ${name} - console program") + return() + endif() + add_copy_commands( + "${CMAKE_CURRENT_SOURCE_DIR}/data" + "${CMAKE_CURRENT_BINARY_DIR}/${name}.project/app/src/main/assets/data" + assets + "${MYOPTS_DATA}" + ) + add_android_app("${name}" "${sources};${assets}") + elseif(IPHONE) + add_our_executable("${name}" SRCS "${sources};${CMAKE_CURRENT_SOURCE_DIR}/data" + LIBS "${libs}") + set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/data" PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources") + else() + add_our_executable("${name}" SRCS "${sources}" LIBS "${libs}") + endif() +endfunction(example) + +#-----------------------------------------------------------------------------# +# vim: set ts=8 sts=4 sw=4 et: diff --git a/allegro/examples/common.c b/allegro/examples/common.c new file mode 100644 index 00000000..ff4f9eaa --- /dev/null +++ b/allegro/examples/common.c @@ -0,0 +1,127 @@ +#include +#include + +#ifdef ALLEGRO_ANDROID + #include "allegro5/allegro_android.h" +#endif + +void init_platform_specific(void); +void abort_example(char const *format, ...); +void open_log(void); +void open_log_monospace(void); +void close_log(bool wait_for_user); +void log_printf(char const *format, ...); + +void init_platform_specific(void) +{ +#ifdef ALLEGRO_ANDROID + al_install_touch_input(); + al_android_set_apk_file_interface(); +#endif +} + +#ifdef ALLEGRO_POPUP_EXAMPLES + +#include "allegro5/allegro_native_dialog.h" + +ALLEGRO_TEXTLOG *textlog = NULL; + +void abort_example(char const *format, ...) +{ + char str[1024]; + va_list args; + ALLEGRO_DISPLAY *display; + + va_start(args, format); + vsnprintf(str, sizeof str, format, args); + va_end(args); + + if (al_init_native_dialog_addon()) { + display = al_is_system_installed() ? al_get_current_display() : NULL; + al_show_native_message_box(display, "Error", "Cannot run example", str, NULL, 0); + } + else { + fprintf(stderr, "%s", str); + } + exit(1); +} + +void open_log(void) +{ + if (al_init_native_dialog_addon()) { + textlog = al_open_native_text_log("Log", 0); + } +} + +void open_log_monospace(void) +{ + if (al_init_native_dialog_addon()) { + textlog = al_open_native_text_log("Log", ALLEGRO_TEXTLOG_MONOSPACE); + } +} + +void close_log(bool wait_for_user) +{ + if (textlog && wait_for_user) { + ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue(); + al_register_event_source(queue, al_get_native_text_log_event_source( + textlog)); + al_wait_for_event(queue, NULL); + al_destroy_event_queue(queue); + } + + al_close_native_text_log(textlog); + textlog = NULL; +} + +void log_printf(char const *format, ...) +{ + char str[1024]; + va_list args; + va_start(args, format); + vsnprintf(str, sizeof str, format, args); + va_end(args); + al_append_native_text_log(textlog, "%s", str); +} + +#else + +void abort_example(char const *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + exit(1); +} + +void open_log(void) +{ +} + +void open_log_monospace(void) +{ +} + +void close_log(bool wait_for_user) +{ + (void)wait_for_user; +} + +void log_printf(char const *format, ...) +{ + va_list args; + va_start(args, format); + #ifdef ALLEGRO_ANDROID + char x[1024]; + vsnprintf(x, sizeof x, format, args); + ALLEGRO_TRACE_CHANNEL_LEVEL("log", 1)("%s", x); + #else + vprintf(format, args); + #endif + va_end(args); +} + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/data/DejaVuSans.LICENSE b/allegro/examples/data/DejaVuSans.LICENSE new file mode 100644 index 00000000..254e2cc4 --- /dev/null +++ b/allegro/examples/data/DejaVuSans.LICENSE @@ -0,0 +1,99 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ diff --git a/allegro/examples/data/DejaVuSans.ttf b/allegro/examples/data/DejaVuSans.ttf new file mode 100644 index 00000000..b69c9186 Binary files /dev/null and b/allegro/examples/data/DejaVuSans.ttf differ diff --git a/allegro/examples/data/a4_font.fnt b/allegro/examples/data/a4_font.fnt new file mode 100644 index 00000000..32d31ced --- /dev/null +++ b/allegro/examples/data/a4_font.fnt @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/allegro/examples/data/a4_font.tga b/allegro/examples/data/a4_font.tga new file mode 100644 index 00000000..4660c260 Binary files /dev/null and b/allegro/examples/data/a4_font.tga differ diff --git a/allegro/examples/data/alexlogo.bmp b/allegro/examples/data/alexlogo.bmp new file mode 100644 index 00000000..c2e17bf5 Binary files /dev/null and b/allegro/examples/data/alexlogo.bmp differ diff --git a/allegro/examples/data/alexlogo.png b/allegro/examples/data/alexlogo.png new file mode 100644 index 00000000..de3ff28c Binary files /dev/null and b/allegro/examples/data/alexlogo.png differ diff --git a/allegro/examples/data/allegro.pcx b/allegro/examples/data/allegro.pcx new file mode 100644 index 00000000..fc0107ca Binary files /dev/null and b/allegro/examples/data/allegro.pcx differ diff --git a/allegro/examples/data/bkg.png b/allegro/examples/data/bkg.png new file mode 100644 index 00000000..cdac4768 Binary files /dev/null and b/allegro/examples/data/bkg.png differ diff --git a/allegro/examples/data/blue_box.png b/allegro/examples/data/blue_box.png new file mode 100644 index 00000000..a52a9266 Binary files /dev/null and b/allegro/examples/data/blue_box.png differ diff --git a/allegro/examples/data/bmpfont.tga b/allegro/examples/data/bmpfont.tga new file mode 100644 index 00000000..4d8ae78d Binary files /dev/null and b/allegro/examples/data/bmpfont.tga differ diff --git a/allegro/examples/data/cursor.tga b/allegro/examples/data/cursor.tga new file mode 100644 index 00000000..ad2ab8f7 Binary files /dev/null and b/allegro/examples/data/cursor.tga differ diff --git a/allegro/examples/data/ex_physfs.zip b/allegro/examples/data/ex_physfs.zip new file mode 100644 index 00000000..5eb8165d Binary files /dev/null and b/allegro/examples/data/ex_physfs.zip differ diff --git a/allegro/examples/data/ex_prim_shader_pixel.glsl b/allegro/examples/data/ex_prim_shader_pixel.glsl new file mode 100644 index 00000000..a0919216 --- /dev/null +++ b/allegro/examples/data/ex_prim_shader_pixel.glsl @@ -0,0 +1,48 @@ +#ifdef GL_ES +precision mediump float; +#endif + +/* This shader implements Phong shading (see http://en.wikipedia.org/wiki/Phong_reflection_model for the math). + * It is not the most optimized version of it, as it sticks closely to the mathematics of the model. */ + +uniform vec3 light_position; +/* diffuse color specifies the color of the illumination outside of the highlights, but still within the light + * radius */ +uniform vec4 diffuse_color; +/* alpha is the shininess of a surface. 1 is dull, >1 is shiny. <1 is weird :) */ +uniform float alpha; + +varying vec3 pixel_position; +varying vec3 normal; + +/* Ambient color and intensity specify the color of the illumination outside the range of the light */ +#define AMBIENT_COLOR vec4(1, 1, 1, 1) +#define AMBIENT_INTENSITY 0.01 +/* Specifies the color of the highlights */ +#define SPECULAR_COLOR vec4(1, 1, 1, 1) + +void main() +{ + /* Vector pointing from the point on the surface to the light */ + vec3 light_vector = light_position - pixel_position; + /* Unit vector of the above */ + vec3 light_dir = normalize(light_vector); + /* Unit vector normal to the surface (linear interpolation between vertex normals does not produce unit vectors in most cases)*/ + vec3 normal_vector = normalize(normal); + + /* Reflectance is used for both diffuse components and specular components. It needs to be non-negative */ + float reflectance = dot(light_dir, normal_vector); + reflectance = max(reflectance, 0.0); + + /* Computes the reflection of the light and then the degree to which it points at the camera. This also is non-negative. + * (0, 0, 1) is the vector that points at the camera */ + float specular_intensity = dot((2.0 * reflectance * normal_vector - light_dir), vec3(0.0, 0.0, 1.0)); + specular_intensity = max(0.0, specular_intensity); + specular_intensity = pow(specular_intensity, alpha); + + /* Compute diffuse intensity by attenuating reflectance with a simple quadratic distance falloff */ + float diffuse_intensity = reflectance * 10000.0 / dot(light_vector, light_vector); + + /* The final color is the combination of the 3 light sources */ + gl_FragColor = AMBIENT_COLOR * AMBIENT_INTENSITY + diffuse_color * diffuse_intensity + SPECULAR_COLOR * specular_intensity; +} diff --git a/allegro/examples/data/ex_prim_shader_pixel.hlsl b/allegro/examples/data/ex_prim_shader_pixel.hlsl new file mode 100644 index 00000000..febcb65e --- /dev/null +++ b/allegro/examples/data/ex_prim_shader_pixel.hlsl @@ -0,0 +1,27 @@ +float3 light_position; +float4 diffuse_color; +float alpha; + +/* Ported from ex_prim_shader_pixel.glsl. See that file for the comments. */ + +#define AMBIENT_COLOR float4(1, 1, 1, 1) +#define AMBIENT_INTENSITY 0.01 +#define SPECULAR_COLOR float4(1, 1, 1, 1) + +float4 ps_main(VS_OUTPUT Input) : COLOR0 +{ + float3 light_vector = light_position - Input.PixelPosition; + float3 light_dir = normalize(light_vector); + float3 normal_vector = normalize(Input.Normal); + + float reflectance = dot(light_dir, normal_vector); + reflectance = max(reflectance, 0.0f); + + float specular_intensity = dot((2 * reflectance * normal_vector - light_dir), float3(0, 0, 1)); + specular_intensity = max(0, specular_intensity); + specular_intensity = pow(specular_intensity, alpha); + + float diffuse_intensity = reflectance * 10000.0 / dot(light_vector, light_vector); + + return AMBIENT_COLOR * AMBIENT_INTENSITY + diffuse_color * diffuse_intensity + SPECULAR_COLOR * specular_intensity; +} diff --git a/allegro/examples/data/ex_prim_shader_vertex.glsl b/allegro/examples/data/ex_prim_shader_vertex.glsl new file mode 100644 index 00000000..3b579010 --- /dev/null +++ b/allegro/examples/data/ex_prim_shader_vertex.glsl @@ -0,0 +1,15 @@ +attribute vec4 al_pos; +attribute vec3 al_user_attr_0; + +uniform mat4 al_projview_matrix; + +/* pixel_position and normal are used to compute the reflections in the pixel shader */ +varying vec3 pixel_position; +varying vec3 normal; + +void main() +{ + pixel_position = al_pos.xyz; + normal = al_user_attr_0; + gl_Position = al_projview_matrix * al_pos; +} diff --git a/allegro/examples/data/ex_prim_shader_vertex.hlsl b/allegro/examples/data/ex_prim_shader_vertex.hlsl new file mode 100644 index 00000000..eefefee5 --- /dev/null +++ b/allegro/examples/data/ex_prim_shader_vertex.hlsl @@ -0,0 +1,24 @@ +struct VS_INPUT +{ + float4 Position : POSITION0; + float3 Normal : TEXCOORD2; +}; +struct VS_OUTPUT +{ + float4 Position : POSITION0; + /* pixel_position and normal are used to compute the reflections in the pixel shader */ + float3 PixelPosition : TEXCOORD0; + float3 Normal : TEXCOORD1; +}; + +float4x4 al_projview_matrix; + +VS_OUTPUT vs_main(VS_INPUT Input) +{ + VS_OUTPUT Output; + + Output.Position = mul(Input.Position, al_projview_matrix); + Output.PixelPosition = Input.Position.xyz; + Output.Normal = Input.Normal; + return Output; +} diff --git a/allegro/examples/data/ex_shader_multitex_pixel.glsl b/allegro/examples/data/ex_shader_multitex_pixel.glsl new file mode 100644 index 00000000..a164ca90 --- /dev/null +++ b/allegro/examples/data/ex_shader_multitex_pixel.glsl @@ -0,0 +1,14 @@ +/* Simple fragment shader which uses the fractional texture coordinate to + * look up the color of the second texture (scaled down by factor 100). + */ +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D al_tex; +uniform sampler2D tex2; +varying vec2 varying_texcoord; +void main() +{ + vec4 color = texture2D(tex2, fract(varying_texcoord * 100.0)); + gl_FragColor = color * texture2D(al_tex, varying_texcoord); +} diff --git a/allegro/examples/data/ex_shader_multitex_pixel.hlsl b/allegro/examples/data/ex_shader_multitex_pixel.hlsl new file mode 100644 index 00000000..c178928e --- /dev/null +++ b/allegro/examples/data/ex_shader_multitex_pixel.hlsl @@ -0,0 +1,14 @@ +texture al_tex; +sampler2D s1 = sampler_state { + texture = ; +}; +texture tex2; +sampler2D s2 = sampler_state { + texture = ; +}; + +float4 ps_main(VS_OUTPUT Input) : COLOR0 +{ + float4 color = tex2D(s2, frac(Input.TexCoord * 100)); + return color * tex2D(s1, Input.TexCoord); +} diff --git a/allegro/examples/data/ex_shader_pixel.glsl b/allegro/examples/data/ex_shader_pixel.glsl new file mode 100644 index 00000000..d131df5d --- /dev/null +++ b/allegro/examples/data/ex_shader_pixel.glsl @@ -0,0 +1,15 @@ +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D al_tex; +uniform vec3 tint; +varying vec4 varying_color; +varying vec2 varying_texcoord; +void main() +{ + vec4 tmp = varying_color * texture2D(al_tex, varying_texcoord); + tmp.r *= tint.r; + tmp.g *= tint.g; + tmp.b *= tint.b; + gl_FragColor = tmp; +} diff --git a/allegro/examples/data/ex_shader_pixel.hlsl b/allegro/examples/data/ex_shader_pixel.hlsl new file mode 100644 index 00000000..ee50b62a --- /dev/null +++ b/allegro/examples/data/ex_shader_pixel.hlsl @@ -0,0 +1,13 @@ +texture al_tex; +sampler2D s = sampler_state { + texture = ; +}; +float3 tint; +float4 ps_main(VS_OUTPUT Input) : COLOR0 +{ + float4 pixel = tex2D(s, Input.TexCoord.xy); + pixel.r *= tint.r; + pixel.g *= tint.g; + pixel.b *= tint.b; + return pixel; +} diff --git a/allegro/examples/data/ex_shader_vertex.glsl b/allegro/examples/data/ex_shader_vertex.glsl new file mode 100644 index 00000000..dd7f31a7 --- /dev/null +++ b/allegro/examples/data/ex_shader_vertex.glsl @@ -0,0 +1,12 @@ +attribute vec4 al_pos; +attribute vec4 al_color; +attribute vec2 al_texcoord; +uniform mat4 al_projview_matrix; +varying vec4 varying_color; +varying vec2 varying_texcoord; +void main() +{ + varying_color = al_color; + varying_texcoord = al_texcoord; + gl_Position = al_projview_matrix * al_pos; +} diff --git a/allegro/examples/data/ex_shader_vertex.hlsl b/allegro/examples/data/ex_shader_vertex.hlsl new file mode 100644 index 00000000..365a6f78 --- /dev/null +++ b/allegro/examples/data/ex_shader_vertex.hlsl @@ -0,0 +1,23 @@ +struct VS_INPUT +{ + float4 Position : POSITION0; + float2 TexCoord : TEXCOORD0; + float4 Color : TEXCOORD1; +}; +struct VS_OUTPUT +{ + float4 Position : POSITION0; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +float4x4 al_projview_matrix; + +VS_OUTPUT vs_main(VS_INPUT Input) +{ + VS_OUTPUT Output; + Output.Position = mul(Input.Position, al_projview_matrix); + Output.Color = Input.Color; + Output.TexCoord = Input.TexCoord; + return Output; +} diff --git a/allegro/examples/data/ex_ttf.ini b/allegro/examples/data/ex_ttf.ini new file mode 100644 index 00000000..ede65e86 --- /dev/null +++ b/allegro/examples/data/ex_ttf.ini @@ -0,0 +1,19 @@ +# There are problems with UTF-8 string literals under MSVC. +# There appear to be two cases: +# 1. It thinks our source file use the local file encoding. This mostly +# works okay: the UTF-8 strings look like strings in an 8-bit charset and +# will be passed through directly. But in other locales (e.g. East Asian) +# it won't work. +# 2. If we add a UTF-8 byte order mark (signature) then MSVC will recognise +# the source file as UTF-8, but will then try to re-encode the strings +# into the local charset. +# So, unfortunately, for portability to MSVC, we have to externalise UTF-8 +# strings or write them out using escape codes. + +symbols1=■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱ +symbols2=▲△▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◆◇◈◉◊ +symbols3=○◌◍◎●◐◑◒◓◔◕◖◗◘◙ +substr1=«Thís»|you +substr2=should|‘ìş’ +substr3=not|“cøünt”|see +substr4=réstrïçteđ…|this. diff --git a/allegro/examples/data/exconfig.ini b/allegro/examples/data/exconfig.ini new file mode 100644 index 00000000..f2dda8f1 --- /dev/null +++ b/allegro/examples/data/exconfig.ini @@ -0,0 +1,28 @@ +# The ini file consists of sections +# which are marked by [ NAME OF SECTION ] +[graphics] + +# mode: +# width height bits per pixel +mode= 640 480 8 + +# Whether or not the program should run windowed +windowed= TRUE + + +# the actual content of the screen +[content] + +# the header line +headline= Welcome to Allegro +# and it's color in RGB +headercolor= 255 255 255 + +# the image to display +image= mysha.pcx + +# kind of image display +# - 0 : stretch the image to size of screen +# - 1 : center the image on screen +# - 2 : tile the image on screen +display= 0 diff --git a/allegro/examples/data/fakeamp.bmp b/allegro/examples/data/fakeamp.bmp new file mode 100644 index 00000000..d63290eb Binary files /dev/null and b/allegro/examples/data/fakeamp.bmp differ diff --git a/allegro/examples/data/fixed_font.tga b/allegro/examples/data/fixed_font.tga new file mode 100644 index 00000000..bc751239 Binary files /dev/null and b/allegro/examples/data/fixed_font.tga differ diff --git a/allegro/examples/data/font.tga b/allegro/examples/data/font.tga new file mode 100644 index 00000000..552cd9a6 Binary files /dev/null and b/allegro/examples/data/font.tga differ diff --git a/allegro/examples/data/gradient1.bmp b/allegro/examples/data/gradient1.bmp new file mode 100644 index 00000000..b3ee01db Binary files /dev/null and b/allegro/examples/data/gradient1.bmp differ diff --git a/allegro/examples/data/green.png b/allegro/examples/data/green.png new file mode 100644 index 00000000..a7b82d22 Binary files /dev/null and b/allegro/examples/data/green.png differ diff --git a/allegro/examples/data/haiku/air_0.ogg b/allegro/examples/data/haiku/air_0.ogg new file mode 100644 index 00000000..387204bb Binary files /dev/null and b/allegro/examples/data/haiku/air_0.ogg differ diff --git a/allegro/examples/data/haiku/air_1.ogg b/allegro/examples/data/haiku/air_1.ogg new file mode 100644 index 00000000..4dcf8c06 Binary files /dev/null and b/allegro/examples/data/haiku/air_1.ogg differ diff --git a/allegro/examples/data/haiku/air_2.ogg b/allegro/examples/data/haiku/air_2.ogg new file mode 100644 index 00000000..b6fa2bbc Binary files /dev/null and b/allegro/examples/data/haiku/air_2.ogg differ diff --git a/allegro/examples/data/haiku/air_3.ogg b/allegro/examples/data/haiku/air_3.ogg new file mode 100644 index 00000000..02dbb204 Binary files /dev/null and b/allegro/examples/data/haiku/air_3.ogg differ diff --git a/allegro/examples/data/haiku/air_4.ogg b/allegro/examples/data/haiku/air_4.ogg new file mode 100644 index 00000000..ed9a0c10 Binary files /dev/null and b/allegro/examples/data/haiku/air_4.ogg differ diff --git a/allegro/examples/data/haiku/air_5.ogg b/allegro/examples/data/haiku/air_5.ogg new file mode 100644 index 00000000..06d57a70 Binary files /dev/null and b/allegro/examples/data/haiku/air_5.ogg differ diff --git a/allegro/examples/data/haiku/air_6.ogg b/allegro/examples/data/haiku/air_6.ogg new file mode 100644 index 00000000..81767ab1 Binary files /dev/null and b/allegro/examples/data/haiku/air_6.ogg differ diff --git a/allegro/examples/data/haiku/air_7.ogg b/allegro/examples/data/haiku/air_7.ogg new file mode 100644 index 00000000..58ea769b Binary files /dev/null and b/allegro/examples/data/haiku/air_7.ogg differ diff --git a/allegro/examples/data/haiku/air_effect.png b/allegro/examples/data/haiku/air_effect.png new file mode 100644 index 00000000..23d2d593 Binary files /dev/null and b/allegro/examples/data/haiku/air_effect.png differ diff --git a/allegro/examples/data/haiku/black_bead_opaque_A.png b/allegro/examples/data/haiku/black_bead_opaque_A.png new file mode 100644 index 00000000..72476cdb Binary files /dev/null and b/allegro/examples/data/haiku/black_bead_opaque_A.png differ diff --git a/allegro/examples/data/haiku/dropshadow.png b/allegro/examples/data/haiku/dropshadow.png new file mode 100644 index 00000000..ea8a6aab Binary files /dev/null and b/allegro/examples/data/haiku/dropshadow.png differ diff --git a/allegro/examples/data/haiku/earth4.png b/allegro/examples/data/haiku/earth4.png new file mode 100644 index 00000000..c76776bd Binary files /dev/null and b/allegro/examples/data/haiku/earth4.png differ diff --git a/allegro/examples/data/haiku/earth_0.ogg b/allegro/examples/data/haiku/earth_0.ogg new file mode 100644 index 00000000..cb795c15 Binary files /dev/null and b/allegro/examples/data/haiku/earth_0.ogg differ diff --git a/allegro/examples/data/haiku/earth_1.ogg b/allegro/examples/data/haiku/earth_1.ogg new file mode 100644 index 00000000..20ea069f Binary files /dev/null and b/allegro/examples/data/haiku/earth_1.ogg differ diff --git a/allegro/examples/data/haiku/earth_2.ogg b/allegro/examples/data/haiku/earth_2.ogg new file mode 100644 index 00000000..3b8b88c6 Binary files /dev/null and b/allegro/examples/data/haiku/earth_2.ogg differ diff --git a/allegro/examples/data/haiku/earth_3.ogg b/allegro/examples/data/haiku/earth_3.ogg new file mode 100644 index 00000000..51d93455 Binary files /dev/null and b/allegro/examples/data/haiku/earth_3.ogg differ diff --git a/allegro/examples/data/haiku/earth_4.ogg b/allegro/examples/data/haiku/earth_4.ogg new file mode 100644 index 00000000..176a82b9 Binary files /dev/null and b/allegro/examples/data/haiku/earth_4.ogg differ diff --git a/allegro/examples/data/haiku/earth_5.ogg b/allegro/examples/data/haiku/earth_5.ogg new file mode 100644 index 00000000..ee640fb2 Binary files /dev/null and b/allegro/examples/data/haiku/earth_5.ogg differ diff --git a/allegro/examples/data/haiku/earth_6.ogg b/allegro/examples/data/haiku/earth_6.ogg new file mode 100644 index 00000000..62bffbf0 Binary files /dev/null and b/allegro/examples/data/haiku/earth_6.ogg differ diff --git a/allegro/examples/data/haiku/earth_7.ogg b/allegro/examples/data/haiku/earth_7.ogg new file mode 100644 index 00000000..858637b0 Binary files /dev/null and b/allegro/examples/data/haiku/earth_7.ogg differ diff --git a/allegro/examples/data/haiku/fire.png b/allegro/examples/data/haiku/fire.png new file mode 100644 index 00000000..63ad571c Binary files /dev/null and b/allegro/examples/data/haiku/fire.png differ diff --git a/allegro/examples/data/haiku/fire_0.ogg b/allegro/examples/data/haiku/fire_0.ogg new file mode 100644 index 00000000..d9f9e314 Binary files /dev/null and b/allegro/examples/data/haiku/fire_0.ogg differ diff --git a/allegro/examples/data/haiku/fire_1.ogg b/allegro/examples/data/haiku/fire_1.ogg new file mode 100644 index 00000000..a5791d68 Binary files /dev/null and b/allegro/examples/data/haiku/fire_1.ogg differ diff --git a/allegro/examples/data/haiku/fire_2.ogg b/allegro/examples/data/haiku/fire_2.ogg new file mode 100644 index 00000000..7bee537d Binary files /dev/null and b/allegro/examples/data/haiku/fire_2.ogg differ diff --git a/allegro/examples/data/haiku/fire_3.ogg b/allegro/examples/data/haiku/fire_3.ogg new file mode 100644 index 00000000..adc748fc Binary files /dev/null and b/allegro/examples/data/haiku/fire_3.ogg differ diff --git a/allegro/examples/data/haiku/fire_4.ogg b/allegro/examples/data/haiku/fire_4.ogg new file mode 100644 index 00000000..8442dd38 Binary files /dev/null and b/allegro/examples/data/haiku/fire_4.ogg differ diff --git a/allegro/examples/data/haiku/fire_5.ogg b/allegro/examples/data/haiku/fire_5.ogg new file mode 100644 index 00000000..752449f3 Binary files /dev/null and b/allegro/examples/data/haiku/fire_5.ogg differ diff --git a/allegro/examples/data/haiku/fire_6.ogg b/allegro/examples/data/haiku/fire_6.ogg new file mode 100644 index 00000000..c59cfc44 Binary files /dev/null and b/allegro/examples/data/haiku/fire_6.ogg differ diff --git a/allegro/examples/data/haiku/fire_7.ogg b/allegro/examples/data/haiku/fire_7.ogg new file mode 100644 index 00000000..4fc346aa Binary files /dev/null and b/allegro/examples/data/haiku/fire_7.ogg differ diff --git a/allegro/examples/data/haiku/flame2.png b/allegro/examples/data/haiku/flame2.png new file mode 100644 index 00000000..d78481b7 Binary files /dev/null and b/allegro/examples/data/haiku/flame2.png differ diff --git a/allegro/examples/data/haiku/healthy_glow.png b/allegro/examples/data/haiku/healthy_glow.png new file mode 100644 index 00000000..efee4a65 Binary files /dev/null and b/allegro/examples/data/haiku/healthy_glow.png differ diff --git a/allegro/examples/data/haiku/main_flame2.png b/allegro/examples/data/haiku/main_flame2.png new file mode 100644 index 00000000..e79ca015 Binary files /dev/null and b/allegro/examples/data/haiku/main_flame2.png differ diff --git a/allegro/examples/data/haiku/overlay_pretty.png b/allegro/examples/data/haiku/overlay_pretty.png new file mode 100644 index 00000000..f8b257cb Binary files /dev/null and b/allegro/examples/data/haiku/overlay_pretty.png differ diff --git a/allegro/examples/data/haiku/select.ogg b/allegro/examples/data/haiku/select.ogg new file mode 100644 index 00000000..444fae37 Binary files /dev/null and b/allegro/examples/data/haiku/select.ogg differ diff --git a/allegro/examples/data/haiku/water.png b/allegro/examples/data/haiku/water.png new file mode 100644 index 00000000..8bc6a080 Binary files /dev/null and b/allegro/examples/data/haiku/water.png differ diff --git a/allegro/examples/data/haiku/water_0.ogg b/allegro/examples/data/haiku/water_0.ogg new file mode 100644 index 00000000..2913d51c Binary files /dev/null and b/allegro/examples/data/haiku/water_0.ogg differ diff --git a/allegro/examples/data/haiku/water_1.ogg b/allegro/examples/data/haiku/water_1.ogg new file mode 100644 index 00000000..acccff4c Binary files /dev/null and b/allegro/examples/data/haiku/water_1.ogg differ diff --git a/allegro/examples/data/haiku/water_2.ogg b/allegro/examples/data/haiku/water_2.ogg new file mode 100644 index 00000000..0007bd31 Binary files /dev/null and b/allegro/examples/data/haiku/water_2.ogg differ diff --git a/allegro/examples/data/haiku/water_3.ogg b/allegro/examples/data/haiku/water_3.ogg new file mode 100644 index 00000000..ad1b0c2c Binary files /dev/null and b/allegro/examples/data/haiku/water_3.ogg differ diff --git a/allegro/examples/data/haiku/water_4.ogg b/allegro/examples/data/haiku/water_4.ogg new file mode 100644 index 00000000..8471058a Binary files /dev/null and b/allegro/examples/data/haiku/water_4.ogg differ diff --git a/allegro/examples/data/haiku/water_5.ogg b/allegro/examples/data/haiku/water_5.ogg new file mode 100644 index 00000000..5c29e9c3 Binary files /dev/null and b/allegro/examples/data/haiku/water_5.ogg differ diff --git a/allegro/examples/data/haiku/water_6.ogg b/allegro/examples/data/haiku/water_6.ogg new file mode 100644 index 00000000..fb40145c Binary files /dev/null and b/allegro/examples/data/haiku/water_6.ogg differ diff --git a/allegro/examples/data/haiku/water_7.ogg b/allegro/examples/data/haiku/water_7.ogg new file mode 100644 index 00000000..dfcbe730 Binary files /dev/null and b/allegro/examples/data/haiku/water_7.ogg differ diff --git a/allegro/examples/data/haiku/water_droplets.png b/allegro/examples/data/haiku/water_droplets.png new file mode 100644 index 00000000..e5978746 Binary files /dev/null and b/allegro/examples/data/haiku/water_droplets.png differ diff --git a/allegro/examples/data/haiku/wind3.png b/allegro/examples/data/haiku/wind3.png new file mode 100644 index 00000000..2104ab57 Binary files /dev/null and b/allegro/examples/data/haiku/wind3.png differ diff --git a/allegro/examples/data/icon.png b/allegro/examples/data/icon.png new file mode 100644 index 00000000..b7b0fcfc Binary files /dev/null and b/allegro/examples/data/icon.png differ diff --git a/allegro/examples/data/icon.tga b/allegro/examples/data/icon.tga new file mode 100644 index 00000000..768ef06d Binary files /dev/null and b/allegro/examples/data/icon.tga differ diff --git a/allegro/examples/data/mask.pcx b/allegro/examples/data/mask.pcx new file mode 100644 index 00000000..032b3013 Binary files /dev/null and b/allegro/examples/data/mask.pcx differ diff --git a/allegro/examples/data/mysha.pcx b/allegro/examples/data/mysha.pcx new file mode 100644 index 00000000..1225b4cf Binary files /dev/null and b/allegro/examples/data/mysha.pcx differ diff --git a/allegro/examples/data/mysha.tga b/allegro/examples/data/mysha.tga new file mode 100644 index 00000000..81495c72 Binary files /dev/null and b/allegro/examples/data/mysha.tga differ diff --git a/allegro/examples/data/mysha256x256.png b/allegro/examples/data/mysha256x256.png new file mode 100644 index 00000000..7f403938 Binary files /dev/null and b/allegro/examples/data/mysha256x256.png differ diff --git a/allegro/examples/data/mysha256x256.webp b/allegro/examples/data/mysha256x256.webp new file mode 100644 index 00000000..ad7bf2d2 Binary files /dev/null and b/allegro/examples/data/mysha256x256.webp differ diff --git a/allegro/examples/data/mysha_dxt1.dds b/allegro/examples/data/mysha_dxt1.dds new file mode 100644 index 00000000..d632ed8e Binary files /dev/null and b/allegro/examples/data/mysha_dxt1.dds differ diff --git a/allegro/examples/data/mysha_dxt3.dds b/allegro/examples/data/mysha_dxt3.dds new file mode 100644 index 00000000..d8e958dd Binary files /dev/null and b/allegro/examples/data/mysha_dxt3.dds differ diff --git a/allegro/examples/data/mysha_dxt5.dds b/allegro/examples/data/mysha_dxt5.dds new file mode 100644 index 00000000..850a238b Binary files /dev/null and b/allegro/examples/data/mysha_dxt5.dds differ diff --git a/allegro/examples/data/mysha_pal.png b/allegro/examples/data/mysha_pal.png new file mode 100644 index 00000000..ef8df690 Binary files /dev/null and b/allegro/examples/data/mysha_pal.png differ diff --git a/allegro/examples/data/obp.jpg b/allegro/examples/data/obp.jpg new file mode 100644 index 00000000..e6441c79 Binary files /dev/null and b/allegro/examples/data/obp.jpg differ diff --git a/allegro/examples/data/planet.pcx b/allegro/examples/data/planet.pcx new file mode 100644 index 00000000..14926119 Binary files /dev/null and b/allegro/examples/data/planet.pcx differ diff --git a/allegro/examples/data/sample.cfg b/allegro/examples/data/sample.cfg new file mode 100644 index 00000000..cf6b73e0 --- /dev/null +++ b/allegro/examples/data/sample.cfg @@ -0,0 +1,22 @@ +# Comments and blank lines should be preserved when this file is written back +# out. + + # Whoa. + +old_var = old global value + +# a long value +mysha.xpm = /* XPM */ static char * mysha_xpm[] = { "40 25 16 1", " c #0B0B0C", ". c #302837", "+ c #362D47", "@ c #38303F", "# c #402E46", "$ c #323345", "% c #453335", "& c #3A3A43", "* c #443B4B", "= c #57525A", "- c #7E6676", "; c #6F6B71", "> c #938C97", ", c #B6B0C0", "' c #C9CBDA", ") c #DEE1EE", "$@@@$$@+@@@@@+@@@@+@@@@@@#@@$&$@$+++....", "$@@@@@+@@@$$+$@@@+++@@@@@$@@@@@@+@++.++.", "@@@@@@@+&@@&$+@@@@@@@@+++++@@@+@+$$$++..", "@@+@+@+##++++@$#++$@+@@@@++@#@@@$@$++@..", "++++@@$#+&@*#*#**###@@+++++@@@@@@++.#++.", "+@@@@@&#&&***;,,,,>;=,->;@+@@@@@@@#@+##+", "+++#+$***,,>'))))))',;;->+@@+$@@@$$+#.++", "+++$+$*#>,,>'))')'',>-->>*#@@@$@@@@@++++", "*#*$$***',,>''))))),>-->>>=*@@@@+###@+$+", "$*&$**;)',>,')))))''>-->>>>*@@@@+@$$$$.+", "+$#$*=))',,')))))',,>-;>>>>>*+@&@@$@@.+$", "****=,)))','))))',>>;;;;>;;;*++@+@@+@@++", "$***;')))'')'')',-@>-==;;;;==&@++++@$$&$", "***=;'))))''%''',% ;;===;;&==&##+@@@++@$", "****>'')))''''',,>>>;==&;;=&%&+@++#@@+@@", "**#*;,')''',,,,>>>;;===;;=%%&&@@@+@@@#@$", "*****,'''',>,,>>=;*=======*=&@@@@@@@@++$", "=;>*&>,',>,,>>-*--=========%%@+++++@@@@@", ">>>=*=>,,>,,>--;*=;=======& %@+@+++@@+@@", " ..;->>>>;-==;==== == @@@++@@+@+$", " & =>-;;==& ** ", " *;==&. @ ", " =&% . ", " *% ", " "}; + +[section] +# Comment inside the section. +old_var = old section value + +# UTF8 in section names, key names and values. +[adição] +€=¿ + +# The following line contains spaces but will probably be trimmed when +# written back out. + +# Final line. diff --git a/allegro/examples/data/texture.tga b/allegro/examples/data/texture.tga new file mode 100644 index 00000000..f4e8358a Binary files /dev/null and b/allegro/examples/data/texture.tga differ diff --git a/allegro/examples/data/welcome.voc b/allegro/examples/data/welcome.voc new file mode 100644 index 00000000..9ca9012c Binary files /dev/null and b/allegro/examples/data/welcome.voc differ diff --git a/allegro/examples/data/welcome.wav b/allegro/examples/data/welcome.wav new file mode 100644 index 00000000..23555b3d Binary files /dev/null and b/allegro/examples/data/welcome.wav differ diff --git a/allegro/examples/enet_common.h b/allegro/examples/enet_common.h new file mode 100644 index 00000000..4b56b4f9 --- /dev/null +++ b/allegro/examples/enet_common.h @@ -0,0 +1,48 @@ +#ifndef ENET_COMMON_H +#define ENET_COMMON_H + +#include + +#define SCREEN_W 640 +#define SCREEN_H 480 + +#define FPS 30 // framerate +#define PLAYER_SIZE 16 // radius of player circle +#define PLAYER_SPEED 200 // movement rate of player in pixels/sec +#define MAX_PLAYER_COUNT 32 +#define DEFAULT_PORT 9234 + +typedef enum +{ + PLAYER_JOIN, + PLAYER_LEAVE, + POSITION_UPDATE, +} MESSAGE_TYPE; + +// message sent from client to server +typedef struct +{ + int x; // requested x movement (-1, 0, or 1) + int y; // requested y movement (-1, 0, or 1) +} ClientMessage; + +// message sent from server to client +typedef struct +{ + int player_id; + MESSAGE_TYPE type; + int x; // current position (x) + int y; // current position (y) + ALLEGRO_COLOR color; // valid when type == PLAYER_JOIN +} ServerMessage; + +// storage for all players +struct +{ + bool active; + int x, y; // current position + int dx, dy; // direction of movemnt + ALLEGRO_COLOR color; +} players[MAX_PLAYER_COUNT]; + +#endif diff --git a/allegro/examples/ex_acodec.c b/allegro/examples/ex_acodec.c new file mode 100644 index 00000000..3b1b394d --- /dev/null +++ b/allegro/examples/ex_acodec.c @@ -0,0 +1,146 @@ +/* + * Ryan Dickie + * Audio example that loads a series of files and puts them through the mixer. + * Originlly derived from the audio example on the wiki. + */ + +#define ALLEGRO_UNSTABLE + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_VOICE *voice; + ALLEGRO_MIXER *mixer; + ALLEGRO_SAMPLE_INSTANCE *sample; + int i; + char const **filenames; + int n; + + if (argc < 2) { + n = 1; + filenames = malloc(sizeof *filenames); + filenames[0] = "data/welcome.wav"; + } + else { + n = argc - 1; + filenames = malloc(sizeof *filenames * n); + for (i = 1; i < argc; ++i) { + filenames[i - 1] = argv[i]; + } + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_init_acodec_addon(); + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + + voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, + ALLEGRO_CHANNEL_CONF_2); + if (!voice) { + abort_example("Could not create ALLEGRO_VOICE.\n"); + } + + mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); + if (!mixer) { + abort_example("al_create_mixer failed.\n"); + } + + if (!al_attach_mixer_to_voice(mixer, voice)) { + abort_example("al_attach_mixer_to_voice failed.\n"); + } + + sample = al_create_sample_instance(NULL); + if (!sample) { + abort_example("al_create_sample failed.\n"); + } + + for (i = 0; i < n; ++i) { + ALLEGRO_SAMPLE *sample_data = NULL; + const char *filename = filenames[i]; + float sample_time = 0; + /* A matrix that puts everything in the left channel. */ + float mono_to_stereo[] = {1.0, 0.0}; + + /* Load the entire sound file from disk. */ + sample_data = al_load_sample(filename); + if (!sample_data) { + abort_example("Could not load sample from '%s'!\n", + filename); + continue; + } + + if (!al_set_sample(sample, sample_data)) { + abort_example("al_set_sample_instance_ptr failed.\n"); + continue; + } + + if (!al_attach_sample_instance_to_mixer(sample, mixer)) { + abort_example("al_attach_sample_instance_to_mixer failed.\n"); + goto done; + } + + /* Play sample in looping mode. */ + al_set_sample_instance_playmode(sample, ALLEGRO_PLAYMODE_LOOP); + al_play_sample_instance(sample); + + sample_time = al_get_sample_instance_time(sample); + log_printf("Playing '%s' (%.3f seconds) normally.\n", filename, + sample_time); + + al_rest(sample_time); + + if (al_get_channel_count(al_get_sample_instance_channels(sample)) == 1) { + if (!al_set_sample_instance_channel_matrix(sample, mono_to_stereo)) { + abort_example("Failed to set channel matrix.\n"); + } + log_printf("Playing left channel only.\n"); + al_rest(sample_time); + } + + if (!al_set_sample_instance_gain(sample, 0.5)) { + abort_example("Failed to set gain.\n"); + } + log_printf("Playing with gain 0.5.\n"); + al_rest(sample_time); + + if (!al_set_sample_instance_gain(sample, 0.25)) { + abort_example("Failed to set gain.\n"); + } + log_printf("Playing with gain 0.25.\n"); + al_rest(sample_time); + + al_stop_sample_instance(sample); + log_printf("Done playing '%s'\n", filename); + + /* Free the memory allocated. */ + al_set_sample(sample, NULL); + al_destroy_sample(sample_data); + } + + al_destroy_sample_instance(sample); + al_destroy_mixer(mixer); + al_destroy_voice(voice); + + al_uninstall_audio(); + +done: + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_acodec_multi.c b/allegro/examples/ex_acodec_multi.c new file mode 100644 index 00000000..1b88c3c7 --- /dev/null +++ b/allegro/examples/ex_acodec_multi.c @@ -0,0 +1,139 @@ +/* + * Milan Mimica + * Audio example that plays multiple files at the same time + * Originlly derived from the ex_acodec example. + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" + +#include "common.c" + +char *default_files[] = {NULL, "data/welcome.voc", + "data/haiku/earth_0.ogg", "data/haiku/water_0.ogg", + "data/haiku/fire_0.ogg", "data/haiku/air_0.ogg"}; + +int main(int argc, char **argv) +{ + int i; + ALLEGRO_SAMPLE **sample_data; + ALLEGRO_SAMPLE_INSTANCE **sample; + ALLEGRO_MIXER *mixer; + ALLEGRO_VOICE *voice; + float longest_sample; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + if (argc < 2) { + log_printf("This example can be run from the command line.\nUsage: %s {audio_files}\n", argv[0]); + argv = default_files; + argc = 6; + } + + al_init_acodec_addon(); + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + + sample = malloc(argc * sizeof(*sample)); + if (!sample) { + abort_example("Out of memory!\n"); + } + + sample_data = malloc(argc * sizeof(*sample_data)); + if (!sample_data) { + abort_example("Out of memory!\n"); + } + + /* a voice is used for playback */ + voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, + ALLEGRO_CHANNEL_CONF_2); + if (!voice) { + abort_example("Could not create ALLEGRO_VOICE from sample\n"); + } + + mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); + if (!mixer) { + abort_example("al_create_mixer failed.\n"); + } + + if (!al_attach_mixer_to_voice(mixer, voice)) { + abort_example("al_attach_mixer_to_voice failed.\n"); + } + + for (i = 1; i < argc; ++i) { + const char *filename = argv[i]; + + sample[i] = NULL; + + /* loads the entire sound file from disk into sample data */ + sample_data[i] = al_load_sample(filename); + if (!sample_data[i]) { + abort_example("Could not load sample from '%s'!\n", filename); + } + + sample[i] = al_create_sample_instance(sample_data[i]); + if (!sample[i]) { + log_printf("Could not create sample!\n"); + al_destroy_sample(sample_data[i]); + sample_data[i] = NULL; + continue; + } + + if (!al_attach_sample_instance_to_mixer(sample[i], mixer)) { + log_printf("al_attach_sample_instance_to_mixer failed.\n"); + continue; + } + } + + longest_sample = 0; + + for (i = 1; i < argc; ++i) { + const char *filename = argv[i]; + float sample_time; + + if (!sample[i]) + continue; + + /* play each sample once */ + al_play_sample_instance(sample[i]); + + sample_time = al_get_sample_instance_time(sample[i]); + log_printf("Playing '%s' (%.3f seconds)\n", filename, sample_time); + + if (sample_time > longest_sample) + longest_sample = sample_time; + } + + al_rest(longest_sample); + + log_printf("Done\n"); + + for (i = 1; i < argc; ++i) { + /* free the memory allocated when creating the sample + voice */ + if (sample[i]) { + al_stop_sample_instance(sample[i]); + al_destroy_sample_instance(sample[i]); + al_destroy_sample(sample_data[i]); + } + } + al_destroy_mixer(mixer); + al_destroy_voice(voice); + + free(sample); + free(sample_data); + + al_uninstall_audio(); + + close_log(true); + + return 0; +} diff --git a/allegro/examples/ex_android.c b/allegro/examples/ex_android.c new file mode 100644 index 00000000..69804383 --- /dev/null +++ b/allegro/examples/ex_android.c @@ -0,0 +1,242 @@ +#include +#include +#include +#ifdef ALLEGRO_ANDROID +#include /* al_android_set_apk_file_interface */ +#endif + +ALLEGRO_DEBUG_CHANNEL("main") + +#define MAX_TOUCH 10 + +struct touch { + bool down; + double x, y; +} touch[MAX_TOUCH]; + +/* debugging */ +#define print_standard_path(std) \ + do { \ + ALLEGRO_PATH *path = al_get_standard_path(std); \ + ALLEGRO_DEBUG(#std ": %s", al_path_cstr(path, '/')); \ + } while (0) + +static void print_standard_paths(void) +{ + print_standard_path(ALLEGRO_RESOURCES_PATH); + print_standard_path(ALLEGRO_TEMP_PATH); + print_standard_path(ALLEGRO_USER_DATA_PATH); + print_standard_path(ALLEGRO_USER_HOME_PATH); + print_standard_path(ALLEGRO_USER_SETTINGS_PATH); + print_standard_path(ALLEGRO_USER_DOCUMENTS_PATH); + print_standard_path(ALLEGRO_EXENAME_PATH); +} + +static void draw_touches(void) +{ + int i; + + for (i = 0; i < MAX_TOUCH; i++) { + if (touch[i].down) { + al_draw_filled_rectangle( + touch[i].x-40, touch[i].y-40, + touch[i].x+40, touch[i].y+40, + al_map_rgb(100+i*20, 40+i*20, 40+i*20)); + } + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *dpy; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + ALLEGRO_TIMER *timer; + ALLEGRO_BITMAP *image; + ALLEGRO_BITMAP *image2; + + (void) argc; + (void) argv; + + ALLEGRO_DEBUG("init allegro!"); + if (!al_init()) { + return 1; + } + + ALLEGRO_DEBUG("init primitives"); + al_init_primitives_addon(); + + ALLEGRO_DEBUG("init image addon"); + al_init_image_addon(); + + ALLEGRO_DEBUG("init touch input"); + al_install_touch_input(); + + ALLEGRO_DEBUG("init keyboard"); + al_install_keyboard(); + + ALLEGRO_DEBUG("creating display"); + dpy = al_create_display(800, 480); + if (!dpy) { + ALLEGRO_ERROR("failed to create display!"); + return 1; + } + + print_standard_paths(); + + /* This is loaded from assets in the apk. */ + #ifdef ALLEGRO_ANDROID + al_android_set_apk_file_interface(); + #endif + image = al_load_bitmap("data/alexlogo.png"); + if (!image) { + ALLEGRO_DEBUG("failed to load alexlogo.png"); + return 1; + } + + #ifdef ALLEGRO_ANDROID + /* Copy the .png from the .apk into the user data area. */ + ALLEGRO_FILE *fin = al_fopen("data/alexlogo.png", "rb"); + al_set_standard_file_interface(); + ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_DATA_PATH); + al_set_path_filename(path, "alexlogo.png"); + ALLEGRO_FILE *fout = al_fopen(al_path_cstr(path, '/'), "wb"); + while (!al_feof(fin)) { + char buf[1024]; + int n = al_fread(fin, buf, 1024); + al_fwrite(fout, buf, n); + } + al_fclose(fin); + al_fclose(fout); + + /* This is now loaded with the normal stdio file interface and not + * from the APK. + */ + image2 = al_load_bitmap(al_path_cstr(path, '/')); + + al_destroy_path(path); + #else + image2 = image; + #endif + + + al_convert_mask_to_alpha(image, al_map_rgb(255,0,255)); + if (image2) + al_convert_mask_to_alpha(image2, al_map_rgb(255,0,255)); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_display_event_source(dpy)); + al_register_event_source(queue, al_get_touch_input_event_source()); + al_register_event_source(queue, al_get_keyboard_event_source()); + + timer = al_create_timer(1/60.0); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + bool draw = true; + bool running = true; + int count = 0; + + while (running) { + al_wait_for_event(queue, &event); + + switch (event.type) { + case ALLEGRO_EVENT_TOUCH_BEGIN: + //ALLEGRO_DEBUG("touch %i begin", event.touch.id); + touch[event.touch.id].down = true; + touch[event.touch.id].x = event.touch.x; + touch[event.touch.id].y = event.touch.y; + break; + + case ALLEGRO_EVENT_TOUCH_END: + //ALLEGRO_DEBUG("touch %i end", event.touch.id); + touch[event.touch.id].down = false; + touch[event.touch.id].x = 0.0; + touch[event.touch.id].y = 0.0; + break; + + case ALLEGRO_EVENT_TOUCH_MOVE: + //ALLEGRO_DEBUG("touch %i move: %fx%f", event.touch.id, event.touch.x, event.touch.y); + touch[event.touch.id].x = event.touch.x; + touch[event.touch.id].y = event.touch.y; + break; + + case ALLEGRO_EVENT_TOUCH_CANCEL: + //ALLEGRO_DEBUG("touch %i canceled", event.touch.id); + break; + + case ALLEGRO_EVENT_KEY_UP: + if (event.keyboard.keycode == ALLEGRO_KEY_BACK) { + ALLEGRO_DEBUG("back key pressed, exit!"); + running = false; + } + else { + ALLEGRO_DEBUG("%i key pressed", event.keyboard.keycode); + } + break; + + case ALLEGRO_EVENT_TIMER: + draw = true; + if (count == 60) { + ALLEGRO_DEBUG("tick"); + count = 0; + } + count++; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + ALLEGRO_DEBUG("display close"); + running = false; + break; + + case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: + ALLEGRO_DEBUG("halt drawing"); + // Stop the timer so we don't run at all while our display isn't + // active. + al_stop_timer(timer); + ALLEGRO_DEBUG("after set target"); + draw = false; + al_acknowledge_drawing_halt(dpy); + break; + + case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: + ALLEGRO_DEBUG("resume drawing"); + + al_acknowledge_drawing_resume(dpy); + ALLEGRO_DEBUG("done waiting for surface recreated"); + + al_start_timer(timer); + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + ALLEGRO_DEBUG("display resize"); + al_acknowledge_resize(dpy); + ALLEGRO_DEBUG("done resize"); + break; + } + + if (draw && al_event_queue_is_empty(queue)) { + draw = false; + al_clear_to_color(al_map_rgb(255, 255, 255)); + if (image) { + al_draw_bitmap(image, + al_get_display_width(dpy)/2 - al_get_bitmap_width(image)/2, + al_get_display_height(dpy)/2 - al_get_bitmap_height(image)/2, + 0); + } + if (image2) { + al_draw_bitmap(image2, + al_get_display_width(dpy)/2 - al_get_bitmap_width(image)/2, + al_get_display_height(dpy)/2 + al_get_bitmap_height(image)/2, + 0); + } + draw_touches(); + al_flip_display(); + } + } + + ALLEGRO_DEBUG("done"); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_audio_chain.cpp b/allegro/examples/ex_audio_chain.cpp new file mode 100644 index 00000000..b1581e3e --- /dev/null +++ b/allegro/examples/ex_audio_chain.cpp @@ -0,0 +1,1024 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * Demonstrate the audio addons. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.c" + +#define DISP_W 800 +#define DISP_H 600 + +using namespace std; + +class Element; +class Voice; +class Mixer; +class SampleInstance; +class Sample; +class Audiostream; + +struct Context { + ALLEGRO_FONT *font; + ALLEGRO_COLOR bg; + ALLEGRO_COLOR fg; + ALLEGRO_COLOR fill; + ALLEGRO_COLOR disabled; + ALLEGRO_COLOR highlight; +}; + +class Element { +public: + Element(); + virtual ~Element() {}; + void set_pos(int x, int y); + void set_random_pos(); + bool attach(Element *elt); + bool detach(); + bool is_attached_to(Element const *elt); + virtual bool is_playing() const = 0; + virtual bool toggle_playing() = 0; + virtual float get_gain() const = 0; + virtual bool adjust_gain(float d) = 0; + void draw(Context const& ctx, bool highlight) const; + void draw_arrow(Context const& ctx, float px, float py, bool highlight) const; + void move_by(int dx, int dy); + bool contains(int x, int y) const; + void output_point(float & ox, float & oy) const; + void input_point(float & ox, float & oy) const; + virtual char const *get_label() const = 0; + + typedef vector::iterator iter; + +protected: + int x, y, w, h; + +private: + virtual bool do_attach(Mixer & mixer); + virtual bool do_attach(SampleInstance & spl); + virtual bool do_attach(Audiostream & stream); + virtual bool do_detach() = 0; + void set_attached_to(Element const *elt); + + Element const *attached_to; +}; + +class Voice : public Element { +public: + Voice(); + ~Voice(); + bool valid() const; + bool is_playing() const; + bool toggle_playing(); + float get_gain() const; + bool adjust_gain(float d); + char const *get_label() const; +private: + bool do_attach(Mixer & mixer); + bool do_attach(SampleInstance & spl); + bool do_attach(Audiostream & stream); + bool do_detach(); + + ALLEGRO_VOICE *voice; +}; + +class Mixer : public Element { +public: + Mixer(); + ~Mixer(); + operator ALLEGRO_MIXER *() const { return mixer; } + bool is_playing() const; + bool toggle_playing(); + float get_gain() const; + bool adjust_gain(float d); + char const *get_label() const; +private: + bool do_attach(Mixer & mixer); + bool do_attach(SampleInstance & spl); + bool do_attach(Audiostream & stream); + bool do_detach(); + + ALLEGRO_MIXER *mixer; +}; + +class SampleInstance : public Element { +public: + SampleInstance(); + ~SampleInstance(); + operator ALLEGRO_SAMPLE_INSTANCE *() const { return splinst; } + bool is_playing() const; + bool toggle_playing(); + float get_gain() const; + bool adjust_gain(float d); + char const *get_label() const; + bool set_sample(Sample const & wav); +private: + bool do_detach(); + + ALLEGRO_SAMPLE_INSTANCE *splinst; + Sample const *spl; + unsigned pos; +}; + +class Sample { +public: + Sample(char const *filename); + ~Sample(); + operator ALLEGRO_SAMPLE *() const { return spl; } + bool valid() const; + string const& get_filename() const; +private: + ALLEGRO_SAMPLE *spl; + string filename; +}; + +class Audiostream : public Element { +public: + Audiostream(string const& filename); + ~Audiostream(); + operator ALLEGRO_AUDIO_STREAM *() const { return stream; } + bool valid() const; + bool is_playing() const; + bool toggle_playing(); + float get_gain() const; + bool adjust_gain(float d); + char const *get_label() const; +private: + bool do_detach(); + + ALLEGRO_AUDIO_STREAM *stream; + string filename; +}; + +/*---------------------------------------------------------------------------*/ + +static ALLEGRO_PATH *make_path(char const *str) +{ + static ALLEGRO_PATH *dir; + ALLEGRO_PATH *path; + + if (!dir) { + dir = al_get_standard_path(ALLEGRO_RESOURCES_PATH); +#ifdef ALLEGRO_MSVC + { + /* Hack to cope automatically with MSVC workspaces. */ + const char *last = al_get_path_component(dir, -1); + if (0 == strcmp(last, "Debug") + || 0 == strcmp(last, "RelWithDebInfo") + || 0 == strcmp(last, "Release") + || 0 == strcmp(last, "Profile")) { + al_remove_path_component(dir, -1); + } + } +#endif + } + + path = al_create_path(str); + al_rebase_path(dir, path); + return path; +} + +static void basename(const string & filename, string & out) +{ + size_t pos = filename.find_last_of("/"); + if (pos != string::npos) + out = filename.substr(pos + 1); + else + out = filename; +} + +static float clamp(float lo, float mid, float hi) +{ + if (mid < lo) + return lo; + if (mid > hi) + return hi; + return mid; +} + +/*---------------------------------------------------------------------------*/ + +Element::Element() : x(0), y(0), w(40), h(40), attached_to(0) +{ +} + +void Element::set_pos(int x, int y) +{ + this->x = x; + this->y = y; +} + +void Element::set_random_pos() +{ + /* Could be smarter. */ + x = rand() % (DISP_W - w); + y = rand() % (DISP_H - h); +} + +bool Element::attach(Element *elt) +{ + Mixer *mixer; + SampleInstance *splinst; + Audiostream *stream; + bool rc = false; + + if ((mixer = dynamic_cast(elt))) { + rc = do_attach(*mixer); + } + else if ((splinst = dynamic_cast(elt))) { + rc = do_attach(*splinst); + } + else if ((stream = dynamic_cast(elt))) { + rc = do_attach(*stream); + } + if (rc) { + elt->set_attached_to(this); + } + return rc; +} + +bool Element::do_attach(Mixer & other) +{ + (void)other; + return false; +} + +bool Element::do_attach(SampleInstance & other) +{ + (void)other; + return false; +} + +bool Element::do_attach(Audiostream & other) +{ + (void)other; + return false; +} + +bool Element::detach() +{ + bool rc = attached_to && do_detach(); + if (rc) { + attached_to = NULL; + } + return rc; +} + +void Element::set_attached_to(Element const *attached_to) +{ + this->attached_to = attached_to; +} + +bool Element::is_attached_to(Element const *elt) +{ + return attached_to == elt; +} + +void Element::draw(Context const& ctx, bool highlight) const +{ + if (attached_to) { + float x2, y2; + attached_to->input_point(x2, y2); + draw_arrow(ctx, x2, y2, highlight); + } + + ALLEGRO_COLOR textcol = ctx.fg; + ALLEGRO_COLOR boxcol = ctx.fg; + if (highlight) + boxcol = ctx.highlight; + if (!is_playing()) + textcol = ctx.disabled; + + float rad = 7.0; + al_draw_filled_rounded_rectangle(x+0.5, y+0.5, x+w-0.5, y+h-0.5, rad, rad, ctx.fill); + al_draw_rounded_rectangle(x+0.5, y+0.5, x+w-0.5, y+h-0.5, rad, rad, boxcol, 1.0); + + float th = al_get_font_line_height(ctx.font); + al_draw_text(ctx.font, textcol, x + w/2, y + h/2 - th/2, + ALLEGRO_ALIGN_CENTRE, get_label()); + + float gain = get_gain(); + if (gain > 0.0) { + float igain = 1.0 - clamp(0.0, gain, 2.0)/2.0; + al_draw_rectangle(x+w+1.5, y+h*igain, x+w+3.5, y+h, ctx.fg, 1.0); + } +} + +void Element::draw_arrow(Context const& ctx, float x2, float y2, bool highlight) const +{ + float x1, y1; + ALLEGRO_COLOR col; + output_point(x1, y1); + col = (highlight ? ctx.highlight : ctx.fg); + al_draw_line(x1, y1, x2, y2, col, 1.0); + + float a = atan2(y1-y2, x1-x2); + float a1 = a + 0.5; + float a2 = a - 0.5; + float len = 7.0; + al_draw_line(x2, y2, x2 + len*cos(a1), y2 + len*sin(a1), col, 1.0); + al_draw_line(x2, y2, x2 + len*cos(a2), y2 + len*sin(a2), col, 1.0); +} + +void Element::move_by(int dx, int dy) +{ + x += dx; + y += dy; + + if (x < 0) x = 0; + if (y < 0) y = 0; + if (x+w > DISP_W) x = DISP_W-w; + if (y+h > DISP_H) y = DISP_H-h; +} + +bool Element::contains(int px, int py) const +{ + return px >= x && px < x + w + && py >= y && py < y + h; +} + +void Element::output_point(float & ox, float & oy) const +{ + ox = x + w/2; + oy = y; +} + +void Element::input_point(float & ox, float & oy) const +{ + ox = x + w/2; + oy = y + h; +} + +/*---------------------------------------------------------------------------*/ + +Voice::Voice() +{ + set_random_pos(); + voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, + ALLEGRO_CHANNEL_CONF_2); +} + +Voice::~Voice() +{ + al_destroy_voice(voice); +} + +bool Voice::valid() const +{ + return (voice != NULL); +} + +bool Voice::do_attach(Mixer & mixer) +{ + return al_attach_mixer_to_voice(mixer, voice); +} + +bool Voice::do_attach(SampleInstance & spl) +{ + return al_attach_sample_instance_to_voice(spl, voice); +} + +bool Voice::do_attach(Audiostream & stream) +{ + return al_attach_audio_stream_to_voice(stream, voice); +} + +bool Voice::do_detach() +{ + return false; +} + +bool Voice::is_playing() const +{ + return al_get_voice_playing(voice); +} + +bool Voice::toggle_playing() +{ + bool playing = al_get_voice_playing(voice); + return al_set_voice_playing(voice, !playing); +} + +float Voice::get_gain() const +{ + return 0.0; +} + +bool Voice::adjust_gain(float d) +{ + (void)d; + return false; +} + +char const *Voice::get_label() const +{ + return "Voice"; +} + +/*---------------------------------------------------------------------------*/ + +Mixer::Mixer() +{ + set_random_pos(); + mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); +} + +Mixer::~Mixer() +{ + al_destroy_mixer(mixer); +} + +bool Mixer::do_attach(Mixer & other) +{ + return al_attach_mixer_to_mixer(other, mixer); +} + +bool Mixer::do_attach(SampleInstance & spl) +{ + return al_attach_sample_instance_to_mixer(spl, mixer); +} + +bool Mixer::do_attach(Audiostream & stream) +{ + return al_attach_audio_stream_to_mixer(stream, mixer); +} + +bool Mixer::do_detach() +{ + return al_detach_mixer(mixer); +} + +bool Mixer::is_playing() const +{ + return al_get_mixer_playing(mixer); +} + +bool Mixer::toggle_playing() +{ + bool playing = al_get_mixer_playing(mixer); + return al_set_mixer_playing(mixer, !playing); +} + +float Mixer::get_gain() const +{ + return al_get_mixer_gain(mixer); +} + +bool Mixer::adjust_gain(float d) +{ + float gain = al_get_mixer_gain(mixer) + d; + gain = clamp(0, gain, 2); + return al_set_mixer_gain(mixer, gain); +} + +char const *Mixer::get_label() const +{ + return "Mixer"; +} + +/*---------------------------------------------------------------------------*/ + +SampleInstance::SampleInstance() : spl(NULL), pos(0) +{ + w = 150; + set_random_pos(); + splinst = al_create_sample_instance(NULL); +} + +SampleInstance::~SampleInstance() +{ + al_destroy_sample_instance(splinst); +} + +bool SampleInstance::do_detach() +{ + return al_detach_sample_instance(splinst); +} + +bool SampleInstance::is_playing() const +{ + return al_get_sample_instance_playing(splinst); +} + +bool SampleInstance::toggle_playing() +{ + bool playing = is_playing(); + if (playing) + pos = al_get_sample_instance_position(splinst); + else + al_set_sample_instance_position(splinst, pos); + return al_set_sample_instance_playing(splinst, !playing); +} + +float SampleInstance::get_gain() const +{ + return al_get_sample_instance_gain(splinst); +} + +bool SampleInstance::adjust_gain(float d) +{ + float gain = al_get_sample_instance_gain(splinst) + d; + gain = clamp(0, gain, 2); + return al_set_sample_instance_gain(splinst, gain); +} + +bool SampleInstance::set_sample(Sample const & spl) +{ + bool playing = is_playing(); + bool rc = al_set_sample(splinst, spl); + if (rc) { + this->spl = &spl; + al_set_sample_instance_playmode(splinst, ALLEGRO_PLAYMODE_LOOP); + al_set_sample_instance_playing(splinst, playing); + } + return rc; +} + +char const *SampleInstance::get_label() const +{ + if (spl) { + return spl->get_filename().c_str(); + } + return "No sample"; +} + +/*---------------------------------------------------------------------------*/ + +Sample::Sample(char const *filename) +{ + spl = al_load_sample(filename); + basename(filename, this->filename); +} + +Sample::~Sample() +{ + al_destroy_sample(spl); +} + +bool Sample::valid() const +{ + return spl; +} + +string const& Sample::get_filename() const +{ + return filename; +} + +/*---------------------------------------------------------------------------*/ + +Audiostream::Audiostream(string const& filename) +{ + w = 150; + set_random_pos(); + basename(filename, this->filename); + + stream = al_load_audio_stream(filename.c_str(), 4, 2048); + if (stream) { + al_set_audio_stream_playmode(stream, ALLEGRO_PLAYMODE_LOOP); + } +} + +Audiostream::~Audiostream() +{ + al_destroy_audio_stream(stream); +} + +bool Audiostream::valid() const +{ + return stream; +} + +bool Audiostream::do_detach() +{ + return al_detach_audio_stream(stream); +} + +bool Audiostream::is_playing() const +{ + return al_get_audio_stream_playing(stream); +} + +bool Audiostream::toggle_playing() +{ + bool playing = al_get_audio_stream_playing(stream); + return al_set_audio_stream_playing(stream, !playing); +} + +float Audiostream::get_gain() const +{ + return al_get_audio_stream_gain(stream); +} + +bool Audiostream::adjust_gain(float d) +{ + float gain = al_get_audio_stream_gain(stream) + d; + gain = clamp(0, gain, 2); + return al_set_audio_stream_gain(stream, gain); +} + +char const *Audiostream::get_label() const +{ + return filename.c_str(); +} + +/*---------------------------------------------------------------------------*/ + +class Prog { +public: + Prog(); + void init(); + void add_sample(char const *filename); + void add_stream_path(char const *filename); + void initial_config(); + void run(void); + +private: + Voice *new_voice(); + Mixer *new_mixer(); + SampleInstance *new_sample_instance(); + Audiostream *new_audiostream(); + void process_mouse_button_down(int mb, int mx, int my); + void process_mouse_button_up(int mb, int mx, int my); + void process_mouse_axes(int mx, int my, int dx, int dy); + void process_mouse_wheel(int dz); + void process_key_char(int unichar); + Element *find_element(int x, int y); + void delete_element(Element *elt); + void redraw(); + + ALLEGRO_DISPLAY *dpy; + ALLEGRO_EVENT_QUEUE *queue; + Context ctx; + vector samples; + vector stream_paths; + vector elements; + int cur_button; + Element *cur_element; + float connect_x; + float connect_y; +}; + +Prog::Prog() : cur_button(0), cur_element(NULL) +{ +} + +void Prog::init() +{ + if (!al_init()) { + abort_example("Could not initialise Allegro.\n"); + } + if (!al_init_primitives_addon()) { + abort_example("Could not initialise primitives.\n"); + } + al_init_font_addon(); + if (!al_init_ttf_addon()) { + abort_example("Could not initialise TTF fonts.\n"); + } + if (!al_install_audio()) { + abort_example("Could not initialise audio.\n"); + } + if (!al_init_acodec_addon()) { + abort_example("Could not initialise audio codecs.\n"); + } + init_platform_specific(); + if (!(dpy = al_create_display(800, 600))) { + abort_example("Could not create display.\n"); + } + if (!al_install_keyboard()) { + abort_example("Could not install keyboard.\n"); + } + if (!al_install_mouse()) { + abort_example("Could not install mouse.\n"); + } + + ctx.font = al_load_ttf_font("data/DejaVuSans.ttf", 10, 0); + if (!ctx.font) { + abort_example("Could not load font.\n"); + } + ctx.bg = al_map_rgb_f(0.9, 0.9, 0.9); + ctx.fg = al_map_rgb_f(0, 0, 0); + ctx.fill = al_map_rgb_f(0.85, 0.85, 0.85); + ctx.disabled = al_map_rgb_f(0.6, 0.6, 0.6); + ctx.highlight = al_map_rgb_f(1, 0.1, 0.1); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(dpy)); +} + +void Prog::add_sample(char const *filename) +{ + ALLEGRO_PATH *path = make_path(filename); + Sample *spl = new Sample(al_path_cstr(path, '/')); + if (spl) { + samples.push_back(spl); + } else { + delete spl; + } + al_destroy_path(path); +} + +void Prog::add_stream_path(char const *filename) +{ + ALLEGRO_PATH *path = make_path(filename); + stream_paths.push_back(al_path_cstr(path, '/')); + al_destroy_path(path); +} + +void Prog::initial_config() +{ + Voice *voice = new_voice(); + if (!voice) { + abort_example("Could not create initial voice.\n"); + } + voice->set_pos(300, 50); + + Mixer *mixer = new_mixer(); + mixer->set_pos(300, 150); + voice->attach(mixer); + + SampleInstance *splinst = new_sample_instance(); + splinst->set_pos(220, 300); + mixer->attach(splinst); + splinst->toggle_playing(); + + SampleInstance *splinst2 = new_sample_instance(); + splinst2->set_pos(120, 240); + mixer->attach(splinst2); + splinst2->toggle_playing(); + + Mixer *mixer2 = new_mixer(); + mixer2->set_pos(500, 250); + mixer->attach(mixer2); + + Audiostream *stream; + if ((stream = new_audiostream())) { + stream->set_pos(450, 350); + mixer2->attach(stream); + } +} + +Voice *Prog::new_voice() +{ + Voice *voice = new Voice(); + if (voice->valid()) { + elements.push_back(voice); + } + else { + delete voice; + voice = NULL; + } + return voice; +} + +Mixer *Prog::new_mixer() +{ + Mixer *mixer = new Mixer(); + elements.push_back(mixer); + return mixer; +} + +SampleInstance *Prog::new_sample_instance() +{ + SampleInstance *splinst = new SampleInstance(); + if (samples.size() > 0) { + static unsigned i = 0; + unsigned n = (i++) % samples.size(); + splinst->set_sample(*samples[n]); + i++; + } + elements.push_back(splinst); + return splinst; +} + +Audiostream *Prog::new_audiostream() +{ + if (stream_paths.size() > 0) { + static unsigned i = 0; + unsigned n = (i++) % stream_paths.size(); + Audiostream *stream = new Audiostream(stream_paths[n]); + if (stream->valid()) { + elements.push_back(stream); + return stream; + } + delete stream; + } + return NULL; +} + +void Prog::run() +{ + for (;;) { + if (al_is_event_queue_empty(queue)) { + redraw(); + } + + ALLEGRO_EVENT ev; + al_wait_for_event(queue, &ev); + switch (ev.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + return; + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + process_mouse_button_down(ev.mouse.button, ev.mouse.x, ev.mouse.y); + break; + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + process_mouse_button_up(ev.mouse.button, ev.mouse.x, ev.mouse.y); + break; + case ALLEGRO_EVENT_MOUSE_AXES: + if (ev.mouse.dz) { + process_mouse_wheel(ev.mouse.dz); + } + else { + process_mouse_axes(ev.mouse.x, ev.mouse.y, + ev.mouse.dx, ev.mouse.dy); + } + break; + case ALLEGRO_EVENT_KEY_CHAR: + if (ev.keyboard.unichar == 27) { + return; + } + process_key_char(ev.keyboard.unichar); + break; + } + } +} + +void Prog::process_mouse_button_down(int mb, int mx, int my) +{ + if (cur_button == 0) { + cur_element = find_element(mx, my); + if (cur_element) { + cur_button = mb; + } + if (cur_button == 2) { + connect_x = mx; + connect_y = my; + } + } +} + +void Prog::process_mouse_button_up(int mb, int mx, int my) +{ + if (mb != cur_button) + return; + + if (cur_button == 2 && cur_element) { + Element *sink = find_element(mx, my); + cur_element->detach(); + if (sink && sink != cur_element) { + sink->attach(cur_element); + } + cur_element = NULL; + } + + cur_button = 0; +} + +void Prog::process_mouse_axes(int mx, int my, int dx, int dy) +{ + if (cur_button == 1 && cur_element) { + cur_element->move_by(dx, dy); + } + if (cur_button == 2 && cur_element) { + connect_x = mx; + connect_y = my; + } +} + +void Prog::process_mouse_wheel(int dz) +{ + if (cur_element) { + cur_element->adjust_gain(dz * 0.1); + } +} + +void Prog::process_key_char(int unichar) +{ + int upper = toupper(unichar); + if (upper == 'V') { + new_voice(); + } + else if (upper == 'M') { + new_mixer(); + } + else if (upper == 'S') { + new_sample_instance(); + } + else if (upper == 'A') { + new_audiostream(); + } + else if (upper == ' ') { + if (cur_element) { + cur_element->toggle_playing(); + } + } + else if (upper == 'X') { + if (cur_element) { + delete_element(cur_element); + cur_element = NULL; + } + } + else if (upper >= '1' && upper <= '9') { + unsigned n = upper - '1'; + SampleInstance *splinst; + if (n < samples.size() && + (splinst = dynamic_cast(cur_element))) + { + splinst->set_sample(*samples.at(n)); + } + } +} + +Element *Prog::find_element(int x, int y) +{ + for (Element::iter it = elements.begin(); it != elements.end(); it++) { + if ((*it)->contains(x, y)) + return *it; + } + return NULL; +} + +void Prog::delete_element(Element *elt) +{ + for (Element::iter it = elements.begin(); it != elements.end(); it++) { + if ((*it)->is_attached_to(elt)) { + (*it)->detach(); + } + } + for (Element::iter it = elements.begin(); it != elements.end(); it++) { + if (*it == elt) { + (*it)->detach(); + delete *it; + elements.erase(it); + break; + } + } +} + +void Prog::redraw() +{ + al_clear_to_color(ctx.bg); + + for (Element::iter it = elements.begin(); it != elements.end(); it++) { + bool highlight = (*it == cur_element); + (*it)->draw(ctx, highlight); + + if (highlight && cur_button == 2) { + (*it)->draw_arrow(ctx, connect_x, connect_y, highlight); + } + } + + float y = al_get_display_height(dpy); + float th = al_get_font_line_height(ctx.font); + al_draw_textf(ctx.font, ctx.fg, 0, y-th*2, ALLEGRO_ALIGN_LEFT, + "Create [v]oices, [m]ixers, [s]ample instances, [a]udiostreams. " + "[SPACE] pause playback. " + "[1]-[9] set sample. " + "[x] delete."); + al_draw_textf(ctx.font, ctx.fg, 0, y-th*1, ALLEGRO_ALIGN_LEFT, + "Mouse: [LMB] select element. " + "[RMB] attach sources to sinks " + "(sample->mixer, mixer->mixer, mixer->voice, sample->voice)"); + + al_flip_display(); +} + +int main(int argc, char **argv) +{ + Prog prog; + prog.init(); + prog.add_sample("data/haiku/air_0.ogg"); + prog.add_sample("data/haiku/air_1.ogg"); + prog.add_sample("data/haiku/earth_0.ogg"); + prog.add_sample("data/haiku/earth_1.ogg"); + prog.add_sample("data/haiku/earth_2.ogg"); + prog.add_sample("data/haiku/fire_0.ogg"); + prog.add_sample("data/haiku/fire_1.ogg"); + prog.add_sample("data/haiku/water_0.ogg"); + prog.add_sample("data/haiku/water_1.ogg"); + prog.add_stream_path("../demos/cosmic_protector/data/sfx/game_music.ogg"); + prog.add_stream_path("../demos/cosmic_protector/data/sfx/title_music.ogg"); + prog.initial_config(); + prog.run(); + /* Let Allegro handle the cleanup. */ + return 0; + + (void)argc; + (void)argv; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_audio_props.cpp b/allegro/examples/ex_audio_props.cpp new file mode 100644 index 00000000..2462e3e4 --- /dev/null +++ b/allegro/examples/ex_audio_props.cpp @@ -0,0 +1,212 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * Test audio properties (gain and panning, for now). + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" +#include "nihgui.hpp" +#include + +#include "common.c" + +ALLEGRO_FONT *font_gui; +ALLEGRO_SAMPLE *sample; +ALLEGRO_SAMPLE_INSTANCE *sample_inst; + +class Prog { +private: + Dialog d; + Label length_label; + HSlider length_slider; + ToggleButton pan_button; + HSlider pan_slider; + Label speed_label; + HSlider speed_slider; + ToggleButton bidir_button; + ToggleButton play_button; + Label gain_label; + VSlider gain_slider; + Label mixer_gain_label; + VSlider mixer_gain_slider; + Label two_label; + Label one_label; + Label zero_label; + +public: + Prog(const Theme & theme, ALLEGRO_DISPLAY *display, unsigned int instance_len); + void run(); + void update_properties(); +}; + +Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display, unsigned int instance_len) : + d(Dialog(theme, display, 40, 20)), + length_label(Label("Length")), + length_slider(HSlider(instance_len, instance_len)), + pan_button(ToggleButton("Pan")), + pan_slider(HSlider(1000, 2000)), + speed_label(Label("Speed")), + speed_slider(HSlider(1000, 5000)), + bidir_button(ToggleButton("Bidir")), + play_button(ToggleButton("Play")), + gain_label(Label("Gain")), + gain_slider(VSlider(1000, 2000)), + mixer_gain_label(Label("Mixer gain")), + mixer_gain_slider(VSlider(1000, 2000)), + two_label(Label("2.0")), + one_label(Label("1.0")), + zero_label(Label("0.0")) +{ + pan_button.set_pushed(true); + play_button.set_pushed(true); + + d.add(length_label, 2, 8, 4, 1); + d.add(length_slider, 6, 8, 22, 1); + + d.add(pan_button, 2, 10, 4, 1); + d.add(pan_slider, 6, 10, 22, 1); + + d.add(speed_label, 2, 12, 4, 1); + d.add(speed_slider, 6, 12, 22, 1); + + d.add(bidir_button, 2, 14, 4, 1); + d.add(play_button, 6, 14, 4, 1); + + d.add(gain_label, 29, 1, 2, 1); + d.add(gain_slider, 29, 2, 2, 17); + + d.add(mixer_gain_label, 33, 1, 6, 1); + d.add(mixer_gain_slider, 35, 2, 2, 17); + + d.add(two_label, 32, 2, 2, 1); + d.add(one_label, 32, 10, 2, 1); + d.add(zero_label, 32, 18, 2, 1); +} + +void Prog::run() +{ + d.prepare(); + + while (!d.is_quit_requested()) { + if (d.is_draw_requested()) { + update_properties(); + al_clear_to_color(al_map_rgb(128, 128, 128)); + d.draw(); + al_flip_display(); + } + + d.run_step(true); + } +} + +void Prog::update_properties() +{ + int length; + float pan; + float speed; + float gain; + float mixer_gain; + + if (pan_button.get_pushed()) + pan = pan_slider.get_cur_value() / 1000.0f - 1.0f; + else + pan = ALLEGRO_AUDIO_PAN_NONE; + al_set_sample_instance_pan(sample_inst, pan); + + speed = speed_slider.get_cur_value() / 1000.0f; + al_set_sample_instance_speed(sample_inst, speed); + + length = length_slider.get_cur_value(); + al_set_sample_instance_length(sample_inst, length); + + if (bidir_button.get_pushed()) + al_set_sample_instance_playmode(sample_inst, ALLEGRO_PLAYMODE_BIDIR); + else + al_set_sample_instance_playmode(sample_inst, ALLEGRO_PLAYMODE_LOOP); + + al_set_sample_instance_playing(sample_inst, play_button.get_pushed()); + + gain = gain_slider.get_cur_value() / 1000.0f; + al_set_sample_instance_gain(sample_inst, gain); + + mixer_gain = mixer_gain_slider.get_cur_value() / 1000.0f; + al_set_mixer_gain(al_get_default_mixer(), mixer_gain); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + const char *filename; + + if (argc >= 2) { + filename = argv[1]; + } + else { + filename = "data/welcome.wav"; + } + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + al_install_keyboard(); + al_install_mouse(); + + al_init_font_addon(); + al_init_primitives_addon(); + al_init_acodec_addon(); + init_platform_specific(); + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + + if (!al_reserve_samples(1)) { + abort_example("Could not set up voice and mixer.\n"); + } + + sample = al_load_sample(filename); + if (!sample) { + abort_example("Could not load sample from '%s'!\n", filename); + } + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(640, 480); + if (!display) { + abort_example("Unable to create display\n"); + } + + font_gui = al_create_builtin_font(); + if (!font_gui) { + abort_example("Failed to create builtin font\n"); + } + + /* Loop the sample. */ + sample_inst = al_create_sample_instance(sample); + al_set_sample_instance_playmode(sample_inst, ALLEGRO_PLAYMODE_LOOP); + al_attach_sample_instance_to_mixer(sample_inst, al_get_default_mixer()); + al_play_sample_instance(sample_inst); + + /* Don't remove these braces. */ + { + Theme theme(font_gui); + Prog prog(theme, display, al_get_sample_instance_length(sample_inst)); + prog.run(); + } + + al_destroy_sample_instance(sample_inst); + al_destroy_sample(sample); + al_uninstall_audio(); + + al_destroy_font(font_gui); + + return 0; + + (void)argc; + (void)argv; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_audio_simple.c b/allegro/examples/ex_audio_simple.c new file mode 100644 index 00000000..de4cbef9 --- /dev/null +++ b/allegro/examples/ex_audio_simple.c @@ -0,0 +1,243 @@ +/* + * Example program for the Allegro library. + * + * Demonstrate 'simple' audio interface. + */ + +#define ALLEGRO_UNSTABLE +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" + +#include "common.c" + +#define RESERVED_SAMPLES 16 +#define MAX_SAMPLE_DATA 10 + +const char *default_files[] = {NULL, "data/welcome.wav", + "data/haiku/fire_0.ogg", "data/haiku/fire_1.ogg", + "data/haiku/fire_2.ogg", "data/haiku/fire_3.ogg", + "data/haiku/fire_4.ogg", "data/haiku/fire_5.ogg", + "data/haiku/fire_6.ogg", "data/haiku/fire_7.ogg", + }; + +int main(int argc, const char *argv[]) +{ + ALLEGRO_SAMPLE *sample_data[MAX_SAMPLE_DATA] = {NULL}; + ALLEGRO_DISPLAY *display = NULL; + ALLEGRO_EVENT_QUEUE *event_queue; + ALLEGRO_EVENT event; + ALLEGRO_SAMPLE_ID sample_id; + bool sample_id_valid = false; + ALLEGRO_TIMER* timer; + ALLEGRO_FONT* font; + int i; + bool panning = false; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + if (!al_init_font_addon()) { + abort_example("Could not init the font addon.\n"); + } + + open_log(); + + if (argc < 2) { + log_printf("This example can be run from the command line.\nUsage: %s {audio_files}\n", argv[0]); + argv = default_files; + argc = 10; + } + argc--; + argv++; + + al_install_keyboard(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display\n"); + } + font = al_create_builtin_font(); + + timer = al_create_timer(1/60.0); + al_start_timer(timer); + event_queue = al_create_event_queue(); + al_register_event_source(event_queue, al_get_keyboard_event_source()); + al_register_event_source(event_queue, al_get_display_event_source(display)); + al_register_event_source(event_queue, al_get_timer_event_source(timer)); + + al_init_acodec_addon(); + +Restart: + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + + if (!al_reserve_samples(RESERVED_SAMPLES)) { + abort_example("Could not set up voice and mixer.\n"); + } + + memset(sample_data, 0, sizeof(sample_data)); + for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) { + const char *filename = argv[i]; + + /* Load the entire sound file from disk. */ + sample_data[i] = al_load_sample(argv[i]); + if (!sample_data[i]) { + log_printf("Could not load sample from '%s'!\n", filename); + continue; + } + } + + log_printf( + "Press digits to play sounds.\n" + "Space to stop sounds.\n" + "Add Alt to play sounds repeatedly.\n" + "'p' to pan the last played sound.\n" + "Escape to quit.\n"); + + while (true) { + al_wait_for_event(event_queue, &event); + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + if (event.keyboard.unichar == ' ') { + log_printf("Stopping all sounds\n"); + al_stop_samples(); + } + + if (event.keyboard.keycode >= ALLEGRO_KEY_0 && event.keyboard.keycode <= ALLEGRO_KEY_9) { + bool loop = event.keyboard.modifiers & ALLEGRO_KEYMOD_ALT; + bool bidir = event.keyboard.modifiers & ALLEGRO_KEYMOD_CTRL; + bool reversed = event.keyboard.modifiers & ALLEGRO_KEYMOD_SHIFT; + i = (event.keyboard.keycode - ALLEGRO_KEY_0 + 9) % 10; + if (sample_data[i]) { + ALLEGRO_SAMPLE_ID new_sample_id; + ALLEGRO_PLAYMODE playmode; + const char* playmode_str; + if (loop) { + playmode = ALLEGRO_PLAYMODE_LOOP; + playmode_str = "on a loop"; + } + else if (bidir) { + playmode = ALLEGRO_PLAYMODE_BIDIR; + playmode_str = "on a bidirectional loop"; + } + else { + playmode = ALLEGRO_PLAYMODE_ONCE; + playmode_str = "once"; + } + bool ret = al_play_sample(sample_data[i], 1.0, 0.0, 1.0, + playmode, &new_sample_id); + if (reversed) { + ALLEGRO_SAMPLE_INSTANCE* inst = al_lock_sample_id(&new_sample_id); + al_set_sample_instance_position(inst, al_get_sample_instance_length(inst) - 1); + al_set_sample_instance_speed(inst, -1); + al_unlock_sample_id(&new_sample_id); + } + if (ret) { + log_printf("Playing %d %s\n", i, playmode_str); + } + else { + log_printf( + "al_play_sample_data failed, perhaps too many sounds\n"); + } + if (!panning) { + if (ret) { + sample_id = new_sample_id; + sample_id_valid = true; + } + } + } + } + + if (event.keyboard.unichar == 'p') { + if (sample_id_valid) { + panning = !panning; + if (panning) { + log_printf("Panning\n"); + } + else { + log_printf("Not panning\n"); + } + } + } + + /* Hidden feature: restart audio subsystem. + * For debugging race conditions on shutting down the audio. + */ + if (event.keyboard.unichar == 'r') { + for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) { + if (sample_data[i]) + al_destroy_sample(sample_data[i]); + } + al_uninstall_audio(); + goto Restart; + } + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + else if (event.type == ALLEGRO_EVENT_TIMER) { + int y = 12; + int dy = 12; + if (panning && sample_id_valid) { + ALLEGRO_SAMPLE_INSTANCE* instance = al_lock_sample_id(&sample_id); + if (instance) { + al_set_sample_instance_pan(instance, sin(al_get_time())); + } + al_unlock_sample_id(&sample_id); + } + al_clear_to_color(al_map_rgb_f(0., 0., 0.)); + al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "CONTROLS"); + y += dy; + al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "1-9 - play the sounds"); + y += dy; + al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "SPACE - stop all sounds"); + y += dy; + al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "Ctrl 1-9 - play sounds with bidirectional looping"); + y += dy; + al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "Alt 1-9 - play sounds with regular looping"); + y += dy; + al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "Shift 1-9 - play sounds reversed"); + y += dy; + al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "p - pan the last played sound"); + y += 2 * dy; + al_draw_text(font, al_map_rgb_f(0.5, 1., 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "SOUNDS"); + y += dy; + for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) { + al_draw_textf(font, al_map_rgb_f(0.5, 1., 0.5), 12, y, + ALLEGRO_ALIGN_LEFT, "%d - %s", i + 1, argv[i]); + y += dy; + } + al_flip_display(); + } + } + + for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) { + if (sample_data[i]) + al_destroy_sample(sample_data[i]); + } + + /* Sample data and other objects will be automatically freed. */ + al_uninstall_audio(); + + al_destroy_display(display); + close_log(true); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_audio_timer.c b/allegro/examples/ex_audio_timer.c new file mode 100644 index 00000000..edde9015 --- /dev/null +++ b/allegro/examples/ex_audio_timer.c @@ -0,0 +1,174 @@ +/* + * Example program for the Allegro library. + */ + +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_font.h" + +#include "common.c" + + +#define RESERVED_SAMPLES 16 +#define PERIOD 5 + + +static ALLEGRO_DISPLAY *display; +static ALLEGRO_FONT *font; +static ALLEGRO_SAMPLE *ping; +static ALLEGRO_TIMER *timer; +static ALLEGRO_EVENT_QUEUE *event_queue; + + +static ALLEGRO_SAMPLE *create_sample_s16(int freq, int len) +{ + char *buf = al_malloc(freq * len * sizeof(int16_t)); + + return al_create_sample(buf, len, freq, ALLEGRO_AUDIO_DEPTH_INT16, + ALLEGRO_CHANNEL_CONF_1, true); +} + + +/* Adapted from SPEED. */ +static ALLEGRO_SAMPLE *generate_ping(void) +{ + float osc1, osc2, vol, ramp; + int16_t *p; + int len; + int i; + + /* ping consists of two sine waves */ + len = 8192; + ping = create_sample_s16(22050, len); + if (!ping) + return NULL; + + p = (int16_t *)al_get_sample_data(ping); + + osc1 = 0; + osc2 = 0; + + for (i=0; i 1) { + bps--; + al_set_timer_speed(timer, 1.0 / bps); + } + } + } + + if (redraw && al_is_event_queue_empty(event_queue)) { + ALLEGRO_COLOR c; + if (last_timer % PERIOD == 0) + c = al_map_rgb_f(1, 1, 1); + else + c = al_map_rgb_f(0.5, 0.5, 1.0); + + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_draw_textf(font, c, 640/32, 480/32 - 4, ALLEGRO_ALIGN_CENTRE, + "%u", last_timer); + al_flip_display(); + } + } + + close_log(false); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_bitmap.c b/allegro/examples/ex_bitmap.c new file mode 100644 index 00000000..726b44ee --- /dev/null +++ b/allegro/examples/ex_bitmap.c @@ -0,0 +1,164 @@ +/* This example displays a picture on the screen, with support for + * command-line parameters, multi-screen, screen-orientation and + * zooming. + */ +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + const char *filename; + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bitmap; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + bool redraw = true; + double zoom = 1; + double t0; + double t1; + + /* The first commandline argument can optionally specify an + * image to display instead of the default. Allegro's image + * addon supports BMP, DDS, PCX, TGA and can be compiled with + * PNG and JPG support on all platforms. Additional formats + * are supported by platform specific libraries and support for + * image formats can also be added at runtime. + */ + if (argc > 1) { + filename = argv[1]; + } + else { + filename = "data/mysha.pcx"; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + // Initializes and displays a log window for debugging purposes. + open_log(); + + /* The second parameter to the process can optionally specify what + * adapter to use. + */ + if (argc > 2) { + al_set_new_display_adapter(atoi(argv[2])); + } + + /* Allegro requires installing drivers for all input devices before + * they can be used. + */ + al_install_mouse(); + al_install_keyboard(); + + /* Initialize the image addon. Requires the allegro_image addon + * library. + */ + al_init_image_addon(); + + // Helper functions from common.c. + init_platform_specific(); + + // Create a new display that we can render the image to. + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + al_set_window_title(display, filename); + + // Load the image and time how long it took for the log. + t0 = al_get_time(); + bitmap = al_load_bitmap(filename); + t1 = al_get_time(); + if (!bitmap) { + abort_example("%s not found or failed to load\n", filename); + } + + log_printf("Loading took %.4f seconds\n", t1 - t0); + + // Create a timer that fires 30 times a second. + timer = al_create_timer(1.0 / 30); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); // Start the timer + + // Primary 'game' loop. + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); // Wait for and get an event. + if (event.type == ALLEGRO_EVENT_DISPLAY_ORIENTATION) { + int o = event.display.orientation; + if (o == ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES) { + log_printf("0 degrees\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES) { + log_printf("90 degrees\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES) { + log_printf("180 degrees\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES) { + log_printf("270 degrees\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_FACE_UP) { + log_printf("Face up\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN) { + log_printf("Face down\n"); + } + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + /* Use keyboard to zoom image in and out. + * 1: Reset zoom. + * +: Zoom in 10% + * -: Zoom out 10% + * f: Zoom to width of window + */ + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; // Break the loop and quite on escape key. + if (event.keyboard.unichar == '1') + zoom = 1; + if (event.keyboard.unichar == '+') + zoom *= 1.1; + if (event.keyboard.unichar == '-') + zoom /= 1.1; + if (event.keyboard.unichar == 'f') + zoom = (double)al_get_display_width(display) / + al_get_bitmap_width(bitmap); + } + + // Trigger a redraw on the timer event + if (event.type == ALLEGRO_EVENT_TIMER) + redraw = true; + + // Redraw, but only if the event queue is empty + if (redraw && al_is_event_queue_empty(queue)) { + redraw = false; + // Clear so we don't get trippy artifacts left after zoom. + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + if (zoom == 1) + al_draw_bitmap(bitmap, 0, 0, 0); + else + al_draw_scaled_rotated_bitmap( + bitmap, 0, 0, 0, 0, zoom, zoom, 0, 0); + al_flip_display(); + } + } + + al_destroy_bitmap(bitmap); + + close_log(false); + + return 0; +} + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_bitmap_file.c b/allegro/examples/ex_bitmap_file.c new file mode 100644 index 00000000..d26f39f8 --- /dev/null +++ b/allegro/examples/ex_bitmap_file.c @@ -0,0 +1,173 @@ +/* This example displays a picture on the screen, with support for + * command-line parameters, multi-screen, screen-orientation and + * zooming. It is a little different from ex_bitmap in the sense + * that it uses the ALLEGRO_FILE interface. + */ +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + const char *filename; + char *fileextension = NULL; + ALLEGRO_DISPLAY *display; + ALLEGRO_FILE *file; + ALLEGRO_BITMAP *bitmap = NULL; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + + bool redraw = true; + double zoom = 1; + double t0; + double t1; + + /* The first commandline argument can optionally specify an + * image to display instead of the default. Allegro's image + * addon supports BMP, DDS, PCX, TGA and can be compiled with + * PNG and JPG support on all platforms. Additional formats + * are supported by platform specific libraries and support for + * image formats can also be added at runtime. + */ + if (argc > 1) { + filename = argv[1]; + } + else { + filename = "data/mysha.pcx"; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + // Initializes and displays a log window for debugging purposes. + open_log(); + + /* The second parameter to the process can optionally specify what + * adapter to use. + */ + if (argc > 2) { + al_set_new_display_adapter(atoi(argv[2])); + } + + /* Allegro requires installing drivers for all input devices before + * they can be used. + */ + al_install_mouse(); + al_install_keyboard(); + + /* Initialize the image addon. Requires the allegro_image addon + * library. + */ + al_init_image_addon(); + + // Helper functions from common.c. + init_platform_specific(); + + // Create a new display that we can render the image to. + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + al_set_window_title(display, filename); + + // Load the image and time how long it took for the log. + t0 = al_get_time(); + file = al_fopen(filename, "rb"); + if (file) { + fileextension = strrchr(filename, '.'); + bitmap = al_load_bitmap_f(file, fileextension); + al_fclose( file ); + } + t1 = al_get_time(); + if (!bitmap) { + abort_example("%s not found or failed to load\n", filename); + } + + log_printf("Loading took %.4f seconds\n", t1 - t0); + + // Create a timer that fires 30 times a second. + timer = al_create_timer(1.0 / 30); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); // Start the timer + + // Primary 'game' loop. + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); // Wait for and get an event. + if (event.type == ALLEGRO_EVENT_DISPLAY_ORIENTATION) { + int o = event.display.orientation; + if (o == ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES) { + log_printf("0 degrees\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES) { + log_printf("90 degrees\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES) { + log_printf("180 degrees\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES) { + log_printf("270 degrees\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_FACE_UP) { + log_printf("Face up\n"); + } + else if (o == ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN) { + log_printf("Face down\n"); + } + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + /* Use keyboard to zoom image in and out. + * 1: Reset zoom. + * +: Zoom in 10% + * -: Zoom out 10% + * f: Zoom to width of window + */ + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; // Break the loop and quite on escape key. + if (event.keyboard.unichar == '1') + zoom = 1; + if (event.keyboard.unichar == '+') + zoom *= 1.1; + if (event.keyboard.unichar == '-') + zoom /= 1.1; + if (event.keyboard.unichar == 'f') + zoom = (double)al_get_display_width(display) / + al_get_bitmap_width(bitmap); + } + + // Trigger a redraw on the timer event + if (event.type == ALLEGRO_EVENT_TIMER) + redraw = true; + + // Redraw, but only if the event queue is empty + if (redraw && al_is_event_queue_empty(queue)) { + redraw = false; + // Clear so we don't get trippy artifacts left after zoom. + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + if (zoom == 1) + al_draw_bitmap(bitmap, 0, 0, 0); + else + al_draw_scaled_rotated_bitmap( + bitmap, 0, 0, 0, 0, zoom, zoom, 0, 0); + al_flip_display(); + } + } + + al_destroy_bitmap(bitmap); + + close_log(false); + + return 0; +} + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_bitmap_flip.c b/allegro/examples/ex_bitmap_flip.c new file mode 100644 index 00000000..75a6f463 --- /dev/null +++ b/allegro/examples/ex_bitmap_flip.c @@ -0,0 +1,190 @@ +/* An example showing bitmap flipping flags, by Steven Wallace. */ + +#include +#include +#include + +#include "common.c" + +/* Fire the update every 10 milliseconds. */ +#define INTERVAL 0.01 + + +float bmp_x = 200; +float bmp_y = 200; +float bmp_dx = 96; +float bmp_dy = 96; +int bmp_flag = 0; + +/* Updates the bitmap velocity, orientation and position. */ +static void update(ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + int display_w = al_get_bitmap_width(target); + int display_h = al_get_bitmap_height(target); + int bitmap_w = al_get_bitmap_width(bmp); + int bitmap_h = al_get_bitmap_height(bmp); + + bmp_x += bmp_dx * INTERVAL; + bmp_y += bmp_dy * INTERVAL; + + /* Make sure bitmap is still on the screen. */ + if (bmp_y < 0) { + bmp_y = 0; + bmp_dy *= -1; + bmp_flag &= ~ALLEGRO_FLIP_VERTICAL; + } + + if (bmp_x < 0) { + bmp_x = 0; + bmp_dx *= -1; + bmp_flag &= ~ALLEGRO_FLIP_HORIZONTAL; + } + + if (bmp_y > display_h - bitmap_h) { + bmp_y = display_h - bitmap_h; + bmp_dy *= -1; + bmp_flag |= ALLEGRO_FLIP_VERTICAL; + } + + if (bmp_x > display_w - bitmap_w) { + bmp_x = display_w - bitmap_w; + bmp_dx *= -1; + bmp_flag |= ALLEGRO_FLIP_HORIZONTAL; + } +} + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_BITMAP *bmp; + ALLEGRO_BITMAP *mem_bmp; + ALLEGRO_BITMAP *disp_bmp; + ALLEGRO_FONT *font; + char *text; + bool done = false; + bool redraw = true; + + /* Silence unused arguments warnings. */ + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + /* Initialize the image addon. Requires the allegro_image addon + * library. + */ + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + /* Initialize the image font. Requires the allegro_font addon + * library. + */ + al_init_font_addon(); + init_platform_specific(); /* Helper functions from common.c. */ + + /* Create a new display that we can render the image to. */ + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display.\n"); + } + + /* Allegro requires installing drivers for all input devices before + * they can be used. + */ + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + /* Loads a font from disk. This will use al_load_bitmap_font if you + * pass the name of a known bitmap format, or else al_load_ttf_font. + */ + font = al_load_font("data/fixed_font.tga", 0, 0); + if (!font) { + abort_example("Error loading data/fixed_font.tga\n"); + } + + bmp = disp_bmp = al_load_bitmap("data/mysha.pcx"); + if (!bmp) { + abort_example("Error loading data/mysha.pcx\n"); + } + text = "Display bitmap (space to change)"; + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + mem_bmp = al_load_bitmap("data/mysha.pcx"); + if (!mem_bmp) { + abort_example("Error loading data/mysha.pcx\n"); + } + + + timer = al_create_timer(INTERVAL); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_display_event_source(display)); + + al_start_timer(timer); + + /* Default premultiplied aplha blending. */ + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + /* Primary 'game' loop. */ + while (!done) { + ALLEGRO_EVENT event; + + /* If the timer has since been fired and the queue is empty, draw.*/ + if (redraw && al_is_event_queue_empty(queue)) { + update(bmp); + /* Clear so we don't get trippy artifacts left after zoom. */ + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_draw_tinted_bitmap(bmp, al_map_rgba_f(1, 1, 1, 0.5), + bmp_x, bmp_y, bmp_flag); + al_draw_text(font, al_map_rgba_f(1, 1, 1, 0.5), 0, 0, 0, text); + al_flip_display(); + redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + /* Spacebar toggles whether render from a memory bitmap + * or display bitamp. + */ + if (bmp == mem_bmp) { + bmp = disp_bmp; + text = "Display bitmap (space to change)"; + } + else { + bmp = mem_bmp; + text = "Memory bitmap (space to change)"; + } + } + + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + redraw = true; + break; + } + } + + al_destroy_bitmap(bmp); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_blend.c b/allegro/examples/ex_blend.c new file mode 100644 index 00000000..591c0a25 --- /dev/null +++ b/allegro/examples/ex_blend.c @@ -0,0 +1,335 @@ +/* An example demonstrating different blending modes. + */ + +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include +#include +#include +#include + +#include "common.c" + +/* A structure holding all variables of our example program. */ +struct Example +{ + ALLEGRO_BITMAP *example; /* Our example bitmap. */ + ALLEGRO_BITMAP *offscreen; /* An offscreen buffer, for testing. */ + ALLEGRO_BITMAP *memory; /* A memory buffer, for testing. */ + ALLEGRO_FONT *myfont; /* Our font. */ + ALLEGRO_EVENT_QUEUE *queue; /* Our events queue. */ + int image; /* Which test image to use. */ + int mode; /* How to draw it. */ + int BUTTONS_X; /* Where to draw buttons. */ + + int FPS; + double last_second; + int frames_accum; + double fps; +} ex; + +/* Print some text with a shadow. */ +static void print(int x, int y, bool vertical, char const *format, ...) +{ + va_list list; + char message[1024]; + ALLEGRO_COLOR color; + int h; + int j; + + va_start(list, format); + vsnprintf(message, sizeof message, format, list); + va_end(list); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + h = al_get_font_line_height(ex.myfont); + + for (j = 0; j < 2; j++) { + if (j == 0) + color = al_map_rgb(0, 0, 0); + else + color = al_map_rgb(255, 255, 255); + + if (vertical) { + int i; + ALLEGRO_USTR_INFO ui; + const ALLEGRO_USTR *us = al_ref_cstr(&ui, message); + for (i = 0; i < (int)al_ustr_length(us); i++) { + ALLEGRO_USTR_INFO letter; + al_draw_ustr(ex.myfont, color, x + 1 - j, y + 1 - j + h * i, 0, + al_ref_ustr(&letter, us, al_ustr_offset(us, i), + al_ustr_offset(us, i + 1))); + } + } + else { + al_draw_text(ex.myfont, color, x + 1 - j, y + 1 - j, 0, message); + } + } +} + +/* Create an example bitmap. */ +static ALLEGRO_BITMAP *create_example_bitmap(void) +{ + ALLEGRO_BITMAP *bitmap; + int i, j; + ALLEGRO_LOCKED_REGION *locked; + unsigned char *data; + + bitmap = al_create_bitmap(100, 100); + locked = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_LOCK_WRITEONLY); + data = locked->data; + + for (j = 0; j < 100; j++) { + for (i = 0; i < 100; i++) { + int x = i - 50, y = j - 50; + int r = sqrt(x * x + y * y); + float rc = 1 - r / 50.0; + if (rc < 0) + rc = 0; + data[i * 4 + 0] = i * 255 / 100; + data[i * 4 + 1] = j * 255 / 100; + data[i * 4 + 2] = rc * 255; + data[i * 4 + 3] = rc * 255; + } + data += locked->pitch; + } + al_unlock_bitmap(bitmap); + + return bitmap; +} + +/* Draw our example scene. */ +static void draw(void) +{ + ALLEGRO_COLOR test[5]; + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + + char const *blend_names[] = {"ZERO", "ONE", "ALPHA", "INVERSE"}; + char const *blend_vnames[] = {"ZERO", "ONE", "ALPHA", "INVER"}; + int blend_modes[] = {ALLEGRO_ZERO, ALLEGRO_ONE, ALLEGRO_ALPHA, + ALLEGRO_INVERSE_ALPHA}; + float x = 40, y = 40; + int i, j; + + al_clear_to_color(al_map_rgb_f(0.5, 0.5, 0.5)); + + test[0] = al_map_rgba_f(1, 1, 1, 1); + test[1] = al_map_rgba_f(1, 1, 1, 0.5); + test[2] = al_map_rgba_f(1, 1, 1, 0.25); + test[3] = al_map_rgba_f(1, 0, 0, 0.75); + test[4] = al_map_rgba_f(0, 0, 0, 0); + + print(x, 0, false, "D E S T I N A T I O N (%0.2f fps)", ex.fps); + print(0, y, true, "S O U R C E"); + for (i = 0; i < 4; i++) { + print(x + i * 110, 20, false, blend_names[i]); + print(20, y + i * 110, true, blend_vnames[i]); + } + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + if (ex.mode >= 1 && ex.mode <= 5) { + al_set_target_bitmap(ex.offscreen); + al_clear_to_color(test[ex.mode - 1]); + } + if (ex.mode >= 6 && ex.mode <= 10) { + al_set_target_bitmap(ex.memory); + al_clear_to_color(test[ex.mode - 6]); + } + + for (j = 0; j < 4; j++) { + for (i = 0; i < 4; i++) { + al_set_blender(ALLEGRO_ADD, blend_modes[j], blend_modes[i]); + if (ex.image == 0) + al_draw_bitmap(ex.example, x + i * 110, y + j * 110, 0); + else if (ex.image >= 1 && ex.image <= 6) { + al_draw_filled_rectangle(x + i * 110, y + j * 110, + x + i * 110 + 100, y + j * 110 + 100, + test[ex.image - 1]); + } + } + } + + if (ex.mode >= 1 && ex.mode <= 5) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_set_target_bitmap(target); + al_draw_bitmap_region(ex.offscreen, x, y, 430, 430, x, y, 0); + } + if (ex.mode >= 6 && ex.mode <= 10) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_set_target_bitmap(target); + al_draw_bitmap_region(ex.memory, x, y, 430, 430, x, y, 0); + } + + #define IS(x) ((ex.image == x) ? "*" : " ") + print(ex.BUTTONS_X, 20 * 1, false, "What to draw"); + print(ex.BUTTONS_X, 20 * 2, false, "%s Picture", IS(0)); + print(ex.BUTTONS_X, 20 * 3, false, "%s Rec1 (1/1/1/1)", IS(1)); + print(ex.BUTTONS_X, 20 * 4, false, "%s Rec2 (1/1/1/.5)", IS(2)); + print(ex.BUTTONS_X, 20 * 5, false, "%s Rec3 (1/1/1/.25)", IS(3)); + print(ex.BUTTONS_X, 20 * 6, false, "%s Rec4 (1/0/0/.75)", IS(4)); + print(ex.BUTTONS_X, 20 * 7, false, "%s Rec5 (0/0/0/0)", IS(5)); + #undef IS + + #define IS(x) ((ex.mode == x) ? "*" : " ") + print(ex.BUTTONS_X, 20 * 9, false, "Where to draw"); + print(ex.BUTTONS_X, 20 * 10, false, "%s screen", IS(0)); + + print(ex.BUTTONS_X, 20 * 11, false, "%s offscreen1", IS(1)); + print(ex.BUTTONS_X, 20 * 12, false, "%s offscreen2", IS(2)); + print(ex.BUTTONS_X, 20 * 13, false, "%s offscreen3", IS(3)); + print(ex.BUTTONS_X, 20 * 14, false, "%s offscreen4", IS(4)); + print(ex.BUTTONS_X, 20 * 15, false, "%s offscreen5", IS(5)); + + print(ex.BUTTONS_X, 20 * 16, false, "%s memory1", IS(6)); + print(ex.BUTTONS_X, 20 * 17, false, "%s memory2", IS(7)); + print(ex.BUTTONS_X, 20 * 18, false, "%s memory3", IS(8)); + print(ex.BUTTONS_X, 20 * 19, false, "%s memory4", IS(9)); + print(ex.BUTTONS_X, 20 * 20, false, "%s memory5", IS(10)); + #undef IS +} + +/* Called a fixed amount of times per second. */ +static void tick(void) +{ + /* Count frames during the last second or so. */ + double t = al_get_time(); + if (t >= ex.last_second + 1) { + ex.fps = ex.frames_accum / (t - ex.last_second); + ex.frames_accum = 0; + ex.last_second = t; + } + + draw(); + al_flip_display(); + ex.frames_accum++; +} + +/* Run our test. */ +static void run(void) +{ + ALLEGRO_EVENT event; + float x, y; + bool need_draw = true; + + while (1) { + /* Perform frame skipping so we don't fall behind the timer events. */ + if (need_draw && al_is_event_queue_empty(ex.queue)) { + tick(); + need_draw = false; + } + + al_wait_for_event(ex.queue, &event); + + switch (event.type) { + /* Was the X button on the window pressed? */ + case ALLEGRO_EVENT_DISPLAY_CLOSE: + return; + + /* Was a key pressed? */ + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + return; + break; + + /* Is it time for the next timer tick? */ + case ALLEGRO_EVENT_TIMER: + need_draw = true; + break; + + /* Mouse click? */ + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + x = event.mouse.x; + y = event.mouse.y; + if (x >= ex.BUTTONS_X) { + int button = y / 20; + if (button == 2) ex.image = 0; + if (button == 3) ex.image = 1; + if (button == 4) ex.image = 2; + if (button == 5) ex.image = 3; + if (button == 6) ex.image = 4; + if (button == 7) ex.image = 5; + + if (button == 10) ex.mode = 0; + + if (button == 11) ex.mode = 1; + if (button == 12) ex.mode = 2; + if (button == 13) ex.mode = 3; + if (button == 14) ex.mode = 4; + if (button == 15) ex.mode = 5; + + if (button == 16) ex.mode = 6; + if (button == 17) ex.mode = 7; + if (button == 18) ex.mode = 8; + if (button == 19) ex.mode = 9; + if (button == 20) ex.mode = 10; + } + break; + } + } +} + +/* Initialize the example. */ +static void init(void) +{ + ex.BUTTONS_X = 40 + 110 * 4; + ex.FPS = 60; + + ex.myfont = al_load_font("data/font.tga", 0, 0); + if (!ex.myfont) { + abort_example("data/font.tga not found\n"); + } + ex.example = create_example_bitmap(); + + ex.offscreen = al_create_bitmap(640, 480); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + ex.memory = al_create_bitmap(640, 480); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + al_install_touch_input(); + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + init(); + + timer = al_create_timer(1.0 / ex.FPS); + + ex.queue = al_create_event_queue(); + al_register_event_source(ex.queue, al_get_keyboard_event_source()); + al_register_event_source(ex.queue, al_get_mouse_event_source()); + al_register_event_source(ex.queue, al_get_display_event_source(display)); + al_register_event_source(ex.queue, al_get_timer_event_source(timer)); + if (al_is_touch_input_installed()) { + al_register_event_source(ex.queue, + al_get_touch_input_mouse_emulation_event_source()); + } + + al_start_timer(timer); + run(); + + al_destroy_event_queue(ex.queue); + + return 0; +} diff --git a/allegro/examples/ex_blend2.cpp b/allegro/examples/ex_blend2.cpp new file mode 100644 index 00000000..12538fe8 --- /dev/null +++ b/allegro/examples/ex_blend2.cpp @@ -0,0 +1,388 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * Compare software blending routines with hardware blending. + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" +#include + +#include "common.c" + +#include "nihgui.hpp" + +ALLEGRO_BITMAP *allegro; +ALLEGRO_BITMAP *mysha; +ALLEGRO_BITMAP *allegro_bmp; +ALLEGRO_BITMAP *mysha_bmp; +ALLEGRO_BITMAP *target; +ALLEGRO_BITMAP *target_bmp; + +class Prog { +private: + Dialog d; + Label memory_label; + Label texture_label; + Label source_label; + Label destination_label; + List source_image; + List destination_image; + List draw_mode; + Label operation_label[6]; + List operations[6]; + Label rgba_label[3]; + HSlider r[3]; + HSlider g[3]; + HSlider b[3]; + HSlider a[3]; + +public: + Prog(const Theme & theme, ALLEGRO_DISPLAY *display); + void run(); + +private: + void blending_test(bool memory); + void draw_samples(); + void draw_bitmap(const std::string &, const std::string &, bool, bool); +}; + +Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : + d(Dialog(theme, display, 20, 40)), + memory_label(Label("Memory")), + texture_label(Label("Texture")), + source_label(Label("Source", false)), + destination_label(Label("Destination", false)), + source_image(List(0)), + destination_image(List(1)), + draw_mode(List(0)) +{ + d.add(memory_label, 9, 0, 10, 2); + d.add(texture_label, 0, 0, 10, 2); + d.add(source_label, 1, 15, 6, 2); + d.add(destination_label, 7, 15, 6, 2); + + List *images[] = {&source_image, &destination_image, &draw_mode}; + for (int i = 0; i < 3; i++) { + List & image = *images[i]; + if (i < 2) { + image.append_item("Mysha"); + image.append_item("Allegro"); + image.append_item("Mysha (tinted)"); + image.append_item("Allegro (tinted)"); + image.append_item("Color"); + } + else { + image.append_item("original"); + image.append_item("scaled"); + image.append_item("rotated"); + } + d.add(image, 1 + i * 6, 16, 4, 6); + } + + for (int i = 0; i < 4; i++) { + operation_label[i] = Label(i % 2 == 0 ? "Color" : "Alpha", false); + d.add(operation_label[i], 1 + i * 3, 23, 3, 2); + List &l = operations[i]; + l.append_item("ONE"); + l.append_item("ZERO"); + l.append_item("ALPHA"); + l.append_item("INVERSE"); + l.append_item("SRC_COLOR"); + l.append_item("DEST_COLOR"); + l.append_item("INV_SRC_COLOR"); + l.append_item("INV_DEST_COLOR"); + l.append_item("CONST_COLOR"); + l.append_item("INV_CONST_COLOR"); + d.add(l, 1 + i * 3, 24, 3, 10); + } + + for (int i = 4; i < 6; i++) { + operation_label[i] = Label(i == 4 ? "Blend op" : "Alpha op", false); + d.add(operation_label[i], 1 + i * 3, 23, 3, 2); + List &l = operations[i]; + l.append_item("ADD"); + l.append_item("SRC_MINUS_DEST"); + l.append_item("DEST_MINUS_SRC"); + d.add(l, 1 + i * 3, 24, 3, 6); + } + + rgba_label[0] = Label("Source tint/color RGBA"); + rgba_label[1] = Label("Dest tint/color RGBA"); + rgba_label[2] = Label("Const color RGBA"); + d.add(rgba_label[0], 1, 34, 5, 1); + d.add(rgba_label[1], 7, 34, 5, 1); + d.add(rgba_label[2], 13, 34, 5, 1); + + for (int i = 0; i < 3; i++) { + r[i] = HSlider(255, 255); + g[i] = HSlider(255, 255); + b[i] = HSlider(255, 255); + a[i] = HSlider(255, 255); + d.add(r[i], 1 + i * 6, 35, 5, 1); + d.add(g[i], 1 + i * 6, 36, 5, 1); + d.add(b[i], 1 + i * 6, 37, 5, 1); + d.add(a[i], 1 + i * 6, 38, 5, 1); + } +} + +void Prog::run() +{ + d.prepare(); + + while (!d.is_quit_requested()) { + if (d.is_draw_requested()) { + al_clear_to_color(al_map_rgb(128, 128, 128)); + draw_samples(); + d.draw(); + al_flip_display(); + } + + d.run_step(true); + } +} + +int str_to_blend_mode(const std::string & str) +{ + if (str == "ZERO") + return ALLEGRO_ZERO; + if (str == "ONE") + return ALLEGRO_ONE; + if (str == "SRC_COLOR") + return ALLEGRO_SRC_COLOR; + if (str == "DEST_COLOR") + return ALLEGRO_DEST_COLOR; + if (str == "INV_SRC_COLOR") + return ALLEGRO_INVERSE_SRC_COLOR; + if (str == "INV_DEST_COLOR") + return ALLEGRO_INVERSE_DEST_COLOR; + if (str == "ALPHA") + return ALLEGRO_ALPHA; + if (str == "INVERSE") + return ALLEGRO_INVERSE_ALPHA; + if (str == "ADD") + return ALLEGRO_ADD; + if (str == "SRC_MINUS_DEST") + return ALLEGRO_SRC_MINUS_DEST; + if (str == "DEST_MINUS_SRC") + return ALLEGRO_DEST_MINUS_SRC; + if (str == "CONST_COLOR") + return ALLEGRO_CONST_COLOR; + if (str == "INV_CONST_COLOR") + return ALLEGRO_INVERSE_CONST_COLOR; + + ALLEGRO_ASSERT(false); + return ALLEGRO_ONE; +} + +void draw_background(int x, int y) +{ + ALLEGRO_COLOR c[] = { + al_map_rgba(0x66, 0x66, 0x66, 0xff), + al_map_rgba(0x99, 0x99, 0x99, 0xff) + }; + + for (int i = 0; i < 320 / 16; i++) { + for (int j = 0; j < 200 / 16; j++) { + al_draw_filled_rectangle(x + i * 16, y + j * 16, + x + i * 16 + 16, y + j * 16 + 16, + c[(i + j) & 1]); + } + } +} + +static ALLEGRO_COLOR makecol(int r, int g, int b, int a) +{ + /* Premultiply alpha. */ + float rf = (float)r / 255.0f; + float gf = (float)g / 255.0f; + float bf = (float)b / 255.0f; + float af = (float)a / 255.0f; + return al_map_rgba_f(rf*af, gf*af, bf*af, af); +} + +static bool contains(const std::string & haystack, const std::string & needle) +{ + return haystack.find(needle) != std::string::npos; +} + +void Prog::draw_bitmap(const std::string & str, + const std::string &how, + bool memory, + bool destination) +{ + int i = destination ? 1 : 0; + int rv = r[i].get_cur_value(); + int gv = g[i].get_cur_value(); + int bv = b[i].get_cur_value(); + int av = a[i].get_cur_value(); + ALLEGRO_COLOR color = makecol(rv, gv, bv, av); + ALLEGRO_BITMAP *bmp; + + if (contains(str, "Mysha")) + bmp = (memory ? mysha_bmp : mysha); + else + bmp = (memory ? allegro_bmp : allegro); + + if (how == "original") { + if (str == "Color") + al_draw_filled_rectangle(0, 0, 320, 200, color); + else if (contains(str, "tint")) + al_draw_tinted_bitmap(bmp, color, 0, 0, 0); + else + al_draw_bitmap(bmp, 0, 0, 0); + } + else if (how == "scaled") { + int w = al_get_bitmap_width(bmp); + int h = al_get_bitmap_height(bmp); + float s = 200.0 / h * 0.9; + if (str == "Color") { + al_draw_filled_rectangle(10, 10, 300, 180, color); + } + else if (contains(str, "tint")) { + al_draw_tinted_scaled_bitmap(bmp, color, 0, 0, w, h, + 160 - w * s / 2, 100 - h * s / 2, w * s, h * s, 0); + } + else { + al_draw_scaled_bitmap(bmp, 0, 0, w, h, + 160 - w * s / 2, 100 - h * s / 2, w * s, h * s, 0); + } + } + else if (how == "rotated") { + if (str == "Color") { + al_draw_filled_circle(160, 100, 100, color); + } + else if (contains(str, "tint")) { + al_draw_tinted_rotated_bitmap(bmp, color, 160, 100, + 160, 100, ALLEGRO_PI / 8, 0); + } + else { + al_draw_rotated_bitmap(bmp, 160, 100, + 160, 100, ALLEGRO_PI / 8, 0); + } + } +} + +void Prog::blending_test(bool memory) +{ + ALLEGRO_COLOR transparency = al_map_rgba_f(0, 0, 0, 0); + int op = str_to_blend_mode(operations[4].get_selected_item_text()); + int aop = str_to_blend_mode(operations[5].get_selected_item_text()); + int src = str_to_blend_mode(operations[0].get_selected_item_text()); + int asrc = str_to_blend_mode(operations[1].get_selected_item_text()); + int dst = str_to_blend_mode(operations[2].get_selected_item_text()); + int adst = str_to_blend_mode(operations[3].get_selected_item_text()); + int rv = r[2].get_cur_value(); + int gv = g[2].get_cur_value(); + int bv = b[2].get_cur_value(); + int av = a[2].get_cur_value(); + ALLEGRO_COLOR color = makecol(rv, gv, bv, av); + + /* Initialize with destination. */ + al_clear_to_color(transparency); // Just in case. + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + draw_bitmap(destination_image.get_selected_item_text(), + "original", memory, true); + + /* Now draw the blended source over it. */ + al_set_separate_blender(op, src, dst, aop, asrc, adst); + al_set_blend_color(color); + draw_bitmap(source_image.get_selected_item_text(), + draw_mode.get_selected_item_text(), memory, false); +} + +void Prog::draw_samples() +{ + ALLEGRO_STATE state; + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); + + /* Draw a background, in case our target bitmap will end up with + * alpha in it. + */ + draw_background(40, 20); + draw_background(400, 20); + + /* Test standard blending. */ + al_set_target_bitmap(target); + blending_test(false); + + /* Test memory blending. */ + al_set_target_bitmap(target_bmp); + blending_test(true); + + /* Display results. */ + al_restore_state(&state); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_bitmap(target, 40, 20, 0); + al_draw_bitmap(target_bmp, 400, 20, 0); + + al_restore_state(&state); +} + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + + al_init_font_addon(); + al_init_image_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(800, 600); + if (!display) { + abort_example("Unable to create display\n"); + } + + font = al_load_font("data/fixed_font.tga", 0, 0); + if (!font) { + abort_example("Failed to load data/fixed_font.tga\n"); + } + allegro = al_load_bitmap("data/allegro.pcx"); + if (!allegro) { + abort_example("Failed to load data/allegro.pcx\n"); + } + mysha = al_load_bitmap("data/mysha256x256.png"); + if (!mysha) { + abort_example("Failed to load data/mysha256x256.png\n"); + } + + target = al_create_bitmap(320, 200); + + al_add_new_bitmap_flag(ALLEGRO_MEMORY_BITMAP); + allegro_bmp = al_clone_bitmap(allegro); + mysha_bmp = al_clone_bitmap(mysha); + target_bmp = al_clone_bitmap(target); + + /* Don't remove these braces. */ + { + Theme theme(font); + Prog prog(theme, display); + prog.run(); + } + + al_destroy_bitmap(allegro); + al_destroy_bitmap(allegro_bmp); + al_destroy_bitmap(mysha); + al_destroy_bitmap(mysha_bmp); + al_destroy_bitmap(target); + al_destroy_bitmap(target_bmp); + + al_destroy_font(font); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_blend_bench.c b/allegro/examples/ex_blend_bench.c new file mode 100644 index 00000000..5f8143a7 --- /dev/null +++ b/allegro/examples/ex_blend_bench.c @@ -0,0 +1,178 @@ +/* + * Benchmark for memory blenders. + */ + +#include +#include +#include +#include +#include + +#include "common.c" + +/* Do a few un-timed runs to switch CPU to performance mode and cache + * data and so on - seems to make the results more stable here. + * Also used to guess the number of timed iterations. + */ +#define WARMUP 100 +/* How many seconds the timing should approximately take - a fixed + * number of iterations is not enough on very fast systems but takes + * too long on slow systems. + */ +#define TEST_TIME 5.0 + +enum Mode { + ALL, + PLAIN_BLIT, + SCALED_BLIT, + ROTATE_BLIT +}; + +static char const *names[] = { + "", "Plain blit", "Scaled blit", "Rotated blit" +}; + +ALLEGRO_DISPLAY *display; + +static void step(enum Mode mode, ALLEGRO_BITMAP *b2) +{ + switch (mode) { + case ALL: break; + case PLAIN_BLIT: + al_draw_bitmap(b2, 0, 0, 0); + break; + case SCALED_BLIT: + al_draw_scaled_bitmap(b2, 0, 0, 320, 200, 0, 0, 640, 480, 0); + break; + case ROTATE_BLIT: + al_draw_scaled_rotated_bitmap(b2, 10, 10, 10, 10, 2.0, 2.0, + ALLEGRO_PI/30, 0); + break; + } +} + +/* al_get_current_time() measures wallclock time - but for the benchmark + * result we prefer CPU time so clock() is better. + */ +static double current_clock(void) +{ + clock_t c = clock(); + return (double)c / CLOCKS_PER_SEC; +} + +static bool do_test(enum Mode mode) +{ + ALLEGRO_STATE state; + ALLEGRO_BITMAP *b1; + ALLEGRO_BITMAP *b2; + int REPEAT; + double t0, t1; + int i; + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + + b1 = al_load_bitmap("data/mysha.pcx"); + if (!b1) { + abort_example("Error loading data/mysha.pcx\n"); + return false; + } + + b2 = al_load_bitmap("data/allegro.pcx"); + if (!b2) { + abort_example("Error loading data/mysha.pcx\n"); + return false; + } + + al_set_target_bitmap(b1); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + step(mode, b2); + + /* Display the blended bitmap to the screen so we can see something. */ + al_store_state(&state, ALLEGRO_STATE_ALL); + al_set_target_backbuffer(display); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_bitmap(b1, 0, 0, 0); + al_flip_display(); + al_restore_state(&state); + + log_printf("Benchmark: %s\n", names[mode]); + log_printf("Please wait...\n"); + + /* Do warmup run and estimate required runs for real test. */ + t0 = current_clock(); + for (i = 0; i < WARMUP; i++) { + step(mode, b2); + } + t1 = current_clock(); + REPEAT = TEST_TIME * 100 / (t1 - t0); + + /* Do the real test. */ + t0 = current_clock(); + for (i = 0; i < REPEAT; i++) { + step(mode, b2); + } + t1 = current_clock(); + + log_printf("Time = %g s, %d steps\n", + t1 - t0, REPEAT); + log_printf("%s: %g FPS\n", names[mode], REPEAT / (t1 - t0)); + log_printf("Done\n"); + + al_destroy_bitmap(b1); + al_destroy_bitmap(b2); + + return true; +} + +int main(int argc, char **argv) +{ + enum Mode mode = ALL; + int i; + + if (argc > 1) { + i = strtol(argv[1], NULL, 10); + switch (i) { + case 0: + mode = PLAIN_BLIT; + break; + case 1: + mode = SCALED_BLIT; + break; + case 2: + mode = ROTATE_BLIT; + break; + } + } + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + + open_log(); + + al_init_image_addon(); + al_init_primitives_addon(); + init_platform_specific(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + if (mode == ALL) { + for (mode = PLAIN_BLIT; mode <= ROTATE_BLIT; mode++) { + do_test(mode); + } + } + else { + do_test(mode); + } + + al_destroy_display(display); + + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_blend_target.c b/allegro/examples/ex_blend_target.c new file mode 100644 index 00000000..216827ff --- /dev/null +++ b/allegro/examples/ex_blend_target.c @@ -0,0 +1,132 @@ +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include +#include + +#include "common.c" + +#define FPS 60 + +static ALLEGRO_BITMAP *load_bitmap(char const *filename) +{ + ALLEGRO_BITMAP *bitmap = al_load_bitmap(filename); + if (!bitmap) + abort_example("%s not found or failed to load\n", filename); + return bitmap; +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP* mysha; + ALLEGRO_BITMAP* parrot; + ALLEGRO_BITMAP* targets[4]; + ALLEGRO_BITMAP* backbuffer; + int w; + int h; + + bool done = false; + bool need_redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init image addon.\n"); + } + + init_platform_specific(); + + mysha = load_bitmap("data/mysha.pcx"); + parrot = load_bitmap("data/obp.jpg"); + + w = al_get_bitmap_width(mysha); + h = al_get_bitmap_height(mysha); + + display = al_create_display(2 * w, 2 * h); + if (!display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + /* Set up blend modes once. */ + backbuffer = al_get_backbuffer(display); + targets[0] = al_create_sub_bitmap(backbuffer, 0, 0, w, h ); + al_set_target_bitmap(targets[0]); + al_set_bitmap_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_SRC_COLOR, ALLEGRO_DST_COLOR); + targets[1] = al_create_sub_bitmap(backbuffer, w, 0, w, h ); + al_set_target_bitmap(targets[1]); + al_set_bitmap_blender(ALLEGRO_ADD, ALLEGRO_SRC_COLOR, ALLEGRO_DST_COLOR); + al_set_bitmap_blend_color(al_map_rgb_f(0.5, 0.5, 1.0)); + targets[2] = al_create_sub_bitmap(backbuffer, 0, h, w, h ); + al_set_target_bitmap(targets[2]); + al_set_bitmap_blender(ALLEGRO_SRC_MINUS_DEST, ALLEGRO_SRC_COLOR, ALLEGRO_DST_COLOR); + targets[3] = al_create_sub_bitmap(backbuffer, w, h, w, h ); + al_set_target_bitmap(targets[3]); + al_set_bitmap_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_INVERSE_SRC_COLOR, ALLEGRO_DST_COLOR); + + timer = al_create_timer(1.0 / FPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_register_event_source(queue, al_get_display_event_source(display)); + + al_start_timer(timer); + + while (!done) { + ALLEGRO_EVENT event; + + if (need_redraw) { + int i; + al_set_target_bitmap(backbuffer); + al_draw_bitmap(parrot, 0, 0, 0); + + for (i = 0; i < 4; i++) { + /* Simply setting the target also sets the blend mode. */ + al_set_target_bitmap(targets[i]); + al_draw_bitmap(mysha, 0, 0, 0); + } + + al_flip_display(); + need_redraw = false; + } + + while (true) { + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_CHAR: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + need_redraw = true; + break; + } + if (al_is_event_queue_empty(queue)) + break; + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_blend_test.c b/allegro/examples/ex_blend_test.c new file mode 100644 index 00000000..1322bd1c --- /dev/null +++ b/allegro/examples/ex_blend_test.c @@ -0,0 +1,327 @@ +#include +#include +#include +#include + +#include "common.c" + +int test_only_index = 0; +int test_index = 0; +bool test_display = false; +ALLEGRO_DISPLAY *display; + +static void print_color(ALLEGRO_COLOR c) +{ + float r, g, b, a; + al_unmap_rgba_f(c, &r, &g, &b, &a); + log_printf("%.2f, %.2f, %.2f, %.2f", r, g, b, a); +} + +static ALLEGRO_COLOR test(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, + int src_format, int dst_format, + int src, int dst, int src_a, int dst_a, + int operation, bool verbose) +{ + ALLEGRO_COLOR result; + ALLEGRO_BITMAP *dst_bmp; + + al_set_new_bitmap_format(dst_format); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + dst_bmp = al_create_bitmap(1, 1); + al_set_target_bitmap(dst_bmp); + al_clear_to_color(dst_col); + if (operation == 0) { + ALLEGRO_BITMAP *src_bmp; + al_set_new_bitmap_format(src_format); + src_bmp = al_create_bitmap(1, 1); + al_set_target_bitmap(src_bmp); + al_clear_to_color(src_col); + al_set_target_bitmap(dst_bmp); + al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a); + al_draw_bitmap(src_bmp, 0, 0, 0); + al_destroy_bitmap(src_bmp); + } + else if (operation == 1) { + al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a); + al_draw_pixel(0, 0, src_col); + } + else if (operation == 2) { + al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a); + al_draw_line(0, 0, 1, 1, src_col, 0); + } + + result = al_get_pixel(dst_bmp, 0, 0); + + al_set_target_backbuffer(display); + + if (test_display) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_bitmap(dst_bmp, 0, 0, 0); + } + + al_destroy_bitmap(dst_bmp); + + if (!verbose) + return result; + + log_printf("---\n"); + log_printf("test id: %d\n", test_index); + + log_printf("source : "); + print_color(src_col); + log_printf(" %s format=%d mode=%d alpha=%d\n", + operation == 0 ? "bitmap" : operation == 1 ? "pixel" : "prim", + src_format, src, src_a); + + log_printf("destination: "); + print_color(dst_col); + log_printf(" format=%d mode=%d alpha=%d\n", + dst_format, dst, dst_a); + + log_printf("result : "); + print_color(result); + log_printf("\n"); + + return result; +} + +static bool same_color(ALLEGRO_COLOR c1, ALLEGRO_COLOR c2) +{ + float r1, g1, b1, a1; + float r2, g2, b2, a2; + float dr, dg, db, da; + float d; + al_unmap_rgba_f(c1, &r1, &g1, &b1, &a1); + al_unmap_rgba_f(c2, &r2, &g2, &b2, &a2); + dr = r1 - r2; + dg = g1 - g2; + db = b1 - b2; + da = a1 - a2; + d = sqrt(dr * dr + dg * dg + db * db + da * da); + if (d < 0.01) + return true; + else + return false; +} + +static float get_factor(int operation, float alpha) +{ + switch(operation) { + case ALLEGRO_ZERO: return 0; + case ALLEGRO_ONE: return 1; + case ALLEGRO_ALPHA: return alpha; + case ALLEGRO_INVERSE_ALPHA: return 1 - alpha; + } + return 0; +} + +static bool has_alpha(int format) +{ + if (format == ALLEGRO_PIXEL_FORMAT_RGB_888) + return false; + if (format == ALLEGRO_PIXEL_FORMAT_BGR_888) + return false; + return true; +} + +#define CLAMP(x) (x > 1 ? 1 : x) + +static ALLEGRO_COLOR reference_implementation( + ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, + int src_format, int dst_format, + int src_mode, int dst_mode, int src_alpha, int dst_alpha, + int operation) +{ + float sr, sg, sb, sa; + float dr, dg, db, da; + float r, g, b, a; + float src, dst, asrc, adst; + + al_unmap_rgba_f(src_col, &sr, &sg, &sb, &sa); + al_unmap_rgba_f(dst_col, &dr, &dg, &db, &da); + + /* Do we even have source alpha? */ + if (operation == 0) { + if (!has_alpha(src_format)) { + sa = 1; + } + } + + r = sr; + g = sg; + b = sb; + a = sa; + + src = get_factor(src_mode, a); + dst = get_factor(dst_mode, a); + asrc = get_factor(src_alpha, a); + adst = get_factor(dst_alpha, a); + + r = r * src + dr * dst; + g = g * src + dg * dst; + b = b * src + db * dst; + a = a * asrc + da * adst; + + r = CLAMP(r); + g = CLAMP(g); + b = CLAMP(b); + a = CLAMP(a); + + /* Do we even have destination alpha? */ + if (!has_alpha(dst_format)) { + a = 1; + } + + return al_map_rgba_f(r, g, b, a); +} + +static void do_test2(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, + int src_format, int dst_format, + int src_mode, int dst_mode, int src_alpha, int dst_alpha, + int operation) +{ + ALLEGRO_COLOR reference, result, from_display; + test_index++; + + if (test_only_index && test_index != test_only_index) + return; + + reference = reference_implementation( + src_col, dst_col, src_format, dst_format, + src_mode, dst_mode, src_alpha, dst_alpha, operation); + + result = test(src_col, dst_col, src_format, + dst_format, src_mode, dst_mode, src_alpha, dst_alpha, + operation, false); + + if (!same_color(reference, result)) { + test(src_col, dst_col, src_format, + dst_format, src_mode, dst_mode, src_alpha, dst_alpha, + operation, true); + log_printf("expected : "); + print_color(reference); + log_printf("\n"); + log_printf("FAILED\n"); + } + else { + log_printf(" OK"); + } + + if (test_display) { + dst_format = al_get_display_format(display); + from_display = al_get_pixel(al_get_backbuffer(display), 0, 0); + reference = reference_implementation( + src_col, dst_col, src_format, dst_format, + src_mode, dst_mode, src_alpha, dst_alpha, operation); + + if (!same_color(reference, from_display)) { + test(src_col, dst_col, src_format, + dst_format, src_mode, dst_mode, src_alpha, dst_alpha, + operation, true); + log_printf("displayed : "); + print_color(from_display); + log_printf("\n"); + log_printf("expected : "); + print_color(reference); + log_printf("\n"); + log_printf("(FAILED on display)\n"); + } + } +} + +static void do_test1(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, + int src_format, int dst_format) +{ + int i, j, k, l, m; + int smodes[4] = {ALLEGRO_ALPHA, ALLEGRO_ZERO, ALLEGRO_ONE, + ALLEGRO_INVERSE_ALPHA}; + int dmodes[4] = {ALLEGRO_INVERSE_ALPHA, ALLEGRO_ZERO, ALLEGRO_ONE, + ALLEGRO_ALPHA}; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) { + for (l = 0; l < 4; l++) { + for (m = 0; m < 3; m++) { + do_test2(src_col, dst_col, + src_format, dst_format, + smodes[i], dmodes[j], smodes[k], dmodes[l], + m); + } + } + } + } + } +} + +#define C al_map_rgba_f + +int main(int argc, char **argv) +{ + int i, j, l, m; + ALLEGRO_COLOR src_colors[2]; + ALLEGRO_COLOR dst_colors[2]; + int src_formats[2] = { + ALLEGRO_PIXEL_FORMAT_ABGR_8888, + ALLEGRO_PIXEL_FORMAT_BGR_888 + }; + int dst_formats[2] = { + ALLEGRO_PIXEL_FORMAT_ABGR_8888, + ALLEGRO_PIXEL_FORMAT_BGR_888 + }; + src_colors[0] = C(0, 0, 0, 1); + src_colors[1] = C(1, 1, 1, 1); + dst_colors[0] = C(1, 1, 1, 1); + dst_colors[1] = C(0, 0, 0, 0); + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d")) + test_display = 1; + else + test_only_index = strtol(argv[i], NULL, 10); + } + + if (!al_init()) { + abort_example("Could not initialise Allegro\n"); + } + + open_log(); + + al_init_primitives_addon(); + if (test_display) { + display = al_create_display(100, 100); + if (!display) { + abort_example("Unable to create display\n"); + } + } + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (l = 0; l < 2; l++) { + for (m = 0; m < 2; m++) { + do_test1( + src_colors[i], + dst_colors[j], + src_formats[l], + dst_formats[m]); + } + } + } + } + log_printf("\nDone\n"); + + if (test_only_index && test_display) { + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + al_flip_display(); + al_install_keyboard(); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_wait_for_event(queue, &event); + } + + close_log(true); + + return 0; +} + diff --git a/allegro/examples/ex_blit.c b/allegro/examples/ex_blit.c new file mode 100644 index 00000000..5eb14ad3 --- /dev/null +++ b/allegro/examples/ex_blit.c @@ -0,0 +1,279 @@ +/* An example demonstrating different blending modes. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "common.c" + +struct Example +{ + ALLEGRO_BITMAP *pattern; + ALLEGRO_FONT *font; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_COLOR background, text, white; + + double timer[4], counter[4]; + int FPS; + float text_x, text_y; +} ex; + +static ALLEGRO_BITMAP *example_bitmap(int w, int h) +{ + int i, j; + float mx = w * 0.5; + float my = h * 0.5; + ALLEGRO_STATE state; + ALLEGRO_BITMAP *pattern = al_create_bitmap(w, h); + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); + al_set_target_bitmap(pattern); + al_lock_bitmap(pattern, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); + for (i = 0; i < w; i++) { + for (j = 0; j < h; j++) { + float a = atan2(i - mx, j - my); + float d = sqrt(pow(i - mx, 2) + pow(j - my, 2)); + float sat = pow(1.0 - 1 / (1 + d * 0.1), 5); + float hue = 3 * a * 180 / ALLEGRO_PI; + hue = (hue / 360 - floorf(hue / 360)) * 360; + al_put_pixel(i, j, al_color_hsv(hue, sat, 1)); + } + } + al_put_pixel(0, 0, al_map_rgb(0, 0, 0)); + al_unlock_bitmap(pattern); + al_restore_state(&state); + return pattern; +} + +static void set_xy(float x, float y) +{ + ex.text_x = x; + ex.text_y = y; +} + +static void get_xy(float *x, float *y) +{ + *x = ex.text_x; + *y = ex.text_y; +} + +static void print(char const *format, ...) +{ + va_list list; + char message[1024]; + int th = al_get_font_line_height(ex.font); + va_start(list, format); + vsnprintf(message, sizeof message, format, list); + va_end(list); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(ex.font, ex.text, ex.text_x, ex.text_y, 0, "%s", message); + ex.text_y += th; +} + +static void start_timer(int i) +{ + ex.timer[i] -= al_get_time(); + ex.counter[i]++; +} + +static void stop_timer(int i) +{ + ex.timer[i] += al_get_time(); +} + +static double get_fps(int i) +{ + if (ex.timer[i] == 0) + return 0; + return ex.counter[i] / ex.timer[i]; +} + +static void draw(void) +{ + float x, y; + int iw = al_get_bitmap_width(ex.pattern); + int ih = al_get_bitmap_height(ex.pattern); + ALLEGRO_BITMAP *screen, *temp; + ALLEGRO_LOCKED_REGION *lock; + void *data; + int size, i, format; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_clear_to_color(ex.background); + + screen = al_get_target_bitmap(); + + set_xy(8, 8); + + /* Test 1. */ + /* Disabled: drawing to same bitmap is not supported. */ + /* + print("Screen -> Screen (%.1f fps)", get_fps(0)); + get_xy(&x, &y); + al_draw_bitmap(ex.pattern, x, y, 0); + + start_timer(0); + al_draw_bitmap_region(screen, x, y, iw, ih, x + 8 + iw, y, 0); + stop_timer(0); + set_xy(x, y + ih); + */ + + /* Test 2. */ + print("Screen -> Bitmap -> Screen (%.1f fps)", get_fps(1)); + get_xy(&x, &y); + al_draw_bitmap(ex.pattern, x, y, 0); + + temp = al_create_bitmap(iw, ih); + al_set_target_bitmap(temp); + al_clear_to_color(al_map_rgba_f(1, 0, 0, 1)); + start_timer(1); + al_draw_bitmap_region(screen, x, y, iw, ih, 0, 0, 0); + + al_set_target_bitmap(screen); + al_draw_bitmap(temp, x + 8 + iw, y, 0); + stop_timer(1); + set_xy(x, y + ih); + + al_destroy_bitmap(temp); + + /* Test 3. */ + print("Screen -> Memory -> Screen (%.1f fps)", get_fps(2)); + get_xy(&x, &y); + al_draw_bitmap(ex.pattern, x, y, 0); + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + temp = al_create_bitmap(iw, ih); + al_set_target_bitmap(temp); + al_clear_to_color(al_map_rgba_f(1, 0, 0, 1)); + start_timer(2); + al_draw_bitmap_region(screen, x, y, iw, ih, 0, 0, 0); + + al_set_target_bitmap(screen); + al_draw_bitmap(temp, x + 8 + iw, y, 0); + stop_timer(2); + set_xy(x, y + ih); + + al_destroy_bitmap(temp); + al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); + + /* Test 4. */ + print("Screen -> Locked -> Screen (%.1f fps)", get_fps(3)); + get_xy(&x, &y); + al_draw_bitmap(ex.pattern, x, y, 0); + + start_timer(3); + lock = al_lock_bitmap_region(screen, x, y, iw, ih, + ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + format = lock->format; + size = lock->pixel_size; + data = malloc(size * iw * ih); + for (i = 0; i < ih; i++) + memcpy((char*)data + i * size * iw, + (char*)lock->data + i * lock->pitch, size * iw); + al_unlock_bitmap(screen); + + lock = al_lock_bitmap_region(screen, x + 8 + iw, y, iw, ih, format, + ALLEGRO_LOCK_WRITEONLY); + for (i = 0; i < ih; i++) + memcpy((char*)lock->data + i * lock->pitch, + (char*)data + i * size * iw, size * iw); + al_unlock_bitmap(screen); + free(data); + stop_timer(3); + set_xy(x, y + ih); + +} + +static void tick(void) +{ + draw(); + al_flip_display(); +} + +static void run(void) +{ + ALLEGRO_EVENT event; + bool need_draw = true; + + while (1) { + if (need_draw && al_is_event_queue_empty(ex.queue)) { + tick(); + need_draw = false; + } + + al_wait_for_event(ex.queue, &event); + + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + return; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + return; + break; + + case ALLEGRO_EVENT_TIMER: + need_draw = true; + break; + } + } +} + +static void init(void) +{ + ex.FPS = 60; + + ex.font = al_load_font("data/fixed_font.tga", 0, 0); + if (!ex.font) { + abort_example("data/fixed_font.tga not found\n"); + } + ex.background = al_color_name("beige"); + ex.text = al_color_name("black"); + ex.white = al_color_name("white"); + ex.pattern = example_bitmap(100, 100); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + al_install_mouse(); + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + init(); + + timer = al_create_timer(1.0 / ex.FPS); + + ex.queue = al_create_event_queue(); + al_register_event_source(ex.queue, al_get_keyboard_event_source()); + al_register_event_source(ex.queue, al_get_mouse_event_source()); + al_register_event_source(ex.queue, al_get_display_event_source(display)); + al_register_event_source(ex.queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + run(); + + al_destroy_event_queue(ex.queue); + + return 0; +} diff --git a/allegro/examples/ex_camera.c b/allegro/examples/ex_camera.c new file mode 100644 index 00000000..2aaf2628 --- /dev/null +++ b/allegro/examples/ex_camera.c @@ -0,0 +1,583 @@ +/* An example demonstrating how to use ALLEGRO_TRANSFORM to represent a 3D + * camera. + */ +#include +#include +#include +#include +#include +#include + +#include "common.c" + +#define pi ALLEGRO_PI + +typedef struct { + float x, y, z; +} Vector; + +typedef struct { + Vector position; + Vector xaxis; /* This represent the direction looking to the right. */ + Vector yaxis; /* This is the up direction. */ + Vector zaxis; /* This is the direction towards the viewer ('backwards'). */ + double vertical_field_of_view; /* In radians. */ +} Camera; + +typedef struct { + Camera camera; + + /* controls sensitivity */ + double mouse_look_speed; + double movement_speed; + + /* keyboard and mouse state */ + int button[10]; + int key[ALLEGRO_KEY_MAX]; + int keystate[ALLEGRO_KEY_MAX]; + int mouse_dx, mouse_dy; + + /* control scheme selection */ + int controls; + char const *controls_names[3]; + + /* the vertex data */ + int n, v_size; + ALLEGRO_VERTEX *v; + + /* used to draw some info text */ + ALLEGRO_FONT *font; + + /* if not NULL the skybox picture to use */ + ALLEGRO_BITMAP *skybox; +} Example; + +Example ex; + +/* Calculate the dot product between two vectors. This corresponds to the + * angle between them times their lengths. + */ +static double vector_dot_product(Vector a, Vector b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +/* Calculate the cross product of two vectors. This produces a normal to the + * plane containing the operands. + */ +static Vector vector_cross_product(Vector a, Vector b) +{ + Vector v = {a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x}; + return v; +} + +/* Return a vector multiplied by a scalar. */ +static Vector vector_mul(Vector a, float s) +{ + Vector v = {a.x * s, a.y * s, a.z * s}; + return v; +} + +/* Return the vector norm (length). */ +static double vector_norm(Vector a) +{ + return sqrt(vector_dot_product(a, a)); +} + +/* Return a normalized version of the given vector. */ +static Vector vector_normalize(Vector a) +{ + double s = vector_norm(a); + if (s == 0) + return a; + return vector_mul(a, 1 / s); +} + +/* In-place add another vector to a vector. */ +static void vector_iadd(Vector *a, Vector b) +{ + a->x += b.x; + a->y += b.y; + a->z += b.z; +} + +/* Rotate the camera around the given axis. */ +static void camera_rotate_around_axis(Camera *c, Vector axis, double radians) +{ + ALLEGRO_TRANSFORM t; + al_identity_transform(&t); + al_rotate_transform_3d(&t, axis.x, axis.y, axis.z, radians); + al_transform_coordinates_3d(&t, &c->yaxis.x, &c->yaxis.y, &c->yaxis.z); + al_transform_coordinates_3d(&t, &c->zaxis.x, &c->zaxis.y, &c->zaxis.z); + + /* Make sure the axes remain orthogonal to each other. */ + c->zaxis = vector_normalize(c->zaxis); + c->xaxis = vector_cross_product(c->yaxis, c->zaxis); + c->xaxis = vector_normalize(c->xaxis); + c->yaxis = vector_cross_product(c->zaxis, c->xaxis); +} + +/* Move the camera along its x axis and z axis (which corresponds to + * right and backwards directions). + */ +static void camera_move_along_direction(Camera *camera, double right, + double forward) +{ + vector_iadd(&camera->position, vector_mul(camera->xaxis, right)); + vector_iadd(&camera->position, vector_mul(camera->zaxis, -forward)); +} + +/* Get a vector with y = 0 looking in the opposite direction as the camera z + * axis. If looking straight up or down returns a 0 vector instead. + */ +static Vector get_ground_forward_vector(Camera *camera) +{ + Vector move = vector_mul(camera->zaxis, -1); + move.y = 0; + return vector_normalize(move); +} + +/* Get a vector with y = 0 looking in the same direction as the camera x axis. + * If looking straight up or down returns a 0 vector instead. + */ +static Vector get_ground_right_vector(Camera *camera) +{ + Vector move = camera->xaxis; + move.y = 0; + return vector_normalize(move); +} + +/* Like camera_move_along_direction but moves the camera along the ground plane + * only. + */ +static void camera_move_along_ground(Camera *camera, double right, + double forward) +{ + Vector f = get_ground_forward_vector(camera); + Vector r = get_ground_right_vector(camera); + camera->position.x += f.x * forward + r.x * right; + camera->position.z += f.z * forward + r.z * right; +} + +/* Calculate the pitch of the camera. This is the angle between the z axis + * vector and our direction vector on the y = 0 plane. + */ +static double get_pitch(Camera *c) +{ + Vector f = get_ground_forward_vector(c); + return asin(vector_dot_product(f, c->yaxis)); +} + +/* Calculate the yaw of the camera. This is basically the compass direction. + */ +static double get_yaw(Camera *c) +{ + return atan2(c->zaxis.x, c->zaxis.z); +} + +/* Calculate the roll of the camera. This is the angle between the x axis + * vector and its project on the y = 0 plane. + */ +static double get_roll(Camera *c) +{ + Vector r = get_ground_right_vector(c); + return asin(vector_dot_product(r, c->yaxis)); +} + +/* Set up a perspective transform. We make the screen span + * 2 vertical units (-1 to +1) with square pixel aspect and the camera's + * vertical field of view. Clip distance is always set to 1. + */ +static void setup_3d_projection(void) +{ + ALLEGRO_TRANSFORM projection; + ALLEGRO_DISPLAY *display = al_get_current_display(); + double dw = al_get_display_width(display); + double dh = al_get_display_height(display); + double f; + al_identity_transform(&projection); + al_translate_transform_3d(&projection, 0, 0, -1); + f = tan(ex.camera.vertical_field_of_view / 2); + al_perspective_transform(&projection, -1 * dw / dh * f, f, + 1, + f * dw / dh, -f, 1000); + al_use_projection_transform(&projection); +} + +/* Adds a new vertex to our scene. */ +static void add_vertex(double x, double y, double z, double u, double v, + ALLEGRO_COLOR color) +{ + int i = ex.n++; + if (i >= ex.v_size) { + ex.v_size += 1; + ex.v_size *= 2; + ex.v = realloc(ex.v, ex.v_size * sizeof *ex.v); + } + ex.v[i].x = x; + ex.v[i].y = y; + ex.v[i].z = z; + ex.v[i].u = u; + ex.v[i].v = v; + ex.v[i].color = color; +} + +/* Adds two triangles (6 vertices) to the scene. */ +static void add_quad(double x, double y, double z, double u, double v, + double ux, double uy, double uz, double uu, double uv, + double vx, double vy, double vz, double vu, double vv, + ALLEGRO_COLOR c1, ALLEGRO_COLOR c2) +{ + add_vertex(x, y, z, u, v, c1); + add_vertex(x + ux, y + uy, z + uz, u + uu, v + uv, c1); + add_vertex(x + vx, y + vy, z + vz, u + vu, v + vv, c2); + add_vertex(x + vx, y + vy, z + vz, u + vu, v + vv, c2); + add_vertex(x + ux, y + uy, z + uz, u + uu, v + uv, c1); + add_vertex(x + ux + vx, y + uy + vy, z + uz + vz, u + uu + vu, + v + uv + vv, c2); +} + +/* Create a checkerboard made from colored quads. */ +static void add_checkerboard(void) +{ + int x, y; + ALLEGRO_COLOR c1 = al_color_name("yellow"); + ALLEGRO_COLOR c2 = al_color_name("green"); + + for (y = 0; y < 20; y++) { + for (x = 0; x < 20; x++) { + double px = x - 20 * 0.5; + double py = 0.2; + double pz = y - 20 * 0.5; + ALLEGRO_COLOR c = c1; + if ((x + y) & 1) { + c = c2; + py -= 0.1; + } + add_quad(px, py, pz, 0, 0, + 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, + c, c); + } + } +} + +/* Create a skybox. This is simply 5 quads with a fixed distance to the + * camera. + */ +static void add_skybox(void) +{ + Vector p = ex.camera.position; + ALLEGRO_COLOR c1 = al_color_name("black"); + ALLEGRO_COLOR c2 = al_color_name("blue"); + ALLEGRO_COLOR c3 = al_color_name("white"); + + double a = 0, b = 0; + if (ex.skybox) { + a = al_get_bitmap_width(ex.skybox) / 4.0; + b = al_get_bitmap_height(ex.skybox) / 3.0; + c1 = c2 = c3; + } + + /* Back skybox wall. */ + add_quad(p.x - 50, p.y - 50, p.z - 50, a * 4, b * 2, + 100, 0, 0, -a, 0, + 0, 100, 0, 0, -b, + c1, c2); + /* Front skybox wall. */ + add_quad(p.x - 50, p.y - 50, p.z + 50, a, b * 2, + 100, 0, 0, a, 0, + 0, 100, 0, 0, -b, + c1, c2); + /* Left skybox wall. */ + add_quad(p.x - 50, p.y - 50, p.z - 50, 0, b * 2, + 0, 0, 100, a, 0, + 0, 100, 0, 0, -b, + c1, c2); + /* Right skybox wall. */ + add_quad(p.x + 50, p.y - 50, p.z - 50, a * 3, b * 2, + 0, 0, 100, -a, 0, + 0, 100, 0, 0, -b, + c1, c2); + + /* Top of skybox. */ + add_vertex(p.x - 50, p.y + 50, p.z - 50, a, 0, c2); + add_vertex(p.x + 50, p.y + 50, p.z - 50, a * 2, 0, c2); + add_vertex(p.x, p.y + 50, p.z, a * 1.5, b * 0.5, c3); + + add_vertex(p.x + 50, p.y + 50, p.z - 50, a * 2, 0, c2); + add_vertex(p.x + 50, p.y + 50, p.z + 50, a * 2, b, c2); + add_vertex(p.x, p.y + 50, p.z, a * 1.5, b * 0.5, c3); + + add_vertex(p.x + 50, p.y + 50, p.z + 50, a * 2, b, c2); + add_vertex(p.x - 50, p.y + 50, p.z + 50, a, b, c2); + add_vertex(p.x, p.y + 50, p.z, a * 1.5, b * 0.5, c3); + + add_vertex(p.x - 50, p.y + 50, p.z + 50, a, b, c2); + add_vertex(p.x - 50, p.y + 50, p.z - 50, a, 0, c2); + add_vertex(p.x, p.y + 50, p.z, a * 1.5, b * 0.5, c3); +} + +static void draw_scene(void) +{ + Camera *c = &ex.camera; + /* We save Allegro's projection so we can restore it for drawing text. */ + ALLEGRO_TRANSFORM projection = *al_get_current_projection_transform(); + ALLEGRO_TRANSFORM t; + ALLEGRO_COLOR back = al_color_name("black"); + ALLEGRO_COLOR front = al_color_name("white"); + int th; + double pitch, yaw, roll; + + setup_3d_projection(); + al_clear_to_color(back); + + /* We use a depth buffer. */ + al_set_render_state(ALLEGRO_DEPTH_TEST, 1); + al_clear_depth_buffer(1); + + /* Recreate the entire scene geometry - this is only a very small example + * so this is fine. + */ + ex.n = 0; + add_checkerboard(); + add_skybox(); + + /* Construct a transform corresponding to our camera. This is an inverse + * translation by the camera position, followed by an inverse rotation + * from the camera orientation. + */ + al_build_camera_transform(&t, + ex.camera.position.x, ex.camera.position.y, ex.camera.position.z, + ex.camera.position.x - ex.camera.zaxis.x, + ex.camera.position.y - ex.camera.zaxis.y, + ex.camera.position.z - ex.camera.zaxis.z, + ex.camera.yaxis.x, ex.camera.yaxis.y, ex.camera.yaxis.z); + al_use_transform(&t); + al_draw_prim(ex.v, NULL, ex.skybox, 0, ex.n, ALLEGRO_PRIM_TRIANGLE_LIST); + + /* Restore projection. */ + al_identity_transform(&t); + al_use_transform(&t); + al_use_projection_transform(&projection); + al_set_render_state(ALLEGRO_DEPTH_TEST, 0); + + /* Draw some text. */ + th = al_get_font_line_height(ex.font); + al_draw_textf(ex.font, front, 0, th * 0, 0, + "look: %+3.1f/%+3.1f/%+3.1f (change with left mouse button and drag)", + -c->zaxis.x, -c->zaxis.y, -c->zaxis.z); + pitch = get_pitch(c) * 180 / pi; + yaw = get_yaw(c) * 180 / pi; + roll = get_roll(c) * 180 / pi; + al_draw_textf(ex.font, front, 0, th * 1, 0, + "pitch: %+4.0f yaw: %+4.0f roll: %+4.0f", pitch, yaw, roll); + al_draw_textf(ex.font, front, 0, th * 2, 0, + "vertical field of view: %3.1f (change with Z/X)", + c->vertical_field_of_view * 180 / pi); + al_draw_textf(ex.font, front, 0, th * 3, 0, "move with WASD or cursor"); + al_draw_textf(ex.font, front, 0, th * 4, 0, "control style: %s (space to change)", + ex.controls_names[ex.controls]); +} + +static void setup_scene(void) +{ + ex.camera.xaxis.x = 1; + ex.camera.yaxis.y = 1; + ex.camera.zaxis.z = 1; + ex.camera.position.y = 2; + ex.camera.vertical_field_of_view = 60 * pi / 180; + + ex.mouse_look_speed = 0.03; + ex.movement_speed = 0.05; + + ex.controls_names[0] = "FPS"; + ex.controls_names[1] = "airplane"; + ex.controls_names[2] = "spaceship"; + + ex.font = al_create_builtin_font(); +} + +static void handle_input(void) +{ + double x = 0, y = 0; + double xy; + if (ex.key[ALLEGRO_KEY_A] || ex.key[ALLEGRO_KEY_LEFT]) x = -1; + if (ex.key[ALLEGRO_KEY_S] || ex.key[ALLEGRO_KEY_DOWN]) y = -1; + if (ex.key[ALLEGRO_KEY_D] || ex.key[ALLEGRO_KEY_RIGHT]) x = 1; + if (ex.key[ALLEGRO_KEY_W] || ex.key[ALLEGRO_KEY_UP]) y = 1; + + /* Change field of view with Z/X. */ + if (ex.key[ALLEGRO_KEY_Z]) { + double m = 20 * pi / 180; + ex.camera.vertical_field_of_view -= 0.01; + if (ex.camera.vertical_field_of_view < m) + ex.camera.vertical_field_of_view = m; + } + if (ex.key[ALLEGRO_KEY_X]) { + double m = 120 * pi / 180; + ex.camera.vertical_field_of_view += 0.01; + if (ex.camera.vertical_field_of_view > m) + ex.camera.vertical_field_of_view = m; + } + + /* In FPS style, always move the camera to height 2. */ + if (ex.controls == 0) { + if (ex.camera.position.y > 2) + ex.camera.position.y -= 0.1; + if (ex.camera.position.y < 2) + ex.camera.position.y = 2; + } + + /* Set the roll (leaning) angle to 0 if not in airplane style. */ + if (ex.controls == 0 || ex.controls == 2) { + double roll = get_roll(&ex.camera); + camera_rotate_around_axis(&ex.camera, ex.camera.zaxis, roll / 60); + } + + /* Move the camera, either freely or along the ground. */ + xy = sqrt(x * x + y * y); + if (xy > 0) { + x /= xy; + y /= xy; + if (ex.controls == 0) { + camera_move_along_ground(&ex.camera, ex.movement_speed * x, + ex.movement_speed * y); + } + if (ex.controls == 1 || ex.controls == 2) { + camera_move_along_direction(&ex.camera, ex.movement_speed * x, + ex.movement_speed * y); + } + } + + /* Rotate the camera, either freely or around world up only. */ + if (ex.button[1]) { + if (ex.controls == 0 || ex.controls == 2) { + Vector up = {0, 1, 0}; + camera_rotate_around_axis(&ex.camera, ex.camera.xaxis, + -ex.mouse_look_speed * ex.mouse_dy); + camera_rotate_around_axis(&ex.camera, up, + -ex.mouse_look_speed * ex.mouse_dx); + } + if (ex.controls == 1) { + camera_rotate_around_axis(&ex.camera, ex.camera.xaxis, + -ex.mouse_look_speed * ex.mouse_dy); + camera_rotate_around_axis(&ex.camera, ex.camera.zaxis, + -ex.mouse_look_speed * ex.mouse_dx); + } + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + int redraw = 0; + char const *skybox_name = NULL; + + if (argc > 1) { + skybox_name = argv[1]; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_font_addon(); + al_init_primitives_addon(); + init_platform_specific(); + al_install_keyboard(); + al_install_mouse(); + + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); + al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST); + al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); + al_set_new_display_flags(ALLEGRO_RESIZABLE); + display = al_create_display(640, 360); + if (!display) { + abort_example("Error creating display\n"); + } + + if (skybox_name) { + al_init_image_addon(); + ex.skybox = al_load_bitmap(skybox_name); + if (ex.skybox) { + printf("Loaded skybox %s: %d x %d\n", skybox_name, + al_get_bitmap_width(ex.skybox), + al_get_bitmap_height(ex.skybox)); + } + else { + printf("Failed loading skybox %s\n", skybox_name); + } + } + + timer = al_create_timer(1.0 / 60); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + setup_scene(); + + al_start_timer(timer); + while (true) { + ALLEGRO_EVENT event; + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + else if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { + al_acknowledge_resize(display); + } + else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + ex.controls++; + ex.controls %= 3; + } + ex.key[event.keyboard.keycode] = 1; + ex.keystate[event.keyboard.keycode] = 1; + } + else if (event.type == ALLEGRO_EVENT_KEY_UP) { + /* In case a key gets pressed and immediately released, we will still + * have set ex.key so it is not lost. + */ + ex.keystate[event.keyboard.keycode] = 0; + } + else if (event.type == ALLEGRO_EVENT_TIMER) { + int i; + handle_input(); + redraw = 1; + + /* Reset keyboard state for keys not held down anymore. */ + for (i = 0; i < ALLEGRO_KEY_MAX; i++) { + if (ex.keystate[i] == 0) + ex.key[i] = 0; + } + ex.mouse_dx = 0; + ex.mouse_dy = 0; + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + ex.button[event.mouse.button] = 1; + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { + ex.button[event.mouse.button] = 0; + } + else if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + ex.mouse_dx += event.mouse.dx; + ex.mouse_dy += event.mouse.dy; + } + + if (redraw && al_is_event_queue_empty(queue)) { + draw_scene(); + + al_flip_display(); + redraw = 0; + } + } + + return 0; +} diff --git a/allegro/examples/ex_clip.c b/allegro/examples/ex_clip.c new file mode 100644 index 00000000..2bd2d036 --- /dev/null +++ b/allegro/examples/ex_clip.c @@ -0,0 +1,242 @@ +/* Test performance of al_draw_bitmap_region, al_create_sub_bitmap and + * al_set_clipping_rectangle when clipping a bitmap. + */ + +#include +#include +#include +#include +#include +#include + +#include "common.c" + +struct Example +{ + ALLEGRO_BITMAP *pattern; + ALLEGRO_FONT *font; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_COLOR background, text, white; + + double timer[4], counter[4]; + int FPS; + float text_x, text_y; +} ex; + +static ALLEGRO_BITMAP *example_bitmap(int w, int h) +{ + int i, j; + float mx = w * 0.5; + float my = h * 0.5; + ALLEGRO_STATE state; + ALLEGRO_BITMAP *pattern = al_create_bitmap(w, h); + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); + al_set_target_bitmap(pattern); + al_lock_bitmap(pattern, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); + for (i = 0; i < w; i++) { + for (j = 0; j < h; j++) { + float a = atan2(i - mx, j - my); + float d = sqrt(pow(i - mx, 2) + pow(j - my, 2)); + float l = 1 - pow(1.0 - 1 / (1 + d * 0.1), 5); + float hue = a * 180 / ALLEGRO_PI; + float sat = 1; + if (i == 0 || j == 0 || i == w - 1 || j == h - 1) { + hue += 180; + } + else if (i == 1 || j == 1 || i == w - 2 || j == h - 2) { + hue += 180; + sat = 0.5; + } + al_put_pixel(i, j, al_color_hsl(hue, sat, l)); + } + } + al_unlock_bitmap(pattern); + al_restore_state(&state); + return pattern; +} + +static void set_xy(float x, float y) +{ + ex.text_x = x; + ex.text_y = y; +} + +static void get_xy(float *x, float *y) +{ + *x = ex.text_x; + *y = ex.text_y; +} + +static void print(char const *format, ...) +{ + va_list list; + char message[1024]; + int th = al_get_font_line_height(ex.font); + + va_start(list, format); + vsnprintf(message, sizeof message, format, list); + va_end(list); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(ex.font, ex.text, ex.text_x, ex.text_y, 0, "%s", message); + + ex.text_y += th; +} + +static void start_timer(int i) +{ + ex.timer[i] -= al_get_time(); + ex.counter[i]++; +} + +static void stop_timer(int i) +{ + ex.timer[i] += al_get_time(); +} + +static double get_fps(int i) +{ + if (ex.timer[i] == 0) + return 0; + return ex.counter[i] / ex.timer[i]; +} + +static void draw(void) +{ + float x, y; + int iw = al_get_bitmap_width(ex.pattern); + int ih = al_get_bitmap_height(ex.pattern); + ALLEGRO_BITMAP *temp; + int cx, cy, cw, ch, gap = 8; + + al_get_clipping_rectangle(&cx, &cy, &cw, &ch); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_clear_to_color(ex.background); + + /* Test 1. */ + set_xy(8, 8); + print("al_draw_bitmap_region (%.1f fps)", get_fps(0)); + get_xy(&x, &y); + al_draw_bitmap(ex.pattern, x, y, 0); + + start_timer(0); + al_draw_bitmap_region(ex.pattern, 1, 1, iw - 2, ih - 2, + x + 8 + iw + 1, y + 1, 0); + stop_timer(0); + set_xy(x, y + ih + gap); + + /* Test 2. */ + print("al_create_sub_bitmap (%.1f fps)", get_fps(1)); + get_xy(&x, &y); + al_draw_bitmap(ex.pattern, x, y, 0); + + start_timer(1); + temp = al_create_sub_bitmap(ex.pattern, 1, 1, iw - 2, ih - 2); + al_draw_bitmap(temp, x + 8 + iw + 1, y + 1, 0); + al_destroy_bitmap(temp); + stop_timer(1); + set_xy(x, y + ih + gap); + + /* Test 3. */ + print("al_set_clipping_rectangle (%.1f fps)", get_fps(2)); + get_xy(&x, &y); + al_draw_bitmap(ex.pattern, x, y, 0); + + start_timer(2); + al_set_clipping_rectangle(x + 8 + iw + 1, y + 1, iw - 2, ih - 2); + al_draw_bitmap(ex.pattern, x + 8 + iw, y, 0); + al_set_clipping_rectangle(cx, cy, cw, ch); + stop_timer(2); + set_xy(x, y + ih + gap); +} + +static void tick(void) +{ + draw(); + al_flip_display(); +} + +static void run(void) +{ + ALLEGRO_EVENT event; + bool need_draw = true; + + while (1) { + if (need_draw && al_is_event_queue_empty(ex.queue)) { + tick(); + need_draw = false; + } + + al_wait_for_event(ex.queue, &event); + + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + return; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + return; + break; + + case ALLEGRO_EVENT_TIMER: + need_draw = true; + break; + } + } +} + +static void init(void) +{ + ex.FPS = 60; + + ex.font = al_create_builtin_font(); + if (!ex.font) { + abort_example("Error creating builtin font.\n"); + } + ex.background = al_color_name("beige"); + ex.text = al_color_name("blue"); + ex.white = al_color_name("white"); + ex.pattern = example_bitmap(100, 100); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + al_install_mouse(); + al_init_font_addon(); + init_platform_specific(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display.\n"); + } + + init(); + + timer = al_create_timer(1.0 / ex.FPS); + + ex.queue = al_create_event_queue(); + al_register_event_source(ex.queue, al_get_keyboard_event_source()); + al_register_event_source(ex.queue, al_get_mouse_event_source()); + al_register_event_source(ex.queue, al_get_display_event_source(display)); + al_register_event_source(ex.queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + run(); + + al_destroy_event_queue(ex.queue); + + return 0; +} diff --git a/allegro/examples/ex_clipboard.c b/allegro/examples/ex_clipboard.c new file mode 100644 index 00000000..e8922ff4 --- /dev/null +++ b/allegro/examples/ex_clipboard.c @@ -0,0 +1,115 @@ +/* An example showing bitmap flipping flags, by Steven Wallace. */ + +#include +#include +#include + +#include "common.c" + +#define INTERVAL 0.1 + + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_FONT *font; + char *text = NULL; + bool done = false; + bool redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + al_init_font_addon(); + init_platform_specific(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + font = al_load_font("data/fixed_font.tga", 0, 0); + if (!font) { + abort_example("Error loading data/fixed_font.tga\n"); + } + + timer = al_create_timer(INTERVAL); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_display_event_source(display)); + + al_start_timer(timer); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + while (!done) { + ALLEGRO_EVENT event; + + if (redraw && al_is_event_queue_empty(queue)) { + if (text) + al_free(text); + if (al_clipboard_has_text(display)) { + text = al_get_clipboard_text(display); + } + else { + text = NULL; + } + + + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + + if (text) { + al_draw_text(font, al_map_rgba_f(1, 1, 1, 1.0), 0, 0, 0, text); + } + else { + al_draw_text(font, al_map_rgba_f(1, 0, 0, 1.0), 0, 0, 0, + "No clipboard text available."); + } + al_flip_display(); + redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + done = true; + } + else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + al_set_clipboard_text(display, "Copied from Allegro!"); + } + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + redraw = true; + break; + } + } + + al_destroy_font(font); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_color.cpp b/allegro/examples/ex_color.cpp new file mode 100644 index 00000000..4c38f834 --- /dev/null +++ b/allegro/examples/ex_color.cpp @@ -0,0 +1,223 @@ +/* + * Example program for the Allegro library, by Elias Pschernig. + * + * Demonstrates some of the conversion functions in the color addon. + */ + +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_ttf.h" +#include "allegro5/allegro_color.h" +#include + +#include "nihgui.hpp" + +#include "common.c" + +#define SLIDERS_COUNT 19 +char const *names[] = {"R", "G", "B", "H", "S", "V", "H", "S", "L", + "Y", "U", "V", "C", "M", "Y", "K", "L", "C", "H"}; + +float clamp(float x) +{ + if (x < 0) + return 0; + if (x > 1) + return 1; + return x; +} + +class Prog { +private: + Dialog d; + VSlider sliders[SLIDERS_COUNT]; + Label labels[SLIDERS_COUNT]; + Label labels2[SLIDERS_COUNT]; + int previous[SLIDERS_COUNT]; + +public: + Prog(const Theme & theme, ALLEGRO_DISPLAY *display); + void run(); + +private: + void draw_swatch(float x, float y, float w, float h, float v[3]); +}; + +Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : + d(Dialog(theme, display, 640, 480)) +{ + for (int i = 0; i < SLIDERS_COUNT; i++) { + int j = i < 12 ? i / 3 : i < 16 ? 4 : 5; + sliders[i] = VSlider(1000, 1000); + d.add(sliders[i], 8 + i * 32 + j * 16, 8, 15, 256); + labels[i].set_text(names[i]); + d.add(labels[i], i * 32 + j * 16, 8 + 256, 32, 20); + d.add(labels2[i], i * 32 + j * 16, 8 + 276, 32, 20); + previous[i] = 0; + } +} + +void Prog::run() +{ + d.prepare(); + + while (!d.is_quit_requested()) { + if (d.is_draw_requested()) { + al_clear_to_color(al_map_rgb(128, 128, 128)); + float v[SLIDERS_COUNT]; + int keep = -1; + for (int i = 0; i < SLIDERS_COUNT; i++) { + int x = sliders[i].get_cur_value(); + v[i] = x / 1000.0; + if (previous[i] != x) { + keep = i; + } + } + + if (keep != -1) { + int space = keep < 12 ? keep / 3 : keep < 16 ? 4 : 5; + switch (space) { + case 0: + al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); + al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); + al_color_rgb_to_cmyk(v[0], v[1], v[2], v + 12, v + 13, v + 14, v + 15); + al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); + al_color_rgb_to_lch(v[0], v[1], v[2], v + 16, v + 17, v + 18); + v[3] /= 360; + v[6] /= 360; + v[18] /= ALLEGRO_PI * 2; + break; + case 1: + al_color_hsv_to_rgb(v[3] * 360, v[4], v[5], v + 0, v + 1, v + 2); + al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); + al_color_rgb_to_cmyk(v[0], v[1], v[2], v + 12, v + 13, v + 14, v + 15); + al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); + al_color_rgb_to_lch(v[0], v[1], v[2], v + 16, v + 17, v + 18); + v[6] /= 360; + v[18] /= ALLEGRO_PI * 2; + break; + case 2: + al_color_hsl_to_rgb(v[6] * 360, v[7], v[8], v + 0, v + 1, v + 2); + al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); + al_color_rgb_to_cmyk(v[0], v[1], v[2], v + 12, v + 13, v + 14, v + 15); + al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); + al_color_rgb_to_lch(v[0], v[1], v[2], v + 16, v + 17, v + 18); + v[3] /= 360; + v[18] /= ALLEGRO_PI * 2; + break; + case 3: + al_color_yuv_to_rgb(v[9], v[10], v[11], v + 0, v + 1, v + 2); + v[0] = clamp(v[0]); + v[1] = clamp(v[1]); + v[2] = clamp(v[2]); + al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); + al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); + al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); + al_color_rgb_to_cmyk(v[0], v[1], v[2], v + 12, v + 13, v + 14, v + 15); + al_color_rgb_to_lch(v[0], v[1], v[2], v + 16, v + 17, v + 18); + v[3] /= 360; + v[6] /= 360; + v[18] /= ALLEGRO_PI * 2; + break; + case 4: + al_color_cmyk_to_rgb(v[12], v[13], v[14], v[15], v + 0, v + 1, v + 2); + al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); + al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); + al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); + al_color_rgb_to_lch(v[0], v[1], v[2], v + 16, v + 17, v + 18); + v[3] /= 360; + v[6] /= 360; + v[18] /= ALLEGRO_PI * 2; + break; + case 5: + al_color_lch_to_rgb(v[16], v[17], v[18] * 2 * ALLEGRO_PI, v + 0, v + 1, v + 2); + v[0] = clamp(v[0]); + v[1] = clamp(v[1]); + v[2] = clamp(v[2]); + al_color_rgb_to_hsv(v[0], v[1], v[2], v + 3, v + 4, v + 5); + al_color_rgb_to_hsl(v[0], v[1], v[2], v + 6, v + 7, v + 8); + al_color_rgb_to_yuv(v[0], v[1], v[2], v + 9, v + 10, v + 11); + al_color_rgb_to_lch(v[0], v[1], v[2], v + 16, v + 17, v + 18); + v[3] /= 360; + v[6] /= 360; + v[18] /= ALLEGRO_PI * 2; + break; + } + } + + for (int i = 0; i < SLIDERS_COUNT; i++) { + sliders[i].set_cur_value((int)(v[i] * 1000)); + previous[i] = sliders[i].get_cur_value(); + char c[100]; + sprintf(c, "%d", (int)(v[i] * 100)); + labels2[i].set_text(c); + } + + d.draw(); + + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + int w = al_get_bitmap_width(target); + int h = al_get_bitmap_height(target); + draw_swatch(0, h - 80, w, h, v); + + al_flip_display(); + } + + d.run_step(true); + } +} + +void Prog::draw_swatch(float x1, float y1, float x2, float y2, float v[3]) +{ + al_draw_filled_rectangle(x1, y1, x2, y2, al_map_rgb_f(v[0], v[1], v[2])); + + char const *name = al_color_rgb_to_name(v[0], v[1], v[2]); + char html[8]; + al_color_rgb_to_html(v[0], v[1], v[2], html); + al_draw_text(d.get_theme().font, al_map_rgb(0, 0, 0), x1, y1 - 20, 0, name); + al_draw_text(d.get_theme().font, al_map_rgb(0, 0, 0), x1, y1 - 40, 0, html); +} + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + + al_init_font_addon(); + al_init_ttf_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(720, 480); + if (!display) { + abort_example("Unable to create display\n"); + } + font = al_load_font("data/DejaVuSans.ttf", 12, 0); + if (!font) { + abort_example("Failed to load data/DejaVuSans.ttf\n"); + } + + /* Prog is destroyed at the end of this scope. */ + { + Theme theme(font); + Prog prog(theme, display); + prog.run(); + } + + al_destroy_font(font); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_color2.c b/allegro/examples/ex_color2.c new file mode 100644 index 00000000..47992233 --- /dev/null +++ b/allegro/examples/ex_color2.c @@ -0,0 +1,367 @@ +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include +#include +#include + +#include "common.c" + +#define FPS 60 + +typedef struct { + ALLEGRO_COLOR rgb; + float l, a, b; +} Color; + +struct Example { + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *lab[512]; + ALLEGRO_COLOR black; + ALLEGRO_COLOR white; + Color color[2]; + int mx, my; + int mb; // 1 = clicked, 2 = released, 3 = pressed + int slider; + int top_y; + int left_x; + int slider_x; + int half_x; +} example; + +static void draw_lab(int l) +{ + if (example.lab[l]) return; + + example.lab[l] = al_create_bitmap(512, 512); + ALLEGRO_LOCKED_REGION *rg = al_lock_bitmap(example.lab[l], + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); + int x, y; + for (y = 0; y < 512; y++) { + for (x = 0; x < 512; x++) { + float a = (x - 511.0 / 2) / (511.0 / 2); + float b = (y - 511.0 / 2) / (511.0 / 2); + b = -b; + ALLEGRO_COLOR rgb = al_color_lab(l / 511.0, a, b); + if (!al_is_color_valid(rgb)) { + rgb = al_map_rgb_f(0, 0, 0); + } + int red = 255 * rgb.r; + int green = 255 * rgb.g; + int blue = 255 * rgb.b; + + uint8_t *p = rg->data; + p += rg->pitch * y; + p += x * 4; + p[0] = red; + p[1] = green; + p[2] = blue; + p[3] = 255; + } + } + al_unlock_bitmap(example.lab[l]); +} + +static void draw_range(int ci) +{ + float l = example.color[ci].l; + int cx = (example.color[ci].a * 511.0 / 2) + 511.0 / 2; + int cy = (-example.color[ci].b * 511.0 / 2) + 511.0 / 2; + int r = 2; + /* Loop around the center in outward circles, starting with a 3 x 3 + * rectangle, then 5 x 5, then 7 x 7, and so on. + * Each loop has four sides, top, right, bottom, left. For example + * these are the four loops for the 5 x 5 case: + * 1 2 3 4 . + * . . + * . . + * . . + * . . . . . + * + * o o o o 1 + * . 2 + * . 3 + * . 4 + * . . . . . + * + * o o o o o + * . o + * . o + * . 3 2 1 1 + * + * o o o o o + * 4 o + * 3 o + * 2 o + * 1 o o o o + * + * 1654321 + */ + while (true) { + bool found = false; + int x = cx - r / 2; + int y = cy - r / 2; + int i; + for (i = 0; i < r * 4; i++) { + if (i < r) x++; + else if (i < r * 2) y++; + else if (i < r * 3) x--; + else y--; + + float a = (x - 511.0 / 2) / (511.0 / 2); + float b = (y - 511.0 / 2) / (511.0 / 2); + float rf, gf, bf; + b = -b; + al_color_lab_to_rgb(l, a, b, &rf, &gf, &bf); + if (rf < 0 || rf > 1 || gf < 0 || gf > 1 || bf < 0 || bf > 1) { + continue; + } + ALLEGRO_COLOR rgb = {rf, gf, bf, 1}; + float d = al_color_distance_ciede2000(rgb, example.color[ci].rgb); + if (d <= 0.05) { + if (d > 0.04) { + al_draw_pixel(example.half_x * ci + example.left_x + x, + example.top_y + y, example.white); + } + found = true; + } + } + if (!found) break; + r += 2; + if (r > 128) break; + } +} + +static void init(void) +{ + example.black = al_map_rgb_f(0, 0, 0); + example.white = al_map_rgb_f(1, 1, 1); + example.left_x = 120; + example.top_y = 48; + example.slider_x = 48; + example.color[0].l = 0.5; + example.color[1].l = 0.5; + example.color[0].a = 0.2; + example.half_x = al_get_display_width(al_get_current_display()) / 2; +} + +static void draw_axis(float x, float y, float a, float a2, float l, + float tl, char const *label, int ticks, + char const *numformat, float num1, float num2, float num) { + al_draw_line(x, y, x + l * cos(a), y - l * sin(a), example.white, 1); + int i; + for (i = 0; i < ticks; i++) { + float x2 = x + l * cos(a) * i / (ticks - 1); + float y2 = y - l * sin(a) * i / (ticks - 1); + al_draw_line(x2, y2, x2 + tl * cos(a2), y2 - tl * sin(a2), example.white, 1); + al_draw_textf(example.font, example.white, + (int)(x2 + (tl + 2) * cos(a2)), (int)(y2 - (tl + 2) * sin(a2)), ALLEGRO_ALIGN_RIGHT, numformat, + num1 + i * (num2 - num1) / (ticks - 1)); + } + float lv = (num - num1) * l / (num2 - num1); + al_draw_filled_circle(x + lv * cos(a), y - lv * sin(a), 8, example.white); + al_draw_textf(example.font, example.white, + (int)(x + (l + 4) * cos(a)) - 24, (int)(y - (l + 4) * sin(a)) - 12, 0, "%s", label); +} + +static void redraw(void) +{ + al_clear_to_color(example.black); + int w = al_get_display_width(al_get_current_display()); + int h = al_get_display_height(al_get_current_display()); + + int ci; + for (ci = 0; ci < 2; ci++) { + int cx = w / 2 * ci; + + float l = example.color[ci].l; + float a = example.color[ci].a; + float b = example.color[ci].b; + + ALLEGRO_COLOR rgb = example.color[ci].rgb; + + draw_lab((int)(l * 511)); + + al_draw_bitmap(example.lab[(int)(l * 511)], cx + example.left_x, example.top_y, 0); + + draw_axis(cx + example.left_x, example.top_y + 512.5, 0, ALLEGRO_PI / -2, 512, 16, + "a*", 11, "%.2f", -1, 1, a); + draw_axis(cx + example.left_x - 0.5, example.top_y + 512, ALLEGRO_PI / 2, ALLEGRO_PI, + 512, 16, "b*", 11, "%.2f", -1, 1, b); + + al_draw_textf(example.font, example.white, cx + example.left_x + 36, 8, 0, + "L*a*b* = %.2f/%.2f/%.2f sRGB = %.2f/%.2f/%.2f", + l, a, b, rgb.r, rgb.g, rgb.b); + draw_axis(cx + example.slider_x - 0.5, example.top_y + 512, ALLEGRO_PI / 2, ALLEGRO_PI, + 512, 4, "L*", 3, "%.1f", 0, 1, l); + + ALLEGRO_COLOR c = al_map_rgb_f(rgb.r, rgb.g, rgb.b); + al_draw_filled_rectangle(cx, h - 128, cx + w / 2, h, c); + + draw_range(ci); + } + + al_draw_textf(example.font, example.white, example.left_x + 36, 28, 0, + "%s", "Lab colors visible in sRGB"); + al_draw_textf(example.font, example.white, example.half_x + example.left_x + 36, 28, 0, + "%s", "ellipse shows CIEDE2000 between 0.4 and 0.5"); + + al_draw_line(w / 2, 0, w / 2, h - 128, example.white, 4); + + float dr = example.color[0].rgb.r - example.color[1].rgb.r; + float dg = example.color[0].rgb.g - example.color[1].rgb.g; + float db = example.color[0].rgb.b - example.color[1].rgb.b; + float drgb = sqrt(dr * dr + dg * dg + db * db); + float dl = example.color[0].l - example.color[1].l; + float da = example.color[0].a - example.color[1].a; + db = example.color[0].b - example.color[1].b; + float dlab = sqrt(da * da + db * db + dl * dl); + float d2000 = al_color_distance_ciede2000(example.color[0].rgb, + example.color[1].rgb); + al_draw_textf(example.font, example.white, w / 2, h - 64, + ALLEGRO_ALIGN_CENTER, "dRGB = %.2f", drgb); + al_draw_textf(example.font, example.white, w / 2, h - 64 + 12, + ALLEGRO_ALIGN_CENTER, "dLab = %.2f", dlab); + al_draw_textf(example.font, example.white, w / 2, h - 64 + 24, + ALLEGRO_ALIGN_CENTER, "CIEDE2000 = %.2f", d2000); + + al_draw_rectangle(w / 2 - 80, h - 70, w / 2 + 80, h - 24, + example.white, 4); +} + +static void update(void) +{ + if (example.mb == 1 || example.mb == 3) { + if (example.mb == 1) { + int s = 0; + int mx = example.mx; + if (example.mx >= example.half_x) { + mx -= example.half_x; + s += 2; + } + if (mx > example.left_x) { + s += 1; + } + example.slider = s; + } + + if (example.slider == 0 || example.slider == 2) { + int l = example.my - example.top_y; + if (l < 0) l = 0; + if (l > 511) l = 511; + example.color[example.slider / 2].l = 1 - l / 511.0; + } + else { + int ci = example.slider / 2; + int a = example.mx - example.left_x - ci * example.half_x; + int b = example.my - example.top_y; + b = 511 - b; + if (a < 0) a = 0; + if (b < 0) b = 0; + if (a > 511) a = 511; + if (b > 511) b = 511; + example.color[ci].a = 2 * a / 511.0 - 1; + example.color[ci].b = 2 * b / 511.0 - 1; + } + } + + if (example.mb == 1) example.mb = 3; + if (example.mb == 2) example.mb = 0; + + int ci; + for (ci = 0; ci < 2; ci++) { + example.color[ci].rgb = al_color_lab(example.color[ci].l, + example.color[ci].a, example.color[ci].b); + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_DISPLAY *display; + int w = 1280, h = 720; + bool done = false; + bool need_redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + al_init_font_addon(); + example.font = al_create_builtin_font(); + + init_platform_specific(); + + display = al_create_display(w, h); + if (!display) { + abort_example("Error creating display.\n"); + } + + al_install_keyboard(); + al_install_mouse(); + al_init_primitives_addon(); + + init(); + + timer = al_create_timer(1.0 / FPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_register_event_source(queue, al_get_display_event_source(display)); + + al_start_timer(timer); + + while (!done) { + ALLEGRO_EVENT event; + + if (need_redraw) { + redraw(); + al_flip_display(); + need_redraw = false; + } + + while (true) { + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_CHAR: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + break; + + case ALLEGRO_EVENT_MOUSE_AXES: + example.mx = event.mouse.x; + example.my = event.mouse.y; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + example.mb = 1; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + example.mb = 2; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + update(); + need_redraw = true; + break; + } + if (al_is_event_queue_empty(queue)) + break; + } + } + + return 0; +} diff --git a/allegro/examples/ex_compressed.c b/allegro/examples/ex_compressed.c new file mode 100644 index 00000000..3a6b656d --- /dev/null +++ b/allegro/examples/ex_compressed.c @@ -0,0 +1,194 @@ +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_font.h" + +#include "common.c" + +typedef struct BITMAP_TYPE { + ALLEGRO_BITMAP* bmp; + ALLEGRO_BITMAP* clone; + ALLEGRO_BITMAP* decomp; + ALLEGRO_BITMAP* lock_clone; + ALLEGRO_PIXEL_FORMAT format; + const char* name; +} BITMAP_TYPE; + +int main(int argc, char **argv) +{ + const char *filename; + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *bkg; + bool redraw = true; + int ii; + int cur_bitmap = 0; + bool compare = false; + #define NUM_BITMAPS 4 + BITMAP_TYPE bitmaps[NUM_BITMAPS] = { + {NULL, NULL, NULL, NULL, ALLEGRO_PIXEL_FORMAT_ANY, "Uncompressed"}, + {NULL, NULL, NULL, NULL, ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1, "DXT1"}, + {NULL, NULL, NULL, NULL, ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3, "DXT3"}, + {NULL, NULL, NULL, NULL, ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5, "DXT5"}, + }; + + if (argc > 1) { + filename = argv[1]; + } + else { + filename = "data/mysha.pcx"; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + if (argc > 2) { + al_set_new_display_adapter(atoi(argv[2])); + } + + al_init_image_addon(); + al_init_font_addon(); + al_install_keyboard(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + for (ii = 0; ii < NUM_BITMAPS; ii++) { + double t0, t1; + al_set_new_bitmap_format(bitmaps[ii].format); + + /* Load */ + t0 = al_get_time(); + bitmaps[ii].bmp = al_load_bitmap(filename); + t1 = al_get_time(); + + if (!bitmaps[ii].bmp) { + abort_example("%s not found or failed to load\n", filename); + } + log_printf("%s load time: %f sec\n", bitmaps[ii].name, t1 - t0); + + /* Clone */ + t0 = al_get_time(); + bitmaps[ii].clone = al_clone_bitmap(bitmaps[ii].bmp); + t1 = al_get_time(); + + if (!bitmaps[ii].clone) { + abort_example("Couldn't clone %s\n", bitmaps[ii].name); + } + log_printf("%s clone time: %f sec\n", bitmaps[ii].name, t1 - t0); + + /* Decompress */ + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY); + t0 = al_get_time(); + bitmaps[ii].decomp = al_clone_bitmap(bitmaps[ii].bmp); + t1 = al_get_time(); + + if (!bitmaps[ii].decomp) { + abort_example("Couldn't decompress %s\n", bitmaps[ii].name); + } + log_printf("%s decompress time: %f sec\n", bitmaps[ii].name, t1 - t0); + + /* RW lock */ + al_set_new_bitmap_format(bitmaps[ii].format); + bitmaps[ii].lock_clone = al_clone_bitmap(bitmaps[ii].bmp); + + if (!bitmaps[ii].lock_clone) { + abort_example("Couldn't clone %s\n", bitmaps[ii].name); + } + + if (al_get_bitmap_width(bitmaps[ii].bmp) > 128 + && al_get_bitmap_height(bitmaps[ii].bmp) > 128) { + int bitmap_format = al_get_bitmap_format(bitmaps[ii].bmp); + int block_width = al_get_pixel_block_width(bitmap_format); + int block_height = al_get_pixel_block_height(bitmap_format); + + /* Lock and unlock it, hopefully causing a no-op operation */ + al_lock_bitmap_region_blocked(bitmaps[ii].lock_clone, + 16 / block_width, 16 / block_height, 64 / block_width, + 64 / block_height, ALLEGRO_LOCK_READWRITE); + + al_unlock_bitmap(bitmaps[ii].lock_clone); + } + } + + bkg = al_load_bitmap("data/bkg.png"); + if (!bkg) { + abort_example("data/bkg.png not found or failed to load\n"); + } + + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY); + font = al_create_builtin_font(); + timer = al_create_timer(1.0 / 30); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + goto EXIT; + case ALLEGRO_EVENT_TIMER: + redraw = true; + break; + case ALLEGRO_EVENT_KEY_DOWN: + switch (event.keyboard.keycode) { + case ALLEGRO_KEY_LEFT: + cur_bitmap = (cur_bitmap - 1 + NUM_BITMAPS) % NUM_BITMAPS; + break; + case ALLEGRO_KEY_RIGHT: + cur_bitmap = (cur_bitmap + 1) % NUM_BITMAPS; + break; + case ALLEGRO_KEY_SPACE: + compare = true; + break; + case ALLEGRO_KEY_ESCAPE: + goto EXIT; + } + break; + case ALLEGRO_EVENT_KEY_UP: + if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + compare = false; + } + break; + } + if (redraw && al_is_event_queue_empty(queue)) { + int w = al_get_bitmap_width(bitmaps[cur_bitmap].bmp); + int h = al_get_bitmap_height(bitmaps[cur_bitmap].bmp); + int idx = compare ? 0 : cur_bitmap; + redraw = false; + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_draw_bitmap(bkg, 0, 0, 0); + al_draw_textf(font, al_map_rgb_f(1, 1, 1), 5, 5, ALLEGRO_ALIGN_LEFT, + "SPACE to compare. Arrows to switch. Format: %s", bitmaps[idx].name); + al_draw_bitmap(bitmaps[idx].bmp, 0, 20, 0); + al_draw_bitmap(bitmaps[idx].clone, w, 20, 0); + al_draw_bitmap(bitmaps[idx].decomp, 0, 20 + h, 0); + al_draw_bitmap(bitmaps[idx].lock_clone, w, 20 + h, 0); + al_flip_display(); + } + } +EXIT: + + al_destroy_bitmap(bkg); + for (ii = 0; ii < NUM_BITMAPS; ii++) { + al_destroy_bitmap(bitmaps[ii].bmp); + } + + close_log(false); + + return 0; +} + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_config.c b/allegro/examples/ex_config.c new file mode 100644 index 00000000..8fbf01d2 --- /dev/null +++ b/allegro/examples/ex_config.c @@ -0,0 +1,119 @@ +/* + * Example program for the Allegro library. + * + * Test config file reading and writing. + */ + +#include +#include "allegro5/allegro.h" + +#include "common.c" + +static int passed = true; + +#define TEST(name, expr) \ +do { \ + if (expr) \ + log_printf(" PASS - %s\n", name); \ + else { \ + log_printf("!FAIL - %s\n", name); \ + passed = false; \ + } \ +} while (0) + +int main(int argc, char **argv) +{ + ALLEGRO_CONFIG *cfg; + const char *value; + ALLEGRO_CONFIG_SECTION *iterator; + ALLEGRO_CONFIG_ENTRY *iterator2; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + open_log(); + + cfg = al_load_config_file("data/sample.cfg"); + if (!cfg) { + abort_example("Couldn't load data/sample.cfg\n"); + } + + value = al_get_config_value(cfg, NULL, "old_var"); + TEST("global var", value && !strcmp(value, "old global value")); + + value = al_get_config_value(cfg, "section", "old_var"); + TEST("section var", value && !strcmp(value, "old section value")); + + value = al_get_config_value(cfg, "", "mysha.xpm"); + TEST("long value", value && strlen(value) == 1394); + + /* Test removing. */ + al_set_config_value(cfg, "empty", "key_remove", "to be removed"); + al_remove_config_key(cfg, "empty", "key_remove"); + + al_set_config_value(cfg, "schrödinger", "box", "cat"); + al_remove_config_section(cfg, "schrödinger"); + + /* Test whether iterating through our whole sample.cfg returns all + * sections and entries, in order. + */ + + value = al_get_first_config_section(cfg, &iterator); + TEST("section1", value && !strcmp(value, "")); + + value = al_get_first_config_entry(cfg, value, &iterator2); + TEST("entry1", value && !strcmp(value, "old_var")); + + value = al_get_next_config_entry(&iterator2); + TEST("entry2", value && !strcmp(value, "mysha.xpm")); + + value = al_get_next_config_entry(&iterator2); + TEST("entry3", value == NULL); + + value = al_get_next_config_section(&iterator); + TEST("section2", value && !strcmp(value, "section")); + + value = al_get_first_config_entry(cfg, value, &iterator2); + TEST("entry4", value && !strcmp(value, "old_var")); + + value = al_get_next_config_entry(&iterator2); + TEST("entry5", value == NULL); + + value = al_get_next_config_section(&iterator); + TEST("section3", value); + + value = al_get_first_config_entry(cfg, value, &iterator2); + TEST("entry6", value); + + value = al_get_next_config_entry(&iterator2); + TEST("entry7", value == NULL); + + value = al_get_next_config_section(&iterator); + TEST("empty", value && !strcmp(value, "empty")); + + value = al_get_first_config_entry(cfg, value, &iterator2); + TEST("empty entry", value == NULL); + + value = al_get_next_config_section(&iterator); + TEST("section4", value == NULL); + + + + al_set_config_value(cfg, "", "new_var", "new value"); + al_set_config_value(cfg, "section", "old_var", "new value"); + + TEST("save_config", al_save_config_file("test.cfg", cfg)); + + log_printf("Done\n"); + + al_destroy_config(cfg); + + close_log(true); + + return passed ? 0 : 1; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_convert.c b/allegro/examples/ex_convert.c new file mode 100644 index 00000000..711e1cdf --- /dev/null +++ b/allegro/examples/ex_convert.c @@ -0,0 +1,55 @@ +/* Image conversion example */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" + +#include "common.c" + + +int main(int argc, char **argv) +{ + ALLEGRO_BITMAP *bitmap; + double t0; + double t1; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + if (argc < 3) { + log_printf("This example needs to be run from the command line.\n"); + log_printf("Usage: %s \n", argv[0]); + log_printf("\tPossible file types: BMP PCX PNG TGA\n"); + goto done; + } + + al_init_image_addon(); + + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ARGB_8888); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + + bitmap = al_load_bitmap_flags(argv[1], ALLEGRO_NO_PREMULTIPLIED_ALPHA); + if (!bitmap) { + log_printf("Error loading input file\n"); + goto done; + } + + t0 = al_get_time(); + if (!al_save_bitmap(argv[2], bitmap)) { + log_printf("Error saving bitmap\n"); + goto done; + } + t1 = al_get_time(); + log_printf("Saving took %.4f seconds\n", t1 - t0); + + al_destroy_bitmap(bitmap); + +done: + close_log(true); + + return 0; +} + diff --git a/allegro/examples/ex_cpu.c b/allegro/examples/ex_cpu.c new file mode 100644 index 00000000..8434e8ce --- /dev/null +++ b/allegro/examples/ex_cpu.c @@ -0,0 +1,92 @@ +/* An example showing the use of al_get_cpu_count() and al_get_ram_size(). */ + +#include +#include +#include + +#include "common.c" + +#define INTERVAL 0.1 + + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_FONT *font; + bool done = false; + bool redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + al_init_font_addon(); + init_platform_specific(); + + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + font = al_create_builtin_font(); + + timer = al_create_timer(INTERVAL); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_display_event_source(display)); + + al_start_timer(timer); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + while (!done) { + ALLEGRO_EVENT event; + + if (redraw && al_is_event_queue_empty(queue)) { + al_clear_to_color(al_map_rgba_f(0, 0, 0, 1.0)); + al_draw_textf(font, al_map_rgba_f(1, 1, 0, 1.0), 16, 16, 0, + "Amount of CPU cores detected: %d.", al_get_cpu_count()); + al_draw_textf(font, al_map_rgba_f(0, 1, 1, 1.0), 16, 32, 0, + "Size of random access memory: %d MiB.", al_get_ram_size()); + al_flip_display(); + redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + done = true; + } + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + redraw = true; + break; + } + } + + al_destroy_font(font); + + return 0; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_curl.c b/allegro/examples/ex_curl.c new file mode 100644 index 00000000..2c90f08d --- /dev/null +++ b/allegro/examples/ex_curl.c @@ -0,0 +1,428 @@ +/* + * Example program for Allegro library. + * + * Custom file stream using cURL library. + */ + +/* + * Adapted from libcurl example fopen.c; licensed as follows: + *--- + * Coyright (c)2003 Simtec Electronics + * + * Re-implemented by Vincent Sanders with extensive + * reference to original curl example code + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#ifndef WIN32 +# include +#endif +#include +#include + +#include +#include +#include + +#include "common.c" + + +typedef struct CURL_FILE CURL_FILE; +struct CURL_FILE { + CURL *curl; + char *buffer; /* buffer to store cached data */ + size_t buffer_len; /* currently allocated buffers length */ + size_t buffer_pos; /* end of data in buffer*/ + int still_running; /* Is background url fetch still in progress */ +}; + + +/* forward declaration */ +static ALLEGRO_FILE_INTERFACE curl_file_vtable; + + +/* we use a global one for convenience */ +static CURLM *multi_handle; + + +/* curl calls this routine to get more data. */ +static size_t write_callback(char *buffer, size_t size, size_t nitems, + void *userp) +{ + CURL_FILE *cf = userp; + char *newbuff; + size_t rembuff; + + size *= nitems; + + rembuff = cf->buffer_len - cf->buffer_pos; + + if (size > rembuff) { + /* Not enough space in buffer. */ + newbuff = realloc(cf->buffer, cf->buffer_len + size - rembuff); + if (!newbuff) { + log_printf("callback buffer grow failed\n"); + size = rembuff; + } + else { + /* realloc increase buffer size. */ + cf->buffer_len += size - rembuff; + cf->buffer = newbuff; + } + } + + memcpy(cf->buffer + cf->buffer_pos, buffer, size); + cf->buffer_pos += size; + return size; +} + + +static void *curl_file_fopen(const char *path, const char *mode) +{ + CURL_FILE *cf; + + /* Only support reading. */ + if (strcmp(mode, "r") != 0 && strcmp(mode, "rb") != 0) + return NULL; + + cf = calloc(1, sizeof(*cf)); + if (!cf) + return NULL; + + cf->curl = curl_easy_init(); + curl_easy_setopt(cf->curl, CURLOPT_URL, path); + curl_easy_setopt(cf->curl, CURLOPT_WRITEDATA, cf); + curl_easy_setopt(cf->curl, CURLOPT_VERBOSE, 1); + curl_easy_setopt(cf->curl, CURLOPT_WRITEFUNCTION, write_callback); + + if (!multi_handle) + multi_handle = curl_multi_init(); + + curl_multi_add_handle(multi_handle, cf->curl); + + /* Let's start the fetch. */ + while (curl_multi_perform(multi_handle, &cf->still_running) == + CURLM_CALL_MULTI_PERFORM); + + if ((cf->buffer_pos == 0) && (!cf->still_running)) { + /* If still_running is 0 now, we should return NULL. */ + curl_multi_remove_handle(multi_handle, cf->curl); + curl_easy_cleanup(cf->curl); + free(cf); + cf = NULL; + } + + return cf; +} + + +static bool curl_file_fclose(ALLEGRO_FILE *f) +{ + CURL_FILE *cf = al_get_file_userdata(f); + + curl_multi_remove_handle(multi_handle, cf->curl); + curl_easy_cleanup(cf->curl); + if (cf->buffer) + free(cf->buffer); + free(cf); + return true; +} + + +static bool fill_buffer(CURL_FILE *cf, size_t size) +{ + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + struct timeval timeout; + int rc; + + /* Only attempt to fill buffer if transactions still running and buffer + * doesn't exceed required size already. + */ + if (!cf->still_running || cf->buffer_pos > size) + return false; + + /* Attempt to fill buffer. */ + do { + int maxfd = -1; + CURLMcode mc; + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + /* Set a suitable timeout to fail on. */ + timeout.tv_sec = 10; + timeout.tv_usec = 0; + + /* Get file descriptors from the transfers. */ + mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); + + if(mc != CURLM_OK) { + abort_example("curl_multi_fdset() failed, code %d.\n", mc); + } + + if (maxfd > -1) { + rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); + } + else { + al_rest(0.1); + rc = 0; + } + + switch (rc) { + case -1: + /* select error */ + break; + + case 0: + default: + /* Timeout or readable/writable sockets. */ + curl_multi_perform(multi_handle, &cf->still_running); + break; + } + } while (cf->still_running && cf->buffer_pos < size); + + return true; +} + + +static void use_buffer(CURL_FILE *cf, size_t size) +{ + if (cf->buffer_pos - size <= 0) { + cf->buffer_pos = 0; + } + else { + /* Move rest down make it available for later. */ + memmove(cf->buffer, cf->buffer + size, cf->buffer_pos - size); + cf->buffer_pos -= size; + } +} + + +static size_t curl_file_fread(ALLEGRO_FILE *f, void *ptr, size_t size) +{ + CURL_FILE *cf = al_get_file_userdata(f); + + fill_buffer(cf, size); + if (!cf->buffer_pos) + return 0; + + if (cf->buffer_pos < size) + size = cf->buffer_pos; + + memcpy(ptr, cf->buffer, size); + use_buffer(cf, size); + return size; +} + + +static size_t curl_file_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) +{ + (void)f; + (void)ptr; + (void)size; + al_set_errno(EBADF); + return 0; +} + + +static bool curl_file_fflush(ALLEGRO_FILE *f) +{ + (void)f; + return true; +} + + +static int64_t curl_file_ftell(ALLEGRO_FILE *f) +{ + /* Not implemented. */ + (void)f; + al_set_errno(ENOSYS); + return -1; +} + + +static bool curl_file_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) +{ + if (whence != ALLEGRO_SEEK_CUR || offset < 0) { + /* Not implemented. */ + al_set_errno(ENOSYS); + return false; + } + + while (offset > 0) { + if (al_fgetc(f) == EOF) + break; + offset--; + } + + return offset == 0; +} + + +static bool curl_file_feof(ALLEGRO_FILE *f) +{ + CURL_FILE *cf = al_get_file_userdata(f); + + return (cf->buffer_pos == 0 && !cf->still_running); +} + + +static int curl_file_ferror(ALLEGRO_FILE *f) +{ + /* Not implemented. */ + (void)f; + return false; +} + + +static const char *curl_file_ferrmsg(ALLEGRO_FILE *f) +{ + /* Not implemented. */ + (void)f; + return ""; +} + + +static void curl_file_fclearerr(ALLEGRO_FILE *f) +{ + /* Not implemented. */ + (void)f; +} + + +static int curl_file_fungetc(ALLEGRO_FILE *f, int c) +{ + /* Not implemented. */ + (void)f; + (void)c; + al_set_errno(ENOSYS); + return -1; +} + + +static off_t curl_file_fsize(ALLEGRO_FILE *f) +{ + /* Not implemented. */ + (void)f; + al_set_errno(ENOSYS); + return -1; +} + + +static ALLEGRO_FILE_INTERFACE curl_file_vtable = +{ + curl_file_fopen, + curl_file_fclose, + curl_file_fread, + curl_file_fwrite, + curl_file_fflush, + curl_file_ftell, + curl_file_fseek, + curl_file_feof, + curl_file_ferror, + curl_file_ferrmsg, + curl_file_fclearerr, + curl_file_fungetc, + curl_file_fsize +}; + + +static void show_image(ALLEGRO_BITMAP *bmp, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(disp)); + + while (true) { + al_draw_bitmap(bmp, 0, 0, 0); + al_flip_display(); + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN + && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + } + + al_destroy_event_queue(queue); +} + + +int main(int argc, const char *argv[]) +{ + const char *url; + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bmp; + bool wait_for_log = true; + + if (argc > 1) + url = argv[1]; + else + url = "http://liballeg.org/images/logo.png"; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_init_image_addon(); + al_install_keyboard(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Unable to create display.\n"); + } + + curl_global_init(CURL_GLOBAL_ALL); + al_set_new_file_interface(&curl_file_vtable); + + bmp = al_load_bitmap(url); + if (bmp) { + show_image(bmp, display); + al_destroy_bitmap(bmp); + wait_for_log = false; + } + + curl_global_cleanup(); + al_destroy_display(display); + + close_log(wait_for_log); + + return 0; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_d3d.cpp b/allegro/examples/ex_d3d.cpp new file mode 100644 index 00000000..842f9ffe --- /dev/null +++ b/allegro/examples/ex_d3d.cpp @@ -0,0 +1,119 @@ +/* + * Example of using D3D calls + * by Jacob Dawid & Trent Gamblin + */ + +#include +#include +#include +#include +#include + +#include "common.c" + +#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) + +struct D3DVERTEX +{ + float fX, fY, fZ; + DWORD dwColor; +}; + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Error initialising Allegro.\n"); + } + + open_log(); + + al_install_keyboard(); + al_set_new_display_flags(ALLEGRO_DIRECT3D); + al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); + display = al_create_display(640, 480); + if (!display) { + abort_example("Unable to create display.\n"); + } + + ALLEGRO_KEYBOARD_STATE state; + + IDirect3DDevice9 *d3dd = al_get_d3d_device(display); + + d3dd->SetRenderState(D3DRS_AMBIENT, 0x11111111); + d3dd->SetRenderState(D3DRS_LIGHTING,false); + d3dd->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); + d3dd->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE); + d3dd->SetFVF(D3DFVF_CUSTOMVERTEX); + + D3DXMATRIX m_matProjection; + float m_fAspectRatio = 1.0f; + float m_fFieldOfView = D3DX_PI / 4.0f; + float m_fNearPlane = 1.0f; + float m_fFarPlane = 1000.0f; + + D3DXMatrixPerspectiveFovLH( &m_matProjection, m_fFieldOfView, + m_fAspectRatio, m_fNearPlane, m_fFarPlane); + + d3dd->SetTransform(D3DTS_PROJECTION, &m_matProjection); + + LPDIRECT3DVERTEXBUFFER9 pTriangleVB = NULL; + VOID *pData; + + D3DVERTEX aTriangle[] = { + { -0.5, -0.5f, 0.0f, 0xffff0000 }, + { 0.5f, -0.5f, 0.0f, 0xff00ff00 }, + { 0.0f, 0.5f, 0.0f, 0xff0000ff } + }; + + d3dd->CreateVertexBuffer(sizeof(aTriangle), D3DUSAGE_WRITEONLY, + D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pTriangleVB, NULL); + + pTriangleVB->Lock(0, sizeof(pData), (void **)&pData, 0); + memcpy(pData, aTriangle, sizeof(aTriangle)); + pTriangleVB->Unlock(); + + float angle = 0.0f; + D3DXMATRIX mat; + double start = al_get_time(); + double start_secs = al_get_time(); + long frames = 0; + + do { + d3dd->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + + /* + * The X and Y translation here is to offset + * a translation Allegro does internally so + * that its coordinate space matches OpenGL's. + * Normally you don't have to worry about this + * but if you're using D3D directly you do. + */ + D3DXMatrixTranslation(&mat, 0.5, 0.5, 2.0f); + d3dd->SetTransform(D3DTS_WORLDMATRIX(0), &mat); + angle += 50 * (al_get_time() - start); + D3DXMatrixRotationY(&mat, angle); + d3dd->MultiplyTransform(D3DTS_WORLDMATRIX(0), &mat); + + d3dd->SetFVF(D3DFVF_CUSTOMVERTEX); + d3dd->SetStreamSource(0, pTriangleVB, 0, sizeof(D3DVERTEX)); + d3dd->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); + + al_flip_display(); + + al_get_keyboard_state(&state); + + start = al_get_time(); + frames++; + } while (!al_key_down(&state, ALLEGRO_KEY_ESCAPE)); + + double elapsed = al_get_time() - start_secs; + log_printf("%g fps\n", frames/elapsed); + al_destroy_display(display); + close_log(true); + + return 0; +} diff --git a/allegro/examples/ex_depth_mask.c b/allegro/examples/ex_depth_mask.c new file mode 100644 index 00000000..5b8d6ca5 --- /dev/null +++ b/allegro/examples/ex_depth_mask.c @@ -0,0 +1,253 @@ +#include +#include +#include +#include +#include + +#include "common.c" + +#define FPS 60 +#define COUNT 80 + +struct Example { + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *mysha, *obp; + ALLEGRO_FONT *font, *font2; + double direct_speed_measure; + + struct Sprite { + double x, y, angle; + } sprites[COUNT]; + +} example; + + +static void redraw(void) +{ + ALLEGRO_TRANSFORM t; + int i; + + /* We first draw the Obp background and clear the depth buffer to 1. */ + + al_set_render_state(ALLEGRO_ALPHA_TEST, true); + al_set_render_state(ALLEGRO_ALPHA_FUNCTION, ALLEGRO_RENDER_GREATER); + al_set_render_state(ALLEGRO_ALPHA_TEST_VALUE, 0); + + al_set_render_state(ALLEGRO_DEPTH_TEST, false); + + al_set_render_state(ALLEGRO_WRITE_MASK, ALLEGRO_MASK_DEPTH | ALLEGRO_MASK_RGBA); + + al_clear_depth_buffer(1); + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + + al_draw_scaled_bitmap(example.obp, 0, 0, 532, 416, 0, 0, 640, 416 * 640 / 532, 0); + + /* Next we draw all sprites but only to the depth buffer (with a depth value + * of 0). + */ + + al_set_render_state(ALLEGRO_DEPTH_TEST, true); + al_set_render_state(ALLEGRO_DEPTH_FUNCTION, ALLEGRO_RENDER_ALWAYS); + al_set_render_state(ALLEGRO_WRITE_MASK, ALLEGRO_MASK_DEPTH); + + for (i = 0; i < COUNT; i++) { + struct Sprite *s = example.sprites + i; + int x, y; + al_hold_bitmap_drawing(true); + for (y = -480; y <= 0; y += 480) { + for (x = -640; x <= 0; x += 640) { + al_identity_transform(&t); + al_rotate_transform(&t, s->angle); + al_translate_transform(&t, s->x + x, s->y + y); + al_use_transform(&t); + al_draw_text(example.font, al_map_rgb(0, 0, 0), 0, 0, + ALLEGRO_ALIGN_CENTER, "Allegro 5"); + } + } + al_hold_bitmap_drawing(false); + } + al_identity_transform(&t); + al_use_transform(&t); + + /* Finally we draw Mysha, with depth testing so she only appears where + * sprites have been drawn before. + */ + + al_set_render_state(ALLEGRO_DEPTH_FUNCTION, ALLEGRO_RENDER_EQUAL); + al_set_render_state(ALLEGRO_WRITE_MASK, ALLEGRO_MASK_RGBA); + al_draw_scaled_bitmap(example.mysha, 0, 0, 320, 200, 0, 0, 320 * 480 / 200, 480, 0); + + /* Finally we draw an FPS counter. */ + al_set_render_state(ALLEGRO_DEPTH_TEST, false); + + al_draw_textf(example.font2, al_map_rgb_f(1, 1, 1), 640, 0, + ALLEGRO_ALIGN_RIGHT, "%.1f FPS", 1.0 / example.direct_speed_measure); +} + +static void update(void) +{ + int i; + for (i = 0; i < COUNT; i++) { + struct Sprite *s = example.sprites + i; + s->x -= 4; + if (s->x < 80) + s->x += 640; + s->angle += i * ALLEGRO_PI / 180 / COUNT; + } +} + +static void init(void) +{ + int i; + for (i = 0; i < COUNT; i++) { + struct Sprite *s = example.sprites + i; + s->x = (i % 4) * 160; + s->y = (i / 4) * 24; + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_MONITOR_INFO info; + int w = 640, h = 480; + bool done = false; + bool need_redraw = true; + bool background = false; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + al_init_font_addon(); + + if (!al_init_ttf_addon()) { + abort_example("Failed to init TTF addon.\n"); + } + + init_platform_specific(); + + al_get_num_video_adapters(); + + al_get_monitor_info(0, &info); + + int flags = 0; + #ifdef ALLEGRO_IPHONE + flags |= ALLEGRO_FULLSCREEN_WINDOW; + #endif + + if (argc > 1 && strcmp(argv[1], "shader") == 0) { + flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; + } + al_set_new_display_flags(flags); + + al_set_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, + ALLEGRO_DISPLAY_ORIENTATION_ALL, ALLEGRO_SUGGEST); + + al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 8, ALLEGRO_SUGGEST); + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + + example.display = al_create_display(w, h); + if (!example.display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + example.font = al_load_font("data/DejaVuSans.ttf", 40, 0); + if (!example.font) { + abort_example("Error loading data/DejaVuSans.ttf\n"); + } + + example.font2 = al_load_font("data/DejaVuSans.ttf", 12, 0); + if (!example.font2) { + abort_example("Error loading data/DejaVuSans.ttf\n"); + } + + example.mysha = al_load_bitmap("data/mysha.pcx"); + if (!example.mysha) { + abort_example("Error loading data/mysha.pcx\n"); + } + + example.obp = al_load_bitmap("data/obp.jpg"); + if (!example.obp) { + abort_example("Error loading data/obp.jpg\n"); + } + + init(); + + timer = al_create_timer(1.0 / FPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_register_event_source(queue, al_get_display_event_source(example.display)); + + al_start_timer(timer); + + while (!done) { + ALLEGRO_EVENT event; + w = al_get_display_width(example.display); + h = al_get_display_height(example.display); + + if (!background && need_redraw && al_is_event_queue_empty(queue)) { + double t = -al_get_time(); + + redraw(); + + t += al_get_time(); + example.direct_speed_measure = t; + al_flip_display(); + need_redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_CHAR: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: + + background = true; + al_acknowledge_drawing_halt(event.display.source); + + break; + + case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: + background = false; + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(event.display.source); + break; + + case ALLEGRO_EVENT_TIMER: + update(); + need_redraw = true; + break; + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_depth_target.c b/allegro/examples/ex_depth_target.c new file mode 100644 index 00000000..767ea9e7 --- /dev/null +++ b/allegro/examples/ex_depth_target.c @@ -0,0 +1,236 @@ +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include +#include +#include +#include + +#include "common.c" + +#define FPS 60 + +struct Example { + ALLEGRO_BITMAP *target_depth; + ALLEGRO_BITMAP *target_no_depth; + ALLEGRO_BITMAP *target_no_multisample; + ALLEGRO_FONT *font; + double t; + double direct_speed_measure; +} example; + +static void draw_on_target(ALLEGRO_BITMAP *target) +{ + ALLEGRO_STATE state; + ALLEGRO_TRANSFORM transform; + + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | + ALLEGRO_STATE_TRANSFORM | + ALLEGRO_STATE_PROJECTION_TRANSFORM); + + al_set_target_bitmap(target); + al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); + al_clear_depth_buffer(1); + + al_identity_transform(&transform); + al_translate_transform_3d(&transform, 0, 0, 0); + al_orthographic_transform(&transform, + -1, 1, -1, 1, -1, 1); + al_use_projection_transform(&transform); + + al_draw_filled_rectangle(-0.75, -0.5, 0.75, 0.5, al_color_name("blue")); + + al_set_render_state(ALLEGRO_DEPTH_TEST, true); + + int i, j; + for (i = 0; i < 24; i++) { + for (j = 0; j < 2; j++) { + al_identity_transform(&transform); + al_translate_transform_3d(&transform, 0, 0, j * 0.01); + al_rotate_transform_3d(&transform, 0, 1, 0, + ALLEGRO_PI * (i / 12.0 + example.t / 2)); + al_rotate_transform_3d(&transform, 1, 0, 0, ALLEGRO_PI * 0.25); + al_use_transform(&transform); + if (j == 0) + al_draw_filled_rectangle(0, -.5, .5, .5, i % 2 == 0 ? + al_color_name("yellow") : al_color_name("red")); + else + al_draw_filled_rectangle(0, -.5, .5, .5, i % 2 == 0 ? + al_color_name("goldenrod") : al_color_name("maroon")); + } + } + + al_set_render_state(ALLEGRO_DEPTH_TEST, false); + + al_identity_transform(&transform); + al_use_transform(&transform); + + al_draw_line(0.9, 0, 1, 0, al_color_name("black"), 0.05); + al_draw_line(-0.9, 0, -1, 0, al_color_name("black"), 0.05); + al_draw_line(0, 0.9, 0, 1, al_color_name("black"), 0.05); + al_draw_line(0, -0.9, 0, -1, al_color_name("black"), 0.05); + + al_restore_state(&state); +} + +static void redraw(void) +{ + double w = 512, h = 512; + ALLEGRO_COLOR black = al_color_name("black"); + draw_on_target(example.target_depth); + draw_on_target(example.target_no_depth); + draw_on_target(example.target_no_multisample); + + al_clear_to_color(al_color_name("green")); + + ALLEGRO_TRANSFORM transform; + + al_identity_transform(&transform); + al_use_transform(&transform); + al_translate_transform(&transform, -128, -128); + al_rotate_transform(&transform, example.t * ALLEGRO_PI / 3); + al_translate_transform(&transform, 512 + 128, 128); + al_use_transform(&transform); + al_draw_bitmap(example.target_no_depth, 0, 0, 0); + al_draw_text(example.font, black, 0, 0, 0, "no depth"); + + al_identity_transform(&transform); + al_use_transform(&transform); + al_translate_transform(&transform, -128, -128); + al_rotate_transform(&transform, example.t * ALLEGRO_PI / 3); + al_translate_transform(&transform, 512 + 128, 256 + 128); + al_use_transform(&transform); + al_draw_bitmap(example.target_no_multisample, 0, 0, 0); + al_draw_textf(example.font, black, 0, 0, 0, "no multisample"); + + al_identity_transform(&transform); + al_use_transform(&transform); + al_translate_transform(&transform, -256, -256); + al_rotate_transform(&transform, example.t * ALLEGRO_PI / 3); + al_translate_transform(&transform, 256, 256); + al_use_transform(&transform); + al_draw_bitmap(example.target_depth, 0, 0, 0); + + al_draw_line(30, h / 2, 60, h / 2, black, 12); + al_draw_line(w - 30, h / 2, w - 60, h / 2, black, 12); + al_draw_line(w / 2, 30, w / 2, 60, black, 12); + al_draw_line(w / 2, h - 30, w / 2, h - 60, black, 12); + al_draw_text(example.font, black, 30, h / 2 - 16, 0, "back buffer"); + al_draw_text(example.font, black, 0, h / 2 + 10, 0, "bitmap"); + + al_identity_transform(&transform); + al_use_transform(&transform); + al_draw_textf(example.font, black, w, 0, + ALLEGRO_ALIGN_RIGHT, "%.1f FPS", 1.0 / example.direct_speed_measure); +} + +static void update(void) +{ + example.t += 1.0 / FPS; +} + +static void init(void) +{ + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + al_set_new_bitmap_depth(16); + al_set_new_bitmap_samples(4); + example.target_depth = al_create_bitmap(512, 512); + al_set_new_bitmap_depth(0); + example.target_no_depth = al_create_bitmap(256, 256); + al_set_new_bitmap_samples(0); + example.target_no_multisample = al_create_bitmap(256, 256); +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_DISPLAY *display; + int w = 512 + 256, h = 512; + bool done = false; + bool need_redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + al_init_font_addon(); + example.font = al_create_builtin_font(); + + al_init_primitives_addon(); + + init_platform_specific(); + + al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); + al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE); + + display = al_create_display(w, h); + if (!display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + init(); + + timer = al_create_timer(1.0 / FPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_register_event_source(queue, al_get_display_event_source(display)); + + al_start_timer(timer); + + double t = -al_get_time(); + + while (!done) { + ALLEGRO_EVENT event; + + if (need_redraw) { + t += al_get_time(); + example.direct_speed_measure = t; + t = -al_get_time(); + redraw(); + al_flip_display(); + need_redraw = false; + } + + while (true) { + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_CHAR: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + update(); + need_redraw = true; + break; + } + if (al_is_event_queue_empty(queue)) + break; + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_dir.c b/allegro/examples/ex_dir.c new file mode 100644 index 00000000..d9fdbc9a --- /dev/null +++ b/allegro/examples/ex_dir.c @@ -0,0 +1,126 @@ +#include +#include + +#include "common.c" + +static void print_file(ALLEGRO_FS_ENTRY *entry) +{ + int mode = al_get_fs_entry_mode(entry); + time_t now = time(NULL); + time_t atime = al_get_fs_entry_atime(entry); + time_t ctime = al_get_fs_entry_ctime(entry); + time_t mtime = al_get_fs_entry_mtime(entry); + off_t size = al_get_fs_entry_size(entry); + const char *name = al_get_fs_entry_name(entry); + + log_printf("%-36s %s%s%s%s%s%s %8u %8u %8u %8u\n", + name, + mode & ALLEGRO_FILEMODE_READ ? "r" : ".", + mode & ALLEGRO_FILEMODE_WRITE ? "w" : ".", + mode & ALLEGRO_FILEMODE_EXECUTE ? "x" : ".", + mode & ALLEGRO_FILEMODE_HIDDEN ? "h" : ".", + mode & ALLEGRO_FILEMODE_ISFILE ? "f" : ".", + mode & ALLEGRO_FILEMODE_ISDIR ? "d" : ".", + (unsigned)(now - ctime), + (unsigned)(now - mtime), + (unsigned)(now - atime), + (unsigned)size); +} + +static void print_entry(ALLEGRO_FS_ENTRY *entry) +{ + ALLEGRO_FS_ENTRY *next; + + print_file(entry); + + if (!(al_get_fs_entry_mode(entry) & ALLEGRO_FILEMODE_ISDIR)) + return; + + if (!al_open_directory(entry)) { + log_printf("Error opening directory: %s\n", al_get_fs_entry_name(entry)); + return; + } + + while (1) { + next = al_read_directory(entry); + if (!next) + break; + + print_entry(next); + al_destroy_fs_entry(next); + } + + al_close_directory(entry); +} + + +static int print_fs_entry_cb(ALLEGRO_FS_ENTRY * entry, void * extra) { + (void) extra; + print_file(entry); + return ALLEGRO_FOR_EACH_FS_ENTRY_OK; +} + +static int print_fs_entry_cb_norecurse(ALLEGRO_FS_ENTRY * entry, void * extra) { + (void) extra; + print_file(entry); + return ALLEGRO_FOR_EACH_FS_ENTRY_SKIP; +} + +static void print_fs_entry(ALLEGRO_FS_ENTRY * dir) +{ + log_printf("\n------------------------------------\nExample of al_for_each_fs_entry with recursion:\n\n"); + al_for_each_fs_entry(dir, print_fs_entry_cb, + (void*) al_get_fs_entry_name(dir)); +} + +static void print_fs_entry_norecurse(ALLEGRO_FS_ENTRY * dir) +{ + log_printf("\n------------------------------------\nExample of al_for_each_fs_entry without recursion:\n\n"); + al_for_each_fs_entry(dir, print_fs_entry_cb_norecurse, + (void*) al_get_fs_entry_name(dir)); +} + +int main(int argc, char **argv) +{ + int i; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + open_log_monospace(); + + log_printf("Example of filesystem entry functions:\n\n%-36s %-6s %8s %8s %8s %8s\n", + "name", "flags", "ctime", "mtime", "atime", "size"); + log_printf( + "------------------------------------ " + "------ " + "-------- " + "-------- " + "-------- " + "--------\n"); + + #ifdef ALLEGRO_ANDROID + al_android_set_apk_fs_interface(); + #endif + + if (argc == 1) { + ALLEGRO_FS_ENTRY *entry = al_create_fs_entry("data"); + print_entry(entry); + print_fs_entry(entry); + print_fs_entry_norecurse(entry); + al_destroy_fs_entry(entry); + } + + for (i = 1; i < argc; i++) { + ALLEGRO_FS_ENTRY *entry = al_create_fs_entry(argv[i]); + print_entry(entry); + print_fs_entry(entry); + print_fs_entry_norecurse(entry); + al_destroy_fs_entry(entry); + } + + close_log(true); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_disable_screensaver.c b/allegro/examples/ex_disable_screensaver.c new file mode 100644 index 00000000..b83394b1 --- /dev/null +++ b/allegro/examples/ex_disable_screensaver.c @@ -0,0 +1,73 @@ +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + ALLEGRO_EVENT_QUEUE *events; + ALLEGRO_EVENT event; + bool done = false; + bool active = true; + bool fullscreen = false; + + if (argc == 2) { + if (!strcmp(argv[1], "-fullscreen")) { + fullscreen = true; + } + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + al_init_font_addon(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS | + (fullscreen ? ALLEGRO_FULLSCREEN : 0)); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display.\n"); + } + + font = al_create_builtin_font(); + if (!font) { + abort_example("Error creating builtin font\n"); + } + + events = al_create_event_queue(); + al_register_event_source(events, al_get_keyboard_event_source()); + /* For expose events */ + al_register_event_source(events, al_get_display_event_source(display)); + + do { + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_draw_textf(font, al_map_rgb_f(1, 1, 1), 0, 0, 0, + "Screen saver: %s", active ? "Normal" : "Inhibited"); + al_flip_display(); + al_wait_for_event(events, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + if (al_inhibit_screensaver(active)) { + active = !active; + } + } + break; + } + } while (!done); + + al_destroy_font(font); + al_destroy_event_queue(events); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_display_events.c b/allegro/examples/ex_display_events.c new file mode 100644 index 00000000..70f2c868 --- /dev/null +++ b/allegro/examples/ex_display_events.c @@ -0,0 +1,133 @@ +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" + +#define MAX_EVENTS 23 + +static char events[MAX_EVENTS][1024]; + +static void add_event(char const *f, ...) +{ + va_list args; + memmove(events[1], events[0], (MAX_EVENTS - 1) * 1024); + va_start(args, f); + vsnprintf(events[0], 1024, f, args); + va_end(args); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + ALLEGRO_FONT *font; + ALLEGRO_COLOR color, black, red, blue; + int i; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_mouse(); + al_install_keyboard(); + al_init_font_addon(); + + al_set_new_display_flags(ALLEGRO_RESIZABLE); + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + font = al_create_builtin_font(); + if (!font) { + abort_example("Error creating builtin font\n"); + } + + black = al_map_rgb_f(0, 0, 0); + red = al_map_rgb_f(1, 0, 0); + blue = al_map_rgb_f(0, 0, 1); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + while (1) { + if (al_is_event_queue_empty(queue)) { + float x = 8, y = 28; + al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); + + al_draw_textf(font, blue, 8, 8, 0, "Display events (newest on top)"); + + color = red; + for (i = 0; i < MAX_EVENTS; i++) { + if (!events[i]) continue; + al_draw_textf(font, color, x, y, 0, "%s", events[i]); + color = black; + y += 20; + } + al_flip_display(); + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY: + add_event("ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY"); + break; + + case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: + add_event("ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY"); + break; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + goto done; + } + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + add_event("ALLEGRO_EVENT_DISPLAY_RESIZE x=%d, y=%d, " + "width=%d, height=%d", + event.display.x, event.display.y, event.display.width, + event.display.height); + al_acknowledge_resize(event.display.source); + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + add_event("ALLEGRO_EVENT_DISPLAY_CLOSE"); + break; + + case ALLEGRO_EVENT_DISPLAY_LOST: + add_event("ALLEGRO_EVENT_DISPLAY_LOST"); + break; + + case ALLEGRO_EVENT_DISPLAY_FOUND: + add_event("ALLEGRO_EVENT_DISPLAY_FOUND"); + break; + + case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: + add_event("ALLEGRO_EVENT_DISPLAY_SWITCH_OUT"); + break; + + case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: + add_event("ALLEGRO_EVENT_DISPLAY_SWITCH_IN"); + break; + } + } + +done: + + al_destroy_event_queue(queue); + + return 0; +} + + +/* vim: set sw=3 sts=3 et: */ diff --git a/allegro/examples/ex_display_options.c b/allegro/examples/ex_display_options.c new file mode 100644 index 00000000..976b93fd --- /dev/null +++ b/allegro/examples/ex_display_options.c @@ -0,0 +1,393 @@ +/* Test retrieving and settings possible modes. */ +#include +#include +#include +#include + +#include "common.c" + +ALLEGRO_FONT *font; +ALLEGRO_COLOR white; +int font_h; +int modes_count; +int options_count; +char status[256]; +int flags, old_flags; + +int visible_rows; +int first_visible_row; + +int selected_column; +int selected_mode; +int selected_option; + +#define X(x, m) {#x, ALLEGRO_##x, 0, m, 0} +struct { + char const *name; + int option; + int value, max_value; + int required; +} options[] = { + X(COLOR_SIZE, 32), + X(RED_SIZE, 8), + X(GREEN_SIZE, 8), + X(BLUE_SIZE, 8), + X(ALPHA_SIZE, 8), + X(RED_SHIFT, 32), + X(GREEN_SHIFT, 32), + X(BLUE_SHIFT, 32), + X(ALPHA_SHIFT, 32), + X(DEPTH_SIZE, 32), + X(FLOAT_COLOR, 1), + X(FLOAT_DEPTH, 1), + X(STENCIL_SIZE, 32), + X(SAMPLE_BUFFERS, 1), + X(SAMPLES, 8), + X(RENDER_METHOD, 2), + X(SINGLE_BUFFER, 1), + X(SWAP_METHOD, 1), + X(VSYNC, 2), + X(COMPATIBLE_DISPLAY, 1), + X(MAX_BITMAP_SIZE, 65536), + X(SUPPORT_NPOT_BITMAP, 1), + X(CAN_DRAW_INTO_BITMAP, 1), + X(SUPPORT_SEPARATE_ALPHA, 1), +}; +#undef X +static char const *flag_names[32]; +static void init_flags(void) +{ + int i; + #define X(f) if (1 << i == ALLEGRO_##f) flag_names[i] = #f; + for (i = 0; i < 32; i++) { + X(WINDOWED) + X(FULLSCREEN) + X(OPENGL) + X(RESIZABLE) + X(FRAMELESS) + X(GENERATE_EXPOSE_EVENTS) + X(FULLSCREEN_WINDOW) + X(MINIMIZED) + } + #undef X +} + +static void load_font(void) +{ + font = al_create_builtin_font(); + if (!font) { + abort_example("Error creating builtin font\n"); + } + font_h = al_get_font_line_height(font); +} + +static void display_options(ALLEGRO_DISPLAY *display) +{ + int i, y = 10; + int x = 10; + int n = options_count; + int dw = al_get_display_width(display); + int dh = al_get_display_height(display); + ALLEGRO_COLOR c; + + modes_count = al_get_num_display_modes(); + + c = al_map_rgb_f(0.8, 0.8, 1); + al_draw_textf(font, c, x, y, 0, "Create new display"); + y += font_h; + for (i = first_visible_row; i < modes_count + 2 && + i < first_visible_row + visible_rows; i++) { + ALLEGRO_DISPLAY_MODE mode; + if (i > 1) { + al_get_display_mode(i - 2, &mode); + } + else if (i == 1) { + mode.width = 800; + mode.height = 600; + mode.format = 0; + mode.refresh_rate = 0; + } + else { + mode.width = 800; + mode.height = 600; + mode.format = 0; + mode.refresh_rate = 0; + } + if (selected_column == 0 && selected_mode == i) { + c = al_map_rgb_f(1, 1, 0); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_filled_rectangle(x, y, x + 300, y + font_h, c); + } + c = al_map_rgb_f(0, 0, 0); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + if ((i == first_visible_row && i > 0) || + (i == first_visible_row + visible_rows - 1 && + i < modes_count + 1)) { + al_draw_textf(font, c, x, y, 0, "..."); + } + else { + al_draw_textf(font, c, x, y, 0, "%s %d x %d (fmt: %x, %d Hz)", + i > 1 ? "Fullscreen" : i == 0 ? "Windowed" : "FS Window", + mode.width, mode.height, mode.format, mode.refresh_rate); + } + y += font_h; + } + + x = dw / 2 + 10; + y = 10; + c = al_map_rgb_f(0.8, 0.8, 1); + al_draw_textf(font, c, x, y, 0, "Options for new display"); + al_draw_textf(font, c, dw - 10, y, ALLEGRO_ALIGN_RIGHT, "(current display)"); + y += font_h; + for (i = 0; i < n; i++) { + if (selected_column == 1 && selected_option == i) { + c = al_map_rgb_f(1, 1, 0); + al_draw_filled_rectangle(x, y, x + 300, y + font_h, c); + } + + switch (options[i].required) { + case ALLEGRO_REQUIRE: c = al_map_rgb_f(0.5, 0, 0); break; + case ALLEGRO_SUGGEST: c = al_map_rgb_f(0, 0, 0); break; + case ALLEGRO_DONTCARE: c = al_map_rgb_f(0.5, 0.5, 0.5); break; + } + al_draw_textf(font, c, x, y, 0, "%s: %d (%s)", options[i].name, + options[i].value, + options[i].required == ALLEGRO_REQUIRE ? "required" : + options[i].required == ALLEGRO_SUGGEST ? "suggested" : + "ignored"); + + c = al_map_rgb_f(0.9, 0.5, 0.3); + al_draw_textf(font, c, dw - 10, y, ALLEGRO_ALIGN_RIGHT, "%d", + al_get_display_option(display, options[i].option)); + y += font_h; + } + + c = al_map_rgb_f(0, 0, 0.8); + x = 10; + y = dh - font_h - 10; + y -= font_h; + al_draw_textf(font, c, x, y, 0, "PageUp/Down: modify values"); + y -= font_h; + al_draw_textf(font, c, x, y, 0, "Return: set mode or require option"); + y -= font_h; + al_draw_textf(font, c, x, y, 0, "Cursor keys: change selection"); + + y -= font_h * 2; + for (i = 0; i < 32; i++) { + if (flag_names[i]) { + if (flags & (1 << i)) c = al_map_rgb_f(0.5, 0, 0); + else if (old_flags & (1 << i)) c = al_map_rgb_f(0.5, 0.4, 0.4); + else continue; + al_draw_text(font, c, x, y, 0, flag_names[i]); + x += al_get_text_width(font, flag_names[i]) + 10; + } + } + + c = al_map_rgb_f(1, 0, 0); + al_draw_text(font, c, dw / 2, dh - font_h, ALLEGRO_ALIGN_CENTRE, status); +} + +static void update_ui(void) +{ + int h = al_get_display_height(al_get_current_display()); + visible_rows = h / font_h - 10; +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + bool redraw = false; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + init_flags(); + al_init_primitives_addon(); + + white = al_map_rgba_f(1, 1, 1, 1); + + al_install_keyboard(); + al_install_mouse(); + al_init_font_addon(); + + display = al_create_display(800, 600); + if (!display) { + abort_example("Could not create display.\n"); + } + + load_font(); + + timer = al_create_timer(1.0 / 60); + + modes_count = al_get_num_display_modes(); + options_count = sizeof(options) / sizeof(options[0]); + + update_ui(); + + al_clear_to_color(al_map_rgb_f(1, 1, 1)); + display_options(display); + al_flip_display(); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + if (event.mouse.button == 1) { + int dw = al_get_display_width(display); + int y = 10; + int row = (event.mouse.y - y) / font_h - 1; + int column = event.mouse.x / (dw / 2); + if (column == 0) { + if (row >= 0 && row <= modes_count) { + selected_column = column; + selected_mode = row; + redraw = true; + } + } + if (column == 1) { + if (row >= 0 && row < options_count) { + selected_column = column; + selected_option = row; + redraw = true; + } + } + } + } + if (event.type == ALLEGRO_EVENT_TIMER) { + int f = al_get_display_flags(display); + if (f != flags) { + redraw = true; + flags = f; + old_flags |= f; + } + } + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + int change; + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + if (event.keyboard.keycode == ALLEGRO_KEY_LEFT) { + selected_column = 0; + redraw = true; + } + if (event.keyboard.keycode == ALLEGRO_KEY_RIGHT) { + selected_column = 1; + redraw = true; + } + if (event.keyboard.keycode == ALLEGRO_KEY_UP) { + if (selected_column == 0) selected_mode -= 1; + if (selected_column == 1) selected_option -= 1; + redraw = true; + } + if (event.keyboard.keycode == ALLEGRO_KEY_DOWN) { + if (selected_column == 0) selected_mode += 1; + if (selected_column == 1) selected_option += 1; + redraw = true; + } + if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { + if (selected_column == 0) { + ALLEGRO_DISPLAY_MODE mode; + ALLEGRO_DISPLAY *new_display; + if (selected_mode > 1) { + al_get_display_mode(selected_mode - 2, &mode); + al_set_new_display_flags(ALLEGRO_FULLSCREEN); + } + else if (selected_mode == 1) { + mode.width = 800; + mode.height = 600; + al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); + } + else { + mode.width = 800; + mode.height = 600; + al_set_new_display_flags(ALLEGRO_WINDOWED); + } + + al_destroy_font(font); + font = NULL; + + new_display = al_create_display( + mode.width, mode.height); + if (new_display) { + al_destroy_display(display); + display = new_display; + al_set_target_backbuffer(display); + al_register_event_source(queue, + al_get_display_event_source(display)); + update_ui(); + sprintf(status, "Display creation succeeded."); + } + else { + sprintf(status, "Display creation failed."); + } + + load_font(); + } + if (selected_column == 1) { + options[selected_option].required += 1; + options[selected_option].required %= 3; + al_set_new_display_option( + options[selected_option].option, + options[selected_option].value, + options[selected_option].required); + } + redraw = true; + } + change = 0; + if (event.keyboard.keycode == ALLEGRO_KEY_PGUP) change = 1; + if (event.keyboard.keycode == ALLEGRO_KEY_PGDN) change = -1; + if (change && selected_column == 1) { + options[selected_option].value += change; + if (options[selected_option].value < 0) + options[selected_option].value = 0; + if (options[selected_option].value > + options[selected_option].max_value) + options[selected_option].value = + options[selected_option].max_value; + al_set_new_display_option(options[selected_option].option, + options[selected_option].value, + options[selected_option].required); + redraw = true; + } + } + + if (selected_mode < 0) selected_mode = 0; + if (selected_mode > modes_count + 1) + selected_mode = modes_count + 1; + if (selected_option < 0) selected_option = 0; + if (selected_option >= options_count) + selected_option = options_count - 1; + if (selected_mode < first_visible_row) + first_visible_row = selected_mode; + if (selected_mode > first_visible_row + visible_rows - 1) + first_visible_row = selected_mode - visible_rows + 1; + + if (redraw && al_is_event_queue_empty(queue)) { + redraw = false; + al_clear_to_color(al_map_rgb_f(1, 1, 1)); + display_options(display); + al_flip_display(); + } + } + + al_destroy_font(font); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_draw.c b/allegro/examples/ex_draw.c new file mode 100644 index 00000000..e7b1bba7 --- /dev/null +++ b/allegro/examples/ex_draw.c @@ -0,0 +1,338 @@ +/* Tests some drawing primitives. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "common.c" + +struct Example +{ + ALLEGRO_FONT *font; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_COLOR background, text, white, foreground; + ALLEGRO_COLOR outline; + ALLEGRO_BITMAP *pattern; + ALLEGRO_BITMAP *zoom; + + double timer[4], counter[4]; + int FPS; + float text_x, text_y; + + bool software; + int samples; + int what; + int thickness; +} ex; + +char const *names[] = { + "filled rectangles", + "rectangles", + "filled circles", + "circles", + "lines" +}; + +static void draw_pattern(ALLEGRO_BITMAP *b) +{ + int w = al_get_bitmap_width(b); + int h = al_get_bitmap_height(b); + int x, y; + int format = ALLEGRO_PIXEL_FORMAT_BGR_888; + ALLEGRO_COLOR light = al_map_rgb_f(1, 1, 1); + ALLEGRO_COLOR dark = al_map_rgb_f(1, 0.9, 0.8); + ALLEGRO_LOCKED_REGION *lock; + lock = al_lock_bitmap(b, format, ALLEGRO_LOCK_WRITEONLY); + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + ALLEGRO_COLOR c = (x + y) & 1 ? light : dark; + unsigned char r, g, b; + unsigned char *data = lock->data; + al_unmap_rgb(c, &r, &g, &b); + data += y * lock->pitch; + data += x * 3; + data[0] = r; + data[1] = g; + data[2] = b; + } + } + al_unlock_bitmap(b); +} + +static void set_xy(float x, float y) +{ + ex.text_x = x; + ex.text_y = y; +} + +static void print(char const *format, ...) +{ + va_list list; + char message[1024]; + ALLEGRO_STATE state; + int th = al_get_font_line_height(ex.font); + al_store_state(&state, ALLEGRO_STATE_BLENDER); + + va_start(list, format); + vsnprintf(message, sizeof message, format, list); + va_end(list); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(ex.font, ex.text, ex.text_x, ex.text_y, 0, "%s", message); + al_restore_state(&state); + + ex.text_y += th; +} + +static void primitive(float l, float t, float r, float b, + ALLEGRO_COLOR color, bool never_fill) +{ + float cx = (l + r) / 2; + float cy = (t + b) / 2; + float rx = (r - l) / 2; + float ry = (b - t) / 2; + int tk = never_fill ? 0 : ex.thickness; + int w = ex.what; + if (w == 0 && never_fill) w = 1; + if (w == 2 && never_fill) w = 3; + if (w == 0) al_draw_filled_rectangle(l, t, r, b, color); + if (w == 1) al_draw_rectangle(l, t, r, b, color, tk); + if (w == 2) al_draw_filled_ellipse(cx, cy, rx, ry, color); + if (w == 3) al_draw_ellipse(cx, cy, rx, ry, color, tk); + if (w == 4) al_draw_line(l, t, r, b, color, tk); +} + +static void draw(void) +{ + float x, y; + int cx, cy, cw, ch; + int w = al_get_bitmap_width(ex.zoom); + int h = al_get_bitmap_height(ex.zoom); + ALLEGRO_BITMAP *screen = al_get_target_bitmap(); + ALLEGRO_BITMAP *mem; + int rects_num = 16, i, j; + float rects[16 * 4]; + for (j = 0; j < 4; j++) { + for (i = 0; i < 4; i++) { + rects[(j * 4 + i) * 4 + 0] = 2 + i * 0.25 + i * 7; + rects[(j * 4 + i) * 4 + 1] = 2 + j * 0.25 + j * 7; + rects[(j * 4 + i) * 4 + 2] = 2 + i * 0.25 + i * 7 + 5; + rects[(j * 4 + i) * 4 + 3] = 2 + j * 0.25 + j * 7 + 5; + } + } + + al_get_clipping_rectangle(&cx, &cy, &cw, &ch); + al_clear_to_color(ex.background); + + set_xy(8, 0); + print("Drawing %s (press SPACE to change)", names[ex.what]); + + set_xy(8, 16); + print("Original"); + + set_xy(80, 16); + print("Enlarged x 16"); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + if (ex.software) { + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + al_set_new_bitmap_format(al_get_bitmap_format(al_get_target_bitmap())); + mem = al_create_bitmap(w, h); + al_set_target_bitmap(mem); + x = 0; + y = 0; + } + else { + mem = NULL; + x = 8; + y = 40; + } + al_draw_bitmap(ex.pattern, x, y, 0); + + /* Draw the test scene. */ + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + for (i = 0; i < rects_num; i++) { + ALLEGRO_COLOR rgba = ex.foreground; + rgba.a *= 0.5; + primitive( + x + rects[i * 4 + 0], + y + rects[i * 4 + 1], + x + rects[i * 4 + 2], + y + rects[i * 4 + 3], + rgba, false); + } + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + if (ex.software) { + al_set_target_bitmap(screen); + x = 8; + y = 40; + al_draw_bitmap(mem, x, y, 0); + al_destroy_bitmap(mem); + } + + /* Grab screen contents into our bitmap. */ + al_set_target_bitmap(ex.zoom); + al_draw_bitmap_region(screen, x, y, w, h, 0, 0, 0); + al_set_target_bitmap(screen); + + /* Draw it enlarged. */ + x = 80; + y = 40; + al_draw_scaled_bitmap(ex.zoom, 0, 0, w, h, x, y, w * 16, h * 16, 0); + + /* Draw outlines. */ + for (i = 0; i < rects_num; i++) { + primitive( + x + rects[i * 4 + 0] * 16, + y + rects[i * 4 + 1] * 16, + x + rects[i * 4 + 2] * 16, + y + rects[i * 4 + 3] * 16, + ex.outline, true); + } + + set_xy(8, 640 - 48); + print("Thickness: %d (press T to change)", ex.thickness); + print("Drawing with: %s (press S to change)", + ex.software ? "software" : "hardware"); + print("Supersampling: %dx (edit ex_draw.ini to change)", ex.samples); + +// FIXME: doesn't work +// al_get_display_option(ALLEGRO_SAMPLE_BUFFERS)); +} + +static void tick(void) +{ + draw(); + al_flip_display(); +} + +static void run(void) +{ + ALLEGRO_EVENT event; + bool need_draw = true; + + while (1) { + if (need_draw && al_is_event_queue_empty(ex.queue)) { + tick(); + need_draw = false; + } + + al_wait_for_event(ex.queue, &event); + + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + return; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + return; + if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + ex.what++; + if (ex.what == 5) ex.what = 0; + } + if (event.keyboard.keycode == ALLEGRO_KEY_S) { + ex.software = !ex.software; + } + if (event.keyboard.keycode == ALLEGRO_KEY_T) { + ex.thickness++; + if (ex.thickness == 2) ex.thickness = 0; + } + break; + + case ALLEGRO_EVENT_TIMER: + need_draw = true; + break; + } + } +} + +static void init(void) +{ + ex.FPS = 60; + + ex.font = al_load_font("data/fixed_font.tga", 0, 0); + if (!ex.font) { + abort_example("data/fixed_font.tga not found.\n"); + } + ex.background = al_color_name("beige"); + ex.foreground = al_color_name("black"); + ex.outline = al_color_name("red"); + ex.text = al_color_name("blue"); + ex.white = al_color_name("white"); + ex.pattern = al_create_bitmap(32, 32); + ex.zoom = al_create_bitmap(32, 32); + draw_pattern(ex.pattern); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_CONFIG *config; + char const *value; + char str[256]; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + /* Read supersampling info from ex_draw.ini. */ + ex.samples = 0; + config = al_load_config_file("ex_draw.ini"); + if (!config) + config = al_create_config(); + value = al_get_config_value(config, "settings", "samples"); + if (value) + ex.samples = strtol(value, NULL, 0); + sprintf(str, "%d", ex.samples); + al_set_config_value(config, "settings", "samples", str); + al_save_config_file("ex_draw.ini", config); + al_destroy_config(config); + + if (ex.samples) { + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE); + al_set_new_display_option(ALLEGRO_SAMPLES, ex.samples, ALLEGRO_SUGGEST); + } + display = al_create_display(640, 640); + if (!display) { + abort_example("Unable to create display.\n"); + } + + init(); + + timer = al_create_timer(1.0 / ex.FPS); + + ex.queue = al_create_event_queue(); + al_register_event_source(ex.queue, al_get_keyboard_event_source()); + al_register_event_source(ex.queue, al_get_mouse_event_source()); + al_register_event_source(ex.queue, al_get_display_event_source(display)); + al_register_event_source(ex.queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + run(); + + al_destroy_event_queue(ex.queue); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_draw_bitmap.c b/allegro/examples/ex_draw_bitmap.c new file mode 100644 index 00000000..3756b6bc --- /dev/null +++ b/allegro/examples/ex_draw_bitmap.c @@ -0,0 +1,467 @@ +#include +#include +#include +#include +#include + +#include "common.c" + +ALLEGRO_DEBUG_CHANNEL("main") + +#define FPS 60 +#define MAX_SPRITES 1024 + +typedef struct Sprite { + float x, y, dx, dy; +} Sprite; + +char const *text[] = { + "H - toggle held drawing", + "Space - toggle use of textures", + "B - toggle alpha blending", + "Left/Right - change bitmap size", + "Up/Down - change bitmap count", + "F1 - toggle help text" +}; + +struct Example { + Sprite sprites[MAX_SPRITES]; + bool use_memory_bitmaps; + int blending; + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *mysha, *bitmap; + bool hold_bitmap_drawing; + int bitmap_size; + int sprite_count; + bool show_help; + ALLEGRO_FONT *font; + + int t; + + ALLEGRO_COLOR white; + ALLEGRO_COLOR half_white; + ALLEGRO_COLOR dark; + ALLEGRO_COLOR red; + + double direct_speed_measure; + + int ftpos; + double frame_times[FPS]; +} example; + +static void add_time(void) +{ + example.frame_times[example.ftpos++] = al_get_time(); + if (example.ftpos >= FPS) + example.ftpos = 0; +} + +static void get_fps(int *average, int *minmax) +{ + int i; + int prev = FPS - 1; + double min_dt = 1; + double max_dt = 1 / 1000000.0; + double av = 0; + double d; + for (i = 0; i < FPS; i++) { + if (i != example.ftpos) { + double dt = example.frame_times[i] - example.frame_times[prev]; + if (dt < min_dt) + min_dt = dt; + if (dt > max_dt) + max_dt = dt; + av += dt; + } + prev = i; + } + av /= (FPS - 1); + *average = ceil(1 / av); + d = 1 / min_dt - 1 / max_dt; + *minmax = floor(d / 2); +} + +static void add_sprite(void) +{ + if (example.sprite_count < MAX_SPRITES) { + int w = al_get_display_width(example.display); + int h = al_get_display_height(example.display); + int i = example.sprite_count++; + Sprite *s = example.sprites + i; + float a = rand() % 360; + s->x = rand() % (w - example.bitmap_size); + s->y = rand() % (h - example.bitmap_size); + s->dx = cos(a) * FPS * 2; + s->dy = sin(a) * FPS * 2; + } +} + +static void add_sprites(int n) +{ + int i; + for (i = 0; i < n; i++) + add_sprite(); +} + +static void remove_sprites(int n) +{ + example.sprite_count -= n; + if (example.sprite_count < 0) + example.sprite_count = 0; +} + +static void change_size(int size) +{ + int bw, bh; + if (size < 1) + size = 1; + if (size > 1024) + size = 1024; + + if (example.bitmap) + al_destroy_bitmap(example.bitmap); + al_set_new_bitmap_flags( + example.use_memory_bitmaps ? ALLEGRO_MEMORY_BITMAP : ALLEGRO_VIDEO_BITMAP); + example.bitmap = al_create_bitmap(size, size); + example.bitmap_size = size; + al_set_target_bitmap(example.bitmap); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); + bw = al_get_bitmap_width(example.mysha); + bh = al_get_bitmap_height(example.mysha); + al_draw_scaled_bitmap(example.mysha, 0, 0, bw, bh, 0, 0, + size, size * bh / bw, 0); + al_set_target_backbuffer(example.display); +} + +static void sprite_update(Sprite *s) +{ + int w = al_get_display_width(example.display); + int h = al_get_display_height(example.display); + + s->x += s->dx / FPS; + s->y += s->dy / FPS; + + if (s->x < 0) { + s->x = -s->x; + s->dx = -s->dx; + } + if (s->x + example.bitmap_size > w) { + s->x = -s->x + 2 * (w - example.bitmap_size); + s->dx = -s->dx; + } + if (s->y < 0) { + s->y = -s->y; + s->dy = -s->dy; + } + if (s->y + example.bitmap_size > h) { + s->y = -s->y + 2 * (h - example.bitmap_size); + s->dy = -s->dy; + } + + if (example.bitmap_size > w) s->x = w / 2 - example.bitmap_size / 2; + if (example.bitmap_size > h) s->y = h / 2 - example.bitmap_size / 2; +} + +static void update(void) +{ + int i; + for (i = 0; i < example.sprite_count; i++) + sprite_update(example.sprites + i); + + example.t++; + if (example.t == 60) { + ALLEGRO_DEBUG("tick"); + example.t = 0; + } +} + +static void redraw(void) +{ + int w = al_get_display_width(example.display); + int h = al_get_display_height(example.display); + int i; + int f1, f2; + int fh = al_get_font_line_height(example.font); + char const *info[] = {"textures", "memory buffers"}; + char const *binfo[] = {"alpha", "additive", "tinted", "solid", "alpha test"}; + ALLEGRO_COLOR tint = example.white; + + if (example.blending == 0) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + tint = example.half_white; + } + else if (example.blending == 1) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + tint = example.dark; + } + else if (example.blending == 2) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + tint = example.red; + } + else if (example.blending == 3) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + } + + if (example.blending == 4) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_set_render_state(ALLEGRO_ALPHA_TEST, true); + al_set_render_state(ALLEGRO_ALPHA_FUNCTION, ALLEGRO_RENDER_GREATER); + al_set_render_state(ALLEGRO_ALPHA_TEST_VALUE, 128); + } + else { + al_set_render_state(ALLEGRO_ALPHA_TEST, false); + } + + if (example.hold_bitmap_drawing) { + al_hold_bitmap_drawing(true); + } + for (i = 0; i < example.sprite_count; i++) { + Sprite *s = example.sprites + i; + al_draw_tinted_bitmap(example.bitmap, tint, s->x, s->y, 0); + } + if (example.hold_bitmap_drawing) { + al_hold_bitmap_drawing(false); + } + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + if (example.show_help) { + int dh = fh * 3.5; + for (i = 5; i >= 0; i--) { + al_draw_text(example.font, example.white, 0, h - dh, 0, text[i]); + dh += fh * 6; + } + } + + al_draw_textf(example.font, example.white, 0, 0, 0, "count: %d", + example.sprite_count); + al_draw_textf(example.font, example.white, 0, fh, 0, "size: %d", + example.bitmap_size); + al_draw_textf(example.font, example.white, 0, fh * 2, 0, "%s", + info[example.use_memory_bitmaps]); + al_draw_textf(example.font, example.white, 0, fh * 3, 0, "%s", + binfo[example.blending]); + + get_fps(&f1, &f2); + al_draw_textf(example.font, example.white, w, 0, ALLEGRO_ALIGN_RIGHT, "FPS: %4d +- %-4d", + f1, f2); + al_draw_textf(example.font, example.white, w, fh, ALLEGRO_ALIGN_RIGHT, "%4d / sec", + (int)(1.0 / example.direct_speed_measure)); + +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_MONITOR_INFO info; + const char* bitmap_filename; + int w = 640, h = 480; + bool done = false; + bool need_redraw = true; + bool background = false; + example.show_help = true; + example.hold_bitmap_drawing = false; + + if (argc > 1) { + bitmap_filename = argv[1]; + } + else { + bitmap_filename = "data/mysha256x256.png"; + } + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + al_init_font_addon(); + init_platform_specific(); + + al_get_num_video_adapters(); + + al_get_monitor_info(0, &info); + + al_set_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, + ALLEGRO_DISPLAY_ORIENTATION_ALL, ALLEGRO_SUGGEST); + example.display = al_create_display(w, h); + if (!example.display) { + abort_example("Error creating display.\n"); + } + + w = al_get_display_width(example.display); + h = al_get_display_height(example.display); + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + if (!al_install_mouse()) { + abort_example("Error installing mouse.\n"); + } + + al_install_touch_input(); + + example.font = al_create_builtin_font(); + if (!example.font) { + abort_example("Error creating builtin font\n"); + } + + example.mysha = al_load_bitmap(bitmap_filename); + if (!example.mysha) { + abort_example("Error loading %s\n", bitmap_filename); + } + + example.white = al_map_rgb_f(1, 1, 1); + example.half_white = al_map_rgba_f(1, 1, 1, 0.5); + example.dark = al_map_rgb(15, 15, 15); + example.red = al_map_rgb_f(1, 0.2, 0.1); + change_size(256); + add_sprite(); + add_sprite(); + + timer = al_create_timer(1.0 / FPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + if (al_install_touch_input()) + al_register_event_source(queue, al_get_touch_input_event_source()); + al_register_event_source(queue, al_get_display_event_source(example.display)); + + al_start_timer(timer); + + while (!done) { + float x, y; + ALLEGRO_EVENT event; + w = al_get_display_width(example.display); + h = al_get_display_height(example.display); + + if (!background && need_redraw && al_is_event_queue_empty(queue)) { + double t = -al_get_time(); + add_time(); + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + redraw(); + t += al_get_time(); + example.direct_speed_measure = t; + al_flip_display(); + need_redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_CHAR: /* includes repeats */ + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + else if (event.keyboard.keycode == ALLEGRO_KEY_UP) { + add_sprites(1); + } + else if (event.keyboard.keycode == ALLEGRO_KEY_DOWN) { + remove_sprites(1); + } + else if (event.keyboard.keycode == ALLEGRO_KEY_LEFT) { + change_size(example.bitmap_size - 1); + } + else if (event.keyboard.keycode == ALLEGRO_KEY_RIGHT) { + change_size(example.bitmap_size + 1); + } + else if (event.keyboard.keycode == ALLEGRO_KEY_F1) { + example.show_help ^= 1; + } + else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + example.use_memory_bitmaps ^= 1; + change_size(example.bitmap_size); + } + else if (event.keyboard.keycode == ALLEGRO_KEY_B) { + example.blending++; + if (example.blending == 5) + example.blending = 0; + } + else if (event.keyboard.keycode == ALLEGRO_KEY_H) { + example.hold_bitmap_drawing ^= 1; + } + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: + + background = true; + al_acknowledge_drawing_halt(event.display.source); + + break; + + case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: + background = false; + al_acknowledge_drawing_resume(event.display.source); + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(event.display.source); + break; + + case ALLEGRO_EVENT_TIMER: + update(); + need_redraw = true; + break; + + case ALLEGRO_EVENT_TOUCH_BEGIN: + x = event.touch.x; + y = event.touch.y; + goto click; + + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + x = event.mouse.x; + y = event.mouse.y; + goto click; + + click: + { + int fh = al_get_font_line_height(example.font); + + if (x < fh * 12 && y >= h - fh * 30) { + int button = (y - (h - fh * 30)) / (fh * 6); + if (button == 0) { + example.use_memory_bitmaps ^= 1; + change_size(example.bitmap_size); + } + if (button == 1) { + example.blending++; + if (example.blending == 5) + example.blending = 0; + } + if (button == 3) { + if (x < fh * 6) + remove_sprites(example.sprite_count / 2); + else + add_sprites(example.sprite_count); + } + if (button == 2) { + int s = example.bitmap_size * 2; + if (x < fh * 6) + s = example.bitmap_size / 2; + change_size(s); + } + if (button == 4) { + example.show_help ^= 1; + } + + } + break; + } + } + } + + al_destroy_bitmap(example.bitmap); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_drawpixels.c b/allegro/examples/ex_drawpixels.c new file mode 100644 index 00000000..f297d665 --- /dev/null +++ b/allegro/examples/ex_drawpixels.c @@ -0,0 +1,137 @@ +#include +#include + +#include "common.c" + +#define WIDTH 640 +#define HEIGHT 480 +#define NUM_STARS 300 +#define TARGET_FPS 9999 + + +typedef struct Point +{ + float x, y; +} Point; + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_KEYBOARD_STATE key_state; + Point stars[3][NUM_STARS/3]; + float speeds[3] = { 0.0001f, 0.05f, 0.15f }; + ALLEGRO_COLOR colors[3]; + long start, now, elapsed, frame_count; + int total_frames = 0; + double program_start; + double length; + int layer, star; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_install_keyboard(); + + display = al_create_display(WIDTH, HEIGHT); + if (!display) { + abort_example("Could not create display.\n"); + } + + colors[0] = al_map_rgba(255, 100, 255, 128); + colors[1] = al_map_rgba(255, 100, 100, 255); + colors[2] = al_map_rgba(100, 100, 255, 255); + + for (layer = 0; layer < 3; layer++) { + for (star = 0; star < NUM_STARS/3; star++) { + Point *p = &stars[layer][star]; + p->x = rand() % WIDTH; + p->y = rand() % HEIGHT; + } + } + + + start = al_get_time() * 1000; + now = start; + elapsed = 0; + frame_count = 0; + program_start = al_get_time(); + + + while (1) { + if (frame_count < (1000/TARGET_FPS)) { + frame_count += elapsed; + } + else { + int X, Y; + + frame_count -= (1000/TARGET_FPS); + al_clear_to_color(al_map_rgb(0, 0, 0)); + for (star = 0; star < NUM_STARS/3; star++) { + Point *p = &stars[0][star]; + al_draw_pixel(p->x, p->y, colors[0]); + } + al_lock_bitmap(al_get_backbuffer(display), ALLEGRO_PIXEL_FORMAT_ANY, 0); + + for (layer = 1; layer < 3; layer++) { + for (star = 0; star < NUM_STARS/3; star++) { + Point *p = &stars[layer][star]; + // put_pixel ignores blending + al_put_pixel(p->x, p->y, colors[layer]); + } + } + + /* Check that dots appear at the window extremes. */ + X = WIDTH - 1; + Y = HEIGHT - 1; + al_put_pixel(0, 0, al_map_rgb_f(1, 1, 1)); + al_put_pixel(X, 0, al_map_rgb_f(1, 1, 1)); + al_put_pixel(0, Y, al_map_rgb_f(1, 1, 1)); + al_put_pixel(X, Y, al_map_rgb_f(1, 1, 1)); + + al_unlock_bitmap(al_get_backbuffer(display)); + al_flip_display(); + total_frames++; + } + + now = al_get_time() * 1000; + elapsed = now - start; + start = now; + + for (layer = 0; layer < 3; layer++) { + for (star = 0; star < NUM_STARS/3; star++) { + Point *p = &stars[layer][star]; + p->y -= speeds[layer] * elapsed; + if (p->y < 0) { + p->x = rand() % WIDTH; + p->y = HEIGHT; + } + } + } + + al_rest(0.001); + + al_get_keyboard_state(&key_state); + if (al_key_down(&key_state, ALLEGRO_KEY_ESCAPE)) + break; + } + + length = al_get_time() - program_start; + + if (length != 0) { + log_printf("%d FPS\n", (int)(total_frames / length)); + } + + al_destroy_display(display); + + close_log(true); + + return 0; +} + diff --git a/allegro/examples/ex_dualies.c b/allegro/examples/ex_dualies.c new file mode 100644 index 00000000..6bebb140 --- /dev/null +++ b/allegro/examples/ex_dualies.c @@ -0,0 +1,88 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include + +#include "common.c" + +static void go(void) +{ + ALLEGRO_DISPLAY *d1, *d2; + ALLEGRO_BITMAP *b1, *b2; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + + al_set_new_display_flags(ALLEGRO_FULLSCREEN); + + al_set_new_display_adapter(0); + d1 = al_create_display(640, 480); + if (!d1) { + abort_example("Error creating first display\n"); + } + b1 = al_load_bitmap("data/mysha.pcx"); + if (!b1) { + abort_example("Error loading mysha.pcx\n"); + } + + al_set_new_display_adapter(1); + d2 = al_create_display(640, 480); + if (!d2) { + abort_example("Error creating second display\n"); + } + b2 = al_load_bitmap("data/allegro.pcx"); + if (!b2) { + abort_example("Error loading allegro.pcx\n"); + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + while (1) { + if (!al_is_event_queue_empty(queue)) { + al_get_next_event(queue, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + } + } + + al_set_target_backbuffer(d1); + al_draw_scaled_bitmap(b1, 0, 0, 320, 200, 0, 0, 640, 480, 0); + al_flip_display(); + + al_set_target_backbuffer(d2); + al_draw_scaled_bitmap(b2, 0, 0, 320, 200, 0, 0, 640, 480, 0); + al_flip_display(); + + al_rest(0.1); + } + + al_destroy_bitmap(b1); + al_destroy_bitmap(b2); + al_destroy_display(d1); + al_destroy_display(d2); +} + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + + al_init_image_addon(); + + if (al_get_num_video_adapters() < 2) { + abort_example("You need 2 or more adapters/monitors for this example.\n"); + } + + go(); + + return 0; + +} + diff --git a/allegro/examples/ex_enet_client.c b/allegro/examples/ex_enet_client.c new file mode 100644 index 00000000..ad1b1c6f --- /dev/null +++ b/allegro/examples/ex_enet_client.c @@ -0,0 +1,259 @@ +/* Simple networked game example using ENet (http://enet.bespin.org/). + * + * You will need enet installed to run this demo. + * + * This example is based on http://enet.bespin.org/Tutorial.html + * + * To try this example, first run ex_enet_server. + * Then start multiple instances of ex_enet_client. + */ +#include +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" +#include "enet_common.h" + +static ENetHost* create_client(void) +{ + ENetHost * client; + client = enet_host_create(NULL /* create a client host */, + 1 /* only allow 1 outgoing connection */, + 2 /* allow up 2 channels to be used, 0 and 1 */, + 57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */, + 14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */); + + if (client == NULL) + abort_example("Client: Failed to create the client.\n"); + + return client; +} + +static void disconnect_client(ENetHost *client, ENetPeer *server) +{ + enet_peer_disconnect(server, 0); + + /* Allow up to 3 seconds for the disconnect to succeed + * and drop any packets received packets. + */ + ENetEvent event; + while (enet_host_service (client, &event, 3000) > 0) { + switch (event.type) { + case ENET_EVENT_TYPE_RECEIVE: + enet_packet_destroy(event.packet); + break; + case ENET_EVENT_TYPE_DISCONNECT: + puts("Client: Disconnect succeeded."); + return; + case ENET_EVENT_TYPE_NONE: + case ENET_EVENT_TYPE_CONNECT: + break; + } + } + + // failed to disconnect gracefully, force the connection closed + enet_peer_reset(server); +} + +static ENetPeer* connect_client(ENetHost *client, int port) +{ + ENetAddress address; + ENetEvent event; + ENetPeer *server; + enet_address_set_host(&address, "localhost"); + address.port = port; + /* Initiate the connection, allocating the two channels 0 and 1. */ + server = enet_host_connect(client, &address, 2, 0); + if (server == NULL) + abort_example("Client: No available peers for initiating an ENet connection.\n"); + + /* Wait up to 5 seconds for the connection attempt to succeed. */ + if (enet_host_service(client, &event, 5000) > 0 && + event.type == ENET_EVENT_TYPE_CONNECT) + { + printf("Client: Connected to %x:%u.\n", + event.peer->address.host, + event.peer->address.port); + } + else + { + /* Either the 5 seconds are up or a disconnect event was */ + /* received. Reset the peer in the event the 5 seconds */ + /* had run out without any significant event. */ + enet_peer_reset(server); + abort_example("Client: Connection to server failed."); + } + + return server; +} + +static void send_receive(ENetHost *client) +{ + ENetEvent event; + ServerMessage *msg; + + // Check if we have any queued incoming messages, but do not wait otherwise. + // This also sends outgoing messages queued with enet_peer_send. + while (enet_host_service(client, &event, 0) > 0) { + // clients only care about incoming packets, they will not receive + // connect/disconnect events. + if (event.type == ENET_EVENT_TYPE_RECEIVE) { + msg = (ServerMessage*)event.packet->data; + + switch (msg->type) { + case POSITION_UPDATE: + players[msg->player_id].x = msg->x; + players[msg->player_id].y = msg->y; + break; + case PLAYER_JOIN: + printf("Client: player #%d joined\n", msg->player_id); + players[msg->player_id].active = true; + players[msg->player_id].x = msg->x; + players[msg->player_id].y = msg->y; + players[msg->player_id].color = msg->color; + break; + case PLAYER_LEAVE: + printf("Client: player #%d left\n", msg->player_id); + players[msg->player_id].active = false; + break; + } + + /* Clean up the packet now that we're done using it. */ + enet_packet_destroy(event.packet); + } + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + ENetHost *client; + ENetPeer *server; + bool update = true; // when true, update positions and render + bool done = false; // when true, client exits + int dx = 0, dy = 0; // movement direction + int port = DEFAULT_PORT; + int i; + + if (argc == 2) { + port = atoi(argv[1]); + } + else if (argc > 2) + abort_example("Usage: %s [portnum]", argv[0]); + + + // --- allegro setup --- + if (!al_init()) + abort_example("Could not init Allegro.\n"); + + init_platform_specific(); + + al_install_keyboard(); + al_init_primitives_addon(); + + // Create a new display that we can render the image to. + display = al_create_display(SCREEN_W, SCREEN_H); + if (!display) + abort_example("Error creating display\n"); + + timer = al_create_timer(1.0 / FPS); // Run at 30FPS + queue = al_create_event_queue(); + + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + // --- enet setup --- + if (enet_initialize() != 0) + abort_example("An error occurred while initializing ENet.\n"); + + client = create_client(); + server = connect_client(client, port); + + // --- game loop --- + bool direction_changed = false; + while (!done) { + al_wait_for_event(queue, &event); // Wait for and get an event. + + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + case ALLEGRO_EVENT_KEY_DOWN: + switch (event.keyboard.keycode) { + case ALLEGRO_KEY_UP: + case ALLEGRO_KEY_W: dy -= 1; direction_changed = true; break; + case ALLEGRO_KEY_DOWN: + case ALLEGRO_KEY_S: dy += 1; direction_changed = true; break; + case ALLEGRO_KEY_LEFT: + case ALLEGRO_KEY_A: dx -= 1; direction_changed = true; break; + case ALLEGRO_KEY_RIGHT: + case ALLEGRO_KEY_D: dx += 1; direction_changed = true; break; + } + break; + case ALLEGRO_EVENT_KEY_UP: + switch (event.keyboard.keycode) { + case ALLEGRO_KEY_UP: + case ALLEGRO_KEY_W: dy += 1; direction_changed = true; break; + case ALLEGRO_KEY_DOWN: + case ALLEGRO_KEY_S: dy -= 1; direction_changed = true; break; + case ALLEGRO_KEY_LEFT: + case ALLEGRO_KEY_A: dx += 1; direction_changed = true; break; + case ALLEGRO_KEY_RIGHT: + case ALLEGRO_KEY_D: dx -= 1; direction_changed = true; break; + } + break; + case (ALLEGRO_EVENT_TIMER): + update = true; + break; + } + + // update, but only if the event queue is empty + if (update && al_is_event_queue_empty(queue)) { + update = false; + + // if player changed direction this frame, notify the server. + // only check once per frame to stop clients from flooding the server + if (direction_changed) { + direction_changed = false; + + ClientMessage msg = { dx, dy }; + + ENetPacket *packet = enet_packet_create(&msg, + sizeof(msg), + ENET_PACKET_FLAG_RELIABLE); + + enet_peer_send(server, 0, packet); + } + + // this will send our queued direction message if we have one, and get + // position updates for other clients + send_receive(client); + + // draw each player + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + for (i = 0; i < MAX_PLAYER_COUNT; i++) { + if (!players[i].active) continue; + + int x = players[i].x; + int y = players[i].y; + ALLEGRO_COLOR color = players[i].color; + al_draw_filled_circle(x, y, PLAYER_SIZE, color); + } + al_flip_display(); + } + } + + disconnect_client(client, server); + enet_host_destroy(client); + enet_deinitialize(); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_enet_server.c b/allegro/examples/ex_enet_server.c new file mode 100644 index 00000000..edb3e89f --- /dev/null +++ b/allegro/examples/ex_enet_server.c @@ -0,0 +1,240 @@ +/* Simple networked game example using ENet (http://enet.bespin.org/). + * + * You will need enet installed to run this demo. + * + * This example is based on http://enet.bespin.org/Tutorial.html + * + * This is the server, which you will want to start first. Once the server is + * running, run ex_enet_client to connect each client. + */ +#include +#include +#include +#include +#include + +#include "common.c" +#include "enet_common.h" + +#define PLAYER_SPEED 200 // pixels / second + +const int port = 9234; + +static float rand01(void) { return rand() / (float)RAND_MAX; } + +static int init_player(void) +{ + int i; + // find the first open player slot + for (i = 0 ; i < MAX_PLAYER_COUNT ; ++i) { + if (!players[i].active) { + // assign a random color and position to this new player + players[i].active = true; + players[i].color = al_map_rgb_f(rand01(), rand01(), rand01()); + players[i].x = rand01() * SCREEN_W; + players[i].y = rand01() * SCREEN_H; + + return i; + } + } + + abort_example("Cannot create more than %d clients", MAX_PLAYER_COUNT); + return -1; +} + +static ServerMessage create_join_message(int player_id) +{ + ServerMessage msg_out; + msg_out.type = PLAYER_JOIN; + msg_out.player_id = player_id; + msg_out.color = players[player_id].color; + msg_out.x = players[player_id].x; + msg_out.y = players[player_id].y; + return msg_out; +} + +static void send_receive(ENetHost *server) +{ + ClientMessage *msg_in; + ServerMessage msg_out; + ENetPacket *packet; + ENetEvent event; + int i; + + // Process all messages in queue, exit as soon as it is empty + while (enet_host_service(server, &event, 0) > 0) { + switch (event.type) { + case ENET_EVENT_TYPE_NONE: + break; + case ENET_EVENT_TYPE_CONNECT: + printf("Server: A new client connected from %x:%u.\n", + event.peer->address.host, + event.peer->address.port); + + int player_id = init_player(); + + // store the id with the peer we can correlate messages from this + // client with this ID + event.peer->data = malloc(sizeof(int)); + *(int*)event.peer->data = player_id; + + // notify all clients of the new player + msg_out = create_join_message(player_id); + + printf("Server: created player #%d at %d,%d\n", + player_id, + players[player_id].x, + players[player_id].y); + + packet = enet_packet_create(&msg_out, + sizeof(msg_out), + ENET_PACKET_FLAG_RELIABLE); + + enet_host_broadcast(server, 0, packet); + + // notify new client of all other existing players + for (i = 0 ; i < MAX_PLAYER_COUNT ; ++i) { + if (!players[i].active || i == player_id) continue; + + msg_out = create_join_message(i); + + packet = enet_packet_create(&msg_out, + sizeof(msg_out), + ENET_PACKET_FLAG_RELIABLE); + enet_peer_send(event.peer, 0, packet); + } + + break; + case ENET_EVENT_TYPE_RECEIVE: + msg_in = (ClientMessage*)event.packet->data; + + // update the player's movement + player_id = *(int*)event.peer->data; + players[player_id].dx = msg_in->x; + players[player_id].dy = msg_in->y; + + /* Clean up the incoming packet now that we're done using it. */ + enet_packet_destroy(event.packet); + break; + case ENET_EVENT_TYPE_DISCONNECT: + printf("Server: client #%d disconnected.\n", *((int*)event.peer->data)); + + // notify all other players that a player left + msg_out.type = PLAYER_LEAVE; + msg_out.player_id = *(int*)event.peer->data; + + packet = enet_packet_create(&msg_out, + sizeof(msg_out), + ENET_PACKET_FLAG_RELIABLE); + + enet_host_broadcast(server, 0, packet); + + /* Reset the peer's server information. */ + free(event.peer->data); + event.peer->data = NULL; + } + } +} + +static void update_players(ENetHost *server, float time) +{ + int i; + for (i = 0 ; i < MAX_PLAYER_COUNT ; ++i) { + if (!players[i].active) continue; + + players[i].x += players[i].dx * PLAYER_SPEED * time; + players[i].y += players[i].dy * PLAYER_SPEED * time; + + // notify all clients of this player's new position + ServerMessage msg; + msg.type = POSITION_UPDATE; + msg.player_id = i; + msg.x = players[i].x; + msg.y = players[i].y; + + ENetPacket *packet = enet_packet_create(&msg, + sizeof(ServerMessage), + ENET_PACKET_FLAG_RELIABLE); + + enet_host_broadcast(server, 0, packet); + } +} + +static ENetHost* create_server(int port) +{ + ENetAddress address; + ENetHost *server; + /* Bind the server to the default localhost. */ + /* A specific host address can be specified by */ + /* enet_address_set_host (&address, "x.x.x.x"); */ + address.host = ENET_HOST_ANY; + /* Bind the server to port 1234. */ + address.port = port; + server = enet_host_create(&address /* the address to bind the server host to */, + 32 /* allow up to 32 clients and/or outgoing connections */, + 2 /* allow up to 2 channels to be used, 0 and 1 */, + 0 /* assume any amount of incoming bandwidth */, + 0 /* assume any amount of outgoing bandwidth */); + if (server == NULL) { + fprintf(stderr, "Failed to create the server.\n"); + exit(EXIT_FAILURE); + } + + return server; +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + double last_time; // time of last update + double cur_time; // time of this update + srand(time(NULL)); + ENetHost * server; + int port; + + if (argc == 1) + port = DEFAULT_PORT; + else if (argc == 2) + port = atoi(argv[1]); + else + abort_example("Usage: %s [portnum]", argv[0]); + + if (!al_init()) + abort_example("Could not init Allegro.\n"); + + if (enet_initialize() != 0) { + fprintf(stderr, "An error occurred while initializing ENet.\n"); + return EXIT_FAILURE; + } + + timer = al_create_timer(1.0 / FPS); // Run at 30FPS + queue = al_create_event_queue(); + + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + server = create_server(port); + + last_time = al_get_time(); + + while(1) + { + al_wait_for_event(queue, &event); // Wait for and get an event. + + if (event.type == ALLEGRO_EVENT_TIMER) { + cur_time = al_get_time(); + update_players(server, cur_time - last_time); + last_time = cur_time; + + send_receive(server); + } + } + + enet_host_destroy(server); + enet_deinitialize(); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_expose.c b/allegro/examples/ex_expose.c new file mode 100644 index 00000000..df9b3d04 --- /dev/null +++ b/allegro/examples/ex_expose.c @@ -0,0 +1,92 @@ +#include +#include +#include + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bitmap; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_init_image_addon(); + al_install_keyboard(); + al_install_mouse(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_RESIZABLE | + ALLEGRO_GENERATE_EXPOSE_EVENTS); + al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, true, ALLEGRO_REQUIRE); + display = al_create_display(320, 200); + if (!display) { + abort_example("Error creating display\n"); + } + + bitmap = al_load_bitmap("data/mysha.pcx"); + if (!bitmap) { + abort_example("mysha.pcx not found or failed to load\n"); + } + al_draw_bitmap(bitmap, 0, 0, 0); + al_flip_display(); + + timer = al_create_timer(0.1); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + while (true) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { + al_acknowledge_resize(event.display.source); + } + if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { + int x = event.display.x, + y = event.display.y, + w = event.display.width, + h = event.display.height; + /* Draw a red rectangle over the damaged area. */ + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_filled_rectangle(x, y, x + w, y + h, al_map_rgba_f(1, 0, 0, 1)); + al_flip_display(); + } + if (event.type == ALLEGRO_EVENT_TIMER) { + /* Slowly restore the original bitmap. */ + int x, y; + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + for (y = 0; y < al_get_display_height(display); y += 200) { + for (x = 0; x < al_get_display_width(display); x += 320) { + al_draw_tinted_bitmap(bitmap, al_map_rgba_f(1, 1, 1, 0.1), x, y, 0); + } + } + al_flip_display(); + } + } + + al_destroy_event_queue(queue); + al_destroy_bitmap(bitmap); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_file.c b/allegro/examples/ex_file.c new file mode 100644 index 00000000..96ed7de4 --- /dev/null +++ b/allegro/examples/ex_file.c @@ -0,0 +1,154 @@ +#include + +#include "common.c" + +static int error = 0; + +#define SEP() \ + log_printf("\n# line %d\n", __LINE__) + +#define CHECK(_expr, _type, _expect) \ + do { \ + _type res = (_expr); \ + if (res != (_expect)) { \ + log_printf("FAIL %s\n", #_expr); \ + error++; \ + } else { \ + log_printf("OK %s\n", #_expr); \ + } \ + } while (0) + +static void read_test(void) +{ + ALLEGRO_FILE *f; + uint8_t bs[8]; + int32_t sz; + + f = al_fopen("data/allegro.pcx", "rb"); + if (!f) { + error++; + return; + } + + /* Test: reading bytes advances position. */ + SEP(); + CHECK(al_ftell(f), int, 0); + CHECK(al_fgetc(f), int, 0xa); + CHECK(al_fgetc(f), int, 0x5); + CHECK(al_ftell(f), int64_t, 2); + + /* Test: ungetc moves position back. */ + SEP(); + CHECK(al_fungetc(f, 0x55), bool, true); + CHECK(al_ftell(f), int64_t, 1); + + /* Test: read buffer. */ + SEP(); + CHECK(al_fread(f, bs, sizeof(bs)), size_t, sizeof(bs)); + CHECK(bs[0], uint8_t, 0x55); /* pushback */ + CHECK(bs[1], uint8_t, 0x01); + CHECK(bs[2], uint8_t, 0x08); + CHECK(bs[3], uint8_t, 0x00); + CHECK(bs[4], uint8_t, 0x00); + CHECK(bs[5], uint8_t, 0x00); + CHECK(bs[6], uint8_t, 0x00); + CHECK(bs[7], uint8_t, 0x3f); + CHECK(al_ftell(f), int64_t, 9); + + /* Test: seek absolute. */ + SEP(); + CHECK(al_fseek(f, 13, ALLEGRO_SEEK_SET), bool, true); + CHECK(al_ftell(f), int64_t, 13); + CHECK(al_fgetc(f), int, 0x02); + + /* Test: seek nowhere. */ + SEP(); + CHECK(al_fseek(f, 0, ALLEGRO_SEEK_CUR), bool, true); + CHECK(al_ftell(f), int64_t, 14); + CHECK(al_fgetc(f), int, 0xe0); + + /* Test: seek nowhere with pushback. */ + SEP(); + CHECK(al_fungetc(f, 0x55), bool, true); + CHECK(al_fseek(f, 0, ALLEGRO_SEEK_CUR), bool, true); + CHECK(al_ftell(f), int64_t, 14); + CHECK(al_fgetc(f), int, 0xe0); + + /* Test: seek relative backwards. */ + SEP(); + CHECK(al_fseek(f, -3, ALLEGRO_SEEK_CUR), bool, true); + CHECK(al_ftell(f), int64_t, 12); + CHECK(al_fgetc(f), int, 0x80); + + /* Test: seek backwards with pushback. */ + SEP(); + CHECK(al_ftell(f), int64_t, 13); + CHECK(al_fungetc(f, 0x66), bool, true); + CHECK(al_ftell(f), int64_t, 12); + CHECK(al_fseek(f, -2, ALLEGRO_SEEK_CUR), bool, true); + CHECK(al_ftell(f), int64_t, 10); + CHECK(al_fgetc(f), int, 0xc7); + + /* Test: seek relative to end. */ + SEP(); + CHECK(al_fseek(f, 0, ALLEGRO_SEEK_END), bool, true); + CHECK(al_feof(f), bool, false); + CHECK(al_ftell(f), int64_t, 0xab06); + + /* Test: read past EOF. */ + SEP(); + CHECK(al_fgetc(f), int, -1); + CHECK(al_feof(f), bool, true); + CHECK(al_ferror(f), int, 0); + + /* Test: seek clears EOF indicator. */ + SEP(); + CHECK(al_fseek(f, 0, ALLEGRO_SEEK_END), bool, true); + CHECK(al_feof(f), bool, false); + CHECK(al_ftell(f), int64_t, 0xab06); + + /* Test: seek backwards from end. */ + SEP(); + CHECK(al_fseek(f, -20, ALLEGRO_SEEK_END), bool, true); + CHECK(al_ftell(f), int64_t, 0xaaf2); + + /* Test: seek forwards from end. */ + SEP(); + CHECK(al_fseek(f, 20, ALLEGRO_SEEK_END), bool, true); + CHECK(al_ftell(f), int64_t, 0xab1a); + CHECK(al_fgetc(f), int, -1); + CHECK(al_feof(f), bool, true); + + /* Test: get file size if possible. */ + SEP(); + CHECK(sz = al_fsize(f), int64_t, sz); + if (sz != -1) + CHECK(sz, int64_t, 0xab06); + + /* Test: close. */ + SEP(); + CHECK(al_fclose(f), bool, true); +} + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + if (!al_init()) + return 1; + init_platform_specific(); + open_log_monospace(); + + read_test(); + + close_log(true); + + if (error) { + exit(EXIT_FAILURE); + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_file_slice.c b/allegro/examples/ex_file_slice.c new file mode 100644 index 00000000..cfa972fa --- /dev/null +++ b/allegro/examples/ex_file_slice.c @@ -0,0 +1,87 @@ +/* + * ex_file_slice - Use slices to pack many objects into a single file. + * + * This example packs two strings into a single file, and then uses a + * file slice to open them one at a time. While this usage is contrived, + * the same principle can be used to pack multiple images (for example) + * into a single file, and later read them back via Allegro's image loader. + * + */ +#include "allegro5/allegro.h" + +#include "common.c" + +#define BUFFER_SIZE 1024 + +static void pack_object(ALLEGRO_FILE *file, const void *object, size_t len) +{ + /* First write the length of the object, so we know how big to make + the slice when it is opened later. */ + al_fwrite32le(file, len); + al_fwrite(file, object, len); +} + +static ALLEGRO_FILE *get_next_chunk(ALLEGRO_FILE *file) +{ + /* Reads the length of the next chunk, and if not at end of file, returns a + slice that represents that portion of the file. */ + const uint32_t length = al_fread32le(file); + return !al_feof(file) ? al_fopen_slice(file, length, "rw") : NULL; +} + +int main(int argc, const char *argv[]) +{ + ALLEGRO_FILE *master, *slice; + ALLEGRO_PATH *tmp_path; + + const char *first_string = "Hello, World!"; + const char *second_string = "The quick brown fox jumps over the lazy dog."; + char buffer[BUFFER_SIZE]; + + (void) argc, (void) argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + master = al_make_temp_file("ex_file_slice_XXXX", &tmp_path); + if (!master) { + abort_example("Unable to create temporary file\n"); + } + + /* Pack both strings into the master file. */ + pack_object(master, first_string, strlen(first_string)); + pack_object(master, second_string, strlen(second_string)); + + /* Seek back to the beginning of the file, as if we had just opened it */ + al_fseek(master, 0, ALLEGRO_SEEK_SET); + + /* Loop through the main file, opening a slice for each object */ + while ((slice = get_next_chunk(master))) { + /* Note: While the slice is open, we must avoid using the master file! + If you were dealing with packed images, this is where you would pass 'slice' + to al_load_bitmap_f(). */ + + if (al_fsize(slice) < BUFFER_SIZE) { + /* We could have used al_fgets(), but just to show that the file slice + is constrained to the string object, we'll read the entire slice. */ + al_fread(slice, buffer, al_fsize(slice)); + buffer[al_fsize(slice)] = 0; + log_printf("Chunk of size %d: '%s'\n", (int) al_fsize(slice), buffer); + } + + /* The slice must be closed before the next slice is opened. Closing + the slice will advanced the master file to the end of the slice. */ + al_fclose(slice); + } + + al_fclose(master); + + al_remove_filename(al_path_cstr(tmp_path, '/')); + + close_log(true); + + return 0; +} diff --git a/allegro/examples/ex_filter.c b/allegro/examples/ex_filter.c new file mode 100644 index 00000000..7fc11df5 --- /dev/null +++ b/allegro/examples/ex_filter.c @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include + +#include "common.c" + +#define FPS 60 + +static struct Example { + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *bitmaps[2][9]; + ALLEGRO_COLOR bg, fg, info; + int bitmap; + int ticks; +} example; + +static int const filter_flags[6] = { + 0, + ALLEGRO_MIN_LINEAR, + ALLEGRO_MIPMAP, + ALLEGRO_MIN_LINEAR | ALLEGRO_MIPMAP, + 0, + ALLEGRO_MAG_LINEAR +}; + +static char const *filter_text[4] = { + "nearest", "linear", + "nearest mipmap", "linear mipmap" +}; + +static void update(void) +{ + example.ticks++; +} + +static void redraw(void) +{ + int w = al_get_display_width(example.display); + int h = al_get_display_height(example.display); + int i; + + al_clear_to_color(example.bg); + + for (i = 0; i < 6; i++) { + float x = (i / 2) * w / 3 + w / 6; + float y = (i % 2) * h / 2 + h / 4; + ALLEGRO_BITMAP *bmp = example.bitmaps[example.bitmap][i]; + float bw = al_get_bitmap_width(bmp); + float bh = al_get_bitmap_height(bmp); + float t = 1 - 2 * fabs((example.ticks % (FPS * 16)) / 16.0 / FPS - 0.5); + float scale; + float angle = example.ticks * ALLEGRO_PI * 2 / FPS / 8; + + if (i < 4) + scale = 1 - t * 0.9; + else + scale = 1 + t * 9; + + al_draw_textf(example.font, example.fg, x, y - 64 - 14, + ALLEGRO_ALIGN_CENTRE, "%s", filter_text[i % 4]); + + al_set_clipping_rectangle(x - 64, y - 64, 128, 128); + al_draw_scaled_rotated_bitmap(bmp, bw / 2, bh / 2, + x, y, scale, scale, angle, 0); + al_set_clipping_rectangle(0, 0, w, h); + } + al_draw_textf(example.font, example.info, w / 2, h - 14, + ALLEGRO_ALIGN_CENTRE, "press space to change"); +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + int w = 640, h = 480; + bool done = false; + bool need_redraw = true; + int i; + ALLEGRO_BITMAP *mysha; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + al_init_font_addon(); + + init_platform_specific(); + + example.display = al_create_display(w, h); + + if (!example.display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + if (!al_install_mouse()) { + abort_example("Error installing mouse.\n"); + } + + example.font = al_load_font("data/fixed_font.tga", 0, 0); + if (!example.font) { + abort_example("Error loading data/fixed_font.tga\n"); + } + + mysha = al_load_bitmap("data/mysha256x256.png"); + if (!mysha) { + abort_example("Error loading data/mysha256x256.png\n"); + } + + for (i = 0; i < 6; i++) { + ALLEGRO_LOCKED_REGION *lock; + int x, y; + /* Only power-of-two bitmaps can have mipmaps. */ + al_set_new_bitmap_flags(filter_flags[i]); + example.bitmaps[0][i] = al_create_bitmap(1024, 1024); + example.bitmaps[1][i] = al_clone_bitmap(mysha); + lock = al_lock_bitmap(example.bitmaps[0][i], + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); + for (y = 0; y < 1024; y++) { + unsigned char *row = (unsigned char *)lock->data + lock->pitch * y; + unsigned char *ptr = row; + for (x = 0; x < 1024; x++) { + int c = 0; + if (((x >> 2) & 1) ^ ((y >> 2) & 1)) c = 255; + *(ptr++) = c; + *(ptr++) = c; + *(ptr++) = c; + *(ptr++) = 255; + } + } + al_unlock_bitmap(example.bitmaps[0][i]); + + } + + example.bg = al_map_rgb_f(0, 0, 0); + example.fg = al_map_rgb_f(1, 1, 1); + example.info = al_map_rgb_f(0.5, 0.5, 1); + + timer = al_create_timer(1.0 / FPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_display_event_source(example.display)); + + al_start_timer(timer); + + while (!done) { + ALLEGRO_EVENT event; + + if (need_redraw && al_is_event_queue_empty(queue)) { + redraw(); + al_flip_display(); + need_redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) + example.bitmap = (example.bitmap + 1) % 2; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + update(); + need_redraw = true; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + example.bitmap = (example.bitmap + 1) % 2; + break; + } + } + + for (i = 0; i < 6; i++) { + al_destroy_bitmap(example.bitmaps[0][i]); + al_destroy_bitmap(example.bitmaps[1][i]); + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_font.c b/allegro/examples/ex_font.c new file mode 100644 index 00000000..184414d7 --- /dev/null +++ b/allegro/examples/ex_font.c @@ -0,0 +1,150 @@ +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" + +#include "common.c" + + +#define EURO "\xe2\x82\xac" + +static void wait_for_esc(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_BITMAP *screen_clone; + al_install_keyboard(); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + screen_clone = al_clone_bitmap(al_get_target_bitmap()); + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { + int x = event.display.x; + int y = event.display.y; + int w = event.display.width; + int h = event.display.height; + + al_draw_bitmap_region(screen_clone, x, y, w, h, + x, y, 0); + al_update_display_region(x, y, w, h); + } + } + al_destroy_bitmap(screen_clone); + al_destroy_event_queue(queue); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bitmap, *font_bitmap; + ALLEGRO_FONT *f1, *f2, *f3; + + int range, index, x, y; + + int ranges[] = { + 0x0020, 0x007F, /* ASCII */ + 0x00A1, 0x00FF, /* Latin 1 */ + 0x0100, 0x017F, /* Extended-A */ + 0x20AC, 0x20AC}; /* Euro */ + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, true, ALLEGRO_SUGGEST); + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(640, 480); + if (!display) { + abort_example("Failed to create display\n"); + } + bitmap = al_load_bitmap("data/mysha.pcx"); + if (!bitmap) { + abort_example("Failed to load mysha.pcx\n"); + } + + f1 = al_load_font("data/bmpfont.tga", 0, 0); + if (!f1) { + abort_example("Failed to load bmpfont.tga\n"); + } + + font_bitmap = al_load_bitmap("data/a4_font.tga"); + if (!font_bitmap) { + abort_example("Failed to load a4_font.tga\n"); + } + f2 = al_grab_font_from_bitmap(font_bitmap, 4, ranges); + + f3 = al_create_builtin_font(); + if (!f3) { + abort_example("Failed to create builtin font.\n"); + } + + /* Draw background */ + al_draw_scaled_bitmap(bitmap, 0, 0, 320, 240, 0, 0, 640, 480, 0); + + /* Draw red text */ + al_draw_textf(f1, al_map_rgb(255, 0, 0), 10, 10, 0, "red"); + + /* Draw green text */ + al_draw_textf(f1, al_map_rgb(0, 255, 0), 120, 10, 0, "green"); + + /* Draw a unicode symbol */ + al_draw_textf(f2, al_map_rgb(0, 0, 255), 60, 60, 0, "Mysha's 0.02" EURO); + + /* Draw a yellow text with the builtin font */ + al_draw_textf(f3, al_map_rgb(255, 255, 0), 20, 200, ALLEGRO_ALIGN_CENTER, + "a string from builtin font data"); + + /* Draw all individual glyphs the f2 font's range in rainbow colors. + */ + x = 10; + y = 300; + al_draw_textf(f3, al_map_rgb(0, 255, 255), x, y - 20, 0, "Draw glyphs: "); + for (range = 0; range < 4; range++) { + int start = ranges[2*range]; + int stop = ranges[2*range + 1]; + for (index = start; index < stop; index ++) { + /* Use al_get_glyph_advance for the stride. */ + int width = al_get_glyph_advance(f2, index, ALLEGRO_NO_KERNING); + int r = fabs(sin(ALLEGRO_PI * (index) * 36 / 360.0)) * 255.0; + int g = fabs(sin(ALLEGRO_PI * (index + 12) * 36 / 360.0)) * 255.0; + int b = fabs(sin(ALLEGRO_PI * (index + 24) * 36 / 360.0)) * 255.0; + al_draw_glyph(f2, al_map_rgb(r, g, b), x, y, index); + x += width; + if (x > (al_get_display_width(display) - 10)) { + x = 10; + y += al_get_font_line_height(f2); + } + } + } + + + + al_flip_display(); + + wait_for_esc(display); + + al_destroy_bitmap(bitmap); + al_destroy_bitmap(font_bitmap); + al_destroy_font(f1); + al_destroy_font(f2); + al_destroy_font(f3); + return 0; +} + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_font_justify.cpp b/allegro/examples/ex_font_justify.cpp new file mode 100644 index 00000000..95eb8f0f --- /dev/null +++ b/allegro/examples/ex_font_justify.cpp @@ -0,0 +1,145 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * Test text justification routines. + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_ttf.h" +#include +#include "nihgui.hpp" + +#include "common.c" + +ALLEGRO_FONT *font; +ALLEGRO_FONT *font_gui; + +class Prog { +private: + Dialog d; + Label text_label; + Label width_label; + Label diff_label; + TextEntry text_entry; + HSlider width_slider; + HSlider diff_slider; + +public: + Prog(const Theme & theme, ALLEGRO_DISPLAY *display); + void run(); + void draw_text(); +}; + +Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : + d(Dialog(theme, display, 10, 20)), + text_label(Label("Text")), + width_label(Label("Width")), + diff_label(Label("Diff")), + text_entry(TextEntry("Lorem ipsum dolor sit amet")), + width_slider(HSlider(400, al_get_display_width(display))), + diff_slider(HSlider(100, al_get_display_width(display))) +{ + d.add(text_label, 0, 10, 1, 1); + d.add(text_entry, 1, 10, 8, 1); + + d.add(width_label, 0, 12, 1, 1); + d.add(width_slider, 1, 12, 8, 1); + + d.add(diff_label, 0, 14, 1, 1); + d.add(diff_slider, 1, 14, 8, 1); +} + +void Prog::run() +{ + d.prepare(); + + while (!d.is_quit_requested()) { + if (d.is_draw_requested()) { + al_clear_to_color(al_map_rgb(128, 128, 128)); + draw_text(); + d.draw(); + al_flip_display(); + } + + d.run_step(true); + } +} + +void Prog::draw_text() +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + const int cx = al_get_bitmap_width(target) / 2; + const int x1 = cx - width_slider.get_cur_value() / 2; + const int x2 = cx + width_slider.get_cur_value() / 2; + const int diff = diff_slider.get_cur_value(); + const int th = al_get_font_line_height(font); + + al_draw_justified_text(font, al_map_rgb_f(1, 1, 1), x1, x2, 50, diff, + ALLEGRO_ALIGN_INTEGER, text_entry.get_text()); + + al_draw_rectangle(x1, 50, x2, 50 + th, al_map_rgb(0, 0, 255), 0); + + al_draw_line(cx - diff / 2, 53 + th, cx + diff / 2, 53 + th, + al_map_rgb(0, 255, 0), 0); +} + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + + al_init_image_addon(); + al_init_font_addon(); + al_init_ttf_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(640, 480); + if (!display) { + abort_example("Unable to create display\n"); + } + + /* Test TTF fonts or bitmap fonts. */ +#if 1 + font = al_load_font("data/DejaVuSans.ttf", 24, 0); + if (!font) { + abort_example("Failed to load data/DejaVuSans.ttf\n"); + } +#else + font = al_load_font("data/font.tga", 0, 0); + if (!font) { + abort_example("Failed to load data/font.tga\n"); + } +#endif + + font_gui = al_load_font("data/DejaVuSans.ttf", 14, 0); + if (!font_gui) { + abort_example("Failed to load data/DejaVuSans.ttf\n"); + } + + /* Don't remove these braces. */ + { + Theme theme(font_gui); + Prog prog(theme, display); + prog.run(); + } + + al_destroy_font(font); + al_destroy_font(font_gui); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_font_multiline.cpp b/allegro/examples/ex_font_multiline.cpp new file mode 100644 index 00000000..e372d66d --- /dev/null +++ b/allegro/examples/ex_font_multiline.cpp @@ -0,0 +1,275 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * Test multi line text routines. + */ + +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_ttf.h" +#include "allegro5/allegro_color.h" +#include "allegro5/allegro_primitives.h" +#include "nihgui.hpp" + +#include "common.c" + +#define TEST_TEXT "This is utf-8 €€€€€ multi line text output with a\nhard break,\n\ntwice even!" + +/* This is a custom mult line output function that demonstrates + * al_do_multiline_text. See below for the implementation. */ +static void draw_custom_multiline(ALLEGRO_FONT * font, int x, int y, + int max_width, int line_height, int tick, const char * text); + +ALLEGRO_TIMER *timer; +ALLEGRO_FONT *font; +ALLEGRO_FONT *font_ttf; +ALLEGRO_FONT *font_bmp; +ALLEGRO_FONT *font_gui; +ALLEGRO_FONT *font_bin; + +class Prog : public EventHandler { +private: + Dialog d; + Label text_label; + Label width_label; + Label height_label; + Label align_label; + Label font_label; + + TextEntry text_entry; + HSlider width_slider; + VSlider height_slider; + List text_align; + List text_font; + int tick; + +public: + Prog(const Theme & theme, ALLEGRO_DISPLAY *display); + virtual ~Prog() {} + void run(); + void draw_text(); + void handle_event(const ALLEGRO_EVENT & event); +}; + +Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : + d(Dialog(theme, display, 14, 20)), + text_label(Label("Text")), + width_label(Label("Width")), + height_label(Label("Line height")), + align_label(Label("Align")), + font_label(Label("Font")), + text_entry(TextEntry(TEST_TEXT)), + width_slider(HSlider(200, al_get_display_width(display))), + height_slider(VSlider(0, 50)), + text_align(List(0)), + text_font(List(0)) +{ + text_align.append_item("Left"); + text_align.append_item("Center"); + text_align.append_item("Right"); + + text_font.append_item("Truetype"); + text_font.append_item("Bitmap"); + text_font.append_item("Builtin"); + + d.add(text_label, 0, 14, 1, 1); + d.add(text_entry, 1, 14, 12, 1); + + d.add(width_label, 0, 15, 1, 1); + d.add(width_slider, 1, 15, 12, 1); + + + d.add(align_label, 0, 17, 2, 1); + d.add(text_align , 2, 17, 2, 3); + + d.add(font_label, 4, 17, 2, 1); + d.add(text_font , 6, 17, 2, 3); + + d.add(height_label, 8, 17, 2, 1); + d.add(height_slider, 10, 17, 2, 3); +} + +void Prog::run() +{ + d.prepare(); + + d.register_event_source(al_get_timer_event_source(timer)); + d.set_event_handler(this); + + while (!d.is_quit_requested()) { + if (d.is_draw_requested()) { + al_clear_to_color(al_map_rgb(128, 128, 128)); + draw_text(); + d.draw(); + al_flip_display(); + } + + d.run_step(true); + } +} + +void Prog::handle_event(const ALLEGRO_EVENT & event) +{ + if (event.type == ALLEGRO_EVENT_TIMER) { + tick = (int)event.timer.count; + d.request_draw(); + } +} + +void Prog::draw_text() +{ + int x = 10, y = 10; + int sx = 10, sy = 10; + int w = width_slider.get_cur_value(); + int h = height_slider.get_cur_value(); + int flags = 0; + const char * text = text_entry.get_text(); + + if (text_font.get_selected_item_text() == "Truetype") { + font = font_ttf; + } else if (text_font.get_selected_item_text() == "Bitmap") { + font = font_bmp; + } else if (text_font.get_selected_item_text() == "Builtin") { + font = font_bin; + } + + if (text_align.get_selected_item_text() == "Left") { + flags = ALLEGRO_ALIGN_LEFT | ALLEGRO_ALIGN_INTEGER; + } else if (text_align.get_selected_item_text() == "Center") { + flags = ALLEGRO_ALIGN_CENTER | ALLEGRO_ALIGN_INTEGER; + x = 10 + w / 2; + } else if (text_align.get_selected_item_text() == "Right") { + flags = ALLEGRO_ALIGN_RIGHT | ALLEGRO_ALIGN_INTEGER; + x = 10 + w; + } + + + /* Draw a red rectangle on the top with the requested width, + * a blue rectangle around the real bounds of the text, + * a green line for the X axis location of drawing the text + * and the line height, and finally the text itself. + */ + + al_draw_rectangle(sx, sy-2 + 30, sx + w, sy - 1 + 30, al_map_rgb(255, 0, 0), 0); + al_draw_line(x, y + 30, x, y + h + 30, al_map_rgb(0, 255, 0), 0); + al_draw_multiline_text(font, al_map_rgb_f(1, 1, 1), x, y + 30, w, h, flags, text); + + /* also do some custom bultiline drawing */ + al_draw_text(font, al_map_rgb_f(1, 1, 1), w + 10, y, 0, "Custom multiline text:" ); + draw_custom_multiline(font, w + 10 , y + 30, w, h, tick, text); +} + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + + al_init_image_addon(); + al_init_font_addon(); + al_init_ttf_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(640, 480); + if (!display) { + abort_example("Unable to create display\n"); + } + + /* Test TTF fonts and bitmap fonts. */ + font_ttf = al_load_font("data/DejaVuSans.ttf", 24, 0); + if (!font_ttf) { + abort_example("Failed to load data/DejaVuSans.ttf\n"); + } + + font_bmp = al_load_font("data/font.tga", 0, 0); + if (!font_bmp) { + abort_example("Failed to load data/font.tga\n"); + } + + font_bin = al_create_builtin_font(); + + font = font_ttf; + + font_gui = al_load_font("data/DejaVuSans.ttf", 14, 0); + if (!font_gui) { + abort_example("Failed to load data/DejaVuSans.ttf\n"); + } + + timer = al_create_timer(1.0 / 60); + al_start_timer(timer); + + /* Don't remove these braces. */ + { + Theme theme(font_gui); + Prog prog(theme, display); + prog.run(); + } + + al_destroy_font(font_bmp); + al_destroy_font(font_ttf); + al_destroy_font(font_bin); + al_destroy_font(font_gui); + al_destroy_timer(timer); + + return 0; +} + + +/* Helper struct for draw_custom_multiline. */ +typedef struct DRAW_CUSTOM_LINE_EXTRA { + const ALLEGRO_FONT *font; + float x; + float y; + int tick; + float line_height; + int flags; +} DRAW_CUSTOM_LINE_EXTRA; + + +/* This function is the helper callback that implements the actual drawing + * for draw_custom_multiline. + */ +static bool draw_custom_multiline_cb(int line_num, const char *line, int size, + void *extra) { + DRAW_CUSTOM_LINE_EXTRA *s = (DRAW_CUSTOM_LINE_EXTRA *) extra; + float x, y; + ALLEGRO_USTR_INFO info; + ALLEGRO_COLOR c = + al_color_hsv(fmod(360.0 * (float)line_num / 5.0 + s->tick, 360.0), + 1.0, 1.0); + x = s->x + 10 + sin(line_num + s->tick * 0.05) * 10; + y = s->y + (s->line_height * line_num); + al_draw_ustr(s->font, c, x, y, 0, al_ref_buffer(&info, line, size)); + return (line_num < 5); +} + +/* This is a custom mult line output function that demonstrates + * al_do_multiline_text. */ +static void draw_custom_multiline(ALLEGRO_FONT * font, int x, int y, + int max_width, int line_height, int tick, const char * text) { + DRAW_CUSTOM_LINE_EXTRA extra; + + extra.font = font; + extra.x = x; + extra.y = y; + extra.line_height = line_height + al_get_font_line_height(font); + extra.tick = tick; + + al_do_multiline_text(font, max_width, text, + draw_custom_multiline_cb, (void *)&extra); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_fs_resize.c b/allegro/examples/ex_fs_resize.c new file mode 100644 index 00000000..5d101bbd --- /dev/null +++ b/allegro/examples/ex_fs_resize.c @@ -0,0 +1,153 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include +#include + +#include "common.c" + +#define NUM_RESOLUTIONS 4 + +static struct { + int w, h; +} res[NUM_RESOLUTIONS] = { + { 640, 480 }, + { 800, 600 }, + { 1024, 768 }, + { 1280, 1024 } +}; + +static int cur_res = 0; + +static void redraw(ALLEGRO_BITMAP *picture) +{ + ALLEGRO_COLOR color; + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + int w = al_get_bitmap_width(target); + int h = al_get_bitmap_height(target); + + color = al_map_rgb( + 128 + rand() % 128, + 128 + rand() % 128, + 128 + rand() % 128); + al_clear_to_color(color); + + color = al_map_rgb(255, 0, 0); + al_draw_line(0, 0, w, h, color, 0); + al_draw_line(0, h, w, 0, color, 0); + + al_draw_bitmap(picture, 0, 0, 0); + al_flip_display(); +} + +static void main_loop(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *picture) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + bool can_draw; + int new_res; + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + can_draw = true; + + while (1) { + if (al_is_event_queue_empty(queue) && can_draw) { + redraw(picture); + } + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_DISPLAY_LOST) { + log_printf("Display lost\n"); + can_draw = false; + continue; + } + if (event.type == ALLEGRO_EVENT_DISPLAY_FOUND) { + log_printf("Display found\n"); + can_draw = true; + continue; + } + if (event.type != ALLEGRO_EVENT_KEY_CHAR) { + continue; + } + + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + + new_res = cur_res; + + if (event.keyboard.unichar == '+' || + event.keyboard.unichar == ' ' || + event.keyboard.keycode == ALLEGRO_KEY_ENTER) { + new_res++; + if (new_res >= NUM_RESOLUTIONS) + new_res = 0; + } + else if (event.keyboard.unichar == '-') { + new_res--; + if (new_res < 0) + new_res = NUM_RESOLUTIONS - 1; + } + + if (new_res != cur_res) { + cur_res = new_res; + log_printf("Switching to %dx%d... ", res[cur_res].w, res[cur_res].h); + if (al_resize_display(display, res[cur_res].w, res[cur_res].h)) { + log_printf("Succeeded.\n"); + } + else { + log_printf("Failed. current resolution: %dx%d\n", + al_get_display_width(display), al_get_display_height(display)); + } + } + } + + al_destroy_event_queue(queue); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *picture; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_primitives_addon(); + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + open_log_monospace(); + + if (argc == 2) { + al_set_new_display_adapter(atoi(argv[1])); + } + + al_set_new_display_flags(ALLEGRO_FULLSCREEN | + ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(res[cur_res].w, res[cur_res].h); + if (!display) { + abort_example("Error creating display\n"); + } + + picture = al_load_bitmap("data/mysha.pcx"); + if (!picture) { + abort_example("mysha.pcx not found\n"); + } + + main_loop(display, picture); + + al_destroy_bitmap(picture); + + /* Destroying the fullscreen display restores the original screen + * resolution. Shutting down Allegro would automatically destroy the + * display, too. + */ + al_destroy_display(display); + + return 0; +} + diff --git a/allegro/examples/ex_fs_window.c b/allegro/examples/ex_fs_window.c new file mode 100644 index 00000000..bda4550d --- /dev/null +++ b/allegro/examples/ex_fs_window.c @@ -0,0 +1,124 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include +#include + +#include "common.c" + +static ALLEGRO_DISPLAY *display; +static ALLEGRO_BITMAP *picture; +static ALLEGRO_EVENT_QUEUE *queue; +static ALLEGRO_FONT *font; +static bool big; + +static void redraw(void) +{ + ALLEGRO_COLOR color; + int w = al_get_display_width(display); + int h = al_get_display_height(display); + int pw = al_get_bitmap_width(picture); + int ph = al_get_bitmap_height(picture); + int th = al_get_font_line_height(font); + float cx = (w - pw) * 0.5; + float cy = (h - ph) * 0.5; + ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1); + + color = al_map_rgb_f(0.8, 0.7, 0.9); + al_clear_to_color(color); + + color = al_map_rgb(255, 0, 0); + al_draw_line(0, 0, w, h, color, 0); + al_draw_line(0, h, w, 0, color, 0); + + al_draw_bitmap(picture, cx, cy, 0); + + al_draw_textf(font, white, w / 2, cy + ph, ALLEGRO_ALIGN_CENTRE, + "Press Space to toggle fullscreen"); + al_draw_textf(font, white, w / 2, cy + ph + th, ALLEGRO_ALIGN_CENTRE, + "Press Enter to toggle window size"); + al_draw_textf(font, white, w / 2, cy + ph + th * 2, ALLEGRO_ALIGN_CENTRE, + "Window: %dx%d (%s)", + al_get_display_width(display), al_get_display_height(display), + (al_get_display_flags(display) & ALLEGRO_FULLSCREEN_WINDOW) ? + "fullscreen" : "not fullscreen"); + + al_flip_display(); +} + +static void run(void) +{ + ALLEGRO_EVENT event; + bool quit = false; + while (!quit) { + while (al_get_next_event(queue, &event)) { + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + quit = true; + else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + quit = true; + else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + bool opp = !(al_get_display_flags(display) & ALLEGRO_FULLSCREEN_WINDOW); + al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, opp); + redraw(); + } + else if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { + big = !big; + if (big) + al_resize_display(display, 800, 600); + else + al_resize_display(display, 640, 480); + redraw(); + } + } + } + /* FIXME: Lazy timing */ + al_rest(0.02); + redraw(); + } +} + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_keyboard(); + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + picture = al_load_bitmap("data/mysha.pcx"); + if (!picture) { + abort_example("mysha.pcx not found\n"); + } + + font = al_load_font("data/fixed_font.tga", 0, 0); + if (!font) { + abort_example("data/fixed_font.tga not found.\n"); + } + + redraw(); + run(); + + al_destroy_display(display); + + al_destroy_event_queue(queue); + + return 0; +} + diff --git a/allegro/examples/ex_get_path.c b/allegro/examples/ex_get_path.c new file mode 100644 index 00000000..2951fd76 --- /dev/null +++ b/allegro/examples/ex_get_path.c @@ -0,0 +1,62 @@ +#include +#include "allegro5/allegro.h" + +#include "common.c" + +static void show_path(int id, const char *label) +{ + ALLEGRO_PATH *path; + const char *path_str; + + path = al_get_standard_path(id); + path_str = (path) ? al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP) : ""; + log_printf("%s: %s\n", label, path_str); + al_destroy_path(path); +} + +int main(int argc, char **argv) +{ + int pass; + + (void)argc; + (void)argv; + + /* defaults to blank */ + al_set_org_name("liballeg.org"); + + /* defaults to the exename, set it here to remove the .exe on windows */ + al_set_app_name("ex_get_path"); + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + open_log(); + + for (pass = 1; pass <= 3; pass++) { + if (pass == 1) { + log_printf("With default exe name:\n"); + } + else if (pass == 2) { + log_printf("\nOverriding exe name to blahblah\n"); + al_set_exe_name("blahblah"); + } + else if (pass == 3) { + log_printf("\nOverriding exe name to /tmp/blahblah.exe:\n"); + al_set_exe_name("/tmp/blahblah.exe"); + } + + show_path(ALLEGRO_RESOURCES_PATH, "RESOURCES_PATH"); + show_path(ALLEGRO_TEMP_PATH, "TEMP_PATH"); + show_path(ALLEGRO_USER_DATA_PATH, "USER_DATA_PATH"); + show_path(ALLEGRO_USER_SETTINGS_PATH, "USER_SETTINGS_PATH"); + show_path(ALLEGRO_USER_HOME_PATH, "USER_HOME_PATH"); + show_path(ALLEGRO_USER_DOCUMENTS_PATH, "USER_DOCUMENTS_PATH"); + show_path(ALLEGRO_EXENAME_PATH, "EXENAME_PATH"); + } + + close_log(true); + return 0; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_gldepth.c b/allegro/examples/ex_gldepth.c new file mode 100644 index 00000000..2f90c014 --- /dev/null +++ b/allegro/examples/ex_gldepth.c @@ -0,0 +1,246 @@ +/* An example program showing how to set and use a depth buffer with an OpenGL + * display. Use arrow keys to rotate, PgUp/PgDown to move closer/farther away. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/allegro_font.h" + +#include "common.c" + +struct camera { + double xangle, yangle, zangle; + double dist; +}; + +struct camera camera = { + 0.0, 0.0, 0.0, + 20.0 +}; + +double angle_speed = 5.0; +double dist_speed = 1.0; + +GLuint tex; +ALLEGRO_BITMAP *bmp; +bool key[ALLEGRO_KEY_MAX]; + +static void set_camera_position(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 40.0); + glTranslatef(0, 0, -camera.dist); + glRotatef(camera.xangle, 1, 0, 0); + glRotatef(camera.yangle, 0, 1, 0); + glRotatef(camera.zangle, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); +} + + + +static void keyboard(void) +{ + if(key[ALLEGRO_KEY_LEFT]) camera.yangle += angle_speed; + if(key[ALLEGRO_KEY_RIGHT]) camera.yangle -= angle_speed; + + if(key[ALLEGRO_KEY_UP]) camera.xangle += angle_speed; + if(key[ALLEGRO_KEY_DOWN]) camera.xangle -= angle_speed; + + if(key[ALLEGRO_KEY_PGUP]) camera.dist -= dist_speed; + if(key[ALLEGRO_KEY_PGDN]) camera.dist += dist_speed; +} + + + +static void draw(void) +{ + // Clear the RGB buffer and the depth buffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Set the modelview matrix to be the identity matrix + glLoadIdentity(); + // Translate and rotate the object + glTranslatef(-2.5, 0.0, 0.0); + glRotatef(-30, 1.0, 0.0, 0.0); + glRotatef(30, 0.0, 1.0, 0.0); + glRotatef(30, 0.0, 0.0, 1.0); + + glColor3f(1.0, 0.0, 1.0); + + // Draw the sides of the three-sided pyramid + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex); + glBegin(GL_TRIANGLE_FAN); + glTexCoord2f(0, 0); glVertex3d(0, 4, 0); + glTexCoord2f(1, 0); glVertex3d(0, -4, -4); + glTexCoord2f(1, 1); glVertex3d(-4, -4, 4); + glTexCoord2f(0, 1); glVertex3d(4, -4, 4); + glTexCoord2f(1, 0); glVertex3d(0, -4, -4); + glEnd(); + + glColor3f(0.0, 1.0, 1.0); + + // Draw the base of the pyramid + glBegin(GL_TRIANGLES); + glTexCoord2f(1, 0); glVertex3d(0, -4, -4); + glTexCoord2f(0, 1); glVertex3d(4, -4, 4); + glTexCoord2f(1, 1); glVertex3d(-4, -4, 4); + glEnd(); + + + glLoadIdentity(); + glTranslatef(2.5, 0.0, 0.0); + glRotatef(45, 1.0, 0.0, 0.0); + glRotatef(45, 0.0, 1.0, 0.0); + glRotatef(45, 0.0, 0.0, 1.0); + + glColor3f(0.0, 1.0, 0.0); + + glDisable(GL_TEXTURE_2D); + // Draw the sides of the cube + glBegin(GL_QUAD_STRIP); + glVertex3d(3, 3, -3); + glVertex3d(3, -3, -3); + glVertex3d(-3, 3, -3); + glVertex3d(-3, -3, -3); + glVertex3d(-3, 3, 3); + glVertex3d(-3, -3, 3); + glVertex3d(3, 3, 3); + glVertex3d(3, -3, 3); + glVertex3d(3, 3, -3); + glVertex3d(3, -3, -3); + glEnd(); + + glColor3f(0.0, 0.0, 1.0); + + // Draw the top of the cube + glBegin(GL_QUADS); + glVertex3d(-3, -3, -3); + glVertex3d(3, -3, -3); + glVertex3d(3, -3, 3); + glVertex3d(-3, -3, 3); + glEnd(); + + /* Bottom is texture-mapped */ + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3d(-3, 3, -3); + glTexCoord2f(1, 0); glVertex3d(-3, 3, 3); + glTexCoord2f(1, 1); glVertex3d(3, 3, 3); + glTexCoord2f(0, 1); glVertex3d(3, 3, -3); + glEnd(); +} + + + +static void setup_textures(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_BITMAP *tmp_bmp; + ALLEGRO_FONT *font; + int w, h, depth; + + font = al_load_font("data/fixed_font.tga", 0, 0); + if(!font) { + abort_example("Error loading `data/fixed_font.tga'\n"); + } + + tmp_bmp = al_load_bitmap("data/mysha.pcx"); + if(!tmp_bmp) { + abort_example("Error loading `data/mysha.pcx'\n"); + } + w = 128; + h = 128; + bmp = al_create_bitmap(w, h); + al_set_target_bitmap(bmp); + al_draw_scaled_bitmap(tmp_bmp, + 0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), + 0, 0, w, h, 0); + + depth = al_get_display_option(display, ALLEGRO_DEPTH_SIZE); + if (!depth) + al_draw_textf(font, al_map_rgb(255, 0, 0), 0, 5, 0, "No Z-buffer!"); + else + al_draw_textf(font, al_map_rgb(255, 0, 0), 0, 5, 0, "Z-buffer: %i bits", depth); + al_set_target_backbuffer(display); + al_destroy_bitmap(tmp_bmp); + al_destroy_font(font); + + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + tex = al_get_opengl_texture(bmp); +} + + + +int main(void) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT event; + + if(!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_image_addon(); + al_init_font_addon(); + al_install_keyboard(); + + al_set_new_display_flags(ALLEGRO_OPENGL); + al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); + display = al_create_display(640, 480); + if(!display) { + abort_example("Could not create display.\n"); + } + + timer = al_create_timer(1. / 60.); + + queue = al_create_event_queue(); + al_register_event_source(queue,al_get_keyboard_event_source()); + al_register_event_source(queue,al_get_display_event_source(display)); + al_register_event_source(queue,al_get_timer_event_source(timer)); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + setup_textures(display); + al_start_timer(timer); + + while(true) { + al_wait_for_event(queue, &event); + switch(event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + goto done; + + case ALLEGRO_EVENT_KEY_DOWN: + if(event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + goto done; + key[event.keyboard.keycode] = true; + break; + + case ALLEGRO_EVENT_KEY_UP: + key[event.keyboard.keycode] = false; + break; + + case ALLEGRO_EVENT_TIMER: + keyboard(); + if(al_is_event_queue_empty(queue)) { + set_camera_position(); + draw(); + al_flip_display(); + } + break; + } + } + +done: + al_destroy_bitmap(bmp); + + return 0; +} + diff --git a/allegro/examples/ex_glext.c b/allegro/examples/ex_glext.c new file mode 100644 index 00000000..f1f11177 --- /dev/null +++ b/allegro/examples/ex_glext.c @@ -0,0 +1,335 @@ +/* This examples demonstrates how to use the extension mechanism. + * Taken from AllegroGL. + */ + +#define ALLEGRO_UNSTABLE + +#include +#include +#include +#include +#include + +#include "common.c" + +#ifdef ALLEGRO_MACOSX +#include +#else +#include +#endif + +#define WINDOW_W 640 +#define WINDOW_H 480 + +#define MESH_SIZE 64 + +GLfloat mesh[MESH_SIZE][MESH_SIZE][3]; +GLfloat wave_movement = 0.0f; + + +/* Define our vertex program. + * It basically does: + * pos = vertex.position; + * pos.y = (sin(wave.x + pos.x / 5) + sin(wave.x + pos.z / 4)) * 2.5; + * result.position = modelview * projection * pos; + */ + +/* Plain ARBvp doesn't have a SIN opcode, so we provide one, built on a taylor + * expansion, with some fugding. + * + * First, we convert the operand to the [-pi..+pi] period by: + * - Dividing by 2pi, adding 1/2 + * - Taking the fraction of the result + * - Multiplying by 2pi, then subtracting pi. + * x' = frac((x / 2pi) + 0.5) * 2pi - pi + * + * Then, we compute the sine using a 7th order Taylor series centered at 0: + * x' = x - x^3/3! + x^5/5! - x^7/7! + * + * Note that we begin by multiplying x by 0.98 as a fugding factor to + * compensate for the fact that our Taylor series is just an approximation. + * The error is then reduced to < 0.5% from the ideal sine function. + */ +#define SIN(d, s, t) \ + /* Convert to [-pi..+pi] period */ \ + "MAD "d", "s", one_over_pi, 0.5;\n" \ + "FRC "d","d";\n" \ + "MAD "d","d", two_pi, -pi;\n" \ + "MUL "d","d", 0.98;\n" /* Scale input to compensate for prec error */\ + /* Compute SIN(d), using a Taylor series */ \ + "MUL "t".x, "d", "d";\n" /* x^2 */ \ + "MUL "t".y, "t".x, "d";\n" /* x^3 */ \ + "MUL "t".z, "t".y, "t".x;\n" /* x^5 */ \ + "MUL "t".w, "t".z, "t".x;\n" /* x^7 */ \ + "MAD "d", "t".y,-inv_3_fact, "d";\n" /* x - x^3/3! */ \ + "MAD "d", "t".z, inv_5_fact, "d";\n" /* x - x^3/3! + x^5/5! */ \ + "MAD "d", "t".w,-inv_7_fact, "d";\n" /* x - x^3/3! + x^5/5! - x^7/7!*/ + + +/* This is the actual vertex program. + * It computes sin(wave.x + pos.x / 5) and sin(wave.x + pos.z), adds them up, + * scales the result by 2.5 and stores that as the vertex's y component. + * + * Then, it does the modelview-projection transform on the vertex. + * + * XXX Broken ATI drivers need a \n after each "line" + */ +const char *program = + "!!ARBvp1.0\n" + "ATTRIB pos = vertex.position;\n" + "ATTRIB wave = vertex.attrib[1];\n" + "PARAM modelview[4] = { state.matrix.mvp };\n" + "PARAM one_over_pi = 0.1591549;\n" + "PARAM pi = 3.1415926;\n" + "PARAM two_pi = 6.2831853;\n" + "PARAM inv_3_fact = 0.1666666;\n" + "PARAM inv_5_fact = 0.00833333333;\n" + "PARAM inv_7_fact = 0.00019841269841269;\n" + "TEMP temp, temp2;\n" + + /* temp.y = sin(wave.x + pos.x / 5) */ + "MAD temp.y, pos.x, 0.2, wave.x;\n" + SIN("temp.y", "temp.y", "temp2") + + /* temp.y += sin(wave.x + pos.z / 4) */ + "MAD temp.x, pos.z, 0.25, wave.x;\n" + SIN("temp.x", "temp.x", "temp2") + "ADD temp.y, temp.x, temp.y;\n" + + /* pos.y = temp.y * 2.5 */ + "MOV temp2, pos;\n" + "MUL temp2.y, temp.y, 2.5;\n" + + /* Transform the position by the modelview matrix */ + "DP4 result.position.w, temp2, modelview[3];\n" + "DP4 result.position.x, temp2, modelview[0];\n" + "DP4 result.position.y, temp2, modelview[1];\n" + "DP4 result.position.z, temp2, modelview[2];\n" + + "MOV result.color, vertex.color;\n" + "END"; + + +/* NVIDIA drivers do a better job; let's use a simpler program if we can. + */ +const char *program_nv = + "!!ARBvp1.0" + "OPTION NV_vertex_program2;" + "ATTRIB wave = vertex.attrib[1];" + "PARAM modelview[4] = { state.matrix.mvp };" + "TEMP temp;" + "TEMP pos;" + + "MOV pos, vertex.position;" + + /* temp.x = sin(wave.x + pos.x / 5) */ + /* temp.z = sin(wave.x + pos.z / 4) */ + "MAD temp.xz, pos, {0.2, 1.0, 0.25, 1.0}, wave.x;" + "SIN temp.x, temp.x;" + "SIN temp.z, temp.z;" + + /* temp.y = temp.x + temp.z */ + "ADD temp.y, temp.x, temp.z;" + + /* pos.y = temp.y * 2.5 */ + "MUL pos.y, temp.y, 2.5;" + + /* Transform the position by the modelview matrix */ + "DP4 result.position.w, pos, modelview[3];" + "DP4 result.position.x, pos, modelview[0];" + "DP4 result.position.y, pos, modelview[1];" + "DP4 result.position.z, pos, modelview[2];" + + "MOV result.color, vertex.color;" + "END"; + + +static void create_mesh(void) +{ + int x, z; + + /* Create our mesh */ + for (x = 0; x < MESH_SIZE; x++) { + for (z = 0; z < MESH_SIZE; z++) { + mesh[x][z][0] = (float) (MESH_SIZE / 2) - x; + mesh[x][z][1] = 0.0f; + mesh[x][z][2] = (float) (MESH_SIZE / 2) - z; + } + } +} + + + +static void draw_mesh(void) +{ + int x, z; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glColor4f(0.5f, 1.0f, 0.5f, 1.0f); + + for (x = 0; x < MESH_SIZE - 1; x++) { + + glBegin(GL_TRIANGLE_STRIP); + + for (z = 0; z < MESH_SIZE - 1; z++) { + glVertexAttrib1fARB(1, wave_movement); + glVertex3fv(&mesh[x][z][0]); + glVertex3fv(&mesh[x+1][z][0]); + + wave_movement += 0.00001f; + + if (wave_movement > 2 * ALLEGRO_PI) { + wave_movement = 0.0f; + } + } + glEnd(); + } + + glFlush(); +} + + + +int main(int argc, const char *argv[]) +{ + GLuint pid; + ALLEGRO_DISPLAY *d; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + ALLEGRO_TIMER *timer; + int frames = 0; + double start; + bool limited = true; + + if (argc > 1 && 0 == strcmp(argv[1], "-nolimit")) { + limited = false; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_set_new_display_flags(ALLEGRO_OPENGL); + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); + al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); + d = al_create_display(WINDOW_W, WINDOW_H); + if (!d) { + abort_example("Unable to open a OpenGL display.\n"); + } + + if (al_get_display_option(d, ALLEGRO_SAMPLE_BUFFERS)) { + log_printf("With multisampling, level %i\n", al_get_display_option(d, ALLEGRO_SAMPLES)); + } + else { + log_printf("Without multisampling.\n"); + } + + al_install_keyboard(); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(d)); + + if (limited) { + timer = al_create_timer(1/60.0); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + } + else { + timer = NULL; + } + + if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multisample) { + glEnable(GL_MULTISAMPLE_ARB); + } + + if (!al_get_opengl_extension_list()->ALLEGRO_GL_ARB_vertex_program) { + abort_example("This example requires a video card that supports " + " the ARB_vertex_program extension.\n"); + } + + glEnable(GL_DEPTH_TEST); + glShadeModel(GL_SMOOTH); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glDisable(GL_CULL_FACE); + + /* Setup projection and modelview matrices */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, WINDOW_W/(float)WINDOW_H, 0.1, 100.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* Position the camera to look at our mesh from a distance */ + gluLookAt(0.0f, 20.0f, -45.0f, 0.0f, 0.0f, 0.0f, 0, 1, 0); + + create_mesh(); + + /* Define the vertex program */ + glEnable(GL_VERTEX_PROGRAM_ARB); + glGenProgramsARB(1, &pid); + glBindProgramARB(GL_VERTEX_PROGRAM_ARB, pid); + glGetError(); + + if (al_get_opengl_extension_list()->ALLEGRO_GL_NV_vertex_program2_option) { + glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(program_nv), program_nv); + } + else { + glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(program), program); + } + + /* Check for errors */ + if (glGetError()) { + const char *pgm = al_get_opengl_extension_list()->ALLEGRO_GL_NV_vertex_program2_option + ? program_nv : program; + GLint error_pos; + const GLubyte *error_str = glGetString(GL_PROGRAM_ERROR_STRING_ARB); + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos); + + abort_example("Error compiling the vertex program:\n%s\n\nat " + "character: %i\n%s\n", error_str, (int)error_pos, + pgm + error_pos); + } + + + start = al_get_time(); + while (1) { + if (limited) { + al_wait_for_event(queue, NULL); + } + + if (!al_is_event_queue_empty(queue)) { + while (al_get_next_event(queue, &event)) { + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + goto done; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + goto done; + break; + } + } + } + + draw_mesh(); + al_flip_display(); + frames++; + } + +done: + log_printf("%.1f FPS\n", frames / (al_get_time() - start)); + glDeleteProgramsARB(1, &pid); + al_destroy_event_queue(queue); + al_destroy_display(d); + close_log(true); + + return 0; +} diff --git a/allegro/examples/ex_haiku.c b/allegro/examples/ex_haiku.c new file mode 100644 index 00000000..7aae9eb7 --- /dev/null +++ b/allegro/examples/ex_haiku.c @@ -0,0 +1,988 @@ +/* + * Haiku - A Musical Instrument, by Mark Oates. + * + * Allegro example version by Peter Wang. + * + * It demonstrates use of the audio functions, and other things besides. + */ + +/* This version leaves out some things from Mark's original version: + * the nice title sequence, text labels and mouse cursors. + */ + +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include + +#include "common.c" + +const float PI = ALLEGRO_PI; +const float TWOPI = ALLEGRO_PI * 2.0; + +enum { + TYPE_EARTH, + TYPE_WIND, + TYPE_WATER, + TYPE_FIRE, + NUM_TYPES, + TYPE_NONE = NUM_TYPES +}; + +enum { + IMG_EARTH = TYPE_EARTH, + IMG_WIND = TYPE_WIND, + IMG_WATER = TYPE_WATER, + IMG_FIRE = TYPE_FIRE, + IMG_BLACK, + IMG_DROPSHADOW, + IMG_GLOW, + IMG_GLOW_OVERLAY, + IMG_AIR_EFFECT, + IMG_WATER_DROPS, + IMG_FLAME, + IMG_MAIN_FLAME, + IMG_MAX +}; + +typedef enum { + INTERP_LINEAR, + INTERP_FAST, + INTERP_DOUBLE_FAST, + INTERP_SLOW, + INTERP_DOUBLE_SLOW, + INTERP_SLOW_IN_OUT, + INTERP_BOUNCE +} Interp; + +typedef struct Anim Anim; +typedef struct Token Token; +typedef struct Flair Flair; +typedef struct Sprite Sprite; + +#define MAX_ANIMS 10 + +struct Anim { + float *lval; /* NULL if unused */ + float start_val; + float end_val; + Interp func; + float start_time; + float end_time; +}; + +struct Sprite { + unsigned image; /* IMG_ */ + float x, scale_x, align_x; + float y, scale_y, align_y; + float angle; + float r, g, b; + float opacity; + Anim anims[MAX_ANIMS]; /* keep it simple */ +}; + +struct Token { + unsigned type; /* TYPE_ */ + float x; + float y; + int pitch; /* [0, NUM_PITCH) */ + Sprite bot; + Sprite top; +}; + +struct Flair { + Flair *next; + float end_time; + Sprite sprite; +}; + +/****************************************************************************/ +/* Globals */ +/****************************************************************************/ + +enum { + NUM_PITCH = 8, + TOKENS_X = 16, + TOKENS_Y = NUM_PITCH, + NUM_TOKENS = TOKENS_X * TOKENS_Y, +}; + +ALLEGRO_DISPLAY *display; +ALLEGRO_TIMER *refresh_timer; +ALLEGRO_TIMER *playback_timer; + +ALLEGRO_BITMAP *images[IMG_MAX]; +ALLEGRO_SAMPLE *element_samples[NUM_TYPES][NUM_PITCH]; +ALLEGRO_SAMPLE *select_sample; + +Token tokens[NUM_TOKENS]; +Token buttons[NUM_TYPES]; +Sprite glow; +Sprite glow_overlay; +ALLEGRO_COLOR glow_color[NUM_TYPES]; +Flair *flairs = NULL; +Token *hover_token = NULL; +Token *selected_button = NULL; +int playback_column = 0; + +const int screen_w = 1024; +const int screen_h = 600; +const float game_board_x = 100.0; +const float token_size = 64; +const float token_scale = 0.8; +const float button_size = 64; +const float button_unsel_scale = 0.8; +const float button_sel_scale = 1.1; +const float dropshadow_unsel_scale = 0.6; +const float dropshadow_sel_scale = 0.9; +const float refresh_rate = 60.0; +const float playback_period = 2.7333; + +#define HAIKU_DATA "data/haiku/" + +/****************************************************************************/ +/* Init */ +/****************************************************************************/ + +static void load_images(void) +{ + int i; + + images[IMG_EARTH] = al_load_bitmap(HAIKU_DATA "earth4.png"); + images[IMG_WIND] = al_load_bitmap(HAIKU_DATA "wind3.png"); + images[IMG_WATER] = al_load_bitmap(HAIKU_DATA "water.png"); + images[IMG_FIRE] = al_load_bitmap(HAIKU_DATA "fire.png"); + images[IMG_BLACK] = al_load_bitmap(HAIKU_DATA "black_bead_opaque_A.png"); + images[IMG_DROPSHADOW] = al_load_bitmap(HAIKU_DATA "dropshadow.png"); + images[IMG_AIR_EFFECT] = al_load_bitmap(HAIKU_DATA "air_effect.png"); + images[IMG_WATER_DROPS] = al_load_bitmap(HAIKU_DATA "water_droplets.png"); + images[IMG_FLAME] = al_load_bitmap(HAIKU_DATA "flame2.png"); + images[IMG_MAIN_FLAME] = al_load_bitmap(HAIKU_DATA "main_flame2.png"); + images[IMG_GLOW] = al_load_bitmap(HAIKU_DATA "healthy_glow.png"); + images[IMG_GLOW_OVERLAY]= al_load_bitmap(HAIKU_DATA "overlay_pretty.png"); + + for (i = 0; i < IMG_MAX; i++) { + if (images[i] == NULL) + abort_example("Error loading image.\n"); + } +} + +static void load_samples(void) +{ + const char *base[NUM_TYPES] = {"earth", "air", "water", "fire"}; + char name[128]; + int t, p; + + for (t = 0; t < NUM_TYPES; t++) { + for (p = 0; p < NUM_PITCH; p++) { + sprintf(name, HAIKU_DATA "%s_%d.ogg", base[t], p); + element_samples[t][p] = al_load_sample(name); + if (!element_samples[t][p]) + abort_example("Error loading %s.\n", name); + } + } + + select_sample = al_load_sample(HAIKU_DATA "select.ogg"); + if (!select_sample) + abort_example("Error loading select.ogg.\n"); +} + +static void init_sprite(Sprite *spr, int image, float x, float y, float scale, + float opacity) +{ + int i; + + spr->image = image; + spr->x = x; + spr->y = y; + spr->scale_x = spr->scale_y = scale; + spr->align_x = spr->align_y = 0.5; + spr->angle = 0.0; + spr->r = spr->g = spr->b = 1.0; + spr->opacity = opacity; + for (i = 0; i < MAX_ANIMS; i++) + spr->anims[i].lval = NULL; +} + +static void init_tokens(void) +{ + const float token_w = token_size * token_scale; + const float token_x = game_board_x + token_w/2.0; + const float token_y = 80; + int i; + + for (i = 0; i < NUM_TOKENS; i++) { + int tx = i % TOKENS_X; + int ty = i / TOKENS_X; + float px = token_x + tx * token_w; + float py = token_y + ty * token_w; + + tokens[i].type = TYPE_NONE; + tokens[i].x = px; + tokens[i].y = py; + tokens[i].pitch = NUM_PITCH - 1 - ty; + assert(tokens[i].pitch >= 0 && tokens[i].pitch < NUM_PITCH); + init_sprite(&tokens[i].bot, IMG_BLACK, px, py, token_scale, 0.4); + init_sprite(&tokens[i].top, IMG_BLACK, px, py, token_scale, 0.0); + } +} + +static void init_buttons(void) +{ + const float dist[NUM_TYPES] = {-1.5, -0.5, 0.5, 1.5}; + int i; + + for (i = 0; i < NUM_TYPES; i++) { + float x = screen_w/2 + 150 * dist[i]; + float y = screen_h - 80; + + buttons[i].type = i; + buttons[i].x = x; + buttons[i].y = y; + init_sprite(&buttons[i].bot, IMG_DROPSHADOW, x, y, + dropshadow_unsel_scale, 0.4); + buttons[i].bot.align_y = 0.0; + init_sprite(&buttons[i].top, i, x, y, button_unsel_scale, 1.0); + } +} + +static void init_glow(void) +{ + init_sprite(&glow, IMG_GLOW, screen_w/2, screen_h, 1.0, 1.0); + glow.align_y = 1.0; + glow.r = glow.g = glow.b = 0.0; + + init_sprite(&glow_overlay, IMG_GLOW_OVERLAY, 0.0, 0.0, 1.0, 1.0); + glow_overlay.align_x = 0.0; + glow_overlay.align_y = 0.0; + glow_overlay.r = glow_overlay.g = glow_overlay.b = 0.0; + + glow_color[TYPE_EARTH] = al_map_rgb(0x6b, 0x8e, 0x23); /* olivedrab */ + glow_color[TYPE_WIND] = al_map_rgb(0xad, 0xd8, 0xe6); /* lightblue */ + glow_color[TYPE_WATER] = al_map_rgb(0x41, 0x69, 0xe1); /* royalblue */ + glow_color[TYPE_FIRE] = al_map_rgb(0xff, 0x00, 0x00); /* red */ +} + +/****************************************************************************/ +/* Flairs */ +/****************************************************************************/ + +static Sprite *make_flair(int image, float x, float y, float end_time) +{ + Flair *fl = malloc(sizeof *fl); + init_sprite(&fl->sprite, image, x, y, 1.0, 1.0); + fl->end_time = end_time; + fl->next = flairs; + flairs = fl; + return &fl->sprite; +} + +static void free_old_flairs(float now) +{ + Flair *prev, *fl, *next; + + prev = NULL; + for (fl = flairs; fl != NULL; fl = next) { + next = fl->next; + if (fl->end_time > now) + prev = fl; + else { + if (prev) + prev->next = next; + else + flairs = next; + free(fl); + } + } +} + +static void free_all_flairs(void) +{ + Flair *next; + + for (; flairs != NULL; flairs = next) { + next = flairs->next; + free(flairs); + } +} + +/****************************************************************************/ +/* Animations */ +/****************************************************************************/ + +static Anim *get_next_anim(Sprite *spr) +{ + static Anim dummy_anim; + unsigned i; + + for (i = 0; i < MAX_ANIMS; i++) { + if (spr->anims[i].lval == NULL) + return &spr->anims[i]; + } + + assert(false); + return &dummy_anim; +} + +static void fix_conflicting_anims(Sprite *grp, float *lval, float start_time, + float start_val) +{ + unsigned i; + + for (i = 0; i < MAX_ANIMS; i++) { + Anim *anim = &grp->anims[i]; + + if (anim->lval != lval) + continue; + + /* If an old animation would overlap with the new one, truncate it + * and make it converge to the new animation's starting value. + */ + if (anim->end_time > start_time) { + anim->end_time = start_time; + anim->end_val = start_val; + } + + /* Cancel any old animations which are scheduled to start after the + * new one, or which have been reduced to nothing. + */ + if (anim->start_time >= start_time || + anim->start_time >= anim->end_time) + { + grp->anims[i].lval = NULL; + } + } +} + +static void anim_full(Sprite *spr, float *lval, float start_val, float end_val, + Interp func, float delay, float duration) +{ + float start_time; + Anim *anim; + + start_time = al_get_time() + delay; + fix_conflicting_anims(spr, lval, start_time, start_val); + + anim = get_next_anim(spr); + anim->lval = lval; + anim->start_val = start_val; + anim->end_val = end_val; + anim->func = func; + anim->start_time = start_time; + anim->end_time = start_time + duration; +} + +static void anim(Sprite *spr, float *lval, float start_val, float end_val, + Interp func, float duration) +{ + anim_full(spr, lval, start_val, end_val, func, 0.0, duration); +} + +static void anim_to(Sprite *spr, float *lval, float end_val, + Interp func, float duration) +{ + anim_full(spr, lval, *lval, end_val, func, 0.0, duration); +} + +static void anim_delta(Sprite *spr, float *lval, float delta, + Interp func, float duration) +{ + anim_full(spr, lval, *lval, *lval + delta, func, 0.0, duration); +} + +static void anim_tint(Sprite *spr, const ALLEGRO_COLOR color, Interp func, + float duration) +{ + float r, g, b; + + al_unmap_rgb_f(color, &r, &g, &b); + anim_to(spr, &spr->r, r, func, duration); + anim_to(spr, &spr->g, g, func, duration); + anim_to(spr, &spr->b, b, func, duration); +} + +static float interpolate(Interp func, float t) +{ + switch (func) { + + case INTERP_LINEAR: + return t; + + case INTERP_FAST: + return -t*(t-2); + + case INTERP_DOUBLE_FAST: + t--; + return t*t*t + 1; + + case INTERP_SLOW: + return t*t; + + case INTERP_DOUBLE_SLOW: + return t*t*t; + + case INTERP_SLOW_IN_OUT: { + // Quadratic easing in/out - acceleration until halfway, then deceleration + float b = 0; + float c = 1; + float d = 1; + t /= d/2; + if (t < 1) { + return c/2 * t * t + b; + } else { + t--; + return -c/2 * (t*(t-2) - 1) + b; + } + } + + case INTERP_BOUNCE: { + // BOUNCE EASING: exponentially decaying parabolic bounce + // t: current time, b: beginning value, c: change in position, d: duration + // bounce easing out + if (t < (1/2.75)) + return (7.5625*t*t); + if (t < (2/2.75)) { + t -= (1.5/2.75); + return (7.5625*t*t + 0.75); + } + if (t < (2.5/2.75)) { + t -= (2.25/2.75); + return (7.5625*t*t + 0.9375); + } + t -= (2.625/2.75); + return (7.5625*t*t + 0.984375); + } + + default: + assert(false); + return 0.0; + } +} + +static void update_anim(Anim *anim, float now) +{ + float dt, t, range; + + if (!anim->lval) + return; + + if (now < anim->start_time) + return; + + dt = now - anim->start_time; + t = dt / (anim->end_time - anim->start_time); + + if (t >= 1.0) { + /* animation has run to completion */ + *anim->lval = anim->end_val; + anim->lval = NULL; + return; + } + + range = anim->end_val - anim->start_val; + *anim->lval = anim->start_val + interpolate(anim->func, t) * range; +} + +static void update_sprite_anims(Sprite *spr, float now) +{ + int i; + + for (i = 0; i < MAX_ANIMS; i++) + update_anim(&spr->anims[i], now); +} + +static void update_token_anims(Token *token, float now) +{ + update_sprite_anims(&token->bot, now); + update_sprite_anims(&token->top, now); +} + +static void update_anims(float now) +{ + Flair *fl; + int i; + + for (i = 0; i < NUM_TOKENS; i++) + update_token_anims(&tokens[i], now); + + for (i = 0; i < NUM_TYPES; i++) + update_token_anims(&buttons[i], now); + + update_sprite_anims(&glow, now); + update_sprite_anims(&glow_overlay, now); + + for (fl = flairs; fl != NULL; fl = fl->next) + update_sprite_anims(&fl->sprite, now); +} + +/****************************************************************************/ +/* Drawing */ +/****************************************************************************/ + +static void draw_sprite(const Sprite *spr) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_COLOR tint; + float cx, cy; + + bmp = images[spr->image]; + cx = spr->align_x * al_get_bitmap_width(bmp); + cy = spr->align_y * al_get_bitmap_height(bmp); + tint = al_map_rgba_f(spr->r, spr->g, spr->b, spr->opacity); + + al_draw_tinted_scaled_rotated_bitmap(bmp, tint, cx, cy, + spr->x, spr->y, spr->scale_x, spr->scale_y, spr->angle, 0); +} + +static void draw_token(const Token *token) +{ + draw_sprite(&token->bot); + draw_sprite(&token->top); +} + +static void draw_screen(void) +{ + Flair *fl; + int i; + + al_clear_to_color(al_map_rgb(0, 0, 0)); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE); + + draw_sprite(&glow); + draw_sprite(&glow_overlay); + + for (i = 0; i < NUM_TOKENS; i++) + draw_token(&tokens[i]); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + for (i = 0; i < NUM_TYPES; i++) + draw_token(&buttons[i]); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE); + + for (fl = flairs; fl != NULL; fl = fl->next) + draw_sprite(&fl->sprite); + + al_flip_display(); +} + +/****************************************************************************/ +/* Playback */ +/****************************************************************************/ + +static void spawn_wind_effects(float x, float y) +{ + const float now = al_get_time(); + Sprite *spr; + + spr = make_flair(IMG_AIR_EFFECT, x, y, now + 1.0); + anim(spr, &spr->scale_x, 0.9, 1.3, INTERP_FAST, 1.0); + anim(spr, &spr->scale_y, 0.9, 1.3, INTERP_FAST, 1.0); + anim(spr, &spr->opacity, 1.0, 0.0, INTERP_FAST, 1.0); + + spr = make_flair(IMG_AIR_EFFECT, x, y, now + 1.2); + anim(spr, &spr->opacity, 1.0, 0.0, INTERP_LINEAR, 1.2); + anim(spr, &spr->scale_x, 1.1, 1.5, INTERP_FAST, 1.2); + anim(spr, &spr->scale_y, 1.1, 0.5, INTERP_FAST, 1.2); + anim_delta(spr, &spr->x, 10.0, INTERP_FAST, 1.2); +} + +static void spawn_fire_effects(float x, float y) +{ + const float now = al_get_time(); + Sprite *spr; + int i; + + spr = make_flair(IMG_MAIN_FLAME, x, y, now + 0.8); + spr->align_y = 0.75; + anim_full(spr, &spr->scale_x, 0.2, 1.3, INTERP_BOUNCE, 0.0, 0.4); + anim_full(spr, &spr->scale_y, 0.2, 1.3, INTERP_BOUNCE, 0.0, 0.4); + anim_full(spr, &spr->scale_x, 1.3, 1.4, INTERP_BOUNCE, 0.4, 0.5); + anim_full(spr, &spr->scale_y, 1.3, 1.4, INTERP_BOUNCE, 0.4, 0.5); + anim_full(spr, &spr->opacity, 1.0, 0.0, INTERP_FAST, 0.3, 0.5); + + for (i = 0; i < 3; i++) { + spr = make_flair(IMG_FLAME, x, y, now + 0.7); + spr->align_x = 1.3; + spr->angle = TWOPI / 3 * i; + + anim_delta(spr, &spr->angle, -PI, INTERP_DOUBLE_FAST, 0.7); + anim(spr, &spr->opacity, 1.0, 0.0, INTERP_SLOW, 0.7); + anim(spr, &spr->scale_x, 0.2, 1.0, INTERP_FAST, 0.7); + anim(spr, &spr->scale_y, 0.2, 1.0, INTERP_FAST, 0.7); + } +} + +static float random_sign(void) +{ + return (rand() % 2) ? -1.0 : 1.0; +} + +static float random_float(float min, float max) +{ + return ((float) rand()/RAND_MAX)*(max-min) + min; +} + +static void spawn_water_effects(float x, float y) +{ +#define RAND(a, b) (random_float((a), (b))) +#define MRAND(a, b) (random_float((a), (b)) * max_duration) +#define SIGN (random_sign()) + + float now = al_get_time(); + float max_duration = 1.0; + Sprite *spr; + int i; + + spr = make_flair(IMG_WATER, x, y, now + max_duration); + anim(spr, &spr->scale_x, 1.0, 2.0, INTERP_FAST, 0.5); + anim(spr, &spr->scale_y, 1.0, 2.0, INTERP_FAST, 0.5); + anim(spr, &spr->opacity, 0.5, 0.0, INTERP_FAST, 0.5); + + for (i = 0; i < 9; i++) { + spr = make_flair(IMG_WATER_DROPS, x, y, now + max_duration); + spr->scale_x = RAND(0.3, 1.2) * SIGN; + spr->scale_y = RAND(0.3, 1.2) * SIGN; + spr->angle = RAND(0.0, TWOPI); + spr->r = RAND(0.0, 0.6); + spr->g = RAND(0.4, 0.6); + spr->b = 1.0; + + if (i == 0) { + anim_to(spr, &spr->opacity, 0.0, INTERP_LINEAR, max_duration); + } else { + anim_to(spr, &spr->opacity, 0.0, INTERP_DOUBLE_SLOW, MRAND(0.7, 1.0)); + } + anim_to(spr, &spr->scale_x, RAND(0.8, 3.0), INTERP_FAST, MRAND(0.7, 1.0)); + anim_to(spr, &spr->scale_y, RAND(0.8, 3.0), INTERP_FAST, MRAND(0.7, 1.0)); + anim_delta(spr, &spr->x, MRAND(0, 20.0)*SIGN, INTERP_FAST, MRAND(0.7, 1.0)); + anim_delta(spr, &spr->y, MRAND(0, 20.0)*SIGN, INTERP_FAST, MRAND(0.7, 1.0)); + } + +#undef RAND +#undef MRAND +#undef SIGN +} + +static void play_element(int type, int pitch, float vol, float pan) +{ + al_play_sample(element_samples[type][pitch], vol, pan, 1.0, + ALLEGRO_PLAYMODE_ONCE, NULL); +} + +static void activate_token(Token *token) +{ + const float sc = token_scale; + Sprite *spr = &token->top; + + switch (token->type) { + + case TYPE_EARTH: + play_element(TYPE_EARTH, token->pitch, 0.8, 0.0); + anim(spr, &spr->scale_x, spr->scale_x+0.4, spr->scale_x, INTERP_FAST, 0.3); + anim(spr, &spr->scale_y, spr->scale_y+0.4, spr->scale_y, INTERP_FAST, 0.3); + break; + + case TYPE_WIND: + play_element(TYPE_WIND, token->pitch, 0.8, 0.0); + anim_full(spr, &spr->scale_x, sc*1.0, sc*0.8, INTERP_SLOW_IN_OUT, 0.0, 0.5); + anim_full(spr, &spr->scale_x, sc*0.8, sc*1.0, INTERP_SLOW_IN_OUT, 0.5, 0.8); + anim_full(spr, &spr->scale_y, sc*1.0, sc*0.8, INTERP_SLOW_IN_OUT, 0.0, 0.5); + anim_full(spr, &spr->scale_y, sc*0.8, sc*1.0, INTERP_SLOW_IN_OUT, 0.5, 0.8); + spawn_wind_effects(spr->x, spr->y); + break; + + case TYPE_WATER: + play_element(TYPE_WATER, token->pitch, 0.7, 0.5); + anim_full(spr, &spr->scale_x, sc*1.3, sc*0.8, INTERP_BOUNCE, 0.0, 0.5); + anim_full(spr, &spr->scale_x, sc*0.8, sc*1.0, INTERP_BOUNCE, 0.5, 0.5); + anim_full(spr, &spr->scale_y, sc*0.8, sc*1.3, INTERP_BOUNCE, 0.0, 0.5); + anim_full(spr, &spr->scale_y, sc*1.3, sc*1.0, INTERP_BOUNCE, 0.5, 0.5); + spawn_water_effects(spr->x, spr->y); + break; + + case TYPE_FIRE: + play_element(TYPE_FIRE, token->pitch, 0.8, 0.0); + anim(spr, &spr->scale_x, sc*1.3, sc, INTERP_SLOW_IN_OUT, 1.0); + anim(spr, &spr->scale_y, sc*1.3, sc, INTERP_SLOW_IN_OUT, 1.0); + spawn_fire_effects(spr->x, spr->y); + break; + } +} + +static void update_playback(void) +{ + int y; + + for (y = 0; y < TOKENS_Y; y++) + activate_token(&tokens[y * TOKENS_X + playback_column]); + + if (++playback_column >= TOKENS_X) + playback_column = 0; +} + +/****************************************************************************/ +/* Control */ +/****************************************************************************/ + +static bool is_touched(Token *token, float size, float x, float y) +{ + float half = size/2.0; + return (token->x - half <= x && x < token->x + half + && token->y - half <= y && y < token->y + half); +} + +static Token *get_touched_token(float x, float y) +{ + int i; + + for (i = 0; i < NUM_TOKENS; i++) { + if (is_touched(&tokens[i], token_size, x, y)) + return &tokens[i]; + } + + return NULL; +} + +static Token *get_touched_button(float x, float y) +{ + int i; + + for (i = 0; i < NUM_TYPES; i++) { + if (is_touched(&buttons[i], button_size, x, y)) + return &buttons[i]; + } + + return NULL; +} + +static void unselect_token(Token *token) +{ + if (token->type != TYPE_NONE) { + Sprite *spr = &token->top; + anim_full(spr, &spr->opacity, spr->opacity, 0.0, INTERP_SLOW, 0.15, 0.15); + token->type = TYPE_NONE; + } +} + +static void unselect_all_tokens(void) +{ + int i; + + for (i = 0; i < NUM_TOKENS; i++) + unselect_token(&tokens[i]); +} + +static void select_token(Token *token) +{ + unsigned prev_type; + + if (!selected_button) + return; + + prev_type = token->type; + unselect_token(token); + + /* Unselect only if same type, for touch input. */ + if (prev_type != selected_button->type) { + Sprite *spr = &token->top; + spr->image = selected_button->type; + anim_to(spr, &spr->opacity, 1.0, INTERP_FAST, 0.15); + token->type = selected_button->type; + } +} + +static void change_healthy_glow(int type, float x) +{ + anim_tint(&glow, glow_color[type], INTERP_SLOW_IN_OUT, 3.0); + anim_to(&glow, &glow.x, x, INTERP_SLOW_IN_OUT, 3.0); + + anim_tint(&glow_overlay, glow_color[type], INTERP_SLOW_IN_OUT, 4.0); + anim_to(&glow_overlay, &glow_overlay.opacity, 1.0, INTERP_SLOW_IN_OUT, 4.0); +} + +static void select_button(Token *button) +{ + Sprite *spr; + + if (button == selected_button) + return; + + if (selected_button) { + spr = &selected_button->top; + anim_to(spr, &spr->scale_x, button_unsel_scale, INTERP_SLOW, 0.3); + anim_to(spr, &spr->scale_y, button_unsel_scale, INTERP_SLOW, 0.3); + anim_to(spr, &spr->opacity, 0.5, INTERP_DOUBLE_SLOW, 0.2); + + spr = &selected_button->bot; + anim_to(spr, &spr->scale_x, dropshadow_unsel_scale, INTERP_SLOW, 0.3); + anim_to(spr, &spr->scale_y, dropshadow_unsel_scale, INTERP_SLOW, 0.3); + } + + selected_button = button; + + spr = &button->top; + anim_to(spr, &spr->scale_x, button_sel_scale, INTERP_FAST, 0.3); + anim_to(spr, &spr->scale_y, button_sel_scale, INTERP_FAST, 0.3); + anim_to(spr, &spr->opacity, 1.0, INTERP_FAST, 0.3); + + spr = &button->bot; + anim_to(spr, &spr->scale_x, dropshadow_sel_scale, INTERP_FAST, 0.3); + anim_to(spr, &spr->scale_y, dropshadow_sel_scale, INTERP_FAST, 0.3); + + change_healthy_glow(button->type, button->x); + + al_play_sample(select_sample, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); +} + +static void on_mouse_down(float x, float y, int mbut) +{ + Token *token; + Token *button; + + if (mbut == 1) { + if ((token = get_touched_token(x, y))) + select_token(token); + else if ((button = get_touched_button(x, y))) + select_button(button); + } + else if (mbut == 2) { + if ((token = get_touched_token(x, y))) + unselect_token(token); + } +} + +static void on_mouse_axes(float x, float y) +{ + Token *token = get_touched_token(x, y); + + if (token == hover_token) + return; + + if (hover_token) { + Sprite *spr = &hover_token->bot; + anim_to(spr, &spr->opacity, 0.4, INTERP_DOUBLE_SLOW, 0.2); + } + + hover_token = token; + + if (hover_token) { + Sprite *spr = &hover_token->bot; + anim_to(spr, &spr->opacity, 0.7, INTERP_FAST, 0.2); + } +} + +static void main_loop(ALLEGRO_EVENT_QUEUE *queue) +{ + ALLEGRO_EVENT event; + bool redraw = true; + + for (;;) { + if (redraw && al_is_event_queue_empty(queue)) { + float now = al_get_time(); + free_old_flairs(now); + update_anims(now); + draw_screen(); + redraw = false; + } + + al_wait_for_event(queue, &event); + + if (event.timer.source == refresh_timer) { + redraw = true; + continue; + } + + if (event.timer.source == playback_timer) { + update_playback(); + continue; + } + + if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + on_mouse_axes(event.mouse.x, event.mouse.y); + continue; + } + + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + on_mouse_down(event.mouse.x, event.mouse.y, event.mouse.button); + continue; + } + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + + if (event.keyboard.keycode == ALLEGRO_KEY_C) + unselect_all_tokens(); + } + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_EVENT_QUEUE *queue; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Error initialising Allegro.\n"); + } + if (!al_install_audio() || !al_reserve_samples(128)) { + abort_example("Error initialising audio.\n"); + } + al_init_acodec_addon(); + al_init_image_addon(); + init_platform_specific(); + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + + display = al_create_display(screen_w, screen_h); + if (!display) { + abort_example("Error creating display.\n"); + } + al_set_window_title(display, "Haiku - A Musical Instrument"); + + load_images(); + load_samples(); + + init_tokens(); + init_buttons(); + init_glow(); + select_button(&buttons[TYPE_EARTH]); + + al_install_keyboard(); + al_install_mouse(); + + refresh_timer = al_create_timer(1.0 / refresh_rate); + playback_timer = al_create_timer(playback_period / TOKENS_X); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_timer_event_source(refresh_timer)); + al_register_event_source(queue, al_get_timer_event_source(playback_timer)); + if (al_is_touch_input_installed()) { + al_register_event_source(queue, + al_get_touch_input_mouse_emulation_event_source()); + } + + al_start_timer(refresh_timer); + al_start_timer(playback_timer); + + main_loop(queue); + + free_all_flairs(); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_haptic.c b/allegro/examples/ex_haptic.c new file mode 100644 index 00000000..f05249ce --- /dev/null +++ b/allegro/examples/ex_haptic.c @@ -0,0 +1,138 @@ +/* + * Example program for the Allegro library, by Beoran. + * + * This program tests haptic effects. + */ + +#define ALLEGRO_UNSTABLE +#include +#include + +#include "common.c" + + +static void test_haptic_joystick(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_HAPTIC_EFFECT_ID id; + ALLEGRO_HAPTIC *haptic; + ALLEGRO_HAPTIC_EFFECT effect; + const double intensity = 1.0; + const double duration = 1.0; + + haptic = al_get_haptic_from_joystick(joy); + + if (!haptic) { + log_printf("Could not get haptic device from joystick!"); + return; + } + + log_printf("Can play back %d haptic effects.\n", + al_get_max_haptic_effects(haptic)); + + log_printf("Set gain to 0.8: %d.\n", + al_set_haptic_gain(haptic, 0.8)); + + log_printf("Get gain: %lf.\n", + al_get_haptic_gain(haptic)); + + log_printf("Capabilities: %d.\n", + al_get_haptic_capabilities(haptic)); + + memset(&effect, 0, sizeof(effect)); + effect.type = ALLEGRO_HAPTIC_RUMBLE; + effect.data.rumble.strong_magnitude = intensity; + effect.data.rumble.weak_magnitude = intensity; + effect.replay.delay = 0.1; + effect.replay.length = duration; + + log_printf("Upload effect: %d.\n", + al_upload_haptic_effect(haptic, &effect, &id)); + + log_printf("Playing effect: %d.\n", + al_play_haptic_effect(&id, 3)); + + do { + al_rest(0.1); + } while (al_is_haptic_effect_playing(&id)); + + log_printf("Set gain to 0.4: %d.\n", + al_set_haptic_gain(haptic, 0.4)); + + log_printf("Get gain: %lf.\n", + al_get_haptic_gain(haptic)); + + log_printf("Playing effect again: %d.\n", + al_play_haptic_effect(&id, 5)); + + al_rest(2.0); + + log_printf("Stopping effect: %d.\n", + al_stop_haptic_effect(&id)); + + do { + al_rest(0.1); + } while (al_is_haptic_effect_playing(&id)); + + log_printf("Release effect: %d.\n", + al_release_haptic_effect(&id)); + + log_printf("Release haptic: %d.\n", + al_release_haptic(haptic)); +} + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + int num_joysticks; + int i; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + display = al_create_display(640, 480); + if (!display) { + abort_example("al_create_display failed\n"); + } + if (!al_install_joystick()) { + abort_example("al_install_joystick failed\n"); + } + if (!al_install_haptic()) { + abort_example("al_install_haptic failed\n"); + } + + open_log(); + + num_joysticks = al_get_num_joysticks(); + log_printf("Found %d joysticks.\n", num_joysticks); + + for (i = 0; i < num_joysticks; i++) { + ALLEGRO_JOYSTICK *joy = al_get_joystick(i); + if (!joy) { + continue; + } + + if (al_is_joystick_haptic(joy)) { + log_printf("Joystick %s supports force feedback.\n", + al_get_joystick_name(joy)); + test_haptic_joystick(joy); + } + else { + log_printf("Joystick %s does not support force feedback.\n", + al_get_joystick_name(joy)); + } + + al_release_joystick(joy); + } + + log_printf("\nAll done!\n"); + close_log(true); + + return 0; +} + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_haptic2.cpp b/allegro/examples/ex_haptic2.cpp new file mode 100644 index 00000000..a20e6a23 --- /dev/null +++ b/allegro/examples/ex_haptic2.cpp @@ -0,0 +1,901 @@ +/* + * Example program for the Allegro library, by Beoran. + * + * Exhaustive haptics example. + */ + +#include + +#define ALLEGRO_UNSTABLE +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/allegro_ttf.h" + +#include "nihgui.hpp" + +#include "common.c" + +struct Haptic +{ + ALLEGRO_HAPTIC *haptic; + ALLEGRO_HAPTIC_EFFECT effect; + ALLEGRO_HAPTIC_EFFECT_ID id; + const char *name; + bool playing; +}; + +#define EX_MAX_HAPTICS 8 + +static Haptic haptics[EX_MAX_HAPTICS]; +static int num_haptics = 0; +static ALLEGRO_EVENT_QUEUE * joystick_queue; +static ALLEGRO_TIMER * update_timer = NULL; + +static void release_all_haptics() { + for (int i = 0; i < num_haptics; i++) { + al_release_haptic(haptics[i].haptic); + haptics[i].haptic = NULL; + } +} + +static void get_all_haptics() { + num_haptics = 0; + ALLEGRO_DISPLAY * display = al_get_current_display(); + + if (al_is_display_haptic(display)) { + haptics[num_haptics].haptic = al_get_haptic_from_display(display); + if (haptics[num_haptics].haptic) { + haptics[num_haptics].name = (const char *)"display"; + haptics[num_haptics].playing = false; + num_haptics++; + } + } + + for (int i = 0; + num_haptics < EX_MAX_HAPTICS && i < al_get_num_joysticks(); + i++) + { + ALLEGRO_JOYSTICK *joy = al_get_joystick(i); + if (al_is_joystick_haptic(joy)) { + haptics[num_haptics].haptic = al_get_haptic_from_joystick(joy); + if (haptics[num_haptics].haptic) { + const char *name = al_get_joystick_name(joy); + haptics[num_haptics].name = (const char *)name; + haptics[num_haptics].playing = false; + num_haptics++; + } + } + } + +} + +struct CapacityName +{ + int value; + const char *name; +}; + +static const CapacityName capname[] = +{ + {ALLEGRO_HAPTIC_RUMBLE, "ALLEGRO_HAPTIC_RUMBLE"}, + {ALLEGRO_HAPTIC_PERIODIC, "ALLEGRO_HAPTIC_PERIODIC"}, + {ALLEGRO_HAPTIC_CONSTANT, "ALLEGRO_HAPTIC_CONSTANT"}, + {ALLEGRO_HAPTIC_SPRING, "ALLEGRO_HAPTIC_SPRING"}, + {ALLEGRO_HAPTIC_FRICTION, "ALLEGRO_HAPTIC_FRICTION"}, + {ALLEGRO_HAPTIC_DAMPER, "ALLEGRO_HAPTIC_DAMPER"}, + {ALLEGRO_HAPTIC_INERTIA, "ALLEGRO_HAPTIC_INERTIA"}, + {ALLEGRO_HAPTIC_RAMP, "ALLEGRO_HAPTIC_RAMP"}, + {ALLEGRO_HAPTIC_SQUARE, "ALLEGRO_HAPTIC_SQUARE"}, + {ALLEGRO_HAPTIC_TRIANGLE, "ALLEGRO_HAPTIC_TRIANGLE"}, + {ALLEGRO_HAPTIC_SINE, "ALLEGRO_HAPTIC_SINE"}, + {ALLEGRO_HAPTIC_SAW_UP, "ALLEGRO_HAPTIC_SAW_UP"}, + {ALLEGRO_HAPTIC_SAW_DOWN, "ALLEGRO_HAPTIC_SAW_DOWN"}, + {ALLEGRO_HAPTIC_CUSTOM, "ALLEGRO_HAPTIC_CUSTOM"}, + {ALLEGRO_HAPTIC_GAIN, "ALLEGRO_HAPTIC_GAIN"}, + {ALLEGRO_HAPTIC_ANGLE, "ALLEGRO_HAPTIC_ANGLE"}, + {ALLEGRO_HAPTIC_RADIUS, "ALLEGRO_HAPTIC_RADIUS"}, + {ALLEGRO_HAPTIC_AZIMUTH, "ALLEGRO_HAPTIC_AZIMUTH"} +}; + +#define EX_START_TYPES 0 +#define EX_MAX_TYPES 8 +#define EX_END_TYPES 8 + +#define EX_START_WAVES 8 +#define EX_END_WAVES 13 +#define EX_MAX_WAVES 5 +/* Ignore custom waveforms for now... */ + +#define EX_START_COORDS 15 +#define EX_MAX_COORDS 3 +#define EX_END_COORDS 18 + +class CanStopAndPlay +{ + public: + virtual void on_play() = 0; + virtual void on_stop() = 0; +}; + +class PlayButton: public Button +{ + protected: + CanStopAndPlay *stop_and_play; + public: + PlayButton(CanStopAndPlay *snp) : + Button("Play"), + stop_and_play(snp) + { + } + void on_click(int mx, int my); +}; + +void PlayButton::on_click(int, int) +{ + if (is_disabled()) + return; + log_printf("Start playing...\n"); + if (stop_and_play) { + stop_and_play->on_play(); + } +} + +class StopButton: public Button +{ + protected: + CanStopAndPlay *stop_and_play; + public: + StopButton(CanStopAndPlay *snp) : + Button("Stop"), + stop_and_play(snp) + { + } + void on_click(int mx, int my); +}; + +void StopButton::on_click(int, int) +{ + if (is_disabled()) + return; + log_printf("Stop playing...\n"); + if (stop_and_play) { + stop_and_play->on_stop(); + } +} + +class Prog: public CanStopAndPlay +{ + private: + Dialog d; + + List device_list; + List type_list; + List waveform_list; + + Label device_label; + Label type_label; + Label waveform_label; + + HSlider length_slider; + HSlider delay_slider; + HSlider loops_slider; + Label replay_label; + Label length_label; + Label delay_label; + Label loops_label; + + HSlider attack_length_slider; + HSlider attack_level_slider; + HSlider fade_length_slider; + HSlider fade_level_slider; + Label envelope_label; + Label attack_length_label; + Label attack_level_label; + Label fade_length_label; + Label fade_level_label; + + HSlider angle_slider; + HSlider radius_slider; + HSlider azimuth_slider; + Label coordinates_label; + Label angle_label; + Label radius_label; + Label azimuth_label; + + HSlider level_slider; + Label constant_effect_label; + Label level_label; + + HSlider start_level_slider; + HSlider end_level_slider; + Label ramp_effect_label; + Label start_level_label; + Label end_level_label; + + HSlider right_saturation_slider; + HSlider right_coeff_slider; + HSlider left_saturation_slider; + HSlider left_coeff_slider; + HSlider deadband_slider; + HSlider center_slider; + + Label right_saturation_label; + Label right_coeff_label; + Label left_saturation_label; + Label left_coeff_label; + Label condition_effect_label; + Label deadband_label; + Label center_label; + + HSlider period_slider; + HSlider magnitude_slider; + HSlider offset_slider; + HSlider phase_slider; + Label periodic_effect_label; + Label period_label; + Label magnitude_label; + Label offset_label; + Label phase_label; + + HSlider strong_magnitude_slider; + HSlider weak_magnitude_slider; + Label rumble_effect_label; + Label strong_magnitude_label; + Label weak_magnitude_label; + + HSlider gain_slider; + Label gain_label; + + HSlider autocenter_slider; + Label autocenter_label; + + Label message_label; + Label message_label_label; + + PlayButton play_button; + StopButton stop_button; + + Haptic *last_haptic; + Haptic *show_haptic; + + public: + Prog(const Theme & theme, ALLEGRO_DISPLAY *display); + void run(); + void update(); + void update_controls(Haptic *dev); + virtual void on_play(); + virtual void on_stop(); + void get_envelope(ALLEGRO_HAPTIC_ENVELOPE *envelope); +}; + +Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : + d(Dialog(theme, display, 20, 40)), + device_list(0), + type_list(0), + waveform_list(0), + device_label("Haptic Device"), + type_label("Haptic Effect Type"), + waveform_label("Wave Form Periodic Effect"), + length_slider(1, 10), + delay_slider(1, 10), + loops_slider(1, 10), + replay_label("Replay"), + length_label("Length", false), + delay_label("Delay", false), + loops_label("Loops"), + attack_length_slider(2, 10), + attack_level_slider(4, 10), + fade_length_slider(2, 10), + fade_level_slider(4, 10), + envelope_label("Envelope"), + attack_length_label("Attack Length", false), + attack_level_label("Attack Level", false), + fade_length_label("Fade Length", false), + fade_level_label("Fade Level", false), + angle_slider(0, 360), + radius_slider(0, 10), + azimuth_slider(180, 360), + coordinates_label("Coordinates"), + angle_label("Angle", false), + radius_label("Radius", false), + azimuth_label("Azimuth", false), + level_slider(5, 10), + constant_effect_label("Constant Effect"), + level_label("Level", false), + start_level_slider(3, 10), + end_level_slider(7, 10), + ramp_effect_label("Ramp Effect"), + start_level_label("Start Level", false), + end_level_label("End Level", false), + right_saturation_slider(5, 10), + right_coeff_slider(5, 10), + left_saturation_slider(5, 10), + left_coeff_slider(5, 10), + deadband_slider(1, 10), + center_slider(5, 10), + right_saturation_label("Right Saturation", false), + right_coeff_label("Right Coefficient", false), + left_saturation_label("Left Saturation", false), + left_coeff_label("Left Coefficient", false), + condition_effect_label("Condition Effect"), + deadband_label("Deadband", false), + center_label("Center", false), + period_slider(1, 10), + magnitude_slider(5, 10), + offset_slider(0, 10), + phase_slider(0, 10), + periodic_effect_label("Periodic Effect"), + period_label("Period", false), + magnitude_label("Magnitude", false), + offset_label("Offset", false), + phase_label("Phase", false), + strong_magnitude_slider(5, 10), + weak_magnitude_slider(5, 10), + rumble_effect_label("Rumble effect"), + strong_magnitude_label("Strong Magnitude", false), + weak_magnitude_label("Weak Magnitude", false), + gain_slider(10, 10), + gain_label("Gain"), + autocenter_slider(0, 10), + autocenter_label("Autocenter"), + message_label("Ready.", false), + message_label_label("Status", false), + play_button(this), + stop_button(this), + last_haptic(NULL), + show_haptic(NULL) +{ + for (int i = 0; i < num_haptics; i++) { + device_list.append_item(haptics[i].name); + } + d.add(device_label, 0, 1, 7, 1); + d.add(device_list, 0, 2, 7, 8); + + for (int i = EX_START_TYPES; i < EX_END_TYPES; i++) { + type_list.append_item(capname[i].name); + } + d.add(type_label, 7, 1, 6, 1); + d.add(type_list, 7, 2, 6, 8); + + for (int i = EX_START_WAVES; i < EX_END_WAVES; i++) { + waveform_list.append_item(capname[i].name); + } + d.add(waveform_label, 13, 1, 7, 1); + d.add(waveform_list, 13, 2, 7, 8); + + d.add(replay_label, 0, 11, 7, 1); + d.add(length_label, 0, 12, 2, 1); + d.add(length_slider, 2, 12, 5, 1); + d.add(delay_label, 0, 13, 2, 1); + d.add(delay_slider, 2, 13, 5, 1); + + d.add(loops_label, 7, 11, 7, 1); + d.add(loops_slider, 7, 12, 6, 1); + d.add(gain_label, 13, 11, 7, 1); + d.add(gain_slider, 13, 12, 7, 1); + + d.add(autocenter_label, 13, 13, 7, 1); + d.add(autocenter_slider, 13, 14, 7, 1); + + + d.add(envelope_label, 0, 15, 9, 1); + d.add(attack_length_label, 0, 16, 3, 1); + d.add(attack_length_slider, 4, 16, 6, 1); + d.add(attack_level_label, 0, 17, 3, 1); + d.add(attack_level_slider, 4, 17, 6, 1); + d.add(fade_length_label, 0, 18, 3, 1); + d.add(fade_length_slider, 4, 18, 6, 1); + d.add(fade_level_label, 0, 19, 3, 1); + d.add(fade_level_slider, 4, 19, 6, 1); + + d.add(coordinates_label, 11, 15, 9, 1); + d.add(angle_label, 11, 16, 2, 1); + d.add(angle_slider, 13, 16, 7, 1); + d.add(radius_label, 11, 17, 2, 1); + d.add(radius_slider, 13, 17, 7, 1); + d.add(azimuth_label, 11, 18, 2, 1); + d.add(azimuth_slider, 13, 18, 7, 1); + + d.add(condition_effect_label, 0, 21, 9, 1); + d.add(right_coeff_label, 0, 22, 4, 1); + d.add(right_coeff_slider, 4, 22, 6, 1); + d.add(right_saturation_label, 0, 23, 4, 1); + d.add(right_saturation_slider, 4, 23, 6, 1); + d.add(left_coeff_label, 0, 24, 4, 1); + d.add(left_coeff_slider, 4, 24, 6, 1); + d.add(left_saturation_label, 0, 25, 4, 1); + d.add(left_saturation_slider, 4, 25, 6, 1); + d.add(deadband_label, 0, 26, 4, 1); + d.add(deadband_slider, 4, 26, 6, 1); + d.add(center_label, 0, 27, 4, 1); + d.add(center_slider, 4, 27, 6, 1); + + d.add(periodic_effect_label, 11, 21, 9, 1); + d.add(period_label, 11, 22, 2, 1); + d.add(period_slider, 13, 22, 7, 1); + d.add(magnitude_label, 11, 23, 2, 1); + d.add(magnitude_slider, 13, 23, 7, 1); + d.add(offset_label, 11, 24, 2, 1); + d.add(offset_slider, 13, 24, 7, 1); + d.add(phase_label, 11, 25, 2, 1); + d.add(phase_slider, 13, 25, 7, 1); + + d.add(ramp_effect_label, 11, 29, 9, 1); + d.add(start_level_label, 11, 30, 2, 1); + d.add(start_level_slider, 13, 30, 7, 1); + d.add(end_level_label, 11, 31, 2, 1); + d.add(end_level_slider, 13, 31, 7, 1); + + d.add(rumble_effect_label, 0, 29, 9, 1); + d.add(strong_magnitude_label, 0, 30, 4, 1); + d.add(strong_magnitude_slider, 4, 30, 6, 1); + d.add(weak_magnitude_label, 0, 31, 4, 1); + d.add(weak_magnitude_slider, 4, 31, 6, 1); + + d.add(constant_effect_label, 0, 33, 9, 1); + d.add(level_label, 0, 34, 3, 1); + d.add(level_slider, 4, 34, 6, 1); + + d.add(message_label_label, 0, 36, 2, 1); + d.add(message_label, 2, 36, 12, 1); + + d.add(play_button, 6, 38, 3, 2); + d.add(stop_button, 12, 38, 3, 2); + + d.register_event_source(al_get_timer_event_source(update_timer)); + +} + +void Prog::update() +{ + /* Update playing state and display. */ + if (last_haptic && last_haptic->playing) { + if (!al_is_haptic_effect_playing(&last_haptic->id)) { + last_haptic->playing = false; + al_release_haptic_effect(&last_haptic->id); + message_label.set_text("Done."); + play_button.set_disabled(false); + d.request_draw(); + log_printf("Play done on %s\n", last_haptic->name); + } + } + + ALLEGRO_EVENT e; + + /* Check for hot plugging*/ + while(al_get_next_event(joystick_queue, &e)) { + /* clear, reconfigure and fetch haptics again. */ + if (e.type == ALLEGRO_EVENT_JOYSTICK_CONFIGURATION) { + al_reconfigure_joysticks(); + release_all_haptics(); + get_all_haptics(); + device_list.clear_items(); + for (int i = 0; i < num_haptics; i++) { + device_list.append_item(haptics[i].name); + } + log_printf("Hot plugging detected...\n"); + message_label.set_text("Hot Plugging..."); + play_button.set_disabled(false); + d.request_draw(); + } + } + + /* Update availability of controls based on capabilities. */ + int devno = device_list.get_cur_value(); + Haptic *dev = haptics + devno; + if (dev && dev->haptic) { + if (dev != show_haptic) { + play_button.set_disabled(false); + update_controls(dev); + show_haptic = dev; + message_label.set_text("Haptic Device Found."); + d.request_draw(); + } + } else { + play_button.set_disabled(true); + message_label.set_text("No Haptic Device."); + d.request_draw(); + } +} + +void Prog::run() +{ + d.prepare(); + + while (!d.is_quit_requested()) { + update(); + if (d.is_draw_requested()) { + al_clear_to_color(al_map_rgb(128, 148, 168)); + d.draw(); + al_flip_display(); + } + + d.run_step(true); + } + + /* Stop playing anything we were still playing. */ + on_stop(); +} + +#define TEST_CAP(CAP, FLAG) (((CAP) & (FLAG)) == (FLAG)) + +void Prog::update_controls(Haptic *dev) +{ + /* Take a deep breath, here we go... */ + bool condition, envelope, periodic; + int cap = 0; + if (dev) { + cap = al_get_haptic_capabilities(dev->haptic); + } + + /* Gain capability */ + gain_slider.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_GAIN)); + gain_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_GAIN)); + + /* Autocenter capability */ + autocenter_slider.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_AUTOCENTER)); + autocenter_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_AUTOCENTER)); + + + /* Envelope related capabilities and sliders. */ + envelope = TEST_CAP(cap, ALLEGRO_HAPTIC_PERIODIC) || + TEST_CAP(cap, ALLEGRO_HAPTIC_CONSTANT) || + TEST_CAP(cap, ALLEGRO_HAPTIC_RAMP); + + envelope_label.set_disabled(!envelope); + attack_level_slider.set_disabled(!envelope); + attack_length_slider.set_disabled(!envelope); + fade_level_slider.set_disabled(!envelope); + fade_length_slider.set_disabled(!envelope); + attack_level_label.set_disabled(!envelope); + attack_length_label.set_disabled(!envelope); + fade_level_label.set_disabled(!envelope); + fade_length_label.set_disabled(!envelope); + + /* Coordinate related capabilities. */ + angle_slider.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_ANGLE)); + angle_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_ANGLE)); + radius_slider.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_RADIUS)); + radius_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_RADIUS)); + azimuth_slider.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_AZIMUTH)); + azimuth_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_AZIMUTH)); + + /* Condition effect related capabilities. */ + condition = TEST_CAP(cap, ALLEGRO_HAPTIC_DAMPER) || + TEST_CAP(cap, ALLEGRO_HAPTIC_FRICTION) || + TEST_CAP(cap, ALLEGRO_HAPTIC_INERTIA) || + TEST_CAP(cap, ALLEGRO_HAPTIC_SPRING); + + condition_effect_label.set_disabled(!condition); + right_coeff_slider.set_disabled(!condition); + left_coeff_slider.set_disabled(!condition); + right_saturation_slider.set_disabled(!condition); + left_saturation_slider.set_disabled(!condition); + center_slider.set_disabled(!condition); + deadband_slider.set_disabled(!condition); + right_coeff_label.set_disabled(!condition); + left_coeff_label.set_disabled(!condition); + right_saturation_label.set_disabled(!condition); + left_saturation_label.set_disabled(!condition); + center_label.set_disabled(!condition); + deadband_label.set_disabled(!condition); + + /* Constant effect related capabilities. */ + constant_effect_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_CONSTANT)); + level_slider.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_CONSTANT)); + level_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_CONSTANT)); + + /* Ramp effect capabilities. */ + ramp_effect_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_RAMP)); + start_level_slider.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_RAMP)); + start_level_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_RAMP)); + end_level_slider.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_RAMP)); + end_level_label.set_disabled(!TEST_CAP(cap, ALLEGRO_HAPTIC_RAMP)); + + /* Period effect capabilities. */ + periodic = TEST_CAP(cap, ALLEGRO_HAPTIC_PERIODIC); + waveform_label.set_disabled(!periodic); + waveform_list.set_disabled(!periodic); + periodic_effect_label.set_disabled(!periodic); + period_slider.set_disabled(!periodic); + magnitude_slider.set_disabled(!periodic); + offset_slider.set_disabled(!periodic); + phase_slider.set_disabled(!periodic); + period_label.set_disabled(!periodic); + magnitude_label.set_disabled(!periodic); + offset_label.set_disabled(!periodic); + phase_label.set_disabled(!periodic); + + /* Change list of supported effect types. */ + type_list.clear_items(); + for (int i = EX_START_TYPES; i < EX_END_TYPES; i++) { + const CapacityName *cn = &capname[i]; + if (TEST_CAP(cap, cn->value)) { + type_list.append_item(cn->name); + } + } + + /* Change list of supported wave form types. */ + waveform_list.clear_items(); + for (int i = EX_START_WAVES; i < EX_END_WAVES; i++) { + const CapacityName *cn = &capname[i]; + if (TEST_CAP(cap, cn->value)) { + waveform_list.append_item(cn->name); + } + } +} + +static int name_to_cap(const std::string & name) +{ + for (int i = 0; i < EX_END_WAVES; i++) { + if (name == capname[i].name) { + return capname[i].value; + } + } + return -1; +} + +static const char *cap_to_name(int cap) +{ + for (int i = 0; i < EX_END_WAVES; i++) { + if (cap == capname[i].value) { + return capname[i].name; + } + } + return "unknown"; +} + +static double slider_to_magnitude(const HSlider & slider) +{ + double value = (double)slider.get_cur_value(); + double max = (double)slider.get_max_value(); + return value / max; +} + +static double slider_to_duration(const HSlider & slider) +{ + double value = (double)slider.get_cur_value(); + double max = 1.0; + return value / max; +} + +static double slider_to_angle(const HSlider & slider) +{ + double value = (double)slider.get_cur_value(); + double max = (double)slider.get_max_value(); + return value / max; +} + +void Prog::get_envelope(ALLEGRO_HAPTIC_ENVELOPE *envelope) +{ + if (!envelope) + return; + envelope->attack_length = slider_to_duration(attack_length_slider); + envelope->fade_length = slider_to_duration(fade_length_slider); + envelope->attack_level = slider_to_magnitude(attack_level_slider); + envelope->fade_level = slider_to_magnitude(fade_level_slider); +} + +void Prog::on_play() +{ + int devno = device_list.get_cur_value(); + if (devno < 0 || devno >= num_haptics) { + message_label.set_text("No Haptic Device!"); + log_printf("No such device: %d\n", devno); + return; + } + + Haptic *haptic = haptics + devno; + if (!haptic || !haptic->haptic) { + log_printf("Device is NULL: %d\n", devno); + message_label.set_text("Device Is NULL!"); + return; + } + + if (!al_is_haptic_active(haptic->haptic)) { + message_label.set_text("Device Not Active!"); + log_printf("Device is not active: %d\n", devno); + return; + } + + /* Stop playing previous effect. */ + if (haptic->playing) { + al_stop_haptic_effect(&haptic->id); + haptic->playing = false; + al_release_haptic_effect(&haptic->id); + } + + /* First set gain. */ + double gain = slider_to_magnitude(gain_slider); + al_set_haptic_gain(haptic->haptic, gain); + + /* Set autocentering. */ + double autocenter = slider_to_magnitude(autocenter_slider); + al_set_haptic_autocenter(haptic->haptic, autocenter); + + + /* Now fill in the effect struct. */ + int type = name_to_cap(type_list.get_selected_item_text()); + int wavetype = name_to_cap(waveform_list.get_selected_item_text()); + + if (type < 0) { + message_label.set_text("Unknown Effect Type!"); + log_printf("Unknown effect type: %d on %s\n", type, haptic->name); + return; + } + + if ((wavetype < 0) && (type == ALLEGRO_HAPTIC_PERIODIC)) { + message_label.set_text("Unknown Wave Form!"); + log_printf("Unknown wave type: %d on %s\n", wavetype, haptic->name); + return; + } + + haptic->effect.type = type; + haptic->effect.replay.delay = slider_to_duration(delay_slider); + haptic->effect.replay.length = slider_to_duration(length_slider); + int loops = loops_slider.get_cur_value(); + haptic->effect.direction.angle = slider_to_angle(angle_slider); + haptic->effect.direction.radius = slider_to_magnitude(angle_slider); + haptic->effect.direction.azimuth = slider_to_angle(angle_slider); + + switch (type) { + case ALLEGRO_HAPTIC_RUMBLE: + haptic->effect.data.rumble.strong_magnitude = slider_to_magnitude(strong_magnitude_slider); + haptic->effect.data.rumble.weak_magnitude = slider_to_magnitude(weak_magnitude_slider); + break; + case ALLEGRO_HAPTIC_PERIODIC: + get_envelope(&haptic->effect.data.periodic.envelope); + haptic->effect.data.periodic.waveform = wavetype; + haptic->effect.data.periodic.magnitude = slider_to_magnitude(magnitude_slider); + haptic->effect.data.periodic.period = slider_to_duration(period_slider); + haptic->effect.data.periodic.offset = slider_to_duration(offset_slider); + haptic->effect.data.periodic.phase = slider_to_duration(phase_slider); + haptic->effect.data.periodic.custom_len = 0; + haptic->effect.data.periodic.custom_data = NULL; + break; + case ALLEGRO_HAPTIC_CONSTANT: + get_envelope(&haptic->effect.data.constant.envelope); + haptic->effect.data.constant.level = slider_to_magnitude(level_slider); + break; + case ALLEGRO_HAPTIC_RAMP: + get_envelope(&haptic->effect.data.ramp.envelope); + haptic->effect.data.ramp.start_level = slider_to_magnitude(start_level_slider); + haptic->effect.data.ramp.end_level = slider_to_magnitude(end_level_slider); + break; + + case ALLEGRO_HAPTIC_SPRING: + case ALLEGRO_HAPTIC_FRICTION: + case ALLEGRO_HAPTIC_DAMPER: + case ALLEGRO_HAPTIC_INERTIA: /* fall through. */ + haptic->effect.data.condition.right_saturation = slider_to_magnitude(right_saturation_slider); + haptic->effect.data.condition.left_saturation = slider_to_magnitude(left_saturation_slider); + haptic->effect.data.condition.right_coeff = slider_to_magnitude(right_coeff_slider); + haptic->effect.data.condition.left_coeff = slider_to_magnitude(left_coeff_slider); + haptic->effect.data.condition.deadband = slider_to_magnitude(deadband_slider); + haptic->effect.data.condition.center = slider_to_magnitude(center_slider); + /* XXX need a different conversion function here, but I don't have a + * controller that supports condition effects anyway... :p + */ + break; + default: + message_label.set_text("Unknown Effect Type!"); + log_printf("Unknown effect type %d %d\n", devno, type); + return; + } + + if (!al_is_haptic_effect_ok(haptic->haptic, &haptic->effect)) { + message_label.set_text("Effect Not Supported!"); + log_printf("Playing of effect type %s on %s not supported\n", + cap_to_name(type), haptic->name); + return; + } + + haptic->playing = al_upload_and_play_haptic_effect(haptic->haptic, + &haptic->effect, &haptic->id, loops); + if (haptic->playing) { + message_label.set_text("Playing..."); + log_printf("Started playing %d loops of effect type %s on %s\n", + loops, cap_to_name(type), haptic->name); + last_haptic = haptic; + } + else { + message_label.set_text("Playing of effect failed!"); + log_printf("Playing of effect type %s on %s failed\n", cap_to_name(type), + haptic->name); + } + + play_button.set_disabled(true); +} + +void Prog::on_stop() +{ + int devno = device_list.get_cur_value(); + if (devno < 0 || devno >= num_haptics) { + log_printf("No such device %d\n", devno); + return; + } + + Haptic *haptic = haptics + devno; + if (haptic->playing && al_is_haptic_effect_playing(&haptic->id)) { + al_stop_haptic_effect(&haptic->id); + haptic->playing = false; + al_release_haptic_effect(&haptic->id); + log_printf("Stopped device %d: %s\n", devno, haptic->name); + } + message_label.set_text("Stopped."); + play_button.set_disabled(false); +} + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + al_install_joystick(); + if (!al_install_haptic()) { + abort_example("Could not init haptics\n"); + } + + al_init_font_addon(); + al_init_ttf_addon(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(800, 600); + if (!display) { + abort_example("Unable to create display\n"); + } + + open_log(); + + font = al_load_font("data/DejaVuSans.ttf", 11, 0); + if (!font) { + log_printf("Failed to load data/DejaVuSans.ttf\n"); + font = al_create_builtin_font(); + if (!font) { + abort_example("Could not create builtin font.\n"); + } + } + + + joystick_queue = al_create_event_queue(); + if (!joystick_queue) { + abort_example("Could not create joystick event queue font.\n"); + } + + al_register_event_source(joystick_queue, al_get_joystick_event_source()); + + + get_all_haptics(); + + /* Don't remove these braces. */ + { + /* Set up a timer so the display of playback state is polled regularly. */ + update_timer = al_create_timer(1.0); + Theme theme(font); + Prog prog(theme, display); + al_start_timer(update_timer); + prog.run(); + al_destroy_timer(update_timer); + } + + release_all_haptics(); + al_destroy_event_queue(joystick_queue); + + close_log(false); + + al_destroy_font(font); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_icon.c b/allegro/examples/ex_icon.c new file mode 100644 index 00000000..998ffcf3 --- /dev/null +++ b/allegro/examples/ex_icon.c @@ -0,0 +1,77 @@ +#include +#include "allegro5/allegro_image.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *icon1; + ALLEGRO_BITMAP *icon2; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + int i; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + display = al_create_display(320, 200); + if (!display) { + abort_example("Error creating display\n"); + } + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_flip_display(); + + /* First icon: Read from file. */ + icon1 = al_load_bitmap("data/icon.tga"); + if (!icon1) { + abort_example("icon.tga not found\n"); + } + + /* Second icon: Create it. */ + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + icon2 = al_create_bitmap(16, 16); + al_set_target_bitmap(icon2); + for (i = 0; i < 256; i++) { + int u = i % 16; + int v = i / 16; + al_put_pixel(u, v, al_map_rgb_f(u / 15.0, v / 15.0, 1)); + } + al_set_target_backbuffer(display); + + al_set_window_title(display, "Changing icon example"); + + timer = al_create_timer(0.5); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + for (;;) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + if (event.type == ALLEGRO_EVENT_TIMER) { + al_set_display_icon(display, (event.timer.count & 1) ? icon2 : icon1); + } + } + + al_uninstall_system(); + + return 0; +} diff --git a/allegro/examples/ex_icon2.c b/allegro/examples/ex_icon2.c new file mode 100644 index 00000000..a13e596d --- /dev/null +++ b/allegro/examples/ex_icon2.c @@ -0,0 +1,90 @@ +/* + * Example program for the Allegro library. + * + * Set multiple window icons, a big one and a small one. + * The small would would be used for the task bar, + * and the big one for the alt-tab popup, for example. + */ + +#define ALLEGRO_UNSTABLE +#include +#include "allegro5/allegro_image.h" + +#ifdef ALLEGRO_UNIX +#include +#endif + +#include "common.c" + +#define NUM_ICONS 2 + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *icons[NUM_ICONS]; + ALLEGRO_EVENT_QUEUE *queue; + int u, v; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + /* First icon 16x16: Read from file. */ + icons[0] = al_load_bitmap("data/cursor.tga"); + if (!icons[0]) { + abort_example("icons.tga not found\n"); + } + +#if defined(ALLEGRO_UNIX) && !defined(ALLEGRO_RASPBERRYPI) + al_x_set_initial_icon(icons[0]); +#endif + + display = al_create_display(320, 200); + if (!display) { + abort_example("Error creating display\n"); + } + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_flip_display(); + + /* Second icon 32x32: Create it. */ + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + icons[1] = al_create_bitmap(32, 32); + al_set_target_bitmap(icons[1]); + for (v = 0; v < 32; v++) { + for (u = 0; u < 32; u++) { + al_put_pixel(u, v, al_map_rgb_f(u / 31.0, v / 31.0, 1)); + } + } + al_set_target_backbuffer(display); + + al_set_display_icons(display, NUM_ICONS, icons); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + for (;;) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + } + + al_uninstall_system(); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_inject_events.c b/allegro/examples/ex_inject_events.c new file mode 100644 index 00000000..d7545bea --- /dev/null +++ b/allegro/examples/ex_inject_events.c @@ -0,0 +1,74 @@ +/* + * Ryan Roden-Corrent + * Example that injects regular (non-user-type) allegro events into a queue. + * This could be useful for 'faking' certain event sources. + * For example, you could imitate joystick events without a * joystick. + * + * Based on the ex_user_events.c example. + */ + +#include +#include "allegro5/allegro.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_EVENT_SOURCE fake_src; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT fake_keydown_event, fake_joystick_event; + ALLEGRO_EVENT event; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + /* register our 'fake' event source with the queue */ + al_init_user_event_source(&fake_src); + queue = al_create_event_queue(); + al_register_event_source(queue, &fake_src); + + /* fake a joystick event */ + fake_joystick_event.any.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + fake_joystick_event.joystick.stick = 1; + fake_joystick_event.joystick.axis = 0; + fake_joystick_event.joystick.pos = 0.5; + al_emit_user_event(&fake_src, &fake_joystick_event, NULL); + + /* fake a keyboard event */ + fake_keydown_event.any.type = ALLEGRO_EVENT_KEY_DOWN; + fake_keydown_event.keyboard.keycode = ALLEGRO_KEY_ENTER; + al_emit_user_event(&fake_src, &fake_keydown_event, NULL); + + /* poll for the events we injected */ + while (!al_is_event_queue_empty(queue)) { + al_wait_for_event(queue, &event); + + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + ALLEGRO_ASSERT(event.user.source == &fake_src); + log_printf("Got keydown: %d\n", event.keyboard.keycode); + break; + case ALLEGRO_EVENT_JOYSTICK_AXIS: + ALLEGRO_ASSERT(event.user.source == &fake_src); + log_printf("Got joystick axis: stick=%d axis=%d pos=%f\n", + event.joystick.stick, event.joystick.axis, event.joystick.pos); + break; + } + } + + al_destroy_user_event_source(&fake_src); + al_destroy_event_queue(queue); + + log_printf("Done.\n"); + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_joystick_events.c b/allegro/examples/ex_joystick_events.c new file mode 100644 index 00000000..e996ed5c --- /dev/null +++ b/allegro/examples/ex_joystick_events.c @@ -0,0 +1,261 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * This program tests joystick events. + */ + +#include +#include +#include + +#include "common.c" + +#define MAX_AXES 3 +#define MAX_STICKS 16 +#define MAX_BUTTONS 32 + + +/* globals */ +ALLEGRO_EVENT_QUEUE *event_queue; +ALLEGRO_FONT *font; +ALLEGRO_COLOR black; +ALLEGRO_COLOR grey; +ALLEGRO_COLOR white; + +int num_sticks = 0; +int num_buttons = 0; +int num_axes[MAX_STICKS] = { 0 }; +float joys[MAX_STICKS][MAX_AXES] = {{ 0 }}; +bool joys_buttons[MAX_BUTTONS] = { 0 }; + + +static void setup_joystick_values(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_STATE jst; + int i, j; + + if (joy == NULL) { + num_sticks = 0; + num_buttons = 0; + return; + } + + al_get_joystick_state(joy, &jst); + + num_sticks = al_get_joystick_num_sticks(joy); + if (num_sticks > MAX_STICKS) + num_sticks = MAX_STICKS; + for (i = 0; i < num_sticks; i++) { + num_axes[i] = al_get_joystick_num_axes(joy, i); + for (j = 0; j < num_axes[i]; ++j) + joys[i][j] = jst.stick[i].axis[j]; + } + + num_buttons = al_get_joystick_num_buttons(joy); + if (num_buttons > MAX_BUTTONS) { + num_buttons = MAX_BUTTONS; + } + for (i = 0; i < num_buttons; i++) { + joys_buttons[i] = (jst.button[i] >= 16384); + } +} + + + +static void draw_joystick_axes(ALLEGRO_JOYSTICK *joy, int cx, int cy, int stick) +{ + const int size = 30; + const int csize = 5; + const int osize = size + csize; + int zx = cx + osize + csize * 2; + int x = cx + joys[stick][0] * size; + int y = cy + joys[stick][1] * size; + int z = cy + joys[stick][2] * size; + int i; + + al_draw_filled_rectangle(cx-osize, cy-osize, cx+osize, cy+osize, grey); + al_draw_rectangle(cx-osize+0.5, cy-osize+0.5, cx+osize-0.5, cy+osize-0.5, black, 0); + al_draw_filled_rectangle(x-5, y-5, x+5, y+5, black); + + if (num_axes[stick] >= 3) { + al_draw_filled_rectangle(zx-csize, cy-osize, zx+csize, cy+osize, grey); + al_draw_rectangle(zx-csize+0.5f, cy-osize+0.5f, zx+csize-0.5f, cy+osize-0.5f, black, 0); + al_draw_filled_rectangle(zx-5, z-5, zx+5, z+5, black); + } + + if (joy) { + al_draw_text(font, black, cx, cy + osize + 1, ALLEGRO_ALIGN_CENTRE, + al_get_joystick_stick_name(joy, stick)); + for (i = 0; i < num_axes[stick]; i++) { + al_draw_text(font, black, cx, cy + osize + (1 + i) * 10, + ALLEGRO_ALIGN_CENTRE, + al_get_joystick_axis_name(joy, stick, i)); + } + } +} + + + +static void draw_joystick_button(ALLEGRO_JOYSTICK *joy, int button, bool down) +{ + ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); + int x = al_get_bitmap_width(bmp)/2-120 + (button % 8) * 30; + int y = al_get_bitmap_height(bmp)-120 + (button / 8) * 30; + ALLEGRO_COLOR fg; + + al_draw_filled_rectangle(x, y, x + 25, y + 25, grey); + al_draw_rectangle(x+0.5, y+0.5, x + 24.5, y + 24.5, black, 0); + if (down) { + al_draw_filled_rectangle(x + 2, y + 2, x + 23, y + 23, black); + fg = white; + } + else { + fg = black; + } + + if (joy) { + const char *name = al_get_joystick_button_name(joy, button); + if (strlen(name) < 4) { + al_draw_text(font, fg, x + 13, y + 8, ALLEGRO_ALIGN_CENTRE, name); + } + } +} + + + +static void draw_all(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); + int width = al_get_bitmap_width(bmp); + int height = al_get_bitmap_height(bmp); + int i; + + al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); + + if (joy) { + al_draw_textf(font, black, width / 2, 10, ALLEGRO_ALIGN_CENTRE, + "Joystick: %s", al_get_joystick_name(joy)); + } + + for (i = 0; i < num_sticks; i++) { + int u = i%4; + int v = i/4; + int cx = (u + 0.5) * width/4; + int cy = (v + 0.5) * height/6; + draw_joystick_axes(joy, cx, cy, i); + } + + for (i = 0; i < num_buttons; i++) { + draw_joystick_button(joy, i, joys_buttons[i]); + } + + al_flip_display(); +} + + + +static void main_loop(void) +{ + ALLEGRO_EVENT event; + + while (true) { + if (al_is_event_queue_empty(event_queue)) + draw_all(al_get_joystick(0)); + + al_wait_for_event(event_queue, &event); + + switch (event.type) { + /* ALLEGRO_EVENT_JOYSTICK_AXIS - a joystick axis value changed. + */ + case ALLEGRO_EVENT_JOYSTICK_AXIS: + if (event.joystick.stick < MAX_STICKS && event.joystick.axis < MAX_AXES) { + joys[event.joystick.stick][event.joystick.axis] = event.joystick.pos; + } + break; + + /* ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN - a joystick button was pressed. + */ + case ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN: + joys_buttons[event.joystick.button] = true; + break; + + /* ALLEGRO_EVENT_JOYSTICK_BUTTON_UP - a joystick button was released. + */ + case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: + joys_buttons[event.joystick.button] = false; + break; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + return; + break; + + /* ALLEGRO_EVENT_DISPLAY_CLOSE - the window close button was pressed. + */ + case ALLEGRO_EVENT_DISPLAY_CLOSE: + return; + + case ALLEGRO_EVENT_JOYSTICK_CONFIGURATION: + al_reconfigure_joysticks(); + setup_joystick_values(al_get_joystick(0)); + break; + + /* We received an event of some type we don't know about. + * Just ignore it. + */ + default: + break; + } + } +} + + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_primitives_addon(); + al_init_font_addon(); + + display = al_create_display(1024, 768); + if (!display) { + abort_example("al_create_display failed\n"); + } + + al_install_keyboard(); + + black = al_map_rgb(0, 0, 0); + grey = al_map_rgb(0xe0, 0xe0, 0xe0); + white = al_map_rgb(255, 255, 255); + font = al_create_builtin_font(); + + al_install_joystick(); + + event_queue = al_create_event_queue(); + if (!event_queue) { + abort_example("al_create_event_queue failed\n"); + } + + if (al_get_keyboard_event_source()) { + al_register_event_source(event_queue, al_get_keyboard_event_source()); + } + al_register_event_source(event_queue, al_get_display_event_source(display)); + al_register_event_source(event_queue, al_get_joystick_event_source()); + + setup_joystick_values(al_get_joystick(0)); + + main_loop(); + + al_destroy_font(font); + + return 0; +} + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_joystick_hotplugging.c b/allegro/examples/ex_joystick_hotplugging.c new file mode 100644 index 00000000..569ea6fe --- /dev/null +++ b/allegro/examples/ex_joystick_hotplugging.c @@ -0,0 +1,157 @@ +#include +#include +#include + +#include "common.c" + +static void print_joystick_info(ALLEGRO_JOYSTICK *joy) +{ + int i, n, a; + + if (!joy) + return; + + log_printf("Joystick: '%s'\n", al_get_joystick_name(joy)); + + log_printf(" Buttons:"); + n = al_get_joystick_num_buttons(joy); + for (i = 0; i < n; i++) { + log_printf(" '%s'", al_get_joystick_button_name(joy, i)); + } + log_printf("\n"); + + n = al_get_joystick_num_sticks(joy); + for (i = 0; i < n; i++) { + log_printf(" Stick %d: '%s'\n", i, al_get_joystick_stick_name(joy, i)); + + for (a = 0; a < al_get_joystick_num_axes(joy, i); a++) { + log_printf(" Axis %d: '%s'\n", + a, al_get_joystick_axis_name(joy, i, a)); + } + } +} + +static void draw(ALLEGRO_JOYSTICK *curr_joy) +{ + int x = 100; + int y = 100; + ALLEGRO_JOYSTICK_STATE joystate; + int i; + + al_clear_to_color(al_map_rgb(0, 0, 0)); + + if (curr_joy) { + al_get_joystick_state(curr_joy, &joystate); + for (i = 0; i < al_get_joystick_num_sticks(curr_joy); i++) { + al_draw_filled_circle( + x+joystate.stick[i].axis[0]*20 + i * 80, + y+joystate.stick[i].axis[1]*20, + 20, al_map_rgb(255, 255, 255) + ); + } + for (i = 0; i < al_get_joystick_num_buttons(curr_joy); i++) { + if (joystate.button[i]) { + al_draw_filled_circle( + i*20+10, 400, 9, al_map_rgb(255, 255, 255) + ); + } + } + } + + al_flip_display(); +} + +int main(int argc, char **argv) +{ + int num_joysticks; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_JOYSTICK *curr_joy; + ALLEGRO_DISPLAY *display; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + if (!al_install_joystick()) { + abort_example("Could not init joysticks.\n"); + } + al_install_keyboard(); + al_init_primitives_addon(); + + open_log(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display.\n"); + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_joystick_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + num_joysticks = al_get_num_joysticks(); + log_printf("Num joysticks: %d\n", num_joysticks); + + if (num_joysticks > 0) { + curr_joy = al_get_joystick(0); + print_joystick_info(curr_joy); + } + else { + curr_joy = NULL; + } + + draw(curr_joy); + + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + else if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + int n = event.keyboard.unichar - '0'; + if (n >= 0 && n < num_joysticks) { + curr_joy = al_get_joystick(n); + log_printf("switching to joystick %d\n", n); + print_joystick_info(curr_joy); + } + } + else if (event.type == ALLEGRO_EVENT_JOYSTICK_CONFIGURATION) { + al_reconfigure_joysticks(); + num_joysticks = al_get_num_joysticks(); + log_printf("after reconfiguration num joysticks = %d\n", + num_joysticks); + if (curr_joy) { + log_printf("current joystick is: %s\n", + al_get_joystick_active(curr_joy) ? "active" : "inactive"); + } + curr_joy = al_get_joystick(0); + } + else if (event.type == ALLEGRO_EVENT_JOYSTICK_AXIS) { + log_printf("axis event from %p, stick %d, axis %d\n", event.joystick.id, event.joystick.stick, event.joystick.axis); + } + else if (event.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN) { + log_printf("button down event %d from %p\n", + event.joystick.button, event.joystick.id); + } + else if (event.type == ALLEGRO_EVENT_JOYSTICK_BUTTON_UP) { + log_printf("button up event %d from %p\n", + event.joystick.button, event.joystick.id); + } + + draw(curr_joy); + } + + close_log(false); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_kcm_direct.c b/allegro/examples/ex_kcm_direct.c new file mode 100644 index 00000000..938679f5 --- /dev/null +++ b/allegro/examples/ex_kcm_direct.c @@ -0,0 +1,104 @@ +/* Shows the ability to play a sample without a mixer. */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" + +#include "common.c" + +char *default_files[] = {NULL, "data/welcome.wav"}; + +int main(int argc, char **argv) +{ + ALLEGRO_VOICE *voice; + ALLEGRO_SAMPLE_INSTANCE *sample; + int i; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + if (argc < 2) { + log_printf("This example can be run from the command line.\nUsage: %s {audio_files}\n", argv[0]); + argv = default_files; + argc = 2; + } + + al_init_acodec_addon(); + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + + for (i = 1; i < argc; ++i) { + ALLEGRO_SAMPLE *sample_data = NULL; + const char *filename = argv[i]; + ALLEGRO_CHANNEL_CONF chan; + ALLEGRO_AUDIO_DEPTH depth; + unsigned long freq; + float sample_time = 0; + + /* Load the entire sound file from disk. */ + sample_data = al_load_sample(filename); + if (!sample_data) { + log_printf("Could not load sample from '%s'!\n", + filename); + continue; + } + + sample = al_create_sample_instance(NULL); + if (!sample) { + abort_example("al_create_sample failed.\n"); + } + + if (!al_set_sample(sample, sample_data)) { + log_printf("al_set_sample failed.\n"); + continue; + } + + depth = al_get_sample_instance_depth(sample); + chan = al_get_sample_instance_channels(sample); + freq = al_get_sample_instance_frequency(sample); + log_printf("Loaded sample: %i-bit depth, %i channels, %li Hz\n", + (depth < 8) ? (8+depth*8) : 0, (chan>>4)+(chan%0xF), freq); + log_printf("Trying to create a voice with the same specs... "); + voice = al_create_voice(freq, depth, chan); + if (!voice) { + abort_example("Could not create ALLEGRO_VOICE.\n"); + } + log_printf("done.\n"); + + if (!al_attach_sample_instance_to_voice(sample, voice)) { + abort_example("al_attach_sample_instance_to_voice failed.\n"); + } + + /* Play sample in looping mode. */ + al_set_sample_instance_playmode(sample, ALLEGRO_PLAYMODE_LOOP); + al_play_sample_instance(sample); + + sample_time = al_get_sample_instance_time(sample); + log_printf("Playing '%s' (%.3f seconds) 3 times", filename, + sample_time); + + al_rest(sample_time * 3); + + al_stop_sample_instance(sample); + log_printf("\n"); + + /* Free the memory allocated. */ + al_set_sample(sample, NULL); + al_destroy_sample(sample_data); + al_destroy_sample_instance(sample); + al_destroy_voice(voice); + } + + al_uninstall_audio(); + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_keyboard_events.c b/allegro/examples/ex_keyboard_events.c new file mode 100644 index 00000000..3d516bd2 --- /dev/null +++ b/allegro/examples/ex_keyboard_events.c @@ -0,0 +1,150 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * Updated by Ryan Dickie. + * + * This program tests keyboard events. + */ + +#include +#define ALLEGRO_UNSTABLE +#include + +#include "common.c" + +#define WIDTH 640 +#define HEIGHT 480 +#define SIZE_LOG 50 + + +/* globals */ +ALLEGRO_EVENT_QUEUE *event_queue; +ALLEGRO_DISPLAY *display; + + + +static void log_key(char const *how, int keycode, int unichar, int modifiers) +{ + char multibyte[5] = {0, 0, 0, 0, 0}; + const char* key_name; + + al_utf8_encode(multibyte, unichar <= 32 ? ' ' : unichar); + key_name = al_keycode_to_name(keycode); + log_printf("%-8s code=%03d, char='%s' (%4d), modifiers=%08x, [%s]\n", + how, keycode, multibyte, unichar, modifiers, key_name); +} + + + +/* main_loop: + * The main loop of the program. Here we wait for events to come in from + * any one of the event sources and react to each one accordingly. While + * there are no events to react to the program sleeps and consumes very + * little CPU time. See main() to see how the event sources and event queue + * are set up. + */ +static void main_loop(void) +{ + ALLEGRO_EVENT event; + + log_printf("Focus on the main window (black) and press keys to see events. "); + log_printf("Escape quits.\n\n"); + + while (true) { + /* Take the next event out of the event queue, and store it in `event'. */ + al_wait_for_event(event_queue, &event); + + /* Check what type of event we got and act accordingly. ALLEGRO_EVENT + * is a union type and interpretation of its contents is dependent on + * the event type, which is given by the 'type' field. + * + * Each event also comes from an event source and has a timestamp. + * These are accessible through the 'any.source' and 'any.timestamp' + * fields respectively, e.g. 'event.any.timestamp' + */ + switch (event.type) { + + /* ALLEGRO_EVENT_KEY_DOWN - a keyboard key was pressed. + */ + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + return; + } + log_key("KEY_DOWN", event.keyboard.keycode, 0, 0); + break; + + /* ALLEGRO_EVENT_KEY_UP - a keyboard key was released. + */ + case ALLEGRO_EVENT_KEY_UP: + log_key("KEY_UP", event.keyboard.keycode, 0, 0); + break; + + /* ALLEGRO_EVENT_KEY_CHAR - a character was typed or repeated. + */ + case ALLEGRO_EVENT_KEY_CHAR: { + char const *label = (event.keyboard.repeat ? "repeat" : "KEY_CHAR"); + log_key(label, + event.keyboard.keycode, + event.keyboard.unichar, + event.keyboard.modifiers); + break; + } + + /* ALLEGRO_EVENT_DISPLAY_CLOSE - the window close button was pressed. + */ + case ALLEGRO_EVENT_DISPLAY_CLOSE: + return; + + case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: + al_clear_keyboard_state(event.display.source); + log_printf("Cleared keyboard state\n"); + break; + + /* We received an event of some type we don't know about. + * Just ignore it. + */ + default: + break; + } + } +} + + + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log_monospace(); + + display = al_create_display(WIDTH, HEIGHT); + if (!display) { + abort_example("al_create_display failed\n"); + } + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_flip_display(); + + if (!al_install_keyboard()) { + abort_example("al_install_keyboard failed\n"); + } + + event_queue = al_create_event_queue(); + if (!event_queue) { + abort_example("al_create_event_queue failed\n"); + } + + al_register_event_source(event_queue, al_get_keyboard_event_source()); + al_register_event_source(event_queue, al_get_display_event_source(display)); + + main_loop(); + + close_log(false); + + return 0; +} + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_keyboard_focus.c b/allegro/examples/ex_keyboard_focus.c new file mode 100644 index 00000000..dc3d921b --- /dev/null +++ b/allegro/examples/ex_keyboard_focus.c @@ -0,0 +1,74 @@ +/* + * Example program for the Allegro library. + * + * This program tests if the ALLEGRO_KEYBOARD_STATE `display' field + * is set correctly to the focused display. + */ + +#include "allegro5/allegro.h" + +#include "common.c" + +static ALLEGRO_DISPLAY *display1; +static ALLEGRO_DISPLAY *display2; + +static void redraw(ALLEGRO_COLOR color1, ALLEGRO_COLOR color2) +{ + al_set_target_backbuffer(display1); + al_clear_to_color(color1); + al_flip_display(); + + al_set_target_backbuffer(display2); + al_clear_to_color(color2); + al_flip_display(); +} + +int main(int argc, char **argv) +{ + ALLEGRO_COLOR black; + ALLEGRO_COLOR red; + ALLEGRO_KEYBOARD_STATE kbdstate; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Error initialising Allegro.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + display1 = al_create_display(300, 300); + display2 = al_create_display(300, 300); + if (!display1 || !display2) { + abort_example("Error creating displays.\n"); + } + + black = al_map_rgb(0, 0, 0); + red = al_map_rgb(255, 0, 0); + + while (1) { + al_get_keyboard_state(&kbdstate); + if (al_key_down(&kbdstate, ALLEGRO_KEY_ESCAPE)) { + break; + } + + if (kbdstate.display == display1) { + redraw(red, black); + } + else if (kbdstate.display == display2) { + redraw(black, red); + } + else { + redraw(black, black); + } + + al_rest(0.1); + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_lines.c b/allegro/examples/ex_lines.c new file mode 100644 index 00000000..58022bf7 --- /dev/null +++ b/allegro/examples/ex_lines.c @@ -0,0 +1,178 @@ +/* + * This example exercises line drawing, and single buffer mode. + */ + +#include +#include "allegro5/allegro.h" +#include + +#include "common.c" + +/* XXX the software line drawer currently doesn't perform clipping properly */ + +const int W = 640; +const int H = 480; + +ALLEGRO_DISPLAY *display; +ALLEGRO_EVENT_QUEUE *queue; +ALLEGRO_COLOR black; +ALLEGRO_COLOR white; +ALLEGRO_COLOR background; +ALLEGRO_BITMAP *dbuf; + +int last_x = -1; +int last_y = -1; + + +static void fade(void) +{ + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + al_draw_filled_rectangle(0, 0, W, H, al_map_rgba_f(0.5, 0.5, 0.6, 0.2)); +} + +static void red_dot(int x, int y) +{ + al_draw_filled_rectangle(x - 2, y - 2, x + 2, y + 2, al_map_rgb_f(1, 0, 0)); +} + +static void draw_clip_rect(void) +{ + al_draw_rectangle(100.5, 100.5, W - 100.5, H - 100.5, black, 0); +} + +static void my_set_clip_rect(void) +{ + al_set_clipping_rectangle(100, 100, W - 200, H - 200); +} + +static void reset_clip_rect(void) +{ + al_set_clipping_rectangle(0, 0, W, H); +} + +static void flip(void) +{ + al_set_target_backbuffer(display); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_bitmap(dbuf, 0.0, 0.0, 0); + al_flip_display(); +} + +static void plonk(const int x, const int y, bool blend) +{ + al_set_target_bitmap(dbuf); + + fade(); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ZERO); + draw_clip_rect(); + red_dot(x, y); + + if (last_x == -1 && last_y == -1) { + last_x = x; + last_y = y; + } + else { + my_set_clip_rect(); + if (blend) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + } + al_draw_line(last_x, last_y, x, y, white, 0); + last_x = last_y = -1; + reset_clip_rect(); + } + + flip(); +} + +static void splat(const int x, const int y, bool blend) +{ + double theta; + + al_set_target_bitmap(dbuf); + + fade(); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ZERO); + draw_clip_rect(); + red_dot(x, y); + + my_set_clip_rect(); + if (blend) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + } + for (theta = 0.0; theta < 2.0 * ALLEGRO_PI; theta += ALLEGRO_PI/16.0) { + al_draw_line(x, y, x + 40.0 * cos(theta), y + 40.0 * sin(theta), white, 0); + } + reset_clip_rect(); + + flip(); +} + +int main(int argc, char **argv) +{ + ALLEGRO_EVENT event; + ALLEGRO_KEYBOARD_STATE kst; + bool blend; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + + display = al_create_display(W, H); + if (!display) { + abort_example("Error creating display\n"); + } + + black = al_map_rgb_f(0.0, 0.0, 0.0); + white = al_map_rgb_f(1.0, 1.0, 1.0); + background = al_map_rgb_f(0.5, 0.5, 0.6); + + if (argc > 1 && 0 == strcmp(argv[1], "--memory-bitmap")) { + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + } + dbuf = al_create_bitmap(W, H); + if (!dbuf) { + abort_example("Error creating double buffer\n"); + } + + al_set_target_bitmap(dbuf); + al_clear_to_color(background); + draw_clip_rect(); + flip(); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + + while (true) { + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + al_get_keyboard_state(&kst); + blend = al_key_down(&kst, ALLEGRO_KEY_LSHIFT) || + al_key_down(&kst, ALLEGRO_KEY_RSHIFT); + if (event.mouse.button == 1) { + plonk(event.mouse.x, event.mouse.y, blend); + } else { + splat(event.mouse.x, event.mouse.y, blend); + } + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) { + last_x = last_y = -1; + } + else if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + { + break; + } + } + + al_destroy_event_queue(queue); + al_destroy_bitmap(dbuf); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_loading_thread.c b/allegro/examples/ex_loading_thread.c new file mode 100644 index 00000000..af1c135d --- /dev/null +++ b/allegro/examples/ex_loading_thread.c @@ -0,0 +1,235 @@ +#include +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" + +static const int load_total = 100; +static int load_count = 0; +static ALLEGRO_BITMAP *bitmaps[100]; +static ALLEGRO_MUTEX *mutex; + +static void *loading_thread(ALLEGRO_THREAD *thread, void *arg) +{ + ALLEGRO_FONT *font; + ALLEGRO_COLOR text; + + font = al_load_font("data/fixed_font.tga", 0, 0); + text = al_map_rgb_f(255, 255, 255); + + /* In this example we load mysha.pcx 100 times to simulate loading + * many bitmaps. + */ + load_count = 0; + while (load_count < load_total) { + ALLEGRO_COLOR color; + ALLEGRO_BITMAP *bmp; + + color = al_map_rgb(rand() % 256, rand() % 256, rand() % 256); + color.r /= 4; + color.g /= 4; + color.b /= 4; + color.a /= 4; + + if (al_get_thread_should_stop(thread)) + break; + + bmp = al_load_bitmap("data/mysha.pcx"); + + /* Simulate different contents. */ + al_set_target_bitmap(bmp); + al_draw_filled_rectangle(0, 0, 320, 200, color); + al_draw_textf(font, text, 0, 0, 0, "bitmap %d", 1 + load_count); + al_set_target_bitmap(NULL); + + /* Allow the main thread to see the completed bitmap. */ + al_lock_mutex(mutex); + bitmaps[load_count] = bmp; + load_count++; + al_unlock_mutex(mutex); + + /* Simulate that it's slow. */ + al_rest(0.05); + } + + al_destroy_font(font); + return arg; +} + +static void print_bitmap_flags(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_USTR *ustr = al_ustr_new(""); + if (al_get_bitmap_flags(bitmap) & ALLEGRO_VIDEO_BITMAP) + al_ustr_append_cstr(ustr, " VIDEO"); + if (al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP) + al_ustr_append_cstr(ustr, " MEMORY"); + if (al_get_bitmap_flags(bitmap) & ALLEGRO_CONVERT_BITMAP) + al_ustr_append_cstr(ustr, " CONVERT"); + + al_ustr_trim_ws(ustr); + al_ustr_find_replace_cstr(ustr, 0, " ", " | "); + + log_printf("%s", al_cstr(ustr)); + al_ustr_free(ustr); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + bool redraw = true; + ALLEGRO_FONT *font; + ALLEGRO_BITMAP *spin, *spin2; + int current_bitmap = 0; + int loaded_bitmap = 0; + ALLEGRO_THREAD *thread; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_image_addon(); + al_init_font_addon(); + al_init_primitives_addon(); + init_platform_specific(); + + open_log(); + + al_install_mouse(); + al_install_keyboard(); + + spin = al_load_bitmap("data/cursor.tga"); + log_printf("default bitmap without display: %p\n", spin); + + al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); + spin2 = al_load_bitmap("data/cursor.tga"); + log_printf("video bitmap without display: %p\n", spin2); + + log_printf("%p before create_display: ", spin); + print_bitmap_flags(spin); + log_printf("\n"); + + display = al_create_display(64, 64); + if (!display) { + abort_example("Error creating display\n"); + } + + spin2 = al_load_bitmap("data/cursor.tga"); + log_printf("video bitmap with display: %p\n", spin2); + + log_printf("%p after create_display: ", spin); + print_bitmap_flags(spin); + log_printf("\n"); + + log_printf("%p after create_display: ", spin2); + print_bitmap_flags(spin2); + log_printf("\n"); + + al_destroy_display(display); + + log_printf("%p after destroy_display: ", spin); + print_bitmap_flags(spin); + log_printf("\n"); + + log_printf("%p after destroy_display: ", spin2); + print_bitmap_flags(spin2); + log_printf("\n"); + + display = al_create_display(640, 480); + + log_printf("%p after create_display: ", spin); + print_bitmap_flags(spin); + log_printf("\n"); + + log_printf("%p after create_display: ", spin2); + print_bitmap_flags(spin2); + log_printf("\n"); + + font = al_load_font("data/fixed_font.tga", 0, 0); + + mutex = al_create_mutex(); + thread = al_create_thread(loading_thread, NULL); + al_start_thread(thread); + + timer = al_create_timer(1.0 / 30); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + } + if (event.type == ALLEGRO_EVENT_TIMER) + redraw = true; + + if (redraw && al_is_event_queue_empty(queue)) { + float x = 20, y = 320; + int i; + ALLEGRO_COLOR color = al_map_rgb_f(0, 0, 0); + float t = al_current_time(); + + redraw = false; + al_clear_to_color(al_map_rgb_f(0.5, 0.6, 1)); + + al_draw_textf(font, color, x + 40, y, 0, "Loading %d%%", + 100 * load_count / load_total); + + al_lock_mutex(mutex); + if (loaded_bitmap < load_count) { + /* This will convert any video bitmaps without a display + * (all the bitmaps being loaded in the loading_thread) to + * video bitmaps we can use in the main thread. + */ + al_convert_bitmap(bitmaps[loaded_bitmap]); + loaded_bitmap++; + } + al_unlock_mutex(mutex); + + if (current_bitmap < loaded_bitmap) { + int bw; + al_draw_bitmap(bitmaps[current_bitmap], 0, 0, 0); + if (current_bitmap + 1 < loaded_bitmap) + current_bitmap++; + + for (i = 0; i <= current_bitmap; i++) { + bw = al_get_bitmap_width(bitmaps[i]); + al_draw_scaled_rotated_bitmap(bitmaps[i], + 0, 0, (i % 20) * 640 / 20, 360 + (i / 20) * 24, + 32.0 / bw, 32.0 / bw, 0, 0); + } + } + + if (loaded_bitmap < load_total) { + al_draw_scaled_rotated_bitmap(spin, + 16, 16, x, y, 1.0, 1.0, t * ALLEGRO_PI * 2, 0); + } + + al_flip_display(); + } + } + + al_join_thread(thread, NULL); + al_destroy_mutex(mutex); + al_destroy_font(font); + al_destroy_display(display); + + close_log(true); + + return 0; +} diff --git a/allegro/examples/ex_lockbitmap.c b/allegro/examples/ex_lockbitmap.c new file mode 100644 index 00000000..86dd0ae4 --- /dev/null +++ b/allegro/examples/ex_lockbitmap.c @@ -0,0 +1,222 @@ +/* + * Example program for the Allegro library. + * + * From left to right you should see Red, Green, Blue gradients. + */ + +#define ALLEGRO_UNSTABLE +#include "allegro5/allegro.h" + +#include "common.c" + +enum Mode +{ + MODE_VIDEO, + MODE_MEMORY, + MODE_BACKBUFFER +}; + +static void fill(ALLEGRO_BITMAP *bitmap, int lock_flags) +{ + ALLEGRO_LOCKED_REGION *locked; + uint8_t *ptr; + int i, j; + + /* Locking the bitmap means, we work directly with pixel data. We can + * choose the format we want to work with, which may imply conversions, or + * use the bitmap's actual format so we can work directly with the bitmap's + * pixel data. + * We use a 16-bit format and odd positions and sizes to increase the + * chances of uncovering bugs. + */ + locked = al_lock_bitmap_region(bitmap, 193, 65, 3*127, 127, + ALLEGRO_PIXEL_FORMAT_RGB_565, lock_flags); + if (!locked) + return; + + for (j = 0; j < 127; j++) { + ptr = (uint8_t *)locked->data + j * locked->pitch; + + for (i = 0; i < 3*127; i++) { + uint8_t red; + uint8_t green; + uint8_t blue; + uint16_t col; + uint16_t *cptr = (uint16_t *)ptr; + + if (j == 0 || j == 126 || i == 0 || i == 3*127-1) { + red = green = blue = 0; + } + else if (i < 127) { + red = 255; + green = blue = j*2; + } + else if (i < 2*127) { + green = 255; + red = blue = j*2; + } + else { + blue = 255; + red = green = j*2; + } + + /* The RGB_555 format means, the 16 bits per pixel are laid out like + * this, least significant bit right: RRRRR GGGGGG BBBBB + * Because the byte order can vary per platform (big endian or + * little endian) we encode an integer and store that + * directly rather than storing each component separately. + * + * In READWRITE mode the light blue background should should through + * the stipple pattern. + */ + if ((lock_flags & ALLEGRO_LOCK_WRITEONLY) || (j + i) % 2 == 1) { + col = ((red/8) << 11) | ((green/4) << 5) | (blue/8); + *cptr = col; + } + ptr += 2; + } + } + al_unlock_bitmap(bitmap); +} + +static void draw(ALLEGRO_DISPLAY *display, enum Mode mode, int lock_flags) +{ + ALLEGRO_BITMAP *bitmap; + + /* Create the bitmap to lock, or use the display backbuffer. */ + if (mode == MODE_VIDEO) { + log_printf("Locking video bitmap"); + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); + bitmap = al_create_bitmap(3*256, 256); + } + else if (mode == MODE_MEMORY) { + log_printf("Locking memory bitmap"); + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + bitmap = al_create_bitmap(3*256, 256); + } + else { + log_printf("Locking display backbuffer"); + bitmap = al_get_backbuffer(display); + } + if (!bitmap) { + abort_example("Error creating bitmap"); + } + + if (lock_flags & ALLEGRO_LOCK_WRITEONLY) { + log_printf(" in write-only mode\n"); + } + else { + log_printf(" in read/write mode\n"); + } + + al_set_target_bitmap(bitmap); + al_clear_to_color(al_map_rgb_f(0.8, 0.8, 0.9)); + al_set_target_backbuffer(display); + + fill(bitmap, lock_flags); + + if (mode != MODE_BACKBUFFER) { + al_draw_bitmap(bitmap, 0, 0, 0); + al_destroy_bitmap(bitmap); + bitmap = NULL; + } + + al_flip_display(); +} + +static enum Mode cycle_mode(enum Mode mode) +{ + switch (mode) { + case MODE_VIDEO: + return MODE_MEMORY; + case MODE_MEMORY: + return MODE_BACKBUFFER; + case MODE_BACKBUFFER: + default: + return MODE_VIDEO; + } +} + +static int toggle_writeonly(int lock_flags) +{ + return lock_flags ^ ALLEGRO_LOCK_WRITEONLY; +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *events; + ALLEGRO_EVENT event; + enum Mode mode = MODE_VIDEO; + int lock_flags = ALLEGRO_LOCK_WRITEONLY; + bool redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + al_install_mouse(); + al_install_touch_input(); + + open_log(); + + /* Create a window. */ + display = al_create_display(3*256, 256); + if (!display) { + abort_example("Error creating display\n"); + } + + events = al_create_event_queue(); + al_register_event_source(events, al_get_keyboard_event_source()); + al_register_event_source(events, al_get_mouse_event_source()); + if (al_is_touch_input_installed()) { + al_register_event_source(events, + al_get_touch_input_mouse_emulation_event_source()); + } + + log_printf("Press space to change bitmap type\n"); + log_printf("Press w to toggle WRITEONLY mode\n"); + + for (;;) { + if (redraw) { + draw(display, mode, lock_flags); + redraw = false; + } + + al_wait_for_event(events, &event); + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + if (event.keyboard.unichar == ' ') { + mode = cycle_mode(mode); + redraw = true; + } + else if (event.keyboard.unichar == 'w' || event.keyboard.unichar == 'W') { + lock_flags = toggle_writeonly(lock_flags); + redraw = true; + } + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + if (event.mouse.button == 1) { + if (event.mouse.x < al_get_display_width(display) / 2) { + mode = cycle_mode(mode); + } + else { + lock_flags = toggle_writeonly(lock_flags); + } + redraw = true; + } + } + } + + close_log(false); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_logo.c b/allegro/examples/ex_logo.c new file mode 100644 index 00000000..e72d2ffc --- /dev/null +++ b/allegro/examples/ex_logo.c @@ -0,0 +1,536 @@ +/* Demo program which creates a logo by direct pixel manipulation of + * bitmaps. Also uses alpha blending to create a real-time flash + * effect (likely not visible with displays using memory bitmaps as it + * is too slow). + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "common.c" + +#ifdef ALLEGRO_MSVC + #define snprintf _snprintf +#endif + +static ALLEGRO_BITMAP *logo, *logo_flash; +static int logo_x, logo_y; +static ALLEGRO_FONT *font; +static int cursor; +static int selection; +static bool regenerate = 0, editing = 0; +static ALLEGRO_CONFIG *config; +static ALLEGRO_COLOR white; +static double anim; + +static float clamp(float x) +{ + if (x < 0) + return 0; + if (x > 1) + return 1; + return x; +} + +static char const *param_names[] = { + "text", "font", "size", "shadow", "blur", "factor", "red", "green", + "blue", NULL +}; + +/* Note: To regenerate something close to the official Allegro logo, + * you need to obtain the non-free "Utopia Regular Italic" font. Then + * replace "DejaVuSans.ttf" with "putri.pfa" below. + */ +static char param_values[][256] = { + "Allegro", "data/DejaVuSans.ttf", "140", "10", "2", "0.5", "1.1", + "1.5", "5" +}; + +/* Generates a bitmap with transparent background and the logo text. + * The bitmap will have screen size. If 'bumpmap' is not NULL, it will + * contain another bitmap which is a white, blurred mask of the logo + * which we use for the flash effect. + */ +static ALLEGRO_BITMAP *generate_logo(char const *text, + char const *fontname, + int font_size, + float shadow_offset, + float blur_radius, + float blur_factor, + float light_red, + float light_green, + float light_blue, + ALLEGRO_BITMAP **bumpmap) +{ + ALLEGRO_COLOR transparent = al_map_rgba_f(0, 0, 0, 0); + int xp, yp, w, h, i, j, x, y, br, bw, dw, dh; + ALLEGRO_COLOR c; + ALLEGRO_FONT *logofont; + ALLEGRO_STATE state; + ALLEGRO_BITMAP *blur, *light, *logo; + int left, right, top, bottom; + float cx, cy; + + dw = al_get_bitmap_width(al_get_target_bitmap()); + dh = al_get_bitmap_height(al_get_target_bitmap()); + + cx = dw * 0.5; + cy = dh * 0.5; + + logofont = al_load_font(fontname, -font_size, 0); + al_get_text_dimensions(logofont, text, &xp, &yp, &w, &h); + + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); + + /* Cheap blur effect to create a bump map. */ + blur = al_create_bitmap(dw, dh); + al_set_target_bitmap(blur); + al_clear_to_color(transparent); + br = blur_radius; + bw = br * 2 + 1; + c = al_map_rgba_f(1, 1, 1, 1.0 / (bw * bw * blur_factor)); + al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, + ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + for (i = -br; i <= br; i++) { + for (j = -br; j <= br; j++) { + al_draw_text(logofont, c, + cx - xp * 0.5 - w * 0.5 + i, + cy - yp * 0.5 - h * 0.5 + j, 0, text); + } + } + + left = cx - xp * 0.5 - w * 0.5 - br + xp; + top = cy - yp * 0.5 - h * 0.5 - br + yp; + right = left + w + br * 2; + bottom = top + h + br * 2; + + if (left < 0) + left = 0; + if (top < 0) + top = 0; + if (right > dw - 1) + right = dw - 1; + if (bottom > dh - 1) + bottom = dh - 1; + + /* Cheap light effect. */ + light = al_create_bitmap(dw, dh); + al_set_target_bitmap(light); + al_clear_to_color(transparent); + al_lock_bitmap(blur, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + al_lock_bitmap_region(light, left, top, + 1 + right - left, 1 + bottom - top, + ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); + for (y = top; y <= bottom; y++) { + for (x = left; x <= right; x++) { + float r1, g1, b1, a1; + float r2, g2, b2, a2; + float r, g, b, a; + float d; + ALLEGRO_COLOR c = al_get_pixel(blur, x, y); + ALLEGRO_COLOR c1 = al_get_pixel(blur, x - 1, y - 1); + ALLEGRO_COLOR c2 = al_get_pixel(blur, x + 1, y + 1); + al_unmap_rgba_f(c, &r, &g, &b, &a); + al_unmap_rgba_f(c1, &r1, &g1, &b1, &a1); + al_unmap_rgba_f(c2, &r2, &g2, &b2, &a2); + + d = r2 - r1 + 0.5; + r = clamp(d * light_red); + g = clamp(d * light_green); + b = clamp(d * light_blue); + + c = al_map_rgba_f(r, g, b, a); + al_put_pixel(x, y, c); + } + } + al_unlock_bitmap(light); + al_unlock_bitmap(blur); + + if (bumpmap) + *bumpmap = blur; + else + al_destroy_bitmap(blur); + + /* Create final logo */ + logo = al_create_bitmap(dw, dh); + al_set_target_bitmap(logo); + al_clear_to_color(transparent); + + /* Draw a shadow. */ + c = al_map_rgba_f(0, 0, 0, 0.5 / 9); + al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, + ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + for (i = -1; i <= 1; i++) + for (j = -1; j <= 1; j++) + al_draw_text(logofont, c, + cx - xp * 0.5 - w * 0.5 + shadow_offset + i, + cy - yp * 0.5 - h * 0.5 + shadow_offset + j, + 0, text); + + /* Then draw the lit text we made before on top. */ + al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, + ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_bitmap(light, 0, 0, 0); + al_destroy_bitmap(light); + + al_restore_state(&state); + al_destroy_font(logofont); + + return logo; +} + +/* Draw the checkerboard background. */ +static void draw_background(void) +{ + ALLEGRO_COLOR c[2]; + int i, j; + c[0] = al_map_rgba(0xaa, 0xaa, 0xaa, 0xff); + c[1] = al_map_rgba(0x99, 0x99, 0x99, 0xff); + + for (i = 0; i < 640 / 16; i++) { + for (j = 0; j < 480 / 16; j++) { + al_draw_filled_rectangle(i * 16, j * 16, + i * 16 + 16, j * 16 + 16, + c[(i + j) & 1]); + } + } +} + +/* Print out the current logo parameters. */ +static void print_parameters(void) +{ + int i; + ALLEGRO_STATE state; + ALLEGRO_COLOR normal = al_map_rgba_f(0, 0, 0, 1); + ALLEGRO_COLOR light = al_map_rgba_f(0, 0, 1, 1); + ALLEGRO_COLOR label = al_map_rgba_f(0.2, 0.2, 0.2, 1); + int th; + + al_store_state(&state, ALLEGRO_STATE_BLENDER); + + th = al_get_font_line_height(font) + 3; + for (i = 0; param_names[i]; i++) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, label, 2, 2 + i * th, 0, "%s", param_names[i]); + } + for (i = 0; param_names[i]; i++) { + int y = 2 + i * th; + al_draw_filled_rectangle(75, y, 375, y + th - 2, + al_map_rgba_f(0.5, 0.5, 0.5, 0.5)); + al_draw_textf(font, i == selection ? light : normal, 75, y, 0, "%s", param_values[i]); + if (i == selection && editing && + (((int)(al_get_time() * 2)) & 1)) { + int x = 75 + al_get_text_width(font, param_values[i]); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_line(x, y, x, y + th, white, 0); + } + } + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, normal, 400, 2, 0, "%s", "R - Randomize"); + al_draw_textf(font, normal, 400, 2 + th, 0, "%s", "S - Save as logo.png"); + + al_draw_textf(font, normal, 2, 480 - th * 2 - 2, 0, "%s", + "To modify, press Return, then enter value, " + "then Return again."); + al_draw_textf(font, normal, 2, 480 - th - 2, 0, "%s", + "Use cursor up/down to " + "select the value to modify."); + al_restore_state(&state); +} + +static char const *rnum(float min, float max) +{ + static char s[256]; + double x = rand() / (double)RAND_MAX; + x = min + x * (max - min); + snprintf(s, sizeof s, "%.1f", x); + return s; +} + +static void randomize(void) +{ + strcpy(param_values[3], rnum(2, 12)); + strcpy(param_values[4], rnum(1, 8)); + strcpy(param_values[5], rnum(0.1, 1)); + strcpy(param_values[6], rnum(0, 5)); + strcpy(param_values[7], rnum(0, 5)); + strcpy(param_values[8], rnum(0, 5)); + regenerate = true; +} + +static void save(void) +{ + al_save_bitmap("logo.png", logo); +} + +static void mouse_click(int x, int y) +{ + int th = al_get_font_line_height(font) + 3; + int sel = (y - 2) / th; + int i; + if (x < 400) { + for (i = 0; param_names[i]; i++) { + if (sel == i) { + selection = i; + cursor = 0; + editing = true; + } + } + } + else if (x < 500) { + if (sel == 0) + randomize(); + if (sel == 1) + save(); + } +} + +static void render(void) +{ + double t = al_get_time(); + if (regenerate) { + al_destroy_bitmap(logo); + al_destroy_bitmap(logo_flash); + logo = NULL; + regenerate = false; + } + if (!logo) { + /* Generate a new logo. */ + ALLEGRO_BITMAP *fullflash; + ALLEGRO_BITMAP *fulllogo = generate_logo(param_values[0], + param_values[1], + strtol(param_values[2], NULL, 10), + strtod(param_values[3], NULL), + strtod(param_values[4], NULL), + strtod(param_values[5], NULL), + strtod(param_values[6], NULL), + strtod(param_values[7], NULL), + strtod(param_values[8], NULL), + &fullflash); + ALLEGRO_BITMAP *crop; + int x, y, left = 640, top = 480, right = -1, bottom = -1; + /* Crop out the non-transparent part. */ + al_lock_bitmap(fulllogo, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + for (y = 0; y < 480; y++) { + for (x = 0; x < 640; x++) { + ALLEGRO_COLOR c = al_get_pixel(fulllogo, x, y); + float r, g, b, a; + al_unmap_rgba_f(c, &r, &g, &b, &a); + if (a > 0) { + if (x < left) + left = x; + if (y < top) + top = y; + if (x > right) + right = x; + if (y > bottom) + bottom = y; + } + } + } + al_unlock_bitmap(fulllogo); + + if (left == 640) + left = 0; + if (top == 480) + top = 0; + if (right < left) + right = left; + if (bottom < top) + bottom = top; + + crop = al_create_sub_bitmap(fulllogo, left, top, + 1 + right - left, 1 + bottom - top); + logo = al_clone_bitmap(crop); + al_destroy_bitmap(crop); + al_destroy_bitmap(fulllogo); + + crop = al_create_sub_bitmap(fullflash, left, top, + 1 + right - left, 1 + bottom - top); + logo_flash = al_clone_bitmap(crop); + al_destroy_bitmap(crop); + al_destroy_bitmap(fullflash); + + logo_x = left; + logo_y = top; + + anim = t; + } + draw_background(); + + /* For half a second, display our flash animation. */ + if (t - anim < 0.5) { + ALLEGRO_STATE state; + int i, j; + float f = sin(ALLEGRO_PI * ((t - anim) / 0.5)); + ALLEGRO_COLOR c = al_map_rgb_f(f * 0.3, f * 0.3, f * 0.3); + al_store_state(&state, ALLEGRO_STATE_BLENDER); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_tinted_bitmap(logo, al_map_rgba_f(1, 1, 1, 1 - f), logo_x, logo_y, 0); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + for (j = -2; j <= 2; j += 2) { + for (i = -2; i <= 2; i += 2) { + al_draw_tinted_bitmap(logo_flash, c, logo_x + i, logo_y + j, 0); + } + } + al_restore_state(&state); + } + else + al_draw_bitmap(logo, logo_x, logo_y, 0); + + + print_parameters(); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + int redraw = 0, i; + bool quit = false; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not initialise Allegro\n"); + } + al_init_primitives_addon(); + al_install_mouse(); + al_init_image_addon(); + al_init_font_addon(); + al_init_ttf_addon(); + init_platform_specific(); + srand(time(NULL)); + + white = al_map_rgba_f(1, 1, 1, 1); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display\n"); + } + al_set_window_title(display, "Allegro Logo Generator"); + al_install_keyboard(); + + /* Read logo parameters from logo.ini (if it exists). */ + config = al_load_config_file("logo.ini"); + if (!config) + config = al_create_config(); + for (i = 0; param_names[i]; i++) { + char const *value = al_get_config_value(config, "logo", param_names[i]); + if (value) + strncpy(param_values[i], value, sizeof(param_values[i])); + } + + font = al_load_font("data/DejaVuSans.ttf", 12, 0); + if (!font) { + abort_example("Could not load font\n"); + } + + timer = al_create_timer(1.0 / 60); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + while (!quit) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + quit = true; + } + else if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { + if (editing) { + regenerate = true; + editing = false; + } + else { + cursor = strlen(param_values[selection]); + editing = true; + } + } + else if (event.keyboard.keycode == ALLEGRO_KEY_UP) { + if (selection > 0) { + selection--; + cursor = strlen(param_values[selection]); + editing = false; + } + } + else if (event.keyboard.keycode == ALLEGRO_KEY_DOWN) { + if (param_names[selection + 1]) { + selection++; + cursor = strlen(param_values[selection]); + editing = false; + } + } + else { + int c = event.keyboard.unichar; + if (editing) { + if (event.keyboard.keycode == ALLEGRO_KEY_BACKSPACE) { + if (cursor > 0) { + ALLEGRO_USTR *u = al_ustr_new(param_values[selection]); + if (al_ustr_prev(u, &cursor)) { + al_ustr_remove_chr(u, cursor); + strncpy(param_values[selection], al_cstr(u), + sizeof param_values[selection]); + } + al_ustr_free(u); + } + } + else if (c >= 32) { + ALLEGRO_USTR *u = al_ustr_new(param_values[selection]); + cursor += al_ustr_set_chr(u, cursor, c); + al_ustr_set_chr(u, cursor, 0); + strncpy(param_values[selection], al_cstr(u), + sizeof param_values[selection]); + al_ustr_free(u); + } + } + else { + if (c == 'r') + randomize(); + if (c == 's') + save(); + } + } + } + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + if (event.mouse.button == 1) { + mouse_click(event.mouse.x, event.mouse.y); + } + } + if (event.type == ALLEGRO_EVENT_TIMER) + redraw++; + + if (redraw && al_is_event_queue_empty(queue)) { + redraw = 0; + + render(); + + al_flip_display(); + } + } + + /* Write modified parameters back to logo.ini. */ + for (i = 0; param_names[i]; i++) { + al_set_config_value(config, "logo", param_names[i], + param_values[i]); + } + al_save_config_file("logo.ini", config); + al_destroy_config(config); + + return 0; +} diff --git a/allegro/examples/ex_membmp.c b/allegro/examples/ex_membmp.c new file mode 100644 index 00000000..abfa5d79 --- /dev/null +++ b/allegro/examples/ex_membmp.c @@ -0,0 +1,126 @@ +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" + +#include "common.c" + +static void print(ALLEGRO_FONT *myfont, char *message, int x, int y) +{ + al_draw_text(myfont, al_map_rgb(0, 0, 0), x+2, y+2, 0, message); + al_draw_text(myfont, al_map_rgb(255, 255, 255), x, y, 0, message); +} + +static bool test(ALLEGRO_BITMAP *bitmap, ALLEGRO_FONT *font, char *message) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + double start_time; + long frames = 0; + double fps = 0; + char second_line[100]; + bool quit = false; + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + start_time = al_get_time(); + + for (;;) { + if (al_get_next_event(queue, &event)) { + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + break; + } + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + quit = true; + break; + } + } + } + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + /* Clear the backbuffer with red so we can tell if the bitmap does not + * cover the entire backbuffer. + */ + al_clear_to_color(al_map_rgb(255, 0, 0)); + + al_draw_scaled_bitmap(bitmap, 0, 0, + al_get_bitmap_width(bitmap), + al_get_bitmap_height(bitmap), + 0, 0, + al_get_bitmap_width(al_get_target_bitmap()), + al_get_bitmap_height(al_get_target_bitmap()), + 0); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + /* Note this makes the memory buffer case much slower due to repeated + * locking of the backbuffer. Officially you can't use al_lock_bitmap + * to solve the problem either. + */ + print(font, message, 0, 0); + sprintf(second_line, "%.1f FPS", fps); + print(font, second_line, 0, al_get_font_line_height(font)+5); + + al_flip_display(); + + frames++; + fps = (double)frames / (al_get_time() - start_time); + } + + al_destroy_event_queue(queue); + + return quit; +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *accelfont; + ALLEGRO_FONT *memfont; + ALLEGRO_BITMAP *accelbmp; + ALLEGRO_BITMAP *membmp; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + display = al_create_display(640, 400); + if (!display) { + abort_example("Error creating display\n"); + } + + accelfont = al_load_font("data/font.tga", 0, 0); + if (!accelfont) { + abort_example("font.tga not found\n"); + } + accelbmp = al_load_bitmap("data/mysha.pcx"); + if (!accelbmp) { + abort_example("mysha.pcx not found\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + + memfont = al_load_font("data/font.tga", 0, 0); + membmp = al_load_bitmap("data/mysha.pcx"); + + for (;;) { + if (test(membmp, memfont, "Memory bitmap (press SPACE key)")) + break; + if (test(accelbmp, accelfont, "Accelerated bitmap (press SPACE key)")) + break; + } + + return 0; +} diff --git a/allegro/examples/ex_memfile.c b/allegro/examples/ex_memfile.c new file mode 100644 index 00000000..f3fce756 --- /dev/null +++ b/allegro/examples/ex_memfile.c @@ -0,0 +1,119 @@ +/* + * Example program for the Allegro library. + * + * Test memfile addon. + */ + +#include +#ifdef _MSC_VER + #pragma comment ( linker, "/SUBSYSTEM:CONSOLE") +#endif +#define ALLEGRO_USE_CONSOLE +#include +#include + +#include "common.c" + +int main(void) +{ + ALLEGRO_FILE *memfile; + char *data; + int i; + const int data_size = 1024; + char buffer[50]; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + data = calloc(1, data_size); + if (!data) + abort_example("Out of memory.\n"); + + log_printf("Creating memfile\n"); + memfile = al_open_memfile(data, data_size, "rw"); + if (!memfile) { + log_printf("Error opening memfile :(\n"); + goto Error; + } + + log_printf("Writing data to memfile\n"); + for (i = 0; i < data_size/4; i++) { + if (al_fwrite32le(memfile, i) < 4) { + log_printf("Failed to write %i to memfile\n", i); + goto Error; + } + } + + al_fseek(memfile, 0, ALLEGRO_SEEK_SET); + + log_printf("Reading and testing data from memfile\n"); + for (i = 0; i < data_size/4; i++) { + int32_t ret = al_fread32le(memfile); + if (ret != i || al_feof(memfile)) { + log_printf("Item %i failed to verify, got %i\n", i, ret); + goto Error; + } + } + + if (al_feof(memfile)) { + log_printf("EOF indicator prematurely set!\n"); + goto Error; + } + + /* testing the ungetc buffer */ + al_fseek(memfile, 0, ALLEGRO_SEEK_SET); + + for (i = 0; al_fungetc(memfile, i) != EOF; ++i) { } + log_printf("Length of ungetc buffer: %d\n", i); + + if (al_ftell(memfile) != -i) { + log_printf("Current position is not correct. Expected -%d, but got %d\n", + i, (int) al_ftell(memfile)); + goto Error; + } + + while (i--) { + if (i != al_fgetc(memfile)) { + log_printf("Failed to verify ungetc data.\n"); + goto Error; + } + } + + if (al_ftell(memfile) != 0) { + log_printf("Current position is not correct after reading back the ungetc buffer\n"); + log_printf("Expected 0, but got %d\n", (int) al_ftell(memfile)); + goto Error; + } + + al_fputs(memfile, "legro rocks!"); + al_fseek(memfile, 0, ALLEGRO_SEEK_SET); + al_fungetc(memfile, 'l'); + al_fungetc(memfile, 'A'); + al_fgets(memfile, buffer, 15); + if (strcmp(buffer, "Allegro rocks!")) { + log_printf("Expected to see 'Allegro rocks!' but got '%s' instead.\n", buffer); + log_printf("(Maybe the ungetc buffer isn't big enough.)\n"); + goto Error; + } + + log_printf("Done.\n"); + + al_fclose(memfile); + free(data); + + close_log(true); + + return 0; + +Error: + + al_fclose(memfile); + free(data); + + close_log(true); + return 1; +} +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_menu.c b/allegro/examples/ex_menu.c new file mode 100644 index 00000000..b7fbd10b --- /dev/null +++ b/allegro/examples/ex_menu.c @@ -0,0 +1,292 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_native_dialog.h" +#include "allegro5/allegro_image.h" +#include +#include + +#include "common.c" + +/* The following is a list of menu item ids. They can be any non-zero, positive + * integer. A menu item must have an id in order for it to generate an event. + * Also, each menu item's id should be unique to get well defined results. + */ +enum { + FILE_ID = 1, + FILE_OPEN_ID, + FILE_RESIZE_ID, + FILE_FULLSCREEN_ID, + FILE_CLOSE_ID, + FILE_EXIT_ID, + DYNAMIC_ID, + DYNAMIC_CHECKBOX_ID, + DYNAMIC_DISABLED_ID, + DYNAMIC_DELETE_ID, + DYNAMIC_CREATE_ID, + HELP_ABOUT_ID +}; + +/* This is one way to define a menu. The entire system, nested menus and all, + * can be defined by this single array. + */ +ALLEGRO_MENU_INFO main_menu_info[] = { + ALLEGRO_START_OF_MENU("&File", FILE_ID), + { "&Open", FILE_OPEN_ID, 0, NULL }, + ALLEGRO_MENU_SEPARATOR, + { "E&xit", FILE_EXIT_ID, 0, NULL }, + ALLEGRO_END_OF_MENU, + + ALLEGRO_START_OF_MENU("&Dynamic Options", DYNAMIC_ID), + { "&Checkbox", DYNAMIC_CHECKBOX_ID, ALLEGRO_MENU_ITEM_CHECKED, NULL }, + { "&Disabled", DYNAMIC_DISABLED_ID, ALLEGRO_MENU_ITEM_DISABLED, NULL }, + { "DELETE ME!", DYNAMIC_DELETE_ID, 0, NULL }, + { "Click Me", DYNAMIC_CREATE_ID, 0, NULL }, + ALLEGRO_END_OF_MENU, + + ALLEGRO_START_OF_MENU("&Help", 0), + { "&About", HELP_ABOUT_ID, 0, NULL }, + ALLEGRO_END_OF_MENU, + + ALLEGRO_END_OF_MENU +}; + +/* This is the menu on the secondary windows. */ +ALLEGRO_MENU_INFO child_menu_info[] = { + ALLEGRO_START_OF_MENU("&File", 0), + { "&Close", FILE_CLOSE_ID, 0, NULL }, + ALLEGRO_END_OF_MENU, + ALLEGRO_END_OF_MENU +}; + +int main(int argc, char **argv) +{ + const int initial_width = 320; + const int initial_height = 200; + int dcount = 0; + + ALLEGRO_DISPLAY *display; + ALLEGRO_MENU *menu; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + bool redraw = true; + bool menu_visible = true; + ALLEGRO_MENU *pmenu; + ALLEGRO_BITMAP *bg; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + if (!al_init_native_dialog_addon()) { + abort_example("Could not init the native dialog addon.\n"); + } + al_init_image_addon(); + al_install_keyboard(); + al_install_mouse(); + + queue = al_create_event_queue(); + +#ifdef ALLEGRO_GTK_TOPLEVEL + /* ALLEGRO_GTK_TOPLEVEL is necessary for menus with GTK. */ + al_set_new_display_flags(ALLEGRO_RESIZABLE | ALLEGRO_GTK_TOPLEVEL); +#else + al_set_new_display_flags(ALLEGRO_RESIZABLE); +#endif + display = al_create_display(initial_width, initial_height); + if (!display) { + abort_example("Error creating display\n"); + } + al_set_window_title(display, "ex_menu - Main Window"); + + menu = al_build_menu(main_menu_info); + if (!menu) { + abort_example("Error creating menu\n"); + } + + /* Add an icon to the Help/About item. Note that Allegro assumes ownership + * of the bitmap. */ + al_set_menu_item_icon(menu, HELP_ABOUT_ID, al_load_bitmap("data/icon.tga")); + + if (!al_set_display_menu(display, menu)) { + /* Since the menu could not be attached to the window, then treat it as + * a popup menu instead. */ + pmenu = al_clone_menu_for_popup(menu); + al_destroy_menu(menu); + menu = pmenu; + } + else { + /* Create a simple popup menu used when right clicking. */ + pmenu = al_create_popup_menu(); + if (pmenu) { + al_append_menu_item(pmenu, "&Open", FILE_OPEN_ID, 0, NULL, NULL); + al_append_menu_item(pmenu, "&Resize", FILE_RESIZE_ID, 0, NULL, NULL); + al_append_menu_item(pmenu, "&Fullscreen window", FILE_FULLSCREEN_ID, 0, NULL, NULL); + al_append_menu_item(pmenu, "E&xit", FILE_EXIT_ID, 0, NULL, NULL); + } + } + + timer = al_create_timer(1.0 / 60); + + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_default_menu_event_source()); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + bg = al_load_bitmap("data/mysha.pcx"); + + al_start_timer(timer); + + while (true) { + ALLEGRO_EVENT event; + + if (redraw && al_is_event_queue_empty(queue)) { + redraw = false; + if (bg) { + float t = al_get_timer_count(timer) * 0.1; + float sw = al_get_bitmap_width(bg); + float sh = al_get_bitmap_height(bg); + float dw = al_get_display_width(display); + float dh = al_get_display_height(display); + float cx = dw/2; + float cy = dh/2; + dw *= 1.2 + 0.2 * cos(t); + dh *= 1.2 + 0.2 * cos(1.1 * t); + al_draw_scaled_bitmap(bg, 0, 0, sw, sh, + cx - dw/2, cy - dh/2, dw, dh, 0); + } + al_flip_display(); + } + + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + if (event.display.source == display) { + /* Closing the primary display */ + break; + } + else { + /* Closing a secondary display */ + al_set_display_menu(event.display.source, NULL); + al_destroy_display(event.display.source); + } + } + else if (event.type == ALLEGRO_EVENT_MENU_CLICK) { + /* data1: id + * data2: display (could be null) + * data3: menu (could be null) + */ + if (event.user.data2 == (intptr_t) display) { + /* The main window. */ + if (event.user.data1 == FILE_OPEN_ID) { + ALLEGRO_DISPLAY *d = al_create_display(320, 240); + if (d) { + ALLEGRO_MENU *menu = al_build_menu(child_menu_info); + al_set_display_menu(d, menu); + al_clear_to_color(al_map_rgb(0,0,0)); + al_flip_display(); + al_register_event_source(queue, al_get_display_event_source(d)); + al_set_target_backbuffer(display); + al_set_window_title(d, "ex_menu - Child Window"); + } + } + else if (event.user.data1 == DYNAMIC_CHECKBOX_ID) { + al_set_menu_item_flags(menu, DYNAMIC_DISABLED_ID, al_get_menu_item_flags(menu, DYNAMIC_DISABLED_ID) ^ ALLEGRO_MENU_ITEM_DISABLED); + al_set_menu_item_caption(menu, DYNAMIC_DISABLED_ID, + (al_get_menu_item_flags(menu, DYNAMIC_DISABLED_ID) & ALLEGRO_MENU_ITEM_DISABLED) ? + "&Disabled" : "&Enabled"); + } + else if (event.user.data1 == DYNAMIC_DELETE_ID) { + al_remove_menu_item(menu, DYNAMIC_DELETE_ID); + } + else if (event.user.data1 == DYNAMIC_CREATE_ID) { + if (dcount < 5) { + char new_name[10]; + + ++dcount; + if (dcount == 1) { + /* append a separator */ + al_append_menu_item(al_find_menu(menu, DYNAMIC_ID), NULL, 0, 0, NULL, NULL); + } + + sprintf(new_name, "New #%d", dcount); + al_append_menu_item(al_find_menu(menu, DYNAMIC_ID), new_name, 0, 0, NULL, NULL); + + if (dcount == 5) { + /* disable the option */ + al_set_menu_item_flags(menu, DYNAMIC_CREATE_ID, ALLEGRO_MENU_ITEM_DISABLED); + } + } + } + else if (event.user.data1 == HELP_ABOUT_ID) { + al_show_native_message_box(display, "About", "ex_menu", + "This is a sample program that shows how to use menus", + "OK", 0); + } + else if (event.user.data1 == FILE_EXIT_ID) { + break; + } + else if (event.user.data1 == FILE_RESIZE_ID) { + int w = al_get_display_width(display) * 2; + int h = al_get_display_height(display) * 2; + if (w > 960) + w = 960; + if (h > 600) + h = 600; + al_resize_display(display, w, h); + } + else if (event.user.data1 == FILE_FULLSCREEN_ID) { + int flags = al_get_display_flags(display); + bool value = (flags & ALLEGRO_FULLSCREEN_WINDOW) ? true : false; + al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, !value); + } + } + else { + /* The child window */ + if (event.user.data1 == FILE_CLOSE_ID) { + ALLEGRO_DISPLAY *d = (ALLEGRO_DISPLAY *) event.user.data2; + if (d) { + al_set_display_menu(d, NULL); + al_destroy_display(d); + } + } + } + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { + /* Popup a context menu on a right click. */ + if (event.mouse.display == display && event.mouse.button == 2) { + if (pmenu) { + if (!al_popup_menu(pmenu, display)) { + log_printf("Couldn't popup menu!\n"); + } + } + } + } + else if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + /* Toggle the menu if the spacebar is pressed */ + if (event.keyboard.display == display) { + if (event.keyboard.unichar == ' ') { + if (menu_visible) + al_remove_display_menu(display); + else + al_set_display_menu(display, menu); + + menu_visible = !menu_visible; + } + } + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { + al_acknowledge_resize(display); + redraw = true; + } + else if (event.type == ALLEGRO_EVENT_TIMER) { + redraw = true; + } + } + + /* You must remove the menu before destroying the display to free resources */ + al_set_display_menu(display, NULL); + + return 0; +} diff --git a/allegro/examples/ex_mixer_chain.c b/allegro/examples/ex_mixer_chain.c new file mode 100644 index 00000000..628e23a4 --- /dev/null +++ b/allegro/examples/ex_mixer_chain.c @@ -0,0 +1,129 @@ +/* + * Example program for the Allegro library. + * + * Test chaining mixers to mixers. + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" + +#include "common.c" + +char *default_files[] = {NULL, "data/haiku/water_0.ogg", + "data/haiku/water_7.ogg"}; + +int main(int argc, char **argv) +{ + ALLEGRO_VOICE *voice; + ALLEGRO_MIXER *mixer; + ALLEGRO_MIXER *submixer[2]; + ALLEGRO_SAMPLE_INSTANCE *sample[2]; + ALLEGRO_SAMPLE *sample_data[2]; + float sample_time; + float max_sample_time; + int i; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + if (argc < 3) { + log_printf("This example can be run from the command line.\nUsage: %s file1 file2\n", argv[0]); + argv = default_files; + argc = 3; + } + + al_init_acodec_addon(); + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + + voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, + ALLEGRO_CHANNEL_CONF_2); + if (!voice) { + abort_example("Could not create ALLEGRO_VOICE.\n"); + } + + mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); + submixer[0] = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); + submixer[1] = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); + if (!mixer || !submixer[0] || !submixer[1]) { + abort_example("al_create_mixer failed.\n"); + } + + if (!al_attach_mixer_to_voice(mixer, voice)) { + abort_example("al_attach_mixer_to_voice failed.\n"); + } + + for (i = 0; i < 2; i++) { + const char *filename = argv[i + 1]; + sample_data[i] = al_load_sample(filename); + if (!sample_data[i]) { + abort_example("Could not load sample from '%s'!\n", filename); + } + sample[i] = al_create_sample_instance(NULL); + if (!sample[i]) { + abort_example("al_create_sample failed.\n"); + } + if (!al_set_sample(sample[i], sample_data[i])) { + abort_example("al_set_sample_ptr failed.\n"); + } + if (!al_attach_sample_instance_to_mixer(sample[i], submixer[i])) { + abort_example("al_attach_sample_instance_to_mixer failed.\n"); + } + if (!al_attach_mixer_to_mixer(submixer[i], mixer)) { + abort_example("al_attach_mixer_to_mixer failed.\n"); + } + } + + /* Play sample in looping mode. */ + for (i = 0; i < 2; i++) { + al_set_sample_instance_playmode(sample[i], ALLEGRO_PLAYMODE_LOOP); + al_play_sample_instance(sample[i]); + } + + max_sample_time = al_get_sample_instance_time(sample[0]); + sample_time = al_get_sample_instance_time(sample[1]); + if (sample_time > max_sample_time) + max_sample_time = sample_time; + + log_printf("Playing..."); + + al_rest(max_sample_time); + + al_set_sample_instance_gain(sample[0], 0.5); + al_rest(max_sample_time); + + al_set_sample_instance_gain(sample[1], 0.25); + al_rest(max_sample_time); + + al_stop_sample_instance(sample[0]); + al_stop_sample_instance(sample[1]); + log_printf("Done\n"); + + /* Free the memory allocated. */ + for (i = 0; i < 2; i++) { + al_set_sample(sample[i], NULL); + al_destroy_sample(sample_data[i]); + al_destroy_sample_instance(sample[i]); + al_destroy_mixer(submixer[i]); + } + al_destroy_mixer(mixer); + al_destroy_voice(voice); + + al_uninstall_audio(); + + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_mixer_pp.c b/allegro/examples/ex_mixer_pp.c new file mode 100644 index 00000000..0d51c633 --- /dev/null +++ b/allegro/examples/ex_mixer_pp.c @@ -0,0 +1,207 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * This program demonstrates a simple use of mixer postprocessing callbacks. + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" + +#define FPS 60 + +static volatile float rms_l = 0.0; +static volatile float rms_r = 0.0; + +static ALLEGRO_DISPLAY *display; +static ALLEGRO_BITMAP *dbuf; +static ALLEGRO_BITMAP *bmp; +static float theta; + +static void update_meter(void *buf, unsigned int samples, void *data) +{ + float *fbuf = (float *)buf; + float sum_l = 0.0; + float sum_r = 0.0; + unsigned int i; + + (void)data; + + for (i = samples; i > 0; i--) { + sum_l += fbuf[0] * fbuf[0]; + sum_r += fbuf[1] * fbuf[1]; + fbuf += 2; + } + + rms_l = sqrt(sum_l / samples); + rms_r = sqrt(sum_r / samples); +} + +static void draw(void) +{ + const float sw = al_get_bitmap_width(bmp); + const float sh = al_get_bitmap_height(bmp); + const float dw = al_get_bitmap_width(dbuf); + const float dh = al_get_bitmap_height(dbuf); + const float dx = dw / 2.0; + const float dy = dh / 2.0; + float db_l; + float db_r; + float db; + float scale; + float disp; + + /* Whatever looks okay. */ + if (rms_l > 0.0 && rms_r > 0.0) { + db_l = 20 * log10(rms_l / 20e-6); + db_r = 20 * log10(rms_r / 20e-6); + db = (db_l + db_r) / 2.0; + scale = db / 20.0; + disp = (rms_l + rms_r) * 200.0; + } + else { + db_l = db_r = db = scale = disp = 0.0; + } + + al_set_target_bitmap(dbuf); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + al_draw_filled_rectangle(0, 0, al_get_bitmap_width(dbuf), al_get_bitmap_height(dbuf), + al_map_rgba_f(0.8, 0.3, 0.1, 0.06)); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_tinted_scaled_rotated_bitmap(bmp, + al_map_rgba_f(0.8, 0.3, 0.1, 0.2), + sw/2.0, sh/2.0, dx, dy - disp, scale, scale, theta, 0); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_set_target_backbuffer(display); + al_draw_bitmap(dbuf, 0, 0, 0); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + al_draw_line(10, dh - db_l, 10, dh, al_map_rgb_f(1, 0.6, 0.2), 6); + al_draw_line(20, dh - db_r, 20, dh, al_map_rgb_f(1, 0.6, 0.2), 6); + + al_flip_display(); + + theta -= (rms_l + rms_r) * 0.1; +} + +static void main_loop(void) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + bool redraw = true; + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + theta = 0.0; + + for (;;) { + if (redraw && al_is_event_queue_empty(queue)) { + draw(); + redraw = false; + } + + if (!al_wait_for_event_timed(queue, &event, 1.0/FPS)) { + redraw = true; + continue; + } + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + } + + al_destroy_event_queue(queue); +} + +int main(int argc, char **argv) +{ + const char *filename = "../demos/cosmic_protector/data/sfx/title_music.ogg"; + ALLEGRO_VOICE *voice; + ALLEGRO_MIXER *mixer; + ALLEGRO_AUDIO_STREAM *stream; + + if (argc > 1) { + filename = argv[1]; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_init_image_addon(); + al_init_acodec_addon(); + init_platform_specific(); + + al_install_keyboard(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display.\n"); + } + + dbuf = al_create_bitmap(640, 480); + + bmp = al_load_bitmap("data/mysha.pcx"); + if (!bmp) { + abort_example("Could not load data/mysha.pcx\n"); + } + + if (!al_install_audio()) { + abort_example("Could not init sound.\n"); + } + + voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, + ALLEGRO_CHANNEL_CONF_2); + if (!voice) { + abort_example("Could not create voice.\n"); + } + + mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); + if (!mixer) { + abort_example("Could not create mixer.\n"); + } + + if (!al_attach_mixer_to_voice(mixer, voice)) { + abort_example("al_attach_mixer_to_voice failed.\n"); + } + + stream = al_load_audio_stream(filename, 4, 2048); + if (!stream) { + /* On Android we only pack this into the APK. */ + stream = al_load_audio_stream("data/welcome.wav", 4, 2048); + } + if (!stream) { + abort_example("Could not load '%s'\n", filename); + } + + al_set_audio_stream_playmode(stream, ALLEGRO_PLAYMODE_LOOP); + al_attach_audio_stream_to_mixer(stream, mixer); + + al_set_mixer_postprocess_callback(mixer, update_meter, NULL); + + main_loop(); + + al_destroy_audio_stream(stream); + al_destroy_mixer(mixer); + al_destroy_voice(voice); + al_uninstall_audio(); + + al_destroy_bitmap(dbuf); + al_destroy_bitmap(bmp); + + return 0; +} diff --git a/allegro/examples/ex_monitorinfo.c b/allegro/examples/ex_monitorinfo.c new file mode 100644 index 00000000..5ca1fdb5 --- /dev/null +++ b/allegro/examples/ex_monitorinfo.c @@ -0,0 +1,47 @@ +#include "allegro5/allegro.h" +#include + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_MONITOR_INFO info; + int num_adapters; + int i, j; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + num_adapters = al_get_num_video_adapters(); + + log_printf("%d adapters found...\n", num_adapters); + + for (i = 0; i < num_adapters; i++) { + al_get_monitor_info(i, &info); + log_printf("Adapter %d: ", i); + int dpi = al_get_monitor_dpi(i); + log_printf("(%d, %d) - (%d, %d) - dpi: %d\n", info.x1, info.y1, info.x2, info.y2, dpi); + al_set_new_display_adapter(i); + log_printf(" Available fullscreen display modes:\n"); + for (j = 0; j < al_get_num_display_modes(); j++) { + ALLEGRO_DISPLAY_MODE mode; + + al_get_display_mode(j, &mode); + + log_printf(" Mode %3d: %4d x %4d, %d Hz\n", + j, mode.width, mode.height, mode.refresh_rate); + } + } + + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_mouse.c b/allegro/examples/ex_mouse.c new file mode 100644 index 00000000..f3fcc6ce --- /dev/null +++ b/allegro/examples/ex_mouse.c @@ -0,0 +1,79 @@ +#include +#include "allegro5/allegro_image.h" +#include + +#include "common.c" + +#define NUM_BUTTONS 3 + +static void draw_mouse_button(int but, bool down) +{ + const int offset[NUM_BUTTONS] = {0, 70, 35}; + ALLEGRO_COLOR grey; + ALLEGRO_COLOR black; + int x; + int y; + + x = 400 + offset[but-1]; + y = 130; + + grey = al_map_rgb(0xe0, 0xe0, 0xe0); + black = al_map_rgb(0, 0, 0); + + al_draw_filled_rectangle(x, y, x + 27, y + 42, grey); + al_draw_rectangle(x + 0.5, y + 0.5, x + 26.5, y + 41.5, black, 0); + if (down) { + al_draw_filled_rectangle(x + 2, y + 2, x + 25, y + 40, black); + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *cursor; + ALLEGRO_MOUSE_STATE msestate; + ALLEGRO_KEYBOARD_STATE kbdstate; + int i; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_mouse(); + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + al_hide_mouse_cursor(display); + + cursor = al_load_bitmap("data/cursor.tga"); + if (!cursor) { + abort_example("Error loading cursor.tga\n"); + } + + do { + al_get_mouse_state(&msestate); + al_get_keyboard_state(&kbdstate); + + al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); + for (i = 1; i <= NUM_BUTTONS; i++) { + draw_mouse_button(i, al_mouse_button_down(&msestate, i)); + } + al_draw_bitmap(cursor, msestate.x, msestate.y, 0); + al_flip_display(); + + al_rest(0.005); + } while (!al_key_down(&kbdstate, ALLEGRO_KEY_ESCAPE)); + + return 0; +} + diff --git a/allegro/examples/ex_mouse_cursor.c b/allegro/examples/ex_mouse_cursor.c new file mode 100644 index 00000000..016c3d3d --- /dev/null +++ b/allegro/examples/ex_mouse_cursor.c @@ -0,0 +1,224 @@ +/* + * Example program for the Allegro library, by Peter Wang. + */ + + +#include +#include +#include "allegro5/allegro_image.h" + +#include "common.c" + + +typedef struct { + int system_cursor; + const char *label; +} CursorList; + + +#define MARGIN_LEFT 20 +#define MARGIN_TOP 20 +#define NUM_CURSORS 20 + +CursorList cursor_list[NUM_CURSORS] = +{ + { ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT, "DEFAULT" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW, "ARROW" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY, "BUSY" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION, "QUESTION" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT, "EDIT" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE, "MOVE" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N, "RESIZE_N" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W, "RESIZE_W" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S, "RESIZE_S" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E, "RESIZE_E" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW, "RESIZE_NW" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW, "RESIZE_SW" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE, "RESIZE_SE" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE, "RESIZE_NE" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS, "PROGRESS" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION, "PRECISION" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK, "LINK" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT, "ALT_SELECT" }, + { ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE, "UNAVAILABLE" }, + { -1, "CUSTOM" } +}; + +int current_cursor[2] = { 0, 0 }; + + +static void draw_display(ALLEGRO_FONT *font) +{ + int th; + int i; + + al_clear_to_color(al_map_rgb(128, 128, 128)); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + th = al_get_font_line_height(font); + for (i = 0; i < NUM_CURSORS; i++) { + al_draw_text(font, al_map_rgba_f(0, 0, 0, 1), + MARGIN_LEFT, MARGIN_TOP + i * th, 0, cursor_list[i].label); + } + + i++; + al_draw_text(font, al_map_rgba_f(0, 0, 0, 1), + MARGIN_LEFT, MARGIN_TOP + i * th, 0, + "Press S/H to show/hide cursor"); + + al_flip_display(); +} + +static int hover(ALLEGRO_FONT *font, int y) +{ + int th; + int i; + + if (y < MARGIN_TOP) + return -1; + + th = al_get_font_line_height(font); + i = (y - MARGIN_TOP) / th; + if (i < NUM_CURSORS) + return i; + + return -1; +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display1; + ALLEGRO_DISPLAY *display2; + ALLEGRO_BITMAP *bmp; + ALLEGRO_BITMAP *shrunk_bmp; + ALLEGRO_MOUSE_CURSOR *custom_cursor; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_FONT *font; + ALLEGRO_EVENT event; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_image_addon(); + init_platform_specific(); + + if (!al_install_mouse()) { + abort_example("Error installing mouse\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard\n"); + } + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display1 = al_create_display(400, 400); + if (!display1) { + abort_example("Error creating display1\n"); + } + + display2 = al_create_display(400, 400); + if (!display2) { + abort_example("Error creating display2\n"); + } + + bmp = al_load_bitmap("data/allegro.pcx"); + if (!bmp) { + abort_example("Error loading data/allegro.pcx\n"); + } + + font = al_load_bitmap_font("data/fixed_font.tga"); + if (!font) { + abort_example("Error loading data/fixed_font.tga\n"); + } + + shrunk_bmp = al_create_bitmap(32, 32); + if (!shrunk_bmp) { + abort_example("Error creating shrunk_bmp\n"); + } + + al_set_target_bitmap(shrunk_bmp); + al_draw_scaled_bitmap(bmp, + 0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), + 0, 0, 32, 32, + 0); + + custom_cursor = al_create_mouse_cursor(shrunk_bmp, 0, 0); + if (!custom_cursor) { + abort_example("Error creating mouse cursor\n"); + } + + al_set_target_bitmap(NULL); + al_destroy_bitmap(shrunk_bmp); + al_destroy_bitmap(bmp); + shrunk_bmp = NULL; + bmp = NULL; + + queue = al_create_event_queue(); + if (!queue) { + abort_example("Error creating event queue\n"); + } + + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_display_event_source(display1)); + al_register_event_source(queue, al_get_display_event_source(display2)); + + al_set_target_backbuffer(display1); + draw_display(font); + + al_set_target_backbuffer(display2); + draw_display(font); + + while (1) { + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { + al_set_target_backbuffer(event.display.source); + draw_display(font); + continue; + } + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + switch (event.keyboard.unichar) { + case 27: /* escape */ + goto Quit; + case 'h': + al_hide_mouse_cursor(event.keyboard.display); + break; + case 's': + al_show_mouse_cursor(event.keyboard.display); + break; + default: + break; + } + } + if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + int dpy = (event.mouse.display == display1) ? 0 : 1; + int i = hover(font, event.mouse.y); + + if (i >= 0 && current_cursor[dpy] != i) { + if (cursor_list[i].system_cursor != -1) { + al_set_system_mouse_cursor(event.mouse.display, + cursor_list[i].system_cursor); + } + else { + al_set_mouse_cursor(event.mouse.display, custom_cursor); + } + current_cursor[dpy] = i; + } + } + } + +Quit: + + al_destroy_mouse_cursor(custom_cursor); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_mouse_events.c b/allegro/examples/ex_mouse_events.c new file mode 100644 index 00000000..0b9e3d83 --- /dev/null +++ b/allegro/examples/ex_mouse_events.c @@ -0,0 +1,187 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" + +#define NUM_BUTTONS 5 +static int actual_buttons; + +static void draw_mouse_button(int but, bool down) +{ + const int offset[NUM_BUTTONS] = {0, 70, 35, 105, 140}; + ALLEGRO_COLOR grey; + ALLEGRO_COLOR black; + int x; + int y; + + x = 400 + offset[but]; + y = 130; + + grey = al_map_rgb(0xe0, 0xe0, 0xe0); + black = al_map_rgb(0, 0, 0); + + al_draw_filled_rectangle(x, y, x + 27, y + 42, grey); + al_draw_rectangle(x + 0.5, y + 0.5, x + 26.5, y + 41.5, black, 0); + if (down) { + al_draw_filled_rectangle(x + 2, y + 2, x + 25, y + 40, black); + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *cursor; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + ALLEGRO_FONT *font; + int mx = 0; + int my = 0; + int mz = 0; + int mw = 0; + int mmx = 0; + int mmy = 0; + int mmz = 0; + int mmw = 0; + int precision = 1; + bool in = true; + bool buttons[NUM_BUTTONS] = {false}; + int i; + float p = 0.0; + ALLEGRO_COLOR black; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_mouse(); + al_install_keyboard(); + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + actual_buttons = al_get_mouse_num_buttons(); + if (actual_buttons > NUM_BUTTONS) + actual_buttons = NUM_BUTTONS; + + al_set_new_display_flags(ALLEGRO_RESIZABLE); + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + al_hide_mouse_cursor(display); + + cursor = al_load_bitmap("data/cursor.tga"); + if (!cursor) { + abort_example("Error loading cursor.tga\n"); + } + + font = al_load_font("data/fixed_font.tga", 1, 0); + if (!font) { + abort_example("data/fixed_font.tga not found\n"); + } + + black = al_map_rgb_f(0, 0, 0); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + while (1) { + if (al_is_event_queue_empty(queue)) { + al_clear_to_color(al_map_rgb(0xff, 0xff, 0xc0)); + for (i = 0; i < actual_buttons; i++) { + draw_mouse_button(i, buttons[i]); + } + al_draw_bitmap(cursor, mx, my, 0); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, black, 5, 5, 0, "dx %i, dy %i, dz %i, dw %i", mmx, mmy, mmz, mmw); + al_draw_textf(font, black, 5, 25, 0, "x %i, y %i, z %i, w %i", mx, my, mz, mw); + al_draw_textf(font, black, 5, 45, 0, "p = %g", p); + al_draw_textf(font, black, 5, 65, 0, "%s", in ? "in" : "out"); + al_draw_textf(font, black, 5, 85, 0, "wheel precision (PgUp/PgDn) %d", precision); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + mmx = mmy = mmz = 0; + al_flip_display(); + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_MOUSE_AXES: + mx = event.mouse.x; + my = event.mouse.y; + mz = event.mouse.z; + mw = event.mouse.w; + mmx = event.mouse.dx; + mmy = event.mouse.dy; + mmz = event.mouse.dz; + mmw = event.mouse.dw; + p = event.mouse.pressure; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + if (event.mouse.button-1 < NUM_BUTTONS) { + buttons[event.mouse.button-1] = true; + } + p = event.mouse.pressure; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + if (event.mouse.button-1 < NUM_BUTTONS) { + buttons[event.mouse.button-1] = false; + } + p = event.mouse.pressure; + break; + + case ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY: + in = true; + break; + + case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: + in = false; + break; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + goto done; + } + break; + + case ALLEGRO_EVENT_KEY_CHAR: + if (event.keyboard.keycode == ALLEGRO_KEY_PGUP) { + precision++; + al_set_mouse_wheel_precision(precision); + } + else if (event.keyboard.keycode == ALLEGRO_KEY_PGDN) { + precision--; + if (precision < 1) + precision = 1; + al_set_mouse_wheel_precision(precision); + } + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(event.display.source); + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + goto done; + } + } + +done: + + al_destroy_event_queue(queue); + + return 0; +} + + +/* vim: set sw=3 sts=3 et: */ diff --git a/allegro/examples/ex_mouse_focus.c b/allegro/examples/ex_mouse_focus.c new file mode 100644 index 00000000..db89634d --- /dev/null +++ b/allegro/examples/ex_mouse_focus.c @@ -0,0 +1,105 @@ +/* + * Example program for the Allegro library. + * + * This program tests if the ALLEGRO_MOUSE_STATE `display' field + * is set correctly. + */ + +#include +#include "allegro5/allegro.h" + +#include "common.c" + +static ALLEGRO_DISPLAY *display1; +static ALLEGRO_DISPLAY *display2; + +static void redraw(ALLEGRO_COLOR color1, ALLEGRO_COLOR color2) +{ + al_set_target_backbuffer(display1); + al_clear_to_color(color1); + al_flip_display(); + + al_set_target_backbuffer(display2); + al_clear_to_color(color2); + al_flip_display(); +} + +int main(int argc, char **argv) +{ + ALLEGRO_COLOR black; + ALLEGRO_COLOR red; + ALLEGRO_MOUSE_STATE mst0; + ALLEGRO_MOUSE_STATE mst; + ALLEGRO_KEYBOARD_STATE kst; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Couldn't initialise Allegro.\n"); + } + if (!al_install_mouse()) { + abort_example("Couldn't install mouse.\n"); + } + if (!al_install_keyboard()) { + abort_example("Couldn't install keyboard.\n"); + } + + display1 = al_create_display(300, 300); + display2 = al_create_display(300, 300); + if (!display1 || !display2) { + al_destroy_display(display1); + al_destroy_display(display2); + abort_example("Couldn't open displays.\n"); + } + + open_log(); + log_printf("Move the mouse cursor over the displays\n"); + + black = al_map_rgb(0, 0, 0); + red = al_map_rgb(255, 0, 0); + + memset(&mst0, 0, sizeof(mst0)); + + while (1) { + al_get_mouse_state(&mst); + if (mst.display != mst0.display || + mst.x != mst0.x || + mst.y != mst0.y) { + if (mst.display == NULL) + log_printf("Outside either display\n"); + else if (mst.display == display1) + log_printf("In display 1, x = %d, y = %d\n", mst.x, mst.y); + else if (mst.display == display2) + log_printf("In display 2, x = %d, y = %d\n", mst.x, mst.y); + else { + log_printf("Unknown display = %p, x = %d, y = %d\n", mst.display, + mst.x, mst.y); + } + mst0 = mst; + } + + if (mst.display == display1) { + redraw(red, black); + } + else if (mst.display == display2) { + redraw(black, red); + } + else { + redraw(black, black); + } + + al_rest(0.1); + + al_get_keyboard_state(&kst); + if (al_key_down(&kst, ALLEGRO_KEY_ESCAPE)) { + break; + } + } + + close_log(false); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_mouse_warp.c b/allegro/examples/ex_mouse_warp.c new file mode 100644 index 00000000..dfc01593 --- /dev/null +++ b/allegro/examples/ex_mouse_warp.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include + +#include "common.c" + +int width = 640; +int height = 480; + +int main(int argc, char **argv) +{ + ALLEGRO_FONT *font; + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *event_queue; + ALLEGRO_EVENT event; + bool right_button_down = false; + bool redraw = true; + int fake_x = 0, fake_y = 0; + ALLEGRO_COLOR white; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_init_primitives_addon(); + al_init_font_addon(); + al_install_mouse(); + al_install_keyboard(); + + al_set_new_display_flags(ALLEGRO_WINDOWED); + display = al_create_display(width, height); + if (!display) { + abort_example("Could not create display.\n"); + } + + memset(&event, 0, sizeof(event)); + + event_queue = al_create_event_queue(); + al_register_event_source(event_queue, al_get_display_event_source(display)); + al_register_event_source(event_queue, al_get_mouse_event_source()); + al_register_event_source(event_queue, al_get_keyboard_event_source()); + + font = al_create_builtin_font(); + white = al_map_rgb_f(1, 1, 1); + + while (1) { + if (redraw && al_is_event_queue_empty(event_queue)) { + int th = al_get_font_line_height(font); + + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + + if (right_button_down) { + al_draw_line(width / 2, height / 2, fake_x, fake_y, + al_map_rgb_f(1, 0, 0), 1); + al_draw_line(fake_x - 5, fake_y, fake_x + 5, fake_y, + al_map_rgb_f(1, 1, 1), 2); + al_draw_line(fake_x, fake_y - 5, fake_x, fake_y + 5, + al_map_rgb_f(1, 1, 1), 2); + } + + al_draw_textf(font, white, 0, 0, 0, "x: %i y: %i dx: %i dy %i", + event.mouse.x, event.mouse.y, + event.mouse.dx, event.mouse.dy); + al_draw_textf(font, white, width / 2, height / 2 - th, ALLEGRO_ALIGN_CENTRE, + "Left-Click to warp pointer to the middle once."); + al_draw_textf(font, white, width / 2, height / 2, ALLEGRO_ALIGN_CENTRE, + "Hold right mouse button to constantly move pointer to the middle."); + al_flip_display(); + redraw = false; + } + + al_wait_for_event(event_queue, &event); + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + } + if (event.type == ALLEGRO_EVENT_MOUSE_WARPED) { + log_printf("Warp\n"); + } + if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + if (right_button_down) { + al_set_mouse_xy(display, width / 2, height / 2); + fake_x += event.mouse.dx; + fake_y += event.mouse.dy; + } + redraw = true; + } + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + if (event.mouse.button == 1) + al_set_mouse_xy(display, width / 2, height / 2); + if (event.mouse.button == 2) { + right_button_down = true; + fake_x = width / 2; + fake_y = height / 2; + } + } + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { + if (event.mouse.button == 2) { + right_button_down = false; + } + } + } + + al_destroy_event_queue(event_queue); + al_destroy_display(display); + + close_log(false); + + return 0; +} diff --git a/allegro/examples/ex_multisample.c b/allegro/examples/ex_multisample.c new file mode 100644 index 00000000..e073d175 --- /dev/null +++ b/allegro/examples/ex_multisample.c @@ -0,0 +1,234 @@ +/* This example demonstrates the effect of multi-sampling on primitives and + * bitmaps. + * + * + * In the window without multi-sampling, the edge of the colored lines will not + * be anti-aliased - each pixel is either filled completely with the primitive + * color or not at all. + * + * The same is true for bitmaps. They will always be drawn at the nearest + * full-pixel position. However this is only true for the bitmap outline - + * when texture filtering is enabled the texture itself will honor the sub-pixel + * position. + * + * Therefore in the case with no multi-sampling but texture-filtering the + * outer black edge will stutter in one-pixel steps while the inside edge will + * be filtered and appear smooth. + * + * + * In the multi-sampled version the colored lines will be anti-aliased. + * + * Same with the bitmaps. This means the bitmap outlines will always move in + * smooth sub-pixel steps. However if texture filtering is turned off the + * texels still are rounded to the next integer position. + * + * Therefore in the case where multi-sampling is enabled but texture-filtering + * is not the outer bitmap edges will move smoothly but the inner will not. + */ + +#include +#include +#include +#include +#include +#include + +#include "common.c" + +static ALLEGRO_FONT *font, *font_ms; +static ALLEGRO_BITMAP *bitmap_normal; +static ALLEGRO_BITMAP *bitmap_filter; +static ALLEGRO_BITMAP *bitmap_normal_ms; +static ALLEGRO_BITMAP *bitmap_filter_ms; +static float bitmap_x[8], bitmap_y[8]; +static float bitmap_t; + + +static ALLEGRO_BITMAP *create_bitmap(void) +{ + const int checkers_size = 8; + const int bitmap_size = 24; + ALLEGRO_BITMAP *bitmap; + ALLEGRO_LOCKED_REGION *locked; + int x, y, p; + unsigned char *rgba; + + bitmap = al_create_bitmap(bitmap_size, bitmap_size); + locked = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888, 0); + rgba = locked->data; + p = locked->pitch; + for (y = 0; y < bitmap_size; y++) { + for (x = 0; x < bitmap_size; x++) { + int c = (((x / checkers_size) + (y / checkers_size)) & 1) * 255; + rgba[y * p + x * 4 + 0] = 0; + rgba[y * p + x * 4 + 1] = 0; + rgba[y * p + x * 4 + 2] = 0; + rgba[y * p + x * 4 + 3] = c; + } + } + al_unlock_bitmap(bitmap); + return bitmap; +} + +static void bitmap_move(void) +{ + int i; + + bitmap_t++; + for (i = 0; i < 8; i++) { + float a = 2 * ALLEGRO_PI * i / 16; + float s = sin((bitmap_t + i * 40) / 180 * ALLEGRO_PI); + s *= 90; + bitmap_x[i] = 100 + s * cos(a); + bitmap_y[i] = 100 + s * sin(a); + } +} + +static void draw(ALLEGRO_BITMAP *bitmap, int y, char const *text) +{ + int i; + + al_draw_text(font_ms, al_map_rgb(0, 0, 0), 0, y, 0, text); + + for (i = 0; i < 16; i++) { + float a = 2 * ALLEGRO_PI * i / 16; + ALLEGRO_COLOR c = al_color_hsv(i * 360 / 16, 1, 1); + al_draw_line(150 + cos(a) * 10, y + 100 + sin(a) * 10, + 150 + cos(a) * 90, y + 100 + sin(a) * 90, c, 3); + } + + for (i = 0; i < 8; i++) { + float a = 2 * ALLEGRO_PI * i / 16; + int s = al_get_bitmap_width(bitmap); + al_draw_rotated_bitmap(bitmap, s / 2, s / 2, + 50 + bitmap_x[i], y + bitmap_y[i], a, 0); + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display, *ms_display; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + ALLEGRO_BITMAP *memory; + char title[1024]; + bool quit = false; + bool redraw = true; + int wx, wy; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Couldn't initialise Allegro.\n"); + } + al_init_primitives_addon(); + + al_install_keyboard(); + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + memory = create_bitmap(); + + /* Create the normal display. */ + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 0, ALLEGRO_REQUIRE); + al_set_new_display_option(ALLEGRO_SAMPLES, 0, ALLEGRO_SUGGEST); + display = al_create_display(300, 450); + if (!display) { + abort_example("Error creating display\n"); + } + al_set_window_title(display, "Normal"); + + /* Create bitmaps for the normal display. */ + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + bitmap_filter = al_clone_bitmap(memory); + al_set_new_bitmap_flags(0); + bitmap_normal = al_clone_bitmap(memory); + + font = al_create_builtin_font(); + + al_get_window_position(display, &wx, &wy); + if (wx < 160) + wx = 160; + + /* Create the multi-sampling display. */ + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE); + al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); + ms_display = al_create_display(300, 450); + if (!ms_display) { + abort_example("Multisampling not available.\n"); + } + sprintf(title, "Multisampling (%dx)", al_get_display_option( + ms_display, ALLEGRO_SAMPLES)); + al_set_window_title(ms_display, title); + + /* Create bitmaps for the multi-sampling display. */ + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + bitmap_filter_ms = al_clone_bitmap(memory); + al_set_new_bitmap_flags(0); + bitmap_normal_ms = al_clone_bitmap(memory); + + font_ms = al_create_builtin_font(); + + /* Move the windows next to each other, because some window manager + * would put them on top of each other otherwise. + */ + al_set_window_position(display, wx - 160, wy); + al_set_window_position(ms_display, wx + 160, wy); + + timer = al_create_timer(1.0 / 30.0); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_display_event_source(ms_display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + while (!quit) { + ALLEGRO_EVENT event; + + /* Check for ESC key or close button event and quit in either case. */ + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + quit = true; + break; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + quit = true; + break; + + case ALLEGRO_EVENT_TIMER: + bitmap_move(); + redraw = true; + break; + } + + if (redraw && al_is_event_queue_empty(queue)) { + /* Draw the multi-sampled version into the first window. */ + al_set_target_backbuffer(ms_display); + + al_clear_to_color(al_map_rgb_f(1, 1, 1)); + + draw(bitmap_filter_ms, 0, "filtered, multi-sample"); + draw(bitmap_normal_ms, 250, "no filter, multi-sample"); + + al_flip_display(); + + /* Draw the normal version into the second window. */ + al_set_target_backbuffer(display); + + al_clear_to_color(al_map_rgb_f(1, 1, 1)); + + draw(bitmap_filter, 0, "filtered"); + draw(bitmap_normal, 250, "no filter"); + + al_flip_display(); + + redraw = false; + } + } + + return 0; +} diff --git a/allegro/examples/ex_multisample_target.c b/allegro/examples/ex_multisample_target.c new file mode 100644 index 00000000..4b416ed3 --- /dev/null +++ b/allegro/examples/ex_multisample_target.c @@ -0,0 +1,249 @@ +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include +#include +#include +#include + +#include "common.c" + +#define FPS 60 + +static struct Example { + ALLEGRO_BITMAP *targets[4]; + ALLEGRO_BITMAP *bitmap_normal; + ALLEGRO_BITMAP *bitmap_filter; + ALLEGRO_BITMAP *sub; + ALLEGRO_FONT *font; + float bitmap_x[8], bitmap_y[8]; + float bitmap_t; + int step_t, step_x, step_y; + ALLEGRO_BITMAP *step[4]; + bool update_step; +} example; + +static ALLEGRO_BITMAP *create_bitmap(void) +{ + const int checkers_size = 8; + const int bitmap_size = 24; + ALLEGRO_BITMAP *bitmap; + ALLEGRO_LOCKED_REGION *locked; + int x, y, p; + unsigned char *rgba; + + bitmap = al_create_bitmap(bitmap_size, bitmap_size); + locked = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888, 0); + rgba = locked->data; + p = locked->pitch; + for (y = 0; y < bitmap_size; y++) { + for (x = 0; x < bitmap_size; x++) { + int c = (((x / checkers_size) + (y / checkers_size)) & 1) * 255; + rgba[y * p + x * 4 + 0] = 0; + rgba[y * p + x * 4 + 1] = 0; + rgba[y * p + x * 4 + 2] = 0; + rgba[y * p + x * 4 + 3] = c; + } + } + al_unlock_bitmap(bitmap); + return bitmap; +} + +static void init(void) +{ + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + ALLEGRO_BITMAP *memory = create_bitmap(); + al_set_new_bitmap_flags(0); + + al_set_new_bitmap_samples(0); + example.targets[0] = al_create_bitmap(300, 200); + example.targets[1] = al_create_bitmap(300, 200); + al_set_new_bitmap_samples(4); + example.targets[2] = al_create_bitmap(300, 200); + example.targets[3] = al_create_bitmap(300, 200); + al_set_new_bitmap_samples(0); + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + example.bitmap_filter = al_clone_bitmap(memory); + al_set_new_bitmap_flags(0); + example.bitmap_normal = al_clone_bitmap(memory); + + example.sub = al_create_sub_bitmap(memory, 0, 0, 30, 30); + example.step[0] = al_create_bitmap(30, 30); + example.step[1] = al_create_bitmap(30, 30); + example.step[2] = al_create_bitmap(30, 30); + example.step[3] = al_create_bitmap(30, 30); +} + +static void bitmap_move(void) +{ + int i; + + example.bitmap_t++; + for (i = 0; i < 8; i++) { + float a = 2 * ALLEGRO_PI * i / 16; + float s = sin((example.bitmap_t + i * 40) / 180 * ALLEGRO_PI); + s *= 90; + example.bitmap_x[i] = 100 + s * cos(a); + example.bitmap_y[i] = 100 + s * sin(a); + } +} + +static void draw(char const *text, ALLEGRO_BITMAP *bitmap) +{ + int i; + + al_clear_to_color(al_color_name("white")); + + al_draw_text(example.font, al_map_rgb(0, 0, 0), 0, 0, 0, text); + + for (i = 0; i < 16; i++) { + float a = 2 * ALLEGRO_PI * i / 16; + ALLEGRO_COLOR c = al_color_hsv(i * 360 / 16, 1, 1); + al_draw_line(100 + cos(a) * 10, 100 + sin(a) * 10, + 100 + cos(a) * 90, 100 + sin(a) * 90, c, 3); + } + + for (i = 0; i < 8; i++) { + float a = 2 * ALLEGRO_PI * i / 16; + int s = al_get_bitmap_width(bitmap); + al_draw_rotated_bitmap(bitmap, s / 2, s / 2, + example.bitmap_x[i], example.bitmap_y[i], a, 0); + } +} + +static void redraw(void) +{ + al_set_target_bitmap(example.targets[1]); + draw("filtered", example.bitmap_filter); + al_set_target_bitmap(example.targets[0]); + draw("no filter", example.bitmap_normal); + al_set_target_bitmap(example.targets[3]); + draw("filtered, multi-sample x4", example.bitmap_filter); + al_set_target_bitmap(example.targets[2]); + draw("no filter, multi-sample x4", example.bitmap_normal); + + float x = example.step_x; + float y = example.step_y; + + if (example.update_step) { + int i; + for (i = 0; i < 4; i++) { + al_set_target_bitmap(example.step[i]); + al_reparent_bitmap(example.sub, example.targets[i], x, y, 30, 30); + al_draw_bitmap(example.sub, 0, 0, 0); + } + example.update_step = false; + } + + al_set_target_backbuffer(al_get_current_display()); + al_clear_to_color(al_map_rgb_f(0.5, 0, 0)); + al_draw_bitmap(example.targets[0], 20, 20, 0); + al_draw_bitmap(example.targets[1], 20, 240, 0); + al_draw_bitmap(example.targets[2], 340, 20, 0); + al_draw_bitmap(example.targets[3], 340, 240, 0); + + al_draw_scaled_rotated_bitmap(example.step[0], 15, 15, 320 - 50, 220 - 50, 4, 4, 0, 0); + al_draw_scaled_rotated_bitmap(example.step[1], 15, 15, 320 - 50, 440 - 50, 4, 4, 0, 0); + al_draw_scaled_rotated_bitmap(example.step[2], 15, 15, 640 - 50, 220 - 50, 4, 4, 0, 0); + al_draw_scaled_rotated_bitmap(example.step[3], 15, 15, 640 - 50, 440 - 50, 4, 4, 0, 0); + +} + +static void update(void) +{ + bitmap_move(); + if (example.step_t == 0) { + example.step_x = example.bitmap_x[1] - 15; + example.step_y = example.bitmap_y[1] - 15; + example.step_t = 60; + example.update_step = true; + } + example.step_t--; +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_DISPLAY *display; + int w = 20 + 300 + 20 + 300 + 20, h = 20 + 200 + 20 + 200 + 20; + bool done = false; + bool need_redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + al_init_font_addon(); + example.font = al_create_builtin_font(); + + al_init_primitives_addon(); + + init_platform_specific(); + + display = al_create_display(w, h); + if (!display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + init(); + + timer = al_create_timer(1.0 / FPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_register_event_source(queue, al_get_display_event_source(display)); + + al_start_timer(timer); + + while (!done) { + ALLEGRO_EVENT event; + + if (need_redraw) { + redraw(); + al_flip_display(); + need_redraw = false; + } + + while (true) { + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_CHAR: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + update(); + need_redraw = true; + break; + } + if (al_is_event_queue_empty(queue)) + break; + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_multiwin.c b/allegro/examples/ex_multiwin.c new file mode 100644 index 00000000..0d8648af --- /dev/null +++ b/allegro/examples/ex_multiwin.c @@ -0,0 +1,137 @@ +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" + +#include "common.c" + +const int W = 640; +const int H = 400; + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display[2]; + ALLEGRO_EVENT event; + ALLEGRO_EVENT_QUEUE *events; + ALLEGRO_BITMAP *pictures[2]; + ALLEGRO_BITMAP *target; + int width, height; + int i; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_install_keyboard(); + al_install_mouse(); + al_init_image_addon(); + + events = al_create_event_queue(); + + al_set_new_display_flags(ALLEGRO_WINDOWED|ALLEGRO_RESIZABLE); + + /* Create two windows. */ + display[0] = al_create_display(W, H); + if (!display[0]) { + abort_example("Error creating display\n"); + } + pictures[0] = al_load_bitmap("data/mysha.pcx"); + if (!pictures[0]) { + abort_example("failed to load mysha.pcx\n"); + } + + display[1] = al_create_display(W, H); + if (!display[1]) { + abort_example("Error creating display\n"); + } + pictures[1] = al_load_bitmap("data/allegro.pcx"); + if (!pictures[1]) { + abort_example("failed to load allegro.pcx\n"); + } + + /* This is only needed since we want to receive resize events. */ + al_register_event_source(events, al_get_display_event_source(display[0])); + al_register_event_source(events, al_get_display_event_source(display[1])); + al_register_event_source(events, al_get_keyboard_event_source()); + + while (1) { + /* read input */ + while (!al_is_event_queue_empty(events)) { + al_get_next_event(events, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + ALLEGRO_KEYBOARD_EVENT *key = &event.keyboard; + if (key->keycode == ALLEGRO_KEY_ESCAPE) { + goto done; + } + } + if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { + ALLEGRO_DISPLAY_EVENT *de = &event.display; + al_acknowledge_resize(de->source); + } + if (event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN) { + log_printf("%p switching in\n", event.display.source); + } + if (event.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) { + log_printf("%p switching out\n", event.display.source); + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + int i; + for (i = 0; i < 2; i++) { + if (display[i] == event.display.source) + display[i] = 0; + } + al_destroy_display(event.display.source); + for (i = 0; i < 2; i++) { + if (display[i]) + goto not_done; + } + goto done; + not_done: + ; + } + } + + for (i = 0; i < 2; i++) { + if (!display[i]) + continue; + + target = al_get_backbuffer(display[i]); + width = al_get_bitmap_width(target); + height = al_get_bitmap_height(target); + + al_set_target_bitmap(target); + al_draw_scaled_bitmap(pictures[0], 0, 0, + al_get_bitmap_width(pictures[0]), + al_get_bitmap_height(pictures[0]), + 0, 0, + width / 2, height, + 0); + al_draw_scaled_bitmap(pictures[1], 0, 0, + al_get_bitmap_width(pictures[1]), + al_get_bitmap_height(pictures[1]), + width / 2, 0, + width / 2, height, + 0); + + al_flip_display(); + } + + al_rest(0.001); + } + +done: + al_destroy_bitmap(pictures[0]); + al_destroy_bitmap(pictures[1]); + al_destroy_display(display[0]); + al_destroy_display(display[1]); + + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_native_filechooser.c b/allegro/examples/ex_native_filechooser.c new file mode 100644 index 00000000..d8a2d358 --- /dev/null +++ b/allegro/examples/ex_native_filechooser.c @@ -0,0 +1,373 @@ +/* + * Example program for the Allegro library. + * + * The native file dialog addon only supports a blocking interface. This + * example makes the blocking call from another thread, using a user event + * source to communicate back to the main program. + */ + +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include +#include +#include + +#include "common.c" + +/* To communicate from a separate thread, we need a user event. */ +#define ASYNC_DIALOG_EVENT1 ALLEGRO_GET_EVENT_TYPE('e', 'N', 'F', '1') +#define ASYNC_DIALOG_EVENT2 ALLEGRO_GET_EVENT_TYPE('e', 'N', 'F', '2') + + +typedef struct +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FILECHOOSER *file_dialog; + ALLEGRO_EVENT_SOURCE event_source; + ALLEGRO_THREAD *thread; +} AsyncDialog; + +ALLEGRO_TEXTLOG *textlog; + +static void message(char const *format, ...) +{ + char str[1024]; + va_list args; + + va_start(args, format); + vsnprintf(str, sizeof str, format, args); + va_end(args); + al_append_native_text_log(textlog, "%s", str); +} + +/* Our thread to show the native file dialog. */ +static void *async_file_dialog_thread_func(ALLEGRO_THREAD *thread, void *arg) +{ + AsyncDialog *data = arg; + ALLEGRO_EVENT event; + (void)thread; + + /* The next line is the heart of this example - we display the + * native file dialog. + */ + al_show_native_file_dialog(data->display, data->file_dialog); + + /* We emit an event to let the main program know that the thread has + * finished. + */ + event.user.type = ASYNC_DIALOG_EVENT1; + al_emit_user_event(&data->event_source, &event, NULL); + + return NULL; +} + + +/* A thread to show the message boxes. */ +static void *message_box_thread(ALLEGRO_THREAD *thread, void *arg) +{ + AsyncDialog *data = arg; + ALLEGRO_EVENT event; + int button; + + (void)thread; + + button = al_show_native_message_box(data->display, "Warning", + "Click Detected", + "That does nothing. Stop clicking there.", + "Oh no!|Don't press|Ok", ALLEGRO_MESSAGEBOX_WARN); + if (button == 2) { + button = al_show_native_message_box(data->display, "Error", "Hey!", + "Stop it! I told you not to click there.", + NULL, ALLEGRO_MESSAGEBOX_ERROR); + } + + event.user.type = ASYNC_DIALOG_EVENT2; + al_emit_user_event(&data->event_source, &event, NULL); + + return NULL; +} + + +/* Function to start the new thread. */ +static AsyncDialog *spawn_async_file_dialog(ALLEGRO_DISPLAY *display, + const char *initial_path, + bool save) +{ + AsyncDialog *data = malloc(sizeof *data); + int flags = save ? ALLEGRO_FILECHOOSER_SAVE : ALLEGRO_FILECHOOSER_MULTIPLE; + const char* title = save ? "Save (no files will be changed)" : "Choose files"; + data->file_dialog = al_create_native_file_dialog( + initial_path, title, NULL, + flags); + al_init_user_event_source(&data->event_source); + data->display = display; + data->thread = al_create_thread(async_file_dialog_thread_func, data); + + al_start_thread(data->thread); + + return data; +} + +static AsyncDialog *spawn_async_message_dialog(ALLEGRO_DISPLAY *display) +{ + AsyncDialog *data = calloc(1, sizeof *data); + + al_init_user_event_source(&data->event_source); + data->display = display; + data->thread = al_create_thread(message_box_thread, data); + + al_start_thread(data->thread); + + return data; +} + + +static void stop_async_dialog(AsyncDialog *data) +{ + if (data) { + al_destroy_thread(data->thread); + al_destroy_user_event_source(&data->event_source); + if (data->file_dialog) + al_destroy_native_file_dialog(data->file_dialog); + free(data); + } +} + + +/* Helper function to display the result from a file dialog. */ +static void show_files_list(ALLEGRO_FILECHOOSER *dialog, + const ALLEGRO_FONT *font, ALLEGRO_COLOR info) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + int count = al_get_native_file_dialog_count(dialog); + int th = al_get_font_line_height(font); + float x = al_get_bitmap_width(target) / 2; + float y = al_get_bitmap_height(target) / 2 - (count * th) / 2; + int i; + + for (i = 0; i < count; i++) { + const char *name = al_get_native_file_dialog_path(dialog, i); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, info, x, y + i * th, ALLEGRO_ALIGN_CENTRE, name, 0, 0); + } +} + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_FONT *font; + ALLEGRO_COLOR background, active, inactive, info; + AsyncDialog *old_dialog = NULL; + AsyncDialog *cur_dialog = NULL; + AsyncDialog *message_box = NULL; + bool redraw = false; + bool close_log = false; + int button; + bool message_log = true; + bool touch; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + if (!al_init_native_dialog_addon()) { + abort_example("Could not init native dialog addon.\n"); + } + + textlog = al_open_native_text_log("Log", 0); + message("Starting up log window.\n"); + + al_init_image_addon(); + al_init_font_addon(); + + background = al_color_name("white"); + active = al_color_name("black"); + inactive = al_color_name("gray"); + info = al_color_name("red"); + + al_install_mouse(); + touch = al_install_touch_input(); + al_install_keyboard(); + + if (touch) { + al_set_mouse_emulation_mode(ALLEGRO_MOUSE_EMULATION_5_0_x); + } + + message("Creating window..."); + +#ifdef ALLEGRO_IPHONE + al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); +#endif + + display = al_create_display(640, 480); + if (!display) { + message("failure.\n"); + abort_example("Error creating display\n"); + } + message("success.\n"); + + message("Loading font '%s'...", "data/fixed_font.tga"); + font = al_load_font("data/fixed_font.tga", 0, 0); + if (!font) { + message("failure.\n"); + abort_example("Error loading data/fixed_font.tga\n"); + } + message("success.\n"); + + timer = al_create_timer(1.0 / 30); +restart: + message("Starting main loop.\n"); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + if (touch) { + al_register_event_source(queue, al_get_touch_input_event_source()); + al_register_event_source(queue, al_get_touch_input_mouse_emulation_event_source()); + } + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + if (textlog) { + al_register_event_source(queue, al_get_native_text_log_event_source( + textlog)); + } + al_start_timer(timer); + + while (1) { + float h = al_get_display_height(display); + + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE && !cur_dialog) + break; + + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE && !cur_dialog) + break; + } + + /* When a mouse button is pressed, and no native dialog is + * shown already, we show a new one. + */ + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + message("Mouse clicked at %d,%d.\n", event.mouse.x, event.mouse.y); + if (event.mouse.y > 30) { + if (event.mouse.y > h - 30) { + message_log = !message_log; + if (message_log) { + textlog = al_open_native_text_log("Log", 0); + if (textlog) { + al_register_event_source(queue, + al_get_native_text_log_event_source(textlog)); + } + } + else { + close_log = true; + } + } + else if (!message_box) { + message_box = spawn_async_message_dialog(display); + al_register_event_source(queue, &message_box->event_source); + } + } + else if (!cur_dialog) { + const char *last_path = NULL; + bool save = event.mouse.x > al_get_display_width(display) / 2; + /* If available, use the path from the last dialog as + * initial path for the new one. + */ + if (old_dialog) { + last_path = al_get_native_file_dialog_path( + old_dialog->file_dialog, 0); + } + cur_dialog = spawn_async_file_dialog(display, last_path, save); + al_register_event_source(queue, &cur_dialog->event_source); + } + } + /* We receive this event from the other thread when the dialog is + * closed. + */ + if (event.type == ASYNC_DIALOG_EVENT1) { + al_unregister_event_source(queue, &cur_dialog->event_source); + + /* If files were selected, we replace the old files list. + * Otherwise the dialog was cancelled, and we keep the old results. + */ + if (al_get_native_file_dialog_count(cur_dialog->file_dialog) > 0) { + if (old_dialog) + stop_async_dialog(old_dialog); + old_dialog = cur_dialog; + } + else { + stop_async_dialog(cur_dialog); + } + cur_dialog = NULL; + } + if (event.type == ASYNC_DIALOG_EVENT2) { + al_unregister_event_source(queue, &message_box->event_source); + stop_async_dialog(message_box); + message_box = NULL; + } + + if (event.type == ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE) { + close_log = true; + } + + if (event.type == ALLEGRO_EVENT_TIMER) { + redraw = true; + } + + if (redraw && al_is_event_queue_empty(queue)) { + float x = al_get_display_width(display) / 2; + float y = 0; + redraw = false; + al_clear_to_color(background); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, cur_dialog ? inactive : active, x/2, y, ALLEGRO_ALIGN_CENTRE, "Open"); + al_draw_textf(font, cur_dialog ? inactive : active, x/2*3, y, ALLEGRO_ALIGN_CENTRE, "Save"); + al_draw_textf(font, cur_dialog ? inactive : active, x, h - 30, + ALLEGRO_ALIGN_CENTRE, message_log ? "Close Message Log" : "Open Message Log"); + if (old_dialog) + show_files_list(old_dialog->file_dialog, font, info); + al_flip_display(); + } + + if (close_log && textlog) { + close_log = false; + message_log = false; + al_unregister_event_source(queue, + al_get_native_text_log_event_source(textlog)); + al_close_native_text_log(textlog); + textlog = NULL; + } + } + + message("Exiting.\n"); + + al_destroy_event_queue(queue); + + button = al_show_native_message_box(display, + "Warning", + "Are you sure?", + "If you click yes then this example will inevitably close." + " This is your last chance to rethink your decision." + " Do you really want to quit?", + NULL, + ALLEGRO_MESSAGEBOX_YES_NO | ALLEGRO_MESSAGEBOX_QUESTION); + if (button != 1) + goto restart; + + stop_async_dialog(old_dialog); + stop_async_dialog(cur_dialog); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_nodisplay.c b/allegro/examples/ex_nodisplay.c new file mode 100644 index 00000000..a711da10 --- /dev/null +++ b/allegro/examples/ex_nodisplay.c @@ -0,0 +1,70 @@ +/* Test that bitmap manipulation without a display works. */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_BITMAP *sprite; + ALLEGRO_COLOR c1, c2, c3; + bool rc; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Error initialising Allegro\n"); + } + al_init_image_addon(); + init_platform_specific(); + + sprite = al_load_bitmap("data/cursor.tga"); + if (!sprite) { + abort_example("Error loading data/cursor.tga\n"); + } + + bmp = al_create_bitmap(256, 256); + if (!bmp) { + abort_example("Error creating bitmap\n"); + } + + al_set_target_bitmap(bmp); + + c1 = al_map_rgb(255, 0, 0); + c2 = al_map_rgb(0, 255, 0); + c3 = al_map_rgb(0, 255, 255); + + al_clear_to_color(al_map_rgba(255, 0, 0, 128)); + al_draw_bitmap(sprite, 0, 0, 0); + al_draw_tinted_bitmap(sprite, c1, 64, 0, ALLEGRO_FLIP_HORIZONTAL); + al_draw_tinted_bitmap(sprite, c2, 0, 64, ALLEGRO_FLIP_VERTICAL); + al_draw_tinted_bitmap(sprite, c3, 64, 64, ALLEGRO_FLIP_HORIZONTAL | + ALLEGRO_FLIP_VERTICAL); + + al_set_target_bitmap(NULL); + + rc = al_save_bitmap("ex_nodisplay_out.tga", bmp); + + if (rc) { +#ifdef ALLEGRO_POPUP_EXAMPLES + al_show_native_message_box(NULL, "ex_nodisplay_out", "", + "Saved ex_nodisplay_out.tga", NULL, 0); +#else + printf("Saved ex_nodisplay_out.tga\n"); +#endif + } + else { + abort_example("Error saving ex_nodisplay_out.tga\n"); + } + + al_destroy_bitmap(sprite); + al_destroy_bitmap(bmp); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_noframe.c b/allegro/examples/ex_noframe.c new file mode 100644 index 00000000..ad178e81 --- /dev/null +++ b/allegro/examples/ex_noframe.c @@ -0,0 +1,96 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" + +#include + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bitmap; + ALLEGRO_EVENT_QUEUE *events; + ALLEGRO_EVENT event; + bool down = false; + int down_x = 0, down_y = 0; + ALLEGRO_TIMER *timer; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_mouse(); + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_FRAMELESS); + display = al_create_display(300, 200); + if (!display) { + abort_example("Error creating display\n"); + } + + bitmap = al_load_bitmap("data/fakeamp.bmp"); + if (!bitmap) { + abort_example("Error loading fakeamp.bmp\n"); + } + + timer = al_create_timer(1.0f/30.0f); + + events = al_create_event_queue(); + al_register_event_source(events, al_get_mouse_event_source()); + al_register_event_source(events, al_get_keyboard_event_source()); + al_register_event_source(events, al_get_display_event_source(display)); + al_register_event_source(events, al_get_timer_event_source(timer)); + + al_start_timer(timer); + + for (;;) { + al_wait_for_event(events, &event); + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + if (event.mouse.button == 1 && event.mouse.x) { + down = true; + down_x = event.mouse.x; + down_y = event.mouse.y; + } + if (event.mouse.button == 2) { + al_set_display_flag(display, ALLEGRO_FRAMELESS, + !(al_get_display_flags(display) & ALLEGRO_FRAMELESS)); + } + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { + if (event.mouse.button == 1) { + down = false; + } + } + else if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + if (down) { + int cx, cy; + if (al_get_mouse_cursor_position(&cx, &cy)) { + al_set_window_position(display, cx - down_x, cy - down_y); + } + } + } + else if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + else if (event.type == ALLEGRO_EVENT_TIMER) { + al_draw_bitmap(bitmap, 0, 0, 0); + al_flip_display(); + } + } + + al_destroy_timer(timer); + al_destroy_event_queue(events); + al_destroy_display(display); + + return 0; +} + diff --git a/allegro/examples/ex_ogre3d.cpp b/allegro/examples/ex_ogre3d.cpp new file mode 100644 index 00000000..52e56636 --- /dev/null +++ b/allegro/examples/ex_ogre3d.cpp @@ -0,0 +1,468 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * Windows support by AMCerasoli. + * + * This is a test program to see if Allegro can be used alongside the OGRE + * graphics library. It currently only works on Linux/GLX and Windows. + * To run, you will need to have OGRE plugins.cfg and resources.cfg files in + * the current directory. + * + * Inputs: W A S D, mouse + * + * This code is based on the samples in the OGRE distribution. + */ + +#include +#include +#ifdef ALLEGRO_WINDOWS +#include +#endif +#include + +/* + * Ogre 1.7 (and, optionally, earlier versions) uses the FreeImage library to + * handle image loading. FreeImage bundles its own copies of common libraries + * like libjpeg and libpng, which can conflict with the system copies of those + * libraries that allegro_image uses. That means we can't use allegro_image + * safely, nor any of the addons which depend on it. + * + * One solution would be to write a codec for Ogre that avoids FreeImage, or + * write allegro_image handlers using FreeImage. The latter would probably be + * easier and useful for other reasons. + */ + +using namespace Ogre; + +const int WIDTH = 640; +const int HEIGHT = 480; +const float MOVE_SPEED = 1500.0; + +class Application +{ +protected: + Root *mRoot; + RenderWindow *mWindow; + SceneManager *mSceneMgr; + Camera *mCamera; + +public: + void setup(ALLEGRO_DISPLAY *display) + { + createRoot(); + defineResources(); + setupRenderSystem(); + createRenderWindow(display); + initializeResourceGroups(); + chooseSceneManager(); + createCamera(); + createViewports(); + createScene(); + } + + Application() + { + mRoot = NULL; + } + + ~Application() + { + delete mRoot; + } + +private: + void createRoot() + { + mRoot = new Root(); + } + + void defineResources() + { + String secName, typeName, archName; + ConfigFile cf; + cf.load("resources.cfg"); + ConfigFile::SectionIterator seci = cf.getSectionIterator(); + while (seci.hasMoreElements()) { + secName = seci.peekNextKey(); + ConfigFile::SettingsMultiMap *settings = seci.getNext(); + ConfigFile::SettingsMultiMap::iterator i; + for (i = settings->begin(); i != settings->end(); ++i) { + typeName = i->first; + archName = i->second; + ResourceGroupManager::getSingleton().addResourceLocation(archName, + typeName, secName); + } + } + } + + void setupRenderSystem() + { + if (!mRoot->restoreConfig() && !mRoot->showConfigDialog()) { + throw Exception(52, "User canceled the config dialog!", + "Application::setupRenderSystem()"); + } + } + + void createRenderWindow(ALLEGRO_DISPLAY *display) + { + int w = al_get_display_width(display); + int h = al_get_display_height(display); + + // Initialise Ogre without creating a window. + mRoot->initialise(false); + + Ogre::NameValuePairList misc; + #ifdef ALLEGRO_WINDOWS + unsigned long winHandle = reinterpret_cast(al_get_win_window_handle(display)); + unsigned long winGlContext = reinterpret_cast(wglGetCurrentContext()); + misc["externalWindowHandle"] = StringConverter::toString(winHandle); + misc["externalGLContext"] = StringConverter::toString(winGlContext); + misc["externalGLControl"] = String("True"); + #else + misc["currentGLContext"] = String("True"); + #endif + + mWindow = mRoot->createRenderWindow("MainRenderWindow", w, h, false, + &misc); + } + + void initializeResourceGroups() + { + TextureManager::getSingleton().setDefaultNumMipmaps(5); + ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + } + + virtual void chooseSceneManager() + { + mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "Default SceneManager"); + } + + virtual void createCamera() + { + mCamera = mSceneMgr->createCamera("PlayerCam"); + mCamera->setPosition(Vector3(-300, 300, -300)); + mCamera->lookAt(Vector3(0, 0, 0)); + mCamera->setNearClipDistance(5); + } + + virtual void createViewports() + { + // Create one viewport, entire window. + Viewport *vp = mWindow->addViewport(mCamera); + vp->setBackgroundColour(ColourValue(0, 0.25, 0.5)); + + // Alter the camera aspect ratio to match the viewport. + mCamera->setAspectRatio( + Real(vp->getActualWidth()) / Real(vp->getActualHeight())); + } + + virtual void createScene() = 0; + +public: + + void render() + { + const bool swap_buffers = false; + mWindow->update(swap_buffers); + mRoot->renderOneFrame(); + al_flip_display(); + } +}; + +class Example : public Application +{ +private: + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + + double startTime; + double lastRenderTime; + double lastMoveTime; + bool lmb; + bool rmb; + bool forward; + bool back; + bool left; + bool right; + float current_speed; + Vector3 last_translate; + +public: + Example(ALLEGRO_DISPLAY *display); + ~Example(); + void setup(); + void mainLoop(); + +private: + void createScene(); + void moveCamera(double timestamp, Radian rot_x, Radian rot_y, + Vector3 & translate); + void animate(double now); + void nextFrame(); +}; + +Example::Example(ALLEGRO_DISPLAY *display) : + display(display), + queue(NULL), + timer(NULL), + startTime(0.0), + lastRenderTime(0.0), + lastMoveTime(0.0), + lmb(false), + rmb(false), + forward(false), + back(false), + left(false), + right(false), + current_speed(0), + last_translate(Vector3::ZERO) +{ +} + +Example::~Example() +{ + if (timer) al_destroy_timer(timer); + if (queue) al_destroy_event_queue(queue); +} + +void Example::createScene() +{ + // Enable shadows. + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.25, 0.0)); + //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); // slower + mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); // faster + + // Create the character. + Entity *ent1 = mSceneMgr->createEntity("Ninja", "ninja.mesh"); + ent1->setCastShadows(true); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent1); + + AnimationState *anim1 = ent1->getAnimationState("Walk"); + anim1->setLoop(true); + anim1->setEnabled(true); + + // Create the ground. + Plane plane(Vector3::UNIT_Y, 0); + MeshManager::getSingleton().createPlane("ground", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, + 1500, 1500, 20, 20, true, 1, 5, 5, Vector3::UNIT_Z); + + Entity *ent2 = mSceneMgr->createEntity("GroundEntity", "ground"); + ent2->setMaterialName("Examples/Rockwall"); + ent2->setCastShadows(false); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent2); + + // Create a light. + Light *light = mSceneMgr->createLight("Light1"); + light->setType(Light::LT_POINT); + light->setPosition(Vector3(0, 150, 250)); + light->setDiffuseColour(1.0, 1.0, 1.0); + light->setSpecularColour(1.0, 0.0, 0.0); +} + +void Example::setup() +{ + Application::setup(display); + + const double BPS = 60.0; + timer = al_create_timer(1.0 / BPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_display_event_source(display)); +} + +void Example::mainLoop() +{ + bool redraw = true; + + startTime = lastMoveTime = al_get_time(); + al_start_timer(timer); + + for (;;) { + ALLEGRO_EVENT event; + + if (al_is_event_queue_empty(queue) && redraw) { + nextFrame(); + redraw = false; + } + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + + Radian rot_x(0); + Radian rot_y(0); + Vector3 translate(Vector3::ZERO); + + switch (event.type) { + case ALLEGRO_EVENT_TIMER: + redraw = true; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + if (event.mouse.button == 1) + lmb = true; + if (event.mouse.button == 2) + rmb = true; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + if (event.mouse.button == 1) + lmb = false; + if (event.mouse.button == 2) + rmb = false; + if (!lmb && !rmb) + al_show_mouse_cursor(display); + break; + + case ALLEGRO_EVENT_MOUSE_AXES: + if (lmb) { + rot_x = Degree(-event.mouse.dx * 0.13); + rot_y = Degree(-event.mouse.dy * 0.13); + } + if (rmb) { + translate.x = event.mouse.dx * 0.5; + translate.y = event.mouse.dy * -0.5; + } + if (lmb || rmb) { + al_hide_mouse_cursor(display); + al_set_mouse_xy(display, + al_get_display_width(display)/2, + al_get_display_height(display)/2); + } + break; + + case ALLEGRO_EVENT_KEY_DOWN: + case ALLEGRO_EVENT_KEY_UP: { + const bool is_down = (event.type == ALLEGRO_EVENT_KEY_DOWN); + if (event.keyboard.keycode == ALLEGRO_KEY_W) + forward = is_down; + if (event.keyboard.keycode == ALLEGRO_KEY_S) + back = is_down; + if (event.keyboard.keycode == ALLEGRO_KEY_A) + left = is_down; + if (event.keyboard.keycode == ALLEGRO_KEY_D) + right = is_down; + break; + } + + case ALLEGRO_EVENT_DISPLAY_RESIZE: { + al_acknowledge_resize(event.display.source); + int w = al_get_display_width(display); + int h = al_get_display_height(display); + mWindow->resize(w, h); + mCamera->setAspectRatio(Real(w) / Real(h)); + redraw = true; + break; + } + } + + moveCamera(event.any.timestamp, rot_x, rot_y, translate); + } +} + +void Example::moveCamera(double timestamp, Radian rot_x, Radian rot_y, + Vector3 & translate) +{ + const double time_since_move = timestamp - lastMoveTime; + const float move_scale = MOVE_SPEED * time_since_move; + + if (forward) { + translate.z = -move_scale; + } + if (back) { + translate.z = move_scale; + } + if (left) { + translate.x = -move_scale; + } + if (right) { + translate.x = move_scale; + } + + if (translate == Vector3::ZERO) { + // Continue previous motion but dampen. + translate = last_translate; + current_speed -= time_since_move * 0.3; + } + else { + // Ramp up. + current_speed += time_since_move; + } + if (current_speed > 1.0) + current_speed = 1.0; + if (current_speed < 0.0) + current_speed = 0.0; + + translate *= current_speed; + + mCamera->yaw(rot_x); + mCamera->pitch(rot_y); + mCamera->moveRelative(translate); + + last_translate = translate; + lastMoveTime = timestamp; +} + +void Example::animate(double now) +{ + const double dt0 = now - startTime; + const double dt = now - lastRenderTime; + + // Animate the character. + Entity *ent = mSceneMgr->getEntity("Ninja"); + AnimationState *anim = ent->getAnimationState("Walk"); + anim->addTime(dt); + + // Move the light around. + Light *light = mSceneMgr->getLight("Light1"); + light->setPosition(Vector3(300 * cos(dt0), 300, 300 * sin(dt0))); +} + +void Example::nextFrame() +{ + const double now = al_get_time(); + animate(now); + render(); + lastRenderTime = now; +} + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + ALLEGRO_DISPLAY *display; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_install_keyboard(); + al_install_mouse(); + + al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_RESIZABLE); + display = al_create_display(WIDTH, HEIGHT); + if (!display) { + abort_example("Error creating display\n"); + } + al_set_window_title(display, "My window"); + + { + Example app(display); + app.setup(); + app.mainLoop(); + } + + al_uninstall_system(); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_opengl.c b/allegro/examples/ex_opengl.c new file mode 100644 index 00000000..012281c9 --- /dev/null +++ b/allegro/examples/ex_opengl.c @@ -0,0 +1,179 @@ +#define ALLEGRO_UNSTABLE + +#include +#include +#include +#include + +#include "common.c" + +/* Simple example showing how to use an extension. It draws a yellow triangle + * on red background onto a texture, then draws a quad with that texture. + */ + +GLuint tex, fbo; +bool no_fbo = false; + +static void draw_opengl(void) +{ + double secs = al_get_time(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* Let's create a texture. It will only be visible if we cannot draw over + * it with the framebuffer extension. + */ + if (!tex) { + unsigned char *pixels = malloc(256 * 256 * 4); + int x, y; + + for (y = 0; y < 256; y++) { + for (x = 0; x < 256; x++) { + unsigned char r = x, g = y, b = 0, a = 255; + pixels[y * 256 * 4 + x * 4 + 0] = r; + pixels[y * 256 * 4 + x * 4 + 1] = g; + pixels[y * 256 * 4 + x * 4 + 2] = b; + pixels[y * 256 * 4 + x * 4 + 3] = a; + } + } + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, + GL_UNSIGNED_INT_8_8_8_8_REV, pixels); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + free(pixels); + } + + /* Let's create a framebuffer object. */ + if (!fbo && !no_fbo) { + /* Did Allegro discover the OpenGL extension for us? */ + if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object) { + /* If yes, then it also filled in the function pointer. How nice. */ + glGenFramebuffersEXT(1, &fbo); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + /* Attach the framebuffer object to our texture. */ + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, tex, 0); + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != + GL_FRAMEBUFFER_COMPLETE_EXT) { + no_fbo = true; + } + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + else { + /* We are screwed, the extension is not available. */ + no_fbo = true; + } + } + + /* Draw a yellow triangle on red background to the framebuffer object. */ + if (fbo && !no_fbo) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + + glPushAttrib(GL_VIEWPORT_BIT | GL_TRANSFORM_BIT); + glViewport(0, 0, 256, 256); + glClearColor(1, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glLoadIdentity(); + glOrtho(0, 256, 256, 0, -1, 1); + + glDisable(GL_TEXTURE_2D); + glColor3f(1, 1, 0); + glTranslatef(128, 128 + sin(secs * ALLEGRO_PI * 2 * 2) * 20, 0); + glBegin(GL_TRIANGLES); + glVertex2f(0, -100); + glVertex2f(100, 0); + glVertex2f(-100, 0); + glEnd(); + + glPopMatrix(); + glPopAttrib(); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + + /* Draw a quad with our texture. */ + glClearColor(0, 0, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glLoadIdentity(); + glTranslatef(320, 240, 0); + glRotatef(secs * 360 / 4, 0, 0, 1); + glColor3f(1, 1, 1); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(-100, -100); + glTexCoord2f(1, 0); glVertex2f(+100, -100); + glTexCoord2f(1, 1); glVertex2f(+100, +100); + glTexCoord2f(0, 1); glVertex2f(-100, +100); + glEnd(); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + int frames = 0; + double start; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_install_keyboard(); + al_set_new_display_flags(ALLEGRO_OPENGL); + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display.\n"); + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + start = al_get_time(); + while (true) { + /* Check for ESC key or close button event and quit in either case. */ + if (!al_is_event_queue_empty(queue)) { + while (al_get_next_event(queue, &event)) { + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + goto done; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + goto done; + break; + } + } + } + draw_opengl(); + al_flip_display(); + frames++; + } + +done: + + log_printf("%.1f FPS\n", frames / (al_get_time() - start)); + al_destroy_event_queue(queue); + al_destroy_display(display); + + close_log(true); + + return 0; +} + diff --git a/allegro/examples/ex_opengl_pixel_shader.c b/allegro/examples/ex_opengl_pixel_shader.c new file mode 100644 index 00000000..b8883bf3 --- /dev/null +++ b/allegro/examples/ex_opengl_pixel_shader.c @@ -0,0 +1,133 @@ +#define ALLEGRO_UNSTABLE + +#include +#include +#include +#include + +#include "common.c" + +GLhandleARB tinter; +GLhandleARB tinter_shader; + +int main(int argc, char **argv) +{ + float r = 0.5, g = 0.5, b = 1, ratio = 0; + int dir = 1; + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *mysha; + ALLEGRO_BITMAP *buffer; + + const char *tinter_shader_src[] = { + "uniform sampler2D backBuffer;", + "uniform float r;", + "uniform float g;", + "uniform float b;", + "uniform float ratio;", + "void main() {", + " vec4 color;", + " float avg, dr, dg, db;", + " color = texture2D(backBuffer, gl_TexCoord[0].st);", + " avg = (color.r + color.g + color.b) / 3.0;", + " dr = avg * r;", + " dg = avg * g;", + " db = avg * b;", + " color.r = color.r - (ratio * (color.r - dr));", + " color.g = color.g - (ratio * (color.g - dg));", + " color.b = color.b - (ratio * (color.b - db));", + " gl_FragColor = color;", + "}" + }; + const int TINTER_LEN = 18; + double start; + GLint loc; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + + al_install_keyboard(); + al_init_image_addon(); + + al_set_new_display_flags(ALLEGRO_OPENGL); + display = al_create_display(320, 200); + if (!display) { + abort_example("Error creating display\n"); + } + + mysha = al_load_bitmap("data/mysha.pcx"); + if (!mysha) { + abort_example("Could not load image.\n"); + } + + buffer = al_create_bitmap(320, 200); + + if (!al_have_opengl_extension("GL_EXT_framebuffer_object") + && !al_have_opengl_extension("GL_ARB_fragment_shader")) { + abort_example("Fragment shaders not supported.\n"); + } + + tinter_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); + + glShaderSourceARB(tinter_shader, TINTER_LEN, tinter_shader_src, NULL); + glCompileShaderARB(tinter_shader); + tinter = glCreateProgramObjectARB(); + glAttachObjectARB(tinter, tinter_shader); + glLinkProgramARB(tinter); + loc = glGetUniformLocationARB(tinter, "backBuffer"); + glUniform1iARB(loc, al_get_opengl_texture(buffer)); + + start = al_get_time(); + + while (1) { + double now, diff; + ALLEGRO_KEYBOARD_STATE state; + al_get_keyboard_state(&state); + if (al_key_down(&state, ALLEGRO_KEY_ESCAPE)) { + break; + } + now = al_get_time(); + diff = now - start; + start = now; + ratio += diff * 0.5 * dir; + if (dir < 0 && ratio < 0) { + ratio = 0; + dir = -dir; + } + else if (dir > 0 && ratio > 1) { + ratio = 1; + dir = -dir; + } + + al_set_target_bitmap(buffer); + + glUseProgramObjectARB(tinter); + loc = glGetUniformLocationARB(tinter, "ratio"); + glUniform1fARB(loc, ratio); + loc = glGetUniformLocationARB(tinter, "r"); + glUniform1fARB(loc, r); + loc = glGetUniformLocationARB(tinter, "g"); + glUniform1fARB(loc, g); + loc = glGetUniformLocationARB(tinter, "b"); + glUniform1fARB(loc, b); + al_draw_bitmap(mysha, 0, 0, 0); + glUseProgramObjectARB(0); + + al_set_target_backbuffer(display); + al_draw_bitmap(buffer, 0, 0, 0); + al_flip_display(); + al_rest(0.001); + } + + glDetachObjectARB(tinter, tinter_shader); + glDeleteObjectARB(tinter_shader); + + al_uninstall_system(); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_palette.c b/allegro/examples/ex_palette.c new file mode 100644 index 00000000..2393e380 --- /dev/null +++ b/allegro/examples/ex_palette.c @@ -0,0 +1,287 @@ +#include +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_color.h" + +/* Note: It should be easy using Cg or HLSL instead of GLSL - for the + * 5.2 release we should make this a config option and implement all 3 + * in any shader examples. + */ +#include "allegro5/allegro_opengl.h" + +#include "common.c" + +int pal_hex[256]; + +typedef struct { + float x, y, angle, t; + int flags, i, j; + float pal[256]; +} Sprite; + +static void interpolate_palette(float *pal, float *pal1, float *pal2, float t) +{ + int i; + for (i = 0; i < 256; i++) { + pal[i * 3 + 0] = pal1[i * 3 + 0] * (1 - t) + (pal2[i * 3 + 0]) * t; + pal[i * 3 + 1] = pal1[i * 3 + 1] * (1 - t) + (pal2[i * 3 + 1]) * t; + pal[i * 3 + 2] = pal1[i * 3 + 2] * (1 - t) + (pal2[i * 3 + 2]) * t; + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bitmap, *background; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + bool redraw = true; + ALLEGRO_SHADER *shader; + float pal[3 * 256], pals[7][3 * 256]; + int i, j; + float t = 0; + Sprite sprite[8]; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_mouse(); + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE | + ALLEGRO_OPENGL); + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8); + bitmap = al_load_bitmap_flags("data/alexlogo.bmp", ALLEGRO_KEEP_INDEX); + if (!bitmap) { + abort_example("alexlogo not found or failed to load\n"); + } + + /* Create 8 sprites. */ + for (i = 0; i < 8; i++) { + Sprite *s = sprite + i; + s->angle = ALLEGRO_PI * 2 * i / 8; + s->x = 320 + sin(s->angle) * (64 + i * 16); + s->y = 240 - cos(s->angle) * (64 + i * 16); + s->flags = (i % 2) ? ALLEGRO_FLIP_HORIZONTAL : 0; + s->t = i / 8.0; + s->i = i % 6; + s->j = (s->i + 1) % 6; + } + + background = al_load_bitmap("data/bkg.png"); + /* Continue even if fail to load. */ + + /* Create 7 palettes with changed hue. */ + for (j = 0; j < 7; j++) { + for (i = 0; i < 256; i++) { + float r, g, b, h, s, l; + r = (pal_hex[i] >> 16) / 255.0; + g = ((pal_hex[i] >> 8) & 255) / 255.0; + b = (pal_hex[i] & 255) / 255.0; + + al_color_rgb_to_hsl(r, g, b, &h, &s, &l); + if (j == 6) { + if (l < 0.3 || l > 0.7) { + h = 0; + s = 1; + l = 0.5; + } + } + else { + h += j * 60; + if (l < 0.3 || l > 0.7) { + if (j & 1) + l = 1 - l; + } + } + al_color_hsl_to_rgb(h, s, l, &r, &g, &b); + + pals[j][i * 3 + 0] = r; + pals[j][i * 3 + 1] = g; + pals[j][i * 3 + 2] = b; + } + } + + shader = al_create_shader(ALLEGRO_SHADER_GLSL); + + al_attach_shader_source( + shader, + ALLEGRO_VERTEX_SHADER, + "attribute vec4 al_pos;\n" + "attribute vec4 al_color;\n" + "attribute vec2 al_texcoord;\n" + "uniform mat4 al_projview_matrix;\n" + "varying vec4 varying_color;\n" + "varying vec2 varying_texcoord;\n" + "void main()\n" + "{\n" + " varying_color = al_color;\n" + " varying_texcoord = al_texcoord;\n" + " gl_Position = al_projview_matrix * al_pos;\n" + "}\n" + ); + al_attach_shader_source( + shader, + ALLEGRO_PIXEL_SHADER, + "uniform sampler2D al_tex;\n" + "uniform vec3 pal[256];\n" + "varying vec4 varying_color;\n" + "varying vec2 varying_texcoord;\n" + "void main()\n" + "{\n" + " vec4 c = texture2D(al_tex, varying_texcoord);\n" + " int index = int(c.r * 255.0);\n" + " if (index != 0) {;\n" + " gl_FragColor = vec4(pal[index], 1);\n" + " }\n" + " else {;\n" + " gl_FragColor = vec4(0, 0, 0, 0);\n" + " };\n" + "}\n" + ); + + al_build_shader(shader); + al_use_shader(shader); + + timer = al_create_timer(1.0 / 60); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + + } + if (event.type == ALLEGRO_EVENT_TIMER) { + redraw = true; + t++; + for (i = 0; i < 8; i++) { + Sprite *s = sprite + i; + int dir = s->flags ? 1 : -1; + s->x += cos(s->angle) * 2 * dir; + s->y += sin(s->angle) * 2 * dir; + s->angle += ALLEGRO_PI / 180.0 * dir; + } + } + + if (redraw && al_is_event_queue_empty(queue)) { + float pos = (int)t % 60 / 60.0; + int p1 = (int)(t / 60) % 3; + int p2 = (p1 + 1) % 3; + + redraw = false; + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + + interpolate_palette(pal, pals[p1 * 2], pals[p2 * 2], pos); + + al_set_shader_float_vector("pal", 3, pal, 256); + if (background) + al_draw_bitmap(background, 0, 0, 0); + + for (i = 0; i < 8; i++) { + Sprite *s = sprite + 7 - i; + float pos = (1 + sin((t / 60 + s->t) * 2 * ALLEGRO_PI)) / 2; + interpolate_palette(pal, pals[s->i], pals[s->j], pos); + al_set_shader_float_vector("pal", 3, pal, 256); + al_draw_rotated_bitmap(bitmap, + 64, 64, s->x, s->y, s->angle, s->flags); + } + + { + float sc = 0.5; + al_set_shader_float_vector("pal", 3, + pals[(int)t % 20 > 15 ? 6 : 0], 256); + #define D al_draw_scaled_rotated_bitmap + D(bitmap, 0, 0, 0, 0, sc, sc, 0, 0); + D(bitmap, 0, 0, 640, 0, -sc, sc, 0, 0); + D(bitmap, 0, 0, 0, 480, sc, -sc, 0, 0); + D(bitmap, 0, 0, 640, 480, -sc, -sc, 0, 0); + } + al_flip_display(); + } + } + + al_use_shader(NULL); + + al_destroy_bitmap(bitmap); + al_destroy_shader(shader); + + return 0; +} + +int pal_hex[256] = { + 0xFF00FF, 0x000100, 0x060000, 0x040006, 0x000200, + 0x000306, 0x010400, 0x030602, 0x02090C, 0x070A06, + 0x020C14, 0x030F1A, 0x0F0E03, 0x0D0F0C, 0x071221, + 0x0D1308, 0x0D1214, 0x121411, 0x12170E, 0x151707, + 0x0A182B, 0x171816, 0x131B0C, 0x1A191C, 0x171D08, + 0x081D35, 0x1A200E, 0x1D1F1C, 0x1D2013, 0x0E2139, + 0x06233F, 0x17230E, 0x1C270E, 0x21260F, 0x0D2845, + 0x0A294C, 0x1F2A12, 0x252724, 0x232B19, 0x222D15, + 0x0C2F51, 0x0D2F57, 0x263012, 0x2B2D2B, 0x233314, + 0x273617, 0x0D3764, 0x17355E, 0x2C3618, 0x2E3623, + 0x333432, 0x2C3A15, 0x093D70, 0x333B17, 0x163C6A, + 0x2F3D18, 0x323D24, 0x383A38, 0x30401B, 0x2F431C, + 0x1E4170, 0x12447D, 0x154478, 0x3F403E, 0x34471A, + 0x3D482C, 0x134B8B, 0x3A4D20, 0x184D86, 0x474846, + 0x3A511D, 0x13549A, 0x3D5420, 0x195595, 0x0F57A3, + 0x4E504D, 0x415925, 0x435B27, 0x485837, 0x125DA9, + 0x485E24, 0x175FB2, 0x235DA3, 0x555754, 0x0565BD, + 0x1C61B5, 0x2163B7, 0x2164B1, 0x49662A, 0x1268C1, + 0x2365B9, 0x1769C3, 0x5E605D, 0x196BBE, 0x55673D, + 0x1B6BC5, 0x2968BC, 0x246BB8, 0x526D2A, 0x0E73CC, + 0x0E74C6, 0x246FC9, 0x2470C4, 0x56712E, 0x666865, + 0x007DCE, 0x537530, 0x2A72CC, 0x55762B, 0x1B77D0, + 0x1F77D8, 0x1E79CC, 0x2E74CF, 0x58782D, 0x2E75CA, + 0x59792E, 0x2279D3, 0x5A7A2F, 0x3276D2, 0x6D6F6C, + 0x1081D3, 0x137FDF, 0x237DC9, 0x5B7C30, 0x637848, + 0x2A7DD7, 0x5E7F33, 0x2C7DDE, 0x2A80CD, 0x1D82E2, + 0x1A85D1, 0x2B80D5, 0x747673, 0x2D82CF, 0x2F84D1, + 0x3381E3, 0x2289D5, 0x3285D2, 0x2986EE, 0x2189ED, + 0x4782C5, 0x3884DF, 0x4083D2, 0x3487D4, 0x278BD7, + 0x298ADD, 0x67883B, 0x7B7D7A, 0x2A8CD9, 0x6C8653, + 0x3289E2, 0x3889D7, 0x2C8DDA, 0x2E8FDB, 0x3D8CDA, + 0x2F90DC, 0x338EE8, 0x3191DD, 0x3E8EDE, 0x3392DE, + 0x838582, 0x709145, 0x3593E0, 0x4191D9, 0x3794E1, + 0x698AB1, 0x4590E5, 0x3B93E6, 0x789158, 0x4594DC, + 0x3C97E4, 0x4896DE, 0x4397EA, 0x3D9AE1, 0x8B8E8B, + 0x409CE3, 0x4B99E1, 0x439CEA, 0x539AD6, 0x5898E2, + 0x439EE5, 0x4E9BE4, 0x439FEC, 0x809C5F, 0x7C9E57, + 0x45A0E7, 0x509FE1, 0x47A1E8, 0x599EDB, 0x48A2E9, + 0x80A153, 0x4AA4EB, 0x959794, 0x5CA1DE, 0x51A3EF, + 0x59A3E3, 0x4DA6ED, 0x4FA7EF, 0x51A8F0, 0x87A763, + 0x5AA8EA, 0x53AAF2, 0x9C9E9B, 0x49AFF5, 0x56ACF5, + 0x55AFF0, 0x8CAD67, 0x64ACE8, 0x60ADF0, 0x59AFF7, + 0x6EACE2, 0x79A9E1, 0x63AFF2, 0x59B2F3, 0x90B162, + 0xA6A8A5, 0x60B5F4, 0x94B56D, 0x99BC72, 0xAEB0AD, + 0x74BBF2, 0x8DB8ED, 0x94B7E3, 0x8ABEEA, 0xA0C379, + 0x82C0F2, 0xB6B8B5, 0xA3C77C, 0xA5C97E, 0xA9CA79, + 0x8FC7F3, 0xBEC0BD, 0xA1C6E9, 0x97C9F0, 0xADD07E, + 0xC8CAC7, 0xACD1F0, 0xB6CFF0, 0xB9D5ED, 0xD1D3D0, + 0xBEDAF4, 0xD9DBD8, 0xC7E2FB, 0xCDE3F6, 0xE1E3E0, + 0xE4E9EC, 0xDBEBF9, 0xEAECE9, 0xE7EFF8, 0xF1F3F0, + 0xECF4FD, 0xF2F7FA, 0xF6F8F5, 0xF7FCFF, 0xFAFCF8, + 0xFDFFFC,}; + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_path.c b/allegro/examples/ex_path.c new file mode 100644 index 00000000..89dd67a1 --- /dev/null +++ b/allegro/examples/ex_path.c @@ -0,0 +1,91 @@ +#include +#include + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_PATH *dyn = NULL; + ALLEGRO_PATH *tostring = NULL; + ALLEGRO_PATH *cloned = NULL; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + open_log(); + + if (argc < 2) { + ALLEGRO_PATH *exe = al_create_path(argv[0]); + if (exe) { + log_printf("This example needs to be run from the command line.\nUsage1: %s \n", al_get_path_filename(exe)); + al_destroy_path(exe); + } + else { + log_printf("This example needs to be run from the command line.\nUsage2: %s \n", argv[0]); + } + goto done; + } + + dyn = al_create_path(argv[1]); + if (!dyn) { + log_printf("Failed to create path structure for '%s'.\n", argv[1]); + } + else { + log_printf("dyn: drive=\"%s\", file=\"%s\"\n", + al_get_path_drive(dyn), + al_get_path_filename(dyn)); + al_destroy_path(dyn); + } + + tostring = al_create_path(argv[1]); + if (!tostring) { + log_printf("Failed to create path structure for tostring test\n"); + } + else { + int i; + + log_printf("tostring: '%s'\n", al_path_cstr(tostring, '/')); + log_printf("tostring: drive:'%s'", al_get_path_drive(tostring)); + log_printf(" dirs:"); + for (i = 0; i < al_get_path_num_components(tostring); i++) { + if (i > 0) + log_printf(","); + log_printf(" '%s'", al_get_path_component(tostring, i)); + } + log_printf(" filename:'%s'\n", al_get_path_filename(tostring)); + al_destroy_path(tostring); + } + + /* FIXME: test out more of the al_path_ functions, ie: insert, remove, + * concat, relative + */ + + dyn = al_create_path(argv[1]); + if(dyn) { + cloned = al_clone_path(dyn); + if(cloned) { + log_printf("dyn: '%s'\n", al_path_cstr(dyn, '/')); + + al_make_path_canonical(cloned); + log_printf("can: '%s'\n", al_path_cstr(cloned, '/')); + + al_destroy_path(dyn); + al_destroy_path(cloned); + } + else { + log_printf("failed to clone ALLEGRO_PATH :(\n"); + al_destroy_path(dyn); + } + } + else { + log_printf("failed to create new ALLEGRO_PATH for cloning..."); + } + +done: + + close_log(true); + return 0; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_path_test.c b/allegro/examples/ex_path_test.c new file mode 100644 index 00000000..4e97924e --- /dev/null +++ b/allegro/examples/ex_path_test.c @@ -0,0 +1,583 @@ +/* + * Example program for the Allegro library. + * + * Stress test path routines. + */ + +#include +#include + +#include "common.c" + +#ifdef ALLEGRO_MSVC + #pragma warning (disable: 4066) +#endif + +typedef void (*test_t)(void); + +int error = 0; + +#define CHECK(x) \ + do { \ + bool ok = (bool)(x); \ + if (!ok) { \ + log_printf("FAIL %s\n", #x); \ + error++; \ + } else { \ + log_printf("OK %s\n", #x); \ + } \ + } while (0) + +#define CHECK_EQ(x,y) CHECK(0 == strcmp(x, y)) + +/*---------------------------------------------------------------------------*/ + +/* Test al_create_path, al_get_path_num_components, al_get_path_component, + * al_get_path_drive, al_get_path_filename, al_destroy_path. + */ +static void t1(void) +{ + ALLEGRO_PATH *path; + + CHECK(path = al_create_path(NULL)); + al_destroy_path(path); + + CHECK(path = al_create_path("")); + CHECK(al_get_path_num_components(path) == 0); + CHECK_EQ(al_get_path_drive(path), ""); + CHECK_EQ(al_get_path_filename(path), ""); + al_destroy_path(path); + + /* . is a directory component. */ + CHECK(path = al_create_path(".")); + CHECK(al_get_path_num_components(path) == 1); + CHECK_EQ(al_get_path_component(path, 0), "."); + CHECK_EQ(al_get_path_drive(path), ""); + CHECK_EQ(al_get_path_filename(path), ""); + al_destroy_path(path); + + /* .. is a directory component. */ + CHECK(path = al_create_path("..")); + CHECK(al_get_path_num_components(path) == 1); + CHECK_EQ(al_get_path_component(path, 0), ".."); + CHECK_EQ(al_get_path_drive(path), ""); + CHECK_EQ(al_get_path_filename(path), ""); + al_destroy_path(path); + + /* Relative path. */ + CHECK(path = al_create_path("abc/def/..")); + CHECK(al_get_path_num_components(path) == 3); + CHECK_EQ(al_get_path_component(path, 0), "abc"); + CHECK_EQ(al_get_path_component(path, 1), "def"); + CHECK_EQ(al_get_path_component(path, 2), ".."); + CHECK_EQ(al_get_path_drive(path), ""); + CHECK_EQ(al_get_path_filename(path), ""); + al_destroy_path(path); + + /* Absolute path. */ + CHECK(path = al_create_path("/abc/def/..")); + CHECK(al_get_path_num_components(path) == 4); + CHECK_EQ(al_get_path_component(path, 0), ""); + CHECK_EQ(al_get_path_component(path, 1), "abc"); + CHECK_EQ(al_get_path_component(path, 2), "def"); + CHECK_EQ(al_get_path_component(path, 3), ".."); + CHECK_EQ(al_get_path_drive(path), ""); + CHECK_EQ(al_get_path_filename(path), ""); + al_destroy_path(path); + + /* Directories + filename. */ + CHECK(path = al_create_path("/abc/def/ghi")); + CHECK(al_get_path_num_components(path) == 3); + CHECK_EQ(al_get_path_component(path, 0), ""); + CHECK_EQ(al_get_path_component(path, 1), "abc"); + CHECK_EQ(al_get_path_component(path, 2), "def"); + CHECK_EQ(al_get_path_drive(path), ""); + CHECK_EQ(al_get_path_filename(path), "ghi"); + al_destroy_path(path); +} + +/* Test parsing UNC paths. */ +static void t2(void) +{ +#ifdef ALLEGRO_WINDOWS + ALLEGRO_PATH *path; + + /* The mixed slashes are deliberate. */ + /* Good paths. */ + CHECK(path = al_create_path("//server\\share name/dir/filename")); + CHECK_EQ(al_get_path_drive(path), "//server"); + CHECK(al_get_path_num_components(path) == 2); + CHECK_EQ(al_get_path_component(path, 0), "share name"); + CHECK_EQ(al_get_path_component(path, 1), "dir"); + CHECK_EQ(al_get_path_filename(path), "filename"); + al_destroy_path(path); + + /* Bad paths. */ + CHECK(! al_create_path("//")); + CHECK(! al_create_path("//filename")); + CHECK(! al_create_path("///share/name/filename")); +#else + log_printf("Skipping Windows-only test...\n"); +#endif +} + +/* Test parsing drive letter paths. */ +static void t3(void) +{ +#ifdef ALLEGRO_WINDOWS + ALLEGRO_PATH *path; + + /* The mixed slashes are deliberate. */ + + CHECK(path = al_create_path("c:abc\\def/ghi")); + CHECK_EQ(al_get_path_drive(path), "c:"); + CHECK(al_get_path_num_components(path) == 2); + CHECK_EQ(al_get_path_component(path, 0), "abc"); + CHECK_EQ(al_get_path_component(path, 1), "def"); + CHECK_EQ(al_get_path_filename(path), "ghi"); + CHECK_EQ(al_path_cstr(path, '\\'), "c:abc\\def\\ghi"); + al_destroy_path(path); + + CHECK(path = al_create_path("c:\\abc/def\\ghi")); + CHECK_EQ(al_get_path_drive(path), "c:"); + CHECK(al_get_path_num_components(path) == 3); + CHECK_EQ(al_get_path_component(path, 0), ""); + CHECK_EQ(al_get_path_component(path, 1), "abc"); + CHECK_EQ(al_get_path_component(path, 2), "def"); + CHECK_EQ(al_get_path_filename(path), "ghi"); + CHECK_EQ(al_path_cstr(path, '\\'), "c:\\abc\\def\\ghi"); + al_destroy_path(path); +#else + log_printf("Skipping Windows-only test...\n"); +#endif +} + +/* Test al_append_path_component. */ +static void t4(void) +{ + ALLEGRO_PATH *path = al_create_path(NULL); + + CHECK(al_get_path_num_components(path) == 0); + + al_append_path_component(path, "abc"); + al_append_path_component(path, "def"); + al_append_path_component(path, "ghi"); + + CHECK(al_get_path_num_components(path) == 3); + + CHECK_EQ(al_get_path_component(path, 0), "abc"); + CHECK_EQ(al_get_path_component(path, 1), "def"); + CHECK_EQ(al_get_path_component(path, 2), "ghi"); + + CHECK_EQ(al_get_path_component(path, -1), "ghi"); + CHECK_EQ(al_get_path_component(path, -2), "def"); + CHECK_EQ(al_get_path_component(path, -3), "abc"); + + al_destroy_path(path); +} + +/* Test al_replace_path_component. */ +static void t5(void) +{ + ALLEGRO_PATH *path = al_create_path(NULL); + + al_append_path_component(path, "abc"); + al_append_path_component(path, "INKY"); + al_append_path_component(path, "def"); + al_append_path_component(path, "BLINKY"); + al_append_path_component(path, "ghi"); + + CHECK(al_get_path_num_components(path) == 5); + + al_replace_path_component(path, 1, "PINKY"); + al_replace_path_component(path, -2, "CLYDE"); + + CHECK(al_get_path_num_components(path) == 5); + + CHECK_EQ(al_get_path_component(path, 0), "abc"); + CHECK_EQ(al_get_path_component(path, 1), "PINKY"); + CHECK_EQ(al_get_path_component(path, 2), "def"); + CHECK_EQ(al_get_path_component(path, 3), "CLYDE"); + CHECK_EQ(al_get_path_component(path, 4), "ghi"); + + al_destroy_path(path); +} + +/* Test al_remove_path_component. */ +static void t6(void) +{ + ALLEGRO_PATH *path = al_create_path(NULL); + + al_append_path_component(path, "abc"); + al_append_path_component(path, "INKY"); + al_append_path_component(path, "def"); + al_append_path_component(path, "BLINKY"); + al_append_path_component(path, "ghi"); + + CHECK(al_get_path_num_components(path) == 5); + + al_remove_path_component(path, 1); + CHECK(al_get_path_num_components(path) == 4); + + al_remove_path_component(path, -2); + CHECK(al_get_path_num_components(path) == 3); + + CHECK_EQ(al_get_path_component(path, 0), "abc"); + CHECK_EQ(al_get_path_component(path, 1), "def"); + CHECK_EQ(al_get_path_component(path, 2), "ghi"); + + al_destroy_path(path); +} + +/* Test al_insert_path_component. */ +static void t7(void) +{ + ALLEGRO_PATH *path = al_create_path("INKY/BLINKY/"); + + al_insert_path_component(path, 0, "abc"); + al_insert_path_component(path, 2, "def"); + al_insert_path_component(path, 4, "ghi"); + + CHECK(al_get_path_num_components(path) == 5); + CHECK_EQ(al_get_path_component(path, 0), "abc"); + CHECK_EQ(al_get_path_component(path, 1), "INKY"); + CHECK_EQ(al_get_path_component(path, 2), "def"); + CHECK_EQ(al_get_path_component(path, 3), "BLINKY"); + CHECK_EQ(al_get_path_component(path, 4), "ghi"); + + al_destroy_path(path); +} + +/* Test al_get_path_tail, al_drop_path_tail. */ +static void t8(void) +{ + ALLEGRO_PATH *path = al_create_path(NULL); + + CHECK(! al_get_path_tail(path)); + + al_append_path_component(path, "abc"); + al_append_path_component(path, "def"); + al_append_path_component(path, "ghi"); + CHECK_EQ(al_get_path_tail(path), "ghi"); + + al_drop_path_tail(path); + CHECK_EQ(al_get_path_tail(path), "def"); + + al_drop_path_tail(path); + al_drop_path_tail(path); + CHECK(! al_get_path_tail(path)); + + /* Drop tail from already empty path. */ + al_drop_path_tail(path); + CHECK(! al_get_path_tail(path)); + + al_destroy_path(path); +} + +/* Test al_set_path_drive, al_set_path_filename, al_path_cstr. + */ +static void t9(void) +{ + ALLEGRO_PATH *path = al_create_path(NULL); + + CHECK_EQ(al_path_cstr(path, '/'), ""); + + /* Drive letters. */ + al_set_path_drive(path, "c:"); + CHECK_EQ(al_path_cstr(path, '/'), "c:"); + CHECK_EQ(al_get_path_drive(path), "c:"); + + al_set_path_drive(path, "d:"); + CHECK_EQ(al_path_cstr(path, '/'), "d:"); + + /* Plus directory components. */ + al_append_path_component(path, "abc"); + al_append_path_component(path, "def"); + CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/"); + + /* Plus filename. */ + al_set_path_filename(path, "uvw"); + CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/uvw"); + CHECK_EQ(al_get_path_filename(path), "uvw"); + + /* Replace filename. */ + al_set_path_filename(path, "xyz"); + CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/xyz"); + + /* Remove drive. */ + al_set_path_drive(path, NULL); + CHECK_EQ(al_path_cstr(path, '/'), "abc/def/xyz"); + + /* Remove filename. */ + al_set_path_filename(path, NULL); + CHECK_EQ(al_path_cstr(path, '/'), "abc/def/"); + + al_destroy_path(path); +} + +/* Test al_join_paths. */ +static void t10(void) +{ + ALLEGRO_PATH *path1; + ALLEGRO_PATH *path2; + + /* Both empty. */ + path1 = al_create_path(NULL); + path2 = al_create_path(NULL); + al_join_paths(path1, path2); + CHECK_EQ(al_path_cstr(path1, '/'), ""); + al_destroy_path(path1); + al_destroy_path(path2); + + /* Both just filenames. */ + path1 = al_create_path("file1"); + path2 = al_create_path("file2"); + al_join_paths(path1, path2); + CHECK_EQ(al_path_cstr(path1, '/'), "file2"); + al_destroy_path(path1); + al_destroy_path(path2); + + /* Both relative paths. */ + path1 = al_create_path("dir1a/dir1b/file1"); + path2 = al_create_path("dir2a/dir2b/file2"); + al_join_paths(path1, path2); + CHECK_EQ(al_path_cstr(path1, '/'), + "dir1a/dir1b/dir2a/dir2b/file2"); + al_destroy_path(path1); + al_destroy_path(path2); + +#ifdef ALLEGRO_WINDOWS + /* Both relative paths with drive letters. */ + path1 = al_create_path("d:dir1a/dir1b/file1"); + path2 = al_create_path("e:dir2a/dir2b/file2"); + al_join_paths(path1, path2); + CHECK_EQ(al_path_cstr(path1, '/'), "d:dir1a/dir1b/dir2a/dir2b/file2"); + al_destroy_path(path1); + al_destroy_path(path2); +#endif + + /* Path1 absolute, path2 relative. */ + path1 = al_create_path("/dir1a/dir1b/file1"); + path2 = al_create_path("dir2a/dir2b/file2"); + al_join_paths(path1, path2); + CHECK_EQ(al_path_cstr(path1, '/'), "/dir1a/dir1b/dir2a/dir2b/file2"); + al_destroy_path(path1); + al_destroy_path(path2); + + /* Both paths absolute. */ + path1 = al_create_path("/dir1a/dir1b/file1"); + path2 = al_create_path("/dir2a/dir2b/file2"); + al_join_paths(path1, path2); + CHECK_EQ(al_path_cstr(path1, '/'), "/dir1a/dir1b/file1"); + al_destroy_path(path1); + al_destroy_path(path2); +} + +/* Test al_rebase_path. */ +static void t11(void) +{ + ALLEGRO_PATH *path1; + ALLEGRO_PATH *path2; + + /* Both empty. */ + path1 = al_create_path(NULL); + path2 = al_create_path(NULL); + al_rebase_path(path1, path2); + CHECK_EQ(al_path_cstr(path2, '/'), ""); + al_destroy_path(path1); + al_destroy_path(path2); + + /* Both just filenames. */ + path1 = al_create_path("file1"); + path2 = al_create_path("file2"); + al_rebase_path(path1, path2); + CHECK_EQ(al_path_cstr(path2, '/'), "file2"); + al_destroy_path(path1); + al_destroy_path(path2); + + /* Both relative paths. */ + path1 = al_create_path("dir1a/dir1b/file1"); + path2 = al_create_path("dir2a/dir2b/file2"); + al_rebase_path(path1, path2); + CHECK_EQ(al_path_cstr(path2, '/'), + "dir1a/dir1b/dir2a/dir2b/file2"); + al_destroy_path(path1); + al_destroy_path(path2); + +#ifdef ALLEGRO_WINDOWS + /* Both relative paths with drive letters. */ + path1 = al_create_path("d:dir1a/dir1b/file1"); + path2 = al_create_path("e:dir2a/dir2b/file2"); + al_rebase_path(path1, path2); + CHECK_EQ(al_path_cstr(path2, '/'), "d:dir1a/dir1b/dir2a/dir2b/file2"); + al_destroy_path(path1); + al_destroy_path(path2); +#endif + + /* Path1 absolute, path2 relative. */ + path1 = al_create_path("/dir1a/dir1b/file1"); + path2 = al_create_path("dir2a/dir2b/file2"); + al_rebase_path(path1, path2); + CHECK_EQ(al_path_cstr(path2, '/'), "/dir1a/dir1b/dir2a/dir2b/file2"); + al_destroy_path(path1); + al_destroy_path(path2); + + /* Both paths absolute. */ + path1 = al_create_path("/dir1a/dir1b/file1"); + path2 = al_create_path("/dir2a/dir2b/file2"); + al_rebase_path(path1, path2); + CHECK_EQ(al_path_cstr(path2, '/'), "/dir2a/dir2b/file2"); + al_destroy_path(path1); + al_destroy_path(path2); +} + +/* Test al_set_path_extension, al_get_path_extension. */ +static void t12(void) +{ + ALLEGRO_PATH *path = al_create_path(NULL); + + /* Get null extension. */ + CHECK_EQ(al_get_path_extension(path), ""); + + /* Set extension on null filename. */ + CHECK(! al_set_path_extension(path, "ext")); + CHECK_EQ(al_get_path_filename(path), ""); + + /* Set extension on extension-less filename. */ + al_set_path_filename(path, "abc"); + CHECK(al_set_path_extension(path, ".ext")); + CHECK_EQ(al_get_path_filename(path), "abc.ext"); + + /* Replacing extension. */ + al_set_path_filename(path, "abc.def"); + CHECK(al_set_path_extension(path, ".ext")); + CHECK_EQ(al_get_path_filename(path), "abc.ext"); + CHECK_EQ(al_get_path_extension(path), ".ext"); + + /* Filename with multiple dots. */ + al_set_path_filename(path, "abc.def.ghi"); + CHECK(al_set_path_extension(path, ".ext")); + CHECK_EQ(al_get_path_filename(path), "abc.def.ext"); + CHECK_EQ(al_get_path_extension(path), ".ext"); + + al_destroy_path(path); +} + +/* Test al_get_path_basename. */ +static void t13(void) +{ + ALLEGRO_PATH *path = al_create_path(NULL); + + /* No filename. */ + al_set_path_filename(path, NULL); + CHECK_EQ(al_get_path_basename(path), ""); + + /* No extension. */ + al_set_path_filename(path, "abc"); + CHECK_EQ(al_get_path_basename(path), "abc"); + + /* Filename with a single dot. */ + al_set_path_filename(path, "abc.ext"); + CHECK_EQ(al_get_path_basename(path), "abc"); + + /* Filename with multiple dots. */ + al_set_path_filename(path, "abc.def.ghi"); + CHECK_EQ(al_get_path_basename(path), "abc.def"); + + al_destroy_path(path); +} + +/* Test al_clone_path. */ +static void t14(void) +{ + ALLEGRO_PATH *path1; + ALLEGRO_PATH *path2; + + path1 = al_create_path("/abc/def/ghi"); + path2 = al_clone_path(path1); + + CHECK_EQ(al_path_cstr(path1, '/'), al_path_cstr(path2, '/')); + + al_replace_path_component(path2, 2, "DEF"); + al_set_path_filename(path2, "GHI"); + CHECK_EQ(al_path_cstr(path1, '/'), "/abc/def/ghi"); + CHECK_EQ(al_path_cstr(path2, '/'), "/abc/DEF/GHI"); + + al_destroy_path(path1); + al_destroy_path(path2); +} + +static void t15(void) +{ + /* nothing */ + log_printf("Skipping empty test...\n"); +} + +static void t16(void) +{ + /* nothing */ + log_printf("Skipping empty test...\n"); +} + +/* Test al_make_path_canonical. */ +static void t17(void) +{ + ALLEGRO_PATH *path; + + path = al_create_path("/../.././abc/./def/../../ghi/jkl"); + CHECK(al_make_path_canonical(path)); + CHECK(al_get_path_num_components(path) == 6); + CHECK_EQ(al_path_cstr(path, '/'), "/abc/def/../../ghi/jkl"); + al_destroy_path(path); + + path = al_create_path("../.././abc/./def/../../ghi/jkl"); + CHECK(al_make_path_canonical(path)); + CHECK(al_get_path_num_components(path) == 7); + CHECK_EQ(al_path_cstr(path, '/'), "../../abc/def/../../ghi/jkl"); + al_destroy_path(path); +} + +/*---------------------------------------------------------------------------*/ + +const test_t all_tests[] = +{ + NULL, t1, t2, t3, t4, t5, t6, t7, t8, t9, + t10, t11, t12, t13, t14, t15, t16, t17 +}; + +#define NUM_TESTS (int)(sizeof(all_tests) / sizeof(all_tests[0])) + +int main(int argc, char **argv) +{ + int i; + + if (!al_init()) { + abort_example("Could not initialise Allegro.\n"); + } + open_log(); + + if (argc < 2) { + for (i = 1; i < NUM_TESTS; i++) { + log_printf("# t%d\n\n", i); + all_tests[i](); + log_printf("\n"); + } + } + else { + i = atoi(argv[1]); + if (i > 0 && i < NUM_TESTS) { + all_tests[i](); + } + } + log_printf("Done\n"); + + close_log(true); + + if (error) { + exit(EXIT_FAILURE); + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_physfs.c b/allegro/examples/ex_physfs.c new file mode 100644 index 00000000..0f32c637 --- /dev/null +++ b/allegro/examples/ex_physfs.c @@ -0,0 +1,182 @@ +/* + * Example program for Allegro library. + * + * Demonstrate PhysicsFS addon. + */ + + +#include +#include +#include +#include +#include + +#include "common.c" + +static void show_image(ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + while (true) { + al_draw_bitmap(bmp, 0, 0, 0); + al_flip_display(); + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN + && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + } + + al_destroy_event_queue(queue); +} + +static void print_file(ALLEGRO_FS_ENTRY *entry) +{ + int mode = al_get_fs_entry_mode(entry); + time_t now = time(NULL); + time_t atime = al_get_fs_entry_atime(entry); + time_t ctime = al_get_fs_entry_ctime(entry); + time_t mtime = al_get_fs_entry_mtime(entry); + const char *name = al_get_fs_entry_name(entry); + off_t size = al_get_fs_entry_size(entry); + + log_printf("%-36s %s%s%s%s%s%s %8u %8u %8u %8u\n", + name, + mode & ALLEGRO_FILEMODE_READ ? "r" : ".", + mode & ALLEGRO_FILEMODE_WRITE ? "w" : ".", + mode & ALLEGRO_FILEMODE_EXECUTE ? "x" : ".", + mode & ALLEGRO_FILEMODE_HIDDEN ? "h" : ".", + mode & ALLEGRO_FILEMODE_ISFILE ? "f" : ".", + mode & ALLEGRO_FILEMODE_ISDIR ? "d" : ".", + (unsigned)(now - ctime), + (unsigned)(now - mtime), + (unsigned)(now - atime), + (unsigned)size); +} + +static void listdir(ALLEGRO_FS_ENTRY *entry) +{ + ALLEGRO_FS_ENTRY *next; + + al_open_directory(entry); + while (1) { + next = al_read_directory(entry); + if (!next) + break; + + print_file(next); + if (al_get_fs_entry_mode(next) & ALLEGRO_FILEMODE_ISDIR) + listdir(next); + al_destroy_fs_entry(next); + } + al_close_directory(entry); +} + +static bool add_main_zipfile(void) +{ + ALLEGRO_PATH *exe; + const char *ext; + const char *zipfile; + bool ret; + + /* On Android we treat the APK itself as the zip file. */ + exe = al_get_standard_path(ALLEGRO_EXENAME_PATH); + ext = al_get_path_extension(exe); + if (0 == strcmp(ext, ".apk")) { + zipfile = al_path_cstr(exe, '/'); + } + else { + zipfile = "data/ex_physfs.zip"; + } + + if (PHYSFS_mount(zipfile, NULL, 1)) { + ret = true; + } + else { + log_printf("Could load the zip file: %s\n", zipfile); + ret = false; + } + + al_destroy_path(exe); + + return ret; +} + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bmp; + ALLEGRO_FS_ENTRY *entry; + int i; + + if (!al_init()) { + abort_example("Could not init Allegro\n"); + } + al_init_image_addon(); + al_install_keyboard(); + open_log_monospace(); + + /* Set up PhysicsFS. */ + if (!PHYSFS_init(argv[0])) { + abort_example("Could not init PhysFS\n"); + } + // This creates a ~/.allegro directory, which is very annoying to say the + // least - and no need for it in this example. + // if (!PHYSFS_setSaneConfig("allegro", "ex_physfs", NULL, 0, 0)) + // return 1; + if (!add_main_zipfile()) { + abort_example("Could not add zip file\n"); + } + + for (i = 1; i < argc; i++) { + if (!PHYSFS_mount(argv[i], NULL, 1)) { + abort_example("Couldn't add %s\n", argv[i]); + } + } + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display.\n"); + } + + /* Make future calls to al_fopen() on this thread go to the PhysicsFS + * backend. + */ + al_set_physfs_file_interface(); + + /* List the contents of our example zip recursively. */ + log_printf("%-36s %-6s %8s %8s %8s %8s\n", + "name", "flags", "ctime", "mtime", "atime", "size"); + log_printf( + "------------------------------------ " + "------ " + "-------- " + "-------- " + "-------- " + "--------\n"); + entry = al_create_fs_entry(""); + listdir(entry); + al_destroy_fs_entry(entry); + + bmp = al_load_bitmap("02.bmp"); + if (!bmp) { + /* Fallback for Android. */ + bmp = al_load_bitmap("assets/data/alexlogo.bmp"); + } + if (bmp) { + show_image(bmp); + al_destroy_bitmap(bmp); + } + + PHYSFS_deinit(); + + close_log(false); + return 0; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_pixelformat.cpp b/allegro/examples/ex_pixelformat.cpp new file mode 100644 index 00000000..a16e8558 --- /dev/null +++ b/allegro/examples/ex_pixelformat.cpp @@ -0,0 +1,272 @@ +/* + * Simple (incomplete) test of pixel format conversions. + * + * This should be made comprehensive. + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_primitives.h" +#include "nihgui.hpp" + +#include "common.c" + +typedef struct FORMAT +{ + int format; + char const *name; +} FORMAT; + +const FORMAT formats[ALLEGRO_NUM_PIXEL_FORMATS] = { + {ALLEGRO_PIXEL_FORMAT_ANY, "any"}, + {ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA, "no alpha"}, + {ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, "alpha"}, + {ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA, "15"}, + {ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA, "16"}, + {ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA, "16 alpha"}, + {ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, "24"}, + {ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA, "32"}, + {ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA, "32 alpha"}, + {ALLEGRO_PIXEL_FORMAT_ARGB_8888, "ARGB8888"}, + {ALLEGRO_PIXEL_FORMAT_RGBA_8888, "RGBA8888"}, + {ALLEGRO_PIXEL_FORMAT_ARGB_4444, "ARGB4444"}, + {ALLEGRO_PIXEL_FORMAT_RGB_888, "RGB888"}, + {ALLEGRO_PIXEL_FORMAT_RGB_565, "RGB565"}, + {ALLEGRO_PIXEL_FORMAT_RGB_555, "RGB555"}, + {ALLEGRO_PIXEL_FORMAT_RGBA_5551, "RGBA5551"}, + {ALLEGRO_PIXEL_FORMAT_ARGB_1555, "ARGB1555"}, + {ALLEGRO_PIXEL_FORMAT_ABGR_8888, "ABGR8888"}, + {ALLEGRO_PIXEL_FORMAT_XBGR_8888, "XBGR8888"}, + {ALLEGRO_PIXEL_FORMAT_BGR_888, "BGR888"}, + {ALLEGRO_PIXEL_FORMAT_BGR_565, "BGR565"}, + {ALLEGRO_PIXEL_FORMAT_BGR_555, "BGR555"}, + {ALLEGRO_PIXEL_FORMAT_RGBX_8888, "RGBX8888"}, + {ALLEGRO_PIXEL_FORMAT_XRGB_8888, "XRGB8888"}, + {ALLEGRO_PIXEL_FORMAT_ABGR_F32, "ABGR32F"}, + {ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, "ABGR(LE)"}, + {ALLEGRO_PIXEL_FORMAT_RGBA_4444, "RGBA4444"}, + {ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, "SINGLE_CHANNEL_8"}, + {ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1, "RGBA_DXT1"}, + {ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3, "RGBA_DXT3"}, + {ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5, "RGBA_DXT5"}, +}; + +#define NUM_FORMATS ALLEGRO_NUM_PIXEL_FORMATS + + +const char *get_format_name(ALLEGRO_BITMAP *bmp) +{ + if (!bmp) + return "none"; + + int format = al_get_bitmap_format(bmp); + for (unsigned i = 0; i < NUM_FORMATS; i++) { + if (formats[i].format == format) + return formats[i].name; + } + return "unknown"; +} + + +class Prog { +private: + Dialog d; + Label source_label; + Label dest_label; + List source_list; + List dest_list; + Label true_formats; + ToggleButton use_memory_button; + ToggleButton enable_timing_button; + Label time_label; + const char* bmp_filename; + +public: + Prog(const Theme & theme, ALLEGRO_DISPLAY *display, const char* bmp_filename); + void run(); + +private: + void draw_sample(); +}; + + +Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display, const char* bmp_filename) : + d(Dialog(theme, display, 20, 30)), + source_label(Label("Source")), + dest_label(Label("Destination")), + source_list(List()), + dest_list(List()), + true_formats(Label("")), + use_memory_button(ToggleButton("Use memory bitmaps")), + enable_timing_button(ToggleButton("Enable timing")), + time_label(Label("")), + bmp_filename(bmp_filename) +{ + d.add(source_label, 11, 0, 4, 1); + d.add(source_list, 11, 1, 4, 27); + d.add(dest_label, 15, 0, 4, 1); + d.add(dest_list, 15, 1, 4, 27); + d.add(true_formats, 0, 20, 10, 1); + d.add(use_memory_button, 0, 24, 10, 2); + d.add(enable_timing_button, 0, 26, 10, 2); + d.add(time_label, 0, 22, 10, 1); + + for (unsigned i = 0; i < NUM_FORMATS; i++) { + source_list.append_item(formats[i].name); + dest_list.append_item(formats[i].name); + } +} + + +void Prog::run() +{ + d.prepare(); + + while (!d.is_quit_requested()) { + if (d.is_draw_requested()) { + al_clear_to_color(al_map_rgb(128, 128, 128)); + draw_sample(); + d.draw(); + al_flip_display(); + } + + d.run_step(true); + } +} + + +void Prog::draw_sample() +{ + const int i = source_list.get_cur_value(); + const int j = dest_list.get_cur_value(); + ALLEGRO_BITMAP *bitmap1; + ALLEGRO_BITMAP *bitmap2; + bool use_memory = use_memory_button.get_pushed(); + bool enable_timing = enable_timing_button.get_pushed(); + int bmp_w = 128; + int bmp_h = 128; + + if (use_memory) + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + else + al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); + + al_set_new_bitmap_format(formats[i].format); + + bitmap1 = al_load_bitmap(bmp_filename); + if (!bitmap1) { + log_printf("Could not load image %s, bitmap format = %d\n", bmp_filename, + formats[i].format); + } + else { + bmp_w = al_get_bitmap_width(bitmap1); + bmp_h = al_get_bitmap_height(bitmap1); + } + + al_set_new_bitmap_format(formats[j].format); + + bitmap2 = al_create_bitmap(bmp_w, bmp_h); + if (!bitmap2) { + log_printf("Could not create bitmap, format = %d\n", formats[j].format); + } + + if (bitmap1 && bitmap2) { + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + + al_set_target_bitmap(bitmap2); + al_clear_to_color(al_map_rgb(128, 128, 128)); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + if (enable_timing) { + double t0, t1; + char str[256]; + int frames = 0; + + t0 = al_get_time(); + log_printf("Timing...\n"); + do { + al_draw_bitmap(bitmap1, 0, 0, 0); + frames++; + t1 = al_get_time(); + } while (t1 - t0 < 0.25); + log_printf(" ...done.\n"); + sprintf(str, "%.0f FPS", (double)frames / (t1 - t0)); + time_label.set_text(str); + } + else { + al_draw_bitmap(bitmap1, 0, 0, 0); + time_label.set_text(""); + } + + al_set_target_bitmap(target); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_bitmap(bitmap2, 0, 0, 0); + } + else { + al_draw_line(0, 0, 320, 200, al_map_rgb_f(1, 0, 0), 0); + al_draw_line(0, 200, 320, 0, al_map_rgb_f(1, 0, 0), 0); + } + + std::string s = get_format_name(bitmap1); + s += " -> "; + s += get_format_name(bitmap2); + true_formats.set_text(s); + + al_destroy_bitmap(bitmap1); + al_destroy_bitmap(bitmap2); +} + + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + const char* bmp_filename = "data/allegro.pcx"; + + if (argc > 1) { + bmp_filename = argv[1]; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_init_primitives_addon(); + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + al_install_keyboard(); + al_install_mouse(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(800, 600); + if (!display) { + abort_example("Error creating display\n"); + } + + //log_printf("Display format = %d\n", al_get_display_format()); + + font = al_load_font("data/fixed_font.tga", 0, 0); + if (!font) { + abort_example("Failed to load data/fixed_font.tga\n"); + } + + /* Don't remove these braces. */ + { + Theme theme(font); + Prog prog(theme, display, bmp_filename); + prog.run(); + } + + al_destroy_font(font); + + close_log(false); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_polygon.c b/allegro/examples/ex_polygon.c new file mode 100644 index 00000000..d34166c6 --- /dev/null +++ b/allegro/examples/ex_polygon.c @@ -0,0 +1,496 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * This program tests the polygon routines in the primitives addon. + */ + +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include +#include + +#include "common.c" + +#define MAX_VERTICES 64 +#define MAX_POLYGONS 9 +#define RADIUS 5 + +enum { + MODE_POLYLINE = 0, + MODE_POLYGON, + MODE_FILLED_POLYGON, + MODE_FILLED_HOLES, + MODE_MAX +}; + +enum AddHole { + NOT_ADDING_HOLE, + NEW_HOLE, + GROW_HOLE +}; + +typedef struct Vertex Vertex; +struct Vertex { + float x; + float y; +}; + +struct Example { + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + ALLEGRO_FONT *fontbmp; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_BITMAP *dbuf; + ALLEGRO_COLOR bg; + ALLEGRO_COLOR fg; + Vertex vertices[MAX_VERTICES]; + int vertex_polygon[MAX_VERTICES]; + int vertex_count; + int cur_vertex; /* -1 = none */ + int cur_polygon; + int mode; + ALLEGRO_LINE_CAP cap_style; + ALLEGRO_LINE_JOIN join_style; + float thickness; + float miter_limit; + bool software; + float zoom; + float scroll_x, scroll_y; + enum AddHole add_hole; +}; + +static struct Example ex; + +static void reset(void) +{ + ex.vertex_count = 0; + ex.cur_vertex = -1; + ex.cur_polygon = 0; + ex.cap_style = ALLEGRO_LINE_CAP_NONE; + ex.join_style = ALLEGRO_LINE_JOIN_NONE; + ex.thickness = 1.0f; + ex.miter_limit = 1.0f; + ex.software = false; + ex.zoom = 1; + ex.scroll_x = 0; + ex.scroll_y = 0; + ex.add_hole = NOT_ADDING_HOLE; +} + +static void transform(float *x, float *y) +{ + *x /= ex.zoom; + *y /= ex.zoom; + *x -= ex.scroll_x; + *y -= ex.scroll_y; +} + +static int hit_vertex(int mx, int my) +{ + int i; + + for (i = 0; i < ex.vertex_count; i++) { + int dx = ex.vertices[i].x - mx; + int dy = ex.vertices[i].y - my; + int dd = dx*dx + dy*dy; + if (dd <= RADIUS * RADIUS) + return i; + } + + return -1; +} + +static void lclick(int mx, int my) +{ + ex.cur_vertex = hit_vertex(mx, my); + + if (ex.cur_vertex < 0 && ex.vertex_count < MAX_VERTICES) { + int i = ex.vertex_count++; + ex.vertices[i].x = mx; + ex.vertices[i].y = my; + ex.cur_vertex = i; + + if (ex.add_hole == NEW_HOLE && ex.cur_polygon < MAX_POLYGONS) { + ex.cur_polygon++; + ex.add_hole = GROW_HOLE; + } + + ex.vertex_polygon[i] = ex.cur_polygon; + } +} + +static void rclick(int mx, int my) +{ + const int i = hit_vertex(mx, my); + if (i >= 0 && ex.add_hole == NOT_ADDING_HOLE) { + ex.vertex_count--; + memmove(&ex.vertices[i], &ex.vertices[i + 1], + sizeof(Vertex) * (ex.vertex_count - i)); + memmove(&ex.vertex_polygon[i], &ex.vertex_polygon[i + 1], + sizeof(int) * (ex.vertex_count - i)); + } + ex.cur_vertex = -1; +} + +static void drag(int mx, int my) +{ + if (ex.cur_vertex >= 0) { + ex.vertices[ex.cur_vertex].x = mx; + ex.vertices[ex.cur_vertex].y = my; + } +} + +static void scroll(int mx, int my) +{ + ex.scroll_x += mx; + ex.scroll_y += my; +} + +static const char *join_style_to_string(ALLEGRO_LINE_JOIN x) +{ + switch (x) { + case ALLEGRO_LINE_JOIN_NONE: + return "NONE"; + case ALLEGRO_LINE_JOIN_BEVEL: + return "BEVEL"; + case ALLEGRO_LINE_JOIN_ROUND: + return "ROUND"; + case ALLEGRO_LINE_JOIN_MITER: + return "MITER"; + default: + return "unknown"; + } +} + +static const char *cap_style_to_string(ALLEGRO_LINE_CAP x) +{ + switch (x) { + case ALLEGRO_LINE_CAP_NONE: + return "NONE"; + case ALLEGRO_LINE_CAP_SQUARE: + return "SQUARE"; + case ALLEGRO_LINE_CAP_ROUND: + return "ROUND"; + case ALLEGRO_LINE_CAP_TRIANGLE: + return "TRIANGLE"; + case ALLEGRO_LINE_CAP_CLOSED: + return "CLOSED"; + default: + return "unknown"; + } +} + +static ALLEGRO_FONT *choose_font(void) +{ + return (ex.software) ? ex.fontbmp : ex.font; +} + +static void draw_vertices(void) +{ + ALLEGRO_FONT *f = choose_font(); + ALLEGRO_COLOR vertc = al_map_rgba_f(0.7, 0, 0, 0.7); + ALLEGRO_COLOR textc = al_map_rgba_f(0, 0, 0, 0.7); + int i; + + for (i = 0; i < ex.vertex_count; i++) { + float x = ex.vertices[i].x; + float y = ex.vertices[i].y; + + al_draw_filled_circle(x, y, RADIUS, vertc); + al_draw_textf(f, textc, x + RADIUS, y + RADIUS, 0, "%d", i); + } +} + +static void compute_polygon_vertex_counts( + int polygon_vertex_count[MAX_POLYGONS + 1]) +{ + int i; + + /* This also implicitly terminates the array with a zero. */ + memset(polygon_vertex_count, 0, sizeof(int) * (MAX_POLYGONS + 1)); + for (i = 0; i < ex.vertex_count; i++) { + const int poly = ex.vertex_polygon[i]; + polygon_vertex_count[poly]++; + } +} + +static void draw_all(void) +{ + ALLEGRO_FONT *f = choose_font(); + ALLEGRO_COLOR textc = al_map_rgb(0, 0, 0); + float texth = al_get_font_line_height(f) * 1.5; + float textx = 5; + float texty = 5; + ALLEGRO_TRANSFORM t; + ALLEGRO_COLOR holec; + + al_clear_to_color(ex.bg); + + al_identity_transform(&t); + al_translate_transform(&t, ex.scroll_x, ex.scroll_y); + al_scale_transform(&t, ex.zoom, ex.zoom); + al_use_transform(&t); + + if (ex.mode == MODE_POLYLINE) { + if (ex.vertex_count >= 2) { + al_draw_polyline( + (float *)ex.vertices, sizeof(Vertex), ex.vertex_count, + ex.join_style, ex.cap_style, ex.fg, ex.thickness, ex.miter_limit); + } + } + else if (ex.mode == MODE_FILLED_POLYGON) { + if (ex.vertex_count >= 2) { + al_draw_filled_polygon( + (float *)ex.vertices, ex.vertex_count, ex.fg); + } + } + else if (ex.mode == MODE_POLYGON) { + if (ex.vertex_count >= 2) { + al_draw_polygon( + (float *)ex.vertices, ex.vertex_count, + ex.join_style, ex.fg, ex.thickness, ex.miter_limit); + } + } + else if (ex.mode == MODE_FILLED_HOLES) { + if (ex.vertex_count >= 2) { + int polygon_vertex_count[MAX_POLYGONS + 1]; + compute_polygon_vertex_counts(polygon_vertex_count); + al_draw_filled_polygon_with_holes( + (float *)ex.vertices, polygon_vertex_count, ex.fg); + } + } + + draw_vertices(); + + al_identity_transform(&t); + al_use_transform(&t); + + if (ex.mode == MODE_POLYLINE) { + al_draw_textf(f, textc, textx, texty, 0, + "al_draw_polyline (SPACE)"); + texty += texth; + } + else if (ex.mode == MODE_FILLED_POLYGON) { + al_draw_textf(f, textc, textx, texty, 0, + "al_draw_filled_polygon (SPACE)"); + texty += texth; + } + else if (ex.mode == MODE_POLYGON) { + al_draw_textf(f, textc, textx, texty, 0, + "al_draw_polygon (SPACE)"); + texty += texth; + } + else if (ex.mode == MODE_FILLED_HOLES) { + al_draw_textf(f, textc, textx, texty, 0, + "al_draw_filled_polygon_with_holes (SPACE)"); + texty += texth; + } + + al_draw_textf(f, textc, textx, texty, 0, + "Line join style: %s (J)", join_style_to_string(ex.join_style)); + texty += texth; + + al_draw_textf(f, textc, textx, texty, 0, + "Line cap style: %s (C)", cap_style_to_string(ex.cap_style)); + texty += texth; + + al_draw_textf(f, textc, textx, texty, 0, + "Line thickness: %.2f (+/-)", ex.thickness); + texty += texth; + + al_draw_textf(f, textc, textx, texty, 0, + "Miter limit: %.2f ([/])", ex.miter_limit); + texty += texth; + + al_draw_textf(f, textc, textx, texty, 0, + "Zoom: %.2f (wheel)", ex.zoom); + texty += texth; + + al_draw_textf(f, textc, textx, texty, 0, + "%s (S)", (ex.software ? "Software rendering" : "Hardware rendering")); + texty += texth; + + al_draw_textf(f, textc, textx, texty, 0, + "Reset (R)"); + texty += texth; + + if (ex.add_hole == NOT_ADDING_HOLE) + holec = textc; + else if (ex.add_hole == GROW_HOLE) + holec = al_map_rgb(200, 0, 0); + else + holec = al_map_rgb(0, 200, 0); + al_draw_textf(f, holec, textx, texty, 0, + "Add Hole (%d) (H)", ex.cur_polygon); + texty += texth; +} + +/* Print vertices in a format for the test suite. */ +static void print_vertices(void) +{ + int i; + + for (i = 0; i < ex.vertex_count; i++) { + log_printf("v%-2d= %.2f, %.2f\n", + i, ex.vertices[i].x, ex.vertices[i].y); + } + log_printf("\n"); +} + +int main(int argc, char **argv) +{ + ALLEGRO_EVENT event; + bool have_touch_input; + bool mdown = false; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + if (!al_init_primitives_addon()) { + abort_example("Could not init primitives.\n"); + } + al_init_font_addon(); + al_install_mouse(); + al_install_keyboard(); + have_touch_input = al_install_touch_input(); + + ex.display = al_create_display(800, 600); + if (!ex.display) { + abort_example("Error creating display\n"); + } + + ex.font = al_create_builtin_font(); + if (!ex.font) { + abort_example("Error creating builtin font\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + ex.dbuf = al_create_bitmap(800, 600); + ex.fontbmp = al_create_builtin_font(); + if (!ex.fontbmp) { + abort_example("Error creating builtin font\n"); + } + + ex.queue = al_create_event_queue(); + al_register_event_source(ex.queue, al_get_keyboard_event_source()); + al_register_event_source(ex.queue, al_get_mouse_event_source()); + al_register_event_source(ex.queue, al_get_display_event_source(ex.display)); + if (have_touch_input) { + al_register_event_source(ex.queue, al_get_touch_input_event_source()); + al_register_event_source(ex.queue, al_get_touch_input_mouse_emulation_event_source()); + } + + ex.bg = al_map_rgba_f(1, 1, 0.9, 1); + ex.fg = al_map_rgba_f(0, 0.5, 1, 1); + + reset(); + + for (;;) { + if (al_is_event_queue_empty(ex.queue)) { + if (ex.software) { + al_set_target_bitmap(ex.dbuf); + draw_all(); + al_set_target_backbuffer(ex.display); + al_draw_bitmap(ex.dbuf, 0, 0, 0); + } + else { + al_set_target_backbuffer(ex.display); + draw_all(); + } + al_flip_display(); + } + + al_wait_for_event(ex.queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + switch (toupper(event.keyboard.unichar)) { + case ' ': + if (++ex.mode >= MODE_MAX) + ex.mode = 0; + break; + case 'J': + if (++ex.join_style > ALLEGRO_LINE_JOIN_MITER) + ex.join_style = ALLEGRO_LINE_JOIN_NONE; + break; + case 'C': + if (++ex.cap_style > ALLEGRO_LINE_CAP_CLOSED) + ex.cap_style = ALLEGRO_LINE_CAP_NONE; + break; + case '+': + ex.thickness += 0.25f; + break; + case '-': + ex.thickness -= 0.25f; + if (ex.thickness <= 0.0f) + ex.thickness = 0.0f; + break; + case '[': + ex.miter_limit -= 0.1f; + if (ex.miter_limit < 0.0f) + ex.miter_limit = 0.0f; + break; + case ']': + ex.miter_limit += 0.1f; + if (ex.miter_limit >= 10.0f) + ex.miter_limit = 10.0f; + break; + case 'S': + ex.software = !ex.software; + break; + case 'R': + reset(); + break; + case 'P': + print_vertices(); + break; + case 'H': + ex.add_hole = NEW_HOLE; + break; + } + } + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + float x = event.mouse.x, y = event.mouse.y; + transform(&x, &y); + if (event.mouse.button == 1) + lclick(x, y); + if (event.mouse.button == 2) + rclick(x, y); + if (event.mouse.button == 3) + mdown = true; + } + if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { + ex.cur_vertex = -1; + if (event.mouse.button == 3) + mdown = false; + } + if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + float x = event.mouse.x, y = event.mouse.y; + transform(&x, &y); + + if (mdown) + scroll(event.mouse.dx, event.mouse.dy); + else + drag(x, y); + + ex.zoom *= pow(0.9, event.mouse.dz); + } + } + + al_destroy_display(ex.display); + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_premulalpha.c b/allegro/examples/ex_premulalpha.c new file mode 100644 index 00000000..d512a7b3 --- /dev/null +++ b/allegro/examples/ex_premulalpha.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *tex1, *tex2; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + bool redraw = true; + ALLEGRO_LOCKED_REGION *lock; + ALLEGRO_FONT *font; + unsigned char *p; + int x, y; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_font_addon(); + + al_install_mouse(); + al_install_keyboard(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + font = al_create_builtin_font(); + + tex1 = al_create_bitmap(8, 8); + lock = al_lock_bitmap(tex1, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY); + p = lock->data; + for (y = 0; y < 8; y++) { + unsigned char *lp = p; + for (x = 0; x < 8; x++) { + if (x == 0 || y == 0 || x == 7 || y == 7) { + p[0] = 0; + p[1] = 0; + p[2] = 0; + p[3] = 0; + } + else { + p[0] = 0; + p[1] = 255; + p[2] = 0; + p[3] = 255; + } + p += 4; + } + p = lp + lock->pitch; + } + al_unlock_bitmap(tex1); + + al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR); + tex2 = al_clone_bitmap(tex1); + + timer = al_create_timer(1.0 / 30); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + } + if (event.type == ALLEGRO_EVENT_TIMER) + redraw = true; + + if (redraw && al_is_event_queue_empty(queue)) { + float x = 8, y = 60; + float a, t = al_get_time(); + float th = al_get_font_line_height(font); + ALLEGRO_COLOR color = al_map_rgb_f(0, 0, 0); + ALLEGRO_COLOR color2 = al_map_rgb_f(1, 0, 0); + ALLEGRO_COLOR color3 = al_map_rgb_f(0, 0.5, 0); + + t /= 10; + a = t - floor(t); + a *= 2 * ALLEGRO_PI; + + redraw = false; + al_clear_to_color(al_map_rgb_f(0.5, 0.6, 1)); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, color, x, y, 0, "not premultiplied"); + al_draw_textf(font, color, x, y + th, 0, "no filtering"); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + al_draw_scaled_rotated_bitmap(tex1, 4, 4, x + 320, y, 8, 8, a, 0); + + y += 120; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, color, x, y, 0, "not premultiplied"); + al_draw_textf(font, color, x, y + th, 0, "mag linear filtering"); + al_draw_textf(font, color2, x + 400, y, 0, "wrong dark border"); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + al_draw_scaled_rotated_bitmap(tex2, 4, 4, x + 320, y, 8, 8, a, 0); + + y += 120; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, color, x, y, 0, "premultiplied alpha"); + al_draw_textf(font, color, x, y + th, 0, "no filtering"); + al_draw_textf(font, color, x + 400, y, 0, "no difference"); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_scaled_rotated_bitmap(tex1, 4, 4, x + 320, y, 8, 8, a, 0); + + y += 120; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(font, color, x, y, 0, "premultiplied alpha"); + al_draw_textf(font, color, x, y + th, 0, "mag linear filtering"); + al_draw_textf(font, color3, x + 400, y, 0, "correct color"); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_scaled_rotated_bitmap(tex2, 4, 4, x + 320, y, 8, 8, a, 0); + + al_flip_display(); + } + } + + al_destroy_font(font); + al_destroy_bitmap(tex1); + al_destroy_bitmap(tex2); + + return 0; +} diff --git a/allegro/examples/ex_prim.c b/allegro/examples/ex_prim.c new file mode 100644 index 00000000..f555e8e7 --- /dev/null +++ b/allegro/examples/ex_prim.c @@ -0,0 +1,915 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * A sampler of the primitive addon. + * All primitives are rendered using the additive blender, so overdraw will manifest itself as overly bright pixels. + * + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + +#include +#include +#include +#include +#include +#include + +#include "common.c" + +typedef void (*Screen)(int); +int ScreenW = 800, ScreenH = 600; +#define NUM_SCREENS 12 +#define ROTATE_SPEED 0.0001f +Screen Screens[NUM_SCREENS]; +const char *ScreenName[NUM_SCREENS]; +ALLEGRO_FONT* Font; +ALLEGRO_TRANSFORM Identity; +ALLEGRO_BITMAP* Buffer; +ALLEGRO_BITMAP* Texture; +ALLEGRO_COLOR solid_white; + +int Soft = 0; +int Blend = 1; +float Speed = ROTATE_SPEED; +float Theta; +int Background = 1; +float Thickness = 0; +ALLEGRO_TRANSFORM MainTrans; + +enum MODE { + INIT, + LOGIC, + DRAW, + DEINIT +}; + +typedef struct +{ + ALLEGRO_COLOR color; + short u, v; + short x, y; + int junk[6]; +} CUSTOM_VERTEX; + +static void CustomVertexFormatPrimitives(int mode) +{ + static CUSTOM_VERTEX vtx[4]; + static ALLEGRO_VERTEX_DECL* decl; + if (mode == INIT) { + int ii = 0; + ALLEGRO_VERTEX_ELEMENT elems[] = { + {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_SHORT_2, offsetof(CUSTOM_VERTEX, x)}, + {ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_SHORT_2, offsetof(CUSTOM_VERTEX, u)}, + {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(CUSTOM_VERTEX, color)}, + {0, 0, 0} + }; + decl = al_create_vertex_decl(elems, sizeof(CUSTOM_VERTEX)); + + for (ii = 0; ii < 4; ii++) { + float x, y; + x = 200 * cosf((float)ii / 4.0f * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 4.0f * 2 * ALLEGRO_PI); + + vtx[ii].x = x; vtx[ii].y = y; + vtx[ii].u = 64 * x / 100; vtx[ii].v = 64 * y / 100; + vtx[ii].color = al_map_rgba_f(1, 1, 1, 1); + } + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_prim(vtx, decl, Texture, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN); + + al_use_transform(&Identity); + } +} + +static void TexturePrimitives(int mode) +{ + static ALLEGRO_VERTEX vtx[13]; + static ALLEGRO_VERTEX vtx2[13]; + if (mode == INIT) { + int ii = 0; + ALLEGRO_COLOR color; + for (ii = 0; ii < 13; ii++) { + float x, y; + x = 200 * cosf((float)ii / 13.0f * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 13.0f * 2 * ALLEGRO_PI); + + color = al_map_rgb((ii + 1) % 3 * 64, (ii + 2) % 3 * 64, (ii) % 3 * 64); + + vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; + vtx2[ii].x = 0.1 * x; vtx2[ii].y = 0.1 * y; + vtx[ii].u = 64 * x / 100; vtx[ii].v = 64 * y / 100; + vtx2[ii].u = 64 * x / 100; vtx2[ii].v = 64 * y / 100; + if(ii < 10) + vtx[ii].color = al_map_rgba_f(1, 1, 1, 1); + else + vtx[ii].color = color; + vtx2[ii].color = vtx[ii].color; + } + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_prim(vtx, 0, Texture, 0, 4, ALLEGRO_PRIM_LINE_LIST); + al_draw_prim(vtx, 0, Texture, 4, 9, ALLEGRO_PRIM_LINE_STRIP); + al_draw_prim(vtx, 0, Texture, 9, 13, ALLEGRO_PRIM_LINE_LOOP); + al_draw_prim(vtx2, 0, Texture, 0, 13, ALLEGRO_PRIM_POINT_LIST); + + al_use_transform(&Identity); + } +} + + +static void FilledTexturePrimitives(int mode) +{ + static ALLEGRO_VERTEX vtx[21]; + if (mode == INIT) { + int ii = 0; + for (ii = 0; ii < 21; ii++) { + float x, y; + ALLEGRO_COLOR color; + if (ii % 2 == 0) { + x = 150 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); + y = 150 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); + } else { + x = 200 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); + } + + if (ii == 0) { + x = y = 0; + } + + color = al_map_rgb((7 * ii + 1) % 3 * 64, (2 * ii + 2) % 3 * 64, (ii) % 3 * 64); + + vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; + vtx[ii].u = 64 * x / 100; vtx[ii].v = 64 * y / 100; + if(ii < 10) + vtx[ii].color = al_map_rgba_f(1, 1, 1, 1); + else + vtx[ii].color = color; + } + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_prim(vtx, 0, Texture, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN); + al_draw_prim(vtx, 0, Texture, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST); + al_draw_prim(vtx, 0, Texture, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP); + + al_use_transform(&Identity); + } +} + +static void FilledPrimitives(int mode) +{ + static ALLEGRO_VERTEX vtx[21]; + if (mode == INIT) { + int ii = 0; + for (ii = 0; ii < 21; ii++) { + float x, y; + ALLEGRO_COLOR color; + if (ii % 2 == 0) { + x = 150 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); + y = 150 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); + } else { + x = 200 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); + } + + if (ii == 0) { + x = y = 0; + } + + color = al_map_rgb((7 * ii + 1) % 3 * 64, (2 * ii + 2) % 3 * 64, (ii) % 3 * 64); + + vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; + vtx[ii].color = color; + } + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_prim(vtx, 0, 0, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN); + al_draw_prim(vtx, 0, 0, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST); + al_draw_prim(vtx, 0, 0, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP); + + al_use_transform(&Identity); + } +} + +static void IndexedFilledPrimitives(int mode) +{ + static ALLEGRO_VERTEX vtx[21]; + static int indices1[] = {12, 13, 14, 16, 17, 18}; + static int indices2[] = {6, 7, 8, 9, 10, 11}; + static int indices3[] = {0, 1, 2, 3, 4, 5}; + if (mode == INIT) { + int ii = 0; + for (ii = 0; ii < 21; ii++) { + float x, y; + ALLEGRO_COLOR color; + if (ii % 2 == 0) { + x = 150 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); + y = 150 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); + } else { + x = 200 * cosf((float)ii / 20 * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 20 * 2 * ALLEGRO_PI); + } + + if (ii == 0) { + x = y = 0; + } + + color = al_map_rgb((7 * ii + 1) % 3 * 64, (2 * ii + 2) % 3 * 64, (ii) % 3 * 64); + + vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; + vtx[ii].color = color; + } + } else if (mode == LOGIC) { + int ii; + Theta += Speed; + for (ii = 0; ii < 6; ii++) { + indices1[ii] = ((int)al_get_time() + ii) % 20 + 1; + indices2[ii] = ((int)al_get_time() + ii + 6) % 20 + 1; + if (ii > 0) + indices3[ii] = ((int)al_get_time() + ii + 12) % 20 + 1; + } + + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_indexed_prim(vtx, 0, 0, indices1, 6, ALLEGRO_PRIM_TRIANGLE_LIST); + al_draw_indexed_prim(vtx, 0, 0, indices2, 6, ALLEGRO_PRIM_TRIANGLE_STRIP); + al_draw_indexed_prim(vtx, 0, 0, indices3, 6, ALLEGRO_PRIM_TRIANGLE_FAN); + + al_use_transform(&Identity); + } +} + +static void HighPrimitives(int mode) +{ + if (mode == INIT) { + + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + float points[8] = { + -300, -200, + 700, 200, + -700, 200, + 300, -200 + }; + + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_line(-300, -200, 300, 200, al_map_rgba_f(0, 0.5, 0.5, 1), Thickness); + al_draw_triangle(-150, -250, 0, 250, 150, -250, al_map_rgba_f(0.5, 0, 0.5, 1), Thickness); + al_draw_rectangle(-300, -200, 300, 200, al_map_rgba_f(0.5, 0, 0, 1), Thickness); + al_draw_rounded_rectangle(-200, -125, 200, 125, 50, 100, al_map_rgba_f(0.2, 0.2, 0, 1), Thickness); + + al_draw_ellipse(0, 0, 300, 150, al_map_rgba_f(0, 0.5, 0.5, 1), Thickness); + al_draw_elliptical_arc(-20, 0, 300, 200, -ALLEGRO_PI / 2, -ALLEGRO_PI, al_map_rgba_f(0.25, 0.25, 0.5, 1), Thickness); + al_draw_arc(0, 0, 200, -ALLEGRO_PI / 2, ALLEGRO_PI, al_map_rgba_f(0.5, 0.25, 0, 1), Thickness); + al_draw_spline(points, al_map_rgba_f(0.1, 0.2, 0.5, 1), Thickness); + al_draw_pieslice(0, 25, 150, ALLEGRO_PI * 3 / 4, -ALLEGRO_PI / 2, al_map_rgba_f(0.4, 0.3, 0.1, 1), Thickness); + + al_use_transform(&Identity); + } +} + +static void HighFilledPrimitives(int mode) +{ + if (mode == INIT) { + + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_filled_triangle(-100, -100, -150, 200, 100, 200, al_map_rgb_f(0.5, 0.7, 0.3)); + al_draw_filled_rectangle(20, -50, 200, 50, al_map_rgb_f(0.3, 0.2, 0.6)); + al_draw_filled_ellipse(-250, 0, 100, 150, al_map_rgb_f(0.3, 0.3, 0.3)); + al_draw_filled_rounded_rectangle(50, -250, 350, -75, 50, 70, al_map_rgb_f(0.4, 0.2, 0)); + al_draw_filled_pieslice(200, 125, 50, ALLEGRO_PI / 4, 3 * ALLEGRO_PI / 2, al_map_rgb_f(0.3, 0.3, 0.1)); + + al_use_transform(&Identity); + } +} + +static void TransformationsPrimitives(int mode) +{ + float t = al_get_time(); + if (mode == INIT) { + + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, sinf(t / 5), cosf(t / 5), Theta); + } else if (mode == DRAW) { + float points[8] = { + -300, -200, + 700, 200, + -700, 200, + 300, -200 + }; + + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_line(-300, -200, 300, 200, al_map_rgba_f(0, 0.5, 0.5, 1), Thickness); + al_draw_triangle(-150, -250, 0, 250, 150, -250, al_map_rgba_f(0.5, 0, 0.5, 1), Thickness); + al_draw_rectangle(-300, -200, 300, 200, al_map_rgba_f(0.5, 0, 0, 1), Thickness); + al_draw_rounded_rectangle(-200, -125, 200, 125, 50, 100, al_map_rgba_f(0.2, 0.2, 0, 1), Thickness); + + al_draw_ellipse(0, 0, 300, 150, al_map_rgba_f(0, 0.5, 0.5, 1), Thickness); + al_draw_elliptical_arc(-20, 0, 300, 200, -ALLEGRO_PI / 2, -ALLEGRO_PI, al_map_rgba_f(0.25, 0.25, 0.5, 1), Thickness); + al_draw_arc(0, 0, 200, -ALLEGRO_PI / 2, ALLEGRO_PI, al_map_rgba_f(0.5, 0.25, 0, 1), Thickness); + al_draw_spline(points, al_map_rgba_f(0.1, 0.2, 0.5, 1), Thickness); + al_draw_pieslice(0, 25, 150, ALLEGRO_PI * 3 / 4, -ALLEGRO_PI / 2, al_map_rgba_f(0.4, 0.3, 0.1, 1), Thickness); + + al_use_transform(&Identity); + } +} + +static void LowPrimitives(int mode) +{ + static ALLEGRO_VERTEX vtx[13]; + static ALLEGRO_VERTEX vtx2[13]; + if (mode == INIT) { + int ii = 0; + ALLEGRO_COLOR color; + for (ii = 0; ii < 13; ii++) { + float x, y; + x = 200 * cosf((float)ii / 13.0f * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 13.0f * 2 * ALLEGRO_PI); + + color = al_map_rgb((ii + 1) % 3 * 64, (ii + 2) % 3 * 64, (ii) % 3 * 64); + + vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; + vtx2[ii].x = 0.1 * x; vtx2[ii].y = 0.1 * y; + vtx[ii].color = color; + vtx2[ii].color = color; + } + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_prim(vtx, 0, 0, 0, 4, ALLEGRO_PRIM_LINE_LIST); + al_draw_prim(vtx, 0, 0, 4, 9, ALLEGRO_PRIM_LINE_STRIP); + al_draw_prim(vtx, 0, 0, 9, 13, ALLEGRO_PRIM_LINE_LOOP); + al_draw_prim(vtx2, 0, 0, 0, 13, ALLEGRO_PRIM_POINT_LIST); + + al_use_transform(&Identity); + } +} + +static void IndexedPrimitives(int mode) +{ + static int indices1[] = {0, 1, 3, 4}; + static int indices2[] = {5, 6, 7, 8}; + static int indices3[] = {9, 10, 11, 12}; + static ALLEGRO_VERTEX vtx[13]; + static ALLEGRO_VERTEX vtx2[13]; + if (mode == INIT) { + int ii = 0; + ALLEGRO_COLOR color; + for (ii = 0; ii < 13; ii++) { + float x, y; + x = 200 * cosf((float)ii / 13.0f * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 13.0f * 2 * ALLEGRO_PI); + + color = al_map_rgb((ii + 1) % 3 * 64, (ii + 2) % 3 * 64, (ii) % 3 * 64); + + vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; + vtx2[ii].x = 0.1 * x; vtx2[ii].y = 0.1 * y; + vtx[ii].color = color; + vtx2[ii].color = color; + } + } else if (mode == LOGIC) { + int ii; + Theta += Speed; + for (ii = 0; ii < 4; ii++) { + indices1[ii] = ((int)al_get_time() + ii) % 13; + indices2[ii] = ((int)al_get_time() + ii + 4) % 13; + indices3[ii] = ((int)al_get_time() + ii + 8) % 13; + } + + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + al_draw_indexed_prim(vtx, 0, 0, indices1, 4, ALLEGRO_PRIM_LINE_LIST); + al_draw_indexed_prim(vtx, 0, 0, indices2, 4, ALLEGRO_PRIM_LINE_STRIP); + al_draw_indexed_prim(vtx, 0, 0, indices3, 4, ALLEGRO_PRIM_LINE_LOOP); + al_draw_indexed_prim(vtx2, 0, 0, indices3, 4, ALLEGRO_PRIM_POINT_LIST); + + al_use_transform(&Identity); + } +} + +static void VertexBuffers(int mode) +{ + static ALLEGRO_VERTEX vtx[13]; + static ALLEGRO_VERTEX vtx2[13]; + static ALLEGRO_VERTEX_BUFFER* vbuff; + static ALLEGRO_VERTEX_BUFFER* vbuff2; + static bool no_soft; + static bool no_soft2; + if (mode == INIT) { + int ii = 0; + ALLEGRO_COLOR color; + for (ii = 0; ii < 13; ii++) { + float x, y; + x = 200 * cosf((float)ii / 13.0f * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 13.0f * 2 * ALLEGRO_PI); + + color = al_map_rgb((ii + 1) % 3 * 64, (ii + 2) % 3 * 64, (ii) % 3 * 64); + + vtx[ii].x = x; vtx[ii].y = y; vtx[ii].z = 0; + vtx2[ii].x = 0.1 * x; vtx2[ii].y = 0.1 * y; + vtx[ii].color = color; + vtx2[ii].color = color; + } + vbuff = al_create_vertex_buffer(0, vtx, 13, ALLEGRO_PRIM_BUFFER_READWRITE); + if (!vbuff) { + vbuff = al_create_vertex_buffer(0, vtx, 13, 0); + no_soft = true; + } + else { + no_soft = false; + } + + vbuff2 = al_create_vertex_buffer(0, vtx2, 13, ALLEGRO_PRIM_BUFFER_READWRITE); + if (!vbuff2) { + vbuff2 = al_create_vertex_buffer(0, vtx2, 13, 0); + no_soft2 = true; + } + else { + no_soft2 = false; + } + } else if (mode == LOGIC) { + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + if (vbuff && !(Soft && no_soft)) { + al_draw_vertex_buffer(vbuff, 0, 0, 4, ALLEGRO_PRIM_LINE_LIST); + al_draw_vertex_buffer(vbuff, 0, 4, 9, ALLEGRO_PRIM_LINE_STRIP); + al_draw_vertex_buffer(vbuff, 0, 9, 13, ALLEGRO_PRIM_LINE_LOOP); + } + else { + al_draw_text(Font, al_map_rgb_f(1, 1, 1), 0, -40, 0, "Vertex buffers not supported"); + } + + if (vbuff2 && !(Soft && no_soft2)) { + al_draw_vertex_buffer(vbuff2, 0, 0, 13, ALLEGRO_PRIM_POINT_LIST); + } + else { + al_draw_text(Font, al_map_rgb_f(1, 1, 1), 0, 40, 0, "Vertex buffers not supported"); + } + + al_use_transform(&Identity); + } else if (mode == DEINIT) { + al_destroy_vertex_buffer(vbuff); + al_destroy_vertex_buffer(vbuff2); + } +} + +static void IndexedBuffers(int mode) +{ + static ALLEGRO_VERTEX_BUFFER* vbuff; + static ALLEGRO_INDEX_BUFFER* ibuff; + static bool soft = true; + if (mode == INIT) { + int ii; + ALLEGRO_COLOR color; + ALLEGRO_VERTEX* vtx; + int flags = ALLEGRO_PRIM_BUFFER_READWRITE; + + vbuff = al_create_vertex_buffer(NULL, NULL, 13, ALLEGRO_PRIM_BUFFER_READWRITE); + if (vbuff == NULL) { + vbuff = al_create_vertex_buffer(NULL, NULL, 13, 0); + soft = false; + flags = 0; + } + + ibuff = al_create_index_buffer(sizeof(short), NULL, 8, flags); + + if (vbuff) { + vtx = al_lock_vertex_buffer(vbuff, 0, 13, ALLEGRO_LOCK_WRITEONLY); + + for (ii = 0; ii < 13; ii++) { + float x, y; + x = 200 * cosf((float)ii / 13.0f * 2 * ALLEGRO_PI); + y = 200 * sinf((float)ii / 13.0f * 2 * ALLEGRO_PI); + + color = al_map_rgb((ii + 1) % 3 * 64, (ii + 2) % 3 * 64, (ii) % 3 * 64); + + vtx[ii].x = x; + vtx[ii].y = y; + vtx[ii].z = 0; + vtx[ii].color = color; + } + + al_unlock_vertex_buffer(vbuff); + } + } else if (mode == LOGIC) { + if (ibuff) { + int ii; + int t = (int)al_get_time(); + short* indices = al_lock_index_buffer(ibuff, 0, 8, ALLEGRO_LOCK_WRITEONLY); + + for (ii = 0; ii < 8; ii++) { + indices[ii] = (t + ii) % 13; + } + al_unlock_index_buffer(ibuff); + } + + Theta += Speed; + al_build_transform(&MainTrans, ScreenW / 2, ScreenH / 2, 1, 1, Theta); + } else if (mode == DRAW) { + if (Blend) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + else + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + + al_use_transform(&MainTrans); + + if(!(Soft && !soft) && vbuff && ibuff) { + al_draw_indexed_buffer(vbuff, NULL, ibuff, 0, 4, ALLEGRO_PRIM_LINE_LIST); + al_draw_indexed_buffer(vbuff, NULL, ibuff, 4, 8, ALLEGRO_PRIM_LINE_STRIP); + } + else { + al_draw_text(Font, al_map_rgb_f(1, 1, 1), 0, 0, 0, "Indexed buffers not supported"); + } + + al_use_transform(&Identity); + } else if (mode == DEINIT) { + al_destroy_vertex_buffer(vbuff); + al_destroy_index_buffer(ibuff); + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP* bkg; + ALLEGRO_COLOR black; + ALLEGRO_EVENT_QUEUE *queue; + bool use_shader = false; + + if (argc > 1) { + if (strcmp(argv[1], "--shader") == 0) { + use_shader = true; + } + else { + abort_example("Invalid command line option: %s", argv[1]); + } + } + + // Initialize Allegro 5 and addons + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_image_addon(); + al_init_font_addon(); + al_init_primitives_addon(); + init_platform_specific(); + + if (use_shader) { + al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE); + } + + // Create a window to display things on: 640x480 pixels + display = al_create_display(ScreenW, ScreenH); + if (!display) { + abort_example("Error creating display.\n"); + } + + // Install the keyboard handler + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + if (!al_install_mouse()) { + abort_example("Error installing mouse.\n"); + } + + // Load a font + Font = al_load_font("data/fixed_font.tga", 0, 0); + if (!Font) { + abort_example("Error loading \"data/fixed_font.tga\".\n"); + } + + solid_white = al_map_rgba_f(1, 1, 1, 1); + + bkg = al_load_bitmap("data/bkg.png"); + + Texture = al_load_bitmap("data/texture.tga"); + + // Make and set some color to draw with + black = al_map_rgba_f(0.0, 0.0, 0.0, 1.0); + + // Start the event queue to handle keyboard input and our timer + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_mouse_event_source()); + + al_set_window_title(display, "Primitives Example"); + + { + int refresh_rate = 60; + int frames_done = 0; + double time_diff = al_get_time(); + double fixed_timestep = 1.0f / refresh_rate; + double real_time = al_get_time(); + double game_time = al_get_time(); + int ii; + int cur_screen = 0; + bool done = false; + int clip = 0; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *timer_queue; + int old; + + timer = al_create_timer(ALLEGRO_BPS_TO_SECS(refresh_rate)); + al_start_timer(timer); + timer_queue = al_create_event_queue(); + al_register_event_source(timer_queue, al_get_timer_event_source(timer)); + + old = al_get_new_bitmap_flags(); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + Buffer = al_create_bitmap(ScreenW, ScreenH); + al_set_new_bitmap_flags(old); + + al_identity_transform(&Identity); + + Screens[0] = LowPrimitives; + Screens[1] = IndexedPrimitives; + Screens[2] = HighPrimitives; + Screens[3] = TransformationsPrimitives; + Screens[4] = FilledPrimitives; + Screens[5] = IndexedFilledPrimitives; + Screens[6] = HighFilledPrimitives; + Screens[7] = TexturePrimitives; + Screens[8] = FilledTexturePrimitives; + Screens[9] = CustomVertexFormatPrimitives; + Screens[10] = VertexBuffers; + Screens[11] = IndexedBuffers; + + ScreenName[0] = "Low Level Primitives"; + ScreenName[1] = "Indexed Primitives"; + ScreenName[2] = "High Level Primitives"; + ScreenName[3] = "Transformations"; + ScreenName[4] = "Low Level Filled Primitives"; + ScreenName[5] = "Indexed Filled Primitives"; + ScreenName[6] = "High Level Filled Primitives"; + ScreenName[7] = "Textured Primitives"; + ScreenName[8] = "Filled Textured Primitives"; + ScreenName[9] = "Custom Vertex Format"; + ScreenName[10] = "Vertex Buffers"; + ScreenName[11] = "Indexed Buffers"; + + for (ii = 0; ii < NUM_SCREENS; ii++) { + Screens[ii](INIT); + Screens[ii](LOGIC); + } + + while (!done) { + double frame_duration = al_get_time() - real_time; + al_rest(fixed_timestep - frame_duration); //rest at least fixed_dt + frame_duration = al_get_time() - real_time; + real_time = al_get_time(); + + if (real_time - game_time > frame_duration) { //eliminate excess overflow + game_time += fixed_timestep * floor((real_time - game_time) / fixed_timestep); + } + + while (real_time - game_time >= 0) { + ALLEGRO_EVENT key_event; + double start_time = al_get_time(); + game_time += fixed_timestep; + + Screens[cur_screen](LOGIC); + + while (al_get_next_event(queue, &key_event)) { + switch (key_event.type) { + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: { + cur_screen++; + if (cur_screen >= NUM_SCREENS) { + cur_screen = 0; + } + break; + } + + case ALLEGRO_EVENT_DISPLAY_CLOSE: { + done = true; + break; + } + case ALLEGRO_EVENT_KEY_CHAR: { + switch (key_event.keyboard.keycode) { + case ALLEGRO_KEY_ESCAPE: { + done = true; + break; + } + case ALLEGRO_KEY_S: { + Soft = !Soft; + time_diff = al_get_time(); + frames_done = 0; + break; + } + case ALLEGRO_KEY_C: { + clip = !clip; + time_diff = al_get_time(); + frames_done = 0; + break; + } + case ALLEGRO_KEY_L: { + Blend = !Blend; + time_diff = al_get_time(); + frames_done = 0; + break; + } + case ALLEGRO_KEY_B: { + Background = !Background; + time_diff = al_get_time(); + frames_done = 0; + break; + } + case ALLEGRO_KEY_LEFT: { + Speed -= ROTATE_SPEED; + break; + } + case ALLEGRO_KEY_RIGHT: { + Speed += ROTATE_SPEED; + break; + } + case ALLEGRO_KEY_PGUP: { + Thickness += 0.5f; + if (Thickness < 1.0f) + Thickness = 1.0f; + break; + } + case ALLEGRO_KEY_PGDN: { + Thickness -= 0.5f; + if (Thickness < 1.0f) + Thickness = 0.0f; + break; + } + case ALLEGRO_KEY_UP: { + cur_screen++; + if (cur_screen >= NUM_SCREENS) { + cur_screen = 0; + } + break; + } + case ALLEGRO_KEY_SPACE: { + Speed = 0; + break; + } + case ALLEGRO_KEY_DOWN: { + cur_screen--; + if (cur_screen < 0) { + cur_screen = NUM_SCREENS - 1; + } + break; + } + } + } + } + } + + if (al_get_time() - start_time >= fixed_timestep) { //break if we start taking too long + break; + } + } + + al_clear_to_color(black); + + if (Soft == 1) { + al_set_target_bitmap(Buffer); + al_clear_to_color(black); + } + + if (Background && bkg) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_scaled_bitmap(bkg, 0, 0, al_get_bitmap_width(bkg), al_get_bitmap_height(bkg), 0, 0, ScreenW, ScreenH, 0); + } + + if (clip == 1) { + al_set_clipping_rectangle(ScreenW / 2, ScreenH / 2, ScreenW / 2, ScreenH / 2); + } + + Screens[cur_screen](DRAW); + + al_set_clipping_rectangle(0, 0, ScreenW, ScreenH); + + if (Soft == 1) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_set_target_backbuffer(display); + al_draw_bitmap(Buffer, 0, 0, 0); + } + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(Font, solid_white, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "%s", ScreenName[cur_screen]); + al_draw_textf(Font, solid_white, 0, 0, 0, "FPS: %f", (float)frames_done / (al_get_time() - time_diff)); + al_draw_textf(Font, solid_white, 0, 20, 0, "Change Screen (Up/Down). Esc to Quit."); + al_draw_textf(Font, solid_white, 0, 40, 0, "Rotation (Left/Right/Space): %f", Speed); + al_draw_textf(Font, solid_white, 0, 60, 0, "Thickness (PgUp/PgDown): %f", Thickness); + al_draw_textf(Font, solid_white, 0, 80, 0, "Software (S): %d", Soft); + al_draw_textf(Font, solid_white, 0, 100, 0, "Blending (L): %d", Blend); + al_draw_textf(Font, solid_white, 0, 120, 0, "Background (B): %d", Background); + al_draw_textf(Font, solid_white, 0, 140, 0, "Clip (C): %d", clip); + + al_flip_display(); + frames_done++; + } + + for (ii = 0; ii < NUM_SCREENS; ii++) + Screens[ii](DEINIT); + + } + + return 0; +} diff --git a/allegro/examples/ex_prim_shader.c b/allegro/examples/ex_prim_shader.c new file mode 100644 index 00000000..9ec3be14 --- /dev/null +++ b/allegro/examples/ex_prim_shader.c @@ -0,0 +1,202 @@ +#include +#include +#include + +#define ALLEGRO_UNSTABLE +#include "allegro5/allegro.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" + +typedef struct +{ + float x, y; + float nx, ny, nz; +} CUSTOM_VERTEX; + +#define RING_SIZE 25 +#define SPHERE_RADIUS 150.1 +#define SCREEN_WIDTH 640 +#define SCREEN_HEIGHT 480 +#define NUM_RINGS (SCREEN_WIDTH / RING_SIZE + 1) +#define NUM_SEGMENTS 64 +#define NUM_VERTICES (NUM_RINGS * NUM_SEGMENTS * 6) +#define FIRST_OUTSIDE_RING ((int)(SPHERE_RADIUS / RING_SIZE)) + +static void setup_vertex(CUSTOM_VERTEX* vtx, int ring, int segment, bool inside) +{ + float len; + float x, y, z; + x = ring * RING_SIZE * cosf(2 * ALLEGRO_PI * segment / NUM_SEGMENTS); + y = ring * RING_SIZE * sinf(2 * ALLEGRO_PI * segment / NUM_SEGMENTS); + vtx->x = x + SCREEN_WIDTH / 2; + vtx->y = y + SCREEN_HEIGHT / 2; + + if (inside) { + /* This comes from the definition of the normal vector as the + * gradient of the 3D surface. */ + z = sqrtf(SPHERE_RADIUS * SPHERE_RADIUS - x * x - y * y); + vtx->nx = x / z; + vtx->ny = y / z; + } + else { + vtx->nx = 0; + vtx->ny = 0; + } + vtx->nz = 1.0; + + len = sqrtf(vtx->nx * vtx->nx + vtx->ny * vtx->ny + vtx->nz * vtx->nz); + vtx->nx /= len; + vtx->ny /= len; + vtx->nz /= len; +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + bool redraw = true; + ALLEGRO_SHADER *shader; + ALLEGRO_VERTEX_DECL *vertex_decl; + ALLEGRO_VERTEX_ELEMENT vertex_elems[] = { + {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(CUSTOM_VERTEX, x)}, + {ALLEGRO_PRIM_USER_ATTR, ALLEGRO_PRIM_FLOAT_3, offsetof(CUSTOM_VERTEX, nx)}, + {0, 0, 0} + }; + CUSTOM_VERTEX vertices[NUM_VERTICES]; + bool quit = false; + const char* vertex_shader_file; + const char* pixel_shader_file; + int vertex_idx = 0; + int ring, segment; + float diffuse_color[4] = {0.1, 0.1, 0.7, 1.0}; + float light_position[3] = {0, 0, 100}; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_mouse(); + al_install_keyboard(); + al_install_touch_input(); + if (!al_init_primitives_addon()) { + abort_example("Could not init primitives addon.\n"); + } + init_platform_specific(); + al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE); + display = al_create_display(SCREEN_WIDTH, SCREEN_HEIGHT); + if (!display) { + abort_example("Error creating display.\n"); + } + + vertex_decl = al_create_vertex_decl(vertex_elems, sizeof(CUSTOM_VERTEX)); + if (!vertex_decl) { + abort_example("Error creating vertex declaration.\n"); + } + + /* Computes a "spherical" bump ring. The z coordinate is not actually set + * appropriately as this is a 2D example, but the normal vectors are computed + * correctly for the light shading effect. */ + for (ring = 0; ring < NUM_RINGS; ring++) { + for (segment = 0; segment < NUM_SEGMENTS; segment++) { + bool inside = ring < FIRST_OUTSIDE_RING; + setup_vertex(&vertices[vertex_idx + 0], ring + 0, segment + 0, inside); + setup_vertex(&vertices[vertex_idx + 1], ring + 0, segment + 1, inside); + setup_vertex(&vertices[vertex_idx + 2], ring + 1, segment + 0, inside); + setup_vertex(&vertices[vertex_idx + 3], ring + 1, segment + 0, inside); + setup_vertex(&vertices[vertex_idx + 4], ring + 0, segment + 1, inside); + setup_vertex(&vertices[vertex_idx + 5], ring + 1, segment + 1, inside); + vertex_idx += 6; + } + } + + shader = al_create_shader(ALLEGRO_SHADER_AUTO); + + if (!shader) { + abort_example("Failed to create shader."); + } + + if (al_get_shader_platform(shader) == ALLEGRO_SHADER_GLSL) { + vertex_shader_file = "data/ex_prim_shader_vertex.glsl"; + pixel_shader_file = "data/ex_prim_shader_pixel.glsl"; + } + else { + vertex_shader_file = "data/ex_prim_shader_vertex.hlsl"; + pixel_shader_file = "data/ex_prim_shader_pixel.hlsl"; + } + + if (!al_attach_shader_source_file(shader, ALLEGRO_VERTEX_SHADER, vertex_shader_file)) { + abort_example("al_attach_shader_source_file for vertex shader failed: %s\n", + al_get_shader_log(shader)); + } + if (!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, pixel_shader_file)) { + abort_example("al_attach_shader_source_file for pixel shader failed: %s\n", + al_get_shader_log(shader)); + } + + if (!al_build_shader(shader)) { + abort_example("al_build_shader for link failed: %s\n", al_get_shader_log(shader)); + } + + al_use_shader(shader); + al_set_shader_float_vector("diffuse_color", 4, diffuse_color, 1); + /* alpha controls shininess, and 25 is very shiny */ + al_set_shader_float("alpha", 25); + + timer = al_create_timer(1.0 / 60); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + if (al_is_touch_input_installed()) { + al_register_event_source(queue, + al_get_touch_input_mouse_emulation_event_source()); + } + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + while (!quit) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + quit = true; + break; + case ALLEGRO_EVENT_MOUSE_AXES: + light_position[0] = event.mouse.x; + light_position[1] = event.mouse.y; + break; + case ALLEGRO_EVENT_KEY_CHAR: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + quit = true; + break; + case ALLEGRO_EVENT_TIMER: + redraw = true; + break; + } + + if (redraw && al_is_event_queue_empty(queue)) { + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + + al_set_shader_float_vector("light_position", 3, light_position, 1); + al_draw_prim(vertices, vertex_decl, NULL, 0, NUM_VERTICES, ALLEGRO_PRIM_TRIANGLE_LIST); + + al_flip_display(); + redraw = false; + } + } + + al_use_shader(NULL); + al_destroy_shader(shader); + al_destroy_vertex_decl(vertex_decl); + + return 0; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_projection.c b/allegro/examples/ex_projection.c new file mode 100644 index 00000000..bdf4a92b --- /dev/null +++ b/allegro/examples/ex_projection.c @@ -0,0 +1,276 @@ +#include +#include +#include + +#include "common.c" + +/* How far has the text been scrolled. */ +static float scroll_y; + +/* Total length of the scrolling text in pixels. */ +static int text_length; + +/* The Alex logo. */ +static ALLEGRO_BITMAP *logo; + +/* The star particle. */ +static ALLEGRO_BITMAP *particle; + +/* The font we use for everything. */ +static ALLEGRO_FONT *font; + + +/* Local pseudo-random number generator. */ +static int rnd(int *seed) +{ + *seed = (*seed + 1) * 1103515245 + 12345; + return ((*seed >> 16) & 0xffff); +} + + +/* Load a bitmap or font and exit with a message if it's missing. */ +static void *load(char const *path, char const *type, ...) +{ + void *data = NULL; + va_list args; + va_start(args, type); + if (!strcmp(type, "bitmap")) { + data = al_load_bitmap(path); + } + else if (!strcmp(type, "font")) { + int size = va_arg(args, int); + int flags = va_arg(args, int); + data = al_load_font(path, size, flags); + } + va_end(args); + if (!data) { + abort_example("Could not load %s %s", type, path); + } + return data; +} + + +/* Print fading text. */ +static int print(ALLEGRO_FONT *font, float x, float y, float r, float g, + float b, float fade, char const *text) +{ + float c = 1 + (y - fade) / 360 / 2.0; + if (c > 1) + c = 1; + if (c < 0) + c = 0; + al_draw_text(font, al_map_rgba_f(c * r, c * g, c * b, c), x, y, + ALLEGRO_ALIGN_CENTER, text); + return y + al_get_font_line_height(font); +} + + +/* Set up a perspective transform. We make the screen span + * 180 vertical units with square pixel aspect and 90° vertical + * FoV. + */ +static void setup_3d_projection(ALLEGRO_TRANSFORM *projection) +{ + ALLEGRO_DISPLAY *display = al_get_current_display(); + int dw = al_get_display_width(display); + int dh = al_get_display_height(display); + al_perspective_transform(projection, -180 * dw / dh, -180, 180, + 180 * dw / dh, 180, 3000); + al_use_projection_transform(projection); +} + + +/* 3D transformations make it very easy to draw a starfield. */ +static void draw_stars(void) +{ + ALLEGRO_TRANSFORM projection; + int seed; + int i; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + + seed = 0; + for (i = 0; i < 100; i++) { + const int x = rnd(&seed); + const int y = rnd(&seed); + const int z = rnd(&seed); + + al_identity_transform(&projection); + al_translate_transform_3d(&projection, 0, 0, + -2000 + ((int)scroll_y * 1000 / text_length + z) % 2000 - 180); + setup_3d_projection(&projection); + al_draw_bitmap(particle, x % 4000 - 2000, y % 2000 - 1000, 0); + } +} + + +/* The main part of this example. */ +static void draw_scrolling_text(void) +{ + ALLEGRO_TRANSFORM projection; + int bw = al_get_bitmap_width(logo); + int bh = al_get_bitmap_height(logo); + float x, y, c; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + al_identity_transform(&projection); + + /* First, we scroll the text in in the y direction (inside the x/z + * plane) and move it away from the camera (in the z direction). + * We move it as far as half the display height to get a vertical + * FOV of 90 degrees. + */ + al_translate_transform_3d(&projection, 0, -scroll_y, -180); + + /* Then we tilt it backwards 30 degrees. */ + al_rotate_transform_3d(&projection, 1, 0, 0, + 30 * ALLEGRO_PI / 180.0); + + /* And finally move it down so the 0 position ends up + * at the bottom of the screen. + */ + al_translate_transform_3d(&projection, 0, 180, 0); + + setup_3d_projection(&projection); + + x = 0; + y = 0; + c = 1 + (y - scroll_y) / 360 / 2.0; + if (c < 0) + c = 0; + al_draw_tinted_bitmap(logo, al_map_rgba_f(c, c, c, c), + x - bw / 2, y, 0); + y += bh; + +#define T(str) (y = print(font, x, y, 1, 0.9, 0.3, scroll_y, (str))); + + T("Allegro 5") + T("") + T("It is a period of game programming.") + T("Game coders have won their first") + T("victory against the evil") + T("General Protection Fault.") + T("") + T("During the battle, hackers managed") + T("to steal the secret source to the") + T("General's ultimate weapon,") + T("the ACCESS VIOLATION, a kernel") + T("exception with enough power to") + T("destroy an entire program.") + T("") + T("Pursued by sinister bugs the") + T("Allegro developers race home") + T("aboard their library to save") + T("all game programmers and restore") + T("freedom to the open source world.") + +#undef T +} + +static void draw_intro_text(void) +{ + ALLEGRO_TRANSFORM projection; + int fade; + int fh = al_get_font_line_height(font); + + if (scroll_y < 50) + fade = (50 - scroll_y) * 12; + else + fade = (scroll_y - 50) * 4; + + al_identity_transform(&projection); + al_translate_transform_3d(&projection, 0, -scroll_y / 3, -181); + setup_3d_projection(&projection); + + print(font, 0, 0, 0, 0.9, 1, fade, "A long time ago, in a galaxy"); + print(font, 0, 0 + fh, 0, 0.9, 1, fade, "not too far away..."); +} + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + int redraw = 0; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_image_addon(); + al_init_font_addon(); + al_init_ttf_addon(); + init_platform_specific(); + al_install_keyboard(); + + al_set_new_display_flags(ALLEGRO_RESIZABLE); + display = al_create_display(640, 360); + if (!display) { + abort_example("Error creating display\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | + ALLEGRO_MIPMAP); + + font = load("data/DejaVuSans.ttf", "font", 40, 0); + logo = load("data/alexlogo.png", "bitmap"); + particle = load("data/haiku/air_effect.png", "bitmap"); + + al_convert_mask_to_alpha(logo, al_map_rgb(255, 0, 255)); + + text_length = al_get_bitmap_height(logo) + + 19 * al_get_font_line_height(font); + + timer = al_create_timer(1.0 / 60); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + while (true) { + ALLEGRO_EVENT event; + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + else if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { + al_acknowledge_resize(display); + } + else if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + else if (event.type == ALLEGRO_EVENT_TIMER) { + scroll_y++; + if (scroll_y > text_length * 2) + scroll_y -= text_length * 2; + + redraw = 1; + } + + if (redraw && al_is_event_queue_empty(queue)) { + ALLEGRO_COLOR black = al_map_rgba_f(0, 0, 0, 1); + + al_clear_to_color(black); + + draw_stars(); + + draw_scrolling_text(); + + draw_intro_text(); + + al_flip_display(); + redraw = 0; + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_projection2.c b/allegro/examples/ex_projection2.c new file mode 100644 index 00000000..49a16c9a --- /dev/null +++ b/allegro/examples/ex_projection2.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include + +#include + +#include "common.c" + +static void draw_pyramid(ALLEGRO_BITMAP* texture, float x, float y, float z, float theta) +{ + ALLEGRO_COLOR c = al_map_rgb_f(1, 1, 1); + ALLEGRO_TRANSFORM t; + ALLEGRO_VERTEX vtx[5] = { + /* x y z u v c */ + { 0, 1, 0, 0, 64, c}, + {-1, -1, -1, 0, 0, c}, + { 1, -1, -1, 64, 64, c}, + { 1, -1, 1, 64, 0, c}, + {-1, -1, 1, 64, 64, c}, + }; + int indices[12] = { + 0, 1, 2, + 0, 2, 3, + 0, 3, 4, + 0, 4, 1 + }; + + al_identity_transform(&t); + al_rotate_transform_3d(&t, 0, 1, 0, theta); + al_translate_transform_3d(&t, x, y, z); + al_use_transform(&t); + al_draw_indexed_prim(vtx, NULL, texture, indices, 12, ALLEGRO_PRIM_TRIANGLE_LIST); +} + +static void set_perspective_transform(ALLEGRO_BITMAP* bmp) +{ + ALLEGRO_TRANSFORM p; + float aspect_ratio = (float)al_get_bitmap_height(bmp) / al_get_bitmap_width(bmp); + al_set_target_bitmap(bmp); + al_identity_transform(&p); + al_perspective_transform(&p, -1, aspect_ratio, 1, 1, -aspect_ratio, 1000); + al_use_projection_transform(&p); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_BITMAP *texture; + ALLEGRO_BITMAP *display_sub_persp; + ALLEGRO_BITMAP *display_sub_ortho; + ALLEGRO_BITMAP *buffer; + ALLEGRO_FONT *font; + bool redraw = false; + bool quit = false; + bool fullscreen = false; + bool background = false; + int display_flags = ALLEGRO_RESIZABLE; + float theta = 0; + + if (argc > 1) { + if(strcmp(argv[1], "--use-shaders") == 0) { + display_flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; + } + else { + abort_example("Unknown command line argument: %s\n", argv[1]); + } + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_image_addon(); + al_init_primitives_addon(); + al_init_font_addon(); + init_platform_specific(); + al_install_keyboard(); + + al_set_new_display_flags(display_flags); + al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); + /* Load everything as a POT bitmap to make sure the projection stuff works + * with mismatched backing texture and bitmap sizes. */ + al_set_new_display_option(ALLEGRO_SUPPORT_NPOT_BITMAP, 0, ALLEGRO_REQUIRE); + display = al_create_display(800, 600); + if (!display) { + abort_example("Error creating display\n"); + } + al_set_window_constraints(display, 256, 512, 0, 0); + al_apply_window_constraints(display, true); + set_perspective_transform(al_get_backbuffer(display)); + + /* This bitmap is a sub-bitmap of the display, and has a perspective transformation. */ + display_sub_persp = al_create_sub_bitmap(al_get_backbuffer(display), 0, 0, 256, 256); + set_perspective_transform(display_sub_persp); + + /* This bitmap is a sub-bitmap of the display, and has a orthographic transformation. */ + display_sub_ortho = al_create_sub_bitmap(al_get_backbuffer(display), 0, 0, 256, 512); + + /* This bitmap has a perspective transformation, purposefully non-POT */ + buffer = al_create_bitmap(200, 200); + set_perspective_transform(buffer); + + timer = al_create_timer(1.0 / 60); + font = al_create_builtin_font(); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | + ALLEGRO_MIPMAP); + + texture = al_load_bitmap("data/bkg.png"); + if (!texture) { + abort_example("Could not load data/bkg.png"); + } + + al_start_timer(timer); + while (!quit) { + ALLEGRO_EVENT event; + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + quit = true; + break; + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(display); + set_perspective_transform(al_get_backbuffer(display)); + break; + case ALLEGRO_EVENT_KEY_DOWN: + switch (event.keyboard.keycode) { + case ALLEGRO_KEY_ESCAPE: + quit = true; + break; + case ALLEGRO_KEY_SPACE: + fullscreen = !fullscreen; + al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, fullscreen); + set_perspective_transform(al_get_backbuffer(display)); + break; + } + break; + case ALLEGRO_EVENT_TIMER: + redraw = true; + theta = fmod(theta + 0.05, 2 * ALLEGRO_PI); + break; + case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: + background = true; + al_acknowledge_drawing_halt(display); + al_stop_timer(timer); + break; + case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: + background = false; + al_acknowledge_drawing_resume(display); + al_start_timer(timer); + break; + } + + if (!background && redraw && al_is_event_queue_empty(queue)) { + al_set_target_backbuffer(display); + al_set_render_state(ALLEGRO_DEPTH_TEST, 1); + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_clear_depth_buffer(1000); + draw_pyramid(texture, 0, 0, -4, theta); + + al_set_target_bitmap(buffer); + al_set_render_state(ALLEGRO_DEPTH_TEST, 1); + al_clear_to_color(al_map_rgb_f(0, 0.1, 0.1)); + al_clear_depth_buffer(1000); + draw_pyramid(texture, 0, 0, -4, theta); + + al_set_target_bitmap(display_sub_persp); + al_set_render_state(ALLEGRO_DEPTH_TEST, 1); + al_clear_to_color(al_map_rgb_f(0, 0, 0.25)); + al_clear_depth_buffer(1000); + draw_pyramid(texture, 0, 0, -4, theta); + + al_set_target_bitmap(display_sub_ortho); + al_set_render_state(ALLEGRO_DEPTH_TEST, 0); + al_draw_text(font, al_map_rgb_f(1, 1, 1), 128, 16, ALLEGRO_ALIGN_CENTER, + "Press Space to toggle fullscreen"); + al_draw_bitmap(buffer, 0, 256, 0); + + al_flip_display(); + redraw = false; + } + } + return 0; +} diff --git a/allegro/examples/ex_record.c b/allegro/examples/ex_record.c new file mode 100644 index 00000000..73962789 --- /dev/null +++ b/allegro/examples/ex_record.c @@ -0,0 +1,324 @@ +/* ex_record + * + * Press spacebar to begin and stop recording. Press 'p' to play back the + * previous recording. Up to five minutes of audio will be recorded. + * + * The raw sample data is saved to a temporary file and played back via + * an audio stream. Thus, minimal memory is used regardless of the length of + * recording. + * + * When recording, it's important to keep the distinction between bytes and + * samples. A sample is only exactly one byte long if it is 8-bit and mono. + * Otherwise it is multiple bytes. The recording functions always work with + * sample counts. However, when using things like memcpy() or fwrite(), you + * will be working with bytes. + */ + +#define ALLEGRO_UNSTABLE +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/allegro_acodec.h" + +#include "common.c" + +/* Comment out the following line to use 16-bit audio */ +#define WANT_8_BIT_DEPTH + +/* The following constants are needed so that the rest of the code can + * work independent from the audio depth. Both 8-bit and 16-bit should be + * supported by all devices, so in your own programs you probably can get by + * with just supporting one or the other. + */ + +#ifdef WANT_8_BIT_DEPTH + +const ALLEGRO_AUDIO_DEPTH audio_depth = ALLEGRO_AUDIO_DEPTH_UINT8; +typedef uint8_t* audio_buffer_t; +const uint8_t sample_center = 128; +const int8_t min_sample_val = 0x80; +const int8_t max_sample_val = 0x7f; +const int sample_range = 0xff; +const int sample_size = 1; + +#else + +const ALLEGRO_AUDIO_DEPTH audio_depth = ALLEGRO_AUDIO_DEPTH_INT16; +typedef int16_t* audio_buffer_t; +const int16_t sample_center = 0; +const int16_t min_sample_val = 0x8000; +const int16_t max_sample_val = 0x7fff; +const int sample_range = 0xffff; +const int sample_size = 2; + +#endif + +/* How many samples do we want to process at one time? + Let's pick a multiple of the width of the screen so that the + visualization graph is easy to draw. */ +const unsigned int samples_per_fragment = 320 * 4; + +/* Frequency is the quality of audio. (Samples per second.) Higher + quality consumes more memory. For speech, numbers as low as 8000 + can be good enough. 44100 is often used for high quality recording. */ +const unsigned int frequency = 22050; +const unsigned int max_seconds_to_record = 60 * 5; + + +/* The playback buffer specs don't need to match the recording sizes. + * The values here are slightly large to help make playback more smooth. + */ +const unsigned int playback_fragment_count = 4; +const unsigned int playback_samples_per_fragment = 4096; + +int main(int argc, char **argv) +{ + ALLEGRO_AUDIO_RECORDER *r; + ALLEGRO_AUDIO_STREAM *s; + + ALLEGRO_EVENT_QUEUE *q; + ALLEGRO_DISPLAY *d; + ALLEGRO_FILE *fp = NULL; + ALLEGRO_PATH *tmp_path = NULL; + + int prev = 0; + bool is_recording = false; + + int n = 0; /* number of samples written to disk */ + + (void) argc; + (void) argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + if (!al_init_primitives_addon()) { + abort_example("Unable to initialize primitives addon"); + } + + if (!al_install_keyboard()) { + abort_example("Unable to install keyboard"); + } + + if (!al_install_audio()) { + abort_example("Unable to initialize audio addon"); + } + + if (!al_init_acodec_addon()) { + abort_example("Unable to initialize acodec addon"); + } + + /* Note: increasing the number of channels will break this demo. Other + * settings can be changed by modifying the constants at the top of the + * file. + */ + r = al_create_audio_recorder(1000, samples_per_fragment, frequency, + audio_depth, ALLEGRO_CHANNEL_CONF_1); + if (!r) { + abort_example("Unable to create audio recorder"); + } + + s = al_create_audio_stream(playback_fragment_count, + playback_samples_per_fragment, frequency, audio_depth, + ALLEGRO_CHANNEL_CONF_1); + if (!s) { + abort_example("Unable to create audio stream"); + } + + al_reserve_samples(0); + al_set_audio_stream_playing(s, false); + al_attach_audio_stream_to_mixer(s, al_get_default_mixer()); + + q = al_create_event_queue(); + + /* Note: the following two options are referring to pixel samples, and have + * nothing to do with audio samples. */ + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); + al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST); + + d = al_create_display(320, 256); + if (!d) { + abort_example("Error creating display\n"); + } + + al_set_window_title(d, "SPACE to record. P to playback."); + + al_register_event_source(q, al_get_audio_recorder_event_source(r)); + al_register_event_source(q, al_get_audio_stream_event_source(s)); + al_register_event_source(q, al_get_display_event_source(d)); + al_register_event_source(q, al_get_keyboard_event_source()); + + al_start_audio_recorder(r); + + while (true) { + ALLEGRO_EVENT e; + + al_wait_for_event(q, &e); + + if (e.type == ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT) { + /* We received an incoming fragment from the microphone. In this + * example, the recorder is constantly recording even when we aren't + * saving to disk. The display is updated every time a new fragment + * comes in, because it makes things more simple. If the fragments + * are coming in faster than we can update the screen, then it will be + * a problem. + */ + ALLEGRO_AUDIO_RECORDER_EVENT *re = al_get_audio_recorder_event(&e); + audio_buffer_t input = (audio_buffer_t) re->buffer; + int sample_count = re->samples; + const int R = sample_count / 320; + int i, gain = 0; + + /* Calculate the volume, and display it regardless if we are actively + * recording to disk. */ + for (i = 0; i < sample_count; ++i) { + if (gain < abs(input[i] - sample_center)) + gain = abs(input[i] - sample_center); + } + + al_clear_to_color(al_map_rgb(0,0,0)); + + if (is_recording) { + /* Save raw bytes to disk. Assumes everything is written + * succesfully. */ + if (fp && n < frequency / (float) samples_per_fragment * + max_seconds_to_record) { + al_fwrite(fp, input, sample_count * sample_size); + ++n; + } + + /* Draw a pathetic visualization. It draws exactly one fragment + * per frame. This means the visualization is dependent on the + * various parameters. A more thorough implementation would use this + * event to copy the new data into a circular buffer that holds a + * few seconds of audio. The graphics routine could then always + * draw that last second of audio, which would cause the + * visualization to appear constant across all different settings. + */ + for (i = 0; i < 320; ++i) { + int j, c = 0; + + /* Take the average of R samples so it fits on the screen */ + for (j = i * R; j < i * R + R && j < sample_count; ++j) { + c += input[j] - sample_center; + } + c /= R; + + /* Draws a line from the previous sample point to the next */ + al_draw_line(i - 1, 128 + ((prev - min_sample_val) / + (float) sample_range) * 256 - 128, i, 128 + + ((c - min_sample_val) / (float) sample_range) * 256 - 128, + al_map_rgb(255,255,255), 1.2); + + prev = c; + } + } + + /* draw volume bar */ + al_draw_filled_rectangle((gain / (float) max_sample_val) * 320, 251, + 0, 256, al_map_rgba(0, 255, 0, 128)); + + al_flip_display(); + } + else if (e.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { + /* This event is received when we are playing back the audio clip. + * See ex_saw.c for an example dedicated to playing streams. + */ + if (fp) { + audio_buffer_t output = al_get_audio_stream_fragment(s); + if (output) { + /* Fill the buffer from the data we have recorded into the file. + * If an error occurs (or end of file) then silence out the + * remainder of the buffer and stop the playback. + */ + const size_t bytes_to_read = + playback_samples_per_fragment * sample_size; + size_t bytes_read = 0, i; + + do { + bytes_read += al_fread(fp, (uint8_t *)output + bytes_read, + bytes_to_read - bytes_read); + } while (bytes_read < bytes_to_read && !al_feof(fp) && + !al_ferror(fp)); + + /* silence out unused part of buffer (end of file) */ + for (i = bytes_read / sample_size; + i < bytes_to_read / sample_size; ++i) { + output[i] = sample_center; + } + + al_set_audio_stream_fragment(s, output); + + if (al_ferror(fp) || al_feof(fp)) { + al_drain_audio_stream(s); + al_fclose(fp); + fp = NULL; + } + } + } + } + else if (e.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + else if (e.type == ALLEGRO_EVENT_KEY_CHAR) { + if (e.keyboard.unichar == 27) { + /* pressed ESC */ + break; + } + else if (e.keyboard.unichar == ' ') { + if (!is_recording) { + /* Start the recording */ + is_recording = true; + + if (al_get_audio_stream_playing(s)) { + al_drain_audio_stream(s); + } + + /* Reuse the same temp file for all recordings */ + if (!tmp_path) { + fp = al_make_temp_file("alrecXXX.raw", &tmp_path); + } + else { + if (fp) al_fclose(fp); + fp = al_fopen(al_path_cstr(tmp_path, '/'), "w"); + } + + n = 0; + } + else { + is_recording = false; + if (fp) { + al_fclose(fp); + fp = NULL; + } + } + } + else if (e.keyboard.unichar == 'p') { + /* Play the previously recorded wav file */ + if (!is_recording) { + if (tmp_path) { + fp = al_fopen(al_path_cstr(tmp_path, '/'), "r"); + if (fp) { + al_set_audio_stream_playing(s, true); + } + } + } + } + } + } + + /* clean up */ + al_destroy_audio_recorder(r); + al_destroy_audio_stream(s); + + if (fp) + al_fclose(fp); + + if (tmp_path) { + al_remove_filename(al_path_cstr(tmp_path, '/')); + al_destroy_path(tmp_path); + } + + return 0; +} diff --git a/allegro/examples/ex_record_name.c b/allegro/examples/ex_record_name.c new file mode 100644 index 00000000..2cda8d95 --- /dev/null +++ b/allegro/examples/ex_record_name.c @@ -0,0 +1,257 @@ +/* ex_record_name + * + * This example automatically detects when you say your name and creates a + * sample (maximum of three seconds). Pressing any key (other than ESC) will + * play it back. + */ + +#define ALLEGRO_UNSTABLE +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + ALLEGRO_AUDIO_RECORDER *recorder; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + int font_height; + + /* Frequency is the number of samples per second. */ + const int frequency = 44100; + + const int channels = 2; + + /* The latency is used to determine the size of the fragment buffer. + More accurately, it represents approximately how many seconds will + pass between fragment events. (There may be overhead latency from + the OS or driver the adds a fixed amount of latency on top of + Allegro's.) + + For this example, the latency should be kept relatively low since + each fragment is processed in its entirety. Increasing the latency + would increase the size of the fragment, which would decrease the + accuracy of the code that processes the fragment. + + But if it's too low, then it will cut out too quickly. (If the + example were more thoroughly written, the latency setting wouldn't + actually change how the voice detection worked.) + */ + const float latency = 0.10; + + const int max_seconds = 3; /* number of seconds of voice recording */ + + int16_t *name_buffer; /* stores up to max_seconds of audio */ + int16_t *name_buffer_pos; /* points to the current recorded position */ + int16_t *name_buffer_end; /* points to the end of the buffer */ + + float gain = 0.0f; /* 0.0 (quiet) - 1.0 (loud) */ + float begin_gain = 0.3f; /* when to begin recording */ + + bool is_recording = false; + + ALLEGRO_SAMPLE *spl = NULL; + + (void) argc; + (void) argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + if (!al_install_audio()) { + abort_example("Unable to initialize audio addon\n"); + } + + if (!al_init_acodec_addon()) { + abort_example("Unable to initialize acoded addon\n"); + } + + if (!al_init_image_addon()) { + abort_example("Unable to initialize image addon\n"); + } + + if (!al_init_primitives_addon()) { + abort_example("Unable to initialize primitives addon\n"); + } + + al_init_font_addon(); + al_install_keyboard(); + + font = al_load_bitmap_font("data/bmpfont.tga"); + if (!font) { + abort_example("Unable to load data/a4_font.tga\n"); + } + + font_height = al_get_font_line_height(font); + + /* WARNING: This demo assumes an audio depth of INT16 and two channels. + Changing those values will break the demo. Nothing here really needs to be + changed. If you want to fiddle with things, adjust the constants at the + beginning of the program. + */ + + recorder = al_create_audio_recorder( + 5 / latency, /* five seconds of buffer space */ + frequency * latency, /* configure the fragment size to give us the given + latency in seconds */ + frequency, /* samples per second (higher => better quality) */ + ALLEGRO_AUDIO_DEPTH_INT16, /* 2-byte sample size */ + ALLEGRO_CHANNEL_CONF_2 /* stereo */ + ); + + if (!recorder) { + abort_example("Unable to create audio recorder\n"); + } + + display = al_create_display(640, 480); + if (!display) { + abort_example("Unable to create display\n"); + } + + /* Used to play back the voice recording. */ + al_reserve_samples(1); + + /* store up to three seconds */ + name_buffer = al_calloc(channels * frequency * max_seconds, sizeof(int16_t)); + name_buffer_pos = name_buffer; + name_buffer_end = name_buffer + channels * frequency * max_seconds; + + queue = al_create_event_queue(); + timer = al_create_timer(1 / 60.0); + + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_audio_recorder_event_source(recorder)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_keyboard_event_source()); + + al_start_timer(timer); + al_start_audio_recorder(recorder); + + while (true) { + ALLEGRO_EVENT event; + bool do_draw = false; + + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE || + (event.type == ALLEGRO_EVENT_KEY_UP && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)) { + break; + } + else if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (spl && event.keyboard.unichar != 27) { + al_play_sample(spl, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL); + } + } + else if (event.type == ALLEGRO_EVENT_TIMER) { + do_draw = true; + } + else if (event.type == ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT && recorder != NULL) { + /* Because the recording happens in a different thread (and simply because we are + queuing up events), it's quite possible to receive (process) a fragment event + after the recorder has been stopped or destroyed. Thus, it is important to + somehow check that the recorder is still valid, as we are doing above. + */ + ALLEGRO_AUDIO_RECORDER_EVENT *re = al_get_audio_recorder_event(&event); + int16_t *buffer = re->buffer; + int16_t low = 0, high = 0; + unsigned int i; + + /* Calculate the volume by comparing the highest and lowest points. This entire + section assumes we are using fairly small fragment size (low latency). If a + large fragment size were used, then we'd have to inspect smaller portions + of it at a time to more accurately deterine when recording started and + stopped. */ + for (i = 0; i < channels * re->samples; ++i) { + if (buffer[i] < low) + low = buffer[i]; + else if (buffer[i] > high) + high = buffer[i]; + } + + gain = gain * 0.25 + ((float) (high - low) / 0xffff) * 0.75; + + /* Set arbitrary thresholds for beginning and stopping recording. This probably + should be calibrated by determining how loud the ambient noise is. + */ + if (!is_recording && gain >= begin_gain && name_buffer_pos == name_buffer) + is_recording = true; + else if (is_recording && gain <= 0.10) + is_recording = false; + + if (is_recording) { + /* Copy out of the fragment buffer into our own buffer that holds the + name. */ + int samples_to_copy = channels * re->samples; + + /* Don't overfill up our name buffer... */ + if (samples_to_copy > name_buffer_end - name_buffer_pos) + samples_to_copy = name_buffer_end - name_buffer_pos; + + if (samples_to_copy) { + /* must multiply by two, since we are using 16-bit samples */ + memcpy(name_buffer_pos, re->buffer, samples_to_copy * 2); + } + + name_buffer_pos += samples_to_copy; + if (name_buffer_pos >= name_buffer_end) { + is_recording = false; + } + } + + if (!is_recording && name_buffer_pos != name_buffer && !spl) { + /* finished recording, but haven't created the sample yet */ + spl = al_create_sample(name_buffer, name_buffer_pos - name_buffer, frequency, + ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2, false); + + /* We no longer need the recorder. Destroying it is the only way to unlock the device. */ + al_destroy_audio_recorder(recorder); + recorder = NULL; + } + } + + if (do_draw) { + al_clear_to_color(al_map_rgb(0,0,0)); + if (!spl) { + const char *msg = "Say Your Name"; + int width = al_get_text_width(font, msg); + + al_draw_text(font, al_map_rgb(255,255,255), + 320, 240 - font_height / 2, ALLEGRO_ALIGN_CENTRE, msg + ); + + /* draw volume meter */ + al_draw_filled_rectangle(320 - width / 2, 242 + font_height / 2, + (320 - width / 2) + (gain * width), 242 + font_height, + al_map_rgb(0,255,0) + ); + + /* draw target line that triggers recording */ + al_draw_line((320 - width / 2) + (begin_gain * width), 242 + font_height / 2, + (320 - width / 2) + (begin_gain * width), 242 + font_height, + al_map_rgb(255,255,0), 1.0 + ); + } + else { + al_draw_text(font, al_map_rgb(255,255,255), 320, 240 - font_height / 2, + ALLEGRO_ALIGN_CENTRE, "Press Any Key"); + } + al_flip_display(); + } + } + + if (recorder) { + al_destroy_audio_recorder(recorder); + } + + al_free(name_buffer); + + return 0; +} diff --git a/allegro/examples/ex_reparent.c b/allegro/examples/ex_reparent.c new file mode 100644 index 00000000..4b09ab49 --- /dev/null +++ b/allegro/examples/ex_reparent.c @@ -0,0 +1,172 @@ +#include +#include +#include +#include +#include + +#include "common.c" + +#define FPS 60 + +struct Example { + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *glyphs[2]; + ALLEGRO_BITMAP *sub; + int i; + int p; +} example; + + +/* Draw the parent bitmaps. */ +static void draw_glyphs(void) +{ + int x = 0, y = 0; + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_draw_bitmap(example.glyphs[0], 0, 0, 0); + al_draw_bitmap(example.glyphs[1], 0, 32 * 6, 0); + if (example.p == 1) + y = 32 * 6; + x += al_get_bitmap_x(example.sub); + y += al_get_bitmap_y(example.sub); + al_draw_filled_rectangle(x, y, + x + al_get_bitmap_width(example.sub), + y + al_get_bitmap_height(example.sub), + al_map_rgba_f(0.5, 0, 0, 0.5)); +} + +static void redraw(void) +{ + int i; + + draw_glyphs(); + + /* Here we draw example.sub, which is never re-created, just + * re-parented. + */ + for (i = 0; i < 8; i++) { + al_draw_scaled_rotated_bitmap(example.sub, 0, 0, + i * 100, 32 * 6 + 33 * 5 + 4, + 2.0, 2.0, ALLEGRO_PI / 4 * i / 8, 0); + } +} + +static void update(void) +{ + /* Re-parent out sub bitmap, jumping from glyph to glyph. */ + int i; + example.i++; + i = (example.i / 4) % (16 * 6 + 20 * 5); + if (i < 16 * 6) { + example.p = 0; + al_reparent_bitmap(example.sub, example.glyphs[0], + (i % 16) * 32, (i / 16) * 32, 32, 32); + } + else { + example.p = 1; + i -= 16 * 6; + al_reparent_bitmap(example.sub, example.glyphs[1], + (i % 20) * 37, (i / 20) * 33, 37, 33); + } +} + +static void init(void) +{ + /* We create out sub bitmap once then use it throughout the + * program, re-parenting as needed. + */ + example.sub = al_create_sub_bitmap(example.glyphs[0], 0, 0, 32, 32); +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + int w = 800, h = 600; + bool done = false; + bool need_redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + al_init_primitives_addon(); + + init_platform_specific(); + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + al_set_new_display_flags(ALLEGRO_RESIZABLE); + example.display = al_create_display(w, h); + if (!example.display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + example.glyphs[0] = al_load_bitmap("data/font.tga"); + if (!example.glyphs[0]) { + abort_example("Error loading data/font.tga\n"); + } + + example.glyphs[1] = al_load_bitmap("data/bmpfont.tga"); + if (!example.glyphs[1]) { + abort_example("Error loading data/bmpfont.tga\n"); + } + + init(); + + timer = al_create_timer(1.0 / FPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_register_event_source(queue, al_get_display_event_source( + example.display)); + + al_start_timer(timer); + + while (!done) { + ALLEGRO_EVENT event; + w = al_get_display_width(example.display); + h = al_get_display_height(example.display); + + if (need_redraw && al_is_event_queue_empty(queue)) { + redraw(); + al_flip_display(); + need_redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_CHAR: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(event.display.source); + break; + + case ALLEGRO_EVENT_TIMER: + update(); + need_redraw = true; + break; + } + } + + return 0; +} diff --git a/allegro/examples/ex_resample_test.c b/allegro/examples/ex_resample_test.c new file mode 100644 index 00000000..ea86a771 --- /dev/null +++ b/allegro/examples/ex_resample_test.c @@ -0,0 +1,198 @@ +/* Resamping test. Probably should integreate into test_driver somehow */ + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" + +#include "common.c" + +#define SAMPLES_PER_BUFFER 1024 + +#define N 2 + +int frequency[N]; +double samplepos[N]; +ALLEGRO_AUDIO_STREAM *stream[N]; +ALLEGRO_DISPLAY *display; + +float waveform[640], waveform_buffer[640]; + +static void mainloop(void) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + float *buf; + double pitch = 440; + int i, si; + int n = 0; + bool redraw = false; + + for (i = 0; i < N; i++) { + frequency[i] = 22050 * pow(2, i / (double)N); + stream[i] = al_create_audio_stream(4, SAMPLES_PER_BUFFER, frequency[i], + ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_1); + if (!stream[i]) { + abort_example("Could not create stream.\n"); + } + + if (!al_attach_audio_stream_to_mixer(stream[i], al_get_default_mixer())) { + abort_example("Could not attach stream to mixer.\n"); + } + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + for (i = 0; i < N; i++) { + al_register_event_source(queue, + al_get_audio_stream_event_source(stream[i])); + } +#ifdef ALLEGRO_POPUP_EXAMPLES + if (textlog) { + al_register_event_source(queue, al_get_native_text_log_event_source(textlog)); + } +#endif + + log_printf("Generating %d sine waves of different sampling quality\n", N); + log_printf("If Allegro's resampling is correct there should be little variation\n", N); + + timer = al_create_timer(1.0 / 60); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_register_event_source(queue, al_get_display_event_source(display)); + + al_start_timer(timer); + while (n < 60 * frequency[0] / SAMPLES_PER_BUFFER * N) { + ALLEGRO_EVENT event; + + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { + for (si = 0; si < N; si++) { + buf = al_get_audio_stream_fragment(stream[si]); + if (!buf) { + continue; + } + + for (i = 0; i < SAMPLES_PER_BUFFER; i++) { + double t = samplepos[si]++ / (double)frequency[si]; + buf[i] = sin(t * pitch * ALLEGRO_PI * 2) / N; + } + + if (!al_set_audio_stream_fragment(stream[si], buf)) { + log_printf("Error setting stream fragment.\n"); + } + + n++; + log_printf("%d", si); + if ((n % 60) == 0) + log_printf("\n"); + } + } + + if (event.type == ALLEGRO_EVENT_TIMER) { + redraw = true; + } + + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + +#ifdef ALLEGRO_POPUP_EXAMPLES + if (event.type == ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE) { + break; + } +#endif + + if (redraw &&al_is_event_queue_empty(queue)) { + ALLEGRO_COLOR c = al_map_rgb(0, 0, 0); + int i; + al_clear_to_color(al_map_rgb_f(1, 1, 1)); + + for (i = 0; i < 640; i++) { + al_draw_pixel(i, 50 + waveform[i] * 50, c); + } + + al_flip_display(); + redraw = false; + } + } + + for (si = 0; si < N; si++) { + al_drain_audio_stream(stream[si]); + } + + log_printf("\n"); + + al_destroy_event_queue(queue); +} + +static void update_waveform(void *buf, unsigned int samples, void *data) +{ + static int pos; + float *fbuf = (float *)buf; + int i; + int n = samples; + (void)data; + + /* Yes, we could do something more advanced, but an oscilloscope of the + * first 640 samples of each buffer is enough for our purpose here. + */ + if (n > 640) n = 640; + + for (i = 0; i < n; i++) { + waveform_buffer[pos++] = fbuf[i * 2]; + if (pos == 640) { + memcpy(waveform, waveform_buffer, 640 * sizeof(float)); + pos = 0; + break; + } + } +} + +int main(int argc, char **argv) +{ + int i; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + + open_log(); + + display = al_create_display(640, 100); + if (!display) { + abort_example("Could not create display.\n"); + } + + if (!al_install_audio()) { + abort_example("Could not init sound.\n"); + } + al_reserve_samples(N); + + al_set_mixer_postprocess_callback(al_get_default_mixer(), update_waveform, NULL); + + mainloop(); + + close_log(false); + + for (i = 0; i < N; i++) { + al_destroy_audio_stream(stream[i]); + } + al_uninstall_audio(); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_resize.c b/allegro/examples/ex_resize.c new file mode 100644 index 00000000..de4cd142 --- /dev/null +++ b/allegro/examples/ex_resize.c @@ -0,0 +1,88 @@ +#include "allegro5/allegro.h" +#include + +#include "common.c" + +static void redraw(void) +{ + ALLEGRO_COLOR black, white; + int w, h; + + white = al_map_rgba_f(1, 1, 1, 1); + black = al_map_rgba_f(0, 0, 0, 1); + + al_clear_to_color(white); + w = al_get_bitmap_width(al_get_target_bitmap()); + h = al_get_bitmap_height(al_get_target_bitmap()); + al_draw_line(0, h, w / 2, 0, black, 0); + al_draw_line(w / 2, 0, w, h, black, 0); + al_draw_line(w / 4, h / 2, 3 * w / 4, h / 2, black, 0); + al_flip_display(); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *events; + ALLEGRO_EVENT event; + int rs = 100; + bool resize = false; + + (void)argc; + (void)argv; + + /* Initialize Allegro and create an event queue. */ + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_primitives_addon(); + events = al_create_event_queue(); + + /* Setup a display driver and register events from it. */ + al_set_new_display_flags(ALLEGRO_RESIZABLE); + display = al_create_display(rs, rs); + if (!display) { + abort_example("Could not create display.\n"); + } + al_register_event_source(events, al_get_display_event_source(display)); + + timer = al_create_timer(0.1); + al_start_timer(timer); + + /* Setup a keyboard driver and register events from it. */ + al_install_keyboard(); + al_register_event_source(events, al_get_keyboard_event_source()); + al_register_event_source(events, al_get_timer_event_source(timer)); + + /* Display a pulsating window until a key or the closebutton is pressed. */ + redraw(); + while (true) { + if (resize) { + int s; + rs += 10; + if (rs == 300) + rs = 100; + s = rs; + if (s > 200) + s = 400 - s; + al_resize_display(display, s, s); + redraw(); + resize = false; + } + al_wait_for_event(events, &event); + if (event.type == ALLEGRO_EVENT_TIMER) { + resize = true; + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + break; + } + } + + return 0; +} + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_resize2.c b/allegro/examples/ex_resize2.c new file mode 100644 index 00000000..7257d195 --- /dev/null +++ b/allegro/examples/ex_resize2.c @@ -0,0 +1,108 @@ +/* + * Test program for Allegro. + * + * Resizing the window currently shows broken behaviour. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_font.h" +#include + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bmp; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + ALLEGRO_FONT *font; + bool redraw; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_install_keyboard(); + al_init_image_addon(); + al_init_font_addon(); + + al_set_new_display_flags(ALLEGRO_RESIZABLE | + ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(640, 480); + if (!display) { + abort_example("Unable to set any graphic mode\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + bmp = al_load_bitmap("data/mysha.pcx"); + if (!bmp) { + abort_example("Unable to load image\n"); + } + + font = al_create_builtin_font(); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_keyboard_event_source()); + + redraw = true; + while (true) { + if (redraw && al_is_event_queue_empty(queue)) { + al_clear_to_color(al_map_rgb(255, 0, 0)); + al_draw_scaled_bitmap(bmp, + 0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), + 0, 0, al_get_display_width(display), al_get_display_height(display), + 0); + al_draw_multiline_textf(font, al_map_rgb(255, 255, 0), 0, 0, 640, + al_get_font_line_height(font), 0, + "size: %d x %d\n" + "maximized: %s\n" + "+ key to maximize\n" + "- key to un-maximize", + al_get_display_width(display), + al_get_display_height(display), + al_get_display_flags(display) & ALLEGRO_MAXIMIZED ? "yes" : + "no"); + + al_flip_display(); + redraw = false; + } + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { + al_acknowledge_resize(event.display.source); + redraw = true; + } + if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { + redraw = true; + } + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + if (event.type == ALLEGRO_EVENT_KEY_CHAR && + event.keyboard.unichar == '+') { + al_set_display_flag(display, ALLEGRO_MAXIMIZED, true); + } + if (event.type == ALLEGRO_EVENT_KEY_CHAR && + event.keyboard.unichar == '-') { + al_set_display_flag(display, ALLEGRO_MAXIMIZED, false); + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + } + + al_destroy_bitmap(bmp); + al_destroy_display(display); + + return 0; + +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_rotate.c b/allegro/examples/ex_rotate.c new file mode 100644 index 00000000..4a6348ab --- /dev/null +++ b/allegro/examples/ex_rotate.c @@ -0,0 +1,171 @@ +/* + * Example program for the Allegro library, by Peter Wang. + */ + + +#include +#include "allegro5/allegro_image.h" +#include + +#include "common.c" + +int main(int argc, char **argv) +{ + const int display_w = 640; + const int display_h = 480; + + ALLEGRO_DISPLAY *dpy; + ALLEGRO_BITMAP *buf; + ALLEGRO_BITMAP *bmp; + ALLEGRO_BITMAP *mem_bmp; + ALLEGRO_BITMAP *src_bmp; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + double theta = 0; + double k = 1.0; + int mode = 0; + bool wide_mode = false; + bool mem_src_mode = false; + bool trans_mode = false; + int flags = 0; + bool clip_mode = false; + ALLEGRO_COLOR trans; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + open_log(); + log_printf("Press 'w' to toggle wide mode.\n"); + log_printf("Press 's' to toggle memory source bitmap.\n"); + log_printf("Press space to toggle drawing to backbuffer or off-screen bitmap.\n"); + log_printf("Press 't' to toggle translucency.\n"); + log_printf("Press 'h' to toggle horizontal flipping.\n"); + log_printf("Press 'v' to toggle vertical flipping.\n"); + log_printf("Press 'c' to toggle clipping.\n"); + log_printf("\n"); + + dpy = al_create_display(display_w, display_h); + if (!dpy) { + abort_example("Unable to set any graphic mode\n"); + } + + buf = al_create_bitmap(display_w, display_h); + if (!buf) { + abort_example("Unable to create buffer\n\n"); + } + + bmp = al_load_bitmap("data/mysha.pcx"); + if (!bmp) { + abort_example("Unable to load image\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + mem_bmp = al_load_bitmap("data/mysha.pcx"); + if (!mem_bmp) { + abort_example("Unable to load image\n"); + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + while (true) { + if (al_get_next_event(queue, &event)) { + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + if (event.keyboard.unichar == ' ') { + mode = !mode; + if (mode == 0) + log_printf("Drawing to off-screen buffer\n"); + else + log_printf("Drawing to display backbuffer\n"); + } + if (event.keyboard.unichar == 'w') + wide_mode = !wide_mode; + if (event.keyboard.unichar == 's') { + mem_src_mode = !mem_src_mode; + if (mem_src_mode) + log_printf("Source is memory bitmap\n"); + else + log_printf("Source is display bitmap\n"); + } + if (event.keyboard.unichar == 't') + trans_mode = !trans_mode; + if (event.keyboard.unichar == 'h') + flags ^= ALLEGRO_FLIP_HORIZONTAL; + if (event.keyboard.unichar == 'v') + flags ^= ALLEGRO_FLIP_VERTICAL; + if (event.keyboard.unichar == 'c') + clip_mode = !clip_mode; + } + } + + /* + * mode 0 = draw scaled to off-screen buffer before + * blitting to display backbuffer + * mode 1 = draw scaled to display backbuffer + */ + + if (mode == 0) { + al_set_target_bitmap(buf); + } + else { + al_set_target_backbuffer(dpy); + } + + src_bmp = (mem_src_mode) ? mem_bmp : bmp; + k = (wide_mode) ? 2.0 : 1.0; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + trans = al_map_rgba_f(1, 1, 1, 1); + if (mode == 0) + al_clear_to_color(al_map_rgba_f(1, 0, 0, 1)); + else + al_clear_to_color(al_map_rgba_f(0, 0, 1, 1)); + + if (trans_mode) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + trans = al_map_rgba_f(1, 1, 1, 0.5); + } + + if (clip_mode) { + al_set_clipping_rectangle(50, 50, display_w - 100, display_h - 100); + } + else { + al_set_clipping_rectangle(0, 0, display_w, display_h); + } + + al_draw_tinted_scaled_rotated_bitmap(src_bmp, + trans, + 50, 50, display_w/2, display_h/2, + k, k, theta, + flags); + + if (mode == 0) { + al_set_target_backbuffer(dpy); + al_set_clipping_rectangle(0, 0, display_w, display_h); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_bitmap(buf, 0, 0, 0); + } + + al_flip_display(); + al_rest(0.01); + theta -= 0.01; + } + + al_destroy_bitmap(bmp); + al_destroy_bitmap(mem_bmp); + al_destroy_bitmap(buf); + + close_log(false); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_saw.c b/allegro/examples/ex_saw.c new file mode 100644 index 00000000..b35700e8 --- /dev/null +++ b/allegro/examples/ex_saw.c @@ -0,0 +1,121 @@ +/* Recreate exstream.c from A4. */ + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" + +#include "common.c" + +#define SAMPLES_PER_BUFFER 1024 + + +static void saw(ALLEGRO_AUDIO_STREAM *stream) +{ + ALLEGRO_EVENT_QUEUE *queue; + int8_t *buf; + int pitch = 0x10000; + int val = 0; + int i; + int n = 200; + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_audio_stream_event_source(stream)); +#ifdef ALLEGRO_POPUP_EXAMPLES + if (textlog) { + al_register_event_source(queue, al_get_native_text_log_event_source(textlog)); + } +#endif + + log_printf("Generating saw wave...\n"); + + while (n > 0) { + ALLEGRO_EVENT event; + + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { + buf = al_get_audio_stream_fragment(stream); + if (!buf) { + /* This is a normal condition you must deal with. */ + continue; + } + + for (i = 0; i < SAMPLES_PER_BUFFER; i++) { + /* Crude saw wave at maximum amplitude. Please keep this compatible + * to the A4 example so we know when something has broken for now. + * + * It would be nice to have a better example with user interface + * and some simple synth effects. + */ + buf[i] = ((val >> 16) & 0xff); + val += pitch; + pitch++; + } + + if (!al_set_audio_stream_fragment(stream, buf)) { + log_printf("Error setting stream fragment.\n"); + } + + n--; + if ((n % 10) == 0) { + log_printf("."); + fflush(stdout); + } + } + +#ifdef ALLEGRO_POPUP_EXAMPLES + if (event.type == ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE) { + break; + } +#endif + } + + al_drain_audio_stream(stream); + + log_printf("\n"); + + al_destroy_event_queue(queue); +} + + +int main(int argc, char **argv) +{ + ALLEGRO_AUDIO_STREAM *stream; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + if (!al_install_audio()) { + abort_example("Could not init sound.\n"); + } + al_reserve_samples(0); + + stream = al_create_audio_stream(8, SAMPLES_PER_BUFFER, 22050, + ALLEGRO_AUDIO_DEPTH_UINT8, ALLEGRO_CHANNEL_CONF_1); + if (!stream) { + abort_example("Could not create stream.\n"); + } + + if (!al_attach_audio_stream_to_mixer(stream, al_get_default_mixer())) { + abort_example("Could not attach stream to mixer.\n"); + } + + open_log(); + + saw(stream); + + close_log(false); + + al_destroy_audio_stream(stream); + al_uninstall_audio(); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_scale.c b/allegro/examples/ex_scale.c new file mode 100644 index 00000000..fc4b18f2 --- /dev/null +++ b/allegro/examples/ex_scale.c @@ -0,0 +1,177 @@ +/* + * Example program for the Allegro library, by Peter Wang. + */ + + +#include +#include "allegro5/allegro_image.h" +#include + +#include "common.c" + +int main(int argc, char **argv) +{ + const int display_w = 640; + const int display_h = 480; + + ALLEGRO_DISPLAY *dpy; + ALLEGRO_BITMAP *buf; + ALLEGRO_BITMAP *bmp; + ALLEGRO_BITMAP *mem_bmp; + ALLEGRO_BITMAP *src_bmp; + int bmp_w; + int bmp_h; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + double theta = 0; + double k = 1.0; + int mode = 0; + bool wide_mode = false; + bool mem_src_mode = false; + bool trans_mode = false; + int flags = 0; + bool clip_mode = false; + ALLEGRO_COLOR tint; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + open_log(); + log_printf("Press 'w' to toggle wide mode.\n"); + log_printf("Press 's' to toggle memory source bitmap.\n"); + log_printf("Press space to toggle drawing to backbuffer or off-screen bitmap.\n"); + log_printf("Press 't' to toggle translucency.\n"); + log_printf("Press 'h' to toggle horizontal flipping.\n"); + log_printf("Press 'v' to toggle vertical flipping.\n"); + log_printf("Press 'c' to toggle clipping.\n"); + log_printf("\n"); + + dpy = al_create_display(display_w, display_h); + if (!dpy) { + abort_example("Unable to set any graphic mode\n"); + } + + buf = al_create_bitmap(display_w, display_h); + if (!buf) { + abort_example("Unable to create buffer\n\n"); + } + + bmp = al_load_bitmap("data/mysha.pcx"); + if (!bmp) { + abort_example("Unable to load image\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + mem_bmp = al_load_bitmap("data/mysha.pcx"); + if (!mem_bmp) { + abort_example("Unable to load image\n"); + } + + bmp_w = al_get_bitmap_width(bmp); + bmp_h = al_get_bitmap_height(bmp); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + while (true) { + if (al_get_next_event(queue, &event)) { + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + if (event.keyboard.unichar == ' ') { + mode = !mode; + if (mode == 0) + log_printf("Drawing to off-screen buffer\n"); + else + log_printf("Drawing to display backbuffer\n"); + } + if (event.keyboard.unichar == 'w') + wide_mode = !wide_mode; + if (event.keyboard.unichar == 's') { + mem_src_mode = !mem_src_mode; + if (mem_src_mode) + log_printf("Source is memory bitmap\n"); + else + log_printf("Source is display bitmap\n"); + } + if (event.keyboard.unichar == 't') + trans_mode = !trans_mode; + if (event.keyboard.unichar == 'h') + flags ^= ALLEGRO_FLIP_HORIZONTAL; + if (event.keyboard.unichar == 'v') + flags ^= ALLEGRO_FLIP_VERTICAL; + if (event.keyboard.unichar == 'c') + clip_mode = !clip_mode; + } + } + + /* + * mode 0 = draw scaled to off-screen buffer before + * blitting to display backbuffer + * mode 1 = draw scaled to display backbuffer + */ + + if (mode == 0) { + al_set_target_bitmap(buf); + } + else { + al_set_target_backbuffer(dpy); + } + + src_bmp = (mem_src_mode) ? mem_bmp : bmp; + k = (wide_mode) ? 2.0 : 1.0; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + tint = al_map_rgba_f(1, 1, 1, 1); + if (mode == 0) + al_clear_to_color(al_map_rgba_f(1, 0, 0, 1)); + else + al_clear_to_color(al_map_rgba_f(0, 0, 1, 1)); + + if (trans_mode) { + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + tint = al_map_rgba_f(1, 1, 1, 0.5); + } + + if (clip_mode) { + al_set_clipping_rectangle(50, 50, display_w - 100, display_h - 100); + } + else { + al_set_clipping_rectangle(0, 0, display_w, display_h); + } + + al_draw_tinted_scaled_bitmap(src_bmp, tint, + 0, 0, bmp_w, bmp_h, + display_w/2, display_h/2, + k * cos(theta) * display_w/2, k * sin(theta) * display_h/2, + flags); + + if (mode == 0) { + al_set_target_backbuffer(dpy); + al_set_clipping_rectangle(0, 0, display_w, display_h); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_bitmap(buf, 0, 0, 0); + } + + al_flip_display(); + al_rest(0.01); + theta += 0.01; + } + + al_destroy_bitmap(bmp); + al_destroy_bitmap(mem_bmp); + al_destroy_bitmap(buf); + + close_log(false); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_shader.cpp b/allegro/examples/ex_shader.cpp new file mode 100644 index 00000000..87a42f58 --- /dev/null +++ b/allegro/examples/ex_shader.cpp @@ -0,0 +1,157 @@ +#include +#include "allegro5/allegro5.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_primitives.h" + +/* The ALLEGRO_CFG_* defines are actually internal to Allegro so don't use them + * in your own programs. + */ +#ifdef ALLEGRO_CFG_D3D + #include "allegro5/allegro_direct3d.h" +#endif +#ifdef ALLEGRO_CFG_OPENGL + #include "allegro5/allegro_opengl.h" +#endif + +#include "common.c" + +static int display_flags = 0; + +static void parse_args(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) { + if (0 == strcmp(argv[i], "--opengl")) { + display_flags = ALLEGRO_OPENGL; + continue; + } +#ifdef ALLEGRO_CFG_D3D + if (0 == strcmp(argv[i], "--d3d")) { + display_flags = ALLEGRO_DIRECT3D; + continue; + } +#endif + abort_example("Unrecognised argument: %s\n", argv[i]); + } +} + +static void choose_shader_source(ALLEGRO_SHADER *shader, + char const **vsource, char const **psource) +{ + ALLEGRO_SHADER_PLATFORM platform = al_get_shader_platform(shader); + if (platform == ALLEGRO_SHADER_HLSL) { + *vsource = "data/ex_shader_vertex.hlsl"; + *psource = "data/ex_shader_pixel.hlsl"; + } + else if (platform == ALLEGRO_SHADER_GLSL) { + *vsource = "data/ex_shader_vertex.glsl"; + *psource = "data/ex_shader_pixel.glsl"; + } + else { + /* Shouldn't happen. */ + *vsource = NULL; + *psource = NULL; + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bmp; + ALLEGRO_SHADER *shader; + const char *vsource; + const char *psource; + + parse_args(argc, argv); + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE | display_flags); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display.\n"); + } + + bmp = al_load_bitmap("data/mysha.pcx"); + if (!bmp) { + abort_example("Could not load bitmap.\n"); + } + + shader = al_create_shader(ALLEGRO_SHADER_AUTO); + if (!shader) { + abort_example("Could not create shader.\n"); + } + + choose_shader_source(shader, &vsource, &psource); + if (!vsource|| !psource) { + abort_example("Could not load source files.\n"); + } + + if (!al_attach_shader_source_file(shader, ALLEGRO_VERTEX_SHADER, vsource)) { + abort_example("al_attach_shader_source_file failed: %s\n", + al_get_shader_log(shader)); + } + if (!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, psource)) { + abort_example("al_attach_shader_source_file failed: %s\n", + al_get_shader_log(shader)); + } + + if (!al_build_shader(shader)) { + abort_example("al_build_shader failed: %s\n", al_get_shader_log(shader)); + } + + al_use_shader(shader); + + float tints[12] = { + 4.0, 0.0, 1.0, + 0.0, 4.0, 1.0, + 1.0, 0.0, 4.0, + 4.0, 4.0, 1.0 + }; + + while (1) { + ALLEGRO_KEYBOARD_STATE s; + al_get_keyboard_state(&s); + if (al_key_down(&s, ALLEGRO_KEY_ESCAPE)) + break; + + al_clear_to_color(al_map_rgb(140, 40, 40)); + + al_set_shader_float_vector("tint", 3, &tints[0], 1); + al_draw_bitmap(bmp, 0, 0, 0); + + al_set_shader_float_vector("tint", 3, &tints[3], 1); + al_draw_bitmap(bmp, 320, 0, 0); + + al_set_shader_float_vector("tint", 3, &tints[6], 1); + al_draw_bitmap(bmp, 0, 240, 0); + + /* Draw the last one transformed */ + ALLEGRO_TRANSFORM trans, backup; + al_copy_transform(&backup, al_get_current_transform()); + al_identity_transform(&trans); + al_translate_transform(&trans, 320, 240); + al_set_shader_float_vector("tint", 3, &tints[9], 1); + al_use_transform(&trans); + al_draw_bitmap(bmp, 0, 0, 0); + al_use_transform(&backup); + + al_flip_display(); + + al_rest(0.01); + } + + al_use_shader(NULL); + al_destroy_shader(shader); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_shader_multitex.c b/allegro/examples/ex_shader_multitex.c new file mode 100644 index 00000000..8b1a1f1e --- /dev/null +++ b/allegro/examples/ex_shader_multitex.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_opengl.h" + +#include "common.c" + +static ALLEGRO_BITMAP *load_bitmap(char const *filename) +{ + ALLEGRO_BITMAP *bitmap = al_load_bitmap(filename); + if (!bitmap) + abort_example("%s not found or failed to load\n", filename); + return bitmap; +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bitmap[2]; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + bool redraw = true; + ALLEGRO_SHADER *shader; + int t = 0; + const char* pixel_file = NULL; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_mouse(); + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | + ALLEGRO_MIPMAP); + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); + al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); + al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE); + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + bitmap[0]= load_bitmap("data/mysha.pcx"); + bitmap[1]= load_bitmap("data/obp.jpg"); + + shader = al_create_shader(ALLEGRO_SHADER_AUTO); + if (!shader) + abort_example("Error creating shader.\n"); + + if (al_get_shader_platform(shader) == ALLEGRO_SHADER_GLSL) { +#ifdef ALLEGRO_CFG_SHADER_GLSL + pixel_file = "data/ex_shader_multitex_pixel.glsl"; +#endif + } + else { +#ifdef ALLEGRO_CFG_SHADER_HLSL + pixel_file = "data/ex_shader_multitex_pixel.hlsl"; +#endif + } + + if (!pixel_file) { + abort_example("No shader source\n"); + } + if (!al_attach_shader_source(shader, ALLEGRO_VERTEX_SHADER, + al_get_default_shader_source(ALLEGRO_SHADER_AUTO, ALLEGRO_VERTEX_SHADER))) { + abort_example("al_attach_shader_source for vertex shader failed: %s\n", al_get_shader_log(shader)); + } + if (!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, pixel_file)) + abort_example("al_attach_shader_source_file for pixel shader failed: %s\n", al_get_shader_log(shader)); + if (!al_build_shader(shader)) + abort_example("al_build_shader failed: %s\n", al_get_shader_log(shader)); + + al_use_shader(shader); + + timer = al_create_timer(1.0 / 60); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + break; + + } + if (event.type == ALLEGRO_EVENT_TIMER) { + redraw = true; + t++; + } + + if (redraw && al_is_event_queue_empty(queue)) { + int dw, dh; + double scale = 1 + 100 * (1 + sin(t * ALLEGRO_PI * 2 / 60 / 10)); + double angle = ALLEGRO_PI * 2 * t / 60 / 15; + double x = 120 - 20 * cos(ALLEGRO_PI * 2 * t / 60 / 25); + double y = 120 - 20 * sin(ALLEGRO_PI * 2 * t / 60 / 25); + + dw = al_get_display_width(display); + dh = al_get_display_height(display); + + redraw = false; + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + + /* We set a second bitmap for texture unit 1. Unit 0 will have + * the normal texture which al_draw_*_bitmap will set up for us. + * We then draw the bitmap like normal, except it will use the + * custom shader. + */ + al_set_shader_sampler("tex2", bitmap[1], 1); + al_draw_scaled_rotated_bitmap(bitmap[0], x, y, dw / 2, dh / 2, + scale, scale, angle, 0); + + al_flip_display(); + } + } + + al_use_shader(NULL); + + al_destroy_bitmap(bitmap[0]); + al_destroy_bitmap(bitmap[1]); + al_destroy_shader(shader); + + return 0; +} + + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_shader_target.c b/allegro/examples/ex_shader_target.c new file mode 100644 index 00000000..4a3f02e6 --- /dev/null +++ b/allegro/examples/ex_shader_target.c @@ -0,0 +1,153 @@ +/* + * Example program for the Allegro library. + * + * Test that shaders are applied per target bitmap. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" + +#include "common.c" + +static const int MAX_REGION = 4; + +static float tints[12] = +{ + 4.0, 0.0, 1.0, + 0.0, 4.0, 1.0, + 1.0, 0.0, 4.0, + 4.0, 4.0, 1.0 +}; + +static void choose_shader_source(ALLEGRO_SHADER_PLATFORM platform, + char const **vsource, char const **psource) +{ + if (platform == ALLEGRO_SHADER_HLSL) { + *vsource = "data/ex_shader_vertex.hlsl"; + *psource = "data/ex_shader_pixel.hlsl"; + } + else if (platform == ALLEGRO_SHADER_GLSL) { + *vsource = "data/ex_shader_vertex.glsl"; + *psource = "data/ex_shader_pixel.glsl"; + } + else { + /* Shouldn't happen. */ + *vsource = NULL; + *psource = NULL; + } +} + +static ALLEGRO_BITMAP *make_region(ALLEGRO_BITMAP *parent, + int x, int y, int w, int h, ALLEGRO_SHADER *shader) +{ + ALLEGRO_BITMAP *sub = al_create_sub_bitmap(parent, x, y, w, h); + if (sub) { + al_set_target_bitmap(sub); + al_use_shader(shader); + /* Not bothering to restore old target bitmap. */ + } + return sub; +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *image; + ALLEGRO_BITMAP *backbuffer; + ALLEGRO_BITMAP *region[4]; + ALLEGRO_SHADER *shader; + const char *vsource; + const char *psource; + ALLEGRO_TRANSFORM t; + int i; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_install_keyboard(); + al_init_image_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_PROGRAMMABLE_PIPELINE); + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display.\n"); + } + + image = al_load_bitmap("data/mysha.pcx"); + if (!image) { + abort_example("Could not load image.\n"); + } + + /* Create the shader. */ + shader = al_create_shader(ALLEGRO_SHADER_AUTO); + if (!shader) { + abort_example("Could not create shader.\n"); + } + choose_shader_source(al_get_shader_platform(shader), &vsource, &psource); + if (!vsource|| !psource) { + abort_example("Could not load source files.\n"); + } + if (!al_attach_shader_source_file(shader, ALLEGRO_VERTEX_SHADER, vsource)) { + abort_example("al_attach_shader_source_file failed: %s\n", + al_get_shader_log(shader)); + } + if (!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, psource)) { + abort_example("al_attach_shader_source_file failed: %s\n", + al_get_shader_log(shader)); + } + if (!al_build_shader(shader)) { + abort_example("al_build_shader failed: %s\n", al_get_shader_log(shader)); + } + + /* Create four sub-bitmaps of the backbuffer sharing a shader. */ + backbuffer = al_get_backbuffer(display); + region[0] = make_region(backbuffer, 0, 0, 320, 200, shader); + region[1] = make_region(backbuffer, 320, 0, 320, 200, shader); + region[2] = make_region(backbuffer, 0, 240, 320, 200, shader); + region[3] = make_region(backbuffer, 320, 240, 320, 200, shader); + if (!region[0] || !region[1] || !region[2] || !region[3]) { + abort_example("make_region failed\n"); + } + + /* Apply a transformation to the last region (the current target). */ + al_identity_transform(&t); + al_scale_transform(&t, 2.0, 2.0); + al_translate_transform(&t, -160, -100); + al_use_transform(&t); + + for (;;) { + ALLEGRO_KEYBOARD_STATE s; + al_get_keyboard_state(&s); + if (al_key_down(&s, ALLEGRO_KEY_ESCAPE)) + break; + + for (i = 0; i < MAX_REGION; i++) { + /* When we change the target bitmap, the shader that was last used on + * that bitmap is automatically in effect. All of our region + * sub-bitmaps use the same shader so we need to set the tint variable + * each time, as it was clobbered when drawing to the previous region. + */ + al_set_target_bitmap(region[i]); + al_set_shader_float_vector("tint", 3, &tints[i * 3], 1); + al_draw_bitmap(image, 0, 0, 0); + } + + al_set_target_backbuffer(display); + al_draw_tinted_bitmap(image, al_map_rgba_f(0.5, 0.5, 0.5, 0.5), + 320/2, 240/2, 0); + + al_flip_display(); + } + + al_set_target_backbuffer(display); + al_use_shader(NULL); + al_destroy_shader(shader); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_stream_file.c b/allegro/examples/ex_stream_file.c new file mode 100644 index 00000000..b6485e70 --- /dev/null +++ b/allegro/examples/ex_stream_file.c @@ -0,0 +1,139 @@ +/* + * An example program that plays a file from the disk using Allegro5 + * streaming API. The file is being read in small chunks and played on the + * sound device instead of being loaded at once. + * + * usage: ./ex_stream_file file.[wav,ogg...] ... + * + * by Milan Mimica + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" + +#include "common.c" + +/* Attaches the stream directly to a voice. Streamed file's and voice's sample + * rate, channels and depth must match. + */ +//#define BYPASS_MIXER + +char *default_files[] = {NULL, "../demos/skater/data/menu/skate2.ogg"}; + +int main(int argc, char **argv) +{ + int i; + ALLEGRO_VOICE* voice; + ALLEGRO_MIXER* mixer; + bool loop = false; + int arg_start = 1; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + if (argc < 2) { + log_printf("This example can be run from the command line.\n"); + log_printf("Usage: %s [--loop] {audio_files}\n", argv[0]); + argv = default_files; + argc = 2; + } + + if (strcmp(argv[1], "--loop") == 0) { + loop = true; + arg_start = 2; + } + + al_init_acodec_addon(); + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + + voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, + ALLEGRO_CHANNEL_CONF_2); + if (!voice) { + abort_example("Could not create ALLEGRO_VOICE.\n"); + } + log_printf("Voice created.\n"); + +#ifndef BYPASS_MIXER + mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, + ALLEGRO_CHANNEL_CONF_2); + if (!mixer) { + abort_example("Could not create ALLEGRO_MIXER.\n"); + } + log_printf("Mixer created.\n"); + + if (!al_attach_mixer_to_voice(mixer, voice)) { + abort_example("al_attach_mixer_to_voice failed.\n"); + } +#endif + + for (i = arg_start; i < argc; ++i) + { + ALLEGRO_AUDIO_STREAM* stream; + const char* filename = argv[i]; + bool playing = true; + ALLEGRO_EVENT event; + ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue(); + + stream = al_load_audio_stream(filename, 4, 2048); + if (!stream) { + /* If it is not packed, e.g. on Android or iOS. */ + if (!strcmp(filename, default_files[1])) { + stream = al_load_audio_stream("data/welcome.wav", 4, 2048); + } + } + if (!stream) { + log_printf("Could not create an ALLEGRO_AUDIO_STREAM from '%s'!\n", + filename); + continue; + } + log_printf("Stream created from '%s'.\n", filename); + if (loop) { + al_set_audio_stream_playmode(stream, loop ? ALLEGRO_PLAYMODE_LOOP : ALLEGRO_PLAYMODE_ONCE); + } + + al_register_event_source(queue, al_get_audio_stream_event_source(stream)); + +#ifndef BYPASS_MIXER + if (!al_attach_audio_stream_to_mixer(stream, mixer)) { + log_printf("al_attach_audio_stream_to_mixer failed.\n"); + continue; + } +#else + if (!al_attach_audio_stream_to_voice(stream, voice)) { + abort_example("al_attach_audio_stream_to_voice failed.\n"); + } +#endif + + log_printf("Playing %s ... Waiting for stream to finish ", filename); + do { + al_wait_for_event(queue, &event); + if(event.type == ALLEGRO_EVENT_AUDIO_STREAM_FINISHED) + playing = false; + } while (playing); + log_printf("\n"); + + al_destroy_event_queue(queue); + al_destroy_audio_stream(stream); + } + log_printf("Done\n"); + +#ifndef BYPASS_MIXER + al_destroy_mixer(mixer); +#endif + al_destroy_voice(voice); + + al_uninstall_audio(); + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_stream_seek.c b/allegro/examples/ex_stream_seek.c new file mode 100644 index 00000000..69ed02c8 --- /dev/null +++ b/allegro/examples/ex_stream_seek.c @@ -0,0 +1,296 @@ +/* + * Example program for the Allegro library, by Todd Cope. + * + * Stream seeking. + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_acodec.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" + +ALLEGRO_DISPLAY *display; +ALLEGRO_TIMER *timer; +ALLEGRO_EVENT_QUEUE *queue; +ALLEGRO_FONT *basic_font = NULL; +ALLEGRO_AUDIO_STREAM *music_stream = NULL; +const char *stream_filename = "data/welcome.wav"; + +float slider_pos = 0.0; +float loop_start, loop_end; +int mouse_button[16] = {0}; + +bool exiting = false; + +static void initialize(void) +{ + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_init_primitives_addon(); + al_init_image_addon(); + al_init_font_addon(); + if (!al_install_keyboard()) { + abort_example("Could not init keyboard!\n"); + } + if (!al_install_mouse()) { + abort_example("Could not init mouse!\n"); + } + + al_init_acodec_addon(); + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + if (!al_reserve_samples(16)) { + abort_example("Could not set up voice and mixer.\n"); + } + + init_platform_specific(); + + display = al_create_display(640, 228); + if (!display) { + abort_example("Could not create display!\n"); + } + + basic_font = al_load_font("data/font.tga", 0, 0); + if (!basic_font) { + abort_example("Could not load font!\n"); + } + timer = al_create_timer(1.000 / 30); + if (!timer) { + abort_example("Could not init timer!\n"); + } + queue = al_create_event_queue(); + if (!queue) { + abort_example("Could not create event queue!\n"); + } + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); +} + +static void logic(void) +{ + /* calculate the position of the slider */ + double w = al_get_display_width(display) - 20; + double pos = al_get_audio_stream_position_secs(music_stream); + double len = al_get_audio_stream_length_secs(music_stream); + slider_pos = w * (pos / len); +} + +static void print_time(int x, int y, float t) +{ + int hours, minutes; + hours = (int)t / 3600; + t -= hours * 3600; + minutes = (int)t / 60; + t -= minutes * 60; + al_draw_textf(basic_font, al_map_rgb(255, 255, 255), x, y, 0, "%02d:%02d:%05.2f", hours, minutes, t); +} + +static void render(void) +{ + double pos = al_get_audio_stream_position_secs(music_stream); + double length = al_get_audio_stream_length_secs(music_stream); + double w = al_get_display_width(display) - 20; + double loop_start_pos = w * (loop_start / length); + double loop_end_pos = w * (loop_end / length); + ALLEGRO_COLOR c = al_map_rgb(255, 255, 255); + + al_clear_to_color(al_map_rgb(64, 64, 128)); + + /* render "music player" */ + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(basic_font, c, 0, 0, 0, "Playing %s", stream_filename); + print_time(8, 24, pos); + al_draw_textf(basic_font, c, 100, 24, 0, "/"); + print_time(110, 24, length); + al_draw_filled_rectangle(10.0, 48.0 + 7.0, 10.0 + w, 48.0 + 9.0, al_map_rgb(0, 0, 0)); + al_draw_line(10.0 + loop_start_pos, 46.0, 10.0 + loop_start_pos, 66.0, al_map_rgb(0, 168, 128), 0); + al_draw_line(10.0 + loop_end_pos, 46.0, 10.0 + loop_end_pos, 66.0, al_map_rgb(255, 0, 0), 0); + al_draw_filled_rectangle(10.0 + slider_pos - 2.0, 48.0, 10.0 + slider_pos + 2.0, 64.0, + al_map_rgb(224, 224, 224)); + + /* show help */ + al_draw_textf(basic_font, c, 0, 96, 0, "Drag the slider to seek."); + al_draw_textf(basic_font, c, 0, 120, 0, "Middle-click to set loop start."); + al_draw_textf(basic_font, c, 0, 144, 0, "Right-click to set loop end."); + al_draw_textf(basic_font, c, 0, 168, 0, "Left/right arrows to seek."); + al_draw_textf(basic_font, c, 0, 192, 0, "Space to pause."); + + al_flip_display(); +} + +static void myexit(void) +{ + bool playing; + playing = al_get_audio_stream_playing(music_stream); + if (playing && music_stream) + al_drain_audio_stream(music_stream); + al_destroy_audio_stream(music_stream); +} + +static void maybe_fiddle_sliders(int mx, int my) +{ + double seek_pos; + double w = al_get_display_width(display) - 20; + + if (!(mx >= 10 && mx < 10 + w && my >= 48 && my < 64)) { + return; + } + + seek_pos = al_get_audio_stream_length_secs(music_stream) * ((mx - 10) / w); + if (mouse_button[1]) { + al_seek_audio_stream_secs(music_stream, seek_pos); + } + else if (mouse_button[2]) { + loop_end = seek_pos; + al_set_audio_stream_loop_secs(music_stream, loop_start, loop_end); + } + else if (mouse_button[3]) { + loop_start = seek_pos; + al_set_audio_stream_loop_secs(music_stream, loop_start, loop_end); + } +} + +static void event_handler(const ALLEGRO_EVENT * event) +{ + int i; + + switch (event->type) { + /* Was the X button on the window pressed? */ + case ALLEGRO_EVENT_DISPLAY_CLOSE: + exiting = true; + break; + + /* Was a key pressed? */ + case ALLEGRO_EVENT_KEY_CHAR: + if (event->keyboard.keycode == ALLEGRO_KEY_LEFT) { + double pos = al_get_audio_stream_position_secs(music_stream); + pos -= 5.0; + if (pos < 0.0) + pos = 0.0; + al_seek_audio_stream_secs(music_stream, pos); + } + else if (event->keyboard.keycode == ALLEGRO_KEY_RIGHT) { + double pos = al_get_audio_stream_position_secs(music_stream); + pos += 5.0; + if (!al_seek_audio_stream_secs(music_stream, pos)) + log_printf("seek error!\n"); + } + else if (event->keyboard.keycode == ALLEGRO_KEY_SPACE) { + bool playing; + playing = al_get_audio_stream_playing(music_stream); + playing = !playing; + al_set_audio_stream_playing(music_stream, playing); + } + else if (event->keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + exiting = true; + } + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + mouse_button[event->mouse.button] = 1; + maybe_fiddle_sliders(event->mouse.x, event->mouse.y); + break; + case ALLEGRO_EVENT_MOUSE_AXES: + maybe_fiddle_sliders(event->mouse.x, event->mouse.y); + break; + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + mouse_button[event->mouse.button] = 0; + break; + case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: + for (i = 0; i < 16; i++) + mouse_button[i] = 0; + break; + + /* Is it time for the next timer tick? */ + case ALLEGRO_EVENT_TIMER: + logic(); + render(); + break; + + case ALLEGRO_EVENT_AUDIO_STREAM_FINISHED: + log_printf("Stream finished.\n"); + break; + } +} + +int main(int argc, char *argv[]) +{ + ALLEGRO_CONFIG *config; + ALLEGRO_EVENT event; + unsigned buffer_count; + unsigned samples; + const char *s; + ALLEGRO_PLAYMODE playmode = ALLEGRO_PLAYMODE_LOOP; + + initialize(); + + if (argc > 1) { + stream_filename = argv[1]; + } + + buffer_count = 0; + samples = 0; + config = al_load_config_file("ex_stream_seek.cfg"); + if (config) { + if ((s = al_get_config_value(config, "", "buffer_count"))) { + buffer_count = atoi(s); + } + if ((s = al_get_config_value(config, "", "samples"))) { + samples = atoi(s); + } + if ((s = al_get_config_value(config, "", "playmode"))) { + if (!strcmp(s, "loop")) { + playmode = ALLEGRO_PLAYMODE_LOOP; + } + else if (!strcmp(s, "once")) { + playmode = ALLEGRO_PLAYMODE_ONCE; + } + } + al_destroy_config(config); + } + if (buffer_count == 0) { + buffer_count = 4; + } + if (samples == 0) { + samples = 1024; + } + + music_stream = al_load_audio_stream(stream_filename, buffer_count, samples); + if (!music_stream) { + abort_example("Stream error!\n"); + } + al_register_event_source(queue, al_get_audio_stream_event_source(music_stream)); + + loop_start = 0.0; + loop_end = al_get_audio_stream_length_secs(music_stream); + al_set_audio_stream_loop_secs(music_stream, loop_start, loop_end); + + al_set_audio_stream_playmode(music_stream, playmode); + al_attach_audio_stream_to_mixer(music_stream, al_get_default_mixer()); + al_start_timer(timer); + + while (!exiting) { + al_wait_for_event(queue, &event); + event_handler(&event); + } + + myexit(); + al_destroy_display(display); + close_log(true); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_subbitmap.c b/allegro/examples/ex_subbitmap.c new file mode 100644 index 00000000..60d3ba31 --- /dev/null +++ b/allegro/examples/ex_subbitmap.c @@ -0,0 +1,316 @@ +/* + * Example program for the Allegro library. + * + * This program blitting to/from sub-bitmaps. + * + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include + +#include "common.c" + +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) +#define CLAMP(x,y,z) MAX((x), MIN((y), (z))) + +typedef enum { + PLAIN_BLIT, + SCALED_BLIT +} Mode; + +enum { + SRC_WIDTH = 640, + SRC_HEIGHT = 480, + SRC_X = 160, + SRC_Y = 120, + DST_WIDTH = 640, + DST_HEIGHT = 480 +}; + + +ALLEGRO_DISPLAY *src_display; +ALLEGRO_DISPLAY *dst_display; +ALLEGRO_EVENT_QUEUE *queue; +ALLEGRO_BITMAP *src_bmp; + +int src_x1 = SRC_X; +int src_y1 = SRC_Y; +int src_x2 = SRC_X + 319; +int src_y2 = SRC_Y + 199; +int dst_x1 = 0; +int dst_y1 = 0; +int dst_x2 = DST_WIDTH-1; +int dst_y2 = DST_HEIGHT-1; + +Mode mode = PLAIN_BLIT; +int draw_flags = 0; + +int main(int argc, char **argv) +{ + ALLEGRO_BITMAP *src_subbmp[2] = {NULL, NULL}; + ALLEGRO_BITMAP *dst_subbmp[2] = {NULL, NULL}; + ALLEGRO_EVENT event; + bool mouse_down; + bool recreate_subbitmaps; + bool redraw; + bool use_memory; + const char *image_filename = NULL; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_primitives_addon(); + al_init_image_addon(); + init_platform_specific(); + + open_log(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + src_display = al_create_display(SRC_WIDTH, SRC_HEIGHT); + if (!src_display) { + abort_example("Error creating display\n"); + } + al_set_window_title(src_display, "Source"); + + dst_display = al_create_display(DST_WIDTH, DST_HEIGHT); + if (!dst_display) { + abort_example("Error creating display\n"); + } + al_set_window_title(dst_display, "Destination"); + + { + int i; + for (i = 1; i < argc; ++i) { + if (!image_filename) + image_filename = argv[i]; + else + abort_example("Unknown argument: %s\n", argv[i]); + } + + if (!image_filename) { + image_filename = "data/mysha.pcx"; + } + } + + src_bmp = al_load_bitmap(image_filename); + if (!src_bmp) { + abort_example("Could not load image file\n"); + } + + src_x2 = src_x1 + al_get_bitmap_width(src_bmp); + src_y2 = src_y1 + al_get_bitmap_height(src_bmp); + + al_install_keyboard(); + al_install_mouse(); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_display_event_source(src_display)); + al_register_event_source(queue, al_get_display_event_source(dst_display)); + + mouse_down = false; + recreate_subbitmaps = true; + redraw = true; + use_memory = false; + + log_printf("Highlight sub-bitmap regions with left mouse button.\n"); + log_printf("Press 'm' to toggle memory bitmaps.\n"); + log_printf("Press '1' to perform plain blits.\n"); + log_printf("Press 's' to perform scaled blits.\n"); + log_printf("Press 'h' to flip horizontally.\n"); + log_printf("Press 'v' to flip vertically.\n"); + + while (true) { + if (recreate_subbitmaps) { + int l, r, t, b, sw, sh; + + al_destroy_bitmap(src_subbmp[0]); + al_destroy_bitmap(dst_subbmp[0]); + al_destroy_bitmap(src_subbmp[1]); + al_destroy_bitmap(dst_subbmp[1]); + + l = MIN(src_x1, src_x2); + r = MAX(src_x1, src_x2); + t = MIN(src_y1, src_y2); + b = MAX(src_y1, src_y2); + + l -= SRC_X; + t -= SRC_Y; + r -= SRC_X; + b -= SRC_Y; + + src_subbmp[0] = al_create_sub_bitmap(src_bmp, l, t, r - l + 1, + b - t + 1); + sw = al_get_bitmap_width(src_subbmp[0]); + sh = al_get_bitmap_height(src_subbmp[0]); + src_subbmp[1] = al_create_sub_bitmap(src_subbmp[0], 2, 2, + sw - 4, sh - 4); + + l = MIN(dst_x1, dst_x2); + r = MAX(dst_x1, dst_x2); + t = MIN(dst_y1, dst_y2); + b = MAX(dst_y1, dst_y2); + + al_set_target_backbuffer(dst_display); + dst_subbmp[0] = al_create_sub_bitmap(al_get_backbuffer(dst_display), + l, t, r - l + 1, b - t + 1); + dst_subbmp[1] = al_create_sub_bitmap(dst_subbmp[0], + 2, 2, r - l - 3, b - t - 3); + + recreate_subbitmaps = false; + } + + if (redraw && al_is_event_queue_empty(queue)) { + al_set_target_backbuffer(dst_display); + al_clear_to_color(al_map_rgb(0, 0, 0)); + + al_set_target_bitmap(dst_subbmp[1]); + switch (mode) { + case PLAIN_BLIT: + { + al_draw_bitmap(src_subbmp[1], 0, 0, draw_flags); + break; + } + case SCALED_BLIT: + { + al_draw_scaled_bitmap(src_subbmp[1], + 0, 0, al_get_bitmap_width(src_subbmp[1]), + al_get_bitmap_height(src_subbmp[1]), + 0, 0, al_get_bitmap_width(dst_subbmp[1]), + al_get_bitmap_height(dst_subbmp[1]), + draw_flags); + break; + } + } + + #define SWAP_GREATER(f1, f2) { \ + if (f1 > f2) { \ + float tmp = f1; \ + f1 = f2; \ + f2 = tmp; \ + } \ + } + + { + /* pixel center is at 0.5/0.5 */ + float x = dst_x1 + 0.5; + float y = dst_y1 + 0.5; + float x_ = dst_x2 + 0.5; + float y_ = dst_y2 + 0.5; + SWAP_GREATER(x, x_) + SWAP_GREATER(y, y_) + al_set_target_backbuffer(dst_display); + al_draw_rectangle(x, y, x_, y_, + al_map_rgb(0, 255, 255), 0); + al_draw_rectangle(x + 2, y + 2, x_ - 2, y_ - 2, + al_map_rgb(255, 255, 0), 0); + al_flip_display(); + } + + { + /* pixel center is at 0.5/0.5 */ + float x = src_x1 + 0.5; + float y = src_y1 + 0.5; + float x_ = src_x2 + 0.5; + float y_ = src_y2 + 0.5; + SWAP_GREATER(x, x_) + SWAP_GREATER(y, y_) + al_set_target_backbuffer(src_display); + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_draw_bitmap(src_bmp, SRC_X, SRC_Y, 0); + al_draw_rectangle(x, y, x_, y_, + al_map_rgb(0, 255, 255), 0); + al_draw_rectangle(x + 2, y + 2, x_ - 2, y_ - 2, + al_map_rgb(255, 255, 0), 0); + al_flip_display(); + } + + #undef SWAP_GREATER + + redraw = false; + } + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + if (event.type == ALLEGRO_EVENT_KEY_CHAR) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + if (event.keyboard.unichar == '1') { + mode = PLAIN_BLIT; + redraw = true; + } + else if (event.keyboard.unichar == 's') { + mode = SCALED_BLIT; + redraw = true; + } + else if (event.keyboard.unichar == 'h') { + draw_flags ^= ALLEGRO_FLIP_HORIZONTAL; + redraw = true; + } + else if (event.keyboard.unichar == 'v') { + draw_flags ^= ALLEGRO_FLIP_VERTICAL; + redraw = true; + } + else if (event.keyboard.unichar == 'm') { + ALLEGRO_BITMAP *temp = src_bmp; + use_memory = !use_memory; + log_printf("Using a %s bitmap.\n", use_memory ? "memory" : "video"); + al_set_new_bitmap_flags(use_memory ? + ALLEGRO_MEMORY_BITMAP : ALLEGRO_VIDEO_BITMAP); + src_bmp = al_clone_bitmap(temp); + al_destroy_bitmap(temp); + redraw = true; + recreate_subbitmaps = true; + } + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN && + event.mouse.button == 1) { + if (event.mouse.display == src_display) { + src_x1 = src_x2 = event.mouse.x; + src_y1 = src_y2 = event.mouse.y; + } + else if (event.mouse.display == dst_display) { + dst_x1 = dst_x2 = event.mouse.x; + dst_y1 = dst_y2 = event.mouse.y; + } + mouse_down = true; + redraw = true; + } + else if (event.type == ALLEGRO_EVENT_MOUSE_AXES) { + if (mouse_down) { + if (event.mouse.display == src_display) { + src_x2 = event.mouse.x; + src_y2 = event.mouse.y; + } + else if (event.mouse.display == dst_display) { + dst_x2 = event.mouse.x; + dst_y2 = event.mouse.y; + } + redraw = true; + } + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP && + event.mouse.button == 1) { + mouse_down = false; + recreate_subbitmaps = true; + redraw = true; + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { + redraw = true; + } + } + + al_destroy_event_queue(queue); + + close_log(false); + return 0; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_synth.cpp b/allegro/examples/ex_synth.cpp new file mode 100644 index 00000000..3ada24d4 --- /dev/null +++ b/allegro/examples/ex_synth.cpp @@ -0,0 +1,525 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * Something like the start of a synthesizer. + */ + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_audio.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_primitives.h" +#include "allegro5/allegro_ttf.h" +#include "nihgui.hpp" + +#include "common.c" + +#define PI (ALLEGRO_PI) +#define TWOPI (2.0 * PI) +#define SAMPLES_PER_BUFFER (1024) +#define STREAM_FREQUENCY (44100) + +const double dt = 1.0 / STREAM_FREQUENCY; + + +enum Waveform { + WAVEFORM_NONE, + WAVEFORM_SINE, + WAVEFORM_SQUARE, + WAVEFORM_TRIANGLE, + WAVEFORM_SAWTOOTH +}; + + +/* forward declarations */ +static void generate_wave(Waveform type, float *buf, size_t samples, double t, + float frequency, float phase); +static void sine(float *buf, size_t samples, double t, + float frequency, float phase); +static void square(float *buf, size_t samples, double t, + float frequency, float phase); +static void triangle(float *buf, size_t samples, double t, + float frequency, float phase); +static void sawtooth(float *buf, size_t samples, double t, + float frequency, float phase); + + +/* globals */ +ALLEGRO_FONT *font_gui; +ALLEGRO_AUDIO_STREAM *stream1; +ALLEGRO_AUDIO_STREAM *stream2; +ALLEGRO_AUDIO_STREAM *stream3; +ALLEGRO_AUDIO_STREAM *stream4; +ALLEGRO_AUDIO_STREAM *stream5; + +bool saving = false; +ALLEGRO_FILE *save_fp = NULL; + + +static void generate_wave(Waveform type, float *buf, size_t samples, double t, + float frequency, float phase) +{ + switch (type) { + case WAVEFORM_NONE: + for (unsigned i = 0; i < samples; i++) { + buf[i] = 0.0; + } + break; + case WAVEFORM_SINE: + sine(buf, samples, t, frequency, phase); + break; + case WAVEFORM_SQUARE: + square(buf, samples, t, frequency, phase); + break; + case WAVEFORM_TRIANGLE: + triangle(buf, samples, t, frequency, phase); + break; + case WAVEFORM_SAWTOOTH: + sawtooth(buf, samples, t, frequency, phase); + break; + } +} + + +static void sine(float *buf, size_t samples, double t, + float frequency, float phase) +{ + const double w = TWOPI * frequency; + unsigned i; + + for (i = 0; i < samples; i++) { + double ti = t + i * dt; + buf[i] = sin(w * ti + phase); + } +} + + +static void square(float *buf, size_t samples, double t, + float frequency, float phase) +{ + const double w = TWOPI * frequency; + unsigned i; + + for (i = 0; i < samples; i++) { + double ti = t + i * dt; + double x = sin(w * ti + phase); + + buf[i] = (x >= 0.0) ? 1.0 : -1.0; + } +} + + +static void triangle(float *buf, size_t samples, double t, + float frequency, float phase) +{ + const double w = TWOPI * frequency; + unsigned i; + + for (i = 0; i < samples; i++) { + double tx = w * (t + i * dt) + PI/2.0 + phase; + double tu = fmod(tx/PI, 2.0); + + if (tu <= 1.0) + buf[i] = (1.0 - 2.0 * tu); + else + buf[i] = (-1.0 + 2.0 * (tu - 1.0)); + } +} + + +static void sawtooth(float *buf, size_t samples, double t, + float frequency, float phase) +{ + const double w = TWOPI * frequency; + unsigned i; + + for (i = 0; i < samples; i++) { + double tx = w * (t + i * dt) + PI + phase; + double tu = fmod(tx/PI, 2.0); + + buf[i] = (-1.0 + tu); + } +} + + +static void mixer_pp_callback(void *buf, unsigned int samples, void *userdata) +{ + ALLEGRO_MIXER *mixer = (ALLEGRO_MIXER *)userdata; + int nch; + int sample_size; + + if (!saving) + return; + + switch (al_get_mixer_channels(mixer)) { + case ALLEGRO_CHANNEL_CONF_1: + nch = 1; + break; + case ALLEGRO_CHANNEL_CONF_2: + nch = 2; + break; + default: + /* Not supported. */ + return; + } + + sample_size = al_get_audio_depth_size(al_get_mixer_depth(mixer)); + al_fwrite(save_fp, buf, nch * samples * sample_size); +} + + +class Group { +private: + List list; + Label freq_label; + HSlider freq_slider; + Label freq_val_label; + Label phase_label; + HSlider phase_slider; + Label phase_val_label; + Label gain_label; + HSlider gain_slider; + Label pan_label; + HSlider pan_slider; + double t; + float last_gain; + float last_pan; + +public: + Group(); + void add_to_dialog(Dialog & d, int x, int y); + void update_labels(); + void generate(float *buf, size_t samples); + bool get_gain_if_changed(float *gain); + bool get_pan_if_changed(float *pan); + +private: + float get_frequency() const; + float get_phase() const; +}; + + +Group::Group() : + freq_label(Label("f")), + freq_slider(220, 1000), + phase_label(Label("φ")), + phase_slider((int)(100 * PI), (int)(2 * 100 * PI)), /* -π .. π */ + gain_label(Label("Gain")), + gain_slider(33, 100), /* 0.0 .. 1.0 */ + pan_label(Label("Pan")), + pan_slider(100, 200), /* -1.0 .. 1.0 */ + t(0.0), + last_gain(-10000), + last_pan(-10000) +{ + /* Order must correspond with Waveform. */ + list.append_item("Off"); + list.append_item("Sine"); + list.append_item("Square"); + list.append_item("Triangle"); + list.append_item("Sawtooth"); +} + + +void Group::add_to_dialog(Dialog & d, int x, int y) +{ + d.add(list, x, y, 4, 4); + + d.add(freq_label, x+4, y, 2, 1); + d.add(freq_slider, x+6, y, 20, 1); + d.add(freq_val_label, x+26, y, 4, 1); + + d.add(phase_label, x+4, y+1, 2, 1); + d.add(phase_slider, x+6, y+1, 20, 1); + d.add(phase_val_label, x+26, y+1, 4, 1); + + d.add(gain_label, x+4, y+2, 2, 1); + d.add(gain_slider, x+6, y+2, 20, 1); + + d.add(pan_label, x+4, y+3, 2, 1); + d.add(pan_slider, x+6, y+3, 20, 1); +} + + +void Group::update_labels() +{ + char buf[32]; + float frequency = get_frequency(); + float phase = get_phase(); + + sprintf(buf, "%4.0f Hz", frequency); + freq_val_label.set_text(buf); + + sprintf(buf, "%.2f π", phase/PI); + phase_val_label.set_text(buf); +} + + +void Group::generate(float *buf, size_t samples) +{ + Waveform type = (Waveform) list.get_cur_value(); + float frequency = get_frequency(); + float phase = get_phase(); + + generate_wave(type, buf, samples, t, frequency, phase); + + t += dt * samples; +} + + +float Group::get_frequency() const +{ + return freq_slider.get_cur_value(); +} + + +float Group::get_phase() const +{ + return phase_slider.get_cur_value() / 100.0 - PI; +} + + +bool Group::get_gain_if_changed(float *gain) +{ + *gain = gain_slider.get_cur_value() / 100.0; + bool changed = (last_gain != *gain); + last_gain = *gain; + return changed; +} + + +bool Group::get_pan_if_changed(float *pan) +{ + *pan = pan_slider.get_cur_value() / 100.0 - 1.0; + bool changed = (last_pan != *pan); + last_pan = *pan; + return changed; +} + + +class SaveButton : public ToggleButton { +public: + SaveButton() : ToggleButton("Save raw") {} + void on_click(int mx, int my); +}; + + +void SaveButton::on_click(int, int) +{ + if (saving) { + log_printf("Stopped saving waveform.\n"); + saving = false; + return; + } + if (!save_fp) { + save_fp = al_fopen("ex_synth.raw", "wb"); + } + if (save_fp) { + log_printf("Started saving waveform.\n"); + saving = true; + } +} + + +class Prog : public EventHandler { +private: + Dialog d; + Group group1; + Group group2; + Group group3; + Group group4; + Group group5; + SaveButton save_button; + +public: + Prog(const Theme & theme, ALLEGRO_DISPLAY *display); + virtual ~Prog() {} + void run(); + void handle_event(const ALLEGRO_EVENT & event); +}; + + +Prog::Prog(const Theme & theme, ALLEGRO_DISPLAY *display) : + d(Dialog(theme, display, 30, 26)), + save_button(SaveButton()) +{ + group1.add_to_dialog(d, 1, 1); + group2.add_to_dialog(d, 1, 6); + group3.add_to_dialog(d, 1, 11); + group4.add_to_dialog(d, 1, 16); + group5.add_to_dialog(d, 1, 21); + d.add(save_button, 27, 25, 3, 1); +} + + +void Prog::run() +{ + d.prepare(); + + d.register_event_source(al_get_audio_stream_event_source(stream1)); + d.register_event_source(al_get_audio_stream_event_source(stream2)); + d.register_event_source(al_get_audio_stream_event_source(stream3)); + d.register_event_source(al_get_audio_stream_event_source(stream4)); + d.register_event_source(al_get_audio_stream_event_source(stream5)); + d.set_event_handler(this); + + while (!d.is_quit_requested()) { + if (d.is_draw_requested()) { + group1.update_labels(); + group2.update_labels(); + group3.update_labels(); + group4.update_labels(); + group5.update_labels(); + + al_clear_to_color(al_map_rgb(128, 128, 128)); + d.draw(); + al_flip_display(); + } + + d.run_step(true); + } +} + + +void Prog::handle_event(const ALLEGRO_EVENT & event) +{ + if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { + ALLEGRO_AUDIO_STREAM *stream; + Group *group; + void *buf; + float gain; + float pan; + + stream = (ALLEGRO_AUDIO_STREAM *) event.any.source; + buf = al_get_audio_stream_fragment(stream); + if (!buf) { + /* This is a normal condition that you must deal with. */ + return; + } + + if (stream == stream1) + group = &group1; + else if (stream == stream2) + group = &group2; + else if (stream == stream3) + group = &group3; + else if (stream == stream4) + group = &group4; + else if (stream == stream5) + group = &group5; + else + group = NULL; + + ALLEGRO_ASSERT(group); + + if (group) { + group->generate((float *) buf, SAMPLES_PER_BUFFER); + if (group->get_gain_if_changed(&gain)) { + al_set_audio_stream_gain(stream, gain); + } + if (group->get_pan_if_changed(&pan)) { + al_set_audio_stream_pan(stream, pan); + } + } + + if (!al_set_audio_stream_fragment(stream, buf)) { + log_printf("Error setting stream fragment.\n"); + } + } +} + + +int main(int argc, char *argv[]) +{ + ALLEGRO_DISPLAY *display; + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + al_install_keyboard(); + al_install_mouse(); + + al_init_primitives_addon(); + al_init_font_addon(); + al_init_ttf_addon(); + init_platform_specific(); + + al_set_new_display_flags(ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(800, 600); + if (!display) { + abort_example("Unable to create display\n"); + } + al_set_window_title(display, "Synthesiser of sorts"); + + font_gui = al_load_ttf_font("data/DejaVuSans.ttf", 12, 0); + if (!font_gui) { + abort_example("Failed to load font\n"); + } + + if (!al_install_audio()) { + abort_example("Could not init sound!\n"); + } + + if (!al_reserve_samples(0)) { + abort_example("Could not set up voice and mixer.\n"); + } + + size_t buffers = 8; + unsigned samples = SAMPLES_PER_BUFFER; + unsigned freq = STREAM_FREQUENCY; + ALLEGRO_AUDIO_DEPTH depth = ALLEGRO_AUDIO_DEPTH_FLOAT32; + ALLEGRO_CHANNEL_CONF ch = ALLEGRO_CHANNEL_CONF_1; + + stream1 = al_create_audio_stream(buffers, samples, freq, depth, ch); + stream2 = al_create_audio_stream(buffers, samples, freq, depth, ch); + stream3 = al_create_audio_stream(buffers, samples, freq, depth, ch); + stream4 = al_create_audio_stream(buffers, samples, freq, depth, ch); + stream5 = al_create_audio_stream(buffers, samples, freq, depth, ch); + if (!stream1 || !stream2 || !stream3 || !stream4 || !stream5) { + abort_example("Could not create stream.\n"); + } + + ALLEGRO_MIXER *mixer = al_get_default_mixer(); + if ( + !al_attach_audio_stream_to_mixer(stream1, mixer) || + !al_attach_audio_stream_to_mixer(stream2, mixer) || + !al_attach_audio_stream_to_mixer(stream3, mixer) || + !al_attach_audio_stream_to_mixer(stream4, mixer) || + !al_attach_audio_stream_to_mixer(stream5, mixer) + ) { + abort_example("Could not attach stream to mixer.\n"); + } + + al_set_mixer_postprocess_callback(mixer, mixer_pp_callback, mixer); + + /* Prog is destroyed at the end of this scope. */ + { + Theme theme(font_gui); + Prog prog(theme, display); + prog.run(); + } + + al_destroy_audio_stream(stream1); + al_destroy_audio_stream(stream2); + al_destroy_audio_stream(stream3); + al_destroy_audio_stream(stream4); + al_destroy_audio_stream(stream5); + al_uninstall_audio(); + + al_destroy_font(font_gui); + + al_fclose(save_fp); + + close_log(false); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_threads.c b/allegro/examples/ex_threads.c new file mode 100644 index 00000000..ef60b8d3 --- /dev/null +++ b/allegro/examples/ex_threads.c @@ -0,0 +1,248 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * In this example, each thread handles its own window and event queue. + */ + +#include +#include +#include + +#include "common.c" + +#define MAX_THREADS 100 +#define MAX_BACKGROUNDS 10 +#define MAX_SQUARES 25 + +typedef struct Background { + double rmax; + double gmax; + double bmax; +} Background; + + +typedef struct Square { + float cx, cy; + float dx, dy; + float size, dsize; + float rot, drot; + float life, dlife; +} Square; + + +static float rand01(void) +{ + return (rand() % 10000) / 10000.0; +} + + +static float rand11(void) +{ + return (-10000 + (rand() % 20000)) / 20000.0; +} + + +static void gen_square(Square *sq, int w, int h) +{ + sq->cx = rand() % w; + sq->cy = rand() % h; + sq->dx = 3.0 * rand11(); + sq->dy = 3.0 * rand11(); + sq->size = 10 + (rand() % 10); + sq->dsize = rand11(); + sq->rot = ALLEGRO_PI * rand01(); + sq->drot = rand11() / 3.0; + sq->life = 0.0; + sq->dlife = (ALLEGRO_PI / 100.0) + (ALLEGRO_PI / 30.0) * rand01(); +} + + +static void animate_square(Square *sq) +{ + sq->cx += sq->dx; + sq->cy += sq->dy; + sq->size += sq->dsize; + sq->rot += sq->drot; + sq->life += sq->dlife; + + if (sq->size < 1.0 || sq->life > ALLEGRO_PI) { + ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); + gen_square(sq, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp)); + } +} + + +static void draw_square(Square *sq) +{ + ALLEGRO_TRANSFORM trans; + float alpha; + float size; + ALLEGRO_COLOR tint; + + al_build_transform(&trans, sq->cx, sq->cy, 1.0, 1.0, sq->rot); + al_use_transform(&trans); + + alpha = sin(sq->life); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE); + tint = al_map_rgba_f(0.5, 0.3, 0, alpha); + + size = sq->size; + al_draw_filled_rounded_rectangle(-size, -size, size, size, 3, 3, tint); + + size *= 1.1; + al_draw_rounded_rectangle(-size, -size, size, size, 3, 3, tint, 2); +} + + +static void *thread_func(ALLEGRO_THREAD *thr, void *arg) +{ + const int INITIAL_WIDTH = 300; + const int INITIAL_HEIGHT = 300; + const Background *background = (Background *) arg; + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *queue = NULL; + ALLEGRO_TIMER *timer = NULL; + ALLEGRO_EVENT event; + ALLEGRO_STATE state; + Square squares[MAX_SQUARES]; + double theta = 0.0; + bool redraw = true; + int i; + + (void)thr; + + al_set_new_display_flags(ALLEGRO_RESIZABLE); + + display = al_create_display(INITIAL_WIDTH, INITIAL_HEIGHT); + if (!display) { + goto Quit; + } + queue = al_create_event_queue(); + if (!queue) { + goto Quit; + } + timer = al_create_timer(0.1); + if (!timer) { + goto Quit; + } + + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + for (i = 0; i < MAX_SQUARES; i++) { + gen_square(&squares[i], INITIAL_WIDTH, INITIAL_HEIGHT); + } + + al_start_timer(timer); + + while (true) { + if (al_is_event_queue_empty(queue) && redraw) { + double r = 0.7 + 0.3 * (sin(theta) + 1.0) / 2.0; + ALLEGRO_COLOR c = al_map_rgb_f( + background->rmax * r, + background->gmax * r, + background->bmax * r + ); + al_clear_to_color(c); + + al_store_state(&state, ALLEGRO_STATE_BLENDER | ALLEGRO_STATE_TRANSFORM); + for (i = 0; i < MAX_SQUARES; i++) { + draw_square(&squares[i]); + } + al_restore_state(&state); + + al_flip_display(); + redraw = false; + } + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_TIMER) { + for (i = 0; i < MAX_SQUARES; i++) { + animate_square(&squares[i]); + } + theta += 0.1; + redraw = true; + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + else if (event.type == ALLEGRO_EVENT_KEY_DOWN + && event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { + al_acknowledge_resize(event.display.source); + } + } + +Quit: + + if (timer) { + al_destroy_timer(timer); + } + if (queue) { + al_destroy_event_queue(queue); + } + if (display) { + al_destroy_display(display); + } + + return NULL; +} + + +int main(int argc, char **argv) +{ + ALLEGRO_THREAD *thread[MAX_THREADS]; + Background background[MAX_BACKGROUNDS] = { + { 1.0, 0.5, 0.5 }, + { 0.5, 1.0, 0.5 }, + { 0.5, 0.5, 1.0 }, + { 1.0, 1.0, 0.5 }, + { 0.5, 1.0, 1.0 }, + { 1.0, 0.7, 0.5 }, + { 0.5, 1.0, 0.7 }, + { 0.7, 0.5, 1.0 }, + { 1.0, 0.7, 0.5 }, + { 0.5, 0.7, 1.0 } + }; + int num_threads; + int i; + + if (argc > 1) { + num_threads = strtol(argv[1], NULL, 10); + if (num_threads > MAX_THREADS) + num_threads = MAX_THREADS; + else if (num_threads < 1) + num_threads = 1; + } + else { + num_threads = 3; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + + for (i = 0; i < num_threads; i++) { + thread[i] = al_create_thread(thread_func, + &background[i % MAX_BACKGROUNDS]); + } + for (i = 0; i < num_threads; i++) { + al_start_thread(thread[i]); + } + for (i = 0; i < num_threads; i++) { + al_join_thread(thread[i], NULL); + al_destroy_thread(thread[i]); + } + + return 0; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_threads2.c b/allegro/examples/ex_threads2.c new file mode 100644 index 00000000..4fbd7857 --- /dev/null +++ b/allegro/examples/ex_threads2.c @@ -0,0 +1,398 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * In this example, threads render to their own memory buffers, while the + * main thread handles events and drawing (copying from the memory buffers + * to the display). + * + * Click on an image to pause its thread. + */ + +#include +#include + +#include "common.c" + +/* feel free to bump these up */ +#define NUM_THREADS 9 +#define IMAGES_PER_ROW 3 + +/* size of each fractal image */ +#define W 120 +#define H 120 + + +typedef struct ThreadInfo { + ALLEGRO_BITMAP *bitmap; + ALLEGRO_MUTEX *mutex; + ALLEGRO_COND *cond; + bool is_paused; + int random_seed; + double target_x, target_y; +} ThreadInfo; + +typedef struct Viewport { + double centre_x; + double centre_y; + double x_extent; + double y_extent; + double zoom; +} Viewport; + +static ThreadInfo thread_info[NUM_THREADS]; + +unsigned char sin_lut[256]; + + +static double cabs2(double re, double im) +{ + return re*re + im*im; +} + + +static int mandel(double cre, double cim, int MAX_ITER) +{ + const float Z_MAX2 = 4.0; + double zre = cre, zim = cim; + int iter; + + for (iter = 0; iter < MAX_ITER; iter++) { + double z1re, z1im; + z1re = zre * zre - zim * zim; + z1im = 2 * zre * zim; + z1re += cre; + z1im += cim; + if (cabs2(z1re, z1im) > Z_MAX2) { + return iter + 1; /* outside set */ + } + zre = z1re; + zim = z1im; + } + + return 0; /* inside set */ +} + + +/* local_rand: + * Simple rand() replacement with guaranteed randomness in the lower 16 bits. + * We just need a RNG with a thread-safe interface. + */ +static int local_rand(int *seed) +{ + const int LOCAL_RAND_MAX = 0xFFFF; + + *seed = (*seed + 1) * 1103515245 + 12345; + return ((*seed >> 16) & LOCAL_RAND_MAX); +} + + +static void random_palette(unsigned char palette[256][3], int *seed) +{ + unsigned char rmax = 128 + local_rand(seed) % 128; + unsigned char gmax = 128 + local_rand(seed) % 128; + unsigned char bmax = 128 + local_rand(seed) % 128; + int i; + + for (i = 0; i < 256; i++) { + palette[i][0] = rmax * i / 256; + palette[i][1] = gmax * i / 256; + palette[i][2] = bmax * i / 256; + } +} + + +static void draw_mandel_line(ALLEGRO_BITMAP *bitmap, const Viewport *viewport, + unsigned char palette[256][3], const int y) +{ + ALLEGRO_LOCKED_REGION *lr; + unsigned char *rgb; + double xlower, ylower; + double xscale, yscale; + double im; + double re; + int w, h; + int x; + int n = 512 / pow(2, viewport->zoom); + + w = al_get_bitmap_width(bitmap); + h = al_get_bitmap_height(bitmap); + + if (!(lr = al_lock_bitmap_region(bitmap, 0, y, w, 1, ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, + ALLEGRO_LOCK_WRITEONLY))) { + abort_example("draw_mandel_line: al_lock_bitmap_region failed\n"); + } + + xlower = viewport->centre_x - viewport->x_extent / 2.0 * viewport->zoom; + ylower = viewport->centre_y - viewport->y_extent / 2.0 * viewport->zoom; + xscale = viewport->x_extent / w * viewport->zoom; + yscale = viewport->y_extent / h * viewport->zoom; + + re = xlower; + im = ylower + y * yscale; + rgb = lr->data; + + for (x = 0; x < w; x++) { + int i = mandel(re, im, n); + int v = sin_lut[(int)(i * 64 / n)]; + + rgb[0] = palette[v][0]; + rgb[1] = palette[v][1]; + rgb[2] = palette[v][2]; + rgb += 3; + + re += xscale; + } + + al_unlock_bitmap(bitmap); +} + + +static void *thread_func(ALLEGRO_THREAD *thr, void *arg) +{ + ThreadInfo *info = (ThreadInfo *) arg; + Viewport viewport; + unsigned char palette[256][3]; + int y, h; + + y = 0; + h = al_get_bitmap_height(info->bitmap); + + viewport.centre_x = info->target_x; + viewport.centre_y = info->target_y; + viewport.x_extent = 3.0; + viewport.y_extent = 3.0; + viewport.zoom = 1.0; + info->target_x = 0; + info->target_y = 0; + + while (!al_get_thread_should_stop(thr)) { + al_lock_mutex(info->mutex); + + while (info->is_paused) { + al_wait_cond(info->cond, info->mutex); + + /* We might be awoken because the program is terminating. */ + if (al_get_thread_should_stop(thr)) { + break; + } + } + + if (!info->is_paused) { + if (y == 0) { + random_palette(palette, &info->random_seed); + } + + draw_mandel_line(info->bitmap, &viewport, palette, y); + + y++; + if (y >= h) { + double z = viewport.zoom; + y = 0; + viewport.centre_x += z * viewport.x_extent * info->target_x; + viewport.centre_y += z * viewport.y_extent * info->target_y; + info->target_x = 0; + info->target_y = 0; + viewport.zoom *= 0.99; + } + } + + al_unlock_mutex(info->mutex); + al_rest(0); + } + + return NULL; +} + + +static void show_images(void) +{ + int x = 0; + int y = 0; + int i; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + for (i = 0; i < NUM_THREADS; i++) { + /* for lots of threads, this is not good enough */ + al_lock_mutex(thread_info[i].mutex); + al_draw_bitmap(thread_info[i].bitmap, x * W, y * H, 0); + al_unlock_mutex(thread_info[i].mutex); + + x++; + if (x == IMAGES_PER_ROW) { + x = 0; + y++; + } + } + al_flip_display(); +} + + +static void set_target(int n, double x, double y) +{ + thread_info[n].target_x = x; + thread_info[n].target_y = y; +} + + +static void toggle_pausedness(int n) +{ + ThreadInfo *info = &thread_info[n]; + + al_lock_mutex(info->mutex); + info->is_paused = !info->is_paused; + al_broadcast_cond(info->cond); + al_unlock_mutex(info->mutex); +} + + +int main(int argc, char **argv) +{ + ALLEGRO_THREAD *thread[NUM_THREADS]; + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + bool need_draw; + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < 256; i++) { + sin_lut[i] = 128 + (int) (127.0 * sin(i / 8.0)); + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + al_install_mouse(); + display = al_create_display(W * IMAGES_PER_ROW, + H * NUM_THREADS / IMAGES_PER_ROW); + if (!display) { + abort_example("Error creating display\n"); + } + timer = al_create_timer(1.0/3); + if (!timer) { + abort_example("Error creating timer\n"); + } + queue = al_create_event_queue(); + if (!queue) { + abort_example("Error creating event queue\n"); + } + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + /* Note: + * Right now, A5 video displays can only be accessed from the thread which + * created them (at least for OpenGL). To lift this restriction, we could + * keep track of the current OpenGL context for each thread and make all + * functions accessing the display check for it.. not sure it's worth the + * additional complexity though. + */ + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_888); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + for (i = 0; i < NUM_THREADS; i++) { + thread_info[i].bitmap = al_create_bitmap(W, H); + if (!thread_info[i].bitmap) { + goto Error; + } + thread_info[i].mutex = al_create_mutex(); + if (!thread_info[i].mutex) { + goto Error; + } + thread_info[i].cond = al_create_cond(); + if (!thread_info[i].cond) { + goto Error; + } + thread_info[i].is_paused = false; + thread_info[i].random_seed = i; + thread[i] = al_create_thread(thread_func, &thread_info[i]); + if (!thread[i]) { + goto Error; + } + } + set_target(0, -0.56062033041600878303, -0.56064322926933807256); + set_target(1, -0.57798076669230014080, -0.63449861991138123418); + set_target(2, 0.36676836392830602929, -0.59081385302214906030); + set_target(3, -1.48319283039401317303, -0.00000000200514696273); + set_target(4, -0.74052910500707636032, 0.18340899525730713915); + set_target(5, 0.25437906525768350097, -0.00046678223345789554); + set_target(6, -0.56062033041600878303, 0.56064322926933807256); + set_target(7, -0.57798076669230014080, 0.63449861991138123418); + set_target(8, 0.36676836392830602929, 0.59081385302214906030); + + for (i = 0; i < NUM_THREADS; i++) { + al_start_thread(thread[i]); + } + al_start_timer(timer); + + need_draw = true; + while (true) { + if (need_draw && al_is_event_queue_empty(queue)) { + show_images(); + need_draw = false; + } + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_TIMER) { + need_draw = true; + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + int n = (event.mouse.y / H) * IMAGES_PER_ROW + (event.mouse.x / W); + if (n < NUM_THREADS) { + double x = event.mouse.x - (event.mouse.x / W) * W; + double y = event.mouse.y - (event.mouse.y / H) * H; + /* Center to the mouse click position. */ + if (thread_info[n].is_paused) { + thread_info[n].target_x = x / W - 0.5; + thread_info[n].target_y = y / H - 0.5; + } + toggle_pausedness(n); + } + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { + need_draw = true; + } + else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + else if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + need_draw = true; + } + } + + for (i = 0; i < NUM_THREADS; i++) { + /* Set the flag to stop the thread. The thread might be waiting on a + * condition variable, so signal the condition to force it to wake up. + */ + al_set_thread_should_stop(thread[i]); + al_lock_mutex(thread_info[i].mutex); + al_broadcast_cond(thread_info[i].cond); + al_unlock_mutex(thread_info[i].mutex); + + /* al_destroy_thread() implicitly joins the thread, so this call is not + * strictly necessary. + */ + al_join_thread(thread[i], NULL); + al_destroy_thread(thread[i]); + } + + al_destroy_event_queue(queue); + al_destroy_timer(timer); + al_destroy_display(display); + + return 0; + +Error: + + return 1; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_timedwait.c b/allegro/examples/ex_timedwait.c new file mode 100644 index 00000000..2512ad71 --- /dev/null +++ b/allegro/examples/ex_timedwait.c @@ -0,0 +1,109 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * Test timed version of al_wait_for_event(). + */ + + +#include + +#include "common.c" + +static void test_relative_timeout(ALLEGRO_EVENT_QUEUE *queue); +static void test_absolute_timeout(ALLEGRO_EVENT_QUEUE *queue); + + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *dpy; + ALLEGRO_EVENT_QUEUE *queue; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + + dpy = al_create_display(640, 480); + if (!dpy) { + abort_example("Unable to set any graphic mode\n"); + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + + test_relative_timeout(queue); + test_absolute_timeout(queue); + + return 0; +} + + + +static void test_relative_timeout(ALLEGRO_EVENT_QUEUE *queue) +{ + ALLEGRO_EVENT event; + float shade = 0.1; + + while (true) { + if (al_wait_for_event_timed(queue, &event, 0.1)) { + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + return; + } + else { + shade = 0.1; + } + } + } + else { + /* timed out */ + shade += 0.1; + if (shade > 1.0) + shade = 1.0; + } + + al_clear_to_color(al_map_rgba_f(0.5 * shade, 0.25 * shade, shade, 0)); + al_flip_display(); + } +} + + + +static void test_absolute_timeout(ALLEGRO_EVENT_QUEUE *queue) +{ + ALLEGRO_TIMEOUT timeout; + ALLEGRO_EVENT event; + float shade = 0.1; + bool ret; + + while (true) { + al_init_timeout(&timeout, 0.1); + while ((ret = al_wait_for_event_until(queue, &event, &timeout))) { + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + return; + } else { + shade = 0.1; + } + } + } + + if (!ret) { + /* timed out */ + shade += 0.1; + if (shade > 1.0) + shade = 1.0; + } + + al_clear_to_color(al_map_rgba_f(shade, 0.5 * shade, 0.25 * shade, 0)); + al_flip_display(); + } +} + + +/* vi: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_timer.c b/allegro/examples/ex_timer.c new file mode 100644 index 00000000..e12ae2db --- /dev/null +++ b/allegro/examples/ex_timer.c @@ -0,0 +1,203 @@ +/* A test of timer events. Since both al_get_time() as well as the timer + * events may be the source of inaccuracy, it doesn't tell a lot. + */ +#include +#include +#include +#include +#include +#include + +#include "common.c" + +/* A structure holding all variables of our example program. */ +struct Example +{ + ALLEGRO_FONT *myfont; /* Our font. */ + ALLEGRO_EVENT_QUEUE *queue; /* Our events queue. */ + + double FPS; /* How often to update per second. */ + + int x[4]; + + bool first_tick; + double this_time, prev_time, accum_time; + double min_diff, max_diff, second_spread; + double second; + double timer_events; + double timer_error; + double timestamp; +} ex; + +/* Initialize the example. */ +static void init(void) +{ + ex.FPS = 50; + ex.first_tick = true; + + ex.myfont = al_create_builtin_font(); + if (!ex.myfont) { + abort_example("Error creating builtin font\n"); + } +} + +/* Cleanup. Always a good idea. */ +static void cleanup(void) +{ + al_destroy_font(ex.myfont); + ex.myfont = NULL; +} + +/* Print some text. */ +static void print(int x, int y, char const *format, ...) +{ + va_list list; + char message[1024]; + + va_start(list, format); + vsnprintf(message, sizeof message, format, list); + va_end(list); + + /* Actual text. */ + al_draw_text(ex.myfont, al_map_rgb_f(0, 0, 0), x, y, 0, message); +} + +/* Draw our example scene. */ +static void draw(void) +{ + int h, y, i; + double cur_time, event_overhead, total_error; + + cur_time = al_get_time(); + event_overhead = cur_time - ex.timestamp; + total_error = event_overhead + ex.timer_error; + + h = al_get_font_line_height(ex.myfont); + al_clear_to_color(al_map_rgb_f(1, 1, 1)); + + print(0, 0, "%.9f target for %.0f Hz Timer", 1.0 / ex.FPS, ex.FPS); + print(0, h, "%.9f now", ex.this_time - ex.prev_time); + print(0, 2 * h, "%.9f accum over one second", + ex.accum_time / ex.timer_events); + print(0, 3 * h, "%.9f min", ex.min_diff); + print(0, 4 * h, "%.9f max", ex.max_diff); + print(300, 3.5 * h, "%.9f (max - min)", ex.second_spread); + print(300, 4.5 * h, "%.9f (timer error)", ex.timer_error); + print(300, 5.5 * h ,"%.9f (event overhead)", event_overhead); + print(300, 6.5 * h, "%.9f (total error)" , total_error); + + y = 240; + for (i = 0; i < 4; i++) { + al_draw_filled_rectangle(ex.x[i], y + i * 60, ex.x[i] + (1 << i), + y + i * 60 + 60, al_map_rgb(1, 0, 0)); + } +} + +/* Called a fixed amount of times per second. */ +static void tick(ALLEGRO_TIMER_EVENT* timer_event) +{ + int i; + + ex.this_time = al_get_time(); + + if (ex.first_tick) { + ex.first_tick = false; + } + else { + double duration; + if (ex.this_time - ex.second >= 1) { + ex.second = ex.this_time; + ex.accum_time = 0; + ex.timer_events = 0; + ex.second_spread = ex.max_diff - ex.min_diff; + ex.max_diff = 0; + ex.min_diff = 1; + } + duration = ex.this_time - ex.prev_time; + if (duration < ex.min_diff) + ex.min_diff = duration; + if (duration > ex.max_diff) + ex.max_diff = duration; + ex.accum_time += duration; + ex.timer_events++; + ex.timer_error = timer_event->error; + ex.timestamp = timer_event->timestamp; + } + + draw(); + al_flip_display(); + + for (i = 0; i < 4; i++) { + ex.x[i] += 1 << i; + ex.x[i] %= 640; + } + + ex.prev_time = ex.this_time; +} + +/* Run our test. */ +static void run(void) +{ + ALLEGRO_EVENT event; + while (1) { + al_wait_for_event(ex.queue, &event); + switch (event.type) { + /* Was the X button on the window pressed? */ + case ALLEGRO_EVENT_DISPLAY_CLOSE: + return; + + /* Was a key pressed? */ + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + return; + break; + + /* Is it time for the next timer tick? */ + case ALLEGRO_EVENT_TIMER: + tick(&event.timer); + break; + } + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_keyboard(); + al_install_mouse(); + al_init_font_addon(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display.\n"); + } + + init(); + + timer = al_create_timer(1.000 / ex.FPS); + + ex.queue = al_create_event_queue(); + al_register_event_source(ex.queue, al_get_keyboard_event_source()); + al_register_event_source(ex.queue, al_get_mouse_event_source()); + al_register_event_source(ex.queue, al_get_display_event_source(display)); + al_register_event_source(ex.queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + run(); + + al_destroy_event_queue(ex.queue); + + cleanup(); + + return 0; +} diff --git a/allegro/examples/ex_timer_pause.c b/allegro/examples/ex_timer_pause.c new file mode 100644 index 00000000..f57a5a86 --- /dev/null +++ b/allegro/examples/ex_timer_pause.c @@ -0,0 +1,73 @@ +/* A test of pausing/resuming a timer. + * + * 1. Create two 5s long timers. + * 2. Let each run for 2s, then stop each for 2s. + * 3. Call al_resume_timer on timer1 and al_start_timer on timer2 + * 4. Wait for timer events + * + * timer1 should finish before timer2, as it was resumed rather than restarted. + */ +#include +#include + +#include "common.c" + +/* Run our test. */ +int main(int argc, char **argv) +{ + const double duration = 5; // timer lasts for 5 seconds + const double pre_pause = 2; // how long to wait before pausing + const double pause = 2; // how long to pause timer for + + ALLEGRO_TIMER *timer1 = NULL; + ALLEGRO_TIMER *timer2 = NULL; + ALLEGRO_EVENT_QUEUE *queue = NULL; + + ALLEGRO_EVENT ev; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + printf("Creating a pair of %2.0fs timers\n", duration); + queue = al_create_event_queue(); + timer1 = al_create_timer(duration); + timer2 = al_create_timer(duration); + al_register_event_source(queue, al_get_timer_event_source(timer1)); + al_register_event_source(queue, al_get_timer_event_source(timer2)); + + printf("Starting both timers at: %2.2fs\n", al_get_time() * 100); + al_start_timer(timer1); + al_start_timer(timer2); + al_rest(pre_pause); + + printf("Pausing timers at: %2.2fs\n", al_get_time() * 100); + al_stop_timer(timer1); + al_stop_timer(timer2); + al_rest(pause); + + printf("Resume timer1 at: %2.2fs\n", al_get_time() * 100); + al_resume_timer(timer1); + + printf("Restart timer2 at: %2.2fs\n", al_get_time() * 100); + al_start_timer(timer2); + + al_wait_for_event(queue, &ev); + printf("Timer%d finished at: %2.2fs\n", + al_get_timer_event_source(timer1) == ev.any.source ? 1 : 2, + al_get_time() * 100); + + al_wait_for_event(queue, &ev); + printf("Timer%d finished at: %2.2fs\n", + al_get_timer_event_source(timer1) == ev.any.source ? 1 : 2, + al_get_time() * 100); + + al_destroy_event_queue(queue); + al_destroy_timer(timer1); + al_destroy_timer(timer2); + + return 0; +} diff --git a/allegro/examples/ex_touch_input.c b/allegro/examples/ex_touch_input.c new file mode 100644 index 00000000..fd925858 --- /dev/null +++ b/allegro/examples/ex_touch_input.c @@ -0,0 +1,123 @@ +#include +#include + +#include "common.c" + +#define MAX_TOUCHES 16 + +typedef struct TOUCH TOUCH; +struct TOUCH { + int id; + int x; + int y; +}; + +static void draw_touches(int num, TOUCH touches[]) +{ + int i; + + for (i = 0; i < num; i++) { + int x = touches[i].x; + int y = touches[i].y; + al_draw_circle(x, y, 50, al_map_rgb(255, 0, 0), 4); + } +} + +static int find_index(int id, int num, TOUCH touches[]) +{ + int i; + + for (i = 0; i < num; i++) { + if (touches[i].id == id) { + return i; + } + } + + return -1; +} + +int main(int argc, char **argv) +{ + int num_touches = 0; + bool quit = false; + bool background = false; + TOUCH touches[MAX_TOUCHES]; + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_primitives_addon(); + if (!al_install_touch_input()) { + abort_example("Could not init touch input.\n"); + } + + display = al_create_display(800, 600); + if (!display) { + abort_example("Error creating display\n"); + } + queue = al_create_event_queue(); + + al_register_event_source(queue, al_get_touch_input_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + while (!quit) { + if (!background && al_is_event_queue_empty(queue)) { + al_clear_to_color(al_map_rgb(255, 255, 255)); + draw_touches(num_touches, touches); + al_flip_display(); + } + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + quit = true; + break; + case ALLEGRO_EVENT_TOUCH_BEGIN: { + int i = num_touches; + if (num_touches < MAX_TOUCHES) { + touches[i].id = event.touch.id; + touches[i].x = event.touch.x; + touches[i].y = event.touch.y; + num_touches++; + } + break; + } + case ALLEGRO_EVENT_TOUCH_END: { + int i = find_index(event.touch.id, num_touches, touches); + if (i >= 0 && i < num_touches) { + touches[i] = touches[num_touches - 1]; + num_touches--; + } + break; + } + case ALLEGRO_EVENT_TOUCH_MOVE: { + int i = find_index(event.touch.id, num_touches, touches); + if (i >= 0) { + touches[i].x = event.touch.x; + touches[i].y = event.touch.y; + } + break; + } + case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: + background = true; + al_acknowledge_drawing_halt(event.display.source); + break; + case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: + background = false; + al_acknowledge_drawing_resume(event.display.source); + break; + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(event.display.source); + break; + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_transform.c b/allegro/examples/ex_transform.c new file mode 100644 index 00000000..7bbc2b48 --- /dev/null +++ b/allegro/examples/ex_transform.c @@ -0,0 +1,190 @@ +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_primitives.h" +#include + +#include "common.c" + +int main(int argc, char **argv) +{ + const char *filename; + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *buffer, *bitmap, *subbitmap, *buffer_subbitmap; + ALLEGRO_BITMAP *overlay; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TRANSFORM transform; + bool software = false; + bool redraw = false; + bool blend = false; + bool use_subbitmap = true; + int w, h; + ALLEGRO_FONT* font; + ALLEGRO_FONT* soft_font; + + if (argc > 1) { + filename = argv[1]; + } + else { + filename = "data/mysha.pcx"; + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_primitives_addon(); + al_install_mouse(); + al_install_keyboard(); + + al_init_image_addon(); + al_init_font_addon(); + init_platform_specific(); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display\n"); + } + + subbitmap = al_create_sub_bitmap(al_get_backbuffer(display), 50, 50, 640 - 50, 480 - 50); + overlay = al_create_sub_bitmap(al_get_backbuffer(display), 100, 100, 300, 50); + + al_set_window_title(display, filename); + + bitmap = al_load_bitmap(filename); + if (!bitmap) { + abort_example("%s not found or failed to load\n", filename); + } + font = al_load_font("data/bmpfont.tga", 0, 0); + if (!font) { + abort_example("data/bmpfont.tga not found or failed to load\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + buffer = al_create_bitmap(640, 480); + buffer_subbitmap = al_create_sub_bitmap(buffer, 50, 50, 640 - 50, 480 - 50); + + soft_font = al_load_font("data/bmpfont.tga", 0, 0); + if (!soft_font) { + abort_example("data/bmpfont.tga not found or failed to load\n"); + } + + timer = al_create_timer(1.0 / 60); + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_start_timer(timer); + + w = al_get_bitmap_width(bitmap); + h = al_get_bitmap_height(bitmap); + + al_set_target_bitmap(overlay); + al_identity_transform(&transform); + al_rotate_transform(&transform, -0.06); + al_use_transform(&transform); + + while (1) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_S) { + software = !software; + if (software) { + /* Restore identity transform on display bitmap. */ + ALLEGRO_TRANSFORM identity; + al_identity_transform(&identity); + al_use_transform(&identity); + } + } else if (event.keyboard.keycode == ALLEGRO_KEY_L) { + blend = !blend; + } else if (event.keyboard.keycode == ALLEGRO_KEY_B) { + use_subbitmap = !use_subbitmap; + } else if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + } + if (event.type == ALLEGRO_EVENT_TIMER) + redraw = true; + + if (redraw && al_is_event_queue_empty(queue)) { + double t = 3.0 + al_get_time(); + ALLEGRO_COLOR tint; + redraw = false; + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + if(blend) + tint = al_map_rgba_f(0.5, 0.5, 0.5, 0.5); + else + tint = al_map_rgba_f(1, 1, 1, 1); + + if(software) { + if(use_subbitmap) { + al_set_target_bitmap(buffer); + al_clear_to_color(al_map_rgb_f(1, 0, 0)); + al_set_target_bitmap(buffer_subbitmap); + } else { + al_set_target_bitmap(buffer); + } + } else { + if(use_subbitmap) { + al_set_target_backbuffer(display); + al_clear_to_color(al_map_rgb_f(1, 0, 0)); + al_set_target_bitmap(subbitmap); + } else { + al_set_target_backbuffer(display); + } + } + + /* Set the transformation on the target bitmap. */ + al_identity_transform(&transform); + al_translate_transform(&transform, -640 / 2, -480 / 2); + al_scale_transform(&transform, 0.15 + sin(t / 5), 0.15 + cos(t / 5)); + al_rotate_transform(&transform, t / 50); + al_translate_transform(&transform, 640 / 2, 480 / 2); + al_use_transform(&transform); + + /* Draw some stuff */ + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_draw_tinted_bitmap(bitmap, tint, 0, 0, 0); + al_draw_tinted_scaled_bitmap(bitmap, tint, w / 4, h / 4, w / 2, h / 2, w, 0, w / 2, h / 4, 0);//ALLEGRO_FLIP_HORIZONTAL); + al_draw_tinted_bitmap_region(bitmap, tint, w / 4, h / 4, w / 2, h / 2, 0, h, ALLEGRO_FLIP_VERTICAL); + al_draw_tinted_scaled_rotated_bitmap(bitmap, tint, w / 2, h / 2, w + w / 2, h + h / 2, 0.7, 0.7, 0.3, 0); + al_draw_pixel(w + w / 2, h + h / 2, al_map_rgb_f(0, 1, 0)); + al_put_pixel(w + w / 2 + 2, h + h / 2 + 2, al_map_rgb_f(0, 1, 1)); + al_draw_circle(w, h, 50, al_map_rgb_f(1, 0.5, 0), 3); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + if(software) { + al_draw_text(soft_font, al_map_rgba_f(1, 1, 1, 1), + 640 / 2, 430, ALLEGRO_ALIGN_CENTRE, "Software Rendering"); + al_set_target_backbuffer(display); + al_draw_bitmap(buffer, 0, 0, 0); + } else { + al_draw_text(font, al_map_rgba_f(1, 1, 1, 1), + 640 / 2, 430, ALLEGRO_ALIGN_CENTRE, "Hardware Rendering"); + } + + /* Each target bitmap has its own transformation matrix, so this + * overlay is unaffected by the transformations set earlier. + */ + al_set_target_bitmap(overlay); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); + al_draw_text(font, al_map_rgba_f(1, 1, 0, 1), + 0, 10, ALLEGRO_ALIGN_LEFT, "hello!"); + + al_set_target_backbuffer(display); + al_flip_display(); + } + } + + al_destroy_bitmap(bitmap); + + return 0; +} + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_ttf.c b/allegro/examples/ex_ttf.c new file mode 100644 index 00000000..e9132c96 --- /dev/null +++ b/allegro/examples/ex_ttf.c @@ -0,0 +1,347 @@ +#define ALLEGRO_UNSTABLE + +#include +#include +#include +#include +#include + +#include "common.c" + +#define MAX_RANGES 256 + +const char *font_file = "data/DejaVuSans.ttf"; + +struct Example +{ + double fps; + ALLEGRO_FONT *f1, *f2, *f3, *f4, *f5; + ALLEGRO_FONT *f_alex; + ALLEGRO_CONFIG *config; + int ranges_count; +} ex; + +static void print_ranges(ALLEGRO_FONT *f) +{ + int ranges[MAX_RANGES * 2]; + int count; + int i; + + count = al_get_font_ranges(f, MAX_RANGES, ranges); + for (i = 0; i < count; i++) { + int begin = ranges[i * 2]; + int end = ranges[i * 2 + 1]; + log_printf("range %3d: %08x-%08x (%d glyph%s)\n", i, begin, end, + 1 + end - begin, begin == end ? "" : "s"); + } +} + +static const char *get_string(const char *key) +{ + const char *v = al_get_config_value(ex.config, "", key); + return (v) ? v : key; +} + +static int ustr_at(ALLEGRO_USTR *string, int index) +{ + return al_ustr_get(string, al_ustr_offset(string, index)); +} + +static void render(void) +{ + ALLEGRO_COLOR white = al_map_rgba_f(1, 1, 1, 1); + ALLEGRO_COLOR black = al_map_rgba_f(0, 0, 0, 1); + ALLEGRO_COLOR red = al_map_rgba_f(1, 0, 0, 1); + ALLEGRO_COLOR green = al_map_rgba_f(0, 0.5, 0, 1); + ALLEGRO_COLOR blue = al_map_rgba_f(0.1, 0.2, 1, 1); + ALLEGRO_COLOR purple = al_map_rgba_f(0.3, 0.1, 0.2, 1); + int x, y, w, h, as, de, xpos, ypos; + unsigned int index; + int target_w, target_h; + ALLEGRO_USTR_INFO info, sub_info; + const ALLEGRO_USTR *u; + ALLEGRO_USTR *tulip = al_ustr_new("Tulip"); + ALLEGRO_USTR *dimension_text = al_ustr_new("Tulip"); + ALLEGRO_USTR *vertical_text = al_ustr_new("Rose."); + ALLEGRO_USTR *dimension_label = al_ustr_new("(dimensions)"); + int prev_cp = -1; + + al_clear_to_color(white); + + al_hold_bitmap_drawing(true); + + al_draw_textf(ex.f1, black, 50, 20, 0, "Tulip (kerning)"); + al_draw_textf(ex.f2, black, 50, 80, 0, "Tulip (no kerning)"); + + x = 50; + y = 140; + for (index = 0; index < al_ustr_length(dimension_text); index ++) { + int cp = ustr_at(dimension_text, index); + int bbx, bby, bbw, bbh; + al_get_glyph_dimensions(ex.f2, cp, &bbx, &bby, &bbw, &bbh); + al_draw_rectangle(x + bbx + 0.5, y + bby + 0.5, x + bbx + bbw - 0.5, y + bby + bbh - 0.5, blue, 1); + al_draw_rectangle(x + 0.5, y + 0.5, x + bbx + bbw - 0.5, y + bby + bbh - 0.5, green, 1); + al_draw_glyph(ex.f2, purple, x, y, cp); + x += al_get_glyph_advance(ex.f2, cp, ALLEGRO_NO_KERNING); + } + al_draw_line(50.5, y+0.5, x+0.5, y+0.5, red, 1); + + for (index = 0; index < al_ustr_length(dimension_label); index++) { + int cp = ustr_at(dimension_label, index); + ALLEGRO_GLYPH g; + if (al_get_glyph(ex.f2, prev_cp, cp, &g)) { + al_draw_tinted_bitmap_region(g.bitmap, black, g.x, g.y, g.w, g.h, x + 10 + g.kerning + g.offset_x, y + g.offset_y, 0); + x += g.advance; + } + prev_cp = cp; + } + + al_draw_textf(ex.f3, black, 50, 200, 0, "This font has a size of 12 pixels, " + "the one above has 48 pixels."); + + al_hold_bitmap_drawing(false); + al_hold_bitmap_drawing(true); + + al_draw_textf(ex.f3, red, 50, 220, 0, "The color can simply be changed.🐊← fallback glyph"); + + al_hold_bitmap_drawing(false); + al_hold_bitmap_drawing(true); + + al_draw_textf(ex.f3, green, 50, 240, 0, "Some unicode symbols:"); + al_draw_textf(ex.f3, green, 50, 260, 0, "%s", get_string("symbols1")); + al_draw_textf(ex.f3, green, 50, 280, 0, "%s", get_string("symbols2")); + al_draw_textf(ex.f3, green, 50, 300, 0, "%s", get_string("symbols3")); + + #define OFF(x) al_ustr_offset(u, x) + #define SUB(x, y) al_ref_ustr(&sub_info, u, OFF(x), OFF(y)) + u = al_ref_cstr(&info, get_string("substr1")); + al_draw_ustr(ex.f3, green, 50, 320, 0, SUB(0, 6)); + u = al_ref_cstr(&info, get_string("substr2")); + al_draw_ustr(ex.f3, green, 50, 340, 0, SUB(7, 11)); + u = al_ref_cstr(&info, get_string("substr3")); + al_draw_ustr(ex.f3, green, 50, 360, 0, SUB(4, 11)); + u = al_ref_cstr(&info, get_string("substr4")); + al_draw_ustr(ex.f3, green, 50, 380, 0, SUB(0, 11)); + + al_draw_textf(ex.f5, black, 50, 395, 0, "forced monochrome"); + + /* Glyph rendering tests. */ + al_draw_textf(ex.f3, red, 50, 410, 0, "Glyph adv Tu: %d, draw: ", + al_get_glyph_advance(ex.f3, 'T', 'u')); + x = 50; + y = 425; + for (index = 0; index < al_ustr_length(tulip); index ++) { + int cp = ustr_at(tulip, index); + /* Use al_get_glyph_advance for the stride, with no kerning. */ + al_draw_glyph(ex.f3, red, x, y, cp); + x += al_get_glyph_advance(ex.f3, cp, ALLEGRO_NO_KERNING); + } + + x = 50; + y = 440; + /* First draw a red string using al_draw_text, that should be hidden + * completely by the same text drawing in green per glyph + * using al_draw_glyph and al_get_glyph_advance below. */ + al_draw_ustr(ex.f3, red, x, y, 0, tulip); + for (index = 0; index < al_ustr_length(tulip); index ++) { + int cp = ustr_at(tulip, index); + int ncp = (index < (al_ustr_length(tulip) - 1)) ? + ustr_at(tulip, index + 1) : ALLEGRO_NO_KERNING; + /* Use al_get_glyph_advance for the stride and apply kerning. */ + al_draw_glyph(ex.f3, green, x, y, cp); + x += al_get_glyph_advance(ex.f3, cp, ncp); + } + + x = 50; + y = 466; + al_draw_ustr(ex.f3, red, x, y, 0, tulip); + for (index = 0; index < al_ustr_length(tulip); index ++) { + int cp = ustr_at(tulip, index); + int bbx, bby, bbw, bbh; + al_get_glyph_dimensions(ex.f3, cp, &bbx, &bby, &bbw, &bbh); + al_draw_glyph(ex.f3, blue, x, y, cp); + x += bbx + bbw; + } + + + x = 10; + y = 30; + for (index = 0; index < al_ustr_length(vertical_text); index ++) { + int bbx, bby, bbw, bbh; + int cp = ustr_at(vertical_text, index); + /* Use al_get_glyph_dimensions for the height to apply. */ + al_get_glyph_dimensions(ex.f3, cp, &bbx, &bby, &bbw, &bbh); + al_draw_glyph(ex.f3, green, x, y, cp); + y += bby; + y += bbh; + } + + + x = 30; + y = 30; + for (index = 0; index < al_ustr_length(vertical_text); index ++) { + int bbx, bby, bbw, bbh; + int cp = ustr_at(vertical_text, index); + /* Use al_get_glyph_dimensions for the height to apply, here bby is + * omited for the wrong result. */ + al_get_glyph_dimensions(ex.f3, cp, &bbx, &bby, &bbw, &bbh); + al_draw_glyph(ex.f3, red, x, y, cp); + y += bbh; + } + + + al_hold_bitmap_drawing(false); + + target_w = al_get_bitmap_width(al_get_target_bitmap()); + target_h = al_get_bitmap_height(al_get_target_bitmap()); + + xpos = target_w - 10; + ypos = target_h - 10; + al_get_text_dimensions(ex.f4, "Allegro", &x, &y, &w, &h); + as = al_get_font_ascent(ex.f4); + de = al_get_font_descent(ex.f4); + xpos -= w; + ypos -= h; + x += xpos; + y += ypos; + + al_draw_rectangle(x, y, x + w - 0.5, y + h - 0.5, black, 0); + al_draw_line(x+0.5, y + as + 0.5, x + w - 0.5, y + as + 0.5, black, 0); + al_draw_line(x + 0.5, y + as + de + 0.5, x + w - 0.5, y + as + de + 0.5, black, 0); + + al_hold_bitmap_drawing(true); + al_draw_textf(ex.f4, blue, xpos, ypos, 0, "Allegro"); + al_hold_bitmap_drawing(false); + + al_hold_bitmap_drawing(true); + + al_draw_textf(ex.f3, black, target_w, 0, ALLEGRO_ALIGN_RIGHT, + "%.1f FPS", ex.fps); + + al_draw_textf(ex.f3, black, 0, 0, 0, "%s: %d unicode ranges", font_file, + ex.ranges_count); + + al_hold_bitmap_drawing(false); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + int redraw = 0; + double t = 0; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log_monospace(); + + al_init_primitives_addon(); + al_install_mouse(); + al_init_font_addon(); + al_init_ttf_addon(); + al_init_image_addon(); + init_platform_specific(); + +#ifdef ALLEGRO_IPHONE + al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); +#endif + display = al_create_display(640, 480); + if (!display) { + abort_example("Could not create display.\n"); + } + al_install_keyboard(); + + if (argc >= 2) { + font_file = argv[1]; + } + + ex.f1 = al_load_font(font_file, 48, 0); + ex.f2 = al_load_font(font_file, 48, ALLEGRO_TTF_NO_KERNING); + ex.f3 = al_load_font(font_file, 12, 0); + /* Specifying negative values means we specify the glyph height + * in pixels, not the usual font size. + */ + ex.f4 = al_load_font(font_file, -140, 0); + ex.f5 = al_load_font(font_file, 12, ALLEGRO_TTF_MONOCHROME); + + { + int ranges[] = {0x1F40A, 0x1F40A}; + ALLEGRO_BITMAP *icon = al_load_bitmap("data/icon.png"); + if (!icon) { + abort_example("Couldn't load data/icon.png.\n"); + } + ALLEGRO_BITMAP *glyph = al_create_bitmap(50, 50); + al_set_target_bitmap(glyph); + al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); + al_draw_rectangle(0.5, 0.5, 49.5, 49.5, al_map_rgb_f(1, 1, 0), + 1); + al_draw_bitmap(icon, 1, 1, 0); + al_set_target_backbuffer(display); + ex.f_alex = al_grab_font_from_bitmap(glyph, 1, ranges); + } + + if (!ex.f1 || !ex.f2 || !ex.f3 || !ex.f4 || !ex.f_alex) { + abort_example("Could not load font: %s\n", font_file); + } + + al_set_fallback_font(ex.f3, ex.f_alex); + + ex.ranges_count = al_get_font_ranges(ex.f1, 0, NULL); + print_ranges(ex.f1); + + ex.config = al_load_config_file("data/ex_ttf.ini"); + if (!ex.config) { + abort_example("Could not data/ex_ttf.ini\n"); + } + + timer = al_create_timer(1.0 / 60); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + while (true) { + ALLEGRO_EVENT event; + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + break; + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + if (event.type == ALLEGRO_EVENT_TIMER) + redraw++; + + while (redraw > 0 && al_is_event_queue_empty(queue)) { + double dt; + redraw--; + + dt = al_get_time(); + render(); + dt = al_get_time() - dt; + + t = 0.99 * t + 0.01 * dt; + + ex.fps = 1.0 / t; + al_flip_display(); + } + } + + al_destroy_font(ex.f1); + al_destroy_font(ex.f2); + al_destroy_font(ex.f3); + al_destroy_font(ex.f4); + al_destroy_font(ex.f5); + al_destroy_config(ex.config); + + close_log(false); + + return 0; +} + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/examples/ex_user_events.c b/allegro/examples/ex_user_events.c new file mode 100644 index 00000000..bf253677 --- /dev/null +++ b/allegro/examples/ex_user_events.c @@ -0,0 +1,120 @@ +/* + * Example program for the Allegro library. + */ + +#include +#include "allegro5/allegro.h" + +#include "common.c" + +#define MY_SIMPLE_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE('m', 's', 'e', 't') +#define MY_COMPLEX_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE('m', 'c', 'e', 't') + + +/* Just some fantasy event, supposedly used in an RPG - it's just to show that + * in practice, the 4 user fields we have now never will be enough. */ +typedef struct MY_EVENT +{ + int id; + int type; /* For example "attack" or "buy". */ + int x, y, z; /* Position in the game world the event takes place. */ + int server_time; /* Game time in ticks the event takes place. */ + int source_unit_id; /* E.g. attacker or seller. */ + int destination_unit_id; /* E.g. defender of buyer. */ + int item_id; /* E.g. weapon used or item sold. */ + int amount; /* Gold the item is sold for. */ +} MY_EVENT; + + +static MY_EVENT *new_event(int id) +{ + MY_EVENT *event = calloc(1, sizeof *event); + event->id = id; + return event; +} + + +static void my_event_dtor(ALLEGRO_USER_EVENT *event) +{ + log_printf("my_event_dtor: %p\n", (void *) event->data1); + free((void *) event->data1); +} + + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_SOURCE user_src; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT user_event; + ALLEGRO_EVENT event; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + timer = al_create_timer(0.5); + if (!timer) { + abort_example("Could not install timer.\n"); + } + + open_log(); + + al_init_user_event_source(&user_src); + + queue = al_create_event_queue(); + al_register_event_source(queue, &user_src); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_start_timer(timer); + + while (true) { + al_wait_for_event(queue, &event); + + if (event.type == ALLEGRO_EVENT_TIMER) { + int n = event.timer.count; + + log_printf("Got timer event %d\n", n); + + user_event.user.type = MY_SIMPLE_EVENT_TYPE; + user_event.user.data1 = n; + al_emit_user_event(&user_src, &user_event, NULL); + + user_event.user.type = MY_COMPLEX_EVENT_TYPE; + user_event.user.data1 = (intptr_t)new_event(n); + al_emit_user_event(&user_src, &user_event, my_event_dtor); + } + else if (event.type == MY_SIMPLE_EVENT_TYPE) { + int n = (int) event.user.data1; + ALLEGRO_ASSERT(event.user.source == &user_src); + + al_unref_user_event(&event.user); + + log_printf("Got simple user event %d\n", n); + if (n == 5) { + break; + } + } + else if (event.type == MY_COMPLEX_EVENT_TYPE) { + MY_EVENT *my_event = (void *)event.user.data1; + ALLEGRO_ASSERT(event.user.source == &user_src); + + log_printf("Got complex user event %d\n", my_event->id); + al_unref_user_event(&event.user); + } + } + + al_destroy_user_event_source(&user_src); + al_destroy_event_queue(queue); + al_destroy_timer(timer); + + log_printf("Done.\n"); + close_log(true); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_utf8.c b/allegro/examples/ex_utf8.c new file mode 100644 index 00000000..c42376cd --- /dev/null +++ b/allegro/examples/ex_utf8.c @@ -0,0 +1,1242 @@ +/* + * Example program for the Allegro library. + * + * Test UTF-8 string routines. + */ + +/* TODO: we should also be checking on inputs with surrogate characters + * (which are not allowed) + */ + +#include +#include +#include +#include + +#include "common.c" + +#ifdef ALLEGRO_MSVC + #pragma warning (disable: 4066) +#endif + +/* Some unicode characters */ +#define U_ae 0x00e6 /* æ */ +#define U_i_acute 0x00ed /* í */ +#define U_eth 0x00f0 /* ð */ +#define U_o_dia 0x00f6 /* ö */ +#define U_thorn 0x00fe /* þ */ +#define U_z_bar 0x01b6 /* ƶ */ +#define U_schwa 0x0259 /* ə */ +#define U_beta 0x03b2 /* β */ +#define U_1d08 0x1d08 /* ᴈ */ +#define U_1ff7 0x1ff7 /* ῷ */ +#define U_2051 0x2051 /* ⁑ */ +#define U_euro 0x20ac /* € */ + +typedef void (*test_t)(void); + +int error = 0; + +#define CHECK(x) \ + do { \ + bool ok = (x); \ + if (!ok) { \ + log_printf("FAIL %s\n", #x); \ + error++; \ + } else { \ + log_printf("OK %s\n", #x); \ + } \ + } while (0) + +/* Test that we can create and destroy strings and get their data and size. */ +static void t1(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new(""); + ALLEGRO_USTR *us2 = al_ustr_new("áƵ"); + + CHECK(0 == strcmp(al_cstr(us1), "")); + CHECK(0 == strcmp(al_cstr(us2), "áƵ")); + CHECK(4 == al_ustr_size(us2)); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +static void t2(void) +{ + CHECK(0 == al_ustr_size(al_ustr_empty_string())); + CHECK(0 == strcmp(al_cstr(al_ustr_empty_string()), "")); +} + +/* Test that we make strings which reference other C strings. */ +/* No memory needs to be freed. */ +static void t3(void) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us = al_ref_cstr(&info, "A static string."); + + CHECK(0 == strcmp(al_cstr(us), "A static string.")); +} + +/* Test that we can make strings which reference arbitrary memory blocks. */ +/* No memory needs to be freed. */ +static void t4(void) +{ + const char s[] = "This contains an embedded NUL: \0 <-- here"; + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us = al_ref_buffer(&info, s, sizeof(s)); + + CHECK(al_ustr_size(us) == sizeof(s)); + CHECK(0 == memcmp(al_cstr(us), s, sizeof(s))); +} + +/* Test that we can make strings which reference (parts of) other strings. */ +static void t5(void) +{ + ALLEGRO_USTR *us1; + const ALLEGRO_USTR *us2; + ALLEGRO_USTR_INFO us2_info; + + us1 = al_ustr_new("aábdðeéfghiíjklmnoóprstuúvxyýþæö"); + + us2 = al_ref_ustr(&us2_info, us1, 36, 36 + 4); + CHECK(0 == memcmp(al_cstr(us2), "þæ", al_ustr_size(us2))); + + /* Start pos underflow */ + us2 = al_ref_ustr(&us2_info, us1, -10, 7); + CHECK(0 == memcmp(al_cstr(us2), "aábdð", al_ustr_size(us2))); + + /* End pos overflow */ + us2 = al_ref_ustr(&us2_info, us1, 36, INT_MAX); + CHECK(0 == memcmp(al_cstr(us2), "þæö", al_ustr_size(us2))); + + /* Start > end */ + us2 = al_ref_ustr(&us2_info, us1, 36 + 4, 36); + CHECK(0 == al_ustr_size(us2)); + + al_ustr_free(us1); +} + +/* Test al_ustr_dup. */ +static void t6(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjklmnoóprstuúvxyýþæö"); + ALLEGRO_USTR *us2 = al_ustr_dup(us1); + + CHECK(al_ustr_size(us1) == al_ustr_size(us2)); + CHECK(0 == memcmp(al_cstr(us1), al_cstr(us2), al_ustr_size(us1))); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +/* Test al_ustr_dup_substr. */ +static void t7(void) +{ + ALLEGRO_USTR *us1; + ALLEGRO_USTR *us2; + + us1 = al_ustr_new("aábdðeéfghiíjklmnoóprstuúvxyýþæö"); + + /* Cut out part of a string. Check for NUL terminator. */ + us2 = al_ustr_dup_substr(us1, 36, 36 + 4); + CHECK(al_ustr_size(us2) == 4); + CHECK(0 == strcmp(al_cstr(us2), "þæ")); + al_ustr_free(us2); + + /* Under and overflow */ + us2 = al_ustr_dup_substr(us1, INT_MIN, INT_MAX); + CHECK(al_ustr_size(us2) == al_ustr_size(us1)); + CHECK(0 == strcmp(al_cstr(us2), al_cstr(us1))); + al_ustr_free(us2); + + /* Start > end */ + us2 = al_ustr_dup_substr(us1, INT_MAX, INT_MIN); + CHECK(0 == al_ustr_size(us2)); + al_ustr_free(us2); + + al_ustr_free(us1); +} + +/* Test al_ustr_append, al_ustr_append_cstr. */ +static void t8(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjklm"); + ALLEGRO_USTR *us2 = al_ustr_new("noóprstuú"); + + CHECK(al_ustr_append(us1, us2)); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmnoóprstuú")); + + CHECK(al_ustr_append_cstr(us1, "vxyýþæö")); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmnoóprstuúvxyýþæö")); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +/* Test al_ustr_append with aliased strings. */ +static void t9(void) +{ + ALLEGRO_USTR *us1; + ALLEGRO_USTR_INFO us2_info; + const ALLEGRO_USTR *us2; + + /* Append a string to itself. */ + us1 = al_ustr_new("aábdðeéfghiíjklm"); + CHECK(al_ustr_append(us1, us1)); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmaábdðeéfghiíjklm")); + al_ustr_free(us1); + + /* Append a substring of a string to itself. */ + us1 = al_ustr_new("aábdðeéfghiíjklm"); + us2 = al_ref_ustr(&us2_info, us1, 5, 5 + 11); /* ð...í */ + CHECK(al_ustr_append(us1, us2)); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmðeéfghií")); + al_ustr_free(us1); +} + +/* Test al_ustr_equal. */ +static void t10(void) +{ + ALLEGRO_USTR *us1; + ALLEGRO_USTR *us2; + const ALLEGRO_USTR *us3; + ALLEGRO_USTR_INFO us3_info; + const char us3_data[] = "aábdð\0eéfgh"; + + us1 = al_ustr_new("aábdð"); + us2 = al_ustr_dup(us1); + us3 = al_ref_buffer(&us3_info, us3_data, sizeof(us3_data)); + + CHECK(al_ustr_equal(us1, us2)); + CHECK(!al_ustr_equal(us1, al_ustr_empty_string())); + + /* Check comparison doesn't stop at embedded NUL. */ + CHECK(!al_ustr_equal(us1, us3)); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +/* Test al_ustr_insert. */ +static void t11(void) +{ + ALLEGRO_USTR *us1; + ALLEGRO_USTR *us2; + size_t sz; + + /* Insert in middle. */ + us1 = al_ustr_new("aábdðeéfghiíjkprstuúvxyýþæö"); + us2 = al_ustr_new("lmnoó"); + al_ustr_insert(us1, 18, us2); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjklmnoóprstuúvxyýþæö")); + + /* Insert into itself. */ + al_ustr_insert(us2, 3, us2); + CHECK(0 == strcmp(al_cstr(us2), "lmnlmnoóoó")); + + /* Insert before start (not allowed). */ + CHECK(!al_ustr_insert(us2, -1, us2)); + + /* Insert past end (will be padded with NULs). */ + sz = al_ustr_size(us2); + al_ustr_insert(us2, sz + 3, us2); + CHECK(al_ustr_size(us2) == sz + sz + 3); + CHECK(0 == memcmp(al_cstr(us2), "lmnlmnoóoó\0\0\0lmnlmnoóoó", sz + sz + 3)); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +/* Test al_ustr_insert_cstr. */ +static void t12(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("aábeéf"); + CHECK(al_ustr_insert_cstr(us1, 4, "dð")); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéf")); + al_ustr_free(us1); +} + +/* Test al_ustr_remove_range. */ +static void t13(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjkprstuúvxyýþæö"); + + /* Remove from middle of string. */ + CHECK(al_ustr_remove_range(us1, 5, 30)); + CHECK(0 == strcmp(al_cstr(us1), "aábdþæö")); + + /* Removing past end. */ + CHECK(al_ustr_remove_range(us1, 100, 120)); + CHECK(0 == strcmp(al_cstr(us1), "aábdþæö")); + + /* Start > End. */ + CHECK(! al_ustr_remove_range(us1, 3, 0)); + CHECK(0 == strcmp(al_cstr(us1), "aábdþæö")); + + al_ustr_free(us1); +} + +/* Test al_ustr_truncate. */ +static void t14(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("aábdðeéfghiíjkprstuúvxyýþæö"); + + /* Truncate from middle of string. */ + CHECK(al_ustr_truncate(us1, 30)); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjkprstuúvxyý")); + + /* Truncate past end (allowed). */ + CHECK(al_ustr_truncate(us1, 100)); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjkprstuúvxyý")); + + /* Truncate before start (not allowed). */ + CHECK(! al_ustr_truncate(us1, -1)); + CHECK(0 == strcmp(al_cstr(us1), "aábdðeéfghiíjkprstuúvxyý")); + + al_ustr_free(us1); +} + +/* Test whitespace trim functions. */ +static void t15(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new(" \f\n\r\t\vhello \f\n\r\t\v"); + ALLEGRO_USTR *us2 = al_ustr_new(" \f\n\r\t\vhello \f\n\r\t\v"); + + CHECK(al_ustr_ltrim_ws(us1)); + CHECK(0 == strcmp(al_cstr(us1), "hello \f\n\r\t\v")); + + CHECK(al_ustr_rtrim_ws(us1)); + CHECK(0 == strcmp(al_cstr(us1), "hello")); + + CHECK(al_ustr_trim_ws(us2)); + CHECK(0 == strcmp(al_cstr(us2), "hello")); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +/* Test whitespace trim functions (edge cases). */ +static void t16(void) +{ + ALLEGRO_USTR *us1; + + /* Check return value when passed empty strings. */ + us1 = al_ustr_new(""); + CHECK(al_ustr_ltrim_ws(us1)); + CHECK(al_ustr_rtrim_ws(us1)); + CHECK(al_ustr_trim_ws(us1)); + al_ustr_free(us1); + + /* Check nothing bad happens if the whole string is whitespace. */ + us1 = al_ustr_new(" \f\n\r\t\v"); + CHECK(al_ustr_ltrim_ws(us1)); + CHECK(al_ustr_size(us1) == 0); + al_ustr_free(us1); + + us1 = al_ustr_new(" \f\n\r\t\v"); + CHECK(al_ustr_rtrim_ws(us1)); + CHECK(al_ustr_size(us1) == 0); + al_ustr_free(us1); + + us1 = al_ustr_new(" \f\n\r\t\v"); + CHECK(al_ustr_trim_ws(us1)); + CHECK(al_ustr_size(us1) == 0); + al_ustr_free(us1); +} + +/* Test al_utf8_width. */ +static void t17(void) +{ + CHECK(al_utf8_width(0x000000) == 1); + CHECK(al_utf8_width(0x00007f) == 1); + CHECK(al_utf8_width(0x000080) == 2); + CHECK(al_utf8_width(0x0007ff) == 2); + CHECK(al_utf8_width(0x000800) == 3); + CHECK(al_utf8_width(0x00ffff) == 3); + CHECK(al_utf8_width(0x010000) == 4); + CHECK(al_utf8_width(0x10ffff) == 4); + + /* These are illegal. */ + CHECK(al_utf8_width(0x110000) == 0); + CHECK(al_utf8_width(0xffffff) == 0); +} + +/* Test al_utf8_encode. */ +static void t18(void) +{ + char buf[4]; + + CHECK(al_utf8_encode(buf, 0) == 1); + CHECK(0 == memcmp(buf, "\x00", 1)); + + CHECK(al_utf8_encode(buf, 0x7f) == 1); + CHECK(0 == memcmp(buf, "\x7f", 1)); + + CHECK(al_utf8_encode(buf, 0x80) == 2); + CHECK(0 == memcmp(buf, "\xC2\x80", 2)); + + CHECK(al_utf8_encode(buf, 0x7ff) == 2); + CHECK(0 == memcmp(buf, "\xDF\xBF", 2)); + + CHECK(al_utf8_encode(buf, 0x000800) == 3); + CHECK(0 == memcmp(buf, "\xE0\xA0\x80", 3)); + + CHECK(al_utf8_encode(buf, 0x00ffff) == 3); + CHECK(0 == memcmp(buf, "\xEF\xBF\xBF", 3)); + + CHECK(al_utf8_encode(buf, 0x010000) == 4); + CHECK(0 == memcmp(buf, "\xF0\x90\x80\x80", 4)); + + CHECK(al_utf8_encode(buf, 0x10ffff) == 4); + CHECK(0 == memcmp(buf, "\xF4\x8f\xBF\xBF", 4)); + + /* These are illegal. */ + CHECK(al_utf8_encode(buf, 0x110000) == 0); + CHECK(al_utf8_encode(buf, 0xffffff) == 0); +} + +/* Test al_ustr_insert_chr. */ +static void t19(void) +{ + ALLEGRO_USTR *us = al_ustr_new(""); + + CHECK(al_ustr_insert_chr(us, 0, 'a') == 1); + CHECK(al_ustr_insert_chr(us, 0, U_ae) == 2); + CHECK(al_ustr_insert_chr(us, 2, U_euro) == 3); + CHECK(0 == strcmp(al_cstr(us), "æ€a")); + + /* Past end. */ + CHECK(al_ustr_insert_chr(us, 8, U_o_dia) == 2); + CHECK(0 == memcmp(al_cstr(us), "æ€a\0\0ö", 9)); + + /* Invalid code points. */ + CHECK(al_ustr_insert_chr(us, 0, -1) == 0); + CHECK(al_ustr_insert_chr(us, 0, 0x110000) == 0); + + al_ustr_free(us); +} + +/* Test al_ustr_append_chr. */ +static void t20(void) +{ + ALLEGRO_USTR *us = al_ustr_new(""); + + CHECK(al_ustr_append_chr(us, 'a') == 1); + CHECK(al_ustr_append_chr(us, U_ae) == 2); + CHECK(al_ustr_append_chr(us, U_euro) == 3); + CHECK(0 == strcmp(al_cstr(us), "aæ€")); + + /* Invalid code points. */ + CHECK(al_ustr_append_chr(us, -1) == 0); + CHECK(al_ustr_append_chr(us, 0x110000) == 0); + + al_ustr_free(us); +} + +/* Test al_ustr_get. */ +static void t21(void) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us; + + us = al_ref_buffer(&info, "", 1); + CHECK(al_ustr_get(us, 0) == 0); + + us = al_ref_cstr(&info, "\x7f"); + CHECK(al_ustr_get(us, 0) == 0x7f); + + us = al_ref_cstr(&info, "\xC2\x80"); + CHECK(al_ustr_get(us, 0) == 0x80); + + us = al_ref_cstr(&info, "\xDF\xBf"); + CHECK(al_ustr_get(us, 0) == 0x7ff); + + us = al_ref_cstr(&info, "\xE0\xA0\x80"); + CHECK(al_ustr_get(us, 0) == 0x800); + + us = al_ref_cstr(&info, "\xEF\xBF\xBF"); + CHECK(al_ustr_get(us, 0) == 0xffff); + + us = al_ref_cstr(&info, "\xF0\x90\x80\x80"); + CHECK(al_ustr_get(us, 0) == 0x010000); + + us = al_ref_cstr(&info, "\xF4\x8F\xBF\xBF"); + CHECK(al_ustr_get(us, 0) == 0x10ffff); +} + +/* Test al_ustr_get on invalid sequences. */ +static void t22(void) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us; + + /* Empty string. */ + al_set_errno(0); + CHECK(al_ustr_get(al_ustr_empty_string(), 0) < 0); + CHECK(al_get_errno() == ERANGE); + + /* 5-byte sequence. */ + us = al_ref_cstr(&info, "\xf8\x88\x80\x80\x80"); + al_set_errno(0); + CHECK(al_ustr_get(us, 0) < 0); + CHECK(al_get_errno() == EILSEQ); + + /* Start in trail byte. */ + us = al_ref_cstr(&info, "ð"); + al_set_errno(0); + CHECK(al_ustr_get(us, 1) < 0); + CHECK(al_get_errno() == EILSEQ); + + /* Truncated 3-byte sequence. */ + us = al_ref_cstr(&info, "\xEF\xBF"); + al_set_errno(0); + CHECK(al_ustr_get(us, 0) < 0); + CHECK(al_get_errno() == EILSEQ); +} + +/* Test al_ustr_get on invalid sequences (part 2). */ +/* Get more ideas for tests from + * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt + */ +static void t23(void) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us; + + /* Examples of an overlong ASCII character */ + us = al_ref_cstr(&info, "\xc0\xaf"); + CHECK(al_ustr_get(us, 0) < 0); + us = al_ref_cstr(&info, "\xe0\x80\xaf"); + CHECK(al_ustr_get(us, 0) < 0); + us = al_ref_cstr(&info, "\xf0\x80\x80\xaf"); + CHECK(al_ustr_get(us, 0) < 0); + us = al_ref_cstr(&info, "\xf8\x80\x80\x80\xaf"); + CHECK(al_ustr_get(us, 0) < 0); + us = al_ref_cstr(&info, "\xfc\x80\x80\x80\x80\xaf"); + CHECK(al_ustr_get(us, 0) < 0); + + /* Maximum overlong sequences */ + us = al_ref_cstr(&info, "\xc1\xbf"); + CHECK(al_ustr_get(us, 0) < 0); + + us = al_ref_cstr(&info, "\xe0\x9f\xbf"); + CHECK(al_ustr_get(us, 0) < 0); + + us = al_ref_cstr(&info, "\xf0\x8f\xbf\xbf"); + CHECK(al_ustr_get(us, 0) < 0); + + us = al_ref_cstr(&info, "\xf8\x87\xbf\xbf\xbf"); + CHECK(al_ustr_get(us, 0) < 0); + + us = al_ref_cstr(&info, "\xfc\x83\xbf\xbf\xbf\xbf"); + CHECK(al_ustr_get(us, 0) < 0); + + /* Overlong representation of the NUL character */ + us = al_ref_cstr(&info, "\xc0\x80"); + CHECK(al_ustr_get(us, 0) < 0); + + us = al_ref_cstr(&info, "\xe0\x80\x80"); + CHECK(al_ustr_get(us, 0) < 0); + + us = al_ref_cstr(&info, "\xf0\x80\x80"); + CHECK(al_ustr_get(us, 0) < 0); + + us = al_ref_cstr(&info, "\xf8\x80\x80\x80"); + CHECK(al_ustr_get(us, 0) < 0); + + us = al_ref_cstr(&info, "\xfc\x80\x80\x80\x80"); + CHECK(al_ustr_get(us, 0) < 0); +} + +/* Test al_ustr_next. */ +static void t24(void) +{ + const char str[] = "a\0þ€\xf4\x8f\xbf\xbf"; + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us = al_ref_buffer(&info, str, sizeof(str) - 1); + int pos = 0; + + CHECK(al_ustr_next(us, &pos)); /* a */ + CHECK(pos == 1); + + CHECK(al_ustr_next(us, &pos)); /* NUL */ + CHECK(pos == 2); + + CHECK(al_ustr_next(us, &pos)); /* þ */ + CHECK(pos == 4); + + CHECK(al_ustr_next(us, &pos)); /* € */ + CHECK(pos == 7); + + CHECK(al_ustr_next(us, &pos)); /* U+10FFFF */ + CHECK(pos == 11); + + CHECK(! al_ustr_next(us, &pos)); /* end */ + CHECK(pos == 11); +} + +/* Test al_ustr_next with invalid input. */ +static void t25(void) +{ + const char str[] = "þ\xf4\x8f\xbf."; + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us = al_ref_buffer(&info, str, sizeof(str) - 1); + int pos; + + /* Starting in middle of a sequence. */ + pos = 1; + CHECK(al_ustr_next(us, &pos)); + CHECK(pos == 2); + + /* Unexpected end of 4-byte sequence. */ + CHECK(al_ustr_next(us, &pos)); + CHECK(pos == 5); +} + +/* Test al_ustr_prev. */ +static void t26(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aþ€\xf4\x8f\xbf\xbf"); + int pos = al_ustr_size(us); + + CHECK(al_ustr_prev(us, &pos)); /* U+10FFFF */ + CHECK(pos == 6); + + CHECK(al_ustr_prev(us, &pos)); /* € */ + CHECK(pos == 3); + + CHECK(al_ustr_prev(us, &pos)); /* þ */ + CHECK(pos == 1); + + CHECK(al_ustr_prev(us, &pos)); /* a */ + CHECK(pos == 0); + + CHECK(!al_ustr_prev(us, &pos)); /* begin */ + CHECK(pos == 0); + + al_ustr_free(us); +} + +/* Test al_ustr_length. */ +static void t27(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aþ€\xf4\x8f\xbf\xbf"); + + CHECK(0 == al_ustr_length(al_ustr_empty_string())); + CHECK(4 == al_ustr_length(us)); + + al_ustr_free(us); +} + +/* Test al_ustr_offset. */ +static void t28(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aþ€\xf4\x8f\xbf\xbf"); + + CHECK(al_ustr_offset(us, 0) == 0); + CHECK(al_ustr_offset(us, 1) == 1); + CHECK(al_ustr_offset(us, 2) == 3); + CHECK(al_ustr_offset(us, 3) == 6); + CHECK(al_ustr_offset(us, 4) == 10); + CHECK(al_ustr_offset(us, 5) == 10); + + CHECK(al_ustr_offset(us, -1) == 6); + CHECK(al_ustr_offset(us, -2) == 3); + CHECK(al_ustr_offset(us, -3) == 1); + CHECK(al_ustr_offset(us, -4) == 0); + CHECK(al_ustr_offset(us, -5) == 0); + + al_ustr_free(us); +} + +/* Test al_ustr_get_next. */ +static void t29(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aþ€"); + int pos; + + pos = 0; + CHECK(al_ustr_get_next(us, &pos) == 'a'); + CHECK(al_ustr_get_next(us, &pos) == U_thorn); + CHECK(al_ustr_get_next(us, &pos) == U_euro); + CHECK(al_ustr_get_next(us, &pos) == -1); + CHECK(pos == (int) al_ustr_size(us)); + + /* Start in the middle of þ. */ + pos = 2; + CHECK(al_ustr_get_next(us, &pos) == -2); + CHECK(al_ustr_get_next(us, &pos) == U_euro); + + al_ustr_free(us); +} + +/* Test al_ustr_prev_get. */ +static void t30(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aþ€"); + int pos; + + pos = al_ustr_size(us); + CHECK(al_ustr_prev_get(us, &pos) == U_euro); + CHECK(al_ustr_prev_get(us, &pos) == U_thorn); + CHECK(al_ustr_prev_get(us, &pos) == 'a'); + CHECK(al_ustr_prev_get(us, &pos) == -1); + + /* Start in the middle of þ. */ + pos = 2; + CHECK(al_ustr_prev_get(us, &pos) == U_thorn); + + al_ustr_free(us); +} + +/* Test al_ustr_find_chr. */ +static void t31(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); + + /* Find ASCII. */ + CHECK(al_ustr_find_chr(us, 0, 'e') == 7); + CHECK(al_ustr_find_chr(us, 7, 'e') == 7); /* start_pos is inclusive */ + CHECK(al_ustr_find_chr(us, 8, 'e') == 23); + CHECK(al_ustr_find_chr(us, 0, '.') == -1); + + /* Find non-ASCII. */ + CHECK(al_ustr_find_chr(us, 0, U_eth) == 5); + CHECK(al_ustr_find_chr(us, 5, U_eth) == 5); /* start_pos is inclusive */ + CHECK(al_ustr_find_chr(us, 6, U_eth) == 21); + CHECK(al_ustr_find_chr(us, 0, U_z_bar) == -1); + + al_ustr_free(us); +} + +/* Test al_ustr_rfind_chr. */ +static void t32(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); + int end = al_ustr_size(us); + + /* Find ASCII. */ + CHECK(al_ustr_rfind_chr(us, end, 'e') == 23); + CHECK(al_ustr_rfind_chr(us, 23, 'e') == 7); /* end_pos exclusive */ + CHECK(al_ustr_rfind_chr(us, end, '.') == -1); + + /* Find non-ASCII. */ + CHECK(al_ustr_rfind_chr(us, end, U_i_acute) == 30); + CHECK(al_ustr_rfind_chr(us, end - 1, U_i_acute) == 14); /* end_pos exclusive */ + CHECK(al_ustr_rfind_chr(us, end, U_z_bar) == -1); + + al_ustr_free(us); +} + +/* Test al_ustr_find_set, al_ustr_find_set_cstr. */ +static void t33(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); + + /* al_ustr_find_set_cstr is s simple wrapper for al_ustr_find_set + * so we test using that. + */ + + /* Find ASCII. */ + CHECK(al_ustr_find_set_cstr(us, 0, "gfe") == 7); + CHECK(al_ustr_find_set_cstr(us, 7, "gfe") == 7); /* start_pos inclusive */ + CHECK(al_ustr_find_set_cstr(us, 0, "") == -1); + CHECK(al_ustr_find_set_cstr(us, 0, "xyz") == -1); + + /* Find non-ASCII. */ + CHECK(al_ustr_find_set_cstr(us, 0, "éðf") == 5); + CHECK(al_ustr_find_set_cstr(us, 5, "éðf") == 5); /* start_pos inclusive */ + CHECK(al_ustr_find_set_cstr(us, 0, "ẋỹƶ") == -1); + + al_ustr_free(us); +} + +/* Test al_ustr_find_set, al_ustr_find_set_cstr (invalid values). */ +static void t34(void) +{ + ALLEGRO_USTR *us = al_ustr_new("a\x80ábdðeéfghií"); + + /* Invalid byte sequence in search string. */ + CHECK(al_ustr_find_set_cstr(us, 0, "gfe") == 8); + + /* Invalid byte sequence in accept set. */ + CHECK(al_ustr_find_set_cstr(us, 0, "é\x80ðf") == 6); + + al_ustr_free(us); +} + +/* Test al_ustr_find_cset, al_ustr_find_cset_cstr. */ +static void t35(void) +{ + ALLEGRO_USTR *us; + + /* al_ustr_find_cset_cstr is s simple wrapper for al_ustr_find_cset + * so we test using that. + */ + + /* Find ASCII. */ + us = al_ustr_new("alphabetagamma"); + CHECK(al_ustr_find_cset_cstr(us, 0, "alphbet") == 9); + CHECK(al_ustr_find_cset_cstr(us, 9, "alphbet") == 9); + CHECK(al_ustr_find_cset_cstr(us, 0, "") == -1); + CHECK(al_ustr_find_cset_cstr(us, 0, "alphbetgm") == -1); + al_ustr_free(us); + + /* Find non-ASCII. */ + us = al_ustr_new("αλφαβεταγαμμα"); + CHECK(al_ustr_find_cset_cstr(us, 0, "αλφβετ") == 16); + CHECK(al_ustr_find_cset_cstr(us, 16, "αλφβετ") == 16); + CHECK(al_ustr_find_cset_cstr(us, 0, "αλφβετγμ") == -1); + al_ustr_free(us); +} + +/* Test al_ustr_find_cset, al_ustr_find_set_cstr (invalid values). */ +static void t36(void) +{ + ALLEGRO_USTR *us = al_ustr_new("a\x80ábdðeéfghií"); + + /* Invalid byte sequence in search string. */ + CHECK(al_ustr_find_cset_cstr(us, 0, "aábd") == 6); + + /* Invalid byte sequence in reject set. */ + CHECK(al_ustr_find_cset_cstr(us, 0, "a\x80ábd") == 6); + + al_ustr_free(us); +} + +/* Test al_ustr_find_str, al_ustr_find_cstr. */ +static void t37(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); + + /* al_ustr_find_cstr is s simple wrapper for al_ustr_find_str + * so we test using that. + */ + + CHECK(al_ustr_find_cstr(us, 0, "") == 0); + CHECK(al_ustr_find_cstr(us, 10, "") == 10); + CHECK(al_ustr_find_cstr(us, 0, "ábd") == 1); + CHECK(al_ustr_find_cstr(us, 10, "ábd") == 17); + CHECK(al_ustr_find_cstr(us, 0, "ábz") == -1); + + al_ustr_free(us); +} + +/* Test al_ustr_rfind_str, al_ustr_rfind_cstr. */ +static void t38(void) +{ + ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); + int end = al_ustr_size(us); + + /* al_ustr_find_cstr is s simple wrapper for al_ustr_find_str + * so we test using that. + */ + + CHECK(al_ustr_rfind_cstr(us, 0, "") == 0); + CHECK(al_ustr_rfind_cstr(us, 1, "") == 1); + CHECK(al_ustr_rfind_cstr(us, end, "hií") == end - 4); + CHECK(al_ustr_rfind_cstr(us, end - 1, "hií") == 12); + CHECK(al_ustr_rfind_cstr(us, end, "ábz") == -1); + + al_ustr_free(us); +} + +/* Test al_ustr_new_from_buffer, al_cstr_dup. */ +static void t39(void) +{ + const char s1[] = "Корабът ми на въздушна възглавница\0е пълен със змиорки"; + ALLEGRO_USTR *us; + char *s2; + + us = al_ustr_new_from_buffer(s1, sizeof(s1) - 1); /* missing NUL term. */ + s2 = al_cstr_dup(us); + al_ustr_free(us); + + CHECK(0 == strcmp(s1, s2)); + CHECK(0 == memcmp(s1, s2, sizeof(s1))); /* including NUL terminator */ + + al_free(s2); +} + +/* Test al_ustr_assign, al_ustr_assign_cstr. */ +static void t40(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("我隻氣墊船裝滿晒鱔"); + ALLEGRO_USTR *us2 = al_ustr_new("Τὸ χόβερκράφτ μου εἶναι γεμᾶτο χέλια"); + + CHECK(al_ustr_assign(us1, us2)); + CHECK(0 == strcmp(al_cstr(us1), "Τὸ χόβερκράφτ μου εἶναι γεμᾶτο χέλια")); + + CHECK(al_ustr_assign_cstr(us1, "私のホバークラフトは鰻でいっぱいです")); + CHECK(54 == al_ustr_size(us1)); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +/* Test al_ustr_assign_cstr. */ +static void t41(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("Моја лебдилица је пуна јегуља"); + ALLEGRO_USTR *us2 = al_ustr_new(""); + + CHECK(al_ustr_assign_substr(us2, us1, 9, 27)); + CHECK(0 == strcmp(al_cstr(us2), "лебдилица")); + + /* Start > End */ + CHECK(al_ustr_assign_substr(us2, us1, 9, 0)); + CHECK(0 == strcmp(al_cstr(us2), "")); + + /* Start, end out of bounds */ + CHECK(al_ustr_assign_substr(us2, us1, -INT_MAX, INT_MAX)); + CHECK(0 == strcmp(al_cstr(us2), "Моја лебдилица је пуна јегуља")); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +/* Test al_ustr_set_chr. */ +static void t42(void) +{ + ALLEGRO_USTR *us = al_ustr_new("abcdef"); + + /* Same size (ASCII). */ + CHECK(al_ustr_set_chr(us, 1, 'B') == 1); + CHECK(0 == strcmp(al_cstr(us), "aBcdef")); + CHECK(6 == al_ustr_size(us)); + + /* Enlarge to 2-bytes. */ + CHECK(al_ustr_set_chr(us, 1, U_beta) == 2); + CHECK(0 == strcmp(al_cstr(us), "aβcdef")); + CHECK(7 == al_ustr_size(us)); + + /* Enlarge to 3-bytes. */ + CHECK(al_ustr_set_chr(us, 5, U_1d08) == 3); + CHECK(0 == strcmp(al_cstr(us), "aβcdᴈf")); + CHECK(9 == al_ustr_size(us)); + + /* Reduce to 2-bytes. */ + CHECK(al_ustr_set_chr(us, 5, U_schwa) == 2); + CHECK(0 == strcmp(al_cstr(us), "aβcdəf")); + CHECK(8 == al_ustr_size(us)); + + /* Set at end of string. */ + CHECK(al_ustr_set_chr(us, al_ustr_size(us), U_1ff7) == 3); + CHECK(0 == strcmp(al_cstr(us), "aβcdəfῷ")); + CHECK(11 == al_ustr_size(us)); + + /* Set past end of string. */ + CHECK(al_ustr_set_chr(us, al_ustr_size(us) + 2, U_2051) == 3); + CHECK(0 == memcmp(al_cstr(us), "aβcdəfῷ\0\0⁑", 16)); + CHECK(16 == al_ustr_size(us)); + + /* Set before start of string (not allowed). */ + CHECK(al_ustr_set_chr(us, -1, U_2051) == 0); + CHECK(16 == al_ustr_size(us)); + + al_ustr_free(us); +} + +/* Test al_ustr_remove_chr. */ +static void t43(void) +{ + ALLEGRO_USTR *us = al_ustr_new("«aβῷ»"); + + CHECK(al_ustr_remove_chr(us, 2)); + CHECK(0 == strcmp(al_cstr(us), "«βῷ»")); + + CHECK(al_ustr_remove_chr(us, 2)); + CHECK(0 == strcmp(al_cstr(us), "«ῷ»")); + + CHECK(al_ustr_remove_chr(us, 2)); + CHECK(0 == strcmp(al_cstr(us), "«»")); + + /* Not at beginning of code point. */ + CHECK(! al_ustr_remove_chr(us, 1)); + + /* Out of bounds. */ + CHECK(! al_ustr_remove_chr(us, -1)); + CHECK(! al_ustr_remove_chr(us, al_ustr_size(us))); + + al_ustr_free(us); +} + +/* Test al_ustr_replace_range. */ +static void t44(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("Šis kungs par visu samaksās"); + ALLEGRO_USTR *us2 = al_ustr_new("ī kundze"); + + CHECK(al_ustr_replace_range(us1, 2, 10, us2)); + CHECK(0 == strcmp(al_cstr(us1), "Šī kundze par visu samaksās")); + + /* Insert into itself. */ + CHECK(al_ustr_replace_range(us1, 5, 11, us1)); + CHECK(0 == strcmp(al_cstr(us1), + "Šī Šī kundze par visu samaksās par visu samaksās")); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +/* Test al_ustr_replace_range (part 2). */ +static void t45(void) +{ + ALLEGRO_USTR *us1 = al_ustr_new("abcdef"); + ALLEGRO_USTR *us2 = al_ustr_new("ABCDEF"); + + /* Start1 < 0 [not allowed] */ + CHECK(! al_ustr_replace_range(us1, -1, 1, us2)); + + /* Start1 > end(us1) [padded] */ + CHECK(al_ustr_replace_range(us1, 8, 100, us2)); + CHECK(0 == memcmp(al_cstr(us1), "abcdef\0\0ABCDEF", 15)); + + /* Start1 > end1 [not allowed] */ + CHECK(! al_ustr_replace_range(us1, 8, 1, us2)); + CHECK(0 == memcmp(al_cstr(us1), "abcdef\0\0ABCDEF", 15)); + + al_ustr_free(us1); + al_ustr_free(us2); +} + +extern bool call_vappendf(ALLEGRO_USTR *us, const char *fmt, ...); + +/* Test al_ustr_newf, al_ustr_appendf, al_ustr_vappendf. */ +static void t46(void) +{ + ALLEGRO_USTR *us; + + us = al_ustr_newf("%s %c %.2f %.02d", "hõljuk", 'c', ALLEGRO_PI, 42); + CHECK(0 == strcmp(al_cstr(us), "hõljuk c 3.14 42")); + + CHECK(al_ustr_appendf(us, " %s", "Luftchüssiboot")); + CHECK(0 == strcmp(al_cstr(us), "hõljuk c 3.14 42 Luftchüssiboot")); + + CHECK(call_vappendf(us, " %s", "χόβερκράφτ")); + CHECK(0 == strcmp(al_cstr(us), "hõljuk c 3.14 42 Luftchüssiboot χόβερκράφτ")); + + al_ustr_free(us); + + us = al_ustr_new(""); + call_vappendf(us, "%s", "test"); + CHECK(0 == strcmp(al_cstr(us), "test")); + al_ustr_free(us); +} + +bool call_vappendf(ALLEGRO_USTR *us, const char *fmt, ...) +{ + va_list ap; + bool rc; + + va_start(ap, fmt); + rc = al_ustr_vappendf(us, fmt, ap); + va_end(ap); + return rc; +} + +/* Test al_ustr_compare, al_ustr_ncompare. */ +static void t47(void) +{ + ALLEGRO_USTR_INFO i1; + ALLEGRO_USTR_INFO i2; + + CHECK(al_ustr_compare( + al_ref_cstr(&i1, "Thú mỏ vịt"), + al_ref_cstr(&i2, "Thú mỏ vịt")) == 0); + + CHECK(al_ustr_compare( + al_ref_cstr(&i1, "Thú mỏ vị"), + al_ref_cstr(&i2, "Thú mỏ vịt")) < 0); + + CHECK(al_ustr_compare( + al_ref_cstr(&i1, "Thú mỏ vịt"), + al_ref_cstr(&i2, "Thú mỏ vit")) > 0); + + CHECK(al_ustr_compare( + al_ref_cstr(&i1, "abc"), + al_ref_cstr(&i2, "abc\001")) < 0); + + CHECK(al_ustr_compare( + al_ref_cstr(&i1, "abc\001"), + al_ref_cstr(&i2, "abc")) > 0); + + CHECK(al_ustr_ncompare( + al_ref_cstr(&i1, "Thú mỏ vịt"), + al_ref_cstr(&i2, "Thú mỏ vit"), 8) == 0); + + CHECK(al_ustr_ncompare( + al_ref_cstr(&i1, "Thú mỏ vịt"), + al_ref_cstr(&i2, "Thú mỏ vit"), 9) > 0); + + CHECK(al_ustr_ncompare( + al_ref_cstr(&i1, "Thú mỏ vịt"), + al_ref_cstr(&i2, "platypus"), 0) == 0); + + CHECK(al_ustr_ncompare( + al_ref_cstr(&i1, "abc"), + al_ref_cstr(&i2, "abc\001"), 4) < 0); + + CHECK(al_ustr_ncompare( + al_ref_cstr(&i1, "abc\001"), + al_ref_cstr(&i2, "abc"), 4) > 0); + +} + +/* Test al_ustr_has_prefix, al_ustr_has_suffix. */ +static void t48(void) +{ + ALLEGRO_USTR_INFO i1; + const ALLEGRO_USTR *us1 = al_ref_cstr(&i1, "Thú mỏ vịt"); + + /* The _cstr versions are simple wrappers around the real functions so its + * okay to test them only. + */ + + CHECK(al_ustr_has_prefix_cstr(us1, "")); + CHECK(al_ustr_has_prefix_cstr(us1, "Thú")); + CHECK(! al_ustr_has_prefix_cstr(us1, "Thú mỏ vịt.")); + + CHECK(al_ustr_has_suffix_cstr(us1, "")); + CHECK(al_ustr_has_suffix_cstr(us1, "vịt")); + CHECK(! al_ustr_has_suffix_cstr(us1, "Thú mỏ vịt.")); +} + +/* Test al_ustr_find_replace, al_ustr_find_replace_cstr. */ +static void t49(void) +{ + ALLEGRO_USTR *us; + ALLEGRO_USTR_INFO findi; + ALLEGRO_USTR_INFO repli; + const ALLEGRO_USTR *find; + const ALLEGRO_USTR *repl; + + us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); + find = al_ref_cstr(&findi, "ðeéf"); + repl = al_ref_cstr(&repli, "deef"); + + CHECK(al_ustr_find_replace(us, 0, find, repl)); + CHECK(0 == strcmp(al_cstr(us), "aábddeefghiíaábddeefghií")); + + find = al_ref_cstr(&findi, "aá"); + repl = al_ref_cstr(&repli, "AÁ"); + + CHECK(al_ustr_find_replace(us, 14, find, repl)); + CHECK(0 == strcmp(al_cstr(us), "aábddeefghiíAÁbddeefghií")); + + CHECK(al_ustr_find_replace_cstr(us, 0, "dd", "đ")); + CHECK(0 == strcmp(al_cstr(us), "aábđeefghiíAÁbđeefghií")); + + /* Not allowed */ + find = al_ustr_empty_string(); + CHECK(! al_ustr_find_replace(us, 0, find, repl)); + CHECK(0 == strcmp(al_cstr(us), "aábđeefghiíAÁbđeefghií")); + + al_ustr_free(us); +} + +/* Test UTF-16 conversion. */ +static void t50(void) +{ + ALLEGRO_USTR *us; + char utf8[] = "⅛-note: 𝅘𝅥𝅮, domino: 🁡"; + uint16_t *utf16; + size_t s; + uint16_t little[8]; + /* Only native byte order supported right now, so have to specify + * elements as uint16_t and not as char. + */ + uint16_t utf16_ref[] = { + 0x215b, 0x002d, 0x006e, 0x006f, 0x0074, + 0x0065, 0x003a, 0x0020, 0xd834, 0xdd60, + 0x002c, 0x0020, 0x0064, 0x006f, 0x006d, + 0x0069, 0x006e, 0x006f, 0x003a, 0x0020, + 0xd83c, 0xdc61, 0x0000}; + uint16_t truncated[] = { + 0x215b, 0x002d, 0x006e, 0x006f, 0x0074, + 0x0065, 0x003a, 0x0000}; + + us = al_ustr_new_from_utf16(utf16_ref); + CHECK(20 == al_ustr_length(us)); + CHECK(0 == strcmp(utf8, al_cstr(us))); + al_ustr_free(us); + + us = al_ustr_new(utf8); + s = al_ustr_size_utf16(us); + CHECK(46 == s); + utf16 = malloc(s); + al_ustr_encode_utf16(us, utf16, s); + CHECK(0 == memcmp(utf16, utf16_ref, s)); + free(utf16); + + s = al_ustr_encode_utf16(us, little, sizeof little); + CHECK(16 == s); + CHECK(0 == memcmp(truncated, little, s)); + al_ustr_free(us); +} + +/* Test al_ustr_to_buffer */ +static void t51(void) +{ + char str[256]; + const ALLEGRO_USTR *us; + ALLEGRO_USTR_INFO info; + + us = al_ref_buffer(&info, "Allegro", 3); + al_ustr_to_buffer(us, str, 10); + CHECK(0 == memcmp(str, "All", 4)); + al_ustr_to_buffer(us, str, 4); + CHECK(0 == memcmp(str, "All", 4)); + al_ustr_to_buffer(us, str, 3); + CHECK(0 == memcmp(str, "Al", 3)); +} + +/*---------------------------------------------------------------------------*/ + +const test_t all_tests[] = +{ + NULL, t1, t2, t3, t4, t5, t6, t7, t8, t9, + t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, + t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, + t30, t31, t32, t33, t34, t35, t36, t37, t38, t39, + t40, t41, t42, t43, t44, t45, t46, t47, t48, t49, + t50, t51 +}; + +#define NUM_TESTS (int)(sizeof(all_tests) / sizeof(all_tests[0])) + +int main(int argc, char **argv) +{ + int i; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + open_log_monospace(); + + if (argc < 2) { + for (i = 1; i < NUM_TESTS; i++) { + log_printf("# t%d\n\n", i); + all_tests[i](); + log_printf("\n"); + } + } + else { + i = atoi(argv[1]); + if (i > 0 && i < NUM_TESTS) { + all_tests[i](); + } + } + log_printf("Done\n"); + + close_log(true); + + if (error) { + exit(EXIT_FAILURE); + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_vertex_buffer.c b/allegro/examples/ex_vertex_buffer.c new file mode 100644 index 00000000..1022f8d5 --- /dev/null +++ b/allegro/examples/ex_vertex_buffer.c @@ -0,0 +1,218 @@ +/* An example comparing different ways of drawing polygons, including usage of + * vertex buffers. + */ + +#include +#include +#include +#include + +#include "common.c" + +#define FPS 60 +#define FRAME_TAU 60 +#define NUM_VERTICES 4096 + +typedef struct METHOD METHOD; + +struct METHOD +{ + float x; + float y; + ALLEGRO_VERTEX_BUFFER *vbuff; + ALLEGRO_VERTEX *vertices; + const char *name; + int flags; + double frame_average; +}; + +static ALLEGRO_COLOR get_color(size_t ii) +{ + double t = al_get_time(); + double frac = (float)(ii) / NUM_VERTICES; + #define THETA(period) ((t / (period) + frac) * 2 * ALLEGRO_PI) + return al_map_rgb_f(sin(THETA(5.0)) / 2 + 1, cos(THETA(1.1)) / 2 + 1, sin(THETA(3.4) / 2) / 2 + 1); +} + +static void draw_method(METHOD *md, ALLEGRO_FONT *font, ALLEGRO_VERTEX* new_vertices) +{ + ALLEGRO_TRANSFORM t; + double start_time; + double new_fps; + ALLEGRO_COLOR c; + + al_identity_transform(&t); + al_translate_transform(&t, md->x, md->y); + al_use_transform(&t); + + al_draw_textf(font, al_map_rgb_f(1, 1, 1), 0, -50, ALLEGRO_ALIGN_CENTRE, "%s%s", md->name, + md->flags & ALLEGRO_PRIM_BUFFER_READWRITE ? "+read/write" : "+write-only"); + + start_time = al_get_time(); + if (md->vbuff) { + if (new_vertices) { + void* lock_mem = al_lock_vertex_buffer(md->vbuff, 0, NUM_VERTICES, ALLEGRO_LOCK_WRITEONLY); + memcpy(lock_mem, new_vertices, sizeof(ALLEGRO_VERTEX) * NUM_VERTICES); + al_unlock_vertex_buffer(md->vbuff); + } + al_draw_vertex_buffer(md->vbuff, 0, 0, NUM_VERTICES, ALLEGRO_PRIM_TRIANGLE_STRIP); + } + else if (md->vertices) { + al_draw_prim(md->vertices, 0, 0, 0, NUM_VERTICES, ALLEGRO_PRIM_TRIANGLE_STRIP); + } + + /* Force the completion of the previous commands by reading from screen */ + c = al_get_pixel(al_get_backbuffer(al_get_current_display()), 0, 0); + (void)c; + + new_fps = 1.0 / (al_get_time() - start_time); + md->frame_average += (new_fps - md->frame_average) / FRAME_TAU; + + if (md->vbuff || md->vertices) { + al_draw_textf(font, al_map_rgb_f(1, 0, 0), 0, 0, ALLEGRO_ALIGN_CENTRE, "%.1e FPS", md->frame_average); + } + else { + al_draw_text(font, al_map_rgb_f(1, 0, 0), 0, 0, ALLEGRO_ALIGN_CENTRE, "N/A"); + } + + al_identity_transform(&t); + al_use_transform(&t); +} + +int main(int argc, char **argv) +{ + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + int w = 640, h = 480; + bool done = false; + bool need_redraw = true; + bool background = false; + bool dynamic_buffers = false; + size_t num_methods; + int num_x = 3; + int num_y = 3; + int spacing_x = 200; + int spacing_y = 150; + size_t ii; + ALLEGRO_VERTEX* vertices; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + al_init_font_addon(); + al_init_primitives_addon(); + + #ifdef ALLEGRO_IPHONE + al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); + #endif + al_set_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, + ALLEGRO_DISPLAY_ORIENTATION_ALL, ALLEGRO_SUGGEST); + display = al_create_display(w, h); + if (!display) { + abort_example("Error creating display.\n"); + } + + w = al_get_display_width(display); + h = al_get_display_height(display); + + al_install_keyboard(); + + font = al_create_builtin_font(); + timer = al_create_timer(1.0 / FPS); + queue = al_create_event_queue(); + + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_display_event_source(display)); + + vertices = al_malloc(sizeof(ALLEGRO_VERTEX) * NUM_VERTICES); + al_calculate_arc(&vertices[0].x, sizeof(ALLEGRO_VERTEX), 0, 0, 80, 30, 0, 2 * ALLEGRO_PI, 10, NUM_VERTICES / 2); + for (ii = 0; ii < NUM_VERTICES; ii++) { + vertices[ii].z = 0; + vertices[ii].color = get_color(ii); + } + + { + #define GETX(n) ((w - (num_x - 1) * spacing_x) / 2 + n * spacing_x) + #define GETY(n) ((h - (num_y - 1) * spacing_y) / 2 + n * spacing_y) + + METHOD methods[] = + { + {GETX(1), GETY(0), 0, vertices, "No buffer", 0, 0}, + {GETX(0), GETY(1), 0, 0, "STREAM", ALLEGRO_PRIM_BUFFER_STREAM | ALLEGRO_PRIM_BUFFER_READWRITE, 0}, + {GETX(1), GETY(1), 0, 0, "STATIC", ALLEGRO_PRIM_BUFFER_STATIC | ALLEGRO_PRIM_BUFFER_READWRITE, 0}, + {GETX(2), GETY(1), 0, 0, "DYNAMIC", ALLEGRO_PRIM_BUFFER_STREAM | ALLEGRO_PRIM_BUFFER_READWRITE, 0}, + {GETX(0), GETY(2), 0, 0, "STREAM", ALLEGRO_PRIM_BUFFER_STREAM, 0}, + {GETX(1), GETY(2), 0, 0, "STATIC", ALLEGRO_PRIM_BUFFER_STATIC, 0}, + {GETX(2), GETY(2), 0, 0, "DYNAMIC", ALLEGRO_PRIM_BUFFER_DYNAMIC, 0} + }; + + num_methods = sizeof(methods) / sizeof(METHOD); + + for (ii = 0; ii < num_methods; ii++) { + METHOD* md = &methods[ii]; + md->frame_average = 1; + if (!md->vertices) + md->vbuff = al_create_vertex_buffer(0, vertices, NUM_VERTICES, md->flags); + } + + al_start_timer(timer); + + while (!done) { + ALLEGRO_EVENT event; + if (!background && need_redraw && al_is_event_queue_empty(queue)) { + al_clear_to_color(al_map_rgb_f(0, 0, 0.2)); + + for (ii = 0; ii < num_methods; ii++) + draw_method(&methods[ii], font, dynamic_buffers ? vertices : 0); + + al_draw_textf(font, al_map_rgb_f(1, 1, 1), 10, 10, 0, "Dynamic (D): %s", dynamic_buffers ? "yes" : "no"); + + al_flip_display(); + need_redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + else if(event.keyboard.keycode == ALLEGRO_KEY_D) + dynamic_buffers = !dynamic_buffers; + break; + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: + background = true; + al_acknowledge_drawing_halt(event.display.source); + break; + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(event.display.source); + break; + case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: + background = false; + break; + case ALLEGRO_EVENT_TIMER: + for (ii = 0; ii < NUM_VERTICES; ii++) + vertices[ii].color = get_color(ii); + need_redraw = true; + break; + } + } + + for (ii = 0; ii < num_methods; ii++) + al_destroy_vertex_buffer(methods[ii].vbuff); + + al_destroy_font(font); + al_free(vertices); + } + + return 0; +} diff --git a/allegro/examples/ex_video.c b/allegro/examples/ex_video.c new file mode 100644 index 00000000..534dfed0 --- /dev/null +++ b/allegro/examples/ex_video.c @@ -0,0 +1,259 @@ +#include +#include +#include +#include +#include + +#include + +#include "common.c" + +static ALLEGRO_DISPLAY *screen; +static ALLEGRO_FONT *font; +static char const *filename; +static float zoom = 0; + +static void video_display(ALLEGRO_VIDEO *video) +{ + /* Videos often do not use square pixels - these return the scaled dimensions + * of the video frame. + */ + float scaled_w = al_get_video_scaled_width(video); + float scaled_h = al_get_video_scaled_height(video); + /* Get the currently visible frame of the video, based on clock + * time. + */ + ALLEGRO_BITMAP *frame = al_get_video_frame(video); + int w, h, x, y; + ALLEGRO_COLOR tc = al_map_rgba_f(0, 0, 0, 0.5); + ALLEGRO_COLOR bc = al_map_rgba_f(0.5, 0.5, 0.5, 0.5); + double p; + + if (!frame) + return; + + if (zoom == 0) { + /* Always make the video fit into the window. */ + h = al_get_display_height(screen); + w = (int)(h * scaled_w / scaled_h); + if (w > al_get_display_width(screen)) { + w = al_get_display_width(screen); + h = (int)(w * scaled_h / scaled_w); + } + } + else { + w = (int)scaled_w; + h = (int)scaled_h; + } + x = (al_get_display_width(screen) - w) / 2; + y = (al_get_display_height(screen) - h) / 2; + + /* Display the frame. */ + al_draw_scaled_bitmap(frame, 0, 0, + al_get_bitmap_width(frame), + al_get_bitmap_height(frame), x, y, w, h, 0); + + /* Show some video information. */ + al_draw_filled_rounded_rectangle(4, 4, + al_get_display_width(screen) - 4, 4 + 14 * 4, 8, 8, bc); + p = al_get_video_position(video, ALLEGRO_VIDEO_POSITION_ACTUAL); + al_draw_textf(font, tc, 8, 8 , 0, "%s", filename); + al_draw_textf(font, tc, 8, 8 + 13, 0, "%3d:%02d (V: %+5.2f A: %+5.2f)", + (int)(p / 60), + ((int)p) % 60, + al_get_video_position(video, ALLEGRO_VIDEO_POSITION_VIDEO_DECODE) - p, + al_get_video_position(video, ALLEGRO_VIDEO_POSITION_AUDIO_DECODE) - p); + al_draw_textf(font, tc, 8, 8 + 13 * 2, 0, + "video rate %.02f (%dx%d, aspect %.1f) audio rate %.0f", + al_get_video_fps(video), + al_get_bitmap_width(frame), + al_get_bitmap_height(frame), + scaled_w / scaled_h, + al_get_video_audio_rate(video)); + al_draw_textf(font, tc, 8, 8 + 13 * 3, 0, + "playing: %s", al_is_video_playing(video) ? "true" : "false"); + al_flip_display(); + al_clear_to_color(al_map_rgb(0, 0, 0)); +} + + +int main(int argc, char *argv[]) +{ + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + ALLEGRO_TIMER *timer; + ALLEGRO_VIDEO *video; + bool fullscreen = false; + bool redraw = true; + bool use_frame_events = false; + int filename_arg_idx = 1; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + open_log(); + + if (argc < 2) { + log_printf("This example needs to be run from the command line.\n" + "Usage: %s [--use-frame-events] \n", argv[0]); + goto done; + } + + /* If use_frame_events is false, we use a fixed FPS timer. If the video is + * displayed in a game this probably makes most sense. In a + * dedicated video player you probably want to listen to + * ALLEGRO_EVENT_VIDEO_FRAME_SHOW events and only redraw whenever one + * arrives - to reduce possible jitter and save CPU. + */ + if (argc == 3 && strcmp(argv[1], "--use-frame-events") == 0) { + use_frame_events = true; + filename_arg_idx++; + } + + if (!al_init_video_addon()) { + abort_example("Could not initialize the video addon.\n"); + } + al_init_font_addon(); + al_install_keyboard(); + + al_install_audio(); + al_reserve_samples(1); + al_init_primitives_addon(); + + timer = al_create_timer(1.0 / 60); + + al_set_new_display_flags(ALLEGRO_RESIZABLE); + al_set_new_display_option(ALLEGRO_VSYNC, 1, ALLEGRO_SUGGEST); + screen = al_create_display(640, 480); + if (!screen) { + abort_example("Could not set video mode - exiting\n"); + } + + font = al_create_builtin_font(); + if (!font) { + abort_example("No font.\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); + + filename = argv[filename_arg_idx]; + video = al_open_video(filename); + if (!video) { + abort_example("Cannot read %s.\n", filename); + } + log_printf("video FPS: %f\n", al_get_video_fps(video)); + log_printf("video audio rate: %f\n", al_get_video_audio_rate(video)); + log_printf( + "keys:\n" + "Space: Play/Pause\n" + "cursor right/left: seek 10 seconds\n" + "cursor up/down: seek one minute\n" + "F: toggle fullscreen\n" + "1: disable scaling\n" + "S: scale to window\n"); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_video_event_source(video)); + al_register_event_source(queue, al_get_display_event_source(screen)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_keyboard_event_source()); + + al_start_video(video, al_get_default_mixer()); + al_start_timer(timer); + for (;;) { + double incr; + + if (redraw && al_event_queue_is_empty(queue)) { + video_display(video); + redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + switch (event.keyboard.keycode) { + case ALLEGRO_KEY_SPACE: + al_set_video_playing(video, !al_is_video_playing(video)); + break; + case ALLEGRO_KEY_ESCAPE: + al_close_video(video); + goto done; + break; + case ALLEGRO_KEY_LEFT: + incr = -10.0; + goto do_seek; + case ALLEGRO_KEY_RIGHT: + incr = 10.0; + goto do_seek; + case ALLEGRO_KEY_UP: + incr = 60.0; + goto do_seek; + case ALLEGRO_KEY_DOWN: + incr = -60.0; + goto do_seek; + + do_seek: + al_seek_video(video, al_get_video_position(video, ALLEGRO_VIDEO_POSITION_ACTUAL) + incr); + break; + + case ALLEGRO_KEY_F: + fullscreen = !fullscreen; + al_set_display_flag(screen, ALLEGRO_FULLSCREEN_WINDOW, + fullscreen); + break; + + case ALLEGRO_KEY_1: + zoom = 1; + break; + + case ALLEGRO_KEY_S: + zoom = 0; + break; + default: + break; + } + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(screen); + al_clear_to_color(al_map_rgb(0, 0, 0)); + break; + + case ALLEGRO_EVENT_TIMER: + /* + display_time += 1.0 / 60; + if (display_time >= video_time) { + video_time = display_time + video_refresh_timer(is); + }*/ + + if (!use_frame_events) { + redraw = true; + } + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + al_close_video(video); + goto done; + break; + + case ALLEGRO_EVENT_VIDEO_FRAME_SHOW: + if (use_frame_events) { + redraw = true; + } + break; + + case ALLEGRO_EVENT_VIDEO_FINISHED: + log_printf("video finished\n"); + break; + default: + break; + } + } +done: + al_destroy_display(screen); + close_log(true); + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_vsync.c b/allegro/examples/ex_vsync.c new file mode 100644 index 00000000..832d892d --- /dev/null +++ b/allegro/examples/ex_vsync.c @@ -0,0 +1,214 @@ +/* Tests vsync. + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_primitives.h" + +#include "common.c" + +int vsync, fullscreen, frequency, bar_width; + +static int option(ALLEGRO_CONFIG *config, char *name, int v) +{ + char const *value; + char str[256]; + value = al_get_config_value(config, "settings", name); + if (value) + v = strtol(value, NULL, 0); + sprintf(str, "%d", v); + al_set_config_value(config, "settings", name, str); + return v; +} + +static bool display_warning(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_FONT *font) +{ + ALLEGRO_EVENT event; + ALLEGRO_DISPLAY *display = al_get_current_display(); + float x = al_get_display_width(display) / 2.0; + float h = al_get_font_line_height(font); + ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1); + + for (;;) { + // Convert from 200 px on 480px high screen to same relative position + // gtiven actual display height. + float y = 5/12.0 * al_get_display_height(display); + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_draw_text(font, white, x, y, ALLEGRO_ALIGN_CENTRE, + "Do not continue if you suffer from photosensitive epilepsy"); + al_draw_text(font, white, x, y + 15, ALLEGRO_ALIGN_CENTRE, + "or simply hate sliding bars."); + al_draw_text(font, white, x, y + 40, ALLEGRO_ALIGN_CENTRE, + "Press Escape to quit or Enter to continue."); + + y += 100; + al_draw_text(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "Parameters from ex_vsync.ini:"); + y += h; + al_draw_textf(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "vsync: %d", vsync); + y += h; + al_draw_textf(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "fullscreen: %d", fullscreen); + y += h; + al_draw_textf(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "frequency: %d", frequency); + y += h; + al_draw_textf(font, white, x, y, ALLEGRO_ALIGN_CENTRE, "bar width: %d", bar_width); + + al_flip_display(); + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + return true; + } + if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { + return false; + } + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + return true; + } + } +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_FONT *font; + ALLEGRO_CONFIG *config; + ALLEGRO_EVENT_QUEUE *queue; + bool write = false; + bool quit; + bool right = true; + int bar_position = 0; + int step_size = 3; + int display_width; + int display_height; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_init_font_addon(); + al_init_primitives_addon(); + al_init_image_addon(); + al_install_keyboard(); + al_install_mouse(); + + /* Read parameters from ex_vsync.ini. */ + config = al_load_config_file("ex_vsync.ini"); + if (!config) { + config = al_create_config(); + write = true; + } + + /* 0 -> Driver chooses. + * 1 -> Force vsync on. + * 2 -> Force vsync off. + */ + vsync = option(config, "vsync", 0); + + fullscreen = option(config, "fullscreen", 0); + frequency = option(config, "frequency", 0); + bar_width = option(config, "bar_width", 10); + + /* Write the file back (so a template is generated on first run). */ + if (write) { + al_save_config_file("ex_vsync.ini", config); + } + al_destroy_config(config); + + /* Vsync 1 means force on, 2 means forced off. */ + if (vsync) + al_set_new_display_option(ALLEGRO_VSYNC, vsync, ALLEGRO_SUGGEST); + + /* Force fullscreen mode. */ + if (fullscreen) { + al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); + /* Set a monitor frequency. */ + if (frequency) + al_set_new_display_refresh_rate(frequency); + } + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display.\n"); + } + + font = al_load_font("data/a4_font.tga", 0, 0); + if (!font) { + abort_example("Failed to load a4_font.tga\n"); + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + quit = display_warning(queue, font); + al_flush_event_queue(queue); + + display_width = al_get_display_width(display); + display_height = al_get_display_height(display); + + while (!quit) { + ALLEGRO_EVENT event; + + /* With vsync, this will appear as a bar moving smoothly left to right. + * Without vsync, it will appear that there are many bars moving left to right. + * More importantly, if you view it in fullscreen, the slanting of the bar will + * appear more exaggerated as it is now much taller. + */ + if (right) { + bar_position += step_size; + } + else { + bar_position -= step_size; + } + + if (right && bar_position >= display_width - bar_width) { + bar_position = display_width - bar_width; + right = false; + } + else if (!right && bar_position <= 0) { + bar_position = 0; + right = true; + } + + al_clear_to_color(al_map_rgb(0,0,0)); + al_draw_filled_rectangle(bar_position, 0, bar_position + bar_width - 1, display_height - 1, al_map_rgb_f(1., 1., 1.)); + + + al_flip_display(); + + while (al_get_next_event(queue, &event)) { + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + quit = true; + break; + + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + quit = true; + } + } + /* Let's not go overboard and limit flipping at 1000 Hz. Without + * this my system locks up and requires a hard reboot :P + */ + /* + * Limiting this to 500hz so the bar doesn't move too fast. We're + * no longer in epilepsy mode (I hope). + */ + al_rest(.002); + } + + al_destroy_font(font); + al_destroy_event_queue(queue); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_window_constraints.c b/allegro/examples/ex_window_constraints.c new file mode 100644 index 00000000..7f2e07a6 --- /dev/null +++ b/allegro/examples/ex_window_constraints.c @@ -0,0 +1,154 @@ +/* + * Test program for Allegro. + * + * Constrains the window to a minimum and or maximum. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_image.h" +#include "allegro5/allegro_font.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_BITMAP *bmp; + ALLEGRO_FONT *f; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_EVENT event; + bool redraw; + int min_w, min_h, max_w, max_h; + int ret_min_w, ret_min_h, ret_max_w, ret_max_h; + bool constr_min_w, constr_min_h, constr_max_w, constr_max_h; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + al_init_image_addon(); + al_init_font_addon(); + + al_set_new_display_flags(ALLEGRO_RESIZABLE | + ALLEGRO_GENERATE_EXPOSE_EVENTS); + display = al_create_display(640, 480); + if (!display) { + abort_example("Unable to set any graphic mode\n"); + } + + bmp = al_load_bitmap("data/mysha.pcx"); + if (!bmp) { + abort_example("Unable to load image\n"); + } + + f = al_load_font("data/a4_font.tga", 0, 0); + if (!f) { + abort_example("Failed to load a4_font.tga\n"); + } + + min_w = 640; + min_h = 480; + max_w = 800; + max_h = 600; + constr_min_w = constr_min_h = constr_max_w = constr_max_h = true; + + if (!al_set_window_constraints( + display, + constr_min_w ? min_w : 0, + constr_min_h ? min_h : 0, + constr_max_w ? max_w : 0, + constr_max_h ? max_h : 0)) { + abort_example("Unable to set window constraints.\n"); + } + + al_apply_window_constraints(display, true); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_keyboard_event_source()); + + redraw = true; + while (true) { + if (redraw && al_is_event_queue_empty(queue)) { + al_clear_to_color(al_map_rgb(255, 0, 0)); + al_draw_scaled_bitmap(bmp, + 0, 0, al_get_bitmap_width(bmp), al_get_bitmap_height(bmp), + 0, 0, al_get_display_width(display), al_get_display_height(display), + 0); + + /* Display screen resolution */ + al_draw_textf(f, al_map_rgb(255, 255, 255), 0, 0, 0, + "Resolution: %dx%d", + al_get_display_width(display), al_get_display_height(display)); + + if (!al_get_window_constraints(display, &ret_min_w, &ret_min_h, + &ret_max_w, &ret_max_h)) + { + abort_example("Unable to get window constraints\n"); + } + + al_draw_textf(f, al_map_rgb(255, 255, 255), 0, + al_get_font_line_height(f), 0, + "Min Width: %d, Min Height: %d, Max Width: %d, Max Height: %d", + ret_min_w, ret_min_h, ret_max_w, ret_max_h); + + al_draw_textf(f, al_map_rgb(255, 255, 255), 0, + al_get_font_line_height(f) * 2,0, + "Toggle Restriction: Min Width: Z, Min Height: X, Max Width: C, Max Height: V"); + + al_flip_display(); + redraw = false; + } + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { + al_acknowledge_resize(event.display.source); + redraw = true; + } + if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) { + redraw = true; + } + if (event.type == ALLEGRO_EVENT_KEY_DOWN) { + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + else if (event.keyboard.keycode == ALLEGRO_KEY_Z) { + constr_min_w = ! constr_min_w; + } + else if (event.keyboard.keycode == ALLEGRO_KEY_X) { + constr_min_h = ! constr_min_h; + } + else if (event.keyboard.keycode == ALLEGRO_KEY_C) { + constr_max_w = ! constr_max_w; + } + else if (event.keyboard.keycode == ALLEGRO_KEY_V) { + constr_max_h = ! constr_max_h; + } + + redraw = true; + + if (!al_set_window_constraints(display, + constr_min_w ? min_w : 0, + constr_min_h ? min_h : 0, + constr_max_w ? max_w : 0, + constr_max_h ? max_h : 0)) { + abort_example("Unable to set window constraints.\n"); + } + al_apply_window_constraints(display, true); + } + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + } + + al_destroy_bitmap(bmp); + al_destroy_display(display); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_window_maximized.c b/allegro/examples/ex_window_maximized.c new file mode 100644 index 00000000..94c98145 --- /dev/null +++ b/allegro/examples/ex_window_maximized.c @@ -0,0 +1,197 @@ +/* + * ex_window_maximized.c - create the maximized, resizable window. + * Press SPACE to change constraints. + */ + +#include +#include +#include +#include +#include +#include + +#include "common.c" + + +#define DISPLAY_W 640 +#define DISPLAY_H 480 + +/* comment out to use GTK backend */ +/* #define USE_GTK */ + +static void +draw_information(ALLEGRO_DISPLAY *display, + ALLEGRO_FONT *font, ALLEGRO_COLOR color); + +static bool use_constraints; + + +extern int +main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_FONT *font; + bool done = false; + bool redraw = true; + use_constraints = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_primitives_addon()) { + abort_example("Failed to init primitives addon.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init image addon.\n"); + } + + if (!al_init_font_addon()) { + abort_example("Failed to init font addon.\n"); + } + + if (!al_init_native_dialog_addon()) { + abort_example("Failed to init native dialog addon.\n"); + } + + al_set_new_display_flags(ALLEGRO_WINDOWED +#if defined(USE_GTK) && !defined(_WIN32) + | ALLEGRO_GTK_TOPLEVEL +#endif + | ALLEGRO_RESIZABLE | ALLEGRO_MAXIMIZED + | ALLEGRO_GENERATE_EXPOSE_EVENTS); + + /* creating really small display */ + display = al_create_display(DISPLAY_W / 3, DISPLAY_H / 3); + if (!display) { + abort_example("Error creating display.\n"); + } + + /* set lower limits for constraints only */ + if(!al_set_window_constraints(display, DISPLAY_W / 2, DISPLAY_H / 2, 0, 0)) + abort_example("Unable to set window constraints.\n"); + al_apply_window_constraints(display, use_constraints); + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + + ALLEGRO_COLOR color_1 = al_map_rgb(255, 127, 0); + ALLEGRO_COLOR color_2 = al_map_rgb(0, 255, 0); + ALLEGRO_COLOR *color = &color_1; + ALLEGRO_COLOR color_text = al_map_rgb(0, 0, 0); + + font = al_create_builtin_font(); + + while (!done) { + ALLEGRO_EVENT event; + + if (redraw && al_is_event_queue_empty(queue)) { + redraw = false; + int x2 = al_get_display_width(display) - 10; + int y2 = al_get_display_height(display) - 10; + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_draw_filled_rectangle(10, 10, x2, y2, *color); + draw_information(display, font, color_text); + al_flip_display(); + } + + al_wait_for_event(queue, &event); + + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + break; + + case ALLEGRO_EVENT_KEY_UP: + if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) { + redraw = true; + + if (color == &color_1) { + if (!al_set_window_constraints(display, + 0, 0, + DISPLAY_W, DISPLAY_H)) + { + abort_example("Unable to set window constraints.\n"); + } + + color = &color_2; + } + else { + if (!al_set_window_constraints(display, + DISPLAY_W / 2, DISPLAY_H / 2, + 0, 0)) + { + abort_example("Unable to set window constraints.\n"); + } + + color = &color_1; + } + + al_apply_window_constraints(display, use_constraints); + } + else if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) { + redraw = true; + use_constraints = !use_constraints; + al_apply_window_constraints(display, use_constraints); + } + break; + + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(event.display.source); + redraw = true; + break; + + case ALLEGRO_EVENT_DISPLAY_EXPOSE: + redraw = true; + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + } /* switch (event.type) { */ + } + + al_destroy_font(font); + + return 0; +} + + +static void +draw_information(ALLEGRO_DISPLAY *display, + ALLEGRO_FONT *font, ALLEGRO_COLOR color) +{ + int min_w, min_h, max_w, max_h; + + al_draw_textf(font, color, 20, 20, 0, "Hotkeys:"); + al_draw_textf(font, color, 30, 30, 0, "enabled/disable constraints: ENTER"); + al_draw_textf(font, color, 30, 40, 0, "change constraints: SPACE"); + + al_draw_textf(font, color, 20, 50, 0, + "Resolution: %dx%d", + al_get_display_width(display), + al_get_display_height(display)); + + if (al_get_window_constraints(display, &min_w, &min_h, &max_w, &max_h)) { + al_draw_textf(font, color, 20, 60, 0, "Constraints: %s", + use_constraints ? "Enabled" : "Disabled"); + al_draw_textf(font, color, 20, 70, 0, "min_w = %d min_h = %d", + min_w, min_h); + al_draw_textf(font, color, 20, 80, 0, "max_w = %d max_h = %d", + max_w, max_h); + } +} + +/* vim: set sts=3 sw=3 et: */ + diff --git a/allegro/examples/ex_window_title.c b/allegro/examples/ex_window_title.c new file mode 100644 index 00000000..0344edae --- /dev/null +++ b/allegro/examples/ex_window_title.c @@ -0,0 +1,112 @@ +/* An example showing how to set the title of a window, by Beoran. */ + +#include +#include +#include + +#include "common.c" + +#define INTERVAL 1.0 + + +float bmp_x = 200; +float bmp_y = 200; +float bmp_dx = 96; +float bmp_dy = 96; +int bmp_flag = 0; + +#define NEW_WINDOW_TITLE "A Custom Window Title. Press space to start changing it." +#define TITLE_SIZE 256 + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_FONT *font; + int step = 0; + const char *text; + char title[TITLE_SIZE] = ""; + bool done = false; + bool redraw = true; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Failed to init Allegro.\n"); + } + + if (!al_init_image_addon()) { + abort_example("Failed to init IIO addon.\n"); + } + + al_init_font_addon(); + init_platform_specific(); + + text = NEW_WINDOW_TITLE; + + al_set_new_window_title(NEW_WINDOW_TITLE); + + display = al_create_display(640, 480); + if (!display) { + abort_example("Error creating display.\n"); + } + + if (!al_install_keyboard()) { + abort_example("Error installing keyboard.\n"); + } + + font = al_load_font("data/fixed_font.tga", 0, 0); + if (!font) { + abort_example("Error loading data/fixed_font.tga\n"); + } + + text = al_get_new_window_title(); + + timer = al_create_timer(INTERVAL); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); + al_register_event_source(queue, al_get_display_event_source(display)); + + + + while (!done) { + ALLEGRO_EVENT event; + + if (redraw && al_is_event_queue_empty(queue)) { + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_draw_text(font, al_map_rgba_f(1, 1, 1, 0.5), 0, 0, 0, text); + al_flip_display(); + redraw = false; + } + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_KEY_DOWN: + if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + done = true; + else if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) + al_start_timer(timer); + break; + + case ALLEGRO_EVENT_DISPLAY_CLOSE: + done = true; + break; + + case ALLEGRO_EVENT_TIMER: + redraw = true; + step++; + sprintf(title, "Title: %d", step); + text = title; + al_set_window_title(display, title); + break; + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/ex_windows.c b/allegro/examples/ex_windows.c new file mode 100644 index 00000000..4d54c53f --- /dev/null +++ b/allegro/examples/ex_windows.c @@ -0,0 +1,114 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" +#include "allegro5/allegro_image.h" +#include +#include + +#include "common.c" + +const int W = 100; +const int H = 100; + + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *displays[2]; + ALLEGRO_MONITOR_INFO *info; + int adapter_count; + int x, y; + ALLEGRO_FONT *myfont; + ALLEGRO_EVENT_QUEUE *events; + ALLEGRO_EVENT event; + int i; + + (void)argc; + (void)argv; + + srand(time(NULL)); + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_mouse(); + al_init_font_addon(); + al_init_image_addon(); + + adapter_count = al_get_num_video_adapters(); + + if (adapter_count == 0) { + abort_example("No adapters found!\n"); + } + + info = malloc(adapter_count * sizeof(ALLEGRO_MONITOR_INFO)); + + for (i = 0; i < adapter_count; i++) { + al_get_monitor_info(i, &info[i]); + } + + x = ((info[0].x2 - info[0].x1) / 3) - (W / 2); + y = ((info[0].y2 - info[0].y1) / 2) - (H / 2); + + al_set_new_window_position(x, y); + + displays[0] = al_create_display(W, H); + + x *= 2; + al_set_new_window_position(x, y); + + displays[1] = al_create_display(W, H); + + if (!displays[0] || !displays[1]) { + abort_example("Could not create displays.\n"); + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + myfont = al_load_font("data/fixed_font.tga", 0, 0); + if (!myfont) { + abort_example("Could not load font.\n"); + } + + events = al_create_event_queue(); + al_register_event_source(events, al_get_mouse_event_source()); + al_register_event_source(events, al_get_display_event_source(displays[0])); + al_register_event_source(events, al_get_display_event_source(displays[1])); + + for (;;) { + for (i = 0; i < 2; i++) { + al_set_target_backbuffer(displays[i]); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + if (i == 0) + al_clear_to_color(al_map_rgb(255, 0, 255)); + else + al_clear_to_color(al_map_rgb(155, 255, 0)); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + al_draw_textf(myfont, al_map_rgb(0, 0, 0), 50, 50, ALLEGRO_ALIGN_CENTRE, "Click me.."); + al_flip_display(); + } + + if (al_wait_for_event_timed(events, &event, 1)) { + if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { + break; + } + else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + int a = rand() % adapter_count; + int w = info[a].x2 - info[a].x1; + int h = info[a].y2 - info[a].y1; + int margin = 20; + x = margin + info[a].x1 + (rand() % (w - W - margin)); + y = margin + info[a].y1 + (rand() % (h - H - margin)); + al_set_window_position(event.mouse.display, x, y); + } + } + } + + al_destroy_event_queue(events); + + al_destroy_display(displays[0]); + al_destroy_display(displays[1]); + + free(info); + + return 0; +} + diff --git a/allegro/examples/ex_winfull.c b/allegro/examples/ex_winfull.c new file mode 100644 index 00000000..8cb168f4 --- /dev/null +++ b/allegro/examples/ex_winfull.c @@ -0,0 +1,69 @@ +#include "allegro5/allegro.h" + +#include "common.c" + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *win, *full; + ALLEGRO_EVENT_QUEUE *events; + ALLEGRO_EVENT event; + + (void)argc; + (void)argv; + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + + al_install_keyboard(); + + if (al_get_num_video_adapters() < 2) { + abort_example("This example requires multiple video adapters.\n"); + } + + al_set_new_display_adapter(1); + al_set_new_display_flags(ALLEGRO_WINDOWED); + win = al_create_display(640, 480); + if (!win) { + abort_example("Error creating windowed display on adapter 1 " + "(do you have multiple adapters?)\n"); + } + + al_set_new_display_adapter(0); + al_set_new_display_flags(ALLEGRO_FULLSCREEN); + full = al_create_display(640, 480); + if (!full) { + abort_example("Error creating fullscreen display on adapter 0\n"); + } + + events = al_create_event_queue(); + al_register_event_source(events, al_get_keyboard_event_source()); + + while (1) { + while (!al_is_event_queue_empty(events)) { + al_get_next_event(events, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) + goto done; + } + + al_set_target_backbuffer(full); + al_clear_to_color(al_map_rgb(rand()%255, rand()%255, rand()%255)); + al_flip_display(); + + al_set_target_backbuffer(win); + al_clear_to_color(al_map_rgb(rand()%255, rand()%255, rand()%255)); + al_flip_display(); + + al_rest(0.5); + } + +done: + al_destroy_event_queue(events); + + al_destroy_display(win); + al_destroy_display(full); + + return 0; +} + diff --git a/allegro/examples/nihgui.cpp b/allegro/examples/nihgui.cpp new file mode 100644 index 00000000..df74fa79 --- /dev/null +++ b/allegro/examples/nihgui.cpp @@ -0,0 +1,899 @@ +/* + * This is a GUI for example programs that require GUI-style interaction. + * It's intended to be as simple and transparent as possible (simplistic, + * even). + */ + +#include +#include +#include + +#define ALLEGRO_UNSTABLE +#include +#include +#include + +#include "nihgui.hpp" + +#define CLAMP(x,y,z) (std::max)(x, (std::min)(y, z)) + +namespace { + +class SaveState +{ + ALLEGRO_STATE state; + +public: + SaveState(int save=ALLEGRO_STATE_ALL) + { + al_store_state(&state, save); + } + ~SaveState() + { + al_restore_state(&state); + } +}; + +class UString +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *ustr; + +public: + UString(const ALLEGRO_USTR *s, int first, int end = -1) + { + if (end == -1) + end = al_ustr_size(s); + ustr = al_ref_ustr(&info, s, first, end); + } + + // Conversion + operator const ALLEGRO_USTR *() const + { + return ustr; + } +}; + +}; + +/*---------------------------------------------------------------------------*/ + +Theme::Theme(const ALLEGRO_FONT *font) +{ + this->bg = al_map_rgb(255, 255, 255); + this->fg = al_map_rgb(0, 0, 0); + this->highlight = al_map_rgb(128, 128, 255); + this->font = font; +} + +/*---------------------------------------------------------------------------*/ + +Widget::Widget(): + grid_x(0), + grid_y(0), + grid_w(0), + grid_h(0), + dialog(NULL), + x1(0), + y1(0), + x2(0), + y2(0), + disabled(false) +{ +} + +void Widget::configure(int xsize, int ysize, int x_padding, int y_padding) +{ + this->x1 = xsize * this->grid_x + x_padding; + this->y1 = ysize * this->grid_y + y_padding; + this->x2 = xsize * (this->grid_x + this->grid_w) - x_padding - 1; + this->y2 = ysize * (this->grid_y + this->grid_h) - y_padding - 1; +} + +bool Widget::contains(int x, int y) +{ + return (x >= this->x1 && y >= this->y1 && x <= this->x2 && y <= this->y2); +} + +/*---------------------------------------------------------------------------*/ + +Dialog::Dialog(const Theme & theme, ALLEGRO_DISPLAY *display, + int grid_m, int grid_n): + theme(theme), + display(display), + grid_m(grid_m), + grid_n(grid_n), + x_padding(1), + y_padding(1), + + draw_requested(true), + quit_requested(false), + mouse_over_widget(NULL), + mouse_down_widget(NULL), + key_widget(NULL), + + event_handler(NULL) +{ + this->event_queue = al_create_event_queue(); + al_register_event_source(this->event_queue, al_get_keyboard_event_source()); + al_register_event_source(this->event_queue, al_get_mouse_event_source()); + al_register_event_source(this->event_queue, al_get_display_event_source(display)); + if (al_is_touch_input_installed()) { + al_register_event_source(this->event_queue, + al_get_touch_input_mouse_emulation_event_source()); + } +} + +Dialog::~Dialog() +{ + this->display = NULL; + + al_destroy_event_queue(this->event_queue); + this->event_queue = NULL; +} + +void Dialog::set_padding(int x_padding, int y_padding) +{ + this->x_padding = x_padding; + this->y_padding = y_padding; +} + +void Dialog::add(Widget & widget, int grid_x, int grid_y, int grid_w, + int grid_h) +{ + widget.grid_x = grid_x; + widget.grid_y = grid_y; + widget.grid_w = grid_w; + widget.grid_h = grid_h; + + this->all_widgets.push_back(&widget); + widget.dialog = this; +} + +void Dialog::prepare() +{ + this->configure_all(); + + /* XXX this isn't working right in X. The mouse position is reported as + * (0,0) initially, until the mouse pointer is moved. + */ + ALLEGRO_MOUSE_STATE mst; + al_get_mouse_state(&mst); + this->check_mouse_over(mst.x, mst.y); +} + +void Dialog::configure_all() +{ + const int xsize = al_get_display_width(display) / this->grid_m; + const int ysize = al_get_display_height(display) / this->grid_n; + + for (std::list::iterator it = this->all_widgets.begin(); + it != this->all_widgets.end(); + ++it) + { + (*it)->configure(xsize, ysize, this->x_padding, this->y_padding); + } +} + +void Dialog::run_step(bool block) +{ + ALLEGRO_EVENT event; + + if (block) { + al_wait_for_event(event_queue, NULL); + } + + while (al_get_next_event(event_queue, &event)) { + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + this->request_quit(); + break; + + case ALLEGRO_EVENT_KEY_CHAR: + on_key_down(event.keyboard); + break; + + case ALLEGRO_EVENT_MOUSE_AXES: + on_mouse_axes(event.mouse); + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + on_mouse_button_down(event.mouse); + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + on_mouse_button_up(event.mouse); + break; + + case ALLEGRO_EVENT_DISPLAY_EXPOSE: + this->request_draw(); + break; + + default: + if (event_handler) { + event_handler->handle_event(event); + } + break; + } + } +} + +void Dialog::on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) +{ + if (event.display != this->display) { + return; + } + + // XXX think of something better when we need it + if (event.keycode == ALLEGRO_KEY_ESCAPE) { + this->request_quit(); + } + + if (this->key_widget) { + this->key_widget->on_key_down(event); + } +} + +void Dialog::on_mouse_axes(const ALLEGRO_MOUSE_EVENT & event) +{ + const int mx = event.x; + const int my = event.y; + + if (event.display != this->display) { + return; + } + + if (this->mouse_down_widget) { + this->mouse_down_widget->on_mouse_button_hold(mx, my); + return; + } + + this->check_mouse_over(mx, my); +} + +void Dialog::check_mouse_over(int mx, int my) +{ + if (this->mouse_over_widget && this->mouse_over_widget->contains(mx, my)) { + /* no change */ + return; + } + + for (std::list::iterator it = this->all_widgets.begin(); + it != this->all_widgets.end(); + ++it) + { + if ((*it)->contains(mx, my) && (*it)->want_mouse_focus()) { + this->mouse_over_widget = (*it); + this->mouse_over_widget->got_mouse_focus(); + return; + } + } + + if (this->mouse_over_widget) { + this->mouse_over_widget->lost_mouse_focus(); + this->mouse_over_widget = NULL; + } +} + +void Dialog::on_mouse_button_down(const ALLEGRO_MOUSE_EVENT & event) +{ + if (event.button != 1) + return; + + /* With touch input we may not receive mouse axes event before the touch + * so we must check which widget the touch is over. + */ + this->check_mouse_over(event.x, event.y); + if (!this->mouse_over_widget) + return; + + this->mouse_down_widget = this->mouse_over_widget; + this->mouse_down_widget->on_mouse_button_down(event.x, event.y); + + /* transfer key focus */ + if (this->mouse_down_widget != this->key_widget) { + if (this->key_widget) { + this->key_widget->lost_key_focus(); + this->key_widget = NULL; + } + if (this->mouse_down_widget->want_key_focus()) { + this->key_widget = this->mouse_down_widget; + this->key_widget->got_key_focus(); + } + } +} + +void Dialog::on_mouse_button_up(const ALLEGRO_MOUSE_EVENT & event) +{ + if (event.button != 1) + return; + if (!this->mouse_down_widget) + return; + + this->mouse_down_widget->on_mouse_button_up(event.x, event.y); + if (this->mouse_down_widget->contains(event.x, event.y)) { + this->mouse_down_widget->on_click(event.x, event.y); + } + this->mouse_down_widget = NULL; +} + +void Dialog::request_quit() +{ + this->quit_requested = true; +} + +bool Dialog::is_quit_requested() const +{ + return this->quit_requested; +} + +void Dialog::request_draw() +{ + this->draw_requested = true; +} + +bool Dialog::is_draw_requested() const +{ + return this->draw_requested; +} + +void Dialog::draw() +{ + int cx, cy, cw, ch; + al_get_clipping_rectangle(&cx, &cy, &cw, &ch); + + for (std::list::iterator it = this->all_widgets.begin(); + it != this->all_widgets.end(); + ++it) + { + Widget *wid = (*it); + al_set_clipping_rectangle(wid->x1, wid->y1, wid->width(), wid->height()); + wid->draw(); + } + + al_set_clipping_rectangle(cx, cy, cw, ch); + + this->draw_requested = false; +} + +const Theme & Dialog::get_theme() const +{ + return this->theme; +} + +void Dialog::register_event_source(ALLEGRO_EVENT_SOURCE *source) +{ + al_register_event_source(this->event_queue, source); +} + +void Dialog::set_event_handler(EventHandler *event_handler) +{ + this->event_handler = event_handler; +} + +/*---------------------------------------------------------------------------*/ + +Label::Label(std::string text, bool centred) : + text(text), + centred(centred) +{ +} + +void Label::draw() +{ + const Theme & theme = this->dialog->get_theme(); + SaveState state; + ALLEGRO_COLOR fg = theme.fg; + + if (is_disabled()) { + fg = al_map_rgb(64, 64, 64); + } + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + if (centred) { + al_draw_text(theme.font, fg, (this->x1 + this->x2 + 1)/2, + this->y1, ALLEGRO_ALIGN_CENTRE, this->text.c_str()); + } + else { + al_draw_text(theme.font, fg, this->x1, this->y1, 0, this->text.c_str()); + } +} + +void Label::set_text(std::string new_text) +{ + this->text = new_text; +} + +bool Label::want_mouse_focus() +{ + return false; +} + +/*---------------------------------------------------------------------------*/ + +Button::Button(std::string text): + text(text), + pushed(false) +{ +} + +void Button::on_mouse_button_down(int mx, int my) +{ + (void)mx; + (void)my; + + if (is_disabled()) + return; + + this->pushed = true; + dialog->request_draw(); +} + +void Button::on_mouse_button_up(int mx, int my) +{ + (void)mx; + (void)my; + + if (is_disabled()) + return; + + this->pushed = false; + dialog->request_draw(); +} + +void Button::draw() +{ + const Theme & theme = this->dialog->get_theme(); + ALLEGRO_COLOR fg; + ALLEGRO_COLOR bg; + SaveState state; + double y; + + if (this->pushed) { + fg = theme.bg; + bg = theme.fg; + } + else { + fg = theme.fg; + bg = theme.bg; + } + + if (is_disabled()) { + bg = al_map_rgb(64, 64, 64); + } + + al_draw_filled_rectangle(this->x1, this->y1, + this->x2, this->y2, bg); + al_draw_rectangle(this->x1 + 0.5, this->y1 + 0.5, + this->x2 - 0.5, this->y2 - 0.5, fg, 0); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + /* Center the text vertically in the button, taking the font size + * into consideration. + */ + y = (this->y1 + this->y2 - al_get_font_line_height(theme.font) - 1) / 2; + + al_draw_text(theme.font, fg, (this->x1 + this->x2 + 1)/2, + y, ALLEGRO_ALIGN_CENTRE, this->text.c_str()); +} + +bool Button::get_pushed() +{ + return pushed; +} + +/*---------------------------------------------------------------------------*/ + +ToggleButton::ToggleButton(std::string text) : + Button(text) +{ +} + +void ToggleButton::on_mouse_button_down(int mx, int my) +{ + (void)mx; + (void)my; + + if (is_disabled()) + return; + + set_pushed(!this->pushed); +} + +void ToggleButton::on_mouse_button_up(int mx, int my) +{ + (void)mx; + (void)my; + + if (is_disabled()) + return; +} + +void ToggleButton::set_pushed(bool pushed) +{ + if (this->pushed != pushed) { + this->pushed = pushed; + if (dialog) + dialog->request_draw(); + } +} + +/*---------------------------------------------------------------------------*/ + +const std::string List::empty_string; + +List::List(int initial_selection) : + selected_item(initial_selection) +{ +} + +bool List::want_key_focus() +{ + return !is_disabled(); +} + +void List::on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) +{ + if (is_disabled()) + return; + + switch (event.keycode) { + case ALLEGRO_KEY_DOWN: + if (selected_item < items.size() - 1) { + selected_item++; + dialog->request_draw(); + } + break; + + case ALLEGRO_KEY_UP: + if (selected_item > 0) { + selected_item--; + dialog->request_draw(); + } + break; + } +} + +void List::on_click(int mx, int my) +{ + if (is_disabled()) + return; + + const Theme & theme = dialog->get_theme(); + unsigned int i = (my - this->y1) / al_get_font_line_height(theme.font); + if (i < this->items.size()) { + this->selected_item = i; + dialog->request_draw(); + } + + (void)mx; + (void)my; +} + +void List::draw() +{ + const Theme & theme = dialog->get_theme(); + SaveState state; + ALLEGRO_COLOR bg = theme.bg; + + if (is_disabled()) { + bg = al_map_rgb(64, 64, 64); + } + + al_draw_filled_rectangle(x1 + 1, y1 + 1, x2 - 1, y2 - 1, bg); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + const int font_height = al_get_font_line_height(theme.font); + for (unsigned i = 0; i < items.size(); i++) { + int yi = y1 + i * font_height; + + if (i == selected_item) { + al_draw_filled_rectangle(x1 + 1, yi, x2 - 1, yi + font_height - 1, + theme.highlight); + } + + al_draw_text(theme.font, theme.fg, x1, yi, 0, items.at(i).c_str()); + } +} + +void List::clear_items() +{ + this->items.clear(); + this->selected_item = 0; +} + +void List::append_item(std::string text) +{ + this->items.push_back(text); +} + +const std::string & List::get_selected_item_text() const +{ + if (this->selected_item < this->items.size()) + return this->items.at(this->selected_item); + else + return List::empty_string; +} + +int List::get_cur_value() const +{ + return this->selected_item; +} + +/*---------------------------------------------------------------------------*/ + +VSlider::VSlider(int cur_value, int max_value) : + cur_value(cur_value), + max_value(max_value) +{ +} + +void VSlider::on_mouse_button_down(int mx, int my) +{ + if (is_disabled()) + return; + + this->on_mouse_button_hold(mx, my); +} + +void VSlider::on_mouse_button_hold(int mx, int my) +{ + if (is_disabled()) + return; + + double r = (double) (this->y2 - 1 - my) / (this->height() - 2); + r = CLAMP(0.0, r, 1.0); + cur_value = (int) (r * max_value); + dialog->request_draw(); + + (void)mx; +} + +void VSlider::draw() +{ + const Theme & theme = dialog->get_theme(); + ALLEGRO_COLOR bg = theme.fg; + float left = x1 + 0.5, top = y1 + 0.5; + float right = x2 + 0.5, bottom = y2 + 0.5; + SaveState state; + + if (is_disabled()) { + bg = al_map_rgb(64, 64, 64); + } + + al_draw_rectangle(left, top, right, bottom, bg, 1); + + double ratio = (double) this->cur_value / (double) this->max_value; + int ypos = (int) (bottom - 0.5 - (int) (ratio * (height() - 7))); + al_draw_filled_rectangle(left + 0.5, ypos - 5, right - 0.5, ypos, theme.fg); +} + +int VSlider::get_cur_value() const +{ + return this->cur_value; +} + +int VSlider::get_max_value() const +{ + return this->max_value; +} + +void VSlider::set_cur_value(int v) +{ + this->cur_value = v; +} + +/*---------------------------------------------------------------------------*/ + +HSlider::HSlider(int cur_value, int max_value) : + cur_value(cur_value), + max_value(max_value) +{ +} + +void HSlider::on_mouse_button_down(int mx, int my) +{ + if (is_disabled()) + return; + + this->on_mouse_button_hold(mx, my); +} + +void HSlider::on_mouse_button_hold(int mx, int my) +{ + if (is_disabled()) + return; + + double r = (double) (mx - 1 - this->x1) / (this->width() - 2); + r = CLAMP(0.0, r, 1.0); + cur_value = (int) (r * max_value); + dialog->request_draw(); + + (void)my; +} + +void HSlider::draw() +{ + const Theme & theme = dialog->get_theme(); + const int cy = (y1 + y2) / 2; + SaveState state; + ALLEGRO_COLOR bg = theme.bg; + + if (is_disabled()) { + bg = al_map_rgb(64, 64, 64); + } + + al_draw_filled_rectangle(x1, y1, x2, y2, bg); + al_draw_line(x1, cy, x2, cy, theme.fg, 0); + + double ratio = (double) this->cur_value / (double) this->max_value; + int xpos = x1 + (int) (ratio * (width() - 2)); + al_draw_filled_rectangle(xpos - 2, y1, xpos + 2, y2, theme.fg); +} + +int HSlider::get_cur_value() const +{ + return this->cur_value; +} + +int HSlider::get_max_value() const +{ + return this->max_value; +} + +void HSlider::set_cur_value(int v) +{ + this->cur_value = v; +} + +/*---------------------------------------------------------------------------*/ + +TextEntry::TextEntry(const char *initial_text) : + focused(false), + cursor_pos(0), + left_pos(0) +{ + text = al_ustr_new(initial_text); +} + +TextEntry::~TextEntry() +{ + al_ustr_free(text); +} + +bool TextEntry::want_key_focus() +{ + return !is_disabled(); +} + +void TextEntry::got_key_focus() +{ + this->focused = true; + dialog->request_draw(); +} + +void TextEntry::lost_key_focus() +{ + this->focused = false; + dialog->request_draw(); +} + +void TextEntry::on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) +{ + if (is_disabled()) + return; + + switch (event.keycode) { + case ALLEGRO_KEY_LEFT: + al_ustr_prev(text, &cursor_pos); + break; + + case ALLEGRO_KEY_RIGHT: + al_ustr_next(text, &cursor_pos); + break; + + case ALLEGRO_KEY_HOME: + cursor_pos = 0; + break; + + case ALLEGRO_KEY_END: + cursor_pos = al_ustr_size(text); + break; + + case ALLEGRO_KEY_DELETE: + al_ustr_remove_chr(text, cursor_pos); + break; + + case ALLEGRO_KEY_BACKSPACE: + if (al_ustr_prev(text, &cursor_pos)) + al_ustr_remove_chr(text, cursor_pos); + break; + + default: + if (event.unichar >= ' ') { + al_ustr_insert_chr(text, cursor_pos, event.unichar); + cursor_pos += al_utf8_width(event.unichar); + } + break; + } + + maybe_scroll(); + dialog->request_draw(); +} + +void TextEntry::maybe_scroll() +{ + const Theme & theme = dialog->get_theme(); + + if (cursor_pos < left_pos + 3) { + if (cursor_pos < 3) + left_pos = 0; + else + left_pos = cursor_pos - 3; + } + else { + for (;;) { + const int tw = al_get_ustr_width(theme.font, + UString(text, left_pos, cursor_pos)); + if (x1 + tw + CURSOR_WIDTH < x2) { + break; + } + al_ustr_next(text, &left_pos); + } + } +} + +void TextEntry::draw() +{ + const Theme & theme = dialog->get_theme(); + SaveState state; + ALLEGRO_COLOR bg = theme.bg; + + if (is_disabled()) { + bg = al_map_rgb(64, 64, 64); + } + + al_draw_filled_rectangle(x1, y1, x2, y2, bg); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + if (!focused) { + al_draw_ustr(theme.font, theme.fg, x1, y1, 0, UString(text, left_pos)); + } + else { + int x = x1; + + if (cursor_pos > 0) { + UString sub(text, left_pos, cursor_pos); + al_draw_ustr(theme.font, theme.fg, x1, y1, 0, sub); + x += al_get_ustr_width(theme.font, sub); + } + + if ((unsigned) cursor_pos == al_ustr_size(text)) { + al_draw_filled_rectangle(x, y1, x + CURSOR_WIDTH, + y1 + al_get_font_line_height(theme.font), theme.fg); + } + else { + int post_cursor = cursor_pos; + al_ustr_next(text, &post_cursor); + + UString sub(text, cursor_pos, post_cursor); + int subw = al_get_ustr_width(theme.font, sub); + al_draw_filled_rectangle(x, y1, x + subw, + y1 + al_get_font_line_height(theme.font), theme.fg); + al_draw_ustr(theme.font, theme.bg, x, y1, 0, sub); + x += subw; + + al_draw_ustr(theme.font, theme.fg, x, y1, 0, + UString(text, post_cursor)); + } + } +} + +const char *TextEntry::get_text() +{ + return al_cstr(text); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/examples/nihgui.hpp b/allegro/examples/nihgui.hpp new file mode 100644 index 00000000..e4a2201f --- /dev/null +++ b/allegro/examples/nihgui.hpp @@ -0,0 +1,245 @@ +#ifndef __included_nihgui_hpp +#define __included_nihgui_hpp + +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_font.h" + +class Theme; +class Dialog; +class Widget; + +class Theme { +public: + ALLEGRO_COLOR bg; + ALLEGRO_COLOR fg; + ALLEGRO_COLOR highlight; + const ALLEGRO_FONT *font; + + // Null font is fine if you don't use a widget that requires text. + explicit Theme(const ALLEGRO_FONT *font=NULL); +}; + +class Widget { +private: + int grid_x; + int grid_y; + int grid_w; + int grid_h; + +protected: + Dialog *dialog; + int x1; + int y1; + int x2; + int y2; + bool disabled; + +public: + Widget(); + virtual ~Widget() {} + + void configure(int xsize, int ysize, + int x_padding, int y_padding); + virtual bool contains(int x, int y); + unsigned int width() { return x2 - x1 + 1; } + unsigned int height() { return y2 - y1 + 1; } + + virtual bool want_mouse_focus() { return true; } + virtual void got_mouse_focus() {} + virtual void lost_mouse_focus() {} + virtual void on_mouse_button_down(int mx, int my) { (void)mx; (void)my; } + virtual void on_mouse_button_hold(int mx, int my) { (void)mx; (void)my; } + virtual void on_mouse_button_up(int mx, int my) { (void)mx; (void)my; } + virtual void on_click(int mx, int my) { (void)mx; (void)my; } + + virtual bool want_key_focus() { return false; } + virtual void got_key_focus() {} + virtual void lost_key_focus() {} + virtual void on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) { + (void)event; } + + virtual void draw() = 0; + virtual void set_disabled(bool value) { disabled = value; } + virtual bool is_disabled() { return disabled; } + + friend class Dialog; +}; + +class EventHandler { +public: + virtual ~EventHandler() {} + virtual void handle_event(const ALLEGRO_EVENT & event) = 0; +}; + +class Dialog { +private: + const Theme & theme; + ALLEGRO_DISPLAY * display; + ALLEGRO_EVENT_QUEUE *event_queue; + int grid_m; + int grid_n; + int x_padding; + int y_padding; + + bool draw_requested; + bool quit_requested; + + std::list all_widgets; + Widget * mouse_over_widget; + Widget * mouse_down_widget; + Widget * key_widget; + + EventHandler * event_handler; + +public: + Dialog(const Theme & theme, ALLEGRO_DISPLAY *display, + int grid_m, int grid_n); + ~Dialog(); + + void set_padding(int x_padding, int y_padding); + void add(Widget & widget, int grid_x, int grid_y, + int grid_w, int grid_h); + void prepare(); + void run_step(bool block); + void request_quit(); + bool is_quit_requested() const; + void request_draw(); + bool is_draw_requested() const; + void draw(); + const Theme & get_theme() const; + + void register_event_source(ALLEGRO_EVENT_SOURCE *source); + void set_event_handler(EventHandler *handler); + +private: + void configure_all(); + void on_key_down(const ALLEGRO_KEYBOARD_EVENT & event); + void on_mouse_axes(const ALLEGRO_MOUSE_EVENT & event); + void check_mouse_over(int mx, int my); + void on_mouse_button_down(const ALLEGRO_MOUSE_EVENT & event); + void on_mouse_button_up(const ALLEGRO_MOUSE_EVENT & event); +}; + +/*---------------------------------------------------------------------------*/ + +class Label : public Widget { +private: + std::string text; + bool centred; + +public: + Label(std::string text="", bool centred=true); + void set_text(std::string text); + virtual void draw(); + virtual bool want_mouse_focus(); +}; + +class Button : public Widget { +protected: + std::string text; + bool pushed; + +public: + explicit Button(std::string text); + virtual void on_mouse_button_down(int mx, int my); + virtual void on_mouse_button_up(int mx, int my); + virtual void draw(); + + bool get_pushed(); +}; + +class ToggleButton : public Button { +public: + explicit ToggleButton(std::string text); + virtual void on_mouse_button_down(int mx, int my); + virtual void on_mouse_button_up(int mx, int my); + + void set_pushed(bool pushed); +}; + +class List : public Widget { +private: + static const std::string empty_string; + + std::vector items; + unsigned int selected_item; + +public: + List(int initial_selection = 0); + virtual bool want_key_focus(); + virtual void on_key_down(const ALLEGRO_KEYBOARD_EVENT & event); + virtual void on_click(int mx, int my); + virtual void draw(); + + void clear_items(); + void append_item(std::string text); + const std::string & get_selected_item_text() const; + int get_cur_value() const; +}; + +class VSlider : public Widget { +private: + int cur_value; + int max_value; + +public: + VSlider(int cur_value = 0, int max_value = 1); + + virtual void on_mouse_button_down(int mx, int my); + virtual void on_mouse_button_hold(int mx, int my); + virtual void draw(); + + int get_max_value() const; + int get_cur_value() const; + void set_cur_value(int v); +}; + +class HSlider : public Widget { +private: + int cur_value; + int max_value; + +public: + HSlider(int cur_value = 0, int max_value = 1); + + virtual void on_mouse_button_down(int mx, int my); + virtual void on_mouse_button_hold(int mx, int my); + virtual void draw(); + + int get_max_value() const; + int get_cur_value() const; + void set_cur_value(int v); +}; + +class TextEntry : public Widget { +private: + static const int CURSOR_WIDTH = 8; + + ALLEGRO_USTR *text; + bool focused; + int cursor_pos; + int left_pos; + +public: + explicit TextEntry(const char *initial_text=""); + ~TextEntry(); + + virtual bool want_key_focus(); + virtual void got_key_focus(); + virtual void lost_key_focus(); + virtual void on_key_down(const ALLEGRO_KEYBOARD_EVENT & event); + virtual void draw(); + + const char * get_text(); + +private: + void maybe_scroll(); +}; + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/alcompat.h b/allegro/include/allegro5/alcompat.h new file mode 100644 index 00000000..e0f6cef3 --- /dev/null +++ b/allegro/include/allegro5/alcompat.h @@ -0,0 +1,24 @@ +#ifndef __al_included_allegro5_alcompat_h +#define __al_included_allegro5_alcompat_h + +#ifdef __cplusplus + extern "C" { +#endif + + +#define ALLEGRO_DST_COLOR (ALLEGRO_DEST_COLOR) +#define ALLEGRO_INVERSE_DST_COLOR (ALLEGRO_INVERSE_DEST_COLOR) + +#define al_convert_bitmaps() (al_convert_memory_bitmaps()) +#define al_current_time() (al_get_time()) +#define al_event_queue_is_empty(q) (al_is_event_queue_empty(q)) +#define al_toggle_display_flag(d, f, o) (al_set_display_flag((d), (f), (o))) + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/allegro.h b/allegro/include/allegro5/allegro.h new file mode 100644 index 00000000..06d40987 --- /dev/null +++ b/allegro/include/allegro5/allegro.h @@ -0,0 +1,79 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Main header file for the entire Allegro library. + * (separate modules can be included from the allegro/ directory) + * + * By Shawn Hargreaves. + * + * Vincent Penquerc'h split the original allegro.h into separate headers. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_allegro_h +#define __al_included_allegro5_allegro_h + + +#include "allegro5/base.h" + +#include "allegro5/altime.h" +#include "allegro5/bitmap.h" +#include "allegro5/bitmap_draw.h" +#include "allegro5/bitmap_io.h" +#include "allegro5/bitmap_lock.h" +#include "allegro5/blender.h" +#include "allegro5/clipboard.h" +#include "allegro5/color.h" +#include "allegro5/config.h" +#include "allegro5/cpu.h" +#include "allegro5/debug.h" +#include "allegro5/display.h" +#include "allegro5/drawing.h" +#include "allegro5/error.h" +#include "allegro5/events.h" +#include "allegro5/file.h" +#include "allegro5/fixed.h" +#include "allegro5/fmaths.h" +#include "allegro5/fshook.h" +#include "allegro5/fullscreen_mode.h" +#include "allegro5/haptic.h" +#include "allegro5/joystick.h" +#include "allegro5/keyboard.h" +#include "allegro5/memory.h" +#include "allegro5/monitor.h" +#include "allegro5/mouse.h" +#include "allegro5/mouse_cursor.h" +#include "allegro5/path.h" +#include "allegro5/render_state.h" +#include "allegro5/shader.h" +#include "allegro5/system.h" +#include "allegro5/threads.h" +#include "allegro5/timer.h" +#include "allegro5/tls.h" +#include "allegro5/touch_input.h" +#include "allegro5/transformations.h" +#include "allegro5/utf8.h" + + +#ifndef ALLEGRO_NO_COMPATIBILITY + #include "allegro5/alcompat.h" +#endif + + +#ifdef ALLEGRO_EXTRA_HEADER + #include ALLEGRO_EXTRA_HEADER +#endif + + +#endif + + diff --git a/allegro/include/allegro5/allegro5.h b/allegro/include/allegro5/allegro5.h new file mode 100644 index 00000000..8e604c69 --- /dev/null +++ b/allegro/include/allegro5/allegro5.h @@ -0,0 +1,2 @@ +#include "allegro.h" + diff --git a/allegro/include/allegro5/allegro_android.h b/allegro/include/allegro5/allegro_android.h new file mode 100644 index 00000000..e8cf5c94 --- /dev/null +++ b/allegro/include/allegro5/allegro_android.h @@ -0,0 +1,41 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + */ + + +#ifndef A5_ANDROID_ALLEGRO_H +#define A5_ANDROID_ALLEGRO_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Public android-related API + */ +void al_android_set_apk_file_interface(void); +const char *al_android_get_os_version(void); +void al_android_set_apk_fs_interface(void); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +JNIEnv *al_android_get_jni_env(void); +jobject al_android_get_activity(void); +#endif + +/* XXX decide if this should be public */ +void _al_android_set_capture_volume_keys(ALLEGRO_DISPLAY *display, bool onoff); + +#ifdef __cplusplus + } +#endif + +#endif /* A5_ANDROID_ALLEGRO_H */ diff --git a/allegro/include/allegro5/allegro_direct3d.h b/allegro/include/allegro5/allegro_direct3d.h new file mode 100644 index 00000000..5bab70a0 --- /dev/null +++ b/allegro/include/allegro5/allegro_direct3d.h @@ -0,0 +1,54 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Header file for Direct3D specific API. + * + * By Milan Mimica. + * + */ + +#ifndef __al_included_allegro5_allegro_direct3d_h +#define __al_included_allegro5_allegro_direct3d_h + +#include +#if defined ALLEGRO_CFG_D3DX9 && defined __cplusplus +#include +#endif +#include "allegro5/platform/alplatf.h" + +/* Display creation flag. */ +#define ALLEGRO_DIRECT3D ALLEGRO_DIRECT3D_INTERNAL + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Public Direct3D-related API + */ + +AL_FUNC(LPDIRECT3DDEVICE9, al_get_d3d_device, (ALLEGRO_DISPLAY *)); +AL_FUNC(LPDIRECT3DTEXTURE9, al_get_d3d_system_texture, (ALLEGRO_BITMAP *)); +AL_FUNC(LPDIRECT3DTEXTURE9, al_get_d3d_video_texture, (ALLEGRO_BITMAP *)); +AL_FUNC(bool, al_have_d3d_non_pow2_texture_support, (void)); +AL_FUNC(bool, al_have_d3d_non_square_texture_support, (void)); +AL_FUNC(void, al_get_d3d_texture_position, (ALLEGRO_BITMAP *bitmap, int *u, int *v)); +AL_FUNC(bool, al_get_d3d_texture_size, (ALLEGRO_BITMAP *bitmap, int *width, int *height)); +AL_FUNC(bool, al_is_d3d_device_lost, (ALLEGRO_DISPLAY *display)); +AL_FUNC(void, al_set_d3d_device_release_callback, (void (*callback)(ALLEGRO_DISPLAY *display))); +AL_FUNC(void, al_set_d3d_device_restore_callback, (void (*callback)(ALLEGRO_DISPLAY *display))); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/allegro_iphone.h b/allegro/include/allegro5/allegro_iphone.h new file mode 100644 index 00000000..eebf41e0 --- /dev/null +++ b/allegro/include/allegro5/allegro_iphone.h @@ -0,0 +1,40 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + */ + + +#ifndef A5_IPHONE_ALLEGRO_H +#define A5_IPHONE_ALLEGRO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Public iPhone-related API + */ + +enum ALLEGRO_IPHONE_STATUSBAR_ORIENTATION { + ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT = 0, + ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT_UPSIDE_DOWN, + ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_RIGHT, + ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_LEFT +}; + +AL_FUNC(void, al_iphone_set_statusbar_orientation, (int orientation)); +AL_FUNC(double, al_iphone_get_last_shake_time, (void)); +AL_FUNC(float, al_iphone_get_battery_level, (void)); + +#ifdef __cplusplus + } +#endif + +#endif /* A5_IPONE_ALLEGRO_H */ diff --git a/allegro/include/allegro5/allegro_iphone_objc.h b/allegro/include/allegro5/allegro_iphone_objc.h new file mode 100644 index 00000000..f405e70a --- /dev/null +++ b/allegro/include/allegro5/allegro_iphone_objc.h @@ -0,0 +1,32 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + */ + + +#ifndef A5_IPHONE_ALLEGRO_OBJC_H +#define A5_IPHONE_ALLEGRO_OBJC_H + +/* + * Public Objective-C iPhone-related API + */ + +#ifdef __cplusplus +extern "C" { +#endif + +AL_FUNC(UIWindow *, al_iphone_get_window, (ALLEGRO_DISPLAY *d)); +AL_FUNC(UIView *, al_iphone_get_view, (ALLEGRO_DISPLAY *d)); + +#ifdef __cplusplus +} +#endif + +#endif /* A5_IPHONE_ALLEGRO_OBJC_H */ diff --git a/allegro/include/allegro5/allegro_opengl.h b/allegro/include/allegro5/allegro_opengl.h new file mode 100644 index 00000000..f8646c38 --- /dev/null +++ b/allegro/include/allegro5/allegro_opengl.h @@ -0,0 +1,209 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Main header file for all OpenGL drivers. + * + * By Milan Mimica. + * + */ + + +#ifndef __al_included_allegro5_allegro_opengl_h +#define __al_included_allegro5_allegro_opengl_h + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(ALLEGRO_WINDOWS) +#include +#endif + +#if defined ALLEGRO_IPHONE + +#ifdef ALLEGRO_CFG_OPENGLES1 +#include +#include +#elif defined(ALLEGRO_CFG_OPENGLES3) +#include +#include +#elif defined(ALLEGRO_CFG_OPENGLES2) +#include +#include +#endif + +#ifdef ALLEGRO_CFG_OPENGLES1 +/* Apple defines OES versions for these - however the separated alpha ones + * don't seem to work on the device and just crash. + */ +#define glBlendEquation glBlendEquationOES +#define glBlendFuncSeparate glBlendFuncSeparateOES +#define glBlendEquationSeparate glBlendEquationSeparateOES +#define glRenderbufferStorageMultisampleEXT glRenderbufferStorageMultisampleAPPLE +#ifdef GL_FUNC_ADD +#undef GL_FUNC_ADD +#undef GL_FUNC_SUBTRACT +#undef GL_FUNC_REVERSE_SUBTRACT +#endif +#define GL_FUNC_ADD GL_FUNC_ADD_OES +#define GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_OES +#define GL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT_OES + +#elif defined(ALLEGRO_CFG_OPENGLES3) + +#define glRenderbufferStorageMultisampleEXT glRenderbufferStorageMultisample + +#endif + +#elif defined(ALLEGRO_MACOSX) + +#include +#include +#include + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +#elif defined(ALLEGRO_CFG_OPENGLES1) + +#include +#include + +#define GL_FUNC_ADD GL_FUNC_ADD_OES +#define GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_OES +#define GL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT_OES + +#define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_OES +#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES +#define GL_RENDERBUFFER_EXT GL_RENDERBUFFER_OES +#define glBlendEquation glBlendEquationOES +#define glBlendFuncSeparate glBlendFuncSeparateOES +#define glBlendEquationSeparate glBlendEquationSeparateOES +#define glGenerateMipmapEXT glGenerateMipmapOES +#define glBindFramebufferEXT glBindFramebufferOES +#define glDeleteFramebuffersEXT glDeleteFramebuffersOES +#define GL_DEPTH_COMPONENT16 GL_DEPTH_COMPONENT16_OES +#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES +#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES +#define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES + +#elif defined(ALLEGRO_CFG_OPENGLES3) + +#include +#include + +// TODO: should defines from GLES2 be there as well? +// TODO: Also, how does it relate to src/opengl/ogl_helpers.h ? + +#define glRenderbufferStorageMultisampleEXT glRenderbufferStorageMultisample + +#elif defined(ALLEGRO_CFG_OPENGLES2) + +#include +#include + +#define GL_RGBA8 GL_RGBA8_OES + +#define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING +#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER +#define glGenerateMipmapEXT glGenerateMipmap +#define glBindFramebufferEXT glBindFramebuffer +#define glDeleteFramebuffersEXT glDeleteFramebuffers + +#else + +/* HACK: Prevent both Mesa and SGI's broken headers from screwing us */ +#define __glext_h_ +#define __gl_glext_h_ +#define __glxext_h_ +#define __glx_glxext_h_ +#include +#undef __glext_h_ +#undef __gl_glext_h_ +#undef __glxext_h_ +#undef __glx_glxext_h_ + +#endif + +#ifdef ALLEGRO_RASPBERRYPI +#include +#include +#endif + +#include "allegro5/bitmap.h" +#include "allegro5/display.h" +#include "allegro5/shader.h" +#include "allegro5/opengl/gl_ext.h" + +#ifdef ALLEGRO_WINDOWS + +/* Missing #defines from Mingw */ +#ifndef PFD_SWAP_LAYER_BUFFERS +#define PFD_SWAP_LAYER_BUFFERS 0x00000800 +#endif + +#ifndef PFD_GENERIC_ACCELERATED +#define PFD_GENERIC_ACCELERATED 0x00001000 +#endif + +#ifndef PFD_SUPPORT_DIRECTDRAW +#define PFD_SUPPORT_DIRECTDRAW 0x00002000 +#endif + +#ifndef CDS_FULLSCREEN +#define CDS_FULLSCREEN 0x00000004 +#endif + +#ifndef ENUM_CURRENT_SETTINGS +#define ENUM_CURRENT_SETTINGS ((DWORD)-1) +#endif + +#endif /* ALLEGRO_WINDOWS */ + +#if defined ALLEGRO_WINDOWS + #define ALLEGRO_DEFINE_PROC_TYPE(type, name, args) \ + typedef type (APIENTRY * name) args; +#else + #define ALLEGRO_DEFINE_PROC_TYPE(type, name, args) \ + typedef type (*name) args; +#endif + +/* + * Public OpenGL-related API + */ + +/* ALLEGRO_OPENGL_VARIANT + */ +typedef enum ALLEGRO_OPENGL_VARIANT { + ALLEGRO_DESKTOP_OPENGL = 0, + ALLEGRO_OPENGL_ES +} ALLEGRO_OPENGL_VARIANT; + +AL_FUNC(uint32_t, al_get_opengl_version, (void)); +AL_FUNC(bool, al_have_opengl_extension, (const char *extension)); +AL_FUNC(void*, al_get_opengl_proc_address, (const char *name)); +AL_FUNC(ALLEGRO_OGL_EXT_LIST*, al_get_opengl_extension_list, (void)); +AL_FUNC(GLuint, al_get_opengl_texture, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_remove_opengl_fbo, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(GLuint, al_get_opengl_fbo, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(bool, al_get_opengl_texture_size, (ALLEGRO_BITMAP *bitmap, + int *w, int *h)); +AL_FUNC(void, al_get_opengl_texture_position, (ALLEGRO_BITMAP *bitmap, + int *u, int *v)); +AL_FUNC(GLuint, al_get_opengl_program_object, (ALLEGRO_SHADER *shader)); +AL_FUNC(void, al_set_current_opengl_context, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_opengl_variant, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/allegro_osx.h b/allegro/include/allegro5/allegro_osx.h new file mode 100644 index 00000000..abbe2091 --- /dev/null +++ b/allegro/include/allegro5/allegro_osx.h @@ -0,0 +1,30 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + */ + + +#ifndef A5_OSX_ALLEGRO_H +#define A5_OSX_ALLEGRO_H + +/* + * Public Objective-C OSX-related API + */ +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(NSWindow *, al_osx_get_window, (ALLEGRO_DISPLAY *d)); + +#ifdef __cplusplus + } +#endif + +#endif /* A5_OSX_ALLEGRO_H */ diff --git a/allegro/include/allegro5/allegro_windows.h b/allegro/include/allegro5/allegro_windows.h new file mode 100644 index 00000000..f87d4754 --- /dev/null +++ b/allegro/include/allegro5/allegro_windows.h @@ -0,0 +1,44 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Header file for Windows specific API. + * + * By Trent Gamblin. + * + */ + +#ifndef __al_included_allegro5_allegro_windows_h +#define __al_included_allegro5_allegro_windows_h + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Public Windows-related API + */ + +AL_FUNC(HWND, al_get_win_window_handle, (ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_win_add_window_callback, (ALLEGRO_DISPLAY *display, + bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam, + LPARAM lparam, LRESULT *result, void *userdata), void *userdata)); +AL_FUNC(bool, al_win_remove_window_callback, (ALLEGRO_DISPLAY *display, + bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam, + LPARAM lparam, LRESULT *result, void *userdata), void *userdata)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/allegro_x.h b/allegro/include/allegro5/allegro_x.h new file mode 100644 index 00000000..6643e0ac --- /dev/null +++ b/allegro/include/allegro5/allegro_x.h @@ -0,0 +1,43 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Header file for X specific functionality. + * + * By Robert MacGregor. + * + */ + +#ifndef __al_included_allegro5_allegro_x_h +#define __al_included_allegro5_allegro_x_h + +#include + +#include "allegro5/base.h" +#include "allegro5/display.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Public X-related API + */ +AL_FUNC(XID, al_get_x_window_id, (ALLEGRO_DISPLAY *display)); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(bool, al_x_set_initial_icon, (ALLEGRO_BITMAP *bitmap)); +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/altime.h b/allegro/include/allegro5/altime.h new file mode 100644 index 00000000..bb0e520d --- /dev/null +++ b/allegro/include/allegro5/altime.h @@ -0,0 +1,30 @@ +#ifndef __al_included_allegro5_altime_h +#define __al_included_allegro5_altime_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_TIMEOUT + */ +typedef struct ALLEGRO_TIMEOUT ALLEGRO_TIMEOUT; +struct ALLEGRO_TIMEOUT { + uint64_t __pad1__; + uint64_t __pad2__; +}; + + + +AL_FUNC(double, al_get_time, (void)); +AL_FUNC(void, al_rest, (double seconds)); +AL_FUNC(void, al_init_timeout, (ALLEGRO_TIMEOUT *timeout, double seconds)); + + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/base.h b/allegro/include/allegro5/base.h new file mode 100644 index 00000000..2a97bad7 --- /dev/null +++ b/allegro/include/allegro5/base.h @@ -0,0 +1,106 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Base header, defines basic stuff needed by pretty much + * everything else. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_base_h +#define __al_included_allegro5_base_h + +#ifndef ALLEGRO_NO_STD_HEADERS + #include + #ifdef _MSC_VER + /* enable posix for limits.h and only limits.h + enabling it for all msvc headers will potentially + disable a lot of commonly used msvcrt functions */ + #define _POSIX_ + #include + #undef _POSIX_ + #else + #include + #endif + #include + #include + #include + #include + #include + #include +#endif + +#if (defined DEBUGMODE) && (defined FORTIFY) + #include +#endif + +#if (defined DEBUGMODE) && (defined DMALLOC) + #include +#endif + +#include "allegro5/internal/alconfig.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define ALLEGRO_VERSION 5 +#define ALLEGRO_SUB_VERSION 2 +#define ALLEGRO_WIP_VERSION 7 + +#ifdef ALLEGRO_UNSTABLE + /* 1 << 31 represented as a signed int to match the arg type of + * al_install_system. + */ + #define ALLEGRO_UNSTABLE_BIT _ALLEGRO_UNSTABLE_BIT_SET +#else + #define ALLEGRO_UNSTABLE_BIT 0 +#endif + +/* Not sure we need it, but since ALLEGRO_VERSION_STR contains it: + * 0 = GIT + * 1 = first release + * 2... = hotfixes? + * + * Note x.y.z (= x.y.z.0) has release number 1, and x.y.z.1 has release + * number 2, just to confuse you. + */ +#define ALLEGRO_RELEASE_NUMBER 1 + +#define ALLEGRO_VERSION_STR "5.2.7" +#define ALLEGRO_DATE_STR "2021" +#define ALLEGRO_DATE 20210307 /* yyyymmdd */ +#define ALLEGRO_VERSION_INT \ + ((ALLEGRO_VERSION << 24) | (ALLEGRO_SUB_VERSION << 16) | \ + (ALLEGRO_WIP_VERSION << 8) | ALLEGRO_RELEASE_NUMBER | \ + ALLEGRO_UNSTABLE_BIT) + +AL_FUNC(uint32_t, al_get_allegro_version, (void)); +AL_FUNC(int, al_run_main, (int argc, char **argv, int (*)(int, char **))); + +/*******************************************/ +/************ Some global stuff ************/ +/*******************************************/ + +/* Type: ALLEGRO_PI + */ +#define ALLEGRO_PI 3.14159265358979323846 + +#define AL_ID(a,b,c,d) (((a)<<24) | ((b)<<16) | ((c)<<8) | (d)) + + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/bitmap.h b/allegro/include/allegro5/bitmap.h new file mode 100644 index 00000000..ef3a2c59 --- /dev/null +++ b/allegro/include/allegro5/bitmap.h @@ -0,0 +1,104 @@ +#ifndef __al_included_allegro5_bitmap_h +#define __al_included_allegro5_bitmap_h + +#include "allegro5/color.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_BITMAP + */ +typedef struct ALLEGRO_BITMAP ALLEGRO_BITMAP; + + +/* + * Bitmap flags + */ +enum { + ALLEGRO_MEMORY_BITMAP = 0x0001, + _ALLEGRO_KEEP_BITMAP_FORMAT = 0x0002, /* now a bitmap loader flag */ + ALLEGRO_FORCE_LOCKING = 0x0004, /* no longer honoured */ + ALLEGRO_NO_PRESERVE_TEXTURE = 0x0008, + _ALLEGRO_ALPHA_TEST = 0x0010, /* now a render state flag */ + _ALLEGRO_INTERNAL_OPENGL = 0x0020, + ALLEGRO_MIN_LINEAR = 0x0040, + ALLEGRO_MAG_LINEAR = 0x0080, + ALLEGRO_MIPMAP = 0x0100, + _ALLEGRO_NO_PREMULTIPLIED_ALPHA = 0x0200, /* now a bitmap loader flag */ + ALLEGRO_VIDEO_BITMAP = 0x0400, + ALLEGRO_CONVERT_BITMAP = 0x1000 +}; + + +AL_FUNC(void, al_set_new_bitmap_format, (int format)); +AL_FUNC(void, al_set_new_bitmap_flags, (int flags)); +AL_FUNC(int, al_get_new_bitmap_format, (void)); +AL_FUNC(int, al_get_new_bitmap_flags, (void)); +AL_FUNC(void, al_add_new_bitmap_flag, (int flag)); + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(int, al_get_new_bitmap_depth, (void)); +AL_FUNC(void, al_set_new_bitmap_depth, (int depth)); +AL_FUNC(int, al_get_new_bitmap_samples, (void)); +AL_FUNC(void, al_set_new_bitmap_samples, (int samples)); +#endif + +AL_FUNC(int, al_get_bitmap_width, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_height, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_format, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_flags, (ALLEGRO_BITMAP *bitmap)); + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(int, al_get_bitmap_depth, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_samples, (ALLEGRO_BITMAP *bitmap)); +#endif + +AL_FUNC(ALLEGRO_BITMAP*, al_create_bitmap, (int w, int h)); +AL_FUNC(void, al_destroy_bitmap, (ALLEGRO_BITMAP *bitmap)); + +AL_FUNC(void, al_put_pixel, (int x, int y, ALLEGRO_COLOR color)); +AL_FUNC(void, al_put_blended_pixel, (int x, int y, ALLEGRO_COLOR color)); +AL_FUNC(ALLEGRO_COLOR, al_get_pixel, (ALLEGRO_BITMAP *bitmap, int x, int y)); + +/* Masking */ +AL_FUNC(void, al_convert_mask_to_alpha, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color)); + +/* Blending */ +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(ALLEGRO_COLOR, al_get_bitmap_blend_color, (void)); +AL_FUNC(void, al_get_bitmap_blender, (int *op, int *src, int *dst)); +AL_FUNC(void, al_get_separate_bitmap_blender, (int *op, int *src, int *dst, int *alpha_op, int *alpha_src, int *alpha_dst)); +AL_FUNC(void, al_set_bitmap_blend_color, (ALLEGRO_COLOR color)); +AL_FUNC(void, al_set_bitmap_blender, (int op, int src, int dst)); +AL_FUNC(void, al_set_separate_bitmap_blender, (int op, int src, int dst, int alpha_op, int alpha_src, int alpha_dst)); +AL_FUNC(void, al_reset_bitmap_blender, (void)); +#endif + +/* Clipping */ +AL_FUNC(void, al_set_clipping_rectangle, (int x, int y, int width, int height)); +AL_FUNC(void, al_reset_clipping_rectangle, (void)); +AL_FUNC(void, al_get_clipping_rectangle, (int *x, int *y, int *w, int *h)); + +/* Sub bitmaps */ +AL_FUNC(ALLEGRO_BITMAP *, al_create_sub_bitmap, (ALLEGRO_BITMAP *parent, int x, int y, int w, int h)); +AL_FUNC(bool, al_is_sub_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(ALLEGRO_BITMAP *, al_get_parent_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_x, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(int, al_get_bitmap_y, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_reparent_bitmap, (ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP *parent, int x, int y, int w, int h)); + +/* Miscellaneous */ +AL_FUNC(ALLEGRO_BITMAP *, al_clone_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_convert_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_convert_memory_bitmaps, (void)); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(void, al_backup_dirty_bitmap, (ALLEGRO_BITMAP *bitmap)); +#endif + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/bitmap_draw.h b/allegro/include/allegro5/bitmap_draw.h new file mode 100644 index 00000000..83e3e144 --- /dev/null +++ b/allegro/include/allegro5/bitmap_draw.h @@ -0,0 +1,42 @@ +#ifndef __al_included_allegro5_bitmap_draw_h +#define __al_included_allegro5_bitmap_draw_h + +#include "allegro5/bitmap.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Flags for the blitting functions */ +enum { + ALLEGRO_FLIP_HORIZONTAL = 0x00001, + ALLEGRO_FLIP_VERTICAL = 0x00002 +}; + +/* Blitting */ +AL_FUNC(void, al_draw_bitmap, (ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags)); +AL_FUNC(void, al_draw_bitmap_region, (ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, float dx, float dy, int flags)); +AL_FUNC(void, al_draw_scaled_bitmap, (ALLEGRO_BITMAP *bitmap, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags)); +AL_FUNC(void, al_draw_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, float cx, float cy, float dx, float dy, float angle, int flags)); +AL_FUNC(void, al_draw_scaled_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags)); + +/* Tinted blitting */ +AL_FUNC(void, al_draw_tinted_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float dx, float dy, int flags)); +AL_FUNC(void, al_draw_tinted_bitmap_region, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, int flags)); +AL_FUNC(void, al_draw_tinted_scaled_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags)); +AL_FUNC(void, al_draw_tinted_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float angle, int flags)); +AL_FUNC(void, al_draw_tinted_scaled_rotated_bitmap, (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags)); +AL_FUNC(void, al_draw_tinted_scaled_rotated_bitmap_region, ( + ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, + ALLEGRO_COLOR tint, + float cx, float cy, float dx, float dy, float xscale, float yscale, + float angle, int flags)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/bitmap_io.h b/allegro/include/allegro5/bitmap_io.h new file mode 100644 index 00000000..70ff94cd --- /dev/null +++ b/allegro/include/allegro5/bitmap_io.h @@ -0,0 +1,47 @@ +#ifndef __al_included_allegro5_bitmap_io_h +#define __al_included_allegro5_bitmap_io_h + +#include "allegro5/bitmap.h" +#include "allegro5/file.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Bitmap loader flag + */ +enum { + ALLEGRO_KEEP_BITMAP_FORMAT = 0x0002, /* was a bitmap flag in 5.0 */ + ALLEGRO_NO_PREMULTIPLIED_ALPHA = 0x0200, /* was a bitmap flag in 5.0 */ + ALLEGRO_KEEP_INDEX = 0x0800 +}; + +typedef ALLEGRO_BITMAP *(*ALLEGRO_IIO_LOADER_FUNCTION)(const char *filename, int flags); +typedef ALLEGRO_BITMAP *(*ALLEGRO_IIO_FS_LOADER_FUNCTION)(ALLEGRO_FILE *fp, int flags); +typedef bool (*ALLEGRO_IIO_SAVER_FUNCTION)(const char *filename, ALLEGRO_BITMAP *bitmap); +typedef bool (*ALLEGRO_IIO_FS_SAVER_FUNCTION)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bitmap); +typedef bool (*ALLEGRO_IIO_IDENTIFIER_FUNCTION)(ALLEGRO_FILE *f); + +AL_FUNC(bool, al_register_bitmap_loader, (const char *ext, ALLEGRO_IIO_LOADER_FUNCTION loader)); +AL_FUNC(bool, al_register_bitmap_saver, (const char *ext, ALLEGRO_IIO_SAVER_FUNCTION saver)); +AL_FUNC(bool, al_register_bitmap_loader_f, (const char *ext, ALLEGRO_IIO_FS_LOADER_FUNCTION fs_loader)); +AL_FUNC(bool, al_register_bitmap_saver_f, (const char *ext, ALLEGRO_IIO_FS_SAVER_FUNCTION fs_saver)); +AL_FUNC(bool, al_register_bitmap_identifier, (const char *ext, + ALLEGRO_IIO_IDENTIFIER_FUNCTION identifier)); +AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap, (const char *filename)); +AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap_flags, (const char *filename, int flags)); +AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap_f, (ALLEGRO_FILE *fp, const char *ident)); +AL_FUNC(ALLEGRO_BITMAP *, al_load_bitmap_flags_f, (ALLEGRO_FILE *fp, const char *ident, int flags)); +AL_FUNC(bool, al_save_bitmap, (const char *filename, ALLEGRO_BITMAP *bitmap)); +AL_FUNC(bool, al_save_bitmap_f, (ALLEGRO_FILE *fp, const char *ident, ALLEGRO_BITMAP *bitmap)); +AL_FUNC(char const *, al_identify_bitmap_f, (ALLEGRO_FILE *fp)); +AL_FUNC(char const *, al_identify_bitmap, (char const *filename)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/bitmap_lock.h b/allegro/include/allegro5/bitmap_lock.h new file mode 100644 index 00000000..198e58a0 --- /dev/null +++ b/allegro/include/allegro5/bitmap_lock.h @@ -0,0 +1,45 @@ +#ifndef __al_included_allegro5_bitmap_lock_h +#define __al_included_allegro5_bitmap_lock_h + +#include "allegro5/bitmap.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* + * Locking flags + */ +enum { + ALLEGRO_LOCK_READWRITE = 0, + ALLEGRO_LOCK_READONLY = 1, + ALLEGRO_LOCK_WRITEONLY = 2 +}; + + +/* Type: ALLEGRO_LOCKED_REGION + */ +typedef struct ALLEGRO_LOCKED_REGION ALLEGRO_LOCKED_REGION; +struct ALLEGRO_LOCKED_REGION { + void *data; + int format; + int pitch; + int pixel_size; +}; + + +AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap, (ALLEGRO_BITMAP *bitmap, int format, int flags)); +AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap_region, (ALLEGRO_BITMAP *bitmap, int x, int y, int width, int height, int format, int flags)); +AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap_blocked, (ALLEGRO_BITMAP *bitmap, int flags)); +AL_FUNC(ALLEGRO_LOCKED_REGION*, al_lock_bitmap_region_blocked, (ALLEGRO_BITMAP *bitmap, int x_block, int y_block, + int width_block, int height_block, int flags)); +AL_FUNC(void, al_unlock_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(bool, al_is_bitmap_locked, (ALLEGRO_BITMAP *bitmap)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/blender.h b/allegro/include/allegro5/blender.h new file mode 100644 index 00000000..a36a3a3a --- /dev/null +++ b/allegro/include/allegro5/blender.h @@ -0,0 +1,51 @@ +#ifndef __al_included_allegro5_blender_h +#define __al_included_allegro5_blender_h + +#include "allegro5/base.h" +#include "allegro5/color.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* + * Blending modes + */ +enum ALLEGRO_BLEND_MODE { + ALLEGRO_ZERO = 0, + ALLEGRO_ONE = 1, + ALLEGRO_ALPHA = 2, + ALLEGRO_INVERSE_ALPHA = 3, + ALLEGRO_SRC_COLOR = 4, + ALLEGRO_DEST_COLOR = 5, + ALLEGRO_INVERSE_SRC_COLOR = 6, + ALLEGRO_INVERSE_DEST_COLOR = 7, + ALLEGRO_CONST_COLOR = 8, + ALLEGRO_INVERSE_CONST_COLOR = 9, + ALLEGRO_NUM_BLEND_MODES +}; + +enum ALLEGRO_BLEND_OPERATIONS { + ALLEGRO_ADD = 0, + ALLEGRO_SRC_MINUS_DEST = 1, + ALLEGRO_DEST_MINUS_SRC = 2, + ALLEGRO_NUM_BLEND_OPERATIONS +}; + + +AL_FUNC(void, al_set_blender, (int op, int source, int dest)); +AL_FUNC(void, al_set_blend_color, (ALLEGRO_COLOR color)); +AL_FUNC(void, al_get_blender, (int *op, int *source, int *dest)); +AL_FUNC(ALLEGRO_COLOR, al_get_blend_color, (void)); +AL_FUNC(void, al_set_separate_blender, (int op, int source, int dest, + int alpha_op, int alpha_source, int alpha_dest)); +AL_FUNC(void, al_get_separate_blender, (int *op, int *source, int *dest, + int *alpha_op, int *alpha_src, int *alpha_dest)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/clipboard.h b/allegro/include/allegro5/clipboard.h new file mode 100644 index 00000000..46851fe4 --- /dev/null +++ b/allegro/include/allegro5/clipboard.h @@ -0,0 +1,42 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Clipboard handling. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_clipboard_h +#define __al_included_allegro5_clipboard_h + +#include "allegro5/base.h" +#include "allegro5/display.h" +#include "allegro5/utf8.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(char *, al_get_clipboard_text, (ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_set_clipboard_text, (ALLEGRO_DISPLAY *display, const char *text)); +AL_FUNC(bool, al_clipboard_has_text, (ALLEGRO_DISPLAY *display)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/include/allegro5/color.h b/allegro/include/allegro5/color.h new file mode 100644 index 00000000..41b94bfb --- /dev/null +++ b/allegro/include/allegro5/color.h @@ -0,0 +1,89 @@ +#ifndef __al_included_allegro5_color_h +#define __al_included_allegro5_color_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_COLOR + */ +typedef struct ALLEGRO_COLOR ALLEGRO_COLOR; + +struct ALLEGRO_COLOR +{ + float r, g, b, a; +}; + + +/* Enum: ALLEGRO_PIXEL_FORMAT + */ +typedef enum ALLEGRO_PIXEL_FORMAT +{ + ALLEGRO_PIXEL_FORMAT_ANY = 0, + ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA = 1, + ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA = 2, + ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA = 3, + ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA = 4, + ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA = 5, + ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA = 6, + ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA = 7, + ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA = 8, + ALLEGRO_PIXEL_FORMAT_ARGB_8888 = 9, + ALLEGRO_PIXEL_FORMAT_RGBA_8888 = 10, + ALLEGRO_PIXEL_FORMAT_ARGB_4444 = 11, + ALLEGRO_PIXEL_FORMAT_RGB_888 = 12, /* 24 bit format */ + ALLEGRO_PIXEL_FORMAT_RGB_565 = 13, + ALLEGRO_PIXEL_FORMAT_RGB_555 = 14, + ALLEGRO_PIXEL_FORMAT_RGBA_5551 = 15, + ALLEGRO_PIXEL_FORMAT_ARGB_1555 = 16, + ALLEGRO_PIXEL_FORMAT_ABGR_8888 = 17, + ALLEGRO_PIXEL_FORMAT_XBGR_8888 = 18, + ALLEGRO_PIXEL_FORMAT_BGR_888 = 19, /* 24 bit format */ + ALLEGRO_PIXEL_FORMAT_BGR_565 = 20, + ALLEGRO_PIXEL_FORMAT_BGR_555 = 21, + ALLEGRO_PIXEL_FORMAT_RGBX_8888 = 22, + ALLEGRO_PIXEL_FORMAT_XRGB_8888 = 23, + ALLEGRO_PIXEL_FORMAT_ABGR_F32 = 24, + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE = 25, + ALLEGRO_PIXEL_FORMAT_RGBA_4444 = 26, + ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 = 27, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1 = 28, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3 = 29, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5 = 30, + ALLEGRO_NUM_PIXEL_FORMATS +} ALLEGRO_PIXEL_FORMAT; + + +/* Pixel mapping */ +AL_FUNC(ALLEGRO_COLOR, al_map_rgb, (unsigned char r, unsigned char g, unsigned char b)); +AL_FUNC(ALLEGRO_COLOR, al_map_rgba, (unsigned char r, unsigned char g, unsigned char b, unsigned char a)); +AL_FUNC(ALLEGRO_COLOR, al_map_rgb_f, (float r, float g, float b)); +AL_FUNC(ALLEGRO_COLOR, al_map_rgba_f, (float r, float g, float b, float a)); +AL_FUNC(ALLEGRO_COLOR, al_premul_rgba, + (unsigned char r, unsigned char g, unsigned char b, unsigned char a)); +AL_FUNC(ALLEGRO_COLOR, al_premul_rgba_f, + (float r, float g, float b, float a)); + +/* Pixel unmapping */ +AL_FUNC(void, al_unmap_rgb, (ALLEGRO_COLOR color, unsigned char *r, unsigned char *g, unsigned char *b)); +AL_FUNC(void, al_unmap_rgba, (ALLEGRO_COLOR color, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)); +AL_FUNC(void, al_unmap_rgb_f, (ALLEGRO_COLOR color, float *r, float *g, float *b)); +AL_FUNC(void, al_unmap_rgba_f, (ALLEGRO_COLOR color, float *r, float *g, float *b, float *a)); + +/* Pixel formats */ +AL_FUNC(int, al_get_pixel_size, (int format)); +AL_FUNC(int, al_get_pixel_format_bits, (int format)); +AL_FUNC(int, al_get_pixel_block_size, (int format)); +AL_FUNC(int, al_get_pixel_block_width, (int format)); +AL_FUNC(int, al_get_pixel_block_height, (int format)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/config.h b/allegro/include/allegro5/config.h new file mode 100644 index 00000000..9402b00d --- /dev/null +++ b/allegro/include/allegro5/config.h @@ -0,0 +1,49 @@ +#ifndef __al_included_allegro5_config_h +#define __al_included_allegro5_config_h + +#include "allegro5/file.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Type: ALLEGRO_CONFIG + */ +typedef struct ALLEGRO_CONFIG ALLEGRO_CONFIG; + +/* Type: ALLEGRO_CONFIG_SECTION + */ +typedef struct ALLEGRO_CONFIG_SECTION ALLEGRO_CONFIG_SECTION; + +/* Type: ALLEGRO_CONFIG_ENTRY + */ +typedef struct ALLEGRO_CONFIG_ENTRY ALLEGRO_CONFIG_ENTRY; + +AL_FUNC(ALLEGRO_CONFIG *, al_create_config, (void)); +AL_FUNC(void, al_add_config_section, (ALLEGRO_CONFIG *config, const char *name)); +AL_FUNC(void, al_set_config_value, (ALLEGRO_CONFIG *config, const char *section, const char *key, const char *value)); +AL_FUNC(void, al_add_config_comment, (ALLEGRO_CONFIG *config, const char *section, const char *comment)); +AL_FUNC(const char*, al_get_config_value, (const ALLEGRO_CONFIG *config, const char *section, const char *key)); +AL_FUNC(ALLEGRO_CONFIG*, al_load_config_file, (const char *filename)); +AL_FUNC(ALLEGRO_CONFIG*, al_load_config_file_f, (ALLEGRO_FILE *filename)); +AL_FUNC(bool, al_save_config_file, (const char *filename, const ALLEGRO_CONFIG *config)); +AL_FUNC(bool, al_save_config_file_f, (ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)); +AL_FUNC(void, al_merge_config_into, (ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add)); +AL_FUNC(ALLEGRO_CONFIG *, al_merge_config, (const ALLEGRO_CONFIG *cfg1, const ALLEGRO_CONFIG *cfg2)); +AL_FUNC(void, al_destroy_config, (ALLEGRO_CONFIG *config)); +AL_FUNC(bool, al_remove_config_section, (ALLEGRO_CONFIG *config, + char const *section)); +AL_FUNC(bool, al_remove_config_key, (ALLEGRO_CONFIG *config, + char const *section, char const *key)); + +AL_FUNC(char const *, al_get_first_config_section, (ALLEGRO_CONFIG const *config, ALLEGRO_CONFIG_SECTION **iterator)); +AL_FUNC(char const *, al_get_next_config_section, (ALLEGRO_CONFIG_SECTION **iterator)); +AL_FUNC(char const *, al_get_first_config_entry, (ALLEGRO_CONFIG const *config, char const *section, + ALLEGRO_CONFIG_ENTRY **iterator)); +AL_FUNC(char const *, al_get_next_config_entry, (ALLEGRO_CONFIG_ENTRY **iterator)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/cpu.h b/allegro/include/allegro5/cpu.h new file mode 100644 index 00000000..512d76c4 --- /dev/null +++ b/allegro/include/allegro5/cpu.h @@ -0,0 +1,39 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * CPU and system information handling. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_cpu_h +#define __al_included_allegro5_cpu_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(int, al_get_cpu_count, (void)); +AL_FUNC(int, al_get_ram_size, (void)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/include/allegro5/debug.h b/allegro/include/allegro5/debug.h new file mode 100644 index 00000000..4ce403df --- /dev/null +++ b/allegro/include/allegro5/debug.h @@ -0,0 +1,100 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Debug facilities. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_debug_h +#define __al_included_allegro5_debug_h + +#include +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(bool, _al_trace_prefix, (char const *channel, int level, + char const *file, int line, char const *function)); + +AL_PRINTFUNC(void, _al_trace_suffix, (const char *msg, ...), 1, 2); + +#if defined(DEBUGMODE) || defined(ALLEGRO_CFG_RELEASE_LOGGING) + /* Must not be used with a trailing semicolon. */ + #ifdef ALLEGRO_GCC + #define ALLEGRO_DEBUG_CHANNEL(x) \ + static char const *__al_debug_channel __attribute__((unused)) = x; + #else + #define ALLEGRO_DEBUG_CHANNEL(x) \ + static char const *__al_debug_channel = x; + #endif + #define ALLEGRO_TRACE_CHANNEL_LEVEL(channel, level) \ + !_al_trace_prefix(channel, level, __FILE__, __LINE__, __func__) \ + ? (void)0 : _al_trace_suffix +#else + #define ALLEGRO_TRACE_CHANNEL_LEVEL(channel, x) 1 ? (void) 0 : _al_trace_suffix + #define ALLEGRO_DEBUG_CHANNEL(x) +#endif + +#define ALLEGRO_TRACE_LEVEL(x) ALLEGRO_TRACE_CHANNEL_LEVEL(__al_debug_channel, x) +#define ALLEGRO_DEBUG ALLEGRO_TRACE_LEVEL(0) +#define ALLEGRO_INFO ALLEGRO_TRACE_LEVEL(1) +#define ALLEGRO_WARN ALLEGRO_TRACE_LEVEL(2) +#define ALLEGRO_ERROR ALLEGRO_TRACE_LEVEL(3) + +/* Run-time assertions. */ +AL_FUNCPTR(void, _al_user_assert_handler, (char const *expr, char const *file, + int line, char const *func)); + +AL_FUNC(void, al_register_assert_handler, (void (*handler)(char const *expr, + char const *file, int line, char const *func))); + +AL_FUNC(void, al_register_trace_handler, (void (*handler)(char const *))); + +#ifdef __clang_analyzer__ + /* Clang doesn't understand _al_user_assert_handler, so we simplify the + * definition for analysis purposes. */ + #define ALLEGRO_ASSERT(e) assert(e) +#else + #ifdef NDEBUG + #define ALLEGRO_ASSERT(e) ((void)(0 && (e))) + #else + #define ALLEGRO_ASSERT(e) \ + ((e) ? (void) 0 \ + : (_al_user_assert_handler) ? \ + _al_user_assert_handler(#e, __FILE__, __LINE__, __func__) \ + : assert(e)) + #endif +#endif + +/* Compile time assertions. */ +#define ALLEGRO_ASSERT_CONCAT_(a, b) a##b +#define ALLEGRO_ASSERT_CONCAT(a, b) ALLEGRO_ASSERT_CONCAT_(a, b) +#define ALLEGRO_STATIC_ASSERT(module, e) \ + struct ALLEGRO_ASSERT_CONCAT(static_assert_##module##_line_, __LINE__) \ + { unsigned int bf : !!(e); } + +/* We are lazy and use just ASSERT while Allegro itself is compiled. */ +#ifdef ALLEGRO_LIB_BUILD + #define ASSERT(x) ALLEGRO_ASSERT(x) +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/display.h b/allegro/include/allegro5/display.h new file mode 100644 index 00000000..2b8c8798 --- /dev/null +++ b/allegro/include/allegro5/display.h @@ -0,0 +1,192 @@ +#ifndef __al_included_allegro5_display_h +#define __al_included_allegro5_display_h + +#include "allegro5/bitmap.h" +#include "allegro5/color.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Possible bit combinations for the flags parameter of al_create_display. */ +enum { + ALLEGRO_WINDOWED = 1 << 0, + ALLEGRO_FULLSCREEN = 1 << 1, + ALLEGRO_OPENGL = 1 << 2, + ALLEGRO_DIRECT3D_INTERNAL = 1 << 3, + ALLEGRO_RESIZABLE = 1 << 4, + ALLEGRO_FRAMELESS = 1 << 5, + ALLEGRO_NOFRAME = ALLEGRO_FRAMELESS, /* older synonym */ + ALLEGRO_GENERATE_EXPOSE_EVENTS = 1 << 6, + ALLEGRO_OPENGL_3_0 = 1 << 7, + ALLEGRO_OPENGL_FORWARD_COMPATIBLE = 1 << 8, + ALLEGRO_FULLSCREEN_WINDOW = 1 << 9, + ALLEGRO_MINIMIZED = 1 << 10, + ALLEGRO_PROGRAMMABLE_PIPELINE = 1 << 11, + ALLEGRO_GTK_TOPLEVEL_INTERNAL = 1 << 12, + ALLEGRO_MAXIMIZED = 1 << 13, + ALLEGRO_OPENGL_ES_PROFILE = 1 << 14, +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) + ALLEGRO_OPENGL_CORE_PROFILE = 1 << 15, +#endif +}; + +/* Possible parameters for al_set_display_option. + * Make sure to update ALLEGRO_EXTRA_DISPLAY_SETTINGS if you modify + * anything here. + */ +enum ALLEGRO_DISPLAY_OPTIONS { + ALLEGRO_RED_SIZE = 0, + ALLEGRO_GREEN_SIZE = 1, + ALLEGRO_BLUE_SIZE = 2, + ALLEGRO_ALPHA_SIZE = 3, + ALLEGRO_RED_SHIFT = 4, + ALLEGRO_GREEN_SHIFT = 5, + ALLEGRO_BLUE_SHIFT = 6, + ALLEGRO_ALPHA_SHIFT = 7, + ALLEGRO_ACC_RED_SIZE = 8, + ALLEGRO_ACC_GREEN_SIZE = 9, + ALLEGRO_ACC_BLUE_SIZE = 10, + ALLEGRO_ACC_ALPHA_SIZE = 11, + ALLEGRO_STEREO = 12, + ALLEGRO_AUX_BUFFERS = 13, + ALLEGRO_COLOR_SIZE = 14, + ALLEGRO_DEPTH_SIZE = 15, + ALLEGRO_STENCIL_SIZE = 16, + ALLEGRO_SAMPLE_BUFFERS = 17, + ALLEGRO_SAMPLES = 18, + ALLEGRO_RENDER_METHOD = 19, + ALLEGRO_FLOAT_COLOR = 20, + ALLEGRO_FLOAT_DEPTH = 21, + ALLEGRO_SINGLE_BUFFER = 22, + ALLEGRO_SWAP_METHOD = 23, + ALLEGRO_COMPATIBLE_DISPLAY = 24, + ALLEGRO_UPDATE_DISPLAY_REGION = 25, + ALLEGRO_VSYNC = 26, + ALLEGRO_MAX_BITMAP_SIZE = 27, + ALLEGRO_SUPPORT_NPOT_BITMAP = 28, + ALLEGRO_CAN_DRAW_INTO_BITMAP = 29, + ALLEGRO_SUPPORT_SEPARATE_ALPHA = 30, + ALLEGRO_AUTO_CONVERT_BITMAPS = 31, + ALLEGRO_SUPPORTED_ORIENTATIONS = 32, + ALLEGRO_OPENGL_MAJOR_VERSION = 33, + ALLEGRO_OPENGL_MINOR_VERSION = 34, + ALLEGRO_DISPLAY_OPTIONS_COUNT +}; + +enum +{ + ALLEGRO_DONTCARE, + ALLEGRO_REQUIRE, + ALLEGRO_SUGGEST +}; + + +/* Bitflags so they can be used for the ALLEGRO_SUPPORTED_ORIENTATIONS option. */ +enum ALLEGRO_DISPLAY_ORIENTATION +{ + ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN = 0, + ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES = 1, + ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES = 2, + ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES = 4, + ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES = 8, + ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT = 5, + ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE = 10, + ALLEGRO_DISPLAY_ORIENTATION_ALL = 15, + ALLEGRO_DISPLAY_ORIENTATION_FACE_UP = 16, + ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN = 32 +}; + + +/* Formally part of the primitives addon. */ +enum +{ + _ALLEGRO_PRIM_MAX_USER_ATTR = 10 +}; + + +/* Type: ALLEGRO_DISPLAY + */ +typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY; + + +/* Enum: ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE +*/ +#define ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE 255 + +AL_FUNC(void, al_set_new_display_refresh_rate, (int refresh_rate)); +AL_FUNC(void, al_set_new_display_flags, (int flags)); +AL_FUNC(int, al_get_new_display_refresh_rate, (void)); +AL_FUNC(int, al_get_new_display_flags, (void)); + +AL_FUNC(void, al_set_new_window_title, (const char *title)); +AL_FUNC(const char *, al_get_new_window_title, (void)); + +AL_FUNC(int, al_get_display_width, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_height, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_format, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_refresh_rate, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_flags, (ALLEGRO_DISPLAY *display)); +AL_FUNC(int, al_get_display_orientation, (ALLEGRO_DISPLAY* display)); +AL_FUNC(bool, al_set_display_flag, (ALLEGRO_DISPLAY *display, int flag, bool onoff)); + +AL_FUNC(ALLEGRO_DISPLAY*, al_create_display, (int w, int h)); +AL_FUNC(void, al_destroy_display, (ALLEGRO_DISPLAY *display)); +AL_FUNC(ALLEGRO_DISPLAY*, al_get_current_display, (void)); +AL_FUNC(void, al_set_target_bitmap, (ALLEGRO_BITMAP *bitmap)); +AL_FUNC(void, al_set_target_backbuffer, (ALLEGRO_DISPLAY *display)); +AL_FUNC(ALLEGRO_BITMAP*, al_get_backbuffer, (ALLEGRO_DISPLAY *display)); +AL_FUNC(ALLEGRO_BITMAP*, al_get_target_bitmap, (void)); + +AL_FUNC(bool, al_acknowledge_resize, (ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_resize_display, (ALLEGRO_DISPLAY *display, int width, int height)); +AL_FUNC(void, al_flip_display, (void)); +AL_FUNC(void, al_update_display_region, (int x, int y, int width, int height)); +AL_FUNC(bool, al_is_compatible_bitmap, (ALLEGRO_BITMAP *bitmap)); + +AL_FUNC(bool, al_wait_for_vsync, (void)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_display_event_source, (ALLEGRO_DISPLAY *display)); + +AL_FUNC(void, al_set_display_icon, (ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon)); +AL_FUNC(void, al_set_display_icons, (ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *icons[])); + +/* Stuff for multihead/window management */ +AL_FUNC(int, al_get_new_display_adapter, (void)); +AL_FUNC(void, al_set_new_display_adapter, (int adapter)); +AL_FUNC(void, al_set_new_window_position, (int x, int y)); +AL_FUNC(void, al_get_new_window_position, (int *x, int *y)); +AL_FUNC(void, al_set_window_position, (ALLEGRO_DISPLAY *display, int x, int y)); +AL_FUNC(void, al_get_window_position, (ALLEGRO_DISPLAY *display, int *x, int *y)); +AL_FUNC(bool, al_set_window_constraints, (ALLEGRO_DISPLAY *display, int min_w, int min_h, int max_w, int max_h)); +AL_FUNC(bool, al_get_window_constraints, (ALLEGRO_DISPLAY *display, int *min_w, int *min_h, int *max_w, int *max_h)); +AL_FUNC(void, al_apply_window_constraints, (ALLEGRO_DISPLAY *display, bool onoff)); + +AL_FUNC(void, al_set_window_title, (ALLEGRO_DISPLAY *display, const char *title)); + +/* Defined in display_settings.c */ +AL_FUNC(void, al_set_new_display_option, (int option, int value, int importance)); +AL_FUNC(int, al_get_new_display_option, (int option, int *importance)); +AL_FUNC(void, al_reset_new_display_options, (void)); +AL_FUNC(void, al_set_display_option, (ALLEGRO_DISPLAY *display, int option, int value)); +AL_FUNC(int, al_get_display_option, (ALLEGRO_DISPLAY *display, int option)); + +/*Deferred drawing*/ +AL_FUNC(void, al_hold_bitmap_drawing, (bool hold)); +AL_FUNC(bool, al_is_bitmap_drawing_held, (void)); + +/* Miscellaneous */ +AL_FUNC(void, al_acknowledge_drawing_halt, (ALLEGRO_DISPLAY *display)); +AL_FUNC(void, al_acknowledge_drawing_resume, (ALLEGRO_DISPLAY *display)); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(void, al_backup_dirty_bitmaps, (ALLEGRO_DISPLAY *display)); +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/drawing.h b/allegro/include/allegro5/drawing.h new file mode 100644 index 00000000..dd21dc6c --- /dev/null +++ b/allegro/include/allegro5/drawing.h @@ -0,0 +1,22 @@ +#ifndef __al_included_allegro5_drawing_h +#define __al_included_allegro5_drawing_h + +#include "allegro5/color.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Drawing primitives */ +AL_FUNC(void, al_clear_to_color, (ALLEGRO_COLOR color)); +AL_FUNC(void, al_clear_depth_buffer, (float x)); +AL_FUNC(void, al_draw_pixel, (float x, float y, ALLEGRO_COLOR color)); + + +#ifdef __cplusplus + } +#endif + +#endif +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/error.h b/allegro/include/allegro5/error.h new file mode 100644 index 00000000..306c7aa0 --- /dev/null +++ b/allegro/include/allegro5/error.h @@ -0,0 +1,39 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Error handling. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_error_h +#define __al_included_allegro5_error_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(int, al_get_errno, (void)); +AL_FUNC(void, al_set_errno, (int errnum)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/include/allegro5/events.h b/allegro/include/allegro5/events.h new file mode 100644 index 00000000..0188c627 --- /dev/null +++ b/allegro/include/allegro5/events.h @@ -0,0 +1,273 @@ +#ifndef __al_included_allegro5_events_h +#define __al_included_allegro5_events_h + +#include "allegro5/altime.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_EVENT_TYPE + */ +typedef unsigned int ALLEGRO_EVENT_TYPE; + +enum +{ + ALLEGRO_EVENT_JOYSTICK_AXIS = 1, + ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN = 2, + ALLEGRO_EVENT_JOYSTICK_BUTTON_UP = 3, + ALLEGRO_EVENT_JOYSTICK_CONFIGURATION = 4, + + ALLEGRO_EVENT_KEY_DOWN = 10, + ALLEGRO_EVENT_KEY_CHAR = 11, + ALLEGRO_EVENT_KEY_UP = 12, + + ALLEGRO_EVENT_MOUSE_AXES = 20, + ALLEGRO_EVENT_MOUSE_BUTTON_DOWN = 21, + ALLEGRO_EVENT_MOUSE_BUTTON_UP = 22, + ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY = 23, + ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY = 24, + ALLEGRO_EVENT_MOUSE_WARPED = 25, + + ALLEGRO_EVENT_TIMER = 30, + + ALLEGRO_EVENT_DISPLAY_EXPOSE = 40, + ALLEGRO_EVENT_DISPLAY_RESIZE = 41, + ALLEGRO_EVENT_DISPLAY_CLOSE = 42, + ALLEGRO_EVENT_DISPLAY_LOST = 43, + ALLEGRO_EVENT_DISPLAY_FOUND = 44, + ALLEGRO_EVENT_DISPLAY_SWITCH_IN = 45, + ALLEGRO_EVENT_DISPLAY_SWITCH_OUT = 46, + ALLEGRO_EVENT_DISPLAY_ORIENTATION = 47, + ALLEGRO_EVENT_DISPLAY_HALT_DRAWING = 48, + ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING = 49, + + ALLEGRO_EVENT_TOUCH_BEGIN = 50, + ALLEGRO_EVENT_TOUCH_END = 51, + ALLEGRO_EVENT_TOUCH_MOVE = 52, + ALLEGRO_EVENT_TOUCH_CANCEL = 53, + + ALLEGRO_EVENT_DISPLAY_CONNECTED = 60, + ALLEGRO_EVENT_DISPLAY_DISCONNECTED = 61 +}; + + +/* Function: ALLEGRO_EVENT_TYPE_IS_USER + * + * 1 <= n < 512 - builtin events + * 512 <= n < 1024 - reserved user events (for addons) + * 1024 <= n - unreserved user events + */ +#define ALLEGRO_EVENT_TYPE_IS_USER(t) ((t) >= 512) + + +/* Function: ALLEGRO_GET_EVENT_TYPE + */ +#define ALLEGRO_GET_EVENT_TYPE(a, b, c, d) AL_ID(a, b, c, d) + + +/* Type: ALLEGRO_EVENT_SOURCE + */ +typedef struct ALLEGRO_EVENT_SOURCE ALLEGRO_EVENT_SOURCE; + +struct ALLEGRO_EVENT_SOURCE +{ + int __pad[32]; +}; + + + +/* + * Event structures + * + * All event types have the following fields in common. + * + * type -- the type of event this is + * timestamp -- when this event was generated + * source -- which event source generated this event + * + * For people writing event sources: The common fields must be at the + * very start of each event structure, i.e. put _AL_EVENT_HEADER at the + * front. + */ + +#define _AL_EVENT_HEADER(srctype) \ + ALLEGRO_EVENT_TYPE type; \ + srctype *source; \ + double timestamp; + + +typedef struct ALLEGRO_ANY_EVENT +{ + _AL_EVENT_HEADER(ALLEGRO_EVENT_SOURCE) +} ALLEGRO_ANY_EVENT; + + +typedef struct ALLEGRO_DISPLAY_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_DISPLAY) + int x, y; + int width, height; + int orientation; +} ALLEGRO_DISPLAY_EVENT; + + +typedef struct ALLEGRO_JOYSTICK_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_JOYSTICK) + struct ALLEGRO_JOYSTICK *id; + int stick; + int axis; + float pos; + int button; +} ALLEGRO_JOYSTICK_EVENT; + + + +typedef struct ALLEGRO_KEYBOARD_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_KEYBOARD) + struct ALLEGRO_DISPLAY *display; /* the window the key was pressed in */ + int keycode; /* the physical key pressed */ + int unichar; /* unicode character or negative */ + unsigned int modifiers; /* bitfield */ + bool repeat; /* auto-repeated or not */ +} ALLEGRO_KEYBOARD_EVENT; + + + +typedef struct ALLEGRO_MOUSE_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_MOUSE) + struct ALLEGRO_DISPLAY *display; + /* (display) Window the event originate from + * (x, y) Primary mouse position + * (z) Mouse wheel position (1D 'wheel'), or, + * (w, z) Mouse wheel position (2D 'ball') + * (pressure) The pressure applied, for stylus (0 or 1 for normal mouse) + */ + int x, y, z, w; + int dx, dy, dz, dw; + unsigned int button; + float pressure; +} ALLEGRO_MOUSE_EVENT; + + + +typedef struct ALLEGRO_TIMER_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_TIMER) + int64_t count; + double error; +} ALLEGRO_TIMER_EVENT; + + + +typedef struct ALLEGRO_TOUCH_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_TOUCH_INPUT) + struct ALLEGRO_DISPLAY *display; + /* (id) Identifier of the event, always positive number. + * (x, y) Touch position on the screen in 1:1 resolution. + * (dx, dy) Relative touch position. + * (primary) True, if touch is a primary one (usually first one). + */ + int id; + float x, y; + float dx, dy; + bool primary; +} ALLEGRO_TOUCH_EVENT; + + + +/* Type: ALLEGRO_USER_EVENT + */ +typedef struct ALLEGRO_USER_EVENT ALLEGRO_USER_EVENT; + +struct ALLEGRO_USER_EVENT +{ + _AL_EVENT_HEADER(struct ALLEGRO_EVENT_SOURCE) + struct ALLEGRO_USER_EVENT_DESCRIPTOR *__internal__descr; + intptr_t data1; + intptr_t data2; + intptr_t data3; + intptr_t data4; +}; + + + +/* Type: ALLEGRO_EVENT + */ +typedef union ALLEGRO_EVENT ALLEGRO_EVENT; + +union ALLEGRO_EVENT +{ + /* This must be the same as the first field of _AL_EVENT_HEADER. */ + ALLEGRO_EVENT_TYPE type; + /* `any' is to allow the user to access the other fields which are + * common to all event types, without using some specific type + * structure. + */ + ALLEGRO_ANY_EVENT any; + ALLEGRO_DISPLAY_EVENT display; + ALLEGRO_JOYSTICK_EVENT joystick; + ALLEGRO_KEYBOARD_EVENT keyboard; + ALLEGRO_MOUSE_EVENT mouse; + ALLEGRO_TIMER_EVENT timer; + ALLEGRO_TOUCH_EVENT touch; + ALLEGRO_USER_EVENT user; +}; + + + +/* Event sources */ + +AL_FUNC(void, al_init_user_event_source, (ALLEGRO_EVENT_SOURCE *)); +AL_FUNC(void, al_destroy_user_event_source, (ALLEGRO_EVENT_SOURCE *)); +/* The second argument is ALLEGRO_EVENT instead of ALLEGRO_USER_EVENT + * to prevent users passing a pointer to a too-short structure. + */ +AL_FUNC(bool, al_emit_user_event, (ALLEGRO_EVENT_SOURCE *, ALLEGRO_EVENT *, + void (*dtor)(ALLEGRO_USER_EVENT *))); +AL_FUNC(void, al_unref_user_event, (ALLEGRO_USER_EVENT *)); +AL_FUNC(void, al_set_event_source_data, (ALLEGRO_EVENT_SOURCE*, intptr_t data)); +AL_FUNC(intptr_t, al_get_event_source_data, (const ALLEGRO_EVENT_SOURCE*)); + + + +/* Event queues */ + +/* Type: ALLEGRO_EVENT_QUEUE + */ +typedef struct ALLEGRO_EVENT_QUEUE ALLEGRO_EVENT_QUEUE; + +AL_FUNC(ALLEGRO_EVENT_QUEUE*, al_create_event_queue, (void)); +AL_FUNC(void, al_destroy_event_queue, (ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(bool, al_is_event_source_registered, (ALLEGRO_EVENT_QUEUE *, + ALLEGRO_EVENT_SOURCE *)); +AL_FUNC(void, al_register_event_source, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT_SOURCE*)); +AL_FUNC(void, al_unregister_event_source, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT_SOURCE*)); +AL_FUNC(void, al_pause_event_queue, (ALLEGRO_EVENT_QUEUE*, bool)); +AL_FUNC(bool, al_is_event_queue_paused, (const ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(bool, al_is_event_queue_empty, (ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(bool, al_get_next_event, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT *ret_event)); +AL_FUNC(bool, al_peek_next_event, (ALLEGRO_EVENT_QUEUE*, ALLEGRO_EVENT *ret_event)); +AL_FUNC(bool, al_drop_next_event, (ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(void, al_flush_event_queue, (ALLEGRO_EVENT_QUEUE*)); +AL_FUNC(void, al_wait_for_event, (ALLEGRO_EVENT_QUEUE*, + ALLEGRO_EVENT *ret_event)); +AL_FUNC(bool, al_wait_for_event_timed, (ALLEGRO_EVENT_QUEUE*, + ALLEGRO_EVENT *ret_event, + float secs)); +AL_FUNC(bool, al_wait_for_event_until, (ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT *ret_event, + ALLEGRO_TIMEOUT *timeout)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/file.h b/allegro/include/allegro5/file.h new file mode 100644 index 00000000..b1873e8e --- /dev/null +++ b/allegro/include/allegro5/file.h @@ -0,0 +1,107 @@ +#ifndef __al_included_allegro5_file_h +#define __al_included_allegro5_file_h + +#include "allegro5/base.h" +#include "allegro5/path.h" +#include "allegro5/utf8.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_FILE + */ +typedef struct ALLEGRO_FILE ALLEGRO_FILE; + + +/* Type: ALLEGRO_FILE_INTERFACE + */ +typedef struct ALLEGRO_FILE_INTERFACE +{ + AL_METHOD(void *, fi_fopen, (const char *path, const char *mode)); + AL_METHOD(bool, fi_fclose, (ALLEGRO_FILE *handle)); + AL_METHOD(size_t, fi_fread, (ALLEGRO_FILE *f, void *ptr, size_t size)); + AL_METHOD(size_t, fi_fwrite, (ALLEGRO_FILE *f, const void *ptr, size_t size)); + AL_METHOD(bool, fi_fflush, (ALLEGRO_FILE *f)); + AL_METHOD(int64_t, fi_ftell, (ALLEGRO_FILE *f)); + AL_METHOD(bool, fi_fseek, (ALLEGRO_FILE *f, int64_t offset, int whence)); + AL_METHOD(bool, fi_feof, (ALLEGRO_FILE *f)); + AL_METHOD(int, fi_ferror, (ALLEGRO_FILE *f)); + AL_METHOD(const char *, fi_ferrmsg, (ALLEGRO_FILE *f)); + AL_METHOD(void, fi_fclearerr, (ALLEGRO_FILE *f)); + AL_METHOD(int, fi_fungetc, (ALLEGRO_FILE *f, int c)); + AL_METHOD(off_t, fi_fsize, (ALLEGRO_FILE *f)); +} ALLEGRO_FILE_INTERFACE; + + +/* Enum: ALLEGRO_SEEK + */ +typedef enum ALLEGRO_SEEK +{ + ALLEGRO_SEEK_SET = 0, + ALLEGRO_SEEK_CUR, + ALLEGRO_SEEK_END +} ALLEGRO_SEEK; + + +/* The basic operations. */ +AL_FUNC(ALLEGRO_FILE*, al_fopen, (const char *path, const char *mode)); +AL_FUNC(ALLEGRO_FILE*, al_fopen_interface, (const ALLEGRO_FILE_INTERFACE *vt, const char *path, const char *mode)); +AL_FUNC(ALLEGRO_FILE*, al_create_file_handle, (const ALLEGRO_FILE_INTERFACE *vt, void *userdata)); +AL_FUNC(bool, al_fclose, (ALLEGRO_FILE *f)); +AL_FUNC(size_t, al_fread, (ALLEGRO_FILE *f, void *ptr, size_t size)); +AL_FUNC(size_t, al_fwrite, (ALLEGRO_FILE *f, const void *ptr, size_t size)); +AL_FUNC(bool, al_fflush, (ALLEGRO_FILE *f)); +AL_FUNC(int64_t, al_ftell, (ALLEGRO_FILE *f)); +AL_FUNC(bool, al_fseek, (ALLEGRO_FILE *f, int64_t offset, int whence)); +AL_FUNC(bool, al_feof, (ALLEGRO_FILE *f)); +AL_FUNC(int, al_ferror, (ALLEGRO_FILE *f)); +AL_FUNC(const char *, al_ferrmsg, (ALLEGRO_FILE *f)); +AL_FUNC(void, al_fclearerr, (ALLEGRO_FILE *f)); +AL_FUNC(int, al_fungetc, (ALLEGRO_FILE *f, int c)); +AL_FUNC(int64_t, al_fsize, (ALLEGRO_FILE *f)); + +/* Convenience functions. */ +AL_FUNC(int, al_fgetc, (ALLEGRO_FILE *f)); +AL_FUNC(int, al_fputc, (ALLEGRO_FILE *f, int c)); +AL_FUNC(int16_t, al_fread16le, (ALLEGRO_FILE *f)); +AL_FUNC(int16_t, al_fread16be, (ALLEGRO_FILE *f)); +AL_FUNC(size_t, al_fwrite16le, (ALLEGRO_FILE *f, int16_t w)); +AL_FUNC(size_t, al_fwrite16be, (ALLEGRO_FILE *f, int16_t w)); +AL_FUNC(int32_t, al_fread32le, (ALLEGRO_FILE *f)); +AL_FUNC(int32_t, al_fread32be, (ALLEGRO_FILE *f)); +AL_FUNC(size_t, al_fwrite32le, (ALLEGRO_FILE *f, int32_t l)); +AL_FUNC(size_t, al_fwrite32be, (ALLEGRO_FILE *f, int32_t l)); +AL_FUNC(char*, al_fgets, (ALLEGRO_FILE *f, char * const p, size_t max)); +AL_FUNC(ALLEGRO_USTR *, al_fget_ustr, (ALLEGRO_FILE *f)); +AL_FUNC(int, al_fputs, (ALLEGRO_FILE *f, const char *p)); +AL_FUNC(int, al_fprintf, (ALLEGRO_FILE *f, const char *format, ...)); +AL_FUNC(int, al_vfprintf, (ALLEGRO_FILE *f, const char* format, va_list args)); + +/* Specific to stdio backend. */ +AL_FUNC(ALLEGRO_FILE*, al_fopen_fd, (int fd, const char *mode)); +AL_FUNC(ALLEGRO_FILE*, al_make_temp_file, (const char *tmpl, + ALLEGRO_PATH **ret_path)); + +/* Specific to slices. */ +AL_FUNC(ALLEGRO_FILE*, al_fopen_slice, (ALLEGRO_FILE *fp, + size_t initial_size, const char *mode)); + +/* Thread-local state. */ +AL_FUNC(const ALLEGRO_FILE_INTERFACE *, al_get_new_file_interface, (void)); +AL_FUNC(void, al_set_new_file_interface, (const ALLEGRO_FILE_INTERFACE * + file_interface)); +AL_FUNC(void, al_set_standard_file_interface, (void)); + +/* ALLEGRO_FILE field accessors */ +AL_FUNC(void *, al_get_file_userdata, (ALLEGRO_FILE *f)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/fixed.h b/allegro/include/allegro5/fixed.h new file mode 100644 index 00000000..7ecc79e7 --- /dev/null +++ b/allegro/include/allegro5/fixed.h @@ -0,0 +1,41 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Fixed point type. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_fixed_h +#define __al_included_allegro5_fixed_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: al_fixed + */ +typedef int32_t al_fixed; + +AL_VAR(const al_fixed, al_fixtorad_r); +AL_VAR(const al_fixed, al_radtofix_r); + +#ifdef __cplusplus + } +#endif + +#endif + + diff --git a/allegro/include/allegro5/fmaths.h b/allegro/include/allegro5/fmaths.h new file mode 100644 index 00000000..e94e4cab --- /dev/null +++ b/allegro/include/allegro5/fmaths.h @@ -0,0 +1,46 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Fixed point math routines. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_fmaths_h +#define __al_included_allegro5_fmaths_h + +#include "allegro5/base.h" +#include "allegro5/fixed.h" + +#ifdef __cplusplus + extern "C" { +#endif + +AL_FUNC(al_fixed, al_fixsqrt, (al_fixed x)); +AL_FUNC(al_fixed, al_fixhypot, (al_fixed x, al_fixed y)); +AL_FUNC(al_fixed, al_fixatan, (al_fixed x)); +AL_FUNC(al_fixed, al_fixatan2, (al_fixed y, al_fixed x)); + +AL_ARRAY(al_fixed, _al_fix_cos_tbl); +AL_ARRAY(al_fixed, _al_fix_tan_tbl); +AL_ARRAY(al_fixed, _al_fix_acos_tbl); + +#ifdef __cplusplus + } +#endif + +#include "allegro5/inline/fmaths.inl" + +#endif + + diff --git a/allegro/include/allegro5/fshook.h b/allegro/include/allegro5/fshook.h new file mode 100644 index 00000000..dcd35b68 --- /dev/null +++ b/allegro/include/allegro5/fshook.h @@ -0,0 +1,148 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * File System Hooks. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_fshook_h +#define __al_included_allegro5_fshook_h + +#include "allegro5/base.h" +#include "allegro5/file.h" +#include "allegro5/path.h" + +#ifdef ALLEGRO_HAVE_SYS_TYPES_H + #include +#else +/* 4 Gig max offsets if sys/types doesn't exist. */ +typedef unsigned int off_t; +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_FS_ENTRY + */ +typedef struct ALLEGRO_FS_ENTRY ALLEGRO_FS_ENTRY; + +struct ALLEGRO_FS_ENTRY { + struct ALLEGRO_FS_INTERFACE const *vtable; +}; + + +/* Enum: ALLEGRO_FILE_MODE + */ +typedef enum ALLEGRO_FILE_MODE +{ + ALLEGRO_FILEMODE_READ = 1, + ALLEGRO_FILEMODE_WRITE = 1 << 1, + ALLEGRO_FILEMODE_EXECUTE = 1 << 2, + ALLEGRO_FILEMODE_HIDDEN = 1 << 3, + ALLEGRO_FILEMODE_ISFILE = 1 << 4, + ALLEGRO_FILEMODE_ISDIR = 1 << 5 +} ALLEGRO_FILE_MODE; + + +#ifndef EOF + #define EOF (-1) +#endif + + +/* Type: ALLEGRO_FS_INTERFACE + */ +typedef struct ALLEGRO_FS_INTERFACE ALLEGRO_FS_INTERFACE; + +struct ALLEGRO_FS_INTERFACE { + AL_METHOD(ALLEGRO_FS_ENTRY *, fs_create_entry, (const char *path)); + AL_METHOD(void, fs_destroy_entry, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(const char *, fs_entry_name, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(bool, fs_update_entry, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(uint32_t, fs_entry_mode, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(time_t, fs_entry_atime, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(time_t, fs_entry_mtime, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(time_t, fs_entry_ctime, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(off_t, fs_entry_size, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(bool, fs_entry_exists, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(bool, fs_remove_entry, (ALLEGRO_FS_ENTRY *e)); + + AL_METHOD(bool, fs_open_directory, (ALLEGRO_FS_ENTRY *e)); + AL_METHOD(ALLEGRO_FS_ENTRY *, fs_read_directory,(ALLEGRO_FS_ENTRY *e)); + AL_METHOD(bool, fs_close_directory, (ALLEGRO_FS_ENTRY *e)); + + AL_METHOD(bool, fs_filename_exists, (const char *path)); + AL_METHOD(bool, fs_remove_filename, (const char *path)); + AL_METHOD(char *, fs_get_current_directory, (void)); + AL_METHOD(bool, fs_change_directory, (const char *path)); + AL_METHOD(bool, fs_make_directory, (const char *path)); + + AL_METHOD(ALLEGRO_FILE *, fs_open_file, (ALLEGRO_FS_ENTRY *e, + const char *mode)); +}; + +AL_FUNC(ALLEGRO_FS_ENTRY *, al_create_fs_entry, (const char *path)); +AL_FUNC(void, al_destroy_fs_entry, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(const char *, al_get_fs_entry_name,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(bool, al_update_fs_entry, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(uint32_t, al_get_fs_entry_mode,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(time_t, al_get_fs_entry_atime,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(time_t, al_get_fs_entry_mtime,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(time_t, al_get_fs_entry_ctime,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(off_t, al_get_fs_entry_size,(ALLEGRO_FS_ENTRY *e)); +AL_FUNC(bool, al_fs_entry_exists, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(bool, al_remove_fs_entry, (ALLEGRO_FS_ENTRY *e)); + +AL_FUNC(bool, al_open_directory, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(ALLEGRO_FS_ENTRY *, al_read_directory, (ALLEGRO_FS_ENTRY *e)); +AL_FUNC(bool, al_close_directory, (ALLEGRO_FS_ENTRY *e)); + +AL_FUNC(bool, al_filename_exists, (const char *path)); +AL_FUNC(bool, al_remove_filename, (const char *path)); +AL_FUNC(char *, al_get_current_directory, (void)); +AL_FUNC(bool, al_change_directory, (const char *path)); +AL_FUNC(bool, al_make_directory, (const char *path)); + +AL_FUNC(ALLEGRO_FILE *, al_open_fs_entry, (ALLEGRO_FS_ENTRY *e, + const char *mode)); + + + +/* Helper function for iterating over a directory using a callback. */ + +/* Type: ALLEGRO_FOR_EACH_FS_ENTRY_RESULT + */ +typedef enum ALLEGRO_FOR_EACH_FS_ENTRY_RESULT { + ALLEGRO_FOR_EACH_FS_ENTRY_ERROR = -1, + ALLEGRO_FOR_EACH_FS_ENTRY_OK = 0, + ALLEGRO_FOR_EACH_FS_ENTRY_SKIP = 1, + ALLEGRO_FOR_EACH_FS_ENTRY_STOP = 2 +} ALLEGRO_FOR_EACH_FS_ENTRY_RESULT; + +AL_FUNC(int, al_for_each_fs_entry, (ALLEGRO_FS_ENTRY *dir, + int (*callback)(ALLEGRO_FS_ENTRY *entry, void *extra), + void *extra)); + + +/* Thread-local state. */ +AL_FUNC(const ALLEGRO_FS_INTERFACE *, al_get_fs_interface, (void)); +AL_FUNC(void, al_set_fs_interface, (const ALLEGRO_FS_INTERFACE *vtable)); +AL_FUNC(void, al_set_standard_fs_interface, (void)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/fullscreen_mode.h b/allegro/include/allegro5/fullscreen_mode.h new file mode 100644 index 00000000..c158ce91 --- /dev/null +++ b/allegro/include/allegro5/fullscreen_mode.h @@ -0,0 +1,33 @@ +#ifndef __al_included_allegro5_fullscreen_mode_h +#define __al_included_allegro5_fullscreen_mode_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_DISPLAY_MODE + */ +typedef struct ALLEGRO_DISPLAY_MODE +{ + int width; + int height; + int format; + int refresh_rate; +} ALLEGRO_DISPLAY_MODE; + + +AL_FUNC(int, al_get_num_display_modes, (void)); +AL_FUNC(ALLEGRO_DISPLAY_MODE*, al_get_display_mode, (int index, + ALLEGRO_DISPLAY_MODE *mode)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/haptic.h b/allegro/include/allegro5/haptic.h new file mode 100644 index 00000000..5de93967 --- /dev/null +++ b/allegro/include/allegro5/haptic.h @@ -0,0 +1,247 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Haptic (that is, force feedback) routines for Allegro. + * + * By Beoran. + * + * See LICENSE.txt for copyright information. + */ + +#ifndef __al_included_allegro5_haptic_h +#define __al_included_allegro5_haptic_h + +#include "allegro5/base.h" +#include "allegro5/display.h" +#include "allegro5/events.h" +#include "allegro5/joystick.h" +#include "allegro5/keyboard.h" +#include "allegro5/mouse.h" +#include "allegro5/touch_input.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) + +/* Enum: ALLEGRO_HAPTIC_CONSTANTS + */ +enum ALLEGRO_HAPTIC_CONSTANTS +{ + ALLEGRO_HAPTIC_RUMBLE = 1 << 0, + ALLEGRO_HAPTIC_PERIODIC = 1 << 1, + ALLEGRO_HAPTIC_CONSTANT = 1 << 2, + ALLEGRO_HAPTIC_SPRING = 1 << 3, + ALLEGRO_HAPTIC_FRICTION = 1 << 4, + ALLEGRO_HAPTIC_DAMPER = 1 << 5, + ALLEGRO_HAPTIC_INERTIA = 1 << 6, + ALLEGRO_HAPTIC_RAMP = 1 << 7, + ALLEGRO_HAPTIC_SQUARE = 1 << 8, + ALLEGRO_HAPTIC_TRIANGLE = 1 << 9, + ALLEGRO_HAPTIC_SINE = 1 << 10, + ALLEGRO_HAPTIC_SAW_UP = 1 << 11, + ALLEGRO_HAPTIC_SAW_DOWN = 1 << 12, + ALLEGRO_HAPTIC_CUSTOM = 1 << 13, + ALLEGRO_HAPTIC_GAIN = 1 << 14, + ALLEGRO_HAPTIC_ANGLE = 1 << 15, + ALLEGRO_HAPTIC_RADIUS = 1 << 16, + ALLEGRO_HAPTIC_AZIMUTH = 1 << 17, + ALLEGRO_HAPTIC_AUTOCENTER= 1 << 18, +}; + + + +/* Type: ALLEGRO_HAPTIC + */ +typedef struct ALLEGRO_HAPTIC ALLEGRO_HAPTIC; + +/* Direction of a haptic effect. Angle is a value between 0 and 2*M_PI. + * An angle 0 means oriented towards the user, M_PI is away from the user + * (towards the screen). Angle is only supported if the device capabilities + * include ALLEGRO_HAPTIC_ANGLE. + * + * Radius (if supported) is the distance of the effect from the user as a + * value between 0 and 1. Normally it is zero. Radius is only supported if the + * device capabilities include ALLEGRO_HAPTIC_RADIUS. + * + * Azimuth is the angle of elevation, between -M_PI/2 and M_PI/2. + * Zero points to the horizontal plane, -M_PI/2 points down, and M_PI/2 points + * up. Azimuth is only supported if the device capabilities include + * ALLEGRO_HAPTIC_AZIMUTH. + */ +struct ALLEGRO_HAPTIC_DIRECTION +{ + double angle; + double radius; + double azimuth; +}; + +/* In all of the following structs, the doubles that express duration + * represent time in seconds. The double that represent levels of intensity + * are between 0.0 and 1.0. + */ + +/* Delay to start the replay and duration of the replay, expressed in seconds. */ +struct ALLEGRO_HAPTIC_REPLAY +{ + double length; + double delay; +}; + +/* Envelope of the effect. */ +struct ALLEGRO_HAPTIC_ENVELOPE +{ + double attack_length; + double attack_level; + double fade_length; + double fade_level; +}; + +/* Constant effect. Level is between 0.0 and 1.0. */ +struct ALLEGRO_HAPTIC_CONSTANT_EFFECT +{ + double level; + struct ALLEGRO_HAPTIC_ENVELOPE envelope; +}; + +/* Ramp effect. Both start_level and end level are between 0.0 and 1.0. */ +struct ALLEGRO_HAPTIC_RAMP_EFFECT +{ + double start_level; + double end_level; + struct ALLEGRO_HAPTIC_ENVELOPE envelope; +}; + +/* Condition effect. */ +struct ALLEGRO_HAPTIC_CONDITION_EFFECT +{ + double right_saturation; + double left_saturation; + double right_coeff; + double left_coeff; + double deadband; + double center; +}; + +/* Periodic (wave) effect. */ +struct ALLEGRO_HAPTIC_PERIODIC_EFFECT +{ + int waveform; + double period; + double magnitude; + double offset; + double phase; + + struct ALLEGRO_HAPTIC_ENVELOPE envelope; + int custom_len; + double *custom_data; +}; + +/* Simple rumble effect with a magnitude between 0.0 and 1.0 for both + * the strong and the weak rumble motors in the haptic device. + */ +struct ALLEGRO_HAPTIC_RUMBLE_EFFECT +{ + double strong_magnitude; + double weak_magnitude; +}; + +union ALLEGRO_HAPTIC_EFFECT_UNION +{ + struct ALLEGRO_HAPTIC_CONSTANT_EFFECT constant; + struct ALLEGRO_HAPTIC_RAMP_EFFECT ramp; + struct ALLEGRO_HAPTIC_PERIODIC_EFFECT periodic; + struct ALLEGRO_HAPTIC_CONDITION_EFFECT condition; + struct ALLEGRO_HAPTIC_RUMBLE_EFFECT rumble; +}; + + +/* Type: ALLEGRO_HAPTIC_EFFECT + */ +struct ALLEGRO_HAPTIC_EFFECT +{ + + int type; + struct ALLEGRO_HAPTIC_DIRECTION direction; + struct ALLEGRO_HAPTIC_REPLAY replay; + union ALLEGRO_HAPTIC_EFFECT_UNION data; +}; + +typedef struct ALLEGRO_HAPTIC_EFFECT ALLEGRO_HAPTIC_EFFECT; + + +/* Type: ALLEGRO_HAPTIC_EFFECT_ID + */ +typedef struct ALLEGRO_HAPTIC_EFFECT_ID ALLEGRO_HAPTIC_EFFECT_ID; + +struct ALLEGRO_HAPTIC_EFFECT_ID +{ + ALLEGRO_HAPTIC *_haptic; + int _id; + int _handle; + void * _pointer; + double _effect_duration; + bool _playing; + double _start_time; + double _end_time; + void * driver; +}; + + +AL_FUNC(bool, al_install_haptic, (void)); +AL_FUNC(void, al_uninstall_haptic, (void)); +AL_FUNC(bool, al_is_haptic_installed, (void)); + +AL_FUNC(bool, al_is_mouse_haptic, (ALLEGRO_MOUSE *)); +AL_FUNC(bool, al_is_joystick_haptic, (ALLEGRO_JOYSTICK *)); +AL_FUNC(bool, al_is_keyboard_haptic, (ALLEGRO_KEYBOARD *)); +AL_FUNC(bool, al_is_display_haptic, (ALLEGRO_DISPLAY *)); +AL_FUNC(bool, al_is_touch_input_haptic, (ALLEGRO_TOUCH_INPUT *)); + +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_mouse, (ALLEGRO_MOUSE *)); +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_joystick, (ALLEGRO_JOYSTICK *)); +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_keyboard, (ALLEGRO_KEYBOARD *)); +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_display, (ALLEGRO_DISPLAY *)); +AL_FUNC(ALLEGRO_HAPTIC *, al_get_haptic_from_touch_input, (ALLEGRO_TOUCH_INPUT *)); + +AL_FUNC(bool, al_release_haptic, (ALLEGRO_HAPTIC *)); + +AL_FUNC(bool, al_is_haptic_active, (ALLEGRO_HAPTIC *)); +AL_FUNC(int, al_get_haptic_capabilities, (ALLEGRO_HAPTIC *)); +AL_FUNC(bool, al_is_haptic_capable, (ALLEGRO_HAPTIC *, int)); + +AL_FUNC(bool, al_set_haptic_gain, (ALLEGRO_HAPTIC *, double)); +AL_FUNC(double, al_get_haptic_gain, (ALLEGRO_HAPTIC *)); + +AL_FUNC(bool, al_set_haptic_autocenter, (ALLEGRO_HAPTIC *, double)); +AL_FUNC(double, al_get_haptic_autocenter, (ALLEGRO_HAPTIC *)); + + +AL_FUNC(int, al_get_max_haptic_effects, (ALLEGRO_HAPTIC *)); +AL_FUNC(bool, al_is_haptic_effect_ok, (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *)); +AL_FUNC(bool, al_upload_haptic_effect, (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, ALLEGRO_HAPTIC_EFFECT_ID *)); +AL_FUNC(bool, al_play_haptic_effect, (ALLEGRO_HAPTIC_EFFECT_ID *, int)); +AL_FUNC(bool, al_upload_and_play_haptic_effect, (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, ALLEGRO_HAPTIC_EFFECT_ID *, int)); +AL_FUNC(bool, al_stop_haptic_effect, (ALLEGRO_HAPTIC_EFFECT_ID *)); +AL_FUNC(bool, al_is_haptic_effect_playing, (ALLEGRO_HAPTIC_EFFECT_ID *)); +AL_FUNC(bool, al_release_haptic_effect, (ALLEGRO_HAPTIC_EFFECT_ID *)); +AL_FUNC(double, al_get_haptic_effect_duration, (ALLEGRO_HAPTIC_EFFECT *)); +AL_FUNC(bool, al_rumble_haptic, (ALLEGRO_HAPTIC *, double, double, ALLEGRO_HAPTIC_EFFECT_ID *)); + +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/inline/fmaths.inl b/allegro/include/allegro5/inline/fmaths.inl new file mode 100644 index 00000000..47b447e3 --- /dev/null +++ b/allegro/include/allegro5/inline/fmaths.inl @@ -0,0 +1,253 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Fixed point math inline functions (generic C). + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_inline_fmaths_inl +#define __al_included_allegro5_inline_fmaths_inl + +#include "allegro5/error.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* al_ftofix and al_fixtof are used in generic C versions of al_fixmul and al_fixdiv */ +AL_INLINE(al_fixed, al_ftofix, (double x), +{ + if (x > 32767.0) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + + if (x < -32767.0) { + al_set_errno(ERANGE); + return -0x7FFFFFFF; + } + + return (al_fixed)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); +}) + + +AL_INLINE(double, al_fixtof, (al_fixed x), +{ + return (double)x / 65536.0; +}) + + +AL_INLINE(al_fixed, al_fixadd, (al_fixed x, al_fixed y), +{ + al_fixed result = x + y; + + if (result >= 0) { + if ((x < 0) && (y < 0)) { + al_set_errno(ERANGE); + return -0x7FFFFFFF; + } + else + return result; + } + else { + if ((x > 0) && (y > 0)) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + else + return result; + } +}) + + +AL_INLINE(al_fixed, al_fixsub, (al_fixed x, al_fixed y), +{ + al_fixed result = x - y; + + if (result >= 0) { + if ((x < 0) && (y > 0)) { + al_set_errno(ERANGE); + return -0x7FFFFFFF; + } + else + return result; + } + else { + if ((x > 0) && (y < 0)) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + else + return result; + } +}) + + +/* In benchmarks conducted circa May 2005 we found that, in the main: + * - IA32 machines performed faster with one implementation; + * - AMD64 and G4 machines performed faster with another implementation. + * + * Benchmarks were mainly done with differing versions of gcc. + * Results varied with other compilers, optimisation levels, etc. + * so this is not optimal, though a tenable compromise. + * + * Note that the following implementation are NOT what were benchmarked. + * We had forgotten to put in overflow detection in those versions. + * If you don't need overflow detection then previous versions in the + * CVS tree might be worth looking at. + * + * PS. Don't move the #ifs inside the AL_INLINE; BCC doesn't like it. + */ +#if defined ALLEGRO_I386 + AL_INLINE(al_fixed, al_fixmul, (al_fixed x, al_fixed y), + { + return al_ftofix(al_fixtof(x) * al_fixtof(y)); + }) +#else + AL_INLINE(al_fixed, al_fixmul, (al_fixed x, al_fixed y), + { + int64_t lx = x; + int64_t ly = y; + int64_t lres = (lx*ly); + + if (lres > 0x7FFFFFFF0000LL) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + else if (lres < -0x7FFFFFFF0000LL) { + al_set_errno(ERANGE); + return 0x80000000; + } + else { + return (al_fixed) (lres >> 16); + } + }) +#endif /* al_fixmul() C implementations */ + + +#if defined ALLEGRO_CFG_NO_FPU +AL_INLINE(al_fixed, al_fixdiv, (al_fixed x, al_fixed y), +{ + int64_t lres = x; + if (y == 0) { + al_set_errno(ERANGE); + return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF; + } + lres <<= 16; + lres /= y; + if (lres > 0x7FFFFFFF) { + al_set_errno(ERANGE); + return 0x7FFFFFFF; + } + else if (lres < -0x7FFFFFFF) { + al_set_errno(ERANGE); + return 0x80000000; + } + else { + return (al_fixed)(lres); + } +}) +#else +AL_INLINE(al_fixed, al_fixdiv, (al_fixed x, al_fixed y), +{ + if (y == 0) { + al_set_errno(ERANGE); + return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF; + } + else + return al_ftofix(al_fixtof(x) / al_fixtof(y)); +}) +#endif + + +AL_INLINE(int, al_fixfloor, (al_fixed x), +{ + /* (x >> 16) is not portable */ + if (x >= 0) + return (x >> 16); + else + return ~((~x) >> 16); +}) + + +AL_INLINE(int, al_fixceil, (al_fixed x), +{ + if (x > 0x7FFF0000) { + al_set_errno(ERANGE); + return 0x7FFF; + } + + return al_fixfloor(x + 0xFFFF); +}) + + +AL_INLINE(al_fixed, al_itofix, (int x), +{ + return x << 16; +}) + + +AL_INLINE(int, al_fixtoi, (al_fixed x), +{ + return al_fixfloor(x) + ((x & 0x8000) >> 15); +}) + + +AL_INLINE(al_fixed, al_fixcos, (al_fixed x), +{ + return _al_fix_cos_tbl[((x + 0x4000) >> 15) & 0x1FF]; +}) + + +AL_INLINE(al_fixed, al_fixsin, (al_fixed x), +{ + return _al_fix_cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF]; +}) + + +AL_INLINE(al_fixed, al_fixtan, (al_fixed x), +{ + return _al_fix_tan_tbl[((x + 0x4000) >> 15) & 0xFF]; +}) + + +AL_INLINE(al_fixed, al_fixacos, (al_fixed x), +{ + if ((x < -65536) || (x > 65536)) { + al_set_errno(EDOM); + return 0; + } + + return _al_fix_acos_tbl[(x+65536+127)>>8]; +}) + + +AL_INLINE(al_fixed, al_fixasin, (al_fixed x), +{ + if ((x < -65536) || (x > 65536)) { + al_set_errno(EDOM); + return 0; + } + + return 0x00400000 - _al_fix_acos_tbl[(x+65536+127)>>8]; +}) + +#ifdef __cplusplus + } +#endif + +#endif + + diff --git a/allegro/include/allegro5/internal/aintern.h b/allegro/include/allegro5/internal/aintern.h new file mode 100644 index 00000000..4e4cb6d4 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern.h @@ -0,0 +1,56 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Some definitions for internal use by the library code. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_aintern_h +#define __al_included_allegro5_aintern_h + +#ifndef __al_included_allegro5_allegro_h + #error must include allegro5/allegro.h first +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#define _ALLEGRO_MIN(x,y) (((x) < (y)) ? (x) : (y)) +#define _ALLEGRO_MAX(x,y) (((x) > (y)) ? (x) : (y)) +#define _ALLEGRO_CLAMP(x,y,z) _ALLEGRO_MAX((x), _ALLEGRO_MIN((y), (z))) + +int _al_get_least_multiple(int val, int mul); + +/* message stuff */ +#define ALLEGRO_MESSAGE_SIZE 4096 + +/* various libc stuff */ +AL_FUNC(void *, _al_sane_realloc, (void *ptr, size_t size)); +AL_FUNC(char *, _al_sane_strncpy, (char *dest, const char *src, size_t n)); + + +#define _AL_RAND_MAX 0xFFFF +AL_FUNC(void, _al_srand, (int seed)); +AL_FUNC(int, _al_rand, (void)); + +AL_FUNC(int, _al_stricmp, (const char *s1, const char *s2)); + +#define _AL_INCHES_PER_MM 0.039370 + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_aatree.h b/allegro/include/allegro5/internal/aintern_aatree.h new file mode 100644 index 00000000..3d85dcae --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_aatree.h @@ -0,0 +1,24 @@ +#ifndef __al_included_allegro5_aintern_aatree_h +#define __al_included_allegro5_aintern_aatree_h + +typedef struct _AL_AATREE _AL_AATREE; + +struct _AL_AATREE +{ + int level; + _AL_AATREE *left; + _AL_AATREE *right; + const void *key; + void *value; +}; + +typedef int (*_al_cmp_t)(const void *a, const void *b); + +_AL_AATREE *_al_aa_insert(_AL_AATREE *T, const void *key, void *value, _al_cmp_t compare); +void *_al_aa_search(const _AL_AATREE *T, const void *key, _al_cmp_t compare); +_AL_AATREE *_al_aa_delete(_AL_AATREE *T, const void *key, _al_cmp_t compare, void **ret_value); +void _al_aa_free(_AL_AATREE *T); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_android.h b/allegro/include/allegro5/internal/aintern_android.h new file mode 100644 index 00000000..949a1fd8 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_android.h @@ -0,0 +1,225 @@ +#ifndef ALLEGRO_AINTERN_ANDROID_H +#define ALLEGRO_AINTERN_ANDROID_H + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/allegro_opengl.h" + +#include + +typedef struct ALLEGRO_SYSTEM_ANDROID { + ALLEGRO_SYSTEM system; +} ALLEGRO_SYSTEM_ANDROID; + +typedef struct ALLEGRO_DISPLAY_ANDROID { + ALLEGRO_DISPLAY display; + jobject surface_object; + + ALLEGRO_COND *cond; + ALLEGRO_MUTEX *mutex; + + bool created; + bool recreate; + bool first_run; + bool resize_acknowledge; + bool resize_acknowledge2; + bool resumed; + bool failed; + bool is_destroy_display; +} ALLEGRO_DISPLAY_ANDROID; + +ALLEGRO_SYSTEM_INTERFACE *_al_system_android_interface(void); +const ALLEGRO_FILE_INTERFACE *_al_get_apk_file_vtable(void); + +ALLEGRO_DISPLAY_INTERFACE *_al_get_android_display_driver(void); +ALLEGRO_KEYBOARD_DRIVER *_al_get_android_keyboard_driver(void); +ALLEGRO_MOUSE_DRIVER *_al_get_android_mouse_driver(void); +ALLEGRO_TOUCH_INPUT_DRIVER *_al_get_android_touch_input_driver(void); + +int _al_android_get_display_orientation(void); + +#define _jni_checkException(env) \ + __jni_checkException(env, __FILE__, __FUNCTION__, __LINE__) + +void __jni_checkException(JNIEnv *env, const char *file, const char *fname, int line); + +#define _jni_call(env, rett, method, args...) \ + ({ \ + rett ret = (*env)->method(env, ##args); \ + _jni_checkException(env); \ + ret; \ + }) + +#define _jni_callv(env, method, args...) \ + ({ \ + (*env)->method(env, ##args); \ + _jni_checkException(env); \ + }) + +#define _jni_callBooleanMethodV(env, obj, name, sig, args...) \ + ({ \ + jclass class_id = _jni_call(env, jclass, GetObjectClass, obj); \ + jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, \ + name, sig); \ + bool ret = false; \ + if (method_id == NULL) { \ + ALLEGRO_DEBUG("couldn't find method %s", name); \ + } \ + else { \ + ret = _jni_call(env, bool, CallBooleanMethod, obj, method_id, \ + ##args); \ + } \ + _jni_callv(env, DeleteLocalRef, class_id); \ + ret; \ + }) + +jobject _jni_callObjectMethod(JNIEnv *env, jobject object, + const char *name, const char *sig); +jobject _jni_callObjectMethodV(JNIEnv *env, jobject object, + const char *name, const char *sig, ...); +ALLEGRO_USTR *_jni_getString(JNIEnv *env, jobject object); +ALLEGRO_USTR *_jni_callStringMethod(JNIEnv *env, jobject obj, + const char *name, const char *sig); +jobject _jni_callStaticObjectMethodV(JNIEnv *env, jclass class_id, + const char *name, const char *sig, ...); +jint _jni_callStaticIntMethodV(JNIEnv *env, jclass cls, + const char *name, const char *sig, ...); + +#define _jni_callIntMethodV(env, obj, name, sig, args...) \ + ({ \ + jclass class_id = _jni_call(env, jclass, GetObjectClass, obj); \ + jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, \ + name, sig); \ + int ret = -1; \ + if (method_id == NULL) { \ + ALLEGRO_DEBUG("couldn't find method %s", #name); \ + } \ + else { \ + ret = _jni_call(env, int, CallIntMethod, obj, method_id, ##args); \ + } \ + _jni_callv(env, DeleteLocalRef, class_id); \ + ret; \ + }) + +#define _jni_callIntMethod(env, obj, name) \ + _jni_callIntMethodV(env, obj, name, "()I") + +#define _jni_callLongMethodV(env, obj, name, sig, args...) \ + ({ \ + jclass class_id = _jni_call(env, jclass, GetObjectClass, obj); \ + jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, \ + name, sig); \ + long ret = -1; \ + if (method_id == NULL) { \ + ALLEGRO_DEBUG("couldn't find method %s", name); \ + } \ + else { \ + ret = _jni_call(env, long, CallLongMethod, obj, method_id, ##args); \ + } \ + _jni_callv(env, DeleteLocalRef, class_id); \ + ret; \ + }) + +#define _jni_callLongMethod(env, obj, name) \ + _jni_callLongMethodV(env, obj, name, "()J"); + +#define _jni_callVoidMethodV(env, obj, name, sig, args...) \ + ({ \ + jclass class_id = _jni_call(env, jclass, GetObjectClass, obj); \ + jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, \ + name, sig); \ + if (method_id == NULL) { \ + ALLEGRO_ERROR("couldn't find method %s", name); \ + } else { \ + _jni_callv(env, CallVoidMethod, obj, method_id, ##args); \ + } \ + _jni_callv(env, DeleteLocalRef, class_id); \ + }) + +#define _jni_callVoidMethod(env, obj, name) \ + _jni_callVoidMethodV(env, obj, name, "()V"); + +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_android_joystick_driver); + +void _al_android_create_surface(JNIEnv *env, bool post); +void _al_android_destroy_surface(JNIEnv *env, jobject obj, bool post); + +ALLEGRO_BITMAP *_al_android_load_image_f(ALLEGRO_FILE *fh, int flags); +ALLEGRO_BITMAP *_al_android_load_image(const char *filename, int flags); + +jobject _al_android_activity_object(void); +jclass _al_android_input_stream_class(void); +jclass _al_android_apk_stream_class(void); +jclass _al_android_image_loader_class(void); +jclass _al_android_clipboard_class(void); +jclass _al_android_apk_fs_class(void); + +void _al_android_generate_mouse_event(unsigned int type, int x, int y, + unsigned int button, ALLEGRO_DISPLAY *d); +void _al_android_mouse_get_state(ALLEGRO_MOUSE_STATE *ret_state); + +void _al_android_generate_accelerometer_event(float x, float y, float z); +void _al_android_generate_joystick_axis_event(int index, int stick, int axis, float value); +void _al_android_generate_joystick_button_event(int index, int button, bool down); + +GLint _al_android_get_curr_fbo(void); +void _al_android_set_curr_fbo(GLint fbo); +bool _al_android_is_os_2_1(void); +void _al_android_thread_created(void); +void _al_android_thread_ended(void); + +void _al_android_set_jnienv(JNIEnv *jnienv); +JNIEnv *_al_android_get_jnienv(void); +bool _al_android_is_paused(void); + +void _al_android_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt); + +#define ALLEGRO_ANDROID_PACKAGE_NAME org_liballeg_android +#define ALLEGRO_ANDROID_PACKAGE_NAME_SLASH "org/liballeg/android" + +#define JNI_FUNC_PASTER(ret, cls, name, params, x) \ + JNIEXPORT ret JNICALL Java_ ## x ## _ ## cls ## _ ## name params +#define JNI_FUNC_EVALUATOR(ret, cls, name, params, x) \ + JNI_FUNC_PASTER(ret, cls, name, params, x) +#define JNI_FUNC(ret, cls, name, params) \ + JNI_FUNC_EVALUATOR(ret, cls, name, params, ALLEGRO_ANDROID_PACKAGE_NAME) + +/* Functions called from Java code. */ +extern JNI_FUNC(bool, AllegroActivity, nativeOnCreate, (JNIEnv *env, jobject obj)); +extern JNI_FUNC(void, AllegroActivity, nativeOnDestroy, (JNIEnv *env, jobject obj)); +extern JNI_FUNC(void, AllegroActivity, nativeOnOrientationChange, (JNIEnv *env, + jobject obj, int orientation, bool init)); +extern JNI_FUNC(void, AllegroActivity, nativeOnPause, (JNIEnv *env, jobject obj)); +extern JNI_FUNC(void, AllegroActivity, nativeOnResume, (JNIEnv *env, jobject obj)); +extern JNI_FUNC(void, AllegroSurface, nativeOnCreate, (JNIEnv *env, jobject obj)); +extern JNI_FUNC(bool, AllegroSurface, nativeOnDestroy, (JNIEnv *env, jobject obj)); +extern JNI_FUNC(void, AllegroSurface, nativeOnChange, (JNIEnv *env, jobject obj, + jint format, jint width, jint height)); +extern JNI_FUNC(int, AllegroInputStream, nativeRead, (JNIEnv *env, jobject obj, + jlong handle, jbyteArray array, int offset, int length)); +extern JNI_FUNC(void, AllegroInputStream, nativeClose, (JNIEnv *env, jobject obj, + jlong handle)); +extern JNI_FUNC(void, KeyListener, nativeOnKeyDown, (JNIEnv *env, jobject obj, + jint scancode, jint unichar)); +extern JNI_FUNC(void, KeyListener, nativeOnKeyUp, (JNIEnv *env, jobject obj, + jint scancode)); +extern JNI_FUNC(void, KeyListener, nativeOnKeyChar, (JNIEnv *env, jobject obj, + jint scancode, jint unichar)); +extern JNI_FUNC(void, TouchListener, nativeOnTouch, (JNIEnv *env, jobject obj, + jint id, jint action, jfloat x, jfloat y, jboolean primary)); +extern JNI_FUNC(void, Sensors, nativeOnAccel, (JNIEnv *env, jobject obj, jint id, + jfloat x, jfloat y, jfloat z)); + +extern JNI_FUNC(void, AllegroSurface, nativeOnJoystickAxis, (JNIEnv *env, jobject obj, + jint index, jint stick, jint axis, jfloat value)); +extern JNI_FUNC(void, AllegroSurface, nativeOnJoystickButton, (JNIEnv *env, jobject obj, + jint index, jint button, jboolean down)); +extern JNI_FUNC(void, KeyListener, nativeOnJoystickButton, (JNIEnv *env, jobject obj, + jint index, jint button, jboolean down)); +extern JNI_FUNC(void, AllegroActivity, nativeSendJoystickConfigurationEvent, + (JNIEnv *env, jobject obj)); + +#endif /* ALLEGRO_AINTERN_ANDROID_H */ + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_atomicops.h b/allegro/include/allegro5/internal/aintern_atomicops.h new file mode 100644 index 00000000..50545521 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_atomicops.h @@ -0,0 +1,120 @@ +#ifndef __al_included_allegro5_aintern_atomicops_h +#define __al_included_allegro5_aintern_atomicops_h + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) + + /* gcc 4.1 and above have builtin atomic operations. */ + + typedef int _AL_ATOMIC; + + AL_INLINE(_AL_ATOMIC, + _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), + { + return __sync_fetch_and_add(ptr, 1); + }) + + AL_INLINE(_AL_ATOMIC, + _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), + { + return __sync_sub_and_fetch(ptr, 1); + }) + +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + + /* gcc, x86 or x86-64 */ + + typedef int _AL_ATOMIC; + + #define __al_fetch_and_add(ptr, value, result) \ + __asm__ __volatile__ ( \ + "lock; xaddl %0, %1" \ + : "=r" (result), "=m" (*ptr) \ + : "0" (value), "m" (*ptr) \ + : "memory" \ + ) + + AL_INLINE(_AL_ATOMIC, + _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), + { + _AL_ATOMIC result; + __al_fetch_and_add(ptr, 1, result); + return result; + }) + + AL_INLINE(_AL_ATOMIC, + _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), + { + _AL_ATOMIC old; + __al_fetch_and_add(ptr, -1, old); + return old - 1; + }) + +#elif defined(_MSC_VER) && _M_IX86 >= 400 + + /* MSVC, x86 */ + /* MinGW supports these too, but we already have asm code above. */ + + typedef LONG _AL_ATOMIC; + + AL_INLINE(_AL_ATOMIC, + _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), + { + return InterlockedIncrement(ptr) - 1; + }) + + AL_INLINE(_AL_ATOMIC, + _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), + { + return InterlockedDecrement(ptr); + }) + +#elif defined(ALLEGRO_HAVE_OSATOMIC_H) + + /* OS X, GCC < 4.1 + * These functions only work on Tiger (10.4) and above. + * FIXME: Apple's manpage says these functions take volatile int* + * arguments, but at least the 10.4 SDK seems to prototype them as + * taking int * - should the volatile qualifier be removed from the + * wrapper functions in this case? (EG) + */ + + #include + typedef int32_t _AL_ATOMIC; + + AL_INLINE(_AL_ATOMIC, + _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), + { + return OSAtomicIncrement32Barrier((_AL_ATOMIC *)ptr) - 1; + }) + + AL_INLINE(_AL_ATOMIC, + _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), + { + return OSAtomicDecrement32Barrier((_AL_ATOMIC *)ptr); + }) + + +#else + + /* Hope for the best? */ + #warning Atomic operations undefined for your compiler/architecture. + + typedef int _AL_ATOMIC; + + AL_INLINE(_AL_ATOMIC, + _al_fetch_and_add1, (volatile _AL_ATOMIC *ptr), + { + return (*ptr)++; + }) + + AL_INLINE(_AL_ATOMIC, + _al_sub1_and_fetch, (volatile _AL_ATOMIC *ptr), + { + return --(*ptr); + }) + +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_bitmap.h b/allegro/include/allegro5/internal/aintern_bitmap.h new file mode 100644 index 00000000..d723fa3b --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_bitmap.h @@ -0,0 +1,188 @@ +#ifndef __al_included_allegro5_aintern_bitmap_h +#define __al_included_allegro5_aintern_bitmap_h + +#include "allegro5/bitmap.h" +#include "allegro5/bitmap_lock.h" +#include "allegro5/display.h" +#include "allegro5/render_state.h" +#include "allegro5/transformations.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ALLEGRO_BITMAP_INTERFACE ALLEGRO_BITMAP_INTERFACE; + +struct ALLEGRO_BITMAP +{ + ALLEGRO_BITMAP_INTERFACE *vt; + + /* + * When this is a sub-bitmap, these are inherited from the parent. Don't + * access them directly, but use al_get_bitmap_format/flags or + * _al_get_bitmap_display unless you are super sure this is not a sub-bitmap + * (e.g. when you're creating a new bitmap). + */ + int _format; + int _flags; + int _depth; + int _samples; + ALLEGRO_DISPLAY *_display; + /* What format is used for the backing memory + * (can be different from _format, for e.g. compressed bitmaps) */ + int _memory_format; + + int w, h; + /* + * The number of bytes between a pixel at (x,y) and (x,y+1). + * This is larger than w * pixel_size if there is padding between lines. + */ + int pitch; + /* + * clip left, right, top, bottom + * Clip anything outside of this. cr/cb are exclusive, that is (0, 0, 1, 1) + * is the single pixel spawning a rectangle from floating point 0/0 to 1/1 - + * or in other words, the single pixel 0/0. + * + * There is always confusion as to whether cr/cb are exclusive, leading to + * subtle bugs. The suffixes are supposed to help with that. + */ + int cl; + int cr_excl; + int ct; + int cb_excl; + /* + * Locking info. + * + * These values represent the actual locking dimensions, which may be different + * from what was passed in to al_lock_bitmap_region. This is transparent to the + * user, but the internal drawing functions must take this into account. To + * that end, use this lock_data parameter value and NOT the one in locked_region. + * + * locked - locked or not? + * lock_x/y - top left of the locked region + * lock_w/h - width and height of the locked region + * lock_flags - flags the region was locked with + * lock_data - the pointer to the real locked data (see above) + * locked_region - a copy of the locked rectangle + */ + bool locked; + int lock_x; + int lock_y; + int lock_w; + int lock_h; + void* lock_data; + int lock_flags; + ALLEGRO_LOCKED_REGION locked_region; + + /* Transformation for this bitmap */ + ALLEGRO_TRANSFORM transform; + ALLEGRO_TRANSFORM inverse_transform; + bool inverse_transform_dirty; + ALLEGRO_TRANSFORM proj_transform; + + /* Blender for this bitmap (if not set, use TLS) */ + bool use_bitmap_blender; + ALLEGRO_BLENDER blender; + + /* Shader applied to this bitmap. Set this field with + * _al_set_bitmap_shader_field to maintain invariants. + */ + ALLEGRO_SHADER *shader; + + /* Info for sub-bitmaps */ + ALLEGRO_BITMAP *parent; + int xofs; + int yofs; + + /* A memory copy of the bitmap data. May be NULL for an empty bitmap. */ + unsigned char *memory; + + /* Extra data for display bitmaps, like texture id and so on. */ + void *extra; + + _AL_LIST_ITEM *dtor_item; + + /* set_target_bitmap and lock_bitmap mark bitmaps as dirty for preservation */ + bool dirty; +}; + +struct ALLEGRO_BITMAP_INTERFACE +{ + int id; + + void (*draw_bitmap_region)(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint,float sx, float sy, + float sw, float sh, int flags); + + /* After the memory-copy of the bitmap has been modified, need to call this + * to update the display-specific copy. E.g. with an OpenGL driver, this + * might create/update a texture. Returns false on failure. + */ + bool (*upload_bitmap)(ALLEGRO_BITMAP *bitmap); + + void (*update_clipping_rectangle)(ALLEGRO_BITMAP *bitmap); + + void (*destroy_bitmap)(ALLEGRO_BITMAP *bitmap); + + ALLEGRO_LOCKED_REGION * (*lock_region)(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int format, int flags); + + void (*unlock_region)(ALLEGRO_BITMAP *bitmap); + + ALLEGRO_LOCKED_REGION * (*lock_compressed_region)(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int flags); + + void (*unlock_compressed_region)(ALLEGRO_BITMAP *bitmap); + + /* Used to update any dangling pointers the bitmap driver might keep. */ + void (*bitmap_pointer_changed)(ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP *old); + + /* Back up texture to system RAM */ + void (*backup_dirty_bitmap)(ALLEGRO_BITMAP *bitmap); +}; + +ALLEGRO_BITMAP *_al_create_bitmap_params(ALLEGRO_DISPLAY *current_display, + int w, int h, int format, int flags, int depth, int samples); + +AL_FUNC(ALLEGRO_DISPLAY*, _al_get_bitmap_display, (ALLEGRO_BITMAP *bitmap)); + +extern void (*_al_convert_funcs[ALLEGRO_NUM_PIXEL_FORMATS] + [ALLEGRO_NUM_PIXEL_FORMATS])(const void *, int, void *, int, + int, int, int, int, int, int); + +/* Bitmap conversion */ +void _al_convert_bitmap_data( + const void *src, int src_format, int src_pitch, + void *dst, int dst_format, int dst_pitch, + int sx, int sy, int dx, int dy, + int width, int height); + +void _al_copy_bitmap_data( + const void *src, int src_pitch, void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height, + int format); + +/* Bitmap type conversion */ +void _al_init_convert_bitmap_list(void); +void _al_register_convert_bitmap(ALLEGRO_BITMAP *bitmap); +void _al_unregister_convert_bitmap(ALLEGRO_BITMAP *bitmap); +void _al_convert_to_display_bitmap(ALLEGRO_BITMAP *bitmap); +void _al_convert_to_memory_bitmap(ALLEGRO_BITMAP *bitmap); + +/* Simple bitmap drawing */ +void _al_put_pixel(ALLEGRO_BITMAP *bitmap, int x, int y, ALLEGRO_COLOR color); + +/* Bitmap I/O */ +void _al_init_iio_table(void); + + +int _al_get_bitmap_memory_format(ALLEGRO_BITMAP *bitmap); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_blend.h b/allegro/include/allegro5/internal/aintern_blend.h new file mode 100644 index 00000000..f69d815d --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_blend.h @@ -0,0 +1,255 @@ +#ifndef __al_included_allegro5_aintern_blend_h +#define __al_included_allegro5_aintern_blend_h + +#include "allegro5/internal/aintern.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef __GNUC__ + #define _AL_ALWAYS_INLINE inline __attribute__((always_inline)) +#else + #define _AL_ALWAYS_INLINE INLINE +#endif + + +#define _AL_DEST_IS_ZERO \ + (dst_mode == ALLEGRO_ZERO && dst_alpha == ALLEGRO_ZERO && \ + op != ALLEGRO_DEST_MINUS_SRC && op_alpha != ALLEGRO_DEST_MINUS_SRC) + +#define _AL_SRC_NOT_MODIFIED \ + (src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE) + +#define _AL_SRC_NOT_MODIFIED_TINT_WHITE \ + (_AL_SRC_NOT_MODIFIED && \ + tint.r == 1.0f && tint.g == 1.0f && tint.b == 1.0f && tint.a == 1.0f) + + +#ifndef _AL_NO_BLEND_INLINE_FUNC + +/* Only cares about alpha blending modes. */ +static _AL_ALWAYS_INLINE float +get_alpha_factor(enum ALLEGRO_BLEND_MODE operation, float src_alpha, float dst_alpha, ALLEGRO_COLOR* const_alpha) +{ + switch (operation) { + case ALLEGRO_ZERO: return 0; + case ALLEGRO_ONE: return 1; + case ALLEGRO_ALPHA: return src_alpha; + case ALLEGRO_INVERSE_ALPHA: return 1 - src_alpha; + case ALLEGRO_SRC_COLOR: return src_alpha; + case ALLEGRO_DEST_COLOR: return dst_alpha; + case ALLEGRO_INVERSE_SRC_COLOR: return 1 - src_alpha; + case ALLEGRO_INVERSE_DEST_COLOR: return 1 - dst_alpha; + case ALLEGRO_CONST_COLOR: return const_alpha->a; + case ALLEGRO_INVERSE_CONST_COLOR: return 1 - const_alpha->a; + default: + ASSERT(false); + return 0; /* silence warning in release build */ + } +} + +/* Puts the blending factor in an ALLEGRO_COLOR object. */ +static _AL_ALWAYS_INLINE void get_factor(enum ALLEGRO_BLEND_MODE operation, + const ALLEGRO_COLOR *source, const ALLEGRO_COLOR *dest, ALLEGRO_COLOR *constcol, + ALLEGRO_COLOR *factor) +{ + switch (operation) { + case ALLEGRO_ZERO: + factor->r = factor->g = factor->b = factor->a = 0; + break; + case ALLEGRO_ONE: + factor->r = factor->g = factor->b = factor->a = 1; + break; + case ALLEGRO_ALPHA: + factor->r = factor->g = factor->b = factor->a = source->a; + break; + case ALLEGRO_INVERSE_ALPHA: + factor->r = factor->g = factor->b = factor->a = 1 - source->a; + break; + case ALLEGRO_SRC_COLOR: + *factor = *source; + break; + case ALLEGRO_DEST_COLOR: + *factor = *dest; + break; + case ALLEGRO_INVERSE_SRC_COLOR: + factor->r = 1 - source->r; + factor->g = 1 - source->g; + factor->b = 1 - source->b; + factor->a = 1 - source->a; + break; + case ALLEGRO_INVERSE_DEST_COLOR: + factor->r = 1 - dest->r; + factor->g = 1 - dest->g; + factor->b = 1 - dest->b; + factor->a = 1 - dest->a; + break; + case ALLEGRO_CONST_COLOR: + *factor = *constcol; + break; + case ALLEGRO_INVERSE_CONST_COLOR: + factor->r = 1 - constcol->r; + factor->g = 1 - constcol->g; + factor->b = 1 - constcol->b; + factor->a = 1 - constcol->a; + break; + default: + ASSERT(false); + factor->r = factor->g = factor->b = factor->a = 0; + break; + } +} + +/* Only call this if the blend modes are one of: + * ALLEGRO_ONE, ALLEGRO_ZERO, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA + */ +static _AL_ALWAYS_INLINE +void _al_blend_alpha_inline( + const ALLEGRO_COLOR *scol, const ALLEGRO_COLOR *dcol, + int op, int src_, int dst_, int aop, int asrc_, int adst_, + ALLEGRO_COLOR *constcol, ALLEGRO_COLOR *result) +{ + float asrc, adst; + float src, dst; + + result->r = scol->r; + result->g = scol->g; + result->b = scol->b; + result->a = scol->a; + + asrc = get_alpha_factor(asrc_, scol->a, dcol->a, constcol); + adst = get_alpha_factor(adst_, scol->a, dcol->a, constcol); + src = get_alpha_factor(src_, scol->a, dcol->a, constcol); + dst = get_alpha_factor(dst_, scol->a, dcol->a, constcol); + + #define BLEND(c, src, dst) \ + result->c = OP(result->c * src, dcol->c * dst); + switch (op) { + case ALLEGRO_ADD: + #define OP(x, y) _ALLEGRO_MIN(1, x + y) + BLEND(r, src, dst) + BLEND(g, src, dst) + BLEND(b, src, dst) + #undef OP + break; + case ALLEGRO_SRC_MINUS_DEST: + #define OP(x, y) _ALLEGRO_MAX(0, x - y) + BLEND(r, src, dst) + BLEND(g, src, dst) + BLEND(b, src, dst) + #undef OP + break; + case ALLEGRO_DEST_MINUS_SRC: + #define OP(x, y) _ALLEGRO_MAX(0, y - x) + BLEND(r, src, dst) + BLEND(g, src, dst) + BLEND(b, src, dst) + #undef OP + break; + } + + switch (aop) { + case ALLEGRO_ADD: + #define OP(x, y) _ALLEGRO_MIN(1, x + y) + BLEND(a, asrc, adst) + #undef OP + break; + case ALLEGRO_SRC_MINUS_DEST: + #define OP(x, y) _ALLEGRO_MAX(0, x - y) + BLEND(a, asrc, adst) + #undef OP + break; + case ALLEGRO_DEST_MINUS_SRC: + #define OP(x, y) _ALLEGRO_MAX(0, y - x) + BLEND(a, asrc, adst) + #undef OP + break; + } + #undef BLEND +} + +/* call this for general blending. its a little slower than just using alpha */ +static _AL_ALWAYS_INLINE +void _al_blend_inline( + const ALLEGRO_COLOR *scol, const ALLEGRO_COLOR *dcol, + int op, int src_, int dst_, int aop, int asrc_, int adst_, + ALLEGRO_COLOR *constcol, ALLEGRO_COLOR *result) +{ + float asrc, adst; + ALLEGRO_COLOR src, dst; + + result->r = scol->r; + result->g = scol->g; + result->b = scol->b; + result->a = scol->a; + + asrc = get_alpha_factor(asrc_, scol->a, dcol->a, constcol); + adst = get_alpha_factor(adst_, scol->a, dcol->a, constcol); + get_factor(src_, scol, dcol, constcol, &src); + get_factor(dst_, scol, dcol, constcol, &dst); + + #define BLEND(c, src, dst) \ + result->c = OP(result->c * src.c, dcol->c * dst.c); + switch (op) { + case ALLEGRO_ADD: + #define OP(x, y) _ALLEGRO_MIN(1, x + y) + BLEND(r, src, dst) + BLEND(g, src, dst) + BLEND(b, src, dst) + #undef OP + break; + case ALLEGRO_SRC_MINUS_DEST: + #define OP(x, y) _ALLEGRO_MAX(0, x - y) + BLEND(r, src, dst) + BLEND(g, src, dst) + BLEND(b, src, dst) + #undef OP + break; + case ALLEGRO_DEST_MINUS_SRC: + #define OP(x, y) _ALLEGRO_MAX(0, y - x) + BLEND(r, src, dst) + BLEND(g, src, dst) + BLEND(b, src, dst) + #undef OP + break; + } + #undef BLEND + + #define BLEND(c, src, dst) \ + result->c = OP(result->c * src, dcol->c * dst); + switch (aop) { + case ALLEGRO_ADD: + #define OP(x, y) _ALLEGRO_MIN(1, x + y) + BLEND(a, asrc, adst) + #undef OP + break; + case ALLEGRO_SRC_MINUS_DEST: + #define OP(x, y) _ALLEGRO_MAX(0, x - y) + BLEND(a, asrc, adst) + #undef OP + break; + case ALLEGRO_DEST_MINUS_SRC: + #define OP(x, y) _ALLEGRO_MAX(0, y - x) + BLEND(a, asrc, adst) + #undef OP + break; + } + #undef BLEND +} + +#endif + + +void _al_blend_memory(ALLEGRO_COLOR *src_color, ALLEGRO_BITMAP *dest, + int dx, int dy, ALLEGRO_COLOR *result); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_config.h b/allegro/include/allegro5/internal/aintern_config.h new file mode 100644 index 00000000..7551df5c --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_config.h @@ -0,0 +1,29 @@ +#ifndef __al_included_allegro5_aintern_config_h +#define __al_included_allegro5_aintern_config_h + +#include "allegro5/internal/aintern_aatree.h" + +struct ALLEGRO_CONFIG_ENTRY { + bool is_comment; + ALLEGRO_USTR *key; /* comment if is_comment is true */ + ALLEGRO_USTR *value; + ALLEGRO_CONFIG_ENTRY *prev, *next; +}; + +struct ALLEGRO_CONFIG_SECTION { + ALLEGRO_USTR *name; + ALLEGRO_CONFIG_ENTRY *head; + ALLEGRO_CONFIG_ENTRY *last; + _AL_AATREE *tree; + ALLEGRO_CONFIG_SECTION *prev, *next; +}; + +struct ALLEGRO_CONFIG { + ALLEGRO_CONFIG_SECTION *head; + ALLEGRO_CONFIG_SECTION *last; + _AL_AATREE *tree; +}; + + +#endif + diff --git a/allegro/include/allegro5/internal/aintern_convert.h b/allegro/include/allegro5/internal/aintern_convert.h new file mode 100644 index 00000000..51eb8a7a --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_convert.h @@ -0,0 +1,1614 @@ +// Warning: This file was created by make_converters.py - do not edit. +#ifndef __al_included_allegro5_aintern_convert_h +#define __al_included_allegro5_aintern_convert_h + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_pixels.h" +#define ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_8888(x) \ + ((((x) & 0xff000000) >> 24) /* A */ | \ + (((x) & 0x00ffffff) << 8) /* BGR */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_ARGB_4444(x) \ + ((((x) & 0xf0000000) >> 16) /* A */ | \ + (((x) & 0x000000f0) >> 4) /* B */ | \ + (((x) & 0x0000f000) >> 8) /* G */ | \ + (((x) & 0x00f00000) >> 12) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_RGB_888(x) \ + (((x) & 0x00ffffff) /* BGR */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_RGB_565(x) \ + ((((x) & 0x000000f8) >> 3) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x00f80000) >> 8) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_RGB_555(x) \ + ((((x) & 0x000000f8) >> 3) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x00f80000) >> 9) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_5551(x) \ + ((((x) & 0x80000000) >> 31) /* A */ | \ + (((x) & 0x000000f8) >> 2) /* B */ | \ + (((x) & 0x0000f800) >> 5) /* G */ | \ + (((x) & 0x00f80000) >> 8) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_ARGB_1555(x) \ + ((((x) & 0x80000000) >> 16) /* A */ | \ + (((x) & 0x000000f8) >> 3) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x00f80000) >> 9) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888(x) \ + ((((x) & 0x000000ff) << 16) /* B */ | \ + (((x) & 0x00ff0000) >> 16) /* R */ | \ + ((x) & 0xff00ff00) /* AG */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_XBGR_8888(x) \ + ((((x) & 0x000000ff) << 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x00ff0000) >> 16) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_BGR_888(x) \ + ((((x) & 0x000000ff) << 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x00ff0000) >> 16) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_BGR_565(x) \ + ((((x) & 0x000000f8) << 8) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x00f80000) >> 19) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_BGR_555(x) \ + ((((x) & 0x000000f8) << 7) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x00f80000) >> 19) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_RGBX_8888(x) \ + ((((x) & 0x00ffffff) << 8) /* BGR */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_XRGB_8888(x) \ + (((x) & 0x00ffffff) /* BGR */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_F32(x) \ + al_map_rgba(((x) >> 16) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 0) & 255,\ + ((x) >> 24) & 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888_LE(x) \ + ((((x) & 0xff000000) >> 24) /* A */ | \ + (((x) & 0x00ffffff) << 8) /* BGR */) +#else +#define ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888_LE(x) \ + ((((x) & 0x000000ff) << 16) /* B */ | \ + (((x) & 0x00ff0000) >> 16) /* R */ | \ + ((x) & 0xff00ff00) /* AG */) +#endif +#define ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_4444(x) \ + ((((x) & 0xf0000000) >> 28) /* A */ | \ + ((x) & 0x000000f0) /* B */ | \ + (((x) & 0x0000f000) >> 4) /* G */ | \ + (((x) & 0x00f00000) >> 8) /* R */) +#define ALLEGRO_CONVERT_ARGB_8888_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 16) & 0xff) +#define ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_8888(x) \ + ((((x) & 0x000000ff) << 24) /* A */ | \ + (((x) & 0xffffff00) >> 8) /* BGR */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_4444(x) \ + ((((x) & 0x000000f0) << 8) /* A */ | \ + (((x) & 0x0000f000) >> 12) /* B */ | \ + (((x) & 0x00f00000) >> 16) /* G */ | \ + (((x) & 0xf0000000) >> 20) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_RGB_888(x) \ + ((((x) & 0xffffff00) >> 8) /* BGR */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_RGB_565(x) \ + ((((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00fc0000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_RGB_555(x) \ + ((((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 17) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_RGBA_5551(x) \ + ((((x) & 0x00000080) >> 7) /* A */ | \ + (((x) & 0x0000f800) >> 10) /* B */ | \ + (((x) & 0x00f80000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_1555(x) \ + ((((x) & 0x00000080) << 8) /* A */ | \ + (((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 17) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888(x) \ + ((((x) & 0x000000ff) << 24) /* A */ | \ + (((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_XBGR_8888(x) \ + ((((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_BGR_888(x) \ + ((((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_BGR_565(x) \ + (((x) & 0x0000f800) /* B */ | \ + (((x) & 0x00fc0000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 27) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_BGR_555(x) \ + ((((x) & 0x0000f800) >> 1) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 27) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_RGBX_8888(x) \ + (((x) & 0xffffff00) /* BGR */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_XRGB_8888(x) \ + ((((x) & 0xffffff00) >> 8) /* BGR */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_F32(x) \ + al_map_rgba(((x) >> 24) & 255,\ + ((x) >> 16) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 0) & 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888_LE(x) \ + (((x) & 0xffffffff) /* ABGR */) +#else +#define ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888_LE(x) \ + ((((x) & 0x000000ff) << 24) /* A */ | \ + (((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#endif +#define ALLEGRO_CONVERT_RGBA_8888_TO_RGBA_4444(x) \ + ((((x) & 0x000000f0) >> 4) /* A */ | \ + (((x) & 0x0000f000) >> 8) /* B */ | \ + (((x) & 0x00f00000) >> 12) /* G */ | \ + (((x) & 0xf0000000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_8888_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 24) & 0xff) +#define ALLEGRO_CONVERT_ARGB_4444_TO_ARGB_8888(x) \ + ((_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_8888(x) \ + ((_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x000f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 24) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_RGB_888(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_RGB_565(x) \ + ((((x) & 0x000f) << 1) /* B */ | \ + (((x) & 0x00f0) << 3) /* G */ | \ + (((x) & 0x0f00) << 4) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_RGB_555(x) \ + ((((x) & 0x000f) << 1) /* B */ | \ + (((x) & 0x00f0) << 2) /* G */ | \ + (((x) & 0x0f00) << 3) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_5551(x) \ + ((((x) & 0x8000) >> 15) /* A */ | \ + (((x) & 0x000f) << 2) /* B */ | \ + (((x) & 0x00f0) << 3) /* G */ | \ + (((x) & 0x0f00) << 4) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_ARGB_1555(x) \ + (((x) & 0x8000) /* A */ | \ + (((x) & 0x000f) << 1) /* B */ | \ + (((x) & 0x00f0) << 2) /* G */ | \ + (((x) & 0x0f00) << 3) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888(x) \ + ((_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x000f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] ) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_XBGR_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] ) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_BGR_888(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] ) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_BGR_565(x) \ + ((((x) & 0x000f) << 12) /* B */ | \ + (((x) & 0x00f0) << 3) /* G */ | \ + (((x) & 0x0f00) >> 7) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_BGR_555(x) \ + ((((x) & 0x000f) << 11) /* B */ | \ + (((x) & 0x00f0) << 2) /* G */ | \ + (((x) & 0x0f00) >> 7) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_RGBX_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 24) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_XRGB_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* R */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_F32(x) \ + al_map_rgba(_al_rgb_scale_4[((x) >> 8) & 15],\ + _al_rgb_scale_4[((x) >> 4) & 15],\ + _al_rgb_scale_4[((x) >> 0) & 15],\ + _al_rgb_scale_4[((x) >> 12) & 15]) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888_LE(x) \ + ((_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x000f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 24) /* R */) +#else +#define ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888_LE(x) \ + ((_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x000f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] ) /* R */) +#endif +#define ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_4444(x) \ + ((((x) & 0xf000) >> 12) /* A */ | \ + (((x) & 0x0fff) << 4) /* BGR */) +#define ALLEGRO_CONVERT_ARGB_4444_TO_SINGLE_CHANNEL_8(x) \ + (_al_rgb_scale_4[(((x) >> 8) & 0xf)]) +#define ALLEGRO_CONVERT_RGB_888_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + ((x) & 0xffffff) /* BGR */) +#define ALLEGRO_CONVERT_RGB_888_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + (((x) & 0xffffff) << 8) /* BGR */) +#define ALLEGRO_CONVERT_RGB_888_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0x0000f0) >> 4) /* B */ | \ + (((x) & 0x00f000) >> 8) /* G */ | \ + (((x) & 0xf00000) >> 12) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_RGB_565(x) \ + ((((x) & 0x0000f8) >> 3) /* B */ | \ + (((x) & 0x00fc00) >> 5) /* G */ | \ + (((x) & 0xf80000) >> 8) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_RGB_555(x) \ + ((((x) & 0x0000f8) >> 3) /* B */ | \ + (((x) & 0x00f800) >> 6) /* G */ | \ + (((x) & 0xf80000) >> 9) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0x0000f8) >> 2) /* B */ | \ + (((x) & 0x00f800) >> 5) /* G */ | \ + (((x) & 0xf80000) >> 8) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + (((x) & 0x0000f8) >> 3) /* B */ | \ + (((x) & 0x00f800) >> 6) /* G */ | \ + (((x) & 0xf80000) >> 9) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0x0000ff) << 16) /* B */ | \ + ((x) & 0x00ff00) /* G */ | \ + (((x) & 0xff0000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_XBGR_8888(x) \ + ((((x) & 0x0000ff) << 16) /* B */ | \ + ((x) & 0x00ff00) /* G */ | \ + (((x) & 0xff0000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_BGR_888(x) \ + ((((x) & 0x0000ff) << 16) /* B */ | \ + ((x) & 0x00ff00) /* G */ | \ + (((x) & 0xff0000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_BGR_565(x) \ + ((((x) & 0x0000f8) << 8) /* B */ | \ + (((x) & 0x00fc00) >> 5) /* G */ | \ + (((x) & 0xf80000) >> 19) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_BGR_555(x) \ + ((((x) & 0x0000f8) << 7) /* B */ | \ + (((x) & 0x00f800) >> 6) /* G */ | \ + (((x) & 0xf80000) >> 19) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_RGBX_8888(x) \ + ((((x) & 0xffffff) << 8) /* BGR */) +#define ALLEGRO_CONVERT_RGB_888_TO_XRGB_8888(x) \ + (((x) & 0xffffff) /* BGR */) +#define ALLEGRO_CONVERT_RGB_888_TO_ABGR_F32(x) \ + al_map_rgb(((x) >> 16) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 0) & 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + (((x) & 0xffffff) << 8) /* BGR */) +#else +#define ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0x0000ff) << 16) /* B */ | \ + ((x) & 0x00ff00) /* G */ | \ + (((x) & 0xff0000) >> 16) /* R */) +#endif +#define ALLEGRO_CONVERT_RGB_888_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + ((x) & 0x0000f0) /* B */ | \ + (((x) & 0x00f000) >> 4) /* G */ | \ + (((x) & 0xf00000) >> 8) /* R */) +#define ALLEGRO_CONVERT_RGB_888_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 16) & 0xff) +#define ALLEGRO_CONVERT_RGB_565_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0x001e) >> 1) /* B */ | \ + (((x) & 0x0780) >> 3) /* G */ | \ + (((x) & 0xf000) >> 4) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_RGB_888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_RGB_555(x) \ + (((x) & 0x001f) /* B */ | \ + (((x) & 0xffc0) >> 1) /* GR */) +#define ALLEGRO_CONVERT_RGB_565_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0x001f) << 1) /* B */ | \ + ((x) & 0xffc0) /* GR */) +#define ALLEGRO_CONVERT_RGB_565_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + ((x) & 0x001f) /* B */ | \ + (((x) & 0xffc0) >> 1) /* GR */) +#define ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_XBGR_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_BGR_888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_BGR_565(x) \ + ((((x) & 0x001f) << 11) /* B */ | \ + ((x) & 0x07e0) /* G */ | \ + (((x) & 0xf800) >> 11) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_BGR_555(x) \ + ((((x) & 0x001f) << 10) /* B */ | \ + (((x) & 0x07c0) >> 1) /* G */ | \ + (((x) & 0xf800) >> 11) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_RGBX_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_XRGB_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_ABGR_F32(x) \ + al_map_rgb(_al_rgb_scale_5[((x) >> 11) & 31],\ + _al_rgb_scale_6[((x) >> 5) & 63],\ + _al_rgb_scale_5[((x) >> 0) & 31]) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) +#else +#define ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) +#endif +#define ALLEGRO_CONVERT_RGB_565_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + (((x) & 0x001e) << 3) /* B */ | \ + (((x) & 0x0780) << 1) /* G */ | \ + ((x) & 0xf000) /* R */) +#define ALLEGRO_CONVERT_RGB_565_TO_SINGLE_CHANNEL_8(x) \ + (_al_rgb_scale_5[(((x) >> 11) & 0x1f)]) +#define ALLEGRO_CONVERT_RGB_555_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0x01e) >> 1) /* B */ | \ + (((x) & 0x3c0) >> 2) /* G */ | \ + (((x) & 0x7800) >> 3) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_RGB_888(x) \ + ((_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_RGB_565(x) \ + (((x) & 0x01f) /* B */ | \ + (((x) & 0x7fe0) << 1) /* GR */) +#define ALLEGRO_CONVERT_RGB_555_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0x7fff) << 1) /* BGR */) +#define ALLEGRO_CONVERT_RGB_555_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + ((x) & 0x7fff) /* BGR */) +#define ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_XBGR_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_BGR_888(x) \ + ((_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_BGR_565(x) \ + ((((x) & 0x01f) << 11) /* B */ | \ + (((x) & 0x3e0) << 1) /* G */ | \ + (((x) & 0x7c00) >> 10) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_BGR_555(x) \ + ((((x) & 0x01f) << 10) /* B */ | \ + ((x) & 0x3e0) /* G */ | \ + (((x) & 0x7c00) >> 10) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_RGBX_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x01f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_XRGB_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_ABGR_F32(x) \ + al_map_rgb(_al_rgb_scale_5[((x) >> 10) & 31],\ + _al_rgb_scale_5[((x) >> 5) & 31],\ + _al_rgb_scale_5[((x) >> 0) & 31]) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) +#else +#define ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) +#endif +#define ALLEGRO_CONVERT_RGB_555_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + (((x) & 0x01e) << 3) /* B */ | \ + (((x) & 0x3c0) << 2) /* G */ | \ + (((x) & 0x7800) << 1) /* R */) +#define ALLEGRO_CONVERT_RGB_555_TO_SINGLE_CHANNEL_8(x) \ + (_al_rgb_scale_5[(((x) >> 10) & 0x1f)]) +#define ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_8888(x) \ + ((_al_rgb_scale_1[((x) & 0x0001) >> 0] << 24) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x003e) >> 1] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_RGBA_8888(x) \ + ((_al_rgb_scale_1[((x) & 0x0001) >> 0] ) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x003e) >> 1] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_4444(x) \ + ((((x) & 0x0001) << 15) /* A */ | \ + (((x) & 0x003c) >> 2) /* B */ | \ + (((x) & 0x0780) >> 3) /* G */ | \ + (((x) & 0xf000) >> 4) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_RGB_888(x) \ + ((_al_rgb_scale_5[((x) & 0x003e) >> 1] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_RGB_565(x) \ + ((((x) & 0x003e) >> 1) /* B */ | \ + ((x) & 0xffc0) /* GR */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_RGB_555(x) \ + ((((x) & 0xfffe) >> 1) /* BGR */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_1555(x) \ + ((((x) & 0x0001) << 15) /* A */ | \ + (((x) & 0xfffe) >> 1) /* BGR */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888(x) \ + ((_al_rgb_scale_1[((x) & 0x0001) >> 0] << 24) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x003e) >> 1] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_XBGR_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x003e) >> 1] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_BGR_888(x) \ + ((_al_rgb_scale_5[((x) & 0x003e) >> 1] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_BGR_565(x) \ + ((((x) & 0x003e) << 10) /* B */ | \ + ((x) & 0x07c0) /* G */ | \ + (((x) & 0xf800) >> 11) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_BGR_555(x) \ + ((((x) & 0x003e) << 9) /* B */ | \ + (((x) & 0x07c0) >> 1) /* G */ | \ + (((x) & 0xf800) >> 11) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_RGBX_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x003e) >> 1] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_XRGB_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x003e) >> 1] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_F32(x) \ + al_map_rgba(_al_rgb_scale_5[((x) >> 11) & 31],\ + _al_rgb_scale_5[((x) >> 6) & 31],\ + _al_rgb_scale_5[((x) >> 1) & 31],\ + _al_rgb_scale_1[((x) >> 0) & 1]) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888_LE(x) \ + ((_al_rgb_scale_1[((x) & 0x0001) >> 0] ) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x003e) >> 1] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 24) /* R */) +#else +#define ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888_LE(x) \ + ((_al_rgb_scale_1[((x) & 0x0001) >> 0] << 24) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x003e) >> 1] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x07c0) >> 6] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* R */) +#endif +#define ALLEGRO_CONVERT_RGBA_5551_TO_RGBA_4444(x) \ + ((((x) & 0x0001) << 3) /* A */ | \ + (((x) & 0x003c) << 2) /* B */ | \ + (((x) & 0x0780) << 1) /* G */ | \ + ((x) & 0xf000) /* R */) +#define ALLEGRO_CONVERT_RGBA_5551_TO_SINGLE_CHANNEL_8(x) \ + (_al_rgb_scale_5[(((x) >> 11) & 0x1f)]) +#define ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_8888(x) \ + ((_al_rgb_scale_1[((x) & 0x8000) >> 15] << 24) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_8888(x) \ + ((_al_rgb_scale_1[((x) & 0x8000) >> 15] ) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_4444(x) \ + (((x) & 0x8000) /* A */ | \ + (((x) & 0x001e) >> 1) /* B */ | \ + (((x) & 0x03c0) >> 2) /* G */ | \ + (((x) & 0x7800) >> 3) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_RGB_888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_RGB_565(x) \ + (((x) & 0x001f) /* B */ | \ + (((x) & 0x7fe0) << 1) /* GR */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_RGB_555(x) \ + (((x) & 0x7fff) /* BGR */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_5551(x) \ + ((((x) & 0x8000) >> 15) /* A */ | \ + (((x) & 0x7fff) << 1) /* BGR */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888(x) \ + ((_al_rgb_scale_1[((x) & 0x8000) >> 15] << 24) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_XBGR_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_BGR_888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_BGR_565(x) \ + ((((x) & 0x001f) << 11) /* B */ | \ + (((x) & 0x03e0) << 1) /* G */ | \ + (((x) & 0x7c00) >> 10) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_BGR_555(x) \ + ((((x) & 0x001f) << 10) /* B */ | \ + ((x) & 0x03e0) /* G */ | \ + (((x) & 0x7c00) >> 10) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_RGBX_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_XRGB_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_F32(x) \ + al_map_rgba(_al_rgb_scale_5[((x) >> 10) & 31],\ + _al_rgb_scale_5[((x) >> 5) & 31],\ + _al_rgb_scale_5[((x) >> 0) & 31],\ + _al_rgb_scale_1[((x) >> 15) & 1]) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888_LE(x) \ + ((_al_rgb_scale_1[((x) & 0x8000) >> 15] ) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 24) /* R */) +#else +#define ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888_LE(x) \ + ((_al_rgb_scale_1[((x) & 0x8000) >> 15] << 24) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x03e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* R */) +#endif +#define ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_4444(x) \ + ((((x) & 0x8000) >> 12) /* A */ | \ + (((x) & 0x001e) << 3) /* B */ | \ + (((x) & 0x03c0) << 2) /* G */ | \ + (((x) & 0x7800) << 1) /* R */) +#define ALLEGRO_CONVERT_ARGB_1555_TO_SINGLE_CHANNEL_8(x) \ + (_al_rgb_scale_5[(((x) >> 10) & 0x1f)]) +#define ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_8888(x) \ + ((((x) & 0x00ff0000) >> 16) /* B */ | \ + (((x) & 0x000000ff) << 16) /* R */ | \ + ((x) & 0xff00ff00) /* AG */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_8888(x) \ + ((((x) & 0xff000000) >> 24) /* A */ | \ + (((x) & 0x00ff0000) >> 8) /* B */ | \ + (((x) & 0x0000ff00) << 8) /* G */ | \ + (((x) & 0x000000ff) << 24) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_4444(x) \ + ((((x) & 0xf0000000) >> 16) /* A */ | \ + (((x) & 0x00f00000) >> 20) /* B */ | \ + (((x) & 0x0000f000) >> 8) /* G */ | \ + (((x) & 0x000000f0) << 4) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_RGB_888(x) \ + ((((x) & 0x00ff0000) >> 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x000000ff) << 16) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_RGB_565(x) \ + ((((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x000000f8) << 8) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_RGB_555(x) \ + ((((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) << 7) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_5551(x) \ + ((((x) & 0x80000000) >> 31) /* A */ | \ + (((x) & 0x00f80000) >> 18) /* B */ | \ + (((x) & 0x0000f800) >> 5) /* G */ | \ + (((x) & 0x000000f8) << 8) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_1555(x) \ + ((((x) & 0x80000000) >> 16) /* A */ | \ + (((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) << 7) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_XBGR_8888(x) \ + (((x) & 0x00ffffff) /* BGR */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_BGR_888(x) \ + (((x) & 0x00ffffff) /* BGR */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_BGR_565(x) \ + ((((x) & 0x00f80000) >> 8) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x000000f8) >> 3) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_BGR_555(x) \ + ((((x) & 0x00f80000) >> 9) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) >> 3) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_RGBX_8888(x) \ + ((((x) & 0x00ff0000) >> 8) /* B */ | \ + (((x) & 0x0000ff00) << 8) /* G */ | \ + (((x) & 0x000000ff) << 24) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_XRGB_8888(x) \ + ((((x) & 0x00ff0000) >> 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x000000ff) << 16) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_F32(x) \ + al_map_rgba(((x) >> 0) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 16) & 255,\ + ((x) >> 24) & 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_8888_LE(x) \ + ((((x) & 0xff000000) >> 24) /* A */ | \ + (((x) & 0x00ff0000) >> 8) /* B */ | \ + (((x) & 0x0000ff00) << 8) /* G */ | \ + (((x) & 0x000000ff) << 24) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_8888_LE(x) \ + (((x) & 0xffffffff) /* ABGR */) +#endif +#define ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_4444(x) \ + ((((x) & 0xf0000000) >> 28) /* A */ | \ + (((x) & 0x00f00000) >> 16) /* B */ | \ + (((x) & 0x0000f000) >> 4) /* G */ | \ + (((x) & 0x000000f0) << 8) /* R */) +#define ALLEGRO_CONVERT_ABGR_8888_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 0) & 0xff) +#define ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0x00ff0000) >> 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x000000ff) << 16) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + (((x) & 0x00ff0000) >> 8) /* B */ | \ + (((x) & 0x0000ff00) << 8) /* G */ | \ + (((x) & 0x000000ff) << 24) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0x00f00000) >> 20) /* B */ | \ + (((x) & 0x0000f000) >> 8) /* G */ | \ + (((x) & 0x000000f0) << 4) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_RGB_888(x) \ + ((((x) & 0x00ff0000) >> 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x000000ff) << 16) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_RGB_565(x) \ + ((((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x000000f8) << 8) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_RGB_555(x) \ + ((((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) << 7) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0x00f80000) >> 18) /* B */ | \ + (((x) & 0x0000f800) >> 5) /* G */ | \ + (((x) & 0x000000f8) << 8) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + (((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) << 7) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + ((x) & 0x00ffffff) /* BGR */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_BGR_888(x) \ + (((x) & 0x00ffffff) /* BGR */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_BGR_565(x) \ + ((((x) & 0x00f80000) >> 8) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x000000f8) >> 3) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_BGR_555(x) \ + ((((x) & 0x00f80000) >> 9) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) >> 3) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_RGBX_8888(x) \ + ((((x) & 0x00ff0000) >> 8) /* B */ | \ + (((x) & 0x0000ff00) << 8) /* G */ | \ + (((x) & 0x000000ff) << 24) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_XRGB_8888(x) \ + ((((x) & 0x00ff0000) >> 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x000000ff) << 16) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_F32(x) \ + al_map_rgb(((x) >> 0) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 16) & 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + (((x) & 0x00ff0000) >> 8) /* B */ | \ + (((x) & 0x0000ff00) << 8) /* G */ | \ + (((x) & 0x000000ff) << 24) /* R */) +#else +#define ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + ((x) & 0x00ffffff) /* BGR */) +#endif +#define ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + (((x) & 0x00f00000) >> 16) /* B */ | \ + (((x) & 0x0000f000) >> 4) /* G */ | \ + (((x) & 0x000000f0) << 8) /* R */) +#define ALLEGRO_CONVERT_XBGR_8888_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 0) & 0xff) +#define ALLEGRO_CONVERT_BGR_888_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0xff0000) >> 16) /* B */ | \ + ((x) & 0x00ff00) /* G */ | \ + (((x) & 0x0000ff) << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + (((x) & 0xff0000) >> 8) /* B */ | \ + (((x) & 0x00ff00) << 8) /* G */ | \ + (((x) & 0x0000ff) << 24) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0xf00000) >> 20) /* B */ | \ + (((x) & 0x00f000) >> 8) /* G */ | \ + (((x) & 0x0000f0) << 4) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_RGB_888(x) \ + ((((x) & 0xff0000) >> 16) /* B */ | \ + ((x) & 0x00ff00) /* G */ | \ + (((x) & 0x0000ff) << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_RGB_565(x) \ + ((((x) & 0xf80000) >> 19) /* B */ | \ + (((x) & 0x00fc00) >> 5) /* G */ | \ + (((x) & 0x0000f8) << 8) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_RGB_555(x) \ + ((((x) & 0xf80000) >> 19) /* B */ | \ + (((x) & 0x00f800) >> 6) /* G */ | \ + (((x) & 0x0000f8) << 7) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0xf80000) >> 18) /* B */ | \ + (((x) & 0x00f800) >> 5) /* G */ | \ + (((x) & 0x0000f8) << 8) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + (((x) & 0xf80000) >> 19) /* B */ | \ + (((x) & 0x00f800) >> 6) /* G */ | \ + (((x) & 0x0000f8) << 7) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + ((x) & 0xffffff) /* BGR */) +#define ALLEGRO_CONVERT_BGR_888_TO_XBGR_8888(x) \ + (((x) & 0xffffff) /* BGR */) +#define ALLEGRO_CONVERT_BGR_888_TO_BGR_565(x) \ + ((((x) & 0xf80000) >> 8) /* B */ | \ + (((x) & 0x00fc00) >> 5) /* G */ | \ + (((x) & 0x0000f8) >> 3) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_BGR_555(x) \ + ((((x) & 0xf80000) >> 9) /* B */ | \ + (((x) & 0x00f800) >> 6) /* G */ | \ + (((x) & 0x0000f8) >> 3) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_RGBX_8888(x) \ + ((((x) & 0xff0000) >> 8) /* B */ | \ + (((x) & 0x00ff00) << 8) /* G */ | \ + (((x) & 0x0000ff) << 24) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_XRGB_8888(x) \ + ((((x) & 0xff0000) >> 16) /* B */ | \ + ((x) & 0x00ff00) /* G */ | \ + (((x) & 0x0000ff) << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_ABGR_F32(x) \ + al_map_rgb(((x) >> 0) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 16) & 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + (((x) & 0xff0000) >> 8) /* B */ | \ + (((x) & 0x00ff00) << 8) /* G */ | \ + (((x) & 0x0000ff) << 24) /* R */) +#else +#define ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + ((x) & 0xffffff) /* BGR */) +#endif +#define ALLEGRO_CONVERT_BGR_888_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + (((x) & 0xf00000) >> 16) /* B */ | \ + (((x) & 0x00f000) >> 4) /* G */ | \ + (((x) & 0x0000f0) << 8) /* R */) +#define ALLEGRO_CONVERT_BGR_888_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 0) & 0xff) +#define ALLEGRO_CONVERT_BGR_565_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 8) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 24) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0xf000) >> 12) /* B */ | \ + (((x) & 0x0780) >> 3) /* G */ | \ + (((x) & 0x001e) << 7) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_RGB_888(x) \ + ((_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_RGB_565(x) \ + ((((x) & 0xf800) >> 11) /* B */ | \ + ((x) & 0x07e0) /* G */ | \ + (((x) & 0x001f) << 11) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_RGB_555(x) \ + ((((x) & 0xf800) >> 11) /* B */ | \ + (((x) & 0x07c0) >> 1) /* G */ | \ + (((x) & 0x001f) << 10) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0xf800) >> 10) /* B */ | \ + ((x) & 0x07c0) /* G */ | \ + (((x) & 0x001f) << 11) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + (((x) & 0xf800) >> 11) /* B */ | \ + (((x) & 0x07c0) >> 1) /* G */ | \ + (((x) & 0x001f) << 10) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_XBGR_8888(x) \ + ((_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_BGR_888(x) \ + ((_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_BGR_555(x) \ + (((x) & 0x001f) /* R */ | \ + (((x) & 0xffc0) >> 1) /* BG */) +#define ALLEGRO_CONVERT_BGR_565_TO_RGBX_8888(x) \ + ((_al_rgb_scale_5[((x) & 0xf800) >> 11] << 8) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 24) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_XRGB_8888(x) \ + ((_al_rgb_scale_5[((x) & 0xf800) >> 11] ) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_ABGR_F32(x) \ + al_map_rgb(_al_rgb_scale_5[((x) >> 0) & 31],\ + _al_rgb_scale_6[((x) >> 5) & 63],\ + _al_rgb_scale_5[((x) >> 11) & 31]) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 8) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] << 24) /* R */) +#else +#define ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0xf800) >> 11] << 16) /* B */ | \ + (_al_rgb_scale_6[((x) & 0x07e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x001f) >> 0] ) /* R */) +#endif +#define ALLEGRO_CONVERT_BGR_565_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + (((x) & 0xf000) >> 8) /* B */ | \ + (((x) & 0x0780) << 1) /* G */ | \ + (((x) & 0x001e) << 11) /* R */) +#define ALLEGRO_CONVERT_BGR_565_TO_SINGLE_CHANNEL_8(x) \ + (_al_rgb_scale_5[(((x) >> 0) & 0x1f)]) +#define ALLEGRO_CONVERT_BGR_555_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 24) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0x7800) >> 11) /* B */ | \ + (((x) & 0x3c0) >> 2) /* G */ | \ + (((x) & 0x01e) << 7) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_RGB_888(x) \ + ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_RGB_565(x) \ + ((((x) & 0x7c00) >> 10) /* B */ | \ + (((x) & 0x3e0) << 1) /* G */ | \ + (((x) & 0x01f) << 11) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_RGB_555(x) \ + ((((x) & 0x7c00) >> 10) /* B */ | \ + ((x) & 0x3e0) /* G */ | \ + (((x) & 0x01f) << 10) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0x7c00) >> 9) /* B */ | \ + (((x) & 0x3e0) << 1) /* G */ | \ + (((x) & 0x01f) << 11) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + (((x) & 0x7c00) >> 10) /* B */ | \ + ((x) & 0x3e0) /* G */ | \ + (((x) & 0x01f) << 10) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_XBGR_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_BGR_888(x) \ + ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_BGR_565(x) \ + (((x) & 0x01f) /* R */ | \ + (((x) & 0x7fe0) << 1) /* BG */) +#define ALLEGRO_CONVERT_BGR_555_TO_RGBX_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 24) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_XRGB_8888(x) \ + ((_al_rgb_scale_5[((x) & 0x7c00) >> 10] ) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 16) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_ABGR_F32(x) \ + al_map_rgb(_al_rgb_scale_5[((x) >> 0) & 31],\ + _al_rgb_scale_5[((x) >> 5) & 31],\ + _al_rgb_scale_5[((x) >> 10) & 31]) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 8) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 16) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] << 24) /* R */) +#else +#define ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + (_al_rgb_scale_5[((x) & 0x7c00) >> 10] << 16) /* B */ | \ + (_al_rgb_scale_5[((x) & 0x3e0) >> 5] << 8) /* G */ | \ + (_al_rgb_scale_5[((x) & 0x01f) >> 0] ) /* R */) +#endif +#define ALLEGRO_CONVERT_BGR_555_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + (((x) & 0x7800) >> 7) /* B */ | \ + (((x) & 0x3c0) << 2) /* G */ | \ + (((x) & 0x01e) << 11) /* R */) +#define ALLEGRO_CONVERT_BGR_555_TO_SINGLE_CHANNEL_8(x) \ + (_al_rgb_scale_5[(((x) >> 0) & 0x1f)]) +#define ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0xffffff00) >> 8) /* BGR */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + ((x) & 0xffffff00) /* BGR */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0x0000f000) >> 12) /* B */ | \ + (((x) & 0x00f00000) >> 16) /* G */ | \ + (((x) & 0xf0000000) >> 20) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_RGB_888(x) \ + ((((x) & 0xffffff00) >> 8) /* BGR */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_RGB_565(x) \ + ((((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00fc0000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_RGB_555(x) \ + ((((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 17) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0x0000f800) >> 10) /* B */ | \ + (((x) & 0x00f80000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + (((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 17) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_XBGR_8888(x) \ + ((((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_BGR_888(x) \ + ((((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_BGR_565(x) \ + (((x) & 0x0000f800) /* B */ | \ + (((x) & 0x00fc0000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 27) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_BGR_555(x) \ + ((((x) & 0x0000f800) >> 1) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 27) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_XRGB_8888(x) \ + ((((x) & 0xffffff00) >> 8) /* BGR */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_F32(x) \ + al_map_rgb(((x) >> 24) & 255,\ + ((x) >> 16) & 255,\ + ((x) >> 8) & 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + ((x) & 0xffffff00) /* BGR */) +#else +#define ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#endif +#define ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + (((x) & 0x0000f000) >> 8) /* B */ | \ + (((x) & 0x00f00000) >> 12) /* G */ | \ + (((x) & 0xf0000000) >> 16) /* R */) +#define ALLEGRO_CONVERT_RGBX_8888_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 24) & 0xff) +#define ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_8888(x) \ + ((0xff000000) /* A */ | \ + ((x) & 0x00ffffff) /* BGR */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_8888(x) \ + ((0x000000ff) /* A */ | \ + (((x) & 0x00ffffff) << 8) /* BGR */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_4444(x) \ + ((0xf000) /* A */ | \ + (((x) & 0x000000f0) >> 4) /* B */ | \ + (((x) & 0x0000f000) >> 8) /* G */ | \ + (((x) & 0x00f00000) >> 12) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_RGB_888(x) \ + (((x) & 0x00ffffff) /* BGR */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_RGB_565(x) \ + ((((x) & 0x000000f8) >> 3) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x00f80000) >> 8) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_RGB_555(x) \ + ((((x) & 0x000000f8) >> 3) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x00f80000) >> 9) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_5551(x) \ + ((0x0001) /* A */ | \ + (((x) & 0x000000f8) >> 2) /* B */ | \ + (((x) & 0x0000f800) >> 5) /* G */ | \ + (((x) & 0x00f80000) >> 8) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_1555(x) \ + ((0x8000) /* A */ | \ + (((x) & 0x000000f8) >> 3) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x00f80000) >> 9) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0x000000ff) << 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x00ff0000) >> 16) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_XBGR_8888(x) \ + ((((x) & 0x000000ff) << 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x00ff0000) >> 16) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_BGR_888(x) \ + ((((x) & 0x000000ff) << 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x00ff0000) >> 16) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_BGR_565(x) \ + ((((x) & 0x000000f8) << 8) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x00f80000) >> 19) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_BGR_555(x) \ + ((((x) & 0x000000f8) << 7) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x00f80000) >> 19) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_RGBX_8888(x) \ + ((((x) & 0x00ffffff) << 8) /* BGR */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_F32(x) \ + al_map_rgb(((x) >> 16) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 0) & 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888_LE(x) \ + ((0x000000ff) /* A */ | \ + (((x) & 0x00ffffff) << 8) /* BGR */) +#else +#define ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888_LE(x) \ + ((0xff000000) /* A */ | \ + (((x) & 0x000000ff) << 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x00ff0000) >> 16) /* R */) +#endif +#define ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_4444(x) \ + ((0x000f) /* A */ | \ + ((x) & 0x000000f0) /* B */ | \ + (((x) & 0x0000f000) >> 4) /* G */ | \ + (((x) & 0x00f00000) >> 8) /* R */) +#define ALLEGRO_CONVERT_XRGB_8888_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 16) & 0xff) +#define ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_8888(x) \ + (((uint32_t)((x).a * 255) << 24) | \ + ((uint32_t)((x).b * 255) << 0) | \ + ((uint32_t)((x).g * 255) << 8) | \ + ((uint32_t)((x).r * 255) << 16)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_8888(x) \ + (((uint32_t)((x).a * 255) << 0) | \ + ((uint32_t)((x).b * 255) << 8) | \ + ((uint32_t)((x).g * 255) << 16) | \ + ((uint32_t)((x).r * 255) << 24)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_4444(x) \ + (((uint32_t)((x).a * 15) << 12) | \ + ((uint32_t)((x).b * 15) << 0) | \ + ((uint32_t)((x).g * 15) << 4) | \ + ((uint32_t)((x).r * 15) << 8)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_RGB_888(x) \ + (((uint32_t)((x).b * 255) << 0) | \ + ((uint32_t)((x).g * 255) << 8) | \ + ((uint32_t)((x).r * 255) << 16)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_RGB_565(x) \ + (((uint32_t)((x).b * 31) << 0) | \ + ((uint32_t)((x).g * 63) << 5) | \ + ((uint32_t)((x).r * 31) << 11)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_RGB_555(x) \ + (((uint32_t)((x).b * 31) << 0) | \ + ((uint32_t)((x).g * 31) << 5) | \ + ((uint32_t)((x).r * 31) << 10)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_5551(x) \ + (((uint32_t)((x).a * 1) << 0) | \ + ((uint32_t)((x).b * 31) << 1) | \ + ((uint32_t)((x).g * 31) << 6) | \ + ((uint32_t)((x).r * 31) << 11)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_1555(x) \ + (((uint32_t)((x).a * 1) << 15) | \ + ((uint32_t)((x).b * 31) << 0) | \ + ((uint32_t)((x).g * 31) << 5) | \ + ((uint32_t)((x).r * 31) << 10)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888(x) \ + (((uint32_t)((x).a * 255) << 24) | \ + ((uint32_t)((x).b * 255) << 16) | \ + ((uint32_t)((x).g * 255) << 8) | \ + ((uint32_t)((x).r * 255) << 0)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_XBGR_8888(x) \ + (((uint32_t)((x).b * 255) << 16) | \ + ((uint32_t)((x).g * 255) << 8) | \ + ((uint32_t)((x).r * 255) << 0)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_BGR_888(x) \ + (((uint32_t)((x).b * 255) << 16) | \ + ((uint32_t)((x).g * 255) << 8) | \ + ((uint32_t)((x).r * 255) << 0)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_BGR_565(x) \ + (((uint32_t)((x).b * 31) << 11) | \ + ((uint32_t)((x).g * 63) << 5) | \ + ((uint32_t)((x).r * 31) << 0)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_BGR_555(x) \ + (((uint32_t)((x).b * 31) << 10) | \ + ((uint32_t)((x).g * 31) << 5) | \ + ((uint32_t)((x).r * 31) << 0)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_RGBX_8888(x) \ + (((uint32_t)((x).b * 255) << 8) | \ + ((uint32_t)((x).g * 255) << 16) | \ + ((uint32_t)((x).r * 255) << 24)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_XRGB_8888(x) \ + (((uint32_t)((x).b * 255) << 0) | \ + ((uint32_t)((x).g * 255) << 8) | \ + ((uint32_t)((x).r * 255) << 16)) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888_LE(x) \ + (((uint32_t)((x).a * 255) << 0) | \ + ((uint32_t)((x).b * 255) << 8) | \ + ((uint32_t)((x).g * 255) << 16) | \ + ((uint32_t)((x).r * 255) << 24)) +#else +#define ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888_LE(x) \ + (((uint32_t)((x).a * 255) << 24) | \ + ((uint32_t)((x).b * 255) << 16) | \ + ((uint32_t)((x).g * 255) << 8) | \ + ((uint32_t)((x).r * 255) << 0)) +#endif +#define ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_4444(x) \ + (((uint32_t)((x).a * 15) << 0) | \ + ((uint32_t)((x).b * 15) << 4) | \ + ((uint32_t)((x).g * 15) << 8) | \ + ((uint32_t)((x).r * 15) << 12)) +#define ALLEGRO_CONVERT_ABGR_F32_TO_SINGLE_CHANNEL_8(x) \ + (uint32_t)((x).r * 255) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_8888(x) \ + ((((x) & 0x000000ff) << 24) /* A */ | \ + (((x) & 0xffffff00) >> 8) /* BGR */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_8888(x) \ + ((((x) & 0x00ff0000) >> 16) /* B */ | \ + (((x) & 0x000000ff) << 16) /* R */ | \ + ((x) & 0xff00ff00) /* AG */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_8888(x) \ + (((x) & 0xffffffff) /* ABGR */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_8888(x) \ + ((((x) & 0xff000000) >> 24) /* A */ | \ + (((x) & 0x00ff0000) >> 8) /* B */ | \ + (((x) & 0x0000ff00) << 8) /* G */ | \ + (((x) & 0x000000ff) << 24) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_4444(x) \ + ((((x) & 0x000000f0) << 8) /* A */ | \ + (((x) & 0x0000f000) >> 12) /* B */ | \ + (((x) & 0x00f00000) >> 16) /* G */ | \ + (((x) & 0xf0000000) >> 20) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_4444(x) \ + ((((x) & 0xf0000000) >> 16) /* A */ | \ + (((x) & 0x00f00000) >> 20) /* B */ | \ + (((x) & 0x0000f000) >> 8) /* G */ | \ + (((x) & 0x000000f0) << 4) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_888(x) \ + ((((x) & 0xffffff00) >> 8) /* BGR */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_888(x) \ + ((((x) & 0x00ff0000) >> 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x000000ff) << 16) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_565(x) \ + ((((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00fc0000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 16) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_565(x) \ + ((((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x000000f8) << 8) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_555(x) \ + ((((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 17) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_555(x) \ + ((((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) << 7) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_5551(x) \ + ((((x) & 0x00000080) >> 7) /* A */ | \ + (((x) & 0x0000f800) >> 10) /* B */ | \ + (((x) & 0x00f80000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 16) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_5551(x) \ + ((((x) & 0x80000000) >> 31) /* A */ | \ + (((x) & 0x00f80000) >> 18) /* B */ | \ + (((x) & 0x0000f800) >> 5) /* G */ | \ + (((x) & 0x000000f8) << 8) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_1555(x) \ + ((((x) & 0x00000080) << 8) /* A */ | \ + (((x) & 0x0000f800) >> 11) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 17) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_1555(x) \ + ((((x) & 0x80000000) >> 16) /* A */ | \ + (((x) & 0x00f80000) >> 19) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) << 7) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_8888(x) \ + ((((x) & 0x000000ff) << 24) /* A */ | \ + (((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_8888(x) \ + (((x) & 0xffffffff) /* ABGR */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_XBGR_8888(x) \ + ((((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_XBGR_8888(x) \ + (((x) & 0x00ffffff) /* BGR */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_888(x) \ + ((((x) & 0x0000ff00) << 8) /* B */ | \ + (((x) & 0x00ff0000) >> 8) /* G */ | \ + (((x) & 0xff000000) >> 24) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_888(x) \ + (((x) & 0x00ffffff) /* BGR */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_565(x) \ + (((x) & 0x0000f800) /* B */ | \ + (((x) & 0x00fc0000) >> 13) /* G */ | \ + (((x) & 0xf8000000) >> 27) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_565(x) \ + ((((x) & 0x00f80000) >> 8) /* B */ | \ + (((x) & 0x0000fc00) >> 5) /* G */ | \ + (((x) & 0x000000f8) >> 3) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_555(x) \ + ((((x) & 0x0000f800) >> 1) /* B */ | \ + (((x) & 0x00f80000) >> 14) /* G */ | \ + (((x) & 0xf8000000) >> 27) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_555(x) \ + ((((x) & 0x00f80000) >> 9) /* B */ | \ + (((x) & 0x0000f800) >> 6) /* G */ | \ + (((x) & 0x000000f8) >> 3) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBX_8888(x) \ + (((x) & 0xffffff00) /* BGR */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBX_8888(x) \ + ((((x) & 0x00ff0000) >> 8) /* B */ | \ + (((x) & 0x0000ff00) << 8) /* G */ | \ + (((x) & 0x000000ff) << 24) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_XRGB_8888(x) \ + ((((x) & 0xffffff00) >> 8) /* BGR */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_XRGB_8888(x) \ + ((((x) & 0x00ff0000) >> 16) /* B */ | \ + ((x) & 0x0000ff00) /* G */ | \ + (((x) & 0x000000ff) << 16) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_F32(x) \ + al_map_rgba(((x) >> 24) & 255,\ + ((x) >> 16) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 0) & 255) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_F32(x) \ + al_map_rgba(((x) >> 0) & 255,\ + ((x) >> 8) & 255,\ + ((x) >> 16) & 255,\ + ((x) >> 24) & 255) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_4444(x) \ + ((((x) & 0x000000f0) >> 4) /* A */ | \ + (((x) & 0x0000f000) >> 8) /* B */ | \ + (((x) & 0x00f00000) >> 12) /* G */ | \ + (((x) & 0xf0000000) >> 16) /* R */) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_4444(x) \ + ((((x) & 0xf0000000) >> 28) /* A */ | \ + (((x) & 0x00f00000) >> 16) /* B */ | \ + (((x) & 0x0000f000) >> 4) /* G */ | \ + (((x) & 0x000000f0) << 8) /* R */) +#endif +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 24) & 0xff) +#else +#define ALLEGRO_CONVERT_ABGR_8888_LE_TO_SINGLE_CHANNEL_8(x) \ + (((x) >> 0) & 0xff) +#endif +#define ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 24) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] ) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_RGBA_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_4444(x) \ + ((((x) & 0x000f) << 12) /* A */ | \ + (((x) & 0xfff0) >> 4) /* BGR */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_RGB_888(x) \ + ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] ) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_RGB_565(x) \ + ((((x) & 0x00f0) >> 3) /* B */ | \ + (((x) & 0x0f00) >> 1) /* G */ | \ + ((x) & 0xf000) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_RGB_555(x) \ + ((((x) & 0x00f0) >> 3) /* B */ | \ + (((x) & 0x0f00) >> 2) /* G */ | \ + (((x) & 0xf000) >> 1) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_RGBA_5551(x) \ + ((((x) & 0x0008) >> 3) /* A */ | \ + (((x) & 0x00f0) >> 2) /* B */ | \ + (((x) & 0x0f00) >> 1) /* G */ | \ + ((x) & 0xf000) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_1555(x) \ + ((((x) & 0x0008) << 12) /* A */ | \ + (((x) & 0x00f0) >> 3) /* B */ | \ + (((x) & 0x0f00) >> 2) /* G */ | \ + (((x) & 0xf000) >> 1) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 24) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_XBGR_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_BGR_888(x) \ + ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_BGR_565(x) \ + ((((x) & 0x00f0) << 8) /* B */ | \ + (((x) & 0x0f00) >> 1) /* G */ | \ + (((x) & 0xf000) >> 11) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_BGR_555(x) \ + ((((x) & 0x00f0) << 7) /* B */ | \ + (((x) & 0x0f00) >> 2) /* G */ | \ + (((x) & 0xf000) >> 11) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_RGBX_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_XRGB_8888(x) \ + ((_al_rgb_scale_4[((x) & 0x00f0) >> 4] ) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 16) /* R */) +#define ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_F32(x) \ + al_map_rgba(_al_rgb_scale_4[((x) >> 12) & 15],\ + _al_rgb_scale_4[((x) >> 8) & 15],\ + _al_rgb_scale_4[((x) >> 4) & 15],\ + _al_rgb_scale_4[((x) >> 0) & 15]) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888_LE(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] ) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 8) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 16) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] << 24) /* R */) +#else +#define ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888_LE(x) \ + ((_al_rgb_scale_4[((x) & 0x000f) >> 0] << 24) /* A */ | \ + (_al_rgb_scale_4[((x) & 0x00f0) >> 4] << 16) /* B */ | \ + (_al_rgb_scale_4[((x) & 0x0f00) >> 8] << 8) /* G */ | \ + (_al_rgb_scale_4[((x) & 0xf000) >> 12] ) /* R */) +#endif +#define ALLEGRO_CONVERT_RGBA_4444_TO_SINGLE_CHANNEL_8(x) \ + (_al_rgb_scale_4[(((x) >> 12) & 0xf)]) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ARGB_8888(x) \ + (0xff000000 | \ + (((x) << 16) & 0xff0000)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGBA_8888(x) \ + (0xff | \ + (((x) << 24) & 0xff000000)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ARGB_4444(x) \ + (0xf000 | \ + (((x) << 4) & 0xf00)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGB_888(x) \ + ((((x) << 16) & 0xff0000)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGB_565(x) \ + ((((x) << 8) & 0xf800)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGB_555(x) \ + ((((x) << 7) & 0x7c00)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGBA_5551(x) \ + (0x1 | \ + (((x) << 8) & 0xf800)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ARGB_1555(x) \ + (0x8000 | \ + (((x) << 7) & 0x7c00)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ABGR_8888(x) \ + (0xff000000 | \ + ((x) & 0xff)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_XBGR_8888(x) \ + (((x) & 0xff)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_BGR_888(x) \ + (((x) & 0xff)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_BGR_565(x) \ + ((((x) >> 3) & 0x1f)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_BGR_555(x) \ + ((((x) >> 3) & 0x1f)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGBX_8888(x) \ + ((((x) << 24) & 0xff000000)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_XRGB_8888(x) \ + ((((x) << 16) & 0xff0000)) +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ABGR_F32(x) \ + al_map_rgb(x, 0, 0) +#ifdef ALLEGRO_BIG_ENDIAN +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ABGR_8888_LE(x) \ + (0xff | \ + (((x) << 24) & 0xff000000)) +#else +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ABGR_8888_LE(x) \ + (0xff000000 | \ + ((x) & 0xff)) +#endif +#define ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGBA_4444(x) \ + (0xf | \ + (((x) << 8) & 0xf000)) +#endif +// Warning: This file was created by make_converters.py - do not edit. diff --git a/allegro/include/allegro5/internal/aintern_debug.h b/allegro/include/allegro5/internal/aintern_debug.h new file mode 100644 index 00000000..b504fc8e --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_debug.h @@ -0,0 +1,17 @@ +#ifndef __al_included_allegro5_aintern_debug_h +#define __al_included_allegro5_aintern_debug_h + +#ifdef __cplusplus + extern "C" { +#endif + + +void _al_configure_logging(void); +void _al_shutdown_logging(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_direct3d.h b/allegro/include/allegro5/internal/aintern_direct3d.h new file mode 100644 index 00000000..acefc6bb --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_direct3d.h @@ -0,0 +1,114 @@ +#ifndef __al_included_allegro5_aintern_direct3d_h +#define __al_included_allegro5_aintern_direct3d_h + +#include "allegro5/platform/alplatf.h" +#include "allegro5/allegro_direct3d.h" +#include "allegro5/platform/aintwin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ALLEGRO_BITMAP_EXTRA_D3D +{ + /* Driver specifics. */ + + unsigned int texture_w; + unsigned int texture_h; + + LPDIRECT3DTEXTURE9 video_texture; + LPDIRECT3DTEXTURE9 system_texture; + int system_format; + + bool initialized; + bool is_backbuffer; + + D3DLOCKED_RECT locked_rect; + + struct ALLEGRO_DISPLAY_D3D *display; + + IDirect3DSurface9 *render_target; + + bool dirty; +} ALLEGRO_BITMAP_EXTRA_D3D; + +typedef struct ALLEGRO_DISPLAY_D3D +{ + ALLEGRO_DISPLAY_WIN win_display; /* This must be the first member. */ + bool es_inited; + + /* Driver specifics */ + LPDIRECT3DDEVICE9 device; + LPDIRECT3DSURFACE9 render_target; + + bool do_reset; + bool reset_done; + bool reset_success; + + ALLEGRO_BITMAP backbuffer_bmp; + ALLEGRO_BITMAP_EXTRA_D3D backbuffer_bmp_extra; + + /* Contains the target video bitmap for this display. */ + ALLEGRO_BITMAP* target_bitmap; + + bool device_lost; + bool suppress_lost_events; + + bool faux_fullscreen; + + bool supports_separate_alpha_blend; + + TCHAR *device_name; + + int format; + D3DFORMAT depth_stencil_format; + int samples; + bool single_buffer; + bool vsync; + + int blender_state_op; + int blender_state_src; + int blender_state_dst; + int blender_state_alpha_op; + int blender_state_alpha_src; + int blender_state_alpha_dst; + + RECT scissor_state; + +#ifdef ALLEGRO_CFG_SHADER_HLSL + LPD3DXEFFECT effect; +#endif +} ALLEGRO_DISPLAY_D3D; + + +AL_FUNC(void, _al_d3d_set_blender, (ALLEGRO_DISPLAY_D3D *disp)); + +void _al_d3d_destroy_bitmap(ALLEGRO_BITMAP *bitmap); +void _al_d3d_update_render_state(ALLEGRO_DISPLAY *display); + +#ifdef ALLEGRO_CFG_SHADER_HLSL + bool _al_hlsl_set_projview_matrix(LPD3DXEFFECT effect, + const ALLEGRO_TRANSFORM *t); +#endif + +#ifdef ALLEGRO_CFG_D3DX9 + typedef HRESULT (WINAPI *_ALLEGRO_D3DXLSFLSPROC)(LPDIRECT3DSURFACE9, const PALETTEENTRY*, + const RECT*, LPDIRECT3DSURFACE9, const PALETTEENTRY*, const RECT*, + DWORD, D3DCOLOR); + + typedef HRESULT (WINAPI *_ALLEGRO_D3DXCREATEEFFECTPROC)(LPDIRECT3DDEVICE9, LPCVOID, UINT, + CONST D3DXMACRO*, LPD3DXINCLUDE, DWORD, LPD3DXEFFECTPOOL, LPD3DXEFFECT*, + LPD3DXBUFFER*); + + bool _al_load_d3dx9_module(); + void _al_unload_d3dx9_module(); + + extern _ALLEGRO_D3DXLSFLSPROC _al_imp_D3DXLoadSurfaceFromSurface; + extern _ALLEGRO_D3DXCREATEEFFECTPROC _al_imp_D3DXCreateEffect; +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_display.h b/allegro/include/allegro5/internal/aintern_display.h new file mode 100644 index 00000000..3a07d9d1 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_display.h @@ -0,0 +1,197 @@ +#ifndef __al_included_allegro5_aintern_display_h +#define __al_included_allegro5_aintern_display_h + +#include "allegro5/allegro.h" +#include "allegro5/transformations.h" +#include "allegro5/display.h" +#include "allegro5/bitmap.h" +#include "allegro5/internal/aintern_events.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ALLEGRO_DISPLAY_INTERFACE ALLEGRO_DISPLAY_INTERFACE; + +struct ALLEGRO_DISPLAY_INTERFACE +{ + int id; + ALLEGRO_DISPLAY *(*create_display)(int w, int h); + void (*destroy_display)(ALLEGRO_DISPLAY *display); + bool (*set_current_display)(ALLEGRO_DISPLAY *d); + void (*unset_current_display)(ALLEGRO_DISPLAY *d); + void (*clear)(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color); + void (*draw_pixel)(ALLEGRO_DISPLAY *d, float x, float y, ALLEGRO_COLOR *color); + void (*flip_display)(ALLEGRO_DISPLAY *d); + void (*update_display_region)(ALLEGRO_DISPLAY *d, int x, int y, + int width, int height); + bool (*acknowledge_resize)(ALLEGRO_DISPLAY *d); + bool (*resize_display)(ALLEGRO_DISPLAY *d, int width, int height); + void (*quick_size)(ALLEGRO_DISPLAY *d); + int (*get_orientation)(ALLEGRO_DISPLAY *d); + + ALLEGRO_BITMAP *(*create_bitmap)(ALLEGRO_DISPLAY *d, + int w, int h, int format, int flags); + + void (*set_target_bitmap)(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); + ALLEGRO_BITMAP *(*get_backbuffer)(ALLEGRO_DISPLAY *d); + + bool (*is_compatible_bitmap)(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); + void (*switch_out)(ALLEGRO_DISPLAY *display); + void (*switch_in)(ALLEGRO_DISPLAY *display); + + void (*draw_memory_bitmap_region)(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, int flags); + + bool (*wait_for_vsync)(ALLEGRO_DISPLAY *display); + + bool (*set_mouse_cursor)(ALLEGRO_DISPLAY *display, + ALLEGRO_MOUSE_CURSOR *cursor); + bool (*set_system_mouse_cursor)(ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id); + bool (*show_mouse_cursor)(ALLEGRO_DISPLAY *display); + bool (*hide_mouse_cursor)(ALLEGRO_DISPLAY *display); + + void (*set_icons)(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *bitmap[]); + + void (*set_window_position)(ALLEGRO_DISPLAY *display, int x, int y); + void (*get_window_position)(ALLEGRO_DISPLAY *display, int *x, int *y); + bool (*set_window_constraints)(ALLEGRO_DISPLAY *display, int min_w, int min_h, int max_w, int max_h); + bool (*get_window_constraints)(ALLEGRO_DISPLAY *display, int *min_w, int *min_h, int *max_w, int *max_h); + bool (*set_display_flag)(ALLEGRO_DISPLAY *display, int flag, bool onoff); + void (*set_window_title)(ALLEGRO_DISPLAY *display, const char *title); + + void (*flush_vertex_cache)(ALLEGRO_DISPLAY *d); + void* (*prepare_vertex_cache)(ALLEGRO_DISPLAY *d, int num_new_vertices); + + void (*update_transformation)(ALLEGRO_DISPLAY* d, ALLEGRO_BITMAP *target); + + /* Unused */ + void (*shutdown)(void); + + void (*acknowledge_drawing_halt)(ALLEGRO_DISPLAY *d); + void (*acknowledge_drawing_resume)(ALLEGRO_DISPLAY *d); + + void (*set_display_option)(ALLEGRO_DISPLAY *display, int option, int val); + + void (*clear_depth_buffer)(ALLEGRO_DISPLAY *display, float x); + void (*update_render_state)(ALLEGRO_DISPLAY *display); + + char *(*get_clipboard_text)(ALLEGRO_DISPLAY *display); + bool (*set_clipboard_text)(ALLEGRO_DISPLAY *display, const char *text); + bool (*has_clipboard_text)(ALLEGRO_DISPLAY *display); + + /* Issue #725 */ + void (*apply_window_constraints)(ALLEGRO_DISPLAY *display, bool onoff); +}; + + +struct ALLEGRO_OGL_EXTRAS; + +typedef struct ALLEGRO_BLENDER +{ + int blend_op; + int blend_source; + int blend_dest; + int blend_alpha_op; + int blend_alpha_source; + int blend_alpha_dest; + ALLEGRO_COLOR blend_color; +} ALLEGRO_BLENDER; + +typedef struct _ALLEGRO_RENDER_STATE { + int write_mask; + int depth_test, depth_function; + int alpha_test, alpha_function, alpha_test_value; +} _ALLEGRO_RENDER_STATE; + + +/* These are settings Allegro itself doesn't really care about on its + * own, but which users may want to specify for a display anyway. + */ +ALLEGRO_STATIC_ASSERT(aintern_display, ALLEGRO_DISPLAY_OPTIONS_COUNT <= 64); +typedef struct +{ + int64_t required, suggested; /* Bitfields. */ + int settings[ALLEGRO_DISPLAY_OPTIONS_COUNT]; + + /* These are come in handy when creating a context. */ + void *info; + int index, score; +} ALLEGRO_EXTRA_DISPLAY_SETTINGS; + +struct ALLEGRO_DISPLAY +{ + /* Must be first, so the display can be used as event source. */ + ALLEGRO_EVENT_SOURCE es; + ALLEGRO_DISPLAY_INTERFACE *vt; + int refresh_rate; + int flags; + int w, h; + int min_w, min_h; + int max_w, max_h; + + int backbuffer_format; /* ALLEGRO_PIXELFORMAT */ + + ALLEGRO_EXTRA_DISPLAY_SETTINGS extra_settings; + struct ALLEGRO_OGL_EXTRAS *ogl_extras; + + /* A list of bitmaps created for this display, sub-bitmaps not included. */ + _AL_VECTOR bitmaps; + + int num_cache_vertices; + bool cache_enabled; + int vertex_cache_size; + void* vertex_cache; + uintptr_t cache_texture; + + ALLEGRO_BLENDER cur_blender; + + ALLEGRO_SHADER* default_shader; + + ALLEGRO_TRANSFORM projview_transform; + + _ALLEGRO_RENDER_STATE render_state; + + _AL_VECTOR display_invalidated_callbacks; + _AL_VECTOR display_validated_callbacks; + + /* Issue #725 */ + bool use_constraints; + + /* On Windows, menus take up the display's height so whenever doing a + * manual resize we need to add this number to the height for things + * to work correctly. See issue #860. */ + int extra_resize_height; +}; + +int _al_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref); +void _al_fill_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds); +void _al_set_color_components(int format, ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, int importance); +int _al_deduce_color_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds); +int _al_display_settings_sorter(const void *p0, const void *p1); + +int _al_get_suggested_display_option(ALLEGRO_DISPLAY *d, + int option, int default_value); + +/* This is called from the primitives addon and for shaders. */ +AL_FUNC(void, _al_add_display_invalidated_callback, (ALLEGRO_DISPLAY *display, + void (*display_invalidated)(ALLEGRO_DISPLAY*))); +AL_FUNC(void, _al_add_display_validated_callback, (ALLEGRO_DISPLAY *display, + void (*display_validated)(ALLEGRO_DISPLAY*))); +AL_FUNC(void, _al_remove_display_invalidated_callback, (ALLEGRO_DISPLAY *display, + void (*display_invalidated)(ALLEGRO_DISPLAY*))); +AL_FUNC(void, _al_remove_display_validated_callback, (ALLEGRO_DISPLAY *display, + void (*display_validated)(ALLEGRO_DISPLAY*))); + +/* Defined in tls.c */ +bool _al_set_current_display_only(ALLEGRO_DISPLAY *display); +void _al_set_new_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings); +ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_get_new_display_settings(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_driver.h b/allegro/include/allegro5/internal/aintern_driver.h new file mode 100644 index 00000000..72bd4ea5 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_driver.h @@ -0,0 +1,13 @@ +#ifndef __al_included_allegro5_internal_aintern_driver_h +#define __al_included_allegro5_internal_aintern_driver_h + + +typedef struct _AL_DRIVER_INFO /* info about a hardware driver */ +{ + int id; /* integer ID */ + void *driver; /* the driver structure */ + int autodetect; /* set to allow autodetection */ +} _AL_DRIVER_INFO; + + +#endif diff --git a/allegro/include/allegro5/internal/aintern_dtor.h b/allegro/include/allegro5/internal/aintern_dtor.h new file mode 100644 index 00000000..dfceb686 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_dtor.h @@ -0,0 +1,33 @@ +#ifndef __al_included_allegro5_aintern_dtor_h +#define __al_included_allegro5_aintern_dtor_h + +#include "allegro5/internal/aintern_list.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct _AL_DTOR_LIST _AL_DTOR_LIST; + + +AL_FUNC(_AL_DTOR_LIST *, _al_init_destructors, (void)); +AL_FUNC(void, _al_push_destructor_owner, (void)); +AL_FUNC(void, _al_pop_destructor_owner, (void)); +AL_FUNC(void, _al_run_destructors, (_AL_DTOR_LIST *dtors)); +AL_FUNC(void, _al_shutdown_destructors, (_AL_DTOR_LIST *dtors)); +AL_FUNC(_AL_LIST_ITEM*, _al_register_destructor, (_AL_DTOR_LIST *dtors, char const *name, + void *object, void (*func)(void*))); +AL_FUNC(void, _al_unregister_destructor, (_AL_DTOR_LIST *dtors, _AL_LIST_ITEM* dtor_item)); +AL_FUNC(void, _al_foreach_destructor, (_AL_DTOR_LIST *dtors, + void (*callback)(void *object, void (*func)(void *), void *udata), + void *userdata)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_events.h b/allegro/include/allegro5/internal/aintern_events.h new file mode 100644 index 00000000..f5555546 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_events.h @@ -0,0 +1,48 @@ +#ifndef __al_included_allegro5_aintern_events_h +#define __al_included_allegro5_aintern_events_h + +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/internal/aintern_vector.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct ALLEGRO_EVENT_SOURCE_REAL ALLEGRO_EVENT_SOURCE_REAL; + +struct ALLEGRO_EVENT_SOURCE_REAL +{ + _AL_MUTEX mutex; + _AL_VECTOR queues; + intptr_t data; +}; + +typedef struct ALLEGRO_USER_EVENT_DESCRIPTOR +{ + void (*dtor)(ALLEGRO_USER_EVENT *event); + int refcount; +} ALLEGRO_USER_EVENT_DESCRIPTOR; + + +void _al_init_events(void); + +void _al_event_source_init(ALLEGRO_EVENT_SOURCE*); +void _al_event_source_free(ALLEGRO_EVENT_SOURCE*); +void _al_event_source_lock(ALLEGRO_EVENT_SOURCE*); +void _al_event_source_unlock(ALLEGRO_EVENT_SOURCE*); +void _al_event_source_on_registration_to_queue(ALLEGRO_EVENT_SOURCE*, ALLEGRO_EVENT_QUEUE*); +void _al_event_source_on_unregistration_from_queue(ALLEGRO_EVENT_SOURCE*, ALLEGRO_EVENT_QUEUE*); +bool _al_event_source_needs_to_generate_event(ALLEGRO_EVENT_SOURCE*); +void _al_event_source_emit_event(ALLEGRO_EVENT_SOURCE *, ALLEGRO_EVENT*); + +void _al_event_queue_push_event(ALLEGRO_EVENT_QUEUE*, const ALLEGRO_EVENT*); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vi ts=8 sts=3 sw=3 et */ diff --git a/allegro/include/allegro5/internal/aintern_exitfunc.h b/allegro/include/allegro5/internal/aintern_exitfunc.h new file mode 100644 index 00000000..119b91df --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_exitfunc.h @@ -0,0 +1,19 @@ +#ifndef __al_included_allegro5_aintern_exitfunc_h +#define __al_included_allegro5_aintern_exitfunc_h + +#ifdef __cplusplus + extern "C" { +#endif + + +/* list of functions to call at program cleanup */ +AL_FUNC(void, _al_add_exit_func, (AL_METHOD(void, func, (void)), const char *desc)); +AL_FUNC(void, _al_remove_exit_func, (AL_METHOD(void, func, (void)))); +AL_FUNC(void, _al_run_exit_funcs, (void)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_file.h b/allegro/include/allegro5/internal/aintern_file.h new file mode 100644 index 00000000..81a7fe56 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_file.h @@ -0,0 +1,27 @@ +#ifndef __al_included_allegro5_aintern_file_h +#define __al_included_allegro5_aintern_file_h + +#ifdef __cplusplus + extern "C" { +#endif + + +extern const ALLEGRO_FILE_INTERFACE _al_file_interface_stdio; + +#define ALLEGRO_UNGETC_SIZE 16 + +struct ALLEGRO_FILE +{ + const ALLEGRO_FILE_INTERFACE *vtable; + void *userdata; + unsigned char ungetc[ALLEGRO_UNGETC_SIZE]; + int ungetc_len; +}; + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_float.h b/allegro/include/allegro5/internal/aintern_float.h new file mode 100644 index 00000000..bca66cf6 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_float.h @@ -0,0 +1,16 @@ +#ifndef __al_included_allegro5_aintern_float_h +#define __al_included_allegro5_aintern_float_h + + /* This file used to contain a tricky function that sped up float->int + * conversions on x86 machines when the SSE instruction CVTTSS2SI wasn't + * available (or when SSE wasn't enabled in the compiler). + * + * However, it performed rounding instead of truncating like (int)f, which + * did cause problems. If an alternative is found we could define this + * macro once again. + */ + #define _al_fast_float_to_int(f) ((int)(f)) + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_fshook.h b/allegro/include/allegro5/internal/aintern_fshook.h new file mode 100644 index 00000000..e159d57a --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_fshook.h @@ -0,0 +1,33 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Internal File System Hook support. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_aintern_fshook_h +#define __al_included_allegro5_aintern_fshook_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +extern struct ALLEGRO_FS_INTERFACE _al_fs_interface_stdio; + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_gp2xwiz.h b/allegro/include/allegro5/internal/aintern_gp2xwiz.h new file mode 100644 index 00000000..be73164b --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_gp2xwiz.h @@ -0,0 +1,51 @@ +#ifndef __al_included_allegro5_aintern_gp2xwiz_h +#define __al_included_allegro5_aintern_gp2xwiz_h + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/platform/aintwiz.h" +#include "allegro5/internal/aintern_opengl.h" + +#include + +typedef struct ALLEGRO_SYSTEM_GP2XWIZ ALLEGRO_SYSTEM_GP2XWIZ; +typedef struct ALLEGRO_DISPLAY_GP2XWIZ_OGL ALLEGRO_DISPLAY_GP2XWIZ_OGL; +typedef struct ALLEGRO_DISPLAY_GP2XWIZ_FB ALLEGRO_DISPLAY_GP2XWIZ_FB; + +struct ALLEGRO_SYSTEM_GP2XWIZ +{ + ALLEGRO_SYSTEM system; /* This must be the first member, we "derive" from it. */ + + ALLEGRO_EXTRA_DISPLAY_SETTINGS extras; +}; + +/* This is our version of ALLEGRO_DISPLAY with driver specific extra data. */ +struct ALLEGRO_DISPLAY_GP2XWIZ_OGL +{ + ALLEGRO_DISPLAY display; /* This must be the first member. */ + + EGLDisplay egl_display; + EGLConfig egl_config; + EGLContext egl_context; + EGLSurface egl_surface; + NativeWindowType hNativeWnd; +}; + +/* This is our version of ALLEGRO_DISPLAY with driver specific extra data. */ +struct ALLEGRO_DISPLAY_GP2XWIZ_FB +{ + ALLEGRO_DISPLAY display; /* This must be the first member. */ + + ALLEGRO_BITMAP *backbuffer; + /* + * We create the backbuffer bitmap then points it's ->memory at + * lc_fb1 (initialized with libcastor. This is a backup of the + * ->memory as created by al_create_bitmap. + */ + unsigned char *screen_mem; +}; + +#endif diff --git a/allegro/include/allegro5/internal/aintern_haptic.h b/allegro/include/allegro5/internal/aintern_haptic.h new file mode 100644 index 00000000..581a5a73 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_haptic.h @@ -0,0 +1,99 @@ +#ifndef __al_included_allegro5_aintern_haptic_h +#define __al_included_allegro5_aintern_haptic_h + +#include "allegro5/haptic.h" + +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_events.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) + +typedef struct ALLEGRO_HAPTIC_DRIVER +{ + int hapdrv_id; + const char *hapdrv_name; + const char *hapdrv_desc; + const char *hapdrv_ascii_name; + AL_METHOD(bool, init_haptic, (void)); + AL_METHOD(void, exit_haptic, (void)); + + AL_METHOD(bool, is_mouse_haptic, (ALLEGRO_MOUSE *)); + AL_METHOD(bool, is_joystick_haptic, (ALLEGRO_JOYSTICK *)); + AL_METHOD(bool, is_keyboard_haptic, (ALLEGRO_KEYBOARD *)); + AL_METHOD(bool, is_display_haptic, (ALLEGRO_DISPLAY *)); + AL_METHOD(bool, is_touch_input_haptic, (ALLEGRO_TOUCH_INPUT *)); + + AL_METHOD(ALLEGRO_HAPTIC *, get_from_mouse, (ALLEGRO_MOUSE *)); + AL_METHOD(ALLEGRO_HAPTIC *, get_from_joystick, (ALLEGRO_JOYSTICK *)); + AL_METHOD(ALLEGRO_HAPTIC *, get_from_keyboard, (ALLEGRO_KEYBOARD *)); + AL_METHOD(ALLEGRO_HAPTIC *, get_from_display, (ALLEGRO_DISPLAY *)); + AL_METHOD(ALLEGRO_HAPTIC *, get_from_touch_input, (ALLEGRO_TOUCH_INPUT *)); + + AL_METHOD(bool, get_active, (ALLEGRO_HAPTIC *)); + AL_METHOD(int, get_capabilities, (ALLEGRO_HAPTIC *)); + AL_METHOD(double, get_gain, (ALLEGRO_HAPTIC *)); + AL_METHOD(bool, set_gain, (ALLEGRO_HAPTIC *, double)); + AL_METHOD(int, get_max_effects, (ALLEGRO_HAPTIC *)); + + AL_METHOD(bool, is_effect_ok, (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *)); + AL_METHOD(bool, upload_effect, (ALLEGRO_HAPTIC *, ALLEGRO_HAPTIC_EFFECT *, + ALLEGRO_HAPTIC_EFFECT_ID *)); + AL_METHOD(bool, play_effect, (ALLEGRO_HAPTIC_EFFECT_ID *, int)); + AL_METHOD(bool, stop_effect, (ALLEGRO_HAPTIC_EFFECT_ID *)); + AL_METHOD(bool, is_effect_playing, (ALLEGRO_HAPTIC_EFFECT_ID *)); + AL_METHOD(bool, release_effect, (ALLEGRO_HAPTIC_EFFECT_ID *)); + AL_METHOD(bool, release, (ALLEGRO_HAPTIC *)); + AL_METHOD(double, get_autocenter, (ALLEGRO_HAPTIC *)); + AL_METHOD(bool, set_autocenter, (ALLEGRO_HAPTIC *, double)); +} ALLEGRO_HAPTIC_DRIVER; + + +enum ALLEGRO_HAPTIC_PARENT +{ + _AL_HAPTIC_FROM_JOYSTICK = 1, + _AL_HAPTIC_FROM_MOUSE, + _AL_HAPTIC_FROM_KEYBOARD, + _AL_HAPTIC_FROM_DISPLAY, + _AL_HAPTIC_FROM_TOUCH_INPUT +}; + +/* haptic has a driver field for per-device drivers on some platforms. */ +struct ALLEGRO_HAPTIC +{ + enum ALLEGRO_HAPTIC_PARENT from; + void *device; + double gain; + double autocenter; + ALLEGRO_HAPTIC_DRIVER *driver; +}; + +/* Haptic driver list. */ +extern const _AL_DRIVER_INFO _al_haptic_driver_list[]; + +/* Macros for constructing the driver list */ +#define _AL_BEGIN_HAPTIC_DRIVER_LIST \ + const _AL_DRIVER_INFO _al_haptic_driver_list[] = \ + { +#define _AL_END_HAPTIC_DRIVER_LIST \ + { 0, NULL, false } \ + }; + +#else + +/* Forward declare it for ALLEGRO_SYSTEM_INTERFACE. */ +typedef struct ALLEGRO_HAPTIC_DRIVER ALLEGRO_HAPTIC_DRIVER; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_iphone.h b/allegro/include/allegro5/internal/aintern_iphone.h new file mode 100644 index 00000000..9bebc5a1 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_iphone.h @@ -0,0 +1,63 @@ +#ifndef ALLEGRO_INTERNAL_IPHONE +#define ALLEGRO_INTERNAL_IPHONE + +#include "allegro5/allegro.h" +#include +#include + +typedef struct ALLEGRO_SYSTEM_IPHONE { + ALLEGRO_SYSTEM system; + + ALLEGRO_MUTEX *mutex; + ALLEGRO_COND *cond; + + bool has_shutdown, wants_shutdown; + int visuals_count; + ALLEGRO_EXTRA_DISPLAY_SETTINGS **visuals; +} ALLEGRO_SYSTEM_IPHONE; + +typedef struct ALLEGRO_DISPLAY_IPHONE_EXTRA ALLEGRO_DISPLAY_IPHONE_EXTRA; + +typedef struct ALLEGRO_DISPLAY_IPHONE { + ALLEGRO_DISPLAY display; + ALLEGRO_DISPLAY_IPHONE_EXTRA *extra; +} ALLEGRO_DISPLAY_IPHONE; + + +void _al_iphone_init_path(void); +bool _al_iphone_add_view(ALLEGRO_DISPLAY *d); +void _al_iphone_make_view_current(ALLEGRO_DISPLAY *display); +void _al_iphone_flip_view(ALLEGRO_DISPLAY *display); +void _al_iphone_reset_framebuffer(ALLEGRO_DISPLAY *display); +void _al_iphone_recreate_framebuffer(ALLEGRO_DISPLAY *); +void _al_iphone_destroy_screen(ALLEGRO_DISPLAY *display); +ALLEGRO_SYSTEM_INTERFACE *_al_get_iphone_system_interface(void); +ALLEGRO_DISPLAY_INTERFACE *_al_get_iphone_display_interface(void); +ALLEGRO_KEYBOARD_DRIVER *_al_get_iphone_keyboard_driver(void); +ALLEGRO_MOUSE_DRIVER *_al_get_iphone_mouse_driver(void); +ALLEGRO_TOUCH_INPUT_DRIVER *_al_get_iphone_touch_input_driver(void); +ALLEGRO_JOYSTICK_DRIVER *_al_get_iphone_joystick_driver(void); +void _al_iphone_setup_opengl_view(ALLEGRO_DISPLAY *d, bool manage_backbuffer); +//void _al_iphone_generate_mouse_event(unsigned int type, +// int x, int y, unsigned int button, ALLEGRO_DISPLAY *d); +//void _al_iphone_generate_touch_event(unsigned int type, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *d); +void _al_iphone_update_visuals(void); +void _al_iphone_accelerometer_control(int frequency); +void _al_iphone_generate_joystick_event(float x, float y, float z); +void _al_iphone_await_termination(void); +void _al_iphone_get_screen_size(int adapter, int *w, int *h); +int _al_iphone_get_num_video_adapters(void); +int _al_iphone_get_orientation(); +void _al_iphone_translate_from_screen(ALLEGRO_DISPLAY *d, int *x, int *y); +void _al_iphone_translate_to_screen(ALLEGRO_DISPLAY *d, int *x, int *y); +void _al_iphone_clip(ALLEGRO_BITMAP const *bitmap, int x_1, int y_1, int x_2, int y_2); + +void _al_iphone_touch_input_handle_begin(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp); +void _al_iphone_touch_input_handle_end(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp); +void _al_iphone_touch_input_handle_move(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp); +void _al_iphone_touch_input_handle_cancel(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp); + +void _al_iphone_disconnect(ALLEGRO_DISPLAY *display); +void _al_iphone_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt); + +#endif // ALLEGRO_INTERNAL_IPHONE diff --git a/allegro/include/allegro5/internal/aintern_joystick.h b/allegro/include/allegro5/internal/aintern_joystick.h new file mode 100644 index 00000000..ef313150 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_joystick.h @@ -0,0 +1,93 @@ +#ifndef __al_included_allegro5_aintern_joystick_h +#define __al_included_allegro5_aintern_joystick_h + +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_events.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct ALLEGRO_JOYSTICK_DRIVER +{ + int joydrv_id; + const char *joydrv_name; + const char *joydrv_desc; + const char *joydrv_ascii_name; + AL_METHOD(bool, init_joystick, (void)); + AL_METHOD(void, exit_joystick, (void)); + AL_METHOD(bool, reconfigure_joysticks, (void)); + AL_METHOD(int, num_joysticks, (void)); + AL_METHOD(ALLEGRO_JOYSTICK *, get_joystick, (int joyn)); + AL_METHOD(void, release_joystick, (ALLEGRO_JOYSTICK *joy)); + AL_METHOD(void, get_joystick_state, (ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state)); + AL_METHOD(const char *, get_name, (ALLEGRO_JOYSTICK *joy)); + AL_METHOD(bool, get_active, (ALLEGRO_JOYSTICK *joy)); +} ALLEGRO_JOYSTICK_DRIVER; + + +extern _AL_DRIVER_INFO _al_joystick_driver_list[]; + + +/* macros for constructing the driver list */ +#define _AL_BEGIN_JOYSTICK_DRIVER_LIST \ + _AL_DRIVER_INFO _al_joystick_driver_list[] = \ + { + +#define _AL_END_JOYSTICK_DRIVER_LIST \ + { 0, NULL, false } \ + }; + + +/* information about a single joystick axis */ +typedef struct _AL_JOYSTICK_AXIS_INFO +{ + char *name; +} _AL_JOYSTICK_AXIS_INFO; + + +/* information about one or more axis (a slider or directional control) */ +typedef struct _AL_JOYSTICK_STICK_INFO +{ + int flags; /* bit-field */ + int num_axes; + _AL_JOYSTICK_AXIS_INFO axis[_AL_MAX_JOYSTICK_AXES]; + char *name; +} _AL_JOYSTICK_STICK_INFO; + + +/* information about a joystick button */ +typedef struct _AL_JOYSTICK_BUTTON_INFO +{ + const char *name; +} _AL_JOYSTICK_BUTTON_INFO; + + +/* information about an entire joystick */ +typedef struct _AL_JOYSTICK_INFO +{ + int num_sticks; + int num_buttons; + _AL_JOYSTICK_STICK_INFO stick[_AL_MAX_JOYSTICK_STICKS]; + _AL_JOYSTICK_BUTTON_INFO button[_AL_MAX_JOYSTICK_BUTTONS]; +} _AL_JOYSTICK_INFO; + + +/* Joystick has a driver field for per-device drivers, + * needed on some platforms. */ +struct ALLEGRO_JOYSTICK +{ + _AL_JOYSTICK_INFO info; + ALLEGRO_JOYSTICK_DRIVER * driver; +}; + +void _al_generate_joystick_event(ALLEGRO_EVENT *event); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vi ts=8 sts=3 sw=3 et */ diff --git a/allegro/include/allegro5/internal/aintern_keyboard.h b/allegro/include/allegro5/internal/aintern_keyboard.h new file mode 100644 index 00000000..dd939225 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_keyboard.h @@ -0,0 +1,65 @@ +#ifndef __al_included_allegro5_aintern_keyboard_h +#define __al_included_allegro5_aintern_keyboard_h + +#include "allegro5/internal/aintern_driver.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct ALLEGRO_KEYBOARD_DRIVER +{ + int keydrv_id; + const char *keydrv_name; + const char *keydrv_desc; + const char *keydrv_ascii_name; + AL_METHOD(bool, init_keyboard, (void)); + AL_METHOD(void, exit_keyboard, (void)); + AL_METHOD(ALLEGRO_KEYBOARD*, get_keyboard, (void)); + AL_METHOD(bool, set_keyboard_leds, (int leds)); + AL_METHOD(const char *, keycode_to_name, (int keycode)); + AL_METHOD(void, get_keyboard_state, (ALLEGRO_KEYBOARD_STATE *ret_state)); + AL_METHOD(void, clear_keyboard_state, (void)); +} ALLEGRO_KEYBOARD_DRIVER; + + +extern _AL_DRIVER_INFO _al_keyboard_driver_list[]; + +extern const char *_al_keyboard_common_names[]; + +int _al_parse_key_binding(const char *s, unsigned int *modifiers); + + +struct ALLEGRO_KEYBOARD +{ + ALLEGRO_EVENT_SOURCE es; +}; + + +/* Helpers for AL_KEYBOARD_STATE structures. */ + +#define _AL_KEYBOARD_STATE_KEY_DOWN(STATE, KEYCODE) \ + (((STATE).__key_down__internal__[(KEYCODE) / 32] & (1 << ((KEYCODE) % 32)))\ + ? true : false) + +#define _AL_KEYBOARD_STATE_SET_KEY_DOWN(STATE, KEYCODE) \ + do { \ + int kc = (KEYCODE); \ + (STATE).__key_down__internal__[kc / 32] |= (1 << (kc % 32)); \ + } while (0) + +#define _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(STATE, KEYCODE) \ + do { \ + int kc = (KEYCODE); \ + (STATE).__key_down__internal__[kc / 32] &= ~(1 << (kc % 32)); \ + } while (0) + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vi ts=8 sts=3 sw=3 et */ diff --git a/allegro/include/allegro5/internal/aintern_list.h b/allegro/include/allegro5/internal/aintern_list.h new file mode 100644 index 00000000..c700773d --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_list.h @@ -0,0 +1,75 @@ +#ifndef __al_included_allegro5_aintern_list_h +#define __al_included_allegro5_aintern_list_h + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _AL_LIST _AL_LIST; +typedef struct _AL_LIST_ITEM _AL_LIST_ITEM; + +typedef void (*_AL_LIST_DTOR)(void* userdata); +typedef void (*_AL_LIST_ITEM_DTOR)(void* value, void* userdata); + +AL_FUNC(_AL_LIST*, _al_list_create, (void)); +AL_FUNC(_AL_LIST*, _al_list_create_static, (size_t capacity)); +AL_FUNC(void, _al_list_destroy, (_AL_LIST* list)); + +AL_FUNC(void, _al_list_set_dtor, (_AL_LIST* list, _AL_LIST_DTOR dtor)); +AL_FUNC(_AL_LIST_DTOR, _al_list_get_dtor, (_AL_LIST* list)); + +AL_FUNC(_AL_LIST_ITEM*, _al_list_push_front, (_AL_LIST* list, void* data)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_push_front_ex, (_AL_LIST* list, void* data, _AL_LIST_ITEM_DTOR dtor)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_push_back, (_AL_LIST* list, void* data)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_push_back_ex, (_AL_LIST* list, void* data, _AL_LIST_ITEM_DTOR dtor)); + +AL_FUNC(void, _al_list_pop_front, (_AL_LIST* list)); +AL_FUNC(void, _al_list_pop_back, (_AL_LIST* list)); + +AL_FUNC(_AL_LIST_ITEM*, _al_list_insert_after, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_insert_after_ex, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data, _AL_LIST_ITEM_DTOR dtor)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_insert_before, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_insert_before_ex, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data, _AL_LIST_ITEM_DTOR dtor)); + +AL_FUNC(void, _al_list_erase, (_AL_LIST* list, _AL_LIST_ITEM* item)); + +AL_FUNC(void, _al_list_clear, (_AL_LIST* list)); + +AL_FUNC(void, _al_list_remove, (_AL_LIST* list, void* data)); + +AL_FUNC(bool, _al_list_is_empty, (_AL_LIST* list)); + +AL_FUNC(bool, _al_list_contains, (_AL_LIST* list, void* data)); + +AL_FUNC(_AL_LIST_ITEM*, _al_list_find_first, (_AL_LIST* list, void* data)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_find_last, (_AL_LIST* list, void* data)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_find_after, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_find_before, (_AL_LIST* list, _AL_LIST_ITEM* where, void* data)); + +AL_FUNC(size_t, _al_list_size, (_AL_LIST* list)); + +AL_FUNC(_AL_LIST_ITEM*, _al_list_at, (_AL_LIST* list, size_t index)); + +AL_FUNC(_AL_LIST_ITEM*, _al_list_front, (_AL_LIST* list)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_back, (_AL_LIST* list)); + +AL_FUNC(_AL_LIST_ITEM*, _al_list_next, (_AL_LIST* list, _AL_LIST_ITEM* item)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_previous, (_AL_LIST* list, _AL_LIST_ITEM* item)); + +AL_FUNC(_AL_LIST_ITEM*, _al_list_next_circular, (_AL_LIST* list, _AL_LIST_ITEM* item)); +AL_FUNC(_AL_LIST_ITEM*, _al_list_previous_circular, (_AL_LIST* list, _AL_LIST_ITEM* item)); + +AL_FUNC(void*, _al_list_item_data, (_AL_LIST_ITEM* item)); + +AL_FUNC(void, _al_list_item_set_dtor, (_AL_LIST_ITEM* item, _AL_LIST_ITEM_DTOR dtor)); +AL_FUNC(_AL_LIST_ITEM_DTOR, _al_list_item_get_dtor, (_AL_LIST_ITEM* item)); + +AL_FUNC(void, _al_list_set_user_data, (_AL_LIST* list, void* user_data)); +AL_FUNC(void*, _al_list_get_user_data, (_AL_LIST* list)); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_ljoynu.h b/allegro/include/allegro5/internal/aintern_ljoynu.h new file mode 100644 index 00000000..355bc320 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_ljoynu.h @@ -0,0 +1,70 @@ +#ifndef __al_included_allegro_aintern_ljoynu_h +#define __al_included_allegro_aintern_ljoynu_h + +#include "allegro5/joystick.h" +#include "allegro5/internal/aintern_joystick.h" + + +/* XXX reconsider what needs to be exposed after the haptics driver is in */ + + +/* State transitions: + * unused -> born + * born -> alive + * born -> dying + * active -> dying + * dying -> unused + */ +typedef enum { + LJOY_STATE_UNUSED, + LJOY_STATE_BORN, + LJOY_STATE_ALIVE, + LJOY_STATE_DYING +} CONFIG_STATE; + +#define ACTIVE_STATE(st) \ + ((st) == LJOY_STATE_ALIVE || (st) == LJOY_STATE_DYING) + + +/* Map a Linux joystick axis number to an Allegro (stick,axis) pair + * Uses the input event interface's numbering where ABS_MISC = 0x28, + * so that is the maximum of allowed axes on Linux. + */ +#define TOTAL_JOYSTICK_AXES (0x28) + +typedef struct { + int stick; + int axis; + /* XXX reconsider what fields are required after the haptics driver is in */ + int value; + int min; + int max; + int fuzz; + int flat; +} AXIS_MAPPING; + + +/* Map a Linux input button code to button number on the Allegro joystick. */ +typedef struct { + int ev_code; +} BUTTON_MAPPING; + + +typedef struct ALLEGRO_JOYSTICK_LINUX +{ + ALLEGRO_JOYSTICK parent; + int config_state; + bool marked; + int fd; + ALLEGRO_USTR *device_name; + + AXIS_MAPPING axis_mapping[TOTAL_JOYSTICK_AXES]; + BUTTON_MAPPING button_mapping[_AL_MAX_JOYSTICK_BUTTONS]; + ALLEGRO_JOYSTICK_STATE joystate; + char name[100]; +} ALLEGRO_JOYSTICK_LINUX; + + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_memblit.h b/allegro/include/allegro5/internal/aintern_memblit.h new file mode 100644 index 00000000..0e6bed2d --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_memblit.h @@ -0,0 +1,20 @@ +#ifndef __al_included_allegro5_aintern_memblit_h +#define __al_included_allegro5_aintern_memblit_h + +#ifdef __cplusplus + extern "C" { +#endif + + +void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + int sx, int sy, int sw, int sh, int dx, int dy, int flags); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_memdraw.h b/allegro/include/allegro5/internal/aintern_memdraw.h new file mode 100644 index 00000000..adb29567 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_memdraw.h @@ -0,0 +1,19 @@ +#ifndef __al_included_allegro5_aintern_memdraw_h +#define __al_included_allegro5_aintern_memdraw_h + +#ifdef __cplusplus + extern "C" { +#endif + + +void _al_clear_bitmap_by_locking(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR *color); +void _al_draw_pixel_memory(ALLEGRO_BITMAP *bmp, float x, float y, ALLEGRO_COLOR *color); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_mouse.h b/allegro/include/allegro5/internal/aintern_mouse.h new file mode 100644 index 00000000..cdbe0467 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_mouse.h @@ -0,0 +1,44 @@ +#ifndef __al_included_allegro5_aintern_mouse_h +#define __al_included_allegro5_aintern_mouse_h + +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_events.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct ALLEGRO_MOUSE_DRIVER +{ + int msedrv_id; + const char *msedrv_name; + const char *msedrv_desc; + const char *msedrv_ascii_name; + AL_METHOD(bool, init_mouse, (void)); + AL_METHOD(void, exit_mouse, (void)); + AL_METHOD(ALLEGRO_MOUSE*, get_mouse, (void)); + AL_METHOD(unsigned int, get_mouse_num_buttons, (void)); + AL_METHOD(unsigned int, get_mouse_num_axes, (void)); + AL_METHOD(bool, set_mouse_xy, (ALLEGRO_DISPLAY *display, int x, int y)); + AL_METHOD(bool, set_mouse_axis, (int which, int value)); + AL_METHOD(void, get_mouse_state, (ALLEGRO_MOUSE_STATE *ret_state)); +} ALLEGRO_MOUSE_DRIVER; + + +extern _AL_DRIVER_INFO _al_mouse_driver_list[]; + + +struct ALLEGRO_MOUSE +{ + ALLEGRO_EVENT_SOURCE es; +}; + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vi ts=8 sts=3 sw=3 et */ diff --git a/allegro/include/allegro5/internal/aintern_opengl.h b/allegro/include/allegro5/internal/aintern_opengl.h new file mode 100644 index 00000000..fd42be41 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_opengl.h @@ -0,0 +1,236 @@ +#ifndef __al_included_allegro5_aintern_opengl_h +#define __al_included_allegro5_aintern_opengl_h + +#include "allegro5/opengl/gl_ext.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +enum { + _ALLEGRO_OPENGL_VERSION_0 = 0, /* dummy */ + _ALLEGRO_OPENGL_VERSION_1_0 = 0x01000000, + _ALLEGRO_OPENGL_VERSION_1_1 = 0x01010000, + _ALLEGRO_OPENGL_VERSION_1_2 = 0x01020000, + _ALLEGRO_OPENGL_VERSION_1_2_1 = 0x01020100, + _ALLEGRO_OPENGL_VERSION_1_3 = 0x01030000, + _ALLEGRO_OPENGL_VERSION_1_4 = 0x01040000, + _ALLEGRO_OPENGL_VERSION_1_5 = 0x01050000, + _ALLEGRO_OPENGL_VERSION_2_0 = 0x02000000, + _ALLEGRO_OPENGL_VERSION_2_1 = 0x02010000, + _ALLEGRO_OPENGL_VERSION_3_0 = 0x03000000, + _ALLEGRO_OPENGL_VERSION_3_1 = 0x03010000, + _ALLEGRO_OPENGL_VERSION_3_2 = 0x03020000, + _ALLEGRO_OPENGL_VERSION_3_3 = 0x03030000, + _ALLEGRO_OPENGL_VERSION_4_0 = 0x04000000 +}; + +#define ALLEGRO_MAX_OPENGL_FBOS 8 + +enum { + FBO_INFO_UNUSED = 0, + FBO_INFO_TRANSIENT = 1, /* may be destroyed for another bitmap */ + FBO_INFO_PERSISTENT = 2 /* exclusive to the owner bitmap */ +}; + +typedef struct ALLEGRO_FBO_BUFFERS +{ + /* It is not easy to determine the best lifetime for these. Unlike + * FBOs they are heavy objects and re-creating them can be costly. + * However if we make them part of ALLEGRO_BITMAP_EXTRA_OPENGL + * below, there is no way to release them. I.e. if you create + * many bitmaps in the beginning of your game and need depth and/or + * multisampling for them, the only way to free the buffers would be + * to copy those bitmaps and then destroy them. + * + * By tying them to the FBO struct, there is a limit of how many + * buffers Allegro will create before recycling them. This will + * work very well in the case where you only have one or a few + * bitmaps you regularly draw into. + */ + GLuint depth_buffer; + int dw, dh, depth; + + GLuint multisample_buffer; + int mw, mh, samples; +} ALLEGRO_FBO_BUFFERS; + +typedef struct ALLEGRO_FBO_INFO +{ + int fbo_state; + GLuint fbo; + + ALLEGRO_FBO_BUFFERS buffers; + + ALLEGRO_BITMAP *owner; + double last_use_time; +} ALLEGRO_FBO_INFO; + +typedef struct ALLEGRO_BITMAP_EXTRA_OPENGL +{ + /* Driver specifics. */ + + int true_w; + int true_h; + + GLuint texture; /* 0 means, not uploaded yet. */ + + ALLEGRO_FBO_INFO *fbo_info; + + /* When an OpenGL bitmap is locked, the locked region is usually backed by a + * temporary memory buffer pointed to by lock_buffer. + * + * On GLES, a locked backbuffer may be backed by a texture bitmap pointed to + * by lock_proxy instead, and lock_buffer is NULL. Upon unlocking the proxy + * bitmap is drawn onto the backbuffer. + */ + unsigned char *lock_buffer; + ALLEGRO_BITMAP *lock_proxy; + + float left, top, right, bottom; /* Texture coordinates. */ + bool is_backbuffer; /* This is not a real bitmap, but the backbuffer. */ +} ALLEGRO_BITMAP_EXTRA_OPENGL; + +typedef struct OPENGL_INFO { + uint32_t version; /* OpenGL version */ + int max_texture_size; /* Maximum texture size */ + int is_voodoo3_and_under; /* Special cases for Voodoo 1-3 */ + int is_voodoo; /* Special cases for Voodoo cards */ + int is_matrox_g200; /* Special cases for Matrox G200 boards */ + int is_ati_rage_pro; /* Special cases for ATI Rage Pro boards */ + int is_ati_radeon_7000; /* Special cases for ATI Radeon 7000 */ + int is_ati_r200_chip; /* Special cases for ATI card with chip R200 */ + int is_mesa_driver; /* Special cases for MESA */ + int is_intel_hd_graphics_3000; +} OPENGL_INFO; + + +typedef struct ALLEGRO_OGL_VARLOCS +{ + /* Cached shader variable locations. */ + GLint pos_loc; + GLint color_loc; + GLint projview_matrix_loc; + GLint texcoord_loc; + GLint use_tex_loc; + GLint tex_loc; + GLint use_tex_matrix_loc; + GLint tex_matrix_loc; + GLint alpha_test_loc; + GLint alpha_func_loc; + GLint alpha_test_val_loc; + GLint user_attr_loc[_ALLEGRO_PRIM_MAX_USER_ATTR]; +} ALLEGRO_OGL_VARLOCS; + +typedef struct ALLEGRO_OGL_EXTRAS +{ + /* A list of extensions supported by Allegro, for this context. */ + ALLEGRO_OGL_EXT_LIST *extension_list; + /* A list of extension API, loaded by Allegro, for this context. */ + ALLEGRO_OGL_EXT_API *extension_api; + /* Various info about OpenGL implementation. */ + OPENGL_INFO ogl_info; + + ALLEGRO_BITMAP *opengl_target; + + ALLEGRO_BITMAP *backbuffer; + + /* True if display resources are shared among displays. */ + bool is_shared; + + ALLEGRO_FBO_INFO fbos[ALLEGRO_MAX_OPENGL_FBOS]; + + /* In non-programmable pipe mode this should be zero. + * In programmable pipeline mode this should be non-zero. + */ + GLuint program_object; + ALLEGRO_OGL_VARLOCS varlocs; + + /* For OpenGL 3.0+ we use a single vao and vbo. */ + GLuint vao, vbo; + +} ALLEGRO_OGL_EXTRAS; + +typedef struct ALLEGRO_OGL_BITMAP_VERTEX +{ + float x, y, z; + float tx, ty; + float r, g, b, a; +} ALLEGRO_OGL_BITMAP_VERTEX; + + +/* extensions */ +int _al_ogl_look_for_an_extension(const char *name, const GLubyte *extensions); +void _al_ogl_set_extensions(ALLEGRO_OGL_EXT_API *ext); +void _al_ogl_manage_extensions(ALLEGRO_DISPLAY *disp); +void _al_ogl_unmanage_extensions(ALLEGRO_DISPLAY *disp); + +/* bitmap */ +int _al_ogl_get_glformat(int format, int component); +ALLEGRO_BITMAP *_al_ogl_create_bitmap(ALLEGRO_DISPLAY *d, int w, int h, + int format, int flags); +void _al_ogl_upload_bitmap_memory(ALLEGRO_BITMAP *bitmap, int format, void *ptr); + +/* locking */ +#ifndef ALLEGRO_CFG_OPENGLES + ALLEGRO_LOCKED_REGION *_al_ogl_lock_region_new(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int format, int flags); + void _al_ogl_unlock_region_new(ALLEGRO_BITMAP *bitmap); +#else + ALLEGRO_LOCKED_REGION *_al_ogl_lock_region_gles(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int format, int flags); + void _al_ogl_unlock_region_gles(ALLEGRO_BITMAP *bitmap); +#endif + +int _al_ogl_pixel_alignment(int pixel_size, bool compressed); + +/* framebuffer objects */ +GLint _al_ogl_bind_framebuffer(GLint fbo); +void _al_ogl_reset_fbo_info(ALLEGRO_FBO_INFO *info); +bool _al_ogl_create_persistent_fbo(ALLEGRO_BITMAP *bitmap); +ALLEGRO_FBO_INFO *_al_ogl_persist_fbo(ALLEGRO_DISPLAY *display, + ALLEGRO_FBO_INFO *transient_fbo_info); +void _al_ogl_setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); +bool _al_ogl_setup_fbo_non_backbuffer(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap); +void _al_ogl_del_fbo(ALLEGRO_FBO_INFO *info); + +/* common driver */ +void _al_ogl_setup_gl(ALLEGRO_DISPLAY *d); +void _al_ogl_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); +void _al_ogl_unset_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); +void _al_ogl_finalize_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); +void _al_ogl_setup_bitmap_clipping(const ALLEGRO_BITMAP *bitmap); +ALLEGRO_BITMAP *_al_ogl_get_backbuffer(ALLEGRO_DISPLAY *d); +ALLEGRO_BITMAP* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp); +void _al_ogl_destroy_backbuffer(ALLEGRO_BITMAP *b); +bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP *b, int w, int h); +void _al_opengl_backup_dirty_bitmaps(ALLEGRO_DISPLAY *d, bool flip); + +/* draw */ +struct ALLEGRO_DISPLAY_INTERFACE; +void _al_ogl_add_drawing_functions(struct ALLEGRO_DISPLAY_INTERFACE *vt); + +AL_FUNC(bool, _al_opengl_set_blender, (ALLEGRO_DISPLAY *disp)); +AL_FUNC(char const *, _al_gl_error_string, (GLenum e)); + +void _al_ogl_update_render_state(ALLEGRO_DISPLAY *display); + +/* shader */ +#ifdef ALLEGRO_CFG_SHADER_GLSL + bool _al_glsl_set_projview_matrix(GLint projview_matrix_loc, + const ALLEGRO_TRANSFORM *t); + void _al_glsl_init_shaders(void); + void _al_glsl_shutdown_shaders(void); + void _al_glsl_unuse_shaders(void); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_osxclipboard.h b/allegro/include/allegro5/internal/aintern_osxclipboard.h new file mode 100644 index 00000000..a2eae18c --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_osxclipboard.h @@ -0,0 +1,21 @@ +#ifndef __al_included_allegro5_aintern_osxclipboard_h +#define __al_included_allegro5_aintern_osxclipboard_h + + +#include "allegro5/internal/aintern_display.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void _al_osx_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt); + +#ifdef __cplusplus +} +#endif + + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_path.h b/allegro/include/allegro5/internal/aintern_path.h new file mode 100644 index 00000000..a0d51c72 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_path.h @@ -0,0 +1,14 @@ +#ifndef __al_included_allegro5_aintern_path_h +#define __al_included_allegro5_aintern_path_h + +struct ALLEGRO_PATH { + ALLEGRO_USTR *drive; + ALLEGRO_USTR *filename; + _AL_VECTOR segments; /* vector of ALLEGRO_USTR * */ + ALLEGRO_USTR *basename; + ALLEGRO_USTR *full_string; +}; + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_pixels.h b/allegro/include/allegro5/internal/aintern_pixels.h new file mode 100644 index 00000000..e85f7096 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_pixels.h @@ -0,0 +1,504 @@ +#ifndef __al_included_allegro5_aintern_pixels_h +#define __al_included_allegro5_aintern_pixels_h + +#include "allegro5/internal/aintern_float.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +#define _AL_MAP_RGBA(_color, _r, _g, _b, _a) \ + do { \ + (_color).r = _al_u8_to_float[_r]; \ + (_color).g = _al_u8_to_float[_g]; \ + (_color).b = _al_u8_to_float[_b]; \ + (_color).a = _al_u8_to_float[_a]; \ + } while (0) + + +#define _AL_INLINE_GET_PIXEL(format, data, color, advance) \ + do { \ + switch (format) { \ + case ALLEGRO_PIXEL_FORMAT_ARGB_8888: { \ + uint32_t _gp_pixel = *(uint32_t *)(data); \ + _AL_MAP_RGBA(color, \ + (_gp_pixel & 0x00FF0000) >> 16, \ + (_gp_pixel & 0x0000FF00) >> 8, \ + (_gp_pixel & 0x000000FF) >> 0, \ + (_gp_pixel & 0xFF000000) >> 24); \ + if (advance) \ + data += 4; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_RGBA_8888: { \ + uint32_t _gp_pixel = *(uint32_t *)(data); \ + _AL_MAP_RGBA(color, \ + (_gp_pixel & 0xFF000000) >> 24, \ + (_gp_pixel & 0x00FF0000) >> 16, \ + (_gp_pixel & 0x0000FF00) >> 8, \ + (_gp_pixel & 0x000000FF) >> 0); \ + if (advance) \ + data += 4; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_ARGB_4444: { \ + uint16_t _gp_pixel = *(uint16_t *)(data); \ + _AL_MAP_RGBA(color, \ + _al_rgb_scale_4[(_gp_pixel & 0x0F00) >> 8], \ + _al_rgb_scale_4[(_gp_pixel & 0x00F0) >> 4], \ + _al_rgb_scale_4[(_gp_pixel & 0x000F)], \ + _al_rgb_scale_4[(_gp_pixel & 0xF000) >> 12]); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_RGB_888: { \ + uint32_t _gp_pixel = _AL_READ3BYTES(data); \ + _AL_MAP_RGBA(color, \ + (_gp_pixel & 0xFF0000) >> 16, \ + (_gp_pixel & 0x00FF00) >> 8, \ + (_gp_pixel & 0x0000FF) >> 0, \ + 255); \ + if (advance) \ + data += 3; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_RGB_565: { \ + uint16_t _gp_pixel = *(uint16_t *)(data); \ + _AL_MAP_RGBA(color, \ + _al_rgb_scale_5[(_gp_pixel & 0xF800) >> 11], \ + _al_rgb_scale_6[(_gp_pixel & 0x07E0) >> 5], \ + _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ + 255); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_RGB_555: { \ + uint16_t _gp_pixel = *(uint16_t *)(data); \ + _AL_MAP_RGBA(color, \ + _al_rgb_scale_5[(_gp_pixel & 0x7C00) >> 10], \ + _al_rgb_scale_5[(_gp_pixel & 0x03E0) >> 5], \ + _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ + 255); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_RGBA_5551: { \ + uint16_t _gp_pixel = *(uint16_t *)(data); \ + _AL_MAP_RGBA(color, \ + _al_rgb_scale_5[(_gp_pixel & 0xF800) >> 11], \ + _al_rgb_scale_5[(_gp_pixel & 0x07C0) >> 6], \ + _al_rgb_scale_5[(_gp_pixel & 0x003E) >> 1], \ + _al_rgb_scale_1[_gp_pixel & 1]); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_ARGB_1555: { \ + uint16_t _gp_pixel = *(uint16_t *)(data); \ + _AL_MAP_RGBA(color, \ + _al_rgb_scale_5[(_gp_pixel & 0x7C00) >> 10], \ + _al_rgb_scale_5[(_gp_pixel & 0x03E0) >> 5], \ + _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ + _al_rgb_scale_1[(_gp_pixel & 0x8000) >> 15]); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_ABGR_8888: { \ + uint32_t _gp_pixel = *(uint32_t *)(data); \ + _AL_MAP_RGBA(color, \ + (_gp_pixel & 0x000000FF) >> 0, \ + (_gp_pixel & 0x0000FF00) >> 8, \ + (_gp_pixel & 0x00FF0000) >> 16, \ + (_gp_pixel & 0xFF000000) >> 24); \ + if (advance) \ + data += 4; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_XBGR_8888: { \ + uint32_t _gp_pixel = *(uint32_t *)(data); \ + _AL_MAP_RGBA(color, \ + (_gp_pixel & 0x000000FF) >> 0, \ + (_gp_pixel & 0x0000FF00) >> 8, \ + (_gp_pixel & 0x00FF0000) >> 16, \ + 255); \ + if (advance) \ + data += 4; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_BGR_888: { \ + uint32_t _gp_pixel = _AL_READ3BYTES(data); \ + _AL_MAP_RGBA(color, \ + (_gp_pixel & 0x000000FF) >> 0, \ + (_gp_pixel & 0x0000FF00) >> 8, \ + (_gp_pixel & 0x00FF0000) >> 16, \ + 255); \ + if (advance) \ + data += 4; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_BGR_565: { \ + uint16_t _gp_pixel = *(uint16_t *)(data); \ + _AL_MAP_RGBA(color, \ + _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ + _al_rgb_scale_6[(_gp_pixel & 0x07E0) >> 5], \ + _al_rgb_scale_5[(_gp_pixel & 0xF800) >> 11], \ + 255); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_BGR_555: { \ + uint16_t _gp_pixel = *(uint16_t *)(data); \ + _AL_MAP_RGBA(color, \ + _al_rgb_scale_5[(_gp_pixel & 0x001F)], \ + _al_rgb_scale_5[(_gp_pixel & 0x03E0) >> 5], \ + _al_rgb_scale_5[(_gp_pixel & 0x7C00) >> 10], \ + 255); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_RGBX_8888: { \ + uint32_t _gp_pixel = *(uint32_t *)(data); \ + _AL_MAP_RGBA(color, \ + (_gp_pixel & 0xFF000000) >> 24, \ + (_gp_pixel & 0x00FF0000) >> 16, \ + (_gp_pixel & 0x0000FF00) >> 8, \ + 255); \ + if (advance) \ + data += 4; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_XRGB_8888: { \ + uint32_t _gp_pixel = *(uint32_t *)(data); \ + _AL_MAP_RGBA(color, \ + (_gp_pixel & 0x00FF0000) >> 16, \ + (_gp_pixel & 0x0000FF00) >> 8, \ + (_gp_pixel & 0x000000FF), \ + 255); \ + if (advance) \ + data += 4; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_ABGR_F32: { \ + float *f = (float *)data; \ + color.r = f[0]; \ + color.g = f[1]; \ + color.b = f[2]; \ + color.a = f[3]; \ + if (advance) \ + data += 4 * sizeof(float); \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE: { \ + uint8_t *p = (uint8_t *)data; \ + _AL_MAP_RGBA(color, *p, *(p + 1), *(p + 2), *(p + 3)); \ + if (advance) \ + data += 4; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_RGBA_4444: { \ + uint16_t _gp_pixel = *(uint16_t *)(data); \ + _AL_MAP_RGBA(color, \ + _al_rgb_scale_4[(_gp_pixel & 0xF000) >> 12], \ + _al_rgb_scale_4[(_gp_pixel & 0x0F00) >> 8], \ + _al_rgb_scale_4[(_gp_pixel & 0x00F0) >> 4], \ + _al_rgb_scale_4[(_gp_pixel & 0x000F)]); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8: { \ + uint8_t c = *(uint8_t *)(data); \ + _AL_MAP_RGBA(color, c, c, c, 255); \ + if (advance) \ + data += 2; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_ANY: \ + case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: \ + ALLEGRO_ERROR("INLINE_GET got fake pixel format: %d\n", format); \ + abort(); \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1: \ + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3: \ + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5: \ + ALLEGRO_ERROR("INLINE_GET got compressed format: %d\n", format); \ + abort(); \ + break; \ + \ + case ALLEGRO_NUM_PIXEL_FORMATS: \ + default: \ + ALLEGRO_ERROR("INLINE_GET got non pixel format: %d\n", format); \ + abort(); \ + break; \ + } \ + } while (0) + + +#define _AL_INLINE_PUT_PIXEL(format, data, color, advance) \ + do { \ + uint32_t _pp_pixel; \ + switch (format) { \ + case ALLEGRO_PIXEL_FORMAT_ARGB_8888: \ + _pp_pixel = _al_fast_float_to_int(color.a * 255) << 24; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 255) << 16; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 255) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 255); \ + *(uint32_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 4; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_RGBA_8888: \ + _pp_pixel = _al_fast_float_to_int(color.r * 255) << 24; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 255) << 16; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 255) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.a * 255); \ + *(uint32_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 4; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_ARGB_4444: \ + _pp_pixel = _al_fast_float_to_int(color.a * 15) << 12; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 15) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 15) << 4; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 15); \ + *(uint16_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 2; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_RGB_888: \ + _pp_pixel = _al_fast_float_to_int(color.r * 255) << 16; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 255) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 255); \ + _AL_WRITE3BYTES(data, _pp_pixel); \ + if (advance) \ + data += 3; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_RGB_565: \ + _pp_pixel = _al_fast_float_to_int(color.r * 0x1f) << 11; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0x3f) << 5; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 0x1f); \ + *(uint16_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 2; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_RGB_555: \ + _pp_pixel = _al_fast_float_to_int(color.r * 0x1f) << 10; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0x1f) << 5; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 0x1f); \ + *(uint16_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 2; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_RGBA_5551: \ + _pp_pixel = _al_fast_float_to_int(color.r * 0x1f) << 11; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0x1f) << 6; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 0x1f) << 1; \ + _pp_pixel |= _al_fast_float_to_int(color.a); \ + *(uint16_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 2; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_ARGB_1555: \ + _pp_pixel = _al_fast_float_to_int(color.a) << 15; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 0x1f) << 10; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0x1f) << 5; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 0x1f); \ + *(uint16_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 2; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_ABGR_8888: \ + _pp_pixel = _al_fast_float_to_int(color.a * 0xff) << 24; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 0xff) << 16; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 0xff); \ + *(uint32_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 4; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_XBGR_8888: \ + _pp_pixel = 0xff000000; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 0xff) << 16; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 0xff); \ + *(uint32_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 4; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_BGR_888: \ + _pp_pixel = _al_fast_float_to_int(color.b * 0xff) << 16; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 0xff); \ + _AL_WRITE3BYTES(data, _pp_pixel); \ + if (advance) \ + data += 3; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_BGR_565: \ + _pp_pixel = _al_fast_float_to_int(color.b * 0x1f) << 11; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0x3f) << 5; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 0x1f); \ + *(uint16_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 2; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_BGR_555: \ + _pp_pixel = _al_fast_float_to_int(color.b * 0x1f) << 10; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0x1f) << 5; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 0x1f); \ + *(uint16_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 2; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_RGBX_8888: \ + _pp_pixel = 0xff; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 0xff) << 24; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 16; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 0xff) << 8; \ + *(uint32_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 4; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_XRGB_8888: \ + _pp_pixel = 0xff000000; \ + _pp_pixel |= _al_fast_float_to_int(color.r * 0xff) << 16; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 0xff) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 0xff); \ + *(uint32_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 4; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_ABGR_F32: { \ + float *f = (float *)data; \ + f[0] = color.r; \ + f[1] = color.g; \ + f[2] = color.b; \ + f[3] = color.a; \ + if (advance) \ + data += 4 * sizeof(float); \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE: \ + *((uint8_t *)data + 0) = _al_fast_float_to_int(color.r * 0xff); \ + *((uint8_t *)data + 1) = _al_fast_float_to_int(color.g * 0xff); \ + *((uint8_t *)data + 2) = _al_fast_float_to_int(color.b * 0xff); \ + *((uint8_t *)data + 3) = _al_fast_float_to_int(color.a * 0xff); \ + if (advance) \ + data += 4; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_RGBA_4444: \ + _pp_pixel = _al_fast_float_to_int(color.a * 15); \ + _pp_pixel |= _al_fast_float_to_int(color.r * 15) << 12; \ + _pp_pixel |= _al_fast_float_to_int(color.g * 15) << 8; \ + _pp_pixel |= _al_fast_float_to_int(color.b * 15) << 4; \ + *(uint16_t *)(data) = _pp_pixel; \ + if (advance) \ + data += 2; \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8: { \ + uint8_t c = color.r; \ + *(uint8_t *)data = c; \ + if (advance) \ + data += 3; \ + break; \ + } \ + \ + case ALLEGRO_PIXEL_FORMAT_ANY: \ + case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: \ + case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: \ + ALLEGRO_ERROR("INLINE_PUT got fake _pp_pixel format: %d\n", format); \ + abort(); \ + break; \ + \ + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1: \ + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3: \ + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5: \ + ALLEGRO_ERROR("INLINE_PUT got compressed format: %d\n", format); \ + abort(); \ + break; \ + \ + case ALLEGRO_NUM_PIXEL_FORMATS: \ + ALLEGRO_ERROR("INLINE_PUT got non _pp_pixel format: %d\n", format); \ + abort(); \ + break; \ + } \ + } while (0) + +AL_ARRAY(int, _al_rgb_scale_1); +AL_ARRAY(int, _al_rgb_scale_4); +AL_ARRAY(int, _al_rgb_scale_5); +AL_ARRAY(int, _al_rgb_scale_6); +AL_ARRAY(float, _al_u8_to_float); + +AL_FUNC(bool, _al_pixel_format_has_alpha, (int format)); +AL_FUNC(bool, _al_pixel_format_is_real, (int format)); +AL_FUNC(bool, _al_pixel_format_is_video_only, (int format)); +AL_FUNC(bool, _al_pixel_format_is_compressed, (int format)); +AL_FUNC(int, _al_get_real_pixel_format, (ALLEGRO_DISPLAY *display, int format)); +AL_FUNC(char const*, _al_pixel_format_name, (ALLEGRO_PIXEL_FORMAT format)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_raspberrypi.h b/allegro/include/allegro5/internal/aintern_raspberrypi.h new file mode 100644 index 00000000..defd81e2 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_raspberrypi.h @@ -0,0 +1,53 @@ +#ifndef _ALLEGRO_INTERNAL_RASPBERRYPI_SYSTEM +#define _ALLEGRO_INTERNAL_RASPBERRYPI_SYSTEM + +#include "allegro5/allegro.h" +#include +#include +#include + +#include + +typedef struct ALLEGRO_SYSTEM_RASPBERRYPI { + ALLEGRO_SYSTEM system; + Display *x11display; + _AL_MUTEX lock; /* thread lock for whenever we access internals. */ + _AL_THREAD thread; /* background thread. */ + ALLEGRO_DISPLAY *mouse_grab_display; /* Best effort: may be inaccurate. */ + bool inhibit_screensaver; /* Should we inhibit the screensaver? */ + Atom AllegroAtom; +} ALLEGRO_SYSTEM_RASPBERRYPI; + +typedef struct ALLEGRO_DISPLAY_RASPBERRYPI_EXTRA + ALLEGRO_DISPLAY_RASPBERRYPI_EXTRA; + +typedef struct ALLEGRO_DISPLAY_RASPBERRYPI { + ALLEGRO_DISPLAY display; + ALLEGRO_DISPLAY_RASPBERRYPI_EXTRA *extra; + Window window; + /* Physical size of display in pixels (gets scaled) */ + int screen_width, screen_height; + /* Cursor stuff */ + bool mouse_warp; + uint32_t *cursor_data; + int cursor_width; + int cursor_height; + int cursor_offset_x, cursor_offset_y; + Atom wm_delete_window_atom; +} ALLEGRO_DISPLAY_RASPBERRYPI; + +typedef struct ALLEGRO_MOUSE_CURSOR_RASPBERRYPI { + ALLEGRO_BITMAP *bitmap; +} ALLEGRO_MOUSE_CURSOR_RASPBERRYPI; + +ALLEGRO_SYSTEM_INTERFACE *_al_system_raspberrypi_driver(void); +ALLEGRO_DISPLAY_INTERFACE *_al_get_raspberrypi_display_interface(void); +void _al_raspberrypi_get_screen_info(int *dx, int *dy, + int *screen_width, int *screen_height); + +bool _al_evdev_set_mouse_range(int x1, int y1, int x2, int y2); // used by console mouse driver +void _al_raspberrypi_get_mouse_scale_ratios(float *x, float *y); // used by X mouse driver + +ALLEGRO_MOUSE_DRIVER _al_mousedrv_linux_evdev; + +#endif diff --git a/allegro/include/allegro5/internal/aintern_shader.h b/allegro/include/allegro5/internal/aintern_shader.h new file mode 100644 index 00000000..b3648fd0 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_shader.h @@ -0,0 +1,73 @@ +#ifndef __al_included_allegro5_internal_aintern_shader_h +#define __al_included_allegro5_internal_aintern_shader_h + +#include "allegro5/internal/aintern_list.h" +#include "allegro5/internal/aintern_vector.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ALLEGRO_SHADER_INTERFACE ALLEGRO_SHADER_INTERFACE; + +struct ALLEGRO_SHADER_INTERFACE +{ + bool (*attach_shader_source)(ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *source); + bool (*build_shader)(ALLEGRO_SHADER *shader); + bool (*use_shader)(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *dpy, + bool set_projview_matrix_from_display); + void (*unuse_shader)(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *dpy); + void (*destroy_shader)(ALLEGRO_SHADER *shader); + void (*on_lost_device)(ALLEGRO_SHADER *shader); + void (*on_reset_device)(ALLEGRO_SHADER *shader); + + bool (*set_shader_sampler)(ALLEGRO_SHADER *shader, const char *name, + ALLEGRO_BITMAP *bitmap, int unit); + bool (*set_shader_matrix)(ALLEGRO_SHADER *shader, const char *name, + const ALLEGRO_TRANSFORM *matrix); + bool (*set_shader_int)(ALLEGRO_SHADER *shader, const char *name, int i); + bool (*set_shader_float)(ALLEGRO_SHADER *shader, const char *name, float f); + bool (*set_shader_int_vector)(ALLEGRO_SHADER *shader, const char *name, + int elem_size, const int *i, int num_elems); + bool (*set_shader_float_vector)(ALLEGRO_SHADER *shader, const char *name, + int elem_size, const float *f, int num_elems); + bool (*set_shader_bool)(ALLEGRO_SHADER *shader, const char *name, bool b); +}; + +struct ALLEGRO_SHADER +{ + ALLEGRO_USTR *vertex_copy; + ALLEGRO_USTR *pixel_copy; + ALLEGRO_USTR *log; + ALLEGRO_SHADER_PLATFORM platform; + ALLEGRO_SHADER_INTERFACE *vt; + _AL_VECTOR bitmaps; /* of ALLEGRO_BITMAP pointers */ + _AL_LIST_ITEM *dtor_item; +}; + +/* In most cases you should use _al_set_bitmap_shader_field. */ +void _al_set_bitmap_shader_field(ALLEGRO_BITMAP *bmp, ALLEGRO_SHADER *shader); +void _al_register_shader_bitmap(ALLEGRO_SHADER *shader, ALLEGRO_BITMAP *bmp); +void _al_unregister_shader_bitmap(ALLEGRO_SHADER *shader, ALLEGRO_BITMAP *bmp); + +ALLEGRO_SHADER *_al_create_default_shader(int display_flags); + +#ifdef ALLEGRO_CFG_SHADER_GLSL +ALLEGRO_SHADER *_al_create_shader_glsl(ALLEGRO_SHADER_PLATFORM platform); +void _al_set_shader_glsl(ALLEGRO_DISPLAY *display, ALLEGRO_SHADER *shader); +#endif + +#ifdef ALLEGRO_CFG_SHADER_HLSL +ALLEGRO_SHADER *_al_create_shader_hlsl(ALLEGRO_SHADER_PLATFORM platform); +void _al_set_shader_hlsl(ALLEGRO_DISPLAY *display, ALLEGRO_SHADER *shader); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_system.h b/allegro/include/allegro5/internal/aintern_system.h new file mode 100644 index 00000000..01d6a36f --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_system.h @@ -0,0 +1,80 @@ +#ifndef __al_included_allegro5_aintern_system_h +#define __al_included_allegro5_aintern_system_h + +#include "allegro5/system.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_haptic.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/internal/aintern_touch_input.h" +#include "allegro5/internal/aintern_vector.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ALLEGRO_SYSTEM_INTERFACE ALLEGRO_SYSTEM_INTERFACE; + +struct ALLEGRO_SYSTEM_INTERFACE +{ + ALLEGRO_SYSTEM_ID id; + ALLEGRO_SYSTEM *(*initialize)(int flags); + ALLEGRO_DISPLAY_INTERFACE *(*get_display_driver)(void); + ALLEGRO_KEYBOARD_DRIVER *(*get_keyboard_driver)(void); + ALLEGRO_MOUSE_DRIVER *(*get_mouse_driver)(void); + ALLEGRO_TOUCH_INPUT_DRIVER *(*get_touch_input_driver)(void); + ALLEGRO_JOYSTICK_DRIVER *(*get_joystick_driver)(void); + ALLEGRO_HAPTIC_DRIVER *(*get_haptic_driver)(void); + int (*get_num_display_modes)(void); + ALLEGRO_DISPLAY_MODE *(*get_display_mode)(int index, ALLEGRO_DISPLAY_MODE *mode); + void (*shutdown_system)(void); + int (*get_num_video_adapters)(void); + bool (*get_monitor_info)(int adapter, ALLEGRO_MONITOR_INFO *info); + int (*get_monitor_refresh_rate)(int adapter); + int (*get_monitor_dpi)(int adapter); + ALLEGRO_MOUSE_CURSOR *(*create_mouse_cursor)(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus); + void (*destroy_mouse_cursor)(ALLEGRO_MOUSE_CURSOR *cursor); + bool (*get_cursor_position)(int *ret_x, int *ret_y); + bool (*grab_mouse)(ALLEGRO_DISPLAY *display); + bool (*ungrab_mouse)(void); + ALLEGRO_PATH *(*get_path)(int id); + bool (*inhibit_screensaver)(bool inhibit); + void (*thread_init)(ALLEGRO_THREAD *thread); + void (*thread_exit)(ALLEGRO_THREAD *thread); + void *(*open_library)(const char *filename); + void *(*import_symbol)(void *library, const char *symbol); + void (*close_library)(void *handle); + void (*heartbeat)(void); + void (*heartbeat_init)(void); + double (*get_time)(void); + void (*rest)(double seconds); + void (*init_timeout)(ALLEGRO_TIMEOUT *timeout, double seconds); +}; + +struct ALLEGRO_SYSTEM +{ + ALLEGRO_SYSTEM_INTERFACE *vt; + _AL_VECTOR displays; /* Keep a list of all displays attached to us. */ + ALLEGRO_PATH *user_exe_path; + int mouse_wheel_precision; + int min_bitmap_size; + bool installed; +}; + + +void _al_register_system_interfaces(void); +extern _AL_VECTOR _al_system_interfaces; +AL_VAR(_AL_DTOR_LIST *, _al_dtor_list); + +AL_FUNC(void *, _al_open_library, (const char *filename)); +AL_FUNC(void *, _al_import_symbol, (void *library, const char *symbol)); +AL_FUNC(void, _al_close_library, (void *library)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_thread.h b/allegro/include/allegro5/internal/aintern_thread.h new file mode 100644 index 00000000..b27ad49f --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_thread.h @@ -0,0 +1,51 @@ +#ifndef __al_included_allegro5_aintern_thread_h +#define __al_included_allegro5_aintern_thread_h + +#include ALLEGRO_INTERNAL_THREAD_HEADER + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct _AL_THREAD _AL_THREAD; +typedef struct _AL_MUTEX _AL_MUTEX; +typedef struct _AL_COND _AL_COND; + + +void _al_thread_create(_AL_THREAD*, void (*proc)(_AL_THREAD*, void*), void *arg); +void _al_thread_create_with_stacksize(_AL_THREAD*, void (*proc)(_AL_THREAD*, void*), void *arg, size_t stacksize); +void _al_thread_set_should_stop(_AL_THREAD *); +/* static inline bool _al_get_thread_should_stop(_AL_THREAD *); */ +void _al_thread_join(_AL_THREAD*); +void _al_thread_detach(_AL_THREAD*); + + +void _al_mutex_init(_AL_MUTEX*); +void _al_mutex_init_recursive(_AL_MUTEX*); +void _al_mutex_destroy(_AL_MUTEX*); +/* static inline void _al_mutex_lock(_AL_MUTEX*); */ +/* static inline void _al_mutex_unlock(_AL_MUTEX*); */ + +/* All 5 functions below are declared inline in aintuthr.h. + * FIXME: Why are they all inline? And if they have to be, why not treat them + * the same as the two functions above? + */ +#ifdef ALLEGRO_WINDOWS +void _al_cond_init(_AL_COND*); +void _al_cond_destroy(_AL_COND*); +void _al_cond_wait(_AL_COND*, _AL_MUTEX*); +void _al_cond_broadcast(_AL_COND*); +void _al_cond_signal(_AL_COND*); +#endif + +int _al_cond_timedwait(_AL_COND*, _AL_MUTEX*, const ALLEGRO_TIMEOUT *timeout); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_timer.h b/allegro/include/allegro5/internal/aintern_timer.h new file mode 100644 index 00000000..b59a8db2 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_timer.h @@ -0,0 +1,18 @@ +#ifndef __al_included_allegro5_aintern_timer_h +#define __al_included_allegro5_aintern_timer_h + +#ifdef __cplusplus + extern "C" { +#endif + +void _al_init_timers(void); +int _al_get_active_timers_count(void); +double _al_timer_thread_handle_tick(double interval); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_tls.h b/allegro/include/allegro5/internal/aintern_tls.h new file mode 100644 index 00000000..a09bb5e1 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_tls.h @@ -0,0 +1,21 @@ +#ifndef __al_included_allegro5_aintern_tls_h +#define __al_included_allegro5_aintern_tls_h + +#ifdef __cplusplus + extern "C" { +#endif + + +void _al_tls_init_once(void); +void _al_reinitialize_tls_values(void); + +int *_al_tls_get_dtor_owner_count(void); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_touch_input.h b/allegro/include/allegro5/internal/aintern_touch_input.h new file mode 100644 index 00000000..90d084a9 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_touch_input.h @@ -0,0 +1,37 @@ +#ifndef __al_included_allegro5_aintern_touch_input_h +#define __al_included_allegro5_aintern_touch_input_h + +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_events.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct ALLEGRO_TOUCH_INPUT_DRIVER +{ + int id; + AL_METHOD(bool, init_touch_input, (void)); + AL_METHOD(void, exit_touch_input, (void)); + AL_METHOD(ALLEGRO_TOUCH_INPUT*, get_touch_input, (void)); + AL_METHOD(void, get_touch_input_state, (ALLEGRO_TOUCH_INPUT_STATE *ret_state)); + AL_METHOD(void, set_mouse_emulation_mode, (int mode)); + AL_METHOD(int, get_mouse_emulation_mode, (void)); +} ALLEGRO_TOUCH_INPUT_DRIVER; + + +struct ALLEGRO_TOUCH_INPUT +{ + ALLEGRO_EVENT_SOURCE es; + ALLEGRO_EVENT_SOURCE mouse_emulation_es; + int mouse_emulation_mode; +}; + +extern _AL_DRIVER_INFO _al_touch_input_driver_list[]; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/internal/aintern_transform.h b/allegro/include/allegro5/internal/aintern_transform.h new file mode 100644 index 00000000..022c263a --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_transform.h @@ -0,0 +1,9 @@ +#ifndef __al_included_allegro5_aintern_transform_h +#define __al_included_allegro5_aintern_transform_h + + +bool _al_transform_is_translation(const ALLEGRO_TRANSFORM* trans, + float *dx, float *dy); + + +#endif diff --git a/allegro/include/allegro5/internal/aintern_tri_soft.h b/allegro/include/allegro5/internal/aintern_tri_soft.h new file mode 100644 index 00000000..eef14fe7 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_tri_soft.h @@ -0,0 +1,27 @@ +#ifndef __al_included_allegro5_aintern_tri_soft_h +#define __al_included_allegro5_aintern_tri_soft_h + +struct ALLEGRO_BITMAP; + +/* Duplicated in allegro_primitives.h */ +#ifndef _ALLEGRO_VERTEX_DEFINED +#define _ALLEGRO_VERTEX_DEFINED + +typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX; + +struct ALLEGRO_VERTEX { + float x, y, z; + float u, v; + ALLEGRO_COLOR color; +}; +#endif + +AL_FUNC(void, _al_triangle_2d, (ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3)); +AL_FUNC(void, _al_draw_soft_triangle, ( + ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, + void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*first)(uintptr_t, int, int, int, int), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int, int))); + +#endif diff --git a/allegro/include/allegro5/internal/aintern_vector.h b/allegro/include/allegro5/internal/aintern_vector.h new file mode 100644 index 00000000..341c98d1 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_vector.h @@ -0,0 +1,55 @@ +#ifndef __al_included_allegro5_aintern_vector_h +#define __al_included_allegro5_aintern_vector_h + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct _AL_VECTOR +{ + /* private */ + size_t _itemsize; + char* _items; /* total size == (size + unused) * itemsize */ + size_t _size; + size_t _unused; +} _AL_VECTOR; + +#define _AL_VECTOR_INITIALIZER(typ) { sizeof(typ), 0, 0, 0 } + + +AL_FUNC(void, _al_vector_init, (_AL_VECTOR*, size_t itemsize)); +AL_INLINE(size_t, _al_vector_size, (const _AL_VECTOR *vec), +{ + return vec->_size; +}) +AL_INLINE(bool, _al_vector_is_empty, (const _AL_VECTOR *vec), +{ + ASSERT(vec); + return vec->_size == 0 ? true : false; +}) +AL_INLINE(bool, _al_vector_is_nonempty, (const _AL_VECTOR *vec), +{ + ASSERT(vec); + return !_al_vector_is_empty(vec); +}) +AL_FUNC(void*, _al_vector_ref, (const _AL_VECTOR*, unsigned int index)); +AL_FUNC(void*, _al_vector_ref_front, (const _AL_VECTOR*)); +AL_FUNC(void*, _al_vector_ref_back, (const _AL_VECTOR*)); +AL_FUNC(bool, _al_vector_append_array, (_AL_VECTOR *vec, unsigned int num, const void *arr)); +AL_FUNC(void*, _al_vector_alloc_back, (_AL_VECTOR*)); +AL_FUNC(void*, _al_vector_alloc_mid, (_AL_VECTOR*, unsigned int index)); +AL_FUNC(int, _al_vector_find, (const _AL_VECTOR*, const void *ptr_item)); +AL_FUNC(bool, _al_vector_contains, (const _AL_VECTOR*, const void *ptr_item)); +AL_FUNC(void, _al_vector_delete_at, (_AL_VECTOR*, unsigned int index)); +AL_FUNC(bool, _al_vector_find_and_delete, (_AL_VECTOR*, const void *ptr_item)); +AL_FUNC(void, _al_vector_free, (_AL_VECTOR*)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vi ts=8 sts=3 sw=3 et */ diff --git a/allegro/include/allegro5/internal/aintern_wclipboard.h b/allegro/include/allegro5/internal/aintern_wclipboard.h new file mode 100644 index 00000000..03895f73 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_wclipboard.h @@ -0,0 +1,21 @@ +#ifndef __al_included_allegro5_aintern_wclipboard_h +#define __al_included_allegro5_aintern_wclipboard_h + + +#include "allegro5/internal/aintern_display.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void _al_win_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt); + +#ifdef __cplusplus +} +#endif + + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_wjoyall.h b/allegro/include/allegro5/internal/aintern_wjoyall.h new file mode 100644 index 00000000..67d7151b --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_wjoyall.h @@ -0,0 +1,18 @@ +#ifndef __al_included_allegro_aintern_wjoydxnu_h +#define __al_included_allegro_aintern_wjoydxnu_h + + +/** Part of the Windows joystick wrapper driver + * types are shared here for use by the haptic susbystem. */ + +typedef struct ALLEGRO_JOYSTICK_WINDOWS_ALL { + ALLEGRO_JOYSTICK parent; /* must be first */ + bool active; + int index; + ALLEGRO_JOYSTICK * handle; + ALLEGRO_JOYSTICK_DRIVER * driver; +} ALLEGRO_JOYSTICK_WINDOWS_ALL; + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_wjoydxnu.h b/allegro/include/allegro5/internal/aintern_wjoydxnu.h new file mode 100644 index 00000000..eeb31e4c --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_wjoydxnu.h @@ -0,0 +1,100 @@ +#ifndef __al_included_allegro_aintern_wjoydxnu_h +#define __al_included_allegro_aintern_wjoydxnu_h + + +/** Part of the Windows DirectInput joystick + * types are shared here for use by the haptic susbystem. */ + +/* arbitrary limit */ +#define MAX_JOYSTICKS 32 + +/* these limits are from DIJOYSTICK_STATE in dinput.h */ +#define MAX_SLIDERS 2 +#define MAX_POVS 4 +#define MAX_BUTTONS 32 + +/* the number of joystick events that DirectInput is told to buffer */ +#define DEVICE_BUFFER_SIZE 128 + +/* make sure all the constants add up */ +/* the first two sticks are (x,y,z) and (rx,ry,rz) */ +ALLEGRO_STATIC_ASSERT(wjoydxnu, _AL_MAX_JOYSTICK_STICKS >= (2 + MAX_SLIDERS + MAX_POVS)); +ALLEGRO_STATIC_ASSERT(wjoydxnu, _AL_MAX_JOYSTICK_BUTTONS >= MAX_BUTTONS); + + +#define GUID_EQUAL(a, b) (0 == memcmp(&(a), &(b), sizeof(GUID))) + + +typedef enum +{ + STATE_UNUSED, + STATE_BORN, + STATE_ALIVE, + STATE_DYING +} CONFIG_STATE; + +#define ACTIVE_STATE(st) \ + ((st) == STATE_ALIVE || (st) == STATE_DYING) + + +/* helper structure to record information through object_enum_callback */ +#define NAME_LEN 128 + +typedef struct +{ + bool have_x; TCHAR name_x[NAME_LEN]; + bool have_y; TCHAR name_y[NAME_LEN]; + bool have_z; TCHAR name_z[NAME_LEN]; + bool have_rx; TCHAR name_rx[NAME_LEN]; + bool have_ry; TCHAR name_ry[NAME_LEN]; + bool have_rz; TCHAR name_rz[NAME_LEN]; + int num_sliders; TCHAR name_slider[MAX_SLIDERS][NAME_LEN]; + int num_povs; TCHAR name_pov[MAX_POVS][NAME_LEN]; + int num_buttons; TCHAR name_button[MAX_BUTTONS][NAME_LEN]; +} CAPS_AND_NAMES; + + +/* map a DirectInput axis to an Allegro (stick,axis) pair */ +typedef struct +{ + int stick, axis; +} AXIS_MAPPING; + + +typedef struct ALLEGRO_JOYSTICK_DIRECTX +{ + ALLEGRO_JOYSTICK parent; /* must be first */ + CONFIG_STATE config_state; + bool marked; + LPDIRECTINPUTDEVICE2 device; + GUID guid; + GUID product_guid; + HANDLE waker_event; + + ALLEGRO_JOYSTICK_STATE joystate; + AXIS_MAPPING x_mapping; + AXIS_MAPPING y_mapping; + AXIS_MAPPING z_mapping; + AXIS_MAPPING rx_mapping; + AXIS_MAPPING ry_mapping; + AXIS_MAPPING rz_mapping; + AXIS_MAPPING slider_mapping[MAX_SLIDERS]; + int pov_mapping_stick[MAX_POVS]; + char name[80]; + char all_names[512]; /* button/stick/axis names with NUL terminators */ +} ALLEGRO_JOYSTICK_DIRECTX; + + + +#ifdef __cplusplus +extern "C" { +#endif + void _al_win_joystick_dinput_trigger_enumeration(void); +#ifdef __cplusplus +} +#endif + + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_wjoyxi.h b/allegro/include/allegro5/internal/aintern_wjoyxi.h new file mode 100644 index 00000000..51f588d8 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_wjoyxi.h @@ -0,0 +1,49 @@ +#ifndef __al_included_allegro_aintern_wjoydxnu_h +#define __al_included_allegro_aintern_wjoydxnu_h + + +/** Part of the Windows XInput joystick + * types are shared here for use by the haptic susbystem. */ + +/* XInput supports only up to 4 joysticks.*/ +#define MAX_JOYSTICKS 4 + +/* XInput joystics always have up to 14 buttons, + 2 triggers which are mapped to sliders, and 2 pairs of 2 axes. */ + +#define MAX_BUTTONS 14 +#define MAX_TRIGGERS 2 +#define MAX_AXES 2 +#define MAX_STICKS 4 + +/* make sure all the constants add up */ +/* the first two sticks are (x,y,z) and (rx,ry,rz) */ +ALLEGRO_STATIC_ASSERT(wjoydxnu, _AL_MAX_JOYSTICK_STICKS >= (2 + MAX_TRIGGERS + MAX_STICKS)); +ALLEGRO_STATIC_ASSERT(wjoydxnu, _AL_MAX_JOYSTICK_BUTTONS >= MAX_BUTTONS); + +typedef enum +{ + STATE_UNUSED, + STATE_ACTIVE, +} CONFIG_STATE; + +#define ACTIVE_STATE(st) \ + ((st) == STATE_ACTIVE) + + +typedef struct ALLEGRO_JOYSTICK_XINPUT +{ + ALLEGRO_JOYSTICK parent; /* must be first */ + bool active; + ALLEGRO_JOYSTICK_STATE joystate; + DWORD index; + XINPUT_STATE state; + XINPUT_CAPABILITIES capabilities; + XINPUT_VIBRATION vibration; + char name[80]; + char all_names[512]; /* button/stick/axis names with NUL terminators */ +} ALLEGRO_JOYSTICK_XINPUT; + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_wunicode.h b/allegro/include/allegro5/internal/aintern_wunicode.h new file mode 100644 index 00000000..d29987d8 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_wunicode.h @@ -0,0 +1,49 @@ +#ifndef __al_included_allegro5_aintern_wunicode_h +#define __al_included_allegro5_aintern_wunicode_h + +#ifdef ALLEGRO_WINDOWS + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +AL_FUNC(wchar_t *, _al_win_ustr_to_utf16, (const ALLEGRO_USTR *u)); +AL_FUNC(char *, _al_win_ustr_to_ansi, (const ALLEGRO_USTR *u)); +AL_FUNC(wchar_t *, _al_win_utf8_to_utf16, (const char *us)); +AL_FUNC(char *, _al_win_utf16_to_utf8, (const wchar_t *ws)); +AL_FUNC(char *, _al_win_utf8_to_ansi, (const char* us)); +AL_FUNC(char *, _al_win_ansi_to_utf8, (const char *s)); +AL_FUNC(char *, _al_win_copy_utf16_to_utf8, (char* us, const wchar_t* ws, size_t uslen)); +// wslen is number of wide characters, not bytes. +AL_FUNC(char *, _al_win_copy_utf8_to_utf16, (wchar_t* ws, const char *us, size_t wslen)); +AL_FUNC(char *, _al_win_copy_ansi_to_utf8, (char* us, const char *s, size_t uslen)); +AL_FUNC(char *, _al_win_copy_utf8_to_ansi, (char* s, const char *us, size_t slen)); + +#ifdef UNICODE +#define _twin_tchar_strlen wcslen +#define _twin_ustr_to_tchar _al_win_ustr_to_utf16 +#define _twin_utf8_to_tchar _al_win_utf8_to_utf16 +#define _twin_tchar_to_utf8 _al_win_utf16_to_utf8 +#define _twin_copy_tchar_to_utf8 _al_win_copy_utf16_to_utf8 +#define _twin_copy_utf8_to_tchar _al_win_copy_utf8_to_utf16 +#else +#define _twin_tchar_strlen strlen +#define _twin_ustr_to_tchar _al_win_ustr_to_ansi +#define _twin_utf8_to_tchar _al_win_utf8_to_ansi +#define _twin_tchar_to_utf8 _al_win_ansi_to_utf8 +#define _twin_copy_tchar_to_utf8 _al_win_copy_ansi_to_utf8 +#define _twin_copy_utf8_to_tchar _al_win_copy_utf8_to_ansi +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_x.h b/allegro/include/allegro5/internal/aintern_x.h new file mode 100644 index 00000000..f405a890 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_x.h @@ -0,0 +1,9 @@ +#ifndef __al_included_allegro5_aintern_x_h +#define __al_included_allegro5_aintern_x_h + +#include + +typedef struct ALLEGRO_SYSTEM_XGLX ALLEGRO_SYSTEM_XGLX; +typedef struct ALLEGRO_DISPLAY_XGLX ALLEGRO_DISPLAY_XGLX; + +#endif diff --git a/allegro/include/allegro5/internal/aintern_xclipboard.h b/allegro/include/allegro5/internal/aintern_xclipboard.h new file mode 100644 index 00000000..ff065edd --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xclipboard.h @@ -0,0 +1,13 @@ +#ifndef __al_included_allegro5_aintern_xclipboard_h +#define __al_included_allegro5_aintern_xclipboard_h + + +#include "allegro5/internal/aintern_display.h" + +void _al_xwin_display_selection_notify(ALLEGRO_DISPLAY *display, XSelectionEvent *xselection); +void _al_xwin_display_selection_request(ALLEGRO_DISPLAY *display, XSelectionRequestEvent *xselectionrequest); +void _al_xwin_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_xcursor.h b/allegro/include/allegro5/internal/aintern_xcursor.h new file mode 100644 index 00000000..5e2f4db3 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xcursor.h @@ -0,0 +1,24 @@ +#ifndef __al_included_allegro5_aintern_xcursor_h +#define __al_included_allegro5_aintern_xcursor_h + +#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR +#include +#endif + +#include "allegro5/internal/aintern_display.h" + +typedef struct ALLEGRO_MOUSE_CURSOR_XWIN ALLEGRO_MOUSE_CURSOR_XWIN; + +struct ALLEGRO_MOUSE_CURSOR_XWIN +{ + Cursor cursor; +}; + +ALLEGRO_MOUSE_CURSOR *_al_xwin_create_mouse_cursor(ALLEGRO_BITMAP *bmp, + int x_focus, int y_focus); +void _al_xwin_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor); +void _al_xwin_add_cursor_functions(ALLEGRO_DISPLAY_INTERFACE *vt); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_xdisplay.h b/allegro/include/allegro5/internal/aintern_xdisplay.h new file mode 100644 index 00000000..bd142ca7 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xdisplay.h @@ -0,0 +1,103 @@ +#ifndef __al_included_allegro5_aintern_xdisplay_h +#define __al_included_allegro5_aintern_xdisplay_h + +/* XXX The Raspberry Pi port does not use GLX. It currently substitutes its own + * ALLEGRO_DISPLAY_RASPBERRYPI for ALLEGRO_DISPLAY_XGLX by a macro renaming + * hack. + */ +#ifndef ALLEGRO_RASPBERRYPI + +#include + +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_x.h" + +typedef struct ALLEGRO_DISPLAY_XGLX_GTK ALLEGRO_DISPLAY_XGLX_GTK; +typedef struct ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE; + +/* This is our version of ALLEGRO_DISPLAY with driver specific extra data. */ +struct ALLEGRO_DISPLAY_XGLX +{ + /* This must be the first member. */ + ALLEGRO_DISPLAY display; + + /* Driver specifics. */ + + const struct ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE *overridable_vt; + + Window window; + int xscreen; /* X Screen ID */ + int adapter; /* allegro virtual adapter id/index */ + GLXWindow glxwindow; + GLXContext context; + Atom wm_delete_window_atom; + XVisualInfo *xvinfo; /* Used when selecting the X11 visual to use. */ + GLXFBConfig *fbc; /* Used when creating the OpenGL context. */ + int glx_version; /* 130 means 1 major and 3 minor, aka 1.3 */ + + /* Points to a structure if this display is contained by a GTK top-level + * window, otherwise it is NULL. + */ + ALLEGRO_DISPLAY_XGLX_GTK *gtk; + + /* If our window is embedded by the XEmbed protocol, this gives + * the window ID of the embedder; Otherwise None. + */ + Window embedder_window; + + _AL_COND mapped; /* Condition variable to wait for mapping a window. */ + bool is_mapped; /* Set to true when mapped. */ + + int resize_count; /* Increments when resized. */ + bool programmatic_resize; /* Set while programmatic resize in progress. */ + + /* Cursor for this window. */ + Cursor invisible_cursor; + Cursor current_cursor; + bool cursor_hidden; + + /* Icon for this window. */ + Pixmap icon, icon_mask; + + /* Desktop position. */ + int x, y; + + /* al_set_mouse_xy implementation */ + bool mouse_warp; + + _AL_COND selectioned; /* Condition variable to wait for a selection event a window. */ + bool is_selectioned; /* Set to true when selection event received. */ + +}; + +void _al_display_xglx_await_resize(ALLEGRO_DISPLAY *d, int old_resize_count, bool delay_hack); +void _al_xglx_display_configure(ALLEGRO_DISPLAY *d, int x, int y, int width, int height, bool setglxy); +void _al_xglx_display_configure_event(ALLEGRO_DISPLAY *d, XEvent *event); +void _al_xwin_display_switch_handler(ALLEGRO_DISPLAY *d, + XFocusChangeEvent *event); +void _al_xwin_display_switch_handler_inner(ALLEGRO_DISPLAY *d, bool focus_in); +void _al_xwin_display_expose(ALLEGRO_DISPLAY *display, XExposeEvent *xevent); + + +/* An ad-hoc interface to allow the GTK backend to override some of the + * normal X display interface implementation. + */ +struct ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE +{ + bool (*create_display_hook)(ALLEGRO_DISPLAY *d, int w, int h); + void (*destroy_display_hook)(ALLEGRO_DISPLAY *d, bool is_last); + bool (*resize_display)(ALLEGRO_DISPLAY *d, int w, int h); + void (*set_window_title)(ALLEGRO_DISPLAY *display, const char *title); + void (*set_fullscreen_window)(ALLEGRO_DISPLAY *display, bool onoff); + void (*set_window_position)(ALLEGRO_DISPLAY *display, int x, int y); + bool (*set_window_constraints)(ALLEGRO_DISPLAY *display, int min_w, int min_h, int max_w, int max_h); +}; + +bool _al_xwin_set_gtk_display_overridable_interface(uint32_t check_version, + const ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE *vt); + +#endif /* !ALLEGRO_RASPBERRYPI */ + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_xembed.h b/allegro/include/allegro5/internal/aintern_xembed.h new file mode 100644 index 00000000..28c4c53f --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xembed.h @@ -0,0 +1,33 @@ +#ifndef __al_included_allegro5_aintern_xembed_h +#define __al_included_allegro5_aintern_xembed_h + +/* From XEmbed Protocol Specification version 0.5 */ +/* http://standards.freedesktop.org/xembed-spec/latest/index.html */ + +/* Flags for _XEMBED_INFO */ +#define XEMBED_MAPPED (1 << 0) + +/* XEMBED messages */ +#define XEMBED_EMBEDDED_NOTIFY 0 +#define XEMBED_WINDOW_ACTIVATE 1 +#define XEMBED_WINDOW_DEACTIVATE 2 +#define XEMBED_REQUEST_FOCUS 3 +#define XEMBED_FOCUS_IN 4 +#define XEMBED_FOCUS_OUT 5 +#define XEMBED_FOCUS_NEXT 6 +#define XEMBED_FOCUS_PREV 7 +/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */ +#define XEMBED_MODALITY_ON 10 +#define XEMBED_MODALITY_OFF 11 +#define XEMBED_REGISTER_ACCELERATOR 12 +#define XEMBED_UNREGISTER_ACCELERATOR 13 +#define XEMBED_ACTIVATE_ACCELERATOR 14 + +/* Details for XEMBED_FOCUS_IN: */ +#define XEMBED_FOCUS_CURRENT 0 +#define XEMBED_FOCUS_FIRST 1 +#define XEMBED_FOCUS_LAST 2 + +#endif + +/* vim: set sts=4 sw=4 et: */ diff --git a/allegro/include/allegro5/internal/aintern_xevents.h b/allegro/include/allegro5/internal/aintern_xevents.h new file mode 100644 index 00000000..11c8d1f6 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xevents.h @@ -0,0 +1,10 @@ +#ifndef __al_included_allegro5_aintern_xevents_h +#define __al_included_allegro5_aintern_xevents_h + +#include "allegro5/internal/aintern_thread.h" + +void _al_xwin_background_thread(_AL_THREAD *self, void *arg); + +void _al_display_xglx_closebutton(ALLEGRO_DISPLAY *d, XEvent *xevent); + +#endif diff --git a/allegro/include/allegro5/internal/aintern_xfullscreen.h b/allegro/include/allegro5/internal/aintern_xfullscreen.h new file mode 100644 index 00000000..5f553d53 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xfullscreen.h @@ -0,0 +1,65 @@ +#ifndef __al_included_allegro5_aintern_xfullscreen_h +#define __al_included_allegro5_aintern_xfullscreen_h + +/* fullscreen and multi monitor stuff */ + +typedef struct _ALLEGRO_XGLX_MMON_INTERFACE _ALLEGRO_XGLX_MMON_INTERFACE; + +struct _ALLEGRO_XGLX_MMON_INTERFACE { + int (*get_num_display_modes)(ALLEGRO_SYSTEM_XGLX *s, int adapter); + ALLEGRO_DISPLAY_MODE *(*get_display_mode)(ALLEGRO_SYSTEM_XGLX *s, int, int, ALLEGRO_DISPLAY_MODE*); + bool (*set_mode)(ALLEGRO_SYSTEM_XGLX *, ALLEGRO_DISPLAY_XGLX *, int, int, int, int); + void (*store_mode)(ALLEGRO_SYSTEM_XGLX *); + void (*restore_mode)(ALLEGRO_SYSTEM_XGLX *, int); + void (*get_display_offset)(ALLEGRO_SYSTEM_XGLX *, int, int *, int *); + int (*get_num_adapters)(ALLEGRO_SYSTEM_XGLX *); + bool (*get_monitor_info)(ALLEGRO_SYSTEM_XGLX *, int, ALLEGRO_MONITOR_INFO *); + int (*get_default_adapter)(ALLEGRO_SYSTEM_XGLX *); + int (*get_adapter)(ALLEGRO_SYSTEM_XGLX *, ALLEGRO_DISPLAY_XGLX *); + int (*get_xscreen)(ALLEGRO_SYSTEM_XGLX *, int); + void (*post_setup)(ALLEGRO_SYSTEM_XGLX *, ALLEGRO_DISPLAY_XGLX *); + void (*handle_xevent)(ALLEGRO_SYSTEM_XGLX *, ALLEGRO_DISPLAY_XGLX *, XEvent *e); +}; + +extern _ALLEGRO_XGLX_MMON_INTERFACE _al_xglx_mmon_interface; + +int _al_xsys_mheadx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s); +int _al_xsys_mheadx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter); +void _al_xsys_get_active_window_center(ALLEGRO_SYSTEM_XGLX *s, int *x, int *y); + +void _al_xsys_mmon_exit(ALLEGRO_SYSTEM_XGLX *s); + +int _al_xglx_get_num_display_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter); +ALLEGRO_DISPLAY_MODE *_al_xglx_get_display_mode( + ALLEGRO_SYSTEM_XGLX *s, int adapter, int index, ALLEGRO_DISPLAY_MODE *mode); +bool _al_xglx_fullscreen_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w, int h, + int format, int refresh_rate); +void _al_xglx_store_video_mode(ALLEGRO_SYSTEM_XGLX *s); +void _al_xglx_restore_video_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter); +void _al_xglx_fullscreen_to_display(ALLEGRO_SYSTEM_XGLX *s, + ALLEGRO_DISPLAY_XGLX *d); +void _al_xglx_set_fullscreen_window(ALLEGRO_DISPLAY *display, int value); +void _al_xglx_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y); + +int _al_xglx_fullscreen_select_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int w, int h, int format, int refresh_rate); + +bool _al_xglx_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *info); +int _al_xglx_get_num_video_adapters(ALLEGRO_SYSTEM_XGLX *s); + +int _al_xglx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s); +int _al_xglx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter); + +void _al_xglx_set_above(ALLEGRO_DISPLAY *display, int value); + +int _al_xglx_get_adapter(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, bool recalc); + +void _al_xglx_handle_mmon_event(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, XEvent *e); + +#ifdef ALLEGRO_XWINDOWS_WITH_XRANDR +void _al_xsys_xrandr_init(ALLEGRO_SYSTEM_XGLX *s); +void _al_xsys_xrandr_exit(ALLEGRO_SYSTEM_XGLX *s); +#endif /* ALLEGRO_XWINDOWS_WITH_XRANDR */ + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_xglx_config.h b/allegro/include/allegro5/internal/aintern_xglx_config.h new file mode 100644 index 00000000..c23802c2 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xglx_config.h @@ -0,0 +1,9 @@ +#ifndef __al_included_allegro5_aintern_xglx_h +#define __al_included_allegro5_aintern_xglx_h + +#include "allegro5/internal/aintern_x.h" + +void _al_xglx_config_select_visual(ALLEGRO_DISPLAY_XGLX *glx); +bool _al_xglx_config_create_context(ALLEGRO_DISPLAY_XGLX *glx); + +#endif diff --git a/allegro/include/allegro5/internal/aintern_xkeyboard.h b/allegro/include/allegro5/internal/aintern_xkeyboard.h new file mode 100644 index 00000000..d02d4dfd --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xkeyboard.h @@ -0,0 +1,12 @@ +#ifndef __al_included_allegro5_aintern_xkeyboard_h +#define __al_included_allegro5_aintern_xkeyboard_h + +#include "allegro5/internal/aintern_keyboard.h" + +ALLEGRO_KEYBOARD_DRIVER *_al_xwin_keyboard_driver(void); +void _al_xwin_keyboard_handler(XKeyEvent *event, ALLEGRO_DISPLAY *display); +void _al_xwin_keyboard_switch_handler(ALLEGRO_DISPLAY *display, bool focus_in); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_xmouse.h b/allegro/include/allegro5/internal/aintern_xmouse.h new file mode 100644 index 00000000..842f7943 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xmouse.h @@ -0,0 +1,15 @@ +#ifndef __al_included_allegro5_aintern_xmouse_h +#define __al_included_allegro5_aintern_xmouse_h + +#include "allegro5/internal/aintern_mouse.h" + +ALLEGRO_MOUSE_DRIVER *_al_xwin_mouse_driver(void); +void _al_xwin_mouse_button_press_handler(int button, ALLEGRO_DISPLAY *display); +void _al_xwin_mouse_button_release_handler(int button, ALLEGRO_DISPLAY *d); +void _al_xwin_mouse_motion_notify_handler(int x, int y, ALLEGRO_DISPLAY *d); +void _al_xwin_mouse_switch_handler(ALLEGRO_DISPLAY *display, + const XCrossingEvent *event); +bool _al_xwin_grab_mouse(ALLEGRO_DISPLAY *display); +bool _al_xwin_ungrab_mouse(void); + +#endif diff --git a/allegro/include/allegro5/internal/aintern_xsystem.h b/allegro/include/allegro5/internal/aintern_xsystem.h new file mode 100644 index 00000000..ed3aed9a --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xsystem.h @@ -0,0 +1,97 @@ +#ifndef __al_included_allegro5_aintern_xsystem_h +#define __al_included_allegro5_aintern_xsystem_h + +#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE +#include +#endif + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA +#include +#endif + +#ifdef ALLEGRO_XWINDOWS_WITH_XRANDR +#include +#endif + +#ifdef ALLEGRO_XWINDOWS_WITH_XSCREENSAVER +#include +#endif + +#include "allegro5/internal/aintern_system.h" + +/* This is our version of ALLEGRO_SYSTEM with driver specific extra data. */ +struct ALLEGRO_SYSTEM_XGLX +{ + /* This must be the first member, we "derive" from it. */ + ALLEGRO_SYSTEM system; + + /* Driver specifics. */ + + /* X11 is not thread-safe. But we use a separate thread to handle X11 events. + * Plus, users may call OpenGL commands in the main thread, and we have no + * way to enforce locking for them. + * The only solution seems to be two X11 display connections. One to do our + * input handling, and one for OpenGL graphics. + * + * Note: these may be NULL if we are not connected to an X server, for + * headless command-line tools. We don't have a separate "null" system + * driver. + */ + /* The X11 display. You *MUST* only access this from one + * thread at a time, use the mutex lock below to ensure it. + */ + Display *x11display; + /* Another X11 display we use for graphics. You *MUST* + * only use this in the main thread. + */ + Display *gfxdisplay; + + Atom AllegroAtom; + Atom XEmbedAtom; + + /* Background thread to process X events. + * Not used if GTK main loop is used. + */ + bool have_xevents_thread; + _AL_THREAD xevents_thread; + _AL_MUTEX lock; /* thread lock for whenever we access internals. */ + // FIXME: One condition variable really would be enough. + _AL_COND resized; /* Condition variable to wait for resizing a window. */ + ALLEGRO_DISPLAY *mouse_grab_display; /* Best effort: may be inaccurate. */ + int toggle_mouse_grab_keycode; /* Disabled if zero */ + unsigned int toggle_mouse_grab_modifiers; + bool inhibit_screensaver; /* Should we inhibit the screensaver? */ + bool screen_saver_query_available; + + bool mmon_interface_inited; +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + int xinerama_available; + int xinerama_screen_count; + XineramaScreenInfo *xinerama_screen_info; +#endif +#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE + /* For VidMode extension. */ + int xfvm_available; + int xfvm_screen_count; + struct { + int mode_count; + XF86VidModeModeInfo **modes; + XF86VidModeModeInfo *original_mode; + } *xfvm_screen; +#endif +#ifdef ALLEGRO_XWINDOWS_WITH_XRANDR + int xrandr_available; + int xrandr_event_base; + _AL_VECTOR xrandr_screens; + _AL_VECTOR xrandr_adaptermap; +#endif + + /* Used to keep track of how many adapters are in use, so the multi-head + * code can bail if we try to use more than one. */ + int adapter_use_count; + int adapter_map[32]; /* XXX magic constant */ +}; + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/aintern_xtouch.h b/allegro/include/allegro5/internal/aintern_xtouch.h new file mode 100644 index 00000000..2984adc6 --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xtouch.h @@ -0,0 +1,8 @@ +#ifndef __al_included_allegro5_aintern_xtouch_h +#define __al_included_allegro5_aintern_xtouch_h + +#include "allegro5/internal/aintern_touch_input.h" + +void _al_x_handle_touch_event(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, XEvent *e); + +#endif diff --git a/allegro/include/allegro5/internal/aintern_xwindow.h b/allegro/include/allegro5/internal/aintern_xwindow.h new file mode 100644 index 00000000..b1c777fc --- /dev/null +++ b/allegro/include/allegro5/internal/aintern_xwindow.h @@ -0,0 +1,16 @@ +#ifndef __al_included_allegro5_aintern_xwindow_h +#define __al_included_allegro5_aintern_xwindow_h + +void _al_xwin_set_size_hints(ALLEGRO_DISPLAY *d, int x_off, int y_off); +void _al_xwin_reset_size_hints(ALLEGRO_DISPLAY *d); +void _al_xwin_set_fullscreen_window(ALLEGRO_DISPLAY *display, int value); +void _al_xwin_set_above(ALLEGRO_DISPLAY *display, int value); +void _al_xwin_set_frame(ALLEGRO_DISPLAY *display, bool frame_on); +void _al_xwin_set_icons(ALLEGRO_DISPLAY *d, + int num_icons, ALLEGRO_BITMAP *bitmaps[]); +void _al_xwin_maximize(ALLEGRO_DISPLAY *d, bool maximized); +void _al_xwin_check_maximized(ALLEGRO_DISPLAY *display); + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/internal/alconfig.h b/allegro/include/allegro5/internal/alconfig.h new file mode 100644 index 00000000..50367595 --- /dev/null +++ b/allegro/include/allegro5/internal/alconfig.h @@ -0,0 +1,255 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +/* for backward compatibility */ +#ifdef USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN + #define ALLEGRO_USE_CONSOLE +#endif + + +/* include platform-specific stuff */ + +#include "allegro5/platform/alplatf.h" + + + +#if defined ALLEGRO_WATCOM + #include "allegro5/platform/alwatcom.h" +#elif defined ALLEGRO_MINGW32 + #include "allegro5/platform/almngw32.h" +#elif defined ALLEGRO_BCC32 + #include "allegro5/platform/albcc32.h" +#elif defined ALLEGRO_MSVC + #include "allegro5/platform/almsvc.h" +#elif defined ALLEGRO_IPHONE + #include "allegro5/platform/aliphonecfg.h" +#elif defined ALLEGRO_MACOSX + #include "allegro5/platform/alosxcfg.h" +#elif defined ALLEGRO_ANDROID + #include "allegro5/platform/alandroidcfg.h" +#elif defined ALLEGRO_RASPBERRYPI + #include "allegro5/platform/alraspberrypicfg.h" +#elif defined ALLEGRO_UNIX + #include "allegro5/platform/alucfg.h" +#elif defined ALLEGRO_SDL + #include "allegro5/platform/allegro_sdl_config.h" +#else + #error platform not supported +#endif + + +#include "allegro5/platform/astdint.h" +#include "allegro5/platform/astdbool.h" + + +/* 1 << 31 represented as a signed int */ +#define _ALLEGRO_UNSTABLE_BIT_SET INT32_MIN + +/* special definitions for the GCC compiler */ +#ifdef __GNUC__ + #define ALLEGRO_GCC + + #ifndef AL_INLINE + #ifdef __cplusplus + #define AL_INLINE(type, name, args, code) \ + static inline type name args; \ + static inline type name args code + /* Needed if this header is included by C99 code, as + * "extern __inline__" in C99 exports a new global function. + */ + #elif __GNUC_STDC_INLINE__ + #define AL_INLINE(type, name, args, code) \ + extern __inline__ __attribute__((__gnu_inline__)) type name args; \ + extern __inline__ __attribute__((__gnu_inline__)) type name args code + #else + #define AL_INLINE(type, name, args, code) \ + extern __inline__ type name args; \ + extern __inline__ type name args code + #endif + #endif + + #ifndef AL_INLINE_STATIC + #ifdef __cplusplus + #define AL_INLINE_STATIC(type, name, args, code) \ + AL_INLINE(type, name, args, code) + #else + #define AL_INLINE_STATIC(type, name, args, code) \ + static __inline__ type name args; \ + static __inline__ type name args code + #endif + #endif + + #define AL_PRINTFUNC(type, name, args, a, b) AL_FUNC(type, name, args) __attribute__ ((format (printf, a, b))) + + #ifndef INLINE + #define INLINE __inline__ + #endif + + #ifndef ZERO_SIZE_ARRAY + #if __GNUC__ < 3 + #define ZERO_SIZE_ARRAY(type, name) __extension__ type name[0] + #else + #define ZERO_SIZE_ARRAY(type, name) type name[] /* ISO C99 flexible array members */ + #endif + #endif + + #ifdef ALLEGRO_GUESS_INTTYPES_OK + #define int64_t signed long long + #define uint64_t unsigned long long + #endif + + #ifdef __i386__ + #define ALLEGRO_I386 + #endif + + #ifdef __amd64__ + #define ALLEGRO_AMD64 + #endif + + #ifdef __arm__ + #define ALLEGRO_ARM + #endif + + #ifndef AL_FUNC_DEPRECATED + #if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) + #define AL_FUNC_DEPRECATED(type, name, args) AL_FUNC(__attribute__ ((deprecated)) type, name, args) + #define AL_PRINTFUNC_DEPRECATED(type, name, args, a, b) AL_PRINTFUNC(__attribute__ ((deprecated)) type, name, args, a, b) + #define AL_INLINE_DEPRECATED(type, name, args, code) AL_INLINE(__attribute__ ((deprecated)) type, name, args, code) + #endif + #endif + + #ifndef AL_ALIAS + #define AL_ALIAS(DECL, CALL) \ + static __attribute__((unused)) __inline__ DECL \ + { \ + return CALL; \ + } + #endif + + #ifndef AL_ALIAS_VOID_RET + #define AL_ALIAS_VOID_RET(DECL, CALL) \ + static __attribute__((unused)) __inline__ void DECL \ + { \ + CALL; \ + } + #endif +#endif + + +/* the rest of this file fills in some default definitions of language + * features and helper functions, which are conditionalised so they will + * only be included if none of the above headers defined custom versions. + */ + +#ifndef INLINE + #define INLINE +#endif + +#ifndef ZERO_SIZE_ARRAY + #define ZERO_SIZE_ARRAY(type, name) type name[] +#endif + +#ifndef AL_VAR + #define AL_VAR(type, name) extern type name +#endif + +#ifndef AL_ARRAY + #define AL_ARRAY(type, name) extern type name[] +#endif + +#ifndef AL_FUNC + #define AL_FUNC(type, name, args) type name args +#endif + +#ifndef AL_PRINTFUNC + #define AL_PRINTFUNC(type, name, args, a, b) AL_FUNC(type, name, args) +#endif + +#ifndef AL_METHOD + #define AL_METHOD(type, name, args) type (*name) args +#endif + +#ifndef AL_FUNCPTR + #define AL_FUNCPTR(type, name, args) extern type (*name) args +#endif + +#ifndef AL_FUNCPTRARRAY + #define AL_FUNCPTRARRAY(type, name, args) extern type (*name[]) args +#endif + +#ifndef AL_INLINE + #define AL_INLINE(type, name, args, code) type name args; +#endif + +#ifndef AL_FUNC_DEPRECATED + #define AL_FUNC_DEPRECATED(type, name, args) AL_FUNC(type, name, args) + #define AL_PRINTFUNC_DEPRECATED(type, name, args, a, b) AL_PRINTFUNC(type, name, args, a, b) + #define AL_INLINE_DEPRECATED(type, name, args, code) AL_INLINE(type, name, args, code) +#endif + +#ifndef AL_ALIAS + #define AL_ALIAS(DECL, CALL) \ + static INLINE DECL \ + { \ + return CALL; \ + } +#endif + +#ifndef AL_ALIAS_VOID_RET + #define AL_ALIAS_VOID_RET(DECL, CALL) \ + static INLINE void DECL \ + { \ + CALL; \ + } +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +/* endian-independent 3-byte accessor macros */ +#ifdef ALLEGRO_LITTLE_ENDIAN + + #define _AL_READ3BYTES(p) ((*(unsigned char *)(p)) \ + | (*((unsigned char *)(p) + 1) << 8) \ + | (*((unsigned char *)(p) + 2) << 16)) + + #define _AL_WRITE3BYTES(p,c) ((*(unsigned char *)(p) = (c)), \ + (*((unsigned char *)(p) + 1) = (c) >> 8), \ + (*((unsigned char *)(p) + 2) = (c) >> 16)) + +#elif defined ALLEGRO_BIG_ENDIAN + + #define _AL_READ3BYTES(p) ((*(unsigned char *)(p) << 16) \ + | (*((unsigned char *)(p) + 1) << 8) \ + | (*((unsigned char *)(p) + 2))) + + #define _AL_WRITE3BYTES(p,c) ((*(unsigned char *)(p) = (c) >> 16), \ + (*((unsigned char *)(p) + 1) = (c) >> 8), \ + (*((unsigned char *)(p) + 2) = (c))) + +#else + #error endianess not defined +#endif + +#ifdef __cplusplus + } +#endif + diff --git a/allegro/include/allegro5/internal/bstrlib.h b/allegro/include/allegro5/internal/bstrlib.h new file mode 100644 index 00000000..3378af37 --- /dev/null +++ b/allegro/include/allegro5/internal/bstrlib.h @@ -0,0 +1,309 @@ +/* + * This source file has had its exported symbols prefixed with _al_ or _AL_ + * for the Allegro project. + */ + +/* + * This source file is part of the _al_bstring string library. This code was + * written by Paul Hsieh in 2002-2008, and is covered by the BSD open source + * license and the GPL. Refer to the accompanying documentation for details + * on usage and license. + */ + +/* + * bstrlib.c + * + * This file is the core module for implementing the _al_bstring functions. + */ + +#ifndef _AL_BSTRLIB_INCLUDE +#define _AL_BSTRLIB_INCLUDE + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP) +# if defined (__TURBOC__) && !defined (__BORLANDC__) +# define BSTRLIB_NOVSNP +# endif +#endif + +#define _AL_BSTR_ERR (-1) +#define _AL_BSTR_OK (0) +#define _AL_BSTR_BS_BUFF_LENGTH_GET (0) + +typedef struct _al_tagbstring * _al_bstring; +typedef const struct _al_tagbstring * _al_const_bstring; + +/* Copy functions */ +#define _al_cstr2bstr _al_bfromcstr +extern _al_bstring _al_bfromcstr (const char * str); +extern _al_bstring _al_bfromcstralloc (int mlen, const char * str); +extern _al_bstring _al_blk2bstr (const void * blk, int len); +extern char * _al_bstr2cstr (_al_const_bstring s, char z); +extern int _al_bcstrfree (char * s); +extern _al_bstring _al_bstrcpy (_al_const_bstring b1); +extern int _al_bassign (_al_bstring a, _al_const_bstring b); +extern int _al_bassignmidstr (_al_bstring a, _al_const_bstring b, int left, int len); +extern int _al_bassigncstr (_al_bstring a, const char * str); +extern int _al_bassignblk (_al_bstring a, const void * s, int len); + +/* Destroy function */ +extern int _al_bdestroy (_al_bstring b); + +/* Space allocation hinting functions */ +extern int _al_balloc (_al_bstring s, int len); +extern int _al_ballocmin (_al_bstring b, int len); + +/* Substring extraction */ +extern _al_bstring _al_bmidstr (_al_const_bstring b, int left, int len); + +/* Various standard manipulations */ +extern int _al_bconcat (_al_bstring b0, _al_const_bstring b1); +extern int _al_bconchar (_al_bstring b0, char c); +extern int _al_bcatcstr (_al_bstring b, const char * s); +extern int _al_bcatblk (_al_bstring b, const void * s, int len); +extern int _al_binsert (_al_bstring s1, int pos, _al_const_bstring s2, unsigned char fill); +extern int _al_binsertch (_al_bstring s1, int pos, int len, unsigned char fill); +extern int _al_breplace (_al_bstring b1, int pos, int len, _al_const_bstring b2, unsigned char fill); +extern int _al_bdelete (_al_bstring s1, int pos, int len); +extern int _al_bsetstr (_al_bstring b0, int pos, _al_const_bstring b1, unsigned char fill); +extern int _al_btrunc (_al_bstring b, int n); + +/* Scan/search functions */ +extern int _al_bstricmp (_al_const_bstring b0, _al_const_bstring b1); +extern int _al_bstrnicmp (_al_const_bstring b0, _al_const_bstring b1, int n); +extern int _al_biseqcaseless (_al_const_bstring b0, _al_const_bstring b1); +extern int _al_bisstemeqcaselessblk (_al_const_bstring b0, const void * blk, int len); +extern int _al_biseq (_al_const_bstring b0, _al_const_bstring b1); +extern int _al_bisstemeqblk (_al_const_bstring b0, const void * blk, int len); +extern int _al_biseqcstr (_al_const_bstring b, const char * s); +extern int _al_biseqcstrcaseless (_al_const_bstring b, const char * s); +extern int _al_bstrcmp (_al_const_bstring b0, _al_const_bstring b1); +extern int _al_bstrncmp (_al_const_bstring b0, _al_const_bstring b1, int n); +extern int _al_binstr (_al_const_bstring s1, int pos, _al_const_bstring s2); +extern int _al_binstrr (_al_const_bstring s1, int pos, _al_const_bstring s2); +extern int _al_binstrcaseless (_al_const_bstring s1, int pos, _al_const_bstring s2); +extern int _al_binstrrcaseless (_al_const_bstring s1, int pos, _al_const_bstring s2); +extern int _al_bstrchrp (_al_const_bstring b, int c, int pos); +extern int _al_bstrrchrp (_al_const_bstring b, int c, int pos); +#define _al_bstrchr(b,c) _al_bstrchrp ((b), (c), 0) +#define _al_bstrrchr(b,c) _al_bstrrchrp ((b), (c), _al_blength(b)-1) +extern int _al_binchr (_al_const_bstring b0, int pos, _al_const_bstring b1); +extern int _al_binchrr (_al_const_bstring b0, int pos, _al_const_bstring b1); +extern int _al_bninchr (_al_const_bstring b0, int pos, _al_const_bstring b1); +extern int _al_bninchrr (_al_const_bstring b0, int pos, _al_const_bstring b1); +extern int _al_bfindreplace (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos); +extern int _al_bfindreplacecaseless (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos); + +/* List of string container functions */ +struct _al_bstrList { + int qty, mlen; + _al_bstring * entry; +}; +extern struct _al_bstrList * _al_bstrListCreate (void); +extern int _al_bstrListDestroy (struct _al_bstrList * sl); +extern int _al_bstrListAlloc (struct _al_bstrList * sl, int msz); +extern int _al_bstrListAllocMin (struct _al_bstrList * sl, int msz); + +/* String split and join functions */ +extern struct _al_bstrList * _al_bsplit (_al_const_bstring str, unsigned char splitChar); +extern struct _al_bstrList * _al_bsplits (_al_const_bstring str, _al_const_bstring splitStr); +extern struct _al_bstrList * _al_bsplitstr (_al_const_bstring str, _al_const_bstring splitStr); +extern _al_bstring _al_bjoin (const struct _al_bstrList * bl, _al_const_bstring sep); +extern int _al_bsplitcb (_al_const_bstring str, unsigned char splitChar, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); +extern int _al_bsplitscb (_al_const_bstring str, _al_const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); +extern int _al_bsplitstrcb (_al_const_bstring str, _al_const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + +/* Miscellaneous functions */ +extern int _al_bpattern (_al_bstring b, int len); +extern int _al_btoupper (_al_bstring b); +extern int _al_btolower (_al_bstring b); +extern int _al_bltrimws (_al_bstring b); +extern int _al_brtrimws (_al_bstring b); +extern int _al_btrimws (_al_bstring b); + +#if !defined (BSTRLIB_NOVSNP) +extern _al_bstring _al_bformat (const char * fmt, ...); +extern int _al_bformata (_al_bstring b, const char * fmt, ...); +extern int _al_bassignformat (_al_bstring b, const char * fmt, ...); +extern int _al_bvcformata (_al_bstring b, int count, const char * fmt, va_list arglist); + +#define _al_bvformata(ret, b, fmt, lastarg) { \ +_al_bstring bstrtmp_b = (b); \ +const char * bstrtmp_fmt = (fmt); \ +int bstrtmp_r = _AL_BSTR_ERR, bstrtmp_sz = 16; \ + for (;;) { \ + va_list bstrtmp_arglist; \ + va_start (bstrtmp_arglist, lastarg); \ + bstrtmp_r = _al_bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \ + va_end (bstrtmp_arglist); \ + if (bstrtmp_r >= 0) { /* Everything went ok */ \ + bstrtmp_r = _AL_BSTR_OK; \ + break; \ + } else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \ + bstrtmp_r = _AL_BSTR_ERR; \ + break; \ + } \ + bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \ + } \ + ret = bstrtmp_r; \ +} + +#endif + +typedef int (*_al_bNgetc) (void *parm); +typedef size_t (* _al_bNread) (void *buff, size_t elsize, size_t nelem, void *parm); + +/* Input functions */ +extern _al_bstring _al_bgets (_al_bNgetc getcPtr, void * parm, char terminator); +extern _al_bstring _al_bread (_al_bNread readPtr, void * parm); +extern int _al_bgetsa (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator); +extern int _al_bassigngets (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator); +extern int _al_breada (_al_bstring b, _al_bNread readPtr, void * parm); + +/* Stream functions */ +extern struct _al_bStream * _al_bsopen (_al_bNread readPtr, void * parm); +extern void * _al_bsclose (struct _al_bStream * s); +extern int _al_bsbufflength (struct _al_bStream * s, int sz); +extern int _al_bsreadln (_al_bstring b, struct _al_bStream * s, char terminator); +extern int _al_bsreadlns (_al_bstring r, struct _al_bStream * s, _al_const_bstring term); +extern int _al_bsread (_al_bstring b, struct _al_bStream * s, int n); +extern int _al_bsreadlna (_al_bstring b, struct _al_bStream * s, char terminator); +extern int _al_bsreadlnsa (_al_bstring r, struct _al_bStream * s, _al_const_bstring term); +extern int _al_bsreada (_al_bstring b, struct _al_bStream * s, int n); +extern int _al_bsunread (struct _al_bStream * s, _al_const_bstring b); +extern int _al_bspeek (_al_bstring r, const struct _al_bStream * s); +extern int _al_bssplitscb (struct _al_bStream * s, _al_const_bstring splitStr, + int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm); +extern int _al_bssplitstrcb (struct _al_bStream * s, _al_const_bstring splitStr, + int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm); +extern int _al_bseof (const struct _al_bStream * s); + +#ifndef __al_tagbstring_defined +#define __al_tagbstring_defined +struct _al_tagbstring { + int mlen; + int slen; + unsigned char * data; +}; +#endif + +/* Accessor macros */ +#define _al_blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen)) +#define _al_blength(b) (_al_blengthe ((b), 0)) +#define _al_bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o)) +#define _al_bdataofs(b, o) (_al_bdataofse ((b), (o), (void *)0)) +#define _al_bdatae(b, e) (_al_bdataofse (b, 0, e)) +#define _al_bdata(b) (_al_bdataofs (b, 0)) +#define _al_bchare(b, p, e) ((((unsigned)(p)) < (unsigned)_al_blength(b)) ? ((b)->data[(p)]) : (e)) +#define _al_bchar(b, p) _al_bchare ((b), (p), '\0') + +/* Static constant string initialization macro */ +#define _al_bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")} +#if defined(_MSC_VER) +# define _al_bsStatic(q) _al_bsStaticMlen(q,-32) +#endif +#ifndef _al_bsStatic +# define _al_bsStatic(q) _al_bsStaticMlen(q,-__LINE__) +#endif + +/* Static constant block parameter pair */ +#define _al_bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1) + +/* Reference building macros */ +#define _al_cstr2tbstr _al_btfromcstr +#define _al_btfromcstr(t,s) { \ + (t).data = (unsigned char *) (s); \ + (t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \ + (t).mlen = -1; \ +} +#define _al_blk2tbstr(t,s,l) { \ + (t).data = (unsigned char *) (s); \ + (t).slen = l; \ + (t).mlen = -1; \ +} +#define _al_btfromblk(t,s,l) _al_blk2tbstr(t,s,l) +#define _al_bmid2tbstr(t,b,p,l) { \ + _al_const_bstring bstrtmp_s = (b); \ + if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \ + int bstrtmp_left = (p); \ + int bstrtmp_len = (l); \ + if (bstrtmp_left < 0) { \ + bstrtmp_len += bstrtmp_left; \ + bstrtmp_left = 0; \ + } \ + if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \ + bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \ + if (bstrtmp_len <= 0) { \ + (t).data = (unsigned char *)""; \ + (t).slen = 0; \ + } else { \ + (t).data = bstrtmp_s->data + bstrtmp_left; \ + (t).slen = bstrtmp_len; \ + } \ + } else { \ + (t).data = (unsigned char *)""; \ + (t).slen = 0; \ + } \ + (t).mlen = -__LINE__; \ +} +#define _al_btfromblkltrimws(t,s,l) { \ + int bstrtmp_idx = 0, bstrtmp_len = (l); \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \ + if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \ + } \ + } \ + (t).data = bstrtmp_s + bstrtmp_idx; \ + (t).slen = bstrtmp_len - bstrtmp_idx; \ + (t).mlen = -__LINE__; \ +} +#define _al_btfromblkrtrimws(t,s,l) { \ + int bstrtmp_len = (l) - 1; \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_len >= 0; bstrtmp_len--) { \ + if (!isspace (bstrtmp_s[bstrtmp_len])) break; \ + } \ + } \ + (t).data = bstrtmp_s; \ + (t).slen = bstrtmp_len + 1; \ + (t).mlen = -__LINE__; \ +} +#define _al_btfromblktrimws(t,s,l) { \ + int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \ + if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \ + } \ + for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \ + if (!isspace (bstrtmp_s[bstrtmp_len])) break; \ + } \ + } \ + (t).data = bstrtmp_s + bstrtmp_idx; \ + (t).slen = bstrtmp_len + 1 - bstrtmp_idx; \ + (t).mlen = -__LINE__; \ +} + +/* Write protection macros */ +#define _al_bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; } +#define _al_bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); } +#define _al_biswriteprotected(t) ((t).mlen <= 0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/allegro/include/allegro5/joystick.h b/allegro/include/allegro5/joystick.h new file mode 100644 index 00000000..4b3e648b --- /dev/null +++ b/allegro/include/allegro5/joystick.h @@ -0,0 +1,91 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Joystick routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_joystick_h +#define __al_included_allegro5_joystick_h + +#include "allegro5/base.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* internal values */ +#define _AL_MAX_JOYSTICK_AXES 3 +#define _AL_MAX_JOYSTICK_STICKS 16 +#define _AL_MAX_JOYSTICK_BUTTONS 32 + + + +/* Type: ALLEGRO_JOYSTICK + */ +typedef struct ALLEGRO_JOYSTICK ALLEGRO_JOYSTICK; + + + +/* Type: ALLEGRO_JOYSTICK_STATE + */ +typedef struct ALLEGRO_JOYSTICK_STATE ALLEGRO_JOYSTICK_STATE; + +struct ALLEGRO_JOYSTICK_STATE +{ + struct { + float axis[_AL_MAX_JOYSTICK_AXES]; /* -1.0 to 1.0 */ + } stick[_AL_MAX_JOYSTICK_STICKS]; + int button[_AL_MAX_JOYSTICK_BUTTONS]; /* 0 to 32767 */ +}; + + +/* Enum: ALLEGRO_JOYFLAGS + */ +enum ALLEGRO_JOYFLAGS +{ + ALLEGRO_JOYFLAG_DIGITAL = 0x01, + ALLEGRO_JOYFLAG_ANALOGUE = 0x02 +}; + + + +AL_FUNC(bool, al_install_joystick, (void)); +AL_FUNC(void, al_uninstall_joystick, (void)); +AL_FUNC(bool, al_is_joystick_installed, (void)); +AL_FUNC(bool, al_reconfigure_joysticks, (void)); + +AL_FUNC(int, al_get_num_joysticks, (void)); +AL_FUNC(ALLEGRO_JOYSTICK *, al_get_joystick, (int joyn)); +AL_FUNC(void, al_release_joystick, (ALLEGRO_JOYSTICK *)); +AL_FUNC(bool, al_get_joystick_active, (ALLEGRO_JOYSTICK *)); +AL_FUNC(const char*, al_get_joystick_name, (ALLEGRO_JOYSTICK *)); + +AL_FUNC(int, al_get_joystick_num_sticks, (ALLEGRO_JOYSTICK *)); +AL_FUNC(int, al_get_joystick_stick_flags, (ALLEGRO_JOYSTICK *, int stick)); /* junk? */ +AL_FUNC(const char*, al_get_joystick_stick_name, (ALLEGRO_JOYSTICK *, int stick)); + +AL_FUNC(int, al_get_joystick_num_axes, (ALLEGRO_JOYSTICK *, int stick)); +AL_FUNC(const char*, al_get_joystick_axis_name, (ALLEGRO_JOYSTICK *, int stick, int axis)); + +AL_FUNC(int, al_get_joystick_num_buttons, (ALLEGRO_JOYSTICK *)); +AL_FUNC(const char*, al_get_joystick_button_name, (ALLEGRO_JOYSTICK *, int buttonn)); + +AL_FUNC(void, al_get_joystick_state, (ALLEGRO_JOYSTICK *, ALLEGRO_JOYSTICK_STATE *ret_state)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_joystick_event_source, (void)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/keyboard.h b/allegro/include/allegro5/keyboard.h new file mode 100644 index 00000000..17cd274b --- /dev/null +++ b/allegro/include/allegro5/keyboard.h @@ -0,0 +1,70 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Keyboard routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_keyboard_h +#define __al_included_allegro5_keyboard_h + +#include "allegro5/base.h" +#include "allegro5/events.h" +#include "allegro5/keycodes.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct ALLEGRO_KEYBOARD ALLEGRO_KEYBOARD; + + + +/* Type: ALLEGRO_KEYBOARD_STATE + */ +typedef struct ALLEGRO_KEYBOARD_STATE ALLEGRO_KEYBOARD_STATE; + +struct ALLEGRO_KEYBOARD_STATE +{ + struct ALLEGRO_DISPLAY *display; /* public */ + /* internal */ + unsigned int __key_down__internal__[(ALLEGRO_KEY_MAX + 31) / 32]; +}; + + +AL_FUNC(bool, al_is_keyboard_installed, (void)); +AL_FUNC(bool, al_install_keyboard, (void)); +AL_FUNC(void, al_uninstall_keyboard, (void)); + +AL_FUNC(bool, al_set_keyboard_leds, (int leds)); + +AL_FUNC(const char *, al_keycode_to_name, (int keycode)); + +AL_FUNC(void, al_get_keyboard_state, (ALLEGRO_KEYBOARD_STATE *ret_state)); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(void, al_clear_keyboard_state, (ALLEGRO_DISPLAY *display)); +#endif +AL_FUNC(bool, al_key_down, (const ALLEGRO_KEYBOARD_STATE *, int keycode)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_keyboard_event_source, (void)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/include/allegro5/keycodes.h b/allegro/include/allegro5/keycodes.h new file mode 100644 index 00000000..0a899017 --- /dev/null +++ b/allegro/include/allegro5/keycodes.h @@ -0,0 +1,214 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Keycode constants. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_keycodes_h +#define __al_included_allegro5_keycodes_h + + + +/* Note these values are deliberately the same as in Allegro 4.1.x */ +enum +{ + ALLEGRO_KEY_A = 1, + ALLEGRO_KEY_B = 2, + ALLEGRO_KEY_C = 3, + ALLEGRO_KEY_D = 4, + ALLEGRO_KEY_E = 5, + ALLEGRO_KEY_F = 6, + ALLEGRO_KEY_G = 7, + ALLEGRO_KEY_H = 8, + ALLEGRO_KEY_I = 9, + ALLEGRO_KEY_J = 10, + ALLEGRO_KEY_K = 11, + ALLEGRO_KEY_L = 12, + ALLEGRO_KEY_M = 13, + ALLEGRO_KEY_N = 14, + ALLEGRO_KEY_O = 15, + ALLEGRO_KEY_P = 16, + ALLEGRO_KEY_Q = 17, + ALLEGRO_KEY_R = 18, + ALLEGRO_KEY_S = 19, + ALLEGRO_KEY_T = 20, + ALLEGRO_KEY_U = 21, + ALLEGRO_KEY_V = 22, + ALLEGRO_KEY_W = 23, + ALLEGRO_KEY_X = 24, + ALLEGRO_KEY_Y = 25, + ALLEGRO_KEY_Z = 26, + + ALLEGRO_KEY_0 = 27, + ALLEGRO_KEY_1 = 28, + ALLEGRO_KEY_2 = 29, + ALLEGRO_KEY_3 = 30, + ALLEGRO_KEY_4 = 31, + ALLEGRO_KEY_5 = 32, + ALLEGRO_KEY_6 = 33, + ALLEGRO_KEY_7 = 34, + ALLEGRO_KEY_8 = 35, + ALLEGRO_KEY_9 = 36, + + ALLEGRO_KEY_PAD_0 = 37, + ALLEGRO_KEY_PAD_1 = 38, + ALLEGRO_KEY_PAD_2 = 39, + ALLEGRO_KEY_PAD_3 = 40, + ALLEGRO_KEY_PAD_4 = 41, + ALLEGRO_KEY_PAD_5 = 42, + ALLEGRO_KEY_PAD_6 = 43, + ALLEGRO_KEY_PAD_7 = 44, + ALLEGRO_KEY_PAD_8 = 45, + ALLEGRO_KEY_PAD_9 = 46, + + ALLEGRO_KEY_F1 = 47, + ALLEGRO_KEY_F2 = 48, + ALLEGRO_KEY_F3 = 49, + ALLEGRO_KEY_F4 = 50, + ALLEGRO_KEY_F5 = 51, + ALLEGRO_KEY_F6 = 52, + ALLEGRO_KEY_F7 = 53, + ALLEGRO_KEY_F8 = 54, + ALLEGRO_KEY_F9 = 55, + ALLEGRO_KEY_F10 = 56, + ALLEGRO_KEY_F11 = 57, + ALLEGRO_KEY_F12 = 58, + + ALLEGRO_KEY_ESCAPE = 59, + ALLEGRO_KEY_TILDE = 60, + ALLEGRO_KEY_MINUS = 61, + ALLEGRO_KEY_EQUALS = 62, + ALLEGRO_KEY_BACKSPACE = 63, + ALLEGRO_KEY_TAB = 64, + ALLEGRO_KEY_OPENBRACE = 65, + ALLEGRO_KEY_CLOSEBRACE = 66, + ALLEGRO_KEY_ENTER = 67, + ALLEGRO_KEY_SEMICOLON = 68, + ALLEGRO_KEY_QUOTE = 69, + ALLEGRO_KEY_BACKSLASH = 70, + ALLEGRO_KEY_BACKSLASH2 = 71, /* DirectInput calls this DIK_OEM_102: "< > | on UK/Germany keyboards" */ + ALLEGRO_KEY_COMMA = 72, + ALLEGRO_KEY_FULLSTOP = 73, + ALLEGRO_KEY_SLASH = 74, + ALLEGRO_KEY_SPACE = 75, + + ALLEGRO_KEY_INSERT = 76, + ALLEGRO_KEY_DELETE = 77, + ALLEGRO_KEY_HOME = 78, + ALLEGRO_KEY_END = 79, + ALLEGRO_KEY_PGUP = 80, + ALLEGRO_KEY_PGDN = 81, + ALLEGRO_KEY_LEFT = 82, + ALLEGRO_KEY_RIGHT = 83, + ALLEGRO_KEY_UP = 84, + ALLEGRO_KEY_DOWN = 85, + + ALLEGRO_KEY_PAD_SLASH = 86, + ALLEGRO_KEY_PAD_ASTERISK = 87, + ALLEGRO_KEY_PAD_MINUS = 88, + ALLEGRO_KEY_PAD_PLUS = 89, + ALLEGRO_KEY_PAD_DELETE = 90, + ALLEGRO_KEY_PAD_ENTER = 91, + + ALLEGRO_KEY_PRINTSCREEN = 92, + ALLEGRO_KEY_PAUSE = 93, + + ALLEGRO_KEY_ABNT_C1 = 94, + ALLEGRO_KEY_YEN = 95, + ALLEGRO_KEY_KANA = 96, + ALLEGRO_KEY_CONVERT = 97, + ALLEGRO_KEY_NOCONVERT = 98, + ALLEGRO_KEY_AT = 99, + ALLEGRO_KEY_CIRCUMFLEX = 100, + ALLEGRO_KEY_COLON2 = 101, + ALLEGRO_KEY_KANJI = 102, + + ALLEGRO_KEY_PAD_EQUALS = 103, /* MacOS X */ + ALLEGRO_KEY_BACKQUOTE = 104, /* MacOS X */ + ALLEGRO_KEY_SEMICOLON2 = 105, /* MacOS X -- TODO: ask lillo what this should be */ + ALLEGRO_KEY_COMMAND = 106, /* MacOS X */ + + ALLEGRO_KEY_BACK = 107, /* Android back key */ + ALLEGRO_KEY_VOLUME_UP = 108, + ALLEGRO_KEY_VOLUME_DOWN = 109, + + /* Android game keys */ + ALLEGRO_KEY_SEARCH = 110, + ALLEGRO_KEY_DPAD_CENTER = 111, + ALLEGRO_KEY_BUTTON_X = 112, + ALLEGRO_KEY_BUTTON_Y = 113, + ALLEGRO_KEY_DPAD_UP = 114, + ALLEGRO_KEY_DPAD_DOWN = 115, + ALLEGRO_KEY_DPAD_LEFT = 116, + ALLEGRO_KEY_DPAD_RIGHT = 117, + ALLEGRO_KEY_SELECT = 118, + ALLEGRO_KEY_START = 119, + ALLEGRO_KEY_BUTTON_L1 = 120, + ALLEGRO_KEY_BUTTON_R1 = 121, + ALLEGRO_KEY_BUTTON_L2 = 122, + ALLEGRO_KEY_BUTTON_R2 = 123, + ALLEGRO_KEY_BUTTON_A = 124, + ALLEGRO_KEY_BUTTON_B = 125, + ALLEGRO_KEY_THUMBL = 126, + ALLEGRO_KEY_THUMBR = 127, + + ALLEGRO_KEY_UNKNOWN = 128, + + /* All codes up to before ALLEGRO_KEY_MODIFIERS can be freely + * assignedas additional unknown keys, like various multimedia + * and application keys keyboards may have. + */ + + ALLEGRO_KEY_MODIFIERS = 215, + + ALLEGRO_KEY_LSHIFT = 215, + ALLEGRO_KEY_RSHIFT = 216, + ALLEGRO_KEY_LCTRL = 217, + ALLEGRO_KEY_RCTRL = 218, + ALLEGRO_KEY_ALT = 219, + ALLEGRO_KEY_ALTGR = 220, + ALLEGRO_KEY_LWIN = 221, + ALLEGRO_KEY_RWIN = 222, + ALLEGRO_KEY_MENU = 223, + ALLEGRO_KEY_SCROLLLOCK = 224, + ALLEGRO_KEY_NUMLOCK = 225, + ALLEGRO_KEY_CAPSLOCK = 226, + + ALLEGRO_KEY_MAX +}; + + + +enum +{ + ALLEGRO_KEYMOD_SHIFT = 0x00001, + ALLEGRO_KEYMOD_CTRL = 0x00002, + ALLEGRO_KEYMOD_ALT = 0x00004, + ALLEGRO_KEYMOD_LWIN = 0x00008, + ALLEGRO_KEYMOD_RWIN = 0x00010, + ALLEGRO_KEYMOD_MENU = 0x00020, + ALLEGRO_KEYMOD_ALTGR = 0x00040, + ALLEGRO_KEYMOD_COMMAND = 0x00080, + ALLEGRO_KEYMOD_SCROLLLOCK = 0x00100, + ALLEGRO_KEYMOD_NUMLOCK = 0x00200, + ALLEGRO_KEYMOD_CAPSLOCK = 0x00400, + ALLEGRO_KEYMOD_INALTSEQ = 0x00800, + ALLEGRO_KEYMOD_ACCENT1 = 0x01000, + ALLEGRO_KEYMOD_ACCENT2 = 0x02000, + ALLEGRO_KEYMOD_ACCENT3 = 0x04000, + ALLEGRO_KEYMOD_ACCENT4 = 0x08000 +}; + + + +#endif diff --git a/allegro/include/allegro5/memory.h b/allegro/include/allegro5/memory.h new file mode 100644 index 00000000..869f6c26 --- /dev/null +++ b/allegro/include/allegro5/memory.h @@ -0,0 +1,75 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Memory management routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_memory_h +#define __al_included_allegro5_memory_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_MEMORY_INTERFACE + */ +typedef struct ALLEGRO_MEMORY_INTERFACE ALLEGRO_MEMORY_INTERFACE; + +struct ALLEGRO_MEMORY_INTERFACE { + void *(*mi_malloc)(size_t n, int line, const char *file, const char *func); + void (*mi_free)(void *ptr, int line, const char *file, const char *func); + void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file, const char *func); + void *(*mi_calloc)(size_t count, size_t n, int line, const char *file, const char *func); +}; + +AL_FUNC(void, al_set_memory_interface, (ALLEGRO_MEMORY_INTERFACE *iface)); + + +/* Function: al_malloc + */ +#define al_malloc(n) \ + (al_malloc_with_context((n), __LINE__, __FILE__, __func__)) + +/* Function: al_free + */ +#define al_free(p) \ + (al_free_with_context((p), __LINE__, __FILE__, __func__)) + +/* Function: al_realloc + */ +#define al_realloc(p, n) \ + (al_realloc_with_context((p), (n), __LINE__, __FILE__, __func__)) + +/* Function: al_calloc + */ +#define al_calloc(c, n) \ + (al_calloc_with_context((c), (n), __LINE__, __FILE__, __func__)) + + +AL_FUNC(void *, al_malloc_with_context, (size_t n, + int line, const char *file, const char *func)); +AL_FUNC(void, al_free_with_context, (void *ptr, + int line, const char *file, const char *func)); +AL_FUNC(void *, al_realloc_with_context, (void *ptr, size_t n, + int line, const char *file, const char *func)); +AL_FUNC(void *, al_calloc_with_context, (size_t count, size_t n, + int line, const char *file, const char *func)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/monitor.h b/allegro/include/allegro5/monitor.h new file mode 100644 index 00000000..efa1c975 --- /dev/null +++ b/allegro/include/allegro5/monitor.h @@ -0,0 +1,38 @@ +#ifndef __al_included_allegro5_monitor_h +#define __al_included_allegro5_monitor_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_MONITOR_INFO + */ +typedef struct ALLEGRO_MONITOR_INFO +{ + int x1; + int y1; + int x2; + int y2; +} ALLEGRO_MONITOR_INFO; + +enum { + ALLEGRO_DEFAULT_DISPLAY_ADAPTER = -1 +}; + +AL_FUNC(int, al_get_num_video_adapters, (void)); +AL_FUNC(bool, al_get_monitor_info, (int adapter, ALLEGRO_MONITOR_INFO *info)); +AL_FUNC(int, al_get_monitor_dpi, (int adapter)); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(int, al_get_monitor_refresh_rate, (int adapter)); +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/mouse.h b/allegro/include/allegro5/mouse.h new file mode 100644 index 00000000..307d6902 --- /dev/null +++ b/allegro/include/allegro5/mouse.h @@ -0,0 +1,82 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Mouse routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_mouse_h +#define __al_included_allegro5_mouse_h + +#include "allegro5/base.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Allow up to four extra axes for future expansion. */ +#define ALLEGRO_MOUSE_MAX_EXTRA_AXES 4 + + +typedef struct ALLEGRO_MOUSE ALLEGRO_MOUSE; + + +/* Type: ALLEGRO_MOUSE_STATE + */ +typedef struct ALLEGRO_MOUSE_STATE ALLEGRO_MOUSE_STATE; + +struct ALLEGRO_MOUSE_STATE +{ + /* (x, y) Primary mouse position + * (z) Mouse wheel position (1D 'wheel'), or, + * (w, z) Mouse wheel position (2D 'ball') + * display - the display the mouse is on (coordinates are relative to this) + * pressure - the pressure applied to the mouse (for stylus/tablet) + */ + int x; + int y; + int z; + int w; + int more_axes[ALLEGRO_MOUSE_MAX_EXTRA_AXES]; + int buttons; + float pressure; + struct ALLEGRO_DISPLAY *display; +}; + + +AL_FUNC(bool, al_is_mouse_installed, (void)); +AL_FUNC(bool, al_install_mouse, (void)); +AL_FUNC(void, al_uninstall_mouse, (void)); +AL_FUNC(unsigned int, al_get_mouse_num_buttons, (void)); +AL_FUNC(unsigned int, al_get_mouse_num_axes, (void)); +AL_FUNC(bool, al_set_mouse_xy, (struct ALLEGRO_DISPLAY *display, int x, int y)); +AL_FUNC(bool, al_set_mouse_z, (int z)); +AL_FUNC(bool, al_set_mouse_w, (int w)); +AL_FUNC(bool, al_set_mouse_axis, (int axis, int value)); +AL_FUNC(void, al_get_mouse_state, (ALLEGRO_MOUSE_STATE *ret_state)); +AL_FUNC(bool, al_mouse_button_down, (const ALLEGRO_MOUSE_STATE *state, int button)); +AL_FUNC(int, al_get_mouse_state_axis, (const ALLEGRO_MOUSE_STATE *state, int axis)); +AL_FUNC(bool, al_get_mouse_cursor_position, (int *ret_x, int *ret_y)); +AL_FUNC(bool, al_grab_mouse, (struct ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_ungrab_mouse, (void)); +AL_FUNC(void, al_set_mouse_wheel_precision, (int precision)); +AL_FUNC(int, al_get_mouse_wheel_precision, (void)); + +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_mouse_event_source, (void)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/mouse_cursor.h b/allegro/include/allegro5/mouse_cursor.h new file mode 100644 index 00000000..69c7043c --- /dev/null +++ b/allegro/include/allegro5/mouse_cursor.h @@ -0,0 +1,58 @@ +#ifndef __al_included_allegro5_mouse_cursor_h +#define __al_included_allegro5_mouse_cursor_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct ALLEGRO_MOUSE_CURSOR ALLEGRO_MOUSE_CURSOR; + +typedef enum ALLEGRO_SYSTEM_MOUSE_CURSOR +{ + ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE = 0, + ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT = 1, + ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW = 2, + ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY = 3, + ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION = 4, + ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT = 5, + ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE = 6, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N = 7, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W = 8, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S = 9, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E = 10, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW = 11, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW = 12, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE = 13, + ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE = 14, + ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS = 15, + ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION = 16, + ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK = 17, + ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT = 18, + ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE = 19, + ALLEGRO_NUM_SYSTEM_MOUSE_CURSORS +} ALLEGRO_SYSTEM_MOUSE_CURSOR; + +struct ALLEGRO_BITMAP; +struct ALLEGRO_DISPLAY; + + +AL_FUNC(ALLEGRO_MOUSE_CURSOR *, al_create_mouse_cursor, ( + struct ALLEGRO_BITMAP *sprite, int xfocus, int yfocus)); +AL_FUNC(void, al_destroy_mouse_cursor, (ALLEGRO_MOUSE_CURSOR *)); +AL_FUNC(bool, al_set_mouse_cursor, (struct ALLEGRO_DISPLAY *display, + ALLEGRO_MOUSE_CURSOR *cursor)); +AL_FUNC(bool, al_set_system_mouse_cursor, (struct ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id)); +AL_FUNC(bool, al_show_mouse_cursor, (struct ALLEGRO_DISPLAY *display)); +AL_FUNC(bool, al_hide_mouse_cursor, (struct ALLEGRO_DISPLAY *display)); + + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/opengl/GLext/gl_ext_alias.h b/allegro/include/allegro5/opengl/GLext/gl_ext_alias.h new file mode 100644 index 00000000..4e077647 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/gl_ext_alias.h @@ -0,0 +1,2611 @@ +/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ +/**/ + +#ifdef _ALLEGRO_GL_VERSION_1_2 +#define glBlendColor _al_glBlendColor +#define glBlendEquation _al_glBlendEquation +#define glDrawRangeElements _al_glDrawRangeElements +#define glColorTable _al_glColorTable +#define glColorTableParameterfv _al_glColorTableParameterfv +#define glColorTableParameteriv _al_glColorTableParameteriv +#define glCopyColorTable _al_glCopyColorTable +#define glGetColorTable _al_glGetColorTable +#define glGetColorTableParameterfv _al_glGetColorTableParameterfv +#define glGetColorTableParameteriv _al_glGetColorTableParameteriv +#define glColorSubTable _al_glColorSubTable +#define glCopyColorSubTable _al_glCopyColorSubTable +#define glTexImage3D _al_glTexImage3D +#define glTexSubImage3D _al_glTexSubImage3D +#define glCopyTexSubImage3D _al_glCopyTexSubImage3D +#endif + +#if defined _ALLEGRO_GL_ARB_imaging +#define glConvolutionFilter1D _al_glConvolutionFilter1D +#define glConvolutionFilter2D _al_glConvolutionFilter2D +#define glConvolutionParameterf _al_glConvolutionParameterf +#define glConvolutionParameterfv _al_glConvolutionParameterfv +#define glConvolutionParameteri _al_glConvolutionParameteri +#define glConvolutionParameteriv _al_glConvolutionParameteriv +#define glCopyConvolutionFilter1D _al_glCopyConvolutionFilter1D +#define glCopyConvolutionFilter2D _al_glCopyConvolutionFilter2D +#define glGetConvolutionFilter _al_glGetConvolutionFilter +#define glGetConvolutionParameterfv _al_glGetConvolutionParameterfv +#define glGetConvolutionParameteriv _al_glGetConvolutionParameteriv +#define glGetSeparableFilter _al_glGetSeparableFilter +#define glSeparableFilter2D _al_glSeparableFilter2D +#define glGetHistogram _al_glGetHistogram +#define glGetHistogramParameterfv _al_glGetHistogramParameterfv +#define glGetHistogramParameteriv _al_glGetHistogramParameteriv +#define glGetMinmax _al_glGetMinmax +#define glGetMinmaxParameterfv _al_glGetMinmaxParameterfv +#define glGetMinmaxParameteriv _al_glGetMinmaxParameteriv +#define glHistogram _al_glHistogram +#define glMinmax _al_glMinmax +#define glResetHistogram _al_glResetHistogram +#define glResetMinmax _al_glResetMinmax +#endif + +#if defined _ALLEGRO_GL_VERSION_1_3 +#define glActiveTexture _al_glActiveTexture +#define glClientActiveTexture _al_glClientActiveTexture +#define glMultiTexCoord1d _al_glMultiTexCoord1d +#define glMultiTexCoord1dv _al_glMultiTexCoord1dv +#define glMultiTexCoord1f _al_glMultiTexCoord1f +#define glMultiTexCoord1fv _al_glMultiTexCoord1fv +#define glMultiTexCoord1i _al_glMultiTexCoord1i +#define glMultiTexCoord1iv _al_glMultiTexCoord1iv +#define glMultiTexCoord1s _al_glMultiTexCoord1s +#define glMultiTexCoord1sv _al_glMultiTexCoord1sv +#define glMultiTexCoord2d _al_glMultiTexCoord2d +#define glMultiTexCoord2dv _al_glMultiTexCoord2dv +#define glMultiTexCoord2f _al_glMultiTexCoord2f +#define glMultiTexCoord2fv _al_glMultiTexCoord2fv +#define glMultiTexCoord2i _al_glMultiTexCoord2i +#define glMultiTexCoord2iv _al_glMultiTexCoord2iv +#define glMultiTexCoord2s _al_glMultiTexCoord2s +#define glMultiTexCoord2sv _al_glMultiTexCoord2sv +#define glMultiTexCoord3d _al_glMultiTexCoord3d +#define glMultiTexCoord3dv _al_glMultiTexCoord3dv +#define glMultiTexCoord3f _al_glMultiTexCoord3f +#define glMultiTexCoord3fv _al_glMultiTexCoord3fv +#define glMultiTexCoord3i _al_glMultiTexCoord3i +#define glMultiTexCoord3iv _al_glMultiTexCoord3iv +#define glMultiTexCoord3s _al_glMultiTexCoord3s +#define glMultiTexCoord3sv _al_glMultiTexCoord3sv +#define glMultiTexCoord4d _al_glMultiTexCoord4d +#define glMultiTexCoord4dv _al_glMultiTexCoord4dv +#define glMultiTexCoord4f _al_glMultiTexCoord4f +#define glMultiTexCoord4fv _al_glMultiTexCoord4fv +#define glMultiTexCoord4i _al_glMultiTexCoord4i +#define glMultiTexCoord4iv _al_glMultiTexCoord4iv +#define glMultiTexCoord4s _al_glMultiTexCoord4s +#define glMultiTexCoord4sv _al_glMultiTexCoord4sv +#define glLoadTransposeMatrixf _al_glLoadTransposeMatrixf +#define glLoadTransposeMatrixd _al_glLoadTransposeMatrixd +#define glMultTransposeMatrixf _al_glMultTransposeMatrixf +#define glMultTransposeMatrixd _al_glMultTransposeMatrixd +#define glSampleCoverage _al_glSampleCoverage +#define glCompressedTexImage3D _al_glCompressedTexImage3D +#define glCompressedTexImage2D _al_glCompressedTexImage2D +#define glCompressedTexImage1D _al_glCompressedTexImage1D +#define glCompressedTexSubImage3D _al_glCompressedTexSubImage3D +#define glCompressedTexSubImage2D _al_glCompressedTexSubImage2D +#define glCompressedTexSubImage1D _al_glCompressedTexSubImage1D +#define glGetCompressedTexImage _al_glGetCompressedTexImage +#endif + +#if defined _ALLEGRO_GL_VERSION_1_4 +#define glBlendFuncSeparate _al_glBlendFuncSeparate +#define glFogCoordf _al_glFogCoordf +#define glFogCoordfv _al_glFogCoordfv +#define glFogCoordd _al_glFogCoordd +#define glFogCoorddv _al_glFogCoorddv +#define glFogCoordPointer _al_glFogCoordPointer +#define glMultiDrawArrays _al_glMultiDrawArrays +#define glMultiDrawElements _al_glMultiDrawElements +#define glPointParameterf _al_glPointParameterf +#define glPointParameterfv _al_glPointParameterfv +#define glPointParameteri _al_glPointParameteri +#define glPointParameteriv _al_glPointParameteriv +#define glSecondaryColor3b _al_glSecondaryColor3b +#define glSecondaryColor3bv _al_glSecondaryColor3bv +#define glSecondaryColor3d _al_glSecondaryColor3d +#define glSecondaryColor3dv _al_glSecondaryColor3dv +#define glSecondaryColor3f _al_glSecondaryColor3f +#define glSecondaryColor3fv _al_glSecondaryColor3fv +#define glSecondaryColor3i _al_glSecondaryColor3i +#define glSecondaryColor3iv _al_glSecondaryColor3iv +#define glSecondaryColor3s _al_glSecondaryColor3s +#define glSecondaryColor3sv _al_glSecondaryColor3sv +#define glSecondaryColor3ub _al_glSecondaryColor3ub +#define glSecondaryColor3ubv _al_glSecondaryColor3ubv +#define glSecondaryColor3ui _al_glSecondaryColor3ui +#define glSecondaryColor3uiv _al_glSecondaryColor3uiv +#define glSecondaryColor3us _al_glSecondaryColor3us +#define glSecondaryColor3usv _al_glSecondaryColor3usv +#define glSecondaryColorPointer _al_glSecondaryColorPointer +#define glWindowPos2d _al_glWindowPos2d +#define glWindowPos2dv _al_glWindowPos2dv +#define glWindowPos2f _al_glWindowPos2f +#define glWindowPos2fv _al_glWindowPos2fv +#define glWindowPos2i _al_glWindowPos2i +#define glWindowPos2iv _al_glWindowPos2iv +#define glWindowPos2s _al_glWindowPos2s +#define glWindowPos2sv _al_glWindowPos2sv +#define glWindowPos3d _al_glWindowPos3d +#define glWindowPos3dv _al_glWindowPos3dv +#define glWindowPos3f _al_glWindowPos3f +#define glWindowPos3fv _al_glWindowPos3fv +#define glWindowPos3i _al_glWindowPos3i +#define glWindowPos3iv _al_glWindowPos3iv +#define glWindowPos3s _al_glWindowPos3s +#define glWindowPos3sv _al_glWindowPos3sv +#endif + + +#if defined _ALLEGRO_GL_VERSION_1_5 +#define glBindBuffer _al_glBindBuffer +#define glDeleteBuffers _al_glDeleteBuffers +#define glGenBuffers _al_glGenBuffers +#define glIsBuffer _al_glIsBuffer +#define glBufferData _al_glBufferData +#define glBufferSubData _al_glBufferSubData +#define glGetBufferSubData _al_glGetBufferSubData +#define glMapBuffer _al_glMapBuffer +#define glUnmapBuffer _al_glUnmapBuffer +#define glGetBufferParameteriv _al_glGetBufferParameteriv +#define glGetBufferPointerv _al_glGetBufferPointerv +#define glGenQueries _al_glGenQueries +#define glDeleteQueries _al_glDeleteQueries +#define glIsQuery _al_glIsQuery +#define glBeginQuery _al_glBeginQuery +#define glEndQuery _al_glEndQuery +#define glGetQueryiv _al_glGetQueryiv +#define glGetQueryObjectiv _al_glGetQueryObjectiv +#define glGetQueryObjectuiv _al_glGetQueryObjectuiv +#endif + + +#if defined _ALLEGRO_GL_VERSION_2_0 +#define glBlendEquationSeparate _al_glBlendEquationSeparate +#define glCreateProgram _al_glCreateProgram +#define glCreateShader _al_glCreateShader +#define glDeleteProgram _al_glDeleteProgram +#define glDeleteShader _al_glDeleteShader +#define glAttachShader _al_glAttachShader +#define glDetachShader _al_glDetachShader +#define glShaderSource _al_glShaderSource +#define glCompileShader _al_glCompileShader +#define glIsProgram _al_glIsProgram +#define glIsShader _al_glIsShader +#define glLinkProgram _al_glLinkProgram +#define glUseProgram _al_glUseProgram +#define glValidateProgram _al_glValidateProgram +#define glUniform1f _al_glUniform1f +#define glUniform2f _al_glUniform2f +#define glUniform3f _al_glUniform3f +#define glUniform4f _al_glUniform4f +#define glUniform1i _al_glUniform1i +#define glUniform2i _al_glUniform2i +#define glUniform3i _al_glUniform3i +#define glUniform4i _al_glUniform4i +#define glUniform1fv _al_glUniform1fv +#define glUniform2fv _al_glUniform2fv +#define glUniform3fv _al_glUniform3fv +#define glUniform4fv _al_glUniform4fv +#define glUniform1iv _al_glUniform1iv +#define glUniform2iv _al_glUniform2iv +#define glUniform3iv _al_glUniform3iv +#define glUniform4iv _al_glUniform4iv +#define glUniformMatrix2fv _al_glUniformMatrix2fv +#define glUniformMatrix3fv _al_glUniformMatrix3fv +#define glUniformMatrix4fv _al_glUniformMatrix4fv +#define glGetShaderfv _al_glGetShaderfv +#define glGetShaderiv _al_glGetShaderiv +#define glGetProgramfv _al_glGetProgramfv +#define glGetProgramiv _al_glGetProgramiv +#define glGetShaderInfoLog _al_glGetShaderInfoLog +#define glGetProgramInfoLog _al_glGetProgramInfoLog +#define glGetAttachedShaders _al_glGetAttachedShaders +#define glGetUniformLocation _al_glGetUniformLocation +#define glGetActiveUniform _al_glGetActiveUniform +#define glGetUniformfv _al_glGetUniformfv +#define glGetUniformiv _al_glGetUniformiv +#define glGetShaderSource _al_glGetShaderSource +#define glVertexAttrib1f _al_glVertexAttrib1f +#define glVertexAttrib1s _al_glVertexAttrib1s +#define glVertexAttrib1d _al_glVertexAttrib1d +#define glVertexAttrib2f _al_glVertexAttrib2f +#define glVertexAttrib2s _al_glVertexAttrib2s +#define glVertexAttrib2d _al_glVertexAttrib2d +#define glVertexAttrib3f _al_glVertexAttrib3f +#define glVertexAttrib3s _al_glVertexAttrib3s +#define glVertexAttrib3d _al_glVertexAttrib3d +#define glVertexAttrib4f _al_glVertexAttrib4f +#define glVertexAttrib4s _al_glVertexAttrib4s +#define glVertexAttrib4d _al_glVertexAttrib4d +#define glVertexAttrib4Nub _al_glVertexAttrib4Nub +#define glVertexAttrib1fv _al_glVertexAttrib1fv +#define glVertexAttrib1sv _al_glVertexAttrib1sv +#define glVertexAttrib1dv _al_glVertexAttrib1dv +#define glVertexAttrib2fv _al_glVertexAttrib2fv +#define glVertexAttrib2sv _al_glVertexAttrib2sv +#define glVertexAttrib2dv _al_glVertexAttrib2dv +#define glVertexAttrib3fv _al_glVertexAttrib3fv +#define glVertexAttrib3sv _al_glVertexAttrib3sv +#define glVertexAttrib3dv _al_glVertexAttrib3dv +#define glVertexAttrib4fv _al_glVertexAttrib4fv +#define glVertexAttrib4sv _al_glVertexAttrib4sv +#define glVertexAttrib4dv _al_glVertexAttrib4dv +#define glVertexAttrib4iv _al_glVertexAttrib4iv +#define glVertexAttrib4bv _al_glVertexAttrib4bv +#define glVertexAttrib4ubv _al_glVertexAttrib4ubv +#define glVertexAttrib4usv _al_glVertexAttrib4usv +#define glVertexAttrib4uiv _al_glVertexAttrib4uiv +#define glVertexAttrib4Nbv _al_glVertexAttrib4Nbv +#define glVertexAttrib4Nsv _al_glVertexAttrib4Nsv +#define glVertexAttrib4Niv _al_glVertexAttrib4Niv +#define glVertexAttrib4Nubv _al_glVertexAttrib4Nubv +#define glVertexAttrib4Nusv _al_glVertexAttrib4Nusv +#define glVertexAttrib4Nuiv _al_glVertexAttrib4Nuiv +#define glVertexAttribPointer _al_glVertexAttribPointer +#define glEnableVertexAttribArray _al_glEnableVertexAttribArray +#define glDisableVertexAttribArray _al_glDisableVertexAttribArray + +#define glBindAttribLocation _al_glBindAttribLocation +#define glGetActiveAttrib _al_glGetActiveAttrib +#define glGetAttribLocation _al_glGetAttribLocation +#define glGetVertexAttribdv _al_glGetVertexAttribdv +#define glGetVertexAttribfv _al_glGetVertexAttribfv +#define glGetVertexAttribiv _al_glGetVertexAttribiv +#define glGetVertexAttribPointerv _al_glGetVertexAttribPointerv + +#define glDrawBuffers _al_glDrawBuffers + +#define glStencilOpSeparate _al_glStencilOpSeparate +#define glStencilFuncSeparate _al_glStencilFuncSeparate +#define glStencilMaskSeparate _al_glStencilMaskSeparate + +#endif + + +#if defined _ALLEGRO_GL_VERSION_2_1 +#define glUniformMatrix2x3fv _al_glUniformMatrix2x3fv +#define glUniformMatrix3x2fv _al_glUniformMatrix3x2fv +#define glUniformMatrix2x4fv _al_glUniformMatrix2x4fv +#define glUniformMatrix4x2fv _al_glUniformMatrix4x2fv +#define glUniformMatrix3x4fv _al_glUniformMatrix3x4fv +#define glUniformMatrix4x3fv _al_glUniformMatrix4x3fv +#endif + +#if defined _ALLEGRO_GL_VERSION_3_0 +/*OpenGL3.0alsoreusesentrypointsfromtheseextensions:*/ +/*ARB_framebuffer_object*/ +/*ARB_map_buffer_range*/ +/*ARB_vertex_array_object*/ +#define glColorMaski _al_glColorMaski +#define glGetBooleani_v _al_glGetBooleani_v +#define glGetIntegeri_v _al_glGetIntegeri_v +#define glEnablei _al_glEnablei +#define glDisablei _al_glDisablei +#define glIsEnabledi _al_glIsEnabledi +#define glBeginTransformFeedback _al_glBeginTransformFeedback +#define glEndTransformFeedback _al_glEndTransformFeedback +#define glBindBufferRange _al_glBindBufferRange +#define glBindBufferBase _al_glBindBufferBase +#define glTransformFeedbackVaryings _al_glTransformFeedbackVaryings +#define glGetTransformFeedbackVarying _al_glGetTransformFeedbackVarying +#define glClampColor _al_glClampColor +#define glBeginConditionalRender _al_glBeginConditionalRender +#define glEndConditionalRender _al_glEndConditionalRender +#define glVertexAttribI1i _al_glVertexAttribI1i +#define glVertexAttribI2i _al_glVertexAttribI2i +#define glVertexAttribI3i _al_glVertexAttribI3i +#define glVertexAttribI4i _al_glVertexAttribI4i +#define glVertexAttribI1ui _al_glVertexAttribI1ui +#define glVertexAttribI2ui _al_glVertexAttribI2ui +#define glVertexAttribI3ui _al_glVertexAttribI3ui +#define glVertexAttribI4ui _al_glVertexAttribI4ui +#define glVertexAttribI1iv _al_glVertexAttribI1iv +#define glVertexAttribI2iv _al_glVertexAttribI2iv +#define glVertexAttribI3iv _al_glVertexAttribI3iv +#define glVertexAttribI4iv _al_glVertexAttribI4iv +#define glVertexAttribI1uiv _al_glVertexAttribI1uiv +#define glVertexAttribI2uiv _al_glVertexAttribI2uiv +#define glVertexAttribI3uiv _al_glVertexAttribI3uiv +#define glVertexAttribI4uiv _al_glVertexAttribI4uiv +#define glVertexAttribI4bv _al_glVertexAttribI4bv +#define glVertexAttribI4sv _al_glVertexAttribI4sv +#define glVertexAttribI4ubv _al_glVertexAttribI4ubv +#define glVertexAttribI4usv _al_glVertexAttribI4usv +#define glVertexAttribIPointer _al_glVertexAttribIPointer +#define glGetVertexAttribIiv _al_glGetVertexAttribIiv +#define glGetVertexAttribIuiv _al_glGetVertexAttribIuiv +#define glGetUniformuiv _al_glGetUniformuiv +#define glBindFragDataLocation _al_glBindFragDataLocation +#define glGetFragDataLocation _al_glGetFragDataLocation +#define glUniform1ui _al_glUniform1ui +#define glUniform2ui _al_glUniform2ui +#define glUniform3ui _al_glUniform3ui +#define glUniform4ui _al_glUniform4ui +#define glUniform1uiv _al_glUniform1uiv +#define glUniform2uiv _al_glUniform2uiv +#define glUniform3uiv _al_glUniform3uiv +#define glUniform4uiv _al_glUniform4uiv +#define glTexParameterIiv _al_glTexParameterIiv +#define glTexParameterIuiv _al_glTexParameterIuiv +#define glGetTexParameterIiv _al_glGetTexParameterIiv +#define glGetTexParameterIuiv _al_glGetTexParameterIuiv +#define glClearBufferiv _al_glClearBufferiv +#define glClearBufferuiv _al_glClearBufferuiv +#define glClearBufferfv _al_glClearBufferfv +#define glClearBufferfi _al_glClearBufferfi +#define glGetStringi _al_glGetStringi +#endif + + +#if defined _ALLEGRO_GL_VERSION_3_1 +/*OpenGL3.1alsoreusesentrypointsfromtheseextensions:*/ +/*ARB_copy_buffer*/ +/*ARB_uniform_buffer_object*/ +#define glDrawArraysInstanced _al_glDrawArraysInstanced +#define glDrawElementsInstanced _al_glDrawElementsInstanced +#define glTexBuffer _al_glTexBuffer +#define glPrimitiveRestartIndex _al_glPrimitiveRestartIndex +#endif + +#if defined _ALLEGRO_GL_VERSION_3_2 +/*OpenGL3.2alsoreusesentrypointsfromtheseextensions:*/ +/*ARB_draw_elements_base_vertex*/ +/*ARB_provoking_vertex*/ +/*ARB_sync*/ +/*ARB_texture_multisample*/ +#define glGetInteger64i_v _al_glGetInteger64i_v +#define glGetBufferParameteri64v _al_glGetBufferParameteri64v +#define glProgramParameteri _al_glProgramParameteri +#define glFramebufferTexture _al_glFramebufferTexture +#endif + +#if defined _ALLEGRO_GL_VERSION_3_3 +/*OpenGL3.3alsoreusesentrypointsfromtheseextensions:*/ +/*ARB_blend_func_extended*/ +/*ARB_sampler_objects*/ +/*ARB_explicit_attrib_location,butithasnone*/ +/*ARB_occlusion_query2(noentrypoints)*/ +/*ARB_shader_bit_encoding(noentrypoints)*/ +/*ARB_texture_rgb10_a2ui(noentrypoints)*/ +/*ARB_texture_swizzle(noentrypoints)*/ +/*ARB_timer_query*/ +/*ARB_vertex_type_2_10_10_10_rev*/ +#endif + +#if defined _ALLEGRO_GL_VERSION_4_3 +#define glClearBufferData _al_glClearBufferData +#define glClearBufferSubData _al_glClearBufferSubData +#define glDispatchCompute _al_glDispatchCompute +#define glDispatchComputeIndirect _al_glDispatchComputeIndirect +#define glCopyImageSubData _al_glCopyImageSubData +#define glFramebufferParameteri _al_glFramebufferParameteri +#define glGetFramebufferParameteriv _al_glGetFramebufferParameteriv +#define glGetInternalformati64v _al_glGetInternalformati64v +#define glInvalidateTexSubImage _al_glInvalidateTexSubImage +#define glInvalidateTexImage _al_glInvalidateTexImage +#define glInvalidateBufferSubData _al_glInvalidateBufferSubData +#define glInvalidateBufferData _al_glInvalidateBufferData +#define glInvalidateFramebuffer _al_glInvalidateFramebuffer +#define glInvalidateSubFramebuffer _al_glInvalidateSubFramebuffer +#define glMultiDrawArraysIndirect _al_glMultiDrawArraysIndirect +#define glMultiDrawElementsIndirect _al_glMultiDrawElementsIndirect +#define glGetProgramInterfaceiv _al_glGetProgramInterfaceiv +#define glGetProgramResourceIndex _al_glGetProgramResourceIndex +#define glGetProgramResourceName _al_glGetProgramResourceName +#define glGetProgramResourceiv _al_glGetProgramResourceiv +#define glGetProgramResourceLocation _al_glGetProgramResourceLocation +#define glGetProgramResourceLocationIndex _al_glGetProgramResourceLocationIndex +#define glShaderStorageBlockBinding _al_glShaderStorageBlockBinding +#define glTexBufferRange _al_glTexBufferRange +#define glTexStorage2DMultisample _al_glTexStorage2DMultisample +#define glTexStorage3DMultisample _al_glTexStorage3DMultisample +#define glTextureView _al_glTextureView +#define glBindVertexBuffer _al_glBindVertexBuffer +#define glVertexAttribFormat _al_glVertexAttribFormat +#define glVertexAttribIFormat _al_glVertexAttribIFormat +#define glVertexAttribLFormat _al_glVertexAttribLFormat +#define glVertexAttribBinding _al_glVertexAttribBinding +#define glVertexBindingDivisor _al_glVertexBindingDivisor +#define glDebugMessageControl _al_glDebugMessageControl +#define glDebugMessageInsert _al_glDebugMessageInsert +#define glDebugMessageCallback _al_glDebugMessageCallback +#define glGetDebugMessageLog _al_glGetDebugMessageLog +#define glPushDebugGroup _al_glPushDebugGroup +#define glPopDebugGroup _al_glPopDebugGroup +#define glObjectLabel _al_glObjectLabel +#define glGetObjectLabel _al_glGetObjectLabel +#define glObjectPtrLabel _al_glObjectPtrLabel +#define glGetObjectPtrLabel _al_glGetObjectPtrLabel +#endif /* GL_VERSION_4_3 */ + + +/**/ +/**/ + +#ifdef _ALLEGRO_GL_ARB_multitexture +#define glActiveTextureARB _al_glActiveTextureARB +#define glClientActiveTextureARB _al_glClientActiveTextureARB +#define glMultiTexCoord1dARB _al_glMultiTexCoord1dARB +#define glMultiTexCoord1dvARB _al_glMultiTexCoord1dvARB +#define glMultiTexCoord1fARB _al_glMultiTexCoord1fARB +#define glMultiTexCoord1fvARB _al_glMultiTexCoord1fvARB +#define glMultiTexCoord1iARB _al_glMultiTexCoord1iARB +#define glMultiTexCoord1ivARB _al_glMultiTexCoord1ivARB +#define glMultiTexCoord1sARB _al_glMultiTexCoord1sARB +#define glMultiTexCoord1svARB _al_glMultiTexCoord1svARB +#define glMultiTexCoord2dARB _al_glMultiTexCoord2dARB +#define glMultiTexCoord2dvARB _al_glMultiTexCoord2dvARB +#define glMultiTexCoord2fARB _al_glMultiTexCoord2fARB +#define glMultiTexCoord2fvARB _al_glMultiTexCoord2fvARB +#define glMultiTexCoord2iARB _al_glMultiTexCoord2iARB +#define glMultiTexCoord2ivARB _al_glMultiTexCoord2ivARB +#define glMultiTexCoord2sARB _al_glMultiTexCoord2sARB +#define glMultiTexCoord2svARB _al_glMultiTexCoord2svARB +#define glMultiTexCoord3dARB _al_glMultiTexCoord3dARB +#define glMultiTexCoord3dvARB _al_glMultiTexCoord3dvARB +#define glMultiTexCoord3fARB _al_glMultiTexCoord3fARB +#define glMultiTexCoord3fvARB _al_glMultiTexCoord3fvARB +#define glMultiTexCoord3iARB _al_glMultiTexCoord3iARB +#define glMultiTexCoord3ivARB _al_glMultiTexCoord3ivARB +#define glMultiTexCoord3sARB _al_glMultiTexCoord3sARB +#define glMultiTexCoord3svARB _al_glMultiTexCoord3svARB +#define glMultiTexCoord4dARB _al_glMultiTexCoord4dARB +#define glMultiTexCoord4dvARB _al_glMultiTexCoord4dvARB +#define glMultiTexCoord4fARB _al_glMultiTexCoord4fARB +#define glMultiTexCoord4fvARB _al_glMultiTexCoord4fvARB +#define glMultiTexCoord4iARB _al_glMultiTexCoord4iARB +#define glMultiTexCoord4ivARB _al_glMultiTexCoord4ivARB +#define glMultiTexCoord4sARB _al_glMultiTexCoord4sARB +#define glMultiTexCoord4svARB _al_glMultiTexCoord4svARB +#endif + +#if defined _ALLEGRO_GL_ARB_transpose_matrix +#define glLoadTransposeMatrixfARB _al_glLoadTransposeMatrixfARB +#define glLoadTransposeMatrixdARB _al_glLoadTransposeMatrixdARB +#define glMultTransposeMatrixfARB _al_glMultTransposeMatrixfARB +#define glMultTransposeMatrixdARB _al_glMultTransposeMatrixdARB +#endif + +#if defined _ALLEGRO_GL_ARB_multisample +#define glSampleCoverageARB _al_glSampleCoverageARB +#endif + +#if defined _ALLEGRO_GL_ARB_texture_compression +#define glCompressedTexImage3DARB _al_glCompressedTexImage3DARB +#define glCompressedTexImage2DARB _al_glCompressedTexImage2DARB +#define glCompressedTexImage1DARB _al_glCompressedTexImage1DARB +#define glCompressedTexSubImage3DARB _al_glCompressedTexSubImage3DARB +#define glCompressedTexSubImage2DARB _al_glCompressedTexSubImage2DARB +#define glCompressedTexSubImage1DARB _al_glCompressedTexSubImage1DARB +#define glGetCompressedTexImageARB _al_glGetCompressedTexImageARB +#endif + +#if defined _ALLEGRO_GL_ARB_point_parameters +#define glPointParameterfARB _al_glPointParameterfARB +#define glPointParameterfvARB _al_glPointParameterfvARB +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_blend +#define glWeightbvARB _al_glWeightbvARB +#define glWeightsvARB _al_glWeightsvARB +#define glWeightivARB _al_glWeightivARB +#define glWeightfvARB _al_glWeightfvARB +#define glWeightdvARB _al_glWeightdvARB +#define glWeightubvARB _al_glWeightubvARB +#define glWeightusvARB _al_glWeightusvARB +#define glWeightuivARB _al_glWeightuivARB +#define glWeightPointerARB _al_glWeightPointerARB +#define glVertexBlendARB _al_glVertexBlendARB +#endif + +#if defined _ALLEGRO_GL_ARB_matrix_palette +#define glCurrentPaletteMatrixARB _al_glCurrentPaletteMatrixARB +#define glMatrixIndexubvARB _al_glMatrixIndexubvARB +#define glMatrixIndexusvARB _al_glMatrixIndexusvARB +#define glMatrixIndexuivARB _al_glMatrixIndexuivARB +#define glMatrixIndexPointerARB _al_glMatrixIndexPointerARB +#endif + +#if defined _ALLEGRO_GL_ARB_window_pos +#define glWindowPos2dARB _al_glWindowPos2dARB +#define glWindowPos2dvARB _al_glWindowPos2dvARB +#define glWindowPos2fARB _al_glWindowPos2fARB +#define glWindowPos2fvARB _al_glWindowPos2fvARB +#define glWindowPos2iARB _al_glWindowPos2iARB +#define glWindowPos2ivARB _al_glWindowPos2ivARB +#define glWindowPos2sARB _al_glWindowPos2sARB +#define glWindowPos2svARB _al_glWindowPos2svARB +#define glWindowPos3dARB _al_glWindowPos3dARB +#define glWindowPos3dvARB _al_glWindowPos3dvARB +#define glWindowPos3fARB _al_glWindowPos3fARB +#define glWindowPos3fvARB _al_glWindowPos3fvARB +#define glWindowPos3iARB _al_glWindowPos3iARB +#define glWindowPos3ivARB _al_glWindowPos3ivARB +#define glWindowPos3sARB _al_glWindowPos3sARB +#define glWindowPos3svARB _al_glWindowPos3svARB +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_program +#define glVertexAttrib1dARB _al_glVertexAttrib1dARB +#define glVertexAttrib1dvARB _al_glVertexAttrib1dvARB +#define glVertexAttrib1fARB _al_glVertexAttrib1fARB +#define glVertexAttrib1fvARB _al_glVertexAttrib1fvARB +#define glVertexAttrib1sARB _al_glVertexAttrib1sARB +#define glVertexAttrib1svARB _al_glVertexAttrib1svARB +#define glVertexAttrib2dARB _al_glVertexAttrib2dARB +#define glVertexAttrib2dvARB _al_glVertexAttrib2dvARB +#define glVertexAttrib2fARB _al_glVertexAttrib2fARB +#define glVertexAttrib2fvARB _al_glVertexAttrib2fvARB +#define glVertexAttrib2sARB _al_glVertexAttrib2sARB +#define glVertexAttrib2svARB _al_glVertexAttrib2svARB +#define glVertexAttrib3dARB _al_glVertexAttrib3dARB +#define glVertexAttrib3dvARB _al_glVertexAttrib3dvARB +#define glVertexAttrib3fARB _al_glVertexAttrib3fARB +#define glVertexAttrib3fvARB _al_glVertexAttrib3fvARB +#define glVertexAttrib3sARB _al_glVertexAttrib3sARB +#define glVertexAttrib3svARB _al_glVertexAttrib3svARB +#define glVertexAttrib4NbvARB _al_glVertexAttrib4NbvARB +#define glVertexAttrib4NivARB _al_glVertexAttrib4NivARB +#define glVertexAttrib4NsvARB _al_glVertexAttrib4NsvARB +#define glVertexAttrib4NubARB _al_glVertexAttrib4NubARB +#define glVertexAttrib4NubvARB _al_glVertexAttrib4NubvARB +#define glVertexAttrib4NuivARB _al_glVertexAttrib4NuivARB +#define glVertexAttrib4NusvARB _al_glVertexAttrib4NusvARB +#define glVertexAttrib4bvARB _al_glVertexAttrib4bvARB +#define glVertexAttrib4dARB _al_glVertexAttrib4dARB +#define glVertexAttrib4dvARB _al_glVertexAttrib4dvARB +#define glVertexAttrib4fARB _al_glVertexAttrib4fARB +#define glVertexAttrib4fvARB _al_glVertexAttrib4fvARB +#define glVertexAttrib4ivARB _al_glVertexAttrib4ivARB +#define glVertexAttrib4sARB _al_glVertexAttrib4sARB +#define glVertexAttrib4svARB _al_glVertexAttrib4svARB +#define glVertexAttrib4ubvARB _al_glVertexAttrib4ubvARB +#define glVertexAttrib4uivARB _al_glVertexAttrib4uivARB +#define glVertexAttrib4usvARB _al_glVertexAttrib4usvARB +#define glVertexAttribPointerARB _al_glVertexAttribPointerARB +#define glEnableVertexAttribArrayARB _al_glEnableVertexAttribArrayARB +#define glDisableVertexAttribArrayARB _al_glDisableVertexAttribArrayARB +#define glProgramStringARB _al_glProgramStringARB +#define glBindProgramARB _al_glBindProgramARB +#define glDeleteProgramsARB _al_glDeleteProgramsARB +#define glGenProgramsARB _al_glGenProgramsARB +#define glProgramEnvParameter4dARB _al_glProgramEnvParameter4dARB +#define glProgramEnvParameter4dvARB _al_glProgramEnvParameter4dvARB +#define glProgramEnvParameter4fARB _al_glProgramEnvParameter4fARB +#define glProgramEnvParameter4fvARB _al_glProgramEnvParameter4fvARB +#define glProgramLocalParameter4dARB _al_glProgramLocalParameter4dARB +#define glProgramLocalParameter4dvARB _al_glProgramLocalParameter4dvARB +#define glProgramLocalParameter4fARB _al_glProgramLocalParameter4fARB +#define glProgramLocalParameter4fvARB _al_glProgramLocalParameter4fvARB +#define glGetProgramEnvParameterdvARB _al_glGetProgramEnvParameterdvARB +#define glGetProgramEnvParameterfvARB _al_glGetProgramEnvParameterfvARB +#define glGetProgramLocalParameterdvARB _al_glGetProgramLocalParameterdvARB +#define glGetProgramLocalParameterfvARB _al_glGetProgramLocalParameterfvARB +#define glGetProgramivARB _al_glGetProgramivARB +#define glGetProgramStringARB _al_glGetProgramStringARB +#define glGetVertexAttribdvARB _al_glGetVertexAttribdvARB +#define glGetVertexAttribfvARB _al_glGetVertexAttribfvARB +#define glGetVertexAttribivARB _al_glGetVertexAttribivARB +#define glGetVertexAttribPointervARB _al_glGetVertexAttribPointervARB +#define glIsProgramARB _al_glIsProgramARB +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_buffer_object +#define glBindBufferARB _al_glBindBufferARB +#define glDeleteBuffersARB _al_glDeleteBuffersARB +#define glGenBuffersARB _al_glGenBuffersARB +#define glIsBufferARB _al_glIsBufferARB +#define glBufferDataARB _al_glBufferDataARB +#define glBufferSubDataARB _al_glBufferSubDataARB +#define glGetBufferSubDataARB _al_glGetBufferSubDataARB +#define glMapBufferARB _al_glMapBufferARB +#define glUnmapBufferARB _al_glUnmapBufferARB +#define glGetBufferParameterivARB _al_glGetBufferParameterivARB +#define glGetBufferPointervARB _al_glGetBufferPointervARB +#endif + +#if defined _ALLEGRO_GL_ARB_occlusion_query +#define glGenQueriesARB _al_glGenQueriesARB +#define glDeleteQueriesARB _al_glDeleteQueriesARB +#define glIsQueryARB _al_glIsQueryARB +#define glBeginQueryARB _al_glBeginQueryARB +#define glEndQueryARB _al_glEndQueryARB +#define glGetQueryivARB _al_glGetQueryivARB +#define glGetQueryObjectivARB _al_glGetQueryObjectivARB +#define glGetQueryObjectuivARB _al_glGetQueryObjectuivARB +#endif + +#if defined _ALLEGRO_GL_ARB_shader_objects +#define glDeleteObjectARB _al_glDeleteObjectARB +#define glGetHandleARB _al_glGetHandleARB +#define glDetachObjectARB _al_glDetachObjectARB +#define glCreateShaderObjectARB _al_glCreateShaderObjectARB +#define glShaderSourceARB _al_glShaderSourceARB +#define glCompileShaderARB _al_glCompileShaderARB +#define glCreateProgramObjectARB _al_glCreateProgramObjectARB +#define glAttachObjectARB _al_glAttachObjectARB +#define glLinkProgramARB _al_glLinkProgramARB +#define glUseProgramObjectARB _al_glUseProgramObjectARB +#define glValidateProgramARB _al_glValidateProgramARB +#define glUniform1fARB _al_glUniform1fARB +#define glUniform2fARB _al_glUniform2fARB +#define glUniform3fARB _al_glUniform3fARB +#define glUniform4fARB _al_glUniform4fARB +#define glUniform1iARB _al_glUniform1iARB +#define glUniform2iARB _al_glUniform2iARB +#define glUniform3iARB _al_glUniform3iARB +#define glUniform4iARB _al_glUniform4iARB +#define glUniform1fvARB _al_glUniform1fvARB +#define glUniform2fvARB _al_glUniform2fvARB +#define glUniform3fvARB _al_glUniform3fvARB +#define glUniform4fvARB _al_glUniform4fvARB +#define glUniform1ivARB _al_glUniform1ivARB +#define glUniform2ivARB _al_glUniform2ivARB +#define glUniform3ivARB _al_glUniform3ivARB +#define glUniform4ivARB _al_glUniform4ivARB +#define glUniformMatrix2fvARB _al_glUniformMatrix2fvARB +#define glUniformMatrix3fvARB _al_glUniformMatrix3fvARB +#define glUniformMatrix4fvARB _al_glUniformMatrix4fvARB +#define glGetObjectParameterfvARB _al_glGetObjectParameterfvARB +#define glGetObjectParameterivARB _al_glGetObjectParameterivARB +#define glGetInfoLogARB _al_glGetInfoLogARB +#define glGetAttachedObjectsARB _al_glGetAttachedObjectsARB +#define glGetUniformLocationARB _al_glGetUniformLocationARB +#define glGetActiveUniformARB _al_glGetActiveUniformARB +#define glGetUniformfvARB _al_glGetUniformfvARB +#define glGetUniformivARB _al_glGetUniformivARB +#define glGetShaderSourceARB _al_glGetShaderSourceARB +#endif + +#ifdef _ALLEGRO_GL_ARB_vertex_shader +#ifndef GL_ARB_vertex_program +#define glVertexAttrib1fARB _al_glVertexAttrib1fARB +#define glVertexAttrib1sARB _al_glVertexAttrib1sARB +#define glVertexAttrib1dARB _al_glVertexAttrib1dARB +#define glVertexAttrib2fARB _al_glVertexAttrib2fARB +#define glVertexAttrib2sARB _al_glVertexAttrib2sARB +#define glVertexAttrib2dARB _al_glVertexAttrib2dARB +#define glVertexAttrib3fARB _al_glVertexAttrib3fARB +#define glVertexAttrib3sARB _al_glVertexAttrib3sARB +#define glVertexAttrib3dARB _al_glVertexAttrib3dARB +#define glVertexAttrib4fARB _al_glVertexAttrib4fARB +#define glVertexAttrib4sARB _al_glVertexAttrib4sARB +#define glVertexAttrib4dARB _al_glVertexAttrib4dARB +#define glVertexAttrib4NubARB _al_glVertexAttrib4NubARB +#define glVertexAttrib1fvARB _al_glVertexAttrib1fvARB +#define glVertexAttrib1svARB _al_glVertexAttrib1svARB +#define glVertexAttrib1dvARB _al_glVertexAttrib1dvARB +#define glVertexAttrib2fvARB _al_glVertexAttrib2fvARB +#define glVertexAttrib2svARB _al_glVertexAttrib2svARB +#define glVertexAttrib2dvARB _al_glVertexAttrib2dvARB +#define glVertexAttrib3fvARB _al_glVertexAttrib3fvARB +#define glVertexAttrib3svARB _al_glVertexAttrib3svARB +#define glVertexAttrib3dvARB _al_glVertexAttrib3dvARB +#define glVertexAttrib4fvARB _al_glVertexAttrib4fvARB +#define glVertexAttrib4svARB _al_glVertexAttrib4svARB +#define glVertexAttrib4dvARB _al_glVertexAttrib4dvARB +#define glVertexAttrib4ivARB _al_glVertexAttrib4ivARB +#define glVertexAttrib4bvARB _al_glVertexAttrib4bvARB +#define glVertexAttrib4ubvARB _al_glVertexAttrib4ubvARB +#define glVertexAttrib4usvARB _al_glVertexAttrib4usvARB +#define glVertexAttrib4uivARB _al_glVertexAttrib4uivARB +#define glVertexAttrib4NbvARB _al_glVertexAttrib4NbvARB +#define glVertexAttrib4NsvARB _al_glVertexAttrib4NsvARB +#define glVertexAttrib4NivARB _al_glVertexAttrib4NivARB +#define glVertexAttrib4NubvARB _al_glVertexAttrib4NubvARB +#define glVertexAttrib4NusvARB _al_glVertexAttrib4NusvARB +#define glVertexAttrib4NuivARB _al_glVertexAttrib4NuivARB +#define glVertexAttribPointerARB _al_glVertexAttribPointerARB +#define glEnableVertexAttribArrayARB _al_glEnableVertexAttribArrayARB +#define glDisableVertexAttribArrayARB _al_glDisableVertexAttribArrayARB +#endif +#define glBindAttribLocationARB _al_glBindAttribLocationARB +#define glGetActiveAttribARB _al_glGetActiveAttribARB +#define glGetAttribLocationARB _al_glGetAttribLocationARB +#ifndef GL_ARB_vertex_program +#define glGetVertexAttribdvARB _al_glGetVertexAttribdvARB +#define glGetVertexAttribfvARB _al_glGetVertexAttribfvARB +#define glGetVertexAttribivARB _al_glGetVertexAttribivARB +#define glGetVertexAttribPointervARB _al_glGetVertexAttribPointervARB +#endif +#endif + +#if defined _ALLEGRO_GL_ARB_draw_buffers +#define glDrawBuffersARB _al_glDrawBuffersARB +#endif + +#if defined _ALLEGRO_GL_ARB_color_buffer_float +#define glClampColorARB _al_glClampColorARB +#endif + +#if defined _ALLEGRO_GL_ARB_draw_instanced +#define glDrawArraysInstancedARB _al_glDrawArraysInstancedARB +#define glDrawElementsInstancedARB _al_glDrawElementsInstancedARB +#endif + +#if defined _ALLEGRO_GL_ARB_framebuffer_object +#define glIsRenderbuffer _al_glIsRenderbuffer +#define glBindRenderbuffer _al_glBindRenderbuffer +#define glDeleteRenderbuffers _al_glDeleteRenderbuffers +#define glGenRenderbuffers _al_glGenRenderbuffers +#define glRenderbufferStorage _al_glRenderbufferStorage +#define glGetRenderbufferParameteriv _al_glGetRenderbufferParameteriv +#define glIsFramebuffer _al_glIsFramebuffer +#define glBindFramebuffer _al_glBindFramebuffer +#define glDeleteFramebuffers _al_glDeleteFramebuffers +#define glGenFramebuffers _al_glGenFramebuffers +#define glCheckFramebufferStatus _al_glCheckFramebufferStatus +#define glFramebufferTexture1D _al_glFramebufferTexture1D +#define glFramebufferTexture2D _al_glFramebufferTexture2D +#define glFramebufferTexture3D _al_glFramebufferTexture3D +#define glFramebufferRenderbuffer _al_glFramebufferRenderbuffer +#define glGetFramebufferAttachmentParameteriv _al_glGetFramebufferAttachmentParameteriv +#define glGenerateMipmap _al_glGenerateMipmap +#define glBlitFramebuffer _al_glBlitFramebuffer +#define glRenderbufferStorageMultisample _al_glRenderbufferStorageMultisample +#define glFramebufferTextureLayer _al_glFramebufferTextureLayer +#endif + +#if defined _ALLEGRO_GL_ARB_geometry_shader4 +#define glProgramParameteriARB _al_glProgramParameteriARB +#define glFramebufferTextureARB _al_glFramebufferTextureARB +#define glFramebufferTextureLayerARB _al_glFramebufferTextureLayerARB +#define glFramebufferTextureFaceARB _al_glFramebufferTextureFaceARB +#endif + +#if defined _ALLEGRO_GL_ARB_instanced_arrays +#define glVertexAttribDivisor _al_glVertexAttribDivisor +#endif + +#if defined _ALLEGRO_GL_ARB_map_buffer_range +#define glMapBufferRange _al_glMapBufferRange +#define glFlushMappedBufferRange _al_glFlushMappedBufferRange +#endif + +#if defined _ALLEGRO_GL_ARB_texture_buffer_object +#define glTexBufferARB _al_glTexBufferARB +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_array_object +#define glBindVertexArray _al_glBindVertexArray +#define glDeleteVertexArrays _al_glDeleteVertexArrays +#define glGenVertexArrays _al_glGenVertexArrays +#define glIsVertexArray _al_glIsVertexArray +#endif + +#if defined _ALLEGRO_GL_ARB_uniform_buffer_object +#define glGetUniformIndices _al_glGetUniformIndices +#define glGetActiveUniformsiv _al_glGetActiveUniformsiv +#define glGetActiveUniformName _al_glGetActiveUniformName +#define glGetUniformBlockIndex _al_glGetUniformBlockIndex +#define glGetActiveUniformBlockiv _al_glGetActiveUniformBlockiv +#define glGetActiveUniformBlockName _al_glGetActiveUniformBlockName +#define glUniformBlockBinding _al_glUniformBlockBinding +#endif + +#if defined _ALLEGRO_GL_ARB_copy_buffer +#define glCopyBufferSubData _al_glCopyBufferSubData +#endif + + +#if defined _ALLEGRO_GL_ARB_draw_elements_base_vertex +#define glDrawElementsBaseVertex _al_glDrawElementsBaseVertex +#define glDrawRangeElementsBaseVertex _al_glDrawRangeElementsBaseVertex +#define glDrawElementsInstancedBaseVertex _al_glDrawElementsInstancedBaseVertex +#define glMultiDrawElementsBaseVertex _al_glMultiDrawElementsBaseVertex +#endif + +#if defined _ALLEGRO_GL_ARB_provoking_vertex +#define glProvokingVertex _al_glProvokingVertex +#endif + +#if defined _ALLEGRO_GL_ARB_sync +#define glFenceSync _al_glFenceSync +#define glIsSync _al_glIsSync +#define glDeleteSync _al_glDeleteSync +#define glClientWaitSync _al_glClientWaitSync +#define glWaitSync _al_glWaitSync +#define glGetInteger64v _al_glGetInteger64v +#define glGetSynciv _al_glGetSynciv +#endif + +#if defined _ALLEGRO_GL_ARB_texture_multisample +#define glTexImage2DMultisample _al_glTexImage2DMultisample +#define glTexImage3DMultisample _al_glTexImage3DMultisample +#define glGetMultisamplefv _al_glGetMultisamplefv +#define glSampleMaski _al_glSampleMaski +#endif + +#if defined _ALLEGRO_GL_ARB_draw_buffers_blend +#define glBlendEquationi _al_glBlendEquationi +#define glBlendEquationSeparatei _al_glBlendEquationSeparatei +#define glBlendFunci _al_glBlendFunci +#define glBlendFuncSeparatei _al_glBlendFuncSeparatei +#endif + +#if defined _ALLEGRO_GL_ARB_sample_shading +#define glMinSampleShading _al_glMinSampleShading +#endif + +#if defined _ALLEGRO_GL_ARB_shading_language_include +#define glNamedStringARB _al_glNamedStringARB +#define glDeleteNamedStringARB _al_glDeleteNamedStringARB +#define glCompileShaderIncludeARB _al_glCompileShaderIncludeARB +#define glIsNamedStringARB _al_glIsNamedStringARB +#define glGetNamedStringARB _al_glGetNamedStringARB +#define glGetNamedStringivARB _al_glGetNamedStringivARB +#endif + +#if defined _ALLEGRO_GL_ARB_blend_func_extended +#define glBindFragDataLocationIndexed _al_glBindFragDataLocationIndexed +#define glGetFragDataIndex _al_glGetFragDataIndex +#endif + +#if defined _ALLEGRO_GL_ARB_sampler_objects +#define glGenSamplers _al_glGenSamplers +#define glDeleteSamplers _al_glDeleteSamplers +#define glIsSampler _al_glIsSampler +#define glBindSampler _al_glBindSampler +#define glSamplerParameteri _al_glSamplerParameteri +#define glSamplerParameteriv _al_glSamplerParameteriv +#define glSamplerParameterf _al_glSamplerParameterf +#define glSamplerParameterfv _al_glSamplerParameterfv +#define glSamplerParameterIiv _al_glSamplerParameterIiv +#define glSamplerParameterIuiv _al_glSamplerParameterIuiv +#define glGetSamplerParameteriv _al_glGetSamplerParameteriv +#define glGetSamplerParameterIiv _al_glGetSamplerParameterIiv +#define glGetSamplerParameterfv _al_glGetSamplerParameterfv +#define glGetSamplerParameterIfv _al_glGetSamplerParameterIfv +#endif + +#if defined _ALLEGRO_GL_ARB_timer_query +#define glQueryCounter _al_glQueryCounter +#define glGetQueryObjecti64v _al_glGetQueryObjecti64v +#define glGetQueryObjectui64v _al_glGetQueryObjectui64v +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev +#define glVertexP2ui _al_glVertexP2ui +#define glVertexP2uiv _al_glVertexP2uiv +#define glVertexP3ui _al_glVertexP3ui +#define glVertexP3uiv _al_glVertexP3uiv +#define glVertexP4ui _al_glVertexP4ui +#define glVertexP4uiv _al_glVertexP4uiv +#define glTexCoordP1ui _al_glTexCoordP1ui +#define glTexCoordP1uiv _al_glTexCoordP1uiv +#define glTexCoordP2ui _al_glTexCoordP2ui +#define glTexCoordP2uiv _al_glTexCoordP2uiv +#define glTexCoordP3ui _al_glTexCoordP3ui +#define glTexCoordP3uiv _al_glTexCoordP3uiv +#define glTexCoordP4ui _al_glTexCoordP4ui +#define glTexCoordP4uiv _al_glTexCoordP4uiv +#define glMultiTexCoordP1ui _al_glMultiTexCoordP1ui +#define glMultiTexCoordP1uiv _al_glMultiTexCoordP1uiv +#define glMultiTexCoordP2ui _al_glMultiTexCoordP2ui +#define glMultiTexCoordP2uiv _al_glMultiTexCoordP2uiv +#define glMultiTexCoordP3ui _al_glMultiTexCoordP3ui +#define glMultiTexCoordP3uiv _al_glMultiTexCoordP3uiv +#define glMultiTexCoordP4ui _al_glMultiTexCoordP4ui +#define glMultiTexCoordP4uiv _al_glMultiTexCoordP4uiv +#define glNormalP3ui _al_glNormalP3ui +#define glNormalP3uiv _al_glNormalP3uiv +#define glColorP3ui _al_glColorP3ui +#define glColorP3uiv _al_glColorP3uiv +#define glColorP4ui _al_glColorP4ui +#define glColorP4uiv _al_glColorP4uiv +#define glSecondaryColorP3ui _al_glSecondaryColorP3ui +#define glSecondaryColorP3uiv _al_glSecondaryColorP3uiv +#define glVertexAttribP1ui _al_glVertexAttribP1ui +#define glVertexAttribP1uiv _al_glVertexAttribP1uiv +#define glVertexAttribP2ui _al_glVertexAttribP2ui +#define glVertexAttribP2uiv _al_glVertexAttribP2uiv +#define glVertexAttribP3ui _al_glVertexAttribP3ui +#define glVertexAttribP3uiv _al_glVertexAttribP3uiv +#define glVertexAttribP4ui _al_glVertexAttribP4ui +#define glVertexAttribP4uiv _al_glVertexAttribP4uiv +#endif + +#if defined _ALLEGRO_GL_ARB_draw_indirect +#define glDrawArraysIndirect _al_glDrawArraysIndirect +#define glDrawElementsIndirect _al_glDrawElementsIndirect +#endif + +#if defined _ALLEGRO_GL_ARB_gpu_shader_fp64 +#define glUniform1d _al_glUniform1d +#define glUniform2d _al_glUniform2d +#define glUniform3d _al_glUniform3d +#define glUniform4d _al_glUniform4d +#define glUniform1dv _al_glUniform1dv +#define glUniform2dv _al_glUniform2dv +#define glUniform3dv _al_glUniform3dv +#define glUniform4dv _al_glUniform4dv +#define glUniformMatrix2dv _al_glUniformMatrix2dv +#define glUniformMatrix3dv _al_glUniformMatrix3dv +#define glUniformMatrix4dv _al_glUniformMatrix4dv +#define glUniformMatrix2x3dv _al_glUniformMatrix2x3dv +#define glUniformMatrix2x4dv _al_glUniformMatrix2x4dv +#define glUniformMatrix3x2dv _al_glUniformMatrix3x2dv +#define glUniformMatrix3x4dv _al_glUniformMatrix3x4dv +#define glUniformMatrix4x2dv _al_glUniformMatrix4x2dv +#define glUniformMatrix4x3dv _al_glUniformMatrix4x3dv +#define glGetUniformdv _al_glGetUniformdv +#define glProgramUniform1dEXT _al_glProgramUniform1dEXT +#define glProgramUniform2dEXT _al_glProgramUniform2dEXT +#define glProgramUniform3dEXT _al_glProgramUniform3dEXT +#define glProgramUniform4dEXT _al_glProgramUniform4dEXT +#define glProgramUniform1dvEXT _al_glProgramUniform1dvEXT +#define glProgramUniform2dvEXT _al_glProgramUniform2dvEXT +#define glProgramUniform3dvEXT _al_glProgramUniform3dvEXT +#define glProgramUniform4dvEXT _al_glProgramUniform4dvEXT +#define glProgramUniformMatrix2dvEXT _al_glProgramUniformMatrix2dvEXT +#define glProgramUniformMatrix3dvEXT _al_glProgramUniformMatrix3dvEXT +#define glProgramUniformMatrix4dvEXT _al_glProgramUniformMatrix4dvEXT +#define glProgramUniformMatrix2x3dvEXT _al_glProgramUniformMatrix2x3dvEXT +#define glProgramUniformMatrix2x4dvEXT _al_glProgramUniformMatrix2x4dvEXT +#define glProgramUniformMatrix3x2dvEXT _al_glProgramUniformMatrix3x2dvEXT +#define glProgramUniformMatrix3x4dvEXT _al_glProgramUniformMatrix3x4dvEXT +#define glProgramUniformMatrix4x2dvEXT _al_glProgramUniformMatrix4x2dvEXT +#define glProgramUniformMatrix4x3dvEXT _al_glProgramUniformMatrix4x3dvEXT +#endif + +#if defined _ALLEGRO_GL_ARB_shader_subroutine +#define glGetSubroutineUniformLocation _al_glGetSubroutineUniformLocation +#define glGetSubroutineIndex _al_glGetSubroutineIndex +#define glGetActiveSubroutineUniformiv _al_glGetActiveSubroutineUniformiv +#define glGetActiveSubroutineUniformName _al_glGetActiveSubroutineUniformName +#define glGetActiveSubroutineName _al_glGetActiveSubroutineName +#define glUniformSubroutinesuiv _al_glUniformSubroutinesuiv +#define glGetUniformSubroutineuiv _al_glGetUniformSubroutineuiv +#define glGetProgramStageiv _al_glGetProgramStageiv +#endif + +#if defined _ALLEGRO_GL_ARB_tessellation_shader +#define glPatchParameteri _al_glPatchParameteri +#define glPatchParameterfv _al_glPatchParameterfv +#endif + +#if defined _ALLEGRO_GL_ARB_transform_feedback2 +#define glBindTransformFeedback _al_glBindTransformFeedback +#define glDeleteTransformFeedbacks _al_glDeleteTransformFeedbacks +#define glGenTransformFeedbacks _al_glGenTransformFeedbacks +#define glIsTransformFeedback _al_glIsTransformFeedback +#define glPauseTransformFeedback _al_glPauseTransformFeedback +#define glResumeTransformFeedback _al_glResumeTransformFeedback +#define glDrawTransformFeedback _al_glDrawTransformFeedback +#endif + +#if defined _ALLEGRO_GL_ARB_transform_feedback3 +#define glDrawTransformFeedbackStream _al_glDrawTransformFeedbackStream +#define glBeginQueryIndexed _al_glBeginQueryIndexed +#define glEndQueryIndexed _al_glEndQueryIndexed +#define glGetQueryIndexediv _al_glGetQueryIndexediv +#endif + + +/**/ + + +#if defined _ALLEGRO_GL_EXT_blend_color +#define glBlendColorEXT _al_glBlendColorEXT +#endif + +#if defined _ALLEGRO_GL_EXT_polygon_offset +#define glPolygonOffsetEXT _al_glPolygonOffsetEXT +#endif + +#if defined _ALLEGRO_GL_EXT_texture3D +#define glTexImage3DEXT _al_glTexImage3DEXT +#define glTexSubImage3DEXT _al_glTexSubImage3DEXT +#endif + +#if defined _ALLEGRO_GL_SGIS_texture_filter4 +#define glGetTexFilterFuncSGIS _al_glGetTexFilterFuncSGIS +#define glTexFilterFuncSGIS _al_glTexFilterFuncSGIS +#endif + +#if defined _ALLEGRO_GL_EXT_subtexture +#define glTexSubImage1DEXT _al_glTexSubImage1DEXT +#define glTexSubImage2DEXT _al_glTexSubImage2DEXT +#endif + +#if defined _ALLEGRO_GL_EXT_copy_texture +#define glCopyTexImage1DEXT _al_glCopyTexImage1DEXT +#define glCopyTexImage2DEXT _al_glCopyTexImage2DEXT +#define glCopyTexSubImage1DEXT _al_glCopyTexSubImage1DEXT +#define glCopyTexSubImage2DEXT _al_glCopyTexSubImage2DEXT +#define glCopyTexSubImage3DEXT _al_glCopyTexSubImage3DEXT +#endif + +#if defined _ALLEGRO_GL_EXT_histogram +#define glGetHistogramEXT _al_glGetHistogramEXT +#define glGetHistogramParameterfvEXT _al_glGetHistogramParameterfvEXT +#define glGetHistogramParameterivEXT _al_glGetHistogramParameterivEXT +#define glGetMinmaxEXT _al_glGetMinmaxEXT +#define glGetMinmaxParameterfvEXT _al_glGetMinmaxParameterfvEXT +#define glGetMinmaxParameterivEXT _al_glGetMinmaxParameterivEXT +#define glHistogramEXT _al_glHistogramEXT +#define glMinmaxEXT _al_glMinmaxEXT +#define glResetHistogramEXT _al_glResetHistogramEXT +#define glResetMinmaxEXT _al_glResetMinmaxEXT +#endif + +#if defined _ALLEGRO_GL_EXT_convolution +#define glConvolutionFilter1DEXT _al_glConvolutionFilter1DEXT +#define glConvolutionFilter2DEXT _al_glConvolutionFilter2DEXT +#define glConvolutionParameterfEXT _al_glConvolutionParameterfEXT +#define glConvolutionParameterfvEXT _al_glConvolutionParameterfvEXT +#define glConvolutionParameteriEXT _al_glConvolutionParameteriEXT +#define glConvolutionParameterivEXT _al_glConvolutionParameterivEXT +#define glCopyConvolutionFilter1DEXT _al_glCopyConvolutionFilter1DEXT +#define glCopyConvolutionFilter2DEXT _al_glCopyConvolutionFilter2DEXT +#define glGetConvolutionFilterEXT _al_glGetConvolutionFilterEXT +#define glGetConvolutionParameterfvEXT _al_glGetConvolutionParameterfvEXT +#define glGetConvolutionParameterivEXT _al_glGetConvolutionParameterivEXT +#define glGetSeparableFilterEXT _al_glGetSeparableFilterEXT +#define glSeparableFilter2DEXT _al_glSeparableFilter2DEXT +#endif + +#if defined _ALLEGRO_GL_SGI_color_table +#define glColorTableSGI _al_glColorTableSGI +#define glColorTableParameterfvSGI _al_glColorTableParameterfvSGI +#define glColorTableParameterivSGI _al_glColorTableParameterivSGI +#define glCopyColorTableSGI _al_glCopyColorTableSGI +#define glGetColorTableSGI _al_glGetColorTableSGI +#define glGetColorTableParameterfvSGI _al_glGetColorTableParameterfvSGI +#define glGetColorTableParameterivSGI _al_glGetColorTableParameterivSGI +#endif + +#if defined _ALLEGRO_GL_SGIX_pixel_texture +#define glPixelTexGenSGIX _al_glPixelTexGenSGIX +#endif + +#if defined _ALLEGRO_GL_SGIS_pixel_texture +#define glPixelTexGenParameteriSGIS _al_glPixelTexGenParameteriSGIS +#define glPixelTexGenParameterivSGIS _al_glPixelTexGenParameterivSGIS +#define glPixelTexGenParameterfSGIS _al_glPixelTexGenParameterfSGIS +#define glPixelTexGenParameterfvSGIS _al_glPixelTexGenParameterfvSGIS +#define glGetPixelTexGenParameterivSGIS _al_glGetPixelTexGenParameterivSGIS +#define glGetPixelTexGenParameterfvSGIS _al_glGetPixelTexGenParameterfvSGIS +#endif + +#if defined _ALLEGRO_GL_SGIS_texture4D +#define glTexImage4DSGIS _al_glTexImage4DSGIS +#define glTexSubImage4DSGIS _al_glTexSubImage4DSGIS +#endif + +#if defined _ALLEGRO_GL_EXT_texture_object +#define glAreTexturesResidentEXT _al_glAreTexturesResidentEXT +#define glBindTextureEXT _al_glBindTextureEXT +#define glDeleteTexturesEXT _al_glDeleteTexturesEXT +#define glGenTexturesEXT _al_glGenTexturesEXT +#define glIsTextureEXT _al_glIsTextureEXT +#define glPrioritizeTexturesEXT _al_glPrioritizeTexturesEXT +#endif + +#if defined _ALLEGRO_GL_SGIS_detail_texture +#define glDetailTexFuncSGIS _al_glDetailTexFuncSGIS +#define glGetDetailTexFuncSGIS _al_glGetDetailTexFuncSGIS +#endif + +#if defined _ALLEGRO_GL_SGIS_sharpen_texture +#define glSharpenTexFuncSGIS _al_glSharpenTexFuncSGIS +#define glGetSharpenTexFuncSGIS _al_glGetSharpenTexFuncSGIS +#endif + +#if defined _ALLEGRO_GL_SGIS_multisample +#define glSampleMaskSGIS _al_glSampleMaskSGIS +#define glSamplePatternSGIS _al_glSamplePatternSGIS +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_array +#define glArrayElementEXT _al_glArrayElementEXT +#define glColorPointerEXT _al_glColorPointerEXT +#define glDrawArraysEXT _al_glDrawArraysEXT +#define glEdgeFlagPointerEXT _al_glEdgeFlagPointerEXT +#define glGetPointervEXT _al_glGetPointervEXT +#define glIndexPointerEXT _al_glIndexPointerEXT +#define glNormalPointerEXT _al_glNormalPointerEXT +#define glTexCoordPointerEXT _al_glTexCoordPointerEXT +#define glVertexPointerEXT _al_glVertexPointerEXT +#endif + +#if defined _ALLEGRO_GL_EXT_blend_minmax +#define glBlendEquationEXT _al_glBlendEquationEXT +#endif + +#if defined _ALLEGRO_GL_SGIX_sprite +#define glSpriteParameterfSGIX _al_glSpriteParameterfSGIX +#define glSpriteParameterfvSGIX _al_glSpriteParameterfvSGIX +#define glSpriteParameteriSGIX _al_glSpriteParameteriSGIX +#define glSpriteParameterivSGIX _al_glSpriteParameterivSGIX +#endif + +#if defined _ALLEGRO_GL_EXT_point_parameters +#define glPointParameterfEXT _al_glPointParameterfEXT +#define glPointParameterfvEXT _al_glPointParameterfvEXT +#endif + +#if defined _ALLEGRO_GL_SGIS_point_parameters +#define glPointParameterfSGIS _al_glPointParameterfSGIS +#define glPointParameterfvSGIS _al_glPointParameterfvSGIS +#endif + +#if defined _ALLEGRO_GL_SGIX_instruments +#define glGetInstrumentsSGIX _al_glGetInstrumentsSGIX +#define glInstrumentsBufferSGIX _al_glInstrumentsBufferSGIX +#define glPollInstrumentsSGIX _al_glPollInstrumentsSGIX +#define glReadInstrumentsSGIX _al_glReadInstrumentsSGIX +#define glStartInstrumentsSGIX _al_glStartInstrumentsSGIX +#define glStopInstrumentsSGIX _al_glStopInstrumentsSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_framezoom +#define glFrameZoomSGIX _al_glFrameZoomSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_tag_sample_buffer +#define glTagSampleBufferSGIX _al_glTagSampleBufferSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_polynomial_ffd +#define glDeformationMap3dSGIX _al_glDeformationMap3dSGIX +#define glDeformationMap3fSGIX _al_glDeformationMap3fSGIX +#define glDeformSGIX _al_glDeformSGIX +#define glLoadIdentityDeformationMapSGIX _al_glLoadIdentityDeformationMapSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_reference_plane +#define glReferencePlaneSGIX _al_glReferencePlaneSGIX +#endif + +#if defined _ALLEGRO_GL_SGIX_flush_raster +#define glFlushRasterSGIX _al_glFlushRasterSGIX +#endif + +#if defined _ALLEGRO_GL_SGIS_fog_function +#define glFogFuncSGIS _al_glFogFuncSGIS +#define glGetFogFuncSGIS _al_glGetFogFuncSGIS +#endif + +#if defined _ALLEGRO_GL_HP_image_transform +#define glImageTransformParameteriHP _al_glImageTransformParameteriHP +#define glImageTransformParameterfHP _al_glImageTransformParameterfHP +#define glImageTransformParameterivHP _al_glImageTransformParameterivHP +#define glImageTransformParameterfvHP _al_glImageTransformParameterfvHP +#define glGetImageTransformParameterivHP _al_glGetImageTransformParameterivHP +#define glGetImageTransformParameterfvHP _al_glGetImageTransformParameterfvHP +#endif + +#if defined _ALLEGRO_GL_EXT_color_subtable +#ifndef GL_EXT_paletted_texture +#define glColorSubTableEXT _al_glColorSubTableEXT +#endif +#define glCopyColorSubTableEXT _al_glCopyColorSubTableEXT +#endif + +#if defined _ALLEGRO_GL_PGI_misc_hints +#define glHintPGI _al_glHintPGI +#endif + +#if defined _ALLEGRO_GL_EXT_paletted_texture +#define glColorTableEXT _al_glColorTableEXT +#define glGetColorTableEXT _al_glGetColorTableEXT +#define glGetColorTableParameterivEXT _al_glGetColorTableParameterivEXT +#define glGetColorTableParameterfvEXT _al_glGetColorTableParameterfvEXT +#endif + +#if defined _ALLEGRO_GL_SGIX_list_priority +#define glGetListParameterfvSGIX _al_glGetListParameterfvSGIX +#define glGetListParameterivSGIX _al_glGetListParameterivSGIX +#define glListParameterfSGIX _al_glListParameterfSGIX +#define glListParameterfvSGIX _al_glListParameterfvSGIX +#define glListParameteriSGIX _al_glListParameteriSGIX +#define glListParameterivSGIX _al_glListParameterivSGIX +#endif + +#if defined _ALLEGRO_GL_EXT_index_material +#define glIndexMaterialEXT _al_glIndexMaterialEXT +#endif + +#if defined _ALLEGRO_GL_EXT_index_func +#define glIndexFuncEXT _al_glIndexFuncEXT +#endif + +#if defined _ALLEGRO_GL_EXT_compiled_vertex_array +#define glLockArraysEXT _al_glLockArraysEXT +#define glUnlockArraysEXT _al_glUnlockArraysEXT +#endif + +#if defined _ALLEGRO_GL_EXT_cull_vertex +#define glCullParameterdvEXT _al_glCullParameterdvEXT +#define glCullParameterfvEXT _al_glCullParameterfvEXT +#endif + +#if defined _ALLEGRO_GL_SGIX_fragment_lighting +#define glFragmentColorMaterialSGIX _al_glFragmentColorMaterialSGIX +#define glFragmentLightfSGIX _al_glFragmentLightfSGIX +#define glFragmentLightfvSGIX _al_glFragmentLightfvSGIX +#define glFragmentLightiSGIX _al_glFragmentLightiSGIX +#define glFragmentLightivSGIX _al_glFragmentLightivSGIX +#define glFragmentLightModelfSGIX _al_glFragmentLightModelfSGIX +#define glFragmentLightModelfvSGIX _al_glFragmentLightModelfvSGIX +#define glFragmentLightModeliSGIX _al_glFragmentLightModeliSGIX +#define glFragmentLightModelivSGIX _al_glFragmentLightModelivSGIX +#define glFragmentMaterialfSGIX _al_glFragmentMaterialfSGIX +#define glFragmentMaterialfvSGIX _al_glFragmentMaterialfvSGIX +#define glFragmentMaterialiSGIX _al_glFragmentMaterialiSGIX +#define glFragmentMaterialivSGIX _al_glFragmentMaterialivSGIX +#define glGetFragmentLightfvSGIX _al_glGetFragmentLightfvSGIX +#define glGetFragmentLightivSGIX _al_glGetFragmentLightivSGIX +#define glGetFragmentMaterialfvSGIX _al_glGetFragmentMaterialfvSGIX +#define glGetFragmentMaterialivSGIX _al_glGetFragmentMaterialivSGIX +#define glLightEnviSGIX _al_glLightEnviSGIX +#endif + +#if defined _ALLEGRO_GL_EXT_draw_range_elements +#define glDrawRangeElementsEXT _al_glDrawRangeElementsEXT +#endif + +#if defined _ALLEGRO_GL_EXT_light_texture +#define glApplyTextureEXT _al_glApplyTextureEXT +#define glTextureLightEXT _al_glTextureLightEXT +#define glTextureMaterialEXT _al_glTextureMaterialEXT +#endif + +#if defined _ALLEGRO_GL_SGIX_async +#define glAsyncMarkerSGIX _al_glAsyncMarkerSGIX +#define glFinishAsyncSGIX _al_glFinishAsyncSGIX +#define glPollAsyncSGIX _al_glPollAsyncSGIX +#define glGenAsyncMarkersSGIX _al_glGenAsyncMarkersSGIX +#define glDeleteAsyncMarkersSGIX _al_glDeleteAsyncMarkersSGIX +#define glIsAsyncMarkerSGIX _al_glIsAsyncMarkerSGIX +#endif + +#if defined _ALLEGRO_GL_INTEL_parallel_arrays +#define glVertexPointervINTEL _al_glVertexPointervINTEL +#define glNormalPointervINTEL _al_glNormalPointervINTEL +#define glColorPointervINTEL _al_glColorPointervINTEL +#define glTexCoordPointervINTEL _al_glTexCoordPointervINTEL +#endif + +#if defined _ALLEGRO_GL_EXT_pixel_transform +#define glPixelTransformParameteriEXT _al_glPixelTransformParameteriEXT +#define glPixelTransformParameterfEXT _al_glPixelTransformParameterfEXT +#define glPixelTransformParameterivEXT _al_glPixelTransformParameterivEXT +#define glPixelTransformParameterfvEXT _al_glPixelTransformParameterfvEXT +#endif + +#if defined _ALLEGRO_GL_EXT_secondary_color +#define glSecondaryColor3bEXT _al_glSecondaryColor3bEXT +#define glSecondaryColor3bvEXT _al_glSecondaryColor3bvEXT +#define glSecondaryColor3dEXT _al_glSecondaryColor3dEXT +#define glSecondaryColor3dvEXT _al_glSecondaryColor3dvEXT +#define glSecondaryColor3fEXT _al_glSecondaryColor3fEXT +#define glSecondaryColor3fvEXT _al_glSecondaryColor3fvEXT +#define glSecondaryColor3iEXT _al_glSecondaryColor3iEXT +#define glSecondaryColor3ivEXT _al_glSecondaryColor3ivEXT +#define glSecondaryColor3sEXT _al_glSecondaryColor3sEXT +#define glSecondaryColor3svEXT _al_glSecondaryColor3svEXT +#define glSecondaryColor3ubEXT _al_glSecondaryColor3ubEXT +#define glSecondaryColor3ubvEXT _al_glSecondaryColor3ubvEXT +#define glSecondaryColor3uiEXT _al_glSecondaryColor3uiEXT +#define glSecondaryColor3uivEXT _al_glSecondaryColor3uivEXT +#define glSecondaryColor3usEXT _al_glSecondaryColor3usEXT +#define glSecondaryColor3usvEXT _al_glSecondaryColor3usvEXT +#define glSecondaryColorPointerEXT _al_glSecondaryColorPointerEXT +#endif + +#if defined _ALLEGRO_GL_EXT_texture_perturb_normal +#define glTextureNormalEXT _al_glTextureNormalEXT +#endif + +#if defined _ALLEGRO_GL_EXT_multi_draw_arrays +#define glMultiDrawArraysEXT _al_glMultiDrawArraysEXT +#define glMultiDrawElementsEXT _al_glMultiDrawElementsEXT +#endif + +#if defined _ALLEGRO_GL_EXT_fog_coord +#define glFogCoordfEXT _al_glFogCoordfEXT +#define glFogCoordfvEXT _al_glFogCoordfvEXT +#define glFogCoorddEXT _al_glFogCoorddEXT +#define glFogCoorddvEXT _al_glFogCoorddvEXT +#define glFogCoordPointerEXT _al_glFogCoordPointerEXT +#endif + +#if defined _ALLEGRO_GL_EXT_coordinate_frame +#define glTangent3bEXT _al_glTangent3bEXT +#define glTangent3bvEXT _al_glTangent3bvEXT +#define glTangent3dEXT _al_glTangent3dEXT +#define glTangent3dvEXT _al_glTangent3dvEXT +#define glTangent3fEXT _al_glTangent3fEXT +#define glTangent3fvEXT _al_glTangent3fvEXT +#define glTangent3iEXT _al_glTangent3iEXT +#define glTangent3ivEXT _al_glTangent3ivEXT +#define glTangent3sEXT _al_glTangent3sEXT +#define glTangent3svEXT _al_glTangent3svEXT +#define glBinormal3bEXT _al_glBinormal3bEXT +#define glBinormal3bvEXT _al_glBinormal3bvEXT +#define glBinormal3dEXT _al_glBinormal3dEXT +#define glBinormal3dvEXT _al_glBinormal3dvEXT +#define glBinormal3fEXT _al_glBinormal3fEXT +#define glBinormal3fvEXT _al_glBinormal3fvEXT +#define glBinormal3iEXT _al_glBinormal3iEXT +#define glBinormal3ivEXT _al_glBinormal3ivEXT +#define glBinormal3sEXT _al_glBinormal3sEXT +#define glBinormal3svEXT _al_glBinormal3svEXT +#define glTangentPointerEXT _al_glTangentPointerEXT +#define glBinormalPointerEXT _al_glBinormalPointerEXT +#endif + +#if defined _ALLEGRO_GL_SUNX_constant_data +#define glFinishTextureSUNX _al_glFinishTextureSUNX +#endif + +#if defined _ALLEGRO_GL_SUN_global_alpha +#define glGlobalAlphaFactorbSUN _al_glGlobalAlphaFactorbSUN +#define glGlobalAlphaFactorsSUN _al_glGlobalAlphaFactorsSUN +#define glGlobalAlphaFactoriSUN _al_glGlobalAlphaFactoriSUN +#define glGlobalAlphaFactorfSUN _al_glGlobalAlphaFactorfSUN +#define glGlobalAlphaFactordSUN _al_glGlobalAlphaFactordSUN +#define glGlobalAlphaFactorubSUN _al_glGlobalAlphaFactorubSUN +#define glGlobalAlphaFactorusSUN _al_glGlobalAlphaFactorusSUN +#define glGlobalAlphaFactoruiSUN _al_glGlobalAlphaFactoruiSUN +#endif + +#if defined _ALLEGRO_GL_SUN_triangle_list +#define glReplacementCodeuiSUN _al_glReplacementCodeuiSUN +#define glReplacementCodeusSUN _al_glReplacementCodeusSUN +#define glReplacementCodeubSUN _al_glReplacementCodeubSUN +#define glReplacementCodeuivSUN _al_glReplacementCodeuivSUN +#define glReplacementCodeusvSUN _al_glReplacementCodeusvSUN +#define glReplacementCodeubvSUN _al_glReplacementCodeubvSUN +#define glReplacementCodePointerSUN _al_glReplacementCodePointerSUN +#endif + +#if defined _ALLEGRO_GL_SUN_vertex +#define glColor4ubVertex2fSUN _al_glColor4ubVertex2fSUN +#define glColor4ubVertex2fvSUN _al_glColor4ubVertex2fvSUN +#define glColor4ubVertex3fSUN _al_glColor4ubVertex3fSUN +#define glColor4ubVertex3fvSUN _al_glColor4ubVertex3fvSUN +#define glColor3fVertex3fSUN _al_glColor3fVertex3fSUN +#define glColor3fVertex3fvSUN _al_glColor3fVertex3fvSUN +#define glNormal3fVertex3fSUN _al_glNormal3fVertex3fSUN +#define glNormal3fVertex3fvSUN _al_glNormal3fVertex3fvSUN +#define glColor4fNormal3fVertex3fSUN _al_glColor4fNormal3fVertex3fSUN +#define glColor4fNormal3fVertex3fvSUN _al_glColor4fNormal3fVertex3fvSUN +#define glTexCoord2fVertex3fSUN _al_glTexCoord2fVertex3fSUN +#define glTexCoord2fVertex3fvSUN _al_glTexCoord2fVertex3fvSUN +#define glTexCoord4fVertex4fSUN _al_glTexCoord4fVertex4fSUN +#define glTexCoord4fVertex4fvSUN _al_glTexCoord4fVertex4fvSUN +#define glTexCoord2fColor4ubVertex3fSUN _al_glTexCoord2fColor4ubVertex3fSUN +#define glTexCoord2fColor4ubVertex3fvSUN _al_glTexCoord2fColor4ubVertex3fvSUN +#define glTexCoord2fColor3fVertex3fSUN _al_glTexCoord2fColor3fVertex3fSUN +#define glTexCoord2fColor3fVertex3fvSUN _al_glTexCoord2fColor3fVertex3fvSUN +#define glTexCoord2fNormal3fVertex3fSUN _al_glTexCoord2fNormal3fVertex3fSUN +#define glTexCoord2fNormal3fVertex3fvSUN _al_glTexCoord2fNormal3fVertex3fvSUN +#define glTexCoord2fColor4fNormal3fVertex3fSUN _al_glTexCoord2fColor4fNormal3fVertex3fSUN +#define glTexCoord2fColor4fNormal3fVertex3fvSUN _al_glTexCoord2fColor4fNormal3fVertex3fvSUN +#define glTexCoord4fColor4fNormal3fVertex4fSUN _al_glTexCoord4fColor4fNormal3fVertex4fSUN +#define glTexCoord4fColor4fNormal3fVertex4fvSUN _al_glTexCoord4fColor4fNormal3fVertex4fvSUN +#define glReplacementCodeuiVertex3fSUN _al_glReplacementCodeuiVertex3fSUN +#define glReplacementCodeuiVertex3fvSUN _al_glReplacementCodeuiVertex3fvSUN +#define glReplacementCodeuiColor4ubVertex3fSUN _al_glReplacementCodeuiColor4ubVertex3fSUN +#define glReplacementCodeuiColor4ubVertex3fvSUN _al_glReplacementCodeuiColor4ubVertex3fvSUN +#define glReplacementCodeuiColor3fVertex3fSUN _al_glReplacementCodeuiColor3fVertex3fSUN +#define glReplacementCodeuiColor3fVertex3fvSUN _al_glReplacementCodeuiColor3fVertex3fvSUN +#define glReplacementCodeuiNormal3fVertex3fSUN _al_glReplacementCodeuiNormal3fVertex3fSUN +#define glReplacementCodeuiNormal3fVertex3fvSUN _al_glReplacementCodeuiNormal3fVertex3fvSUN +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN _al_glReplacementCodeuiColor4fNormal3fVertex3fSUN +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN _al_glReplacementCodeuiColor4fNormal3fVertex3fvSUN +#define glReplacementCodeuiTexCoord2fVertex3fSUN _al_glReplacementCodeuiTexCoord2fVertex3fSUN +#define glReplacementCodeuiTexCoord2fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fVertex3fvSUN +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN _al_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN _al_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN _al_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN +#endif + +#if defined _ALLEGRO_GL_EXT_blend_func_separate +#define glBlendFuncSeparateEXT _al_glBlendFuncSeparateEXT +#endif + +#if defined _ALLEGRO_GL_INGR_blend_func_separate +#define glBlendFuncSeparateINGR _al_glBlendFuncSeparateINGR +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_weighting +#define glVertexWeightfEXT _al_glVertexWeightfEXT +#define glVertexWeightfvEXT _al_glVertexWeightfvEXT +#define glVertexWeightPointerEXT _al_glVertexWeightPointerEXT +#endif + +#if defined _ALLEGRO_GL_NV_vertex_array_range +#define glFlushVertexArrayRangeNV _al_glFlushVertexArrayRangeNV +#define glVertexArrayRangeNV _al_glVertexArrayRangeNV +#endif + +#if defined _ALLEGRO_GL_NV_register_combiners +#define glCombinerParameterfvNV _al_glCombinerParameterfvNV +#define glCombinerParameterfNV _al_glCombinerParameterfNV +#define glCombinerParameterivNV _al_glCombinerParameterivNV +#define glCombinerParameteriNV _al_glCombinerParameteriNV +#define glCombinerInputNV _al_glCombinerInputNV +#define glCombinerOutputNV _al_glCombinerOutputNV +#define glFinalCombinerInputNV _al_glFinalCombinerInputNV +#define glGetCombinerInputParameterfvNV _al_glGetCombinerInputParameterfvNV +#define glGetCombinerInputParameterivNV _al_glGetCombinerInputParameterivNV +#define glGetCombinerOutputParameterfvNV _al_glGetCombinerOutputParameterfvNV +#define glGetCombinerOutputParameterivNV _al_glGetCombinerOutputParameterivNV +#define glGetFinalCombinerInputParameterfvNV _al_glGetFinalCombinerInputParameterfvNV +#define glGetFinalCombinerInputParameterivNV _al_glGetFinalCombinerInputParameterivNV +#endif + +#if defined _ALLEGRO_GL_MESA_resize_buffers +#define glResizeBuffersMESA _al_glResizeBuffersMESA +#endif + +#if defined _ALLEGRO_GL_MESA_window_pos +#define glWindowPos2dMESA _al_glWindowPos2dMESA +#define glWindowPos2dvMESA _al_glWindowPos2dvMESA +#define glWindowPos2fMESA _al_glWindowPos2fMESA +#define glWindowPos2fvMESA _al_glWindowPos2fvMESA +#define glWindowPos2iMESA _al_glWindowPos2iMESA +#define glWindowPos2ivMESA _al_glWindowPos2ivMESA +#define glWindowPos2sMESA _al_glWindowPos2sMESA +#define glWindowPos2svMESA _al_glWindowPos2svMESA +#define glWindowPos3dMESA _al_glWindowPos3dMESA +#define glWindowPos3dvMESA _al_glWindowPos3dvMESA +#define glWindowPos3fMESA _al_glWindowPos3fMESA +#define glWindowPos3fvMESA _al_glWindowPos3fvMESA +#define glWindowPos3iMESA _al_glWindowPos3iMESA +#define glWindowPos3ivMESA _al_glWindowPos3ivMESA +#define glWindowPos3sMESA _al_glWindowPos3sMESA +#define glWindowPos3svMESA _al_glWindowPos3svMESA +#define glWindowPos4dMESA _al_glWindowPos4dMESA +#define glWindowPos4dvMESA _al_glWindowPos4dvMESA +#define glWindowPos4fMESA _al_glWindowPos4fMESA +#define glWindowPos4fvMESA _al_glWindowPos4fvMESA +#define glWindowPos4iMESA _al_glWindowPos4iMESA +#define glWindowPos4ivMESA _al_glWindowPos4ivMESA +#define glWindowPos4sMESA _al_glWindowPos4sMESA +#define glWindowPos4svMESA _al_glWindowPos4svMESA +#endif + +#if defined _ALLEGRO_GL_IBM_multimode_draw_arrays +#define glMultiModeDrawArraysIBM _al_glMultiModeDrawArraysIBM +#define glMultiModeDrawElementsIBM _al_glMultiModeDrawElementsIBM +#endif + +#ifdef AGK_IBM_vertex_array_lists +#define glColorPointerListIBM _al_glColorPointerListIBM +#define glSecondaryColorPointerListIBM _al_glSecondaryColorPointerListIBM +#define glEdgeFlagPointerListIBM _al_glEdgeFlagPointerListIBM +#define glFogCoordPointerListIBM _al_glFogCoordPointerListIBM +#define glIndexPointerListIBM _al_glIndexPointerListIBM +#define glNormalPointerListIBM _al_glNormalPointerListIBM +#define glTexCoordPointerListIBM _al_glTexCoordPointerListIBM +#define glVertexPointerListIBM _al_glVertexPointerListIBM +#endif + +#if defined _ALLEGRO_GL_3DFX_tbuffer +#define glTbufferMask3DFX _al_glTbufferMask3DFX +#endif + +#if defined _ALLEGRO_GL_EXT_multisample +#define glSampleMaskEXT _al_glSampleMaskEXT +#define glSamplePatternEXT _al_glSamplePatternEXT +#endif + +#if defined _ALLEGRO_GL_SGIS_texture_color_mask +#define glTextureColorMaskSGIS _al_glTextureColorMaskSGIS +#endif + +#if defined _ALLEGRO_GL_SGIX_igloo_interface +#define glIglooInterfaceSGIX _al_glIglooInterfaceSGIX +#endif + +#if defined _ALLEGRO_GL_NV_fence +#define glDeleteFencesNV _al_glDeleteFencesNV +#define glGenFencesNV _al_glGenFencesNV +#define glIsFenceNV _al_glIsFenceNV +#define glTestFenceNV _al_glTestFenceNV +#define glGetFenceivNV _al_glGetFenceivNV +#define glFinishFenceNV _al_glFinishFenceNV +#define glSetFenceNV _al_glSetFenceNV +#endif + +#if defined _ALLEGRO_GL_NV_evaluators +#define glMapControlPointsNV _al_glMapControlPointsNV +#define glMapParameterivNV _al_glMapParameterivNV +#define glMapParameterfvNV _al_glMapParameterfvNV +#define glGetMapControlPointsNV _al_glGetMapControlPointsNV +#define glGetMapParameterivNV _al_glGetMapParameterivNV +#define glGetMapParameterfvNV _al_glGetMapParameterfvNV +#define glGetMapAttribParameterivNV _al_glGetMapAttribParameterivNV +#define glGetMapAttribParameterfvNV _al_glGetMapAttribParameterfvNV +#define glEvalMapsNV _al_glEvalMapsNV +#endif + +#if defined _ALLEGRO_GL_NV_register_combiners2 +#define glCombinerStageParameterfvNV _al_glCombinerStageParameterfvNV +#define glGetCombinerStageParameterfvNV _al_glGetCombinerStageParameterfvNV +#endif + +#if defined _ALLEGRO_GL_NV_vertex_program +#define glAreProgramsResidentNV _al_glAreProgramsResidentNV +#define glBindProgramNV _al_glBindProgramNV +#define glDeleteProgramsNV _al_glDeleteProgramsNV +#define glExecuteProgramNV _al_glExecuteProgramNV +#define glGenProgramsNV _al_glGenProgramsNV +#define glGetProgramParameterdvNV _al_glGetProgramParameterdvNV +#define glGetProgramParameterfvNV _al_glGetProgramParameterfvNV +#define glGetProgramivNV _al_glGetProgramivNV +#define glGetProgramStringNV _al_glGetProgramStringNV +#define glGetTrackMatrixivNV _al_glGetTrackMatrixivNV +#define glGetVertexAttribdvNV _al_glGetVertexAttribdvNV +#define glGetVertexAttribfvNV _al_glGetVertexAttribfvNV +#define glGetVertexAttribivNV _al_glGetVertexAttribivNV +#define glGetVertexAttribPointervNV _al_glGetVertexAttribPointervNV +#define glIsProgramNV _al_glIsProgramNV +#define glLoadProgramNV _al_glLoadProgramNV +#define glProgramParameter4dNV _al_glProgramParameter4dNV +#define glProgramParameter4dvNV _al_glProgramParameter4dvNV +#define glProgramParameter4fNV _al_glProgramParameter4fNV +#define glProgramParameter4fvNV _al_glProgramParameter4fvNV +#define glProgramParameters4dvNV _al_glProgramParameters4dvNV +#define glProgramParameters4fvNV _al_glProgramParameters4fvNV +#define glRequestResidentProgramsNV _al_glRequestResidentProgramsNV +#define glTrackMatrixNV _al_glTrackMatrixNV +#define glVertexAttribPointerNV _al_glVertexAttribPointerNV +#define glVertexAttrib1dNV _al_glVertexAttrib1dNV +#define glVertexAttrib1dvNV _al_glVertexAttrib1dvNV +#define glVertexAttrib1fNV _al_glVertexAttrib1fNV +#define glVertexAttrib1fvNV _al_glVertexAttrib1fvNV +#define glVertexAttrib1sNV _al_glVertexAttrib1sNV +#define glVertexAttrib1svNV _al_glVertexAttrib1svNV +#define glVertexAttrib2dNV _al_glVertexAttrib2dNV +#define glVertexAttrib2dvNV _al_glVertexAttrib2dvNV +#define glVertexAttrib2fNV _al_glVertexAttrib2fNV +#define glVertexAttrib2fvNV _al_glVertexAttrib2fvNV +#define glVertexAttrib2sNV _al_glVertexAttrib2sNV +#define glVertexAttrib2svNV _al_glVertexAttrib2svNV +#define glVertexAttrib3dNV _al_glVertexAttrib3dNV +#define glVertexAttrib3dvNV _al_glVertexAttrib3dvNV +#define glVertexAttrib3fNV _al_glVertexAttrib3fNV +#define glVertexAttrib3fvNV _al_glVertexAttrib3fvNV +#define glVertexAttrib3sNV _al_glVertexAttrib3sNV +#define glVertexAttrib3svNV _al_glVertexAttrib3svNV +#define glVertexAttrib4dNV _al_glVertexAttrib4dNV +#define glVertexAttrib4dvNV _al_glVertexAttrib4dvNV +#define glVertexAttrib4fNV _al_glVertexAttrib4fNV +#define glVertexAttrib4fvNV _al_glVertexAttrib4fvNV +#define glVertexAttrib4sNV _al_glVertexAttrib4sNV +#define glVertexAttrib4svNV _al_glVertexAttrib4svNV +#define glVertexAttrib4ubNV _al_glVertexAttrib4ubNV +#define glVertexAttrib4ubvNV _al_glVertexAttrib4ubvNV +#define glVertexAttribs1dvNV _al_glVertexAttribs1dvNV +#define glVertexAttribs1fvNV _al_glVertexAttribs1fvNV +#define glVertexAttribs1svNV _al_glVertexAttribs1svNV +#define glVertexAttribs2dvNV _al_glVertexAttribs2dvNV +#define glVertexAttribs2fvNV _al_glVertexAttribs2fvNV +#define glVertexAttribs2svNV _al_glVertexAttribs2svNV +#define glVertexAttribs3dvNV _al_glVertexAttribs3dvNV +#define glVertexAttribs3fvNV _al_glVertexAttribs3fvNV +#define glVertexAttribs3svNV _al_glVertexAttribs3svNV +#define glVertexAttribs4dvNV _al_glVertexAttribs4dvNV +#define glVertexAttribs4fvNV _al_glVertexAttribs4fvNV +#define glVertexAttribs4svNV _al_glVertexAttribs4svNV +#define glVertexAttribs4ubvNV _al_glVertexAttribs4ubvNV +#endif + +#if defined _ALLEGRO_GL_ATI_envmap_bumpmap +#define glTexBumpParameterivATI _al_glTexBumpParameterivATI +#define glTexBumpParameterfvATI _al_glTexBumpParameterfvATI +#define glGetTexBumpParameterivATI _al_glGetTexBumpParameterivATI +#define glGetTexBumpParameterfvATI _al_glGetTexBumpParameterfvATI +#endif + +#if defined _ALLEGRO_GL_ATI_fragment_shader +#define glGenFragmentShadersATI _al_glGenFragmentShadersATI +#define glBindFragmentShaderATI _al_glBindFragmentShaderATI +#define glDeleteFragmentShaderATI _al_glDeleteFragmentShaderATI +#define glBeginFragmentShaderATI _al_glBeginFragmentShaderATI +#define glEndFragmentShaderATI _al_glEndFragmentShaderATI +#define glPassTexCoordATI _al_glPassTexCoordATI +#define glSampleMapATI _al_glSampleMapATI +#define glColorFragmentOp1ATI _al_glColorFragmentOp1ATI +#define glColorFragmentOp2ATI _al_glColorFragmentOp2ATI +#define glColorFragmentOp3ATI _al_glColorFragmentOp3ATI +#define glAlphaFragmentOp1ATI _al_glAlphaFragmentOp1ATI +#define glAlphaFragmentOp2ATI _al_glAlphaFragmentOp2ATI +#define glAlphaFragmentOp3ATI _al_glAlphaFragmentOp3ATI +#define glSetFragmentShaderConstantATI _al_glSetFragmentShaderConstantATI +#endif + +#if defined _ALLEGRO_GL_ATI_pn_triangles +#define glPNTrianglesiATI _al_glPNTrianglesiATI +#define glPNTrianglesfATI _al_glPNTrianglesfATI +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_array_object +#define glNewObjectBufferATI _al_glNewObjectBufferATI +#define glIsObjectBufferATI _al_glIsObjectBufferATI +#define glUpdateObjectBufferATI _al_glUpdateObjectBufferATI +#define glGetObjectBufferfvATI _al_glGetObjectBufferfvATI +#define glGetObjectBufferivATI _al_glGetObjectBufferivATI +#define glFreeObjectBufferATI _al_glFreeObjectBufferATI +#define glArrayObjectATI _al_glArrayObjectATI +#define glGetArrayObjectfvATI _al_glGetArrayObjectfvATI +#define glGetArrayObjectivATI _al_glGetArrayObjectivATI +#define glVariantArrayObjectATI _al_glVariantArrayObjectATI +#define glGetVariantArrayObjectfvATI _al_glGetVariantArrayObjectfvATI +#define glGetVariantArrayObjectivATI _al_glGetVariantArrayObjectivATI +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_shader +#define glBeginVertexShaderEXT _al_glBeginVertexShaderEXT +#define glEndVertexShaderEXT _al_glEndVertexShaderEXT +#define glBindVertexShaderEXT _al_glBindVertexShaderEXT +#define glGenVertexShadersEXT _al_glGenVertexShadersEXT +#define glDeleteVertexShaderEXT _al_glDeleteVertexShaderEXT +#define glShaderOp1EXT _al_glShaderOp1EXT +#define glShaderOp2EXT _al_glShaderOp2EXT +#define glShaderOp3EXT _al_glShaderOp3EXT +#define glSwizzleEXT _al_glSwizzleEXT +#define glWriteMaskEXT _al_glWriteMaskEXT +#define glInsertComponentEXT _al_glInsertComponentEXT +#define glExtractComponentEXT _al_glExtractComponentEXT +#define glGenSymbolsEXT _al_glGenSymbolsEXT +#define glSetInvariantEXT _al_glSetInvariantEXT +#define glSetLocalConstantEXT _al_glSetLocalConstantEXT +#define glVariantbvEXT _al_glVariantbvEXT +#define glVariantsvEXT _al_glVariantsvEXT +#define glVariantivEXT _al_glVariantivEXT +#define glVariantfvEXT _al_glVariantfvEXT +#define glVariantdvEXT _al_glVariantdvEXT +#define glVariantubvEXT _al_glVariantubvEXT +#define glVariantusvEXT _al_glVariantusvEXT +#define glVariantuivEXT _al_glVariantuivEXT +#define glVariantPointerEXT _al_glVariantPointerEXT +#define glEnableVariantClientStateEXT _al_glEnableVariantClientStateEXT +#define glDisableVariantClientStateEXT _al_glDisableVariantClientStateEXT +#define glBindLightParameterEXT _al_glBindLightParameterEXT +#define glBindMaterialParameterEXT _al_glBindMaterialParameterEXT +#define glBindTexGenParameterEXT _al_glBindTexGenParameterEXT +#define glBindTextureUnitParameterEXT _al_glBindTextureUnitParameterEXT +#define glBindParameterEXT _al_glBindParameterEXT +#define glIsVariantEnabledEXT _al_glIsVariantEnabledEXT +#define glGetVariantBooleanvEXT _al_glGetVariantBooleanvEXT +#define glGetVariantIntegervEXT _al_glGetVariantIntegervEXT +#define glGetVariantFloatvEXT _al_glGetVariantFloatvEXT +#define glGetVariantPointervEXT _al_glGetVariantPointervEXT +#define glGetInvariantBooleanvEXT _al_glGetInvariantBooleanvEXT +#define glGetInvariantIntegervEXT _al_glGetInvariantIntegervEXT +#define glGetInvariantFloatvEXT _al_glGetInvariantFloatvEXT +#define glGetLocalConstantBooleanvEXT _al_glGetLocalConstantBooleanvEXT +#define glGetLocalConstantIntegervEXT _al_glGetLocalConstantIntegervEXT +#define glGetLocalConstantFloatvEXT _al_glGetLocalConstantFloatvEXT +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_streams +#define glVertexStream1sATI _al_glVertexStream1sATI +#define glVertexStream1svATI _al_glVertexStream1svATI +#define glVertexStream1iATI _al_glVertexStream1iATI +#define glVertexStream1ivATI _al_glVertexStream1ivATI +#define glVertexStream1fATI _al_glVertexStream1fATI +#define glVertexStream1fvATI _al_glVertexStream1fvATI +#define glVertexStream1dATI _al_glVertexStream1dATI +#define glVertexStream1dvATI _al_glVertexStream1dvATI +#define glVertexStream2sATI _al_glVertexStream2sATI +#define glVertexStream2svATI _al_glVertexStream2svATI +#define glVertexStream2iATI _al_glVertexStream2iATI +#define glVertexStream2ivATI _al_glVertexStream2ivATI +#define glVertexStream2fATI _al_glVertexStream2fATI +#define glVertexStream2fvATI _al_glVertexStream2fvATI +#define glVertexStream2dATI _al_glVertexStream2dATI +#define glVertexStream2dvATI _al_glVertexStream2dvATI +#define glVertexStream3sATI _al_glVertexStream3sATI +#define glVertexStream3svATI _al_glVertexStream3svATI +#define glVertexStream3iATI _al_glVertexStream3iATI +#define glVertexStream3ivATI _al_glVertexStream3ivATI +#define glVertexStream3fATI _al_glVertexStream3fATI +#define glVertexStream3fvATI _al_glVertexStream3fvATI +#define glVertexStream3dATI _al_glVertexStream3dATI +#define glVertexStream3dvATI _al_glVertexStream3dvATI +#define glVertexStream4sATI _al_glVertexStream4sATI +#define glVertexStream4svATI _al_glVertexStream4svATI +#define glVertexStream4iATI _al_glVertexStream4iATI +#define glVertexStream4ivATI _al_glVertexStream4ivATI +#define glVertexStream4fATI _al_glVertexStream4fATI +#define glVertexStream4fvATI _al_glVertexStream4fvATI +#define glVertexStream4dATI _al_glVertexStream4dATI +#define glVertexStream4dvATI _al_glVertexStream4dvATI +#define glNormalStream3bATI _al_glNormalStream3bATI +#define glNormalStream3bvATI _al_glNormalStream3bvATI +#define glNormalStream3sATI _al_glNormalStream3sATI +#define glNormalStream3svATI _al_glNormalStream3svATI +#define glNormalStream3iATI _al_glNormalStream3iATI +#define glNormalStream3ivATI _al_glNormalStream3ivATI +#define glNormalStream3fATI _al_glNormalStream3fATI +#define glNormalStream3fvATI _al_glNormalStream3fvATI +#define glNormalStream3dATI _al_glNormalStream3dATI +#define glNormalStream3dvATI _al_glNormalStream3dvATI +#define glClientActiveVertexStreamATI _al_glClientActiveVertexStreamATI +#define glVertexBlendEnviATI _al_glVertexBlendEnviATI +#define glVertexBlendEnvfATI _al_glVertexBlendEnvfATI +#endif + +#if defined _ALLEGRO_GL_ATI_element_array +#define glElementPointerATI _al_glElementPointerATI +#define glDrawElementArrayATI _al_glDrawElementArrayATI +#define glDrawRangeElementArrayATI _al_glDrawRangeElementArrayATI +#endif + +#if defined _ALLEGRO_GL_SUN_mesh_array +#define glDrawMeshArraysSUN _al_glDrawMeshArraysSUN +#endif + +#if defined _ALLEGRO_GL_NV_occlusion_query +#define glGenOcclusionQueriesNV _al_glGenOcclusionQueriesNV +#define glDeleteOcclusionQueriesNV _al_glDeleteOcclusionQueriesNV +#define glIsOcclusionQueryNV _al_glIsOcclusionQueryNV +#define glBeginOcclusionQueryNV _al_glBeginOcclusionQueryNV +#define glEndOcclusionQueryNV _al_glEndOcclusionQueryNV +#define glGetOcclusionQueryivNV _al_glGetOcclusionQueryivNV +#define glGetOcclusionQueryuivNV _al_glGetOcclusionQueryuivNV +#endif + +#if defined _ALLEGRO_GL_NV_point_sprite +#define glPointParameteriNV _al_glPointParameteriNV +#define glPointParameterivNV _al_glPointParameterivNV +#endif + +#if defined _ALLEGRO_GL_EXT_stencil_two_side +#define glActiveStencilFaceEXT _al_glActiveStencilFaceEXT +#endif + +#if defined _ALLEGRO_GL_APPLE_element_array +#define glElementPointerAPPLE _al_glElementPointerAPPLE +#define glDrawElementArrayAPPLE _al_glDrawElementArrayAPPLE +#define glDrawRangeElementArrayAPPLE _al_glDrawRangeElementArrayAPPLE +#define glMultiDrawElementArrayAPPLE _al_glMultiDrawElementArrayAPPLE +#define glMultiDrawRangeElementArrayAPPLE _al_glMultiDrawRangeElementArrayAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_fence +#define glGenFencesAPPLE _al_glGenFencesAPPLE +#define glDeleteFencesAPPLE _al_glDeleteFencesAPPLE +#define glSetFenceAPPLE _al_glSetFenceAPPLE +#define glIsFenceAPPLE _al_glIsFenceAPPLE +#define glTestFenceAPPLE _al_glTestFenceAPPLE +#define glFinishFenceAPPLE _al_glFinishFenceAPPLE +#define glTestObjectAPPLE _al_glTestObjectAPPLE +#define glFinishObjectAPPLE _al_glFinishObjectAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_array_object +#define glBindVertexArrayAPPLE _al_glBindVertexArrayAPPLE +#define glDeleteVertexArraysAPPLE _al_glDeleteVertexArraysAPPLE +#define glGenVertexArraysAPPLE _al_glGenVertexArraysAPPLE +#define glIsVertexArrayAPPLE _al_glIsVertexArrayAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_array_range +#define glVertexArrayRangeAPPLE _al_glVertexArrayRangeAPPLE +#define glFlushVertexArrayRangeAPPLE _al_glFlushVertexArrayRangeAPPLE +#define glVertexArrayParameteriAPPLE _al_glVertexArrayParameteriAPPLE +#endif + +#if defined _ALLEGRO_GL_ATI_draw_buffers +#define glDrawBuffersATI _al_glDrawBuffersATI +#endif + +#if defined _ALLEGRO_GL_NV_fragment_program +#define glProgramNamedParameter4fNV _al_glProgramNamedParameter4fNV +#define glProgramNamedParameter4dNV _al_glProgramNamedParameter4dNV +#define glProgramNamedParameter4fvNV _al_glProgramNamedParameter4fvNV +#define glProgramNamedParameter4dvNV _al_glProgramNamedParameter4dvNV +#define glGetProgramNamedParameterfvNV _al_glGetProgramNamedParameterfvNV +#define glGetProgramNamedParameterdvNV _al_glGetProgramNamedParameterdvNV +#endif + +#if defined _ALLEGRO_GL_NV_half_float +#define glVertex2hNV _al_glVertex2hNV +#define glVertex2hvNV _al_glVertex2hvNV +#define glVertex3hNV _al_glVertex3hNV +#define glVertex3hvNV _al_glVertex3hvNV +#define glVertex4hNV _al_glVertex4hNV +#define glVertex4hvNV _al_glVertex4hvNV +#define glNormal3hNV _al_glNormal3hNV +#define glNormal3hvNV _al_glNormal3hvNV +#define glColor3hNV _al_glColor3hNV +#define glColor3hvNV _al_glColor3hvNV +#define glColor4hNV _al_glColor4hNV +#define glColor4hvNV _al_glColor4hvNV +#define glTexCoord1hNV _al_glTexCoord1hNV +#define glTexCoord1hvNV _al_glTexCoord1hvNV +#define glTexCoord2hNV _al_glTexCoord2hNV +#define glTexCoord2hvNV _al_glTexCoord2hvNV +#define glTexCoord3hNV _al_glTexCoord3hNV +#define glTexCoord3hvNV _al_glTexCoord3hvNV +#define glTexCoord4hNV _al_glTexCoord4hNV +#define glTexCoord4hvNV _al_glTexCoord4hvNV +#define glMultiTexCoord1hNV _al_glMultiTexCoord1hNV +#define glMultiTexCoord1hvNV _al_glMultiTexCoord1hvNV +#define glMultiTexCoord2hNV _al_glMultiTexCoord2hNV +#define glMultiTexCoord2hvNV _al_glMultiTexCoord2hvNV +#define glMultiTexCoord3hNV _al_glMultiTexCoord3hNV +#define glMultiTexCoord3hvNV _al_glMultiTexCoord3hvNV +#define glMultiTexCoord4hNV _al_glMultiTexCoord4hNV +#define glMultiTexCoord4hvNV _al_glMultiTexCoord4hvNV +#define glFogCoordhNV _al_glFogCoordhNV +#define glFogCoordhvNV _al_glFogCoordhvNV +#define glSecondaryColor3hNV _al_glSecondaryColor3hNV +#define glSecondaryColor3hvNV _al_glSecondaryColor3hvNV +#define glVertexWeighthNV _al_glVertexWeighthNV +#define glVertexWeighthvNV _al_glVertexWeighthvNV +#define glVertexAttrib1hNV _al_glVertexAttrib1hNV +#define glVertexAttrib1hvNV _al_glVertexAttrib1hvNV +#define glVertexAttrib2hNV _al_glVertexAttrib2hNV +#define glVertexAttrib2hvNV _al_glVertexAttrib2hvNV +#define glVertexAttrib3hNV _al_glVertexAttrib3hNV +#define glVertexAttrib3hvNV _al_glVertexAttrib3hvNV +#define glVertexAttrib4hNV _al_glVertexAttrib4hNV +#define glVertexAttrib4hvNV _al_glVertexAttrib4hvNV +#define glVertexAttribs1hvNV _al_glVertexAttribs1hvNV +#define glVertexAttribs2hvNV _al_glVertexAttribs2hvNV +#define glVertexAttribs3hvNV _al_glVertexAttribs3hvNV +#define glVertexAttribs4hvNV _al_glVertexAttribs4hvNV +#endif + +#if defined _ALLEGRO_GL_NV_pixel_data_range +#define glPixelDataRangeNV _al_glPixelDataRangeNV +#define glFlushPixelDataRangeNV _al_glFlushPixelDataRangeNV +#endif + +#if defined _ALLEGRO_GL_NV_primitive_restart +#define glPrimitiveRestartNV _al_glPrimitiveRestartNV +#define glPrimitiveRestartIndexNV _al_glPrimitiveRestartIndexNV +#endif + +#if defined _ALLEGRO_GL_ATI_map_object_buffer +#define glMapObjectBufferATI _al_glMapObjectBufferATI +#define glUnmapObjectBufferATI _al_glUnmapObjectBufferATI +#endif + +#if defined _ALLEGRO_GL_ATI_separate_stencil +#define glStencilOpSeparateATI _al_glStencilOpSeparateATI +#define glStencilFuncSeparateATI _al_glStencilFuncSeparateATI +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_attrib_array_object +#define glVertexAttribArrayObjectATI _al_glVertexAttribArrayObjectATI +#define glGetVertexAttribArrayObjectfvATI _al_glGetVertexAttribArrayObjectfvATI +#define glGetVertexAttribArrayObjectivATI _al_glGetVertexAttribArrayObjectivATI +#endif + +#if defined _ALLEGRO_GL_OES_byte_coordinates +#define glVertex2bOES _al_glVertex2bOES +#define glVertex3bOES _al_glVertex3bOES +#define glVertex4bOES _al_glVertex4bOES +#define glVertex2bvOES _al_glVertex2bvOES +#define glVertex3bvOES _al_glVertex3bvOES +#define glVertex4bvOES _al_glVertex4bvOES +#define glTexCoord1bOES _al_glTexCoord1bOES +#define glTexCoord2bOES _al_glTexCoord2bOES +#define glTexCoord3bOES _al_glTexCoord3bOES +#define glTexCoord4bOES _al_glTexCoord4bOES +#define glTexCoord1bvOES _al_glTexCoord1bvOES +#define glTexCoord2bvOES _al_glTexCoord2bvOES +#define glTexCoord3bvOES _al_glTexCoord3bvOES +#define glTexCoord4bvOES _al_glTexCoord4bvOES +#define glMultiTexCoord1bOES _al_glMultiTexCoord1bOES +#define glMultiTexCoord2bOES _al_glMultiTexCoord2bOES +#define glMultiTexCoord3bOES _al_glMultiTexCoord3bOES +#define glMultiTexCoord4bOES _al_glMultiTexCoord4bOES +#define glMultiTexCoord1bvOES _al_glMultiTexCoord1bvOES +#define glMultiTexCoord2bvOES _al_glMultiTexCoord2bvOES +#define glMultiTexCoord3bvOES _al_glMultiTexCoord3bvOES +#define glMultiTexCoord4bvOES _al_glMultiTexCoord4bvOES +#endif + +#if defined _ALLEGRO_GL_OES_fixed_point +#define glVertex2xOES _al_glVertex2xOES +#define glVertex3xOES _al_glVertex3xOES +#define glVertex4xOES _al_glVertex4xOES +#define glVertex2xvOES _al_glVertex2xvOES +#define glVertex3xvOES _al_glVertex3xvOES +#define glVertex4xvOES _al_glVertex4xvOES +#define glNormal3xOES _al_glNormal3xOES +#define glNormal3xvOES _al_glNormal3xvOES +#define glTexCoord1xOES _al_glTexCoord1xOES +#define glTexCoord2xOES _al_glTexCoord2xOES +#define glTexCoord3xOES _al_glTexCoord3xOES +#define glTexCoord4xOES _al_glTexCoord4xOES +#define glTexCoord1xvOES _al_glTexCoord1xvOES +#define glTexCoord2xvOES _al_glTexCoord2xvOES +#define glTexCoord3xvOES _al_glTexCoord3xvOES +#define glTexCoord4xvOES _al_glTexCoord4xvOES +#define glMultiTexCoord1xOES _al_glMultiTexCoord1xOES +#define glMultiTexCoord2xOES _al_glMultiTexCoord2xOES +#define glMultiTexCoord3xOES _al_glMultiTexCoord3xOES +#define glMultiTexCoord4xOES _al_glMultiTexCoord4xOES +#define glMultiTexCoord1xvOES _al_glMultiTexCoord1xvOES +#define glMultiTexCoord2xvOES _al_glMultiTexCoord2xvOES +#define glMultiTexCoord3xvOES _al_glMultiTexCoord3xvOES +#define glMultiTexCoord4xvOES _al_glMultiTexCoord4xvOES +#define glColor3xOES _al_glColor3xOES +#define glColor4xOES _al_glColor4xOES +#define glColor3xvOES _al_glColor3xvOES +#define glColor4xvOES _al_glColor4xvOES +#define glIndexxOES _al_glIndexxOES +#define glIndexxvOES _al_glIndexxvOES +#define glRectxOES _al_glRectxOES +#define glRectxvOES _al_glRectxvOES +#define glDepthRangexOES _al_glDepthRangexOES +#define glLoadMatrixxOES _al_glLoadMatrixxOES +#define glMultMatrixxOES _al_glMultMatrixxOES +#define glLoadTransposeMatrixxOES _al_glLoadTransposeMatrixxOES +#define glMultTransposeMatrixxOES _al_glMultTransposeMatrixxOES +#define glRotatexOES _al_glRotatexOES +#define glScalexOES _al_glScalexOES +#define glTranslatexOES _al_glTranslatexOES +#define glFrustumxOES _al_glFrustumxOES +#define glOrthoxOES _al_glOrthoxOES +#define glTexGenxOES _al_glTexGenxOES +#define glTexGenxvOES _al_glTexGenxvOES +#define glGetTexGenxvOES _al_glGetTexGenxvOES +#define glClipPlanexOES _al_glClipPlanexOES +#define glGetClipPlanexOES _al_glGetClipPlanexOES +#define glRasterPos2xOES _al_glRasterPos2xOES +#define glRasterPos3xOES _al_glRasterPos3xOES +#define glRasterPos4xOES _al_glRasterPos4xOES +#define glRasterPos2xvOES _al_glRasterPos2xvOES +#define glRasterPos3xvOES _al_glRasterPos3xvOES +#define glRasterPos4xvOES _al_glRasterPos4xvOES +#define glMaterialxOES _al_glMaterialxOES +#define glMaterialxvOES _al_glMaterialxvOES +#define glGetMaterialxOES _al_glGetMaterialxOES +#define glLightxOES _al_glLightxOES +#define glLightxvOES _al_glLightxvOES +#define glGetLightxOES _al_glGetLightxOES +#define glLightModelxOES _al_glLightModelxOES +#define glLightModelxvOES _al_glLightModelxvOES +#define glPointSizexOES _al_glPointSizexOES +#define glLineWidthxOES _al_glLineWidthxOES +#define glPolygonOffsetxOES _al_glPolygonOffsetxOES +#define glPixelStorex _al_glPixelStorex +#define glPixelTransferxOES _al_glPixelTransferxOES +#define glPixelMapx _al_glPixelMapx +#define glGetPixelMapxv _al_glGetPixelMapxv +#define glConvolutionParameterxOES _al_glConvolutionParameterxOES +#define glConvolutionParameterxvOES _al_glConvolutionParameterxvOES +#define glGetConvolutionParameterxvOES _al_glGetConvolutionParameterxvOES +#define glGetHistogramParameterxvOES _al_glGetHistogramParameterxvOES +#define glPixelZoomxOES _al_glPixelZoomxOES +#define glBitmapxOES _al_glBitmapxOES +#define glTexParameterxOES _al_glTexParameterxOES +#define glTexParameterxvOES _al_glTexParameterxvOES +#define glGetTexParameterxvOES _al_glGetTexParameterxvOES +#define glGetTexLevelParameterxvOES _al_glGetTexLevelParameterxvOES +#define glPrioritizeTexturesxOES _al_glPrioritizeTexturesxOES +#define glTexEnvxOES _al_glTexEnvxOES +#define glTexEnvxvOES _al_glTexEnvxvOES +#define glGetTexEnvxvOES _al_glGetTexEnvxvOES +#define glFogxOES _al_glFogxOES +#define glFogxvOES _al_glFogxvOES +#define glSampleCoverageOES _al_glSampleCoverageOES +#define glAlphaFuncxOES _al_glAlphaFuncxOES +#define glBlendColorxOES _al_glBlendColorxOES +#define glClearColorxOES _al_glClearColorxOES +#define glClearDepthxOES _al_glClearDepthxOES +#define glClearAccumxOES _al_glClearAccumxOES +#define glAccumxOES _al_glAccumxOES +#define glMap1xOES _al_glMap1xOES +#define glMap2xOES _al_glMap2xOES +#define glMapGrid1xOES _al_glMapGrid1xOES +#define glMapGrid2xOES _al_glMapGrid2xOES +#define glGetMapxvOES _al_glGetMapxvOES +#define glEvalCoord1xOES _al_glEvalCoord1xOES +#define glEvalCoord2xOES _al_glEvalCoord2xOES +#define glEvalCoord1xvOES _al_glEvalCoord1xvOES +#define glEvalCoord2xvOES _al_glEvalCoord2xvOES +#define glFeedbackBufferxOES _al_glFeedbackBufferxOES +#define glPassThroughxOES _al_glPassThroughxOES +#define glGetFixedvOES _al_glGetFixedvOES +#endif + +#if defined _ALLEGRO_GL_OES_single_precision +#define glDepthRangefOES _al_glDepthRangefOES +#define glFrustumfOES _al_glFrustumfOES +#define glOrthofOES _al_glOrthofOES +#define glClipPlanefOES _al_glClipPlanefOES +#define glGetClipPlanefOES _al_glGetClipPlanefOES +#define glClearDepthfOES _al_glClearDepthfOES +#endif + +#if defined _ALLEGRO_GL_OES_query_matrix +#define glQueryMatrixxOES _al_glQueryMatrixxOES +#endif + +#if defined _ALLEGRO_GL_EXT_depth_bounds_test +#define glDepthBoundsEXT _al_glDepthBoundsEXT +#endif + + +#if defined _ALLEGRO_GL_EXT_blend_equation_separate +#define glBlendEquationSeparateEXT _al_glBlendEquationSeparateEXT +#endif + + +#if defined _ALLEGRO_GL_EXT_framebuffer_object +#define glIsRenderbufferEXT _al_glIsRenderbufferEXT +#define glBindRenderbufferEXT _al_glBindRenderbufferEXT +#define glDeleteRenderbuffersEXT _al_glDeleteRenderbuffersEXT +#define glGenRenderbuffersEXT _al_glGenRenderbuffersEXT +#define glRenderbufferStorageEXT _al_glRenderbufferStorageEXT +#define glGetRenderbufferParameterivEXT _al_glGetRenderbufferParameterivEXT +#define glIsFramebufferEXT _al_glIsFramebufferEXT +#define glBindFramebufferEXT _al_glBindFramebufferEXT +#define glDeleteFramebuffersEXT _al_glDeleteFramebuffersEXT +#define glGenFramebuffersEXT _al_glGenFramebuffersEXT +#define glCheckFramebufferStatusEXT _al_glCheckFramebufferStatusEXT +#define glFramebufferTexture1DEXT _al_glFramebufferTexture1DEXT +#define glFramebufferTexture2DEXT _al_glFramebufferTexture2DEXT +#define glFramebufferTexture3DEXT _al_glFramebufferTexture3DEXT +#define glFramebufferRenderbufferEXT _al_glFramebufferRenderbufferEXT +#define glGetFramebufferAttachmentParameterivEXT _al_glGetFramebufferAttachmentParameterivEXT +#define glGenerateMipmapEXT _al_glGenerateMipmapEXT +#endif + +#if defined _ALLEGRO_GL_GREMEDY_string_marker +#define glStringMarkerGREMEDY _al_glStringMarkerGREMEDY +#endif + +#if defined _ALLEGRO_GL_EXT_stencil_clear_tag +#define glStencilClearTagEXT _al_glStencilClearTagEXT +#endif + +#if defined _ALLEGRO_GL_EXT_framebuffer_blit +#define glBlitFramebufferEXT _al_glBlitFramebufferEXT +#endif + +#if defined _ALLEGRO_GL_EXT_framebuffer_multisample +#define glRenderbufferStorageMultisampleEXT _al_glRenderbufferStorageMultisampleEXT +#endif + +#if defined _ALLEGRO_GL_EXT_timer_query +#define glGetQueryObjecti64vEXT _al_glGetQueryObjecti64vEXT +#define glGetQueryObjectui64vEXT _al_glGetQueryObjectui64vEXT +#endif + +#if defined _ALLEGRO_GL_EXT_gpu_program_parameters +#define glProgramEnvParameters4fvEXT _al_glProgramEnvParameters4fvEXT +#define glProgramLocalParameters4fvEXT _al_glProgramLocalParameters4fvEXT +#endif + +#if defined _ALLEGRO_GL_APPLE_flush_buffer_range +#define glBufferParameteriAPPLE _al_glBufferParameteriAPPLE +#define glFlushMappedBufferRangeAPPLE _al_glFlushMappedBufferRangeAPPLE +#endif + +#if defined _ALLEGRO_GL_EXT_bindable_uniform +#define glUniformBufferEXT _al_glUniformBufferEXT +#define glGetUniformBufferSizeEXT _al_glGetUniformBufferSizeEXT +#define glGetUniformOffsetEXT _al_glGetUniformOffsetEXT +#endif + +#if defined _ALLEGRO_GL_EXT_draw_buffers2 +#define glColorMaskIndexedEXT _al_glColorMaskIndexedEXT +#define glGetBooleanIndexedvEXT _al_glGetBooleanIndexedvEXT +#define glGetIntegerIndexedvEXT _al_glGetIntegerIndexedvEXT +#define glEnableIndexedEXT _al_glEnableIndexedEXT +#define glDisableIndexedEXT _al_glDisableIndexedEXT +#define glIsEnabledIndexedEXT _al_glIsEnabledIndexedEXT +#endif + +#if defined _ALLEGRO_GL_EXT_draw_instanced +#define glDrawArraysInstancedEXT _al_glDrawArraysInstancedEXT +#define glDrawElementsInstancedEXT _al_glDrawElementsInstancedEXT +#endif + +#if defined _ALLEGRO_GL_EXT_geometry_shader4 +#define glProgramParameteriEXT _al_glProgramParameteriEXT +#define glFramebufferTextureEXT _al_glFramebufferTextureEXT +#if !defined _ALLEGRO_GL_EXT_texture_array +#define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT +#endif +#define glFramebufferTextureFaceEXT _al_glFramebufferTextureFaceEXT +#endif + +#if defined _ALLEGRO_GL_EXT_gpu_shader4 +#define glVertexAttribI1iEXT _al_glVertexAttribI1iEXT +#define glVertexAttribI2iEXT _al_glVertexAttribI2iEXT +#define glVertexAttribI3iEXT _al_glVertexAttribI3iEXT +#define glVertexAttribI4iEXT _al_glVertexAttribI4iEXT +#define glVertexAttribI1uiEXT _al_glVertexAttribI1uiEXT +#define glVertexAttribI2uiEXT _al_glVertexAttribI2uiEXT +#define glVertexAttribI3uiEXT _al_glVertexAttribI3uiEXT +#define glVertexAttribI4uiEXT _al_glVertexAttribI4uiEXT +#define glVertexAttribI1ivEXT _al_glVertexAttribI1ivEXT +#define glVertexAttribI2ivEXT _al_glVertexAttribI2ivEXT +#define glVertexAttribI3ivEXT _al_glVertexAttribI3ivEXT +#define glVertexAttribI4ivEXT _al_glVertexAttribI4ivEXT +#define glVertexAttribI1uivEXT _al_glVertexAttribI1uivEXT +#define glVertexAttribI2uivEXT _al_glVertexAttribI2uivEXT +#define glVertexAttribI3uivEXT _al_glVertexAttribI3uivEXT +#define glVertexAttribI4uivEXT _al_glVertexAttribI4uivEXT +#define glVertexAttribI4bvEXT _al_glVertexAttribI4bvEXT +#define glVertexAttribI4svEXT _al_glVertexAttribI4svEXT +#define glVertexAttribI4ubvEXT _al_glVertexAttribI4ubvEXT +#define glVertexAttribI4usvEXT _al_glVertexAttribI4usvEXT +#define glVertexAttribIPointerEXT _al_glVertexAttribIPointerEXT +#define glGetVertexAttribIivEXT _al_glGetVertexAttribIivEXT +#define glGetVertexAttribIuivEXT _al_glGetVertexAttribIuivEXT +#define glUniform1uiEXT _al_glUniform1uiEXT +#define glUniform2uiEXT _al_glUniform2uiEXT +#define glUniform3uiEXT _al_glUniform3uiEXT +#define glUniform4uiEXT _al_glUniform4uiEXT +#define glUniform1uivEXT _al_glUniform1uivEXT +#define glUniform2uivEXT _al_glUniform2uivEXT +#define glUniform3uivEXT _al_glUniform3uivEXT +#define glUniform4uivEXT _al_glUniform4uivEXT +#define glGetUniformuivEXT _al_glGetUniformuivEXT +#define glBindFragDataLocationEXT _al_glBindFragDataLocationEXT +#define glGetFragDataLocationEXT _al_glGetFragDataLocationEXT +#endif + +#if defined _ALLEGRO_GL_EXT_texture_array +#define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT +#endif + +#if defined _ALLEGRO_GL_EXT_texture_buffer_object +#define glTexBufferEXT _al_glTexBufferEXT +#endif + +#if defined _ALLEGRO_GL_texture_integer +#define glClearColorIiEXT _al_glClearColorIiEXT +#define glClearColorIuiEXT _al_glClearColorIuiEXT +#define glTexParameterIivEXT _al_glTexParameterIivEXT +#define glTexParameterIuivEXT _al_glTexParameterIuivEXT +#define glGetTexParameterIivEXT _al_glGetTexParameterIivEXT +#define glGetTexParameterIiuvEXT _al_glGetTexParameterIiuvEXT +#endif + +#if defined _ALLEGRO_GL_NV_depth_buffer_float +#define glDepthRangedNV _al_glDepthRangedNV +#define glClearDepthdNV _al_glClearDepthdNV +#define glDepthBoundsdNV _al_glDepthBoundsdNV +#endif + +#if defined _ALLEGRO_GL_NV_framebuffer_multisample_coverage +#define glRenderbufferStorageMultsampleCoverageNV _al_glRenderbufferStorageMultsampleCoverageNV +#endif + +#if defined _ALLEGRO_GL_NV_geometry_program4 +#define glProgramVertexLimitNV _al_glProgramVertexLimitNV +#if !defined _ALLEGRO_GL_EXT_geometry_shader4 +#define glFramebufferTextureEXT _al_glFramebufferTextureEXT +#if !defined _ALLEGRO_GL_EXT_texture_array +#define glFramebufferTextureLayerEXT _al_glFramebufferTextureLayerEXT +#endif +#endif +#endif + +#if defined _ALLEGRO_GL_NV_gpu_program4 +#define glProgramLocalParameterI4iNV _al_glProgramLocalParameterI4iNV +#define glProgramLocalParameterI4ivNV _al_glProgramLocalParameterI4ivNV +#define glProgramLocalParametersI4ivNV _al_glProgramLocalParametersI4ivNV +#define glProgramLocalParameterI4uiNV _al_glProgramLocalParameterI4uiNV +#define glProgramLocalParameterI4uivNV _al_glProgramLocalParameterI4uivNV +#define glProgramLocalParametersI4uivNV _al_glProgramLocalParametersI4uivNV +#define glProgramEnvParameterI4iNV _al_glProgramEnvParameterI4iNV +#define glProgramEnvParameterI4ivNV _al_glProgramEnvParameterI4ivNV +#define glProgramEnvParametersI4ivNV _al_glProgramEnvParametersI4ivNV +#define glProgramEnvParameterI4uiNV _al_glProgramEnvParameterI4uiNV +#define glProgramEnvParameterI4uivNV _al_glProgramEnvParameterI4uivNV +#define glProgramEnvParametersI4uivNV _al_glProgramEnvParametersI4uivNV +#define glGetProgramLocalParameterIivNV _al_glGetProgramLocalParameterIivNV +#define glGetProgramLocalParameterIuivNV _al_glGetProgramLocalParameterIuivNV +#define glGetProgramEnvParameterIivNV _al_glGetProgramEnvParameterIivNV +#define glGetProgramEnvParameterIuivNV _al_glGetProgramEnvParameterIuivNV +#endif + +#if defined _ALLEGRO_GL_NV_parameter_buffer_object +#if !defined _ALLEGRO_GL_NV_transform_feedback +#define glBindBufferRangeNV _al_glBindBufferRangeNV +#define glBindBufferOffsetNV _al_glBindBufferOffsetNV +#define glBindBufferBaseNV _al_glBindBufferBaseNV +#endif +#define glProgramBufferParametersfvNV _al_glProgramBufferParametersfvNV +#define glProgramBufferParametersIivNV _al_glProgramBufferParametersIivNV +#define glProgramBufferParametersIuivNV _al_glProgramBufferParametersIuivNV +#if !defined _ALLEGRO_GL_EXT_draw_buffers2 +#define glGetIntegerIndexedvEXT _al_glGetIntegerIndexedvEXT +#endif +#endif + +#if defined _ALLEGRO_GL_NV_transform_feedback +#define glBindBufferRangeNV _al_glBindBufferRangeNV +#define glBindBufferOffsetNV _al_glBindBufferOffsetNV +#define glBindBufferBaseNV _al_glBindBufferBaseNV +#define glTransformFeedbackAttribsNV _al_glTransformFeedbackAttribsNV +#define glTransformFeedbackVaryingsNV _al_glTransformFeedbackVaryingsNV +#define glBeginTransformFeedbackNV _al_glBeginTransformFeedbackNV +#define glEndTransformFeedbackNV _al_glEndTransformFeedbackNV +#define glGetVaryingLocationNV _al_glGetVaryingLocationNV +#define glGetActiveVaryingNV _al_glGetActiveVaryingNV +#define glActiveVaryingNV _al_glActiveVaryingNV +#define glGetTransformFeedbackVaryingNV _al_glGetTransformFeedbackVaryingNV +#if !defined _ALLEGRO_GL_EXT_draw_buffers2 +#define glGetBooleanIndexedvEXT _al_glGetBooleanIndexedvEXT +/*AGL_API(void,GetIntegerIndexedvEXT,(GLenum,GLuint,GLint*))*/ +#endif +#endif + +#if defined _ALLEGRO_GL_NV_vertex_program4 +#ifndef _ALLEGRO_GL_EXT_gpu_shader4 +#define glVertexAttribI1iEXT _al_glVertexAttribI1iEXT +#define glVertexAttribI2iEXT _al_glVertexAttribI2iEXT +#define glVertexAttribI3iEXT _al_glVertexAttribI3iEXT +#define glVertexAttribI4iEXT _al_glVertexAttribI4iEXT +#define glVertexAttribI1uiEXT _al_glVertexAttribI1uiEXT +#define glVertexAttribI2uiEXT _al_glVertexAttribI2uiEXT +#define glVertexAttribI3uiEXT _al_glVertexAttribI3uiEXT +#define glVertexAttribI4uiEXT _al_glVertexAttribI4uiEXT +#define glVertexAttribI1ivEXT _al_glVertexAttribI1ivEXT +#define glVertexAttribI2ivEXT _al_glVertexAttribI2ivEXT +#define glVertexAttribI3ivEXT _al_glVertexAttribI3ivEXT +#define glVertexAttribI4ivEXT _al_glVertexAttribI4ivEXT +#define glVertexAttribI1uivEXT _al_glVertexAttribI1uivEXT +#define glVertexAttribI2uivEXT _al_glVertexAttribI2uivEXT +#define glVertexAttribI3uivEXT _al_glVertexAttribI3uivEXT +#define glVertexAttribI4uivEXT _al_glVertexAttribI4uivEXT +#define glVertexAttribI4bvEXT _al_glVertexAttribI4bvEXT +#define glVertexAttribI4svEXT _al_glVertexAttribI4svEXT +#define glVertexAttribI4ubvEXT _al_glVertexAttribI4ubvEXT +#define glVertexAttribI4usvEXT _al_glVertexAttribI4usvEXT +#define glVertexAttribIPointerEXT _al_glVertexAttribIPointerEXT +#define glGetVertexAttribIivEXT _al_glGetVertexAttribIivEXT +#define glGetVertexAttribIuivEXT _al_glGetVertexAttribIuivEXT +#endif +#endif + +#if defined _ALLEGRO_GL_GREMEDY_frame_terminator +#define glFrameTerminatorGREMEDY _al_glFrameTerminatorGREMEDY +#endif + +#if defined _ALLEGRO_GL_NV_conditional_render +#define glBeginConditionalRenderNV _al_glBeginConditionalRenderNV +#define glEndConditionalRenderNV _al_glEndConditionalRenderNV +#endif + +#if defined _ALLEGRO_GL_EXT_transform_feedback +#define glBeginTransformFeedbackEXT _al_glBeginTransformFeedbackEXT +#define glEndTransformFeedbackEXT _al_glEndTransformFeedbackEXT +#define glBindBufferRangeEXT _al_glBindBufferRangeEXT +#define glBindBufferOffsetEXT _al_glBindBufferOffsetEXT +#define glBindBufferBaseEXT _al_glBindBufferBaseEXT +#define glTransformFeedbackVaryingsEXT _al_glTransformFeedbackVaryingsEXT +#define glGetTransformFeedbackVaryingEXT _al_glGetTransformFeedbackVaryingEXT +#endif + +#if defined _ALLEGRO_GL_EXT_direct_state_access +#define glClientAttribDefaultEXT _al_glClientAttribDefaultEXT +#define glPushClientAttribDefaultEXT _al_glPushClientAttribDefaultEXT +#define glMatrixLoadfEXT _al_glMatrixLoadfEXT +#define glMatrixLoaddEXT _al_glMatrixLoaddEXT +#define glMatrixMultfEXT _al_glMatrixMultfEXT +#define glMatrixMultdEXT _al_glMatrixMultdEXT +#define glMatrixLoadIdentityEXT _al_glMatrixLoadIdentityEXT +#define glMatrixRotatefEXT _al_glMatrixRotatefEXT +#define glMatrixRotatedEXT _al_glMatrixRotatedEXT +#define glMatrixScalefEXT _al_glMatrixScalefEXT +#define glMatrixScaledEXT _al_glMatrixScaledEXT +#define glMatrixTranslatefEXT _al_glMatrixTranslatefEXT +#define glMatrixTranslatedEXT _al_glMatrixTranslatedEXT +#define glMatrixFrustumEXT _al_glMatrixFrustumEXT +#define glMatrixOrthoEXT _al_glMatrixOrthoEXT +#define glMatrixPopEXT _al_glMatrixPopEXT +#define glMatrixPushEXT _al_glMatrixPushEXT +#define glMatrixLoadTransposefEXT _al_glMatrixLoadTransposefEXT +#define glMatrixLoadTransposedEXT _al_glMatrixLoadTransposedEXT +#define glMatrixMultTransposefEXT _al_glMatrixMultTransposefEXT +#define glMatrixMultTransposedEXT _al_glMatrixMultTransposedEXT +#define glTextureParameterfEXT _al_glTextureParameterfEXT +#define glTextureParameterfvEXT _al_glTextureParameterfvEXT +#define glTextureParameteriEXT _al_glTextureParameteriEXT +#define glTextureParameterivEXT _al_glTextureParameterivEXT +#define glTextureImage1DEXT _al_glTextureImage1DEXT +#define glTextureImage2DEXT _al_glTextureImage2DEXT +#define glTextureSubImage1DEXT _al_glTextureSubImage1DEXT +#define glTextureSubImage2DEXT _al_glTextureSubImage2DEXT +#define glCopyTextureImage1DEXT _al_glCopyTextureImage1DEXT +#define glCopyTextureImage2DEXT _al_glCopyTextureImage2DEXT +#define glCopyTextureSubImage1DEXT _al_glCopyTextureSubImage1DEXT +#define glCopyTextureSubImage2DEXT _al_glCopyTextureSubImage2DEXT +#define glGetTextureImageEXT _al_glGetTextureImageEXT +#define glGetTextureParameterfvEXT _al_glGetTextureParameterfvEXT +#define glGetTextureParameterivEXT _al_glGetTextureParameterivEXT +#define glGetTextureLevelParameterfvEXT _al_glGetTextureLevelParameterfvEXT +#define glGetTextureLevelParameterivEXT _al_glGetTextureLevelParameterivEXT +#define glTextureImage3DEXT _al_glTextureImage3DEXT +#define glTextureSubImage3DEXT _al_glTextureSubImage3DEXT +#define glCopyTextureSubImage3DEXT _al_glCopyTextureSubImage3DEXT +#define glMultiTexParameterfEXT _al_glMultiTexParameterfEXT +#define glMultiTexParameterfvEXT _al_glMultiTexParameterfvEXT +#define glMultiTexParameteriEXT _al_glMultiTexParameteriEXT +#define glMultiTexParameterivEXT _al_glMultiTexParameterivEXT +#define glMultiTexImage1DEXT _al_glMultiTexImage1DEXT +#define glMultiTexImage2DEXT _al_glMultiTexImage2DEXT +#define glMultiTexSubImage1DEXT _al_glMultiTexSubImage1DEXT +#define glMultiTexSubImage2DEXT _al_glMultiTexSubImage2DEXT +#define glCopyMultiTexImage1DEXT _al_glCopyMultiTexImage1DEXT +#define glCopyMultiTexImage2DEXT _al_glCopyMultiTexImage2DEXT +#define glCopyMultiTexSubImage1DEXT _al_glCopyMultiTexSubImage1DEXT +#define glCopyMultiTexSubImage2DEXT _al_glCopyMultiTexSubImage2DEXT +#define glGetMultiTexImageEXT _al_glGetMultiTexImageEXT +#define glGetMultiTexParameterfvEXT _al_glGetMultiTexParameterfvEXT +#define glGetMultiTexParameterivEXT _al_glGetMultiTexParameterivEXT +#define glGetMultiTexLevelParameterfvEXT _al_glGetMultiTexLevelParameterfvEXT +#define glGetMultiTexLevelParameterivEXT _al_glGetMultiTexLevelParameterivEXT +#define glMultiTexImage3DEXT _al_glMultiTexImage3DEXT +#define glMultiTexSubImage3DEXT _al_glMultiTexSubImage3DEXT +#define glCopyMultiTexSubImage3DEXT _al_glCopyMultiTexSubImage3DEXT +#define glBindMultiTextureEXT _al_glBindMultiTextureEXT +#define glEnableClientStateIndexedEXT _al_glEnableClientStateIndexedEXT +#define glDisableClientStateIndexedEXT _al_glDisableClientStateIndexedEXT +#define glMultiTexCoordPointerEXT _al_glMultiTexCoordPointerEXT +#define glMultiTexEnvfEXT _al_glMultiTexEnvfEXT +#define glMultiTexEnvfvEXT _al_glMultiTexEnvfvEXT +#define glMultiTexEnviEXT _al_glMultiTexEnviEXT +#define glMultiTexEnvivEXT _al_glMultiTexEnvivEXT +#define glMultiTexGendEXT _al_glMultiTexGendEXT +#define glMultiTexGendvEXT _al_glMultiTexGendvEXT +#define glMultiTexGenfEXT _al_glMultiTexGenfEXT +#define glMultiTexGenfvEXT _al_glMultiTexGenfvEXT +#define glMultiTexGeniEXT _al_glMultiTexGeniEXT +#define glMultiTexGenivEXT _al_glMultiTexGenivEXT +#define glGetMultiTexEnvfvEXT _al_glGetMultiTexEnvfvEXT +#define glGetMultiTexEnvivEXT _al_glGetMultiTexEnvivEXT +#define glGetMultiTexGendvEXT _al_glGetMultiTexGendvEXT +#define glGetMultiTexGenfvEXT _al_glGetMultiTexGenfvEXT +#define glGetMultiTexGenivEXT _al_glGetMultiTexGenivEXT +#define glGetFloatIndexedvEXT _al_glGetFloatIndexedvEXT +#define glGetDoubleIndexedvEXT _al_glGetDoubleIndexedvEXT +#define glGetPointerIndexedvEXT _al_glGetPointerIndexedvEXT +#define glCompressedTextureImage3DEXT _al_glCompressedTextureImage3DEXT +#define glCompressedTextureImage2DEXT _al_glCompressedTextureImage2DEXT +#define glCompressedTextureImage1DEXT _al_glCompressedTextureImage1DEXT +#define glCompressedTextureSubImage3DEXT _al_glCompressedTextureSubImage3DEXT +#define glCompressedTextureSubImage2DEXT _al_glCompressedTextureSubImage2DEXT +#define glCompressedTextureSubImage1DEXT _al_glCompressedTextureSubImage1DEXT +#define glGetCompressedTextureImageEXT _al_glGetCompressedTextureImageEXT +#define glCompressedMultiTexImage3DEXT _al_glCompressedMultiTexImage3DEXT +#define glCompressedMultiTexImage2DEXT _al_glCompressedMultiTexImage2DEXT +#define glCompressedMultiTexImage1DEXT _al_glCompressedMultiTexImage1DEXT +#define glCompressedMultiTexSubImage3DEXT _al_glCompressedMultiTexSubImage3DEXT +#define glCompressedMultiTexSubImage2DEXT _al_glCompressedMultiTexSubImage2DEXT +#define glCompressedMultiTexSubImage1DEXT _al_glCompressedMultiTexSubImage1DEXT +#define glGetCompressedMultiTexImageEXT _al_glGetCompressedMultiTexImageEXT +#define glNamedProgramStringEXT _al_glNamedProgramStringEXT +#define glNamedProgramLocalParameter4dEXT _al_glNamedProgramLocalParameter4dEXT +#define glNamedProgramLocalParameter4dvEXT _al_glNamedProgramLocalParameter4dvEXT +#define glNamedProgramLocalParameter4fEXT _al_glNamedProgramLocalParameter4fEXT +#define glNamedProgramLocalParameter4fvEXT _al_glNamedProgramLocalParameter4fvEXT +#define glGetNamedProgramLocalParameterdvEXT _al_glGetNamedProgramLocalParameterdvEXT +#define glGetNamedProgramLocalParameterfvEXT _al_glGetNamedProgramLocalParameterfvEXT +#define glGetNamedProgramivEXT _al_glGetNamedProgramivEXT +#define glGetNamedProgramStringEXT _al_glGetNamedProgramStringEXT +#define glNamedProgramLocalParameters4fvEXT _al_glNamedProgramLocalParameters4fvEXT +#define glNamedProgramLocalParameterI4iEXT _al_glNamedProgramLocalParameterI4iEXT +#define glNamedProgramLocalParameterI4ivEXT _al_glNamedProgramLocalParameterI4ivEXT +#define glNamedProgramLocalParametersI4ivEXT _al_glNamedProgramLocalParametersI4ivEXT +#define glNamedProgramLocalParameterI4uiEXT _al_glNamedProgramLocalParameterI4uiEXT +#define glNamedProgramLocalParameterI4uivEXT _al_glNamedProgramLocalParameterI4uivEXT +#define glNamedProgramLocalParametersI4uivEXT _al_glNamedProgramLocalParametersI4uivEXT +#define glGetNamedProgramLocalParameterIivEXT _al_glGetNamedProgramLocalParameterIivEXT +#define glGetNamedProgramLocalParameterIuivEXT _al_glGetNamedProgramLocalParameterIuivEXT +#define glTextureParameterIivEXT _al_glTextureParameterIivEXT +#define glTextureParameterIuivEXT _al_glTextureParameterIuivEXT +#define glGetTextureParameterIivEXT _al_glGetTextureParameterIivEXT +#define glGetTextureParameterIuivEXT _al_glGetTextureParameterIuivEXT +#define glMultiTexParameterIivEXT _al_glMultiTexParameterIivEXT +#define glMultiTexParameterIuivEXT _al_glMultiTexParameterIuivEXT +#define glGetMultiTexParameterIivEXT _al_glGetMultiTexParameterIivEXT +#define glGetMultiTexParameterIuivEXT _al_glGetMultiTexParameterIuivEXT +#define glProgramUniform1fEXT _al_glProgramUniform1fEXT +#define glProgramUniform2fEXT _al_glProgramUniform2fEXT +#define glProgramUniform3fEXT _al_glProgramUniform3fEXT +#define glProgramUniform4fEXT _al_glProgramUniform4fEXT +#define glProgramUniform1iEXT _al_glProgramUniform1iEXT +#define glProgramUniform2iEXT _al_glProgramUniform2iEXT +#define glProgramUniform3iEXT _al_glProgramUniform3iEXT +#define glProgramUniform4iEXT _al_glProgramUniform4iEXT +#define glProgramUniform1fvEXT _al_glProgramUniform1fvEXT +#define glProgramUniform2fvEXT _al_glProgramUniform2fvEXT +#define glProgramUniform3fvEXT _al_glProgramUniform3fvEXT +#define glProgramUniform4fvEXT _al_glProgramUniform4fvEXT +#define glProgramUniform1ivEXT _al_glProgramUniform1ivEXT +#define glProgramUniform2ivEXT _al_glProgramUniform2ivEXT +#define glProgramUniform3ivEXT _al_glProgramUniform3ivEXT +#define glProgramUniform4ivEXT _al_glProgramUniform4ivEXT +#define glProgramUniformMatrix2fvEXT _al_glProgramUniformMatrix2fvEXT +#define glProgramUniformMatrix3fvEXT _al_glProgramUniformMatrix3fvEXT +#define glProgramUniformMatrix4fvEXT _al_glProgramUniformMatrix4fvEXT +#define glProgramUniformMatrix2x3fvEXT _al_glProgramUniformMatrix2x3fvEXT +#define glProgramUniformMatrix3x2fvEXT _al_glProgramUniformMatrix3x2fvEXT +#define glProgramUniformMatrix2x4fvEXT _al_glProgramUniformMatrix2x4fvEXT +#define glProgramUniformMatrix4x2fvEXT _al_glProgramUniformMatrix4x2fvEXT +#define glProgramUniformMatrix3x4fvEXT _al_glProgramUniformMatrix3x4fvEXT +#define glProgramUniformMatrix4x3fvEXT _al_glProgramUniformMatrix4x3fvEXT +#define glProgramUniform1uiEXT _al_glProgramUniform1uiEXT +#define glProgramUniform2uiEXT _al_glProgramUniform2uiEXT +#define glProgramUniform3uiEXT _al_glProgramUniform3uiEXT +#define glProgramUniform4uiEXT _al_glProgramUniform4uiEXT +#define glProgramUniform1uivEXT _al_glProgramUniform1uivEXT +#define glProgramUniform2uivEXT _al_glProgramUniform2uivEXT +#define glProgramUniform3uivEXT _al_glProgramUniform3uivEXT +#define glProgramUniform4uivEXT _al_glProgramUniform4uivEXT +#define glNamedBufferDataEXT _al_glNamedBufferDataEXT +#define glNamedBufferSubDataEXT _al_glNamedBufferSubDataEXT +#define glMapNamedBufferEXT _al_glMapNamedBufferEXT +#define glUnmapNamedBufferEXT _al_glUnmapNamedBufferEXT +#define glGetNamedBufferParameterivEXT _al_glGetNamedBufferParameterivEXT +#define glGetNamedBufferPointervEXT _al_glGetNamedBufferPointervEXT +#define glGetNamedBufferSubDataEXT _al_glGetNamedBufferSubDataEXT +#define glTextureBufferEXT _al_glTextureBufferEXT +#define glMultiTexBufferEXT _al_glMultiTexBufferEXT +#define glNamedRenderbufferStorageEXT _al_glNamedRenderbufferStorageEXT +#define glGetNamedRenderbufferParameterivEXT _al_glGetNamedRenderbufferParameterivEXT +#define glCheckNamedFramebufferStatusEXT _al_glCheckNamedFramebufferStatusEXT +#define glNamedFramebufferTexture1DEXT _al_glNamedFramebufferTexture1DEXT +#define glNamedFramebufferTexture2DEXT _al_glNamedFramebufferTexture2DEXT +#define glNamedFramebufferTexture3DEXT _al_glNamedFramebufferTexture3DEXT +#define glNamedFramebufferRenderbufferEXT _al_glNamedFramebufferRenderbufferEXT +#define glGetNamedFramebufferAttachmentParameterivEXT _al_glGetNamedFramebufferAttachmentParameterivEXT +#define glGenerateTextureMipmapEXT _al_glGenerateTextureMipmapEXT +#define glGenerateMultiTexMipmapEXT _al_glGenerateMultiTexMipmapEXT +#define glFramebufferDrawBufferEXT _al_glFramebufferDrawBufferEXT +#define glFramebufferDrawBuffersEXT _al_glFramebufferDrawBuffersEXT +#define glFramebufferReadBufferEXT _al_glFramebufferReadBufferEXT +#define glGetFramebufferParameterivEXT _al_glGetFramebufferParameterivEXT +#define glNamedRenderbufferStorageMultisampleEXT _al_glNamedRenderbufferStorageMultisampleEXT +#define glNamedRenderbufferStorageMultisampleCoverageEXT _al_glNamedRenderbufferStorageMultisampleCoverageEXT +#define glNamedFramebufferTextureEXT _al_glNamedFramebufferTextureEXT +#define glNamedFramebufferTextureLayerEXT _al_glNamedFramebufferTextureLayerEXT +#define glNamedFramebufferTextureFaceEXT _al_glNamedFramebufferTextureFaceEXT +#define glTextureRenderbufferEXT _al_glTextureRenderbufferEXT +#define glMultiTexRenderbufferEXT _al_glMultiTexRenderbufferEXT +#endif + +#if defined _ALLEGRO_GL_NV_explicit_multisample +#define glGetMultisamplefvNV _al_glGetMultisamplefvNV +#define glSampleMaskIndexedNV _al_glSampleMaskIndexedNV +#define glTexRenderbufferNV _al_glTexRenderbufferNV +#endif + +#if defined _ALLEGRO_GL_NV_transform_feedback2 +#define glBindTransformFeedbackNV _al_glBindTransformFeedbackNV +#define glDeleteTransformFeedbacksNV _al_glDeleteTransformFeedbacksNV +#define glGenTransformFeedbacksNV _al_glGenTransformFeedbacksNV +#define glIsTransformFeedbackNV _al_glIsTransformFeedbackNV +#define glPauseTransformFeedbackNV _al_glPauseTransformFeedbackNV +#define glResumeTransformFeedbackNV _al_glResumeTransformFeedbackNV +#define glDrawTransformFeedbackNV _al_glDrawTransformFeedbackNV +#endif + +#if defined _ALLEGRO_GL_AMD_performance_monitor +#define glGetPerfMonitorGroupsAMD _al_glGetPerfMonitorGroupsAMD +#define glGetPerfMonitorCountersAMD _al_glGetPerfMonitorCountersAMD +#define glGetPerfMonitorGroupStringAMD _al_glGetPerfMonitorGroupStringAMD +#define glGetPerfMonitorCounterStringAMD _al_glGetPerfMonitorCounterStringAMD +#define glGetPerfMonitorCounterInfoAMD _al_glGetPerfMonitorCounterInfoAMD +#define glGenPerfMonitorsAMD _al_glGenPerfMonitorsAMD +#define glDeletePerfMonitorsAMD _al_glDeletePerfMonitorsAMD +#define glSelectPerfMonitorCountersAMD _al_glSelectPerfMonitorCountersAMD +#define glBeginPerfMonitorAMD _al_glBeginPerfMonitorAMD +#define glEndPerfMonitorAMD _al_glEndPerfMonitorAMD +#define glGetPerfMonitorCounterDataAMD _al_glGetPerfMonitorCounterDataAMD +#endif + +#if defined _ALLEGRO_GL_AMD_vertex_shader_tesselator +#define glTessellationFactorAMD _al_glTessellationFactorAMD +#define glTessellationModeAMD _al_glTessellationModeAMD +#endif + +#if defined _ALLEGRO_GL_EXT_provoking_vertex +#define glProvokingVertexEXT _al_glProvokingVertexEXT +#endif + +#if defined _ALLEGRO_GL_AMD_draw_buffers_blend +#define glBlendFuncIndexedAMD _al_glBlendFuncIndexedAMD +#define glBlendFuncSeparateIndexedAMD _al_glBlendFuncSeparateIndexedAMD +#define glBlendEquationIndexedAMD _al_glBlendEquationIndexedAMD +#define glBlendEquationSeparateIndexedAMD _al_glBlendEquationSeparateIndexedAMD +#endif + +#if defined _ALLEGRO_GL_APPLE_texture_range +#define glTextureRangeAPPLE _al_glTextureRangeAPPLE +#define glGetTexParameterPointervAPPLE _al_glGetTexParameterPointervAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_program_evaluators +#define glEnableVertexAttribAPPLE _al_glEnableVertexAttribAPPLE +#define glDisableVertexAttribAPPLE _al_glDisableVertexAttribAPPLE +#define glIsVertexAttribEnabledAPPLE _al_glIsVertexAttribEnabledAPPLE +#define glMapVertexAttrib1dAPPLE _al_glMapVertexAttrib1dAPPLE +#define glMapVertexAttrib1fAPPLE _al_glMapVertexAttrib1fAPPLE +#define glMapVertexAttrib2dAPPLE _al_glMapVertexAttrib2dAPPLE +#define glMapVertexAttrib2fAPPLE _al_glMapVertexAttrib2fAPPLE +#endif + +#if defined _ALLEGRO_GL_APPLE_object_purgeable +#define glObjectPurgeableAPPLE _al_glObjectPurgeableAPPLE +#define glObjectUnpurgeableAPPLE _al_glObjectUnpurgeableAPPLE +#define glGetObjectParameterivAPPLE _al_glGetObjectParameterivAPPLE +#endif + +#if defined _ALLEGRO_GL_NV_video_capture +#define glBeginVideoCaptureNV _al_glBeginVideoCaptureNV +#define glBindVideoCaptureStreamBufferNV _al_glBindVideoCaptureStreamBufferNV +#define glBindVideoCaptureStreamTextureNV _al_glBindVideoCaptureStreamTextureNV +#define glEndVideoCaptureNV _al_glEndVideoCaptureNV +#define glGetVideoCaptureivNV _al_glGetVideoCaptureivNV +#define glGetVideoCaptureStreamivNV _al_glGetVideoCaptureStreamivNV +#define glGetVideoCaptureStreamfvNV _al_glGetVideoCaptureStreamfvNV +#define glGetVideoCaptureStreamdvNV _al_glGetVideoCaptureStreamdvNV +#define glVideoCaptureNV _al_glVideoCaptureNV +#define glVideoCaptureStreamParameterivNV _al_glVideoCaptureStreamParameterivNV +#define glVideoCaptureStreamParameterfvNV _al_glVideoCaptureStreamParameterfvNV +#define glVideoCaptureStreamParameterdvNV _al_glVideoCaptureStreamParameterdvNV +#endif + +#if defined _ALLEGRO_GL_EXT_separate_shader_objects +#define glUseShaderProgramEXT _al_glUseShaderProgramEXT +#define glActiveProgramEXT _al_glActiveProgramEXT +#define glCreateShaderProgramEXT _al_glCreateShaderProgramEXT +#endif + +#if defined _ALLEGRO_GL_NV_shader_buffer_load +#define glMakeBufferResidentNV _al_glMakeBufferResidentNV +#define glMakeBufferNonResidentNV _al_glMakeBufferNonResidentNV +#define glIsBufferResidentNV _al_glIsBufferResidentNV +#define glMakeNamedBufferResidentNV _al_glMakeNamedBufferResidentNV +#define glMakeNamedBufferNonResidentNV _al_glMakeNamedBufferNonResidentNV +#define glIsNamedBufferResidentNV _al_glIsNamedBufferResidentNV +#define glGetBufferParameterui64vNV _al_glGetBufferParameterui64vNV +#define glGetNamedBufferParameterui64vNV _al_glGetNamedBufferParameterui64vNV +#define glGetIntegerui64vNV _al_glGetIntegerui64vNV +#define glUniformui64NV _al_glUniformui64NV +#define glUniformui64vNV _al_glUniformui64vNV +#define glGetUniformui64vNV _al_glGetUniformui64vNV +#define glProgramUniformui64NV _al_glProgramUniformui64NV +#define glProgramUniformui64vNV _al_glProgramUniformui64vNV +#endif + +#if defined _ALLEGRO_GL_NV_vertex_buffer_unified_memory +#define glBufferAddressRangeNV _al_glBufferAddressRangeNV +#define glVertexFormatNV _al_glVertexFormatNV +#define glNormalFormatNV _al_glNormalFormatNV +#define glColorFormatNV _al_glColorFormatNV +#define glIndexFormatNV _al_glIndexFormatNV +#define glTexCoordFormatNV _al_glTexCoordFormatNV +#define glEdgeFlagFormatNV _al_glEdgeFlagFormatNV +#define glSecondaryColorFormatNV _al_glSecondaryColorFormatNV +#define glFogCoordFormatNV _al_glFogCoordFormatNV +#define glVertexAttribFormatNV _al_glVertexAttribFormatNV +#define glVertexAttribIFormatNV _al_glVertexAttribIFormatNV +#define glGetIntegerui64i_vNV _al_glGetIntegerui64i_vNV +#endif + +#if defined _ALLEGRO_GL_NV_texture_barrier +#define glTextureBarrierNV _al_glTextureBarrierNV +#endif diff --git a/allegro/include/allegro5/opengl/GLext/gl_ext_api.h b/allegro/include/allegro5/opengl/GLext/gl_ext_api.h new file mode 100644 index 00000000..633f1e41 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/gl_ext_api.h @@ -0,0 +1,2610 @@ +/* */ + +#ifdef _ALLEGRO_GL_VERSION_1_2 +AGL_API(void, BlendColor, (GLclampf, GLclampf, GLclampf, GLclampf)) +AGL_API(void, BlendEquation, (GLenum)) +AGL_API(void, DrawRangeElements, (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *)) +AGL_API(void, ColorTable, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ColorTableParameterfv, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, ColorTableParameteriv, (GLenum, GLenum, const GLint *)) +AGL_API(void, CopyColorTable, (GLenum, GLenum, GLint, GLint, GLsizei)) +AGL_API(void, GetColorTable, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetColorTableParameterfv, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetColorTableParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, ColorSubTable, (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyColorSubTable, (GLenum, GLsizei, GLint, GLint, GLsizei)) +AGL_API(void, TexImage3D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyTexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_ARB_imaging +AGL_API(void, ConvolutionFilter1D, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ConvolutionFilter2D, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ConvolutionParameterf, (GLenum, GLenum, GLfloat)) +AGL_API(void, ConvolutionParameterfv, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, ConvolutionParameteri, (GLenum, GLenum, GLint)) +AGL_API(void, ConvolutionParameteriv, (GLenum, GLenum, const GLint *)) +AGL_API(void, CopyConvolutionFilter1D, (GLenum, GLenum, GLint, GLint, GLsizei)) +AGL_API(void, CopyConvolutionFilter2D, (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, GetConvolutionFilter, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetConvolutionParameterfv, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetConvolutionParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetSeparableFilter, (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *)) +AGL_API(void, SeparableFilter2D, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *)) +AGL_API(void, GetHistogram, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetHistogramParameterfv, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetHistogramParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetMinmax, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetMinmaxParameterfv, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMinmaxParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, Histogram, (GLenum, GLsizei, GLenum, GLboolean)) +AGL_API(void, Minmax, (GLenum, GLenum, GLboolean)) +AGL_API(void, ResetHistogram, (GLenum)) +AGL_API(void, ResetMinmax, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_VERSION_1_3 +AGL_API(void, ActiveTexture, (GLenum)) +AGL_API(void, ClientActiveTexture, (GLenum)) +AGL_API(void, MultiTexCoord1d, (GLenum, GLdouble)) +AGL_API(void, MultiTexCoord1dv, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord1f, (GLenum, GLfloat)) +AGL_API(void, MultiTexCoord1fv, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord1i, (GLenum, GLint)) +AGL_API(void, MultiTexCoord1iv, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord1s, (GLenum, GLshort)) +AGL_API(void, MultiTexCoord1sv, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord2d, (GLenum, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord2dv, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord2f, (GLenum, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord2fv, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord2i, (GLenum, GLint, GLint)) +AGL_API(void, MultiTexCoord2iv, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord2s, (GLenum, GLshort, GLshort)) +AGL_API(void, MultiTexCoord2sv, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord3d, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord3dv, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord3f, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord3fv, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord3i, (GLenum, GLint, GLint, GLint)) +AGL_API(void, MultiTexCoord3iv, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord3s, (GLenum, GLshort, GLshort, GLshort)) +AGL_API(void, MultiTexCoord3sv, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord4d, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord4dv, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord4f, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord4fv, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord4i, (GLenum, GLint, GLint, GLint, GLint)) +AGL_API(void, MultiTexCoord4iv, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord4s, (GLenum, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, MultiTexCoord4sv, (GLenum, const GLshort *)) +AGL_API(void, LoadTransposeMatrixf, (const GLfloat *)) +AGL_API(void, LoadTransposeMatrixd, (const GLdouble *)) +AGL_API(void, MultTransposeMatrixf, (const GLfloat *)) +AGL_API(void, MultTransposeMatrixd, (const GLdouble *)) +AGL_API(void, SampleCoverage, (GLclampf, GLboolean)) +AGL_API(void, CompressedTexImage3D, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexImage2D, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexImage1D, (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage3D, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage1D, (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetCompressedTexImage, (GLenum, GLint, GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_VERSION_1_4 +AGL_API(void, BlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, FogCoordf, (GLfloat)) +AGL_API(void, FogCoordfv, (const GLfloat *)) +AGL_API(void, FogCoordd, (GLdouble)) +AGL_API(void, FogCoorddv, (const GLdouble *)) +AGL_API(void, FogCoordPointer, (GLenum, GLsizei, const GLvoid *)) +AGL_API(void, MultiDrawArrays, (GLenum, GLint *, GLsizei *, GLsizei)) +AGL_API(void, MultiDrawElements, (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei)) +AGL_API(void, PointParameterf, (GLenum, GLfloat)) +AGL_API(void, PointParameterfv, (GLenum, const GLfloat *)) +AGL_API(void, PointParameteri, (GLenum, GLint)) +AGL_API(void, PointParameteriv, (GLenum, const GLint *)) +AGL_API(void, SecondaryColor3b, (GLbyte, GLbyte, GLbyte)) +AGL_API(void, SecondaryColor3bv, (const GLbyte *)) +AGL_API(void, SecondaryColor3d, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, SecondaryColor3dv, (const GLdouble *)) +AGL_API(void, SecondaryColor3f, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, SecondaryColor3fv, (const GLfloat *)) +AGL_API(void, SecondaryColor3i, (GLint, GLint, GLint)) +AGL_API(void, SecondaryColor3iv, (const GLint *)) +AGL_API(void, SecondaryColor3s, (GLshort, GLshort, GLshort)) +AGL_API(void, SecondaryColor3sv, (const GLshort *)) +AGL_API(void, SecondaryColor3ub, (GLubyte, GLubyte, GLubyte)) +AGL_API(void, SecondaryColor3ubv, (const GLubyte *)) +AGL_API(void, SecondaryColor3ui, (GLuint, GLuint, GLuint)) +AGL_API(void, SecondaryColor3uiv, (const GLuint *)) +AGL_API(void, SecondaryColor3us, (GLushort, GLushort, GLushort)) +AGL_API(void, SecondaryColor3usv, (const GLushort *)) +AGL_API(void, SecondaryColorPointer, (GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, WindowPos2d, (GLdouble, GLdouble)) +AGL_API(void, WindowPos2dv, (const GLdouble *)) +AGL_API(void, WindowPos2f, (GLfloat, GLfloat)) +AGL_API(void, WindowPos2fv, (const GLfloat *)) +AGL_API(void, WindowPos2i, (GLint, GLint)) +AGL_API(void, WindowPos2iv, (const GLint *)) +AGL_API(void, WindowPos2s, (GLshort, GLshort)) +AGL_API(void, WindowPos2sv, (const GLshort *)) +AGL_API(void, WindowPos3d, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, WindowPos3dv, (const GLdouble *)) +AGL_API(void, WindowPos3f, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, WindowPos3fv, (const GLfloat *)) +AGL_API(void, WindowPos3i, (GLint, GLint, GLint)) +AGL_API(void, WindowPos3iv, (const GLint *)) +AGL_API(void, WindowPos3s, (GLshort, GLshort, GLshort)) +AGL_API(void, WindowPos3sv, (const GLshort *)) +#endif + + +#if defined _ALLEGRO_GL_VERSION_1_5 +AGL_API(void, BindBuffer, (GLenum, GLuint)) +AGL_API(void, DeleteBuffers, (GLsizei, const GLuint *)) +AGL_API(void, GenBuffers, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsBuffer, (GLuint)) +AGL_API(void, BufferData, (GLenum, GLsizeiptr, const GLvoid *, GLenum)) +AGL_API(void, BufferSubData, (GLenum, GLintptr, GLsizeiptr, const GLvoid *)) +AGL_API(void, GetBufferSubData, (GLenum, GLintptr, GLsizeiptr, GLvoid *)) +AGL_API(GLvoid*, MapBuffer, (GLenum, GLenum)) +AGL_API(GLboolean, UnmapBuffer, (GLenum)) +AGL_API(void, GetBufferParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetBufferPointerv, (GLenum, GLenum, GLvoid* *)) +AGL_API(void, GenQueries, (GLsizei, GLuint *)) +AGL_API(void, DeleteQueries, (GLsizei, const GLuint *)) +AGL_API(GLboolean, IsQuery, (GLuint)) +AGL_API(void, BeginQuery, (GLenum, GLuint)) +AGL_API(void, EndQuery, (GLenum)) +AGL_API(void, GetQueryiv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetQueryObjectiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetQueryObjectuiv, (GLuint, GLenum, GLuint *)) +#endif + + +#if defined _ALLEGRO_GL_VERSION_2_0 +AGL_API(void, BlendEquationSeparate, (GLenum, GLenum)) +AGL_API(GLuint, CreateProgram, (void)) +AGL_API(GLuint, CreateShader, (GLenum)) +AGL_API(void, DeleteProgram, (GLuint)) +AGL_API(void, DeleteShader, (GLuint)) +AGL_API(void, AttachShader, (GLuint, GLuint)) +AGL_API(void, DetachShader, (GLuint, GLuint)) +AGL_API(void, ShaderSource, (GLuint, GLsizei, const GLchar **, const GLint *)) +AGL_API(void, CompileShader, (GLuint)) +AGL_API(GLboolean, IsProgram, (GLuint)) +AGL_API(GLboolean, IsShader, (GLuint)) +AGL_API(void, LinkProgram, (GLuint)) +AGL_API(void, UseProgram, (GLuint)) +AGL_API(void, ValidateProgram, (GLuint)) +AGL_API(void, Uniform1f, (GLint, GLfloat)) +AGL_API(void, Uniform2f, (GLint, GLfloat, GLfloat)) +AGL_API(void, Uniform3f, (GLint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Uniform4f, (GLint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Uniform1i, (GLint, GLint)) +AGL_API(void, Uniform2i, (GLint, GLint, GLint)) +AGL_API(void, Uniform3i, (GLint, GLint, GLint, GLint)) +AGL_API(void, Uniform4i, (GLint, GLint, GLint, GLint, GLint)) +AGL_API(void, Uniform1fv, (GLint, GLsizei, const GLfloat *)) +AGL_API(void, Uniform2fv, (GLint, GLsizei, const GLfloat *)) +AGL_API(void, Uniform3fv, (GLint, GLsizei, const GLfloat *)) +AGL_API(void, Uniform4fv, (GLint, GLsizei, const GLfloat *)) +AGL_API(void, Uniform1iv, (GLint, GLsizei, const GLint *)) +AGL_API(void, Uniform2iv, (GLint, GLsizei, const GLint *)) +AGL_API(void, Uniform3iv, (GLint, GLsizei, const GLint *)) +AGL_API(void, Uniform4iv, (GLint, GLsizei, const GLint *)) +AGL_API(void, UniformMatrix2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, GetShaderfv, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetShaderiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetProgramfv, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetProgramiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetShaderInfoLog, (GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, GetProgramInfoLog, (GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, GetAttachedShaders, (GLuint, GLsizei, GLsizei *, GLuint *)) +AGL_API(GLint, GetUniformLocation, (GLuint, const GLchar *)) +AGL_API(void, GetActiveUniform, (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *)) +AGL_API(void, GetUniformfv, (GLuint, GLint, GLfloat *)) +AGL_API(void, GetUniformiv, (GLuint, GLint, GLint *)) +AGL_API(void, GetShaderSource, (GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, VertexAttrib1f, (GLuint, GLfloat)) +AGL_API(void, VertexAttrib1s, (GLuint, GLshort)) +AGL_API(void, VertexAttrib1d, (GLuint, GLdouble)) +AGL_API(void, VertexAttrib2f, (GLuint, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib2s, (GLuint, GLshort, GLshort)) +AGL_API(void, VertexAttrib2d, (GLuint, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib3f, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib3s, (GLuint, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib3d, (GLuint, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4f, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib4s, (GLuint, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib4d, (GLuint, GLdouble,GLdouble,GLdouble,GLdouble)) +AGL_API(void, VertexAttrib4Nub, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) +AGL_API(void, VertexAttrib1fv, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib1sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib1dv, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib2fv, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib2sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib2dv, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib3fv, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib3sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib3dv, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4fv, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib4sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4dv, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4bv, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4ubv, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4usv, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttrib4Nbv, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4Nsv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4Niv, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4Nubv, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4Nusv, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4Nuiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribPointer,(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) +AGL_API(void, EnableVertexAttribArray, (GLuint)) +AGL_API(void, DisableVertexAttribArray, (GLuint)) + +AGL_API(void, BindAttribLocation, (GLuint, GLuint, const GLchar *)) +AGL_API(void, GetActiveAttrib, (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *)) +AGL_API(GLint, GetAttribLocation, (GLuint, const GLchar *)) +AGL_API(void, GetVertexAttribdv, (GLuint, GLenum, GLdouble *)) +AGL_API(void, GetVertexAttribfv, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribPointerv, (GLuint, GLenum, GLvoid **)) + +AGL_API(void, DrawBuffers, (GLsizei n, const GLenum *)) + +AGL_API(void, StencilOpSeparate, (GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, StencilFuncSeparate, (GLenum, GLenum, GLint, GLuint)) +AGL_API(void, StencilMaskSeparate, (GLenum, GLuint)) + +#endif + + +#if defined _ALLEGRO_GL_VERSION_2_1 +AGL_API(void, UniformMatrix2x3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix3x2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix2x4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix4x2fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix3x4fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, UniformMatrix4x3fv, (GLint, GLsizei, GLboolean, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_VERSION_3_0 +/* OpenGL 3.0 also reuses entry points from these extensions: */ +/* ARB_framebuffer_object */ +/* ARB_map_buffer_range */ +/* ARB_vertex_array_object */ +AGL_API(void, ColorMaski, (GLuint, GLboolean, GLboolean, GLboolean, GLboolean)) +AGL_API(void, GetBooleani_v, (GLenum, GLuint, GLboolean *)) +AGL_API(void, GetIntegeri_v, (GLenum, GLuint, GLint *)) +AGL_API(void, Enablei, (GLenum, GLuint)) +AGL_API(void, Disablei, (GLenum, GLuint)) +AGL_API(GLboolean, IsEnabledi, (GLenum, GLuint)) +AGL_API(void, BeginTransformFeedback, (GLenum)) +AGL_API(void, EndTransformFeedback, (void)) +AGL_API(void, BindBufferRange, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) +AGL_API(void, BindBufferBase, (GLenum, GLuint, GLuint)) +AGL_API(void, TransformFeedbackVaryings, (GLuint, GLsizei, const GLint *, GLenum)) +AGL_API(void, GetTransformFeedbackVarying, (GLuint, GLuint, GLint *)) +AGL_API(void, ClampColor, (GLenum, GLenum)) +AGL_API(void, BeginConditionalRender, (GLuint, GLenum)) +AGL_API(void, EndConditionalRender, (void)) +AGL_API(void, VertexAttribI1i, (GLuint, GLint)) +AGL_API(void, VertexAttribI2i, (GLuint, GLint, GLint)) +AGL_API(void, VertexAttribI3i, (GLuint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI4i, (GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI1ui, (GLuint, GLuint)) +AGL_API(void, VertexAttribI2ui, (GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI3ui, (GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI4ui, (GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI1iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI2iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI3iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI4iv, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI1uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI2uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI3uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4uiv, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4bv, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttribI4sv, (GLuint, const GLshort *)) +AGL_API(void, VertexAttribI4ubv, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttribI4usv, (GLuint, const GLushort *)) +AGL_API(void, VertexAttribIPointer, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetVertexAttribIiv, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribIuiv, (GLuint, GLenum, GLuint *)) +AGL_API(void, GetUniformuiv, (GLuint, GLint, GLuint *)) +AGL_API(void, BindFragDataLocation, (GLuint, GLuint, const GLchar *)) +AGL_API(GLint, GetFragDataLocation, (GLuint, const GLchar *)) +AGL_API(void, Uniform1ui, (GLint, GLuint)) +AGL_API(void, Uniform2ui, (GLint, GLuint, GLuint)) +AGL_API(void, Uniform3ui, (GLint, GLuint, GLuint, GLuint)) +AGL_API(void, Uniform4ui, (GLint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, Uniform1uiv, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform2uiv, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform3uiv, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform4uiv, (GLint, GLsizei, const GLuint *)) +AGL_API(void, TexParameterIiv, (GLenum, GLenum, const GLint *)) +AGL_API(void, TexParameterIuiv, (GLenum, GLenum, const GLuint *)) +AGL_API(void, GetTexParameterIiv, (GLenum, GLenum, GLint *)) +AGL_API(void, GetTexParameterIuiv, (GLenum, GLenum, GLuint *)) +AGL_API(void, ClearBufferiv, (GLenum, GLint, const GLint *)) +AGL_API(void, ClearBufferuiv, (GLenum, GLint, const GLuint *)) +AGL_API(void, ClearBufferfv, (GLenum, GLint, const GLfloat *)) +AGL_API(void, ClearBufferfi, (GLenum, GLint, GLfloat, GLint)) +AGL_API(const GLubyte *, GetStringi, (GLenum, GLuint)) +#endif + + +#if defined _ALLEGRO_GL_VERSION_3_1 +/* OpenGL 3.1 also reuses entry points from these extensions: */ +/* ARB_copy_buffer */ +/* ARB_uniform_buffer_object */ +AGL_API(void, DrawArraysInstanced, (GLenum, GLint, GLsizei, GLsizei)) +AGL_API(void, DrawElementsInstanced, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) +AGL_API(void, TexBuffer, (GLenum, GLenum, GLuint)) +AGL_API(void, PrimitiveRestartIndex, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_VERSION_3_2 +/* OpenGL 3.2 also reuses entry points from these extensions: */ +/* ARB_draw_elements_base_vertex */ +/* ARB_provoking_vertex */ +/* ARB_sync */ +/* ARB_texture_multisample */ +AGL_API(void, GetInteger64i_v, (GLenum target, GLuint index, GLint64 *data)) +AGL_API(void, GetBufferParameteri64v, (GLenum target, GLenum pname, GLint64 *params)) +AGL_API(void, ProgramParameteri, (GLuint program, GLenum pname, GLint value)) +AGL_API(void, FramebufferTexture, (GLenum target, GLenum attachment, GLuint texture, GLint level)) +#endif + +#if defined _ALLEGRO_GL_VERSION_3_3 +/* OpenGL 3.3 also reuses entry points from these extensions: */ +/* ARB_blend_func_extended */ +/* ARB_sampler_objects */ +/* ARB_explicit_attrib_location, but it has none */ +/* ARB_occlusion_query2 (no entry points) */ +/* ARB_shader_bit_encoding (no entry points) */ +/* ARB_texture_rgb10_a2ui (no entry points) */ +/* ARB_texture_swizzle (no entry points) */ +/* ARB_timer_query */ +/* ARB_vertex_type_2_10_10_10_rev */ +#endif + +#if defined _ALLEGRO_GL_VERSION_4_3 +AGL_API(void, ClearBufferData, (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data)) +AGL_API(void, ClearBufferSubData, (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data)) +AGL_API(void, DispatchCompute, (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)) +AGL_API(void, DispatchComputeIndirect, (GLintptr indirect)) +AGL_API(void, CopyImageSubData, (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)) +AGL_API(void, FramebufferParameteri, (GLenum target, GLenum pname, GLint param)) +AGL_API(void, GetFramebufferParameteriv, (GLenum target, GLenum pname, GLint *params)) +AGL_API(void, GetInternalformati64v, (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params)) +AGL_API(void, InvalidateTexSubImage, (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)) +AGL_API(void, InvalidateTexImage, (GLuint texture, GLint level)) +AGL_API(void, InvalidateBufferSubData, (GLuint buffer, GLintptr offset, GLsizeiptr length)) +AGL_API(void, InvalidateBufferData, (GLuint buffer)) +AGL_API(void, InvalidateFramebuffer, (GLenum target, GLsizei numAttachments, const GLenum *attachments)) +AGL_API(void, InvalidateSubFramebuffer, (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)) +AGL_API(void, MultiDrawArraysIndirect, (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride)) +AGL_API(void, MultiDrawElementsIndirect, (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride)) +AGL_API(void, GetProgramInterfaceiv, (GLuint program, GLenum programInterface, GLenum pname, GLint *params)) +AGL_API(GLuint, GetProgramResourceIndex, (GLuint program, GLenum programInterface, const GLchar *name)) +AGL_API(void, GetProgramResourceName, (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name)) +AGL_API(void, GetProgramResourceiv, (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params)) +AGL_API(GLint, GetProgramResourceLocation, (GLuint program, GLenum programInterface, const GLchar *name)) +AGL_API(GLint, GetProgramResourceLocationIndex, (GLuint program, GLenum programInterface, const GLchar *name)) +AGL_API(void, ShaderStorageBlockBinding, (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding)) +AGL_API(void, TexBufferRange, (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)) +AGL_API(void, TexStorage2DMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) +AGL_API(void, TexStorage3DMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)) +AGL_API(void, TextureView, (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers)) +AGL_API(void, BindVertexBuffer, (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)) +AGL_API(void, VertexAttribFormat, (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)) +AGL_API(void, VertexAttribIFormat, (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)) +AGL_API(void, VertexAttribLFormat, (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)) +AGL_API(void, VertexAttribBinding, (GLuint attribindex, GLuint bindingindex)) +AGL_API(void, VertexBindingDivisor, (GLuint bindingindex, GLuint divisor)) +AGL_API(void, DebugMessageControl, (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled)) +AGL_API(void, DebugMessageInsert, (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf)) +AGL_API(void, DebugMessageCallback, (GLDEBUGPROC callback, const void *userParam)) +AGL_API(GLuint, GetDebugMessageLog, (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog)) +AGL_API(void, PushDebugGroup, (GLenum source, GLuint id, GLsizei length, const GLchar *message)) +AGL_API(void, PopDebugGroup, (void)) +AGL_API(void, ObjectLabel, (GLenum identifier, GLuint name, GLsizei length, const GLchar *label)) +AGL_API(void, GetObjectLabel, (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)) +AGL_API(void, ObjectPtrLabel, (const void *ptr, GLsizei length, const GLchar *label)) +AGL_API(void, GetObjectPtrLabel, (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)) +#endif /* GL_VERSION_4_3 */ + + +/* */ +/* */ + +#ifdef _ALLEGRO_GL_ARB_multitexture +AGL_API(void, ActiveTextureARB, (GLenum)) +AGL_API(void, ClientActiveTextureARB, (GLenum)) +AGL_API(void, MultiTexCoord1dARB, (GLenum, GLdouble)) +AGL_API(void, MultiTexCoord1dvARB, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord1fARB, (GLenum, GLfloat)) +AGL_API(void, MultiTexCoord1fvARB, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord1iARB, (GLenum, GLint)) +AGL_API(void, MultiTexCoord1ivARB, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord1sARB, (GLenum, GLshort)) +AGL_API(void, MultiTexCoord1svARB, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord2dARB, (GLenum, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord2dvARB, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord2fARB, (GLenum, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord2fvARB, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord2iARB, (GLenum, GLint, GLint)) +AGL_API(void, MultiTexCoord2ivARB, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord2sARB, (GLenum, GLshort, GLshort)) +AGL_API(void, MultiTexCoord2svARB, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord3dARB, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord3dvARB, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord3fARB, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord3fvARB, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord3iARB, (GLenum, GLint, GLint, GLint)) +AGL_API(void, MultiTexCoord3ivARB, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord3sARB, (GLenum, GLshort, GLshort, GLshort)) +AGL_API(void, MultiTexCoord3svARB, (GLenum, const GLshort *)) +AGL_API(void, MultiTexCoord4dARB, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MultiTexCoord4dvARB, (GLenum, const GLdouble *)) +AGL_API(void, MultiTexCoord4fARB, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MultiTexCoord4fvARB, (GLenum, const GLfloat *)) +AGL_API(void, MultiTexCoord4iARB, (GLenum, GLint, GLint, GLint, GLint)) +AGL_API(void, MultiTexCoord4ivARB, (GLenum, const GLint *)) +AGL_API(void, MultiTexCoord4sARB, (GLenum, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, MultiTexCoord4svARB, (GLenum, const GLshort *)) +#endif + +#if defined _ALLEGRO_GL_ARB_transpose_matrix +AGL_API(void, LoadTransposeMatrixfARB, (const GLfloat *)) +AGL_API(void, LoadTransposeMatrixdARB, (const GLdouble *)) +AGL_API(void, MultTransposeMatrixfARB, (const GLfloat *)) +AGL_API(void, MultTransposeMatrixdARB, (const GLdouble *)) +#endif + +#if defined _ALLEGRO_GL_ARB_multisample +AGL_API(void, SampleCoverageARB, (GLclampf, GLboolean)) +#endif + +#if defined _ALLEGRO_GL_ARB_texture_compression +AGL_API(void, CompressedTexImage3DARB, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexImage2DARB, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexImage1DARB, (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage3DARB, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage2DARB, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTexSubImage1DARB, (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetCompressedTexImageARB, (GLenum, GLint, GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_ARB_point_parameters +AGL_API(void, PointParameterfARB, (GLenum, GLfloat)) +AGL_API(void, PointParameterfvARB, (GLenum, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_blend +AGL_API(void, WeightbvARB, (GLint, const GLbyte *)) +AGL_API(void, WeightsvARB, (GLint, const GLshort *)) +AGL_API(void, WeightivARB, (GLint, const GLint *)) +AGL_API(void, WeightfvARB, (GLint, const GLfloat *)) +AGL_API(void, WeightdvARB, (GLint, const GLdouble *)) +AGL_API(void, WeightubvARB, (GLint, const GLubyte *)) +AGL_API(void, WeightusvARB, (GLint, const GLushort *)) +AGL_API(void, WeightuivARB, (GLint, const GLuint *)) +AGL_API(void, WeightPointerARB, (GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, VertexBlendARB, (GLint)) +#endif + +#if defined _ALLEGRO_GL_ARB_matrix_palette +AGL_API(void, CurrentPaletteMatrixARB, (GLint)) +AGL_API(void, MatrixIndexubvARB, (GLint, const GLubyte *)) +AGL_API(void, MatrixIndexusvARB, (GLint, const GLushort *)) +AGL_API(void, MatrixIndexuivARB, (GLint, const GLuint *)) +AGL_API(void, MatrixIndexPointerARB, (GLint, GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_ARB_window_pos +AGL_API(void, WindowPos2dARB, (GLdouble, GLdouble)) +AGL_API(void, WindowPos2dvARB, (const GLdouble *)) +AGL_API(void, WindowPos2fARB, (GLfloat, GLfloat)) +AGL_API(void, WindowPos2fvARB, (const GLfloat *)) +AGL_API(void, WindowPos2iARB, (GLint, GLint)) +AGL_API(void, WindowPos2ivARB, (const GLint *)) +AGL_API(void, WindowPos2sARB, (GLshort, GLshort)) +AGL_API(void, WindowPos2svARB, (const GLshort *)) +AGL_API(void, WindowPos3dARB, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, WindowPos3dvARB, (const GLdouble *)) +AGL_API(void, WindowPos3fARB, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, WindowPos3fvARB, (const GLfloat *)) +AGL_API(void, WindowPos3iARB, (GLint, GLint, GLint)) +AGL_API(void, WindowPos3ivARB, (const GLint *)) +AGL_API(void, WindowPos3sARB, (GLshort, GLshort, GLshort)) +AGL_API(void, WindowPos3svARB, (const GLshort *)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_program +AGL_API(void, VertexAttrib1dARB, (GLuint, GLdouble)) +AGL_API(void, VertexAttrib1dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib1fARB, (GLuint, GLfloat)) +AGL_API(void, VertexAttrib1fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib1sARB, (GLuint, GLshort)) +AGL_API(void, VertexAttrib1svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib2dARB, (GLuint, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib2dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib2fARB, (GLuint, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib2fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib2sARB, (GLuint, GLshort, GLshort)) +AGL_API(void, VertexAttrib2svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib3dARB, (GLuint, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib3dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib3fARB, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib3fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib3sARB, (GLuint, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib3svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4NbvARB, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4NivARB, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4NsvARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4NubARB, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) +AGL_API(void, VertexAttrib4NubvARB, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4NuivARB, (GLuint, const GLuint *)) +AGL_API(void, VertexAttrib4NusvARB, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4bvARB, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4dARB, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4fARB, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib4fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib4ivARB, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4sARB, (GLuint, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib4svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4ubvARB, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4uivARB, (GLuint, const GLuint *)) +AGL_API(void, VertexAttrib4usvARB, (GLuint, const GLushort *)) +AGL_API(void, VertexAttribPointerARB, (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) +AGL_API(void, EnableVertexAttribArrayARB, (GLuint)) +AGL_API(void, DisableVertexAttribArrayARB, (GLuint)) +AGL_API(void, ProgramStringARB, (GLenum, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, BindProgramARB, (GLenum, GLuint)) +AGL_API(void, DeleteProgramsARB, (GLsizei, const GLuint *)) +AGL_API(void, GenProgramsARB, (GLsizei, GLuint *)) +AGL_API(void, ProgramEnvParameter4dARB, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, ProgramEnvParameter4dvARB, (GLenum, GLuint, const GLdouble *)) +AGL_API(void, ProgramEnvParameter4fARB, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramEnvParameter4fvARB, (GLenum, GLuint, const GLfloat *)) +AGL_API(void, ProgramLocalParameter4dARB, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, ProgramLocalParameter4dvARB, (GLenum, GLuint, const GLdouble *)) +AGL_API(void, ProgramLocalParameter4fARB, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramLocalParameter4fvARB, (GLenum, GLuint, const GLfloat *)) +AGL_API(void, GetProgramEnvParameterdvARB, (GLenum, GLuint, GLdouble *)) +AGL_API(void, GetProgramEnvParameterfvARB, (GLenum, GLuint, GLfloat *)) +AGL_API(void, GetProgramLocalParameterdvARB, (GLenum, GLuint, GLdouble *)) +AGL_API(void, GetProgramLocalParameterfvARB, (GLenum, GLuint, GLfloat *)) +AGL_API(void, GetProgramivARB, (GLenum, GLenum, GLint *)) +AGL_API(void, GetProgramStringARB, (GLenum, GLenum, GLvoid *)) +AGL_API(void, GetVertexAttribdvARB, (GLuint, GLenum, GLdouble *)) +AGL_API(void, GetVertexAttribfvARB, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribivARB, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribPointervARB, (GLuint, GLenum, GLvoid* *)) +AGL_API(GLboolean, IsProgramARB, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_buffer_object +AGL_API(void, BindBufferARB, (GLenum, GLuint)) +AGL_API(void, DeleteBuffersARB, (GLsizei, const GLuint *)) +AGL_API(void, GenBuffersARB, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsBufferARB, (GLuint)) +AGL_API(void, BufferDataARB, (GLenum, GLsizeiptrARB, const GLvoid *, GLenum)) +AGL_API(void, BufferSubDataARB, (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *)) +AGL_API(void, GetBufferSubDataARB, (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *)) +AGL_API(GLvoid*, MapBufferARB, (GLenum, GLenum)) +AGL_API(GLboolean, UnmapBufferARB, (GLenum)) +AGL_API(void, GetBufferParameterivARB, (GLenum, GLenum, GLint *)) +AGL_API(void, GetBufferPointervARB, (GLenum, GLenum, GLvoid* *)) +#endif + +#if defined _ALLEGRO_GL_ARB_occlusion_query +AGL_API(void, GenQueriesARB, (GLsizei, GLuint *)) +AGL_API(void, DeleteQueriesARB, (GLsizei, const GLuint *)) +AGL_API(GLboolean, IsQueryARB, (GLuint)) +AGL_API(void, BeginQueryARB, (GLenum, GLuint)) +AGL_API(void, EndQueryARB, (GLenum)) +AGL_API(void, GetQueryivARB, (GLenum, GLenum, GLint *)) +AGL_API(void, GetQueryObjectivARB, (GLuint, GLenum, GLint *)) +AGL_API(void, GetQueryObjectuivARB, (GLuint, GLenum, GLuint *)) +#endif + +#if defined _ALLEGRO_GL_ARB_shader_objects +AGL_API(void, DeleteObjectARB, (GLhandleARB)) +AGL_API(GLhandleARB, GetHandleARB, (GLenum)) +AGL_API(void, DetachObjectARB, (GLhandleARB, GLhandleARB)) +AGL_API(GLhandleARB, CreateShaderObjectARB, (GLenum)) +AGL_API(void, ShaderSourceARB, (GLhandleARB, GLsizei, const GLcharARB **, const GLint *)) +AGL_API(void, CompileShaderARB, (GLhandleARB)) +AGL_API(GLhandleARB, CreateProgramObjectARB, (void)) +AGL_API(void, AttachObjectARB, (GLhandleARB, GLhandleARB)) +AGL_API(void, LinkProgramARB, (GLhandleARB)) +AGL_API(void, UseProgramObjectARB, (GLhandleARB)) +AGL_API(void, ValidateProgramARB, (GLhandleARB)) +AGL_API(void, Uniform1fARB, (GLint, GLfloat)) +AGL_API(void, Uniform2fARB, (GLint, GLfloat, GLfloat)) +AGL_API(void, Uniform3fARB, (GLint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Uniform4fARB, (GLint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Uniform1iARB, (GLint, GLint)) +AGL_API(void, Uniform2iARB, (GLint, GLint, GLint)) +AGL_API(void, Uniform3iARB, (GLint, GLint, GLint, GLint)) +AGL_API(void, Uniform4iARB, (GLint, GLint, GLint, GLint, GLint)) +AGL_API(void, Uniform1fvARB, (GLint, GLsizei, GLfloat *)) +AGL_API(void, Uniform2fvARB, (GLint, GLsizei, GLfloat *)) +AGL_API(void, Uniform3fvARB, (GLint, GLsizei, GLfloat *)) +AGL_API(void, Uniform4fvARB, (GLint, GLsizei, GLfloat *)) +AGL_API(void, Uniform1ivARB, (GLint, GLsizei, GLint *)) +AGL_API(void, Uniform2ivARB, (GLint, GLsizei, GLint *)) +AGL_API(void, Uniform3ivARB, (GLint, GLsizei, GLint *)) +AGL_API(void, Uniform4ivARB, (GLint, GLsizei, GLint *)) +AGL_API(void, UniformMatrix2fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) +AGL_API(void, UniformMatrix3fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) +AGL_API(void, UniformMatrix4fvARB, (GLint, GLsizei, GLboolean, GLfloat *)) +AGL_API(void, GetObjectParameterfvARB, (GLhandleARB, GLenum, GLfloat *)) +AGL_API(void, GetObjectParameterivARB, (GLhandleARB, GLenum, GLint *)) +AGL_API(void, GetInfoLogARB, (GLhandleARB, GLsizei, GLsizei *, GLcharARB *)) +AGL_API(void, GetAttachedObjectsARB, (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *)) +AGL_API(GLint, GetUniformLocationARB, (GLhandleARB, const GLcharARB *)) +AGL_API(void, GetActiveUniformARB, (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *)) +AGL_API(void, GetUniformfvARB, (GLhandleARB, GLint, GLfloat *)) +AGL_API(void, GetUniformivARB, (GLhandleARB, GLint, GLint *)) +AGL_API(void, GetShaderSourceARB, (GLhandleARB, GLsizei, GLsizei *, GLcharARB *)) +#endif + +#ifdef _ALLEGRO_GL_ARB_vertex_shader +#ifndef GL_ARB_vertex_program +AGL_API(void, VertexAttrib1fARB, (GLuint, GLfloat)) +AGL_API(void, VertexAttrib1sARB, (GLuint, GLshort)) +AGL_API(void, VertexAttrib1dARB, (GLuint, GLdouble)) +AGL_API(void, VertexAttrib2fARB, (GLuint, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib2sARB, (GLuint, GLshort, GLshort)) +AGL_API(void, VertexAttrib2dARB, (GLuint, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib3fARB, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib3sARB, (GLuint, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib3dARB, (GLuint, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4fARB, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib4sARB, (GLuint, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib4dARB, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4NubARB, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) +AGL_API(void, VertexAttrib1fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib1svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib1dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib2fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib2svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib2dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib3fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib3svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib3dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4fvARB, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib4svARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4dvARB, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4ivARB, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4bvARB, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4ubvARB, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4usvARB, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4uivARB, (GLuint, const GLuint *)) +AGL_API(void, VertexAttrib4NbvARB, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttrib4NsvARB, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4NivARB, (GLuint, const GLint *)) +AGL_API(void, VertexAttrib4NubvARB, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttrib4NusvARB, (GLuint, const GLushort *)) +AGL_API(void, VertexAttrib4NuivARB, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribPointerARB, (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *)) +AGL_API(void, EnableVertexAttribArrayARB, (GLuint)) +AGL_API(void, DisableVertexAttribArrayARB, (GLuint)) +#endif +AGL_API(void, BindAttribLocationARB, (GLhandleARB, GLuint, const GLcharARB *)) +AGL_API(void, GetActiveAttribARB, (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *)) +AGL_API(GLint, GetAttribLocationARB, (GLhandleARB, const GLcharARB *)) +#ifndef GL_ARB_vertex_program +AGL_API(void, GetVertexAttribdvARB, (GLuint, GLenum, GLdouble *)) +AGL_API(void, GetVertexAttribfvARB, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribivARB, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribPointervARB, (GLuint, GLenum, GLvoid **)) +#endif +#endif + +#if defined _ALLEGRO_GL_ARB_draw_buffers +AGL_API(void, DrawBuffersARB, (GLsizei n, const GLenum *bufs)) +#endif + +#if defined _ALLEGRO_GL_ARB_color_buffer_float +AGL_API(void, ClampColorARB, (GLenum, GLenum clamp)) +#endif + +#if defined _ALLEGRO_GL_ARB_draw_instanced +AGL_API(void, DrawArraysInstancedARB, (GLenum, GLint, GLsizei, GLsizei)) +AGL_API(void, DrawElementsInstancedARB, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_ARB_framebuffer_object +AGL_API(GLboolean, IsRenderbuffer, (GLuint)) +AGL_API(void, BindRenderbuffer, (GLenum, GLuint)) +AGL_API(void, DeleteRenderbuffers, (GLsizei, const GLuint *)) +AGL_API(void, GenRenderbuffers, (GLsizei, GLuint *)) +AGL_API(void, RenderbufferStorage, (GLenum, GLenum, GLsizei, GLsizei)) +AGL_API(void, GetRenderbufferParameteriv, (GLenum, GLenum, GLint *)) +AGL_API(GLboolean, IsFramebuffer, (GLuint)) +AGL_API(void, BindFramebuffer, (GLenum, GLuint)) +AGL_API(void, DeleteFramebuffers, (GLsizei, const GLuint *)) +AGL_API(void, GenFramebuffers, (GLsizei, GLuint *)) +AGL_API(GLenum, CheckFramebufferStatus, (GLenum)) +AGL_API(void, FramebufferTexture1D, (GLenum, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTexture2D, (GLenum, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTexture3D, (GLenum, GLenum, GLenum, GLuint, GLint, GLint)) +AGL_API(void, FramebufferRenderbuffer, (GLenum, GLenum, GLenum, GLuint)) +AGL_API(void, GetFramebufferAttachmentParameteriv, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GenerateMipmap, (GLenum)) +AGL_API(void, BlitFramebuffer, (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) +AGL_API(void, RenderbufferStorageMultisample, (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) +AGL_API(void, FramebufferTextureLayer, (GLenum, GLenum, GLuint, GLint, GLint)) +#endif + +#if defined _ALLEGRO_GL_ARB_geometry_shader4 +AGL_API(void, ProgramParameteriARB, (GLuint, GLenum, GLint)) +AGL_API(void, FramebufferTextureARB, (GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTextureLayerARB, (GLenum, GLenum, GLuint, GLint, GLint)) +AGL_API(void, FramebufferTextureFaceARB, (GLenum, GLenum, GLuint, GLint, GLenum)) +#endif + +#if defined _ALLEGRO_GL_ARB_instanced_arrays +AGL_API(void, VertexAttribDivisor, (GLuint, GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_map_buffer_range +AGL_API(void, MapBufferRange, (GLenum, GLintptr, GLsizeiptr, GLbitfield)) +AGL_API(void, FlushMappedBufferRange, (GLenum, GLintptr, GLsizeiptr)) +#endif + +#if defined _ALLEGRO_GL_ARB_texture_buffer_object +AGL_API(void, TexBufferARB, (GLenum, GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_array_object +AGL_API(void, BindVertexArray, (GLuint)) +AGL_API(void, DeleteVertexArrays, (GLsizei, const GLuint *)) +AGL_API(void, GenVertexArrays, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsVertexArray, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_uniform_buffer_object +AGL_API(void, GetUniformIndices, (GLuint, GLsizei, const GLchar* *, GLuint *)) +AGL_API(void, GetActiveUniformsiv, (GLuint, GLsizei, const GLuint *, GLenum, GLint *)) +AGL_API(void, GetActiveUniformName, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(GLuint, GetUniformBlockIndex, (GLuint, const GLchar *)) +AGL_API(void, GetActiveUniformBlockiv, (GLuint, GLuint, GLenum, GLint *)) +AGL_API(void, GetActiveUniformBlockName, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, UniformBlockBinding, (GLuint, GLuint, GLuint)) +#endif + +#if defined _ALLEGRO_GL_ARB_copy_buffer +AGL_API(void, CopyBufferSubData, (GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr)) +#endif + + +#if defined _ALLEGRO_GL_ARB_draw_elements_base_vertex +AGL_API(void, DrawElementsBaseVertex, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)) +AGL_API(void, DrawRangeElementsBaseVertex, (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)) +AGL_API(void, DrawElementsInstancedBaseVertex, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex)) +AGL_API(void, MultiDrawElementsBaseVertex, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex)) +#endif + +#if defined _ALLEGRO_GL_ARB_provoking_vertex +AGL_API(void, ProvokingVertex, (GLenum mode)) +#endif + +#if defined _ALLEGRO_GL_ARB_sync +AGL_API(GLsync, FenceSync, (GLenum condition, GLbitfield flags)) +AGL_API(GLboolean, IsSync, (GLsync sync)) +AGL_API(void, DeleteSync, (GLsync sync)) +AGL_API(GLenum, ClientWaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) +AGL_API(void, WaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) +AGL_API(void, GetInteger64v, (GLenum pname, GLint64 *params)) +AGL_API(void, GetSynciv, (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)) +#endif + +#if defined _ALLEGRO_GL_ARB_texture_multisample +AGL_API(void, TexImage2DMultisample, (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)) +AGL_API(void, TexImage3DMultisample, (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)) +AGL_API(void, GetMultisamplefv, (GLenum pname, GLuint index, GLfloat *val)) +AGL_API(void, SampleMaski, (GLuint index, GLbitfield mask)) +#endif + +#if defined _ALLEGRO_GL_ARB_draw_buffers_blend +AGL_API(void, BlendEquationi, (GLuint buf, GLenum mode)) +AGL_API(void, BlendEquationSeparatei, (GLuint buf, GLenum modeRGB, GLenum modeAlpha)) +AGL_API(void, BlendFunci, (GLuint buf, GLenum src, GLenum dst)) +AGL_API(void, BlendFuncSeparatei, (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)) +#endif + +#if defined _ALLEGRO_GL_ARB_sample_shading +AGL_API(void, MinSampleShading, (GLclampf value)) +#endif + +#if defined _ALLEGRO_GL_ARB_shading_language_include +AGL_API(void, NamedStringARB, (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string)) +AGL_API(void, DeleteNamedStringARB, (GLint namelen, const GLchar *name)) +AGL_API(void, CompileShaderIncludeARB, (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length)) +AGL_API(GLboolean, IsNamedStringARB, (GLint namelen, const GLchar *name)) +AGL_API(void, GetNamedStringARB, (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string)) +AGL_API(void, GetNamedStringivARB, (GLint namelen, const GLchar *name, GLenum pname, GLint *params)) +#endif + +#if defined _ALLEGRO_GL_ARB_blend_func_extended +AGL_API(void, BindFragDataLocationIndexed, (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name)) +AGL_API(GLint, GetFragDataIndex, (GLuint program, const GLchar *name)) +#endif + +#if defined _ALLEGRO_GL_ARB_sampler_objects +AGL_API(void, GenSamplers, (GLsizei count, GLuint *samplers)) +AGL_API(void, DeleteSamplers, (GLsizei count, const GLuint *samplers)) +AGL_API(GLboolean, IsSampler, (GLuint sampler)) +AGL_API(void, BindSampler, (GLenum unit, GLuint sampler)) +AGL_API(void, SamplerParameteri, (GLuint sampler, GLenum pname, GLint param)) +AGL_API(void, SamplerParameteriv, (GLuint sampler, GLenum pname, const GLint *param)) +AGL_API(void, SamplerParameterf, (GLuint sampler, GLenum pname, GLfloat param)) +AGL_API(void, SamplerParameterfv, (GLuint sampler, GLenum pname, const GLfloat *param)) +AGL_API(void, SamplerParameterIiv, (GLuint sampler, GLenum pname, const GLint *param)) +AGL_API(void, SamplerParameterIuiv, (GLuint sampler, GLenum pname, const GLuint *param)) +AGL_API(void, GetSamplerParameteriv, (GLuint sampler, GLenum pname, GLint *params)) +AGL_API(void, GetSamplerParameterIiv, (GLuint sampler, GLenum pname, GLint *params)) +AGL_API(void, GetSamplerParameterfv, (GLuint sampler, GLenum pname, GLfloat *params)) +AGL_API(void, GetSamplerParameterIfv, (GLuint sampler, GLenum pname, GLfloat *params)) +#endif + +#if defined _ALLEGRO_GL_ARB_timer_query +AGL_API(void, QueryCounter, (GLuint id, GLenum target)) +AGL_API(void, GetQueryObjecti64v, (GLuint id, GLenum pname, GLint64 *params)) +AGL_API(void, GetQueryObjectui64v, (GLuint id, GLenum pname, GLuint64 *params)) +#endif + +#if defined _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev +AGL_API(void, VertexP2ui, (GLenum type, GLuint value)) +AGL_API(void, VertexP2uiv, (GLenum type, const GLuint *value)) +AGL_API(void, VertexP3ui, (GLenum type, GLuint value)) +AGL_API(void, VertexP3uiv, (GLenum type, const GLuint *value)) +AGL_API(void, VertexP4ui, (GLenum type, GLuint value)) +AGL_API(void, VertexP4uiv, (GLenum type, const GLuint *value)) +AGL_API(void, TexCoordP1ui, (GLenum type, GLuint coords)) +AGL_API(void, TexCoordP1uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, TexCoordP2ui, (GLenum type, GLuint coords)) +AGL_API(void, TexCoordP2uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, TexCoordP3ui, (GLenum type, GLuint coords)) +AGL_API(void, TexCoordP3uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, TexCoordP4ui, (GLenum type, GLuint coords)) +AGL_API(void, TexCoordP4uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, MultiTexCoordP1ui, (GLenum texture, GLenum type, GLuint coords)) +AGL_API(void, MultiTexCoordP1uiv, (GLenum texture, GLenum type, const GLuint *coords)) +AGL_API(void, MultiTexCoordP2ui, (GLenum texture, GLenum type, GLuint coords)) +AGL_API(void, MultiTexCoordP2uiv, (GLenum texture, GLenum type, const GLuint *coords)) +AGL_API(void, MultiTexCoordP3ui, (GLenum texture, GLenum type, GLuint coords)) +AGL_API(void, MultiTexCoordP3uiv, (GLenum texture, GLenum type, const GLuint *coords)) +AGL_API(void, MultiTexCoordP4ui, (GLenum texture, GLenum type, GLuint coords)) +AGL_API(void, MultiTexCoordP4uiv, (GLenum texture, GLenum type, const GLuint *coords)) +AGL_API(void, NormalP3ui, (GLenum type, GLuint coords)) +AGL_API(void, NormalP3uiv, (GLenum type, const GLuint *coords)) +AGL_API(void, ColorP3ui, (GLenum type, GLuint color)) +AGL_API(void, ColorP3uiv, (GLenum type, const GLuint *color)) +AGL_API(void, ColorP4ui, (GLenum type, GLuint color)) +AGL_API(void, ColorP4uiv, (GLenum type, const GLuint *color)) +AGL_API(void, SecondaryColorP3ui, (GLenum type, GLuint color)) +AGL_API(void, SecondaryColorP3uiv, (GLenum type, const GLuint *color)) +AGL_API(void, VertexAttribP1ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) +AGL_API(void, VertexAttribP1uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) +AGL_API(void, VertexAttribP2ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) +AGL_API(void, VertexAttribP2uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) +AGL_API(void, VertexAttribP3ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) +AGL_API(void, VertexAttribP3uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) +AGL_API(void, VertexAttribP4ui, (GLuint index, GLenum type, GLboolean normalized, GLuint value)) +AGL_API(void, VertexAttribP4uiv, (GLuint index, GLenum type, GLboolean normalized, const GLuint *value)) +#endif + +#if defined _ALLEGRO_GL_ARB_draw_indirect +AGL_API(void, DrawArraysIndirect, (GLenum mode, const GLvoid *indirect)) +AGL_API(void, DrawElementsIndirect, (GLenum mode, GLenum type, const GLvoid *indirect)) +#endif + +#if defined _ALLEGRO_GL_ARB_gpu_shader_fp64 +AGL_API(void, Uniform1d, (GLint location, GLdouble x)) +AGL_API(void, Uniform2d, (GLint location, GLdouble x, GLdouble y)) +AGL_API(void, Uniform3d, (GLint location, GLdouble x, GLdouble y, GLdouble z)) +AGL_API(void, Uniform4d, (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +AGL_API(void, Uniform1dv, (GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, Uniform2dv, (GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, Uniform3dv, (GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, Uniform4dv, (GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, UniformMatrix2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix2x3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix2x4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix3x2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix3x4dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix4x2dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, UniformMatrix4x3dv, (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, GetUniformdv, (GLuint program, GLint location, GLdouble *params)) +AGL_API(void, ProgramUniform1dEXT, (GLuint program, GLint location, GLdouble x)) +AGL_API(void, ProgramUniform2dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y)) +AGL_API(void, ProgramUniform3dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z)) +AGL_API(void, ProgramUniform4dEXT, (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +AGL_API(void, ProgramUniform1dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, ProgramUniform2dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, ProgramUniform3dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, ProgramUniform4dvEXT, (GLuint program, GLint location, GLsizei count, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix2x3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix2x4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix3x2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix3x4dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix4x2dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +AGL_API(void, ProgramUniformMatrix4x3dvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)) +#endif + +#if defined _ALLEGRO_GL_ARB_shader_subroutine +AGL_API(GLint, GetSubroutineUniformLocation, (GLuint program, GLenum shadertype, const GLchar *name)) +AGL_API(GLuint, GetSubroutineIndex, (GLuint program, GLenum shadertype, const GLchar *name)) +AGL_API(void, GetActiveSubroutineUniformiv, (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values)) +AGL_API(void, GetActiveSubroutineUniformName, (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)) +AGL_API(void, GetActiveSubroutineName, (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)) +AGL_API(void, UniformSubroutinesuiv, (GLenum shadertype, GLsizei count, const GLuint *indices)) +AGL_API(void, GetUniformSubroutineuiv, (GLenum shadertype, GLint location, GLuint *params)) +AGL_API(void, GetProgramStageiv, (GLuint program, GLenum shadertype, GLenum pname, GLint *values)) +#endif + +#if defined _ALLEGRO_GL_ARB_tessellation_shader +AGL_API(void, PatchParameteri, (GLenum pname, GLint value)) +AGL_API(void, PatchParameterfv, (GLenum pname, const GLfloat *values)) +#endif + +#if defined _ALLEGRO_GL_ARB_transform_feedback2 +AGL_API(void, BindTransformFeedback, (GLenum target, GLuint id)) +AGL_API(void, DeleteTransformFeedbacks, (GLsizei n, const GLuint *ids)) +AGL_API(void, GenTransformFeedbacks, (GLsizei n, GLuint *ids)) +AGL_API(GLboolean, IsTransformFeedback, (GLuint id)) +AGL_API(void, PauseTransformFeedback, (void)) +AGL_API(void, ResumeTransformFeedback, (void)) +AGL_API(void, DrawTransformFeedback, (GLenum mode, GLuint id)) +#endif + +#if defined _ALLEGRO_GL_ARB_transform_feedback3 +AGL_API(void, DrawTransformFeedbackStream, (GLenum mode, GLuint id, GLuint stream)) +AGL_API(void, BeginQueryIndexed, (GLenum target, GLuint index, GLuint id)) +AGL_API(void, EndQueryIndexed, (GLenum target, GLuint index)) +AGL_API(void, GetQueryIndexediv, (GLenum target, GLuint index, GLenum pname, GLint *params)) +#endif + + +/* */ + + +#if defined _ALLEGRO_GL_EXT_blend_color +AGL_API(void, BlendColorEXT, (GLclampf, GLclampf, GLclampf, GLclampf)) +#endif + +#if defined _ALLEGRO_GL_EXT_polygon_offset +AGL_API(void, PolygonOffsetEXT, (GLfloat, GLfloat)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture3D +AGL_API(void, TexImage3DEXT, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TexSubImage3DEXT, (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_texture_filter4 +AGL_API(void, GetTexFilterFuncSGIS, (GLenum, GLenum, GLfloat *)) +AGL_API(void, TexFilterFuncSGIS, (GLenum, GLenum, GLsizei, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_EXT_subtexture +AGL_API(void, TexSubImage1DEXT, (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TexSubImage2DEXT, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_copy_texture +AGL_API(void, CopyTexImage1DEXT, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) +AGL_API(void, CopyTexImage2DEXT, (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) +AGL_API(void, CopyTexSubImage1DEXT, (GLenum, GLint, GLint, GLint, GLint, GLsizei)) +AGL_API(void, CopyTexSubImage2DEXT, (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, CopyTexSubImage3DEXT, (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_EXT_histogram +AGL_API(void, GetHistogramEXT, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetHistogramParameterfvEXT, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetHistogramParameterivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, GetMinmaxEXT, (GLenum, GLboolean, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetMinmaxParameterfvEXT, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMinmaxParameterivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, HistogramEXT, (GLenum, GLsizei, GLenum, GLboolean)) +AGL_API(void, MinmaxEXT, (GLenum, GLenum, GLboolean)) +AGL_API(void, ResetHistogramEXT, (GLenum)) +AGL_API(void, ResetMinmaxEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_convolution +AGL_API(void, ConvolutionFilter1DEXT, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ConvolutionFilter2DEXT, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ConvolutionParameterfEXT, (GLenum, GLenum, GLfloat)) +AGL_API(void, ConvolutionParameterfvEXT, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, ConvolutionParameteriEXT, (GLenum, GLenum, GLint)) +AGL_API(void, ConvolutionParameterivEXT, (GLenum, GLenum, const GLint *)) +AGL_API(void, CopyConvolutionFilter1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei)) +AGL_API(void, CopyConvolutionFilter2DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, GetConvolutionFilterEXT, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetConvolutionParameterfvEXT, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetConvolutionParameterivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, GetSeparableFilterEXT, (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *)) +AGL_API(void, SeparableFilter2DEXT, (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_SGI_color_table +AGL_API(void, ColorTableSGI, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, ColorTableParameterfvSGI, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, ColorTableParameterivSGI, (GLenum, GLenum, const GLint *)) +AGL_API(void, CopyColorTableSGI, (GLenum, GLenum, GLint, GLint, GLsizei)) +AGL_API(void, GetColorTableSGI, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetColorTableParameterfvSGI, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetColorTableParameterivSGI, (GLenum, GLenum, GLint *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_pixel_texture +AGL_API(void, PixelTexGenSGIX, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_SGIS_pixel_texture +AGL_API(void, PixelTexGenParameteriSGIS, (GLenum, GLint)) +AGL_API(void, PixelTexGenParameterivSGIS, (GLenum, const GLint *)) +AGL_API(void, PixelTexGenParameterfSGIS, (GLenum, GLfloat)) +AGL_API(void, PixelTexGenParameterfvSGIS, (GLenum, const GLfloat *)) +AGL_API(void, GetPixelTexGenParameterivSGIS, (GLenum, GLint *)) +AGL_API(void, GetPixelTexGenParameterfvSGIS, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_texture4D +AGL_API(void, TexImage4DSGIS, (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TexSubImage4DSGIS, (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture_object +AGL_API(GLboolean, AreTexturesResidentEXT, (GLsizei, const GLuint *, GLboolean *)) +AGL_API(void, BindTextureEXT, (GLenum, GLuint)) +AGL_API(void, DeleteTexturesEXT, (GLsizei, const GLuint *)) +AGL_API(void, GenTexturesEXT, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsTextureEXT, (GLuint)) +AGL_API(void, PrioritizeTexturesEXT, (GLsizei, const GLuint *, const GLclampf *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_detail_texture +AGL_API(void, DetailTexFuncSGIS, (GLenum, GLsizei, const GLfloat *)) +AGL_API(void, GetDetailTexFuncSGIS, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_sharpen_texture +AGL_API(void, SharpenTexFuncSGIS, (GLenum, GLsizei, const GLfloat *)) +AGL_API(void, GetSharpenTexFuncSGIS, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_multisample +AGL_API(void, SampleMaskSGIS, (GLclampf, GLboolean)) +AGL_API(void, SamplePatternSGIS, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_array +AGL_API(void, ArrayElementEXT, (GLint)) +AGL_API(void, ColorPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) +AGL_API(void, DrawArraysEXT, (GLenum, GLint, GLsizei)) +AGL_API(void, EdgeFlagPointerEXT, (GLsizei, GLsizei, const GLboolean *)) +AGL_API(void, GetPointervEXT, (GLenum, GLvoid* *)) +AGL_API(void, IndexPointerEXT, (GLenum, GLsizei, GLsizei, const GLvoid *)) +AGL_API(void, NormalPointerEXT, (GLenum, GLsizei, GLsizei, const GLvoid *)) +AGL_API(void, TexCoordPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) +AGL_API(void, VertexPointerEXT, (GLint, GLenum, GLsizei, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_blend_minmax +AGL_API(void, BlendEquationEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_SGIX_sprite +AGL_API(void, SpriteParameterfSGIX, (GLenum, GLfloat)) +AGL_API(void, SpriteParameterfvSGIX, (GLenum, const GLfloat *)) +AGL_API(void, SpriteParameteriSGIX, (GLenum, GLint)) +AGL_API(void, SpriteParameterivSGIX, (GLenum, const GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_point_parameters +AGL_API(void, PointParameterfEXT, (GLenum, GLfloat)) +AGL_API(void, PointParameterfvEXT, (GLenum, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIS_point_parameters +AGL_API(void, PointParameterfSGIS, (GLenum, GLfloat)) +AGL_API(void, PointParameterfvSGIS, (GLenum, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_instruments +AGL_API(GLint, GetInstrumentsSGIX, (void)) +AGL_API(void, InstrumentsBufferSGIX, (GLsizei, GLint *)) +AGL_API(GLint, PollInstrumentsSGIX, (GLint *)) +AGL_API(void, ReadInstrumentsSGIX, (GLint)) +AGL_API(void, StartInstrumentsSGIX, (void)) +AGL_API(void, StopInstrumentsSGIX, (GLint)) +#endif + +#if defined _ALLEGRO_GL_SGIX_framezoom +AGL_API(void, FrameZoomSGIX, (GLint)) +#endif + +#if defined _ALLEGRO_GL_SGIX_tag_sample_buffer +AGL_API(void, TagSampleBufferSGIX, (void)) +#endif + +#if defined _ALLEGRO_GL_SGIX_polynomial_ffd +AGL_API(void, DeformationMap3dSGIX, (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *)) +AGL_API(void, DeformationMap3fSGIX, (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *)) +AGL_API(void, DeformSGIX, (GLbitfield)) +AGL_API(void, LoadIdentityDeformationMapSGIX, (GLbitfield)) +#endif + +#if defined _ALLEGRO_GL_SGIX_reference_plane +AGL_API(void, ReferencePlaneSGIX, (const GLdouble *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_flush_raster +AGL_API(void, FlushRasterSGIX, (void)) +#endif + +#if defined _ALLEGRO_GL_SGIS_fog_function +AGL_API(void, FogFuncSGIS, (GLsizei, const GLfloat *)) +AGL_API(void, GetFogFuncSGIS, (GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_HP_image_transform +AGL_API(void, ImageTransformParameteriHP, (GLenum, GLenum, GLint)) +AGL_API(void, ImageTransformParameterfHP, (GLenum, GLenum, GLfloat)) +AGL_API(void, ImageTransformParameterivHP, (GLenum, GLenum, const GLint *)) +AGL_API(void, ImageTransformParameterfvHP, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, GetImageTransformParameterivHP, (GLenum, GLenum, GLint *)) +AGL_API(void, GetImageTransformParameterfvHP, (GLenum, GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_EXT_color_subtable +#ifndef GL_EXT_paletted_texture +AGL_API(void, ColorSubTableEXT, (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +#endif +AGL_API(void, CopyColorSubTableEXT, (GLenum, GLsizei, GLint, GLint, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_PGI_misc_hints +AGL_API(void, HintPGI, (GLenum, GLint)) +#endif + +#if defined _ALLEGRO_GL_EXT_paletted_texture +AGL_API(void, ColorTableEXT, (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, GetColorTableEXT, (GLenum, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetColorTableParameterivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, GetColorTableParameterfvEXT, (GLenum, GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_list_priority +AGL_API(void, GetListParameterfvSGIX, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetListParameterivSGIX, (GLuint, GLenum, GLint *)) +AGL_API(void, ListParameterfSGIX, (GLuint, GLenum, GLfloat)) +AGL_API(void, ListParameterfvSGIX, (GLuint, GLenum, const GLfloat *)) +AGL_API(void, ListParameteriSGIX, (GLuint, GLenum, GLint)) +AGL_API(void, ListParameterivSGIX, (GLuint, GLenum, const GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_index_material +AGL_API(void, IndexMaterialEXT, (GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_index_func +AGL_API(void, IndexFuncEXT, (GLenum, GLclampf)) +#endif + +#if defined _ALLEGRO_GL_EXT_compiled_vertex_array +AGL_API(void, LockArraysEXT, (GLint, GLsizei)) +AGL_API(void, UnlockArraysEXT, (void)) +#endif + +#if defined _ALLEGRO_GL_EXT_cull_vertex +AGL_API(void, CullParameterdvEXT, (GLenum, GLdouble *)) +AGL_API(void, CullParameterfvEXT, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_SGIX_fragment_lighting +AGL_API(void, FragmentColorMaterialSGIX, (GLenum, GLenum)) +AGL_API(void, FragmentLightfSGIX, (GLenum, GLenum, GLfloat)) +AGL_API(void, FragmentLightfvSGIX, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, FragmentLightiSGIX, (GLenum, GLenum, GLint)) +AGL_API(void, FragmentLightivSGIX, (GLenum, GLenum, const GLint *)) +AGL_API(void, FragmentLightModelfSGIX, (GLenum, GLfloat)) +AGL_API(void, FragmentLightModelfvSGIX, (GLenum, const GLfloat *)) +AGL_API(void, FragmentLightModeliSGIX, (GLenum, GLint)) +AGL_API(void, FragmentLightModelivSGIX, (GLenum, const GLint *)) +AGL_API(void, FragmentMaterialfSGIX, (GLenum, GLenum, GLfloat)) +AGL_API(void, FragmentMaterialfvSGIX, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, FragmentMaterialiSGIX, (GLenum, GLenum, GLint)) +AGL_API(void, FragmentMaterialivSGIX, (GLenum, GLenum, const GLint *)) +AGL_API(void, GetFragmentLightfvSGIX, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetFragmentLightivSGIX, (GLenum, GLenum, GLint *)) +AGL_API(void, GetFragmentMaterialfvSGIX, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetFragmentMaterialivSGIX, (GLenum, GLenum, GLint *)) +AGL_API(void, LightEnviSGIX, (GLenum, GLint)) +#endif + +#if defined _ALLEGRO_GL_EXT_draw_range_elements +AGL_API(void, DrawRangeElementsEXT, (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_light_texture +AGL_API(void, ApplyTextureEXT, (GLenum)) +AGL_API(void, TextureLightEXT, (GLenum)) +AGL_API(void, TextureMaterialEXT, (GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_SGIX_async +AGL_API(void, AsyncMarkerSGIX, (GLuint)) +AGL_API(GLint, FinishAsyncSGIX, (GLuint *)) +AGL_API(GLint, PollAsyncSGIX, (GLuint *)) +AGL_API(GLuint, GenAsyncMarkersSGIX, (GLsizei)) +AGL_API(void, DeleteAsyncMarkersSGIX, (GLuint, GLsizei)) +AGL_API(GLboolean, IsAsyncMarkerSGIX, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_INTEL_parallel_arrays +AGL_API(void, VertexPointervINTEL, (GLint, GLenum, const GLvoid* *)) +AGL_API(void, NormalPointervINTEL, (GLenum, const GLvoid* *)) +AGL_API(void, ColorPointervINTEL, (GLint, GLenum, const GLvoid* *)) +AGL_API(void, TexCoordPointervINTEL, (GLint, GLenum, const GLvoid* *)) +#endif + +#if defined _ALLEGRO_GL_EXT_pixel_transform +AGL_API(void, PixelTransformParameteriEXT, (GLenum, GLenum, GLint)) +AGL_API(void, PixelTransformParameterfEXT, (GLenum, GLenum, GLfloat)) +AGL_API(void, PixelTransformParameterivEXT, (GLenum, GLenum, const GLint *)) +AGL_API(void, PixelTransformParameterfvEXT, (GLenum, GLenum, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_EXT_secondary_color +AGL_API(void, SecondaryColor3bEXT, (GLbyte, GLbyte, GLbyte)) +AGL_API(void, SecondaryColor3bvEXT, (const GLbyte *)) +AGL_API(void, SecondaryColor3dEXT, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, SecondaryColor3dvEXT, (const GLdouble *)) +AGL_API(void, SecondaryColor3fEXT, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, SecondaryColor3fvEXT, (const GLfloat *)) +AGL_API(void, SecondaryColor3iEXT, (GLint, GLint, GLint)) +AGL_API(void, SecondaryColor3ivEXT, (const GLint *)) +AGL_API(void, SecondaryColor3sEXT, (GLshort, GLshort, GLshort)) +AGL_API(void, SecondaryColor3svEXT, (const GLshort *)) +AGL_API(void, SecondaryColor3ubEXT, (GLubyte, GLubyte, GLubyte)) +AGL_API(void, SecondaryColor3ubvEXT, (const GLubyte *)) +AGL_API(void, SecondaryColor3uiEXT, (GLuint, GLuint, GLuint)) +AGL_API(void, SecondaryColor3uivEXT, (const GLuint *)) +AGL_API(void, SecondaryColor3usEXT, (GLushort, GLushort, GLushort)) +AGL_API(void, SecondaryColor3usvEXT, (const GLushort *)) +AGL_API(void, SecondaryColorPointerEXT, (GLint, GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture_perturb_normal +AGL_API(void, TextureNormalEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_multi_draw_arrays +AGL_API(void, MultiDrawArraysEXT, (GLenum, GLint *, GLsizei *, GLsizei)) +AGL_API(void, MultiDrawElementsEXT, (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_EXT_fog_coord +AGL_API(void, FogCoordfEXT, (GLfloat)) +AGL_API(void, FogCoordfvEXT, (const GLfloat *)) +AGL_API(void, FogCoorddEXT, (GLdouble)) +AGL_API(void, FogCoorddvEXT, (const GLdouble *)) +AGL_API(void, FogCoordPointerEXT, (GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_coordinate_frame +AGL_API(void, Tangent3bEXT, (GLbyte, GLbyte, GLbyte)) +AGL_API(void, Tangent3bvEXT, (const GLbyte *)) +AGL_API(void, Tangent3dEXT, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, Tangent3dvEXT, (const GLdouble *)) +AGL_API(void, Tangent3fEXT, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, Tangent3fvEXT, (const GLfloat *)) +AGL_API(void, Tangent3iEXT, (GLint, GLint, GLint)) +AGL_API(void, Tangent3ivEXT, (const GLint *)) +AGL_API(void, Tangent3sEXT, (GLshort, GLshort, GLshort)) +AGL_API(void, Tangent3svEXT, (const GLshort *)) +AGL_API(void, Binormal3bEXT, (GLbyte, GLbyte, GLbyte)) +AGL_API(void, Binormal3bvEXT, (const GLbyte *)) +AGL_API(void, Binormal3dEXT, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, Binormal3dvEXT, (const GLdouble *)) +AGL_API(void, Binormal3fEXT, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, Binormal3fvEXT, (const GLfloat *)) +AGL_API(void, Binormal3iEXT, (GLint, GLint, GLint)) +AGL_API(void, Binormal3ivEXT, (const GLint *)) +AGL_API(void, Binormal3sEXT, (GLshort, GLshort, GLshort)) +AGL_API(void, Binormal3svEXT, (const GLshort *)) +AGL_API(void, TangentPointerEXT, (GLenum, GLsizei, const GLvoid *)) +AGL_API(void, BinormalPointerEXT, (GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_SUNX_constant_data +AGL_API(void, FinishTextureSUNX, (void)) +#endif + +#if defined _ALLEGRO_GL_SUN_global_alpha +AGL_API(void, GlobalAlphaFactorbSUN, (GLbyte)) +AGL_API(void, GlobalAlphaFactorsSUN, (GLshort)) +AGL_API(void, GlobalAlphaFactoriSUN, (GLint)) +AGL_API(void, GlobalAlphaFactorfSUN, (GLfloat)) +AGL_API(void, GlobalAlphaFactordSUN, (GLdouble)) +AGL_API(void, GlobalAlphaFactorubSUN, (GLubyte)) +AGL_API(void, GlobalAlphaFactorusSUN, (GLushort)) +AGL_API(void, GlobalAlphaFactoruiSUN, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_SUN_triangle_list +AGL_API(void, ReplacementCodeuiSUN, (GLuint)) +AGL_API(void, ReplacementCodeusSUN, (GLushort)) +AGL_API(void, ReplacementCodeubSUN, (GLubyte)) +AGL_API(void, ReplacementCodeuivSUN, (const GLuint *)) +AGL_API(void, ReplacementCodeusvSUN, (const GLushort *)) +AGL_API(void, ReplacementCodeubvSUN, (const GLubyte *)) +AGL_API(void, ReplacementCodePointerSUN, (GLenum, GLsizei, const GLvoid* *)) +#endif + +#if defined _ALLEGRO_GL_SUN_vertex +AGL_API(void, Color4ubVertex2fSUN, (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat)) +AGL_API(void, Color4ubVertex2fvSUN, (const GLubyte *, const GLfloat *)) +AGL_API(void, Color4ubVertex3fSUN, (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Color4ubVertex3fvSUN, (const GLubyte *, const GLfloat *)) +AGL_API(void, Color3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Color3fVertex3fvSUN, (const GLfloat *, const GLfloat *)) +AGL_API(void, Normal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Normal3fVertex3fvSUN, (const GLfloat *, const GLfloat *)) +AGL_API(void, Color4fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, Color4fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord2fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fVertex3fvSUN, (const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord4fVertex4fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord4fVertex4fvSUN, (const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord2fColor4ubVertex3fSUN, (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fColor4ubVertex3fvSUN, (const GLfloat *, const GLubyte *, const GLfloat *)) +AGL_API(void, TexCoord2fColor3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fColor3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord2fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord2fColor4fNormal3fVertex3fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord2fColor4fNormal3fVertex3fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, TexCoord4fColor4fNormal3fVertex4fSUN, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, TexCoord4fColor4fNormal3fVertex4fvSUN, (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiVertex3fvSUN, (const GLuint *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiColor4ubVertex3fSUN, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiColor4ubVertex3fvSUN, (const GLuint *, const GLubyte *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiColor3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiColor3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiColor4fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiColor4fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiTexCoord2fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiTexCoord2fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *)) +AGL_API(void, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN, (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_EXT_blend_func_separate +AGL_API(void, BlendFuncSeparateEXT, (GLenum, GLenum, GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_INGR_blend_func_separate +AGL_API(void, BlendFuncSeparateINGR, (GLenum, GLenum, GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_weighting +AGL_API(void, VertexWeightfEXT, (GLfloat)) +AGL_API(void, VertexWeightfvEXT, (const GLfloat *)) +AGL_API(void, VertexWeightPointerEXT, (GLsizei, GLenum, GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_NV_vertex_array_range +AGL_API(void, FlushVertexArrayRangeNV, (void)) +AGL_API(void, VertexArrayRangeNV, (GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_NV_register_combiners +AGL_API(void, CombinerParameterfvNV, (GLenum, const GLfloat *)) +AGL_API(void, CombinerParameterfNV, (GLenum, GLfloat)) +AGL_API(void, CombinerParameterivNV, (GLenum, const GLint *)) +AGL_API(void, CombinerParameteriNV, (GLenum, GLint)) +AGL_API(void, CombinerInputNV, (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, CombinerOutputNV, (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean)) +AGL_API(void, FinalCombinerInputNV, (GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, GetCombinerInputParameterfvNV, (GLenum, GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetCombinerInputParameterivNV, (GLenum, GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetCombinerOutputParameterfvNV, (GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetCombinerOutputParameterivNV, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetFinalCombinerInputParameterfvNV, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetFinalCombinerInputParameterivNV, (GLenum, GLenum, GLint *)) +#endif + +#if defined _ALLEGRO_GL_MESA_resize_buffers +AGL_API(void, ResizeBuffersMESA, (void)) +#endif + +#if defined _ALLEGRO_GL_MESA_window_pos +AGL_API(void, WindowPos2dMESA, (GLdouble, GLdouble)) +AGL_API(void, WindowPos2dvMESA, (const GLdouble *)) +AGL_API(void, WindowPos2fMESA, (GLfloat, GLfloat)) +AGL_API(void, WindowPos2fvMESA, (const GLfloat *)) +AGL_API(void, WindowPos2iMESA, (GLint, GLint)) +AGL_API(void, WindowPos2ivMESA, (const GLint *)) +AGL_API(void, WindowPos2sMESA, (GLshort, GLshort)) +AGL_API(void, WindowPos2svMESA, (const GLshort *)) +AGL_API(void, WindowPos3dMESA, (GLdouble, GLdouble, GLdouble)) +AGL_API(void, WindowPos3dvMESA, (const GLdouble *)) +AGL_API(void, WindowPos3fMESA, (GLfloat, GLfloat, GLfloat)) +AGL_API(void, WindowPos3fvMESA, (const GLfloat *)) +AGL_API(void, WindowPos3iMESA, (GLint, GLint, GLint)) +AGL_API(void, WindowPos3ivMESA, (const GLint *)) +AGL_API(void, WindowPos3sMESA, (GLshort, GLshort, GLshort)) +AGL_API(void, WindowPos3svMESA, (const GLshort *)) +AGL_API(void, WindowPos4dMESA, (GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, WindowPos4dvMESA, (const GLdouble *)) +AGL_API(void, WindowPos4fMESA, (GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, WindowPos4fvMESA, (const GLfloat *)) +AGL_API(void, WindowPos4iMESA, (GLint, GLint, GLint, GLint)) +AGL_API(void, WindowPos4ivMESA, (const GLint *)) +AGL_API(void, WindowPos4sMESA, (GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, WindowPos4svMESA, (const GLshort *)) +#endif + +#if defined _ALLEGRO_GL_IBM_multimode_draw_arrays +AGL_API(void, MultiModeDrawArraysIBM, (GLenum, const GLint *, const GLsizei *, GLsizei, GLint)) +AGL_API(void, MultiModeDrawElementsIBM, (const GLenum *, const GLsizei *, GLenum, const GLvoid* *, GLsizei, GLint)) +#endif + +#ifdef AGK_IBM_vertex_array_lists +AGL_API(void, ColorPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, SecondaryColorPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, EdgeFlagPointerListIBM, (GLint, const GLboolean* *, GLint)) +AGL_API(void, FogCoordPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, IndexPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, NormalPointerListIBM, (GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, TexCoordPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) +AGL_API(void, VertexPointerListIBM, (GLint, GLenum, GLint, const GLvoid* *, GLint)) +#endif + +#if defined _ALLEGRO_GL_3DFX_tbuffer +AGL_API(void, TbufferMask3DFX, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_EXT_multisample +AGL_API(void, SampleMaskEXT, (GLclampf, GLboolean)) +AGL_API(void, SamplePatternEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_SGIS_texture_color_mask +AGL_API(void, TextureColorMaskSGIS, (GLboolean, GLboolean, GLboolean, GLboolean)) +#endif + +#if defined _ALLEGRO_GL_SGIX_igloo_interface +AGL_API(void, IglooInterfaceSGIX, (GLenum, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_NV_fence +AGL_API(void, DeleteFencesNV, (GLsizei, const GLuint *)) +AGL_API(void, GenFencesNV, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsFenceNV, (GLuint)) +AGL_API(GLboolean, TestFenceNV, (GLuint)) +AGL_API(void, GetFenceivNV, (GLuint, GLenum, GLint *)) +AGL_API(void, FinishFenceNV, (GLuint)) +AGL_API(void, SetFenceNV, (GLuint, GLenum)) +#endif + +#if defined _ALLEGRO_GL_NV_evaluators +AGL_API(void, MapControlPointsNV, (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *)) +AGL_API(void, MapParameterivNV, (GLenum, GLenum, const GLint *)) +AGL_API(void, MapParameterfvNV, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, GetMapControlPointsNV, (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *)) +AGL_API(void, GetMapParameterivNV, (GLenum, GLenum, GLint *)) +AGL_API(void, GetMapParameterfvNV, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMapAttribParameterivNV, (GLenum, GLuint, GLenum, GLint *)) +AGL_API(void, GetMapAttribParameterfvNV, (GLenum, GLuint, GLenum, GLfloat *)) +AGL_API(void, EvalMapsNV, (GLenum, GLenum)) +#endif + +#if defined _ALLEGRO_GL_NV_register_combiners2 +AGL_API(void, CombinerStageParameterfvNV, (GLenum, GLenum, const GLfloat *)) +AGL_API(void, GetCombinerStageParameterfvNV, (GLenum, GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_NV_vertex_program +AGL_API(GLboolean, AreProgramsResidentNV, (GLsizei, const GLuint *, GLboolean *)) +AGL_API(void, BindProgramNV, (GLenum, GLuint)) +AGL_API(void, DeleteProgramsNV, (GLsizei, const GLuint *)) +AGL_API(void, ExecuteProgramNV, (GLenum, GLuint, const GLfloat *)) +AGL_API(void, GenProgramsNV, (GLsizei, GLuint *)) +AGL_API(void, GetProgramParameterdvNV, (GLenum, GLuint, GLenum, GLdouble *)) +AGL_API(void, GetProgramParameterfvNV, (GLenum, GLuint, GLenum, GLfloat *)) +AGL_API(void, GetProgramivNV, (GLuint, GLenum, GLint *)) +AGL_API(void, GetProgramStringNV, (GLuint, GLenum, GLubyte *)) +AGL_API(void, GetTrackMatrixivNV, (GLenum, GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribdvNV, (GLuint, GLenum, GLdouble *)) +AGL_API(void, GetVertexAttribfvNV, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribivNV, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribPointervNV, (GLuint, GLenum, GLvoid* *)) +AGL_API(GLboolean, IsProgramNV, (GLuint)) +AGL_API(void, LoadProgramNV, (GLenum, GLuint, GLsizei, const GLubyte *)) +AGL_API(void, ProgramParameter4dNV, (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, ProgramParameter4dvNV, (GLenum, GLuint, const GLdouble *)) +AGL_API(void, ProgramParameter4fNV, (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramParameter4fvNV, (GLenum, GLuint, const GLfloat *)) +AGL_API(void, ProgramParameters4dvNV, (GLenum, GLuint, GLuint, const GLdouble *)) +AGL_API(void, ProgramParameters4fvNV, (GLenum, GLuint, GLuint, const GLfloat *)) +AGL_API(void, RequestResidentProgramsNV, (GLsizei, const GLuint *)) +AGL_API(void, TrackMatrixNV, (GLenum, GLuint, GLenum, GLenum)) +AGL_API(void, VertexAttribPointerNV, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, VertexAttrib1dNV, (GLuint, GLdouble)) +AGL_API(void, VertexAttrib1dvNV, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib1fNV, (GLuint, GLfloat)) +AGL_API(void, VertexAttrib1fvNV, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib1sNV, (GLuint, GLshort)) +AGL_API(void, VertexAttrib1svNV, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib2dNV, (GLuint, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib2dvNV, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib2fNV, (GLuint, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib2fvNV, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib2sNV, (GLuint, GLshort, GLshort)) +AGL_API(void, VertexAttrib2svNV, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib3dNV, (GLuint, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib3dvNV, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib3fNV, (GLuint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib3fvNV, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib3sNV, (GLuint, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib3svNV, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4dNV, (GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexAttrib4dvNV, (GLuint, const GLdouble *)) +AGL_API(void, VertexAttrib4fNV, (GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexAttrib4fvNV, (GLuint, const GLfloat *)) +AGL_API(void, VertexAttrib4sNV, (GLuint, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexAttrib4svNV, (GLuint, const GLshort *)) +AGL_API(void, VertexAttrib4ubNV, (GLuint, GLubyte, GLubyte, GLubyte, GLubyte)) +AGL_API(void, VertexAttrib4ubvNV, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttribs1dvNV, (GLuint, GLsizei, const GLdouble *)) +AGL_API(void, VertexAttribs1fvNV, (GLuint, GLsizei, const GLfloat *)) +AGL_API(void, VertexAttribs1svNV, (GLuint, GLsizei, const GLshort *)) +AGL_API(void, VertexAttribs2dvNV, (GLuint, GLsizei, const GLdouble *)) +AGL_API(void, VertexAttribs2fvNV, (GLuint, GLsizei, const GLfloat *)) +AGL_API(void, VertexAttribs2svNV, (GLuint, GLsizei, const GLshort *)) +AGL_API(void, VertexAttribs3dvNV, (GLuint, GLsizei, const GLdouble *)) +AGL_API(void, VertexAttribs3fvNV, (GLuint, GLsizei, const GLfloat *)) +AGL_API(void, VertexAttribs3svNV, (GLuint, GLsizei, const GLshort *)) +AGL_API(void, VertexAttribs4dvNV, (GLuint, GLsizei, const GLdouble *)) +AGL_API(void, VertexAttribs4fvNV, (GLuint, GLsizei, const GLfloat *)) +AGL_API(void, VertexAttribs4svNV, (GLuint, GLsizei, const GLshort *)) +AGL_API(void, VertexAttribs4ubvNV, (GLuint, GLsizei, const GLubyte *)) +#endif + +#if defined _ALLEGRO_GL_ATI_envmap_bumpmap +AGL_API(void, TexBumpParameterivATI, (GLenum, const GLint *)) +AGL_API(void, TexBumpParameterfvATI, (GLenum, const GLfloat *)) +AGL_API(void, GetTexBumpParameterivATI, (GLenum, GLint *)) +AGL_API(void, GetTexBumpParameterfvATI, (GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_ATI_fragment_shader +AGL_API(GLuint, GenFragmentShadersATI, (GLuint)) +AGL_API(void, BindFragmentShaderATI, (GLuint)) +AGL_API(void, DeleteFragmentShaderATI, (GLuint)) +AGL_API(void, BeginFragmentShaderATI, (void)) +AGL_API(void, EndFragmentShaderATI, (void)) +AGL_API(void, PassTexCoordATI, (GLuint, GLuint, GLenum)) +AGL_API(void, SampleMapATI, (GLuint, GLuint, GLenum)) +AGL_API(void, ColorFragmentOp1ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ColorFragmentOp2ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ColorFragmentOp3ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, AlphaFragmentOp1ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, AlphaFragmentOp2ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, AlphaFragmentOp3ATI, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, SetFragmentShaderConstantATI, (GLuint, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_ATI_pn_triangles +AGL_API(void, PNTrianglesiATI, (GLenum, GLint)) +AGL_API(void, PNTrianglesfATI, (GLenum, GLfloat)) +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_array_object +AGL_API(GLuint, NewObjectBufferATI, (GLsizei, const GLvoid *, GLenum)) +AGL_API(GLboolean, IsObjectBufferATI, (GLuint)) +AGL_API(void, UpdateObjectBufferATI, (GLuint, GLuint, GLsizei, const GLvoid *, GLenum)) +AGL_API(void, GetObjectBufferfvATI, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetObjectBufferivATI, (GLuint, GLenum, GLint *)) +AGL_API(void, FreeObjectBufferATI, (GLuint)) +AGL_API(void, ArrayObjectATI, (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint)) +AGL_API(void, GetArrayObjectfvATI, (GLenum, GLenum, GLfloat *)) +AGL_API(void, GetArrayObjectivATI, (GLenum, GLenum, GLint *)) +AGL_API(void, VariantArrayObjectATI, (GLuint, GLenum, GLsizei, GLuint, GLuint)) +AGL_API(void, GetVariantArrayObjectfvATI, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVariantArrayObjectivATI, (GLuint, GLenum, GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_vertex_shader +AGL_API(void, BeginVertexShaderEXT, (void)) +AGL_API(void, EndVertexShaderEXT, (void)) +AGL_API(void, BindVertexShaderEXT, (GLuint)) +AGL_API(GLuint, GenVertexShadersEXT, (GLuint)) +AGL_API(void, DeleteVertexShaderEXT, (GLuint)) +AGL_API(void, ShaderOp1EXT, (GLenum, GLuint, GLuint)) +AGL_API(void, ShaderOp2EXT, (GLenum, GLuint, GLuint, GLuint)) +AGL_API(void, ShaderOp3EXT, (GLenum, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, SwizzleEXT, (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, WriteMaskEXT, (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, InsertComponentEXT, (GLuint, GLuint, GLuint)) +AGL_API(void, ExtractComponentEXT, (GLuint, GLuint, GLuint)) +AGL_API(GLuint, GenSymbolsEXT, (GLenum, GLenum, GLenum, GLuint)) +AGL_API(void, SetInvariantEXT, (GLuint, GLenum, const GLvoid *)) +AGL_API(void, SetLocalConstantEXT, (GLuint, GLenum, const GLvoid *)) +AGL_API(void, VariantbvEXT, (GLuint, const GLbyte *)) +AGL_API(void, VariantsvEXT, (GLuint, const GLshort *)) +AGL_API(void, VariantivEXT, (GLuint, const GLint *)) +AGL_API(void, VariantfvEXT, (GLuint, const GLfloat *)) +AGL_API(void, VariantdvEXT, (GLuint, const GLdouble *)) +AGL_API(void, VariantubvEXT, (GLuint, const GLubyte *)) +AGL_API(void, VariantusvEXT, (GLuint, const GLushort *)) +AGL_API(void, VariantuivEXT, (GLuint, const GLuint *)) +AGL_API(void, VariantPointerEXT, (GLuint, GLenum, GLuint, const GLvoid *)) +AGL_API(void, EnableVariantClientStateEXT, (GLuint)) +AGL_API(void, DisableVariantClientStateEXT, (GLuint)) +AGL_API(GLuint, BindLightParameterEXT, (GLenum, GLenum)) +AGL_API(GLuint, BindMaterialParameterEXT, (GLenum, GLenum)) +AGL_API(GLuint, BindTexGenParameterEXT, (GLenum, GLenum, GLenum)) +AGL_API(GLuint, BindTextureUnitParameterEXT, (GLenum, GLenum)) +AGL_API(GLuint, BindParameterEXT, (GLenum)) +AGL_API(GLboolean, IsVariantEnabledEXT, (GLuint, GLenum)) +AGL_API(void, GetVariantBooleanvEXT, (GLuint, GLenum, GLboolean *)) +AGL_API(void, GetVariantIntegervEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVariantFloatvEXT, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVariantPointervEXT, (GLuint, GLenum, GLvoid* *)) +AGL_API(void, GetInvariantBooleanvEXT, (GLuint, GLenum, GLboolean *)) +AGL_API(void, GetInvariantIntegervEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetInvariantFloatvEXT, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetLocalConstantBooleanvEXT, (GLuint, GLenum, GLboolean *)) +AGL_API(void, GetLocalConstantIntegervEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetLocalConstantFloatvEXT, (GLuint, GLenum, GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_streams +AGL_API(void, VertexStream1sATI, (GLenum, GLshort)) +AGL_API(void, VertexStream1svATI, (GLenum, const GLshort *)) +AGL_API(void, VertexStream1iATI, (GLenum, GLint)) +AGL_API(void, VertexStream1ivATI, (GLenum, const GLint *)) +AGL_API(void, VertexStream1fATI, (GLenum, GLfloat)) +AGL_API(void, VertexStream1fvATI, (GLenum, const GLfloat *)) +AGL_API(void, VertexStream1dATI, (GLenum, GLdouble)) +AGL_API(void, VertexStream1dvATI, (GLenum, const GLdouble *)) +AGL_API(void, VertexStream2sATI, (GLenum, GLshort, GLshort)) +AGL_API(void, VertexStream2svATI, (GLenum, const GLshort *)) +AGL_API(void, VertexStream2iATI, (GLenum, GLint, GLint)) +AGL_API(void, VertexStream2ivATI, (GLenum, const GLint *)) +AGL_API(void, VertexStream2fATI, (GLenum, GLfloat, GLfloat)) +AGL_API(void, VertexStream2fvATI, (GLenum, const GLfloat *)) +AGL_API(void, VertexStream2dATI, (GLenum, GLdouble, GLdouble)) +AGL_API(void, VertexStream2dvATI, (GLenum, const GLdouble *)) +AGL_API(void, VertexStream3sATI, (GLenum, GLshort, GLshort, GLshort)) +AGL_API(void, VertexStream3svATI, (GLenum, const GLshort *)) +AGL_API(void, VertexStream3iATI, (GLenum, GLint, GLint, GLint)) +AGL_API(void, VertexStream3ivATI, (GLenum, const GLint *)) +AGL_API(void, VertexStream3fATI, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexStream3fvATI, (GLenum, const GLfloat *)) +AGL_API(void, VertexStream3dATI, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexStream3dvATI, (GLenum, const GLdouble *)) +AGL_API(void, VertexStream4sATI, (GLenum, GLshort, GLshort, GLshort, GLshort)) +AGL_API(void, VertexStream4svATI, (GLenum, const GLshort *)) +AGL_API(void, VertexStream4iATI, (GLenum, GLint, GLint, GLint, GLint)) +AGL_API(void, VertexStream4ivATI, (GLenum, const GLint *)) +AGL_API(void, VertexStream4fATI, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, VertexStream4fvATI, (GLenum, const GLfloat *)) +AGL_API(void, VertexStream4dATI, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, VertexStream4dvATI, (GLenum, const GLdouble *)) +AGL_API(void, NormalStream3bATI, (GLenum, GLbyte, GLbyte, GLbyte)) +AGL_API(void, NormalStream3bvATI, (GLenum, const GLbyte *)) +AGL_API(void, NormalStream3sATI, (GLenum, GLshort, GLshort, GLshort)) +AGL_API(void, NormalStream3svATI, (GLenum, const GLshort *)) +AGL_API(void, NormalStream3iATI, (GLenum, GLint, GLint, GLint)) +AGL_API(void, NormalStream3ivATI, (GLenum, const GLint *)) +AGL_API(void, NormalStream3fATI, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, NormalStream3fvATI, (GLenum, const GLfloat *)) +AGL_API(void, NormalStream3dATI, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, NormalStream3dvATI, (GLenum, const GLdouble *)) +AGL_API(void, ClientActiveVertexStreamATI, (GLenum)) +AGL_API(void, VertexBlendEnviATI, (GLenum, GLint)) +AGL_API(void, VertexBlendEnvfATI, (GLenum, GLfloat)) +#endif + +#if defined _ALLEGRO_GL_ATI_element_array +AGL_API(void, ElementPointerATI, (GLenum, const GLvoid *)) +AGL_API(void, DrawElementArrayATI, (GLenum, GLsizei)) +AGL_API(void, DrawRangeElementArrayATI, (GLenum, GLuint, GLuint, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_SUN_mesh_array +AGL_API(void, DrawMeshArraysSUN, (GLenum, GLint, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_NV_occlusion_query +AGL_API(void, GenOcclusionQueriesNV, (GLsizei, GLuint *)) +AGL_API(void, DeleteOcclusionQueriesNV, (GLsizei, const GLuint *)) +AGL_API(GLboolean, IsOcclusionQueryNV, (GLuint)) +AGL_API(void, BeginOcclusionQueryNV, (GLuint)) +AGL_API(void, EndOcclusionQueryNV, (void)) +AGL_API(void, GetOcclusionQueryivNV, (GLuint, GLenum, GLint *)) +AGL_API(void, GetOcclusionQueryuivNV, (GLuint, GLenum, GLuint *)) +#endif + +#if defined _ALLEGRO_GL_NV_point_sprite +AGL_API(void, PointParameteriNV, (GLenum, GLint)) +AGL_API(void, PointParameterivNV, (GLenum, const GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_stencil_two_side +AGL_API(void, ActiveStencilFaceEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_APPLE_element_array +AGL_API(void, ElementPointerAPPLE, (GLenum, const GLvoid *)) +AGL_API(void, DrawElementArrayAPPLE, (GLenum, GLint, GLsizei)) +AGL_API(void, DrawRangeElementArrayAPPLE, (GLenum, GLuint, GLuint, GLint, GLsizei)) +AGL_API(void, MultiDrawElementArrayAPPLE, (GLenum, const GLint *, const GLsizei *, GLsizei)) +AGL_API(void, MultiDrawRangeElementArrayAPPLE, (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_APPLE_fence +AGL_API(void, GenFencesAPPLE, (GLsizei, GLuint *)) +AGL_API(void, DeleteFencesAPPLE, (GLsizei, const GLuint *)) +AGL_API(void, SetFenceAPPLE, (GLuint)) +AGL_API(GLboolean, IsFenceAPPLE, (GLuint)) +AGL_API(GLboolean, TestFenceAPPLE, (GLuint)) +AGL_API(void, FinishFenceAPPLE, (GLuint)) +AGL_API(GLboolean, TestObjectAPPLE, (GLenum, GLuint)) +AGL_API(void, FinishObjectAPPLE, (GLenum, GLint)) +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_array_object +AGL_API(void, BindVertexArrayAPPLE, (GLuint)) +AGL_API(void, DeleteVertexArraysAPPLE, (GLsizei, const GLuint *)) +AGL_API(void, GenVertexArraysAPPLE, (GLsizei, const GLuint *)) +AGL_API(GLboolean, IsVertexArrayAPPLE, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_array_range +AGL_API(void, VertexArrayRangeAPPLE, (GLsizei, GLvoid *)) +AGL_API(void, FlushVertexArrayRangeAPPLE, (GLsizei, GLvoid *)) +AGL_API(void, VertexArrayParameteriAPPLE, (GLenum, GLint)) +#endif + +#if defined _ALLEGRO_GL_ATI_draw_buffers +AGL_API(void, DrawBuffersATI, (GLsizei, const GLenum *)) +#endif + +#if defined _ALLEGRO_GL_NV_fragment_program +AGL_API(void, ProgramNamedParameter4fNV, (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramNamedParameter4dNV, (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, ProgramNamedParameter4fvNV, (GLuint, GLsizei, const GLubyte *, const GLfloat *)) +AGL_API(void, ProgramNamedParameter4dvNV, (GLuint, GLsizei, const GLubyte *, const GLdouble *)) +AGL_API(void, GetProgramNamedParameterfvNV, (GLuint, GLsizei, const GLubyte *, GLfloat *)) +AGL_API(void, GetProgramNamedParameterdvNV, (GLuint, GLsizei, const GLubyte *, GLdouble *)) +#endif + +#if defined _ALLEGRO_GL_NV_half_float +AGL_API(void, Vertex2hNV, (GLhalfNV, GLhalfNV)) +AGL_API(void, Vertex2hvNV, (const GLhalfNV *)) +AGL_API(void, Vertex3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Vertex3hvNV, (const GLhalfNV *)) +AGL_API(void, Vertex4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Vertex4hvNV, (const GLhalfNV *)) +AGL_API(void, Normal3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Normal3hvNV, (const GLhalfNV *)) +AGL_API(void, Color3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Color3hvNV, (const GLhalfNV *)) +AGL_API(void, Color4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, Color4hvNV, (const GLhalfNV *)) +AGL_API(void, TexCoord1hNV, (GLhalfNV)) +AGL_API(void, TexCoord1hvNV, (const GLhalfNV *)) +AGL_API(void, TexCoord2hNV, (GLhalfNV, GLhalfNV)) +AGL_API(void, TexCoord2hvNV, (const GLhalfNV *)) +AGL_API(void, TexCoord3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, TexCoord3hvNV, (const GLhalfNV *)) +AGL_API(void, TexCoord4hNV, (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, TexCoord4hvNV, (const GLhalfNV *)) +AGL_API(void, MultiTexCoord1hNV, (GLenum, GLhalfNV)) +AGL_API(void, MultiTexCoord1hvNV, (GLenum, const GLhalfNV *)) +AGL_API(void, MultiTexCoord2hNV, (GLenum, GLhalfNV, GLhalfNV)) +AGL_API(void, MultiTexCoord2hvNV, (GLenum, const GLhalfNV *)) +AGL_API(void, MultiTexCoord3hNV, (GLenum, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, MultiTexCoord3hvNV, (GLenum, const GLhalfNV *)) +AGL_API(void, MultiTexCoord4hNV, (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, MultiTexCoord4hvNV, (GLenum, const GLhalfNV *)) +AGL_API(void, FogCoordhNV, (GLhalfNV)) +AGL_API(void, FogCoordhvNV, (const GLhalfNV *)) +AGL_API(void, SecondaryColor3hNV, (GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, SecondaryColor3hvNV, (const GLhalfNV *)) +AGL_API(void, VertexWeighthNV, (GLhalfNV)) +AGL_API(void, VertexWeighthvNV, (const GLhalfNV *)) +AGL_API(void, VertexAttrib1hNV, (GLuint, GLhalfNV)) +AGL_API(void, VertexAttrib1hvNV, (GLuint, const GLhalfNV *)) +AGL_API(void, VertexAttrib2hNV, (GLuint, GLhalfNV, GLhalfNV)) +AGL_API(void, VertexAttrib2hvNV, (GLuint, const GLhalfNV *)) +AGL_API(void, VertexAttrib3hNV, (GLuint, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, VertexAttrib3hvNV, (GLuint, const GLhalfNV *)) +AGL_API(void, VertexAttrib4hNV, (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV)) +AGL_API(void, VertexAttrib4hvNV, (GLuint, const GLhalfNV *)) +AGL_API(void, VertexAttribs1hvNV, (GLuint, GLsizei, const GLhalfNV *)) +AGL_API(void, VertexAttribs2hvNV, (GLuint, GLsizei, const GLhalfNV *)) +AGL_API(void, VertexAttribs3hvNV, (GLuint, GLsizei, const GLhalfNV *)) +AGL_API(void, VertexAttribs4hvNV, (GLuint, GLsizei, const GLhalfNV *)) +#endif + +#if defined _ALLEGRO_GL_NV_pixel_data_range +AGL_API(void, PixelDataRangeNV, (GLenum, GLsizei, GLvoid *)) +AGL_API(void, FlushPixelDataRangeNV, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_NV_primitive_restart +AGL_API(void, PrimitiveRestartNV, (void)) +AGL_API(void, PrimitiveRestartIndexNV, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_ATI_map_object_buffer +AGL_API(GLvoid*, MapObjectBufferATI, (GLuint)) +AGL_API(void, UnmapObjectBufferATI, (GLuint)) +#endif + +#if defined _ALLEGRO_GL_ATI_separate_stencil +AGL_API(void, StencilOpSeparateATI, (GLenum, GLenum, GLenum, GLenum)) +AGL_API(void, StencilFuncSeparateATI, (GLenum, GLenum, GLint, GLuint)) +#endif + +#if defined _ALLEGRO_GL_ATI_vertex_attrib_array_object +AGL_API(void, VertexAttribArrayObjectATI, (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint)) +AGL_API(void, GetVertexAttribArrayObjectfvATI, (GLuint, GLenum, GLfloat *)) +AGL_API(void, GetVertexAttribArrayObjectivATI, (GLuint, GLenum, GLint *)) +#endif + +#if defined _ALLEGRO_GL_OES_byte_coordinates +AGL_API(void, Vertex2bOES, ( GLbyte, GLbyte )) +AGL_API(void, Vertex3bOES, ( GLbyte, GLbyte, GLbyte )) +AGL_API(void, Vertex4bOES, ( GLbyte, GLbyte, GLbyte, GLbyte )) +AGL_API(void, Vertex2bvOES, ( const GLbyte * )) +AGL_API(void, Vertex3bvOES, ( const GLbyte * )) +AGL_API(void, Vertex4bvOES, ( const GLbyte * )) +AGL_API(void, TexCoord1bOES, ( GLbyte )) +AGL_API(void, TexCoord2bOES, ( GLbyte, GLbyte )) +AGL_API(void, TexCoord3bOES, ( GLbyte, GLbyte, GLbyte )) +AGL_API(void, TexCoord4bOES, ( GLbyte, GLbyte, GLbyte, GLbyte )) +AGL_API(void, TexCoord1bvOES, ( const GLbyte * )) +AGL_API(void, TexCoord2bvOES, ( const GLbyte * )) +AGL_API(void, TexCoord3bvOES, ( const GLbyte * )) +AGL_API(void, TexCoord4bvOES, ( const GLbyte * )) +AGL_API(void, MultiTexCoord1bOES, ( GLenum, GLbyte )) +AGL_API(void, MultiTexCoord2bOES, ( GLenum, GLbyte, GLbyte )) +AGL_API(void, MultiTexCoord3bOES, ( GLenum, GLbyte, GLbyte, GLbyte )) +AGL_API(void, MultiTexCoord4bOES, ( GLenum, GLbyte, GLbyte, GLbyte, GLbyte )) +AGL_API(void, MultiTexCoord1bvOES, ( GLenum texture, const GLbyte * )) +AGL_API(void, MultiTexCoord2bvOES, ( GLenum texture, const GLbyte * )) +AGL_API(void, MultiTexCoord3bvOES, ( GLenum texture, const GLbyte * )) +AGL_API(void, MultiTexCoord4bvOES, ( GLenum texture, const GLbyte * )) +#endif + +#if defined _ALLEGRO_GL_OES_fixed_point +AGL_API(void, Vertex2xOES, (GLfixed, GLfixed)) +AGL_API(void, Vertex3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, Vertex4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, Vertex2xvOES, (const GLfixed *)) +AGL_API(void, Vertex3xvOES, (const GLfixed *)) +AGL_API(void, Vertex4xvOES, (const GLfixed *)) +AGL_API(void, Normal3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, Normal3xvOES, (const GLfixed *)) +AGL_API(void, TexCoord1xOES, (GLfixed)) +AGL_API(void, TexCoord2xOES, (GLfixed, GLfixed)) +AGL_API(void, TexCoord3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, TexCoord4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, TexCoord1xvOES, (const GLfixed *)) +AGL_API(void, TexCoord2xvOES, (const GLfixed *)) +AGL_API(void, TexCoord3xvOES, (const GLfixed *)) +AGL_API(void, TexCoord4xvOES, (const GLfixed *)) +AGL_API(void, MultiTexCoord1xOES, (GLenum, GLfixed)) +AGL_API(void, MultiTexCoord2xOES, (GLenum, GLfixed, GLfixed)) +AGL_API(void, MultiTexCoord3xOES, (GLenum, GLfixed, GLfixed, GLfixed)) +AGL_API(void, MultiTexCoord4xOES, (GLenum, GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, MultiTexCoord1xvOES, (GLenum, const GLfixed *)) +AGL_API(void, MultiTexCoord2xvOES, (GLenum, const GLfixed *)) +AGL_API(void, MultiTexCoord3xvOES, (GLenum, const GLfixed *)) +AGL_API(void, MultiTexCoord4xvOES, (GLenum, const GLfixed *)) +AGL_API(void, Color3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, Color4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, Color3xvOES, (const GLfixed *)) +AGL_API(void, Color4xvOES, (const GLfixed *)) +AGL_API(void, IndexxOES, (GLfixed)) +AGL_API(void, IndexxvOES, (const GLfixed *)) +AGL_API(void, RectxOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, RectxvOES, (const GLfixed [2], const GLfixed [2])) +AGL_API(void, DepthRangexOES, (GLclampx, GLclampx)) +AGL_API(void, LoadMatrixxOES, (const GLfixed [16])) +AGL_API(void, MultMatrixxOES, (const GLfixed [16])) +AGL_API(void, LoadTransposeMatrixxOES, (const GLfixed [16])) +AGL_API(void, MultTransposeMatrixxOES, (const GLfixed [16])) +AGL_API(void, RotatexOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, ScalexOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, TranslatexOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, FrustumxOES, (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, OrthoxOES, (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, TexGenxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, TexGenxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetTexGenxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, ClipPlanexOES, (GLenum, const GLfixed *)) +AGL_API(void, GetClipPlanexOES, (GLenum, GLfixed *)) +AGL_API(void, RasterPos2xOES, (GLfixed, GLfixed)) +AGL_API(void, RasterPos3xOES, (GLfixed, GLfixed, GLfixed)) +AGL_API(void, RasterPos4xOES, (GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, RasterPos2xvOES, (const GLfixed *)) +AGL_API(void, RasterPos3xvOES, (const GLfixed *)) +AGL_API(void, RasterPos4xvOES, (const GLfixed *)) +AGL_API(void, MaterialxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, MaterialxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetMaterialxOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, LightxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, LightxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetLightxOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, LightModelxOES, (GLenum, GLfixed)) +AGL_API(void, LightModelxvOES, (GLenum, const GLfixed *)) +AGL_API(void, PointSizexOES, (GLfixed size)) +AGL_API(void, LineWidthxOES, (GLfixed width)) +AGL_API(void, PolygonOffsetxOES, (GLfixed factor, GLfixed units)) +AGL_API(void, PixelStorex, (GLenum pname, GLfixed param)) +AGL_API(void, PixelTransferxOES, (GLenum pname, GLfixed param)) +AGL_API(void, PixelMapx, (GLenum, GLint, const GLfixed *)) +AGL_API(void, GetPixelMapxv, (GLenum, GLint, GLfixed *)) +AGL_API(void, ConvolutionParameterxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, ConvolutionParameterxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetConvolutionParameterxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, GetHistogramParameterxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, PixelZoomxOES, (GLfixed, GLfixed)) +AGL_API(void, BitmapxOES, (GLsizei, GLsizei, GLfixed, GLfixed, GLfixed, GLfixed, const GLubyte *)) +AGL_API(void, TexParameterxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, TexParameterxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetTexParameterxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, GetTexLevelParameterxvOES, (GLenum, GLint, GLenum, GLfixed *)) +AGL_API(void, PrioritizeTexturesxOES, (GLsizei, GLuint *, GLclampx *)) +AGL_API(void, TexEnvxOES, (GLenum, GLenum, GLfixed)) +AGL_API(void, TexEnvxvOES, (GLenum, GLenum, const GLfixed *)) +AGL_API(void, GetTexEnvxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, FogxOES, (GLenum, GLfixed)) +AGL_API(void, FogxvOES, (GLenum, const GLfixed *)) +AGL_API(void, SampleCoverageOES, (GLclampx, GLboolean)) +AGL_API(void, AlphaFuncxOES, (GLenum, GLclampx)) +AGL_API(void, BlendColorxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) +AGL_API(void, ClearColorxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) +AGL_API(void, ClearDepthxOES, (GLclampx)) +AGL_API(void, ClearAccumxOES, (GLclampx, GLclampx, GLclampx, GLclampx)) +AGL_API(void, AccumxOES, (GLenum, GLfixed)) +AGL_API(void, Map1xOES, (GLenum, GLfixed, GLfixed, GLint, GLint, const GLfixed *)) +AGL_API(void, Map2xOES, (GLenum, GLfixed, GLfixed, GLint, GLint, GLfixed, GLfixed, GLint, GLint, const GLfixed *)) +AGL_API(void, MapGrid1xOES, (GLint, GLfixed, GLfixed)) +AGL_API(void, MapGrid2xOES, (GLint, GLfixed, GLfixed, GLfixed, GLfixed)) +AGL_API(void, GetMapxvOES, (GLenum, GLenum, GLfixed *)) +AGL_API(void, EvalCoord1xOES, (GLfixed)) +AGL_API(void, EvalCoord2xOES, (GLfixed, GLfixed)) +AGL_API(void, EvalCoord1xvOES, (const GLfixed *)) +AGL_API(void, EvalCoord2xvOES, (const GLfixed *)) +AGL_API(void, FeedbackBufferxOES, (GLsizei, GLenum, GLfixed *)) +AGL_API(void, PassThroughxOES, (GLfixed)) +AGL_API(void, GetFixedvOES, (GLenum, GLfixed *)) +#endif + +#if defined _ALLEGRO_GL_OES_single_precision +AGL_API(void, DepthRangefOES, (GLclampf, GLclampf)) +AGL_API(void, FrustumfOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, OrthofOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ClipPlanefOES, (GLenum, const GLfloat*)) +AGL_API(void, GetClipPlanefOES, (GLenum, GLfloat*)) +AGL_API(void, ClearDepthfOES, (GLclampd)) +#endif + +#if defined _ALLEGRO_GL_OES_query_matrix +AGL_API(GLbitfield, QueryMatrixxOES, (GLfixed [16], GLint [16] )) +#endif + +#if defined _ALLEGRO_GL_EXT_depth_bounds_test +AGL_API(void, DepthBoundsEXT, (GLclampd, GLclampd)) +#endif + + +#if defined _ALLEGRO_GL_EXT_blend_equation_separate +AGL_API(void, BlendEquationSeparateEXT, (GLenum, GLenum)) +#endif + + +#if defined _ALLEGRO_GL_EXT_framebuffer_object +AGL_API(GLboolean, IsRenderbufferEXT, (GLuint)) +AGL_API(void, BindRenderbufferEXT, (GLenum, GLuint)) +AGL_API(void, DeleteRenderbuffersEXT, (GLsizei, const GLuint *)) +AGL_API(void, GenRenderbuffersEXT, (GLsizei, GLuint *)) +AGL_API(void, RenderbufferStorageEXT, (GLenum, GLenum, GLsizei, GLsizei)) +AGL_API(void, GetRenderbufferParameterivEXT, (GLenum, GLenum, GLint*)) +AGL_API(GLboolean, IsFramebufferEXT, (GLuint)) +AGL_API(void, BindFramebufferEXT, (GLenum, GLuint)) +AGL_API(void, DeleteFramebuffersEXT, (GLsizei, const GLuint *)) +AGL_API(void, GenFramebuffersEXT, (GLsizei, GLuint *)) +AGL_API(GLenum, CheckFramebufferStatusEXT, (GLenum)) +AGL_API(void, FramebufferTexture1DEXT, (GLenum, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTexture2DEXT, (GLenum, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, FramebufferTexture3DEXT, (GLenum, GLenum, GLenum, GLuint, GLint, GLint)) +AGL_API(void, FramebufferRenderbufferEXT, (GLenum, GLenum, GLenum, GLuint)) +AGL_API(void, GetFramebufferAttachmentParameterivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GenerateMipmapEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_GREMEDY_string_marker +AGL_API(void, StringMarkerGREMEDY, (GLsizei, const GLvoid *)) +#endif + +#if defined _ALLEGRO_GL_EXT_stencil_clear_tag +AGL_API(void, StencilClearTagEXT, (GLsizei, GLuint)) +#endif + +#if defined _ALLEGRO_GL_EXT_framebuffer_blit +AGL_API(void, BlitFramebufferEXT, (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_framebuffer_multisample +AGL_API(void, RenderbufferStorageMultisampleEXT, (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_EXT_timer_query +AGL_API(void, GetQueryObjecti64vEXT, (GLuint, GLenum, GLint64EXT *)) +AGL_API(void, GetQueryObjectui64vEXT, (GLuint, GLenum, GLuint64EXT *)) +#endif + +#if defined _ALLEGRO_GL_EXT_gpu_program_parameters +AGL_API(void, ProgramEnvParameters4fvEXT, (GLenum, GLuint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramLocalParameters4fvEXT, (GLenum, GLuint, GLsizei, const GLfloat *)) +#endif + +#if defined _ALLEGRO_GL_APPLE_flush_buffer_range +AGL_API(void, BufferParameteriAPPLE, (GLenum, GLenum, GLint)) +AGL_API(void, FlushMappedBufferRangeAPPLE, (GLenum, GLintptr, GLsizeiptr)) +#endif + +#if defined _ALLEGRO_GL_EXT_bindable_uniform +AGL_API(void, UniformBufferEXT, (GLuint, GLint, GLuint)) +AGL_API(GLint, GetUniformBufferSizeEXT, (GLuint, GLint)) +AGL_API(GLintptr, GetUniformOffsetEXT, (GLuint program, GLint)) +#endif + +#if defined _ALLEGRO_GL_EXT_draw_buffers2 +AGL_API(void, ColorMaskIndexedEXT, (GLuint, GLboolean, GLboolean, GLboolean, GLboolean)) +AGL_API(void, GetBooleanIndexedvEXT, (GLenum, GLuint, GLboolean *)) +AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLint *)) +AGL_API(void, EnableIndexedEXT, (GLenum, GLuint)) +AGL_API(void, DisableIndexedEXT, (GLenum, GLuint)) +AGL_API(GLboolean, IsEnabledIndexedEXT, (GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_EXT_draw_instanced +AGL_API(void, DrawArraysInstancedEXT, (GLenum, GLint, GLsizei, GLsizei)) +AGL_API(void, DrawElementsInstancedEXT, (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_EXT_geometry_shader4 +AGL_API(void, ProgramParameteriEXT, (GLuint, GLenum, GLint)) +AGL_API(void, FramebufferTextureEXT, (GLenum, GLenum, GLuint, GLint)) +#if !defined _ALLEGRO_GL_EXT_texture_array +AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) +#endif +AGL_API(void, FramebufferTextureFaceEXT, (GLenum, GLenum, GLuint, GLint, GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_gpu_shader4 +AGL_API(void, VertexAttribI1iEXT, (GLuint, GLint)) +AGL_API(void, VertexAttribI2iEXT, (GLuint, GLint, GLint)) +AGL_API(void, VertexAttribI3iEXT, (GLuint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI4iEXT, (GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI1uiEXT, (GLuint, GLuint)) +AGL_API(void, VertexAttribI2uiEXT, (GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI3uiEXT, (GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI4uiEXT, (GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI1ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI2ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI3ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI4ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI1uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI2uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI3uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4bvEXT, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttribI4svEXT, (GLuint, const GLshort *)) +AGL_API(void, VertexAttribI4ubvEXT, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttribI4usvEXT, (GLuint, const GLushort *)) +AGL_API(void, VertexAttribIPointerEXT, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetVertexAttribIivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribIuivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, Uniform1uiEXT, (GLint, GLuint)) +AGL_API(void, Uniform2uiEXT, (GLint, GLuint, GLuint)) +AGL_API(void, Uniform3uiEXT, (GLint, GLuint, GLuint, GLuint)) +AGL_API(void, Uniform4uiEXT, (GLint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, Uniform1uivEXT, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform2uivEXT, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform3uivEXT, (GLint, GLsizei, const GLuint *)) +AGL_API(void, Uniform4uivEXT, (GLint, GLsizei, const GLuint *)) +AGL_API(void, GetUniformuivEXT, (GLuint, GLint location, GLint *)) +AGL_API(void, BindFragDataLocationEXT, (GLuint, GLuint, const GLchar *)) +AGL_API(GLint, GetFragDataLocationEXT, (GLuint, const GLchar *)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture_array +AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) +#endif + +#if defined _ALLEGRO_GL_EXT_texture_buffer_object +AGL_API(void, TexBufferEXT, (GLenum, GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_texture_integer +AGL_API(void, ClearColorIiEXT, (GLint, GLint, GLint, GLint)) +AGL_API(void, ClearColorIuiEXT, (GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, TexParameterIivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, TexParameterIuivEXT, (GLenum, GLenum, GLuint *)) +AGL_API(void, GetTexParameterIivEXT, (GLenum, GLenum, GLint *)) +AGL_API(void, GetTexParameterIiuvEXT, (GLenum, GLenum, GLuint *)) +#endif + +#if defined _ALLEGRO_GL_NV_depth_buffer_float +AGL_API(void, DepthRangedNV, (GLdouble, GLdouble)) +AGL_API(void, ClearDepthdNV, (GLdouble)) +AGL_API(void, DepthBoundsdNV, (GLdouble, GLdouble)) +#endif + +#if defined _ALLEGRO_GL_NV_framebuffer_multisample_coverage +AGL_API(void, RenderbufferStorageMultsampleCoverageNV, (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei)) +#endif + +#if defined _ALLEGRO_GL_NV_geometry_program4 +AGL_API(void, ProgramVertexLimitNV, (GLenum, GLint)) +#if !defined _ALLEGRO_GL_EXT_geometry_shader4 +AGL_API(void, FramebufferTextureEXT, (GLenum, GLenum, GLuint, GLint)) +#if !defined _ALLEGRO_GL_EXT_texture_array +AGL_API(void, FramebufferTextureLayerEXT, (GLenum, GLenum, GLuint, GLint, GLint)) +#endif +#endif +#endif + +#if defined _ALLEGRO_GL_NV_gpu_program4 +AGL_API(void, ProgramLocalParameterI4iNV, (GLenum, GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, ProgramLocalParameterI4ivNV, (GLenum, GLuint, const GLint *)) +AGL_API(void, ProgramLocalParametersI4ivNV, (GLenum, GLuint, GLsizei, const GLint *)) +AGL_API(void, ProgramLocalParameterI4uiNV, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ProgramLocalParameterI4uivNV, (GLenum, GLuint, const GLuint *)) +AGL_API(void, ProgramLocalParametersI4uivNV, (GLenum, GLuint, GLsizei, const GLuint *)) +AGL_API(void, ProgramEnvParameterI4iNV, (GLenum, GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, ProgramEnvParameterI4ivNV, (GLenum, GLuint, const GLint *)) +AGL_API(void, ProgramEnvParametersI4ivNV, (GLenum, GLuint, GLsizei, const GLint *)) +AGL_API(void, ProgramEnvParameterI4uiNV, (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ProgramEnvParameterI4uivNV, (GLenum, GLuint, const GLuint *)) +AGL_API(void, ProgramEnvParametersI4uivNV, (GLenum, GLuint, GLsizei, const GLuint *)) +AGL_API(void, GetProgramLocalParameterIivNV, (GLenum, GLuint, GLint *)) +AGL_API(void, GetProgramLocalParameterIuivNV,(GLenum, GLuint, GLuint *)) +AGL_API(void, GetProgramEnvParameterIivNV, (GLenum, GLuint, GLint *)) +AGL_API(void, GetProgramEnvParameterIuivNV, (GLenum, GLuint, GLuint *)) +#endif + +#if defined _ALLEGRO_GL_NV_parameter_buffer_object +#if !defined _ALLEGRO_GL_NV_transform_feedback +AGL_API(void, BindBufferRangeNV, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) +AGL_API(void, BindBufferOffsetNV,(GLenum, GLuint, GLuint, GLintptr)) +AGL_API(void, BindBufferBaseNV, (GLenum, GLuint, GLuint)) +#endif +AGL_API(void, ProgramBufferParametersfvNV, (GLenum, GLuint, GLuint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramBufferParametersIivNV, (GLenum, GLuint, GLuint, GLsizei, const GLint *)) +AGL_API(void, ProgramBufferParametersIuivNV,(GLenum, GLuint, GLuint, GLuint, const GLuint *)) +#if !defined _ALLEGRO_GL_EXT_draw_buffers2 +AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLboolean *)) +#endif +#endif + +#if defined _ALLEGRO_GL_NV_transform_feedback +AGL_API(void, BindBufferRangeNV, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) +AGL_API(void, BindBufferOffsetNV,(GLenum, GLuint, GLuint, GLintptr)) +AGL_API(void, BindBufferBaseNV, (GLenum, GLuint, GLuint)) +AGL_API(void, TransformFeedbackAttribsNV, (GLsizei, const GLint *, GLenum)) +AGL_API(void, TransformFeedbackVaryingsNV,(GLuint, GLsizei, const GLint *, GLenum)) +AGL_API(void, BeginTransformFeedbackNV, (GLenum)) +AGL_API(void, EndTransformFeedbackNV, (void)) +AGL_API(GLint, GetVaryingLocationNV, (GLuint, const GLchar *)) +AGL_API(void, GetActiveVaryingNV, (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *)) +AGL_API(void, ActiveVaryingNV, (GLuint, const GLchar *)) +AGL_API(void, GetTransformFeedbackVaryingNV, (GLuint, GLuint, GLint *)) +#if !defined _ALLEGRO_GL_EXT_draw_buffers2 +AGL_API(void, GetBooleanIndexedvEXT, (GLenum, GLuint, GLboolean *)) +/*AGL_API(void, GetIntegerIndexedvEXT, (GLenum, GLuint, GLint *))*/ +#endif +#endif + +#if defined _ALLEGRO_GL_NV_vertex_program4 +#ifndef _ALLEGRO_GL_EXT_gpu_shader4 +AGL_API(void, VertexAttribI1iEXT, (GLuint, GLint)) +AGL_API(void, VertexAttribI2iEXT, (GLuint, GLint, GLint)) +AGL_API(void, VertexAttribI3iEXT, (GLuint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI4iEXT, (GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, VertexAttribI1uiEXT, (GLuint, GLuint)) +AGL_API(void, VertexAttribI2uiEXT, (GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI3uiEXT, (GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI4uiEXT, (GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, VertexAttribI1ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI2ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI3ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI4ivEXT, (GLuint, const GLint *)) +AGL_API(void, VertexAttribI1uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI2uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI3uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4uivEXT, (GLuint, const GLuint *)) +AGL_API(void, VertexAttribI4bvEXT, (GLuint, const GLbyte *)) +AGL_API(void, VertexAttribI4svEXT, (GLuint, const GLshort *)) +AGL_API(void, VertexAttribI4ubvEXT, (GLuint, const GLubyte *)) +AGL_API(void, VertexAttribI4usvEXT, (GLuint, const GLushort *)) +AGL_API(void, VertexAttribIPointerEXT, (GLuint, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetVertexAttribIivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetVertexAttribIuivEXT, (GLuint, GLenum, GLint *)) +#endif +#endif + +#if defined _ALLEGRO_GL_GREMEDY_frame_terminator +AGL_API(void, FrameTerminatorGREMEDY, (void)) +#endif + +#if defined _ALLEGRO_GL_NV_conditional_render +AGL_API(void, BeginConditionalRenderNV, (GLuint, GLenum)) +AGL_API(void, EndConditionalRenderNV, (void)) +#endif + +#if defined _ALLEGRO_GL_EXT_transform_feedback +AGL_API(void, BeginTransformFeedbackEXT, (GLenum)) +AGL_API(void, EndTransformFeedbackEXT, (void)) +AGL_API(void, BindBufferRangeEXT, (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr)) +AGL_API(void, BindBufferOffsetEXT, (GLenum, GLuint, GLuint, GLintptr)) +AGL_API(void, BindBufferBaseEXT, (GLenum, GLuint, GLuint)) +AGL_API(void, TransformFeedbackVaryingsEXT, (GLuint, GLsizei, const GLint *, GLenum)) +AGL_API(void, GetTransformFeedbackVaryingEXT, (GLuint, GLuint, GLint *)) +#endif + +#if defined _ALLEGRO_GL_EXT_direct_state_access +AGL_API(void, ClientAttribDefaultEXT, (GLbitfield)) +AGL_API(void, PushClientAttribDefaultEXT, (GLbitfield)) +AGL_API(void, MatrixLoadfEXT, (GLenum, const GLfloat *)) +AGL_API(void, MatrixLoaddEXT, (GLenum, const GLdouble *)) +AGL_API(void, MatrixMultfEXT, (GLenum, const GLfloat *)) +AGL_API(void, MatrixMultdEXT, (GLenum, const GLdouble *)) +AGL_API(void, MatrixLoadIdentityEXT, (GLenum)) +AGL_API(void, MatrixRotatefEXT, (GLenum, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MatrixRotatedEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixScalefEXT, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MatrixScaledEXT, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixTranslatefEXT, (GLenum, GLfloat, GLfloat, GLfloat)) +AGL_API(void, MatrixTranslatedEXT, (GLenum, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixFrustumEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixOrthoEXT, (GLenum, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, MatrixPopEXT, (GLenum)) +AGL_API(void, MatrixPushEXT, (GLenum)) +AGL_API(void, MatrixLoadTransposefEXT, (GLenum, const GLfloat *)) +AGL_API(void, MatrixLoadTransposedEXT, (GLenum, const GLdouble *)) +AGL_API(void, MatrixMultTransposefEXT, (GLenum, const GLfloat *)) +AGL_API(void, MatrixMultTransposedEXT, (GLenum, const GLdouble *)) +AGL_API(void, TextureParameterfEXT, (GLuint, GLenum, GLenum, GLfloat)) +AGL_API(void, TextureParameterfvEXT, (GLuint, GLenum, GLenum, const GLfloat *)) +AGL_API(void, TextureParameteriEXT, (GLuint, GLenum, GLenum, GLint)) +AGL_API(void, TextureParameterivEXT, (GLuint, GLenum, GLenum, const GLint *)) +AGL_API(void, TextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyTextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) +AGL_API(void, CopyTextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) +AGL_API(void, CopyTextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei)) +AGL_API(void, CopyTextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, GetTextureImageEXT, (GLuint, GLenum, GLint, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetTextureParameterfvEXT, (GLuint, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetTextureParameterivEXT, (GLuint, GLenum, GLenum, GLint *)) +AGL_API(void, GetTextureLevelParameterfvEXT, (GLuint, GLenum, GLint, GLenum, GLfloat *)) +AGL_API(void, GetTextureLevelParameterivEXT, (GLuint, GLenum, GLint, GLenum, GLint *)) +AGL_API(void, TextureImage3DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, TextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyTextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, MultiTexParameterfEXT, (GLenum, GLenum, GLenum, GLfloat)) +AGL_API(void, MultiTexParameterfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) +AGL_API(void, MultiTexParameteriEXT, (GLenum, GLenum, GLenum, GLint)) +AGL_API(void, MultiTexParameterivEXT, (GLenum, GLenum, GLenum, const GLint *)) +AGL_API(void, MultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, MultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, MultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, MultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyMultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint)) +AGL_API(void, CopyMultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)) +AGL_API(void, CopyMultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei)) +AGL_API(void, CopyMultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, GetMultiTexImageEXT, (GLenum, GLenum, GLint, GLenum, GLenum, GLvoid *)) +AGL_API(void, GetMultiTexParameterfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMultiTexParameterivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetMultiTexLevelParameterfvEXT, (GLenum, GLenum, GLint, GLenum, GLfloat *)) +AGL_API(void, GetMultiTexLevelParameterivEXT, (GLenum, GLenum, GLint, GLenum, GLint *)) +AGL_API(void, MultiTexImage3DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) +AGL_API(void, MultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) +AGL_API(void, CopyMultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)) +AGL_API(void, BindMultiTextureEXT, (GLenum, GLenum, GLuint)) +AGL_API(void, EnableClientStateIndexedEXT, (GLenum, GLuint)) +AGL_API(void, DisableClientStateIndexedEXT, (GLenum, GLuint)) +AGL_API(void, MultiTexCoordPointerEXT, (GLenum, GLint, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, MultiTexEnvfEXT, (GLenum, GLenum, GLenum, GLfloat)) +AGL_API(void, MultiTexEnvfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) +AGL_API(void, MultiTexEnviEXT, (GLenum, GLenum, GLenum, GLint)) +AGL_API(void, MultiTexEnvivEXT, (GLenum, GLenum, GLenum, const GLint *)) +AGL_API(void, MultiTexGendEXT, (GLenum, GLenum, GLenum, GLdouble)) +AGL_API(void, MultiTexGendvEXT, (GLenum, GLenum, GLenum, const GLdouble *)) +AGL_API(void, MultiTexGenfEXT, (GLenum, GLenum, GLenum, GLfloat)) +AGL_API(void, MultiTexGenfvEXT, (GLenum, GLenum, GLenum, const GLfloat *)) +AGL_API(void, MultiTexGeniEXT, (GLenum, GLenum, GLenum, GLint)) +AGL_API(void, MultiTexGenivEXT, (GLenum, GLenum, GLenum, const GLint *)) +AGL_API(void, GetMultiTexEnvfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMultiTexEnvivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetMultiTexGendvEXT, (GLenum, GLenum, GLenum, GLdouble *)) +AGL_API(void, GetMultiTexGenfvEXT, (GLenum, GLenum, GLenum, GLfloat *)) +AGL_API(void, GetMultiTexGenivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetFloatIndexedvEXT, (GLenum, GLuint, GLfloat *)) +AGL_API(void, GetDoubleIndexedvEXT, (GLenum, GLuint, GLdouble *)) +AGL_API(void, GetPointerIndexedvEXT, (GLenum, GLuint, GLvoid* *)) +AGL_API(void, CompressedTextureImage3DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureImage2DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureImage1DEXT, (GLuint, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureSubImage3DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureSubImage2DEXT, (GLuint, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedTextureSubImage1DEXT, (GLuint, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetCompressedTextureImageEXT, (GLuint, GLenum, GLint, GLvoid *)) +AGL_API(void, CompressedMultiTexImage3DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexImage2DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexImage1DEXT, (GLenum, GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexSubImage3DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexSubImage2DEXT, (GLenum, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, CompressedMultiTexSubImage1DEXT, (GLenum, GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, GetCompressedMultiTexImageEXT, (GLenum, GLenum, GLint, GLvoid *)) +AGL_API(void, NamedProgramStringEXT, (GLuint, GLenum, GLenum, GLsizei, const GLvoid *)) +AGL_API(void, NamedProgramLocalParameter4dEXT, (GLuint, GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble)) +AGL_API(void, NamedProgramLocalParameter4dvEXT, (GLuint, GLenum, GLuint, const GLdouble *)) +AGL_API(void, NamedProgramLocalParameter4fEXT, (GLuint, GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, NamedProgramLocalParameter4fvEXT, (GLuint, GLenum, GLuint, const GLfloat *)) +AGL_API(void, GetNamedProgramLocalParameterdvEXT, (GLuint, GLenum, GLuint, GLdouble *)) +AGL_API(void, GetNamedProgramLocalParameterfvEXT, (GLuint, GLenum, GLuint, GLfloat *)) +AGL_API(void, GetNamedProgramivEXT, (GLuint, GLenum, GLenum, GLint *)) +AGL_API(void, GetNamedProgramStringEXT, (GLuint, GLenum, GLenum, GLvoid *)) +AGL_API(void, NamedProgramLocalParameters4fvEXT, (GLuint, GLenum, GLuint, GLsizei, const GLfloat *)) +AGL_API(void, NamedProgramLocalParameterI4iEXT, (GLuint, GLenum, GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, NamedProgramLocalParameterI4ivEXT, (GLuint, GLenum, GLuint, const GLint *)) +AGL_API(void, NamedProgramLocalParametersI4ivEXT, (GLuint, GLenum, GLuint, GLsizei, const GLint *)) +AGL_API(void, NamedProgramLocalParameterI4uiEXT, (GLuint, GLenum, GLuint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, NamedProgramLocalParameterI4uivEXT, (GLuint, GLenum, GLuint, const GLuint *)) +AGL_API(void, NamedProgramLocalParametersI4uivEXT, (GLuint, GLenum, GLuint, GLsizei, const GLuint *)) +AGL_API(void, GetNamedProgramLocalParameterIivEXT, (GLuint, GLenum, GLuint, GLint *)) +AGL_API(void, GetNamedProgramLocalParameterIuivEXT, (GLuint, GLenum, GLuint, GLuint *)) +AGL_API(void, TextureParameterIivEXT, (GLuint, GLenum, GLenum, const GLint *)) +AGL_API(void, TextureParameterIuivEXT, (GLuint, GLenum, GLenum, const GLuint *)) +AGL_API(void, GetTextureParameterIivEXT, (GLuint, GLenum, GLenum, GLint *)) +AGL_API(void, GetTextureParameterIuivEXT, (GLuint, GLenum, GLenum, GLuint *)) +AGL_API(void, MultiTexParameterIivEXT, (GLenum, GLenum, GLenum, const GLint *)) +AGL_API(void, MultiTexParameterIuivEXT, (GLenum, GLenum, GLenum, const GLuint *)) +AGL_API(void, GetMultiTexParameterIivEXT, (GLenum, GLenum, GLenum, GLint *)) +AGL_API(void, GetMultiTexParameterIuivEXT, (GLenum, GLenum, GLenum, GLuint *)) +AGL_API(void, ProgramUniform1fEXT, (GLuint, GLint, GLfloat)) +AGL_API(void, ProgramUniform2fEXT, (GLuint, GLint, GLfloat, GLfloat)) +AGL_API(void, ProgramUniform3fEXT, (GLuint, GLint, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramUniform4fEXT, (GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat)) +AGL_API(void, ProgramUniform1iEXT, (GLuint, GLint, GLint)) +AGL_API(void, ProgramUniform2iEXT, (GLuint, GLint, GLint, GLint)) +AGL_API(void, ProgramUniform3iEXT, (GLuint, GLint, GLint, GLint, GLint)) +AGL_API(void, ProgramUniform4iEXT, (GLuint, GLint, GLint, GLint, GLint, GLint)) +AGL_API(void, ProgramUniform1fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramUniform2fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramUniform3fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramUniform4fvEXT, (GLuint, GLint, GLsizei, const GLfloat *)) +AGL_API(void, ProgramUniform1ivEXT, (GLuint, GLint, GLsizei, const GLint *)) +AGL_API(void, ProgramUniform2ivEXT, (GLuint, GLint, GLsizei, const GLint *)) +AGL_API(void, ProgramUniform3ivEXT, (GLuint, GLint, GLsizei, const GLint *)) +AGL_API(void, ProgramUniform4ivEXT, (GLuint, GLint, GLsizei, const GLint *)) +AGL_API(void, ProgramUniformMatrix2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix2x3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix3x2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix2x4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix4x2fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix3x4fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniformMatrix4x3fvEXT, (GLuint, GLint, GLsizei, GLboolean, const GLfloat *)) +AGL_API(void, ProgramUniform1uiEXT, (GLuint, GLint, GLuint)) +AGL_API(void, ProgramUniform2uiEXT, (GLuint, GLint, GLuint, GLuint)) +AGL_API(void, ProgramUniform3uiEXT, (GLuint, GLint, GLuint, GLuint, GLuint)) +AGL_API(void, ProgramUniform4uiEXT, (GLuint, GLint, GLuint, GLuint, GLuint, GLuint)) +AGL_API(void, ProgramUniform1uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) +AGL_API(void, ProgramUniform2uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) +AGL_API(void, ProgramUniform3uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) +AGL_API(void, ProgramUniform4uivEXT, (GLuint, GLint, GLsizei, const GLuint *)) +AGL_API(void, NamedBufferDataEXT, (GLuint, GLsizeiptr, const GLvoid *, GLenum)) +AGL_API(void, NamedBufferSubDataEXT, (GLuint, GLintptr, GLsizeiptr, const GLvoid *)) +AGL_API(GLvoid*, MapNamedBufferEXT, (GLuint, GLenum)) +AGL_API(GLboolean, UnmapNamedBufferEXT, (GLuint)) +AGL_API(void, GetNamedBufferParameterivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, GetNamedBufferPointervEXT, (GLuint, GLenum, GLvoid* *)) +AGL_API(void, GetNamedBufferSubDataEXT, (GLuint, GLintptr, GLsizeiptr, GLvoid *)) +AGL_API(void, TextureBufferEXT, (GLuint, GLenum, GLenum, GLuint)) +AGL_API(void, MultiTexBufferEXT, (GLenum, GLenum, GLenum, GLuint)) +AGL_API(void, NamedRenderbufferStorageEXT, (GLuint, GLenum, GLsizei, GLsizei)) +AGL_API(void, GetNamedRenderbufferParameterivEXT, (GLuint, GLenum, GLint *)) +AGL_API(GLenum, CheckNamedFramebufferStatusEXT, (GLuint, GLenum)) +AGL_API(void, NamedFramebufferTexture1DEXT, (GLuint, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, NamedFramebufferTexture2DEXT, (GLuint, GLenum, GLenum, GLuint, GLint)) +AGL_API(void, NamedFramebufferTexture3DEXT, (GLuint, GLenum, GLenum, GLuint, GLint, GLint)) +AGL_API(void, NamedFramebufferRenderbufferEXT, (GLuint, GLenum, GLenum, GLuint)) +AGL_API(void, GetNamedFramebufferAttachmentParameterivEXT, (GLuint, GLenum, GLenum, GLint *)) +AGL_API(void, GenerateTextureMipmapEXT, (GLuint, GLenum)) +AGL_API(void, GenerateMultiTexMipmapEXT, (GLenum, GLenum)) +AGL_API(void, FramebufferDrawBufferEXT, (GLuint, GLenum)) +AGL_API(void, FramebufferDrawBuffersEXT, (GLuint, GLsizei, const GLenum *)) +AGL_API(void, FramebufferReadBufferEXT, (GLuint, GLenum)) +AGL_API(void, GetFramebufferParameterivEXT, (GLuint, GLenum, GLint *)) +AGL_API(void, NamedRenderbufferStorageMultisampleEXT, (GLuint, GLsizei, GLenum, GLsizei, GLsizei)) +AGL_API(void, NamedRenderbufferStorageMultisampleCoverageEXT, (GLuint, GLsizei, GLsizei, GLenum, GLsizei, GLsizei)) +AGL_API(void, NamedFramebufferTextureEXT, (GLuint, GLenum, GLuint, GLint)) +AGL_API(void, NamedFramebufferTextureLayerEXT, (GLuint, GLenum, GLuint, GLint, GLint)) +AGL_API(void, NamedFramebufferTextureFaceEXT, (GLuint, GLenum, GLuint, GLint, GLenum)) +AGL_API(void, TextureRenderbufferEXT, (GLuint, GLenum, GLuint)) +AGL_API(void, MultiTexRenderbufferEXT, (GLenum, GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_NV_explicit_multisample +AGL_API(void, GetMultisamplefvNV, (GLenum, GLuint, GLfloat *)) +AGL_API(void, SampleMaskIndexedNV, (GLuint, GLbitfield)) +AGL_API(void, TexRenderbufferNV, (GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_NV_transform_feedback2 +AGL_API(void, BindTransformFeedbackNV, (GLenum, GLuint)) +AGL_API(void, DeleteTransformFeedbacksNV, (GLsizei, const GLuint *)) +AGL_API(void, GenTransformFeedbacksNV, (GLsizei, GLuint *)) +AGL_API(GLboolean, IsTransformFeedbackNV, (GLuint)) +AGL_API(void, PauseTransformFeedbackNV, (void)) +AGL_API(void, ResumeTransformFeedbackNV, (void)) +AGL_API(void, DrawTransformFeedbackNV, (GLenum, GLuint)) +#endif + +#if defined _ALLEGRO_GL_AMD_performance_monitor +AGL_API(void, GetPerfMonitorGroupsAMD, (GLint *, GLsizei, GLuint *)) +AGL_API(void, GetPerfMonitorCountersAMD, (GLuint, GLint *, GLint *, GLsizei, GLuint *)) +AGL_API(void, GetPerfMonitorGroupStringAMD, (GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, GetPerfMonitorCounterStringAMD, (GLuint, GLuint, GLsizei, GLsizei *, GLchar *)) +AGL_API(void, GetPerfMonitorCounterInfoAMD, (GLuint, GLuint, GLenum, void *)) +AGL_API(void, GenPerfMonitorsAMD, (GLsizei, GLuint *)) +AGL_API(void, DeletePerfMonitorsAMD, (GLsizei, GLuint *)) +AGL_API(void, SelectPerfMonitorCountersAMD, (GLuint, GLboolean, GLuint, GLint, GLuint *)) +AGL_API(void, BeginPerfMonitorAMD, (GLuint)) +AGL_API(void, EndPerfMonitorAMD, (GLuint)) +AGL_API(void, GetPerfMonitorCounterDataAMD, (GLuint, GLenum, GLsizei, GLuint *, GLint *)) +#endif + +#if defined _ALLEGRO_GL_AMD_vertex_shader_tesselator +AGL_API(void, TessellationFactorAMD, (GLfloat)) +AGL_API(void, TessellationModeAMD, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_EXT_provoking_vertex +AGL_API(void, ProvokingVertexEXT, (GLenum)) +#endif + +#if defined _ALLEGRO_GL_AMD_draw_buffers_blend +AGL_API(void, BlendFuncIndexedAMD, (GLuint buf, GLenum src, GLenum dst)) +AGL_API(void, BlendFuncSeparateIndexedAMD, (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)) +AGL_API(void, BlendEquationIndexedAMD, (GLuint buf, GLenum mode)) +AGL_API(void, BlendEquationSeparateIndexedAMD, (GLuint buf, GLenum modeRGB, GLenum modeAlpha)) +#endif + +#if defined _ALLEGRO_GL_APPLE_texture_range +AGL_API(void, TextureRangeAPPLE, (GLenum target, GLsizei length, const GLvoid *pointer)) +AGL_API(void, GetTexParameterPointervAPPLE, (GLenum target, GLenum pname, GLvoid* *params)) +#endif + +#if defined _ALLEGRO_GL_APPLE_vertex_program_evaluators +AGL_API(void, EnableVertexAttribAPPLE, (GLuint index, GLenum pname)) +AGL_API(void, DisableVertexAttribAPPLE, (GLuint index, GLenum pname)) +AGL_API(GLboolean, IsVertexAttribEnabledAPPLE, (GLuint index, GLenum pname)) +AGL_API(void, MapVertexAttrib1dAPPLE, (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)) +AGL_API(void, MapVertexAttrib1fAPPLE, (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)) +AGL_API(void, MapVertexAttrib2dAPPLE, (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)) +AGL_API(void, MapVertexAttrib2fAPPLE, (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)) +#endif + +#if defined _ALLEGRO_GL_APPLE_object_purgeable +AGL_API(GLenum, ObjectPurgeableAPPLE, (GLenum objectType, GLuint name, GLenum option)) +AGL_API(GLenum, ObjectUnpurgeableAPPLE, (GLenum objectType, GLuint name, GLenum option)) +AGL_API(void, GetObjectParameterivAPPLE, (GLenum objectType, GLuint name, GLenum pname, GLint *params)) +#endif + +#if defined _ALLEGRO_GL_NV_video_capture +AGL_API(void, BeginVideoCaptureNV, (GLuint video_capture_slot)) +AGL_API(void, BindVideoCaptureStreamBufferNV, (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset)) +AGL_API(void, BindVideoCaptureStreamTextureNV, (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture)) +AGL_API(void, EndVideoCaptureNV, (GLuint video_capture_slot)) +AGL_API(void, GetVideoCaptureivNV, (GLuint video_capture_slot, GLenum pname, GLint *params)) +AGL_API(void, GetVideoCaptureStreamivNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params)) +AGL_API(void, GetVideoCaptureStreamfvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params)) +AGL_API(void, GetVideoCaptureStreamdvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params)) +AGL_API(GLenum, VideoCaptureNV, (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time)) +AGL_API(void, VideoCaptureStreamParameterivNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params)) +AGL_API(void, VideoCaptureStreamParameterfvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params)) +AGL_API(void, VideoCaptureStreamParameterdvNV, (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params)) +#endif + +#if defined _ALLEGRO_GL_EXT_separate_shader_objects +AGL_API(void, UseShaderProgramEXT, (GLenum type, GLuint program)) +AGL_API(void, ActiveProgramEXT, (GLuint program)) +AGL_API(GLuint, CreateShaderProgramEXT, (GLenum type, const GLchar *string)) +#endif + +#if defined _ALLEGRO_GL_NV_shader_buffer_load +AGL_API(void, MakeBufferResidentNV, (GLenum target, GLenum access)) +AGL_API(void, MakeBufferNonResidentNV, (GLenum target)) +AGL_API(GLboolean, IsBufferResidentNV, (GLenum target)) +AGL_API(void, MakeNamedBufferResidentNV, (GLuint buffer, GLenum access)) +AGL_API(void, MakeNamedBufferNonResidentNV, (GLuint buffer)) +AGL_API(GLboolean, IsNamedBufferResidentNV, (GLuint buffer)) +AGL_API(void, GetBufferParameterui64vNV, (GLenum target, GLenum pname, GLuint64EXT *params)) +AGL_API(void, GetNamedBufferParameterui64vNV, (GLuint buffer, GLenum pname, GLuint64EXT *params)) +AGL_API(void, GetIntegerui64vNV, (GLenum value, GLuint64EXT *result)) +AGL_API(void, Uniformui64NV, (GLint location, GLuint64EXT value)) +AGL_API(void, Uniformui64vNV, (GLint location, GLsizei count, const GLuint64EXT *value)) +AGL_API(void, GetUniformui64vNV, (GLuint program, GLint location, GLuint64EXT *params)) +AGL_API(void, ProgramUniformui64NV, (GLuint program, GLint location, GLuint64EXT value)) +AGL_API(void, ProgramUniformui64vNV, (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value)) +#endif + +#if defined _ALLEGRO_GL_NV_vertex_buffer_unified_memory +AGL_API(void, BufferAddressRangeNV, (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length)) +AGL_API(void, VertexFormatNV, (GLint size, GLenum type, GLsizei stride)) +AGL_API(void, NormalFormatNV, (GLenum type, GLsizei stride)) +AGL_API(void, ColorFormatNV, (GLint size, GLenum type, GLsizei stride)) +AGL_API(void, IndexFormatNV, (GLenum type, GLsizei stride)) +AGL_API(void, TexCoordFormatNV, (GLint size, GLenum type, GLsizei stride)) +AGL_API(void, EdgeFlagFormatNV, (GLsizei stride)) +AGL_API(void, SecondaryColorFormatNV, (GLint size, GLenum type, GLsizei stride)) +AGL_API(void, FogCoordFormatNV, (GLenum type, GLsizei stride)) +AGL_API(void, VertexAttribFormatNV, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride)) +AGL_API(void, VertexAttribIFormatNV, (GLuint index, GLint size, GLenum type, GLsizei stride)) +AGL_API(void, GetIntegerui64i_vNV, (GLenum value, GLuint index, GLuint64EXT *result)) +#endif + +#if defined _ALLEGRO_GL_NV_texture_barrier +AGL_API(void, TextureBarrierNV, (void)) +#endif diff --git a/allegro/include/allegro5/opengl/GLext/gl_ext_defs.h b/allegro/include/allegro5/opengl/GLext/gl_ext_defs.h new file mode 100644 index 00000000..f8d3a904 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/gl_ext_defs.h @@ -0,0 +1,5464 @@ +/* */ + +#if (defined _MSC_VER) && (_MSC_VER < 1400) +typedef __int64 GLint64; +typedef unsigned __int64 GLuint64; +#else +typedef int64_t GLint64; +typedef uint64_t GLuint64; +#endif + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#define _ALLEGRO_GL_VERSION_1_2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#endif + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging +#define _ALLEGRO_GL_ARB_imaging +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#endif + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#define _ALLEGRO_GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#endif + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#define _ALLEGRO_GL_VERSION_1_4 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#endif + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#define _ALLEGRO_GL_VERSION_1_5 +/* New types */ +#include +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +/* Renamed enumerants */ +#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE +#define GL_FOG_COORD GL_FOG_COORDINATE +#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE +#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE +#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE +#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER +#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY +#define GL_SRC0_RGB GL_SOURCE0_RGB +#define GL_SRC1_RGB GL_SOURCE1_RGB +#define GL_SRC2_RGB GL_SOURCE2_RGB +#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA +#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA +#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA +/* Promoted exts */ +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#endif + + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +#define _ALLEGRO_GL_VERSION_2_0 +/* New types */ +typedef char GLchar; + +#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#endif + + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#define _ALLEGRO_GL_VERSION_2_1 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#endif + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 +#define _ALLEGRO_GL_VERSION_3_0 +#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB +#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 +#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 +#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 +#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 +#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 +#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 +#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_DEPTH_BUFFER 0x8223 +#define GL_STENCIL_BUFFER 0x8224 +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#endif + +#ifndef GL_VERSION_3_0_DEPRECATED +#define GL_VERSION_3_0_DEPRECATED +#define _ALLEGRO_GL_VERSION_3_0_DEPRECATED +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_ALPHA_INTEGER 0x8D97 +/* Reuse tokens from ARB_framebuffer_object */ +/* reuse GL_TEXTURE_LUMINANCE_TYPE */ +/* reuse GL_TEXTURE_INTENSITY_TYPE */ +#endif + + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 +#define _ALLEGRO_GL_VERSION_3_1 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#endif + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 +#define _ALLEGRO_GL_VERSION_3_2 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#endif + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 +#define _ALLEGRO_GL_VERSION_3_3 +#endif + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 +#define _ALLEGRO_GL_VERSION_4_3 +typedef void (*GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_MIPMAP 0x8293 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_COLOR_ENCODING 0x8296 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_FILTER 0x829A +#define GL_VERTEX_TEXTURE 0x829B +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F +#define GL_IS_PER_PATCH 0x92E7 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_DISPLAY_LIST 0x82E7 +typedef void (PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); +typedef void (PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +typedef void (PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +typedef void (PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); +typedef void (PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); +typedef void (PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +typedef void (PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +typedef GLuint (PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +typedef void (PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef GLint (PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef GLint (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +typedef void (PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +typedef void (PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); +typedef void (PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); +typedef GLuint (PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (PFNGLPOPDEBUGGROUPPROC) (void); +typedef void (PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif + + +/* */ +/* */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture +#define _ALLEGRO_GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix +#define _ALLEGRO_GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample +#define _ALLEGRO_GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map +#define _ALLEGRO_GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression +#define _ALLEGRO_GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp +#define _ALLEGRO_GL_ARB_texture_border_clamp +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters +#define _ALLEGRO_GL_ARB_point_parameters +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend +#define _ALLEGRO_GL_ARB_vertex_blend +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#endif + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette +#define _ALLEGRO_GL_ARB_matrix_palette +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +#endif + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine +#define _ALLEGRO_GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 +#define _ALLEGRO_GL_ARB_texture_env_dot3 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat +#define _ALLEGRO_GL_ARB_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture +#define _ALLEGRO_GL_ARB_depth_texture +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos +#define _ALLEGRO_GL_ARB_window_pos +#endif + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow +#define _ALLEGRO_GL_ARB_shadow +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient +#define _ALLEGRO_GL_ARB_shadow_ambient +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program +#define _ALLEGRO_GL_ARB_vertex_program +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#endif + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program +#define _ALLEGRO_GL_ARB_fragment_program +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object +#define _ALLEGRO_GL_ARB_vertex_buffer_object +#include +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +#endif + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query +#define _ALLEGRO_GL_ARB_occlusion_query +#define GL_SAMPLES_PASSED_ARB 0x8914 +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#endif + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects +#define _ALLEGRO_GL_ARB_shader_objects +typedef char GLcharARB; +typedef unsigned long GLhandleARB; +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#define GL_SHADER_OBJECT_ARB 0x8B48 +/* GL_FLOAT */ +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +/* GL_INT */ +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#endif + + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader +#define _ALLEGRO_GL_ARB_vertex_shader +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#if !defined GL_ARB_shader_objects +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#endif +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#if !defined GL_ARB_shader_objects +#define GL_SHADER_OBJECT_ARB 0x8B48 +#endif +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#if !defined GL_ARB_shader_objects +/* GL_FLOAT */ +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#endif +#endif + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader +#define _ALLEGRO_GL_ARB_fragment_shader +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#if !defined GL_ARB_shader_objects && !defined GL_ARB_vertex_shader +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_SHADER_OBJECT_ARB 0x8B48 +#endif +#endif + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 +#define _ALLEGRO_GL_ARB_shading_language_100 +#endif + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two +#define _ALLEGRO_GL_ARB_texture_non_power_of_two +#endif + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite +#define _ALLEGRO_GL_ARB_point_sprite +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +/* GL_FALSE */ +/* GL_TRUE */ +#endif + + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers +#define _ALLEGRO_GL_ARB_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +#endif + + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle +#define _ALLEGRO_GL_ARB_texture_rectangle +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif +#ifdef ALLEGRO_MACOSX +#ifndef GL_EXT_texture_rectangle +#define GL_EXT_texture_rectangle +#define _ALLEGRO_GL_EXT_texture_rectangle +#define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8 +#endif +#endif + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float +#define _ALLEGRO_GL_ARB_color_buffer_float +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +#endif + + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel +#define _ALLEGRO_GL_ARB_half_float_pixel +#define GL_HALF_FLOAT_ARB 0x140B +#endif + + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float +#define _ALLEGRO_GL_ARB_texture_float +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object +#define _ALLEGRO_GL_ARB_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float +#define _ALLEGRO_GL_ARB_depth_buffer_float +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#endif + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced +#define _ALLEGRO_GL_ARB_draw_instanced +#endif + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object +#define _ALLEGRO_GL_ARB_framebuffer_object +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_INDEX 0x8222 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#endif + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB +#define _ALLEGRO_GL_ARB_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#endif + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 +#define _ALLEGRO_GL_ARB_geometry_shader4 +#define GL_LINES_ADJACENCY_ARB 0x000A +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B +#define GL_TRIANGLES_ADJACENCY_ARB 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 +/* reuse GL_MAX_VARYING_COMPONENTS */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ +#endif + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex +#define _ALLEGRO_GL_ARB_half_float_vertex +#define GL_HALF_FLOAT 0x140B +#endif + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays +#define _ALLEGRO_GL_ARB_instanced_arrays +#endif + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range +#define _ALLEGRO_GL_ARB_map_buffer_range +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#endif + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object +#define _ALLEGRO_GL_ARB_texture_buffer_object +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E +#endif + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc +#define _ALLEGRO_GL_ARB_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg +#define _ALLEGRO_GL_ARB_texture_rg +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#endif + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object +#define _ALLEGRO_GL_ARB_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#endif + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object +#define _ALLEGRO_GL_ARB_uniform_buffer_object +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#endif + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility +#define _ALLEGRO_GL_ARB_compatibility +/* ARB_compatibility just defines tokens from core 3.0 */ +#endif + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer +#define _ALLEGRO_GL_ARB_copy_buffer +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#endif + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod +#define _ALLEGRO_GL_ARB_shader_texture_lod +#endif + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp +#define _ALLEGRO_GL_ARB_depth_clamp +#define GL_DEPTH_CLAMP 0x864F +#endif + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex +#define _ALLEGRO_GL_ARB_draw_elements_base_vertex +#endif + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions +#define _ALLEGRO_GL_ARB_fragment_coord_conventions +#endif + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex +#define _ALLEGRO_GL_ARB_provoking_vertex +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#endif + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map +#define _ALLEGRO_GL_ARB_seamless_cube_map +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#endif + +#ifndef GL_ARB_sync +#define GL_ARB_sync +#define _ALLEGRO_GL_ARB_sync +typedef struct __GLsync *GLsync; +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#endif + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample +#define _ALLEGRO_GL_ARB_texture_multisample +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#endif + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra +#define _ALLEGRO_GL_ARB_vertex_array_bgra +/* reuse GL_BGRA */ +#endif + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend +#define _ALLEGRO_GL_ARB_draw_buffers_blend +#endif + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading +#define _ALLEGRO_GL_ARB_sample_shading +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#endif + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array +#define _ALLEGRO_GL_ARB_texture_cube_map_array +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#endif + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather +#define _ALLEGRO_GL_ARB_texture_gather +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#endif + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod +#define _ALLEGRO_GL_ARB_texture_query_lod +#endif + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include +#define _ALLEGRO_GL_ARB_shading_language_include +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA +#endif + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc +#define _ALLEGRO_GL_ARB_texture_compression_bptc +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended +#define _ALLEGRO_GL_ARB_blend_func_extended +#define GL_SRC1_COLOR 0x88F9 +/* reuse GL_SRC1_ALPHA */ +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#endif + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location +#define _ALLEGRO_GL_ARB_explicit_attrib_location +#endif + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 +#define _ALLEGRO_GL_ARB_occlusion_query2 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#endif + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects +#define _ALLEGRO_GL_ARB_sampler_objects +#define GL_SAMPLER_BINDING 0x8919 +#endif + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding +#define _ALLEGRO_GL_ARB_shader_bit_encoding +#endif + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui +#define _ALLEGRO_GL_ARB_texture_rgb10_a2ui +#define GL_RGB10_A2UI 0x906F +#endif + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle +#define _ALLEGRO_GL_ARB_texture_swizzle +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#endif + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query +#define _ALLEGRO_GL_ARB_timer_query +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 +#endif + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev +#define _ALLEGRO_GL_ARB_vertex_type_2_10_10_10_rev +/* reuse GL_UNSIGNED_INT_2_10_10_10_REV */ +#define GL_INT_2_10_10_10_REV 0x8D9F +#endif + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect +#define _ALLEGRO_GL_ARB_draw_indirect +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#endif + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 +#define _ALLEGRO_GL_ARB_gpu_shader5 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#endif + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 +#define _ALLEGRO_GL_ARB_gpu_shader_fp64 +/* reuse GL_DOUBLE */ +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#endif + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine +#define _ALLEGRO_GL_ARB_shader_subroutine +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +/* reuse GL_UNIFORM_SIZE */ +/* reuse GL_UNIFORM_NAME_LENGTH */ +#endif + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader +#define _ALLEGRO_GL_ARB_tessellation_shader +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +/* reuse GL_TRIANGLES */ +/* reuse GL_QUADS */ +#define GL_ISOLINES 0x8E7A +/* reuse GL_EQUAL */ +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +/* reuse GL_CCW */ +/* reuse GL_CW */ +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#endif + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 +#define _ALLEGRO_GL_ARB_texture_buffer_object_rgb32 +/* reuse GL_RGB32F */ +/* reuse GL_RGB32UI */ +/* reuse GL_RGB32I */ +#endif + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 +#define _ALLEGRO_GL_ARB_transform_feedback2 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#endif + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 +#define _ALLEGRO_GL_ARB_transform_feedback3 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#endif + + +/* */ + + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr +#define _ALLEGRO_GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color +#define _ALLEGRO_GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset +#define _ALLEGRO_GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture +#define _ALLEGRO_GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D +#define _ALLEGRO_GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 +#define _ALLEGRO_GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram +#define _ALLEGRO_GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture +#define _ALLEGRO_GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture +/* NV's headers don't define EXT_copy_texture yet provide the API */ +#ifndef ALLEGRO_GL_HEADER_NV +#define _ALLEGRO_GL_EXT_copy_texture +#endif +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram +#define _ALLEGRO_GL_EXT_histogram +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution +#define _ALLEGRO_GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix +#define _ALLEGRO_GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table +#define _ALLEGRO_GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture +#define _ALLEGRO_GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture +#define _ALLEGRO_GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D +#define _ALLEGRO_GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table +#define _ALLEGRO_GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka +#define _ALLEGRO_GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object +#define _ALLEGRO_GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture +#define _ALLEGRO_GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture +#define _ALLEGRO_GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels +#define _ALLEGRO_GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod +#define _ALLEGRO_GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample +#define _ALLEGRO_GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal +#define _ALLEGRO_GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array +#define _ALLEGRO_GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap +#define _ALLEGRO_GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap +#define _ALLEGRO_GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow +#define _ALLEGRO_GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp +#define _ALLEGRO_GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax +#define _ALLEGRO_GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract +#define _ALLEGRO_GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace +#define _ALLEGRO_GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles +#define _ALLEGRO_GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select +#define _ALLEGRO_GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite +#define _ALLEGRO_GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer +#define _ALLEGRO_GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters +#define _ALLEGRO_GL_EXT_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters +#define _ALLEGRO_GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments +#define _ALLEGRO_GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias +#define _ALLEGRO_GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom +#define _ALLEGRO_GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_FfdMaskSGIX +#define GL_FfdMaskSGIX +#define _ALLEGRO_GL_FfdMaskSGIX +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer +#define _ALLEGRO_GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd +#define _ALLEGRO_GL_SGIX_polynomial_ffd +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane +#define _ALLEGRO_GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture +#define _ALLEGRO_GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster +#define _ALLEGRO_GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function +#define _ALLEGRO_GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset +#define _ALLEGRO_GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform +#define _ALLEGRO_GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes +#define _ALLEGRO_GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env +#define _ALLEGRO_GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable +#define _ALLEGRO_GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints +#define _ALLEGRO_GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints +#define _ALLEGRO_GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture +#define _ALLEGRO_GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint +#define _ALLEGRO_GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority +#define _ALLEGRO_GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 +#define _ALLEGRO_GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment +#define _ALLEGRO_GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias +#define _ALLEGRO_GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient +#define _ALLEGRO_GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material +#define _ALLEGRO_GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func +#define _ALLEGRO_GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats +#define _ALLEGRO_GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array +#define _ALLEGRO_GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex +#define _ALLEGRO_GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb +#define _ALLEGRO_GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting +#define _ALLEGRO_GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip +#define _ALLEGRO_GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting +#define _ALLEGRO_GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements +#define _ALLEGRO_GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading +#define _ALLEGRO_GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog +#define _ALLEGRO_GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture +#define _ALLEGRO_GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +#ifndef GL_FRAGMENT_DEPTH_EXT +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#endif +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax +#define _ALLEGRO_GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_SGIX_impact_pixel_texture +#define GL_SGIX_impact_pixel_texture +#define _ALLEGRO_GL_SGIX_impact_pixel_texture +#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 +#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 +#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 +#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 +#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 +#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 +#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra +#define _ALLEGRO_GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_SGIX_async +#define GL_SGIX_async +#define _ALLEGRO_GL_SGIX_async +#define GL_ASYNC_MARKER_SGIX 0x8329 +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel +#define _ALLEGRO_GL_SGIX_async_pixel +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram +#define _ALLEGRO_GL_SGIX_async_histogram +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays +#define _ALLEGRO_GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test +#define _ALLEGRO_GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform +#define _ALLEGRO_GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette +#define _ALLEGRO_GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color +#define _ALLEGRO_GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color +#define _ALLEGRO_GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal +#define _ALLEGRO_GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays +#define _ALLEGRO_GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord +#define _ALLEGRO_GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates +#define _ALLEGRO_GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame +#define _ALLEGRO_GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine +#define _ALLEGRO_GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector +#define _ALLEGRO_GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint +#define _ALLEGRO_GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale +#define _ALLEGRO_GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data +#define _ALLEGRO_GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha +#define _ALLEGRO_GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list +#define _ALLEGRO_GL_SUN_triangle_list +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex +#define _ALLEGRO_GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate +#define _ALLEGRO_GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp +#define _ALLEGRO_GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate +#define _ALLEGRO_GL_INGR_blend_func_separate +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read +#define _ALLEGRO_GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap +#define _ALLEGRO_GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels +#define _ALLEGRO_GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection +#define _ALLEGRO_GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map +#define _ALLEGRO_GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes +#define _ALLEGRO_GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias +#define _ALLEGRO_GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic +#define _ALLEGRO_GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting +#define _ALLEGRO_GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent +#define _ALLEGRO_GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range +#define _ALLEGRO_GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners +#define _ALLEGRO_GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* GL_TEXTURE0_ARB */ +/* GL_TEXTURE1_ARB */ +/* GL_ZERO */ +/* GL_NONE */ +/* GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance +#define _ALLEGRO_GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss +#define _ALLEGRO_GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 +#define _ALLEGRO_GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc +#define _ALLEGRO_GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers +#define _ALLEGRO_GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos +#define _ALLEGRO_GL_MESA_window_pos +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex +#define _ALLEGRO_GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays +#define _ALLEGRO_GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists +#define _ALLEGRO_GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample +#define _ALLEGRO_GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba +#define _ALLEGRO_GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_SGI_depth_pass_instrument +#define _ALLEGRO_GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 +#define _ALLEGRO_GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample +#define _ALLEGRO_GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer +#ifndef ALLEGRO_GL_HEADER_NV +#define _ALLEGRO_GL_3DFX_tbuffer +#endif +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample +#define _ALLEGRO_GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip +#define _ALLEGRO_GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy +#define _ALLEGRO_GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample +#define _ALLEGRO_GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen +#define _ALLEGRO_GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask +#ifndef ALLEGRO_GL_HEADER_NV +#define _ALLEGRO_GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif +#endif + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface +#define _ALLEGRO_GL_SGIX_igloo_interface +#endif + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 +#define _ALLEGRO_GL_EXT_texture_env_dot3 +/* GL_DOT3_RGB_EXT */ +/* GL_DOT3_RGBA_EXT */ +#endif + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once +#define _ALLEGRO_GL_ATI_texture_mirror_once +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif + +#ifndef GL_NV_fence +#define GL_NV_fence +#define _ALLEGRO_GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat +#define _ALLEGRO_GL_IBM_texture_mirrored_repeat +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators +#define _ALLEGRO_GL_NV_evaluators +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +#endif + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil +#define _ALLEGRO_GL_NV_packed_depth_stencil +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 +#define _ALLEGRO_GL_NV_register_combiners2 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +#endif + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle +#define _ALLEGRO_GL_NV_texture_rectangle +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader +#define _ALLEGRO_GL_NV_texture_shader +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV +#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV +#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 +#define _ALLEGRO_GL_NV_texture_shader2 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 +#define _ALLEGRO_GL_NV_vertex_array_range2 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program +#define _ALLEGRO_GL_NV_vertex_program +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +#endif + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp +#define _ALLEGRO_GL_SGIX_texture_coordinate_clamp +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint +#define _ALLEGRO_GL_SGIX_scalebias_hint +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif + +#ifndef GL_OML_interlace +#define GL_OML_interlace +#define _ALLEGRO_GL_OML_interlace +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif + +#ifndef GL_OML_subsample +#define GL_OML_subsample +#define _ALLEGRO_GL_OML_subsample +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif + +#ifndef GL_OML_resample +#define GL_OML_resample +#define _ALLEGRO_GL_OML_resample +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color +#define _ALLEGRO_GL_NV_copy_depth_to_color +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap +#define _ALLEGRO_GL_ATI_envmap_bumpmap +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +#endif + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader +#define _ALLEGRO_GL_ATI_fragment_shader +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +#endif + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles +#define _ALLEGRO_GL_ATI_pn_triangles +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +#endif + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object +#define _ALLEGRO_GL_ATI_vertex_array_object +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +#endif + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader +#define _ALLEGRO_GL_EXT_vertex_shader +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +#endif + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams +#define _ALLEGRO_GL_ATI_vertex_streams +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +#endif + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array +#define _ALLEGRO_GL_ATI_element_array +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +#endif + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array +#define _ALLEGRO_GL_SUN_mesh_array +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +#endif + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum +#define _ALLEGRO_GL_SUN_slice_accum +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint +#define _ALLEGRO_GL_NV_multisample_filter_hint +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp +#define _ALLEGRO_GL_NV_depth_clamp +#define GL_DEPTH_CLAMP_NV 0x864F +#endif + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query +#define _ALLEGRO_GL_NV_occlusion_query +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +#endif + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite +#define _ALLEGRO_GL_NV_point_sprite +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +#endif + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 +#define _ALLEGRO_GL_NV_texture_shader3 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side +#define _ALLEGRO_GL_EXT_stencil_two_side +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#endif + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader +#define _ALLEGRO_GL_ATI_text_fragment_shader +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage +#define _ALLEGRO_GL_APPLE_client_storage +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array +#define _ALLEGRO_GL_APPLE_element_array +#define GL_ELEMENT_ARRAY_APPLE 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A +#endif + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence +#define _ALLEGRO_GL_APPLE_fence +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +#endif + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object +#define _ALLEGRO_GL_APPLE_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +#endif + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range +#define _ALLEGRO_GL_APPLE_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +#endif + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 +#define _ALLEGRO_GL_APPLE_ycbcr_422 +#define GL_YCBCR_422_APPLE 0x85B9 +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc +#define _ALLEGRO_GL_S3_s3tc +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#endif + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers +#define _ALLEGRO_GL_ATI_draw_buffers +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +#endif + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 +#define _ALLEGRO_GL_ATI_texture_env_combine3 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float +#define _ALLEGRO_GL_ATI_texture_float +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer +#define _ALLEGRO_GL_NV_float_buffer +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program +#define _ALLEGRO_GL_NV_fragment_program +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#endif + +#ifndef GL_NV_half_float +#define GL_NV_half_float +#define _ALLEGRO_GL_NV_half_float +typedef short GLhalfNV; +#define GL_HALF_FLOAT_NV 0x140B +#endif + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range +#define _ALLEGRO_GL_NV_pixel_data_range +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +#endif + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart +#define _ALLEGRO_GL_NV_primitive_restart +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +#endif + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal +#define _ALLEGRO_GL_NV_texture_expand_normal +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer +#define _ALLEGRO_GL_ATI_map_object_buffer +#endif + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#endif + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object +#define _ALLEGRO_GL_ATI_vertex_attrib_array_object +#endif + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates +#define _ALLEGRO_GL_OES_byte_coordinates +/* GL_BYTE */ +#endif + +#ifndef GL_OES_fixed_point +#define GL_OES_fixed_point +#define _ALLEGRO_GL_OES_fixed_point +typedef int GLfixed; +typedef int GLclampx; +#define GL_FIXED_OES 0x140C +#endif + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision +#define _ALLEGRO_GL_OES_single_precision +#endif + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture +#define _ALLEGRO_GL_OES_compressed_paletted_texture +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + +#ifndef GL_OES_read_format +#define GL_OES_read_format +#define _ALLEGRO_GL_OES_read_format +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif + +#ifndef GL_OES_query_matrix +#define GL_OES_query_matrix +#define _ALLEGRO_GL_OES_query_matrix +#endif + +#ifndef GL_OES_framebuffer_object +#define GL_OES_framebuffer_object +#define GL_FRAMEBUFFER_OES 0x8D40 +#define GL_RENDERBUFFER_OES 0x8D41 +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +#define GL_RGBA4_OES 0x8056 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB565_OES 0x8D62 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#define GL_STENCIL_INDEX8_OES 0x8D48 +#define GL_RENDERBUFFER_WIDTH_OES 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_OES 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE_OES 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_OES 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_OES 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_OES 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_OES 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +#define GL_COLOR_ATTACHMENT0_OES 0x8CE0 +#define GL_DEPTH_ATTACHMENT_OES 0x8D00 +#define GL_STENCIL_ATTACHMENT_OES 0x8D20 +#define GL_GL_NONE_OES 0 +#define GL_FRAMEBUFFER_COMPLETE_OES 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_OES 0x8CDD +#define GL_FRAMEBUFFER_BINDING_OES 0x8CA6 +#define GL_RENDERBUFFER_BINDING_OES 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506 +#endif + +#ifndef GL_OES_depth24 +#define GL_OES_depth24 +#define DEPTH_COMPONENT24_OES 0x81A6 +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test +#define _ALLEGRO_GL_EXT_depth_bounds_test +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +#endif + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp +#define _ALLEGRO_GL_EXT_texture_mirror_clamp +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate +#define _ALLEGRO_GL_EXT_blend_equation_separate +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 /* Same as GL_BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +#endif + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert +#define _ALLEGRO_GL_MESA_pack_invert +#define GL_PACK_INVERT_MESA 0x8758 +#endif + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture +#define _ALLEGRO_GL_MESA_ycbcr_texture +#define GL_YCBCR_MESA 0x8757 +/* Same as GL_UNSIGNED_SHORT_8_8_APPLE and GL_UNSIGNED_SHORT_8_8_REV_APPLE */ +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#endif + + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object +#define _ALLEGRO_GL_EXT_pixel_buffer_object +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif + + + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option +#define _ALLEGRO_GL_NV_fragment_program_option +#endif + + + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 +#define _ALLEGRO_GL_NV_fragment_program2 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif + + + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option +#define _ALLEGRO_GL_NV_vertex_program2_option +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#endif + + + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 +#define _ALLEGRO_GL_NV_vertex_program3 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#endif + + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 +#define _ALLEGRO_GL_EXT_texture_compression_dxt1 +#ifndef ALLEGRO_GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif +#endif + + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object +#define _ALLEGRO_GL_EXT_framebuffer_object +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_STENCIL_INDEX_EXT 0x8D45 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_FRAMEBUFFER_STATUS_ERROR_EXT 0x8CDE +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#endif + + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker +#define _ALLEGRO_GL_GREMEDY_string_marker +#endif + + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil +#define _ALLEGRO_GL_EXT_packed_depth_stencil +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#endif + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag +#define _ALLEGRO_GL_EXT_stencil_clear_tag +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +#endif + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB +#define _ALLEGRO_GL_EXT_texture_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit +#define _ALLEGRO_GL_EXT_framebuffer_blit +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CAA +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample +#define _ALLEGRO_GL_EXT_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack +#define _ALLEGRO_GL_MESAX_texture_stack +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#endif + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query +#define _ALLEGRO_GL_EXT_timer_query +#if (defined _MSC_VER) && (_MSC_VER < 1400) +typedef __int64 GLint64EXT; +typedef unsigned __int64 GLuint64EXT; +#else +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif +#define GL_TIME_ELAPSED_EXT 0x88BF +#endif + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters +#define _ALLEGRO_GL_EXT_gpu_program_parameters +#endif + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range +#define _ALLEGRO_GL_APPLE_flush_buffer_range +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform +#define _ALLEGRO_GL_EXT_bindable_uniform +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#endif + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 +#define _ALLEGRO_GL_EXT_draw_buffers2 +#endif + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced +#define _ALLEGRO_GL_EXT_draw_instanced +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB +#define _ALLEGRO_GL_EXT_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 +#define _ALLEGRO_GL_EXT_geometry_shader4 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 +#define _ALLEGRO_GL_EXT_gpu_shader4 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +#endif + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float +#define _ALLEGRO_GL_EXT_packed_float +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array +#define _ALLEGRO_GL_EXT_texture_array +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object +#define _ALLEGRO_GL_EXT_texture_buffer_object +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc +#define _ALLEGRO_GL_EXT_texture_compression_latc +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc +#define _ALLEGRO_GL_EXT_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer +#define _ALLEGRO_GL_EXT_texture_integer +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent +#define _ALLEGRO_GL_EXT_texture_shared_exponent +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float +#define _ALLEGRO_GL_NV_depth_buffer_float +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#endif + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 +#define _ALLEGRO_GL_NV_fragment_program4 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage +#define _ALLEGRO_GL_NV_framebuffer_multisample_coverage +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 +#define _ALLEGRO_GL_NV_geometry_program4 +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#if !defined GL_EXT_geometry_shader4 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_LINES_ADJACENCY_EXT 0xA +#define GL_LINE_STRIP_ADJACENCY_EXT 0xB +#define GL_TRIANGLES_ADJACENCY_EXT 0xC +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 +#define _ALLEGRO_GL_NV_gpu_program4 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#endif + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object +#define _ALLEGRO_GL_NV_parameter_buffer_object +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +#endif + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback +#define _ALLEGRO_GL_NV_transform_feedback +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#if !defined GL_NV_register_combiners +#define GL_SECONDARY_COLOR_NV 0x852D +#endif +#if !defined GL_EXT_gpu_shader4 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#endif +#endif + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 +#define _ALLEGRO_GL_NV_vertex_program4 +#if !defined GL_EXT_vertex_shader4 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#endif +#endif + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator +#define _ALLEGRO_GL_GREMEDY_frame_terminator +#endif + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render +#define _ALLEGRO_GL_NV_conditional_render +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +#endif + +#ifndef GL_NV_present_video +#define GL_NV_present_video +#define _ALLEGRO_GL_NV_present_video +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B +#endif + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback +#define _ALLEGRO_GL_EXT_transform_feedback +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +#endif + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access +#define _ALLEGRO_GL_EXT_direct_state_access +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +#endif + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle +#define _ALLEGRO_GL_EXT_texture_swizzle +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 +#endif + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample +#define _ALLEGRO_GL_NV_explicit_multisample +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#endif + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 +#define _ALLEGRO_GL_NV_transform_feedback2 +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 +#endif + +#ifndef GL_ATI_meminfo +#define GL_ATI_meminfo +#define _ALLEGRO_GL_ATI_meminfo +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD +#endif + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor +#define _ALLEGRO_GL_AMD_performance_monitor +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +#endif + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 +#define _ALLEGRO_GL_AMD_texture_texture4 +#endif + +#ifndef GL_AMD_vertex_shader_tesselator +#define GL_AMD_vertex_shader_tesselator +#define _ALLEGRO_GL_AMD_vertex_shader_tesselator +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_DISCRETE_AMD 0x9006 +#define GL_CONTINUOUS_AMD 0x9007 +#endif + +#ifndef GL_EXT_provoking_vertex +#define GL_EXT_provoking_vertex +#define _ALLEGRO_GL_EXT_provoking_vertex +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_PROVOKING_VERTEX_EXT 0x8E4F +#endif + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm +#define _ALLEGRO_GL_EXT_texture_snorm +#define GL_ALPHA_SNORM 0x9010 +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_ALPHA8_SNORM 0x9014 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_ALPHA16_SNORM 0x9018 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_INTENSITY16_SNORM 0x901B +/* reuse GL_RED_SNORM */ +/* reuse GL_RG_SNORM */ +/* reuse GL_RGB_SNORM */ +/* reuse GL_RGBA_SNORM */ +/* reuse GL_R8_SNORM */ +/* reuse GL_RG8_SNORM */ +/* reuse GL_RGB8_SNORM */ +/* reuse GL_RGBA8_SNORM */ +/* reuse GL_R16_SNORM */ +/* reuse GL_RG16_SNORM */ +/* reuse GL_RGB16_SNORM */ +/* reuse GL_RGBA16_SNORM */ +/* reuse GL_SIGNED_NORMALIZED */ +#endif + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend +#define _ALLEGRO_GL_AMD_draw_buffers_blend +#endif + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range +#define _ALLEGRO_GL_APPLE_texture_range +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +/* reuse GL_STORAGE_CACHED_APPLE */ +/* reuse GL_STORAGE_SHARED_APPLE */ +#endif + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels +#define _ALLEGRO_GL_APPLE_float_pixels +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F +#endif + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators +#define _ALLEGRO_GL_APPLE_vertex_program_evaluators +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 +#endif + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil +#define _ALLEGRO_GL_APPLE_aux_depth_stencil +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 +#endif + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable +#define _ALLEGRO_GL_APPLE_object_purgeable +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D +#endif + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes +#define _ALLEGRO_GL_APPLE_row_bytes +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 +#endif + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 +#define _ALLEGRO_GL_APPLE_rgb_422 +#define GL_RGB_422_APPLE 0x8A1F +/* reuse GL_UNSIGNED_SHORT_8_8_APPLE */ +/* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */ +#endif + +#ifndef GL_NV_video_capture +#define GL_NV_video_capture +#define _ALLEGRO_GL_NV_video_capture +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_SUCCESS_NV 0x902F +#define GL_FAILURE_NV 0x9030 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C +#endif + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects +#define _ALLEGRO_GL_EXT_separate_shader_objects +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D +#endif + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 +#define _ALLEGRO_GL_NV_parameter_buffer_object2 +#endif + +#ifndef GL_NV_shader_buffer_load +#define GL_NV_shader_buffer_load +#define _ALLEGRO_GL_NV_shader_buffer_load +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 +#endif + +#ifndef GL_NV_vertex_buffer_unified_memory +#define GL_NV_vertex_buffer_unified_memory +#define _ALLEGRO_GL_NV_vertex_buffer_unified_memory +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#endif + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier +#define _ALLEGRO_GL_NV_texture_barrier +#endif + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export +#define _ALLEGRO_GL_AMD_shader_stencil_export +#endif + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture +#define _ALLEGRO_GL_AMD_seamless_cubemap_per_texture +/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS_ARB */ +#endif + +#ifndef GL_AMD_conservative_depth +#define GL_AMD_conservative_depth +#define _ALLEGRO_GL_AMD_conservative_depth +#endif diff --git a/allegro/include/allegro5/opengl/GLext/gl_ext_list.h b/allegro/include/allegro5/opengl/GLext/gl_ext_list.h new file mode 100644 index 00000000..e4e4b342 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/gl_ext_list.h @@ -0,0 +1,359 @@ +AGL_EXT(ARB_imaging, 0) +AGL_EXT(ARB_multitexture, 1_2_1) +AGL_EXT(ARB_transpose_matrix, 1_3) +AGL_EXT(ARB_multisample, 1_3) +AGL_EXT(ARB_texture_env_add, 1_3) +AGL_EXT(ARB_texture_cube_map, 1_3) +AGL_EXT(ARB_texture_compression, 1_3) +AGL_EXT(ARB_texture_border_clamp, 1_3) +AGL_EXT(ARB_point_parameters, 1_4) +AGL_EXT(ARB_vertex_blend, 0) +AGL_EXT(ARB_texture_env_combine, 1_3) +AGL_EXT(ARB_texture_env_crossbar, 1_4) +AGL_EXT(ARB_texture_env_dot3, 1_3) +AGL_EXT(ARB_texture_mirrored_repeat, 1_4) +AGL_EXT(ARB_depth_texture, 1_4) +AGL_EXT(ARB_shadow, 1_4) +AGL_EXT(ARB_shadow_ambient, 0) +AGL_EXT(ARB_window_pos, 1_4) +AGL_EXT(ARB_vertex_program, 0) +AGL_EXT(ARB_fragment_program, 0) +AGL_EXT(ARB_vertex_buffer_object, 1_5) +AGL_EXT(ARB_occlusion_query, 1_5) +AGL_EXT(ARB_shader_objects, 0) /* Those were promoted to Core in */ +AGL_EXT(ARB_vertex_shader, 0) /* 2.0 with modifications. */ +AGL_EXT(ARB_fragment_shader, 0) /* */ +AGL_EXT(ARB_shading_language_100, 0) /* */ +AGL_EXT(ARB_texture_non_power_of_two,2_0) +AGL_EXT(ARB_point_sprite, 2_0) +AGL_EXT(ARB_fragment_program_shadow, 0) +AGL_EXT(ARB_draw_buffers, 2_0) +AGL_EXT(ARB_texture_rectangle, 3_1) +AGL_EXT(ARB_color_buffer_float, 3_0) +AGL_EXT(ARB_half_float_pixel, 3_0) +AGL_EXT(ARB_texture_float, 3_0) +AGL_EXT(ARB_pixel_buffer_object, 2_1) +AGL_EXT(ARB_instanced_arrays, 0) +AGL_EXT(ARB_draw_instanced, 3_1) +AGL_EXT(ARB_geometry_shader4, 0) +AGL_EXT(ARB_texture_buffer_object, 3_1) +AGL_EXT(ARB_depth_buffer_float, 3_0) +AGL_EXT(ARB_framebuffer_object, 3_0) +AGL_EXT(ARB_framebuffer_sRGB, 3_0) +AGL_EXT(ARB_half_float_vertex, 3_0) +AGL_EXT(ARB_map_buffer_range, 3_0) +AGL_EXT(ARB_texture_compression_rgtc,3_0) +AGL_EXT(ARB_texture_rg, 3_0) +AGL_EXT(ARB_vertex_array_object, 3_0) +AGL_EXT(ARB_copy_buffer, 3_1) +AGL_EXT(ARB_compatibility, 0) +AGL_EXT(ARB_uniform_buffer_object, 3_1) +AGL_EXT(ARB_shader_texture_lod, 0) +AGL_EXT(ARB_depth_clamp, 3_2) +AGL_EXT(ARB_draw_elements_base_vertex, 3_2) +AGL_EXT(ARB_fragment_coord_conventions, 3_2) +AGL_EXT(ARB_provoking_vertex, 3_2) +AGL_EXT(ARB_seamless_cube_map, 3_2) +AGL_EXT(ARB_sync, 3_2) +AGL_EXT(ARB_texture_multisample, 3_2) +AGL_EXT(ARB_vertex_array_bgra, 0) +AGL_EXT(ARB_draw_buffers_blend, 0) +AGL_EXT(ARB_sample_shading, 0) +AGL_EXT(ARB_texture_cube_map_array, 0) +AGL_EXT(ARB_texture_gather, 0) +AGL_EXT(ARB_texture_query_lod, 0) +AGL_EXT(ARB_shading_language_include, 0) +AGL_EXT(ARB_texture_compression_bptc, 0) +AGL_EXT(ARB_blend_func_extended, 3_3) +AGL_EXT(ARB_explicit_attrib_location, 3_3) +AGL_EXT(ARB_occlusion_query2, 3_3) +AGL_EXT(ARB_sampler_objects, 3_3) +AGL_EXT(ARB_shader_bit_encoding, 3_3) +AGL_EXT(ARB_texture_rgb10_a2ui, 3_3) +AGL_EXT(ARB_texture_swizzle, 3_3) +AGL_EXT(ARB_timer_query, 3_3) +AGL_EXT(ARB_vertex_type_2_10_10_10_rev, 3_3) +AGL_EXT(ARB_draw_indirect, 4_0) +AGL_EXT(ARB_gpu_shader5, 4_0) +AGL_EXT(ARB_gpu_shader_fp64, 4_0) +AGL_EXT(ARB_shader_subroutine, 4_0) +AGL_EXT(ARB_tessellation_shader, 4_0) +AGL_EXT(ARB_texture_buffer_object_rgb32, 4_0) +AGL_EXT(ARB_transform_feedback2, 4_0) +AGL_EXT(ARB_transform_feedback3, 4_0) + +AGL_EXT(EXT_abgr, 0) +AGL_EXT(EXT_blend_color, 1_1) +AGL_EXT(EXT_polygon_offset, 1_1) +AGL_EXT(EXT_texture, 1_1) +AGL_EXT(EXT_texture3D, 1_2) +AGL_EXT(SGIS_texture_filter4, 0) +AGL_EXT(EXT_subtexture, 1_1) +AGL_EXT(EXT_copy_texture, 1_1) +AGL_EXT(EXT_histogram, 0) +AGL_EXT(EXT_convolution, 0) +AGL_EXT(SGI_color_matrix, 0) +AGL_EXT(SGI_color_table, 0) +AGL_EXT(SGIS_pixel_texture, 0) +AGL_EXT(SGIX_pixel_texture, 0) +AGL_EXT(SGIS_texture4D, 0) +AGL_EXT(SGI_texture_color_table, 0) +AGL_EXT(EXT_cmyka, 0) +AGL_EXT(EXT_texture_object, 1_1) +AGL_EXT(SGIS_detail_texture, 0) +AGL_EXT(SGIS_sharpen_texture, 0) +AGL_EXT(EXT_packed_pixels, 1_2) +AGL_EXT(SGIS_texture_lod, 1_2) +AGL_EXT(SGIS_multisample, 1_3) +AGL_EXT(EXT_rescale_normal, 1_2) +AGL_EXT(EXT_vertex_array, 1_1) +AGL_EXT(EXT_misc_attribute, 0) +AGL_EXT(SGIS_generate_mipmap, 1_4) +AGL_EXT(SGIX_clipmap, 0) +AGL_EXT(SGIX_shadow, 0) +AGL_EXT(SGIS_texture_edge_clamp, 1_2) +AGL_EXT(SGIS_texture_border_clamp, 0) +AGL_EXT(EXT_blend_minmax, 0) +AGL_EXT(EXT_blend_subtract, 0) +AGL_EXT(EXT_blend_logic_op, 1_1) +AGL_EXT(SGIX_interlace, 0) +AGL_EXT(SGIS_texture_select, 0) +AGL_EXT(SGIX_sprite, 0) +AGL_EXT(SGIX_texture_multi_buffer, 0) +AGL_EXT(EXT_point_parameters, 0) +AGL_EXT(SGIX_instruments, 0) +AGL_EXT(SGIX_texture_scale_bias, 0) +AGL_EXT(SGIX_framezoom, 0) +AGL_EXT(SGIX_tag_sample_buffer, 0) +AGL_EXT(SGIX_reference_plane, 0) +AGL_EXT(SGIX_flush_raster, 0) +AGL_EXT(SGIX_depth_texture, 0) +AGL_EXT(SGIS_fog_function, 0) +AGL_EXT(SGIX_fog_offset, 0) +AGL_EXT(HP_image_transform, 0) +AGL_EXT(HP_convolution_border_modes, 0) +AGL_EXT(SGIX_texture_add_env, 0) +AGL_EXT(EXT_color_subtable, 0) +AGL_EXT(PGI_vertex_hints, 0) +AGL_EXT(PGI_misc_hints, 0) +AGL_EXT(EXT_paletted_texture, 0) +AGL_EXT(EXT_clip_volume_hint, 0) +AGL_EXT(SGIX_list_priority, 0) +AGL_EXT(SGIX_ir_instrument1, 0) +AGL_EXT(SGIX_texture_lod_bias, 0) +AGL_EXT(SGIX_shadow_ambient, 0) +AGL_EXT(EXT_index_texture, 0) +AGL_EXT(EXT_index_material, 0) +AGL_EXT(EXT_index_func, 0) +AGL_EXT(EXT_index_array_formats, 0) +AGL_EXT(EXT_compiled_vertex_array, 0) +AGL_EXT(EXT_cull_vertex, 0) +AGL_EXT(SGIX_ycrcb, 0) +AGL_EXT(EXT_fragment_lighting, 0) +AGL_EXT(IBM_rasterpos_clip, 0) +AGL_EXT(HP_texture_lighting, 0) +AGL_EXT(EXT_draw_range_elements, 0) +AGL_EXT(WIN_phong_shading, 0) +AGL_EXT(WIN_specular_fog, 0) +AGL_EXT(EXT_light_texture, 0) +AGL_EXT(SGIX_blend_alpha_minmax, 0) +AGL_EXT(EXT_scene_marker, 0) +AGL_EXT(SGIX_pixel_texture_bits, 0) +AGL_EXT(EXT_bgra, 1_2) +AGL_EXT(SGIX_async, 0) +AGL_EXT(SGIX_async_pixel, 0) +AGL_EXT(SGIX_async_histogram, 0) +AGL_EXT(INTEL_texture_scissor, 0) +AGL_EXT(INTEL_parallel_arrays, 0) +AGL_EXT(HP_occlusion_test, 0) +AGL_EXT(EXT_pixel_transform, 0) +AGL_EXT(EXT_pixel_transform_color_table, 0) +AGL_EXT(EXT_shared_texture_palette, 0) +AGL_EXT(EXT_separate_specular_color, 1_2) +AGL_EXT(EXT_secondary_color, 1_4) +AGL_EXT(EXT_texture_env, 0) +AGL_EXT(EXT_texture_perturb_normal, 0) +AGL_EXT(EXT_multi_draw_arrays, 1_4) +AGL_EXT(EXT_fog_coord, 1_4) +AGL_EXT(REND_screen_coordinates, 0) +AGL_EXT(EXT_coordinate_frame, 0) +AGL_EXT(EXT_texture_env_combine, 0) +AGL_EXT(APPLE_specular_vector, 0) +AGL_EXT(APPLE_transform_hint, 0) +AGL_EXT(SUNX_constant_data, 0) +AGL_EXT(SUN_global_alpha, 0) +AGL_EXT(SUN_triangle_list, 0) +AGL_EXT(SUN_vertex, 0) +AGL_EXT(EXT_blend_func_separate, 1_4) +AGL_EXT(INGR_color_clamp, 0) +AGL_EXT(INGR_interlace_read, 0) +AGL_EXT(EXT_stencil_wrap, 1_4) +AGL_EXT(EXT_422_pixels, 0) +AGL_EXT(NV_texgen_reflection, 0) +AGL_EXT(SGIX_texture_range, 0) +AGL_EXT(SUN_convolution_border_modes, 0) +AGL_EXT(EXT_texture_env_add, 0) +AGL_EXT(EXT_texture_lod_bias, 1_4) +AGL_EXT(EXT_texture_filter_anisotropic, 0) +AGL_EXT(EXT_vertex_weighting, 0) +AGL_EXT(NV_light_max_exponent, 0) +AGL_EXT(NV_vertex_array_range, 0) +AGL_EXT(NV_register_combiners, 0) +AGL_EXT(NV_fog_distance, 0) +AGL_EXT(NV_texgen_emboss, 0) +AGL_EXT(NV_blend_square, 1_4) +AGL_EXT(NV_texture_env_combine4, 0) +AGL_EXT(MESA_resize_buffers, 0) +AGL_EXT(MESA_window_pos, 0) +AGL_EXT(EXT_texture_compression_s3tc, 0) +AGL_EXT(IBM_cull_vertex, 0) +AGL_EXT(IBM_multimode_draw_arrays, 0) +AGL_EXT(IBM_vertex_array_lists, 0) +AGL_EXT(3DFX_texture_compression_FXT1, 0) +AGL_EXT(3DFX_multisample, 0) +AGL_EXT(3DFX_tbuffer, 0) +AGL_EXT(SGIX_vertex_preclip, 0) +AGL_EXT(SGIX_resample, 0) +AGL_EXT(SGIS_texture_color_mask, 0) +AGL_EXT(EXT_texture_env_dot3, 0) +AGL_EXT(ATI_texture_mirror_once, 0) +AGL_EXT(NV_fence, 0) +AGL_EXT(IBM_static_data, 0) +AGL_EXT(IBM_texture_mirrored_repeat, 0) +AGL_EXT(NV_evaluators, 0) +AGL_EXT(NV_packed_depth_stencil, 3_0) +AGL_EXT(NV_register_combiners2, 0) +AGL_EXT(NV_texture_compression_vtc, 0) +AGL_EXT(NV_texture_rectangle, 0) +AGL_EXT(NV_texture_shader, 0) +AGL_EXT(NV_texture_shader2, 0) +AGL_EXT(NV_vertex_array_range2, 0) +AGL_EXT(NV_vertex_program, 0) +AGL_EXT(SGIX_texture_coordinate_clamp, 0) +AGL_EXT(OML_interlace, 0) +AGL_EXT(OML_subsample, 0) +AGL_EXT(OML_resample, 0) +AGL_EXT(NV_copy_depth_to_color, 0) +AGL_EXT(ATI_envmap_bumpmap, 0) +AGL_EXT(ATI_fragment_shader, 0) +AGL_EXT(ATI_pn_triangles, 0) +AGL_EXT(ATI_vertex_array_object, 0) +AGL_EXT(EXT_vertex_shader, 0) +AGL_EXT(ATI_vertex_streams, 0) +AGL_EXT(ATI_element_array, 0) +AGL_EXT(SUN_mesh_array, 0) +AGL_EXT(SUN_slice_accum, 0) +AGL_EXT(NV_multisample_filter_hint, 0) +AGL_EXT(NV_depth_clamp, 0) +AGL_EXT(NV_occlusion_query, 0) +AGL_EXT(NV_point_sprite, 0) +AGL_EXT(NV_texture_shader3, 0) +AGL_EXT(NV_vertex_program1_1, 0) +AGL_EXT(EXT_shadow_funcs, 1_5) +AGL_EXT(EXT_stencil_two_side, 0) +AGL_EXT(ATI_text_fragment_shader, 0) +AGL_EXT(APPLE_client_storage, 0) +AGL_EXT(APPLE_element_array, 0) +AGL_EXT(APPLE_fence, 0) +AGL_EXT(APPLE_vertex_array_object, 3_0) +AGL_EXT(APPLE_vertex_array_range, 0) +AGL_EXT(APPLE_ycbcr_422, 0) +AGL_EXT(S3_s3tc, 0) +AGL_EXT(ATI_draw_buffers, 0) +AGL_EXT(ATI_texture_env_combine3, 0) +AGL_EXT(ATI_texture_float, 0) +AGL_EXT(NV_float_buffer, 0) +AGL_EXT(NV_fragment_program, 0) +AGL_EXT(NV_half_float, 3_0) +AGL_EXT(NV_pixel_data_range, 0) +AGL_EXT(NV_primitive_restart, 3_1) +AGL_EXT(NV_texture_expand_normal, 0) +AGL_EXT(NV_vertex_program2, 0) +AGL_EXT(ATI_map_object_buffer, 0) +AGL_EXT(ATI_separate_stencil, 2_0) +AGL_EXT(ATI_vertex_attrib_array_object, 0) +AGL_EXT(OES_byte_coordinates, 0) +AGL_EXT(OES_fixed_point, 0) +AGL_EXT(OES_single_precision, 0) +AGL_EXT(OES_compressed_paletted_texture, 0) +AGL_EXT(OES_read_format, 0) +AGL_EXT(OES_query_matrix, 0) +AGL_EXT(OES_framebuffer_object, 0) +AGL_EXT(OES_texture_npot, 0) +AGL_EXT(EXT_depth_bounds_test, 0) +AGL_EXT(EXT_texture_mirror_clamp, 0) +AGL_EXT(EXT_blend_equation_separate, 0) +AGL_EXT(MESA_pack_invert, 0) +AGL_EXT(MESA_ycbcr_texture, 0) +AGL_EXT(EXT_pixel_buffer_object, 0) +AGL_EXT(NV_fragment_program_option, 0) +AGL_EXT(NV_fragment_program2, 0) +AGL_EXT(NV_vertex_program2_option, 0) +AGL_EXT(NV_vertex_program3, 0) +AGL_EXT(EXT_texture_compression_dxt1, 0) +AGL_EXT(EXT_framebuffer_object, 3_0) +AGL_EXT(GREMEDY_string_marker, 0) +AGL_EXT(EXT_packed_depth_stencil, 0) +AGL_EXT(EXT_stencil_clear_tag, 0) +AGL_EXT(EXT_texture_sRGB, 2_1) +AGL_EXT(EXT_framebuffer_blit, 3_0) +AGL_EXT(EXT_framebuffer_multisample, 3_0) +AGL_EXT(MESAX_texture_stack, 0) +AGL_EXT(EXT_timer_query, 0) +AGL_EXT(EXT_gpu_program_parameters, 0) +AGL_EXT(APPLE_flush_buffer_range, 0) +#ifdef ALLEGRO_MACOSX +AGL_EXT(EXT_texture_rectangle, 0) +#endif +AGL_EXT(EXT_bindable_uniform, 0) +AGL_EXT(EXT_draw_buffers2, 3_0) +AGL_EXT(EXT_draw_instanced, 0) +AGL_EXT(EXT_framebuffer_sRGB, 3_0) +AGL_EXT(EXT_geometry_shader4, 0) +AGL_EXT(EXT_gpu_shader4, 3_0) +AGL_EXT(EXT_packed_float, 3_0) +AGL_EXT(EXT_texture_array, 3_0) +AGL_EXT(EXT_texture_buffer_object, 0) +AGL_EXT(EXT_texture_compression_latc, 0) +AGL_EXT(EXT_texture_compression_rgtc,3_0) +AGL_EXT(EXT_texture_integer, 3_0) +AGL_EXT(EXT_texture_shared_exponent, 3_0) +AGL_EXT(NV_depth_buffer_float, 3_0) +AGL_EXT(NV_fragment_program4, 0) +AGL_EXT(NV_framebuffer_multisample_coverage, 0) +AGL_EXT(NV_geometry_program4, 0) +AGL_EXT(NV_gpu_program4, 0) +AGL_EXT(NV_parameter_buffer_object, 0) +AGL_EXT(NV_transform_feedback, 0) +AGL_EXT(NV_vertex_program4, 0) +AGL_EXT(GREMEDY_frame_terminator, 0) +AGL_EXT(NV_conditional_render, 3_0) +AGL_EXT(NV_present_video, 0) +AGL_EXT(EXT_direct_state_access, 0) +AGL_EXT(EXT_transform_feedback, 3_0) +AGL_EXT(EXT_texture_swizzle, 0) +AGL_EXT(NV_explicit_multisample, 0) +AGL_EXT(NV_transform_feedback2, 0) +AGL_EXT(ATI_meminfo, 0) +AGL_EXT(AMD_performance_monitor, 0) +AGL_EXT(AMD_texture_texture4, 0) +AGL_EXT(AMD_vertex_shader_tesselator, 0) +AGL_EXT(EXT_provoking_vertex, 0) +AGL_EXT(EXT_texture_snorm, 0) +AGL_EXT(AMD_draw_buffers_blend, 0) +AGL_EXT(APPLE_texture_range, 0) +AGL_EXT(APPLE_float_pixels, 0) +AGL_EXT(APPLE_vertex_program_evaluators, 0) +AGL_EXT(APPLE_aux_depth_stencil, 0) +AGL_EXT(APPLE_object_purgeable, 0) +AGL_EXT(APPLE_row_bytes, 0) +AGL_EXT(APPLE_rgb_422, 0) +AGL_EXT(NV_video_capture, 0) +AGL_EXT(EXT_separate_shader_objects, 0) +AGL_EXT(NV_parameter_buffer_object2, 0) +AGL_EXT(NV_shader_buffer_load, 0) +AGL_EXT(NV_vertex_buffer_unified_memory, 0) +AGL_EXT(NV_texture_barrier, 0) +AGL_EXT(AMD_shader_stencil_export, 0) +AGL_EXT(AMD_seamless_cubemap_per_texture, 0) +AGL_EXT(AMD_conservative_depth, 0) diff --git a/allegro/include/allegro5/opengl/GLext/glx_ext_alias.h b/allegro/include/allegro5/opengl/GLext/glx_ext_alias.h new file mode 100644 index 00000000..0194ccba --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/glx_ext_alias.h @@ -0,0 +1,217 @@ +/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ +#ifdef _ALLEGRO_GLX_VERSION_1_3 +/*GLX1.3*/ +#define glXGetFBConfigs _al_glXGetFBConfigs +#define glXChooseFBConfig _al_glXChooseFBConfig +#define glXGetFBConfigAttrib _al_glXGetFBConfigAttrib +#define glXGetVisualFromFBConfig _al_glXGetVisualFromFBConfig +#define glXCreateWindow _al_glXCreateWindow +#define glXDestroyWindow _al_glXDestroyWindow +#define glXCreatePixmap _al_glXCreatePixmap +#define glXDestroyPixmap _al_glXDestroyPixmap +#define glXCreatePbuffer _al_glXCreatePbuffer +#define glXDestroyPbuffer _al_glXDestroyPbuffer +#define glXQueryDrawable _al_glXQueryDrawable +#define glXCreateNewContext _al_glXCreateNewContext +#define glXMakeContextCurrent _al_glXMakeContextCurrent +#define glXGetCurrentReadDrawable _al_glXGetCurrentReadDrawable +#define glXGetCurrentDisplay _al_glXGetCurrentDisplay +#define glXQueryContext _al_glXQueryContext +#define glXSelectEvent _al_glXSelectEvent +#define glXGetSelectedEvent _al_glXGetSelectedEvent +#endif +#ifdef _ALLEGRO_GLX_VERSION_1_4 +/*GLX1.4*/ +#define glXGetProcAddress _al_glXGetProcAddress +#endif + +#ifdef _ALLEGRO_GLX_ARB_get_proc_address +/*GLX_ARB_get_proc_address*/ +#define glXGetProcAddressARB _al_glXGetProcAddressARB +#endif + +#ifdef _ALLEGRO_GLX_ARB_create_context +#define glXCreateContextAttribsARB _al_glXCreateContextAttribsARB +#endif + +#ifdef _ALLEGRO_GLX_SGI_swap_control +/*GLX_SGI_swap_control*/ +#define glXSwapIntervalSGI _al_glXSwapIntervalSGI +#endif + +#ifdef _ALLEGRO_GLX_SGI_video_sync +/*GLX_SGI_video_sync*/ +#define glXGetVideoSyncSGI _al_glXGetVideoSyncSGI +#define glXWaitVideoSyncSGI _al_glXWaitVideoSyncSGI +#endif + +#ifdef _ALLEGRO_GLX_SGI_make_current_read +/*GLX_SGI_make_current_read*/ +#define glXMakeCurrentReadSGI _al_glXMakeCurrentReadSGI +#define glXGetCurrentReadDrawableSGI _al_glXGetCurrentReadDrawableSGI +#endif + +#ifdef _ALLEGRO_GLX_SGIX_video_source +/*GLX_SGIX_video_source*/ +/*ThisoneneedsSGI'sheaderfiletobeincludedfirst*/ +#ifdef _VL_H_ +#define glXCreateGLXVideoSourceSGIX _al_glXCreateGLXVideoSourceSGIX +#define glXDestroyGLXVideoSourceSGIX _al_glXDestroyGLXVideoSourceSGIX +#endif +#endif + +#ifdef _ALLEGRO_GLX_EXT_import_context +/*GLX_EXT_import_context*/ +#define glXGetCurrentDisplayEXT _al_glXGetCurrentDisplayEXT +#define glXQueryContextInfoEXT _al_glXQueryContextInfoEXT +#define glXGetContextIDEXT _al_glXGetContextIDEXT +#define glXImportContextEXT _al_glXImportContextEXT +#define glXFreeContextEXT _al_glXFreeContextEXT +#endif + +#ifdef _ALLEGRO_GLX_SGIX_fbconfig +/*GLX_SGIX_fbconfig*/ +#define glXGetFBConfigAttribSGIX _al_glXGetFBConfigAttribSGIX +#define glXChooseFBConfigSGIX _al_glXChooseFBConfigSGIX +#define glXCreateGLXPixmapWithConfigSGIX _al_glXCreateGLXPixmapWithConfigSGIX +#define glXCreateContextWithConfigSGIX _al_glXCreateContextWithConfigSGIX +#define glXGetVisualFromFBConfigSGIX _al_glXGetVisualFromFBConfigSGIX +#define glXGetFBConfigFromVisualSGIX _al_glXGetFBConfigFromVisualSGIX +#endif + +#ifdef _ALLEGRO_GLX_SGIX_pbuffer +/*GLX_SGIX_pbuffer*/ +#define glXCreateGLXPbufferSGIX _al_glXCreateGLXPbufferSGIX +#define glXDestroyGLXPbufferSGIX _al_glXDestroyGLXPbufferSGIX +#define glXQueryGLXPbufferSGIX _al_glXQueryGLXPbufferSGIX +#define glXSelectEventSGIX _al_glXSelectEventSGIX +#define glXGetSelectedEventSGIX _al_glXGetSelectedEventSGIX +#endif + +#ifdef _ALLEGRO_GLX_SGI_cushion +/*GLX_SGI_cushion*/ +#define glXCushionSGI _al_glXCushionSGI +#endif + +#ifdef _ALLEGRO_GLX_SGIX_video_resize +/*GLX_SGIX_video_resize*/ +#define glXBindChannelToWindowSGIX _al_glXBindChannelToWindowSGIX +#define glXChannelRectSGIX _al_glXChannelRectSGIX +#define glXQueryChannelRectSGIX _al_glXQueryChannelRectSGIX +#define glXQueryChannelDeltasSGIX _al_glXQueryChannelDeltasSGIX +#define glXChannelRectSyncSGIX _al_glXChannelRectSyncSGIX +#endif + +#ifdef _ALLEGRO_GLX_SGIX_dmbuffer +/*GLX_SGIX_dmbuffer*/ +/*ThisoneneedsSGI'sheaderfiletobeincludedfirst*/ +#ifdef _DM_BUFFER_H_ +#define glXAssociateDMPbufferSGIX _al_glXAssociateDMPbufferSGIX +#endif +#endif + +#ifdef _ALLEGRO_GLX_SGIX_swap_group +/*GLX_SGIX_swap_group*/ +#define glXJoinSwapGroupSGIX _al_glXJoinSwapGroupSGIX +#endif + +#ifdef _ALLEGRO_GLX_SGIX_swap_barrier +/*GLX_SGIX_swap_barrier*/ +#define glXBindSwapBarrierSGIX _al_glXBindSwapBarrierSGIX +#define glXQueryMaxSwapBarriersSGIX _al_glXQueryMaxSwapBarriersSGIX +#endif + +#ifdef _ALLEGRO_GLX_SUN_get_transparent_index +/*GLX_SUN_get_transparent_index*/ +#define glXGetTransparentIndexSUN _al_glXGetTransparentIndexSUN +#endif + +#ifdef _ALLEGRO_GLX_MESA_copy_sub_buffer +/*GLX_MESA_copy_sub_buffer*/ +#define glXCopySubBufferMESA _al_glXCopySubBufferMESA +#endif + +#ifdef _ALLEGRO_GLX_MESA_pixmap_colormap +/*GLX_MESA_pixmap_colormap*/ +#define glXCreateGLXPixmapMESA _al_glXCreateGLXPixmapMESA +#endif + +#ifdef _ALLEGRO_GLX_MESA_release_buffers +/*GLX_MESA_release_buffers*/ +#define glXReleaseBuffersMESA _al_glXReleaseBuffersMESA +#endif + +#ifdef _ALLEGRO_GLX_MESA_set_3dfx_mode +/*GLX_MESA_set_3dfx_mode*/ +#define glXSet3DfxModeMESA _al_glXSet3DfxModeMESA +#endif + +#ifdef _ALLEGRO_GLX_OML_sync_control +/*GLX_OML_sync_control*/ +#define glXGetSyncValuesOML _al_glXGetSyncValuesOML +#define glXGetMscRateOML _al_glXGetMscRateOML +#define glXSwapBuffersMscOML _al_glXSwapBuffersMscOML +#define glXWaitForMscOML _al_glXWaitForMscOML +#define glXWaitForSbcOML _al_glXWaitForSbcOML +#endif + + +#ifdef _ALLEGRO_GLX_SGIX_hyperpipe +#define glXQueryHyperpipeNetworkSGIX _al_glXQueryHyperpipeNetworkSGIX +#define glXHyperpipeConfigSGIX _al_glXHyperpipeConfigSGIX +#define glXQueryHyperpipeConfigSGIX _al_glXQueryHyperpipeConfigSGIX +#define glXDestroyHyperpipeConfigSGIX _al_glXDestroyHyperpipeConfigSGIX +#define glXBindHyperpipeSGIX _al_glXBindHyperpipeSGIX +#define glXQueryHyperpipeBestAttribSGIX _al_glXQueryHyperpipeBestAttribSGIX +#define glXHyperpipeAttribSGIX _al_glXHyperpipeAttribSGIX +#define glXQueryHyperpipeAttribSGIX _al_glXQueryHyperpipeAttribSGIX +#endif + + +#ifdef _ALLEGRO_GLX_MESA_agp_offset +#define glXGetAGPOffsetMESA _al_glXGetAGPOffsetMESA +#endif + + +#ifdef _ALLEGRO_GLX_EXT_texture_from_pixmap +#define glXBindTexImageEXT _al_glXBindTexImageEXT +#define glXReleaseTextImageEXT _al_glXReleaseTextImageEXT +#endif + +#ifdef _ALLEGRO_GLX_NV_video_output +#define glXGetVideoDeviceNV _al_glXGetVideoDeviceNV +#define glXReleaseVideoDeviceNV _al_glXReleaseVideoDeviceNV +#define glXBindVideoImageNV _al_glXBindVideoImageNV +#define glXReleaseVideoImageNV _al_glXReleaseVideoImageNV +#define glXSendPbufferToVideoNV _al_glXSendPbufferToVideoNV +#define glXGetVideoInfoNV _al_glXGetVideoInfoNV +#endif + +#ifdef _ALLEGRO_GLX_NV_swap_group +#define glXJoinSwapGroupNV _al_glXJoinSwapGroupNV +#define glXBindSwapBarrierNV _al_glXBindSwapBarrierNV +#define glXQuerySwapGroupNV _al_glXQuerySwapGroupNV +#define glXQueryMaxSwapGroupsNV _al_glXQueryMaxSwapGroupsNV +#define glXQueryFrameCountNV _al_glXQueryFrameCountNV +#define glXResetFrameCountNV _al_glXResetFrameCountNV +#endif + +#ifdef _ALLEGRO_GLX_NV_video_capture +#define glXBindVideoCaptureDeviceNV _al_glXBindVideoCaptureDeviceNV +#define glXEnumerateVideoCaptureDevicesNV _al_glXEnumerateVideoCaptureDevicesNV +#define glXLockVideoCaptureDeviceNV _al_glXLockVideoCaptureDeviceNV +#define glXQueryVideoCaptureDeviceNV _al_glXQueryVideoCaptureDeviceNV +#define glXReleaseVideoCaptureDeviceNV _al_glXReleaseVideoCaptureDeviceNV +#endif + +#ifdef _ALLEGRO_GLX_EXT_swap_control +#define glXSwapIntervalEXT _al_glXSwapIntervalEXT +#endif + +#ifdef _ALLEGRO_GLX_NV_copy_image +#define glXCopyImageSubDataNV _al_glXCopyImageSubDataNV +#endif + +#ifdef _ALLEGRO_GLX_EXT_create_context_es_profile +//nofunctions +#endif diff --git a/allegro/include/allegro5/opengl/GLext/glx_ext_api.h b/allegro/include/allegro5/opengl/GLext/glx_ext_api.h new file mode 100644 index 00000000..8694bc2f --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/glx_ext_api.h @@ -0,0 +1,216 @@ +#ifdef _ALLEGRO_GLX_VERSION_1_3 +/* GLX 1.3 */ +AGL_API(GLXFBConfig *, GetFBConfigs, (Display *, int, int *)) +AGL_API(GLXFBConfig *, ChooseFBConfig, (Display *, int, const int *, int *)) +AGL_API(int, GetFBConfigAttrib, (Display *, GLXFBConfig, int, int *)) +AGL_API(XVisualInfo *, GetVisualFromFBConfig, (Display *, GLXFBConfig)) +AGL_API(GLXWindow, CreateWindow, (Display *, GLXFBConfig, Window, const int *)) +AGL_API(void, DestroyWindow, (Display *, GLXWindow)) +AGL_API(GLXPixmap, CreatePixmap, (Display *, GLXFBConfig, Pixmap, const int *)) +AGL_API(void, DestroyPixmap, (Display *, GLXPixmap)) +AGL_API(GLXPbuffer, CreatePbuffer, (Display *, GLXFBConfig, const int *)) +AGL_API(void, DestroyPbuffer, (Display *, GLXPbuffer)) +AGL_API(void, QueryDrawable, (Display *, GLXDrawable, int, unsigned int *)) +AGL_API(GLXContext, CreateNewContext, (Display *, GLXFBConfig, int, GLXContext, Bool)) +AGL_API(Bool, MakeContextCurrent, (Display *, GLXDrawable, GLXDrawable, GLXContext)) +AGL_API(GLXDrawable, GetCurrentReadDrawable, (void)) +AGL_API(Display *, GetCurrentDisplay, (void)) +AGL_API(int, QueryContext, (Display *, GLXContext, int, int *)) +AGL_API(void, SelectEvent, (Display *, GLXDrawable, unsigned long)) +AGL_API(void, GetSelectedEvent, (Display *, GLXDrawable, unsigned long *)) +#endif +#ifdef _ALLEGRO_GLX_VERSION_1_4 +/* GLX 1.4 */ +AGL_API(__GLXextFuncPtr, GetProcAddress, (const GLubyte *)) +#endif + +#ifdef _ALLEGRO_GLX_ARB_get_proc_address +/* GLX_ARB_get_proc_address */ +AGL_API(__GLXextFuncPtr, GetProcAddressARB, (const GLubyte *)) +#endif + +#ifdef _ALLEGRO_GLX_ARB_create_context +AGL_API(GLXContext, CreateContextAttribsARB, (Display *, GLXFBConfig, GLXContext, Bool, const int *)) +#endif + +#ifdef _ALLEGRO_GLX_SGI_swap_control +/* GLX_SGI_swap_control */ +AGL_API(int, SwapIntervalSGI, (int)) +#endif + +#ifdef _ALLEGRO_GLX_SGI_video_sync +/* GLX_SGI_video_sync */ +AGL_API(int, GetVideoSyncSGI, (unsigned int *)) +AGL_API(int, WaitVideoSyncSGI, (int, int, unsigned int *)) +#endif + +#ifdef _ALLEGRO_GLX_SGI_make_current_read +/* GLX_SGI_make_current_read */ +AGL_API(Bool, MakeCurrentReadSGI, (Display *, GLXDrawable, GLXDrawable, GLXContext)) +AGL_API(GLXDrawable, GetCurrentReadDrawableSGI, (void)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_video_source +/* GLX_SGIX_video_source */ +/* This one needs SGI's header file to be included first */ +#ifdef _VL_H_ +AGL_API(GLXVideoSourceSGIX, CreateGLXVideoSourceSGIX, (Display *, int, VLServer, VLPath, int, VLNode)) +AGL_API(void, DestroyGLXVideoSourceSGIX, (Display *, GLXVideoSourceSGIX)) +#endif +#endif + +#ifdef _ALLEGRO_GLX_EXT_import_context +/* GLX_EXT_import_context */ +AGL_API(Display *, GetCurrentDisplayEXT, (void)) +AGL_API(int, QueryContextInfoEXT, (Display *, GLXContext, int, int *)) +AGL_API(GLXContextID, GetContextIDEXT, (const GLXContext)) +AGL_API(GLXContext, ImportContextEXT, (Display *, GLXContextID)) +AGL_API(void, FreeContextEXT, (Display *, GLXContext)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_fbconfig +/* GLX_SGIX_fbconfig */ +AGL_API(int, GetFBConfigAttribSGIX, (Display *, GLXFBConfigSGIX, int, int *)) +AGL_API(GLXFBConfigSGIX *, ChooseFBConfigSGIX, (Display *, int, int *, int *)) +AGL_API(GLXPixmap, CreateGLXPixmapWithConfigSGIX, (Display *, GLXFBConfigSGIX, Pixmap)) +AGL_API(GLXContext, CreateContextWithConfigSGIX, (Display *, GLXFBConfigSGIX, int, GLXContext, Bool)) +AGL_API(XVisualInfo *, GetVisualFromFBConfigSGIX, (Display *, GLXFBConfigSGIX)) +AGL_API(GLXFBConfigSGIX, GetFBConfigFromVisualSGIX, (Display *, XVisualInfo *)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_pbuffer +/* GLX_SGIX_pbuffer */ +AGL_API(GLXPbufferSGIX, CreateGLXPbufferSGIX, (Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *)) +AGL_API(void, DestroyGLXPbufferSGIX, (Display *, GLXPbufferSGIX)) +AGL_API(int, QueryGLXPbufferSGIX, (Display *, GLXPbufferSGIX, int, unsigned int *)) +AGL_API(void, SelectEventSGIX, (Display *, GLXDrawable, unsigned long)) +AGL_API(void, GetSelectedEventSGIX, (Display *, GLXDrawable, unsigned long *)) +#endif + +#ifdef _ALLEGRO_GLX_SGI_cushion +/* GLX_SGI_cushion */ +AGL_API(void, CushionSGI, (Display *, Window, float)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_video_resize +/* GLX_SGIX_video_resize */ +AGL_API(int, BindChannelToWindowSGIX, (Display *, int, int, Window)) +AGL_API(int, ChannelRectSGIX, (Display *, int, int, int, int, int, int)) +AGL_API(int, QueryChannelRectSGIX, (Display *, int, int, int *, int *, int *, int *)) +AGL_API(int, QueryChannelDeltasSGIX, (Display *, int, int, int *, int *, int *, int *)) +AGL_API(int, ChannelRectSyncSGIX, (Display *, int, int, GLenum)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_dmbuffer +/* GLX_SGIX_dmbuffer */ +/* This one needs SGI's header file to be included first */ +#ifdef _DM_BUFFER_H_ +AGL_API(Bool, AssociateDMPbufferSGIX, (Display *, GLXPbufferSGIX, DMparams *, DMbuffer)) +#endif +#endif + +#ifdef _ALLEGRO_GLX_SGIX_swap_group +/* GLX_SGIX_swap_group */ +AGL_API(void, JoinSwapGroupSGIX, (Display *, GLXDrawable, GLXDrawable)) +#endif + +#ifdef _ALLEGRO_GLX_SGIX_swap_barrier +/* GLX_SGIX_swap_barrier */ +AGL_API(void, BindSwapBarrierSGIX, (Display *, GLXDrawable, int)) +AGL_API(Bool, QueryMaxSwapBarriersSGIX, (Display *, int, int *)) +#endif + +#ifdef _ALLEGRO_GLX_SUN_get_transparent_index +/* GLX_SUN_get_transparent_index */ +AGL_API(Status, GetTransparentIndexSUN, (Display *, Window, Window, long *)) +#endif + +#ifdef _ALLEGRO_GLX_MESA_copy_sub_buffer +/* GLX_MESA_copy_sub_buffer */ +AGL_API(void, CopySubBufferMESA, (Display *, GLXDrawable, int, int, int, int)) +#endif + +#ifdef _ALLEGRO_GLX_MESA_pixmap_colormap +/* GLX_MESA_pixmap_colormap */ +AGL_API(GLXPixmap, CreateGLXPixmapMESA, (Display *, XVisualInfo *, Pixmap, Colormap)) +#endif + +#ifdef _ALLEGRO_GLX_MESA_release_buffers +/* GLX_MESA_release_buffers */ +AGL_API(Bool, ReleaseBuffersMESA, (Display *, GLXDrawable)) +#endif + +#ifdef _ALLEGRO_GLX_MESA_set_3dfx_mode +/* GLX_MESA_set_3dfx_mode */ +AGL_API(Bool, Set3DfxModeMESA, (int)) +#endif + +#ifdef _ALLEGRO_GLX_OML_sync_control +/* GLX_OML_sync_control */ +AGL_API(Bool, GetSyncValuesOML, (Display *, GLXDrawable, int64_t *, int64_t *, int64_t *)) +AGL_API(Bool, GetMscRateOML, (Display *, GLXDrawable, int32_t *, int32_t *)) +AGL_API(int64_t, SwapBuffersMscOML, (Display *, GLXDrawable, int64_t, int64_t, int64_t)) +AGL_API(Bool, WaitForMscOML, (Display *, GLXDrawable, int64_t, int64_t, int64_t, int64_t *, int64_t *, int64_t *)) +AGL_API(Bool, WaitForSbcOML, (Display *, GLXDrawable, int64_t, int64_t *, int64_t *, int64_t *)) +#endif + + +#ifdef _ALLEGRO_GLX_SGIX_hyperpipe +AGL_API(GLXHyperpipeNetworkSGIX *, QueryHyperpipeNetworkSGIX, (Display *dpy, int *npipes)) +AGL_API(int, HyperpipeConfigSGIX, (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId)) +AGL_API(GLXHyperpipeConfigSGIX *, QueryHyperpipeConfigSGIX, (Display *dpy, int hpId, int *npipes)) +AGL_API(int, DestroyHyperpipeConfigSGIX, (Display * dpy, int hpId)) +AGL_API(int, BindHyperpipeSGIX, (Display *dpy, int hpId)) +AGL_API(int, QueryHyperpipeBestAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList)) +AGL_API(int, HyperpipeAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *attribList)) +AGL_API(int, QueryHyperpipeAttribSGIX, (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList)) +#endif + + +#ifdef _ALLEGRO_GLX_MESA_agp_offset +AGL_API(unsigned int, GetAGPOffsetMESA, (const void *pointer)) +#endif + + +#ifdef _ALLEGRO_GLX_EXT_texture_from_pixmap +AGL_API(void, BindTexImageEXT, (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list)) +AGL_API(void, ReleaseTextImageEXT, (Display *dpy, GLXDrawable drawable, int buffer)) +#endif + +#ifdef _ALLEGRO_GLX_NV_video_output +AGL_API(int, GetVideoDeviceNV, (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice)) +AGL_API(int, ReleaseVideoDeviceNV, (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice)) +AGL_API(int, BindVideoImageNV, (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer)) +AGL_API(int, ReleaseVideoImageNV, (Display *dpy, GLXPbuffer pbuf)) +AGL_API(int, SendPbufferToVideoNV, (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock)) +AGL_API(int, GetVideoInfoNV, (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputVideo, unsigned long *pulCounterOutputPbuffer)) +#endif + +#ifdef _ALLEGRO_GLX_NV_swap_group +AGL_API(Bool, JoinSwapGroupNV, (Display *dpy, GLXDrawable drawable, GLuint group)) +AGL_API(Bool, BindSwapBarrierNV, (Display *dpy, GLuint group, GLuint barrier)) +AGL_API(Bool, QuerySwapGroupNV, (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier)) +AGL_API(Bool, QueryMaxSwapGroupsNV, (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers)) +AGL_API(Bool, QueryFrameCountNV, (Display *dpy, int screen, GLuint *count)) +AGL_API(Bool, ResetFrameCountNV, (Display *dpy, int screen)) +#endif + +#ifdef _ALLEGRO_GLX_NV_video_capture +AGL_API(int, BindVideoCaptureDeviceNV, (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device)) +AGL_API(GLXVideoCaptureDeviceNV *, EnumerateVideoCaptureDevicesNV, (Display *dpy, int screen, int *nelements)) +AGL_API(void, LockVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device)) +AGL_API(int, QueryVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value)) +AGL_API(void, ReleaseVideoCaptureDeviceNV, (Display *dpy, GLXVideoCaptureDeviceNV device)) +#endif + +#ifdef _ALLEGRO_GLX_EXT_swap_control +AGL_API(int, SwapIntervalEXT, (Display *dpy, GLXDrawable drawable, int interval)) +#endif + +#ifdef _ALLEGRO_GLX_NV_copy_image +AGL_API(void, CopyImageSubDataNV, (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth)) +#endif + +#ifdef _ALLEGRO_GLX_EXT_create_context_es_profile +// no functions +#endif diff --git a/allegro/include/allegro5/opengl/GLext/glx_ext_defs.h b/allegro/include/allegro5/opengl/GLext/glx_ext_defs.h new file mode 100644 index 00000000..fba8aea5 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/glx_ext_defs.h @@ -0,0 +1,515 @@ +/* HACK: Prevent both Mesa and SGI's broken headers from screwing us */ +#define __glxext_h_ +#define __glx_glxext_h_ +#include +#undef __glxext_h_ +#undef __glx_glxext_h_ + +#ifndef GLX_VERSION_1_3 +#define _ALLEGRO_GLX_VERSION_1_3 +#define GLX_VERSION_1_3 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#endif + +#ifndef GLX_VERSION_1_4 +#define _ALLEGRO_GLX_VERSION_1_4 +#define GLX_VERSION_1_4 +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 +#endif + +#ifndef GLX_ARB_get_proc_address +#define _ALLEGRO_GLX_ARB_get_proc_address +#define GLX_ARB_get_proc_address +typedef void (*__GLXextFuncPtr)(void); +#endif + +#ifndef GLX_ARB_multisample +#define _ALLEGRO_GLX_ARB_multisample +#define GLX_ARB_multisample +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 +#endif + +#ifndef GLX_ARB_vertex_buffer_object +#define GLX_ARB_vertex_buffer_object +#define _ALLEGRO_GLX_ARB_vertex_buffer_object +#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 +#endif + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float +#define _ALLEGRO_GLX_ARB_fbconfig_float +#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 +#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 +#endif + +#ifndef GLX_ARB_create_context +#define GLX_ARB_create_context +#define _ALLEGRO_GLX_ARB_create_context +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#endif + +#ifndef GLX_ARB_create_context_profile +#define GLX_ARB_create_context_profile +#define _ALLEGRO_GLX_ARB_create_context_profile +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#endif + +#ifndef GLX_SGIS_multisample +#define _ALLEGRO_GLX_SGIS_multisample +#define GLX_SGIS_multisample +#define GLX_SAMPLE_BUFFERS_SGIS 100000 +#define GLX_SAMPLES_SGIS 100001 +#endif + +/* Fix for system headers that define GLX_VERSION_1_4 but do not define + * GLX_SAMPLES and GLX_SAMPLE_BUFFERS. */ +#ifndef GLX_SAMPLES +#define GLX_SAMPLE_BUFFERS 100000 +#define GLX_SAMPLES 100001 +#endif + +#ifndef GLX_EXT_visual_info +#define _ALLEGRO_GLX_EXT_visual_info +#define GLX_EXT_visual_info +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#endif + +#ifndef GLX_EXT_visual_rating +#define _ALLEGRO_GLX_EXT_visual_rating +#define GLX_EXT_visual_rating +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +/* GLX_NONE_EXT */ +#endif + +#ifndef GLX_EXT_import_context +#define _ALLEGRO_GLX_EXT_import_context +#define GLX_EXT_import_context +#define GLX_SHARE_CONTEXT_EXT 0x800A +#define GLX_VISUAL_ID_EXT 0x800B +#define GLX_SCREEN_EXT 0x800C +#endif + +#ifndef GLX_SGIX_fbconfig +#define _ALLEGRO_GLX_SGIX_fbconfig +#define GLX_SGIX_fbconfig +typedef XID GLXFBConfigIDSGIX; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +#define GLX_WINDOW_BIT_SGIX 0x00000001 +#define GLX_PIXMAP_BIT_SGIX 0x00000002 +#define GLX_RGBA_BIT_SGIX 0x00000001 +#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 +#define GLX_DRAWABLE_TYPE_SGIX 0x8010 +#define GLX_RENDER_TYPE_SGIX 0x8011 +#define GLX_X_RENDERABLE_SGIX 0x8012 +#define GLX_FBCONFIG_ID_SGIX 0x8013 +#define GLX_RGBA_TYPE_SGIX 0x8014 +#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 +/* GLX_SCREEN_EXT */ +#endif + +#ifndef GLX_SGIX_pbuffer +#define _ALLEGRO_GLX_SGIX_pbuffer +#define GLX_SGIX_pbuffer +typedef XID GLXPbufferSGIX; +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ +} GLXBufferClobberEventSGIX; +#define GLX_PBUFFER_BIT_SGIX 0x00000004 +#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 +#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 +#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 +#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 +#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 +#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 +#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 +#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 +#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 +#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 +#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A +#define GLX_PRESERVED_CONTENTS_SGIX 0x801B +#define GLX_LARGEST_PBUFFER_SGIX 0x801C +#define GLX_WIDTH_SGIX 0x801D +#define GLX_HEIGHT_SGIX 0x801E +#define GLX_EVENT_MASK_SGIX 0x801F +#define GLX_DAMAGED_SGIX 0x8020 +#define GLX_SAVED_SGIX 0x8021 +#define GLX_WINDOW_SGIX 0x8022 +#define GLX_PBUFFER_SGIX 0x8023 +#endif + +#ifndef GLX_SGIX_video_resize +#define _ALLEGRO_GLX_SGIX_video_resize +#define GLX_SGIX_video_resize +#define GLX_SYNC_FRAME_SGIX 0x00000000 +#define GLX_SYNC_SWAP_SGIX 0x00000001 +#endif + +#ifndef GLX_SGIX_dmbuffer +#define _ALLEGRO_GLX_SGIX_dmbuffer +#define GLX_SGIX_dmbuffer +#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 +#endif + +#ifndef GLX_SGIS_blended_overlay +#define _ALLEGRO_GLX_SGIS_blended_overlay +#define GLX_SGIS_blended_overlay +#define GLX_BLENDED_RGBA_SGIS 0x8025 +#endif + +#ifndef GLX_SGIS_shared_multisample +#define _ALLEGRO_GLX_SGIS_shared_multisample +#define GLX_SGIS_shared_multisample +#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 +#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 +#endif + +#ifndef GLX_3DFX_multisample +#define _ALLEGRO_GLX_3DFX_multisample +#define GLX_3DFX_multisample +#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 +#define GLX_SAMPLES_3DFX 0x8051 +#endif + +#ifndef GLX_MESA_set_3dfx_mode +#define _ALLEGRO_GLX_MESA_set_3dfx_mode +#define GLX_MESA_set_3dfx_mode +#define GLX_3DFX_WINDOW_MODE_MESA 0x1 +#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 +#endif + +#ifndef GLX_SGIX_visual_select_group +#define _ALLEGRO_GLX_SGIX_visual_select_group +#define GLX_SGIX_visual_select_group +#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 +#endif + +#ifndef GLX_OML_swap_method +#define _ALLEGRO_GLX_OML_swap_method +#define GLX_OML_swap_method +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 +#endif + +#ifndef GLX_SGIX_video_source +#define _ALLEGRO_GLX_SGIX_video_source +#define GLX_SGIX_video_source +typedef XID GLXVideoSourceSGIX; +#endif + +#ifndef GLX_SGI_video_sync +#define GLX_SGI_video_sync +#define _ALLEGRO_GLX_SGI_video_sync +#endif + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control +#define _ALLEGRO_GLX_SGI_swap_control +#endif + +#ifndef GLX_SGI_make_current_read +#define GLX_SGI_make_current_read +#define _ALLEGRO_GLX_SGI_make_current_read +#endif + +#ifndef GLX_SGI_cushion +#define GLX_SGI_cushion +#define _ALLEGRO_GLX_SGI_cushion +#endif + +#ifndef GLX_SGIX_swap_group +#define GLX_SGIX_swap_group +#define _ALLEGRO_GLX_SGIX_swap_group +#endif + +#ifndef GLX_SGIX_swap_barrier +#define GLX_SGIX_swap_barrier +#define _ALLEGRO_GLX_SGIX_swap_barrier +#endif + +#ifndef GLX_SUN_get_transparent_index +#define GLX_SUN_get_transparent_index +#define _ALLEGRO_GLX_SUN_get_transparent_index +#endif + +#ifndef GLX_MESA_copy_sub_buffer +#define GLX_MESA_copy_sub_buffer +#define _ALLEGRO_GLX_MESA_copy_sub_buffer +#endif + +#ifndef GLX_MESA_pixmap_colormap +#define GLX_MESA_pixmap_colormap +#define _ALLEGRO_GLX_MESA_pixmap_colormap +#endif + +#ifndef GLX_MESA_release_buffers +#define GLX_MESA_release_buffers +#define _ALLEGRO_GLX_MESA_release_buffers +#endif + +#ifndef GLX_OML_sync_control +#define GLX_OML_sync_control +#define _ALLEGRO_GLX_OML_sync_control +#endif + +#ifndef GLX_SGIX_hyperpipe +#define GLX_SGIX_hyperpipe +#define _ALLEGRO_GLX_SGIX_hyperpipe +#define GLX_HYPERPIPE_ID_SGIX 0x8030 +#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 +#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 +#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 +#define GLX_PIPE_RECT_SGIX 0x00000001 +#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 +#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 +#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 +#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 +#define GLX_BAD_HYPERPIPE_SGIX 92 + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int networkId; +} GLXHyperpipeNetworkSGIX; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int channel; + unsigned int participationType; + int timeSlice; +} GLXHyperpipeConfigSGIX; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int srcXOrigin; + int srcYOrigin; + int srcWidth; + int srcHeight; + int destXOrigin; + int destYOrigin; + int destWidth; + int destHeight; +} GLXPipeRect; + +typedef struct { + char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; + int XOrigin; + int YOrigin; + int maxHeight; + int maxWidth; +} GLXPipeRectLimits; +#endif + + +#ifndef GLX_MESA_agp_offset +#define GLX_MESA_agp_offset +#define _ALLEGRO_GLX_MESA_agp_offset +#endif + +#ifndef GLX_EXT_framebuffer_sRGB +#define GLX_EXT_framebuffer_sRGB +#define _ALLEGRO_GLX_EXT_framebuffer_sRGB +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 +#endif + +#ifndef GLX_EXT_fbconfig_packed_float +#define GLX_EXT_fbconfig_packed_float +#define _ALLEGRO_GLX_EXT_fbconfig_packed_float +#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 +#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 +#endif + +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_EXT_texture_from_pixmap +#define _ALLEGRO_GLX_EXT_texture_from_pixmap +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT +#define GLX_BACK_EXT GLX_BACK_LEFT_EXT +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB +#endif + +#ifndef GLX_NV_present_video +#define GLX_NV_present_video +#define _ALLEGRO_GLX_NV_present_video +#define GLX_GLX_NUM_VIDEO_SLOTS_NV 0x20F0 +#endif + +#ifndef GLX_NV_video_output +#define GLX_NV_video_output +#define _ALLEGRO_GLX_NV_video_output +#define GLX_VIDEO_OUT_COLOR_NV 0x20C3 +#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4 +#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5 +#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define GLX_VIDEO_OUT_FRAME_NV 0x20C8 +#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9 +#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA +typedef unsigned int GLXVideoDeviceNV; +#endif + +#ifndef GLX_NV_swap_group +#define GLX_NV_swap_group +#define _ALLEGRO_GLX_NV_swap_group +#endif + +#ifndef GLX_NV_video_capture +#define GLX_NV_video_capture +#define _ALLEGRO_GLX_NV_video_capture +#define GLX_DEVICE_ID_NV 0x20CD +#define GLX_UNIQUE_ID_NV 0x20CE +#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF +typedef XID GLXVideoCaptureDeviceNV; +#endif + +#ifndef GLX_EXT_swap_control +#define GLX_EXT_swap_control +#define _ALLEGRO_GLX_EXT_swap_control +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 +#endif + +#ifndef GLX_NV_copy_image +#define GLX_NV_copy_image +#define _ALLEGRO_GLX_NV_copy_image +#endif + +#ifndef GLX_INTEL_swap_event +#define GLX_INTEL_swap_event +#define _ALLEGRO_GLX_INTEL_swap_event +#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000 +#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180 +#define GLX_COPY_COMPLETE_INTEL 0x8181 +#define GLX_FLIP_COMPLETE_INTEL 0x8182 +#endif + +#ifndef GLX_EXT_create_context_es_profile +#define GLX_EXT_create_context_es_profile +#define GLX_EXT_create_context_es2_profile +#define _ALLEGRO_GLX_EXT_create_context_es_profile +#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#endif diff --git a/allegro/include/allegro5/opengl/GLext/glx_ext_list.h b/allegro/include/allegro5/opengl/GLext/glx_ext_list.h new file mode 100644 index 00000000..098f74ce --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/glx_ext_list.h @@ -0,0 +1,41 @@ +AGL_EXT(ARB_get_proc_address, 0) +AGL_EXT(ARB_multisample, 0) +AGL_EXT(ARB_fbconfig_float, 0) +AGL_EXT(ARB_create_context, 0) +AGL_EXT(ARB_vertex_buffer_object, 0) +AGL_EXT(EXT_visual_info, 0) +AGL_EXT(SGI_swap_control, 0) +AGL_EXT(SGI_video_sync, 0) +AGL_EXT(SGI_make_current_read, 0) +AGL_EXT(SGIX_video_source, 0) +AGL_EXT(EXT_visual_rating, 0) +AGL_EXT(EXT_import_context, 0) +AGL_EXT(SGIX_fbconfig, 0) +AGL_EXT(SGIX_pbuffer, 0) +AGL_EXT(SGI_cushion, 0) +AGL_EXT(SGIX_video_resize, 0) +AGL_EXT(SGIX_dm_buffer, 0) +AGL_EXT(SGIX_swap_group, 0) +AGL_EXT(SGIX_swap_barrier, 0) +AGL_EXT(SGIS_color_range, 0) +AGL_EXT(SGIS_blended_overlay, 0) +AGL_EXT(SUN_get_transparent_index, 0) +AGL_EXT(MESA_copy_sub_buffer, 0) +AGL_EXT(MESA_pixmap_colormap, 0) +AGL_EXT(MESA_release_buffers, 0) +AGL_EXT(MESA_set_3dfx_mode, 0) +AGL_EXT(SGIX_visual_select_group, 0) +AGL_EXT(OML_swap_method, 0) +AGL_EXT(OML_sync_control, 0) +AGL_EXT(SGIX_hyperpipe, 0) +AGL_EXT(MESA_agp_offset, 0) +AGL_EXT(EXT_framebuffer_sRGB, 0) +AGL_EXT(EXT_packed_float, 0) +AGL_EXT(EXT_texture_from_pixmap, 0) +AGL_EXT(NV_video_output, 0) +AGL_EXT(NV_swap_group, 0) +AGL_EXT(NV_video_capture, 0) +AGL_EXT(EXT_swap_control, 0) +AGL_EXT(NV_copy_image, 0) +AGL_EXT(INTEL_swap_event, 0) +AGL_EXT(EXT_create_context_es_profile, 0) diff --git a/allegro/include/allegro5/opengl/GLext/wgl_ext_alias.h b/allegro/include/allegro5/opengl/GLext/wgl_ext_alias.h new file mode 100644 index 00000000..ab0cf1f2 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/wgl_ext_alias.h @@ -0,0 +1,168 @@ +/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/ +/*WGL_ARB_buffer_region*/ +#define wglCreateBufferRegionARB _al_wglCreateBufferRegionARB +#define wglDeleteBufferRegionARB _al_wglDeleteBufferRegionARB +#define wglSaveBufferRegionARB _al_wglSaveBufferRegionARB +#define wglRestoreBufferRegionARB _al_wglRestoreBufferRegionARB + +/*WGL_ARB_extensions_string*/ +#define wglGetExtensionsStringARB _al_wglGetExtensionsStringARB + +/*WGL_ARB_pixel_format*/ +#define wglGetPixelFormatAttribivARB _al_wglGetPixelFormatAttribivARB +#define wglGetPixelFormatAttribfvARB _al_wglGetPixelFormatAttribfvARB +#define wglChoosePixelFormatARB _al_wglChoosePixelFormatARB + +/*WGL_ARB_make_current_read*/ +#define wglMakeContextCurrentARB _al_wglMakeContextCurrentARB +#define wglGetCurrentReadDCARB _al_wglGetCurrentReadDCARB + +/*WGL_ARB_pbuffer*/ +#define wglCreatePbufferARB _al_wglCreatePbufferARB +#define wglGetPbufferDCARB _al_wglGetPbufferDCARB +#define wglReleasePbufferDCARB _al_wglReleasePbufferDCARB +#define wglDestroyPbufferARB _al_wglDestroyPbufferARB +#define wglQueryPbufferARB _al_wglQueryPbufferARB + +/*WGL_ARB_render_texture*/ +#define wglBindTexImageARB _al_wglBindTexImageARB +#define wglReleaseTexImageARB _al_wglReleaseTexImageARB +#define wglSetPbufferAttribARB _al_wglSetPbufferAttribARB + +/*WGL_ARB_create_context*/ +#define wglCreateContextAttribsARB _al_wglCreateContextAttribsARB + +/*WGL_EXT_display_color_table*/ +#define wglCreateDisplayColorTableEXT _al_wglCreateDisplayColorTableEXT +#define wglLoadDisplayColorTableEXT _al_wglLoadDisplayColorTableEXT +#define wglBindDisplayColorTableEXT _al_wglBindDisplayColorTableEXT +#define wglDestroyDisplayColorTableEXT _al_wglDestroyDisplayColorTableEXT + +/*WGL_EXT_extensions_string*/ +#define wglGetExtensionsStringEXT _al_wglGetExtensionsStringEXT + +/*WGL_EXT_make_current_read*/ +#define wglMakeContextCurrentEXT _al_wglMakeContextCurrentEXT +#define wglGetCurrentReadDCEXT _al_wglGetCurrentReadDCEXT + +/*WGL_EXT_pbuffer*/ +#define wglCreatePbufferEXT _al_wglCreatePbufferEXT +#define wglGetPbufferDCEXT _al_wglGetPbufferDCEXT +#define wglReleasePbufferDCEXT _al_wglReleasePbufferDCEXT +#define wglDestroyPbufferEXT _al_wglDestroyPbufferEXT +#define wglQueryPbufferEXT _al_wglQueryPbufferEXT + +/*WGL_EXT_pixel_format*/ +#define wglGetPixelFormatAttribivEXT _al_wglGetPixelFormatAttribivEXT +#define wglGetPixelFormatAttribfvEXT _al_wglGetPixelFormatAttribfvEXT +#define wglChoosePixelFormatEXT _al_wglChoosePixelFormatEXT + +/*WGL_EXT_swap_control*/ +#define wglSwapIntervalEXT _al_wglSwapIntervalEXT +#define wglGetSwapIntervalEXT _al_wglGetSwapIntervalEXT + +/*WGL_NV_vertex_array_range*/ +#define wglAllocateMemoryNV _al_wglAllocateMemoryNV +#define wglFreeMemoryNV _al_wglFreeMemoryNV + +/*WGL_OML_sync_control*/ +#define wglGetSyncValuesOML _al_wglGetSyncValuesOML +#define wglGetMscRateOML _al_wglGetMscRateOML +#define wglSwapBuffersMscOML _al_wglSwapBuffersMscOML +#define wglSwapLayerBuffersMscOML _al_wglSwapLayerBuffersMscOML +#define wglWaitForMscOML _al_wglWaitForMscOML +#define wglWaitForSbcOML _al_wglWaitForSbcOML + +/*WGL_I3D_digital_video_control*/ +#define wglGetDigitalVideoParametersI3D _al_wglGetDigitalVideoParametersI3D +#define wglSetDigitalVideoParametersI3D _al_wglSetDigitalVideoParametersI3D + +/*WGL_I3D_gamma*/ +#define wglGetGammaTableParametersI3D _al_wglGetGammaTableParametersI3D +#define wglSetGammaTableParametersI3D _al_wglSetGammaTableParametersI3D +#define wglGetGammaTableI3D _al_wglGetGammaTableI3D +#define wglSetGammaTableI3D _al_wglSetGammaTableI3D + +/*WGL_I3D_genlock*/ +#define wglEnableGenlockI3D _al_wglEnableGenlockI3D +#define wglDisableGenlockI3D _al_wglDisableGenlockI3D +#define wglIsEnabledGenlockI3D _al_wglIsEnabledGenlockI3D +#define wglGenlockSourceI3D _al_wglGenlockSourceI3D +#define wglGetGenlockSourceI3D _al_wglGetGenlockSourceI3D +#define wglGenlockSourceEdgeI3D _al_wglGenlockSourceEdgeI3D +#define wglGetGenlockSourceEdgeI3D _al_wglGetGenlockSourceEdgeI3D +#define wglGenlockSampleRateI3D _al_wglGenlockSampleRateI3D +#define wglGetGenlockSampleRateI3D _al_wglGetGenlockSampleRateI3D +#define wglGenlockSourceDelayI3D _al_wglGenlockSourceDelayI3D +#define wglGetGenlockSourceDelayI3D _al_wglGetGenlockSourceDelayI3D +#define wglQueryGenlockMaxSourceDelayI3D _al_wglQueryGenlockMaxSourceDelayI3D + +/*WGL_I3D_image_buffer*/ +#define wglCreateImageBufferI3D _al_wglCreateImageBufferI3D +#define wglDestroyImageBufferI3D _al_wglDestroyImageBufferI3D +#define wglAssociateImageBufferEventsI3D _al_wglAssociateImageBufferEventsI3D +#define wglReleaseImageBufferEventsI3D _al_wglReleaseImageBufferEventsI3D + +/*WGL_I3D_swap_frame_lock*/ +#define wglEnableFrameLockI3D _al_wglEnableFrameLockI3D +#define wglDisableFrameLockI3D _al_wglDisableFrameLockI3D +#define wglIsEnabledFrameLockI3D _al_wglIsEnabledFrameLockI3D +#define wglQueryFrameLockMasterI3D _al_wglQueryFrameLockMasterI3D + +/*WGL_I3D_swap_frame_usage*/ +#define wglGetFrameUsageI3D _al_wglGetFrameUsageI3D +#define wglBeginFrameTrackingI3D _al_wglBeginFrameTrackingI3D +#define wglEndFrameTrackingI3D _al_wglEndFrameTrackingI3D +#define wglQueryFrameTrackingI3D _al_wglQueryFrameTrackingI3D + +/*glAddSwapHintRectWIN*/ +#define wglAddSwapHintRectWIN _al_wglAddSwapHintRectWIN + +/*WGL_NV_present_video*/ +#define wglEnumerateVideoDevicesNV _al_wglEnumerateVideoDevicesNV +#define wglBindVideoDeviceNV _al_wglBindVideoDeviceNV +#define wglQueryCurrentContextNV _al_wglQueryCurrentContextNV + +/*WGL_NV_video_out*/ +#define wglGetVideoDeviceNV _al_wglGetVideoDeviceNV +#define wglReleaseVideoDeviceNV _al_wglReleaseVideoDeviceNV +#define wglBindVideoImageNV _al_wglBindVideoImageNV +#define wglReleaseVideoImageNV _al_wglReleaseVideoImageNV +#define wglSendPbufferToVideoNV _al_wglSendPbufferToVideoNV +#define wglGetVideoInfoNV _al_wglGetVideoInfoNV + +/*WGL_NV_swap_group*/ +#define wglJoinSwapGroupNV _al_wglJoinSwapGroupNV +#define wglBindSwapBarrierNV _al_wglBindSwapBarrierNV +#define wglQuerySwapGroupNV _al_wglQuerySwapGroupNV +#define wglQueryMaxSwapGroupsNV _al_wglQueryMaxSwapGroupsNV +#define wglQueryFrameCountNV _al_wglQueryFrameCountNV +#define wglResetFrameCountNV _al_wglResetFrameCountNV + +/*WGL_NV_gpu_affinity*/ +#define wglEnumGpusNV _al_wglEnumGpusNV +#define wglEnumGpuDevicesNV _al_wglEnumGpuDevicesNV +#define wglCreateAffinityDCNV _al_wglCreateAffinityDCNV +#define wglEnumGpusFromAffinityDCNV _al_wglEnumGpusFromAffinityDCNV +#define wglDeleteDCNV _al_wglDeleteDCNV + +/*WGL_AMD_gpu_association*/ +#define wglGetGPUIDsAMD _al_wglGetGPUIDsAMD +#define wglGetGPUInfoAMD _al_wglGetGPUInfoAMD +#define wglGetContextGPUIDAMD _al_wglGetContextGPUIDAMD +#define wglCreateAssociatedContextAMD _al_wglCreateAssociatedContextAMD +#define wglCreateAssociatedContextAttribsAMD _al_wglCreateAssociatedContextAttribsAMD +#define wglDeleteAssociatedContextAMD _al_wglDeleteAssociatedContextAMD +#define wglMakeAssociatedContextCurrentAMD _al_wglMakeAssociatedContextCurrentAMD +#define wglGetCurrentAssociatedContextAMD _al_wglGetCurrentAssociatedContextAMD +#define wglBlitContextFramebufferAMD _al_wglBlitContextFramebufferAMD + +/*WGL_NV_video_capture*/ +#define wglBindVideoCaptureDeviceNV _al_wglBindVideoCaptureDeviceNV +#define wglEnumerateVideoCaptureDevicesNV _al_wglEnumerateVideoCaptureDevicesNV +#define wglLockVideoCaptureDeviceNV _al_wglLockVideoCaptureDeviceNV +#define wglQueryVideoCaptureDeviceNV _al_wglQueryVideoCaptureDeviceNV +#define wglReleaseVideoCaptureDeviceNV _al_wglReleaseVideoCaptureDeviceNV + +/*WGL_NV_copy_image*/ +#define wglCopyImageSubDataNV _al_wglCopyImageSubDataNV diff --git a/allegro/include/allegro5/opengl/GLext/wgl_ext_api.h b/allegro/include/allegro5/opengl/GLext/wgl_ext_api.h new file mode 100644 index 00000000..40aa9642 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/wgl_ext_api.h @@ -0,0 +1,167 @@ +/* WGL_ARB_buffer_region */ +AGL_API(HANDLE, CreateBufferRegionARB, (HDC, int, UINT)) +AGL_API(VOID, DeleteBufferRegionARB, (HANDLE)) +AGL_API(BOOL, SaveBufferRegionARB, (HANDLE, int, int, int, int)) +AGL_API(BOOL, RestoreBufferRegionARB, (HANDLE, int, int, int, int, int, int)) + +/* WGL_ARB_extensions_string */ +AGL_API(const char *, GetExtensionsStringARB, (HDC)) + +/* WGL_ARB_pixel_format */ +AGL_API(BOOL, GetPixelFormatAttribivARB, (HDC, int, int, UINT, const int *, int *)) +AGL_API(BOOL, GetPixelFormatAttribfvARB, (HDC, int, int, UINT, const int *, FLOAT *)) +AGL_API(BOOL, ChoosePixelFormatARB, (HDC, const int *, const FLOAT *, UINT, int *, UINT *)) + +/* WGL_ARB_make_current_read */ +AGL_API(BOOL, MakeContextCurrentARB, (HDC, HDC, HGLRC)) +AGL_API(HDC, GetCurrentReadDCARB, (void)) + +/* WGL_ARB_pbuffer */ +AGL_API(HPBUFFERARB, CreatePbufferARB, (HDC, int, int, int, const int *)) +AGL_API(HDC, GetPbufferDCARB, (HPBUFFERARB)) +AGL_API(int, ReleasePbufferDCARB, (HPBUFFERARB, HDC)) +AGL_API(BOOL, DestroyPbufferARB, (HPBUFFERARB)) +AGL_API(BOOL, QueryPbufferARB, (HPBUFFERARB, int, int *)) + +/* WGL_ARB_render_texture */ +AGL_API(BOOL, BindTexImageARB, (HPBUFFERARB, int)) +AGL_API(BOOL, ReleaseTexImageARB, (HPBUFFERARB, int)) +AGL_API(BOOL, SetPbufferAttribARB, (HPBUFFERARB, const int *)) + +/* WGL_ARB_create_context */ +AGL_API(HGLRC, CreateContextAttribsARB, (HDC, HGLRC, const int *)) + +/* WGL_EXT_display_color_table */ +AGL_API(GLboolean, CreateDisplayColorTableEXT, (GLushort)) +AGL_API(GLboolean, LoadDisplayColorTableEXT, (const GLushort *, GLuint)) +AGL_API(GLboolean, BindDisplayColorTableEXT, (GLushort)) +AGL_API(VOID, DestroyDisplayColorTableEXT, (GLushort)) + +/* WGL_EXT_extensions_string */ +AGL_API(const char *, GetExtensionsStringEXT, (void)) + +/* WGL_EXT_make_current_read */ +AGL_API(BOOL, MakeContextCurrentEXT, (HDC, HDC, HGLRC)) +AGL_API(HDC, GetCurrentReadDCEXT, (void)) + +/* WGL_EXT_pbuffer */ +AGL_API(HPBUFFEREXT, CreatePbufferEXT, (HDC, int, int, int, const int *)) +AGL_API(HDC, GetPbufferDCEXT, (HPBUFFEREXT)) +AGL_API(int, ReleasePbufferDCEXT, (HPBUFFEREXT, HDC)) +AGL_API(BOOL, DestroyPbufferEXT, (HPBUFFEREXT)) +AGL_API(BOOL, QueryPbufferEXT, (HPBUFFEREXT, int, int *)) + +/* WGL_EXT_pixel_format */ +AGL_API(BOOL, GetPixelFormatAttribivEXT, (HDC, int, int, UINT, int *, int *)) +AGL_API(BOOL, GetPixelFormatAttribfvEXT, (HDC, int, int, UINT, int *, FLOAT *)) +AGL_API(BOOL, ChoosePixelFormatEXT, (HDC, const int *, const FLOAT *, UINT, int *, UINT *)) + +/* WGL_EXT_swap_control */ +AGL_API(BOOL, SwapIntervalEXT, (int)) +AGL_API(int, GetSwapIntervalEXT, (void)) + +/* WGL_NV_vertex_array_range */ +AGL_API(void*, AllocateMemoryNV, (GLsizei, GLfloat, GLfloat, GLfloat)) +AGL_API(void, FreeMemoryNV, (void *)) + +/* WGL_OML_sync_control */ +AGL_API(BOOL, GetSyncValuesOML, (HDC, INT64 *, INT64 *, INT64 *)) +AGL_API(BOOL, GetMscRateOML, (HDC, INT32 *, INT32 *)) +AGL_API(INT64, SwapBuffersMscOML, (HDC, INT64, INT64, INT64)) +AGL_API(INT64, SwapLayerBuffersMscOML, (HDC, int, INT64, INT64, INT64)) +AGL_API(BOOL, WaitForMscOML, (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *)) +AGL_API(BOOL, WaitForSbcOML, (HDC, INT64, INT64 *, INT64 *, INT64 *)) + +/* WGL_I3D_digital_video_control */ +AGL_API(BOOL, GetDigitalVideoParametersI3D, (HDC, int, int *)) +AGL_API(BOOL, SetDigitalVideoParametersI3D, (HDC, int, const int *)) + +/* WGL_I3D_gamma */ +AGL_API(BOOL, GetGammaTableParametersI3D, (HDC, int, int *)) +AGL_API(BOOL, SetGammaTableParametersI3D, (HDC, int, const int *)) +AGL_API(BOOL, GetGammaTableI3D, (HDC, int, USHORT *, USHORT *, USHORT *)) +AGL_API(BOOL, SetGammaTableI3D, (HDC, int, const USHORT *, const USHORT *, const USHORT *)) + +/* WGL_I3D_genlock */ +AGL_API(BOOL, EnableGenlockI3D, (HDC)) +AGL_API(BOOL, DisableGenlockI3D, (HDC)) +AGL_API(BOOL, IsEnabledGenlockI3D, (HDC, BOOL *)) +AGL_API(BOOL, GenlockSourceI3D, (HDC, UINT)) +AGL_API(BOOL, GetGenlockSourceI3D, (HDC, UINT *)) +AGL_API(BOOL, GenlockSourceEdgeI3D, (HDC, UINT)) +AGL_API(BOOL, GetGenlockSourceEdgeI3D, (HDC, UINT *)) +AGL_API(BOOL, GenlockSampleRateI3D, (HDC, UINT)) +AGL_API(BOOL, GetGenlockSampleRateI3D, (HDC, UINT *)) +AGL_API(BOOL, GenlockSourceDelayI3D, (HDC, UINT)) +AGL_API(BOOL, GetGenlockSourceDelayI3D, (HDC, UINT *)) +AGL_API(BOOL, QueryGenlockMaxSourceDelayI3D, (HDC, UINT *, UINT *)) + +/* WGL_I3D_image_buffer */ +AGL_API(LPVOID, CreateImageBufferI3D, (HDC, DWORD, UINT)) +AGL_API(BOOL, DestroyImageBufferI3D, (HDC, LPVOID)) +AGL_API(BOOL, AssociateImageBufferEventsI3D, (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT)) +AGL_API(BOOL, ReleaseImageBufferEventsI3D, (HDC, const LPVOID *, UINT)) + +/* WGL_I3D_swap_frame_lock */ +AGL_API(BOOL, EnableFrameLockI3D, (void)) +AGL_API(BOOL, DisableFrameLockI3D, (void)) +AGL_API(BOOL, IsEnabledFrameLockI3D, (BOOL *)) +AGL_API(BOOL, QueryFrameLockMasterI3D, (BOOL *)) + +/* WGL_I3D_swap_frame_usage */ +AGL_API(BOOL, GetFrameUsageI3D, (float *)) +AGL_API(BOOL, BeginFrameTrackingI3D, (void)) +AGL_API(BOOL, EndFrameTrackingI3D, (void)) +AGL_API(BOOL, QueryFrameTrackingI3D, (DWORD *, DWORD *, float *)) + +/* glAddSwapHintRectWIN */ +AGL_API(void, AddSwapHintRectWIN, (int, int, int, int)) + +/* WGL_NV_present_video */ +AGL_API(int, EnumerateVideoDevicesNV, (HDC, HVIDEOOUTPUTDEVICENV *)) +AGL_API(BOOL, BindVideoDeviceNV, (HDC, unsigned int, HVIDEOOUTPUTDEVICENV, const int *)) +AGL_API(BOOL, QueryCurrentContextNV, (int, int *)) + +/* WGL_NV_video_out */ +AGL_API(BOOL, GetVideoDeviceNV, (HDC, int, HPVIDEODEV *)) +AGL_API(BOOL, ReleaseVideoDeviceNV, (HPVIDEODEV)) +AGL_API(BOOL, BindVideoImageNV, (HPVIDEODEV, HPBUFFERARB, int)) +AGL_API(BOOL, ReleaseVideoImageNV, (HPBUFFERARB, int)) +AGL_API(BOOL, SendPbufferToVideoNV, (HPBUFFERARB, int, unsigned long *, BOOL)) +AGL_API(BOOL, GetVideoInfoNV, (HPVIDEODEV, unsigned long *, unsigned long *)) + +/* WGL_NV_swap_group */ +AGL_API(BOOL, JoinSwapGroupNV, (HDC hDC, GLuint group)) +AGL_API(BOOL, BindSwapBarrierNV, (GLuint group, GLuint barrier)) +AGL_API(BOOL, QuerySwapGroupNV, (HDC hDC, GLuint *group, GLuint *barrier)) +AGL_API(BOOL, QueryMaxSwapGroupsNV, (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers)) +AGL_API(BOOL, QueryFrameCountNV, (HDC hDC, GLuint *count)) +AGL_API(BOOL, ResetFrameCountNV, (HDC hDC)) + +/* WGL_NV_gpu_affinity */ +AGL_API(BOOL, EnumGpusNV, (UINT, HGPUNV *)) +AGL_API(BOOL, EnumGpuDevicesNV, (HGPUNV, UINT, PGPU_DEVICE)) +AGL_API(HDC, CreateAffinityDCNV, (const HGPUNV *)) +AGL_API(BOOL, EnumGpusFromAffinityDCNV, (HDC, UINT, HGPUNV *)) +AGL_API(BOOL, DeleteDCNV, (HDC)) + +/* WGL_AMD_gpu_association */ +AGL_API(UINT, GetGPUIDsAMD, (UINT, UINT *)) +AGL_API(INT, GetGPUInfoAMD, (UINT, int, GLenum, UINT, void *)) +AGL_API(UINT, GetContextGPUIDAMD, (HGLRC)) +AGL_API(HGLRC, CreateAssociatedContextAMD, (UINT)) +AGL_API(HGLRC, CreateAssociatedContextAttribsAMD, (UINT, HGLRC, const int *)) +AGL_API(BOOL, DeleteAssociatedContextAMD, (HGLRC)) +AGL_API(BOOL, MakeAssociatedContextCurrentAMD, (HGLRC)) +AGL_API(HGLRC, GetCurrentAssociatedContextAMD, (void)) +AGL_API(VOID, BlitContextFramebufferAMD, (HGLRC, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) + +/* WGL_NV_video_capture */ +AGL_API(BOOL, BindVideoCaptureDeviceNV, (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice)) +AGL_API(UINT, EnumerateVideoCaptureDevicesNV, (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList)) +AGL_API(BOOL, LockVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice)) +AGL_API(BOOL, QueryVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue)) +AGL_API(BOOL, ReleaseVideoCaptureDeviceNV, (HDC hDc, HVIDEOINPUTDEVICENV hDevice)) + +/* WGL_NV_copy_image */ +AGL_API(BOOL, CopyImageSubDataNV, (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth)) diff --git a/allegro/include/allegro5/opengl/GLext/wgl_ext_defs.h b/allegro/include/allegro5/opengl/GLext/wgl_ext_defs.h new file mode 100644 index 00000000..aed3eac5 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/wgl_ext_defs.h @@ -0,0 +1,386 @@ +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#endif + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer +DECLARE_HANDLE(HPBUFFERARB); +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#endif + + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float +#define AWGL_ARB_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +#endif + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define ERROR_INVALID_PROFILE_ARB 0x2096 +#endif + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer +DECLARE_HANDLE(HPBUFFEREXT); +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#endif + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#endif + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 +#endif + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 +#endif + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 +#endif + +#ifndef WGL_WIN_swap_hint +#define WGL_WIN_swap_hint +#endif + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 +#endif + +#ifndef WGL_NV_video_out +#define WGL_NV_video_out +DECLARE_HANDLE(HPVIDEODEV); +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC +#endif + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group +#endif + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity +DECLARE_HANDLE(HPGPUNV); +DECLARE_HANDLE(HGPUNV); + +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 +#endif + +#ifndef WGL_AMD_gpu_association +#define WGL_AMD_gpu_association +#define WGL_GPU_VENDOR_AMD 0x1F00 +#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 +#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define WGL_GPU_RAM_AMD 0x21A3 +#define WGL_GPU_CLOCK_AMD 0x21A4 +#define WGL_GPU_NUM_PIPES_AMD 0x21A5 +#define WGL_GPU_NUM_SIMD_AMD 0x21A6 +#define WGL_GPU_NUM_RB_AMD 0x21A7 +#define WGL_GPU_NUM_SPI_AMD 0x21A8 +#endif + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF +#endif + +#ifndef WGL_NV_copy_image +#define WGL_NV_copy_image +#endif diff --git a/allegro/include/allegro5/opengl/GLext/wgl_ext_list.h b/allegro/include/allegro5/opengl/GLext/wgl_ext_list.h new file mode 100644 index 00000000..1fd69621 --- /dev/null +++ b/allegro/include/allegro5/opengl/GLext/wgl_ext_list.h @@ -0,0 +1,38 @@ +AGL_EXT(ARB_buffer_region, 0) +AGL_EXT(ARB_multisample, 0) +AGL_EXT(ARB_extensions_string, 0) +AGL_EXT(ARB_pixel_format, 0) +AGL_EXT(ARB_make_current_read, 0) +AGL_EXT(ARB_pbuffer, 0) +AGL_EXT(ARB_render_texture, 0) +AGL_EXT(ARB_pixel_format_float, 0) +AGL_EXT(EXT_display_color_table, 0) +AGL_EXT(EXT_extensions_string, 0) +AGL_EXT(EXT_make_current_read, 0) +AGL_EXT(EXT_pixel_format, 0) +AGL_EXT(EXT_pbuffer, 0) +AGL_EXT(EXT_swap_control, 0) +AGL_EXT(EXT_depth_float, 0) +AGL_EXT(EXT_multisample, 0) +AGL_EXT(OML_sync_control, 0) +AGL_EXT(I3D_digital_video_control, 0) +AGL_EXT(I3D_gamma, 0) +AGL_EXT(I3D_genlock, 0) +AGL_EXT(I3D_image_buffer, 0) +AGL_EXT(I3D_swap_frame_lock, 0) +AGL_EXT(I3D_swap_frame_usage, 0) +AGL_EXT(NV_render_depth_texture, 0) +AGL_EXT(NV_render_texture_rectangle, 0) +AGL_EXT(ATI_pixel_format_float, 0) +AGL_EXT(EXT_framebuffer_sRGB, 0) +AGL_EXT(EXT_pixel_format_packed_float,0) +AGL_EXT(WIN_swap_hint, 0) +AGL_EXT(3DL_stereo_control, 0) +AGL_EXT(NV_swap_group, 0) +AGL_EXT(NV_gpu_affinity, 0) +AGL_EXT(NV_video_out, 0) +AGL_EXT(NV_present_video, 0) +AGL_EXT(ARB_create_context, 0) +AGL_EXT(AMD_gpu_association, 0) +AGL_EXT(NV_copy_image, 0) +AGL_EXT(NV_video_capture, 0) diff --git a/allegro/include/allegro5/opengl/gl_ext.h b/allegro/include/allegro5/opengl/gl_ext.h new file mode 100644 index 00000000..5c137486 --- /dev/null +++ b/allegro/include/allegro5/opengl/gl_ext.h @@ -0,0 +1,145 @@ + +#ifndef __al_included_allegro5_gl_ext_h +#define __al_included_allegro5_gl_ext_h + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) + +/* + * MSVC declares the following extensions and MinGW doesn't. In order to + * export the same symbols on both platforms we removed the extensions from + * MSVC. + */ +#ifdef ALLEGRO_MSVC + #undef GL_EXT_vertex_array + #undef GL_EXT_paletted_texture + #undef GL_WIN_swap_hint + #undef GL_WIN_draw_range_elements +#endif + +/* GL extension definitions. */ + +/* For example: + * + * #define GL_BGRA 0x80E1 + * + */ + +#if !defined ALLEGRO_CFG_OPENGLES +#include "allegro5/opengl/GLext/gl_ext_defs.h" +#endif +#if defined ALLEGRO_WINDOWS && !defined ALLEGRO_EXCLUDE_WGL +#include "allegro5/opengl/GLext/wgl_ext_defs.h" +#elif defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX +#include "allegro5/opengl/GLext/glx_ext_defs.h" +#endif + +/* GL extension types */ + +/* For example: + * + * typedef void (APIENTRY * _ALLEGRO_glBlendEquation_t (GLenum); + * + */ + +#ifndef APIENTRY +#define APIENTRY +#define APIENTRY_defined +#endif + +#define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_gl##name##_t) args; +# include "allegro5/opengl/GLext/gl_ext_api.h" +#undef AGL_API +#ifdef ALLEGRO_WINDOWS +#define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_wgl##name##_t) args; +# include "allegro5/opengl/GLext/wgl_ext_api.h" +#undef AGL_API +#elif defined ALLEGRO_UNIX +#define AGL_API(type, name, args) typedef type (APIENTRY * _ALLEGRO_glX##name##_t) args; +# include "allegro5/opengl/GLext/glx_ext_api.h" +#undef AGL_API +#endif + +#ifdef APIENTRY_defined +#undef APIENTRY +#undef APIENTRY_defined +#endif + +/* GL extension declarations */ + +/* For example: + * + * #define glBlendEquation _al_glBlendEquation + * extern _ALLEGRO_glBlendEquation_t _al_glBlendEquation; + * + */ + +#define AGL_API(type, name, args) AL_VAR(_ALLEGRO_gl##name##_t, _al_gl##name); +# include "allegro5/opengl/GLext/gl_ext_alias.h" +# include "allegro5/opengl/GLext/gl_ext_api.h" +#undef AGL_API +#ifdef ALLEGRO_WINDOWS +#define AGL_API(type, name, args) AL_VAR(_ALLEGRO_wgl##name##_t, _al_wgl##name); +# include "allegro5/opengl/GLext/wgl_ext_alias.h" +# include "allegro5/opengl/GLext/wgl_ext_api.h" +#undef AGL_API +#elif defined ALLEGRO_UNIX +#define AGL_API(type, name, args) extern _ALLEGRO_glX##name##_t _al_glX##name; +# include "allegro5/opengl/GLext/glx_ext_alias.h" +# include "allegro5/opengl/GLext/glx_ext_api.h" +#undef AGL_API +#endif + +/* A list of all supported extensions. + * + * For example: + * int ALLEGRO_GL_ARB_imaging; + * + */ + +typedef struct ALLEGRO_OGL_EXT_LIST { +# define AGL_EXT(name, ver) int ALLEGRO_GL_##name; +# include "allegro5/opengl/GLext/gl_ext_list.h" +# undef AGL_EXT + +#ifdef ALLEGRO_UNIX +# define AGL_EXT(name, ver) int ALLEGRO_GLX_##name; +# include "allegro5/opengl/GLext/glx_ext_list.h" +# undef AGL_EXT +#elif defined ALLEGRO_WINDOWS +# define AGL_EXT(name, ver) int ALLEGRO_WGL_##name; +# include "allegro5/opengl/GLext/wgl_ext_list.h" +# undef AGL_EXT + +#endif +} ALLEGRO_OGL_EXT_LIST; + + +/* GL extension Structure. Holds the pointers to all the functions + * of all extensions, for a single context. + * + * Example: + * ALLEGRO_BlendEquation_t BlendEquation; + */ +typedef struct ALLEGRO_OGL_EXT_API { +#define AGL_API(type, name, args) _ALLEGRO_gl##name##_t name; +# include "allegro5/opengl/GLext/gl_ext_api.h" +#undef AGL_API +#ifdef ALLEGRO_WINDOWS +#define AGL_API(type, name, args) _ALLEGRO_wgl##name##_t name; +# include "allegro5/opengl/GLext/wgl_ext_api.h" +#undef AGL_API +#elif defined ALLEGRO_UNIX +#define AGL_API(type, name, args) _ALLEGRO_glX##name##_t name; +# include "allegro5/opengl/GLext/glx_ext_api.h" +#undef AGL_API +#endif +} ALLEGRO_OGL_EXT_API; + +#else + +typedef struct ALLEGRO_OGL_EXT_LIST ALLEGRO_OGL_EXT_LIST; + +#endif + +#endif + diff --git a/allegro/include/allegro5/path.h b/allegro/include/allegro5/path.h new file mode 100644 index 00000000..0eb78c62 --- /dev/null +++ b/allegro/include/allegro5/path.h @@ -0,0 +1,57 @@ +#ifndef __al_included_allegro5_path_h +#define __al_included_allegro5_path_h + +#include "allegro5/base.h" +#include "allegro5/utf8.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef ALLEGRO_WINDOWS +# define ALLEGRO_NATIVE_PATH_SEP '\\' +# define ALLEGRO_NATIVE_DRIVE_SEP ':' +#else +# define ALLEGRO_NATIVE_PATH_SEP '/' +# define ALLEGRO_NATIVE_DRIVE_SEP '\0' +#endif + +typedef struct ALLEGRO_PATH ALLEGRO_PATH; + +AL_FUNC(ALLEGRO_PATH*, al_create_path, (const char *str)); +AL_FUNC(ALLEGRO_PATH*, al_create_path_for_directory, (const char *str)); +AL_FUNC(ALLEGRO_PATH*, al_clone_path, (const ALLEGRO_PATH *path)); + +AL_FUNC(int, al_get_path_num_components, (const ALLEGRO_PATH *path)); +AL_FUNC(const char*, al_get_path_component, (const ALLEGRO_PATH *path, int i)); +AL_FUNC(void, al_replace_path_component, (ALLEGRO_PATH *path, int i, const char *s)); +AL_FUNC(void, al_remove_path_component, (ALLEGRO_PATH *path, int i)); +AL_FUNC(void, al_insert_path_component, (ALLEGRO_PATH *path, int i, const char *s)); +AL_FUNC(const char*, al_get_path_tail, (const ALLEGRO_PATH *path)); +AL_FUNC(void, al_drop_path_tail, (ALLEGRO_PATH *path)); +AL_FUNC(void, al_append_path_component, (ALLEGRO_PATH *path, const char *s)); +AL_FUNC(bool, al_join_paths, (ALLEGRO_PATH *path, const ALLEGRO_PATH *tail)); +AL_FUNC(bool, al_rebase_path, (const ALLEGRO_PATH *head, ALLEGRO_PATH *tail)); +AL_FUNC(const char*, al_path_cstr, (const ALLEGRO_PATH *path, char delim)); +AL_FUNC(const ALLEGRO_USTR*, al_path_ustr, (const ALLEGRO_PATH *path, char delim)); +AL_FUNC(void, al_destroy_path, (ALLEGRO_PATH *path)); + +AL_FUNC(void, al_set_path_drive, (ALLEGRO_PATH *path, const char *drive)); +AL_FUNC(const char*, al_get_path_drive, (const ALLEGRO_PATH *path)); + +AL_FUNC(void, al_set_path_filename, (ALLEGRO_PATH *path, const char *filename)); +AL_FUNC(const char*, al_get_path_filename, (const ALLEGRO_PATH *path)); + +AL_FUNC(const char*, al_get_path_extension, (const ALLEGRO_PATH *path)); +AL_FUNC(bool, al_set_path_extension, (ALLEGRO_PATH *path, char const *extension)); +AL_FUNC(const char*, al_get_path_basename, (const ALLEGRO_PATH *path)); + +AL_FUNC(bool, al_make_path_canonical, (ALLEGRO_PATH *path)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/platform/aintandroid.h b/allegro/include/allegro5/platform/aintandroid.h new file mode 100644 index 00000000..1767200b --- /dev/null +++ b/allegro/include/allegro5/platform/aintandroid.h @@ -0,0 +1,37 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Some definitions for internal use by the Android library code. + * + * By Thomas Fjellstrom. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_aintandroid_h +#define __al_included_allegro5_aintandroid_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_display.h" + +ALLEGRO_PATH *_al_android_get_path(int id); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/allegro/include/allegro5/platform/aintiphone.h b/allegro/include/allegro5/platform/aintiphone.h new file mode 100644 index 00000000..f51f9a51 --- /dev/null +++ b/allegro/include/allegro5/platform/aintiphone.h @@ -0,0 +1,15 @@ +#ifndef __al_included_allegro5_aintiphone_h +#define __al_included_allegro5_aintiphone_h + +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/system.h" +#include "allegro5/platform/aintunix.h" + +ALLEGRO_DISPLAY_INTERFACE *_al_display_iphone(void); +ALLEGRO_SYSTEM_INTERFACE *_al_system_iphone(void); +ALLEGRO_PATH *_al_iphone_get_path(int id); + +#endif + diff --git a/allegro/include/allegro5/platform/aintlnx.h b/allegro/include/allegro5/platform/aintlnx.h new file mode 100644 index 00000000..f0866e34 --- /dev/null +++ b/allegro/include/allegro5/platform/aintlnx.h @@ -0,0 +1,103 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Some definitions for internal use by the Linux console code. + * + * By George Foot. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_aintlnx_h +#define __al_included_allegro5_aintlnx_h + +#ifdef __cplusplus +extern "C" { +#endif + + +/**************************************/ +/************ Driver lists ************/ +/**************************************/ + +extern _AL_DRIVER_INFO _al_linux_keyboard_driver_list[]; +extern _AL_DRIVER_INFO _al_linux_mouse_driver_list[]; + +#ifdef ALLEGRO_RASPBERRYPI +#define AL_MOUSEDRV_LINUX_EVDEV AL_ID('E', 'V', 'D', 'V') +#endif + +/****************************************/ +/************ Memory mapping ************/ /* (src/linux/lmemory.c) */ +/****************************************/ + +/* struct MAPPED_MEMORY: Used to describe a block of memory mapped + * into our address space (in particular, the video memory). + */ +struct MAPPED_MEMORY { + unsigned int base, size; /* linear address and size of block */ + int perms; /* PROT_READ | PROT_WRITE, etc */ + void *data; /* pointer to block after mapping */ +}; + +extern int __al_linux_have_ioperms; + +int __al_linux_init_memory (void); +int __al_linux_shutdown_memory (void); +int __al_linux_map_memory (struct MAPPED_MEMORY *info); +int __al_linux_unmap_memory (struct MAPPED_MEMORY *info); + + +/******************************************/ +/************ Console routines ************/ /* (src/linux/lconsole.c) */ +/******************************************/ + +extern int __al_linux_vt; +extern int __al_linux_console_fd; +extern int __al_linux_prev_vt; +extern int __al_linux_got_text_message; +extern struct termios __al_linux_startup_termio; +extern struct termios __al_linux_work_termio; + +int __al_linux_use_console (void); +int __al_linux_leave_console (void); + +int __al_linux_console_graphics (void); +int __al_linux_console_text (void); + +int __al_linux_wait_for_display (void); + + +/**************************************/ +/************ VT switching ************/ /* (src/linux/vtswitch.c) */ +/**************************************/ + +/* signals for VT switching */ +#define SIGRELVT SIGUSR1 +#define SIGACQVT SIGUSR2 + +int __al_linux_init_vtswitch (void); +int __al_linux_done_vtswitch (void); + +int __al_linux_set_display_switch_mode (int mode); +void __al_linux_display_switch_lock (int lock, int foreground); + +extern volatile int __al_linux_switching_blocked; + + + +#ifdef __cplusplus +} +#endif + + + +#endif + diff --git a/allegro/include/allegro5/platform/aintosx.h b/allegro/include/allegro5/platform/aintosx.h new file mode 100644 index 00000000..5d0c7e63 --- /dev/null +++ b/allegro/include/allegro5/platform/aintosx.h @@ -0,0 +1,170 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Internal header file for the MacOS X Allegro library port. + * + * By Angelo Mottola. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_aintosx_h +#define __al_included_allegro5_aintosx_h + +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/platform/aintunix.h" + +#ifdef __OBJC__ + +#include +#include +#include +#include +#include +#include + + +#ifndef NSAppKitVersionNumber10_1 +#define NSAppKitVersionNumber10_1 620 +#endif +#ifndef NSAppKitVersionNumber10_2 +#define NSAppKitVersionNumber10_2 663 +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 +#error Cannot target OS X versions before 10.4 +#endif + +/* We include code to detect a "dead bootstrap context" and fail + * gracefully if that situation is detected, but some of the code uses + * deprecated functions and it isn't generally clear what "dead bootstrap + * context" means (google's first result points back to Allegro). It is + * also not clear if the problem this aims to solve still occurs on recent + * versions of OS X. + * Define OSX_BOOTSTRAP_DETECTION to compile this check in. It can + * be brought back/reactivated when someone finds out how. + */ +//#define OSX_BOOTSTRAP_DETECTION + + +#define HID_MAX_DEVICES MAX_JOYSTICKS +#define HID_MOUSE 0 +#define HID_JOYSTICK 1 +#define HID_GAMEPAD 2 + +#define HID_MAX_DEVICE_ELEMENTS ((MAX_JOYSTICK_AXIS * MAX_JOYSTICK_STICKS) + MAX_JOYSTICK_BUTTONS) +#define HID_ELEMENT_BUTTON 0 +#define HID_ELEMENT_AXIS 1 +#define HID_ELEMENT_AXIS_PRIMARY_X 2 +#define HID_ELEMENT_AXIS_PRIMARY_Y 3 +#define HID_ELEMENT_STANDALONE_AXIS 4 +#define HID_ELEMENT_HAT 5 + + +/* If we've included IOKit, generate the full definition + * otherwise just a forward definition + */ +#ifdef _IOKIT_HID_IOHIDLIB_H_ + +typedef struct HID_ELEMENT +{ + int type; + IOHIDElementCookie cookie; + int max, min; + int app; + int col; + int index; + char *name; +} HID_ELEMENT; + + +typedef struct HID_DEVICE +{ + int type; + char *manufacturer; + char *product; + int num_elements; + int capacity; + HID_ELEMENT *element; + IOHIDDeviceInterface **interface; + int cur_app; +} HID_DEVICE; + +typedef struct +{ + int count; + int capacity; + HID_DEVICE* devices; +} HID_DEVICE_COLLECTION; +#else +typedef struct HID_ELEMENT HID_ELEMENT; +typedef struct HID_DEVICE HID_DEVICE; +typedef struct HID_DEVICE_COLLECTION HID_DEVICE_COLLECTION; +#endif + +int _al_osx_bootstrap_ok(void); + +void _al_osx_keyboard_handler(int pressed, NSEvent *event, ALLEGRO_DISPLAY*); +void _al_osx_keyboard_modifiers(unsigned int new_mods, ALLEGRO_DISPLAY*); +void _al_osx_keyboard_focused(int focused, int state); + +void _al_osx_mouse_generate_event(NSEvent*, ALLEGRO_DISPLAY*); +void _al_osx_mouse_handler(NSEvent*); +int _al_osx_mouse_set_sprite(ALLEGRO_BITMAP *sprite, int x, int y); +int _al_osx_mouse_show(ALLEGRO_BITMAP *bmp, int x, int y); +void _al_osx_mouse_hide(void); +void _al_osx_mouse_move(int x, int y); + +HID_DEVICE_COLLECTION *_al_osx_hid_scan(int type, HID_DEVICE_COLLECTION*); +void _al_osx_hid_free(HID_DEVICE_COLLECTION *); + +// Record in the keyboard state that the main window has changed +void _al_osx_switch_keyboard_focus(ALLEGRO_DISPLAY *, bool switch_in); +// Record in the mouse state that the main window has changed +void _al_osx_switch_mouse_focus(ALLEGRO_DISPLAY *, bool switch_in); +// Clear the mouse state when a dialog closes in the dialog addon +void _al_osx_clear_mouse_state(void); +// Notify the display that the mouse driver was installed/uninstalled. +void _al_osx_mouse_was_installed(BOOL); +// Create and destroy mouse cursors +ALLEGRO_MOUSE_CURSOR *_al_osx_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus); +void _al_osx_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *curs); +// Notify the display that the keyboard driver was installed/uninstalled. +void _al_osx_keyboard_was_installed(BOOL); +// Notify that the quit menu was clicked +void _al_osx_post_quit(void); +// Get the underlying view +NSView* _al_osx_view_from_display(ALLEGRO_DISPLAY*); +// Create an image from an allegro bitmap +NSImage* NSImageFromAllegroBitmap(ALLEGRO_BITMAP* bmp); +// Drivers +AL_FUNC(ALLEGRO_KEYBOARD_DRIVER*, _al_osx_get_keyboard_driver, (void)); +AL_FUNC(ALLEGRO_DISPLAY_INTERFACE*, _al_osx_get_display_driver, (void)); +AL_FUNC(ALLEGRO_MOUSE_DRIVER*, _al_osx_get_mouse_driver, (void)); +AL_FUNC(ALLEGRO_JOYSTICK_DRIVER*, _al_osx_get_joystick_driver, (void)); +#endif + +AL_FUNC(int, _al_osx_run_main, (int argc, char **argv, + int (*real_main)(int, char **))); + +#endif + +/* Local variables: */ +/* mode: objc */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/allegro/include/allegro5/platform/aintraspberrypi.h b/allegro/include/allegro5/platform/aintraspberrypi.h new file mode 100644 index 00000000..ec46db21 --- /dev/null +++ b/allegro/include/allegro5/platform/aintraspberrypi.h @@ -0,0 +1,36 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Some definitions for internal use by the Raspberry Pi library code. + * + * By Trent Gamblin. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_aintraspberrypi_h +#define __al_included_allegro5_aintraspberrypi_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "allegro5/platform/aintunix.h" + +#include "allegro5/internal/aintern_keyboard.h" + +ALLEGRO_KEYBOARD_DRIVER *_al_xwin_keyboard_driver(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/allegro/include/allegro5/platform/aintunix.h b/allegro/include/allegro5/platform/aintunix.h new file mode 100644 index 00000000..6126c4e7 --- /dev/null +++ b/allegro/include/allegro5/platform/aintunix.h @@ -0,0 +1,95 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Some definitions for internal use by the Unix library code. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_aintunix_h +#define __al_included_allegro5_aintunix_h + +#include "allegro5/altime.h" +#include "allegro5/path.h" +#include "allegro5/internal/aintern_driver.h" + +/* Need right now for XKeyEvent --pw */ +#ifdef ALLEGRO_WITH_XWINDOWS +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +ALLEGRO_PATH *_al_unix_get_path(int id); +double _al_unix_get_time(void); +void _al_unix_rest(double seconds); +void _al_unix_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds); + + +#ifdef __cplusplus +} +#endif + + +#ifdef ALLEGRO_LINUX + #include "allegro5/platform/aintlnx.h" +#endif + + + +/*----------------------------------------------------------------------* + * * + * New stuff * + * * + *----------------------------------------------------------------------*/ + +/* TODO: integrate this above */ + +#include "allegro5/platform/aintuthr.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +/* time */ +void _al_unix_init_time(void); + +/* fdwatch */ +void _al_unix_start_watching_fd(int fd, void (*callback)(void *), void *cb_data); +void _al_unix_stop_watching_fd(int fd); + +/* ljoynu.c */ +/* This isn't in aintlnx.h because it's needed for the X11 port as well. */ +#define _ALLEGRO_JOYDRV_LINUX AL_ID('L','N','X','A') + +#ifdef ALLEGRO_HAVE_LINUX_INPUT_H +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_linux); +#endif + +/* lhaptic.c */ +/* This isn't in aintlnx.h because it's needed for the X11 port as well. */ +#define _ALLEGRO_HAPDRV_LINUX AL_ID('L','N','X','H') + +#ifdef ALLEGRO_HAVE_LINUX_INPUT_H +AL_VAR(struct ALLEGRO_HAPTIC_DRIVER, _al_hapdrv_linux); +#endif + + +#ifdef __cplusplus + } +#endif + + +#endif diff --git a/allegro/include/allegro5/platform/aintuthr.h b/allegro/include/allegro5/platform/aintuthr.h new file mode 100644 index 00000000..809753ae --- /dev/null +++ b/allegro/include/allegro5/platform/aintuthr.h @@ -0,0 +1,101 @@ +/* + * UNIX threads + */ +#ifndef __al_included_allegro5_aintuthr_h +#define __al_included_allegro5_aintuthr_h + +#include +#include "allegro5/internal/aintern_thread.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* threads */ +struct _AL_THREAD +{ + /* private: */ + pthread_t thread; + pthread_mutex_t mutex; + bool should_stop; + void (*proc)(struct _AL_THREAD *self, void *arg); + void *arg; +}; + +struct _AL_MUTEX +{ + bool inited; + pthread_mutex_t mutex; +}; + +#define _AL_MUTEX_UNINITED { false, PTHREAD_MUTEX_INITIALIZER } + /* makes no sense, but shuts gcc up */ +#define _AL_MARK_MUTEX_UNINITED(M) do { M.inited = false; } while (0) + +struct _AL_COND +{ + pthread_cond_t cond; +}; + +typedef struct ALLEGRO_TIMEOUT_UNIX ALLEGRO_TIMEOUT_UNIX; +struct ALLEGRO_TIMEOUT_UNIX +{ + struct timespec abstime; +}; + + +AL_INLINE(bool, _al_get_thread_should_stop, (struct _AL_THREAD *t), +{ + bool ret; + pthread_mutex_lock(&t->mutex); + ret = t->should_stop; + pthread_mutex_unlock(&t->mutex); + return ret; +}) + + +AL_FUNC(void, _al_mutex_init, (struct _AL_MUTEX*)); +AL_FUNC(void, _al_mutex_destroy, (struct _AL_MUTEX*)); +AL_INLINE(void, _al_mutex_lock, (struct _AL_MUTEX *m), +{ + if (m->inited) + pthread_mutex_lock(&m->mutex); +}) +AL_INLINE(void, _al_mutex_unlock, (struct _AL_MUTEX *m), +{ + if (m->inited) + pthread_mutex_unlock(&m->mutex); +}) + +AL_INLINE(void, _al_cond_init, (struct _AL_COND *cond), +{ + pthread_cond_init(&cond->cond, NULL); +}) + +AL_INLINE(void, _al_cond_destroy, (struct _AL_COND *cond), +{ + pthread_cond_destroy(&cond->cond); +}) + +AL_INLINE(void, _al_cond_wait, (struct _AL_COND *cond, struct _AL_MUTEX *mutex), +{ + pthread_cond_wait(&cond->cond, &mutex->mutex); +}) + +AL_INLINE(void, _al_cond_broadcast, (struct _AL_COND *cond), +{ + pthread_cond_broadcast(&cond->cond); +}) + +AL_INLINE(void, _al_cond_signal, (struct _AL_COND *cond), +{ + pthread_cond_signal(&cond->cond); +}) + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/platform/aintwin.h b/allegro/include/allegro5/platform/aintwin.h new file mode 100644 index 00000000..a560c6c6 --- /dev/null +++ b/allegro/include/allegro5/platform/aintwin.h @@ -0,0 +1,303 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Some definitions for internal use by the Windows library code. + * + * By Stefan Schimanski. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_aintwin_h +#define __al_included_allegro5_aintwin_h + +#ifndef __al_included_allegro5_allegro_h + #error must include allegro.h first +#endif + +#ifndef ALLEGRO_WINDOWS + #error bad include +#endif + + +#include "allegro5/platform/aintwthr.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/system.h" + + +#define WINDOWS_RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) + + +#ifdef __cplusplus + extern "C" { +#endif + +/* user defined hooks into the main win32 event loop */ + +typedef bool (*ALLEGRO_DISPLAY_WIN_CALLBACK_PROC) + (ALLEGRO_DISPLAY *, UINT, WPARAM, LPARAM, LRESULT*, void *); + +typedef struct ALLEGRO_DISPLAY_WIN_CALLBACK ALLEGRO_DISPLAY_WIN_CALLBACK; + +struct ALLEGRO_DISPLAY_WIN_CALLBACK +{ + ALLEGRO_DISPLAY_WIN_CALLBACK_PROC proc; + void *userdata; +}; + +/* the extended display struct for Windows */ + +typedef struct ALLEGRO_DISPLAY_WIN ALLEGRO_DISPLAY_WIN; + +struct ALLEGRO_DISPLAY_WIN +{ + ALLEGRO_DISPLAY display; + + HWND window; + HCURSOR mouse_selected_hcursor; + bool mouse_cursor_shown; + + UINT adapter; + + /* + * The display thread must communicate with the main thread + * through these variables. + */ + volatile bool end_thread; /* The display thread should end */ + volatile bool thread_ended; /* The display thread has ended */ + + /* For internal use by drivers, when this has been set to true + * after al_resize_display called you can call acknowledge_resize + */ + bool can_acknowledge; + + /* For internal use by the windows driver. When this is set and a Windows + * window resize event is received by the window procedure, the event is + * ignored and this value is set to false. + */ + bool ignore_resize; + + /* Size to reset to when al_set_display_flag(FULLSCREEN_WINDOW, false) + * is called. + */ + int toggle_w; + int toggle_h; + + /* A list of user callbacks associated with the window messages */ + _AL_VECTOR msg_callbacks; +}; + + +/* standard path */ +ALLEGRO_PATH *_al_win_get_path(int id); + +/* thread routines */ +void _al_win_thread_init(void); +void _al_win_thread_exit(void); + +/* input routines */ +void _al_win_grab_input(ALLEGRO_DISPLAY_WIN *win_disp); + +/* keyboard routines */ +void _al_win_kbd_handle_key_press(int scode, int vcode, bool extended, + bool repeated, ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_kbd_handle_key_release(int scode, int vcode, bool extended, + ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_fix_modifiers(void); + +/* mouse routines */ +void _al_win_mouse_handle_move(int x, int y, bool abs, ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_mouse_handle_wheel(int raw_dz, bool abs, ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_mouse_handle_hwheel(int raw_dw, bool abs, ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_mouse_handle_button(int button, bool down, int x, int y, bool abs, ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_mouse_handle_leave(ALLEGRO_DISPLAY_WIN *win_display); +void _al_win_mouse_handle_enter(ALLEGRO_DISPLAY_WIN *win_display); + +/* joystick routines */ +void _al_win_joystick_dinput_unacquire(void *unused); +void _al_win_joystick_dinput_grab(void *ALLEGRO_DISPLAY_WIN); + +/* custom Allegro messages */ +extern UINT _al_win_msg_call_proc; +extern UINT _al_win_msg_suicide; + +/* main window routines */ +AL_FUNC(void, _al_win_wnd_schedule_proc, (HWND wnd, void (*proc)(void*), void *param)); +AL_FUNC(void, _al_win_wnd_call_proc, (HWND wnd, void (*proc)(void*), void *param)); + +int _al_win_determine_adapter(void); + +extern bool _al_win_disable_screensaver; + +/* dynamic library loading */ +HMODULE _al_win_safe_load_library(const char *filename); + +/* time */ +void _al_win_init_time(void); +void _al_win_shutdown_time(void); + +/* This is used to stop MinGW from complaining about type-punning */ +#define MAKE_UNION(ptr, t) \ + union { \ + LPVOID *v; \ + t p; \ + } u; \ + u.p = (ptr); + +typedef struct ALLEGRO_SYSTEM_WIN ALLEGRO_SYSTEM_WIN; +/* This is our version of ALLEGRO_SYSTEM with driver specific extra data. */ +struct ALLEGRO_SYSTEM_WIN +{ + ALLEGRO_SYSTEM system; /* This must be the first member, we "derive" from it. */ + ALLEGRO_DISPLAY *mouse_grab_display; /* May be inaccurate. */ + int toggle_mouse_grab_keycode; /* Disabled if zero. */ + unsigned int toggle_mouse_grab_modifiers; +}; + +/* helpers to create windows */ +HWND _al_win_create_window(ALLEGRO_DISPLAY *display, int width, int height, int flags); +HWND _al_win_create_faux_fullscreen_window(LPCTSTR devname, ALLEGRO_DISPLAY *display, + int x1, int y1, int width, int height, + int refresh_rate, int flags); +int _al_win_init_window(void); +HWND _al_win_create_hidden_window(void); +void _al_win_post_create_window(ALLEGRO_DISPLAY *display); + +/* icon helpers */ +void _al_win_set_display_icons(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *bitmap[]); +HICON _al_win_create_icon(HWND wnd, ALLEGRO_BITMAP *sprite, int xfocus, int yfocus, bool is_cursor, bool resize); +void _al_win_destroy_display_icons(ALLEGRO_DISPLAY *display); + +/* window decorations */ +void _al_win_set_window_position(HWND window, int x, int y); +void _al_win_get_window_position(HWND window, int *x, int *y); +bool _al_win_set_window_constraints(ALLEGRO_DISPLAY *display, int min_w, int min_h, int max_w, int max_h); +bool _al_win_get_window_constraints(ALLEGRO_DISPLAY *display, int *min_w, int *min_h, int *max_w, int *max_h); +void _al_win_apply_window_constraints(ALLEGRO_DISPLAY *display, bool onoff); +void _al_win_set_window_frameless(ALLEGRO_DISPLAY *display, HWND window, bool frameless); +bool _al_win_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff); +void _al_win_set_window_title(ALLEGRO_DISPLAY *display, const char *title); + +/* cursor routines */ +typedef struct ALLEGRO_MOUSE_CURSOR_WIN ALLEGRO_MOUSE_CURSOR_WIN; +struct ALLEGRO_MOUSE_CURSOR_WIN +{ + HCURSOR hcursor; +}; + +ALLEGRO_MOUSE_CURSOR* _al_win_create_mouse_cursor(ALLEGRO_BITMAP *sprite, int xfocus, int yfocus); +void _al_win_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor); +bool _al_win_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor); +bool _al_win_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id); +bool _al_win_show_mouse_cursor(ALLEGRO_DISPLAY *display); +bool _al_win_hide_mouse_cursor(ALLEGRO_DISPLAY *display); + + +/* driver specific functions */ + +#if defined ALLEGRO_CFG_D3D + ALLEGRO_DISPLAY_INTERFACE* _al_display_d3d_driver(void); + int _al_d3d_get_num_display_modes(int format, int refresh_rate, int flags); + ALLEGRO_DISPLAY_MODE* _al_d3d_get_display_mode(int index, int format, + int refresh_rate, int flags, + ALLEGRO_DISPLAY_MODE *mode); + void _al_d3d_shutdown_display(void); +#endif /* defined ALLEGRO_CFG_D3D */ + +#if defined ALLEGRO_CFG_OPENGL + ALLEGRO_DISPLAY_INTERFACE *_al_display_wgl_driver(void); + int _al_wgl_get_num_display_modes(int format, int refresh_rate, int flags); + ALLEGRO_DISPLAY_MODE* _al_wgl_get_display_mode(int index, int format, + int refresh_rate, int flags, + ALLEGRO_DISPLAY_MODE *mode); +#endif /* defined ALLEGRO_CFG_OPENGL */ + + +/* touch input specific API */ + +#if (_WIN32_WINNT < 0x0601) +typedef struct tagTOUCHINPUT { + LONG x; + LONG y; + HANDLE hSource; + DWORD dwID; + DWORD dwFlags; + DWORD dwMask; + DWORD dwTime; + ULONG_PTR dwExtraInfo; + DWORD cxContact; + DWORD cyContact; +} TOUCHINPUT, *PTOUCHINPUT; +#endif + +/* Define those fellows. They are available on Windows SDK 7.0, + * which is shipped with Visual Studio 2010. So it is not likely they + * will be defined in . Also do not trust MinGW WinAPI + * headers as they are outdated. Version 3.15, which is newest at the + * time of writting this, still have invalid defines related to + * multi-touch support. + */ +#define _AL_WM_TOUCH 0x0240 + +#define _AL_MOUSEEVENTF_FROMTOUCH 0xFF515700 + +#define _AL_TOUCHEVENTF_MOVE 0x0001 +#define _AL_TOUCHEVENTF_DOWN 0x0002 +#define _AL_TOUCHEVENTF_UP 0x0004 +#define _AL_TOUCHEVENTF_PRIMARY 0x0010 + +#define _AL_SM_DIGITIZER 94 + +#define _AL_NID_READY 0x80 + + +/* set of function required to handle touch input on Windows */ +typedef BOOL (WINAPI *CLOSETOUCHINPUTHANDLEPROC)(HANDLE hTouchInput); +typedef BOOL (WINAPI *GETTOUCHINPUTINFOPROC)(HANDLE hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize); +typedef BOOL (WINAPI *ISTOUCHWINDOWPROC)(HWND hWnd, PULONG pulFlags); +typedef BOOL (WINAPI *REGISTERTOUCHWINDOWPROC)(HWND hWnd, ULONG ulFlags); +typedef BOOL (WINAPI *UNREGISTERTOUCHWINDOWPROC)(HWND hWnd); + +bool _al_win_init_touch_input_api(void); +void _al_win_exit_touch_input_api(void); + +extern CLOSETOUCHINPUTHANDLEPROC _al_win_close_touch_input_handle; +extern GETTOUCHINPUTINFOPROC _al_win_get_touch_input_info; +extern ISTOUCHWINDOWPROC _al_win_is_touch_window; +extern REGISTERTOUCHWINDOWPROC _al_win_register_touch_window; +extern UNREGISTERTOUCHWINDOWPROC _al_win_unregister_touch_window; + +/* touch input routines */ +void _al_win_touch_input_set_time_stamp(size_t timestamp); +void _al_win_touch_input_handle_begin(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_touch_input_handle_end(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_touch_input_handle_move(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp); +void _al_win_touch_input_handle_cancel(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp); + +/* Helpers for getting Windows system errors + * May be called from addons + */ +AL_FUNC(const char*, _al_win_error, (DWORD)); +AL_FUNC(const char*, _al_win_last_error, (void)); + +/* Time handling */ +double _al_win_get_time(void); +void _al_win_rest(double seconds); +void _al_win_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds); + +#ifdef __cplusplus + } +#endif + + +#endif + diff --git a/allegro/include/allegro5/platform/aintwiz.h b/allegro/include/allegro5/platform/aintwiz.h new file mode 100644 index 00000000..b48a1a94 --- /dev/null +++ b/allegro/include/allegro5/platform/aintwiz.h @@ -0,0 +1,16 @@ +#ifndef __al_included_allegro5_aintwiz_h +#define __al_included_allegro5_aintwiz_h + +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/system.h" +#include "allegro5/platform/aintunix.h" + +ALLEGRO_DISPLAY_INTERFACE *_al_display_gp2xwiz_opengl_driver(void); +ALLEGRO_DISPLAY_INTERFACE *_al_display_gp2xwiz_framebuffer_driver(void); +ALLEGRO_SYSTEM_INTERFACE *_al_system_gp2xwiz_driver(void); +ALLEGRO_BITMAP_INTERFACE *_al_bitmap_gp2xwiz_driver(void); + +#endif + diff --git a/allegro/include/allegro5/platform/aintwthr.h b/allegro/include/allegro5/platform/aintwthr.h new file mode 100644 index 00000000..cbe88c0f --- /dev/null +++ b/allegro/include/allegro5/platform/aintwthr.h @@ -0,0 +1,75 @@ +/* + * Windows threads + */ +#ifndef __al_included_allegro5_aintwthr_h +#define __al_included_allegro5_aintwthr_h + +#include + +#ifdef __cplusplus + extern "C" { +#endif + + +/* threads */ +struct _AL_THREAD +{ + /* private: */ + HANDLE thread; + CRITICAL_SECTION cs; + bool should_stop; /* XXX: use a dedicated terminate Event object? */ + void (*proc)(struct _AL_THREAD *self, void *arg); + void *arg; +}; + +struct _AL_MUTEX +{ + PCRITICAL_SECTION cs; +}; + +#define _AL_MUTEX_UNINITED { NULL } +#define _AL_MARK_MUTEX_UNINITED(M) do { M.cs = NULL; } while (0) + +struct _AL_COND +{ + long nWaitersBlocked; + long nWaitersGone; + long nWaitersToUnblock; + HANDLE semBlockQueue; + CRITICAL_SECTION semBlockLock; + CRITICAL_SECTION mtxUnblockLock; +}; + +typedef struct ALLEGRO_TIMEOUT_WIN ALLEGRO_TIMEOUT_WIN; +struct ALLEGRO_TIMEOUT_WIN +{ + DWORD abstime; +}; + + +AL_INLINE(bool, _al_get_thread_should_stop, (struct _AL_THREAD *t), +{ + bool ret; + EnterCriticalSection(&t->cs); + ret = t->should_stop; + LeaveCriticalSection(&t->cs); + return ret; +}) + +AL_INLINE(void, _al_mutex_lock, (struct _AL_MUTEX *m), +{ + if (m->cs) + EnterCriticalSection(m->cs); +}) +AL_INLINE(void, _al_mutex_unlock, (struct _AL_MUTEX *m), +{ + if (m->cs) + LeaveCriticalSection(m->cs); +}) + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/platform/aintxglx.h b/allegro/include/allegro5/platform/aintxglx.h new file mode 100644 index 00000000..6a528450 --- /dev/null +++ b/allegro/include/allegro5/platform/aintxglx.h @@ -0,0 +1,7 @@ +#ifndef __al_included_allegro5_aintxglx_h +#define __al_included_allegro5_aintxglx_h + +ALLEGRO_DISPLAY_INTERFACE *_al_display_xglx_driver(void); +ALLEGRO_SYSTEM_INTERFACE *_al_system_xglx_driver(void); + +#endif diff --git a/allegro/include/allegro5/platform/alandroid.h b/allegro/include/allegro5/platform/alandroid.h new file mode 100644 index 00000000..261cd7df --- /dev/null +++ b/allegro/include/allegro5/platform/alandroid.h @@ -0,0 +1,29 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android-specific header defines. + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_ANDROID + #error bad include +#endif + +#include + +#ifdef __cplusplus +extern "C" int main(int argc, char ** argv); +#else +extern int main(int argc, char ** argv); +#endif + +/* Nothing left */ diff --git a/allegro/include/allegro5/platform/alandroidcfg.h b/allegro/include/allegro5/platform/alandroidcfg.h new file mode 100644 index 00000000..9399c43e --- /dev/null +++ b/allegro/include/allegro5/platform/alandroidcfg.h @@ -0,0 +1,25 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on Android platforms. + * + * By Thomas Fjellstrom. + * + * See readme.txt for copyright information. + */ + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "Android" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alandroid.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintandroid.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +#define ALLEGRO_EXCLUDE_GLX diff --git a/allegro/include/allegro5/platform/albcc32.h b/allegro/include/allegro5/platform/albcc32.h new file mode 100644 index 00000000..ca6bbc26 --- /dev/null +++ b/allegro/include/allegro5/platform/albcc32.h @@ -0,0 +1,97 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with Borland C++Builder. + * + * By Greg Hackmann. + * + * See readme.txt for copyright information. + */ + + +/* +#ifdef ALLEGRO_SRC + #error Currently BCC32 cannot build the library +#endif +*/ + + +#include +#include +#include +#include + + +#pragma warn -8004 /* unused assigned value */ +#pragma warn -8008 /* condition always met */ +#pragma warn -8057 /* unused parameter */ +#pragma warn -8066 /* unreachable code */ + + +/* describe this platform */ +#define ALLEGRO_PLATFORM_STR "BCC32" +#define ALLEGRO_WINDOWS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN +#define ALLEGRO_GUESS_INTTYPES_OK + /* TODO: check if BCC has inttypes.h and/or stdint.h */ + +#ifdef ALLEGRO_USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN +#endif + + +/* describe how function prototypes look to BCC32 */ +#if (defined ALLEGRO_STATICLINK) + #define _AL_DLL +#elif (defined ALLEGRO_SRC) + #define _AL_DLL __declspec(dllexport) +#else + #define _AL_DLL __declspec(dllimport) +#endif + +#define AL_VAR(type, name) extern _AL_DLL type name +#define AL_ARRAY(type, name) extern _AL_DLL type name[] +#define AL_FUNC(type, name, args) extern _AL_DLL type name args +#define AL_METHOD(type, name, args) type (*name) args +#define AL_FUNCPTR(type, name, args) extern _AL_DLL type (*name) args + + +#define END_OF_INLINE(name) +//#define AL_INLINE(type, name, args, code) extern __inline type name args code END_OF_INLINE(name) + +#define INLINE __inline + +#undef AL_INLINE +#undef AL_INLINE_STATIC + +#define AL_INLINE(type, name, args, code) extern __inline type __cdecl name args code END_OF_INLINE(name) +#define AL_INLINE_STATIC(type, name, args, code) static __inline type name args code END_OF_INLINE(name) + +#define int64_t signed __int64 +#define uint64_t unsigned __int64 + +#define __func__ "FIXME" + +#define _wfindfirst __wfindfirst +#define _wfindnext __wfindnext + +#define WinMain _main + +/* windows specific defines */ +#ifdef NONAMELESSUNION + #undef NONAMELESSUNION +#endif +/* This fixes 99.999999% of Borland C++Builder's problems with structs. */ + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" diff --git a/allegro/include/allegro5/platform/aldmc.h b/allegro/include/allegro5/platform/aldmc.h new file mode 100644 index 00000000..2063ad78 --- /dev/null +++ b/allegro/include/allegro5/platform/aldmc.h @@ -0,0 +1,85 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with Digital Mars C compiler. + * + * By Matthew Leverton. + * + * See readme.txt for copyright information. + */ + + +#include +#include + +#include + + +/* a static auto config */ +#define ALLEGRO_HAVE_INTTYPES_H +#define ALLEGRO_HAVE_STDINT_H + +#define LONG_LONG long long + +/* describe this platform */ +#ifdef ALLEGRO_STATICLINK + #define ALLEGRO_PLATFORM_STR "DMC.s" +#else + #define ALLEGRO_PLATFORM_STR "DMC" +#endif + +#define ALLEGRO_WINDOWS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN + +#ifdef ALLEGRO_USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN +#endif + + +/* describe how function prototypes look to DMC */ +#if (defined ALLEGRO_STATICLINK) || (defined ALLEGRO_SRC) + #define _AL_DLL +#else + #define _AL_DLL __declspec(dllimport) +#endif + +#define AL_VAR(type, name) extern _AL_DLL type name +#define AL_ARRAY(type, name) extern _AL_DLL type name[] +#define AL_FUNC(type, name, args) extern type name args +#define AL_METHOD(type, name, args) type (*name) args +#define AL_FUNCPTR(type, name, args) extern _AL_DLL type (*name) args + + +/* Windows specific defines */ + +#if (defined ALLEGRO_SRC) + +#if (!defined S_IRUSR) + #define S_IRUSR S_IREAD + #define S_IWUSR S_IWRITE +#endif + +typedef unsigned long _fsize_t; + +struct _wfinddata_t { + unsigned attrib; + time_t time_create; /* -1 for FAT file systems */ + time_t time_access; /* -1 for FAT file systems */ + time_t time_write; + _fsize_t size; + wchar_t name[260]; /* may include spaces. */ +}; + +#endif /* ALLEGRO_SRC */ + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" diff --git a/allegro/include/allegro5/platform/aliphone.h b/allegro/include/allegro5/platform/aliphone.h new file mode 100644 index 00000000..228c07ee --- /dev/null +++ b/allegro/include/allegro5/platform/aliphone.h @@ -0,0 +1,11 @@ +#ifndef ALLEGRO_IPHONE + #error bad include +#endif + +#ifndef ALLEGRO_LIB_BUILD +#define ALLEGRO_MAGIC_MAIN +#define main _al_mangled_main +#ifdef __cplusplus + extern "C" int _al_mangled_main(int, char **); +#endif +#endif diff --git a/allegro/include/allegro5/platform/aliphonecfg.h b/allegro/include/allegro5/platform/aliphonecfg.h new file mode 100644 index 00000000..a4739acc --- /dev/null +++ b/allegro/include/allegro5/platform/aliphonecfg.h @@ -0,0 +1,33 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on iOS. + * + * See readme.txt for copyright information. + */ + + +#include +#include + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "IPHONE" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/aliphone.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintiphone.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +#define ALLEGRO_EXCLUDE_GLX + +#ifndef AL_INLINE +#define AL_INLINE(type, name, args, code) \ +static __inline__ type name args; \ +static __inline__ type name args code +#endif diff --git a/allegro/include/allegro5/platform/allegro_internal_sdl.h b/allegro/include/allegro5/platform/allegro_internal_sdl.h new file mode 100644 index 00000000..61d42cd4 --- /dev/null +++ b/allegro/include/allegro5/platform/allegro_internal_sdl.h @@ -0,0 +1,52 @@ +#include "SDL.h" + +#include "allegro5/altime.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_system.h" + +typedef struct +{ + ALLEGRO_SYSTEM system; + ALLEGRO_MUTEX *mutex; + #ifdef __EMSCRIPTEN__ + double timer_time; + #endif +} ALLEGRO_SYSTEM_SDL; + +typedef struct ALLEGRO_DISPLAY_SDL +{ + ALLEGRO_DISPLAY display; /* This must be the first member. */ + + int x, y; + SDL_Window *window; + SDL_GLContext context; +} ALLEGRO_DISPLAY_SDL; + +ALLEGRO_SYSTEM_INTERFACE *_al_sdl_system_driver(void); +ALLEGRO_DISPLAY_INTERFACE *_al_sdl_display_driver(void); +ALLEGRO_KEYBOARD_DRIVER *_al_sdl_keyboard_driver(void); +ALLEGRO_MOUSE_DRIVER *_al_sdl_mouse_driver(void); +ALLEGRO_TOUCH_INPUT_DRIVER *_al_sdl_touch_input_driver(void); +ALLEGRO_JOYSTICK_DRIVER *_al_sdl_joystick_driver(void); +ALLEGRO_BITMAP_INTERFACE *_al_sdl_bitmap_driver(void); + +void _al_sdl_keyboard_event(SDL_Event *e); +void _al_sdl_mouse_event(SDL_Event *e); +void _al_sdl_touch_input_event(SDL_Event *e); +void _al_sdl_display_event(SDL_Event *e); +void _al_sdl_joystick_event(SDL_Event *e); + +int _al_sdl_get_allegro_pixel_format(int sdl_format); +int _al_sdl_get_sdl_pixel_format(int allegro_format); + +ALLEGRO_DISPLAY *_al_sdl_find_display(uint32_t window_id); +float _al_sdl_get_display_pixel_ratio(ALLEGRO_DISPLAY *display); + +void _al_sdl_event_hack(void); + +double _al_sdl_get_time(void); +void _al_sdl_rest(double seconds); +void _al_sdl_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds); diff --git a/allegro/include/allegro5/platform/allegro_sdl_config.h b/allegro/include/allegro5/platform/allegro_sdl_config.h new file mode 100644 index 00000000..79e98d1b --- /dev/null +++ b/allegro/include/allegro5/platform/allegro_sdl_config.h @@ -0,0 +1,8 @@ +#define ALLEGRO_PLATFORM_STR "SDL" + +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/allegro_internal_sdl.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/allegro_sdl_thread.h" + +// FIXME: remove once we don't use Unix specifics anymore +#include +#include diff --git a/allegro/include/allegro5/platform/allegro_sdl_thread.h b/allegro/include/allegro5/platform/allegro_sdl_thread.h new file mode 100644 index 00000000..ed00cab3 --- /dev/null +++ b/allegro/include/allegro5/platform/allegro_sdl_thread.h @@ -0,0 +1,88 @@ +#ifndef __al_included_allegro5_allegro_sdl_thread_h +#define __al_included_allegro5_allegro_sdl_thread_h + +#include "SDL.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +struct _AL_MUTEX +{ + SDL_mutex *mutex; +}; + +struct _AL_THREAD +{ + /* private: */ + SDL_Thread *thread; + bool should_stop; + void (*proc)(struct _AL_THREAD *self, void *arg); + void *arg; +}; + +#define _AL_MUTEX_UNINITED { NULL } +#define _AL_MARK_MUTEX_UNINITED(M) do { M.mutex = NULL; } while (0) + +struct _AL_COND +{ + SDL_cond *cond; +}; + +typedef struct ALLEGRO_TIMEOUT_SDL ALLEGRO_TIMEOUT_SDL; +struct ALLEGRO_TIMEOUT_SDL +{ + int ms; +}; + +AL_INLINE(bool, _al_get_thread_should_stop, (struct _AL_THREAD *t), +{ + return t->should_stop; +}) + + +AL_FUNC(void, _al_mutex_init, (struct _AL_MUTEX*)); +AL_FUNC(void, _al_mutex_destroy, (struct _AL_MUTEX*)); +AL_INLINE(void, _al_mutex_lock, (struct _AL_MUTEX *m), +{ + if (m->mutex) + SDL_LockMutex(m->mutex); +}) +AL_INLINE(void, _al_mutex_unlock, (struct _AL_MUTEX *m), +{ + if (m->mutex) + SDL_UnlockMutex(m->mutex); +}) + +AL_INLINE(void, _al_cond_init, (struct _AL_COND *cond), +{ + cond->cond = SDL_CreateCond(); +}) + +AL_INLINE(void, _al_cond_destroy, (struct _AL_COND *cond), +{ + SDL_DestroyCond(cond->cond); +}) + +AL_INLINE(void, _al_cond_wait, (struct _AL_COND *cond, struct _AL_MUTEX *mutex), +{ + SDL_CondWait(cond->cond, mutex->mutex); +}) + +AL_INLINE(void, _al_cond_broadcast, (struct _AL_COND *cond), +{ + SDL_CondBroadcast(cond->cond); +}) + +AL_INLINE(void, _al_cond_signal, (struct _AL_COND *cond), +{ + SDL_CondSignal(cond->cond); +}) + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/platform/almngw32.h b/allegro/include/allegro5/platform/almngw32.h new file mode 100644 index 00000000..cfda24fd --- /dev/null +++ b/allegro/include/allegro5/platform/almngw32.h @@ -0,0 +1,84 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with Mingw32. + * + * By Michael Rickmann. + * + * Native build version by Henrik Stokseth. + * + * See readme.txt for copyright information. + */ + + +#include +#include +#include +#include + +#include "allegro5/platform/alplatf.h" + + +/* describe this platform */ +#ifdef ALLEGRO_STATICLINK + #define ALLEGRO_PLATFORM_STR "MinGW32.s" +#else + #define ALLEGRO_PLATFORM_STR "MinGW32" +#endif + +#define ALLEGRO_WINDOWS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN + +#ifdef ALLEGRO_USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN +#endif + + +/* describe how function prototypes look to MINGW32 */ +#if (defined ALLEGRO_STATICLINK) || (defined ALLEGRO_SRC) + #define _AL_DLL +#else + #define _AL_DLL __declspec(dllimport) +#endif + +#define AL_VAR(type, name) extern _AL_DLL type name +#define AL_ARRAY(type, name) extern _AL_DLL type name[] +#define AL_FUNC(type, name, args) extern type name args +#define AL_METHOD(type, name, args) type (*name) args +#define AL_FUNCPTR(type, name, args) extern _AL_DLL type (*name) args + + +/* windows specific defines */ + +#if (defined ALLEGRO_SRC) +/* pathches to handle DX7 headers on a win9x system */ + +/* should WINNT be defined on win9x systems? */ +#ifdef WINNT + #undef WINNT +#endif + +/* defined in windef.h */ +#ifndef HMONITOR_DECLARED + #define HMONITOR_DECLARED 1 +#endif + +#endif /* ALLEGRO_SRC */ + +/* another instance of missing constants in the mingw32 headers */ +#ifndef ENUM_CURRENT_SETTINGS + #define ENUM_CURRENT_SETTINGS ((DWORD)-1) +#endif + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" diff --git a/allegro/include/allegro5/platform/almsvc.h b/allegro/include/allegro5/platform/almsvc.h new file mode 100644 index 00000000..9a3cdf56 --- /dev/null +++ b/allegro/include/allegro5/platform/almsvc.h @@ -0,0 +1,105 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with MSVC. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#include +#include +#include +#include + +#include "allegro5/platform/alplatf.h" + +#pragma warning (disable: 4200 4244 4305 4800) + + +/* describe this platform */ +#ifdef ALLEGRO_STATICLINK + #define ALLEGRO_PLATFORM_STR "MSVC.s" +#else + #define ALLEGRO_PLATFORM_STR "MSVC" +#endif + +#define ALLEGRO_WINDOWS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN +#define ALLEGRO_GUESS_INTTYPES_OK + +#ifdef ALLEGRO_USE_CONSOLE + #define ALLEGRO_NO_MAGIC_MAIN +#endif + + +/* describe how function prototypes look to MSVC */ +#ifndef ALLEGRO_STATICLINK + #ifdef ALLEGRO_SRC + #define _AL_DLL __declspec(dllexport) + #else + #define _AL_DLL __declspec(dllimport) + #endif +#else + #define _AL_DLL +#endif + +#define AL_VAR(type, name) extern _AL_DLL type name +#define AL_ARRAY(type, name) extern _AL_DLL type name[] +#define AL_FUNC(type, name, args) _AL_DLL type __cdecl name args +#define AL_METHOD(type, name, args) type (__cdecl *name) args +#define AL_FUNCPTR(type, name, args) extern _AL_DLL type (__cdecl *name) args + +#ifdef AL_INLINE + #define END_OF_INLINE(name) void *_force_instantiate_##name = name; +#else + #define END_OF_INLINE(name) +#endif + +#undef AL_INLINE +#undef AL_INLINE_STATIC + +#define AL_INLINE(type, name, args, code) __inline _AL_DLL type __cdecl name args code END_OF_INLINE(name) +#define AL_INLINE_STATIC(type, name, args, code) __inline type __cdecl name args code END_OF_INLINE(name) + +#define INLINE __inline + +/* VC10 is the first version to define int64_t and uint64_t */ +#if _MSC_VER < 1600 +#define int64_t signed __int64 +#define uint64_t unsigned __int64 +#endif + +/* __func__ is C99 */ +#ifndef __func__ + /* MSVC versions before VC7 don't have __FUNCTION__ */ + #if _MSC_VER < 1300 + #define __func__ "???" + #else + #define __func__ __FUNCTION__ + #endif +#endif + + +/* life would be so easy if compilers would all use the same names! */ +#if (!defined S_IRUSR) + #define S_IRUSR S_IREAD + #define S_IWUSR S_IWRITE + #define S_IXUSR S_IEXEC +#endif + + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwin.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwin.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintwthr.h" diff --git a/allegro/include/allegro5/platform/alosx.h b/allegro/include/allegro5/platform/alosx.h new file mode 100644 index 00000000..d9845b92 --- /dev/null +++ b/allegro/include/allegro5/platform/alosx.h @@ -0,0 +1,79 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * MacOS X specific header defines. + * + * By Angelo Mottola. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_alosx_h +#define __al_included_allegro5_alosx_h + +#ifndef ALLEGRO_MACOSX + #error bad include +#endif + + + +#include +#include +#include +#include +#include +#include +#if defined __OBJC__ && defined ALLEGRO_SRC + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import +#endif + +ALLEGRO_PATH *_al_osx_get_path(int id); + +#ifndef ALLEGRO_LIB_BUILD + #ifndef ALLEGRO_NO_MAGIC_MAIN + #define ALLEGRO_MAGIC_MAIN + #if __GNUC__ >= 4 + #define main __attribute__ ((visibility("default"),used)) _al_mangled_main + #else + #define main _al_mangled_main + #endif + #ifdef __cplusplus + extern "C" int _al_mangled_main(int, char **); + /* We can't provide a prototype for C without restricting + * users into a single function signature for main(). + */ + #endif + #endif +#endif + +/* Keyboard driver */ +#define KEYBOARD_MACOSX AL_ID('O','S','X','K') + +#endif + +/* Local variables: */ +/* mode: objc */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/platform/alosxcfg.h b/allegro/include/allegro5/platform/alosxcfg.h new file mode 100644 index 00000000..830cf116 --- /dev/null +++ b/allegro/include/allegro5/platform/alosxcfg.h @@ -0,0 +1,36 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with MacOS X. + * + * By Angelo Mottola. + * + * See readme.txt for copyright information. + */ + + +#ifndef __al_included_allegro5_alosxcfg_h +#define __al_included_allegro5_alosxcfg_h + +/* Include configuration information. */ +#include "allegro5/platform/alplatf.h" + +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +/* Describe this platform */ +#define ALLEGRO_PLATFORM_STR "MacOS X" + + +/* Arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alosx.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintosx.h" + + +#endif diff --git a/allegro/include/allegro5/platform/alplatf.h.cmake b/allegro/include/allegro5/platform/alplatf.h.cmake new file mode 100644 index 00000000..a5cfcf82 --- /dev/null +++ b/allegro/include/allegro5/platform/alplatf.h.cmake @@ -0,0 +1,127 @@ +/* alplatf.h is generated from alplatf.h.cmake */ +#cmakedefine ALLEGRO_MINGW32 +#cmakedefine ALLEGRO_UNIX +#cmakedefine ALLEGRO_MSVC +#cmakedefine ALLEGRO_MACOSX +#cmakedefine ALLEGRO_BCC32 +#cmakedefine ALLEGRO_IPHONE +#cmakedefine ALLEGRO_ANDROID +#cmakedefine ALLEGRO_RASPBERRYPI +#cmakedefine ALLEGRO_CFG_NO_FPU +#cmakedefine ALLEGRO_CFG_DLL_TLS +#cmakedefine ALLEGRO_CFG_PTHREADS_TLS +#cmakedefine ALLEGRO_CFG_RELEASE_LOGGING + +#cmakedefine ALLEGRO_CFG_D3D +#cmakedefine ALLEGRO_CFG_D3D9EX +#cmakedefine ALLEGRO_CFG_D3DX9 +#cmakedefine ALLEGRO_CFG_XINPUT +#cmakedefine ALLEGRO_CFG_OPENGL +#cmakedefine ALLEGRO_CFG_OPENGLES +#cmakedefine ALLEGRO_CFG_OPENGLES1 +#cmakedefine ALLEGRO_CFG_OPENGLES2 +#cmakedefine ALLEGRO_CFG_OPENGLES3 +#cmakedefine ALLEGRO_CFG_OPENGL_FIXED_FUNCTION +#cmakedefine ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE +#cmakedefine ALLEGRO_CFG_SHADER_GLSL +#cmakedefine ALLEGRO_CFG_SHADER_HLSL + +#cmakedefine ALLEGRO_CFG_ANDROID_LEGACY + +/*---------------------------------------------------------------------------*/ + +/* Define to 1 if you have the corresponding header file. */ +#cmakedefine ALLEGRO_HAVE_DIRENT_H +#cmakedefine ALLEGRO_HAVE_INTTYPES_H +#cmakedefine ALLEGRO_HAVE_LINUX_AWE_VOICE_H +#cmakedefine ALLEGRO_HAVE_LINUX_INPUT_H +#cmakedefine ALLEGRO_HAVE_LINUX_SOUNDCARD_H +#cmakedefine ALLEGRO_HAVE_MACHINE_SOUNDCARD_H +#cmakedefine ALLEGRO_HAVE_SOUNDCARD_H +#cmakedefine ALLEGRO_HAVE_STDBOOL_H +#cmakedefine ALLEGRO_HAVE_STDINT_H +#cmakedefine ALLEGRO_HAVE_SV_PROCFS_H +#cmakedefine ALLEGRO_HAVE_SYS_IO_H +#cmakedefine ALLEGRO_HAVE_SYS_SOUNDCARD_H +#cmakedefine ALLEGRO_HAVE_SYS_STAT_H +#cmakedefine ALLEGRO_HAVE_SYS_TIME_H +#cmakedefine ALLEGRO_HAVE_TIME_H +#cmakedefine ALLEGRO_HAVE_SYS_UTSNAME_H +#cmakedefine ALLEGRO_HAVE_SYS_TYPES_H +#cmakedefine ALLEGRO_HAVE_OSATOMIC_H +#cmakedefine ALLEGRO_HAVE_SYS_INOTIFY_H +#cmakedefine ALLEGRO_HAVE_SAL_H + +/* Define to 1 if the corresponding functions are available. */ +#cmakedefine ALLEGRO_HAVE_GETEXECNAME +#cmakedefine ALLEGRO_HAVE_MKSTEMP +#cmakedefine ALLEGRO_HAVE_MMAP +#cmakedefine ALLEGRO_HAVE_MPROTECT +#cmakedefine ALLEGRO_HAVE_SCHED_YIELD +#cmakedefine ALLEGRO_HAVE_SYSCONF +#cmakedefine ALLEGRO_HAVE_SYSCTL + +#cmakedefine ALLEGRO_HAVE_FSEEKO +#cmakedefine ALLEGRO_HAVE_FTELLO +#cmakedefine ALLEGRO_HAVE_STRERROR_R +#cmakedefine ALLEGRO_HAVE_STRERROR_S +#cmakedefine ALLEGRO_HAVE_VA_COPY +#cmakedefine ALLEGRO_HAVE_FTELLI64 +#cmakedefine ALLEGRO_HAVE_FSEEKI64 + +/* Define to 1 if procfs reveals argc and argv */ +#cmakedefine ALLEGRO_HAVE_PROCFS_ARGCV + +/*---------------------------------------------------------------------------*/ + +/* Define if target machine is little endian. */ +#cmakedefine ALLEGRO_LITTLE_ENDIAN + +/* Define if target machine is big endian. */ +#cmakedefine ALLEGRO_BIG_ENDIAN + +/* Define if target platform is Darwin. */ +#cmakedefine ALLEGRO_DARWIN + +/*---------------------------------------------------------------------------*/ + +/* Define if you need support for X-Windows. */ +#cmakedefine ALLEGRO_WITH_XWINDOWS + +/* Define if XCursor ARGB extension is available. */ +#cmakedefine ALLEGRO_XWINDOWS_WITH_XCURSOR + +/* Define if XF86VidMode extension is supported. */ +#cmakedefine ALLEGRO_XWINDOWS_WITH_XF86VIDMODE + +/* Define if Xinerama extension is supported. */ +#cmakedefine ALLEGRO_XWINDOWS_WITH_XINERAMA + +/* Define if XRandR extension is supported. */ +#cmakedefine ALLEGRO_XWINDOWS_WITH_XRANDR + +/* Define if XScreenSaver extension is supported. */ +#cmakedefine ALLEGRO_XWINDOWS_WITH_XSCREENSAVER + +/* Define if XIM extension is supported. */ +#cmakedefine ALLEGRO_XWINDOWS_WITH_XIM + +/* Define if XInput 2.2 X11 extension is supported. */ +#cmakedefine ALLEGRO_XWINDOWS_WITH_XINPUT2 + +/* Define if Xpm is found. Useful on Ubuntu Unity to set icon. */ +#cmakedefine ALLEGRO_XWINDOWS_WITH_XPM + +/*---------------------------------------------------------------------------*/ + +/* Define if target platform is linux. */ +#cmakedefine ALLEGRO_LINUX + +/* Define if we are building with SDL backend. */ +#cmakedefine ALLEGRO_SDL + +/* Define if sleep should be used instead of threads (only useful for emscripten without web workers) */ +#cmakedefine ALLEGRO_WAIT_EVENT_SLEEP + +/*---------------------------------------------------------------------------*/ +/* vi: set ft=c ts=3 sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/platform/alraspberrypi.h b/allegro/include/allegro5/platform/alraspberrypi.h new file mode 100644 index 00000000..629a02ff --- /dev/null +++ b/allegro/include/allegro5/platform/alraspberrypi.h @@ -0,0 +1,25 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Raspberry Pi-specific header defines. + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_RASPBERRYPI + #error bad include +#endif + +#ifdef ALLEGRO_LIB_BUILD +#include "allegro5/platform/aintuthr.h" +#endif + +/* Nothing left */ diff --git a/allegro/include/allegro5/platform/alraspberrypicfg.h b/allegro/include/allegro5/platform/alraspberrypicfg.h new file mode 100644 index 00000000..17941ca7 --- /dev/null +++ b/allegro/include/allegro5/platform/alraspberrypicfg.h @@ -0,0 +1,29 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on Raspberry Pi platforms. + * + * By Trent Gamblin. + * + * See readme.txt for copyright information. + */ + +#include +#include +#include + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "RaspberryPi" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alraspberrypi.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintraspberrypi.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +#define ALLEGRO_EXCLUDE_GLX diff --git a/allegro/include/allegro5/platform/alucfg.h b/allegro/include/allegro5/platform/alucfg.h new file mode 100644 index 00000000..b9947c88 --- /dev/null +++ b/allegro/include/allegro5/platform/alucfg.h @@ -0,0 +1,40 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on Unix platforms. + * + * By Michael Bukin. + * + * See readme.txt for copyright information. + */ + + +#include +#include + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "Unix" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alunix.h" + +#ifdef _this_is_a_hack_to_fool_scons +#include "alunix.h" +#endif + +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintunix.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +/* Include configuration information. */ +#include "allegro5/platform/alplatf.h" + +/* Enable OpenGL if GLX is available. */ +#ifdef ALLEGRO_GLX +#define ALLEGRO_CFG_OPENGL +#endif diff --git a/allegro/include/allegro5/platform/alunix.h b/allegro/include/allegro5/platform/alunix.h new file mode 100644 index 00000000..ae1b858a --- /dev/null +++ b/allegro/include/allegro5/platform/alunix.h @@ -0,0 +1,23 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Unix-specific header defines. + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_UNIX + #error bad include +#endif + + +/* Nothing left */ + diff --git a/allegro/include/allegro5/platform/alwatcom.h b/allegro/include/allegro5/platform/alwatcom.h new file mode 100644 index 00000000..f2d07714 --- /dev/null +++ b/allegro/include/allegro5/platform/alwatcom.h @@ -0,0 +1,181 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use with Watcom. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef __SW_3S + #error Allegro only supports stack based calling convention +#endif + +#ifndef __SW_S + #error Stack overflow checking must be disabled +#endif + +#include +#include +#include +#include +#include +#include + + +#pragma disable_message (120 201 202) + + +/* these are available in OpenWatcom 1.3 (12.3) */ +#if __WATCOMC__ >= 1230 + #define ALLEGRO_HAVE_INTTYPES_H 1 + #define ALLEGRO_HAVE_STDINT_H 1 +#else + #define ALLEGRO_GUESS_INTTYPES_OK +#endif + + +/* describe this platform */ +#define ALLEGRO_PLATFORM_STR "Watcom" +#define ALLEGRO_DOS +#define ALLEGRO_I386 +#define ALLEGRO_LITTLE_ENDIAN + +#ifdef ALLEGRO_GUESS_INTTYPES_OK + #define int64_t signed long long + #define uint64_t unsigned long long +#endif + + +/* emulate some important djgpp routines */ +#define inportb(port) inp(port) +#define inportw(port) inpw(port) +#define outportb(port, val) outp(port, val) +#define outportw(port, val) outpw(port, val) + +#define ffblk find_t +#define ff_name name +#define ff_attrib attrib +#define ff_fsize size +#define ff_ftime wr_time +#define ff_fdate wr_date + +#define findfirst(name, dta, attrib) _dos_findfirst(name, attrib, dta) +#define findnext(dta) _dos_findnext(dta) + +#define random() rand() +#define srandom(n) srand(n) + +#define _dos_ds _default_ds() + +#define dosmemget(offset, length, buffer) memcpy(buffer, (void *)(offset), length) +#define dosmemput(buffer, length, offset) memcpy((void *)(offset), buffer, length) + +#define __djgpp_nearptr_enable() 1 +#define __djgpp_nearptr_disable() + +#define __djgpp_base_address 0 +#define __djgpp_conventional_base 0 + +#define _crt0_startup_flags 1 +#define _CRT0_FLAG_NEARPTR 1 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union __dpmi_regs +{ + struct { + unsigned long edi, esi, ebp, res, ebx, edx, ecx, eax; + } d; + struct { + unsigned short di, di_hi, si, si_hi, bp, bp_hi, res, res_hi; + unsigned short bx, bx_hi, dx, dx_hi, cx, cx_hi, ax, ax_hi; + unsigned short flags, es, ds, fs, gs, ip, cs, sp, ss; + } x; + struct { + unsigned char edi[4], esi[4], ebp[4], res[4]; + unsigned char bl, bh, ebx_b2, ebx_b3, dl, dh, edx_b2, edx_b3; + unsigned char cl, ch, ecx_b2, ecx_b3, al, ah, eax_b2, eax_b3; + } h; +} __dpmi_regs; + + +typedef struct __dpmi_meminfo +{ + unsigned long handle; + unsigned long size; + unsigned long address; +} __dpmi_meminfo; + + +typedef struct __dpmi_free_mem_info +{ + unsigned long largest_available_free_block_in_bytes; + unsigned long maximum_unlocked_page_allocation_in_pages; + unsigned long maximum_locked_page_allocation_in_pages; + unsigned long linear_address_space_size_in_pages; + unsigned long total_number_of_unlocked_pages; + unsigned long total_number_of_free_pages; + unsigned long total_number_of_physical_pages; + unsigned long free_linear_address_space_in_pages; + unsigned long size_of_paging_file_partition_in_pages; + unsigned long reserved[3]; +} __dpmi_free_mem_info; + + +extern unsigned long __tb; + + +int __dpmi_int(int vector, __dpmi_regs *regs); +int __dpmi_allocate_dos_memory(int paragraphs, int *ret); +int __dpmi_free_dos_memory(int selector); +int __dpmi_physical_address_mapping(__dpmi_meminfo *info); +int __dpmi_free_physical_address_mapping(__dpmi_meminfo *info); +int __dpmi_lock_linear_region(__dpmi_meminfo *info); +int __dpmi_unlock_linear_region(__dpmi_meminfo *info); +int __dpmi_allocate_ldt_descriptors(int count); +int __dpmi_free_ldt_descriptor(int descriptor); +int __dpmi_get_segment_base_address(int selector, unsigned long *addr); +int __dpmi_set_segment_base_address(int selector, unsigned long address); +int __dpmi_set_segment_limit(int selector, unsigned long limit); +int __dpmi_get_free_memory_information(__dpmi_free_mem_info *info); +int __dpmi_simulate_real_mode_interrupt(int vector, __dpmi_regs *regs); +int __dpmi_simulate_real_mode_procedure_retf(__dpmi_regs *regs); +int _go32_dpmi_lock_data(void *lockaddr, unsigned long locksize); +int _go32_dpmi_lock_code(void *lockaddr, unsigned long locksize); + +long _allocate_real_mode_callback(void (*handler)(__dpmi_regs *r), __dpmi_regs *regs); + + +/* memory locking macros */ +void _unlock_dpmi_data(void *addr, int size); + +#ifdef __cplusplus +} +#endif + + +#define END_OF_FUNCTION(x) void x##_end(void) { } +#define END_OF_STATIC_FUNCTION(x) static void x##_end(void) { } +#define LOCK_DATA(d, s) _go32_dpmi_lock_data(d, s) +#define LOCK_CODE(c, s) _go32_dpmi_lock_code(c, s) +#define UNLOCK_DATA(d,s) _unlock_dpmi_data(d, s) +#define LOCK_VARIABLE(x) LOCK_DATA((void *)&x, sizeof(x)) +#define LOCK_FUNCTION(x) LOCK_CODE((void *)FP_OFF(x), (long)FP_OFF(x##_end) - (long)FP_OFF(x)) + + +/* arrange for other headers to be included later on */ +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/aldos.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintdos.h" diff --git a/allegro/include/allegro5/platform/alwin.h b/allegro/include/allegro5/platform/alwin.h new file mode 100644 index 00000000..eab4b10f --- /dev/null +++ b/allegro/include/allegro5/platform/alwin.h @@ -0,0 +1,148 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows-specific header defines. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_WINDOWS + #error bad include +#endif + +/*******************************************/ +/********** magic main emulation ***********/ +/*******************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +AL_FUNC(int, _WinMain, (void *_main, void *hInst, void *hPrev, char *Cmd, int nShow)); + +#ifdef __cplusplus +} +#endif + + +/* The following is due to torhu from A.cc (see + * http://www.allegro.cc/forums/thread/596872/756993#target) + */ +#ifndef ALLEGRO_NO_MAGIC_MAIN + #if defined _MSC_VER && !defined ALLEGRO_LIB_BUILD + #pragma comment(linker,"/ENTRY:mainCRTStartup") + #endif +#endif + + +/*******************************************/ +/************ joystick drivers *************/ +/*******************************************/ +#define AL_JOY_TYPE_DIRECTX AL_ID('D','X',' ',' ') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_directx); + +#ifdef __cplusplus +} +#endif + +#define _AL_JOYSTICK_DRIVER_DIRECTX \ + { AL_JOY_TYPE_DIRECTX, &_al_joydrv_directx, true }, + +#define AL_JOY_TYPE_XINPUT AL_ID('X','I',' ',' ') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_xinput); + +#ifdef __cplusplus +} +#endif + +#define _AL_JOYSTICK_DRIVER_XINPUT \ + { AL_JOY_TYPE_XINPUT, &_al_joydrv_xinput, true }, + +#define AL_JOY_TYPE_WINDOWS_ALL AL_ID('X','D',' ',' ') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_windows_all); + +#ifdef __cplusplus +} +#endif + +#define _AL_JOYSTICK_DRIVER_WINDOWS_ALL \ + { AL_JOY_TYPE_WINDOWS_ALL, &_al_joydrv_windows_all, true }, + + + +/*******************************************/ +/************ haptic drivers *************/ +/*******************************************/ + +#define AL_HAPTIC_TYPE_DIRECTX AL_ID('D','X','F','F') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_HAPTIC_DRIVER, _al_hapdrv_directx); + +#ifdef __cplusplus +} +#endif + +#define _AL_HAPTIC_DRIVER_DIRECTX \ + { AL_HAPTIC_TYPE_DIRECTX, &_al_hapdrv_directx, true }, + + +#define AL_HAPTIC_TYPE_XINPUT AL_ID('X','I','F','F') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_HAPTIC_DRIVER, _al_hapdrv_xinput); + +#ifdef __cplusplus +} +#endif + +#define _AL_HAPTIC_DRIVER_XINPUT \ + { AL_HAPTIC_TYPE_XINPUT, &_al_hapdrv_xinput, true }, + + +#define AL_HAPTIC_TYPE_WINDOWS_ALL AL_ID('X','D','F','F') + +#ifdef __cplusplus +extern "C" { +#endif + +AL_VAR(struct ALLEGRO_HAPTIC_DRIVER, _al_hapdrv_windows_all); + +#ifdef __cplusplus +} +#endif + +#define _AL_HAPTIC_DRIVER_WINDOWS_ALL \ + { AL_HAPTIC_TYPE_WINDOWS_ALL, &_al_hapdrv_windows_all, true }, + + diff --git a/allegro/include/allegro5/platform/alwiz.h b/allegro/include/allegro5/platform/alwiz.h new file mode 100644 index 00000000..9595b3f5 --- /dev/null +++ b/allegro/include/allegro5/platform/alwiz.h @@ -0,0 +1,32 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Wiz-specific header defines. + * + * By Trent Gamblin + * + * See readme.txt for copyright information. + */ + + +#ifndef ALLEGRO_GP2XWIZ + #error bad include +#endif + +#define AL_JOY_TYPE_GP2XWIZ AL_ID('W','I','Z',' ') + +AL_VAR(struct ALLEGRO_JOYSTICK_DRIVER, _al_joydrv_gp2xwiz); + +#define _AL_JOYSTICK_DRIVER_GP2XWIZ \ + { AL_JOY_TYPE_GP2XWIZ, &_al_joydrv_gp2xwiz, true }, + + +#include "allegro5/platform/alunix.h" + diff --git a/allegro/include/allegro5/platform/alwizcfg.h b/allegro/include/allegro5/platform/alwizcfg.h new file mode 100644 index 00000000..a8afe365 --- /dev/null +++ b/allegro/include/allegro5/platform/alwizcfg.h @@ -0,0 +1,33 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration defines for use on GP2X Wiz + * + * By Trent Gamblin + * + * See readme.txt for copyright information. + */ + + +#include +#include + +/* Describe this platform. */ +#define ALLEGRO_PLATFORM_STR "GP2XWIZ" + +#define ALLEGRO_EXTRA_HEADER "allegro5/platform/alwiz.h" +#define ALLEGRO_INTERNAL_HEADER "allegro5/platform/aintwiz.h" +#define ALLEGRO_INTERNAL_THREAD_HEADER "allegro5/platform/aintuthr.h" + +/* Include configuration information. */ +#include "allegro5/platform/alplatf.h" + +/* No GLX on the Wiz */ +#define ALLEGRO_EXCLUDE_GLX diff --git a/allegro/include/allegro5/platform/astdbool.h b/allegro/include/allegro5/platform/astdbool.h new file mode 100644 index 00000000..591f4769 --- /dev/null +++ b/allegro/include/allegro5/platform/astdbool.h @@ -0,0 +1,35 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * A header file to get C99's stdbool.h. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_astdbool_h +#define __al_included_allegro5_astdbool_h + +#ifndef __cplusplus +# ifdef ALLEGRO_HAVE_STDBOOL_H +# include +# else +# ifndef ALLEGRO_HAVE__BOOL + typedef unsigned char _Bool; +# endif +# define bool _Bool +# define false 0 +# define true 1 +# define __bool_true_false_are_defined 1 +# endif +#endif + +#endif diff --git a/allegro/include/allegro5/platform/astdint.h b/allegro/include/allegro5/platform/astdint.h new file mode 100644 index 00000000..63b00305 --- /dev/null +++ b/allegro/include/allegro5/platform/astdint.h @@ -0,0 +1,87 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * A header file to get definitions of uint*_t and int*_t. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_astdint_h +#define __al_included_allegro5_astdint_h + +/* Please only include this file from include/allegro5/internal/alconfig.h + * and don't add more than inttypes.h/stdint.h emulation here. Thanks. + */ + + + +#if defined ALLEGRO_HAVE_INTTYPES_H + #include +#elif defined ALLEGRO_HAVE_STDINT_H + #include +#elif defined ALLEGRO_I386 && defined ALLEGRO_LITTLE_ENDIAN + #ifndef ALLEGRO_GUESS_INTTYPES_OK + #warning Guessing the definitions of fixed-width integer types. + #endif + #include + + #define int8_t signed char + #define uint8_t unsigned char + #define int16_t signed short + #define uint16_t unsigned short + #define int32_t signed int + #define uint32_t unsigned int + + #define INT8_MIN CHAR_MIN + #define INT8_MAX CHAR_MAX + #define UINT8_MAX UCHAR_MAX + #define INT16_MIN SHRT_MIN + #define INT16_MAX SHRT_MAX + #define UINT16_MAX USHRT_MAX + #define INT32_MIN INT_MIN + #define INT32_MAX INT_MAX + #define UINT32_MAX UINT_MAX + + #ifdef ALLEGRO_WINDOWS + + #ifndef _INTPTR_T_DEFINED + #ifdef _WIN64 + #define intptr_t __int64 + #else + #define intptr_t int + #endif + #define _INTPTR_T_DEFINED + #endif + + #ifndef _UINTPTR_T_DEFINED + #ifdef _WIN64 + #define uintptr_t unsigned __int64 + #else + #define uintptr_t unsigned int + #endif + #define _UINTPTR_T_DEFINED + #endif + + #else + + #define intptr_t int32_t + #define uintptr_t uint32_t + + #endif + +#else + #error I dunno how to get the definitions of fixed-width integer types on your platform. Please report this to your friendly Allegro developer. +#endif + + + +#endif diff --git a/allegro/include/allegro5/render_state.h b/allegro/include/allegro5/render_state.h new file mode 100644 index 00000000..99c07648 --- /dev/null +++ b/allegro/include/allegro5/render_state.h @@ -0,0 +1,55 @@ +#ifndef __al_included_allegro5_render_state_h +#define __al_included_allegro5_render_state_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Enum: ALLEGRO_RENDER_STATE + */ +typedef enum ALLEGRO_RENDER_STATE { + /* ALLEGRO_ALPHA_TEST was the name of a rare bitmap flag only used on the + * Wiz port. Reuse the name but retain the same value. + */ + ALLEGRO_ALPHA_TEST = 0x0010, + ALLEGRO_WRITE_MASK, + ALLEGRO_DEPTH_TEST, + ALLEGRO_DEPTH_FUNCTION, + ALLEGRO_ALPHA_FUNCTION, + ALLEGRO_ALPHA_TEST_VALUE +} ALLEGRO_RENDER_STATE; + +/* Enum: ALLEGRO_RENDER_FUNCTION + */ +typedef enum ALLEGRO_RENDER_FUNCTION { + ALLEGRO_RENDER_NEVER, + ALLEGRO_RENDER_ALWAYS, + ALLEGRO_RENDER_LESS, + ALLEGRO_RENDER_EQUAL, + ALLEGRO_RENDER_LESS_EQUAL, + ALLEGRO_RENDER_GREATER, + ALLEGRO_RENDER_NOT_EQUAL, + ALLEGRO_RENDER_GREATER_EQUAL +} ALLEGRO_RENDER_FUNCTION; + +/* Enum: ALLEGRO_WRITE_MASK_FLAGS + */ +typedef enum ALLEGRO_WRITE_MASK_FLAGS { + ALLEGRO_MASK_RED = 1 << 0, + ALLEGRO_MASK_GREEN = 1 << 1, + ALLEGRO_MASK_BLUE = 1 << 2, + ALLEGRO_MASK_ALPHA = 1 << 3, + ALLEGRO_MASK_DEPTH = 1 << 4, + ALLEGRO_MASK_RGB = (ALLEGRO_MASK_RED | ALLEGRO_MASK_GREEN | ALLEGRO_MASK_BLUE), + ALLEGRO_MASK_RGBA = (ALLEGRO_MASK_RGB | ALLEGRO_MASK_ALPHA) +} ALLEGRO_WRITE_MASK_FLAGS; + +AL_FUNC(void, al_set_render_state, (ALLEGRO_RENDER_STATE state, int value)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/shader.h b/allegro/include/allegro5/shader.h new file mode 100644 index 00000000..30c2d6af --- /dev/null +++ b/allegro/include/allegro5/shader.h @@ -0,0 +1,81 @@ +#ifndef __al_included_allegro5_shader_h +#define __al_included_allegro5_shader_h + +#include "allegro5/base.h" +#include "allegro5/transformations.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type: ALLEGRO_SHADER + */ +typedef struct ALLEGRO_SHADER ALLEGRO_SHADER; + +enum ALLEGRO_SHADER_TYPE { + ALLEGRO_VERTEX_SHADER = 1, + ALLEGRO_PIXEL_SHADER = 2 +}; + +/* Enum: ALLEGRO_SHADER_TYPE + */ +typedef enum ALLEGRO_SHADER_TYPE ALLEGRO_SHADER_TYPE; + +enum ALLEGRO_SHADER_PLATFORM { + ALLEGRO_SHADER_AUTO = 0, + ALLEGRO_SHADER_GLSL = 1, + ALLEGRO_SHADER_HLSL = 2 +}; + +/* Enum: ALLEGRO_SHADER_PLATFORM + */ +typedef enum ALLEGRO_SHADER_PLATFORM ALLEGRO_SHADER_PLATFORM; + +/* Shader variable names */ +#define ALLEGRO_SHADER_VAR_COLOR "al_color" +#define ALLEGRO_SHADER_VAR_POS "al_pos" +#define ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX "al_projview_matrix" +#define ALLEGRO_SHADER_VAR_TEX "al_tex" +#define ALLEGRO_SHADER_VAR_TEXCOORD "al_texcoord" +#define ALLEGRO_SHADER_VAR_TEX_MATRIX "al_tex_matrix" +#define ALLEGRO_SHADER_VAR_USER_ATTR "al_user_attr_" +#define ALLEGRO_SHADER_VAR_USE_TEX "al_use_tex" +#define ALLEGRO_SHADER_VAR_USE_TEX_MATRIX "al_use_tex_matrix" +#define ALLEGRO_SHADER_VAR_ALPHA_TEST "al_alpha_test" +#define ALLEGRO_SHADER_VAR_ALPHA_FUNCTION "al_alpha_func" +#define ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE "al_alpha_test_val" + +AL_FUNC(ALLEGRO_SHADER *, al_create_shader, (ALLEGRO_SHADER_PLATFORM platform)); +AL_FUNC(bool, al_attach_shader_source, (ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *source)); +AL_FUNC(bool, al_attach_shader_source_file, (ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *filename)); +AL_FUNC(bool, al_build_shader, (ALLEGRO_SHADER *shader)); +AL_FUNC(const char *, al_get_shader_log, (ALLEGRO_SHADER *shader)); +AL_FUNC(ALLEGRO_SHADER_PLATFORM, al_get_shader_platform, (ALLEGRO_SHADER *shader)); +AL_FUNC(bool, al_use_shader, (ALLEGRO_SHADER *shader)); +AL_FUNC(void, al_destroy_shader, (ALLEGRO_SHADER *shader)); + +AL_FUNC(bool, al_set_shader_sampler, (const char *name, ALLEGRO_BITMAP *bitmap, + int unit)); +AL_FUNC(bool, al_set_shader_matrix, (const char *name, + const ALLEGRO_TRANSFORM *matrix)); +AL_FUNC(bool, al_set_shader_int, (const char *name, int i)); +AL_FUNC(bool, al_set_shader_float, (const char *name, float f)); +AL_FUNC(bool, al_set_shader_int_vector, (const char *name, int num_components, + const int *i, int num_elems)); +AL_FUNC(bool, al_set_shader_float_vector, (const char *name, int num_components, + const float *f, int num_elems)); +AL_FUNC(bool, al_set_shader_bool, (const char *name, bool b)); + +AL_FUNC(char const *, al_get_default_shader_source, (ALLEGRO_SHADER_PLATFORM platform, + ALLEGRO_SHADER_TYPE type)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/system.h b/allegro/include/allegro5/system.h new file mode 100644 index 00000000..5e25cf68 --- /dev/null +++ b/allegro/include/allegro5/system.h @@ -0,0 +1,66 @@ +#ifndef __al_included_allegro5_system_h +#define __al_included_allegro5_system_h + +#include "allegro5/config.h" +#include "allegro5/path.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct ALLEGRO_SYSTEM ALLEGRO_SYSTEM; + +/* Enum: ALLEGRO_SYSTEM_ID + */ +enum ALLEGRO_SYSTEM_ID { + ALLEGRO_SYSTEM_ID_UNKNOWN = 0, + ALLEGRO_SYSTEM_ID_XGLX = AL_ID('X', 'G', 'L', 'X'), + ALLEGRO_SYSTEM_ID_WINDOWS = AL_ID('W', 'I', 'N', 'D'), + ALLEGRO_SYSTEM_ID_MACOSX = AL_ID('O', 'S', 'X', ' '), + ALLEGRO_SYSTEM_ID_ANDROID = AL_ID('A', 'N', 'D', 'R'), + ALLEGRO_SYSTEM_ID_IPHONE = AL_ID('I', 'P', 'H', 'O'), + ALLEGRO_SYSTEM_ID_GP2XWIZ = AL_ID('W', 'I', 'Z', ' '), + ALLEGRO_SYSTEM_ID_RASPBERRYPI = AL_ID('R', 'A', 'S', 'P'), + ALLEGRO_SYSTEM_ID_SDL = AL_ID('S', 'D', 'L', '2') +}; +typedef enum ALLEGRO_SYSTEM_ID ALLEGRO_SYSTEM_ID; + +/* Function: al_init + */ +#define al_init() (al_install_system(ALLEGRO_VERSION_INT, atexit)) + +AL_FUNC(bool, al_install_system, (int version, int (*atexit_ptr)(void (*)(void)))); +AL_FUNC(void, al_uninstall_system, (void)); +AL_FUNC(bool, al_is_system_installed, (void)); +AL_FUNC(ALLEGRO_SYSTEM *, al_get_system_driver, (void)); +AL_FUNC(ALLEGRO_CONFIG *, al_get_system_config, (void)); +AL_FUNC(ALLEGRO_SYSTEM_ID, al_get_system_id, (void)); + +enum { + ALLEGRO_RESOURCES_PATH = 0, + ALLEGRO_TEMP_PATH, + ALLEGRO_USER_DATA_PATH, + ALLEGRO_USER_HOME_PATH, + ALLEGRO_USER_SETTINGS_PATH, + ALLEGRO_USER_DOCUMENTS_PATH, + ALLEGRO_EXENAME_PATH, + ALLEGRO_LAST_PATH /* must be last */ +}; + +AL_FUNC(ALLEGRO_PATH *, al_get_standard_path, (int id)); +AL_FUNC(void, al_set_exe_name, (char const *path)); + +AL_FUNC(void, al_set_org_name, (const char *org_name)); +AL_FUNC(void, al_set_app_name, (const char *app_name)); +AL_FUNC(const char *, al_get_org_name, (void)); +AL_FUNC(const char *, al_get_app_name, (void)); + +AL_FUNC(bool, al_inhibit_screensaver, (bool inhibit)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/threads.h b/allegro/include/allegro5/threads.h new file mode 100644 index 00000000..5a94a163 --- /dev/null +++ b/allegro/include/allegro5/threads.h @@ -0,0 +1,71 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_threads_h +#define __al_included_allegro5_threads_h + +#include "allegro5/altime.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_THREAD + */ +typedef struct ALLEGRO_THREAD ALLEGRO_THREAD; + +/* Type: ALLEGRO_MUTEX + */ +typedef struct ALLEGRO_MUTEX ALLEGRO_MUTEX; + +/* Type: ALLEGRO_COND + */ +typedef struct ALLEGRO_COND ALLEGRO_COND; + + +AL_FUNC(ALLEGRO_THREAD *, al_create_thread, + (void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg)); +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(ALLEGRO_THREAD *, al_create_thread_with_stacksize, + (void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg, size_t stacksize)); +#endif +AL_FUNC(void, al_start_thread, (ALLEGRO_THREAD *outer)); +AL_FUNC(void, al_join_thread, (ALLEGRO_THREAD *outer, void **ret_value)); +AL_FUNC(void, al_set_thread_should_stop, (ALLEGRO_THREAD *outer)); +AL_FUNC(bool, al_get_thread_should_stop, (ALLEGRO_THREAD *outer)); +AL_FUNC(void, al_destroy_thread, (ALLEGRO_THREAD *thread)); +AL_FUNC(void, al_run_detached_thread, (void *(*proc)(void *arg), void *arg)); + +AL_FUNC(ALLEGRO_MUTEX *, al_create_mutex, (void)); +AL_FUNC(ALLEGRO_MUTEX *, al_create_mutex_recursive, (void)); +AL_FUNC(void, al_lock_mutex, (ALLEGRO_MUTEX *mutex)); +AL_FUNC(void, al_unlock_mutex, (ALLEGRO_MUTEX *mutex)); +AL_FUNC(void, al_destroy_mutex, (ALLEGRO_MUTEX *mutex)); + +AL_FUNC(ALLEGRO_COND *, al_create_cond, (void)); +AL_FUNC(void, al_destroy_cond, (ALLEGRO_COND *cond)); +AL_FUNC(void, al_wait_cond, (ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)); +AL_FUNC(int, al_wait_cond_until, (ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex, + const ALLEGRO_TIMEOUT *timeout)); +AL_FUNC(void, al_broadcast_cond, (ALLEGRO_COND *cond)); +AL_FUNC(void, al_signal_cond, (ALLEGRO_COND *cond)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/include/allegro5/timer.h b/allegro/include/allegro5/timer.h new file mode 100644 index 00000000..1d6bffdd --- /dev/null +++ b/allegro/include/allegro5/timer.h @@ -0,0 +1,67 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Timer routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_timer_h +#define __al_included_allegro5_timer_h + +#include "allegro5/base.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Function: ALLEGRO_USECS_TO_SECS + */ +#define ALLEGRO_USECS_TO_SECS(x) ((x) / 1000000.0) + +/* Function: ALLEGRO_MSECS_TO_SECS + */ +#define ALLEGRO_MSECS_TO_SECS(x) ((x) / 1000.0) + +/* Function: ALLEGRO_BPS_TO_SECS + */ +#define ALLEGRO_BPS_TO_SECS(x) (1.0 / (x)) + +/* Function: ALLEGRO_BPM_TO_SECS + */ +#define ALLEGRO_BPM_TO_SECS(x) (60.0 / (x)) + + +/* Type: ALLEGRO_TIMER + */ +typedef struct ALLEGRO_TIMER ALLEGRO_TIMER; + + +AL_FUNC(ALLEGRO_TIMER*, al_create_timer, (double speed_secs)); +AL_FUNC(void, al_destroy_timer, (ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_start_timer, (ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_stop_timer, (ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_resume_timer, (ALLEGRO_TIMER *timer)); +AL_FUNC(bool, al_get_timer_started, (const ALLEGRO_TIMER *timer)); +AL_FUNC(double, al_get_timer_speed, (const ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_set_timer_speed, (ALLEGRO_TIMER *timer, double speed_secs)); +AL_FUNC(int64_t, al_get_timer_count, (const ALLEGRO_TIMER *timer)); +AL_FUNC(void, al_set_timer_count, (ALLEGRO_TIMER *timer, int64_t count)); +AL_FUNC(void, al_add_timer_count, (ALLEGRO_TIMER *timer, int64_t diff)); +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_timer_event_source, (ALLEGRO_TIMER *timer)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/tls.h b/allegro/include/allegro5/tls.h new file mode 100644 index 00000000..949b18a7 --- /dev/null +++ b/allegro/include/allegro5/tls.h @@ -0,0 +1,66 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread local storage routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_tls_h +#define __al_included_allegro5_tls_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Enum: ALLEGRO_STATE_FLAGS + */ +typedef enum ALLEGRO_STATE_FLAGS +{ + ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS = 0x0001, + ALLEGRO_STATE_NEW_BITMAP_PARAMETERS = 0x0002, + ALLEGRO_STATE_DISPLAY = 0x0004, + ALLEGRO_STATE_TARGET_BITMAP = 0x0008, + ALLEGRO_STATE_BLENDER = 0x0010, + ALLEGRO_STATE_NEW_FILE_INTERFACE = 0x0020, + ALLEGRO_STATE_TRANSFORM = 0x0040, + ALLEGRO_STATE_PROJECTION_TRANSFORM = 0x0100, + + ALLEGRO_STATE_BITMAP = ALLEGRO_STATE_TARGET_BITMAP +\ + ALLEGRO_STATE_NEW_BITMAP_PARAMETERS, + + ALLEGRO_STATE_ALL = 0xffff + +} ALLEGRO_STATE_FLAGS; + + +/* Type: ALLEGRO_STATE + */ +typedef struct ALLEGRO_STATE ALLEGRO_STATE; + +struct ALLEGRO_STATE +{ + /* Internally, a thread_local_state structure is placed here. */ + char _tls[1024]; +}; + + +AL_FUNC(void, al_store_state, (ALLEGRO_STATE *state, int flags)); +AL_FUNC(void, al_restore_state, (ALLEGRO_STATE const *state)); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/touch_input.h b/allegro/include/allegro5/touch_input.h new file mode 100644 index 00000000..cd2f3bce --- /dev/null +++ b/allegro/include/allegro5/touch_input.h @@ -0,0 +1,98 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Touch input routines. + * + * See readme.txt for copyright information. + */ + +#ifndef __al_included_allegro5_touch_input_h +#define __al_included_allegro5_touch_input_h + +#include "allegro5/base.h" +#include "allegro5/events.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Enum: ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT + */ +#define ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT 16 + + +/* Type: ALLEGRO_TOUCH_INPUT + */ +typedef struct ALLEGRO_TOUCH_INPUT ALLEGRO_TOUCH_INPUT; + + +/* Type: ALLEGRO_TOUCH_INPUT_STATE + */ +typedef struct ALLEGRO_TOUCH_INPUT_STATE ALLEGRO_TOUCH_INPUT_STATE; + + +/* Type: ALLEGRO_TOUCH_STATE + */ +typedef struct ALLEGRO_TOUCH_STATE ALLEGRO_TOUCH_STATE; + + +struct ALLEGRO_TOUCH_STATE +{ + /* (id) An identifier of touch. If touch is valid this number is positive. + * (x, y) Touch position on the screen in 1:1 resolution. + * (dx, dy) Relative touch position. + * (primary) True, if touch is a primary one (usually first one). + * (display) Display at which the touch belong. + */ + int id; + float x, y; + float dx, dy; + bool primary; + struct ALLEGRO_DISPLAY *display; +}; + +struct ALLEGRO_TOUCH_INPUT_STATE +{ + ALLEGRO_TOUCH_STATE touches[ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT]; +}; + + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +/* Enum: ALLEGRO_MOUSE_EMULATION_MODE + */ +typedef enum ALLEGRO_MOUSE_EMULATION_MODE +{ + ALLEGRO_MOUSE_EMULATION_NONE, + ALLEGRO_MOUSE_EMULATION_TRANSPARENT, + ALLEGRO_MOUSE_EMULATION_INCLUSIVE, + ALLEGRO_MOUSE_EMULATION_EXCLUSIVE, + ALLEGRO_MOUSE_EMULATION_5_0_x +} ALLEGRO_MOUSE_EMULATION_MODE; +#endif + + +AL_FUNC(bool, al_is_touch_input_installed, (void)); +AL_FUNC(bool, al_install_touch_input, (void)); +AL_FUNC(void, al_uninstall_touch_input, (void)); +AL_FUNC(void, al_get_touch_input_state, (ALLEGRO_TOUCH_INPUT_STATE *ret_state)); +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_touch_input_event_source, (void)); + +#if defined(ALLEGRO_UNSTABLE) || defined(ALLEGRO_INTERNAL_UNSTABLE) || defined(ALLEGRO_SRC) +AL_FUNC(void, al_set_mouse_emulation_mode, (int mode)); +AL_FUNC(int, al_get_mouse_emulation_mode, (void)); +AL_FUNC(ALLEGRO_EVENT_SOURCE *, al_get_touch_input_mouse_emulation_event_source, (void)); +#endif + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/transformations.h b/allegro/include/allegro5/transformations.h new file mode 100644 index 00000000..fe146f10 --- /dev/null +++ b/allegro/include/allegro5/transformations.h @@ -0,0 +1,57 @@ +#ifndef __al_included_allegro5_transformations_h +#define __al_included_allegro5_transformations_h + +#include "allegro5/display.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_TRANSFORM + */ +typedef struct ALLEGRO_TRANSFORM ALLEGRO_TRANSFORM; + +struct ALLEGRO_TRANSFORM { + float m[4][4]; +}; + +/* Transformations*/ +AL_FUNC(void, al_use_transform, (const ALLEGRO_TRANSFORM* trans)); +AL_FUNC(void, al_use_projection_transform, (const ALLEGRO_TRANSFORM* trans)); +AL_FUNC(void, al_copy_transform, (ALLEGRO_TRANSFORM* dest, const ALLEGRO_TRANSFORM* src)); +AL_FUNC(void, al_identity_transform, (ALLEGRO_TRANSFORM* trans)); +AL_FUNC(void, al_build_transform, (ALLEGRO_TRANSFORM* trans, float x, float y, float sx, float sy, float theta)); +AL_FUNC(void, al_build_camera_transform, (ALLEGRO_TRANSFORM *trans, + float position_x, float position_y, float position_z, + float look_x, float look_y, float look_z, + float up_x, float up_y, float up_z)); +AL_FUNC(void, al_translate_transform, (ALLEGRO_TRANSFORM* trans, float x, float y)); +AL_FUNC(void, al_translate_transform_3d, (ALLEGRO_TRANSFORM *trans, float x, float y, float z)); +AL_FUNC(void, al_rotate_transform, (ALLEGRO_TRANSFORM* trans, float theta)); +AL_FUNC(void, al_rotate_transform_3d, (ALLEGRO_TRANSFORM *trans, float x, float y, float z, float angle)); +AL_FUNC(void, al_scale_transform, (ALLEGRO_TRANSFORM* trans, float sx, float sy)); +AL_FUNC(void, al_scale_transform_3d, (ALLEGRO_TRANSFORM *trans, float sx, float sy, float sz)); +AL_FUNC(void, al_transform_coordinates, (const ALLEGRO_TRANSFORM* trans, float* x, float* y)); +AL_FUNC(void, al_transform_coordinates_3d, (const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z)); +AL_FUNC(void, al_transform_coordinates_4d, (const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z, float *w)); +AL_FUNC(void, al_transform_coordinates_3d_projective, (const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z)); +AL_FUNC(void, al_compose_transform, (ALLEGRO_TRANSFORM* trans, const ALLEGRO_TRANSFORM* other)); +AL_FUNC(const ALLEGRO_TRANSFORM*, al_get_current_transform, (void)); +AL_FUNC(const ALLEGRO_TRANSFORM*, al_get_current_inverse_transform, (void)); +AL_FUNC(const ALLEGRO_TRANSFORM *, al_get_current_projection_transform, (void)); +AL_FUNC(void, al_invert_transform, (ALLEGRO_TRANSFORM *trans)); +AL_FUNC(void, al_transpose_transform, (ALLEGRO_TRANSFORM *trans)); +AL_FUNC(int, al_check_inverse, (const ALLEGRO_TRANSFORM *trans, float tol)); +AL_FUNC(void, al_orthographic_transform, (ALLEGRO_TRANSFORM *trans, float left, float top, float n, float right, float bottom, float f)); +AL_FUNC(void, al_perspective_transform, (ALLEGRO_TRANSFORM *trans, float left, float top, float n, float right, float bottom, float f)); +AL_FUNC(void, al_horizontal_shear_transform, (ALLEGRO_TRANSFORM *trans, float theta)); +AL_FUNC(void, al_vertical_shear_transform, (ALLEGRO_TRANSFORM *trans, float theta)); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/allegro/include/allegro5/utf8.h b/allegro/include/allegro5/utf8.h new file mode 100644 index 00000000..f0459dac --- /dev/null +++ b/allegro/include/allegro5/utf8.h @@ -0,0 +1,150 @@ +#ifndef __al_included_allegro5_utf8_h +#define __al_included_allegro5_utf8_h + +#include "allegro5/base.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type: ALLEGRO_USTR + */ +typedef struct _al_tagbstring ALLEGRO_USTR; + +/* Type: ALLEGRO_USTR_INFO + */ +typedef struct _al_tagbstring ALLEGRO_USTR_INFO; + +#ifndef __al_tagbstring_defined +#define __al_tagbstring_defined +struct _al_tagbstring { + int mlen; + int slen; + unsigned char * data; +}; +#endif + +/* Creating strings */ +AL_FUNC(ALLEGRO_USTR *, al_ustr_new, (const char *s)); +AL_FUNC(ALLEGRO_USTR *, al_ustr_new_from_buffer, (const char *s, size_t size)); +AL_PRINTFUNC(ALLEGRO_USTR *, al_ustr_newf, (const char *fmt, ...), 1, 2); +AL_FUNC(void, al_ustr_free, (ALLEGRO_USTR *us)); +AL_FUNC(const char *, al_cstr, (const ALLEGRO_USTR *us)); +AL_FUNC(void, al_ustr_to_buffer, (const ALLEGRO_USTR *us, char *buffer, int size)); +AL_FUNC(char *, al_cstr_dup, (const ALLEGRO_USTR *us)); +AL_FUNC(ALLEGRO_USTR *, al_ustr_dup, (const ALLEGRO_USTR *us)); +AL_FUNC(ALLEGRO_USTR *, al_ustr_dup_substr, (const ALLEGRO_USTR *us, + int start_pos, int end_pos)); + +/* Predefined string */ +AL_FUNC(const ALLEGRO_USTR *, al_ustr_empty_string, (void)); + +/* Reference strings */ +AL_FUNC(const ALLEGRO_USTR *, al_ref_cstr, (ALLEGRO_USTR_INFO *info, const char *s)); +AL_FUNC(const ALLEGRO_USTR *, al_ref_buffer, (ALLEGRO_USTR_INFO *info, const char *s, + size_t size)); +AL_FUNC(const ALLEGRO_USTR *, al_ref_ustr, (ALLEGRO_USTR_INFO *info, + const ALLEGRO_USTR *us, int start_pos, int end_pos)); + +/* Sizes and offsets */ +AL_FUNC(size_t, al_ustr_size, (const ALLEGRO_USTR *us)); +AL_FUNC(size_t, al_ustr_length, (const ALLEGRO_USTR *us)); +AL_FUNC(int, al_ustr_offset, (const ALLEGRO_USTR *us, int index)); +AL_FUNC(bool, al_ustr_next, (const ALLEGRO_USTR *us, int *pos)); +AL_FUNC(bool, al_ustr_prev, (const ALLEGRO_USTR *us, int *pos)); + +/* Get codepoints */ +AL_FUNC(int32_t, al_ustr_get, (const ALLEGRO_USTR *us, int pos)); +AL_FUNC(int32_t, al_ustr_get_next, (const ALLEGRO_USTR *us, int *pos)); +AL_FUNC(int32_t, al_ustr_prev_get, (const ALLEGRO_USTR *us, int *pos)); + +/* Insert */ +AL_FUNC(bool, al_ustr_insert, (ALLEGRO_USTR *us1, int pos, + const ALLEGRO_USTR *us2)); +AL_FUNC(bool, al_ustr_insert_cstr, (ALLEGRO_USTR *us, int pos, + const char *us2)); +AL_FUNC(size_t, al_ustr_insert_chr, (ALLEGRO_USTR *us, int pos, int32_t c)); + +/* Append */ +AL_FUNC(bool, al_ustr_append, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); +AL_FUNC(bool, al_ustr_append_cstr, (ALLEGRO_USTR *us, const char *s)); +AL_FUNC(size_t, al_ustr_append_chr, (ALLEGRO_USTR *us, int32_t c)); +AL_PRINTFUNC(bool, al_ustr_appendf, (ALLEGRO_USTR *us, const char *fmt, ...), + 2, 3); +AL_FUNC(bool, al_ustr_vappendf, (ALLEGRO_USTR *us, const char *fmt, + va_list ap)); + +/* Remove */ +AL_FUNC(bool, al_ustr_remove_chr, (ALLEGRO_USTR *us, int pos)); +AL_FUNC(bool, al_ustr_remove_range, (ALLEGRO_USTR *us, int start_pos, + int end_pos)); +AL_FUNC(bool, al_ustr_truncate, (ALLEGRO_USTR *us, int start_pos)); +AL_FUNC(bool, al_ustr_ltrim_ws, (ALLEGRO_USTR *us)); +AL_FUNC(bool, al_ustr_rtrim_ws, (ALLEGRO_USTR *us)); +AL_FUNC(bool, al_ustr_trim_ws, (ALLEGRO_USTR *us)); + +/* Assign */ +AL_FUNC(bool, al_ustr_assign, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); +AL_FUNC(bool, al_ustr_assign_substr, (ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, + int start_pos, int end_pos)); +AL_FUNC(bool, al_ustr_assign_cstr, (ALLEGRO_USTR *us1, const char *s)); + +/* Replace */ +AL_FUNC(size_t, al_ustr_set_chr, (ALLEGRO_USTR *us, int pos, int32_t c)); +AL_FUNC(bool, al_ustr_replace_range, (ALLEGRO_USTR *us1, int start_pos1, + int end_pos1, const ALLEGRO_USTR *us2)); + +/* Searching */ +AL_FUNC(int, al_ustr_find_chr, (const ALLEGRO_USTR *us, int start_pos, + int32_t c)); +AL_FUNC(int, al_ustr_rfind_chr, (const ALLEGRO_USTR *us, int start_pos, + int32_t c)); +AL_FUNC(int, al_ustr_find_set, (const ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *accept)); +AL_FUNC(int, al_ustr_find_set_cstr, (const ALLEGRO_USTR *us, int start_pos, + const char *accept)); +AL_FUNC(int, al_ustr_find_cset, (const ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *reject)); +AL_FUNC(int, al_ustr_find_cset_cstr, (const ALLEGRO_USTR *us, int start_pos, + const char *reject)); +AL_FUNC(int, al_ustr_find_str, (const ALLEGRO_USTR *haystack, int start_pos, + const ALLEGRO_USTR *needle)); +AL_FUNC(int, al_ustr_find_cstr, (const ALLEGRO_USTR *haystack, int start_pos, + const char *needle)); +AL_FUNC(int, al_ustr_rfind_str, (const ALLEGRO_USTR *haystack, int start_pos, + const ALLEGRO_USTR *needle)); +AL_FUNC(int, al_ustr_rfind_cstr, (const ALLEGRO_USTR *haystack, int start_pos, + const char *needle)); +AL_FUNC(bool, al_ustr_find_replace, (ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace)); +AL_FUNC(bool, al_ustr_find_replace_cstr, (ALLEGRO_USTR *us, int start_pos, + const char *find, const char *replace)); + +/* Compare */ +AL_FUNC(bool, al_ustr_equal, (const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)); +AL_FUNC(int, al_ustr_compare, (const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); +AL_FUNC(int, al_ustr_ncompare, (const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, + int n)); +AL_FUNC(bool, al_ustr_has_prefix,(const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); +AL_FUNC(bool, al_ustr_has_prefix_cstr, (const ALLEGRO_USTR *u, const char *s)); +AL_FUNC(bool, al_ustr_has_suffix,(const ALLEGRO_USTR *u, const ALLEGRO_USTR *v)); +AL_FUNC(bool, al_ustr_has_suffix_cstr,(const ALLEGRO_USTR *us1, const char *s)); + +/* Low level UTF-8 functions */ +AL_FUNC(size_t, al_utf8_width, (int32_t c)); +AL_FUNC(size_t, al_utf8_encode, (char s[], int32_t c)); + +/* UTF-16 */ +AL_FUNC(ALLEGRO_USTR *, al_ustr_new_from_utf16, (uint16_t const *s)); +AL_FUNC(size_t, al_ustr_size_utf16, (const ALLEGRO_USTR *us)); +AL_FUNC(size_t, al_ustr_encode_utf16, (const ALLEGRO_USTR *us, uint16_t *s, size_t n)); +AL_FUNC(size_t, al_utf16_width, (int c)); +AL_FUNC(size_t, al_utf16_encode, (uint16_t s[], int32_t c)); + +#ifdef __cplusplus + } +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/indent.pro b/allegro/indent.pro new file mode 100644 index 00000000..8e0847c0 --- /dev/null +++ b/allegro/indent.pro @@ -0,0 +1,5 @@ +-kr -nce -ss -ncs -i3 -cli3 -nut -bls -l80 +-T ALLEGRO_BITMAP +-T PACKFILE +-T BMPINFOHEADER +-T PalEntry diff --git a/allegro/misc/Allegro5_iOS/Allegro5_iOS.xcodeproj/project.pbxproj b/allegro/misc/Allegro5_iOS/Allegro5_iOS.xcodeproj/project.pbxproj new file mode 100644 index 00000000..216985cb --- /dev/null +++ b/allegro/misc/Allegro5_iOS/Allegro5_iOS.xcodeproj/project.pbxproj @@ -0,0 +1,719 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 968608761B6B12960008BD29 /* dds.c in Sources */ = {isa = PBXBuildFile; fileRef = 968608751B6B12960008BD29 /* dds.c */; }; + 96A12D031D2F3C3E00F245D9 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 96A12D021D2F3C3E00F245D9 /* png.c */; }; + 96A12D051D2F3F9300F245D9 /* identify.c in Sources */ = {isa = PBXBuildFile; fileRef = 96A12D041D2F3F9300F245D9 /* identify.c */; }; + 96A3016E1B9A874F002E2D1C /* clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = 96A3016D1B9A874F002E2D1C /* clipboard.c */; }; + 96A301701B9A8778002E2D1C /* iphone_clipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 96A3016F1B9A8778002E2D1C /* iphone_clipboard.m */; }; + 96CE34EB1B6B059C00705360 /* allegro.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34BB1B6B059C00705360 /* allegro.c */; }; + 96CE34EC1B6B059C00705360 /* bitmap_draw.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34BC1B6B059C00705360 /* bitmap_draw.c */; }; + 96CE34ED1B6B059C00705360 /* bitmap_io.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34BD1B6B059C00705360 /* bitmap_io.c */; }; + 96CE34EE1B6B059C00705360 /* bitmap_lock.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34BE1B6B059C00705360 /* bitmap_lock.c */; }; + 96CE34EF1B6B059C00705360 /* bitmap_pixel.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34BF1B6B059C00705360 /* bitmap_pixel.c */; }; + 96CE34F01B6B059C00705360 /* bitmap_type.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C01B6B059C00705360 /* bitmap_type.c */; }; + 96CE34F11B6B059C00705360 /* bitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C11B6B059C00705360 /* bitmap.c */; }; + 96CE34F21B6B059C00705360 /* blenders.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C21B6B059C00705360 /* blenders.c */; }; + 96CE34F31B6B059C00705360 /* config.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C31B6B059C00705360 /* config.c */; }; + 96CE34F41B6B059C00705360 /* convert.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C41B6B059C00705360 /* convert.c */; }; + 96CE34F51B6B059C00705360 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C51B6B059C00705360 /* debug.c */; }; + 96CE34F61B6B059C00705360 /* display_settings.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C61B6B059C00705360 /* display_settings.c */; }; + 96CE34F71B6B059C00705360 /* display.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C71B6B059C00705360 /* display.c */; }; + 96CE34F81B6B059C00705360 /* drawing.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C81B6B059C00705360 /* drawing.c */; }; + 96CE34F91B6B059C00705360 /* dtor.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34C91B6B059C00705360 /* dtor.c */; }; + 96CE34FA1B6B059C00705360 /* events.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34CA1B6B059C00705360 /* events.c */; }; + 96CE34FB1B6B059C00705360 /* evtsrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34CB1B6B059C00705360 /* evtsrc.c */; }; + 96CE34FC1B6B059C00705360 /* exitfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34CC1B6B059C00705360 /* exitfunc.c */; }; + 96CE34FD1B6B059C00705360 /* file_slice.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34CD1B6B059C00705360 /* file_slice.c */; }; + 96CE34FE1B6B059C00705360 /* file_stdio.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34CE1B6B059C00705360 /* file_stdio.c */; }; + 96CE34FF1B6B059C00705360 /* file.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34CF1B6B059C00705360 /* file.c */; }; + 96CE35001B6B059C00705360 /* fshook_stdio.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D01B6B059C00705360 /* fshook_stdio.c */; }; + 96CE35011B6B059C00705360 /* fshook.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D11B6B059C00705360 /* fshook.c */; }; + 96CE35021B6B059C00705360 /* fullscreen_mode.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D21B6B059C00705360 /* fullscreen_mode.c */; }; + 96CE35031B6B059C00705360 /* haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D31B6B059C00705360 /* haptic.c */; }; + 96CE35041B6B059C00705360 /* inline.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D41B6B059C00705360 /* inline.c */; }; + 96CE35051B6B059C00705360 /* joynu.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D51B6B059C00705360 /* joynu.c */; }; + 96CE35061B6B059C00705360 /* keybdnu.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D61B6B059C00705360 /* keybdnu.c */; }; + 96CE35071B6B059C00705360 /* libc.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D71B6B059C00705360 /* libc.c */; }; + 96CE35081B6B059C00705360 /* math.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D81B6B059C00705360 /* math.c */; }; + 96CE35091B6B059C00705360 /* memblit.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34D91B6B059C00705360 /* memblit.c */; }; + 96CE350A1B6B059C00705360 /* memdraw.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34DA1B6B059C00705360 /* memdraw.c */; }; + 96CE350B1B6B059C00705360 /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34DB1B6B059C00705360 /* memory.c */; }; + 96CE350C1B6B059C00705360 /* monitor.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34DC1B6B059C00705360 /* monitor.c */; }; + 96CE350D1B6B059C00705360 /* mouse_cursor.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34DD1B6B059C00705360 /* mouse_cursor.c */; }; + 96CE350E1B6B059C00705360 /* mousenu.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34DE1B6B059C00705360 /* mousenu.c */; }; + 96CE350F1B6B059C00705360 /* path.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34DF1B6B059C00705360 /* path.c */; }; + 96CE35101B6B059C00705360 /* pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E01B6B059C00705360 /* pixels.c */; }; + 96CE35111B6B059C00705360 /* shader.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E11B6B059C00705360 /* shader.c */; }; + 96CE35121B6B059C00705360 /* system.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E21B6B059C00705360 /* system.c */; }; + 96CE35131B6B059C00705360 /* threads.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E31B6B059C00705360 /* threads.c */; }; + 96CE35141B6B059C00705360 /* timernu.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E41B6B059C00705360 /* timernu.c */; }; + 96CE35151B6B059C00705360 /* tls_dll.inc in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E51B6B059C00705360 /* tls_dll.inc */; }; + 96CE35161B6B059C00705360 /* tls.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E61B6B059C00705360 /* tls.c */; }; + 96CE35171B6B059C00705360 /* touch_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E71B6B059C00705360 /* touch_input.c */; }; + 96CE35181B6B059C00705360 /* transformations.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E81B6B059C00705360 /* transformations.c */; }; + 96CE35191B6B059C00705360 /* tri_soft.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34E91B6B059C00705360 /* tri_soft.c */; }; + 96CE351A1B6B059C00705360 /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE34EA1B6B059C00705360 /* utf8.c */; }; + 96CE351D1B6B05D100705360 /* utime.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE351B1B6B05D100705360 /* utime.c */; }; + 96CE351E1B6B05D100705360 /* uxthread.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE351C1B6B05D100705360 /* uxthread.c */; }; + 96CE35281B6B05F900705360 /* extensions.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE351F1B6B05F900705360 /* extensions.c */; }; + 96CE35291B6B05F900705360 /* ogl_bitmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35201B6B05F900705360 /* ogl_bitmap.c */; }; + 96CE352A1B6B05F900705360 /* ogl_display.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35211B6B05F900705360 /* ogl_display.c */; }; + 96CE352B1B6B05F900705360 /* ogl_draw.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35221B6B05F900705360 /* ogl_draw.c */; }; + 96CE352C1B6B05F900705360 /* ogl_fbo.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35231B6B05F900705360 /* ogl_fbo.c */; }; + 96CE352D1B6B05F900705360 /* ogl_lock_es.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35241B6B05F900705360 /* ogl_lock_es.c */; }; + 96CE352E1B6B05F900705360 /* ogl_lock.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35251B6B05F900705360 /* ogl_lock.c */; }; + 96CE352F1B6B05F900705360 /* ogl_render_state.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35261B6B05F900705360 /* ogl_render_state.c */; }; + 96CE35301B6B05F900705360 /* ogl_shader.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35271B6B05F900705360 /* ogl_shader.c */; }; + 96CE35361B6B061200705360 /* aatree.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35311B6B061200705360 /* aatree.c */; }; + 96CE35371B6B061200705360 /* bstrlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35321B6B061200705360 /* bstrlib.c */; }; + 96CE35381B6B061200705360 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35341B6B061200705360 /* list.c */; }; + 96CE35391B6B061200705360 /* vector.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35351B6B061200705360 /* vector.c */; }; + 96CE35451B6B063800705360 /* allegroAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE353A1B6B063800705360 /* allegroAppDelegate.m */; }; + 96CE35461B6B063800705360 /* EAGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE353B1B6B063800705360 /* EAGLView.m */; }; + 96CE35471B6B063800705360 /* iphone_display.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE353C1B6B063800705360 /* iphone_display.m */; }; + 96CE35481B6B063800705360 /* iphone_joystick.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE353D1B6B063800705360 /* iphone_joystick.m */; }; + 96CE35491B6B063800705360 /* iphone_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE353E1B6B063800705360 /* iphone_keyboard.c */; }; + 96CE354A1B6B063800705360 /* iphone_main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE353F1B6B063800705360 /* iphone_main.m */; }; + 96CE354B1B6B063800705360 /* iphone_mouse.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35401B6B063800705360 /* iphone_mouse.m */; }; + 96CE354C1B6B063800705360 /* iphone_path.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35411B6B063800705360 /* iphone_path.m */; }; + 96CE354D1B6B063800705360 /* iphone_system.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35421B6B063800705360 /* iphone_system.c */; }; + 96CE354E1B6B063800705360 /* iphone_touch_input.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35431B6B063800705360 /* iphone_touch_input.m */; }; + 96CE354F1B6B063800705360 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35441B6B063800705360 /* ViewController.m */; }; + 96CE35511B6B064F00705360 /* color.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35501B6B064F00705360 /* color.c */; }; + 96CE35561B6B066100705360 /* font.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35521B6B066100705360 /* font.c */; }; + 96CE35571B6B066100705360 /* fontbmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35531B6B066100705360 /* fontbmp.c */; }; + 96CE35581B6B066100705360 /* stdfont.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35541B6B066100705360 /* stdfont.c */; }; + 96CE35591B6B066100705360 /* text.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35551B6B066100705360 /* text.c */; }; + 96CE355F1B6B068800705360 /* bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE355A1B6B068800705360 /* bmp.c */; }; + 96CE35601B6B068800705360 /* iio.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE355B1B6B068800705360 /* iio.c */; }; + 96CE35621B6B068800705360 /* pcx.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE355D1B6B068800705360 /* pcx.c */; }; + 96CE35631B6B068800705360 /* tga.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE355E1B6B068800705360 /* tga.c */; }; + 96CE35651B6B069700705360 /* generic_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35641B6B069700705360 /* generic_main.c */; }; + 96CE35671B6B06A400705360 /* memfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35661B6B06A400705360 /* memfile.c */; }; + 96CE356A1B6B06C400705360 /* a5_physfs_dir.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35681B6B06C400705360 /* a5_physfs_dir.c */; }; + 96CE356B1B6B06C400705360 /* a5_physfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35691B6B06C400705360 /* a5_physfs.c */; }; + 96CE35791B6B06EF00705360 /* directx_shaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 96CE356C1B6B06EF00705360 /* directx_shaders.cpp */; }; + 96CE357A1B6B06EF00705360 /* high_primitives.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE356D1B6B06EF00705360 /* high_primitives.c */; }; + 96CE357B1B6B06EF00705360 /* line_soft.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE356E1B6B06EF00705360 /* line_soft.c */; }; + 96CE357D1B6B06EF00705360 /* point_soft.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35701B6B06EF00705360 /* point_soft.c */; }; + 96CE357E1B6B06EF00705360 /* polygon.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35711B6B06EF00705360 /* polygon.c */; }; + 96CE357F1B6B06EF00705360 /* polyline.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35721B6B06EF00705360 /* polyline.c */; }; + 96CE35801B6B06EF00705360 /* prim_directx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35731B6B06EF00705360 /* prim_directx.cpp */; }; + 96CE35811B6B06EF00705360 /* prim_opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35741B6B06EF00705360 /* prim_opengl.c */; }; + 96CE35821B6B06EF00705360 /* prim_soft.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35751B6B06EF00705360 /* prim_soft.c */; }; + 96CE35831B6B06EF00705360 /* prim_util.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35761B6B06EF00705360 /* prim_util.c */; }; + 96CE35841B6B06EF00705360 /* primitives.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35771B6B06EF00705360 /* primitives.c */; }; + 96CE35851B6B06EF00705360 /* triangulator.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35781B6B06EF00705360 /* triangulator.c */; }; + 96CE35871B6B070300705360 /* ttf.c in Sources */ = {isa = PBXBuildFile; fileRef = 96CE35861B6B070300705360 /* ttf.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 964130ED1A6353E700184496 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 964130EF1A6353E700184496 /* libAllegro5_iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAllegro5_iOS.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 968608751B6B12960008BD29 /* dds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dds.c; path = ../../addons/image/dds.c; sourceTree = ""; }; + 96A12D021D2F3C3E00F245D9 /* png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = png.c; path = ../../addons/image/png.c; sourceTree = ""; }; + 96A12D041D2F3F9300F245D9 /* identify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = identify.c; path = ../../addons/image/identify.c; sourceTree = ""; }; + 96A3016D1B9A874F002E2D1C /* clipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = clipboard.c; path = ../../src/clipboard.c; sourceTree = ""; }; + 96A3016F1B9A8778002E2D1C /* iphone_clipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iphone_clipboard.m; path = ../../src/iphone/iphone_clipboard.m; sourceTree = ""; }; + 96CE34BB1B6B059C00705360 /* allegro.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = allegro.c; path = ../../src/allegro.c; sourceTree = ""; }; + 96CE34BC1B6B059C00705360 /* bitmap_draw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitmap_draw.c; path = ../../src/bitmap_draw.c; sourceTree = ""; }; + 96CE34BD1B6B059C00705360 /* bitmap_io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitmap_io.c; path = ../../src/bitmap_io.c; sourceTree = ""; }; + 96CE34BE1B6B059C00705360 /* bitmap_lock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitmap_lock.c; path = ../../src/bitmap_lock.c; sourceTree = ""; }; + 96CE34BF1B6B059C00705360 /* bitmap_pixel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitmap_pixel.c; path = ../../src/bitmap_pixel.c; sourceTree = ""; }; + 96CE34C01B6B059C00705360 /* bitmap_type.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitmap_type.c; path = ../../src/bitmap_type.c; sourceTree = ""; }; + 96CE34C11B6B059C00705360 /* bitmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitmap.c; path = ../../src/bitmap.c; sourceTree = ""; }; + 96CE34C21B6B059C00705360 /* blenders.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blenders.c; path = ../../src/blenders.c; sourceTree = ""; }; + 96CE34C31B6B059C00705360 /* config.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = config.c; path = ../../src/config.c; sourceTree = ""; }; + 96CE34C41B6B059C00705360 /* convert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = convert.c; path = ../../src/convert.c; sourceTree = ""; }; + 96CE34C51B6B059C00705360 /* debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = debug.c; path = ../../src/debug.c; sourceTree = ""; }; + 96CE34C61B6B059C00705360 /* display_settings.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = display_settings.c; path = ../../src/display_settings.c; sourceTree = ""; }; + 96CE34C71B6B059C00705360 /* display.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = display.c; path = ../../src/display.c; sourceTree = ""; }; + 96CE34C81B6B059C00705360 /* drawing.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = drawing.c; path = ../../src/drawing.c; sourceTree = ""; }; + 96CE34C91B6B059C00705360 /* dtor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dtor.c; path = ../../src/dtor.c; sourceTree = ""; }; + 96CE34CA1B6B059C00705360 /* events.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = events.c; path = ../../src/events.c; sourceTree = ""; }; + 96CE34CB1B6B059C00705360 /* evtsrc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = evtsrc.c; path = ../../src/evtsrc.c; sourceTree = ""; }; + 96CE34CC1B6B059C00705360 /* exitfunc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = exitfunc.c; path = ../../src/exitfunc.c; sourceTree = ""; }; + 96CE34CD1B6B059C00705360 /* file_slice.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = file_slice.c; path = ../../src/file_slice.c; sourceTree = ""; }; + 96CE34CE1B6B059C00705360 /* file_stdio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = file_stdio.c; path = ../../src/file_stdio.c; sourceTree = ""; }; + 96CE34CF1B6B059C00705360 /* file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = file.c; path = ../../src/file.c; sourceTree = ""; }; + 96CE34D01B6B059C00705360 /* fshook_stdio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fshook_stdio.c; path = ../../src/fshook_stdio.c; sourceTree = ""; }; + 96CE34D11B6B059C00705360 /* fshook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fshook.c; path = ../../src/fshook.c; sourceTree = ""; }; + 96CE34D21B6B059C00705360 /* fullscreen_mode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fullscreen_mode.c; path = ../../src/fullscreen_mode.c; sourceTree = ""; }; + 96CE34D31B6B059C00705360 /* haptic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = haptic.c; path = ../../src/haptic.c; sourceTree = ""; }; + 96CE34D41B6B059C00705360 /* inline.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inline.c; path = ../../src/inline.c; sourceTree = ""; }; + 96CE34D51B6B059C00705360 /* joynu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = joynu.c; path = ../../src/joynu.c; sourceTree = ""; }; + 96CE34D61B6B059C00705360 /* keybdnu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = keybdnu.c; path = ../../src/keybdnu.c; sourceTree = ""; }; + 96CE34D71B6B059C00705360 /* libc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libc.c; path = ../../src/libc.c; sourceTree = ""; }; + 96CE34D81B6B059C00705360 /* math.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = math.c; path = ../../src/math.c; sourceTree = ""; }; + 96CE34D91B6B059C00705360 /* memblit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memblit.c; path = ../../src/memblit.c; sourceTree = ""; }; + 96CE34DA1B6B059C00705360 /* memdraw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memdraw.c; path = ../../src/memdraw.c; sourceTree = ""; }; + 96CE34DB1B6B059C00705360 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memory.c; path = ../../src/memory.c; sourceTree = ""; }; + 96CE34DC1B6B059C00705360 /* monitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor.c; path = ../../src/monitor.c; sourceTree = ""; }; + 96CE34DD1B6B059C00705360 /* mouse_cursor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mouse_cursor.c; path = ../../src/mouse_cursor.c; sourceTree = ""; }; + 96CE34DE1B6B059C00705360 /* mousenu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mousenu.c; path = ../../src/mousenu.c; sourceTree = ""; }; + 96CE34DF1B6B059C00705360 /* path.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = path.c; path = ../../src/path.c; sourceTree = ""; }; + 96CE34E01B6B059C00705360 /* pixels.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pixels.c; path = ../../src/pixels.c; sourceTree = ""; }; + 96CE34E11B6B059C00705360 /* shader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = shader.c; path = ../../src/shader.c; sourceTree = ""; }; + 96CE34E21B6B059C00705360 /* system.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = system.c; path = ../../src/system.c; sourceTree = ""; }; + 96CE34E31B6B059C00705360 /* threads.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = threads.c; path = ../../src/threads.c; sourceTree = ""; }; + 96CE34E41B6B059C00705360 /* timernu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = timernu.c; path = ../../src/timernu.c; sourceTree = ""; }; + 96CE34E51B6B059C00705360 /* tls_dll.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = tls_dll.inc; path = ../../src/tls_dll.inc; sourceTree = ""; }; + 96CE34E61B6B059C00705360 /* tls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tls.c; path = ../../src/tls.c; sourceTree = ""; }; + 96CE34E71B6B059C00705360 /* touch_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = touch_input.c; path = ../../src/touch_input.c; sourceTree = ""; }; + 96CE34E81B6B059C00705360 /* transformations.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = transformations.c; path = ../../src/transformations.c; sourceTree = ""; }; + 96CE34E91B6B059C00705360 /* tri_soft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tri_soft.c; path = ../../src/tri_soft.c; sourceTree = ""; }; + 96CE34EA1B6B059C00705360 /* utf8.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = utf8.c; path = ../../src/utf8.c; sourceTree = ""; }; + 96CE351B1B6B05D100705360 /* utime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = utime.c; path = ../../src/unix/utime.c; sourceTree = ""; }; + 96CE351C1B6B05D100705360 /* uxthread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = uxthread.c; path = ../../src/unix/uxthread.c; sourceTree = ""; }; + 96CE351F1B6B05F900705360 /* extensions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extensions.c; path = ../../src/opengl/extensions.c; sourceTree = ""; }; + 96CE35201B6B05F900705360 /* ogl_bitmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ogl_bitmap.c; path = ../../src/opengl/ogl_bitmap.c; sourceTree = ""; }; + 96CE35211B6B05F900705360 /* ogl_display.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ogl_display.c; path = ../../src/opengl/ogl_display.c; sourceTree = ""; }; + 96CE35221B6B05F900705360 /* ogl_draw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ogl_draw.c; path = ../../src/opengl/ogl_draw.c; sourceTree = ""; }; + 96CE35231B6B05F900705360 /* ogl_fbo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ogl_fbo.c; path = ../../src/opengl/ogl_fbo.c; sourceTree = ""; }; + 96CE35241B6B05F900705360 /* ogl_lock_es.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ogl_lock_es.c; path = ../../src/opengl/ogl_lock_es.c; sourceTree = ""; }; + 96CE35251B6B05F900705360 /* ogl_lock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ogl_lock.c; path = ../../src/opengl/ogl_lock.c; sourceTree = ""; }; + 96CE35261B6B05F900705360 /* ogl_render_state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ogl_render_state.c; path = ../../src/opengl/ogl_render_state.c; sourceTree = ""; }; + 96CE35271B6B05F900705360 /* ogl_shader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ogl_shader.c; path = ../../src/opengl/ogl_shader.c; sourceTree = ""; }; + 96CE35311B6B061200705360 /* aatree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = aatree.c; path = ../../src/misc/aatree.c; sourceTree = ""; }; + 96CE35321B6B061200705360 /* bstrlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bstrlib.c; path = ../../src/misc/bstrlib.c; sourceTree = ""; }; + 96CE35331B6B061200705360 /* bstrlib.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = bstrlib.txt; path = ../../src/misc/bstrlib.txt; sourceTree = ""; }; + 96CE35341B6B061200705360 /* list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = list.c; path = ../../src/misc/list.c; sourceTree = ""; }; + 96CE35351B6B061200705360 /* vector.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vector.c; path = ../../src/misc/vector.c; sourceTree = ""; }; + 96CE353A1B6B063800705360 /* allegroAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = allegroAppDelegate.m; path = ../../src/iphone/allegroAppDelegate.m; sourceTree = ""; }; + 96CE353B1B6B063800705360 /* EAGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EAGLView.m; path = ../../src/iphone/EAGLView.m; sourceTree = ""; }; + 96CE353C1B6B063800705360 /* iphone_display.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iphone_display.m; path = ../../src/iphone/iphone_display.m; sourceTree = ""; }; + 96CE353D1B6B063800705360 /* iphone_joystick.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iphone_joystick.m; path = ../../src/iphone/iphone_joystick.m; sourceTree = ""; }; + 96CE353E1B6B063800705360 /* iphone_keyboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iphone_keyboard.c; path = ../../src/iphone/iphone_keyboard.c; sourceTree = ""; }; + 96CE353F1B6B063800705360 /* iphone_main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iphone_main.m; path = ../../src/iphone/iphone_main.m; sourceTree = ""; }; + 96CE35401B6B063800705360 /* iphone_mouse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iphone_mouse.m; path = ../../src/iphone/iphone_mouse.m; sourceTree = ""; }; + 96CE35411B6B063800705360 /* iphone_path.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iphone_path.m; path = ../../src/iphone/iphone_path.m; sourceTree = ""; }; + 96CE35421B6B063800705360 /* iphone_system.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iphone_system.c; path = ../../src/iphone/iphone_system.c; sourceTree = ""; }; + 96CE35431B6B063800705360 /* iphone_touch_input.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iphone_touch_input.m; path = ../../src/iphone/iphone_touch_input.m; sourceTree = ""; }; + 96CE35441B6B063800705360 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ViewController.m; path = ../../src/iphone/ViewController.m; sourceTree = ""; }; + 96CE35501B6B064F00705360 /* color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = color.c; path = ../../addons/color/color.c; sourceTree = ""; }; + 96CE35521B6B066100705360 /* font.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = font.c; path = ../../addons/font/font.c; sourceTree = ""; }; + 96CE35531B6B066100705360 /* fontbmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fontbmp.c; path = ../../addons/font/fontbmp.c; sourceTree = ""; }; + 96CE35541B6B066100705360 /* stdfont.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stdfont.c; path = ../../addons/font/stdfont.c; sourceTree = ""; }; + 96CE35551B6B066100705360 /* text.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = text.c; path = ../../addons/font/text.c; sourceTree = ""; }; + 96CE355A1B6B068800705360 /* bmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bmp.c; path = ../../addons/image/bmp.c; sourceTree = ""; }; + 96CE355B1B6B068800705360 /* iio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iio.c; path = ../../addons/image/iio.c; sourceTree = ""; }; + 96CE355D1B6B068800705360 /* pcx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pcx.c; path = ../../addons/image/pcx.c; sourceTree = ""; }; + 96CE355E1B6B068800705360 /* tga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tga.c; path = ../../addons/image/tga.c; sourceTree = ""; }; + 96CE35641B6B069700705360 /* generic_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = generic_main.c; path = ../../addons/main/generic_main.c; sourceTree = ""; }; + 96CE35661B6B06A400705360 /* memfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memfile.c; path = ../../addons/memfile/memfile.c; sourceTree = ""; }; + 96CE35681B6B06C400705360 /* a5_physfs_dir.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = a5_physfs_dir.c; path = ../../addons/physfs/a5_physfs_dir.c; sourceTree = ""; }; + 96CE35691B6B06C400705360 /* a5_physfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = a5_physfs.c; path = ../../addons/physfs/a5_physfs.c; sourceTree = ""; }; + 96CE356C1B6B06EF00705360 /* directx_shaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = directx_shaders.cpp; path = ../../addons/primitives/directx_shaders.cpp; sourceTree = ""; }; + 96CE356D1B6B06EF00705360 /* high_primitives.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = high_primitives.c; path = ../../addons/primitives/high_primitives.c; sourceTree = ""; }; + 96CE356E1B6B06EF00705360 /* line_soft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = line_soft.c; path = ../../addons/primitives/line_soft.c; sourceTree = ""; }; + 96CE35701B6B06EF00705360 /* point_soft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = point_soft.c; path = ../../addons/primitives/point_soft.c; sourceTree = ""; }; + 96CE35711B6B06EF00705360 /* polygon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = polygon.c; path = ../../addons/primitives/polygon.c; sourceTree = ""; }; + 96CE35721B6B06EF00705360 /* polyline.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = polyline.c; path = ../../addons/primitives/polyline.c; sourceTree = ""; }; + 96CE35731B6B06EF00705360 /* prim_directx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = prim_directx.cpp; path = ../../addons/primitives/prim_directx.cpp; sourceTree = ""; }; + 96CE35741B6B06EF00705360 /* prim_opengl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prim_opengl.c; path = ../../addons/primitives/prim_opengl.c; sourceTree = ""; }; + 96CE35751B6B06EF00705360 /* prim_soft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prim_soft.c; path = ../../addons/primitives/prim_soft.c; sourceTree = ""; }; + 96CE35761B6B06EF00705360 /* prim_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prim_util.c; path = ../../addons/primitives/prim_util.c; sourceTree = ""; }; + 96CE35771B6B06EF00705360 /* primitives.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = primitives.c; path = ../../addons/primitives/primitives.c; sourceTree = ""; }; + 96CE35781B6B06EF00705360 /* triangulator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = triangulator.c; path = ../../addons/primitives/triangulator.c; sourceTree = ""; }; + 96CE35861B6B070300705360 /* ttf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ttf.c; path = ../../addons/ttf/ttf.c; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 964130EC1A6353E700184496 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 964130E61A6353E700184496 = { + isa = PBXGroup; + children = ( + 96CE35861B6B070300705360 /* ttf.c */, + 96CE34BA1B6B055300705360 /* src */, + 964130F01A6353E700184496 /* Products */, + ); + sourceTree = ""; + }; + 964130F01A6353E700184496 /* Products */ = { + isa = PBXGroup; + children = ( + 964130EF1A6353E700184496 /* libAllegro5_iOS.a */, + ); + name = Products; + sourceTree = ""; + }; + 96CE34BA1B6B055300705360 /* src */ = { + isa = PBXGroup; + children = ( + 96A12D041D2F3F9300F245D9 /* identify.c */, + 96A12D021D2F3C3E00F245D9 /* png.c */, + 96A3016F1B9A8778002E2D1C /* iphone_clipboard.m */, + 96A3016D1B9A874F002E2D1C /* clipboard.c */, + 96CE356C1B6B06EF00705360 /* directx_shaders.cpp */, + 96CE356D1B6B06EF00705360 /* high_primitives.c */, + 96CE356E1B6B06EF00705360 /* line_soft.c */, + 96CE35701B6B06EF00705360 /* point_soft.c */, + 96CE35711B6B06EF00705360 /* polygon.c */, + 96CE35721B6B06EF00705360 /* polyline.c */, + 96CE35731B6B06EF00705360 /* prim_directx.cpp */, + 96CE35741B6B06EF00705360 /* prim_opengl.c */, + 96CE35751B6B06EF00705360 /* prim_soft.c */, + 96CE35761B6B06EF00705360 /* prim_util.c */, + 96CE35771B6B06EF00705360 /* primitives.c */, + 96CE35781B6B06EF00705360 /* triangulator.c */, + 96CE35681B6B06C400705360 /* a5_physfs_dir.c */, + 96CE35691B6B06C400705360 /* a5_physfs.c */, + 96CE35661B6B06A400705360 /* memfile.c */, + 96CE35641B6B069700705360 /* generic_main.c */, + 96CE355A1B6B068800705360 /* bmp.c */, + 96CE355B1B6B068800705360 /* iio.c */, + 96CE355D1B6B068800705360 /* pcx.c */, + 96CE355E1B6B068800705360 /* tga.c */, + 968608751B6B12960008BD29 /* dds.c */, + 96CE35521B6B066100705360 /* font.c */, + 96CE35531B6B066100705360 /* fontbmp.c */, + 96CE35541B6B066100705360 /* stdfont.c */, + 96CE35551B6B066100705360 /* text.c */, + 96CE35501B6B064F00705360 /* color.c */, + 96CE353A1B6B063800705360 /* allegroAppDelegate.m */, + 96CE353B1B6B063800705360 /* EAGLView.m */, + 96CE353C1B6B063800705360 /* iphone_display.m */, + 96CE353D1B6B063800705360 /* iphone_joystick.m */, + 96CE353E1B6B063800705360 /* iphone_keyboard.c */, + 96CE353F1B6B063800705360 /* iphone_main.m */, + 96CE35401B6B063800705360 /* iphone_mouse.m */, + 96CE35411B6B063800705360 /* iphone_path.m */, + 96CE35421B6B063800705360 /* iphone_system.c */, + 96CE35431B6B063800705360 /* iphone_touch_input.m */, + 96CE35441B6B063800705360 /* ViewController.m */, + 96CE35311B6B061200705360 /* aatree.c */, + 96CE35321B6B061200705360 /* bstrlib.c */, + 96CE35331B6B061200705360 /* bstrlib.txt */, + 96CE35341B6B061200705360 /* list.c */, + 96CE35351B6B061200705360 /* vector.c */, + 96CE351F1B6B05F900705360 /* extensions.c */, + 96CE35201B6B05F900705360 /* ogl_bitmap.c */, + 96CE35211B6B05F900705360 /* ogl_display.c */, + 96CE35221B6B05F900705360 /* ogl_draw.c */, + 96CE35231B6B05F900705360 /* ogl_fbo.c */, + 96CE35241B6B05F900705360 /* ogl_lock_es.c */, + 96CE35251B6B05F900705360 /* ogl_lock.c */, + 96CE35261B6B05F900705360 /* ogl_render_state.c */, + 96CE35271B6B05F900705360 /* ogl_shader.c */, + 96CE351B1B6B05D100705360 /* utime.c */, + 96CE351C1B6B05D100705360 /* uxthread.c */, + 96CE34BB1B6B059C00705360 /* allegro.c */, + 96CE34BC1B6B059C00705360 /* bitmap_draw.c */, + 96CE34BD1B6B059C00705360 /* bitmap_io.c */, + 96CE34BE1B6B059C00705360 /* bitmap_lock.c */, + 96CE34BF1B6B059C00705360 /* bitmap_pixel.c */, + 96CE34C01B6B059C00705360 /* bitmap_type.c */, + 96CE34C11B6B059C00705360 /* bitmap.c */, + 96CE34C21B6B059C00705360 /* blenders.c */, + 96CE34C31B6B059C00705360 /* config.c */, + 96CE34C41B6B059C00705360 /* convert.c */, + 96CE34C51B6B059C00705360 /* debug.c */, + 96CE34C61B6B059C00705360 /* display_settings.c */, + 96CE34C71B6B059C00705360 /* display.c */, + 96CE34C81B6B059C00705360 /* drawing.c */, + 96CE34C91B6B059C00705360 /* dtor.c */, + 96CE34CA1B6B059C00705360 /* events.c */, + 96CE34CB1B6B059C00705360 /* evtsrc.c */, + 96CE34CC1B6B059C00705360 /* exitfunc.c */, + 96CE34CD1B6B059C00705360 /* file_slice.c */, + 96CE34CE1B6B059C00705360 /* file_stdio.c */, + 96CE34CF1B6B059C00705360 /* file.c */, + 96CE34D01B6B059C00705360 /* fshook_stdio.c */, + 96CE34D11B6B059C00705360 /* fshook.c */, + 96CE34D21B6B059C00705360 /* fullscreen_mode.c */, + 96CE34D31B6B059C00705360 /* haptic.c */, + 96CE34D41B6B059C00705360 /* inline.c */, + 96CE34D51B6B059C00705360 /* joynu.c */, + 96CE34D61B6B059C00705360 /* keybdnu.c */, + 96CE34D71B6B059C00705360 /* libc.c */, + 96CE34D81B6B059C00705360 /* math.c */, + 96CE34D91B6B059C00705360 /* memblit.c */, + 96CE34DA1B6B059C00705360 /* memdraw.c */, + 96CE34DB1B6B059C00705360 /* memory.c */, + 96CE34DC1B6B059C00705360 /* monitor.c */, + 96CE34DD1B6B059C00705360 /* mouse_cursor.c */, + 96CE34DE1B6B059C00705360 /* mousenu.c */, + 96CE34DF1B6B059C00705360 /* path.c */, + 96CE34E01B6B059C00705360 /* pixels.c */, + 96CE34E11B6B059C00705360 /* shader.c */, + 96CE34E21B6B059C00705360 /* system.c */, + 96CE34E31B6B059C00705360 /* threads.c */, + 96CE34E41B6B059C00705360 /* timernu.c */, + 96CE34E51B6B059C00705360 /* tls_dll.inc */, + 96CE34E61B6B059C00705360 /* tls.c */, + 96CE34E71B6B059C00705360 /* touch_input.c */, + 96CE34E81B6B059C00705360 /* transformations.c */, + 96CE34E91B6B059C00705360 /* tri_soft.c */, + 96CE34EA1B6B059C00705360 /* utf8.c */, + ); + name = "src "; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 964130EE1A6353E700184496 /* Allegro5_iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 964131031A6353E800184496 /* Build configuration list for PBXNativeTarget "Allegro5_iOS" */; + buildPhases = ( + 964130EB1A6353E700184496 /* Sources */, + 964130EC1A6353E700184496 /* Frameworks */, + 964130ED1A6353E700184496 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Allegro5_iOS; + productName = "Allegro 5 iOS"; + productReference = 964130EF1A6353E700184496 /* libAllegro5_iOS.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 964130E71A6353E700184496 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = Allegro; + TargetAttributes = { + 964130EE1A6353E700184496 = { + CreatedOnToolsVersion = 6.1.1; + }; + }; + }; + buildConfigurationList = 964130EA1A6353E700184496 /* Build configuration list for PBXProject "Allegro5_iOS" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 964130E61A6353E700184496; + productRefGroup = 964130F01A6353E700184496 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 964130EE1A6353E700184496 /* Allegro5_iOS */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 964130EB1A6353E700184496 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 96CE35091B6B059C00705360 /* memblit.c in Sources */, + 96CE35591B6B066100705360 /* text.c in Sources */, + 96CE35381B6B061200705360 /* list.c in Sources */, + 96CE35011B6B059C00705360 /* fshook.c in Sources */, + 96CE35181B6B059C00705360 /* transformations.c in Sources */, + 96CE357A1B6B06EF00705360 /* high_primitives.c in Sources */, + 96CE350E1B6B059C00705360 /* mousenu.c in Sources */, + 96CE356B1B6B06C400705360 /* a5_physfs.c in Sources */, + 96CE34F91B6B059C00705360 /* dtor.c in Sources */, + 96CE35851B6B06EF00705360 /* triangulator.c in Sources */, + 96CE35031B6B059C00705360 /* haptic.c in Sources */, + 96CE357E1B6B06EF00705360 /* polygon.c in Sources */, + 96CE34FC1B6B059C00705360 /* exitfunc.c in Sources */, + 96CE354A1B6B063800705360 /* iphone_main.m in Sources */, + 96CE35511B6B064F00705360 /* color.c in Sources */, + 96CE352D1B6B05F900705360 /* ogl_lock_es.c in Sources */, + 96CE35821B6B06EF00705360 /* prim_soft.c in Sources */, + 96A3016E1B9A874F002E2D1C /* clipboard.c in Sources */, + 96CE35651B6B069700705360 /* generic_main.c in Sources */, + 96CE352A1B6B05F900705360 /* ogl_display.c in Sources */, + 96CE357D1B6B06EF00705360 /* point_soft.c in Sources */, + 96CE34FF1B6B059C00705360 /* file.c in Sources */, + 96CE35831B6B06EF00705360 /* prim_util.c in Sources */, + 96CE35841B6B06EF00705360 /* primitives.c in Sources */, + 96CE34F01B6B059C00705360 /* bitmap_type.c in Sources */, + 96CE35131B6B059C00705360 /* threads.c in Sources */, + 96CE35491B6B063800705360 /* iphone_keyboard.c in Sources */, + 96CE350A1B6B059C00705360 /* memdraw.c in Sources */, + 96CE35631B6B068800705360 /* tga.c in Sources */, + 96CE35291B6B05F900705360 /* ogl_bitmap.c in Sources */, + 96CE35621B6B068800705360 /* pcx.c in Sources */, + 96CE357F1B6B06EF00705360 /* polyline.c in Sources */, + 96CE352C1B6B05F900705360 /* ogl_fbo.c in Sources */, + 96A12D051D2F3F9300F245D9 /* identify.c in Sources */, + 96CE354F1B6B063800705360 /* ViewController.m in Sources */, + 96CE34FD1B6B059C00705360 /* file_slice.c in Sources */, + 96CE35481B6B063800705360 /* iphone_joystick.m in Sources */, + 96CE35451B6B063800705360 /* allegroAppDelegate.m in Sources */, + 96CE351E1B6B05D100705360 /* uxthread.c in Sources */, + 96CE35471B6B063800705360 /* iphone_display.m in Sources */, + 96CE34EC1B6B059C00705360 /* bitmap_draw.c in Sources */, + 96CE34FB1B6B059C00705360 /* evtsrc.c in Sources */, + 96CE35001B6B059C00705360 /* fshook_stdio.c in Sources */, + 96CE35021B6B059C00705360 /* fullscreen_mode.c in Sources */, + 96A12D031D2F3C3E00F245D9 /* png.c in Sources */, + 96CE34F81B6B059C00705360 /* drawing.c in Sources */, + 96CE350D1B6B059C00705360 /* mouse_cursor.c in Sources */, + 96CE350C1B6B059C00705360 /* monitor.c in Sources */, + 96CE34F21B6B059C00705360 /* blenders.c in Sources */, + 96CE354D1B6B063800705360 /* iphone_system.c in Sources */, + 96CE35811B6B06EF00705360 /* prim_opengl.c in Sources */, + 96CE35801B6B06EF00705360 /* prim_directx.cpp in Sources */, + 96CE34EB1B6B059C00705360 /* allegro.c in Sources */, + 96CE34F31B6B059C00705360 /* config.c in Sources */, + 96CE355F1B6B068800705360 /* bmp.c in Sources */, + 96CE35371B6B061200705360 /* bstrlib.c in Sources */, + 96CE35871B6B070300705360 /* ttf.c in Sources */, + 96CE352E1B6B05F900705360 /* ogl_lock.c in Sources */, + 96CE34ED1B6B059C00705360 /* bitmap_io.c in Sources */, + 96CE350F1B6B059C00705360 /* path.c in Sources */, + 96CE35171B6B059C00705360 /* touch_input.c in Sources */, + 96CE35101B6B059C00705360 /* pixels.c in Sources */, + 96CE34F51B6B059C00705360 /* debug.c in Sources */, + 96CE35571B6B066100705360 /* fontbmp.c in Sources */, + 96CE350B1B6B059C00705360 /* memory.c in Sources */, + 96CE35111B6B059C00705360 /* shader.c in Sources */, + 968608761B6B12960008BD29 /* dds.c in Sources */, + 96CE35601B6B068800705360 /* iio.c in Sources */, + 96CE35301B6B05F900705360 /* ogl_shader.c in Sources */, + 96CE34EF1B6B059C00705360 /* bitmap_pixel.c in Sources */, + 96CE35281B6B05F900705360 /* extensions.c in Sources */, + 96CE351A1B6B059C00705360 /* utf8.c in Sources */, + 96CE354B1B6B063800705360 /* iphone_mouse.m in Sources */, + 96A301701B9A8778002E2D1C /* iphone_clipboard.m in Sources */, + 96CE35561B6B066100705360 /* font.c in Sources */, + 96CE354C1B6B063800705360 /* iphone_path.m in Sources */, + 96CE34F41B6B059C00705360 /* convert.c in Sources */, + 96CE34F61B6B059C00705360 /* display_settings.c in Sources */, + 96CE351D1B6B05D100705360 /* utime.c in Sources */, + 96CE35791B6B06EF00705360 /* directx_shaders.cpp in Sources */, + 96CE357B1B6B06EF00705360 /* line_soft.c in Sources */, + 96CE35391B6B061200705360 /* vector.c in Sources */, + 96CE352B1B6B05F900705360 /* ogl_draw.c in Sources */, + 96CE35061B6B059C00705360 /* keybdnu.c in Sources */, + 96CE34FE1B6B059C00705360 /* file_stdio.c in Sources */, + 96CE35141B6B059C00705360 /* timernu.c in Sources */, + 96CE35161B6B059C00705360 /* tls.c in Sources */, + 96CE35191B6B059C00705360 /* tri_soft.c in Sources */, + 96CE34F71B6B059C00705360 /* display.c in Sources */, + 96CE354E1B6B063800705360 /* iphone_touch_input.m in Sources */, + 96CE35461B6B063800705360 /* EAGLView.m in Sources */, + 96CE34F11B6B059C00705360 /* bitmap.c in Sources */, + 96CE356A1B6B06C400705360 /* a5_physfs_dir.c in Sources */, + 96CE35671B6B06A400705360 /* memfile.c in Sources */, + 96CE35151B6B059C00705360 /* tls_dll.inc in Sources */, + 96CE352F1B6B05F900705360 /* ogl_render_state.c in Sources */, + 96CE34FA1B6B059C00705360 /* events.c in Sources */, + 96CE35581B6B066100705360 /* stdfont.c in Sources */, + 96CE35081B6B059C00705360 /* math.c in Sources */, + 96CE35051B6B059C00705360 /* joynu.c in Sources */, + 96CE35041B6B059C00705360 /* inline.c in Sources */, + 96CE35071B6B059C00705360 /* libc.c in Sources */, + 96CE35121B6B059C00705360 /* system.c in Sources */, + 96CE34EE1B6B059C00705360 /* bitmap_lock.c in Sources */, + 96CE35361B6B061200705360 /* aatree.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 964131011A6353E800184496 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 964131021A6353E800184496 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 964131041A6353E800184496 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++98"; + CLANG_CXX_LIBRARY = "libstdc++"; + CLANG_ENABLE_OBJC_ARC = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + ALLEGRO_LIB_BUILD, + ALLEGRO_UNSTABLE, + ALLEGRO_INTERNAL_UNSTABLE, + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + ../../include, + ../../deps/include, + ../../addons/color, + ../../addons/font, + ../../addons/image, + ../../addons/main, + ../../addons/memfile, + ../../addons/physfs, + ../../addons/primitives, + ../../addons/ttf, + ../../misc/Allegro5_iOS, + ); + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + LIBRARY_SEARCH_PATHS = ""; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = Allegro5_iOS; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "arm64 armv7"; + }; + name = Debug; + }; + 964131051A6353E800184496 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++98"; + CLANG_CXX_LIBRARY = "libstdc++"; + CLANG_ENABLE_OBJC_ARC = NO; + GCC_OPTIMIZATION_LEVEL = s; + GCC_PREPROCESSOR_DEFINITIONS = ( + ALLEGRO_LIB_BUILD, + ALLEGRO_UNSTABLE, + ALLEGRO_INTERNAL_UNSTABLE, + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + ../../include, + ../../deps/include, + ../../addons/color, + ../../addons/font, + ../../addons/image, + ../../addons/main, + ../../addons/memfile, + ../../addons/physfs, + ../../addons/primitives, + ../../addons/ttf, + ../../misc/Allegro5_iOS, + ); + IPHONEOS_DEPLOYMENT_TARGET = 6.1; + LIBRARY_SEARCH_PATHS = ""; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = Allegro5_iOS; + SKIP_INSTALL = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "arm64 armv7"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 964130EA1A6353E700184496 /* Build configuration list for PBXProject "Allegro5_iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 964131011A6353E800184496 /* Debug */, + 964131021A6353E800184496 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 964131031A6353E800184496 /* Build configuration list for PBXNativeTarget "Allegro5_iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 964131041A6353E800184496 /* Debug */, + 964131051A6353E800184496 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 964130E71A6353E700184496 /* Project object */; +} diff --git a/allegro/misc/Allegro5_iOS/allegro5/internal/aintern_image_cfg.h b/allegro/misc/Allegro5_iOS/allegro5/internal/aintern_image_cfg.h new file mode 100644 index 00000000..70f7cd8e --- /dev/null +++ b/allegro/misc/Allegro5_iOS/allegro5/internal/aintern_image_cfg.h @@ -0,0 +1,14 @@ +/* #define ALLEGRO_CFG_WANT_NATIVE_IMAGE_LOADER */ + +/* which libraries are present and needed? */ +/* #undef ALLEGRO_CFG_IIO_HAVE_GDIPLUS */ +/* #undef ALLEGRO_CFG_IIO_HAVE_GDIPLUS_LOWERCASE_H */ +/* #undef ALLEGRO_CFG_IIO_HAVE_ANDROID */ +/* #undef ALLEGRO_CFG_IIO_HAVE_PNG */ +/* #undef ALLEGRO_CFG_IIO_HAVE_JPG */ + +#define ALLEGRO_CFG_IIO_HAVE_PNG + +/* which formats are supported and wanted? */ +#define ALLEGRO_CFG_IIO_SUPPORT_PNG +//#define ALLEGRO_CFG_IIO_SUPPORT_JPG diff --git a/allegro/misc/Allegro5_iOS/allegro5/internal/aintern_ttf_cfg.h b/allegro/misc/Allegro5_iOS/allegro5/internal/aintern_ttf_cfg.h new file mode 100644 index 00000000..ad50e076 --- /dev/null +++ b/allegro/misc/Allegro5_iOS/allegro5/internal/aintern_ttf_cfg.h @@ -0,0 +1 @@ +/* #undef ALLEGRO_CFG_TTF_FREETYPE */ diff --git a/allegro/misc/Allegro5_iOS/allegro5/platform/alplatf.h b/allegro/misc/Allegro5_iOS/allegro5/platform/alplatf.h new file mode 100644 index 00000000..b3257979 --- /dev/null +++ b/allegro/misc/Allegro5_iOS/allegro5/platform/alplatf.h @@ -0,0 +1,109 @@ +/* alplatf.h is generated from alplatf.h.cmake */ +/* #undef ALLEGRO_MINGW32 */ +/* #undef ALLEGRO_UNIX */ +/* #undef ALLEGRO_MSVC */ +/* #undef ALLEGRO_MACOSX */ +/* #undef ALLEGRO_BCC32 */ +#define ALLEGRO_IPHONE +/* #undef ALLEGRO_ANDROID */ +/* #undef ALLEGRO_RASPBERRYPI */ +/* #undef ALLEGRO_CFG_NO_FPU */ +/* #undef ALLEGRO_CFG_DLL_TLS */ +#define ALLEGRO_CFG_PTHREADS_TLS +/* #undef ALLEGRO_CFG_RELEASE_LOGGING */ + +/* #undef ALLEGRO_CFG_D3D */ +/* #undef ALLEGRO_CFG_D3D9EX */ +/* #undef ALLEGRO_CFG_D3DX9 */ +/* #undef ALLEGRO_CFG_XINPUT */ +#define ALLEGRO_CFG_OPENGL +#define ALLEGRO_CFG_OPENGLES +#define ALLEGRO_CFG_OPENGLES2 +#define ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE +#define ALLEGRO_CFG_SHADER_GLSL +/* #undef ALLEGRO_CFG_SHADER_HLSL */ +/* #undef ALLEGRO_CFG_OPENGL_S3TC_LOCKING */ + +/* #undef ALLEGRO_CFG_ANDROID_LEGACY */ + +/*---------------------------------------------------------------------------*/ + +/* Define to 1 if you have the corresponding header file. */ +#define ALLEGRO_HAVE_DIRENT_H +#define ALLEGRO_HAVE_INTTYPES_H +/* #undef ALLEGRO_HAVE_LINUX_AWE_VOICE_H */ +/* #undef ALLEGRO_HAVE_LINUX_INPUT_H */ +/* #undef ALLEGRO_HAVE_LINUX_SOUNDCARD_H */ +/* #undef ALLEGRO_HAVE_MACHINE_SOUNDCARD_H */ +/* #undef ALLEGRO_HAVE_SOUNDCARD_H */ +#define ALLEGRO_HAVE_STDBOOL_H +#define ALLEGRO_HAVE_STDINT_H +/* #undef ALLEGRO_HAVE_SV_PROCFS_H */ +/* #undef ALLEGRO_HAVE_SYS_IO_H */ +/* #undef ALLEGRO_HAVE_SYS_SOUNDCARD_H */ +#define ALLEGRO_HAVE_SYS_STAT_H +#define ALLEGRO_HAVE_SYS_TIME_H +#define ALLEGRO_HAVE_TIME_H +#define ALLEGRO_HAVE_SYS_UTSNAME_H +#define ALLEGRO_HAVE_SYS_TYPES_H +#define ALLEGRO_HAVE_OSATOMIC_H +/* #undef ALLEGRO_HAVE_SYS_INOTIFY_H */ +/* #undef ALLEGRO_HAVE_SAL_H */ + +/* Define to 1 if the corresponding functions are available. */ +/* #undef ALLEGRO_HAVE_GETEXECNAME */ +#define ALLEGRO_HAVE_MKSTEMP +#define ALLEGRO_HAVE_MMAP +#define ALLEGRO_HAVE_MPROTECT +#define ALLEGRO_HAVE_SCHED_YIELD +#define ALLEGRO_HAVE_SYSCONF +#define ALLEGRO_HAVE_FSEEKO +#define ALLEGRO_HAVE_FTELLO +#define ALLEGRO_HAVE_STRERROR_R +/* #undef ALLEGRO_HAVE_STRERROR_S */ +#define ALLEGRO_HAVE_VA_COPY + +/* Define to 1 if procfs reveals argc and argv */ +/* #undef ALLEGRO_HAVE_PROCFS_ARGCV */ + +/*---------------------------------------------------------------------------*/ + +/* Define if target machine is little endian. */ +#define ALLEGRO_LITTLE_ENDIAN + +/* Define if target machine is big endian. */ +/* #undef ALLEGRO_BIG_ENDIAN */ + +/* Define if target platform is Darwin. */ +/* #undef ALLEGRO_DARWIN */ + +/*---------------------------------------------------------------------------*/ + +/* Define if you need support for X-Windows. */ +/* #undef ALLEGRO_WITH_XWINDOWS */ + +/* Define if XCursor ARGB extension is available. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XCURSOR */ + +/* Define if XF86VidMode extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE */ + +/* Define if Xinerama extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XINERAMA */ + +/* Define if XRandR extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XRANDR */ + +/* Define if XIM extension is supported. */ +/* #undef ALLEGRO_XWINDOWS_WITH_XIM */ + +/*---------------------------------------------------------------------------*/ + +/* Define if target platform is linux. */ +/* #undef ALLEGRO_LINUX */ + +/* Define if we are building with SDL backend. */ +/* #undef ALLEGRO_SDL */ + +/*---------------------------------------------------------------------------*/ +/* vi: set ft=c ts=3 sts=3 sw=3 et: */ diff --git a/allegro/misc/allegro.pc.in b/allegro/misc/allegro.pc.in new file mode 100644 index 00000000..c7185cfe --- /dev/null +++ b/allegro/misc/allegro.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro +Description: Allegro game programming library +Version: ${version} +Libs: -L${libdir} -lallegro${suffix} +Libs.private: @link_with@ +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_acodec.pc.in b/allegro/misc/allegro_acodec.pc.in new file mode 100644 index 00000000..2187dea9 --- /dev/null +++ b/allegro/misc/allegro_acodec.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_acodec +Description: Allegro game programming library, audio codec addon +Version: ${version} +Libs: -L${libdir} -lallegro_acodec${suffix} +Libs.private: @link_with@ +Requires: allegro_audio${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_audio.pc.in b/allegro/misc/allegro_audio.pc.in new file mode 100644 index 00000000..3ce87fdd --- /dev/null +++ b/allegro/misc/allegro_audio.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_audio +Description: Allegro game programming library, audio addon +Version: ${version} +Libs: -L${libdir} -lallegro_audio${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_color.pc.in b/allegro/misc/allegro_color.pc.in new file mode 100644 index 00000000..fc985b0d --- /dev/null +++ b/allegro/misc/allegro_color.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_color +Description: Allegro game programming library, colors addon +Version: ${version} +Libs: -L${libdir} -lallegro_color${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_dialog.pc.in b/allegro/misc/allegro_dialog.pc.in new file mode 100644 index 00000000..67b8cb72 --- /dev/null +++ b/allegro/misc/allegro_dialog.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_dialog +Description: Allegro game programming library, native dialog addon +Version: ${version} +Libs: -L${libdir} -lallegro_dialog${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_font.pc.in b/allegro/misc/allegro_font.pc.in new file mode 100644 index 00000000..46ea1d56 --- /dev/null +++ b/allegro/misc/allegro_font.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_font +Description: Allegro game programming library, font addon +Version: ${version} +Libs: -L${libdir} -lallegro_font${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_image.pc.in b/allegro/misc/allegro_image.pc.in new file mode 100644 index 00000000..4bdc9f00 --- /dev/null +++ b/allegro/misc/allegro_image.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_image +Description: Allegro game programming library, image I/O addon +Version: ${version} +Libs: -L${libdir} -lallegro_image${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_main.pc.in b/allegro/misc/allegro_main.pc.in new file mode 100644 index 00000000..0f620d57 --- /dev/null +++ b/allegro/misc/allegro_main.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_main +Description: Allegro game programming library, magic main addon +Version: ${version} +Libs: -L${libdir} -lallegro_main${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_memfile.pc.in b/allegro/misc/allegro_memfile.pc.in new file mode 100644 index 00000000..f6887de6 --- /dev/null +++ b/allegro/misc/allegro_memfile.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_memfile +Description: Allegro game programming library, memory files addon +Version: ${version} +Libs: -L${libdir} -lallegro_memfile${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_monolith.pc.in b/allegro/misc/allegro_monolith.pc.in new file mode 100644 index 00000000..f8bcc488 --- /dev/null +++ b/allegro/misc/allegro_monolith.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_monolith +Description: Allegro game programming library (all addons included) +Version: ${version} +Libs: -L${libdir} -lallegro_monolith${suffix} +Libs.private: @link_with@ +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_physfs.pc.in b/allegro/misc/allegro_physfs.pc.in new file mode 100644 index 00000000..2a0d7d8f --- /dev/null +++ b/allegro/misc/allegro_physfs.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_physfs +Description: Allegro game programming library, PhysicsFS addon +Version: ${version} +Libs: -L${libdir} -lallegro_physfs${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_primitives.pc.in b/allegro/misc/allegro_primitives.pc.in new file mode 100644 index 00000000..1932353b --- /dev/null +++ b/allegro/misc/allegro_primitives.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_primitives +Description: Allegro game programming library, primitives addon +Version: ${version} +Libs: -L${libdir} -lallegro_primitives${suffix} +Libs.private: @link_with@ +Requires: allegro${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_ttf.pc.in b/allegro/misc/allegro_ttf.pc.in new file mode 100644 index 00000000..be44bc49 --- /dev/null +++ b/allegro/misc/allegro_ttf.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_ttf +Description: Allegro game programming library, TrueType fonts addon +Version: ${version} +Libs: -L${libdir} -lallegro_ttf${suffix} +Libs.private: @link_with@ +Requires: allegro_font${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/allegro_video.pc.in b/allegro/misc/allegro_video.pc.in new file mode 100644 index 00000000..566a4bbf --- /dev/null +++ b/allegro/misc/allegro_video.pc.in @@ -0,0 +1,15 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ +version=@ALLEGRO_VERSION@ +suffix=@lib_type@@lib_linkage@ +versuffix=@versuffix@ + +Name: allegro_video +Description: Allegro game programming library, video player addon +Version: ${version} +Libs: -L${libdir} -lallegro_video${suffix} +Libs.private: @link_with@ +Requires: allegro_audio${suffix}-${versuffix} >= ${version} +Cflags: -I${includedir} diff --git a/allegro/misc/askq.c b/allegro/misc/askq.c new file mode 100644 index 00000000..643d11c1 --- /dev/null +++ b/allegro/misc/askq.c @@ -0,0 +1,38 @@ +/* + * ASKQ - asks a yes/no question, returning an exit status to the caller. + * This is used by the msvcmake installation batch file. + */ + + +#include +#include + + + +int main(int argc, char *argv[]) +{ + int i; + + puts("\n"); + + for (i=1; i 1) + putc(' ', stdout); + + puts(argv[i]); + } + + puts("? [y/n] "); + + for (;;) { + i = getc(stdin); + + if ((tolower(i) == 'y') || (tolower(i) == 'n')) { + putc(i, stdout); + puts("\n\n"); + return (tolower(i) == 'y') ? 0 : 1; + } + else + putc(7, stdout); + } +} diff --git a/allegro/misc/convert_line_endings.sh b/allegro/misc/convert_line_endings.sh new file mode 100644 index 00000000..8aebf968 --- /dev/null +++ b/allegro/misc/convert_line_endings.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# +# This file is only used now to convert file line endings by misc/zipup.sh. +# We used to do this in fix.sh/fix.bat but those files have been removed +# in the 4.9.x series as running them could confuse the CMake and Scons builds, +# plus the old build system is not being maintained. +# + +proc_filelist() +{ + # common files. This must not include any shell scripts or batch files. + AL_FILELIST=`find . -type f "(" ! -path "*/.*" ")" -a "(" \ + -name "*.c" -o -name "*.cfg" -o -name "*.cpp" -o -name "*.def" -o \ + -name "*.h" -o -name "*.hin" -o -name "*.in" -o -name "*.inc" -o \ + -name "*.m" -o -name "*.m4" -o -name "*.mft" -o -name "*.s" -o \ + -name "*.rc" -o -name "*.rh" -o -name "*.spec" -o -name "*.pl" -o \ + -name "*.txt" -o -name "*._tx" -o -name "makefile*" -o \ + -name "*.inl" -o -name "CHANGES" -o \ + -name "AUTHORS" -o -name "THANKS" ")" \ + -a ! -path "*.dist*" \ + ` + + # touch unix shell scripts? + if [ "$1" != "omit_sh" ]; then + AL_FILELIST="$AL_FILELIST `find . -type f -name '*.sh' -o \ + -name 'configure' -a ! -path "*addons*"`" + fi + + # touch DOS batch files? + if [ "$1" != "omit_bat" ]; then + AL_FILELIST="$AL_FILELIST `find . -type f -name '*.bat' -a \ + ! -path "*addons*"`" + fi +} + +proc_utod() +{ + echo "Converting files from Unix to DOS/Win32 ..." + proc_filelist "omit_sh" + /bin/sh misc/utod.sh $AL_FILELIST +} + +proc_dtou() +{ + echo "Converting files from DOS/Win32 to Unix ..." + proc_filelist "omit_bat" + /bin/sh misc/dtou.sh $AL_FILELIST +} + +trap 'exit $?' 1 2 3 13 15 + +case "$1" in + "--utod" ) proc_utod ;; + "--dtou" ) proc_dtou ;; +esac + +echo "Done!" diff --git a/allegro/misc/coverage.sh b/allegro/misc/coverage.sh new file mode 100644 index 00000000..fe32adf4 --- /dev/null +++ b/allegro/misc/coverage.sh @@ -0,0 +1,56 @@ +#!/bin/sh -e +# Produce test coverage results using lcov. +# Run this from a dedicated build directory unless you don't mind your build +# flags being changed. + +BUILDDIR=$(dirname $PWD) +JOBS=${JOBS:-4} + +if ! test ../LICENSE.txt +then + echo "Run this in a build subdirectory." 1>&2 + exit 1 +fi + +if ! which lcov 2>&1 >/dev/null +then + echo "lcov is required." 1>&2 + exit 1 +fi + +# ccache can interfere with gcov by causing profiling data to end up in the +# ~/.ccache directory. +export CCACHE_DISABLE=1 + +cmake \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCMAKE_C_FLAGS=--coverage \ + -DCMAKE_CXX_FLAGS=--coverage \ + -DCMAKE_EXE_LINKER_FLAGS=--coverage \ + -DWANT_POPUP_EXAMPLES=no \ + .. + +lcov -d $BUILDDIR --zerocounters + +make -j${JOBS} ex_blend_test +make -j${JOBS} ex_config +make -j${JOBS} ex_dir +make -j${JOBS} ex_path_test +make -j${JOBS} ex_utf8 +make -j${JOBS} copy_example_data copy_demo_data + +( cd examples + ./ex_blend_test + ./ex_config + ./ex_dir + ./ex_path_test + ./ex_utf8 +) || true + +( cd tests + make -j${JOBS} run_tests +) || true + +lcov -d $BUILDDIR --capture --output allegro_auto.info + +genhtml --legend allegro_auto.info --output-directory coverage diff --git a/allegro/misc/create_release_archives.sh b/allegro/misc/create_release_archives.sh new file mode 100644 index 00000000..e4727f63 --- /dev/null +++ b/allegro/misc/create_release_archives.sh @@ -0,0 +1,50 @@ +#!/bin/sh +set -e + +ver=$1 + +if [ -z "$ver" ] +then + echo "Please pass a version." + exit 1 +fi + +if git show $ver -- 2>&1 | grep -q 'fatal' +then + echo "$ver is not a valid revision." + exit 1 +fi + +export LC_ALL=en_US + +repo=$PWD +tmpdir=$( mktemp -d ) + +git archive --format=tar --prefix=allegro/ ${ver} | ( cd $tmpdir && tar xf - ) + +( cd "$tmpdir/allegro" + for file in $( find -type f -printf '%P\n' ) + do + echo $file + commit=$( cd $repo && git rev-list ${ver} "$file" | head -n 1 ) + mtime=$( cd $repo && git show --pretty=format:%ai $commit | head -n 1) + touch -d "$mtime" "$file" + done +) + +( cd "$tmpdir/allegro" + ./misc/zipup.sh allegro-$ver.zip + mv .dist/*.* .. +) + +(cd "$tmpdir" + rm -rf allegro + unzip allegro-$ver.zip + ./allegro/misc/mkunixdists.sh allegro-$ver.zip +) + +mv "$tmpdir"/*.* ./ + +rm -rf -- "$tmpdir" + +echo "Done and done!" diff --git a/allegro/misc/dtou.sh b/allegro/misc/dtou.sh new file mode 100644 index 00000000..2788f000 --- /dev/null +++ b/allegro/misc/dtou.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# Convert CR/LF line endings to LF line endings, preserving timestamps and +# permissions on the file. +# + +with_unix_tools() { + for file in "$@" + do + echo "$file" + + tmpfile=`dirname "$file"`/__dtou_tmp.$RANDOM || exit 1 + trap 'rm -f "$tmpfile"' 1 2 3 13 15 + + # We go through a slightly convoluted sequence of commands in order to + # preserve both the timestamp and permissions on the file. + { + tr -d '\015' < "$file" > "$tmpfile" && + touch -r "$file" "$tmpfile" && + cat "$tmpfile" > "$file" && + touch -r "$tmpfile" "$file" && + rm -f "$tmpfile" + } || exit 1 + done +} + +with_cygwin() { + for file in "$@" + do + dos2unix $file || exit 1 + done +} + +if test -z "$1" +then + echo "$0 filename" + exit +fi + +if test "$ALLEGRO_USE_CYGWIN" = "1" +then + with_cygwin "$@" +else + with_unix_tools "$@" +fi + +# vi: sts=3 sw=3 et diff --git a/allegro/misc/embedman.bat b/allegro/misc/embedman.bat new file mode 100644 index 00000000..b295c9f8 --- /dev/null +++ b/allegro/misc/embedman.bat @@ -0,0 +1,66 @@ +@ECHO OFF +REM *** embedman.bat is a helper tool for MSVC8. +REM It embeds all XML manifest files into its corresponding executable. + +REM ======== DISPATCHING ======== +IF "%1" == "" GOTO usage +IF "%1" == "all" IF "%2" == "" GOTO search +IF "%2" == "" GOTO bad_usage +IF NOT EXIST "%1" GOTO file_not_found +IF NOT EXIST "%1.manifest" GOTO no_manifest + +REM ======== EMBED MANIFEST ======== +mt -nologo -manifest %1.manifest -outputresource:%1;%2 +IF NOT "%ERRORLEVEL%" == "0" GOTO mt_fail +del %1.manifest +GOTO end + +REM ======== SEARCH AND EMBED ======== +:search +FOR /R %%v IN (*.exe) DO CALL %0 %%v 1 -silent +FOR /R %%v IN (*.scr) DO CALL %0 %%v 1 -silent +FOR /R %%v IN (*.dll) DO CALL %0 %%v 2 -silent + +GOTO end + +REM ======== ERRORS ======== +:usage +ECHO. +ECHO Running embedman.bat with "all" as the first and only parameter causes it to +ECHO search for all executables and DLLs with manifest files, and embed them. +ECHO. +ECHO %0 all +ECHO. +ECHO Alternatively, you can specify an exact file: +ECHO. +ECHO %0 file.exe 1 +ECHO %0 file.dll 2 +ECHO. +ECHO In every case, the manifest file must exist in the same folder with the same +ECHO name as the executable for it to work. The manifest file is then deleted. +GOTO end + +:bad_usage +ECHO. +ECHO You must specify whether the file is an executable or DLL via the second +ECHO parameter. +ECHO. +ECHO 1 = Executable +ECHO 2 = DLL +GOTO end + +:file_not_found +ECHO. +ECHO The file "%1" was not found. +GOTO end + +:mt_fail +ECHO Unable to embed %1.manifest! Make sure mt.exe is in the path. +GOTO end + +:no_manifest +IF NOT "%3" == "-silent" ECHO No manifest found for %1 + + +REM ======== THE END ======== +:end \ No newline at end of file diff --git a/allegro/misc/fixver.sh b/allegro/misc/fixver.sh new file mode 100644 index 00000000..b25175c7 --- /dev/null +++ b/allegro/misc/fixver.sh @@ -0,0 +1,100 @@ +#! /bin/sh -e +# +# Shell script to adjust the version numbers and dates in files. +# +# Note: if you pass "datestamp" as the only argument, then the version +# digits will remain unchanged and the comment will be set to the date. +# This is in particular useful for making SVN snapshots. + + +if [ $# -eq 1 -a $1 == "datestamp" ]; then + # Uses GNU grep -o. + ver=$( grep -o "ALLEGRO_VERSION [0-9.]*" CMakeLists.txt | cut -d' ' -f2 ) + major_num=$( echo $ver | cut -d. -f1 ) + sub_num=$( echo $ver | cut -d. -f2 ) + wip_num=$( echo $ver | cut -d. -f3 ) + $0 $major_num $sub_num $wip_num `date '+%Y%m%d'` + exit 0 +fi + +case $# in + 3|4|5) ;; + *) + echo "Usage: fixver major_num sub_num wip_num [n] [comment]" 1>&2 + echo " or: fixver datestamp" 1>&2 + echo "Example: fixver 4 9 14 SVN" 1>&2 + echo " fixver 4 9 14 WIP" 1>&2 + echo " fixver 4 9 14 1 WIP" 1>&2 + echo " fixver 5 0 0" 1>&2 + exit 1 + ;; +esac + +# get the version and date strings in a nice format +case $# in + 3) + # Proper release. + fourth=1 + comment= + ;; + 4) + case $4 in + WIP) + # Proper release + fourth=1 + comment=WIP + ;; + [0-9]) + # Proper release + fourth=$(( $4 + 1 )) + comment= + ;; + *) + fourth=0 + comment=$4 + ;; + esac + ;; + 5) + fourth=$(( $4 + 1 )) + comment=$5 + ;; +esac + +if [ -z "$comment" ]; then + verstr="$1.$2.$3" +else + verstr="$1.$2.$3 ($comment)" +fi + +year=$(date +%Y) +month=$(date +%m) +day=$(date +%d) +datestr="$(date +%b) $day, $year" + +# patch allegro/base.h +echo "s/\#define ALLEGRO_VERSION .*/\#define ALLEGRO_VERSION $1/" > fixver.sed +echo "s/\#define ALLEGRO_SUB_VERSION .*/\#define ALLEGRO_SUB_VERSION $2/" >> fixver.sed +echo "s/\#define ALLEGRO_WIP_VERSION .*/\#define ALLEGRO_WIP_VERSION $3/" >> fixver.sed +echo "s/\#define ALLEGRO_RELEASE_NUMBER .*/\#define ALLEGRO_RELEASE_NUMBER $fourth/" >> fixver.sed +echo "s/\#define ALLEGRO_VERSION_STR .*/\#define ALLEGRO_VERSION_STR \"$verstr\"/" >> fixver.sed +echo "s/\#define ALLEGRO_DATE_STR .*/\#define ALLEGRO_DATE_STR \"$year\"/" >> fixver.sed +echo "s/\#define ALLEGRO_DATE .*/\#define ALLEGRO_DATE $year$month$day \/\* yyyymmdd \*\//" >> fixver.sed + +echo "Patching include/allegro5/base.h..." +cp include/allegro5/base.h fixver.tmp +sed -f fixver.sed fixver.tmp > include/allegro5/base.h + +# patch the OSX package readme +echo "s/\\_\/__\/ Version .*/\\_\/__\/ Version $verstr/" > fixver.sed +echo "s/By Shawn Hargreaves, .*\./By Shawn Hargreaves, $datestr\./" >> fixver.sed + +# patch CMakeLists.txt +echo "Patching CMakeLists.txt..." +cp CMakeLists.txt fixver.tmp +sed -e "s/set(ALLEGRO_VERSION [^)]*)/set(ALLEGRO_VERSION $1.$2.$3)/" fixver.tmp > CMakeLists.txt + +# clean up after ourselves +rm fixver.sed fixver.tmp + +echo "Done!" diff --git a/allegro/misc/gcc-uni.sh b/allegro/misc/gcc-uni.sh new file mode 100644 index 00000000..a5f48dcd --- /dev/null +++ b/allegro/misc/gcc-uni.sh @@ -0,0 +1,131 @@ +#!/bin/sh + +# gcc-uni.sh +# ---------- +# By Matthew Leverton +# +# Builds a universal binary by a multi-step process to allow for individual +# options for both architectures. Its primary use is to be used as a wrapper +# for makefile based projects. +# +# Although untested, it should be able to build OS X 10.2 compatible builds. +# Note that you may need to install the various OS SDKs before this will +# work. gcc-3.3 is used for the PPC build. The active version of gcc is used +# for the Intel build. (Note that it must be at least version 4.) +# +# If the makefile has a CC variable, this is all that should be necessary: +# +# CC=/usr/bin/gcc-uni.sh +# + +# set up defaults +mode=link +output= +cmd= + +# check whether to use gcc or g++ +# (using a symlink with g++ in name is recommended) +case "$0" in + *g++*) + gcc=g++ + ;; + *) + gcc=gcc + ;; +esac + +# which OSX to target (used for PPC) +OSX_TARGET=10.2 + +# which SDK to use (unused with PPC because gcc-3.3 doesn't know about it)) +SDK_i386=/Developer/SDKs/MacOSX10.4u.sdk +SDK_PPC= + +# i386 flags +CFLAGS_i386=" -isysroot $SDK_i386" +LDFLAGS_i386=" -isysroot $SDK_i386 -Wl,-syslibroot,$SDK_i386" + +# ppc flags +CFLAGS_PPC= +LDFLAGS_PPC= + +# Parse options: +# -arch switches are ignored +# looks for -c to enable the CFLAGS +# looks for -o to determine the name of the output + +if [ $# -eq 0 ]; then + echo "This is a wrapper around gcc that builds universal binaries." + echo "It can only be used to compile or link." + exit 1 +fi + +# remember the arguments in case there's no output files +args=$* + +while [ -n "$1" ]; do + case "$1" in + -arch) + shift + ;; + -c) + mode=compile + cmd="$cmd -c" + ;; + -o) + shift + output="$1" + ;; + *) + cmd="$cmd $1" + ;; + esac + + shift +done + +# if no output file, just pass the original command as-is and hope for the best +if [ -z "$output" ]; then + exec $gcc $args +fi + +# figure out if we are compiling or linking +case "$mode" in + link) + FLAGS_i386="$LDFLAGS_i386" + FLAGS_PPC="$LDFLAGS_PPC" + ;; + compile) + FLAGS_i386="$CFLAGS_i386" + FLAGS_PPC="$CFLAGS_PPC" + ;; + *) + echo "internal error in gcc-uni.sh script" + exit 1 + ;; +esac + +# TODO: use trap to cleanup + +# build the i386 version +$gcc $cmd $FLAGS_i386 -arch i386 -o $output.i386 +if [ $? -ne 0 ]; then + exit 1 +fi + +# build the PPC version +MACOSX_DEPLOYMENT_TARGET=$OSX_TARGET /usr/bin/$gcc-3.3 $cmd $FLAGS_PPC -arch ppc -o $output.ppc +if [ $? -ne 0 ]; then + rm -f $output.i386 + exit 1 +fi + +# create the universal version +lipo -create $output.i386 $output.ppc -output $output +if [ $? -ne 0 ]; then + rm -f $output.i386 $output.ppc + exit 1 +fi + +# cleanup +rm -f $output.i386 $output.ppc diff --git a/allegro/misc/gl_mkalias.sh b/allegro/misc/gl_mkalias.sh new file mode 100644 index 00000000..21481693 --- /dev/null +++ b/allegro/misc/gl_mkalias.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# This script creates '*_ext_alias.h' from '*_ext_api.h' in +# include/allegro5/opengl/GLext/ dir + +prefix="glx wgl gl" + +for name in $prefix; do + src="include/allegro5/opengl/GLext/"$name"_ext_api.h" + out="include/allegro5/opengl/GLext/"$name"_ext_alias.h" + prfx=`echo $name | sed 's/glx/glX/'` + cat $src | sed -e '/^[ ]*#/!s/[ ]//g' | awk -F"," "BEGIN{print\"/*Automatically generated by gl_mkalias.sh DO NOT EDIT!*/\"} + {if (\$0 ~ /^AGL_API/) printf \"#define $prfx%s _al_$prfx%s\n\",\$2,\$2; + else print \$0}" > $out +done diff --git a/allegro/misc/icon.png b/allegro/misc/icon.png new file mode 100644 index 00000000..7202c29f Binary files /dev/null and b/allegro/misc/icon.png differ diff --git a/allegro/misc/icon.xpm b/allegro/misc/icon.xpm new file mode 100644 index 00000000..613d02c2 --- /dev/null +++ b/allegro/misc/icon.xpm @@ -0,0 +1,57 @@ +/* XPM */ +static char * alex_xpm[] = { +"48 48 6 1", +" c None", +". c #080808", +"+ c #FCFCFC", +"@ c #486028", +"# c #587834", +"$ c #A4C47C", +" .... .... ", +" .... .... ", +" .++++.. .++++.. ", +" .++++.. .++++.. ", +" ...... ...++.......++... ", +" ...... ...++.......++... ", +"..@@####............@@###....##@.. ", +"..@@####............@@###....##@.. ", +"..###########################..#@@.. ", +"..###########################..#@@.. ", +".............................#####.. ", +".............................#####.. ", +" ...#########@@.. ", +" ......#####..#######.. ", +" ......#####..#######.. ", +" .....######.....$$#######.. ", +" .....######.....$$#######.. ", +" .....#####...... ..$$#######.. ", +" .....#####...... ..$$#######.. ", +" ..#####..... .$$##..###@@.. ", +" ..#####..... .$$##..###@@.. ", +" ..... .......###@@.. ", +" ..... .......###@@.. ", +" ..#########.@@.. ", +" ..##.......@##.. ", +" ..##.......@##.. ", +" ...$$$$#####.. ", +" ...$$$$#####.. ", +" .$$$$#####.. .. ", +" .$$$$#####.. .. ", +" .$$$$#####.. ..@@.", +" .$$$$#####.. ..@@.", +" .$$..#####@@.. ..@@.", +" .$$..#####@@.. ..@@.", +" ..####@..##.. ..##@@.", +" ..####@..##.. ..##@@.", +" ..####@..####...##@@$$.", +" .####@@.$$#######@@$$.. ", +" .####@@.$$#######@@$$.. ", +" .##@@.....$$$$$$$$$.. ", +" .##@@.....$$$$$$$$$.. ", +" ..##@@............ ", +" ..##@@............ ", +" ...######.@@.. ", +" ...######.@@.. ", +" ..#####@@###..@@.. ", +" ..#####@@###..@@.. ", +" .................. "}; diff --git a/allegro/misc/install_test.c b/allegro/misc/install_test.c new file mode 100644 index 00000000..8334dc18 --- /dev/null +++ b/allegro/misc/install_test.c @@ -0,0 +1,50 @@ +/* + * A small test program that you can compile and run to verify that Allegro was + * installed correctly. It assumes you installed all the addons. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int main() { + uint32_t version = al_get_allegro_version(); + int major = version >> 24; + int minor = (version >> 16) & 255; + int revision = (version >> 8) & 255; + int release = version & 255; + + fprintf(stderr, "Library version: %d.%d.%d.%d\n", major, minor, revision, release); + fprintf(stderr, "Header version: %d.%d.%d.%d\n", ALLEGRO_VERSION, ALLEGRO_SUB_VERSION, ALLEGRO_WIP_VERSION, ALLEGRO_RELEASE_NUMBER); + fprintf(stderr, "Header version string: %s\n", ALLEGRO_VERSION_STR); + + if (!al_init()) { + fprintf(stderr, "Failed to initialize Allegro, probably a header/shared library version mismatch.\n"); + return -1; + } + +#define INIT_CHECK(init_function, addon_name) do { if (!init_function()) { fprintf(stderr, "Failed to initialize the " addon_name " addon.\n"); return -1; } } while (0) + + INIT_CHECK(al_init_font_addon, "font"); + INIT_CHECK(al_init_ttf_addon, "TTF"); + INIT_CHECK(al_init_image_addon, "image"); + INIT_CHECK(al_install_audio, "audio"); + INIT_CHECK(al_init_acodec_addon, "acodec"); + INIT_CHECK(al_init_native_dialog_addon, "native dialog"); + INIT_CHECK(al_init_primitives_addon, "primitives"); + INIT_CHECK(al_init_video_addon, "video"); + + fprintf(stderr, "Everything looks good!\n"); + return 0; +} diff --git a/allegro/misc/make_converters.py b/allegro/misc/make_converters.py new file mode 100644 index 00000000..b14ddad5 --- /dev/null +++ b/allegro/misc/make_converters.py @@ -0,0 +1,478 @@ +#!/usr/bin/env python3 +import collections, optparse, re, sys + +formats_by_name = {} +formats_list = [] + +def read_color_h(filename): + """ + Read in the list of formats. + """ + formats = [] + inside_enum = False + for line in open(filename): + line = line.strip() + if line == "{": continue + if line == "typedef enum ALLEGRO_PIXEL_FORMAT": inside_enum = True + elif inside_enum: + match = re.match(r"\s*ALLEGRO_PIXEL_FORMAT_(\w+)", line) + if match: + formats.append(match.group(1)) + else: + break + return formats + +def parse_format(format): + """ + Parse the format name into an info structure. + """ + if format.startswith("ANY"): return None + if "DXT" in format: return None + + separator = format.find("_") + class Info: pass + class Component: pass + + Info = collections.namedtuple("Info", "components, name, little_endian," + "float, single_channel, size") + Component = collections.namedtuple("Component", "color, size," + "position_from_left, position") + + pos = 0 + info = Info( + components={}, + name=format, + little_endian="_LE" in format, + float=False, + single_channel=False, + size=None, + ) + + if "F32" in format: + return info._replace( + float=True, + size=128, + ) + + if "SINGLE_CHANNEL" in format: + return info._replace( + single_channel=True, + size=8, + ) + + for i in range(separator): + c = Component( + color=format[i], + size=int(format[separator + 1 + i]), + position_from_left=pos, + position=None, + ) + info.components[c.color] = c + pos += c.size + size = pos + return info._replace( + components={k: c._replace(position=size - c.position_from_left - c.size) + for k, c in info.components.items()}, + size=size, + float=False, + ) + +def macro_lines(info_a, info_b): + """ + Write out the lines of a conversion macro. + """ + r = "" + + names = list(info_b.components.keys()) + names.sort() + + if info_a.float: + if info_b.single_channel: + return " (uint32_t)((x).r * 255)\n" + lines = [] + for name in names: + if name == "X": continue + c = info_b.components[name] + mask = (1 << c.size) - 1 + lines.append( + "((uint32_t)((x)." + name.lower() + " * " + str(mask) + + ") << " + str(c.position) + ")") + r += " (" + r += " | \\\n ".join(lines) + r += ")\n" + return r + + if info_b.float: + if info_a.single_channel: + return " al_map_rgb(x, 0, 0)\n" + lines = [] + for name in "RGBA": + if name not in info_a.components: break + c = info_a.components[name] + mask = (1 << c.size) - 1 + line = "((x) >> " + str(c.position) + ") & " + str(mask) + if c.size < 8: + line = "_al_rgb_scale_" + str(c.size) + "[" + line + "]" + lines.append(line) + + r += " al_map_rgba(" if len(lines) == 4 else " al_map_rgb(" + r += ",\\\n ".join(lines) + r += ")\n" + return r + + if info_a.single_channel: + lines = [] + for name in names: + # Only map to R, and let A=1 + if name in ["X", "G", "B"]: + continue + c = info_b.components[name] + shift = 8 - c.size - c.position + m = hex(((1 << c.size) - 1) << c.position) + if name == "A": + lines.append(m) + continue + if shift > 0: + lines.append("(((x) >> " + str(shift) + ") & " + m + ")") + elif shift < 0: + lines.append("(((x) << " + str(-shift) + ") & " + m + ")") + else: + lines.append("((x) & " + m + ")") + r += " (" + r += " | \\\n ".join(lines) + r += ")\n" + return r + + if info_b.single_channel: + c = info_a.components["R"] + m = (1 << c.size) - 1 + extract = "(((x) >> " + str(c.position) + ") & " + hex(m) + ")" + if (c.size != 8): + scale = "(_al_rgb_scale_" + str(c.size) + "[" + extract + "])" + else: + scale = extract + r += " " + scale + "\n" + return r + + # Generate a list of (mask, shift, add) tuples for all components. + ops = {} + for name in names: + if name == "X": continue # We simply ignore X components. + c_b = info_b.components[name] + if name not in info_a.components: + # Set A component to all 1 bits if the source doesn't have it. + if name == "A": + add = (1 << c_b.size) - 1 + add <<= c_b.position + ops[name] = (0, 0, add, 0, 0, 0) + continue + c_a = info_a.components[name] + mask = (1 << c_b.size) - 1 + shift_right = c_a.position + mask_pos = c_a.position + shift_left = c_b.position + bitdiff = c_a.size - c_b.size + if bitdiff > 0: + shift_right += bitdiff + mask_pos += bitdiff + else: + shift_left -= bitdiff + mask = (1 << c_a.size) - 1 + + mask <<= mask_pos + shift = shift_left - shift_right + ops[name] = (mask, shift, 0, c_a.size, c_b.size, mask_pos) + + # Collapse multiple components if possible. + common_shifts = {} + for name, (mask, shift, add, size_a, size_b, mask_pos) in ops.items(): + if not add and not (size_a != 8 and size_b == 8): + if shift in common_shifts: common_shifts[shift].append(name) + else: common_shifts[shift] = [name] + for newshift, colors in common_shifts.items(): + if len(colors) == 1: continue + newname = "" + newmask = 0 + colors.sort() + masks_pos = [] + for name in colors: + mask, shift, add, size_a, size_b, mask_pos = ops[name] + + names.remove(name) + newname += name + newmask |= mask + masks_pos.append(mask_pos) + names.append(newname) + ops[newname] = (newmask, newshift, 0, size_a, size_b, min(masks_pos)) + + # Write out a line for each remaining operation. + lines = [] + add_format = "0x%0" + str(info_b.size >> 2) + "x" + mask_format = "0x%0" + str(info_a.size >> 2) + "x" + for name in names: + if not name in ops: continue + mask, shift, add, size_a, size_b, mask_pos = ops[name] + if add: + line = "(" + (add_format % add) + ")" + lines.append((line, name, 0, size_a, size_b, mask_pos)) + continue + mask_string = "((x) & " + (mask_format % mask) + ")" + if (size_a != 8 and size_b == 8): + line = "(_al_rgb_scale_" + str(size_a) + "[" + mask_string + " >> %2d" % mask_pos + "]" + else: + if (shift > 0): + line = "(" + mask_string + " << %2d" % shift + ")" + elif (shift < 0): + line = "(" + mask_string + " >> %2d" % -shift + ")" + else: + line = mask_string + " " + lines.append((line, name, shift, size_a, size_b, mask_pos)) + + # Concoct the macro. + for i in range(len(lines)): + line, name, shift, size_a, size_b, mask_pos = lines[i] + if i == 0: start = " (" + else: start = " " + if i == len(lines) - 1: cont = ") " + else: cont = " | \\" + if size_a != 8 and size_b == 8: + shift = shift+(mask_pos-(8-size_a)) + if shift > 0: + backshift = " << %2d)" % shift + elif shift < 0: + backshift = " >> %2d)" % -shift + else: + backshift = " )" + else: + backshift = " " + r += start + line + backshift + " /* " + name + " */" + cont + "\n" + return r + + +def converter_macro(info_a, info_b): + """ + Create a conversion macro. + """ + if not info_a or not info_b: return None + + name = "ALLEGRO_CONVERT_" + info_a.name + "_TO_" + info_b.name + + r = "" + + if info_a.little_endian or info_b.little_endian: + r += "#ifdef ALLEGRO_BIG_ENDIAN\n" + r += "#define " + name + "(x) \\\n" + if info_a.name == "ABGR_8888_LE": + r += macro_lines(formats_by_name["RGBA_8888"], info_b) + elif info_b.name == "ABGR_8888_LE": + r += macro_lines(info_a, formats_by_name["RGBA_8888"]) + else: + r += "#error Conversion %s -> %s not understood by make_converters.py\n" % ( + info_a.name, info_b.name) + r += "#else\n" + r += "#define " + name + "(x) \\\n" + r += macro_lines(info_a, info_b) + r += "#endif\n" + else: + r += "#define " + name + "(x) \\\n" + r += macro_lines(info_a, info_b) + + return r + +def write_convert_h(filename): + """ + Create the file with all the conversion macros. + """ + f = open(filename, "w") + f.write("""\ +// Warning: This file was created by make_converters.py - do not edit. +#ifndef __al_included_allegro5_aintern_convert_h +#define __al_included_allegro5_aintern_convert_h + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_pixels.h" +""") + + for a in formats_list: + for b in formats_list: + if b == a: continue + macro = converter_macro(a, b) + if macro: + f.write(macro) + + f.write("""\ +#endif +// Warning: This file was created by make_converters.py - do not edit. +""") + +def converter_function(info_a, info_b): + """ + Create a string with one conversion function. + """ + name = info_a.name.lower() + "_to_" + info_b.name.lower() + params = "const void *src, int src_pitch,\n" + params += " void *dst, int dst_pitch,\n" + params += " int sx, int sy, int dx, int dy, int width, int height" + declaration = "static void " + name + "(" + params + ")" + + macro_name = "ALLEGRO_CONVERT_" + info_a.name + "_TO_" + info_b.name + + types_and_sizes = { + 8 : ("uint8_t", "", 1), + 15 : ("uint16_t", "", 2), + 16 : ("uint16_t", "", 2), + 24: ("uint8_t", " * 3", 1), + 32 : ("uint32_t", "", 4), + 128 : ("ALLEGRO_COLOR", "", 16)} + a_type, a_count, a_size = types_and_sizes[info_a.size] + b_type, b_count, b_size = types_and_sizes[info_b.size] + + if a_count == "" and b_count == "": + conversion = """\ + *dst_ptr = %(macro_name)s(*src_ptr); + dst_ptr++; + src_ptr++;""" % locals() + else: + + if a_count != "": + s_conversion = """\ + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif +""" % locals() + + if b_count != "": + d_conversion = """\ + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif +""" % locals() + + if a_count != "" and b_count != "": + conversion = s_conversion + ("""\ + int dst_pixel = %(macro_name)s(src_pixel); +""" % locals()) + d_conversion + + elif a_count != "": + conversion = s_conversion + ("""\ + *dst_ptr = %(macro_name)s(src_pixel); +""" % locals()) + + else: + conversion = ("""\ + int dst_pixel = %(macro_name)s(*src_ptr); +""" % locals()) + d_conversion + + conversion += """\ + src_ptr += 1%(a_count)s; + dst_ptr += 1%(b_count)s;""" % locals() + + r = declaration + "\n" + r += "{\n" + r += """\ + int y; + const %(a_type)s *src_ptr = (const %(a_type)s *)((const char *)src + sy * src_pitch); + %(b_type)s *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / %(a_size)d - width%(a_count)s; + int dst_gap = dst_pitch / %(b_size)d - width%(b_count)s; + src_ptr += sx%(a_count)s; + dst_ptr += dx%(b_count)s; + for (y = 0; y < height; y++) { + %(b_type)s *dst_end = dst_ptr + width%(b_count)s; + while (dst_ptr < dst_end) { +%(conversion)s + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +""" % locals() + + r += "}\n" + + return r + +def write_convert_c(filename): + """ + Write out the file with the conversion functions. + """ + f = open(filename, "w") + f.write("""\ +// Warning: This file was created by make_converters.py - do not edit. +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_convert.h" +""") + + for a in formats_list: + for b in formats_list: + if b == a: continue + if not a or not b: continue + function = converter_function(a, b) + f.write(function) + + f.write("""\ +void (*_al_convert_funcs[ALLEGRO_NUM_PIXEL_FORMATS] + [ALLEGRO_NUM_PIXEL_FORMATS])(const void *, int, void *, int, + int, int, int, int, int, int) = { +""") + for a in formats_list: + if not a: + f.write(" {NULL},\n") + else: + f.write(" {") + was_null = False + for b in formats_list: + if b and a != b: + name = a.name.lower() + "_to_" + b.name.lower() + f.write("\n " + name + ",") + was_null = False + else: + if not was_null: f.write("\n ") + f.write(" NULL,") + was_null = True + f.write("\n },\n") + + f.write("""\ +}; + +// Warning: This file was created by make_converters.py - do not edit. +""") + +def main(argv): + global options + p = optparse.OptionParser() + p.description = """\ +When run from the toplevel A5 folder, this will re-create the convert.h and +convert.c files containing all the low-level color conversion macros and +functions.""" + options, args = p.parse_args() + + # Read in color.h to get the available formats. + formats = read_color_h("include/allegro5/color.h") + + print(formats) + + # Parse the component info for each format. + for f in formats: + info = parse_format(f) + formats_by_name[f] = info + formats_list.append(info) + + # Output a macro for each possible conversion. + write_convert_h("include/allegro5/internal/aintern_convert.h") + + # Output a function for each possible conversion. + write_convert_c("src/convert.c") + +if __name__ == "__main__": + main(sys.argv) + +# vim: set sts=4 sw=4 et: diff --git a/allegro/misc/make_mixer_helpers.py b/allegro/misc/make_mixer_helpers.py new file mode 100644 index 00000000..3a823470 --- /dev/null +++ b/allegro/misc/make_mixer_helpers.py @@ -0,0 +1,306 @@ +#!/usr/bin/env python3 +# +# Run: +# misc/make_resamplers.py | indent -kr -i3 -l0 + +import sys, re + +# http://code.activestate.com/recipes/502257/ +def interp(string): + locals = sys._getframe(1).f_locals + globals = sys._getframe(1).f_globals + for item in re.findall(r'#\{([^}]*)\}', string): + string = string.replace('#{%s}' % item, str(eval(item, globals, locals))) + return string + + +class Depth: + def index(self, fmt): + if fmt == "f32": + return self.index_f32 + if fmt == "s16": + return self.index_s16 + +class Depth_f32(Depth): + def constant(self): + return "ALLEGRO_AUDIO_DEPTH_FLOAT32" + def index_f32(self, buf, index): + return interp("#{buf}.f32[ #{index} ]") + def index_s16(self, buf, index): + return interp("(int16_t) (#{buf}.f32[ #{index} ] * 0x7FFF)") + +class Depth_int24(Depth): + def constant(self): + return "ALLEGRO_AUDIO_DEPTH_INT24" + def index_f32(self, buf, index): + return interp("(float) #{buf}.s24[ #{index} ] / ((float)0x7FFFFF + 0.5f)") + def index_s16(self, buf, index): + return interp("(int16_t) (#{buf}.s24[ #{index} ] >> 9)") + +class Depth_uint24(Depth): + def constant(self): + return "ALLEGRO_AUDIO_DEPTH_UINT24" + def index_f32(self, buf, index): + return interp("(float) #{buf}.u24[ #{index} ] / ((float)0x7FFFFF + 0.5f) - 1.0f") + def index_s16(self, buf, index): + return interp("(int16_t) ((#{buf}.u24[ #{index} ] - 0x800000) >> 9)") + +class Depth_int16(Depth): + def constant(self): + return "ALLEGRO_AUDIO_DEPTH_INT16" + def index_f32(self, buf, index): + return interp("(float) #{buf}.s16[ #{index} ] / ((float)0x7FFF + 0.5f)") + def index_s16(self, buf, index): + return interp("#{buf}.s16[ #{index} ]") + +class Depth_uint16(Depth): + def constant(self): + return "ALLEGRO_AUDIO_DEPTH_UINT16" + def index_f32(self, buf, index): + return interp("(float) #{buf}.u16[ #{index} ] / ((float)0x7FFF + 0.5f) - 1.0f") + def index_s16(self, buf, index): + return interp("(int16_t) (#{buf}.u16[ #{index} ] - 0x8000)") + +class Depth_int8(Depth): + def constant(self): + return "ALLEGRO_AUDIO_DEPTH_INT8" + def index_f32(self, buf, index): + return interp("(float) #{buf}.s8[ #{index} ] / ((float)0x7F + 0.5f)") + def index_s16(self, buf, index): + return interp("(int16_t) #{buf}.s8[ #{index} ] << 7") + +class Depth_uint8(Depth): + def constant(self): + return "ALLEGRO_AUDIO_DEPTH_UINT8" + def index_f32(self, buf, index): + return interp("(float) #{buf}.u8[ #{index} ] / ((float)0x7F + 0.5f) - 1.0f") + def index_s16(self, buf, index): + return interp("(int16_t) (#{buf}.u8[ #{index} ] - 0x80) << 7") + +depths = [ + Depth_f32(), + Depth_int24(), + Depth_uint24(), + Depth_int16(), + Depth_uint16(), + Depth_int8(), + Depth_uint8() +] + +def make_point_interpolator(name, fmt): + print(interp("""\ + static INLINE const void * + #{name} + (SAMP_BUF *samp_buf, + const ALLEGRO_SAMPLE_INSTANCE *spl, + unsigned int maxc) + { + unsigned int i0 = spl->pos*maxc; + unsigned int i; + + switch (spl->spl_data.depth) { + """)) + + for depth in depths: + buf_index = depth.index(fmt)("spl->spl_data.buffer", "i0 + i") + print(interp("""\ + case #{depth.constant()}: + for (i = 0; i < maxc; i++) { + samp_buf-> #{fmt} [i] = #{buf_index}; + } + break; + """)) + + print(interp("""\ + } + return samp_buf-> #{fmt} ; + }""")) + +def make_linear_interpolator(name, fmt): + assert fmt == "f32" or fmt == "s16" + + print(interp("""\ + static INLINE const void * + #{name} + (SAMP_BUF *samp_buf, + const ALLEGRO_SAMPLE_INSTANCE *spl, + unsigned int maxc) + { + int p0 = spl->pos; + int p1 = spl->pos+1; + + switch (spl->loop) { + case ALLEGRO_PLAYMODE_ONCE: + if (p1 >= spl->spl_data.len) + p1 = p0; + break; + case ALLEGRO_PLAYMODE_LOOP: + if (p1 >= spl->loop_end) + p1 = spl->loop_start; + break; + case ALLEGRO_PLAYMODE_BIDIR: + if (p1 >= spl->loop_end) { + p1 = spl->loop_end - 1; + if (p1 < spl->loop_start) + p1 = spl->loop_start; + } + break; + case _ALLEGRO_PLAYMODE_STREAM_ONCE: + case _ALLEGRO_PLAYMODE_STREAM_ONEDIR:""" + + # For audio streams, sample i+1 may be in the next buffer fragment, + # which may not even be generated yet. So we lag by one sample and + # interpolate between sample i-1 and sample i. + # + # We arrange the buffers in memory such that indexing i-1 is always + # valid, even after wrapping around from the last buffer fragment to + # the first buffer fragment. See _al_kcm_refill_stream. + """ + p0--; + p1--; + break; + } + + p0 *= maxc; + p1 *= maxc; + + switch (spl->spl_data.depth) { + """)) + + for depth in depths: + x0 = depth.index(fmt)("spl->spl_data.buffer", "p0 + i") + x1 = depth.index(fmt)("spl->spl_data.buffer", "p1 + i") + print(interp("""\ + case #{depth.constant()}: + {""")) + + if fmt == "f32": + print(interp("""\ + const float t = (float)spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int)maxc; i++) { + const float x0 = #{x0}; + const float x1 = #{x1}; + const float s = (x0 * (1.0f - t)) + (x1 * t); + samp_buf->f32[i] = s; + }""")) + elif fmt == "s16": + print(interp("""\ + const int32_t t = 256 * spl->pos_bresenham_error / spl->step_denom; + int i; + for (i = 0; i < (int)maxc; i++) { + const int32_t x0 = #{x0}; + const int32_t x1 = #{x1}; + const int32_t s = ((x0 * (256 - t))>>8) + ((x1 * t)>>8); + samp_buf->s16[i] = (int16_t)s; + }""")) + + print(interp("""\ + } + break; + """)) + + print(interp("""\ + } + return samp_buf-> #{fmt}; + }""")) + +def make_cubic_interpolator(name, fmt): + assert fmt == "f32" + + print(interp("""\ + static INLINE const void * + #{name} + (SAMP_BUF *samp_buf, + const ALLEGRO_SAMPLE_INSTANCE *spl, + unsigned int maxc) + { + int p0 = spl->pos-1; + int p1 = spl->pos; + int p2 = spl->pos+1; + int p3 = spl->pos+2; + + switch (spl->loop) { + case ALLEGRO_PLAYMODE_ONCE: + if (p0 < 0) + p0 = 0; + if (p2 >= spl->spl_data.len) + p2 = spl->spl_data.len - 1; + if (p3 >= spl->spl_data.len) + p3 = spl->spl_data.len - 1; + break; + case ALLEGRO_PLAYMODE_LOOP: + case ALLEGRO_PLAYMODE_BIDIR: + /* These positions should really wrap/bounce instead of clamping + * but it's probably unnoticeable. + */ + if (p0 < spl->loop_start) + p0 = spl->loop_end - 1; + if (p2 >= spl->loop_end) + p2 = spl->loop_start; + if (p3 >= spl->loop_end) + p3 = spl->loop_start; + break; + case _ALLEGRO_PLAYMODE_STREAM_ONCE: + case _ALLEGRO_PLAYMODE_STREAM_ONEDIR: + /* Lag by three samples in total. */ + p0 -= 2; + p1 -= 2; + p2 -= 2; + p3 -= 2; + break; + } + + p0 *= maxc; + p1 *= maxc; + p2 *= maxc; + p3 *= maxc; + + switch (spl->spl_data.depth) { + """)) + + for depth in depths: + value0 = depth.index(fmt)("spl->spl_data.buffer", "p0 + i") + value1 = depth.index(fmt)("spl->spl_data.buffer", "p1 + i") + value2 = depth.index(fmt)("spl->spl_data.buffer", "p2 + i") + value3 = depth.index(fmt)("spl->spl_data.buffer", "p3 + i") + # 4-point, cubic Hermite interpolation + # Code transcribed from "Polynomial Interpolators for High-Quality + # Resampling of Oversampled Audio" by Olli Niemitalo + # http://yehar.com/blog/?p=197 + print(interp("""\ + case #{depth.constant()}: + { + const float t = (float)spl->pos_bresenham_error / spl->step_denom; + signed int i; + for (i = 0; i < (signed int)maxc; i++) { + float x0 = #{value0}; + float x1 = #{value1}; + float x2 = #{value2}; + float x3 = #{value3}; + float c0 = x1; + float c1 = 0.5f * (x2 - x0); + float c2 = x0 - (2.5f * x1) + (2.0f * x2) - (0.5f * x3); + float c3 = (0.5f * (x3 - x0)) + (1.5f * (x1 - x2)); + float s = (((((c3 * t) + c2) * t) + c1) * t) + c0; + samp_buf->f32[i] = s; + } + } + break; + """)) + + print(interp("""\ + } + return samp_buf-> #{fmt} ; + }""")) + +if __name__ == "__main__": + print("// Warning: This file was created by make_resamplers.py - do not edit.") + print("// vim: set ft=c:") + + make_point_interpolator("point_spl32", "f32") + make_point_interpolator("point_spl16", "s16") + make_linear_interpolator("linear_spl32", "f32") + make_linear_interpolator("linear_spl16", "s16") + make_cubic_interpolator("cubic_spl32", "f32") + +# vim: set sts=3 sw=3 et: diff --git a/allegro/misc/make_pixel_tables.py b/allegro/misc/make_pixel_tables.py new file mode 100644 index 00000000..40eb1567 --- /dev/null +++ b/allegro/misc/make_pixel_tables.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +import optparse, sys + +def main(argv): + p = optparse.OptionParser() + p.description = ("When run from the toplevel A5 folder, this will " + "re-create the src/pixel_tables.inc.""") + p.parse_args() + + with open("src/pixel_tables.inc", "w") as f: + f.write("""// Warning: This file was created by make_pixel_tables.py - do not edit. + +"""); + + f.write("float _al_u8_to_float[] = {\n") + for i in range(256): + f.write(f" {i / 255.0},\n") + f.write("};\n\n") + + f.write("int _al_rgb_scale_1[] = {\n") + for i in range(2): + f.write(f" {i * 255 // 1},\n") + f.write("};\n\n") + + f.write("int _al_rgb_scale_4[] = {\n") + for i in range(16): + f.write(f" {i * 255 // 15},\n") + f.write("};\n\n") + + f.write("int _al_rgb_scale_5[] = {\n") + for i in range(32): + f.write(f" {i * 255 // 31},\n") + f.write("};\n\n") + + f.write("int _al_rgb_scale_6[] = {\n") + for i in range(64): + f.write(f" {i * 255 // 63},\n") + f.write("};\n\n") + + f.write("""// Warning: This file was created by make_pixel_tables.py - do not edit. +"""); + +if __name__ == "__main__": + main(sys.argv) diff --git a/allegro/misc/make_scanline_drawers.py b/allegro/misc/make_scanline_drawers.py new file mode 100644 index 00000000..ec47f1e8 --- /dev/null +++ b/allegro/misc/make_scanline_drawers.py @@ -0,0 +1,500 @@ +#!/usr/bin/env python3 +# +# Generate the routines to draw each scanline of a primitive. +# Run: +# misc/make_scanline_drawers.py | indent -kr -i3 -l0 > src/scanline_drawers.inc + +import sys, re + +# http://code.activestate.com/recipes/502257/ +def interp(string): + locals = sys._getframe(1).f_locals + globals = sys._getframe(1).f_globals + for item in re.findall(r'#\{([^}]*)\}', string): + string = string.replace('#{%s}' % item, str(eval(item, globals, locals))) + return string + +def make_drawer(name): + global texture, grad, solid, shade, opaque, white + texture = "_texture_" in name + grad = "_grad_" in name + solid = "_solid_" in name + shade = "_shade" in name + opaque = "_opaque" in name + white = "_white" in name + + if grad and solid: + raise Exception("grad and solid") + if grad and white: + raise Exception("grad and white") + if shade and opaque: + raise Exception("shade and opaque") + + print(interp("static void #{name} (uintptr_t state, int x1, int y, int x2) {")) + + if not texture: + if grad: + print("""\ + state_grad_any_2d *gs = (state_grad_any_2d *)state; + state_solid_any_2d *s = &gs->solid; + ALLEGRO_COLOR cur_color = s->cur_color; + """) + else: + print("""\ + state_solid_any_2d *s = (state_solid_any_2d *)state; + ALLEGRO_COLOR cur_color = s->cur_color; + """) + else: + if grad: + print("""\ + state_texture_grad_any_2d *gs = (state_texture_grad_any_2d *)state; + state_texture_solid_any_2d *s = &gs->solid; + ALLEGRO_COLOR cur_color = s->cur_color; + """) + else: + print("""\ + state_texture_solid_any_2d *s = (state_texture_solid_any_2d *)state; + """) + print("""\ + float u = s->u; + float v = s->v; + """) + + # XXX still don't understand why y-1 is required + print("""\ + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + """) + if texture: + print("""\ + u += s->du_dx * -x1; + v += s->dv_dx * -x1; + """) + + if grad: + print("""\ + cur_color.r += gs->color_dx.r * -x1; + cur_color.g += gs->color_dx.g * -x1; + cur_color.b += gs->color_dx.b * -x1; + cur_color.a += gs->color_dx.a * -x1; + """) + + print("""\ + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + """) + + print("{") + if shade: + print("""\ + int op, src_mode, dst_mode; + int op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR const_color; + al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, + &op_alpha, &src_alpha, &dst_alpha); + const_color = al_get_blend_color(); + """) + + print("{") + if texture: + print("""\ + const int offset_x = s->texture->parent ? s->texture->xofs : 0; + const int offset_y = s->texture->parent ? s->texture->yofs : 0; + ALLEGRO_BITMAP* texture = s->texture->parent ? s->texture->parent : s->texture; + const int src_format = texture->locked_region.format; + const int src_size = texture->locked_region.pixel_size; + + /* Ensure u in [0, s->w) and v in [0, s->h). */ + while (u < 0) u += s->w; + while (v < 0) v += s->h; + u = fmodf(u, s->w); + v = fmodf(v, s->h); + ASSERT(0 <= u); ASSERT(u < s->w); + ASSERT(0 <= v); ASSERT(v < s->h); + """) + + print("{") + print("""\ + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *)target->lock_data + + y * target->locked_region.pitch + + x1 * target->locked_region.pixel_size; + """) + + if shade: + make_if_blender_loop( + op='ALLEGRO_ADD', + src_mode='ALLEGRO_ONE', + src_alpha='ALLEGRO_ONE', + op_alpha='ALLEGRO_ADD', + dst_mode='ALLEGRO_INVERSE_ALPHA', + dst_alpha='ALLEGRO_INVERSE_ALPHA', + const_color='NULL', + if_format='ALLEGRO_PIXEL_FORMAT_ARGB_8888', + alpha_only=True + ) + print("else") + make_if_blender_loop( + op='ALLEGRO_ADD', + src_mode='ALLEGRO_ALPHA', + src_alpha='ALLEGRO_ALPHA', + op_alpha='ALLEGRO_ADD', + dst_mode='ALLEGRO_INVERSE_ALPHA', + dst_alpha='ALLEGRO_INVERSE_ALPHA', + const_color='NULL', + if_format='ALLEGRO_PIXEL_FORMAT_ARGB_8888', + alpha_only=True + ) + print("else") + make_if_blender_loop( + op='ALLEGRO_ADD', + src_mode='ALLEGRO_ONE', + src_alpha='ALLEGRO_ONE', + op_alpha='ALLEGRO_ADD', + dst_mode='ALLEGRO_ONE', + dst_alpha='ALLEGRO_ONE', + const_color='NULL', + if_format='ALLEGRO_PIXEL_FORMAT_ARGB_8888', + alpha_only=True + ) + print("else") + + if opaque and white: + make_loop(copy_format=True, src_size='4') + print("else") + make_loop(copy_format=True, src_size='3') + print("else") + make_loop(copy_format=True, src_size='2') + print("else") + else: + make_loop( + if_format='ALLEGRO_PIXEL_FORMAT_ARGB_8888' + ) + print("else") + + make_loop() + + print("""\ + } + } + } + } + """) + +def make_if_blender_loop( + op='op', + src_mode='src_mode', + dst_mode='dst_mode', + op_alpha='op_alpha', + src_alpha='src_alpha', + dst_alpha='dst_alpha', + src_format='src_format', + dst_format='dst_format', + const_color='NULL', + if_format=None, + alpha_only=False + ): + print(interp("""\ + if (op == #{op} && + src_mode == #{src_mode} && + src_alpha == #{src_alpha} && + op_alpha == #{op_alpha} && + dst_mode == #{dst_mode} && + dst_alpha == #{dst_alpha}) { + """)) + + if texture and if_format: + make_loop( + op=op, + src_mode=src_mode, + src_alpha=src_alpha, + op_alpha=op_alpha, + dst_mode=dst_mode, + dst_alpha=dst_alpha, + const_color=const_color, + if_format=if_format, + alpha_only=alpha_only + ) + print("else") + + make_loop( + op=op, + src_mode=src_mode, + src_alpha=src_alpha, + op_alpha=op_alpha, + dst_mode=dst_mode, + dst_alpha=dst_alpha, + const_color=const_color, + alpha_only=alpha_only) + + print("}") + +def make_loop( + op='op', + src_mode='src_mode', + dst_mode='dst_mode', + op_alpha='op_alpha', + src_alpha='src_alpha', + dst_alpha='dst_alpha', + src_format='src_format', + dst_format='dst_format', + src_size='src_size', + const_color='&const_color', + if_format=None, + copy_format=False, + alpha_only=False + ): + + if if_format: + src_format = if_format + dst_format = if_format + print(interp("if (dst_format == #{dst_format}")) + if texture: + print(interp("&& src_format == #{src_format}")) + print(")") + elif copy_format: + assert opaque and white + print(interp("if (dst_format == src_format && src_size == #{src_size})")) + + print("{") + + if texture: + print("""\ + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + """) + + if opaque: + # If texture coordinates never wrap around then we can simplify the + # innermost loop. It doesn't seem to have so great an impact when the + # loop is complicated by blending. + print("""\ + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + """) + make_innermost_loop( + op=op, + src_mode=src_mode, + dst_mode=dst_mode, + op_alpha=op_alpha, + src_alpha=src_alpha, + dst_alpha=dst_alpha, + src_format=src_format, + dst_format=dst_format, + const_color=const_color, + src_size=src_size, + copy_format=copy_format, + tiling=False, + alpha_only=alpha_only + ) + print("} else") + + make_innermost_loop( + op=op, + src_mode=src_mode, + dst_mode=dst_mode, + op_alpha=op_alpha, + src_alpha=src_alpha, + dst_alpha=dst_alpha, + src_format=src_format, + dst_format=dst_format, + const_color=const_color, + src_size=src_size, + copy_format=copy_format, + alpha_only=alpha_only + ) + + print("}") + +def make_innermost_loop( + op='op', + src_mode='src_mode', + dst_mode='dst_mode', + op_alpha='op_alpha', + src_alpha='src_alpha', + dst_alpha='dst_alpha', + src_format='src_format', + dst_format='dst_format', + const_color='&const_color', + src_size='src_size', + copy_format=False, + tiling=True, + alpha_only=True + ): + + print("{") + + if texture: + # In non-tiling mode we can hoist offsets out of the loop. + if tiling: + print("""\ + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + """) + uu_ofs = "uu_ofs" + vv_ofs = "vv_ofs" + else: + print("""\ + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + """) + uu_ofs = vv_ofs = "0" + + print("for (; x1 <= x2; x1++) {") + + if not texture: + print("""\ + ALLEGRO_COLOR src_color = cur_color; + """) + else: + print(interp("""\ + const int src_x = (uu >> 16) + #{uu_ofs}; + const int src_y = (vv >> 16) + #{vv_ofs}; + uint8_t *src_data = lock_data + + src_y * src_pitch + + src_x * #{src_size}; + """)) + + if copy_format: + pass + else: + print(interp("""\ + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(#{src_format}, src_data, src_color, false); + """)) + if grad: + print("""\ + SHADE_COLORS(src_color, cur_color); + """) + elif not white: + print("""\ + SHADE_COLORS(src_color, s->cur_color); + """) + + if copy_format: + print(interp("""\ + switch (#{src_size}) { + case 4: + memcpy(dst_data, src_data, 4); + dst_data += 4; + break; + case 3: + memcpy(dst_data, src_data, 3); + dst_data += 3; + break; + case 2: + *dst_data++ = *src_data++; + *dst_data++ = *src_data; + break; + case 1: + *dst_data++ = *src_data; + break; + } + """)) + elif shade: + blend = "_al_blend_inline" + if alpha_only: + blend = "_al_blend_alpha_inline" + print(interp("""\ + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(#{dst_format}, dst_data, dst_color, false); + #{blend}(&src_color, &dst_color, + #{op}, #{src_mode}, #{dst_mode}, + #{op_alpha}, #{src_alpha}, #{dst_alpha}, + #{const_color}, &result); + _AL_INLINE_PUT_PIXEL(#{dst_format}, dst_data, result, true); + } + """)) + else: + print(interp("""\ + _AL_INLINE_PUT_PIXEL(#{dst_format}, dst_data, src_color, true); + """)) + + if texture: + print("""\ + uu += du_dx; + vv += dv_dx; + """) + + if tiling: + print("""\ + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + """) + + if grad: + print("""\ + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + """) + + print("""\ + } + }""") + +if __name__ == "__main__": + print("""\ +// Warning: This file was created by make_scanline_drawers.py - do not edit. + +#if __GNUC__ +#define _AL_EXPECT_FAIL(expr) __builtin_expect((expr), 0) +#else +#define _AL_EXPECT_FAIL(expr) (expr) +#endif +""") + + make_drawer("shader_solid_any_draw_shade") + make_drawer("shader_solid_any_draw_opaque") + + make_drawer("shader_grad_any_draw_shade") + make_drawer("shader_grad_any_draw_opaque") + + make_drawer("shader_texture_solid_any_draw_shade") + make_drawer("shader_texture_solid_any_draw_shade_white") + make_drawer("shader_texture_solid_any_draw_opaque") + make_drawer("shader_texture_solid_any_draw_opaque_white") + + make_drawer("shader_texture_grad_any_draw_shade") + make_drawer("shader_texture_grad_any_draw_opaque") + +# vim: set sts=3 sw=3 et: diff --git a/allegro/misc/mkunixdists.sh b/allegro/misc/mkunixdists.sh new file mode 100644 index 00000000..e8975b19 --- /dev/null +++ b/allegro/misc/mkunixdists.sh @@ -0,0 +1,158 @@ +#!/bin/sh + +################################################################ +# mkunixdists.sh -- shell script to generate Unix distributions +# +# Usage: mkunixdists.sh [.zip] [tmpdir] +# +# This generates all the Unix-specific distributions. The +# existing ZIP format is fine on Unix too, but we'll generate +# here a .tar.gz in Unix format (no `fix.sh unix' necessary) and +# also an end-user distribution which just creates and installs +# the library, without examples, documentation, etc. I suppose +# there's a danger that people will download this as a cut-down +# development version, but if we shoot those people then this +# problem will be solved. This script might need a lot of disk +# space, but no more than the existing zipup.sh needs. :) + + + +################################################################ +# First process the arguments + +if [ $# -lt 1 -o $# -gt 2 ]; then + echo "Usage: mkunixdists.sh [.zip] [tmpdir]" + exit 1 +fi + +# Sort out `dir', adding a trailing `/' if necessary +if [ $# -gt 1 ]; then + dir=$(echo "$2" | sed -e 's/\([^/]\)$/\0\//').tmp +else + dir=.tmp +fi + + + +################################################################ +# Error reporter + +error() { + echo "Error occured, aborting" ; rm -rf $dir ; exit 1 +} + + +################################################################ +# Unzip the archive and convert line endings + +mkdir $dir || error + +echo "Unzipping $1 to $dir" + unzip -qq $1 -d $dir || error +echo "Running 'convert_line_endings.sh --dtou'" + (cd $dir/allegro && + rm -f makefile && + sh misc/convert_line_endings.sh --dtou >/dev/null + ) || error +echo "Checking version number" + # Derive version number from the archive name, as the number in + # CMakeLists.txt won't reflect the fourth version digit. + version=$( echo $1 | sed -e 's/^allegro-// ; s/\.zip$//' ) + test -n "$version" || error + basename="allegro-$version" + basename2="allegro-enduser-$version" +echo "Renaming 'allegro' to '$basename'" + mv $dir/allegro $dir/$basename || error + +################################################################ +# Make .tar.gz distributions + +mktargz() { + echo "Creating $1.tar" + (cd $dir && tar -cf - $basename) > $1.tar || error + echo "gzipping to $1.tar.gz" + gzip $1.tar || error +} + +# Create the developers' archive +mktargz $basename + +# Hack'n'slash +# XXX end-user distribution is useless while we are in WIP mode +# This code is outdated anyway. +if false +then + echo "Stripping to form end-user distribution" + (cd $dir/$basename && { + (cd src && rm -rf beos qnx dos mac ppc win) + (cd obj && rm -rf bcc32 beos qnx djgpp mingw32 msvc watcom) + (cd lib && rm -rf bcc32 beos qnx djgpp mingw32 msvc watcom) + (cd include && rm -f bealleg.h qnxalleg.h winalleg.h) + (cd misc && rm -f cmplog.pl dllsyms.lst findtext.sh fixpatch.sh fixver.sh) + (cd misc && rm -f allegro-config-qnx.sh zipup.sh zipwin.sh *.bat *.c) + mkdir .saveme + cp readme.txt docs/build/unix.txt docs/build/linux.txt .saveme + rm -rf demo docs examples resource setup tests tools + rm -f AUTHORS CHANGES THANKS *.txt fix* indent* readme.* allegro.mft + rm -f makefile.all makefile.be makefile.qnx makefile.bcc makefile.dj + rm -f makefile.mgw makefile.mpw makefile.vc makefile.wat makefile.tst + rm -f xmake.sh + rm -f keyboard.dat language.dat + mv .saveme/* . + rmdir .saveme + { # Tweak makefile.in + cp makefile.in makefile.old && + cat makefile.old | + sed -e "s/INSTALL_TARGETS = .*/INSTALL_TARGETS = mini-install/" | + sed -e "s/DEFAULT_TARGETS = .*/DEFAULT_TARGETS = lib modules/" | + cat > makefile.in && + rm -f makefile.old + } + }) + + # Create the end users' archive + mktargz $basename2 +fi # false + + +################################################################ +# Create SRPM distribution +# +# We don't actually create the binary RPMs here, since that +# will really need to be done on many different machines. +# Instead we'll build the source RPM. +# +# This requires you to have Red Hat's default RPM build system +# properly set up, so we'll skip it if that's not the case. + +# XXX SRPMs disabled because they must be broken by now +# Also, they are useless. +if false +then + rpmdir= + [ -d /usr/src/redhat ] && rpmdir=/usr/src/redhat + [ -d /usr/src/packages ] && rpmdir=/usr/src/packages + [ -d /usr/src/RPM ] && rpmdir=/usr/src/RPM + [ -d /usr/src/rpm ] && rpmdir=/usr/src/rpm + + if [ -n "$rpmdir" ]; then + echo "Creating SRPM" + echo "Enter your root password if prompted" + su -c "(\ + cp -f $basename.tar.gz $rpmdir/SOURCES ;\ + cp -f $dir/$basename/misc/icon.xpm $rpmdir/SOURCES ;\ + rpm -bs $dir/$basename/misc/allegro.spec ;\ + mv -f $rpmdir/SRPMS/allegro-*.rpm . ;\ + rm -f $rpmdir/SOURCES/icon.xpm ;\ + rm -f $rpmdir/SOURCES/$basename.tar.gz ;\ + )" + fi +fi # false + + +################################################################ +# All done! + +rm -rf $dir +echo "All done!" + diff --git a/allegro/misc/msvchelp.c b/allegro/misc/msvchelp.c new file mode 100644 index 00000000..165b9934 --- /dev/null +++ b/allegro/misc/msvchelp.c @@ -0,0 +1,53 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + + +#define MAKEFILE_HELPER_FILENAME "makefile.helper" + + +int main(int argc, char *argv[]) +{ + char shortfilename[MAX_PATH]; + char *longfilename; + int ret; + FILE *fout; + + if (argc != 2) { + fprintf(stderr, "msvchelp: No argument given!\n"); + return 1; + } + + longfilename = getenv(argv[1]); + if (longfilename == NULL) { + fprintf(stderr, "msvchelp: Given argument does not correspond to any enviroment variable name!\n"); + return 2; + } + + ret = GetShortPathName(longfilename, shortfilename, MAX_PATH); + if (ret == 0 || ret > MAX_PATH) { + fprintf(stderr, "msvchelp: Cannot convert to short name!\n"); + return 3; + } + + fout = fopen(MAKEFILE_HELPER_FILENAME, "wt"); + if (fout == NULL) { + fprintf(stderr, "msvchelp: Cannot create output file '%s'!\n", MAKEFILE_HELPER_FILENAME); + return 4; + } + + ret = fprintf(fout, "%s = %s\n", argv[1], shortfilename); + if (ret < 0) { + fprintf(stderr, "msvchelp: Cannot write to the output file '%s'!\n", MAKEFILE_HELPER_FILENAME); + return 5; + } + + ret = fclose(fout); + if (ret != 0) { + fprintf(stderr, "msvchelp: Cannot close the output file '%s'!\n", MAKEFILE_HELPER_FILENAME); + return 6; + } + + return EXIT_SUCCESS; +} diff --git a/allegro/misc/regenerate.sh b/allegro/misc/regenerate.sh new file mode 100644 index 00000000..7228adeb --- /dev/null +++ b/allegro/misc/regenerate.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# Recreate the automatically generated source files in the tree. + +set -e +set -x + +misc/make_scanline_drawers.py | \ + indent -kr -i3 -l0 > src/scanline_drawers.inc + +misc/make_converters.py + +misc/gl_mkalias.sh + +misc/make_mixer_helpers.py | \ + indent -kr -i3 -l0 > addons/audio/kcm_mixer_helpers.inc + +# vim: set sts=3 sw=3 et: diff --git a/allegro/misc/utod.sh b/allegro/misc/utod.sh new file mode 100644 index 00000000..3a1e7e92 --- /dev/null +++ b/allegro/misc/utod.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# Convert LF line endings to CR/LF line endings, preserving timestamps and +# permissions on the file. +# + +with_unix_tools() { + for file in "$@" + do + echo "$file" + + tmpfile=`dirname "$file"`/__dtou_tmp.$RANDOM || exit 1 + trap 'rm -f "$tmpfile"' 1 2 3 13 15 + + # We go through a slightly convoluted sequence of commands in order to + # preserve both the timestamp and permissions on the file. + { + perl -p -e "s/([^\r]|^)\n/\1\r\n/" "$file" > "$tmpfile" && + touch -r "$file" "$tmpfile" && + cat "$tmpfile" > "$file" && + touch -r "$tmpfile" "$file" && + rm -f "$tmpfile" + } || exit 1 + done +} + +with_cygwin() { + for file in "$@" + do + unix2dos $file || exit 1 + done +} + +if test -z "$1" +then + echo "$0 filename" + exit +fi + +if test "$ALLEGRO_USE_CYGWIN" = "1" +then + with_cygwin "$@" +else + with_unix_tools "$@" +fi + +# vi: sts=3 sw=3 et diff --git a/allegro/misc/vcvars.c b/allegro/misc/vcvars.c new file mode 100644 index 00000000..073ac65d --- /dev/null +++ b/allegro/misc/vcvars.c @@ -0,0 +1,147 @@ +/* + * VCVARS - sets up a command prompt with suitable options for using MSVC. + * + * This program tries to locate the vcvars32.bat file, first by looking in + * the registry, and then if that fails, by asking the user. It then sets + * the environment variable VCVARS to the full path of this file. + * + * If it was given a commandline argument, it then runs that program, + * or otherwise it opens up a new command prompt. In either case it will + * adjust the environment size to make sure there is enough space for + * setting the compiler variables. + */ + + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include + + + +/* try to read a value from the registry */ +int read_registry(char *path, char *var, char *val, int size) +{ + HKEY key; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &key) != ERROR_SUCCESS) + return 0; + + if (RegQueryValueEx(key, var, NULL, NULL, val, &size) != ERROR_SUCCESS) { + RegCloseKey(key); + return 0; + } + + RegCloseKey(key); + return 1; +} + + + +/* locate vcvars32.bat */ +void find_vcvars() +{ + char data[256], name[256]; + int i; + + /* look in the registry (try VC versions 4 through 9, just in case :-) */ + for (i=9; i>=4; i--) { + sprintf(name, "Software\\Microsoft\\DevStudio\\%d.0\\Products\\Microsoft Visual C++", i); + + if (read_registry(name, "ProductDir", data, sizeof(data))) { + strcat(data, "\\bin\\vcvars32.bat"); + + if (access(data, 4) == 0) { + printf("Found %s\n", data); + break; + } + } + + data[0] = 0; + } + + /* oh dear, have to ask the user where they put it */ + if (!data[0]) { + printf("\n Unable to find MSVC ProductDir information in your registry!\n\n"); + printf(" To install Allegro, I need to know the path where your compiler is\n"); + printf(" installed. Somewhere in your MSVC installation directory there will\n"); + printf(" be a file called vcvars32.bat, which contains this information.\n"); + printf(" Please enter the full path to where I can find that file, for example\n"); + printf(" c:\\Program Files\\Microsoft Visual Studio\\VC98\\bin\\vcvars32.bat\n"); + + for (;;) { + printf("\n> "); + fflush(stdout); + + if (gets(data)) { + i = strlen(data) - 12; + if (i < 0) + i = 0; + + if (stricmp(data+i, "vcvars32.bat") != 0) + printf("\nError: that path doesn't end in vcvars32.bat!\n"); + else if (access(data, 4) != 0) + printf("\nError: can't find a vcvars32.bat file there!\n"); + else { + printf("\nUsing %s\n", data); + break; + } + } + + data[0] = 0; + } + } + + /* put it in the environment */ + strcpy(name, "VCVARS="); + strcat(name, data); + + putenv(name); +} + + + +/* the main program */ +int main(int argc, char *argv[]) +{ + char cmd[256]; + int i; + + find_vcvars(); + + if ((getenv("OS")) && (stricmp(getenv("OS"), "Windows_NT") == 0)) { + if (argc > 1) { + /* run program using cmd.exe */ + strcpy(cmd, "cmd.exe /e:8192 /c"); + } + else { + /* TSR using cmd.exe */ + sprintf(cmd, "cmd.exe /e:8192 /k \"%s\"", getenv("VCVARS")); + } + } + else { + if (argc > 1) { + /* run program using command.com */ + strcpy(cmd, "command.com /e:8192 /c"); + } + else { + /* TSR using command.com */ + sprintf(cmd, "command.com /e:8192 /k \"%s\"", getenv("VCVARS")); + } + } + + /* what program do we want to invoke? */ + for (i=1; i&2 + exit 1 +fi + +if [ -n "$2" ] && [ ! -r ../"$2" ]; then + echo "Previous archive $2 not in parent directory, aborting" + exit 1 +fi + + + +# strip off the path and extension from our arguments +name=$(echo "$1" | sed -e 's/.*[\\\/]//; s/\.zip//') +prev=$(echo "$2" | sed -e 's/.*[\\\/]//; s/\.zip//') + +# make a datestamped archive if specified +if test $name = datestamp; then + date=`date '+%Y%m%d'` + name=allegro_$date +fi + +# make sure all the makefiles are in Unix text format +# for file in makefile.*; do +# mv $file _tmpfile +# tr -d \\\r < _tmpfile > $file +# touch -r _tmpfile $file +# rm _tmpfile +# done + + +# delete all generated files +# echo "Cleaning the Allegro tree..." +# +# sed -n -e "/CLEAN_FILES/,/^$/p; /^ALLEGRO_.*_EXES/,/^$/p" makefile.lst | \ +# sed -e "/CLEAN_FILES/d; /ALLEGRO_.*_EXES/d; s/\\\\//g" | \ +# xargs -n 1 echo | \ +# sed -e "s/\(.*\)/-c \"rm -f \1\"/" | \ +# xargs -l sh +# +# find . -name '*~' -exec rm -f {} \; + + +# emulation of the djgpp utod utility program (Unix to DOS text format) +utod() +{ + for file in $*; do + if echo $file | grep "^\.\.\./" >/dev/null; then + # files like .../*.c recurse into directories (emulating djgpp libc) + spec=$(echo $file | sed -e "s/^\.\.\.\///") + find . -type f -name "$spec" -exec perl -p -i -e 's/([^\r]|^)\n/\1\r\n/' {} \; + else + perl -p -e "s/([^\r]|^)\n/\1\r\n/" $file > _tmpfile + touch -r $file _tmpfile + mv _tmpfile $file + fi + done +} + + +# generate dependencies for DJGPP +# echo "Generating DJGPP dependencies..." +# +# ./fix.sh djgpp --quick +# +# make depend UNIX_TOOLS=1 CC=gcc + + +# generate dependencies for Watcom +# echo "Generating Watcom dependencies..." +# +# ./fix.sh watcom --quick +# +# make depend UNIX_TOOLS=1 CC=gcc + + +# generate dependencies for MSVC +# echo "Generating MSVC dependencies..." +# +# ./fix.sh msvc --quick +# +# make depend UNIX_TOOLS=1 CC=gcc + + +# generate dependencies for MinGW +# echo "Generating MinGW dependencies..." +# +# ./fix.sh mingw --quick +# +# make depend UNIX_TOOLS=1 CC=gcc + + +# generate dependencies for Borland C++ +# echo "Generating BCC32 dependencies..." +# +# ./fix.sh bcc32 --quick +# +# make depend UNIX_TOOLS=1 CC=gcc + + +# generate dependencies for BeOS +# echo "Generating BeOS dependencies..." +# +# ./fix.sh beos --quick +# +# make depend UNIX_TOOLS=1 CC=gcc + + +# generate dependencies for QNX +# echo "Generating QNX dependencies..." +# +# ./fix.sh qnx --quick +# +# make depend UNIX_TOOLS=1 CC=gcc + + +# generate dependencies for MacOS X +# echo "Generating MacOS X dependencies..." +# +# ./fix.sh macosx --quick +# +# make depend UNIX_TOOLS=1 CC=gcc + + +# generate the DLL export definition files for Windows compilers +# misc/fixdll.sh + +# running autoconf +# echo "Running autoconf to generate configure script..." +# autoconf || exit 1 + +# touch stamp-h.in so the user doesn't need autoheader to compile +# touch stamp-h.in + + +# convert documentation from the ._tx source files +# echo "Converting documentation..." +# +# gcc -o _makedoc.exe docs/src/makedoc/*.c +# +# ./_makedoc.exe -ascii readme.txt docs/src/readme._tx +# ./_makedoc.exe -ascii CHANGES docs/src/changes._tx +# ./_makedoc.exe -part -ascii AUTHORS docs/src/thanks._tx +# ./_makedoc.exe -part -ascii THANKS docs/src/thanks._tx +# for base in abi ahack allegro const faq help mistakes; do +# ./_makedoc.exe -ascii docs/txt/$base.txt docs/src/$base._tx +# done +# for base in bcc32 beos darwin djgpp linux macosx mingw32 msvc qnx unix watcom; do +# ./_makedoc.exe -ascii docs/build/$base.txt docs/src/build/$base._tx +# done +# +# +# rm _makedoc.exe + + +# convert documentation from pandoc-format source files +if which cmake >/dev/null && which pandoc >/dev/null +then + echo "Generating documentation from Pandoc source files..." + builddir=,,zipup_builddir.$$ + trap 'rm -rf $builddir' 0 1 2 3 13 15 + mkdir $builddir + ( cd $builddir + cmake .. + make -j4 docs html man + mv docs/txt/changes-5.0.txt ../CHANGES-5.0.txt + mv docs/txt/changes-5.1.txt ../CHANGES-5.1.txt + mv docs/txt/changes-5.2.txt ../CHANGES-5.2.txt + + test -d ../docs/html || mkdir -p ../docs/html + rm -rf ../docs/html/refman + mv docs/html/refman ../docs/html/refman + + rm -rf ../docs/man + mv docs/man ../docs/man + ) || exit 1 + rm -rf $builddir +else + echo "WARNING: CMake or Pandoc not found, skipping step" 1>&2 +fi + + +# generate NaturalDocs documentation +# if which NaturalDocs >/dev/null +# then +# echo "Generating NaturalDocs..." +# ( cd docs/naturaldocs +# make clean +# make public +# ) || exit 1 +# else +# echo "WARNING: NaturalDocs not found, skipping step" 1>&2 +# fi + + +# create language.dat and keyboard.dat files +# misc/mkdata.sh || exit 1 + + +# convert files to djgpp format for distribution +# ./fix.sh djgpp --utod + + +# convert line endings to CR/LF +./misc/convert_line_endings.sh --utod || exit 1 + + +# recursive helper to fill any empty directories with a tmpfile.txt +scan_for_empties() +{ + if [ -f $1/tmpfile.txt ]; then rm $1/tmpfile.txt; fi + + files=`echo $1/*` + if [ "$files" = "$1/CVS" -o "$files" = "$1/cvs" -o "$files" = "$1/*" ]; then + echo "This file is needed because some unzip programs skip empty directories." > $1/tmpfile.txt + else + for file in $files; do + if [ -d $file ]; then + scan_for_empties $file + fi + done + fi +} + + +#echo "Filling empty directories with tmpfile.txt..." +scan_for_empties "." + + +# build the main zip archive +echo "Creating $name.zip..." +if [ -f .dist/$name.zip ]; then rm .dist/$name.zip; fi +rm -rf ./autom4te* +mkdir -p .dist/allegro +# Note: we use -print0 and xargs -0 to handle file names with spaces. +find . -type f "(" -path "*/.*" -prune -o -iname "*.rej" \ + -prune -o -iname "*.orig" -prune -o -print0 ")" | \ + xargs -0 cp -a --parents -t .dist/allegro + +# from now on, the scripts runs inside .dist +cd .dist + + +# If 7za is available, use that to produce .7z files. +# I used to produce .zip files with it as well but I noticed upon extraction +# files with timestamps 10 hours into the future (I'm at UTC+10). .7z files +# seem to be unaffected. This was with p7zip 4.65. +if 7za > /dev/null ; then + rm -f $name.7z + if [ -n "$FAST_ZIPUP" ]; then + 7za a -mx0 $name.7z allegro + else + 7za a -mx9 -ms=on $name.7z allegro + fi +fi + +rm -f $name.zip +if [ -n "$FAST_ZIPUP" ]; then + zip -0 -r $name.zip allegro +else + zip -9 -r $name.zip allegro +fi + + +# generate the manifest file +echo "Generating allegro.mft..." +unzip -Z1 $name.zip | sort > allegro/allegro.mft +echo "allegro/allegro.mft" >> allegro/allegro.mft +utod allegro/allegro.mft +zip -9 $name.zip allegro/allegro.mft + +if [ -r $name.7z ]; then + 7za a $name.7z allegro/allegro.mft +fi + + +# if we are building diffs as well, do those +if [ $# -eq 2 ]; then + + echo "Inflating current version ($name.zip)..." + mkdir current + unzip -q $name.zip -d current + + echo "Inflating previous version ($2)..." + mkdir previous + unzip -q ../../"$2" -d previous || exit 1 + + echo "Generating diffs..." + diff -U 3 -N --recursive previous/ current/ > $name.diff + + echo "Deleting temp files..." + rm -r previous + rm -r current + + + # generate the .txt file for the diff archive + echo "This is a set of diffs to upgrade from $prev to $name." > $name.txt + echo >> $name.txt + echo "Date: $(date '+%A %B %d, %Y, %H:%M')" >> $name.txt + echo >> $name.txt + echo "To apply this patch, copy $name.diff into the same directory where you" >> $name.txt + echo "installed Allegro (this should be one level up from the allegro/ dir, eg." >> $name.txt + echo "if your Allegro installation lives in c:/djgpp/allegro/, you should be in" >> $name.txt + echo "c:/djgpp/). Then type the command:" >> $name.txt + echo >> $name.txt + echo " patch -p1 < $name.diff" >> $name.txt + echo >> $name.txt + echo "Change into the allegro directory, run make, and enjoy!" >> $name.txt + + utod $name.txt + + + # zip up the diff archive + echo "Creating ${name}_diff.zip..." + if [ -f ${name}_diff.zip ]; then rm ${name}_diff.zip; fi + zip -9 ${name}_diff.zip $name.diff $name.txt + + + # find if we need to add any binary files as well + bin=$(sed -n -e "s/Binary files previous\/\(.*\) and current.* differ/\1/p" $name.diff) + + if [ "$bin" != "" ]; then + echo "Adding binary diffs..." + zip -9 ${name}_diff.zip $bin + fi + + rm $name.diff $name.txt + +fi + + +# convert line endings to back to LF +cd .. +./misc/convert_line_endings.sh --dtou || exit 1 diff --git a/allegro/misc/zipwin.sh b/allegro/misc/zipwin.sh new file mode 100644 index 00000000..76e93bd5 --- /dev/null +++ b/allegro/misc/zipwin.sh @@ -0,0 +1,362 @@ +#! /bin/sh +# +# Shell script to create a Windows binary distribution. This will +# compile the DLL files using MSVC or Cygwin, generate the batch file and +# associated helpers needed for end users to build the example programs, +# and finally zip up the results. +# +# Note! If you use Cygwin to generate the DLLs make sure you have set up +# your MINGDIR and ALLEGRO_USE_CYGWIN environment variables correctly. +# +# It should be run from the root of the Allegro directory, eg. +# bash misc/zipwin.sh, so that it can find misc/vcvars.c and misc/askq.c. + + +# check we have a filename, and strip off the path and extension from it +if [ $# -ne 1 ]; then + echo "Usage: zipwin " 1>&2 + exit 1 +fi + +name=$(echo "$1" | sed -e 's/.*[\\\/]//; s/\.zip//') + + +# check that MSVC or Cygwin is available +if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then + if [ "$MINGDIR" = "" ]; then + echo "You need to set up Cygwin before running this script" 1>&2 + exit 1 + fi +else + if [ "$MSVCDIR" = "" ]; then + echo "You need to set up MSVC (run vcvars32.bat) before running this script" 1>&2 + exit 1 + fi +fi + + +# check that we are in the Allegro dir +if [ ! -f include/allegro5/allegro.h ]; then + echo "Oops, you don't appear to be in the root of the Allegro directory" 1>&2 + exit 1 +fi + + +# convert Allegro to MSVC or Cygwin format +if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then + ./fix.sh mingw --dtou +else + ./fix.sh msvc --utod +fi + + +# delete all generated files +echo "Cleaning the Allegro tree..." +make.exe -s veryclean + + +# generate DLL export definition files +misc/fixdll.sh + + +# generate dependencies +echo "Generating dependencies..." +make.exe depend + + +# build all three libs +make.exe lib +make.exe lib DEBUGMODE=1 +make.exe lib PROFILEMODE=1 + + +# find what library version (DLL filename) the batch file should build +ver=`sed -n -e "s/LIBRARY_VERSION = \(.*\)/\1/p" makefile.ver` + + +# compile vcvars +echo "Compiling vcvars.exe..." +if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then + gcc -Wl,--subsystem,console -o vcvars.exe misc/vcvars.c -ladvapi32 +else + cl -nologo misc/vcvars.c advapi32.lib + rm vcvars.obj +fi + + +# compile askq +echo "Compiling askq.exe..." +if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then + gcc -Wl,--subsystem,console -o askq.exe misc/askq.c +else + cl -nologo misc/askq.c + rm askq.obj +fi + + +# generate the setup code for msvcmake.bat (this bit checks for vcvars32, +# and builds the import libs) +echo "Generating msvcmake.bat..." + +cat > msvcmake.bat << END_OF_BATCH +@echo off + +rem Batch file for installing the precompiled Allegro DLL files, +rem and building the MSVC example and test programs. + +rem Generated by misc/zipwin.sh + +if not exist include\\allegro.h goto no_allegro + +if not "%MSVCDIR%" == "" goto got_msvc + +if "%VCVARS%" == "" goto no_vcvars + +call "%VCVARS%" +goto got_msvc + +:no_vcvars + +echo MSVC environment variables not found: running vcvars.exe to look for them +vcvars.exe msvcmake.bat + +goto the_end + +:got_msvc + +call fix.bat msvc --quick + +echo Generating release mode import library +copy lib\\msvc\\allegro.def lib\\msvc\\alleg$ver.def > nul +lib /nologo /machine:ix86 /def:lib\\msvc\\alleg$ver.def /out:lib\\msvc\\alleg.lib + +echo Generating debug mode import library +copy lib\\msvc\\allegro.def lib\\msvc\\alld$ver.def > nul +lib /nologo /machine:ix86 /def:lib\\msvc\\alld$ver.def /out:lib\\msvc\\alld.lib /debugtype:cv + +echo Generating profile mode import library +copy lib\\msvc\\allegro.def lib\\msvc\\allp$ver.def > nul +lib /nologo /machine:ix86 /def:lib\\msvc\\allp$ver.def /out:lib\\msvc\\allp.lib + +echo Compiling test and example programs +END_OF_BATCH + + +# If running Cygwin, we need to do some trickery +if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then + ./fix.sh msvc --utod + export MSVCDIR="MSVCDIR" + make.exe depend UNIX_TOOLS=1 + + echo "Fooling the MSVC makefile ..." + cp lib/mingw32/*.dll lib/msvc/ + make.exe -t lib +fi + + +# SED script for converting make -n output into a funky batch file +cat > _fix1.sed << END_OF_SED + +# remove any echo messages from the make output +/^echo/d + +# strip out references to runner.exe +s/obj\/msvc\/runner.exe // + +# turn program name slashes into DOS format +s/\\//\\\\/g + +# make sure were are using command.com copy, rather than cp +s/^.*cat tools.*msvc.plugins.h/copy \/B tools\\\\plugins\\\\*.inc tools\\\\plugins\\\\plugins.h/ + +# add blank lines, to make the batch output more readable +s/^\([^@]*\)$/\\ +\1/ + +# turn any @ argfile references into an echo+tmpfile sequence +s/\(.*\) @ \(.*\)/\\ +echo \2 > _tmp.arg\\ +\1 @_tmp.arg\\ +del _tmp.arg/ + +END_OF_SED + + +# second SED script, for splitting long echos into multiple segments +cat > _fix2.sed << END_OF_SED + +s/echo \(................................................[^ ]*\) \(........*\) \(>>*\) _tmp\.arg/echo \1 \3 _tmp.arg\\ +echo \2 >> _tmp.arg/ + +END_OF_SED + + +# run make -n, to see what commands are needed for building this thing +echo "Running make -n, to generate the command list..." + +make.exe -n | \ + sed -f _fix1.sed | \ + sed -f _fix2.sed | \ + sed -f _fix2.sed | \ + sed -f _fix2.sed | \ + sed -f _fix2.sed | \ + sed -f _fix2.sed | \ + sed -f _fix2.sed | \ + sed -f _fix2.sed | \ + sed -f _fix2.sed \ + >> msvcmake.bat + +rm _fix1.sed _fix2.sed + +if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then + unset MSVCDIR +fi + +# finish writing msvcmake.bat (this bit asks whether to install the headers, +# libs, and DLL files) +cat >> msvcmake.bat << END_OF_BATCH +askq.exe Would you like to copy the headers and libs to your MSVC directories +if errorlevel 1 goto no_lib_copy + +if not "%MSVCDIR%" == "" set _VC_DIR_=%MSVCDIR% + +echo Copying libraries +copy lib\\msvc\\*.lib "%_VC_DIR_%\\lib" + +echo Copying allegro.h +copy include\\allegro.h "%_VC_DIR_%\\include" + +echo Copying winalleg.h +copy include\\winalleg.h "%_VC_DIR_%\\include" + +echo Copying module headers +md "%_VC_DIR_%\\include\\allegro" +copy include\\allegro\\*.h "%_VC_DIR_%\\include\\allegro" + +echo Copying inline headers +md "%_VC_DIR_%\\include\\allegro\\inline" +copy include\\allegro\\inline\\*.inl "%_VC_DIR_%\\include\\allegro\\inline" + +echo Copying internal headers +md "%_VC_DIR_%\\include\\allegro\\internal" +copy include\\allegro\\internal\\*.h "%_VC_DIR_%\\include\\allegro\\internal" + +echo Copying platform headers +md "%_VC_DIR_%\\include\\allegro\\platform" +copy include\\allegro\\platform\\aintwin.h "%_VC_DIR_%\\include\\allegro\\platform" +copy include\\allegro\\platform\\almsvc.h "%_VC_DIR_%\\include\\allegro\\platform" +copy include\\allegro\\platform\\alplatf.h "%_VC_DIR_%\\include\\allegro\\platform" +copy include\\allegro\\platform\\alwin.h "%_VC_DIR_%\\include\\allegro\\platform" + +set _VC_DIR_= + +goto lib_copy_done + +:no_lib_copy +echo Library and header files were not installed. +echo You can find the headers in the allegro\\include directory, +echo and the libs in allegro\\lib\\msvc\\ + +:lib_copy_done + +askq.exe Would you like to copy the DLL files to your Windows system directory +if errorlevel 1 goto no_dll_copy + +if "%OS%" == "Windows_NT" set _WIN_DIR_=%SYSTEMROOT%\\system32 +if "%OS%" == "" set _WIN_DIR_=%windir%\\system + +echo Copying DLL files to %_WIN_DIR_% +copy lib\\msvc\\*.dll %_WIN_DIR_% + +set _WIN_DIR_= + +goto dll_copy_done + +:no_dll_copy +echo DLL files were not installed. +echo You can find them in allegro\\lib\\msvc\\ + +:dll_copy_done + +echo. +echo All done: Allegro is now installed on your system! + +goto the_end + +:no_allegro + +echo Can't find the Allegro library source files! To install this binary +echo distribution, you must also have a copy of the library sources, so +echo that I can compile the support programs and convert the documentation. + +:the_end + +END_OF_BATCH + + +# generate the readme +cat > $name.txt << END_OF_README + ______ ___ ___ + /\\ _ \\ /\\_ \\ /\\_ \\ + \\ \\ \\L\\ \\\\//\\ \\ \\//\\ \\ __ __ _ __ ___ + \\ \\ __ \\ \\ \\ \\ \\ \\ \\ /'__\`\\ /'_ \`\\/\\\`'__\\/ __\`\\ + \\ \\ \\/\\ \\ \\_\\ \\_ \\_\\ \\_/\\ __//\\ \\L\\ \\ \\ \\//\\ \\L\\ \\ + \\ \\_\\ \\_\\/\\____\\/\\____\\ \\____\\ \\____ \\ \\_\\\\ \\____/ + \\/_/\\/_/\\/____/\\/____/\\/____/\\/___L\\ \\/_/ \\/___/ + /\\____/ + \\_/__/ + + + Windows binary distribution. + + + +This package contains precompiled copies of the Windows DLL files for the +Allegro library, to save you having to compile it yourself. This is not a +complete distribution of Allegro, as it does not contain any of the +documentation, example programs, headers, etc. You need to download the full +source version, and then just unzip this package over the top of it. + +To install, run the batch file msvcmake.bat, either from a command prompt or +by double-clicking on it from the Windows explorer. This will hopefully be +able to autodetect all the details of where to find your compiler, and will +automatically compile the various support programs that come with Allegro. + +At the end of the install process you will be asked whether to copy libs and +headers into your compiler directories, and whether to install the DLL files +into the Windows system directory. You should normally say yes here, but if +you prefer, you can leave these files in the Allegro directory, and then +specify the paths to them later on, when you come to compile your own +programs using Allegro. + +There are three versions of the DLL included in this zip: + + alleg$ver.dll is the normal optimised version + alld$ver.dll is the debugging build, and should be used during development + allp$ver.dll is a profiling build, for collecting performance info + +For more general information about using Allegro, see the readme.txt and +docs/build/msvc.txt files from the source distribution. + +END_OF_README + + +# build the main zip archive +echo "Creating $name.zip..." +cd .. +if [ -f $name.zip ]; then rm $name.zip; fi + +if [ "$ALLEGRO_USE_CYGWIN" = "1" ]; then + unix2dos allegro/$name.txt + unix2dos allegro/msvcmake.bat +fi + +zip -9 $name.zip allegro/$name.txt allegro/msvcmake.bat allegro/vcvars.exe allegro/askq.exe allegro/lib/msvc/*.dll + + +# clean up after ourselves +cd allegro +rm $name.txt msvcmake.bat vcvars.exe askq.exe + + +echo "Done!" diff --git a/allegro/python/CMakeLists.txt b/allegro/python/CMakeLists.txt new file mode 100644 index 00000000..f802d5a2 --- /dev/null +++ b/allegro/python/CMakeLists.txt @@ -0,0 +1,52 @@ +include(FindPythonInterp) + +# Construct list of files whose modification should trigger a rebuild of +# the Python API. +foreach(x ${MONOLITH_SOURCES} ${MONOLITH_HEADERS} ${ALLEGRO_PUBLIC_HEADERS}) + if(NOT ${x} MATCHES "^/.*") + file(RELATIVE_PATH xrel ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/${x}) + list(APPEND SOURCES ${xrel}) + endif() +endforeach() + +if(WIN32) + add_custom_command( + OUTPUT python_protos + DEPENDS ${SOURCES} + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/python/checkdocs.py + -c ${CMAKE_C_COMPILER} + -p python_protos + -b ${PROJECT_BINARY_DIR} + -s ${PROJECT_SOURCE_DIR} + -w + ) +else(WIN32) + add_custom_command( + OUTPUT python_protos + DEPENDS ${SOURCES} + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/python/checkdocs.py + -p python_protos + -b ${PROJECT_BINARY_DIR} + -s ${PROJECT_SOURCE_DIR} + ) +endif(WIN32) + +SET(release "") +append_lib_type_suffix(release) +append_lib_linkage_suffix(release) +SET(version "${ALLEGRO_SOVERSION}") + +add_custom_command( + OUTPUT allegro.py + DEPENDS python_protos + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/python/generate_python_ctypes.py + -p python_protos + -o allegro.py + -t \"${release}\" + -v \"${version}\" + ) + +add_custom_target(python + ALL + DEPENDS allegro.py + ) diff --git a/allegro/python/checkdocs.py b/allegro/python/checkdocs.py new file mode 100644 index 00000000..7d9cf88a --- /dev/null +++ b/allegro/python/checkdocs.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python3 +import optparse +import subprocess +import sys +import os +import re +import glob + +links = {} +symbols = {} +structs = {} +types = {} +anonymous_enums = {} +functions = {} +constants = {} +sections = {} + +def check_references(): + """ + Check if each [link] in the reference manual actually exists. Also fills + in global variable "links". + """ + print("Checking References...") + + html_refs = os.path.join(options.build, "docs", "html_refs") + for line in open(html_refs): + mob = re.match(r"\[(.*?)\]", line) + if mob: + links[mob.group(1)] = True + + docs = glob.glob("docs/src/refman/*.txt") + for doc in docs: + text = file(doc).read() + text = re.compile(".*?", re.S).sub("", text) + # in case of [A][B], we will not see A but we do see B. + for link in re.findall(r" \[([^[]*?)\][^([]", text): + if not link in links: + print("Missing: %s: %s" % (doc, link)) + for section in re.findall(r"^#+ (.*)", text, re.MULTILINE): + if not section.startswith("API:"): + sections[section] = 1 + + for link in sections.keys(): + del links[link] + +def add_struct(line): + if options.protos: + kind = re.match("\s*(\w+)", line).group(1) + if kind in ["typedef", "struct", "enum", "union"]: + mob = None + if kind != "typedef": + mob = re.match(kind + "\s+(\w+)", line) + if not mob: + mob = re.match(".*?(\w+);$", line) + if not mob and kind == "typedef": + mob = re.match("typedef.*?\(\s*\*\s*(\w+)\)", line) + if not mob: + anonymous_enums[line] = 1 + else: + sname = mob.group(1) + if sname.startswith("_ALLEGRO_gl"): + return + if kind == "typedef": + types[sname] = line + else: + structs[sname] = line + + +def parse_header(lines, filename): + """ + Minimal C parser which extracts most symbols from a header. Fills + them into the global variable "symbols". + """ + n = 0 + ok = False + brace = 0 + lines2 = [] + cline = "" + for line in lines: + line = line.strip() + if not line: + continue + + if line.startswith("#"): + if line.startswith("#define"): + if ok: + name = line[8:] + match = re.match("#define ([a-zA-Z_]+)", line) + name = match.group(1) + symbols[name] = "macro" + simple_constant = line.split() + + if len(simple_constant) == 3 and\ + not "(" in simple_constant[1] and\ + simple_constant[2][0].isdigit(): + constants[name] = simple_constant[2] + n += 1 + elif line.startswith("#undef"): + pass + else: + ok = False + match = re.match(r'# \d+ "(.*?)"', line) + if match: + name = match.group(1) + if name == "" or name.startswith(options.build) or \ + name.startswith("include") or \ + name.startswith("addons") or\ + name.startswith(options.source): + ok = True + continue + if not ok: + continue + + sublines = line.split(";") + + for i, subline in enumerate(sublines): + if i < len(sublines) - 1: + subline += ";" + + brace -= subline.count("}") + brace -= subline.count(")") + brace += subline.count("{") + brace += subline.count("(") + + if cline: + if cline[-1].isalnum(): + cline += " " + cline += subline + if brace == 0 and subline.endswith(";") or subline.endswith("}"): + + lines2.append(cline.strip()) + cline = "" + + for line in lines2: + line = line.replace("__attribute__((__stdcall__))", "") + if line.startswith("enum"): + add_struct(line) + elif line.startswith("typedef"): + match = None + if not match: + match = re.match(r".*?(\w+);$", line) + if not match: + match = re.match(r".*?(\w*)\[", line) + if not match: + match = re.match(r".*?\(\s*\*\s*(\w+)\s*\).*?", line) + + if match: + name = match.group(1) + symbols[name] = "typedef" + n += 1 + else: + print("? " + line) + + add_struct(line) + + elif line.startswith("struct"): + add_struct(line) + elif line.startswith("union"): + add_struct(line) + else: + try: + parenthesis = line.find("(") + if parenthesis < 0: + match = re.match(r".*?(\w+)\s*=", line) + if not match: + match = re.match(r".*?(\w+)\s*;$", line) + if not match: + match = re.match(r".*?(\w+)", line) + symbols[match.group(1)] = "variable" + n += 1 + else: + match = re.match(r".*?(\w+)\s*\(", line) + fname = match.group(1) + symbols[fname] = "function" + if not fname in functions: + functions[fname] = line + n += 1 + except AttributeError as e: + print("Cannot parse in " + filename) + print("Line is: " + line) + print(e) + return n + + +def parse_all_headers(): + """ + Call parse_header() on all of Allegro's public include files. + """ + p = options.source + includes = " -I " + p + "/include -I " + os.path.join(options.build, + "include") + includes += " -I " + p + "/addons/acodec" + headers = [p + "/include/allegro5/allegro.h", + p + "/addons/acodec/allegro5/allegro_acodec.h", + p + "/include/allegro5/allegro_opengl.h"] + if options.windows: + headers += [p + "/include/allegro5/allegro_windows.h"] + + for addon in glob.glob(p + "/addons/*"): + name = addon[len(p + "/addons/"):] + header = os.path.join(p, "addons", name, "allegro5", + "allegro_" + name + ".h") + if os.path.exists(header): + headers.append(header) + includes += " -I " + os.path.join(p, "addons", name) + + for header in headers: + p = subprocess.Popen(options.compiler + " -E -dD - " + includes, + stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) + filename = "#include \n" + open(header).read() + p.stdin.write(filename.encode('utf-8')) + p.stdin.close() + text = p.stdout.read().decode("utf-8") + parse_header(text.splitlines(), header) + #print("%d definitions in %s" % (n, header)) + + +def check_undocumented_functions(): + """ + Cross-compare the documentation links with public symbols found in headers. + """ + print("Checking if each documented function exists...") + + parse_all_headers() + + for link in links: + if not link in symbols: + print("Missing: " + link) + + print("") + print("Checking if each function is documented...") + others = [] + for link in symbols: + if not link in links: + if symbols[link] == "function": + print("Missing: " + link) + else: + if link and not link.startswith("GL") and \ + not link.startswith("gl") and \ + not link.startswith("_al_gl") and \ + not link.startswith("_ALLEGRO_gl") and \ + not link.startswith("_ALLEGRO_GL") and \ + not link.startswith("ALLEGRO_"): + others.append(link) + + print("Also leaking:") + others.sort() + print(", ".join(others)) + + +def list_all_symbols(): + parse_all_headers() + for name in sorted(symbols.keys()): + print(name) + + +def main(argv): + global options + p = optparse.OptionParser() + p.description = """\ +When run from the toplevel A5 directory, this script will parse the include, +addons and cmake build directory for global definitions and check against all +references in the documentation - then report symbols which are not documented. +""" + p.add_option("-b", "--build", help="Path to the build directory.") + p.add_option("-c", "--compiler", help="Path to gcc.") + p.add_option("-s", "--source", help="Path to the source directory.") + p.add_option("-l", "--list", action="store_true", + help="List all symbols.") + p.add_option("-p", "--protos", help="Write all public " + + "prototypes to the given file.") + p.add_option("-w", "--windows", action="store_true", + help="Include windows specific symbols.") + options, args = p.parse_args() + + if not options.source: + options.source = "." + if not options.compiler: + options.compiler = "gcc" + + if not options.build: + sys.stderr.write("Build path required (-p).\n") + p.print_help() + sys.exit(-1) + + if options.protos: + parse_all_headers() + f = open(options.protos, "w") + for name, s in structs.items(): + f.write(name + ": " + s + "\n") + for name, s in types.items(): + f.write(name + ": " + s + "\n") + for e in anonymous_enums.keys(): + f.write(": " + e + "\n") + for fname, proto in functions.items(): + f.write(fname + "(): " + proto + "\n") + for name, value in constants.items(): + f.write(name + ": #define " + name + " " + value + "\n") + elif options.list: + list_all_symbols() + else: + check_references() + print("") + check_undocumented_functions() + + +if __name__ == "__main__": + main(sys.argv) diff --git a/allegro/python/ex_draw_bitmap.py b/allegro/python/ex_draw_bitmap.py new file mode 100644 index 00000000..b7582d9d --- /dev/null +++ b/allegro/python/ex_draw_bitmap.py @@ -0,0 +1,346 @@ +#!/usr/bin/env python3 +import sys, os +from random import * +from math import * +from ctypes import * + +# Get path to examples data. +p = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "examples")) + +from allegro import * + +def abort_example(text): + sys.stderr.write(text) + sys.exit(1) + +FPS = 60 +MAX_SPRITES = 1024 + +class Sprite: + def __init__(self): + self.x, self.y, self.dx, self.dy = 0, 0, 0, 0 + +text = [ + "Space - toggle use of textures", + "B - toggle alpha blending", + "Left/Right - change bitmap size", + "Up/Down - change bitmap count", + "F1 - toggle help text" + ] + +class Example: + sprites = [Sprite() for i in range(MAX_SPRITES)] + use_memory_bitmaps = False + blending = False + display = None + mysha = None + bitmap = None + bitmap_size = 0 + sprite_count = 0 + show_help = True + font = None + + mouse_down = False + last_x, last_y = 0, 0 + + white = None + half_white = None + dark = None + red = None + + direct_speed_measure = 1.0 + + ftpos = 0 + frame_times = [0.0] * FPS + +example = Example() + +def add_time(): + example.frame_times[example.ftpos] = al_get_time() + example.ftpos += 1 + if example.ftpos >= FPS: + example.ftpos = 0 + +def get_fps(): + prev = FPS - 1 + min_dt = 1 + max_dt = 1 / 1000000 + av = 0 + for i in range(FPS): + if i != example.ftpos: + dt = example.frame_times[i] - example.frame_times[prev] + if dt < min_dt and dt > 0: + min_dt = dt + if dt > max_dt: + max_dt = dt + av += dt + prev = i + av /= FPS - 1 + average = ceil(1 / av) + d = 1 / min_dt - 1 / max_dt + minmax = floor(d / 2) + return average, minmax + +def add_sprite(): + if example.sprite_count < MAX_SPRITES: + w = al_get_display_width(example.display) + h = al_get_display_height(example.display) + i = example.sprite_count + example.sprite_count += 1 + s = example.sprites[i] + a = randint(0, 359) + s.x = randint(0, w - example.bitmap_size - 1) + s.y = randint(0, h - example.bitmap_size - 1) + s.dx = cos(a) * FPS * 2 + s.dy = sin(a) * FPS * 2 + +def add_sprites(n): + for i in range(n): + add_sprite() + +def remove_sprites(n): + example.sprite_count -= n + if example.sprite_count < 0: + example.sprite_count = 0 + +def change_size(size): + if size < 1: + size = 1 + if size > 1024: + size = 1024 + + if example.bitmap: + al_destroy_bitmap(example.bitmap) + al_set_new_bitmap_flags( + ALLEGRO_MEMORY_BITMAP if example.use_memory_bitmaps else 0) + example.bitmap = al_create_bitmap(size, size) + example.bitmap_size = size + al_set_target_bitmap(example.bitmap) + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, example.white) + al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)) + bw = al_get_bitmap_width(example.mysha) + bh = al_get_bitmap_height(example.mysha) + al_draw_scaled_bitmap(example.mysha, 0, 0, bw, bh, 0, 0, + size, size, 0) + al_set_target_backbuffer(example.display) + +def sprite_update(s): + w = al_get_display_width(example.display) + h = al_get_display_height(example.display) + + s.x += s.dx / FPS + s.y += s.dy / FPS + + if s.x < 0: + s.x = -s.x + s.dx = -s.dx + + if s.x + example.bitmap_size > w: + s.x = -s.x + 2 * (w - example.bitmap_size) + s.dx = -s.dx + + if s.y < 0: + s.y = -s.y + s.dy = -s.dy + + if s.y + example.bitmap_size > h: + s.y = -s.y + 2 * (h - example.bitmap_size) + s.dy = -s.dy + + if example.bitmap_size > w: s.x = w / 2 - example.bitmap_size / 2 + if example.bitmap_size > h: s.y = h / 2 - example.bitmap_size / 2 + +def update(): + for i in range(example.sprite_count): + sprite_update(example.sprites[i]) + +def redraw(): + w = al_get_display_width(example.display) + h = al_get_display_height(example.display) + fh = al_get_font_line_height(example.font) + info = ["textures", "memory buffers"] + binfo = ["alpha", "additive", "tinted", "solid"] + tint = example.white + + if example.blending == 0: + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) + tint = example.half_white + elif example.blending == 1: + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) + tint = example.dark + elif example.blending == 2: + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) + tint = example.red + elif example.blending == 3: + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, example.white) + + for i in range(example.sprite_count): + s = example.sprites[i] + al_draw_tinted_bitmap(example.bitmap, tint, s.x, s.y, 0) + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) + if example.show_help: + for i in range(5): + al_draw_text(example.font, example.white, 0, h - 5 * fh + i * fh, 0, text[i]) + + al_draw_textf(example.font, example.white, 0, 0, 0, "count: %d", + example.sprite_count) + al_draw_textf(example.font, example.white, 0, fh, 0, "size: %d", + example.bitmap_size) + al_draw_textf(example.font, example.white, 0, fh * 2, 0, "%s", + info[example.use_memory_bitmaps].encode("utf8")) + al_draw_textf(example.font, example.white, 0, fh * 3, 0, "%s", + binfo[example.blending].encode("utf8")) + + f1, f2 = get_fps() + al_draw_textf(example.font, example.white, w, 0, ALLEGRO_ALIGN_RIGHT, "%s", + ("FPS: %4d +- %-4d" % (f1, f2)).encode("utf8")) + al_draw_textf(example.font, example.white, w, fh, ALLEGRO_ALIGN_RIGHT, "%s", + ("%4d / sec" % int(1.0 / example.direct_speed_measure)).encode("utf8")) + +def main(): + w, h = 640, 480 + done = False + need_redraw = True + example.show_help = True + + if not al_install_system(ALLEGRO_VERSION_INT, None): + abort_example("Failed to init Allegro.\n") + sys.exit(1) + + if not al_init_image_addon(): + abort_example("Failed to init IIO addon.\n") + sys.exit(1) + + al_init_font_addon() + + al_get_num_video_adapters() + + info = ALLEGRO_MONITOR_INFO() + al_get_monitor_info(0, byref(info)) + if info.x2 - info.x1 < w: + w = info.x2 - info.x1 + if info.y2 - info.y1 < h: + h = info.y2 - info.y1 + example.display = al_create_display(w, h) + + if not example.display: + abort_example("Error creating display.\n") + + if not al_install_keyboard(): + abort_example("Error installing keyboard.\n") + + if not al_install_mouse(): + abort_example("Error installing mouse.\n") + + example.font = al_load_font(p + "/data/fixed_font.tga", 0, 0) + if not example.font: + abort_example("Error loading data/fixed_font.tga\n") + + example.mysha = al_load_bitmap(p + "/data/mysha256x256.png") + if not example.mysha: + abort_example("Error loading data/mysha256x256.png\n") + + example.white = al_map_rgb_f(1, 1, 1) + example.half_white = al_map_rgba_f(1, 1, 1, 0.5) + example.dark = al_map_rgb(15, 15, 15) + example.red = al_map_rgb_f(1, 0.2, 0.1) + change_size(256) + add_sprite() + add_sprite() + + timer = al_create_timer(1.0 / FPS) + + queue = al_create_event_queue() + al_register_event_source(queue, al_get_keyboard_event_source()) + al_register_event_source(queue, al_get_mouse_event_source()) + al_register_event_source(queue, al_get_timer_event_source(timer)) + al_register_event_source(queue, al_get_display_event_source(example.display)) + + al_start_timer(timer) + + while not done: + event = ALLEGRO_EVENT() + + if need_redraw and al_is_event_queue_empty(queue): + t = -al_get_time() + add_time() + al_clear_to_color(al_map_rgb_f(0, 0, 0)) + redraw() + t += al_get_time() + example.direct_speed_measure = t + al_flip_display() + need_redraw = False + + al_wait_for_event(queue, byref(event)) + + if event.type == ALLEGRO_EVENT_KEY_CHAR: + if event.keyboard.keycode == ALLEGRO_KEY_ESCAPE: + done = True + elif event.keyboard.keycode == ALLEGRO_KEY_UP: + add_sprites(1) + elif event.keyboard.keycode == ALLEGRO_KEY_DOWN: + remove_sprites(1) + elif event.keyboard.keycode == ALLEGRO_KEY_LEFT: + change_size(example.bitmap_size - 1) + elif event.keyboard.keycode == ALLEGRO_KEY_RIGHT: + change_size(example.bitmap_size + 1) + elif event.keyboard.keycode == ALLEGRO_KEY_F1: + example.show_help ^= 1 + elif event.keyboard.keycode == ALLEGRO_KEY_SPACE: + example.use_memory_bitmaps ^= 1 + change_size(example.bitmap_size) + elif event.keyboard.keycode == ALLEGRO_KEY_B: + example.blending += 1 + if example.blending == 4: + example.blending = 0 + elif event.type == ALLEGRO_EVENT_DISPLAY_CLOSE: + done = True + + elif event.type == ALLEGRO_EVENT_TIMER: + update() + need_redraw = True + + elif event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + example.mouse_down = True + example.last_x = event.mouse.x + example.last_y = event.mouse.y + + elif event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP: + fh = al_get_font_line_height(example.font) + example.mouse_down = False + if event.mouse.x < 40 and event.mouse.y >= h - fh * 5: + button = (event.mouse.y - (h - fh * 5)) // fh + if button == 0: + example.use_memory_bitmaps ^= 1 + change_size(example.bitmap_size) + if button == 1: + example.blending += 1 + if example.blending == 4: + example.blending = 0 + if button == 4: + example.show_help ^= 1 + + elif event.type == ALLEGRO_EVENT_MOUSE_AXES: + if example.mouse_down: + dx = event.mouse.x - example.last_x + dy = event.mouse.y - example.last_y + if dy > 4: + add_sprites(int(dy / 4)) + + if dy < -4: + remove_sprites(-int(dy / 4)) + + if dx > 4: + change_size(example.bitmap_size + dx - 4) + + if dx < -4: + change_size(example.bitmap_size + dx + 4) + + example.last_x = event.mouse.x + example.last_y = event.mouse.y + + al_destroy_bitmap(example.bitmap) + al_uninstall_system() + +al_main(main) diff --git a/allegro/python/generate_python_ctypes.py b/allegro/python/generate_python_ctypes.py new file mode 100644 index 00000000..6af193bf --- /dev/null +++ b/allegro/python/generate_python_ctypes.py @@ -0,0 +1,551 @@ +#!/usr/bin/env python3 +import sys +import re +import optparse +from ctypes import * + +""" +This script will use the prototypes from "checkdocs.py -s" to concoct +a 1:1 Python wrapper for Allegro. +""" + + +class _AL_UTF8String: + pass + + +class Allegro: + def __init__(self): + self.types = {} + self.functions = {} + self.constants = {} + + def add_struct(self, name): + x = type(name, (Structure, ), {}) + self.types[name] = x + + def add_union(self, name): + x = type(name, (Union, ), {}) + self.types[name] = x + + def get_type(self, ptype): + conversion = { + "bool": c_bool, + "_Bool": c_bool, + "char": c_byte, + "unsignedchar": c_ubyte, + "int": c_int, + "unsigned": c_uint, + "unsignedint": c_uint, + "int16_t": c_int16, + "uint16_t": c_uint16, + "int32_t": c_int32, + "uint32_t": c_uint32, + "int64_t": c_int64, + "uint64_t": c_uint64, + "uintptr_t": c_void_p, + "intptr_t": c_void_p, + "GLuint": c_uint, + "unsignedlong": c_ulong, + "long": c_long, + "size_t": c_size_t, + "off_t": c_int64, + "time_t": c_int64, + "va_list": c_void_p, + "float": c_float, + "double": c_double, + "al_fixed": c_int, + "HWND": c_void_p, + "char*": _AL_UTF8String, + + # hack: this probably shouldn't be in the public docs + "postprocess_callback_t": c_void_p, + } + + ptype = re.sub(r"\b(struct|union)\b", "", ptype) + ptype = re.sub(r"\bconst\b", "", ptype) + ptype = re.sub(r"\bextern\b", "", ptype) + ptype = re.sub(r"\b__inline__\b", "", ptype) + ptype = re.sub(r"\s+", "", ptype) + + if ptype.endswith("*"): + if ptype in conversion: + return conversion[ptype] + t = ptype[:-1] + if t in self.types: + return POINTER(self.types[t]) + return c_void_p + elif ptype in self.types: + return self.types[ptype] + else: + try: + return conversion[ptype] + except KeyError: + print("Type Error:" + str(ptype)) + return None + + def parse_funcs(self, funcs): + """ + Go through all documented functions and add their prototypes + as Python functions. + + The file should have been generated by Allegro's documentation + generation scripts. + """ + + for func in funcs: + name, proto = func.split(":", 1) + if not name.startswith("al_"): + continue + proto = proto.strip() + name = name[:-2] + if proto.startswith("enum"): + continue + if proto.startswith("typedef"): + continue + if "=" in proto: + continue + if proto.startswith("#"): + continue + funcstart = proto.find(name) + funcend = funcstart + len(name) + ret = proto[:funcstart].rstrip() + params = proto[funcend:].strip(" ;") + if params[0] != "(" or params[-1] != ")": + print("Error:") + print(params) + continue + params2 = params[1:-1] + # remove callback argument lists + balance = 0 + params = "" + for c in params2: + if c == ")": + balance -= 1 + if balance == 0: + params += c + if c == "(": + balance += 1 + params = params.split(",") + plist = [] + for param in params: + param = re.sub(r"\bconst\b", "", param) + param = param.strip() + if param == "void": + continue + if param == "": + continue + if param == "...": + continue + + # treat arrays as a void pointer, for now + if param.endswith("]") or param.endswith("*"): + plist.append(c_void_p) + continue + + # treat callbacks as a void pointer, for now + if param.endswith(")"): + plist.append(c_void_p) + continue + + mob = re.match("^.*?(\w+)$", param) + if mob: + pnamepos = mob.start(1) + if pnamepos == 0: + # Seems the parameter is not named + pnamepos = len(param) + else: + print(params) + print(proto) + print("") + continue + ptype = param[:pnamepos] + ptype = self.get_type(ptype) + plist.append(ptype) + + f = type("", (object, ), {"restype": c_int}) + if not ret.endswith("void"): + f.restype = self.get_type(ret) + try: + f.argtypes = plist + except TypeError as e: + print(e) + print(name) + print(plist) + self.functions[name] = f + + def parse_protos(self, filename): + protos = [] + unions = [] + funcs = [] + + # first pass: create all structs, but without fields + for line in open(filename): + name, proto = line.split(":", 1) + proto = proto.lstrip() + if name.endswith("()"): + funcs.append(line) + continue + # anonymous structs have no name at all + if name and not name.startswith("ALLEGRO_"): + continue + if name == "ALLEGRO_OGL_EXT_API": + continue + if proto.startswith("union") or\ + proto.startswith("typedef union"): + self.add_union(name) + unions.append((name, proto)) + elif proto.startswith("struct") or\ + proto.startswith("typedef struct"): + self.add_struct(name) + protos.append((name, proto)) + elif proto.startswith("enum") or\ + proto.startswith("typedef enum"): + if name: + self.types[name] = c_int + protos.append(("", proto)) + elif proto.startswith("#define"): + if not name.startswith("_") and not name.startswith("GL_"): + i = eval(proto.split(None, 2)[2]) + self.constants[name] = i + else: + # actual typedef + mob = re.match("typedef (.*) " + name, proto) + if mob: + t = mob.group(1) + self.types[name] = self.get_type(t.strip()) + else: + # Probably a function pointer + self.types[name] = c_void_p + + protos += unions + + # second pass: fill in fields + for name, proto in protos: + bo = proto.find("{") + if bo == -1: + continue + bc = proto.rfind("}") + braces = proto[bo + 1:bc] + + if proto.startswith("enum") or \ + proto.startswith("typedef enum"): + + fields = braces.split(",") + i = 0 + for field in fields: + if "=" in field: + fname, val = field.split("=", 1) + fname = fname.strip() + # replace any 'X' (an integer value in C) with + # ord('X') to match up in Python + val = re.sub("('.')", "ord(\\1)", val) + try: + i = int(eval(val, globals(), self.constants)) + except NameError: + i = val + except Exception: + raise ValueError( + "Exception while parsing '{}'".format( + val)) + else: + fname = field.strip() + if not fname: + continue + self.constants[fname] = i + try: + i += 1 + except TypeError: + pass + continue + + balance = 0 + fields = [""] + for c in braces: + if c == "{": + balance += 1 + if c == "}": + balance -= 1 + if c == ";" and balance == 0: + fields.append("") + else: + fields[-1] += c + + flist = [] + for field in fields: + if not field: + continue + + # add function pointer as void pointer + mob = re.match(".*?\(\*(\w+)\)", field) + if mob: + flist.append((mob.group(1), "c_void_p")) + continue + + # add any pointer as void pointer + mob = re.match(".*?\*(\w+)$", field) + if mob: + flist.append((mob.group(1), "c_void_p")) + continue + + # add an array + mob = re.match("(.*)\s+(\w+)\[(.*?)\]$", field) + if mob: + # this is all a hack + n = 0 + ftype = mob.group(1) + if ftype.startswith("struct"): + if ftype == "struct {float axis[3];}": + t = "c_float * 3" + else: + print("Error: Can't parse " + ftype + " yet.") + t = None + else: + n = mob.group(3) + # something in A5 uses a 2d array + if "][" in n: + n = n.replace("][", " * ") + # something uses a division expression + if "/" in n: + n = "(" + n.replace("/", "//") + ")" + t = self.get_type(ftype).__name__ + " * " + n + fname = mob.group(2) + flist.append((fname, t)) + continue + + vars = field.split(",") + mob = re.match("\s*(.*?)\s+(\w+)\s*$", vars[0]) + + t = self.get_type(mob.group(1)) + vname = mob.group(2) + if t is not None and vname is not None: + flist.append((vname, t.__name__)) + for v in vars[1:]: + flist.append((v.strip(), t.__name__)) + else: + print("Error: " + str(vars)) + + try: + self.types[name].my_fields = flist + except AttributeError: + print(name, flist) + + self.parse_funcs(funcs) + + +def main(): + p = optparse.OptionParser() + p.add_option("-o", "--output", help="location of generated file") + p.add_option("-p", "--protos", help="A file with all " + + "prototypes to generate Python wrappers for, one per line. " + "Generate it with docs/scripts/checkdocs.py -p") + p.add_option("-t", "--type", help="the library type to " + + "use, e.g. debug") + p.add_option("-v", "--version", help="the library version to " + + "use, e.g. 5.1") + options, args = p.parse_args() + + if not options.protos: + p.print_help() + return + + al = Allegro() + + al.parse_protos(options.protos) + + f = open(options.output, "w") if options.output else sys.stdout + + release = options.type + version = options.version + f.write(r"""# Generated by generate_python_ctypes.py. +import os, platform, sys +from ctypes import * +from ctypes.util import * + +# You must adjust this function to point ctypes to the A5 DLLs you are +# distributing. +_dlls = [] +def _add_dll(name): + release = "%(release)s" + if os.name == "nt": + release = "%(release)s-%(version)s" + + # Under Windows, DLLs are found in the current directory, so this + # would be an easy way to keep all your DLLs in a sub-folder. + + # os.chdir("dlls") + + path = find_library(name + release) + if not path: + if os.name == "mac": + path = name + release + ".dylib" + elif os.name == "nt": + path = name + release + ".dll" + elif os.name == "posix": + if platform.mac_ver()[0]: + path = name + release + ".dylib" + else: + path = "lib" + name + release + ".so" + else: + sys.stderr.write("Cannot find library " + name + "\n") + + # In most cases, you actually don't want the above and instead + # use the exact filename within your game distribution, possibly + # even within a .zip file. + # if not os.path.exists(path): + # path = "dlls/" + path + + try: + # RTLD_GLOBAL is required under OSX for some reason (?) + _dlls.append(CDLL(path, RTLD_GLOBAL)) + except OSError: + # No need to fail here, might just be one of the addons. + pass + + # os.chdir("..") + +_add_dll("allegro") +_add_dll("allegro_acodec") +_add_dll("allegro_audio") +_add_dll("allegro_primitives") +_add_dll("allegro_color") +_add_dll("allegro_font") +_add_dll("allegro_ttf") +_add_dll("allegro_image") +_add_dll("allegro_dialog") +_add_dll("allegro_memfile") +_add_dll("allegro_physfs") +_add_dll("allegro_shader") +_add_dll("allegro_main") +_add_dll("allegro_video") +_add_dll("allegro_monolith") + +# We don't have information ready which A5 function is in which DLL, +# so we just try them all. +def _dll(func, ret, params): + for dll in _dlls: + try: + f = dll[func] + f.restype = ret + f.argtypes = params + if ret is _AL_UTF8String: + # ctypes cannot do parameter conversion of the return type for us + f.restype = c_char_p + if sys.version_info[0] > 2: return lambda *x: f(*x).decode("utf8") + return f + except AttributeError: pass + sys.stderr.write("Cannot find function " + func + "\n") + return lambda *args: None + +# In Python3, all Python strings are unicode so we have to convert to +# UTF8 byte strings before passing to Allegro. +if sys.version_info[0] > 2: + class _AL_UTF8String: + def from_param(x): + return x.encode("utf8") +else: + _AL_UTF8String = c_char_p + +""" % locals()) + + postpone = [] + + for name, val in sorted(al.constants.items()): + try: + if isinstance(val, str): + val = int(eval(val, globals(), al.constants)) + f.write(name + " = " + str(val) + "\n") + except: + postpone.append((name, val)) + + for name, val in postpone: + f.write(name + " = " + val + "\n") + + structs = set() + + # output everything except structs and unions + for name, x in sorted(al.types.items()): + if not name: + continue + base = x.__bases__[0] + if base != Structure and base != Union: + f.write(name + " = " + x.__name__ + "\n") + else: + structs.add(name) + + # order structs and unions by their dependencies + structs_list = [] + + remaining = set(structs) + while remaining: + for name in sorted(remaining): + ok = True + x = al.types[name] + if hasattr(x, "my_fields"): + for fname, ftype in x.my_fields: + if " " in ftype: + ftype = ftype.split()[0] + if ftype in structs and ftype in remaining: + ok = False + break + if ok: + structs_list.append(name) + remaining.remove(name) + + for name in structs_list: + x = al.types[name] + base = x.__bases__[0] + f.write("class " + name + "(" + base.__name__ + "):\n") + + + if hasattr(x, "my_fields"): + f.write(" _fields_ = [\n") + for fname, ftype in x.my_fields: + f.write(" (\"" + fname + "\", " + ftype + "),\n") + f.write(" ]\n") + else: + f.write(" pass\n") + + pt = POINTER(x) + f.write("%s = POINTER(%s)\n" % (pt.__name__, name)) + + for name, x in sorted(al.functions.items()): + try: + line = name + " = _dll(\"" + name + "\", " + line += x.restype.__name__ + ", " + line += "[" + (", ".join([a.__name__ for a in x.argtypes])) +\ + "])\n" + f.write(line) + except AttributeError as e: + print("Ignoring " + name + " because of errors (" + str(e) + ").") + + # some stuff the automated parser doesn't pick up + f.write(r""" +ALLEGRO_VERSION_INT = \ + ((ALLEGRO_VERSION << 24) | (ALLEGRO_SUB_VERSION << 16) | \ + (ALLEGRO_WIP_VERSION << 8) | ALLEGRO_RELEASE_NUMBER) + """) + + f.write(r""" +# work around bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36834 +if os.name == "nt": + def al_map_rgba_f(r, g, b, a): return ALLEGRO_COLOR(r, g, b, a) + def al_map_rgb_f(r, g, b): return ALLEGRO_COLOR(r, g, b, 1) + def al_map_rgba(r, g, b, a): + return ALLEGRO_COLOR(r / 255.0, g / 255.0, b / 255.0, a / 255.0) + def al_map_rgb(r, g, b): + return ALLEGRO_COLOR(r / 255.0, g / 255.0, b / 255.0, 1) + """) + + f.write(""" +def al_main(real_main, *args): + def python_callback(argc, argv): + real_main(*args) + return 0 + cb = CFUNCTYPE(c_int, c_int, c_void_p)(python_callback) + al_run_main(0, 0, cb); +""") + + f.close() + +main() diff --git a/allegro/python/pong.py b/allegro/python/pong.py new file mode 100644 index 00000000..c17a30ed --- /dev/null +++ b/allegro/python/pong.py @@ -0,0 +1,299 @@ +#!/usr/bin/env python3 +""" + Allegro Python port game example + Original Author: Jeroen De Busser +""" +from allegro import * +from random import randint, random +import os + +examples_data = os.path.abspath(os.path.join(os.path.dirname(__file__), + "..", "examples/data")) + + +class Pallet: + def __init__(self, x, y, w, h, speed, color): + self.__initials = (x, y, w, h, speed, color, 0) + self.reset() + + def reset(self): + '''Resets this pallet to its starting values ''' + self.x, self.y, self.w, self.h, self.speed, self.color, self.moving =\ + self.__initials + + def update(self): + self.y += self.moving * self.speed + if self.y < 0: + self.y = 0 + elif self.y > al_get_display_height(al_get_current_display()) - self.h: + self.y = al_get_display_height(al_get_current_display()) - self.h + + def draw(self): + # Fill + al_draw_filled_rounded_rectangle(self.x, self.y, self.x + self.w, + self.y + self.h, 6, 6, self.color) + # Highlight + al_draw_filled_rounded_rectangle(self.x + 2, self.y + 2, + self.x + self.w / 2, self.y + self.h - 5, 4, 4, + al_map_rgba_f(0.2, 0.2, 0.2, 0.2)) + + +class Player(Pallet): + def __init__(self, x, y, h, w, speed, keyup, keydown, color): + self.__initials = (x, y, h, w, speed, keyup, keydown, color) + Pallet.__init__(self, x, y, h, w, speed, color) + self.keyup, self.keydown = keyup, keydown + + def handle_event(self, ev): + if ev.type == ALLEGRO_EVENT_KEY_DOWN: + if ev.keyboard.keycode == self.keyup: + self.moving = -1 + elif ev.keyboard.keycode == self.keydown: + self.moving = 1 + elif ev.type == ALLEGRO_EVENT_KEY_UP: + if (ev.keyboard.keycode == self.keyup and self.moving == -1) or\ + (ev.keyboard.keycode == self.keydown and self.moving == 1): + self.moving = 0 + + +class AI(Pallet): + def __init__(self, x, y, w, h, speed, color, difficulty, ball): + Pallet.__init__(self, x, y, w, h, speed, color) + self.difficulty = difficulty + self.ball = ball + + def handle_event(self, ev): + #Only fire on a timer event + if ev.type == ALLEGRO_EVENT_TIMER: + #Calculate the target y location according to the difficulty level + if self.difficulty == 1: + target_y = self.ball.y + self.ball.size / 2 + else: + # Higher difficulty, so we need to precalculate the position of + # the ball if it is closer than a certain treshold + dh = al_get_display_height(al_get_current_display()) + if self.ball.xdir == -1 or abs(self.x - self.ball.x) >\ + al_get_display_width(al_get_current_display()) * ( + self.difficulty - 1) / self.difficulty: + # If the ball is moving away, return to the center of the + # screen + target_y = dh / 2 + else: + # The ball is moving towards this pallet within its FOV. + # Calculate what the y location of the ball will be when it + # lands at this pallets x location + target_y = self.ball.y + (self.x - self.ball.x) *\ + self.ball.ydir + if target_y < 0: + target_y = abs(target_y) + elif target_y > dh: + target_y = dh - target_y % dh + + #Set the movement + if target_y > self.y + self.h * 3 / 4: + self.moving = 1 + elif target_y < self.y + self.h * 1 / 4: + self.moving = -1 + else: + self.moving = 0 + + +class Ball: + def __init__(self, x, y, speed, size, pallets, color): + self.x, self.y, self.speed, self.size, self.pallets, self.color =\ + x, y, speed, size, pallets, color + self.xdir = randint(0, 1) + self.xdir = self.xdir - (self.xdir == 0) + self.ydir = randint(0, 1) + self.ydir = self.ydir - (self.ydir == 0) + + def update(self): + new_x = self.x + self.xdir * self.speed + new_y = self.y + self.ydir * self.speed + p = self.pallets[(self.xdir == 1)] # The pallet this ball is flying to + if ((new_x <= p.x + p.w and self.xdir == -1) or (new_x + self.size >= + p.x and self.xdir == 1)) and new_y + self.size >= p.y and\ + new_y <= p.y + p.h: + # We hit the pallet + self.xdir = -self.xdir + self.speed += 0.1 + self.on_pallet_touch(p) + self.new_x = self.x + dw = al_get_display_width(al_get_current_display()) + dh = al_get_display_height(al_get_current_display()) + if self.x < 0 or self.x > dw: + self.on_screen_exit() + if new_y < 0 or new_y + self.size > dh: + # We hit a wall + self.ydir = -self.ydir + new_y = self.y # Reset the y value + self.x = new_x + self.y = new_y + + def on_pallet_touch(self, pallet): + """This function should be called on hitting a pallet""" + pass + + def on_screen_exit(self): + '''This function is called when this ball exits the screen''' + pass + + def draw(self): + # Fill + al_draw_filled_circle(self.x + self.size / 2, self.y + self.size / 2, + self.size / 2, self.color) + # Highlight + al_draw_filled_circle(self.x + self.size / 4, self.y + self.size / 4, + self.size / 6, al_map_rgb_f(0.8, 0.9, 0.8)) + + +class Upgrade(Ball): + def __init__(self, x, y, speed, pallets, color, effect_function): + Ball.__init__(self, x, y, speed, 10, pallets, color) + self.function = effect_function + self.touched = False + + def on_pallet_touch(self, pallet): + self.touched = True + self.function(pallet) + + def on_screen_exit(self): + self.touched = True + + +def main(): + #Initialisation + difficulty = int(input("What difficulty do you want to play on? " + + "Input: 0 for two-player mode, 1-4 for AI difficulty setting.\n")) + al_install_system(ALLEGRO_VERSION_INT, None) + + w, h = 800, 600 + #Make lines draw smoother + al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST) + al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST) + display = al_create_display(w, h) + + al_init_primitives_addon() + al_install_keyboard() + al_init_image_addon() + al_init_font_addon() + + font = al_load_font(os.path.join(examples_data, "fixed_font.tga"), 0, 0) + + finished = False + need_redraw = True + FPS = 60 + pallet_w, pallet_h, pallet_speed = 20, 80, 5 + ball_size, ball_speed = 30, 4.6 + players = [] + players.append(Player(0, h / 2 - pallet_h / 2, + pallet_w, pallet_h, pallet_speed, + ALLEGRO_KEY_W, ALLEGRO_KEY_S, al_map_rgb_f(1.0, 0.0, 0.0))) + ball = Ball(w / 2, h / 2, ball_speed, ball_size, players, + al_map_rgb_f(0, 1.0, 0)) + if not difficulty: + players.append(Player(w - pallet_w, h / 2 - pallet_h / 2, + pallet_w, pallet_h, + pallet_speed, ALLEGRO_KEY_UP, ALLEGRO_KEY_DOWN, + al_map_rgb_f(0.0, 0.0, 1.0))) + else: + players.append(AI(w - pallet_w, h / 2 - pallet_h / 2, pallet_w, + pallet_h, pallet_speed, al_map_rgb_f(0.0, 0.0, 1.0), + difficulty, ball)) + + def upgrade_grow_height(pallet): + pallet.h *= 1.25 + + def upgrade_shrink_height(pallet): + pallet.h *= 0.8 + + def upgrade_increase_speed(pallet): + pallet.speed *= 1.5 + + def upgrade_decrease_speed(pallet): + pallet.speed /= 1.5 + + upgrade_types = [ + (al_map_rgb_f(0.0, 1.0, 0.0), upgrade_grow_height), + (al_map_rgb_f(1.0, 0.0, 0.0), upgrade_shrink_height), + (al_map_rgb_f(1.0, 1.0, 1.0), upgrade_increase_speed), + (al_map_rgb_f(0.3, 0.3, 0.3), upgrade_decrease_speed)] + upgrade_probability = 0.005 + + timer = al_create_timer(1.0 / FPS) + + queue = al_create_event_queue() + al_register_event_source(queue, al_get_timer_event_source(timer)) + al_register_event_source(queue, al_get_keyboard_event_source()) + al_register_event_source(queue, al_get_display_event_source(display)) + + al_start_timer(timer) + + upgrades = [] + + score = [0, 0] + + while True: + if need_redraw and al_is_event_queue_empty(queue): + al_clear_to_color(al_map_rgb_f(0, 0, 0)) + for player in players: + player.draw() + ball.draw() + for upgrade in upgrades: + upgrade.draw() + if not finished: + al_draw_text(font, al_map_rgb_f(1, 1, 1), w / 2, 10, + ALLEGRO_ALIGN_CENTRE, "Player 1: use W and S to move, " + + "Player 2: use the up and down arrow keys.") + else: + al_draw_text(font, al_map_rgb_f(1, 1, 1), w / 2, 10, + ALLEGRO_ALIGN_CENTRE, "Press R to reset, ESC to exit.") + al_draw_text(font, al_map_rgb_f(1, 1, 1), w / 2, h - 20, + ALLEGRO_ALIGN_CENTRE, "{0} - {1}".format(*score)) + al_flip_display() + need_redraw = False + + ev = ALLEGRO_EVENT() + al_wait_for_event(queue, byref(ev)) + + if ev.type == ALLEGRO_EVENT_TIMER: + for player in players: + player.update() + ball.update() + if ball.x + ball.size < 0 or ball.x > w: + finished = True + score[ball.x < 0] += 1 + al_stop_timer(timer) + for upgrade in upgrades: + upgrade.update() + if upgrade.touched: + upgrades.remove(upgrade) + if random() < upgrade_probability: + i = randint(0, len(upgrade_types) - 1) + upgrades.append(Upgrade(w / 2, h / 2, ball_speed, + players, upgrade_types[i][0], upgrade_types[i][1])) + need_redraw = True + elif (ev.type == ALLEGRO_EVENT_KEY_DOWN and + ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) or\ + ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE: + break + elif ev.type == ALLEGRO_EVENT_KEY_DOWN and\ + ev.keyboard.keycode == ALLEGRO_KEY_R: + ball.x = w / 2 + ball.y = h / 2 + ball.speed = ball_speed + upgrades = [] + for player in players: + player.reset() + al_start_timer(timer) + finished = False + + for player in players: + player.handle_event(ev) + + al_uninstall_system() + + +if __name__ == '__main__': + #Only start the game when this file is executed directly. + al_main(main) diff --git a/allegro/python/readme.txt b/allegro/python/readme.txt new file mode 100644 index 00000000..1828e7fe --- /dev/null +++ b/allegro/python/readme.txt @@ -0,0 +1,111 @@ +# Python wrapper + +This wrapper is not a proper Python-Allegro, but a simple 1:1 export +of all Allegro functions and constants using ctypes. + +## Building + +Enable WANT_PYTHON_WRAPPER in cmake and you should end up with a +single file called allegro.py in the python folder of your build +directory. You also need to build the shared version so you end up +with either: + +Windows: liballegro*.dll +OSX: liballegro*.dylib +Unix: liballegro*.so + +For simplicity we will simply call those files "DLL files". + +## Using it + +Distribute the allegro.py as well as the required DLL files along with +your project. If you want you can modify it to directly point to the +DLL files so you can be sure they are found. By default, it will try +several system specific locations. + +E.g. in linux it will find .so files as long as they are in +LD_LIBRARY_PATH or in ldconfig paths. For distribution build of your +game, this usually means that the .so files are found within your +distributions /usr/lib directory. For a standalone distribution, you +may provide a shell script which modifies LD_LIBRARY_PATH to point +to your game's library folder then runs the python executable. + +To run the included Python example something like this will work under +Linux, starting within the Allegro source distribution folder: + + mkdir build + cd build + cmake -D WANT_PYTHON_WRAPPER=1 .. + make + export PYTHONPATH=python/ + export LD_LIBRARY_PATH=lib/ + python ../python/ex_draw_bitmap.py + +We use PYTHONPATH to specify the location of the allegro.py module and +LD_LIBRARY_PATH to specify the location of the .so files. + +For OSX, this should work: + + mkdir build + cd build + cmake -D WANT_PYTHON_WRAPPER=1 .. + make + export PYTHONPATH=python/ + export DYLD_LIBRARY_PATH=lib/ + python ../python/ex_draw_bitmap.py + +For Windows: + +Make sure to have WANT_PYTHON_WRAPPER enabled when building. It doesn't +matter whether you use mingw or MSVC, but Python must be installed on +your system. + +Then run ex_draw_bitmap.py. The DLLs as well as allegro.py must be +found, easiest is to just have them all in the same directory. Or +you can also edit allegro.py and specify a directory from which to +load the DLLs - see the comments in there. + +## Limitations + +Right now this is only a proof-of concept implementation, some +important things still have to be fixed: + +### Variable arguments not parsed properly yet + +For example, if C code has: + +al_draw_textf(font, x, y, flags, "%d, %d", x, y); + +You have to do it like this in Python right now: + +al_draw_textf(font, x, y, flags, "%s", "%d, %d" % (x, y)) + +### No reference counting or garbage collection + +For example, if you call al_load_bitmap, a C pointer is returned. If +it goes out of scope you end up with a memory leak - very unpythonic. + +Therefore you should do something like this: + + class Bitmap: + + def __init__(self, filename): + self.c_pointer = al_load_bitmap(filename) + + def __del__(self): + al_destroy_bitmap(self.c_pointer) + + def draw(self, x, y, flags): + al_draw_bitmap(self.c_pointer, x, y, flags); + +In other words, make a proper Python wrapper. + +### No docstrings + +Even though the documentation system provides the description of +each functions it's not copied into allegro.py right now. You will +need to use the C documentation until this is fixed. + +### Need more examples + +Or a demo game. It should test that at least each addon can be used. diff --git a/allegro/src/allegro.c b/allegro/src/allegro.c new file mode 100644 index 00000000..b63c50f7 --- /dev/null +++ b/allegro/src/allegro.c @@ -0,0 +1,54 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Assorted routines. + * + * By Shawn Hargreaves and Allegro developers. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/platform/alplatf.h" +#include "allegro5/internal/aintern.h" +#include ALLEGRO_INTERNAL_HEADER + + +/* Function: al_get_allegro_version + */ +uint32_t al_get_allegro_version(void) +{ + return ALLEGRO_VERSION_INT; +} + + + +/* Function: al_run_main + */ +int al_run_main(int argc, char **argv, int (*user_main)(int, char **)) +{ +#ifdef ALLEGRO_MACOSX + return _al_osx_run_main(argc, argv, user_main); +#else + return user_main(argc, argv); +#endif +} + +int _al_get_least_multiple(int val, int mul) +{ + int rem = val % mul; + if (rem == 0) + return val; + else + return val + mul - rem; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_apk_file.c b/allegro/src/android/android_apk_file.c new file mode 100644 index 00000000..84aaf199 --- /dev/null +++ b/allegro/src/android/android_apk_file.c @@ -0,0 +1,312 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_android.h" +#include "allegro5/internal/aintern_android.h" + +#define streq(a, b) (0 == strcmp(a, b)) + +ALLEGRO_DEBUG_CHANNEL("android") + + +typedef struct ALLEGRO_FILE_APK ALLEGRO_FILE_APK; + +struct ALLEGRO_FILE_APK +{ + jobject apk; + bool error_indicator; +}; + + +static ALLEGRO_FILE_APK *cast_stream(ALLEGRO_FILE *f) +{ + return (ALLEGRO_FILE_APK *)al_get_file_userdata(f); +} + + +static void apk_set_errno(ALLEGRO_FILE_APK *fp) +{ + al_set_errno(-1); + + if (fp) { + fp->error_indicator = true; + } +} + + +static jobject APK_openRead(const char *filename) +{ + JNIEnv *jnienv; + jmethodID ctor; + jstring str; + jobject is, ref; + jboolean res; + + jnienv = _al_android_get_jnienv(); + ctor = _jni_call(jnienv, jclass, GetMethodID, + _al_android_apk_stream_class(), "", + "(L" ALLEGRO_ANDROID_PACKAGE_NAME_SLASH "/AllegroActivity;Ljava/lang/String;)V"); + str = (*jnienv)->NewStringUTF(jnienv, filename); + + ref = _jni_call(jnienv, jobject, NewObject, _al_android_apk_stream_class(), + ctor, _al_android_activity_object(), str); + + is = _jni_call(jnienv, jobject, NewGlobalRef, ref); + _jni_callv(jnienv, DeleteLocalRef, ref); + _jni_callv(jnienv, DeleteLocalRef, str); + + res = _jni_callBooleanMethodV(_al_android_get_jnienv(), is, "open", "()Z"); + + return (res) ? is : NULL; +} + + +static bool APK_close(jobject apk_stream) +{ + jboolean ret = _jni_callBooleanMethodV(_al_android_get_jnienv(), apk_stream, + "close", "()Z"); + _jni_callv(_al_android_get_jnienv(), DeleteGlobalRef, apk_stream); + + if (ret) { + apk_set_errno(NULL); + } + return ret; +} + + +static bool APK_seek(jobject apk_stream, long bytes) +{ + jboolean res = _jni_callBooleanMethodV(_al_android_get_jnienv(), + apk_stream, "seek", "(J)Z", (jlong)bytes); + return res; +} + + +static long APK_tell(jobject apk_stream) +{ + long res = _jni_callLongMethodV(_al_android_get_jnienv(), + apk_stream, "tell", "()J"); + return res; +} + + +static int APK_read(jobject apk_stream, char *buf, int len) +{ + JNIEnv *jnienv = _al_android_get_jnienv(); + + jbyteArray b = (*jnienv)->NewByteArray(jnienv, len); + + jint res = _jni_callIntMethodV(jnienv, apk_stream, "read", "([B)I", b); + + if (res > 0) { + (*jnienv)->GetByteArrayRegion(jnienv, b, 0, res, (jbyte *)buf); + } + + _jni_callv(jnienv, DeleteLocalRef, b); + + return res; +} + + +static long APK_size(jobject apk_stream) +{ + long res = _jni_callLongMethod(_al_android_get_jnienv(), apk_stream, "size"); + return res; +} + + +static void *file_apk_fopen(const char *filename, const char *mode) +{ + ALLEGRO_FILE_APK *fp; + jobject apk; + + if (streq(mode, "r") || streq(mode, "rb")) + apk = APK_openRead(filename); + else + return NULL; + + if (!apk) { + apk_set_errno(NULL); + return NULL; + } + + fp = al_malloc(sizeof(*fp)); + if (!fp) { + al_set_errno(ENOMEM); + APK_close(apk); + return NULL; + } + + fp->apk = apk; + fp->error_indicator = false; + + return fp; +} + + +static bool file_apk_fclose(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_APK *fp = cast_stream(f); + bool ret; + + ret = APK_close(fp->apk); + + al_free(fp); + + return ret; +} + + +static size_t file_apk_fread(ALLEGRO_FILE *f, void *buf, size_t buf_size) +{ + ALLEGRO_FILE_APK *fp = cast_stream(f); + int n; + + if (buf_size == 0) + return 0; + + n = APK_read(fp->apk, buf, buf_size); + if (n < 0) { + apk_set_errno(fp); + return 0; + } + return n; +} + + +static size_t file_apk_fwrite(ALLEGRO_FILE *f, const void *buf, + size_t buf_size) +{ + // Not supported + (void)f; + (void)buf; + (void)buf_size; + return 0; +} + + +static bool file_apk_fflush(ALLEGRO_FILE *f) +{ + // Not supported + (void)f; + return true; +} + + +static int64_t file_apk_ftell(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_APK *fp = cast_stream(f); + return APK_tell(fp->apk); +} + + +static bool file_apk_seek(ALLEGRO_FILE *f, int64_t offset, int whence) +{ + ALLEGRO_FILE_APK *fp = cast_stream(f); + long base; + + switch (whence) { + case ALLEGRO_SEEK_SET: + base = 0; + break; + + case ALLEGRO_SEEK_CUR: + base = APK_tell(fp->apk); + if (base < 0) { + apk_set_errno(fp); + return false; + } + break; + + case ALLEGRO_SEEK_END: + base = APK_size(fp->apk); + if (base < 0) { + apk_set_errno(fp); + return false; + } + break; + + default: + al_set_errno(EINVAL); + return false; + } + + if (!APK_seek(fp->apk, base + offset)) { + apk_set_errno(fp); + return false; + } + + return true; +} + + +static bool file_apk_feof(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_APK *fp = cast_stream(f); + jboolean res = _jni_callBooleanMethodV(_al_android_get_jnienv(), fp->apk, + "eof", "()Z"); + return res; +} + + +static int file_apk_ferror(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_APK *fp = cast_stream(f); + + return (fp->error_indicator) ? 1 : 0; +} + + +static const char *file_apk_ferrmsg(ALLEGRO_FILE *f) +{ + (void)f; + return ""; +} + + +static void file_apk_fclearerr(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_APK *fp = cast_stream(f); + + fp->error_indicator = false; +} + + +static off_t file_apk_fsize(ALLEGRO_FILE *f) +{ + ALLEGRO_FILE_APK *fp = cast_stream(f); + return APK_size(fp->apk); +} + + +static const ALLEGRO_FILE_INTERFACE file_apk_vtable = +{ + file_apk_fopen, + file_apk_fclose, + file_apk_fread, + file_apk_fwrite, + file_apk_fflush, + file_apk_ftell, + file_apk_seek, + file_apk_feof, + file_apk_ferror, + file_apk_ferrmsg, + file_apk_fclearerr, + NULL, /* default ungetc implementation */ + file_apk_fsize +}; + + +const ALLEGRO_FILE_INTERFACE *_al_get_apk_file_vtable(void) +{ + return &file_apk_vtable; +} + + +/* Function: al_android_set_apk_file_interface + */ +void al_android_set_apk_file_interface(void) +{ + al_set_new_file_interface(&file_apk_vtable); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_apk_fs.c b/allegro/src/android/android_apk_fs.c new file mode 100644 index 00000000..21d86f05 --- /dev/null +++ b/allegro/src/android/android_apk_fs.c @@ -0,0 +1,308 @@ +/* + * Filesystem driver for APK contents. + * + * By Elias Pschernig. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_android.h" +#include "allegro5/internal/aintern_android.h" + +#include + +ALLEGRO_DEBUG_CHANNEL("android") + +typedef struct ALLEGRO_FS_ENTRY_APK ALLEGRO_FS_ENTRY_APK; + +struct ALLEGRO_FS_ENTRY_APK +{ + ALLEGRO_FS_ENTRY fs_entry; /* must be first */ + ALLEGRO_PATH *path; + const char *path_cstr; + + /* For directory listing. */ + char *file_list; + char *file_list_pos; + bool is_dir_open; +}; + +/* forward declaration */ +static const ALLEGRO_FS_INTERFACE fs_apk_vtable; + +/* current working directory */ +/* TODO: free this somewhere */ +static ALLEGRO_USTR *fs_apk_cwd_ustr; + +static ALLEGRO_FILE *fs_apk_open_file(ALLEGRO_FS_ENTRY *fse, const char *mode); + +static ALLEGRO_USTR *get_fake_cwd(void) { + if (!fs_apk_cwd_ustr) { + fs_apk_cwd_ustr = al_ustr_new("/"); + } + return fs_apk_cwd_ustr; +} + +static bool path_is_absolute(const char *path) +{ + return (path && path[0] == '/'); +} + +static void ensure_trailing_slash(ALLEGRO_USTR *us) +{ + int pos = al_ustr_size(us); + if (al_ustr_prev_get(us, &pos) != '/') { + al_ustr_append_chr(us, '/'); + } +} + +static ALLEGRO_USTR *apply_cwd(const char *path) +{ + ALLEGRO_USTR *us; + + if (path_is_absolute(path)) { + return al_ustr_new(path); + } + + us = al_ustr_dup(get_fake_cwd()); + al_ustr_append_cstr(us, path); + return us; +} + +static ALLEGRO_FS_ENTRY *fs_apk_create_entry(const char *path) +{ + ALLEGRO_FS_ENTRY_APK *e; + ALLEGRO_USTR *us; + + e = al_calloc(1, sizeof *e); + if (!e) + return NULL; + e->fs_entry.vtable = &fs_apk_vtable; + + us = apply_cwd(path); + e->path = al_create_path(al_cstr(us)); + al_ustr_free(us); + if (!e->path) { + al_free(e); + return NULL; + } + e->path_cstr = al_path_cstr(e->path, '/'); + + return &e->fs_entry; +} + +static char *fs_apk_get_current_directory(void) +{ + return al_cstr_dup(get_fake_cwd()); +} + +static bool fs_apk_change_directory(const char *path) +{ + ALLEGRO_USTR *us; + ALLEGRO_USTR *cwd = get_fake_cwd(); + + /* Figure out which directory we are trying to change to. */ + if (path_is_absolute(path)) + us = al_ustr_new(path); + else + us = apply_cwd(path); + + ensure_trailing_slash(us); + + al_ustr_assign(cwd, us); + + al_ustr_free(us); + + return true; +} + +static bool fs_apk_remove_filename(const char *path) +{ + (void)path; + return false; +} + +static bool fs_apk_make_directory(const char *path) +{ + (void)path; + return false; +} + +static const char *fs_apk_entry_name(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_APK *e = (ALLEGRO_FS_ENTRY_APK *)fse; + return al_path_cstr(e->path, '/'); +} + +static bool fs_apk_update_entry(ALLEGRO_FS_ENTRY *fse) +{ + (void)fse; + return true; +} + +static off_t fs_apk_entry_size(ALLEGRO_FS_ENTRY *fse) +{ + // Only way to determine the size would be to read the file... + // we won't do that. + (void)fse; + return 0; +} + +static uint32_t fs_apk_entry_mode(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_APK *e = (ALLEGRO_FS_ENTRY_APK *)fse; + uint32_t mode = ALLEGRO_FILEMODE_READ; + int n = strlen(e->path_cstr); + if (e->path_cstr[n - 1] == '/') + mode |= ALLEGRO_FILEMODE_ISDIR | ALLEGRO_FILEMODE_EXECUTE; + else + mode |= ALLEGRO_FILEMODE_ISFILE; + return mode; +} + +static time_t fs_apk_entry_mtime(ALLEGRO_FS_ENTRY *fse) +{ + (void)fse; + return 0; +} + +static bool fs_apk_entry_exists(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FILE *f = fs_apk_open_file(fse, "r"); + if (f) { + al_fclose(f); + return true; + } + return false; +} + +static bool fs_apk_remove_entry(ALLEGRO_FS_ENTRY *fse) +{ + (void)fse; + return false; +} + +static bool fs_apk_open_directory(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_APK *e = (ALLEGRO_FS_ENTRY_APK *)fse; + + JNIEnv *jnienv; + jnienv = _al_android_get_jnienv(); + jstring jpath = (*jnienv)->NewStringUTF(jnienv, e->path_cstr); + jstring js = _jni_callStaticObjectMethodV(jnienv, + _al_android_apk_fs_class(), "list", + "(L" ALLEGRO_ANDROID_PACKAGE_NAME_SLASH "/AllegroActivity;Ljava/lang/String;)Ljava/lang/String;", + _al_android_activity_object(), jpath); + + const char *cs = _jni_call(jnienv, const char *, GetStringUTFChars, js, NULL); + e->file_list = al_malloc(strlen(cs) + 1); + strcpy(e->file_list, cs); + e->file_list_pos = e->file_list; + + _jni_callv(jnienv, ReleaseStringUTFChars, js, cs); + _jni_callv(jnienv, DeleteLocalRef, js); + _jni_callv(jnienv, DeleteLocalRef, jpath); + + e->is_dir_open = true; + return true; +} + +static ALLEGRO_FS_ENTRY *fs_apk_read_directory(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_APK *e = (ALLEGRO_FS_ENTRY_APK *)fse; + ALLEGRO_FS_ENTRY *next; + ALLEGRO_USTR *tmp; + + if (!e->file_list_pos) + return NULL; + if (!*e->file_list_pos) + return NULL; + + tmp = al_ustr_new(e->path_cstr); + ensure_trailing_slash(tmp); + char *name = e->file_list_pos; + char *semi = strchr(name, ';'); + if (semi) { + *semi = 0; + e->file_list_pos = semi + 1; + } + else { + e->file_list_pos = name + strlen(name); + } + al_ustr_append_cstr(tmp, name); + next = fs_apk_create_entry(al_cstr(tmp)); + al_ustr_free(tmp); + + return next; +} + +static bool fs_apk_close_directory(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_APK *e = (ALLEGRO_FS_ENTRY_APK *)fse; + al_free(e->file_list); + e->file_list = NULL; + e->is_dir_open = false; + return true; +} + +static void fs_apk_destroy_entry(ALLEGRO_FS_ENTRY *fse) +{ + ALLEGRO_FS_ENTRY_APK *e = (ALLEGRO_FS_ENTRY_APK *)fse; + if (e->is_dir_open) + fs_apk_close_directory(fse); + al_destroy_path(e->path); + al_free(e); +} + +static ALLEGRO_FILE *fs_apk_open_file(ALLEGRO_FS_ENTRY *fse, const char *mode) +{ + return al_fopen_interface(_al_get_apk_file_vtable(), fs_apk_entry_name(fse), + mode); +} + +static bool fs_apk_filename_exists(const char *path) +{ + bool ret; + + ALLEGRO_FS_ENTRY *e = fs_apk_create_entry(path); + ret = fs_apk_entry_exists(e); + fs_apk_destroy_entry(e); + return ret; +} + +static const ALLEGRO_FS_INTERFACE fs_apk_vtable = +{ + fs_apk_create_entry, + fs_apk_destroy_entry, + fs_apk_entry_name, + fs_apk_update_entry, + fs_apk_entry_mode, + fs_apk_entry_mtime, + fs_apk_entry_mtime, + fs_apk_entry_mtime, + fs_apk_entry_size, + fs_apk_entry_exists, + fs_apk_remove_entry, + + fs_apk_open_directory, + fs_apk_read_directory, + fs_apk_close_directory, + + fs_apk_filename_exists, + fs_apk_remove_filename, + fs_apk_get_current_directory, + fs_apk_change_directory, + fs_apk_make_directory, + + fs_apk_open_file +}; + +/* Function: al_android_set_apk_fs_interface + */ +void al_android_set_apk_fs_interface(void) +{ + al_set_fs_interface(&fs_apk_vtable); +} + +/* vim: set sts=3 sw=3 et: */ + diff --git a/allegro/src/android/android_clipboard.c b/allegro/src/android/android_clipboard.c new file mode 100644 index 00000000..d5255f0d --- /dev/null +++ b/allegro/src/android/android_clipboard.c @@ -0,0 +1,71 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_//_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android clipboard handling. + * + * By Beoran. + * + * See readme.txt for copyright information. + */ + + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_android.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_android.h" +#include "allegro5/internal/aintern_bitmap.h" + +#include + +ALLEGRO_DEBUG_CHANNEL("clipboard") + +static bool android_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text) +{ + JNIEnv * env = (JNIEnv *)_al_android_get_jnienv(); + jstring jtext= _jni_call(env, jstring, NewStringUTF, text); + (void) display; + return _jni_callBooleanMethodV(env, _al_android_activity_object(), + "setClipboardText", "(Ljava/lang/String;)Z", jtext); +} + +static char *android_get_clipboard_text(ALLEGRO_DISPLAY *display) +{ + JNIEnv * env = (JNIEnv *)_al_android_get_jnienv(); + jobject jtext = _jni_callObjectMethod(env, _al_android_activity_object(), "getClipboardText", "()Ljava/lang/String;"); + jsize len = _jni_call(env, jsize, GetStringUTFLength, jtext); + const char *str = _jni_call(env, const char *, GetStringUTFChars, jtext, NULL); + char * text = al_malloc(len+1); + (void) display; + + text = _al_sane_strncpy(text, str, len); + _jni_callv(env, ReleaseStringUTFChars, jtext, str); + _jni_callv(env, DeleteLocalRef, jtext); + + return text; +} + +static bool android_has_clipboard_text(ALLEGRO_DISPLAY *display) +{ + JNIEnv * env = (JNIEnv *)_al_android_get_jnienv(); + (void) display; + return _jni_callBooleanMethodV(env, _al_android_activity_object(), + "hasClipboardText", "()Z"); +} + + +void _al_android_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt) +{ + vt->set_clipboard_text = android_set_clipboard_text; + vt->get_clipboard_text = android_get_clipboard_text; + vt->has_clipboard_text = android_has_clipboard_text; +} + +/* vi: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_display.c b/allegro/src/android/android_display.c new file mode 100644 index 00000000..7ef3bc2c --- /dev/null +++ b/allegro/src/android/android_display.c @@ -0,0 +1,961 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android Java/JNI display driver + * + * By Thomas Fjellstrom. + * + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_android.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_shader.h" +#include "allegro5/internal/aintern_pixels.h" + +#include "EGL/egl.h" + +ALLEGRO_DEBUG_CHANNEL("display") + +static ALLEGRO_DISPLAY_INTERFACE *vt; +static ALLEGRO_EXTRA_DISPLAY_SETTINGS main_thread_display_settings; + +static int select_best_visual_and_update(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d); +static void android_set_display_option(ALLEGRO_DISPLAY *d, int o, int v); +static void _al_android_resize_display(ALLEGRO_DISPLAY_ANDROID *d, int width, int height); +static bool _al_android_init_display(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *display); +void _al_android_clear_current(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d); +void _al_android_make_current(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d); + +JNI_FUNC(void, AllegroSurface, nativeOnCreate, (JNIEnv *env, jobject obj)) +{ + ALLEGRO_DEBUG("nativeOnCreate"); + (void)env; + (void)obj; + + ALLEGRO_SYSTEM *system = (void *)al_get_system_driver(); + ASSERT(system != NULL); + + ALLEGRO_DEBUG("AllegroSurface_nativeOnCreate"); + + ALLEGRO_DISPLAY_ANDROID **dptr = _al_vector_ref(&system->displays, 0); + ALLEGRO_DISPLAY_ANDROID *d = *dptr; + ASSERT(d != NULL); + + d->recreate = true; +} + +JNI_FUNC(bool, AllegroSurface, nativeOnDestroy, (JNIEnv *env, jobject obj)) +{ + ALLEGRO_SYSTEM *sys = (void *)al_get_system_driver(); + ASSERT(sys != NULL); + + ALLEGRO_DISPLAY_ANDROID **dptr = _al_vector_ref(&sys->displays, 0); + ALLEGRO_DISPLAY_ANDROID *display = *dptr; + ASSERT(display != NULL); + + ALLEGRO_DISPLAY *d = (ALLEGRO_DISPLAY *)display; + + ALLEGRO_DEBUG("AllegroSurface_nativeOnDestroy"); + (void)obj; + (void)env; + + if (!display->created) { + ALLEGRO_DEBUG("Display creation failed, not sending HALT"); + return false; + } + + display->created = false; + + if (display->is_destroy_display) { + return true; + } + + ALLEGRO_DEBUG("locking display event source: %p %p", d, &d->es); + + _al_event_source_lock(&d->es); + + if (_al_event_source_needs_to_generate_event(&d->es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_HALT_DRAWING; + event.display.timestamp = al_current_time(); + _al_event_source_emit_event(&d->es, &event); + } + + ALLEGRO_DEBUG("unlocking display event source"); + _al_event_source_unlock(&d->es); + + // wait for acknowledge_drawing_halt + al_lock_mutex(display->mutex); + al_wait_cond(display->cond, display->mutex); + al_unlock_mutex(display->mutex); + + ALLEGRO_DEBUG("AllegroSurface_nativeOnDestroy end"); + + return true; +} + +// FIXME: need to loop over the display list looking for the right surface +// object in the following jni callbacks +JNI_FUNC(void, AllegroSurface, nativeOnChange, (JNIEnv *env, jobject obj, + jint format, jint width, jint height)) +{ + ALLEGRO_SYSTEM *system = (void *)al_get_system_driver(); + ASSERT(system != NULL); + + ALLEGRO_DISPLAY_ANDROID **dptr = _al_vector_ref(&system->displays, 0); + ALLEGRO_DISPLAY_ANDROID *d = *dptr; + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY*)d; + ASSERT(display != NULL); + + ALLEGRO_DEBUG("on change %dx%d!", width, height); + (void)format; + + if (!d->first_run && !d->recreate) { + _al_android_resize_display(d, width, height); + return; + } + + al_lock_mutex(d->mutex); + + if (d->first_run || d->recreate) { + d->surface_object = (*env)->NewGlobalRef(env, obj); + if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) { + display->w = width; + display->h = height; + } + } + + bool ret = _al_android_init_display(env, d); + if (!ret && d->first_run) { + al_broadcast_cond(d->cond); + al_unlock_mutex(d->mutex); + return; + } + + _al_android_clear_current(env, d); + + d->created = true; + d->recreate = false; + d->resumed = false; + + if (!d->first_run) { + ALLEGRO_DEBUG("locking display event source: %p", d); + _al_event_source_lock(&display->es); + + ALLEGRO_DEBUG("check generate event"); + if (_al_event_source_needs_to_generate_event(&display->es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING; + event.display.timestamp = al_current_time(); + _al_event_source_emit_event(&display->es, &event); + } + + ALLEGRO_DEBUG("unlocking display event source"); + _al_event_source_unlock(&display->es); + } + + if (d->first_run) { + al_broadcast_cond(d->cond); + d->first_run = false; + } + else { + ALLEGRO_DEBUG("Waiting for al_acknowledge_drawing_resume"); + while (!d->resumed) { + al_wait_cond(d->cond, d->mutex); + } + ALLEGRO_DEBUG("Got al_acknowledge_drawing_resume"); + } + + al_unlock_mutex(d->mutex); + + /* Send a resize event to signify that the display may have changed sizes. */ + if (!d->first_run) { + _al_android_resize_display(d, width, height); + } +} + +JNI_FUNC(void, AllegroSurface, nativeOnJoystickAxis, (JNIEnv *env, jobject obj, + jint index, jint stick, jint axis, jfloat value)) +{ + (void)env; + (void)obj; + _al_android_generate_joystick_axis_event(index+1, stick, axis, value); +} + +JNI_FUNC(void, AllegroSurface, nativeOnJoystickButton, (JNIEnv *env, jobject obj, + jint index, jint button, jboolean down)) +{ + (void)env; + (void)obj; + _al_android_generate_joystick_button_event(index+1, button, down); +} + +void _al_android_create_surface(JNIEnv *env, bool post) +{ + if (post) { + _jni_callVoidMethod(env, _al_android_activity_object(), + "postCreateSurface"); + } + else { + _jni_callVoidMethod(env, _al_android_activity_object(), + "createSurface"); + } +} + +void _al_android_destroy_surface(JNIEnv *env, jobject surface, bool post) +{ + (void)surface; + if (post) { + _jni_callVoidMethodV(env, _al_android_activity_object(), + "postDestroySurface", "()V"); + } + else { + _jni_callVoidMethodV(env, _al_android_activity_object(), + "destroySurface", "()V"); + } +} + +void _al_android_make_current(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d) +{ + _jni_callVoidMethodV(env, d->surface_object, "egl_makeCurrent", "()V"); +} + +void _al_android_clear_current(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d) +{ + _jni_callVoidMethodV(env, d->surface_object, "egl_clearCurrent", "()V"); +} + +static bool _al_android_init_display(JNIEnv *env, + ALLEGRO_DISPLAY_ANDROID *display) +{ + ALLEGRO_SYSTEM_ANDROID *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY *d = (ALLEGRO_DISPLAY *)display; + int config_index; + bool programmable_pipeline; + int ret; + + ASSERT(system != NULL); + ASSERT(display != NULL); + + ALLEGRO_DEBUG("calling egl_Init"); + + if (!_jni_callBooleanMethodV(env, display->surface_object, + "egl_Init", "()Z")) + { + // XXX should probably destroy the AllegroSurface here + ALLEGRO_ERROR("failed to initialize EGL"); + display->failed = true; + return false; + } + + config_index = select_best_visual_and_update(env, display); + if (config_index < 0) { + // XXX should probably destroy the AllegroSurface here + ALLEGRO_ERROR("Failed to choose config.\n"); + display->failed = true; + return false; + } + + programmable_pipeline = (d->flags & ALLEGRO_PROGRAMMABLE_PIPELINE); + + ALLEGRO_DEBUG("calling egl_createContext"); + ret = _jni_callIntMethodV(env, display->surface_object, + "egl_createContext", "(IZ)I", config_index, programmable_pipeline); + if (!ret) { + // XXX should probably destroy the AllegroSurface here + ALLEGRO_ERROR("failed to create egl context!"); + display->failed = true; + return false; + } + + ALLEGRO_DEBUG("calling egl_createSurface"); + if (!_jni_callBooleanMethodV(env, display->surface_object, + "egl_createSurface", "()Z")) + { + // XXX should probably destroy the AllegroSurface here + ALLEGRO_ERROR("failed to create egl surface!"); + display->failed = true; + return false; + } + + ALLEGRO_DEBUG("initialize ogl extensions"); + _al_ogl_manage_extensions(d); + _al_ogl_set_extensions(d->ogl_extras->extension_api); + + _al_ogl_setup_gl(d); + + return true; +} + + +/* implementation helpers */ + +static void _al_android_resize_display(ALLEGRO_DISPLAY_ANDROID *d, + int width, int height) +{ + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)d; + bool emitted_event = true; + + ALLEGRO_DEBUG("display resize"); + + d->resize_acknowledge = false; + d->resize_acknowledge2 = false; + + ALLEGRO_DEBUG("locking mutex"); + al_lock_mutex(d->mutex); + ALLEGRO_DEBUG("done locking mutex"); + + ALLEGRO_DEBUG("locking display event source: %p", d); + _al_event_source_lock(&display->es); + + ALLEGRO_DEBUG("check generate event"); + if(_al_event_source_needs_to_generate_event(&display->es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; + event.display.timestamp = al_current_time(); + event.display.x = 0; // FIXME: probably not correct + event.display.y = 0; + event.display.width = width; + event.display.height = height; + event.display.orientation = _al_android_get_display_orientation(); + _al_event_source_emit_event(&display->es, &event); + } + else { + emitted_event = false; + } + + ALLEGRO_DEBUG("unlocking display event source"); + _al_event_source_unlock(&display->es); + + if (emitted_event) { + ALLEGRO_DEBUG("waiting for display resize acknowledge"); + while (!d->resize_acknowledge) { + ALLEGRO_DEBUG("calling al_wait_cond"); + al_wait_cond(d->cond, d->mutex); + } + al_unlock_mutex(d->mutex); + ALLEGRO_DEBUG("done waiting for display resize acknowledge"); + } + + display->w = width; + display->h = height; + + ALLEGRO_DEBUG("resize backbuffer"); + _al_ogl_setup_gl(display); + + if (emitted_event) { + d->resize_acknowledge2 = true; + al_broadcast_cond(d->cond); + } + + al_unlock_mutex(d->mutex); + + ALLEGRO_DEBUG("done"); +} + +static void call_initRequiredAttribs(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d) +{ + _jni_callVoidMethodV(env, d->surface_object, + "egl_initRequiredAttribs", "()V"); +} + +static void call_setRequiredAttrib(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d, + int attr, int value) +{ + _jni_callVoidMethodV(env, d->surface_object, + "egl_setRequiredAttrib", "(II)V", attr, value); +} + +static int call_chooseConfig(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d) +{ + bool pp = (d->display.flags & ALLEGRO_PROGRAMMABLE_PIPELINE); + return _jni_callIntMethodV(env, d->surface_object, + "egl_chooseConfig", "(Z)I", pp); +} + +static void call_getConfigAttribs(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d, + int configIndex, ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) +{ + jintArray jArray; + jint *ptr; + int i; + + jArray = (*env)->NewIntArray(env, ALLEGRO_DISPLAY_OPTIONS_COUNT); + if (jArray == NULL) { + ALLEGRO_ERROR("NewIntArray failed\n"); + return; + } + + _jni_callVoidMethodV(env, d->surface_object, + "egl_getConfigAttribs", "(I[I)V", configIndex, jArray); + + ptr = (*env)->GetIntArrayElements(env, jArray, 0); + for (i = 0; i < ALLEGRO_DISPLAY_OPTIONS_COUNT; i++) { + eds->settings[i] = ptr[i]; + } + + (*env)->ReleaseIntArrayElements(env, jArray, ptr, 0); +} + +static void set_required_attribs(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d, + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref) +{ + #define MAYBE_SET(v) \ + do { \ + bool required = (ref->required & ((int64_t)1 << (v))); \ + if (required) { \ + call_setRequiredAttrib(env, d, (v), ref->settings[(v)]); \ + } \ + } while (0) + + MAYBE_SET(ALLEGRO_RED_SIZE); + MAYBE_SET(ALLEGRO_GREEN_SIZE); + MAYBE_SET(ALLEGRO_BLUE_SIZE); + MAYBE_SET(ALLEGRO_ALPHA_SIZE); + MAYBE_SET(ALLEGRO_COLOR_SIZE); + MAYBE_SET(ALLEGRO_DEPTH_SIZE); + MAYBE_SET(ALLEGRO_STENCIL_SIZE); + MAYBE_SET(ALLEGRO_SAMPLE_BUFFERS); + MAYBE_SET(ALLEGRO_SAMPLES); + + #undef MAYBE_SET +} + +static int select_best_visual_and_update(JNIEnv *env, + ALLEGRO_DISPLAY_ANDROID *d) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref = &main_thread_display_settings; + ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds = NULL; + int num_configs; + int chosen_index; + int i; + + ALLEGRO_DEBUG("Setting required display settings.\n"); + call_initRequiredAttribs(env, d); + set_required_attribs(env, d, ref); + + ALLEGRO_DEBUG("Calling eglChooseConfig.\n"); + num_configs = call_chooseConfig(env, d); + if (num_configs < 1) { + return -1; + } + + eds = al_calloc(num_configs, sizeof(*eds)); + + for (i = 0; i < num_configs; i++) { + eds[i] = al_calloc(1, sizeof(*eds[i])); + + call_getConfigAttribs(env, d, i, eds[i]); + + eds[i]->settings[ALLEGRO_RENDER_METHOD] = 1; + eds[i]->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; + eds[i]->settings[ALLEGRO_SWAP_METHOD] = 2; + eds[i]->settings[ALLEGRO_VSYNC] = 1; + + eds[i]->index = i; + eds[i]->score = _al_score_display_settings(eds[i], ref); + } + + ALLEGRO_DEBUG("Sorting configs.\n"); + qsort(eds, num_configs, sizeof(*eds), _al_display_settings_sorter); + + chosen_index = eds[0]->index; + ALLEGRO_INFO("Chose config %i\n", chosen_index); + + d->display.extra_settings = *eds[0]; + + /* Don't need this any more. */ + for (i = 0; i < num_configs; i++) { + al_free(eds[i]); + } + al_free(eds); + + return chosen_index; +} + +/* driver implementation hooks */ + +static bool android_set_display_flag(ALLEGRO_DISPLAY *dpy, int flag, bool onoff) +{ + (void)dpy; (void)flag; (void)onoff; + + if (flag == ALLEGRO_FRAMELESS) { + _jni_callVoidMethodV(_al_android_get_jnienv(), + _al_android_activity_object(), "setAllegroFrameless", "(Z)V", onoff); + } + + return false; +} + +static ALLEGRO_DISPLAY *android_create_display(int w, int h) +{ + ALLEGRO_DEBUG("begin"); + + int flags = al_get_new_display_flags(); +#ifndef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + ALLEGRO_WARN("Programmable pipeline support not built.\n"); + return NULL; + } +#endif + + ALLEGRO_DISPLAY_ANDROID *d = al_malloc(sizeof *d); + ALLEGRO_DISPLAY *display = (void *)d; + + ALLEGRO_OGL_EXTRAS *ogl = al_malloc(sizeof *ogl); + memset(d, 0, sizeof *d); + memset(ogl, 0, sizeof *ogl); + display->ogl_extras = ogl; + display->vt = _al_get_android_display_driver(); + display->w = w; + display->h = h; + display->flags = flags; + + display->flags |= ALLEGRO_OPENGL; +#ifdef ALLEGRO_CFG_OPENGLES2 + display->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + display->flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + + _al_event_source_init(&display->es); + + /* Java thread needs this but it's thread local. + * For now we assume display is created and set up in main thread. + */ + main_thread_display_settings = *_al_get_new_display_settings(); + + d->mutex = al_create_mutex(); + d->cond = al_create_cond(); + d->recreate = true; + d->first_run = true; + d->failed = false; + + ALLEGRO_SYSTEM *system = (void *)al_get_system_driver(); + ASSERT(system != NULL); + + ALLEGRO_DISPLAY_ANDROID **add; + add = _al_vector_alloc_back(&system->displays); + *add = d; + + al_lock_mutex(d->mutex); + + // post create surface request and wait + _al_android_create_surface(_al_android_get_jnienv(), true); + + // wait for sizing to happen + ALLEGRO_DEBUG("waiting for surface onChange"); + while (!d->created && !d->failed) { + al_wait_cond(d->cond, d->mutex); + } + al_unlock_mutex(d->mutex); + ALLEGRO_DEBUG("done waiting for surface onChange"); + + if (d->failed) { + ALLEGRO_DEBUG("Display creation failed"); + _al_vector_find_and_delete(&system->displays, &d); + al_free(ogl); + al_free(d); + return NULL; + } + + ALLEGRO_DEBUG("display: %p %ix%i", display, display->w, display->h); + + _al_android_clear_current(_al_android_get_jnienv(), d); + _al_android_make_current(_al_android_get_jnienv(), d); + + /* Don't need to repeat what this does */ + android_set_display_option(display, ALLEGRO_SUPPORTED_ORIENTATIONS, + al_get_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, NULL)); + + /* Fill in opengl version */ + const int v = d->display.ogl_extras->ogl_info.version; + d->display.extra_settings.settings[ALLEGRO_OPENGL_MAJOR_VERSION] = (v >> 24) & 0xFF; + d->display.extra_settings.settings[ALLEGRO_OPENGL_MINOR_VERSION] = (v >> 16) & 0xFF; + + if (flags & ALLEGRO_FRAMELESS) { + android_set_display_flag(display, ALLEGRO_FRAMELESS, true); + } + + ALLEGRO_DEBUG("end"); + return display; +} + +static void android_destroy_display(ALLEGRO_DISPLAY *dpy) +{ + ALLEGRO_DISPLAY_ANDROID *d = (ALLEGRO_DISPLAY_ANDROID*)dpy; + + ALLEGRO_DEBUG("clear current"); + + if (!d->created) { + // if nativeOnDestroy was called (the app switched out) and + // then the display is destroyed before the app switches back + // in, there is no EGL context to destroy. + goto already_deleted; + } + + _al_android_clear_current(_al_android_get_jnienv(), d); + + al_lock_mutex(d->mutex); + + d->is_destroy_display = true; + + _al_android_destroy_surface(_al_android_get_jnienv(), d, true); + + /* I don't think we can use a condition for this, because there are two + * possibilities of how a nativeOnDestroy/surfaceDestroyed callback can be + * called. One is from here, manually, and one happens automatically and is + * out of our hands. + */ + while (d->created) { + al_rest(0.001); + } + + _al_event_source_free(&dpy->es); + +already_deleted: + // XXX: this causes a crash, no idea why as of yet + //ALLEGRO_DEBUG("destroy backbuffer"); + //_al_ogl_destroy_backbuffer(al_get_backbuffer(dpy)); + + ALLEGRO_DEBUG("destroy mutex"); + al_destroy_mutex(d->mutex); + + ALLEGRO_DEBUG("destroy cond"); + al_destroy_cond(d->cond); + + ALLEGRO_DEBUG("free ogl_extras"); + al_free(dpy->ogl_extras); + + ALLEGRO_DEBUG("remove display from system list"); + ALLEGRO_SYSTEM *s = al_get_system_driver(); + _al_vector_find_and_delete(&s->displays, &d); + + _al_vector_free(&dpy->bitmaps); + al_free(dpy->vertex_cache); + + ALLEGRO_DEBUG("free display"); + al_free(d); + + ALLEGRO_DEBUG("done"); +} + +static bool android_set_current_display(ALLEGRO_DISPLAY *dpy) +{ + ALLEGRO_DEBUG("make current %p", dpy); + + if (al_get_current_display() != NULL){ + _al_android_clear_current(_al_android_get_jnienv(), + (ALLEGRO_DISPLAY_ANDROID *)al_get_current_display()); + } + + if (dpy) { + _al_android_make_current(_al_android_get_jnienv(), + (ALLEGRO_DISPLAY_ANDROID *)dpy); + } + + _al_ogl_update_render_state(dpy); + + return true; +} + +static void android_unset_current_display(ALLEGRO_DISPLAY *dpy) +{ + ALLEGRO_DEBUG("unset current %p", dpy); + _al_android_clear_current(_al_android_get_jnienv(), + (ALLEGRO_DISPLAY_ANDROID *)dpy); +} + +static void android_flip_display(ALLEGRO_DISPLAY *dpy) +{ + // Some Androids crash if you swap buffers with an fbo bound + // so temporarily change target to the backbuffer. + ALLEGRO_BITMAP *old_target = al_get_target_bitmap(); + al_set_target_backbuffer(dpy); + + _jni_callVoidMethod(_al_android_get_jnienv(), + ((ALLEGRO_DISPLAY_ANDROID *)dpy)->surface_object, "egl_SwapBuffers"); + + al_set_target_bitmap(old_target); + + /* Backup bitmaps created without ALLEGRO_NO_PRESERVE_TEXTURE that are + * dirty, to system memory. + */ + al_backup_dirty_bitmaps(dpy); +} + +static void android_update_display_region(ALLEGRO_DISPLAY *dpy, int x, int y, + int width, int height) +{ + (void)x; + (void)y; + (void)width; + (void)height; + android_flip_display(dpy); +} + +static bool android_acknowledge_resize(ALLEGRO_DISPLAY *dpy) +{ + ALLEGRO_DISPLAY_ANDROID *d = (ALLEGRO_DISPLAY_ANDROID *)dpy; + + ALLEGRO_DEBUG("clear current context"); + _al_android_clear_current(_al_android_get_jnienv(), d); + + ALLEGRO_DEBUG("locking mutex"); + al_lock_mutex(d->mutex); + d->resize_acknowledge = true; + al_broadcast_cond(d->cond); + ALLEGRO_DEBUG("broadcasted condvar"); + + ALLEGRO_DEBUG("waiting for display resize acknowledge 2"); + while (!d->resize_acknowledge2) { + ALLEGRO_DEBUG("calling al_wait_cond"); + al_wait_cond(d->cond, d->mutex); + } + al_unlock_mutex(d->mutex); + ALLEGRO_DEBUG("done waiting for display resize acknowledge 2"); + + ALLEGRO_DEBUG("acquire context"); + _al_android_make_current(_al_android_get_jnienv(), d); + + ALLEGRO_DEBUG("done"); + return true; +} + +static int android_get_orientation(ALLEGRO_DISPLAY *dpy) +{ + (void)dpy; + return _al_android_get_display_orientation(); +} + +static bool android_is_compatible_bitmap(ALLEGRO_DISPLAY *dpy, + ALLEGRO_BITMAP *bmp) +{ + (void)dpy; + (void)bmp; + return true; +} + +static bool android_resize_display(ALLEGRO_DISPLAY *dpy, int w, int h) +{ + (void)dpy; + (void)w; + (void)h; + return false; +} + +static void android_set_icons(ALLEGRO_DISPLAY *dpy, int num_icons, + ALLEGRO_BITMAP *bmps[]) +{ + (void)dpy; + (void)num_icons; + (void)bmps; +} + +static void android_set_window_title(ALLEGRO_DISPLAY *dpy, const char *title) +{ + (void)dpy; (void)title; +} + +static void android_set_window_position(ALLEGRO_DISPLAY *dpy, int x, int y) +{ + (void)dpy; + (void)x; + (void)y; +} + +static void android_get_window_position(ALLEGRO_DISPLAY *dpy, int *x, int *y) +{ + (void)dpy; + *x = *y = 0; +} + +static bool android_wait_for_vsync(ALLEGRO_DISPLAY *dpy) +{ + (void)dpy; + return false; +} + +static bool android_set_mouse_cursor(ALLEGRO_DISPLAY *dpy, + ALLEGRO_MOUSE_CURSOR *cursor) +{ + (void)dpy; (void)cursor; + return false; +} + +static bool android_set_system_mouse_cursor(ALLEGRO_DISPLAY *dpy, + ALLEGRO_SYSTEM_MOUSE_CURSOR id) +{ + (void)dpy; (void)id; + return false; +} + +static bool android_show_mouse_cursor(ALLEGRO_DISPLAY *dpy) +{ + (void)dpy; + return false; +} + +static bool android_hide_mouse_cursor(ALLEGRO_DISPLAY *dpy) +{ + (void)dpy; + return false; +} + +static void android_acknowledge_drawing_halt(ALLEGRO_DISPLAY *dpy) +{ + int i; + ALLEGRO_DEBUG("android_acknowledge_drawing_halt"); + + for (i = 0; i < (int)dpy->bitmaps._size; i++) { + ALLEGRO_BITMAP **bptr = _al_vector_ref(&dpy->bitmaps, i); + ALLEGRO_BITMAP *bmp = *bptr; + int bitmap_flags = al_get_bitmap_flags(bmp); + + if (!bmp->parent && + !(bitmap_flags & ALLEGRO_MEMORY_BITMAP) && + !(bitmap_flags & ALLEGRO_NO_PRESERVE_TEXTURE)) + { + ALLEGRO_BITMAP_EXTRA_OPENGL *extra = bmp->extra; + al_remove_opengl_fbo(bmp); + glDeleteTextures(1, &extra->texture); + extra->texture = 0; + } + } + + ALLEGRO_DISPLAY_ANDROID *d = (ALLEGRO_DISPLAY_ANDROID *)dpy; + + _al_android_clear_current(_al_android_get_jnienv(), d); + + /* XXX mutex? */ + al_broadcast_cond(d->cond); + + ALLEGRO_DEBUG("acknowledged drawing halt"); +} + +static void android_broadcast_resume(ALLEGRO_DISPLAY_ANDROID *d) +{ + ALLEGRO_DEBUG("Broadcasting resume"); + d->resumed = true; + al_broadcast_cond(d->cond); + ALLEGRO_DEBUG("done broadcasting resume"); +} + +static void android_acknowledge_drawing_resume(ALLEGRO_DISPLAY *dpy) +{ + unsigned i; + + ALLEGRO_DEBUG("begin"); + + ALLEGRO_DISPLAY_ANDROID *d = (ALLEGRO_DISPLAY_ANDROID *)dpy; + + _al_android_clear_current(_al_android_get_jnienv(), d); + _al_android_make_current(_al_android_get_jnienv(), d); + + ALLEGRO_DEBUG("made current"); + + if (dpy->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + dpy->default_shader = _al_create_default_shader(dpy->flags); + } + + // Bitmaps can still have stale shaders attached. + _al_glsl_unuse_shaders(); + + // Restore the transformations. + dpy->vt->update_transformation(dpy, al_get_target_bitmap()); + + // Restore bitmaps + // have to get this because new bitmaps could be created below + for (i = 0; i < _al_vector_size(&dpy->bitmaps); i++) { + ALLEGRO_BITMAP **bptr = _al_vector_ref(&dpy->bitmaps, i); + ALLEGRO_BITMAP *bmp = *bptr; + int bitmap_flags = al_get_bitmap_flags(bmp); + + if (!bmp->parent && + !(bitmap_flags & ALLEGRO_MEMORY_BITMAP) && + !(bitmap_flags & ALLEGRO_NO_PRESERVE_TEXTURE)) + { + int format = al_get_bitmap_format(bmp); + format = _al_pixel_format_is_compressed(format) ? ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE : format; + _al_ogl_upload_bitmap_memory(bmp, format, bmp->memory); + bmp->dirty = false; + } + } + + android_broadcast_resume(d); + + ALLEGRO_DEBUG("acknowledge_drawing_resume end"); +} + +static void android_set_display_option(ALLEGRO_DISPLAY *d, int o, int v) +{ + (void)d; + + if (o == ALLEGRO_SUPPORTED_ORIENTATIONS) { + _jni_callVoidMethodV(_al_android_get_jnienv(), + _al_android_activity_object(), "setAllegroOrientation", "(I)V", v); + } +} + +/* obtain a reference to the android driver */ +ALLEGRO_DISPLAY_INTERFACE *_al_get_android_display_driver(void) +{ + if (vt) + return vt; + + vt = al_malloc(sizeof *vt); + memset(vt, 0, sizeof *vt); + + vt->create_display = android_create_display; + vt->destroy_display = android_destroy_display; + vt->set_current_display = android_set_current_display; + vt->unset_current_display = android_unset_current_display; + vt->flip_display = android_flip_display; + vt->update_display_region = android_update_display_region; + vt->acknowledge_resize = android_acknowledge_resize; + vt->create_bitmap = _al_ogl_create_bitmap; + vt->get_backbuffer = _al_ogl_get_backbuffer; + vt->set_target_bitmap = _al_ogl_set_target_bitmap; + + vt->get_orientation = android_get_orientation; + + vt->is_compatible_bitmap = android_is_compatible_bitmap; + vt->resize_display = android_resize_display; + vt->set_icons = android_set_icons; + vt->set_window_title = android_set_window_title; + vt->set_window_position = android_set_window_position; + vt->get_window_position = android_get_window_position; + vt->set_display_flag = android_set_display_flag; + vt->wait_for_vsync = android_wait_for_vsync; + + vt->set_mouse_cursor = android_set_mouse_cursor; + vt->set_system_mouse_cursor = android_set_system_mouse_cursor; + vt->show_mouse_cursor = android_show_mouse_cursor; + vt->hide_mouse_cursor = android_hide_mouse_cursor; + + vt->acknowledge_drawing_halt = android_acknowledge_drawing_halt; + vt->acknowledge_drawing_resume = android_acknowledge_drawing_resume; + + vt->set_display_option = android_set_display_option; + + vt->update_render_state = _al_ogl_update_render_state; + + _al_ogl_add_drawing_functions(vt); + _al_android_add_clipboard_functions(vt); + + return vt; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_image.c b/allegro/src/android/android_image.c new file mode 100644 index 00000000..a3daf546 --- /dev/null +++ b/allegro/src/android/android_image.c @@ -0,0 +1,312 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android image loading. + * + * By Thomas Fjellstrom. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_android.h" +#include "allegro5/internal/aintern_android.h" +#include "allegro5/internal/aintern_bitmap.h" + +#include + +ALLEGRO_DEBUG_CHANNEL("android") + +static void +copy_bitmap_data(ALLEGRO_BITMAP *bitmap, + const uint32_t *src, ALLEGRO_PIXEL_FORMAT src_format, int src_pitch, + int bitmap_w, int bitmap_h) +{ + ALLEGRO_LOCKED_REGION *lr; + + lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ANY, + ALLEGRO_LOCK_WRITEONLY); + ASSERT(lr); + if (!lr) + return; + + _al_convert_bitmap_data(src, src_format, src_pitch, + lr->data, lr->format, lr->pitch, + 0, 0, 0, 0, bitmap_w, bitmap_h); + + al_unlock_bitmap(bitmap); +} + +static void +copy_bitmap_data_multiply_alpha(ALLEGRO_BITMAP *bitmap, const uint32_t *src, + int bitmap_w, int bitmap_h) +{ + ALLEGRO_LOCKED_REGION *lr; + int x, y; + + lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888, + ALLEGRO_LOCK_WRITEONLY); + ASSERT(lr); + if (!lr) + return; + + for (y = 0; y < bitmap_h; y++) { + uint32_t *dst = (uint32_t *)(((uint8_t *)lr->data) + y * lr->pitch); + for (x = 0; x < bitmap_w; x++) { + uint32_t c = *src++; + uint32_t a = (c >> 24) & 0xff; + c = (a << 24) + | (((c >> 16) & 0xff) * a / 255) + | ((((c >> 8) & 0xff) * a / 255) << 8) + | (((c & 0xff) * a / 255) << 16); + *dst++ = c; + } + } + + al_unlock_bitmap(bitmap); +} + +static void +copy_bitmap_data_demultiply_alpha(ALLEGRO_BITMAP *bitmap, const uint32_t *src, + int src_format, int src_pitch, int bitmap_w, int bitmap_h) +{ + ALLEGRO_LOCKED_REGION *lr; + int x, y; + + lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888, + ALLEGRO_LOCK_WRITEONLY); + ASSERT(lr); + if (!lr) + return; + + _al_convert_bitmap_data(src, src_format, src_pitch, + lr->data, lr->format, lr->pitch, + 0, 0, 0, 0, bitmap_w, bitmap_h); + + for (y = 0; y < bitmap_h; y++) { + uint32_t *dst = (uint32_t *)(((uint8_t *)lr->data) + y * lr->pitch); + for (x = 0; x < bitmap_w; x++) { + uint32_t c = *dst; + uint8_t a = (c >> 24); + uint8_t b = (c >> 16); + uint8_t g = (c >> 8); + uint8_t r = (c >> 0); + // NOTE: avoid divide by zero by adding a fraction. + float alpha_mul = 255.0f / (a+0.001f); + r *= alpha_mul; + g *= alpha_mul; + b *= alpha_mul; + *dst = ((uint32_t)a << 24) + | ((uint32_t)b << 16) + | ((uint32_t)g << 8) + | ((uint32_t)r); + dst++; + } + } + + al_unlock_bitmap(bitmap); +} + +/* Note: This is not used when loading an image from the .apk. + * + * The ImageLoader class uses Java to load a bitmap. To support + * Allegro's filesystem functions, the bitmap is read from an + * AllegroInputStream which in turn calls back into C to use Allegro's + * file functions. + */ +ALLEGRO_BITMAP *_al_android_load_image_f(ALLEGRO_FILE *fh, int flags) +{ + JNIEnv *jnienv; + jclass image_loader_class; + jobject input_stream_class; + jmethodID input_stream_ctor; + jobject input_stream; + int buffer_len; + uint8_t *buffer; + jobject byte_buffer; + jobject jbitmap; + ALLEGRO_BITMAP *bitmap; + int bitmap_w; + int bitmap_h; + int pitch; + + if (flags & ALLEGRO_KEEP_INDEX) { + ALLEGRO_ERROR("ALLEGRO_KEEP_INDEX not yet supported\n"); + return NULL; + } + + jnienv = (JNIEnv *)_al_android_get_jnienv(); + // Note: This is always ImageLoader + image_loader_class = _al_android_image_loader_class(); + // Note: This is always AllegroInputStream + input_stream_class = _al_android_input_stream_class(); + input_stream_ctor = _jni_call(jnienv, jclass, GetMethodID, + input_stream_class, "", "(J)V"); + input_stream = _jni_call(jnienv, jobject, NewObject, input_stream_class, + input_stream_ctor, (jlong)(intptr_t)fh); + if (!input_stream) { + ALLEGRO_ERROR("failed to create new AllegroInputStream object"); + return NULL; + } + + jbitmap = _jni_callStaticObjectMethodV(jnienv, image_loader_class, + "decodeBitmapStream", + "(Ljava/io/InputStream;)Landroid/graphics/Bitmap;", + input_stream); + + _jni_callv(jnienv, DeleteLocalRef, input_stream); + + if (!jbitmap) + return NULL; + + bitmap_w = _jni_callIntMethod(jnienv, jbitmap, "getWidth"); + bitmap_h = _jni_callIntMethod(jnienv, jbitmap, "getHeight"); + pitch = _jni_callIntMethod(jnienv, jbitmap, "getRowBytes"); + + buffer_len = pitch * bitmap_h; + buffer = al_malloc(buffer_len); + if (!buffer) { + _jni_callv(jnienv, DeleteLocalRef, jbitmap); + return NULL; + } + + int src_format = _jni_callStaticIntMethodV(jnienv, image_loader_class, + "getBitmapFormat", "(Landroid/graphics/Bitmap;)I", jbitmap); + + // FIXME: at some point add support for the ndk AndroidBitmap api need to + // check for header at build time, and android version at runtime if thats + // even possible, might need to try and dynamically load the lib? I dunno. + // That would get rid of this buffer allocation and copy. + byte_buffer = _jni_call(jnienv, jobject, NewDirectByteBuffer, buffer, + buffer_len); + + _jni_callVoidMethodV(jnienv, jbitmap, + "copyPixelsToBuffer", "(Ljava/nio/Buffer;)V", byte_buffer); + + // Tell java we don't need the byte_buffer object. + _jni_callv(jnienv, DeleteLocalRef, byte_buffer); + + // Tell java we're done with the bitmap as well. + _jni_callv(jnienv, DeleteLocalRef, jbitmap); + + bitmap = al_create_bitmap(bitmap_w, bitmap_h); + if (!bitmap) { + al_free(buffer); + return NULL; + } + + /* buffer already has alpha multiplied in. */ + if (flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA) { + copy_bitmap_data_demultiply_alpha(bitmap, (const uint32_t *)buffer, + src_format, pitch, bitmap_w, bitmap_h); + } + else { + copy_bitmap_data(bitmap, (const uint32_t *)buffer, src_format, pitch, + bitmap_w, bitmap_h); + } + + al_free(buffer); + + return bitmap; +} + +static ALLEGRO_BITMAP *android_load_image_asset(const char *filename, int flags) +{ + JNIEnv *jnienv; + jclass image_loader_class; + jobject activity; + jobject str; + jobject jbitmap; + int bitmap_w; + int bitmap_h; + ALLEGRO_BITMAP *bitmap; + jintArray ia; + jint *arr; + + if (flags & ALLEGRO_KEEP_INDEX) { + ALLEGRO_ERROR("ALLEGRO_KEEP_INDEX not yet supported\n"); + return NULL; + } + + jnienv = _al_android_get_jnienv(); + image_loader_class = _al_android_image_loader_class(); + activity = _al_android_activity_object(); + str = (*jnienv)->NewStringUTF(jnienv, filename); + jbitmap = _jni_callStaticObjectMethodV(jnienv, image_loader_class, + "decodeBitmapAsset", + "(Landroid/app/Activity;Ljava/lang/String;)Landroid/graphics/Bitmap;", + activity, str); + + /* For future Java noobs like me: If the calling thread is a Java + * thread, it will clean up these references when the native method + * returns. But here that's not the case (though technically we were + * spawned ultimately by a Java thread, we never return.) In any case, + * it never does any harm to release the reference anyway. + */ + (*jnienv)->DeleteLocalRef(jnienv, str); + + if (!jbitmap) + return NULL; + + bitmap_w = _jni_callIntMethod(jnienv, jbitmap, "getWidth"); + bitmap_h = _jni_callIntMethod(jnienv, jbitmap, "getHeight"); + ALLEGRO_DEBUG("bitmap dimensions: %d, %d", bitmap_w, bitmap_h); + + bitmap = al_create_bitmap(bitmap_w, bitmap_h); + if (!bitmap) { + _jni_callv(jnienv, DeleteLocalRef, jbitmap); + return NULL; + } + + ia = _jni_callStaticObjectMethodV(jnienv, image_loader_class, + "getPixels", "(Landroid/graphics/Bitmap;)[I", jbitmap); + arr = (*jnienv)->GetIntArrayElements(jnienv, ia, 0); + + /* arr is an array of packed colours, NON-premultiplied alpha. */ + if (flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA) { + int src_format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; + int src_pitch = bitmap_w * sizeof(uint32_t); + copy_bitmap_data(bitmap, (const uint32_t *)arr, + src_format, src_pitch, bitmap_w, bitmap_h); + } + else { + copy_bitmap_data_multiply_alpha(bitmap, (const uint32_t *)arr, + bitmap_w, bitmap_h); + } + + (*jnienv)->ReleaseIntArrayElements(jnienv, ia, arr, JNI_ABORT); + _jni_callv(jnienv, DeleteLocalRef, ia); + _jni_callv(jnienv, DeleteLocalRef, jbitmap); + + return bitmap; +} + +ALLEGRO_BITMAP *_al_android_load_image(const char *filename, int flags) +{ + ALLEGRO_FILE *fp; + ALLEGRO_BITMAP *bmp; + + /* Bypass the ALLEGRO_FILE interface when we know the underlying stream + * implementation, to avoid a lot of shunting between C and Java. + * We could probably do this for normal filesystem as well. + */ + if (al_get_new_file_interface() == _al_get_apk_file_vtable()) { + return android_load_image_asset(filename, flags); + } + + fp = al_fopen(filename, "rb"); + if (fp) { + bmp = _al_android_load_image_f(fp, flags); + al_fclose(fp); + return bmp; + } + + return NULL; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_input_stream.c b/allegro/src/android/android_input_stream.c new file mode 100644 index 00000000..fcc1bb38 --- /dev/null +++ b/allegro/src/android/android_input_stream.c @@ -0,0 +1,67 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android input stream. + * + * By Thomas Fjellstrom. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_android.h" + +#include + +ALLEGRO_DEBUG_CHANNEL("android") + +/* XXX ALLEGRO_FILE pointers currently passed as ints */ +ALLEGRO_STATIC_ASSERT(android, sizeof(jlong) >= sizeof(ALLEGRO_FILE *)); + +JNI_FUNC(int, AllegroInputStream, nativeRead, (JNIEnv *env, jobject obj, + jlong handle, jbyteArray array, int offset, int length)) +{ + ALLEGRO_FILE *fp = (ALLEGRO_FILE *)(intptr_t)handle; + int ret = -1; + jbyte *array_ptr = NULL; + ASSERT(fp != NULL); + + (void)obj; + ALLEGRO_DEBUG("nativeRead begin: handle:%lli fp:%p offset:%i length:%i", + handle, fp, offset, length); + + int array_len = _jni_call(env, int, GetArrayLength, array); + ALLEGRO_DEBUG("array length: %i", array_len); + + array_ptr = _jni_call(env, jbyte *, GetByteArrayElements, array, NULL); + ASSERT(array_ptr != NULL); + + ALLEGRO_DEBUG("al_fread: p:%p, o:%i, l:%i", array_ptr, offset, length); + ret = al_fread(fp, array_ptr + offset, length); + + if (ret == 0 && al_feof(fp)) { + /* InputStream.read() semantics. */ + ret = -1; + } + + _jni_callv(env, ReleaseByteArrayElements, array, array_ptr, 0); + + ALLEGRO_DEBUG("nativeRead end"); + return ret; +} + +JNI_FUNC(void, AllegroInputStream, nativeClose, (JNIEnv *env, jobject obj, + jlong handle)) +{ + ALLEGRO_FILE *fp = (ALLEGRO_FILE *)(intptr_t)handle; + (void)env; + (void)obj; + al_fclose(fp); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_joystick.c b/allegro/src/android/android_joystick.c new file mode 100644 index 00000000..05c10b9a --- /dev/null +++ b/allegro/src/android/android_joystick.c @@ -0,0 +1,330 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_android.h" + +ALLEGRO_DEBUG_CHANNEL("android") + +typedef struct ALLEGRO_JOYSTICK_ANDROID { + ALLEGRO_JOYSTICK parent; + ALLEGRO_JOYSTICK_STATE joystate; + const char *name; +} ALLEGRO_JOYSTICK_ANDROID; + +static _AL_VECTOR joysticks = _AL_VECTOR_INITIALIZER(ALLEGRO_JOYSTICK_ANDROID *); +static bool initialized; + +static void android_init_joysticks(int num) +{ + int i, j; + + for (i = 0; i < num; i++) { + ALLEGRO_JOYSTICK_ANDROID *stick = al_calloc(1, sizeof(ALLEGRO_JOYSTICK_ANDROID)); + ALLEGRO_JOYSTICK_ANDROID **ptr; + ALLEGRO_JOYSTICK *joy; + + joy = (void *)stick; + stick->name = "Android Joystick"; + + /* Fill in the joystick information fields. */ + joy->info.num_sticks = 2; + joy->info.num_buttons = 11; + joy->info.stick[0].name = "Stick 1"; + joy->info.stick[0].num_axes = 2; + joy->info.stick[0].axis[0].name = "X"; + joy->info.stick[0].axis[1].name = "Y"; + joy->info.stick[0].flags = ALLEGRO_JOYFLAG_ANALOGUE; + joy->info.stick[1].name = "Stick 2"; + joy->info.stick[1].num_axes = 2; + joy->info.stick[1].axis[0].name = "X"; + joy->info.stick[1].axis[1].name = "Y"; + joy->info.stick[1].flags = ALLEGRO_JOYFLAG_ANALOGUE; + + for (j = 0; j < joy->info.num_buttons; j++) { + joy->info.button[j].name = ""; + } + + ptr = _al_vector_alloc_back(&joysticks); + *ptr = stick; + } +} + +static bool andjoy_init_joystick(void) +{ + ALLEGRO_JOYSTICK_ANDROID *accel = al_calloc(1, sizeof(ALLEGRO_JOYSTICK_ANDROID)); + ALLEGRO_JOYSTICK_ANDROID **ptr; + ALLEGRO_JOYSTICK *joy; + int num; + + accel->name = "Accelerometer"; + + joy = (void *)accel; + + /* Fill in the joystick information fields. */ + joy->info.num_sticks = 1; + joy->info.num_buttons = 0; + joy->info.stick[0].name = "Accelerometer"; + joy->info.stick[0].num_axes = 3; + joy->info.stick[0].axis[0].name = "X"; + joy->info.stick[0].axis[1].name = "Y"; + joy->info.stick[0].axis[2].name = "Z"; + joy->info.stick[0].flags = ALLEGRO_JOYFLAG_ANALOGUE; + + ptr = _al_vector_alloc_back(&joysticks); + *ptr = accel; + + num = _jni_callIntMethodV(_al_android_get_jnienv(), _al_android_activity_object(), "getNumJoysticks", "()I"); + + android_init_joysticks(num); + + initialized = true; + + _jni_callVoidMethod(_al_android_get_jnienv(), _al_android_activity_object(), "setJoystickActive"); + + return true; +} + +static void andjoy_exit_joystick(void) +{ + initialized = false; +} + +static bool andjoy_reconfigure_joysticks(void) +{ + int i; + int sz; + int num; + + sz = _al_vector_size(&joysticks); + + for (i = 1; i < sz; i++) { + al_free(*((ALLEGRO_JOYSTICK_ANDROID **)_al_vector_ref(&joysticks, 1))); + _al_vector_delete_at(&joysticks, 1); + } + + _jni_callVoidMethod(_al_android_get_jnienv(), _al_android_activity_object(), "reconfigureJoysticks"); + + num = _jni_callIntMethodV(_al_android_get_jnienv(), _al_android_activity_object(), "getNumJoysticks", "()I"); + + android_init_joysticks(num); + + return true; +} + +static int andjoy_num_joysticks(void) +{ + return _al_vector_size(&joysticks); +} + +static ALLEGRO_JOYSTICK *andjoy_get_joystick(int num) +{ + ALLEGRO_JOYSTICK_ANDROID *andjoy; + ALLEGRO_JOYSTICK *joy; + + if (num >= andjoy_num_joysticks()) + return NULL; + + andjoy = *((ALLEGRO_JOYSTICK_ANDROID **)_al_vector_ref(&joysticks, num)); + joy = &andjoy->parent; + + return joy; +} + +static void andjoy_release_joystick(ALLEGRO_JOYSTICK *joy) +{ + int i; + int sz; + (void)joy; + + sz = _al_vector_size(&joysticks); + + for (i = 0; i < sz; i++) { + al_free(*((ALLEGRO_JOYSTICK_ANDROID **)_al_vector_ref(&joysticks, 0))); + _al_vector_delete_at(&joysticks, 0); + } + + _jni_callVoidMethod(_al_android_get_jnienv(), _al_android_activity_object(), "setJoystickInactive"); + + ALLEGRO_DEBUG("Joystick released.\n"); + initialized = false; +} + +static void andjoy_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + ALLEGRO_JOYSTICK_ANDROID *andjoy = (void *)joy; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + int i; + bool found = false; + + for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_ANDROID **ptr = _al_vector_ref(&joysticks, i); + ALLEGRO_JOYSTICK_ANDROID *thisjoy = *ptr; + if (andjoy == thisjoy) { + found = true; + break; + } + } + + if (!found) { + memset(ret_state, 0, sizeof(*ret_state)); + return; + } + + _al_event_source_lock(es); + *ret_state = andjoy->joystate; + _al_event_source_unlock(es); +} + +void _al_android_generate_accelerometer_event(float x, float y, float z) +{ + if (!initialized) + return; + + /* Android reports accelerometer data in the approximate range + * -9.81 -> 9.81, but can be higher or lower. Allegro joysticks + * use -1 -> 1. Also, the axis' are all reversed on Android, + * hence the negative division. + */ + x /= -9.81f; + if (x < -1) x = -1; + if (x > 1) x = 1; + y /= -9.81f; + if (y < -1) y = -1; + if (y > 1) y = 1; + z /= -9.81f; + if (z < -1) z = -1; + if (z > 1) z = 1; + + ALLEGRO_JOYSTICK_ANDROID *accel = *((ALLEGRO_JOYSTICK_ANDROID **)_al_vector_ref(&joysticks, 0)); + ALLEGRO_JOYSTICK *joy = &accel->parent; + + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + ALLEGRO_EVENT event; + + _al_event_source_lock(es); + + if (_al_event_source_needs_to_generate_event(es)) { + float pos[] = {x, y, z}; + int i; + for (i = 0; i < 3; i++) { + event.joystick.id = joy; + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.timestamp = al_get_time(); + event.joystick.stick = 0; + event.joystick.axis = i; + event.joystick.pos = pos[i]; + event.joystick.button = 0; + + accel->joystate.stick[0].axis[i] = pos[i]; + + _al_event_source_emit_event(es, &event); + } + } + + _al_event_source_unlock(es); +} + +void _al_android_generate_joystick_axis_event(int index, int stick, int axis, float value) +{ + if (!initialized || index >= andjoy_num_joysticks()) + return; + + ALLEGRO_JOYSTICK_ANDROID *joystick = *((ALLEGRO_JOYSTICK_ANDROID **)_al_vector_ref(&joysticks, index)); + ALLEGRO_JOYSTICK *joy = &joystick->parent; + + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + ALLEGRO_EVENT event; + + _al_event_source_lock(es); + + if (_al_event_source_needs_to_generate_event(es)) { + event.joystick.id = joy; + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.timestamp = al_get_time(); + event.joystick.stick = stick; + event.joystick.axis = axis; + event.joystick.pos = value; + event.joystick.button = 0; + + joystick->joystate.stick[stick].axis[axis] = value; + + _al_event_source_emit_event(es, &event); + } + _al_event_source_unlock(es); +} + +void _al_android_generate_joystick_button_event(int index, int button, bool down) +{ + int type; + + if (!initialized || index >= andjoy_num_joysticks()) + return; + + ALLEGRO_JOYSTICK_ANDROID *joystick = *((ALLEGRO_JOYSTICK_ANDROID **)_al_vector_ref(&joysticks, index)); + ALLEGRO_JOYSTICK *joy = &joystick->parent; + + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + ALLEGRO_EVENT event; + + _al_event_source_lock(es); + + if (down) + type = ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN; + else + type = ALLEGRO_EVENT_JOYSTICK_BUTTON_UP; + + if (_al_event_source_needs_to_generate_event(es)) { + event.joystick.id = joy; + event.joystick.type = type; + event.joystick.timestamp = al_get_time(); + event.joystick.stick = 0; + event.joystick.axis = 0; + event.joystick.pos = 0; + event.joystick.button = button; + + joystick->joystate.button[button] = type == ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN ? 1 : 0; + + _al_event_source_emit_event(es, &event); + } + _al_event_source_unlock(es); +} + +static char const *andjoy_get_name(ALLEGRO_JOYSTICK *joy) +{ + int i; + (void)joy; + + for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_ANDROID *andjoy = *((ALLEGRO_JOYSTICK_ANDROID **)_al_vector_ref(&joysticks, i)); + if ((ALLEGRO_JOYSTICK *)andjoy == joy) + return andjoy->name; + } + + return ""; +} + +static bool andjoy_get_active(ALLEGRO_JOYSTICK *joy) +{ + (void)joy; + return true; +} + +ALLEGRO_JOYSTICK_DRIVER _al_android_joystick_driver = { + AL_ID('A', 'N', 'D', 'R'), + "", + "", + "android joystick", + andjoy_init_joystick, + andjoy_exit_joystick, + andjoy_reconfigure_joysticks, + andjoy_num_joysticks, + andjoy_get_joystick, + andjoy_release_joystick, + andjoy_get_joystick_state, + andjoy_get_name, + andjoy_get_active +}; diff --git a/allegro/src/android/android_keyboard.c b/allegro/src/android/android_keyboard.c new file mode 100644 index 00000000..1cc1bff5 --- /dev/null +++ b/allegro/src/android/android_keyboard.c @@ -0,0 +1,183 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_android.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_keyboard.h" + +#include + +ALLEGRO_DEBUG_CHANNEL("keyboard") + +static ALLEGRO_KEYBOARD the_keyboard; +static ALLEGRO_KEYBOARD_STATE the_state; + +static bool android_init_keyboard(void) +{ + memset(&the_keyboard, 0, sizeof the_keyboard); + _al_event_source_init(&the_keyboard.es); + return true; +} + +static void android_exit_keyboard(void) +{ + _al_event_source_free(&the_keyboard.es); +} + + +static ALLEGRO_KEYBOARD *android_get_keyboard(void) +{ + return &the_keyboard; +} + +static bool android_set_keyboard_leds(int leds) +{ + (void)leds; + return false; +} + +static char const *android_keycode_to_name(int keycode) +{ + static bool created = false; + static char names[ALLEGRO_KEY_MAX][5]; + + ASSERT(keycode >= 0 && keycode < ALLEGRO_KEY_MAX); + + if (!created) { + int i; + created = true; + for (i = 0; i < ALLEGRO_KEY_MAX; i++) { + snprintf(names[i], 5, "%d", i); + } + } + + return names[keycode]; +} + +static void android_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) +{ + _al_event_source_lock(&the_keyboard.es); + { + *ret_state = the_state; + } + _al_event_source_unlock(&the_keyboard.es); +} + +static void android_clear_keyboard_state(void) +{ + _al_event_source_lock(&the_keyboard.es); + { + memset(&the_state, 0, sizeof(the_state)); + } + _al_event_source_unlock(&the_keyboard.es); +} + +static ALLEGRO_KEYBOARD_DRIVER android_keyboard_driver = { + AL_ID('A','N','D','R'), + "", + "", + "android keyboard", + android_init_keyboard, + android_exit_keyboard, + android_get_keyboard, + android_set_keyboard_leds, + android_keycode_to_name, + android_get_keyboard_state, + android_clear_keyboard_state +}; + +ALLEGRO_KEYBOARD_DRIVER *_al_get_android_keyboard_driver(void) +{ + return &android_keyboard_driver; +} + +static void android_keyboard_handle_event(ALLEGRO_DISPLAY *display, + int scancode, int unichar, ALLEGRO_EVENT_TYPE event_type) +{ + ALLEGRO_EVENT event; + + ASSERT(display != NULL); + ASSERT(scancode > 0); + + if (event_type == ALLEGRO_EVENT_KEY_UP) { + _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, scancode); + } + else { + _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, scancode); + } + + _al_event_source_lock(&the_keyboard.es); + + if (_al_event_source_needs_to_generate_event(&the_keyboard.es)) { + + event.keyboard.type = event_type; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = display; + event.keyboard.keycode = scancode; + event.keyboard.unichar = unichar; + event.keyboard.modifiers = 0; + event.keyboard.repeat = event_type == ALLEGRO_EVENT_KEY_CHAR; + + _al_event_source_emit_event(&the_keyboard.es, &event); + } + + _al_event_source_unlock(&the_keyboard.es); +} + +JNI_FUNC(void, KeyListener, nativeOnKeyDown, (JNIEnv *env, jobject obj, + jint scancode, jint unichar)) +{ + (void)env; + (void)obj; + + ALLEGRO_SYSTEM *system = al_get_system_driver(); + ASSERT(system != NULL); + + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&system->displays, 0); + ALLEGRO_DISPLAY *display = *dptr; + ASSERT(display != NULL); + + android_keyboard_handle_event(display, scancode, unichar, + ALLEGRO_EVENT_KEY_DOWN); +} + +JNI_FUNC(void, KeyListener, nativeOnKeyUp, (JNIEnv *env, jobject obj, + jint scancode)) +{ + (void)env; + (void)obj; + + ALLEGRO_SYSTEM *system = al_get_system_driver(); + ASSERT(system != NULL); + + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&system->displays, 0); + ALLEGRO_DISPLAY *display = *dptr; + ASSERT(display != NULL); + + android_keyboard_handle_event(display, scancode, 0, ALLEGRO_EVENT_KEY_UP); +} + +JNI_FUNC(void, KeyListener, nativeOnKeyChar, (JNIEnv *env, jobject obj, + jint scancode, jint unichar)) +{ + (void)env; + (void)obj; + + ALLEGRO_SYSTEM *system = al_get_system_driver(); + ASSERT(system != NULL); + + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&system->displays, 0); + ALLEGRO_DISPLAY *display = *dptr; + ASSERT(display != NULL); + + android_keyboard_handle_event(display, scancode, unichar, + ALLEGRO_EVENT_KEY_CHAR); +} + +JNI_FUNC(void, KeyListener, nativeOnJoystickButton, (JNIEnv *env, jobject obj, + jint index, jint button, jboolean down)) +{ + (void)env; + (void)obj; + _al_android_generate_joystick_button_event(index+1, button, down); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_mouse.c b/allegro/src/android/android_mouse.c new file mode 100644 index 00000000..98548216 --- /dev/null +++ b/allegro/src/android/android_mouse.c @@ -0,0 +1,129 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_android.h" + +typedef struct ALLEGRO_MOUSE_ANDROID { + ALLEGRO_MOUSE parent; + ALLEGRO_MOUSE_STATE state; +} ALLEGRO_MOUSE_ANDROID; + +static ALLEGRO_MOUSE_ANDROID the_mouse; + +static bool amouse_installed; + +/* + * Helper to generate a mouse event. + */ +void _al_android_generate_mouse_event(unsigned int type, int x, int y, + unsigned int button, ALLEGRO_DISPLAY *d) +{ + ALLEGRO_EVENT event; + + _al_event_source_lock(&the_mouse.parent.es); + + //_al_android_translate_from_screen(d, &x, &y); + + the_mouse.state.x = x; + the_mouse.state.y = y; + + if (type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + the_mouse.state.buttons |= (1 << button); + } + else if (type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { + the_mouse.state.buttons &= ~(1 << button); + } + + the_mouse.state.pressure = the_mouse.state.buttons ? 1.0 : 0.0; // TODO + + if (_al_event_source_needs_to_generate_event(&the_mouse.parent.es)) { + event.mouse.type = type; + event.mouse.timestamp = al_get_time(); + event.mouse.display = d; + event.mouse.x = x; + event.mouse.y = y; + event.mouse.z = 0; + event.mouse.w = 0; + event.mouse.dx = 0; // TODO + event.mouse.dy = 0; // TODO + event.mouse.dz = 0; // TODO + event.mouse.dw = 0; // TODO + event.mouse.button = button; + event.mouse.pressure = the_mouse.state.pressure; + _al_event_source_emit_event(&the_mouse.parent.es, &event); + } + + _al_event_source_unlock(&the_mouse.parent.es); +} + +static void amouse_exit(void); +static bool amouse_init(void) +{ + if (amouse_installed) + amouse_exit(); + memset(&the_mouse, 0, sizeof the_mouse); + _al_event_source_init(&the_mouse.parent.es); + amouse_installed = true; + return true; +} + +static void amouse_exit(void) +{ + if (!amouse_installed) + return; + amouse_installed = false; + _al_event_source_free(&the_mouse.parent.es); +} + +static ALLEGRO_MOUSE *amouse_get_mouse(void) +{ + ASSERT(amouse_installed); + return (ALLEGRO_MOUSE *)&the_mouse; +} + +/* We report multi-touch as different buttons. */ +static unsigned int amouse_get_mouse_num_buttons(void) +{ + return 5; +} + +static unsigned int amouse_get_mouse_num_axes(void) +{ + return 2; +} + +/* Hard to accomplish on a touch screen. */ +static bool amouse_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) +{ + (void)display; + (void)x; + (void)y; + return false; +} + +static bool amouse_set_mouse_axis(int which, int z) +{ + (void)which; + (void)z; + return false; +} + +static ALLEGRO_MOUSE_DRIVER android_mouse_driver = { + AL_ID('A', 'N', 'D', 'R'), + "", + "", + "android mouse", + amouse_init, + amouse_exit, + amouse_get_mouse, + amouse_get_mouse_num_buttons, + amouse_get_mouse_num_axes, + amouse_set_mouse_xy, + amouse_set_mouse_axis, + _al_android_mouse_get_state +}; + +ALLEGRO_MOUSE_DRIVER *_al_get_android_mouse_driver(void) +{ + return &android_mouse_driver; +} diff --git a/allegro/src/android/android_sensors.c b/allegro/src/android/android_sensors.c new file mode 100644 index 00000000..e352e50a --- /dev/null +++ b/allegro/src/android/android_sensors.c @@ -0,0 +1,31 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android Java/JNI system driver + * + * By Thomas Fjellstrom. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_android.h" +#include "allegro5/internal/aintern_android.h" + +#include + +JNI_FUNC(void, Sensors, nativeOnAccel, (JNIEnv *env, jobject obj, jint id, + jfloat x, jfloat y, jfloat z)) +{ + (void)env; + (void)obj; + (void)id; + _al_android_generate_accelerometer_event(x, y, z); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_system.c b/allegro/src/android/android_system.c new file mode 100644 index 00000000..41edfb44 --- /dev/null +++ b/allegro/src/android/android_system.c @@ -0,0 +1,659 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android Java/JNI system driver + * + * By Thomas Fjellstrom. + * + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_android.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/internal/aintern_android.h" +#include "allegro5/internal/aintern_tls.h" +#include "allegro5/platform/aintandroid.h" +#include "allegro5/platform/alandroid.h" +#include "allegro5/threads.h" + +#include +#include + +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_opengl.h" + +ALLEGRO_DEBUG_CHANNEL("android") + +struct system_data_t { + JNIEnv *env; + jobject activity_object; + jclass input_stream_class; + jclass illegal_argument_exception_class; + jclass apk_stream_class; + jclass image_loader_class; + jclass clipboard_class; + jclass apk_fs_class; + + ALLEGRO_SYSTEM_ANDROID *system; + ALLEGRO_MUTEX *mutex; + ALLEGRO_COND *cond; + ALLEGRO_THREAD *trampoline; + bool trampoline_running; + + ALLEGRO_USTR *user_lib_name; + ALLEGRO_USTR *resources_dir; + ALLEGRO_USTR *data_dir; + ALLEGRO_USTR *apk_path; + ALLEGRO_USTR *model; + ALLEGRO_USTR *manufacturer; + + void *user_lib; + int (*user_main)(int argc, char **argv); + + int orientation; + + bool paused; +}; + +static struct system_data_t system_data; +static JavaVM* javavm; +static JNIEnv *main_env; + +static const char *_real_al_android_get_os_version(JNIEnv *env); + +bool _al_android_is_paused(void) +{ + return system_data.paused; +} + +int _al_android_get_display_orientation(void) +{ + return system_data.orientation; +} + +jclass _al_android_input_stream_class(void) +{ + return system_data.input_stream_class; +} + +jclass _al_android_apk_stream_class(void) +{ + return system_data.apk_stream_class; +} + +jclass _al_android_image_loader_class(void) +{ + return system_data.image_loader_class; +} + +jclass _al_android_clipboard_class(void) +{ + return system_data.clipboard_class; +} + +jobject _al_android_activity_object() +{ + return system_data.activity_object; +} + +jclass _al_android_apk_fs_class(void) +{ + return system_data.apk_fs_class; +} + +static void finish_activity(JNIEnv *env); + +static bool already_cleaned_up = false; + +/* NOTE: don't put any ALLEGRO_DEBUG in here! */ +static void android_cleanup(bool uninstall_system) +{ + if (already_cleaned_up) { + return; + } + + already_cleaned_up = true; + + if (uninstall_system) { + /* I don't think android calls our atexit() stuff since we're in a shared lib + so make sure al_uninstall_system is called */ + al_uninstall_system(); + } + + finish_activity(_al_android_get_jnienv()); + + (*javavm)->DetachCurrentThread(javavm); +} + +static void *android_app_trampoline(ALLEGRO_THREAD *thr, void *arg) +{ + const int argc = 1; + const char *argv[2] = {system_data.user_lib, NULL}; + int ret; + + (void)thr; + (void)arg; + + ALLEGRO_DEBUG("signaling running"); + + al_lock_mutex(system_data.mutex); + system_data.trampoline_running = true; + al_broadcast_cond(system_data.cond); + al_unlock_mutex(system_data.mutex); + + ALLEGRO_DEBUG("entering main function %p", system_data.user_main); + + ret = (system_data.user_main)(argc, (char **)argv); + + /* Can we do anything with this exit code? */ + ALLEGRO_DEBUG("returned from main function, exit code = %d", ret); + + /* NOTE: don't put any ALLEGRO_DEBUG in here after running main! */ + + android_cleanup(true); + + return NULL; +} + +/* called by JNI/Java */ +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + (void)reserved; + javavm = vm; + return JNI_VERSION_1_4; +} + +JNI_FUNC(bool, AllegroActivity, nativeOnCreate, (JNIEnv *env, jobject obj)) +{ + ALLEGRO_SYSTEM_ANDROID *na_sys = NULL; + jclass iae; + jclass aisc; + jclass asc; + + ALLEGRO_DEBUG("entered nativeOnCreate"); + + // we're already initialized, we REALLY don't want to run all the stuff below again. + if(system_data.system) { + return true; + } + + pthread_t self = pthread_self(); + ALLEGRO_DEBUG("pthread_self:%p", (void*)self); + ALLEGRO_DEBUG("nativeOnCreate begin"); + + memset(&system_data, 0, sizeof(system_data)); + + ALLEGRO_DEBUG("grab activity global refs"); + system_data.env = env; + system_data.activity_object = (*env)->NewGlobalRef(env, obj); + + iae = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); + system_data.illegal_argument_exception_class = (*env)->NewGlobalRef(env, iae); + + aisc = (*env)->FindClass(env, ALLEGRO_ANDROID_PACKAGE_NAME_SLASH "/AllegroInputStream"); + system_data.input_stream_class = (*env)->NewGlobalRef(env, aisc); + + asc = (*env)->FindClass(env, ALLEGRO_ANDROID_PACKAGE_NAME_SLASH "/AllegroAPKStream"); + system_data.apk_stream_class = (*env)->NewGlobalRef(env, asc); + + asc = (*env)->FindClass(env, ALLEGRO_ANDROID_PACKAGE_NAME_SLASH "/ImageLoader"); + system_data.image_loader_class = (*env)->NewGlobalRef(env, asc); + + asc = (*env)->FindClass(env, ALLEGRO_ANDROID_PACKAGE_NAME_SLASH "/Clipboard"); + system_data.clipboard_class = (*env)->NewGlobalRef(env, asc); + + asc = (*env)->FindClass(env, ALLEGRO_ANDROID_PACKAGE_NAME_SLASH "/AllegroAPKList"); + system_data.apk_fs_class = (*env)->NewGlobalRef(env, asc); + + ALLEGRO_DEBUG("create mutex and cond objects"); + system_data.mutex = al_create_mutex(); + system_data.cond = al_create_cond(); + + ALLEGRO_DEBUG("get directories"); + system_data.user_lib_name = _jni_callStringMethod(env, system_data.activity_object, "getUserLibName", "()Ljava/lang/String;"); + system_data.resources_dir = _jni_callStringMethod(env, system_data.activity_object, "getResourcesDir", "()Ljava/lang/String;"); + system_data.data_dir = _jni_callStringMethod(env, system_data.activity_object, "getPubDataDir", "()Ljava/lang/String;"); + system_data.apk_path = _jni_callStringMethod(env, system_data.activity_object, "getApkPath", "()Ljava/lang/String;"); + system_data.model = _jni_callStringMethod(env, system_data.activity_object, "getModel", "()Ljava/lang/String;"); + system_data.manufacturer = _jni_callStringMethod(env, system_data.activity_object, "getManufacturer", "()Ljava/lang/String;"); + ALLEGRO_DEBUG("resources_dir: %s", al_cstr(system_data.resources_dir)); + ALLEGRO_DEBUG("data_dir: %s", al_cstr(system_data.data_dir)); + ALLEGRO_DEBUG("apk_path: %s", al_cstr(system_data.apk_path)); + ALLEGRO_DEBUG("model: %s", al_cstr(system_data.model)); + ALLEGRO_DEBUG("manufacturer: %s", al_cstr(system_data.manufacturer)); + + ALLEGRO_DEBUG("creating ALLEGRO_SYSTEM_ANDROID struct"); + na_sys = system_data.system = (ALLEGRO_SYSTEM_ANDROID*)al_malloc(sizeof *na_sys); + memset(na_sys, 0, sizeof *na_sys); + + ALLEGRO_DEBUG("get system pointer"); + ALLEGRO_SYSTEM *sys = &na_sys->system; + ALLEGRO_DEBUG("get system interface"); + sys->vt = _al_system_android_interface(); + + ALLEGRO_DEBUG("init display vector"); + _al_vector_init(&sys->displays, sizeof(ALLEGRO_DISPLAY_ANDROID *)); + + ALLEGRO_DEBUG("init time"); + _al_unix_init_time(); + + const char *user_lib_name = al_cstr(system_data.user_lib_name); + ALLEGRO_DEBUG("load user lib: %s", user_lib_name); + system_data.user_lib = dlopen(user_lib_name, RTLD_LAZY|RTLD_GLOBAL); + if (!system_data.user_lib) { + ALLEGRO_ERROR("failed to load user lib: %s", user_lib_name); + ALLEGRO_ERROR("%s", dlerror()); + return false; + } + + system_data.user_main = dlsym(system_data.user_lib, "main"); + if (!system_data.user_main) { + ALLEGRO_ERROR("failed to locate symbol main: %s", dlerror()); + dlclose(system_data.user_lib); + return false; + } + ALLEGRO_DEBUG("main function address: %p\n", system_data.user_main); + + ALLEGRO_DEBUG("creating trampoline for app thread"); + system_data.trampoline = al_create_thread(android_app_trampoline, NULL); + al_start_thread(system_data.trampoline); + + ALLEGRO_DEBUG("waiting for app trampoline to signal running"); + al_lock_mutex(system_data.mutex); + while(!system_data.trampoline_running) { + al_wait_cond(system_data.cond, system_data.mutex); + } + al_unlock_mutex(system_data.mutex); + + ALLEGRO_DEBUG("setup done. returning to dalvik."); + + return true; +} + + +JNI_FUNC(void, AllegroActivity, nativeOnPause, (JNIEnv *env, jobject obj)) +{ + (void)env; + (void)obj; + + ALLEGRO_DEBUG("pause activity\n"); + + system_data.paused = true; + + ALLEGRO_SYSTEM *sys = (void *)al_get_system_driver(); + + if (!system_data.system || !sys) { + ALLEGRO_DEBUG("no system driver"); + return; + } + + if (!_al_vector_size(&sys->displays)) { + ALLEGRO_DEBUG("no display, not sending SWITCH_OUT event"); + return; + } + + ALLEGRO_DISPLAY *display = *(ALLEGRO_DISPLAY**)_al_vector_ref(&sys->displays, 0); + + if (display) { + ALLEGRO_EVENT event; + _al_event_source_lock(&display->es); + + if(_al_event_source_needs_to_generate_event(&display->es)) { + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; + event.display.timestamp = al_current_time(); + _al_event_source_emit_event(&display->es, &event); + } + _al_event_source_unlock(&display->es); + } +} + +JNI_FUNC(void, AllegroActivity, nativeOnResume, (JNIEnv *env, jobject obj)) +{ + ALLEGRO_SYSTEM *sys = &system_data.system->system; + ALLEGRO_DISPLAY *d = NULL; + + (void)obj; + + system_data.paused = false; + + ALLEGRO_DEBUG("resume activity"); + + if(!system_data.system || !sys) { + ALLEGRO_DEBUG("no system driver"); + return; + } + + if(!_al_vector_size(&sys->displays)) { + ALLEGRO_DEBUG("no display, not sending SWITCH_IN event"); + return; + } + + d = *(ALLEGRO_DISPLAY**)_al_vector_ref(&sys->displays, 0); + ALLEGRO_DEBUG("got display: %p", d); + + if(!((ALLEGRO_DISPLAY_ANDROID*)d)->created) { + _al_android_create_surface(env, true); // request android create our surface + } + + ALLEGRO_DISPLAY *display = *(ALLEGRO_DISPLAY**)_al_vector_ref(&sys->displays, 0); + + if (display) { + ALLEGRO_EVENT event; + _al_event_source_lock(&display->es); + + if(_al_event_source_needs_to_generate_event(&display->es)) { + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; + event.display.timestamp = al_current_time(); + _al_event_source_emit_event(&display->es, &event); + } + _al_event_source_unlock(&display->es); + } +} + +/* NOTE: don't put any ALLEGRO_DEBUG in here! */ +JNI_FUNC(void, AllegroActivity, nativeOnDestroy, (JNIEnv *env, jobject obj)) +{ + (void)obj; + + /* onDestroy can be called before main returns, for example if you start + * a new activity, your Allegro game will get onDestroy when it returns. + * At that point there's nothing you can do and any code you execute will + * crash, so this attempts to handle that more gracefully. Calling + * android_cleanup() eventually leads back here anyway. We ask android_cleanup + * not to call al_uninstall_system because GPU access causes a crash at + * this point (cleaning up bitmaps/displays etc.) The trampoline will exit + * eventually too so we guard against android_cleanup() being called twice. + */ + bool main_returned = _jni_callBooleanMethodV( + env, + system_data.activity_object, + "getMainReturned", + "()Z" + ); + + if (!main_returned) { + exit(0); + } + + if(!system_data.user_lib) { + return; + } + + system_data.user_main = NULL; + if(dlclose(system_data.user_lib) != 0) { + return; + } + + (*env)->DeleteGlobalRef(env, system_data.activity_object); + (*env)->DeleteGlobalRef(env, system_data.illegal_argument_exception_class); + (*env)->DeleteGlobalRef(env, system_data.input_stream_class); + + free(system_data.system); + + memset(&system_data, 0, sizeof(system_data)); +} + +JNI_FUNC(void, AllegroActivity, nativeOnOrientationChange, (JNIEnv *env, jobject obj, int orientation, bool init)) +{ + ALLEGRO_SYSTEM *sys = &system_data.system->system; + ALLEGRO_DISPLAY *d = NULL; + ALLEGRO_EVENT event; + + (void)env; (void)obj; + + ALLEGRO_DEBUG("got orientation change!"); + + system_data.orientation = orientation; + + if (!init) { + + /* no display, just skip */ + if (!_al_vector_size(&sys->displays)) { + ALLEGRO_DEBUG("no display, not sending orientation change event"); + return; + } + + d = *(ALLEGRO_DISPLAY**)_al_vector_ref(&sys->displays, 0); + ASSERT(d != NULL); + + ALLEGRO_DEBUG("locking display event source: %p %p", d, &d->es); + + _al_event_source_lock(&d->es); + + if(_al_event_source_needs_to_generate_event(&d->es)) { + ALLEGRO_DEBUG("emit event"); + event.display.type = ALLEGRO_EVENT_DISPLAY_ORIENTATION; + event.display.timestamp = al_current_time(); + event.display.orientation = orientation; + _al_event_source_emit_event(&d->es, &event); + } + + ALLEGRO_DEBUG("unlocking display event source"); + _al_event_source_unlock(&d->es); + + } +} + +JNI_FUNC(void, AllegroActivity, nativeSendJoystickConfigurationEvent, (JNIEnv *env, jobject obj)) +{ + (void)env; + (void)obj; + + if (!al_is_joystick_installed()) { + return; + } + + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + _al_event_source_lock(es); + ALLEGRO_EVENT event; + event.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; + _al_event_source_emit_event(es, &event); + _al_event_source_unlock(es); +} + +/* NOTE: don't put any ALLEGRO_DEBUG in here! */ +static void finish_activity(JNIEnv *env) +{ + _jni_callVoidMethod(env, system_data.activity_object, "postFinish"); +} + +static ALLEGRO_SYSTEM *android_initialize(int flags) +{ + (void)flags; + + ALLEGRO_DEBUG("android_initialize"); + + /* This was stored before user main ran, to make it easy and accessible + * the same way for all threads, we set it in tls + */ + _al_android_set_jnienv(main_env); + + return &system_data.system->system; +} + +static ALLEGRO_JOYSTICK_DRIVER *android_get_joystick_driver(void) +{ + return &_al_android_joystick_driver; +} + +static int android_get_num_video_adapters(void) +{ + return 1; +} + +static bool android_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +{ + if (adapter >= android_get_num_video_adapters()) + return false; + + JNIEnv * env = (JNIEnv *)_al_android_get_jnienv(); + jobject rect = _jni_callObjectMethod(env, _al_android_activity_object(), "getDisplaySize", "()Landroid/graphics/Rect;"); + + info->x1 = 0; + info->y1 = 0; + info->x2 = _jni_callIntMethod(env, rect, "width"); + info->y2 = _jni_callIntMethod(env, rect, "height"); + + ALLEGRO_DEBUG("Monitor Info: %d:%d", info->x2, info->y2); + + return true; +} + +static void android_shutdown_system(void) +{ + ALLEGRO_SYSTEM *s = al_get_system_driver(); + /* Close all open displays. */ + while (_al_vector_size(&s->displays) > 0) { + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); + ALLEGRO_DISPLAY *d = *dptr; + al_destroy_display(d); + } + _al_vector_free(&s->displays); +} + +static bool android_inhibit_screensaver(bool inhibit) +{ + return _jni_callBooleanMethodV(_al_android_get_jnienv(), system_data.activity_object, "inhibitScreenLock", "(Z)Z", inhibit); +} + +static ALLEGRO_SYSTEM_INTERFACE *android_vt; + +ALLEGRO_SYSTEM_INTERFACE *_al_system_android_interface() +{ + if(android_vt) + return android_vt; + + android_vt = al_malloc(sizeof *android_vt); + memset(android_vt, 0, sizeof *android_vt); + + android_vt->id = ALLEGRO_SYSTEM_ID_ANDROID; + android_vt->initialize = android_initialize; + android_vt->get_display_driver = _al_get_android_display_driver; + android_vt->get_keyboard_driver = _al_get_android_keyboard_driver; + android_vt->get_mouse_driver = _al_get_android_mouse_driver; + android_vt->get_touch_input_driver = _al_get_android_touch_input_driver; + android_vt->get_joystick_driver = android_get_joystick_driver; + android_vt->get_num_video_adapters = android_get_num_video_adapters; + android_vt->get_monitor_info = android_get_monitor_info; + android_vt->get_path = _al_android_get_path; + android_vt->shutdown_system = android_shutdown_system; + android_vt->inhibit_screensaver = android_inhibit_screensaver; + android_vt->get_time = _al_unix_get_time; + android_vt->rest = _al_unix_rest; + android_vt->init_timeout = _al_unix_init_timeout; + + return android_vt; +} + +ALLEGRO_PATH *_al_android_get_path(int id) +{ + ALLEGRO_PATH *path = NULL; + + switch(id) { + case ALLEGRO_RESOURCES_PATH: + /* path to bundle's files */ + path = al_create_path_for_directory(al_cstr(system_data.resources_dir)); + break; + + case ALLEGRO_TEMP_PATH: + case ALLEGRO_USER_DATA_PATH: + case ALLEGRO_USER_HOME_PATH: + case ALLEGRO_USER_SETTINGS_PATH: + case ALLEGRO_USER_DOCUMENTS_PATH: + /* path to sdcard */ + path = al_create_path_for_directory(al_cstr(system_data.data_dir)); + break; + + case ALLEGRO_EXENAME_PATH: + /* bundle path + bundle name */ + // FIXME! + path = al_create_path(al_cstr(system_data.apk_path)); + break; + + default: + path = al_create_path_for_directory("/DANGER/WILL/ROBINSON"); + break; + } + + return path; +} + +static const char *_real_al_android_get_os_version(JNIEnv *env) +{ + static char buffer[25]; + ALLEGRO_USTR *s = _jni_callStringMethod(env, system_data.activity_object, "getOsVersion", "()Ljava/lang/String;"); + strncpy(buffer, al_cstr(s), 25); + al_ustr_free(s); + return buffer; +} + +/* Function: al_android_get_os_version + */ +const char *al_android_get_os_version(void) +{ + return _real_al_android_get_os_version(_al_android_get_jnienv()); +} + +void _al_android_thread_created(void) +{ + JNIEnv *env; + JavaVMAttachArgs attach_args = { JNI_VERSION_1_4, "trampoline", NULL }; + (*javavm)->AttachCurrentThread(javavm, &env, &attach_args); + /* This function runs once before al_init, so before TLS is initialized + * so we save the environment and set it later in that case. + */ + ALLEGRO_SYSTEM *s = al_get_system_driver(); + if (s && s->installed) { + _al_android_set_jnienv(env); + } + else { + main_env = env; + } +} + +void _al_android_thread_ended(void) +{ + (*javavm)->DetachCurrentThread(javavm); +} + +void _al_android_set_capture_volume_keys(ALLEGRO_DISPLAY *display, bool onoff) +{ + ALLEGRO_DISPLAY_ANDROID *d = (ALLEGRO_DISPLAY_ANDROID *)display; + _jni_callVoidMethodV(_al_android_get_jnienv(), d->surface_object, "setCaptureVolumeKeys", "(Z)V", onoff); +} + +/* register system interfaces */ + +void _al_register_system_interfaces(void) +{ + ALLEGRO_SYSTEM_INTERFACE **add; + + /* add the native activity driver */ + add = _al_vector_alloc_back(&_al_system_interfaces); + *add = _al_system_android_interface(); + + /* TODO: add the non native activity driver */ +} + +/* Function: al_android_get_jni_env + */ +JNIEnv *al_android_get_jni_env(void) +{ + return _al_android_get_jnienv(); +} + +/* Function: al_android_get_activity + */ +jobject al_android_get_activity(void) +{ + return _al_android_activity_object(); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/android_touch.c b/allegro/src/android/android_touch.c new file mode 100644 index 00000000..5c17345c --- /dev/null +++ b/allegro/src/android/android_touch.c @@ -0,0 +1,401 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android family device touch input driver. + * + * By Thomas Fjellstrom. + * + * Based on the iOS touch input driver by Michał Cichoń. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_android.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_touch_input.h" + +ALLEGRO_DEBUG_CHANNEL("android") + + +/* forward declaration */ +static void android_touch_input_handle_cancel(int id, double timestamp, + float x, float y, bool primary, ALLEGRO_DISPLAY *disp); + + +static ALLEGRO_TOUCH_INPUT_STATE touch_input_state; +static ALLEGRO_MOUSE_STATE mouse_state; +static ALLEGRO_TOUCH_INPUT touch_input; +static bool installed = false; + + +static void reset_touch_input_state(void) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; i++) { + touch_input_state.touches[i].id = -1; + } +} + + +static void generate_touch_input_event(unsigned int type, double timestamp, + int id, float x, float y, float dx, float dy, bool primary, + ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_EVENT event; + + bool want_touch_event = _al_event_source_needs_to_generate_event(&touch_input.es); + bool want_mouse_emulation_event; + + if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_5_0_x) { + want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input.mouse_emulation_es) && al_is_mouse_installed(); + } + else { + want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input.mouse_emulation_es) && primary && al_is_mouse_installed(); + } + + if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_NONE) + want_mouse_emulation_event = false; + else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_INCLUSIVE) + want_touch_event = al_is_mouse_installed() ? (want_touch_event && !primary) : want_touch_event; + else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_EXCLUSIVE) + want_touch_event = al_is_mouse_installed() ? false : want_touch_event; + + + if (!want_touch_event && !want_mouse_emulation_event) + return; + + if (want_touch_event) { + + event.touch.type = type; + event.touch.display = (ALLEGRO_DISPLAY*)disp; + event.touch.timestamp = timestamp; + event.touch.id = id; + event.touch.x = x; + event.touch.y = y; + event.touch.dx = dx; + event.touch.dy = dy; + event.touch.primary = primary; + + _al_event_source_lock(&touch_input.es); + _al_event_source_emit_event(&touch_input.es, &event); + _al_event_source_unlock(&touch_input.es); + } + + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_NONE) { + mouse_state.x = (int)x; + mouse_state.y = (int)y; + if (type == ALLEGRO_EVENT_TOUCH_BEGIN) + mouse_state.buttons++; + else if (type == ALLEGRO_EVENT_TOUCH_END) + mouse_state.buttons--; + + mouse_state.pressure = mouse_state.buttons ? 1.0 : 0.0; /* TODO */ + + _al_event_source_lock(&touch_input.mouse_emulation_es); + if (want_mouse_emulation_event) { + + switch (type) { + case ALLEGRO_EVENT_TOUCH_BEGIN: type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; break; + case ALLEGRO_EVENT_TOUCH_CANCEL: + case ALLEGRO_EVENT_TOUCH_END: type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; break; + case ALLEGRO_EVENT_TOUCH_MOVE: type = ALLEGRO_EVENT_MOUSE_AXES; break; + } + + event.mouse.type = type; + event.mouse.timestamp = timestamp; + event.mouse.display = (ALLEGRO_DISPLAY*)disp; + event.mouse.x = (int)x; + event.mouse.y = (int)y; + event.mouse.dx = (int)dx; + event.mouse.dy = (int)dy; + event.mouse.dz = 0; + event.mouse.dw = 0; + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_5_0_x) { + event.mouse.button = 1; + } + else { + event.mouse.button = id; + } + event.mouse.pressure = mouse_state.pressure; + + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_5_0_x) { + al_set_mouse_xy(event.mouse.display, event.mouse.x, event.mouse.y); + } + + _al_event_source_emit_event(&touch_input.mouse_emulation_es, &event); + } + _al_event_source_unlock(&touch_input.mouse_emulation_es); + } +} + + +static bool init_touch_input(void) +{ + if (installed) + return false; + + reset_touch_input_state(); + memset(&mouse_state, 0, sizeof(mouse_state)); + + _al_event_source_init(&touch_input.es); + _al_event_source_init(&touch_input.mouse_emulation_es); + touch_input.mouse_emulation_mode = ALLEGRO_MOUSE_EMULATION_TRANSPARENT; + + installed = true; + + return true; +} + + +static void exit_touch_input(void) +{ + if (!installed) + return; + + reset_touch_input_state(); + memset(&mouse_state, 0, sizeof(mouse_state)); + + _al_event_source_free(&touch_input.es); + _al_event_source_free(&touch_input.mouse_emulation_es); + + installed = false; +} + + +static ALLEGRO_TOUCH_INPUT* get_touch_input(void) +{ + return &touch_input; +} + + +static void get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state) +{ + _al_event_source_lock(&touch_input.es); + *ret_state = touch_input_state; + _al_event_source_unlock(&touch_input.es); +} + + +static void set_mouse_emulation_mode(int mode) +{ + if (touch_input.mouse_emulation_mode != mode) { + + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) { + + ALLEGRO_TOUCH_STATE* touch = touch_input_state.touches + i; + + if (touch->id > 0) { + android_touch_input_handle_cancel(touch->id, al_get_time(), + touch->x, touch->y, touch->primary, touch->display); + } + } + + touch_input.mouse_emulation_mode = mode; + } +} + + +static ALLEGRO_TOUCH_STATE* find_free_touch_state(void) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) + if (touch_input_state.touches[i].id < 0) + return touch_input_state.touches + i; + + return NULL; +} + + +static ALLEGRO_TOUCH_STATE* find_touch_state_with_id(int id) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) + if (touch_input_state.touches[i].id == id) + return touch_input_state.touches + i; + + return NULL; +} + + +static void android_touch_input_handle_begin(int id, double timestamp, + float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = find_free_touch_state(); + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->id = id; + state->x = x; + state->y = y; + state->dx = 0.0f; + state->dy = 0.0f; + state->primary = primary; + state->display = disp; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_BEGIN, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, + disp); +} + + +static void android_touch_input_handle_end(int id, double timestamp, + float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = find_touch_state_with_id(id); + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_END, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, + disp); + + _al_event_source_lock(&touch_input.es); + state->id = -1; + _al_event_source_unlock(&touch_input.es); +} + + +static void android_touch_input_handle_move(int id, double timestamp, + float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = find_touch_state_with_id(id); + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_MOVE, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, + disp); +} + + +static void android_touch_input_handle_cancel(int id, double timestamp, + float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = find_touch_state_with_id(id); + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_CANCEL, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, disp); + + _al_event_source_lock(&touch_input.es); + state->id = -1; + _al_event_source_unlock(&touch_input.es); +} + + +JNI_FUNC(void, TouchListener, nativeOnTouch, (JNIEnv *env, jobject obj, + jint id, jint action, jfloat x, jfloat y, jboolean primary)) +{ + (void)env; + (void)obj; + + ALLEGRO_SYSTEM *system = al_get_system_driver(); + ASSERT(system != NULL); + + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&system->displays, 0); + ALLEGRO_DISPLAY *display = *dptr; + ASSERT(display != NULL); + + switch (action) { + case ALLEGRO_EVENT_TOUCH_BEGIN: + android_touch_input_handle_begin(id, al_get_time(), x, y, primary, + display); + break; + + case ALLEGRO_EVENT_TOUCH_END: + android_touch_input_handle_end(id, al_get_time(), x, y, primary, + display); + break; + + case ALLEGRO_EVENT_TOUCH_MOVE: + android_touch_input_handle_move(id, al_get_time(), x, y, primary, + display); + break; + + case ALLEGRO_EVENT_TOUCH_CANCEL: + android_touch_input_handle_cancel(id, al_get_time(), x, y, + primary, display); + break; + + default: + ALLEGRO_ERROR("unknown touch action: %i", action); + break; + } +} + + +/* the driver vtable */ +#define TOUCH_INPUT_ANDROID AL_ID('A','T','I','D') + +static ALLEGRO_TOUCH_INPUT_DRIVER touch_input_driver = +{ + TOUCH_INPUT_ANDROID, + init_touch_input, + exit_touch_input, + get_touch_input, + get_touch_input_state, + set_mouse_emulation_mode, + NULL +}; + + +ALLEGRO_TOUCH_INPUT_DRIVER *_al_get_android_touch_input_driver(void) +{ + return &touch_input_driver; +} + + +void _al_android_mouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + _al_event_source_lock(&touch_input.es); + *ret_state = mouse_state; + _al_event_source_unlock(&touch_input.es); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/android/jni_helpers.c b/allegro/src/android/jni_helpers.c new file mode 100644 index 00000000..ffe98360 --- /dev/null +++ b/allegro/src/android/jni_helpers.c @@ -0,0 +1,133 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Android jni helpers + * + * By Thomas Fjellstrom. + * + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_android.h" +#include +#include + +ALLEGRO_DEBUG_CHANNEL("jni") + +#define VERBOSE_DEBUG(a, ...) (void)0 + +/* jni helpers */ + +void __jni_checkException(JNIEnv *env, const char *file, const char *func, int line) +{ + jthrowable exc; + + exc = (*env)->ExceptionOccurred(env); + if (exc) { + ALLEGRO_DEBUG("GOT AN EXCEPTION @ %s:%i %s", file, line, func); + /* We don't do much with the exception, except that + we print a debug message for it, clear it, and + throw a new exception. */ + (*env)->ExceptionDescribe(env); + (*env)->ExceptionClear(env); + (*env)->FatalError(env, "EXCEPTION"); + //(*env)->ThrowNew(env, system_data.illegal_argument_exception_class, "thrown from C code"); + } +} + +jobject _jni_callObjectMethod(JNIEnv *env, jobject object, + const char *name, const char *sig) +{ + VERBOSE_DEBUG("%s (%s)", name, sig); + + jclass class_id = _jni_call(env, jclass, GetObjectClass, object); + jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, name, sig); + jobject ret = _jni_call(env, jobject, CallObjectMethod, object, method_id); + + _jni_callv(env, DeleteLocalRef, class_id); + + return ret; +} + +jobject _jni_callObjectMethodV(JNIEnv *env, jobject object, + const char *name, const char *sig, ...) +{ + va_list ap; + + VERBOSE_DEBUG("%s (%s)", name, sig); + + jclass class_id = _jni_call(env, jclass, GetObjectClass, object); + jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, name, sig); + + va_start(ap, sig); + jobject ret = _jni_call(env, jobject, CallObjectMethodV, object, method_id, ap); + va_end(ap); + + _jni_callv(env, DeleteLocalRef, class_id); + + VERBOSE_DEBUG("callObjectMethodV end"); + return ret; +} + +ALLEGRO_USTR *_jni_getString(JNIEnv *env, jobject object) +{ + VERBOSE_DEBUG("GetStringUTFLength"); + jsize len = _jni_call(env, jsize, GetStringUTFLength, object); + + const char *str = _jni_call(env, const char *, GetStringUTFChars, object, NULL); + + VERBOSE_DEBUG("al_ustr_new_from_buffer"); + ALLEGRO_USTR *ustr = al_ustr_new_from_buffer(str, len); + + _jni_callv(env, ReleaseStringUTFChars, object, str); + + return ustr; +} + +ALLEGRO_USTR *_jni_callStringMethod(JNIEnv *env, jobject obj, + const char *name, const char *sig) +{ + jobject str_obj = _jni_callObjectMethod(env, obj, name, sig); + return _jni_getString(env, str_obj); +} + +jobject _jni_callStaticObjectMethodV(JNIEnv *env, jclass cls, + const char *name, const char *sig, ...) +{ + jmethodID mid; + jobject ret; + va_list ap; + + mid = _jni_call(env, jmethodID, GetStaticMethodID, cls, name, sig); + + va_start(ap, sig); + ret = _jni_call(env, jobject, CallStaticObjectMethodV, cls, mid, ap); + va_end(ap); + + return ret; +} + +jint _jni_callStaticIntMethodV(JNIEnv *env, jclass cls, + const char *name, const char *sig, ...) +{ + jmethodID mid; + jint ret; + va_list ap; + + mid = _jni_call(env, jmethodID, GetStaticMethodID, cls, name, sig); + + va_start(ap, sig); + ret = _jni_call(env, jint, CallStaticIntMethodV, cls, mid, ap); + va_end(ap); + + return ret; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/bitmap.c b/allegro/src/bitmap.c new file mode 100644 index 00000000..77c76c29 --- /dev/null +++ b/allegro/src/bitmap.c @@ -0,0 +1,813 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New bitmap routines. + * + * By Elias Pschernig and Trent Gamblin. + * + * See readme.txt for copyright information. + */ + +/* Title: Bitmap routines + */ + + +#include +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_shader.h" +#include "allegro5/internal/aintern_system.h" + +ALLEGRO_DEBUG_CHANNEL("bitmap") + + +/* Creates a memory bitmap. + */ +static ALLEGRO_BITMAP *create_memory_bitmap(ALLEGRO_DISPLAY *current_display, + int w, int h, int format, int flags) +{ + ALLEGRO_BITMAP *bitmap; + int pitch; + + if (_al_pixel_format_is_video_only(format)) { + /* Can't have a video-only memory bitmap... */ + return NULL; + } + + format = _al_get_real_pixel_format(current_display, format); + + bitmap = al_calloc(1, sizeof *bitmap); + + pitch = w * al_get_pixel_size(format); + + bitmap->vt = NULL; + bitmap->_format = format; + + /* If this is really a video bitmap, we add it to the list of to + * be converted bitmaps. + */ + bitmap->_flags = flags | ALLEGRO_MEMORY_BITMAP; + bitmap->_flags &= ~ALLEGRO_VIDEO_BITMAP; + bitmap->w = w; + bitmap->h = h; + bitmap->pitch = pitch; + bitmap->_display = NULL; + bitmap->locked = false; + bitmap->cl = bitmap->ct = 0; + bitmap->cr_excl = w; + bitmap->cb_excl = h; + al_identity_transform(&bitmap->transform); + al_identity_transform(&bitmap->inverse_transform); + bitmap->inverse_transform_dirty = false; + al_identity_transform(&bitmap->proj_transform); + al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, w, h, 1.0); + bitmap->parent = NULL; + bitmap->xofs = bitmap->yofs = 0; + bitmap->memory = al_malloc(pitch * h); + bitmap->use_bitmap_blender = false; + bitmap->blender.blend_color = al_map_rgba(0, 0, 0, 0); + + _al_register_convert_bitmap(bitmap); + return bitmap; +} + + + +static void destroy_memory_bitmap(ALLEGRO_BITMAP *bmp) +{ + _al_unregister_convert_bitmap(bmp); + + if (bmp->memory) + al_free(bmp->memory); + al_free(bmp); +} + + + +ALLEGRO_BITMAP *_al_create_bitmap_params(ALLEGRO_DISPLAY *current_display, + int w, int h, int format, int flags, int depth, int samples) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + ALLEGRO_BITMAP *bitmap; + ALLEGRO_BITMAP **back; + int64_t mul; + bool result; + + /* Reject bitmaps where a calculation pixel_size*w*h would overflow + * int. Supporting such bitmaps would require a lot more work. + */ + mul = 4 * (int64_t) w * (int64_t) h; + if (mul > (int64_t) INT_MAX) { + ALLEGRO_WARN("Rejecting %dx%d bitmap\n", w, h); + return NULL; + } + + if ((flags & ALLEGRO_MEMORY_BITMAP) || + !current_display || + !current_display->vt || + current_display->vt->create_bitmap == NULL || + _al_vector_size(&system->displays) < 1) + { + if (flags & ALLEGRO_VIDEO_BITMAP) + return NULL; + + return create_memory_bitmap(current_display, w, h, format, flags); + } + + /* Else it's a display bitmap */ + + bitmap = current_display->vt->create_bitmap(current_display, w, h, + format, flags); + if (!bitmap) { + ALLEGRO_ERROR("failed to create display bitmap\n"); + return NULL; + } + + bitmap->_display = current_display; + bitmap->w = w; + bitmap->h = h; + bitmap->locked = false; + bitmap->cl = 0; + bitmap->ct = 0; + bitmap->cr_excl = w; + bitmap->cb_excl = h; + al_identity_transform(&bitmap->transform); + al_identity_transform(&bitmap->inverse_transform); + bitmap->inverse_transform_dirty = false; + al_identity_transform(&bitmap->proj_transform); + al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, w, h, 1.0); + bitmap->parent = NULL; + bitmap->xofs = 0; + bitmap->yofs = 0; + bitmap->_flags |= ALLEGRO_VIDEO_BITMAP; + bitmap->dirty = !(bitmap->_flags & ALLEGRO_NO_PRESERVE_TEXTURE); + bitmap->_depth = depth; + bitmap->_samples = samples; + bitmap->use_bitmap_blender = false; + bitmap->blender.blend_color = al_map_rgba(0, 0, 0, 0); + + /* The display driver should have set the bitmap->memory field if + * appropriate; video bitmaps may leave it NULL. + */ + + ASSERT(bitmap->pitch >= w * al_get_pixel_size(bitmap->_format)); + result = bitmap->vt->upload_bitmap(bitmap); + + if (!result) { + al_destroy_bitmap(bitmap); + if (flags & ALLEGRO_VIDEO_BITMAP) + return NULL; + /* With ALLEGRO_CONVERT_BITMAP, just use a memory bitmap instead if + * video failed. + */ + return create_memory_bitmap(current_display, w, h, format, flags); + } + + /* We keep a list of bitmaps depending on the current display so that we can + * convert them to memory bimaps when the display is destroyed. */ + back = _al_vector_alloc_back(¤t_display->bitmaps); + *back = bitmap; + + return bitmap; +} + + +/* Function: al_create_bitmap + */ +ALLEGRO_BITMAP *al_create_bitmap(int w, int h) +{ + ALLEGRO_BITMAP *bitmap; + + bitmap = _al_create_bitmap_params(al_get_current_display(), w, h, + al_get_new_bitmap_format(), al_get_new_bitmap_flags(), + al_get_new_bitmap_depth(), al_get_new_bitmap_samples()); + if (bitmap) { + bitmap->dtor_item = _al_register_destructor(_al_dtor_list, "bitmap", bitmap, + (void (*)(void *))al_destroy_bitmap); + } + + return bitmap; +} + + +/* Function: al_destroy_bitmap + */ +void al_destroy_bitmap(ALLEGRO_BITMAP *bitmap) +{ + if (!bitmap) { + return; + } + + /* As a convenience, implicitly untarget the bitmap on the calling thread + * before it is destroyed, but maintain the current display. + */ + if (bitmap == al_get_target_bitmap()) { + ALLEGRO_DISPLAY *display = al_get_current_display(); + if (display) + al_set_target_bitmap(al_get_backbuffer(display)); + else + al_set_target_bitmap(NULL); + } + + _al_set_bitmap_shader_field(bitmap, NULL); + + _al_unregister_destructor(_al_dtor_list, bitmap->dtor_item); + + if (!al_is_sub_bitmap(bitmap)) { + ALLEGRO_DISPLAY* disp = _al_get_bitmap_display(bitmap); + if (al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP) { + destroy_memory_bitmap(bitmap); + return; + } + + /* Else it's a display bitmap */ + + if (bitmap->locked) + al_unlock_bitmap(bitmap); + + if (bitmap->vt) + bitmap->vt->destroy_bitmap(bitmap); + + if (disp) + _al_vector_find_and_delete(&disp->bitmaps, &bitmap); + + if (bitmap->memory) + al_free(bitmap->memory); + } + + al_free(bitmap); +} + + +/* Function: al_convert_mask_to_alpha + */ +void al_convert_mask_to_alpha(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color) +{ + ALLEGRO_LOCKED_REGION *lr; + int x, y; + ALLEGRO_COLOR pixel; + ALLEGRO_COLOR alpha_pixel; + ALLEGRO_STATE state; + + if (!(lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ANY, 0))) { + ALLEGRO_ERROR("Couldn't lock bitmap."); + return; + } + + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); + al_set_target_bitmap(bitmap); + + alpha_pixel = al_map_rgba(0, 0, 0, 0); + + for (y = 0; y < bitmap->h; y++) { + for (x = 0; x < bitmap->w; x++) { + pixel = al_get_pixel(bitmap, x, y); + if (memcmp(&pixel, &mask_color, sizeof(ALLEGRO_COLOR)) == 0) { + al_put_pixel(x, y, alpha_pixel); + } + } + } + + al_unlock_bitmap(bitmap); + + al_restore_state(&state); +} + + + +/* Function: al_get_bitmap_width + */ +int al_get_bitmap_width(ALLEGRO_BITMAP *bitmap) +{ + return bitmap->w; +} + + + +/* Function: al_get_bitmap_height + */ +int al_get_bitmap_height(ALLEGRO_BITMAP *bitmap) +{ + return bitmap->h; +} + + + +/* Function: al_get_bitmap_format + */ +int al_get_bitmap_format(ALLEGRO_BITMAP *bitmap) +{ + if (bitmap->parent) + return bitmap->parent->_format; + else + return bitmap->_format; +} + + +int _al_get_bitmap_memory_format(ALLEGRO_BITMAP *bitmap) +{ + if (bitmap->parent) + return bitmap->parent->_memory_format; + else + return bitmap->_memory_format; +} + + + +/* Function: al_get_bitmap_flags + */ +int al_get_bitmap_flags(ALLEGRO_BITMAP *bitmap) +{ + if (bitmap->parent) + return bitmap->parent->_flags; + else + return bitmap->_flags; +} + + +ALLEGRO_DISPLAY *_al_get_bitmap_display(ALLEGRO_BITMAP *bitmap) +{ + if (bitmap->parent) + return bitmap->parent->_display; + else + return bitmap->_display; +} + + +/* Function: al_get_bitmap_depth + */ +int al_get_bitmap_depth(ALLEGRO_BITMAP *bitmap) +{ + if (bitmap->parent) + return bitmap->parent->_depth; + else + return bitmap->_depth; +} + + +/* Function: al_get_bitmap_samples + */ +int al_get_bitmap_samples(ALLEGRO_BITMAP *bitmap) +{ + if (bitmap->parent) + return bitmap->parent->_samples; + else + return bitmap->_samples; +} + +/* Function: al_get_bitmap_blend_color + */ +ALLEGRO_COLOR al_get_bitmap_blend_color(void) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + ALLEGRO_BLENDER *b; + + ASSERT(bitmap); + + if (!bitmap->use_bitmap_blender) { + /* If no bitmap blender set, use TLS */ + return al_get_blend_color(); + } + + b = &bitmap->blender; + return b->blend_color; +} + +/* Function: al_get_bitmap_blender + */ +void al_get_bitmap_blender(int *op, int *src, int *dst) +{ + al_get_separate_bitmap_blender(op, src, dst, NULL, NULL, NULL); +} + +/* Function: al_get_separate_bitmap_blender + */ +void al_get_separate_bitmap_blender(int *op, int *src, int *dst, int *alpha_op, int *alpha_src, int *alpha_dst) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + ALLEGRO_BLENDER *b; + + ASSERT(bitmap); + + if (!bitmap->use_bitmap_blender) { + /* If no bitmap blender set, use TLS */ + al_get_separate_blender(op, src, dst, alpha_op, alpha_src, alpha_dst); + return; + } + + b = &bitmap->blender; + + if (op) + *op = b->blend_op; + + if (src) + *src = b->blend_source; + + if (dst) + *dst = b->blend_dest; + + if (alpha_op) + *alpha_op = b->blend_alpha_op; + + if (alpha_src) + *alpha_src = b->blend_alpha_source; + + if (alpha_dst) + *alpha_dst = b->blend_alpha_dest; +} + +/* Function: al_set_bitmap_blend_color + */ +void al_set_bitmap_blend_color(ALLEGRO_COLOR col) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + ALLEGRO_BLENDER *b; + + ASSERT(bitmap); + + b = &bitmap->blender; + b->blend_color = col; +} + +/* Function: al_set_bitmap_blender + */ +void al_set_bitmap_blender(int op, int src, int dest) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + + ASSERT(bitmap); + + al_set_separate_bitmap_blender(op, src, dest, op, src, dest); +} + +/* Function: al_set_separate_bitmap_blender + */ +void al_set_separate_bitmap_blender(int op, int src, int dst, int alpha_op, int alpha_src, int alpha_dst) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + ALLEGRO_BLENDER *b; + + ASSERT(bitmap); + + bitmap->use_bitmap_blender = true; + b = &bitmap->blender; + b->blend_op = op; + b->blend_source = src; + b->blend_dest = dst; + b->blend_alpha_op = alpha_op; + b->blend_alpha_source = alpha_src; + b->blend_alpha_dest = alpha_dst; +} + +/* Function: al_reset_bitmap_blender + */ +void al_reset_bitmap_blender(void) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + + ASSERT(bitmap); + + bitmap->use_bitmap_blender = false; + bitmap->blender.blend_color = al_map_rgba(0, 0, 0, 0); +} + +/* Function: al_set_clipping_rectangle + */ +void al_set_clipping_rectangle(int x, int y, int width, int height) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + + ASSERT(bitmap); + + if (x < 0) { + width += x; + x = 0; + } + if (y < 0) { + height += y; + y = 0; + } + if (x + width > bitmap->w) { + width = bitmap->w - x; + } + if (y + height > bitmap->h) { + height = bitmap->h - y; + } + if (width < 0) { + width = 0; + } + if (height < 0) { + height = 0; + } + + bitmap->cl = x; + bitmap->ct = y; + bitmap->cr_excl = x + width; + bitmap->cb_excl = y + height; + + if (bitmap->vt && bitmap->vt->update_clipping_rectangle) { + bitmap->vt->update_clipping_rectangle(bitmap); + } +} + + + +/* Function: al_reset_clipping_rectangle + */ +void al_reset_clipping_rectangle(void) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + + if (bitmap) { + int w = al_get_bitmap_width(bitmap); + int h = al_get_bitmap_height(bitmap); + al_set_clipping_rectangle(0, 0, w, h); + } +} + + + +/* Function: al_get_clipping_rectangle + */ +void al_get_clipping_rectangle(int *x, int *y, int *w, int *h) +{ + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + + ASSERT(bitmap); + + if (x) *x = bitmap->cl; + if (y) *y = bitmap->ct; + if (w) *w = bitmap->cr_excl - bitmap->cl; + if (h) *h = bitmap->cb_excl - bitmap->ct; +} + + + +/* Function: al_create_sub_bitmap + */ +ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent, + int x, int y, int w, int h) +{ + ALLEGRO_BITMAP *bitmap; + + if (parent->parent) { + x += parent->xofs; + y += parent->yofs; + parent = parent->parent; + } + + bitmap = al_calloc(1, sizeof *bitmap); + bitmap->vt = parent->vt; + + /* Sub-bitmap inherits these from the parent. + * Leave these unchanged so they can be detected if improperly accessed + * directly. */ + bitmap->_format = 0; + bitmap->_flags = 0; + bitmap->_display = (ALLEGRO_DISPLAY*)0x1; + + bitmap->w = w; + bitmap->h = h; + bitmap->locked = false; + bitmap->cl = bitmap->ct = 0; + bitmap->cr_excl = w; + bitmap->cb_excl = h; + al_identity_transform(&bitmap->transform); + al_identity_transform(&bitmap->inverse_transform); + bitmap->inverse_transform_dirty = false; + al_identity_transform(&bitmap->proj_transform); + al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, w, h, 1.0); + bitmap->shader = NULL; + bitmap->parent = parent; + bitmap->xofs = x; + bitmap->yofs = y; + bitmap->memory = NULL; + + bitmap->dtor_item = _al_register_destructor(_al_dtor_list, "sub_bitmap", bitmap, + (void (*)(void *))al_destroy_bitmap); + + return bitmap; +} + + +/* Function: al_reparent_bitmap + */ +void al_reparent_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP *parent, + int x, int y, int w, int h) +{ + ASSERT(bitmap->parent); + /* Re-parenting a non-sub-bitmap makes no sense, so in release mode + * just ignore it. */ + if (!bitmap->parent) + return; + + if (parent->parent) { + x += parent->xofs; + y += parent->yofs; + parent = parent->parent; + } + + bitmap->parent = parent; + bitmap->xofs = x; + bitmap->yofs = y; + bitmap->w = w; + bitmap->h = h; +} + + +/* Function: al_is_sub_bitmap + */ +bool al_is_sub_bitmap(ALLEGRO_BITMAP *bitmap) +{ + return (bitmap->parent != NULL); +} + + +/* Function: al_get_parent_bitmap + */ +ALLEGRO_BITMAP *al_get_parent_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ASSERT(bitmap); + return bitmap->parent; +} + + +/* Function: al_get_bitmap_x + */ +int al_get_bitmap_x(ALLEGRO_BITMAP *bitmap) +{ + ASSERT(bitmap); + return bitmap->xofs; +} + + +/* Function: al_get_bitmap_y + */ +int al_get_bitmap_y(ALLEGRO_BITMAP *bitmap) +{ + ASSERT(bitmap); + return bitmap->yofs; +} + + +static bool transfer_bitmap_data(ALLEGRO_BITMAP *src, ALLEGRO_BITMAP *dst) +{ + ALLEGRO_LOCKED_REGION *dst_region; + ALLEGRO_LOCKED_REGION *src_region; + int src_format = al_get_bitmap_format(src); + int dst_format = al_get_bitmap_format(dst); + bool src_compressed = _al_pixel_format_is_compressed(src_format); + bool dst_compressed = _al_pixel_format_is_compressed(dst_format); + int copy_w = src->w; + int copy_h = src->h; + + if (src_compressed && dst_compressed && src_format == dst_format) { + int block_width = al_get_pixel_block_width(src_format); + int block_height = al_get_pixel_block_height(src_format); + if (!(src_region = al_lock_bitmap_blocked(src, ALLEGRO_LOCK_READONLY))) + return false; + + if (!(dst_region = al_lock_bitmap_blocked(dst, ALLEGRO_LOCK_WRITEONLY))) { + al_unlock_bitmap(src); + return false; + } + copy_w = _al_get_least_multiple(copy_w, block_width); + copy_h = _al_get_least_multiple(copy_h, block_height); + ALLEGRO_DEBUG("Taking fast clone path.\n"); + } + else { + int lock_format = ALLEGRO_PIXEL_FORMAT_ANY; + /* Go through a non-compressed intermediate */ + if (src_compressed && !dst_compressed) { + lock_format = dst_format; + } + else if (!src_compressed && dst_compressed) { + lock_format = src_format; + } + + if (!(src_region = al_lock_bitmap(src, lock_format, ALLEGRO_LOCK_READONLY))) + return false; + + if (!(dst_region = al_lock_bitmap(dst, lock_format, ALLEGRO_LOCK_WRITEONLY))) { + al_unlock_bitmap(src); + return false; + } + } + + _al_convert_bitmap_data( + src_region->data, src_region->format, src_region->pitch, + dst_region->data, dst_region->format, dst_region->pitch, + 0, 0, 0, 0, copy_w, copy_h); + + al_unlock_bitmap(src); + al_unlock_bitmap(dst); + + return true; +} + + +void _al_copy_bitmap_data( + const void *src, int src_pitch, void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height, + int format) +{ + int block_width = al_get_pixel_block_width(format); + int block_height = al_get_pixel_block_height(format); + int block_size = al_get_pixel_block_size(format); + const char *src_ptr = src; + char *dst_ptr = dst; + int y; + + ASSERT(src); + ASSERT(dst); + ASSERT(_al_pixel_format_is_real(format)); + ASSERT(width % block_width == 0); + ASSERT(height % block_height == 0); + ASSERT(sx % block_width == 0); + ASSERT(sy % block_height == 0); + ASSERT(dx % block_width == 0); + ASSERT(dy % block_height == 0); + + sx /= block_width; + sy /= block_height; + dx /= block_width; + dy /= block_height; + width /= block_width; + height /= block_height; + + if ((src_ptr == dst_ptr) && (src_pitch == dst_pitch)) { + return; + } + + src_ptr += sy * src_pitch + sx * block_size; + dst_ptr += dy * dst_pitch + dx * block_size; + + for (y = 0; y < height; y++) { + memcpy(dst_ptr, src_ptr, width * block_size); + src_ptr += src_pitch; + dst_ptr += dst_pitch; + } +} + +void _al_convert_bitmap_data( + const void *src, int src_format, int src_pitch, + void *dst, int dst_format, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + ASSERT(src); + ASSERT(dst); + ASSERT(_al_pixel_format_is_real(dst_format)); + + /* Use memcpy if no conversion is needed. */ + if (src_format == dst_format) { + _al_copy_bitmap_data(src, src_pitch, dst, dst_pitch, sx, sy, + dx, dy, width, height, src_format); + return; + } + + /* Video-only formats don't have conversion functions, so they should have + * been taken care of before reaching this location. */ + ASSERT(!_al_pixel_format_is_video_only(src_format)); + ASSERT(!_al_pixel_format_is_video_only(dst_format)); + + (_al_convert_funcs[src_format][dst_format])(src, src_pitch, + dst, dst_pitch, sx, sy, dx, dy, width, height); +} + + +/* Function: al_clone_bitmap + */ +ALLEGRO_BITMAP *al_clone_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP *clone; + ASSERT(bitmap); + + clone = al_create_bitmap(bitmap->w, bitmap->h); + if (!clone) + return NULL; + if (!transfer_bitmap_data(bitmap, clone)) { + al_destroy_bitmap(clone); + return NULL; + } + return clone; +} + +/* Function: al_backup_dirty_bitmap + */ +void al_backup_dirty_bitmap(ALLEGRO_BITMAP *bitmap) +{ + if (bitmap->vt && bitmap->vt->backup_dirty_bitmap) + bitmap->vt->backup_dirty_bitmap(bitmap); +} + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/src/bitmap_draw.c b/allegro/src/bitmap_draw.c new file mode 100644 index 00000000..cd01dfd1 --- /dev/null +++ b/allegro/src/bitmap_draw.c @@ -0,0 +1,253 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Bitmap drawing routines. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_memblit.h" +#include "allegro5/internal/aintern_pixels.h" + + +static ALLEGRO_COLOR solid_white = {1, 1, 1, 1}; + + +static void _bitmap_drawer(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, + float sx, float sy, float sw, float sh, int flags) +{ + ALLEGRO_BITMAP *dest = al_get_target_bitmap(); + ALLEGRO_DISPLAY *display = _al_get_bitmap_display(dest); + ASSERT(bitmap->parent == NULL); + ASSERT(!(flags & (ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL))); + ASSERT(bitmap != dest && bitmap != dest->parent); + + /* If destination is memory, do a memory blit */ + if (al_get_bitmap_flags(dest) & ALLEGRO_MEMORY_BITMAP || + _al_pixel_format_is_compressed(al_get_bitmap_format(dest))) { + _al_draw_bitmap_region_memory(bitmap, tint, sx, sy, sw, sh, 0, 0, flags); + } + else { + /* if source is memory or incompatible */ + if ((al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP) || + (!al_is_compatible_bitmap(bitmap))) + { + if (display && display->vt->draw_memory_bitmap_region) { + display->vt->draw_memory_bitmap_region(display, bitmap, + sx, sy, sw, sh, flags); + } + else { + _al_draw_bitmap_region_memory(bitmap, tint, sx, sy, sw, sh, 0, 0, flags); + } + } + else { + /* Compatible display bitmap, use full acceleration */ + bitmap->vt->draw_bitmap_region(bitmap, tint, sx, sy, sw, sh, flags); + } + } +} + + +static void _draw_tinted_rotated_scaled_bitmap_region(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, float cx, float cy, float angle, + float xscale, float yscale, + float sx, float sy, float sw, float sh, float dx, float dy, + int flags) +{ + ALLEGRO_TRANSFORM backup; + ALLEGRO_TRANSFORM t; + ALLEGRO_BITMAP *parent = bitmap; + float const orig_sw = sw; + float const orig_sh = sh; + ASSERT(bitmap); + + al_copy_transform(&backup, al_get_current_transform()); + al_identity_transform(&t); + + if (bitmap->parent) { + parent = bitmap->parent; + sx += bitmap->xofs; + sy += bitmap->yofs; + } + + if (sx < 0) { + sw += sx; + al_translate_transform(&t, -sx, 0); + sx = 0; + } + if (sy < 0) { + sh += sy; + al_translate_transform(&t, 0, -sy); + sy = 0; + } + if (sx + sw > parent->w) + sw = parent->w - sx; + if (sy + sh > parent->h) + sh = parent->h - sy; + + if (flags & ALLEGRO_FLIP_HORIZONTAL) { + al_scale_transform(&t, -1, 1); + al_translate_transform(&t, orig_sw, 0); + flags &= ~ALLEGRO_FLIP_HORIZONTAL; + } + + if (flags & ALLEGRO_FLIP_VERTICAL) { + al_scale_transform(&t, 1, -1); + al_translate_transform(&t, 0, orig_sh); + flags &= ~ALLEGRO_FLIP_VERTICAL; + } + + al_translate_transform(&t, -cx, -cy); + al_scale_transform(&t, xscale, yscale); + al_rotate_transform(&t, angle); + al_translate_transform(&t, dx, dy); + al_compose_transform(&t, &backup); + + al_use_transform(&t); + _bitmap_drawer(parent, tint, sx, sy, sw, sh, flags); + al_use_transform(&backup); +} + + +/* Function: al_draw_tinted_bitmap_region + */ +void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float sx, float sy, float sw, float sh, float dx, float dy, + int flags) +{ + _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint, + 0, 0, 0, 1, 1, sx, sy, sw, sh, dx, dy, flags); +} + + +/* Function: al_draw_tinted_bitmap + */ +void al_draw_tinted_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, + float dx, float dy, int flags) +{ + ASSERT(bitmap); + al_draw_tinted_bitmap_region(bitmap, tint, 0, 0, + bitmap->w, bitmap->h, dx, dy, flags); +} + + +/* Function: al_draw_bitmap + */ +void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags) +{ + al_draw_tinted_bitmap(bitmap, solid_white, dx, dy, flags); +} + + +/* Function: al_draw_bitmap_region + */ +void al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, float dx, float dy, int flags) +{ + al_draw_tinted_bitmap_region(bitmap, solid_white, sx, sy, sw, sh, + dx, dy, flags); +} + + +/* Function: al_draw_tinted_scaled_bitmap + */ +void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float sx, float sy, float sw, float sh, + float dx, float dy, float dw, float dh, int flags) +{ + _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint, + 0, 0, 0, + dw / sw, dh / sh, + sx, sy, sw, sh, dx, dy, flags); +} + + +/* Function: al_draw_scaled_bitmap + */ +void al_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, + float dx, float dy, float dw, float dh, int flags) +{ + al_draw_tinted_scaled_bitmap(bitmap, solid_white, sx, sy, sw, sh, + dx, dy, dw, dh, flags); +} + + +/* Function: al_draw_tinted_rotated_bitmap + * + * angle is specified in radians and moves clockwise + * on the screen. + */ +void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float cx, float cy, float dx, float dy, float angle, int flags) +{ + al_draw_tinted_scaled_rotated_bitmap(bitmap, tint, cx, cy, dx, dy, + 1, 1, angle, flags); +} + + +/* Function: al_draw_rotated_bitmap + */ +void al_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap, + float cx, float cy, float dx, float dy, float angle, int flags) +{ + al_draw_tinted_rotated_bitmap(bitmap, solid_white, cx, cy, dx, dy, + angle, flags); +} + + +/* Function: al_draw_tinted_scaled_rotated_bitmap + */ +void al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float cx, float cy, float dx, float dy, float xscale, float yscale, + float angle, int flags) +{ + _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint, + cx, cy, angle, + xscale, yscale, + 0, 0, bitmap->w, bitmap->h, dx, dy, flags); +} + + +/* Function: al_draw_tinted_scaled_rotated_bitmap_region + */ +void al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP *bitmap, + float sx, float sy, float sw, float sh, + ALLEGRO_COLOR tint, + float cx, float cy, float dx, float dy, float xscale, float yscale, + float angle, int flags) +{ + _draw_tinted_rotated_scaled_bitmap_region(bitmap, tint, + cx, cy, angle, + xscale, yscale, + sx, sy, sw, sh, dx, dy, flags); +} + + +/* Function: al_draw_scaled_rotated_bitmap + */ +void al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap, + float cx, float cy, float dx, float dy, float xscale, float yscale, + float angle, int flags) +{ + al_draw_tinted_scaled_rotated_bitmap(bitmap, solid_white, + cx, cy, dx, dy, xscale, yscale, angle, flags); +} + + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/src/bitmap_io.c b/allegro/src/bitmap_io.c new file mode 100644 index 00000000..77055b4d --- /dev/null +++ b/allegro/src/bitmap_io.c @@ -0,0 +1,318 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Bitmap I/O framework. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_vector.h" + +#include + +ALLEGRO_DEBUG_CHANNEL("bitmap") + +#define MAX_EXTENSION (32) + + +typedef struct Handler +{ + char extension[MAX_EXTENSION]; + ALLEGRO_IIO_LOADER_FUNCTION loader; + ALLEGRO_IIO_SAVER_FUNCTION saver; + ALLEGRO_IIO_FS_LOADER_FUNCTION fs_loader; + ALLEGRO_IIO_FS_SAVER_FUNCTION fs_saver; + ALLEGRO_IIO_IDENTIFIER_FUNCTION identifier; +} Handler; + + +/* globals */ +static _AL_VECTOR iio_table = _AL_VECTOR_INITIALIZER(Handler); + + +static Handler *add_iio_table_f(const char *ext) +{ + Handler *ent; + + ent = _al_vector_alloc_back(&iio_table); + strcpy(ent->extension, ext); + ent->loader = NULL; + ent->saver = NULL; + ent->fs_loader = NULL; + ent->fs_saver = NULL; + ent->identifier = NULL; + + return ent; +} + + +static Handler *find_handler(const char *extension, bool create_if_not) +{ + unsigned i; + + ASSERT(extension); + + if (strlen(extension) + 1 >= MAX_EXTENSION) { + return NULL; + } + + for (i = 0; i < _al_vector_size(&iio_table); i++) { + Handler *l = _al_vector_ref(&iio_table, i); + if (0 == _al_stricmp(extension, l->extension)) { + return l; + } + } + + if (create_if_not) + return add_iio_table_f(extension); + + return NULL; +} + + +static Handler *find_handler_for_file(ALLEGRO_FILE *f) +{ + unsigned i; + + ASSERT(f); + + for (i = 0; i < _al_vector_size(&iio_table); i++) { + Handler *l = _al_vector_ref(&iio_table, i); + if (l->identifier) { + int64_t pos = al_ftell(f); + bool identified = l->identifier(f); + al_fseek(f, pos, ALLEGRO_SEEK_SET); + if (identified) + return l; + } + } + return NULL; +} + + +static void free_iio_table(void) +{ + _al_vector_free(&iio_table); +} + + +void _al_init_iio_table(void) +{ + _al_add_exit_func(free_iio_table, "free_iio_table"); +} + +#define REGISTER(function) \ + Handler *ent = find_handler(extension, function != NULL); \ + if (!function) { \ + if (!ent || !ent->function) { \ + return false; /* Nothing to remove. */ \ + } \ + } \ + ent->function = function; \ + return true; + + +/* Function: al_register_bitmap_loader + */ +bool al_register_bitmap_loader(const char *extension, + ALLEGRO_BITMAP *(*loader)(const char *filename, int flags)) +{ + REGISTER(loader) +} + + +/* Function: al_register_bitmap_saver + */ +bool al_register_bitmap_saver(const char *extension, + bool (*saver)(const char *filename, ALLEGRO_BITMAP *bmp)) +{ + REGISTER(saver) +} + + +/* Function: al_register_bitmap_loader_f + */ +bool al_register_bitmap_loader_f(const char *extension, + ALLEGRO_BITMAP *(*fs_loader)(ALLEGRO_FILE *fp, int flags)) +{ + REGISTER(fs_loader) +} + + +/* Function: al_register_bitmap_saver_f + */ +bool al_register_bitmap_saver_f(const char *extension, + bool (*fs_saver)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp)) +{ + REGISTER(fs_saver) +} + + +/* Function: al_register_bitmap_identifier + */ +bool al_register_bitmap_identifier(const char *extension, + bool (*identifier)(ALLEGRO_FILE *f)) +{ + REGISTER(identifier) +} + + +/* Function: al_load_bitmap + */ +ALLEGRO_BITMAP *al_load_bitmap(const char *filename) +{ + int flags = 0; + + /* For backwards compatibility with the 5.0 branch. */ + if (al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA) { + flags |= ALLEGRO_NO_PREMULTIPLIED_ALPHA; + ALLEGRO_WARN("ALLEGRO_NO_PREMULTIPLIED_ALPHA in new_bitmap_flags " + "is deprecated\n"); + } + + return al_load_bitmap_flags(filename, flags); +} + + +/* Function: al_load_bitmap_flags + */ +ALLEGRO_BITMAP *al_load_bitmap_flags(const char *filename, int flags) +{ + const char *ext; + Handler *h; + ALLEGRO_BITMAP *ret; + + ext = al_identify_bitmap(filename); + if (!ext) { + ext = strrchr(filename, '.'); + if (!ext) { + ALLEGRO_ERROR("Could not identify bitmap %s!", filename); + return NULL; + } + } + + h = find_handler(ext, false); + if (h && h->loader) { + ret = h->loader(filename, flags); + if (!ret) + ALLEGRO_ERROR("Failed loading bitmap %s with %s handler.\n", + filename, ext); + } + else { + ALLEGRO_ERROR("No handler for bitmap %s!", filename); + ret = NULL; + } + + return ret; +} + + +/* Function: al_save_bitmap + */ +bool al_save_bitmap(const char *filename, ALLEGRO_BITMAP *bitmap) +{ + const char *ext; + Handler *h; + + ext = strrchr(filename, '.'); + if (!ext) { + ALLEGRO_ERROR("Unable to determine file format from %s\n", filename); + return false; + } + + h = find_handler(ext, false); + if (h && h->saver) + return h->saver(filename, bitmap); + else { + ALLEGRO_ERROR("No handler for image %s found\n", filename); + return false; + } +} + + +/* Function: al_load_bitmap_f + */ +ALLEGRO_BITMAP *al_load_bitmap_f(ALLEGRO_FILE *fp, const char *ident) +{ + int flags = 0; + + /* For backwards compatibility with the 5.0 branch. */ + if (al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA) { + flags |= ALLEGRO_NO_PREMULTIPLIED_ALPHA; + ALLEGRO_WARN("ALLEGRO_NO_PREMULTIPLIED_ALPHA in new_bitmap_flags " + "is deprecated\n"); + } + + return al_load_bitmap_flags_f(fp, ident, flags); +} + + +/* Function: al_load_bitmap_flags_f + */ +ALLEGRO_BITMAP *al_load_bitmap_flags_f(ALLEGRO_FILE *fp, + const char *ident, int flags) +{ + Handler *h; + if (ident) + h = find_handler(ident, false); + else + h = find_handler_for_file(fp); + if (h && h->fs_loader) + return h->fs_loader(fp, flags); + else + return NULL; +} + + +/* Function: al_save_bitmap_f + */ +bool al_save_bitmap_f(ALLEGRO_FILE *fp, const char *ident, + ALLEGRO_BITMAP *bitmap) +{ + Handler *h = find_handler(ident, false); + if (h && h->fs_saver) + return h->fs_saver(fp, bitmap); + else { + ALLEGRO_ERROR("No handler for image %s found\n", ident); + return false; + } +} + + +/* Function: al_identify_bitmap_f + */ +char const *al_identify_bitmap_f(ALLEGRO_FILE *fp) +{ + Handler *h = find_handler_for_file(fp); + if (!h) + return NULL; + return h->extension; +} + + +/* Function: al_identify_bitmap + */ +char const *al_identify_bitmap(char const *filename) +{ + char const *ext; + ALLEGRO_FILE *fp = al_fopen(filename, "rb"); + if (!fp) + return NULL; + ext = al_identify_bitmap_f(fp); + al_fclose(fp); + return ext; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/bitmap_lock.c b/allegro/src/bitmap_lock.c new file mode 100644 index 00000000..ba0d1492 --- /dev/null +++ b/allegro/src/bitmap_lock.c @@ -0,0 +1,250 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Bitmap locking routines. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_pixels.h" + + +/* Function: al_lock_bitmap_region + */ +ALLEGRO_LOCKED_REGION *al_lock_bitmap_region(ALLEGRO_BITMAP *bitmap, + int x, int y, int width, int height, int format, int flags) +{ + ALLEGRO_LOCKED_REGION *lr; + int bitmap_format = al_get_bitmap_format(bitmap); + int bitmap_flags = al_get_bitmap_flags(bitmap); + int block_width = al_get_pixel_block_width(bitmap_format); + int block_height = al_get_pixel_block_height(bitmap_format); + int xc, yc, wc, hc; + ASSERT(x >= 0); + ASSERT(y >= 0); + ASSERT(width >= 0); + ASSERT(height >= 0); + ASSERT(!_al_pixel_format_is_video_only(format)); + if (_al_pixel_format_is_real(format)) { + ASSERT(al_get_pixel_block_width(format) == 1); + ASSERT(al_get_pixel_block_height(format) == 1); + } + + /* For sub-bitmaps */ + if (bitmap->parent) { + x += bitmap->xofs; + y += bitmap->yofs; + bitmap = bitmap->parent; + } + + if (bitmap->locked) + return NULL; + + if (!(bitmap_flags & ALLEGRO_MEMORY_BITMAP) && + !(flags & ALLEGRO_LOCK_READONLY)) + bitmap->dirty = true; + + ASSERT(x+width <= bitmap->w); + ASSERT(y+height <= bitmap->h); + + xc = (x / block_width) * block_width; + yc = (y / block_height) * block_height; + wc = _al_get_least_multiple(x + width, block_width) - xc; + hc = _al_get_least_multiple(y + height, block_height) - yc; + + bitmap->lock_x = xc; + bitmap->lock_y = yc; + bitmap->lock_w = wc; + bitmap->lock_h = hc; + bitmap->lock_flags = flags; + + if (flags == ALLEGRO_LOCK_WRITEONLY && + (xc != x || yc != y || wc != width || hc != height)) { + /* Unaligned write-only access requires that we fill in the padding + * from the texture. + * XXX: In principle, this could be done more efficiently. */ + flags = ALLEGRO_LOCK_READWRITE; + } + + if (bitmap_flags & ALLEGRO_MEMORY_BITMAP) { + int f = _al_get_real_pixel_format(al_get_current_display(), format); + if (f < 0) { + return NULL; + } + ASSERT(bitmap->memory); + if (format == ALLEGRO_PIXEL_FORMAT_ANY || bitmap_format == format || bitmap_format == f) { + bitmap->locked_region.data = bitmap->memory + + bitmap->pitch * yc + xc * al_get_pixel_size(bitmap_format); + bitmap->locked_region.format = bitmap_format; + bitmap->locked_region.pitch = bitmap->pitch; + bitmap->locked_region.pixel_size = al_get_pixel_size(bitmap_format); + } + else { + bitmap->locked_region.pitch = al_get_pixel_size(f) * wc; + bitmap->locked_region.data = al_malloc(bitmap->locked_region.pitch*hc); + bitmap->locked_region.format = f; + bitmap->locked_region.pixel_size = al_get_pixel_size(f); + if (!(bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY)) { + _al_convert_bitmap_data( + bitmap->memory, bitmap_format, bitmap->pitch, + bitmap->locked_region.data, f, bitmap->locked_region.pitch, + xc, yc, 0, 0, wc, hc); + } + } + lr = &bitmap->locked_region; + } + else { + lr = bitmap->vt->lock_region(bitmap, xc, yc, wc, hc, format, flags); + if (!lr) { + return NULL; + } + } + + bitmap->lock_data = lr->data; + /* Fixup the data pointer for unaligned access */ + lr->data = (char*)lr->data + (x - xc) * lr->pixel_size + (y - yc) * lr->pitch; + + bitmap->locked = true; + + return lr; +} + + +/* Function: al_lock_bitmap + */ +ALLEGRO_LOCKED_REGION *al_lock_bitmap(ALLEGRO_BITMAP *bitmap, + int format, int flags) +{ + return al_lock_bitmap_region(bitmap, 0, 0, bitmap->w, bitmap->h, format, flags); +} + + +/* Function: al_unlock_bitmap + */ +void al_unlock_bitmap(ALLEGRO_BITMAP *bitmap) +{ + int bitmap_format = al_get_bitmap_format(bitmap); + /* For sub-bitmaps */ + if (bitmap->parent) { + bitmap = bitmap->parent; + } + + if (!(al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP)) { + if (_al_pixel_format_is_compressed(bitmap->locked_region.format)) + bitmap->vt->unlock_compressed_region(bitmap); + else + bitmap->vt->unlock_region(bitmap); + } + else { + if (bitmap->locked_region.format != 0 && bitmap->locked_region.format != bitmap_format) { + if (!(bitmap->lock_flags & ALLEGRO_LOCK_READONLY)) { + _al_convert_bitmap_data( + bitmap->locked_region.data, bitmap->locked_region.format, bitmap->locked_region.pitch, + bitmap->memory, bitmap_format, bitmap->pitch, + 0, 0, bitmap->lock_x, bitmap->lock_y, bitmap->lock_w, bitmap->lock_h); + } + al_free(bitmap->locked_region.data); + } + } + + bitmap->locked = false; +} + + +/* Function: al_is_bitmap_locked + */ +bool al_is_bitmap_locked(ALLEGRO_BITMAP *bitmap) +{ + return bitmap->locked; +} + +/* Function: al_lock_bitmap_blocked + */ +ALLEGRO_LOCKED_REGION *al_lock_bitmap_blocked(ALLEGRO_BITMAP *bitmap, + int flags) +{ + int bitmap_format = al_get_bitmap_format(bitmap); + int block_width = al_get_pixel_block_width(bitmap_format); + int block_height = al_get_pixel_block_height(bitmap_format); + + return al_lock_bitmap_region_blocked(bitmap, 0, 0, + _al_get_least_multiple(bitmap->w, block_width) / block_width, + _al_get_least_multiple(bitmap->h, block_height) / block_height, + flags); +} + +/* Function: al_lock_bitmap_region_blocked + */ +ALLEGRO_LOCKED_REGION *al_lock_bitmap_region_blocked(ALLEGRO_BITMAP *bitmap, + int x_block, int y_block, int width_block, int height_block, int flags) +{ + ALLEGRO_LOCKED_REGION *lr; + int bitmap_format = al_get_bitmap_format(bitmap); + int bitmap_flags = al_get_bitmap_flags(bitmap); + int block_width = al_get_pixel_block_width(bitmap_format); + int block_height = al_get_pixel_block_height(bitmap_format); + ASSERT(x_block >= 0); + ASSERT(y_block >= 0); + ASSERT(width_block >= 0); + ASSERT(height_block >= 0); + + if (block_width == 1 && block_height == 1 && !_al_pixel_format_is_video_only(bitmap_format)) { + return al_lock_bitmap_region(bitmap, x_block, y_block, width_block, + height_block, bitmap_format, flags); + } + + /* Currently, this is the only format that gets to this point */ + ASSERT(_al_pixel_format_is_compressed(bitmap_format)); + ASSERT(!(bitmap_flags & ALLEGRO_MEMORY_BITMAP)); + + /* For sub-bitmaps */ + if (bitmap->parent) { + if (bitmap->xofs % block_width != 0 || + bitmap->yofs % block_height != 0) { + return NULL; + } + x_block += bitmap->xofs / block_width; + y_block += bitmap->yofs / block_height; + bitmap = bitmap->parent; + } + + if (bitmap->locked) + return NULL; + + if (!(flags & ALLEGRO_LOCK_READONLY)) + bitmap->dirty = true; + + ASSERT(x_block + width_block + <= _al_get_least_multiple(bitmap->w, block_width) / block_width); + ASSERT(y_block + height_block + <= _al_get_least_multiple(bitmap->h, block_height) / block_height); + + bitmap->lock_x = x_block * block_width; + bitmap->lock_y = y_block * block_height; + bitmap->lock_w = width_block * block_width; + bitmap->lock_h = height_block * block_height; + bitmap->lock_flags = flags; + + lr = bitmap->vt->lock_compressed_region(bitmap, bitmap->lock_x, + bitmap->lock_y, bitmap->lock_w, bitmap->lock_h, flags); + if (!lr) { + return NULL; + } + + bitmap->locked = true; + + return lr; +} + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/src/bitmap_pixel.c b/allegro/src/bitmap_pixel.c new file mode 100644 index 00000000..3d1bd325 --- /dev/null +++ b/allegro/src/bitmap_pixel.c @@ -0,0 +1,148 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Bitmap pixel manipulation. + * + * See LICENSE.txt for copyright information. + */ + +#include /* for memset */ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_blend.h" +#include "allegro5/internal/aintern_pixels.h" + +ALLEGRO_DEBUG_CHANNEL("bitmap") + + +/* Function: al_get_pixel + */ +ALLEGRO_COLOR al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int y) +{ + ALLEGRO_LOCKED_REGION *lr; + char *data; + ALLEGRO_COLOR color = al_map_rgba_f(0, 0, 0, 0); + + if (bitmap->parent) { + x += bitmap->xofs; + y += bitmap->yofs; + bitmap = bitmap->parent; + } + + if (bitmap->locked) { + if (_al_pixel_format_is_video_only(bitmap->locked_region.format)) { + ALLEGRO_ERROR("Invalid lock format."); + return color; + } + x -= bitmap->lock_x; + y -= bitmap->lock_y; + if (x < 0 || y < 0 || x >= bitmap->lock_w || y >= bitmap->lock_h) { + ALLEGRO_ERROR("Out of bounds."); + return color; + } + + data = bitmap->locked_region.data; + data += y * bitmap->locked_region.pitch; + data += x * al_get_pixel_size(bitmap->locked_region.format); + + _AL_INLINE_GET_PIXEL(bitmap->locked_region.format, data, color, false); + } + else { + /* FIXME: must use clip not full bitmap */ + if (x < 0 || y < 0 || x >= bitmap->w || y >= bitmap->h) { + return color; + } + + if (!(lr = al_lock_bitmap_region(bitmap, x, y, 1, 1, + ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY))) { + return color; + } + + /* FIXME: check for valid pixel format */ + + data = bitmap->lock_data; + _AL_INLINE_GET_PIXEL(lr->format, data, color, false); + + al_unlock_bitmap(bitmap); + } + + return color; +} + + +void _al_put_pixel(ALLEGRO_BITMAP *bitmap, int x, int y, ALLEGRO_COLOR color) +{ + ALLEGRO_LOCKED_REGION *lr; + char *data; + + if (bitmap->parent) { + x += bitmap->xofs; + y += bitmap->yofs; + bitmap = bitmap->parent; + } + + if (x < bitmap->cl || y < bitmap->ct || + x >= bitmap->cr_excl || y >= bitmap->cb_excl) { + return; + } + + if (bitmap->locked) { + if (_al_pixel_format_is_video_only(bitmap->locked_region.format)) { + ALLEGRO_ERROR("Invalid lock format."); + return; + } + x -= bitmap->lock_x; + y -= bitmap->lock_y; + if (x < 0 || y < 0 || x >= bitmap->lock_w || y >= bitmap->lock_h) { + return; + } + + data = bitmap->locked_region.data; + data += y * bitmap->locked_region.pitch; + data += x * al_get_pixel_size(bitmap->locked_region.format); + + _AL_INLINE_PUT_PIXEL(bitmap->locked_region.format, data, color, false); + } + else { + lr = al_lock_bitmap_region(bitmap, x, y, 1, 1, + ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); + if (!lr) + return; + + /* FIXME: check for valid pixel format */ + + data = bitmap->lock_data; + _AL_INLINE_PUT_PIXEL(lr->format, data, color, false); + + al_unlock_bitmap(bitmap); + } +} + + +/* Function: al_put_pixel + */ +void al_put_pixel(int x, int y, ALLEGRO_COLOR color) +{ + _al_put_pixel(al_get_target_bitmap(), x, y, color); +} + + +/* Function: al_put_blended_pixel + */ +void al_put_blended_pixel(int x, int y, ALLEGRO_COLOR color) +{ + ALLEGRO_COLOR result; + ALLEGRO_BITMAP* bitmap = al_get_target_bitmap(); + _al_blend_memory(&color, bitmap, x, y, &result); + _al_put_pixel(bitmap, x, y, result); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/bitmap_type.c b/allegro/src/bitmap_type.c new file mode 100644 index 00000000..c23c984c --- /dev/null +++ b/allegro/src/bitmap_type.c @@ -0,0 +1,318 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Convert between memory and video bitmap types. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_shader.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_vector.h" + +ALLEGRO_DEBUG_CHANNEL("bitmap") + + +/* Global list of MEMORY bitmaps with ALLEGRO_CONVERT_BITMAP flag. */ +struct BITMAP_CONVERSION_LIST { + ALLEGRO_MUTEX *mutex; + _AL_VECTOR bitmaps; +}; + + +static struct BITMAP_CONVERSION_LIST convert_bitmap_list; + + +static void cleanup_convert_bitmap_list(void) +{ + _al_vector_free(&convert_bitmap_list.bitmaps); + al_destroy_mutex(convert_bitmap_list.mutex); +} + + +/* This is called in al_install_system. Exit functions are called in + * al_uninstall_system. + */ +void _al_init_convert_bitmap_list(void) +{ + convert_bitmap_list.mutex = al_create_mutex_recursive(); + _al_vector_init(&convert_bitmap_list.bitmaps, sizeof(ALLEGRO_BITMAP *)); + _al_add_exit_func(cleanup_convert_bitmap_list, + "cleanup_convert_bitmap_list"); +} + + +void _al_register_convert_bitmap(ALLEGRO_BITMAP *bitmap) +{ + int bitmap_flags = al_get_bitmap_flags(bitmap); + if (!(bitmap_flags & ALLEGRO_MEMORY_BITMAP)) + return; + if (bitmap_flags & ALLEGRO_CONVERT_BITMAP) { + ALLEGRO_BITMAP **back; + al_lock_mutex(convert_bitmap_list.mutex); + back = _al_vector_alloc_back(&convert_bitmap_list.bitmaps); + *back = bitmap; + al_unlock_mutex(convert_bitmap_list.mutex); + } +} + + +void _al_unregister_convert_bitmap(ALLEGRO_BITMAP *bitmap) +{ + int bitmap_flags = al_get_bitmap_flags(bitmap); + if (!(bitmap_flags & ALLEGRO_MEMORY_BITMAP)) + return; + if (bitmap_flags & ALLEGRO_CONVERT_BITMAP) { + al_lock_mutex(convert_bitmap_list.mutex); + _al_vector_find_and_delete(&convert_bitmap_list.bitmaps, &bitmap); + al_unlock_mutex(convert_bitmap_list.mutex); + } +} + + +static void swap_bitmaps(ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP *other) +{ + ALLEGRO_BITMAP temp; + _AL_LIST_ITEM *bitmap_dtor_item = bitmap->dtor_item; + _AL_LIST_ITEM *other_dtor_item = other->dtor_item; + ALLEGRO_DISPLAY *bitmap_display, *other_display; + + _al_unregister_convert_bitmap(bitmap); + _al_unregister_convert_bitmap(other); + + if (other->shader) + _al_unregister_shader_bitmap(other->shader, other); + if (bitmap->shader) + _al_unregister_shader_bitmap(bitmap->shader, bitmap); + + temp = *bitmap; + *bitmap = *other; + *other = temp; + + /* Re-associate the destructors back, as they are tied to the object + * pointers. + */ + bitmap->dtor_item = bitmap_dtor_item; + other->dtor_item = other_dtor_item; + + bitmap_display = _al_get_bitmap_display(bitmap); + other_display = _al_get_bitmap_display(other); + + /* We are basically done already. Except we now have to update everything + * possibly referencing any of the two bitmaps. + */ + + if (bitmap_display && !other_display) { + /* This means before the swap, other was the display bitmap, and we + * now should replace it with the swapped pointer. + */ + ALLEGRO_BITMAP **back; + int pos = _al_vector_find(&bitmap_display->bitmaps, &other); + ASSERT(pos >= 0); + back = _al_vector_ref(&bitmap_display->bitmaps, pos); + *back = bitmap; + } + + if (other_display && !bitmap_display) { + ALLEGRO_BITMAP **back; + int pos = _al_vector_find(&other_display->bitmaps, &bitmap); + ASSERT(pos >= 0); + back = _al_vector_ref(&other_display->bitmaps, pos); + *back = other; + } + + if (other->shader) + _al_register_shader_bitmap(other->shader, other); + if (bitmap->shader) + _al_register_shader_bitmap(bitmap->shader, bitmap); + + _al_register_convert_bitmap(bitmap); + _al_register_convert_bitmap(other); + + if (bitmap->vt && bitmap->vt->bitmap_pointer_changed) + bitmap->vt->bitmap_pointer_changed(bitmap, other); + + if (other->vt && other->vt->bitmap_pointer_changed) + other->vt->bitmap_pointer_changed(other, bitmap); +} + + +/* Function: al_convert_bitmap + */ +void al_convert_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP *clone; + int bitmap_flags = al_get_bitmap_flags(bitmap); + int new_bitmap_flags = al_get_new_bitmap_flags(); + bool want_memory = (new_bitmap_flags & ALLEGRO_MEMORY_BITMAP) != 0; + bool clone_memory; + ALLEGRO_BITMAP *target_bitmap; + + bitmap_flags &= ~_ALLEGRO_INTERNAL_OPENGL; + + /* If a cloned bitmap would be identical, we can just do nothing. */ + if (al_get_bitmap_format(bitmap) == al_get_new_bitmap_format() && + bitmap_flags == new_bitmap_flags && + _al_get_bitmap_display(bitmap) == al_get_current_display()) { + return; + } + + if (bitmap->parent) { + al_convert_bitmap(bitmap->parent); + return; + } + else { + clone = al_clone_bitmap(bitmap); + } + + if (!clone) { + return; + } + + clone_memory = (al_get_bitmap_flags(clone) & ALLEGRO_MEMORY_BITMAP) != 0; + + if (clone_memory != want_memory) { + /* We couldn't convert. */ + al_destroy_bitmap(clone); + return; + } + + swap_bitmaps(bitmap, clone); + + /* Preserve bitmap state. */ + bitmap->cl = clone->cl; + bitmap->ct = clone->ct; + bitmap->cr_excl = clone->cr_excl; + bitmap->cb_excl = clone->cb_excl; + bitmap->transform = clone->transform; + bitmap->inverse_transform = clone->inverse_transform; + bitmap->inverse_transform_dirty = clone->inverse_transform_dirty; + + /* Memory bitmaps do not support custom projection transforms, + * so reset it to the orthographic transform. */ + if (new_bitmap_flags & ALLEGRO_MEMORY_BITMAP) { + al_identity_transform(&bitmap->proj_transform); + al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, bitmap->w, bitmap->h, 1.0); + } else { + bitmap->proj_transform = clone->proj_transform; + } + + /* If we just converted this bitmap, and the backing bitmap is the same + * as the target's backing bitmap, then the viewports and transformations + * will be messed up. Detect this, and just re-call al_set_target_bitmap + * on the current target. */ + target_bitmap = al_get_target_bitmap(); + if (target_bitmap) { + ALLEGRO_BITMAP *target_parent = + target_bitmap->parent ? target_bitmap->parent : target_bitmap; + if (bitmap == target_parent || bitmap->parent == target_parent) { + al_set_target_bitmap(target_bitmap); + } + } + + al_destroy_bitmap(clone); +} + + +/* Function: al_convert_memory_bitmaps + */ +void al_convert_memory_bitmaps(void) +{ + ALLEGRO_STATE backup; + ALLEGRO_DISPLAY *display = al_get_current_display(); + _AL_VECTOR copy; + size_t i; + if (!display) return; + + al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); + + al_lock_mutex(convert_bitmap_list.mutex); + + _al_vector_init(©, sizeof(ALLEGRO_BITMAP *)); + for (i = 0; i < _al_vector_size(&convert_bitmap_list.bitmaps); i++) { + ALLEGRO_BITMAP **bptr, **bptr2; + bptr = _al_vector_ref(&convert_bitmap_list.bitmaps, i); + bptr2 = _al_vector_alloc_back(©); + *bptr2 = *bptr; + } + _al_vector_free(&convert_bitmap_list.bitmaps); + _al_vector_init(&convert_bitmap_list.bitmaps, sizeof(ALLEGRO_BITMAP *)); + for (i = 0; i < _al_vector_size(©); i++) { + ALLEGRO_BITMAP **bptr; + int flags; + bptr = _al_vector_ref(©, i); + flags = al_get_bitmap_flags(*bptr); + flags &= ~ALLEGRO_MEMORY_BITMAP; + al_set_new_bitmap_flags(flags); + al_set_new_bitmap_format(al_get_bitmap_format(*bptr)); + + ALLEGRO_DEBUG("converting memory bitmap %p to display bitmap\n", *bptr); + + al_convert_bitmap(*bptr); + } + + _al_vector_free(©); + + al_unlock_mutex(convert_bitmap_list.mutex); + + al_restore_state(&backup); +} + + +/* Converts a memory bitmap to a display bitmap preserving its contents. + * The created bitmap belongs to the current display. + * + * If this is called for a sub-bitmap, the parent also is converted. + */ +void _al_convert_to_display_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_STATE backup; + int bitmap_flags = al_get_bitmap_flags(bitmap); + /* Do nothing if it is a display bitmap already. */ + if (!(bitmap_flags & ALLEGRO_MEMORY_BITMAP)) + return; + + ALLEGRO_DEBUG("converting memory bitmap %p to display bitmap\n", bitmap); + + al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); + al_set_new_bitmap_flags(bitmap_flags & ~ALLEGRO_MEMORY_BITMAP); + al_set_new_bitmap_format(al_get_bitmap_format(bitmap)); + al_convert_bitmap(bitmap); + al_restore_state(&backup); +} + + +/* Converts a display bitmap to a memory bitmap preserving its contents. + * If this is called for a sub-bitmap, the parent also is converted. + */ +void _al_convert_to_memory_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_STATE backup; + int bitmap_flags = al_get_bitmap_flags(bitmap); + /* Do nothing if it is a memory bitmap already. */ + if (bitmap_flags & ALLEGRO_MEMORY_BITMAP) + return; + + ALLEGRO_DEBUG("converting display bitmap %p to memory bitmap\n", bitmap); + + al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); + al_set_new_bitmap_flags((bitmap_flags & ~ALLEGRO_VIDEO_BITMAP) | ALLEGRO_MEMORY_BITMAP); + al_set_new_bitmap_format(al_get_bitmap_format(bitmap)); + al_convert_bitmap(bitmap); + al_restore_state(&backup); +} + + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/src/blenders.c b/allegro/src/blenders.c new file mode 100644 index 00000000..bd6a2418 --- /dev/null +++ b/allegro/src/blenders.c @@ -0,0 +1,42 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Memory bitmap blending routines + * + * by Trent Gamblin. + * + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_blend.h" +#include "allegro5/internal/aintern_display.h" +#include + +void _al_blend_memory(ALLEGRO_COLOR *scol, + ALLEGRO_BITMAP *dest, + int dx, int dy, ALLEGRO_COLOR *result) +{ + ALLEGRO_COLOR dcol; + ALLEGRO_COLOR constcol; + int op, src_blend, dest_blend, alpha_op, alpha_src_blend, alpha_dest_blend; + dcol = al_get_pixel(dest, dx, dy); + al_get_separate_bitmap_blender(&op, &src_blend, &dest_blend, + &alpha_op, &alpha_src_blend, + &alpha_dest_blend); + constcol = al_get_blend_color(); + _al_blend_inline(scol, &dcol, + op, src_blend, dest_blend, + alpha_op, alpha_src_blend, alpha_dest_blend, + &constcol, result); + (void) _al_blend_alpha_inline; // silence compiler +} diff --git a/allegro/src/clipboard.c b/allegro/src/clipboard.c new file mode 100644 index 00000000..7425a4e3 --- /dev/null +++ b/allegro/src/clipboard.c @@ -0,0 +1,79 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Clipboard handling. + * + * By Beoran. + * + * See readme.txt for copyright information. + */ + +/* Title: Event sources + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_display.h" + + +/* Function: al_get_clipboard_text + */ +char *al_get_clipboard_text(ALLEGRO_DISPLAY *display) +{ + if (!display) + display = al_get_current_display(); + + if (!display) + return NULL; + + if (!display->vt->get_clipboard_text) + return NULL; + + return display->vt->get_clipboard_text(display); +} + + +/* Function: al_set_clipboard_text + */ +bool al_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text) +{ + if (!display) + display = al_get_current_display(); + + if (!display) + return false; + + if (!display->vt->set_clipboard_text) + return false; + + return display->vt->set_clipboard_text(display, text); + +} + + +/* Function: al_clipboard_has_text + */ +bool al_clipboard_has_text(ALLEGRO_DISPLAY *display) +{ + if (!display) + display = al_get_current_display(); + + if (!display) + return false; + + if (!display->vt->has_clipboard_text) + return false; + + return display->vt->has_clipboard_text(display); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/config.c b/allegro/src/config.c new file mode 100644 index 00000000..1848d5e7 --- /dev/null +++ b/allegro/src/config.c @@ -0,0 +1,747 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Configuration routines. + * + * By Trent Gamblin. + */ + +/* Title: Configuration routines + */ + + +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_aatree.h" +#include "allegro5/internal/aintern_config.h" + + + +static int cmp_ustr(void const *a, void const *b) +{ + return al_ustr_compare(a, b); +} + + +/* Function: al_create_config + */ +ALLEGRO_CONFIG *al_create_config(void) +{ + ALLEGRO_CONFIG *config = al_calloc(1, sizeof(ALLEGRO_CONFIG)); + ASSERT(config); + + return config; +} + + +static ALLEGRO_CONFIG_SECTION *find_section(const ALLEGRO_CONFIG *config, + const ALLEGRO_USTR *section) +{ + return _al_aa_search(config->tree, section, cmp_ustr); +} + + +static ALLEGRO_CONFIG_ENTRY *find_entry(const ALLEGRO_CONFIG_SECTION *section, + const ALLEGRO_USTR *key) +{ + return _al_aa_search(section->tree, key, cmp_ustr); +} + + +static void get_key_and_value(const ALLEGRO_USTR *buf, + ALLEGRO_USTR *key, ALLEGRO_USTR *value) +{ + int eq = al_ustr_find_chr(buf, 0, '='); + + if (eq == -1) { + al_ustr_assign(key, buf); + al_ustr_assign_cstr(value, ""); + } + else { + al_ustr_assign_substr(key, buf, 0, eq); + al_ustr_assign_substr(value, buf, eq + 1, al_ustr_size(buf)); + } + + al_ustr_trim_ws(key); + al_ustr_trim_ws(value); +} + + +static ALLEGRO_CONFIG_SECTION *config_add_section(ALLEGRO_CONFIG *config, + const ALLEGRO_USTR *name) +{ + ALLEGRO_CONFIG_SECTION *sec = config->head; + ALLEGRO_CONFIG_SECTION *section; + + if ((section = find_section(config, name))) + return section; + + section = al_calloc(1, sizeof(ALLEGRO_CONFIG_SECTION)); + section->name = al_ustr_dup(name); + + if (sec == NULL) { + config->head = section; + config->last = section; + } + else { + ASSERT(config->last->next == NULL); + config->last->next = section; + section->prev = config->last; + config->last = section; + } + + config->tree = _al_aa_insert(config->tree, section->name, section, cmp_ustr); + + return section; +} + + +/* Function: al_add_config_section + */ +void al_add_config_section(ALLEGRO_CONFIG *config, const char *name) +{ + ALLEGRO_USTR_INFO name_info; + const ALLEGRO_USTR *uname; + + uname = al_ref_cstr(&name_info, name); + config_add_section(config, uname); +} + + +static void config_set_value(ALLEGRO_CONFIG *config, + const ALLEGRO_USTR *section, const ALLEGRO_USTR *key, + const ALLEGRO_USTR *value) +{ + ALLEGRO_CONFIG_SECTION *s; + ALLEGRO_CONFIG_ENTRY *entry; + + s = find_section(config, section); + if (s) { + entry = find_entry(s, key); + if (entry) { + al_ustr_assign(entry->value, value); + al_ustr_trim_ws(entry->value); + return; + } + } + + entry = al_calloc(1, sizeof(ALLEGRO_CONFIG_ENTRY)); + entry->is_comment = false; + entry->key = al_ustr_dup(key); + entry->value = al_ustr_dup(value); + al_ustr_trim_ws(entry->value); + + if (!s) { + s = config_add_section(config, section); + } + + if (s->head == NULL) { + s->head = entry; + s->last = entry; + } + else { + ASSERT(s->last->next == NULL); + s->last->next = entry; + entry->prev = s->last; + s->last = entry; + } + + s->tree = _al_aa_insert(s->tree, entry->key, entry, cmp_ustr); +} + + +/* Function: al_set_config_value + */ +void al_set_config_value(ALLEGRO_CONFIG *config, + const char *section, const char *key, const char *value) +{ + ALLEGRO_USTR_INFO section_info; + ALLEGRO_USTR_INFO key_info; + ALLEGRO_USTR_INFO value_info; + const ALLEGRO_USTR *usection; + const ALLEGRO_USTR *ukey; + const ALLEGRO_USTR *uvalue; + + if (section == NULL) { + section = ""; + } + + ASSERT(key); + ASSERT(value); + + usection = al_ref_cstr(§ion_info, section); + ukey = al_ref_cstr(&key_info, key); + uvalue = al_ref_cstr(&value_info, value); + + config_set_value(config, usection, ukey, uvalue); +} + + +static void config_add_comment(ALLEGRO_CONFIG *config, + const ALLEGRO_USTR *section, const ALLEGRO_USTR *comment) +{ + ALLEGRO_CONFIG_SECTION *s; + ALLEGRO_CONFIG_ENTRY *entry; + + s = find_section(config, section); + + entry = al_calloc(1, sizeof(ALLEGRO_CONFIG_ENTRY)); + entry->is_comment = true; + entry->key = al_ustr_dup(comment); + + /* Replace all newline characters by spaces, otherwise the written comment + * file will be corrupted. + */ + al_ustr_find_replace_cstr(entry->key, 0, "\n", " "); + + if (!s) { + s = config_add_section(config, section); + } + + if (s->head == NULL) { + s->head = entry; + s->last = entry; + } + else { + ASSERT(s->last->next == NULL); + s->last->next = entry; + entry->prev = s->last; + s->last = entry; + } +} + + +/* Function: al_add_config_comment + */ +void al_add_config_comment(ALLEGRO_CONFIG *config, + const char *section, const char *comment) +{ + ALLEGRO_USTR_INFO section_info; + ALLEGRO_USTR_INFO comment_info; + const ALLEGRO_USTR *usection; + const ALLEGRO_USTR *ucomment; + + if (section == NULL) { + section = ""; + } + + ASSERT(comment); + + usection = al_ref_cstr(§ion_info, section); + ucomment = al_ref_cstr(&comment_info, comment); + + config_add_comment(config, usection, ucomment); +} + + +static bool config_get_value(const ALLEGRO_CONFIG *config, + const ALLEGRO_USTR *section, const ALLEGRO_USTR *key, + const ALLEGRO_USTR **ret_value) +{ + ALLEGRO_CONFIG_SECTION *s; + ALLEGRO_CONFIG_ENTRY *e; + + s = find_section(config, section); + if (!s) + return false; + + e = find_entry(s, key); + if (!e) + return false; + + *ret_value = e->value; + return true; +} + + +/* Function: al_get_config_value + */ +const char *al_get_config_value(const ALLEGRO_CONFIG *config, + const char *section, const char *key) +{ + ALLEGRO_USTR_INFO section_info; + ALLEGRO_USTR_INFO key_info; + const ALLEGRO_USTR *usection; + const ALLEGRO_USTR *ukey; + const ALLEGRO_USTR *value; + + if (section == NULL) { + section = ""; + } + + usection = al_ref_cstr(§ion_info, section); + ukey = al_ref_cstr(&key_info, key); + + if (config_get_value(config, usection, ukey, &value)) + return al_cstr(value); + else + return NULL; +} + + +static bool readline(ALLEGRO_FILE *file, ALLEGRO_USTR *line) +{ + char buf[128]; + + if (!al_fgets(file, buf, sizeof(buf))) { + return false; + } + + do { + al_ustr_append_cstr(line, buf); + if (al_ustr_has_suffix_cstr(line, "\n")) + break; + } while (al_fgets(file, buf, sizeof(buf))); + + return true; +} + + +/* Function: al_load_config_file + */ +ALLEGRO_CONFIG *al_load_config_file(const char *filename) +{ + ALLEGRO_FILE *file; + ALLEGRO_CONFIG *cfg = NULL; + + file = al_fopen(filename, "r"); + if (file) { + cfg = al_load_config_file_f(file); + al_fclose(file); + } + + return cfg; +} + + +/* Function: al_load_config_file_f + */ +ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file) +{ + ALLEGRO_CONFIG *config; + ALLEGRO_CONFIG_SECTION *current_section = NULL; + ALLEGRO_USTR *line; + ALLEGRO_USTR *section; + ALLEGRO_USTR *key; + ALLEGRO_USTR *value; + ASSERT(file); + + config = al_create_config(); + if (!config) { + return NULL; + } + + line = al_ustr_new(""); + section = al_ustr_new(""); + key = al_ustr_new(""); + value = al_ustr_new(""); + + while (1) { + al_ustr_assign_cstr(line, ""); + if (!readline(file, line)) + break; + al_ustr_trim_ws(line); + + if (al_ustr_has_prefix_cstr(line, "#") || al_ustr_size(line) == 0) { + /* Preserve comments and blank lines */ + const ALLEGRO_USTR *name; + if (current_section) + name = current_section->name; + else + name = al_ustr_empty_string(); + config_add_comment(config, name, line); + } + else if (al_ustr_has_prefix_cstr(line, "[")) { + int rbracket = al_ustr_rfind_chr(line, al_ustr_size(line), ']'); + if (rbracket == -1) + rbracket = al_ustr_size(line); + al_ustr_assign_substr(section, line, 1, rbracket); + current_section = config_add_section(config, section); + } + else { + get_key_and_value(line, key, value); + if (current_section == NULL) + config_set_value(config, al_ustr_empty_string(), key, value); + else + config_set_value(config, current_section->name, key, value); + } + } + + al_ustr_free(line); + al_ustr_free(section); + al_ustr_free(key); + al_ustr_free(value); + + return config; +} + + +static bool config_write_section(ALLEGRO_FILE *file, + const ALLEGRO_CONFIG_SECTION *s) +{ + ALLEGRO_CONFIG_ENTRY *e; + + if (al_ustr_size(s->name) > 0) { + al_fputc(file, '['); + al_fputs(file, al_cstr(s->name)); + al_fputs(file, "]\n"); + if (al_ferror(file)) { + return false; + } + } + + e = s->head; + while (e != NULL) { + if (e->is_comment) { + if (al_ustr_size(e->key) > 0) { + if (!al_ustr_has_prefix_cstr(e->key, "#")) { + al_fputs(file, "# "); + } + al_fputs(file, al_cstr(e->key)); + } + al_fputc(file, '\n'); + } + else { + al_fputs(file, al_cstr(e->key)); + al_fputc(file, '='); + al_fputs(file, al_cstr(e->value)); + al_fputc(file, '\n'); + } + if (al_ferror(file)) { + return false; + } + + e = e->next; + } + + return !al_feof(file); +} + + +/* Function: al_save_config_file + */ +bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config) +{ + ALLEGRO_FILE *file; + + file = al_fopen(filename, "w"); + if (file) { + bool retsave = al_save_config_file_f(file, config); + bool retclose = al_fclose(file); + return retsave && retclose; + } + + return false; +} + + +/* Function: al_save_config_file_f + */ +bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config) +{ + ALLEGRO_CONFIG_SECTION *s; + + /* Save global section */ + s = config->head; + while (s != NULL) { + if (al_ustr_size(s->name) == 0) { + if (!config_write_section(file, s)) { + return false; + } + break; + } + s = s->next; + } + + /* Save other sections */ + s = config->head; + while (s != NULL) { + if (al_ustr_size(s->name) > 0) { + if (!config_write_section(file, s)) { + return false; + } + } + s = s->next; + } + + return !al_feof(file); +} + + +/* do_config_merge_into: + * Helper function for merging. + */ +static void do_config_merge_into(ALLEGRO_CONFIG *master, + const ALLEGRO_CONFIG *add, bool merge_comments) +{ + ALLEGRO_CONFIG_SECTION *s; + ALLEGRO_CONFIG_ENTRY *e; + ASSERT(master); + + if (!add) { + return; + } + + /* Save each section */ + s = add->head; + while (s != NULL) { + config_add_section(master, s->name); + e = s->head; + while (e != NULL) { + if (!e->is_comment) { + config_set_value(master, s->name, e->key, e->value); + } + else if (merge_comments) { + config_add_comment(master, s->name, e->key); + } + e = e->next; + } + s = s->next; + } +} + + +/* Function: al_merge_config_into + */ +void al_merge_config_into(ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add) +{ + do_config_merge_into(master, add, false); +} + + +/* Function: al_merge_config + */ +ALLEGRO_CONFIG *al_merge_config(const ALLEGRO_CONFIG *cfg1, + const ALLEGRO_CONFIG *cfg2) +{ + ALLEGRO_CONFIG *config = al_create_config(); + + do_config_merge_into(config, cfg1, true); + do_config_merge_into(config, cfg2, false); + + return config; +} + + +static void destroy_entry(ALLEGRO_CONFIG_ENTRY *e) +{ + al_ustr_free(e->key); + al_ustr_free(e->value); + al_free(e); +} + + +static void destroy_section(ALLEGRO_CONFIG_SECTION *s) +{ + ALLEGRO_CONFIG_ENTRY *e = s->head; + while (e) { + ALLEGRO_CONFIG_ENTRY *tmp = e->next; + destroy_entry(e); + e = tmp; + } + al_ustr_free(s->name); + _al_aa_free(s->tree); + al_free(s); +} + + +/* Function: al_destroy_config + */ +void al_destroy_config(ALLEGRO_CONFIG *config) +{ + ALLEGRO_CONFIG_SECTION *s; + + if (!config) { + return; + } + + s = config->head; + while (s) { + ALLEGRO_CONFIG_SECTION *tmp = s->next; + destroy_section(s); + s = tmp; + } + + _al_aa_free(config->tree); + al_free(config); +} + + +/* Function: al_get_first_config_section + */ +char const *al_get_first_config_section(ALLEGRO_CONFIG const *config, + ALLEGRO_CONFIG_SECTION **iterator) +{ + ALLEGRO_CONFIG_SECTION *s; + + if (!config) + return NULL; + s = config->head; + if (iterator) *iterator = s; + return s ? al_cstr(s->name) : NULL; +} + + +/* Function: al_get_next_config_section + */ +char const *al_get_next_config_section(ALLEGRO_CONFIG_SECTION **iterator) +{ + ALLEGRO_CONFIG_SECTION *s; + + if (!iterator) + return NULL; + s = *iterator; + if (s) + s = s->next; + *iterator = s; + return s ? al_cstr(s->name) : NULL; +} + + +/* Function: al_get_first_config_entry + */ +char const *al_get_first_config_entry(ALLEGRO_CONFIG const *config, + char const *section, ALLEGRO_CONFIG_ENTRY **iterator) +{ + ALLEGRO_USTR_INFO section_info; + const ALLEGRO_USTR *usection; + ALLEGRO_CONFIG_SECTION *s; + ALLEGRO_CONFIG_ENTRY *e; + + if (!config) + return NULL; + + if (section == NULL) + section = ""; + + usection = al_ref_cstr(§ion_info, section); + s = find_section(config, usection); + if (!s) + return NULL; + e = s->head; + while (e && e->is_comment) + e = e->next; + if (iterator) *iterator = e; + return e ? al_cstr(e->key) : NULL; +} + + +/* Function: al_get_next_config_entry + */ +char const *al_get_next_config_entry(ALLEGRO_CONFIG_ENTRY **iterator) +{ + ALLEGRO_CONFIG_ENTRY *e; + + if (!iterator) + return NULL; + e = *iterator; + if (e) + e = e->next; + while (e && e->is_comment) + e = e->next; + *iterator = e; + return e ? al_cstr(e->key) : NULL; +} + + +/* Function: al_remove_config_section + */ +bool al_remove_config_section(ALLEGRO_CONFIG *config, char const *section) +{ + ALLEGRO_USTR_INFO section_info; + ALLEGRO_USTR const *usection; + void *value; + ALLEGRO_CONFIG_SECTION *s; + + if (section == NULL) + section = ""; + + usection = al_ref_cstr(§ion_info, section); + + value = NULL; + config->tree = _al_aa_delete(config->tree, usection, cmp_ustr, &value); + if (!value) + return false; + + s = value; + + if (s->prev) { + s->prev->next = s->next; + } + else { + ASSERT(config->head == s); + config->head = s->next; + } + + if (s->next) { + s->next->prev = s->prev; + } + else { + ASSERT(config->last == s); + config->last = s->prev; + } + + destroy_section(s); + return true; +} + + +/* Function: al_remove_config_key + */ +bool al_remove_config_key(ALLEGRO_CONFIG *config, char const *section, + char const *key) +{ + ALLEGRO_USTR_INFO section_info; + ALLEGRO_USTR_INFO key_info; + ALLEGRO_USTR const *usection; + ALLEGRO_USTR const *ukey = al_ref_cstr(&key_info, key); + void *value; + ALLEGRO_CONFIG_ENTRY * e; + + if (section == NULL) + section = ""; + + usection = al_ref_cstr(§ion_info, section); + + ALLEGRO_CONFIG_SECTION *s = find_section(config, usection); + if (!s) + return false; + + value = NULL; + s->tree = _al_aa_delete(s->tree, ukey, cmp_ustr, &value); + if (!value) + return false; + + e = value; + + if (e->prev) { + e->prev->next = e->next; + } + else { + ASSERT(s->head == e); + s->head = e->next; + } + + if (e->next) { + e->next->prev = e->prev; + } + else { + ASSERT(s->last == e); + s->last = e->prev; + } + + destroy_entry(e); + + return true; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/convert.c b/allegro/src/convert.c new file mode 100644 index 00000000..73eda47a --- /dev/null +++ b/allegro/src/convert.c @@ -0,0 +1,8485 @@ +// Warning: This file was created by make_converters.py - do not edit. +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_convert.h" +static void argb_8888_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ARGB_8888_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ARGB_8888_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_8888_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_8888_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGBA_8888_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGBA_8888_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_8888_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_8888_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ARGB_4444_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ARGB_4444_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_4444_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_4444_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ARGB_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGBA_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ARGB_4444(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGB_565(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGB_555(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGBA_5551(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ARGB_1555(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_XBGR_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx * 3; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + int dst_pixel = ALLEGRO_CONVERT_RGB_888_TO_BGR_888(src_pixel); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1 * 3; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_BGR_565(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_BGR_555(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGBX_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_XRGB_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ABGR_F32(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_ABGR_8888_LE(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_RGBA_4444(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_888_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_RGB_888_TO_SINGLE_CHANNEL_8(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGB_565_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGB_565_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_565_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_565_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGB_555_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGB_555_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgb_555_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGB_555_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGBA_5551_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGBA_5551_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_5551_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_5551_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ARGB_1555_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ARGB_1555_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void argb_1555_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ARGB_1555_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ABGR_8888_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ABGR_8888_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_XBGR_8888_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_XBGR_8888_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xbgr_8888_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XBGR_8888_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ARGB_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGBA_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ARGB_4444(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx * 3; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + int dst_pixel = ALLEGRO_CONVERT_BGR_888_TO_RGB_888(src_pixel); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1 * 3; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGB_565(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGB_555(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGBA_5551(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ARGB_1555(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_XBGR_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_BGR_565(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_BGR_555(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGBX_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_XRGB_8888(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ABGR_F32(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_ABGR_8888_LE(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_RGBA_4444(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_888_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width * 3; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx * 3; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + #ifdef ALLEGRO_BIG_ENDIAN + int src_pixel = src_ptr[2] | (src_ptr[1] << 8) | (src_ptr[0] << 16); + #else + int src_pixel = src_ptr[0] | (src_ptr[1] << 8) | (src_ptr[2] << 16); + #endif + *dst_ptr = ALLEGRO_CONVERT_BGR_888_TO_SINGLE_CHANNEL_8(src_pixel); + src_ptr += 1 * 3; + dst_ptr += 1; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_BGR_565_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_BGR_565_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_565_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_565_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_BGR_555_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_BGR_555_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void bgr_555_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_BGR_555_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGBX_8888_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGBX_8888_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgbx_8888_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBX_8888_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_XRGB_8888_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_XRGB_8888_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void xrgb_8888_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_XRGB_8888_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ABGR_F32_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ABGR_F32_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_f32_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const ALLEGRO_COLOR *src_ptr = (const ALLEGRO_COLOR *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 16 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_F32_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void abgr_8888_le_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint32_t *src_ptr = (const uint32_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 4 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_ABGR_8888_LE_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGBA_4444_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_RGBA_4444_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void rgba_4444_to_single_channel_8(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint16_t *src_ptr = (const uint16_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 2 - width; + int dst_gap = dst_pitch / 1 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_RGBA_4444_TO_SINGLE_CHANNEL_8(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_argb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ARGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_rgba_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGBA_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_argb_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ARGB_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_rgb_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGB_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_rgb_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGB_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_rgb_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGB_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_rgba_5551(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGBA_5551(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_argb_1555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ARGB_1555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_abgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ABGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_xbgr_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_XBGR_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_bgr_888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint8_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 1 - width * 3; + src_ptr += sx; + dst_ptr += dx * 3; + for (y = 0; y < height; y++) { + uint8_t *dst_end = dst_ptr + width * 3; + while (dst_ptr < dst_end) { + int dst_pixel = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_BGR_888(*src_ptr); + #ifdef ALLEGRO_BIG_ENDIAN + dst_ptr[0] = dst_pixel >> 16; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel; + #else + dst_ptr[0] = dst_pixel; + dst_ptr[1] = dst_pixel >> 8; + dst_ptr[2] = dst_pixel >> 16; + #endif + src_ptr += 1; + dst_ptr += 1 * 3; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_bgr_565(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_BGR_565(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_bgr_555(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_BGR_555(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_rgbx_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGBX_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_xrgb_8888(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_XRGB_8888(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_abgr_f32(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + ALLEGRO_COLOR *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 16 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + ALLEGRO_COLOR *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ABGR_F32(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_abgr_8888_le(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint32_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 4 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint32_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_ABGR_8888_LE(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +static void single_channel_8_to_rgba_4444(const void *src, int src_pitch, + void *dst, int dst_pitch, + int sx, int sy, int dx, int dy, int width, int height) +{ + int y; + const uint8_t *src_ptr = (const uint8_t *)((const char *)src + sy * src_pitch); + uint16_t *dst_ptr = (void *)((char *)dst + dy * dst_pitch); + int src_gap = src_pitch / 1 - width; + int dst_gap = dst_pitch / 2 - width; + src_ptr += sx; + dst_ptr += dx; + for (y = 0; y < height; y++) { + uint16_t *dst_end = dst_ptr + width; + while (dst_ptr < dst_end) { + *dst_ptr = ALLEGRO_CONVERT_SINGLE_CHANNEL_8_TO_RGBA_4444(*src_ptr); + dst_ptr++; + src_ptr++; + } + src_ptr += src_gap; + dst_ptr += dst_gap; + } +} +void (*_al_convert_funcs[ALLEGRO_NUM_PIXEL_FORMATS] + [ALLEGRO_NUM_PIXEL_FORMATS])(const void *, int, void *, int, + int, int, int, int, int, int) = { + {NULL}, + {NULL}, + {NULL}, + {NULL}, + {NULL}, + {NULL}, + {NULL}, + {NULL}, + {NULL}, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + argb_8888_to_rgba_8888, + argb_8888_to_argb_4444, + argb_8888_to_rgb_888, + argb_8888_to_rgb_565, + argb_8888_to_rgb_555, + argb_8888_to_rgba_5551, + argb_8888_to_argb_1555, + argb_8888_to_abgr_8888, + argb_8888_to_xbgr_8888, + argb_8888_to_bgr_888, + argb_8888_to_bgr_565, + argb_8888_to_bgr_555, + argb_8888_to_rgbx_8888, + argb_8888_to_xrgb_8888, + argb_8888_to_abgr_f32, + argb_8888_to_abgr_8888_le, + argb_8888_to_rgba_4444, + argb_8888_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rgba_8888_to_argb_8888, + NULL, + rgba_8888_to_argb_4444, + rgba_8888_to_rgb_888, + rgba_8888_to_rgb_565, + rgba_8888_to_rgb_555, + rgba_8888_to_rgba_5551, + rgba_8888_to_argb_1555, + rgba_8888_to_abgr_8888, + rgba_8888_to_xbgr_8888, + rgba_8888_to_bgr_888, + rgba_8888_to_bgr_565, + rgba_8888_to_bgr_555, + rgba_8888_to_rgbx_8888, + rgba_8888_to_xrgb_8888, + rgba_8888_to_abgr_f32, + rgba_8888_to_abgr_8888_le, + rgba_8888_to_rgba_4444, + rgba_8888_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + argb_4444_to_argb_8888, + argb_4444_to_rgba_8888, + NULL, + argb_4444_to_rgb_888, + argb_4444_to_rgb_565, + argb_4444_to_rgb_555, + argb_4444_to_rgba_5551, + argb_4444_to_argb_1555, + argb_4444_to_abgr_8888, + argb_4444_to_xbgr_8888, + argb_4444_to_bgr_888, + argb_4444_to_bgr_565, + argb_4444_to_bgr_555, + argb_4444_to_rgbx_8888, + argb_4444_to_xrgb_8888, + argb_4444_to_abgr_f32, + argb_4444_to_abgr_8888_le, + argb_4444_to_rgba_4444, + argb_4444_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rgb_888_to_argb_8888, + rgb_888_to_rgba_8888, + rgb_888_to_argb_4444, + NULL, + rgb_888_to_rgb_565, + rgb_888_to_rgb_555, + rgb_888_to_rgba_5551, + rgb_888_to_argb_1555, + rgb_888_to_abgr_8888, + rgb_888_to_xbgr_8888, + rgb_888_to_bgr_888, + rgb_888_to_bgr_565, + rgb_888_to_bgr_555, + rgb_888_to_rgbx_8888, + rgb_888_to_xrgb_8888, + rgb_888_to_abgr_f32, + rgb_888_to_abgr_8888_le, + rgb_888_to_rgba_4444, + rgb_888_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rgb_565_to_argb_8888, + rgb_565_to_rgba_8888, + rgb_565_to_argb_4444, + rgb_565_to_rgb_888, + NULL, + rgb_565_to_rgb_555, + rgb_565_to_rgba_5551, + rgb_565_to_argb_1555, + rgb_565_to_abgr_8888, + rgb_565_to_xbgr_8888, + rgb_565_to_bgr_888, + rgb_565_to_bgr_565, + rgb_565_to_bgr_555, + rgb_565_to_rgbx_8888, + rgb_565_to_xrgb_8888, + rgb_565_to_abgr_f32, + rgb_565_to_abgr_8888_le, + rgb_565_to_rgba_4444, + rgb_565_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rgb_555_to_argb_8888, + rgb_555_to_rgba_8888, + rgb_555_to_argb_4444, + rgb_555_to_rgb_888, + rgb_555_to_rgb_565, + NULL, + rgb_555_to_rgba_5551, + rgb_555_to_argb_1555, + rgb_555_to_abgr_8888, + rgb_555_to_xbgr_8888, + rgb_555_to_bgr_888, + rgb_555_to_bgr_565, + rgb_555_to_bgr_555, + rgb_555_to_rgbx_8888, + rgb_555_to_xrgb_8888, + rgb_555_to_abgr_f32, + rgb_555_to_abgr_8888_le, + rgb_555_to_rgba_4444, + rgb_555_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rgba_5551_to_argb_8888, + rgba_5551_to_rgba_8888, + rgba_5551_to_argb_4444, + rgba_5551_to_rgb_888, + rgba_5551_to_rgb_565, + rgba_5551_to_rgb_555, + NULL, + rgba_5551_to_argb_1555, + rgba_5551_to_abgr_8888, + rgba_5551_to_xbgr_8888, + rgba_5551_to_bgr_888, + rgba_5551_to_bgr_565, + rgba_5551_to_bgr_555, + rgba_5551_to_rgbx_8888, + rgba_5551_to_xrgb_8888, + rgba_5551_to_abgr_f32, + rgba_5551_to_abgr_8888_le, + rgba_5551_to_rgba_4444, + rgba_5551_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + argb_1555_to_argb_8888, + argb_1555_to_rgba_8888, + argb_1555_to_argb_4444, + argb_1555_to_rgb_888, + argb_1555_to_rgb_565, + argb_1555_to_rgb_555, + argb_1555_to_rgba_5551, + NULL, + argb_1555_to_abgr_8888, + argb_1555_to_xbgr_8888, + argb_1555_to_bgr_888, + argb_1555_to_bgr_565, + argb_1555_to_bgr_555, + argb_1555_to_rgbx_8888, + argb_1555_to_xrgb_8888, + argb_1555_to_abgr_f32, + argb_1555_to_abgr_8888_le, + argb_1555_to_rgba_4444, + argb_1555_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + abgr_8888_to_argb_8888, + abgr_8888_to_rgba_8888, + abgr_8888_to_argb_4444, + abgr_8888_to_rgb_888, + abgr_8888_to_rgb_565, + abgr_8888_to_rgb_555, + abgr_8888_to_rgba_5551, + abgr_8888_to_argb_1555, + NULL, + abgr_8888_to_xbgr_8888, + abgr_8888_to_bgr_888, + abgr_8888_to_bgr_565, + abgr_8888_to_bgr_555, + abgr_8888_to_rgbx_8888, + abgr_8888_to_xrgb_8888, + abgr_8888_to_abgr_f32, + abgr_8888_to_abgr_8888_le, + abgr_8888_to_rgba_4444, + abgr_8888_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + xbgr_8888_to_argb_8888, + xbgr_8888_to_rgba_8888, + xbgr_8888_to_argb_4444, + xbgr_8888_to_rgb_888, + xbgr_8888_to_rgb_565, + xbgr_8888_to_rgb_555, + xbgr_8888_to_rgba_5551, + xbgr_8888_to_argb_1555, + xbgr_8888_to_abgr_8888, + NULL, + xbgr_8888_to_bgr_888, + xbgr_8888_to_bgr_565, + xbgr_8888_to_bgr_555, + xbgr_8888_to_rgbx_8888, + xbgr_8888_to_xrgb_8888, + xbgr_8888_to_abgr_f32, + xbgr_8888_to_abgr_8888_le, + xbgr_8888_to_rgba_4444, + xbgr_8888_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + bgr_888_to_argb_8888, + bgr_888_to_rgba_8888, + bgr_888_to_argb_4444, + bgr_888_to_rgb_888, + bgr_888_to_rgb_565, + bgr_888_to_rgb_555, + bgr_888_to_rgba_5551, + bgr_888_to_argb_1555, + bgr_888_to_abgr_8888, + bgr_888_to_xbgr_8888, + NULL, + bgr_888_to_bgr_565, + bgr_888_to_bgr_555, + bgr_888_to_rgbx_8888, + bgr_888_to_xrgb_8888, + bgr_888_to_abgr_f32, + bgr_888_to_abgr_8888_le, + bgr_888_to_rgba_4444, + bgr_888_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + bgr_565_to_argb_8888, + bgr_565_to_rgba_8888, + bgr_565_to_argb_4444, + bgr_565_to_rgb_888, + bgr_565_to_rgb_565, + bgr_565_to_rgb_555, + bgr_565_to_rgba_5551, + bgr_565_to_argb_1555, + bgr_565_to_abgr_8888, + bgr_565_to_xbgr_8888, + bgr_565_to_bgr_888, + NULL, + bgr_565_to_bgr_555, + bgr_565_to_rgbx_8888, + bgr_565_to_xrgb_8888, + bgr_565_to_abgr_f32, + bgr_565_to_abgr_8888_le, + bgr_565_to_rgba_4444, + bgr_565_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + bgr_555_to_argb_8888, + bgr_555_to_rgba_8888, + bgr_555_to_argb_4444, + bgr_555_to_rgb_888, + bgr_555_to_rgb_565, + bgr_555_to_rgb_555, + bgr_555_to_rgba_5551, + bgr_555_to_argb_1555, + bgr_555_to_abgr_8888, + bgr_555_to_xbgr_8888, + bgr_555_to_bgr_888, + bgr_555_to_bgr_565, + NULL, + bgr_555_to_rgbx_8888, + bgr_555_to_xrgb_8888, + bgr_555_to_abgr_f32, + bgr_555_to_abgr_8888_le, + bgr_555_to_rgba_4444, + bgr_555_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rgbx_8888_to_argb_8888, + rgbx_8888_to_rgba_8888, + rgbx_8888_to_argb_4444, + rgbx_8888_to_rgb_888, + rgbx_8888_to_rgb_565, + rgbx_8888_to_rgb_555, + rgbx_8888_to_rgba_5551, + rgbx_8888_to_argb_1555, + rgbx_8888_to_abgr_8888, + rgbx_8888_to_xbgr_8888, + rgbx_8888_to_bgr_888, + rgbx_8888_to_bgr_565, + rgbx_8888_to_bgr_555, + NULL, + rgbx_8888_to_xrgb_8888, + rgbx_8888_to_abgr_f32, + rgbx_8888_to_abgr_8888_le, + rgbx_8888_to_rgba_4444, + rgbx_8888_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + xrgb_8888_to_argb_8888, + xrgb_8888_to_rgba_8888, + xrgb_8888_to_argb_4444, + xrgb_8888_to_rgb_888, + xrgb_8888_to_rgb_565, + xrgb_8888_to_rgb_555, + xrgb_8888_to_rgba_5551, + xrgb_8888_to_argb_1555, + xrgb_8888_to_abgr_8888, + xrgb_8888_to_xbgr_8888, + xrgb_8888_to_bgr_888, + xrgb_8888_to_bgr_565, + xrgb_8888_to_bgr_555, + xrgb_8888_to_rgbx_8888, + NULL, + xrgb_8888_to_abgr_f32, + xrgb_8888_to_abgr_8888_le, + xrgb_8888_to_rgba_4444, + xrgb_8888_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + abgr_f32_to_argb_8888, + abgr_f32_to_rgba_8888, + abgr_f32_to_argb_4444, + abgr_f32_to_rgb_888, + abgr_f32_to_rgb_565, + abgr_f32_to_rgb_555, + abgr_f32_to_rgba_5551, + abgr_f32_to_argb_1555, + abgr_f32_to_abgr_8888, + abgr_f32_to_xbgr_8888, + abgr_f32_to_bgr_888, + abgr_f32_to_bgr_565, + abgr_f32_to_bgr_555, + abgr_f32_to_rgbx_8888, + abgr_f32_to_xrgb_8888, + NULL, + abgr_f32_to_abgr_8888_le, + abgr_f32_to_rgba_4444, + abgr_f32_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + abgr_8888_le_to_argb_8888, + abgr_8888_le_to_rgba_8888, + abgr_8888_le_to_argb_4444, + abgr_8888_le_to_rgb_888, + abgr_8888_le_to_rgb_565, + abgr_8888_le_to_rgb_555, + abgr_8888_le_to_rgba_5551, + abgr_8888_le_to_argb_1555, + abgr_8888_le_to_abgr_8888, + abgr_8888_le_to_xbgr_8888, + abgr_8888_le_to_bgr_888, + abgr_8888_le_to_bgr_565, + abgr_8888_le_to_bgr_555, + abgr_8888_le_to_rgbx_8888, + abgr_8888_le_to_xrgb_8888, + abgr_8888_le_to_abgr_f32, + NULL, + abgr_8888_le_to_rgba_4444, + abgr_8888_le_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + rgba_4444_to_argb_8888, + rgba_4444_to_rgba_8888, + rgba_4444_to_argb_4444, + rgba_4444_to_rgb_888, + rgba_4444_to_rgb_565, + rgba_4444_to_rgb_555, + rgba_4444_to_rgba_5551, + rgba_4444_to_argb_1555, + rgba_4444_to_abgr_8888, + rgba_4444_to_xbgr_8888, + rgba_4444_to_bgr_888, + rgba_4444_to_bgr_565, + rgba_4444_to_bgr_555, + rgba_4444_to_rgbx_8888, + rgba_4444_to_xrgb_8888, + rgba_4444_to_abgr_f32, + rgba_4444_to_abgr_8888_le, + NULL, + rgba_4444_to_single_channel_8, + NULL, NULL, NULL, + }, + { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + single_channel_8_to_argb_8888, + single_channel_8_to_rgba_8888, + single_channel_8_to_argb_4444, + single_channel_8_to_rgb_888, + single_channel_8_to_rgb_565, + single_channel_8_to_rgb_555, + single_channel_8_to_rgba_5551, + single_channel_8_to_argb_1555, + single_channel_8_to_abgr_8888, + single_channel_8_to_xbgr_8888, + single_channel_8_to_bgr_888, + single_channel_8_to_bgr_565, + single_channel_8_to_bgr_555, + single_channel_8_to_rgbx_8888, + single_channel_8_to_xrgb_8888, + single_channel_8_to_abgr_f32, + single_channel_8_to_abgr_8888_le, + single_channel_8_to_rgba_4444, + NULL, NULL, NULL, NULL, + }, + {NULL}, + {NULL}, + {NULL}, +}; + +// Warning: This file was created by make_converters.py - do not edit. diff --git a/allegro/src/cpu.c b/allegro/src/cpu.c new file mode 100644 index 00000000..f17ad065 --- /dev/null +++ b/allegro/src/cpu.c @@ -0,0 +1,111 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * CPU and hardware information. + * + * By Beoran. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/cpu.h" +#include "allegro5/internal/aintern.h" + +/* +* The CPU and pysical memory detection functions below use +* sysconf() if the right define is available as a parameter, +* otherwise they use sysctl(), again if the right define is available. +* This was chosen so because sysconf is POSIX and (in theory) +* more portable than sysctl(). +* On Windows, of course, the Windows API is always used. +*/ + +#ifdef ALLEGRO_HAVE_SYSCONF +#include +#endif + +#ifdef ALLEGRO_HAVE_SYSCTL +#include +#include +#endif + +#ifdef ALLEGRO_WINDOWS +#ifndef WINVER +#define WINVER 0x0500 +#endif +#include +#endif + + +/* Function: al_get_cpu_count + */ +int al_get_cpu_count(void) +{ +#if defined(ALLEGRO_HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) + return (int)sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(ALLEGRO_HAVE_SYSCTL) + #if defined(HW_AVAILCPU) + int mib[2] = {CTL_HW, HW_AVAILCPU}; + #elif defined(HW_NCPU) + int mib[2] = {CTL_HW, HW_NCPU}; + #else + return -1; + #endif + int ncpu = 1; + size_t len = sizeof(ncpu); + if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == 0) { + return ncpu; + } +#elif defined(ALLEGRO_WINDOWS) + SYSTEM_INFO info; + GetSystemInfo(&info); + return info.dwNumberOfProcessors; +#endif + return -1; +} + +/* Function: al_get_ram_size + */ +int al_get_ram_size(void) +{ +#if defined(ALLEGRO_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) + uint64_t aid = (uint64_t) sysconf(_SC_PHYS_PAGES); + aid *= (uint64_t) sysconf(_SC_PAGESIZE); + aid /= (uint64_t) (1024 * 1024); + return (int)(aid); +#elif defined(ALLEGRO_HAVE_SYSCTL) + #ifdef HW_REALMEM + int mib[2] = {CTL_HW, HW_REALMEM}; + #elif defined(HW_PHYSMEM) + int mib[2] = {CTL_HW, HW_PHYSMEM}; + #elif defined(HW_MEMSIZE) + int mib[2] = {CTL_HW, HW_MEMSIZE}; + #else + return -1; + #endif + uint64_t memsize = 0; + size_t len = sizeof(memsize); + if (sysctl(mib, 2, &memsize, &len, NULL, 0) == 0) { + return (int)(memsize / (1024*1024)); + } +#elif defined(ALLEGRO_WINDOWS) + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + if (GlobalMemoryStatusEx(&status)) { + return (int)(status.ullTotalPhys / (1024 * 1024)); + } +#endif + return -1; +} + + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/allegro/src/debug.c b/allegro/src/debug.c new file mode 100644 index 00000000..b5dadfc7 --- /dev/null +++ b/allegro/src/debug.c @@ -0,0 +1,373 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Logging and assertion handlers. + * + * See LICENSE.txt for copyright information. + */ + + +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_debug.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/internal/aintern_vector.h" + +#ifdef ALLEGRO_WINDOWS +#include "allegro5/internal/aintern_wunicode.h" +#endif + +#ifdef ALLEGRO_ANDROID +#include +#include +#endif + + +/* tracing */ +typedef struct TRACE_INFO +{ + bool trace_virgin; + FILE *trace_file; + _AL_MUTEX trace_mutex; + + /* 0: debug, 1: info, 2: warn, 3: error */ + int level; + /* 1: line number, 2: function name, 4: timestamp */ + int flags; + /* List of channels to log. NULL to log all channels. */ + _AL_VECTOR channels; + _AL_VECTOR excluded; + /* Whether settings have been read from allegro5.cfg or not. */ + bool configured; +} TRACE_INFO; + + +static TRACE_INFO trace_info = +{ + true, + NULL, + _AL_MUTEX_UNINITED, + 0, + 7, + _AL_VECTOR_INITIALIZER(ALLEGRO_USTR *), + _AL_VECTOR_INITIALIZER(ALLEGRO_USTR *), + false +}; + +static char static_trace_buffer[2048]; + +/* run-time assertions */ +void (*_al_user_assert_handler)(char const *expr, char const *file, + int line, char const *func); + +void (*_al_user_trace_handler)(char const *message); + + +static void delete_string_list(_AL_VECTOR *v) +{ + while (_al_vector_is_nonempty(v)) { + int i = _al_vector_size(v) - 1; + ALLEGRO_USTR **iter = _al_vector_ref(v, i); + al_ustr_free(*iter); + _al_vector_delete_at(v, i); + } + _al_vector_free(v); +} + + +void _al_configure_logging(void) +{ + ALLEGRO_CONFIG *config; + char const *v; + bool got_all = false; + + config = al_get_system_config(); + v = al_get_config_value(config, "trace", "channels"); + if (v) { + ALLEGRO_USTR_INFO uinfo; + const ALLEGRO_USTR *u = al_ref_cstr(&uinfo, v); + int pos = 0; + + while (pos >= 0) { + int comma = al_ustr_find_chr(u, pos, ','); + int first; + ALLEGRO_USTR *u2, **iter; + if (comma == -1) + u2 = al_ustr_dup_substr(u, pos, al_ustr_length(u)); + else + u2 = al_ustr_dup_substr(u, pos, comma); + al_ustr_trim_ws(u2); + first = al_ustr_get(u2, 0); + + if (first == '-') { + al_ustr_remove_chr(u2, 0); + iter = _al_vector_alloc_back(&trace_info.excluded); + *iter = u2; + } + else { + if (first == '+') + al_ustr_remove_chr(u2, 0); + iter = _al_vector_alloc_back(&trace_info.channels); + *iter = u2; + if (!strcmp(al_cstr(u2), "all")) + got_all = true; + } + pos = comma; + al_ustr_get_next(u, &pos); + } + + if (got_all) + delete_string_list(&trace_info.channels); + } + +#ifdef DEBUGMODE + trace_info.level = 0; +#else + trace_info.level = 9999; +#endif + + v = al_get_config_value(config, "trace", "level"); + if (v) { + if (!strcmp(v, "error")) trace_info.level = 3; + else if (!strcmp(v, "warn")) trace_info.level = 2; + else if (!strcmp(v, "info")) trace_info.level = 1; + else if (!strcmp(v, "debug")) trace_info.level = 0; + else if (!strcmp(v, "none")) trace_info.level = 9999; + } + + v = al_get_config_value(config, "trace", "timestamps"); + if (!v || strcmp(v, "0")) + trace_info.flags |= 4; + else + trace_info.flags &= ~4; + + v = al_get_config_value(config, "trace", "functions"); + if (!v || strcmp(v, "0")) + trace_info.flags |= 2; + else + trace_info.flags &= ~2; + + v = al_get_config_value(config, "trace", "lines"); + if (!v || strcmp(v, "0")) + trace_info.flags |= 1; + else + trace_info.flags &= ~1; + + if (!trace_info.configured) + _al_mutex_init(&trace_info.trace_mutex); + + trace_info.configured = true; +} + + +static void open_trace_file(void) +{ + if (trace_info.trace_virgin) { + const char *s = getenv("ALLEGRO_TRACE"); + + if (s) + trace_info.trace_file = fopen(s, "w"); + else +#if defined(ALLEGRO_IPHONE) || defined(ALLEGRO_ANDROID) || defined(__EMSCRIPTEN__) + /* iPhone and Android don't like us writing files, so we'll be doing + * something else there by default. */ + trace_info.trace_file = NULL; +#else + trace_info.trace_file = fopen("allegro.log", "w"); +#endif + + trace_info.trace_virgin = false; + } +} + + +static void do_trace(const char *msg, ...) +{ + va_list ap; + int s = strlen(static_trace_buffer); + va_start(ap, msg); + vsnprintf(static_trace_buffer + s, sizeof(static_trace_buffer) - s, + msg, ap); + va_end(ap); +} + + +/* _al_trace_prefix: + * Conditionally write the initial part of a trace message. If we do, return true + * and continue to hold the trace_mutex lock. + */ +bool _al_trace_prefix(char const *channel, int level, + char const *file, int line, char const *function) +{ + size_t i; + char *name; + _AL_VECTOR const *v; + + if (!trace_info.configured) { + _al_configure_logging(); + } + + if (level < trace_info.level) + return false; + + v = &trace_info.channels; + if (_al_vector_is_empty(v)) + goto channel_included; + + for (i = 0; i < _al_vector_size(v); i++) { + ALLEGRO_USTR **iter = _al_vector_ref(v, i); + if (!strcmp(al_cstr(*iter), channel)) + goto channel_included; + } + + return false; + +channel_included: + + v = &trace_info.excluded; + if (_al_vector_is_nonempty(v)) { + for (i = 0; i < _al_vector_size(v); i++) { + ALLEGRO_USTR **iter = _al_vector_ref(v, i); + if (!strcmp(al_cstr(*iter), channel)) + return false; + } + } + + /* Avoid interleaved output from different threads. */ + _al_mutex_lock(&trace_info.trace_mutex); + + if (!_al_user_trace_handler) + open_trace_file(); + + do_trace("%-8s ", channel); + if (level == 0) do_trace("D "); + if (level == 1) do_trace("I "); + if (level == 2) do_trace("W "); + if (level == 3) do_trace("E "); + +#ifdef ALLEGRO_ANDROID + { + char pid_buf[16]; + snprintf(pid_buf, sizeof(pid_buf), "%i: ", gettid()); + do_trace(pid_buf); + } +#endif + +#ifdef ALLEGRO_MSVC + name = strrchr(file, '\\'); +#else + name = strrchr(file, '/'); +#endif + if (trace_info.flags & 1) { + do_trace("%20s:%-4d ", name ? name + 1 : file, line); + } + if (trace_info.flags & 2) { + do_trace("%-32s ", function); + } + if (trace_info.flags & 4) { + double t = 0; + if (al_is_system_installed()) + t = al_get_time(); + do_trace("[%10.5f] ", t); + } + + /* Do not unlock trace_mutex here; that is done by _al_trace_suffix. */ + return true; +} + + +/* _al_trace_suffix: + * Output the final part of a trace message, and release the trace_mutex lock. + */ +void _al_trace_suffix(const char *msg, ...) +{ + int olderr = errno; + va_list ap; + int s = strlen(static_trace_buffer); + va_start(ap, msg); + vsnprintf(static_trace_buffer + s, sizeof(static_trace_buffer) - s, + msg, ap); + va_end(ap); + + if (_al_user_trace_handler) { + _al_user_trace_handler(static_trace_buffer); + static_trace_buffer[0] = '\0'; + return; + } + +#ifdef ALLEGRO_ANDROID + (void)__android_log_print(ANDROID_LOG_INFO, "allegro", "%s", + static_trace_buffer); +#endif +#if defined(ALLEGRO_IPHONE) || defined(__EMSCRIPTEN__) + fprintf(stderr, "%s", static_trace_buffer); + fflush(stderr); +#endif +#ifdef ALLEGRO_WINDOWS + { + TCHAR *windows_output = _twin_utf8_to_tchar(static_trace_buffer); + OutputDebugString(windows_output); + al_free(windows_output); + } +#endif + + /* We're intentially still writing to a file if it's set even with the + * additional logging options above. */ + if (trace_info.trace_file) { + fprintf(trace_info.trace_file, "%s", static_trace_buffer); + fflush(trace_info.trace_file); + } + static_trace_buffer[0] = '\0'; + + _al_mutex_unlock(&trace_info.trace_mutex); + + errno = olderr; +} + + +void _al_shutdown_logging(void) +{ + if (trace_info.configured) { + _al_mutex_destroy(&trace_info.trace_mutex); + + delete_string_list(&trace_info.channels); + delete_string_list(&trace_info.excluded); + + trace_info.configured = false; + } + + if (trace_info.trace_file) { + fclose(trace_info.trace_file); + } + + trace_info.trace_file = NULL; + trace_info.trace_virgin = true; +} + + +/* Function: al_register_assert_handler + */ +void al_register_assert_handler(void (*handler)(char const *expr, + char const *file, int line, char const *func)) +{ + _al_user_assert_handler = handler; +} + + +/* Function: al_register_trace_handler + */ +void al_register_trace_handler(void (*handler)(char const *)) +{ + _al_user_trace_handler = handler; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/display.c b/allegro/src/display.c new file mode 100644 index 00000000..62f12f24 --- /dev/null +++ b/allegro/src/display.c @@ -0,0 +1,656 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New display driver. + * + * By Elias Pschernig. + * + * Modified by Trent Gamblin. + * + * See readme.txt for copyright information. + */ + +/* Title: Display routines + */ + + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_shader.h" +#include "allegro5/internal/aintern_system.h" + + +ALLEGRO_DEBUG_CHANNEL("display") + + +/* Function: al_create_display + */ +ALLEGRO_DISPLAY *al_create_display(int w, int h) +{ + ALLEGRO_SYSTEM *system; + ALLEGRO_DISPLAY_INTERFACE *driver; + ALLEGRO_DISPLAY *display; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings; + int64_t flags; + + system = al_get_system_driver(); + driver = system->vt->get_display_driver(); + if (!driver) { + ALLEGRO_ERROR("Failed to create display (no display driver)\n"); + return NULL; + } + + display = driver->create_display(w, h); + if (!display) { + ALLEGRO_ERROR("Failed to create display (NULL)\n"); + return NULL; + } + + ASSERT(display->vt); + + settings = &display->extra_settings; + flags = settings->required | settings->suggested; + if (!(flags & (1 << ALLEGRO_AUTO_CONVERT_BITMAPS))) { + settings->settings[ALLEGRO_AUTO_CONVERT_BITMAPS] = 1; + } + + display->min_w = 0; + display->min_h = 0; + display->max_w = 0; + display->max_h = 0; + display->use_constraints = false; + display->extra_resize_height = 0; + + display->vertex_cache = 0; + display->num_cache_vertices = 0; + display->cache_enabled = false; + display->vertex_cache_size = 0; + display->cache_texture = 0; + al_identity_transform(&display->projview_transform); + + display->default_shader = NULL; + + _al_vector_init(&display->display_invalidated_callbacks, sizeof(void *)); + _al_vector_init(&display->display_validated_callbacks, sizeof(void *)); + + display->render_state.write_mask = ALLEGRO_MASK_RGBA | ALLEGRO_MASK_DEPTH; + display->render_state.depth_test = false; + display->render_state.depth_function = ALLEGRO_RENDER_LESS; + display->render_state.alpha_test = false; + display->render_state.alpha_function = ALLEGRO_RENDER_ALWAYS; + display->render_state.alpha_test_value = 0; + + _al_vector_init(&display->bitmaps, sizeof(ALLEGRO_BITMAP*)); + + if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) { + al_set_target_bitmap(al_get_backbuffer(display)); + } + else { + ALLEGRO_DEBUG("ALLEGRO_COMPATIBLE_DISPLAY not set\n"); + _al_set_current_display_only(display); + } + + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + display->default_shader = _al_create_default_shader(display->flags); + if (!display->default_shader) { + al_destroy_display(display); + return NULL; + } + al_use_shader(display->default_shader); + } + + /* Clear the screen */ + if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) { + al_clear_to_color(al_map_rgb(0, 0, 0)); + + /* TODO: + * on iphone, don't kill the initial splashscreen - in fact, it's also + * annoying in linux to have an extra black frame as first frame and I + * suppose we never really want it + */ +#if 0 + al_flip_display(); +#endif + } + + if (settings->settings[ALLEGRO_AUTO_CONVERT_BITMAPS]) { + /* We convert video bitmaps to memory bitmaps when the display is + * destroyed, so seems only fair to re-convertt hem when the + * display is re-created again. + */ + al_convert_memory_bitmaps(); + } + + return display; +} + + + +/* Function: al_destroy_display + */ +void al_destroy_display(ALLEGRO_DISPLAY *display) +{ + if (display) { + /* This causes warnings and potential errors on Android because + * it clears the context and Android needs this thread to have + * the context bound in its destroy function and to destroy the + * shader. Just skip this part on Android. + */ +#ifndef ALLEGRO_ANDROID + ALLEGRO_BITMAP *bmp; + + bmp = al_get_target_bitmap(); + if (bmp && _al_get_bitmap_display(bmp) == display) + al_set_target_bitmap(NULL); + + /* This can happen if we have a current display, but the target bitmap + * was a memory bitmap. + */ + if (display == al_get_current_display()) + _al_set_current_display_only(NULL); +#endif + + al_destroy_shader(display->default_shader); + display->default_shader = NULL; + + ASSERT(display->vt); + display->vt->destroy_display(display); + } +} + + + +/* Function: al_get_backbuffer + */ +ALLEGRO_BITMAP *al_get_backbuffer(ALLEGRO_DISPLAY *display) +{ + if (display) { + ASSERT(display->vt); + return display->vt->get_backbuffer(display); + } + return NULL; +} + + + +/* Function: al_flip_display + */ +void al_flip_display(void) +{ + ALLEGRO_DISPLAY *display = al_get_current_display(); + + if (display) { + ASSERT(display->vt); + display->vt->flip_display(display); + } +} + + + +/* Function: al_update_display_region + */ +void al_update_display_region(int x, int y, int width, int height) +{ + ALLEGRO_DISPLAY *display = al_get_current_display(); + + if (display) { + ASSERT(display->vt); + display->vt->update_display_region(display, x, y, width, height); + } +} + + + +/* Function: al_acknowledge_resize + */ +bool al_acknowledge_resize(ALLEGRO_DISPLAY *display) +{ + ASSERT(display); + ASSERT(display->vt); + + if (!(display->flags & ALLEGRO_FULLSCREEN)) { + if (display->vt->acknowledge_resize) { + return display->vt->acknowledge_resize(display); + } + } + return false; +} + + + +/* Function: al_resize_display + */ +bool al_resize_display(ALLEGRO_DISPLAY *display, int width, int height) +{ + ASSERT(display); + ASSERT(display->vt); + + ALLEGRO_INFO("Requested display resize %dx%d+%d\n", width, height, display->extra_resize_height); + + if (display->vt->resize_display) { + return display->vt->resize_display(display, width, height + display->extra_resize_height); + } + return false; +} + + + +/* Function: al_is_compatible_bitmap + */ +bool al_is_compatible_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_DISPLAY *display = al_get_current_display(); + ASSERT(bitmap); + + if (display) { + ASSERT(display->vt); + return display->vt->is_compatible_bitmap(display, bitmap); + } + + return false; +} + + + +/* Function: al_get_display_width + */ +int al_get_display_width(ALLEGRO_DISPLAY *display) +{ + ASSERT(display); + + return display->w; +} + + + +/* Function: al_get_display_height + */ +int al_get_display_height(ALLEGRO_DISPLAY *display) +{ + ASSERT(display); + + return display->h; +} + + +/* Function: al_get_display_format + */ +int al_get_display_format(ALLEGRO_DISPLAY *display) +{ + ASSERT(display); + + return display->backbuffer_format; +} + + +/* Function: al_get_display_refresh_rate + */ +int al_get_display_refresh_rate(ALLEGRO_DISPLAY *display) +{ + ASSERT(display); + + return display->refresh_rate; +} + + + +/* Function: al_get_display_flags + */ +int al_get_display_flags(ALLEGRO_DISPLAY *display) +{ + ASSERT(display); + + return display->flags; +} + + +/* Function: al_get_display_orientation + */ +int al_get_display_orientation(ALLEGRO_DISPLAY* display) +{ + if (display && display->vt->get_orientation) + return display->vt->get_orientation(display); + else + return ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN; +} + + +/* Function: al_wait_for_vsync + */ +bool al_wait_for_vsync(void) +{ + ALLEGRO_DISPLAY *display = al_get_current_display(); + ASSERT(display); + + if (display->vt->wait_for_vsync) + return display->vt->wait_for_vsync(display); + else + return false; +} + + + +/* Function: al_set_display_icon + */ +void al_set_display_icon(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon) +{ + ALLEGRO_BITMAP *icons[1] = { icon }; + + al_set_display_icons(display, 1, icons); +} + + + +/* Function: al_set_display_icons + */ +void al_set_display_icons(ALLEGRO_DISPLAY *display, + int num_icons, ALLEGRO_BITMAP *icons[]) +{ + int i; + + ASSERT(display); + ASSERT(num_icons >= 1); + ASSERT(icons); + for (i = 0; i < num_icons; i++) { + ASSERT(icons[i]); + } + + if (display->vt->set_icons) { + display->vt->set_icons(display, num_icons, icons); + } +} + +/* Function: al_set_window_position + */ +void al_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +{ + ASSERT(display); + + if (display && display->flags & ALLEGRO_FULLSCREEN) { + return; + } + + if (display && display->vt && display->vt->set_window_position) { + display->vt->set_window_position(display, x, y); + } +} + + +/* Function: al_get_window_position + */ +void al_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + ASSERT(x); + ASSERT(y); + + if (display && display->vt && display->vt->get_window_position) { + display->vt->get_window_position(display, x, y); + } + else { + *x = *y = -1; + } +} + + +/* Function: al_set_window_constraints + */ +bool al_set_window_constraints(ALLEGRO_DISPLAY *display, + int min_w, int min_h, int max_w, int max_h) +{ + ASSERT(display); + + /* Perform some basic checks. */ + if (min_w < 0 || min_h < 0 || max_w < 0 || max_h < 0) { + return false; + } + if (min_w > 0 && max_w > 0 && max_w < min_w) { + return false; + } + if (min_h > 0 && max_h > 0 && max_h < min_h) { + return false; + } + + /* Cannot constrain when fullscreen. */ + if (display->flags & ALLEGRO_FULLSCREEN) { + return false; + } + + /* Cannot constrain if not resizable. */ + if (!(display->flags & ALLEGRO_RESIZABLE)) { + return false; + } + + if (display && display->vt && display->vt->set_window_constraints) { + return display->vt->set_window_constraints(display, min_w, min_h, + max_w, max_h); + } + else { + return false; + } +} + + +/* Function: al_get_window_constraints + */ +bool al_get_window_constraints(ALLEGRO_DISPLAY *display, + int *min_w, int *min_h, int *max_w, int *max_h) +{ + ASSERT(display); + ASSERT(min_w); + ASSERT(min_h); + ASSERT(max_w); + ASSERT(max_h); + + if (display && display->vt && display->vt->get_window_constraints) { + return display->vt->get_window_constraints(display, min_w, min_h, + max_w, max_h); + } + else { + return false; + } +} + + +/* Function: al_set_display_flag + */ +bool al_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) +{ + ASSERT(display); + + if (display && display->vt && display->vt->set_display_flag) { + return display->vt->set_display_flag(display, flag, onoff); + } + return false; +} + + +/* Function: al_set_window_title + */ +void al_set_window_title(ALLEGRO_DISPLAY *display, const char *title) +{ + if (display && display->vt && display->vt->set_window_title) + display->vt->set_window_title(display, title); +} + + +/* Function: al_get_display_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_display_event_source(ALLEGRO_DISPLAY *display) +{ + return &display->es; +} + +/* Function: al_hold_bitmap_drawing + */ +void al_hold_bitmap_drawing(bool hold) +{ + ALLEGRO_DISPLAY *current_display = al_get_current_display(); + + if (current_display) { + if (hold && !current_display->cache_enabled) { + /* + * Set the hardware transformation to identity, but keep the bitmap + * transform the same as it was. Relies on the fact that when bitmap + * holding is turned on, al_use_transform does not update the hardware + * transformation. + */ + ALLEGRO_TRANSFORM old, ident; + al_copy_transform(&old, al_get_current_transform()); + al_identity_transform(&ident); + + al_use_transform(&ident); + current_display->cache_enabled = hold; + al_use_transform(&old); + } + else { + current_display->cache_enabled = hold; + } + + if (!hold) { + current_display->vt->flush_vertex_cache(current_display); + /* + * Reset the hardware transform to match the stored transform. + */ + al_use_transform(al_get_current_transform()); + } + } +} + +/* Function: al_is_bitmap_drawing_held + */ +bool al_is_bitmap_drawing_held(void) +{ + ALLEGRO_DISPLAY *current_display = al_get_current_display(); + + if (current_display) + return current_display->cache_enabled; + else + return false; +} + +void _al_add_display_invalidated_callback(ALLEGRO_DISPLAY* display, void (*display_invalidated)(ALLEGRO_DISPLAY*)) +{ + if (_al_vector_find(&display->display_invalidated_callbacks, display_invalidated) >= 0) { + return; + } + else { + void (**callback)(ALLEGRO_DISPLAY *) = _al_vector_alloc_back(&display->display_invalidated_callbacks); + *callback = display_invalidated; + } +} + +void _al_add_display_validated_callback(ALLEGRO_DISPLAY* display, void (*display_validated)(ALLEGRO_DISPLAY*)) +{ + if (_al_vector_find(&display->display_validated_callbacks, display_validated) >= 0) { + return; + } + else { + void (**callback)(ALLEGRO_DISPLAY *) = _al_vector_alloc_back(&display->display_validated_callbacks); + *callback = display_validated; + } +} + +void _al_remove_display_invalidated_callback(ALLEGRO_DISPLAY *display, void (*callback)(ALLEGRO_DISPLAY *)) +{ + _al_vector_find_and_delete(&display->display_invalidated_callbacks, &callback); +} + +void _al_remove_display_validated_callback(ALLEGRO_DISPLAY *display, void (*callback)(ALLEGRO_DISPLAY *)) +{ + _al_vector_find_and_delete(&display->display_validated_callbacks, &callback); +} + +/* Function: al_acknowledge_drawing_halt + */ +void al_acknowledge_drawing_halt(ALLEGRO_DISPLAY *display) +{ + if (display->vt->acknowledge_drawing_halt) { + display->vt->acknowledge_drawing_halt(display); + } +} + +/* Function: al_acknowledge_drawing_resume + */ +void al_acknowledge_drawing_resume(ALLEGRO_DISPLAY *display) +{ + if (display->vt->acknowledge_drawing_resume) { + display->vt->acknowledge_drawing_resume(display); + } +} + +/* Function: al_set_render_state + */ +void al_set_render_state(ALLEGRO_RENDER_STATE state, int value) +{ + ALLEGRO_DISPLAY *display = al_get_current_display(); + + if (!display) + return; + + switch (state) { + case ALLEGRO_ALPHA_TEST: + display->render_state.alpha_test = value; + break; + case ALLEGRO_WRITE_MASK: + display->render_state.write_mask = value; + break; + case ALLEGRO_DEPTH_TEST: + display->render_state.depth_test = value; + break; + case ALLEGRO_DEPTH_FUNCTION: + display->render_state.depth_function = value; + break; + case ALLEGRO_ALPHA_FUNCTION: + display->render_state.alpha_function = value; + break; + case ALLEGRO_ALPHA_TEST_VALUE: + display->render_state.alpha_test_value = value; + break; + default: + ALLEGRO_WARN("unknown state to change: %d\n", state); + break; + } + + if (display->vt && display->vt->update_render_state) { + display->vt->update_render_state(display); + } +} + +/* Function: al_backup_dirty_bitmaps + */ +void al_backup_dirty_bitmaps(ALLEGRO_DISPLAY *display) +{ + unsigned int i; + + for (i = 0; i < display->bitmaps._size; i++) { + ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&display->bitmaps, i); + ALLEGRO_BITMAP *bmp = *bptr; + if (_al_get_bitmap_display(bmp) == display) { + if (bmp->vt && bmp->vt->backup_dirty_bitmap) { + bmp->vt->backup_dirty_bitmap(bmp); + } + } + } +} + +/* Function: al_apply_window_constraints + */ +void al_apply_window_constraints(ALLEGRO_DISPLAY *display, bool onoff) +{ + display->use_constraints = onoff; + + if (display->vt && display->vt->apply_window_constraints) + display->vt->apply_window_constraints(display, onoff); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/display_settings.c b/allegro/src/display_settings.c new file mode 100644 index 00000000..549309c4 --- /dev/null +++ b/allegro/src/display_settings.c @@ -0,0 +1,900 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Additional display settings (like multisample). + * + * Original code from AllegroGL. + * + * Heavily modified by Elias Pschernig. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_display.h" +#include + +ALLEGRO_DEBUG_CHANNEL("display") + + +/* Function: al_set_new_display_option + */ +void al_set_new_display_option(int option, int value, int importance) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; + extras = _al_get_new_display_settings(); + switch (importance) { + case ALLEGRO_REQUIRE: + extras->required |= (int64_t)1 << option; + extras->suggested &= ~((int64_t)1 << option); + break; + case ALLEGRO_SUGGEST: + extras->suggested |= (int64_t)1 << option; + extras->required &= ~((int64_t)1 << option); + break; + case ALLEGRO_DONTCARE: + extras->required &= ~((int64_t)1 << option); + extras->suggested &= ~((int64_t)1 << option); + break; + } + extras->settings[option] = value; +} + + +int _al_get_suggested_display_option(ALLEGRO_DISPLAY *d, + int option, int default_value) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *s = &d->extra_settings; + uint64_t flags = s->required | s->suggested; + if (flags & ((uint64_t)1 << option)) + return s->settings[option]; + return default_value; +} + + +/* Function: al_get_new_display_option + */ +int al_get_new_display_option(int option, int *importance) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; + extras = _al_get_new_display_settings(); + if (extras->required & ((int64_t)1 << option)) { + if (importance) *importance = ALLEGRO_REQUIRE; + return extras->settings[option]; + } + if (extras->suggested & ((int64_t)1 << option)) { + if (importance) *importance = ALLEGRO_SUGGEST; + return extras->settings[option]; + } + if (importance) *importance = ALLEGRO_DONTCARE; + return 0; +} + +/* Function: al_set_display_option + */ +void al_set_display_option(ALLEGRO_DISPLAY *display, int option, int value) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; + extras = &display->extra_settings; + extras->settings[option] = value; + if (display->vt->set_display_option) { + display->vt->set_display_option(display, option, value); + } +} + +/* Function: al_get_display_option + */ +int al_get_display_option(ALLEGRO_DISPLAY *display, int option) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; + extras = &display->extra_settings; + return extras->settings[option]; +} + + +/* Function: al_reset_new_display_options + */ +void al_reset_new_display_options(void) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; + extras = _al_get_new_display_settings(); + _al_fill_display_settings(extras); +} + + +#define req ref->required +#define sug ref->suggested + + +/* _al_fill_display_settings() + * Will fill in missing settings by 'guessing' what the user intended. + */ +void _al_fill_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref) +{ + int all_components = (1<settings[ALLEGRO_COLOR_SIZE] = ref->settings[ALLEGRO_RED_SIZE] + + ref->settings[ALLEGRO_GREEN_SIZE] + + ref->settings[ALLEGRO_BLUE_SIZE] + + ref->settings[ALLEGRO_ALPHA_SIZE]; + + /* Round depth to 8 bits */ + ref->settings[ALLEGRO_COLOR_SIZE] = (ref->settings[ALLEGRO_COLOR_SIZE] + 7) / 8; + } + /* If only some components were set, guess the others */ + else if ((req | sug) & all_components) { + int avg = ((req | sug) & (1<settings[ALLEGRO_RED_SIZE]: 0) + + ((req | sug) & (1<settings[ALLEGRO_GREEN_SIZE]: 0) + + ((req | sug) & (1<settings[ALLEGRO_BLUE_SIZE]: 0) + + ((req | sug) & (1<settings[ALLEGRO_ALPHA_SIZE]: 0); + + int num = ((req | sug) & (1<settings[ALLEGRO_RED_SIZE] = avg; + } + if (((req | sug) & (1<settings[ALLEGRO_GREEN_SIZE] = avg; + } + if (((req | sug) & (1<settings[ALLEGRO_BLUE_SIZE] = avg; + } + if (((req | sug) & (1<settings[ALLEGRO_ALPHA_SIZE] = avg; + } + + /* If color depth wasn't defined, figure it out */ + if (((req | sug) & (1<settings[ALLEGRO_COLOR_SIZE], + eds->settings[ALLEGRO_RED_SIZE], + eds->settings[ALLEGRO_GREEN_SIZE], + eds->settings[ALLEGRO_BLUE_SIZE], + eds->settings[ALLEGRO_ALPHA_SIZE], + eds->settings[ALLEGRO_DEPTH_SIZE], + eds->settings[ALLEGRO_STENCIL_SIZE], + eds->settings[ALLEGRO_ACC_RED_SIZE], + eds->settings[ALLEGRO_ACC_RED_SIZE], + eds->settings[ALLEGRO_ACC_RED_SIZE], + eds->settings[ALLEGRO_ACC_RED_SIZE], + eds->settings[ALLEGRO_SAMPLES], + eds->settings[ALLEGRO_SAMPLE_BUFFERS]); +} + +int _al_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref) +{ + int score = 0; + + debug_display_settings(eds); + + if (eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] != ref->settings[ALLEGRO_COMPATIBLE_DISPLAY]) { + if (req & (1<settings[ALLEGRO_VSYNC] != ref->settings[ALLEGRO_VSYNC]) { + if (req & (1<settings[ALLEGRO_COLOR_SIZE] != ref->settings[ALLEGRO_COLOR_SIZE]) { + if (req & (1<settings[ALLEGRO_COLOR_SIZE] < ref->settings[ALLEGRO_COLOR_SIZE]) + score += (96 * eds->settings[ALLEGRO_COLOR_SIZE]) / ref->settings[ALLEGRO_COLOR_SIZE]; + else + score += 96 + 96 / (1 + eds->settings[ALLEGRO_COLOR_SIZE] - ref->settings[ALLEGRO_COLOR_SIZE]); + } + + /* check colour component widths here and Allegro formatness */ + if ((req & (1<settings[ALLEGRO_RED_SIZE] != ref->settings[ALLEGRO_RED_SIZE])) { + ALLEGRO_DEBUG("Red depth requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_RED_SIZE] < ref->settings[ALLEGRO_RED_SIZE]) { + score += (16 * eds->settings[ALLEGRO_RED_SIZE]) / ref->settings[ALLEGRO_RED_SIZE]; + } + else { + score += 16 + 16 / (1 + eds->settings[ALLEGRO_RED_SIZE] - ref->settings[ALLEGRO_RED_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_GREEN_SIZE] != ref->settings[ALLEGRO_GREEN_SIZE])) { + ALLEGRO_DEBUG("Green depth requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_GREEN_SIZE] < ref->settings[ALLEGRO_GREEN_SIZE]) { + score += (16 * eds->settings[ALLEGRO_GREEN_SIZE]) / ref->settings[ALLEGRO_GREEN_SIZE]; + } + else { + score += 16 + 16 / (1 + eds->settings[ALLEGRO_GREEN_SIZE] - ref->settings[ALLEGRO_GREEN_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_BLUE_SIZE] != ref->settings[ALLEGRO_BLUE_SIZE])) { + ALLEGRO_DEBUG("Blue depth requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_BLUE_SIZE] < ref->settings[ALLEGRO_BLUE_SIZE]) { + score += (16 * eds->settings[ALLEGRO_BLUE_SIZE]) / ref->settings[ALLEGRO_BLUE_SIZE]; + } + else { + score += 16 + 16 / (1 + eds->settings[ALLEGRO_BLUE_SIZE] - ref->settings[ALLEGRO_BLUE_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_ALPHA_SIZE] != ref->settings[ALLEGRO_ALPHA_SIZE])) { + ALLEGRO_DEBUG("Alpha depth requirement not met (%d instead of %d).\n", + eds->settings[ALLEGRO_ALPHA_SIZE], ref->settings[ALLEGRO_ALPHA_SIZE]); + return -1; + } + + if (sug & (1<settings[ALLEGRO_ALPHA_SIZE] < ref->settings[ALLEGRO_ALPHA_SIZE]) { + score += (16 * eds->settings[ALLEGRO_ALPHA_SIZE]) / ref->settings[ALLEGRO_ALPHA_SIZE]; + } + else { + score += 16 + 16 / (1 + eds->settings[ALLEGRO_ALPHA_SIZE] - ref->settings[ALLEGRO_ALPHA_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_ACC_RED_SIZE] != ref->settings[ALLEGRO_ACC_RED_SIZE])) { + ALLEGRO_DEBUG("Accumulator Red depth requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_ACC_RED_SIZE] < ref->settings[ALLEGRO_ACC_RED_SIZE]) { + score += (16 * eds->settings[ALLEGRO_ACC_RED_SIZE]) / ref->settings[ALLEGRO_ACC_RED_SIZE]; + } + else { + score += 16 + 16 / (1 + eds->settings[ALLEGRO_ACC_RED_SIZE] - ref->settings[ALLEGRO_ACC_RED_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_ACC_GREEN_SIZE] != ref->settings[ALLEGRO_ACC_GREEN_SIZE])) { + ALLEGRO_DEBUG("Accumulator Green depth requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_ACC_GREEN_SIZE] < ref->settings[ALLEGRO_ACC_GREEN_SIZE]) { + score += (16 * eds->settings[ALLEGRO_ACC_GREEN_SIZE]) / ref->settings[ALLEGRO_ACC_GREEN_SIZE]; + } + else { + score += 16 + 16 / (1 + eds->settings[ALLEGRO_ACC_GREEN_SIZE] - ref->settings[ALLEGRO_ACC_GREEN_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_ACC_BLUE_SIZE] != ref->settings[ALLEGRO_ACC_BLUE_SIZE])) { + ALLEGRO_DEBUG("Accumulator Blue depth requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_ACC_BLUE_SIZE] < ref->settings[ALLEGRO_ACC_BLUE_SIZE]) { + score += (16 * eds->settings[ALLEGRO_ACC_BLUE_SIZE]) / ref->settings[ALLEGRO_ACC_BLUE_SIZE]; + } + else { + score += 16 + 16 / (1 + eds->settings[ALLEGRO_ACC_BLUE_SIZE] - ref->settings[ALLEGRO_ACC_BLUE_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_ACC_ALPHA_SIZE] != ref->settings[ALLEGRO_ACC_ALPHA_SIZE])) { + ALLEGRO_DEBUG("Accumulator Alpha depth requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_ACC_ALPHA_SIZE] < ref->settings[ALLEGRO_ACC_ALPHA_SIZE]) { + score += (16 * eds->settings[ALLEGRO_ACC_ALPHA_SIZE]) / ref->settings[ALLEGRO_ACC_ALPHA_SIZE]; + } + else { + score += 16 + 16 / (1 + eds->settings[ALLEGRO_ACC_ALPHA_SIZE] - ref->settings[ALLEGRO_ACC_ALPHA_SIZE]); + } + } + + if (!eds->settings[ALLEGRO_SINGLE_BUFFER] != !ref->settings[ALLEGRO_SINGLE_BUFFER]) { + if (req & (1<settings[ALLEGRO_STEREO] != !ref->settings[ALLEGRO_STEREO]) { + if (req & (1<settings[ALLEGRO_AUX_BUFFERS] < ref->settings[ALLEGRO_AUX_BUFFERS])) { + ALLEGRO_DEBUG("Aux Buffer requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_AUX_BUFFERS] < ref->settings[ALLEGRO_AUX_BUFFERS]) { + score += (64 * eds->settings[ALLEGRO_AUX_BUFFERS]) / ref->settings[ALLEGRO_AUX_BUFFERS]; + } + else { + score += 64 + 64 / (1 + eds->settings[ALLEGRO_AUX_BUFFERS] - ref->settings[ALLEGRO_AUX_BUFFERS]); + } + } + + if ((req & (1<settings[ALLEGRO_DEPTH_SIZE] != ref->settings[ALLEGRO_DEPTH_SIZE])) { + ALLEGRO_DEBUG("Z-Buffer requirement not met.\n"); + return -1; + } + if (sug & (1<settings[ALLEGRO_DEPTH_SIZE] < ref->settings[ALLEGRO_DEPTH_SIZE]) { + score += (64 * eds->settings[ALLEGRO_DEPTH_SIZE]) / ref->settings[ALLEGRO_DEPTH_SIZE]; + } + else { + score += 64 + 64 / (1 + eds->settings[ALLEGRO_DEPTH_SIZE] - ref->settings[ALLEGRO_DEPTH_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_STENCIL_SIZE] != ref->settings[ALLEGRO_STENCIL_SIZE])) { + ALLEGRO_DEBUG("Stencil depth requirement not met.\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_STENCIL_SIZE] < ref->settings[ALLEGRO_STENCIL_SIZE]) { + score += (64 * eds->settings[ALLEGRO_STENCIL_SIZE]) / ref->settings[ALLEGRO_STENCIL_SIZE]; + } + else { + score += 64 + 64 / (1 + eds->settings[ALLEGRO_STENCIL_SIZE] - ref->settings[ALLEGRO_STENCIL_SIZE]); + } + } + + if ((req & (1<settings[ALLEGRO_RENDER_METHOD] != ref->settings[ALLEGRO_RENDER_METHOD]) + || (ref->settings[ALLEGRO_RENDER_METHOD] == 2))) { + ALLEGRO_DEBUG("Render Method requirement not met.\n"); + return -1; + } + + if ((sug & (1<settings[ALLEGRO_RENDER_METHOD] == ref->settings[ALLEGRO_RENDER_METHOD])) { + score += 1024; + } + else if (eds->settings[ALLEGRO_RENDER_METHOD] == 1) { + score++; /* Add 1 for hw accel */ + } + + if ((req & (1<settings[ALLEGRO_SAMPLE_BUFFERS] != ref->settings[ALLEGRO_SAMPLE_BUFFERS])) { + ALLEGRO_DEBUG("Multisample Buffers requirement not met\n"); + return -1; + } + else if (sug & (1<settings[ALLEGRO_SAMPLE_BUFFERS] == ref->settings[ALLEGRO_SAMPLE_BUFFERS]) { + score += 128; + } + } + + if ((req & (1<settings[ALLEGRO_SAMPLES] != ref->settings[ALLEGRO_SAMPLES])) { + ALLEGRO_DEBUG("Multisample Samples requirement not met\n"); + return -1; + } + + if (sug & (1<settings[ALLEGRO_SAMPLES] < ref->settings[ALLEGRO_SAMPLES]) { + score += (64 * eds->settings[ALLEGRO_SAMPLES]) / ref->settings[ALLEGRO_SAMPLES]; + } + else { + score += 64 + 64 / (1 + eds->settings[ALLEGRO_SAMPLES] - ref->settings[ALLEGRO_SAMPLES]); + } + } + + if (!eds->settings[ALLEGRO_FLOAT_COLOR] != !ref->settings[ALLEGRO_FLOAT_COLOR]) { + if (req & (1<settings[ALLEGRO_FLOAT_DEPTH] != !ref->settings[ALLEGRO_FLOAT_DEPTH]) { + if (req & (1<score == f1->score) + return f0->index - f1->index; /* lower better */ + else + return f1->score - f0->score; /* higher better */ +} + + +int _al_deduce_color_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) +{ + /* dummy value to check if the format was detected */ + int format = ALLEGRO_PIXEL_FORMAT_ANY; + + if (eds->settings[ALLEGRO_RED_SIZE] == 8 && + eds->settings[ALLEGRO_GREEN_SIZE] == 8 && + eds->settings[ALLEGRO_BLUE_SIZE] == 8) { + if (eds->settings[ALLEGRO_ALPHA_SIZE] == 8 && + eds->settings[ALLEGRO_COLOR_SIZE] == 32) { + if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 0 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 8 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 16 && + eds->settings[ALLEGRO_RED_SHIFT] == 24) { + format = ALLEGRO_PIXEL_FORMAT_RGBA_8888; + } + else if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 24 && + eds->settings[ALLEGRO_RED_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 16) { + format = ALLEGRO_PIXEL_FORMAT_ABGR_8888; + } + else if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 24 && + eds->settings[ALLEGRO_RED_SHIFT] == 16 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 0) { + format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; + } + } + else if (eds->settings[ALLEGRO_ALPHA_SIZE] == 0 && + eds->settings[ALLEGRO_COLOR_SIZE] == 24) { + if (eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && + eds->settings[ALLEGRO_RED_SHIFT] == 16) { + format = ALLEGRO_PIXEL_FORMAT_RGB_888; + } + else if (eds->settings[ALLEGRO_RED_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 16) { + format = ALLEGRO_PIXEL_FORMAT_BGR_888; + } + } + else if (eds->settings[ALLEGRO_ALPHA_SIZE] == 0 && + eds->settings[ALLEGRO_COLOR_SIZE] == 32) { + if (eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && + eds->settings[ALLEGRO_RED_SHIFT] == 16) { + format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; + } + else if (eds->settings[ALLEGRO_RED_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 8 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 16) { + format = ALLEGRO_PIXEL_FORMAT_XBGR_8888; + } + else if (eds->settings[ALLEGRO_RED_SHIFT] == 24 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 16 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 8) { + format = ALLEGRO_PIXEL_FORMAT_RGBX_8888; + } + } + } + else if (eds->settings[ALLEGRO_RED_SIZE] == 5 && + eds->settings[ALLEGRO_GREEN_SIZE] == 6 && + eds->settings[ALLEGRO_BLUE_SIZE] == 5) { + if (eds->settings[ALLEGRO_RED_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 5 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 11) { + format = ALLEGRO_PIXEL_FORMAT_BGR_565; + } + else if (eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 5 && + eds->settings[ALLEGRO_RED_SHIFT] == 11) { + format = ALLEGRO_PIXEL_FORMAT_RGB_565; + } + } + else if (eds->settings[ALLEGRO_RED_SIZE] == 5 && + eds->settings[ALLEGRO_GREEN_SIZE] == 5 && + eds->settings[ALLEGRO_BLUE_SIZE] == 5) { + if (eds->settings[ALLEGRO_ALPHA_SIZE] == 1 && + eds->settings[ALLEGRO_COLOR_SIZE] == 16) { + if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 0 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 1 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 6 && + eds->settings[ALLEGRO_RED_SHIFT] == 11) { + format = ALLEGRO_PIXEL_FORMAT_RGBA_5551; + } + if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 15 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 5 && + eds->settings[ALLEGRO_RED_SHIFT] == 10) { + format = ALLEGRO_PIXEL_FORMAT_ARGB_1555; + } + } + } + else if (eds->settings[ALLEGRO_RED_SIZE] == 4 && + eds->settings[ALLEGRO_GREEN_SIZE] == 4 && + eds->settings[ALLEGRO_BLUE_SIZE] == 4) { + if (eds->settings[ALLEGRO_ALPHA_SIZE] == 4 && + eds->settings[ALLEGRO_COLOR_SIZE] == 16) { + if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 12 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 4 && + eds->settings[ALLEGRO_RED_SHIFT] == 8) { + format = ALLEGRO_PIXEL_FORMAT_ARGB_4444; + } + else if (eds->settings[ALLEGRO_ALPHA_SHIFT] == 12 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 8 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 4 && + eds->settings[ALLEGRO_RED_SHIFT] == 0) { + format = ALLEGRO_PIXEL_FORMAT_RGBA_4444; + } + } + } + + if (format == ALLEGRO_PIXEL_FORMAT_ANY) { + ALLEGRO_WARN( + "Could not deduce color format, sizes = (%d,%d,%d,%d,%d), shifts = (%d,%d,%d,%d)\n", + eds->settings[ALLEGRO_RED_SIZE], + eds->settings[ALLEGRO_GREEN_SIZE], + eds->settings[ALLEGRO_BLUE_SIZE], + eds->settings[ALLEGRO_ALPHA_SIZE], + eds->settings[ALLEGRO_COLOR_SIZE], + eds->settings[ALLEGRO_RED_SHIFT], + eds->settings[ALLEGRO_GREEN_SHIFT], + eds->settings[ALLEGRO_BLUE_SHIFT], + eds->settings[ALLEGRO_ALPHA_SHIFT]); + } + + return format; +} + + +void _al_set_color_components(int format, ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, + int importance) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS old_eds; + memcpy(&old_eds, _al_get_new_display_settings(), sizeof(old_eds)); + _al_set_new_display_settings(eds); + + al_set_new_display_option(ALLEGRO_RED_SIZE, 0, ALLEGRO_DONTCARE); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, ALLEGRO_DONTCARE); + al_set_new_display_option(ALLEGRO_GREEN_SIZE, 0, ALLEGRO_DONTCARE); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 0, ALLEGRO_DONTCARE); + al_set_new_display_option(ALLEGRO_BLUE_SIZE, 0, ALLEGRO_DONTCARE); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, ALLEGRO_DONTCARE); + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, ALLEGRO_DONTCARE); + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, ALLEGRO_DONTCARE); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 0, ALLEGRO_DONTCARE); + + switch (format) { + case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 8, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 1, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 24, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: + /* With OpenGL drivers, we never "know" the actual pixel + * format. We use glReadPixels when we lock the screen, so + * we can always lock the screen in any format we want. There + * is no "display format". + * + * Therefore it makes no sense to fail display creation + * if either an RGB or RGBX format was requested but the + * other seems available only in WGL/GLX (those really report + * the number of bits used for red/green/blue/alpha to us only. + * They never report any "X bits".). + */ + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, ALLEGRO_SUGGEST); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 8, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, importance); + break; + } + + switch (format) { + case ALLEGRO_PIXEL_FORMAT_RGBA_8888: + case ALLEGRO_PIXEL_FORMAT_ABGR_8888: + case ALLEGRO_PIXEL_FORMAT_ARGB_8888: + case ALLEGRO_PIXEL_FORMAT_RGB_888: + case ALLEGRO_PIXEL_FORMAT_BGR_888: + case ALLEGRO_PIXEL_FORMAT_RGBX_8888: + case ALLEGRO_PIXEL_FORMAT_XRGB_8888: + case ALLEGRO_PIXEL_FORMAT_XBGR_8888: + al_set_new_display_option(ALLEGRO_RED_SIZE, 8, importance); + al_set_new_display_option(ALLEGRO_GREEN_SIZE, 8, importance); + al_set_new_display_option(ALLEGRO_BLUE_SIZE, 8, importance); + break; + case ALLEGRO_PIXEL_FORMAT_BGR_565: + case ALLEGRO_PIXEL_FORMAT_RGB_565: + al_set_new_display_option(ALLEGRO_RED_SIZE, 5, importance); + al_set_new_display_option(ALLEGRO_GREEN_SIZE, 6, importance); + al_set_new_display_option(ALLEGRO_BLUE_SIZE, 5, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGBA_5551: + case ALLEGRO_PIXEL_FORMAT_ARGB_1555: + al_set_new_display_option(ALLEGRO_RED_SIZE, 5, importance); + al_set_new_display_option(ALLEGRO_GREEN_SIZE, 5, importance); + al_set_new_display_option(ALLEGRO_BLUE_SIZE, 5, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ARGB_4444: + case ALLEGRO_PIXEL_FORMAT_RGBA_4444: + al_set_new_display_option(ALLEGRO_RED_SIZE, 4, importance); + al_set_new_display_option(ALLEGRO_GREEN_SIZE, 4, importance); + al_set_new_display_option(ALLEGRO_BLUE_SIZE, 4, importance); + break; + } + + switch (format) { + case ALLEGRO_PIXEL_FORMAT_RGBA_8888: + case ALLEGRO_PIXEL_FORMAT_ABGR_8888: + case ALLEGRO_PIXEL_FORMAT_ARGB_8888: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 8, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGB_888: + case ALLEGRO_PIXEL_FORMAT_BGR_888: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 24, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGBX_8888: + case ALLEGRO_PIXEL_FORMAT_XRGB_8888: + case ALLEGRO_PIXEL_FORMAT_XBGR_8888: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, importance); + break; + case ALLEGRO_PIXEL_FORMAT_BGR_565: + case ALLEGRO_PIXEL_FORMAT_RGB_565: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGBA_5551: + case ALLEGRO_PIXEL_FORMAT_ARGB_1555: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 1, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ARGB_4444: + case ALLEGRO_PIXEL_FORMAT_RGBA_4444: + al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 4, importance); + al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance); + break; + } + + switch (format) { + case ALLEGRO_PIXEL_FORMAT_RGBA_8888: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 16, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 24, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ABGR_8888: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 24, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 16, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ARGB_8888: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 24, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 16, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGB_888: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 16, importance); + break; + case ALLEGRO_PIXEL_FORMAT_BGR_888: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 16, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); + break; + case ALLEGRO_PIXEL_FORMAT_XRGB_8888: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 16, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGBX_8888: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 16, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 24, importance); + break; + case ALLEGRO_PIXEL_FORMAT_XBGR_8888: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 16, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); + break; + case ALLEGRO_PIXEL_FORMAT_BGR_565: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 11, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 0, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGB_565: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 11, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGBA_5551: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 1, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 6, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 11, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ARGB_1555: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 15, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 10, importance); + break; + case ALLEGRO_PIXEL_FORMAT_ARGB_4444: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 12, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 4, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 8, importance); + break; + case ALLEGRO_PIXEL_FORMAT_RGBA_4444: + al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance); + al_set_new_display_option(ALLEGRO_BLUE_SHIFT, 4, importance); + al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance); + al_set_new_display_option(ALLEGRO_RED_SHIFT, 12, importance); + break; + } + + memcpy(eds, _al_get_new_display_settings(), sizeof(*eds)); + _al_set_new_display_settings(&old_eds); +} diff --git a/allegro/src/drawing.c b/allegro/src/drawing.c new file mode 100644 index 00000000..8b8744d9 --- /dev/null +++ b/allegro/src/drawing.c @@ -0,0 +1,83 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Simple drawing primitives. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_memdraw.h" +#include "allegro5/internal/aintern_pixels.h" + + +/* Function: al_clear_to_color + */ +void al_clear_to_color(ALLEGRO_COLOR color) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ASSERT(target); + + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP || + _al_pixel_format_is_compressed(al_get_bitmap_format(target))) { + _al_clear_bitmap_by_locking(target, &color); + } + else { + ALLEGRO_DISPLAY *display = _al_get_bitmap_display(target); + ASSERT(display); + ASSERT(display->vt); + display->vt->clear(display, &color); + } +} + + +/* Function: al_clear_depth_buffer + */ +void al_clear_depth_buffer(float z) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ASSERT(target); + + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP) { + /* has no depth buffer */ + } + else { + ALLEGRO_DISPLAY *display = _al_get_bitmap_display(target); + ASSERT(display); + display->vt->clear_depth_buffer(display, z); + } +} + + +/* Function: al_draw_pixel + */ +void al_draw_pixel(float x, float y, ALLEGRO_COLOR color) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + + ASSERT(target); + + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP || + _al_pixel_format_is_compressed(al_get_bitmap_format(target))) { + _al_draw_pixel_memory(target, x, y, &color); + } + else { + ALLEGRO_DISPLAY *display = _al_get_bitmap_display(target); + ASSERT(display); + ASSERT(display->vt); + display->vt->draw_pixel(display, x, y, &color); + } +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/dtor.c b/allegro/src/dtor.c new file mode 100644 index 00000000..b966a125 --- /dev/null +++ b/allegro/src/dtor.c @@ -0,0 +1,265 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Destructors. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +/* Title: Destructors + * + * This file records a list of objects created by the user and/or Allegro + * itself, that need to be destroyed when Allegro is shut down. Strictly + * speaking, this list should not be necessary if the user is careful to + * destroy all the objects he creates. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/internal/aintern_tls.h" +#include "allegro5/internal/aintern_list.h" + +/* XXX The dependency on tls.c is not nice but the DllMain stuff for Windows + * does not it easy to make abstract away TLS API differences. + */ + +ALLEGRO_DEBUG_CHANNEL("dtor") + + +struct _AL_DTOR_LIST { + _AL_MUTEX mutex; + _AL_LIST* dtors; +}; + + +typedef struct DTOR { + char const *name; + void *object; + void (*func)(void*); +} DTOR; + + +/* Internal function: _al_init_destructors + * Initialise a list of destructors. + */ +_AL_DTOR_LIST *_al_init_destructors(void) +{ + _AL_DTOR_LIST *dtors = al_malloc(sizeof(*dtors)); + + _AL_MARK_MUTEX_UNINITED(dtors->mutex); + _al_mutex_init(&dtors->mutex); + dtors->dtors = _al_list_create(); + + return dtors; +} + + + +/* _al_push_destructor_owner: + * Increase the owner count for the current thread. When it is greater than + * zero, _al_register_destructor will do nothing. + * + * This is required if an object to-be-registered (B) should be "owned" by an + * object (A), which is responsible for destroying (B). (B) should not be + * destroyed independently of (A). + */ +void _al_push_destructor_owner(void) +{ + int *dtor_owner_count = _al_tls_get_dtor_owner_count(); + (*dtor_owner_count)++; +} + + + +/* _al_push_destructor_owner: + * Decrease the owner count for the current thread. + */ +void _al_pop_destructor_owner(void) +{ + int *dtor_owner_count = _al_tls_get_dtor_owner_count(); + (*dtor_owner_count)--; + ASSERT(*dtor_owner_count >= 0); +} + + + +/* _al_run_destructors: + * Run all the destructors on the list in reverse order. + */ +void _al_run_destructors(_AL_DTOR_LIST *dtors) +{ + if (!dtors) { + return; + } + + /* call the destructors in reverse order */ + _al_mutex_lock(&dtors->mutex); + { + _AL_LIST_ITEM *iter = _al_list_back(dtors->dtors); + while (iter) { + DTOR *dtor = _al_list_item_data(iter); + void *object = dtor->object; + void (*func)(void *) = dtor->func; + + ALLEGRO_DEBUG("calling dtor for %s %p, func %p\n", + dtor->name, object, func); + _al_mutex_unlock(&dtors->mutex); + { + (*func)(object); + } + _al_mutex_lock(&dtors->mutex); + /* Don't do normal iteration as the destructors will possibly run + * multiple destructors at once. */ + iter = _al_list_back(dtors->dtors); + } + } + _al_mutex_unlock(&dtors->mutex); +} + + + +/* _al_shutdown_destructors: + * Free the list of destructors. The list should be empty now. + */ +void _al_shutdown_destructors(_AL_DTOR_LIST *dtors) +{ + if (!dtors) { + return; + } + + /* free resources used by the destructor subsystem */ + ASSERT(_al_list_is_empty(dtors->dtors)); + _al_list_destroy(dtors->dtors); + + _al_mutex_destroy(&dtors->mutex); + + al_free(dtors); +} + + + +/* Internal function: _al_register_destructor + * Register OBJECT to be destroyed by FUNC during Allegro shutdown. + * This would be done in the object's constructor function. + * + * Returns a list item representing the destructor's position in the list + * (possibly null). + * + * [thread-safe] + */ +_AL_LIST_ITEM *_al_register_destructor(_AL_DTOR_LIST *dtors, char const *name, + void *object, void (*func)(void*)) +{ + int *dtor_owner_count; + _AL_LIST_ITEM *ret = NULL; + ASSERT(object); + ASSERT(func); + + dtor_owner_count = _al_tls_get_dtor_owner_count(); + if (*dtor_owner_count > 0) + return NULL; + + _al_mutex_lock(&dtors->mutex); + { +#ifdef DEBUGMODE + /* make sure the object is not registered twice */ + { + _AL_LIST_ITEM *iter = _al_list_front(dtors->dtors); + + while (iter) { + DTOR *dtor = _al_list_item_data(iter); + ASSERT(dtor->object != object); + iter = _al_list_next(dtors->dtors, iter); + } + } +#endif /* DEBUGMODE */ + + /* add the destructor to the list */ + { + DTOR *new_dtor = al_malloc(sizeof(DTOR)); + if (new_dtor) { + new_dtor->object = object; + new_dtor->func = func; + new_dtor->name = name; + ALLEGRO_DEBUG("added dtor for %s %p, func %p\n", name, + object, func); + ret = _al_list_push_back(dtors->dtors, new_dtor); + } + else { + ALLEGRO_WARN("failed to add dtor for %s %p\n", name, + object); + } + } + } + _al_mutex_unlock(&dtors->mutex); + return ret; +} + + + +/* Internal function: _al_unregister_destructor + * Unregister a previously registered object. This must be called + * in the normal object destroyer routine, e.g. al_destroy_timer. + * + * [thread-safe] + */ +void _al_unregister_destructor(_AL_DTOR_LIST *dtors, _AL_LIST_ITEM *dtor_item) +{ + if (!dtor_item) { + return; + } + + _al_mutex_lock(&dtors->mutex); + { + DTOR *dtor = _al_list_item_data(dtor_item); + ALLEGRO_DEBUG("removed dtor for %s %p\n", dtor->name, dtor->object); + al_free(dtor); + _al_list_erase(dtors->dtors, dtor_item); + } + _al_mutex_unlock(&dtors->mutex); +} + + + +/* Internal function: _al_foreach_destructor + * Call the callback for each registered object. + * [thread-safe] + */ +void _al_foreach_destructor(_AL_DTOR_LIST *dtors, + void (*callback)(void *object, void (*func)(void *), void *udata), + void *userdata) +{ + _al_mutex_lock(&dtors->mutex); + { + _AL_LIST_ITEM *iter = _al_list_front(dtors->dtors); + + while (iter) { + DTOR *dtor = _al_list_item_data(iter); + callback(dtor->object, dtor->func, userdata); + iter = _al_list_next(dtors->dtors, iter); + } + } + _al_mutex_unlock(&dtors->mutex); +} + + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/events.c b/allegro/src/events.c new file mode 100644 index 00000000..fc44171f --- /dev/null +++ b/allegro/src/events.c @@ -0,0 +1,737 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Event queues. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +/* Title: Event queues + * + * An event queue buffers events generated by event sources that were + * registered with the queue. + */ + + +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_system.h" + + + +struct ALLEGRO_EVENT_QUEUE +{ + _AL_VECTOR sources; /* vector of (ALLEGRO_EVENT_SOURCE *) */ + _AL_VECTOR events; /* vector of ALLEGRO_EVENT, used as circular array */ + unsigned int events_head; /* write end of circular array */ + unsigned int events_tail; /* read end of circular array */ + bool paused; + _AL_MUTEX mutex; + _AL_COND cond; + _AL_LIST_ITEM *dtor_item; +}; + + + +/* to prevent concurrent modification of user event reference counts */ +static _AL_MUTEX user_event_refcount_mutex = _AL_MUTEX_UNINITED; + + + +/* forward declarations */ +static void shutdown_events(void); +static bool do_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout); +static void copy_event(ALLEGRO_EVENT *dest, const ALLEGRO_EVENT *src); +static void ref_if_user_event(ALLEGRO_EVENT *event); +static void unref_if_user_event(ALLEGRO_EVENT *event); +static void discard_events_of_source(ALLEGRO_EVENT_QUEUE *queue, + const ALLEGRO_EVENT_SOURCE *source); + + + +/* _al_init_events: + * Initialise globals for the event system. + */ +void _al_init_events(void) +{ + _al_mutex_init(&user_event_refcount_mutex); + _al_add_exit_func(shutdown_events, "shutdown_events"); +} + + + +/* shutdown_events: + * Clean up after _al_init_events. + */ +static void shutdown_events(void) +{ + _al_mutex_destroy(&user_event_refcount_mutex); +} + + + +/* Function: al_create_event_queue + */ +ALLEGRO_EVENT_QUEUE *al_create_event_queue(void) +{ + ALLEGRO_EVENT_QUEUE *queue = al_malloc(sizeof *queue); + + ASSERT(queue); + + if (queue) { + _al_vector_init(&queue->sources, sizeof(ALLEGRO_EVENT_SOURCE *)); + + _al_vector_init(&queue->events, sizeof(ALLEGRO_EVENT)); + _al_vector_alloc_back(&queue->events); + queue->events_head = 0; + queue->events_tail = 0; + queue->paused = false; + + _AL_MARK_MUTEX_UNINITED(queue->mutex); + _al_mutex_init(&queue->mutex); + _al_cond_init(&queue->cond); + + queue->dtor_item = _al_register_destructor(_al_dtor_list, "queue", queue, + (void (*)(void *)) al_destroy_event_queue); + } + + return queue; +} + + + +/* Function: al_destroy_event_queue + */ +void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue) +{ + ASSERT(queue); + + _al_unregister_destructor(_al_dtor_list, queue->dtor_item); + + /* Unregister any event sources registered with this queue. */ + while (_al_vector_is_nonempty(&queue->sources)) { + ALLEGRO_EVENT_SOURCE **slot = _al_vector_ref_back(&queue->sources); + al_unregister_event_source(queue, *slot); + } + + ASSERT(_al_vector_is_empty(&queue->sources)); + _al_vector_free(&queue->sources); + + ASSERT(queue->events_head == queue->events_tail); + _al_vector_free(&queue->events); + + _al_cond_destroy(&queue->cond); + _al_mutex_destroy(&queue->mutex); + + al_free(queue); +} + + +/* Function: al_is_event_source_registered + */ +bool al_is_event_source_registered(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT_SOURCE *source) +{ + ASSERT(queue); + ASSERT(source); + + if(_al_vector_contains(&queue->sources, &source)) + return true; + else + return false; +} + +/* Function: al_register_event_source + */ +void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT_SOURCE *source) +{ + ALLEGRO_EVENT_SOURCE **slot; + ASSERT(queue); + ASSERT(source); + + if (!_al_vector_contains(&queue->sources, &source)) { + _al_event_source_on_registration_to_queue(source, queue); + _al_mutex_lock(&queue->mutex); + slot = _al_vector_alloc_back(&queue->sources); + *slot = source; + _al_mutex_unlock(&queue->mutex); + } +} + + + +/* Function: al_unregister_event_source + */ +void al_unregister_event_source(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT_SOURCE *source) +{ + bool found; + ASSERT(queue); + ASSERT(source); + + /* Remove source from our list. */ + _al_mutex_lock(&queue->mutex); + found = _al_vector_find_and_delete(&queue->sources, &source); + _al_mutex_unlock(&queue->mutex); + + if (found) { + /* Tell the event source that it was unregistered. */ + _al_event_source_on_unregistration_from_queue(source, queue); + + /* Drop all the events in the queue that belonged to the source. */ + _al_mutex_lock(&queue->mutex); + discard_events_of_source(queue, source); + _al_mutex_unlock(&queue->mutex); + } +} + + + +/* Function: al_pause_event_queue + */ +void al_pause_event_queue(ALLEGRO_EVENT_QUEUE *queue, bool pause) +{ + ASSERT(queue); + + _al_mutex_lock(&queue->mutex); + queue->paused = pause; + _al_mutex_unlock(&queue->mutex); +} + + + +/* Function: al_is_event_queue_paused + */ +bool al_is_event_queue_paused(const ALLEGRO_EVENT_QUEUE *queue) +{ + ASSERT(queue); + + return queue->paused; +} + + + +static void heartbeat(void) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + if (system->vt->heartbeat) + system->vt->heartbeat(); +} + + + +static bool is_event_queue_empty(ALLEGRO_EVENT_QUEUE *queue) +{ + return (queue->events_head == queue->events_tail); +} + + + +/* Function: al_is_event_queue_empty + */ +bool al_is_event_queue_empty(ALLEGRO_EVENT_QUEUE *queue) +{ + ASSERT(queue); + + heartbeat(); + + return is_event_queue_empty(queue); +} + + + +/* circ_array_next: + * Return the next index in a circular array. + */ +static unsigned int circ_array_next(const _AL_VECTOR *vector, unsigned int i) +{ + return (i + 1) % _al_vector_size(vector); +} + + + +/* get_next_event_if_any: [primary thread] + * Helper function. It returns a pointer to the next event in the + * queue, or NULL. Optionally the event is removed from the queue. + * However, the event is _not released_ (which is the caller's + * responsibility). The event queue must be locked before entering + * this function. + */ +static ALLEGRO_EVENT *get_next_event_if_any(ALLEGRO_EVENT_QUEUE *queue, + bool delete) +{ + ALLEGRO_EVENT *event; + + if (is_event_queue_empty(queue)) { + return NULL; + } + + event = _al_vector_ref(&queue->events, queue->events_tail); + if (delete) { + queue->events_tail = circ_array_next(&queue->events, queue->events_tail); + } + return event; +} + + + +/* Function: al_get_next_event + */ +bool al_get_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) +{ + ALLEGRO_EVENT *next_event; + ASSERT(queue); + ASSERT(ret_event); + + heartbeat(); + + _al_mutex_lock(&queue->mutex); + + next_event = get_next_event_if_any(queue, true); + if (next_event) { + copy_event(ret_event, next_event); + /* Don't increment reference count on user events. */ + } + + _al_mutex_unlock(&queue->mutex); + + return (next_event ? true : false); +} + + + +/* Function: al_peek_next_event + */ +bool al_peek_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) +{ + ALLEGRO_EVENT *next_event; + ASSERT(queue); + ASSERT(ret_event); + + heartbeat(); + + _al_mutex_lock(&queue->mutex); + + next_event = get_next_event_if_any(queue, false); + if (next_event) { + copy_event(ret_event, next_event); + ref_if_user_event(ret_event); + } + + _al_mutex_unlock(&queue->mutex); + + return (next_event ? true : false); +} + + + +/* Function: al_drop_next_event + */ +bool al_drop_next_event(ALLEGRO_EVENT_QUEUE *queue) +{ + ALLEGRO_EVENT *next_event; + ASSERT(queue); + + heartbeat(); + + _al_mutex_lock(&queue->mutex); + + next_event = get_next_event_if_any(queue, true); + if (next_event) { + unref_if_user_event(next_event); + } + + _al_mutex_unlock(&queue->mutex); + + return (next_event ? true : false); +} + + + +/* Function: al_flush_event_queue + */ +void al_flush_event_queue(ALLEGRO_EVENT_QUEUE *queue) +{ + unsigned int i; + ASSERT(queue); + + heartbeat(); + + _al_mutex_lock(&queue->mutex); + + /* Decrement reference counts on all user events. */ + i = queue->events_tail; + while (i != queue->events_head) { + ALLEGRO_EVENT *old_ev = _al_vector_ref(&queue->events, i); + unref_if_user_event(old_ev); + i = circ_array_next(&queue->events, i); + } + + queue->events_head = queue->events_tail = 0; + _al_mutex_unlock(&queue->mutex); +} + + + +/* [primary thread] */ +/* Function: al_wait_for_event + */ +void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event) +{ + ALLEGRO_EVENT *next_event = NULL; + + ASSERT(queue); + + heartbeat(); + + _al_mutex_lock(&queue->mutex); + { + while (is_event_queue_empty(queue)) { + #ifdef ALLEGRO_WAIT_EVENT_SLEEP + al_rest(0.001); + heartbeat(); + #else + _al_cond_wait(&queue->cond, &queue->mutex); + #endif + } + + if (ret_event) { + next_event = get_next_event_if_any(queue, true); + copy_event(ret_event, next_event); + } + } + _al_mutex_unlock(&queue->mutex); +} + + + +/* [primary thread] */ +/* Function: al_wait_for_event_timed + */ +bool al_wait_for_event_timed(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT *ret_event, float secs) +{ + ALLEGRO_TIMEOUT timeout; + + ASSERT(queue); + ASSERT(secs >= 0); + + heartbeat(); + + if (secs < 0.0) + al_init_timeout(&timeout, 0); + else + al_init_timeout(&timeout, secs); + + return do_wait_for_event(queue, ret_event, &timeout); +} + + + +/* Function: al_wait_for_event_until + */ +bool al_wait_for_event_until(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout) +{ + ASSERT(queue); + + heartbeat(); + + return do_wait_for_event(queue, ret_event, timeout); +} + + + +static bool do_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, + ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout) +{ + bool timed_out = false; + ALLEGRO_EVENT *next_event = NULL; + + _al_mutex_lock(&queue->mutex); + { + int result = 0; + + /* Is the queue is non-empty? If not, block on a condition + * variable, which will be signaled when an event is placed into + * the queue. + */ + while (is_event_queue_empty(queue) && (result != -1)) { + result = _al_cond_timedwait(&queue->cond, &queue->mutex, timeout); + } + + if (result == -1) + timed_out = true; + else if (ret_event) { + next_event = get_next_event_if_any(queue, true); + copy_event(ret_event, next_event); + } + } + _al_mutex_unlock(&queue->mutex); + + if (timed_out) + return false; + + return true; +} + + + +/* expand_events_array: + * Expand the circular array holding events. + */ +static void expand_events_array(ALLEGRO_EVENT_QUEUE *queue) +{ + /* The underlying vector grows by powers of two. */ + const size_t old_size = _al_vector_size(&queue->events); + const size_t new_size = old_size * 2; + unsigned int i; + + for (i = old_size; i < new_size; i++) { + _al_vector_alloc_back(&queue->events); + } + + /* Move wrapped-around elements at the start of the array to the back. */ + if (queue->events_head < queue->events_tail) { + for (i = 0; i < queue->events_head; i++) { + ALLEGRO_EVENT *old_ev = _al_vector_ref(&queue->events, i); + ALLEGRO_EVENT *new_ev = _al_vector_ref(&queue->events, old_size + i); + copy_event(new_ev, old_ev); + } + queue->events_head += old_size; + } +} + + +/* alloc_event: + * + * The event source must be _locked_ before calling this function. + * + * [runs in background threads] + */ +static ALLEGRO_EVENT *alloc_event(ALLEGRO_EVENT_QUEUE *queue) +{ + ALLEGRO_EVENT *event; + unsigned int adv_head; + + adv_head = circ_array_next(&queue->events, queue->events_head); + if (adv_head == queue->events_tail) { + expand_events_array(queue); + adv_head = circ_array_next(&queue->events, queue->events_head); + } + + event = _al_vector_ref(&queue->events, queue->events_head); + queue->events_head = adv_head; + return event; +} + + + +/* copy_event: + * Copies the contents of the event SRC to DEST. + */ +static void copy_event(ALLEGRO_EVENT *dest, const ALLEGRO_EVENT *src) +{ + ASSERT(dest); + ASSERT(src); + + *dest = *src; +} + + + +/* Increment a user event's reference count, if the event passed is a user + * event and requires it. + */ +static void ref_if_user_event(ALLEGRO_EVENT *event) +{ + if (ALLEGRO_EVENT_TYPE_IS_USER(event->type)) { + ALLEGRO_USER_EVENT_DESCRIPTOR *descr = event->user.__internal__descr; + if (descr) { + _al_mutex_lock(&user_event_refcount_mutex); + descr->refcount++; + _al_mutex_unlock(&user_event_refcount_mutex); + } + } +} + + + +/* Decrement a user event's reference count, if the event passed is a user + * event and requires it. + */ +static void unref_if_user_event(ALLEGRO_EVENT *event) +{ + if (ALLEGRO_EVENT_TYPE_IS_USER(event->type)) { + al_unref_user_event(&event->user); + } +} + + + +/* Internal function: _al_event_queue_push_event + * Event sources call this function when they have something to add to + * the queue. If a queue cannot accept the event, the event's + * refcount will not be incremented. + * + * If no event queues can accept the event, the event should be + * returned to the event source's list of recyclable events. + */ +void _al_event_queue_push_event(ALLEGRO_EVENT_QUEUE *queue, + const ALLEGRO_EVENT *orig_event) +{ + ALLEGRO_EVENT *new_event; + ASSERT(queue); + ASSERT(orig_event); + + if (queue->paused) + return; + + _al_mutex_lock(&queue->mutex); + { + new_event = alloc_event(queue); + copy_event(new_event, orig_event); + ref_if_user_event(new_event); + + /* Wake up threads that are waiting for an event to be placed in + * the queue. + */ + _al_cond_broadcast(&queue->cond); + } + _al_mutex_unlock(&queue->mutex); +} + + + +/* contains_event_of_source: + * Return true iff the event queue contains an event from the given source. + * The queue must be locked. + */ +static bool contains_event_of_source(const ALLEGRO_EVENT_QUEUE *queue, + const ALLEGRO_EVENT_SOURCE *source) +{ + ALLEGRO_EVENT *event; + unsigned int i; + + i = queue->events_tail; + while (i != queue->events_head) { + event = _al_vector_ref(&queue->events, i); + if (event->any.source == source) { + return true; + } + i = circ_array_next(&queue->events, i); + } + + return false; +} + + + +/* Helper to get smallest fitting power of two. */ +static int pot(int x) +{ + int y = 1; + while (y < x) y *= 2; + return y; +} + + + +/* discard_events_of_source: + * Discard all the events in the queue that belong to the source. + * The queue must be locked. + */ +static void discard_events_of_source(ALLEGRO_EVENT_QUEUE *queue, + const ALLEGRO_EVENT_SOURCE *source) +{ + _AL_VECTOR old_events; + ALLEGRO_EVENT *old_event; + ALLEGRO_EVENT *new_event; + size_t old_size; + size_t new_size; + unsigned int i; + + if (!contains_event_of_source(queue, source)) { + return; + } + + /* Copy elements we want to keep from the old vector to a new one. */ + old_events = queue->events; + _al_vector_init(&queue->events, sizeof(ALLEGRO_EVENT)); + + i = queue->events_tail; + while (i != queue->events_head) { + old_event = _al_vector_ref(&old_events, i); + if (old_event->any.source != source) { + new_event = _al_vector_alloc_back(&queue->events); + copy_event(new_event, old_event); + } + else { + unref_if_user_event(old_event); + } + i = circ_array_next(&old_events, i); + } + + queue->events_tail = 0; + queue->events_head = _al_vector_size(&queue->events); + + /* The circular array always needs at least one unused element. */ + old_size = _al_vector_size(&queue->events); + new_size = pot(old_size + 1); + for (i = old_size; i < new_size; i++) { + _al_vector_alloc_back(&queue->events); + } + + _al_vector_free(&old_events); +} + + + +/* Function: al_unref_user_event + */ +void al_unref_user_event(ALLEGRO_USER_EVENT *event) +{ + ALLEGRO_USER_EVENT_DESCRIPTOR *descr; + int refcount; + + ASSERT(event); + + descr = event->__internal__descr; + if (descr) { + _al_mutex_lock(&user_event_refcount_mutex); + ASSERT(descr->refcount > 0); + refcount = --descr->refcount; + _al_mutex_unlock(&user_event_refcount_mutex); + + if (refcount == 0) { + (descr->dtor)(event); + al_free(descr); + } + } +} + + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/evtsrc.c b/allegro/src/evtsrc.c new file mode 100644 index 00000000..2275fad9 --- /dev/null +++ b/allegro/src/evtsrc.c @@ -0,0 +1,288 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Event sources. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +/* Title: Event sources + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_system.h" + + +ALLEGRO_STATIC_ASSERT(evtsrc, + sizeof(ALLEGRO_EVENT_SOURCE_REAL) <= sizeof(ALLEGRO_EVENT_SOURCE)); + + + +/* Internal function: _al_event_source_init + * Initialise an event source structure. + */ +void _al_event_source_init(ALLEGRO_EVENT_SOURCE *es) +{ + ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; + + memset(es, 0, sizeof(*es)); + _AL_MARK_MUTEX_UNINITED(this->mutex); + _al_mutex_init(&this->mutex); + _al_vector_init(&this->queues, sizeof(ALLEGRO_EVENT_QUEUE *)); + this->data = 0; +} + + + +/* Internal function: _al_event_source_free + * Free the resources using by an event source structure. It + * automatically unregisters the event source from all the event + * queues it is currently registered with. + */ +void _al_event_source_free(ALLEGRO_EVENT_SOURCE *es) +{ + ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; + + /* Unregister from all queues. */ + while (!_al_vector_is_empty(&this->queues)) { + ALLEGRO_EVENT_QUEUE **slot = _al_vector_ref_back(&this->queues); + al_unregister_event_source(*slot, es); + } + + _al_vector_free(&this->queues); + + _al_mutex_destroy(&this->mutex); +} + + + +/* Internal function: _al_event_source_lock + * Lock the event source. See below for when you should call this function. + */ +void _al_event_source_lock(ALLEGRO_EVENT_SOURCE *es) +{ + ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; + + _al_mutex_lock(&this->mutex); +} + + + +/* Internal function: _al_event_source_unlock + * Unlock the event source. + */ +void _al_event_source_unlock(ALLEGRO_EVENT_SOURCE *es) +{ + ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; + + _al_mutex_unlock(&this->mutex); +} + + + +/* Internal function: _al_event_source_on_registration_to_queue + * This function is called by al_register_event_source() when an + * event source is registered to an event queue. This gives the + * event source a chance to remember which queues it is registered + * to. + */ +void _al_event_source_on_registration_to_queue(ALLEGRO_EVENT_SOURCE *es, + ALLEGRO_EVENT_QUEUE *queue) +{ + _al_event_source_lock(es); + { + ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; + + /* Add the queue to the source's list. */ + ALLEGRO_EVENT_QUEUE **slot = _al_vector_alloc_back(&this->queues); + *slot = queue; + } + _al_event_source_unlock(es); +} + + + +/* Internal function: _al_event_source_on_unregistration_from_queue + * This function is called by al_unregister_event_source() when an + * event source is unregistered from a queue. + */ +void _al_event_source_on_unregistration_from_queue(ALLEGRO_EVENT_SOURCE *es, + ALLEGRO_EVENT_QUEUE *queue) +{ + _al_event_source_lock(es); + { + ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; + + _al_vector_find_and_delete(&this->queues, &queue); + } + _al_event_source_unlock(es); +} + + + +/* Internal function: _al_event_source_needs_to_generate_event + * This function is called by modules that implement event sources + * when some interesting thing happens. They call this to check if + * they should bother generating an event of the given type, i.e. if + * the given event source is actually registered with one or more + * event queues. This is an optimisation to avoid allocating and + * filling in unwanted event structures. + * + * The event source must be _locked_ before calling this function. + * + * [runs in background threads] + */ +bool _al_event_source_needs_to_generate_event(ALLEGRO_EVENT_SOURCE *es) +{ + ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; + + /* We don't consider pausing of event queues, but it does not seem worth + * optimising for. + */ + return !_al_vector_is_empty(&this->queues); +} + + + +/* Internal function: _al_event_source_emit_event + * After an event structure has been filled in, it is time for the + * event source to tell the event queues it knows of about the new + * event. Afterwards, the caller of this function should not touch + * the event any more. + * + * The event source must be _locked_ before calling this function. + * + * [runs in background threads] + */ +void _al_event_source_emit_event(ALLEGRO_EVENT_SOURCE *es, ALLEGRO_EVENT *event) +{ + ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; + + event->any.source = es; + + /* Push the event to all the queues that this event source is + * registered to. + */ + { + size_t num_queues = _al_vector_size(&this->queues); + unsigned int i; + ALLEGRO_EVENT_QUEUE **slot; + + for (i = 0; i < num_queues; i++) { + slot = _al_vector_ref(&this->queues, i); + _al_event_queue_push_event(*slot, event); + } + } +} + + + +/* Function: al_init_user_event_source + */ +void al_init_user_event_source(ALLEGRO_EVENT_SOURCE *src) +{ + ASSERT(src); + + _al_event_source_init(src); +} + + + +/* Function: al_destroy_user_event_source + */ +void al_destroy_user_event_source(ALLEGRO_EVENT_SOURCE *src) +{ + if (src) { + _al_event_source_free(src); + } +} + + + +/* Function: al_emit_user_event + */ +bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src, + ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *)) +{ + size_t num_queues; + bool rc; + + ASSERT(src); + ASSERT(event); + + if (dtor) { + ALLEGRO_USER_EVENT_DESCRIPTOR *descr = al_malloc(sizeof(*descr)); + descr->refcount = 0; + descr->dtor = dtor; + event->user.__internal__descr = descr; + } + else { + event->user.__internal__descr = NULL; + } + + _al_event_source_lock(src); + { + ALLEGRO_EVENT_SOURCE_REAL *rsrc = (ALLEGRO_EVENT_SOURCE_REAL *)src; + + num_queues = _al_vector_size(&rsrc->queues); + if (num_queues > 0) { + event->any.timestamp = al_get_time(); + _al_event_source_emit_event(src, event); + rc = true; + } + else { + rc = false; + } + } + _al_event_source_unlock(src); + + if (dtor && !rc) { + dtor(&event->user); + al_free(event->user.__internal__descr); + } + + return rc; +} + + + +/* Function: al_set_event_source_data + */ +void al_set_event_source_data(ALLEGRO_EVENT_SOURCE *source, intptr_t data) +{ + ALLEGRO_EVENT_SOURCE_REAL *const rsource = (ALLEGRO_EVENT_SOURCE_REAL *)source; + rsource->data = data; +} + + + +/* Function: al_get_event_source_data + */ +intptr_t al_get_event_source_data(const ALLEGRO_EVENT_SOURCE *source) +{ + const ALLEGRO_EVENT_SOURCE_REAL *const rsource = (ALLEGRO_EVENT_SOURCE_REAL *)source; + return rsource->data; +} + + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/exitfunc.c b/allegro/src/exitfunc.c new file mode 100644 index 00000000..98fa99e6 --- /dev/null +++ b/allegro/src/exitfunc.c @@ -0,0 +1,97 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * List of functions to call at program cleanup. + * + * By Shawn Hargreaves. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_exitfunc.h" + + +/* dynamic registration system for cleanup code */ +struct al_exit_func { + void (*funcptr)(void); + const char *desc; + struct al_exit_func *next; +}; + +static struct al_exit_func *exit_func_list = NULL; + + + +/* _al_add_exit_func: + * Adds a function to the list that need to be called on Allegro shutdown. + * `desc' should point to a statically allocated string to help with + * debugging. + */ +void _al_add_exit_func(void (*func)(void), const char *desc) +{ + struct al_exit_func *n; + + for (n = exit_func_list; n; n = n->next) + if (n->funcptr == func) + return; + + n = al_malloc(sizeof(struct al_exit_func)); + if (!n) + return; + + n->next = exit_func_list; + n->funcptr = func; + n->desc = desc; + exit_func_list = n; +} + + + +/* _al_remove_exit_func: + * Removes a function from the list that need to be called on Allegro + * shutdown. + */ +void _al_remove_exit_func(void (*func)(void)) +{ + struct al_exit_func *iter = exit_func_list, *prev = NULL; + + while (iter) { + if (iter->funcptr == func) { + if (prev) + prev->next = iter->next; + else + exit_func_list = iter->next; + al_free(iter); + return; + } + prev = iter; + iter = iter->next; + } +} + + + +/* _al_run_exit_funcs: + * Run all the functions registered with _al_add_exit_func, in reverse order of + * registration. + */ +void _al_run_exit_funcs(void) +{ + while (exit_func_list) { + void (*func)(void) = exit_func_list->funcptr; + _al_remove_exit_func(func); + (*func)(); + } +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/file.c b/allegro/src/file.c new file mode 100644 index 00000000..0bd33535 --- /dev/null +++ b/allegro/src/file.c @@ -0,0 +1,591 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * File I/O routines. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_file.h" + + +/* Function: al_fopen + */ +ALLEGRO_FILE *al_fopen(const char *path, const char *mode) +{ + return al_fopen_interface(al_get_new_file_interface(), path, mode); +} + + +/* Function: al_fopen_interface + */ +ALLEGRO_FILE *al_fopen_interface(const ALLEGRO_FILE_INTERFACE *drv, + const char *path, const char *mode) +{ + ALLEGRO_FILE *f = NULL; + + ASSERT(drv); + ASSERT(path); + ASSERT(mode); + + if (drv->fi_fopen) { + f = al_malloc(sizeof(*f)); + if (!f) { + al_set_errno(ENOMEM); + } + else { + f->vtable = drv; + f->userdata = drv->fi_fopen(path, mode); + f->ungetc_len = 0; + if (!f->userdata) { + al_free(f); + f = NULL; + } + } + } + + return f; +} + + +/* Function: al_create_file_handle + */ +ALLEGRO_FILE *al_create_file_handle(const ALLEGRO_FILE_INTERFACE *drv, + void *userdata) +{ + ALLEGRO_FILE *f; + + ASSERT(drv); + + f = al_malloc(sizeof(*f)); + if (!f) { + al_set_errno(ENOMEM); + } + else { + f->vtable = drv; + f->userdata = userdata; + f->ungetc_len = 0; + } + + return f; +} + + +/* Function: al_fclose + */ +bool al_fclose(ALLEGRO_FILE *f) +{ + if (f) { + bool ret = f->vtable->fi_fclose(f); + al_free(f); + return ret; + } + + al_set_errno(EINVAL); + return false; +} + + +/* Function: al_fread + */ +size_t al_fread(ALLEGRO_FILE *f, void *ptr, size_t size) +{ + ASSERT(f); + ASSERT(ptr || size == 0); + + if (f->ungetc_len) { + int bytes_ungetc = 0; + unsigned char *cptr = ptr; + + while (f->ungetc_len > 0 && size > 0) { + *cptr++ = f->ungetc[--f->ungetc_len]; + ++bytes_ungetc; + --size; + } + + return bytes_ungetc + f->vtable->fi_fread(f, cptr, size); + } + else { + return f->vtable->fi_fread(f, ptr, size); + } +} + + +/* Function: al_fwrite + */ +size_t al_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) +{ + ASSERT(f); + ASSERT(ptr || size == 0); + + f->ungetc_len = 0; + return f->vtable->fi_fwrite(f, ptr, size); +} + + +/* Function: al_fflush + */ +bool al_fflush(ALLEGRO_FILE *f) +{ + ASSERT(f); + + return f->vtable->fi_fflush(f); +} + + +/* Function: al_ftell + */ +int64_t al_ftell(ALLEGRO_FILE *f) +{ + ASSERT(f); + + return f->vtable->fi_ftell(f) - f->ungetc_len; +} + + +/* Function: al_fseek + */ +bool al_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) +{ + ASSERT(f); + /* offset can be negative */ + ASSERT( + whence == ALLEGRO_SEEK_SET || + whence == ALLEGRO_SEEK_CUR || + whence == ALLEGRO_SEEK_END + ); + + if (f->ungetc_len) { + if (whence == ALLEGRO_SEEK_CUR) { + offset -= f->ungetc_len; + } + f->ungetc_len = 0; + } + + return f->vtable->fi_fseek(f, offset, whence); +} + + +/* Function: al_feof + */ +bool al_feof(ALLEGRO_FILE *f) +{ + ASSERT(f); + + return f->ungetc_len == 0 && f->vtable->fi_feof(f); +} + + +/* Function: al_ferror + */ +int al_ferror(ALLEGRO_FILE *f) +{ + ASSERT(f); + + return f->vtable->fi_ferror(f); +} + + +/* Function: al_ferrmsg + */ +const char *al_ferrmsg(ALLEGRO_FILE *f) +{ + const char *msg; + + ASSERT(f); + msg = f->vtable->fi_ferrmsg(f); + ASSERT(msg); + return msg; +} + + +/* Function: al_fclearerr + */ +void al_fclearerr(ALLEGRO_FILE *f) +{ + ASSERT(f); + + f->vtable->fi_fclearerr(f); +} + + +/* Function: al_fgetc + */ +int al_fgetc(ALLEGRO_FILE *f) +{ + uint8_t c; + ASSERT(f); + + if (al_fread(f, &c, 1) != 1) { + return EOF; + } + + return c; +} + + +/* Function: al_fputc + */ +int al_fputc(ALLEGRO_FILE *f, int c) +{ + uint8_t b = (c & 0xff); + ASSERT(f); + + if (al_fwrite(f, &b, 1) != 1) { + return EOF; + } + + return b; +} + + +/* Function: al_fread16le + */ +int16_t al_fread16le(ALLEGRO_FILE *f) +{ + unsigned char b[2]; + ASSERT(f); + + if (al_fread(f, b, 2) == 2) { + return (((int16_t)b[1] << 8) | (int16_t)b[0]); + } + + return EOF; +} + + +/* Function: al_fread32le + */ +int32_t al_fread32le(ALLEGRO_FILE *f) +{ + unsigned char b[4]; + ASSERT(f); + + if (al_fread(f, b, 4) == 4) { + return (((int32_t)b[3] << 24) | ((int32_t)b[2] << 16) | + ((int32_t)b[1] << 8) | (int32_t)b[0]); + } + + return EOF; +} + + +/* Function: al_fwrite16le + */ +size_t al_fwrite16le(ALLEGRO_FILE *f, int16_t w) +{ + uint8_t b1, b2; + ASSERT(f); + + b1 = (w & 0xFF00) >> 8; + b2 = w & 0x00FF; + + if (al_fputc(f, b2) == b2) { + if (al_fputc(f, b1) == b1) { + return 2; + } + return 1; + } + return 0; +} + + +/* Function: al_fwrite32le + */ +size_t al_fwrite32le(ALLEGRO_FILE *f, int32_t l) +{ + uint8_t b1, b2, b3, b4; + ASSERT(f); + + b1 = ((l & 0xFF000000L) >> 24); + b2 = ((l & 0x00FF0000L) >> 16); + b3 = ((l & 0x0000FF00L) >> 8); + b4 = l & 0x00FF; + + if (al_fputc(f, b4) == b4) { + if (al_fputc(f, b3) == b3) { + if (al_fputc(f, b2) == b2) { + if (al_fputc(f, b1) == b1) { + return 4; + } + return 3; + } + return 2; + } + return 1; + } + return 0; +} + + +/* Function: al_fread16be + */ +int16_t al_fread16be(ALLEGRO_FILE *f) +{ + unsigned char b[2]; + ASSERT(f); + + if (al_fread(f, b, 2) == 2) { + return (((int16_t)b[0] << 8) | (int16_t)b[1]); + } + + return EOF; +} + + +/* Function: al_fread32be + */ +int32_t al_fread32be(ALLEGRO_FILE *f) +{ + unsigned char b[4]; + ASSERT(f); + + if (al_fread(f, b, 4) == 4) { + return (((int32_t)b[0] << 24) | ((int32_t)b[1] << 16) | + ((int32_t)b[2] << 8) | (int32_t)b[3]); + } + + return EOF; +} + + +/* Function: al_fwrite16be + */ +size_t al_fwrite16be(ALLEGRO_FILE *f, int16_t w) +{ + uint8_t b1, b2; + ASSERT(f); + + b1 = (w & 0xFF00) >> 8; + b2 = w & 0x00FF; + + if (al_fputc(f, b1) == b1) { + if (al_fputc(f, b2) == b2) { + return 2; + } + return 1; + } + return 0; +} + + +/* Function: al_fwrite32be + */ +size_t al_fwrite32be(ALLEGRO_FILE *f, int32_t l) +{ + uint8_t b1, b2, b3, b4; + ASSERT(f); + + b1 = ((l & 0xFF000000L) >> 24); + b2 = ((l & 0x00FF0000L) >> 16); + b3 = ((l & 0x0000FF00L) >> 8); + b4 = l & 0x00FF; + + if (al_fputc(f, b1) == b1) { + if (al_fputc(f, b2) == b2) { + if (al_fputc(f, b3) == b3) { + if (al_fputc(f, b4) == b4) { + return 4; + } + return 3; + } + return 2; + } + return 1; + } + return 0; +} + + +/* Function: al_fgets + */ +char *al_fgets(ALLEGRO_FILE *f, char * const buf, size_t max) +{ + char *p = buf; + int c; + ASSERT(f); + ASSERT(buf); + + /* Handle silly cases. */ + if (max == 0) { + return NULL; + } + if (max == 1) { + *buf = '\0'; + return buf; + } + + /* Return NULL if already at end of file. */ + if ((c = al_fgetc(f)) == EOF) { + return NULL; + } + + /* Fill buffer until empty, or we reach a newline or EOF or error. */ + do { + *p++ = c; + max--; + if (max == 1 || c == '\n') + break; + c = al_fgetc(f); + } while (c != EOF); + + /* Return NULL on error. */ + if (c == EOF && al_ferror(f)) { + return NULL; + } + + /* Add null terminator. */ + ASSERT(max >= 1); + *p = '\0'; + + return buf; +} + + +/* Function: al_fget_ustr + */ +ALLEGRO_USTR *al_fget_ustr(ALLEGRO_FILE *f) +{ + ALLEGRO_USTR *us; + char buf[128]; + + if (!al_fgets(f, buf, sizeof(buf))) { + return NULL; + } + + us = al_ustr_new(""); + + do { + al_ustr_append_cstr(us, buf); + if (al_ustr_has_suffix_cstr(us, "\n")) + break; + } while (al_fgets(f, buf, sizeof(buf))); + + return us; +} + + +/* Function: al_fputs + */ +int al_fputs(ALLEGRO_FILE *f, char const *p) +{ + size_t n; + ASSERT(f); + ASSERT(p); + + n = strlen(p); + if (al_fwrite(f, p, n) != n) { + return EOF; + } + + return n; +} + + +/* Function: al_fungetc + */ +int al_fungetc(ALLEGRO_FILE *f, int c) +{ + ASSERT(f != NULL); + + if (f->vtable->fi_fungetc) { + return f->vtable->fi_fungetc(f, c); + } + else { + /* If the interface does not provide an implementation for ungetc, + * then a default one will be used. (Note that if the interface does + * implement it, then this ungetc buffer will never be filled, and all + * other references to it within this file will always be ignored.) + */ + if (f->ungetc_len == ALLEGRO_UNGETC_SIZE) { + return EOF; + } + + f->ungetc[f->ungetc_len++] = (unsigned char) c; + + return c; + } +} + + +/* Function: al_fsize + */ +int64_t al_fsize(ALLEGRO_FILE *f) +{ + ASSERT(f != NULL); + + return f->vtable->fi_fsize(f); +} + + +/* Function: al_get_file_userdata + */ +void *al_get_file_userdata(ALLEGRO_FILE *f) +{ + ASSERT(f != NULL); + + return f->userdata; +} + + +/* Function: al_vfprintf + */ +int al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args) +{ + int rv = -1; + ALLEGRO_USTR *ustr = 0; + size_t size = 0; + bool success; + + if (pfile != 0 && format != 0) + { + ustr = al_ustr_new(""); + if (ustr) + { + success = al_ustr_vappendf(ustr, format, args); + if (success) + { + size = al_ustr_size(ustr); + if (size > 0) + { + rv = al_fwrite(pfile, (const void*)(al_cstr(ustr)), size); + if (rv != (int)size) { + rv = -1; + } + } + } + al_ustr_free(ustr); + } + } + return rv; +} + + +/* Function: al_fprintf + */ +int al_fprintf(ALLEGRO_FILE *pfile, const char *format, ...) +{ + int rv = -1; + va_list args; + + if (pfile != 0 && format != 0) + { + va_start(args, format); + rv = al_vfprintf(pfile, format, args); + va_end(args); + } + return rv; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/file_slice.c b/allegro/src/file_slice.c new file mode 100644 index 00000000..6d866a01 --- /dev/null +++ b/allegro/src/file_slice.c @@ -0,0 +1,231 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * File Slices - treat a subset of a random access file + * as its own file + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" + +typedef struct SLICE_DATA SLICE_DATA; + +enum { + SLICE_READ = 1, + SLICE_WRITE = 2, + SLICE_EXPANDABLE = 4 +}; + +struct SLICE_DATA +{ + ALLEGRO_FILE *fp; /* parent file handle */ + size_t anchor; /* beginning position relative to parent */ + size_t pos; /* position relative to anchor */ + size_t size; /* size of slice relative to anchor */ + int mode; +}; + +static bool slice_fclose(ALLEGRO_FILE *f) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + bool ret; + + /* seek to end of slice */ + ret = al_fseek(slice->fp, slice->anchor + slice->size, ALLEGRO_SEEK_SET); + + al_free(slice); + + return ret; +} + +static size_t slice_fread(ALLEGRO_FILE *f, void *ptr, size_t size) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + + if (!(slice->mode & SLICE_READ)) { + /* no read permissions */ + return 0; + } + + if (!(slice->mode & SLICE_EXPANDABLE) && slice->pos + size > slice->size) { + /* don't read past the buffer size if not expandable */ + size = slice->size - slice->pos; + } + + if (!size) { + return 0; + } + else { + /* unbuffered, read directly from parent file */ + size_t b = al_fread(slice->fp, ptr, size); + slice->pos += b; + + if (slice->pos > slice->size) + slice->size = slice->pos; + + return b; + } +} + +static size_t slice_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + + if (!(slice->mode & SLICE_WRITE)) { + /* no write permissions */ + return 0; + } + + if (!(slice->mode & SLICE_EXPANDABLE) && slice->pos + size > slice->size) { + /* don't write past the buffer size if not expandable */ + size = slice->size - slice->pos; + } + + if (!size) { + return 0; + } + else { + /* unbuffered, write directly to parent file */ + size_t b = al_fwrite(slice->fp, ptr, size); + slice->pos += b; + + if (slice->pos > slice->size) + slice->size = slice->pos; + + return b; + } +} + +static bool slice_fflush(ALLEGRO_FILE *f) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + + return al_fflush(slice->fp); +} + +static int64_t slice_ftell(ALLEGRO_FILE *f) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + return slice->pos; +} + +static bool slice_fseek(ALLEGRO_FILE *f, int64_t offset, int whence) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + + if (whence == ALLEGRO_SEEK_SET) { + offset = slice->anchor + offset; + } + else if (whence == ALLEGRO_SEEK_CUR) { + offset = slice->anchor + slice->pos + offset; + } + else if (whence == ALLEGRO_SEEK_END) { + offset = slice->anchor + slice->size + offset; + } + else { + return false; + } + + if ((size_t) offset < slice->anchor) { + offset = slice->anchor; + } + else if ((size_t) offset > slice->anchor + slice->size) { + if (!(slice->mode & SLICE_EXPANDABLE)) { + offset = slice->anchor + slice->size; + } + } + + if (al_fseek(slice->fp, offset, ALLEGRO_SEEK_SET)) { + slice->pos = offset - slice->anchor; + if (slice->pos > slice->size) + slice->size = slice->pos; + return true; + } + + return false; +} + +static bool slice_feof(ALLEGRO_FILE *f) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + return slice->pos >= slice->size; +} + +static int slice_ferror(ALLEGRO_FILE *f) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + return al_ferror(slice->fp); +} + +static const char *slice_ferrmsg(ALLEGRO_FILE *f) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + return al_ferrmsg(slice->fp); +} + +static void slice_fclearerr(ALLEGRO_FILE *f) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + al_fclearerr(slice->fp); +} + +static off_t slice_fsize(ALLEGRO_FILE *f) +{ + SLICE_DATA *slice = al_get_file_userdata(f); + return slice->size; +} + +static const ALLEGRO_FILE_INTERFACE fi = +{ + NULL, + slice_fclose, + slice_fread, + slice_fwrite, + slice_fflush, + slice_ftell, + slice_fseek, + slice_feof, + slice_ferror, + slice_ferrmsg, + slice_fclearerr, + NULL, + slice_fsize +}; + +/* Function: al_fopen_slice + */ +ALLEGRO_FILE *al_fopen_slice(ALLEGRO_FILE *fp, size_t initial_size, const char *mode) +{ + SLICE_DATA *userdata = al_calloc(1, sizeof(*userdata)); + + if (!userdata) { + return NULL; + } + + if (strstr(mode, "r") || strstr(mode, "R")) { + userdata->mode |= SLICE_READ; + } + + if (strstr(mode, "w") || strstr(mode, "W")) { + userdata->mode |= SLICE_WRITE; + } + + if (strstr(mode, "e") || strstr(mode, "E")) { + userdata->mode |= SLICE_EXPANDABLE; + } + + userdata->fp = fp; + userdata->anchor = al_ftell(fp); + userdata->size = initial_size; + + return al_create_file_handle(&fi, userdata); +} + diff --git a/allegro/src/file_stdio.c b/allegro/src/file_stdio.c new file mode 100644 index 00000000..79765747 --- /dev/null +++ b/allegro/src/file_stdio.c @@ -0,0 +1,488 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * File I/O. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" + +/* enable large file support in gcc/glibc */ +#if defined ALLEGRO_HAVE_FTELLO && defined ALLEGRO_HAVE_FSEEKO +#ifndef _LARGEFILE_SOURCE + #define _LARGEFILE_SOURCE +#endif +#ifndef _LARGEFILE_SOURCE64 + #define _LARGEFILE_SOURCE64 +#endif +#ifndef _FILE_OFFSET_BITS + #define _FILE_OFFSET_BITS 64 +#endif +#endif + +#include + +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_file.h" +#include "allegro5/internal/aintern_wunicode.h" +#include ALLEGRO_INTERNAL_HEADER + +#ifdef ALLEGRO_HAVE_SYS_STAT_H +#include +#endif + +ALLEGRO_DEBUG_CHANNEL("stdio") + +/* forward declaration */ +const struct ALLEGRO_FILE_INTERFACE _al_file_interface_stdio; + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + + +typedef struct +{ + FILE *fp; + int errnum; + char errmsg[80]; +} USERDATA; + + +static USERDATA *get_userdata(ALLEGRO_FILE *f) +{ + if (f) + return al_get_file_userdata(f); + else + return NULL; +} + + +/* Function: al_fopen_fd + */ +ALLEGRO_FILE *al_fopen_fd(int fd, const char *mode) +{ + ALLEGRO_FILE *f; + USERDATA *userdata; + FILE *fp; + + userdata = al_malloc(sizeof(USERDATA)); + if (!userdata) + return NULL; + + /* The fd should remain open if this function fails in any way, + * so delay the fdopen() call to last. + */ + userdata->fp = NULL; + userdata->errnum = 0; + + f = al_create_file_handle(&_al_file_interface_stdio, userdata); + if (!f) { + al_free(userdata); + return NULL; + } + + fp = fdopen(fd, mode); + if (!fp) { + al_set_errno(errno); + al_fclose(f); + return NULL; + } + + userdata->fp = fp; + return f; +} + + +static void *file_stdio_fopen(const char *path, const char *mode) +{ + FILE *fp; + USERDATA *userdata; + + ALLEGRO_DEBUG("opening %s %s\n", path, mode); + +#ifdef ALLEGRO_WINDOWS + { + wchar_t *wpath = _al_win_utf8_to_utf16(path); + wchar_t *wmode = _al_win_utf8_to_utf16(mode); + fp = _wfopen(wpath, wmode); + al_free(wpath); + al_free(wmode); + } +#else + fp = fopen(path, mode); +#endif + + if (!fp) { + al_set_errno(errno); + return NULL; + } + + userdata = al_malloc(sizeof(USERDATA)); + if (!userdata) { + fclose(fp); + return NULL; + } + + userdata->fp = fp; + userdata->errnum = 0; + + return userdata; +} + + +static bool file_stdio_fclose(ALLEGRO_FILE *f) +{ + USERDATA *userdata = get_userdata(f); + bool ret; + + if (userdata->fp == NULL) { + /* This can happen in the middle of al_fopen_fd. */ + ret = true; + } + else if (fclose(userdata->fp) == 0) { + ret = true; + } + else { + al_set_errno(errno); + ret = false; + } + + al_free(userdata); + + return ret; +} + + +static size_t file_stdio_fread(ALLEGRO_FILE *f, void *ptr, size_t size) +{ + USERDATA *userdata = get_userdata(f); + + if (size == 1) { + /* Optimise common case. */ + int c = fgetc(userdata->fp); + if (c == EOF) { + userdata->errnum = errno; + al_set_errno(errno); + return 0; + } + *((char *)ptr) = (char)c; + return 1; + } + else { + size_t ret = fread(ptr, 1, size, userdata->fp); + if (ret < size) { + userdata->errnum = errno; + al_set_errno(errno); + } + return ret; + } +} + + +static size_t file_stdio_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size) +{ + USERDATA *userdata = get_userdata(f); + size_t ret; + + ret = fwrite(ptr, 1, size, userdata->fp); + if (ret < size) { + userdata->errnum = errno; + al_set_errno(errno); + } + + return ret; +} + + +static bool file_stdio_fflush(ALLEGRO_FILE *f) +{ + USERDATA *userdata = get_userdata(f); + + if (fflush(userdata->fp) == EOF) { + userdata->errnum = errno; + al_set_errno(errno); + return false; + } + + return true; +} + + +static int64_t file_stdio_ftell(ALLEGRO_FILE *f) +{ + USERDATA *userdata = get_userdata(f); + int64_t ret; + +#if defined(ALLEGRO_HAVE_FTELLO) + ret = ftello(userdata->fp); +#elif defined(ALLEGRO_HAVE_FTELLI64) + ret = _ftelli64(userdata->fp); +#else + ret = ftell(userdata->fp); +#endif + if (ret == -1) { + userdata->errnum = errno; + al_set_errno(errno); + } + + return ret; +} + + +static bool file_stdio_fseek(ALLEGRO_FILE *f, int64_t offset, + int whence) +{ + USERDATA *userdata = get_userdata(f); + int rc; + + switch (whence) { + case ALLEGRO_SEEK_SET: whence = SEEK_SET; break; + case ALLEGRO_SEEK_CUR: whence = SEEK_CUR; break; + case ALLEGRO_SEEK_END: whence = SEEK_END; break; + } + +#if defined(ALLEGRO_HAVE_FSEEKO) + rc = fseeko(userdata->fp, offset, whence); +#elif defined(ALLEGRO_HAVE_FSEEKI64) + rc = _fseeki64(userdata->fp, offset, whence); +#else + rc = fseek(userdata->fp, offset, whence); +#endif + + if (rc == -1) { + userdata->errnum = errno; + al_set_errno(errno); + return false; + } + + return true; +} + + +static bool file_stdio_feof(ALLEGRO_FILE *f) +{ + USERDATA *userdata = get_userdata(f); + + return feof(userdata->fp); +} + + +static int file_stdio_ferror(ALLEGRO_FILE *f) +{ + USERDATA *userdata = get_userdata(f); + + return ferror(userdata->fp); +} + + +static const char *file_stdio_ferrmsg(ALLEGRO_FILE *f) +{ + USERDATA *userdata = get_userdata(f); + + if (userdata->errnum == 0) + return ""; + + /* Note: at this time MinGW has neither strerror_r nor strerror_s. */ +#if defined(ALLEGRO_HAVE_STRERROR_R) + { + int rc = strerror_r(userdata->errnum, userdata->errmsg, + sizeof(userdata->errmsg)); + if (rc == 0) { + return userdata->errmsg; + } + } +#endif + +#if defined(ALLEGRO_HAVE_STRERROR_S) + { + errno_t rc = strerror_s(userdata->errmsg, sizeof(userdata->errmsg), + userdata->errnum); + if (rc == 0) { + return userdata->errmsg; + } + } +#endif + + return ""; +} + + +static void file_stdio_fclearerr(ALLEGRO_FILE *f) +{ + USERDATA *userdata = get_userdata(f); + + clearerr(userdata->fp); +} + + +static int file_stdio_fungetc(ALLEGRO_FILE *f, int c) +{ + USERDATA *userdata = get_userdata(f); + int rc; + + rc = ungetc(c, userdata->fp); + if (rc == EOF) { + userdata->errnum = errno; + al_set_errno(errno); + } + + return rc; +} + + +static off_t file_stdio_fsize(ALLEGRO_FILE *f) +{ + int64_t old_pos; + int64_t new_pos; + + old_pos = file_stdio_ftell(f); + if (old_pos == -1) + return -1; + + if (!file_stdio_fseek(f, 0, ALLEGRO_SEEK_END)) + return -1; + + new_pos = file_stdio_ftell(f); + if (new_pos == -1) + return -1; + + if (!file_stdio_fseek(f, old_pos, ALLEGRO_SEEK_SET)) + return -1; + + return new_pos; +} + + +const struct ALLEGRO_FILE_INTERFACE _al_file_interface_stdio = +{ + file_stdio_fopen, + file_stdio_fclose, + file_stdio_fread, + file_stdio_fwrite, + file_stdio_fflush, + file_stdio_ftell, + file_stdio_fseek, + file_stdio_feof, + file_stdio_ferror, + file_stdio_ferrmsg, + file_stdio_fclearerr, + file_stdio_fungetc, + file_stdio_fsize +}; + + +/* Function: al_set_standard_file_interface + */ +void al_set_standard_file_interface(void) +{ + al_set_new_file_interface(&_al_file_interface_stdio); +} + + +#define MAX_MKTEMP_TRIES 1000 + +static void mktemp_replace_XX(const char *template, char *dst) +{ + static const char chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + size_t len = strlen(template); + unsigned i; + + for (i=0; ifs_create_entry); + return vt->fs_create_entry(path); +} + + +/* Function: al_destroy_fs_entry + */ +void al_destroy_fs_entry(ALLEGRO_FS_ENTRY *fh) +{ + if (fh) { + fh->vtable->fs_destroy_entry(fh); + } +} + + +/* Function: al_get_fs_entry_name + */ +const char *al_get_fs_entry_name(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_entry_name(e); +} + + +/* Function: al_update_fs_entry + */ +bool al_update_fs_entry(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_update_entry(e); +} + + +/* Function: al_get_fs_entry_mode + */ +uint32_t al_get_fs_entry_mode(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_entry_mode(e); +} + + +/* Function: al_get_fs_entry_atime + */ +time_t al_get_fs_entry_atime(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_entry_atime(e); +} + + +/* Function: al_get_fs_entry_mtime + */ +time_t al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_entry_mtime(e); +} + + +/* Function: al_get_fs_entry_ctime + */ +time_t al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_entry_ctime(e); +} + + +/* Function: al_get_fs_entry_size + */ +off_t al_get_fs_entry_size(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_entry_size(e); +} + + +/* Function: al_remove_fs_entry + */ +bool al_remove_fs_entry(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_remove_entry(e); +} + + +/* Function: al_fs_entry_exists + */ +bool al_fs_entry_exists(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_entry_exists(e); +} + + +/* Function: al_open_directory + */ +bool al_open_directory(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_open_directory(e); +} + + +/* Function: al_close_directory + */ +bool al_close_directory(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_close_directory(e); +} + + +/* Function: al_read_directory + */ +ALLEGRO_FS_ENTRY *al_read_directory(ALLEGRO_FS_ENTRY *e) +{ + ASSERT(e != NULL); + + return e->vtable->fs_read_directory(e); +} + + +/* Function: al_get_current_directory + */ +char *al_get_current_directory(void) +{ + const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); + ASSERT(vt->fs_get_current_directory); + return vt->fs_get_current_directory(); +} + + +/* Function: al_change_directory + */ +bool al_change_directory(const char *path) +{ + const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); + ASSERT(vt->fs_change_directory); + ASSERT(path); + + return vt->fs_change_directory(path); +} + + +/* Function: al_make_directory + */ +bool al_make_directory(const char *path) +{ + const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); + ASSERT(path); + ASSERT(vt->fs_make_directory); + + return vt->fs_make_directory(path); +} + + +/* Function: al_filename_exists + */ +bool al_filename_exists(const char *path) +{ + const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); + ASSERT(path != NULL); + ASSERT(vt->fs_filename_exists); + + return vt->fs_filename_exists(path); +} + + +/* Function: al_remove_filename + */ +bool al_remove_filename(const char *path) +{ + const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface(); + ASSERT(vt->fs_remove_filename); + ASSERT(path != NULL); + + return vt->fs_remove_filename(path); +} + + +/* Function: al_open_fs_entry + */ +ALLEGRO_FILE *al_open_fs_entry(ALLEGRO_FS_ENTRY *e, const char *mode) +{ + ASSERT(e != NULL); + + if (e->vtable->fs_open_file) + return e->vtable->fs_open_file(e, mode); + + al_set_errno(EINVAL); + return NULL; +} + + +/* Utility functions for iterating over a directory using callbacks. */ + +/* Function: al_for_each_fs_entry + */ +int al_for_each_fs_entry(ALLEGRO_FS_ENTRY *dir, + int (*callback)(ALLEGRO_FS_ENTRY *dir, void *extra), + void *extra) +{ + ALLEGRO_FS_ENTRY *entry; + + if (!dir || !al_open_directory(dir)) { + al_set_errno(ENOENT); + return ALLEGRO_FOR_EACH_FS_ENTRY_ERROR; + } + + for (entry = al_read_directory(dir); entry; entry = al_read_directory(dir)) { + /* Call the callback first. */ + int result = callback(entry, extra); + + /* Recurse if requested and needed. Only OK allows recursion. */ + if (result == ALLEGRO_FOR_EACH_FS_ENTRY_OK) { + if (al_get_fs_entry_mode(entry) & ALLEGRO_FILEMODE_ISDIR) { + result = al_for_each_fs_entry(entry, callback, extra); + } + } + + al_destroy_fs_entry(entry); + + if ((result == ALLEGRO_FOR_EACH_FS_ENTRY_STOP) || + (result == ALLEGRO_FOR_EACH_FS_ENTRY_ERROR)) { + return result; + } + } + + return ALLEGRO_FOR_EACH_FS_ENTRY_OK; +} + + + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/fshook_stdio.c b/allegro/src/fshook_stdio.c new file mode 100644 index 00000000..588dd4ea --- /dev/null +++ b/allegro/src/fshook_stdio.c @@ -0,0 +1,774 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * File System Hook, POSIX "driver" (not stdio). + * + * By Thomas Fjellstrom. + * + * Modified by Peter Wang. + * + * See readme.txt for copyright information. + */ + +/* Eventually we will make Allegro use the Unicode (UTF-16) Windows API + * globally but not yet. + */ +#ifndef UNICODE +#define UNICODE +#define _UNICODE +#endif + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_wunicode.h" +#include ALLEGRO_INTERNAL_HEADER + +ALLEGRO_DEBUG_CHANNEL("fshook") + +/* Enable large file support in gcc/glibc. */ +#if defined ALLEGRO_HAVE_FTELLO && defined ALLEGRO_HAVE_FSEEKO + #define _LARGEFILE_SOURCE + #define _LARGEFILE_SOURCE64 + #define _FILE_OFFSET_BITS 64 +#endif + +#include +#include + +#ifdef _MSC_VER + #define _POSIX_ + #include + #undef _POSIX_ + #include +#endif + +#include "allegro5/internal/aintern_file.h" +#include "allegro5/internal/aintern_fshook.h" + +#ifdef ALLEGRO_HAVE_SYS_STAT_H + #include +#endif + +#ifdef ALLEGRO_HAVE_DIRENT_H + #include + #include + #define NAMLEN(dirent) (strlen((dirent)->d_name)) +#else + #define dirent direct + #define NAMLEN(dirent) ((dirent)->d_namlen) + #ifdef ALLEGRO_HAVE_SYS_NDIR_H + #include + #endif + #ifdef ALLEGRO_HAVE_SYS_DIR_H + #include + #endif + #ifdef ALLEGRO_HAVE_NDIR_H + #include + #endif +#endif + +#ifndef S_IRGRP + #define S_IRGRP (0) +#endif +#ifndef S_IWGRP + #define S_IWGRP (0) +#endif +#ifndef S_IXGRP + #define S_IXGRP (0) +#endif + +#ifdef ALLEGRO_HAVE_SYS_TIME + #include +#endif +#ifdef ALLEGRO_HAVE_TIME_H + #include +#endif + +#ifdef ALLEGRO_WINDOWS + #include + #include "fshook_win.inc" + + typedef wchar_t WRAP_CHAR; + typedef struct _stat WRAP_STAT_TYPE; + typedef _WDIR WRAP_DIR_TYPE; + typedef struct _wdirent WRAP_DIRENT_TYPE; + #define WRAP_LIT(s) _TEXT(s) + #define WRAP_STRLEN(s) (wcslen(s)) + #define WRAP_STRCMP(s1, s2) (wcscmp((s1), (s2))) + #define WRAP_STAT(p, b) (_wstat((p), (b))) + #define WRAP_MKDIR(p) (_wmkdir(p)) + #define WRAP_RMDIR(p) (_wrmdir(p)) + #define WRAP_UNLINK(p) (_wunlink(p)) + #define WRAP_OPENDIR(p) (_wopendir(p)) + #define WRAP_CLOSEDIR(d) (_wclosedir(d)) + #define WRAP_READDIR(d) (_wreaddir(d)) +#else + typedef char WRAP_CHAR; + typedef struct stat WRAP_STAT_TYPE; + typedef DIR WRAP_DIR_TYPE; + typedef struct dirent WRAP_DIRENT_TYPE; + #define WRAP_LIT(s) (s) + #define WRAP_STRLEN(s) (strlen(s)) + #define WRAP_STRCMP(s1, s2) (strcmp((s1), (s2))) + #define WRAP_STAT(p, b) (stat((p), (b))) + #define WRAP_STAT_UNSLASH(p, b) (stat((p), (b))) + #define WRAP_MKDIR(p) (mkdir(p, 0755)) + #define WRAP_RMDIR(p) (rmdir(p)) + #define WRAP_UNLINK(p) (unlink(p)) + #define WRAP_OPENDIR(p) (opendir(p)) + #define WRAP_CLOSEDIR(d) (closedir(d)) + #define WRAP_READDIR(d) (readdir(d)) +#endif + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + + +typedef struct ALLEGRO_FS_ENTRY_STDIO ALLEGRO_FS_ENTRY_STDIO; + +struct ALLEGRO_FS_ENTRY_STDIO +{ + ALLEGRO_FS_ENTRY fs_entry; /* must be first */ + WRAP_CHAR *abs_path; +#ifdef ALLEGRO_WINDOWS + char *abs_path_utf8; + #define ABS_PATH_UTF8 abs_path_utf8 +#else + #define ABS_PATH_UTF8 abs_path +#endif + uint32_t stat_mode; + WRAP_STAT_TYPE st; + WRAP_DIR_TYPE *dir; +}; + + +static void fs_update_stat_mode(ALLEGRO_FS_ENTRY_STDIO *fp_stdio); +static bool fs_stdio_update_entry(ALLEGRO_FS_ENTRY *fp); + + +/* Make an absolute path given a potentially relative path. + * The result must be freed with free(), NOT al_free(). + */ +static WRAP_CHAR *make_absolute_path_inner(const WRAP_CHAR *tail) +{ +#ifdef ALLEGRO_WINDOWS + /* We use _wfullpath to get the proper drive letter semantics on Windows. */ + wchar_t *abs_path = _wfullpath(NULL, tail, 0); + + /* Remove trailing backslash (_wstat fails otherwise), but NOT directly + * following the drive letter. + */ + if (abs_path) { + const size_t abs_len = WRAP_STRLEN(abs_path); + if (abs_len == 3 && abs_path[1] == ':' && abs_path[2] == '\\') { + /* Do not strip "C:\" */ + } + else if (abs_len > 1 && abs_path[abs_len - 1] == '\\') { + abs_path[abs_len - 1] = '\0'; + } + } + + return abs_path; +#else + char cwd[PATH_MAX]; + ALLEGRO_PATH *cwdpath = NULL; + ALLEGRO_PATH *tailpath = NULL; + char *ret = NULL; + + if (!getcwd(cwd, sizeof(cwd))) { + ALLEGRO_WARN("Unable to get current working directory.\n"); + al_set_errno(errno); + goto Error; + } + + cwdpath = al_create_path_for_directory(cwd); + if (!cwdpath) { + goto Error; + } + + tailpath = al_create_path(tail); + if (!tailpath) { + goto Error; + } + + if (al_rebase_path(cwdpath, tailpath)) { + al_make_path_canonical(tailpath); + } + + ret = strdup(al_path_cstr(tailpath, ALLEGRO_NATIVE_PATH_SEP)); + +Error: + + al_destroy_path(cwdpath); + al_destroy_path(tailpath); + return ret; +#endif +} + + +static WRAP_CHAR *make_absolute_path(const char *tail) +{ + WRAP_CHAR *abs_path = NULL; +#ifdef ALLEGRO_WINDOWS + wchar_t *wtail = _al_win_utf8_to_utf16(tail); + if (wtail) { + abs_path = make_absolute_path_inner(wtail); + al_free(wtail); + } +#else + abs_path = make_absolute_path_inner(tail); +#endif + return abs_path; +} + + +static ALLEGRO_FS_ENTRY *create_abs_path_entry(const WRAP_CHAR *abs_path) +{ + ALLEGRO_FS_ENTRY_STDIO *fh; + size_t len; + + fh = al_calloc(1, sizeof(*fh)); + if (!fh) { + al_set_errno(errno); + return NULL; + } + + fh->fs_entry.vtable = &_al_fs_interface_stdio; + + len = WRAP_STRLEN(abs_path) + 1; /* including terminator */ + fh->abs_path = al_malloc(len * sizeof(WRAP_CHAR)); + if (!fh->abs_path) { + al_free(fh); + return NULL; + } + memcpy(fh->abs_path, abs_path, len * sizeof(WRAP_CHAR)); + +#ifdef ALLEGRO_WINDOWS + fh->abs_path_utf8 = _al_win_utf16_to_utf8(fh->abs_path); + if (!fh->abs_path_utf8) { + al_free(fh->abs_path); + al_free(fh); + return NULL; + } +#endif + + ALLEGRO_DEBUG("Creating entry for %s\n", fh->ABS_PATH_UTF8); + + fs_stdio_update_entry((ALLEGRO_FS_ENTRY *) fh); + + return (ALLEGRO_FS_ENTRY *) fh; +} + + +static ALLEGRO_FS_ENTRY *fs_stdio_create_entry(const char *orig_path) +{ + ALLEGRO_FS_ENTRY *ret = NULL; + WRAP_CHAR *abs_path; + + abs_path = make_absolute_path(orig_path); + if (abs_path) { + ret = create_abs_path_entry(abs_path); + free(abs_path); + } + return ret; +} + + +#if defined(ALLEGRO_UNIX) || defined(ALLEGRO_MACOSX) +static bool unix_hidden_file(const char *path) +{ + /* Filenames beginning with dot are considered hidden. */ + const char *p = strrchr(path, ALLEGRO_NATIVE_PATH_SEP); + if (p) + p++; + else + p = path; + return (p[0] == '.'); +} +#endif + + +static void fs_update_stat_mode(ALLEGRO_FS_ENTRY_STDIO *fp_stdio) +{ + fp_stdio->stat_mode = 0; + + if (S_ISDIR(fp_stdio->st.st_mode)) + fp_stdio->stat_mode |= ALLEGRO_FILEMODE_ISDIR; + else /* marks special unix files as files... might want to add enum items for symlink, CHAR, BLOCK and SOCKET files. */ + fp_stdio->stat_mode |= ALLEGRO_FILEMODE_ISFILE; + + /* + if (S_ISREG(fh->st.st_mode)) + fh->stat_mode |= ALLEGRO_FILEMODE_ISFILE; + */ + + if (fp_stdio->st.st_mode & (S_IRUSR | S_IRGRP)) + fp_stdio->stat_mode |= ALLEGRO_FILEMODE_READ; + + if (fp_stdio->st.st_mode & (S_IWUSR | S_IWGRP)) + fp_stdio->stat_mode |= ALLEGRO_FILEMODE_WRITE; + + if (fp_stdio->st.st_mode & (S_IXUSR | S_IXGRP)) + fp_stdio->stat_mode |= ALLEGRO_FILEMODE_EXECUTE; + +#if defined(ALLEGRO_WINDOWS) + { + DWORD attrib = GetFileAttributes(fp_stdio->abs_path); + if (attrib & FILE_ATTRIBUTE_HIDDEN) + fp_stdio->stat_mode |= ALLEGRO_FILEMODE_HIDDEN; + } +#endif +#if defined(ALLEGRO_MACOSX) && defined(UF_HIDDEN) + { + /* OSX hidden files can both start with the dot as well as having this flag set... + * Note that this flag does not exist on all versions of OS X (Tiger + * doesn't seem to have it) so we need to test for it. + */ + if (fp_stdio->st.st_flags & UF_HIDDEN) + fp_stdio->stat_mode |= ALLEGRO_FILEMODE_HIDDEN; + } +#endif +#if defined(ALLEGRO_UNIX) || defined(ALLEGRO_MACOSX) + if (0 == (fp_stdio->stat_mode & ALLEGRO_FILEMODE_HIDDEN)) { + if (unix_hidden_file(fp_stdio->abs_path)) { + fp_stdio->stat_mode |= ALLEGRO_FILEMODE_HIDDEN; + } + } +#endif +} + + +static bool fs_stdio_update_entry(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; + int ret; + + ret = WRAP_STAT(fp_stdio->abs_path, &(fp_stdio->st)); + if (ret == -1) { + al_set_errno(errno); + return false; + } + + fs_update_stat_mode(fp_stdio); + + return true; +} + + +static bool fs_stdio_open_directory(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; + + if (!(fp_stdio->stat_mode & ALLEGRO_FILEMODE_ISDIR)) + return false; + + fp_stdio->dir = WRAP_OPENDIR(fp_stdio->abs_path); + if (!fp_stdio->dir) { + al_set_errno(errno); + return false; + } + + return true; +} + + +static bool fs_stdio_close_directory(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; + int rc; + + if (!fp_stdio->dir) { + al_set_errno(ENOTDIR); + return false; + } + + rc = WRAP_CLOSEDIR(fp_stdio->dir); + fp_stdio->dir = NULL; + if (rc == -1) { + al_set_errno(errno); + return false; + } + + return true; +} + + +static ALLEGRO_FS_ENTRY *fs_stdio_read_directory(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; + // FIXME: Must use readdir_r as Allegro allows file functions being + // called from different threads. + WRAP_DIRENT_TYPE *ent; + ALLEGRO_FS_ENTRY *ret; + + ASSERT(fp_stdio->dir); + + do { + ent = WRAP_READDIR(fp_stdio->dir); + if (!ent) { + al_set_errno(errno); + return NULL; + } + /* Don't bother the user with these entries. */ + } while (0 == WRAP_STRCMP(ent->d_name, WRAP_LIT(".")) + || 0 == WRAP_STRCMP(ent->d_name, WRAP_LIT(".."))); + +#ifdef ALLEGRO_WINDOWS + { + wchar_t buf[MAX_PATH]; + int buflen; + + buflen = _snwprintf(buf, MAX_PATH, L"%s\\%s", + fp_stdio->abs_path, ent->d_name); + if (buflen >= MAX_PATH) { + al_set_errno(ERANGE); + return NULL; + } + ret = create_abs_path_entry(buf); + } +#else + { + int abs_path_len = strlen(fp_stdio->abs_path); + int ent_name_len = strlen(ent->d_name); + char *buf = al_malloc(abs_path_len + 1 + ent_name_len + 1); + if (!buf) { + al_set_errno(ENOMEM); + return NULL; + } + memcpy(buf, fp_stdio->abs_path, abs_path_len); + if ( (abs_path_len >= 1) && + buf[abs_path_len - 1] == ALLEGRO_NATIVE_PATH_SEP) + { + /* do NOT add a new separator if we have one already */ + memcpy(buf + abs_path_len, ent->d_name, ent_name_len); + buf[abs_path_len + ent_name_len] = '\0'; + } + else { + /* append separator */ + buf[abs_path_len] = ALLEGRO_NATIVE_PATH_SEP; + memcpy(buf + abs_path_len + 1, ent->d_name, ent_name_len); + buf[abs_path_len + 1 + ent_name_len] = '\0'; + } + ret = create_abs_path_entry(buf); + al_free(buf); + } +#endif + return ret; +} + + +static void fs_stdio_destroy_entry(ALLEGRO_FS_ENTRY *fh_) +{ + ALLEGRO_FS_ENTRY_STDIO *fh = (ALLEGRO_FS_ENTRY_STDIO *) fh_; + + al_free(fh->abs_path); +#ifdef ALLEGRO_WINDOWS + al_free(fh->abs_path_utf8); +#endif + + if (fh->dir) + fs_stdio_close_directory(fh_); + + al_free(fh); +} + + +static off_t fs_stdio_entry_size(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; + ASSERT(ent); + return ent->st.st_size; +} + + +static uint32_t fs_stdio_entry_mode(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; + ASSERT(ent); + return ent->stat_mode; +} + + +static time_t fs_stdio_entry_atime(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; + ASSERT(ent); + return ent->st.st_atime; +} + + +static time_t fs_stdio_entry_mtime(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; + ASSERT(ent); + return ent->st.st_mtime; +} + + +static time_t fs_stdio_entry_ctime(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *ent = (ALLEGRO_FS_ENTRY_STDIO *) fp; + ASSERT(ent); + return ent->st.st_ctime; +} + + +static char *fs_stdio_get_current_directory(void) +{ +#ifdef ALLEGRO_WINDOWS + wchar_t *wcwd; + char *cwd; + + wcwd = _wgetcwd(NULL, 1); + if (!wcwd) { + al_set_errno(errno); + return NULL; + } + cwd = _al_win_utf16_to_utf8(wcwd); + free(wcwd); + return cwd; +#else + char tmpdir[PATH_MAX]; + char *cwd; + + if (!getcwd(tmpdir, PATH_MAX)) { + al_set_errno(errno); + return NULL; + } + + cwd = al_malloc(strlen(tmpdir) + 1); + if (!cwd) { + al_set_errno(ENOMEM); + return NULL; + } + return strcpy(cwd, tmpdir); +#endif +} + + +static bool fs_stdio_change_directory(const char *path) +{ + int ret = -1; + +#ifdef ALLEGRO_WINDOWS + wchar_t *wpath = _al_win_utf8_to_utf16(path); + if (wpath) { + ret = _wchdir(wpath); + al_free(wpath); + } +#else + ret = chdir(path); +#endif + + if (ret == -1) { + al_set_errno(errno); + return false; + } + + return true; +} + + +static bool mkdir_exists(const WRAP_CHAR *path) +{ + WRAP_STAT_TYPE st; + + if (WRAP_STAT(path, &st) == 0) { + return S_ISDIR(st.st_mode); + } + + return WRAP_MKDIR(path) == 0; +} + + +static bool do_make_directory(WRAP_CHAR *abs_path) +{ + const WRAP_CHAR * const end = abs_path + WRAP_STRLEN(abs_path); + WRAP_CHAR *p; + bool ret; + + p = abs_path + 1; + +#ifdef ALLEGRO_WINDOWS + /* Skip drive letter. */ + if (end - abs_path >= 3 + && abs_path[1] == ':' + && (abs_path[2] == '\\' || abs_path[2] == '/')) + { + p = abs_path + 3; + } +#endif + + for ( ; p < end; p++) { + const WRAP_CHAR c = *p; + if (c == ALLEGRO_NATIVE_PATH_SEP || c == '/') { + *p = '\0'; + ret = mkdir_exists(abs_path); + *p = c; + if (!ret) + return false; + } + } + + return mkdir_exists(abs_path); +} + + +static bool fs_stdio_make_directory(const char *tail) +{ + bool ret = false; + WRAP_CHAR *abs_path = make_absolute_path(tail); + if (abs_path) { + ret = do_make_directory(abs_path); + free(abs_path); + } + return ret; +} + + +static bool fs_stdio_entry_exists(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; + WRAP_STAT_TYPE st; + + if (WRAP_STAT(fp_stdio->abs_path, &st) != 0) { + if (errno != ENOENT) { + al_set_errno(errno); + } + return false; + } + + return true; +} + + +static bool fs_stdio_filename_exists(const char *path) +{ + WRAP_STAT_TYPE st; + bool ret = false; + ASSERT(path); + +#ifdef ALLEGRO_WINDOWS + { + /* Pass an path created by _wfullpath() to avoid issues + * with stat() failing when there is a trailing slash. + */ + wchar_t *abs_path = make_absolute_path(path); + if (abs_path) { + ret = (0 == WRAP_STAT(abs_path, &st)); + if (!ret && errno != ENOENT) { + al_set_errno(errno); + } + free(abs_path); + } + } +#else + ret = (0 == WRAP_STAT(path, &st)); + if (!ret && errno != ENOENT) { + al_set_errno(errno); + } +#endif + + return ret; +} + + +static bool fs_stdio_remove_entry(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; + int err; + + ASSERT(fp); + + if (fs_stdio_entry_mode(fp) & ALLEGRO_FILEMODE_ISDIR) { + err = WRAP_RMDIR(fp_stdio->abs_path); + } + else if (fs_stdio_entry_mode(fp) & ALLEGRO_FILEMODE_ISFILE) { + err = WRAP_UNLINK(fp_stdio->abs_path); + } + else { + al_set_errno(ENOENT); + return false; + } + + if (err != 0) { + al_set_errno(errno); + return false; + } + + return true; +} + + +static bool fs_stdio_remove_filename(const char *path) +{ + ALLEGRO_FS_ENTRY *fp; + bool rc; + + fp = fs_stdio_create_entry(path); + if (!fp) { + ALLEGRO_WARN("Cannot remove %s.", path); + return false; + } + + rc = fs_stdio_remove_entry(fp); + fs_stdio_destroy_entry(fp); + return rc; +} + + +static const char *fs_stdio_name(ALLEGRO_FS_ENTRY *fp) +{ + ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; + + return fp_stdio->ABS_PATH_UTF8; +} + + +static ALLEGRO_FILE *fs_stdio_open_file(ALLEGRO_FS_ENTRY *fp, const char *mode) +{ + ALLEGRO_FS_ENTRY_STDIO *fp_stdio = (ALLEGRO_FS_ENTRY_STDIO *) fp; + + /* XXX on Windows it would be nicer to use the UTF-16 abs_path field + * directly + */ + return al_fopen_interface(&_al_file_interface_stdio, + fp_stdio->ABS_PATH_UTF8, mode); +} + + +struct ALLEGRO_FS_INTERFACE _al_fs_interface_stdio = { + fs_stdio_create_entry, + fs_stdio_destroy_entry, + fs_stdio_name, + fs_stdio_update_entry, + fs_stdio_entry_mode, + fs_stdio_entry_atime, + fs_stdio_entry_mtime, + fs_stdio_entry_ctime, + fs_stdio_entry_size, + fs_stdio_entry_exists, + fs_stdio_remove_entry, + + fs_stdio_open_directory, + fs_stdio_read_directory, + fs_stdio_close_directory, + + fs_stdio_filename_exists, + fs_stdio_remove_filename, + fs_stdio_get_current_directory, + fs_stdio_change_directory, + fs_stdio_make_directory, + + fs_stdio_open_file +}; + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/fshook_win.inc b/allegro/src/fshook_win.inc new file mode 100644 index 00000000..87997c76 --- /dev/null +++ b/allegro/src/fshook_win.inc @@ -0,0 +1,264 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Helper routines for fshook implementation on Windows. + * + * See LICENSE.txt for copyright information. + */ + +#include + +#if defined(ALLEGRO_MSVC) + +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) + + +/* + * MSVC is missing the whole dirent.h so we implement the bits we need here. + * The following block is copied from dirent.c from MinGW Runtime sources + * version 3.15.1 with minor modifications. The code was public domain. + */ + +#ifdef _UNICODE + #define _TDIR _WDIR + #define _tdirent _wdirent + #define _topendir _wopendir + #define _tclosedir _wclosedir + #define _treaddir _wreaddir +#else + #error _UNICODE not defined +#endif + +#define SUFFIX _T("*") +#define SLASH _T("\\") + +struct _wdirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + wchar_t d_name[FILENAME_MAX]; /* File name. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + * dd_stat field is now int (was short in older versions). + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _wfinddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct _wdirent dd_dir; + + /* _findnext handle */ + intptr_t dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + wchar_t dd_name[1]; +} _WDIR; + + +/* + * opendir + * + * Returns a pointer to a DIR structure appropriately filled in to begin + * searching a directory. + */ +static _TDIR *_topendir(const _TCHAR *szPath) +{ + _TDIR *nd; + unsigned int rc; + _TCHAR szFullPath[MAX_PATH]; + + errno = 0; + + if (!szPath) { + errno = EFAULT; + return (_TDIR *) 0; + } + + if (szPath[0] == _T('\0')) { + errno = ENOTDIR; + return (_TDIR*) 0; + } + + /* Attempt to determine if the given path really is a directory. */ + rc = GetFileAttributes(szPath); + if (rc == (unsigned int)-1) { + /* call GetLastError for more error info */ + errno = ENOENT; + return (_TDIR*) 0; + } + if (!(rc & FILE_ATTRIBUTE_DIRECTORY)) { + /* Error, entry exists but not a directory. */ + errno = ENOTDIR; + return (_TDIR*) 0; + } + + /* Make an absolute pathname. */ + _tfullpath(szFullPath, szPath, MAX_PATH); + + /* Allocate enough space to store DIR structure and the complete + * directory path given. */ + nd = (_TDIR *) al_malloc(sizeof (_TDIR) + (_tcslen(szFullPath) + _tcslen(SLASH) + + _tcslen(SUFFIX) + 1) * sizeof(_TCHAR)); + + if (!nd) { + /* Error, out of memory. */ + errno = ENOMEM; + return (_TDIR*) 0; + } + + /* Create the search expression. */ + _tcscpy(nd->dd_name, szFullPath); + + /* Add on a slash if the path does not end with one. */ + if (nd->dd_name[0] != _T('\0') + && _tcsrchr(nd->dd_name, _T('/')) != + nd->dd_name + _tcslen(nd->dd_name) - 1 + && _tcsrchr(nd->dd_name, _T('\\')) != + nd->dd_name + _tcslen(nd->dd_name) - 1) + { + _tcscat(nd->dd_name, SLASH); + } + + /* Add on the search pattern */ + _tcscat(nd->dd_name, SUFFIX); + + /* Initialize handle to -1 so that a premature closedir doesn't try + * to call _findclose on it. */ + nd->dd_handle = -1; + + /* Initialize the status. */ + nd->dd_stat = 0; + + /* Initialize the dirent structure. ino and reclen are invalid under + * Win32, and name simply points at the appropriate part of the + * findfirst_t structure. */ + nd->dd_dir.d_ino = 0; + nd->dd_dir.d_reclen = 0; + nd->dd_dir.d_namlen = 0; + memset(nd->dd_dir.d_name, 0, FILENAME_MAX); + + return nd; +} + + +/* + * readdir + * + * Return a pointer to a dirent structure filled with the information on the + * next entry in the directory. + */ +static struct _tdirent* _treaddir(_TDIR* dirp) +{ + errno = 0; + + /* Check for valid DIR struct. */ + if (!dirp) { + errno = EFAULT; + return (struct _tdirent*) 0; + } + + if (dirp->dd_stat < 0) { + /* We have already returned all files in the directory + * (or the structure has an invalid dd_stat). */ + return (struct _tdirent*) 0; + } + else if (dirp->dd_stat == 0) { + /* We haven't started the search yet. */ + /* Start the search */ + dirp->dd_handle = _tfindfirst(dirp->dd_name, &(dirp->dd_dta)); + + if (dirp->dd_handle == -1) { + /* Whoops! Seems there are no files in that + * directory. */ + dirp->dd_stat = -1; + } + else { + dirp->dd_stat = 1; + } + } + else { + /* Get the next search entry. */ + if (_tfindnext(dirp->dd_handle, &(dirp->dd_dta))) { + /* We are off the end or otherwise error. + _findnext sets errno to ENOENT if no more file + Undo this. */ + DWORD winerr = GetLastError(); + if (winerr == ERROR_NO_MORE_FILES) + errno = 0; + _findclose(dirp->dd_handle); + dirp->dd_handle = -1; + dirp->dd_stat = -1; + } + else { + /* Update the status to indicate the correct + * number. */ + dirp->dd_stat++; + } + } + + if (dirp->dd_stat > 0) { + /* Successfully got an entry. Everything about the file is + * already appropriately filled in except the length of the + * file name. */ + dirp->dd_dir.d_namlen = (unsigned short)_tcslen(dirp->dd_dta.name); + _tcscpy(dirp->dd_dir.d_name, dirp->dd_dta.name); + return &dirp->dd_dir; + } + + return (struct _tdirent*) 0; +} + + +/* + * closedir + * + * Frees up resources allocated by opendir. + */ +static int _tclosedir(_TDIR* dirp) +{ + int rc; + + errno = 0; + rc = 0; + + if (!dirp) { + errno = EFAULT; + return -1; + } + + if (dirp->dd_handle != -1) { + rc = _findclose(dirp->dd_handle); + } + + /* Delete the dir structure. */ + al_free(dirp); + + return rc; +} + +#endif /* ALLEGRO_MSVC */ + +/* vim: set ft=c sts=3 sw=3 et: */ diff --git a/allegro/src/fullscreen_mode.c b/allegro/src/fullscreen_mode.c new file mode 100644 index 00000000..dd353164 --- /dev/null +++ b/allegro/src/fullscreen_mode.c @@ -0,0 +1,39 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Fullscreen mode queries. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" + + +/* Function: al_get_num_display_modes + */ +int al_get_num_display_modes(void) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + return system->vt->get_num_display_modes(); +} + + +/* Function: al_get_display_mode + */ +ALLEGRO_DISPLAY_MODE *al_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + return system->vt->get_display_mode(index, mode); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/gp2xwiz/wiz_display_fb.c b/allegro/src/gp2xwiz/wiz_display_fb.c new file mode 100644 index 00000000..a82c0bc8 --- /dev/null +++ b/allegro/src/gp2xwiz/wiz_display_fb.c @@ -0,0 +1,196 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * GP2X Wiz framebuffer display driver + * + * By Trent Gamblin. + * + */ + +#include "allegro5/internal/aintern_gp2xwiz.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_opengl.h" + +ALLEGRO_DEBUG_CHANNEL("display") + +static ALLEGRO_DISPLAY_INTERFACE *gp2xwiz_vt; + +static bool set_gfx_mode = false; + +/* Create a new X11 display, which maps directly to a GLX window. */ +static ALLEGRO_DISPLAY *gp2xwiz_create_display_fb(int w, int h) +{ + (void)w; + (void)h; + + /* Only one display allowed at a time */ + if (set_gfx_mode) + return NULL; + + lc_init_rest(); + + ALLEGRO_DISPLAY_GP2XWIZ_FB *d = al_calloc(1, sizeof *d); + ALLEGRO_DISPLAY *display = (void *)d; + + ALLEGRO_SYSTEM_GP2XWIZ *system = (void *)al_get_system_driver(); + + display->w = 320; + display->h = 240; + display->vt = _al_display_gp2xwiz_framebuffer_driver(); + display->refresh_rate = 60; + display->flags = al_get_new_display_flags(); + + display->flags |= ALLEGRO_FULLSCREEN; + + /* Add ourself to the list of displays. */ + ALLEGRO_DISPLAY_GP2XWIZ_FB **add; + add = _al_vector_alloc_back(&system->system.displays); + *add = d; + + /* Each display is an event source. */ + _al_event_source_init(&display->es); + + /* Create a backbuffer and point it to the framebuffer */ + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + d->backbuffer = al_create_bitmap(320, 240); + d->screen_mem = d->backbuffer->memory; + d->backbuffer->memory = (unsigned char *)lc_fb1; + + set_gfx_mode = true; + + ALLEGRO_DEBUG("Display created successfully\n"); + + return display; +} + + +static void gp2xwiz_destroy_display_fb(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_GP2XWIZ *s = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_GP2XWIZ_FB *wiz_disp = (void *)d; + + _al_vector_find_and_delete(&s->system.displays, &d); + + /* All bitmaps are memory bitmaps, no need to do anything */ + + _al_vector_free(&d->bitmaps); + _al_event_source_free(&d->es); + + wiz_disp->backbuffer->memory = wiz_disp->screen_mem; + al_destroy_bitmap(wiz_disp->backbuffer); + + al_free(d->vertex_cache); + al_free(d); + + set_gfx_mode = false; +} + + +static bool gp2xwiz_set_current_display_fb(ALLEGRO_DISPLAY *d) +{ + (void)d; + return true; +} + + +static void gp2xwiz_flip_display_fb(ALLEGRO_DISPLAY *d) +{ + (void)d; +} + +static void gp2xwiz_update_display_region_fb(ALLEGRO_DISPLAY *d, int x, int y, + int w, int h) +{ + (void)x; + (void)y; + (void)w; + (void)h; + gp2xwiz_flip_display_fb(d); +} + +static bool gp2xwiz_acknowledge_resize_fb(ALLEGRO_DISPLAY *d) +{ + (void)d; + return false; +} + + +static bool gp2xwiz_resize_display_fb(ALLEGRO_DISPLAY *d, int w, int h) +{ + (void)d; + (void)w; + (void)h; + return false; +} + + +static bool gp2xwiz_is_compatible_bitmap_fb(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap) +{ + (void)display; + (void)bitmap; + return true; +} + + +static void gp2xwiz_get_window_position_fb(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + (void)display; + *x = 0; + *y = 0; +} + + +static bool gp2xwiz_wait_for_vsync_fb(ALLEGRO_DISPLAY *display) +{ + (void)display; + return false; +} + + +static ALLEGRO_BITMAP *gp2xwiz_get_backbuffer_fb(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_GP2XWIZ_FB *d = (void *)display; + return d->backbuffer; +} + + +/* Obtain a reference to this driver. */ +ALLEGRO_DISPLAY_INTERFACE *_al_display_gp2xwiz_framebuffer_driver(void) +{ + if (gp2xwiz_vt) + return gp2xwiz_vt; + + gp2xwiz_vt = al_calloc(1, sizeof *gp2xwiz_vt); + + gp2xwiz_vt->create_display = gp2xwiz_create_display_fb; + gp2xwiz_vt->destroy_display = gp2xwiz_destroy_display_fb; + gp2xwiz_vt->set_current_display = gp2xwiz_set_current_display_fb; + gp2xwiz_vt->flip_display = gp2xwiz_flip_display_fb; + gp2xwiz_vt->update_display_region = gp2xwiz_update_display_region_fb; + gp2xwiz_vt->acknowledge_resize = gp2xwiz_acknowledge_resize_fb; + gp2xwiz_vt->create_bitmap = NULL; + gp2xwiz_vt->get_backbuffer = gp2xwiz_get_backbuffer_fb; + gp2xwiz_vt->set_target_bitmap = NULL; + gp2xwiz_vt->is_compatible_bitmap = gp2xwiz_is_compatible_bitmap_fb; + gp2xwiz_vt->resize_display = gp2xwiz_resize_display_fb; + gp2xwiz_vt->set_icons = NULL; + gp2xwiz_vt->set_window_title = NULL; + gp2xwiz_vt->set_window_position = NULL; + gp2xwiz_vt->get_window_position = gp2xwiz_get_window_position_fb; + gp2xwiz_vt->set_window_constraints = NULL; + gp2xwiz_vt->get_window_constraints = NULL; + gp2xwiz_vt->set_display_flag = NULL; + gp2xwiz_vt->wait_for_vsync = gp2xwiz_wait_for_vsync_fb; + + return gp2xwiz_vt; +} + +/* vi: set sts=3 sw=3 et: */ diff --git a/allegro/src/gp2xwiz/wiz_display_opengl.c b/allegro/src/gp2xwiz/wiz_display_opengl.c new file mode 100644 index 00000000..665faa73 --- /dev/null +++ b/allegro/src/gp2xwiz/wiz_display_opengl.c @@ -0,0 +1,272 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * GP2X Wiz OpenGL display driver + * + * By Trent Gamblin. + * + */ + +#include "allegro5/internal/aintern_gp2xwiz.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_opengl.h" + +ALLEGRO_DEBUG_CHANNEL("display") + +static ALLEGRO_DISPLAY_INTERFACE *gp2xwiz_vt; + +static bool set_gfx_mode = false; + +/* Helper to set up GL state as we want it. */ +static void setup_gl(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; + + glViewport(0, 0, d->w, d->h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, d->w, d->h, 0, -1, 1); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if (!ogl->backbuffer) + ogl->backbuffer = _al_ogl_create_backbuffer(d); +} + + +/* Create a new X11 display, which maps directly to a GLX window. */ +static ALLEGRO_DISPLAY *gp2xwiz_create_display_ogl(int w, int h) +{ + (void)w; + (void)h; + + /* Only one display allowed at a time */ + if (set_gfx_mode) + return NULL; + + ALLEGRO_DISPLAY_GP2XWIZ_OGL *d = al_calloc(1, sizeof *d); + ALLEGRO_DISPLAY *display = (void*)d; + ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl); + EGLint numConfigs; + + display->ogl_extras = ogl; + + ALLEGRO_SYSTEM_GP2XWIZ *system = (void *)al_get_system_driver(); + + display->w = 320; + display->h = 240; + display->vt = _al_display_gp2xwiz_opengl_driver(); + display->refresh_rate = 60; + display->flags = al_get_new_display_flags(); + + // FIXME: default? Is this the right place to set this? + display->flags |= ALLEGRO_OPENGL; +#ifdef ALLEGRO_CFG_OPENGLES2 + display->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + display->flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + display->flags |= ALLEGRO_FULLSCREEN; + + /* Add ourself to the list of displays. */ + ALLEGRO_DISPLAY_GP2XWIZ_OGL **add; + add = _al_vector_alloc_back(&system->system.displays); + *add = d; + + /* Each display is an event source. */ + _al_event_source_init(&display->es); + + EGLint attrib_list[] = + { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 6, + EGL_BLUE_SIZE, 5, + EGL_DEPTH_SIZE, 16, + EGL_NONE + }; + + EGLint majorVersion, minorVersion; + + nanoGL_Init(); + + d->hNativeWnd = OS_CreateWindow(); + + d->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + + eglInitialize(d->egl_display, &majorVersion, &minorVersion); + + ALLEGRO_DEBUG("EGL Version: %d.%d\n", majorVersion, minorVersion); + + eglChooseConfig(d->egl_display, attrib_list, &d->egl_config, 1, &numConfigs); + + d->egl_surface = eglCreateWindowSurface(d->egl_display, d->egl_config, d->hNativeWnd, NULL); + + d->egl_context = eglCreateContext(d->egl_display, d->egl_config, EGL_NO_CONTEXT, NULL); + + eglMakeCurrent(d->egl_display, d->egl_surface, d->egl_surface, d->egl_context); + + + //eglSwapInterval(d->egl_display, EGL_MAX_SWAP_INTERVAL); + + ALLEGRO_DEBUG("GP2X Wiz window created.\n"); + + // FIXME: + ALLEGRO_DEBUG("Calling _al_ogl_manage_extensions\n"); + _al_ogl_manage_extensions(display); + ALLEGRO_DEBUG("Calling _al_ogl_set_extensions\n"); + _al_ogl_set_extensions(ogl->extension_api); + + // FIXME + // We don't have this extra_settings stuff set up right + //if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY]) + setup_gl(display); + + set_gfx_mode = true; + + ALLEGRO_DEBUG("Display created successfully\n"); + + return display; +} + + +static void gp2xwiz_destroy_display_ogl(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_GP2XWIZ *s = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_GP2XWIZ_OGL *wiz_disp = (void *)d; + + while (d->bitmaps._size > 0) { + ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps); + ALLEGRO_BITMAP *b = *bptr; + _al_convert_to_memory_bitmap(b); + } + + _al_ogl_unmanage_extensions(d); + + _al_vector_find_and_delete(&s->system.displays, &d); + + eglMakeCurrent(wiz_disp->egl_display, 0, 0, wiz_disp->egl_context); + + eglDestroySurface(wiz_disp->egl_display, wiz_disp->egl_surface); + eglDestroyContext(wiz_disp->egl_display, wiz_disp->egl_context); + eglTerminate(wiz_disp->egl_display); + al_free(wiz_disp->hNativeWnd); + nanoGL_Destroy(); + + _al_vector_free(&d->bitmaps); + _al_event_source_free(&d->es); + + al_free(d->ogl_extras); + al_free(d->vertex_cache); + al_free(d); + + set_gfx_mode = false; +} + + +static bool gp2xwiz_set_current_display_ogl(ALLEGRO_DISPLAY *d) +{ + (void)d; + return true; +} + + +static void gp2xwiz_flip_display_ogl(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_GP2XWIZ_OGL *wiz_disp = (ALLEGRO_DISPLAY_GP2XWIZ_OGL *)d; + eglSwapBuffers(wiz_disp->egl_display, wiz_disp->egl_surface); +} + +static void gp2xwiz_update_display_region_ogl(ALLEGRO_DISPLAY *d, int x, int y, + int w, int h) +{ + (void)x; + (void)y; + (void)w; + (void)h; + gp2xwiz_flip_display_ogl(d); +} + +static bool gp2xwiz_acknowledge_resize_ogl(ALLEGRO_DISPLAY *d) +{ + (void)d; + return false; +} + + +static bool gp2xwiz_resize_display_ogl(ALLEGRO_DISPLAY *d, int w, int h) +{ + (void)d; + (void)w; + (void)h; + return false; +} + + +static bool gp2xwiz_is_compatible_bitmap_ogl(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap) +{ + (void)display; + (void)bitmap; + return true; +} + + +static void gp2xwiz_get_window_position_ogl(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + (void)display; + *x = 0; + *y = 0; +} + + +static bool gp2xwiz_wait_for_vsync_ogl(ALLEGRO_DISPLAY *display) +{ + (void)display; + return false; +} + +/* Obtain a reference to this driver. */ +ALLEGRO_DISPLAY_INTERFACE *_al_display_gp2xwiz_opengl_driver(void) +{ + if (gp2xwiz_vt) + return gp2xwiz_vt; + + gp2xwiz_vt = al_calloc(1, sizeof *gp2xwiz_vt); + + gp2xwiz_vt->create_display = gp2xwiz_create_display_ogl; + gp2xwiz_vt->destroy_display = gp2xwiz_destroy_display_ogl; + gp2xwiz_vt->set_current_display = gp2xwiz_set_current_display_ogl; + gp2xwiz_vt->flip_display = gp2xwiz_flip_display_ogl; + gp2xwiz_vt->update_display_region = gp2xwiz_update_display_region_ogl; + gp2xwiz_vt->acknowledge_resize = gp2xwiz_acknowledge_resize_ogl; + gp2xwiz_vt->create_bitmap = _al_ogl_create_bitmap; + gp2xwiz_vt->get_backbuffer = _al_ogl_get_backbuffer; + gp2xwiz_vt->set_target_bitmap = _al_ogl_set_target_bitmap; + gp2xwiz_vt->is_compatible_bitmap = gp2xwiz_is_compatible_bitmap_ogl; + gp2xwiz_vt->resize_display = gp2xwiz_resize_display_ogl; + gp2xwiz_vt->set_icons = NULL; + gp2xwiz_vt->set_window_title = NULL; + gp2xwiz_vt->set_window_position = NULL; + gp2xwiz_vt->get_window_position = gp2xwiz_get_window_position_ogl; + gp2xwiz_vt->set_window_constraints = NULL; + gp2xwiz_vt->get_window_constraints = NULL; + gp2xwiz_vt->set_display_flag = NULL; + gp2xwiz_vt->wait_for_vsync = gp2xwiz_wait_for_vsync_ogl; + + _al_ogl_add_drawing_functions(gp2xwiz_vt); + + return gp2xwiz_vt; +} + +/* vi: set sts=3 sw=3 et: */ diff --git a/allegro/src/gp2xwiz/wiz_joystick.c b/allegro/src/gp2xwiz/wiz_joystick.c new file mode 100644 index 00000000..6688359d --- /dev/null +++ b/allegro/src/gp2xwiz/wiz_joystick.c @@ -0,0 +1,247 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * GP2X Wiz joystick driver + * + * by Trent Gamblin. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/joystick.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintwiz.h" +#include "allegro5/platform/alwiz.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_gp2xwiz.h" + +static ALLEGRO_JOYSTICK joy; + +static ALLEGRO_JOYSTICK_STATE joystate; +static ALLEGRO_THREAD *wiz_joystick_thread; + +const int POLLS_PER_SECOND = 60; + +#define BUTTON(x) (buttons & x) + +static void joywiz_fill_joystate(ALLEGRO_JOYSTICK_STATE *state) +{ + uint32_t buttons = lc_getbuttons(); + + /* Left-right axis */ + if (BUTTON(BTN_LEFT)) { + state->stick[0].axis[0] = -1; + } + else if (BUTTON(BTN_RIGHT)) { + state->stick[0].axis[0] = 1; + } + else { + state->stick[0].axis[0] = 0; + } + + /* Up-down axis */ + if (BUTTON(BTN_UP)) { + state->stick[0].axis[1] = -1; + } + else if (BUTTON(BTN_DOWN)) { + state->stick[0].axis[1] = 1; + } + else { + state->stick[0].axis[1] = 0; + } + + /* Other buttons */ + state->button[0] = BUTTON(BTN_A); + state->button[1] = BUTTON(BTN_B); + state->button[2] = BUTTON(BTN_X); + state->button[3] = BUTTON(BTN_Y); + state->button[4] = BUTTON(BTN_L); + state->button[5] = BUTTON(BTN_R); + state->button[6] = BUTTON(BTN_MENU); + state->button[7] = BUTTON(BTN_SELECT); + state->button[8] = BUTTON(BTN_VOLUP); + state->button[9] = BUTTON(BTN_VOLDOWN); +} + + +static void generate_axis_event(ALLEGRO_JOYSTICK *joy, int stick, int axis, float pos) +{ + ALLEGRO_EVENT event; + + if (!_al_event_source_needs_to_generate_event(&joy->es)) + return; + + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.timestamp = al_get_time(); + event.joystick.stick = stick; + event.joystick.axis = axis; + event.joystick.pos = pos; event.joystick.button = 0; + + _al_event_source_emit_event(&joy->es, &event); +} + + +static void generate_button_event(ALLEGRO_JOYSTICK *joy, int button, ALLEGRO_EVENT_TYPE event_type) +{ + ALLEGRO_EVENT event; + + if (!_al_event_source_needs_to_generate_event(&joy->es)) + return; + + event.joystick.type = event_type; + event.joystick.timestamp = al_get_time(); + event.joystick.stick = 0; + event.joystick.axis = 0; + event.joystick.pos = 0.0; + event.joystick.button = button; + + _al_event_source_emit_event(&joy->es, &event); +} + +static void *joywiz_thread_proc(ALLEGRO_THREAD *thread, void *unused) +{ + ALLEGRO_JOYSTICK_STATE oldstate; + memset(&oldstate, 0, sizeof(ALLEGRO_JOYSTICK_STATE)); + + (void)unused; + + while (!al_get_thread_should_stop(thread)) { + joywiz_fill_joystate(&joystate); + if (joystate.stick[0].axis[0] != oldstate.stick[0].axis[0]) { + generate_axis_event(&joy, 0, 0, + joystate.stick[0].axis[0]); + } + if (joystate.stick[0].axis[1] != oldstate.stick[0].axis[1]) { + generate_axis_event(&joy, 0, 1, + joystate.stick[0].axis[1]); + } + int i; + for (i = 0; i < 10; i++) { + ALLEGRO_EVENT_TYPE type; + if (oldstate.button[i] == 0) + type = ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN; + else + type = ALLEGRO_EVENT_JOYSTICK_BUTTON_UP; + if (joystate.button[i] != oldstate.button[i]) { + generate_button_event(&joy, i, type); + } + } + oldstate = joystate; + al_rest(1.0/POLLS_PER_SECOND); + } + + return NULL; +} + +static void joywiz_fill_joy(void) +{ + joy.info.num_sticks = 1; + joy.info.num_buttons = 10; + + joy.info.stick[0].flags = ALLEGRO_JOYFLAG_DIGITAL; + joy.info.stick[0].num_axes = 2; + joy.info.stick[0].name = "Wiz D-pad"; + joy.info.stick[0].axis[0].name = "Left-right axis"; + joy.info.stick[0].axis[1].name = "Up-down axis"; + + joy.info.button[0].name = "A"; + joy.info.button[1].name = "B"; + joy.info.button[2].name = "X"; + joy.info.button[3].name = "Y"; + joy.info.button[4].name = "L"; + joy.info.button[5].name = "R"; + joy.info.button[6].name = "Menu"; + joy.info.button[7].name = "Select"; + joy.info.button[8].name = "VolUp"; + joy.info.button[9].name = "VolDown"; + + joy.num = 0; +} + +static bool joywiz_init_joystick(void) +{ + lc_init_joy(); + + joywiz_fill_joy(); + + _al_event_source_init(&joy.es); + + memset(&joystate, 0, sizeof(ALLEGRO_JOYSTICK_STATE)); + + wiz_joystick_thread = al_create_thread(joywiz_thread_proc, NULL); + if (!wiz_joystick_thread) { + return false; + } + + al_start_thread(wiz_joystick_thread); + + return true; +} + +static void joywiz_exit_joystick(void) +{ + al_join_thread(wiz_joystick_thread, NULL); + al_destroy_thread(wiz_joystick_thread); + _al_event_source_free(&joy.es); +} + +static int joywiz_get_num_joysticks(void) +{ + return 1; +} + +static ALLEGRO_JOYSTICK *joywiz_get_joystick(int num) +{ + (void)num; /* Only 1 supported now */ + return &joy; +} + +static void joywiz_release_joystick(ALLEGRO_JOYSTICK *joy) +{ + (void)joy; +} + +static void joywiz_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + _al_event_source_lock(&joy->es); + { + *ret_state = joystate; + } + _al_event_source_unlock(&joy->es); +} + + + +/* the driver vtable */ +ALLEGRO_JOYSTICK_DRIVER _al_joydrv_gp2xwiz = +{ + AL_JOY_TYPE_GP2XWIZ, + "", + "", + "GP2X Wiz joystick", + joywiz_init_joystick, + joywiz_exit_joystick, + joywiz_get_num_joysticks, + joywiz_get_joystick, + joywiz_release_joystick, + joywiz_get_joystick_state +}; + + diff --git a/allegro/src/gp2xwiz/wiz_system.c b/allegro/src/gp2xwiz/wiz_system.c new file mode 100644 index 00000000..941ec722 --- /dev/null +++ b/allegro/src/gp2xwiz/wiz_system.c @@ -0,0 +1,177 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * GP2X Wiz system driver + * + * By Trent Gamblin. + * + */ + +#include + +#include "allegro5/allegro.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/internal/aintern_gp2xwiz.h" +#include "allegro5/platform/aintwiz.h" + +static ALLEGRO_SYSTEM_INTERFACE *gp2xwiz_vt; + +static ALLEGRO_SYSTEM *gp2xwiz_initialize(int flags) +{ + ALLEGRO_SYSTEM_GP2XWIZ *s; + + (void)flags; + + _al_unix_init_time(); + + s = al_calloc(1, sizeof *s); + + _al_vector_init(&s->system.displays, sizeof (ALLEGRO_DISPLAY *)); + + s->system.vt = gp2xwiz_vt; + + return &s->system; +} + +static void gp2xwiz_shutdown_system(void) +{ + /* Close all open displays. */ + ALLEGRO_SYSTEM *s = al_get_system_driver(); + ALLEGRO_SYSTEM_GP2XWIZ *sx = (void *)s; + + while (_al_vector_size(&s->displays) > 0) { + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); + ALLEGRO_DISPLAY *d = *dptr; + al_destroy_display(d); + } + _al_vector_free(&s->displays); + + al_free(sx); + + lc_exit(); + +} + +static ALLEGRO_DISPLAY_INTERFACE *gp2xwiz_get_display_driver(void) +{ + if (al_get_new_display_flags() & ALLEGRO_OPENGL) + return _al_display_gp2xwiz_opengl_driver(); + else + return _al_display_gp2xwiz_framebuffer_driver(); +} + +static ALLEGRO_KEYBOARD_DRIVER *gp2xwiz_get_keyboard_driver(void) +{ + //return _al_gp2xwiz_keyboard_driver; + return NULL; +} + +static ALLEGRO_MOUSE_DRIVER *gp2xwiz_get_mouse_driver(void) +{ + //return _al_gp2xwiz_mouse_driver; + return NULL; +} + +static ALLEGRO_JOYSTICK_DRIVER *gp2xwiz_get_joystick_driver(void) +{ + return _al_joystick_driver_list[0].driver; +} + +static int gp2xwiz_get_num_video_adapters(void) +{ + return 1; +} + +static bool gp2xwiz_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +{ + (void)adapter; + info->x1 = 0; + info->y1 = 0; + info->x2 = 320; + info->y2 = 240; + return true; +} + +// FIXME +static bool gp2xwiz_get_cursor_position(int *ret_x, int *ret_y) +{ + *ret_x = 0; + *ret_y = 0; + return true; +} + +static bool gp2xwiz_inhibit_screensaver(bool inhibit) +{ + (void)inhibit; + return false; +} + + +static int gp2xwiz_get_num_display_modes(void) +{ + return 1; +} + + +static ALLEGRO_DISPLAY_MODE *gp2xwiz_get_display_mode(int index, + ALLEGRO_DISPLAY_MODE *mode) +{ + (void)index; + ASSERT(index == 0); + mode->width = 320; + mode->height = 240; + mode->format = ALLEGRO_PIXEL_FORMAT_RGB_565; + mode->refresh_rate = 60; + return mode; +} + + +/* Internal function to get a reference to this driver. */ +ALLEGRO_SYSTEM_INTERFACE *_al_system_gp2xwiz_driver(void) +{ + if (gp2xwiz_vt) + return gp2xwiz_vt; + + gp2xwiz_vt = al_calloc(1, sizeof *gp2xwiz_vt); + + gp2xwiz_vt->id = ALLEGRO_SYSTEM_ID_GP2XWIZ; + gp2xwiz_vt->initialize = gp2xwiz_initialize; + gp2xwiz_vt->get_display_driver = gp2xwiz_get_display_driver; + gp2xwiz_vt->get_keyboard_driver = gp2xwiz_get_keyboard_driver; + gp2xwiz_vt->get_mouse_driver = gp2xwiz_get_mouse_driver; + gp2xwiz_vt->get_joystick_driver = gp2xwiz_get_joystick_driver; + gp2xwiz_vt->get_num_display_modes = gp2xwiz_get_num_display_modes; + gp2xwiz_vt->get_display_mode = gp2xwiz_get_display_mode; + gp2xwiz_vt->shutdown_system = gp2xwiz_shutdown_system; + gp2xwiz_vt->get_num_video_adapters = gp2xwiz_get_num_video_adapters; + gp2xwiz_vt->get_monitor_info = gp2xwiz_get_monitor_info; + gp2xwiz_vt->get_cursor_position = gp2xwiz_get_cursor_position; + gp2xwiz_vt->get_path = _al_unix_get_path; + gp2xwiz_vt->inhibit_screensaver = gp2xwiz_inhibit_screensaver; + gp2xwiz_vt->get_num_display_formats = gp2xwiz_get_num_display_formats; + gp2xwiz_vt->get_time = _al_unix_get_time; + gp2xwiz_vt->rest = _al_unix_rest; + gp2xwiz_vt->init_timeout = _al_unix_init_timeout; + + return gp2xwiz_vt; +} + +/* This is a function each platform must define to register all available + * system drivers. + */ +void _al_register_system_interfaces(void) +{ + ALLEGRO_SYSTEM_INTERFACE **add; + + add = _al_vector_alloc_back(&_al_system_interfaces); + *add = _al_system_gp2xwiz_driver(); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/haptic.c b/allegro/src/haptic.c new file mode 100644 index 00000000..ed23f140 --- /dev/null +++ b/allegro/src/haptic.c @@ -0,0 +1,394 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Haptic API. + * + * By Beoran. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/haptic.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_haptic.h" +#include "allegro5/internal/aintern_system.h" + + +/* the active haptic driver */ +static ALLEGRO_HAPTIC_DRIVER *haptic_driver = NULL; + + +/* Function: al_install_haptic + */ +bool al_install_haptic(void) +{ + ALLEGRO_SYSTEM *sysdrv; + ALLEGRO_HAPTIC_DRIVER *hapdrv; + + if (haptic_driver) + return true; + + sysdrv = al_get_system_driver(); + ASSERT(sysdrv); + + /* Currently every platform only has at most one haptic driver. */ + if (sysdrv->vt->get_haptic_driver) { + hapdrv = sysdrv->vt->get_haptic_driver(); + /* Avoid race condition in case the haptic driver generates an + * event right after ->init_haptic. + */ + if (hapdrv && hapdrv->init_haptic()) { + haptic_driver = hapdrv; + _al_add_exit_func(al_uninstall_haptic, "al_uninstall_haptic"); + return true; + } + } + + return false; +} + + +/* Function: al_uninstall_haptic + */ +void al_uninstall_haptic(void) +{ + if (haptic_driver) { + /* perform driver clean up */ + haptic_driver->exit_haptic(); + haptic_driver = NULL; + } +} + + +/* Function: al_is_haptic_installed + */ +bool al_is_haptic_installed(void) +{ + return (haptic_driver) ? true : false; +} + + +/* Function: al_is_joystick_haptic + */ +bool al_is_joystick_haptic(ALLEGRO_JOYSTICK *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->is_joystick_haptic(dev); +} + + +/* Function: al_is_mouse_haptic + */ +bool al_is_mouse_haptic(ALLEGRO_MOUSE *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->is_mouse_haptic(dev); +} + + +/* Function: al_is_keyboard_haptic + */ +bool al_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->is_keyboard_haptic(dev); +} + + +/* Function: al_is_display_haptic + */ +bool al_is_display_haptic(ALLEGRO_DISPLAY *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->is_display_haptic(dev); +} + +/* Function: al_is_touch_input_haptic + */ +bool al_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->is_touch_input_haptic(dev); +} + +/* Function: al_get_haptic_from_joystick + */ +ALLEGRO_HAPTIC *al_get_haptic_from_joystick(ALLEGRO_JOYSTICK *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->get_from_joystick(dev); +} + + +/* Function: al_get_haptic_from_mouse + */ +ALLEGRO_HAPTIC *al_get_haptic_from_mouse(ALLEGRO_MOUSE *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->get_from_mouse(dev); +} + + +/* Function: al_get_haptic_from_keyboard + */ +ALLEGRO_HAPTIC *al_get_haptic_from_keyboard(ALLEGRO_KEYBOARD *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->get_from_keyboard(dev); +} + + +/* Function: al_get_haptic_from_display + */ +ALLEGRO_HAPTIC *al_get_haptic_from_display(ALLEGRO_DISPLAY *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->get_from_display(dev); +} + + +/* Function: al_get_haptic_from_touch_input + */ +ALLEGRO_HAPTIC *al_get_haptic_from_touch_input(ALLEGRO_TOUCH_INPUT *dev) +{ + ASSERT(dev); + ASSERT(haptic_driver); + + return haptic_driver->get_from_touch_input(dev); +} + + +/* Function: al_is_haptic_active + */ +bool al_is_haptic_active(ALLEGRO_HAPTIC *hap) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->get_active(hap); +} + + +/* Function: al_get_haptic_capabilities + */ +int al_get_haptic_capabilities(ALLEGRO_HAPTIC *hap) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->get_capabilities(hap); +} + +/* Function: al_is_haptic_capable + */ +bool al_is_haptic_capable(ALLEGRO_HAPTIC * hap, int query) { + int capabilities = al_get_haptic_capabilities(hap); + return (capabilities & query) == query; +} + +/* Function: al_get_haptic_gain + */ +double al_get_haptic_gain(ALLEGRO_HAPTIC *hap) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->get_gain(hap); +} + + +/* Function: al_set_haptic_gain + */ +bool al_set_haptic_gain(ALLEGRO_HAPTIC *hap, double gain) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->set_gain(hap, gain); +} + +/* Function: al_get_haptic_autocenter + */ +double al_get_haptic_autocenter(ALLEGRO_HAPTIC *hap) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->get_autocenter(hap); +} + + +/* Function: al_set_haptic_autocenter + */ +bool al_set_haptic_autocenter(ALLEGRO_HAPTIC *hap, double intensity) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->set_autocenter(hap, intensity); +} + + + +/* Function: al_get_max_haptic_effects + */ +int al_get_max_haptic_effects(ALLEGRO_HAPTIC *hap) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->get_max_effects(hap); +} + + +/* Function: al_is_haptic_effect_ok + */ +bool al_is_haptic_effect_ok(ALLEGRO_HAPTIC *hap, ALLEGRO_HAPTIC_EFFECT *effect) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->is_effect_ok(hap, effect); +} + + +/* Function: al_upload_haptic_effect + */ +bool al_upload_haptic_effect(ALLEGRO_HAPTIC *hap, + ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ASSERT(hap); + ASSERT(haptic_driver); + + return haptic_driver->upload_effect(hap, effect, id); +} + + +/* Function: al_play_haptic_effect + */ +bool al_play_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop) +{ + ASSERT(haptic_driver); + ASSERT(id); + + return haptic_driver->play_effect(id, loop); +} + + +/* Function: al_upload_and_play_haptic_effect + */ +bool al_upload_and_play_haptic_effect(ALLEGRO_HAPTIC *hap, + ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id, int loop) +{ + ASSERT(hap); + ASSERT(effect); + ASSERT(id); + + if (!al_upload_haptic_effect(hap, effect, id)) + return false; + /* If playing the effect failed, unload the haptic effect automatically + */ + if (!al_play_haptic_effect(id, loop)) { + al_release_haptic_effect(id); + return false; + } + return true; +} + + +/* Function: al_stop_haptic_effect + */ +bool al_stop_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ASSERT(id); + + return haptic_driver->stop_effect(id); +} + + +/* Function: al_is_haptic_effect_playing + */ +bool al_is_haptic_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ASSERT(id); + + return haptic_driver->is_effect_playing(id); +} + +/* Function: al_get_haptic_effect_duration + */ +double al_get_haptic_effect_duration(ALLEGRO_HAPTIC_EFFECT * effect) +{ + return effect->replay.delay + effect->replay.length; +} + +/* Function: al_rumble_haptic + */ +bool al_rumble_haptic(ALLEGRO_HAPTIC *hap, + double intensity, double duration, ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_EFFECT effect; + ASSERT(hap); + ASSERT(id); + + effect.type = ALLEGRO_HAPTIC_RUMBLE; + effect.data.rumble.strong_magnitude = intensity; + effect.data.rumble.weak_magnitude = intensity; + effect.replay.delay = 0.0; + effect.replay.length = duration; + return al_upload_and_play_haptic_effect(hap, &effect, id, 1); +} + + +/* Function: al_release_haptic_effect + */ +bool al_release_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ASSERT(haptic_driver); + ASSERT(id); + + return haptic_driver->release_effect(id); +} + + +/* Function: al_release_haptic + */ +bool al_release_haptic(ALLEGRO_HAPTIC *haptic) +{ + ASSERT(haptic_driver); + ASSERT(haptic); + + return haptic_driver->release(haptic); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/inline.c b/allegro/src/inline.c new file mode 100644 index 00000000..6237d2e8 --- /dev/null +++ b/allegro/src/inline.c @@ -0,0 +1,42 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Copies of the inline functions in allegro.h, in case anyone needs + * to take the address of them, or is compiling without optimisation. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/platform/alplatf.h" + +// apple's cross-compiler already adds the symbols for the "extern __inline__" +// declared variants, so the ones here are duplicates and the linker dies +#ifndef ALLEGRO_IPHONE + +#define AL_INLINE(type, name, args, code) \ + extern type name args; \ + type name args code + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" + +#ifdef ALLEGRO_INTERNAL_HEADER + #include ALLEGRO_INTERNAL_HEADER +#endif + +/* not used now */ +/* #include "allegro5/internal/aintern_atomicops.h" */ + +#include "allegro5/internal/aintern_float.h" +#include "allegro5/internal/aintern_vector.h" + +#endif diff --git a/allegro/src/iphone/EAGLView.h b/allegro/src/iphone/EAGLView.h new file mode 100644 index 00000000..5fd8a2fd --- /dev/null +++ b/allegro/src/iphone/EAGLView.h @@ -0,0 +1,51 @@ +#import +#import +#import +#import +#include +#include +#include + +/* +This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. +The view content is basically an EAGL surface you render your OpenGL scene into. +Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. +*/ +@interface EAGLView : UIView { + +@private + EAGLContext *context; + ALLEGRO_DISPLAY *allegro_display; + + /* OpenGL names for the renderbuffer and framebuffers used to render to this view */ + GLuint viewRenderbuffer, viewFramebuffer; + + /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */ + GLuint depthRenderbuffer; + + /* Stuff for managing ID's for touches. List held struct which connect UITouch with ID on Allegro site. + * NSMutableIndexSet hold list of free id's which were used. 'next_free_touch_id' hold next unused ID. + * + * 'touch_list' serve actuall as dictionary which map UITouch do ID. + */ + _AL_LIST* touch_list; + NSMutableIndexSet* touch_id_set; + UITouch* primary_touch; + int next_free_touch_id; + + float scale; +} + +@property (nonatomic, retain) EAGLContext *context; +@property GLint backingWidth; +@property GLint backingHeight; + + +- (void)make_current; +- (void)flip; +- (void)reset_framebuffer; +- (void)set_allegro_display:(ALLEGRO_DISPLAY *)display; +- (BOOL) createFramebuffer; +- (void) destroyFramebuffer; +- (BOOL)orientation_supported:(UIInterfaceOrientation)o; +@end diff --git a/allegro/src/iphone/EAGLView.m b/allegro/src/iphone/EAGLView.m new file mode 100644 index 00000000..ae0218be --- /dev/null +++ b/allegro/src/iphone/EAGLView.m @@ -0,0 +1,395 @@ +#import +#import + +#import "EAGLView.h" +#import "allegroAppDelegate.h" +#include +#include + +#include "allegro5/allegro_iphone.h" +#include "allegro5/internal/aintern_iphone.h" + +ALLEGRO_DEBUG_CHANNEL("iphone") + +typedef struct touch_t +{ + int id; + UITouch* touch; +} touch_t; + +/* Every UITouch have associated touch_t structure. This destructor + * is used in list which held touch information. While ending touch it will + * be called and memory will be freed. + */ +static void touch_item_dtor(void* value, void* userdata) +{ + (void)userdata; + al_free(value); +} + +/* Search for touch_t associated with UITouch. + */ +static touch_t* find_touch(_AL_LIST* list, UITouch* nativeTouch) +{ + _AL_LIST_ITEM* item; + + for (item = _al_list_front(list); item; item = _al_list_next(list, item)) { + + touch_t* touch = (touch_t*)_al_list_item_data(item); + + if (touch->touch == nativeTouch) + return touch; + } + + return NULL; +} + +@implementation EAGLView + +@synthesize context; +@synthesize backingWidth; +@synthesize backingHeight; + + +// You must implement this method ++ (Class)layerClass { + return [CAEAGLLayer class]; +} + +- (void)set_allegro_display:(ALLEGRO_DISPLAY *)display { + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)display; + + allegro_display = display; + + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + NSString *color_format = kEAGLColorFormatRGBA8; + if (display->extra_settings.settings[ALLEGRO_COLOR_SIZE] == 16) + color_format = kEAGLColorFormatRGB565; + + eaglLayer.opaque = YES; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, + color_format, kEAGLDrawablePropertyColorFormat, nil]; + + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + ALLEGRO_INFO("Attempting to create ES2 context\n"); + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + if (context == nil) { + ALLEGRO_WARN("ES2 context could not be created. Attempting to create ES1 context instead.\n"); + display->flags &= ~ ALLEGRO_PROGRAMMABLE_PIPELINE; + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + } + } + else { + ALLEGRO_INFO("Attempting to create ES1 context.\n"); + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + } + + ALLEGRO_INFO("Context is %p\n", context); + + if (!context || ![EAGLContext setCurrentContext:context]) { + ALLEGRO_ERROR("context is nil or setCurrentContext failed.\n"); + [self release]; + return; + } + + /* FIXME: Make this depend on a display setting. */ + [self setMultipleTouchEnabled:YES]; + + + ALLEGRO_INFO("Created EAGLView.\n"); +} + +- (id)initWithFrame:(CGRect)frame { + + ALLEGRO_DEBUG("Creating UIView.\n"); + + self = [super initWithFrame:frame]; + + touch_list = _al_list_create(); + + primary_touch = NULL; + + touch_id_set = [[NSMutableIndexSet alloc] init]; + next_free_touch_id = 1; + + return self; +} + +- (void)make_current { + [EAGLContext setCurrentContext:context]; + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); +} + +- (void)reset_framebuffer { + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); +} + +- (void)flip { + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + +- (void)send_resize_event { + ALLEGRO_DISPLAY *display = allegro_display; + + int x = self.frame.origin.x; + int y = self.frame.origin.y; + int w = self.frame.size.width; + int h = self.frame.size.height; + + _al_event_source_lock(&display->es); + if (_al_event_source_needs_to_generate_event(&display->es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; + event.display.timestamp = al_get_time(); + event.display.x = x; + event.display.y = y; + event.display.width = w; + event.display.height = h; + event.display.orientation = _al_iphone_get_orientation(display); + _al_event_source_emit_event(&display->es, &event); + } + _al_event_source_unlock(&display->es); +} + +- (void)layoutSubviews { + [EAGLContext setCurrentContext:context]; + if (!viewRenderbuffer) { + [self createFramebuffer]; + /* Depending on the orientation, the initial framebuffer dimensions may be + * rotated so we need to update them. For example + * a call to al_create_display(480, 640) will create a display of + * 640x480 pixels in landscape mode. + */ + allegro_display->w = backingWidth; + allegro_display->h = backingHeight; + } + [self send_resize_event]; +} + +- (BOOL)orientation_supported:(UIInterfaceOrientation) o { + if (!allegro_display) return NO; + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)allegro_display; + if (d->extra->adapter != 0) return NO; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *options = &allegro_display->extra_settings; + int supported = options->settings[ALLEGRO_SUPPORTED_ORIENTATIONS]; + if (o == UIInterfaceOrientationPortrait) return supported & ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES; + if (o == UIInterfaceOrientationLandscapeLeft) return supported & ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES; + if (o == UIInterfaceOrientationPortraitUpsideDown) return supported & ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES; + if (o == UIInterfaceOrientationLandscapeRight) return supported & ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES; + return NO; +} + +- (BOOL)createFramebuffer { + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)allegro_display; + + if (d->extra->adapter == 0 && [self respondsToSelector:@selector(contentScaleFactor)]) { + scale = self.contentScaleFactor = [[UIScreen mainScreen] scale]; + ALLEGRO_INFO("Screen scale is %f\n", self.contentScaleFactor); + } + else { + scale = 1.0f; + } + + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer]; + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + ALLEGRO_INFO("Creating GL framebuffer %dx%d.\n", backingWidth, backingHeight); + + if (allegro_display->extra_settings.settings[ALLEGRO_DEPTH_SIZE]) { + GLint depth_stencil_format; + if (allegro_display->extra_settings.settings[ALLEGRO_STENCIL_SIZE]) { + depth_stencil_format = GL_DEPTH24_STENCIL8_OES; + } + else { + depth_stencil_format = GL_DEPTH_COMPONENT16_OES; + } + glGenRenderbuffersOES(1, &depthRenderbuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); + glRenderbufferStorageOES(GL_RENDERBUFFER_OES, depth_stencil_format, backingWidth, backingHeight); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); + if (allegro_display->extra_settings.settings[ALLEGRO_STENCIL_SIZE]) { + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); + } + } + + if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { + NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + return YES; +} + + +- (void)destroyFramebuffer { + + glDeleteFramebuffersOES(1, &viewFramebuffer); + viewFramebuffer = 0; + glDeleteRenderbuffersOES(1, &viewRenderbuffer); + viewRenderbuffer = 0; + + if (depthRenderbuffer) { + glDeleteRenderbuffersOES(1, &depthRenderbuffer); + depthRenderbuffer = 0; + } +} + +- (void)dealloc { + if (touch_list) + _al_list_destroy(touch_list); + + [touch_id_set release]; + + if ([EAGLContext currentContext] == context) { + [EAGLContext setCurrentContext:nil]; + } + + [context release]; + [super dealloc]; +} + +/* Handling of touch events. */ + +-(NSArray*)getSortedTouches:(NSSet*)touches +{ + NSArray* unsorted = [NSArray arrayWithArray: [touches allObjects]]; + NSArray* sorted = [unsorted sortedArrayUsingComparator: ^(id obj1, id obj2) + { + if ([obj1 timestamp] > [obj2 timestamp]) + return (NSComparisonResult)NSOrderedDescending; + else if ([obj1 timestamp] < [obj2 timestamp]) + return (NSComparisonResult)NSOrderedAscending; + else + return (NSComparisonResult)NSOrderedSame; + }]; + return sorted; +} + +// Handles the start of a touch +-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + (void)event; + + // TODO: handle double-clicks (send two events?) + // NSUInteger numTaps = [[touches anyObject] tapCount]; + // Enumerate through all the touch objects. + + for (UITouch *nativeTouch in touches) { + /* Create new touch_t and associate ID with UITouch. */ + touch_t* touch = al_malloc(sizeof(touch_t)); + + touch->touch = nativeTouch; + + if ([touch_id_set count] != 0) { + touch->id = [touch_id_set firstIndex]; + [touch_id_set removeIndex:touch->id]; + } + else + touch->id = next_free_touch_id++; + + _al_list_push_back_ex(touch_list, touch, touch_item_dtor); + + CGPoint p = [nativeTouch locationInView:[nativeTouch view]]; + + if (NULL == primary_touch) + primary_touch = nativeTouch; + + _al_iphone_touch_input_handle_begin(touch->id, al_get_time(), + p.x*scale, p.y*scale, primary_touch == nativeTouch, allegro_display); + } +} + +// Handles the continuation of a touch. +-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + (void)event; + + touch_t* touch; + + // Enumerates through all touch objects + for (UITouch *nativeTouch in touches) { + if ((touch = find_touch(touch_list, nativeTouch))) { + + CGPoint p = [nativeTouch locationInView:[nativeTouch view]]; + + _al_iphone_touch_input_handle_move(touch->id, al_get_time(), + p.x*scale, p.y*scale, primary_touch == nativeTouch, allegro_display); + } + } +} + +// Handles the end of a touch event. +-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + (void)event; + + touch_t* touch; + + // Enumerates through all touch objects + for (UITouch *nativeTouch in touches) { + if ((touch = find_touch(touch_list, nativeTouch))) { + + CGPoint p = [nativeTouch locationInView:[nativeTouch view]]; + + _al_iphone_touch_input_handle_end(touch->id, al_get_time(), + p.x*scale, p.y*scale, primary_touch == nativeTouch, allegro_display); + + [touch_id_set addIndex:touch->id]; + _al_list_remove(touch_list, touch); + + if (primary_touch == nativeTouch) + primary_touch = NULL; + } + } +} + +// Quoting Apple docs: +// "The system cancelled tracking for the touch, as when (for example) the user +// puts the device to his or her face." +-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + (void)event; + + touch_t* touch; + + // Enumerates through all touch objects + for (UITouch *nativeTouch in touches) { + if ((touch = find_touch(touch_list, nativeTouch))) { + + CGPoint p = [nativeTouch locationInView:[nativeTouch view]]; + + _al_iphone_touch_input_handle_cancel(touch->id, al_get_time(), + p.x*scale, p.y*scale, primary_touch == nativeTouch, allegro_display); + + if (primary_touch == nativeTouch) + primary_touch = NULL; + + [touch_id_set addIndex:touch->id]; + _al_list_remove(touch_list, touch); + } + } +} + +-(BOOL)canBecomeFirstResponder { + return YES; +} + +-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ + (void)motion; +} + +@end + diff --git a/allegro/src/iphone/ViewController.h b/allegro/src/iphone/ViewController.h new file mode 100644 index 00000000..71da38fc --- /dev/null +++ b/allegro/src/iphone/ViewController.h @@ -0,0 +1,14 @@ +#import + +struct ALLEGRO_DISPLAY; + +@interface ViewController : UIViewController +{ +@public + int adapter; + struct ALLEGRO_DISPLAY *display; +} + +- (void) create_view; + +@end diff --git a/allegro/src/iphone/ViewController.m b/allegro/src/iphone/ViewController.m new file mode 100644 index 00000000..d5c8f3cc --- /dev/null +++ b/allegro/src/iphone/ViewController.m @@ -0,0 +1,125 @@ +#import "ViewController.h" +#import "EAGLView.h" +#import + +#include "allegroAppDelegate.h" + +ALLEGRO_DEBUG_CHANNEL("iphone"); + +@implementation ViewController + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; +} + +- (void)loadView +{ +} + +- (void)viewDidLoad +{ + ALLEGRO_DEBUG("Loading view controller.\n"); + display = NULL; +} + +- (void)viewDidUnload +{ + [super viewDidUnload]; +} + +- (BOOL)shouldAutorotate +{ + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)display; + if (display == NULL) + return YES; + if (d->extra->adapter != 0) { + return NO; + } + return YES; +} + +/* Taken from Apple docs + */ +/* +typedef enum { + UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait), + UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft), + UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight), + UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown), + UIInterfaceOrientationMaskLandscape = + (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight), + UIInterfaceOrientationMaskAll = + (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | + UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown), + UIInterfaceOrientationMaskAllButUpsideDown = + (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | + UIInterfaceOrientationMaskLandscapeRight), +} UIInterfaceOrientationMask; +*/ + +- (NSUInteger)supportedInterfaceOrientations +{ + if (!display) return UIInterfaceOrientationMaskAll; + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)display; + if (d->extra->adapter != 0) return UIInterfaceOrientationMaskAll; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *options = &display->extra_settings; + int supported = options->settings[ALLEGRO_SUPPORTED_ORIENTATIONS]; + int mask = 0; + + switch (supported) { + default: + case ALLEGRO_DISPLAY_ORIENTATION_ALL: + mask = UIInterfaceOrientationMaskAll; + break; + case ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT: + mask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; + break; + case ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE: + mask = UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight; + break; + case ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES: + mask = UIInterfaceOrientationMaskPortrait; + break; + case ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES: + mask = UIInterfaceOrientationMaskLandscapeRight; + break; + case ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES: + mask = UIInterfaceOrientationMaskPortraitUpsideDown; + break; + case ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES: + mask = UIInterfaceOrientationMaskLandscapeLeft; + break; + } + + return mask; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)display; + if (display == NULL) + return YES; + if (d->extra->adapter != 0) { + return NO; + } + EAGLView *view = (EAGLView *)al_iphone_get_view(display); + if (view) { + return [view orientation_supported:interfaceOrientation]; + } + return NO; +} + +- (void) create_view +{ + UIScreen *screen; + + if (adapter == 0) + screen = [UIScreen mainScreen]; + else + screen = [[UIScreen screens] objectAtIndex:adapter]; + self.view = [[EAGLView alloc] initWithFrame:[screen bounds]]; + [self.view release]; +} + +@end diff --git a/allegro/src/iphone/allegroAppDelegate.h b/allegro/src/iphone/allegroAppDelegate.h new file mode 100644 index 00000000..424a0439 --- /dev/null +++ b/allegro/src/iphone/allegroAppDelegate.h @@ -0,0 +1,28 @@ +#import +#include +#import "ViewController.h" + +struct ALLEGRO_DISPLAY_IPHONE_EXTRA { + bool failed; + ViewController *vc; + UIWindow *window; + int adapter; + bool disconnected; +}; + +@class EAGLView; + +@interface allegroAppDelegate : NSObject { +@public + ALLEGRO_DISPLAY *main_display; +} + ++ (void)run:(int)argc:(char **)argv; +- (void)add_view:(NSValue *)value; +- (void)orientation_change:(NSNotification *)notification; +- (void)setupScreenConnectionNotificationHandlers; +- (void)add_screen:(UIScreen *)screen; + +@end + diff --git a/allegro/src/iphone/allegroAppDelegate.m b/allegro/src/iphone/allegroAppDelegate.m new file mode 100644 index 00000000..003ffe12 --- /dev/null +++ b/allegro/src/iphone/allegroAppDelegate.m @@ -0,0 +1,720 @@ +#import "allegroAppDelegate.h" +#import "EAGLView.h" + +#import +#include + +#include "allegro5/allegro_opengl.h" +#include "allegro5/allegro_iphone.h" +#include "allegro5/internal/aintern_opengl.h" + +ALLEGRO_DEBUG_CHANNEL("iphone") + +void _al_iphone_run_user_main(void); + +static allegroAppDelegate *global_delegate; +static UIApplication *app = NULL; +static volatile bool waiting_for_program_halt = false; +static bool disconnect_wait = false; +static UIScreen *airplay_screen = NULL; +static bool airplay_connected = false; + +ALLEGRO_MUTEX *_al_iphone_display_hotplug_mutex = NULL; + +/* Screen handling */ +@interface iphone_screen : NSObject +{ +@public + int adapter; + UIScreen *screen; + UIWindow *window; + ViewController *vc; + EAGLView *view; + ALLEGRO_DISPLAY *display; +} +@end + +@implementation iphone_screen +@end + +void _al_iphone_disconnect(ALLEGRO_DISPLAY *display) +{ + (void)display; + + disconnect_wait = false; +} + +static NSMutableArray *iphone_screens; + +static int iphone_get_adapter(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)display; + return d->extra->adapter; +} + +static iphone_screen *iphone_get_screen_by_adapter(int adapter) +{ + al_lock_mutex(_al_iphone_display_hotplug_mutex); + + int num = [iphone_screens count]; + int i; + iphone_screen *ret = NULL; + + for (i = 0; i < num; i++) { + iphone_screen *scr = [iphone_screens objectAtIndex:i]; + if (scr->adapter == adapter) { + ret = scr; + break; + } + } + + al_unlock_mutex(_al_iphone_display_hotplug_mutex); + return ret; +} + +static iphone_screen *iphone_get_screen(ALLEGRO_DISPLAY *display) +{ + int adapter = iphone_get_adapter(display); + return iphone_get_screen_by_adapter(adapter); +} + +bool _al_iphone_is_display_connected(ALLEGRO_DISPLAY *display) +{ + iphone_screen *scr = iphone_get_screen(display); + return scr && (scr->display == display); +} + +static void iphone_remove_screen(UIScreen *screen) +{ + al_lock_mutex(_al_iphone_display_hotplug_mutex); + + int num_screens = [iphone_screens count]; + int i; + + for (i = 1; i < num_screens; i++) { + iphone_screen *scr = iphone_get_screen_by_adapter(i); + if (scr->screen == screen) { + [iphone_screens removeObjectAtIndex:i]; + [scr release]; + break; + } + } + + al_unlock_mutex(_al_iphone_display_hotplug_mutex); +} + +void _al_iphone_destroy_screen(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)display; + + if (d->extra->adapter == 0) { + global_delegate->main_display = NULL; + } + + al_free(d->extra); +} + +// create iphone_screen for all currently attached screens +static void iphone_create_screens(void) +{ + iphone_screens = [[NSMutableArray alloc] init]; + + _al_iphone_display_hotplug_mutex = al_create_mutex_recursive(); + + if ([UIScreen respondsToSelector:NSSelectorFromString(@"screens")]) { + int num_screens; + int i; + + num_screens = [[UIScreen screens] count];; + for (i = 0; i < num_screens && i < 2; i++) { + if (i == 1) { + airplay_screen = [[UIScreen screens] objectAtIndex:i]; + continue; + } + [global_delegate add_screen:[[UIScreen screens] objectAtIndex:i]]; + } + } + else { + [global_delegate add_screen:[UIScreen mainScreen]]; + } +} + +/* Function: al_iphone_get_window + */ +UIWindow *al_iphone_get_window(ALLEGRO_DISPLAY *display) +{ + al_lock_mutex(_al_iphone_display_hotplug_mutex); + iphone_screen *scr = iphone_get_screen(display); + if (scr == NULL) { + al_unlock_mutex(_al_iphone_display_hotplug_mutex); + return NULL; + } + al_unlock_mutex(_al_iphone_display_hotplug_mutex); + return scr->window; +} + +/* Function: al_iphone_get_view + */ +UIView *al_iphone_get_view(ALLEGRO_DISPLAY *display) +{ + iphone_screen *scr = iphone_get_screen(display); + if (scr == NULL) { + return NULL; + } + return scr->vc.view; +} + +static int iphone_orientation_to_allegro(UIDeviceOrientation orientation) +{ + switch (orientation) { + case UIDeviceOrientationPortrait: + return ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES; + + case UIDeviceOrientationPortraitUpsideDown: + return ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES; + + case UIDeviceOrientationLandscapeRight: + return ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES; + + case UIDeviceOrientationLandscapeLeft: + return ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES; + + case UIDeviceOrientationFaceUp: + return ALLEGRO_DISPLAY_ORIENTATION_FACE_UP; + + case UIDeviceOrientationFaceDown: + return ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN; + + default: + return ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN; + } +} + +static void iphone_send_orientation_event(ALLEGRO_DISPLAY* display, int orientation) +{ + _al_event_source_lock(&display->es); + if (_al_event_source_needs_to_generate_event(&display->es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_ORIENTATION; + event.display.timestamp = al_get_time(); + event.display.source = display; + event.display.orientation = orientation; + _al_event_source_emit_event(&display->es, &event); + } + _al_event_source_unlock(&display->es); +} + + +void _al_iphone_acknowledge_drawing_halt(ALLEGRO_DISPLAY *display) +{ + (void)display; + waiting_for_program_halt = false; +} + +/* Function: al_iphone_set_statusbar_orientation + */ +void al_iphone_set_statusbar_orientation(int o) +{ + UIInterfaceOrientation orientation = UIInterfaceOrientationPortrait; + + if (o == ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT) + orientation = UIInterfaceOrientationPortrait; + else if (o == ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT_UPSIDE_DOWN) + orientation = UIInterfaceOrientationPortraitUpsideDown; + else if (o == ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_RIGHT) + orientation = UIInterfaceOrientationLandscapeRight; + else if (o == ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_LEFT) + orientation = UIInterfaceOrientationLandscapeLeft; + + [app setStatusBarOrientation:orientation animated:NO]; +} + +bool _al_iphone_add_view(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_IPHONE *d = (ALLEGRO_DISPLAY_IPHONE *)display; + + d->extra = al_calloc(1, sizeof(ALLEGRO_DISPLAY_IPHONE_EXTRA)); + int adapter = al_get_new_display_adapter(); + if (adapter < 0) + adapter = 0; + d->extra->adapter = adapter; + + /* This is the same as + * [global_delegate.view add_view]; + * except it will run in the main thread. + */ + [global_delegate performSelectorOnMainThread: @selector(add_view:) + withObject: [NSValue valueWithPointer:display] + waitUntilDone: YES]; + + if (d->extra->failed) { + return false; + } + + /* There are two ways to get orientation information under ios - but they seem + * to be mutually exclusive (just my experience, the documentation never says + * they are). + * One method has 6 orientations including face up and face down and is + * independent of the screen orientations, just directly using the accelerometer + * to determine how the device is positioned relative to gravity. The other + * method has 4 orientations and simply tells how the view controller thinks + * the user interface should be rotated. + * + * Supporting both at the same time is a) slightly confusing since we'd need + * two sets of query functions and events and b) does not seem to work due to + * the mutual exclusivity. + * + * Now normally using just the 4-orientation way would appear to be the best + * choice as you can always use the accelerometer anyway to get the actual + * 3d orientation and otherwise are likely more concerned with the orientation + * things are being displayed at right now (instead of just seeing FACE_UP which + * would not tell you). + * + * But to stay compatible with how things worked at first we still support the + * 6-orientations way as well - but only if the display has a sole supported + * orientation of ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES. + */ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *options = &display->extra_settings; + int supported = options->settings[ALLEGRO_SUPPORTED_ORIENTATIONS]; + if (supported == ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES) { + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + } + + return true; +} + +void _al_iphone_make_view_current(ALLEGRO_DISPLAY *display) +{ + iphone_screen *scr = iphone_get_screen(display); + if (scr) + [scr->view make_current]; +} + +void _al_iphone_recreate_framebuffer(ALLEGRO_DISPLAY *display) +{ + iphone_screen *scr = iphone_get_screen(display); + if (scr) { + EAGLView *view = scr->view; + [view destroyFramebuffer]; + [view createFramebuffer]; + display->w = view.backingWidth; + display->h = view.backingHeight; + _al_ogl_resize_backbuffer(display->ogl_extras->backbuffer, display->w, display->h); + } +} + +void _al_iphone_flip_view(ALLEGRO_DISPLAY *display) +{ + iphone_screen *scr = iphone_get_screen(display); + if (scr) + [scr->view flip]; +} + +void _al_iphone_reset_framebuffer(ALLEGRO_DISPLAY *display) +{ + iphone_screen *scr = iphone_get_screen(display); + if (scr) + [scr->view reset_framebuffer]; +} + +/* Use a frequency to start receiving events at the freuqency, 0 to shut off + * the accelerometer (according to Apple, it drains a bit of battery while on). + */ +void _al_iphone_accelerometer_control(int frequency) +{ + if (frequency) { + [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / frequency)]; + [[UIAccelerometer sharedAccelerometer] setDelegate:global_delegate]; + } + else { + [[UIAccelerometer sharedAccelerometer] setDelegate:nil]; + } +} + +int _al_iphone_get_num_video_adapters(void) +{ + if (![UIScreen respondsToSelector:NSSelectorFromString(@"screens")]) { + return 1; + } + return [[UIScreen screens] count]; +} + +void _al_iphone_get_screen_size(int adapter, int *w, int *h) +{ + iphone_screen *scr = iphone_get_screen_by_adapter(adapter); + UIScreen *screen = scr->screen; + + if (NULL != screen) { + + CGRect bounds = [screen bounds]; + CGFloat scale = 1.0f; + + if (adapter == 0 && [screen respondsToSelector:NSSelectorFromString(@"scale")]) { + scale = [screen scale]; + } + + *w = (int)(bounds.size.width * scale); + *h = (int)(bounds.size.height * scale); + } + else { + + ASSERT("You should never see this message, unless Apple changed their policy and allows for removing screens from iDevices." && false); + } +} + +int _al_iphone_get_orientation(ALLEGRO_DISPLAY *display) +{ + if (display) { + ALLEGRO_EXTRA_DISPLAY_SETTINGS *options = &display->extra_settings; + int supported = options->settings[ALLEGRO_SUPPORTED_ORIENTATIONS]; + if (supported != ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES) { + iphone_screen *scr = iphone_get_screen(display); + UIInterfaceOrientation o = scr->vc.interfaceOrientation; + UIDeviceOrientation od = (int)o; /* They are compatible. */ + return iphone_orientation_to_allegro(od); + } + } + + UIDevice* device = [UIDevice currentDevice]; + + if (NULL != device) + return iphone_orientation_to_allegro([device orientation]); + else + return ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN; +} + +@implementation allegroAppDelegate + ++ (void)run:(int)argc:(char **)argv { + UIApplicationMain(argc, argv, nil, @"allegroAppDelegate"); +} + +- (void)orientation_change:(NSNotification *)notification +{ + (void)notification; + + int orientation = _al_iphone_get_orientation(NULL); + + if (main_display == NULL) + return; + + iphone_send_orientation_event(main_display, orientation); +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + ALLEGRO_INFO("App launched.\n"); + + global_delegate = self; + app = application; + + iphone_create_screens(); + + // Register for device orientation notifications + // Note: The notifications won't be generated unless they are enabled, which + // we do elsewhere. + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientation_change:) + name:UIDeviceOrientationDidChangeNotification object:nil]; + + // Register for screen connect/disconnect notifications + [self setupScreenConnectionNotificationHandlers]; + + _al_iphone_run_user_main(); +} + +/* This may never get called on iOS 4 */ +- (void)applicationWillTerminate:(UIApplication *)application { + (void)application; + ALLEGRO_EVENT event; + ALLEGRO_DISPLAY *d = main_display; + ALLEGRO_SYSTEM_IPHONE *iphone = (void *)al_get_system_driver(); + iphone->wants_shutdown = true; + + ALLEGRO_INFO("Terminating.\n"); + + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + + _al_event_source_lock(&d->es); + + if (_al_event_source_needs_to_generate_event(&d->es)) { + event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; + event.display.timestamp = al_get_time(); + _al_event_source_emit_event(&d->es, &event); + } + _al_event_source_unlock(&d->es); + + /* When this method returns, the application terminates - so lets wait a bit + * so the user app can shutdown properly, e.g. to save state as is usually + * required by iphone apps. + */ + _al_iphone_await_termination(); +} + +- (void)applicationWillResignActive:(UIApplication *)application { + ALLEGRO_DISPLAY *d = main_display; + ALLEGRO_EVENT event; + + (void)application; + + ALLEGRO_INFO("Application becoming inactive.\n"); + + _al_event_source_lock(&d->es); + if (_al_event_source_needs_to_generate_event(&d->es)) { + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; + event.display.timestamp = al_current_time(); + _al_event_source_emit_event(&d->es, &event); + } + _al_event_source_unlock(&d->es); +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + ALLEGRO_DISPLAY *d = main_display; + ALLEGRO_EVENT event; + + (void)application; + + ALLEGRO_INFO("Application becoming active.\n"); + + if (!d) + return; + + _al_event_source_lock(&d->es); + if (_al_event_source_needs_to_generate_event(&d->es)) { + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; + event.display.timestamp = al_current_time(); + _al_event_source_emit_event(&d->es, &event); + } + _al_event_source_unlock(&d->es); +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + ALLEGRO_DISPLAY *d = main_display; + ALLEGRO_EVENT event; + + (void)application; + + ALLEGRO_INFO("Application entering background.\n"); + + waiting_for_program_halt = true; + + _al_event_source_lock(&d->es); + if (_al_event_source_needs_to_generate_event(&d->es)) { + event.display.type = ALLEGRO_EVENT_DISPLAY_HALT_DRAWING; + event.display.timestamp = al_current_time(); + _al_event_source_emit_event(&d->es, &event); + } + _al_event_source_unlock(&d->es); + + while (waiting_for_program_halt) { + // do nothing, this should be quick + al_rest(0.001); + } +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + ALLEGRO_DISPLAY *d = main_display; + ALLEGRO_EVENT event; + + (void)application; + + ALLEGRO_INFO("Application coming back to foreground.\n"); + + _al_event_source_lock(&d->es); + if (_al_event_source_needs_to_generate_event(&d->es)) { + event.display.type = ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING; + event.display.timestamp = al_current_time(); + _al_event_source_emit_event(&d->es, &event); + } + _al_event_source_unlock(&d->es); +} + +/* Note: This must be called from the main thread. Ask Apple why - but I tried + * it and otherwise things simply don't work (the screen just stays black). + */ +- (void)add_view:(NSValue *)value { + ALLEGRO_DISPLAY *d = [value pointerValue]; + ALLEGRO_DISPLAY_IPHONE *disp = (ALLEGRO_DISPLAY_IPHONE *)d; + + int adapter = iphone_get_adapter(d); + if (adapter == 0) { + main_display = d; + } + + iphone_screen *scr = iphone_get_screen_by_adapter(adapter); + + scr->display = d; + + ViewController *vc = scr->vc; + vc->display = d; + EAGLView *view = (EAGLView *)vc.view; + [view set_allegro_display:d]; + + [scr->window addSubview:view]; + + if (adapter == 0) { + [view becomeFirstResponder]; + [scr->window makeKeyAndVisible]; + } + else { + scr->window.hidden = NO; + } + + disp->extra->failed = false; + disp->extra->vc = vc; + disp->extra->window = scr->window; +} + +- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration +{ + (void)accelerometer; + _al_iphone_generate_joystick_event(acceleration.x, acceleration.y, acceleration.z); +} + +- (void)setupScreenConnectionNotificationHandlers +{ + /* Screen connect/disconnect notifications were added in iOS 3.2 */ + NSString *reqSysVer = @"3.2"; + NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; + BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending); + + if (osVersionSupported) { + NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; + + [center addObserver:self selector:@selector(handleScreenConnectNotification:) + name:UIScreenDidConnectNotification object:nil]; + [center addObserver:self selector:@selector(handleScreenDisconnectNotification:) + name:UIScreenDidDisconnectNotification object:nil]; + } +} + +- (void)handleScreenConnectNotification:(NSNotification*)aNotification +{ + airplay_screen = [aNotification object]; + + ALLEGRO_DISPLAY *display = main_display; + + if (!display) return; + + _al_event_source_lock(&display->es); + if (_al_event_source_needs_to_generate_event(&display->es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_CONNECTED; + event.display.timestamp = al_get_time(); + event.display.source = display; + _al_event_source_emit_event(&display->es, &event); + } + _al_event_source_unlock(&display->es); +} + +- (void)handleScreenDisconnectNotification:(NSNotification*)aNotification +{ + ALLEGRO_DISPLAY *display = main_display; + ALLEGRO_DISPLAY_IPHONE *idisplay = (ALLEGRO_DISPLAY_IPHONE *)display; + ALLEGRO_DISPLAY_IPHONE_EXTRA *extra; + + if (!display) return; + + extra = idisplay->extra; + extra->disconnected = true; + + disconnect_wait = true; + + _al_event_source_lock(&display->es); + if (_al_event_source_needs_to_generate_event(&display->es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_DISCONNECTED; + event.display.timestamp = al_get_time(); + event.display.source = display; + _al_event_source_emit_event(&display->es, &event); + } + _al_event_source_unlock(&display->es); + + if (airplay_connected) { + // wait for user to destroy display + while (disconnect_wait) + al_rest(0.001); + + iphone_remove_screen([aNotification object]); + airplay_connected = false; + } +} + +- (void)dealloc { + [super dealloc]; +} + +- (void)add_screen:(UIScreen *)screen +{ + int i; + + if (screen == [UIScreen mainScreen]) { + i = 0; + } + else { + for (i = 0; i < (int)[[UIScreen screens] count]; i++) { + if ([[UIScreen screens] objectAtIndex:i] == screen) + break; + } + } + + if (i != 0) { + if ([screen respondsToSelector:NSSelectorFromString(@"availableModes")]) { + NSArray *a = [screen availableModes]; + int j; + UIScreenMode *largest = NULL; + for (j = 0; j < (int)[a count]; j++) { + UIScreenMode *m = [a objectAtIndex:j]; + float w = m.size.width; + float h = m.size.height; + if ((largest == NULL) || (w+h > largest.size.width+largest.size.height)) { + largest = m; + } + } + if (largest) { + screen.currentMode = largest; + } + } + } + + iphone_screen *scr = iphone_get_screen_by_adapter(i); + bool add = scr == NULL; + + UIWindow *window = [[UIWindow alloc] initWithFrame:[screen bounds]]; + if ([window respondsToSelector:NSSelectorFromString(@"screen")]) { + window.screen = screen; + } + + ViewController *vc = [[ViewController alloc] init]; + vc->adapter = i; + [vc create_view]; + // Doesn't work on iOS < 4. + NSString *reqSysVer = @"4.0"; + NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; + BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending); + if (osVersionSupported) { + window.rootViewController = vc; + } + + if (add) + scr = [[iphone_screen alloc] init]; + + scr->adapter = i; + scr->screen = screen; + scr->window = window; + scr->vc = vc; + scr->view = (EAGLView *)vc.view; + scr->display = NULL; + + if (add) { + al_lock_mutex(_al_iphone_display_hotplug_mutex); + [iphone_screens addObject:scr]; + al_unlock_mutex(_al_iphone_display_hotplug_mutex); + } +} + +@end + +void _al_iphone_connect_airplay(void) +{ + [global_delegate performSelectorOnMainThread: @selector(add_screen:) withObject:airplay_screen waitUntilDone:TRUE]; + airplay_connected = true; +} diff --git a/allegro/src/iphone/iphone.h b/allegro/src/iphone/iphone.h new file mode 100644 index 00000000..ac733023 --- /dev/null +++ b/allegro/src/iphone/iphone.h @@ -0,0 +1,6 @@ +#ifndef __al_included_iphone_h +#define __al_included_iphone_h + +void _al_iphone_acknowledge_drawing_halt(ALLEGRO_DISPLAY *display); + +#endif diff --git a/allegro/src/iphone/iphone_clipboard.m b/allegro/src/iphone/iphone_clipboard.m new file mode 100644 index 00000000..8ab60ef1 --- /dev/null +++ b/allegro/src/iphone/iphone_clipboard.m @@ -0,0 +1,85 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * MacOS X clipboard handling. + * + * By Beoran. + * + * See readme.txt for copyright information. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "iphone.h" +#include "allegroAppDelegate.h" +#include + +ALLEGRO_DEBUG_CHANNEL("iphone") + +#ifndef ALLEGRO_IPHONE +#error Something is wrong with the makefile +#endif + +/* Ensure that we have the right version number available. */ +#ifndef NSAppKitVersionNumber10_6 +#define NSAppKitVersionNumber10_6 1038 +#endif + + +static char *iphone_get_clipboard_text(ALLEGRO_DISPLAY *display) +{ + const char *utf8; + NSString *pbtext; + size_t size; + char *text; + + pbtext = [[UIPasteboard generalPasteboard] string]; + if (pbtext == nil) + return NULL; + + utf8 = [pbtext UTF8String]; + size = strlen(utf8); + text = al_malloc(size+1); + text = _al_sane_strncpy(text, utf8, size+1); + + return text; +} + +static bool iphone_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text) +{ + NSData *data = [NSData dataWithBytes:text length:strlen(text)]; + [[UIPasteboard generalPasteboard] setData:data forPasteboardType:(NSString *)kUTTypeUTF8PlainText]; + return true; +} + +static bool iphone_has_clipboard_text(ALLEGRO_DISPLAY *display) +{ + NSString *pbtext; + + pbtext = [[UIPasteboard generalPasteboard] string]; + + return (pbtext != nil); +} + +void _al_iphone_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt) +{ + vt->set_clipboard_text = iphone_set_clipboard_text; + vt->get_clipboard_text = iphone_get_clipboard_text; + vt->has_clipboard_text = iphone_has_clipboard_text; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/iphone/iphone_display.m b/allegro/src/iphone/iphone_display.m new file mode 100644 index 00000000..59f3024d --- /dev/null +++ b/allegro/src/iphone/iphone_display.m @@ -0,0 +1,455 @@ +#include +#include +#include +#include +#include +#include + +#include "iphone.h" +#include "allegroAppDelegate.h" + +ALLEGRO_DEBUG_CHANNEL("iphone") + +static ALLEGRO_DISPLAY_INTERFACE *vt; + +static float _screen_iscale = 1.0; +static float _screen_x, _screen_y; +static float _screen_w, _screen_h; +static bool _screen_hack; + +bool _al_iphone_is_display_connected(ALLEGRO_DISPLAY *display); +void _al_iphone_connect_airplay(void); +extern ALLEGRO_MUTEX *_al_iphone_display_hotplug_mutex; + +void _al_iphone_setup_opengl_view(ALLEGRO_DISPLAY *d, bool manage_backbuffer) +{ + int w, h; + + w = d->w; + h = d->h; + + _al_iphone_reset_framebuffer(d); + + _screen_w = w; + _screen_h = h; + + if (manage_backbuffer) { + _al_ogl_setup_gl(d); + } +} + +void _al_iphone_translate_from_screen(ALLEGRO_DISPLAY *d, int *x, int *y) +{ + if (!_screen_hack) return; + // See _al_iphone_setup_opengl_view + float ox = *x, oy = *y; + + if (d->w >= d->h) { + *x = _screen_x + oy * _screen_iscale; + *y = _screen_y + (_screen_w - ox) * _screen_iscale; + } + else { + // TODO + } +} + +void _al_iphone_clip(ALLEGRO_BITMAP const *bitmap, int x_1, int y_1, int x_2, int y_2) +{ + ALLEGRO_BITMAP *oglb = (void *)(bitmap->parent ? bitmap->parent : bitmap); + int h = oglb->h; + glScissor(x_1, h - y_2, x_2 - x_1, y_2 - y_1); +} + +static void set_rgba8888(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) +{ + eds->settings[ALLEGRO_RED_SIZE] = 8; + eds->settings[ALLEGRO_GREEN_SIZE] = 8; + eds->settings[ALLEGRO_BLUE_SIZE] = 8; + eds->settings[ALLEGRO_ALPHA_SIZE] = 8; + eds->settings[ALLEGRO_RED_SHIFT] = 0; + eds->settings[ALLEGRO_GREEN_SHIFT] = 8; + eds->settings[ALLEGRO_BLUE_SHIFT] = 16; + eds->settings[ALLEGRO_ALPHA_SHIFT] = 24; + eds->settings[ALLEGRO_COLOR_SIZE] = 32; +} + +static void set_rgb565(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) +{ + eds->settings[ALLEGRO_RED_SIZE] = 5; + eds->settings[ALLEGRO_GREEN_SIZE] = 6; + eds->settings[ALLEGRO_BLUE_SIZE] = 5; + eds->settings[ALLEGRO_ALPHA_SIZE] = 0; + eds->settings[ALLEGRO_RED_SHIFT] = 0; + eds->settings[ALLEGRO_GREEN_SHIFT] = 5; + eds->settings[ALLEGRO_BLUE_SHIFT] = 11; + eds->settings[ALLEGRO_ALPHA_SHIFT] = 0; + eds->settings[ALLEGRO_COLOR_SIZE] = 16; +} + +#define VISUALS_COUNT 6 +void _al_iphone_update_visuals(void) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; + ALLEGRO_SYSTEM_IPHONE *system = (void *)al_get_system_driver(); + + ref = _al_get_new_display_settings(); + + /* If we aren't called the first time, only updated scores. */ + if (system->visuals) { + for (int i = 0; i < system->visuals_count; i++) { + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = system->visuals[i]; + eds->score = _al_score_display_settings(eds, ref); + } + return; + } + + system->visuals = al_calloc(1, VISUALS_COUNT * sizeof(*system->visuals)); + system->visuals_count = VISUALS_COUNT; + + for (int i = 0; i < VISUALS_COUNT; i++) { + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = al_calloc(1, sizeof *eds); + eds->settings[ALLEGRO_RENDER_METHOD] = 1; + eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; + eds->settings[ALLEGRO_SWAP_METHOD] = 2; + eds->settings[ALLEGRO_VSYNC] = 1; + eds->settings[ALLEGRO_SUPPORTED_ORIENTATIONS] = + ref->settings[ALLEGRO_SUPPORTED_ORIENTATIONS]; + switch (i) { + case 0: + set_rgba8888(eds); + break; + case 1: + set_rgb565(eds); + break; + case 2: + set_rgba8888(eds); + eds->settings[ALLEGRO_DEPTH_SIZE] = 16; + break; + case 3: + set_rgb565(eds); + eds->settings[ALLEGRO_DEPTH_SIZE] = 16; + break; + case 4: + set_rgba8888(eds); + eds->settings[ALLEGRO_DEPTH_SIZE] = 24; + eds->settings[ALLEGRO_STENCIL_SIZE] = 8; + break; + case 5: + set_rgb565(eds); + eds->settings[ALLEGRO_DEPTH_SIZE] = 24; + eds->settings[ALLEGRO_STENCIL_SIZE] = 8; + break; + + } + eds->score = _al_score_display_settings(eds, ref); + eds->index = i; + system->visuals[i] = eds; + } +} + +static ALLEGRO_DISPLAY *iphone_create_display(int w, int h) +{ + ALLEGRO_DISPLAY_IPHONE *d = al_calloc(1, sizeof *d); + ALLEGRO_DISPLAY *display = (void*)d; + ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl); + display->ogl_extras = ogl; + display->vt = _al_get_iphone_display_interface(); + display->flags = al_get_new_display_flags(); + int adapter; + + adapter = al_get_new_display_adapter(); + if (adapter < 0) + adapter = 0; + + if (adapter == 1) { + _al_iphone_connect_airplay(); + } + + if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) { + _al_iphone_get_screen_size(adapter, &w, &h); + } + + display->w = w; + display->h = h; + + ALLEGRO_SYSTEM_IPHONE *system = (void *)al_get_system_driver(); + + /* Add ourself to the list of displays. */ + ALLEGRO_DISPLAY_IPHONE **add; + add = _al_vector_alloc_back(&system->system.displays); + *add = d; + + /* Each display is an event source. */ + _al_event_source_init(&display->es); + + _al_iphone_update_visuals(); + + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds[system->visuals_count]; + memcpy(eds, system->visuals, sizeof(*eds) * system->visuals_count); + qsort(eds, system->visuals_count, sizeof(*eds), _al_display_settings_sorter); + + ALLEGRO_INFO("Chose visual no. %i\n", eds[0]->index); + + memcpy(&display->extra_settings, eds[0], sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); + + display->flags |= ALLEGRO_OPENGL; +#ifdef ALLEGRO_CFG_OPENGLES2 + display->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + display->flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + + /* This will add an OpenGL view with an OpenGL context, then return. */ + if (!_al_iphone_add_view(display)) { + /* FIXME: cleanup */ + return NULL; + } + + _al_iphone_make_view_current(display); + + /* FIXME: there is some sort of race condition somewhere. */ + al_rest(1.0); + + _al_ogl_manage_extensions(display); + _al_ogl_set_extensions(ogl->extension_api); + _al_iphone_setup_opengl_view(display, true); + + int ndisplays = system->system.displays._size; + [[UIApplication sharedApplication] setIdleTimerDisabled:(ndisplays > 1)]; + + /* Fill in opengl version */ + const int v = display->ogl_extras->ogl_info.version; + display->extra_settings.settings[ALLEGRO_OPENGL_MAJOR_VERSION] = (v >> 24) & 0xFF; + display->extra_settings.settings[ALLEGRO_OPENGL_MINOR_VERSION] = (v >> 16) & 0xFF; + + return display; +} + +static void iphone_destroy_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_IPHONE *idisplay = (ALLEGRO_DISPLAY_IPHONE *)d; + ALLEGRO_DISPLAY_IPHONE_EXTRA *extra = idisplay->extra; + bool disconnected = extra->disconnected; + + _al_set_current_display_only(d); + + while (d->bitmaps._size > 0) { + ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref_back(&d->bitmaps); + ALLEGRO_BITMAP *b = *bptr; + _al_convert_to_memory_bitmap(b); + } + + _al_event_source_free(&d->es); + _al_iphone_destroy_screen(d); + + if (disconnected) { + _al_iphone_disconnect(d); + } + + ALLEGRO_SYSTEM_IPHONE *system = (void *)al_get_system_driver(); + _al_vector_find_and_delete(&system->system.displays, &d); + + [[UIApplication sharedApplication] setIdleTimerDisabled:FALSE]; +} + +static bool iphone_set_current_display(ALLEGRO_DISPLAY *d) +{ + (void)d; + _al_iphone_make_view_current(d); + _al_ogl_update_render_state(d); + return true; +} + +static int iphone_get_orientation(ALLEGRO_DISPLAY *d) +{ + return _al_iphone_get_orientation(d); +} + + +/* There can be only one window and only one OpenGL context, so all bitmaps + * are compatible. + */ +static bool iphone_is_compatible_bitmap(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap) +{ + (void)display; + (void)bitmap; + return true; +} + +/* Resizing is not possible. */ +static bool iphone_resize_display(ALLEGRO_DISPLAY *d, int w, int h) +{ + (void)d; + (void)w; + (void)h; + return false; +} + +/* The icon must be provided in the Info.plist file, it cannot be changed + * at runtime. + */ +static void iphone_set_icons(ALLEGRO_DISPLAY *d, int num_icons, ALLEGRO_BITMAP *bitmaps[]) +{ + (void)d; + (void)num_icons; + (void)bitmaps; +} + +/* There is no way to leave fullscreen so no window title is visible. */ +static void iphone_set_window_title(ALLEGRO_DISPLAY *display, char const *title) +{ + (void)display; + (void)title; +} + +/* The window always spans the entire screen right now. */ +static void iphone_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +{ + (void)display; + (void)x; + (void)y; +} + +/* The window cannot be constrained. */ +static bool iphone_set_window_constraints(ALLEGRO_DISPLAY *display, + int min_w, int min_h, int max_w, int max_h) +{ + (void)display; + (void)min_w; + (void)min_h; + (void)max_w; + (void)max_h; + return false; +} + +/* Always fullscreen. */ +static bool iphone_set_display_flag(ALLEGRO_DISPLAY *display, + int flag, bool onoff) +{ + (void)display; + (void)flag; + (void)onoff; + return false; +} + +static void iphone_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + (void)display; + *x = 0; + *y = 0; +} + +/* The window cannot be constrained. */ +static bool iphone_get_window_constraints(ALLEGRO_DISPLAY *display, + int *min_w, int *min_h, int *max_w, int *max_h) +{ + (void)display; + (void)min_w; + (void)min_h; + (void)max_w; + (void)max_h; + return false; +} + +static bool iphone_wait_for_vsync(ALLEGRO_DISPLAY *display) +{ + (void)display; + return false; +} + +static void iphone_flip_display(ALLEGRO_DISPLAY *d) +{ + _al_iphone_flip_view(d); +} + +static void iphone_update_display_region(ALLEGRO_DISPLAY *d, int x, int y, + int w, int h) +{ + (void)x; + (void)y; + (void)w; + (void)h; + iphone_flip_display(d); +} + +static bool iphone_acknowledge_resize(ALLEGRO_DISPLAY *d) +{ + _al_iphone_recreate_framebuffer(d); + _al_iphone_setup_opengl_view(d, true); + return true; +} + +static bool iphone_set_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_MOUSE_CURSOR *cursor) +{ + (void)display; + (void)cursor; + return false; +} + +static bool iphone_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +{ + (void)display; + (void)cursor_id; + return false; +} + +static bool iphone_show_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + (void)display; + return false; +} + +static bool iphone_hide_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + (void)display; + return false; +} + +/* Obtain a reference to this driver. */ +ALLEGRO_DISPLAY_INTERFACE *_al_get_iphone_display_interface(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + + vt->create_display = iphone_create_display; + vt->destroy_display = iphone_destroy_display; + vt->set_current_display = iphone_set_current_display; + vt->flip_display = iphone_flip_display; + vt->update_display_region = iphone_update_display_region; + vt->acknowledge_resize = iphone_acknowledge_resize; + vt->create_bitmap = _al_ogl_create_bitmap; + vt->get_backbuffer = _al_ogl_get_backbuffer; + vt->set_target_bitmap = _al_ogl_set_target_bitmap; + + vt->get_orientation = iphone_get_orientation; + + vt->is_compatible_bitmap = iphone_is_compatible_bitmap; + vt->resize_display = iphone_resize_display; + vt->set_icons = iphone_set_icons; + vt->set_window_title = iphone_set_window_title; + vt->set_window_position = iphone_set_window_position; + vt->get_window_position = iphone_get_window_position; + vt->set_window_constraints = iphone_set_window_constraints; + vt->get_window_constraints = iphone_get_window_constraints; + vt->set_display_flag = iphone_set_display_flag; + vt->wait_for_vsync = iphone_wait_for_vsync; + + vt->set_mouse_cursor = iphone_set_mouse_cursor; + vt->set_system_mouse_cursor = iphone_set_system_mouse_cursor; + vt->show_mouse_cursor = iphone_show_mouse_cursor; + vt->hide_mouse_cursor = iphone_hide_mouse_cursor; + + vt->acknowledge_drawing_halt = _al_iphone_acknowledge_drawing_halt; + vt->update_render_state = _al_ogl_update_render_state; + + _al_ogl_add_drawing_functions(vt); + _al_iphone_add_clipboard_functions(vt); + + return vt; +} diff --git a/allegro/src/iphone/iphone_joystick.m b/allegro/src/iphone/iphone_joystick.m new file mode 100644 index 00000000..2f142849 --- /dev/null +++ b/allegro/src/iphone/iphone_joystick.m @@ -0,0 +1,143 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_iphone.h" + +ALLEGRO_DEBUG_CHANNEL("iphone") + +typedef struct ALLEGRO_JOYSTICK_IPHONE { + ALLEGRO_JOYSTICK parent; + ALLEGRO_JOYSTICK_STATE joystate; +} ALLEGRO_JOYSTICK_IPHONE; + +static ALLEGRO_JOYSTICK_IPHONE the_joystick; +static bool initialized; + +static bool ijoy_init_joystick(void) +{ + ALLEGRO_JOYSTICK_IPHONE *ijoy; + ALLEGRO_JOYSTICK *joy; + + ijoy = &the_joystick; + + memset(ijoy, 0, sizeof *ijoy); + joy = (void *)ijoy; + + /* Fill in the joystick information fields. */ + joy->info.num_sticks = 1; + joy->info.num_buttons = 0; + joy->info.stick[0].name = "Accelerometer"; + joy->info.stick[0].num_axes = 3; + joy->info.stick[0].axis[0].name = "X"; + joy->info.stick[0].axis[1].name = "Y"; + joy->info.stick[0].axis[2].name = "Z"; + joy->info.stick[0].flags = ALLEGRO_JOYFLAG_ANALOGUE; + + // TODO: What's a good frequency to use here? + _al_iphone_accelerometer_control(60); + initialized = true; + + return true; +} + +static void ijoy_exit_joystick(void) +{ + _al_iphone_accelerometer_control(0); + initialized = false; +} + +static bool ijoy_reconfigure_joysticks(void) +{ + return false; +} + +static int ijoy_num_joysticks(void) +{ + return 1; +} + +static ALLEGRO_JOYSTICK *ijoy_get_joystick(int num) +{ + if (num != 0) + return NULL; + + ALLEGRO_DEBUG("Joystick %d acquired.\n", num); + + return &the_joystick.parent; +} + +static void ijoy_release_joystick(ALLEGRO_JOYSTICK *joy) +{ + (void)joy; + ALLEGRO_DEBUG("Joystick released.\n"); + initialized = false; +} + +static void ijoy_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + ALLEGRO_JOYSTICK_IPHONE *ijoy = (void *)joy; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + _al_event_source_lock(es); + *ret_state = ijoy->joystate; + _al_event_source_unlock(es); +} + +void _al_iphone_generate_joystick_event(float x, float y, float z) +{ + if (!initialized) + return; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + ALLEGRO_EVENT event; + + _al_event_source_lock(es); + + if (_al_event_source_needs_to_generate_event(es)) { + float pos[] = {x, y, z}; + for (int i = 0; i < 3; i++) { + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.timestamp = al_get_time(); + event.joystick.stick = 0; + event.joystick.axis = i; + event.joystick.pos = pos[i]; + event.joystick.button = 0; + _al_event_source_emit_event(es, &event); + } + } + _al_event_source_unlock(es); +} + +static char const *ijoy_get_name(ALLEGRO_JOYSTICK *joy) +{ + (void)joy; + return "Accelerometer"; +} + +static bool ijoy_get_active(ALLEGRO_JOYSTICK *joy) +{ + (void)joy; + return true; +} + +static ALLEGRO_JOYSTICK_DRIVER iphone_joystick_driver = { + AL_ID('I', 'P', 'H', 'O'), + "", + "", + "iphone joystick", + ijoy_init_joystick, + ijoy_exit_joystick, + ijoy_reconfigure_joysticks, + ijoy_num_joysticks, + ijoy_get_joystick, + ijoy_release_joystick, + ijoy_get_joystick_state, + ijoy_get_name, + ijoy_get_active +}; + +ALLEGRO_JOYSTICK_DRIVER *_al_get_iphone_joystick_driver(void) +{ + return &iphone_joystick_driver; +} diff --git a/allegro/src/iphone/iphone_keyboard.c b/allegro/src/iphone/iphone_keyboard.c new file mode 100644 index 00000000..80675972 --- /dev/null +++ b/allegro/src/iphone/iphone_keyboard.c @@ -0,0 +1,64 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/internal/aintern_events.h" + +static ALLEGRO_KEYBOARD the_keyboard; + +static bool iphone_init_keyboard(void) +{ + memset(&the_keyboard, 0, sizeof the_keyboard); + _al_event_source_init(&the_keyboard.es); + return true; +} + +static void iphone_exit_keyboard(void) +{ + _al_event_source_free(&the_keyboard.es); +} + + +static ALLEGRO_KEYBOARD *iphone_get_keyboard(void) +{ + return &the_keyboard; +} + +static bool iphone_set_keyboard_leds(int leds) +{ + (void)leds; + return false; +} + +static char const *iphone_keycode_to_name(int keycode) +{ + (void)keycode; + return "none"; +} + +static void iphone_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) +{ + memset(ret_state, 0, sizeof *ret_state); +} + +static void iphone_clear_keyboard_state(void) +{ + return; +} + +static ALLEGRO_KEYBOARD_DRIVER iphone_keyboard_driver = { + AL_ID('I','P','H','O'), + "", + "", + "iphone keyboard", + iphone_init_keyboard, + iphone_exit_keyboard, + iphone_get_keyboard, + iphone_set_keyboard_leds, + iphone_keycode_to_name, + iphone_get_keyboard_state, + iphone_clear_keyboard_state +}; + +ALLEGRO_KEYBOARD_DRIVER *_al_get_iphone_keyboard_driver(void) +{ + return &iphone_keyboard_driver; +} diff --git a/allegro/src/iphone/iphone_main.m b/allegro/src/iphone/iphone_main.m new file mode 100644 index 00000000..204fb7f4 --- /dev/null +++ b/allegro/src/iphone/iphone_main.m @@ -0,0 +1,66 @@ +#import +#import "allegroAppDelegate.h" +#include +#include +#include + +ALLEGRO_DEBUG_CHANNEL("iphone") + +/* Not that there could ever be any arguments on iphone... */ +static int global_argc; +static char **global_argv; +extern int _al_mangled_main(int, char **); + +/* We run the user's "main" in its own thread. */ +static void *user_main(ALLEGRO_THREAD *thread, void *arg) +{ + (void)thread; + ALLEGRO_INFO("Starting user main.\n"); + _al_mangled_main(global_argc, global_argv); + ALLEGRO_INFO("User main has returned.\n"); + ALLEGRO_SYSTEM_IPHONE *iphone = (void *)al_get_system_driver(); + al_lock_mutex(iphone->mutex); + iphone->has_shutdown = true; + al_signal_cond(iphone->cond); + al_unlock_mutex(iphone->mutex); + /* Apple does not allow iphone applications to shutdown and provides + * no API for it: + * http://developer.apple.com/iphone/library/qa/qa2008/qa1561.html + * + * Therefore we only call exit here if the user actually returned from + * there main - in that case crashing the app is better then freezing it. + */ + if (!iphone->wants_shutdown) + exit(0); /* "crash grazefully" */ + return arg; +} + +/* There really is no point running the user main before the application + * has finished launching, so this function is called back when we receive + * the applicationDidFinishLaunching message. + */ +void _al_iphone_run_user_main(void) +{ + ALLEGRO_THREAD *thread = al_create_thread(user_main, NULL); + al_start_thread(thread); +} + +void _al_iphone_init_path(void) +{ + /* On iphone, data always can only be in the resource bundle. So we set + * the initial path to that. As each app is sandboxed, there is not much + * else to access anyway. + */ + NSFileManager *fm = [NSFileManager defaultManager]; + NSBundle *mainBundle = [NSBundle mainBundle]; + NSString *string = [mainBundle resourcePath]; + [fm changeCurrentDirectoryPath:string]; +} + +int main(int argc, char **argv) { + global_argc = argc; + global_argv = argv; + [allegroAppDelegate run:argc:argv]; + ASSERT(false); /* can never reach */ + return 0; +} diff --git a/allegro/src/iphone/iphone_mouse.m b/allegro/src/iphone/iphone_mouse.m new file mode 100644 index 00000000..de29ff56 --- /dev/null +++ b/allegro/src/iphone/iphone_mouse.m @@ -0,0 +1,143 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_iphone.h" + +typedef struct ALLEGRO_MOUSE_IPHONE { + ALLEGRO_MOUSE parent; + ALLEGRO_MOUSE_STATE state; +} ALLEGRO_MOUSE_IPHONE; + +static ALLEGRO_MOUSE_IPHONE the_mouse; + +static bool imouse_installed; + +/* + * Helper to generate a mouse event. + */ +void _al_iphone_generate_mouse_event(unsigned int type, int x, int y, + unsigned int button, ALLEGRO_DISPLAY *d) +{ + ALLEGRO_EVENT event; + + _al_event_source_lock(&the_mouse.parent.es); + + _al_iphone_translate_from_screen(d, &x, &y); + + the_mouse.state.x = x; + the_mouse.state.y = y; + + if (type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { + the_mouse.state.buttons |= (1 << button); + } + else if (type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { + the_mouse.state.buttons &= ~(1 << button); + } + + the_mouse.state.pressure = the_mouse.state.buttons ? 1.0 : 0.0; // TODO + + if (_al_event_source_needs_to_generate_event(&the_mouse.parent.es)) { + event.mouse.type = type; + event.mouse.timestamp = al_get_time(); + event.mouse.display = d; + event.mouse.x = x; + event.mouse.y = y; + event.mouse.z = 0; + event.mouse.w = 0; + event.mouse.dx = 0; // TODO + event.mouse.dy = 0; // TODO + event.mouse.dz = 0; // TODO + event.mouse.dw = 0; // TODO + event.mouse.button = button; + event.mouse.pressure = the_mouse.state.pressure; + _al_event_source_emit_event(&the_mouse.parent.es, &event); + } + + _al_event_source_unlock(&the_mouse.parent.es); +} + +static void imouse_exit(void); +static bool imouse_init(void) +{ + if (imouse_installed) + imouse_exit(); + memset(&the_mouse, 0, sizeof the_mouse); + _al_event_source_init(&the_mouse.parent.es); + imouse_installed = true; + return true; +} + +static void imouse_exit(void) +{ + if (!imouse_installed) + return; + imouse_installed = false; + _al_event_source_free(&the_mouse.parent.es); +} + +static ALLEGRO_MOUSE *imouse_get_mouse(void) +{ + ASSERT(imouse_installed); + return (ALLEGRO_MOUSE *)&the_mouse; +} + +/* We report multi-touch as different buttons. */ +static unsigned int imouse_get_mouse_num_buttons(void) +{ + return 5; +} + +static unsigned int imouse_get_mouse_num_axes(void) +{ + return 2; +} + +/* Hard to accomplish on a touch screen. */ +static bool imouse_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) +{ + (void)display; + (void)x; + (void)y; + return false; +} + +static bool imouse_set_mouse_axis(int which, int z) +{ + (void)which; + (void)z; + return false; +} + +/* +static void imouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + ASSERT(imouse_installed); + + _al_event_source_lock(&the_mouse.parent.es); + { + *ret_state = the_mouse.state; + } + _al_event_source_unlock(&the_mouse.parent.es); +} +*/ +void imouse_get_state(ALLEGRO_MOUSE_STATE *ret_state); + +static ALLEGRO_MOUSE_DRIVER iphone_mouse_driver = { + AL_ID('I', 'P', 'H', 'O'), + "", + "", + "iphone mouse", + imouse_init, + imouse_exit, + imouse_get_mouse, + imouse_get_mouse_num_buttons, + imouse_get_mouse_num_axes, + imouse_set_mouse_xy, + imouse_set_mouse_axis, + imouse_get_state +}; + +ALLEGRO_MOUSE_DRIVER *_al_get_iphone_mouse_driver(void) +{ + return &iphone_mouse_driver; +} diff --git a/allegro/src/iphone/iphone_path.m b/allegro/src/iphone/iphone_path.m new file mode 100644 index 00000000..421cf73c --- /dev/null +++ b/allegro/src/iphone/iphone_path.m @@ -0,0 +1,60 @@ +#import +#include +#include + +ALLEGRO_PATH *_al_iphone_get_path(int id) +{ + char str[PATH_MAX]; + NSString *string; + NSArray *array; + NSBundle *mainBundle; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + switch (id) { + case ALLEGRO_USER_HOME_PATH: + string = NSHomeDirectory(); + break; + case ALLEGRO_TEMP_PATH: + string = NSTemporaryDirectory(); + break; + case ALLEGRO_RESOURCES_PATH: + mainBundle = [NSBundle mainBundle]; + string = [mainBundle resourcePath]; + break; + case ALLEGRO_USER_SETTINGS_PATH: + case ALLEGRO_USER_DATA_PATH: + array = NSSearchPathForDirectoriesInDomains( + NSApplicationSupportDirectory, + NSUserDomainMask, + TRUE); + string = (NSString *)[array objectAtIndex:0]; + break; + + case ALLEGRO_USER_DOCUMENTS_PATH: + array = NSSearchPathForDirectoriesInDomains( + NSDocumentDirectory, + NSUserDomainMask, + TRUE); + string = (NSString *)[array objectAtIndex:0]; + break; + case ALLEGRO_EXENAME_PATH: { + uint32_t size = sizeof(str); + if (_NSGetExecutablePath(str, &size) != 0) { + [pool drain]; + return NULL; + } + [pool drain]; + return al_create_path(str); + } + default: + [pool drain]; + return NULL; + } + + sprintf(str, "%s", [string UTF8String]); + + [pool drain]; + + return al_create_path_for_directory(str); +} diff --git a/allegro/src/iphone/iphone_system.c b/allegro/src/iphone/iphone_system.c new file mode 100644 index 00000000..e1fd1f7d --- /dev/null +++ b/allegro/src/iphone/iphone_system.c @@ -0,0 +1,114 @@ +#include +#include +#include + +ALLEGRO_DEBUG_CHANNEL("iphone") + +ALLEGRO_SYSTEM_IPHONE *iphone; +static ALLEGRO_SYSTEM_INTERFACE *vt; + +extern ALLEGRO_MUTEX *_al_iphone_display_hotplug_mutex; + +/* al_init will call this. */ +ALLEGRO_SYSTEM *iphone_initialize(int flags) +{ + (void)flags; + iphone = al_calloc(1, sizeof *iphone); + + ALLEGRO_SYSTEM *sys = &iphone->system; + + iphone->mutex = al_create_mutex(); + iphone->cond = al_create_cond(); + sys->vt = _al_get_iphone_system_interface(); + _al_vector_init(&sys->displays, sizeof (ALLEGRO_DISPLAY_IPHONE *)); + + _al_unix_init_time(); + _al_iphone_init_path(); + + return sys; +} + +static void iphone_shutdown_system(void) +{ + al_destroy_mutex(_al_iphone_display_hotplug_mutex); +} + +/* This is called from the termination message - it has to return soon as the + * user expects the app to close when it is closed. + */ +void _al_iphone_await_termination(void) +{ + ALLEGRO_INFO("Application awaiting termination.\n"); + al_lock_mutex(iphone->mutex); + while (!iphone->has_shutdown) { + al_wait_cond(iphone->cond, iphone->mutex); + } + al_unlock_mutex(iphone->mutex); +} + +static ALLEGRO_DISPLAY_INTERFACE *iphone_get_display_driver(void) +{ + return _al_get_iphone_display_interface(); +} + +static int iphone_get_num_video_adapters(void) +{ + return _al_iphone_get_num_video_adapters(); +} + +static bool iphone_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +{ + int w, h; + _al_iphone_get_screen_size(adapter, &w, &h); + info->x1 = 0; + info->y1 = 0; + info->x2 = w; + info->y2 = h; + return true; +} + +/* There is no cursor. */ +static bool iphone_get_cursor_position(int *ret_x, int *ret_y) +{ + (void)ret_x; + (void)ret_y; + return false; +} + +ALLEGRO_SYSTEM_INTERFACE *_al_get_iphone_system_interface(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + + vt->id = ALLEGRO_SYSTEM_ID_IPHONE; + vt->initialize = iphone_initialize; + vt->get_display_driver = iphone_get_display_driver; + vt->get_keyboard_driver = _al_get_iphone_keyboard_driver; + vt->get_mouse_driver = _al_get_iphone_mouse_driver; + vt->get_touch_input_driver = _al_get_iphone_touch_input_driver; + vt->get_joystick_driver = _al_get_iphone_joystick_driver; + //xglx_vt->get_num_display_modes = _al_xglx_get_num_display_modes; + //xglx_vt->get_display_mode = _al_xglx_get_display_mode; + //xglx_vt->shutdown_system = xglx_shutdown_system; + vt->shutdown_system = iphone_shutdown_system; + vt->get_num_video_adapters = iphone_get_num_video_adapters; + vt->get_monitor_info = iphone_get_monitor_info; + vt->get_cursor_position = iphone_get_cursor_position; + vt->get_path = _al_iphone_get_path; + //xglx_vt->inhibit_screensaver = xglx_inhibit_screensaver; + + return vt; +} + +/* This is a function each platform must define to register all available + * system drivers. + */ +void _al_register_system_interfaces(void) +{ + ALLEGRO_SYSTEM_INTERFACE **add; + + add = _al_vector_alloc_back(&_al_system_interfaces); + *add = _al_get_iphone_system_interface(); +} diff --git a/allegro/src/iphone/iphone_touch_input.m b/allegro/src/iphone/iphone_touch_input.m new file mode 100644 index 00000000..e57826a1 --- /dev/null +++ b/allegro/src/iphone/iphone_touch_input.m @@ -0,0 +1,326 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * iPhone family device touch input driver. + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + */ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_touch_input.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_iphone.h" + + +static ALLEGRO_TOUCH_INPUT_STATE touch_input_state; +static ALLEGRO_MOUSE_STATE mouse_state; +static ALLEGRO_TOUCH_INPUT touch_input; +static bool installed = false; + +static void generate_touch_input_event(unsigned int type, double timestamp, int id, float x, float y, float dx, float dy, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_EVENT event; + + bool want_touch_event = _al_event_source_needs_to_generate_event(&touch_input.es); + bool want_mouse_emulation_event; + + if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_5_0_x) { + want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input.mouse_emulation_es) && al_is_mouse_installed(); + } + else { + want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input.mouse_emulation_es) && primary && al_is_mouse_installed(); + } + + if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_NONE) + want_mouse_emulation_event = false; + else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_INCLUSIVE) + want_touch_event = al_is_mouse_installed() ? (want_touch_event && !primary) : want_touch_event; + else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_EXCLUSIVE) + want_touch_event = al_is_mouse_installed() ? false : want_touch_event; + + + if (!want_touch_event && !want_mouse_emulation_event) + return; + + if (want_touch_event) { + + event.touch.type = type; + event.touch.display = (ALLEGRO_DISPLAY*)disp; + event.touch.timestamp = timestamp; + event.touch.id = id; + event.touch.x = x; + event.touch.y = y; + event.touch.dx = dx; + event.touch.dy = dy; + event.touch.primary = primary; + + _al_event_source_lock(&touch_input.es); + _al_event_source_emit_event(&touch_input.es, &event); + _al_event_source_unlock(&touch_input.es); + } + + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_NONE) { + _al_event_source_lock(&touch_input.mouse_emulation_es); + if (want_mouse_emulation_event) { + + switch (type) { + case ALLEGRO_EVENT_TOUCH_BEGIN: type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; break; + case ALLEGRO_EVENT_TOUCH_CANCEL: + case ALLEGRO_EVENT_TOUCH_END: type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; break; + case ALLEGRO_EVENT_TOUCH_MOVE: type = ALLEGRO_EVENT_MOUSE_AXES; break; + } + + event.mouse.type = type; + event.mouse.timestamp = timestamp; + event.mouse.display = (ALLEGRO_DISPLAY*)disp; + event.mouse.x = (int)x; + event.mouse.y = (int)y; + event.mouse.dx = (int)dx; + event.mouse.dy = (int)dy; + event.mouse.dz = 0; + event.mouse.dw = 0; + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_5_0_x) { + event.mouse.button = 1; + } + else { + event.mouse.button = id; + } + event.mouse.pressure = 1.0; + + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_5_0_x) { + al_set_mouse_xy(event.mouse.display, event.mouse.x, event.mouse.y); + } + + _al_event_source_emit_event(&touch_input.mouse_emulation_es, &event); + } + + mouse_state.x = (int)x; + mouse_state.y = (int)y; + if (type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) + mouse_state.buttons |= id; + else if (type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) + mouse_state.buttons &= ~id; + + _al_event_source_unlock(&touch_input.mouse_emulation_es); + } +} + + +static bool init_touch_input(void) +{ + if (installed) + return false; + + memset(&touch_input_state, 0, sizeof(touch_input_state)); + memset(&mouse_state, 0, sizeof(mouse_state)); + + _al_event_source_init(&touch_input.es); + _al_event_source_init(&touch_input.mouse_emulation_es); + touch_input.mouse_emulation_mode = ALLEGRO_MOUSE_EMULATION_TRANSPARENT; + + installed = true; + + return true; +} + + +static void exit_touch_input(void) +{ + if (!installed) + return; + + memset(&touch_input_state, 0, sizeof(touch_input_state)); + memset(&mouse_state, 0, sizeof(mouse_state)); + + _al_event_source_free(&touch_input.es); + _al_event_source_free(&touch_input.mouse_emulation_es); + + installed = false; +} + + +static ALLEGRO_TOUCH_INPUT* get_touch_input(void) +{ + return &touch_input; +} + + +static void get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state) +{ + _al_event_source_lock(&touch_input.es); + *ret_state = touch_input_state; + _al_event_source_unlock(&touch_input.es); +} + + +static void set_mouse_emulation_mode(int mode) +{ + if (touch_input.mouse_emulation_mode != mode) { + + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) { + + ALLEGRO_TOUCH_STATE* touch = touch_input_state.touches + i; + + if (touch->id > 0) { + _al_iphone_touch_input_handle_cancel(touch->id, al_get_time(), + touch->x, touch->y, touch->primary, touch->display); + } + } + + touch_input.mouse_emulation_mode = mode; + } +} + + +static ALLEGRO_TOUCH_STATE* find_free_touch_state() +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) + if (touch_input_state.touches[i].id <= 0) + return touch_input_state.touches + i; + + return NULL; +} + + +static ALLEGRO_TOUCH_STATE* find_touch_state_with_id(int id) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) + if (touch_input_state.touches[i].id == id) + return touch_input_state.touches + i; + + return NULL; +} + + + +void _al_iphone_touch_input_handle_begin(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = find_free_touch_state(); + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->id = id; + state->x = x; + state->y = y; + state->dx = 0.0f; + state->dy = 0.0f; + state->primary = primary; + state->display = disp; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_BEGIN, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, disp); +} + + +void _al_iphone_touch_input_handle_end(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = find_touch_state_with_id(id); + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_END, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, disp); + + _al_event_source_lock(&touch_input.es); + memset(state, 0, sizeof(ALLEGRO_TOUCH_STATE)); + _al_event_source_unlock(&touch_input.es); +} + + +void _al_iphone_touch_input_handle_move(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = find_touch_state_with_id(id); + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_MOVE, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, disp); +} + + +void _al_iphone_touch_input_handle_cancel(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = find_touch_state_with_id(id); + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_CANCEL, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, disp); + + _al_event_source_lock(&touch_input.es); + memset(state, 0, sizeof(ALLEGRO_TOUCH_STATE)); + _al_event_source_unlock(&touch_input.es); +} + + +/* the driver vtable */ +#define TOUCH_INPUT_IPHONE AL_ID('I','T','I','D') + +static ALLEGRO_TOUCH_INPUT_DRIVER touch_input_driver = +{ + TOUCH_INPUT_IPHONE, + init_touch_input, + exit_touch_input, + get_touch_input, + get_touch_input_state, + set_mouse_emulation_mode, + NULL +}; + +ALLEGRO_TOUCH_INPUT_DRIVER *_al_get_iphone_touch_input_driver(void) +{ + return &touch_input_driver; +} + +void imouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + _al_event_source_lock(&touch_input.es); + *ret_state = mouse_state; + _al_event_source_unlock(&touch_input.es); +} + diff --git a/allegro/src/joynu.c b/allegro/src/joynu.c new file mode 100644 index 00000000..ef3ced8d --- /dev/null +++ b/allegro/src/joynu.c @@ -0,0 +1,309 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New joystick API. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +/* Title: Joystick routines + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_system.h" + + + +/* the active joystick driver */ +static ALLEGRO_JOYSTICK_DRIVER *new_joystick_driver = NULL; +static ALLEGRO_EVENT_SOURCE es; + + +/* Function: al_install_joystick + */ +bool al_install_joystick(void) +{ + ALLEGRO_SYSTEM *sysdrv; + ALLEGRO_JOYSTICK_DRIVER *joydrv; + + if (new_joystick_driver) + return true; + + sysdrv = al_get_system_driver(); + ASSERT(sysdrv); + + /* Currently every platform only has at most one joystick driver. */ + if (sysdrv->vt->get_joystick_driver) { + joydrv = sysdrv->vt->get_joystick_driver(); + /* Avoid race condition in case the joystick driver generates an + * event right after ->init_joystick. + */ + _al_event_source_init(&es); + if (joydrv && joydrv->init_joystick()) { + new_joystick_driver = joydrv; + _al_add_exit_func(al_uninstall_joystick, "al_uninstall_joystick"); + return true; + } + _al_event_source_free(&es); + } + + return false; +} + + + +/* Function: al_uninstall_joystick + */ +void al_uninstall_joystick(void) +{ + if (new_joystick_driver) { + /* perform driver clean up */ + new_joystick_driver->exit_joystick(); + _al_event_source_free(&es); + new_joystick_driver = NULL; + } +} + + + +/* Function: al_is_joystick_installed + */ +bool al_is_joystick_installed(void) +{ + return (new_joystick_driver) ? true : false; +} + + + +/* Function: al_reconfigure_joysticks + */ +bool al_reconfigure_joysticks(void) +{ + if (!new_joystick_driver) + return false; + + /* XXX only until Windows and Mac joystick drivers are updated */ + if (!new_joystick_driver->reconfigure_joysticks) { + new_joystick_driver->num_joysticks(); + return true; + } + + return new_joystick_driver->reconfigure_joysticks(); +} + + + +/* Function: al_get_joystick_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_joystick_event_source(void) +{ + if (!new_joystick_driver) + return NULL; + return &es; +} + + + +void _al_generate_joystick_event(ALLEGRO_EVENT *event) +{ + ASSERT(new_joystick_driver); + + _al_event_source_lock(&es); + if (_al_event_source_needs_to_generate_event(&es)) { + _al_event_source_emit_event(&es, event); + } + _al_event_source_unlock(&es); +} + + + +/* Function: al_get_num_joysticks + */ +int al_get_num_joysticks(void) +{ + if (new_joystick_driver) + return new_joystick_driver->num_joysticks(); + + return 0; +} + + + +/* Function: al_get_joystick + */ +ALLEGRO_JOYSTICK * al_get_joystick(int num) +{ + ASSERT(new_joystick_driver); + ASSERT(num >= 0); + + return new_joystick_driver->get_joystick(num); +} + + + +/* Function: al_release_joystick + */ +void al_release_joystick(ALLEGRO_JOYSTICK *joy) +{ + ASSERT(new_joystick_driver); + ASSERT(joy); + + new_joystick_driver->release_joystick(joy); +} + + + +/* Function: al_get_joystick_active + */ +bool al_get_joystick_active(ALLEGRO_JOYSTICK *joy) +{ + ASSERT(joy); + + return new_joystick_driver->get_active(joy); +} + + + +/* Function: al_get_joystick_name + */ +const char *al_get_joystick_name(ALLEGRO_JOYSTICK *joy) +{ + ASSERT(joy); + + return new_joystick_driver->get_name(joy); +} + + + +/* Function: al_get_joystick_num_sticks + */ +int al_get_joystick_num_sticks(ALLEGRO_JOYSTICK *joy) +{ + ASSERT(joy); + + return joy->info.num_sticks; +} + + + +/* Function: al_get_joystick_stick_flags + */ +int al_get_joystick_stick_flags(ALLEGRO_JOYSTICK *joy, int stick) +{ + ASSERT(joy); + ASSERT(stick >= 0); + + if (stick < joy->info.num_sticks) + return joy->info.stick[stick].flags; + + return 0; +} + + + +/* Function: al_get_joystick_stick_name + */ +const char *al_get_joystick_stick_name(ALLEGRO_JOYSTICK *joy, int stick) +{ + ASSERT(joy); + ASSERT(stick >= 0); + + if (stick < joy->info.num_sticks) + return joy->info.stick[stick].name; + + return NULL; +} + + + +/* Function: al_get_joystick_num_axes + */ +int al_get_joystick_num_axes(ALLEGRO_JOYSTICK *joy, int stick) +{ + ASSERT(joy); + + if (stick < joy->info.num_sticks) + return joy->info.stick[stick].num_axes; + + return 0; +} + + + +/* Function: al_get_joystick_axis_name + */ +const char *al_get_joystick_axis_name(ALLEGRO_JOYSTICK *joy, int stick, int axis) +{ + ASSERT(joy); + ASSERT(stick >= 0); + ASSERT(axis >= 0); + + if (stick < joy->info.num_sticks) + if (axis < joy->info.stick[stick].num_axes) + return joy->info.stick[stick].axis[axis].name; + + return NULL; +} + + + +/* Function: al_get_joystick_num_buttons + */ +int al_get_joystick_num_buttons(ALLEGRO_JOYSTICK *joy) +{ + ASSERT(joy); + + return joy->info.num_buttons; +} + + + +/* Function: al_get_joystick_button_name + */ +const char *al_get_joystick_button_name(ALLEGRO_JOYSTICK *joy, int button) +{ + ASSERT(joy); + ASSERT(button >= 0); + + if (button < joy->info.num_buttons) + return joy->info.button[button].name; + + return NULL; +} + + + +/* Function: al_get_joystick_state + */ +void al_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + ASSERT(new_joystick_driver); + ASSERT(joy); + ASSERT(ret_state); + + new_joystick_driver->get_joystick_state(joy, ret_state); +} + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/keybdnu.c b/allegro/src/keybdnu.c new file mode 100644 index 00000000..f4a989b5 --- /dev/null +++ b/allegro/src/keybdnu.c @@ -0,0 +1,375 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New keyboard API. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +/* Title: Keyboard routines + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/internal/aintern_system.h" + + + +/* the active keyboard driver */ +static ALLEGRO_KEYBOARD_DRIVER *new_keyboard_driver = NULL; + + +/* Provide a default naming for the most common keys. Keys whose + * mapping changes dependind on the layout aren't listed - it's up to + * the keyboard driver to do that. All keyboard drivers should + * provide their own implementation though, especially if they use + * positional mapping. + */ +const char *_al_keyboard_common_names[/* leave empty */] = +{ + "(none)", "A", "B", "C", + "D", "E", "F", "G", + "H", "I", "J", "K", + "L", "M", "N", "O", + "P", "Q", "R", "S", + "T", "U", "V", "W", + "X", "Y", "Z", "0", + "1", "2", "3", "4", + "5", "6", "7", "8", + "9", "PAD 0", "PAD 1", "PAD 2", + "PAD 3", "PAD 4", "PAD 5", "PAD 6", + "PAD 7", "PAD 8", "PAD 9", "F1", + "F2", "F3", "F4", "F5", + "F6", "F7", "F8", "F9", + "F10", "F11", "F12", "ESCAPE", + "KEY60", "KEY61", "KEY62", "BACKSPACE", + "TAB", "KEY65", "KEY66", "ENTER", + "KEY68", "KEY69", "BACKSLASH", "KEY71", + "KEY72", "KEY73", "KEY74", "SPACE", + "INSERT", "DELETE", "HOME", "END", + "PGUP", "PGDN", "LEFT", "RIGHT", + "UP", "DOWN", "PAD /", "PAD *", + "PAD -", "PAD +", "PAD DELETE", "PAD ENTER", + "PRINTSCREEN","PAUSE", "KEY94", "KEY95", + "KEY96", "KEY97", "KEY98", "KEY99", + "KEY100", "KEY101", "KEY102", "PAD =", + "KEY104", "KEY105", "KEY106", "KEY107", + "KEY108", "KEY109", "KEY110", "KEY111", + "KEY112", "KEY113", "KEY114", "KEY115", + "KEY116", "KEY117", "KEY118", "KEY119", + "KEY120", "KEY121", "KEY122", "KEY123", + "KEY124", "KEY125", "KEY126", "KEY127", + "KEY128", "KEY129", "KEY130", "KEY131", + "KEY132", "KEY133", "KEY134", "KEY135", + "KEY136", "KEY137", "KEY138", "KEY139", + "KEY140", "KEY141", "KEY142", "KEY143", + "KEY144", "KEY145", "KEY146", "KEY147", + "KEY148", "KEY149", "KEY150", "KEY151", + "KEY152", "KEY153", "KEY154", "KEY155", + "KEY156", "KEY157", "KEY158", "KEY159", + "KEY160", "KEY161", "KEY162", "KEY163", + "KEY164", "KEY165", "KEY166", "KEY167", + "KEY168", "KEY169", "KEY170", "KEY171", + "KEY172", "KEY173", "KEY174", "KEY175", + "KEY176", "KEY177", "KEY178", "KEY179", + "KEY180", "KEY181", "KEY182", "KEY183", + "KEY184", "KEY185", "KEY186", "KEY187", + "KEY188", "KEY189", "KEY190", "KEY191", + "KEY192", "KEY193", "KEY194", "KEY195", + "KEY196", "KEY197", "KEY198", "KEY199", + "KEY200", "KEY201", "KEY202", "KEY203", + "KEY204", "KEY205", "KEY206", "KEY207", + "KEY208", "KEY209", "KEY210", "KEY211", + "KEY212", "KEY213", "KEY214", "LSHIFT", + "RSHIFT", "LCTRL", "RCTRL", "ALT", + "ALTGR", "LWIN", "RWIN", "MENU", + "SCROLLLOCK", "NUMLOCK", "CAPSLOCK" +}; + +ALLEGRO_STATIC_ASSERT(keybdnu, + sizeof(_al_keyboard_common_names) / sizeof(_al_keyboard_common_names[0]) + == ALLEGRO_KEY_MAX); + + + +/* Function: al_is_keyboard_installed + */ +bool al_is_keyboard_installed(void) +{ + return (new_keyboard_driver ? true : false); +} + + + +/* Function: al_install_keyboard + */ +bool al_install_keyboard(void) +{ + if (new_keyboard_driver) + return true; + + //FIXME: seems A4/A5 driver list stuff doesn't quite agree right now + if (al_get_system_driver()->vt->get_keyboard_driver) { + new_keyboard_driver = al_get_system_driver()->vt->get_keyboard_driver(); + if (!new_keyboard_driver->init_keyboard()) { + new_keyboard_driver = NULL; + return false; + } + _al_add_exit_func(al_uninstall_keyboard, "al_uninstall_keyboard"); + return true; + } + + return false; + + /* + if (system_driver->keyboard_drivers) + driver_list = system_driver->keyboard_drivers(); + else + driver_list = _al_keyboard_driver_list; + + for (i=0; driver_list[i].driver; i++) { + new_keyboard_driver = driver_list[i].driver; + name = get_config_text(new_keyboard_driver->keydrv_ascii_name); + new_keyboard_driver->keydrv_name = name; + new_keyboard_driver->keydrv_desc = name; + if (new_keyboard_driver->init_keyboard()) + break; + } + + if (!driver_list[i].driver) { + new_keyboard_driver = NULL; + return false; + } + + //set_leds(-1); + + _al_add_exit_func(al_uninstall_keyboard, "al_uninstall_keyboard"); + + + return true; + */ +} + + + +/* Function: al_uninstall_keyboard + */ +void al_uninstall_keyboard(void) +{ + if (!new_keyboard_driver) + return; + + //set_leds(-1); + + new_keyboard_driver->exit_keyboard(); + new_keyboard_driver = NULL; +} + + + +/* This was in the public API but its only purpose is now served by + * al_get_keyboard_event_source(). + */ +static ALLEGRO_KEYBOARD *al_get_keyboard(void) +{ + ASSERT(new_keyboard_driver); + { + ALLEGRO_KEYBOARD *kbd = new_keyboard_driver->get_keyboard(); + ASSERT(kbd); + + return kbd; + } +} + + + +/* Function: al_set_keyboard_leds + */ +bool al_set_keyboard_leds(int leds) +{ + ASSERT(new_keyboard_driver); + + if (new_keyboard_driver->set_keyboard_leds) + return new_keyboard_driver->set_keyboard_leds(leds); + + return false; +} + + + +/* Function: al_keycode_to_name + */ +const char *al_keycode_to_name(int keycode) +{ + const char *name = NULL; + + ASSERT(new_keyboard_driver); + ASSERT((keycode >= 0) && (keycode < ALLEGRO_KEY_MAX)); + + if (new_keyboard_driver->keycode_to_name) + name = new_keyboard_driver->keycode_to_name(keycode); + + if (!name) + name = _al_keyboard_common_names[keycode]; + + ASSERT(name); + + return name; +} + + + +/* Function: al_get_keyboard_state + */ +void al_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) +{ + ASSERT(new_keyboard_driver); + ASSERT(ret_state); + + new_keyboard_driver->get_keyboard_state(ret_state); +} + + + +/* Function: al_clear_keyboard_state + */ +void al_clear_keyboard_state(ALLEGRO_DISPLAY *display) +{ + ASSERT(new_keyboard_driver); + + if (display) { + ALLEGRO_EVENT_SOURCE *es = al_get_keyboard_event_source(); + ALLEGRO_KEYBOARD_STATE ks; al_get_keyboard_state(&ks); + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + int keycode; + for (keycode = ALLEGRO_KEY_A; keycode < ALLEGRO_KEY_MAX; keycode++) { + if (al_key_down(&ks, keycode)) { + ALLEGRO_EVENT event; + event.keyboard.type = ALLEGRO_EVENT_KEY_UP; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = display; + event.keyboard.keycode = keycode; + event.keyboard.unichar = 0; + event.keyboard.modifiers = 0; + _al_event_source_emit_event(es, &event); + } + } + } + _al_event_source_unlock(es); + } + + new_keyboard_driver->clear_keyboard_state(); +} + + + +/* Function: al_key_down + */ +bool al_key_down(const ALLEGRO_KEYBOARD_STATE *state, int keycode) +{ + return _AL_KEYBOARD_STATE_KEY_DOWN(*state, keycode); +} + + + +/* Function: al_get_keyboard_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_keyboard_event_source(void) +{ + ALLEGRO_KEYBOARD *keyboard = al_get_keyboard(); + + return (keyboard) ? &keyboard->es : NULL; +} + + + +static int match_key_name(const char *s) +{ + int i; + + /* Some key names are not intuitive, but this is all we've got. */ + for (i = 1; i < ALLEGRO_KEY_MAX; i++) { + if (0 == _al_stricmp(s, _al_keyboard_common_names[i])) + return i; + } + return 0; +} + + + +static unsigned int match_modifier(const char *s) +{ + if (0 == _al_stricmp(s, "SHIFT")) return ALLEGRO_KEYMOD_SHIFT; + if (0 == _al_stricmp(s, "CTRL")) return ALLEGRO_KEYMOD_CTRL; + if (0 == _al_stricmp(s, "ALT")) return ALLEGRO_KEYMOD_ALT; + if (0 == _al_stricmp(s, "LWIN")) return ALLEGRO_KEYMOD_LWIN; + if (0 == _al_stricmp(s, "RWIN")) return ALLEGRO_KEYMOD_RWIN; + if (0 == _al_stricmp(s, "ALTGR")) return ALLEGRO_KEYMOD_ALTGR; + if (0 == _al_stricmp(s, "COMMAND")) return ALLEGRO_KEYMOD_COMMAND; + return 0; +} + + + +int _al_parse_key_binding(const char *s, unsigned int *modifiers) +{ + ALLEGRO_USTR *us; + unsigned start = 0; + int keycode = 0; + + us = al_ustr_new(s); + al_ustr_trim_ws(us); + *modifiers = 0; + + while (start < al_ustr_size(us)) { + /* XXX not all keys can be bound due to a conflict with the delimiter + * characters + */ + int end = al_ustr_find_set_cstr(us, start, "+-"); + unsigned int mod; + + /* Last component must be a key. */ + if (end == -1) { + keycode = match_key_name(al_cstr(us) + start); + break; + } + + /* Otherwise must be a modifier. */ + al_ustr_set_chr(us, end, '\0'); + mod = match_modifier(al_cstr(us) + start); + if (!mod) { + break; + } + (*modifiers) |= mod; + start = end + 1; + } + + al_ustr_free(us); + + return keycode; +} + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/libc.c b/allegro/src/libc.c new file mode 100644 index 00000000..cce1dcd8 --- /dev/null +++ b/allegro/src/libc.c @@ -0,0 +1,108 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Emulation for libc routines that may be missing on some platforms. + * + * By Michael Bukin. + * + * Henrik Stokseth added _al_sane_realloc() and _al_sane_strncpy() functions. + * + * _al_srand() and _al_rand() functions based on code by Paul Pridham. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include +#include + + +static int _al_rand_seed = 0; + + +/* _al_stricmp: + * Case-insensitive comparison of 7-bit ASCII strings. + */ +int _al_stricmp(const char *s1, const char *s2) +{ + int c1, c2; + ASSERT(s1); + ASSERT(s2); + + do { + c1 = tolower(*(s1++)); + c2 = tolower(*(s2++)); + } while ((c1) && (c1 == c2)); + + return c1 - c2; +} + + +/* _al_sane_realloc: + * al_realloc() substitution with guaranteed behaviour. + */ +void *_al_sane_realloc(void *ptr, size_t size) +{ + void *tmp_ptr; + + tmp_ptr = NULL; + + if (ptr && size) { + tmp_ptr = al_realloc(ptr, size); + if (!tmp_ptr && ptr) al_free(ptr); + } + else if (!size) { + tmp_ptr = NULL; + if (ptr) al_free(ptr); + } + else if (!ptr) { + tmp_ptr = al_malloc(size); + } + + return tmp_ptr; +} + + + +/* _al_sane_strncpy: + * strncpy() substitution which properly null terminates a string. + */ +char *_al_sane_strncpy(char *dest, const char *src, size_t n) +{ + if (n <= 0) + return dest; + dest[0] = '\0'; + strncat(dest, src, n - 1); + + return dest; +} + + + +/* _al_srand: + * Seed initialization routine for rand() replacement. + */ +void _al_srand(int seed) +{ + _al_rand_seed = seed; +} + + + +/* _al_rand: + * Simple rand() replacement with guaranteed randomness in the lower 16 bits. + */ +int _al_rand(void) +{ + _al_rand_seed = (_al_rand_seed + 1) * 1103515245 + 12345; + return ((_al_rand_seed >> 16) & _AL_RAND_MAX); +} diff --git a/allegro/src/linux/lasyncio.c b/allegro/src/linux/lasyncio.c new file mode 100644 index 00000000..c5840fd3 --- /dev/null +++ b/allegro/src/linux/lasyncio.c @@ -0,0 +1,118 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Asynchronous I/O helpers for Linux Allegro. + * + * By Marek Habersack, mangled by George Foot. + * + * See readme.txt for copyright information. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/linalleg.h" + +#include +#include +#include + + +static SIGIO_HOOK user_sigio_hook = NULL; + +#define DEFAULT_ASYNC_IO_MODE ASYNC_BSD + +unsigned __al_linux_async_io_mode = 0; + + +/* al_linux_install_sigio_hook: + * Install a hook to be called from inside the SIGIO signal handler. + * It will be invoked AFTER the standard drivers are called. Note + * that it's not a very good way to handle SIGIO in your application. + * If you really need to use SIGIO, consider updating input events + * by hand, i.e. synchronously. Or, preferably, use the select(2) + * facility for asynchronous input. + * + * The previous hook is returned, NULL if none. + */ +SIGIO_HOOK al_linux_install_sigio_hook (SIGIO_HOOK hook) +{ + SIGIO_HOOK ret = user_sigio_hook; + user_sigio_hook = hook; + return ret; +} + + +/* async_io_event: + * A handler for the SIGIO signal. It used to be inelegant, more + * optimised for speed, but I changed that because it was causing + * problems (mouse motion stopped the keyboard responding). + */ +static void async_io_event(int signo) +{ + if (__al_linux_std_drivers[STD_MOUSE]) __al_linux_std_drivers[STD_MOUSE]->update(); + if (__al_linux_std_drivers[STD_KBD]) __al_linux_std_drivers[STD_KBD]->update(); + if (user_sigio_hook) user_sigio_hook(SIGIO); + return; +} + + + +/* al_linux_set_async_mode: + * Sets the asynchronous I/O mode for the registered standard device + * drivers. The async I/O is based on the BSD-compatible SIGIO signal. + */ +int al_linux_set_async_mode (unsigned type) +{ + static struct sigaction org_sigio; + struct sigaction sa; + + if (type == ASYNC_DEFAULT) + type = DEFAULT_ASYNC_IO_MODE; + + /* Turn off drivers */ + __al_linux_async_set_drivers (__al_linux_async_io_mode, 0); + + /* Shut down the previous mode */ + switch (__al_linux_async_io_mode) { + case ASYNC_BSD: + sigaction (SIGIO, &org_sigio, NULL); + break; + } + + __al_linux_async_io_mode = type; + + /* Initialise the new mode */ + switch (__al_linux_async_io_mode) { + case ASYNC_BSD: + sa.sa_flags = SA_RESTART; + sa.sa_handler = async_io_event; + sigfillset (&sa.sa_mask); + sigaction (SIGIO, &sa, &org_sigio); + break; + } + + /* Turn drivers back on again */ + __al_linux_async_set_drivers (__al_linux_async_io_mode, 1); + + return 0; +} + + +int al_linux_is_async_mode (void) +{ + return (__al_linux_async_io_mode != ASYNC_OFF); +} + + diff --git a/allegro/src/linux/lconsole.c b/allegro/src/linux/lconsole.c new file mode 100644 index 00000000..e0b922f9 --- /dev/null +++ b/allegro/src/linux/lconsole.c @@ -0,0 +1,370 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Console control functions for Linux Allegro. + * + * Originally by Marek Habersack, mangled by George Foot. + * + * See readme.txt for copyright information. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/linalleg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Console number and open file descriptor */ +int __al_linux_vt = -1; +int __al_linux_console_fd = -1; +int __al_linux_prev_vt = -1; +int __al_linux_got_text_message = false; + +/* Startup termios and working copy */ +struct termios __al_linux_startup_termio; +struct termios __al_linux_work_termio; + + +/* get_tty: + * Compares the inodes of /dev/ttyn (1 <= n <= 24) with the inode of the + * passed file, returning whichever it matches, 0 if none, -1 on error. + */ +static int get_tty (int fd) +{ + char name[16]; + int tty; + ino_t inode; + struct stat st; + + if (fstat (fd, &st)) + return -1; + + inode = st.st_ino; + for (tty = 1; tty <= 24; tty++) { + snprintf (name, sizeof(name), "/dev/tty%d", tty); + name[sizeof(name)-1] = 0; + if (!stat (name, &st) && (inode == st.st_ino)) + break; + } + + return (tty <= 24) ? tty : 0; +} + + +/* init_console: + * Initialises this subsystem. + */ +static int init_console(void) +{ + char tmp[256]; + + /* Find our tty's VT number */ + __al_linux_vt = get_tty(STDIN_FILENO); + + if (__al_linux_vt < 0) { + uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Error finding our VT: %s"), ustrerror(errno)); + return 1; + } + + if (__al_linux_vt != 0) { + /* Open our current console */ + if ((__al_linux_console_fd = open("/dev/tty", O_RDWR)) < 0) { + uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to open %s: %s"), + uconvert_ascii("/dev/tty", tmp), ustrerror(errno)); + return 1; + } + } else { + int tty, console_fd, fd, child; + unsigned short mask; + char tty_name[16]; + struct vt_stat vts; + + /* Now we need to find a VT we can use. It must be readable and + * writable by us, if we're not setuid root. VT_OPENQRY itself + * isn't too useful because it'll only ever come up with one + * suggestion, with no guarrantee that we actually have access + * to it. + * + * At some stage I think this is a candidate for config + * file overriding, but for now we'll stat the first N consoles + * to see which ones we can write to (hopefully at least one!), + * so that we can use that one to do ioctls. We used to use + * /dev/console for that purpose but it looks like it's not + * always writable by enough people. + * + * Having found and opened a writable device, we query the state + * of the first sixteen (fifteen really) consoles, and try + * opening each unused one in turn. + */ + + if ((console_fd = open ("/dev/console", O_WRONLY)) < 0) { + int n; + uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii("%s /dev/console: %s", tmp), + get_config_text("Unable to open"), ustrerror (errno)); + /* Try some ttys instead... */ + for (n = 1; n <= 24; n++) { + snprintf (tty_name, sizeof(tty_name), "/dev/tty%d", n); + tty_name[sizeof(tty_name)-1] = 0; + if ((console_fd = open (tty_name, O_WRONLY)) >= 0) + break; + } + if (n > 24) + return 1; /* leave the error message about /dev/console */ + } + + /* Get the state of the console -- in particular, the free VT field */ + if (ioctl (console_fd, VT_GETSTATE, &vts)) { + uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii("VT_GETSTATE: %s", tmp), ustrerror (errno)); + close (console_fd); + return 1; + } + + __al_linux_prev_vt = vts.v_active; + + /* We attempt to set our euid to 0; if we were run with euid 0 to + * start with, we'll be able to do this now. Otherwise, we'll just + * ignore the error returned since it might not be a problem if the + * ttys we look at are owned by the user running the program. */ + seteuid(0); + + /* tty0 is not really a console, so start counting at 2. */ + fd = -1; + for (tty = 1, mask = 2; mask; tty++, mask <<= 1) { + if (!(vts.v_state & mask)) { + snprintf (tty_name, sizeof(tty_name), "/dev/tty%d", tty); + tty_name[sizeof(tty_name)-1] = 0; + if ((fd = open (tty_name, O_RDWR)) != -1) { + close (fd); + break; + } + } + } + + seteuid (getuid()); + + if (!mask) { + ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to find a usable VT")); + close (console_fd); + return 1; + } + + /* OK, now fork into the background, detach from the current console, + * and attach to the new one. */ + child = fork(); + + if (child < 0) { + /* fork failed */ + uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii ("fork: %s", tmp), ustrerror (errno)); + close (console_fd); + return 1; + } + + if (child) { + /* We're the parent -- write a note to the user saying where the + * app went, then quit */ + fprintf (stderr, "Allegro application is running on VT %d\n", tty); + exit (0); + } + + /* We're the child. Detach from our controlling terminal, and start + * a new session. */ + close (console_fd); + ioctl (0, TIOCNOTTY, 0); + setsid(); + + /* Open the new one again. It becomes our ctty, because we started a + * new session above. */ + seteuid(0); + fd = open (tty_name, O_RDWR); + seteuid(getuid()); + + if (fd == -1) { + ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to reopen new console")); + return 1; + } + + /* Try to switch to it -- should succeed, since it's our ctty */ + ioctl (fd, VT_ACTIVATE, tty); + + __al_linux_vt = tty; + __al_linux_console_fd = fd; + + /* Check we can reliably wait until we have the display */ + if (__al_linux_wait_for_display()) { + close (fd); + ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("VT_WAITACTIVE failure")); + return 1; + } + + /* dup2 it to stdin, stdout and stderr if necessary */ + if (isatty(0)) dup2 (fd, 0); + if (isatty(1)) dup2 (fd, 1); + if (isatty(2)) dup2 (fd, 2); + } + + /* Get termio settings and make a working copy */ + tcgetattr(__al_linux_console_fd, &__al_linux_startup_termio); + __al_linux_work_termio = __al_linux_startup_termio; + + return 0; +} + + +/* done_console + * Undo `init_console'. + */ +static int done_console (void) +{ + char msg[256]; + int ret; + + if (__al_linux_prev_vt >= 0) { + if (__al_linux_got_text_message) { + snprintf(msg, sizeof(msg), "\nProgram finished: press %s+F%d to switch back to the previous console\n", + (__al_linux_prev_vt > 12) ? "AltGR" : "Alt", + __al_linux_prev_vt%12); + msg[sizeof(msg)-1] = 0; + + do { + ret = write(STDERR_FILENO, msg, strlen(msg)); + if ((ret < 0) && (errno != EINTR)) + break; + } while (ret < (int)strlen(msg)); + + __al_linux_got_text_message = false; + } + else + ioctl (__al_linux_console_fd, VT_ACTIVATE, __al_linux_prev_vt); + + __al_linux_prev_vt = -1; + } + + tcsetattr (__al_linux_console_fd, TCSANOW, &__al_linux_startup_termio); + close (__al_linux_console_fd); + __al_linux_console_fd = -1; + + return 0; +} + + +static int console_users = 0; + +/* __al_linux_use_console: + * Init Linux console if not initialized yet. + */ +int __al_linux_use_console(void) +{ + console_users++; + if (console_users > 1) + return 0; + + if (init_console()) { + console_users--; + return 1; + } + + /* Initialise the console switching system */ + set_display_switch_mode (SWITCH_PAUSE); + return __al_linux_init_vtswitch(); +} + + +/* __al_linux_leave_console: + * Close Linux console if no driver uses it any more. + */ +int __al_linux_leave_console(void) +{ + ASSERT (console_users > 0); + console_users--; + if (console_users > 0) + return 0; + + /* shut down the console switching system */ + if (__al_linux_done_vtswitch()) + return 1; + if (done_console()) + return 1; + + return 0; +} + + +static int graphics_mode = 0; + +/* __al_linux_console_graphics: + * Puts the Linux console into graphics mode. + */ +int __al_linux_console_graphics (void) +{ + if (__al_linux_use_console()) + return 1; + + if (graphics_mode) + return 0; /* shouldn't happen */ + ioctl(__al_linux_console_fd, KDSETMODE, KD_GRAPHICS); + __al_linux_wait_for_display(); + graphics_mode = 1; + + return 0; +} + + +/* __al_linux_console_text: + * Returns the console to text mode. + */ +int __al_linux_console_text (void) +{ + int ret; + + if (!graphics_mode) + return 0; /* shouldn't happen */ + + ioctl(__al_linux_console_fd, KDSETMODE, KD_TEXT); + + do { + ret = write(__al_linux_console_fd, "\e[H\e[J\e[0m", 10); + if ((ret < 0) && (errno != EINTR)) + break; + } while (ret < 10); + + graphics_mode = 0; + + __al_linux_leave_console(); + + return 0; +} + + +/* __al_linux_wait_for_display: + * Waits until we have the display. + */ +int __al_linux_wait_for_display (void) +{ + int x; + do { + x = ioctl (__al_linux_console_fd, VT_WAITACTIVE, __al_linux_vt); + } while (x && errno != EINTR); + return x; +} + diff --git a/allegro/src/linux/lhaptic.c b/allegro/src/linux/lhaptic.c new file mode 100644 index 00000000..27147095 --- /dev/null +++ b/allegro/src/linux/lhaptic.c @@ -0,0 +1,859 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux haptic (force-feedback) device driver. + * + * By Beoran. + * + * See LICENSE.txt for copyright information. + */ + + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_haptic.h" +#include "allegro5/internal/aintern_ljoynu.h" +#include "allegro5/platform/aintunix.h" + +#ifdef ALLEGRO_HAVE_LINUX_INPUT_H + +#include + +ALLEGRO_DEBUG_CHANNEL("lhaptic") + + +/* Support at most 32 haptic devices. */ +#define HAPTICS_MAX 32 + +/* Support at most 16 effects per device. */ +#define HAPTICS_EFFECTS_MAX 16 + + +typedef struct +{ + struct ALLEGRO_HAPTIC parent; /* must be first */ + bool active; + int fd; + int flags; + int effects[HAPTICS_EFFECTS_MAX]; +} ALLEGRO_HAPTIC_LINUX; + + +#define LONG_BITS (sizeof(long) * 8) +#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS) +/* Tests if a bit in an array of longs is set. */ +#define TEST_BIT(nr, addr) \ + ((1UL << ((nr) % LONG_BITS)) & (addr)[(nr) / LONG_BITS]) + + +/* forward declarations */ +static bool lhap_init_haptic(void); +static void lhap_exit_haptic(void); + +static bool lhap_is_mouse_haptic(ALLEGRO_MOUSE *dev); +static bool lhap_is_joystick_haptic(ALLEGRO_JOYSTICK *); +static bool lhap_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev); +static bool lhap_is_display_haptic(ALLEGRO_DISPLAY *dev); +static bool lhap_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev); + +static ALLEGRO_HAPTIC *lhap_get_from_mouse(ALLEGRO_MOUSE *dev); +static ALLEGRO_HAPTIC *lhap_get_from_joystick(ALLEGRO_JOYSTICK *dev); +static ALLEGRO_HAPTIC *lhap_get_from_keyboard(ALLEGRO_KEYBOARD *dev); +static ALLEGRO_HAPTIC *lhap_get_from_display(ALLEGRO_DISPLAY *dev); +static ALLEGRO_HAPTIC *lhap_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev); + +static bool lhap_release(ALLEGRO_HAPTIC *haptic); + +static bool lhap_get_active(ALLEGRO_HAPTIC *hap); +static int lhap_get_capabilities(ALLEGRO_HAPTIC *dev); +static double lhap_get_gain(ALLEGRO_HAPTIC *dev); +static bool lhap_set_gain(ALLEGRO_HAPTIC *dev, double); +static int lhap_get_max_effects(ALLEGRO_HAPTIC *dev); + +static bool lhap_is_effect_ok(ALLEGRO_HAPTIC *dev, ALLEGRO_HAPTIC_EFFECT *eff); +static bool lhap_upload_effect(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *eff, + ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool lhap_play_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop); +static bool lhap_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool lhap_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool lhap_release_effect(ALLEGRO_HAPTIC_EFFECT_ID *id); + +static double lhap_get_autocenter(ALLEGRO_HAPTIC *dev); +static bool lhap_set_autocenter(ALLEGRO_HAPTIC *dev, double); + +ALLEGRO_HAPTIC_DRIVER _al_hapdrv_linux = +{ + _ALLEGRO_HAPDRV_LINUX, + "", + "", + "Linux haptic(s)", + lhap_init_haptic, + lhap_exit_haptic, + + lhap_is_mouse_haptic, + lhap_is_joystick_haptic, + lhap_is_keyboard_haptic, + lhap_is_display_haptic, + lhap_is_touch_input_haptic, + + lhap_get_from_mouse, + lhap_get_from_joystick, + lhap_get_from_keyboard, + lhap_get_from_display, + lhap_get_from_touch_input, + + lhap_get_active, + lhap_get_capabilities, + lhap_get_gain, + lhap_set_gain, + lhap_get_max_effects, + + lhap_is_effect_ok, + lhap_upload_effect, + lhap_play_effect, + lhap_stop_effect, + lhap_is_effect_playing, + lhap_release_effect, + + lhap_release, + + lhap_get_autocenter, + lhap_set_autocenter +}; + + +static ALLEGRO_HAPTIC_LINUX haptics[HAPTICS_MAX]; +static ALLEGRO_MUTEX *haptic_mutex = NULL; + + +struct CAP_MAP { + int linux_bit; + int allegro_bit; +}; + +static const struct CAP_MAP cap_map[] = { + { FF_PERIODIC, ALLEGRO_HAPTIC_PERIODIC }, + { FF_RUMBLE, ALLEGRO_HAPTIC_RUMBLE }, + { FF_CONSTANT, ALLEGRO_HAPTIC_CONSTANT }, + { FF_SPRING, ALLEGRO_HAPTIC_SPRING }, + { FF_FRICTION, ALLEGRO_HAPTIC_FRICTION }, + { FF_DAMPER, ALLEGRO_HAPTIC_DAMPER }, + { FF_INERTIA, ALLEGRO_HAPTIC_INERTIA }, + { FF_RAMP, ALLEGRO_HAPTIC_RAMP }, + { FF_SQUARE, ALLEGRO_HAPTIC_SQUARE }, + { FF_TRIANGLE, ALLEGRO_HAPTIC_TRIANGLE }, + { FF_SINE, ALLEGRO_HAPTIC_SINE }, + { FF_SAW_UP, ALLEGRO_HAPTIC_SAW_UP }, + { FF_SAW_DOWN, ALLEGRO_HAPTIC_SAW_DOWN }, + { FF_CUSTOM, ALLEGRO_HAPTIC_CUSTOM }, + { FF_GAIN, ALLEGRO_HAPTIC_GAIN }, + { FF_AUTOCENTER, ALLEGRO_HAPTIC_AUTOCENTER }, + { -1, -1 } +}; + + +static bool lhap_init_haptic(void) +{ + int i; + + ASSERT(haptic_mutex == NULL); + haptic_mutex = al_create_mutex(); + if (!haptic_mutex) + return false; + + for (i = 0; i < HAPTICS_MAX; i++) { + haptics[i].active = false; + } + + return true; +} + + +static ALLEGRO_HAPTIC_LINUX *lhap_get_available_haptic(void) +{ + int i; + + for (i = 0; i < HAPTICS_MAX; i++) { + if (!haptics[i].active) { + haptics[i].active = true; + return &haptics[i]; + } + } + + return NULL; +} + + +/* Converts a generic haptic device to a Linux-specific one. */ +static ALLEGRO_HAPTIC_LINUX *lhap_from_al(ALLEGRO_HAPTIC *hap) +{ + return (ALLEGRO_HAPTIC_LINUX *)hap; +} + + +static void lhap_exit_haptic(void) +{ + ASSERT(haptic_mutex); + al_destroy_mutex(haptic_mutex); + haptic_mutex = NULL; +} + + +static bool lhap_type2lin(__u16 *res, int type) +{ + ASSERT(res); + + switch (type) { + case ALLEGRO_HAPTIC_RUMBLE: + (*res) = FF_RUMBLE; + break; + case ALLEGRO_HAPTIC_PERIODIC: + (*res) = FF_PERIODIC; + break; + case ALLEGRO_HAPTIC_CONSTANT: + (*res) = FF_CONSTANT; + break; + case ALLEGRO_HAPTIC_SPRING: + (*res) = FF_SPRING; + break; + case ALLEGRO_HAPTIC_FRICTION: + (*res) = FF_FRICTION; + break; + case ALLEGRO_HAPTIC_DAMPER: + (*res) = FF_DAMPER; + break; + case ALLEGRO_HAPTIC_INERTIA: + (*res) = FF_INERTIA; + break; + case ALLEGRO_HAPTIC_RAMP: + (*res) = FF_RAMP; + break; + default: + return false; + } + return true; +} + + +static bool lhap_wave2lin(__u16 *res, int type) +{ + ASSERT(res); + + switch (type) { + case ALLEGRO_HAPTIC_SQUARE: + (*res) = FF_SQUARE; + break; + case ALLEGRO_HAPTIC_TRIANGLE: + (*res) = FF_TRIANGLE; + break; + case ALLEGRO_HAPTIC_SINE: + (*res) = FF_SINE; + break; + case ALLEGRO_HAPTIC_SAW_UP: + (*res) = FF_SAW_UP; + break; + case ALLEGRO_HAPTIC_SAW_DOWN: + (*res) = FF_SAW_DOWN; + break; + case ALLEGRO_HAPTIC_CUSTOM: + (*res) = FF_CUSTOM; + break; + default: + return false; + } + return true; +} + + +/* Converts the time in seconds to a Linux-compatible time. + * Return false if out of bounds. + */ +static bool lhap_time2lin(__u16 *res, double sec) +{ + ASSERT(res); + + if (sec < 0.0 || sec > 32.767) + return false; + (*res) = (__u16) round(sec * 1000.0); + return true; +} + + +/* Converts the time in seconds to a Linux-compatible time. + * Return false if out of bounds. This one allows negative times. + */ +static bool lhap_stime2lin(__s16 *res, double sec) +{ + ASSERT(res); + + if (sec < -32.767 || sec > 32.767) + return false; + (*res) = (__s16) round(sec * 1000.0); + return true; +} + + +/* Converts replay data to Linux-compatible data. */ +static bool lhap_replay2lin(struct ff_replay *lin, + struct ALLEGRO_HAPTIC_REPLAY *al) +{ + return lhap_time2lin(&lin->delay, al->delay) + && lhap_time2lin(&lin->length, al->length); +} + + +/* Converts the level in range 0.0 to 1.0 to a Linux-compatible level. + * Returns false if out of bounds. + */ +static bool lhap_level2lin(__u16 *res, double level) +{ + ASSERT(res); + + if (level < 0.0 || level > 1.0) + return false; + *res = (__u16) round(level * (double)0x7fff); + return true; +} + + +/* Converts the level in range -1.0 to 1.0 to a Linux-compatible level. + * Returns false if out of bounds. + */ +static bool lhap_slevel2lin(__s16 *res, double level) +{ + ASSERT(res); + + if (level < -1.0 || level > 1.0) + return false; + *res = (__s16) round(level * (double)0x7ffe); + return true; +} + + +/* Converts an Allegro haptic effect envelope to Linux input API. */ +static bool lhap_envelope2lin(struct ff_envelope *lin, + struct ALLEGRO_HAPTIC_ENVELOPE *al) +{ + return lhap_time2lin(&lin->attack_length, al->attack_length) + && lhap_time2lin(&lin->fade_length, al->fade_length) + && lhap_level2lin(&lin->attack_level, al->attack_level) + && lhap_level2lin(&lin->fade_level, al->fade_level); +} + + +/* Converts a rumble effect to Linux input API. */ +static bool lhap_rumble2lin(struct ff_rumble_effect *lin, + struct ALLEGRO_HAPTIC_RUMBLE_EFFECT *al) +{ + return lhap_level2lin(&lin->strong_magnitude, al->strong_magnitude) + && lhap_level2lin(&lin->weak_magnitude, al->weak_magnitude); +} + + +/* Converts a constant effect to Linux input API. */ +static bool lhap_constant2lin(struct ff_constant_effect *lin, + struct ALLEGRO_HAPTIC_CONSTANT_EFFECT *al) +{ + return lhap_envelope2lin(&lin->envelope, &al->envelope) + && lhap_slevel2lin(&lin->level, al->level); +} + + +/* Converts a ramp effect to Linux input API. */ +static bool lhap_ramp2lin(struct ff_ramp_effect *lin, + struct ALLEGRO_HAPTIC_RAMP_EFFECT *al) +{ + return lhap_envelope2lin(&lin->envelope, &al->envelope) + && lhap_slevel2lin(&lin->start_level, al->start_level) + && lhap_slevel2lin(&lin->end_level, al->end_level); +} + + +/* Converts a ramp effect to Linux input API. */ +static bool lhap_condition2lin(struct ff_condition_effect *lin, + struct ALLEGRO_HAPTIC_CONDITION_EFFECT *al) +{ + return lhap_slevel2lin(&lin->center, al->center) + && lhap_level2lin(&lin->deadband, al->deadband) + && lhap_slevel2lin(&lin->right_coeff, al->right_coeff) + && lhap_level2lin(&lin->right_saturation, al->right_saturation) + && lhap_slevel2lin(&lin->left_coeff, al->left_coeff) + && lhap_level2lin(&lin->left_saturation, al->left_saturation); +} + + +/* Converts a periodic effect to linux input API. */ +static bool lhap_periodic2lin(struct ff_periodic_effect *lin, + struct ALLEGRO_HAPTIC_PERIODIC_EFFECT *al) +{ + /* Custom data is not supported yet, because currently no Linux + * haptic driver supports it. + */ + if (al->custom_data) + return false; + + return lhap_slevel2lin(&lin->magnitude, al->magnitude) + && lhap_stime2lin(&lin->offset, al->offset) + && lhap_time2lin(&lin->period, al->period) + && lhap_time2lin(&lin->phase, al->phase) + && lhap_wave2lin(&lin->waveform, al->waveform) + && lhap_envelope2lin(&lin->envelope, &al->envelope); +} + + +/* Converts Allegro haptic effect to Linux input API. */ +static bool lhap_effect2lin(struct ff_effect *lin, ALLEGRO_HAPTIC_EFFECT *al) +{ + memset(lin, 0, sizeof(*lin)); + + if (!lhap_type2lin(&lin->type, al->type)) + return false; + /* lin_effect->replay = effect->re; */ + lin->direction = (__u16) + round(((double)0xC000 * al->direction.angle) / (2 * M_PI)); + lin->id = -1; + if (!lhap_replay2lin(&lin->replay, &al->replay)) + return false; + switch (lin->type) { + case FF_RUMBLE: + return lhap_rumble2lin(&lin->u.rumble, &al->data.rumble); + case FF_PERIODIC: + return lhap_periodic2lin(&lin->u.periodic, &al->data.periodic); + case FF_CONSTANT: + return lhap_constant2lin(&lin->u.constant, &al->data.constant); + case FF_RAMP: + return lhap_ramp2lin(&lin->u.ramp, &al->data.ramp); + case FF_SPRING: /* fall through */ + case FF_FRICTION: /* fall through */ + case FF_DAMPER: /* fall through */ + case FF_INERTIA: + return lhap_condition2lin(&lin->u.condition[0], &al->data.condition); + default: + return false; + } +} + + +static bool lhap_get_active(ALLEGRO_HAPTIC *haptic) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(haptic); + return lhap->active; +} + + +static bool lhap_is_mouse_haptic(ALLEGRO_MOUSE *mouse) +{ + (void)mouse; + return false; +} + + +static bool lhap_fd_can_ff(int fd) +{ + long bitmask[NLONGS(EV_CNT)] = { 0 }; + + if (ioctl(fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) { + return false; + } + if (TEST_BIT(EV_FF, bitmask)) { + return true; + } + return false; +} + + +static bool lhap_is_joystick_haptic(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_LINUX *ljoy = (ALLEGRO_JOYSTICK_LINUX *) joy; + if (!al_is_joystick_installed()) + return false; + if (!al_get_joystick_active(joy)) + return false; + if (ljoy->fd <= 0) + return false; + return lhap_fd_can_ff(ljoy->fd); +} + + +static bool lhap_is_display_haptic(ALLEGRO_DISPLAY *dev) +{ + (void)dev; + return false; +} + + +static bool lhap_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev) +{ + (void)dev; + return false; +} + + +static bool lhap_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev) +{ + (void)dev; + return false; +} + + +static ALLEGRO_HAPTIC *lhap_get_from_mouse(ALLEGRO_MOUSE *mouse) +{ + (void)mouse; + return NULL; +} + + +static bool get_haptic_capabilities(int fd, int *capabilities) +{ + unsigned long bitmask[NLONGS(FF_CNT)] = { 0 }; + int caps; + int i; + + if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(bitmask)), bitmask) < 0) { + ALLEGRO_ERROR("EVIOCGBIT failed for fd %d", fd); + return false; + } + + caps = 0; + for (i = 0; cap_map[i].allegro_bit >= 0; i++) { + if (TEST_BIT(cap_map[i].linux_bit, bitmask)) { + caps |= cap_map[i].allegro_bit; + } + } + (*capabilities) = caps; + ALLEGRO_INFO("Capabilities: 0x%x\n", caps); + return true; +} + + +static ALLEGRO_HAPTIC *lhap_get_from_joystick(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_LINUX *ljoy = (ALLEGRO_JOYSTICK_LINUX *) joy; + ALLEGRO_HAPTIC_LINUX *lhap; + int i; + + if (!al_is_joystick_haptic(joy)) + return NULL; + + al_lock_mutex(haptic_mutex); + + lhap = lhap_get_available_haptic(); + + if (!lhap) { + al_unlock_mutex(haptic_mutex); + return NULL; + } + + lhap->parent.device = joy; + lhap->parent.from = _AL_HAPTIC_FROM_JOYSTICK; + + lhap->fd = ljoy->fd; + lhap->active = true; + for (i = 0; i < HAPTICS_EFFECTS_MAX; i++) { + lhap->effects[i] = -1; /* not in use */ + } + lhap->parent.gain = 1.0; + get_haptic_capabilities(lhap->fd, &lhap->flags); + + al_unlock_mutex(haptic_mutex); + + return &lhap->parent; +} + + +static ALLEGRO_HAPTIC *lhap_get_from_display(ALLEGRO_DISPLAY *dev) +{ + (void)dev; + return NULL; +} + + +static ALLEGRO_HAPTIC *lhap_get_from_keyboard(ALLEGRO_KEYBOARD *dev) +{ + (void)dev; + return NULL; +} + + +static ALLEGRO_HAPTIC *lhap_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev) +{ + (void)dev; + return NULL; +} + + +static int lhap_get_capabilities(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(dev); + return lhap->flags; +} + + +static double lhap_get_gain(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(dev); + (void)dev; + + if(!al_is_haptic_capable(dev, ALLEGRO_HAPTIC_GAIN)) { + return 0.0; + } + + /* Unfortunately there seems to be no API to GET gain, only to set?! + * So, return the stored gain. + */ + return lhap->parent.gain; +} + + +static bool lhap_set_gain(ALLEGRO_HAPTIC *dev, double gain) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(dev); + struct input_event ie; + + lhap->parent.gain = gain; + timerclear(&ie.time); + ie.type = EV_FF; + ie.code = FF_GAIN; + ie.value = (__s32) ((double)0xFFFF * gain); + if (write(lhap->fd, &ie, sizeof(ie)) < 0) { + return false; + } + return true; +} + + +static bool lhap_set_autocenter(ALLEGRO_HAPTIC *dev, double autocenter) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(dev); + struct input_event ie; + + lhap->parent.autocenter = autocenter; + timerclear(&ie.time); + ie.type = EV_FF; + ie.code = FF_AUTOCENTER; + ie.value = (__s32) ((double)0xFFFF * autocenter); + if (write(lhap->fd, &ie, sizeof(ie)) < 0) { + return false; + } + return true; +} + +static double lhap_get_autocenter(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(dev); + (void)dev; + + if(!al_is_haptic_capable(dev, ALLEGRO_HAPTIC_AUTOCENTER)) { + return 0.0; + } + + /* Unfortunately there seems to be no API to GET gain, only to set?! + * So, return the stored autocenter. + */ + return lhap->parent.autocenter; +} + +int lhap_get_max_effects(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(dev); + int n_effects; + + if (ioctl(lhap->fd, EVIOCGEFFECTS, &n_effects) < 0) { + ALLEGRO_WARN("EVIOCGEFFECTS failed on fd %d\n", lhap->fd); + n_effects = HAPTICS_EFFECTS_MAX; + } + + if (n_effects < HAPTICS_EFFECTS_MAX) + return n_effects; + else + return HAPTICS_EFFECTS_MAX; +} + + +static bool lhap_is_effect_ok(ALLEGRO_HAPTIC *haptic, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + int caps; + struct ff_effect leff; + + caps = al_get_haptic_capabilities(haptic); + if (caps & effect->type) { + return lhap_effect2lin(&leff, effect); + } + return false; +} + + +static bool lhap_upload_effect(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(dev); + struct ff_effect leff; + int found; + int i; + + ASSERT(dev); + ASSERT(id); + ASSERT(effect); + + /* Set id's values to indicate failure. */ + id->_haptic = NULL; + id->_id = -1; + id->_handle = -1; + + if (!lhap_effect2lin(&leff, effect)) { + ALLEGRO_WARN("lhap_effect2lin failed"); + return false; + } + + /* Find empty spot for effect . */ + found = -1; + for (i = 0; i < al_get_max_haptic_effects(dev); i++) { + if (lhap->effects[i] < 0) { + found = i; + break; + } + } + + /* No more space for an effect. */ + if (found < 0) { + ALLEGRO_WARN("No free effect slot."); + return false; + } + + /* Upload effect. */ + leff.id = -1; + if (ioctl(lhap->fd, EVIOCSFF, &leff) < 0) { + ALLEGRO_ERROR("EVIOCSFF failed for fd %d\n", lhap->fd); + return false; + } + + id->_haptic = dev; + id->_id = found; + id->_handle = leff.id; + id->_effect_duration = al_get_haptic_effect_duration(effect); + id->_playing = false; + + /* XXX should be bool or something? */ + lhap->effects[i] = found; + + return true; +} + + +static bool lhap_play_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loops) +{ + ALLEGRO_HAPTIC_LINUX *lhap = (ALLEGRO_HAPTIC_LINUX *) id->_haptic; + struct input_event play; + int fd; + double now; + double duration; + + if (!lhap) + return false; + + fd = lhap->fd; + + timerclear(&play.time); + play.type = EV_FF; + play.code = id->_handle; + loops = (loops < 0) ? 1 : loops; + play.value = loops; /* play: 1, stop: 0 */ + + if (write(fd, (const void *)&play, sizeof(play)) < 0) { + ALLEGRO_ERROR("Effect play failed.\n"); + return false; + } + + now = al_get_time(); + duration = loops * id->_effect_duration; + + id->_playing = true; + id->_start_time = now; + id->_end_time = now + duration; + + return true; +} + + +static bool lhap_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_LINUX *lhap = (ALLEGRO_HAPTIC_LINUX *) id->_haptic; + struct input_event play; + + if (!lhap) + return false; + + memset(&play, 0, sizeof(play)); + + play.type = EV_FF; + play.code = id->_handle; + play.value = 0; + if (write(lhap->fd, (const void *)&play, sizeof(play)) < 0) { + ALLEGRO_ERROR("Stop effect failed.\n"); + return false; + } + id->_playing = false; + return true; +} + + +static bool lhap_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ASSERT(id); + + /* Since AFAICS there is no Linux API to test this, use a timer to check + * if the effect has been playing long enough to be finished or not. + */ + return (id->_playing && al_get_time() < id->_end_time); +} + + +static bool lhap_release_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_LINUX *lhap = (ALLEGRO_HAPTIC_LINUX *)id->_haptic; + + lhap_stop_effect(id); + + if (ioctl(lhap->fd, EVIOCRMFF, id->_handle) < 0) { + ALLEGRO_ERROR("EVIOCRMFF failed.\n"); + return false; + } + lhap->effects[id->_id] = -1; /* not in use */ + return true; +} + + +static bool lhap_release(ALLEGRO_HAPTIC *haptic) +{ + ALLEGRO_HAPTIC_LINUX *lhap = lhap_from_al(haptic); + ASSERT(haptic); + + if (!lhap->active) + return false; + + lhap->active = false; + lhap->fd = -1; + return true; +} + + +#endif /* ALLEGRO_HAVE_LINUX_INPUT_H */ + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/linux/ljoynu.c b/allegro/src/linux/ljoynu.c new file mode 100644 index 00000000..89dc084f --- /dev/null +++ b/allegro/src/linux/ljoynu.c @@ -0,0 +1,1015 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux joystick driver. + * + * By George Foot and Peter Wang. + * + * Updated for new joystick API by Peter Wang. + * + * See readme.txt for copyright information. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define ALLEGRO_NO_KEY_DEFINES +#define ALLEGRO_NO_COMPATIBILITY + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/platform/aintunix.h" + +#ifdef ALLEGRO_HAVE_LINUX_INPUT_H + +/* To be safe, include sys/types.h before linux/joystick.h to avoid conflicting + * definitions of fd_set. + */ +#include +#include + +#if defined(ALLEGRO_HAVE_SYS_INOTIFY_H) + #define SUPPORT_HOTPLUG + #include +#endif + +#ifndef KEY_CNT + #define KEY_CNT (KEY_MAX+1) +#endif + +#ifndef ABS_CNT + #define ABS_CNT (ABS_MAX+1) +#endif + +ALLEGRO_DEBUG_CHANNEL("ljoy"); + +#include "allegro5/internal/aintern_ljoynu.h" + + + +#define LONG_BITS (sizeof(long) * 8) +#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS) +/* Tests if a bit in an array of longs is set. */ +#define TEST_BIT(nr, addr) \ + ((1UL << ((nr) % LONG_BITS)) & (addr)[(nr) / LONG_BITS]) + + +/* We only accept the axes ABS_X to ABS_HAT3Y as real joystick axes. + * The axes ABS_PRESSURE, ABS_DISTANCE, ABS_TILT_X, ABS_TILT_Y, + * ABS_TOOL_WIDTH are for use by a drawing tablet. + * ABS_VOLUME is for volume sliders or key pairs on some keyboards. + * Other axes up to ABS_MISC may exist, such as on the PS3, but they are + * most likely not useful. + */ +#define LJOY_AXIS_RANGE_START (ABS_X) +#define LJOY_AXIS_RANGE_END (ABS_HAT3Y + 1) + + +/* The range of potential joystick button codes in the Linux input API + * is from BTN_MISC to BTN_GEAR_UP. + */ +#define LJOY_BTN_RANGE_START (BTN_MISC) +#if !defined(ALLEGRO_ANDROID) && defined(BTN_TRIGGER_HAPPY) +#define LJOY_BTN_RANGE_END (BTN_TRIGGER_HAPPY40 + 1) +#else +#define LJOY_BTN_RANGE_END (BTN_GEAR_UP + 1) +#endif + + + +/* forward declarations */ +static bool ljoy_init_joystick(void); +static void ljoy_exit_joystick(void); +static bool ljoy_reconfigure_joysticks(void); +static int ljoy_num_joysticks(void); +static ALLEGRO_JOYSTICK *ljoy_get_joystick(int num); +static void ljoy_release_joystick(ALLEGRO_JOYSTICK *joy_); +static void ljoy_get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state); +static const char *ljoy_get_name(ALLEGRO_JOYSTICK *joy_); +static bool ljoy_get_active(ALLEGRO_JOYSTICK *joy_); + +static void ljoy_process_new_data(void *data); +static void ljoy_generate_axis_event(ALLEGRO_JOYSTICK_LINUX *joy, int stick, int axis, float pos); +static void ljoy_generate_button_event(ALLEGRO_JOYSTICK_LINUX *joy, int button, ALLEGRO_EVENT_TYPE event_type); + + + +/* the driver vtable */ +ALLEGRO_JOYSTICK_DRIVER _al_joydrv_linux = +{ + _ALLEGRO_JOYDRV_LINUX, + "", + "", + "Linux joystick(s)", + ljoy_init_joystick, + ljoy_exit_joystick, + ljoy_reconfigure_joysticks, + ljoy_num_joysticks, + ljoy_get_joystick, + ljoy_release_joystick, + ljoy_get_joystick_state, + ljoy_get_name, + ljoy_get_active +}; + + +static unsigned num_joysticks; /* number of joysticks known to the user */ +static _AL_VECTOR joysticks; /* of ALLEGRO_JOYSTICK_LINUX pointers */ +static volatile bool config_needs_merging; +static ALLEGRO_MUTEX *config_mutex; +#ifdef SUPPORT_HOTPLUG +static int inotify_fd = -1; +static ALLEGRO_THREAD *hotplug_thread; +static ALLEGRO_MUTEX *hotplug_mutex; +static ALLEGRO_COND *hotplug_cond; +static bool hotplug_ended = false; +#endif + + +/* Return true if a joystick-related button or key: + * + * BTN_MISC to BTN_9 for miscellaneous input, + * BTN_JOYSTICK to BTN_DEAD for joysticks, + * BTN_GAMEPAD to BTN_THUMBR for game pads, + * BTN_WHEEL, BTN_GEAR_DOWN, BTN_GEAR_UP for steering wheels, + * BTN_TRIGGER_HAPPY_n buttons just in case. + */ +static bool is_joystick_button(int i) +{ + ASSERT(i >= LJOY_BTN_RANGE_START && i < LJOY_BTN_RANGE_END); + + return (i >= BTN_MISC && i <= BTN_9) + || (i >= BTN_JOYSTICK && i <= BTN_DEAD) + || (i >= BTN_GAMEPAD && i <= BTN_THUMBR) + || (i >= BTN_WHEEL && i <= BTN_GEAR_UP) +#if !defined(ALLEGRO_ANDROID) && defined(BTN_TRIGGER_HAPPY) + || (i >= BTN_TRIGGER_HAPPY && i <= BTN_TRIGGER_HAPPY40) +#endif + ; +} + + + +static bool is_single_axis_throttle(int i) +{ + ASSERT(i >= LJOY_AXIS_RANGE_START && i < LJOY_AXIS_RANGE_END); + + /* Consider all these types of axis as throttle axis. */ + return i == ABS_THROTTLE + || i == ABS_RUDDER + || i == ABS_WHEEL + || i == ABS_GAS + || i == ABS_BRAKE + || i == ABS_PRESSURE + || i == ABS_DISTANCE + || i == ABS_TOOL_WIDTH; +} + + + +static bool is_hat_axis(int i) +{ + return (i >= ABS_HAT0X && i <= ABS_HAT3Y); +} + + + +/* Check if the device has at least once joystick-related button. */ +static bool have_joystick_button(int fd) +{ + unsigned long key_bits[NLONGS(KEY_CNT)] = {0}; + int i; + + if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits) < 0) + return false; + + for (i = LJOY_BTN_RANGE_START; i < LJOY_BTN_RANGE_END; i++) { + if (TEST_BIT(i, key_bits) && is_joystick_button(i)) + return true; + } + + return false; +} + + + +/* Check if the device has at least one joystick-related absolute axis. + * Some devices, like (wireless) keyboards, may actually have absolute axes + * such as a volume axis for the volume up/down buttons. + * Also, some devices like a PS3 controller report many unusual axes, probably + * used in nonstandard ways by the PS3 console. All such axes are ignored by + * this function and by this driver. + */ +static bool have_joystick_axis(int fd) +{ + unsigned long abs_bits[NLONGS(ABS_CNT)] = {0}; + int i; + + if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits) < 0) + return false; + + for (i = LJOY_AXIS_RANGE_START; i < LJOY_AXIS_RANGE_END; i++) { + if (TEST_BIT(i, abs_bits)) + return true; + } + + return false; +} + + + +static bool ljoy_detect_device_name(int num, ALLEGRO_USTR *device_name) +{ + char key[80]; + const char *value; + struct stat stbuf; + + al_ustr_truncate(device_name, 0); + + snprintf(key, sizeof(key), "device%d", num); + value = al_get_config_value(al_get_system_config(), "joystick", key); + if (value) + al_ustr_assign_cstr(device_name, value); + + return (stat(al_cstr(device_name), &stbuf) == 0); +} + + + +static ALLEGRO_JOYSTICK_LINUX *ljoy_by_device_name( + const ALLEGRO_USTR *device_name) +{ + unsigned i; + + for (i = 0; i < _al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i); + ALLEGRO_JOYSTICK_LINUX *joy = *slot; + + if (joy && al_ustr_equal(device_name, joy->device_name)) + return joy; + } + + return NULL; +} + + + +static void ljoy_generate_configure_event(void) +{ + ALLEGRO_EVENT event; + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; + event.joystick.timestamp = al_get_time(); + + _al_generate_joystick_event(&event); +} + + + +static ALLEGRO_JOYSTICK_LINUX *ljoy_allocate_structure(void) +{ + ALLEGRO_JOYSTICK_LINUX **slot; + ALLEGRO_JOYSTICK_LINUX *joy; + unsigned i; + + for (i = 0; i < _al_vector_size(&joysticks); i++) { + slot = _al_vector_ref(&joysticks, i); + joy = *slot; + + if (joy->config_state == LJOY_STATE_UNUSED) + return joy; + } + + joy = al_calloc(1, sizeof *joy); + slot = _al_vector_alloc_back(&joysticks); + *slot = joy; + return joy; +} + + + +static void inactivate_joy(ALLEGRO_JOYSTICK_LINUX *joy) +{ + int i; + + if (joy->config_state == LJOY_STATE_UNUSED) + return; + joy->config_state = LJOY_STATE_UNUSED; + + _al_unix_stop_watching_fd(joy->fd); + close(joy->fd); + joy->fd = -1; + + for (i = 0; i < joy->parent.info.num_sticks; i++) + al_free((void *)joy->parent.info.stick[i].name); + for (i = 0; i < joy->parent.info.num_buttons; i++) + al_free((void *)joy->parent.info.button[i].name); + memset(&joy->parent.info, 0, sizeof(joy->parent.info)); + memset(&joy->joystate, 0, sizeof(joy->joystate)); + + al_ustr_free(joy->device_name); + joy->device_name = NULL; +} + + + +static void set_axis_mapping(AXIS_MAPPING *map, int stick, int axis, + const struct input_absinfo *absinfo) +{ + map->stick = stick; + map->axis = axis; + map->min = absinfo->minimum; + map->max = absinfo->maximum; + map->value = absinfo->value; + map->fuzz = absinfo->fuzz; + map->flat = absinfo->flat; +} + + + +static bool fill_joystick_axes(ALLEGRO_JOYSTICK_LINUX *joy, int fd) +{ + unsigned long abs_bits[NLONGS(ABS_CNT)] = {0}; + int stick; + int axis; + int name_sticks; + int name_throttles; + int res, i; + + /* Scan the axes to get their properties. */ + res = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits); + if (res < 0) + return false; + + stick = 0; + axis = 0; + name_sticks = 0; + name_throttles = 0; + + for (i = LJOY_AXIS_RANGE_START; i < LJOY_AXIS_RANGE_END; i++) { + struct input_absinfo absinfo; + + if (!TEST_BIT(i, abs_bits)) + continue; + + if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) + continue; + + if (is_single_axis_throttle(i)) { + /* One axis throttle. */ + name_throttles++; + joy->parent.info.stick[stick].flags = ALLEGRO_JOYFLAG_ANALOGUE; + joy->parent.info.stick[stick].num_axes = 1; + joy->parent.info.stick[stick].axis[0].name = "X"; + joy->parent.info.stick[stick].name = al_malloc(32); + snprintf((char *)joy->parent.info.stick[stick].name, 32, + "Throttle %d", name_throttles); + set_axis_mapping(&joy->axis_mapping[i], stick, 0, &absinfo); + stick++; + } + else { + /* Regular axis, two axis stick. */ + if (axis == 0) { + /* First axis of new joystick. */ + name_sticks++; + if (is_hat_axis(i)) { + joy->parent.info.stick[stick].flags = ALLEGRO_JOYFLAG_DIGITAL; + } else { + joy->parent.info.stick[stick].flags = ALLEGRO_JOYFLAG_ANALOGUE; + } + joy->parent.info.stick[stick].num_axes = 2; + joy->parent.info.stick[stick].axis[0].name = "X"; + joy->parent.info.stick[stick].axis[1].name = "Y"; + joy->parent.info.stick[stick].name = al_malloc(32); + snprintf((char *)joy->parent.info.stick[stick].name, 32, + "Stick %d", name_sticks); + set_axis_mapping(&joy->axis_mapping[i], stick, axis, &absinfo); + axis++; + } + else { + /* Second axis. */ + ASSERT(axis == 1); + set_axis_mapping(&joy->axis_mapping[i], stick, axis, &absinfo); + stick++; + axis = 0; + } + } + } + + joy->parent.info.num_sticks = stick; + + return true; +} + + + +static bool fill_joystick_buttons(ALLEGRO_JOYSTICK_LINUX *joy, int fd) +{ + unsigned long key_bits[NLONGS(KEY_CNT)] = {0}; + int b; + int i; + + if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits) < 0) + return false; + + b = 0; + + for (i = LJOY_BTN_RANGE_START; i < LJOY_BTN_RANGE_END; i++) { + if (TEST_BIT(i, key_bits) && is_joystick_button(i)) { + joy->button_mapping[b].ev_code = i; + ALLEGRO_DEBUG("Input event code %d maps to button %d\n", i, b); + + joy->parent.info.button[b].name = al_malloc(32); + snprintf((char *)joy->parent.info.button[b].name, 32, "B%d", b+1); + + b++; + if (b == _AL_MAX_JOYSTICK_BUTTONS) + break; + } + } + + joy->parent.info.num_buttons = b; + + /* Clear the rest. */ + for (; b < _AL_MAX_JOYSTICK_BUTTONS; b++) { + joy->button_mapping[b].ev_code = -1; + } + + return true; +} + + + +static void ljoy_device(ALLEGRO_USTR *device_name) { + ALLEGRO_JOYSTICK_LINUX *joy = ljoy_by_device_name(device_name); + if (joy) { + ALLEGRO_DEBUG("Device %s still exists\n", al_cstr(device_name)); + joy->marked = true; + return; + } + + /* Try to open the device. The device must be opened in O_RDWR mode to + * allow writing of haptic effects! The haptic driver for linux + * reuses the joystick driver's fd. + */ + int fd = open(al_cstr(device_name), O_RDWR|O_NONBLOCK); + if (fd == -1) { + ALLEGRO_WARN("Failed to open device %s\n", al_cstr(device_name)); + return; + } + + /* The device must have at least one joystick-related axis, and one + * joystick-related button. Some devices, such as mouse pads, have ABS_X + * and ABS_Y axes like a joystick but not joystick-related buttons. By + * checking for both axes and buttons, such devices can be excluded. + */ + if (!have_joystick_button(fd) || !have_joystick_axis(fd)) { + ALLEGRO_DEBUG("Device %s not a joystick\n", al_cstr(device_name)); + close(fd); + return; + } + + ALLEGRO_DEBUG("Device %s is new\n", al_cstr(device_name)); + + joy = ljoy_allocate_structure(); + joy->fd = fd; + joy->device_name = al_ustr_dup(device_name); + joy->config_state = LJOY_STATE_BORN; + joy->marked = true; + config_needs_merging = true; + + if (ioctl(fd, EVIOCGNAME(sizeof(joy->name)), joy->name) < 0) + strcpy(joy->name, "Unknown"); + + /* Map Linux input API axis and button numbers to ours, and fill in + * information. + */ + if (!fill_joystick_axes(joy, fd) || !fill_joystick_buttons(joy, fd)) { + ALLEGRO_ERROR("fill_joystick_info failed %s\n", al_cstr(device_name)); + inactivate_joy(joy); + close(fd); + return; + } + + /* Register the joystick with the fdwatch subsystem. */ + _al_unix_start_watching_fd(joy->fd, ljoy_process_new_data, joy); +} + + +static void ljoy_scan(bool configure) +{ + int num; + ALLEGRO_USTR *device_name; + unsigned i; + int t; + + /* Clear mark bits. */ + for (i = 0; i < _al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_LINUX **joypp = _al_vector_ref(&joysticks, i); + (*joypp)->marked = false; + } + + device_name = al_ustr_new(""); + + /* First try to read devices from allegro.cfg. */ + for (num = 0; num < 32; num++) { + if (!ljoy_detect_device_name(num, device_name)) + continue; + ljoy_device(device_name); + } + + /* Then scan /dev/input/by-path for *-event-joystick devices and if + * no device is found there scan all files in /dev/input. + * Note: That last step might be overkill, we probably don't need + * to support non-evdev kernels any longer. + */ + static char const *folders[] = {"/dev/input/by-path", "/dev/input"}; + for (t = 0; t < 2; t++) { + bool found = false; + ALLEGRO_FS_ENTRY *dir = al_create_fs_entry(folders[t]); + if (al_open_directory(dir)) { + static char const *suffix = "-event-joystick"; + while (true) { + ALLEGRO_FS_ENTRY *dev = al_read_directory(dir); + if (!dev) { + break; + } + if (al_get_fs_entry_mode(dev) & ALLEGRO_FILEMODE_ISDIR) { + al_destroy_fs_entry(dev); + continue; + } + char const *path = al_get_fs_entry_name(dev); + /* In the second pass in /dev/input we don't filter anymore. */ + if (t ==1 || strcmp(suffix, path + strlen(path) - strlen(suffix)) == 0) { + found = true; + al_ustr_assign_cstr(device_name, path); + ljoy_device(device_name); + } + al_destroy_fs_entry(dev); + } + al_close_directory(dir); + } + al_destroy_fs_entry(dir); + if (found) { + /* Don't scan the second folder if we found something in the + * first as it would be duplicates. + */ + break; + } + ALLEGRO_WARN("Could not find joysticks in %s\n", folders[t]); + } + + al_ustr_free(device_name); + + /* Schedule unmarked structures to be inactivated. */ + for (i = 0; i < _al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_LINUX **joypp = _al_vector_ref(&joysticks, i); + ALLEGRO_JOYSTICK_LINUX *joy = *joypp; + + if (joy->config_state == LJOY_STATE_ALIVE && !joy->marked) { + ALLEGRO_DEBUG("Device %s to be inactivated\n", + al_cstr(joy->device_name)); + joy->config_state = LJOY_STATE_DYING; + config_needs_merging = true; + } + } + + /* Generate a configure event if necessary. + * Even if we generated one before that the user hasn't responded to, + * we don't know if the user received it so always generate it. + */ + if (config_needs_merging && configure) { + ljoy_generate_configure_event(); + } +} + + + +static void ljoy_merge(void) +{ + unsigned i; + + config_needs_merging = false; + num_joysticks = 0; + + for (i = 0; i < _al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i); + ALLEGRO_JOYSTICK_LINUX *joy = *slot; + + switch (joy->config_state) { + case LJOY_STATE_UNUSED: + break; + + case LJOY_STATE_BORN: + case LJOY_STATE_ALIVE: + joy->config_state = LJOY_STATE_ALIVE; + num_joysticks++; + break; + + case LJOY_STATE_DYING: + inactivate_joy(joy); + break; + } + } + + ALLEGRO_DEBUG("Merge done, num_joysticks=%d\n", num_joysticks); +} + + + +#ifdef SUPPORT_HOTPLUG +/* ljoy_config_dev_changed: [fdwatch thread] + * Called when the /dev hierarchy changes. + */ +static void ljoy_config_dev_changed(void *data) +{ + char buf[128]; + (void)data; + + /* Empty the event buffer. We only care that some inotify event was sent but it + * doesn't matter what it is since we are going to do a full scan anyway once + * the timer_fd fires. + */ + while (read(inotify_fd, buf, sizeof(buf)) > 0) { + } + + al_signal_cond(hotplug_cond); +} + +static void *hotplug_proc(ALLEGRO_THREAD *thread, void *data) +{ + (void)data; + + while (!al_get_thread_should_stop(thread)) { + if (!hotplug_ended) { + al_wait_cond(hotplug_cond, hotplug_mutex); + } + if (hotplug_ended) { + break; + } + + al_rest(1); + + al_lock_mutex(config_mutex); + ljoy_scan(true); + al_unlock_mutex(config_mutex); + } + + hotplug_ended = false; + + return NULL; +} +#endif + + + +/* ljoy_init_joystick: [primary thread] + * Initialise the joystick driver. + */ +static bool ljoy_init_joystick(void) +{ + _al_vector_init(&joysticks, sizeof(ALLEGRO_JOYSTICK_LINUX *)); + num_joysticks = 0; + + if (!(config_mutex = al_create_mutex())) { + return false; + } + + // Scan for joysticks + ljoy_scan(false); + ljoy_merge(); + +#ifdef SUPPORT_HOTPLUG + if (!(hotplug_mutex = al_create_mutex())) { + al_destroy_mutex(config_mutex); + return false; + } + if (!(hotplug_cond = al_create_cond())) { + al_destroy_mutex(config_mutex); + al_destroy_mutex(hotplug_mutex); + return false; + } + if (!(hotplug_thread = al_create_thread(hotplug_proc, NULL))) { + al_destroy_mutex(config_mutex); + al_destroy_mutex(hotplug_mutex); + al_destroy_cond(hotplug_cond); + return false; + } + + al_start_thread(hotplug_thread); + + inotify_fd = inotify_init(); + if (inotify_fd != -1) { + fcntl(inotify_fd, F_SETFL, O_NONBLOCK); + /* Modern Linux probably only needs to monitor /dev/input. */ + inotify_add_watch(inotify_fd, "/dev/input", IN_CREATE|IN_DELETE); + _al_unix_start_watching_fd(inotify_fd, ljoy_config_dev_changed, NULL); + ALLEGRO_INFO("Hotplugging enabled\n"); + } + else { + ALLEGRO_WARN("Hotplugging not enabled\n"); + if (inotify_fd != -1) { + close(inotify_fd); + inotify_fd = -1; + } + } +#endif + + return true; +} + + + +/* ljoy_exit_joystick: [primary thread] + * Shut down the joystick driver. + */ +static void ljoy_exit_joystick(void) +{ + int i; + +#ifdef SUPPORT_HOTPLUG + if (inotify_fd != -1) { + _al_unix_stop_watching_fd(inotify_fd); + close(inotify_fd); + inotify_fd = -1; + } + hotplug_ended = true; + al_signal_cond(hotplug_cond); + al_join_thread(hotplug_thread, NULL); +#endif + + al_destroy_mutex(config_mutex); + config_mutex = NULL; + + for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i); + inactivate_joy(*slot); + al_free(*slot); + } + _al_vector_free(&joysticks); + num_joysticks = 0; +} + + + +/* ljoy_reconfigure_joysticks: [primary thread] + */ +static bool ljoy_reconfigure_joysticks(void) +{ + bool ret = false; + + al_lock_mutex(config_mutex); + + if (config_needs_merging) { + ljoy_merge(); + ret = true; + } + + al_unlock_mutex(config_mutex); + + return ret; +} + + + +/* ljoy_num_joysticks: [primary thread] + * + * Return the number of joysticks available on the system. + */ +static int ljoy_num_joysticks(void) +{ + return num_joysticks; +} + + + +/* ljoy_get_joystick: [primary thread] + * + * Returns the address of a ALLEGRO_JOYSTICK structure for the device + * number NUM. + */ +static ALLEGRO_JOYSTICK *ljoy_get_joystick(int num) +{ + ALLEGRO_JOYSTICK *ret = NULL; + unsigned i; + ASSERT(num >= 0); + + al_lock_mutex(config_mutex); + + for (i = 0; i < _al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i); + ALLEGRO_JOYSTICK_LINUX *joy = *slot; + + if (ACTIVE_STATE(joy->config_state)) { + if (num == 0) { + ret = (ALLEGRO_JOYSTICK *)joy; + break; + } + num--; + } + } + + al_unlock_mutex(config_mutex); + + return ret; +} + + + +/* ljoy_release_joystick: [primary thread] + * + * Close the device for a joystick then free the joystick structure. + */ +static void ljoy_release_joystick(ALLEGRO_JOYSTICK *joy_) +{ + (void)joy_; +} + + + +/* ljoy_get_joystick_state: [primary thread] + * + * Copy the internal joystick state to a user-provided structure. + */ +static void ljoy_get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *) joy_; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + _al_event_source_lock(es); + { + *ret_state = joy->joystate; + } + _al_event_source_unlock(es); +} + + + +static const char *ljoy_get_name(ALLEGRO_JOYSTICK *joy_) +{ + ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *)joy_; + return joy->name; +} + + + +static bool ljoy_get_active(ALLEGRO_JOYSTICK *joy_) +{ + ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *)joy_; + + return ACTIVE_STATE(joy->config_state); +} + + + +static int map_button_number(const ALLEGRO_JOYSTICK_LINUX *joy, int ev_code) +{ + int b; + + for (b = 0; b < _AL_MAX_JOYSTICK_BUTTONS; b++) { + if (joy->button_mapping[b].ev_code == ev_code) + return b; + } + + return -1; +} + + + +static float norm_pos(const AXIS_MAPPING *map, float value) +{ + const float range = (float)map->max - (float)map->min; + return ((value - (float)map->min) / range) * 2.0f - 1.0f; +} + + + +/* ljoy_process_new_data: [fdwatch thread] + * + * Process new data arriving in the joystick's fd. + */ +static void ljoy_process_new_data(void *data) +{ + ALLEGRO_JOYSTICK_LINUX *joy = data; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + if (!es) { + // Joystick driver not fully initialized + return; + } + + _al_event_source_lock(es); + { + struct input_event input_events[32]; + int bytes, nr, i; + + while ((bytes = read(joy->fd, &input_events, sizeof input_events)) > 0) { + nr = bytes / sizeof(struct input_event); + + for (i = 0; i < nr; i++) { + int type = input_events[i].type; + int code = input_events[i].code; + int value = input_events[i].value; + + if (type == EV_KEY) { + int number = map_button_number(joy, code); + if (number >= 0) { + if (value) + joy->joystate.button[number] = 32767; + else + joy->joystate.button[number] = 0; + + ljoy_generate_button_event(joy, number, + (value + ? ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN + : ALLEGRO_EVENT_JOYSTICK_BUTTON_UP)); + } + } + else if (type == EV_ABS) { + int number = code; + if (number < TOTAL_JOYSTICK_AXES) { + const AXIS_MAPPING *map = &joy->axis_mapping[number]; + int stick = map->stick; + int axis = map->axis; + float pos = norm_pos(map, value); + + joy->joystate.stick[stick].axis[axis] = pos; + ljoy_generate_axis_event(joy, stick, axis, pos); + } + } + } + } + } + _al_event_source_unlock(es); +} + + + +/* ljoy_generate_axis_event: [fdwatch thread] + * + * Helper to generate an event after an axis is moved. + * The joystick must be locked BEFORE entering this function. + */ +static void ljoy_generate_axis_event(ALLEGRO_JOYSTICK_LINUX *joy, int stick, int axis, float pos) +{ + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(es)) + return; + + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.timestamp = al_get_time(); + event.joystick.id = (ALLEGRO_JOYSTICK *)joy; + event.joystick.stick = stick; + event.joystick.axis = axis; + event.joystick.pos = pos; + event.joystick.button = 0; + + _al_event_source_emit_event(es, &event); +} + + + +/* ljoy_generate_button_event: [fdwatch thread] + * + * Helper to generate an event after a button is pressed or released. + * The joystick must be locked BEFORE entering this function. + */ +static void ljoy_generate_button_event(ALLEGRO_JOYSTICK_LINUX *joy, int button, ALLEGRO_EVENT_TYPE event_type) +{ + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(es)) + return; + + event.joystick.type = event_type; + event.joystick.timestamp = al_get_time(); + event.joystick.id = (ALLEGRO_JOYSTICK *)joy; + event.joystick.stick = 0; + event.joystick.axis = 0; + event.joystick.pos = 0.0; + event.joystick.button = button; + + _al_event_source_emit_event(es, &event); +} + +#endif /* ALLEGRO_HAVE_LINUX_INPUT_H */ + + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/linux/lkeybdnu.c b/allegro/src/linux/lkeybdnu.c new file mode 100644 index 00000000..d715672a --- /dev/null +++ b/allegro/src/linux/lkeybdnu.c @@ -0,0 +1,663 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux console keyboard driver. + * + * By Marek Habersack, modified by George Foot. + * + * Modified for the new keyboard API by Peter Wang. + * + * See readme.txt for copyright information. + * + *--- + * Recommended reading: + * + * - "Kernel Korner: The Linux keyboard driver" by Andries E. Brouwer + * http://www.linuxjournal.com/article.php?sid=1080 + * + * - Console Programming HOWTO + * + * TODO: diacriticals + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/platform/aintlnx.h" +#include "allegro5/platform/aintunix.h" + + +ALLEGRO_DEBUG_CHANNEL("keyboard") + + +#define PREFIX_I "al-ckey INFO: " +#define PREFIX_W "al-ckey WARNING: " +#define PREFIX_E "al-ckey ERROR: " + + + +typedef struct ALLEGRO_KEYBOARD_LINUX +{ + ALLEGRO_KEYBOARD parent; + int fd; + struct termios startup_termio; + struct termios work_termio; + int startup_kbmode; + ALLEGRO_KEYBOARD_STATE state; + unsigned int modifiers; + // Quit if Ctrl-Alt-Del is pressed. + bool three_finger_flag; + // Whether to let the LED lights if the . + bool key_led_flag; +} ALLEGRO_KEYBOARD_LINUX; + + + +/* the one and only keyboard object */ +static ALLEGRO_KEYBOARD_LINUX the_keyboard; + +/* the pid to kill when three finger saluting */ +static pid_t main_pid; + + + +/* forward declarations */ +static bool lkeybd_init_keyboard(void); +static void lkeybd_exit_keyboard(void); +static ALLEGRO_KEYBOARD *lkeybd_get_keyboard(void); +static bool lkeybd_set_keyboard_leds(int leds); +static void lkeybd_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state); +static void lkeybd_clear_keyboard_state(void); + +static void process_new_data(void *unused); +static void process_character(unsigned char ch); +static void handle_key_press(int mycode, unsigned int ascii); +static void handle_key_release(int mycode); + + + +/* the driver vtable */ +#define KEYDRV_LINUX AL_ID('L','N','X','C') + +static ALLEGRO_KEYBOARD_DRIVER keydrv_linux = +{ + KEYDRV_LINUX, + "", + "", + "Linux console keyboard", + lkeybd_init_keyboard, + lkeybd_exit_keyboard, + lkeybd_get_keyboard, + lkeybd_set_keyboard_leds, + NULL, /* const char *keycode_to_name(int keycode) */ + lkeybd_get_keyboard_state, + lkeybd_clear_keyboard_state +}; + + + +/* list the available drivers */ +_AL_DRIVER_INFO _al_linux_keyboard_driver_list[] = +{ + { KEYDRV_LINUX, &keydrv_linux, true }, + { 0, NULL, 0 } +}; + + + +/* + * Various ugly things. + */ + + +#define KB_MODIFIERS (ALLEGRO_KEYMOD_SHIFT | ALLEGRO_KEYMOD_CTRL | ALLEGRO_KEYMOD_ALT | \ + ALLEGRO_KEYMOD_ALTGR | ALLEGRO_KEYMOD_LWIN | ALLEGRO_KEYMOD_RWIN | \ + ALLEGRO_KEYMOD_MENU) + +#define KB_LED_FLAGS (ALLEGRO_KEYMOD_SCROLLLOCK | ALLEGRO_KEYMOD_NUMLOCK | \ + ALLEGRO_KEYMOD_CAPSLOCK) + + +/* lookup table for converting kernel keycodes into Allegro format */ +static unsigned char kernel_to_mycode[128] = +{ + /* 0x00 */ 0, ALLEGRO_KEY_ESCAPE, ALLEGRO_KEY_1, ALLEGRO_KEY_2, + /* 0x04 */ ALLEGRO_KEY_3, ALLEGRO_KEY_4, ALLEGRO_KEY_5, ALLEGRO_KEY_6, + /* 0x08 */ ALLEGRO_KEY_7, ALLEGRO_KEY_8, ALLEGRO_KEY_9, ALLEGRO_KEY_0, + /* 0x0C */ ALLEGRO_KEY_MINUS, ALLEGRO_KEY_EQUALS, ALLEGRO_KEY_BACKSPACE, ALLEGRO_KEY_TAB, + /* 0x10 */ ALLEGRO_KEY_Q, ALLEGRO_KEY_W, ALLEGRO_KEY_E, ALLEGRO_KEY_R, + /* 0x14 */ ALLEGRO_KEY_T, ALLEGRO_KEY_Y, ALLEGRO_KEY_U, ALLEGRO_KEY_I, + /* 0x18 */ ALLEGRO_KEY_O, ALLEGRO_KEY_P, ALLEGRO_KEY_OPENBRACE, ALLEGRO_KEY_CLOSEBRACE, + /* 0x1C */ ALLEGRO_KEY_ENTER, ALLEGRO_KEY_LCTRL, ALLEGRO_KEY_A, ALLEGRO_KEY_S, + /* 0x20 */ ALLEGRO_KEY_D, ALLEGRO_KEY_F, ALLEGRO_KEY_G, ALLEGRO_KEY_H, + /* 0x24 */ ALLEGRO_KEY_J, ALLEGRO_KEY_K, ALLEGRO_KEY_L, ALLEGRO_KEY_SEMICOLON, + /* 0x28 */ ALLEGRO_KEY_QUOTE, ALLEGRO_KEY_TILDE, ALLEGRO_KEY_LSHIFT, ALLEGRO_KEY_BACKSLASH, + /* 0x2C */ ALLEGRO_KEY_Z, ALLEGRO_KEY_X, ALLEGRO_KEY_C, ALLEGRO_KEY_V, + /* 0x30 */ ALLEGRO_KEY_B, ALLEGRO_KEY_N, ALLEGRO_KEY_M, ALLEGRO_KEY_COMMA, + /* 0x34 */ ALLEGRO_KEY_FULLSTOP, ALLEGRO_KEY_SLASH, ALLEGRO_KEY_RSHIFT, ALLEGRO_KEY_PAD_ASTERISK, + /* 0x38 */ ALLEGRO_KEY_ALT, ALLEGRO_KEY_SPACE, ALLEGRO_KEY_CAPSLOCK, ALLEGRO_KEY_F1, + /* 0x3C */ ALLEGRO_KEY_F2, ALLEGRO_KEY_F3, ALLEGRO_KEY_F4, ALLEGRO_KEY_F5, + /* 0x40 */ ALLEGRO_KEY_F6, ALLEGRO_KEY_F7, ALLEGRO_KEY_F8, ALLEGRO_KEY_F9, + /* 0x44 */ ALLEGRO_KEY_F10, ALLEGRO_KEY_NUMLOCK, ALLEGRO_KEY_SCROLLLOCK, ALLEGRO_KEY_PAD_7, + /* 0x48 */ ALLEGRO_KEY_PAD_8, ALLEGRO_KEY_PAD_9, ALLEGRO_KEY_PAD_MINUS, ALLEGRO_KEY_PAD_4, + /* 0x4C */ ALLEGRO_KEY_PAD_5, ALLEGRO_KEY_PAD_6, ALLEGRO_KEY_PAD_PLUS, ALLEGRO_KEY_PAD_1, + /* 0x50 */ ALLEGRO_KEY_PAD_2, ALLEGRO_KEY_PAD_3, ALLEGRO_KEY_PAD_0, ALLEGRO_KEY_PAD_DELETE, + /* 0x54 */ ALLEGRO_KEY_PRINTSCREEN, 0, ALLEGRO_KEY_BACKSLASH2, ALLEGRO_KEY_F11, + /* 0x58 */ ALLEGRO_KEY_F12, 0, 0, 0, + /* 0x5C */ 0, 0, 0, 0, + /* 0x60 */ ALLEGRO_KEY_PAD_ENTER, ALLEGRO_KEY_RCTRL, ALLEGRO_KEY_PAD_SLASH, ALLEGRO_KEY_PRINTSCREEN, + /* 0x64 */ ALLEGRO_KEY_ALTGR, ALLEGRO_KEY_PAUSE, ALLEGRO_KEY_HOME, ALLEGRO_KEY_UP, + /* 0x68 */ ALLEGRO_KEY_PGUP, ALLEGRO_KEY_LEFT, ALLEGRO_KEY_RIGHT, ALLEGRO_KEY_END, + /* 0x6C */ ALLEGRO_KEY_DOWN, ALLEGRO_KEY_PGDN, ALLEGRO_KEY_INSERT, ALLEGRO_KEY_DELETE, + /* 0x70 */ 0, 0, 0, 0, + /* 0x74 */ 0, 0, 0, ALLEGRO_KEY_PAUSE, + /* 0x78 */ 0, 0, 0, 0, + /* 0x7C */ 0, ALLEGRO_KEY_LWIN, ALLEGRO_KEY_RWIN, ALLEGRO_KEY_MENU + + /* "Two keys are unusual in the sense that their keycode is not constant, + * but depends on modifiers. The PrintScrn key will yield keycode 84 when + * combined with either Alt key, but keycode 99 otherwise. The Pause key + * will yield keycode 101 when combined with either Ctrl key, but keycode + * 119 otherwise. (This has historic reasons, but might change, to free + * keycodes 99 and 119 for other purposes.)" + */ +}; + + +/* convert kernel keycodes for numpad keys into ASCII characters */ +#define NUM_PAD_KEYS 17 +static const char pad_asciis[NUM_PAD_KEYS] = +{ + '0','1','2','3','4','5','6','7','8','9', + '+','-','*','/','\r',',','.' +}; +static const char pad_asciis_no_numlock[NUM_PAD_KEYS] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + '+', '-', '*', '/', '\r', 0, 0 +}; + + +/* convert Allegro format keycodes into ALLEGRO_KEYMOD_* */ +static const unsigned int modifier_table[ALLEGRO_KEY_MAX - ALLEGRO_KEY_MODIFIERS] = +{ + ALLEGRO_KEYMOD_SHIFT, ALLEGRO_KEYMOD_SHIFT, ALLEGRO_KEYMOD_CTRL, + ALLEGRO_KEYMOD_CTRL, ALLEGRO_KEYMOD_ALT, ALLEGRO_KEYMOD_ALTGR, + ALLEGRO_KEYMOD_LWIN, ALLEGRO_KEYMOD_RWIN, ALLEGRO_KEYMOD_MENU, + ALLEGRO_KEYMOD_SCROLLLOCK, ALLEGRO_KEYMOD_NUMLOCK, ALLEGRO_KEYMOD_CAPSLOCK +}; + + + +/* keycode_to_char: [fdwatch thread] + * Helper function. + * KEYCODE is a Linux kernel keycode, not an Allegro keycode. + * + * In the process of doing the translation, we may find that the user + * has pressed a key that for VT switching. In that case a negative + * number is returned, the absolute value of which is the VT to + * switch to. Yes, ugly. + */ +static int keycode_to_char(int keycode) +{ + const unsigned int modifiers = the_keyboard.modifiers; + struct kbentry kbe; + int keymap; + int ascii; + + /* build kernel keymap number */ + keymap = 0; + if (modifiers & ALLEGRO_KEYMOD_SHIFT) keymap |= 1; + if (modifiers & ALLEGRO_KEYMOD_ALTGR) keymap |= 2; + if (modifiers & ALLEGRO_KEYMOD_CTRL) keymap |= 4; + if (modifiers & ALLEGRO_KEYMOD_ALT) keymap |= 8; + + /* map keycode to type and value */ + kbe.kb_table = keymap; + kbe.kb_index = keycode; + ioctl(the_keyboard.fd, KDGKBENT, &kbe); + + if (keycode == KEY_BACKSPACE) + ascii = 8; + else { + if (kbe.kb_value == K_NOSUCHMAP) { + /* invalid keymaps */ + /* FIXME: Maybe we should just redo the */ + /* ioctl with keymap 0? */ + ascii = 0; + } + else { + /* most keys come here */ + ascii = KVAL(kbe.kb_value); + } + } + + /* finally do some things based on key type */ + switch (KTYP(kbe.kb_value)) { + + case KT_CONS: + /* VT switch key -- return a negative number */ + return -( KVAL(kbe.kb_value)+1 ); + + case KT_LETTER: + /* apply capslock translation. */ + if (modifiers & ALLEGRO_KEYMOD_CAPSLOCK) + return ascii ^ 0x20; + else + return ascii; + + case KT_LATIN: + case KT_ASCII: + return ascii; + + case KT_PAD: + { + int val = KVAL(kbe.kb_value); + if (modifiers & ALLEGRO_KEYMOD_NUMLOCK) { + if ((val >= 0) && (val < NUM_PAD_KEYS)) + ascii = pad_asciis[val]; + } else { + if ((val >= 0) && (val < NUM_PAD_KEYS)) + ascii = pad_asciis_no_numlock[val]; + } + return ascii; + } + + case KT_SPEC: + if (keycode == KEY_ENTER) + return '\r'; + else + return 0; + + default: + /* dunno */ + return 0; + } +} + + + +/* lkeybd_init_keyboard: [primary thread] + * Initialise the keyboard driver. + */ +static bool lkeybd_init_keyboard(void) +{ + bool can_restore_termio_and_kbmode = false; + + memset(&the_keyboard, 0, sizeof the_keyboard); + +/* + if (__al_linux_use_console()) + return false; +*/ + the_keyboard.fd = open("/dev/tty", O_RDWR); + + /* Save the current terminal attributes, which we will restore when + * we close up shop. + */ + if (tcgetattr(the_keyboard.fd, &the_keyboard.startup_termio) != 0) { + goto Error; + } + + /* Save previous keyboard mode (probably XLATE). */ + if (ioctl(the_keyboard.fd, KDGKBMODE, &the_keyboard.startup_kbmode) != 0) { + //goto Error; + } + + can_restore_termio_and_kbmode = false; + + /* Set terminal attributes we need. + * + * Input modes (c_iflag): We want to disable: + * - stripping bytes to 7 bits + * - ignoring of carriage returns + * - translating of carriage returns to newlines, and vice versa + * - start/stop control on input and output + * + * Control modes (c_cflag): We want 8 bits per byte. + * + * Local modes (c_lflag: We want to disable: + * - canonical (line by line) input + * - echoing input back to the display + * - interpretation of signal characters + * + * The c_iflag, c_lflag settings come from svgalib. Allegro 4 + * simply set them to 0, which is a bit crude. + */ + the_keyboard.work_termio = the_keyboard.startup_termio; + the_keyboard.work_termio.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); + the_keyboard.work_termio.c_cflag &= ~CSIZE; + the_keyboard.work_termio.c_cflag |= CS8; + the_keyboard.work_termio.c_lflag &= ~(ICANON | ECHO | ISIG); + + if (tcsetattr(the_keyboard.fd, TCSANOW, &the_keyboard.work_termio) != 0) { + goto Error; + } + + /* Set the keyboard mode to mediumraw. */ + if (ioctl(the_keyboard.fd, KDSKBMODE, K_MEDIUMRAW) != 0) { + //goto Error; + } + + the_keyboard.three_finger_flag = true; + the_keyboard.key_led_flag = true; + + const char *value = al_get_config_value(al_get_system_config(), + "keyboard", "enable_three_finger_exit"); + if (value) { + the_keyboard.three_finger_flag = !strncmp(value, "true", 4); + } + value = al_get_config_value(al_get_system_config(), + "keyboard", "enable_key_led_toggle"); + if (value) { + the_keyboard.key_led_flag = !strncmp(value, "true", 4); + } + + ALLEGRO_DEBUG("Three finger flag enabled: %s\n", + the_keyboard.three_finger_flag ? "true" : "false"); + ALLEGRO_DEBUG("Key LED toggle enabled: %s\n", + the_keyboard.key_led_flag ? "true" : "false"); + + /* Initialise the keyboard object for use as an event source. */ + _al_event_source_init(&the_keyboard.parent.es); + + /* Start watching for data on the fd. */ + _al_unix_start_watching_fd(the_keyboard.fd, process_new_data, NULL); + + /* Get the pid, which we use for the three finger salute */ + main_pid = getpid(); + + return true; + + Error: + + if (can_restore_termio_and_kbmode) { + tcsetattr(the_keyboard.fd, TCSANOW, &the_keyboard.startup_termio); + ioctl(the_keyboard.fd, KDSKBMODE, the_keyboard.startup_kbmode); + } + + close(the_keyboard.fd); + +/* + __al_linux_leave_console(); +*/ + + return false; +} + + + +/* lkeybd_exit_keyboard: [primary thread] + * Shut down the keyboard driver. + */ +static void lkeybd_exit_keyboard(void) +{ + _al_unix_stop_watching_fd(the_keyboard.fd); + + _al_event_source_free(&the_keyboard.parent.es); + + /* Restore terminal attrs, keyboard mode, and reset the LED mode. */ + tcsetattr(the_keyboard.fd, TCSANOW, &the_keyboard.startup_termio); + ioctl(the_keyboard.fd, KDSKBMODE, the_keyboard.startup_kbmode); + ioctl(the_keyboard.fd, KDSETLED, 8); + + close(the_keyboard.fd); + + //__al_linux_leave_console(); + + /* This may help catch bugs in the user program, since the pointer + * we return to the user is always the same. + */ + memset(&the_keyboard, 0, sizeof the_keyboard); +} + + + +/* lkeybd_get_keyboard: + * Returns the address of a ALLEGRO_KEYBOARD structure representing the keyboard. + */ +static ALLEGRO_KEYBOARD *lkeybd_get_keyboard(void) +{ + return (ALLEGRO_KEYBOARD *)&the_keyboard; +} + + + +/* lkeybd_set_keyboard_leds: + * Updates the LED state. + */ +static bool lkeybd_set_keyboard_leds(int leds) +{ + int val = 0; + + if (leds & ALLEGRO_KEYMOD_SCROLLLOCK) val |= LED_SCR; + if (leds & ALLEGRO_KEYMOD_NUMLOCK) val |= LED_NUM; + if (leds & ALLEGRO_KEYMOD_CAPSLOCK) val |= LED_CAP; + + return (ioctl(the_keyboard.fd, KDSETLED, val) == 0) ? true : false; +} + + + +/* lkeybd_get_keyboard_state: [primary thread] + * Copy the current keyboard state into RET_STATE, with any necessary locking. + */ +static void lkeybd_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) +{ + _al_event_source_lock(&the_keyboard.parent.es); + { + *ret_state = the_keyboard.state; + } + _al_event_source_unlock(&the_keyboard.parent.es); +} + + + +/* lkeybd_clear_keyboard_state: [primary thread] + * Clear the current keyboard state, with any necessary locking. + */ +static void lkeybd_clear_keyboard_state(void) +{ + _al_event_source_lock(&the_keyboard.parent.es); + { + memset(&the_keyboard.state, 0, sizeof(the_keyboard.state)); + } + _al_event_source_unlock(&the_keyboard.parent.es); +} + + + +/* process_new_data: [fdwatch thread] + * Process new data arriving in the keyboard's fd. + */ +static void process_new_data(void *unused) +{ + _al_event_source_lock(&the_keyboard.parent.es); + { + unsigned char buf[128]; + size_t bytes_read; + unsigned int ch; + + bytes_read = read(the_keyboard.fd, &buf, sizeof(buf)); + for (ch = 0; ch < bytes_read; ch++) + process_character(buf[ch]); + } + _al_event_source_unlock(&the_keyboard.parent.es); + + (void)unused; +} + + + +/* process_character: [fdwatch thread] + * This is where most of the work gets done. CH is a byte read in + * from the keyboard's fd. This function finds the Allegro equivalent + * of that key code, figures out which ASCII character that key + * generates (if any), and then calls the handle_key_press() and + * handle_key_release() functions with that information. It also does + * some things with modifier keys. + */ +static void process_character(unsigned char ch) +{ + /* read kernel's keycode and convert to Allegro's keycode */ + int keycode = ch & 0x7f; + bool press = !(ch & 0x80); + int mycode = kernel_to_mycode[keycode]; + + /* if the key was something weird we don't understand, skip it */ + if (mycode == 0) + return; + + /* process modifiers */ + if (mycode >= ALLEGRO_KEY_MODIFIERS) { + int flag = modifier_table[mycode - ALLEGRO_KEY_MODIFIERS]; + if (press) { + if (flag & KB_MODIFIERS) + the_keyboard.modifiers |= flag; + else if ((flag & KB_LED_FLAGS) && the_keyboard.key_led_flag) + the_keyboard.modifiers ^= flag; + } + else { + /* XXX: if the user presses LCTRL, then RCTRL, then releases + * LCTRL, the ALLEGRO_KEYMOD_CTRL modifier should still be on. + */ + if (flag & KB_MODIFIERS) + the_keyboard.modifiers &= ~flag; + } + } + + /* call the handlers */ + if (press) { + int ascii = keycode_to_char(keycode); + + /* switch VT if the user requested so */ + if (ascii < 0) { + int console = -ascii; + int last_console; + + ioctl(the_keyboard.fd, VT_OPENQRY, &last_console); + if (console < last_console) + if (ioctl(the_keyboard.fd, VT_ACTIVATE, console) == 0) + return; + } + + handle_key_press(mycode, ascii); + } + else { + handle_key_release(mycode); + } + + /* three-finger salute for killing the program */ + if ((the_keyboard.three_finger_flag) + && ((mycode == ALLEGRO_KEY_DELETE) || (mycode == ALLEGRO_KEY_END)) + && (the_keyboard.modifiers & ALLEGRO_KEYMOD_CTRL) + && (the_keyboard.modifiers & ALLEGRO_KEYMOD_ALT)) + { + kill(main_pid, SIGTERM); + } +} + + + +/* handle_key_press: [fdwatch thread] + * Helper: stuff to do when a key is pressed. + */ +static void handle_key_press(int mycode, unsigned int ascii) +{ + ALLEGRO_EVENT_TYPE event_type; + ALLEGRO_EVENT event; + + event_type = (_AL_KEYBOARD_STATE_KEY_DOWN(the_keyboard.state, mycode) + ? ALLEGRO_EVENT_KEY_CHAR + : ALLEGRO_EVENT_KEY_DOWN); + + /* Maintain the key_down array. */ + _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_keyboard.state, mycode); + + /* Generate key press/repeat events if necessary. */ + if (!_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) + return; + + event.keyboard.type = event_type; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = NULL; + event.keyboard.keycode = mycode; + event.keyboard.unichar = ascii; + event.keyboard.modifiers = the_keyboard.modifiers; + + _al_event_source_emit_event(&the_keyboard.parent.es, &event); + + /* The first press should generate a KEY_CHAR also */ + if (event_type == ALLEGRO_EVENT_KEY_DOWN) { + event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; + event.keyboard.timestamp = al_get_time(); + _al_event_source_emit_event(&the_keyboard.parent.es, &event); + } +} + + + +/* handle_key_release: [fdwatch thread] + * Helper: stuff to do when a key is released. + */ +static void handle_key_release(int mycode) +{ + ALLEGRO_EVENT event; + + /* This can happen, e.g. when we are switching back into a VT with + * ALT+Fn, we only get the release event of the function key. + */ + if (!_AL_KEYBOARD_STATE_KEY_DOWN(the_keyboard.state, mycode)) + return; + + /* Maintain the key_down array. */ + _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_keyboard.state, mycode); + + /* Generate key release events if necessary. */ + if (!_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) + return; + + event.keyboard.type = ALLEGRO_EVENT_KEY_UP; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = NULL; + event.keyboard.keycode = mycode; + event.keyboard.unichar = 0; + event.keyboard.modifiers = the_keyboard.modifiers; + + _al_event_source_emit_event(&the_keyboard.parent.es, &event); +} + + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/src/linux/lmemory.c b/allegro/src/linux/lmemory.c new file mode 100644 index 00000000..a6cd95c2 --- /dev/null +++ b/allegro/src/linux/lmemory.c @@ -0,0 +1,94 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Memory mapping helpers for Linux Allegro. + * + * By George Foot, heavily based upon Marek Habersack's code. + * + * See readme.txt for copyright information. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" + +#if !defined(_POSIX_MAPPED_FILES) || !defined(ALLEGRO_HAVE_MMAP) +#error "Sorry, mapped files are required for Linux console Allegro to work!" +#endif + +#include +#include + + +static int mem_fd = -1; /* fd of /dev/mem */ + +/* __al_linux_init_memory: + * Prepares to be able to map memory; returns 0 on success. + */ +int __al_linux_init_memory (void) +{ + mem_fd = open ("/dev/mem", O_RDWR); + if (mem_fd < 0) return 1; + + mprotect ((void *)&mem_fd, sizeof mem_fd, PROT_READ); + return 0; +} + +/* __al_linux_shutdown_memory: + * Turns off memory mapping, returning 0 on success. + */ +int __al_linux_shutdown_memory (void) +{ + if (mem_fd < 0) return 1; + + mprotect ((void *)&mem_fd, sizeof mem_fd, PROT_READ | PROT_WRITE); + close (mem_fd); + mem_fd = -1; + return 0; +} + + +/* __al_linux_map_memory: + * Given a MAPPED_MEMORY struct with physical address, size and + * permissions filled in, this function maps the memory and fills + * in the pointer in the struct. Returns 0 on success; errno will + * be set on error. + */ +int __al_linux_map_memory (struct MAPPED_MEMORY *info) +{ + ASSERT(info); + info->data = mmap (0, info->size, info->perms, MAP_SHARED, mem_fd, info->base); + if (info->data == MAP_FAILED) { + info->data = NULL; + return 1; + } + return 0; +} + +/* __al_linux_unmap_memory: + * Given a MAPPED_MEMORY struct, this function unmaps + * the block. Returns 0 on success, errno set on error. + */ +int __al_linux_unmap_memory (struct MAPPED_MEMORY *info) +{ + ASSERT(info); + if (info->data == NULL) + return 0; + if (!munmap (info->data, info->size)) { + info->data = NULL; + return 0; + } + return 1; +} + diff --git a/allegro/src/linux/lmouse.c b/allegro/src/linux/lmouse.c new file mode 100644 index 00000000..97c48a8d --- /dev/null +++ b/allegro/src/linux/lmouse.c @@ -0,0 +1,279 @@ +#error This file is no longer used. + +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux console mouse module. + * + * By George Foot. + * + * This file contains a generic framework for different mouse + * types to hook into. See lmseps2.c for an example. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/linalleg.h" + + +static int mouse_mx = 0; /* internal position, in mickeys */ +static int mouse_my = 0; + +static int mouse_sx = 128; /* mickey -> pixel scaling factor */ +static int mouse_sy = 128; + +static int mouse_minx = 0; /* mouse range */ +static int mouse_miny = 0; +static int mouse_maxx = 319; +static int mouse_maxy = 199; + +static int mymickey_x = 0; /* for get_mouse_mickeys() */ +static int mymickey_y = 0; + +#define MICKEY_TO_COORD_X(n) ((n) * mouse_sx / 256) +#define MICKEY_TO_COORD_Y(n) ((n) * mouse_sy / 256) + +#define COORD_TO_MICKEY_X(n) ((n) * 256 / mouse_sx) +#define COORD_TO_MICKEY_Y(n) ((n) * 256 / mouse_sy) + + +/* __al_linux_mouse_position: + * Sets the position of the mickey-mode mouse. + */ +void __al_linux_mouse_position(int x, int y) +{ + DISABLE(); + + _mouse_x = x; + _mouse_y = y; + + mouse_mx = COORD_TO_MICKEY_X(x); + mouse_my = COORD_TO_MICKEY_Y(y); + + mymickey_x = mymickey_y = 0; + + ENABLE(); +} + +/* __al_linux_mouse_set_range: + * Sets the range of the mickey-mode mouse. + */ +void __al_linux_mouse_set_range(int x1, int y1, int x2, int y2) +{ + mouse_minx = x1; + mouse_miny = y1; + mouse_maxx = x2; + mouse_maxy = y2; + + DISABLE(); + + _mouse_x = CLAMP(mouse_minx, _mouse_x, mouse_maxx); + _mouse_y = CLAMP(mouse_miny, _mouse_y, mouse_maxy); + + mouse_mx = COORD_TO_MICKEY_X(_mouse_x); + mouse_my = COORD_TO_MICKEY_Y(_mouse_y); + + ENABLE(); +} + +/* __al_linux_mouse_set_speed: + * Sets the speed of the mickey-mode mouse. + */ +void __al_linux_mouse_set_speed(int xspeed, int yspeed) +{ + int scale; + + if (gfx_driver) + scale = 256*gfx_driver->w/320; + else + scale = 256; + + DISABLE(); + + mouse_sx = scale / MAX(1, xspeed); + mouse_sy = scale / MAX(1, yspeed); + + mouse_mx = COORD_TO_MICKEY_X(_mouse_x); + mouse_my = COORD_TO_MICKEY_Y(_mouse_y); + + ENABLE(); +} + +/* __al_linux_mouse_get_mickeys: + * Reads the mickey-mode count. + */ +void __al_linux_mouse_get_mickeys(int *mickeyx, int *mickeyy) +{ + int temp_x = mymickey_x; + int temp_y = mymickey_y; + + mymickey_x -= temp_x; + mymickey_y -= temp_y; + + *mickeyx = temp_x; + *mickeyy = temp_y; +} + +/* __al_linux_mouse_handler: + * Movement callback for mickey-mode driver. + */ +void __al_linux_mouse_handler (int x, int y, int z, int b) +{ + _mouse_b = b; + + mymickey_x += x; + mymickey_y -= y; + + mouse_mx += x; + mouse_my -= y; + + _mouse_x = MICKEY_TO_COORD_X(mouse_mx); + _mouse_y = MICKEY_TO_COORD_Y(mouse_my); + _mouse_z += z; + + if ((_mouse_x < mouse_minx) || (_mouse_x > mouse_maxx) || + (_mouse_y < mouse_miny) || (_mouse_y > mouse_maxy)) { + + _mouse_x = CLAMP(mouse_minx, _mouse_x, mouse_maxx); + _mouse_y = CLAMP(mouse_miny, _mouse_y, mouse_maxy); + + mouse_mx = COORD_TO_MICKEY_X(_mouse_x); + mouse_my = COORD_TO_MICKEY_Y(_mouse_y); + } + + _handle_mouse_input(); +} + + +static int update_mouse (void); +static void resume_mouse (void); +static void suspend_mouse (void); + +static STD_DRIVER std_mouse = { + STD_MOUSE, + update_mouse, + resume_mouse, + suspend_mouse, + -1 /* fd -- filled in later */ +}; + + +#include +#include +#include +#include +#include +#include + + +static int resume_count; +static INTERNAL_MOUSE_DRIVER *internal_driver; + + +/* update_mouse: + * Reads data from the mouse, attempting to process it. + */ +static int update_mouse (void) +{ + static unsigned char buf[1024]; + static int bytes_in_buffer = 0; + int bytes_read; + fd_set set; + struct timeval tv = { 0, 0 }; + + if (resume_count <= 0) + return 0; + + FD_ZERO(&set); + FD_SET(std_mouse.fd, &set); + if (select (FD_SETSIZE, &set, NULL, NULL, &tv) <= 0) + return 0; + + bytes_read = read(std_mouse.fd, &buf[bytes_in_buffer], sizeof(buf) - bytes_in_buffer); + if (bytes_read <= 0) + return 0; + + bytes_in_buffer += bytes_read; + + while (bytes_in_buffer && (bytes_read = internal_driver->process (buf, bytes_in_buffer))) { + int i; + bytes_in_buffer -= bytes_read; + for (i = 0; i < bytes_in_buffer; i++) + buf[i] = buf[i+bytes_read]; + } + + return 1; +} + + +/* activate_mouse: + * Put mouse device into the mode we want. + */ +static void activate_mouse (void) +{ +} + +/* deactivate_mouse: + * Restore the original settings. + */ +static void deactivate_mouse (void) +{ +} + +/* suspend_mouse: + * Suspend our mouse handling. + */ +static void suspend_mouse (void) +{ + resume_count--; + if (resume_count == 0) + deactivate_mouse(); +} + +/* resume_mouse: + * Start/resume Allegro mouse handling. + */ +static void resume_mouse (void) +{ + if (resume_count == 0) + activate_mouse(); + resume_count++; +} + + +/* __al_linux_mouse_init: + * Sets up the mouse driver. + */ +int __al_linux_mouse_init (INTERNAL_MOUSE_DRIVER *drv) +{ + internal_driver = drv; + std_mouse.fd = drv->device; + + /* Mouse is disabled now. */ + resume_count = 0; + + /* Register our driver (enables it too). */ + __al_linux_add_standard_driver (&std_mouse); + + return internal_driver->num_buttons; +} + +/* __al_linux_mouse_exit: + * Removes our driver. + */ +void __al_linux_mouse_exit (void) +{ + __al_linux_remove_standard_driver (&std_mouse); +} + diff --git a/allegro/src/linux/lmsedrv.c b/allegro/src/linux/lmsedrv.c new file mode 100644 index 00000000..3a6bcab4 --- /dev/null +++ b/allegro/src/linux/lmsedrv.c @@ -0,0 +1,46 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux console mouse driver list. + * + * By George Foot. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/platform/aintlnx.h" + +#ifdef ALLEGRO_RASPBERRYPI +#include "allegro5/internal/aintern_raspberrypi.h" +#endif + +/* list the available drivers */ +_AL_DRIVER_INFO _al_linux_mouse_driver_list[] = +{ + /* These drivers have not been updated for the new mouse API. + * They may be updated as required, although the evdev driver + * should be fine on modern kernels --pw + */ +/* { MOUSEDRV_LINUX_GPMDATA, &mousedrv_linux_gpmdata, true },*/ +/* { MOUSEDRV_LINUX_MS, &mousedrv_linux_ms, true },*/ +/* { MOUSEDRV_LINUX_IMS, &mousedrv_linux_ims, true },*/ +/* { MOUSEDRV_LINUX_PS2, &mousedrv_linux_ps2, true },*/ +/* { MOUSEDRV_LINUX_IPS2, &mousedrv_linux_ips2, true },*/ +#if defined ALLEGRO_HAVE_LINUX_INPUT_H || defined ALLEGRO_RASPBERRYPI + { AL_MOUSEDRV_LINUX_EVDEV, &_al_mousedrv_linux_evdev, true }, +#endif + { 0, NULL, 0 } +}; + diff --git a/allegro/src/linux/lmseev.c b/allegro/src/linux/lmseev.c new file mode 100644 index 00000000..da83804d --- /dev/null +++ b/allegro/src/linux/lmseev.c @@ -0,0 +1,853 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux console mouse driver for event interface (EVDEV). + * + * By Annie Testes. + * + * Handles all inputs that fill evdev with informations + * about movement and click. + * + * Hacked for new mouse API by Peter Wang. + * + * See readme.txt for copyright information. + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#include "allegro5/allegro.h" + +#ifdef ALLEGRO_HAVE_LINUX_INPUT_H + +ALLEGRO_DEBUG_CHANNEL("lmseev"); + +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/platform/aintlnx.h" + +#ifdef ALLEGRO_RASPBERRYPI +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_vector.h" +#endif + +#include +#include +#include +#include + +#define PREFIX_I "al-evdev INFO: " +#define PREFIX_W "al-evdev WARNING: " +#define PREFIX_E "al-evdev ERROR: " + + +typedef struct AL_MOUSE_EVDEV +{ + ALLEGRO_MOUSE parent; + int fd; + ALLEGRO_MOUSE_STATE state; +} AL_MOUSE_EVDEV; + + +/* the one and only mouse object */ +static AL_MOUSE_EVDEV the_mouse; + + + +/* forward declarations */ +static void process_new_data(void *unused); +static void process_event(struct input_event *event); +static void handle_button_event(unsigned int button, bool is_down); +static void handle_axis_event(int dx, int dy, int dz); +static void generate_mouse_event(unsigned int type, + int x, int y, int z, + int dx, int dy, int dz, + unsigned int button); +bool _al_evdev_set_mouse_range(int x1, int y1, int x2, int y2); + + + +/* + * Tools data + */ + +/* Tool mode + * This mode is the behavior the user sees, it is not the way the device + * reports the position. + * Tools that send relative informations can only be in relative mode, + * tools that send absolute informations can be either in absolute mode or in + * relative mode */ +typedef enum { + MODE_RELATIVE, + MODE_ABSOLUTE +} MODE; + + + +typedef struct TOOL { + int tool_id; /* One of the BTN_TOOL_... from linux/input.h */ + MODE mode; /* Relative or absolute */ +} TOOL; + + + +static TOOL tools[] = { + { BTN_TOOL_MOUSE, MODE_RELATIVE }, + { BTN_TOOL_PEN, MODE_ABSOLUTE }, + { BTN_TOOL_RUBBER, MODE_ABSOLUTE }, + { BTN_TOOL_BRUSH, MODE_ABSOLUTE }, + { BTN_TOOL_PENCIL, MODE_ABSOLUTE }, + { BTN_TOOL_AIRBRUSH, MODE_ABSOLUTE }, + { BTN_TOOL_FINGER, MODE_ABSOLUTE }, + { BTN_TOOL_LENS, MODE_ABSOLUTE }, + + { -1, MODE_ABSOLUTE } /* No tool */ +}; + + + +/* Default tool, in case the device does not send a tool id */ +static TOOL *default_tool = tools + 0; + +static TOOL *no_tool = tools + (sizeof(tools)/sizeof(tools[0]) - 1); + +static TOOL *current_tool; + + + +/* find_tool: + * Returns the tool with id 'tool_id' which is one of the BTN_TOOL_... defined + * in linux/input.h. Returns 'default_tool' if not found. + */ +static TOOL *find_tool(int tool_id) +{ + TOOL *t; + for (t=tools; t!=no_tool; t++) { + if (t->tool_id == tool_id) + return t; + } + return default_tool; +} + + + + +/* + * Pointer axis + */ +typedef struct AXIS { + int in_min; /* For absolute mode */ + int in_max; /* For absolute mode */ + int out_min; /* For absolute mode */ + int out_max; /* For absolute mode */ + + float speed; /* For set_mouse_speed */ + int mickeys; /* For get_mouse_mickeys */ + float scale; /* Scale factor, because tablet mice generate more movement + than common mice */ + + int in_abs; /* Current absolute position, used for absolute input, + whether the output is absolute or relative */ + int out_abs; /* Position on the screen */ +} AXIS; + + +#define IN_RANGE(axis) ( (axis).in_max-(axis).in_min+1 ) +#define OUT_RANGE(axis) ( (axis).out_max-(axis).out_min+1 ) + + +/* in_to_screen: + * maps an input absolute position to a screen position + */ +static int in_to_screen(const AXIS *axis, int v) +{ + return (((v-axis->in_min) * OUT_RANGE(*axis)) / IN_RANGE(*axis)) + axis->out_min; +} + + + +/* rel_event: + * returns the new screen position, given the input relative one. + * The tool mode is always relative + */ +static int rel_event(AXIS *axis, int v) +{ + /* When input only send relative events, the mode is always relative */ + int ret = axis->out_abs + v*axis->speed; + axis->mickeys += v; + axis->in_abs += v; + return ret; +} + + + +/* abs_event: + * returns the new screen position, given the input absolute one, + * and depending on the tool mode + */ +static int abs_event(AXIS *axis, MODE mode, int v) +{ + if (mode == MODE_ABSOLUTE) { + axis->mickeys = 0; /* No mickeys in absolute mode */ + axis->in_abs = v; + return in_to_screen(axis, v); + } + else { /* Input is absolute, but tool is relative */ + int value = (v-axis->in_abs)*axis->scale; + axis->mickeys += value; + axis->in_abs = v; + return axis->out_abs + value*axis->speed; + } +} + + + +/* get_axis_value: + * returns the input absolute position + */ +static void get_axis_value(int fd, AXIS *axis, int type) +{ + int abs[5]; + int ret = ioctl(fd, EVIOCGABS(type), abs); + if (ret>=0) { + axis->in_abs = abs[0]; + } +} + + + +/* has_event: + * returns true if the device generates the event + */ +static int has_event(int fd, unsigned short type, unsigned short code) +{ + const unsigned int len = sizeof(unsigned long)*8; + const unsigned int max = _ALLEGRO_MAX(EV_MAX, _ALLEGRO_MAX(KEY_MAX, _ALLEGRO_MAX(REL_MAX, _ALLEGRO_MAX(ABS_MAX, _ALLEGRO_MAX(LED_MAX, _ALLEGRO_MAX(SND_MAX, FF_MAX)))))); + unsigned long bits[(max+len-1)/len]; + if (ioctl(fd, EVIOCGBIT(type, max), bits)) { + return (bits[code/len] >> (code%len)) & 1; + } + return 0; +} + + + +/* get_num_buttons: + * return the number of buttons + */ +static int get_num_buttons(int fd) +{ + if (has_event(fd, EV_KEY, BTN_MIDDLE)) + return 3; + if (has_event(fd, EV_KEY, BTN_RIGHT)) + return 2; + if (has_event(fd, EV_KEY, BTN_MOUSE)) + return 1; + return 0; /* Not a mouse */ +} + + + +/* The three axis: horizontal, vertical and wheel */ +static AXIS x_axis; +static AXIS y_axis; +static AXIS z_axis; + + + +/* + * Initialization functions + */ + +/* init_axis: + * initialize an AXIS structure, from the device and the config file + */ +static void init_axis(int fd, AXIS *axis, const char *name, const char *section, int type) +{ +#if 0 + char tmp1[256]; /* config string */ + char tmp2[256]; /* format string */ + char tmp3[256]; /* Converted 'name' */ +#endif + int abs[5]; /* values given by the input */ + int config_speed; + + (void)name; + (void)section; + + config_speed = 1; + axis->scale = 1; + + /* Ask the input */ + if (ioctl(fd, EVIOCGABS(type), abs)>=0) { + if (axis->in_min==0) + axis->in_min=abs[1]; + if (axis->in_max==0) + axis->in_max=abs[2]; + axis->in_abs = abs[0]; + axis->scale = 320.0*config_speed/IN_RANGE(*axis); + } + if (axis->in_min>axis->in_max) { + axis->in_min = axis->in_max = 0; + axis->scale = 1; + } + + axis->out_min = INT_MIN; + axis->out_max = INT_MAX; + + axis->speed = 1; + axis->mickeys = 0; +} + + + +/* init_tablet: + * initialize the tools and axis + */ +static void init_tablet(int fd) +{ + int default_abs = default_tool->mode==MODE_ABSOLUTE; + + if (default_abs) { + default_tool->mode = MODE_ABSOLUTE; + } + else { + default_tool->mode = MODE_RELATIVE; + } + + init_axis(fd, &x_axis, "x", "mouse", ABS_X); + init_axis(fd, &y_axis, "y", "mouse", ABS_Y); + init_axis(fd, &z_axis, "z", "mouse", ABS_Z); +} + + + + +/* + * Process input functions + */ + +/* process_key: [fdwatch thread] + * process events of type key (button clicks and vicinity events are currently + * supported) + */ +static void process_key(const struct input_event *event) +{ + switch (event->code) { + /* Buttons click + * if event->value is 1 the button has just been pressed + * if event->value is 0 the button has just been released */ + case BTN_LEFT: /* Mouse */ + case BTN_TOUCH: /* Stylus */ + handle_button_event(1, event->value); + break; + + case BTN_RIGHT: /* Mouse */ + case BTN_STYLUS: /* Stylus */ + handle_button_event(2, event->value); + break; + + case BTN_MIDDLE: /* Mouse */ + case BTN_STYLUS2: /* Stylus */ + handle_button_event(3, event->value); + break; + + /* Vicinity events + * if event->value is 1, the tool enters the tablet vicinity + * if event->value is 0, the tool leaves the tablet vicinity */ + case BTN_TOOL_MOUSE: + case BTN_TOOL_PEN: + case BTN_TOOL_RUBBER: + case BTN_TOOL_BRUSH: + case BTN_TOOL_PENCIL: + case BTN_TOOL_AIRBRUSH: + case BTN_TOOL_FINGER: + case BTN_TOOL_LENS: + if (event->value) { + current_tool = find_tool(event->code); + get_axis_value(the_mouse.fd, &x_axis, ABS_X); + get_axis_value(the_mouse.fd, &y_axis, ABS_Y); + get_axis_value(the_mouse.fd, &z_axis, ABS_Z); +#ifdef ABS_WHEEL /* absent in 2.2.x */ + get_axis_value(the_mouse.fd, &z_axis, ABS_WHEEL); +#endif + } + else { + current_tool = no_tool; + } + break; + } +} + + +/* [fdwatch thread] */ +static void handle_button_event(unsigned int button, bool is_down) +{ + unsigned int event_type; + + if (is_down) { + the_mouse.state.buttons |= (1 << (button-1)); + event_type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; + } + else { + the_mouse.state.buttons &=~ (1 << (button-1)); + event_type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; + } + + generate_mouse_event( + event_type, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + 0, 0, 0, + button); +} + + + + +/* process_rel: [fdwatch thread] + * process relative events (x, y and z movement are currently supported) + */ +static void process_rel(const struct input_event *event) +{ + /* The device can send a report when there's no tool */ + if (current_tool!=no_tool) { + switch (event->code) { + case REL_X: + x_axis.out_abs = rel_event(&x_axis, event->value); + handle_axis_event(x_axis.mickeys, 0, 0); + x_axis.mickeys = 0; + break; + + case REL_Y: + y_axis.out_abs = rel_event(&y_axis, event->value); + handle_axis_event(0, y_axis.mickeys, 0); + y_axis.mickeys = 0; + break; + +#ifdef REL_WHEEL /* absent in 2.2.x */ + case REL_WHEEL: +#endif + case REL_Z: + z_axis.out_abs = rel_event(&z_axis, event->value); + handle_axis_event(0, 0, z_axis.mickeys); + z_axis.mickeys = 0; + break; + } + } +} + + + +/* process_abs: [fdwatch thread] + * process absolute events (x, y and z movement are currently supported) + * TODO: missing handle_axis_event calls + */ +static void process_abs(const struct input_event *event) +{ + /* The device can send a report when there's no tool */ + if (current_tool!=no_tool) { + switch (event->code) { + case ABS_X: + x_axis.out_abs = abs_event(&x_axis, current_tool->mode, event->value); + break; + + case ABS_Y: + y_axis.out_abs = abs_event(&y_axis, current_tool->mode, event->value); + break; + +#ifdef ABS_WHEEL /* absent in 2.2.x */ + case ABS_WHEEL: +#endif + case ABS_Z: + z_axis.out_abs = abs_event(&z_axis, current_tool->mode, event->value); + break; + } + } +} + + + +/* [fdwatch thread] */ +static void handle_axis_event(int dx, int dy, int dz) +{ + if (current_tool != no_tool) { + x_axis.out_abs = _ALLEGRO_CLAMP(x_axis.out_min, x_axis.out_abs, x_axis.out_max); + y_axis.out_abs = _ALLEGRO_CLAMP(y_axis.out_min, y_axis.out_abs, y_axis.out_max); + /* There's no range for z */ + + the_mouse.state.x = x_axis.out_abs; + the_mouse.state.y = y_axis.out_abs; + the_mouse.state.z = z_axis.out_abs * al_get_mouse_wheel_precision(); + + dz *= al_get_mouse_wheel_precision(); + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_AXES, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + dx, dy, dz, + 0); + } +} + + + +/* open_mouse_device: + * Open the specified device file and check that it is a mouse device. + * Returns the file descriptor if successful or a negative number on error. + */ +static int open_mouse_device (const char *device_file) +{ + int fd; + + fd = open (device_file, O_RDONLY | O_NONBLOCK); + if (fd >= 0) { + ALLEGRO_DEBUG("Opened device %s\n", device_file); + /* The device is a mouse if it has a BTN_MOUSE */ + if (has_event(fd, EV_KEY, BTN_MOUSE)) { + ALLEGRO_DEBUG("Device %s was a mouse.\n", device_file); + } + else { + ALLEGRO_DEBUG("Device %s was not mouse, closing.\n", device_file); + close(fd); + fd = -1; + } + } + + return fd; +} + + + +/* mouse_init: + * Here we open the mouse device, initialise anything that needs it, + * and chain to the framework init routine. + */ +static bool mouse_init (void) +{ +/* + char tmp1[128], tmp2[128]; + const char *udevice; +*/ + + /* Set the current tool */ + current_tool = default_tool; + + /* try several /dev/input/event + * devices. */ + const char *device_name[] = { "/dev/input/event0", + "/dev/input/event1", + "/dev/input/event2", + "/dev/input/event3", + NULL }; + int i; + + ALLEGRO_DEBUG("Trying /dev/input/event[0-3] devices\n"); + + for (i=0; device_name[i]; i++) { + the_mouse.fd = open_mouse_device (device_name[i]); + if (the_mouse.fd >= 0) + break; + } + + if (!device_name[i]) { + return false; + } + + /* Init the tablet data */ + init_tablet(the_mouse.fd); + + /* Initialise the mouse object for use as an event source. */ + _al_event_source_init(&the_mouse.parent.es); + + /* Start watching for data on the fd. */ + _al_unix_start_watching_fd(the_mouse.fd, process_new_data, &the_mouse); + + return true; +} + + + +/* mouse_exit: + * Chain to the framework, then uninitialise things. + */ +static void mouse_exit (void) +{ + _al_unix_stop_watching_fd(the_mouse.fd); + + _al_event_source_free(&the_mouse.parent.es); + + close(the_mouse.fd); + + /* This may help catch bugs in the user program, since the pointer + * we return to the user is always the same. + */ + memset(&the_mouse, 0, sizeof the_mouse); + the_mouse.fd = -1; +} + + + +/* mouse_get_mouse: + * Returns the address of a ALLEGRO_MOUSE structure representing the mouse. + */ +static ALLEGRO_MOUSE *mouse_get_mouse(void) +{ + return (ALLEGRO_MOUSE *)&the_mouse; +} + + + +/* mouse_get_mouse_num_buttons: + * Return the number of buttons on the mouse. + */ +static unsigned int mouse_get_mouse_num_buttons(void) +{ + ASSERT(the_mouse.fd >= 0); + + return get_num_buttons(the_mouse.fd); +} + + + +/* mouse_get_mouse_num_axes: + * Return the number of axes on the mouse. + */ +static unsigned int mouse_get_mouse_num_axes(void) +{ + ASSERT(the_mouse.fd >= 0); + + /* XXX get the right number later */ + return 3; +} + + + +/* mouse_set_mouse_xy: + * + */ +static bool mouse_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) +{ + (void)display; + + _al_event_source_lock(&the_mouse.parent.es); + { + int dx, dy; + + x_axis.out_abs = _ALLEGRO_CLAMP(x_axis.out_min, x, x_axis.out_max); + y_axis.out_abs = _ALLEGRO_CLAMP(y_axis.out_min, y, y_axis.out_max); + x_axis.mickeys = 0; + y_axis.mickeys = 0; + + dx = x_axis.out_abs - the_mouse.state.x; + dy = y_axis.out_abs - the_mouse.state.y; + + if ((dx != 0) && (dy != 0)) { + the_mouse.state.x = x_axis.out_abs; + the_mouse.state.y = y_axis.out_abs; + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_AXES, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + dx, dy, 0, + 0); + } + } + _al_event_source_unlock(&the_mouse.parent.es); + + return true; +} + + + +/* mouse_set_mouse_axis: + * + * Number of mickeys to cross the screen horizontally: speed * 320. + */ +static bool mouse_set_mouse_axis(int which, int z) +{ + if (which != 2) { + return false; + } + + _al_event_source_lock(&the_mouse.parent.es); + { + int dz; + + z_axis.out_abs = z; + + dz = z_axis.out_abs - the_mouse.state.z; + + if (dz != 0) { + the_mouse.state.z = z_axis.out_abs; + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_AXES, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + 0, 0, dz, + 0); + } + } + _al_event_source_unlock(&the_mouse.parent.es); + + return true; +} + + + +/* mouse_set_mouse_range: + * + */ +bool _al_evdev_set_mouse_range(int x1, int y1, int x2, int y2) +{ + _al_event_source_lock(&the_mouse.parent.es); + { + int dx, dy; + + x_axis.out_min = x1; + y_axis.out_min = y1; + x_axis.out_max = x2; + y_axis.out_max = y2; + + x_axis.out_abs = _ALLEGRO_CLAMP(x_axis.out_min, x_axis.out_abs, x_axis.out_max); + y_axis.out_abs = _ALLEGRO_CLAMP(y_axis.out_min, y_axis.out_abs, y_axis.out_max); + + dx = x_axis.out_abs - the_mouse.state.x; + dy = y_axis.out_abs - the_mouse.state.y; + + if ((dx != 0) && (dy != 0)) { + the_mouse.state.x = x_axis.out_abs; + the_mouse.state.y = y_axis.out_abs; + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_AXES, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + dx, dy, 0, + 0); + } + } + _al_event_source_unlock(&the_mouse.parent.es); + + return true; +} + + + +/* mouse_get_state: + * Copy the current mouse state into RET_STATE, with any necessary locking. + */ +static void mouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + _al_event_source_lock(&the_mouse.parent.es); + { + *ret_state = the_mouse.state; + } + _al_event_source_unlock(&the_mouse.parent.es); +} + + + +/* process_new_data: [fdwatch thread] + * Process new data arriving in the keyboard's fd. + */ +static void process_new_data(void *data) +{ + ASSERT((AL_MOUSE_EVDEV *)data == &the_mouse); + + _al_event_source_lock(&the_mouse.parent.es); + { + struct input_event events[32]; + int bytes, nr, i; + + while ((bytes = read(the_mouse.fd, &events, sizeof events)) > 0) { + nr = bytes / sizeof(events[0]); + for (i = 0; i < nr; i++) { + process_event(&events[i]); + } + } + } + _al_event_source_unlock(&the_mouse.parent.es); +} + + + +/* [fdwatch thread] */ +static void process_event(struct input_event *event) +{ + switch (event->type) { + case EV_KEY: + process_key(event); + break; + case EV_REL: + process_rel(event); + break; + case EV_ABS: + process_abs(event); + break; + } +} + + + +/* [fdwatch thread] */ +static void generate_mouse_event(unsigned int type, + int x, int y, int z, + int dx, int dy, int dz, + unsigned int button) +{ + ALLEGRO_EVENT event; + + if (!_al_event_source_needs_to_generate_event(&the_mouse.parent.es)) + return; + + event.mouse.type = type; + event.mouse.timestamp = al_get_time(); + event.mouse.display = NULL; + event.mouse.x = x; + event.mouse.y = y; + event.mouse.z = z; + event.mouse.dx = dx; + event.mouse.dy = dy; + event.mouse.dz = dz; + event.mouse.button = button; + event.mouse.pressure = 0.0; /* TODO */ + _al_event_source_emit_event(&the_mouse.parent.es, &event); +} + + + +/* the driver vtable */ +ALLEGRO_MOUSE_DRIVER _al_mousedrv_linux_evdev = +{ + AL_MOUSEDRV_LINUX_EVDEV, + "", + "", + "Linux EVDEV mouse (and tablet)", + mouse_init, + mouse_exit, + mouse_get_mouse, + mouse_get_mouse_num_buttons, + mouse_get_mouse_num_axes, + mouse_set_mouse_xy, + mouse_set_mouse_axis, + mouse_get_state +}; + + + +#endif /* ALLEGRO_HAVE_LINUX_INPUT_H */ + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/src/linux/lmsegpmd.c b/allegro/src/linux/lmsegpmd.c new file mode 100644 index 00000000..d0e57d2c --- /dev/null +++ b/allegro/src/linux/lmsegpmd.c @@ -0,0 +1,151 @@ +#error This driver has not been updated to the new mouse API. + +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux console internal mouse driver for `gpmdata' repeater. + * + * By George Foot. + * + * See readme.txt for copyright information. + */ + +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/linalleg.h" + + +#define ASCII_NAME "GPM repeater" +#define DEVICE_FILENAME "/dev/gpmdata" + + +/* processor: + * Processes the first packet in the buffer, if any, returning the number + * of bytes eaten. + * + * The GPM repeater uses Mouse Systems protocol. Packets contain five + * bytes. The low bits of the first byte represent the button state. + * The following bytes represent motion left, up, right and down + * respectively. I think. + * + * We recognise the start of a packet by looking for a byte with the top + * bit set and the next four bits not set -- while this can occur in the + * data bytes, it's pretty unlikely. + */ +static int processor (unsigned char *buf, int buf_size) +{ + int r, m, l, x, y, z; + + if (buf_size < 5) + return 0; /* not enough data, spit it out for now */ + + if ((buf[0] & 0xf8) != 0x80) + return 1; /* invalid byte, eat it */ + + /* packet is valid, process the data */ + r = !(buf[0] & 1); + m = !(buf[0] & 2); + l = !(buf[0] & 4); + x = (signed char)buf[1] + (signed char)buf[3]; + y = (signed char)buf[2] + (signed char)buf[4]; + z = 0; + __al_linux_mouse_handler(x, y, z, l+(r<<1)+(m<<2)); + return 5; /* yum */ +} + +static INTERNAL_MOUSE_DRIVER intdrv = { + -1, + processor, + 3 +}; + +/* sync_mouse: + * To find the start of a packet, we just read all the data that's + * waiting. This isn't a particularly good way, obviously. :) + */ +static void sync_mouse (int fd) +{ + fd_set set; + int result; + struct timeval tv; + char bitbucket; + + do { + FD_ZERO (&set); + FD_SET (fd, &set); + tv.tv_sec = tv.tv_usec = 0; + result = select (FD_SETSIZE, &set, NULL, NULL, &tv); + if (result > 0) read (fd, &bitbucket, 1); + } while (result > 0); +} + +/* mouse_init: + * Here we open the mouse device, initialise anything that needs it, + * and chain to the framework init routine. + */ +static int mouse_init (void) +{ + char tmp1[128], tmp2[128], tmp3[128]; + const char *udevice; + + /* Find the device filename */ + udevice = get_config_string (uconvert_ascii ("mouse", tmp1), + uconvert_ascii ("mouse_device", tmp2), + uconvert_ascii (DEVICE_FILENAME, tmp3)); + + /* Open mouse device. Devices are cool. */ + intdrv.device = open (uconvert_toascii (udevice, tmp1), O_RDONLY | O_NONBLOCK); + if (intdrv.device < 0) { + uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), + udevice, ustrerror (errno)); + return -1; + } + + /* Discard any garbage, so the next thing we read is a packet header */ + sync_mouse (intdrv.device); + + return __al_linux_mouse_init (&intdrv); +} + +/* mouse_exit: + * Chain to the framework, then uninitialise things. + */ +static void mouse_exit (void) +{ + __al_linux_mouse_exit(); + close (intdrv.device); +} + +MOUSE_DRIVER mousedrv_linux_gpmdata = +{ + MOUSEDRV_LINUX_GPMDATA, + "", + "", + ASCII_NAME, + mouse_init, + mouse_exit, + NULL, /* poll() */ + NULL, /* timer_poll() */ + __al_linux_mouse_position, + __al_linux_mouse_set_range, + __al_linux_mouse_set_speed, + __al_linux_mouse_get_mickeys, + NULL, /* analyse_data */ + NULL, + NULL +}; + diff --git a/allegro/src/linux/lmsems.c b/allegro/src/linux/lmsems.c new file mode 100644 index 00000000..83757018 --- /dev/null +++ b/allegro/src/linux/lmsems.c @@ -0,0 +1,250 @@ +#error This driver has not been updated to the new mouse API. + +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux console internal mouse driver for Microsoft mouse. + * + * By George Foot. + * + * See readme.txt for copyright information. + */ + +#include +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/linalleg.h" + + +static int intellimouse; +static int packet_size; + + +/* processor: + * Processes the first packet in the buffer, if any, returning the number + * of bytes eaten. + * + * Microsoft protocol has only seven data bits. The top bit is set in + * the first byte of the packet, clear in the other two. The next two + * bits in the header are the button state. The next two are the top + * bits of the Y offset (second data byte), and the last two are the + * top bits of the X offset (first data byte). + */ +static int processor (unsigned char *buf, int buf_size) +{ + int r, l, m, x, y, z; + + if (buf_size < packet_size) return 0; /* not enough data, spit it out for now */ + + /* if packet is invalid, just eat it */ + if (!(buf[0] & 0x40)) return 1; /* invalid byte */ + if (buf[1] & 0x40) return 1; /* first data byte is actually a header */ + if (buf[2] & 0x40) return 2; /* second data byte is actually a header */ + + /* packet is valid, decode the data */ + l = !!(buf[0] & 0x20); + r = !!(buf[0] & 0x10); + + if (intellimouse) { + m = !!(buf[3] & 0x10); + z = (buf[3] & 0x0f); + if (z) + z = (z-7) >> 3; + } + else { + m = 0; + z = 0; + } + + x = (signed char) (((buf[0] & 0x03) << 6) | (buf[1] & 0x3F)); + y = -(signed char) (((buf[0] & 0x0C) << 4) | (buf[2] & 0x3F)); + + __al_linux_mouse_handler(x, y, z, l+(r<<1)+(m<<2)); + return packet_size; /* yum */ +} + +/* analyse_data: + * Analyses the given data, returning 0 if it is unparsable, nonzero + * if there's a reasonable chance that this driver can work with that + * data. + */ +static int analyse_data (const char *buffer, int size) +{ + int pos = 0; + int packets = 0, errors = 0; + + int step = 0; + + for (pos = 0; pos < size; pos++) + switch (step) { + case 3: + packets++; + step = 0; + case 0: + if (!(buffer[pos] & 0x40)) { + errors++; + } else { + step++; + } + break; + + case 1: + case 2: + if (buffer[pos] & 0x40) { + errors++; + step = 0; + pos--; + } else { + step++; + } + break; + } + + return (errors <= 5) || (errors < size / 20); /* 5% error allowance */ +} + + +static INTERNAL_MOUSE_DRIVER intdrv = { + -1, + processor, + 2 +}; + +/* sync_mouse: + * To find the start of a packet, we just read all the data that's + * waiting. This isn't a particularly good way, obviously. :) + */ +static void sync_mouse (int fd) +{ + fd_set set; + int result; + struct timeval tv; + char bitbucket; + + do { + FD_ZERO (&set); + FD_SET (fd, &set); + tv.tv_sec = tv.tv_usec = 0; + result = select (FD_SETSIZE, &set, NULL, NULL, &tv); + if (result > 0) read (fd, &bitbucket, 1); + } while (result > 0); +} + +/* mouse_init: + * Here we open the mouse device, initialise anything that needs it, + * and chain to the framework init routine. + */ +static int mouse_init (void) +{ + char tmp1[128], tmp2[128], tmp3[128]; + const char *udevice; + struct termios t; + + /* Find the device filename */ + udevice = get_config_string (uconvert_ascii ("mouse", tmp1), + uconvert_ascii ("mouse_device", tmp2), + uconvert_ascii ("/dev/mouse", tmp3)); + + /* Open mouse device. Devices are cool. */ + intdrv.device = open (uconvert_toascii (udevice, tmp1), O_RDONLY | O_NONBLOCK); + if (intdrv.device < 0) { + uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), + udevice, ustrerror (errno)); + return -1; + } + + /* Set parameters */ + tcgetattr (intdrv.device, &t); + t.c_iflag = IGNBRK | IGNPAR; + t.c_oflag = t.c_lflag = t.c_line = 0; + t.c_cflag = CS7 | CREAD | CLOCAL | HUPCL | B1200; + tcsetattr (intdrv.device, TCSAFLUSH, &t); + + /* Discard any garbage, so the next thing we read is a packet header */ + sync_mouse (intdrv.device); + + return __al_linux_mouse_init (&intdrv); +} + +/* ms_mouse_init: + * Initialisation for vanilla MS mouse. + */ +static int ms_mouse_init (void) +{ + intellimouse = false; + packet_size = 3; + intdrv.num_buttons = 2; + return mouse_init (); +} + +/* msi_mouse_init: + * Initialisation for MS mouse with Intellimouse extension. + */ +static int ims_mouse_init (void) +{ + intellimouse = true; + packet_size = 4; + intdrv.num_buttons = 3; + return mouse_init (); +} + +/* mouse_exit: + * Chain to the framework, then uninitialise things. + */ +static void mouse_exit (void) +{ + __al_linux_mouse_exit(); + close (intdrv.device); +} + +MOUSE_DRIVER mousedrv_linux_ms = +{ + MOUSEDRV_LINUX_MS, + "", + "", + "Linux MS mouse", + ms_mouse_init, + mouse_exit, + NULL, /* poll() */ + NULL, /* timer_poll() */ + __al_linux_mouse_position, + __al_linux_mouse_set_range, + __al_linux_mouse_set_speed, + __al_linux_mouse_get_mickeys, + analyse_data, + NULL, /* enable_hardware_cursor */ + NULL +}; + +MOUSE_DRIVER mousedrv_linux_ims = +{ + MOUSEDRV_LINUX_IMS, + "", + "", + "Linux MS Intellimouse", + ims_mouse_init, + mouse_exit, + NULL, /* poll() */ + NULL, /* timer_poll() */ + __al_linux_mouse_position, + __al_linux_mouse_set_range, + __al_linux_mouse_set_speed, + __al_linux_mouse_get_mickeys, + analyse_data, + NULL, /* enable_hardware_cursor */ + NULL +}; diff --git a/allegro/src/linux/lmseps2.c b/allegro/src/linux/lmseps2.c new file mode 100644 index 00000000..d382eaac --- /dev/null +++ b/allegro/src/linux/lmseps2.c @@ -0,0 +1,283 @@ +#error This driver has not been updated to the new mouse API. + +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux console internal mouse driver for PS/2. + * + * By George Foot. + * + * See readme.txt for copyright information. + */ + +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/linalleg.h" + + +static int intellimouse; +static int packet_size; + + +/* processor: + * Processes the first packet in the buffer, if any, returning the number + * of bytes eaten. + * + * PS/2 mouse protocol is pretty simple; packets consist of three bytes, + * one header byte and two data bytes. In the header, the bottom three + * bits show the current button state. The next bit should always be + * set, but apparently some mice don't do this. The next two bits are + * the X and Y sign bits, and the last two are the X and Y overflow + * flags. The two data bytes are the X and Y deltas; prepend the + * corresponding sign bit to get a nine-bit two's complement number. + * + * Finding the header byte can be tricky in you lose sync; bit 3 isn't + * that useful, not only because some mice don't set it, but also + * because a data byte could have it set. The overflow bits are very + * rarely set, so we just test for these being zero. Of course the + * data bytes can have zeros here too, but as soon as you move the + * mouse down or left the data bytes become negative and have ones + * here instead. + */ +static int processor (unsigned char *buf, int buf_size) +{ + int r, l, m, x, y, z; + + if (buf_size < packet_size) return 0; /* not enough data, spit it out for now */ + + /* if data is invalid, return no motion and all buttons released */ + if (intellimouse) { + if ((buf[0] & 0xc8) != 0x08) return 1; /* invalid byte, eat it */ + } + else { + if ((buf[0] & 0xc0) != 0x00) return 1; /* invalid byte, eat it */ + } + + /* data is valid, process it */ + l = !!(buf[0] & 1); + r = !!(buf[0] & 2); + m = !!(buf[0] & 4); + + x = buf[1]; + y = buf[2]; + if (buf[0] & 0x10) x -= 256; + if (buf[0] & 0x20) y -= 256; + + if (intellimouse) { + z = buf[3] & 0xf; + if (z) + z = (z-7) >> 3; + } + else + z = 0; + + __al_linux_mouse_handler(x, y, z, l+(r<<1)+(m<<2)); + return packet_size; /* yum */ +} + +/* analyse_data: + * Analyses the given data, returning 0 if it is unparsable, nonzero + * if there's a reasonable chance that this driver can work with that + * data. + */ +static int analyse_data (const char *buffer, int size) +{ + int pos = 0; + int packets = 0, errors = 0; + + int step = 0; + + for (pos = 0; pos < size; pos++) + switch (step) { + case 3: + packets++; + step = 0; + case 0: + if (buffer[pos] & 0xC0) { + errors++; + } else { + step++; + } + break; + + case 1: + case 2: + step++; + break; + } + + return (errors <= 5) || (errors < size / 20); /* 5% error allowance */ +} + + +static INTERNAL_MOUSE_DRIVER intdrv = { + -1, + processor, + 3 +}; + +/* sync_mouse: + * To find the start of a packet, we just read all the data that's + * waiting. This isn't a particularly good way, obviously. :) + */ +static void sync_mouse (int fd) +{ + fd_set set; + int result; + struct timeval tv; + char bitbucket; + + do { + FD_ZERO (&set); + FD_SET (fd, &set); + tv.tv_sec = tv.tv_usec = 0; + result = select (FD_SETSIZE, &set, NULL, NULL, &tv); + if (result > 0) read (fd, &bitbucket, 1); + } while (result > 0); +} + +/* wakeup_im: + * Intellimouse needs some special initialisation. + */ +static void wakeup_im (int fd) +{ + unsigned char init[] = { 243, 200, 243, 100, 243, 80 }; + int ret; + do { + ret = write (fd, init, sizeof (init)); + if ((ret < 0) && (errno != EINTR)) + break; + } while (ret < (int)sizeof (init)); +} + +/* mouse_init: + * Here we open the mouse device, initialise anything that needs it, + * and chain to the framework init routine. + */ +static int mouse_init (void) +{ + char tmp1[128], tmp2[128]; + const char *udevice; + int flags; + + static const char * const default_devices[] = { + "/dev/mouse", + "/dev/input/mice", + }; + + /* Find the device filename */ + udevice = get_config_string (uconvert_ascii ("mouse", tmp1), + uconvert_ascii ("mouse_device", tmp2), + NULL); + + /* Open mouse device. Devices are cool. */ + flags = O_NONBLOCK | (intellimouse ? O_RDWR : O_RDONLY); + if (udevice) { + intdrv.device = open (uconvert_toascii (udevice, tmp1), flags); + } + else { + size_t n; + for (n = 0; n < sizeof(default_devices) / sizeof(default_devices[0]); n++) { + intdrv.device = open (default_devices[n], flags); + if (intdrv.device >= 0) + break; + } + } + + if (intdrv.device < 0) { + uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), + udevice ? udevice : get_config_text("one of the default mice devices"), + ustrerror (errno)); + return -1; + } + + /* Put Intellimouse into wheel mode */ + if (intellimouse) + wakeup_im (intdrv.device); + + /* Discard any garbage, so the next thing we read is a packet header */ + sync_mouse (intdrv.device); + + return __al_linux_mouse_init (&intdrv); +} + +/* ps2_mouse_init: + * Plain PS/2 mouse init. + */ +static int ps2_mouse_init (void) +{ + intellimouse = false; + packet_size = 3; + return mouse_init (); +} + +/* ps2i_mouse_init: + * PS/2 Intellimouse init. + */ +static int ips2_mouse_init (void) +{ + intellimouse = true; + packet_size = 4; + return mouse_init (); +} + +/* mouse_exit: + * Chain to the framework, then uninitialise things. + */ +static void mouse_exit (void) +{ + __al_linux_mouse_exit(); + close (intdrv.device); +} + +MOUSE_DRIVER mousedrv_linux_ps2 = +{ + MOUSEDRV_LINUX_PS2, + "", + "", + "Linux PS/2 mouse", + ps2_mouse_init, + mouse_exit, + NULL, /* poll() */ + NULL, /* timer_poll() */ + __al_linux_mouse_position, + __al_linux_mouse_set_range, + __al_linux_mouse_set_speed, + __al_linux_mouse_get_mickeys, + analyse_data, + NULL, /* enable_hardware_cursor */ + NULL +}; + +MOUSE_DRIVER mousedrv_linux_ips2 = +{ + MOUSEDRV_LINUX_IPS2, + "", + "", + "Linux PS/2 Intellimouse", + ips2_mouse_init, + mouse_exit, + NULL, /* poll() */ + NULL, /* timer_poll() */ + __al_linux_mouse_position, + __al_linux_mouse_set_range, + __al_linux_mouse_set_speed, + __al_linux_mouse_get_mickeys, + analyse_data, + NULL, /* enable_hardware_cursor */ + NULL +}; diff --git a/allegro/src/linux/lstddrv.c b/allegro/src/linux/lstddrv.c new file mode 100644 index 00000000..996b0ccb --- /dev/null +++ b/allegro/src/linux/lstddrv.c @@ -0,0 +1,106 @@ +#error This file is no longer used. + +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Standard driver helpers for Linux Allegro. + * + * By Marek Habersack, mangled by George Foot. + * + * See readme.txt for copyright information. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/linalleg.h" + +#include + + +/* List of standard drivers */ +STD_DRIVER *__al_linux_std_drivers[N_STD_DRIVERS]; + +static int std_drivers_suspended = false; + + +/* __al_linux_add_standard_driver: + * Adds a standard driver; returns 0 on success, non-zero if the sanity + * checks fail. + */ +int __al_linux_add_standard_driver (STD_DRIVER *spec) +{ + if (!spec) return 1; + if (spec->type >= N_STD_DRIVERS) return 2; + if (!spec->update) return 3; + if (spec->fd < 0) return 4; + + __al_linux_std_drivers[spec->type] = spec; + + spec->resume(); + + return 0; +} + +/* __al_linux_remove_standard_driver: + * Removes a standard driver, returning 0 on success or non-zero on + * failure. + */ +int __al_linux_remove_standard_driver (STD_DRIVER *spec) +{ + if (!spec) return 1; + if (spec->type >= N_STD_DRIVERS) return 3; + if (!__al_linux_std_drivers[spec->type]) return 4; + if (__al_linux_std_drivers[spec->type] != spec) return 5; + + spec->suspend(); + + __al_linux_std_drivers[spec->type] = NULL; + + return 0; +} + + +/* __al_linux_update_standard_drivers: + * Updates all drivers. + */ +void __al_linux_update_standard_drivers (int threaded) +{ + int i; + if (!std_drivers_suspended) { + for (i = 0; i < N_STD_DRIVERS; i++) + if (__al_linux_std_drivers[i]) + __al_linux_std_drivers[i]->update(); + } +} + + +/* __al_linux_suspend_standard_drivers: + * Temporary disable standard drivers during a VT switch. + */ +void __al_linux_suspend_standard_drivers (void) +{ + ASSERT(!std_drivers_suspended); + std_drivers_suspended = true; +} + +/* __al_linux_resume_standard_drivers: + * Re-enable standard drivers after a VT switch. + */ +void __al_linux_resume_standard_drivers (void) +{ + ASSERT(std_drivers_suspended); + std_drivers_suspended = false; +} + diff --git a/allegro/src/linux/lsystem.c b/allegro/src/linux/lsystem.c new file mode 100644 index 00000000..a032df25 --- /dev/null +++ b/allegro/src/linux/lsystem.c @@ -0,0 +1,247 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Linux console system driver. + * + * By George Foot. + * + * See readme.txt for copyright information. + */ + + +#include +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/platform/aintlnx.h" + +#include "allegro5/linalleg.h" + +#ifndef ALLEGRO_LINUX + #error Something is wrong with the makefile +#endif + + +static int sys_linux_init(void); +static void sys_linux_exit(void); +static void sys_linux_message (const char *msg); +static void sys_linux_save_console_state(void); +static void sys_linux_restore_console_state(void); + + +/* driver list getters */ +#define make_getter(x,y) static _AL_DRIVER_INFO *get_##y##_driver_list (void) { return x##_##y##_driver_list; } + make_getter (_unix, gfx) + make_getter (_unix, digi) + make_getter (_unix, midi) + make_getter (_al_linux, keyboard) + make_getter (_al_linux, mouse) + make_getter (_al_linux, joystick) +#undef make_getter + + +/* the main system driver for running on the Linux console */ +SYSTEM_DRIVER system_linux = +{ + SYSTEM_LINUX, + "", + "", + "Linux console", + sys_linux_init, + sys_linux_exit, + _unix_get_executable_name, + _unix_get_path, + _unix_find_resource, + NULL, /* set_window_title */ + NULL, /* set_close_button_callback */ + sys_linux_message, + NULL, /* assert */ + sys_linux_save_console_state, + sys_linux_restore_console_state, + NULL, /* create_bitmap */ + NULL, /* created_bitmap */ + NULL, /* created_sub_bitmap */ + NULL, /* destroy_bitmap */ + NULL, /* read_hardware_palette */ + NULL, /* set_palette_range */ + NULL, /* get_vtable */ + __al_linux_set_display_switch_mode, + __al_linux_display_switch_lock, + NULL, /* desktop_color_depth */ + NULL, /* get_desktop_resolution */ + NULL, /* get_gfx_safe_mode */ + _unix_yield_timeslice, + get_gfx_driver_list, + get_digi_driver_list, + get_midi_driver_list, + get_keyboard_driver_list, + get_mouse_driver_list, + get_joystick_driver_list +}; + + +int __al_linux_have_ioperms = 0; + + +typedef void (*temp_sighandler_t)(int); +static temp_sighandler_t old_sig_abrt, old_sig_fpe, old_sig_ill, old_sig_segv, old_sig_term, old_sig_int, old_sig_quit; + + +/* signal_handler: + * Used to trap various signals, to make sure things get shut down cleanly. + */ +static void signal_handler (int num) +{ + al_uninstall_system(); + fprintf (stderr, "Shutting down Allegro due to signal #%d\n", num); + raise (num); +} + + +/* __al_linux_bgman_init: + * Starts asynchronous processing. + */ +static int __al_linux_bgman_init (void) +{ + _unix_bg_man = &_bg_man_pthreads; + if (_unix_bg_man->init()) + return -1; + /* + if (_unix_bg_man->register_func (__al_linux_update_standard_drivers)) + return -1; + */ + return 0; +} + + +/* __al_linux_bgman_exit: + * Stops asynchronous processing. + */ +static void __al_linux_bgman_exit (void) +{ + _unix_bg_man->exit(); +} + + + +/* sys_linux_init: + * Top level system driver wakeup call. + */ +static int sys_linux_init (void) +{ + /* Get OS type */ + _unix_read_os_type(); + if (os_type != OSTYPE_LINUX) return -1; /* FWIW */ + + /* This is the only bit that needs root privileges. First + * we attempt to set our euid to 0, in case this is the + * second time we've been called. */ + __al_linux_have_ioperms = !seteuid (0); + __al_linux_have_ioperms &= !__al_linux_init_memory(); + + /* At this stage we can drop the root privileges. */ + seteuid (getuid()); + + /* Install emergency-exit signal handlers */ + old_sig_abrt = signal(SIGABRT, signal_handler); + old_sig_fpe = signal(SIGFPE, signal_handler); + old_sig_ill = signal(SIGILL, signal_handler); + old_sig_segv = signal(SIGSEGV, signal_handler); + old_sig_term = signal(SIGTERM, signal_handler); + old_sig_int = signal(SIGINT, signal_handler); +#ifdef SIGQUIT + old_sig_quit = signal(SIGQUIT, signal_handler); +#endif + + /* Initialise async event processing */ + if (__al_linux_bgman_init()) { + /* shutdown everything. */ + sys_linux_exit(); + return -1; + } + + /* Mark the beginning of time */ + _al_unix_init_time(); + + return 0; +} + + + +/* sys_linux_exit: + * The end of the world... + */ +static void sys_linux_exit (void) +{ + /* shut down asynchronous event processing */ + __al_linux_bgman_exit(); + + /* remove emergency exit signal handlers */ + signal(SIGABRT, old_sig_abrt); + signal(SIGFPE, old_sig_fpe); + signal(SIGILL, old_sig_ill); + signal(SIGSEGV, old_sig_segv); + signal(SIGTERM, old_sig_term); + signal(SIGINT, old_sig_int); +#ifdef SIGQUIT + signal(SIGQUIT, old_sig_quit); +#endif + + __al_linux_shutdown_memory(); +} + + + +static void sys_linux_save_console_state(void) +{ + __al_linux_use_console(); +} + + + +static void sys_linux_restore_console_state(void) +{ + __al_linux_leave_console(); +} + + + +/* sys_linux_message: + * Display a message on our original console. + */ +static void sys_linux_message (const char *msg) +{ + char *tmp; + int ret; + ASSERT(msg); + + tmp = al_malloc(ALLEGRO_MESSAGE_SIZE); + msg = uconvert(msg, U_UTF8, tmp, U_ASCII, ALLEGRO_MESSAGE_SIZE); + + do { + ret = write(STDERR_FILENO, msg, strlen(msg)); + if ((ret < 0) && (errno != EINTR)) + break; + } while (ret < (int)strlen(msg)); + + __al_linux_got_text_message = true; + + al_free(tmp); +} + + + diff --git a/allegro/src/linux/vtswitch.c b/allegro/src/linux/vtswitch.c new file mode 100644 index 00000000..e954dd42 --- /dev/null +++ b/allegro/src/linux/vtswitch.c @@ -0,0 +1,285 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Virtual console handling routines for Linux console Allegro. + * + * By George Foot, based on Marek Habersack's code. + * + * See readme.txt for copyright information. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/linalleg.h" + +#ifdef ALLEGRO_HAVE_MMAP +#include +#endif + +#if !defined(_POSIX_MAPPED_FILES) || !defined(ALLEGRO_HAVE_MMAP) +#error "Sorry, mapped files are required for Allegro/Linux to work!" +#endif + + +static int switch_mode = SWITCH_PAUSE; + +static int vtswitch_initialised = 0; +static struct vt_mode startup_vtmode; + +volatile int __al_linux_switching_blocked = 0; + +static volatile int console_active = 1; /* are we active? */ +static volatile int console_should_be_active = 1; /* should we be? */ + + + +int __al_linux_set_display_switch_mode (int mode) +{ + /* Clean up after the previous mode, if necessary */ + if (switch_mode == SWITCH_NONE) __al_linux_switching_blocked--; + + switch_mode = mode; + + /* Initialise the new mode */ + if (switch_mode == SWITCH_NONE) __al_linux_switching_blocked++; + + return 0; +} + + + +/* go_away: + * Performs a switch away. + */ +static void go_away(void) +{ + _switch_out(); + + _unix_bg_man->disable_interrupts(); + if ((switch_mode == SWITCH_PAUSE) || (switch_mode == SWITCH_AMNESIA)) + _al_suspend_old_timer_emulation(); + + /* Disable input devices while we're away */ + /* __al_linux_suspend_standard_drivers(); */ + + _save_switch_state(switch_mode); + + if (gfx_driver && gfx_driver->save_video_state) + gfx_driver->save_video_state(); + + ioctl (__al_linux_console_fd, VT_RELDISP, 1); + console_active = 0; + + __al_linux_switching_blocked--; + + if ((switch_mode == SWITCH_PAUSE) || (switch_mode == SWITCH_AMNESIA)) { + __al_linux_wait_for_display(); + _al_resume_old_timer_emulation(); + } + + _unix_bg_man->enable_interrupts(); +} + + + +/* come_back: + * Performs a switch back. + */ +static void come_back(void) +{ + _unix_bg_man->disable_interrupts(); + + if (gfx_driver && gfx_driver->restore_video_state) + gfx_driver->restore_video_state(); + + _restore_switch_state(); + + ioctl(__al_linux_console_fd, VT_RELDISP, VT_ACKACQ); + console_active = 1; + + /* __al_linux_resume_standard_drivers(); */ + + _unix_bg_man->enable_interrupts(); + + _switch_in(); + + __al_linux_switching_blocked--; +} + + + +/* poll_console_switch: + * Checks whether a switch is needed and not blocked; if so, + * makes the switch. + */ +static void poll_console_switch (void) +{ + if (console_active == console_should_be_active) return; + if (__al_linux_switching_blocked) return; + + __al_linux_switching_blocked++; + + if (console_should_be_active) + come_back(); + else + go_away(); +} + + + +/* vt_switch_requested: + * This is our signal handler; it gets called whenever a switch is + * requested, because either SIGRELVT or SIGACQVT is raised. + */ +static void vt_switch_requested(int signo) +{ + switch (signo) { + case SIGRELVT: + console_should_be_active = 0; + break; + case SIGACQVT: + console_should_be_active = 1; + break; + default: + return; + } + poll_console_switch(); +} + + + +/* __al_linux_acquire_bitmap: + * Increases the switching_blocked counter to block switches during + * critical code (e.g. code accessing unsaved graphics controller + * registers; or in background mode, code that does anything at all + * connected with the screen bitmap). + */ +void __al_linux_acquire_bitmap(BITMAP *bmp) +{ + ASSERT(bmp); + + __al_linux_switching_blocked++; +} + + + +/* __al_linux_release_bitmap: + * Decreases the blocking count and polls for switching. + */ +void __al_linux_release_bitmap(BITMAP *bmp) +{ + ASSERT(bmp); + + __al_linux_switching_blocked--; + poll_console_switch(); +} + + + +/* __al_linux_display_switch_lock: + * System driver routine for locking the display around crucial bits of + * code, for example when changing video modes. + */ +void __al_linux_display_switch_lock(int lock, int foreground) +{ + if (__al_linux_console_fd == -1) { + return; + } + + if (foreground) { + __al_linux_wait_for_display(); + } + + if (lock) { + __al_linux_switching_blocked++; + } + else { + __al_linux_switching_blocked--; + poll_console_switch(); + } +} + + + +/* __al_linux_init_vtswitch: + * Takes control over our console. It means we'll be notified when user + * switches to and from the graphics console. + */ +int __al_linux_init_vtswitch(void) +{ + struct sigaction sa; + struct vt_mode vtm; + + if (vtswitch_initialised) return 0; /* shouldn't happen */ + + __al_linux_switching_blocked = (switch_mode == SWITCH_NONE) ? 1 : 0; + console_active = console_should_be_active = 1; + + /* Hook the signals */ + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGIO); /* block async IO during the VT switch */ + sa.sa_flags = 0; + sa.sa_handler = vt_switch_requested; + if ((sigaction(SIGRELVT, &sa, NULL) < 0) || (sigaction(SIGACQVT, &sa, NULL) < 0)) { + ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to control VT switching")); + return 1; + } + + /* Save old mode, take control, and arrange for the signals + * to be raised. */ + ioctl(__al_linux_console_fd, VT_GETMODE, &startup_vtmode); + vtm = startup_vtmode; + + vtm.mode = VT_PROCESS; + vtm.relsig = SIGRELVT; + vtm.acqsig = SIGACQVT; + + ioctl(__al_linux_console_fd, VT_SETMODE, &vtm); + + vtswitch_initialised = 1; + + return 0; +} + + + +/* __al_linux_done_vtswitch: + * Undoes the effect of `init_vtswitch'. + */ +int __al_linux_done_vtswitch(void) +{ + struct sigaction sa; + + if (!vtswitch_initialised) return 0; /* shouldn't really happen either */ + + /* !trout gfoot. Must turn off the signals before unhooking them... */ + ioctl(__al_linux_console_fd, VT_SETMODE, &startup_vtmode); + + sigemptyset (&sa.sa_mask); + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_RESTART; + sigaction (SIGRELVT, &sa, NULL); + sigaction (SIGACQVT, &sa, NULL); + + vtswitch_initialised = 0; + + return 0; +} + + diff --git a/allegro/src/macosx/hidjoy-10.4.m b/allegro/src/macosx/hidjoy-10.4.m new file mode 100644 index 00000000..55a419ac --- /dev/null +++ b/allegro/src/macosx/hidjoy-10.4.m @@ -0,0 +1,445 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * HID Joystick driver routines for MacOS X. + * + * By Angelo Mottola. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro5.h" +#include "allegro5/platform/aintosx.h" +#import +#import +#import + + +#ifndef ALLEGRO_MACOSX +#error something is wrong with the makefile +#endif + +ALLEGRO_DEBUG_CHANNEL("MacOSX") + +#define _AL_MAX_JOYSTICKS 8 + +static bool init_joystick(void); +static void exit_joystick(void); +static int num_joysticks(void); +static ALLEGRO_JOYSTICK* get_joystick(int); +static void release_joystick(ALLEGRO_JOYSTICK*); +static void get_joystick_state(ALLEGRO_JOYSTICK*, ALLEGRO_JOYSTICK_STATE*); + +/* OSX HID Joystick + * Maintains an array of links which connect a HID cookie to + * an element in the ALLEGRO_JOYSTICK_STATE structure. + */ +typedef struct { + ALLEGRO_JOYSTICK parent; + struct { + IOHIDElementCookie cookie; + int* ppressed; + } button_link[_AL_MAX_JOYSTICK_BUTTONS]; + struct { + IOHIDElementCookie cookie; + SInt32 intvalue; + float* pvalue; + float offset; + float multiplier; + int stick, axis; + } axis_link[_AL_MAX_JOYSTICK_AXES * _AL_MAX_JOYSTICK_STICKS]; + int num_axis_links; + ALLEGRO_JOYSTICK_STATE state; + IOHIDDeviceInterface122** interface; + IOHIDQueueInterface** queue; + CFRunLoopSourceRef source; +} ALLEGRO_JOYSTICK_OSX; + +static ALLEGRO_JOYSTICK_OSX joysticks[_AL_MAX_JOYSTICKS]; +static unsigned int joystick_count; + +/* create_device_iterator: + * Create an iterator which will match all joysticks/ + * gamepads on the system. + */ +static io_iterator_t create_device_iterator(UInt16 usage) +{ + NSMutableDictionary* matching; + io_iterator_t iter; + matching = (NSMutableDictionary*) IOServiceMatching(kIOHIDDeviceKey); + // Add in our criteria: + [matching setObject:[NSNumber numberWithShort: usage] forKey: (NSString*) CFSTR(kIOHIDPrimaryUsageKey)]; + [matching setObject:[NSNumber numberWithShort: kHIDPage_GenericDesktop] forKey: (NSString*) CFSTR(kIOHIDPrimaryUsagePageKey)]; + // Get the iterator + IOReturn err = IOServiceGetMatchingServices(kIOMasterPortDefault, (CFDictionaryRef) matching, &iter); + return (err == kIOReturnSuccess) ? iter : 0; +} + +/* create_interface: + * Create the interface to access this device, via + * the intermediate plug-in interface +*/ +static BOOL create_interface(io_object_t device, IOHIDDeviceInterface122*** interface) +{ + io_name_t class_name; + IOReturn err = IOObjectGetClass(device,class_name); + SInt32 score; + IOCFPlugInInterface** plugin; + err = IOCreatePlugInInterfaceForService(device, + kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugin, + &score); + (*plugin)->QueryInterface(plugin, + CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), + (LPVOID) interface); + + (*plugin)->Release(plugin); + return YES; +} + +/* joystick_callback: + * Called when an event occurs on the joystick event queue + * target: the joystick + * refcon: always null + * sender: the queue + */ +static void joystick_callback(void *target, IOReturn result, void *refcon __attribute__((unused)), void *sender) +{ + ALLEGRO_JOYSTICK_OSX* joy = (ALLEGRO_JOYSTICK_OSX*) target; + IOHIDQueueInterface** queue = (IOHIDQueueInterface**) sender; + AbsoluteTime past = {0,0}; + ALLEGRO_EVENT_SOURCE *src = al_get_joystick_event_source(); + if (src == NULL) { + return; + } + _al_event_source_lock(src); + while (result == kIOReturnSuccess) { + IOHIDEventStruct event; + result = (*queue)->getNextEvent(queue, &event, past, 0); + if (result == kIOReturnSuccess) { + int i; + for (i=0; iparent.info.num_buttons; ++i) { + if (joy->button_link[i].cookie == event.elementCookie) { + int newvalue = event.value; + if (*joy->button_link[i].ppressed != newvalue) { + *joy->button_link[i].ppressed = newvalue; + // emit event + ALLEGRO_EVENT evt; + if (newvalue) + evt.type = ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN; + else + evt.type = ALLEGRO_EVENT_JOYSTICK_BUTTON_UP; + evt.joystick.button = i; + _al_event_source_emit_event(src, &evt); + } + } + } + for (i=0; inum_axis_links; ++i) { + if (joy->axis_link[i].cookie == event.elementCookie) { + SInt32 newvalue = event.value; + if (joy->axis_link[i].intvalue != newvalue) { + joy->axis_link[i].intvalue = newvalue; + *joy->axis_link[i].pvalue = (joy->axis_link[i].offset + newvalue) * joy->axis_link[i].multiplier; + // emit event + ALLEGRO_EVENT evt; + evt.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + evt.joystick.axis = joy->axis_link[i].axis; + evt.joystick.pos = *joy->axis_link[i].pvalue; + evt.joystick.stick = joy->axis_link[i].stick; + _al_event_source_emit_event(src, &evt); + } + } + } + } + } + _al_event_source_unlock(src); +} + +/* add_device: + * Create the joystick structure for this device + * and add it to the 'joysticks' vector + * TODO this only works for simple joysticks and + * only allows access to the primary X & Y axes. + * In reality there can be more axes than this and + * more that one distinct controller handled by the same + * interface. + * We should iterate through the application collections to + * find the joysticks then through the physical collections + * therein to identify the individual sticks. + */ +static void add_device(io_object_t device) +{ + ALLEGRO_JOYSTICK_OSX* joy; + NSArray* elements = nil; + int num_buttons = 0; + BOOL have_x = NO, have_y = NO; + IOReturn err; + joy = &joysticks[joystick_count++]; + memset(joy, 0, sizeof(*joy)); + joy->parent.info.num_sticks = 0; + joy->parent.info.num_buttons = 0; + IOHIDDeviceInterface122** interface; + create_interface(device, &interface); + // Open the device + err = (*interface)->open(interface, 0); + // Create an event queue + IOHIDQueueInterface** queue = (*interface)->allocQueue(interface); + err = (*queue)->create(queue, 0, 8); + // Create a source + err = (*queue)->createAsyncEventSource(queue, &joy->source); + err = (*queue)->setEventCallout(queue, joystick_callback, joy, NULL); + joy->queue = queue; + (*interface)->copyMatchingElements(interface, NULL, (CFArrayRef*) &elements); + NSEnumerator* enumerator = [elements objectEnumerator]; + NSDictionary* element; + while ((element = (NSDictionary*) [enumerator nextObject])) { + short usage = [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementUsageKey)]) shortValue]; + short usage_page = [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementUsagePageKey)]) shortValue]; + + if (usage_page == kHIDPage_Button && num_buttons < _AL_MAX_JOYSTICK_BUTTONS) { + joy->button_link[num_buttons].cookie = (IOHIDElementCookie) [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementCookieKey)]) pointerValue]; + joy->button_link[num_buttons].ppressed = &joy->state.button[num_buttons]; + // Use the provided name or make one up. + NSString* name = (NSString*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementNameKey)]; + if (name == nil) { + name = [NSString stringWithFormat:@"Button %d", (num_buttons+1)]; + } + ALLEGRO_INFO("Found button named \"%s\"\n", [name UTF8String]); + // Say that we want events from this button + err = (*queue)->addElement(queue, joy->button_link[num_buttons].cookie, 0); + if (err != 0) { + ALLEGRO_WARN("Button named \"%s\" NOT added to event queue\n", [name UTF8String]); + } else { + joy->parent.info.button[num_buttons].name = strdup([name UTF8String]); + ++num_buttons; + } + } + + if (usage_page == kHIDPage_GenericDesktop) { + if ((usage == kHIDUsage_GD_X) && (!have_x)) { + NSNumber* minValue = (NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementMinKey)]; + NSNumber* maxValue = (NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementMaxKey)]; + joy->axis_link[0].axis = 0; + joy->axis_link[0].stick = 0; + joy->axis_link[0].offset = - ([minValue floatValue] + [maxValue floatValue]) / 2.0f; + joy->axis_link[0].multiplier = 2.0f / ([maxValue floatValue] - [minValue floatValue]); + joy->axis_link[0].cookie = (IOHIDElementCookie) [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementCookieKey)]) pointerValue]; + joy->axis_link[0].pvalue = &joy->state.stick[0].axis[0]; + NSString* name = (NSString*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementNameKey)]; + if (name == nil) { + name = @"X-axis"; + } + ALLEGRO_INFO("Found X-axis named \"%s\"\n", [name UTF8String]); + // Say that we want events from this axis + err = (*queue)->addElement(queue, joy->axis_link[0].cookie, 0); + if (err != 0) { + ALLEGRO_WARN("X-axis named \"%s\" NOT added to event queue\n", [name UTF8String]); + } else { + have_x = YES; + joy->parent.info.stick[0].axis[0].name = strdup([name UTF8String]); + } + } + if ((usage == kHIDUsage_GD_Y) && (!have_y)) { + NSNumber* minValue = (NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementMinKey)]; + NSNumber* maxValue = (NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementMaxKey)]; + joy->axis_link[1].axis = 1; + joy->axis_link[1].stick = 0; + joy->axis_link[1].offset = - ([minValue floatValue] + [maxValue floatValue]) / 2.0f; + joy->axis_link[1].multiplier = 2.0f / ([maxValue floatValue] - [minValue floatValue]); + joy->axis_link[1].cookie = (IOHIDElementCookie) [((NSNumber*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementCookieKey)]) pointerValue]; + joy->axis_link[1].pvalue = &joy->state.stick[0].axis[1]; + NSString* name = (NSString*) [element objectForKey: (NSString*) CFSTR(kIOHIDElementNameKey)]; + if (name == nil) { + name = @"Y-axis"; + } + ALLEGRO_INFO("Found Y-axis named \"%s\"\n", [name UTF8String]); + // Say that we want events from this axis + err = (*queue)->addElement(queue, joy->axis_link[1].cookie, 0); + if (err != 0) { + ALLEGRO_WARN("Y-axis named \"%s\" NOT added to event queue\n", [name UTF8String]); + } else { + have_y = YES; + joy->parent.info.stick[0].axis[1].name = strdup([name UTF8String]); + } + } + } + } + joy->parent.info.num_buttons = num_buttons; + if (have_x && have_y) { + joy->parent.info.stick[0].name = strdup("Primary axis"); + joy->parent.info.num_sticks = 1; + joy->parent.info.stick[0].num_axes = 2; + joy->num_axis_links = 2; + } + joy->interface = interface; + joystick_callback(joy,kIOReturnSuccess,NULL,queue); + [elements release]; +} + +// FIXME! +static const char *get_joystick_name(ALLEGRO_JOYSTICK *joy_) +{ + (void)joy_; + return "Joystick"; +} + +static bool get_joystick_active(ALLEGRO_JOYSTICK *joy_) +{ + (void)joy_; + return true; +} + +static bool reconfigure_joysticks(void) +{ + return false; +} + +ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver_10_4(void) +{ + static ALLEGRO_JOYSTICK_DRIVER* vt = NULL; + if (vt == NULL) { + vt = al_malloc(sizeof(*vt)); + memset(vt, 0, sizeof(*vt)); + vt->joydrv_ascii_name = "OSX HID Driver"; + vt->init_joystick = init_joystick; + vt->exit_joystick = exit_joystick; + vt->num_joysticks = num_joysticks; + vt->get_joystick = get_joystick; + vt->release_joystick = release_joystick; + vt->get_joystick_state = get_joystick_state; + vt->reconfigure_joysticks = reconfigure_joysticks; + vt->get_name = get_joystick_name; + vt->get_active = get_joystick_active; + } + return vt; +} + +/* init_joystick: + * Initializes the HID joystick driver. + */ +static bool init_joystick(void) +{ + joystick_count = 0; + io_iterator_t iterator; + io_object_t device; + iterator = create_device_iterator(kHIDUsage_GD_GamePad); + if (iterator != 0) { + while ((device = IOIteratorNext(iterator))) { + add_device(device); + } + IOObjectRelease(iterator); + } + iterator = create_device_iterator(kHIDUsage_GD_Joystick); + if (iterator != 0) { + while ((device = IOIteratorNext(iterator))) { + add_device(device); + } + IOObjectRelease(iterator); + } + /* Ensure the source is added and started on the main thread */ + dispatch_sync(dispatch_get_main_queue(), ^{ + unsigned int i; + CFRunLoopRef current = CFRunLoopGetCurrent(); + for (i=0; isource,kCFRunLoopDefaultMode); + (*joy->queue)->start(joy->queue); + } + }); + return true; +} + + + +/* exit_joystick: + * Shuts down the HID joystick driver. + */ +static void exit_joystick(void) +{ + /* Ensure the source is stopped and removed on the main thread */ + dispatch_sync(dispatch_get_main_queue(), ^{ + unsigned int i; + CFRunLoopRef current = CFRunLoopGetCurrent(); + for (i=0; iqueue)->stop(joy->queue); + CFRunLoopRemoveSource(current,joy->source,kCFRunLoopDefaultMode); + } + }); + unsigned int i; + for (i=0; i< joystick_count; ++i) { + ALLEGRO_JOYSTICK_OSX* joy = &joysticks[i]; + CFRelease(joy->source); + if (joy->queue) { + (*joy->queue)->dispose(joy->queue); + (*joy->queue)->Release(joy->queue); + } + if (joy->interface) { + (*joy->interface)->close(joy->interface); + (*joy->interface)->Release(joy->interface); + } + int a, b, s; + /* Free everything we might have created + * (all fields set to NULL initially so this is OK.) + */ + for (b = 0; b < _AL_MAX_JOYSTICK_BUTTONS; ++ b) { + al_free((void*) joy->parent.info.button[b].name); + } + for (s = 0; s < _AL_MAX_JOYSTICK_STICKS; ++s) { + al_free((void*) joy->parent.info.stick[s].name); + for (a = 0; a < _AL_MAX_JOYSTICK_AXES; ++a) { + al_free((void*) joy->parent.info.stick[s].axis[a].name); + } + } + } +} + +/* num_joysticks: + * Return number of active joysticks + */ +static int num_joysticks(void) +{ + return joystick_count; +} + +/* get_joystick: + * Get a pointer to a joystick structure + */ +static ALLEGRO_JOYSTICK* get_joystick(int index) +{ + ALLEGRO_JOYSTICK* joy = NULL; + if (index >= 0 && index < (int) joystick_count) { + joy = (ALLEGRO_JOYSTICK *)&joysticks[index]; + } + return joy; +} + +/* release_joystick: + * Release a pointer that has been obtained + */ +static void release_joystick(ALLEGRO_JOYSTICK* joy __attribute__((unused)) ) +{ + // No-op +} + +/* get_joystick_state: + * Get the current status of a joystick + */ +static void get_joystick_state(ALLEGRO_JOYSTICK* ajoy, ALLEGRO_JOYSTICK_STATE* state) +{ + ALLEGRO_JOYSTICK_OSX* joy = (ALLEGRO_JOYSTICK_OSX*) ajoy; + memcpy(state, &joy->state,sizeof(*state)); +} + +/* Local variables: */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/allegro/src/macosx/hidjoy.m b/allegro/src/macosx/hidjoy.m new file mode 100644 index 00000000..5108b766 --- /dev/null +++ b/allegro/src/macosx/hidjoy.m @@ -0,0 +1,790 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * HID Joystick driver routines for MacOS X. + * + * By Angelo Mottola. + * New API (Leopard) support and hotplugging by Trent Gamblin. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/platform/aintosx.h" + +#import +#import + +#ifndef ALLEGRO_MACOSX +#error something is wrong with the makefile +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + +#import + +/* State transitions: + * unused -> born + * born -> alive + * born -> dying + * active -> dying + * dying -> unused + */ +typedef enum { + JOY_STATE_UNUSED, + JOY_STATE_BORN, + JOY_STATE_ALIVE, + JOY_STATE_DYING +} CONFIG_STATE; + +// These values can be found in the USB HID Usage Tables: +// http://www.usb.org/developers/hidpage +#define GENERIC_DESKTOP_USAGE_PAGE 0x01 +#define JOYSTICK_USAGE_NUMBER 0x04 +#define GAMEPAD_USAGE_NUMBER 0x05 + +typedef struct { + ALLEGRO_JOYSTICK parent; + IOHIDElementRef buttons[_AL_MAX_JOYSTICK_BUTTONS]; + IOHIDElementRef axes[_AL_MAX_JOYSTICK_STICKS][_AL_MAX_JOYSTICK_AXES]; + IOHIDElementRef dpad; + int dpad_stick; + int dpad_axis_vert; + int dpad_axis_horiz; + long min[_AL_MAX_JOYSTICK_STICKS][_AL_MAX_JOYSTICK_AXES]; + long max[_AL_MAX_JOYSTICK_STICKS][_AL_MAX_JOYSTICK_AXES]; + CONFIG_STATE cfg_state; + ALLEGRO_JOYSTICK_STATE state; + IOHIDDeviceRef ident; +} ALLEGRO_JOYSTICK_OSX; + +static IOHIDManagerRef hidManagerRef; +static _AL_VECTOR joysticks; +static CONFIG_STATE new_joystick_state = JOY_STATE_ALIVE; +static bool initialized = false; +static ALLEGRO_MUTEX *add_mutex; + +ALLEGRO_DEBUG_CHANNEL("MacOSX") + +// function to create matching dictionary (for devices) +static CFMutableDictionaryRef CreateDeviceMatchingDictionary( + UInt32 inUsagePage, + UInt32 inUsage +) { + // create a dictionary to add usage page/usages to + CFMutableDictionaryRef result = CFDictionaryCreateMutable( + kCFAllocatorDefault, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks + ); + + if (result) { + // Add key for device type to refine the matching dictionary. + CFNumberRef pageCFNumberRef = CFNumberCreate( + kCFAllocatorDefault, + kCFNumberIntType, + &inUsagePage + ); + + if (pageCFNumberRef) { + CFStringRef usage_page = CFSTR(kIOHIDDeviceUsagePageKey); + + CFDictionarySetValue( + result, + usage_page, + pageCFNumberRef + ); + + CFRelease(pageCFNumberRef); + + // note: the usage is only valid if the usage page is also defined + + CFNumberRef usageCFNumberRef = CFNumberCreate( + kCFAllocatorDefault, + kCFNumberIntType, + &inUsage + ); + + if (usageCFNumberRef) { + CFStringRef usage_key = CFSTR(kIOHIDDeviceUsageKey); + + CFDictionarySetValue( + result, + usage_key, + usageCFNumberRef + ); + + CFRelease(usageCFNumberRef); + } + } + } + + return result; +} + +static ALLEGRO_JOYSTICK_OSX *find_joystick(IOHIDDeviceRef ident) +{ + int i; + for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); + if (ident == joy->ident) { + return joy; + } + } + + return NULL; +} + +static const char *get_element_name(IOHIDElementRef elem, const char *default_name) +{ + CFStringRef name = IOHIDElementGetName(elem); + if (name) { + return CFStringGetCStringPtr(name, kCFStringEncodingUTF8); + } + else + return default_name; +} + +static void joy_null(ALLEGRO_JOYSTICK_OSX *joy) +{ + int i, j; + + // NULL the parent + for (i = 0; i < _AL_MAX_JOYSTICK_BUTTONS; i++) { + joy->parent.info.button[i].name = NULL; + } + for (i = 0; i < _AL_MAX_JOYSTICK_STICKS; i++) { + joy->parent.info.stick[i].name = NULL; + for (j = 0; j < _AL_MAX_JOYSTICK_AXES; j++) { + joy->parent.info.stick[i].axis[j].name = NULL; + } + } +} + +static void add_axis(ALLEGRO_JOYSTICK_OSX *joy, int stick_index, int axis_index, int min, int max, char *name, IOHIDElementRef elem) +{ + if (axis_index >= _AL_MAX_JOYSTICK_AXES) + return; + + joy->min[stick_index][axis_index] = min; + joy->max[stick_index][axis_index] = max; + + joy->parent.info.stick[stick_index].axis[axis_index].name = name; + joy->parent.info.stick[stick_index].num_axes++; + joy->axes[stick_index][axis_index] = elem; +} + +static void add_elements(CFArrayRef elements, ALLEGRO_JOYSTICK_OSX *joy) +{ + int i; + char default_name[100]; + int stick_class = -1; + int axis_index = 0; + + joy_null(joy); + + for (i = 0; i < CFArrayGetCount(elements); i++) { + IOHIDElementRef elem = (IOHIDElementRef)CFArrayGetValueAtIndex( + elements, + i + ); + + int usage = IOHIDElementGetUsage(elem); + if (IOHIDElementGetType(elem) == kIOHIDElementTypeInput_Button) { + if (usage >= 0 && usage < _AL_MAX_JOYSTICK_BUTTONS && + !joy->buttons[usage-1]) { + joy->buttons[usage-1] = elem; + sprintf(default_name, "Button %d", usage-1); + const char *name = get_element_name(elem, default_name); + char *str = al_malloc(strlen(name)+1); + strcpy(str, name); + joy->parent.info.button[usage-1].name = str; + joy->parent.info.num_buttons++; + } + } + else if ( + IOHIDElementGetType(elem) == kIOHIDElementTypeInput_Misc) { + long min = IOHIDElementGetLogicalMin(elem); + long max = IOHIDElementGetLogicalMax(elem); + int new_stick_class = -1; + int stick_index = joy->parent.info.num_sticks - 1; + + switch (usage) { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + case kHIDUsage_GD_Z: + new_stick_class = 1; + break; + + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + new_stick_class = 2; + break; + + case kHIDUsage_GD_Hatswitch: + new_stick_class = 3; + break; + } + + if (new_stick_class < 0) + continue; + + if (stick_class != new_stick_class) { + if (joy->parent.info.num_sticks >= _AL_MAX_JOYSTICK_STICKS-1) + break; + + joy->parent.info.num_sticks++; + + stick_index++; + axis_index = 0; + + stick_class = new_stick_class; + + char *buf = al_malloc(20); + sprintf(buf, "Stick %d", stick_index); + joy->parent.info.stick[stick_index].name = buf; + } + else + axis_index++; + + if (stick_class == 3) { + joy->dpad_stick = stick_index; + joy->dpad = elem; + + joy->dpad_axis_horiz = axis_index; + sprintf(default_name, "Axis %i", axis_index); + char *str = al_malloc(strlen(default_name)+1); + strcpy(str, default_name); + joy->parent.info.stick[stick_index].axis[axis_index].name = str; + + ++axis_index; + joy->dpad_axis_vert = axis_index; + sprintf(default_name, "Axis %i", axis_index); + str = al_malloc(strlen(default_name)+1); + strcpy(str, default_name); + add_axis(joy, stick_index, axis_index, min, max, str, elem); + joy->parent.info.stick[stick_index].axis[axis_index].name = str; + + joy->parent.info.stick[stick_index].num_axes = 2; + } + else { + sprintf(default_name, "Axis %i", axis_index); + const char *name = get_element_name(elem, default_name); + char *str = al_malloc(strlen(name)+1); + strcpy(str, name); + add_axis(joy, stick_index, axis_index, min, max, str, elem); + } + } + } +} + +static void osx_joy_generate_configure_event(void) +{ + if (!initialized) return; + + ALLEGRO_EVENT event; + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; + event.joystick.timestamp = al_current_time(); + + _al_generate_joystick_event(&event); +} + +static void device_add_callback( + void *context, + IOReturn result, + void *sender, + IOHIDDeviceRef ref +) { + (void)context; + (void)result; + (void)sender; + + al_lock_mutex(add_mutex); + + ALLEGRO_JOYSTICK_OSX *joy = find_joystick(ref); + if (joy == NULL) { + joy = al_calloc(1, sizeof(ALLEGRO_JOYSTICK_OSX)); + joy->ident = ref; + ALLEGRO_JOYSTICK_OSX **back = _al_vector_alloc_back(&joysticks); + *back = joy; + } + joy->cfg_state = new_joystick_state; + + CFArrayRef elements = IOHIDDeviceCopyMatchingElements( + ref, + NULL, + kIOHIDOptionsTypeNone + ); + + add_elements(elements, joy); + + CFRelease(elements); + + + al_unlock_mutex(add_mutex); + + osx_joy_generate_configure_event(); + + ALLEGRO_INFO("Found joystick (%d buttons, %d sticks)\n", + joy->parent.info.num_buttons, joy->parent.info.num_sticks); +} + +static void device_remove_callback( + void *context, + IOReturn result, + void *sender, + IOHIDDeviceRef ref +) { + (void)context; + (void)result; + (void)sender; + + int i; + for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); + if (joy->ident == ref) { + joy->cfg_state = JOY_STATE_DYING; + osx_joy_generate_configure_event(); + return; + } + } +} + +static void osx_joy_generate_axis_event(ALLEGRO_JOYSTICK_OSX *joy, int stick, int axis, float pos) +{ + joy->state.stick[stick].axis[axis] = pos; + + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(es)) + return; + + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.timestamp = al_current_time(); + event.joystick.id = (ALLEGRO_JOYSTICK *)joy; + event.joystick.stick = stick; + event.joystick.axis = axis; + event.joystick.pos = pos; + event.joystick.button = 0; + + _al_event_source_emit_event(es, &event); +} + +static void osx_joy_generate_button_event(ALLEGRO_JOYSTICK_OSX *joy, int button, ALLEGRO_EVENT_TYPE event_type) +{ + joy->state.button[button] = event_type == ALLEGRO_EVENT_JOYSTICK_BUTTON_UP ? + 0 : 1;; + + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(es)) + return; + + event.joystick.type = event_type; + event.joystick.timestamp = al_current_time(); + event.joystick.id = (ALLEGRO_JOYSTICK *)joy; + event.joystick.stick = 0; + event.joystick.axis = 0; + event.joystick.pos = 0.0; + event.joystick.button = button; + + _al_event_source_emit_event(es, &event); +} + +#define MAX_HAT_DIRECTIONS 9 +struct HAT_MAPPING { + int axisV; + int axisH; +} hat_mapping[MAX_HAT_DIRECTIONS] = { + { -1, 0 }, // 0 + { -1, 1 }, // 1 + { 0, 1 }, // 2 + { 1, 1 }, // 3 + { 1, 0 }, // 4 + { 1, -1 }, // 5 + { 0, -1 }, // 6 + { -1, -1 }, // 7 + { 0, 0 }, // 8 +}; + +static void value_callback( + void *context, + IOReturn result, + void *sender, + IOHIDValueRef value +) { + if (!initialized) return; + + (void)context; + (void)result; + (void)sender; + + IOHIDElementRef elem = IOHIDValueGetElement(value); + IOHIDDeviceRef ref = IOHIDElementGetDevice(elem); + ALLEGRO_JOYSTICK_OSX *joy = find_joystick(ref); + + if (!joy) return; + + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + _al_event_source_lock(es); + + int i; + for (i = 0; i < joy->parent.info.num_buttons; i++) { + if (joy->buttons[i] == elem) { + ALLEGRO_EVENT_TYPE type; + if (IOHIDValueGetIntegerValue(value) == 0) + type = ALLEGRO_EVENT_JOYSTICK_BUTTON_UP; + else + type = ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN; + osx_joy_generate_button_event(joy, i, type); + goto done; + } + } + + int int_value = IOHIDValueGetIntegerValue(value); + + if (joy->dpad == elem){ + if (int_value >= 0 && int_value < MAX_HAT_DIRECTIONS) { + osx_joy_generate_axis_event(joy, joy->dpad_stick, joy->dpad_axis_vert, (float)hat_mapping[int_value].axisV); + osx_joy_generate_axis_event(joy, joy->dpad_stick, joy->dpad_axis_horiz, (float)hat_mapping[int_value].axisH); + } + goto done; + } + + int stick = -1; + int axis = -1; + for (stick = 0; stick < joy->parent.info.num_sticks; stick++) { + for(axis = 0; axis < joy->parent.info.stick[stick].num_axes; ++axis) { + if (joy->axes[stick][axis] == elem) { + goto gen_axis_event; + } + } + } + + // Unknown event + goto done; + +gen_axis_event: + { + float pos; + long min = joy->min[stick][axis]; + long max = joy->max[stick][axis]; + if (min < 0) { + if (int_value < 0) + pos = -(float)int_value/min; + else + pos = (float)int_value/max; + } + else { + pos = ((float)int_value/max*2) - 1; + } + + osx_joy_generate_axis_event(joy, stick, axis, pos); + } + +done: + _al_event_source_unlock(es); +} + +/* init_joystick: + * Initializes the HID joystick driver. + */ +static bool init_joystick(void) +{ + add_mutex = al_create_mutex(); + + hidManagerRef = IOHIDManagerCreate( + kCFAllocatorDefault, + kIOHIDOptionsTypeNone + ); + + if (CFGetTypeID(hidManagerRef) != IOHIDManagerGetTypeID()) { + ALLEGRO_ERROR("Unable to create HID Manager\n"); + return false; + } + + // Set which devices we want to match + CFMutableDictionaryRef criteria0 = CreateDeviceMatchingDictionary( + GENERIC_DESKTOP_USAGE_PAGE, + JOYSTICK_USAGE_NUMBER + ); + CFMutableDictionaryRef criteria1 = CreateDeviceMatchingDictionary( + GENERIC_DESKTOP_USAGE_PAGE, + GAMEPAD_USAGE_NUMBER + ); + CFMutableDictionaryRef criteria_list[] = { + criteria0, + criteria1 + }; + CFArrayRef criteria = CFArrayCreate( + kCFAllocatorDefault, + (const void **)criteria_list, + 2, NULL + ); + + IOHIDManagerSetDeviceMatchingMultiple( + hidManagerRef, + criteria + ); + + CFRelease(criteria0); + CFRelease(criteria1); + CFRelease(criteria); + + /* Register for plug/unplug notifications */ + IOHIDManagerRegisterDeviceMatchingCallback( + hidManagerRef, + device_add_callback, + NULL + ); + IOHIDManagerRegisterDeviceRemovalCallback( + hidManagerRef, + device_remove_callback, + NULL + ); + + // Register for value changes + IOHIDManagerRegisterInputValueCallback( + hidManagerRef, + value_callback, + NULL + ); + + IOHIDManagerScheduleWithRunLoop( + hidManagerRef, + CFRunLoopGetMain(), + kCFRunLoopDefaultMode + ); + + _al_vector_init(&joysticks, sizeof(ALLEGRO_JOYSTICK_OSX *)); + + al_lock_mutex(add_mutex); + + IOReturn ret = IOHIDManagerOpen( + hidManagerRef, + kIOHIDOptionsTypeSeizeDevice + ); + + al_unlock_mutex(add_mutex); + + if (ret != kIOReturnSuccess) { + return false; + } + + // Wait for the devices to be enumerated + int count; + int size; + do { + al_rest(0.001); + CFSetRef devices = IOHIDManagerCopyDevices(hidManagerRef); + if (devices == nil) { + break; + } + count = CFSetGetCount(devices); + CFRelease(devices); + al_lock_mutex(add_mutex); + size = _al_vector_size(&joysticks); + al_unlock_mutex(add_mutex); + } while (size < count); + + new_joystick_state = JOY_STATE_BORN; + + initialized = true; + + return true; +} + +/* exit_joystick: + * Shuts down the HID joystick driver. + */ +static void exit_joystick(void) +{ + al_destroy_mutex(add_mutex); + + IOHIDManagerUnscheduleFromRunLoop( + hidManagerRef, + CFRunLoopGetCurrent(), + kCFRunLoopDefaultMode + ); + // Unregister from value changes + IOHIDManagerRegisterInputValueCallback( + hidManagerRef, + NULL, + NULL + ); + IOHIDManagerClose( + hidManagerRef, + kIOHIDOptionsTypeNone + ); + CFRelease(hidManagerRef); + + _al_vector_free(&joysticks); + + initialized = false; +} + +/* num_joysticks: + * Return number of active joysticks + */ +static int num_joysticks(void) +{ + int i; + int count = 0; + for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); + if (joy->cfg_state == JOY_STATE_ALIVE) { + count++; + } + } + + return count; +} + +/* get_joystick: + * Get a pointer to a joystick structure + */ +static ALLEGRO_JOYSTICK* get_joystick(int index) +{ + ASSERT(index >= 0 && index < (int)_al_vector_size(&joysticks)); + + int i; + int count = 0; + for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); + if (joy->cfg_state == JOY_STATE_ALIVE || + joy->cfg_state == JOY_STATE_DYING) { + if (count == index) { + return (ALLEGRO_JOYSTICK *)joy; + } + count++; + } + } + + return NULL; +} + +/* release_joystick: + * Release a pointer that has been obtained + */ +static void release_joystick(ALLEGRO_JOYSTICK* joy __attribute__((unused)) ) +{ + // No-op +} + +/* get_joystick_state: + * Get the current status of a joystick + */ +static void get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + ALLEGRO_JOYSTICK_OSX *joy = (ALLEGRO_JOYSTICK_OSX *) joy_; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + _al_event_source_lock(es); + { + *ret_state = joy->state; + } + _al_event_source_unlock(es); +} + +static bool reconfigure_joysticks(void) +{ + int i; + bool ret = false; + for (i = 0; i < (int)_al_vector_size(&joysticks); i++) { + ALLEGRO_JOYSTICK_OSX *joy = *(ALLEGRO_JOYSTICK_OSX **)_al_vector_ref(&joysticks, i); + if (joy->cfg_state == JOY_STATE_DYING) { + joy->cfg_state = JOY_STATE_UNUSED; + for (i = 0; i < _AL_MAX_JOYSTICK_BUTTONS; i++) { + al_free((char *)joy->parent.info.button[i].name); + } + for (i = 0; i < _AL_MAX_JOYSTICK_STICKS; i++) { + int j; + al_free(joy->parent.info.stick[i].name); + for (j = 0; j < _AL_MAX_JOYSTICK_AXES; j++) { + al_free(joy->parent.info.stick[i].axis[j].name); + } + } + joy_null(joy); + memset(joy->buttons, 0, _AL_MAX_JOYSTICK_BUTTONS*sizeof(IOHIDElementRef)); + memset(&joy->state, 0, sizeof(ALLEGRO_JOYSTICK_STATE)); + joy->dpad=0; + } + else if (joy->cfg_state == JOY_STATE_BORN) + joy->cfg_state = JOY_STATE_ALIVE; + else + continue; + ret = true; + } + + return ret; +} + +// FIXME! +static const char *get_joystick_name(ALLEGRO_JOYSTICK *joy_) +{ + (void)joy_; + return "Joystick"; +} + +static bool get_joystick_active(ALLEGRO_JOYSTICK *joy_) +{ + ALLEGRO_JOYSTICK_OSX *joy = (ALLEGRO_JOYSTICK_OSX *)joy_; + return joy->cfg_state == JOY_STATE_ALIVE || joy->cfg_state == JOY_STATE_DYING; +} + +ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver_10_5(void) +{ + static ALLEGRO_JOYSTICK_DRIVER* vt = NULL; + if (vt == NULL) { + vt = al_malloc(sizeof(*vt)); + memset(vt, 0, sizeof(*vt)); + vt->joydrv_ascii_name = "OSX HID Driver"; + vt->init_joystick = init_joystick; + vt->exit_joystick = exit_joystick; + vt->reconfigure_joysticks = reconfigure_joysticks; + vt->num_joysticks = num_joysticks; + vt->get_joystick = get_joystick; + vt->release_joystick = release_joystick; + vt->get_joystick_state = get_joystick_state; + vt->get_name = get_joystick_name; + vt->get_active = get_joystick_active; + } + return vt; +} + +#endif // Leopard+ + +#ifndef NSAppKitVersionNumber10_5 +#define NSAppKitVersionNumber10_5 949 +#endif + + + +ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver_10_4(void); +ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver_10_5(void); + +ALLEGRO_JOYSTICK_DRIVER* _al_osx_get_joystick_driver(void) +{ + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_5) { + return _al_osx_get_joystick_driver_10_5(); + } + else { + return _al_osx_get_joystick_driver_10_4(); + } +} + +/* Local variables: */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/allegro/src/macosx/hidman.m b/allegro/src/macosx/hidman.m new file mode 100644 index 00000000..74f6af20 --- /dev/null +++ b/allegro/src/macosx/hidman.m @@ -0,0 +1,532 @@ +/* ______ ___ ___ +* /\ _ \ /\_ \ /\_ \ +* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ +* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ +* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ +* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ +* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ +* /\____/ +* \_/__/ +* +* MacOS X HID Manager access routines. +* +* By Angelo Mottola. +* +* See readme.txt for copyright information. +*/ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/platform/aintosx.h" + +#ifndef ALLEGRO_MACOSX +#error Something is wrong with the makefile +#endif + +#define USAGE(p, u) (((p)<<16)+(u)) + +static void hid_store_element_data(CFTypeRef element, int type, HID_DEVICE *device, int app, int collection, int index); +static void hid_scan_physical_collection(CFTypeRef properties, HID_DEVICE *device, int app, int collection); +static void hid_scan_application_collection(CFMutableDictionaryRef properties, HID_DEVICE *device); + +static HID_DEVICE* add_device(HID_DEVICE_COLLECTION*); + +/* add_element: +* Add a new, blank element to a device. +* This is later specialized into a button +* axis or whatever +*/ +static HID_ELEMENT* add_element(HID_DEVICE* d) { + HID_ELEMENT* e; + if (d->element==NULL) { + d->capacity=8; + d->element=al_malloc(d->capacity*sizeof(HID_ELEMENT)); + } + if (d->num_elements>=d->capacity) { + d->capacity*=2; + d->element=al_realloc(d->element, d->capacity*sizeof(HID_ELEMENT)); + } + e=&d->element[d->num_elements++]; + memset(e, 0, sizeof(HID_ELEMENT)); + return e; +} + +/* i_val: +* Helper method - get an integer value from a dictionary +* Defaults to 0 if the value is not found; in practice this +* should not occur. +*/ +static int i_val(CFTypeRef d, CFStringRef key) { + int ans; + CFTypeRef num = CFDictionaryGetValue(d, key); + if (num) + CFNumberGetValue(num, kCFNumberIntType, &ans); + else + ans = 0; + return ans; +} + +/* hid_store_element_data: +* Parse this HID element, break it down and store the +* relevant data in the device structure +*/ +static void hid_store_element_data(CFTypeRef element, int type, HID_DEVICE *device, int app, int col, int idx) +{ + HID_ELEMENT *hid_element; + CFTypeRef type_ref; + const char *name; + + hid_element = add_element(device); + hid_element->type = type; + hid_element->index = idx; + hid_element->col = col; + hid_element->app = app; + hid_element->cookie = (IOHIDElementCookie) i_val(element, CFSTR(kIOHIDElementCookieKey)); + hid_element->min = i_val(element, CFSTR(kIOHIDElementMinKey)); + hid_element->max = i_val(element, CFSTR(kIOHIDElementMaxKey)); + type_ref = CFDictionaryGetValue(element, CFSTR(kIOHIDElementNameKey)); + if ((type_ref) && (name = CFStringGetCStringPtr(type_ref, CFStringGetSystemEncoding()))) + hid_element->name = strdup(name); + else + hid_element->name = NULL; +} + +/* hid_scan_application: +* scan the elements that make up one 'application' +* i.e. one unit like a joystick. +*/ +static void hid_scan_application(CFTypeRef properties, HID_DEVICE *device, int app) +{ + CFTypeRef array_ref, element; + int type, usage_page, usage; + int i; + int axis=0; + int stick=0; + array_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDElementKey)); + if ((array_ref) && (CFGetTypeID(array_ref) == CFArrayGetTypeID())) { + for (i = 0; i < CFArrayGetCount(array_ref); i++) { + element = CFArrayGetValueAtIndex(array_ref, i); + if (CFGetTypeID(element) == CFDictionaryGetTypeID()) { + type = i_val(element, CFSTR(kIOHIDElementTypeKey)); + usage = i_val(element, CFSTR(kIOHIDElementUsageKey)); + usage_page = i_val(element, CFSTR(kIOHIDElementUsagePageKey)); + if (type == kIOHIDElementTypeCollection) + { + /* It is a collection; recurse into it, if it is part of the + * generic desktop (sometimes the whole joystick is wrapped + * up inside a collection like this. + */ + if (usage_page == kHIDPage_GenericDesktop) + hid_scan_application(element, device, app); + } + else + { + switch (usage_page) { + case kHIDPage_GenericDesktop: + switch (usage) { + case kHIDUsage_GD_Pointer: + if (axis!=0) { + /* already have some elements in this stick */ + ++stick; + axis=0; + } + hid_scan_physical_collection(element, device, app, stick); + ++stick; + break; + case kHIDUsage_GD_X: + hid_store_element_data(element, HID_ELEMENT_AXIS_PRIMARY_X, device, app, stick, axis++); + break; + + case kHIDUsage_GD_Y: + hid_store_element_data(element, HID_ELEMENT_AXIS_PRIMARY_Y, device, app, stick, axis++); + break; + + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + hid_store_element_data(element, HID_ELEMENT_AXIS, device,app, stick, axis++); + break; + + case kHIDUsage_GD_Slider: + case kHIDUsage_GD_Dial: + case kHIDUsage_GD_Wheel: + /* If we've already seen some axes on this stick, move to the next one */ + if (axis > 0) + { + ++stick; + axis=0; + } + hid_store_element_data(element, HID_ELEMENT_STANDALONE_AXIS, device, app, stick++, 0); + break; + + case kHIDUsage_GD_Hatswitch: + /* If we've already seen some axes on this stick, move to the next one */ + if (axis > 0) + { + ++stick; + axis=0; + } + hid_store_element_data(element, HID_ELEMENT_HAT, device, app, stick++, 0); + break; + } + break; + case kHIDPage_Button: + hid_store_element_data(element, HID_ELEMENT_BUTTON, device, app, 0, usage-1); + break; + } + } + if (axis>=2) { + ++stick; + axis=0; + } + } + } + } +} + +/* hid_scan_physical_collection: +* scan the elements that make up one 'stick' +*/ +static void hid_scan_physical_collection(CFTypeRef properties, HID_DEVICE *device, int app, int stick) +{ + CFTypeRef array_ref, element; + int type, usage_page, usage; + int i; + int axis=0; + array_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDElementKey)); + if ((array_ref) && (CFGetTypeID(array_ref) == CFArrayGetTypeID())) { + for (i = 0; i < CFArrayGetCount(array_ref); i++) { + element = CFArrayGetValueAtIndex(array_ref, i); + if (CFGetTypeID(element) == CFDictionaryGetTypeID()) { + type = i_val(element, CFSTR(kIOHIDElementTypeKey)); + usage = i_val(element, CFSTR(kIOHIDElementUsageKey)); + usage_page = i_val(element, CFSTR(kIOHIDElementUsagePageKey)); + switch (usage_page) { + case kHIDPage_GenericDesktop: + switch (usage) { + case kHIDUsage_GD_X: + hid_store_element_data(element, HID_ELEMENT_AXIS_PRIMARY_X, device, app, stick, axis++); + break; + + case kHIDUsage_GD_Y: + hid_store_element_data(element, HID_ELEMENT_AXIS_PRIMARY_Y, device, app, stick, axis++); + break; + + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + hid_store_element_data(element, HID_ELEMENT_AXIS, device,app, stick, axis++); + break; + } + break; + case kHIDPage_Button: + hid_store_element_data(element, HID_ELEMENT_BUTTON, device, app, 0, usage-1); + break; + } + } + } + } +} + +/* hid_scan_application_collection: +* Scan the elements array; each element will be an 'application' +* i.e. one joystick, gamepad or mouse +* +*/ +static void hid_scan_application_collection(CFMutableDictionaryRef properties, HID_DEVICE *device) +{ + CFTypeRef array_ref, element; + + int usage, usage_page; + int i; + + array_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDElementKey)); + if ((array_ref) && (CFGetTypeID(array_ref) == CFArrayGetTypeID())) { + for (i = 0; i < CFArrayGetCount(array_ref); i++) { + element = CFArrayGetValueAtIndex(array_ref, i); + if (CFGetTypeID(element) == CFDictionaryGetTypeID()) { + usage=i_val(element, CFSTR(kIOHIDElementUsageKey)); + usage_page=i_val(element, CFSTR(kIOHIDElementUsagePageKey)); + switch (USAGE(usage_page, usage)) { + case USAGE(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick): + device->type=HID_JOYSTICK; + hid_scan_application(element, device, device->cur_app); + device->cur_app++; + break; + case USAGE(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad): + device->type=HID_GAMEPAD; + hid_scan_application(element, device, device->cur_app); + device->cur_app++; + break; + case USAGE(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse): + device->type=HID_MOUSE; + hid_scan_application(element, device, device->cur_app); + device->cur_app++; + break; + } + } + } + } +} + +/* get_usb_properties: +* Get a property dictionary from the USB plane. +*/ +static CFMutableDictionaryRef get_usb_properties(io_object_t device) +{ + io_registry_entry_t parent, grandparent; + CFMutableDictionaryRef usb_properties = NULL; + if (IORegistryEntryGetParentEntry(device, kIOServicePlane, &parent) == KERN_SUCCESS) { + if (IORegistryEntryGetParentEntry(parent, kIOServicePlane, &grandparent) == KERN_SUCCESS) { + IORegistryEntryCreateCFProperties (grandparent, &usb_properties, + kCFAllocatorDefault, kNilOptions); + IOObjectRelease(grandparent); + } + IOObjectRelease(parent); + } + return usb_properties; +} + +#if OSX_HID_PSEUDO_SCAN +/* + * Pseudo scan - for development purposes, if someone has hardware + * that isn't parsed by this code, you can ask them to dump _their_ scan + * as a plist, then reload it here in order to debug it. + */ +HID_DEVICE_COLLECTION *_al_osx_hid_scan(int type, HID_DEVICE_COLLECTION* col) +{ + HID_DEVICE* this_device; + NSDictionary* properties = nil; + NSString* filename; + switch (type) { + case HID_GAMEPAD: + filename = @"gamepad.plist"; + break; + case HID_JOYSTICK: + filename = @"joystick.plist"; + break; + case HID_MOUSE: + filename = @"mouse.plist"; + break; + default: + filename = nil; + break; + } + if (filename != nil) + properties = [NSDictionary dictionaryWithContentsOfFile:filename]; + if (properties) + { + this_device = add_device(col); + this_device->manufacturer = strdup([((NSString*) [properties objectForKey: @kIOHIDManufacturerKey]) lossyCString]); + this_device->product = strdup([((NSString*) [properties objectForKey: @kIOHIDProductKey]) lossyCString]); + hid_scan_application_collection((CFDictionaryRef) properties, this_device); + [properties release]; + } + return col; +} +#else +/* _get_matching_services: + * get iterator for corresponding services + */ +static IOReturn _get_matching_services(mach_port_t master_port, int usage_page, int usage, io_iterator_t *hid_object_iterator) +{ + CFMutableDictionaryRef class_dictionary = NULL; + CFNumberRef usage_ref = NULL; + CFNumberRef usage_page_ref = NULL; + + class_dictionary = IOServiceMatching(kIOHIDDeviceKey); + if (class_dictionary) { + /* Add key for device type to refine the matching dictionary. */ + usage_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); + usage_page_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page); + CFDictionarySetValue(class_dictionary, CFSTR(kIOHIDDeviceUsageKey), usage_ref); + CFDictionarySetValue(class_dictionary, CFSTR(kIOHIDDeviceUsagePageKey), usage_page_ref); + } + IOReturn result = IOServiceGetMatchingServices(master_port, class_dictionary, hid_object_iterator); + if (usage_ref) CFRelease(usage_ref); + if (usage_page_ref) CFRelease(usage_page_ref); + return result; +} + +/* _al_osx_hid_scan: +* Scan the hid manager for devices of type 'type', +* and append to the collection col +*/ +HID_DEVICE_COLLECTION *_al_osx_hid_scan(int type, HID_DEVICE_COLLECTION* col) +{ + ASSERT(col); + HID_DEVICE *this_device; + mach_port_t master_port = 0; + io_iterator_t hid_object_iterator = 0; + io_object_t hid_device = 0; + int usage, usage_page; + CFTypeRef type_ref; + CFMutableDictionaryRef properties = NULL, usb_properties = NULL; + IOCFPlugInInterface **plugin_interface = NULL; + IOReturn result; + const char *string; + SInt32 score = 0; + int error; + + usage_page = kHIDPage_GenericDesktop; + switch (type) { + case HID_MOUSE: + usage = kHIDUsage_GD_Mouse; + break; + case HID_JOYSTICK: + usage = kHIDUsage_GD_Joystick; + break; + case HID_GAMEPAD: + usage=kHIDUsage_GD_GamePad; + break; + } + + result = IOMasterPort(bootstrap_port, &master_port); + if (result == kIOReturnSuccess) { + result = _get_matching_services(master_port, usage_page, usage, &hid_object_iterator); + if ((type == HID_MOUSE) && (hid_object_iterator == IO_OBJECT_NULL)) { + /* in case of a mouse, GD_Mouse must not be true but can also be a pointing device */ + result = _get_matching_services(master_port, usage_page, kHIDUsage_GD_Pointer, &hid_object_iterator); + } + if ((result == kIOReturnSuccess) && (hid_object_iterator)) { + /* Ok, we have a list of attached HID devices; scan them. */ + while ((hid_device = IOIteratorNext(hid_object_iterator))!=0) { + if ((IORegistryEntryCreateCFProperties(hid_device, &properties, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS) && (properties != NULL)) { + error = false; + this_device = add_device(col); + this_device->type = type; + if (col->count==0) { + this_device->cur_app=0; + } + else { + this_device->cur_app=col->devices[col->count-1].cur_app; + } + /* + * Mac OS X currently is not mirroring all USB properties + * to HID page so need to look at USB device page also. + */ + usb_properties = get_usb_properties(hid_device); + type_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDManufacturerKey)); + if (!type_ref) + type_ref = CFDictionaryGetValue(usb_properties, CFSTR("USB Vendor Name")); + if ((type_ref) && (string = CFStringGetCStringPtr(type_ref, CFStringGetSystemEncoding()))) + this_device->manufacturer = strdup(string); + else + this_device->manufacturer = NULL; + type_ref = CFDictionaryGetValue(properties, CFSTR(kIOHIDProductKey)); + if (!type_ref) + type_ref = CFDictionaryGetValue(usb_properties, CFSTR("USB Product Name")); + if ((type_ref) && (string = CFStringGetCStringPtr(type_ref, CFStringGetSystemEncoding()))) + this_device->product = strdup(string); + else + this_device->product = NULL; + + type_ref = CFDictionaryGetValue(usb_properties, CFSTR("USB Address")); + if ((type == HID_MOUSE) && (!type_ref)) { + /* Not an USB mouse. Must be integrated trackpad: we report it as a single button mouse */ + add_element(this_device)->type = HID_ELEMENT_BUTTON; + } + else { + /* Scan for device elements */ + this_device->num_elements = 0; + hid_scan_application_collection(properties, this_device); + } + + this_device->interface = NULL; + if ((type == HID_JOYSTICK) || (type == HID_GAMEPAD)) { + /* Joystick or gamepad device: create HID interface */ + if (IOCreatePlugInInterfaceForService(hid_device, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin_interface, &score) != kIOReturnSuccess) + error = true; + else { + if ((*plugin_interface)->QueryInterface(plugin_interface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void *)&(this_device->interface)) != S_OK) + error = true; + (*plugin_interface)->Release(plugin_interface); + if ((*(this_device->interface))->open(this_device->interface, 0) != KERN_SUCCESS) + error = true; + } + } + if (error) { + if (this_device->manufacturer) + al_free(this_device->manufacturer); + if (this_device->product) + al_free(this_device->product); + if (this_device->interface) + (*(this_device->interface))->Release(this_device->interface); + this_device->interface=NULL; + --col->count; + } + + CFRelease(properties); + CFRelease(usb_properties); + } + } + IOObjectRelease(hid_object_iterator); + } + mach_port_deallocate(mach_task_self(), master_port); + } + + return col; +} +#endif +/* add_device: +* add a new device to a collection +*/ +static HID_DEVICE* add_device(HID_DEVICE_COLLECTION* o) { + HID_DEVICE* d; + if (o->devices==NULL) { + o->count=0; + o->capacity=1; + o->devices=al_malloc(o->capacity*sizeof(HID_DEVICE)); + } + if (o->count>=o->capacity) { + o->capacity*=2; + o->devices=al_realloc(o->devices, o->capacity*sizeof(HID_DEVICE)); + } + d=&o->devices[o->count]; + memset(d, 0, sizeof(HID_DEVICE)); + /* Chain onto the preceding app count */ + if (o->count>0) + d->cur_app = o->devices[o->count-1].cur_app; + ++o->count; + return d; +} + +/* _al_osx_hid_free: +* Release the memory taken up by a collection +*/ +void _al_osx_hid_free(HID_DEVICE_COLLECTION *col) +{ + HID_DEVICE *device; + HID_ELEMENT *element; + int i, j; + + for (i = 0; i < col->count; i++) { + device = &col->devices[i]; + if (device->manufacturer) + al_free(device->manufacturer); + if (device->product) + al_free(device->product); + for (j = 0; j < device->num_elements; j++) { + element = &device->element[j]; + if (element->name) + al_free(element->name); + } + al_free(device->element); + if (device->interface) { + (*(device->interface))->close(device->interface); + (*(device->interface))->Release(device->interface); + } + } + al_free(col->devices); +} + + +/* Local variables: */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/allegro/src/macosx/keybd.m b/allegro/src/macosx/keybd.m new file mode 100644 index 00000000..6a463091 --- /dev/null +++ b/allegro/src/macosx/keybd.m @@ -0,0 +1,357 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * MacOS X keyboard module. + * + * By Angelo Mottola. + * + * Based on Unix/X11 version by Michael Bukin. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/platform/aintosx.h" + +#ifndef ALLEGRO_MACOSX +#error Something is wrong with the makefile +#endif + + + +/* Dictionary to translate OS X modifier codes to Allegro modifier codes + * and key codes. + */ +static unsigned const int mod_info[5][3] = { + { NSAlphaShiftKeyMask, ALLEGRO_KEYMOD_CAPSLOCK, ALLEGRO_KEY_CAPSLOCK }, + { NSShiftKeyMask, ALLEGRO_KEYMOD_SHIFT, ALLEGRO_KEY_LSHIFT }, + { NSControlKeyMask, ALLEGRO_KEYMOD_CTRL, ALLEGRO_KEY_LCTRL }, + { NSAlternateKeyMask, ALLEGRO_KEYMOD_ALT, ALLEGRO_KEY_ALT }, + { NSCommandKeyMask, ALLEGRO_KEYMOD_COMMAND, ALLEGRO_KEY_COMMAND } +}; + + + +static bool osx_keyboard_init(void); +static void osx_keyboard_exit(void); +static ALLEGRO_KEYBOARD* osx_get_keyboard(void); +static ALLEGRO_KEYBOARD keyboard; +static ALLEGRO_KEYBOARD_STATE kbdstate; + + + +/* translate_modifier_flags: + * Translate a bitmask of OS X modifier flags to Allegro's modifier flags + */ +static int translate_modifier_flags(int osx_mods) +{ + int allegro_mods = 0; + int i; + + for (i = 0; i < 5; i++) { + if (osx_mods & mod_info[i][0]) + allegro_mods |= mod_info[i][1]; + } + + return allegro_mods; +} + + + +/* _al_osx_switch_keyboard_focus: + * Handle a focus switch event. + */ +void _al_osx_switch_keyboard_focus(ALLEGRO_DISPLAY *dpy, bool switch_in) +{ + _al_event_source_lock(&keyboard.es); + + if (switch_in) + kbdstate.display = dpy; + else + kbdstate.display = NULL; + + _al_event_source_unlock(&keyboard.es); +} + + + +static void _handle_key_press(ALLEGRO_DISPLAY* dpy, int unicode, int scancode, + int modifiers, bool is_repeat) +{ + _al_event_source_lock(&keyboard.es); + { + /* Generate the press event if necessary. */ + if (_al_event_source_needs_to_generate_event(&keyboard.es)) { + ALLEGRO_EVENT event; + event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = dpy; + event.keyboard.keycode = scancode; + event.keyboard.unichar = 0; + event.keyboard.modifiers = modifiers; + event.keyboard.repeat = false; + if (!is_repeat) { + _al_event_source_emit_event(&keyboard.es, &event); + } + if (unicode > 0) { + /* Apple maps function, arrow, and other keys to Unicode points. */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/CORPCHAR.TXT */ + if (unicode >= 0xF700 && unicode <= 0xF747) { + unicode = 0; + } + event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; + event.keyboard.unichar = unicode; + event.keyboard.modifiers = modifiers; + event.keyboard.repeat = is_repeat; + _al_event_source_emit_event(&keyboard.es, &event); + } + } + } + /* Maintain the kbdstate array. */ + _AL_KEYBOARD_STATE_SET_KEY_DOWN(kbdstate, scancode); + _al_event_source_unlock(&keyboard.es); +} + + + +static void _handle_key_release(ALLEGRO_DISPLAY* dpy, int modifiers, int scancode) +{ + _al_event_source_lock(&keyboard.es); + { + /* Generate the release event if necessary. */ + if (_al_event_source_needs_to_generate_event(&keyboard.es)) { + ALLEGRO_EVENT event; + event.keyboard.type = ALLEGRO_EVENT_KEY_UP; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = dpy; + event.keyboard.keycode = scancode; + event.keyboard.unichar = 0; + event.keyboard.modifiers = modifiers; + _al_event_source_emit_event(&keyboard.es, &event); + } + } + /* Maintain the kbdstate array. */ + _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(kbdstate, scancode); + _al_event_source_unlock(&keyboard.es); +} + + + +/* Mac keycode to Allegro scancode conversion table */ +static const int mac_to_scancode[128] = +{ + /* 0x00 */ ALLEGRO_KEY_A, ALLEGRO_KEY_S, ALLEGRO_KEY_D, ALLEGRO_KEY_F, + /* 0x04 */ ALLEGRO_KEY_H, ALLEGRO_KEY_G, ALLEGRO_KEY_Z, ALLEGRO_KEY_X, + /* 0x08 */ ALLEGRO_KEY_C, ALLEGRO_KEY_V, 0, ALLEGRO_KEY_B, + /* 0x0c */ ALLEGRO_KEY_Q, ALLEGRO_KEY_W, ALLEGRO_KEY_E, ALLEGRO_KEY_R, + /* 0x10 */ ALLEGRO_KEY_Y, ALLEGRO_KEY_T, ALLEGRO_KEY_1, ALLEGRO_KEY_2, + /* 0x14 */ ALLEGRO_KEY_3, ALLEGRO_KEY_4, ALLEGRO_KEY_6, ALLEGRO_KEY_5, + /* 0x18 */ ALLEGRO_KEY_EQUALS, ALLEGRO_KEY_9, ALLEGRO_KEY_7, ALLEGRO_KEY_MINUS, + /* 0x1c */ ALLEGRO_KEY_8, ALLEGRO_KEY_0, ALLEGRO_KEY_CLOSEBRACE, ALLEGRO_KEY_O, + /* 0x20 */ ALLEGRO_KEY_U, ALLEGRO_KEY_OPENBRACE, ALLEGRO_KEY_I, ALLEGRO_KEY_P, + /* 0x24 */ ALLEGRO_KEY_ENTER, ALLEGRO_KEY_L, ALLEGRO_KEY_J, ALLEGRO_KEY_QUOTE, + /* 0x28 */ ALLEGRO_KEY_K, ALLEGRO_KEY_SEMICOLON, ALLEGRO_KEY_BACKSLASH, ALLEGRO_KEY_COMMA, + /* 0x2c */ ALLEGRO_KEY_SLASH, ALLEGRO_KEY_N, ALLEGRO_KEY_M, ALLEGRO_KEY_FULLSTOP, + /* 0x30 */ ALLEGRO_KEY_TAB, ALLEGRO_KEY_SPACE, ALLEGRO_KEY_BACKQUOTE, ALLEGRO_KEY_BACKSPACE, + /* 0x34 */ ALLEGRO_KEY_ENTER, ALLEGRO_KEY_ESCAPE, 0, ALLEGRO_KEY_COMMAND, + /* 0x38 */ ALLEGRO_KEY_LSHIFT, ALLEGRO_KEY_CAPSLOCK, ALLEGRO_KEY_ALT, ALLEGRO_KEY_LEFT, + /* 0x3c */ ALLEGRO_KEY_RIGHT, ALLEGRO_KEY_DOWN, ALLEGRO_KEY_UP, 0, + /* 0x40 */ 0, ALLEGRO_KEY_FULLSTOP, 0, ALLEGRO_KEY_PAD_ASTERISK, + /* 0x44 */ 0, ALLEGRO_KEY_PAD_PLUS, 0, ALLEGRO_KEY_NUMLOCK, + /* 0x48 */ 0, 0, 0, ALLEGRO_KEY_PAD_SLASH, + /* 0x4c */ ALLEGRO_KEY_PAD_ENTER,0, ALLEGRO_KEY_PAD_MINUS, 0, + /* 0x50 */ 0, ALLEGRO_KEY_PAD_EQUALS, ALLEGRO_KEY_PAD_0, ALLEGRO_KEY_PAD_1, + /* 0x54 */ ALLEGRO_KEY_PAD_2, ALLEGRO_KEY_PAD_3, ALLEGRO_KEY_PAD_4, ALLEGRO_KEY_PAD_5, + /* 0x58 */ ALLEGRO_KEY_PAD_6, ALLEGRO_KEY_PAD_7, 0, ALLEGRO_KEY_PAD_8, + /* 0x5c */ ALLEGRO_KEY_PAD_9, 0, 0, 0, + /* 0x60 */ ALLEGRO_KEY_F5, ALLEGRO_KEY_F6, ALLEGRO_KEY_F7, ALLEGRO_KEY_F3, + /* 0x64 */ ALLEGRO_KEY_F8, ALLEGRO_KEY_F9, 0, ALLEGRO_KEY_F11, + /* 0x68 */ 0, ALLEGRO_KEY_PRINTSCREEN,0, ALLEGRO_KEY_SCROLLLOCK, + /* 0x6c */ 0, ALLEGRO_KEY_F10, 0, ALLEGRO_KEY_F12, + /* 0x70 */ 0, ALLEGRO_KEY_PAUSE, ALLEGRO_KEY_INSERT, ALLEGRO_KEY_HOME, + /* 0x74 */ ALLEGRO_KEY_PGUP, ALLEGRO_KEY_DELETE, ALLEGRO_KEY_F4, ALLEGRO_KEY_END, + /* 0x78 */ ALLEGRO_KEY_F2, ALLEGRO_KEY_PGDN, ALLEGRO_KEY_F1, ALLEGRO_KEY_LEFT, + /* 0x7c */ ALLEGRO_KEY_RIGHT, ALLEGRO_KEY_DOWN, ALLEGRO_KEY_UP, 0 +}; + + + +/* get_state: + * Copy a snapshot of the keyboard state into the user's structure + */ +static void get_state(ALLEGRO_KEYBOARD_STATE *ret_state) +{ + _al_event_source_lock(&keyboard.es); + { + memcpy(ret_state, &kbdstate, sizeof(ALLEGRO_KEYBOARD_STATE)); + } + _al_event_source_unlock(&keyboard.es); +} + + + +/* clear_state: + * Clear the keyboard state + */ +static void clear_state(void) +{ + _al_event_source_lock(&keyboard.es); + { + memset(&kbdstate, 0, sizeof(kbdstate)); + } + _al_event_source_unlock(&keyboard.es); +} + + + +static ALLEGRO_KEYBOARD_DRIVER keyboard_macosx = +{ + KEYBOARD_MACOSX, + "", + "", + "MacOS X keyboard", + osx_keyboard_init, + osx_keyboard_exit, + osx_get_keyboard, + NULL, // ALLEGRO_METHOD(bool, set_leds, (int leds)); + NULL, // ALLEGRO_METHOD(const char *, keycode_to_name, (int keycode)); + get_state, + clear_state, +}; + + + +_AL_DRIVER_INFO _al_keyboard_driver_list[] = +{ + { KEYBOARD_MACOSX, &keyboard_macosx, 1 }, + { 0, NULL, 0 } +}; + + + +/* _al_osx_get_keyboard_driver: + * Returns the keyboard driver. + */ +ALLEGRO_KEYBOARD_DRIVER* _al_osx_get_keyboard_driver(void) +{ + return &keyboard_macosx; +} + + + +/* _al_osx_keyboard_handler: + * Keyboard "interrupt" handler. + */ +void _al_osx_keyboard_handler(int pressed, NSEvent *event, ALLEGRO_DISPLAY* dpy) +{ + /* We need to distinguish between the raw character code (needed for + * ctrl and alt) and the "shifted" character code when neither of these + * is held down. This is needed to get the correct behavior when caps + * lock is on (ie, letters are upper case) + */ + int scancode = mac_to_scancode[[event keyCode]]; + + /* Translate OS X modifier flags to Allegro modifier flags */ + int key_shifts = translate_modifier_flags([event modifierFlags]); + + if (pressed) { + NSString* raw_characters = [event charactersIgnoringModifiers]; + NSString* upper_characters = [event characters]; + const unichar raw_character = ([raw_characters length] > 0) ? [raw_characters characterAtIndex: 0] : 0; + const unichar upper_character =([upper_characters length] > 0) ? [upper_characters characterAtIndex: 0] : 0; + bool is_repeat = pressed ? ([event isARepeat] == YES) : false; + /* Special processing to send character 1 for CTRL-A, 2 for CTRL-B etc. */ + if ((key_shifts & ALLEGRO_KEYMOD_CTRL) && (isalpha(raw_character))) + _handle_key_press(dpy, tolower(raw_character) - 'a' + 1, scancode, key_shifts, is_repeat); + else + _handle_key_press(dpy, upper_character, scancode, key_shifts, is_repeat); + } + else { + _handle_key_release(dpy, key_shifts, scancode); + } +} + + + +/* _al_osx_keyboard_modifier: + * Handles keyboard modifiers changes. + */ +void _al_osx_keyboard_modifiers(unsigned int modifiers, ALLEGRO_DISPLAY* dpy) +{ + static unsigned int old_modifiers = 0; + int i, changed; + int key_shifts; + + /* Translate OS X modifier flags to Allegro modifier flags */ + key_shifts = translate_modifier_flags(modifiers); + + for (i = 0; i < 5; i++) { + changed = (modifiers ^ old_modifiers) & mod_info[i][0]; + if (changed) { + if (modifiers & mod_info[i][0]) { + _handle_key_press(dpy, -1, mod_info[i][2], key_shifts, false); + if (i == 0) { + /* Caps lock requires special handling */ + _handle_key_release(dpy, key_shifts, mod_info[0][2]); + } + } + else { + if (i == 0) { + _handle_key_press(dpy, -1, mod_info[0][2], key_shifts, false); + } + + _handle_key_release(dpy, key_shifts, mod_info[i][2]); + } + } + } + old_modifiers = modifiers; +} + + + +/* osx_keyboard_init: + * Installs the keyboard handler. + */ +static bool osx_keyboard_init(void) +{ + memset(&keyboard, 0, sizeof keyboard); + _al_osx_keyboard_was_installed(YES); + _al_event_source_init(&keyboard.es); + return true; +} + + + +/* osx_keyboard_exit: + * Removes the keyboard handler. + */ +static void osx_keyboard_exit(void) +{ + _al_event_source_free(&keyboard.es); + _al_osx_keyboard_was_installed(NO); +} + + + +/* osx_get_keyboard: + * Returns the keyboard object. + */ +static ALLEGRO_KEYBOARD* osx_get_keyboard(void) +{ + return &keyboard; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/macosx/osx_app_delegate.m b/allegro/src/macosx/osx_app_delegate.m new file mode 100644 index 00000000..d99e11ad --- /dev/null +++ b/allegro/src/macosx/osx_app_delegate.m @@ -0,0 +1,343 @@ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/platform/aintosx.h" + +#ifdef __LP64__ +/* FIXME: the following prototype and enum definition appear to needed in + * 64 bit mode on 10.5 (Leopard). Apple's documentation indicates that + * "deprecated features" are not available in 64 bit, but + * UpdateSystemActivity is not deprecated and the documentation likewise + * suggests that all that should be required is to #include CoreServices.h + * or Power.h. However, this does not appear to work... for now, this + * should work ok. + * On 10.6 (Snow Leopard) these defines cause a problem, so they are + * disabled. + */ +extern OSErr UpdateSystemActivity(uint8_t activity); + +#if 0 +enum { + OverallAct = 0, /* Delays idle sleep by small amount */ + UsrActivity = 1, /* Delays idle sleep and dimming by timeout time */ + NetActivity = 2, /* Delays idle sleep and power cycling by small amount */ + HDActivity = 3, /* Delays hard drive spindown and idle sleep by small amount */ + IdleActivity = 4 /* Delays idle sleep by timeout time */ +}; +#endif + +#endif + +extern NSBundle *_al_osx_bundle; + +/* For compatibility with the unix code */ +static int __crt0_argc; +static char **__crt0_argv; +static int (*user_main)(int, char **); + +static char *arg0, *arg1 = NULL; + +static BOOL in_bundle(void) +{ + /* This comes from the ADC tips & tricks section: how to detect if the app + * lives inside a bundle + */ + FSRef processRef; + ProcessSerialNumber psn = { 0, kCurrentProcess }; + FSCatalogInfo processInfo; + GetProcessBundleLocation(&psn, &processRef); + FSGetCatalogInfo(&processRef, kFSCatInfoNodeFlags, &processInfo, NULL, NULL, NULL); + if (processInfo.nodeFlags & kFSNodeIsDirectoryMask) + return YES; + else + return NO; +} + + +@interface AllegroAppDelegate : NSObject +{ + NSTimer* activity; +} +- (void) dealloc; +- (BOOL)application: (NSApplication *)theApplication openFile: (NSString *)filename; +- (void)applicationDidFinishLaunching: (NSNotification *)aNotification; +- (void)applicationDidChangeScreenParameters: (NSNotification *)aNotification; ++ (void)app_main: (id)arg; +- (NSApplicationTerminateReply) applicationShouldTerminate: (id)sender; +- (void) updateSystemActivity:(NSTimer*) timer; +- (void) setInhibitScreenSaver: (NSNumber*) inhibit; +@end + +@interface AllegroWindowDelegate : NSObject +- (BOOL)windowShouldClose: (id)sender; +- (void)windowDidDeminiaturize: (NSNotification *)aNotification; +@end + +@implementation AllegroAppDelegate + +/* setInhibitScreenSaver: + * If inhibit is YES, set up an infrequent timer to call + * updateSystemActivity: to prevent the screen saver from activating + * Must be called from the main thread (osx_inhibit_screensaver ensures + * this) + * Has no effect if inhibit is YES and the timer is already active + * or if inhibit is NO and the timer is not active + */ +-(void) setInhibitScreenSaver: (NSNumber *) inhibit +{ + if ([inhibit boolValue] == YES) { + if (activity == nil) { + // Schedule every 30 seconds + activity = [NSTimer scheduledTimerWithTimeInterval:30.0 + target:self + selector:@selector(updateSystemActivity:) + userInfo:nil + repeats:YES]; + [activity retain]; + } + // else already active + } + else { + // OK to send message to nil if timer wasn't set. + [activity invalidate]; + [activity release]; + activity = nil; + } +} +/* updateSystemActivity: + * called by a timer to inform the system that there is still activity and + * therefore do not dim the screen/start the screensaver + */ +-(void) updateSystemActivity: (NSTimer*) timer +{ + (void)timer; + UpdateSystemActivity(UsrActivity); +} + +-(void) dealloc +{ + [activity invalidate]; + [activity release]; + [super dealloc]; +} +- (BOOL)application: (NSApplication *)theApplication openFile: (NSString *)filename +{ + NSData* data = [filename dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + (void)theApplication; + if (data != nil) { + unsigned int len = 1 + [data length]; + arg1 = al_malloc(len); + memset(arg1, 0, len); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1100 + [data getBytes: arg1 length:len]; +#else + [data getBytes: arg1]; +#endif + return YES; + } + else { + return NO; + } +} + + + +/* applicationDidFinishLaunching: + * Called when the app is ready to run. + */ +- (void)applicationDidFinishLaunching: (NSNotification *)aNotification +{ + NSString* exename, *resdir; + NSFileManager* fm; + BOOL isDir; + + (void)aNotification; + + if (in_bundle() == YES) + { + /* In a bundle, so chdir to the containing directory, + * or to the 'magic' resource directory if it exists. + * (see the readme.osx file for more info) + */ + _al_osx_bundle = [NSBundle mainBundle]; + exename = [[_al_osx_bundle executablePath] lastPathComponent]; + resdir = [[_al_osx_bundle resourcePath] stringByAppendingPathComponent: exename]; + fm = [NSFileManager defaultManager]; + if ([fm fileExistsAtPath: resdir isDirectory: &isDir] && isDir) { + /* Yes, it exists inside the bundle */ + [fm changeCurrentDirectoryPath: resdir]; + } + else { + /* No, change to the 'standard' OSX resource directory if it exists*/ + if ([fm fileExistsAtPath: [_al_osx_bundle resourcePath] isDirectory: &isDir] && isDir) + { + [fm changeCurrentDirectoryPath: [_al_osx_bundle resourcePath]]; + } + /* It doesn't exist - this is unusual for a bundle. Don't chdir */ + } + arg0 = strdup([[_al_osx_bundle bundlePath] fileSystemRepresentation]); + if (arg1) { + static char *args[2]; + args[0] = arg0; + args[1] = arg1; + __crt0_argv = args; + __crt0_argc = 2; + } + else { + __crt0_argv = &arg0; + __crt0_argc = 1; + } + } + /* else: not in a bundle so don't chdir */ + + [NSThread detachNewThreadSelector: @selector(app_main:) + toTarget: [AllegroAppDelegate class] + withObject: nil]; + return; +} + + + +/* applicationDidChangeScreenParameters: + * Invoked when the screen did change resolution/color depth. + */ +- (void)applicationDidChangeScreenParameters: (NSNotification *)aNotification +{ + /* no-op */ + (void)aNotification; +} + + + +/* Call the user main() */ +static void call_user_main(void) +{ + exit(user_main(__crt0_argc, __crt0_argv)); +} + + + +/* app_main: + * Thread dedicated to the user program; real main() gets called here. + */ ++ (void)app_main: (id)arg +{ + (void)arg; + call_user_main(); +} + + + +/* applicationShouldTerminate: + * Called upon Command-Q or "Quit" menu item selection. + * Post a message but do not quit directly + */ +- (NSApplicationTerminateReply) applicationShouldTerminate: (id)sender +{ + (void)sender; + _al_osx_post_quit(); + return NSTerminateCancel; +} + +/* end of AllegroAppDelegate implementation */ +@end + + + +/* This prevents warnings that 'NSApplication might not + * respond to setAppleMenu' on OS X 10.4+ + */ +@interface NSApplication(AllegroOSX) +- (void)setAppleMenu:(NSMenu *)menu; +@end + +/* Helper macro to add entries to the menu */ +#define add_menu(name, sel, eq) \ + [menu addItem: [[[NSMenuItem alloc] \ + initWithTitle: name \ + action: @selector(sel) \ + keyEquivalent: eq] autorelease]] \ + +int _al_osx_run_main(int argc, char **argv, + int (*real_main)(int, char **)) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + AllegroAppDelegate *app_delegate = [[AllegroAppDelegate alloc] init]; + NSMenu *menu; + NSMenuItem *temp_item; + + user_main = real_main; + __crt0_argc = argc; + __crt0_argv = argv; + +#ifdef OSX_BOOTSTRAP_DETECTION + if (!_al_osx_bootstrap_ok()) /* not safe to use NSApplication */ + call_user_main(); +#endif + + [NSApplication sharedApplication]; + + /* Load the main menu nib if possible */ + if ((!in_bundle()) || ([NSBundle loadNibNamed: @"MainMenu" + owner: NSApp] == NO)) + { + /* Didn't load the nib; create a default menu programmatically */ + NSString* title = nil; + NSDictionary* app_dictionary = [[NSBundle mainBundle] infoDictionary]; + if (app_dictionary) + { + title = [app_dictionary objectForKey: @"CFBundleName"]; + } + if (title == nil) + { + title = [[NSProcessInfo processInfo] processName]; + } + NSMenu* main_menu = [[NSMenu alloc] initWithTitle: @""]; + [NSApp setMainMenu: main_menu]; + + /* Add application ("Apple") menu */ + menu = [[NSMenu alloc] initWithTitle: @"Apple menu"]; + temp_item = [[NSMenuItem alloc] + initWithTitle: @"" + action: NULL + keyEquivalent: @""]; + [main_menu addItem: temp_item]; + [main_menu setSubmenu: menu forItem: temp_item]; + [temp_item release]; + add_menu([@"Hide " stringByAppendingString: title], hide:, @"h"); + add_menu(@"Hide Others", hideOtherApplications:, @""); + add_menu(@"Show All", unhideAllApplications:, @""); + [menu addItem: [NSMenuItem separatorItem]]; + add_menu([@"Quit " stringByAppendingString: title], terminate:, @"q"); + [NSApp setAppleMenu: menu]; + [menu release]; + + /* Add "Window" menu */ + menu = [[NSMenu alloc] + initWithTitle: @"Window"]; + temp_item = [[NSMenuItem alloc] + initWithTitle: @"" + action: NULL + keyEquivalent: @""]; + [main_menu addItem: temp_item]; + [main_menu setSubmenu: menu forItem: temp_item]; + [temp_item release]; + /* Add menu entries */ + add_menu(@"Minimize", performMiniaturize:, @"M"); + add_menu(@"Bring All to Front", arrangeInFront:, @""); + [NSApp setWindowsMenu:menu]; + [menu release]; + + [main_menu release]; + } + // setDelegate: doesn't retain the delegate here (a Cocoa convention) + // therefore we don't release it. + [NSApp setDelegate: app_delegate]; + [pool drain]; + [NSApp run]; + /* Can never get here */ + [app_delegate release]; + return 0; +} diff --git a/allegro/src/macosx/osxclipboard.m b/allegro/src/macosx/osxclipboard.m new file mode 100644 index 00000000..9eae91b9 --- /dev/null +++ b/allegro/src/macosx/osxclipboard.m @@ -0,0 +1,146 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * MacOS X clipboard handling. + * + * By Beoran. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/internal/aintern_osxclipboard.h" +#include "allegro5/platform/aintosx.h" +#include "./osxgl.h" + +#ifndef ALLEGRO_MACOSX +#error Something is wrong with the makefile +#endif + +/* Ensure that we have the right version number available. */ +#ifndef NSAppKitVersionNumber10_6 +#define NSAppKitVersionNumber10_6 1038 +#endif + +static NSString *osx_get_text_format(ALLEGRO_DISPLAY *display) +{ + (void) display; + +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + return NSStringPboardType; +#else + /* This is now the preferred way of version checking, + Gestalt has been deprecated. + */ + if ( floor(NSAppKitVersionNumber) < NSAppKitVersionNumber10_6 ) { + return NSPasteboardTypeString; + } + else { + return NSStringPboardType; + } +#endif +} + +static bool osx_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text) +{ + NSAutoreleasePool *pool; + NSPasteboard *pasteboard; + NSString *format = osx_get_text_format(display); + BOOL ok; + + pool = [[NSAutoreleasePool alloc] init]; + if (!pool) return false; + + pasteboard = [NSPasteboard generalPasteboard]; + if (!pasteboard) return false; + /* First clear the clipboard, otherwise the setString will fail. */ + [pasteboard clearContents]; + ok = [pasteboard setString:[NSString stringWithUTF8String:text] forType:format]; + + [pool release]; + + return ok == YES; +} + +static char * osx_get_clipboard_text(ALLEGRO_DISPLAY *display) +{ + NSAutoreleasePool *pool; + NSPasteboard *pasteboard; + NSString *format = osx_get_text_format(display); + NSString *available; + char *text; + + pool = [[NSAutoreleasePool alloc] init]; + + pasteboard = [NSPasteboard generalPasteboard]; + available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:format]]; + if ([available isEqualToString:format]) { + NSString* string; + const char *utf8; + + string = [pasteboard stringForType:format]; + if (string == nil) { + text = NULL; + } else { + size_t size; + utf8 = [string UTF8String]; + size = strlen(utf8); + text = al_malloc(size+1); + text = _al_sane_strncpy(text, utf8, size+1); + } + } else { + text = NULL; + } + + [pool release]; + + return text; +} + +static bool osx_has_clipboard_text(ALLEGRO_DISPLAY *display) +{ + NSAutoreleasePool *pool; + NSPasteboard *pasteboard; + NSString *format = osx_get_text_format(display); + NSString *available; + bool result = false; + + pool = [[NSAutoreleasePool alloc] init]; + + pasteboard = [NSPasteboard generalPasteboard]; + available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:format]]; + + if ([available isEqualToString:format]) { + NSString* string; + string = [pasteboard stringForType:format]; + if (string != nil) { + result = true; + } + } + + [pool release]; + + return result; +} + +void _al_osx_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt) +{ + vt->set_clipboard_text = osx_set_clipboard_text; + vt->get_clipboard_text = osx_get_clipboard_text; + vt->has_clipboard_text = osx_has_clipboard_text; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/macosx/osxgl.h b/allegro/src/macosx/osxgl.h new file mode 100644 index 00000000..2f31a632 --- /dev/null +++ b/allegro/src/macosx/osxgl.h @@ -0,0 +1,49 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintosx.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_opengl.h" + +#include "allegro5/opengl/gl_ext.h" + + +/* Number of pixel format attributes we can set */ +#define AL_OSX_NUM_PFA 64 + +@interface ALWindow : NSWindow { + ALLEGRO_DISPLAY* display; +} + +@property ALLEGRO_DISPLAY *display; + +@end + +/* This is our version of ALLEGRO_DISPLAY with driver specific extra data. */ +typedef struct ALLEGRO_DISPLAY_OSX_WIN { + ALLEGRO_DISPLAY parent; + int depth; + NSOpenGLContext* ctx; + NSOpenGLPixelFormatAttribute attributes[AL_OSX_NUM_PFA]; + ALWindow* win; + NSCursor* cursor; + CGDirectDisplayID display_id; + BOOL show_cursor; + NSTrackingArea *tracking; + unsigned int display_group; + BOOL in_fullscreen; + BOOL single_buffer; + CGDisplayModeRef original_mode; + /* For new (10.14+) vsyncing. */ + CVDisplayLinkRef display_link; + ALLEGRO_MUTEX *flip_mutex; + ALLEGRO_COND *flip_cond; + int num_flips; +} ALLEGRO_DISPLAY_OSX_WIN; + +/* This is our version of ALLEGRO_MOUSE_CURSOR */ +typedef struct ALLEGRO_MOUSE_CURSOR_OSX +{ + NSCursor *cursor; +} ALLEGRO_MOUSE_CURSOR_OSX; + diff --git a/allegro/src/macosx/osxgl.m b/allegro/src/macosx/osxgl.m new file mode 100644 index 00000000..93f178be --- /dev/null +++ b/allegro/src/macosx/osxgl.m @@ -0,0 +1,2521 @@ +/* ______ ___ ___ +* /\ _ \ /\_ \ /\_ \ +* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ +* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ +* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ +* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ +* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ +* /\____/ +* \_/__/ +* +* MacOS X OpenGL gfx driver +* +* By Peter Hull. +* +* See readme.txt for copyright information. +*/ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_osxclipboard.h" +#include "allegro5/platform/aintosx.h" +#include "./osxgl.h" +#include "allegro5/allegro_osx.h" +#ifndef ALLEGRO_MACOSX +#error something is wrong with the makefile +#endif + +#import +#import + +ALLEGRO_DEBUG_CHANNEL("MacOSX") + +/* Many Cocoa methods can only be called from the main thread, but Allegro runs the + user's code on a separate thread or threads. It relies on `dispatch_sync` or + `[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]` to make sure the + operation happens on the main thread. Comments on functions in this file indicate their + thread requirements, if any. + #define EXTRA_THREAD_CHECKS to catch any issues during development (don't leave it defined though.) */ +#undef EXTRA_THREAD_CHECKS +#ifdef EXTRA_THREAD_CHECKS +#define ASSERT_MAIN_THREAD() NSCAssert([NSThread isMainThread], @"Must be run on main thread") +#define ASSERT_USER_THREAD() NSCAssert(![NSThread isMainThread], @"Must be run on user thread") +#else +#define ASSERT_MAIN_THREAD() +#define ASSERT_USER_THREAD() +#endif + +/* This constant isn't available on OS X < 10.7, define + * it here so the library can be built on < 10.7 (10.6 + * tested so far.) + */ +#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1070 && !defined(NSWindowCollectionBehaviorFullScreenPrimary)) +enum { + NSWindowCollectionBehaviorFullScreenPrimary = (1 << 7) +}; +#endif + +/* Defines */ +#define MINIMUM_WIDTH 48 +#define MINIMUM_HEIGHT 48 + +/* Unsigned integer; data type only avaliable for OS X >= 10.5 */ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +typedef unsigned int NSUInteger; +#endif + +/* Module Variables */ +static BOOL _osx_mouse_installed = NO, _osx_keyboard_installed = NO; +static NSPoint last_window_pos; +static unsigned int next_display_group = 1; + +/* The parameters are passed to initialiseDisplay manually, as it runs + * in a separate thread which renders TLS values incorrect. + */ +typedef struct OSX_DISPLAY_PARAMS { + ALLEGRO_DISPLAY_OSX_WIN* dpy; + int new_window_pos_x; + int new_window_pos_y; + int new_display_adapter; + /* A copy of the new window title. */ + char* new_window_title; +} _OSX_DISPLAY_PARAMS; + +/* Dictionary to map Allegro's DISPLAY_OPTIONS to OS X + * PixelFormatAttributes. + * The first column is Allegro's name, the second column is the OS X + * PixelFormatAttribute (or 0), the third column indicates whether we + * need an extra parameter or not (eg, colour depth). + */ +static const unsigned int allegro_to_osx_settings[][3] = { + { ALLEGRO_RED_SIZE, 0, 0}, // Not supported per component + { ALLEGRO_GREEN_SIZE, 0, 0}, // Not supported per component + { ALLEGRO_BLUE_SIZE, 0, 0}, // Not supported per component + { ALLEGRO_ALPHA_SIZE, NSOpenGLPFAAlphaSize, 1}, + { ALLEGRO_RED_SHIFT, 0, 0}, // Not available + { ALLEGRO_GREEN_SHIFT, 0, 0}, // Not available + { ALLEGRO_BLUE_SHIFT, 0, 0}, // Not available + { ALLEGRO_ALPHA_SHIFT, 0, 0}, // Not available + { ALLEGRO_ACC_RED_SIZE, NSOpenGLPFAAccumSize, 1}, // Correct? + { ALLEGRO_ACC_GREEN_SIZE, NSOpenGLPFAAccumSize, 1}, // Correct? + { ALLEGRO_ACC_BLUE_SIZE, NSOpenGLPFAAccumSize, 1}, // Correct? + { ALLEGRO_ACC_ALPHA_SIZE, NSOpenGLPFAAccumSize, 1}, // Correct? + { ALLEGRO_STEREO, NSOpenGLPFAStereo, 0}, + { ALLEGRO_AUX_BUFFERS, NSOpenGLPFAAuxBuffers, 1}, + { ALLEGRO_COLOR_SIZE, NSOpenGLPFAColorSize, 1}, + { ALLEGRO_DEPTH_SIZE, NSOpenGLPFADepthSize, 1}, + { ALLEGRO_STENCIL_SIZE, NSOpenGLPFAStencilSize, 1}, + { ALLEGRO_SAMPLE_BUFFERS, NSOpenGLPFASampleBuffers, 1}, + { ALLEGRO_SAMPLES, NSOpenGLPFASamples, 1}, + //{ ALLEGRO_RENDER_METHOD, NSOpenGLPFAAccelerated, 0}, handled separately + { ALLEGRO_FLOAT_COLOR, NSOpenGLPFAColorFloat, 0}, + { ALLEGRO_FLOAT_DEPTH, 0, 0}, + //{ ALLEGRO_SINGLE_BUFFER , 0, 0}, handled separately + { ALLEGRO_SWAP_METHOD, 0, 0}, + { ALLEGRO_COMPATIBLE_DISPLAY, 0, 0}, + { ALLEGRO_DISPLAY_OPTIONS_COUNT, 0, 0} +}; +static const int number_of_settings = + sizeof(allegro_to_osx_settings)/sizeof(*allegro_to_osx_settings); + +static const char *allegro_pixel_format_names[] = { + "ALLEGRO_RED_SIZE", + "ALLEGRO_GREEN_SIZE", + "ALLEGRO_BLUE_SIZE", + "ALLEGRO_ALPHA_SIZE", + "ALLEGRO_RED_SHIFT", + "ALLEGRO_GREEN_SHIFT", + "ALLEGRO_BLUE_SHIFT", + "ALLEGRO_ALPHA_SHIFT", + "ALLEGRO_ACC_RED_SIZE", + "ALLEGRO_ACC_GREEN_SIZE", + "ALLEGRO_ACC_BLUE_SIZE", + "ALLEGRO_ACC_ALPHA_SIZE", + "ALLEGRO_STEREO", + "ALLEGRO_AUX_BUFFERS", + "ALLEGRO_COLOR_SIZE", + "ALLEGRO_DEPTH_SIZE", + "ALLEGRO_STENCIL_SIZE", + "ALLEGRO_SAMPLE_BUFFERS", + "ALLEGRO_SAMPLES", + "ALLEGRO_RENDER_METHOD", + "ALLEGRO_FLOAT_COLOR", + "ALLEGRO_FLOAT_DEPTH", + "ALLEGRO_SINGLE_BUFFER", + "ALLEGRO_SWAP_METHOD", + "ALLEGRO_COMPATIBLE_DISPLAY", + "ALLEGRO_DISPLAY_OPTIONS_COUNT" +}; + +/* Module functions */ +ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver(void); +ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_win(void); +ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_fs(void); +static NSOpenGLContext* osx_create_shareable_context(NSOpenGLPixelFormat* fmt, unsigned int* group); +static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff); +static bool resize_display_win(ALLEGRO_DISPLAY *d, int w, int h); +static bool resize_display_win_main_thread(ALLEGRO_DISPLAY *d, int w, int h); + +static void clear_to_black(NSOpenGLContext *context) +{ + /* Clear and flush (for double buffering) */ + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + [context flushBuffer]; + glClear(GL_COLOR_BUFFER_BIT); +} + +static NSTrackingArea *create_tracking_area(NSView *view) +{ + NSTrackingAreaOptions options = + NSTrackingMouseEnteredAndExited | + NSTrackingMouseMoved | + NSTrackingCursorUpdate | + NSTrackingActiveAlways; + return [[NSTrackingArea alloc] initWithRect:[view bounds] options:options owner:view userInfo:nil]; +} + +/* _al_osx_change_cursor: + * Actually change the current cursor. This can be called fom any thread + * but ensures that the change is only called from the main thread. + */ +static void _al_osx_change_cursor(ALLEGRO_DISPLAY_OSX_WIN *dpy, NSCursor* cursor) +{ + NSCursor* old = dpy->cursor; + dpy->cursor = [cursor retain]; + [old release]; + if (dpy->show_cursor) + [cursor performSelectorOnMainThread: @selector(set) withObject: nil waitUntilDone: NO]; +} + +/* _al_osx_keyboard_was_installed: + * Called by the keyboard driver when the driver is installed or uninstalled. + * Set the variable so we can decide to pass events or not. + */ +void _al_osx_keyboard_was_installed(BOOL install) { + _osx_keyboard_installed = install; +} + +/* The main additions to this view are event-handling functions */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 +@interface ALOpenGLView : NSOpenGLView +#else +@interface ALOpenGLView : NSOpenGLView +#endif +{ + /* This is passed onto the event functions so we know where the event came from */ + ALLEGRO_DISPLAY* dpy_ptr; +} +-(void)setAllegroDisplay: (ALLEGRO_DISPLAY*) ptr; +-(ALLEGRO_DISPLAY*) allegroDisplay; +-(void) reshape; +-(BOOL) acceptsFirstResponder; +-(void) keyDown:(NSEvent*) event; +-(void) keyUp:(NSEvent*) event; +-(void) flagsChanged:(NSEvent*) event; +-(void) mouseDown: (NSEvent*) evt; +-(void) mouseUp: (NSEvent*) evt; +-(void) mouseDragged: (NSEvent*) evt; +-(void) rightMouseDown: (NSEvent*) evt; +-(void) rightMouseUp: (NSEvent*) evt; +-(void) rightMouseDragged: (NSEvent*) evt; +-(void) otherMouseDown: (NSEvent*) evt; +-(void) otherMouseUp: (NSEvent*) evt; +-(void) otherMouseDragged: (NSEvent*) evt; +-(void) mouseMoved: (NSEvent*) evt; +-(void) scrollWheel: (NSEvent*) evt; +-(void) viewDidMoveToWindow; +-(void) viewWillMoveToWindow: (NSWindow*) newWindow; +-(void) mouseEntered: (NSEvent*) evt; +-(void) mouseExited: (NSEvent*) evt; +-(void) viewDidEndLiveResize; +/* Window delegate methods */ +-(void) windowDidBecomeMain:(NSNotification*) notification; +-(void) windowDidResignMain:(NSNotification*) notification; +-(void) windowDidResize:(NSNotification*) notification; +-(void) enterFullScreenWindowMode; +-(void) exitFullScreenWindowMode; +-(void) finishExitingFullScreenWindowMode; +-(void) maximize; +-(NSRect) windowWillUseStandardFrame: + (NSWindow *) window + defaultFrame: (NSRect) newFrame; +@end + +@implementation ALWindow +@synthesize display; + +-(BOOL) canBecomeKeyWindow +{ + return YES; +} +// main thread only +-(void) zoom:(id)sender +{ + self.display->flags ^= ALLEGRO_MAXIMIZED; + [super zoom:sender]; +} + +@end + +/* _al_osx_mouse_was_installed: + * Called by the mouse driver when the driver is installed or uninstalled. + * Set the variable so we can decide to pass events or not, and notify all + * existing displays that they need to set up their tracking areas. + * User thread only + */ +void _al_osx_mouse_was_installed(BOOL install) { + ASSERT_USER_THREAD(); + if (_osx_mouse_installed == install) { + // done it already + return; + } + _osx_mouse_installed = install; + _AL_VECTOR* dpys = &al_get_system_driver()->displays; + dispatch_sync(dispatch_get_main_queue(), ^{ + unsigned int i; + for (i = 0; i < _al_vector_size(dpys); ++i) { + ALLEGRO_DISPLAY_OSX_WIN* dpy = *(ALLEGRO_DISPLAY_OSX_WIN**) _al_vector_ref(dpys, i); + NSWindow* window = dpy->win; + if (window) { + [window setAcceptsMouseMovedEvents: _osx_mouse_installed]; + } + } + }); +} + +@implementation ALOpenGLView + +-(void) prepareOpenGL +{ + [super prepareOpenGL]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { + [self setWantsBestResolutionOpenGLSurface:YES]; + } +#endif +} + +/* setDisplay: +* Set the display this view is associated with +*/ +-(void) setAllegroDisplay: (ALLEGRO_DISPLAY*) ptr +{ + dpy_ptr = ptr; +} + +/* display +* return the display this view is associated with +*/ +-(ALLEGRO_DISPLAY*) allegroDisplay +{ + return dpy_ptr; +} + +/* reshape +* Called when the view changes size */ +- (void) reshape +{ + [super reshape]; + if ([NSOpenGLContext currentContext] != nil) { + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + + if (dpy->tracking) { + [self removeTrackingArea: dpy->tracking]; + dpy->tracking = create_tracking_area(self); + [self addTrackingArea: dpy->tracking]; + } + } +} + +/* acceptsFirstResponder +* Overridden to return YES, so that +* this view will receive events +*/ +-(BOOL) acceptsFirstResponder +{ + return YES; +} + +/* Keyboard event handler */ +-(void) keyDown:(NSEvent*) event +{ + if (_osx_keyboard_installed) + _al_osx_keyboard_handler(true, event, dpy_ptr); +} + +-(void) keyUp:(NSEvent*) event +{ + if (_osx_keyboard_installed) + _al_osx_keyboard_handler(false, event, dpy_ptr); +} + +-(void) flagsChanged:(NSEvent*) event +{ + if (_osx_keyboard_installed) { + _al_osx_keyboard_modifiers([event modifierFlags], dpy_ptr); + } +} + +/* Mouse handling + */ +-(void) mouseDown: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) mouseUp: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) mouseDragged: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) rightMouseDown: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) rightMouseUp: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) rightMouseDragged: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) otherMouseDown: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) otherMouseUp: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) otherMouseDragged: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) mouseMoved: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) scrollWheel: (NSEvent*) evt +{ + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +/* Cursor handling */ +- (void) viewDidMoveToWindow { + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + if (dpy->tracking) { + [self removeTrackingArea: dpy->tracking]; + } + dpy->tracking = create_tracking_area(self); + [self addTrackingArea: dpy->tracking]; +} + +- (void) viewWillMoveToWindow: (NSWindow*) newWindow { + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + (void)newWindow; + if (([self window] != nil) && (dpy->tracking != 0)) { + [self removeTrackingArea:dpy->tracking]; + dpy->tracking = 0; + } +} + +-(void) mouseEntered: (NSEvent*) evt +{ + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); + if (dpy->show_cursor) { + [dpy->cursor set]; + } + else { + [NSCursor hide]; + } + _al_event_source_lock(src); + _al_osx_switch_mouse_focus(dpy_ptr, true); + _al_event_source_unlock(src); + _al_osx_mouse_generate_event(evt, dpy_ptr); +} +-(void) mouseExited: (NSEvent*) evt +{ + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); + if (!dpy->show_cursor) { + [NSCursor unhide]; + } + _al_event_source_lock(src); + _al_osx_switch_mouse_focus(dpy_ptr, false); + _al_event_source_unlock(src); + _al_osx_mouse_generate_event(evt, dpy_ptr); +} + +/* windowShouldClose: + * Veto the close and post a message + */ +- (BOOL)windowShouldClose:(id)sender +{ + (void)sender; + ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); + _al_event_source_lock(src); + ALLEGRO_EVENT evt; + evt.type = ALLEGRO_EVENT_DISPLAY_CLOSE; + _al_event_source_emit_event(src, &evt); + _al_event_source_unlock(src); + return NO; +} + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1074 +-(void) viewDidChangeBackingProperties +{ + [super viewDidChangeBackingProperties]; + if (!(al_get_display_flags(dpy_ptr) & ALLEGRO_RESIZABLE) && + dpy_ptr->ogl_extras) { + resize_display_win_main_thread(dpy_ptr, al_get_display_width(dpy_ptr), al_get_display_height(dpy_ptr)); + } + else { + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + NSWindow *window = dpy->win; + NSRect rc = [window frame]; + NSRect content = [window contentRectForFrameRect: rc]; + content = [self convertRectToBacking: content]; + ALLEGRO_EVENT_SOURCE *es = &dpy->parent.es; + + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; + event.display.timestamp = al_get_time(); + event.display.width = NSWidth(content); + event.display.height = NSHeight(content); + _al_event_source_emit_event(es, &event); + ALLEGRO_INFO("Window finished resizing"); + } + _al_event_source_unlock(es); + } +} +#endif + +-(void) viewDidEndLiveResize +{ + [super viewDidEndLiveResize]; + + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + NSWindow *window = dpy->win; + NSRect rc = [window frame]; + NSRect content = [window contentRectForFrameRect: rc]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + content = [self convertRectToBacking: content]; +#endif + ALLEGRO_EVENT_SOURCE *es = &dpy->parent.es; + + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; + event.display.timestamp = al_get_time(); + event.display.width = NSWidth(content); + event.display.height = NSHeight(content); + _al_event_source_emit_event(es, &event); + ALLEGRO_INFO("Window finished resizing"); + } + _al_event_source_unlock(es); +} +/* Window switch in/out */ +-(void) windowDidBecomeMain:(NSNotification*) notification +{ + (void)notification; + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); + _al_event_source_lock(src); + ALLEGRO_EVENT evt; + evt.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; + _al_event_source_emit_event(src, &evt); + _al_osx_switch_keyboard_focus(dpy_ptr, true); + _al_event_source_unlock(src); + _al_osx_change_cursor(dpy, dpy->cursor); +} +-(void) windowDidResignMain:(NSNotification*) notification +{ + (void)notification; + ALLEGRO_EVENT_SOURCE* src = &([self allegroDisplay]->es); + _al_event_source_lock(src); + ALLEGRO_EVENT evt; + evt.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; + _al_event_source_emit_event(src, &evt); + _al_osx_switch_keyboard_focus(dpy_ptr, false); + _al_event_source_unlock(src); +} +-(void) windowDidResize:(NSNotification*) notification +{ + (void)notification; + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + NSWindow *window = dpy->win; + NSRect rc = [window frame]; + NSRect content = [window contentRectForFrameRect: rc]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + content = [self convertRectToBacking: content]; +#endif + ALLEGRO_EVENT_SOURCE *es = &dpy->parent.es; + + /* Restore max. constraints when the window has been un-maximized. + * Note: isZoomed will return false in FullScreen mode. + */ + if (dpy_ptr->use_constraints && + !(dpy_ptr->flags & ALLEGRO_FULLSCREEN_WINDOW) && ![window isZoomed]) + { + float scale_factor = 1.0; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + if ([window respondsToSelector:@selector(backingScaleFactor)]) { + scale_factor = [window backingScaleFactor]; + } +#endif + + NSSize max_size; + max_size.width = (dpy_ptr->max_w > 0) ? dpy_ptr->max_w / scale_factor : FLT_MAX; + max_size.height = (dpy_ptr->max_h > 0) ? dpy_ptr->max_h / scale_factor : FLT_MAX; + [window setContentMaxSize: max_size]; + } + + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; + event.display.timestamp = al_get_time(); + event.display.width = NSWidth(content); + event.display.height = NSHeight(content); + _al_event_source_emit_event(es, &event); + ALLEGRO_INFO("Window was resized\n"); + } + _al_event_source_unlock(es); +} + +-(void)windowWillEnterFullScreen:(NSNotification *)notification +{ + (void)notification; + ALLEGRO_DISPLAY *display = dpy_ptr; + display->flags |= ALLEGRO_FULLSCREEN_WINDOW; +} + +-(void)windowWillExitFullScreen:(NSNotification *)notification +{ + (void)notification; + ALLEGRO_DISPLAY *display = dpy_ptr; + display->flags &= ~ALLEGRO_FULLSCREEN_WINDOW; +} + +-(void) enterFullScreenWindowMode +{ +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + int flags = NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar; + [dict setObject:[NSNumber numberWithInt: flags] forKey:NSFullScreenModeApplicationPresentationOptions]; + /* HACK? For some reason, we need to disable the chrome. If we don't, the fullscreen window + will be created with space left over for it. Are we creating a fullscreen window in the wrong way? */ + [dpy->win setStyleMask: [dpy->win styleMask] & ~NSWindowStyleMaskTitled]; + [[dpy->win contentView] enterFullScreenMode: [dpy->win screen] withOptions: dict]; + [dict release]; +#endif +} + +/* Toggles maximize state. In OSX 10.10 this is the same as double clicking the title bar. */ +-(void) maximize +{ + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + [dpy->win performZoom: nil]; +} + +/* Called by NSWindow's zoom: method while determining the frame + * a window may be zoomed to. + * We use it to update max. constraints values when the window changes + * its maximized state. + */ +-(NSRect) windowWillUseStandardFrame: + (NSWindow *) window + defaultFrame: (NSRect) newFrame +{ + NSSize max_size; + + if (dpy_ptr->use_constraints) { + if (dpy_ptr->flags & ALLEGRO_MAXIMIZED) { + max_size.width = FLT_MAX; + max_size.height = FLT_MAX; + newFrame.size.width = max_size.width; + newFrame.size.height = max_size.height; + } + else { + float scale_factor = 1.0; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + if ([window respondsToSelector:@selector(backingScaleFactor)]) { + scale_factor = [window backingScaleFactor]; + } +#endif + max_size.width = (dpy_ptr->max_w > 0) ? dpy_ptr->max_w / scale_factor : FLT_MAX; + max_size.height = (dpy_ptr->max_h > 0) ? dpy_ptr->max_h / scale_factor : FLT_MAX; + } + + [window setContentMaxSize: max_size]; + } + + return newFrame; +} + +-(void) exitFullScreenWindowMode +{ + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + + /* Going from a fullscreen window to a smaller window, the mouse may end up outside + * the window when it was inside before (not possible the other way.) This causes a + * crash. To avoid it, remove the tracking area and add it back after exiting fullscreen. + * (my theory) + */ + [dpy->win orderOut:[dpy->win contentView]]; + [self exitFullScreenModeWithOptions: nil]; + /* Restore the title bar disabled in enterFullScreenWindowMode. */ + if (!(dpy_ptr->flags & ALLEGRO_FRAMELESS)) { + [dpy->win setStyleMask: [dpy->win styleMask] | NSWindowStyleMaskTitled]; + } +} + +-(void) finishExitingFullScreenWindowMode +{ + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; + + [dpy->win center]; + [dpy->win makeKeyAndOrderFront:[dpy->win contentView]]; + [[self window] makeFirstResponder: self]; +} + +/* End of ALOpenGLView implementation */ +@end + +/* set_current_display: +* Set the current windowed display to be current. +*/ +static bool set_current_display(ALLEGRO_DISPLAY* d) { + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; + if (dpy->ctx != nil) { + [dpy->ctx makeCurrentContext]; + } + _al_ogl_set_extensions(d->ogl_extras->extension_api); + return true; +} + +/* Helper to set up GL state as we want it. */ +static void setup_gl(ALLEGRO_DISPLAY *d) +{ + _al_ogl_setup_gl(d); + + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; + [dpy->ctx performSelectorOnMainThread:@selector(update) withObject:nil waitUntilDone:YES]; +} + + +/* Fills the array of NSOpenGLPixelFormatAttributes, which has a specfied + * maximum size, with the options appropriate for the display. + */ +static void osx_set_opengl_pixelformat_attributes(ALLEGRO_DISPLAY_OSX_WIN *dpy) +{ + int i, n; + bool want_double_buffer; + NSOpenGLPixelFormatAttribute *a; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras; + /* The following combination of flags indicates that multi-sampling is + * requested. + */ + const int sample_flags = (1<attributes, 0, AL_OSX_NUM_PFA*sizeof(*dpy->attributes)); + + /* We normally want a double buffer */ + want_double_buffer = true; + + /* Begin with the first attribute */ + a = dpy->attributes; + + /* First, check the display flags, so we know if we want a fullscreen + * mode or a windowed mode. + */ + if (dpy->parent.flags & ALLEGRO_FULLSCREEN) { + *a = NSOpenGLPFAFullScreen; a++; + // Take over the screen. + *a = NSOpenGLPFAScreenMask; a++; + *a = CGDisplayIDToOpenGLDisplayMask(dpy->display_id); a++; + } else { + *a = NSOpenGLPFAWindow; a++; + } + + /* Find the requested colour depth */ + if (extras) + dpy->depth = extras->settings[ALLEGRO_COLOR_SIZE]; + if (!dpy->depth) { /* Use default */ + NSScreen *screen; + int adapter = al_get_new_display_adapter(); + if ((adapter >= 0) && (adapter < al_get_num_video_adapters())) { + screen = [[NSScreen screens] objectAtIndex: adapter]; + } else { + screen = [NSScreen mainScreen]; + } + dpy->depth = NSBitsPerPixelFromDepth([screen depth]); + if (dpy->depth == 24) + dpy->depth = 32; + if (dpy->depth == 15) + dpy->depth = 16; + ALLEGRO_DEBUG("Using default colour depth %d\n", dpy->depth); + } + *a = NSOpenGLPFAColorSize; a++; + *a = dpy->depth; a++; + + /* Say we don't need an exact match for the depth of the colour buffer. + * FIXME: right now, this is set whenever nothing is required or + * something is suggested. Probably need finer control over this... + */ + if (!extras || !(extras->required) || extras->suggested) { + *a = NSOpenGLPFAClosestPolicy; a++; + } + + /* Should we set double buffering? If it's not required we don't care + * and go with the default. + */ + if (extras && (extras->required & (1 << ALLEGRO_SINGLE_BUFFER)) && + extras->settings[ALLEGRO_SINGLE_BUFFER]) { + want_double_buffer = false; + dpy->single_buffer = true; + } + if (want_double_buffer) { + *a = NSOpenGLPFADoubleBuffer; a++; + } + + /* Detect if multi-sampling is requested */ + /* Or "NSOpenGLPFASupersample" ? */ + if (extras && (extras->required & sample_flags) && + (extras->settings[ALLEGRO_SAMPLES]||extras->settings[ALLEGRO_SAMPLE_BUFFERS])) { + *a = NSOpenGLPFAMultisample; a++; + } + + /* Now go through all other options, if set */ + for (n = 0; n < number_of_settings; n++) { + i = allegro_to_osx_settings[n][0]; + if (allegro_to_osx_settings[n][1] && extras && + ((extras->required & (1 << i)) || (extras->suggested & (1 << i)))) { + /* Need to distinguish between boolean attributes and settings that + * require a value. + */ + if (allegro_to_osx_settings[n][2]) { /* Value */ + /* We must make sure the value is non-zero because the list are + * building is 0-terminated. + */ + if (extras->settings[i]) { + *a = allegro_to_osx_settings[n][1]; a++; + *a = extras->settings[i]; a++; + ALLEGRO_DEBUG("Passing pixel format attribute %s = %d\n", allegro_pixel_format_names[n], extras->settings[i]); + } + } else if (extras->settings[i]) { /* Boolean, just turn this on */ + *a = allegro_to_osx_settings[n][1]; a++; + ALLEGRO_DEBUG("Passing pixel format attribute %s = %d\n", allegro_pixel_format_names[n], extras->settings[i]); + } + } + } + + /* Accelerated is always preferred, so we only set this for required not + * for suggested. + */ + if (extras->required & ALLEGRO_RENDER_METHOD) { + *a++ = NSOpenGLPFAAccelerated; + } +} + + +/* Set the extra_settings[] array in the display, to report which options + * we have selected. + */ +static void osx_get_opengl_pixelformat_attributes(ALLEGRO_DISPLAY_OSX_WIN *dpy) +{ + int n; + + if (!dpy) + return; + + /* Clear list of settings (none selected) */ + memset(&dpy->parent.extra_settings, 0, sizeof(dpy->parent.extra_settings)); + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + /* Get the pixel format associated with the OpenGL context. + * We use the Carbon API rather than the Cocoa API because that way we + * can use the same code in Windowed mode as in fullscreen mode (we + * don't have an NSOpenGLView in fullscreen mode). + */ + CGLContextObj ctx = [dpy->ctx CGLContextObj]; + CGLPixelFormatObj pixel_format = CGLGetPixelFormat(ctx); + GLint screen_id; + CGLGetVirtualScreen(ctx, &screen_id); + ALLEGRO_DEBUG("Screen has ID %d\n", (int)screen_id); + for (n = 0; n < number_of_settings; n++) { + /* Go through the list of options and relist the ones that we have + * set to Allegro's option list. + */ + + CGLPixelFormatAttribute attrib = allegro_to_osx_settings[n][1]; + /* Skip options that don't exist on OS X */ + if (attrib == 0) + continue; + + /* Get value for this attribute */ + GLint value; + CGLDescribePixelFormat(pixel_format, screen_id, attrib, &value); + + int al_setting = allegro_to_osx_settings[n][0]; + if (allegro_to_osx_settings[n][2] == 0) /* Boolean attribute */ + value = 1; + + dpy->parent.extra_settings.settings[al_setting] = value; + ALLEGRO_DEBUG("Pixel format attribute %s set to %d\n", allegro_pixel_format_names[n], value); + } +#else + /* CGLGetPixelFormat does not exist on Tiger, so we need to do something + * else. + * FIXME: right now, we just return the settings that were chosen by the + * user. To be correct, we should query the pixelformat corresponding to + * the display, using the NSOpenGLView pixelFormat method and the + * NSOpenGLPixelFormat getValues:forAttribute:forVirtualScreen: method, + * for which we need to know the logical screen number that the display + * is on. That doesn't work for fullscreen modes though... + */ + NSOpenGLPixelFormatAttribute *attributes = dpy->attributes; + + for (n = 0; n < number_of_settings; n++) { + /* Go through the list of options and relist the ones that we have + * set to Allegro's option list. + */ + NSOpenGLPixelFormatAttribute *a = dpy->attributes; + while (*a) { + if (*a == allegro_to_osx_settings[n][1]) { + int al_setting = allegro_to_osx_settings[n][0]; + int value = 1; + if (allegro_to_osx_settings[n][2]) + value = a[1]; + dpy->parent.extra_settings.settings[al_setting] = value; + ALLEGRO_DEBUG("Setting pixel format attribute %d to %d\n", al_setting, value); + } + /* Advance to next option */ + if (allegro_to_osx_settings[n][2]) /* Has a parameter in the list */ + a++; + a++; + } + } +#endif + dpy->parent.extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; + + // Fill in the missing colour format options, as best we can + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = &dpy->parent.extra_settings; + if (eds->settings[ALLEGRO_COLOR_SIZE] == 0) { + eds->settings[ALLEGRO_COLOR_SIZE] = 32; + eds->settings[ALLEGRO_RED_SIZE] = 8; + eds->settings[ALLEGRO_GREEN_SIZE] = 8; + eds->settings[ALLEGRO_BLUE_SIZE] = 8; + eds->settings[ALLEGRO_ALPHA_SIZE] = 8; + eds->settings[ALLEGRO_RED_SHIFT] = 0; + eds->settings[ALLEGRO_GREEN_SHIFT] = 8; + eds->settings[ALLEGRO_BLUE_SHIFT] = 16; + eds->settings[ALLEGRO_ALPHA_SHIFT] = 24; + } else { + int size = eds->settings[ALLEGRO_ALPHA_SIZE]; + if (!size) { + switch (eds->settings[ALLEGRO_COLOR_SIZE]) { + case 32: + size = 8; + break; + + case 16: + size = 5; + break; + + case 8: + size = 8; + break; + } + } + if (!eds->settings[ALLEGRO_RED_SIZE]) + eds->settings[ALLEGRO_RED_SIZE] = size; + if (!eds->settings[ALLEGRO_BLUE_SIZE]) + eds->settings[ALLEGRO_BLUE_SIZE] = size; + if (!eds->settings[ALLEGRO_GREEN_SIZE]) + eds->settings[ALLEGRO_GREEN_SIZE] = size; + if (!eds->settings[ALLEGRO_RED_SHIFT]) + eds->settings[ALLEGRO_RED_SHIFT] = 0; + if (!eds->settings[ALLEGRO_GREEN_SHIFT]) + eds->settings[ALLEGRO_GREEN_SHIFT] = eds->settings[ALLEGRO_RED_SIZE]; + if (!eds->settings[ALLEGRO_BLUE_SHIFT]) + eds->settings[ALLEGRO_BLUE_SHIFT] = eds->settings[ALLEGRO_GREEN_SIZE]+eds->settings[ALLEGRO_GREEN_SHIFT]; + if (!eds->settings[ALLEGRO_ALPHA_SHIFT]) + eds->settings[ALLEGRO_ALPHA_SHIFT] = eds->settings[ALLEGRO_BLUE_SIZE]+eds->settings[ALLEGRO_BLUE_SHIFT]; + } +} + +/* This function must be run on the main thread */ +static void osx_run_fullscreen_display(ALLEGRO_DISPLAY_OSX_WIN* dpy) +{ + ASSERT_MAIN_THREAD(); + ALLEGRO_DISPLAY* display = &dpy->parent; + while (dpy->in_fullscreen) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + // Collect an event + NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + // Process it as required. + switch ([event type]) { + case NSEventTypeKeyDown: + _al_osx_keyboard_handler(true,event,display); + break; + case NSEventTypeKeyUp: + _al_osx_keyboard_handler(false,event,display); + break; + case NSEventTypeFlagsChanged: + _al_osx_keyboard_modifiers([event modifierFlags],display); + break; + case NSEventTypeLeftMouseDown: + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseDown: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseDown: + case NSEventTypeOtherMouseUp: + case NSEventTypeMouseMoved: + case NSEventTypeLeftMouseDragged: + case NSEventTypeRightMouseDragged: + case NSEventTypeOtherMouseDragged: + if (_osx_mouse_installed) + _al_osx_mouse_generate_event(event, display); + break; + default: + [NSApp sendEvent: event]; + break; + } + [pool release]; + } +} + +/* osx_create_shareable_context: + * + * Create an NSOpenGLContext with a given pixel format. If possible, make + * the context compatible with one that has already been created and + * assigned to a display. If this can't be done, create an unshared one + * (which may itself be shared in the future) + * Each context is given a group number so that all shared contexts have the + * same group number. + * + * Parameters: + * fmt - The pixel format to use + * group - Pointer to the assigned group for the new context + * + * Returns: + * The new context or nil if it cannot be created. + */ +static NSOpenGLContext* osx_create_shareable_context(NSOpenGLPixelFormat* fmt, unsigned int* group) +{ + // Iterate through all existing displays and try and find one that's compatible + _AL_VECTOR* dpys = &al_get_system_driver()->displays; + unsigned int i; + NSOpenGLContext* compat = nil; + + for (i = 0; i < _al_vector_size(dpys); ++i) { + ALLEGRO_DISPLAY_OSX_WIN* other = *(ALLEGRO_DISPLAY_OSX_WIN**) _al_vector_ref(dpys, i); + compat = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext: other->ctx]; + if (compat != nil) { + // OK, we can share with this one + *group = other->display_group; + ALLEGRO_DEBUG("Sharing display group %d\n", *group); + break; + } + } + if (compat == nil) { + // Set to a new group + *group = next_display_group++; + ALLEGRO_DEBUG("Creating new display group %d\n", *group); + compat = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext: nil]; + } + return compat; +} + +#ifndef NSAppKitVersionNumber10_7 +#define NSAppKitVersionNumber10_7 1138 +#endif + +static CVReturn display_link_callback(CVDisplayLinkRef display_link, + const CVTimeStamp *now, + const CVTimeStamp *output_time, + CVOptionFlags flags_in, + CVOptionFlags *flags_out, + void *user_info) +{ + (void)display_link; + (void)now; + (void)output_time; + (void)flags_in; + (void)flags_out; + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN*)user_info; + + al_lock_mutex(dpy->flip_mutex); + dpy->num_flips += 1; + al_signal_cond(dpy->flip_cond); + al_unlock_mutex(dpy->flip_mutex); + + return kCVReturnSuccess; +} + +static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy) +{ + dpy->flip_cond = al_create_cond(); + dpy->flip_mutex = al_create_mutex(); + CVDisplayLinkCreateWithActiveCGDisplays(&dpy->display_link); + CVDisplayLinkSetOutputCallback(dpy->display_link, &display_link_callback, dpy); + CGLContextObj ctx = [dpy->ctx CGLContextObj]; + CGLPixelFormatObj pixel_format = CGLGetPixelFormat(ctx); + CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(dpy->display_link, ctx, pixel_format); + CVDisplayLinkStart(dpy->display_link); +} + +/* create_display_fs: + * Create a fullscreen display - capture the display + */ +static ALLEGRO_DISPLAY* create_display_fs(int w, int h) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + ALLEGRO_DEBUG("Switching to fullscreen mode sized %dx%d\n", w, h); + + #define IS_LION (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_7) + + if (al_get_new_display_adapter() >= al_get_num_video_adapters()) { + [pool drain]; + return NULL; + } + ALLEGRO_DISPLAY_OSX_WIN* dpy = al_malloc(sizeof(ALLEGRO_DISPLAY_OSX_WIN)); + if (dpy == NULL) { + [pool drain]; + return NULL; + } + memset(dpy, 0, sizeof(*dpy)); + ALLEGRO_DISPLAY* display = &dpy->parent; + + /* Set up the ALLEGRO_DISPLAY part */ + display->vt = _al_osx_get_display_driver_fs(); + display->refresh_rate = al_get_new_display_refresh_rate(); + display->flags = al_get_new_display_flags() | ALLEGRO_OPENGL | ALLEGRO_FULLSCREEN; +#ifdef ALLEGRO_CFG_OPENGLES2 + display.flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + display.flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + display->w = w; + display->h = h; + _al_event_source_init(&display->es); + dpy->cursor = [[NSCursor arrowCursor] retain]; + dpy->display_id = CGMainDisplayID(); + + /* Get display ID for the requested display */ + if (al_get_new_display_adapter() > 0) { + int adapter = al_get_new_display_adapter(); + NSScreen *screen = [[NSScreen screens] objectAtIndex: adapter]; + NSDictionary *dict = [screen deviceDescription]; + NSNumber *display_id = [dict valueForKey: @"NSScreenNumber"]; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + dpy->display_id = [display_id intValue]; +#else + dpy->display_id = [display_id integerValue]; +#endif + //dpy->display_id = (CGDirectDisplayID)[display_id pointerValue]; + } + + // Set up a pixel format to describe the mode we want. + osx_set_opengl_pixelformat_attributes(dpy); + NSOpenGLPixelFormat* fmt = + [[NSOpenGLPixelFormat alloc] initWithAttributes: dpy->attributes]; + if (fmt == nil) { + ALLEGRO_DEBUG("Could not set pixel format\n"); + [pool drain]; + return NULL; + } + + // Create a context which shares with any other contexts with the same format + NSOpenGLContext* context = osx_create_shareable_context(fmt, &dpy->display_group); + [fmt release]; + if (context == nil) { + ALLEGRO_DEBUG("Could not create rendering context\n"); + [pool drain]; + return NULL; + } + dpy->ctx = context; + + // Prevent other apps from writing to this display and switch it to our + // chosen mode. +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + CGDisplayCapture(dpy->display_id); + CFDictionaryRef mode = CGDisplayBestModeForParametersAndRefreshRate(dpy->display_id, dpy->depth, w, h, display->refresh_rate, NULL); + CGDisplaySwitchToMode(dpy->display_id, mode); +#else + CGDisplayModeRef mode = NULL; + CFArrayRef modes = NULL; + CFStringRef pixel_format = NULL; + int i; + + /* Set pixel format string */ + if (dpy->depth == 32) + pixel_format = CFSTR(IO32BitDirectPixels); + if (dpy->depth == 16) + pixel_format = CFSTR(IO16BitDirectPixels); + if (dpy->depth == 8) + pixel_format = CFSTR(IO8BitIndexedPixels); + modes = CGDisplayCopyAllDisplayModes(dpy->display_id, NULL); + for (i = 0; i < CFArrayGetCount(modes); i++) { + CGDisplayModeRef try_mode = + (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); + + CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(try_mode); + + /* Found mode with matching size/colour depth */ + if ( w == (int)CGDisplayModeGetWidth(try_mode) && + h == (int)CGDisplayModeGetHeight(try_mode) && + CFStringCompare(pixel_encoding, pixel_format, 1) == 0) { + mode = try_mode; + CFRelease(pixel_encoding); + break; + } + + /* Found mode with matching size; colour depth does not match, but + * it's the best so far. + */ + if ( w == (int)CGDisplayModeGetWidth(try_mode) && + h == (int)CGDisplayModeGetHeight(try_mode) && + mode == NULL) { + mode = try_mode; + } + + CFRelease(pixel_encoding); + } + CFRelease(modes); + + if (!mode) { + /* Trouble! - we can't find a nice mode to set. */ + [dpy->ctx clearDrawable]; + CGDisplayRelease(dpy->display_id); + al_free(dpy); + [pool drain]; + return NULL; + } + + /* Switch display mode */ + dpy->original_mode = CGDisplayCopyDisplayMode(dpy->display_id); + CGDisplayCapture(dpy->display_id); + CGDisplaySetDisplayMode(dpy->display_id, mode, NULL); +#endif + + NSRect rect = NSMakeRect(0, 0, w, h); + NSString* title = [NSString stringWithUTF8String: al_get_new_window_title()]; + dispatch_sync(dispatch_get_main_queue(), ^{ + dpy->win = [[ALWindow alloc] initWithContentRect:rect styleMask:(IS_LION ? NSWindowStyleMaskBorderless : 0) backing:NSBackingStoreBuffered defer:NO]; + [dpy->win setTitle: title]; + [dpy->win setAcceptsMouseMovedEvents:YES]; + [dpy->win setViewsNeedDisplay:NO]; + + NSView *window_view = [[NSView alloc] initWithFrame:rect]; + [window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + [[dpy->win contentView] addSubview:window_view]; + [dpy->win setLevel:CGShieldingWindowLevel()]; + [context setView:window_view]; + [context update]; + [window_view release]; + [dpy->win setHasShadow:NO]; + [dpy->win setOpaque:YES]; + [dpy->win makeKeyAndOrderFront:nil]; + }); + // This is set per-thread + [context makeCurrentContext]; + + // Set up the Allegro OpenGL implementation + display->ogl_extras = al_malloc(sizeof(ALLEGRO_OGL_EXTRAS)); + memset(display->ogl_extras, 0, sizeof(ALLEGRO_OGL_EXTRAS)); + _al_ogl_manage_extensions(&dpy->parent); + _al_ogl_set_extensions(dpy->parent.ogl_extras->extension_api); + display->ogl_extras->is_shared = true; + + /* Retrieve the options that were set */ + osx_get_opengl_pixelformat_attributes(dpy); + /* Turn on vsyncing possibly. The old way doesn't work on new OSX's, + but works better than the new way when it does work. */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 + if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { + init_new_vsync(dpy); + } +#else + if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { + GLint swapInterval = 1; + [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; + } + else { + GLint swapInterval = 0; + [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; + } +#endif + + /* Set up GL as we want */ + setup_gl(display); + + clear_to_black(dpy->ctx); + + /* Add to the display list */ + ALLEGRO_DISPLAY **add = _al_vector_alloc_back(&al_get_system_driver()->displays); + *add = display; + dpy->in_fullscreen = YES; + // Begin the 'private' event loop + // Necessary because there's no NSResponder (i.e. a view) to collect + // events from the window server. + dispatch_sync(dispatch_get_main_queue(), ^{ + osx_run_fullscreen_display(dpy); + }); + [pool drain]; + return &dpy->parent; +} +#if 0 +/* Alternative, Cocoa-based mode switching. + * Works, but I can't get the display to respond to a resize request + * properly - EG + */ +static ALLEGRO_DISPLAY* create_display_fs(int w, int h) +{ + ALLEGRO_DEBUG("Creating full screen mode sized %dx%d\n", w, h); + if (al_get_new_display_adapter() >= al_get_num_video_adapters()) + return NULL; + ALLEGRO_DISPLAY_OSX_WIN* dpy = al_malloc(sizeof(ALLEGRO_DISPLAY_OSX_WIN)); + if (dpy == NULL) { + return NULL; + } + memset(dpy, 0, sizeof(*dpy)); + + /* Set up the ALLEGRO_DISPLAY part */ + dpy->parent.vt = _al_osx_get_display_driver_win(); + dpy->parent.refresh_rate = al_get_new_display_refresh_rate(); + dpy->parent.flags = al_get_new_display_flags() | ALLEGRO_OPENGL | ALLEGRO_FULLSCREEN; +#ifdef ALLEGRO_CFG_OPENGLES2 + dpy->parent.flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + dpy->parent.flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + dpy->parent.w = w; + dpy->parent.h = h; + _al_event_source_init(&dpy->parent.es); + osx_change_cursor(dpy, [NSCursor arrowCursor]); + dpy->show_cursor = YES; + + // Set up a pixel format to describe the mode we want. + osx_set_opengl_pixelformat_attributes(dpy); + + // Clear last window position to 0 if there are no other open windows + if (_al_vector_is_empty(&al_get_system_driver()->displays)) { + last_window_pos = NSZeroPoint; + } + + /* OSX specific part - finish the initialisation on the main thread */ + [ALDisplayHelper performSelectorOnMainThread: @selector(initialiseDisplay:) + withObject: [NSValue valueWithPointer:dpy] + waitUntilDone: YES]; + + [dpy->ctx makeCurrentContext]; + [dpy->ctx setFullScreen]; + + NSScreen *screen = [dpy->win screen]; + NSDictionary *dict = [screen deviceDescription]; + NSNumber *display_id = [dict valueForKey: @"NSScreenNumber"]; + dpy->display_id = [display_id integerValue]; + //dpy->display_id = (CGDirectDisplayID)[display_id pointerValue]; + CGDisplayCapture(dpy->display_id); + +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + CFDictionaryRef mode = CGDisplayBestModeForParametersAndRefreshRate(dpy->display_id, dpy->depth, w, h, dpy->parent.refresh_rate, NULL); + CGDisplaySwitchToMode(dpy->display_id, mode); +#else + CGDisplayModeRef mode = NULL; + CFArrayRef modes = NULL; + CFStringRef pixel_format = NULL; + int i; + + /* Set pixel format string */ + if (dpy->depth == 32) + pixel_format = CFSTR(IO32BitDirectPixels); + if (dpy->depth == 16) + pixel_format = CFSTR(IO16BitDirectPixels); + if (dpy->depth == 8) + pixel_format = CFSTR(IO8BitIndexedPixels); + modes = CGDisplayCopyAllDisplayModes(dpy->display_id, NULL); + for (i = 0; i < CFArrayGetCount(modes); i++) { + CGDisplayModeRef try_mode = + (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); + + CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(try_mode); + + /* Found mode with matching size/colour depth */ + if ( w == (int)CGDisplayModeGetWidth(try_mode) && + h == (int)CGDisplayModeGetHeight(try_mode) && + CFStringCompare(pixel_encoding, pixel_format, 1) == 0) { + mode = try_mode; + CFRelease(pixel_encoding); + break; + } + + /* Found mode with matching size; colour depth does not match, but + * it's the best so far. + */ + if ( w == (int)CGDisplayModeGetWidth(try_mode) && + h == (int)CGDisplayModeGetHeight(try_mode) && + mode == NULL) { + mode = try_mode; + } + + CFRelease(pixel_encoding); + } + + if (!mode) { + /* Trouble! - we can't find a nice mode to set. */ + [dpy->ctx clearDrawable]; + CGDisplayRelease(dpy->display_id); + [dpy->win close]; + al_free(dpy); + return NULL; + } + + /* Switch display mode */ + CFDictionaryRef options = CFDictionaryCreate(NULL, NULL, NULL, 0, NULL, NULL); + CGDisplaySetDisplayMode(dpy->display_id, mode, NULL); + CFRelease(options); + CFRelease(modes); +#endif + + [[dpy->win contentView] enterFullScreenMode: screen withOptions: nil]; + + // Set up the Allegro OpenGL implementation + dpy->parent.ogl_extras = al_malloc(sizeof(ALLEGRO_OGL_EXTRAS)); + memset(dpy->parent.ogl_extras, 0, sizeof(ALLEGRO_OGL_EXTRAS)); + _al_ogl_manage_extensions(&dpy->parent); + _al_ogl_set_extensions(dpy->parent.ogl_extras->extension_api); + dpy->parent.ogl_extras->is_shared = true; + + /* Retrieve the options that were set */ + osx_get_opengl_pixelformat_attributes(dpy); + /* Turn on vsyncing possibly. The old way doesn't work on new OSX's, + but works better than the new way when it does work. */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 + if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { + init_new_vsync(dpy); + } +#else + if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { + GLint swapInterval = 1; + [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; + } + else { + GLint swapInterval = 0; + [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; + } +#endif + + /* Set up GL as we want */ + setup_gl(&dpy->parent); + + clear_to_black(dpy->ctx); + + /* Add to the display list */ + ALLEGRO_DISPLAY **add = _al_vector_alloc_back(&al_get_system_driver()->displays); + *add = &dpy->parent; + dpy->in_fullscreen = YES; + + return &dpy->parent; +} +#endif + +/* create_display_win: +* Create a windowed display - create the window with an ALOpenGLView +* to be its content view +* Call from user thread. +*/ +static ALLEGRO_DISPLAY* create_display_win(int w, int h) { + ASSERT_USER_THREAD(); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + /* Create a temporary view so that we can check whether a fullscreen + * window can be created. + */ + if (al_get_new_display_flags() & ALLEGRO_FULLSCREEN_WINDOW) { + __block BOOL ok; + dispatch_sync(dispatch_get_main_queue(), ^{ + NSRect rc = NSMakeRect(0, 0, w, h); + ALOpenGLView* view = [[ALOpenGLView alloc] initWithFrame: rc]; + ok = [view respondsToSelector: + @selector(enterFullScreenMode:withOptions:)]; + [view release]; + }); + if (!ok) { + ALLEGRO_DEBUG("Cannot create FULLSCREEN_WINDOW"); + return NULL; + } + } + + ALLEGRO_DEBUG("Creating window sized %dx%d\n", w, h); + if (al_get_new_display_adapter() >= al_get_num_video_adapters()) { + [pool drain]; + return NULL; + } + ALLEGRO_DISPLAY_OSX_WIN* dpy = al_malloc(sizeof(ALLEGRO_DISPLAY_OSX_WIN)); + if (dpy == NULL) { + [pool drain]; + return NULL; + } + memset(dpy, 0, sizeof(*dpy)); + ALLEGRO_DISPLAY* display = &dpy->parent; + /* Set up the ALLEGRO_DISPLAY part */ + display->vt = _al_osx_get_display_driver_win(); + display->refresh_rate = al_get_new_display_refresh_rate(); + display->flags = al_get_new_display_flags() | ALLEGRO_OPENGL | ALLEGRO_WINDOWED; +#ifdef ALLEGRO_CFG_OPENGLES2 + display->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + display->flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + display->w = w; + display->h = h; + _al_event_source_init(&display->es); + _al_osx_change_cursor(dpy, [NSCursor arrowCursor]); + dpy->show_cursor = YES; + + // Set up a pixel format to describe the mode we want. + osx_set_opengl_pixelformat_attributes(dpy); + + // Clear last window position to 0 if there are no other open windows + if (_al_vector_is_empty(&al_get_system_driver()->displays)) { + last_window_pos = NSZeroPoint; + } + + /* Get the new window position. This is stored in TLS, so we need to do + * this before calling initialise_display, which runs on a different + * thread. + */ + int x, y; + int adapter = al_get_new_display_adapter(); + const char* title = al_get_new_window_title(); + al_get_new_window_position(&x, &y); + + /* OSX specific part - finish the initialisation on the main thread */ + dispatch_sync(dispatch_get_main_queue(), ^{ + NSRect rc = NSMakeRect(0, 0, w, h); + ALWindow *alwin = dpy->win = [ALWindow alloc]; + NSWindow* win = alwin; + NSScreen *screen; + unsigned int mask = (display->flags & ALLEGRO_FRAMELESS) ? NSWindowStyleMaskBorderless : + (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable); + if (display->flags & ALLEGRO_RESIZABLE) + mask |= NSWindowStyleMaskResizable; + if (display->flags & ALLEGRO_FULLSCREEN) + mask |= NSWindowStyleMaskResizable; + + if ((adapter >= 0) && + (adapter < al_get_num_video_adapters())) { + screen = [[NSScreen screens] objectAtIndex: adapter]; + } else { + screen = [NSScreen mainScreen]; + } + float screen_scale_factor = 1.0; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + if ([screen respondsToSelector:@selector(backingScaleFactor)]) { + screen_scale_factor = [screen backingScaleFactor]; + } +#endif + rc.size.width /= screen_scale_factor; + rc.size.height /= screen_scale_factor; + [win initWithContentRect: rc + styleMask: mask + backing: NSBackingStoreBuffered + defer: NO + screen: screen + ]; + alwin.display = (ALLEGRO_DISPLAY *)dpy; + if (display->flags & ALLEGRO_RESIZABLE) { + if ([win respondsToSelector:NSSelectorFromString(@"setCollectionBehavior:")]) { + [win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } + } + NSOpenGLPixelFormat* fmt = + [[NSOpenGLPixelFormat alloc] initWithAttributes: dpy->attributes]; + ALOpenGLView* view = [[ALOpenGLView alloc] initWithFrame: rc]; + dpy->ctx = osx_create_shareable_context(fmt, &dpy->display_group); + if (dpy->ctx == nil) { + ALLEGRO_DEBUG("Could not create rendering context\n"); + [view release]; + [fmt release]; + + return; + } + /* Hook up the view to its display */ + [view setAllegroDisplay: &dpy->parent]; + [view setOpenGLContext: dpy->ctx]; + [view setPixelFormat: fmt]; + /* Realize the window on the main thread */ + [win setContentView: view]; + [win setDelegate: view]; + [win setReleasedWhenClosed: YES]; + [win setAcceptsMouseMovedEvents: _osx_mouse_installed]; + [win setTitle: [NSString stringWithUTF8String: title]]; + /* Set minimum size, otherwise the window can be resized so small we can't + * grab the handle any more to make it bigger + */ + [win setMinSize: NSMakeSize(MINIMUM_WIDTH / screen_scale_factor, + MINIMUM_HEIGHT / screen_scale_factor)]; + + /* Maximize the window and update its width & height information */ + if (display->flags & ALLEGRO_MAXIMIZED) { + [win setFrame: [screen visibleFrame] display: true animate: false]; + NSRect content = [win contentRectForFrameRect: [win frame]]; + display->w = content.size.width; + display->h = content.size.height; + } + + /* Place the window, respecting the location set by the user with + * al_set_new_window_position(). + * If the user never called al_set_new_window_position, we simply let + * the window manager pick a suitable location. + * + * CAUTION: the window manager under OS X requires that x and y be in + * the range -16000 ... 16000 (approximately, probably the range of a + * signed 16 bit integer). Should we check for this? + */ + + if ((x != INT_MAX) && (y != INT_MAX)) { + /* The user gave us window coordinates */ + NSRect rc = [win frame]; + NSRect sc = [[win screen] frame]; + NSPoint origin; + + /* We need to modify the y coordinate, cf. set_window_position */ + origin.x = sc.origin.x + x / screen_scale_factor; + origin.y = sc.origin.y + sc.size.height - rc.size.height - y / screen_scale_factor; + [win setFrameOrigin: origin]; + } + else { + [win center]; + } + [win makeKeyAndOrderFront:nil]; + if (mask != NSWindowStyleMaskBorderless) { + [win makeMainWindow]; + } + [fmt release]; + [view release]; + if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) { + NSRect sc = [[dpy->win screen] frame]; + dpy->parent.w = sc.size.width; + dpy->parent.h = sc.size.height; + } + }); + + [dpy->ctx makeCurrentContext]; + + /* Print out OpenGL version info */ + ALLEGRO_INFO("OpenGL Version: %s\n", glGetString(GL_VERSION)); + ALLEGRO_INFO("Vendor: %s\n", glGetString(GL_VENDOR)); + ALLEGRO_INFO("Renderer: %s\n", glGetString(GL_RENDERER)); + + /* Set up a pixel format to describe the mode we want. */ + osx_set_opengl_pixelformat_attributes(dpy); + /* Retrieve the options that were set */ + // Note: This initializes dpy->extra_settings + osx_get_opengl_pixelformat_attributes(dpy); + + // Set up the Allegro OpenGL implementation + display->ogl_extras = al_malloc(sizeof(ALLEGRO_OGL_EXTRAS)); + memset(display->ogl_extras, 0, sizeof(ALLEGRO_OGL_EXTRAS)); + _al_ogl_manage_extensions(display); + _al_ogl_set_extensions(display->ogl_extras->extension_api); + display->ogl_extras->is_shared = true; + + /* Turn on vsyncing possibly. The old way doesn't work on new OSX's, + but works better than the new way when it does work. */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 + if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { + init_new_vsync(dpy); + } +#else + if (_al_get_new_display_settings()->settings[ALLEGRO_VSYNC] == 1) { + GLint swapInterval = 1; + [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; + } + else { + GLint swapInterval = 0; + [dpy->ctx setValues:&swapInterval forParameter: NSOpenGLCPSwapInterval]; + } +#endif + + /* Set up GL as we want */ + setup_gl(display); + + clear_to_black(dpy->ctx); + + /* Add to the display list */ + ALLEGRO_DISPLAY **add = _al_vector_alloc_back(&al_get_system_driver()->displays); + *add = display; + dpy->in_fullscreen = NO; + + if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) { + display->flags ^= ALLEGRO_FULLSCREEN_WINDOW; /* Not set yet */ + set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, true); + } + + [pool drain]; + + return display; +} + +/* destroy_display: + * Destroy display, actually close the window or exit fullscreen on the main thread + * Called from user thread + */ +static void destroy_display(ALLEGRO_DISPLAY* d) +{ + ASSERT_USER_THREAD(); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + ALLEGRO_DISPLAY *old_dpy = al_get_current_display(); + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; + ALLEGRO_DISPLAY_OSX_WIN* other = NULL; + unsigned int i; + + // Set the display as the current display; needed because we need to + // make the context current. + if (old_dpy != d) { + _al_set_current_display_only(d); + } + + /* First of all, save video bitmaps attached to this display. */ + // Check for other displays in this display group + _AL_VECTOR* dpys = &al_get_system_driver()->displays; + for (i = 0; i < _al_vector_size(dpys); ++i) { + ALLEGRO_DISPLAY_OSX_WIN* d = *(ALLEGRO_DISPLAY_OSX_WIN**) _al_vector_ref(dpys, i); + if (d->display_group == dpy->display_group && (d!=dpy)) { + other = d; + break; + } + } + if (other != NULL) { + // Found another compatible display. Transfer our bitmaps to it. + _AL_VECTOR* bmps = &dpy->parent.bitmaps; + for (i = 0; i<_al_vector_size(bmps); ++i) { + ALLEGRO_BITMAP **add = _al_vector_alloc_back(&other->parent.bitmaps); + ALLEGRO_BITMAP **ref = _al_vector_ref(bmps, i); + *add = *ref; + (*add)->_display = &(other->parent); + } + } + else { + // This is the last in its group. Convert all its bitmaps to memory bmps + while (dpy->parent.bitmaps._size > 0) { + ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&dpy->parent.bitmaps); + ALLEGRO_BITMAP *bmp = *bptr; + _al_convert_to_memory_bitmap(bmp); + } + } + _al_vector_free(&dpy->parent.bitmaps); + ALLEGRO_DISPLAY* display = &dpy->parent; + ALLEGRO_OGL_EXTRAS *ogl = display->ogl_extras; + _al_vector_find_and_delete(&al_get_system_driver()->displays, &display); + if (ogl->backbuffer) { + _al_ogl_destroy_backbuffer(ogl->backbuffer); + ogl->backbuffer = NULL; + ALLEGRO_DEBUG("destroy backbuffer.\n"); + } + dispatch_sync(dispatch_get_main_queue(), ^{ + // Disconnect from its view or exit fullscreen mode + [dpy->ctx clearDrawable]; + // Unlock the screen + if (display->flags & ALLEGRO_FULLSCREEN) { + CGDisplaySetDisplayMode(dpy->display_id, dpy->original_mode, NULL); + CGDisplayModeRelease(dpy->original_mode); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + if (dpy->win) { + [[dpy->win contentView] exitFullScreenModeWithOptions: nil]; + } +#endif + CGDisplayRelease(dpy->display_id); + dpy->in_fullscreen = false; + } + else if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + if (dpy->win) { + [[dpy->win contentView] exitFullScreenModeWithOptions: nil]; + } +#endif + } + if (dpy->win) { + // Destroy the containing window if there is one + [dpy->win close]; + dpy->win = nil; + } + }); + _al_ogl_unmanage_extensions(&dpy->parent); + [dpy->ctx release]; + [dpy->cursor release]; + _al_event_source_free(&d->es); + al_free(d->ogl_extras); + + // Restore original display from before this function was called. + // If the display we just destroyed is actually current, set the current + // display to NULL. + if (old_dpy != d) + _al_set_current_display_only(old_dpy); + else { + // Is this redundant? --pw + _al_set_current_display_only(NULL); + } + + if (dpy->flip_mutex) { + al_destroy_mutex(dpy->flip_mutex); + al_destroy_cond(dpy->flip_cond); + CVDisplayLinkRelease(dpy->display_link); + } + al_free(d->vertex_cache); + al_free(d); + [pool drain]; +} + +/* create_display: + * Create a display either fullscreen or windowed depending on flags + * Call from user thread + */ +static ALLEGRO_DISPLAY* create_display(int w, int h) +{ + ASSERT_USER_THREAD(); + int flags = al_get_new_display_flags(); + if (flags & ALLEGRO_FULLSCREEN) { + return create_display_fs(w,h); + } + else { + return create_display_win(w,h); + } +} + +/* Note: in windowed mode, contexts always behave like single-buffered + * though in fact they are composited offscreen */ +static void flip_display(ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) disp; + + ALLEGRO_BITMAP *old_target = NULL; + if (!((ALLEGRO_BITMAP_EXTRA_OPENGL *)disp->ogl_extras->opengl_target->extra)->is_backbuffer) { + old_target = al_get_target_bitmap(); + al_set_target_backbuffer(disp); + } + + if (dpy->flip_mutex) { + al_lock_mutex(dpy->flip_mutex); + int old_flips = dpy->num_flips; + while (dpy->num_flips == old_flips) { + al_wait_cond(dpy->flip_cond, dpy->flip_mutex); + } + dpy->num_flips = 0; + al_unlock_mutex(dpy->flip_mutex); + } + + if (dpy->single_buffer) { + glFlush(); + } + else { + [dpy->ctx flushBuffer]; + } + + if (old_target) { + al_set_target_bitmap(old_target); + } +} + +static void update_display_region(ALLEGRO_DISPLAY *disp, + int x, int y, int width, int height) +{ + (void)x; + (void)y; + (void)width; + (void)height; + flip_display(disp); +} + +/* _al_osx_create_mouse_cursor: + * creates a custom system cursor from the bitmap bmp. + * (x_focus, y_focus) indicates the cursor hot-spot. + */ +ALLEGRO_MOUSE_CURSOR *_al_osx_create_mouse_cursor(ALLEGRO_BITMAP *bmp, + int x_focus, int y_focus) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + ALLEGRO_MOUSE_CURSOR_OSX *cursor = NULL; + + if (!bmp) { + [pool drain]; + return NULL; + } + + NSImage* cursor_image = NSImageFromAllegroBitmap(bmp); + cursor = al_malloc(sizeof *cursor); + cursor->cursor = [[NSCursor alloc] initWithImage: cursor_image + hotSpot: NSMakePoint(x_focus, y_focus)]; + [cursor_image release]; + [pool drain]; + + return (ALLEGRO_MOUSE_CURSOR *)cursor; +} + +/* _al_osx_destroy_mouse_cursor: + * destroys a mouse cursor previously created with _al_osx_create_mouse_cursor + */ +void _al_osx_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *curs) +{ + ALLEGRO_MOUSE_CURSOR_OSX *cursor = (ALLEGRO_MOUSE_CURSOR_OSX *) curs; + unsigned i; + + if (!cursor) + return; + + /* XXX not at all thread safe */ + + _AL_VECTOR* dpys = &al_get_system_driver()->displays; + for (i = 0; i < _al_vector_size(dpys); ++i) { + ALLEGRO_DISPLAY* dpy = *(ALLEGRO_DISPLAY**) _al_vector_ref(dpys, i); + ALLEGRO_DISPLAY_OSX_WIN *osx_dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy; + + if (osx_dpy->cursor == cursor->cursor) { + _al_osx_change_cursor(osx_dpy, [NSCursor arrowCursor]); + } + } + + [cursor->cursor release]; + al_free(cursor); +} + +/* osx_set_mouse_cursor: + * change the mouse cursor for the active window to the cursor previously + * allocated by osx_create_mouse_cursor + */ +static bool osx_set_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_MOUSE_CURSOR *cursor) +{ + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display; + ALLEGRO_MOUSE_CURSOR_OSX *osxcursor = (ALLEGRO_MOUSE_CURSOR_OSX *)cursor; + + _al_osx_change_cursor(dpy, osxcursor->cursor); + + return true; +} + +/* osx_set_system_mouse_cursor: + * change the mouse cursor to one of the system default cursors. + * NOTE: Allegro defines four of these, but OS X has no dedicated "busy" or + * "question" cursors, so we just set an arrow in those cases. + */ +static bool osx_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +{ + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display; + NSCursor *requested_cursor = NULL; + + switch (cursor_id) { + case ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT: + requested_cursor = [NSCursor arrowCursor]; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE: + requested_cursor = [NSCursor operationNotAllowedCursor]; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT: + requested_cursor = [NSCursor IBeamCursor]; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N: + requested_cursor = [NSCursor resizeUpCursor]; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S: + requested_cursor = [NSCursor resizeDownCursor]; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E: + requested_cursor = [NSCursor resizeRightCursor]; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W: + requested_cursor = [NSCursor resizeLeftCursor]; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION: + requested_cursor = [NSCursor crosshairCursor]; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK: + requested_cursor = [NSCursor pointingHandCursor]; + break; + default: + return false; + } + + _al_osx_change_cursor(dpy, requested_cursor); + return true; +} + +/* (show|hide)_cursor: + Cursor show or hide. The same function works for both windowed and fullscreen. + */ +static bool show_cursor(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; + dpy->show_cursor = YES; + [NSCursor unhide]; + return true; +} + +static bool hide_cursor(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; + dpy->show_cursor = NO; + [NSCursor hide]; + return true; +} + +/* Call from main thread. */ +static bool acknowledge_resize_display_win_main_thread(ALLEGRO_DISPLAY *d) +{ + ASSERT_MAIN_THREAD(); + + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)d; + NSWindow* window = dpy->win; + NSRect frame = [window frame]; + NSRect content = [window contentRectForFrameRect: frame]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + content = [window convertRectToBacking: content]; +#endif + + /* At any moment when a window has been changed its size we either + * clear ALLEGRO_MAXIMIZED flag (e.g. resize was done by a human) + * or restore the flag back (at the end of live resize caused by zoom). + * Note: affects zoom:(id)sender (if you will debug it). + */ + if (!(d->flags & ALLEGRO_FULLSCREEN_WINDOW) && ![window isZoomed]) + d->flags &= ~ALLEGRO_MAXIMIZED; + else if (!(d->flags & ALLEGRO_MAXIMIZED)) + d->flags |= ALLEGRO_MAXIMIZED; + + d->w = NSWidth(content); + d->h = NSHeight(content); + + if (d->ogl_extras->backbuffer) { + _al_ogl_resize_backbuffer(d->ogl_extras->backbuffer, d->w, d->h); + } + setup_gl(d); + + return true; +} +/* Call from user thread */ +static bool acknowledge_resize_display_win(ALLEGRO_DISPLAY *d) { + ASSERT_USER_THREAD(); + dispatch_sync(dispatch_get_main_queue(), ^{ + acknowledge_resize_display_win_main_thread(d); + }); + return true; +} + +/* resize_display_win + * Change the size of the display by altering the window size or changing the screen mode + * This must be called from the User thread + */ +static bool resize_display_win(ALLEGRO_DISPLAY *d, int w, int h) +{ + ASSERT_USER_THREAD(); + /* Don't resize a fullscreen window */ + if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) { + return false; + } + bool __block rc; + dispatch_sync(dispatch_get_main_queue(), ^{ + rc = resize_display_win_main_thread(d, w, h); + }); + return rc; +} + +/* resize_display_win_main_thread +* Change the size of the display by altering the window size or changing the screen mode +* This must be called from the Main thread +*/ +static bool resize_display_win_main_thread(ALLEGRO_DISPLAY *d, int w, int h) +{ + ASSERT_MAIN_THREAD(); + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; + NSWindow* window = dpy->win; + NSRect current; + float scale_factor = 1.0; + NSRect content = NSMakeRect(0.0f, 0.0f, (float) w, (float) h); + + current = [window frame]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + content = [window convertRectFromBacking: content]; + if ([window respondsToSelector:@selector(backingScaleFactor)]) { + scale_factor = [window backingScaleFactor]; + } +#endif + + w = _ALLEGRO_MAX(w, MINIMUM_WIDTH / scale_factor); + h = _ALLEGRO_MAX(h, MINIMUM_HEIGHT / scale_factor); + + if (d->use_constraints) { + if (d->min_w > 0 && w < d->min_w) { + w = d->min_w; + } + if (d->min_h > 0 && h < d->min_h) { + h = d->min_h; + } + /* Don't use max. constraints when a window is maximized. */ + if (!(d->flags & ALLEGRO_MAXIMIZED)) { + if (d->max_w > 0 && w > d->max_w) { + w = d->max_w; + } + if (d->max_h > 0 && h > d->max_h) { + h = d->max_h; + } + } + } + + /* Set new width & height values to content rectangle + * before calling 'set_frame' below. + */ + content.size.width = w / scale_factor; + content.size.height = h / scale_factor; + + NSRect rc = [window frameRectForContentRect: content]; + rc.origin = current.origin; + [window setFrame: rc display: YES animate: NO]; + + clear_to_black(dpy->ctx); + return acknowledge_resize_display_win_main_thread(d); +} + +static bool resize_display_fs(ALLEGRO_DISPLAY *d, int w, int h) +{ + ALLEGRO_DEBUG("Resize full screen display to %d x %d\n", w, h); + bool success = true; + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + CFDictionaryRef current = CGDisplayCurrentMode(dpy->display_id); + CFNumberRef bps = (CFNumberRef) CFDictionaryGetValue(current, kCGDisplayBitsPerPixel); + int b; + CFNumberGetValue(bps, kCFNumberSInt32Type,&b); + CFDictionaryRef mode = CGDisplayBestModeForParameters(dpy->display_id, b, w, h, NULL); + [dpy->ctx clearDrawable]; + CGError err = CGDisplaySwitchToMode(dpy->display_id, mode); + success = (err == kCGErrorSuccess); +#else + CGDisplayModeRef current = CGDisplayCopyDisplayMode(dpy->display_id); + CFStringRef bps = CGDisplayModeCopyPixelEncoding(current); + CFRelease(current); + CGDisplayModeRef mode = NULL; + CFArrayRef modes = NULL; + int i; + + modes = CGDisplayCopyAllDisplayModes(dpy->display_id, NULL); + for (i = 0; i < CFArrayGetCount(modes); i++) { + CGDisplayModeRef try_mode = + (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); + + CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(try_mode); + + /* Found mode with matching size/colour depth */ + if ( w == (int)CGDisplayModeGetWidth(try_mode) && + h == (int)CGDisplayModeGetHeight(try_mode) && + CFStringCompare(pixel_encoding, bps, 1) == 0) { + mode = try_mode; + CFRelease(pixel_encoding); + break; + } + + CFRelease(pixel_encoding); + } + CFRelease(bps); + CFRelease(modes); + if (!mode) { + ALLEGRO_DEBUG("Can't resize fullscreen display\n"); + + return false; + } + + /* Switch display mode */ + [dpy->ctx clearDrawable]; + CFDictionaryRef options = CFDictionaryCreate(NULL, NULL, NULL, 0, NULL, NULL); + CGDisplaySetDisplayMode(dpy->display_id, mode, NULL); + CFRelease(options); +#endif + d->w = w; + d->h = h; + [dpy->ctx setFullScreen]; + _al_ogl_resize_backbuffer(d->ogl_extras->backbuffer, d->w, d->h); + setup_gl(d); + return success; +} + +static bool is_compatible_bitmap(ALLEGRO_DISPLAY* disp, ALLEGRO_BITMAP* bmp) +{ + return (_al_get_bitmap_display(bmp) == disp) + || (((ALLEGRO_DISPLAY_OSX_WIN*) _al_get_bitmap_display(bmp))->display_group == ((ALLEGRO_DISPLAY_OSX_WIN*) disp)->display_group); +} + +/* set_window_position: + * Set the position of the window that owns this display + * Slightly complicated because Allegro measures from the top down to + * the top left corner, OS X from the bottom up to the bottom left corner. + * Call from user thread. + */ +static void set_window_position(ALLEGRO_DISPLAY* display, int x, int y) +{ + ASSERT_USER_THREAD(); + ALLEGRO_DISPLAY_OSX_WIN* d = (ALLEGRO_DISPLAY_OSX_WIN*) display; + NSWindow* window = d->win; + + /* Set the frame on the main thread. Because this is where + * the window's frame was initially set, this is where it should be + * modified too. + */ + dispatch_sync(dispatch_get_main_queue(), ^{ + NSRect rc = [window frame]; + NSRect sc = [[window screen] frame]; + rc.origin.x = (float) x; + rc.origin.y = sc.size.height - rc.size.height - ((float) y); + [window setFrame: rc display: YES animate: NO]; + }); +} + +/* get_window_position: + * Get the position of the window that owns this display. See comment for + * set_window_position. + * Call from user thread. + */ +static void get_window_position(ALLEGRO_DISPLAY* display, int* px, int* py) +{ + ASSERT_USER_THREAD(); + ALLEGRO_DISPLAY_OSX_WIN* d = (ALLEGRO_DISPLAY_OSX_WIN*) display; + NSWindow* window = d->win; + dispatch_sync(dispatch_get_main_queue(), ^{ + NSRect rc = [window frame]; + NSRect sc = [[window screen] frame]; + *px = (int) rc.origin.x; + *py = (int) (sc.size.height - rc.origin.y - rc.size.height); + }); +} + +static bool set_window_constraints(ALLEGRO_DISPLAY* display, + int min_w, int min_h, int max_w, int max_h) +{ + if (min_w > 0 && min_w < MINIMUM_WIDTH) { + min_w = MINIMUM_WIDTH; + } + if (min_h > 0 && min_h < MINIMUM_HEIGHT) { + min_h = MINIMUM_HEIGHT; + } + + display->min_w = min_w; + display->min_h = min_h; + display->max_w = max_w; + display->max_h = max_h; + + return true; +} + +static bool get_window_constraints(ALLEGRO_DISPLAY* display, + int* min_w, int* min_h, int* max_w, int* max_h) +{ + *min_w = display->min_w; + *min_h = display->min_h; + *max_w = display->max_w; + *max_h = display->max_h; + + return true; +} +/* apply_window_constraints: + * Tell Cocoa about new window min/max size. + * Resize the window if needed. + * Call from user thread. + */ +static void apply_window_constraints(ALLEGRO_DISPLAY *display, + bool onoff) +{ + ASSERT_USER_THREAD(); + ALLEGRO_DISPLAY_OSX_WIN* d = (ALLEGRO_DISPLAY_OSX_WIN*) display; + + NSWindow* window = d->win; + float __block scale_factor = 1.0; + NSSize max_size; + NSSize min_size; + dispatch_sync(dispatch_get_main_queue(), ^{ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + if ([window respondsToSelector:@selector(backingScaleFactor)]) { + scale_factor = [window backingScaleFactor]; + } +#endif + }); + if (onoff) { + min_size.width = display->min_w / scale_factor; + min_size.height = display->min_h / scale_factor; + + if (display->max_w > 0) + max_size.width = display->max_w / scale_factor; + else + max_size.width = FLT_MAX; + + if (display->max_h > 0) + max_size.height = display->max_h / scale_factor; + else + max_size.height = FLT_MAX; + + al_resize_display(display, display->w, display->h); + } + else { + min_size.width = MINIMUM_WIDTH / scale_factor; + min_size.height = MINIMUM_HEIGHT / scale_factor; + max_size.width = FLT_MAX; + max_size.height = FLT_MAX; + } + dispatch_sync(dispatch_get_main_queue(), ^{ + [window setContentMaxSize:max_size]; + [window setContentMinSize:min_size]; + }); +} + +/* set_window_title: + * Set the title of the window with this display + * Call from user thread + */ +static void set_window_title(ALLEGRO_DISPLAY *display, const char *title) +{ + ASSERT_USER_THREAD(); + ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) display; + NSString* string = [[NSString alloc] initWithUTF8String:title]; + [dpy->win performSelectorOnMainThread:@selector(setTitle:) withObject:string waitUntilDone:YES]; + [string release]; +} + +/* set_icons: + * Set the icon - OS X doesn't have per-window icons so + * ignore the display parameter + * Call from user thread + */ +static void set_icons(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP* bitmaps[]) +{ + ASSERT_USER_THREAD(); + /* Multiple icons not yet implemented. */ + ALLEGRO_BITMAP *bitmap = bitmaps[num_icons - 1]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSImage *image = NSImageFromAllegroBitmap(bitmap); + (void)display; + [NSApp performSelectorOnMainThread: @selector(setApplicationIconImage:) + withObject: image + waitUntilDone: YES]; + [image release]; + [pool drain]; +} + +/* set_display_flag: + * Change settings for an already active display + * Call from user thread. + */ +static bool set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) +{ + ASSERT_USER_THREAD(); +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + return false; +#else + if (!display) + return false; + + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)display; + ALWindow *win = dpy->win; + + if (!win) + return false; + bool __block retcode = true; + dispatch_sync(dispatch_get_main_queue(), ^{ + NSWindowStyleMask mask = [win styleMask]; + ALOpenGLView *view = (ALOpenGLView *)[win contentView]; + switch (flag) { + case ALLEGRO_FRAMELESS: + if (onoff) + display->flags |= ALLEGRO_FRAMELESS; + else + display->flags &= ~ALLEGRO_FRAMELESS; + /* BUGS: + - This causes the keyboard focus to be lost. + - On 10.10, disabling the frameless mode causes the title bar to be partially drawn + (resizing the window makes it appear again). + */ + ALLEGRO_DEBUG("Toggle FRAME for display %p to %d\n", dpy, onoff); + if (onoff) + mask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable); + else + mask |= NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable; + NSString *title = [win title]; + [win setStyleMask:mask]; + /* When going from frameless to frameful, the title gets reset, so we have to manually put it back. */ + [win setTitle:title]; + break; + case ALLEGRO_RESIZABLE: + ALLEGRO_DEBUG("Toggle RESIZABLE for display %p to %d\n", dpy, onoff); + if (onoff) { + display->flags |= ALLEGRO_RESIZABLE; + mask |= NSWindowStyleMaskResizable; + } else { + display->flags &= ~ALLEGRO_RESIZABLE; + mask &= ~NSWindowStyleMaskResizable; + } + [win setStyleMask:mask]; + break; + case ALLEGRO_MAXIMIZED: + retcode= true; + if ((!!(display->flags & ALLEGRO_MAXIMIZED)) == onoff) + break; + if (onoff) + display->flags |= ALLEGRO_MAXIMIZED; + else + display->flags &= ~ALLEGRO_MAXIMIZED; + [[win contentView] maximize]; + break; + case ALLEGRO_FULLSCREEN_WINDOW: + if (onoff) { + [view enterFullScreenWindowMode]; + NSRect sc = [[win screen] frame]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + sc = [win convertRectToBacking: sc]; +#endif + resize_display_win_main_thread(display, sc.size.width, sc.size.height); + display->flags |= ALLEGRO_FULLSCREEN_WINDOW; + } else { + [view exitFullScreenWindowMode]; + NSRect sc = [view frame]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + sc = [win convertRectToBacking: sc]; +#endif + display->flags &= ~ALLEGRO_FULLSCREEN_WINDOW; + resize_display_win(display, sc.size.width, sc.size.height); + [view finishExitingFullScreenWindowMode]; + } + break; + default: + retcode = false; + break; + } + }); + return retcode; +#endif +} + +ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_win(void) +{ + static ALLEGRO_DISPLAY_INTERFACE* vt = NULL; + if (vt == NULL) { + vt = al_malloc(sizeof(*vt)); + memset(vt, 0, sizeof(ALLEGRO_DISPLAY_INTERFACE)); + vt->create_display = create_display_win; + vt->destroy_display = destroy_display; + vt->set_current_display = set_current_display; + vt->flip_display = flip_display; + vt->update_display_region = update_display_region; + vt->resize_display = resize_display_win; + vt->acknowledge_resize = acknowledge_resize_display_win; + vt->create_bitmap = _al_ogl_create_bitmap; + vt->set_target_bitmap = _al_ogl_set_target_bitmap; + vt->get_backbuffer = _al_ogl_get_backbuffer; + vt->is_compatible_bitmap = is_compatible_bitmap; + vt->show_mouse_cursor = show_cursor; + vt->hide_mouse_cursor = hide_cursor; + vt->set_mouse_cursor = osx_set_mouse_cursor; + vt->set_system_mouse_cursor = osx_set_system_mouse_cursor; + vt->get_window_position = get_window_position; + vt->set_window_position = set_window_position; + vt->get_window_constraints = get_window_constraints; + vt->set_window_constraints = set_window_constraints; + vt->apply_window_constraints = apply_window_constraints; + vt->set_window_title = set_window_title; + vt->set_display_flag = set_display_flag; + vt->set_icons = set_icons; + vt->update_render_state = _al_ogl_update_render_state; + _al_ogl_add_drawing_functions(vt); + _al_osx_add_clipboard_functions(vt); + } + return vt; +} + +ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver_fs(void) +{ + static ALLEGRO_DISPLAY_INTERFACE* vt = NULL; + if (vt == NULL) { + vt = al_malloc(sizeof(*vt)); + memset(vt, 0, sizeof(ALLEGRO_DISPLAY_INTERFACE)); + vt->create_display = create_display_fs; + vt->destroy_display = destroy_display; + vt->set_current_display = set_current_display; + vt->flip_display = flip_display; + vt->resize_display = resize_display_fs; + vt->create_bitmap = _al_ogl_create_bitmap; + vt->set_target_bitmap = _al_ogl_set_target_bitmap; + vt->show_mouse_cursor = show_cursor; + vt->hide_mouse_cursor = hide_cursor; + vt->set_mouse_cursor = osx_set_mouse_cursor; + vt->set_system_mouse_cursor = osx_set_system_mouse_cursor; + vt->get_backbuffer = _al_ogl_get_backbuffer; + vt->is_compatible_bitmap = is_compatible_bitmap; + vt->update_render_state = _al_ogl_update_render_state; + _al_ogl_add_drawing_functions(vt); + } + return vt; +} + +/* Mini VT just for creating displays */ +ALLEGRO_DISPLAY_INTERFACE* _al_osx_get_display_driver(void) +{ + static ALLEGRO_DISPLAY_INTERFACE* vt = NULL; + if (vt == NULL) { + vt = al_malloc(sizeof(*vt)); + memset(vt, 0, sizeof(ALLEGRO_DISPLAY_INTERFACE)); + vt->create_display = create_display; + } + return vt; +} + +/* Function: al_osx_get_window + */ +NSWindow* al_osx_get_window(ALLEGRO_DISPLAY *display) +{ + if (!display) + return NULL; + return ((ALLEGRO_DISPLAY_OSX_WIN *)display)->win; +} diff --git a/allegro/src/macosx/qzmouse.m b/allegro/src/macosx/qzmouse.m new file mode 100644 index 00000000..75799408 --- /dev/null +++ b/allegro/src/macosx/qzmouse.m @@ -0,0 +1,445 @@ +/* ______ ___ ___ +* /\ _ \ /\_ \ /\_ \ +* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ +* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ +* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ +* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ +* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ +* /\____/ +* \_/__/ +* +* MacOS X mouse driver. +* +* By Angelo Mottola. +* +* Modified for 4.9 mouse API by Peter Hull. +* +* See readme.txt for copyright information. +*/ + + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/platform/aintosx.h" +#include "./osxgl.h" +#ifndef ALLEGRO_MACOSX +#error Something is wrong with the makefile +#endif + +ALLEGRO_DEBUG_CHANNEL("MacOSX"); + +typedef struct ALLEGRO_MOUSE AL_MOUSE; +typedef struct ALLEGRO_MOUSE_STATE AL_MOUSE_STATE; + +static bool osx_init_mouse(void); +static unsigned int osx_get_mouse_num_buttons(void); +static unsigned int osx_get_mouse_num_axes(void); +static bool osx_set_mouse_axis(int axis, int value); +static ALLEGRO_MOUSE* osx_get_mouse(void); + +/* Mouse info - includes extra info for OS X */ +static struct { + ALLEGRO_MOUSE parent; + unsigned int button_count; + unsigned int axis_count; + int minx, miny, maxx, maxy; + ALLEGRO_MOUSE_STATE state; + float z_axis, w_axis; + BOOL warped; + int warped_x, warped_y; + NSCursor* cursor; +} osx_mouse; + +void _al_osx_clear_mouse_state(void) +{ + memset(&osx_mouse.state, 0, sizeof(ALLEGRO_MOUSE_STATE)); +} + +/* _al_osx_switch_keyboard_focus: + * Handle a focus switch event. + */ +void _al_osx_switch_mouse_focus(ALLEGRO_DISPLAY *dpy, bool switch_in) +{ + _al_event_source_lock(&osx_mouse.parent.es); + + if (switch_in) + osx_mouse.state.display = dpy; + else + osx_mouse.state.display = NULL; + + _al_event_source_unlock(&osx_mouse.parent.es); +} + +/* osx_get_mouse: +* Return the Allegro mouse structure +*/ +static ALLEGRO_MOUSE* osx_get_mouse(void) +{ + return (ALLEGRO_MOUSE*) &osx_mouse.parent; +} + +/* _al_osx_mouse_generate_event: +* Convert an OS X mouse event to an Allegro event +* and push it into a queue. +* First check that the event is wanted. +*/ +void _al_osx_mouse_generate_event(NSEvent* evt, ALLEGRO_DISPLAY* dpy) +{ + NSPoint pos; + int type, b_change = 0, b = 0; + float pressure = 0.0; + float dx = 0, dy = 0, dz = 0, dw = 0; + switch ([evt type]) + { + case NSMouseMoved: + type = ALLEGRO_EVENT_MOUSE_AXES; + dx = [evt deltaX]; + dy = [evt deltaY]; + pressure = [evt pressure]; + break; + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + type = ALLEGRO_EVENT_MOUSE_AXES; + b = [evt buttonNumber]+1; + dx = [evt deltaX]; + dy = [evt deltaY]; + pressure = [evt pressure]; + break; + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; + b = [evt buttonNumber]+1; + b_change = 1; + osx_mouse.state.buttons |= (1 << (b-1)); + pressure = [evt pressure]; + break; + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; + b = [evt buttonNumber]+1; + b_change = 1; + osx_mouse.state.buttons &= ~(1 << (b-1)); + pressure = [evt pressure]; + break; + case NSScrollWheel: + type = ALLEGRO_EVENT_MOUSE_AXES; + dx = 0; + dy = 0; + osx_mouse.w_axis += al_get_mouse_wheel_precision() * [evt deltaX]; + osx_mouse.z_axis += al_get_mouse_wheel_precision() * [evt deltaY]; + dw = osx_mouse.w_axis - osx_mouse.state.w; + dz = osx_mouse.z_axis - osx_mouse.state.z; + break; + case NSMouseEntered: + type = ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY; + b = [evt buttonNumber]+1; + dx = [evt deltaX]; + dy = [evt deltaY]; + break; + case NSMouseExited: + type = ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY; + b = [evt buttonNumber]+1; + dx = [evt deltaX]; + dy = [evt deltaY]; + break; + default: + return; + } + pos = [evt locationInWindow]; + BOOL within = true; + float scaling_factor = 1.0; + if ([evt window]) + { + NSRect frm = [[[evt window] contentView] frame]; + within = NSMouseInRect(pos, frm, NO); + // Y-coordinates in OS X start from the bottom. + pos.y = NSHeight(frm) - pos.y; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + scaling_factor = [[evt window] backingScaleFactor]; +#endif + } + else + { + pos.y = [[NSScreen mainScreen] frame].size.height - pos.y; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + scaling_factor = [[NSScreen mainScreen] backingScaleFactor]; +#endif + } + dx *= scaling_factor; + dy *= scaling_factor; + if (osx_mouse.warped && type == ALLEGRO_EVENT_MOUSE_AXES) { + dx -= osx_mouse.warped_x; + dy -= osx_mouse.warped_y; + osx_mouse.warped = FALSE; + } + _al_event_source_lock(&osx_mouse.parent.es); + if ((within || b_change || type == ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY) + && _al_event_source_needs_to_generate_event(&osx_mouse.parent.es)) + { + ALLEGRO_EVENT new_event; + ALLEGRO_MOUSE_EVENT* mouse_event = &new_event.mouse; + mouse_event->type = type; + // Note: we use 'allegro time' rather than the time stamp + // from the event + mouse_event->timestamp = al_get_time(); + mouse_event->display = dpy; + mouse_event->button = b; + mouse_event->x = pos.x * scaling_factor; + mouse_event->y = pos.y * scaling_factor; + mouse_event->z = osx_mouse.z_axis; + mouse_event->w = osx_mouse.w_axis; + mouse_event->dx = dx; + mouse_event->dy = dy; + mouse_event->dz = dz; + mouse_event->dw = dw; + mouse_event->pressure = pressure; + _al_event_source_emit_event(&osx_mouse.parent.es, &new_event); + } + // Record current state + osx_mouse.state.x = pos.x * scaling_factor; + osx_mouse.state.y = pos.y * scaling_factor; + osx_mouse.state.w = osx_mouse.w_axis; + osx_mouse.state.z = osx_mouse.z_axis; + osx_mouse.state.pressure = pressure; + _al_event_source_unlock(&osx_mouse.parent.es); +} + +/* osx_init_mouse: +* Initializes the driver. +*/ +static bool osx_init_mouse(void) +{ + /* NOTE: This function is deprecated, however until we have a better fix + * or it is removed, we can used it. The problem without calling this + * function is that after synthesizing events (as with al_set_mouse_xy) + * there is an unacceptably long delay in receiving new events (mouse + * locks up for about 0.5 seconds.) + */ + CGSetLocalEventsSuppressionInterval(0.0); + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + HID_DEVICE_COLLECTION devices={0,0,NULL}; + int i = 0, j = 0; + int axes = 0, buttons = 0; + int max_axes = 0, max_buttons = 0; + HID_DEVICE* device = nil; + NSString* desc = nil; + + _al_osx_hid_scan(HID_MOUSE, &devices); + ALLEGRO_INFO("Detected %d pointing devices\n", devices.count); + for (i=0; imanufacturer ? device->manufacturer : "", + device->product ? device->product : ""]; + ALLEGRO_INFO("Device %d is a \"%s\"\n", i, [desc UTF8String]); + + for (j = 0; j < device->num_elements; j++) { + switch (device->element[j].type) { + case HID_ELEMENT_BUTTON: + buttons++; + break; + case HID_ELEMENT_AXIS: + case HID_ELEMENT_AXIS_PRIMARY_X: + case HID_ELEMENT_AXIS_PRIMARY_Y: + case HID_ELEMENT_STANDALONE_AXIS: + axes ++; + break; + } + } + ALLEGRO_INFO("Detected %d axes and %d buttons\n", axes, buttons); + + /* When mouse events reach the application, it is not clear which + * device generated them, so effectively the largest number of + * buttons and axes reported corresponds to the device that the + * application "sees" + */ + if (axes > max_axes) max_axes = axes; + if (buttons > max_buttons) max_buttons = buttons; + } + _al_osx_hid_free(&devices); + ALLEGRO_INFO("Device effectively has %d axes and %d buttons\n", axes, buttons); + + if (max_buttons <= 0) return false; + _al_event_source_init(&osx_mouse.parent.es); + osx_mouse.button_count = max_buttons; + osx_mouse.axis_count = max_axes; + osx_mouse.warped = FALSE; + memset(&osx_mouse.state, 0, sizeof(ALLEGRO_MOUSE_STATE)); + _al_osx_mouse_was_installed(YES); + [pool drain]; + return true; +} + +/* osx_exit_mouse: +* Shut down the mouse driver +*/ +static void osx_exit_mouse(void) +{ + _al_osx_mouse_was_installed(NO); +} + +/* osx_get_mouse_num_buttons: +* Return the number of buttons on the mouse +*/ +static unsigned int osx_get_mouse_num_buttons(void) +{ + return osx_mouse.button_count; +} + +/* osx_get_mouse_num_buttons: +* Return the number of buttons on the mouse +*/ +static unsigned int osx_get_mouse_num_axes(void) +{ + return osx_mouse.axis_count; +} + + +static void osx_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + _al_event_source_lock(&osx_mouse.parent.es); + memcpy(ret_state, &osx_mouse.state, sizeof(ALLEGRO_MOUSE_STATE)); + _al_event_source_unlock(&osx_mouse.parent.es); +} + +/* osx_set_mouse_xy: +* Set the current mouse position +*/ +static bool osx_set_mouse_xy(ALLEGRO_DISPLAY *dpy_, int x, int y) +{ + CGPoint pos; + CGDirectDisplayID display = 0; + ALLEGRO_DISPLAY_OSX_WIN *dpy = (ALLEGRO_DISPLAY_OSX_WIN *)dpy_; + float scaling_factor = 1.0; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + scaling_factor = [[NSScreen mainScreen] backingScaleFactor]; +#endif + x /= scaling_factor; + y /= scaling_factor; + + if ((dpy) && !(dpy->parent.flags & ALLEGRO_FULLSCREEN) && + !(dpy->parent.flags & ALLEGRO_FULLSCREEN_WINDOW) && (dpy->win)) { + NSWindow *window = dpy->win; + NSRect content = [window contentRectForFrameRect: [window frame]]; + NSRect frame = [[window screen] frame]; + CGRect rect = { { NSMinX(frame), NSMinY(frame) }, { NSWidth(frame), NSHeight(frame) } }; + CGDirectDisplayID displays[16]; + CGDisplayCount displayCount; + + if ((CGGetDisplaysWithRect(rect, 16, displays, &displayCount) == 0) && (displayCount >= 1)) + display = displays[0]; + + CGPoint point_pos = CGPointMake(x, y); +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + point_pos = NSPointToCGPoint([[window contentView] convertPointFromBacking: NSPointFromCGPoint(point_pos)]); +#endif + pos.x = content.origin.x + point_pos.x; + pos.y = rect.size.height - content.origin.y - content.size.height + point_pos.y; + } + else { + if (dpy) + display = dpy->display_id; + pos.x = x; + pos.y = y; + } + + _al_event_source_lock(&osx_mouse.parent.es); + if (_al_event_source_needs_to_generate_event(&osx_mouse.parent.es)) { + ALLEGRO_EVENT new_event; + ALLEGRO_MOUSE_EVENT* mouse_event = &new_event.mouse; + mouse_event->type = ALLEGRO_EVENT_MOUSE_WARPED; + // Note: we use 'allegro time' rather than the time stamp + // from the event + mouse_event->timestamp = al_get_time(); + mouse_event->display = (ALLEGRO_DISPLAY *)dpy; + mouse_event->button = 0; + mouse_event->x = x; + mouse_event->y = y; + mouse_event->z = osx_mouse.z_axis; + mouse_event->dx = x - osx_mouse.state.x; + mouse_event->dy = y - osx_mouse.state.y; + mouse_event->dz = 0; + mouse_event->pressure = osx_mouse.state.pressure; + if (mouse_event->dx || mouse_event->dy) { + osx_mouse.warped = TRUE; + osx_mouse.warped_x = mouse_event->dx; + osx_mouse.warped_y = mouse_event->dy; + _al_event_source_emit_event(&osx_mouse.parent.es, &new_event); + } + } + CGDisplayMoveCursorToPoint(display, pos); + osx_mouse.state.x = x; + osx_mouse.state.y = y; + _al_event_source_unlock(&osx_mouse.parent.es); + return true; +} + +/* osx_set_mouse_axis: +* Set the axis value of the mouse +*/ +static bool osx_set_mouse_axis(int axis, int value) +{ + bool result = false; + _al_event_source_lock(&osx_mouse.parent.es); + switch (axis) + { + case 0: + case 1: + // By design, this doesn't apply to (x, y) + break; + case 2: + osx_mouse.z_axis = value; + result = true; + break; + case 3: + osx_mouse.w_axis = value; + result = true; + break; + } + /* XXX generate an event if the axis value changed */ + _al_event_source_unlock(&osx_mouse.parent.es); + return result; +} +/* Mouse driver */ +static ALLEGRO_MOUSE_DRIVER osx_mouse_driver = +{ + 0, //int msedrv_id; + "OSXMouse", //const char *msedrv_name; + "Driver for Mac OS X",// const char *msedrv_desc; + "OSX Mouse", //const char *msedrv_ascii_name; + osx_init_mouse, //AL_METHOD(bool, init_mouse, (void)); + osx_exit_mouse, //AL_METHOD(void, exit_mouse, (void)); + osx_get_mouse, //AL_METHOD(ALLEGRO_MOUSE*, get_mouse, (void)); + osx_get_mouse_num_buttons, //AL_METHOD(unsigned int, get_mouse_num_buttons, (void)); + osx_get_mouse_num_axes, //AL_METHOD(unsigned int, get_mouse_num_axes, (void)); + osx_set_mouse_xy, //AL_METHOD(bool, set_mouse_xy, (int x, int y)); + osx_set_mouse_axis, //AL_METHOD(bool, set_mouse_axis, (int which, int value)); + osx_get_mouse_state, //AL_METHOD(void, get_mouse_state, (ALLEGRO_MOUSE_STATE *ret_state)); +}; +ALLEGRO_MOUSE_DRIVER* _al_osx_get_mouse_driver(void) +{ + return &osx_mouse_driver; +} + +/* list the available drivers */ +_AL_DRIVER_INFO _al_mouse_driver_list[] = +{ + { 1, &osx_mouse_driver, 1 }, + { 0, NULL, 0 } +}; + +/* Local variables: */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/allegro/src/macosx/system.m b/allegro/src/macosx/system.m new file mode 100644 index 00000000..311491df --- /dev/null +++ b/allegro/src/macosx/system.m @@ -0,0 +1,675 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * MacOS X system driver. + * + * By Angelo Mottola. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/platform/aintosx.h" +#include "allegro5/internal/aintern_osxclipboard.h" +#include + +#ifndef ALLEGRO_MACOSX + #error something is wrong with the makefile +#endif + +#import +#include +#include +#include + +ALLEGRO_DEBUG_CHANNEL("MacOSX") + +/* These are used to warn the dock about the application */ +struct CPSProcessSerNum +{ + UInt32 lo; + UInt32 hi; +}; +extern OSErr CPSGetCurrentProcess(struct CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation(struct CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess(struct CPSProcessSerNum *psn); +typedef struct THREAD_AND_POOL { + ALLEGRO_THREAD *thread; +} THREAD_AND_POOL; + + + +static ALLEGRO_SYSTEM* osx_sys_init(int flags); +ALLEGRO_SYSTEM_INTERFACE *_al_system_osx_driver(void); +static void osx_sys_exit(void); + + +/* Global variables */ +NSBundle *_al_osx_bundle = NULL; +static _AL_VECTOR osx_display_modes; +static ALLEGRO_SYSTEM osx_system; +_AL_VECTOR _osx_threads = _AL_VECTOR_INITIALIZER(THREAD_AND_POOL *); + +/* osx_tell_dock: + * Tell the dock about us; promote us from a console app to a graphical app + * with dock icon and menu + */ +static void osx_tell_dock(void) +{ + ProcessSerialNumber psn = { 0, kCurrentProcess }; + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + [[NSApplication sharedApplication] performSelectorOnMainThread: @selector(activateIgnoringOtherApps:) + withObject: [NSNumber numberWithBool:YES] + waitUntilDone: YES]; +} + + + +/* _al_osx_bootstrap_ok: + * Check if the current bootstrap context is privilege. If it's not, we can't + * use NSApplication, and instead have to go directly to main. + * Returns 1 if ok, 0 if not. + */ +#ifdef OSX_BOOTSTRAP_DETECTION +int _al_osx_bootstrap_ok(void) +{ + static int _ok = -1; + mach_port_t bp; + kern_return_t ret; + CFMachPortRef cfport; + + /* If have tested once, just return that answer */ + if (_ok >= 0) + return _ok; + cfport = CFMachPortCreate(NULL, NULL, NULL, NULL); + task_get_bootstrap_port(mach_task_self(), &bp); + ret = bootstrap_register(bp, "bootstrap-ok-test", CFMachPortGetPort(cfport)); + CFRelease(cfport); + _ok = (ret == KERN_SUCCESS) ? 1 : 0; + return _ok; +} +#endif + + + +/* osx_sys_init: + * Initalizes the MacOS X system driver. + */ +static ALLEGRO_SYSTEM* osx_sys_init(int flags) +{ + (void)flags; + +#ifdef OSX_BOOTSTRAP_DETECTION + /* If we're in the 'dead bootstrap' environment, the Mac driver won't work. */ + if (!_al_osx_bootstrap_ok()) { + return NULL; + } +#endif + /* Initialise the vt and display list */ + osx_system.vt = _al_system_osx_driver(); + _al_vector_init(&osx_system.displays, sizeof(ALLEGRO_DISPLAY*)); + + if (_al_osx_bundle == NULL) { + /* If in a bundle, the dock will recognise us automatically */ + osx_tell_dock(); + } + + /* Mark the beginning of time. */ + _al_unix_init_time(); + + _al_vector_init(&osx_display_modes, sizeof(ALLEGRO_DISPLAY_MODE)); + + ALLEGRO_DEBUG("system driver initialised.\n"); + return &osx_system; +} + + + +/* osx_sys_exit: + * Shuts down the system driver. + */ +static void osx_sys_exit(void) +{ + _al_vector_free(&osx_display_modes); + ALLEGRO_DEBUG("system driver shutdown.\n"); +} + + + +/* + * _al_osx_get_num_display_modes: + * Gets the number of available display modes + */ +static int _al_osx_get_num_display_modes(void) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras = _al_get_new_display_settings(); + ALLEGRO_EXTRA_DISPLAY_SETTINGS temp; + int refresh_rate = al_get_new_display_refresh_rate(); + int adapter = al_get_new_display_adapter(); + int depth = 0; + CGDirectDisplayID display; + CFArrayRef modes; + CFIndex i; + + if (extras) + depth = extras->settings[ALLEGRO_COLOR_SIZE]; + memset(&temp, 0, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); + + display = CGMainDisplayID(); + /* Get display ID for the requested display */ + if (adapter > 0) { + NSScreen *screen = [[NSScreen screens] objectAtIndex: adapter]; + NSDictionary *dict = [screen deviceDescription]; + NSNumber *display_id = [dict valueForKey: @"NSScreenNumber"]; + + /* FIXME (how?): in 64 bit-mode, this generates a warning, because + * CGDirectDisplayID is apparently 32 bit whereas a pointer is 64 + * bit. Considering that a CGDirectDisplayID is supposed to be a + * pointer as well (according to the documentation available on-line) + * it is not quite clear what the correct way to do this would be. + */ + display = (CGDirectDisplayID) [display_id pointerValue]; + } + + _al_vector_free(&osx_display_modes); +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + /* Note: modes is owned by OSX and must not be released */ + modes = CGDisplayAvailableModes(display); + ALLEGRO_INFO("detected %d display modes.\n", (int)CFArrayGetCount(modes)); + for (i = 0; i < CFArrayGetCount(modes); i++) { + ALLEGRO_DISPLAY_MODE *mode; + CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(modes, i); + CFNumberRef number; + int value, samples; + + number = CFDictionaryGetValue(dict, kCGDisplayBitsPerPixel); + CFNumberGetValue(number, kCFNumberIntType, &value); + ALLEGRO_INFO("Mode %d has colour depth %d.\n", (int)i, value); + if (depth && value != depth) { + ALLEGRO_WARN("Skipping mode %d (requested colour depth %d).\n", (int)i, depth); + continue; + } + + number = CFDictionaryGetValue(dict, kCGDisplayRefreshRate); + CFNumberGetValue(number, kCFNumberIntType, &value); + ALLEGRO_INFO("Mode %d has colour depth %d.\n", (int)i, value); + if (refresh_rate && value != refresh_rate) { + ALLEGRO_WARN("Skipping mode %d (requested refresh rate %d).\n", (int)i, refresh_rate); + continue; + } + + mode = (ALLEGRO_DISPLAY_MODE *)_al_vector_alloc_back(&osx_display_modes); + number = CFDictionaryGetValue(dict, kCGDisplayWidth); + CFNumberGetValue(number, kCFNumberIntType, &mode->width); + number = CFDictionaryGetValue(dict, kCGDisplayHeight); + CFNumberGetValue(number, kCFNumberIntType, &mode->height); + number = CFDictionaryGetValue(dict, kCGDisplayRefreshRate); + CFNumberGetValue(number, kCFNumberIntType, &mode->refresh_rate); + ALLEGRO_INFO("Mode %d is %dx%d@%dHz\n", (int)i, mode->width, mode->height, mode->refresh_rate); + + number = CFDictionaryGetValue(dict, kCGDisplayBitsPerPixel); + CFNumberGetValue(number, kCFNumberIntType, &temp.settings[ALLEGRO_COLOR_SIZE]); + number = CFDictionaryGetValue(dict, kCGDisplaySamplesPerPixel); + CFNumberGetValue(number, kCFNumberIntType, &samples); + number = CFDictionaryGetValue(dict, kCGDisplayBitsPerSample); + CFNumberGetValue(number, kCFNumberIntType, &value); + ALLEGRO_INFO("Mode %d has %d bits per pixel, %d samples per pixel and %d bits per sample\n", + (int)i, temp.settings[ALLEGRO_COLOR_SIZE], samples, value); + if (samples >= 3) { + temp.settings[ALLEGRO_RED_SIZE] = value; + temp.settings[ALLEGRO_GREEN_SIZE] = value; + temp.settings[ALLEGRO_BLUE_SIZE] = value; + if (samples == 4) + temp.settings[ALLEGRO_ALPHA_SIZE] = value; + } + _al_fill_display_settings(&temp); + mode->format = _al_deduce_color_format(&temp); + } +#else + modes = CGDisplayCopyAllDisplayModes(display, NULL); + ALLEGRO_INFO("detected %d display modes.\n", (int)CFArrayGetCount(modes)); + for (i = 0; i < CFArrayGetCount(modes); i++) { + ALLEGRO_DISPLAY_MODE *amode; + CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i); + CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(mode); + + int bpp = 0, mode_refresh_rate, samples = 0, value = 0; + + /* Determine pixel format. Whever thought this was a better idea than + * having query functions for each of these properties should be + * spoken to very harshly in a very severe voice. + */ + + if (CFStringCompare(pixel_encoding, CFSTR(kIO16BitFloatPixels), 1) == 0) { + bpp = 64; + samples = 3; + value = 16; + } + + if (CFStringCompare(pixel_encoding, CFSTR(kIO32BitFloatPixels), 1) == 0) { + bpp = 128; + samples = 3; + value = 32; + } + + if (CFStringCompare(pixel_encoding, CFSTR(kIO64BitDirectPixels), 1) == 0) { + bpp = 64; + samples = 3; + value = 16; + } + + if (CFStringCompare(pixel_encoding, CFSTR(kIO30BitDirectPixels), 1) == 0) { + bpp = 32; + samples = 3; + value = 10; + } + + if (CFStringCompare(pixel_encoding, CFSTR(IO32BitDirectPixels), 1) == 0) { + bpp = 32; + samples = 3; + value = 8; + } + + if (CFStringCompare(pixel_encoding, CFSTR(IO16BitDirectPixels), 1) == 0) { + bpp = 16; + samples = 3; + value = 5; + } + + if (CFStringCompare(pixel_encoding, CFSTR(IO8BitIndexedPixels), 1) == 0) { + bpp = 8; + samples = 1; + value = 8; + } + CFRelease(pixel_encoding); + + /* Check if this mode is ok in terms of depth and refresh rate */ + ALLEGRO_INFO("Mode %d has colour depth %d.\n", (int)i, bpp); + if (depth && bpp != depth) { + ALLEGRO_WARN("Skipping mode %d (requested colour depth %d).\n", (int)i, depth); + continue; + } + + mode_refresh_rate = CGDisplayModeGetRefreshRate(mode); + ALLEGRO_INFO("Mode %d has a refresh rate of %d.\n", (int)i, mode_refresh_rate); + if (refresh_rate && mode_refresh_rate != refresh_rate) { + ALLEGRO_WARN("Skipping mode %d (requested refresh rate %d).\n", (int)i, refresh_rate); + continue; + } + + /* Yes, it's fine */ + amode = (ALLEGRO_DISPLAY_MODE *)_al_vector_alloc_back(&osx_display_modes); + amode->width = CGDisplayModeGetWidth(mode); + amode->height = CGDisplayModeGetHeight(mode); + amode->refresh_rate = mode_refresh_rate; + ALLEGRO_INFO("Mode %d is %dx%d@%dHz\n", (int)i, amode->width, amode->height, amode->refresh_rate); + + temp.settings[ALLEGRO_COLOR_SIZE] = bpp; + ALLEGRO_INFO("Mode %d has %d bits per pixel, %d samples per pixel and %d bits per sample\n", + (int)i, temp.settings[ALLEGRO_COLOR_SIZE], samples, value); + if (samples >= 3) { + temp.settings[ALLEGRO_RED_SIZE] = value; + temp.settings[ALLEGRO_GREEN_SIZE] = value; + temp.settings[ALLEGRO_BLUE_SIZE] = value; + if (samples == 4) + temp.settings[ALLEGRO_ALPHA_SIZE] = value; + } + _al_fill_display_settings(&temp); + amode->format = _al_deduce_color_format(&temp); + } + CFRelease(modes); +#endif + return _al_vector_size(&osx_display_modes); +} + + + +/* + * _al_osx_get_num_display_modes: + * Gets the number of available display modes + */ +static ALLEGRO_DISPLAY_MODE *_al_osx_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode) +{ + if ((unsigned)index >= _al_vector_size(&osx_display_modes)) + return NULL; + memcpy(mode, _al_vector_ref(&osx_display_modes, index), sizeof(ALLEGRO_DISPLAY_MODE)); + return mode; +} + + + +/* osx_get_num_video_adapters: + * Return the number of video adapters i.e displays + */ +static int osx_get_num_video_adapters(void) +{ + NSArray *screen_list; + int num = 0; + + screen_list = [NSScreen screens]; + if (screen_list) + num = [screen_list count]; + + ALLEGRO_INFO("Detected %d displays\n", num); + return num; +} + +/* osx_get_monitor_info: + * Return the details of one monitor + */ +static bool osx_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO* info) +{ + int count = osx_get_num_video_adapters(); + if (adapter < count) { + NSScreen *screen = [[NSScreen screens] objectAtIndex: adapter]; + NSRect rc = [screen frame]; + rc = [screen convertRectToBacking: rc]; + info->x1 = (int) rc.origin.x; + info->x2 = (int) (rc.origin.x + rc.size.width); + info->y1 = (int) rc.origin.y; + info->y2 = (int) (rc.origin.y + rc.size.height); + ALLEGRO_INFO("Display %d has coordinates (%d, %d) - (%d, %d)\n", + adapter, info->x1, info->y1, info->x2, info->y2); + return true; + } + else { + return false; + } +/* + CGDisplayCount count; + // Assume no more than 16 monitors connected + static const int max_displays = 16; + CGDirectDisplayID displays[max_displays]; + CGError err = CGGetActiveDisplayList(max_displays, displays, &count); + if (err == kCGErrorSuccess && adapter >= 0 && adapter < (int) count) { + CGRect rc = CGDisplayBounds(displays[adapter]); + info->x1 = (int) rc.origin.x; + info->x2 = (int) (rc.origin.x + rc.size.width); + info->y1 = (int) rc.origin.y; + info->y2 = (int) (rc.origin.y + rc.size.height); + ALLEGRO_INFO("Display %d has coordinates (%d, %d) - (%d, %d)\n", + adapter, info->x1, info->y1, info->x2, info->y2); + return true; + } + else { + return false; + } +*/ +} + +/* osx_get_monitor_dpi: + * Return the dots per inch value of one monitor + */ +static int osx_get_monitor_dpi(int adapter) +{ + int count = osx_get_num_video_adapters(); + if (adapter < count) { + NSScreen *screen = [[NSScreen screens] objectAtIndex: adapter]; + NSRect rc = [screen frame]; + rc = [screen convertRectToBacking: rc]; + + NSDictionary *description = [screen deviceDescription]; + CGSize size = CGDisplayScreenSize([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]); + float dpi_hori = rc.size.width / (_AL_INCHES_PER_MM * size.width); + float dpi_vert = rc.size.height / (_AL_INCHES_PER_MM * size.height); + + return sqrt(dpi_hori * dpi_vert); + } + else { + return 0; + } +} + +/* osx_inhibit_screensaver: + * Stops the screen dimming/screen saver activation if inhibit is true + * otherwise re-enable normal behaviour. The last call takes force (i.e + * it does not count the calls to inhibit/uninhibit. + * Always returns true + */ +static bool osx_inhibit_screensaver(bool inhibit) +{ + // Send a message to the App's delegate always on the main thread + NSObject* delegate = [NSApp delegate]; + [delegate performSelectorOnMainThread: @selector(setInhibitScreenSaver:) + withObject: [NSNumber numberWithBool:inhibit ? YES : NO] + waitUntilDone: NO]; + ALLEGRO_INFO("Stop screensaver\n"); + return true; +} + +/* NSImageFromAllegroBitmap: + * Create an NSImage from an Allegro bitmap + * This could definitely be speeded up if necessary. + */ +NSImage* NSImageFromAllegroBitmap(ALLEGRO_BITMAP* bmp) +{ + int w = al_get_bitmap_width(bmp); + int h = al_get_bitmap_height(bmp); + NSImage* img = [[NSImage alloc] initWithSize: NSMakeSize((float) w, (float) h)]; + NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL // Allocate memory yourself + pixelsWide:w + pixelsHigh:h + bitsPerSample: 8 + samplesPerPixel: 4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow: 0 // Calculate yourself + bitsPerPixel:0 ];// Calculate yourself + al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + int x, y; + for (y = 0; y 1 */ +static bool osx_get_cursor_position(int *x, int *y) +{ + NSPoint p = [NSEvent mouseLocation]; + NSRect r = [[NSScreen mainScreen] frame]; + *x = p.x; + *y = r.size.height - p.y; + return true; +} + +static void osx_thread_init(ALLEGRO_THREAD *thread) +{ + THREAD_AND_POOL *tap = al_malloc(sizeof(THREAD_AND_POOL)); + + tap->thread = thread; + THREAD_AND_POOL **ptr = _al_vector_alloc_back(&_osx_threads); + *ptr = tap; +} + +static void osx_thread_exit(ALLEGRO_THREAD *thread) +{ + unsigned int i; + THREAD_AND_POOL *tap; + + for (i = 0; i < _osx_threads._size; i++) { + tap = _al_vector_ref(&_osx_threads, i); + if (tap->thread == thread) { + _al_vector_delete_at(&_osx_threads, i); + al_free(tap); + return; + } + } +} + +/* Internal function to get a reference to this driver. */ +ALLEGRO_SYSTEM_INTERFACE *_al_system_osx_driver(void) +{ + static ALLEGRO_SYSTEM_INTERFACE* vt = NULL; + if (vt == NULL) { + vt = al_malloc(sizeof(*vt)); + memset(vt, 0, sizeof(*vt)); + vt->id = ALLEGRO_SYSTEM_ID_MACOSX; + vt->initialize = osx_sys_init; + vt->get_display_driver = _al_osx_get_display_driver; + vt->get_keyboard_driver = _al_osx_get_keyboard_driver; + vt->get_mouse_driver = _al_osx_get_mouse_driver; + vt->get_joystick_driver = _al_osx_get_joystick_driver; + vt->get_num_display_modes = _al_osx_get_num_display_modes; + vt->get_display_mode = _al_osx_get_display_mode; + vt->shutdown_system = osx_sys_exit; + vt->get_num_video_adapters = osx_get_num_video_adapters; + vt->get_monitor_info = osx_get_monitor_info; + vt->get_monitor_dpi = osx_get_monitor_dpi; + vt->create_mouse_cursor = _al_osx_create_mouse_cursor; + vt->destroy_mouse_cursor = _al_osx_destroy_mouse_cursor; + vt->get_cursor_position = osx_get_cursor_position; + vt->get_path = _al_osx_get_path; + vt->inhibit_screensaver = osx_inhibit_screensaver; + vt->thread_init = osx_thread_init; + vt->thread_exit = osx_thread_exit; + vt->get_time = _al_unix_get_time; + vt->rest = _al_unix_rest; + vt->init_timeout = _al_unix_init_timeout; + + }; + + return vt; +} + +/* This is a function each platform must define to register all available + * system drivers. + */ +void _al_register_system_interfaces() +{ + ALLEGRO_SYSTEM_INTERFACE **add; + + add = _al_vector_alloc_back(&_al_system_interfaces); + *add = _al_system_osx_driver(); +} + +/* Implementation of get_path */ +ALLEGRO_PATH *_al_osx_get_path(int id) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSString* ans = nil; + NSArray* paths = nil; + NSString *org_name = [[NSString alloc] initWithUTF8String: al_get_org_name()]; + NSString *app_name = [[NSString alloc] initWithUTF8String: al_get_app_name()]; + ALLEGRO_PATH *path = NULL; + + switch (id) { + case ALLEGRO_RESOURCES_PATH: + if (_al_osx_bundle) { + ans = [_al_osx_bundle resourcePath]; + path = al_create_path_for_directory([ans UTF8String]); + } else { + /* Otherwise, return the executable pathname */ + path = _al_osx_get_path(ALLEGRO_EXENAME_PATH); + al_set_path_filename(path, NULL); + } + break; + case ALLEGRO_TEMP_PATH: + ans = NSTemporaryDirectory(); + path = al_create_path_for_directory([ans UTF8String]); + break; + case ALLEGRO_USER_DATA_PATH: + paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, + NSUserDomainMask, + YES); + if ([paths count] > 0) + ans = [paths objectAtIndex: 0]; + if (ans != nil) { + /* Append program name */ + ans = [[ans stringByAppendingPathComponent: org_name] + stringByAppendingPathComponent: app_name]; + } + path = al_create_path_for_directory([ans UTF8String]); + break; + case ALLEGRO_USER_HOME_PATH: + ans = NSHomeDirectory(); + path = al_create_path_for_directory([ans UTF8String]); + break; + case ALLEGRO_USER_DOCUMENTS_PATH: + paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, + NSUserDomainMask, + YES); + if ([paths count] > 0) + ans = [paths objectAtIndex: 0]; + path = al_create_path_for_directory([ans UTF8String]); + break; + case ALLEGRO_EXENAME_PATH: { + char exepath[PATH_MAX]; + uint32_t size = sizeof(exepath); + if (_NSGetExecutablePath(exepath, &size) == 0) + ans = [NSString stringWithUTF8String: exepath]; + + path = al_create_path([ans UTF8String]); + break; + } + case ALLEGRO_USER_SETTINGS_PATH: + paths = + NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, + NSUserDomainMask, + YES); + if ([paths count] > 0) + ans = [paths objectAtIndex: 0]; + if (ans != nil) { + /* Append program name */ + ans = [[ans stringByAppendingPathComponent: org_name] + stringByAppendingPathComponent: app_name]; + } + path = al_create_path_for_directory([ans UTF8String]); + break; + default: + break; + } + [org_name release]; + [app_name release]; + [pool drain]; + + return path; +} + +/* _al_osx_post_quit + * called when the user clicks the quit menu or cmd-Q. + * Currently just sends a window close event to all windows. + * This is a bit unsatisfactory + */ +void _al_osx_post_quit(void) +{ + unsigned int i; + _AL_VECTOR* dpys = &al_get_system_driver()->displays; + // Iterate through all existing displays + for (i = 0; i < _al_vector_size(dpys); ++i) { + ALLEGRO_DISPLAY* dpy = *(ALLEGRO_DISPLAY**) _al_vector_ref(dpys, i); + ALLEGRO_EVENT_SOURCE* src = &(dpy->es); + _al_event_source_lock(src); + ALLEGRO_EVENT evt; + evt.type = ALLEGRO_EVENT_DISPLAY_CLOSE; + // Send event + _al_event_source_emit_event(src, &evt); + _al_event_source_unlock(src); + } +} + +/* Local variables: */ +/* c-basic-offset: 3 */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/allegro/src/math.c b/allegro/src/math.c new file mode 100644 index 00000000..30b7bbce --- /dev/null +++ b/allegro/src/math.c @@ -0,0 +1,389 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Fixed point math routines and lookup tables. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#include + +#include "allegro5/allegro.h" + +#ifdef ALLEGRO_MSVC + #define hypotf(x, y) _hypotf((x), (y)) +#endif + +al_fixed _al_fix_cos_tbl[512] = +{ + /* precalculated fixed point (16.16) cosines for a full circle (0-255) */ + + 65536L, 65531L, 65516L, 65492L, 65457L, 65413L, 65358L, 65294L, + 65220L, 65137L, 65043L, 64940L, 64827L, 64704L, 64571L, 64429L, + 64277L, 64115L, 63944L, 63763L, 63572L, 63372L, 63162L, 62943L, + 62714L, 62476L, 62228L, 61971L, 61705L, 61429L, 61145L, 60851L, + 60547L, 60235L, 59914L, 59583L, 59244L, 58896L, 58538L, 58172L, + 57798L, 57414L, 57022L, 56621L, 56212L, 55794L, 55368L, 54934L, + 54491L, 54040L, 53581L, 53114L, 52639L, 52156L, 51665L, 51166L, + 50660L, 50146L, 49624L, 49095L, 48559L, 48015L, 47464L, 46906L, + 46341L, 45769L, 45190L, 44604L, 44011L, 43412L, 42806L, 42194L, + 41576L, 40951L, 40320L, 39683L, 39040L, 38391L, 37736L, 37076L, + 36410L, 35738L, 35062L, 34380L, 33692L, 33000L, 32303L, 31600L, + 30893L, 30182L, 29466L, 28745L, 28020L, 27291L, 26558L, 25821L, + 25080L, 24335L, 23586L, 22834L, 22078L, 21320L, 20557L, 19792L, + 19024L, 18253L, 17479L, 16703L, 15924L, 15143L, 14359L, 13573L, + 12785L, 11996L, 11204L, 10411L, 9616L, 8820L, 8022L, 7224L, + 6424L, 5623L, 4821L, 4019L, 3216L, 2412L, 1608L, 804L, + 0L, -804L, -1608L, -2412L, -3216L, -4019L, -4821L, -5623L, + -6424L, -7224L, -8022L, -8820L, -9616L, -10411L, -11204L, -11996L, + -12785L, -13573L, -14359L, -15143L, -15924L, -16703L, -17479L, -18253L, + -19024L, -19792L, -20557L, -21320L, -22078L, -22834L, -23586L, -24335L, + -25080L, -25821L, -26558L, -27291L, -28020L, -28745L, -29466L, -30182L, + -30893L, -31600L, -32303L, -33000L, -33692L, -34380L, -35062L, -35738L, + -36410L, -37076L, -37736L, -38391L, -39040L, -39683L, -40320L, -40951L, + -41576L, -42194L, -42806L, -43412L, -44011L, -44604L, -45190L, -45769L, + -46341L, -46906L, -47464L, -48015L, -48559L, -49095L, -49624L, -50146L, + -50660L, -51166L, -51665L, -52156L, -52639L, -53114L, -53581L, -54040L, + -54491L, -54934L, -55368L, -55794L, -56212L, -56621L, -57022L, -57414L, + -57798L, -58172L, -58538L, -58896L, -59244L, -59583L, -59914L, -60235L, + -60547L, -60851L, -61145L, -61429L, -61705L, -61971L, -62228L, -62476L, + -62714L, -62943L, -63162L, -63372L, -63572L, -63763L, -63944L, -64115L, + -64277L, -64429L, -64571L, -64704L, -64827L, -64940L, -65043L, -65137L, + -65220L, -65294L, -65358L, -65413L, -65457L, -65492L, -65516L, -65531L, + -65536L, -65531L, -65516L, -65492L, -65457L, -65413L, -65358L, -65294L, + -65220L, -65137L, -65043L, -64940L, -64827L, -64704L, -64571L, -64429L, + -64277L, -64115L, -63944L, -63763L, -63572L, -63372L, -63162L, -62943L, + -62714L, -62476L, -62228L, -61971L, -61705L, -61429L, -61145L, -60851L, + -60547L, -60235L, -59914L, -59583L, -59244L, -58896L, -58538L, -58172L, + -57798L, -57414L, -57022L, -56621L, -56212L, -55794L, -55368L, -54934L, + -54491L, -54040L, -53581L, -53114L, -52639L, -52156L, -51665L, -51166L, + -50660L, -50146L, -49624L, -49095L, -48559L, -48015L, -47464L, -46906L, + -46341L, -45769L, -45190L, -44604L, -44011L, -43412L, -42806L, -42194L, + -41576L, -40951L, -40320L, -39683L, -39040L, -38391L, -37736L, -37076L, + -36410L, -35738L, -35062L, -34380L, -33692L, -33000L, -32303L, -31600L, + -30893L, -30182L, -29466L, -28745L, -28020L, -27291L, -26558L, -25821L, + -25080L, -24335L, -23586L, -22834L, -22078L, -21320L, -20557L, -19792L, + -19024L, -18253L, -17479L, -16703L, -15924L, -15143L, -14359L, -13573L, + -12785L, -11996L, -11204L, -10411L, -9616L, -8820L, -8022L, -7224L, + -6424L, -5623L, -4821L, -4019L, -3216L, -2412L, -1608L, -804L, + 0L, 804L, 1608L, 2412L, 3216L, 4019L, 4821L, 5623L, + 6424L, 7224L, 8022L, 8820L, 9616L, 10411L, 11204L, 11996L, + 12785L, 13573L, 14359L, 15143L, 15924L, 16703L, 17479L, 18253L, + 19024L, 19792L, 20557L, 21320L, 22078L, 22834L, 23586L, 24335L, + 25080L, 25821L, 26558L, 27291L, 28020L, 28745L, 29466L, 30182L, + 30893L, 31600L, 32303L, 33000L, 33692L, 34380L, 35062L, 35738L, + 36410L, 37076L, 37736L, 38391L, 39040L, 39683L, 40320L, 40951L, + 41576L, 42194L, 42806L, 43412L, 44011L, 44604L, 45190L, 45769L, + 46341L, 46906L, 47464L, 48015L, 48559L, 49095L, 49624L, 50146L, + 50660L, 51166L, 51665L, 52156L, 52639L, 53114L, 53581L, 54040L, + 54491L, 54934L, 55368L, 55794L, 56212L, 56621L, 57022L, 57414L, + 57798L, 58172L, 58538L, 58896L, 59244L, 59583L, 59914L, 60235L, + 60547L, 60851L, 61145L, 61429L, 61705L, 61971L, 62228L, 62476L, + 62714L, 62943L, 63162L, 63372L, 63572L, 63763L, 63944L, 64115L, + 64277L, 64429L, 64571L, 64704L, 64827L, 64940L, 65043L, 65137L, + 65220L, 65294L, 65358L, 65413L, 65457L, 65492L, 65516L, 65531L +}; + + + +al_fixed _al_fix_tan_tbl[256] = +{ + /* precalculated fixed point (16.16) tangents for a half circle (0-127) */ + + 0L, 804L, 1609L, 2414L, 3220L, 4026L, 4834L, 5644L, + 6455L, 7268L, 8083L, 8901L, 9721L, 10545L, 11372L, 12202L, + 13036L, 13874L, 14717L, 15564L, 16416L, 17273L, 18136L, 19005L, + 19880L, 20762L, 21650L, 22546L, 23449L, 24360L, 25280L, 26208L, + 27146L, 28093L, 29050L, 30018L, 30996L, 31986L, 32988L, 34002L, + 35030L, 36071L, 37126L, 38196L, 39281L, 40382L, 41500L, 42636L, + 43790L, 44963L, 46156L, 47369L, 48605L, 49863L, 51145L, 52451L, + 53784L, 55144L, 56532L, 57950L, 59398L, 60880L, 62395L, 63947L, + 65536L, 67165L, 68835L, 70548L, 72308L, 74116L, 75974L, 77887L, + 79856L, 81885L, 83977L, 86135L, 88365L, 90670L, 93054L, 95523L, + 98082L, 100736L, 103493L, 106358L, 109340L, 112447L, 115687L, 119071L, + 122609L, 126314L, 130198L, 134276L, 138564L, 143081L, 147847L, 152884L, + 158218L, 163878L, 169896L, 176309L, 183161L, 190499L, 198380L, 206870L, + 216043L, 225990L, 236817L, 248648L, 261634L, 275959L, 291845L, 309568L, + 329472L, 351993L, 377693L, 407305L, 441808L, 482534L, 531352L, 590958L, + 665398L, 761030L, 888450L, 1066730L,1334016L,1779314L,2669641L,5340086L, + -2147483647L,-5340086L,-2669641L,-1779314L,-1334016L,-1066730L,-888450L,-761030L, + -665398L,-590958L,-531352L,-482534L,-441808L,-407305L,-377693L,-351993L, + -329472L,-309568L,-291845L,-275959L,-261634L,-248648L,-236817L,-225990L, + -216043L,-206870L,-198380L,-190499L,-183161L,-176309L,-169896L,-163878L, + -158218L,-152884L,-147847L,-143081L,-138564L,-134276L,-130198L,-126314L, + -122609L,-119071L,-115687L,-112447L,-109340L,-106358L,-103493L,-100736L, + -98082L, -95523L, -93054L, -90670L, -88365L, -86135L, -83977L, -81885L, + -79856L, -77887L, -75974L, -74116L, -72308L, -70548L, -68835L, -67165L, + -65536L, -63947L, -62395L, -60880L, -59398L, -57950L, -56532L, -55144L, + -53784L, -52451L, -51145L, -49863L, -48605L, -47369L, -46156L, -44963L, + -43790L, -42636L, -41500L, -40382L, -39281L, -38196L, -37126L, -36071L, + -35030L, -34002L, -32988L, -31986L, -30996L, -30018L, -29050L, -28093L, + -27146L, -26208L, -25280L, -24360L, -23449L, -22546L, -21650L, -20762L, + -19880L, -19005L, -18136L, -17273L, -16416L, -15564L, -14717L, -13874L, + -13036L, -12202L, -11372L, -10545L, -9721L, -8901L, -8083L, -7268L, + -6455L, -5644L, -4834L, -4026L, -3220L, -2414L, -1609L, -804L +}; + + + +al_fixed _al_fix_acos_tbl[513] = +{ + /* precalculated fixed point (16.16) inverse cosines (-1 to 1) */ + + 0x800000L, 0x7C65C7L, 0x7AE75AL, 0x79C19EL, 0x78C9BEL, 0x77EF25L, 0x772953L, 0x76733AL, + 0x75C991L, 0x752A10L, 0x74930CL, 0x740345L, 0x7379C1L, 0x72F5BAL, 0x72768FL, 0x71FBBCL, + 0x7184D3L, 0x711174L, 0x70A152L, 0x703426L, 0x6FC9B5L, 0x6F61C9L, 0x6EFC36L, 0x6E98D1L, + 0x6E3777L, 0x6DD805L, 0x6D7A5EL, 0x6D1E68L, 0x6CC40BL, 0x6C6B2FL, 0x6C13C1L, 0x6BBDAFL, + 0x6B68E6L, 0x6B1558L, 0x6AC2F5L, 0x6A71B1L, 0x6A217EL, 0x69D251L, 0x698420L, 0x6936DFL, + 0x68EA85L, 0x689F0AL, 0x685465L, 0x680A8DL, 0x67C17DL, 0x67792CL, 0x673194L, 0x66EAAFL, + 0x66A476L, 0x665EE5L, 0x6619F5L, 0x65D5A2L, 0x6591E7L, 0x654EBFL, 0x650C26L, 0x64CA18L, + 0x648890L, 0x64478CL, 0x640706L, 0x63C6FCL, 0x63876BL, 0x63484FL, 0x6309A5L, 0x62CB6AL, + 0x628D9CL, 0x625037L, 0x621339L, 0x61D69FL, 0x619A68L, 0x615E90L, 0x612316L, 0x60E7F7L, + 0x60AD31L, 0x6072C3L, 0x6038A9L, 0x5FFEE3L, 0x5FC56EL, 0x5F8C49L, 0x5F5372L, 0x5F1AE7L, + 0x5EE2A7L, 0x5EAAB0L, 0x5E7301L, 0x5E3B98L, 0x5E0473L, 0x5DCD92L, 0x5D96F3L, 0x5D6095L, + 0x5D2A76L, 0x5CF496L, 0x5CBEF2L, 0x5C898BL, 0x5C545EL, 0x5C1F6BL, 0x5BEAB0L, 0x5BB62DL, + 0x5B81E1L, 0x5B4DCAL, 0x5B19E7L, 0x5AE638L, 0x5AB2BCL, 0x5A7F72L, 0x5A4C59L, 0x5A1970L, + 0x59E6B6L, 0x59B42AL, 0x5981CCL, 0x594F9BL, 0x591D96L, 0x58EBBDL, 0x58BA0EL, 0x588889L, + 0x58572DL, 0x5825FAL, 0x57F4EEL, 0x57C40AL, 0x57934DL, 0x5762B5L, 0x573243L, 0x5701F5L, + 0x56D1CCL, 0x56A1C6L, 0x5671E4L, 0x564224L, 0x561285L, 0x55E309L, 0x55B3ADL, 0x558471L, + 0x555555L, 0x552659L, 0x54F77BL, 0x54C8BCL, 0x549A1BL, 0x546B98L, 0x543D31L, 0x540EE7L, + 0x53E0B9L, 0x53B2A7L, 0x5384B0L, 0x5356D4L, 0x532912L, 0x52FB6BL, 0x52CDDDL, 0x52A068L, + 0x52730CL, 0x5245C9L, 0x52189EL, 0x51EB8BL, 0x51BE8FL, 0x5191AAL, 0x5164DCL, 0x513825L, + 0x510B83L, 0x50DEF7L, 0x50B280L, 0x50861FL, 0x5059D2L, 0x502D99L, 0x500175L, 0x4FD564L, + 0x4FA967L, 0x4F7D7DL, 0x4F51A6L, 0x4F25E2L, 0x4EFA30L, 0x4ECE90L, 0x4EA301L, 0x4E7784L, + 0x4E4C19L, 0x4E20BEL, 0x4DF574L, 0x4DCA3AL, 0x4D9F10L, 0x4D73F6L, 0x4D48ECL, 0x4D1DF1L, + 0x4CF305L, 0x4CC829L, 0x4C9D5AL, 0x4C729AL, 0x4C47E9L, 0x4C1D45L, 0x4BF2AEL, 0x4BC826L, + 0x4B9DAAL, 0x4B733BL, 0x4B48D9L, 0x4B1E84L, 0x4AF43BL, 0x4AC9FEL, 0x4A9FCDL, 0x4A75A7L, + 0x4A4B8DL, 0x4A217EL, 0x49F77AL, 0x49CD81L, 0x49A393L, 0x4979AFL, 0x494FD5L, 0x492605L, + 0x48FC3FL, 0x48D282L, 0x48A8CFL, 0x487F25L, 0x485584L, 0x482BECL, 0x48025DL, 0x47D8D6L, + 0x47AF57L, 0x4785E0L, 0x475C72L, 0x47330AL, 0x4709ABL, 0x46E052L, 0x46B701L, 0x468DB7L, + 0x466474L, 0x463B37L, 0x461201L, 0x45E8D0L, 0x45BFA6L, 0x459682L, 0x456D64L, 0x45444BL, + 0x451B37L, 0x44F229L, 0x44C920L, 0x44A01CL, 0x44771CL, 0x444E21L, 0x44252AL, 0x43FC38L, + 0x43D349L, 0x43AA5FL, 0x438178L, 0x435894L, 0x432FB4L, 0x4306D8L, 0x42DDFEL, 0x42B527L, + 0x428C53L, 0x426381L, 0x423AB2L, 0x4211E5L, 0x41E91AL, 0x41C051L, 0x41978AL, 0x416EC5L, + 0x414601L, 0x411D3EL, 0x40F47CL, 0x40CBBBL, 0x40A2FBL, 0x407A3CL, 0x40517DL, 0x4028BEL, + 0x400000L, 0x3FD742L, 0x3FAE83L, 0x3F85C4L, 0x3F5D05L, 0x3F3445L, 0x3F0B84L, 0x3EE2C2L, + 0x3EB9FFL, 0x3E913BL, 0x3E6876L, 0x3E3FAFL, 0x3E16E6L, 0x3DEE1BL, 0x3DC54EL, 0x3D9C7FL, + 0x3D73ADL, 0x3D4AD9L, 0x3D2202L, 0x3CF928L, 0x3CD04CL, 0x3CA76CL, 0x3C7E88L, 0x3C55A1L, + 0x3C2CB7L, 0x3C03C8L, 0x3BDAD6L, 0x3BB1DFL, 0x3B88E4L, 0x3B5FE4L, 0x3B36E0L, 0x3B0DD7L, + 0x3AE4C9L, 0x3ABBB5L, 0x3A929CL, 0x3A697EL, 0x3A405AL, 0x3A1730L, 0x39EDFFL, 0x39C4C9L, + 0x399B8CL, 0x397249L, 0x3948FFL, 0x391FAEL, 0x38F655L, 0x38CCF6L, 0x38A38EL, 0x387A20L, + 0x3850A9L, 0x38272AL, 0x37FDA3L, 0x37D414L, 0x37AA7CL, 0x3780DBL, 0x375731L, 0x372D7EL, + 0x3703C1L, 0x36D9FBL, 0x36B02BL, 0x368651L, 0x365C6DL, 0x36327FL, 0x360886L, 0x35DE82L, + 0x35B473L, 0x358A59L, 0x356033L, 0x353602L, 0x350BC5L, 0x34E17CL, 0x34B727L, 0x348CC5L, + 0x346256L, 0x3437DAL, 0x340D52L, 0x33E2BBL, 0x33B817L, 0x338D66L, 0x3362A6L, 0x3337D7L, + 0x330CFBL, 0x32E20FL, 0x32B714L, 0x328C0AL, 0x3260F0L, 0x3235C6L, 0x320A8CL, 0x31DF42L, + 0x31B3E7L, 0x31887CL, 0x315CFFL, 0x313170L, 0x3105D0L, 0x30DA1EL, 0x30AE5AL, 0x308283L, + 0x305699L, 0x302A9CL, 0x2FFE8BL, 0x2FD267L, 0x2FA62EL, 0x2F79E1L, 0x2F4D80L, 0x2F2109L, + 0x2EF47DL, 0x2EC7DBL, 0x2E9B24L, 0x2E6E56L, 0x2E4171L, 0x2E1475L, 0x2DE762L, 0x2DBA37L, + 0x2D8CF4L, 0x2D5F98L, 0x2D3223L, 0x2D0495L, 0x2CD6EEL, 0x2CA92CL, 0x2C7B50L, 0x2C4D59L, + 0x2C1F47L, 0x2BF119L, 0x2BC2CFL, 0x2B9468L, 0x2B65E5L, 0x2B3744L, 0x2B0885L, 0x2AD9A7L, + 0x2AAAABL, 0x2A7B8FL, 0x2A4C53L, 0x2A1CF7L, 0x29ED7BL, 0x29BDDCL, 0x298E1CL, 0x295E3AL, + 0x292E34L, 0x28FE0BL, 0x28CDBDL, 0x289D4BL, 0x286CB3L, 0x283BF6L, 0x280B12L, 0x27DA06L, + 0x27A8D3L, 0x277777L, 0x2745F2L, 0x271443L, 0x26E26AL, 0x26B065L, 0x267E34L, 0x264BD6L, + 0x26194AL, 0x25E690L, 0x25B3A7L, 0x25808EL, 0x254D44L, 0x2519C8L, 0x24E619L, 0x24B236L, + 0x247E1FL, 0x2449D3L, 0x241550L, 0x23E095L, 0x23ABA2L, 0x237675L, 0x23410EL, 0x230B6AL, + 0x22D58AL, 0x229F6BL, 0x22690DL, 0x22326EL, 0x21FB8DL, 0x21C468L, 0x218CFFL, 0x215550L, + 0x211D59L, 0x20E519L, 0x20AC8EL, 0x2073B7L, 0x203A92L, 0x20011DL, 0x1FC757L, 0x1F8D3DL, + 0x1F52CFL, 0x1F1809L, 0x1EDCEAL, 0x1EA170L, 0x1E6598L, 0x1E2961L, 0x1DECC7L, 0x1DAFC9L, + 0x1D7264L, 0x1D3496L, 0x1CF65BL, 0x1CB7B1L, 0x1C7895L, 0x1C3904L, 0x1BF8FAL, 0x1BB874L, + 0x1B7770L, 0x1B35E8L, 0x1AF3DAL, 0x1AB141L, 0x1A6E19L, 0x1A2A5EL, 0x19E60BL, 0x19A11BL, + 0x195B8AL, 0x191551L, 0x18CE6CL, 0x1886D4L, 0x183E83L, 0x17F573L, 0x17AB9BL, 0x1760F6L, + 0x17157BL, 0x16C921L, 0x167BE0L, 0x162DAFL, 0x15DE82L, 0x158E4FL, 0x153D0BL, 0x14EAA8L, + 0x14971AL, 0x144251L, 0x13EC3FL, 0x1394D1L, 0x133BF5L, 0x12E198L, 0x1285A2L, 0x1227FBL, + 0x11C889L, 0x11672FL, 0x1103CAL, 0x109E37L, 0x10364BL, 0xFCBDAL, 0xF5EAEL, 0xEEE8CL, + 0xE7B2DL, 0xE0444L, 0xD8971L, 0xD0A46L, 0xC863FL, 0xBFCBBL, 0xB6CF4L, 0xAD5F0L, + 0xA366FL, 0x98CC6L, 0x8D6ADL, 0x810DBL, 0x73642L, 0x63E62L, 0x518A6L, 0x39A39L, + 0x0L +}; + + + +/* Function: al_fixatan + * Fixed point inverse tangent. Does a binary search on the tan table. + */ +al_fixed al_fixatan(al_fixed x) +{ + int a, b, c; /* for binary search */ + al_fixed d; /* difference value for search */ + + if (x >= 0) { /* search the first part of tan table */ + a = 0; + b = 127; + } + else { /* search the second half instead */ + a = 128; + b = 255; + } + + do { + c = (a + b) >> 1; + d = x - _al_fix_tan_tbl[c]; + + if (d > 0) + a = c + 1; + else + if (d < 0) + b = c - 1; + + } while ((a <= b) && (d)); + + if (x >= 0) + return ((long)c) << 15; + + return (-0x00800000L + (((long)c) << 15)); +} + + + +/* Function: al_fixatan2 + * Like the libc atan2, but for fixed point numbers. + */ +al_fixed al_fixatan2(al_fixed y, al_fixed x) +{ + al_fixed r; + + if (x==0) { + if (y==0) { + al_set_errno(EDOM); + return 0L; + } + else + return ((y < 0) ? -0x00400000L : 0x00400000L); + } + + al_set_errno(0); + r = al_fixdiv(y, x); + + if (al_get_errno()) { + al_set_errno(0); + return ((y < 0) ? -0x00400000L : 0x00400000L); + } + + r = al_fixatan(r); + + if (x >= 0) + return r; + + if (y >= 0) + return 0x00800000L + r; + + return r - 0x00800000L; +} + + + +/* Enum: al_fixtorad_r + * Ratios for converting between radians and fixed point angles. + * 2pi/256 + */ +const al_fixed al_fixtorad_r = (al_fixed)1608; + + + +/* Enum: al_radtofix_r + * Ratios for converting between radians and fixed point angles. + * 256/2pi + */ +const al_fixed al_radtofix_r = (al_fixed)2670177; + + + +/* Function: al_fixsqrt + * Fixed point square root routine for non-i386. + */ +al_fixed al_fixsqrt(al_fixed x) +{ + if (x > 0) + return al_ftofix(sqrt(al_fixtof(x))); + + if (x < 0) + al_set_errno(EDOM); + + return 0; +} + + + +/* Function: al_fixhypot + * Fixed point sqrt (x*x+y*y) for non-i386. + */ +al_fixed al_fixhypot(al_fixed x, al_fixed y) +{ + return al_ftofix(hypotf(al_fixtof(x), al_fixtof(y))); +} + + + +/* These prototypes exist for documentation only. */ + +/* Function: al_itofix + */ +al_fixed al_itofix(int x); + +/* Function: al_fixtoi + */ +int al_fixtoi(al_fixed x); + +/* Function: al_fixfloor + */ +int al_fixfloor(al_fixed x); + +/* Function: al_fixceil + */ +int al_fixceil(al_fixed x); + +/* Function: al_ftofix + */ +al_fixed al_ftofix(double x); + +/* Function: al_fixtof + */ +double al_fixtof(al_fixed x); + +/* Function: al_fixadd + */ +al_fixed al_fixadd(al_fixed x, al_fixed y); + +/* Function: al_fixsub + */ +al_fixed al_fixsub(al_fixed x, al_fixed y); + +/* Function: al_fixmul + */ +al_fixed al_fixmul(al_fixed x, al_fixed y); + +/* Function: al_fixdiv + */ +al_fixed al_fixdiv(al_fixed x, al_fixed y); + +/* Function: al_fixcos + */ +al_fixed al_fixcos(al_fixed x); + +/* Function: al_fixsin + */ +al_fixed al_fixsin(al_fixed x); + +/* Function: al_fixtan + */ +al_fixed al_fixtan(al_fixed x); + +/* Function: al_fixacos + */ +al_fixed al_fixacos(al_fixed x); + +/* Function: al_fixasin + */ +al_fixed al_fixasin(al_fixed x); + diff --git a/allegro/src/memblit.c b/allegro/src/memblit.c new file mode 100644 index 00000000..584721ba --- /dev/null +++ b/allegro/src/memblit.c @@ -0,0 +1,306 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Memory bitmap drawing routines + * + */ + +#define _AL_NO_BLEND_INLINE_FUNC + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_blend.h" +#include "allegro5/internal/aintern_convert.h" +#include "allegro5/internal/aintern_memblit.h" +#include "allegro5/internal/aintern_transform.h" +#include "allegro5/internal/aintern_tri_soft.h" +#include + +#define MIN _ALLEGRO_MIN +#define MAX _ALLEGRO_MAX + +static void _al_draw_transformed_scaled_bitmap_memory( + ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, + int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, + int flags); +static void _al_draw_bitmap_region_memory_fast(ALLEGRO_BITMAP *bitmap, + int sx, int sy, int sw, int sh, + int dx, int dy, int flags); + + +/* The CLIPPER macro takes pre-clipped coordinates for both the source + * and destination bitmaps and clips them as necessary, taking sub- + * bitmaps into consideration. The wr and hr parameters are the ratio of + * source width & height to destination width & height _before_ clipping. + * + * First the left (top) coordinates are moved inward. Then the right + * (bottom) coordinates are moved inward. The changes are applied + * simultaneously to the complementary bitmap with scaling taken into + * consideration. + * + * The coordinates are modified, and the sub-bitmaps are set to the + * parent bitmaps. If nothing needs to be drawn, the macro exits the + * function. + */ + +#define CLIPPER(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, wr, hr, flags)\ +{ \ + float cl = dest->cl, cr = dest->cr_excl; \ + float ct = dest->ct, cb = dest->cb_excl; \ + float sx_ = 0, sy_ = 0, sw_ = 0, sh_ = 0; \ + bool hflip = false, vflip = false; \ + if (dw < 0) { \ + hflip = true; \ + dx += dw; \ + dw = -dw; \ + sx_ = sx; sw_ = sw; \ + } \ + if (dh < 0) { \ + vflip = true; \ + dy += dh; \ + dh = -dh; \ + sy_ = sy; sh_ = sh; \ + } \ + \ + if (dest->parent) { \ + dx += dest->xofs; \ + dy += dest->yofs; \ + \ + cl += dest->xofs; \ + if (cl >= dest->parent->w) { \ + return; \ + } \ + else if (cl < 0) { \ + cl = 0; \ + } \ + \ + ct += dest->yofs; \ + if (ct >= dest->parent->h) { \ + return; \ + } \ + else if (ct < 0) { \ + ct = 0; \ + } \ + \ + cr = MIN(dest->parent->w, cr + dest->xofs); \ + cb = MIN(dest->parent->h, cb + dest->yofs); \ + \ + dest = dest->parent; \ + } \ + \ + if (dx < cl) { \ + const int d = cl - dx; \ + dx = cl; \ + dw -= d; \ + sx += d * wr; \ + sw -= d * wr; \ + } \ + \ + if (dx + dw > cr) { \ + const int d = dx + dw - cr; \ + dw -= d; \ + sw -= d * wr; \ + } \ + \ + if (dy < ct) { \ + const int d = ct - dy; \ + dy = ct; \ + dh -= d; \ + sy += d * hr; \ + sh -= d * hr; \ + } \ + \ + if (dy + dh > cb) { \ + const int d = dy + dh - cb; \ + dh -= d; \ + sh -= d * hr; \ + } \ + \ + if (sh <= 0 || sw <= 0) return; \ + \ + if (hflip) {dx += dw; dw = -dw; sx = sx_ + sw_ - sw + sx_ - sx; dx--;} \ + if (vflip) {dy += dh; dh = -dh; sy = sy_ + sh_ - sh + sy_ - sy; dy--;} \ +} + + +void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *src, + ALLEGRO_COLOR tint, + int sx, int sy, int sw, int sh, + int dx, int dy, int flags) +{ + int op, src_mode, dst_mode; + int op_alpha, src_alpha, dst_alpha; + float xtrans, ytrans; + + ASSERT(src->parent == NULL); + + al_get_separate_bitmap_blender(&op, + &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + + if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED_TINT_WHITE && + _al_transform_is_translation(al_get_current_transform(), &xtrans, &ytrans)) + { + _al_draw_bitmap_region_memory_fast(src, sx, sy, sw, sh, + dx + xtrans, dy + ytrans, flags); + return; + } + + /* We used to have special cases for translation/scaling only, but the + * general version received much more optimisation and ended up being + * faster. + */ + _al_draw_transformed_scaled_bitmap_memory(src, tint, sx, sy, + sw, sh, dx, dy, sw, sh, flags); +} + + +static void _al_draw_transformed_bitmap_memory(ALLEGRO_BITMAP *src, + ALLEGRO_COLOR tint, + int sx, int sy, int sw, int sh, int dw, int dh, + ALLEGRO_TRANSFORM* local_trans, int flags) +{ + float xsf[4], ysf[4]; + int tl = 0, tr = 1, bl = 3, br = 2; + int tmp; + ALLEGRO_VERTEX v[4]; + + ASSERT(_al_pixel_format_is_real(al_get_bitmap_format(src))); + + /* Decide what order to take corners in. */ + if (flags & ALLEGRO_FLIP_VERTICAL) { + tl = 3; + tr = 2; + bl = 0; + br = 1; + } + else { + tl = 0; + tr = 1; + bl = 3; + br = 2; + } + if (flags & ALLEGRO_FLIP_HORIZONTAL) { + tmp = tl; + tl = tr; + tr = tmp; + tmp = bl; + bl = br; + br = tmp; + } + + xsf[0] = 0; + ysf[0] = 0; + + xsf[1] = dw; + ysf[1] = 0; + + xsf[2] = 0; + ysf[2] = dh; + + al_transform_coordinates(local_trans, &xsf[0], &ysf[0]); + al_transform_coordinates(local_trans, &xsf[1], &ysf[1]); + al_transform_coordinates(local_trans, &xsf[2], &ysf[2]); + + v[tl].x = xsf[0]; + v[tl].y = ysf[0]; + v[tl].z = 0; + v[tl].u = sx; + v[tl].v = sy; + v[tl].color = tint; + + v[tr].x = xsf[1]; + v[tr].y = ysf[1]; + v[tr].z = 0; + v[tr].u = sx + sw; + v[tr].v = sy; + v[tr].color = tint; + + v[br].x = xsf[2] + xsf[1] - xsf[0]; + v[br].y = ysf[2] + ysf[1] - ysf[0]; + v[br].z = 0; + v[br].u = sx + sw; + v[br].v = sy + sh; + v[br].color = tint; + + v[bl].x = xsf[2]; + v[bl].y = ysf[2]; + v[bl].z = 0; + v[bl].u = sx; + v[bl].v = sy + sh; + v[bl].color = tint; + + al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + + _al_triangle_2d(src, &v[tl], &v[tr], &v[br]); + _al_triangle_2d(src, &v[tl], &v[br], &v[bl]); + + al_unlock_bitmap(src); +} + + +static void _al_draw_transformed_scaled_bitmap_memory( + ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, + int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int flags) +{ + ALLEGRO_TRANSFORM local_trans; + + al_identity_transform(&local_trans); + al_translate_transform(&local_trans, dx, dy); + al_compose_transform(&local_trans, al_get_current_transform()); + + _al_draw_transformed_bitmap_memory(src, tint, sx, sy, sw, sh, dw, dh, + &local_trans, flags); +} + + +static void _al_draw_bitmap_region_memory_fast(ALLEGRO_BITMAP *bitmap, + int sx, int sy, int sw, int sh, + int dx, int dy, int flags) +{ + ALLEGRO_LOCKED_REGION *src_region; + ALLEGRO_LOCKED_REGION *dst_region; + ALLEGRO_BITMAP *dest = al_get_target_bitmap(); + int dw = sw, dh = sh; + + ASSERT(_al_pixel_format_is_real(al_get_bitmap_format(bitmap))); + ASSERT(_al_pixel_format_is_real(al_get_bitmap_format(dest))); + ASSERT(bitmap->parent == NULL); + + /* Currently the only flags are for flipping, which is handled as negative + * scaling. + */ + ASSERT(flags == 0); + (void)flags; + + CLIPPER(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1, 1, flags) + + if (!(src_region = al_lock_bitmap_region(bitmap, sx, sy, sw, sh, + ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY))) { + return; + } + + if (!(dst_region = al_lock_bitmap_region(dest, dx, dy, sw, sh, + ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY))) { + al_unlock_bitmap(bitmap); + return; + } + + /* will detect if no conversion is needed */ + _al_convert_bitmap_data( + src_region->data, src_region->format, src_region->pitch, + dst_region->data, dst_region->format, dst_region->pitch, + 0, 0, 0, 0, sw, sh); + + al_unlock_bitmap(bitmap); + al_unlock_bitmap(dest); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/memdraw.c b/allegro/src/memdraw.c new file mode 100644 index 00000000..847e245a --- /dev/null +++ b/allegro/src/memdraw.c @@ -0,0 +1,162 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Memory bitmap drawing routines + * + * Based on Michael Bukin's C drawing functions. + * + * Conversion to the new API by Trent Gamblin. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_blend.h" +#include "allegro5/internal/aintern_memdraw.h" +#include "allegro5/internal/aintern_pixels.h" + +/* generic versions of the video memory access helpers */ +/* FIXME: why do we need macros for this? */ +#define bmp_write16(addr, c) (*((uint16_t *)(addr)) = (c)) +#define bmp_write32(addr, c) (*((uint32_t *)(addr)) = (c)) + +#define bmp_read16(addr) (*((uint16_t *)(addr))) +#define bmp_read32(addr) (*((uint32_t *)(addr))) + +typedef struct { + float x[4]; +} float4; + + +void _al_draw_pixel_memory(ALLEGRO_BITMAP *bitmap, float x, float y, + ALLEGRO_COLOR *color) +{ + ALLEGRO_COLOR result; + int ix, iy; + /* + * Probably not worth it to check for identity + */ + al_transform_coordinates(al_get_current_transform(), &x, &y); + ix = (int)x; + iy = (int)y; + _al_blend_memory(color, bitmap, ix, iy, &result); + _al_put_pixel(bitmap, ix, iy, result); +} + + +void _al_clear_bitmap_by_locking(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR *color) +{ + ALLEGRO_LOCKED_REGION *lr; + int x1, y1, w, h; + int x, y; + unsigned char *line_ptr; + + /* This function is not just used on memory bitmaps, but also on OpenGL + * video bitmaps which are not the current target, or when locked. + */ + ASSERT(bitmap); + ASSERT((al_get_bitmap_flags(bitmap) & (ALLEGRO_MEMORY_BITMAP | _ALLEGRO_INTERNAL_OPENGL)) || + _al_pixel_format_is_compressed(al_get_bitmap_format(bitmap))); + + x1 = bitmap->cl; + y1 = bitmap->ct; + w = bitmap->cr_excl - x1; + h = bitmap->cb_excl - y1; + + if (w <= 0 || h <= 0) + return; + + /* XXX what about pre-locked bitmaps? */ + lr = al_lock_bitmap_region(bitmap, x1, y1, w, h, ALLEGRO_PIXEL_FORMAT_ANY, 0); + if (!lr) + return; + + /* Write a single pixel so we can get the raw value. */ + _al_put_pixel(bitmap, x1, y1, *color); + + /* Fill in the region. */ + line_ptr = lr->data; + switch (lr->pixel_size) { + case 2: { + int pixel_value = bmp_read16(line_ptr); + for (y = y1; y < y1 + h; y++) { + if (pixel_value == 0) { /* fast path */ + memset(line_ptr, 0, 2 * w); + } + else { + uint16_t *data = (uint16_t *)line_ptr; + for (x = 0; x < w; x++) { + bmp_write16(data, pixel_value); + data++; + } + } + line_ptr += lr->pitch; + } + break; + } + + case 3: { + int pixel_value = _AL_READ3BYTES(line_ptr); + for (y = y1; y < y1 + h; y++) { + unsigned char *data = (unsigned char *)line_ptr; + if (pixel_value == 0) { /* fast path */ + memset(data, 0, 3 * w); + } + else { + for (x = 0; x < w; x++) { + _AL_WRITE3BYTES(data, pixel_value); + data += 3; + } + } + line_ptr += lr->pitch; + } + break; + } + + case 4: { + int pixel_value = bmp_read32(line_ptr); + for (y = y1; y < y1 + h; y++) { + uint32_t *data = (uint32_t *)line_ptr; + /* Special casing pixel_value == 0 doesn't seem to make any + * difference to speed, so don't bother. + */ + for (x = 0; x < w; x++) { + bmp_write32(data, pixel_value); + data++; + } + line_ptr += lr->pitch; + } + break; + } + + case sizeof(float4): { + float4 *data = (float4 *)line_ptr; + float4 pixel_value = *data; + + for (y = y1; y < y1 + h; y++) { + data = (float4 *)line_ptr; + for (x = 0; x < w; x++) { + *data = pixel_value; + data++; + } + line_ptr += lr->pitch; + } + break; + } + + default: + ASSERT(false); + break; + } + + al_unlock_bitmap(bitmap); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/memory.c b/allegro/src/memory.c new file mode 100644 index 00000000..d855199e --- /dev/null +++ b/allegro/src/memory.c @@ -0,0 +1,87 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Memory management routines. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" + + +/* globals */ +static ALLEGRO_MEMORY_INTERFACE *mem = NULL; + + + +/* Function: al_set_memory_interface + */ +void al_set_memory_interface(ALLEGRO_MEMORY_INTERFACE *memory_interface) +{ + mem = memory_interface; +} + + + +/* Function: al_malloc_with_context + */ +void *al_malloc_with_context(size_t n, + int line, const char *file, const char *func) +{ + if (mem) + return mem->mi_malloc(n, line, file, func); + else + return malloc(n); +} + + + +/* Function: al_free_with_context + */ +void al_free_with_context(void *ptr, + int line, const char *file, const char *func) +{ + if (mem) + mem->mi_free(ptr, line, file, func); + else + free(ptr); +} + + + +/* Function: al_realloc_with_context + */ +void *al_realloc_with_context(void *ptr, size_t n, + int line, const char *file, const char *func) +{ + if (mem) + return mem->mi_realloc(ptr, n, line, file, func); + else + return realloc(ptr, n); +} + + + +/* Function: al_calloc_with_context + */ +void *al_calloc_with_context(size_t count, size_t n, + int line, const char *file, const char *func) +{ + if (mem) + return mem->mi_calloc(count, n, line, file, func); + else + return calloc(count, n); +} + + +/* vim: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/src/misc/aatree.c b/allegro/src/misc/aatree.c new file mode 100644 index 00000000..7370501e --- /dev/null +++ b/allegro/src/misc/aatree.c @@ -0,0 +1,190 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * AA tree, a type of self-balancing search tree. + * + * By Peter Wang. + */ + +/* prettier */ +#define _AL_AATREE Aatree + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_aatree.h" + +struct DelInfo +{ + const void *key; + _al_cmp_t compare; + Aatree *last; + Aatree *deleted; +}; + +static Aatree nil = { 0, &nil, &nil, NULL, NULL }; + +static Aatree *skew(Aatree *T) +{ + if (T == &nil) + return T; + if (T->left->level == T->level) { + Aatree *L = T->left; + T->left = L->right; + L->right = T; + return L; + } + return T; +} + +static Aatree *split(Aatree *T) +{ + if (T == &nil) + return T; + if (T->level == T->right->right->level) { + Aatree *R = T->right; + T->right = R->left; + R->left = T; + R->level = R->level + 1; + return R; + } + return T; +} + +static Aatree *singleton(const void *key, void *value) +{ + Aatree *T = al_malloc(sizeof(Aatree)); + T->level = 1; + T->left = &nil; + T->right = &nil; + T->key = key; + T->value = value; + return T; +} + +static Aatree *doinsert(Aatree *T, const void *key, void *value, + _al_cmp_t compare) +{ + int cmp; + if (T == &nil) { + return singleton(key, value); + } + cmp = compare(key, T->key); + if (cmp < 0) { + T->left = doinsert(T->left, key, value, compare); + } + else if (cmp > 0) { + T->right = doinsert(T->right, key, value, compare); + } + else { + /* Already exists. We don't yet return any indication of this. */ + return T; + } + T = skew(T); + T = split(T); + return T; +} + +Aatree *_al_aa_insert(Aatree *T, const void *key, void *value, + _al_cmp_t compare) +{ + if (T == NULL) + T = &nil; + return doinsert(T, key, value, compare); +} + +void *_al_aa_search(const Aatree *T, const void *key, _al_cmp_t compare) +{ + if (T == NULL) + return NULL; + while (T != &nil) { + int cmp = compare(key, T->key); + if (cmp == 0) + return T->value; + T = (cmp < 0) ? T->left : T->right; + } + return NULL; +} + +static Aatree *dodelete(struct DelInfo *info, Aatree *T, void **ret_value) +{ + if (T == &nil) + return T; + + /* Search down the tree and set pointers last and deleted. */ + info->last = T; + if (info->compare(info->key, T->key) < 0) { + T->left = dodelete(info, T->left, ret_value); + } + else { + info->deleted = T; + T->right = dodelete(info, T->right, ret_value); + } + + /* At the bottom of the tree we remove the element if it is present. */ + if (T == info->last && + info->deleted != &nil && + info->compare(info->key, info->deleted->key) == 0) + { + Aatree *right = T->right; + *ret_value = info->deleted->value; + info->deleted->key = T->key; + info->deleted->value = T->value; + info->deleted = &nil; + al_free(T); + return right; + } + + /* On the way back, we rebalance. */ + if (T->left->level < T->level - 1 + || T->right->level < T->level - 1) + { + T->level--; + if (T->right->level > T->level) { + T->right->level = T->level; + } + T = skew(T); + T->right = skew(T->right); + T->right->right = skew(T->right->right); + T = split(T); + T->right = split(T->right); + } + return T; +} + +/* ret_value is only set if the item was found and deleted. + * The caller should set it to some distinct value, e.g. NULL, + * to detect if no item was found. + */ +Aatree *_al_aa_delete(Aatree *T, const void *key, _al_cmp_t compare, + void **ret_value) +{ + struct DelInfo info; + info.key = key; + info.compare = compare; + info.last = &nil; + info.deleted = &nil; + + if (T) { + T = dodelete(&info, T, ret_value); + if (T == &nil) + T = NULL; + } + return T; +} + +void _al_aa_free(Aatree *T) +{ + if (T && T != &nil) { + _al_aa_free(T->left); + _al_aa_free(T->right); + al_free(T); + } +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/misc/bstrlib.c b/allegro/src/misc/bstrlib.c new file mode 100644 index 00000000..e6a6b603 --- /dev/null +++ b/allegro/src/misc/bstrlib.c @@ -0,0 +1,2970 @@ +/* + * This source file has had its exported symbols prefixed with _al_ or _AL_ + * for the Allegro project. + */ + +/* + * This source file is part of the _al_bstring string library. This code was + * written by Paul Hsieh in 2002-2008, and is covered by the BSD open source + * license and the GPL. Refer to the accompanying documentation for details + * on usage and license. + */ + +/* + * bstrlib.c + * + * This file is the core module for implementing the _al_bstring functions. + */ + +#include +#include +#include +#include +#include +#include +#include "allegro5/allegro.h" +#include "allegro5/internal/bstrlib.h" + +#define bstr__alloc(x) al_malloc(x) +#define bstr__free(p) al_free(p) +#define bstr__realloc(p, x) al_realloc((p), (x)) + +/* Optionally include a mechanism for debugging memory */ + +#if defined(MEMORY_DEBUG) || defined(BSTRLIB_MEMORY_DEBUG) +#include "memdbg.h" +#endif + +#ifndef bstr__alloc +#define bstr__alloc(x) malloc (x) +#endif + +#ifndef bstr__free +#define bstr__free(p) free (p) +#endif + +#ifndef bstr__realloc +#define bstr__realloc(p,x) realloc ((p), (x)) +#endif + +#ifndef bstr__memcpy +#define bstr__memcpy(d,s,l) memcpy ((d), (s), (l)) +#endif + +#ifndef bstr__memmove +#define bstr__memmove(d,s,l) memmove ((d), (s), (l)) +#endif + +#ifndef bstr__memset +#define bstr__memset(d,c,l) memset ((d), (c), (l)) +#endif + +#ifndef bstr__memcmp +#define bstr__memcmp(d,c,l) memcmp ((d), (c), (l)) +#endif + +#ifndef bstr__memchr +#define bstr__memchr(s,c,l) memchr ((s), (c), (l)) +#endif + +/* Just a length safe wrapper for memmove. */ + +#define bBlockCopy(D,S,L) { if ((L) > 0) bstr__memmove ((D),(S),(L)); } + +/* Compute the snapped size for a given requested size. By snapping to powers + of 2 like this, repeated reallocations are avoided. */ +static int snapUpSize (int i) { + if (i < 8) { + i = 8; + } else { + unsigned int j; + j = (unsigned int) i; + + j |= (j >> 1); + j |= (j >> 2); + j |= (j >> 4); + j |= (j >> 8); /* Ok, since int >= 16 bits */ +#if (UINT_MAX != 0xffff) + j |= (j >> 16); /* For 32 bit int systems */ +#if (UINT_MAX > 0xffffffffUL) + j |= (j >> 32); /* For 64 bit int systems */ +#endif +#endif + /* Least power of two greater than i */ + j++; + if ((int) j >= i) i = (int) j; + } + return i; +} + +/* int _al_balloc (_al_bstring b, int len) + * + * Increase the size of the memory backing the _al_bstring b to at least len. + */ +int _al_balloc (_al_bstring b, int olen) { + int len; + if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen <= 0 || + b->mlen < b->slen || olen <= 0) { + return _AL_BSTR_ERR; + } + + if (olen >= b->mlen) { + unsigned char * x; + + if ((len = snapUpSize (olen)) <= b->mlen) return _AL_BSTR_OK; + + /* Assume probability of a non-moving realloc is 0.125 */ + if (7 * b->mlen < 8 * b->slen) { + + /* If slen is close to mlen in size then use realloc to reduce + the memory defragmentation */ + + reallocStrategy:; + + x = (unsigned char *) bstr__realloc (b->data, (size_t) len); + if (x == NULL) { + + /* Since we failed, try allocating the tighest possible + allocation */ + + if (NULL == (x = (unsigned char *) bstr__realloc (b->data, (size_t) (len = olen)))) { + return _AL_BSTR_ERR; + } + } + } else { + + /* If slen is not close to mlen then avoid the penalty of copying + the extra bytes that are allocated, but not considered part of + the string */ + + if (NULL == (x = (unsigned char *) bstr__alloc ((size_t) len))) { + + /* Perhaps there is no available memory for the two + allocations to be in memory at once */ + + goto reallocStrategy; + + } else { + if (b->slen) bstr__memcpy ((char *) x, (char *) b->data, (size_t) b->slen); + bstr__free (b->data); + } + } + b->data = x; + b->mlen = len; + b->data[b->slen] = (unsigned char) '\0'; + } + + return _AL_BSTR_OK; +} + +/* int _al_ballocmin (_al_bstring b, int len) + * + * Set the size of the memory backing the _al_bstring b to len or b->slen+1, + * whichever is larger. Note that repeated use of this function can degrade + * performance. + */ +int _al_ballocmin (_al_bstring b, int len) { + unsigned char * s; + + if (b == NULL || b->data == NULL || (b->slen+1) < 0 || b->mlen <= 0 || + b->mlen < b->slen || len <= 0) { + return _AL_BSTR_ERR; + } + + if (len < b->slen + 1) len = b->slen + 1; + + if (len != b->mlen) { + s = (unsigned char *) bstr__realloc (b->data, (size_t) len); + if (NULL == s) return _AL_BSTR_ERR; + s[b->slen] = (unsigned char) '\0'; + b->data = s; + b->mlen = len; + } + + return _AL_BSTR_OK; +} + +/* _al_bstring _al_bfromcstr (const char * str) + * + * Create a _al_bstring which contains the contents of the '\0' terminated char * + * buffer str. + */ +_al_bstring _al_bfromcstr (const char * str) { +_al_bstring b; +int i; +size_t j; + + if (str == NULL) return NULL; + j = (strlen) (str); + i = snapUpSize ((int) (j + (2 - (j != 0)))); + if (i <= (int) j) return NULL; + + b = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); + if (NULL == b) return NULL; + b->slen = (int) j; + if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) { + bstr__free (b); + return NULL; + } + + bstr__memcpy (b->data, str, j+1); + return b; +} + +/* _al_bstring _al_bfromcstralloc (int mlen, const char * str) + * + * Create a _al_bstring which contains the contents of the '\0' terminated char * + * buffer str. The memory buffer backing the string is at least len + * characters in length. + */ +_al_bstring _al_bfromcstralloc (int mlen, const char * str) { +_al_bstring b; +int i; +size_t j; + + if (str == NULL) return NULL; + j = (strlen) (str); + i = snapUpSize ((int) (j + (2 - (j != 0)))); + if (i <= (int) j) return NULL; + + b = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); + if (b == NULL) return NULL; + b->slen = (int) j; + if (i < mlen) i = mlen; + + if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) { + bstr__free (b); + return NULL; + } + + bstr__memcpy (b->data, str, j+1); + return b; +} + +/* _al_bstring _al_blk2bstr (const void * blk, int len) + * + * Create a _al_bstring which contains the content of the block blk of length + * len. + */ +_al_bstring _al_blk2bstr (const void * blk, int len) { +_al_bstring b; +int i; + + if (blk == NULL || len < 0) return NULL; + b = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); + if (b == NULL) return NULL; + b->slen = len; + + i = len + (2 - (len != 0)); + i = snapUpSize (i); + + b->mlen = i; + + b->data = (unsigned char *) bstr__alloc ((size_t) b->mlen); + if (b->data == NULL) { + bstr__free (b); + return NULL; + } + + if (len > 0) bstr__memcpy (b->data, blk, (size_t) len); + b->data[len] = (unsigned char) '\0'; + + return b; +} + +/* char * _al_bstr2cstr (_al_const_bstring s, char z) + * + * Create a '\0' terminated char * buffer which is equal to the contents of + * the _al_bstring s, except that any contained '\0' characters are converted + * to the character in z. This returned value should be freed with a + * _al_bcstrfree () call, by the calling application. + */ +char * _al_bstr2cstr (_al_const_bstring b, char z) { +int i, l; +char * r; + + if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; + l = b->slen; + r = (char *) bstr__alloc ((size_t) (l + 1)); + if (r == NULL) return r; + + for (i=0; i < l; i ++) { + r[i] = (char) ((b->data[i] == '\0') ? z : (char) (b->data[i])); + } + + r[l] = (unsigned char) '\0'; + + return r; +} + +/* int _al_bcstrfree (char * s) + * + * Frees a C-string generated by _al_bstr2cstr (). This is normally unnecessary + * since it just wraps a call to bstr__free (), however, if bstr__alloc () + * and bstr__free () have been redefined as a macros within the bstrlib + * module (via defining them in memdbg.h after defining + * BSTRLIB_MEMORY_DEBUG) with some difference in behaviour from the std + * library functions, then this allows a correct way of freeing the memory + * that allows higher level code to be independent from these macro + * redefinitions. + */ +int _al_bcstrfree (char * s) { + if (s) { + bstr__free (s); + return _AL_BSTR_OK; + } + return _AL_BSTR_ERR; +} + +/* int _al_bconcat (_al_bstring b0, _al_const_bstring b1) + * + * Concatenate the _al_bstring b1 to the _al_bstring b0. + */ +int _al_bconcat (_al_bstring b0, _al_const_bstring b1) { +int len, d; +_al_bstring aux = (_al_bstring) b1; + + if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL) return _AL_BSTR_ERR; + + d = b0->slen; + len = b1->slen; + if ((d | (b0->mlen - d) | len | (d + len)) < 0) return _AL_BSTR_ERR; + + if (b0->mlen <= d + len + 1) { + ptrdiff_t pd = b1->data - b0->data; + if (0 <= pd && pd < b0->mlen) { + if (NULL == (aux = _al_bstrcpy (b1))) return _AL_BSTR_ERR; + } + if (_al_balloc (b0, d + len + 1) != _AL_BSTR_OK) { + if (aux != b1) _al_bdestroy (aux); + return _AL_BSTR_ERR; + } + } + + bBlockCopy (&b0->data[d], &aux->data[0], (size_t) len); + b0->data[d + len] = (unsigned char) '\0'; + b0->slen = d + len; + if (aux != b1) _al_bdestroy (aux); + return _AL_BSTR_OK; +} + +/* int _al_bconchar (_al_bstring b, char c) +/ * + * Concatenate the single character c to the _al_bstring b. + */ +int _al_bconchar (_al_bstring b, char c) { +int d; + + if (b == NULL) return _AL_BSTR_ERR; + d = b->slen; + if ((d | (b->mlen - d)) < 0 || _al_balloc (b, d + 2) != _AL_BSTR_OK) return _AL_BSTR_ERR; + b->data[d] = (unsigned char) c; + b->data[d + 1] = (unsigned char) '\0'; + b->slen++; + return _AL_BSTR_OK; +} + +/* int _al_bcatcstr (_al_bstring b, const char * s) + * + * Concatenate a char * string to a _al_bstring. + */ +int _al_bcatcstr (_al_bstring b, const char * s) { +char * d; +int i, l; + + if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen + || b->mlen <= 0 || s == NULL) return _AL_BSTR_ERR; + + /* Optimistically concatenate directly */ + l = b->mlen - b->slen; + d = (char *) &b->data[b->slen]; + for (i=0; i < l; i++) { + if ((*d++ = *s++) == '\0') { + b->slen += i; + return _AL_BSTR_OK; + } + } + b->slen += i; + + /* Need to explicitely resize and concatenate tail */ + return _al_bcatblk (b, (const void *) s, (int) strlen (s)); +} + +/* int _al_bcatblk (_al_bstring b, const void * s, int len) + * + * Concatenate a fixed length buffer to a _al_bstring. + */ +int _al_bcatblk (_al_bstring b, const void * s, int len) { +int nl; + + if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen + || b->mlen <= 0 || s == NULL || len < 0) return _AL_BSTR_ERR; + + if (0 > (nl = b->slen + len)) return _AL_BSTR_ERR; /* Overflow? */ + if (b->mlen <= nl && 0 > _al_balloc (b, nl + 1)) return _AL_BSTR_ERR; + + bBlockCopy (&b->data[b->slen], s, (size_t) len); + b->slen = nl; + b->data[nl] = (unsigned char) '\0'; + return _AL_BSTR_OK; +} + +/* _al_bstring _al_bstrcpy (_al_const_bstring b) + * + * Create a copy of the _al_bstring b. + */ +_al_bstring _al_bstrcpy (_al_const_bstring b) { +_al_bstring b0; +int i,j; + + /* Attempted to copy an invalid string? */ + if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; + + b0 = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); + if (b0 == NULL) { + /* Unable to allocate memory for string header */ + return NULL; + } + + i = b->slen; + j = snapUpSize (i + 1); + + b0->data = (unsigned char *) bstr__alloc (j); + if (b0->data == NULL) { + j = i + 1; + b0->data = (unsigned char *) bstr__alloc (j); + if (b0->data == NULL) { + /* Unable to allocate memory for string data */ + bstr__free (b0); + return NULL; + } + } + + b0->mlen = j; + b0->slen = i; + + if (i) bstr__memcpy ((char *) b0->data, (char *) b->data, i); + b0->data[b0->slen] = (unsigned char) '\0'; + + return b0; +} + +/* int _al_bassign (_al_bstring a, _al_const_bstring b) + * + * Overwrite the string a with the contents of string b. + */ +int _al_bassign (_al_bstring a, _al_const_bstring b) { + if (b == NULL || b->data == NULL || b->slen < 0) + return _AL_BSTR_ERR; + if (b->slen != 0) { + if (_al_balloc (a, b->slen) != _AL_BSTR_OK) return _AL_BSTR_ERR; + bstr__memmove (a->data, b->data, b->slen); + } else { + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0) + return _AL_BSTR_ERR; + } + a->data[b->slen] = (unsigned char) '\0'; + a->slen = b->slen; + return _AL_BSTR_OK; +} + +/* int _al_bassignmidstr (_al_bstring a, _al_const_bstring b, int left, int len) + * + * Overwrite the string a with the middle of contents of string b + * starting from position left and running for a length len. left and + * len are clamped to the ends of b as with the function _al_bmidstr. + */ +int _al_bassignmidstr (_al_bstring a, _al_const_bstring b, int left, int len) { + if (b == NULL || b->data == NULL || b->slen < 0) + return _AL_BSTR_ERR; + + if (left < 0) { + len += left; + left = 0; + } + + if (len > b->slen - left) len = b->slen - left; + + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0) + return _AL_BSTR_ERR; + + if (len > 0) { + if (_al_balloc (a, len) != _AL_BSTR_OK) return _AL_BSTR_ERR; + bstr__memmove (a->data, b->data + left, len); + a->slen = len; + } else { + a->slen = 0; + } + a->data[a->slen] = (unsigned char) '\0'; + return _AL_BSTR_OK; +} + +/* int _al_bassigncstr (_al_bstring a, const char * str) + * + * Overwrite the string a with the contents of char * string str. Note that + * the _al_bstring a must be a well defined and writable _al_bstring. If an error + * occurs _AL_BSTR_ERR is returned however a may be partially overwritten. + */ +int _al_bassigncstr (_al_bstring a, const char * str) { +int i; +size_t len; + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0 || NULL == str) + return _AL_BSTR_ERR; + + for (i=0; i < a->mlen; i++) { + if ('\0' == (a->data[i] = str[i])) { + a->slen = i; + return _AL_BSTR_OK; + } + } + + a->slen = i; + len = strlen (str + i); + if (len > INT_MAX || i + len + 1 > INT_MAX || + 0 > _al_balloc (a, (int) (i + len + 1))) return _AL_BSTR_ERR; + bBlockCopy (a->data + i, str + i, (size_t) len + 1); + a->slen += (int) len; + return _AL_BSTR_OK; +} + +/* int _al_bassignblk (_al_bstring a, const void * s, int len) + * + * Overwrite the string a with the contents of the block (s, len). Note that + * the _al_bstring a must be a well defined and writable _al_bstring. If an error + * occurs _AL_BSTR_ERR is returned and a is not overwritten. + */ +int _al_bassignblk (_al_bstring a, const void * s, int len) { + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0 || NULL == s || len + 1 < 1) + return _AL_BSTR_ERR; + if (len + 1 > a->mlen && 0 > _al_balloc (a, len + 1)) return _AL_BSTR_ERR; + bBlockCopy (a->data, s, (size_t) len); + a->data[len] = (unsigned char) '\0'; + a->slen = len; + return _AL_BSTR_OK; +} + +/* int _al_btrunc (_al_bstring b, int n) + * + * Truncate the _al_bstring to at most n characters. + */ +int _al_btrunc (_al_bstring b, int n) { + if (n < 0 || b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; + if (b->slen > n) { + b->slen = n; + b->data[n] = (unsigned char) '\0'; + } + return _AL_BSTR_OK; +} + +#define upcase(c) (toupper ((unsigned char) c)) +#define downcase(c) (tolower ((unsigned char) c)) +#define wspace(c) (isspace ((unsigned char) c)) + +/* int _al_btoupper (_al_bstring b) + * + * Convert contents of _al_bstring to upper case. + */ +int _al_btoupper (_al_bstring b) { +int i, len; + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; + for (i=0, len = b->slen; i < len; i++) { + b->data[i] = (unsigned char) upcase (b->data[i]); + } + return _AL_BSTR_OK; +} + +/* int _al_btolower (_al_bstring b) + * + * Convert contents of _al_bstring to lower case. + */ +int _al_btolower (_al_bstring b) { +int i, len; + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; + for (i=0, len = b->slen; i < len; i++) { + b->data[i] = (unsigned char) downcase (b->data[i]); + } + return _AL_BSTR_OK; +} + +/* int _al_bstricmp (_al_const_bstring b0, _al_const_bstring b1) + * + * Compare two strings without differentiating between case. The return + * value is the difference of the values of the characters where the two + * strings first differ after lower case transformation, otherwise 0 is + * returned indicating that the strings are equal. If the lengths are + * different, then a difference from 0 is given, but if the first extra + * character is '\0', then it is taken to be the value UCHAR_MAX+1. + */ +int _al_bstricmp (_al_const_bstring b0, _al_const_bstring b1) { +int i, v, n; + + if (_al_bdata (b0) == NULL || b0->slen < 0 || + _al_bdata (b1) == NULL || b1->slen < 0) return SHRT_MIN; + if ((n = b0->slen) > b1->slen) n = b1->slen; + else if (b0->slen == b1->slen && b0->data == b1->data) return _AL_BSTR_OK; + + for (i = 0; i < n; i ++) { + v = (char) downcase (b0->data[i]) + - (char) downcase (b1->data[i]); + if (0 != v) return v; + } + + if (b0->slen > n) { + v = (char) downcase (b0->data[n]); + if (v) return v; + return UCHAR_MAX + 1; + } + if (b1->slen > n) { + v = - (char) downcase (b1->data[n]); + if (v) return v; + return - (int) (UCHAR_MAX + 1); + } + return _AL_BSTR_OK; +} + +/* int _al_bstrnicmp (_al_const_bstring b0, _al_const_bstring b1, int n) + * + * Compare two strings without differentiating between case for at most n + * characters. If the position where the two strings first differ is + * before the nth position, the return value is the difference of the values + * of the characters, otherwise 0 is returned. If the lengths are different + * and less than n characters, then a difference from 0 is given, but if the + * first extra character is '\0', then it is taken to be the value + * UCHAR_MAX+1. + */ +int _al_bstrnicmp (_al_const_bstring b0, _al_const_bstring b1, int n) { +int i, v, m; + + if (_al_bdata (b0) == NULL || b0->slen < 0 || + _al_bdata (b1) == NULL || b1->slen < 0 || n < 0) return SHRT_MIN; + m = n; + if (m > b0->slen) m = b0->slen; + if (m > b1->slen) m = b1->slen; + + if (b0->data != b1->data) { + for (i = 0; i < m; i ++) { + v = (char) downcase (b0->data[i]); + v -= (char) downcase (b1->data[i]); + if (v != 0) return b0->data[i] - b1->data[i]; + } + } + + if (n == m || b0->slen == b1->slen) return _AL_BSTR_OK; + + if (b0->slen > m) { + v = (char) downcase (b0->data[m]); + if (v) return v; + return UCHAR_MAX + 1; + } + + v = - (char) downcase (b1->data[m]); + if (v) return v; + return - (int) (UCHAR_MAX + 1); +} + +/* int _al_biseqcaseless (_al_const_bstring b0, _al_const_bstring b1) + * + * Compare two strings for equality without differentiating between case. + * If the strings differ other than in case, 0 is returned, if the strings + * are the same, 1 is returned, if there is an error, -1 is returned. If + * the length of the strings are different, this function is O(1). '\0' + * termination characters are not treated in any special way. + */ +int _al_biseqcaseless (_al_const_bstring b0, _al_const_bstring b1) { +int i, n; + + if (_al_bdata (b0) == NULL || b0->slen < 0 || + _al_bdata (b1) == NULL || b1->slen < 0) return _AL_BSTR_ERR; + if (b0->slen != b1->slen) return _AL_BSTR_OK; + if (b0->data == b1->data || b0->slen == 0) return 1; + for (i=0, n=b0->slen; i < n; i++) { + if (b0->data[i] != b1->data[i]) { + unsigned char c = (unsigned char) downcase (b0->data[i]); + if (c != (unsigned char) downcase (b1->data[i])) return 0; + } + } + return 1; +} + +/* int _al_bisstemeqcaselessblk (_al_const_bstring b0, const void * blk, int len) + * + * Compare beginning of string b0 with a block of memory of length len + * without differentiating between case for equality. If the beginning of b0 + * differs from the memory block other than in case (or if b0 is too short), + * 0 is returned, if the strings are the same, 1 is returned, if there is an + * error, -1 is returned. '\0' characters are not treated in any special + * way. + */ +int _al_bisstemeqcaselessblk (_al_const_bstring b0, const void * blk, int len) { +int i; + + if (_al_bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0) + return _AL_BSTR_ERR; + if (b0->slen < len) return _AL_BSTR_OK; + if (b0->data == (const unsigned char *) blk || len == 0) return 1; + + for (i = 0; i < len; i ++) { + if (b0->data[i] != ((const unsigned char *) blk)[i]) { + if (downcase (b0->data[i]) != + downcase (((const unsigned char *) blk)[i])) return 0; + } + } + return 1; +} + +/* + * int _al_bltrimws (_al_bstring b) + * + * Delete whitespace contiguous from the left end of the string. + */ +int _al_bltrimws (_al_bstring b) { +int i, len; + + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; + + for (len = b->slen, i = 0; i < len; i++) { + if (!wspace (b->data[i])) { + return _al_bdelete (b, 0, i); + } + } + + b->data[0] = (unsigned char) '\0'; + b->slen = 0; + return _AL_BSTR_OK; +} + +/* + * int _al_brtrimws (_al_bstring b) + * + * Delete whitespace contiguous from the right end of the string. + */ +int _al_brtrimws (_al_bstring b) { +int i; + + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; + + for (i = b->slen - 1; i >= 0; i--) { + if (!wspace (b->data[i])) { + if (b->mlen > i) b->data[i+1] = (unsigned char) '\0'; + b->slen = i + 1; + return _AL_BSTR_OK; + } + } + + b->data[0] = (unsigned char) '\0'; + b->slen = 0; + return _AL_BSTR_OK; +} + +/* + * int _al_btrimws (_al_bstring b) + * + * Delete whitespace contiguous from both ends of the string. + */ +int _al_btrimws (_al_bstring b) { +int i, j; + + if (b == NULL || b->data == NULL || b->mlen < b->slen || + b->slen < 0 || b->mlen <= 0) return _AL_BSTR_ERR; + + for (i = b->slen - 1; i >= 0; i--) { + if (!wspace (b->data[i])) { + if (b->mlen > i) b->data[i+1] = (unsigned char) '\0'; + b->slen = i + 1; + for (j = 0; wspace (b->data[j]); j++) {} + return _al_bdelete (b, 0, j); + } + } + + b->data[0] = (unsigned char) '\0'; + b->slen = 0; + return _AL_BSTR_OK; +} + +/* int _al_biseq (_al_const_bstring b0, _al_const_bstring b1) + * + * Compare the string b0 and b1. If the strings differ, 0 is returned, if + * the strings are the same, 1 is returned, if there is an error, -1 is + * returned. If the length of the strings are different, this function is + * O(1). '\0' termination characters are not treated in any special way. + */ +int _al_biseq (_al_const_bstring b0, _al_const_bstring b1) { + if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || + b0->slen < 0 || b1->slen < 0) return _AL_BSTR_ERR; + if (b0->slen != b1->slen) return _AL_BSTR_OK; + if (b0->data == b1->data || b0->slen == 0) return 1; + return !bstr__memcmp (b0->data, b1->data, b0->slen); +} + +/* int _al_bisstemeqblk (_al_const_bstring b0, const void * blk, int len) + * + * Compare beginning of string b0 with a block of memory of length len for + * equality. If the beginning of b0 differs from the memory block (or if b0 + * is too short), 0 is returned, if the strings are the same, 1 is returned, + * if there is an error, -1 is returned. '\0' characters are not treated in + * any special way. + */ +int _al_bisstemeqblk (_al_const_bstring b0, const void * blk, int len) { +int i; + + if (_al_bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0) + return _AL_BSTR_ERR; + if (b0->slen < len) return _AL_BSTR_OK; + if (b0->data == (const unsigned char *) blk || len == 0) return 1; + + for (i = 0; i < len; i ++) { + if (b0->data[i] != ((const unsigned char *) blk)[i]) return _AL_BSTR_OK; + } + return 1; +} + +/* int _al_biseqcstr (_al_const_bstring b, const char *s) + * + * Compare the _al_bstring b and char * string s. The C string s must be '\0' + * terminated at exactly the length of the _al_bstring b, and the contents + * between the two must be identical with the _al_bstring b with no '\0' + * characters for the two contents to be considered equal. This is + * equivalent to the condition that their current contents will be always be + * equal when comparing them in the same format after converting one or the + * other. If the strings are equal 1 is returned, if they are unequal 0 is + * returned and if there is a detectable error _AL_BSTR_ERR is returned. + */ +int _al_biseqcstr (_al_const_bstring b, const char * s) { +int i; + if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return _AL_BSTR_ERR; + for (i=0; i < b->slen; i++) { + if (s[i] == '\0' || b->data[i] != (unsigned char) s[i]) return _AL_BSTR_OK; + } + return s[i] == '\0'; +} + +/* int _al_biseqcstrcaseless (_al_const_bstring b, const char *s) + * + * Compare the _al_bstring b and char * string s. The C string s must be '\0' + * terminated at exactly the length of the _al_bstring b, and the contents + * between the two must be identical except for case with the _al_bstring b with + * no '\0' characters for the two contents to be considered equal. This is + * equivalent to the condition that their current contents will be always be + * equal ignoring case when comparing them in the same format after + * converting one or the other. If the strings are equal, except for case, + * 1 is returned, if they are unequal regardless of case 0 is returned and + * if there is a detectable error _AL_BSTR_ERR is returned. + */ +int _al_biseqcstrcaseless (_al_const_bstring b, const char * s) { +int i; + if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return _AL_BSTR_ERR; + for (i=0; i < b->slen; i++) { + if (s[i] == '\0' || + (b->data[i] != (unsigned char) s[i] && + downcase (b->data[i]) != (unsigned char) downcase (s[i]))) + return _AL_BSTR_OK; + } + return s[i] == '\0'; +} + +/* int _al_bstrcmp (_al_const_bstring b0, _al_const_bstring b1) + * + * Compare the string b0 and b1. If there is an error, SHRT_MIN is returned, + * otherwise a value less than or greater than zero, indicating that the + * string pointed to by b0 is lexicographically less than or greater than + * the string pointed to by b1 is returned. If the the string lengths are + * unequal but the characters up until the length of the shorter are equal + * then a value less than, or greater than zero, indicating that the string + * pointed to by b0 is shorter or longer than the string pointed to by b1 is + * returned. 0 is returned if and only if the two strings are the same. If + * the length of the strings are different, this function is O(n). Like its + * standard C library counter part strcmp, the comparison does not proceed + * past any '\0' termination characters encountered. + */ +int _al_bstrcmp (_al_const_bstring b0, _al_const_bstring b1) { +int i, v, n; + + if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || + b0->slen < 0 || b1->slen < 0) return SHRT_MIN; + n = b0->slen; if (n > b1->slen) n = b1->slen; + if (b0->slen == b1->slen && (b0->data == b1->data || b0->slen == 0)) + return _AL_BSTR_OK; + + for (i = 0; i < n; i ++) { + v = ((char) b0->data[i]) - ((char) b1->data[i]); + if (v != 0) return v; + if (b0->data[i] == (unsigned char) '\0') return _AL_BSTR_OK; + } + + if (b0->slen > n) return 1; + if (b1->slen > n) return -1; + return _AL_BSTR_OK; +} + +/* int _al_bstrncmp (_al_const_bstring b0, _al_const_bstring b1, int n) + * + * Compare the string b0 and b1 for at most n characters. If there is an + * error, SHRT_MIN is returned, otherwise a value is returned as if b0 and + * b1 were first truncated to at most n characters then _al_bstrcmp was called + * with these new strings are paremeters. If the length of the strings are + * different, this function is O(n). Like its standard C library counter + * part strcmp, the comparison does not proceed past any '\0' termination + * characters encountered. + */ +int _al_bstrncmp (_al_const_bstring b0, _al_const_bstring b1, int n) { +int i, v, m; + + if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL || + b0->slen < 0 || b1->slen < 0) return SHRT_MIN; + m = n; + if (m > b0->slen) m = b0->slen; + if (m > b1->slen) m = b1->slen; + + if (b0->data != b1->data) { + for (i = 0; i < m; i ++) { + v = ((char) b0->data[i]) - ((char) b1->data[i]); + if (v != 0) return v; + if (b0->data[i] == (unsigned char) '\0') return _AL_BSTR_OK; + } + } + + if (n == m || b0->slen == b1->slen) return _AL_BSTR_OK; + + if (b0->slen > m) return 1; + return -1; +} + +/* _al_bstring _al_bmidstr (_al_const_bstring b, int left, int len) + * + * Create a _al_bstring which is the substring of b starting from position left + * and running for a length len (clamped by the end of the _al_bstring b.) If + * b is detectably invalid, then NULL is returned. The section described + * by (left, len) is clamped to the boundaries of b. + */ +_al_bstring _al_bmidstr (_al_const_bstring b, int left, int len) { + + if (b == NULL || b->slen < 0 || b->data == NULL) return NULL; + + if (left < 0) { + len += left; + left = 0; + } + + if (len > b->slen - left) len = b->slen - left; + + if (len <= 0) return _al_bfromcstr (""); + return _al_blk2bstr (b->data + left, len); +} + +/* int _al_bdelete (_al_bstring b, int pos, int len) + * + * Removes characters from pos to pos+len-1 inclusive and shifts the tail of + * the _al_bstring starting from pos+len to pos. len must be positive for this + * call to have any effect. The section of the string described by (pos, + * len) is clamped to boundaries of the _al_bstring b. + */ +int _al_bdelete (_al_bstring b, int pos, int len) { + /* Clamp to left side of _al_bstring */ + if (pos < 0) { + len += pos; + pos = 0; + } + + if (len < 0 || b == NULL || b->data == NULL || b->slen < 0 || + b->mlen < b->slen || b->mlen <= 0) + return _AL_BSTR_ERR; + if (len > 0 && pos < b->slen) { + if (pos + len >= b->slen) { + b->slen = pos; + } else { + bBlockCopy ((char *) (b->data + pos), + (char *) (b->data + pos + len), + b->slen - (pos+len)); + b->slen -= len; + } + b->data[b->slen] = (unsigned char) '\0'; + } + return _AL_BSTR_OK; +} + +/* int _al_bdestroy (_al_bstring b) + * + * Free up the _al_bstring. Note that if b is detectably invalid or not writable + * then no action is performed and _AL_BSTR_ERR is returned. Like a freed memory + * allocation, dereferences, writes or any other action on b after it has + * been bdestroyed is undefined. + */ +int _al_bdestroy (_al_bstring b) { + if (b == NULL || b->slen < 0 || b->mlen <= 0 || b->mlen < b->slen || + b->data == NULL) + return _AL_BSTR_ERR; + + bstr__free (b->data); + + /* In case there is any stale usage, there is one more chance to + notice this error. */ + + b->slen = -1; + b->mlen = -__LINE__; + b->data = NULL; + + bstr__free (b); + return _AL_BSTR_OK; +} + +/* int _al_binstr (_al_const_bstring b1, int pos, _al_const_bstring b2) + * + * Search for the _al_bstring b2 in b1 starting from position pos, and searching + * forward. If it is found then return with the first position where it is + * found, otherwise return _AL_BSTR_ERR. Note that this is just a brute force + * string searcher that does not attempt clever things like the Boyer-Moore + * search algorithm. Because of this there are many degenerate cases where + * this can take much longer than it needs to. + */ +int _al_binstr (_al_const_bstring b1, int pos, _al_const_bstring b2) { +int j, ii, ll, lf; +unsigned char * d0; +unsigned char c0; +register unsigned char * d1; +register unsigned char c1; +register int i; + + if (b1 == NULL || b1->data == NULL || b1->slen < 0 || + b2 == NULL || b2->data == NULL || b2->slen < 0) return _AL_BSTR_ERR; + if (b1->slen == pos) return (b2->slen == 0)?pos:_AL_BSTR_ERR; + if (b1->slen < pos || pos < 0) return _AL_BSTR_ERR; + if (b2->slen == 0) return pos; + + /* No space to find such a string? */ + if ((lf = b1->slen - b2->slen + 1) <= pos) return _AL_BSTR_ERR; + + /* An obvious alias case */ + if (b1->data == b2->data && pos == 0) return 0; + + i = pos; + + d0 = b2->data; + d1 = b1->data; + ll = b2->slen; + + /* Peel off the b2->slen == 1 case */ + c0 = d0[0]; + if (1 == ll) { + for (;i < lf; i++) if (c0 == d1[i]) return i; + return _AL_BSTR_ERR; + } + + c1 = c0; + j = 0; + lf = b1->slen - 1; + + ii = -1; + if (i < lf) do { + /* Unrolled current character test */ + if (c1 != d1[i]) { + if (c1 != d1[1+i]) { + i += 2; + continue; + } + i++; + } + + /* Take note if this is the start of a potential match */ + if (0 == j) ii = i; + + /* Shift the test character down by one */ + j++; + i++; + + /* If this isn't past the last character continue */ + if (j < ll) { + c1 = d0[j]; + continue; + } + + N0:; + + /* If no characters mismatched, then we matched */ + if (i == ii+j) return ii; + + /* Shift back to the beginning */ + i -= j; + j = 0; + c1 = c0; + } while (i < lf); + + /* Deal with last case if unrolling caused a misalignment */ + if (i == lf && ll == j+1 && c1 == d1[i]) goto N0; + + return _AL_BSTR_ERR; +} + +/* int _al_binstrr (_al_const_bstring b1, int pos, _al_const_bstring b2) + * + * Search for the _al_bstring b2 in b1 starting from position pos, and searching + * backward. If it is found then return with the first position where it is + * found, otherwise return _AL_BSTR_ERR. Note that this is just a brute force + * string searcher that does not attempt clever things like the Boyer-Moore + * search algorithm. Because of this there are many degenerate cases where + * this can take much longer than it needs to. + */ +int _al_binstrr (_al_const_bstring b1, int pos, _al_const_bstring b2) { +int j, i, l; +unsigned char * d0, * d1; + + if (b1 == NULL || b1->data == NULL || b1->slen < 0 || + b2 == NULL || b2->data == NULL || b2->slen < 0) return _AL_BSTR_ERR; + if (b1->slen == pos && b2->slen == 0) return pos; + if (b1->slen < pos || pos < 0) return _AL_BSTR_ERR; + if (b2->slen == 0) return pos; + + /* Obvious alias case */ + if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return 0; + + i = pos; + if ((l = b1->slen - b2->slen) < 0) return _AL_BSTR_ERR; + + /* If no space to find such a string then snap back */ + if (l + 1 <= i) i = l; + j = 0; + + d0 = b2->data; + d1 = b1->data; + l = b2->slen; + + for (;;) { + if (d0[j] == d1[i + j]) { + j ++; + if (j >= l) return i; + } else { + i --; + if (i < 0) break; + j=0; + } + } + + return _AL_BSTR_ERR; +} + +/* int _al_binstrcaseless (_al_const_bstring b1, int pos, _al_const_bstring b2) + * + * Search for the _al_bstring b2 in b1 starting from position pos, and searching + * forward but without regard to case. If it is found then return with the + * first position where it is found, otherwise return _AL_BSTR_ERR. Note that + * this is just a brute force string searcher that does not attempt clever + * things like the Boyer-Moore search algorithm. Because of this there are + * many degenerate cases where this can take much longer than it needs to. + */ +int _al_binstrcaseless (_al_const_bstring b1, int pos, _al_const_bstring b2) { +int j, i, l, ll; +unsigned char * d0, * d1; + + if (b1 == NULL || b1->data == NULL || b1->slen < 0 || + b2 == NULL || b2->data == NULL || b2->slen < 0) return _AL_BSTR_ERR; + if (b1->slen == pos) return (b2->slen == 0)?pos:_AL_BSTR_ERR; + if (b1->slen < pos || pos < 0) return _AL_BSTR_ERR; + if (b2->slen == 0) return pos; + + l = b1->slen - b2->slen + 1; + + /* No space to find such a string? */ + if (l <= pos) return _AL_BSTR_ERR; + + /* An obvious alias case */ + if (b1->data == b2->data && pos == 0) return _AL_BSTR_OK; + + i = pos; + j = 0; + + d0 = b2->data; + d1 = b1->data; + ll = b2->slen; + + for (;;) { + if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) { + j ++; + if (j >= ll) return i; + } else { + i ++; + if (i >= l) break; + j=0; + } + } + + return _AL_BSTR_ERR; +} + +/* int _al_binstrrcaseless (_al_const_bstring b1, int pos, _al_const_bstring b2) + * + * Search for the _al_bstring b2 in b1 starting from position pos, and searching + * backward but without regard to case. If it is found then return with the + * first position where it is found, otherwise return _AL_BSTR_ERR. Note that + * this is just a brute force string searcher that does not attempt clever + * things like the Boyer-Moore search algorithm. Because of this there are + * many degenerate cases where this can take much longer than it needs to. + */ +int _al_binstrrcaseless (_al_const_bstring b1, int pos, _al_const_bstring b2) { +int j, i, l; +unsigned char * d0, * d1; + + if (b1 == NULL || b1->data == NULL || b1->slen < 0 || + b2 == NULL || b2->data == NULL || b2->slen < 0) return _AL_BSTR_ERR; + if (b1->slen == pos && b2->slen == 0) return pos; + if (b1->slen < pos || pos < 0) return _AL_BSTR_ERR; + if (b2->slen == 0) return pos; + + /* Obvious alias case */ + if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return _AL_BSTR_OK; + + i = pos; + if ((l = b1->slen - b2->slen) < 0) return _AL_BSTR_ERR; + + /* If no space to find such a string then snap back */ + if (l + 1 <= i) i = l; + j = 0; + + d0 = b2->data; + d1 = b1->data; + l = b2->slen; + + for (;;) { + if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) { + j ++; + if (j >= l) return i; + } else { + i --; + if (i < 0) break; + j=0; + } + } + + return _AL_BSTR_ERR; +} + + +/* int _al_bstrchrp (_al_const_bstring b, int c, int pos) + * + * Search for the character c in b forwards from the position pos + * (inclusive). + */ +int _al_bstrchrp (_al_const_bstring b, int c, int pos) { +unsigned char * p; + + if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return _AL_BSTR_ERR; + p = (unsigned char *) bstr__memchr ((b->data + pos), (unsigned char) c, (b->slen - pos)); + if (p) return (int) (p - b->data); + return _AL_BSTR_ERR; +} + +/* int _al_bstrrchrp (_al_const_bstring b, int c, int pos) + * + * Search for the character c in b backwards from the position pos in string + * (inclusive). + */ +int _al_bstrrchrp (_al_const_bstring b, int c, int pos) { +int i; + + if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return _AL_BSTR_ERR; + for (i=pos; i >= 0; i--) { + if (b->data[i] == (unsigned char) c) return i; + } + return _AL_BSTR_ERR; +} + +#if !defined (BSTRLIB_AGGRESSIVE_MEMORY_FOR_SPEED_TRADEOFF) +#define LONG_LOG_BITS_QTY (3) +#define LONG_BITS_QTY (1 << LONG_LOG_BITS_QTY) +#define LONG_TYPE unsigned char + +#define CFCLEN ((1 << CHAR_BIT) / LONG_BITS_QTY) +struct charField { LONG_TYPE content[CFCLEN]; }; +#define testInCharField(cf,c) ((cf)->content[(c) >> LONG_LOG_BITS_QTY] & (((long)1) << ((c) & (LONG_BITS_QTY-1)))) +#define setInCharField(cf,idx) { \ + unsigned int c = (unsigned int) (idx); \ + (cf)->content[c >> LONG_LOG_BITS_QTY] |= (LONG_TYPE) (1ul << (c & (LONG_BITS_QTY-1))); \ +} + +#else + +#define CFCLEN (1 << CHAR_BIT) +struct charField { unsigned char content[CFCLEN]; }; +#define testInCharField(cf,c) ((cf)->content[(unsigned char) (c)]) +#define setInCharField(cf,idx) (cf)->content[(unsigned int) (idx)] = ~0 + +#endif + +/* Convert a _al_bstring to charField */ +static int buildCharField (struct charField * cf, _al_const_bstring b) { +int i; + if (b == NULL || b->data == NULL || b->slen <= 0) return _AL_BSTR_ERR; + memset ((void *) cf->content, 0, sizeof (struct charField)); + for (i=0; i < b->slen; i++) { + setInCharField (cf, b->data[i]); + } + return _AL_BSTR_OK; +} + +static void invertCharField (struct charField * cf) { +int i; + for (i=0; i < CFCLEN; i++) cf->content[i] = ~cf->content[i]; +} + +/* Inner engine for _al_binchr */ +static int binchrCF (const unsigned char * data, int len, int pos, const struct charField * cf) { +int i; + for (i=pos; i < len; i++) { + unsigned char c = (unsigned char) data[i]; + if (testInCharField (cf, c)) return i; + } + return _AL_BSTR_ERR; +} + +/* int _al_binchr (_al_const_bstring b0, int pos, _al_const_bstring b1); + * + * Search for the first position in b0 starting from pos or after, in which + * one of the characters in b1 is found and return it. If such a position + * does not exist in b0, then _AL_BSTR_ERR is returned. + */ +int _al_binchr (_al_const_bstring b0, int pos, _al_const_bstring b1) { +struct charField chrs; + if (pos < 0 || b0 == NULL || b0->data == NULL || + b0->slen <= pos) return _AL_BSTR_ERR; + if (1 == b1->slen) return _al_bstrchrp (b0, b1->data[0], pos); + if (0 > buildCharField (&chrs, b1)) return _AL_BSTR_ERR; + return binchrCF (b0->data, b0->slen, pos, &chrs); +} + +/* Inner engine for _al_binchrr */ +static int binchrrCF (const unsigned char * data, int pos, const struct charField * cf) { +int i; + for (i=pos; i >= 0; i--) { + unsigned int c = (unsigned int) data[i]; + if (testInCharField (cf, c)) return i; + } + return _AL_BSTR_ERR; +} + +/* int _al_binchrr (_al_const_bstring b0, int pos, _al_const_bstring b1); + * + * Search for the last position in b0 no greater than pos, in which one of + * the characters in b1 is found and return it. If such a position does not + * exist in b0, then _AL_BSTR_ERR is returned. + */ +int _al_binchrr (_al_const_bstring b0, int pos, _al_const_bstring b1) { +struct charField chrs; + if (pos < 0 || b0 == NULL || b0->data == NULL || b1 == NULL || + b0->slen < pos) return _AL_BSTR_ERR; + if (pos == b0->slen) pos--; + if (1 == b1->slen) return _al_bstrrchrp (b0, b1->data[0], pos); + if (0 > buildCharField (&chrs, b1)) return _AL_BSTR_ERR; + return binchrrCF (b0->data, pos, &chrs); +} + +/* int _al_bninchr (_al_const_bstring b0, int pos, _al_const_bstring b1); + * + * Search for the first position in b0 starting from pos or after, in which + * none of the characters in b1 is found and return it. If such a position + * does not exist in b0, then _AL_BSTR_ERR is returned. + */ +int _al_bninchr (_al_const_bstring b0, int pos, _al_const_bstring b1) { +struct charField chrs; + if (pos < 0 || b0 == NULL || b0->data == NULL || + b0->slen <= pos) return _AL_BSTR_ERR; + if (buildCharField (&chrs, b1) < 0) return _AL_BSTR_ERR; + invertCharField (&chrs); + return binchrCF (b0->data, b0->slen, pos, &chrs); +} + +/* int _al_bninchrr (_al_const_bstring b0, int pos, _al_const_bstring b1); + * + * Search for the last position in b0 no greater than pos, in which none of + * the characters in b1 is found and return it. If such a position does not + * exist in b0, then _AL_BSTR_ERR is returned. + */ +int _al_bninchrr (_al_const_bstring b0, int pos, _al_const_bstring b1) { +struct charField chrs; + if (pos < 0 || b0 == NULL || b0->data == NULL || + b0->slen < pos) return _AL_BSTR_ERR; + if (pos == b0->slen) pos--; + if (buildCharField (&chrs, b1) < 0) return _AL_BSTR_ERR; + invertCharField (&chrs); + return binchrrCF (b0->data, pos, &chrs); +} + +/* int _al_bsetstr (_al_bstring b0, int pos, _al_bstring b1, unsigned char fill) + * + * Overwrite the string b0 starting at position pos with the string b1. If + * the position pos is past the end of b0, then the character "fill" is + * appended as necessary to make up the gap between the end of b0 and pos. + * If b1 is NULL, it behaves as if it were a 0-length string. + */ +int _al_bsetstr (_al_bstring b0, int pos, _al_const_bstring b1, unsigned char fill) { +int d, newlen; +ptrdiff_t pd; +_al_bstring aux = (_al_bstring) b1; + + if (pos < 0 || b0 == NULL || b0->slen < 0 || NULL == b0->data || + b0->mlen < b0->slen || b0->mlen <= 0) return _AL_BSTR_ERR; + if (b1 != NULL && (b1->slen < 0 || b1->data == NULL)) return _AL_BSTR_ERR; + + d = pos; + + /* Aliasing case */ + if (NULL != aux) { + if ((pd = (ptrdiff_t) (b1->data - b0->data)) >= 0 && pd < (ptrdiff_t) b0->mlen) { + if (NULL == (aux = _al_bstrcpy (b1))) return _AL_BSTR_ERR; + } + d += aux->slen; + } + + /* Increase memory size if necessary */ + if (_al_balloc (b0, d + 1) != _AL_BSTR_OK) { + if (aux != b1) _al_bdestroy (aux); + return _AL_BSTR_ERR; + } + + newlen = b0->slen; + + /* Fill in "fill" character as necessary */ + if (pos > newlen) { + bstr__memset (b0->data + b0->slen, (int) fill, (size_t) (pos - b0->slen)); + newlen = pos; + } + + /* Copy b1 to position pos in b0. */ + if (aux != NULL) { + bBlockCopy ((char *) (b0->data + pos), (char *) aux->data, aux->slen); + if (aux != b1) _al_bdestroy (aux); + } + + /* Indicate the potentially increased size of b0 */ + if (d > newlen) newlen = d; + + b0->slen = newlen; + b0->data[newlen] = (unsigned char) '\0'; + + return _AL_BSTR_OK; +} + +/* int _al_binsert (_al_bstring b1, int pos, _al_bstring b2, unsigned char fill) + * + * Inserts the string b2 into b1 at position pos. If the position pos is + * past the end of b1, then the character "fill" is appended as necessary to + * make up the gap between the end of b1 and pos. Unlike _al_bsetstr, _al_binsert + * does not allow b2 to be NULL. + */ +int _al_binsert (_al_bstring b1, int pos, _al_const_bstring b2, unsigned char fill) { +int d, l; +ptrdiff_t pd; +_al_bstring aux = (_al_bstring) b2; + + if (pos < 0 || b1 == NULL || b2 == NULL || b1->slen < 0 || + b2->slen < 0 || b1->mlen < b1->slen || b1->mlen <= 0) return _AL_BSTR_ERR; + + /* Aliasing case */ + if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->mlen) { + if (NULL == (aux = _al_bstrcpy (b2))) return _AL_BSTR_ERR; + } + + /* Compute the two possible end pointers */ + d = b1->slen + aux->slen; + l = pos + aux->slen; + if ((d|l) < 0) return _AL_BSTR_ERR; + + if (l > d) { + /* Inserting past the end of the string */ + if (_al_balloc (b1, l + 1) != _AL_BSTR_OK) { + if (aux != b2) _al_bdestroy (aux); + return _AL_BSTR_ERR; + } + bstr__memset (b1->data + b1->slen, (int) fill, (size_t) (pos - b1->slen)); + b1->slen = l; + } else { + /* Inserting in the middle of the string */ + if (_al_balloc (b1, d + 1) != _AL_BSTR_OK) { + if (aux != b2) _al_bdestroy (aux); + return _AL_BSTR_ERR; + } + bBlockCopy (b1->data + l, b1->data + pos, d - l); + b1->slen = d; + } + bBlockCopy (b1->data + pos, aux->data, aux->slen); + b1->data[b1->slen] = (unsigned char) '\0'; + if (aux != b2) _al_bdestroy (aux); + return _AL_BSTR_OK; +} + +/* int _al_breplace (_al_bstring b1, int pos, int len, _al_bstring b2, + * unsigned char fill) + * + * Replace a section of a string from pos for a length len with the string b2. + * fill is used is pos > b1->slen. + */ +int _al_breplace (_al_bstring b1, int pos, int len, _al_const_bstring b2, + unsigned char fill) { +int pl, ret; +ptrdiff_t pd; +_al_bstring aux = (_al_bstring) b2; + + if (pos < 0 || len < 0 || (pl = pos + len) < 0 || b1 == NULL || + b2 == NULL || b1->data == NULL || b2->data == NULL || + b1->slen < 0 || b2->slen < 0 || b1->mlen < b1->slen || + b1->mlen <= 0) return _AL_BSTR_ERR; + + /* Straddles the end? */ + if (pl >= b1->slen) { + if ((ret = _al_bsetstr (b1, pos, b2, fill)) < 0) return ret; + if (pos + b2->slen < b1->slen) { + b1->slen = pos + b2->slen; + b1->data[b1->slen] = (unsigned char) '\0'; + } + return ret; + } + + /* Aliasing case */ + if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->slen) { + if (NULL == (aux = _al_bstrcpy (b2))) return _AL_BSTR_ERR; + } + + if (aux->slen > len) { + if (_al_balloc (b1, b1->slen + aux->slen - len) != _AL_BSTR_OK) { + if (aux != b2) _al_bdestroy (aux); + return _AL_BSTR_ERR; + } + } + + if (aux->slen != len) bstr__memmove (b1->data + pos + aux->slen, b1->data + pos + len, b1->slen - (pos + len)); + bstr__memcpy (b1->data + pos, aux->data, aux->slen); + b1->slen += aux->slen - len; + b1->data[b1->slen] = (unsigned char) '\0'; + if (aux != b2) _al_bdestroy (aux); + return _AL_BSTR_OK; +} + +/* int _al_bfindreplace (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, + * int pos) + * + * Replace all occurrences of a find string with a replace string after a + * given point in a _al_bstring. + */ + +typedef int (*instr_fnptr) (_al_const_bstring s1, int pos, _al_const_bstring s2); + +static int findreplaceengine (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos, instr_fnptr instr) { +int i, ret, slen, mlen, delta, acc; +int * d; +int static_d[32]; +ptrdiff_t pd; +_al_bstring auxf = (_al_bstring) find; +_al_bstring auxr = (_al_bstring) repl; + + if (b == NULL || b->data == NULL || find == NULL || + find->data == NULL || repl == NULL || repl->data == NULL || + pos < 0 || find->slen <= 0 || b->mlen < 0 || b->slen > b->mlen || + b->mlen <= 0 || b->slen < 0 || repl->slen < 0) return _AL_BSTR_ERR; + if (pos > b->slen - find->slen) return _AL_BSTR_OK; + + /* Alias with find string */ + pd = (ptrdiff_t) (find->data - b->data); + if ((ptrdiff_t) (pos - find->slen) < pd && pd < (ptrdiff_t) b->slen) { + if (NULL == (auxf = _al_bstrcpy (find))) return _AL_BSTR_ERR; + } + + /* Alias with repl string */ + pd = (ptrdiff_t) (repl->data - b->data); + if ((ptrdiff_t) (pos - repl->slen) < pd && pd < (ptrdiff_t) b->slen) { + if (NULL == (auxr = _al_bstrcpy (repl))) { + if (auxf != find) _al_bdestroy (auxf); + return _AL_BSTR_ERR; + } + } + + delta = auxf->slen - auxr->slen; + + /* in-place replacement since find and replace strings are of equal + length */ + if (delta == 0) { + while ((pos = instr (b, pos, auxf)) >= 0) { + bstr__memcpy (b->data + pos, auxr->data, auxr->slen); + pos += auxf->slen; + } + if (auxf != find) _al_bdestroy (auxf); + if (auxr != repl) _al_bdestroy (auxr); + return _AL_BSTR_OK; + } + + /* shrinking replacement since auxf->slen > auxr->slen */ + if (delta > 0) { + acc = 0; + + while ((i = instr (b, pos, auxf)) >= 0) { + if (acc && i > pos) + bstr__memmove (b->data + pos - acc, b->data + pos, i - pos); + if (auxr->slen) + bstr__memcpy (b->data + i - acc, auxr->data, auxr->slen); + acc += delta; + pos = i + auxf->slen; + } + + if (acc) { + i = b->slen; + if (i > pos) + bstr__memmove (b->data + pos - acc, b->data + pos, i - pos); + b->slen -= acc; + b->data[b->slen] = (unsigned char) '\0'; + } + + if (auxf != find) _al_bdestroy (auxf); + if (auxr != repl) _al_bdestroy (auxr); + return _AL_BSTR_OK; + } + + /* expanding replacement since find->slen < repl->slen. Its a lot + more complicated. */ + + mlen = 32; + d = (int *) static_d; /* Avoid malloc for trivial cases */ + acc = slen = 0; + + while ((pos = instr (b, pos, auxf)) >= 0) { + if (slen + 1 >= mlen) { + int sl; + int * t; + mlen += mlen; + sl = sizeof (int *) * mlen; + if (static_d == d) d = NULL; + if (sl < mlen || NULL == (t = (int *) bstr__realloc (d, sl))) { + ret = _AL_BSTR_ERR; + goto done; + } + if (NULL == d) bstr__memcpy (t, static_d, sizeof (static_d)); + d = t; + } + d[slen] = pos; + slen++; + acc -= delta; + pos += auxf->slen; + if (pos < 0 || acc < 0) { + ret = _AL_BSTR_ERR; + goto done; + } + } + d[slen] = b->slen; + + if (_AL_BSTR_OK == (ret = _al_balloc (b, b->slen + acc + 1))) { + b->slen += acc; + for (i = slen-1; i >= 0; i--) { + int s, l; + s = d[i] + auxf->slen; + l = d[i+1] - s; + if (l) { + bstr__memmove (b->data + s + acc, b->data + s, l); + } + if (auxr->slen) { + bstr__memmove (b->data + s + acc - auxr->slen, + auxr->data, auxr->slen); + } + acc += delta; + } + b->data[b->slen] = (unsigned char) '\0'; + } + + done:; + if (static_d == d) d = NULL; + bstr__free (d); + if (auxf != find) _al_bdestroy (auxf); + if (auxr != repl) _al_bdestroy (auxr); + return ret; +} + +/* int _al_bfindreplace (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, + * int pos) + * + * Replace all occurrences of a find string with a replace string after a + * given point in a _al_bstring. + */ +int _al_bfindreplace (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos) { + return findreplaceengine (b, find, repl, pos, _al_binstr); +} + +/* int _al_bfindreplacecaseless (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, + * int pos) + * + * Replace all occurrences of a find string, ignoring case, with a replace + * string after a given point in a _al_bstring. + */ +int _al_bfindreplacecaseless (_al_bstring b, _al_const_bstring find, _al_const_bstring repl, int pos) { + return findreplaceengine (b, find, repl, pos, _al_binstrcaseless); +} + +/* int _al_binsertch (_al_bstring b, int pos, int len, unsigned char fill) + * + * Inserts the character fill repeatedly into b at position pos for a + * length len. If the position pos is past the end of b, then the + * character "fill" is appended as necessary to make up the gap between the + * end of b and the position pos + len. + */ +int _al_binsertch (_al_bstring b, int pos, int len, unsigned char fill) { +int d, l, i; + + if (pos < 0 || b == NULL || b->slen < 0 || b->mlen < b->slen || + b->mlen <= 0 || len < 0) return _AL_BSTR_ERR; + + /* Compute the two possible end pointers */ + d = b->slen + len; + l = pos + len; + if ((d|l) < 0) return _AL_BSTR_ERR; + + if (l > d) { + /* Inserting past the end of the string */ + if (_al_balloc (b, l + 1) != _AL_BSTR_OK) return _AL_BSTR_ERR; + pos = b->slen; + b->slen = l; + } else { + /* Inserting in the middle of the string */ + if (_al_balloc (b, d + 1) != _AL_BSTR_OK) return _AL_BSTR_ERR; + for (i = d - 1; i >= l; i--) { + b->data[i] = b->data[i - len]; + } + b->slen = d; + } + + for (i=pos; i < l; i++) b->data[i] = fill; + b->data[b->slen] = (unsigned char) '\0'; + return _AL_BSTR_OK; +} + +/* int _al_bpattern (_al_bstring b, int len) + * + * Replicate the _al_bstring, b in place, end to end repeatedly until it + * surpasses len characters, then chop the result to exactly len characters. + * This function operates in-place. The function will return with _AL_BSTR_ERR + * if b is NULL or of length 0, otherwise _AL_BSTR_OK is returned. + */ +int _al_bpattern (_al_bstring b, int len) { +int i, d; + + d = _al_blength (b); + if (d <= 0 || len < 0 || _al_balloc (b, len + 1) != _AL_BSTR_OK) return _AL_BSTR_ERR; + if (len > 0) { + if (d == 1) return _al_bsetstr (b, len, NULL, b->data[0]); + for (i = d; i < len; i++) b->data[i] = b->data[i - d]; + } + b->data[len] = (unsigned char) '\0'; + b->slen = len; + return _AL_BSTR_OK; +} + +#define BS_BUFF_SZ (1024) + +/* int _al_breada (_al_bstring b, _al_bNread readPtr, void * parm) + * + * Use a finite buffer fread-like function readPtr to concatenate to the + * _al_bstring b the entire contents of file-like source data in a roughly + * efficient way. + */ +int _al_breada (_al_bstring b, _al_bNread readPtr, void * parm) { +int i, l, n; + + if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || + b->mlen <= 0 || readPtr == NULL) return _AL_BSTR_ERR; + + i = b->slen; + for (n=i+16; ; n += ((n < BS_BUFF_SZ) ? n : BS_BUFF_SZ)) { + if (_AL_BSTR_OK != _al_balloc (b, n + 1)) return _AL_BSTR_ERR; + l = (int) readPtr ((void *) (b->data + i), 1, n - i, parm); + i += l; + b->slen = i; + if (i < n) break; + } + + b->data[i] = (unsigned char) '\0'; + return _AL_BSTR_OK; +} + +/* _al_bstring _al_bread (_al_bNread readPtr, void * parm) + * + * Use a finite buffer fread-like function readPtr to create a _al_bstring + * filled with the entire contents of file-like source data in a roughly + * efficient way. + */ +_al_bstring _al_bread (_al_bNread readPtr, void * parm) { +_al_bstring buff; + + if (0 > _al_breada (buff = _al_bfromcstr (""), readPtr, parm)) { + _al_bdestroy (buff); + return NULL; + } + return buff; +} + +/* int _al_bassigngets (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator) + * + * Use an fgetc-like single character stream reading function (getcPtr) to + * obtain a sequence of characters which are concatenated to the end of the + * _al_bstring b. The stream read is terminated by the passed in terminator + * parameter. + * + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the + * function returns with a partial result in b. If there is an empty partial + * result, 1 is returned. If no characters are read, or there is some other + * detectable error, _AL_BSTR_ERR is returned. + */ +int _al_bassigngets (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator) { +int c, d, e; + + if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || + b->mlen <= 0 || getcPtr == NULL) return _AL_BSTR_ERR; + d = 0; + e = b->mlen - 2; + + while ((c = getcPtr (parm)) >= 0) { + if (d > e) { + b->slen = d; + if (_al_balloc (b, d + 2) != _AL_BSTR_OK) return _AL_BSTR_ERR; + e = b->mlen - 2; + } + b->data[d] = (unsigned char) c; + d++; + if (c == terminator) break; + } + + b->data[d] = (unsigned char) '\0'; + b->slen = d; + + return d == 0 && c < 0; +} + +/* int _al_bgetsa (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator) + * + * Use an fgetc-like single character stream reading function (getcPtr) to + * obtain a sequence of characters which are concatenated to the end of the + * _al_bstring b. The stream read is terminated by the passed in terminator + * parameter. + * + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the + * function returns with a partial result concatentated to b. If there is + * an empty partial result, 1 is returned. If no characters are read, or + * there is some other detectable error, _AL_BSTR_ERR is returned. + */ +int _al_bgetsa (_al_bstring b, _al_bNgetc getcPtr, void * parm, char terminator) { +int c, d, e; + + if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen || + b->mlen <= 0 || getcPtr == NULL) return _AL_BSTR_ERR; + d = b->slen; + e = b->mlen - 2; + + while ((c = getcPtr (parm)) >= 0) { + if (d > e) { + b->slen = d; + if (_al_balloc (b, d + 2) != _AL_BSTR_OK) return _AL_BSTR_ERR; + e = b->mlen - 2; + } + b->data[d] = (unsigned char) c; + d++; + if (c == terminator) break; + } + + b->data[d] = (unsigned char) '\0'; + b->slen = d; + + return d == 0 && c < 0; +} + +/* _al_bstring _al_bgets (_al_bNgetc getcPtr, void * parm, char terminator) + * + * Use an fgetc-like single character stream reading function (getcPtr) to + * obtain a sequence of characters which are concatenated into a _al_bstring. + * The stream read is terminated by the passed in terminator function. + * + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the + * result obtained thus far is returned. If no characters are read, or + * there is some other detectable error, NULL is returned. + */ +_al_bstring _al_bgets (_al_bNgetc getcPtr, void * parm, char terminator) { +_al_bstring buff; + + if (0 > _al_bgetsa (buff = _al_bfromcstr (""), getcPtr, parm, terminator) || 0 >= buff->slen) { + _al_bdestroy (buff); + buff = NULL; + } + return buff; +} + +struct _al_bStream { + _al_bstring buff; /* Buffer for over-reads */ + void * parm; /* The stream handle for core stream */ + _al_bNread readFnPtr; /* fread compatible fnptr for core stream */ + int isEOF; /* track file's EOF state */ + int maxBuffSz; +}; + +/* struct _al_bStream * _al_bsopen (_al_bNread readPtr, void * parm) + * + * Wrap a given open stream (described by a fread compatible function + * pointer and stream handle) into an open _al_bStream suitable for the _al_bstring + * library streaming functions. + */ +struct _al_bStream * _al_bsopen (_al_bNread readPtr, void * parm) { +struct _al_bStream * s; + + if (readPtr == NULL) return NULL; + s = (struct _al_bStream *) bstr__alloc (sizeof (struct _al_bStream)); + if (s == NULL) return NULL; + s->parm = parm; + s->buff = _al_bfromcstr (""); + s->readFnPtr = readPtr; + s->maxBuffSz = BS_BUFF_SZ; + s->isEOF = 0; + return s; +} + +/* int _al_bsbufflength (struct _al_bStream * s, int sz) + * + * Set the length of the buffer used by the _al_bStream. If sz is zero, the + * length is not set. This function returns with the previous length. + */ +int _al_bsbufflength (struct _al_bStream * s, int sz) { +int oldSz; + if (s == NULL || sz < 0) return _AL_BSTR_ERR; + oldSz = s->maxBuffSz; + if (sz > 0) s->maxBuffSz = sz; + return oldSz; +} + +int _al_bseof (const struct _al_bStream * s) { + if (s == NULL || s->readFnPtr == NULL) return _AL_BSTR_ERR; + return s->isEOF && (s->buff->slen == 0); +} + +/* void * _al_bsclose (struct _al_bStream * s) + * + * Close the _al_bStream, and return the handle to the stream that was originally + * used to open the given stream. + */ +void * _al_bsclose (struct _al_bStream * s) { +void * parm; + if (s == NULL) return NULL; + s->readFnPtr = NULL; + if (s->buff) _al_bdestroy (s->buff); + s->buff = NULL; + parm = s->parm; + s->parm = NULL; + s->isEOF = 1; + bstr__free (s); + return parm; +} + +/* int _al_bsreadlna (_al_bstring r, struct _al_bStream * s, char terminator) + * + * Read a _al_bstring terminated by the terminator character or the end of the + * stream from the _al_bStream (s) and return it into the parameter r. This + * function may read additional characters from the core stream that are not + * returned, but will be retained for subsequent read operations. + */ +int _al_bsreadlna (_al_bstring r, struct _al_bStream * s, char terminator) { +int i, l, ret, rlo; +char * b; +struct _al_tagbstring x; + + if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 || + r->slen < 0 || r->mlen < r->slen) return _AL_BSTR_ERR; + l = s->buff->slen; + if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; + b = (char *) s->buff->data; + x.data = (unsigned char *) b; + + /* First check if the current buffer holds the terminator */ + b[l] = terminator; /* Set sentinel */ + for (i=0; b[i] != terminator; i++) ; + if (i < l) { + x.slen = i + 1; + ret = _al_bconcat (r, &x); + s->buff->slen = l; + if (_AL_BSTR_OK == ret) _al_bdelete (s->buff, 0, i + 1); + return _AL_BSTR_OK; + } + + rlo = r->slen; + + /* If not then just concatenate the entire buffer to the output */ + x.slen = l; + if (_AL_BSTR_OK != _al_bconcat (r, &x)) return _AL_BSTR_ERR; + + /* Perform direct in-place reads into the destination to allow for + the minimum of data-copies */ + for (;;) { + if (_AL_BSTR_OK != _al_balloc (r, r->slen + s->maxBuffSz + 1)) return _AL_BSTR_ERR; + b = (char *) (r->data + r->slen); + l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm); + if (l <= 0) { + r->data[r->slen] = (unsigned char) '\0'; + s->buff->slen = 0; + s->isEOF = 1; + /* If nothing was read return with an error message */ + return _AL_BSTR_ERR & -(r->slen == rlo); + } + b[l] = terminator; /* Set sentinel */ + for (i=0; b[i] != terminator; i++) ; + if (i < l) break; + r->slen += l; + } + + /* Terminator found, push over-read back to buffer */ + i++; + r->slen += i; + s->buff->slen = l - i; + bstr__memcpy (s->buff->data, b + i, l - i); + r->data[r->slen] = (unsigned char) '\0'; + return _AL_BSTR_OK; +} + +/* int _al_bsreadlnsa (_al_bstring r, struct _al_bStream * s, _al_bstring term) + * + * Read a _al_bstring terminated by any character in the term string or the end + * of the stream from the _al_bStream (s) and return it into the parameter r. + * This function may read additional characters from the core stream that + * are not returned, but will be retained for subsequent read operations. + */ +int _al_bsreadlnsa (_al_bstring r, struct _al_bStream * s, _al_const_bstring term) { +int i, l, ret, rlo; +unsigned char * b; +struct _al_tagbstring x; +struct charField cf; + + if (s == NULL || s->buff == NULL || r == NULL || term == NULL || + term->data == NULL || r->mlen <= 0 || r->slen < 0 || + r->mlen < r->slen) return _AL_BSTR_ERR; + if (term->slen == 1) return _al_bsreadlna (r, s, term->data[0]); + if (term->slen < 1 || buildCharField (&cf, term)) return _AL_BSTR_ERR; + + l = s->buff->slen; + if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; + b = (unsigned char *) s->buff->data; + x.data = b; + + /* First check if the current buffer holds the terminator */ + b[l] = term->data[0]; /* Set sentinel */ + for (i=0; !testInCharField (&cf, b[i]); i++) ; + if (i < l) { + x.slen = i + 1; + ret = _al_bconcat (r, &x); + s->buff->slen = l; + if (_AL_BSTR_OK == ret) _al_bdelete (s->buff, 0, i + 1); + return _AL_BSTR_OK; + } + + rlo = r->slen; + + /* If not then just concatenate the entire buffer to the output */ + x.slen = l; + if (_AL_BSTR_OK != _al_bconcat (r, &x)) return _AL_BSTR_ERR; + + /* Perform direct in-place reads into the destination to allow for + the minimum of data-copies */ + for (;;) { + if (_AL_BSTR_OK != _al_balloc (r, r->slen + s->maxBuffSz + 1)) return _AL_BSTR_ERR; + b = (unsigned char *) (r->data + r->slen); + l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm); + if (l <= 0) { + r->data[r->slen] = (unsigned char) '\0'; + s->buff->slen = 0; + s->isEOF = 1; + /* If nothing was read return with an error message */ + return _AL_BSTR_ERR & -(r->slen == rlo); + } + + b[l] = term->data[0]; /* Set sentinel */ + for (i=0; !testInCharField (&cf, b[i]); i++) ; + if (i < l) break; + r->slen += l; + } + + /* Terminator found, push over-read back to buffer */ + i++; + r->slen += i; + s->buff->slen = l - i; + bstr__memcpy (s->buff->data, b + i, l - i); + r->data[r->slen] = (unsigned char) '\0'; + return _AL_BSTR_OK; +} + +/* int _al_bsreada (_al_bstring r, struct _al_bStream * s, int n) + * + * Read a _al_bstring of length n (or, if it is fewer, as many bytes as is + * remaining) from the _al_bStream. This function may read additional + * characters from the core stream that are not returned, but will be + * retained for subsequent read operations. This function will not read + * additional characters from the core stream beyond virtual stream pointer. + */ +int _al_bsreada (_al_bstring r, struct _al_bStream * s, int n) { +int l, ret, orslen; +char * b; +struct _al_tagbstring x; + + if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 + || r->slen < 0 || r->mlen < r->slen || n <= 0) return _AL_BSTR_ERR; + + n += r->slen; + if (n <= 0) return _AL_BSTR_ERR; + + l = s->buff->slen; + + orslen = r->slen; + + if (0 == l) { + if (s->isEOF) return _AL_BSTR_ERR; + if (r->mlen > n) { + l = (int) s->readFnPtr (r->data + r->slen, 1, n - r->slen, s->parm); + if (0 >= l || l > n - r->slen) { + s->isEOF = 1; + return _AL_BSTR_ERR; + } + r->slen += l; + r->data[r->slen] = (unsigned char) '\0'; + return 0; + } + } + + if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; + b = (char *) s->buff->data; + x.data = (unsigned char *) b; + + do { + if (l + r->slen >= n) { + x.slen = n - r->slen; + ret = _al_bconcat (r, &x); + s->buff->slen = l; + if (_AL_BSTR_OK == ret) _al_bdelete (s->buff, 0, x.slen); + return _AL_BSTR_ERR & -(r->slen == orslen); + } + + x.slen = l; + if (_AL_BSTR_OK != _al_bconcat (r, &x)) break; + + l = n - r->slen; + if (l > s->maxBuffSz) l = s->maxBuffSz; + + l = (int) s->readFnPtr (b, 1, l, s->parm); + + } while (l > 0); + if (l < 0) l = 0; + if (l == 0) s->isEOF = 1; + s->buff->slen = l; + return _AL_BSTR_ERR & -(r->slen == orslen); +} + +/* int _al_bsreadln (_al_bstring r, struct _al_bStream * s, char terminator) + * + * Read a _al_bstring terminated by the terminator character or the end of the + * stream from the _al_bStream (s) and return it into the parameter r. This + * function may read additional characters from the core stream that are not + * returned, but will be retained for subsequent read operations. + */ +int _al_bsreadln (_al_bstring r, struct _al_bStream * s, char terminator) { + if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0) + return _AL_BSTR_ERR; + if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; + r->slen = 0; + return _al_bsreadlna (r, s, terminator); +} + +/* int _al_bsreadlns (_al_bstring r, struct _al_bStream * s, _al_bstring term) + * + * Read a _al_bstring terminated by any character in the term string or the end + * of the stream from the _al_bStream (s) and return it into the parameter r. + * This function may read additional characters from the core stream that + * are not returned, but will be retained for subsequent read operations. + */ +int _al_bsreadlns (_al_bstring r, struct _al_bStream * s, _al_const_bstring term) { + if (s == NULL || s->buff == NULL || r == NULL || term == NULL + || term->data == NULL || r->mlen <= 0) return _AL_BSTR_ERR; + if (term->slen == 1) return _al_bsreadln (r, s, term->data[0]); + if (term->slen < 1) return _AL_BSTR_ERR; + if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; + r->slen = 0; + return _al_bsreadlnsa (r, s, term); +} + +/* int _al_bsread (_al_bstring r, struct _al_bStream * s, int n) + * + * Read a _al_bstring of length n (or, if it is fewer, as many bytes as is + * remaining) from the _al_bStream. This function may read additional + * characters from the core stream that are not returned, but will be + * retained for subsequent read operations. This function will not read + * additional characters from the core stream beyond virtual stream pointer. + */ +int _al_bsread (_al_bstring r, struct _al_bStream * s, int n) { + if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 + || n <= 0) return _AL_BSTR_ERR; + if (_AL_BSTR_OK != _al_balloc (s->buff, s->maxBuffSz + 1)) return _AL_BSTR_ERR; + r->slen = 0; + return _al_bsreada (r, s, n); +} + +/* int _al_bsunread (struct _al_bStream * s, _al_const_bstring b) + * + * Insert a _al_bstring into the _al_bStream at the current position. These + * characters will be read prior to those that actually come from the core + * stream. + */ +int _al_bsunread (struct _al_bStream * s, _al_const_bstring b) { + if (s == NULL || s->buff == NULL) return _AL_BSTR_ERR; + return _al_binsert (s->buff, 0, b, (unsigned char) '?'); +} + +/* int _al_bspeek (_al_bstring r, const struct _al_bStream * s) + * + * Return the currently buffered characters from the _al_bStream that will be + * read prior to reads from the core stream. + */ +int _al_bspeek (_al_bstring r, const struct _al_bStream * s) { + if (s == NULL || s->buff == NULL) return _AL_BSTR_ERR; + return _al_bassign (r, s->buff); +} + +/* _al_bstring _al_bjoin (const struct _al_bstrList * bl, _al_const_bstring sep); + * + * Join the entries of a _al_bstrList into one _al_bstring by sequentially + * concatenating them with the sep string in between. If there is an error + * NULL is returned, otherwise a _al_bstring with the correct result is returned. + */ +_al_bstring _al_bjoin (const struct _al_bstrList * bl, _al_const_bstring sep) { +_al_bstring b; +int i, c, v; + + if (bl == NULL || bl->qty < 0) return NULL; + if (sep != NULL && (sep->slen < 0 || sep->data == NULL)) return NULL; + + for (i = 0, c = 1; i < bl->qty; i++) { + v = bl->entry[i]->slen; + if (v < 0) return NULL; /* Invalid input */ + c += v; + if (c < 0) return NULL; /* Wrap around ?? */ + } + + if (sep != NULL) c += (bl->qty - 1) * sep->slen; + + b = (_al_bstring) bstr__alloc (sizeof (struct _al_tagbstring)); + if (NULL == b) return NULL; /* Out of memory */ + b->data = (unsigned char *) bstr__alloc (c); + if (b->data == NULL) { + bstr__free (b); + return NULL; + } + + b->mlen = c; + b->slen = c-1; + + for (i = 0, c = 0; i < bl->qty; i++) { + if (i > 0 && sep != NULL) { + bstr__memcpy (b->data + c, sep->data, sep->slen); + c += sep->slen; + } + v = bl->entry[i]->slen; + bstr__memcpy (b->data + c, bl->entry[i]->data, v); + c += v; + } + b->data[c] = (unsigned char) '\0'; + return b; +} + +#define BSSSC_BUFF_LEN (256) + +/* int _al_bssplitscb (struct _al_bStream * s, _al_const_bstring splitStr, + * int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm) + * + * Iterate the set of disjoint sequential substrings read from a stream + * divided by any of the characters in splitStr. An empty splitStr causes + * the whole stream to be iterated once. + * + * Note: At the point of calling the cb function, the _al_bStream pointer is + * pointed exactly at the position right after having read the split + * character. The cb function can act on the stream by causing the _al_bStream + * pointer to move, and _al_bssplitscb will continue by starting the next split + * at the position of the pointer after the return from cb. + * + * However, if the cb causes the _al_bStream s to be destroyed then the cb must + * return with a negative value, otherwise _al_bssplitscb will continue in an + * undefined manner. + */ +int _al_bssplitscb (struct _al_bStream * s, _al_const_bstring splitStr, + int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm) { +struct charField chrs; +_al_bstring buff; +int i, p, ret; + + if (cb == NULL || s == NULL || s->readFnPtr == NULL + || splitStr == NULL || splitStr->slen < 0) return _AL_BSTR_ERR; + + if (NULL == (buff = _al_bfromcstr (""))) return _AL_BSTR_ERR; + + if (splitStr->slen == 0) { + while (_al_bsreada (buff, s, BSSSC_BUFF_LEN) >= 0) ; + if ((ret = cb (parm, 0, buff)) > 0) + ret = 0; + } else { + buildCharField (&chrs, splitStr); + ret = p = i = 0; + for (;;) { + if (i >= buff->slen) { + _al_bsreada (buff, s, BSSSC_BUFF_LEN); + if (i >= buff->slen) { + if (0 < (ret = cb (parm, p, buff))) ret = 0; + break; + } + } + if (testInCharField (&chrs, buff->data[i])) { + struct _al_tagbstring t; + unsigned char c; + + _al_blk2tbstr (t, buff->data + i + 1, buff->slen - (i + 1)); + if ((ret = _al_bsunread (s, &t)) < 0) break; + buff->slen = i; + c = buff->data[i]; + buff->data[i] = (unsigned char) '\0'; + if ((ret = cb (parm, p, buff)) < 0) break; + buff->data[i] = c; + buff->slen = 0; + p += i + 1; + i = -1; + } + i++; + } + } + + _al_bdestroy (buff); + return ret; +} + +/* int _al_bssplitstrcb (struct _al_bStream * s, _al_const_bstring splitStr, + * int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm) + * + * Iterate the set of disjoint sequential substrings read from a stream + * divided by the entire substring splitStr. An empty splitStr causes + * each character of the stream to be iterated. + * + * Note: At the point of calling the cb function, the _al_bStream pointer is + * pointed exactly at the position right after having read the split + * character. The cb function can act on the stream by causing the _al_bStream + * pointer to move, and _al_bssplitscb will continue by starting the next split + * at the position of the pointer after the return from cb. + * + * However, if the cb causes the _al_bStream s to be destroyed then the cb must + * return with a negative value, otherwise _al_bssplitscb will continue in an + * undefined manner. + */ +int _al_bssplitstrcb (struct _al_bStream * s, _al_const_bstring splitStr, + int (* cb) (void * parm, int ofs, _al_const_bstring entry), void * parm) { +_al_bstring buff; +int i, p, ret; + + if (cb == NULL || s == NULL || s->readFnPtr == NULL + || splitStr == NULL || splitStr->slen < 0) return _AL_BSTR_ERR; + + if (splitStr->slen == 1) return _al_bssplitscb (s, splitStr, cb, parm); + + if (NULL == (buff = _al_bfromcstr (""))) return _AL_BSTR_ERR; + + if (splitStr->slen == 0) { + for (i=0; _al_bsreada (buff, s, BSSSC_BUFF_LEN) >= 0; i++) { + if ((ret = cb (parm, 0, buff)) < 0) { + _al_bdestroy (buff); + return ret; + } + buff->slen = 0; + } + return _AL_BSTR_OK; + } else { + ret = p = i = 0; + for (i=p=0;;) { + if ((ret = _al_binstr (buff, 0, splitStr)) >= 0) { + struct _al_tagbstring t; + _al_blk2tbstr (t, buff->data, ret); + i = ret + splitStr->slen; + if ((ret = cb (parm, p, &t)) < 0) break; + p += i; + _al_bdelete (buff, 0, i); + } else { + _al_bsreada (buff, s, BSSSC_BUFF_LEN); + if (_al_bseof (s)) { + if ((ret = cb (parm, p, buff)) > 0) ret = 0; + break; + } + } + } + } + + _al_bdestroy (buff); + return ret; +} + +/* int _al_bstrListCreate (void) + * + * Create a _al_bstrList. + */ +struct _al_bstrList * _al_bstrListCreate (void) { +struct _al_bstrList * sl = (struct _al_bstrList *) bstr__alloc (sizeof (struct _al_bstrList)); + if (sl) { + sl->entry = (_al_bstring *) bstr__alloc (1*sizeof (_al_bstring)); + if (!sl->entry) { + bstr__free (sl); + sl = NULL; + } else { + sl->qty = 0; + sl->mlen = 1; + } + } + return sl; +} + +/* int _al_bstrListDestroy (struct _al_bstrList * sl) + * + * Destroy a _al_bstrList that has been created by _al_bsplit, _al_bsplits or _al_bstrListCreate. + */ +int _al_bstrListDestroy (struct _al_bstrList * sl) { +int i; + if (sl == NULL || sl->qty < 0) return _AL_BSTR_ERR; + for (i=0; i < sl->qty; i++) { + if (sl->entry[i]) { + _al_bdestroy (sl->entry[i]); + sl->entry[i] = NULL; + } + } + sl->qty = -1; + sl->mlen = -1; + bstr__free (sl->entry); + sl->entry = NULL; + bstr__free (sl); + return _AL_BSTR_OK; +} + +/* int _al_bstrListAlloc (struct _al_bstrList * sl, int msz) + * + * Ensure that there is memory for at least msz number of entries for the + * list. + */ +int _al_bstrListAlloc (struct _al_bstrList * sl, int msz) { +_al_bstring * l; +int smsz; +size_t nsz; + if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return _AL_BSTR_ERR; + if (sl->mlen >= msz) return _AL_BSTR_OK; + smsz = snapUpSize (msz); + nsz = ((size_t) smsz) * sizeof (_al_bstring); + if (nsz < (size_t) smsz) return _AL_BSTR_ERR; + l = (_al_bstring *) bstr__realloc (sl->entry, nsz); + if (!l) { + smsz = msz; + nsz = ((size_t) smsz) * sizeof (_al_bstring); + l = (_al_bstring *) bstr__realloc (sl->entry, nsz); + if (!l) return _AL_BSTR_ERR; + } + sl->mlen = smsz; + sl->entry = l; + return _AL_BSTR_OK; +} + +/* int _al_bstrListAllocMin (struct _al_bstrList * sl, int msz) + * + * Try to allocate the minimum amount of memory for the list to include at + * least msz entries or sl->qty whichever is greater. + */ +int _al_bstrListAllocMin (struct _al_bstrList * sl, int msz) { +_al_bstring * l; +size_t nsz; + if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return _AL_BSTR_ERR; + if (msz < sl->qty) msz = sl->qty; + if (sl->mlen == msz) return _AL_BSTR_OK; + nsz = ((size_t) msz) * sizeof (_al_bstring); + if (nsz < (size_t) msz) return _AL_BSTR_ERR; + l = (_al_bstring *) bstr__realloc (sl->entry, nsz); + if (!l) return _AL_BSTR_ERR; + sl->mlen = msz; + sl->entry = l; + return _AL_BSTR_OK; +} + +/* int _al_bsplitcb (_al_const_bstring str, unsigned char splitChar, int pos, + * int (* cb) (void * parm, int ofs, int len), void * parm) + * + * Iterate the set of disjoint sequential substrings over str divided by the + * character in splitChar. + * + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. _al_bsplitcb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, _al_bsplitcb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, + * otherwise _al_bsplitcb will continue in an undefined manner. + */ +int _al_bsplitcb (_al_const_bstring str, unsigned char splitChar, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm) { +int i, p, ret; + + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen) + return _AL_BSTR_ERR; + + p = pos; + do { + for (i=p; i < str->slen; i++) { + if (str->data[i] == splitChar) break; + } + if ((ret = cb (parm, p, i - p)) < 0) return ret; + p = i + 1; + } while (p <= str->slen); + return _AL_BSTR_OK; +} + +/* int _al_bsplitscb (_al_const_bstring str, _al_const_bstring splitStr, int pos, + * int (* cb) (void * parm, int ofs, int len), void * parm) + * + * Iterate the set of disjoint sequential substrings over str divided by any + * of the characters in splitStr. An empty splitStr causes the whole str to + * be iterated once. + * + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. _al_bsplitscb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, _al_bsplitscb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, + * otherwise _al_bsplitscb will continue in an undefined manner. + */ +int _al_bsplitscb (_al_const_bstring str, _al_const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm) { +struct charField chrs; +int i, p, ret; + + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen + || splitStr == NULL || splitStr->slen < 0) return _AL_BSTR_ERR; + if (splitStr->slen == 0) { + if ((ret = cb (parm, 0, str->slen)) > 0) ret = 0; + return ret; + } + + if (splitStr->slen == 1) + return _al_bsplitcb (str, splitStr->data[0], pos, cb, parm); + + buildCharField (&chrs, splitStr); + + p = pos; + do { + for (i=p; i < str->slen; i++) { + if (testInCharField (&chrs, str->data[i])) break; + } + if ((ret = cb (parm, p, i - p)) < 0) return ret; + p = i + 1; + } while (p <= str->slen); + return _AL_BSTR_OK; +} + +/* int _al_bsplitstrcb (_al_const_bstring str, _al_const_bstring splitStr, int pos, + * int (* cb) (void * parm, int ofs, int len), void * parm) + * + * Iterate the set of disjoint sequential substrings over str divided by the + * substring splitStr. An empty splitStr causes the whole str to be + * iterated once. + * + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. _al_bsplitstrcb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, _al_bsplitscb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, + * otherwise _al_bsplitscb will continue in an undefined manner. + */ +int _al_bsplitstrcb (_al_const_bstring str, _al_const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm) { +int i, p, ret; + + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen + || splitStr == NULL || splitStr->slen < 0) return _AL_BSTR_ERR; + + if (0 == splitStr->slen) { + for (i=pos; i < str->slen; i++) { + if ((ret = cb (parm, i, 1)) < 0) return ret; + } + return _AL_BSTR_OK; + } + + if (splitStr->slen == 1) + return _al_bsplitcb (str, splitStr->data[0], pos, cb, parm); + + for (i=p=pos; i <= str->slen - splitStr->slen; i++) { + if (0 == bstr__memcmp (splitStr->data, str->data + i, splitStr->slen)) { + if ((ret = cb (parm, p, i - p)) < 0) return ret; + i += splitStr->slen; + p = i; + } + } + if ((ret = cb (parm, p, str->slen - p)) < 0) return ret; + return _AL_BSTR_OK; +} + +struct genBstrList { + _al_bstring b; + struct _al_bstrList * bl; +}; + +static int bscb (void * parm, int ofs, int len) { +struct genBstrList * g = (struct genBstrList *) parm; + if (g->bl->qty >= g->bl->mlen) { + int mlen = g->bl->mlen * 2; + _al_bstring * tbl; + + while (g->bl->qty >= mlen) { + if (mlen < g->bl->mlen) return _AL_BSTR_ERR; + mlen += mlen; + } + + tbl = (_al_bstring *) bstr__realloc (g->bl->entry, sizeof (_al_bstring) * mlen); + if (tbl == NULL) return _AL_BSTR_ERR; + + g->bl->entry = tbl; + g->bl->mlen = mlen; + } + + g->bl->entry[g->bl->qty] = _al_bmidstr (g->b, ofs, len); + g->bl->qty++; + return _AL_BSTR_OK; +} + +/* struct _al_bstrList * _al_bsplit (_al_const_bstring str, unsigned char splitChar) + * + * Create an array of sequential substrings from str divided by the character + * splitChar. + */ +struct _al_bstrList * _al_bsplit (_al_const_bstring str, unsigned char splitChar) { +struct genBstrList g; + + if (str == NULL || str->data == NULL || str->slen < 0) return NULL; + + g.bl = (struct _al_bstrList *) bstr__alloc (sizeof (struct _al_bstrList)); + if (g.bl == NULL) return NULL; + g.bl->mlen = 4; + g.bl->entry = (_al_bstring *) bstr__alloc (g.bl->mlen * sizeof (_al_bstring)); + if (NULL == g.bl->entry) { + bstr__free (g.bl); + return NULL; + } + + g.b = (_al_bstring) str; + g.bl->qty = 0; + if (_al_bsplitcb (str, splitChar, 0, bscb, &g) < 0) { + _al_bstrListDestroy (g.bl); + return NULL; + } + return g.bl; +} + +/* struct _al_bstrList * _al_bsplitstr (_al_const_bstring str, _al_const_bstring splitStr) + * + * Create an array of sequential substrings from str divided by the entire + * substring splitStr. + */ +struct _al_bstrList * _al_bsplitstr (_al_const_bstring str, _al_const_bstring splitStr) { +struct genBstrList g; + + if (str == NULL || str->data == NULL || str->slen < 0) return NULL; + + g.bl = (struct _al_bstrList *) bstr__alloc (sizeof (struct _al_bstrList)); + if (g.bl == NULL) return NULL; + g.bl->mlen = 4; + g.bl->entry = (_al_bstring *) bstr__alloc (g.bl->mlen * sizeof (_al_bstring)); + if (NULL == g.bl->entry) { + bstr__free (g.bl); + return NULL; + } + + g.b = (_al_bstring) str; + g.bl->qty = 0; + if (_al_bsplitstrcb (str, splitStr, 0, bscb, &g) < 0) { + _al_bstrListDestroy (g.bl); + return NULL; + } + return g.bl; +} + +/* struct _al_bstrList * _al_bsplits (_al_const_bstring str, _al_bstring splitStr) + * + * Create an array of sequential substrings from str divided by any of the + * characters in splitStr. An empty splitStr causes a single entry _al_bstrList + * containing a copy of str to be returned. + */ +struct _al_bstrList * _al_bsplits (_al_const_bstring str, _al_const_bstring splitStr) { +struct genBstrList g; + + if ( str == NULL || str->slen < 0 || str->data == NULL || + splitStr == NULL || splitStr->slen < 0 || splitStr->data == NULL) + return NULL; + + g.bl = (struct _al_bstrList *) bstr__alloc (sizeof (struct _al_bstrList)); + if (g.bl == NULL) return NULL; + g.bl->mlen = 4; + g.bl->entry = (_al_bstring *) bstr__alloc (g.bl->mlen * sizeof (_al_bstring)); + if (NULL == g.bl->entry) { + bstr__free (g.bl); + return NULL; + } + g.b = (_al_bstring) str; + g.bl->qty = 0; + + if (_al_bsplitscb (str, splitStr, 0, bscb, &g) < 0) { + _al_bstrListDestroy (g.bl); + return NULL; + } + return g.bl; +} + +#if defined (__TURBOC__) && !defined (__BORLANDC__) +# ifndef BSTRLIB_NOVSNP +# define BSTRLIB_NOVSNP +# endif +#endif + +/* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */ +#if defined(__WATCOMC__) || defined(_MSC_VER) +#define exvsnprintf(r,b,n,f,a) {r = _vsnprintf (b,n,f,a);} +#else +#ifdef BSTRLIB_NOVSNP +/* This is just a hack. If you are using a system without a vsnprintf, it is + not recommended that _al_bformat be used at all. */ +#define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;} +#define START_VSNBUFF (256) +#else + +#ifdef __GNUC__ +/* Something is making gcc complain about this prototype not being here, so + I've just gone ahead and put it in. */ +/* Commented out in Allegro source because vsnprintf seems to be defined as a + * macro that calls compiler builtins sometimes, e.g. Mac OS X 10.6. + */ +/* +extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg); +*/ +#endif + +#define exvsnprintf(r,b,n,f,a) {r = vsnprintf (b,n,f,a);} +#endif +#endif + +#if !defined (BSTRLIB_NOVSNP) + +#ifndef START_VSNBUFF +#define START_VSNBUFF (16) +#endif + +/* On IRIX vsnprintf returns n-1 when the operation would overflow the target + buffer, WATCOM and MSVC both return -1, while C99 requires that the + returned value be exactly what the length would be if the buffer would be + large enough. This leads to the idea that if the return value is larger + than n, then changing n to the return value will reduce the number of + iterations required. */ + +/* int _al_bformata (_al_bstring b, const char * fmt, ...) + * + * After the first parameter, it takes the same parameters as printf (), but + * rather than outputting results to stdio, it appends the results to + * a _al_bstring which contains what would have been output. Note that if there + * is an early generation of a '\0' character, the _al_bstring will be truncated + * to this end point. + */ +int _al_bformata (_al_bstring b, const char * fmt, ...) { +va_list arglist; +_al_bstring buff; +int n, r; + + if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 + || b->slen < 0 || b->slen > b->mlen) return _AL_BSTR_ERR; + + /* Since the length is not determinable beforehand, a search is + performed using the truncating "vsnprintf" call (to avoid buffer + overflows) on increasing potential sizes for the output result. */ + + if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; + if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) { + n = 1; + if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) return _AL_BSTR_ERR; + } + + for (;;) { + va_start (arglist, fmt); + exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); + va_end (arglist); + + buff->data[n] = (unsigned char) '\0'; + buff->slen = (int) (strlen) ((char *) buff->data); + + if (buff->slen < n) break; + + if (r > n) n = r; else n += n; + + if (_AL_BSTR_OK != _al_balloc (buff, n + 2)) { + _al_bdestroy (buff); + return _AL_BSTR_ERR; + } + } + + r = _al_bconcat (b, buff); + _al_bdestroy (buff); + return r; +} + +/* int _al_bassignformat (_al_bstring b, const char * fmt, ...) + * + * After the first parameter, it takes the same parameters as printf (), but + * rather than outputting results to stdio, it outputs the results to + * the _al_bstring parameter b. Note that if there is an early generation of a + * '\0' character, the _al_bstring will be truncated to this end point. + */ +int _al_bassignformat (_al_bstring b, const char * fmt, ...) { +va_list arglist; +_al_bstring buff; +int n, r; + + if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 + || b->slen < 0 || b->slen > b->mlen) return _AL_BSTR_ERR; + + /* Since the length is not determinable beforehand, a search is + performed using the truncating "vsnprintf" call (to avoid buffer + overflows) on increasing potential sizes for the output result. */ + + if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; + if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) { + n = 1; + if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) return _AL_BSTR_ERR; + } + + for (;;) { + va_start (arglist, fmt); + exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); + va_end (arglist); + + buff->data[n] = (unsigned char) '\0'; + buff->slen = (int) (strlen) ((char *) buff->data); + + if (buff->slen < n) break; + + if (r > n) n = r; else n += n; + + if (_AL_BSTR_OK != _al_balloc (buff, n + 2)) { + _al_bdestroy (buff); + return _AL_BSTR_ERR; + } + } + + r = _al_bassign (b, buff); + _al_bdestroy (buff); + return r; +} + +/* _al_bstring _al_bformat (const char * fmt, ...) + * + * Takes the same parameters as printf (), but rather than outputting results + * to stdio, it forms a _al_bstring which contains what would have been output. + * Note that if there is an early generation of a '\0' character, the + * _al_bstring will be truncated to this end point. + */ +_al_bstring _al_bformat (const char * fmt, ...) { +va_list arglist; +_al_bstring buff; +int n, r; + + if (fmt == NULL) return NULL; + + /* Since the length is not determinable beforehand, a search is + performed using the truncating "vsnprintf" call (to avoid buffer + overflows) on increasing potential sizes for the output result. */ + + if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF; + if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) { + n = 1; + if (NULL == (buff = _al_bfromcstralloc (n + 2, ""))) return NULL; + } + + for (;;) { + va_start (arglist, fmt); + exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist); + va_end (arglist); + + buff->data[n] = (unsigned char) '\0'; + buff->slen = (int) (strlen) ((char *) buff->data); + + if (buff->slen < n) break; + + if (r > n) n = r; else n += n; + + if (_AL_BSTR_OK != _al_balloc (buff, n + 2)) { + _al_bdestroy (buff); + return NULL; + } + } + + return buff; +} + +/* int _al_bvcformata (_al_bstring b, int count, const char * fmt, va_list arglist) + * + * The _al_bvcformata function formats data under control of the format control + * string fmt and attempts to append the result to b. The fmt parameter is + * the same as that of the printf function. The variable argument list is + * replaced with arglist, which has been initialized by the va_start macro. + * The size of the output is upper bounded by count. If the required output + * exceeds count, the string b is not augmented with any contents and a value + * below _AL_BSTR_ERR is returned. If a value below -count is returned then it + * is recommended that the negative of this value be used as an update to the + * count in a subsequent pass. On other errors, such as running out of + * memory, parameter errors or numeric wrap around _AL_BSTR_ERR is returned. + * _AL_BSTR_OK is returned when the output is successfully generated and + * appended to b. + * + * Note: There is no sanity checking of arglist, and this function is + * destructive of the contents of b from the b->slen point onward. If there + * is an early generation of a '\0' character, the _al_bstring will be truncated + * to this end point. + */ +int _al_bvcformata (_al_bstring b, int count, const char * fmt, va_list arg) { +int n, r, l; + + if (b == NULL || fmt == NULL || count <= 0 || b->data == NULL + || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return _AL_BSTR_ERR; + + if (count > (n = b->slen + count) + 2) return _AL_BSTR_ERR; + if (_AL_BSTR_OK != _al_balloc (b, n + 2)) return _AL_BSTR_ERR; + + exvsnprintf (r, (char *) b->data + b->slen, count + 2, fmt, arg); + + /* Did the operation complete successfully within bounds? */ + + if (n >= (l = b->slen + (int) (strlen) ((const char *) b->data + b->slen))) { + b->slen = l; + return _AL_BSTR_OK; + } + + /* Abort, since the buffer was not large enough. The return value + tries to help set what the retry length should be. */ + + b->data[b->slen] = '\0'; + if (r > count+1) l = r; else { + l = count+count; + if (count > l) l = INT_MAX; + } + n = -l; + if (n > _AL_BSTR_ERR-1) n = _AL_BSTR_ERR-1; + return n; +} + +#endif diff --git a/allegro/src/misc/bstrlib.txt b/allegro/src/misc/bstrlib.txt new file mode 100644 index 00000000..6e579537 --- /dev/null +++ b/allegro/src/misc/bstrlib.txt @@ -0,0 +1,3188 @@ +Better String library +--------------------- + +by Paul Hsieh + +The bstring library is an attempt to provide improved string processing +functionality to the C and C++ language. At the heart of the bstring library +(Bstrlib for short) is the management of "bstring"s which are a significant +improvement over '\0' terminated char buffers. + +=============================================================================== + +Motivation +---------- + +The standard C string library has serious problems: + + 1) Its use of '\0' to denote the end of the string means knowing a + string's length is O(n) when it could be O(1). + 2) It imposes an interpretation for the character value '\0'. + 3) gets() always exposes the application to a buffer overflow. + 4) strtok() modifies the string its parsing and thus may not be usable in + programs which are re-entrant or multithreaded. + 5) fgets has the unusual semantic of ignoring '\0's that occur before + '\n's are consumed. + 6) There is no memory management, and actions performed such as strcpy, + strcat and sprintf are common places for buffer overflows. + 7) strncpy() doesn't '\0' terminate the destination in some cases. + 8) Passing NULL to C library string functions causes an undefined NULL + pointer access. + 9) Parameter aliasing (overlapping, or self-referencing parameters) + within most C library functions has undefined behavior. + 10) Many C library string function calls take integer parameters with + restricted legal ranges. Parameters passed outside these ranges are + not typically detected and cause undefined behavior. + +So the desire is to create an alternative string library that does not suffer +from the above problems and adds in the following functionality: + + 1) Incorporate string functionality seen from other languages. + a) MID$() - from BASIC + b) split()/join() - from Python + c) string/char x n - from Perl + 2) Implement analogs to functions that combine stream IO and char buffers + without creating a dependency on stream IO functionality. + 3) Implement the basic text editor-style functions insert, delete, find, + and replace. + 4) Implement reference based sub-string access (as a generalization of + pointer arithmetic.) + 5) Implement runtime write protection for strings. + +There is also a desire to avoid "API-bloat". So functionality that can be +implemented trivially in other functionality is omitted. So there is no +left$() or right$() or reverse() or anything like that as part of the core +functionality. + +Explaining Bstrings +------------------- + +A bstring is basically a header which wraps a pointer to a char buffer. Lets +start with the declaration of a struct tagbstring: + + struct tagbstring { + int mlen; + int slen; + unsigned char * data; + }; + +This definition is considered exposed, not opaque (though it is neither +necessary nor recommended that low level maintenance of bstrings be performed +whenever the abstract interfaces are sufficient). The mlen field (usually) +describes a lower bound for the memory allocated for the data field. The +slen field describes the exact length for the bstring. The data field is a +single contiguous buffer of unsigned chars. Note that the existence of a '\0' +character in the unsigned char buffer pointed to by the data field does not +necessarily denote the end of the bstring. + +To be a well formed modifiable bstring the mlen field must be at least the +length of the slen field, and slen must be non-negative. Furthermore, the +data field must point to a valid buffer in which access to the first mlen +characters has been acquired. So the minimal check for correctness is: + + (slen >= 0 && mlen >= slen && data != NULL) + +bstrings returned by bstring functions can be assumed to be either NULL or +satisfy the above property. (When bstrings are only readable, the mlen >= +slen restriction is not required; this is discussed later in this section.) +A bstring itself is just a pointer to a struct tagbstring: + + typedef struct tagbstring * bstring; + +Note that use of the prefix "tag" in struct tagbstring is required to work +around the inconsistency between C and C++'s struct namespace usage. This +definition is also considered exposed. + +Bstrlib basically manages bstrings allocated as a header and an associated +data-buffer. Since the implementation is exposed, they can also be +constructed manually. Functions which mutate bstrings assume that the header +and data buffer have been malloced; the bstring library may perform al_free() or +al_realloc() on both the header and data buffer of any bstring parameter. +Functions which return bstring's create new bstrings. The string memory is +freed by a bdestroy() call (or using the bstrFree macro). + +The following related typedef is also provided: + + typedef const struct tagbstring * const_bstring; + +which is also considered exposed. These are directly bstring compatible (no +casting required) but are just used for parameters which are meant to be +non-mutable. So in general, bstring parameters which are read as input but +not meant to be modified will be declared as const_bstring, and bstring +parameters which may be modified will be declared as bstring. This convention +is recommended for user written functions as well. + +Since bstrings maintain interoperability with C library char-buffer style +strings, all functions which modify, update or create bstrings also append a +'\0' character into the position slen + 1. This trailing '\0' character is +not required for bstrings input to the bstring functions; this is provided +solely as a convenience for interoperability with standard C char-buffer +functionality. + +Analogs for the ANSI C string library functions have been created when they +are necessary, but have also been left out when they are not. In particular +there are no functions analogous to fwrite, or puts just for the purposes of +bstring. The ->data member of any string is exposed, and therefore can be +used just as easily as char buffers for C functions which read strings. + +For those that wish to hand construct bstrings, the following should be kept +in mind: + + 1) While bstrlib can accept constructed bstrings without terminating + '\0' characters, the rest of the C language string library will not + function properly on such non-terminated strings. This is obvious + but must be kept in mind. + 2) If it is intended that a constructed bstring be written to by the + bstring library functions then the data portion should be allocated + by the malloc function and the slen and mlen fields should be entered + properly. The struct tagbstring header is not reallocated, and only + freed by bdestroy. + 3) Writing arbitrary '\0' characters at various places in the string + will not modify its length as perceived by the bstring library + functions. In fact, '\0' is a legitimate non-terminating character + for a bstring to contain. + 4) For read only parameters, bstring functions do not check the mlen. + I.e., the minimal correctness requirements are reduced to: + + (slen >= 0 && data != NULL) + +Better pointer arithmetic +------------------------- + +One built-in feature of '\0' terminated char * strings, is that its very easy +and fast to obtain a reference to the tail of any string using pointer +arithmetic. Bstrlib does one better by providing a way to get a reference to +any substring of a bstring (or any other length delimited block of memory.) +So rather than just having pointer arithmetic, with bstrlib one essentially +has segment arithmetic. This is achieved using the macro blk2tbstr() which +builds a reference to a block of memory and the macro bmid2tbstr() which +builds a reference to a segment of a bstring. Bstrlib also includes +functions for direct consumption of memory blocks into bstrings, namely +bcatblk () and blk2bstr (). + +One scenario where this can be extremely useful is when string contains many +substrings which one would like to pass as read-only reference parameters to +some string consuming function without the need to allocate entire new +containers for the string data. More concretely, imagine parsing a command +line string whose parameters are space delimited. This can only be done for +tails of the string with '\0' terminated char * strings. + +Improved NULL semantics and error handling +------------------------------------------ + +Unless otherwise noted, if a NULL pointer is passed as a bstring or any other +detectably illegal parameter, the called function will return with an error +indicator (either NULL or BSTR_ERR) rather than simply performing a NULL +pointer access, or having undefined behavior. + +To illustrate the value of this, consider the following example: + + strcpy (p = malloc (13 * sizeof (char)), "Hello,"); + strcat (p, " World"); + +This is not correct because malloc may return NULL (due to an out of memory +condition), and the behaviour of strcpy is undefined if either of its +parameters are NULL. However: + + bstrcat (p = bfromcstr ("Hello,"), q = bfromcstr (" World")); + bdestroy (q); + +is well defined, because if either p or q are assigned NULL (indicating a +failure to allocate memory) both bstrcat and bdestroy will recognize it and +perform no detrimental action. + +Note that it is not necessary to check any of the members of a returned +bstring for internal correctness (in particular the data member does not need +to be checked against NULL when the header is non-NULL), since this is +assured by the bstring library itself. + +bStreams +-------- + +In addition to the bgets and bread functions, bstrlib can abstract streams +with a high performance read only stream called a bStream. In general, the +idea is to open a core stream (with something like fopen) then pass its +handle as well as a bNread function pointer (like fread) to the bsopen +function which will return a handle to an open bStream. Then the functions +bsread, bsreadln or bsreadlns can be called to read portions of the stream. +Finally, the bsclose function is called to close the bStream -- it will +return a handle to the original (core) stream. So bStreams, essentially, +wrap other streams. + +The bStreams have two main advantages over the bgets and bread (as well as +fgets/ungetc) paradigms: + +1) Improved functionality via the bunread function which allows a stream to + unread characters, giving the bStream stack-like functionality if so + desired. +2) A very high performance bsreadln function. The C library function fgets() + (and the bgets function) can typically be written as a loop on top of + fgetc(), thus paying all of the overhead costs of calling fgetc on a per + character basis. bsreadln will read blocks at a time, thus amortizing the + overhead of fread calls over many characters at once. + +However, clearly bStreams are suboptimal or unusable for certain kinds of +streams (stdin) or certain usage patterns (a few spotty, or non-sequential +reads from a slow stream.) For those situations, using bgets will be more +appropriate. + +The semantics of bStreams allows practical construction of layerable data +streams. What this means is that by writing a bNread compatible function on +top of a bStream, one can construct a new bStream on top of it. This can be +useful for writing multi-pass parsers that don't actually read the entire +input more than once and don't require the use of intermediate storage. + +Aliasing +-------- + +Aliasing occurs when a function is given two parameters which point to data +structures which overlap in the memory they occupy. While this does not +disturb read only functions, for many libraries this can make functions that +write to these memory locations malfunction. This is a common problem of the +C standard library and especially the string functions in the C standard +library. + +The C standard string library is entirely char by char oriented (as is +bstring) which makes conforming implementations alias safe for some +scenarios. However no actual detection of aliasing is typically performed, +so it is easy to find cases where the aliasing will cause anomolous or +undesirable behaviour (consider: strcat (p, p).) The C99 standard includes +the "restrict" pointer modifier which allows the compiler to document and +assume a no-alias condition on usage. However, only the most trivial cases +can be caught (if at all) by the compiler at compile time, and thus there is +no actual enforcement of non-aliasing. + +Bstrlib, by contrast, permits aliasing and is completely aliasing safe, in +the C99 sense of aliasing. That is to say, under the assumption that +pointers of incompatible types from distinct objects can never alias, bstrlib +is completely aliasing safe. (In practice this means that the data buffer +portion of any bstring and header of any bstring are assumed to never alias.) +With the exception of the reference building macros, the library behaves as +if all read-only parameters are first copied and replaced by temporary +non-aliased parameters before any writing to any output bstring is performed +(though actual copying is extremely rarely ever done.) + +Besides being a useful safety feature, bstring searching/comparison +functions can improve to O(1) execution when aliasing is detected. + +Note that aliasing detection and handling code in Bstrlib is generally +extremely cheap. There is almost never any appreciable performance penalty +for using aliased parameters. + +Reenterancy +----------- + +Nearly every function in Bstrlib is a leaf function, and is completely +reenterable with the exception of writing to common bstrings. The split +functions which use a callback mechanism requires only that the source string +not be destroyed by the callback function unless the callback function returns +with an error status (note that Bstrlib functions which return an error do +not modify the string in any way.) The string can in fact be modified by the +callback and the behaviour is deterministic. See the documentation of the +various split functions for more details. + +Undefined scenarios +------------------- + +One of the basic important premises for Bstrlib is to not to increase the +propogation of undefined situations from parameters that are otherwise legal +in of themselves. In particular, except for extremely marginal cases, usages +of bstrings that use the bstring library functions alone cannot lead to any +undefined action. But due to C/C++ language and library limitations, there +is no way to define a non-trivial library that is completely without +undefined operations. All such possible undefined operations are described +below: + +1) bstrings or struct tagbstrings that are not explicitely initialized cannot + be passed as a parameter to any bstring function. +2) The members of the NULL bstring cannot be accessed directly. (Though all + APIs and macros detect the NULL bstring.) +3) A bstring whose data member has not been obtained from a malloc or + compatible call and which is write accessible passed as a writable + parameter will lead to undefined results. (i.e., do not writeAllow any + constructed bstrings unless the data portion has been obtained from the + heap.) +4) If the headers of two strings alias but are not identical (which can only + happen via a defective manual construction), then passing them to a + bstring function in which one is writable is not defined. +5) If the mlen member is larger than the actual accessible length of the data + member for a writable bstring, or if the slen member is larger than the + readable length of the data member for a readable bstring, then the + corresponding bstring operations are undefined. +6) Any bstring definition whose header or accessible data portion has been + assigned to inaccessible or otherwise illegal memory clearly cannot be + acted upon by the bstring library in any way. +7) Destroying the source of an incremental split from within the callback + and not returning with a negative value (indicating that it should abort) + will lead to undefined behaviour. (Though *modifying* or adjusting the + state of the source data, even if those modification fail within the + bstrlib API, has well defined behavior.) +8) Modifying a bstring which is write protected by direct access has + undefined behavior. + +While this may seem like a long list, with the exception of invalid uses of +the writeAllow macro, and source destruction during an iterative split +without an accompanying abort, no usage of the bstring API alone can cause +any undefined scenario to occurr. I.e., the policy of restricting usage of +bstrings to the bstring API can significantly reduce the risk of runtime +errors (in practice it should eliminate them) related to string manipulation +due to undefined action. + +C++ wrapper +----------- + +A C++ wrapper has been created to enable bstring functionality for C++ in the +most natural (for C++ programers) way possible. The mandate for the C++ +wrapper is different from the base C bstring library. Since the C++ language +has far more abstracting capabilities, the CBString structure is considered +fully abstracted -- i.e., hand generated CBStrings are not supported (though +conversion from a struct tagbstring is allowed) and all detectable errors are +manifest as thrown exceptions. + +- The C++ class definitions are all under the namespace Bstrlib. bstrwrap.h + enables this namespace (with a using namespace Bstrlib; directive at the + end) unless the macro BSTRLIB_DONT_ASSUME_NAMESPACE has been defined before + it is included. + +- Erroneous accesses results in an exception being thrown. The exception + parameter is of type "struct CBStringException" which is derived from + std::exception if STL is used. A verbose description of the error message + can be obtained from the what() method. + +- CBString is a C++ structure derived from a struct tagbstring. An address + of a CBString cast to a bstring must not be passed to bdestroy. The bstring + C API has been made C++ safe and can be used directly in a C++ project. + +- It includes constructors which can take a char, '\0' terminated char + buffer, tagbstring, (char, repeat-value), a length delimited buffer or a + CBStringList to initialize it. + +- Concatenation is performed with the + and += operators. Comparisons are + done with the ==, !=, <, >, <= and >= operators. Note that == and != use + the biseq call, while <, >, <= and >= use bstrcmp. + +- CBString's can be directly cast to const character buffers. + +- CBString's can be directly cast to double, float, int or unsigned int so + long as the CBString are decimal representations of those types (otherwise + an exception will be thrown). Converting the other way should be done with + the format(a) method(s). + +- CBString contains the length, character and [] accessor methods. The + character and [] accessors are aliases of each other. If the bounds for + the string are exceeded, an exception is thrown. To avoid the overhead for + this check, first cast the CBString to a (const char *) and use [] to + dereference the array as normal. Note that the character and [] accessor + methods allows both reading and writing of individual characters. + +- The methods: format, formata, find, reversefind, findcaseless, + reversefindcaseless, midstr, insert, insertchrs, replace, findreplace, + findreplacecaseless, remove, findchr, nfindchr, alloc, toupper, tolower, + gets, read are analogous to the functions that can be found in the C API. + +- The caselessEqual and caselessCmp methods are analogous to biseqcaseless + and bstricmp functions respectively. + +- Note that just like the bformat function, the format and formata methods do + not automatically cast CBStrings into char * strings for "%s"-type + substitutions: + + CBString w("world"); + CBString h("Hello"); + CBString hw; + + /* The casts are necessary */ + hw.format ("%s, %s", (const char *)h, (const char *)w); + +- The methods trunc and repeat have been added instead of using pattern. + +- ltrim, rtrim and trim methods have been added. These remove characters + from a given character string set (defaulting to the whitespace characters) + from either the left, right or both ends of the CBString, respectively. + +- The method setsubstr is also analogous in functionality to bsetstr, except + that it cannot be passed NULL. Instead the method fill and the fill-style + constructor have been supplied to enable this functionality. + +- The writeprotect(), writeallow() and iswriteprotected() methods are + analogous to the bwriteprotect(), bwriteallow() and biswriteprotected() + macros in the C API. Write protection semantics in CBString are stronger + than with the C API in that indexed character assignment is checked for + write protection. However, unlike with the C API, a write protected + CBString can be destroyed by the destructor. + +- CBStream is a C++ structure which wraps a struct bStream (its not derived + from it, since destruction is slightly different). It is constructed by + passing in a bNread function pointer and a stream parameter cast to void *. + This structure includes methods for detecting eof, setting the buffer + length, reading the whole stream or reading entries line by line or block + by block, an unread function, and a peek function. + +- If STL is available, the CBStringList structure is derived from a vector of + CBString with various split methods. The split method has been overloaded + to accept either a character or CBString as the second parameter (when the + split parameter is a CBString any character in that CBString is used as a + seperator). The splitstr method takes a CBString as a substring seperator. + Joins can be performed via a CBString constructor which takes a + CBStringList as a parameter, or just using the CBString::join() method. + +- If there is proper support for std::iostreams, then the >> and << operators + and the getline() function have been added (with semantics the same as + those for std::string). + +Multithreading +-------------- + +A mutable bstring is kind of analogous to a small (two entry) linked list +allocated by malloc, with all aliasing completely under programmer control. +I.e., manipulation of one bstring will never affect any other distinct +bstring unless explicitely constructed to do so by the programmer via hand +construction or via building a reference. Bstrlib also does not use any +static or global storage, so there are no hidden unremovable race conditions. +Bstrings are also clearly not inherently thread local. So just like +char *'s, bstrings can be passed around from thread to thread and shared and +so on, so long as modifications to a bstring correspond to some kind of +exclusive access lock as should be expected (or if the bstring is read-only, +which can be enforced by bstring write protection) for any sort of shared +object in a multithreaded environment. + +Bsafe module +------------ + +For convenience, a bsafe module has been included. The idea is that if this +module is included, inadvertant usage of the most dangerous C functions will +be overridden and lead to an immediate run time abort. Of course, it should +be emphasized that usage of this module is completely optional. The +intention is essentially to provide an option for creating project safety +rules which can be enforced mechanically rather than socially. This is +useful for larger, or open development projects where its more difficult to +enforce social rules or "coding conventions". + +Problems not solved +------------------- + +Bstrlib is written for the C and C++ languages, which have inherent weaknesses +that cannot be easily solved: + +1. Memory leaks: Forgetting to call bdestroy on a bstring that is about to be + unreferenced, just as forgetting to call free on a heap buffer that is + about to be dereferenced. Though bstrlib itself is leak free. +2. Read before write usage: In C, declaring an auto bstring does not + automatically fill it with legal/valid contents. This problem has been + somewhat mitigated in C++. (The bstrDeclare and bstrFree macros from + bstraux can be used to help mitigate this problem.) + +Other problems not addressed: + +3. Built-in mutex usage to automatically avoid all bstring internal race + conditions in multitasking environments: The problem with trying to + implement such things at this low a level is that it is typically more + efficient to use locks in higher level primitives. There is also no + platform independent way to implement locks or mutexes. +4. Unicode/widecharacter support. + +Note that except for spotty support of wide characters, the default C +standard library does not address any of these problems either. + +Configurable compilation options +-------------------------------- + +All configuration options are meant solely for the purpose of compiler +compatibility. Configuration options are not meant to change the semantics +or capabilities of the library, except where it is unavoidable. + +Since some C++ compilers don't include the Standard Template Library and some +have the options of disabling exception handling, a number of macros can be +used to conditionally compile support for each of this: + +BSTRLIB_CAN_USE_STL + + - defining this will enable the used of the Standard Template Library. + Defining BSTRLIB_CAN_USE_STL overrides the BSTRLIB_CANNOT_USE_STL macro. + +BSTRLIB_CANNOT_USE_STL + + - defining this will disable the use of the Standard Template Library. + Defining BSTRLIB_CAN_USE_STL overrides the BSTRLIB_CANNOT_USE_STL macro. + +BSTRLIB_CAN_USE_IOSTREAM + + - defining this will enable the used of streams from class std. Defining + BSTRLIB_CAN_USE_IOSTREAM overrides the BSTRLIB_CANNOT_USE_IOSTREAM macro. + +BSTRLIB_CANNOT_USE_IOSTREAM + + - defining this will disable the use of streams from class std. Defining + BSTRLIB_CAN_USE_IOSTREAM overrides the BSTRLIB_CANNOT_USE_IOSTREAM macro. + +BSTRLIB_THROWS_EXCEPTIONS + + - defining this will enable the exception handling within bstring. + Defining BSTRLIB_THROWS_EXCEPTIONS overrides the + BSTRLIB_DOESNT_THROWS_EXCEPTIONS macro. + +BSTRLIB_DOESNT_THROW_EXCEPTIONS + + - defining this will disable the exception handling within bstring. + Defining BSTRLIB_THROWS_EXCEPTIONS overrides the + BSTRLIB_DOESNT_THROW_EXCEPTIONS macro. + +Note that these macros must be defined consistently throughout all modules +that use CBStrings including bstrwrap.cpp. + +Some older C compilers do not support functions such as vsnprintf. This is +handled by the following macro variables: + +BSTRLIB_NOVSNP + + - defining this indicates that the compiler does not support vsnprintf. + This will cause bformat and bformata to not be declared. Note that + for some compilers, such as Turbo C, this is set automatically. + Defining BSTRLIB_NOVSNP overrides the BSTRLIB_VSNP_OK macro. + +BSTRLIB_VSNP_OK + + - defining this will disable the autodetection of compilers the do not + support of compilers that do not support vsnprintf. + Defining BSTRLIB_NOVSNP overrides the BSTRLIB_VSNP_OK macro. + +Semantic compilation options +---------------------------- + +Bstrlib comes with very few compilation options for changing the semantics of +of the library. These are described below. + +BSTRLIB_DONT_ASSUME_NAMESPACE + + - Defining this before including bstrwrap.h will disable the automatic + enabling of the Bstrlib namespace for the C++ declarations. + +BSTRLIB_DONT_USE_VIRTUAL_DESTRUCTOR + + - Defining this will make the CBString destructor non-virtual. + +BSTRLIB_MEMORY_DEBUG + + - Defining this will cause the bstrlib modules bstrlib.c and bstrwrap.cpp + to invoke a #include "memdbg.h". memdbg.h has to be supplied by the user. + +Note that these macros must be defined consistently throughout all modules +that use bstrings or CBStrings including bstrlib.c, bstraux.c and +bstrwrap.cpp. + +=============================================================================== + +Files +----- + +bstrlib.c - C implementaion of bstring functions. +bstrlib.h - C header file for bstring functions. +bstraux.c - C example that implements trivial additional functions. +bstraux.h - C header for bstraux.c +bstest.c - C unit/regression test for bstrlib.c + +bstrwrap.cpp - C++ implementation of CBString. +bstrwrap.h - C++ header file for CBString. +test.cpp - C++ unit/regression test for bstrwrap.cpp + +bsafe.c - C runtime stubs to abort usage of unsafe C functions. +bsafe.h - C header file for bsafe.c functions. + +C projects need only include bstrlib.h and compile/link bstrlib.c to use the +bstring library. C++ projects need to additionally include bstrwrap.h and +compile/link bstrwrap.cpp. For both, there may be a need to make choices +about feature configuration as described in the "Configurable compilation +options" in the section above. + +Other files that are included in this archive are: + +license.txt - The BSD license for Bstrlib +gpl.txt - The GPL version 2 +security.txt - A security statement useful for auditting Bstrlib +porting.txt - A guide to porting Bstrlib +bstrlib.txt - This file + +=============================================================================== + +The functions +------------- + + extern bstring bfromcstr (const char * str); + + Take a standard C library style '\0' terminated char buffer and generate + a bstring with the same contents as the char buffer. If an error occurs + NULL is returned. + + So for example: + + bstring b = bfromcstr ("Hello"); + if (!b) { + fprintf (stderr, "Out of memory"); + } else { + puts ((char *) b->data); + } + + .......................................................................... + + extern bstring bfromcstralloc (int mlen, const char * str); + + Create a bstring which contains the contents of the '\0' terminated + char * buffer str. The memory buffer backing the bstring is at least + mlen characters in length. If an error occurs NULL is returned. + + So for example: + + bstring b = bfromcstralloc (64, someCstr); + if (b) b->data[63] = 'x'; + + The idea is that this will set the 64th character of b to 'x' if it is at + least 64 characters long otherwise do nothing. And we know this is well + defined so long as b was successfully created, since it will have been + allocated with at least 64 characters. + + .......................................................................... + + extern bstring blk2bstr (const void * blk, int len); + + Create a bstring whose contents are described by the contiguous buffer + pointing to by blk with a length of len bytes. Note that this function + creates a copy of the data in blk, rather than simply referencing it. + Compare with the blk2tbstr macro. If an error occurs NULL is returned. + + .......................................................................... + + extern char * bstr2cstr (const_bstring s, char z); + + Create a '\0' terminated char buffer which contains the contents of the + bstring s, except that any contained '\0' characters are converted to the + character in z. This returned value should be freed with bcstrfree(), by + the caller. If an error occurs NULL is returned. + + .......................................................................... + + extern int bcstrfree (char * s); + + Frees a C-string generated by bstr2cstr (). This is normally unnecessary + since it just wraps a call to free (), however, if malloc () and free () + have been redefined as a macros within the bstrlib module (via macros in + the memdbg.h backdoor) with some difference in behaviour from the std + library functions, then this allows a correct way of freeing the memory + that allows higher level code to be independent from these macro + redefinitions. + + .......................................................................... + + extern bstring bstrcpy (const_bstring b1); + + Make a copy of the passed in bstring. The copied bstring is returned if + there is no error, otherwise NULL is returned. + + .......................................................................... + + extern int bassign (bstring a, const_bstring b); + + Overwrite the bstring a with the contents of bstring b. Note that the + bstring a must be a well defined and writable bstring. If an error + occurs BSTR_ERR is returned and a is not overwritten. + + .......................................................................... + + int bassigncstr (bstring a, const char * str); + + Overwrite the string a with the contents of char * string str. Note that + the bstring a must be a well defined and writable bstring. If an error + occurs BSTR_ERR is returned and a may be partially overwritten. + + .......................................................................... + + int bassignblk (bstring a, const void * s, int len); + + Overwrite the string a with the contents of the block (s, len). Note that + the bstring a must be a well defined and writable bstring. If an error + occurs BSTR_ERR is returned and a is not overwritten. + + .......................................................................... + + extern int bassignmidstr (bstring a, const_bstring b, int left, int len); + + Overwrite the bstring a with the middle of contents of bstring b + starting from position left and running for a length len. left and + len are clamped to the ends of b as with the function bmidstr. Note that + the bstring a must be a well defined and writable bstring. If an error + occurs BSTR_ERR is returned and a is not overwritten. + + .......................................................................... + + extern bstring bmidstr (const_bstring b, int left, int len); + + Create a bstring which is the substring of b starting from position left + and running for a length len (clamped by the end of the bstring b.) If + there was no error, the value of this constructed bstring is returned + otherwise NULL is returned. + + .......................................................................... + + extern int bdelete (bstring s1, int pos, int len); + + Removes characters from pos to pos+len-1 and shifts the tail of the + bstring starting from pos+len to pos. len must be positive for this call + to have any effect. The section of the bstring described by (pos, len) + is clamped to boundaries of the bstring b. The value BSTR_OK is returned + if the operation is successful, otherwise BSTR_ERR is returned. + + .......................................................................... + + extern int bconcat (bstring b0, const_bstring b1); + + Concatenate the bstring b1 to the end of bstring b0. The value BSTR_OK + is returned if the operation is successful, otherwise BSTR_ERR is + returned. + + .......................................................................... + + extern int bconchar (bstring b, char c); + + Concatenate the character c to the end of bstring b. The value BSTR_OK + is returned if the operation is successful, otherwise BSTR_ERR is + returned. + + .......................................................................... + + extern int bcatcstr (bstring b, const char * s); + + Concatenate the char * string s to the end of bstring b. The value + BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is + returned. + + .......................................................................... + + extern int bcatblk (bstring b, const void * s, int len); + + Concatenate a fixed length buffer (s, len) to the end of bstring b. The + value BSTR_OK is returned if the operation is successful, otherwise + BSTR_ERR is returned. + + .......................................................................... + + extern int biseq (const_bstring b0, const_bstring b1); + + Compare the bstring b0 and b1 for equality. If the bstrings differ, 0 + is returned, if the bstrings are the same, 1 is returned, if there is an + error, -1 is returned. If the length of the bstrings are different, this + function has O(1) complexity. Contained '\0' characters are not treated + as a termination character. + + Note that the semantics of biseq are not completely compatible with + bstrcmp because of its different treatment of the '\0' character. + + .......................................................................... + + extern int bisstemeqblk (const_bstring b, const void * blk, int len); + + Compare beginning of bstring b0 with a block of memory of length len for + equality. If the beginning of b0 differs from the memory block (or if b0 + is too short), 0 is returned, if the bstrings are the same, 1 is returned, + if there is an error, -1 is returned. + + .......................................................................... + + extern int biseqcaseless (const_bstring b0, const_bstring b1); + + Compare two bstrings for equality without differentiating between case. + If the bstrings differ other than in case, 0 is returned, if the bstrings + are the same, 1 is returned, if there is an error, -1 is returned. If + the length of the bstrings are different, this function is O(1). '\0' + termination characters are not treated in any special way. + + .......................................................................... + + extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len); + + Compare beginning of bstring b0 with a block of memory of length len + without differentiating between case for equality. If the beginning of b0 + differs from the memory block other than in case (or if b0 is too short), + 0 is returned, if the bstrings are the same, 1 is returned, if there is an + error, -1 is returned. + + .......................................................................... + + extern int biseqcstr (const_bstring b, const char *s); + + Compare the bstring b and char * bstring s. The C string s must be '\0' + terminated at exactly the length of the bstring b, and the contents + between the two must be identical with the bstring b with no '\0' + characters for the two contents to be considered equal. This is + equivalent to the condition that their current contents will be always be + equal when comparing them in the same format after converting one or the + other. If they are equal 1 is returned, if they are unequal 0 is + returned and if there is a detectable error BSTR_ERR is returned. + + .......................................................................... + + extern int biseqcstrcaseless (const_bstring b, const char *s); + + Compare the bstring b and char * string s. The C string s must be '\0' + terminated at exactly the length of the bstring b, and the contents + between the two must be identical except for case with the bstring b with + no '\0' characters for the two contents to be considered equal. This is + equivalent to the condition that their current contents will be always be + equal ignoring case when comparing them in the same format after + converting one or the other. If they are equal, except for case, 1 is + returned, if they are unequal regardless of case 0 is returned and if + there is a detectable error BSTR_ERR is returned. + + .......................................................................... + + extern int bstrcmp (const_bstring b0, const_bstring b1); + + Compare the bstrings b0 and b1 for ordering. If there is an error, + SHRT_MIN is returned, otherwise a value less than or greater than zero, + indicating that the bstring pointed to by b0 is lexicographically less + than or greater than the bstring pointed to by b1 is returned. If the + bstring lengths are unequal but the characters up until the length of the + shorter are equal then a value less than, or greater than zero, + indicating that the bstring pointed to by b0 is shorter or longer than the + bstring pointed to by b1 is returned. 0 is returned if and only if the + two bstrings are the same. If the length of the bstrings are different, + this function is O(n). Like its standard C library counter part, the + comparison does not proceed past any '\0' termination characters + encountered. + + The seemingly odd error return value, merely provides slightly more + granularity than the undefined situation given in the C library function + strcmp. The function otherwise behaves very much like strcmp(). + + Note that the semantics of bstrcmp are not completely compatible with + biseq because of its different treatment of the '\0' termination + character. + + .......................................................................... + + extern int bstrncmp (const_bstring b0, const_bstring b1, int n); + + Compare the bstrings b0 and b1 for ordering for at most n characters. If + there is an error, SHRT_MIN is returned, otherwise a value is returned as + if b0 and b1 were first truncated to at most n characters then bstrcmp + was called with these new bstrings are paremeters. If the length of the + bstrings are different, this function is O(n). Like its standard C + library counter part, the comparison does not proceed past any '\0' + termination characters encountered. + + The seemingly odd error return value, merely provides slightly more + granularity than the undefined situation given in the C library function + strncmp. The function otherwise behaves very much like strncmp(). + + .......................................................................... + + extern int bstricmp (const_bstring b0, const_bstring b1); + + Compare two bstrings without differentiating between case. The return + value is the difference of the values of the characters where the two + bstrings first differ, otherwise 0 is returned indicating that the + bstrings are equal. If the lengths are different, then a difference from + 0 is given, but if the first extra character is '\0', then it is taken to + be the value UCHAR_MAX+1. + + .......................................................................... + + extern int bstrnicmp (const_bstring b0, const_bstring b1, int n); + + Compare two bstrings without differentiating between case for at most n + characters. If the position where the two bstrings first differ is + before the nth position, the return value is the difference of the values + of the characters, otherwise 0 is returned. If the lengths are different + and less than n characters, then a difference from 0 is given, but if the + first extra character is '\0', then it is taken to be the value + UCHAR_MAX+1. + + .......................................................................... + + extern int bdestroy (bstring b); + + Deallocate the bstring passed. Passing NULL in as a parameter will have + no effect. Note that both the header and the data portion of the bstring + will be freed. No other bstring function which modifies one of its + parameters will free or reallocate the header. Because of this, in + general, bdestroy cannot be called on any declared struct tagbstring even + if it is not write protected. A bstring which is write protected cannot + be destroyed via the bdestroy call. Any attempt to do so will result in + no action taken, and BSTR_ERR will be returned. + + Note to C++ users: Passing in a CBString cast to a bstring will lead to + undefined behavior (free will be called on the header, rather than the + CBString destructor.) Instead just use the ordinary C++ language + facilities to dealloc a CBString. + + .......................................................................... + + extern int binstr (const_bstring s1, int pos, const_bstring s2); + + Search for the bstring s2 in s1 starting at position pos and looking in a + forward (increasing) direction. If it is found then it returns with the + first position after pos where it is found, otherwise it returns BSTR_ERR. + The algorithm used is brute force; O(m*n). + + .......................................................................... + + extern int binstrr (const_bstring s1, int pos, const_bstring s2); + + Search for the bstring s2 in s1 starting at position pos and looking in a + backward (decreasing) direction. If it is found then it returns with the + first position after pos where it is found, otherwise return BSTR_ERR. + Note that the current position at pos is tested as well -- so to be + disjoint from a previous forward search it is recommended that the + position be backed up (decremented) by one position. The algorithm used + is brute force; O(m*n). + + .......................................................................... + + extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2); + + Search for the bstring s2 in s1 starting at position pos and looking in a + forward (increasing) direction but without regard to case. If it is + found then it returns with the first position after pos where it is + found, otherwise it returns BSTR_ERR. The algorithm used is brute force; + O(m*n). + + .......................................................................... + + extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2); + + Search for the bstring s2 in s1 starting at position pos and looking in a + backward (decreasing) direction but without regard to case. If it is + found then it returns with the first position after pos where it is + found, otherwise return BSTR_ERR. Note that the current position at pos + is tested as well -- so to be disjoint from a previous forward search it + is recommended that the position be backed up (decremented) by one + position. The algorithm used is brute force; O(m*n). + + .......................................................................... + + extern int binchr (const_bstring b0, int pos, const_bstring b1); + + Search for the first position in b0 starting from pos or after, in which + one of the characters in b1 is found. This function has an execution + time of O(b0->slen + b1->slen). If such a position does not exist in b0, + then BSTR_ERR is returned. + + .......................................................................... + + extern int binchrr (const_bstring b0, int pos, const_bstring b1); + + Search for the last position in b0 no greater than pos, in which one of + the characters in b1 is found. This function has an execution time + of O(b0->slen + b1->slen). If such a position does not exist in b0, + then BSTR_ERR is returned. + + .......................................................................... + + extern int bninchr (const_bstring b0, int pos, const_bstring b1); + + Search for the first position in b0 starting from pos or after, in which + none of the characters in b1 is found and return it. This function has + an execution time of O(b0->slen + b1->slen). If such a position does + not exist in b0, then BSTR_ERR is returned. + + .......................................................................... + + extern int bninchrr (const_bstring b0, int pos, const_bstring b1); + + Search for the last position in b0 no greater than pos, in which none of + the characters in b1 is found and return it. This function has an + execution time of O(b0->slen + b1->slen). If such a position does not + exist in b0, then BSTR_ERR is returned. + + .......................................................................... + + extern int bstrchr (const_bstring b, int c); + + Search for the character c in the bstring b forwards from the start of + the bstring. Returns the position of the found character or BSTR_ERR if + it is not found. + + NOTE: This has been implemented as a macro on top of bstrchrp (). + + .......................................................................... + + extern int bstrrchr (const_bstring b, int c); + + Search for the character c in the bstring b backwards from the end of the + bstring. Returns the position of the found character or BSTR_ERR if it is + not found. + + NOTE: This has been implemented as a macro on top of bstrrchrp (). + + .......................................................................... + + extern int bstrchrp (const_bstring b, int c, int pos); + + Search for the character c in b forwards from the position pos + (inclusive). Returns the position of the found character or BSTR_ERR if + it is not found. + + .......................................................................... + + extern int bstrrchrp (const_bstring b, int c, int pos); + + Search for the character c in b backwards from the position pos in bstring + (inclusive). Returns the position of the found character or BSTR_ERR if + it is not found. + + .......................................................................... + + extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill); + + Overwrite the bstring b0 starting at position pos with the bstring b1. If + the position pos is past the end of b0, then the character "fill" is + appended as necessary to make up the gap between the end of b0 and pos. + If b1 is NULL, it behaves as if it were a 0-length bstring. The value + BSTR_OK is returned if the operation is successful, otherwise BSTR_ERR is + returned. + + .......................................................................... + + extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill); + + Inserts the bstring s2 into s1 at position pos. If the position pos is + past the end of s1, then the character "fill" is appended as necessary to + make up the gap between the end of s1 and pos. The value BSTR_OK is + returned if the operation is successful, otherwise BSTR_ERR is returned. + + .......................................................................... + + extern int binsertch (bstring s1, int pos, int len, unsigned char fill); + + Inserts the character fill repeatedly into s1 at position pos for a + length len. If the position pos is past the end of s1, then the + character "fill" is appended as necessary to make up the gap between the + end of s1 and the position pos + len (exclusive). The value BSTR_OK is + returned if the operation is successful, otherwise BSTR_ERR is returned. + + .......................................................................... + + extern int breplace (bstring b1, int pos, int len, const_bstring b2, + unsigned char fill); + + Replace a section of a bstring from pos for a length len with the bstring + b2. If the position pos is past the end of b1 then the character "fill" + is appended as necessary to make up the gap between the end of b1 and + pos. + + .......................................................................... + + extern int bfindreplace (bstring b, const_bstring find, + const_bstring replace, int position); + + Replace all occurrences of the find substring with a replace bstring + after a given position in the bstring b. The find bstring must have a + length > 0 otherwise BSTR_ERR is returned. This function does not + perform recursive per character replacement; that is to say successive + searches resume at the position after the last replace. + + So for example: + + bfindreplace (a0 = bfromcstr("aabaAb"), a1 = bfromcstr("a"), + a2 = bfromcstr("aa"), 0); + + Should result in changing a0 to "aaaabaaAb". + + This function performs exactly (b->slen - position) bstring comparisons, + and data movement is bounded above by character volume equivalent to size + of the output bstring. + + .......................................................................... + + extern int bfindreplacecaseless (bstring b, const_bstring find, + const_bstring replace, int position); + + Replace all occurrences of the find substring, ignoring case, with a + replace bstring after a given position in the bstring b. The find bstring + must have a length > 0 otherwise BSTR_ERR is returned. This function + does not perform recursive per character replacement; that is to say + successive searches resume at the position after the last replace. + + So for example: + + bfindreplacecaseless (a0 = bfromcstr("AAbaAb"), a1 = bfromcstr("a"), + a2 = bfromcstr("aa"), 0); + + Should result in changing a0 to "aaaabaaaab". + + This function performs exactly (b->slen - position) bstring comparisons, + and data movement is bounded above by character volume equivalent to size + of the output bstring. + + .......................................................................... + + extern int balloc (bstring b, int length); + + Increase the allocated memory backing the data buffer for the bstring b + to a length of at least length. If the memory backing the bstring b is + already large enough, not action is performed. This has no effect on the + bstring b that is visible to the bstring API. Usually this function will + only be used when a minimum buffer size is required coupled with a direct + access to the ->data member of the bstring structure. + + Be warned that like any other bstring function, the bstring must be well + defined upon entry to this function. I.e., doing something like: + + b->slen *= 2; /* ?? Most likely incorrect */ + balloc (b, b->slen); + + is invalid, and should be implemented as: + + int t; + if (BSTR_OK == balloc (b, t = (b->slen * 2))) b->slen = t; + + This function will return with BSTR_ERR if b is not detected as a valid + bstring or length is not greater than 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int ballocmin (bstring b, int length); + + Change the amount of memory backing the bstring b to at least length. + This operation will never truncate the bstring data including the + extra terminating '\0' and thus will not decrease the length to less than + b->slen + 1. Note that repeated use of this function may cause + performance problems (realloc may be called on the bstring more than + the O(log(INT_MAX)) times). This function will return with BSTR_ERR if b + is not detected as a valid bstring or length is not greater than 0, + otherwise BSTR_OK is returned. + + So for example: + + if (BSTR_OK == ballocmin (b, 64)) b->data[63] = 'x'; + + The idea is that this will set the 64th character of b to 'x' if it is at + least 64 characters long otherwise do nothing. And we know this is well + defined so long as the ballocmin call was successfully, since it will + ensure that b has been allocated with at least 64 characters. + + .......................................................................... + + int btrunc (bstring b, int n); + + Truncate the bstring to at most n characters. This function will return + with BSTR_ERR if b is not detected as a valid bstring or n is less than + 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int bpattern (bstring b, int len); + + Replicate the starting bstring, b, end to end repeatedly until it + surpasses len characters, then chop the result to exactly len characters. + This function operates in-place. This function will return with BSTR_ERR + if b is NULL or of length 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int btoupper (bstring b); + + Convert contents of bstring to upper case. This function will return with + BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int btolower (bstring b); + + Convert contents of bstring to lower case. This function will return with + BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int bltrimws (bstring b); + + Delete whitespace contiguous from the left end of the bstring. This + function will return with BSTR_ERR if b is NULL or of length 0, otherwise + BSTR_OK is returned. + + .......................................................................... + + extern int brtrimws (bstring b); + + Delete whitespace contiguous from the right end of the bstring. This + function will return with BSTR_ERR if b is NULL or of length 0, otherwise + BSTR_OK is returned. + + .......................................................................... + + extern int btrimws (bstring b); + + Delete whitespace contiguous from both ends of the bstring. This function + will return with BSTR_ERR if b is NULL or of length 0, otherwise BSTR_OK + is returned. + + .......................................................................... + + extern int bstrListCreate (void); + + Create an empty struct bstrList. The struct bstrList output structure is + declared as follows: + + struct bstrList { + int qty, mlen; + bstring * entry; + }; + + The entry field actually is an array with qty number entries. The mlen + record counts the maximum number of bstring's for which there is memory + in the entry record. + + The Bstrlib API does *NOT* include a comprehensive set of functions for + full management of struct bstrList in an abstracted way. The reason for + this is because aliasing semantics of the list are best left to the user + of this function, and performance varies wildly depending on the + assumptions made. For a complete list of bstring data type it is + recommended that the C++ public std::vector be used, since its + semantics are usage are more standard. + + .......................................................................... + + extern int bstrListDestroy (struct bstrList * sl); + + Destroy a struct bstrList structure that was returned by the bsplit + function. Note that this will destroy each bstring in the ->entry array + as well. See bstrListCreate() above for structure of struct bstrList. + + .......................................................................... + + extern int bstrListAlloc (struct bstrList * sl, int msz); + + Ensure that there is memory for at least msz number of entries for the + list. + + .......................................................................... + + extern int bstrListAllocMin (struct bstrList * sl, int msz); + + Try to allocate the minimum amount of memory for the list to include at + least msz entries or sl->qty whichever is greater. + + .......................................................................... + + extern struct bstrList * bsplit (bstring str, unsigned char splitChar); + + Create an array of sequential substrings from str divided by the + character splitChar. Successive occurrences of the splitChar will be + divided by empty bstring entries, following the semantics from the Python + programming language. To reclaim the memory from this output structure, + bstrListDestroy () should be called. See bstrListCreate() above for + structure of struct bstrList. + + .......................................................................... + + extern struct bstrList * bsplits (bstring str, const_bstring splitStr); + + Create an array of sequential substrings from str divided by any + character contained in splitStr. An empty splitStr causes a single entry + bstrList containing a copy of str to be returned. See bstrListCreate() + above for structure of struct bstrList. + + .......................................................................... + + extern struct bstrList * bsplitstr (bstring str, const_bstring splitStr); + + Create an array of sequential substrings from str divided by the entire + substring splitStr. An empty splitStr causes a single entry bstrList + containing a copy of str to be returned. See bstrListCreate() above for + structure of struct bstrList. + + .......................................................................... + + extern bstring bjoin (const struct bstrList * bl, const_bstring sep); + + Join the entries of a bstrList into one bstring by sequentially + concatenating them with the sep bstring in between. If sep is NULL, it + is treated as if it were the empty bstring. Note that: + + bjoin (l = bsplit (b, s->data[0]), s); + + should result in a copy of b, if s->slen is 1. If there is an error NULL + is returned, otherwise a bstring with the correct result is returned. + See bstrListCreate() above for structure of struct bstrList. + + .......................................................................... + + extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + + Iterate the set of disjoint sequential substrings over str starting at + position pos divided by the character splitChar. The parm passed to + bsplitcb is passed on to cb. If the function cb returns a value < 0, + then further iterating is halted and this value is returned by bsplitcb. + + Note: Non-destructive modification of str from within the cb function + while performing this split is not undefined. bsplitcb behaves in + sequential lock step with calls to cb. I.e., after returning from a cb + that return a non-negative integer, bsplitcb continues from the position + 1 character after the last detected split character and it will halt + immediately if the length of str falls below this point. However, if the + cb function destroys str, then it *must* return with a negative value, + otherwise bsplitcb will continue in an undefined manner. + + This function is provided as an incremental alternative to bsplit that is + abortable and which does not impose additional memory allocation. + + .......................................................................... + + extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + + Iterate the set of disjoint sequential substrings over str starting at + position pos divided by any of the characters in splitStr. An empty + splitStr causes the whole str to be iterated once. The parm passed to + bsplitcb is passed on to cb. If the function cb returns a value < 0, + then further iterating is halted and this value is returned by bsplitcb. + + Note: Non-destructive modification of str from within the cb function + while performing this split is not undefined. bsplitscb behaves in + sequential lock step with calls to cb. I.e., after returning from a cb + that return a non-negative integer, bsplitscb continues from the position + 1 character after the last detected split character and it will halt + immediately if the length of str falls below this point. However, if the + cb function destroys str, then it *must* return with a negative value, + otherwise bsplitscb will continue in an undefined manner. + + This function is provided as an incremental alternative to bsplits that + is abortable and which does not impose additional memory allocation. + + .......................................................................... + + extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + + Iterate the set of disjoint sequential substrings over str starting at + position pos divided by the entire substring splitStr. An empty splitStr + causes each character of str to be iterated. The parm passed to bsplitcb + is passed on to cb. If the function cb returns a value < 0, then further + iterating is halted and this value is returned by bsplitcb. + + Note: Non-destructive modification of str from within the cb function + while performing this split is not undefined. bsplitstrcb behaves in + sequential lock step with calls to cb. I.e., after returning from a cb + that return a non-negative integer, bsplitstrcb continues from the position + 1 character after the last detected split character and it will halt + immediately if the length of str falls below this point. However, if the + cb function destroys str, then it *must* return with a negative value, + otherwise bsplitscb will continue in an undefined manner. + + This function is provided as an incremental alternative to bsplitstr that + is abortable and which does not impose additional memory allocation. + + .......................................................................... + + extern bstring bformat (const char * fmt, ...); + + Takes the same parameters as printf (), but rather than outputting + results to stdio, it forms a bstring which contains what would have been + output. Note that if there is an early generation of a '\0' character, + the bstring will be truncated to this end point. + + Note that %s format tokens correspond to '\0' terminated char * buffers, + not bstrings. To print a bstring, first dereference data element of the + the bstring: + + /* b1->data needs to be '\0' terminated, so tagbstrings generated + by blk2tbstr () might not be suitable. */ + b0 = bformat ("Hello, %s", b1->data); + + Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been + compiled the bformat function is not present. + + .......................................................................... + + extern int bformata (bstring b, const char * fmt, ...); + + In addition to the initial output buffer b, bformata takes the same + parameters as printf (), but rather than outputting results to stdio, it + appends the results to the initial bstring parameter. Note that if + there is an early generation of a '\0' character, the bstring will be + truncated to this end point. + + Note that %s format tokens correspond to '\0' terminated char * buffers, + not bstrings. To print a bstring, first dereference data element of the + the bstring: + + /* b1->data needs to be '\0' terminated, so tagbstrings generated + by blk2tbstr () might not be suitable. */ + bformata (b0 = bfromcstr ("Hello"), ", %s", b1->data); + + Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been + compiled the bformata function is not present. + + .......................................................................... + + extern int bassignformat (bstring b, const char * fmt, ...); + + After the first parameter, it takes the same parameters as printf (), but + rather than outputting results to stdio, it outputs the results to + the bstring parameter b. Note that if there is an early generation of a + '\0' character, the bstring will be truncated to this end point. + + Note that %s format tokens correspond to '\0' terminated char * buffers, + not bstrings. To print a bstring, first dereference data element of the + the bstring: + + /* b1->data needs to be '\0' terminated, so tagbstrings generated + by blk2tbstr () might not be suitable. */ + bassignformat (b0 = bfromcstr ("Hello"), ", %s", b1->data); + + Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been + compiled the bassignformat function is not present. + + .......................................................................... + + extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist); + + The bvcformata function formats data under control of the format control + string fmt and attempts to append the result to b. The fmt parameter is + the same as that of the printf function. The variable argument list is + replaced with arglist, which has been initialized by the va_start macro. + The size of the output is upper bounded by count. If the required output + exceeds count, the string b is not augmented with any contents and a value + below BSTR_ERR is returned. If a value below -count is returned then it + is recommended that the negative of this value be used as an update to the + count in a subsequent pass. On other errors, such as running out of + memory, parameter errors or numeric wrap around BSTR_ERR is returned. + BSTR_OK is returned when the output is successfully generated and + appended to b. + + Note: There is no sanity checking of arglist, and this function is + destructive of the contents of b from the b->slen point onward. If there + is an early generation of a '\0' character, the bstring will be truncated + to this end point. + + Although this function is part of the external API for Bstrlib, the + interface and semantics (length limitations, and unusual return codes) + are fairly atypical. The real purpose for this function is to provide an + engine for the bvformata macro. + + Note that if the BSTRLIB_NOVSNP macro has been set when bstrlib has been + compiled the bvcformata function is not present. + + .......................................................................... + + extern bstring bread (bNread readPtr, void * parm); + typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, + void *parm); + + Read an entire stream into a bstring, verbatum. The readPtr function + pointer is compatible with fread sematics, except that it need not obtain + the stream data from a file. The intention is that parm would contain + the stream data context/state required (similar to the role of the FILE* + I/O stream parameter of fread.) + + Abstracting the block read function allows for block devices other than + file streams to be read if desired. Note that there is an ANSI + compatibility issue if "fread" is used directly; see the ANSI issues + section below. + + .......................................................................... + + extern int breada (bstring b, bNread readPtr, void * parm); + + Read an entire stream and append it to a bstring, verbatum. Behaves + like bread, except that it appends it results to the bstring b. + BSTR_ERR is returned on error, otherwise 0 is returned. + + .......................................................................... + + extern bstring bgets (bNgetc getcPtr, void * parm, char terminator); + typedef int (* bNgetc) (void * parm); + + Read a bstring from a stream. As many bytes as is necessary are read + until the terminator is consumed or no more characters are available from + the stream. If read from the stream, the terminator character will be + appended to the end of the returned bstring. The getcPtr function must + have the same semantics as the fgetc C library function (i.e., returning + an integer whose value is negative when there are no more characters + available, otherwise the value of the next available unsigned character + from the stream.) The intention is that parm would contain the stream + data context/state required (similar to the role of the FILE* I/O stream + parameter of fgets.) If no characters are read, or there is some other + detectable error, NULL is returned. + + bgets will never call the getcPtr function more often than necessary to + construct its output (including a single call, if required, to determine + that the stream contains no more characters.) + + Abstracting the character stream function and terminator character allows + for different stream devices and string formats other than '\n' + terminated lines in a file if desired (consider \032 terminated email + messages, in a UNIX mailbox for example.) + + For files, this function can be used analogously as fgets as follows: + + fp = fopen ( ... ); + if (fp) b = bgets ((bNgetc) fgetc, fp, '\n'); + + (Note that only one terminator character can be used, and that '\0' is + not assumed to terminate the stream in addition to the terminator + character. This is consistent with the semantics of fgets.) + + .......................................................................... + + extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator); + + Read from a stream and concatenate to a bstring. Behaves like bgets, + except that it appends it results to the bstring b. The value 1 is + returned if no characters are read before a negative result is returned + from getcPtr. Otherwise BSTR_ERR is returned on error, and 0 is returned + in other normal cases. + + .......................................................................... + + extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator); + + Read from a stream and concatenate to a bstring. Behaves like bgets, + except that it assigns the results to the bstring b. The value 1 is + returned if no characters are read before a negative result is returned + from getcPtr. Otherwise BSTR_ERR is returned on error, and 0 is returned + in other normal cases. + + .......................................................................... + + extern struct bStream * bsopen (bNread readPtr, void * parm); + + Wrap a given open stream (described by a fread compatible function + pointer and stream handle) into an open bStream suitable for the bstring + library streaming functions. + + .......................................................................... + + extern void * bsclose (struct bStream * s); + + Close the bStream, and return the handle to the stream that was + originally used to open the given stream. If s is NULL or detectably + invalid, NULL will be returned. + + .......................................................................... + + extern int bsbufflength (struct bStream * s, int sz); + + Set the length of the buffer used by the bStream. If sz is the macro + BSTR_BS_BUFF_LENGTH_GET (which is 0), the length is not set. If s is + NULL or sz is negative, the function will return with BSTR_ERR, otherwise + this function returns with the previous length. + + .......................................................................... + + extern int bsreadln (bstring r, struct bStream * s, char terminator); + + Read a bstring terminated by the terminator character or the end of the + stream from the bStream (s) and return it into the parameter r. The + matched terminator, if found, appears at the end of the line read. If + the stream has been exhausted of all available data, before any can be + read, BSTR_ERR is returned. This function may read additional characters + into the stream buffer from the core stream that are not returned, but + will be retained for subsequent read operations. When reading from high + speed streams, this function can perform significantly faster than bgets. + + .......................................................................... + + extern int bsreadlna (bstring r, struct bStream * s, char terminator); + + Read a bstring terminated by the terminator character or the end of the + stream from the bStream (s) and concatenate it to the parameter r. The + matched terminator, if found, appears at the end of the line read. If + the stream has been exhausted of all available data, before any can be + read, BSTR_ERR is returned. This function may read additional characters + into the stream buffer from the core stream that are not returned, but + will be retained for subsequent read operations. When reading from high + speed streams, this function can perform significantly faster than bgets. + + .......................................................................... + + extern int bsreadlns (bstring r, struct bStream * s, bstring terminators); + + Read a bstring terminated by any character in the terminators bstring or + the end of the stream from the bStream (s) and return it into the + parameter r. This function may read additional characters from the core + stream that are not returned, but will be retained for subsequent read + operations. + + .......................................................................... + + extern int bsreadlnsa (bstring r, struct bStream * s, bstring terminators); + + Read a bstring terminated by any character in the terminators bstring or + the end of the stream from the bStream (s) and concatenate it to the + parameter r. If the stream has been exhausted of all available data, + before any can be read, BSTR_ERR is returned. This function may read + additional characters from the core stream that are not returned, but + will be retained for subsequent read operations. + + .......................................................................... + + extern int bsread (bstring r, struct bStream * s, int n); + + Read a bstring of length n (or, if it is fewer, as many bytes as is + remaining) from the bStream. This function will read the minimum + required number of additional characters from the core stream. When the + stream is at the end of the file BSTR_ERR is returned, otherwise BSTR_OK + is returned. + + .......................................................................... + + extern int bsreada (bstring r, struct bStream * s, int n); + + Read a bstring of length n (or, if it is fewer, as many bytes as is + remaining) from the bStream and concatenate it to the parameter r. This + function will read the minimum required number of additional characters + from the core stream. When the stream is at the end of the file BSTR_ERR + is returned, otherwise BSTR_OK is returned. + + .......................................................................... + + extern int bsunread (struct bStream * s, const_bstring b); + + Insert a bstring into the bStream at the current position. These + characters will be read prior to those that actually come from the core + stream. + + .......................................................................... + + extern int bspeek (bstring r, const struct bStream * s); + + Return the number of currently buffered characters from the bStream that + will be read prior to reads from the core stream, and append it to the + the parameter r. + + .......................................................................... + + extern int bssplitscb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); + + Iterate the set of disjoint sequential substrings over the stream s + divided by any character from the bstring splitStr. The parm passed to + bssplitscb is passed on to cb. If the function cb returns a value < 0, + then further iterating is halted and this return value is returned by + bssplitscb. + + Note: At the point of calling the cb function, the bStream pointer is + pointed exactly at the position right after having read the split + character. The cb function can act on the stream by causing the bStream + pointer to move, and bssplitscb will continue by starting the next split + at the position of the pointer after the return from cb. + + However, if the cb causes the bStream s to be destroyed then the cb must + return with a negative value, otherwise bssplitscb will continue in an + undefined manner. + + This function is provided as way to incrementally parse through a file + or other generic stream that in total size may otherwise exceed the + practical or desired memory available. As with the other split callback + based functions this is abortable and does not impose additional memory + allocation. + + .......................................................................... + + extern int bssplitstrcb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); + + Iterate the set of disjoint sequential substrings over the stream s + divided by the entire substring splitStr. The parm passed to + bssplitstrcb is passed on to cb. If the function cb returns a + value < 0, then further iterating is halted and this return value is + returned by bssplitstrcb. + + Note: At the point of calling the cb function, the bStream pointer is + pointed exactly at the position right after having read the split + character. The cb function can act on the stream by causing the bStream + pointer to move, and bssplitstrcb will continue by starting the next + split at the position of the pointer after the return from cb. + + However, if the cb causes the bStream s to be destroyed then the cb must + return with a negative value, otherwise bssplitscb will continue in an + undefined manner. + + This function is provided as way to incrementally parse through a file + or other generic stream that in total size may otherwise exceed the + practical or desired memory available. As with the other split callback + based functions this is abortable and does not impose additional memory + allocation. + + .......................................................................... + + extern int bseof (const struct bStream * s); + + Return the defacto "EOF" (end of file) state of a stream (1 if the + bStream is in an EOF state, 0 if not, and BSTR_ERR if stream is closed or + detectably erroneous.) When the readPtr callback returns a value <= 0 + the stream reaches its "EOF" state. Note that bunread with non-empty + content will essentially turn off this state, and the stream will not be + in its "EOF" state so long as its possible to read more data out of it. + + Also note that the semantics of bseof() are slightly different from + something like feof(). I.e., reaching the end of the stream does not + necessarily guarantee that bseof() will return with a value indicating + that this has happened. bseof() will only return indicating that it has + reached the "EOF" and an attempt has been made to read past the end of + the bStream. + +The macros +---------- + + The macros described below are shown in a prototype form indicating their + intended usage. Note that the parameters passed to these macros will be + referenced multiple times. As with all macros, programmer care is + required to guard against unintended side effects. + + int blengthe (const_bstring b, int err); + + Returns the length of the bstring. If the bstring is NULL err is + returned. + + .......................................................................... + + int blength (const_bstring b); + + Returns the length of the bstring. If the bstring is NULL, the length + returned is 0. + + .......................................................................... + + int bchare (const_bstring b, int p, int c); + + Returns the p'th character of the bstring b. If the position p refers to + a position that does not exist in the bstring or the bstring is NULL, + then c is returned. + + .......................................................................... + + char bchar (const_bstring b, int p); + + Returns the p'th character of the bstring b. If the position p refers to + a position that does not exist in the bstring or the bstring is NULL, + then '\0' is returned. + + .......................................................................... + + char * bdatae (bstring b, char * err); + + Returns the char * data portion of the bstring b. If b is NULL, err is + returned. + + .......................................................................... + + char * bdata (bstring b); + + Returns the char * data portion of the bstring b. If b is NULL, NULL is + returned. + + .......................................................................... + + char * bdataofse (bstring b, int ofs, char * err); + + Returns the char * data portion of the bstring b offset by ofs. If b is + NULL, err is returned. + + .......................................................................... + + char * bdataofs (bstring b, int ofs); + + Returns the char * data portion of the bstring b offset by ofs. If b is + NULL, NULL is returned. + + .......................................................................... + + struct tagbstring var = bsStatic ("..."); + + The bsStatic macro allows for static declarations of literal string + constants as struct tagbstring structures. The resulting tagbstring does + not need to be freed or destroyed. Note that this macro is only well + defined for string literal arguments. For more general string pointers, + use the btfromcstr macro. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct + tagbstring has no effect. + + .......................................................................... + + <- bsStaticBlkParms ("...") + + The bsStaticBlkParms macro emits a pair of comma seperated parameters + corresponding to the block parameters for the block functions in Bstrlib + (i.e., blk2bstr, bcatblk, blk2tbstr, bisstemeqblk, bisstemeqcaselessblk.) + Note that this macro is only well defined for string literal arguments. + + Examples: + + bstring b = blk2bstr (bsStaticBlkParms ("Fast init. ")); + bcatblk (b, bsStaticBlkParms ("No frills fast concatenation.")); + + These are faster than using bfromcstr() and bcatcstr() respectively + because the length of the inline string is known as a compile time + constant. Also note that seperate struct tagbstring declarations for + holding the output of a bsStatic() macro are not required. + + .......................................................................... + + void btfromcstr (struct tagbstring& t, const char * s); + + Fill in the tagbstring t with the '\0' terminated char buffer s. This + action is purely reference oriented; no memory management is done. The + data member is just assigned s, and slen is assigned the strlen of s. + The s parameter is accessed exactly once in this macro. + + The resulting struct tagbstring is initially write protected. Attempts + to write to this struct tagbstring in a write protected state from any + bstrlib function will lead to BSTR_ERR being returned. Invoke the + bwriteallow on this struct tagbstring to make it writeable (though this + requires that s be obtained from a function compatible with malloc.) + + .......................................................................... + + void btfromblk (struct tagbstring& t, void * s, int len); + + Fill in the tagbstring t with the data buffer s with length len. This + action is purely reference oriented; no memory management is done. The + data member of t is just assigned s, and slen is assigned len. Note that + the buffer is not appended with a '\0' character. The s and len + parameters are accessed exactly once each in this macro. + + The resulting struct tagbstring is initially write protected. Attempts + to write to this struct tagbstring in a write protected state from any + bstrlib function will lead to BSTR_ERR being returned. Invoke the + bwriteallow on this struct tagbstring to make it writeable (though this + requires that s be obtained from a function compatible with malloc.) + + .......................................................................... + + void btfromblkltrimws (struct tagbstring& t, void * s, int len); + + Fill in the tagbstring t with the data buffer s with length len after it + has been left trimmed. This action is purely reference oriented; no + memory management is done. The data member of t is just assigned to a + pointer inside the buffer s. Note that the buffer is not appended with a + '\0' character. The s and len parameters are accessed exactly once each + in this macro. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct + tagbstring has no effect. + + .......................................................................... + + void btfromblkrtrimws (struct tagbstring& t, void * s, int len); + + Fill in the tagbstring t with the data buffer s with length len after it + has been right trimmed. This action is purely reference oriented; no + memory management is done. The data member of t is just assigned to a + pointer inside the buffer s. Note that the buffer is not appended with a + '\0' character. The s and len parameters are accessed exactly once each + in this macro. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct + tagbstring has no effect. + + .......................................................................... + + void btfromblktrimws (struct tagbstring& t, void * s, int len); + + Fill in the tagbstring t with the data buffer s with length len after it + has been left and right trimmed. This action is purely reference + oriented; no memory management is done. The data member of t is just + assigned to a pointer inside the buffer s. Note that the buffer is not + appended with a '\0' character. The s and len parameters are accessed + exactly once each in this macro. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. Invoking the bwriteallow macro onto this struct + tagbstring has no effect. + + .......................................................................... + + void bmid2tbstr (struct tagbstring& t, bstring b, int pos, int len); + + Fill the tagbstring t with the substring from b, starting from position + pos with a length len. The segment is clamped by the boundaries of + the bstring b. This action is purely reference oriented; no memory + management is done. Note that the buffer is not appended with a '\0' + character. Note that the t parameter to this macro may be accessed + multiple times. Note that the contents of t will become undefined + if the contents of b change or are destroyed. + + The resulting struct tagbstring is permanently write protected. Attempts + to write to this struct tagbstring in a write protected state from any + bstrlib function will lead to BSTR_ERR being returned. Invoking the + bwriteallow macro on this struct tagbstring will have no effect. + + .......................................................................... + + void bvformata (int& ret, bstring b, const char * format, lastarg); + + Append the bstring b with printf like formatting with the format control + string, and the arguments taken from the ... list of arguments after + lastarg passed to the containing function. If the containing function + does not have ... parameters or lastarg is not the last named parameter + before the ... then the results are undefined. If successful, the + results are appended to b and BSTR_OK is assigned to ret. Otherwise + BSTR_ERR is assigned to ret. + + Example: + + void dbgerror (FILE * fp, const char * fmt, ...) { + int ret; + bstring b; + bvformata (ret, b = bfromcstr ("DBG: "), fmt, fmt); + if (BSTR_OK == ret) fputs ((char *) bdata (b), fp); + bdestroy (b); + } + + Note that if the BSTRLIB_NOVSNP macro was set when bstrlib had been + compiled the bvformata macro will not link properly. If the + BSTRLIB_NOVSNP macro has been set, the bvformata macro will not be + available. + + .......................................................................... + + void bwriteprotect (struct tagbstring& t); + + Disallow bstring from being written to via the bstrlib API. Attempts to + write to the resulting tagbstring from any bstrlib function will lead to + BSTR_ERR being returned. + + Note: bstrings which are write protected cannot be destroyed via bdestroy. + + Note to C++ users: Setting a CBString as write protected will not prevent + it from being destroyed by the destructor. + + .......................................................................... + + void bwriteallow (struct tagbstring& t); + + Allow bstring to be written to via the bstrlib API. Note that such an + action makes the bstring both writable and destroyable. If the bstring is + not legitimately writable (as is the case for struct tagbstrings + initialized with a bsStatic value), the results of this are undefined. + + Note that invoking the bwriteallow macro may increase the number of + reallocs by one more than necessary for every call to bwriteallow + interleaved with any bstring API which writes to this bstring. + + .......................................................................... + + int biswriteprotected (struct tagbstring& t); + + Returns 1 if the bstring is write protected, otherwise 0 is returned. + +=============================================================================== + +The bstest module +----------------- + +The bstest module is just a unit test for the bstrlib module. For correct +implementations of bstrlib, it should execute with 0 failures being reported. +This test should be utilized if modifications/customizations to bstrlib have +been performed. It tests each core bstrlib function with bstrings of every +mode (read-only, NULL, static and mutable) and ensures that the expected +semantics are observed (including results that should indicate an error). It +also tests for aliasing support. Passing bstest is a necessary but not a +sufficient condition for ensuring the correctness of the bstrlib module. + + +The test module +--------------- + +The test module is just a unit test for the bstrwrap module. For correct +implementations of bstrwrap, it should execute with 0 failures being +reported. This test should be utilized if modifications/customizations to +bstrwrap have been performed. It tests each core bstrwrap function with +CBStrings write protected or not and ensures that the expected semantics are +observed (including expected exceptions.) Note that exceptions cannot be +disabled to run this test. Passing test is a necessary but not a sufficient +condition for ensuring the correctness of the bstrwrap module. + +=============================================================================== + +Using Bstring and CBString as an alternative to the C library +------------------------------------------------------------- + +First let us give a table of C library functions and the alternative bstring +functions and CBString methods that should be used instead of them. + +C-library Bstring alternative CBString alternative +--------- ------------------- -------------------- +gets bgets ::gets +strcpy bassign = operator +strncpy bassignmidstr ::midstr +strcat bconcat += operator +strncat bconcat + btrunc += operator + ::trunc +strtok bsplit, bsplits ::split +sprintf b(assign)format ::format +snprintf b(assign)format + btrunc ::format + ::trunc +vsprintf bvformata bvformata + +vsnprintf bvformata + btrunc bvformata + btrunc +vfprintf bvformata + fputs use bvformata + fputs +strcmp biseq, bstrcmp comparison operators. +strncmp bstrncmp, memcmp bstrncmp, memcmp +strlen ->slen, blength ::length +strdup bstrcpy constructor +strset bpattern ::fill +strstr binstr ::find +strpbrk binchr ::findchr +stricmp bstricmp cast & use bstricmp +strlwr btolower cast & use btolower +strupr btoupper cast & use btoupper +strrev bReverse (aux module) cast & use bReverse +strchr bstrchr cast & use bstrchr +strspnp use strspn use strspn +ungetc bsunread bsunread + +The top 9 C functions listed here are troublesome in that they impose memory +management in the calling function. The Bstring and CBstring interfaces have +built-in memory management, so there is far less code with far less potential +for buffer overrun problems. strtok can only be reliably called as a "leaf" +calculation, since it (quite bizarrely) maintains hidden internal state. And +gets is well known to be broken no matter what. The Bstrlib alternatives do +not suffer from those sorts of problems. + +The substitute for strncat can be performed with higher performance by using +the blk2tbstr macro to create a presized second operand for bconcat. + +C-library Bstring alternative CBString alternative +--------- ------------------- -------------------- +strspn strspn acceptable strspn acceptable +strcspn strcspn acceptable strcspn acceptable +strnset strnset acceptable strnset acceptable +printf printf acceptable printf acceptable +puts puts acceptable puts acceptable +fprintf fprintf acceptable fprintf acceptable +fputs fputs acceptable fputs acceptable +memcmp memcmp acceptable memcmp acceptable + +Remember that Bstring (and CBstring) functions will automatically append the +'\0' character to the character data buffer. So by simply accessing the data +buffer directly, ordinary C string library functions can be called directly +on them. Note that bstrcmp is not the same as memcmp in exactly the same way +that strcmp is not the same as memcmp. + +C-library Bstring alternative CBString alternative +--------- ------------------- -------------------- +fread balloc + fread ::alloc + fread +fgets balloc + fgets ::alloc + fgets + +These are odd ones because of the exact sizing of the buffer required. The +Bstring and CBString alternatives requires that the buffers are forced to +hold at least the prescribed length, then just use fread or fgets directly. +However, typically the automatic memory management of Bstring and CBstring +will make the typical use of fgets and fread to read specifically sized +strings unnecessary. + +Implementation Choices +---------------------- + +Overhead: +......... + +The bstring library has more overhead versus straight char buffers for most +functions. This overhead is essentially just the memory management and +string header allocation. This overhead usually only shows up for small +string manipulations. The performance loss has to be considered in +light of the following: + +1) What would be the performance loss of trying to write this management + code in one's own application? +2) Since the bstring library source code is given, a sufficiently powerful + modern inlining globally optimizing compiler can remove function call + overhead. + +Since the data type is exposed, a developer can replace any unsatisfactory +function with their own inline implementation. And that is besides the main +point of what the better string library is mainly meant to provide. Any +overhead lost has to be compared against the value of the safe abstraction +for coupling memory management and string functionality. + +Performance of the C interface: +............................... + +The algorithms used have performance advantages versus the analogous C +library functions. For example: + +1. bfromcstr/blk2str/bstrcpy versus strcpy/strdup. By using memmove instead + of strcpy, the break condition of the copy loop is based on an independent + counter (that should be allocated in a register) rather than having to + check the results of the load. Modern out-of-order executing CPUs can + parallelize the final branch mis-predict penality with the loading of the + source string. Some CPUs will also tend to have better built-in hardware + support for counted memory moves than load-compare-store. (This is a + minor, but non-zero gain.) +2. biseq versus strcmp. If the strings are unequal in length, bsiseq will + return in O(1) time. If the strings are aliased, or have aliased data + buffers, biseq will return in O(1) time. strcmp will always be O(k), + where k is the length of the common prefix or the whole string if they are + identical. +3. ->slen versus strlen. ->slen is obviously always O(1), while strlen is + always O(n) where n is the length of the string. +4. bconcat versus strcat. Both rely on precomputing the length of the + destination string argument, which will favor the bstring library. On + iterated concatenations the performance difference can be enormous. +5. bsreadln versus fgets. The bsreadln function reads large blocks at a time + from the given stream, then parses out lines from the buffers directly. + Some C libraries will implement fgets as a loop over single fgetc calls. + Testing indicates that the bsreadln approach can be several times faster + for fast stream devices (such as a file that has been entirely cached.) +6. bsplits/bsplitscb versus strspn. Accelerators for the set of match + characters are generated only once. + +Practical testing indicates that in general Bstrlib is never signifcantly +slower than the C library for common operations, while very often having a +performance advantage that ranges from significant to massive. Even for +functions like b(n)inchr versus str(c)spn() (where, in theory, there is no +advantage for the Bstrlib architecture) the performance of Bstrlib is vastly +superior to most tested C library implementations. + +Some of Bstrlib's extra functionality also lead to inevitable performance +advantages over typical C solutions. For example, using the blk2tbstr macro, +one can (in O(1) time) generate an internal substring by reference while not +disturbing the original string. If disturbing the original string is not an +option, typically, a comparable C solution would have to make a copy of the +substring to provide similar functionality. Another example is reverse +character set scanning -- the str(c)spn functions only scan in a forward +direction which can complicate some parsing algorithms. + +Where high performance char * based algorithms are available, Bstrlib can +still leverage them by accessing the ->data field on bstrings. So +realistically Bstrlib can never be significantly slower than any standard +'\0' terminated char * based solutions. + +Performance of the C++ interface: +................................. + +The C++ interface has been designed with an emphasis on abstraction and safety +first. However, since it is substantially a wrapper for the C bstring +functions, for longer strings the performance comments described in the +"Performance of the C interface" section above still apply. Note that the +(CBString *) type can be directly cast to a (bstring) type, and passed as +parameters to the C functions (though a CBString must never be passed to +bdestroy.) + +Probably the most controversial choice is performing full bounds checking on +the [] operator. This decision was made because 1) the fast alternative of +not bounds checking is still available by first casting the CBString to a +(const char *) buffer or to a (struct tagbstring) then derefencing .data and +2) because the lack of bounds checking is seen as one of the main weaknesses +of C/C++ versus other languages. This check being done on every access leads +to individual character extraction being actually slower than other languages +in this one respect (other language's compilers will normally dedicate more +resources on hoisting or removing bounds checking as necessary) but otherwise +bring C++ up to the level of other languages in terms of functionality. + +It is common for other C++ libraries to leverage the abstractions provided by +C++ to use reference counting and "copy on write" policies. While these +techniques can speed up some scenarios, they impose a problem with respect to +thread safety. bstrings and CBStrings can be properly protected with +"per-object" mutexes, meaning that two bstrlib calls can be made and execute +simultaneously, so long as the bstrings and CBstrings are distinct. With a +reference count and alias before copy on write policy, global mutexes are +required that prevent multiple calls to the strings library to execute +simultaneously regardless of whether or not the strings represent the same +string. + +One interesting trade off in CBString is that the default constructor is not +trivial. I.e., it always prepares a ready to use memory buffer. The purpose +is to ensure that there is a uniform internal composition for any functioning +CBString that is compatible with bstrings. It also means that the other +methods in the class are not forced to perform "late initialization" checks. +In the end it means that construction of CBStrings are slower than other +comparable C++ string classes. Initial testing, however, indicates that +CBString outperforms std::string and MFC's CString, for example, in all other +operations. So to work around this weakness it is recommended that CBString +declarations be pushed outside of inner loops. + +Practical testing indicates that with the exception of the caveats given +above (constructors and safe index character manipulations) the C++ API for +Bstrlib generally outperforms popular standard C++ string classes. Amongst +the standard libraries and compilers, the quality of concatenation operations +varies wildly and very little care has gone into search functions. Bstrlib +dominates those performance benchmarks. + +Memory management: +.................. + +The bstring functions which write and modify bstrings will automatically +reallocate the backing memory for the char buffer whenever it is required to +grow. The algorithm for resizing chosen is to snap up to sizes that are a +power of two which are sufficient to hold the intended new size. Memory +reallocation is not performed when the required size of the buffer is +decreased. This behavior can be relied on, and is necessary to make the +behaviour of balloc deterministic. This trades off additional memory usage +for decreasing the frequency for required reallocations: + +1. For any bstring whose size never exceeds n, its buffer is not ever + reallocated more than log_2(n) times for its lifetime. +2. For any bstring whose size never exceeds n, its buffer is never more than + 2*(n+1) in length. (The extra characters beyond 2*n are to allow for the + implicit '\0' which is always added by the bstring modifying functions.) + +Decreasing the buffer size when the string decreases in size would violate 1) +above and in real world case lead to pathological heap thrashing. Similarly, +allocating more tightly than "least power of 2 greater than necessary" would +lead to a violation of 1) and have the same potential for heap thrashing. + +Property 2) needs emphasizing. Although the memory allocated is always a +power of 2, for a bstring that grows linearly in size, its buffer memory also +grows linearly, not exponentially. The reason is that the amount of extra +space increases with each reallocation, which decreases the frequency of +future reallocations. + +Obviously, given that bstring writing functions may reallocate the data +buffer backing the target bstring, one should not attempt to cache the data +buffer address and use it after such bstring functions have been called. +This includes making reference struct tagbstrings which alias to a writable +bstring. + +balloc or bfromcstralloc can be used to preallocate the minimum amount of +space used for a given bstring. This will reduce even further the number of +times the data portion is reallocated. If the length of the string is never +more than one less than the memory length then there will be no further +reallocations. + +Note that invoking the bwriteallow macro may increase the number of reallocs +by one more than necessary for every call to bwriteallow interleaved with any +bstring API which writes to this bstring. + +The library does not use any mechanism for automatic clean up for the C API. +Thus explicit clean up via calls to bdestroy() are required to avoid memory +leaks. + +Constant and static tagbstrings: +................................ + +A struct tagbstring can be write protected from any bstrlib function using +the bwriteprotect macro. A write protected struct tagbstring can then be +reset to being writable via the bwriteallow macro. There is, of course, no +protection from attempts to directly access the bstring members. Modifying a +bstring which is write protected by direct access has undefined behavior. + +static struct tagbstrings can be declared via the bsStatic macro. They are +considered permanently unwritable. Such struct tagbstrings's are declared +such that attempts to write to it are not well defined. Invoking either +bwriteallow or bwriteprotect on static struct tagbstrings has no effect. + +struct tagbstring's initialized via btfromcstr or blk2tbstr are protected by +default but can be made writeable via the bwriteallow macro. If bwriteallow +is called on such struct tagbstring's, it is the programmer's responsibility +to ensure that: + +1) the buffer supplied was allocated from the heap. +2) bdestroy is not called on this tagbstring (unless the header itself has + also been allocated from the heap.) +3) free is called on the buffer to reclaim its memory. + +bwriteallow and bwriteprotect can be invoked on ordinary bstrings (they have +to be dereferenced with the (*) operator to get the levels of indirection +correct) to give them write protection. + +Buffer declaration: +................... + +The memory buffer is actually declared "unsigned char *" instead of "char *". +The reason for this is to trigger compiler warnings whenever uncasted char +buffers are assigned to the data portion of a bstring. This will draw more +diligent programmers into taking a second look at the code where they +have carelessly left off the typically required cast. (Research from +AT&T/Lucent indicates that additional programmer eyeballs is one of the most +effective mechanisms at ferreting out bugs.) + +Function pointers: +.................. + +The bgets, bread and bStream functions use function pointers to obtain +strings from data streams. The function pointer declarations have been +specifically chosen to be compatible with the fgetc and fread functions. +While this may seem to be a convoluted way of implementing fgets and fread +style functionality, it has been specifically designed this way to ensure +that there is no dependency on a single narrowly defined set of device +interfaces, such as just stream I/O. In the embedded world, its quite +possible to have environments where such interfaces may not exist in the +standard C library form. Furthermore, the generalization that this opens up +allows for more sophisticated uses for these functions (performing an fgets +like function on a socket, for example.) By using function pointers, it also +allows such abstract stream interfaces to be created using the bstring library +itself while not creating a circular dependency. + +Use of int's for sizes: +....................... + +This is just a recognition that 16bit platforms with requirements for strings +that are larger than 64K and 32bit+ platforms with requirements for strings +that are larger than 4GB are pretty marginal. The main focus is for 32bit +platforms, and emerging 64bit platforms with reasonable < 4GB string +requirements. Using ints allows for negative values which has meaning +internally to bstrlib. + +Semantic consideration: +....................... + +Certain care needs to be taken when copying and aliasing bstrings. A bstring +is essentially a pointer type which points to a multipart abstract data +structure. Thus usage, and lifetime of bstrings have semantics that follow +these considerations. For example: + + bstring a, b; + struct tagbstring t; + + a = bfromcstr("Hello"); /* Create new bstring and copy "Hello" into it. */ + b = a; /* Alias b to the contents of a. */ + t = *a; /* Create a current instance pseudo-alias of a. */ + bconcat (a, b); /* Double a and b, t is now undefined. */ + bdestroy (a); /* Destroy the contents of both a and b. */ + +Variables of type bstring are really just references that point to real +bstring objects. The equal operator (=) creates aliases, and the asterisk +dereference operator (*) creates a kind of alias to the current instance (which +is generally not useful for any purpose.) Using bstrcpy() is the correct way +of creating duplicate instances. The ampersand operator (&) is useful for +creating aliases to struct tagbstrings (remembering that constructed struct +tagbstrings are not writable by default.) + +CBStrings use complete copy semantics for the equal operator (=), and thus do +not have these sorts of issues. + +Debugging: +.......... + +Bstrings have a simple, exposed definition and construction, and the library +itself is open source. So most debugging is going to be fairly straight- +forward. But the memory for bstrings come from the heap, which can often be +corrupted indirectly, and it might not be obvious what has happened even from +direct examination of the contents in a debugger or a core dump. There are +some tools such as Purify, Insure++ and Electric Fence which can help solve +such problems, however another common approach is to directly instrument the +calls to malloc, realloc, calloc, free, memcpy, memmove and/or other calls +by overriding them with macro definitions. + +Although the user could hack on the Bstrlib sources directly as necessary to +perform such an instrumentation, Bstrlib comes with a built-in mechanism for +doing this. By defining the macro BSTRLIB_MEMORY_DEBUG and providing an +include file named memdbg.h this will force the core Bstrlib modules to +attempt to include this file. In such a file, macros could be defined which +overrides Bstrlib's useage of the C standard library. + +Rather than calling malloc, realloc, free, memcpy or memmove directly, Bstrlib +emits the macros bstr__alloc, bstr__realloc, bstr__free, bstr__memcpy and +bstr__memmove in their place respectively. By default these macros are simply +assigned to be equivalent to their corresponding C standard library function +call. However, if they are given earlier macro definitions (via the back +door include file) they will not be given their default definition. In this +way Bstrlib's interface to the standard library can be changed but without +having to directly redefine or link standard library symbols (both of which +are not strictly ANSI C compliant.) + +An example definition might include: + + #define bstr__alloc(sz) X_malloc ((sz), __LINE__, __FILE__) + +which might help contextualize heap entries in a debugging environment. + +The NULL parameter and sanity checking of bstrings is part of the Bstrlib +API, and thus Bstrlib itself does not present any different modes which would +correspond to "Debug" or "Release" modes. Bstrlib always contains mechanisms +which one might think of as debugging features, but retains the performance +and small memory footprint one would normally associate with release mode +code. + +Integration Microsoft's Visual Studio debugger: +............................................... + +Microsoft's Visual Studio debugger has a capability of customizable mouse +float over data type descriptions. This is accomplished by editting the +AUTOEXP.DAT file to include the following: + + ; new for CBString + tagbstring =slen= mlen= + Bstrlib::CBStringList =count= + +In Visual C++ 6.0 this file is located in the directory: + + C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin + +and in Visual Studio .NET 2003 its located here: + + C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\Debugger + +This will improve the ability of debugging with Bstrlib under Visual Studio. + +Security +-------- + +Bstrlib does not come with explicit security features outside of its fairly +comprehensive error detection, coupled with its strict semantic support. +That is to say that certain common security problems, such as buffer overrun, +constant overwrite, arbitrary truncation etc, are far less likely to happen +inadvertently. Where it does help, Bstrlib maximizes its advantage by +providing developers a simple adoption path that lets them leave less secure +string mechanisms behind. The library will not leave developers wanting, so +they will be less likely to add new code using a less secure string library +to add functionality that might be missing from Bstrlib. + +That said there are a number of security ideas not addressed by Bstrlib: + +1. Race condition exploitation (i.e., verifying a string's contents, then +raising the privilege level and execute it as a shell command as two +non-atomic steps) is well beyond the scope of what Bstrlib can provide. It +should be noted that MFC's built-in string mutex actually does not solve this +problem either -- it just removes immediate data corruption as a possible +outcome of such exploit attempts (it can be argued that this is worse, since +it will leave no trace of the exploitation). In general race conditions have +to be dealt with by careful design and implementation; it cannot be assisted +by a string library. + +2. Any kind of access control or security attributes to prevent usage in +dangerous interfaces such as system(). Perl includes a "trust" attribute +which can be endowed upon strings that are intended to be passed to such +dangerous interfaces. However, Perl's solution reflects its own limitations +-- notably that it is not a strongly typed language. In the example code for +Bstrlib, there is a module called taint.cpp. It demonstrates how to write a +simple wrapper class for managing "untainted" or trusted strings using the +type system to prevent questionable mixing of ordinary untrusted strings with +untainted ones then passing them to dangerous interfaces. In this way the +security correctness of the code reduces to auditing the direct usages of +dangerous interfaces or promotions of tainted strings to untainted ones. + +3. Encryption of string contents is way beyond the scope of Bstrlib. +Maintaining encrypted string contents in the futile hopes of thwarting things +like using system-level debuggers to examine sensitive string data is likely +to be a wasted effort (imagine a debugger that runs at a higher level than a +virtual processor where the application runs). For more standard encryption +usages, since the bstring contents are simply binary blocks of data, this +should pose no problem for usage with other standard encryption libraries. + +Compatibility +------------- + +The Better String Library is known to compile and function correctly with the +following compilers: + + - Microsoft Visual C++ + - Watcom C/C++ + - Intel's C/C++ compiler (Windows) + - The GNU C/C++ compiler (cygwin and Linux on PPC64) + - Borland C + - Turbo C + +Setting of configuration options should be unnecessary for these compilers +(unless exceptions are being disabled or STLport has been added to WATCOM +C/C++). Bstrlib has been developed with an emphasis on portability. As such +porting it to other compilers should be straight forward. This package +includes a porting guide (called porting.txt) which explains what issues may +exist for porting Bstrlib to different compilers and environments. + +ANSI issues +----------- + +1. The function pointer types bNgetc and bNread have prototypes which are very +similar to, but not exactly the same as fgetc and fread respectively. +Basically the FILE * parameter is replaced by void *. The purpose of this +was to allow one to create other functions with fgetc and fread like +semantics without being tied to ANSI C's file streaming mechanism. I.e., one +could very easily adapt it to sockets, or simply reading a block of memory, +or procedurally generated strings (for fractal generation, for example.) + +The problem is that invoking the functions (bNgetc)fgetc and (bNread)fread is +not technically legal in ANSI C. The reason being that the compiler is only +able to coerce the function pointers themselves into the target type, however +are unable to perform any cast (implicit or otherwise) on the parameters +passed once invoked. I.e., if internally void * and FILE * need some kind of +mechanical coercion, the compiler will not properly perform this conversion +and thus lead to undefined behavior. + +Apparently a platform from Data General called "Eclipse" and another from +Tandem called "NonStop" have a different representation for pointers to bytes +and pointers to words, for example, where coercion via casting is necessary. +(Actual confirmation of the existence of such machines is hard to come by, so +it is prudent to be skeptical about this information.) However, this is not +an issue for any known contemporary platforms. One may conclude that such +platforms are effectively apocryphal even if they do exist. + +To correctly work around this problem to the satisfaction of the ANSI +limitations, one needs to create wrapper functions for fgets and/or +fread with the prototypes of bNgetc and/or bNread respectively which performs +no other action other than to explicitely cast the void * parameter to a +FILE *, and simply pass the remaining parameters straight to the function +pointer call. + +The wrappers themselves are trivial: + + size_t freadWrap (void * buff, size_t esz, size_t eqty, void * parm) { + return fread (buff, esz, eqty, (FILE *) parm); + } + + int fgetcWrap (void * parm) { + return fgetc ((FILE *) parm); + } + +These have not been supplied in bstrlib or bstraux to prevent unnecessary +linking with file I/O functions. + +2. vsnprintf is not available on all compilers. Because of this, the bformat +and bformata functions (and format and formata methods) are not guaranteed to +work properly. For those compilers that don't have vsnprintf, the +BSTRLIB_NOVSNP macro should be set before compiling bstrlib, and the format +functions/method will be disabled. + +The more recent ANSI C standards have specified the required inclusion of a +vsnprintf function. + +3. The bstrlib function names are not unique in the first 6 characters. This +is only an issue for older C compiler environments which do not store more +than 6 characters for function names. + +4. The bsafe module defines macros and function names which are part of the +C library. This simply overrides the definition as expected on all platforms +tested, however it is not sanctioned by the ANSI standard. This module is +clearly optional and should be omitted on platforms which disallow its +undefined semantics. + +In practice the real issue is that some compilers in some modes of operation +can/will inline these standard library functions on a module by module basis +as they appear in each. The linker will thus have no opportunity to override +the implementation of these functions for those cases. This can lead to +inconsistent behaviour of the bsafe module on different platforms and +compilers. + +=============================================================================== + +Comparison with Microsoft's CString class +----------------------------------------- + +Although developed independently, CBStrings have very similar functionality to +Microsoft's CString class. However, the bstring library has significant +advantages over CString: + +1. Bstrlib is a C-library as well as a C++ library (using the C++ wrapper). + + - Thus it is compatible with more programming environments and + available to a wider population of programmers. + +2. The internal structure of a bstring is considered exposed. + + - A single contiguous block of data can be cut into read-only pieces by + simply creating headers, without allocating additional memory to create + reference copies of each of these sub-strings. + - In this way, using bstrings in a totally abstracted way becomes a choice + rather than an imposition. Further this choice can be made differently + at different layers of applications that use it. + +3. Static declaration support precludes the need for constructor + invocation. + + - Allows for static declarations of constant strings that has no + additional constructor overhead. + +4. Bstrlib is not attached to another library. + + - Bstrlib is designed to be easily plugged into any other library + collection, without dependencies on other libraries or paradigms (such + as "MFC".) + +The bstring library also comes with a few additional functions that are not +available in the CString class: + + - bsetstr + - bsplit + - bread + - breplace (this is different from CString::Replace()) + - Writable indexed characters (for example a[i]='x') + +Interestingly, although Microsoft did implement mid$(), left$() and right$() +functional analogues (these are functions from GWBASIC) they seem to have +forgotten that mid$() could be also used to write into the middle of a string. +This functionality exists in Bstrlib with the bsetstr() and breplace() +functions. + +Among the disadvantages of Bstrlib is that there is no special support for +localization or wide characters. Such things are considered beyond the scope +of what bstrings are trying to deliver. CString essentially supports the +older UCS-2 version of Unicode via widechar_t as an application-wide compile +time switch. + +CString's also use built-in mechanisms for ensuring thread safety under all +situations. While this makes writing thread safe code that much easier, this +built-in safety feature has a price -- the inner loops of each CString method +runs in its own critical section (grabbing and releasing a light weight mutex +on every operation.) The usual way to decrease the impact of a critical +section performance penalty is to amortize more operations per critical +section. But since the implementation of CStrings is fixed as a one critical +section per-operation cost, there is no way to leverage this common +performance enhancing idea. + +The search facilities in Bstrlib are comparable to those in MFC's CString +class, though it is missing locale specific collation. But because Bstrlib +is interoperable with C's char buffers, it will allow programmers to write +their own string searching mechanism (such as Boyer-Moore), or be able to +choose from a variety of available existing string searching libraries (such +as those for regular expressions) without difficulty. + +Microsoft used a very non-ANSI conforming trick in its implementation to +allow printf() to use the "%s" specifier to output a CString correctly. This +can be convenient, but it is inherently not portable. CBString requires an +explicit cast, while bstring requires the data member to be dereferenced. +Microsoft's own documentation recommends casting, instead of relying on this +feature. + +Comparison with C++'s std::string +--------------------------------- + +This is the C++ language's standard STL based string class. + +1. There is no C implementation. +2. The [] operator is not bounds checked. +3. Missing a lot of useful functions like printf-like formatting. +4. Some sub-standard std::string implementations (SGI) are necessarily unsafe + to use with multithreading. +5. Limited by STL's std::iostream which in turn is limited by ifstream which + can only take input from files. (Compare to CBStream's API which can take + abstracted input.) +6. Extremely uneven performance across implementations. + +Comparison with ISO C TR 24731 proposal +--------------------------------------- + +Following the ISO C99 standard, Microsoft has proposed a group of C library +extensions which are supposedly "safer and more secure". This proposal is +expected to be adopted by the ISO C standard which follows C99. + +The proposal reveals itself to be very similar to Microsoft's "StrSafe" +library. The functions are basically the same as other standard C library +string functions except that destination parameters are paired with an +additional length parameter of type rsize_t. rsize_t is the same as size_t, +however, the range is checked to make sure its between 1 and RSIZE_MAX. Like +Bstrlib, the functions perform a "parameter check". Unlike Bstrlib, when a +parameter check fails, rather than simply outputing accumulatable error +statuses, they call a user settable global error function handler, and upon +return of control performs no (additional) detrimental action. The proposal +covers basic string functions as well as a few non-reenterable functions +(asctime, ctime, and strtok). + +1. Still based solely on char * buffers (and therefore strlen() and strcat() + is still O(n), and there are no faster streq() comparison functions.) +2. No growable string semantics. +3. Requires manual buffer length synchronization in the source code. +4. No attempt to enhance functionality of the C library. +5. Introduces a new error scenario (strings exceeding RSIZE_MAX length). + +The hope is that by exposing the buffer length requirements there will be +fewer buffer overrun errors. However, the error modes are really just +transformed, rather than removed. The real problem of buffer overflows is +that they all happen as a result of erroneous programming. So forcing +programmers to manually deal with buffer limits, will make them more aware of +the problem but doesn't remove the possibility of erroneous programming. So +a programmer that erroneously mixes up the rsize_t parameters is no better off +from a programmer that introduces potential buffer overflows through other +more typical lapses. So at best this may reduce the rate of erroneous +programming, rather than making any attempt at removing failure modes. + +The error handler can discriminate between types of failures, but does not +take into account any callsite context. So the problem is that the error is +going to be manifest in a piece of code, but there is no pointer to that +code. It would seem that passing in the call site __FILE__, __LINE__ as +parameters would be very useful, but the API clearly doesn't support such a +thing (it would increase code bloat even more than the extra length +parameter does, and would require macro tricks to implement). + +The Bstrlib C API takes the position that error handling needs to be done at +the callsite, and just tries to make it as painless as possible. Furthermore, +error modes are removed by supporting auto-growing strings and aliasing. For +capturing errors in more central code fragments, Bstrlib's C++ API uses +exception handling extensively, which is superior to the leaf-only error +handler approach. + +Comparison with Managed String Library CERT proposal +---------------------------------------------------- + +The main webpage for the managed string library: +http://www.cert.org/secure-coding/managedstring.html + +Robert Seacord at CERT has proposed a C string library that he calls the +"Managed String Library" for C. Like Bstrlib, it introduces a new type +which is called a managed string. The structure of a managed string +(string_m) is like a struct tagbstring but missing the length field. This +internal structure is considered opaque. The length is, like the C standard +library, always computed on the fly by searching for a terminating NUL on +every operation that requires it. So it suffers from every performance +problem that the C standard library suffers from. Interoperating with C +string APIs (like printf, fopen, or anything else that takes a string +parameter) requires copying to additionally allocating buffers that have to +be manually freed -- this makes this library probably slower and more +cumbersome than any other string library in existence. + +The library gives a fully populated error status as the return value of every +string function. The hope is to be able to diagnose all problems +specifically from the return code alone. Comparing this to Bstrlib, which +aways returns one consistent error message, might make it seem that Bstrlib +would be harder to debug; but this is not true. With Bstrlib, if an error +occurs there is always enough information from just knowing there was an error +and examining the parameters to deduce exactly what kind of error has +happened. The managed string library thus gives up nested function calls +while achieving little benefit, while Bstrlib does not. + +One interesting feature that "managed strings" has is the idea of data +sanitization via character set whitelisting. That is to say, a globally +definable filter that makes any attempt to put invalid characters into strings +lead to an error and not modify the string. The author gives the following +example: + + // create valid char set + if (retValue = strcreate_m(&str1, "abc") ) { + fprintf( + stderr, + "Error %d from strcreate_m.\n", + retValue + ); + } + if (retValue = setcharset(str1)) { + fprintf( + stderr, + "Error %d from setcharset().\n", + retValue + ); + } + if (retValue = strcreate_m(&str1, "aabbccabc")) { + fprintf( + stderr, + "Error %d from strcreate_m.\n", + retValue + ); + } + // create string with invalid char set + if (retValue = strcreate_m(&str1, "abbccdabc")) { + fprintf( + stderr, + "Error %d from strcreate_m.\n", + retValue + ); + } + +Which we can compare with a more Bstrlib way of doing things: + + bstring bCreateWithFilter (const char * cstr, const_bstring filter) { + bstring b = bfromcstr (cstr); + if (BSTR_ERR != bninchr (b, filter) && NULL != b) { + fprintf (stderr, "Filter violation.\n"); + bdestroy (b); + b = NULL; + } + return b; + } + + struct tagbstring charFilter = bsStatic ("abc"); + bstring str1 = bCreateWithFilter ("aabbccabc", &charFilter); + bstring str2 = bCreateWithFilter ("aabbccdabc", &charFilter); + +The first thing we should notice is that with the Bstrlib approach you can +have different filters for different strings if necessary. Furthermore, +selecting a charset filter in the Managed String Library is uni-contextual. +That is to say, there can only be one such filter active for the entire +program, which means its usage is not well defined for intermediate library +usage (a library that uses it will interfere with user code that uses it, and +vice versa.) It is also likely to be poorly defined in multi-threading +environments. + +There is also a question as to whether the data sanitization filter is checked +on every operation, or just on creation operations. Since the charset can be +set arbitrarily at run time, it might be set *after* some managed strings have +been created. This would seem to imply that all functions should run this +additional check every time if there is an attempt to enforce this. This +would make things tremendously slow. On the other hand, if it is assumed that +only creates and other operations that take char *'s as input need be checked +because the charset was only supposed to be called once at and before any +other managed string was created, then one can see that its easy to cover +Bstrlib with equivalent functionality via a few wrapper calls such as the +example given above. + +And finally we have to question the value of sanitation in the first place. +For example, for httpd servers, there is generally a requirement that the +URLs parsed have some form that avoids undesirable translation to local file +system filenames or resources. The problem is that the way URLs can be +encoded, it must be completely parsed and translated to know if it is using +certain invalid character combinations. That is to say, merely filtering +each character one at a time is not necessarily the right way to ensure that +a string has safe contents. + +In the article that describes this proposal, it is claimed that it fairly +closely approximates the existing C API semantics. On this point we should +compare this "closeness" with Bstrlib: + + Bstrlib Managed String Library + ------- ---------------------- + +Pointer arithmetic Segment arithmetic N/A + +Use in C Std lib ->data, or bdata{e} getstr_m(x,*) ... free(x) + +String literals bsStatic, bsStaticBlk strcreate_m() + +Transparency Complete None + +Its pretty clear that the semantic mapping from C strings to Bstrlib is fairly +straightforward, and that in general semantic capabilities are the same or +superior in Bstrlib. On the other hand the Managed String Library is either +missing semantics or changes things fairly significantly. + +Comparison with Annexia's c2lib library +--------------------------------------- + +This library is available at: +http://www.annexia.org/freeware/c2lib + +1. Still based solely on char * buffers (and therefore strlen() and strcat() + is still O(n), and there are no faster streq() comparison functions.) + Their suggestion that alternatives which wrap the string data type (such as + bstring does) imposes a difficulty in interoperating with the C langauge's + ordinary C string library is not founded. +2. Introduction of memory (and vector?) abstractions imposes a learning + curve, and some kind of memory usage policy that is outside of the strings + themselves (and therefore must be maintained by the developer.) +3. The API is massive, and filled with all sorts of trivial (pjoin) and + controvertial (pmatch -- regular expression are not sufficiently + standardized, and there is a very large difference in performance between + compiled and non-compiled, REs) functions. Bstrlib takes a decidely + minimal approach -- none of the functionality in c2lib is difficult or + challenging to implement on top of Bstrlib (except the regex stuff, which + is going to be difficult, and controvertial no matter what.) +4. Understanding why c2lib is the way it is pretty much requires a working + knowledge of Perl. bstrlib requires only knowledge of the C string library + while providing just a very select few worthwhile extras. +5. It is attached to a lot of cruft like a matrix math library (that doesn't + include any functions for getting the determinant, eigenvectors, + eigenvalues, the matrix inverse, test for singularity, test for + orthogonality, a grahm schmit orthogonlization, LU decomposition ... I + mean why bother?) + +Convincing a development house to use c2lib is likely quite difficult. It +introduces too much, while not being part of any kind of standards body. The +code must therefore be trusted, or maintained by those that use it. While +bstring offers nothing more on this front, since its so much smaller, covers +far less in terms of scope, and will typically improve string performance, +the barrier to usage should be much smaller. + +Comparison with stralloc/qmail +------------------------------ + +More information about this library can be found here: +http://www.canonical.org/~kragen/stralloc.html or here: +http://cr.yp.to/lib/stralloc.html + +1. Library is very very minimal. A little too minimal. +2. Untargetted source parameters are not declared const. +3. Slightly different expected emphasis (like _cats function which takes an + ordinary C string char buffer as a parameter.) Its clear that the + remainder of the C string library is still required to perform more + useful string operations. + +The struct declaration for their string header is essentially the same as that +for bstring. But its clear that this was a quickly written hack whose goals +are clearly a subset of what Bstrlib supplies. For anyone who is served by +stralloc, Bstrlib is complete substitute that just adds more functionality. + +stralloc actually uses the interesting policy that a NULL data pointer +indicates an empty string. In this way, non-static empty strings can be +declared without construction. This advantage is minimal, since static empty +bstrings can be declared inline without construction, and if the string needs +to be written to it should be constructed from an empty string (or its first +initializer) in any event. + +wxString class +-------------- + +This is the string class used in the wxWindows project. A description of +wxString can be found here: +http://www.wxwindows.org/manuals/2.4.2/wx368.htm#wxstring + +This C++ library is similar to CBString. However, it is littered with +trivial functions (IsAscii, UpperCase, RemoveLast etc.) + +1. There is no C implementation. +2. The memory management strategy is to allocate a bounded fixed amount of + additional space on each resize, meaning that it does not have the + log_2(n) property that Bstrlib has (it will thrash very easily, cause + massive fragmentation in common heap implementations, and can easily be a + common source of performance problems). +3. The library uses a "copy on write" strategy, meaning that it has to deal + with multithreading problems. + +Vstr +---- + +This is a highly orthogonal C string library with an emphasis on +networking/realtime programming. It can be found here: +http://www.and.org/vstr/ + +1. The convoluted internal structure does not contain a '\0' char * compatible + buffer, so interoperability with the C library a non-starter. +2. The API and implementation is very large (owing to its orthogonality) and + can lead to difficulty in understanding its exact functionality. +3. An obvious dependency on gnu tools (confusing make configure step) +4. Uses a reference counting system, meaning that it is not likely to be + thread safe. + +The implementation has an extreme emphasis on performance for nontrivial +actions (adds, inserts and deletes are all constant or roughly O(#operations) +time) following the "zero copy" principle. This trades off performance of +trivial functions (character access, char buffer access/coersion, alias +detection) which becomes significantly slower, as well as incremental +accumulative costs for its searching/parsing functions. Whether or not Vstr +wins any particular performance benchmark will depend a lot on the benchmark, +but it should handily win on some, while losing dreadfully on others. + +The learning curve for Vstr is very steep, and it doesn't come with any +obvious way to build for Windows or other platforms without gnu tools. At +least one mechanism (the iterator) introduces a new undefined scenario +(writing to a Vstr while iterating through it.) Vstr has a very large +footprint, and is very ambitious in its total functionality. Vstr has no C++ +API. + +Vstr usage requires context initialization via vstr_init() which must be run +in a thread-local context. Given the totally reference based architecture +this means that sharing Vstrings across threads is not well defined, or at +least not safe from race conditions. This API is clearly geared to the older +standard of fork() style multitasking in UNIX, and is not safely transportable +to modern shared memory multithreading available in Linux and Windows. There +is no portable external solution making the library thread safe (since it +requires a mutex around each Vstr context -- not each string.) + +In the documentation for this library, a big deal is made of its self hosted +s(n)printf-like function. This is an issue for older compilers that don't +include vsnprintf(), but also an issue because Vstr has a slow conversion to +'\0' terminated char * mechanism. That is to say, using "%s" to format data +that originates from Vstr would be slow without some sort of native function +to do so. Bstrlib sidesteps the issue by relying on what snprintf-like +functionality does exist and having a high performance conversion to a char * +compatible string so that "%s" can be used directly. + +Str Library +----------- + +This is a fairly extensive string library, that includes full unicode support +and targetted at the goal of out performing MFC and STL. The architecture, +similarly to MFC's CStrings, is a copy on write reference counting mechanism. + +http://www.utilitycode.com/str/default.aspx + +1. Commercial. +2. C++ only. + +This library, like Vstr, uses a ref counting system. There is only so deeply +I can analyze it, since I don't have a license for it. However, performance +improvements over MFC's and STL, doesn't seem like a sufficient reason to +move your source base to it. For example, in the future, Microsoft may +improve the performance CString. + +It should be pointed out that performance testing of Bstrlib has indicated +that its relative performance advantage versus MFC's CString and STL's +std::string is at least as high as that for the Str library. + +libmib astrings +--------------- + +A handful of functional extensions to the C library that add dynamic string +functionality. +http://www.mibsoftware.com/libmib/astring/ + +This package basically references strings through char ** pointers and assumes +they are pointing to the top of an allocated heap entry (or NULL, in which +case memory will be newly allocated from the heap.) So its still up to user +to mix and match the older C string functions with these functions whenever +pointer arithmetic is used (i.e., there is no leveraging of the type system +to assert semantic differences between references and base strings as Bstrlib +does since no new types are introduced.) Unlike Bstrlib, exact string length +meta data is not stored, thus requiring a strlen() call on *every* string +writing operation. The library is very small, covering only a handful of C's +functions. + +While this is better than nothing, it is clearly slower than even the +standard C library, less safe and less functional than Bstrlib. + +To explain the advantage of using libmib, their website shows an example of +how dangerous C code: + + char buf[256]; + char *pszExtraPath = ";/usr/local/bin"; + + strcpy(buf,getenv("PATH")); /* oops! could overrun! */ + strcat(buf,pszExtraPath); /* Could overrun as well! */ + + printf("Checking...%s\n",buf); /* Some printfs overrun too! */ + +is avoided using libmib: + + char *pasz = 0; /* Must initialize to 0 */ + char *paszOut = 0; + char *pszExtraPath = ";/usr/local/bin"; + + if (!astrcpy(&pasz,getenv("PATH"))) /* malloc error */ exit(-1); + if (!astrcat(&pasz,pszExtraPath)) /* malloc error */ exit(-1); + + /* Finally, a "limitless" printf! we can use */ + asprintf(&paszOut,"Checking...%s\n",pasz);fputs(paszOut,stdout); + + astrfree(&pasz); /* Can use free(pasz) also. */ + astrfree(&paszOut); + +However, compare this to Bstrlib: + + bstring b, out; + + bcatcstr (b = bfromcstr (getenv ("PATH")), ";/usr/local/bin"); + out = bformat ("Checking...%s\n", bdatae (b, "")); + /* if (out && b) */ fputs (bdatae (out, ""), stdout); + bdestroy (b); + bdestroy (out); + +Besides being shorter, we can see that error handling can be deferred right +to the very end. Also, unlike the above two versions, if getenv() returns +with NULL, the Bstrlib version will not exhibit undefined behavior. +Initialization starts with the relevant content rather than an extra +autoinitialization step. + +libclc +------ + +An attempt to add to the standard C library with a number of common useful +functions, including additional string functions. +http://libclc.sourceforge.net/ + +1. Uses standard char * buffer, and adopts C 99's usage of "restrict" to pass + the responsibility to guard against aliasing to the programmer. +2. Adds no safety or memory management whatsoever. +3. Most of the supplied string functions are completely trivial. + +The goals of libclc and Bstrlib are clearly quite different. + +fireString +---------- + +http://firestuff.org/ + +1. Uses standard char * buffer, and adopts C 99's usage of "restrict" to pass + the responsibility to guard against aliasing to the programmer. +2. Mixes char * and length wrapped buffers (estr) functions, doubling the API + size, with safety limited to only half of the functions. + +Firestring was originally just a wrapper of char * functionality with extra +length parameters. However, it has been augmented with the inclusion of the +estr type which has similar functionality to stralloc. But firestring does +not nearly cover the functional scope of Bstrlib. + +Safe C String Library +--------------------- + +A library written for the purpose of increasing safety and power to C's string +handling capabilities. +http://www.zork.org/safestr/safestr.html + +1. While the safestr_* functions are safe in of themselves, interoperating + with char * string has dangerous unsafe modes of operation. +2. The architecture of safestr's causes the base pointer to change. Thus, + its not practical/safe to store a safestr in multiple locations if any + single instance can be manipulated. +3. Dependent on an additional error handling library. +4. Uses reference counting, meaning that it is either not thread safe or + slow and not portable. + +I think the idea of reallocating (and hence potentially changing) the base +pointer is a serious design flaw that is fatal to this architecture. True +safety is obtained by having automatic handling of all common scenarios +without creating implicit constraints on the user. + +Because of its automatic temporary clean up system, it cannot use "const" +semantics on input arguments. Interesting anomolies such as: + + safestr_t s, t; + s = safestr_replace (t = SAFESTR_TEMP ("This is a test"), + SAFESTR_TEMP (" "), SAFESTR_TEMP (".")); + /* t is now undefined. */ + +are possible. If one defines a function which takes a safestr_t as a +parameter, then the function would not know whether or not the safestr_t is +defined after it passes it to a safestr library function. The author +recommended method for working around this problem is to examine the +attributes of the safestr_t within the function which is to modify any of +its parameters and play games with its reference count. I think, therefore, +that the whole SAFESTR_TEMP idea is also fatally broken. + +The library implements immutability, optional non-resizability, and a "trust" +flag. This trust flag is interesting, and suggests that applying any +arbitrary sequence of safestr_* function calls on any set of trusted strings +will result in a trusted string. It seems to me, however, that if one wanted +to implement a trusted string semantic, one might do so by actually creating +a different *type* and only implement the subset of string functions that are +deemed safe (i.e., user input would be excluded, for example.) This, in +essence, would allow the compiler to enforce trust propogation at compile +time rather than run time. Non-resizability is also interesting, however, +it seems marginal (i.e., to want a string that cannot be resized, yet can be +modified and yet where a fixed sized buffer is undesirable.) + +=============================================================================== + +Examples +-------- + + Dumping a line numbered file: + + FILE * fp; + int i, ret; + struct bstrList * lines; + struct tagbstring prefix = bsStatic ("-> "); + + if (NULL != (fp = fopen ("bstrlib.txt", "rb"))) { + bstring b = bread ((bNread) fread, fp); + fclose (fp); + if (NULL != (lines = bsplit (b, '\n'))) { + for (i=0; i < lines->qty; i++) { + binsert (lines->entry[i], 0, &prefix, '?'); + printf ("%04d: %s\n", i, bdatae (lines->entry[i], "NULL")); + } + bstrListDestroy (lines); + } + bdestroy (b); + } + +For numerous other examples, see bstraux.c, bstraux.h and the example archive. + +=============================================================================== + +License +------- + +The Better String Library is available under either the BSD license (see the +accompanying license.txt) or the Gnu Public License version 2 (see the +accompanying gpl.txt) at the option of the user. + +=============================================================================== + +Acknowledgements +---------------- + +The following individuals have made significant contributions to the design +and testing of the Better String Library: + +Bjorn Augestad +Clint Olsen +Darryl Bleau +Fabian Cenedese +Graham Wideman +Ignacio Burgueno +International Business Machines Corporation +Ira Mica +John Kortink +Manuel Woelker +Marcel van Kervinck +Michael Hsieh +Richard A. Smith +Simon Ekstrom +Wayne Scott + +=============================================================================== diff --git a/allegro/src/misc/list.c b/allegro/src/misc/list.c new file mode 100644 index 00000000..66d98b26 --- /dev/null +++ b/allegro/src/misc/list.c @@ -0,0 +1,732 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Double linked list. + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + * + * + * This is a simple general purpose double linked list. + * + * This module is NOT thread-safe. + */ + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_list.h" + + +ALLEGRO_DEBUG_CHANNEL("list") + + +/* Definition of list, holds root and size. */ +struct _AL_LIST { + /* Root of the list. It is an element, but + * not visible one. Using it end and the + * beginning can be easily identified. */ + _AL_LIST_ITEM* root; + size_t size; + size_t capacity; + size_t item_size; + size_t item_size_with_extra; + _AL_LIST_ITEM* next_free; + void* user_data; + _AL_LIST_DTOR dtor; +}; + +/* List item, holds user data and destructor. */ +struct _AL_LIST_ITEM { + _AL_LIST* list; + _AL_LIST_ITEM* next; + _AL_LIST_ITEM* prev; + void* data; + _AL_LIST_ITEM_DTOR dtor; +}; + + +/* List of the internal functions. */ +static _AL_LIST* list_do_create(size_t capacity, size_t item_extra_size); +static bool list_is_static(_AL_LIST* list); + +static _AL_LIST_ITEM* list_get_free_item(_AL_LIST* list); +static _AL_LIST_ITEM* list_create_item(_AL_LIST* list); +static void list_destroy_item(_AL_LIST* list, _AL_LIST_ITEM* item); + + +/* + * Create an instance of double linked list. + * + * Parameters: + * capacity [in] + * Maximum number of elements list can hold. If it is zero, list is + * created as fully dynamic linked list with unlimited item count. + * For any other positive number static linked list is created, + * memory for all elements is allocated once and then used. + * + * extra_item_size [in] + * Number of extra bytes which should be left after each list item. + * It is currently not used, so default value is zero. + * + * Returns: + * Pointer to new instance of double linked list. + * + * Remarks: + * There are two kind of double linked list supported: dynamic and static. + * For dynamic linked list each item is allocated while adding and freed + * while removing. This kind of list does not have capacity limit but + * suffer from memory allocation delay. + * Static linked list use one memory allocation and are hold as solid + * piece of memory. This kind of list have capacity, but adding and + * removing elements is very cheap operation. + */ +static _AL_LIST* list_do_create(size_t capacity, size_t extra_item_size) +{ + size_t i; + size_t memory_size; + uint8_t* memory_ptr; + _AL_LIST* list = NULL; + _AL_LIST_ITEM* item = NULL; + _AL_LIST_ITEM* prev = NULL; + + + /* Calculate amount of memory needed for the list. + * Always at least one element is allocated together with list, + * which is intended to be a root. + */ + memory_size = sizeof(_AL_LIST) + (capacity + 1) * (sizeof(_AL_LIST_ITEM) + extra_item_size); + + memory_ptr = (uint8_t*)al_malloc(memory_size); + if (NULL == memory_ptr) { + ALLEGRO_ERROR("Out of memory."); + return NULL; + } + + list = (_AL_LIST*)memory_ptr; + memory_ptr += sizeof(_AL_LIST); + list->size = 0; + list->capacity = capacity; + list->item_size = sizeof(_AL_LIST_ITEM); + list->item_size_with_extra = sizeof(_AL_LIST_ITEM) + extra_item_size; + list->next_free = (_AL_LIST_ITEM*)memory_ptr; + list->user_data = NULL; + list->dtor = NULL; + + /* Initialize free item list. + */ + prev = NULL; + item = list->next_free; + for (i = 0; i <= list->capacity; ++i) { + + memory_ptr += list->item_size_with_extra; + item->list = list; + item->next = (_AL_LIST_ITEM*)memory_ptr; + prev = item; + item = item->next; + } + + /* Set proper free list tail value. */ + prev->next = NULL; + + /* Initialize root. */ + list->root = list_get_free_item(list); + list->root->dtor = NULL; + list->root->next = list->root; + list->root->prev = list->root; + + return list; +} + + +/* + * Returns true if 'list' point to static double linked list. + */ +static bool list_is_static(_AL_LIST* list) +{ + return 0 != list->capacity; +} + + +/* + * Returns free item from internal list. Call to this function + * is valid only for static lists. + */ +static _AL_LIST_ITEM* list_get_free_item(_AL_LIST* list) +{ + _AL_LIST_ITEM* item; + + //thedmd: disabled, root is always static-like element and this method + // is called even for dynamic lists + //ASSERT(list_is_static(list)); + + item = list->next_free; + if (NULL != item) + list->next_free = item->next; + + return item; +} + + +/* + * Create an instance of new double linked list item. + */ +static _AL_LIST_ITEM* list_create_item(_AL_LIST* list) +{ + _AL_LIST_ITEM* item = NULL; + + if (list_is_static(list)) { + + /* Items from internal list already are partially initialized. + * So we do not have to setup list pointer. + */ + item = list_get_free_item(list); + } + else { + + item = (_AL_LIST_ITEM*)al_malloc(list->item_size_with_extra); + + item->list = list; + } + + return item; +} + + +/* + * Destroys double linked list item. Item destructor is called + * when necessary. + */ +static void list_destroy_item(_AL_LIST* list, _AL_LIST_ITEM* item) +{ + ASSERT(list == item->list); + + if (NULL != item->dtor) + item->dtor(item->data, list->user_data); + + if (list_is_static(list)) { + item->next = list->next_free; + list->next_free = item; + } + else + al_free(item); +} + + +/* + * Create new instance of dynamic double linked list. + * + * See: + * list_do_create + */ +_AL_LIST* _al_list_create(void) +{ + return list_do_create(0, 0); +} + + +/* + * Create new instance of list item. Maximum number of list items is + * limited by capacity. + * + * See: + * list_do_create + */ +_AL_LIST* _al_list_create_static(size_t capacity) +{ + if (capacity < 1) { + + ALLEGRO_ERROR("Cannot create static list without any capacity."); + return NULL; + } + + return list_do_create(capacity, 0); +} + + +/* + * Destroys instance of the list. All elements + * that list contain are also destroyed. + */ +void _al_list_destroy(_AL_LIST* list) +{ + if (NULL == list) + return; + + if (list->dtor) + list->dtor(list->user_data); + + _al_list_clear(list); + + al_free(list); +} + + +/* + * Sets a destructor for the list. + */ +void _al_list_set_dtor(_AL_LIST* list, _AL_LIST_DTOR dtor) +{ + list->dtor = dtor; +} + + +/* + * Returns destructor of the list. + */ +_AL_LIST_DTOR _al_list_get_dtor(_AL_LIST* list) +{ + return list->dtor; +} + + +/* + * Create and push new item at the beginning of the list. + * + * Returns pointer to new item. + */ +_AL_LIST_ITEM* _al_list_push_front(_AL_LIST* list, void* data) +{ + return _al_list_insert_after(list, list->root, data); +} + + +/* + * Pretty the same as _al_list_push_front(), but also allow + * to provide custom destructor for the item. + */ +_AL_LIST_ITEM* _al_list_push_front_ex(_AL_LIST* list, void* data, _AL_LIST_ITEM_DTOR dtor) +{ + return _al_list_insert_after_ex(list, list->root, data, dtor); +} + + +/* + * Create and push new item at the end of the list. + * + * Returns pointer to new item. + */ +_AL_LIST_ITEM* _al_list_push_back(_AL_LIST* list, void* data) +{ + return _al_list_insert_before(list, list->root, data); +} + + +/* + * Pretty the same as _al_list_push_back(), but also allow + * to provide custom destructor for the item. + */ +_AL_LIST_ITEM* _al_list_push_back_ex(_AL_LIST* list, void* data, _AL_LIST_ITEM_DTOR dtor) +{ + return _al_list_insert_before_ex(list, list->root, data, dtor); +} + + +/* + * Remove first item in the list. + */ +void _al_list_pop_front(_AL_LIST* list) +{ + if (list->size > 0) + _al_list_erase(list, list->root->next); +} + + +/* + * Remove last item in the list. + */ +void _al_list_pop_back(_AL_LIST* list) +{ + if (list->size > 0) + _al_list_erase(list, list->root->prev); +} + + +/* + * Create and insert new item after one specified by 'where'. + * + * Returns pointer to new item. + */ +_AL_LIST_ITEM* _al_list_insert_after(_AL_LIST* list, _AL_LIST_ITEM* where, void* data) +{ + return _al_list_insert_after_ex(list, where, data, NULL); +} + + +/* + * Pretty the same as _al_list_insert_after(), but also allow + * to provide custom destructor for the item. + */ +_AL_LIST_ITEM* _al_list_insert_after_ex(_AL_LIST* list, _AL_LIST_ITEM* where, void* data, _AL_LIST_ITEM_DTOR dtor) +{ + _AL_LIST_ITEM* item; + + ASSERT(list == where->list); + + item = list_create_item(list); + if (NULL == item) + return NULL; + + item->data = data; + item->dtor = dtor; + + item->prev = where; + item->next = where->next; + + where->next->prev = item; + where->next = item; + + list->size++; + + return item; +} + + +/* + * Create and insert new item before one specified by 'where'. + * + * Returns pointer to new item. + */ +_AL_LIST_ITEM* _al_list_insert_before(_AL_LIST* list, _AL_LIST_ITEM* where, void* data) +{ + return _al_list_insert_before_ex(list, where, data, NULL); +} + + +/* + * Pretty the same as _al_list_insert_before(), but also allow + * to provide custom destructor for the item. + */ +_AL_LIST_ITEM* _al_list_insert_before_ex(_AL_LIST* list, _AL_LIST_ITEM* where, void* data, _AL_LIST_ITEM_DTOR dtor) +{ + _AL_LIST_ITEM* item; + + ASSERT(list == where->list); + + item = list_create_item(list); + if (NULL == item) + return NULL; + + item->data = data; + item->dtor = dtor; + + item->next = where; + item->prev = where->prev; + + where->prev->next = item; + where->prev = item; + + list->size++; + + return item; +} + + +/* + * Remove specified item from the list. + */ +void _al_list_erase(_AL_LIST* list, _AL_LIST_ITEM* item) +{ + if (NULL == item) + return; + + ASSERT(list == item->list); + + item->prev->next = item->next; + item->next->prev = item->prev; + + list->size--; + + list_destroy_item(list, item); +} + + +/* + * Remove all items from the list. + */ +void _al_list_clear(_AL_LIST* list) +{ + _AL_LIST_ITEM* item; + _AL_LIST_ITEM* next; + + item = _al_list_front(list); + + while (NULL != item) { + + next = _al_list_next(list, item); + + _al_list_erase(list, item); + + item = next; + } +} + + +/* + * Remove all occurrences of specified value in the list. + */ +void _al_list_remove(_AL_LIST* list, void* data) +{ + _AL_LIST_ITEM* item = NULL; + _AL_LIST_ITEM* next = NULL; + + item = _al_list_find_first(list, data); + + while (NULL != item) { + + next = _al_list_find_after(list, item, data); + + _al_list_erase(list, item); + + item = next; + } +} + + +/* + * Returns true if list is empty. + */ +bool _al_list_is_empty(_AL_LIST* list) +{ + return 0 == list->size; +} + + +/* + * Returns true if list contain specified value. + */ +bool _al_list_contains(_AL_LIST* list, void* data) +{ + return NULL != _al_list_find_first(list, data); +} + + +/* + * Returns first occurrence of specified value in the list. + */ +_AL_LIST_ITEM* _al_list_find_first(_AL_LIST* list, void* data) +{ + return _al_list_find_after(list, list->root, data); +} + + +/* + * Returns last occurrence of specified value in the list. + */ +_AL_LIST_ITEM* _al_list_find_last(_AL_LIST* list, void* data) +{ + return _al_list_find_before(list, list->root, data); +} + + +/* + * Return occurrence of specified value in the list after 'where' item. + */ +_AL_LIST_ITEM* _al_list_find_after(_AL_LIST* list, _AL_LIST_ITEM* where, void* data) +{ + _AL_LIST_ITEM* item; + + ASSERT(list == where->list); + + for (item = where->next; item != list->root; item = item->next) + if (item->data == data) + return item; + + return NULL; +} + + +/* + * Return occurrence of specified value in the list before 'where' item. + */ +_AL_LIST_ITEM* _al_list_find_before(_AL_LIST* list, _AL_LIST_ITEM* where, void* data) +{ + _AL_LIST_ITEM* item; + + ASSERT(list == where->list); + + for (item = where->prev; item != list->root; item = item->prev) + if (item->data == data) + return item; + + return NULL; +} + + +/* + * Returns current size of the list. + */ +size_t _al_list_size(_AL_LIST* list) +{ + return list->size; +} + + +/* + * Returns item located at specified index. + */ +_AL_LIST_ITEM* _al_list_at(_AL_LIST* list, size_t index) +{ + if (index >= list->size) + return NULL; + + if (index < list->size / 2) { + + _AL_LIST_ITEM* item = list->root->next; + + while (index--) + item = item->next; + + return item; + } + else { + + _AL_LIST_ITEM* item = list->root->prev; + + index = list->size - index; + + while (index--) + item = item->prev; + + return item; + } +} + + +/* + * Returns first item in the list. + */ +_AL_LIST_ITEM* _al_list_front(_AL_LIST* list) +{ + if (list->size > 0) + return list->root->next; + else + return NULL; +} + + +/* + * Returns last item in the list. + */ +_AL_LIST_ITEM* _al_list_back(_AL_LIST* list) +{ + if (list->size > 0) + return list->root->prev; + else + return NULL; +} + + +/* + * Returns next element in the list. + */ +_AL_LIST_ITEM* _al_list_next(_AL_LIST* list, _AL_LIST_ITEM* item) +{ + ASSERT(list == item->list); + (void)list; + + if (item->next != item->list->root) + return item->next; + else + return NULL; +} + + +/* + * Returns previous element in the list. + */ +_AL_LIST_ITEM* _al_list_previous(_AL_LIST* list, _AL_LIST_ITEM* item) +{ + ASSERT(list == item->list); + (void)list; + + if (item->prev != item->list->root) + return item->prev; + else + return NULL; +} + + +/* + * Returns next element in the list. If end of the list is reached, + * first element is returned instead of NULL. + */ +_AL_LIST_ITEM* _al_list_next_circular(_AL_LIST* list, _AL_LIST_ITEM* item) +{ + ASSERT(list == item->list); + + if (item->next != item->list->root) + return item->next; + else + return list->root->next; +} + + +/* + * Returns previous element in the list. If beginning of the list is reached, + * last element is returned instead of NULL. + */ +_AL_LIST_ITEM* _al_list_previous_circular(_AL_LIST* list, _AL_LIST_ITEM* item) +{ + ASSERT(list == item->list); + + if (item->prev != item->list->root) + return item->prev; + else + return list->root->prev; +} + + +/* + * Returns value associated with specified item. + */ +void* _al_list_item_data(_AL_LIST_ITEM* item) +{ + return item->data; +} + + +/* + * Sets item destructor. + */ +void _al_list_item_set_dtor(_AL_LIST_ITEM* item, _AL_LIST_ITEM_DTOR dtor) +{ + item->dtor = dtor; +} + + +/* + * Returns item destructor. + */ +_AL_LIST_ITEM_DTOR _al_list_item_get_dtor(_AL_LIST_ITEM* item) +{ + return item->dtor; +} + + +/* + * Sets user data for list. This pointer is passed to list destructor. + */ +void _al_list_set_user_data(_AL_LIST* list, void* user_data) +{ + list->user_data = user_data; +} + + +/* + * Returns user data for list. + */ +void* _al_list_get_user_data(_AL_LIST* list) +{ + return list->user_data; +} diff --git a/allegro/src/misc/vector.c b/allegro/src/misc/vector.c new file mode 100644 index 00000000..b974cffe --- /dev/null +++ b/allegro/src/misc/vector.c @@ -0,0 +1,362 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Vectors, aka growing arrays. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + * + * + * This is a simple growing array to hold objects of various sizes, + * growing by powers of two as needed. At the moment the vector never + * shrinks, except when it is freed. Usually the vector would hold + * pointers to objects, not the objects themselves, as the vector is + * allowed to move the objects around. + * + * This module is NOT thread-safe. + */ + +/* Internal Title: Vectors + */ + + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_vector.h" + + +/* return the given item's starting address in the vector */ +#define ITEM_START(vec, idx) (vec->_items + ((idx) * vec->_itemsize)) + + + +/* Internal function: _al_vector_init + * + * Initialise a vector. ITEMSIZE is the number of bytes to allocate for + * each item in the vector. + * + * Alternatively, you can statically initialise a vector using + * _AL_VECTOR vec = _AL_VECTOR_INITIALIZER(itemtype); + */ +void _al_vector_init(_AL_VECTOR *vec, size_t itemsize) +{ + ASSERT(vec); + ASSERT(itemsize > 0); + + vec->_itemsize = itemsize; + vec->_items = NULL; + vec->_size = 0; + vec->_unused = 0; +} + + + +/* + * Simple inline functions: + * + * size_t _al_vector_size(const _AL_VECTOR *vec); + * bool _al_vector_is_empty(const _AL_VECTOR*); + */ + + + +/* Internal function: _al_vector_ref + * + * Return a pointer to the SLOT in the vector given by INDEX. The returned + * address should only be used while the vector is not modified; after that + * it is invalid. + * + * Tip: If you are storing pointers in the vector, you need to dereference + * the returned value! + */ +void *_al_vector_ref(const _AL_VECTOR *vec, unsigned int idx) +{ + ASSERT(vec); + ASSERT(idx < vec->_size); + + return ITEM_START(vec, idx); +} + + + +/* Internal function: _al_vector_ref_front + * Convenience function. + */ +void* _al_vector_ref_front(const _AL_VECTOR *vec) +{ + return _al_vector_ref(vec, 0); +} + + + +/* Internal function: _al_vector_ref_back + * Convenience function. + */ +void* _al_vector_ref_back(const _AL_VECTOR *vec) +{ + ASSERT(vec); + + return _al_vector_ref(vec, vec->_size-1); +} + + + +/* Internal function: _al_vector_append_array + * Append `num` elements from `arr` array to _AL_VECTOR `vec` + */ +bool _al_vector_append_array(_AL_VECTOR *vec, unsigned int num, const void *arr) +{ + ASSERT(vec); + ASSERT(arr); + ASSERT(num); + + if (vec->_items == NULL) { + ASSERT(vec->_size == 0); + ASSERT(vec->_unused == 0); + + vec->_items = al_malloc(vec->_itemsize * num); + ASSERT(vec->_items); + if (!vec->_items) + return false; + + vec->_unused = num; + } + else if (vec->_unused < num) { + char *new_items; + new_items = al_realloc(vec->_items, (vec->_size + num) * vec->_itemsize); + ASSERT(new_items); + if (!new_items) + return false; + + vec->_items = new_items; + vec->_unused = num; + } + + memcpy(vec->_items + (vec->_size * vec->_itemsize), + arr, vec->_itemsize * num); + + vec->_size += num; + vec->_unused -= num; + + return true; +} + + + +/* Internal function: _al_vector_alloc_back + * + * Allocate a block of memory at the back of the vector of the vector's item + * size (see _AL_VECTOR_INITIALIZER and _al_vector_init). Returns a pointer + * to the start of this block. This address should only be used while the + * vector is not modified; after that it is invalid. You may fill the block + * with whatever you want. + * + * Example: + * _AL_VECTOR vec = _AL_VECTOR_INITIALIZER(struct boo); + * struct boo *thing = _al_vector_alloc_back(&vec); + * thing->aaa = 100; + * thing->bbb = "a string"; + */ +void* _al_vector_alloc_back(_AL_VECTOR *vec) +{ + ASSERT(vec); + ASSERT(vec->_itemsize > 0); + { + if (vec->_items == NULL) { + ASSERT(vec->_size == 0); + ASSERT(vec->_unused == 0); + + vec->_items = al_malloc(vec->_itemsize); + ASSERT(vec->_items); + if (!vec->_items) + return NULL; + + vec->_unused = 1; + } + else if (vec->_unused == 0) { + char *new_items = al_realloc(vec->_items, 2 * vec->_size * vec->_itemsize); + ASSERT(new_items); + if (!new_items) + return NULL; + + vec->_items = new_items; + vec->_unused = vec->_size; + } + + vec->_size++; + vec->_unused--; + + return ITEM_START(vec, vec->_size-1); + } +} + + + +/* Internal function: _al_vector_alloc_mid + * + * Allocate a block of memory in the middle of the vector of the vector's + * item + * size (see _AL_VECTOR_INITIALIZER and _al_vector_init). Returns a pointer + * to the start of this block. This address should only be used while the + * vector is not modified; after that it is invalid. You may fill the block + * with whatever you want. + */ +void* _al_vector_alloc_mid(_AL_VECTOR *vec, unsigned int index) +{ + ASSERT(vec); + ASSERT(vec->_itemsize > 0); + { + if (vec->_items == NULL) { + ASSERT(index == 0); + return _al_vector_alloc_back(vec); + } + + if (vec->_unused == 0) { + char *new_items = al_realloc(vec->_items, 2 * vec->_size * vec->_itemsize); + ASSERT(new_items); + if (!new_items) + return NULL; + + vec->_items = new_items; + vec->_unused = vec->_size; + } + + memmove(ITEM_START(vec, index + 1), ITEM_START(vec, index), + vec->_itemsize * (vec->_size - index)); + + vec->_size++; + vec->_unused--; + + return ITEM_START(vec, index); + } +} + + + +/* Internal function: _al_vector_find + * + * Find the slot in the vector where the contents of the slot + * match whatever PTR_ITEM points to, bit-for-bit. If no such + * slot is found, a negative number is returned (currently -1). + */ +int _al_vector_find(const _AL_VECTOR *vec, const void *ptr_item) +{ + ASSERT(vec); + ASSERT(ptr_item); + + if (vec->_itemsize == sizeof(void *)) { + /* fast path for pointers */ + void **items = (void **)vec->_items; + unsigned int i; + + for (i = 0; i < vec->_size; i++) + if (items[i] == *(void **)ptr_item) + return i; + } + else { + /* slow path */ + unsigned int i; + for (i = 0; i < vec->_size; i++) + if (memcmp(ITEM_START(vec, i), ptr_item, vec->_itemsize) == 0) + return i; + } + + return -1; +} + + + +/* Internal function: _al_vector_contains + * A simple wrapper over _al_vector_find. + */ +bool _al_vector_contains(const _AL_VECTOR *vec, const void *ptr_item) +{ + return _al_vector_find(vec, ptr_item) >= 0; +} + + + +/* Internal function: _al_vector_delete_at + * + * Delete the slot given by index. Deleting from the start or middle of the + * vector requires moving the rest of the vector towards the front, so it is + * better to delete from the tail of the vector. + * + * Example: + * while (!_al_vector_is_empty(&v)) + * _al_vector_delete_at(&v, _al_vector_size(&v)-1); + */ +void _al_vector_delete_at(_AL_VECTOR *vec, unsigned int idx) +{ + ASSERT(vec); + ASSERT(idx < vec->_size); + { + int to_move = vec->_size - idx - 1; + if (to_move > 0) + memmove(ITEM_START(vec, idx), + ITEM_START(vec, idx+1), + to_move * vec->_itemsize); + vec->_size--; + vec->_unused++; + memset(ITEM_START(vec, vec->_size), 0, vec->_itemsize); + } +} + + + +/* Internal function: _al_vector_find_and_delete + * + * Similar to _al_vector_delete_at(_al_vector_find(vec, ptr_item)) but is + * lenient if the item is not found. Returns true if the item was found and + * deleted. + */ +bool _al_vector_find_and_delete(_AL_VECTOR *vec, const void *ptr_item) +{ + int idx = _al_vector_find(vec, ptr_item); + if (idx >= 0) { + _al_vector_delete_at(vec, idx); + return true; + } + else + return false; +} + + + +/* Internal function: _al_vector_free + * + * Free the space used by the vector. You really must do this at some + * stage. It is not enough to delete all the items in the vector (which you + * should usually do also). + */ +void _al_vector_free(_AL_VECTOR *vec) +{ + ASSERT(vec); + + if (vec->_items != NULL) { + al_free(vec->_items); + vec->_items = NULL; + } + vec->_size = 0; + vec->_unused = 0; +} + + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/src/monitor.c b/allegro/src/monitor.c new file mode 100644 index 00000000..39a987f9 --- /dev/null +++ b/allegro/src/monitor.c @@ -0,0 +1,81 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Monitor queries. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" + + +/* Function: al_get_num_video_adapters + */ +int al_get_num_video_adapters(void) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + + if (system && system->vt && system->vt->get_num_video_adapters) { + return system->vt->get_num_video_adapters(); + } + + return 0; +} + +/* Function: al_get_monitor_refresh_rate + */ +int al_get_monitor_refresh_rate(int adapter) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + + if (adapter < al_get_num_video_adapters()) { + if (system && system->vt && system->vt->get_monitor_refresh_rate) { + return system->vt->get_monitor_refresh_rate(adapter); + } + } + + return 0; +} + + +/* Function: al_get_monitor_info + */ +bool al_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + + if (adapter < al_get_num_video_adapters()) { + if (system && system->vt && system->vt->get_monitor_info) { + return system->vt->get_monitor_info(adapter, info); + } + } + + info->x1 = info->y1 = info->x2 = info->y2 = INT_MAX; + return false; +} + +/* Function: al_get_monitor_dpi + */ +int al_get_monitor_dpi(int adapter) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + + if (adapter < al_get_num_video_adapters()) { + if (system && system->vt && system->vt->get_monitor_dpi) { + return system->vt->get_monitor_dpi(adapter); + } + } + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/mouse_cursor.c b/allegro/src/mouse_cursor.c new file mode 100644 index 00000000..ed256a81 --- /dev/null +++ b/allegro/src/mouse_cursor.c @@ -0,0 +1,120 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Mouse cursors. + * + * See LICENSE.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_system.h" + + +/* Function: al_create_mouse_cursor + */ +ALLEGRO_MOUSE_CURSOR *al_create_mouse_cursor(ALLEGRO_BITMAP *bmp, + int x_focus, int y_focus) +{ + ALLEGRO_SYSTEM *sysdrv = al_get_system_driver(); + ASSERT(bmp); + + ASSERT(sysdrv->vt->create_mouse_cursor); + return sysdrv->vt->create_mouse_cursor(bmp, x_focus, y_focus); +} + + +/* Function: al_destroy_mouse_cursor + */ +void al_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) +{ + ALLEGRO_SYSTEM *sysdrv; + + if (!cursor) { + return; + } + + sysdrv = al_get_system_driver(); + + ASSERT(sysdrv->vt->destroy_mouse_cursor); + sysdrv->vt->destroy_mouse_cursor(cursor); +} + + +/* Function: al_set_mouse_cursor + */ +bool al_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) +{ + if (!cursor) { + return false; + } + + if (display) { + ASSERT(display->vt->set_mouse_cursor); + return display->vt->set_mouse_cursor(display, cursor); + } + + return false; +} + + +/* Function: al_set_system_mouse_cursor + */ +bool al_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +{ + /* XXX should you be able to set ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE? */ + ASSERT(cursor_id > ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE); + ASSERT(cursor_id < ALLEGRO_NUM_SYSTEM_MOUSE_CURSORS); + ASSERT(display); + + if (cursor_id <= ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE) { + return false; + } + if (cursor_id > ALLEGRO_NUM_SYSTEM_MOUSE_CURSORS) { + return false; + } + if (!display) { + return false; + } + + ASSERT(display->vt->set_system_mouse_cursor); + return display->vt->set_system_mouse_cursor(display, cursor_id); +} + + +/* Function: al_show_mouse_cursor + */ +bool al_show_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + if (display) { + ASSERT(display->vt->show_mouse_cursor); + return display->vt->show_mouse_cursor(display); + } + + return false; +} + + +/* Function: al_hide_mouse_cursor + */ +bool al_hide_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + if (display) { + ASSERT(display->vt->hide_mouse_cursor); + return display->vt->hide_mouse_cursor(display); + } + + return false; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/mousenu.c b/allegro/src/mousenu.c new file mode 100644 index 00000000..f10e1b79 --- /dev/null +++ b/allegro/src/mousenu.c @@ -0,0 +1,336 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New mouse API. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +/* Title: Mouse routines + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/internal/aintern_system.h" + + + +/* the active keyboard driver */ +static ALLEGRO_MOUSE_DRIVER *new_mouse_driver = NULL; + + + +/* Function: al_is_mouse_installed + */ +bool al_is_mouse_installed(void) +{ + return (new_mouse_driver ? true : false); +} + + + +/* Function: al_install_mouse + */ +bool al_install_mouse(void) +{ + if (new_mouse_driver) + return true; + + //FIXME: seems A4/A5 driver list stuff doesn't quite agree right now + if (al_get_system_driver()->vt->get_mouse_driver) { + new_mouse_driver = al_get_system_driver()->vt->get_mouse_driver(); + if (!new_mouse_driver->init_mouse()) { + new_mouse_driver = NULL; + return false; + } + _al_add_exit_func(al_uninstall_mouse, "al_uninstall_mouse"); + return true; + } + + + return false; +#if 0 + + if (system_driver && system_driver->mouse_drivers) + driver_list = system_driver->mouse_drivers(); + else + driver_list = _al_mouse_driver_list; + + ASSERT(driver_list); + + for (i=0; driver_list[i].driver; i++) { + new_mouse_driver = driver_list[i].driver; + //name = get_config_text(new_mouse_driver->msedrv_ascii_name); + name = new_mouse_driver->msedrv_ascii_name; + new_mouse_driver->msedrv_name = name; + new_mouse_driver->msedrv_desc = name; + if (new_mouse_driver->init_mouse()) { + break; + } + } + + if (!driver_list[i].driver) { + new_mouse_driver = NULL; + return false; + } + _al_add_exit_func(al_uninstall_mouse, "al_uninstall_mouse"); + + + return true; +#endif + +} + + + + +/* Function: al_uninstall_mouse + */ +void al_uninstall_mouse(void) +{ + if (!new_mouse_driver) + return; + + new_mouse_driver->exit_mouse(); + new_mouse_driver = NULL; +} + + + +/* This was in the public API but its only purpose is now served by + * al_get_mouse_event_source(). + */ +static ALLEGRO_MOUSE *al_get_mouse(void) +{ + ALLEGRO_MOUSE *mse; + + ASSERT(new_mouse_driver); + + mse = new_mouse_driver->get_mouse(); + ASSERT(mse); + + return mse; +} + + + +/* Function: al_get_mouse_num_buttons + */ +unsigned int al_get_mouse_num_buttons(void) +{ + ASSERT(new_mouse_driver); + + return new_mouse_driver->get_mouse_num_buttons(); +} + + + +/* Function: al_get_mouse_num_axes + */ +unsigned int al_get_mouse_num_axes(void) +{ + ASSERT(new_mouse_driver); + + return new_mouse_driver->get_mouse_num_axes(); +} + + + +/* Function: al_set_mouse_xy + */ +bool al_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) +{ + ASSERT(new_mouse_driver); + ASSERT(new_mouse_driver->set_mouse_xy); + + return new_mouse_driver->set_mouse_xy(display, x, y); +} + + + +/* Function: al_set_mouse_z + */ +bool al_set_mouse_z(int z) +{ + ASSERT(new_mouse_driver); + ASSERT(new_mouse_driver->set_mouse_axis); + + return new_mouse_driver->set_mouse_axis(2, z); +} + + + +/* Function: al_set_mouse_w + */ +bool al_set_mouse_w(int w) +{ + ASSERT(new_mouse_driver); + ASSERT(new_mouse_driver->set_mouse_axis); + + return new_mouse_driver->set_mouse_axis(3, w); +} + + + +/* Function: al_set_mouse_axis + */ +bool al_set_mouse_axis(int which, int value) +{ + ASSERT(new_mouse_driver); + ASSERT(new_mouse_driver->set_mouse_axis); + ASSERT(which >= 2); + ASSERT(which < 4 + ALLEGRO_MOUSE_MAX_EXTRA_AXES); + + if (which >= 2 && which < 4 + ALLEGRO_MOUSE_MAX_EXTRA_AXES) + return new_mouse_driver->set_mouse_axis(which, value); + else + return false; +} + + + +/* Function: al_get_mouse_state + */ +void al_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + ASSERT(new_mouse_driver); + ASSERT(ret_state); + + new_mouse_driver->get_mouse_state(ret_state); +} + + + +/* Function: al_get_mouse_state_axis + */ +int al_get_mouse_state_axis(const ALLEGRO_MOUSE_STATE *state, int axis) +{ + ASSERT(state); + ASSERT(axis >= 0); + ASSERT(axis < (4 + ALLEGRO_MOUSE_MAX_EXTRA_AXES)); + + switch (axis) { + case 0: + return state->x; + case 1: + return state->y; + case 2: + return state->z; + case 3: + return state->w; + default: + return state->more_axes[axis - 4]; + } +} + + + +/* Function: al_mouse_button_down + */ +bool al_mouse_button_down(const ALLEGRO_MOUSE_STATE *state, int button) +{ + ASSERT(state); + ASSERT(button > 0); + + return (state->buttons & (1 << (button-1))); +} + + + +/* Function: al_get_mouse_cursor_position + */ +bool al_get_mouse_cursor_position(int *ret_x, int *ret_y) +{ + ALLEGRO_SYSTEM *alsys = al_get_system_driver(); + ASSERT(ret_x); + ASSERT(ret_y); + + if (alsys->vt->get_cursor_position) { + return alsys->vt->get_cursor_position(ret_x, ret_y); + } + else { + *ret_x = 0; + *ret_y = 0; + return false; + } +} + + + +/* Function: al_grab_mouse + */ +bool al_grab_mouse(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_SYSTEM *alsys = al_get_system_driver(); + + if (alsys->vt->grab_mouse) + return alsys->vt->grab_mouse(display); + + return false; +} + + + +/* Function: al_ungrab_mouse + */ +bool al_ungrab_mouse(void) +{ + ALLEGRO_SYSTEM *alsys = al_get_system_driver(); + + if (alsys->vt->ungrab_mouse) + return alsys->vt->ungrab_mouse(); + + return false; +} + + + +/* Function: al_get_mouse_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_mouse_event_source(void) +{ + ALLEGRO_MOUSE *mouse = al_get_mouse(); + + return (mouse) ? &mouse->es : NULL; +} + + + +/* Function: al_set_mouse_wheel_precision + */ +void al_set_mouse_wheel_precision(int precision) +{ + ALLEGRO_SYSTEM *alsys = al_get_system_driver(); + ASSERT(alsys); + if (precision < 1) + precision = 1; + alsys->mouse_wheel_precision = precision; +} + + + +/* Function: al_get_mouse_wheel_precision + */ +int al_get_mouse_wheel_precision(void) +{ + ALLEGRO_SYSTEM *alsys = al_get_system_driver(); + ASSERT(alsys); + return alsys->mouse_wheel_precision; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/extensions.c b/allegro/src/opengl/extensions.c new file mode 100644 index 00000000..c9d369ac --- /dev/null +++ b/allegro/src/opengl/extensions.c @@ -0,0 +1,951 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL extensions management subsystem + * + * By Elias Pschernig and Milan Mimica. + * + * Based on AllegroGL extensions management. + */ + +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/opengl/gl_ext.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_system.h" + +/* We need some driver specific details not worth of a vtable entry. */ +#if defined ALLEGRO_WINDOWS + #include "../win/wgl.h" +#elif defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX + #include "allegro5/internal/aintern_xdisplay.h" + #include "allegro5/internal/aintern_xsystem.h" +#endif + +#if defined ALLEGRO_MACOSX +#include +#elif !defined ALLEGRO_CFG_OPENGLES +#include +#endif + +ALLEGRO_DEBUG_CHANNEL("opengl") + + +#ifdef ALLEGRO_HAVE_DYNAMIC_LINK + #include + /* Handle for dynamic library libGL.so */ + static void *__libgl_handle = NULL; + /* Pointer to glXGetProcAddressARB */ + typedef void *(*GLXGETPROCADDRESSARBPROC) (const GLubyte *); + static GLXGETPROCADDRESSARBPROC alXGetProcAddress; +#else /* #ifdef ALLEGRO_HAVE_DYNAMIC_LINK */ + /* Tries static linking */ + /* FIXME: set ALLEGRO_GLXGETPROCADDRESSARB on configure time, if + * glXGetProcAddressARB must be used! + */ + #if defined ALLEGRO_GLXGETPROCADDRESSARB + #define alXGetProcAddress glXGetProcAddressARB + #elif defined ALLEGRO_RASPBERRYPI + #define alXGetProcAddress eglGetProcAddress + #else + #define alXGetProcAddress glXGetProcAddress + #endif +#endif /* #ifdef ALLEGRO_HAVE_DYNAMIC_LINK */ + + +#ifdef ALLEGRO_MACOSX + #include + static CFBundleRef opengl_bundle_ref; +#endif + + +/* Define the GL API pointers. + * Example: + * _ALLEGRO_glBlendEquation_t _al_glBlendEquation = NULL; + */ +#define AGL_API(type, name, args) _ALLEGRO_gl##name##_t _al_gl##name = NULL; +# include "allegro5/opengl/GLext/gl_ext_api.h" +#undef AGL_API +#ifdef ALLEGRO_WINDOWS +#define AGL_API(type, name, args) _ALLEGRO_wgl##name##_t _al_wgl##name = NULL; +# include "allegro5/opengl/GLext/wgl_ext_api.h" +#undef AGL_API +#elif defined ALLEGRO_UNIX +#define AGL_API(type, name, args) _ALLEGRO_glX##name##_t _al_glX##name = NULL; +# include "allegro5/opengl/GLext/glx_ext_api.h" +#undef AGL_API +#endif + + + +static uint32_t parse_opengl_version(const char *s) +{ + char *p = (char *) s; + int v[4] = {0, 0, 0, 0}; + int n; + uint32_t ver; + + /* For OpenGL ES version strings have the form: + * "OpenGL ES- ." + * So for example: "OpenGL ES-CM 2.0". We simply skip any non-digit + * characters and then parse it like for normal OpenGL. + */ + while (*p && !isdigit(*p)) { + p++; + } + + /* e.g. "4.0.0 Vendor blah blah" */ + for (n = 0; n < 4; n++) { + char *end; + long l; + + errno = 0; + l = strtol(p, &end, 10); + if (errno) + break; + v[n] = _ALLEGRO_CLAMP(0, l, 255); + if (*end != '.') + break; + p = end + 1; /* skip dot */ + } + + ver = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3]; + ALLEGRO_DEBUG("Parsed '%s' as 0x%08x\n", s, ver); + return ver; +} + + + +/* Reads version info out of glGetString(GL_VERSION) */ +static uint32_t _al_ogl_version(void) +{ + char const *value = al_get_config_value(al_get_system_config(), "opengl", + "force_opengl_version"); + if (value) { + uint32_t v = parse_opengl_version(value); + ALLEGRO_INFO("OpenGL version forced to %d.%d.%d.%d.\n", + (v >> 24) & 0xff, + (v >> 16) & 0xff, + (v >> 8) & 0xff, + (v & 0xff)); + return v; + } + + const char *str; + + str = (const char *)glGetString(GL_VERSION); + if (str) { + #ifdef ALLEGRO_CFG_OPENGLES + char *str2 = strstr(str, "ES "); + if (str2) + str = str2 + 3; + #endif + return parse_opengl_version(str); + } + else { + /* The OpenGL driver does not return a version + * number. However it probably supports at least OpenGL 1.0 + */ + return _ALLEGRO_OPENGL_VERSION_1_0; + } + +} + + + +/* print_extensions: + * Given a string containing extensions (i.e. a NULL terminated string where + * each extension are separated by a space and which names do not contain any + * space) + */ +static void print_extensions(char const *extension) +{ + char buf[80]; + char *start; + ASSERT(extension); + + while (*extension != '\0') { + start = buf; + _al_sane_strncpy(buf, extension, 80); + while ((*start != ' ') && (*start != '\0')) { + extension++; + start++; + } + *start = '\0'; + if (*extension != '\0') + extension++; + ALLEGRO_DEBUG("%s\n", buf); + } +} + + + +#if !defined ALLEGRO_CFG_OPENGLES +/* Print all extensions the OpenGL 3.0 way. */ +static void print_extensions_3_0(void) +{ + int i; + GLint n; + GLubyte const *name; + glGetIntegerv(GL_NUM_EXTENSIONS, &n); + for (i = 0; i < n; i++) { + name = glGetStringi(GL_EXTENSIONS, i); + ALLEGRO_DEBUG("%s\n", name); + } +} +#endif + + + +/* Function: al_get_opengl_version + */ +uint32_t al_get_opengl_version(void) +{ + ALLEGRO_DISPLAY *ogl_disp; + + ogl_disp = al_get_current_display(); + if (!ogl_disp || !ogl_disp->ogl_extras) + return 0x0; + + return ogl_disp->ogl_extras->ogl_info.version; +} + + +/* NOTE: al_get_opengl_variant is pretty simple right now but may + * eventually need driver support. + */ + +/* Function: al_get_opengl_variant + */ +int al_get_opengl_variant(void) +{ +#if defined ALLEGRO_CFG_OPENGLES + return ALLEGRO_OPENGL_ES; +#else + return ALLEGRO_DESKTOP_OPENGL; +#endif +} + +/* Create the extension list */ +static ALLEGRO_OGL_EXT_LIST *create_extension_list(void) +{ + ALLEGRO_OGL_EXT_LIST *ret = al_calloc(1, sizeof(ALLEGRO_OGL_EXT_LIST)); + + if (!ret) { + return NULL; + } + + return ret; +} + + + +/* Create the extension API table */ +static ALLEGRO_OGL_EXT_API *create_extension_api_table(void) +{ + ALLEGRO_OGL_EXT_API *ret = al_calloc(1, sizeof(ALLEGRO_OGL_EXT_API)); + + if (!ret) { + return NULL; + } + + return ret; +} + + + +typedef void (*VOID_FPTR)(void); +/* GCC 4.8.2 and possibly others are really slow at optimizing the 100's of the + * if statements in the load_extensions function below, so we extract them to + * this function. + */ +static VOID_FPTR load_extension(const char* name) +{ + VOID_FPTR fptr = NULL; +#ifdef ALLEGRO_WINDOWS + fptr = (VOID_FPTR)wglGetProcAddress(name); +#elif defined ALLEGRO_UNIX + fptr = (VOID_FPTR)alXGetProcAddress((const GLubyte*)name); +#elif defined ALLEGRO_MACOSX + CFStringRef cfstr = CFStringCreateWithCStringNoCopy(NULL, name, + kCFStringEncodingUTF8, kCFAllocatorNull); + if (cfstr) { + fptr = (VOID_FPTR)CFBundleGetFunctionPointerForName(opengl_bundle_ref, cfstr); + CFRelease(cfstr); + } +#elif defined ALLEGRO_SDL + fptr = SDL_GL_GetProcAddress(name); +#endif + if (fptr) { + ALLEGRO_DEBUG("%s successfully loaded (%p)\n", name, fptr); + } + return fptr; +} + + + +/* Load the extension API addresses into the table. + * Should only be done on context creation. + */ +static void load_extensions(ALLEGRO_OGL_EXT_API *ext) +{ + if (!ext) { + return; + } + +#ifdef ALLEGRO_UNIX +#ifdef ALLEGRO_HAVE_DYNAMIC_LINK + if (!alXGetProcAddress) { + return; + } +#endif +#endif + +#ifdef ALLEGRO_WINDOWS + + #define AGL_API(type, name, args) \ + ext->name = (_ALLEGRO_gl##name##_t)load_extension("gl" #name); + + #include "allegro5/opengl/GLext/gl_ext_api.h" + + #undef AGL_API + + #define AGL_API(type, name, args) \ + ext->name = (_ALLEGRO_wgl##name##_t)load_extension("wgl" #name); + + #include "allegro5/opengl/GLext/wgl_ext_api.h" + + #undef AGL_API + +#elif defined ALLEGRO_UNIX + + #define AGL_API(type, name, args) \ + ext->name = (_ALLEGRO_gl##name##_t)load_extension("gl" #name); + + #include "allegro5/opengl/GLext/gl_ext_api.h" + + #undef AGL_API + + #define AGL_API(type, name, args) \ + ext->name = (_ALLEGRO_glX##name##_t)load_extension("glX" #name); + + #include "allegro5/opengl/GLext/glx_ext_api.h" + + #undef AGL_API + +#elif defined ALLEGRO_MACOSX + +#define AGL_API(type, name, args) \ + ext->name = (_ALLEGRO_gl##name##_t)load_extension("gl" # name); + + #include "allegro5/opengl/GLext/gl_ext_api.h" + + #undef AGL_API + +#elif defined ALLEGRO_SDL + +#define AGL_API(type, name, args) \ + ext->name = (_ALLEGRO_gl##name##_t)load_extension("gl" # name); + + #include "allegro5/opengl/GLext/gl_ext_api.h" + + #undef AGL_API + +#endif + +} + + + +/* Set the GL API pointers to the current table + * Should only be called on context switches. + */ +void _al_ogl_set_extensions(ALLEGRO_OGL_EXT_API *ext) +{ + if (!ext) { + return; + } + +#define AGL_API(type, name, args) _al_gl##name = ext->name; +# include "allegro5/opengl/GLext/gl_ext_api.h" +#undef AGL_API + +#ifdef ALLEGRO_WINDOWS +#define AGL_API(type, name, args) _al_wgl##name = ext->name; +# include "allegro5/opengl/GLext/wgl_ext_api.h" +#undef AGL_API + +#elif defined ALLEGRO_UNIX +#define AGL_API(type, name, args) _al_glX##name = ext->name; +# include "allegro5/opengl/GLext/glx_ext_api.h" +#undef AGL_API +#endif +} + + + +/* Destroys the extension API table */ +static void destroy_extension_api_table(ALLEGRO_OGL_EXT_API *ext) +{ + if (ext) { + al_free(ext); + } +} + + + +/* Destroys the extension list */ +static void destroy_extension_list(ALLEGRO_OGL_EXT_LIST *list) +{ + if (list) { + al_free(list); + } +} + + + +/* _al_ogl_look_for_an_extension: + * This function has been written by Mark J. Kilgard in one of his + * tutorials about OpenGL extensions + */ +int _al_ogl_look_for_an_extension(const char *name, const GLubyte *extensions) +{ + const GLubyte *start; + GLubyte *where, *terminator; + ASSERT(extensions); + + /* Extension names should not have spaces. */ + where = (GLubyte *) strchr(name, ' '); + if (where || *name == '\0') + return false; + /* It takes a bit of care to be fool-proof about parsing the + * OpenGL extensions string. Don't be fooled by sub-strings, etc. + */ + start = extensions; + for (;;) { + where = (GLubyte *) strstr((const char *)start, name); + if (!where) + break; + terminator = where + strlen(name); + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') + return true; + start = terminator; + } + return false; +} + + + +static bool _ogl_is_extension_supported(const char *extension, + ALLEGRO_DISPLAY *disp) +{ + int ret = 0; + GLubyte const *ext_str; +#if !defined ALLEGRO_CFG_OPENGLES + int v = al_get_opengl_version(); +#endif + (void)disp; + +#if !defined ALLEGRO_CFG_OPENGLES + if (disp->flags & ALLEGRO_OPENGL_3_0 || v >= _ALLEGRO_OPENGL_VERSION_3_0) { + int i; + GLint ext_cnt; + glGetIntegerv(GL_NUM_EXTENSIONS, &ext_cnt); + for (i = 0; i < ext_cnt; i++) { + ext_str = glGetStringi(GL_EXTENSIONS, i); + if (ext_str && !strcmp(extension, (char*)ext_str)) { + ret = 1; + break; + } + } + } + else +#endif + { + ext_str = glGetString(GL_EXTENSIONS); + if (!ext_str) + return false; + ret = _al_ogl_look_for_an_extension(extension, ext_str); + } + +#ifdef ALLEGRO_WINDOWS + if (!ret && strncmp(extension, "WGL", 3) == 0) { + ALLEGRO_DISPLAY_WGL *wgl_disp = (void*)disp; + _ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB; + + if (!wgl_disp->dc) + return false; + + _wglGetExtensionsStringARB = (void *) + wglGetProcAddress("wglGetExtensionsStringARB"); + if (_wglGetExtensionsStringARB) { + ret = _al_ogl_look_for_an_extension(extension, (const GLubyte *) + _wglGetExtensionsStringARB(wgl_disp->dc)); + } + } + +#elif defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX + if (!ret && strncmp(extension, "GLX", 3) == 0) { + ALLEGRO_SYSTEM_XGLX *sys = (void*)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx_disp = (void*)disp; + char const *ext; + + if (!sys->gfxdisplay) + return false; + + ext = glXQueryExtensionsString(sys->gfxdisplay, glx_disp->xscreen); + if (!ext) { + /* work around driver bugs? */ + ext = ""; + } + ret = _al_ogl_look_for_an_extension(extension, (const GLubyte *)ext); + } +#endif + + return ret; +} + + + +static bool _ogl_is_extension_with_version_supported( + const char *extension, ALLEGRO_DISPLAY *disp, uint32_t ver) +{ + char const *value; + + /* For testing purposes, any OpenGL extension can be disable in + * the config by using something like: + * + * [opengl_disabled_extensions] + * GL_ARB_texture_non_power_of_two=0 + * GL_EXT_framebuffer_object=0 + * + */ + value = al_get_config_value(al_get_system_config(), + "opengl_disabled_extensions", extension); + if (value) { + ALLEGRO_WARN("%s found in [opengl_disabled_extensions].\n", + extension); + return false; + } + + /* If the extension is included in the OpenGL version, there is no + * need to check the extensions list. + */ + if (ver > 0 && disp->ogl_extras->ogl_info.version >= ver) { + return true; + } + + return _ogl_is_extension_supported(extension, disp); +} + + + +/* Function: al_have_opengl_extension + */ +bool al_have_opengl_extension(const char *extension) +{ + ALLEGRO_DISPLAY *disp; + + disp = al_get_current_display(); + if (!disp) + return false; + + if (!(disp->flags & ALLEGRO_OPENGL)) + return false; + + return _ogl_is_extension_supported(extension, disp); +} + + + +/* Function: al_get_opengl_proc_address + */ +void *al_get_opengl_proc_address(const char *name) +{ + void *symbol = NULL; +#ifdef ALLEGRO_MACOSX + CFStringRef function; +#endif + ALLEGRO_DISPLAY *disp; + + disp = al_get_current_display(); + if (!disp) + return NULL; + + if (!(disp->flags & ALLEGRO_OPENGL)) + return NULL; + +#if defined ALLEGRO_WINDOWS + /* For once Windows is the easiest platform to use :) + * It provides a standardized way to get a function address + * But of course there is a drawback : the symbol is only valid + * under the current context :P + */ + { + ALLEGRO_DISPLAY_WGL *wgl_disp = (void*)disp; + + if (!wgl_disp->dc) + return NULL; + + symbol = wglGetProcAddress(name); + } +#elif defined ALLEGRO_UNIX +#if defined ALLEGRO_HAVE_DYNAMIC_LINK + if (alXGetProcAddress) +#endif + { + /* This is definitely the *good* way on Unix to get a GL proc + * address. Unfortunately glXGetProcAddress is an extension + * and may not be available on all platforms + */ +#if defined ALLEGRO_RASPBERRYPI + symbol = alXGetProcAddress(name); +#else + symbol = alXGetProcAddress((const GLubyte *)name); +#endif + } +#elif defined ALLEGRO_HAVE_DYNAMIC_LINK + else { + /* Hack if glXGetProcAddress is not available : + * we try to find the symbol into libGL.so + */ + if (__al_handle) { + symbol = dlsym(__al_handle, name); + } + } +#elif defined ALLEGRO_MACOSX + function = CFStringCreateWithCString(kCFAllocatorDefault, name, + kCFStringEncodingASCII); + if (function) { + symbol = + CFBundleGetFunctionPointerForName(opengl_bundle_ref, function); + CFRelease(function); + } +#endif + + if (!symbol) { + +#if defined ALLEGRO_HAVE_DYNAMIC_LINK + if (!alXGetProcAddress) { + ALLEGRO_WARN("get_proc_address: libdl::dlsym: %s\n", dlerror()); + } +#endif + + ALLEGRO_WARN("get_proc_address : Unable to load symbol %s\n", name); + } + else { + ALLEGRO_DEBUG("get_proc_address : Symbol %s successfully loaded\n", name); + } + return symbol; +} + + + +/* fill_in_info_struct: + * Fills in the OPENGL_INFO info struct for blacklisting video cards. + */ +static void fill_in_info_struct(const GLubyte *rendereru, OPENGL_INFO *info) +{ + const char *renderer = (const char *)rendereru; + ASSERT(renderer); + + /* Some cards are "special"... */ + if (strstr(renderer, "3Dfx/Voodoo")) { + info->is_voodoo = 1; + } + else if (strstr(renderer, "Matrox G200")) { + info->is_matrox_g200 = 1; + } + else if (strstr(renderer, "RagePRO")) { + info->is_ati_rage_pro = 1; + } + else if (strstr(renderer, "RADEON 7000")) { + info->is_ati_radeon_7000 = 1; + } + else if (strstr(renderer, "Mesa DRI R200")) { + info->is_ati_r200_chip = 1; + } + else if (strstr(renderer, "Intel HD Graphics 3000 OpenGL Engine")) { + info->is_intel_hd_graphics_3000 = 1; + } + + if ((strncmp(renderer, "3Dfx/Voodoo3 ", 13) == 0) + || (strncmp(renderer, "3Dfx/Voodoo2 ", 13) == 0) + || (strncmp(renderer, "3Dfx/Voodoo ", 12) == 0)) { + info->is_voodoo3_and_under = 1; + } + + /* Read OpenGL properties */ + info->version = _al_ogl_version(); + ALLEGRO_INFO("Assumed OpenGL version: %d.%d.%d.%d\n", + (info->version >> 24) & 0xff, + (info->version >> 16) & 0xff, + (info->version >> 8) & 0xff, + (info->version ) & 0xff); + + return; +} + + + +/* _al_ogl_manage_extensions: + * This functions fills the extensions API table and extension list + * structures and displays on the log file which extensions are available. + */ +void _al_ogl_manage_extensions(ALLEGRO_DISPLAY *gl_disp) +{ + //const GLubyte *buf; +#if defined ALLEGRO_MACOSX + CFURLRef bundle_url; +#endif + ALLEGRO_OGL_EXT_API *ext_api; + ALLEGRO_OGL_EXT_LIST *ext_list; + + /* Some functions depend on knowing the version of opengl in use */ + fill_in_info_struct(glGetString(GL_RENDERER), &(gl_disp->ogl_extras->ogl_info)); + + /* Print out OpenGL extensions + * We should use glGetStringi(GL_EXTENSIONS, i) for OpenGL 3.0+ + * but it doesn't seem to work until later. + */ + if (gl_disp->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_3_0) { + ALLEGRO_DEBUG("OpenGL Extensions:\n"); + print_extensions((char const *)glGetString(GL_EXTENSIONS)); + } + + /* Print out GLU version */ + //buf = gluGetString(GLU_VERSION); + //ALLEGRO_INFO("GLU Version : %s\n", buf); + +#ifdef ALLEGRO_HAVE_DYNAMIC_LINK + /* Get glXGetProcAddress entry */ + __libgl_handle = dlopen("libGL.so", RTLD_LAZY); + if (__libgl_handle) { + alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle, + "glXGetProcAddressARB"); + if (!alXGetProcAddress) { + alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle, + "glXGetProcAddress"); + if (!alXGetProcAddress) { + alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle, + "eglGetProcAddress"); + } + } + } + else { + ALLEGRO_WARN("Failed to dlopen libGL.so : %s\n", dlerror()); + } + ALLEGRO_INFO("glXGetProcAddress Extension: %s\n", + alXGetProcAddress ? "Supported" : "Unsupported"); +#elif defined ALLEGRO_UNIX +#ifdef ALLEGROGL_GLXGETPROCADDRESSARB + ALLEGRO_INFO("glXGetProcAddressARB Extension: supported\n"); +#else + ALLEGRO_INFO("glXGetProcAddress Extension: supported\n"); +#endif +#endif + +#ifdef ALLEGRO_MACOSX + bundle_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, + CFSTR + ("/System/Library/Frameworks/OpenGL.framework"), + kCFURLPOSIXPathStyle, true); + opengl_bundle_ref = CFBundleCreate(kCFAllocatorDefault, bundle_url); + CFRelease(bundle_url); +#endif + +#if defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX + ALLEGRO_DEBUG("GLX Extensions:\n"); + ALLEGRO_SYSTEM_XGLX *glx_sys = (void*)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx_disp = (void *)gl_disp; + char const *ext = glXQueryExtensionsString( + glx_sys->gfxdisplay, glx_disp->xscreen); + if (!ext) { + /* work around driver bugs? */ + ext = ""; + } + print_extensions(ext); +#endif + + /* Create & load extension API table */ + ext_api = create_extension_api_table(); + load_extensions(ext_api); + gl_disp->ogl_extras->extension_api = ext_api; + +#if !defined ALLEGRO_CFG_OPENGLES + /* Need that symbol already so can't wait until it is assigned later. */ + glGetStringi = ext_api->GetStringi; + + if (gl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_3_0) { + ALLEGRO_DEBUG("OpenGL Extensions:\n"); + print_extensions_3_0(); + } +#endif + + /* Create the list of supported extensions. */ + ext_list = create_extension_list(); + gl_disp->ogl_extras->extension_list = ext_list; + + /* Fill the list. */ +#define AGL_EXT(name, ver) { \ + ext_list->ALLEGRO_GL_##name = \ + _ogl_is_extension_with_version_supported("GL_" #name, gl_disp, \ + _ALLEGRO_OPENGL_VERSION_##ver); \ + } + #include "allegro5/opengl/GLext/gl_ext_list.h" +#undef AGL_EXT + +#ifdef ALLEGRO_UNIX +#define AGL_EXT(name, ver) { \ + ext_list->ALLEGRO_GLX_##name = \ + _ogl_is_extension_with_version_supported("GLX_" #name, gl_disp, \ + _ALLEGRO_OPENGL_VERSION_##ver); \ + } + #include "allegro5/opengl/GLext/glx_ext_list.h" +#undef AGL_EXT +#elif defined ALLEGRO_WINDOWS +#define AGL_EXT(name, ver) { \ + ext_list->ALLEGRO_WGL_##name = \ + _ogl_is_extension_with_version_supported("WGL_" #name, gl_disp, \ + _ALLEGRO_OPENGL_VERSION_##ver); \ + } + #include "allegro5/opengl/GLext/wgl_ext_list.h" +#undef AGL_EXT +#endif + + /* Get max texture size */ + glGetIntegerv(GL_MAX_TEXTURE_SIZE, + (GLint *) & gl_disp->ogl_extras->ogl_info.max_texture_size); + + /* Note: Voodoo (even V5) don't seem to correctly support + * packed pixel formats. Disabling them for those cards. + */ + ext_list->ALLEGRO_GL_EXT_packed_pixels &= !gl_disp->ogl_extras->ogl_info.is_voodoo; + + + if (ext_list->ALLEGRO_GL_EXT_packed_pixels) { + + ALLEGRO_INFO("Packed Pixels formats available\n"); + + /* XXX On NV cards, we want to use BGRA instead of RGBA for speed */ + /* Fills the __allegro_gl_texture_format array */ + /* TODO: use these somewhere */ +#if 0 + __allegro_gl_texture_read_format[0] = GL_UNSIGNED_BYTE_3_3_2; + __allegro_gl_texture_read_format[1] = GL_UNSIGNED_SHORT_5_5_5_1; + __allegro_gl_texture_read_format[2] = GL_UNSIGNED_SHORT_5_6_5; +#endif /* #if 0 */ + } + + /* NVidia and ATI cards expose OpenGL 2.0 but often don't accelerate + * non-power-of-2 textures. This check is how you verify that NP2 + * textures are hardware accelerated or not. + * We should clobber the NPOT support if it's not accelerated. + */ + { + const char *vendor = (const char *)glGetString(GL_VENDOR); + if (strstr(vendor, "NVIDIA Corporation")) { + if (!ext_list->ALLEGRO_GL_NV_fragment_program2 + || !ext_list->ALLEGRO_GL_NV_vertex_program3) { + ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two = 0; + } + } + else if (strstr(vendor, "ATI Technologies")) { + if (gl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_3_0) { + /* Assume okay. */ + } + else if (!strstr((const char *)glGetString(GL_EXTENSIONS), + "GL_ARB_texture_non_power_of_two") + && gl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { + ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two = 0; + } + } + } + + { + int *s = gl_disp->extra_settings.settings; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, s + ALLEGRO_MAX_BITMAP_SIZE); + + if (gl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) + s[ALLEGRO_SUPPORT_SEPARATE_ALPHA] = 1; + + s[ALLEGRO_SUPPORT_NPOT_BITMAP] = + ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two || + ext_list->ALLEGRO_GL_OES_texture_npot; + ALLEGRO_INFO("Use of non-power-of-two textures %s.\n", + s[ALLEGRO_SUPPORT_NPOT_BITMAP] ? "enabled" : "disabled"); +#if defined ALLEGRO_CFG_OPENGLES + if (gl_disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + s[ALLEGRO_CAN_DRAW_INTO_BITMAP] = true; + } + else { + s[ALLEGRO_CAN_DRAW_INTO_BITMAP] = + ext_list->ALLEGRO_GL_OES_framebuffer_object; + } + ALLEGRO_INFO("Use of FBO to draw to textures %s.\n", + s[ALLEGRO_CAN_DRAW_INTO_BITMAP] ? "enabled" : + "disabled"); +#else + s[ALLEGRO_CAN_DRAW_INTO_BITMAP] = + ext_list->ALLEGRO_GL_EXT_framebuffer_object; + ALLEGRO_INFO("Use of FBO to draw to textures %s.\n", + s[ALLEGRO_CAN_DRAW_INTO_BITMAP] ? "enabled" : + "disabled"); +#endif + } +} + + + +/* Function: al_get_opengl_extension_list + */ +ALLEGRO_OGL_EXT_LIST *al_get_opengl_extension_list(void) +{ + ALLEGRO_DISPLAY *disp; + + disp = al_get_current_display(); + ASSERT(disp); + + if (!(disp->flags & ALLEGRO_OPENGL)) + return NULL; + + ASSERT(disp->ogl_extras); + return disp->ogl_extras->extension_list; +} + + + +void _al_ogl_unmanage_extensions(ALLEGRO_DISPLAY *gl_disp) +{ + destroy_extension_api_table(gl_disp->ogl_extras->extension_api); + destroy_extension_list(gl_disp->ogl_extras->extension_list); + gl_disp->ogl_extras->extension_api = NULL; + gl_disp->ogl_extras->extension_list = NULL; + +#ifdef ALLEGRO_MACOSX + CFRelease(opengl_bundle_ref); +#endif +#ifdef ALLEGRO_HAVE_DYNAMIC_LINK + if (__libgl_handle) { + dlclose(__libgl_handle); + __libgl_handle = NULL; + } +#endif +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/ogl_bitmap.c b/allegro/src/opengl/ogl_bitmap.c new file mode 100644 index 00000000..2d6dc19b --- /dev/null +++ b/allegro/src/opengl/ogl_bitmap.c @@ -0,0 +1,1242 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL bitmap vtable + * + * By Elias Pschernig. + * OpenGL ES 1.1 support by Trent Gamblin. + * + */ + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_memblit.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_transform.h" + +#if defined ALLEGRO_ANDROID +#include "allegro5/internal/aintern_android.h" +#endif + +#include "ogl_helpers.h" + +ALLEGRO_DEBUG_CHANNEL("opengl") + +/* OpenGL does not support "locking", i.e. direct access to a memory + * buffer with pixel data. Instead, the data can be copied from/to + * client memory. Because OpenGL stores pixel data starting with the + * pixel in the lower left corner, that's also how we return locked + * data. Otherwise (and as was done in earlier versions of this code) + * we would have to flip all locked memory after receiving and before + * sending it to OpenGL. + * + * Also, we do support old OpenGL drivers where textures must have + * power-of-two dimensions. If a non-power-of-two bitmap is created in + * such a case, we use a texture with the next larger POT dimensions, + * and just keep some unused padding space to the right/bottom of the + * pixel data. + * + * Putting it all together, if we have an Allegro bitmap like this, + * with Allegro's y-coordinates: + * 0 ########### + * 1 #111 # + * 2 #222 # + * 3 #333 # + * 4 ########### + * + * Then the corresponding texture looks like this with OpenGL + * y-coordinates (assuming we use an old driver which needs padding to + * POT): + * 7 ................ + * 6 ................ + * 5 ................ + * 4 ###########..... + * 3 #333 #..... + * 2 #222 #..... + * 1 #111 #..... + * 0 ###########..... + */ + +/* Conversion table from Allegro's pixel formats to corresponding OpenGL + * formats. The three entries are: + * - GL internal format: the number of color components in the texture + * - GL pixel type: Specifies the data type of the pixel data. + * - GL format: Specifies the format of the pixel data. + * + * GL does not support RGB_555 and BGR_555 directly so we use + * GL_UNSIGNED_SHORT_1_5_5_5_REV when transferring pixel data, and ensure that + * the alpha bit (the "1" component) is present by setting GL_ALPHA_BIAS. + * + * Desktop OpenGL 3.0+ has no GL_LUMINANCE, so we have to adjust depending on + * the runtime version. + */ +#define get_glformat(f, c) _al_ogl_get_glformat((f), (c)) +int _al_ogl_get_glformat(int format, int component) +{ + #if !defined ALLEGRO_CFG_OPENGLES + static int glformats[ALLEGRO_NUM_PIXEL_FORMATS][3] = { + /* Skip pseudo formats */ + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + /* Actual formats */ + {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA}, /* ARGB_8888 */ + {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8, GL_RGBA}, /* RGBA_8888 */ + {GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_BGRA}, /* ARGB_4444 */ + {GL_RGB8, GL_UNSIGNED_BYTE, GL_BGR}, /* RGB_888 */ + {GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB}, /* RGB_565 */ + {GL_RGB5, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_BGRA}, /* RGB_555 - see above */ + {GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA}, /* RGBA_5551 */ + {GL_RGB5_A1, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_BGRA}, /* ARGB_1555 */ + {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_RGBA}, /* ABGR_8888 */ + {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_RGBA}, /* XBGR_8888 */ + {GL_RGB8, GL_UNSIGNED_BYTE, GL_RGB}, /* BGR_888 */ + {GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, GL_RGB}, /* BGR_565 */ + {GL_RGB5, GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_RGBA}, /* BGR_555 - see above */ + {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8, GL_RGBA}, /* RGBX_8888 */ + {GL_RGBA8, GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA}, /* XRGB_8888 */ + {GL_RGBA32F_ARB, GL_FLOAT, GL_RGBA}, /* ABGR_F32 */ + {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA}, /* ABGR_8888_LE */ + {GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA}, /* RGBA_4444 */ + {GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE}, /* SINGLE_CHANNEL_8 */ + {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_INT_8_8_8_8, GL_RGBA}, /* RGBA_DXT1 */ + {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_UNSIGNED_INT_8_8_8_8, GL_RGBA}, /* RGBA_DXT3 */ + {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_UNSIGNED_INT_8_8_8_8, GL_RGBA}, /* RGBA_DXT5 */ + }; + + if (al_get_opengl_version() >= _ALLEGRO_OPENGL_VERSION_3_0) { + glformats[ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8][0] = GL_RED; + glformats[ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8][2] = GL_RED; + } + #else + // TODO: Check supported formats by various GLES versions + static const int glformats[ALLEGRO_NUM_PIXEL_FORMATS][3] = { + /* Skip pseudo formats */ + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + /* Actual formats */ + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB}, /* RGB_565 */ + {0, 0, 0}, + {GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA}, /* RGBA_5551 */ + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA}, /* ABGR_8888_LE */ + {GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA}, /* RGBA_4444 */ + {GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE}, /* SINGLE_CHANNEL_8 */ + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + }; + #endif + + return glformats[format][component]; +} + +static ALLEGRO_BITMAP_INTERFACE glbmp_vt; + + +#define SWAP(type, x, y) {type temp = x; x = y; y = temp;} + +#define ERR(e) case e: return #e; +char const *_al_gl_error_string(GLenum e) +{ + switch (e) { + ERR(GL_NO_ERROR) + ERR(GL_INVALID_ENUM) + ERR(GL_INVALID_VALUE) + ERR(GL_INVALID_OPERATION) +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + ERR(GL_STACK_OVERFLOW) + ERR(GL_STACK_UNDERFLOW) +#endif + ERR(GL_OUT_OF_MEMORY) +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + ERR(GL_INVALID_FRAMEBUFFER_OPERATION) +#endif + } + return "UNKNOWN"; +} +#undef ERR + +static INLINE void transform_vertex(float* x, float* y, float* z) +{ + al_transform_coordinates_3d(al_get_current_transform(), x, y, z); +} + +static void draw_quad(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, + float sx, float sy, float sw, float sh, + int flags) +{ + float tex_l, tex_t, tex_r, tex_b, w, h, true_w, true_h; + float dw = sw, dh = sh; + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra; + ALLEGRO_OGL_BITMAP_VERTEX *verts; + ALLEGRO_DISPLAY *disp = al_get_current_display(); + + (void)flags; + + if (disp->num_cache_vertices != 0 && ogl_bitmap->texture != disp->cache_texture) { + disp->vt->flush_vertex_cache(disp); + } + disp->cache_texture = ogl_bitmap->texture; + + verts = disp->vt->prepare_vertex_cache(disp, 6); + + tex_l = ogl_bitmap->left; + tex_r = ogl_bitmap->right; + tex_t = ogl_bitmap->top; + tex_b = ogl_bitmap->bottom; + + w = bitmap->w; + h = bitmap->h; + true_w = ogl_bitmap->true_w; + true_h = ogl_bitmap->true_h; + + tex_l += sx / true_w; + tex_t -= sy / true_h; + tex_r -= (w - sx - sw) / true_w; + tex_b += (h - sy - sh) / true_h; + + verts[0].x = 0; + verts[0].y = dh; + verts[0].z = 0; + verts[0].tx = tex_l; + verts[0].ty = tex_b; + verts[0].r = tint.r; + verts[0].g = tint.g; + verts[0].b = tint.b; + verts[0].a = tint.a; + + verts[1].x = 0; + verts[1].y = 0; + verts[1].z = 0; + verts[1].tx = tex_l; + verts[1].ty = tex_t; + verts[1].r = tint.r; + verts[1].g = tint.g; + verts[1].b = tint.b; + verts[1].a = tint.a; + + verts[2].x = dw; + verts[2].y = dh; + verts[2].z = 0; + verts[2].tx = tex_r; + verts[2].ty = tex_b; + verts[2].r = tint.r; + verts[2].g = tint.g; + verts[2].b = tint.b; + verts[2].a = tint.a; + + verts[4].x = dw; + verts[4].y = 0; + verts[4].z = 0; + verts[4].tx = tex_r; + verts[4].ty = tex_t; + verts[4].r = tint.r; + verts[4].g = tint.g; + verts[4].b = tint.b; + verts[4].a = tint.a; + + if (disp->cache_enabled) { + /* If drawing is batched, we apply transformations manually. */ + transform_vertex(&verts[0].x, &verts[0].y, &verts[0].z); + transform_vertex(&verts[1].x, &verts[1].y, &verts[1].z); + transform_vertex(&verts[2].x, &verts[2].y, &verts[2].z); + transform_vertex(&verts[4].x, &verts[4].y, &verts[4].z); + } + verts[3] = verts[1]; + verts[5] = verts[2]; + + if (!disp->cache_enabled) + disp->vt->flush_vertex_cache(disp); +} +#undef SWAP + + +static void ogl_draw_bitmap_region(ALLEGRO_BITMAP *bitmap, + ALLEGRO_COLOR tint, float sx, float sy, + float sw, float sh, int flags) +{ + // FIXME: hack + // FIXME: need format conversion if they don't match + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target; + ALLEGRO_DISPLAY *disp = _al_get_bitmap_display(target); + + /* For sub-bitmaps */ + if (target->parent) { + target = target->parent; + } + + ogl_target = target->extra; + + if (!(al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP) && !bitmap->locked && + !target->locked) { + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_source = bitmap->extra; + if (ogl_source->is_backbuffer) { + /* Our source bitmap is the OpenGL backbuffer, the target + * is an OpenGL texture. + */ + float xtrans, ytrans; + + /* Source and target cannot both be the back-buffer. */ + ASSERT(!ogl_target->is_backbuffer); + + /* If we only translate, we can do this fast. */ + if (_al_transform_is_translation(al_get_current_transform(), + &xtrans, &ytrans)) { + /* In general, we can't modify the texture while it's + * FBO bound - so we temporarily disable the FBO. + */ + if (ogl_target->fbo_info) + _al_ogl_set_target_bitmap(disp, bitmap); + + /* We need to do clipping because glCopyTexSubImage2D + * fails otherwise. + */ + if (xtrans < target->cl) { + sx -= xtrans - target->cl; + sw += xtrans - target->cl; + xtrans = target->cl; + } + if (ytrans < target->ct) { + sy -= ytrans - target->ct; + sh += ytrans - target->ct; + ytrans = target->ct; + } + if (xtrans + sw > target->cr_excl) { + sw = target->cr_excl - xtrans; + } + if (ytrans + sh > target->cb_excl) { + sh = target->cb_excl - ytrans; + } + + /* Note: Allegro 5.0.0 does not support blending or + * tinting if the source bitmap is the screen. So it is + * correct to ignore them here. + */ + + glBindTexture(GL_TEXTURE_2D, ogl_target->texture); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, + xtrans, target->h - ytrans - sh, + sx, bitmap->h - sy - sh, + sw, sh); + /* Fix up FBO again after the copy. */ + if (ogl_target->fbo_info) + _al_ogl_set_target_bitmap(disp, target); + return; + } + + /* Drawing a deformed backbuffer is not supported. */ + ASSERT(0); + } + } + if (disp->ogl_extras->opengl_target == target) { + draw_quad(bitmap, tint, sx, sy, sw, sh, flags); + return; + } + + /* If all else fails, fall back to software implementation. */ + _al_draw_bitmap_region_memory(bitmap, tint, sx, sy, sw, sh, 0, 0, flags); +} + + +/* Helper to get smallest fitting power of two. */ +static int pot(int x) +{ + int y = 1; + while (y < x) y *= 2; + return y; +} + + + +// FIXME: need to do all the logic AllegroGL does, checking extensions, +// proxy textures, formats, limits ... +static bool ogl_upload_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra; + int w = bitmap->w; + int h = bitmap->h; + int bitmap_format = al_get_bitmap_format(bitmap); + int bitmap_flags = al_get_bitmap_flags(bitmap); + bool post_generate_mipmap = false; + GLenum e; + int filter; + int gl_filters[] = { + GL_NEAREST, GL_LINEAR, + GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR + }; + + if (ogl_bitmap->texture == 0) { + glGenTextures(1, &ogl_bitmap->texture); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glGenTextures failed: %s\n", _al_gl_error_string(e)); + } + else { + ALLEGRO_DEBUG("Created new OpenGL texture %d (%dx%d, format %s)\n", + ogl_bitmap->texture, + ogl_bitmap->true_w, ogl_bitmap->true_h, + _al_pixel_format_name(bitmap_format)); + } + } + glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glBindTexture for texture %d failed (%s).\n", + ogl_bitmap->texture, _al_gl_error_string(e)); + } + + /* Wrap, Min/Mag should always come before glTexImage2D so the texture is "complete" */ + // NOTE: on OGLES CLAMP_TO_EDGE is only one supported with NPOT textures + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + filter = (bitmap_flags & ALLEGRO_MIPMAP) ? 2 : 0; + if (bitmap_flags & ALLEGRO_MIN_LINEAR) { + filter++; + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filters[filter]); + + filter = 0; + if (bitmap_flags & ALLEGRO_MAG_LINEAR) { + filter++; + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filters[filter]); + +// TODO: To support anisotropy, we would need an API for it. Something +// like: +// al_set_new_bitmap_option(ALLEGRO_ANISOTROPY, 16.0); +#if 0 + if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_texture_filter_anisotropic) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); + } +#endif + + if (bitmap_flags & ALLEGRO_MIPMAP) { + /* If using FBOs, use glGenerateMipmapEXT instead of the GL_GENERATE_MIPMAP + * texture parameter. GL_GENERATE_MIPMAP is deprecated in GL 3.0 so we + * may want to use the new method in other cases as well. + */ + if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object || + al_get_opengl_extension_list()->ALLEGRO_GL_OES_framebuffer_object || + IS_OPENGLES /* FIXME */) { + post_generate_mipmap = true; + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glTexParameteri for texture %d failed (%s).\n", + ogl_bitmap->texture, _al_gl_error_string(e)); + } +#endif + } + } + + /* If there's unused space around the bitmap, we need to clear it + * else linear filtering will cause artifacts from the random + * data there. We also clear for floating point formats because + * NaN values in the texture cause some blending modes to fail on + * those pixels + */ + if (!IS_OPENGLES) { + if (ogl_bitmap->true_w != bitmap->w || + ogl_bitmap->true_h != bitmap->h || + bitmap_format == ALLEGRO_PIXEL_FORMAT_ABGR_F32) { + unsigned char *buf; + buf = al_calloc(ogl_bitmap->true_h, ogl_bitmap->true_w); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, get_glformat(bitmap_format, 0), + ogl_bitmap->true_w, ogl_bitmap->true_h, 0, + GL_ALPHA, GL_UNSIGNED_BYTE, buf); + e = glGetError(); + al_free(buf); + } + else { + glTexImage2D(GL_TEXTURE_2D, 0, get_glformat(bitmap_format, 0), + ogl_bitmap->true_w, ogl_bitmap->true_h, 0, + get_glformat(bitmap_format, 2), get_glformat(bitmap_format, 1), + NULL); + e = glGetError(); + } + } + else { + unsigned char *buf; + int pix_size = al_get_pixel_size(bitmap_format); + buf = al_calloc(pix_size, + ogl_bitmap->true_h * ogl_bitmap->true_w); + glPixelStorei(GL_UNPACK_ALIGNMENT, pix_size); + glTexImage2D(GL_TEXTURE_2D, 0, get_glformat(bitmap_format, 0), + ogl_bitmap->true_w, ogl_bitmap->true_h, 0, + get_glformat(bitmap_format, 2), + get_glformat(bitmap_format, 1), buf); + e = glGetError(); + al_free(buf); + } + + if (e) { + ALLEGRO_ERROR("glTexImage2D for format %s, size %dx%d failed (%s)\n", + _al_pixel_format_name(bitmap_format), + ogl_bitmap->true_w, ogl_bitmap->true_h, + _al_gl_error_string(e)); + glDeleteTextures(1, &ogl_bitmap->texture); + ogl_bitmap->texture = 0; + // FIXME: Should we convert it into a memory bitmap? Or if the size is + // the problem try to use multiple textures? + return false; + } + + if (post_generate_mipmap) { + glGenerateMipmapEXT(GL_TEXTURE_2D); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glGenerateMipmapEXT for texture %d failed (%s).\n", + ogl_bitmap->texture, _al_gl_error_string(e)); + } + } + + ogl_bitmap->left = 0; + ogl_bitmap->right = (float) w / ogl_bitmap->true_w; + ogl_bitmap->top = (float) h / ogl_bitmap->true_h; + ogl_bitmap->bottom = 0; + + return true; +} + + + +static void ogl_update_clipping_rectangle(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_DISPLAY *ogl_disp = al_get_current_display(); + ALLEGRO_BITMAP *target_bitmap = bitmap; + + if (bitmap->parent) { + target_bitmap = bitmap->parent; + } + + if (ogl_disp->ogl_extras->opengl_target == target_bitmap) { + _al_ogl_setup_bitmap_clipping(bitmap); + } +} + + + +static void ogl_destroy_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra; + ALLEGRO_DISPLAY *disp; + ALLEGRO_DISPLAY *bmp_disp; + ALLEGRO_DISPLAY *old_disp = NULL; + + ASSERT(!al_is_sub_bitmap(bitmap)); + + bmp_disp = _al_get_bitmap_display(bitmap); + disp = al_get_current_display(); + if (bmp_disp->ogl_extras->is_shared == false && + bmp_disp != disp) { + old_disp = disp; + _al_set_current_display_only(bmp_disp); + } + + if (bmp_disp->ogl_extras->opengl_target == bitmap) { + bmp_disp->ogl_extras->opengl_target = NULL; + } + + al_remove_opengl_fbo(bitmap); + + if (ogl_bitmap->texture) { + glDeleteTextures(1, &ogl_bitmap->texture); + ogl_bitmap->texture = 0; + } + + if (old_disp) { + _al_set_current_display_only(old_disp); + } + + al_free(ogl_bitmap); +} + + + +static void ogl_bitmap_pointer_changed(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP *old) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *extra = bitmap->extra; + if (extra && extra->fbo_info) { + ASSERT(extra->fbo_info->owner == old); + extra->fbo_info->owner = bitmap; + } +} + + +static bool can_flip_blocks(ALLEGRO_PIXEL_FORMAT format) +{ + switch (format) { + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1: + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3: + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5: + return true; + default: + return false; + } +} + + +static void ogl_flip_blocks(ALLEGRO_LOCKED_REGION *lr, int wc, int hc) +{ +#define SWAP(x, y) do { unsigned char t = x; x = y; y = t; } while (0) + int x, y; + unsigned char* data = lr->data; + ASSERT(can_flip_blocks(lr->format)); + switch (lr->format) { + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1: { + for (y = 0; y < hc; y++) { + unsigned char* row = data; + for (x = 0; x < wc; x++) { + /* Skip color table */ + row += 4; + + /* Swap colors */ + SWAP(row[0], row[3]); + SWAP(row[2], row[1]); + + /* Skip bit-map */ + row += 4; + } + data += lr->pitch; + } + break; + } + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3: { + for (y = 0; y < hc; y++) { + unsigned char* row = data; + for (x = 0; x < wc; x++) { + /* Swap alpha */ + SWAP(row[0], row[6]); + SWAP(row[1], row[7]); + SWAP(row[2], row[4]); + SWAP(row[3], row[5]); + + /* Skip alpha bit-map */ + row += 8; + + /* Skip color table */ + row += 4; + + /* Swap colors */ + SWAP(row[0], row[3]); + SWAP(row[2], row[1]); + + /* Skip bit-map */ + row += 4; + } + data += lr->pitch; + } + break; + } + case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5: { + for (y = 0; y < hc; y++) { + unsigned char* row = data; + for (x = 0; x < wc; x++) { + uint16_t bit_row0, bit_row1, bit_row2, bit_row3; + + /* Skip the alpha table */ + row += 2; + + bit_row0 = (((uint16_t)row[0]) | (uint16_t)row[1] << 8) << 4; + bit_row1 = (((uint16_t)row[1]) | (uint16_t)row[2] << 8) >> 4; + bit_row2 = (((uint16_t)row[3]) | (uint16_t)row[4] << 8) << 4; + bit_row3 = (((uint16_t)row[4]) | (uint16_t)row[5] << 8) >> 4; + + row[0] = (unsigned char)(bit_row3 & 0x00ff); + row[1] = (unsigned char)((bit_row2 & 0x00ff) | ((bit_row3 & 0xff00) >> 8)); + row[2] = (unsigned char)((bit_row2 & 0xff00) >> 8); + + row[3] = (unsigned char)(bit_row1 & 0x00ff); + row[4] = (unsigned char)((bit_row0 & 0x00ff) | ((bit_row1 & 0xff00) >> 8)); + row[5] = (unsigned char)((bit_row0 & 0xff00) >> 8); + + /* Skip the alpha bit-map */ + row += 6; + + /* Skip color table */ + row += 4; + + /* Swap colors */ + SWAP(row[0], row[3]); + SWAP(row[2], row[1]); + + /* Skip bit-map */ + row += 4; + } + data += lr->pitch; + } + break; + } + default: + (void)x; + (void)y; + (void)data; + (void)wc; + (void)hc; + } +#undef SWAP +} + +static ALLEGRO_LOCKED_REGION *ogl_lock_compressed_region(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int flags) +{ +#if !defined ALLEGRO_CFG_OPENGLES + ALLEGRO_BITMAP_EXTRA_OPENGL *const ogl_bitmap = bitmap->extra; + ALLEGRO_DISPLAY *disp; + ALLEGRO_DISPLAY *old_disp = NULL; + GLenum e; + bool ok = true; + int bitmap_format = al_get_bitmap_format(bitmap); + int block_width = al_get_pixel_block_width(bitmap_format); + int block_height = al_get_pixel_block_height(bitmap_format); + int block_size = al_get_pixel_block_size(bitmap_format); + int xc = x / block_width; + int yc = y / block_width; + int wc = w / block_width; + int hc = h / block_width; + int true_wc = ogl_bitmap->true_w / block_width; + int true_hc = ogl_bitmap->true_h / block_height; + int gl_yc = _al_get_least_multiple(bitmap->h, block_height) / block_height - yc - hc; + + if (!can_flip_blocks(bitmap_format)) { + return NULL; + } + + if (flags & ALLEGRO_LOCK_WRITEONLY) { + int pitch = wc * block_size; + ogl_bitmap->lock_buffer = al_malloc(pitch * hc); + if (ogl_bitmap->lock_buffer == NULL) { + return NULL; + } + + bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (hc - 1); + bitmap->locked_region.format = bitmap_format; + bitmap->locked_region.pitch = -pitch; + bitmap->locked_region.pixel_size = block_size; + return &bitmap->locked_region; + } + + disp = al_get_current_display(); + + /* Change OpenGL context if necessary. */ + if (!disp || + (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false && + _al_get_bitmap_display(bitmap) != disp)) + { + old_disp = disp; + _al_set_current_display_only(_al_get_bitmap_display(bitmap)); + } + + /* Set up the pixel store state. We will need to match it when unlocking. + * There may be other pixel store state we should be setting. + * See also pitfalls 7 & 8 from: + * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ + */ + int previous_alignment; + glGetIntegerv(GL_PACK_ALIGNMENT, &previous_alignment); + if (previous_alignment != 1) { + glPixelStorei(GL_PACK_ALIGNMENT, 1); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glPixelStorei(GL_PACK_ALIGNMENT, %d) failed (%s).\n", + 1, _al_gl_error_string(e)); + ok = false; + } + } + + if (ok) { + ogl_bitmap->lock_buffer = al_malloc(true_wc * true_hc * block_size); + + if (ogl_bitmap->lock_buffer != NULL) { + glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); + glGetCompressedTexImage(GL_TEXTURE_2D, 0, ogl_bitmap->lock_buffer); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glGetCompressedTexImage for format %s failed (%s).\n", + _al_pixel_format_name(bitmap_format), _al_gl_error_string(e)); + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; + ok = false; + } + else { + if (flags == ALLEGRO_LOCK_READWRITE) { + /* Need to make the locked memory contiguous, as + * glCompressedTexSubImage2D cannot read strided + * memory. */ + int y; + int src_pitch = true_wc * block_size; + int dest_pitch = wc * block_size; + char* dest_ptr = (char*)ogl_bitmap->lock_buffer; + char* src_ptr = (char*)ogl_bitmap->lock_buffer + + src_pitch * gl_yc + block_size * xc; + for (y = 0; y < hc; y++) { + memmove(dest_ptr, src_ptr, dest_pitch); + src_ptr += src_pitch; + dest_ptr += dest_pitch; + } + bitmap->locked_region.data = ogl_bitmap->lock_buffer + + dest_pitch * (hc - 1); + bitmap->locked_region.pitch = -dest_pitch; + } + else { + int pitch = true_wc * block_size; + bitmap->locked_region.data = ogl_bitmap->lock_buffer + + pitch * (gl_yc + hc - 1) + block_size * xc; + bitmap->locked_region.pitch = -pitch; + } + bitmap->locked_region.format = bitmap_format; + bitmap->locked_region.pixel_size = block_size; + } + } + else { + ok = false; + } + } + + if (previous_alignment != 1) { + glPixelStorei(GL_PACK_ALIGNMENT, previous_alignment); + } + + if (old_disp != NULL) { + _al_set_current_display_only(old_disp); + } + + if (ok) { + ogl_flip_blocks(&bitmap->locked_region, wc, hc); + return &bitmap->locked_region; + } + + ALLEGRO_ERROR("Failed to lock region\n"); + ASSERT(ogl_bitmap->lock_buffer == NULL); + return NULL; +#else + (void)bitmap; + (void)x; + (void)y; + (void)w; + (void)h; + (void)flags; + return NULL; +#endif +} + + +static void ogl_unlock_compressed_region(ALLEGRO_BITMAP *bitmap) +{ +#if !defined ALLEGRO_CFG_OPENGLES + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra; + int lock_format = bitmap->locked_region.format; + ALLEGRO_DISPLAY *old_disp = NULL; + ALLEGRO_DISPLAY *disp; + GLenum e; + int block_size = al_get_pixel_block_size(lock_format); + int block_width = al_get_pixel_block_width(lock_format); + int block_height = al_get_pixel_block_height(lock_format); + int data_size = bitmap->lock_h * bitmap->lock_w / + (block_width * block_height) * block_size; + int gl_y = _al_get_least_multiple(bitmap->h, block_height) - bitmap->lock_y - bitmap->lock_h; + + /* It shouldn't be possible for this to fail, as we wouldn't have been able + * to lock earlier */ + ASSERT(can_flip_blocks(bitmap->locked_region.format)); + + if ((bitmap->lock_flags & ALLEGRO_LOCK_READONLY)) { + goto EXIT; + } + + ogl_flip_blocks(&bitmap->locked_region, bitmap->lock_w / block_width, + bitmap->lock_h / block_height); + + disp = al_get_current_display(); + + /* Change OpenGL context if necessary. */ + if (!disp || + (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false && + _al_get_bitmap_display(bitmap) != disp)) + { + old_disp = disp; + _al_set_current_display_only(_al_get_bitmap_display(bitmap)); + } + + /* Keep this in sync with ogl_lock_compressed_region. */ + int previous_alignment; + glGetIntegerv(GL_UNPACK_ALIGNMENT, &previous_alignment); + if (previous_alignment != 1) { + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glPixelStorei(GL_UNPACK_ALIGNMENT, %d) failed (%s).\n", + 1, _al_gl_error_string(e)); + } + } + + glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, + bitmap->lock_x, gl_y, + bitmap->lock_w, bitmap->lock_h, + get_glformat(lock_format, 0), + data_size, + ogl_bitmap->lock_buffer); + + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glCompressedTexSubImage2D for format %s failed (%s).\n", + _al_pixel_format_name(lock_format), _al_gl_error_string(e)); + } + + if (previous_alignment != 1) { + glPixelStorei(GL_UNPACK_ALIGNMENT, previous_alignment); + } + + if (old_disp) { + _al_set_current_display_only(old_disp); + } + +EXIT: + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; +#else + (void)bitmap; +#endif +} + +static void ogl_backup_dirty_bitmap(ALLEGRO_BITMAP *b) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = b->extra; + ALLEGRO_LOCKED_REGION *lr; + int bitmap_flags = al_get_bitmap_flags(b); + + if (b->parent) + return; + + if ((bitmap_flags & ALLEGRO_MEMORY_BITMAP) || + (bitmap_flags & ALLEGRO_NO_PRESERVE_TEXTURE) || + !b->dirty || + ogl_bitmap->is_backbuffer) + return; + + ALLEGRO_DEBUG("Backing up dirty bitmap %p\n", b); + + lr = al_lock_bitmap( + b, + _al_get_bitmap_memory_format(b), + ALLEGRO_LOCK_READONLY + ); + + if (lr) { + int line_size = al_get_pixel_size(lr->format) * b->w; + int y; + for (y = 0; y < b->h; y++) { + unsigned char *p = ((unsigned char *)lr->data) + lr->pitch * y; + unsigned char *p2; + p2 = ((unsigned char *)b->memory) + line_size * (b->h-1-y); + memcpy(p2, p, line_size); + } + al_unlock_bitmap(b); + b->dirty = false; + } + else { + ALLEGRO_WARN("Failed to lock dirty bitmap %p\n", b); + } +} + +/* Obtain a reference to this driver. */ +static ALLEGRO_BITMAP_INTERFACE *ogl_bitmap_driver(void) +{ + if (glbmp_vt.draw_bitmap_region) { + return &glbmp_vt; + } + + glbmp_vt.draw_bitmap_region = ogl_draw_bitmap_region; + glbmp_vt.upload_bitmap = ogl_upload_bitmap; + glbmp_vt.update_clipping_rectangle = ogl_update_clipping_rectangle; + glbmp_vt.destroy_bitmap = ogl_destroy_bitmap; + glbmp_vt.bitmap_pointer_changed = ogl_bitmap_pointer_changed; +#if defined(ALLEGRO_CFG_OPENGLES) + glbmp_vt.lock_region = _al_ogl_lock_region_gles; + glbmp_vt.unlock_region = _al_ogl_unlock_region_gles; +#else + glbmp_vt.lock_region = _al_ogl_lock_region_new; + glbmp_vt.unlock_region = _al_ogl_unlock_region_new; +#endif + glbmp_vt.lock_compressed_region = ogl_lock_compressed_region; + glbmp_vt.unlock_compressed_region = ogl_unlock_compressed_region; + glbmp_vt.backup_dirty_bitmap = ogl_backup_dirty_bitmap; + + return &glbmp_vt; +} + + + +ALLEGRO_BITMAP *_al_ogl_create_bitmap(ALLEGRO_DISPLAY *d, int w, int h, + int format, int flags) +{ + ALLEGRO_BITMAP *bitmap; + ALLEGRO_BITMAP_EXTRA_OPENGL *extra; + int true_w; + int true_h; + int block_width; + int block_height; + ALLEGRO_SYSTEM *system = al_get_system_driver(); + (void)d; + + format = _al_get_real_pixel_format(d, format); + ASSERT(_al_pixel_format_is_real(format)); + + block_width = al_get_pixel_block_width(format); + block_height = al_get_pixel_block_width(format); + true_w = _al_get_least_multiple(w, block_width); + true_h = _al_get_least_multiple(h, block_height); + + if (_al_pixel_format_is_compressed(format)) { + if (!al_get_opengl_extension_list()->ALLEGRO_GL_EXT_texture_compression_s3tc) { + ALLEGRO_DEBUG("Device does not support S3TC compressed textures.\n"); + return NULL; + } + } + + if (!d->extra_settings.settings[ALLEGRO_SUPPORT_NPOT_BITMAP]) { + true_w = pot(true_w); + true_h = pot(true_h); + } + + /* This used to be an iOS/Android only workaround - but + * Intel is making GPUs with the same chips now. Very + * small textures can have garbage pixels and FBOs don't + * work with them on some of these chips. This is a + * workaround. + */ + if (true_w < system->min_bitmap_size) true_w = system->min_bitmap_size; + if (true_h < system->min_bitmap_size) true_h = system->min_bitmap_size; + + /* glReadPixels requires 32 byte aligned rows */ + if (IS_ANDROID) { + int mod = true_w % 32; + if (mod != 0) { + true_w += 32 - mod; + } + } + + ASSERT(true_w % block_width == 0); + ASSERT(true_h % block_height == 0); + + bitmap = al_calloc(1, sizeof *bitmap); + ASSERT(bitmap); + bitmap->extra = al_calloc(1, sizeof(ALLEGRO_BITMAP_EXTRA_OPENGL)); + ASSERT(bitmap->extra); + extra = bitmap->extra; + + bitmap->vt = ogl_bitmap_driver(); + bitmap->_memory_format = + _al_pixel_format_is_compressed(format) ? ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE : format; + bitmap->pitch = true_w * al_get_pixel_size(bitmap->_memory_format); + bitmap->_format = format; + bitmap->_flags = flags | _ALLEGRO_INTERNAL_OPENGL; + + extra->true_w = true_w; + extra->true_h = true_h; + + if (!(flags & ALLEGRO_NO_PRESERVE_TEXTURE)) { + bitmap->memory = al_calloc(1, al_get_pixel_size(bitmap->_memory_format)*w*h); + } + + return bitmap; +} + + + +/* lets you setup the memory pointer to skip a lock/unlock copy + * if it's unnecessary + * 'ptr' should be tightly packed or NULL if no texture data + * upload is desired. + */ +void _al_ogl_upload_bitmap_memory(ALLEGRO_BITMAP *bitmap, int format, void *ptr) +{ + int w = bitmap->w; + int h = bitmap->h; + int pixsize = al_get_pixel_size(format); + int y; + ALLEGRO_BITMAP *tmp; + ALLEGRO_LOCKED_REGION *lr; + uint8_t *dst; + uint8_t *src; + + ASSERT(ptr); + ASSERT(al_get_current_display() == _al_get_bitmap_display(bitmap)); + + tmp = _al_create_bitmap_params(_al_get_bitmap_display(bitmap), w, h, format, + al_get_bitmap_flags(bitmap), 0, 0); + ASSERT(tmp); + + lr = al_lock_bitmap(tmp, format, ALLEGRO_LOCK_WRITEONLY); + ASSERT(lr); + + dst = (uint8_t *)lr->data; + // we need to flip it + src = ((uint8_t *)ptr) + (pixsize * w * (h-1)); + + for (y = 0; y < h; y++) { + memcpy(dst, src, pixsize * w); + dst += lr->pitch; + src -= pixsize * w; // minus because it's flipped + } + + al_unlock_bitmap(tmp); + + ((ALLEGRO_BITMAP_EXTRA_OPENGL *)bitmap->extra)->texture = + ((ALLEGRO_BITMAP_EXTRA_OPENGL *)tmp->extra)->texture; + ((ALLEGRO_BITMAP_EXTRA_OPENGL *)tmp->extra)->texture = 0; + al_destroy_bitmap(tmp); +} + +/* Function: al_get_opengl_texture + */ +GLuint al_get_opengl_texture(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *extra; + if (bitmap->parent) + bitmap = bitmap->parent; + if (!(al_get_bitmap_flags(bitmap) & _ALLEGRO_INTERNAL_OPENGL)) + return 0; + extra = bitmap->extra; + return extra->texture; +} + +/* Function: al_remove_opengl_fbo + */ +void al_remove_opengl_fbo(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap; + if (bitmap->parent) + bitmap = bitmap->parent; + if (!(al_get_bitmap_flags(bitmap) & _ALLEGRO_INTERNAL_OPENGL)) + return; + ogl_bitmap = bitmap->extra; + if (!ogl_bitmap->fbo_info) + return; + + ASSERT(ogl_bitmap->fbo_info->fbo_state > FBO_INFO_UNUSED); + ASSERT(ogl_bitmap->fbo_info->fbo != 0); + + ALLEGRO_FBO_INFO *info = ogl_bitmap->fbo_info; + _al_ogl_del_fbo(info); + + if (info->fbo_state == FBO_INFO_PERSISTENT) { + al_free(info); + } + else { + _al_ogl_reset_fbo_info(info); + } +} + +/* Function: al_get_opengl_fbo + */ +GLuint al_get_opengl_fbo(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap; + if (bitmap->parent) + bitmap = bitmap->parent; + + if (!(al_get_bitmap_flags(bitmap) & _ALLEGRO_INTERNAL_OPENGL)) + return 0; + + ogl_bitmap = bitmap->extra; + + if (!ogl_bitmap->fbo_info) { + if (!_al_ogl_create_persistent_fbo(bitmap)) { + return 0; + } + } + + if (ogl_bitmap->fbo_info->fbo_state == FBO_INFO_TRANSIENT) { + ogl_bitmap->fbo_info = _al_ogl_persist_fbo(_al_get_bitmap_display(bitmap), + ogl_bitmap->fbo_info); + } + return ogl_bitmap->fbo_info->fbo; +} + +/* Function: al_get_opengl_texture_size + */ +bool al_get_opengl_texture_size(ALLEGRO_BITMAP *bitmap, int *w, int *h) +{ + /* The designers of OpenGL ES 1.0 forgot to add a function to query + * texture sizes, so this will be the only way there to get the texture + * size. On normal OpenGL also glGetTexLevelParameter could be used. + */ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap; + if (bitmap->parent) + bitmap = bitmap->parent; + + if (!(al_get_bitmap_flags(bitmap) & _ALLEGRO_INTERNAL_OPENGL)) { + *w = 0; + *h = 0; + return false; + } + + ogl_bitmap = bitmap->extra; + *w = ogl_bitmap->true_w; + *h = ogl_bitmap->true_h; + return true; +} + +/* Function: al_get_opengl_texture_position + */ +void al_get_opengl_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v) +{ + ASSERT(bitmap); + ASSERT(u); + ASSERT(v); + + *u = bitmap->xofs; + *v = bitmap->yofs; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/ogl_display.c b/allegro/src/opengl/ogl_display.c new file mode 100644 index 00000000..7ae4db29 --- /dev/null +++ b/allegro/src/opengl/ogl_display.c @@ -0,0 +1,270 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL routines common to all OpenGL drivers. + * + * By Elias Pschernig and Milan Mimica. + * + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/transformations.h" + +#ifdef ALLEGRO_IPHONE +#include "allegro5/internal/aintern_iphone.h" +#endif + +#ifdef ALLEGRO_ANDROID +#include "allegro5/internal/aintern_android.h" +#endif + +#include "ogl_helpers.h" + +ALLEGRO_DEBUG_CHANNEL("opengl") + +/* Helper to set up GL state as we want it. */ +void _al_ogl_setup_gl(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; + + if (ogl->backbuffer) { + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + _al_ogl_resize_backbuffer(ogl->backbuffer, d->w, d->h); + /* If we are currently targetting the backbuffer, we need to update the + * transformations. */ + if (target && (target == ogl->backbuffer || + target->parent == ogl->backbuffer)) { + /* vt should be set at this point, but doesn't hurt to check */ + ASSERT(d->vt); + d->vt->update_transformation(d, target); + } + } else { + ogl->backbuffer = _al_ogl_create_backbuffer(d); + } +} + + +void _al_ogl_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP *target = bitmap; + if (bitmap->parent) + target = bitmap->parent; + + /* if either this bitmap or its parent (in the case of subbitmaps) + * is locked then don't do anything + */ + if (bitmap->locked) + return; + if (bitmap->parent && bitmap->parent->locked) + return; + + _al_ogl_setup_fbo(display, bitmap); + if (display->ogl_extras->opengl_target == target) { + _al_ogl_setup_bitmap_clipping(bitmap); + } +} + + +void _al_ogl_unset_target_bitmap(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *target) +{ + if (!target) + return; + _al_ogl_finalize_fbo(display, target); +} + + +/* Function: al_set_current_opengl_context + */ +void al_set_current_opengl_context(ALLEGRO_DISPLAY *display) +{ + ASSERT(display); + + if (!(display->flags & ALLEGRO_OPENGL)) + return; + + if (display) { + ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); + if (bmp && _al_get_bitmap_display(bmp) && + _al_get_bitmap_display(bmp) != display) { + al_set_target_bitmap(NULL); + } + } + + _al_set_current_display_only(display); +} + + +void _al_ogl_setup_bitmap_clipping(const ALLEGRO_BITMAP *bitmap) +{ + int x_1, y_1, x_2, y_2, h; + bool use_scissor = true; + + x_1 = bitmap->cl; + y_1 = bitmap->ct; + x_2 = bitmap->cr_excl; + y_2 = bitmap->cb_excl; + h = bitmap->h; + + /* Drawing onto the sub bitmap is handled by clipping the parent. */ + if (bitmap->parent) { + x_1 += bitmap->xofs; + y_1 += bitmap->yofs; + x_2 += bitmap->xofs; + y_2 += bitmap->yofs; + h = bitmap->parent->h; + } + + if (x_1 == 0 && y_1 == 0 && x_2 == bitmap->w && y_2 == bitmap->h) { + if (bitmap->parent) { + /* Can only disable scissor if the sub-bitmap covers the + * complete parent. + */ + if (bitmap->xofs == 0 && bitmap->yofs == 0 && + bitmap->w == bitmap->parent->w && bitmap->h == bitmap->parent->h) + { + use_scissor = false; + } + } + else { + use_scissor = false; + } + } + if (!use_scissor) { + glDisable(GL_SCISSOR_TEST); + } + else { + glEnable(GL_SCISSOR_TEST); + + #ifdef ALLEGRO_IPHONE + _al_iphone_clip(bitmap, x_1, y_1, x_2, y_2); + #else + /* OpenGL is upside down, so must adjust y_2 to the height. */ + glScissor(x_1, h - y_2, x_2 - x_1, y_2 - y_1); + #endif + } +} + + +ALLEGRO_BITMAP *_al_ogl_get_backbuffer(ALLEGRO_DISPLAY *d) +{ + return (ALLEGRO_BITMAP *)d->ogl_extras->backbuffer; +} + + +bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP *b, int w, int h) +{ + int pitch; + ALLEGRO_BITMAP_EXTRA_OPENGL *extra = b->extra; + + pitch = w * al_get_pixel_size(al_get_bitmap_format(b)); + + b->w = w; + b->h = h; + b->pitch = pitch; + b->cl = 0; + b->ct = 0; + b->cr_excl = w; + b->cb_excl = h; + al_identity_transform(&b->proj_transform); + al_orthographic_transform(&b->proj_transform, 0, 0, -1.0, w, h, 1.0); + + /* There is no texture associated with the backbuffer so no need to care + * about texture size limitations. */ + extra->true_w = w; + extra->true_h = h; + + b->memory = NULL; + + return true; +} + + +ALLEGRO_BITMAP* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_backbuffer; + ALLEGRO_BITMAP *backbuffer; + int format; + + ALLEGRO_DEBUG("Creating backbuffer\n"); + + // FIXME: _al_deduce_color_format would work fine if the display paramerers + // are filled in, for OpenGL ES + if (IS_OPENGLES) { + if (disp->extra_settings.settings[ALLEGRO_COLOR_SIZE] == 16) { + format = ALLEGRO_PIXEL_FORMAT_RGB_565; + } + else { + format = ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE; + } + } + else { + format = _al_deduce_color_format(&disp->extra_settings); + /* Eww. No OpenGL hardware in the world does that - let's just + * switch to some default. + */ + if (al_get_pixel_size(format) == 3) { + /* Or should we use RGBA? Maybe only if not Nvidia cards? */ + format = ALLEGRO_PIXEL_FORMAT_ABGR_8888; + } + } + ALLEGRO_TRACE_CHANNEL_LEVEL("display", 1)("Deduced format %s for backbuffer.\n", + _al_pixel_format_name(format)); + + /* Now that the display backbuffer has a format, update extra_settings so + * the user can query it back. + */ + _al_set_color_components(format, &disp->extra_settings, ALLEGRO_REQUIRE); + disp->backbuffer_format = format; + + ALLEGRO_DEBUG("Creating backbuffer bitmap\n"); + /* Using ALLEGRO_NO_PRESERVE_TEXTURE prevents extra memory being allocated */ + backbuffer = _al_ogl_create_bitmap(disp, disp->w, disp->h, + format, ALLEGRO_VIDEO_BITMAP | ALLEGRO_NO_PRESERVE_TEXTURE); + if (!backbuffer) { + ALLEGRO_DEBUG("Backbuffer bitmap creation failed.\n"); + return NULL; + } + + backbuffer->w = disp->w; + backbuffer->h = disp->h; + backbuffer->cl = 0; + backbuffer->ct = 0; + backbuffer->cr_excl = disp->w; + backbuffer->cb_excl = disp->h; + al_identity_transform(&backbuffer->transform); + al_identity_transform(&backbuffer->proj_transform); + al_orthographic_transform(&backbuffer->proj_transform, 0, 0, -1.0, disp->w, disp->h, 1.0); + + ALLEGRO_TRACE_CHANNEL_LEVEL("display", 1)( + "Created backbuffer bitmap (actual format: %s)\n", + _al_pixel_format_name(al_get_bitmap_format(backbuffer))); + + ogl_backbuffer = backbuffer->extra; + ogl_backbuffer->true_w = disp->w; + ogl_backbuffer->true_h = disp->h; + ogl_backbuffer->is_backbuffer = 1; + backbuffer->_display = disp; + + return backbuffer; +} + + +void _al_ogl_destroy_backbuffer(ALLEGRO_BITMAP *b) +{ + al_destroy_bitmap(b); +} + + +/* vi: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/ogl_draw.c b/allegro/src/opengl/ogl_draw.c new file mode 100644 index 00000000..4f2b5a8e --- /dev/null +++ b/allegro/src/opengl/ogl_draw.c @@ -0,0 +1,523 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL drawing routines + * + * By Elias Pschernig. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_memdraw.h" +#include "allegro5/internal/aintern_opengl.h" + +#ifdef ALLEGRO_ANDROID +#include "allegro5/internal/aintern_android.h" +#endif + +#include "ogl_helpers.h" + +ALLEGRO_DEBUG_CHANNEL("opengl") + +/* FIXME: For some reason x86_64 Android crashes for me when calling + * glBlendColor - so adding this hack to disable it. + */ +#ifdef ALLEGRO_ANDROID +#if defined(__x86_64__) || defined(__i686__) +#define ALLEGRO_ANDROID_HACK_X86_64 +#endif +#endif + +static void try_const_color(ALLEGRO_DISPLAY *ogl_disp, ALLEGRO_COLOR *c) +{ + #ifdef ALLEGRO_CFG_OPENGLES + #ifndef ALLEGRO_CFG_OPENGLES2 + return; + #endif + // Only OpenGL ES 2.0 has glBlendColor + if (ogl_disp->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_2_0) { + return; + } + #else + (void)ogl_disp; + #endif + glBlendColor(c->r, c->g, c->b, c->a); +} + +bool _al_opengl_set_blender(ALLEGRO_DISPLAY *ogl_disp) +{ + int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR const_color; + const int blend_modes[10] = { + GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, + GL_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, + GL_ONE_MINUS_DST_COLOR, +#if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES) + GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR +#else + GL_ONE, GL_ONE +#endif + }; + const int blend_equations[3] = { + GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT + }; + + (void)ogl_disp; + + al_get_separate_bitmap_blender(&op, &src_color, &dst_color, + &op_alpha, &src_alpha, &dst_alpha); + const_color = al_get_bitmap_blend_color(); + /* glBlendFuncSeparate was only included with OpenGL 1.4 */ +#if !defined ALLEGRO_CFG_OPENGLES + if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) { +#else + /* FIXME: At this time (09/2014) there are a lot of Android phones that + * don't support glBlendFuncSeparate even though they claim OpenGL ES 2.0 + * support. Rather than not work on 20-25% of phones, we just don't support + * separate blending on Android for now. + */ +#if defined ALLEGRO_ANDROID && !defined ALLEGRO_CFG_OPENGLES3 + if (false) { +#else + if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { +#endif +#endif + glEnable(GL_BLEND); + try_const_color(ogl_disp, &const_color); + glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], + blend_modes[src_alpha], blend_modes[dst_alpha]); + if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { + glBlendEquationSeparate( + blend_equations[op], + blend_equations[op_alpha]); + } + else { + glBlendEquation(blend_equations[op]); + } + } + else { + if (src_color == src_alpha && dst_color == dst_alpha) { + glEnable(GL_BLEND); + try_const_color(ogl_disp, &const_color); + glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); + } + else { + ALLEGRO_ERROR("Blender unsupported with this OpenGL version (%d %d %d %d %d %d)\n", + op, src_color, dst_color, op_alpha, src_alpha, dst_alpha); + return false; + } + } + return true; +} + +/* These functions make drawing calls use shaders or the fixed pipeline + * based on what the user has set up. FIXME: OpenGL only right now. + */ + +static void vert_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) +{ +/* Only use this shader stuff with GLES2+ or equivalent */ + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (display->ogl_extras->varlocs.pos_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.pos_loc, n, t, false, stride, v); + glEnableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); + } +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(n, t, stride, v); +#endif + } +} + +static void vert_ptr_off(ALLEGRO_DISPLAY *display) +{ + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (display->ogl_extras->varlocs.pos_loc >= 0) { + glDisableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); + } +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glDisableClientState(GL_VERTEX_ARRAY); +#endif + } +} + +static void color_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) +{ + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (display->ogl_extras->varlocs.color_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.color_loc, n, t, false, stride, v); + glEnableVertexAttribArray(display->ogl_extras->varlocs.color_loc); + } +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(n, t, stride, v); +#endif + } +} + +static void color_ptr_off(ALLEGRO_DISPLAY *display) +{ + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (display->ogl_extras->varlocs.color_loc >= 0) { + glDisableVertexAttribArray(display->ogl_extras->varlocs.color_loc); + } +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glDisableClientState(GL_COLOR_ARRAY); +#endif + } +} + +static void tex_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) +{ + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (display->ogl_extras->varlocs.texcoord_loc >= 0) { + glVertexAttribPointer(display->ogl_extras->varlocs.texcoord_loc, n, t, false, stride, v); + glEnableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); + } +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(n, t, stride, v); +#endif + } +} + +static void tex_ptr_off(ALLEGRO_DISPLAY *display) +{ + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (display->ogl_extras->varlocs.texcoord_loc >= 0) { + glDisableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); + } +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#endif + } +} + +static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color) +{ + ALLEGRO_DISPLAY *ogl_disp = (void *)d; + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target; + float r, g, b, a; + + if (target->parent) + target = target->parent; + + ogl_target = target->extra; + + if ((!ogl_target->is_backbuffer && + ogl_disp->ogl_extras->opengl_target != target) + || target->locked) + { + _al_clear_bitmap_by_locking(target, color); + return; + } + + al_unmap_rgba_f(*color, &r, &g, &b, &a); + + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT); +} + + +static void ogl_draw_pixel(ALLEGRO_DISPLAY *d, float x, float y, + ALLEGRO_COLOR *color) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target; + GLfloat vert[2]; + GLfloat color_array[4]; + + /* For sub-bitmaps */ + if (target->parent) { + target = target->parent; + } + + ogl_target = target->extra; + + if ((!ogl_target->is_backbuffer && + d->ogl_extras->opengl_target != target) || + target->locked || !_al_opengl_set_blender(d)) { + _al_draw_pixel_memory(target, x, y, color); + return; + } + + vert[0] = x; + vert[1] = y; + + color_array[0] = color->r; + color_array[1] = color->g; + color_array[2] = color->b; + color_array[3] = color->a; + + vert_ptr_on(d, 2, GL_FLOAT, 2*sizeof(float), vert); + color_ptr_on(d, 4, GL_FLOAT, 4*sizeof(float), color_array); + + // Should this be here if it's in the if above? + if (!_al_opengl_set_blender(d)) { + return; + } + + glDrawArrays(GL_POINTS, 0, 1); + + vert_ptr_off(d); + color_ptr_off(d); +} + +static void* ogl_prepare_vertex_cache(ALLEGRO_DISPLAY* disp, + int num_new_vertices) +{ + disp->num_cache_vertices += num_new_vertices; + if (!disp->vertex_cache) { + disp->vertex_cache = al_malloc(num_new_vertices * sizeof(ALLEGRO_OGL_BITMAP_VERTEX)); + + disp->vertex_cache_size = num_new_vertices; + } else if (disp->num_cache_vertices > disp->vertex_cache_size) { + disp->vertex_cache = al_realloc(disp->vertex_cache, + 2 * disp->num_cache_vertices * sizeof(ALLEGRO_OGL_BITMAP_VERTEX)); + + disp->vertex_cache_size = 2 * disp->num_cache_vertices; + } + return (ALLEGRO_OGL_BITMAP_VERTEX*)disp->vertex_cache + + (disp->num_cache_vertices - num_new_vertices); +} + +static void ogl_flush_vertex_cache(ALLEGRO_DISPLAY *disp) +{ + GLuint current_texture; + ALLEGRO_OGL_EXTRAS *o = disp->ogl_extras; + (void)o; /* not used in all ports */ + + if (!disp->vertex_cache) + return; + if (disp->num_cache_vertices == 0) + return; + + if (!_al_opengl_set_blender(disp)) { + disp->num_cache_vertices = 0; + return; + } + + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (disp->ogl_extras->varlocs.use_tex_loc >= 0) { + glUniform1i(disp->ogl_extras->varlocs.use_tex_loc, 1); + } + if (disp->ogl_extras->varlocs.use_tex_matrix_loc >= 0) { + glUniform1i(disp->ogl_extras->varlocs.use_tex_matrix_loc, 0); + } +#endif + } + else { + glEnable(GL_TEXTURE_2D); + } + + glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)¤t_texture); + if (current_texture != disp->cache_texture) { + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + /* Use texture unit 0 */ + glActiveTexture(GL_TEXTURE0); + if (disp->ogl_extras->varlocs.tex_loc >= 0) + glUniform1i(disp->ogl_extras->varlocs.tex_loc, 0); +#endif + } + glBindTexture(GL_TEXTURE_2D, disp->cache_texture); + } + +#if !defined(ALLEGRO_CFG_OPENGLES) && !defined(ALLEGRO_MACOSX) + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + int stride = sizeof(ALLEGRO_OGL_BITMAP_VERTEX); + int bytes = disp->num_cache_vertices * stride; + + /* We create the VAO and VBO on first use. */ + if (o->vao == 0) { + glGenVertexArrays(1, &o->vao); + ALLEGRO_DEBUG("new VAO: %u\n", o->vao); + } + glBindVertexArray(o->vao); + + if (o->vbo == 0) { + glGenBuffers(1, &o->vbo); + ALLEGRO_DEBUG("new VBO: %u\n", o->vbo); + } + glBindBuffer(GL_ARRAY_BUFFER, o->vbo); + + /* Then we upload data into it. */ + glBufferData(GL_ARRAY_BUFFER, bytes, disp->vertex_cache, GL_STREAM_DRAW); + + /* Finally set the "pos", "texccord" and "color" attributes used by our + * shader and enable them. + */ + if (o->varlocs.pos_loc >= 0) { + glVertexAttribPointer(o->varlocs.pos_loc, 3, GL_FLOAT, false, stride, + (void *)offsetof(ALLEGRO_OGL_BITMAP_VERTEX, x)); + glEnableVertexAttribArray(o->varlocs.pos_loc); + } + + if (o->varlocs.texcoord_loc >= 0) { + glVertexAttribPointer(o->varlocs.texcoord_loc, 2, GL_FLOAT, false, stride, + (void *)offsetof(ALLEGRO_OGL_BITMAP_VERTEX, tx)); + glEnableVertexAttribArray(o->varlocs.texcoord_loc); + } + + if (o->varlocs.color_loc >= 0) { + glVertexAttribPointer(o->varlocs.color_loc, 4, GL_FLOAT, false, stride, + (void *)offsetof(ALLEGRO_OGL_BITMAP_VERTEX, r)); + glEnableVertexAttribArray(o->varlocs.color_loc); + } + } + else +#endif + { + vert_ptr_on(disp, 3, GL_FLOAT, sizeof(ALLEGRO_OGL_BITMAP_VERTEX), + (char *)(disp->vertex_cache) + offsetof(ALLEGRO_OGL_BITMAP_VERTEX, x)); + tex_ptr_on(disp, 2, GL_FLOAT, sizeof(ALLEGRO_OGL_BITMAP_VERTEX), + (char*)(disp->vertex_cache) + offsetof(ALLEGRO_OGL_BITMAP_VERTEX, tx)); + color_ptr_on(disp, 4, GL_FLOAT, sizeof(ALLEGRO_OGL_BITMAP_VERTEX), + (char*)(disp->vertex_cache) + offsetof(ALLEGRO_OGL_BITMAP_VERTEX, r)); + +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + if (!(disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) + glDisableClientState(GL_NORMAL_ARRAY); +#endif + } + + glGetError(); /* clear error */ + glDrawArrays(GL_TRIANGLES, 0, disp->num_cache_vertices); + +#ifdef DEBUGMODE + { + int e = glGetError(); + if (e) { + ALLEGRO_WARN("glDrawArrays failed: %s\n", _al_gl_error_string(e)); + } + } +#endif + +#if !defined ALLEGRO_CFG_OPENGLES && !defined ALLEGRO_MACOSX + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + if (o->varlocs.pos_loc >= 0) + glDisableVertexAttribArray(o->varlocs.pos_loc); + if (o->varlocs.texcoord_loc >= 0) + glDisableVertexAttribArray(o->varlocs.texcoord_loc); + if (o->varlocs.color_loc >= 0) + glDisableVertexAttribArray(o->varlocs.color_loc); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + } + else +#endif + { + vert_ptr_off(disp); + tex_ptr_off(disp); + color_ptr_off(disp); + } + + disp->num_cache_vertices = 0; + + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE + if (disp->ogl_extras->varlocs.use_tex_loc >= 0) + glUniform1i(disp->ogl_extras->varlocs.use_tex_loc, 0); +#endif + } + else { + glDisable(GL_TEXTURE_2D); + } +} + +static void ogl_update_transformation(ALLEGRO_DISPLAY* disp, + ALLEGRO_BITMAP *target) +{ + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_SHADER_GLSL + GLint loc = disp->ogl_extras->varlocs.projview_matrix_loc; + ALLEGRO_TRANSFORM projview; + al_copy_transform(&projview, &target->transform); + al_compose_transform(&projview, &target->proj_transform); + al_copy_transform(&disp->projview_transform, &projview); + + if (disp->ogl_extras->program_object > 0 && loc >= 0) { + _al_glsl_set_projview_matrix(loc, &disp->projview_transform); + } +#endif + } else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((float *)target->proj_transform.m); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf((float *)target->transform.m); +#endif + } + + if (target->parent) { + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_extra = target->parent->extra; + /* glViewport requires the bottom-left coordinate of the corner. */ + glViewport(target->xofs, ogl_extra->true_h - (target->yofs + target->h), target->w, target->h); + } else { + glViewport(0, 0, target->w, target->h); + } +} + +static void ogl_clear_depth_buffer(ALLEGRO_DISPLAY *display, float x) +{ + (void)display; + +#if defined(ALLEGRO_CFG_OPENGLES) + glClearDepthf(x); +#else + glClearDepth(x); +#endif + + /* We may want to defer this to the next glClear call as a combined + * color/depth clear may be faster. + */ + glClear(GL_DEPTH_BUFFER_BIT); +} + +/* Add drawing commands to the vtable. */ +void _al_ogl_add_drawing_functions(ALLEGRO_DISPLAY_INTERFACE *vt) +{ + vt->clear = ogl_clear; + vt->draw_pixel = ogl_draw_pixel; + vt->clear_depth_buffer = ogl_clear_depth_buffer; + + vt->flush_vertex_cache = ogl_flush_vertex_cache; + vt->prepare_vertex_cache = ogl_prepare_vertex_cache; + vt->update_transformation = ogl_update_transformation; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/ogl_fbo.c b/allegro/src/opengl/ogl_fbo.c new file mode 100644 index 00000000..c6dda63b --- /dev/null +++ b/allegro/src/opengl/ogl_fbo.c @@ -0,0 +1,669 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL framebuffer objects. + * + * See LICENSE.txt for copyright information. + */ + +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_pixels.h" + +#ifdef ALLEGRO_ANDROID + #include "allegro5/internal/aintern_android.h" +#elif defined ALLEGRO_IPHONE + #include "allegro5/internal/aintern_iphone.h" +#endif + +#include "ogl_helpers.h" + +ALLEGRO_DEBUG_CHANNEL("opengl") + + +/* forward declarations */ +static void setup_fbo_backbuffer(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap); +static void use_fbo_for_bitmap(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap, ALLEGRO_FBO_INFO *info); + + +/* glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT..) not supported on some Androids. + * We keep track of it manually. + */ +#ifdef ALLEGRO_ANDROID + +static GLint _al_gl_curr_fbo = 0; + +GLint _al_android_get_curr_fbo(void) +{ + return _al_gl_curr_fbo; +} + +void _al_android_set_curr_fbo(GLint fbo) +{ + _al_gl_curr_fbo = fbo; +} + +GLint _al_ogl_bind_framebuffer(GLint fbo) +{ + GLint old_fbo = _al_android_get_curr_fbo(); + GLint e; + + if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + } + else { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + } + e = glGetError(); + if (e) { + ALLEGRO_DEBUG("glBindFramebufferEXT failed (%s)", + _al_gl_error_string(e)); + } + _al_android_set_curr_fbo(fbo); + return old_fbo; +} + +#else /* !ALLEGRO_ANDROID */ + +GLint _al_ogl_bind_framebuffer(GLint fbo) +{ + GLint old_fbo; + glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &old_fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + return old_fbo; +} + +#endif /* !ALLEGRO_ANDROID */ + + +void _al_ogl_reset_fbo_info(ALLEGRO_FBO_INFO *info) +{ + info->fbo_state = FBO_INFO_UNUSED; + info->fbo = 0; + info->buffers.depth_buffer = 0; + info->buffers.multisample_buffer = 0; + info->buffers.dw = 0; + info->buffers.dh = 0; + info->buffers.mw = 0; + info->buffers.mh = 0; + info->owner = NULL; + info->last_use_time = 0.0; +} + + +#if (!defined ALLEGRO_CFG_OPENGLES) || defined ALLEGRO_CFG_OPENGLES3 +static void check_gl_error(void) +{ + GLint e = glGetError(); + if (e) { + ALLEGRO_ERROR("OpenGL call failed! (%s)\n", + _al_gl_error_string(e)); + } +} +#endif + + +static void detach_depth_buffer(ALLEGRO_FBO_INFO *info) +{ +#ifndef ALLEGRO_RASPBERRYPI + if (info->buffers.depth_buffer == 0) + return; + ALLEGRO_DEBUG("Deleting depth render buffer: %u\n", + info->buffers.depth_buffer); + glDeleteRenderbuffersEXT(1, &info->buffers.depth_buffer); + info->buffers.depth_buffer = 0; + info->buffers.dw = 0; + info->buffers.dh = 0; + info->buffers.depth = 0; +#endif +} + + +static void detach_multisample_buffer(ALLEGRO_FBO_INFO *info) +{ +#ifndef ALLEGRO_RASPBERRYPI + if (info->buffers.multisample_buffer == 0) + return; + ALLEGRO_DEBUG("Deleting multisample render buffer: %u\n", + info->buffers.depth_buffer); + glDeleteRenderbuffersEXT(1, &info->buffers.multisample_buffer); + info->buffers.multisample_buffer = 0; + info->buffers.mw = 0; + info->buffers.mh = 0; + info->buffers.samples = 0; +#endif +} + + + +static void attach_depth_buffer(ALLEGRO_FBO_INFO *info) +{ +#if !defined ALLEGRO_RASPBERRYPI + GLuint rb; + GLenum gldepth = GL_DEPTH_COMPONENT16; + + ALLEGRO_BITMAP *b = info->owner; + int bits = al_get_bitmap_depth(b); + + if (info->buffers.depth_buffer != 0) { + + if (info->buffers.depth != bits || + info->buffers.dw != al_get_bitmap_width(b) || + info->buffers.dh != al_get_bitmap_height(b)) { + detach_depth_buffer(info); + } + } + + if (!bits) + return; + + if (info->buffers.depth_buffer == 0) { + ALLEGRO_DISPLAY *display = _al_get_bitmap_display(info->owner); + int w = al_get_bitmap_width(info->owner); + int h = al_get_bitmap_height(info->owner); + +#if !defined ALLEGRO_CFG_OPENGLES || defined ALLEGRO_CFG_OPENGLES3 + if (bits == 24) gldepth = GL_DEPTH_COMPONENT24; +#endif + + glGenRenderbuffersEXT(1, &rb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); + + int samples = al_get_bitmap_samples(info->owner); + + bool extension_supported; +#ifdef ALLEGRO_CFG_OPENGLES + (void)display; + extension_supported = al_have_opengl_extension("EXT_multisampled_render_to_texture"); +#else + extension_supported = display->ogl_extras->extension_list->ALLEGRO_GL_EXT_framebuffer_multisample; +#endif + + if (samples == 0 || !extension_supported) + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, gldepth, w, h); +#if !defined ALLEGRO_CFG_OPENGLES || defined ALLEGRO_CFG_OPENGLES3 + else + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, + samples, gldepth, w, h); +#else + else { + return; + } +#endif + + info->buffers.depth_buffer = rb; + info->buffers.dw = w; + info->buffers.dh = h; + info->buffers.depth = bits; + GLint e = glGetError(); + if (e) { + ALLEGRO_ERROR("glRenderbufferStorage failed! bits=%d w=%d h=%d (%s)\n", + bits, w, h, _al_gl_error_string(e)); + } + else { + ALLEGRO_DEBUG("Depth render buffer created: %u\n", + info->buffers.depth_buffer); + } + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, rb); + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { + ALLEGRO_ERROR("attaching depth renderbuffer failed\n"); + } + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } +#endif +} + + +static void attach_multisample_buffer(ALLEGRO_FBO_INFO *info) +{ +#if !defined ALLEGRO_CFG_OPENGLES || defined ALLEGRO_CFG_OPENGLES3 + ALLEGRO_BITMAP *b = info->owner; + int samples = al_get_bitmap_samples(b); + + if (info->buffers.multisample_buffer != 0) { + + if (info->buffers.samples != samples || + info->buffers.mw != al_get_bitmap_width(b) || + info->buffers.mh != al_get_bitmap_height(b)) { + detach_multisample_buffer(info); + } + } + + if (!samples) + return; + ALLEGRO_DISPLAY *display = _al_get_bitmap_display(info->owner); + if (!display->ogl_extras->extension_list->ALLEGRO_GL_EXT_framebuffer_multisample) + return; + +#ifdef ALLEGRO_CFG_OPENGLES + (void)display; +#else + + if (info->buffers.multisample_buffer == 0) { + GLuint rb; + GLint e; + int w = al_get_bitmap_width(info->owner); + int h = al_get_bitmap_height(info->owner); + + glGenRenderbuffersEXT(1, &rb); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb); + check_gl_error(); + + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, + samples, _al_ogl_get_glformat( + al_get_bitmap_format(info->owner), 0), w, h); + info->buffers.multisample_buffer = rb; + info->buffers.mw = w; + info->buffers.mh = h; + info->buffers.samples = samples; + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glRenderbufferStorage failed! samples=%d w=%d h=%d (%s)\n", + samples, w, h, _al_gl_error_string(e)); + } + else { + ALLEGRO_DEBUG("Multisample render buffer created: %u\n", + info->buffers.multisample_buffer); + } + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rb); + + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { + ALLEGRO_ERROR("attaching multisample renderbuffer failed\n"); + } + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + #endif +#else + (void)info; +#endif +} + + +bool _al_ogl_create_persistent_fbo(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap; + ALLEGRO_FBO_INFO *info; + GLint old_fbo, e; + + if (bitmap->parent) + bitmap = bitmap->parent; + ogl_bitmap = bitmap->extra; + + /* Don't continue if the bitmap does not belong to the current display. */ + if (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false && + _al_get_bitmap_display(bitmap) != al_get_current_display()) { + return false; + } + + if (ogl_bitmap->is_backbuffer) { + return false; + } + + ASSERT(!ogl_bitmap->fbo_info); + + info = al_malloc(sizeof(ALLEGRO_FBO_INFO)); + info->owner = bitmap; + if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) { + glGenFramebuffers(1, &info->fbo); + } + else { + glGenFramebuffersEXT(1, &info->fbo); + } + if (info->fbo == 0) { + al_free(info); + return false; + } + + old_fbo = _al_ogl_bind_framebuffer(info->fbo); + + if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, ogl_bitmap->texture, 0); + } + else { + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, ogl_bitmap->texture, 0); + } + + e = glGetError(); + if (e) { + ALLEGRO_DEBUG("glFrameBufferTexture2DEXT failed! fbo=%d texture=%d (%s)\n", + info->fbo, ogl_bitmap->texture, _al_gl_error_string(e)); + } + + attach_depth_buffer(info); + + /* You'll see this a couple times in this file: some ES 1.1 functions aren't + * implemented on Android. This is an ugly workaround. + */ + if (UNLESS_ANDROID_OR_RPI( + glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)) + { + ALLEGRO_ERROR("FBO incomplete.\n"); + _al_ogl_bind_framebuffer(old_fbo); + glDeleteFramebuffersEXT(1, &info->fbo); + al_free(info); + return false; + } + + _al_ogl_bind_framebuffer(old_fbo); + + info->fbo_state = FBO_INFO_PERSISTENT; + info->last_use_time = al_get_time(); + ogl_bitmap->fbo_info = info; + ALLEGRO_DEBUG("Persistent FBO: %u\n", info->fbo); + return true; +} + + +ALLEGRO_FBO_INFO *_al_ogl_persist_fbo(ALLEGRO_DISPLAY *display, + ALLEGRO_FBO_INFO *transient_fbo_info) +{ + ALLEGRO_OGL_EXTRAS *extras = display->ogl_extras; + int i; + ASSERT(transient_fbo_info->fbo_state == FBO_INFO_TRANSIENT); + + for (i = 0; i < ALLEGRO_MAX_OPENGL_FBOS; i++) { + if (transient_fbo_info == &extras->fbos[i]) { + ALLEGRO_FBO_INFO *new_info = al_malloc(sizeof(ALLEGRO_FBO_INFO)); + *new_info = *transient_fbo_info; + new_info->fbo_state = FBO_INFO_PERSISTENT; + _al_ogl_reset_fbo_info(transient_fbo_info); + ALLEGRO_DEBUG("Persistent FBO: %u\n", new_info->fbo); + return new_info; + } + } + + ALLEGRO_ERROR("Could not find FBO %u in pool\n", transient_fbo_info->fbo); + return transient_fbo_info; +} + + +static ALLEGRO_FBO_INFO *ogl_find_unused_fbo(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_OGL_EXTRAS *extras = display->ogl_extras; + double min_time = DBL_MAX; + int min_time_index = -1; + int i; + + for (i = 0; i < ALLEGRO_MAX_OPENGL_FBOS; i++) { + if (extras->fbos[i].fbo_state == FBO_INFO_UNUSED) + return &extras->fbos[i]; + if (extras->fbos[i].last_use_time < min_time) { + min_time = extras->fbos[i].last_use_time; + min_time_index = i; + } + } + + return &extras->fbos[min_time_index]; +} + + +void _al_ogl_del_fbo(ALLEGRO_FBO_INFO *info) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *extra = info->owner->extra; + extra->fbo_info = NULL; + ALLEGRO_DEBUG("Deleting FBO: %u\n", info->fbo); + if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) { + glDeleteFramebuffers(1, &info->fbo); + } + else { + glDeleteFramebuffersEXT(1, &info->fbo); + } + + detach_depth_buffer(info); + detach_multisample_buffer(info); + + info->fbo = 0; +} + + +static ALLEGRO_FBO_INFO *ogl_new_fbo(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_FBO_INFO *info; + GLint e; + + info = ogl_find_unused_fbo(display); + ASSERT(info->fbo_state != FBO_INFO_PERSISTENT); + + if (info->fbo_state == FBO_INFO_TRANSIENT) { + _al_ogl_del_fbo(info); + _al_ogl_reset_fbo_info(info); + } + else { + /* FBO_INFO_UNUSED */ + } + + if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) { + glGenFramebuffers(1, &info->fbo); + } + else { + glGenFramebuffersEXT(1, &info->fbo); + } + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glGenFramebuffersEXT failed\n"); + _al_ogl_reset_fbo_info(info); + return NULL; + } + + ALLEGRO_DEBUG("Created FBO: %u\n", info->fbo); + return info; +} + + +void _al_ogl_setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap; + + if (bitmap->parent) + bitmap = bitmap->parent; + ogl_bitmap = bitmap->extra; + + /* We can't return here. Target's FBO can be taken away by locking + * a lot of bitmaps consecutively. + * Also affects ex_multiwin; resizing one window affects the other. + */ + if (false && display->ogl_extras->opengl_target == bitmap) + return; + + _al_ogl_unset_target_bitmap(display, display->ogl_extras->opengl_target); + + if (ogl_bitmap->is_backbuffer) + setup_fbo_backbuffer(display, bitmap); + else + _al_ogl_setup_fbo_non_backbuffer(display, bitmap); +} + + +/* With the framebuffer_multisample extension, the absolutely one and + * only way to ever access the multisample buffer is with the + * framebuffer_blit extension. [1] + * + * This is what we do in this function - if there is a multisample + * buffer, downsample it back into the texture. + * + * [1] https://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt + */ +void _al_ogl_finalize_fbo(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *extra = bitmap->extra; + if (!extra) + return; + ALLEGRO_FBO_INFO *info = extra->fbo_info; + (void)display; + if (!info) + return; + if (!info->buffers.multisample_buffer) + return; + #ifndef ALLEGRO_CFG_OPENGLES + int w = al_get_bitmap_width(bitmap); + int h = al_get_bitmap_height(bitmap); + + GLuint blit_fbo; + glGenFramebuffersEXT(1, &blit_fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blit_fbo); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, extra->texture, 0); + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, info->fbo); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, blit_fbo); + glBlitFramebufferEXT(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST); + check_gl_error(); + + glDeleteFramebuffersEXT(1, &blit_fbo); + #else + (void)bitmap; + #endif +} + + +static void setup_fbo_backbuffer(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap) +{ + display->ogl_extras->opengl_target = bitmap; + + // The IS_OPENGLES part is a hack. + if (IS_OPENGLES || + display->ogl_extras->extension_list->ALLEGRO_GL_EXT_framebuffer_object || + display->ogl_extras->extension_list->ALLEGRO_GL_OES_framebuffer_object) + { + _al_ogl_bind_framebuffer(0); + } + +#ifdef ALLEGRO_IPHONE + _al_iphone_setup_opengl_view(display, false); +#endif +} + + +bool _al_ogl_setup_fbo_non_backbuffer(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra; + ALLEGRO_FBO_INFO *info; + + ASSERT(bitmap->parent == NULL); + + /* When a bitmap is set as target bitmap, we try to create an FBO for it. */ + info = ogl_bitmap->fbo_info; + if (!info) { + /* FIXME The IS_OPENGLES part is quite a hack but I don't know how the + * Allegro extension manager works to fix this properly (getting + * extensions properly reported on iphone). All iOS devices support + * FBOs though (currently.) + */ + if (IS_OPENGLES || + al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object || + al_get_opengl_extension_list()->ALLEGRO_GL_OES_framebuffer_object) + { + info = ogl_new_fbo(display); + } + } + + if (!info || info->fbo == 0) { + return false; + } + + use_fbo_for_bitmap(display, bitmap, info); + return true; /* state changed */ +} + + +static void use_fbo_for_bitmap(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap, ALLEGRO_FBO_INFO *info) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra; + GLint e; + + if (info->fbo_state == FBO_INFO_UNUSED) + info->fbo_state = FBO_INFO_TRANSIENT; + info->owner = bitmap; + info->last_use_time = al_get_time(); + ogl_bitmap->fbo_info = info; + + /* Bind to the FBO. */ + _al_ogl_bind_framebuffer(info->fbo); + + attach_multisample_buffer(info); + attach_depth_buffer(info); + + /* If we have a multisample renderbuffer, we can only syncronize + * it back to the texture once we stop drawing into it - i.e. + * when the target bitmap is changed to something else. + */ + if (!info->buffers.multisample_buffer) { + + /* Attach the texture. */ +#ifdef ALLEGRO_CFG_OPENGLES + if (ANDROID_PROGRAMMABLE_PIPELINE(al_get_current_display())) { + if (al_get_bitmap_samples(bitmap) == 0 || !al_have_opengl_extension("EXT_multisampled_render_to_texture")) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, ogl_bitmap->texture, 0); + } +#if ((!defined ALLEGRO_CFG_OPENGLES || defined ALLEGRO_CFG_OPENGLES3) && !defined ALLEGRO_IPHONE) + else { + glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ogl_bitmap->texture, + 0, al_get_bitmap_samples(bitmap)); + + } +#endif + } + else +#endif + { + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, ogl_bitmap->texture, 0); + } + + e = glGetError(); + if (e) { + ALLEGRO_DEBUG("glFrameBufferTexture2DEXT failed! fbo=%d texture=%d (%s)\n", + info->fbo, ogl_bitmap->texture, _al_gl_error_string(e)); + } + } + + /* See comment about unimplemented functions on Android above */ + if (UNLESS_ANDROID_OR_RPI( + glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)) + { + /* For some reason, we cannot use the FBO with this + * texture. So no reason to keep re-trying, output a log + * message and switch to (extremely slow) software mode. + */ + ALLEGRO_ERROR("Could not use FBO for bitmap with format %s.\n", + _al_pixel_format_name(al_get_bitmap_format(bitmap))); + ALLEGRO_ERROR("*** SWITCHING TO SOFTWARE MODE ***\n"); + _al_ogl_bind_framebuffer(0); + glDeleteFramebuffersEXT(1, &info->fbo); + _al_ogl_reset_fbo_info(info); + ogl_bitmap->fbo_info = NULL; + } + else { + display->ogl_extras->opengl_target = bitmap; + } +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/ogl_helpers.h b/allegro/src/opengl/ogl_helpers.h new file mode 100644 index 00000000..4fd51dcf --- /dev/null +++ b/allegro/src/opengl/ogl_helpers.h @@ -0,0 +1,96 @@ +#ifndef __al_included_ogl_helpers_h +#define __al_included_ogl_helpers_h + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" + +/* Some definitions to smooth out the code in the opengl directory. */ + +#ifdef ALLEGRO_CFG_OPENGLES + #define IS_OPENGLES (true) +#else + #define IS_OPENGLES (false) +#endif + +#ifdef ALLEGRO_IPHONE + #define IS_IPHONE (true) +#else + #define IS_IPHONE (false) +#endif + +#ifdef ALLEGRO_ANDROID + #define IS_ANDROID (true) + #define IS_ANDROID_AND(x) (x) +#else + #define IS_ANDROID (false) + #define IS_ANDROID_AND(x) (false) +#endif + +#ifdef ALLEGRO_RASPBERRYPI + #define IS_RASPBERRYPI (true) +#else + #define IS_RASPBERRYPI (false) +#endif + +#if defined(ALLEGRO_ANDROID) || defined(ALLEGRO_RASPBERRYPI) + #define UNLESS_ANDROID_OR_RPI(x) (0) +#else + #define UNLESS_ANDROID_OR_RPI(x) (x) +#endif + +/* Android uses different functions/symbol names depending on ES version */ +#define ANDROID_PROGRAMMABLE_PIPELINE(dpy) \ + IS_ANDROID_AND(al_get_display_flags(dpy) & ALLEGRO_PROGRAMMABLE_PIPELINE) + +#if defined ALLEGRO_CFG_OPENGLES2 + #define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0 + #define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING + #define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE + #define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER + #define GL_RENDERBUFFER_EXT GL_RENDERBUFFER + #define GL_DEPTH_ATTACHMENT_EXT GL_DEPTH_ATTACHMENT + #define glBindFramebufferEXT glBindFramebuffer + #define glCheckFramebufferStatusEXT glCheckFramebufferStatus + #define glDeleteFramebuffersEXT glDeleteFramebuffers + #define glFramebufferTexture2DEXT glFramebufferTexture2D + #define glGenFramebuffersEXT glGenFramebuffers + #define glGenerateMipmapEXT glGenerateMipmap + #define glOrtho glOrthof + #define glGenRenderbuffersEXT glGenRenderbuffers + #define glBindRenderbufferEXT glBindRenderbuffer + #define glRenderbufferStorageEXT glRenderbufferStorage + #define glFramebufferRenderbufferEXT glFramebufferRenderbuffer + #define glDeleteRenderbuffersEXT glDeleteRenderbuffers + #define GL_DEPTH_ATTACHMENT_EXT GL_DEPTH_ATTACHMENT +#elif defined ALLEGRO_CFG_OPENGLES + /* Note: This works because all the constants are the same, e.g. + * GL_FRAMEBUFFER_OES == GL_FRAMEBUFFER_EXT == 0x8D40 + * And so we can use the OpenGL framebuffer extension in the same was + * as the OpenGL ES framebuffer extension. + */ +#ifndef GL_EXT_draw_buffers + #define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0_OES +#endif + #define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_OES + #define GL_FRAMEBUFFER_COMPLETE_EXT GL_FRAMEBUFFER_COMPLETE_OES + #define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES + #define GL_RENDERBUFFER_EXT GL_RENDERBUFFER_OES + #define GL_DEPTH_ATTACHMENT_EXT GL_DEPTH_ATTACHMENT_OES + + #define glBindFramebufferEXT glBindFramebufferOES + #define glCheckFramebufferStatusEXT glCheckFramebufferStatusOES + #define glDeleteFramebuffersEXT glDeleteFramebuffersOES + #define glFramebufferTexture2DEXT glFramebufferTexture2DOES + #define glGenFramebuffersEXT glGenFramebuffersOES + #define glGenerateMipmapEXT glGenerateMipmapOES + #define glGenRenderbuffersEXT glGenRenderbuffersOES + #define glBindRenderbufferEXT glBindRenderbufferOES + #define glRenderbufferStorageEXT glRenderbufferStorageOES + #define glFramebufferRenderbufferEXT glFramebufferRenderbufferOES + #define glOrtho glOrthof + #define glDeleteRenderbuffersEXT glDeleteRenderbuffersOES +#endif + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/ogl_lock.c b/allegro/src/opengl/ogl_lock.c new file mode 100644 index 00000000..4c048f65 --- /dev/null +++ b/allegro/src/opengl/ogl_lock.c @@ -0,0 +1,701 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL bitmap locking. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_pixels.h" + +/* + * This is an attempt to refactor ogl_lock_region and ogl_unlock_region. + * To begin with it only supports desktop OpenGL. Support for mobile platforms + * should be migrated here gradually, but PLEASE try not to do it by inserting + * #ifdefs everywhere. Combined with huge functions, that made the previous + * version very hard to follow and prone to break. + */ +#if !defined(ALLEGRO_CFG_OPENGLES) + +ALLEGRO_DEBUG_CHANNEL("opengl") + +#define get_glformat(f, c) _al_ogl_get_glformat((f), (c)) + + +/* + * Helpers - duplicates code in ogl_bitmap.c for now + */ + +static int ogl_pixel_alignment(int pixel_size) +{ + /* Valid alignments are: 1, 2, 4, 8 bytes. */ + switch (pixel_size) { + case 1: + case 2: + case 4: + case 8: + return pixel_size; + case 3: + return 1; + case 16: /* float32 */ + return 4; + default: + ASSERT(false); + return 4; + } +} + +static int ogl_pitch(int w, int pixel_size) +{ + int pitch = w * pixel_size; + return pitch; +} + +static bool exactly_15bpp(int pixel_format) +{ + return pixel_format == ALLEGRO_PIXEL_FORMAT_RGB_555 + || pixel_format == ALLEGRO_PIXEL_FORMAT_BGR_555; +} + + + +/* + * Locking + */ + +static bool ogl_lock_region_backbuffer( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format, int flags); +static bool ogl_lock_region_nonbb_writeonly( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format); +static bool ogl_lock_region_nonbb_readwrite( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format, bool* restore_fbo); +static bool ogl_lock_region_nonbb_readwrite_fbo( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format); +static bool ogl_lock_region_nonbb_readwrite_nonfbo( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format); + + +ALLEGRO_LOCKED_REGION *_al_ogl_lock_region_new(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int format, int flags) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL * const ogl_bitmap = bitmap->extra; + const GLint gl_y = bitmap->h - y - h; + ALLEGRO_DISPLAY *disp; + ALLEGRO_DISPLAY *old_disp = NULL; + ALLEGRO_BITMAP *old_target = al_get_target_bitmap(); + GLenum e; + bool ok; + bool restore_fbo = false; + bool reset_alignment = false; + + if (format == ALLEGRO_PIXEL_FORMAT_ANY) { + /* Never pick compressed formats with ANY, as it interacts weirdly with + * existing code (e.g. al_get_pixel_size() etc) */ + int bitmap_format = al_get_bitmap_format(bitmap); + if (_al_pixel_format_is_compressed(bitmap_format)) { + // XXX Get a good format from the driver? + format = ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE; + } + else { + format = bitmap_format; + } + } + + disp = al_get_current_display(); + format = _al_get_real_pixel_format(disp, format); + + /* Change OpenGL context if necessary. */ + if (!disp || + (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false && + _al_get_bitmap_display(bitmap) != disp)) + { + old_disp = disp; + _al_set_current_display_only(_al_get_bitmap_display(bitmap)); + } + + ok = true; + + /* Set up the pixel store state. We will need to match it when unlocking. + * There may be other pixel store state we should be setting. + * See also pitfalls 7 & 8 from: + * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ + */ + int previous_alignment; + glGetIntegerv(GL_PACK_ALIGNMENT, &previous_alignment); + { + const int pixel_size = al_get_pixel_size(format); + const int pixel_alignment = ogl_pixel_alignment(pixel_size); + if (previous_alignment != pixel_alignment) { + reset_alignment = true; + glPixelStorei(GL_PACK_ALIGNMENT, pixel_alignment); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glPixelStorei(GL_PACK_ALIGNMENT, %d) failed (%s).\n", + pixel_alignment, _al_gl_error_string(e)); + ok = false; + } + } + } + + if (ok) { + if (ogl_bitmap->is_backbuffer) { + ALLEGRO_DEBUG("Locking backbuffer\n"); + ok = ogl_lock_region_backbuffer(bitmap, ogl_bitmap, + x, gl_y, w, h, format, flags); + } + else if (flags & ALLEGRO_LOCK_WRITEONLY) { + ALLEGRO_DEBUG("Locking non-backbuffer WRITEONLY\n"); + ok = ogl_lock_region_nonbb_writeonly(bitmap, ogl_bitmap, + x, gl_y, w, h, format); + } + else { + ALLEGRO_DEBUG("Locking non-backbuffer READWRITE\n"); + ok = ogl_lock_region_nonbb_readwrite(bitmap, ogl_bitmap, + x, gl_y, w, h, format, &restore_fbo); + } + } + + if (reset_alignment) { + glPixelStorei(GL_PACK_ALIGNMENT, previous_alignment); + } + + /* Restore state after switching FBO. */ + if (restore_fbo) { + if (!old_target) { + /* Old target was NULL; release the context. */ + _al_set_current_display_only(NULL); + } + else if (!_al_get_bitmap_display(old_target)) { + /* Old target was memory bitmap; leave the current display alone. */ + } + else if (old_target != bitmap) { + /* Old target was another OpenGL bitmap. */ + _al_ogl_setup_fbo(_al_get_bitmap_display(old_target), old_target); + } + } + + ASSERT(al_get_target_bitmap() == old_target); + + if (old_disp != NULL) { + _al_set_current_display_only(old_disp); + } + + if (ok) { + return &bitmap->locked_region; + } + + ALLEGRO_ERROR("Failed to lock region\n"); + ASSERT(ogl_bitmap->lock_buffer == NULL); + return NULL; +} + + +static bool ogl_lock_region_backbuffer( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format, int flags) +{ + const int pixel_size = al_get_pixel_size(format); + const int pitch = ogl_pitch(w, pixel_size); + GLenum e; + + ogl_bitmap->lock_buffer = al_malloc(pitch * h); + if (ogl_bitmap->lock_buffer == NULL) { + return false; + } + + if (!(flags & ALLEGRO_LOCK_WRITEONLY)) { + glReadPixels(x, gl_y, w, h, + get_glformat(format, 2), + get_glformat(format, 1), + ogl_bitmap->lock_buffer); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n", + _al_pixel_format_name(format), _al_gl_error_string(e)); + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; + return false; + } + } + + bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1); + bitmap->locked_region.format = format; + bitmap->locked_region.pitch = -pitch; + bitmap->locked_region.pixel_size = pixel_size; + return true; +} + + +static bool ogl_lock_region_nonbb_writeonly( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format) +{ + const int pixel_size = al_get_pixel_size(format); + const int pitch = ogl_pitch(w, pixel_size); + (void) x; + (void) gl_y; + + ogl_bitmap->lock_buffer = al_malloc(pitch * h); + if (ogl_bitmap->lock_buffer == NULL) { + return false; + } + + bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1); + bitmap->locked_region.format = format; + bitmap->locked_region.pitch = -pitch; + bitmap->locked_region.pixel_size = pixel_size; + return true; +} + + +static bool ogl_lock_region_nonbb_readwrite( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format, bool* restore_fbo) +{ + bool ok; + + ASSERT(bitmap->parent == NULL); + ASSERT(bitmap->locked == false); + ASSERT(_al_get_bitmap_display(bitmap) == al_get_current_display()); + + /* Try to create an FBO if there isn't one. */ + *restore_fbo = + _al_ogl_setup_fbo_non_backbuffer(_al_get_bitmap_display(bitmap), bitmap); + + if (ogl_bitmap->fbo_info) { + ALLEGRO_DEBUG("Locking non-backbuffer READWRITE with fbo\n"); + ok = ogl_lock_region_nonbb_readwrite_fbo(bitmap, ogl_bitmap, + x, gl_y, w, h, format); + } + else { + ALLEGRO_DEBUG("Locking non-backbuffer READWRITE no fbo\n"); + ok = ogl_lock_region_nonbb_readwrite_nonfbo(bitmap, ogl_bitmap, + x, gl_y, w, h, format); + } + + return ok; +} + + +static bool ogl_lock_region_nonbb_readwrite_fbo( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format) +{ + const int pixel_size = al_get_pixel_size(format); + const int pitch = ogl_pitch(w, pixel_size); + GLint old_fbo; + GLenum e; + bool ok; + + glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &old_fbo); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT) failed (%s).\n", + _al_gl_error_string(e)); + return false; + } + + ok = true; + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ogl_bitmap->fbo_info->fbo); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glBindFramebufferEXT failed (%s).\n", + _al_gl_error_string(e)); + ok = false; + } + + if (ok) { + ogl_bitmap->lock_buffer = al_malloc(pitch * h); + if (ogl_bitmap->lock_buffer == NULL) { + ok = false; + } + } + + if (ok) { + glReadPixels(x, gl_y, w, h, + get_glformat(format, 2), + get_glformat(format, 1), + ogl_bitmap->lock_buffer); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n", + _al_pixel_format_name(format), _al_gl_error_string(e)); + } + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fbo); + + if (ok) { + bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1); + bitmap->locked_region.format = format; + bitmap->locked_region.pitch = -pitch; + bitmap->locked_region.pixel_size = pixel_size; + return true; + } + + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; + return ok; +} + + +static bool ogl_lock_region_nonbb_readwrite_nonfbo( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int format) +{ + /* No FBO - fallback to reading the entire texture */ + const int pixel_size = al_get_pixel_size(format); + const int pitch = ogl_pitch(ogl_bitmap->true_w, pixel_size); + GLenum e; + bool ok; + (void) w; + + ogl_bitmap->lock_buffer = al_malloc(pitch * ogl_bitmap->true_h); + if (ogl_bitmap->lock_buffer == NULL) { + return false; + } + + ok = true; + + glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); + glGetTexImage(GL_TEXTURE_2D, 0, + get_glformat(format, 2), + get_glformat(format, 1), + ogl_bitmap->lock_buffer); + + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glGetTexImage for format %s failed (%s).\n", + _al_pixel_format_name(format), _al_gl_error_string(e)); + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; + ok = false; + } + + if (ok) { + bitmap->locked_region.data = ogl_bitmap->lock_buffer + + pitch * (gl_y + h - 1) + pixel_size * x; + bitmap->locked_region.format = format; + bitmap->locked_region.pitch = -pitch; + bitmap->locked_region.pixel_size = pixel_size; + } + + return ok; +} + + + +/* + * Unlocking + */ + +static void ogl_unlock_region_non_readonly(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap); +static void ogl_unlock_region_backbuffer(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y); +static void ogl_unlock_region_nonbb_fbo(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format); +static void ogl_unlock_region_nonbb_fbo_writeonly(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format); +static void ogl_unlock_region_nonbb_fbo_readwrite(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y); +static void ogl_unlock_region_nonbb_nonfbo(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y); + + +void _al_ogl_unlock_region_new(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra; + + if (bitmap->lock_flags & ALLEGRO_LOCK_READONLY) { + ALLEGRO_DEBUG("Unlocking non-backbuffer READONLY\n"); + } + else { + ogl_unlock_region_non_readonly(bitmap, ogl_bitmap); + } + + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; +} + + +static void ogl_unlock_region_non_readonly(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap) +{ + const int lock_format = bitmap->locked_region.format; + const int gl_y = bitmap->h - bitmap->lock_y - bitmap->lock_h; + ALLEGRO_DISPLAY *old_disp = NULL; + ALLEGRO_DISPLAY *disp; + int orig_format; + bool biased_alpha = false; + bool reset_alignment = false; + GLenum e; + + disp = al_get_current_display(); + orig_format = _al_get_real_pixel_format(disp, _al_get_bitmap_memory_format(bitmap)); + + /* Change OpenGL context if necessary. */ + if (!disp || + (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false && + _al_get_bitmap_display(bitmap) != disp)) + { + old_disp = disp; + _al_set_current_display_only(_al_get_bitmap_display(bitmap)); + } + + /* Keep this in sync with ogl_lock_region. */ + int previous_alignment; + glGetIntegerv(GL_UNPACK_ALIGNMENT, &previous_alignment); + { + const int lock_pixel_size = al_get_pixel_size(lock_format); + const int pixel_alignment = ogl_pixel_alignment(lock_pixel_size); + if (pixel_alignment != previous_alignment) { + reset_alignment = true; + glPixelStorei(GL_UNPACK_ALIGNMENT, pixel_alignment); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glPixelStorei(GL_UNPACK_ALIGNMENT, %d) failed (%s).\n", + pixel_alignment, _al_gl_error_string(e)); + } + } + } + if (exactly_15bpp(lock_format)) { + /* OpenGL does not support 15-bpp internal format without an alpha, + * so when storing such data we must ensure the alpha bit is set. + */ + glPixelTransferi(GL_ALPHA_BIAS, 1); + biased_alpha = true; + } + + if (ogl_bitmap->is_backbuffer) { + ALLEGRO_DEBUG("Unlocking backbuffer\n"); + ogl_unlock_region_backbuffer(bitmap, ogl_bitmap, gl_y); + } + else { + glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); + if (ogl_bitmap->fbo_info) { + ALLEGRO_DEBUG("Unlocking non-backbuffer (FBO)\n"); + ogl_unlock_region_nonbb_fbo(bitmap, ogl_bitmap, gl_y, orig_format); + } + else { + ALLEGRO_DEBUG("Unlocking non-backbuffer (non-FBO)\n"); + ogl_unlock_region_nonbb_nonfbo(bitmap, ogl_bitmap, gl_y); + } + + /* If using FBOs, we need to regenerate mipmaps explicitly now. */ + /* XXX why don't we check ogl_bitmap->fbo_info? */ + if ((al_get_bitmap_flags(bitmap) & ALLEGRO_MIPMAP) && + al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object) + { + glGenerateMipmapEXT(GL_TEXTURE_2D); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glGenerateMipmapEXT for texture %d failed (%s).\n", + ogl_bitmap->texture, _al_gl_error_string(e)); + } + } + } + + if (biased_alpha) { + glPixelTransferi(GL_ALPHA_BIAS, 0); + } + if (reset_alignment) { + glPixelStorei(GL_UNPACK_ALIGNMENT, previous_alignment); + } + + if (old_disp) { + _al_set_current_display_only(old_disp); + } +} + + +static void ogl_unlock_region_backbuffer(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y) +{ + const int lock_format = bitmap->locked_region.format; + bool popmatrix = false; + GLenum e; + GLint program = 0; + ALLEGRO_DISPLAY *display = al_get_current_display(); + + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + // FIXME: This is a hack where we temporarily disable the active shader. + // It will only work on Desktop OpenGL in non-strict mode where we even + // can switch back to the fixed pipeline. The correct way would be to not + // use any OpenGL 2 functions (like glDrawPixels). Probably we will want + // separate OpenGL <= 2 (including OpenGL ES 1) and OpenGL >= 3 (including + // OpenGL ES >= 2) drivers at some point. + glGetIntegerv(GL_CURRENT_PROGRAM, &program); + glUseProgram(0); + } + + /* glWindowPos2i may not be available. */ + if (al_get_opengl_version() >= _ALLEGRO_OPENGL_VERSION_1_4) { + glWindowPos2i(bitmap->lock_x, gl_y); + } + else { + /* glRasterPos is affected by the current modelview and projection + * matrices (so maybe we actually need to reset both of them?). + * The coordinate is also clipped; the small offset was required to + * prevent it being culled on one of my machines. --pw + * + * Consider using glWindowPos2fMESAemulate from: + * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ + */ + glPushMatrix(); + glLoadIdentity(); + glRasterPos2f(bitmap->lock_x, bitmap->lock_y + bitmap->lock_h - 1e-4f); + popmatrix = true; + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glDrawPixels(bitmap->lock_w, bitmap->lock_h, + get_glformat(lock_format, 2), + get_glformat(lock_format, 1), + ogl_bitmap->lock_buffer); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glDrawPixels for format %s failed (%s).\n", + _al_pixel_format_name(lock_format), _al_gl_error_string(e)); + } + + if (popmatrix) { + glPopMatrix(); + } + + if (program != 0) { + glUseProgram(program); + } +} + + +static void ogl_unlock_region_nonbb_fbo(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format) +{ + if (bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY) { + ALLEGRO_DEBUG("Unlocking non-backbuffer FBO WRITEONLY\n"); + ogl_unlock_region_nonbb_fbo_writeonly(bitmap, ogl_bitmap, gl_y, + orig_format); + } + else { + ALLEGRO_DEBUG("Unlocking non-backbuffer FBO READWRITE\n"); + ogl_unlock_region_nonbb_fbo_readwrite(bitmap, ogl_bitmap, gl_y); + } +} + + +static void ogl_unlock_region_nonbb_fbo_writeonly(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format) +{ + const int lock_format = bitmap->locked_region.format; + const int orig_pixel_size = al_get_pixel_size(orig_format); + const int dst_pitch = bitmap->lock_w * orig_pixel_size; + unsigned char * const tmpbuf = al_malloc(dst_pitch * bitmap->lock_h); + GLenum e; + + _al_convert_bitmap_data( + ogl_bitmap->lock_buffer, + bitmap->locked_region.format, + -bitmap->locked_region.pitch, + tmpbuf, + orig_format, + dst_pitch, + 0, 0, 0, 0, + bitmap->lock_w, bitmap->lock_h); + + glTexSubImage2D(GL_TEXTURE_2D, 0, + bitmap->lock_x, gl_y, + bitmap->lock_w, bitmap->lock_h, + get_glformat(orig_format, 2), + get_glformat(orig_format, 1), + tmpbuf); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glTexSubImage2D for format %d failed (%s).\n", + lock_format, _al_gl_error_string(e)); + } + + al_free(tmpbuf); +} + + +static void ogl_unlock_region_nonbb_fbo_readwrite(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y) +{ + const int lock_format = bitmap->locked_region.format; + GLenum e; + GLint tex_internalformat; + + glTexSubImage2D(GL_TEXTURE_2D, 0, bitmap->lock_x, gl_y, + bitmap->lock_w, bitmap->lock_h, + get_glformat(lock_format, 2), + get_glformat(lock_format, 1), + ogl_bitmap->lock_buffer); + + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glTexSubImage2D for format %s failed (%s).\n", + _al_pixel_format_name(lock_format), _al_gl_error_string(e)); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, + GL_TEXTURE_INTERNAL_FORMAT, &tex_internalformat); + ALLEGRO_DEBUG("x/y/w/h: %d/%d/%d/%d, internal format: %d\n", + bitmap->lock_x, gl_y, bitmap->lock_w, bitmap->lock_h, + tex_internalformat); + } +} + + +static void ogl_unlock_region_nonbb_nonfbo(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y) +{ + const int lock_format = bitmap->locked_region.format; + unsigned char *start_ptr; + GLenum e; + + if (bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY) { + ALLEGRO_DEBUG("Unlocking non-backbuffer non-FBO WRITEONLY\n"); + start_ptr = ogl_bitmap->lock_buffer; + } + else { + ALLEGRO_DEBUG("Unlocking non-backbuffer non-FBO READWRITE\n"); + glPixelStorei(GL_UNPACK_ROW_LENGTH, ogl_bitmap->true_w); + start_ptr = (unsigned char *)bitmap->lock_data + + (bitmap->lock_h - 1) * bitmap->locked_region.pitch; + } + + glTexSubImage2D(GL_TEXTURE_2D, 0, + bitmap->lock_x, gl_y, + bitmap->lock_w, bitmap->lock_h, + get_glformat(lock_format, 2), + get_glformat(lock_format, 1), + start_ptr); + + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glTexSubImage2D for format %s failed (%s).\n", + _al_pixel_format_name(lock_format), _al_gl_error_string(e)); + } +} + + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/ogl_lock_es.c b/allegro/src/opengl/ogl_lock_es.c new file mode 100644 index 00000000..b4d14498 --- /dev/null +++ b/allegro/src/opengl/ogl_lock_es.c @@ -0,0 +1,716 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL bitmap locking (GLES). + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_pixels.h" + +#if defined ALLEGRO_ANDROID + #include "allegro5/internal/aintern_android.h" +#endif + +#include "ogl_helpers.h" + +/* + * This is the GLES implementation of ogl_lock_region and ogl_unlock_region. + * The version for desktop GL is in ogl_lock.c. They are pretty similar again + * so probably could consider unifying them again. + */ +#if defined(ALLEGRO_CFG_OPENGLES) + +ALLEGRO_DEBUG_CHANNEL("opengl") + +#define get_glformat(f, c) _al_ogl_get_glformat((f), (c)) + +/* + * Helpers - duplicates code in ogl_bitmap.c for now + */ + +static int ogl_pixel_alignment(int pixel_size) +{ + /* Valid alignments are: 1, 2, 4, 8 bytes. */ + switch (pixel_size) { + case 1: + case 2: + case 4: + case 8: + return pixel_size; + case 3: + return 1; + case 16: /* float32 */ + return 4; + default: + ASSERT(false); + return 4; + } +} + +static int ogl_pitch(int w, int pixel_size) +{ + int pitch = w * pixel_size; + return pitch; +} + + + +/* + * Locking + */ + +static ALLEGRO_LOCKED_REGION *ogl_lock_region_bb_readonly( + ALLEGRO_BITMAP *bitmap, int x, int y, int w, int h, int real_format); +static ALLEGRO_LOCKED_REGION *ogl_lock_region_bb_proxy(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int real_format, int flags); +static ALLEGRO_LOCKED_REGION *ogl_lock_region_nonbb(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int real_format, int flags); +static bool ogl_lock_region_nonbb_writeonly( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int real_format); +static bool ogl_lock_region_nonbb_readwrite( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int real_format, bool* restore_fbo); +static bool ogl_lock_region_nonbb_readwrite_fbo( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int real_format); + + +ALLEGRO_LOCKED_REGION *_al_ogl_lock_region_gles(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int format, int flags) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL * const ogl_bitmap = bitmap->extra; + ALLEGRO_DISPLAY *disp; + int real_format; + + if (format == ALLEGRO_PIXEL_FORMAT_ANY) { + /* Never pick compressed formats with ANY, as it interacts weirdly with + * existing code (e.g. al_get_pixel_size() etc) */ + int bitmap_format = al_get_bitmap_format(bitmap); + if (_al_pixel_format_is_compressed(bitmap_format)) { + // XXX Get a good format from the driver? + format = ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE; + } + else { + format = bitmap_format; + } + } + + disp = al_get_current_display(); + real_format = _al_get_real_pixel_format(disp, format); + + if (ogl_bitmap->is_backbuffer) { + if (flags & ALLEGRO_LOCK_READONLY) { + return ogl_lock_region_bb_readonly(bitmap, x, y, w, h, real_format); + } + else { + return ogl_lock_region_bb_proxy(bitmap, x, y, w, h, real_format, + flags); + } + } + else { + return ogl_lock_region_nonbb(bitmap, x, y, w, h, real_format, flags); + } +} + + +static ALLEGRO_LOCKED_REGION *ogl_lock_region_bb_readonly( + ALLEGRO_BITMAP *bitmap, int x, int y, int w, int h, int real_format) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL * const ogl_bitmap = bitmap->extra; + const int pixel_size = al_get_pixel_size(real_format); + const int pitch = ogl_pitch(w, pixel_size); + const int gl_y = bitmap->h - y - h; + GLenum e; + + ogl_bitmap->lock_buffer = al_malloc(pitch * h); + if (ogl_bitmap->lock_buffer == NULL) { + ALLEGRO_ERROR("Out of memory\n"); + return false; + } + + /* NOTE: GLES can only read 4 byte pixels (or one other implementation + * defined format), we have to convert + */ + glReadPixels(x, gl_y, w, h, + GL_RGBA, GL_UNSIGNED_BYTE, + ogl_bitmap->lock_buffer); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n", + _al_pixel_format_name(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE), _al_gl_error_string(e)); + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; + return false; + } + + ALLEGRO_DEBUG("Converting from format %d -> %d\n", + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, real_format); + + /* That's right, we convert in-place. + * (safe as long as dst size <= src size, which it always is) + */ + _al_convert_bitmap_data(ogl_bitmap->lock_buffer, + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ogl_pitch(w, 4), + ogl_bitmap->lock_buffer, + real_format, + pitch, + 0, 0, 0, 0, + w, h); + + bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1); + bitmap->locked_region.format = real_format; + bitmap->locked_region.pitch = -pitch; + bitmap->locked_region.pixel_size = pixel_size; + return &bitmap->locked_region; +} + + +static ALLEGRO_LOCKED_REGION *ogl_lock_region_bb_proxy(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int real_format, int flags) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL * const ogl_bitmap = bitmap->extra; + ALLEGRO_BITMAP *proxy; + ALLEGRO_LOCKED_REGION *lr; + const int pixel_size = al_get_pixel_size(real_format); + const int pitch = ogl_pitch(w, pixel_size); + + ALLEGRO_DEBUG("Creating backbuffer proxy bitmap\n"); + proxy = _al_create_bitmap_params(al_get_current_display(), + w, h, real_format, ALLEGRO_VIDEO_BITMAP|ALLEGRO_NO_PRESERVE_TEXTURE, + 0, 0); + if (!proxy) { + return NULL; + } + + ALLEGRO_DEBUG("Locking backbuffer proxy bitmap\n"); + proxy->lock_x = 0; + proxy->lock_y = 0; + proxy->lock_w = w; + proxy->lock_h = h; + proxy->lock_flags = flags; + lr = ogl_lock_region_nonbb(proxy, 0, 0, w, h, real_format, flags); + if (!lr) { + al_destroy_bitmap(proxy); + return NULL; + } + + if (!(flags & ALLEGRO_LOCK_WRITEONLY)) { + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_proxy = proxy->extra; + const int gl_y = bitmap->h - y - h; + GLenum e; + + /* NOTE: GLES can only read 4 byte pixels (or one other implementation + * defined format), we have to convert + */ + glReadPixels(x, gl_y, w, h, + GL_RGBA, GL_UNSIGNED_BYTE, + ogl_proxy->lock_buffer); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n", + _al_pixel_format_name(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE), _al_gl_error_string(e)); + al_destroy_bitmap(proxy); + return NULL; + } + + ALLEGRO_DEBUG("Converting from format %d -> %d\n", + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, real_format); + + /* That's right, we convert in-place. + * (safe as long as dst size <= src size, which it always is) + */ + _al_convert_bitmap_data(ogl_proxy->lock_buffer, + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ogl_pitch(w, 4), + ogl_proxy->lock_buffer, + real_format, + pitch, + 0, 0, 0, 0, + w, h); + } + + proxy->locked = true; + bitmap->locked_region = proxy->locked_region; + ogl_bitmap->lock_proxy = proxy; + return lr; +} + + +static ALLEGRO_LOCKED_REGION *ogl_lock_region_nonbb(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int real_format, int flags) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL * const ogl_bitmap = bitmap->extra; + const int gl_y = bitmap->h - y - h; + ALLEGRO_DISPLAY *disp; + ALLEGRO_DISPLAY *old_disp = NULL; + ALLEGRO_BITMAP *old_target = al_get_target_bitmap(); + bool ok; + bool restore_fbo = false; + + disp = al_get_current_display(); + + /* Change OpenGL context if necessary. */ + if (!disp || + (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false && + _al_get_bitmap_display(bitmap) != disp)) + { + old_disp = disp; + _al_set_current_display_only(_al_get_bitmap_display(bitmap)); + } + + ok = true; + + /* Set up the pixel store state. We will need to match it when unlocking. + * There may be other pixel store state we should be setting. + * See also pitfalls 7 & 8 from: + * http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ + */ + { + const int pixel_size = al_get_pixel_size(real_format); + const int pixel_alignment = ogl_pixel_alignment(pixel_size); + GLenum e; + glPixelStorei(GL_PACK_ALIGNMENT, pixel_alignment); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glPixelStorei(GL_PACK_ALIGNMENT, %d) failed (%s).\n", + pixel_alignment, _al_gl_error_string(e)); + ok = false; + } + } + + if (ok) { + if (flags & ALLEGRO_LOCK_WRITEONLY) { + ALLEGRO_DEBUG("Locking non-backbuffer WRITEONLY\n"); + ok = ogl_lock_region_nonbb_writeonly(bitmap, ogl_bitmap, + x, gl_y, w, h, real_format); + } + else { + ALLEGRO_DEBUG("Locking non-backbuffer %s\n", + (flags & ALLEGRO_LOCK_READONLY) ? "READONLY" : "READWRITE"); + ok = ogl_lock_region_nonbb_readwrite(bitmap, ogl_bitmap, + x, gl_y, w, h, real_format, &restore_fbo); + } + } + + /* Restore state after switching FBO. */ + if (restore_fbo) { + if (!old_target) { + /* Old target was NULL; release the context. */ + _al_set_current_display_only(NULL); + } + else if (!_al_get_bitmap_display(old_target)) { + /* Old target was memory bitmap; leave the current display alone. */ + } + else if (old_target != bitmap) { + /* Old target was another OpenGL bitmap. */ + _al_ogl_setup_fbo(_al_get_bitmap_display(old_target), old_target); + } + } + + ASSERT(al_get_target_bitmap() == old_target); + + if (old_disp != NULL) { + _al_set_current_display_only(old_disp); + } + + if (ok) { + return &bitmap->locked_region; + } + + ALLEGRO_ERROR("Failed to lock region\n"); + ASSERT(ogl_bitmap->lock_buffer == NULL); + return NULL; +} + + +static bool ogl_lock_region_nonbb_writeonly( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int real_format) +{ + const int pixel_size = al_get_pixel_size(real_format); + const int pitch = ogl_pitch(w, pixel_size); + (void) x; + (void) gl_y; + + ogl_bitmap->lock_buffer = al_malloc(pitch * h); + if (ogl_bitmap->lock_buffer == NULL) { + return false; + } + + bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (h - 1); + bitmap->locked_region.format = real_format; + bitmap->locked_region.pitch = -pitch; + bitmap->locked_region.pixel_size = pixel_size; + + // Not sure why this is needed on Pi + if (IS_RASPBERRYPI) { + glFlush(); + } + + return true; +} + + +static bool ogl_lock_region_nonbb_readwrite( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int real_format, bool* restore_fbo) +{ + bool ok; + + ASSERT(bitmap->parent == NULL); + ASSERT(bitmap->locked == false); + ASSERT(_al_get_bitmap_display(bitmap) == al_get_current_display()); + + /* Try to create an FBO if there isn't one. */ + *restore_fbo = + _al_ogl_setup_fbo_non_backbuffer(_al_get_bitmap_display(bitmap), bitmap); + + /* Unlike in desktop GL, there seems to be nothing we can do without an FBO. */ + if (*restore_fbo && ogl_bitmap->fbo_info) { + ok = ogl_lock_region_nonbb_readwrite_fbo(bitmap, ogl_bitmap, + x, gl_y, w, h, real_format); + } + else { + ALLEGRO_ERROR("no fbo\n"); + ok = false; + } + + return ok; +} + + +static bool ogl_lock_region_nonbb_readwrite_fbo( + ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, + int x, int gl_y, int w, int h, int real_format) +{ + const int pixel_size = al_get_pixel_size(real_format); + const int pitch = ogl_pitch(w, pixel_size); + const int start_h = h; + GLint old_fbo; + GLenum e; + bool ok; + + ASSERT(ogl_bitmap->fbo_info); + + old_fbo = _al_ogl_bind_framebuffer(ogl_bitmap->fbo_info->fbo); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glBindFramebufferEXT failed (%s).\n", + _al_gl_error_string(e)); + return false; + } + + ok = true; + + /* Allocate a buffer big enough for both purposes. This requires more + * memory to be held for the period of the lock, but overall less + * memory is needed to complete the lock. + */ + if (ok) { + size_t size = _ALLEGRO_MAX(pitch * h, ogl_pitch(w, 4) * h); + ogl_bitmap->lock_buffer = al_malloc(size); + if (ogl_bitmap->lock_buffer == NULL) { + ok = false; + } + } + + if (ok) { + /* NOTE: GLES can only read 4 byte pixels (or one other implementation + * defined format), we have to convert + */ + glReadPixels(x, gl_y, w, h, + GL_RGBA, GL_UNSIGNED_BYTE, + ogl_bitmap->lock_buffer); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glReadPixels for format %s failed (%s).\n", + _al_pixel_format_name(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE), _al_gl_error_string(e)); + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; + ok = false; + } + } + + if (ok) { + ALLEGRO_DEBUG("Converting from format %d -> %d\n", + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, real_format); + + /* That's right, we convert in-place. + * (safe as long as dst size <= src size, which it always is) + */ + _al_convert_bitmap_data(ogl_bitmap->lock_buffer, + ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ogl_pitch(w, 4), + ogl_bitmap->lock_buffer, + real_format, + pitch, + 0, 0, 0, 0, + w, h); + + bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (start_h - 1); + bitmap->locked_region.format = real_format; + bitmap->locked_region.pitch = -pitch; + bitmap->locked_region.pixel_size = pixel_size; + ok = true; + } + + _al_ogl_bind_framebuffer(old_fbo); + + return ok; +} + + + +/* + * Unlocking + */ + +static void ogl_unlock_region_bb_proxy(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap); +static void ogl_unlock_region_nonbb(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap); +static void ogl_unlock_region_nonbb_2(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format); +static void ogl_unlock_region_nonbb_nonfbo_conv(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format); +static void ogl_unlock_region_nonbb_nonfbo_noconv(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format); + + +void _al_ogl_unlock_region_gles(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra; + + if (bitmap->lock_flags & ALLEGRO_LOCK_READONLY) { + ALLEGRO_DEBUG("Unlocking READONLY\n"); + ASSERT(ogl_bitmap->lock_proxy == NULL); + } + else if (ogl_bitmap->lock_proxy != NULL) { + ogl_unlock_region_bb_proxy(bitmap, ogl_bitmap); + } + else { + ogl_unlock_region_nonbb(bitmap, ogl_bitmap); + } + + al_free(ogl_bitmap->lock_buffer); + ogl_bitmap->lock_buffer = NULL; +} + + +static void ogl_unlock_region_bb_proxy(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap) +{ + ALLEGRO_BITMAP *proxy = ogl_bitmap->lock_proxy; + + ASSERT(proxy); + ASSERT(ogl_bitmap->lock_buffer == NULL); + + ALLEGRO_DEBUG("Unlocking backbuffer proxy bitmap\n"); + _al_ogl_unlock_region_gles(proxy); + proxy->locked = false; + + ALLEGRO_DEBUG("Drawing proxy to backbuffer\n"); + { + ALLEGRO_DISPLAY *disp; + ALLEGRO_STATE state0; + ALLEGRO_TRANSFORM t; + bool held; + + disp = al_get_current_display(); + held = al_is_bitmap_drawing_held(); + if (held) { + al_hold_bitmap_drawing(false); + } + al_store_state(&state0, ALLEGRO_STATE_TARGET_BITMAP | + ALLEGRO_STATE_TRANSFORM | ALLEGRO_STATE_BLENDER | + ALLEGRO_STATE_PROJECTION_TRANSFORM); + { + al_set_target_bitmap(bitmap); + al_identity_transform(&t); + al_use_transform(&t); + al_orthographic_transform(&t, 0, 0, -1, disp->w, disp->h, 1); + al_use_projection_transform(&t); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_bitmap(proxy, bitmap->lock_x, bitmap->lock_y, 0); + } + al_restore_state(&state0); + al_hold_bitmap_drawing(held); + } + + ALLEGRO_DEBUG("Destroying backbuffer proxy bitmap\n"); + al_destroy_bitmap(proxy); + ogl_bitmap->lock_proxy = NULL; +} + + +static void ogl_unlock_region_nonbb(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap) +{ + const int gl_y = bitmap->h - bitmap->lock_y - bitmap->lock_h; + ALLEGRO_DISPLAY *old_disp = NULL; + ALLEGRO_DISPLAY *disp; + int orig_format; + GLenum e; + + disp = al_get_current_display(); + orig_format = _al_get_real_pixel_format(disp, al_get_bitmap_format(bitmap)); + + /* Change OpenGL context if necessary. */ + if (!disp || + (_al_get_bitmap_display(bitmap)->ogl_extras->is_shared == false && + _al_get_bitmap_display(bitmap) != disp)) + { + old_disp = disp; + _al_set_current_display_only(_al_get_bitmap_display(bitmap)); + } + + /* Desktop code sets GL_UNPACK_ALIGNMENT here instead of later. */ + + ogl_unlock_region_nonbb_2(bitmap, ogl_bitmap, gl_y, orig_format); + + /* If using FBOs, we need to regenerate mipmaps explicitly now. */ + /* XXX why don't we check ogl_bitmap->fbo_info? */ + if ((al_get_bitmap_flags(bitmap) & ALLEGRO_MIPMAP) && + (al_get_opengl_extension_list()->ALLEGRO_GL_OES_framebuffer_object || + IS_OPENGLES) /* FIXME */) + { + glGenerateMipmapEXT(GL_TEXTURE_2D); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glGenerateMipmapEXT for texture %d failed (%s).\n", + ogl_bitmap->texture, _al_gl_error_string(e)); + } + } + + if (old_disp) { + _al_set_current_display_only(old_disp); + } +} + + +static void ogl_unlock_region_nonbb_2(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format) +{ + GLint fbo; + GLenum e; + +#ifdef ALLEGRO_ANDROID + fbo = _al_android_get_curr_fbo(); +#else + glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo); +#endif + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +#ifdef ALLEGRO_ANDROID + _al_android_set_curr_fbo(0); +#endif + + glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glBindTexture failed (%s).\n", _al_gl_error_string(e)); + } + + /* Differs from desktop code. */ + ALLEGRO_DEBUG("Unlocking non-backbuffer (non-FBO)\n"); + if (bitmap->locked_region.format != orig_format) { + ALLEGRO_DEBUG( + "Unlocking non-backbuffer non-FBO with conversion (%d -> %d)\n", + bitmap->locked_region.format, orig_format); + ogl_unlock_region_nonbb_nonfbo_conv(bitmap, ogl_bitmap, gl_y, + orig_format); + } + else { + ALLEGRO_DEBUG("Unlocking non-backbuffer non-FBO without conversion\n"); + ogl_unlock_region_nonbb_nonfbo_noconv(bitmap, ogl_bitmap, gl_y, + orig_format); + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); +#ifdef ALLEGRO_ANDROID + _al_android_set_curr_fbo(fbo); +#endif +} + + +static void ogl_unlock_region_nonbb_nonfbo_conv(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format) +{ + const int lock_format = bitmap->locked_region.format; + const int orig_pixel_size = al_get_pixel_size(orig_format); + const int dst_pitch = bitmap->lock_w * orig_pixel_size; + unsigned char * const tmpbuf = al_malloc(dst_pitch * bitmap->lock_h); + GLenum e; + + _al_convert_bitmap_data( + ogl_bitmap->lock_buffer, + bitmap->locked_region.format, + -bitmap->locked_region.pitch, + tmpbuf, + orig_format, + dst_pitch, + 0, 0, 0, 0, + bitmap->lock_w, bitmap->lock_h); + + glPixelStorei(GL_UNPACK_ALIGNMENT, ogl_pixel_alignment(orig_pixel_size)); + + glTexSubImage2D(GL_TEXTURE_2D, 0, + bitmap->lock_x, gl_y, + bitmap->lock_w, bitmap->lock_h, + get_glformat(orig_format, 2), + get_glformat(orig_format, 1), + tmpbuf); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glTexSubImage2D for format %d failed (%s).\n", + lock_format, _al_gl_error_string(e)); + } + + al_free(tmpbuf); +} + + +static void ogl_unlock_region_nonbb_nonfbo_noconv(ALLEGRO_BITMAP *bitmap, + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int gl_y, int orig_format) +{ + const int lock_format = bitmap->locked_region.format; + const int orig_pixel_size = al_get_pixel_size(orig_format); + GLenum e; + + glPixelStorei(GL_UNPACK_ALIGNMENT, ogl_pixel_alignment(orig_pixel_size)); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glPixelStorei for format %s failed (%s).\n", + _al_pixel_format_name(lock_format), _al_gl_error_string(e)); + } + + glTexSubImage2D(GL_TEXTURE_2D, 0, + bitmap->lock_x, gl_y, + bitmap->lock_w, bitmap->lock_h, + get_glformat(lock_format, 2), + get_glformat(lock_format, 1), + ogl_bitmap->lock_buffer); + e = glGetError(); + if (e) { + ALLEGRO_ERROR("glTexSubImage2D for format %s failed (%s).\n", + _al_pixel_format_name(lock_format), _al_gl_error_string(e)); + } +} + + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/opengl/ogl_render_state.c b/allegro/src/opengl/ogl_render_state.c new file mode 100644 index 00000000..574e3db2 --- /dev/null +++ b/allegro/src/opengl/ogl_render_state.c @@ -0,0 +1,63 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_opengl.h" + +ALLEGRO_DEBUG_CHANNEL("opengl") + +/* Note: synched to ALLEGRO_RENDER_FUNCTION values as array indices */ +static int _gl_funcs[] = { + GL_NEVER, + GL_ALWAYS, + GL_LESS, + GL_EQUAL, + GL_LEQUAL, + GL_GREATER, + GL_NOTEQUAL, + GL_GEQUAL +}; + +void _al_ogl_update_render_state(ALLEGRO_DISPLAY *display) +{ + _ALLEGRO_RENDER_STATE *r = &display->render_state; + + /* TODO: We could store the previous state and/or mark updated states to + * avoid so many redundant OpenGL calls. + */ + + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_SHADER_GLSL + GLint atloc = display->ogl_extras->varlocs.alpha_test_loc; + GLint floc = display->ogl_extras->varlocs.alpha_func_loc; + GLint tvloc = display->ogl_extras->varlocs.alpha_test_val_loc; + + if (display->ogl_extras->program_object > 0 && floc >= 0 && tvloc >= 0) { + glUniform1i(atloc, r->alpha_test); + glUniform1i(floc, r->alpha_function); + glUniform1f(tvloc, (float)r->alpha_test_value / 255.0); + } +#endif + } + else { +#ifdef ALLEGRO_CFG_OPENGL_FIXED_FUNCTION + if (r->alpha_test == 0) + glDisable(GL_ALPHA_TEST); + else + glEnable(GL_ALPHA_TEST); + glAlphaFunc(_gl_funcs[r->alpha_function], (float)r->alpha_test_value / 255.0); +#endif + } + + if (r->depth_test == 0) + glDisable(GL_DEPTH_TEST); + else + glEnable(GL_DEPTH_TEST); + glDepthFunc(_gl_funcs[r->depth_function]); + + glDepthMask((r->write_mask & ALLEGRO_MASK_DEPTH) ? GL_TRUE : GL_FALSE); + glColorMask( + (r->write_mask & ALLEGRO_MASK_RED) ? GL_TRUE : GL_FALSE, + (r->write_mask & ALLEGRO_MASK_GREEN) ? GL_TRUE : GL_FALSE, + (r->write_mask & ALLEGRO_MASK_BLUE) ? GL_TRUE : GL_FALSE, + (r->write_mask & ALLEGRO_MASK_ALPHA) ? GL_TRUE : GL_FALSE); +} diff --git a/allegro/src/opengl/ogl_shader.c b/allegro/src/opengl/ogl_shader.c new file mode 100644 index 00000000..21762c2a --- /dev/null +++ b/allegro/src/opengl/ogl_shader.c @@ -0,0 +1,525 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * OpenGL shader support. + * + * See LICENSE.txt for copyright information. + */ + +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_shader.h" + +#ifdef ALLEGRO_MSVC + #define snprintf _snprintf +#endif + +#ifdef ALLEGRO_CFG_SHADER_GLSL + +ALLEGRO_DEBUG_CHANNEL("shader") + +static _AL_VECTOR shaders; +static ALLEGRO_MUTEX *shaders_mutex; + +typedef struct ALLEGRO_SHADER_GLSL_S ALLEGRO_SHADER_GLSL_S; + +struct ALLEGRO_SHADER_GLSL_S +{ + ALLEGRO_SHADER shader; + GLuint vertex_shader; + GLuint pixel_shader; + GLuint program_object; + ALLEGRO_OGL_VARLOCS varlocs; +}; + + +/* forward declarations */ +static struct ALLEGRO_SHADER_INTERFACE shader_glsl_vt; +static void lookup_varlocs(ALLEGRO_OGL_VARLOCS *varlocs, GLuint program); + + +static bool check_gl_error(const char* name) +{ + GLenum err = glGetError(); + if (err != 0) { + ALLEGRO_WARN("%s (%s)\n", name, _al_gl_error_string(err)); + return false; + } + return true; +} + + +ALLEGRO_SHADER *_al_create_shader_glsl(ALLEGRO_SHADER_PLATFORM platform) +{ + ALLEGRO_SHADER_GLSL_S *shader = al_calloc(1, sizeof(ALLEGRO_SHADER_GLSL_S)); + + if (!shader) + return NULL; + + shader->shader.platform = platform; + shader->shader.vt = &shader_glsl_vt; + _al_vector_init(&shader->shader.bitmaps, sizeof(ALLEGRO_BITMAP *)); + + al_lock_mutex(shaders_mutex); + { + ALLEGRO_SHADER **back = (ALLEGRO_SHADER **)_al_vector_alloc_back(&shaders); + *back = (ALLEGRO_SHADER *)shader; + } + al_unlock_mutex(shaders_mutex); + + return (ALLEGRO_SHADER *)shader; +} + +static bool glsl_attach_shader_source(ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *source) +{ + GLint status; + GLchar error_buf[4096]; + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + ALLEGRO_DISPLAY *display = al_get_current_display(); + ASSERT(display); + ASSERT(display->flags & ALLEGRO_OPENGL); + + if (source == NULL) { + if (type == ALLEGRO_VERTEX_SHADER) { + if (gl_shader->vertex_shader) { + glDetachShader(gl_shader->program_object, gl_shader->vertex_shader); + glDeleteShader(gl_shader->vertex_shader); + gl_shader->vertex_shader = 0; + } + } + else { + if (gl_shader->pixel_shader) { + glDetachShader(gl_shader->program_object, gl_shader->pixel_shader); + glDeleteShader(gl_shader->pixel_shader); + gl_shader->pixel_shader = 0; + } + } + return true; + } + else { + GLuint *handle; + GLenum gl_type; + if (type == ALLEGRO_VERTEX_SHADER) { + handle = &(gl_shader->vertex_shader); + gl_type = GL_VERTEX_SHADER; + } + else { + handle = &(gl_shader->pixel_shader); + gl_type = GL_FRAGMENT_SHADER; + } + *handle = glCreateShader(gl_type); + if ((*handle) == 0) { + return false; + } + glShaderSource(*handle, 1, &source, NULL); + glCompileShader(*handle); + glGetShaderiv(*handle, GL_COMPILE_STATUS, &status); + if (status == 0) { + glGetShaderInfoLog(*handle, sizeof(error_buf), NULL, error_buf); + if (shader->log) { + al_ustr_truncate(shader->log, 0); + al_ustr_append_cstr(shader->log, error_buf); + } + else { + shader->log = al_ustr_new(error_buf); + } + ALLEGRO_ERROR("Compile error: %s\n", error_buf); + glDeleteShader(*handle); + return false; + } + } + + return true; +} + +static bool glsl_build_shader(ALLEGRO_SHADER *shader) +{ + GLint status; + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLchar error_buf[4096]; + + if (gl_shader->vertex_shader == 0 && gl_shader->pixel_shader == 0) + return false; + + if (gl_shader->program_object != 0) { + glDeleteProgram(gl_shader->program_object); + } + + gl_shader->program_object = glCreateProgram(); + if (gl_shader->program_object == 0) + return false; + + if (gl_shader->vertex_shader) + glAttachShader(gl_shader->program_object, gl_shader->vertex_shader); + if (gl_shader->pixel_shader) + glAttachShader(gl_shader->program_object, gl_shader->pixel_shader); + + glLinkProgram(gl_shader->program_object); + + glGetProgramiv(gl_shader->program_object, GL_LINK_STATUS, &status); + + if (status == 0) { + glGetProgramInfoLog(gl_shader->program_object, sizeof(error_buf), NULL, + error_buf); + if (shader->log) { + al_ustr_truncate(shader->log, 0); + al_ustr_append_cstr(shader->log, error_buf); + } + else { + shader->log = al_ustr_new(error_buf); + } + ALLEGRO_ERROR("Link error: %s\n", error_buf); + glDeleteProgram(gl_shader->program_object); + return false; + } + + /* Look up variable locations. */ + lookup_varlocs(&gl_shader->varlocs, gl_shader->program_object); + + return true; +} + +static bool glsl_use_shader(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *display, + bool set_projview_matrix_from_display) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader; + GLuint program_object; + GLenum err; + + if (!(display->flags & ALLEGRO_OPENGL)) { + return false; + } + + gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + program_object = gl_shader->program_object; + + glGetError(); /* clear error */ + glUseProgram(program_object); + err = glGetError(); + if (err != GL_NO_ERROR) { + ALLEGRO_WARN("glUseProgram(%u) failed: %s\n", program_object, + _al_gl_error_string(err)); + display->ogl_extras->program_object = 0; + return false; + } + + display->ogl_extras->program_object = program_object; + + /* Copy variable locations. */ + display->ogl_extras->varlocs = gl_shader->varlocs; + + /* Optionally set projview matrix. We skip this when it is known that the + * matrices in the display are out of date and are about to be clobbered + * itself. + */ + if (set_projview_matrix_from_display) { + _al_glsl_set_projview_matrix( + display->ogl_extras->varlocs.projview_matrix_loc, &display->projview_transform); + } + + /* Alpha testing may be done in the shader and so when a shader is + * set the uniforms need to be synchronized. + */ + _al_ogl_update_render_state(display); + + return true; +} + +static void glsl_unuse_shader(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *display) +{ + (void)shader; + (void)display; + glUseProgram(0); +} + +static void glsl_destroy_shader(ALLEGRO_SHADER *shader) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + + al_lock_mutex(shaders_mutex); + _al_vector_find_and_delete(&shaders, &shader); + al_unlock_mutex(shaders_mutex); + + glDeleteShader(gl_shader->vertex_shader); + glDeleteShader(gl_shader->pixel_shader); + glDeleteProgram(gl_shader->program_object); + al_free(shader); +} + +static bool glsl_set_shader_sampler(ALLEGRO_SHADER *shader, + const char *name, ALLEGRO_BITMAP *bitmap, int unit) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLint handle; + GLuint texture; + + if (bitmap && al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP) { + ALLEGRO_WARN("Cannot use memory bitmap for sampler\n"); + return false; + } + + handle = glGetUniformLocation(gl_shader->program_object, name); + + if (handle < 0) { + ALLEGRO_WARN("No uniform variable '%s' in shader program\n", name); + return false; + } + + glActiveTexture(GL_TEXTURE0 + unit); + + texture = bitmap ? al_get_opengl_texture(bitmap) : 0; + glBindTexture(GL_TEXTURE_2D, texture); + + glUniform1i(handle, unit); + + return check_gl_error(name); +} + +static bool glsl_set_shader_matrix(ALLEGRO_SHADER *shader, + const char *name, const ALLEGRO_TRANSFORM *matrix) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLint handle; + + handle = glGetUniformLocation(gl_shader->program_object, name); + + if (handle < 0) { + ALLEGRO_WARN("No uniform variable '%s' in shader program\n", name); + return false; + } + + glUniformMatrix4fv(handle, 1, false, (const float *)matrix->m); + + return check_gl_error(name); +} + +static bool glsl_set_shader_int(ALLEGRO_SHADER *shader, + const char *name, int i) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLint handle; + + handle = glGetUniformLocation(gl_shader->program_object, name); + + if (handle < 0) { + ALLEGRO_WARN("No uniform variable '%s' in shader program\n", name); + return false; + } + + glUniform1i(handle, i); + + return check_gl_error(name); +} + +static bool glsl_set_shader_float(ALLEGRO_SHADER *shader, + const char *name, float f) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLint handle; + + handle = glGetUniformLocation(gl_shader->program_object, name); + + if (handle < 0) { + ALLEGRO_WARN("No uniform variable '%s' in shader program\n", name); + return false; + } + + glUniform1f(handle, f); + + return check_gl_error(name); +} + +static bool glsl_set_shader_int_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const int *i, int num_elems) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLint handle; + + handle = glGetUniformLocation(gl_shader->program_object, name); + + if (handle < 0) { + ALLEGRO_WARN("No uniform variable '%s' in shader program\n", name); + return false; + } + + switch (num_components) { + case 1: + glUniform1iv(handle, num_elems, i); + break; + case 2: + glUniform2iv(handle, num_elems, i); + break; + case 3: + glUniform3iv(handle, num_elems, i); + break; + case 4: + glUniform4iv(handle, num_elems, i); + break; + default: + ASSERT(false); + break; + } + + return check_gl_error(name); +} + +static bool glsl_set_shader_float_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const float *f, int num_elems) +{ + ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; + GLint handle; + + handle = glGetUniformLocation(gl_shader->program_object, name); + + if (handle < 0) { + ALLEGRO_WARN("No uniform variable '%s' in shader program\n", name); + return false; + } + + switch (num_components) { + case 1: + glUniform1fv(handle, num_elems, f); + break; + case 2: + glUniform2fv(handle, num_elems, f); + break; + case 3: + glUniform3fv(handle, num_elems, f); + break; + case 4: + glUniform4fv(handle, num_elems, f); + break; + default: + ASSERT(false); + break; + } + + return check_gl_error(name); +} + +static bool glsl_set_shader_bool(ALLEGRO_SHADER *shader, + const char *name, bool b) +{ + return glsl_set_shader_int(shader, name, b); +} + +static struct ALLEGRO_SHADER_INTERFACE shader_glsl_vt = +{ + glsl_attach_shader_source, + glsl_build_shader, + glsl_use_shader, + glsl_unuse_shader, + glsl_destroy_shader, + NULL, /* on_lost_device */ + NULL, /* on_reset_device */ + glsl_set_shader_sampler, + glsl_set_shader_matrix, + glsl_set_shader_int, + glsl_set_shader_float, + glsl_set_shader_int_vector, + glsl_set_shader_float_vector, + glsl_set_shader_bool +}; + +static void lookup_varlocs(ALLEGRO_OGL_VARLOCS *varlocs, GLuint program) +{ + unsigned i; + + varlocs->pos_loc = glGetAttribLocation(program, ALLEGRO_SHADER_VAR_POS); + varlocs->color_loc = glGetAttribLocation(program, ALLEGRO_SHADER_VAR_COLOR); + varlocs->projview_matrix_loc = glGetUniformLocation(program, ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX); + varlocs->texcoord_loc = glGetAttribLocation(program, ALLEGRO_SHADER_VAR_TEXCOORD); + varlocs->use_tex_loc = glGetUniformLocation(program, ALLEGRO_SHADER_VAR_USE_TEX); + varlocs->tex_loc = glGetUniformLocation(program, ALLEGRO_SHADER_VAR_TEX); + varlocs->use_tex_matrix_loc = glGetUniformLocation(program, ALLEGRO_SHADER_VAR_USE_TEX_MATRIX); + varlocs->tex_matrix_loc = glGetUniformLocation(program, ALLEGRO_SHADER_VAR_TEX_MATRIX); + varlocs->alpha_test_loc = glGetUniformLocation(program, ALLEGRO_SHADER_VAR_ALPHA_TEST); + varlocs->alpha_func_loc = glGetUniformLocation(program, ALLEGRO_SHADER_VAR_ALPHA_FUNCTION); + varlocs->alpha_test_val_loc = glGetUniformLocation(program, ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE); + + for (i = 0; i < _ALLEGRO_PRIM_MAX_USER_ATTR; i++) { + /* al_user_attr_##0 */ + char user_attr_name[sizeof(ALLEGRO_SHADER_VAR_USER_ATTR "999")]; + + snprintf(user_attr_name, sizeof(user_attr_name), ALLEGRO_SHADER_VAR_USER_ATTR "%d", i); + varlocs->user_attr_loc[i] = glGetAttribLocation(program, user_attr_name); + } + + check_gl_error("glGetAttribLocation, glGetUniformLocation"); +} + +bool _al_glsl_set_projview_matrix(GLint projview_matrix_loc, + const ALLEGRO_TRANSFORM *t) +{ + if (projview_matrix_loc >= 0) { + glUniformMatrix4fv(projview_matrix_loc, 1, false, (float *)t->m); + return true; + } + + return false; +} + +void _al_glsl_init_shaders(void) +{ + _al_vector_init(&shaders, sizeof(ALLEGRO_SHADER *)); + shaders_mutex = al_create_mutex(); +} + +void _al_glsl_shutdown_shaders(void) +{ + _al_vector_free(&shaders); + al_destroy_mutex(shaders_mutex); + shaders_mutex = NULL; +} + +/* Look through all the bitmaps associated with all the shaders and c;ear their + * shader field */ +void _al_glsl_unuse_shaders(void) +{ + unsigned i; + al_lock_mutex(shaders_mutex); + for (i = 0; i < _al_vector_size(&shaders); i++) { + unsigned j; + ALLEGRO_SHADER *shader = *((ALLEGRO_SHADER **)_al_vector_ref(&shaders, i)); + + for (j = 0; j < _al_vector_size(&shader->bitmaps); j++) { + ALLEGRO_BITMAP *bitmap = + *((ALLEGRO_BITMAP **)_al_vector_ref(&shader->bitmaps, j)); + _al_set_bitmap_shader_field(bitmap, NULL); + } + } + al_unlock_mutex(shaders_mutex); +} + +#endif + +/* Function: al_get_opengl_program_object + */ +GLuint al_get_opengl_program_object(ALLEGRO_SHADER *shader) +{ + ASSERT(shader); +#ifdef ALLEGRO_CFG_SHADER_GLSL + if (shader->platform != ALLEGRO_SHADER_GLSL) + return 0; + + return ((ALLEGRO_SHADER_GLSL_S *)shader)->program_object; +#else + return 0; +#endif +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/path.c b/allegro/src/path.c new file mode 100644 index 00000000..ef957db3 --- /dev/null +++ b/allegro/src/path.c @@ -0,0 +1,592 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Filesystem path routines. + * + * By Thomas Fjellstrom. + * + * See LICENSE.txt for copyright information. + */ + +/* Title: Filesystem path routines + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/internal/aintern_path.h" + + +/* get_segment: + * Return the i'th directory component of a path. + */ +static ALLEGRO_USTR *get_segment(const ALLEGRO_PATH *path, unsigned i) +{ + ALLEGRO_USTR **seg = _al_vector_ref(&path->segments, i); + return *seg; +} + + +/* get_segment_cstr: + * Return the i'th directory component of a path as a C string. + */ +static const char *get_segment_cstr(const ALLEGRO_PATH *path, unsigned i) +{ + return al_cstr(get_segment(path, i)); +} + + +/* replace_backslashes: + * Replace backslashes by slashes. + */ +static void replace_backslashes(ALLEGRO_USTR *path) +{ + al_ustr_find_replace_cstr(path, 0, "\\", "/"); +} + + +/* parse_path_string: + * + * Parse a path string according to the following grammar. The last + * component, if it is not followed by a directory separator, is interpreted + * as the filename component, unless it is "." or "..". + * + * GRAMMAR + * + * path ::= "//" c+ "/" nonlast [Windows only] + * | c ":" nonlast [Windows only] + * | nonlast + * + * nonlast ::= c* "/" nonlast + * | last + * + * last ::= "." + * | ".." + * | filename + * + * filename ::= c* [but not "." and ".."] + * + * c ::= any character but '/' + */ +static bool parse_path_string(const ALLEGRO_USTR *str, ALLEGRO_PATH *path) +{ + ALLEGRO_USTR_INFO dot_info; + ALLEGRO_USTR_INFO dotdot_info; + const ALLEGRO_USTR * dot = al_ref_cstr(&dot_info, "."); + const ALLEGRO_USTR * dotdot = al_ref_cstr(&dotdot_info, ".."); + + ALLEGRO_USTR *piece = al_ustr_new(""); + int pos = 0; + bool on_windows; + + /* We compile the drive handling code on non-Windows platforms to prevent + * it becoming broken. + */ +#ifdef ALLEGRO_WINDOWS + on_windows = true; +#else + on_windows = false; +#endif + if (on_windows) { + /* UNC \\server\share name */ + if (al_ustr_has_prefix_cstr(str, "//")) { + int slash = al_ustr_find_chr(str, 2, '/'); + if (slash == -1 || slash == 2) { + /* Missing slash or server component is empty. */ + goto Error; + } + al_ustr_assign_substr(path->drive, str, pos, slash); + // Note: The slash will be parsed again, so we end up with + // "//server/share" and not "//servershare"! + pos = slash; + } + else { + /* Drive letter. */ + int colon = al_ustr_offset(str, 1); + if (colon > -1 && al_ustr_get(str, colon) == ':') { + /* Include the colon in the drive string. */ + al_ustr_assign_substr(path->drive, str, 0, colon + 1); + pos = colon + 1; + } + } + } + + for (;;) { + int slash = al_ustr_find_chr(str, pos, '/'); + + if (slash == -1) { + /* Last component. */ + al_ustr_assign_substr(piece, str, pos, al_ustr_size(str)); + if (al_ustr_equal(piece, dot) || al_ustr_equal(piece, dotdot)) { + al_append_path_component(path, al_cstr(piece)); + } + else { + /* This might be an empty string, but that's okay. */ + al_ustr_assign(path->filename, piece); + } + break; + } + + /* Non-last component. */ + al_ustr_assign_substr(piece, str, pos, slash); + al_append_path_component(path, al_cstr(piece)); + pos = slash + 1; + } + + al_ustr_free(piece); + return true; + +Error: + + al_ustr_free(piece); + return false; +} + + +/* Function: al_create_path + */ +ALLEGRO_PATH *al_create_path(const char *str) +{ + ALLEGRO_PATH *path; + + path = al_malloc(sizeof(ALLEGRO_PATH)); + if (!path) + return NULL; + + path->drive = al_ustr_new(""); + path->filename = al_ustr_new(""); + _al_vector_init(&path->segments, sizeof(ALLEGRO_USTR *)); + path->basename = al_ustr_new(""); + path->full_string = al_ustr_new(""); + + if (str != NULL) { + ALLEGRO_USTR *copy = al_ustr_new(str); + replace_backslashes(copy); + + if (!parse_path_string(copy, path)) { + al_destroy_path(path); + path = NULL; + } + + al_ustr_free(copy); + } + + return path; +} + + +/* Function: al_create_path_for_directory + */ +ALLEGRO_PATH *al_create_path_for_directory(const char *str) +{ + ALLEGRO_PATH *path = al_create_path(str); + if (al_ustr_length(path->filename)) { + ALLEGRO_USTR *last = path->filename; + path->filename = al_ustr_new(""); + al_append_path_component(path, al_cstr(last)); + al_ustr_free(last); + } + return path; +} + + +/* Function: al_clone_path + */ +ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path) +{ + ALLEGRO_PATH *clone; + unsigned int i; + + ASSERT(path); + + clone = al_create_path(NULL); + if (!clone) { + return NULL; + } + + al_ustr_assign(clone->drive, path->drive); + al_ustr_assign(clone->filename, path->filename); + + for (i = 0; i < _al_vector_size(&path->segments); i++) { + ALLEGRO_USTR **slot = _al_vector_alloc_back(&clone->segments); + (*slot) = al_ustr_dup(get_segment(path, i)); + } + + return clone; +} + + +/* Function: al_get_path_num_components + */ +int al_get_path_num_components(const ALLEGRO_PATH *path) +{ + ASSERT(path); + + return _al_vector_size(&path->segments); +} + + +/* Function: al_get_path_component + */ +const char *al_get_path_component(const ALLEGRO_PATH *path, int i) +{ + ASSERT(path); + ASSERT(i < (int)_al_vector_size(&path->segments)); + + if (i < 0) + i = _al_vector_size(&path->segments) + i; + + ASSERT(i >= 0); + + return get_segment_cstr(path, i); +} + + +/* Function: al_replace_path_component + */ +void al_replace_path_component(ALLEGRO_PATH *path, int i, const char *s) +{ + ASSERT(path); + ASSERT(s); + ASSERT(i < (int)_al_vector_size(&path->segments)); + + if (i < 0) + i = _al_vector_size(&path->segments) + i; + + ASSERT(i >= 0); + + al_ustr_assign_cstr(get_segment(path, i), s); +} + + +/* Function: al_remove_path_component + */ +void al_remove_path_component(ALLEGRO_PATH *path, int i) +{ + ASSERT(path); + ASSERT(i < (int)_al_vector_size(&path->segments)); + + if (i < 0) + i = _al_vector_size(&path->segments) + i; + + ASSERT(i >= 0); + + al_ustr_free(get_segment(path, i)); + _al_vector_delete_at(&path->segments, i); +} + + +/* Function: al_insert_path_component + */ +void al_insert_path_component(ALLEGRO_PATH *path, int i, const char *s) +{ + ALLEGRO_USTR **slot; + ASSERT(path); + ASSERT(i <= (int)_al_vector_size(&path->segments)); + + if (i < 0) + i = _al_vector_size(&path->segments) + i; + + ASSERT(i >= 0); + + slot = _al_vector_alloc_mid(&path->segments, i); + (*slot) = al_ustr_new(s); +} + + +/* Function: al_get_path_tail + */ +const char *al_get_path_tail(const ALLEGRO_PATH *path) +{ + ASSERT(path); + + if (al_get_path_num_components(path) == 0) + return NULL; + + return al_get_path_component(path, -1); +} + + +/* Function: al_drop_path_tail + */ +void al_drop_path_tail(ALLEGRO_PATH *path) +{ + if (al_get_path_num_components(path) > 0) { + al_remove_path_component(path, -1); + } +} + + +/* Function: al_append_path_component + */ +void al_append_path_component(ALLEGRO_PATH *path, const char *s) +{ + ALLEGRO_USTR **slot = _al_vector_alloc_back(&path->segments); + (*slot) = al_ustr_new(s); +} + + +static bool path_is_absolute(const ALLEGRO_PATH *path) +{ + /* If the first segment is empty, we have an absolute path. */ + return (_al_vector_size(&path->segments) > 0) + && (al_ustr_size(get_segment(path, 0)) == 0); +} + + +/* Function: al_join_paths + */ +bool al_join_paths(ALLEGRO_PATH *path, const ALLEGRO_PATH *tail) +{ + unsigned i; + ASSERT(path); + ASSERT(tail); + + /* Don't bother concating if the tail is an absolute path. */ + if (path_is_absolute(tail)) { + return false; + } + + /* We ignore tail->drive. The other option is to do nothing if tail + * contains a drive letter. + */ + + al_ustr_assign(path->filename, tail->filename); + + for (i = 0; i < _al_vector_size(&tail->segments); i++) { + al_append_path_component(path, get_segment_cstr(tail, i)); + } + + return true; +} + + +/* Function: al_rebase_path + */ +bool al_rebase_path(const ALLEGRO_PATH *head, ALLEGRO_PATH *tail) +{ + unsigned i; + ASSERT(head); + ASSERT(tail); + + /* Don't bother concating if the tail is an absolute path. */ + if (path_is_absolute(tail)) { + return false; + } + + al_set_path_drive(tail, al_get_path_drive(head)); + + for (i = 0; i < _al_vector_size(&head->segments); i++) { + al_insert_path_component(tail, i, get_segment_cstr(head, i)); + } + + return true; +} + + +static void path_to_ustr(const ALLEGRO_PATH *path, int32_t delim, + ALLEGRO_USTR *str) +{ + unsigned i; + + al_ustr_assign(str, path->drive); + + for (i = 0; i < _al_vector_size(&path->segments); i++) { + al_ustr_append(str, get_segment(path, i)); + al_ustr_append_chr(str, delim); + } + + al_ustr_append(str, path->filename); +} + + +/* Function: al_path_cstr + */ +const char *al_path_cstr(const ALLEGRO_PATH *path, char delim) +{ + return al_cstr(al_path_ustr(path, delim)); +} + +/* Function: al_path_ustr + */ +const ALLEGRO_USTR *al_path_ustr(const ALLEGRO_PATH *path, char delim) +{ + path_to_ustr(path, delim, path->full_string); + return path->full_string; +} + + +/* Function: al_destroy_path + */ +void al_destroy_path(ALLEGRO_PATH *path) +{ + unsigned i; + + if (!path) { + return; + } + + if (path->drive) { + al_ustr_free(path->drive); + path->drive = NULL; + } + + if (path->filename) { + al_ustr_free(path->filename); + path->filename = NULL; + } + + for (i = 0; i < _al_vector_size(&path->segments); i++) { + al_ustr_free(get_segment(path, i)); + } + _al_vector_free(&path->segments); + + if (path->basename) { + al_ustr_free(path->basename); + path->basename = NULL; + } + + if (path->full_string) { + al_ustr_free(path->full_string); + path->full_string = NULL; + } + + al_free(path); +} + + +/* Function: al_set_path_drive + */ +void al_set_path_drive(ALLEGRO_PATH *path, const char *drive) +{ + ASSERT(path); + + if (drive) + al_ustr_assign_cstr(path->drive, drive); + else + al_ustr_truncate(path->drive, 0); +} + + +/* Function: al_get_path_drive + */ +const char *al_get_path_drive(const ALLEGRO_PATH *path) +{ + ASSERT(path); + + return al_cstr(path->drive); +} + + +/* Function: al_set_path_filename + */ +void al_set_path_filename(ALLEGRO_PATH *path, const char *filename) +{ + ASSERT(path); + + if (filename) + al_ustr_assign_cstr(path->filename, filename); + else + al_ustr_truncate(path->filename, 0); +} + + +/* Function: al_get_path_filename + */ +const char *al_get_path_filename(const ALLEGRO_PATH *path) +{ + ASSERT(path); + + return al_cstr(path->filename); +} + + +/* Function: al_get_path_extension + */ +const char *al_get_path_extension(const ALLEGRO_PATH *path) +{ + int pos; + ASSERT(path); + + pos = al_ustr_rfind_chr(path->filename, al_ustr_size(path->filename), '.'); + if (pos == -1) + pos = al_ustr_size(path->filename); + + return al_cstr(path->filename) + pos; /* include dot */ +} + + +/* Function: al_set_path_extension + */ +bool al_set_path_extension(ALLEGRO_PATH *path, char const *extension) +{ + int dot; + ASSERT(path); + + if (al_ustr_size(path->filename) == 0) { + return false; + } + + dot = al_ustr_rfind_chr(path->filename, al_ustr_size(path->filename), '.'); + if (dot >= 0) { + al_ustr_truncate(path->filename, dot); + } + al_ustr_append_cstr(path->filename, extension); + return true; +} + + +/* Function: al_get_path_basename + */ +const char *al_get_path_basename(const ALLEGRO_PATH *path) +{ + int dot; + ASSERT(path); + + dot = al_ustr_rfind_chr(path->filename, al_ustr_size(path->filename), '.'); + if (dot >= 0) { + al_ustr_assign_substr(path->basename, path->filename, 0, dot); + return al_cstr(path->basename); + } + + return al_cstr(path->filename); +} + + +/* Function: al_make_path_canonical + */ +bool al_make_path_canonical(ALLEGRO_PATH *path) +{ + unsigned i; + ASSERT(path); + + for (i = 0; i < _al_vector_size(&path->segments); ) { + if (strcmp(get_segment_cstr(path, i), ".") == 0) + al_remove_path_component(path, i); + else + i++; + } + + /* Remove leading '..'s on absolute paths. */ + if (_al_vector_size(&path->segments) >= 1 && + al_ustr_size(get_segment(path, 0)) == 0) + { + while (_al_vector_size(&path->segments) >= 2 && + strcmp(get_segment_cstr(path, 1), "..") == 0) + { + al_remove_path_component(path, 1); + } + } + + return true; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/pixel_tables.inc b/allegro/src/pixel_tables.inc new file mode 100644 index 00000000..6b2dec10 --- /dev/null +++ b/allegro/src/pixel_tables.inc @@ -0,0 +1,388 @@ +// Warning: This file was created by make_pixel_tables.py - do not edit. + +float _al_u8_to_float[] = { + 0.0, + 0.00392156862745098, + 0.00784313725490196, + 0.011764705882352941, + 0.01568627450980392, + 0.0196078431372549, + 0.023529411764705882, + 0.027450980392156862, + 0.03137254901960784, + 0.03529411764705882, + 0.0392156862745098, + 0.043137254901960784, + 0.047058823529411764, + 0.050980392156862744, + 0.054901960784313725, + 0.058823529411764705, + 0.06274509803921569, + 0.06666666666666667, + 0.07058823529411765, + 0.07450980392156863, + 0.0784313725490196, + 0.08235294117647059, + 0.08627450980392157, + 0.09019607843137255, + 0.09411764705882353, + 0.09803921568627451, + 0.10196078431372549, + 0.10588235294117647, + 0.10980392156862745, + 0.11372549019607843, + 0.11764705882352941, + 0.12156862745098039, + 0.12549019607843137, + 0.12941176470588237, + 0.13333333333333333, + 0.13725490196078433, + 0.1411764705882353, + 0.1450980392156863, + 0.14901960784313725, + 0.15294117647058825, + 0.1568627450980392, + 0.1607843137254902, + 0.16470588235294117, + 0.16862745098039217, + 0.17254901960784313, + 0.17647058823529413, + 0.1803921568627451, + 0.1843137254901961, + 0.18823529411764706, + 0.19215686274509805, + 0.19607843137254902, + 0.2, + 0.20392156862745098, + 0.20784313725490197, + 0.21176470588235294, + 0.21568627450980393, + 0.2196078431372549, + 0.2235294117647059, + 0.22745098039215686, + 0.23137254901960785, + 0.23529411764705882, + 0.23921568627450981, + 0.24313725490196078, + 0.24705882352941178, + 0.25098039215686274, + 0.2549019607843137, + 0.25882352941176473, + 0.2627450980392157, + 0.26666666666666666, + 0.27058823529411763, + 0.27450980392156865, + 0.2784313725490196, + 0.2823529411764706, + 0.28627450980392155, + 0.2901960784313726, + 0.29411764705882354, + 0.2980392156862745, + 0.30196078431372547, + 0.3058823529411765, + 0.30980392156862746, + 0.3137254901960784, + 0.3176470588235294, + 0.3215686274509804, + 0.3254901960784314, + 0.32941176470588235, + 0.3333333333333333, + 0.33725490196078434, + 0.3411764705882353, + 0.34509803921568627, + 0.34901960784313724, + 0.35294117647058826, + 0.3568627450980392, + 0.3607843137254902, + 0.36470588235294116, + 0.3686274509803922, + 0.37254901960784315, + 0.3764705882352941, + 0.3803921568627451, + 0.3843137254901961, + 0.38823529411764707, + 0.39215686274509803, + 0.396078431372549, + 0.4, + 0.403921568627451, + 0.40784313725490196, + 0.4117647058823529, + 0.41568627450980394, + 0.4196078431372549, + 0.4235294117647059, + 0.42745098039215684, + 0.43137254901960786, + 0.43529411764705883, + 0.4392156862745098, + 0.44313725490196076, + 0.4470588235294118, + 0.45098039215686275, + 0.4549019607843137, + 0.4588235294117647, + 0.4627450980392157, + 0.4666666666666667, + 0.47058823529411764, + 0.4745098039215686, + 0.47843137254901963, + 0.4823529411764706, + 0.48627450980392156, + 0.49019607843137253, + 0.49411764705882355, + 0.4980392156862745, + 0.5019607843137255, + 0.5058823529411764, + 0.5098039215686274, + 0.5137254901960784, + 0.5176470588235295, + 0.5215686274509804, + 0.5254901960784314, + 0.5294117647058824, + 0.5333333333333333, + 0.5372549019607843, + 0.5411764705882353, + 0.5450980392156862, + 0.5490196078431373, + 0.5529411764705883, + 0.5568627450980392, + 0.5607843137254902, + 0.5647058823529412, + 0.5686274509803921, + 0.5725490196078431, + 0.5764705882352941, + 0.5803921568627451, + 0.5843137254901961, + 0.5882352941176471, + 0.592156862745098, + 0.596078431372549, + 0.6, + 0.6039215686274509, + 0.6078431372549019, + 0.611764705882353, + 0.615686274509804, + 0.6196078431372549, + 0.6235294117647059, + 0.6274509803921569, + 0.6313725490196078, + 0.6352941176470588, + 0.6392156862745098, + 0.6431372549019608, + 0.6470588235294118, + 0.6509803921568628, + 0.6549019607843137, + 0.6588235294117647, + 0.6627450980392157, + 0.6666666666666666, + 0.6705882352941176, + 0.6745098039215687, + 0.6784313725490196, + 0.6823529411764706, + 0.6862745098039216, + 0.6901960784313725, + 0.6941176470588235, + 0.6980392156862745, + 0.7019607843137254, + 0.7058823529411765, + 0.7098039215686275, + 0.7137254901960784, + 0.7176470588235294, + 0.7215686274509804, + 0.7254901960784313, + 0.7294117647058823, + 0.7333333333333333, + 0.7372549019607844, + 0.7411764705882353, + 0.7450980392156863, + 0.7490196078431373, + 0.7529411764705882, + 0.7568627450980392, + 0.7607843137254902, + 0.7647058823529411, + 0.7686274509803922, + 0.7725490196078432, + 0.7764705882352941, + 0.7803921568627451, + 0.7843137254901961, + 0.788235294117647, + 0.792156862745098, + 0.796078431372549, + 0.8, + 0.803921568627451, + 0.807843137254902, + 0.8117647058823529, + 0.8156862745098039, + 0.8196078431372549, + 0.8235294117647058, + 0.8274509803921568, + 0.8313725490196079, + 0.8352941176470589, + 0.8392156862745098, + 0.8431372549019608, + 0.8470588235294118, + 0.8509803921568627, + 0.8549019607843137, + 0.8588235294117647, + 0.8627450980392157, + 0.8666666666666667, + 0.8705882352941177, + 0.8745098039215686, + 0.8784313725490196, + 0.8823529411764706, + 0.8862745098039215, + 0.8901960784313725, + 0.8941176470588236, + 0.8980392156862745, + 0.9019607843137255, + 0.9058823529411765, + 0.9098039215686274, + 0.9137254901960784, + 0.9176470588235294, + 0.9215686274509803, + 0.9254901960784314, + 0.9294117647058824, + 0.9333333333333333, + 0.9372549019607843, + 0.9411764705882353, + 0.9450980392156862, + 0.9490196078431372, + 0.9529411764705882, + 0.9568627450980393, + 0.9607843137254902, + 0.9647058823529412, + 0.9686274509803922, + 0.9725490196078431, + 0.9764705882352941, + 0.9803921568627451, + 0.984313725490196, + 0.9882352941176471, + 0.9921568627450981, + 0.996078431372549, + 1.0, +}; + +int _al_rgb_scale_1[] = { + 0, + 255, +}; + +int _al_rgb_scale_4[] = { + 0, + 17, + 34, + 51, + 68, + 85, + 102, + 119, + 136, + 153, + 170, + 187, + 204, + 221, + 238, + 255, +}; + +int _al_rgb_scale_5[] = { + 0, + 8, + 16, + 24, + 32, + 41, + 49, + 57, + 65, + 74, + 82, + 90, + 98, + 106, + 115, + 123, + 131, + 139, + 148, + 156, + 164, + 172, + 180, + 189, + 197, + 205, + 213, + 222, + 230, + 238, + 246, + 255, +}; + +int _al_rgb_scale_6[] = { + 0, + 4, + 8, + 12, + 16, + 20, + 24, + 28, + 32, + 36, + 40, + 44, + 48, + 52, + 56, + 60, + 64, + 68, + 72, + 76, + 80, + 85, + 89, + 93, + 97, + 101, + 105, + 109, + 113, + 117, + 121, + 125, + 129, + 133, + 137, + 141, + 145, + 149, + 153, + 157, + 161, + 165, + 170, + 174, + 178, + 182, + 186, + 190, + 194, + 198, + 202, + 206, + 210, + 214, + 218, + 222, + 226, + 230, + 234, + 238, + 242, + 246, + 250, + 255, +}; + +// Warning: This file was created by make_pixel_tables.py - do not edit. diff --git a/allegro/src/pixels.c b/allegro/src/pixels.c new file mode 100644 index 00000000..e1b8421f --- /dev/null +++ b/allegro/src/pixels.c @@ -0,0 +1,664 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Pixel formats. + * + * By Trent Gamblin. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_pixels.h" + +ALLEGRO_DEBUG_CHANNEL("pixels") + + +/* lookup table for scaling 8 bit integers up to floats [0.0, 1.0] */ +#include "pixel_tables.inc" + +static int pixel_sizes[] = { + 0, /* ALLEGRO_PIXEL_FORMAT_ANY */ + 0, + 0, + 2, + 2, + 2, + 3, + 4, + 4, + 4, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + 4, + 2, + 3, + 2, + 2, + 2, + 2, + 4, + 4, + 3, + 2, + 2, + 4, + 4, + 16, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + 4, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + 2, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + 1, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + 0, + 0, + 0, +}; + +static int pixel_bits[] = { + 0, /* ALLEGRO_PIXEL_FORMAT_ANY */ + 0, + 0, + 15, + 16, + 16, + 24, + 32, + 32, + 32, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + 32, + 16, + 24, + 16, + 15, + 16, + 16, + 32, + 32, + 24, + 16, + 15, + 32, + 32, + 128, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + 32, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + 16, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + 8, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + 0, + 0, + 0, +}; + +static int pixel_block_widths[] = { + 0, /* ALLEGRO_PIXEL_FORMAT_ANY */ + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + 1, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + 1, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + 1, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + 4, + 4, + 4, +}; + +static int pixel_block_heights[] = { + 0, /* ALLEGRO_PIXEL_FORMAT_ANY */ + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + 1, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + 1, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + 1, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + 4, + 4, + 4, +}; + +static int pixel_block_sizes[] = { + 0, /* ALLEGRO_PIXEL_FORMAT_ANY */ + 0, + 0, + 2, + 2, + 2, + 3, + 4, + 4, + 4, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + 4, + 2, + 3, + 2, + 2, + 2, + 2, + 4, + 4, + 3, + 2, + 2, + 4, + 4, + 16, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + 4, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + 2, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + 1, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + 8, + 16, + 16, +}; + +static bool format_alpha_table[ALLEGRO_NUM_PIXEL_FORMATS] = { + false, /* neutral (ALLEGRO_PIXEL_FORMAT_ANY) */ + false, + true, + false, + false, + true, + false, + false, + true, + true, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + true, + true, + false, + false, + false, + true, + true, + true, + false, + false, + false, + false, + false, + false, + true, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + true, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + true, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + false, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + true, + true, + true, +}; + +static char const *pixel_format_names[ALLEGRO_NUM_PIXEL_FORMATS + 1] = { + "ANY", + "ANY_NO_ALPHA", + "ANY_WITH_ALPHA", + "ANY_15_NO_ALPHA", + "ANY_16_NO_ALPHA", + "ANY_16_WITH_ALPHA", + "ANY_24_NO_ALPHA", + "ANY_32_NO_ALPHA", + "ANY_32_WITH_ALPHA", + "ARGB_8888", + "RGBA_8888", + "ARGB_4444", + "RGB_888", + "RGB_565", + "RGB_555", + "RGBA_5551", + "ARGB_1555", + "ABGR_8888", + "XBGR_8888", + "BGR_888", + "BGR_565", + "BGR_555", + "RGBX_8888", + "XRGB_8888", + "ABGR_F32", + "ABGR_8888_LE", + "RGBA_4444", + "SINGLE_CHANNEL_8", + "RGBA_DXT1", + "RGBA_DXT3", + "RGBA_DXT5", + "INVALID" +}; + +static bool format_is_real[ALLEGRO_NUM_PIXEL_FORMATS] = +{ + false, /* ALLEGRO_PIXEL_FORMAT_ANY */ + false, + false, + false, + false, + false, + false, + false, + false, + true, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + true, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + true, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + true, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + true, + true, + true, +}; + +static bool format_is_video_only[ALLEGRO_NUM_PIXEL_FORMATS] = +{ + false, /* ALLEGRO_PIXEL_FORMAT_ANY */ + false, + false, + false, + false, + false, + false, + false, + false, + false, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + false, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + false, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + false, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + true, + true, + true, +}; + +static bool format_is_compressed[ALLEGRO_NUM_PIXEL_FORMATS] = +{ + false, /* ALLEGRO_PIXEL_FORMAT_ANY */ + false, + false, + false, + false, + false, + false, + false, + false, + false, /* ALLEGRO_PIXEL_FORMAT_ARGB_8888 */ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, /* ALLEGRO_PIXEL_FORMAT_ABGR_F32 */ + false, /* ALLEGRO_PIXEL_FORMAT_ABGR_LE */ + false, /* ALLEGRO_PIXEL_FORMAT_RGBA_4444 */ + false, /* ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8 */ + true, + true, + true, +}; + + +/* Function: al_get_pixel_block_size + */ +int al_get_pixel_block_size(int format) +{ + return pixel_block_sizes[format]; +} + + +/* Function: al_get_pixel_block_width + */ +int al_get_pixel_block_width(int format) +{ + return pixel_block_widths[format]; +} + + +/* Function: al_get_pixel_block_height + */ +int al_get_pixel_block_height(int format) +{ + return pixel_block_heights[format]; +} + + +/* Function: al_get_pixel_size + */ +int al_get_pixel_size(int format) +{ + return pixel_sizes[format]; +} + + +/* Function: al_get_pixel_format_bits + */ +int al_get_pixel_format_bits(int format) +{ + return pixel_bits[format]; +} + + +bool _al_pixel_format_has_alpha(int format) +{ + return format_alpha_table[format]; +} + + +bool _al_pixel_format_is_real(int format) +{ + ASSERT(format >= 0); + ASSERT(format < ALLEGRO_NUM_PIXEL_FORMATS); + + return format_is_real[format]; +} + +bool _al_pixel_format_is_video_only(int format) +{ + ASSERT(format >= 0); + ASSERT(format < ALLEGRO_NUM_PIXEL_FORMATS); + + return format_is_video_only[format]; +} + +bool _al_pixel_format_is_compressed(int format) +{ + ASSERT(format >= 0); + ASSERT(format < ALLEGRO_NUM_PIXEL_FORMATS); + + return format_is_compressed[format]; +} + + +/* We use al_get_display_format() as a hint for the preferred RGB ordering when + * nothing else is specified. + */ +static bool try_display_format(ALLEGRO_DISPLAY *display, int *format) +{ + int best_format; + int bytes; + + if (!display) { + return false; + } + + best_format = al_get_display_format(display); + if (!_al_pixel_format_is_real(best_format)) + return false; + + bytes = al_get_pixel_size(*format); + if (bytes && bytes != al_get_pixel_size(best_format)) + return false; + + if (_al_pixel_format_has_alpha(*format) && + !_al_pixel_format_has_alpha(best_format)) { + switch (best_format) { + case ALLEGRO_PIXEL_FORMAT_RGBX_8888: + *format = ALLEGRO_PIXEL_FORMAT_RGBA_8888; + return true; + case ALLEGRO_PIXEL_FORMAT_XRGB_8888: + *format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; + return true; + case ALLEGRO_PIXEL_FORMAT_XBGR_8888: + *format = ALLEGRO_PIXEL_FORMAT_ABGR_8888; + return true; + default: + return false; + } + } + if (!_al_pixel_format_has_alpha(*format) && + _al_pixel_format_has_alpha(best_format)) { + switch (best_format) { + case ALLEGRO_PIXEL_FORMAT_RGBA_8888: + *format = ALLEGRO_PIXEL_FORMAT_RGBX_8888; + return true; + case ALLEGRO_PIXEL_FORMAT_ARGB_8888: + *format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; + return true; + case ALLEGRO_PIXEL_FORMAT_ABGR_8888: + *format = ALLEGRO_PIXEL_FORMAT_XBGR_8888; + return true; + default: + return false; + } + } + *format = best_format; + return true; +} + + +int _al_get_real_pixel_format(ALLEGRO_DISPLAY *display, int format) +{ + /* Pick an appropriate format if the user is vague */ + switch (format) { + case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: + case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: + if (!try_display_format(display, &format)) + format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; + break; + case ALLEGRO_PIXEL_FORMAT_ANY: + case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: + case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: + if (!try_display_format(display, &format)) +#if defined ALLEGRO_CFG_OPENGLES // OPENGLES doesn't have ARGB_8888 + format = ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE; +#else + format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; +#endif + break; + case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: + format = ALLEGRO_PIXEL_FORMAT_RGB_555; + break; + case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: + if (!try_display_format(display, &format)) + format = ALLEGRO_PIXEL_FORMAT_RGB_565; + break; + case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: + format = ALLEGRO_PIXEL_FORMAT_RGBA_4444; + break; + case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: + format = ALLEGRO_PIXEL_FORMAT_RGB_888; + break; + default: + /* Already a real format - don't change it. */ + break; + } + + ASSERT(_al_pixel_format_is_real(format)); + return format; +} + + +char const *_al_pixel_format_name(ALLEGRO_PIXEL_FORMAT format) +{ + if (format >= ALLEGRO_NUM_PIXEL_FORMATS) format = ALLEGRO_NUM_PIXEL_FORMATS; + return pixel_format_names[format]; +} + + +/* Color mapping functions */ + +/* Function: al_map_rgba + */ +ALLEGRO_COLOR al_map_rgba( + unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + ALLEGRO_COLOR color; + _AL_MAP_RGBA(color, r, g, b, a); + return color; +} + + +/* Function: al_premul_rgba + */ +ALLEGRO_COLOR al_premul_rgba( + unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + ALLEGRO_COLOR color; + _AL_MAP_RGBA(color, r * a / 255, g * a / 255, b * a / 255, a); + return color; +} + + +/* Function: al_map_rgb + */ +ALLEGRO_COLOR al_map_rgb( + unsigned char r, unsigned char g, unsigned char b) +{ + return al_map_rgba(r, g, b, 255); +} + + +/* Function: al_map_rgba_f + */ +ALLEGRO_COLOR al_map_rgba_f(float r, float g, float b, float a) +{ + ALLEGRO_COLOR color; + color.r = r; + color.g = g; + color.b = b; + color.a = a; + return color; +} + + +/* Function: al_premul_rgba_f + */ +ALLEGRO_COLOR al_premul_rgba_f(float r, float g, float b, float a) +{ + ALLEGRO_COLOR color; + color.r = r * a; + color.g = g * a; + color.b = b * a; + color.a = a; + return color; +} + + +/* Function: al_map_rgb_f + */ +ALLEGRO_COLOR al_map_rgb_f(float r, float g, float b) +{ + return al_map_rgba_f(r, g, b, 1.0f); +} + + +/* unmapping functions */ + + +/* Function: al_unmap_rgba + */ +void al_unmap_rgba(ALLEGRO_COLOR color, + unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) +{ + *r = color.r * 255.0f; + *g = color.g * 255.0f; + *b = color.b * 255.0f; + *a = color.a * 255.0f; +} + + +/* Function: al_unmap_rgb + */ +void al_unmap_rgb(ALLEGRO_COLOR color, + unsigned char *r, unsigned char *g, unsigned char *b) +{ + unsigned char tmp; + + al_unmap_rgba(color, r, g, b, &tmp); +} + + +/* Function: al_unmap_rgba_f + */ +void al_unmap_rgba_f(ALLEGRO_COLOR color, + float *r, float *g, float *b, float *a) +{ + *r = color.r; + *g = color.g; + *b = color.b; + *a = color.a; +} + + +/* Function: al_unmap_rgb_f + */ +void al_unmap_rgb_f(ALLEGRO_COLOR color, float *r, float *g, float *b) +{ + float tmp; + + al_unmap_rgba_f(color, r, g, b, &tmp); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/raspberrypi/picursor.h b/allegro/src/raspberrypi/picursor.h new file mode 100644 index 00000000..fa07531c --- /dev/null +++ b/allegro/src/raspberrypi/picursor.h @@ -0,0 +1,30 @@ +static uint32_t default_cursor[] = { + 0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0xff000000,0xff000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0xff000000,0xff000000,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0xff000000,0xff000000,0xffffffff,0xffffffff,0xffffffff,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0xff000000,0xff000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xff000000,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xff000000,0xff000000,0xffffffff,0xffffffff,0xffffffff,0xff000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xff000000,0xff000000,0xffffffff,0xffffffff,0xff000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xff000000,0xff000000,0xff000000,0xff000000,0x00000000,0x00000000,0x00000000 +}; diff --git a/allegro/src/raspberrypi/pidisplay.c b/allegro/src/raspberrypi/pidisplay.c new file mode 100644 index 00000000..63a1363e --- /dev/null +++ b/allegro/src/raspberrypi/pidisplay.c @@ -0,0 +1,756 @@ +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/internal/aintern_raspberrypi.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xwindow.h" + +#include +#include +#include + +#include + +#include "picursor.h" +#define DEFAULT_CURSOR_WIDTH 17 +#define DEFAULT_CURSOR_HEIGHT 28 + +static ALLEGRO_DISPLAY_INTERFACE *vt; + +static EGLDisplay egl_display; +static EGLSurface egl_window; +static EGLContext egl_context; +static DISPMANX_UPDATE_HANDLE_T dispman_update; +static DISPMANX_RESOURCE_HANDLE_T cursor_resource; +static DISPMANX_DISPLAY_HANDLE_T dispman_display; +static DISPMANX_ELEMENT_HANDLE_T cursor_element; +static VC_RECT_T dst_rect; +static VC_RECT_T src_rect; +static bool cursor_added = false; +static float mouse_scale_ratio_x = 1.0f, mouse_scale_ratio_y = 1.0f; + +struct ALLEGRO_DISPLAY_RASPBERRYPI_EXTRA { +}; + +static int pot(int n) +{ + int i = 1; + while (i < n) { + i = i * 2; + } + return i; +} + +static void set_cursor_data(ALLEGRO_DISPLAY_RASPBERRYPI *d, uint32_t *data, int width, int height) +{ + al_free(d->cursor_data); + int spitch = sizeof(uint32_t) * width; + int dpitch = pot(spitch); + d->cursor_data = al_malloc(dpitch * height); + int y; + for (y = 0; y < height; y++) { + uint8_t *p1 = (uint8_t *)d->cursor_data + y * dpitch; + uint8_t *p2 = (uint8_t *)data + y * spitch; + memcpy(p1, p2, spitch); + } + d->cursor_width = width; + d->cursor_height = height; +} + +static void delete_cursor_data(ALLEGRO_DISPLAY_RASPBERRYPI *d) +{ + al_free(d->cursor_data); + d->cursor_data = NULL; +} + +static void show_cursor(ALLEGRO_DISPLAY_RASPBERRYPI *d) +{ + if (d->cursor_data == NULL) { + return; + } + + int width = d->cursor_width; + int height = d->cursor_height; + + if (cursor_added == false) { + uint32_t unused; + cursor_resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, width, height, &unused); + + VC_RECT_T r; + r.x = 0; + r.y = 0; + r.width = width; + r.height = height; + + int dpitch = pot(sizeof(uint32_t) * width); + + dispman_update = vc_dispmanx_update_start(0); + vc_dispmanx_resource_write_data(cursor_resource, VC_IMAGE_ARGB8888, dpitch, d->cursor_data, &r); + vc_dispmanx_update_submit_sync(dispman_update); + + ALLEGRO_MOUSE_STATE state; + al_get_mouse_state(&state); + + dst_rect.x = state.x+d->cursor_offset_x; + dst_rect.y = state.y+d->cursor_offset_y; + dst_rect.width = width; + dst_rect.height = height; + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = width << 16; + src_rect.height = height << 16; + + dispman_update = vc_dispmanx_update_start(0); + + cursor_element = vc_dispmanx_element_add( + dispman_update, + dispman_display, + 0/*layer*/, + &dst_rect, + cursor_resource, + &src_rect, + DISPMANX_PROTECTION_NONE, + 0 /*alpha*/, + 0/*clamp*/, + 0/*transform*/ + ); + + vc_dispmanx_update_submit_sync(dispman_update); + + cursor_added = true; + } + else { + ALLEGRO_DISPLAY *disp = (ALLEGRO_DISPLAY *)d; + VC_RECT_T src, dst; + src.x = 0; + src.y = 0; + src.width = d->cursor_width << 16; + src.height = d->cursor_height << 16; + ALLEGRO_MOUSE_STATE st; + al_get_mouse_state(&st); + st.x = (st.x+0.5) * d->screen_width / disp->w; + st.y = (st.y+0.5) * d->screen_height / disp->h; + dst.x = st.x+d->cursor_offset_x; + dst.y = st.y+d->cursor_offset_y; + dst.width = d->cursor_width; + dst.height = d->cursor_height; + dispman_update = vc_dispmanx_update_start(0); + vc_dispmanx_element_change_attributes( + dispman_update, + cursor_element, + 0, + 0, + 0, + &dst, + &src, + 0, + 0 + ); + vc_dispmanx_update_submit_sync(dispman_update); + } +} + +static void hide_cursor(ALLEGRO_DISPLAY_RASPBERRYPI *d) +{ + (void)d; + + if (!cursor_added) { + return; + } + + dispman_update = vc_dispmanx_update_start(0); + vc_dispmanx_element_remove(dispman_update, cursor_element); + vc_dispmanx_update_submit_sync(dispman_update); + vc_dispmanx_resource_delete(cursor_resource); + cursor_added = false; +} + +/* Helper to set up GL state as we want it. */ +static void setup_gl(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; + + if (ogl->backbuffer) + _al_ogl_resize_backbuffer(ogl->backbuffer, d->w, d->h); + else + ogl->backbuffer = _al_ogl_create_backbuffer(d); +} + +void _al_raspberrypi_get_screen_info(int *dx, int *dy, + int *screen_width, int *screen_height) +{ + graphics_get_display_size(0 /* LCD */, (uint32_t *)screen_width, (uint32_t *)screen_height); + + /* On TV-out the visible area (area used by X and console) + * is different from that reported by the bcm functions. We + * have to 1) read fbwidth and fbheight from /proc/cmdline + * and also overscan parameters from /boot/config.txt so our + * displays are the same size and overlap perfectly. + */ + *dx = 0; + *dy = 0; + FILE *cmdline = fopen("/proc/cmdline", "r"); + if (cmdline) { + char line[1000]; + int i; + for (i = 0; i < 999; i++) { + int c = fgetc(cmdline); + if (c == EOF) break; + line[i] = c; + } + line[i] = 0; + const char *p = strstr(line, "fbwidth="); + if (p) { + const char *p2 = strstr(line, "fbheight="); + if (p2) { + p += strlen("fbwidth="); + p2 += strlen("fbheight="); + int w = atoi(p); + int h = atoi(p2); + const ALLEGRO_FILE_INTERFACE *file_interface = al_get_new_file_interface(); + al_set_standard_file_interface(); + ALLEGRO_CONFIG *cfg = al_load_config_file("/boot/config.txt"); + if (cfg) { + const char *disable_overscan = + al_get_config_value( + cfg, "", "disable_overscan" + ); + // If overscan parameters are disabled don't process + if (!disable_overscan || + (disable_overscan && + (!strcasecmp(disable_overscan, "false") || + atoi(disable_overscan) == 0))) { + const char *left = al_get_config_value( + cfg, "", "overscan_left"); + const char *right = al_get_config_value( + cfg, "", "overscan_right"); + const char *top = al_get_config_value( + cfg, "", "overscan_top"); + const char *bottom = al_get_config_value( + cfg, "", "overscan_bottom"); + int xx = left ? atoi(left) : 0; + xx -= right ? atoi(right) : 0; + int yy = top ? atoi(top) : 0; + yy -= bottom ? atoi(bottom) : 0; + *dx = (*screen_width - w + xx) / 2; + *dy = (*screen_height - h + yy) / 2; + *screen_width = w; + *screen_height = h; + } + else { + *dx = (*screen_width - w) / 2; + *dy = (*screen_height - h) / 2; + *screen_width = w; + *screen_height = h; + } + al_destroy_config(cfg); + } + else { + printf("Couldn't open /boot/config.txt\n"); + } + al_set_new_file_interface(file_interface); + } + } + fclose(cmdline); + } +} + +void _al_raspberrypi_get_mouse_scale_ratios(float *x, float *y) +{ + *x = mouse_scale_ratio_x; + *y = mouse_scale_ratio_y; +} + +static bool pi_create_display(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_RASPBERRYPI *d = (void *)display; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings(); + + egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (egl_display == EGL_NO_DISPLAY) { + return false; + } + + int major, minor; + if (!eglInitialize(egl_display, &major, &minor)) { + return false; + } + + static EGLint attrib_list[] = + { + EGL_DEPTH_SIZE, 0, + EGL_STENCIL_SIZE, 0, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + + attrib_list[1] = eds->settings[ALLEGRO_DEPTH_SIZE]; + attrib_list[3] = eds->settings[ALLEGRO_STENCIL_SIZE]; + + if (eds->settings[ALLEGRO_RED_SIZE] || eds->settings[ALLEGRO_GREEN_SIZE] || + eds->settings[ALLEGRO_BLUE_SIZE] || + eds->settings[ALLEGRO_ALPHA_SIZE]) { + attrib_list[5] = eds->settings[ALLEGRO_RED_SIZE]; + attrib_list[7] = eds->settings[ALLEGRO_GREEN_SIZE]; + attrib_list[9] = eds->settings[ALLEGRO_BLUE_SIZE]; + attrib_list[11] = eds->settings[ALLEGRO_ALPHA_SIZE]; + } + else if (eds->settings[ALLEGRO_COLOR_SIZE] == 16) { + attrib_list[5] = 5; + attrib_list[7] = 6; + attrib_list[9] = 5; + attrib_list[11] = 0; + } + + EGLConfig config; + int num_configs; + + if (!eglChooseConfig(egl_display, attrib_list, &config, 1, &num_configs)) { + return false; + } + + eglBindAPI(EGL_OPENGL_ES_API); + + int es_ver = (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) ? + 2 : 1; + + static EGLint ctxattr[3] = { + EGL_CONTEXT_CLIENT_VERSION, 0xDEADBEEF, + EGL_NONE + }; + + ctxattr[1] = es_ver; + + egl_context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT, ctxattr); + if (egl_context == EGL_NO_CONTEXT) { + return false; + } + + static EGL_DISPMANX_WINDOW_T nativewindow; + DISPMANX_ELEMENT_HANDLE_T dispman_element; + + int dx, dy, screen_width, screen_height; + _al_raspberrypi_get_screen_info(&dx, &dy, &screen_width, &screen_height); + + mouse_scale_ratio_x = (float)display->w / screen_width; + mouse_scale_ratio_y = (float)display->h / screen_height; + + d->cursor_offset_x = dx; + d->cursor_offset_y = dy; + + dst_rect.x = dx; + dst_rect.y = dy; + dst_rect.width = screen_width; + dst_rect.height = screen_height; + + d->screen_width = screen_width; + d->screen_height = screen_height; + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = display->w << 16; + src_rect.height = display->h << 16; + + dispman_display = vc_dispmanx_display_open(0 /* LCD */); + dispman_update = vc_dispmanx_update_start(0); + + dispman_element = vc_dispmanx_element_add ( + dispman_update, + dispman_display, + 0/*layer*/, + &dst_rect, + 0/*src*/, + &src_rect, + DISPMANX_PROTECTION_NONE, + 0 /*alpha*/, + 0/*clamp*/, + DISPMANX_NO_ROTATE/*transform*/ + ); + + nativewindow.element = dispman_element; + nativewindow.width = display->w; + nativewindow.height = display->h; + vc_dispmanx_update_submit_sync(dispman_update); + + egl_window = eglCreateWindowSurface( + egl_display, config, &nativewindow, NULL); + if (egl_window == EGL_NO_SURFACE) { + return false; + } + + if (!eglMakeCurrent(egl_display, egl_window, egl_window, egl_context)) { + return false; + } + + if (!getenv("DISPLAY")) { + _al_evdev_set_mouse_range(0, 0, display->w-1, display->h-1); + } + + return true; +} + +static ALLEGRO_DISPLAY *raspberrypi_create_display(int w, int h) +{ + ALLEGRO_DISPLAY_RASPBERRYPI *d = al_calloc(1, sizeof *d); + ALLEGRO_DISPLAY *display = (void*)d; + ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl); + display->ogl_extras = ogl; + display->vt = _al_get_raspberrypi_display_interface(); + display->flags = al_get_new_display_flags(); + + ALLEGRO_SYSTEM_RASPBERRYPI *system = (void *)al_get_system_driver(); + + /* Add ourself to the list of displays. */ + ALLEGRO_DISPLAY_RASPBERRYPI **add; + add = _al_vector_alloc_back(&system->system.displays); + *add = d; + + /* Each display is an event source. */ + _al_event_source_init(&display->es); + + display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; + + display->w = w; + display->h = h; + + display->flags |= ALLEGRO_OPENGL; +#ifdef ALLEGRO_CFG_OPENGLES2 + display->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + display->flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + + if (!pi_create_display(display)) { + // FIXME: cleanup + return NULL; + } + + if (getenv("DISPLAY")) { + _al_mutex_lock(&system->lock); + Window root = RootWindow( + system->x11display, DefaultScreen(system->x11display)); + XWindowAttributes attr; + XGetWindowAttributes(system->x11display, root, &attr); + d->window = XCreateWindow( + system->x11display, + root, + 0, + 0, + attr.width, + attr.height, + 0, 0, + InputOnly, + DefaultVisual(system->x11display, 0), + 0, + NULL + ); + XGetWindowAttributes(system->x11display, d->window, &attr); + XSelectInput( + system->x11display, + d->window, + PointerMotionMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask + ); + XMapWindow(system->x11display, d->window); + _al_xwin_reset_size_hints(display); + _al_xwin_set_fullscreen_window(display, 2); + _al_xwin_set_size_hints(display, INT_MAX, INT_MAX); + d->wm_delete_window_atom = XInternAtom(system->x11display, + "WM_DELETE_WINDOW", False); + XSetWMProtocols(system->x11display, d->window, &d->wm_delete_window_atom, 1); + _al_mutex_unlock(&system->lock); + } + + al_grab_mouse(display); + + _al_ogl_manage_extensions(display); + _al_ogl_set_extensions(ogl->extension_api); + + setup_gl(display); + + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); + + if (al_is_mouse_installed() && !getenv("DISPLAY")) { + _al_evdev_set_mouse_range(0, 0, display->w-1, display->h-1); + } + + set_cursor_data(d, default_cursor, DEFAULT_CURSOR_WIDTH, DEFAULT_CURSOR_HEIGHT); + + /* Fill in opengl version */ + const int v = display->ogl_extras->ogl_info.version; + display->extra_settings.settings[ALLEGRO_OPENGL_MAJOR_VERSION] = (v >> 24) & 0xFF; + display->extra_settings.settings[ALLEGRO_OPENGL_MINOR_VERSION] = (v >> 16) & 0xFF; + + return display; +} + +static void raspberrypi_destroy_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_RASPBERRYPI *pidisplay = (ALLEGRO_DISPLAY_RASPBERRYPI *)d; + + hide_cursor(pidisplay); + delete_cursor_data(pidisplay); + + _al_set_current_display_only(d); + + while (d->bitmaps._size > 0) { + ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref_back(&d->bitmaps); + ALLEGRO_BITMAP *b = *bptr; + _al_convert_to_memory_bitmap(b); + } + + _al_event_source_free(&d->es); + + ALLEGRO_SYSTEM_RASPBERRYPI *system = (void *)al_get_system_driver(); + _al_vector_find_and_delete(&system->system.displays, &d); + + eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroySurface(egl_display, egl_window); + eglDestroyContext(egl_display, egl_context); + eglTerminate(egl_display); + + if (getenv("DISPLAY")) { + _al_mutex_lock(&system->lock); + XUnmapWindow(system->x11display, pidisplay->window); + XDestroyWindow(system->x11display, pidisplay->window); + _al_mutex_unlock(&system->lock); + } + + if (system->mouse_grab_display == d) { + system->mouse_grab_display = NULL; + } +} + +static bool raspberrypi_set_current_display(ALLEGRO_DISPLAY *d) +{ + (void)d; +// FIXME + _al_ogl_update_render_state(d); + return true; +} + +static int raspberrypi_get_orientation(ALLEGRO_DISPLAY *d) +{ + (void)d; + return ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES; +} + + +/* There can be only one window and only one OpenGL context, so all bitmaps + * are compatible. + */ +static bool raspberrypi_is_compatible_bitmap( + ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap +) { + (void)display; + (void)bitmap; + return true; +} + +/* Resizing is not possible. */ +static bool raspberrypi_resize_display(ALLEGRO_DISPLAY *d, int w, int h) +{ + (void)d; + (void)w; + (void)h; + return false; +} + +/* The icon must be provided in the Info.plist file, it cannot be changed + * at runtime. + */ +static void raspberrypi_set_icons(ALLEGRO_DISPLAY *d, int num_icons, ALLEGRO_BITMAP *bitmaps[]) +{ + (void)d; + (void)num_icons; + (void)bitmaps; +} + +/* There is no way to leave fullscreen so no window title is visible. */ +static void raspberrypi_set_window_title(ALLEGRO_DISPLAY *display, char const *title) +{ + (void)display; + (void)title; +} + +/* The window always spans the entire screen right now. */ +static void raspberrypi_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +{ + (void)display; + (void)x; + (void)y; +} + +/* The window cannot be constrained. */ +static bool raspberrypi_set_window_constraints(ALLEGRO_DISPLAY *display, + int min_w, int min_h, int max_w, int max_h) +{ + (void)display; + (void)min_w; + (void)min_h; + (void)max_w; + (void)max_h; + return false; +} + +/* Always fullscreen. */ +static bool raspberrypi_set_display_flag(ALLEGRO_DISPLAY *display, + int flag, bool onoff) +{ + (void)display; + (void)flag; + (void)onoff; + return false; +} + +static void raspberrypi_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + (void)display; + *x = 0; + *y = 0; +} + +/* The window cannot be constrained. */ +static bool raspberrypi_get_window_constraints(ALLEGRO_DISPLAY *display, + int *min_w, int *min_h, int *max_w, int *max_h) +{ + (void)display; + (void)min_w; + (void)min_h; + (void)max_w; + (void)max_h; + return false; +} + +static bool raspberrypi_wait_for_vsync(ALLEGRO_DISPLAY *display) +{ + (void)display; + return false; +} + +static void raspberrypi_flip_display(ALLEGRO_DISPLAY *disp) +{ + eglSwapBuffers(egl_display, egl_window); + + if (cursor_added) { + show_cursor((ALLEGRO_DISPLAY_RASPBERRYPI *)disp); + } +} + +static void raspberrypi_update_display_region(ALLEGRO_DISPLAY *d, int x, int y, + int w, int h) +{ + (void)x; + (void)y; + (void)w; + (void)h; + raspberrypi_flip_display(d); +} + +static bool raspberrypi_acknowledge_resize(ALLEGRO_DISPLAY *d) +{ + setup_gl(d); + return true; +} + +static bool raspberrypi_show_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_RASPBERRYPI *d = (void *)display; + hide_cursor(d); + show_cursor(d); + return true; +} + +static bool raspberrypi_hide_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_RASPBERRYPI *d = (void *)display; + hide_cursor(d); + return true; +} + +static bool raspberrypi_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) +{ + ALLEGRO_DISPLAY_RASPBERRYPI *d = (void *)display; + ALLEGRO_MOUSE_CURSOR_RASPBERRYPI *pi_cursor = (void *)cursor; + int w = al_get_bitmap_width(pi_cursor->bitmap); + int h = al_get_bitmap_height(pi_cursor->bitmap); + int pitch = w * sizeof(uint32_t); + uint32_t *data = al_malloc(pitch * h); + ALLEGRO_LOCKED_REGION *lr = al_lock_bitmap(pi_cursor->bitmap, ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_READONLY); + int y; + for (y = 0; y < h; y++) { + uint8_t *p = (uint8_t *)lr->data + lr->pitch * y; + uint8_t *p2 = (uint8_t *)data + pitch * y; + memcpy(p2, p, pitch); + } + al_unlock_bitmap(pi_cursor->bitmap); + delete_cursor_data(d); + set_cursor_data(d, data, w, h); + al_free(data); + if (cursor_added) { + hide_cursor(d); + show_cursor(d); + } + return true; +} + +static bool raspberrypi_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +{ + (void)cursor_id; + ALLEGRO_DISPLAY_RASPBERRYPI *d = (void *)display; + delete_cursor_data(d); + set_cursor_data(d, default_cursor, DEFAULT_CURSOR_WIDTH, DEFAULT_CURSOR_HEIGHT); + return true; +} + +/* Obtain a reference to this driver. */ +ALLEGRO_DISPLAY_INTERFACE *_al_get_raspberrypi_display_interface(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + + vt->create_display = raspberrypi_create_display; + vt->destroy_display = raspberrypi_destroy_display; + vt->set_current_display = raspberrypi_set_current_display; + vt->flip_display = raspberrypi_flip_display; + vt->update_display_region = raspberrypi_update_display_region; + vt->acknowledge_resize = raspberrypi_acknowledge_resize; + vt->create_bitmap = _al_ogl_create_bitmap; + vt->get_backbuffer = _al_ogl_get_backbuffer; + vt->set_target_bitmap = _al_ogl_set_target_bitmap; + + vt->get_orientation = raspberrypi_get_orientation; + + vt->is_compatible_bitmap = raspberrypi_is_compatible_bitmap; + vt->resize_display = raspberrypi_resize_display; + vt->set_icons = raspberrypi_set_icons; + vt->set_window_title = raspberrypi_set_window_title; + vt->set_window_position = raspberrypi_set_window_position; + vt->get_window_position = raspberrypi_get_window_position; + vt->set_window_constraints = raspberrypi_set_window_constraints; + vt->get_window_constraints = raspberrypi_get_window_constraints; + vt->set_display_flag = raspberrypi_set_display_flag; + vt->wait_for_vsync = raspberrypi_wait_for_vsync; + + vt->update_render_state = _al_ogl_update_render_state; + + _al_ogl_add_drawing_functions(vt); + + vt->set_mouse_cursor = raspberrypi_set_mouse_cursor; + vt->set_system_mouse_cursor = raspberrypi_set_system_mouse_cursor; + vt->show_mouse_cursor = raspberrypi_show_mouse_cursor; + vt->hide_mouse_cursor = raspberrypi_hide_mouse_cursor; + + return vt; +} + diff --git a/allegro/src/raspberrypi/pisystem.c b/allegro/src/raspberrypi/pisystem.c new file mode 100644 index 00000000..bf4d597c --- /dev/null +++ b/allegro/src/raspberrypi/pisystem.c @@ -0,0 +1,206 @@ +#include + +#include "allegro5/allegro.h" +#include "allegro5/platform/aintraspberrypi.h" +#include "allegro5/internal/aintern_raspberrypi.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/platform/aintlnx.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xevents.h" +#include "allegro5/internal/aintern_xmouse.h" + +#include + +#include + +ALLEGRO_DEBUG_CHANNEL("system") + +static ALLEGRO_SYSTEM_INTERFACE *pi_vt; + +static ALLEGRO_SYSTEM *pi_initialize(int flags) +{ + (void)flags; + + ALLEGRO_SYSTEM_RASPBERRYPI *s; + + bcm_host_init(); + + s = al_calloc(1, sizeof *s); + + _al_vector_init(&s->system.displays, sizeof (ALLEGRO_DISPLAY_RASPBERRYPI *)); + + _al_unix_init_time(); + + if (getenv("DISPLAY")) { + _al_mutex_init_recursive(&s->lock); + s->x11display = XOpenDisplay(0); + _al_thread_create(&s->thread, _al_xwin_background_thread, s); + ALLEGRO_INFO("events thread spawned.\n"); + /* We need to put *some* atom into the ClientMessage we send for + * faking mouse movements with al_set_mouse_xy - so let's ask X11 + * for one here. + */ + s->AllegroAtom = XInternAtom(s->x11display, "AllegroAtom", False); + } + + s->inhibit_screensaver = false; + + s->system.vt = pi_vt; + + return &s->system; +} + +static void pi_shutdown_system(void) +{ + ALLEGRO_SYSTEM *s = al_get_system_driver(); + ALLEGRO_SYSTEM_RASPBERRYPI *spi = (void *)s; + + ALLEGRO_INFO("shutting down.\n"); + + /* Close all open displays. */ + while (_al_vector_size(&s->displays) > 0) { + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); + ALLEGRO_DISPLAY *d = *dptr; + al_destroy_display(d); + } + _al_vector_free(&s->displays); + + if (getenv("DISPLAY")) { + _al_thread_join(&spi->thread); + XCloseDisplay(spi->x11display); + } + + bcm_host_deinit(); + + raise(SIGINT); + + al_free(spi); +} + +static ALLEGRO_KEYBOARD_DRIVER *pi_get_keyboard_driver(void) +{ + if (getenv("DISPLAY")) { + return _al_xwin_keyboard_driver(); + } + return _al_linux_keyboard_driver_list[0].driver; +} + +static ALLEGRO_MOUSE_DRIVER *pi_get_mouse_driver(void) +{ + if (getenv("DISPLAY")) { + return _al_xwin_mouse_driver(); + } + return _al_linux_mouse_driver_list[0].driver; +} + +static ALLEGRO_JOYSTICK_DRIVER *pi_get_joystick_driver(void) +{ + return _al_joystick_driver_list[0].driver; +} + +static int pi_get_num_video_adapters(void) +{ + return 1; +} + +static bool pi_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +{ + (void)adapter; + int dx, dy, w, h; + _al_raspberrypi_get_screen_info(&dx, &dy, &w, &h); + info->x1 = 0; + info->y1 = 0; + info->x2 = w; + info->y2 = h; + return true; +} + +static bool pi_get_cursor_position(int *ret_x, int *ret_y) +{ + // FIXME: + (void)ret_x; + (void)ret_y; + return false; +} + +static bool pi_inhibit_screensaver(bool inhibit) +{ + ALLEGRO_SYSTEM_RASPBERRYPI *system = (void *)al_get_system_driver(); + + system->inhibit_screensaver = inhibit; + return true; +} + +static int pi_get_num_display_modes(void) +{ + return 1; +} + +static ALLEGRO_DISPLAY_MODE *pi_get_display_mode(int mode, ALLEGRO_DISPLAY_MODE *dm) +{ + (void)mode; + int dx, dy, w, h; + _al_raspberrypi_get_screen_info(&dx, &dy, &w, &h); + dm->width = w; + dm->height = h; + dm->format = 0; // FIXME + dm->refresh_rate = 60; + return dm; +} + +static ALLEGRO_MOUSE_CURSOR *pi_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int focus_x_ignored, int focus_y_ignored) +{ + (void)focus_x_ignored; + (void)focus_y_ignored; + + ALLEGRO_STATE state; + al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS | ALLEGRO_STATE_TARGET_BITMAP); + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ARGB_8888); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + ALLEGRO_BITMAP *cursor_bmp = al_clone_bitmap(bmp); + ALLEGRO_MOUSE_CURSOR_RASPBERRYPI *cursor = al_malloc(sizeof(ALLEGRO_MOUSE_CURSOR_RASPBERRYPI)); + cursor->bitmap = cursor_bmp; + al_restore_state(&state); + return (ALLEGRO_MOUSE_CURSOR *)cursor; +} + +static void pi_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) +{ + ALLEGRO_MOUSE_CURSOR_RASPBERRYPI *pi_cursor = (void *)cursor; + al_destroy_bitmap(pi_cursor->bitmap); + al_free(pi_cursor); +} + +/* Internal function to get a reference to this driver. */ +ALLEGRO_SYSTEM_INTERFACE *_al_system_raspberrypi_driver(void) +{ + if (pi_vt) + return pi_vt; + + pi_vt = al_calloc(1, sizeof *pi_vt); + + pi_vt->id = ALLEGRO_SYSTEM_ID_RASPBERRYPI; + pi_vt->initialize = pi_initialize; + pi_vt->get_display_driver = _al_get_raspberrypi_display_interface; + pi_vt->get_keyboard_driver = pi_get_keyboard_driver; + pi_vt->get_mouse_driver = pi_get_mouse_driver; + pi_vt->get_joystick_driver = pi_get_joystick_driver; + pi_vt->get_num_display_modes = pi_get_num_display_modes; + pi_vt->get_display_mode = pi_get_display_mode; + pi_vt->shutdown_system = pi_shutdown_system; + pi_vt->get_num_video_adapters = pi_get_num_video_adapters; + pi_vt->get_monitor_info = pi_get_monitor_info; + pi_vt->create_mouse_cursor = pi_create_mouse_cursor; + pi_vt->destroy_mouse_cursor = pi_destroy_mouse_cursor; + pi_vt->get_cursor_position = pi_get_cursor_position; + pi_vt->get_path = _al_unix_get_path; + pi_vt->inhibit_screensaver = pi_inhibit_screensaver; + pi_vt->get_time = _al_unix_get_time; + pi_vt->rest = _al_unix_rest; + pi_vt->init_timeout = _al_unix_init_timeout; + + return pi_vt; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/scanline_drawers.inc b/allegro/src/scanline_drawers.inc new file mode 100644 index 00000000..a08894a2 --- /dev/null +++ b/allegro/src/scanline_drawers.inc @@ -0,0 +1,2677 @@ +// Warning: This file was created by make_scanline_drawers.py - do not edit. + +#if __GNUC__ +#define _AL_EXPECT_FAIL(expr) __builtin_expect((expr), 0) +#else +#define _AL_EXPECT_FAIL(expr) (expr) +#endif + +static void shader_solid_any_draw_shade(uintptr_t state, int x1, int y, int x2) +{ + state_solid_any_2d *s = (state_solid_any_2d *) state; + ALLEGRO_COLOR cur_color = s->cur_color; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + int op, src_mode, dst_mode; + int op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR const_color; + al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + const_color = al_get_blend_color(); + + { + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { + + { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + } + } + } + } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + } + } + } else { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + } + } + } + } + } + } +} + +static void shader_solid_any_draw_opaque(uintptr_t state, int x1, int y, int x2) +{ + state_solid_any_2d *s = (state_solid_any_2d *) state; + ALLEGRO_COLOR cur_color = s->cur_color; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + { + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); + + } + } + } else { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); + + } + } + } + } + } + } +} + +static void shader_grad_any_draw_shade(uintptr_t state, int x1, int y, int x2) +{ + state_grad_any_2d *gs = (state_grad_any_2d *) state; + state_solid_any_2d *s = &gs->solid; + ALLEGRO_COLOR cur_color = s->cur_color; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + cur_color.r += gs->color_dx.r * -x1; + cur_color.g += gs->color_dx.g * -x1; + cur_color.b += gs->color_dx.b * -x1; + cur_color.a += gs->color_dx.a * -x1; + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + int op, src_mode, dst_mode; + int op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR const_color; + al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + const_color = al_get_blend_color(); + + { + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { + + { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } + } + } +} + +static void shader_grad_any_draw_opaque(uintptr_t state, int x1, int y, int x2) +{ + state_grad_any_2d *gs = (state_grad_any_2d *) state; + state_solid_any_2d *s = &gs->solid; + ALLEGRO_COLOR cur_color = s->cur_color; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + cur_color.r += gs->color_dx.r * -x1; + cur_color.g += gs->color_dx.g * -x1; + cur_color.b += gs->color_dx.b * -x1; + cur_color.a += gs->color_dx.a * -x1; + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + { + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + { + for (; x1 <= x2; x1++) { + ALLEGRO_COLOR src_color = cur_color; + + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } + } + } +} + +static void shader_texture_solid_any_draw_shade(uintptr_t state, int x1, int y, int x2) +{ + state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; + + float u = s->u; + float v = s->v; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + u += s->du_dx * -x1; + v += s->dv_dx * -x1; + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + int op, src_mode, dst_mode; + int op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR const_color; + al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + const_color = al_get_blend_color(); + + { + const int offset_x = s->texture->parent ? s->texture->xofs : 0; + const int offset_y = s->texture->parent ? s->texture->yofs : 0; + ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; + const int src_format = texture->locked_region.format; + const int src_size = texture->locked_region.pixel_size; + + /* Ensure u in [0, s->w) and v in [0, s->h). */ + while (u < 0) + u += s->w; + while (v < 0) + v += s->h; + u = fmodf(u, s->w); + v = fmodf(v, s->h); + ASSERT(0 <= u); + ASSERT(u < s->w); + ASSERT(0 <= v); + ASSERT(v < s->h); + + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } + } + } +} + +static void shader_texture_solid_any_draw_shade_white(uintptr_t state, int x1, int y, int x2) +{ + state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; + + float u = s->u; + float v = s->v; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + u += s->du_dx * -x1; + v += s->dv_dx * -x1; + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + int op, src_mode, dst_mode; + int op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR const_color; + al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + const_color = al_get_blend_color(); + + { + const int offset_x = s->texture->parent ? s->texture->xofs : 0; + const int offset_y = s->texture->parent ? s->texture->yofs : 0; + ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; + const int src_format = texture->locked_region.format; + const int src_size = texture->locked_region.pixel_size; + + /* Ensure u in [0, s->w) and v in [0, s->h). */ + while (u < 0) + u += s->w; + while (v < 0) + v += s->h; + u = fmodf(u, s->w); + v = fmodf(v, s->h); + ASSERT(0 <= u); + ASSERT(u < s->w); + ASSERT(0 <= v); + ASSERT(v < s->h); + + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } + } + } +} + +static void shader_texture_solid_any_draw_opaque(uintptr_t state, int x1, int y, int x2) +{ + state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; + + float u = s->u; + float v = s->v; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + u += s->du_dx * -x1; + v += s->dv_dx * -x1; + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + { + const int offset_x = s->texture->parent ? s->texture->xofs : 0; + const int offset_y = s->texture->parent ? s->texture->yofs : 0; + ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; + const int src_format = texture->locked_region.format; + const int src_size = texture->locked_region.pixel_size; + + /* Ensure u in [0, s->w) and v in [0, s->h). */ + while (u < 0) + u += s->w; + while (v < 0) + v += s->h; + u = fmodf(u, s->w); + v = fmodf(v, s->h); + ASSERT(0 <= u); + ASSERT(u < s->w); + ASSERT(0 <= v); + ASSERT(v < s->h); + + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + + { + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + 0; + const int src_y = (vv >> 16) + 0; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + } + } + } else { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + + { + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + 0; + const int src_y = (vv >> 16) + 0; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + } + } + } else { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, s->cur_color); + + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } + } + } +} + +static void shader_texture_solid_any_draw_opaque_white(uintptr_t state, int x1, int y, int x2) +{ + state_texture_solid_any_2d *s = (state_texture_solid_any_2d *) state; + + float u = s->u; + float v = s->v; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + u += s->du_dx * -x1; + v += s->dv_dx * -x1; + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + { + const int offset_x = s->texture->parent ? s->texture->xofs : 0; + const int offset_y = s->texture->parent ? s->texture->yofs : 0; + ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; + const int src_format = texture->locked_region.format; + const int src_size = texture->locked_region.pixel_size; + + /* Ensure u in [0, s->w) and v in [0, s->h). */ + while (u < 0) + u += s->w; + while (v < 0) + v += s->h; + u = fmodf(u, s->w); + v = fmodf(v, s->h); + ASSERT(0 <= u); + ASSERT(u < s->w); + ASSERT(0 <= v); + ASSERT(v < s->h); + + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (dst_format == src_format && src_size == 4) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + + { + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + 0; + const int src_y = (vv >> 16) + 0; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 4; + + switch (4) { + case 4: + memcpy(dst_data, src_data, 4); + dst_data += 4; + break; + case 3: + memcpy(dst_data, src_data, 3); + dst_data += 3; + break; + case 2: + *dst_data++ = *src_data++; + *dst_data++ = *src_data; + break; + case 1: + *dst_data++ = *src_data; + break; + } + + uu += du_dx; + vv += dv_dx; + + } + } + } else { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 4; + + switch (4) { + case 4: + memcpy(dst_data, src_data, 4); + dst_data += 4; + break; + case 3: + memcpy(dst_data, src_data, 3); + dst_data += 3; + break; + case 2: + *dst_data++ = *src_data++; + *dst_data++ = *src_data; + break; + case 1: + *dst_data++ = *src_data; + break; + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else if (dst_format == src_format && src_size == 3) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + + { + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + 0; + const int src_y = (vv >> 16) + 0; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 3; + + switch (3) { + case 4: + memcpy(dst_data, src_data, 4); + dst_data += 4; + break; + case 3: + memcpy(dst_data, src_data, 3); + dst_data += 3; + break; + case 2: + *dst_data++ = *src_data++; + *dst_data++ = *src_data; + break; + case 1: + *dst_data++ = *src_data; + break; + } + + uu += du_dx; + vv += dv_dx; + + } + } + } else { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 3; + + switch (3) { + case 4: + memcpy(dst_data, src_data, 4); + dst_data += 4; + break; + case 3: + memcpy(dst_data, src_data, 3); + dst_data += 3; + break; + case 2: + *dst_data++ = *src_data++; + *dst_data++ = *src_data; + break; + case 1: + *dst_data++ = *src_data; + break; + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else if (dst_format == src_format && src_size == 2) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + + { + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + 0; + const int src_y = (vv >> 16) + 0; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 2; + + switch (2) { + case 4: + memcpy(dst_data, src_data, 4); + dst_data += 4; + break; + case 3: + memcpy(dst_data, src_data, 3); + dst_data += 3; + break; + case 2: + *dst_data++ = *src_data++; + *dst_data++ = *src_data; + break; + case 1: + *dst_data++ = *src_data; + break; + } + + uu += du_dx; + vv += dv_dx; + + } + } + } else { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * 2; + + switch (2) { + case 4: + memcpy(dst_data, src_data, 4); + dst_data += 4; + break; + case 3: + memcpy(dst_data, src_data, 3); + dst_data += 3; + break; + case 2: + *dst_data++ = *src_data++; + *dst_data++ = *src_data; + break; + case 1: + *dst_data++ = *src_data; + break; + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + + { + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + 0; + const int src_y = (vv >> 16) + 0; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + } + } + } else { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + } + } + } + } + } + } +} + +static void shader_texture_grad_any_draw_shade(uintptr_t state, int x1, int y, int x2) +{ + state_texture_grad_any_2d *gs = (state_texture_grad_any_2d *) state; + state_texture_solid_any_2d *s = &gs->solid; + ALLEGRO_COLOR cur_color = s->cur_color; + + float u = s->u; + float v = s->v; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + u += s->du_dx * -x1; + v += s->dv_dx * -x1; + + cur_color.r += gs->color_dx.r * -x1; + cur_color.g += gs->color_dx.g * -x1; + cur_color.b += gs->color_dx.b * -x1; + cur_color.a += gs->color_dx.a * -x1; + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + int op, src_mode, dst_mode; + int op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR const_color; + al_get_separate_bitmap_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + const_color = al_get_blend_color(); + + { + const int offset_x = s->texture->parent ? s->texture->xofs : 0; + const int offset_y = s->texture->parent ? s->texture->yofs : 0; + ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; + const int src_format = texture->locked_region.format; + const int src_size = texture->locked_region.pixel_size; + + /* Ensure u in [0, s->w) and v in [0, s->h). */ + while (u < 0) + u += s->w; + while (v < 0) + v += s->h; + u = fmodf(u, s->w); + v = fmodf(v, s->h); + ASSERT(0 <= u); + ASSERT(u < s->w); + ASSERT(0 <= v); + ASSERT(v < s->h); + + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ALPHA && src_alpha == ALLEGRO_ALPHA && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_INVERSE_ALPHA && dst_alpha == ALLEGRO_INVERSE_ALPHA) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } else if (op == ALLEGRO_ADD && src_mode == ALLEGRO_ONE && src_alpha == ALLEGRO_ONE && op_alpha == ALLEGRO_ADD && dst_mode == ALLEGRO_ONE && dst_alpha == ALLEGRO_ONE) { + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_alpha_inline(&src_color, &dst_color, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, NULL, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } else if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + { + ALLEGRO_COLOR dst_color; + ALLEGRO_COLOR result; + _AL_INLINE_GET_PIXEL(dst_format, dst_data, dst_color, false); + _al_blend_inline(&src_color, &dst_color, op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &const_color, &result); + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, result, true); + } + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } + } + } +} + +static void shader_texture_grad_any_draw_opaque(uintptr_t state, int x1, int y, int x2) +{ + state_texture_grad_any_2d *gs = (state_texture_grad_any_2d *) state; + state_texture_solid_any_2d *s = &gs->solid; + ALLEGRO_COLOR cur_color = s->cur_color; + + float u = s->u; + float v = s->v; + + ALLEGRO_BITMAP *target = s->target; + + if (target->parent) { + x1 += target->xofs; + x2 += target->xofs; + y += target->yofs; + target = target->parent; + } + + x1 -= target->lock_x; + x2 -= target->lock_x; + y -= target->lock_y; + y--; + + if (y < 0 || y >= target->lock_h) { + return; + } + + if (x1 < 0) { + + u += s->du_dx * -x1; + v += s->dv_dx * -x1; + + cur_color.r += gs->color_dx.r * -x1; + cur_color.g += gs->color_dx.g * -x1; + cur_color.b += gs->color_dx.b * -x1; + cur_color.a += gs->color_dx.a * -x1; + + x1 = 0; + } + + if (x2 > target->lock_w - 1) { + x2 = target->lock_w - 1; + } + + { + { + const int offset_x = s->texture->parent ? s->texture->xofs : 0; + const int offset_y = s->texture->parent ? s->texture->yofs : 0; + ALLEGRO_BITMAP *texture = s->texture->parent ? s->texture->parent : s->texture; + const int src_format = texture->locked_region.format; + const int src_size = texture->locked_region.pixel_size; + + /* Ensure u in [0, s->w) and v in [0, s->h). */ + while (u < 0) + u += s->w; + while (v < 0) + v += s->h; + u = fmodf(u, s->w); + v = fmodf(v, s->h); + ASSERT(0 <= u); + ASSERT(u < s->w); + ASSERT(0 <= v); + ASSERT(v < s->h); + + { + const int dst_format = target->locked_region.format; + uint8_t *dst_data = (uint8_t *) target->lock_data + y * target->locked_region.pitch + x1 * target->locked_region.pixel_size; + + if (dst_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888 && src_format == ALLEGRO_PIXEL_FORMAT_ARGB_8888) { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + + { + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + 0; + const int src_y = (vv >> 16) + 0; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + _AL_INLINE_PUT_PIXEL(ALLEGRO_PIXEL_FORMAT_ARGB_8888, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + uint8_t *lock_data = texture->locked_region.data; + const int src_pitch = texture->locked_region.pitch; + const al_fixed du_dx = al_ftofix(s->du_dx); + const al_fixed dv_dx = al_ftofix(s->dv_dx); + + const float steps = x2 - x1 + 1; + const float end_u = u + steps * s->du_dx; + const float end_v = v + steps * s->dv_dx; + if (end_u >= 0 && end_u < s->w && end_v >= 0 && end_v < s->h) { + + { + al_fixed uu = al_ftofix(u) + ((offset_x - texture->lock_x) << 16); + al_fixed vv = al_ftofix(v) + ((offset_y - texture->lock_y) << 16); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + 0; + const int src_y = (vv >> 16) + 0; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } else { + al_fixed uu = al_ftofix(u); + al_fixed vv = al_ftofix(v); + const int uu_ofs = offset_x - texture->lock_x; + const int vv_ofs = offset_y - texture->lock_y; + const al_fixed w = al_ftofix(s->w); + const al_fixed h = al_ftofix(s->h); + + for (; x1 <= x2; x1++) { + const int src_x = (uu >> 16) + uu_ofs; + const int src_y = (vv >> 16) + vv_ofs; + uint8_t *src_data = lock_data + src_y * src_pitch + src_x * src_size; + + ALLEGRO_COLOR src_color; + _AL_INLINE_GET_PIXEL(src_format, src_data, src_color, false); + + SHADE_COLORS(src_color, cur_color); + + _AL_INLINE_PUT_PIXEL(dst_format, dst_data, src_color, true); + + uu += du_dx; + vv += dv_dx; + + if (_AL_EXPECT_FAIL(uu < 0)) + uu += w; + else if (_AL_EXPECT_FAIL(uu >= w)) + uu -= w; + + if (_AL_EXPECT_FAIL(vv < 0)) + vv += h; + else if (_AL_EXPECT_FAIL(vv >= h)) + vv -= h; + + cur_color.r += gs->color_dx.r; + cur_color.g += gs->color_dx.g; + cur_color.b += gs->color_dx.b; + cur_color.a += gs->color_dx.a; + + } + } + } + } + } + } +} diff --git a/allegro/src/sdl/sdl_display.c b/allegro/src/sdl/sdl_display.c new file mode 100644 index 00000000..3a193949 --- /dev/null +++ b/allegro/src/sdl/sdl_display.c @@ -0,0 +1,562 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL display implementation. + * + * See LICENSE.txt for copyright information. + */ +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/system.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_shader.h" +#include "allegro5/platform/allegro_internal_sdl.h" + +ALLEGRO_DEBUG_CHANNEL("display") + +int _al_win_determine_adapter(void); + +static ALLEGRO_DISPLAY_INTERFACE *vt; + +float _al_sdl_get_display_pixel_ratio(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + int window_width, drawable_width, h; + SDL_GetWindowSize(sdl->window, &window_width, &h); + SDL_GL_GetDrawableSize(sdl->window, &drawable_width, &h); + return drawable_width / (float)window_width; +} + +ALLEGRO_DISPLAY *_al_sdl_find_display(uint32_t window_id) { + unsigned int i; + ALLEGRO_SYSTEM *s = al_get_system_driver(); + for (i = 0; i < _al_vector_size(&s->displays); i++) { + void **v = (void **)_al_vector_ref(&s->displays, i); + ALLEGRO_DISPLAY_SDL *d = *v; + if (SDL_GetWindowID(d->window) == window_id) { + return &d->display; + break; + } + } + return NULL; +} + +void _al_sdl_display_event(SDL_Event *e) +{ + ALLEGRO_EVENT event; + event.display.timestamp = al_get_time(); + + ALLEGRO_DISPLAY *d = NULL; + + if (e->type == SDL_WINDOWEVENT) { + d = _al_sdl_find_display(e->window.windowID); + if (e->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; + } + if (e->window.event == SDL_WINDOWEVENT_FOCUS_LOST) { + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; + } + if (e->window.event == SDL_WINDOWEVENT_CLOSE) { + event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; + } + if (e->window.event == SDL_WINDOWEVENT_RESIZED) { + float ratio = _al_sdl_get_display_pixel_ratio(d); + event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; + event.display.width = e->window.data1 * ratio; + event.display.height = e->window.data2 * ratio; + } + } + if (e->type == SDL_QUIT) { + event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; + /* Use the first display as event source if we have any displays. */ + ALLEGRO_SYSTEM *s = al_get_system_driver(); + if (_al_vector_size(&s->displays) > 0) { + void **v = (void **)_al_vector_ref(&s->displays, 0); + d = *v; + } + } + + if (!d) + return; + ALLEGRO_EVENT_SOURCE *es = &d->es; + _al_event_source_lock(es); + _al_event_source_emit_event(es, &event); + _al_event_source_unlock(es); +} + +static void GLoption(int allegro, int sdl) +{ + int i; + int x = al_get_new_display_option(allegro, &i); + if (i == ALLEGRO_DONTCARE) + return; + SDL_GL_SetAttribute(sdl, x); +} + +static ALLEGRO_DISPLAY *sdl_create_display_locked(int w, int h) +{ + ALLEGRO_DISPLAY_SDL *sdl = al_calloc(1, sizeof *sdl); + ALLEGRO_DISPLAY *d = (void *)sdl; + d->w = w; + d->h = h; + d->flags = al_get_new_display_flags(); + d->flags |= ALLEGRO_OPENGL; +#ifdef ALLEGRO_CFG_OPENGLES2 + d->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + d->flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + int flags = SDL_WINDOW_OPENGL; + if (d->flags & ALLEGRO_FULLSCREEN) + flags |= SDL_WINDOW_FULLSCREEN; + if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) + flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + if (d->flags & ALLEGRO_FRAMELESS) + flags |= SDL_WINDOW_BORDERLESS; + if (d->flags & ALLEGRO_RESIZABLE) + flags |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; + + if (d->flags & ALLEGRO_OPENGL_ES_PROFILE) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); +#ifdef ALLEGRO_CFG_OPENGLES1 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); +#else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); +#endif + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + } + + GLoption(ALLEGRO_COLOR_SIZE, SDL_GL_BUFFER_SIZE); + GLoption(ALLEGRO_RED_SIZE, SDL_GL_RED_SIZE); + GLoption(ALLEGRO_GREEN_SIZE, SDL_GL_GREEN_SIZE); + GLoption(ALLEGRO_BLUE_SIZE, SDL_GL_BLUE_SIZE); + GLoption(ALLEGRO_ALPHA_SIZE, SDL_GL_ALPHA_SIZE); + GLoption(ALLEGRO_ACC_RED_SIZE, SDL_GL_ACCUM_RED_SIZE); + GLoption(ALLEGRO_ACC_GREEN_SIZE, SDL_GL_ACCUM_GREEN_SIZE); + GLoption(ALLEGRO_ACC_BLUE_SIZE, SDL_GL_ACCUM_BLUE_SIZE); + GLoption(ALLEGRO_ACC_ALPHA_SIZE, SDL_GL_ACCUM_ALPHA_SIZE); + GLoption(ALLEGRO_STEREO, SDL_GL_STEREO); + GLoption(ALLEGRO_DEPTH_SIZE, SDL_GL_DEPTH_SIZE); + GLoption(ALLEGRO_STENCIL_SIZE, SDL_GL_STENCIL_SIZE); + GLoption(ALLEGRO_SAMPLE_BUFFERS, SDL_GL_MULTISAMPLEBUFFERS); + GLoption(ALLEGRO_SAMPLES, SDL_GL_MULTISAMPLESAMPLES); + GLoption(ALLEGRO_OPENGL_MAJOR_VERSION, SDL_GL_CONTEXT_MAJOR_VERSION); + GLoption(ALLEGRO_OPENGL_MINOR_VERSION, SDL_GL_CONTEXT_MINOR_VERSION); + + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); + + sdl->window = SDL_CreateWindow(al_get_new_window_title(), sdl->x, sdl->y, + d->w, d->h, flags); + if (!sdl->window) { + ALLEGRO_ERROR("SDL_CreateWindow failed: %s", SDL_GetError()); + return NULL; + } + + sdl->context = SDL_GL_CreateContext(sdl->window); + + SDL_GL_GetDrawableSize(sdl->window, &d->w, &d->h); + + // there's no way to query pixel ratio before creating the window, so we + // have to compensate afterwards + if (d->flags & ALLEGRO_RESIZABLE && + !(d->flags & ALLEGRO_FULLSCREEN || d->flags & ALLEGRO_FULLSCREEN_WINDOW)) { + int window_width, window_height; + SDL_GetWindowSize(sdl->window, &window_width, &window_height); + float ratio = _al_sdl_get_display_pixel_ratio(d); + + ALLEGRO_DEBUG("resizing the display to %dx%d to match the scaling factor %f\n", (int)(window_width / ratio), (int)(window_height / ratio), ratio); + + SDL_SetWindowSize(sdl->window, window_width / ratio, window_height / ratio); + + SDL_GL_GetDrawableSize(sdl->window, &d->w, &d->h); + } + + ALLEGRO_DISPLAY **add; + ALLEGRO_SYSTEM *system = al_get_system_driver(); + add = _al_vector_alloc_back(&system->displays); + *add = d; + + _al_event_source_init(&d->es); + d->vt = vt; + + d->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = true; + + d->ogl_extras = al_calloc(1, sizeof *d->ogl_extras); + _al_ogl_manage_extensions(d); + _al_ogl_set_extensions(d->ogl_extras->extension_api); + + _al_ogl_setup_gl(d); + + /* Fill in opengl version */ + const int v = d->ogl_extras->ogl_info.version; + d->extra_settings.settings[ALLEGRO_OPENGL_MAJOR_VERSION] = (v >> 24) & 0xFF; + d->extra_settings.settings[ALLEGRO_OPENGL_MINOR_VERSION] = (v >> 16) & 0xFF; + + return d; +} + +static ALLEGRO_DISPLAY *sdl_create_display(int w, int h) +{ + ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver(); + al_lock_mutex(s->mutex); + ALLEGRO_DISPLAY *d = sdl_create_display_locked(w, h); + al_unlock_mutex(s->mutex); + return d; +} + +static void convert_display_bitmaps_to_memory_bitmap(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DEBUG("converting display bitmaps to memory bitmaps.\n"); + + while (d->bitmaps._size > 0) { + ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps); + ALLEGRO_BITMAP *b = *bptr; + _al_convert_to_memory_bitmap(b); + } +} + +static void transfer_display_bitmaps_to_any_other_display( + ALLEGRO_SYSTEM *s, ALLEGRO_DISPLAY *d) +{ + size_t i; + ALLEGRO_DISPLAY *living = NULL; + ASSERT(s->displays._size > 1); + + for (i = 0; i < s->displays._size; i++) { + ALLEGRO_DISPLAY **slot = _al_vector_ref(&s->displays, i); + living = *slot; + if (living != d) + break; + } + + ALLEGRO_DEBUG("transferring display bitmaps to other display.\n"); + + for (i = 0; i < d->bitmaps._size; i++) { + ALLEGRO_BITMAP **add = _al_vector_alloc_back(&(living->bitmaps)); + ALLEGRO_BITMAP **ref = _al_vector_ref(&d->bitmaps, i); + *add = *ref; + (*add)->_display = living; + } +} + +static void sdl_destroy_display_locked(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)d; + ALLEGRO_SYSTEM *system = al_get_system_driver(); + ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; + bool is_last; + + ALLEGRO_DEBUG("destroying display.\n"); + + /* If we're the last display, convert all bitmaps to display independent + * (memory) bitmaps. Otherwise, pass all bitmaps to any other living + * display. We assume all displays are compatible.) + */ + + is_last = (system->displays._size == 1); + if (is_last) + convert_display_bitmaps_to_memory_bitmap(d); + else + transfer_display_bitmaps_to_any_other_display(system, d); + + _al_ogl_unmanage_extensions(d); + ALLEGRO_DEBUG("unmanaged extensions.\n"); + + if (ogl->backbuffer) { + _al_ogl_destroy_backbuffer(ogl->backbuffer); + ogl->backbuffer = NULL; + ALLEGRO_DEBUG("destroy backbuffer.\n"); + } + + _al_vector_free(&d->bitmaps); + _al_event_source_free(&d->es); + + al_free(d->ogl_extras); + al_free(d->vertex_cache); + + _al_event_source_free(&d->es); + _al_vector_find_and_delete(&system->displays, &d); + + SDL_GL_DeleteContext(sdl->context); + SDL_DestroyWindow(sdl->window); + al_free(sdl); +} + +static void sdl_destroy_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver(); + al_lock_mutex(s->mutex); + sdl_destroy_display_locked(d); + al_unlock_mutex(s->mutex); +} + +static bool sdl_set_current_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)d; + SDL_GL_MakeCurrent(sdl->window, sdl->context); + return true; +} + +static void sdl_unset_current_display(ALLEGRO_DISPLAY *d) +{ + (void)d; +} + +static void sdl_flip_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)d; + SDL_GL_SwapWindow(sdl->window); + + // SDL loses texture contents, for example on resize. + al_backup_dirty_bitmaps(d); +} + +static void sdl_update_display_region(ALLEGRO_DISPLAY *d, int x, int y, + int width, int height) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)d; + (void)x; + (void)y; + (void)width; + (void)height; + SDL_GL_SwapWindow(sdl->window); +} + +static bool sdl_is_compatible_bitmap(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap) +{ + (void)display; + (void)bitmap; + return true; +} + +static bool sdl_set_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_MOUSE_CURSOR *cursor) +{ + (void)display; + (void)cursor; + return false; +} + +static bool sdl_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +{ + (void)display; + (void)cursor_id; + return false; +} + +static bool sdl_show_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + (void)display; + return SDL_ShowCursor(SDL_ENABLE) == SDL_ENABLE; +} + +static bool sdl_hide_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + (void)display; + return SDL_ShowCursor(SDL_DISABLE) == SDL_DISABLE; +} + +static void sdl_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + SDL_SetWindowPosition(sdl->window, x, y); +} + +static void sdl_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + SDL_GetWindowPosition(sdl->window, x, y); +} + +static void recreate_textures(ALLEGRO_DISPLAY *display) +{ + unsigned int i; + for (i = 0; i < _al_vector_size(&display->bitmaps); i++) { + ALLEGRO_BITMAP **bptr = _al_vector_ref(&display->bitmaps, i); + ALLEGRO_BITMAP *bitmap = *bptr; + int bitmap_flags = al_get_bitmap_flags(bitmap); + if (bitmap->parent) + continue; + if (bitmap_flags & ALLEGRO_MEMORY_BITMAP) + continue; + if (bitmap_flags & ALLEGRO_NO_PRESERVE_TEXTURE) + continue; + _al_ogl_upload_bitmap_memory(bitmap, _al_get_bitmap_memory_format( + bitmap), bitmap->memory); + } +} + +static bool sdl_acknowledge_resize(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + SDL_GL_GetDrawableSize(sdl->window, &display->w, &display->h); + + _al_ogl_setup_gl(display); + + if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + display->default_shader = _al_create_default_shader(display->flags); + al_use_shader(display->default_shader); + } + + recreate_textures(display); + + _al_glsl_unuse_shaders(); + + return true; +} + +static void sdl_set_window_title(ALLEGRO_DISPLAY *display, char const *title) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + SDL_SetWindowTitle(sdl->window, title); +} + +static bool sdl_resize_display(ALLEGRO_DISPLAY *display, int width, int height) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + + // Allegro uses pixels everywhere, while SDL uses screen space for window size + int window_width, drawable_width, h; + SDL_GetWindowSize(sdl->window, &window_width, &h); + SDL_GL_GetDrawableSize(sdl->window, &drawable_width, &h); + float ratio = drawable_width / (float)window_width; + + SDL_SetWindowSize(sdl->window, width / ratio, height / ratio); + sdl_acknowledge_resize(display); + return true; +} + +static bool sdl_set_display_flag(ALLEGRO_DISPLAY *display, int flag, + bool flag_onoff) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + switch (flag) { + case ALLEGRO_FRAMELESS: + /* The ALLEGRO_FRAMELESS flag is backwards. */ + SDL_SetWindowBordered(sdl->window, !flag_onoff); + return true; + case ALLEGRO_FULLSCREEN_WINDOW: + SDL_SetWindowFullscreen(sdl->window, flag_onoff ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + return true; + case ALLEGRO_MAXIMIZED: + if (flag_onoff) { + SDL_MaximizeWindow(sdl->window); + } else { + SDL_RestoreWindow(sdl->window); + } + return true; + } + return false; +} + +static void sdl_set_icons(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *bitmaps[]) { + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + int w = al_get_bitmap_width(bitmaps[0]); + int h = al_get_bitmap_height(bitmaps[0]); + int data_size = w * h * 4; + (void)num_icons; + + unsigned char* data = al_malloc(data_size * sizeof(data[0])); + + Uint32 rmask, gmask, bmask, amask; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else // little endian, like x86 + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + + ALLEGRO_LOCKED_REGION *lock = al_lock_bitmap(bitmaps[0], ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_LOCK_READONLY); + if (lock) { + int i = 0, y = 0; + for (y = 0; y < h; y++) { + int x = 0; + for (x = 0; x < w; x++) { + ALLEGRO_COLOR c = al_get_pixel(bitmaps[0], x, y); + al_unmap_rgba(c, data+i, data+i+1, data+i+2, data+i+3); + i += 4; + } + } + al_unlock_bitmap(bitmaps[0]); + + SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(data, w, h, 4 * 8, w * 4, rmask, gmask, bmask, amask); + SDL_SetWindowIcon(sdl->window, icon); + SDL_FreeSurface(icon); + } + + al_free(data); +} + +ALLEGRO_DISPLAY_INTERFACE *_al_sdl_display_driver(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + vt->id = AL_ID('S', 'D', 'L', '2'); + vt->create_display = sdl_create_display; + vt->destroy_display = sdl_destroy_display; + vt->set_current_display = sdl_set_current_display; + vt->unset_current_display = sdl_unset_current_display; + //vt->clear = GL + //vt->draw_pixel = GL + vt->flip_display = sdl_flip_display; + vt->update_display_region = sdl_update_display_region; + vt->acknowledge_resize = sdl_acknowledge_resize; + vt->resize_display = sdl_resize_display; + /*vt->quick_size = sdl_quick_size; + vt->get_orientation = sdl_get_orientation;*/ + vt->create_bitmap = _al_ogl_create_bitmap; + vt->set_target_bitmap = _al_ogl_set_target_bitmap; + vt->get_backbuffer = _al_ogl_get_backbuffer; + vt->is_compatible_bitmap = sdl_is_compatible_bitmap; + /*vt->switch_out = sdl_switch_out; + vt->switch_in = sdl_switch_in; + vt->draw_memory_bitmap_region = sdl_draw_memory_bitmap_region; + vt->wait_for_vsync = sdl_wait_for_vsync;*/ + vt->set_mouse_cursor = sdl_set_mouse_cursor; + vt->set_system_mouse_cursor = sdl_set_system_mouse_cursor; + vt->show_mouse_cursor = sdl_show_mouse_cursor; + vt->hide_mouse_cursor = sdl_hide_mouse_cursor; + vt->set_icons = sdl_set_icons; + vt->set_window_position = sdl_set_window_position; + vt->get_window_position = sdl_get_window_position; + /*vt->set_window_constraints = sdl_set_window_constraints; + vt->get_window_constraints = sdl_get_window_constraints;*/ + vt->set_display_flag = sdl_set_display_flag; + vt->set_window_title = sdl_set_window_title; + //vt->flush_vertex_cache = GL + //vt->prepare_vertex_cache = GL + //vt->update_transformation = GL + //vt->set_projection = GL + /*vt->shutdown = sdl_shutdown; + vt->acknowledge_drawing_halt = sdl_acknowledge_drawing_halt; + vt->acknowledge_drawing_resume = sdl_acknowledge_drawing_resume; + vt->set_display_option = sdl_set_display_option;*/ + //vt->clear_depth_buffer = GL + vt->update_render_state = _al_ogl_update_render_state; + + _al_ogl_add_drawing_functions(vt); + + return vt; +} diff --git a/allegro/src/sdl/sdl_event_hack.c b/allegro/src/sdl/sdl_event_hack.c new file mode 100644 index 00000000..5d299085 --- /dev/null +++ b/allegro/src/sdl/sdl_event_hack.c @@ -0,0 +1,72 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL event hack (see below). + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_timer.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/platform/allegro_internal_sdl.h" + +/* This is a thread which wakes up event queues from time to time (with fake + * timer events) to prevent a deadlock in an unbound al_wait_for_event. + */ + +static ALLEGRO_THREAD *thread; + +static void wakeup_with_fake_timer_event(void) +{ + ALLEGRO_EVENT_SOURCE *es = al_get_keyboard_event_source(); + _al_event_source_lock(es); + ALLEGRO_EVENT event; + event.timer.type = ALLEGRO_EVENT_TIMER; + event.timer.timestamp = al_get_time(); + event.timer.count = 0; + event.timer.error = 0; + _al_event_source_emit_event(es, &event); + _al_event_source_unlock(es); +} + +static void *wakeup_thread(ALLEGRO_THREAD *thread, void *user) +{ + al_rest(1); + while (!al_get_thread_should_stop(thread)) { + /* If the program uses timers, this hack is not required usually. */ + if (_al_get_active_timers_count()) + break; + if (!al_is_keyboard_installed()) + break; + wakeup_with_fake_timer_event(); + al_rest(0.01); + } + return user; +} + +static void _uninstall_sdl_event_hack(void) +{ + if (thread) { + al_set_thread_should_stop(thread); + al_join_thread(thread, NULL); + al_destroy_thread(thread); + } +} + +void _al_sdl_event_hack(void) +{ + if (thread) + return; + _al_add_exit_func(_uninstall_sdl_event_hack, "uninstall_sdl_event_hack"); + thread = al_create_thread(wakeup_thread, NULL); + al_start_thread(thread); +} diff --git a/allegro/src/sdl/sdl_joystick.c b/allegro/src/sdl/sdl_joystick.c new file mode 100644 index 00000000..447713ae --- /dev/null +++ b/allegro/src/sdl/sdl_joystick.c @@ -0,0 +1,208 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL joystick driver. + * + * See LICENSE.txt for copyright information. + */ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/platform/allegro_internal_sdl.h" + +ALLEGRO_DEBUG_CHANNEL("SDL") + +typedef struct ALLEGRO_JOYSTICK_SDL +{ + int id; + ALLEGRO_JOYSTICK allegro; + SDL_Joystick *sdl; +} ALLEGRO_JOYSTICK_SDL; + +static ALLEGRO_JOYSTICK_DRIVER *vt; +static int count; +static ALLEGRO_JOYSTICK_SDL *joysticks; + +static int get_id(ALLEGRO_JOYSTICK *allegro) +{ + int i; + for (i = 0; i < count; i++) { + if (&joysticks[i].allegro == allegro) + return i; + } + return -1; +} + +static SDL_Joystick *get_sdl(ALLEGRO_JOYSTICK *allegro) +{ + int id = get_id(allegro); + if (id < 0) + return NULL; + return joysticks[id].sdl; +} + +void _al_sdl_joystick_event(SDL_Event *e) +{ + if (count <= 0) + return; + + ALLEGRO_EVENT event; + memset(&event, 0, sizeof event); + + event.joystick.timestamp = al_get_time(); + + if (e->type == SDL_JOYAXISMOTION) { + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.id = &joysticks[e->jaxis.which].allegro; + event.joystick.stick = e->jaxis.axis / 2; + event.joystick.axis = e->jaxis.axis % 2; + event.joystick.pos = e->jaxis.value / 32768.0; + event.joystick.button = 0; + } + else if (e->type == SDL_JOYBUTTONDOWN) { + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN; + event.joystick.id = &joysticks[e->jbutton.which].allegro; + event.joystick.stick = 0; + event.joystick.axis = 0; + event.joystick.pos = 0; + event.joystick.button = e->jbutton.button; + } + else if (e->type == SDL_JOYBUTTONUP) { + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_BUTTON_UP; + event.joystick.id = &joysticks[e->jbutton.which].allegro; + event.joystick.stick = 0; + event.joystick.axis = 0; + event.joystick.pos = 0; + event.joystick.button = e->jbutton.button; + } + else if (e->type == SDL_JOYDEVICEADDED || e->type == SDL_JOYDEVICEREMOVED) { + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; + } + else { + return; + } + + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + _al_event_source_lock(es); + _al_event_source_emit_event(es, &event); + _al_event_source_unlock(es); +} + +static bool sdl_init_joystick(void) +{ + count = SDL_NumJoysticks(); + joysticks = calloc(count, sizeof * joysticks); + int i; + for (i = 0; i < count; i++) { + joysticks[i].sdl = SDL_JoystickOpen(i); + _AL_JOYSTICK_INFO *info = &joysticks[i].allegro.info; + int an = SDL_JoystickNumAxes(joysticks[i].sdl); + int a; + info->num_sticks = an / 2; + for (a = 0; a < an; a++) { + info->stick[a / 2].num_axes = 2; + info->stick[a / 2].name = "stick"; + info->stick[a / 2].axis[0].name = "X"; + info->stick[a / 2].axis[1].name = "Y"; + } + + int bn = SDL_JoystickNumButtons(joysticks[i].sdl); + info->num_buttons = bn; + int b; + for (b = 0; b < bn; b++) { + info->button[b].name = "button"; + } + } + SDL_JoystickEventState(SDL_ENABLE); + return true; +} + +static void sdl_exit_joystick(void) +{ + int i; + for (i = 0; i < count; i++) { + SDL_JoystickClose(joysticks[i].sdl); + } + count = 0; + free(joysticks); +} + +static bool sdl_reconfigure_joysticks(void) +{ + sdl_exit_joystick(); + return sdl_init_joystick(); +} + +static int sdl_num_joysticks(void) +{ + return count; +} + +static ALLEGRO_JOYSTICK *sdl_get_joystick(int joyn) +{ + return &joysticks[joyn].allegro; +} + +static void sdl_release_joystick(ALLEGRO_JOYSTICK *joy) +{ + ASSERT(joy); +} + +static void sdl_get_joystick_state(ALLEGRO_JOYSTICK *joy, + ALLEGRO_JOYSTICK_STATE *ret_state) +{ + ALLEGRO_SYSTEM_INTERFACE *s = _al_sdl_system_driver(); + s->heartbeat(); + + SDL_Joystick *sdl = get_sdl(joy); + int an = SDL_JoystickNumAxes(sdl); + int i; + for (i = 0; i < an; i++) { + ret_state->stick[i / 2].axis[i % 2] = SDL_JoystickGetAxis(sdl, i) / 32768.0; + } + int bn = SDL_JoystickNumButtons(sdl); + for (i = 0; i < bn; i++) { + ret_state->button[i] = SDL_JoystickGetButton(sdl, i) * 32767; + } +} + +static const char *sdl_get_name(ALLEGRO_JOYSTICK *joy) +{ + SDL_Joystick *sdl = get_sdl(joy); + return SDL_JoystickName(sdl); +} + +static bool sdl_get_active(ALLEGRO_JOYSTICK *joy) +{ + SDL_Joystick *sdl = get_sdl(joy); + return SDL_JoystickGetAttached(sdl); +} + +ALLEGRO_JOYSTICK_DRIVER *_al_sdl_joystick_driver(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + vt->joydrv_id = AL_ID('S','D','L','2'); + vt->joydrv_name = "SDL2 Joystick"; + vt->joydrv_desc = "SDL2 Joystick"; + vt->joydrv_ascii_name = "SDL2 Joystick"; + vt->init_joystick = sdl_init_joystick; + vt->exit_joystick = sdl_exit_joystick; + vt->reconfigure_joysticks = sdl_reconfigure_joysticks; + vt->num_joysticks = sdl_num_joysticks; + vt->get_joystick = sdl_get_joystick; + vt->release_joystick = sdl_release_joystick; + vt->get_joystick_state = sdl_get_joystick_state;; + vt->get_name = sdl_get_name; + vt->get_active = sdl_get_active; + + return vt; +} diff --git a/allegro/src/sdl/sdl_keyboard.c b/allegro/src/sdl/sdl_keyboard.c new file mode 100644 index 00000000..0f4cb543 --- /dev/null +++ b/allegro/src/sdl/sdl_keyboard.c @@ -0,0 +1,449 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL keyboard driver. + * + * See LICENSE.txt for copyright information. + */ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/platform/allegro_internal_sdl.h" + +ALLEGRO_DEBUG_CHANNEL("SDL") + +typedef struct ALLEGRO_KEYBOARD_SDL +{ + ALLEGRO_KEYBOARD keyboard; + int table[1024]; + int inverse[1024]; + int unicode[1024]; + int inverse_unicode[1024]; + bool create_extra_char[1024]; + ALLEGRO_DISPLAY *display; +} ALLEGRO_KEYBOARD_SDL; + +static ALLEGRO_KEYBOARD_DRIVER *vt; +static ALLEGRO_KEYBOARD_SDL *keyboard; + + +static unsigned int get_modifiers(int modifiers) +{ + int result = 0; + + if (modifiers & KMOD_LSHIFT) result |= ALLEGRO_KEYMOD_SHIFT; + if (modifiers & KMOD_RSHIFT) result |= ALLEGRO_KEYMOD_SHIFT; + if (modifiers & KMOD_LCTRL) result |= ALLEGRO_KEYMOD_CTRL; + if (modifiers & KMOD_RCTRL) result |= ALLEGRO_KEYMOD_CTRL; + if (modifiers & KMOD_LALT) result |= ALLEGRO_KEYMOD_ALT; + if (modifiers & KMOD_RALT) result |= ALLEGRO_KEYMOD_ALT; + if (modifiers & KMOD_LGUI) result |= ALLEGRO_KEYMOD_LWIN; + if (modifiers & KMOD_RGUI) result |= ALLEGRO_KEYMOD_RWIN; + if (modifiers & KMOD_NUM) result |= ALLEGRO_KEYMOD_NUMLOCK; + if (modifiers & KMOD_CAPS) result |= ALLEGRO_KEYMOD_CAPSLOCK; + if (modifiers & KMOD_MODE) result |= ALLEGRO_KEYMOD_ALTGR; + + return result; +} + +void _al_sdl_keyboard_event(SDL_Event *e) +{ + if (!keyboard) + return; + if (e->type == SDL_WINDOWEVENT) { + if (e->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { + keyboard->display = _al_sdl_find_display(e->window.windowID); + } + else { + keyboard->display = NULL; + } + return; + } + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es = &keyboard->keyboard.es; + _al_event_source_lock(es); + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = NULL; + event.keyboard.modifiers = get_modifiers(e->key.keysym.mod); + event.keyboard.repeat = false; + + if (e->type == SDL_TEXTINPUT) { + ALLEGRO_USTR_INFO info; + ALLEGRO_USTR const *u = al_ref_cstr(&info, e->text.text); + int pos = 0; + while (true) { + int32_t c = al_ustr_get_next(u, &pos); + if (c <= 0) + break; + event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; + event.keyboard.keycode = c < 1024 ? keyboard->inverse_unicode[c] : 0; + event.keyboard.unichar = c; + event.keyboard.display = _al_sdl_find_display(e->text.windowID); + _al_event_source_emit_event(es, &event); + } + + } + else if (e->type == SDL_KEYDOWN) { + event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN; + event.keyboard.keycode = keyboard->table[e->key.keysym.scancode]; + event.keyboard.unichar = keyboard->unicode[e->key.keysym.scancode]; + event.keyboard.display = _al_sdl_find_display(e->key.windowID); + if (!e->key.repeat) { + _al_event_source_emit_event(es, &event); + } + + if (keyboard->create_extra_char[e->key.keysym.scancode]) { + event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; + _al_event_source_emit_event(es, &event); + } + } + else if (e->type == SDL_KEYUP) { + event.keyboard.type = ALLEGRO_EVENT_KEY_UP; + event.keyboard.keycode = keyboard->table[e->key.keysym.scancode]; + event.keyboard.unichar = keyboard->unicode[e->key.keysym.scancode]; + event.keyboard.display = _al_sdl_find_display(e->key.windowID); + _al_event_source_emit_event(es, &event); + } + + keyboard->display = event.keyboard.display; + + _al_event_source_unlock(es); +} + +static void adde(int sdl_scancode, int allegro_keycode, int unicode, bool extra) +{ + if (sdl_scancode >= 1024) { + ALLEGRO_WARN("Cannot map SDL scancode %d.\n", sdl_scancode); + return; + } + keyboard->table[sdl_scancode] = allegro_keycode; + keyboard->inverse[allegro_keycode] = sdl_scancode; + keyboard->unicode[sdl_scancode] = unicode; + keyboard->inverse_unicode[unicode] = allegro_keycode; + keyboard->create_extra_char[sdl_scancode] = extra; +} + +static void add(int sdl_scancode, int allegro_keycode, int unicode) +{ + adde(sdl_scancode, allegro_keycode, unicode, false); +} + +#define ADD_SAME(X, c) add(SDL_SCANCODE_##X, ALLEGRO_KEY_##X, c) +#define ADD_SAMEC(X) add(SDL_SCANCODE_##X, ALLEGRO_KEY_##X, tolower(#X[0])) +#define ADD_SAMEE(X, c) adde(SDL_SCANCODE_##X, ALLEGRO_KEY_##X, c, true) + +static bool sdl_init_keyboard(void) +{ + keyboard = al_calloc(1, sizeof *keyboard); + _al_event_source_init(&keyboard->keyboard.es); + + add(SDL_SCANCODE_UNKNOWN, 0, 0); + ADD_SAMEC(A); + ADD_SAMEC(B); + ADD_SAMEC(C); + ADD_SAMEC(D); + ADD_SAMEC(E); + ADD_SAMEC(F); + ADD_SAMEC(G); + ADD_SAMEC(H); + ADD_SAMEC(I); + ADD_SAMEC(J); + ADD_SAMEC(K); + ADD_SAMEC(L); + ADD_SAMEC(M); + ADD_SAMEC(N); + ADD_SAMEC(O); + ADD_SAMEC(P); + ADD_SAMEC(Q); + ADD_SAMEC(R); + ADD_SAMEC(S); + ADD_SAMEC(T); + ADD_SAMEC(U); + ADD_SAMEC(V); + ADD_SAMEC(W); + ADD_SAMEC(X); + ADD_SAMEC(Y); + ADD_SAMEC(Z); + ADD_SAMEC(1); + ADD_SAMEC(2); + ADD_SAMEC(3); + ADD_SAMEC(4); + ADD_SAMEC(5); + ADD_SAMEC(6); + ADD_SAMEC(7); + ADD_SAMEC(8); + ADD_SAMEC(9); + ADD_SAMEC(0); + adde(SDL_SCANCODE_RETURN, ALLEGRO_KEY_ENTER, 13, true); + ADD_SAMEE(ESCAPE, 27); + ADD_SAMEE(BACKSPACE, 8); + ADD_SAMEE(TAB, 9); + ADD_SAME(SPACE, ' '); + ADD_SAME(MINUS, '-'); + ADD_SAME(EQUALS, '='); + add(SDL_SCANCODE_LEFTBRACKET, ALLEGRO_KEY_OPENBRACE, '['); + add(SDL_SCANCODE_RIGHTBRACKET, ALLEGRO_KEY_CLOSEBRACE, ']'); + ADD_SAME(BACKSLASH, '\\'); + add(SDL_SCANCODE_NONUSHASH, 0, '#'); + ADD_SAME(SEMICOLON, ';'); + add(SDL_SCANCODE_APOSTROPHE, ALLEGRO_KEY_QUOTE, '\''); + add(SDL_SCANCODE_GRAVE, ALLEGRO_KEY_TILDE, '~'); + ADD_SAME(COMMA, ','); + add(SDL_SCANCODE_PERIOD, ALLEGRO_KEY_FULLSTOP, '.'); + ADD_SAME(SLASH, '/'); + ADD_SAME(CAPSLOCK, 0); + ADD_SAMEE(F1, 0); + ADD_SAMEE(F2, 0); + ADD_SAMEE(F3, 0); + ADD_SAMEE(F4, 0); + ADD_SAMEE(F5, 0); + ADD_SAMEE(F6, 0); + ADD_SAMEE(F7, 0); + ADD_SAMEE(F8, 0); + ADD_SAMEE(F9, 0); + ADD_SAMEE(F10, 0); + ADD_SAMEE(F11, 0); + ADD_SAMEE(F12, 0); + ADD_SAME(PRINTSCREEN, 0); + ADD_SAME(SCROLLLOCK, 0); + ADD_SAME(PAUSE, 0); + ADD_SAMEE(INSERT, 0); + ADD_SAMEE(HOME, 0); + add(SDL_SCANCODE_PAGEUP, ALLEGRO_KEY_PGUP, 0); + ADD_SAMEE(DELETE, 0); + ADD_SAMEE(END, 0); + add(SDL_SCANCODE_PAGEDOWN, ALLEGRO_KEY_PGDN, 0); + ADD_SAMEE(RIGHT, 0); + ADD_SAMEE(LEFT, 0); + ADD_SAMEE(DOWN, 0); + ADD_SAMEE(UP, 0); + add(SDL_SCANCODE_NUMLOCKCLEAR, ALLEGRO_KEY_NUMLOCK, 0); + add(SDL_SCANCODE_KP_DIVIDE, ALLEGRO_KEY_PAD_SLASH, '/'); + add(SDL_SCANCODE_KP_MULTIPLY, ALLEGRO_KEY_PAD_ASTERISK, '*'); + add(SDL_SCANCODE_KP_MINUS, ALLEGRO_KEY_PAD_MINUS, '-'); + add(SDL_SCANCODE_KP_PLUS, ALLEGRO_KEY_PAD_PLUS, '+'); + add(SDL_SCANCODE_KP_ENTER, ALLEGRO_KEY_PAD_ENTER, 13); + add(SDL_SCANCODE_KP_1, ALLEGRO_KEY_PAD_1, '1'); + add(SDL_SCANCODE_KP_2, ALLEGRO_KEY_PAD_2, '2'); + add(SDL_SCANCODE_KP_3, ALLEGRO_KEY_PAD_3, '3'); + add(SDL_SCANCODE_KP_4, ALLEGRO_KEY_PAD_4, '4'); + add(SDL_SCANCODE_KP_5, ALLEGRO_KEY_PAD_5, '5'); + add(SDL_SCANCODE_KP_6, ALLEGRO_KEY_PAD_6, '6'); + add(SDL_SCANCODE_KP_7, ALLEGRO_KEY_PAD_7, '7'); + add(SDL_SCANCODE_KP_8, ALLEGRO_KEY_PAD_8, '8'); + add(SDL_SCANCODE_KP_9, ALLEGRO_KEY_PAD_9, '9'); + add(SDL_SCANCODE_KP_0, ALLEGRO_KEY_PAD_0, '0'); + add(SDL_SCANCODE_KP_PERIOD, ALLEGRO_KEY_PAD_DELETE, 0); + add(SDL_SCANCODE_NONUSBACKSLASH, 0, '\\'); + add(SDL_SCANCODE_APPLICATION, 0, 0); + add(SDL_SCANCODE_POWER, 0, 0); + add(SDL_SCANCODE_KP_EQUALS, ALLEGRO_KEY_PAD_EQUALS, '='); + add(SDL_SCANCODE_F13, 0, 0); + add(SDL_SCANCODE_F14, 0, 0); + add(SDL_SCANCODE_F15, 0, 0); + add(SDL_SCANCODE_F16, 0, 0); + add(SDL_SCANCODE_F17, 0, 0); + add(SDL_SCANCODE_F18, 0, 0); + add(SDL_SCANCODE_F19, 0, 0); + add(SDL_SCANCODE_F20, 0, 0); + add(SDL_SCANCODE_F21, 0, 0); + add(SDL_SCANCODE_F22, 0, 0); + add(SDL_SCANCODE_F23, 0, 0); + add(SDL_SCANCODE_F24, 0, 0); + add(SDL_SCANCODE_EXECUTE, 0, 0); + add(SDL_SCANCODE_HELP, 0, 0); + ADD_SAME(MENU, 0); + add(SDL_SCANCODE_SELECT, 0, 0); + add(SDL_SCANCODE_STOP, 0, 0); + add(SDL_SCANCODE_AGAIN, 0, 0); + add(SDL_SCANCODE_UNDO, 0, 0); + add(SDL_SCANCODE_CUT, 0, 0); + add(SDL_SCANCODE_COPY, 0, 0); + add(SDL_SCANCODE_PASTE, 0, 0); + add(SDL_SCANCODE_FIND, 0, 0); + add(SDL_SCANCODE_MUTE, 0, 0); + add(SDL_SCANCODE_VOLUMEUP, 0, 0); + add(SDL_SCANCODE_VOLUMEDOWN, 0, 0); + add(SDL_SCANCODE_KP_COMMA, 0, ','); + add(SDL_SCANCODE_KP_EQUALSAS400, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL1, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL2, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL3, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL4, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL5, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL6, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL7, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL8, 0, 0); + add(SDL_SCANCODE_INTERNATIONAL9, 0, 0); + add(SDL_SCANCODE_LANG1, 0, 0); + add(SDL_SCANCODE_LANG2, 0, 0); + add(SDL_SCANCODE_LANG3, 0, 0); + add(SDL_SCANCODE_LANG4, 0, 0); + add(SDL_SCANCODE_LANG5, 0, 0); + add(SDL_SCANCODE_LANG6, 0, 0); + add(SDL_SCANCODE_LANG7, 0, 0); + add(SDL_SCANCODE_LANG8, 0, 0); + add(SDL_SCANCODE_LANG9, 0, 0); + add(SDL_SCANCODE_ALTERASE, 0, 0); + add(SDL_SCANCODE_SYSREQ, 0, 0); + add(SDL_SCANCODE_CANCEL, 0, 0); + add(SDL_SCANCODE_CLEAR, 0, 0); + add(SDL_SCANCODE_PRIOR, 0, 0); + add(SDL_SCANCODE_RETURN2, 0, 0); + add(SDL_SCANCODE_SEPARATOR, 0, 0); + add(SDL_SCANCODE_OUT, 0, 0); + add(SDL_SCANCODE_OPER, 0, 0); + add(SDL_SCANCODE_CLEARAGAIN, 0, 0); + add(SDL_SCANCODE_CRSEL, 0, 0); + add(SDL_SCANCODE_EXSEL, 0, 0); + add(SDL_SCANCODE_KP_00, 0, 0); + add(SDL_SCANCODE_KP_000, 0, 0); + add(SDL_SCANCODE_THOUSANDSSEPARATOR, 0, 0); + add(SDL_SCANCODE_DECIMALSEPARATOR, 0, 0); + add(SDL_SCANCODE_CURRENCYUNIT, 0, 0); + add(SDL_SCANCODE_CURRENCYSUBUNIT, 0, 0); + add(SDL_SCANCODE_KP_LEFTPAREN, 0, 0); + add(SDL_SCANCODE_KP_RIGHTPAREN, 0, 0); + add(SDL_SCANCODE_KP_LEFTBRACE, 0, '{'); + add(SDL_SCANCODE_KP_RIGHTBRACE, 0, '}'); + add(SDL_SCANCODE_KP_TAB, 0, 9); + add(SDL_SCANCODE_KP_BACKSPACE, 0, 8); + add(SDL_SCANCODE_KP_A, 0, 0); + add(SDL_SCANCODE_KP_B, 0, 0); + add(SDL_SCANCODE_KP_C, 0, 0); + add(SDL_SCANCODE_KP_D, 0, 0); + add(SDL_SCANCODE_KP_E, 0, 0); + add(SDL_SCANCODE_KP_F, 0, 0); + add(SDL_SCANCODE_KP_XOR, 0, 0); + add(SDL_SCANCODE_KP_POWER, 0, 0); + add(SDL_SCANCODE_KP_PERCENT, 0, 0); + add(SDL_SCANCODE_KP_LESS, 0, '<'); + add(SDL_SCANCODE_KP_GREATER, 0, '>'); + add(SDL_SCANCODE_KP_AMPERSAND, 0, '&'); + add(SDL_SCANCODE_KP_DBLAMPERSAND, 0, 0); + add(SDL_SCANCODE_KP_VERTICALBAR, 0, '|'); + add(SDL_SCANCODE_KP_DBLVERTICALBAR, 0, 0); + add(SDL_SCANCODE_KP_COLON, 0, ':'); + add(SDL_SCANCODE_KP_HASH, 0, '#'); + add(SDL_SCANCODE_KP_SPACE, 0, 0); + add(SDL_SCANCODE_KP_AT, 0, '@'); + add(SDL_SCANCODE_KP_EXCLAM, 0, '!'); + add(SDL_SCANCODE_KP_MEMSTORE, 0, 0); + add(SDL_SCANCODE_KP_MEMRECALL, 0, 0); + add(SDL_SCANCODE_KP_MEMCLEAR, 0, 0); + add(SDL_SCANCODE_KP_MEMADD, 0, 0); + add(SDL_SCANCODE_KP_MEMSUBTRACT, 0, 0); + add(SDL_SCANCODE_KP_MEMMULTIPLY, 0, 0); + add(SDL_SCANCODE_KP_MEMDIVIDE, 0, 0); + add(SDL_SCANCODE_KP_PLUSMINUS, 0, 0); + add(SDL_SCANCODE_KP_CLEAR, 0, 0); + add(SDL_SCANCODE_KP_CLEARENTRY, 0, 0); + add(SDL_SCANCODE_KP_BINARY, 0, 0); + add(SDL_SCANCODE_KP_OCTAL, 0, 0); + add(SDL_SCANCODE_KP_DECIMAL, 0, 0); + add(SDL_SCANCODE_KP_HEXADECIMAL, 0, 0); + ADD_SAME(LCTRL, 0); + ADD_SAME(LSHIFT, 0); + add(SDL_SCANCODE_LALT, ALLEGRO_KEY_ALT, 0); + add(SDL_SCANCODE_LGUI, ALLEGRO_KEY_LWIN, 0); + ADD_SAME(RCTRL, 0); + ADD_SAME(RSHIFT, 0); + add(SDL_SCANCODE_RALT, ALLEGRO_KEY_ALTGR, 0); + add(SDL_SCANCODE_RGUI, ALLEGRO_KEY_RWIN, 0); + add(SDL_SCANCODE_MODE, 0, 0); + add(SDL_SCANCODE_AUDIONEXT, 0, 0); + add(SDL_SCANCODE_AUDIOPREV, 0, 0); + add(SDL_SCANCODE_AUDIOSTOP, 0, 0); + add(SDL_SCANCODE_AUDIOPLAY, 0, 0); + add(SDL_SCANCODE_AUDIOMUTE, 0, 0); + add(SDL_SCANCODE_MEDIASELECT, 0, 0); + add(SDL_SCANCODE_WWW, 0, 0); + add(SDL_SCANCODE_MAIL, 0, 0); + add(SDL_SCANCODE_CALCULATOR, 0, 0); + add(SDL_SCANCODE_COMPUTER, 0, 0); + add(SDL_SCANCODE_AC_SEARCH, 0, 0); + add(SDL_SCANCODE_AC_HOME, 0, 0); + add(SDL_SCANCODE_AC_BACK, 0, 0); + add(SDL_SCANCODE_AC_FORWARD, 0, 0); + add(SDL_SCANCODE_AC_STOP, 0, 0); + add(SDL_SCANCODE_AC_REFRESH, 0, 0); + add(SDL_SCANCODE_AC_BOOKMARKS, 0, 0); + add(SDL_SCANCODE_BRIGHTNESSDOWN, 0, 0); + add(SDL_SCANCODE_BRIGHTNESSUP, 0, 0); + add(SDL_SCANCODE_DISPLAYSWITCH, 0, 0); + add(SDL_SCANCODE_KBDILLUMTOGGLE, 0, 0); + add(SDL_SCANCODE_KBDILLUMDOWN, 0, 0); + add(SDL_SCANCODE_KBDILLUMUP, 0, 0); + add(SDL_SCANCODE_EJECT, 0, 0); + add(SDL_SCANCODE_SLEEP, 0, 0); + + _al_sdl_event_hack(); + + return true; +} + +static void sdl_exit_keyboard(void) +{ +} + +static ALLEGRO_KEYBOARD *sdl_get_keyboard(void) +{ + return &keyboard->keyboard; +} + +static bool sdl_set_keyboard_leds(int leds) +{ + (void)leds; + return false; +} + +static char const *sdl_keycode_to_name(int keycode) +{ + return SDL_GetScancodeName(keyboard->inverse[keycode]); +} + +static void sdl_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) +{ + int i, n; + ALLEGRO_SYSTEM_INTERFACE *sdl = _al_sdl_system_driver(); + sdl->heartbeat(); + const Uint8 *s = SDL_GetKeyboardState(&n); + for (i = 0; i < n; i++) { + if (s[i]) + _AL_KEYBOARD_STATE_SET_KEY_DOWN(*ret_state, keyboard->table[i]); + else + _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(*ret_state, keyboard->table[i]); + } + ret_state->display = keyboard->display; +} + +static void sdl_clear_keyboard_state(void) +{ + return; +} + +ALLEGRO_KEYBOARD_DRIVER *_al_sdl_keyboard_driver(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + vt->keydrv_id = AL_ID('S','D','L','2'); + vt->keydrv_name = "SDL2 Keyboard"; + vt->keydrv_desc = "SDL2 Keyboard"; + vt->keydrv_ascii_name = "SDL2 Keyboard"; + vt->init_keyboard = sdl_init_keyboard; + vt->exit_keyboard = sdl_exit_keyboard; + vt->get_keyboard = sdl_get_keyboard; + vt->set_keyboard_leds = sdl_set_keyboard_leds; + vt->keycode_to_name = sdl_keycode_to_name; + vt->get_keyboard_state = sdl_get_keyboard_state; + vt->clear_keyboard_state = sdl_clear_keyboard_state; + return vt; +} diff --git a/allegro/src/sdl/sdl_mouse.c b/allegro/src/sdl/sdl_mouse.c new file mode 100644 index 00000000..f74b7fc1 --- /dev/null +++ b/allegro/src/sdl/sdl_mouse.c @@ -0,0 +1,234 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL mouse driver. + * + * See LICENSE.txt for copyright information. + */ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/platform/allegro_internal_sdl.h" + +ALLEGRO_DEBUG_CHANNEL("SDL") + +typedef struct ALLEGRO_MOUSE_SDL +{ + ALLEGRO_MOUSE mouse; + ALLEGRO_MOUSE_STATE state; + ALLEGRO_DISPLAY *display; +} ALLEGRO_MOUSE_SDL; + +static ALLEGRO_MOUSE_DRIVER *vt; +static ALLEGRO_MOUSE_SDL *mouse; + +static ALLEGRO_DISPLAY *find_display(uint32_t window_id) +{ + ALLEGRO_DISPLAY *d = _al_sdl_find_display(window_id); + if (d) { + return d; + } + else { + // if there's only one display, we can assume that all + // events refer to its coordinate system + ALLEGRO_SYSTEM *s = al_get_system_driver(); + if (_al_vector_size(&s->displays) == 1) { + void **v = (void **)_al_vector_ref(&s->displays, 0); + ALLEGRO_DISPLAY_SDL *d = *v; + return &d->display; + } + } + return NULL; +} + +void _al_sdl_mouse_event(SDL_Event *e) +{ + if (!mouse) + return; + + ALLEGRO_EVENT_SOURCE *es = &mouse->mouse.es; + _al_event_source_lock(es); + ALLEGRO_EVENT event; + memset(&event, 0, sizeof event); + + event.mouse.timestamp = al_get_time(); + + ALLEGRO_DISPLAY *d = NULL; + + if (e->type == SDL_WINDOWEVENT) { + d = find_display(e->window.windowID); + float ratio = _al_sdl_get_display_pixel_ratio(d); + if (e->window.event == SDL_WINDOWEVENT_ENTER) { + event.mouse.type = ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY; + SDL_GetMouseState(&event.mouse.x, &event.mouse.y); + event.mouse.x *= ratio; + event.mouse.y *= ratio; + } + else { + event.mouse.type = ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY; + event.mouse.x = mouse->state.x; + event.mouse.y = mouse->state.y; + event.mouse.z = mouse->state.z; + event.mouse.w = mouse->state.w; + } + mouse->display = e->window.event == SDL_WINDOWEVENT_ENTER ? d : NULL; + } + else if (e->type == SDL_MOUSEMOTION) { + if (e->motion.which == SDL_TOUCH_MOUSEID) { + _al_event_source_unlock(es); + return; + } + d = find_display(e->motion.windowID); + float ratio = d ? _al_sdl_get_display_pixel_ratio(d) : 1.0; + event.mouse.type = ALLEGRO_EVENT_MOUSE_AXES; + event.mouse.x = e->motion.x * ratio; + event.mouse.y = e->motion.y * ratio; + event.mouse.z = mouse->state.z; + event.mouse.w = mouse->state.w; + event.mouse.dx = e->motion.xrel * ratio; + event.mouse.dy = e->motion.yrel * ratio; + event.mouse.dz = 0; + event.mouse.dw = 0; + mouse->state.x = e->motion.x * ratio; + mouse->state.y = e->motion.y * ratio; + } + else if (e->type == SDL_MOUSEWHEEL) { + if (e->wheel.which == SDL_TOUCH_MOUSEID) { + _al_event_source_unlock(es); + return; + } + d = find_display(e->wheel.windowID); + event.mouse.type = ALLEGRO_EVENT_MOUSE_AXES; + mouse->state.z += al_get_mouse_wheel_precision() * e->wheel.y; + mouse->state.w += al_get_mouse_wheel_precision() * e->wheel.x; + event.mouse.x = mouse->state.x; + event.mouse.y = mouse->state.y; + event.mouse.z = mouse->state.z; + event.mouse.w = mouse->state.w; + event.mouse.dx = 0; + event.mouse.dy = 0; + event.mouse.dz = al_get_mouse_wheel_precision() * e->wheel.y; + event.mouse.dw = al_get_mouse_wheel_precision() * e->wheel.x; + } + else { + if (e->button.which == SDL_TOUCH_MOUSEID) { + _al_event_source_unlock(es); + return; + } + d = find_display(e->button.windowID); + float ratio = d ? _al_sdl_get_display_pixel_ratio(d) : 1.0; + switch (e->button.button) { + case SDL_BUTTON_LEFT: event.mouse.button = 1; break; + case SDL_BUTTON_RIGHT: event.mouse.button = 2; break; + case SDL_BUTTON_MIDDLE: event.mouse.button = 3; break; + case SDL_BUTTON_X1: event.mouse.button = 4; break; + case SDL_BUTTON_X2: event.mouse.button = 5; break; + } + event.mouse.x = e->button.x * ratio; + event.mouse.y = e->button.y * ratio; + event.mouse.z = mouse->state.z; + event.mouse.w = mouse->state.w; + if (e->type == SDL_MOUSEBUTTONDOWN) { + event.mouse.type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; + mouse->state.buttons |= 1 << (event.mouse.button - 1); + } + if (e->type == SDL_MOUSEBUTTONUP) { + event.mouse.type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; + mouse->state.buttons &= ~(1 << (event.mouse.button - 1)); + } + } + + event.mouse.pressure = mouse->state.buttons ? 1.0 : 0.0; /* TODO */ + event.mouse.display = d; + + _al_event_source_emit_event(es, &event); + _al_event_source_unlock(es); +} + +static bool sdl_init_mouse(void) +{ + mouse = al_calloc(1, sizeof *mouse); + _al_event_source_init(&mouse->mouse.es); + return true; +} + +static void sdl_exit_mouse(void) +{ +} + +static ALLEGRO_MOUSE *sdl_get_mouse(void) +{ + return &mouse->mouse; +} + +static unsigned int sdl_get_mouse_num_buttons(void) +{ + return 5; +} + +static unsigned int sdl_get_mouse_num_axes(void) +{ + return 4; +} + +static bool sdl_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) +{ + ALLEGRO_DISPLAY_SDL *sdl = (void *)display; + float ratio = _al_sdl_get_display_pixel_ratio(display); + SDL_WarpMouseInWindow(sdl->window, x / ratio, y / ratio); + return true; +} + +static bool sdl_set_mouse_axis(int which, int value) +{ + if (which == 1) mouse->state.z = value; + else if (which == 2) mouse->state.w = value; + else return false; + return true; +} + +static void sdl_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + int x, y, i; + float ratio = _al_sdl_get_display_pixel_ratio(mouse->display); + ALLEGRO_SYSTEM_INTERFACE *sdl = _al_sdl_system_driver(); + sdl->heartbeat(); + SDL_GetMouseState(&x, &y); + ret_state->x = x * ratio; + ret_state->y = y * ratio; + ret_state->z = 0; + ret_state->w = 0; + for (i = 0; i < ALLEGRO_MOUSE_MAX_EXTRA_AXES; i++) + ret_state->more_axes[i] = 0; + ret_state->buttons = mouse->state.buttons; + ret_state->pressure = mouse->state.buttons ? 1.0 : 0.0; /* TODO */ + ret_state->display = mouse->display; +} + +ALLEGRO_MOUSE_DRIVER *_al_sdl_mouse_driver(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + vt->msedrv_id = AL_ID('S','D','L','2'); + vt->msedrv_name = "SDL2 Mouse"; + vt->msedrv_desc = "SDL2 Mouse"; + vt->msedrv_ascii_name = "SDL2 Mouse"; + vt->init_mouse = sdl_init_mouse; + vt->exit_mouse = sdl_exit_mouse; + vt->get_mouse = sdl_get_mouse; + vt->get_mouse_num_buttons = sdl_get_mouse_num_buttons; + vt->get_mouse_num_axes = sdl_get_mouse_num_axes; + vt->set_mouse_xy = sdl_set_mouse_xy; + vt->set_mouse_axis = sdl_set_mouse_axis; + vt->get_mouse_state = sdl_get_mouse_state; + + return vt; +} diff --git a/allegro/src/sdl/sdl_system.c b/allegro/src/sdl/sdl_system.c new file mode 100644 index 00000000..3e996765 --- /dev/null +++ b/allegro/src/sdl/sdl_system.c @@ -0,0 +1,359 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL system interface. + * + * See LICENSE.txt for copyright information. + */ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/platform/allegro_internal_sdl.h" +#include "allegro5/internal/aintern_timer.h" + +ALLEGRO_DEBUG_CHANNEL("SDL") + +static ALLEGRO_SYSTEM_INTERFACE *vt; + +#ifdef DEBUGMODE +#define _E(x) if (type == x) return #x; +static char const *event_name(int type) +{ + _E(SDL_FIRSTEVENT) + _E(SDL_QUIT) + _E(SDL_APP_TERMINATING) + _E(SDL_APP_LOWMEMORY) + _E(SDL_APP_WILLENTERBACKGROUND) + _E(SDL_APP_DIDENTERBACKGROUND) + _E(SDL_APP_WILLENTERFOREGROUND) + _E(SDL_APP_DIDENTERFOREGROUND) + _E(SDL_WINDOWEVENT) + _E(SDL_SYSWMEVENT) + _E(SDL_KEYDOWN) + _E(SDL_KEYUP) + _E(SDL_TEXTEDITING) + _E(SDL_TEXTINPUT) + _E(SDL_MOUSEMOTION) + _E(SDL_MOUSEBUTTONDOWN) + _E(SDL_MOUSEBUTTONUP) + _E(SDL_MOUSEWHEEL) + _E(SDL_JOYAXISMOTION) + _E(SDL_JOYBALLMOTION) + _E(SDL_JOYHATMOTION) + _E(SDL_JOYBUTTONDOWN) + _E(SDL_JOYBUTTONUP) + _E(SDL_JOYDEVICEADDED) + _E(SDL_JOYDEVICEREMOVED) + _E(SDL_CONTROLLERAXISMOTION) + _E(SDL_CONTROLLERBUTTONDOWN) + _E(SDL_CONTROLLERBUTTONUP) + _E(SDL_CONTROLLERDEVICEADDED) + _E(SDL_CONTROLLERDEVICEREMOVED) + _E(SDL_CONTROLLERDEVICEREMAPPED) + _E(SDL_FINGERDOWN) + _E(SDL_FINGERUP) + _E(SDL_FINGERMOTION) + _E(SDL_DOLLARGESTURE) + _E(SDL_DOLLARRECORD) + _E(SDL_MULTIGESTURE) + _E(SDL_CLIPBOARDUPDATE) + _E(SDL_DROPFILE) + _E(SDL_RENDER_TARGETS_RESET) + _E(SDL_USEREVENT) + return "(unknown)"; +} +#undef _E +#endif + +static void sdl_heartbeat(void) +{ + ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver(); + al_lock_mutex(s->mutex); + SDL_Event event; + while (SDL_PollEvent(&event)) { + //printf("event %s\n", event_name(event.type)); + switch (event.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + case SDL_TEXTINPUT: + _al_sdl_keyboard_event(&event); + break; + case SDL_MOUSEMOTION: + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEWHEEL: + _al_sdl_mouse_event(&event); + break; + case SDL_FINGERDOWN: + case SDL_FINGERMOTION: + case SDL_FINGERUP: + _al_sdl_touch_input_event(&event); + break; + case SDL_JOYAXISMOTION: + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + case SDL_JOYDEVICEADDED: + case SDL_JOYDEVICEREMOVED: + _al_sdl_joystick_event(&event); + break; + case SDL_QUIT: + _al_sdl_display_event(&event); + break; + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_ENTER: + case SDL_WINDOWEVENT_LEAVE: + _al_sdl_mouse_event(&event); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + _al_sdl_display_event(&event); + _al_sdl_keyboard_event(&event); + break; + case SDL_WINDOWEVENT_CLOSE: + case SDL_WINDOWEVENT_RESIZED: + _al_sdl_display_event(&event); + break; + } + } + } +#ifdef __EMSCRIPTEN__ + double t = al_get_time(); + double interval = t - s->timer_time; + _al_timer_thread_handle_tick(interval); + s->timer_time = t; +#endif + al_unlock_mutex(s->mutex); +} + +static ALLEGRO_SYSTEM *sdl_initialize(int flags) +{ + (void)flags; + ALLEGRO_SYSTEM_SDL *s = al_calloc(1, sizeof *s); + s->system.vt = vt; + + SDL_Init(SDL_INIT_EVERYTHING); + + _al_vector_init(&s->system.displays, sizeof (ALLEGRO_DISPLAY_SDL *)); + + return &s->system; +} + +static void sdl_heartbeat_init(void) +{ + ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver(); + + /* This cannot be done in sdl_initialize because the threading system + * requires a completed ALLEGRO_SYSTEM which only exists after the + * function returns. This function on the other hand will get called + * once the system was created. + */ + s->mutex = al_create_mutex(); + +#ifdef __EMSCRIPTEN__ + s->timer_time = al_get_time(); +#endif +} + +static void sdl_shutdown_system(void) +{ + ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver(); + + /* Close all open displays. */ + while (_al_vector_size(&s->system.displays) > 0) { + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->system.displays, 0); + ALLEGRO_DISPLAY *d = *dptr; + al_destroy_display(d); + } + _al_vector_free(&s->system.displays); + + al_destroy_mutex(s->mutex); + al_free(s); + SDL_Quit(); +} + +static ALLEGRO_PATH *sdl_get_path(int id) +{ + ALLEGRO_PATH *p = NULL; + char* dir; + switch (id) { + case ALLEGRO_TEMP_PATH: + case ALLEGRO_USER_DOCUMENTS_PATH: + case ALLEGRO_USER_DATA_PATH: + case ALLEGRO_USER_SETTINGS_PATH: + dir = SDL_GetPrefPath(al_get_org_name(), al_get_app_name()); + p = al_create_path_for_directory(dir); + if (id == ALLEGRO_TEMP_PATH) { + al_append_path_component(p, "tmp"); + } + SDL_free(dir); + break; + case ALLEGRO_RESOURCES_PATH: + case ALLEGRO_EXENAME_PATH: + case ALLEGRO_USER_HOME_PATH: + dir = SDL_GetBasePath(); + p = al_create_path_for_directory(dir); + if (id == ALLEGRO_EXENAME_PATH) { + al_set_path_filename(p, al_get_app_name()); + } + SDL_free(dir); + break; + } + return p; +} + +static ALLEGRO_DISPLAY_INTERFACE *sdl_get_display_driver(void) +{ + return _al_sdl_display_driver(); +} + +static ALLEGRO_KEYBOARD_DRIVER *sdl_get_keyboard_driver(void) +{ + return _al_sdl_keyboard_driver(); +} + +static ALLEGRO_MOUSE_DRIVER *sdl_get_mouse_driver(void) +{ + return _al_sdl_mouse_driver(); +} + +static ALLEGRO_TOUCH_INPUT_DRIVER *sdl_get_touch_input_driver(void) +{ + return _al_sdl_touch_input_driver(); +} + +static ALLEGRO_JOYSTICK_DRIVER *sdl_get_joystick_driver(void) +{ + return _al_sdl_joystick_driver(); +} + +#define ADD(allegro, sdl) if (sdl_format == \ + SDL_PIXELFORMAT_##sdl) return ALLEGRO_PIXEL_FORMAT_##allegro; +int _al_sdl_get_allegro_pixel_format(int sdl_format) { + ADD(ARGB_8888, ARGB8888) + ADD(RGBA_8888, RGBA8888) + ADD(ABGR_8888, ABGR8888) + return 0; +} +#undef ADD + +#define ADD(allegro, sdl) if (allegro_format == \ + ALLEGRO_PIXEL_FORMAT_##allegro) return SDL_PIXELFORMAT_##sdl; +int _al_sdl_get_sdl_pixel_format(int allegro_format) { + ADD(ANY, ABGR8888) + ADD(ANY_NO_ALPHA, ABGR8888) + ADD(ANY_WITH_ALPHA, ABGR8888) + ADD(ANY_32_NO_ALPHA, ABGR8888) + ADD(ANY_32_WITH_ALPHA, ABGR8888) + ADD(ARGB_8888, ARGB8888) + ADD(RGBA_8888, RGBA8888) + ADD(ABGR_8888, ABGR8888) + ADD(ABGR_8888_LE, ABGR8888) + return 0; +} +#undef ADD + + +static int sdl_get_num_video_adapters(void) +{ + return SDL_GetNumVideoDisplays(); +} + +static bool sdl_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +{ + SDL_Rect rect; + if (SDL_GetDisplayBounds(adapter, &rect) < 0) + return false; + info->x1 = rect.x; + info->y1 = rect.y; + info->x2 = rect.x + rect.w; + info->y2 = rect.y + rect.h; + return true; +} + +static int sdl_get_num_display_modes(void) +{ + int i = al_get_new_display_adapter(); + if (i < 0) + i = 0; + return SDL_GetNumDisplayModes(i); +} + +static ALLEGRO_DISPLAY_MODE *sdl_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode) +{ + SDL_DisplayMode sdl_mode; + int i = al_get_new_display_adapter(); + if (i < 0) + i = 0; + if (SDL_GetDisplayMode(i, index, &sdl_mode) < 0) + return NULL; + mode->width = sdl_mode.w; + mode->height = sdl_mode.h; + mode->format = _al_sdl_get_allegro_pixel_format(sdl_mode.format); + mode->refresh_rate = sdl_mode.refresh_rate; + return mode; +} + +static bool sdl_inhibit_screensaver(bool inhibit) +{ + if (inhibit) { + SDL_DisableScreenSaver(); + } else { + SDL_EnableScreenSaver(); + } + return SDL_IsScreenSaverEnabled() != inhibit; +} + +/* Internal function to get a reference to this driver. */ +ALLEGRO_SYSTEM_INTERFACE *_al_sdl_system_driver(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + vt->id = ALLEGRO_SYSTEM_ID_SDL; + vt->initialize = sdl_initialize; + vt->get_display_driver = sdl_get_display_driver; + vt->get_keyboard_driver = sdl_get_keyboard_driver; + vt->get_mouse_driver = sdl_get_mouse_driver; + vt->get_touch_input_driver = sdl_get_touch_input_driver; + vt->get_joystick_driver = sdl_get_joystick_driver; + //vt->get_haptic_driver = sdl_get_haptic_driver; + vt->get_num_display_modes = sdl_get_num_display_modes; + vt->get_display_mode = sdl_get_display_mode; + vt->shutdown_system = sdl_shutdown_system; + vt->get_num_video_adapters = sdl_get_num_video_adapters; + vt->get_monitor_info = sdl_get_monitor_info; + /*vt->create_mouse_cursor = sdl_create_mouse_cursor; + vt->destroy_mouse_cursor = sdl_destroy_mouse_cursor; + vt->get_cursor_position = sdl_get_cursor_position; + vt->grab_mouse = sdl_grab_mouse; + vt->ungrab_mouse = sdl_ungrab_mouse;*/ + vt->get_path = sdl_get_path; + vt->inhibit_screensaver = sdl_inhibit_screensaver; + /*vt->thread_init = sdl_thread_init; + vt->thread_exit = sdl_thread_exit; + vt->open_library = sdl_open_library; + vt->import_symbol = sdl_import_symbol; + vt->close_library = sdl_close_library;*/ + vt->heartbeat = sdl_heartbeat; + vt->heartbeat_init = sdl_heartbeat_init; + vt->get_time = _al_sdl_get_time; + vt->rest = _al_sdl_rest; + vt->init_timeout = _al_sdl_init_timeout; + + return vt; +} + +void _al_register_system_interfaces(void) +{ + ALLEGRO_SYSTEM_INTERFACE **add; + add = _al_vector_alloc_back(&_al_system_interfaces); + *add = _al_sdl_system_driver(); +} diff --git a/allegro/src/sdl/sdl_thread.c b/allegro/src/sdl/sdl_thread.c new file mode 100644 index 00000000..f34f3b02 --- /dev/null +++ b/allegro/src/sdl/sdl_thread.c @@ -0,0 +1,112 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL thread support. + * + * See LICENSE.txt for copyright information. + */ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/platform/allegro_internal_sdl.h" + +ALLEGRO_DEBUG_CHANNEL("thread") + +static int thread_trampoline(void* data) +{ + _AL_THREAD *thread = data; + (*thread->proc)(thread, thread->arg); + return 0; +} + +void _al_thread_create(_AL_THREAD *thread, void (*proc)(_AL_THREAD*, void*), + void *arg) +{ + ASSERT(thread); + ASSERT(proc); + thread->should_stop = false; + thread->proc = proc; + thread->arg = arg; + thread->thread = SDL_CreateThread(thread_trampoline, "allegro", thread); +} + +void _al_thread_create_with_stacksize(_AL_THREAD *thread, void (*proc)(_AL_THREAD*, void*), + void *arg, size_t stacksize) +{ + ASSERT(thread); + ASSERT(proc); + thread->should_stop = false; + thread->proc = proc; + thread->arg = arg; +#if SDL_VERSION_ATLEAST(2,0,9) + thread->thread = SDL_CreateThreadWithStackSize(thread_trampoline, "allegro", stacksize, thread); +#else + (void)stacksize; + ALLEGRO_WARN("Creating a thread with a custom thread size is not supported " + "on this version of SDL, it is too old.\n"); + thread->thread = SDL_CreateThread(thread_trampoline, "allegro", thread); +#endif +} + +void _al_thread_set_should_stop(_AL_THREAD *thread) +{ + ASSERT(thread); + thread->should_stop = true; +} + +void _al_thread_join(_AL_THREAD *thread) +{ + ASSERT(thread); + _al_thread_set_should_stop(thread); + int r; + SDL_WaitThread(thread->thread, &r); +} + +void _al_thread_detach(_AL_THREAD *thread) +{ + ASSERT(thread); + SDL_DetachThread(thread->thread); +} + +/* mutexes */ + +void _al_mutex_init(_AL_MUTEX *mutex) +{ + ASSERT(mutex); + + mutex->mutex = SDL_CreateMutex(); +} + +void _al_mutex_init_recursive(_AL_MUTEX *mutex) +{ + _al_mutex_init(mutex); +} + +void _al_mutex_destroy(_AL_MUTEX *mutex) +{ + ASSERT(mutex); + + if (mutex->mutex) { + SDL_DestroyMutex(mutex->mutex); + mutex->mutex = NULL; + } +} + +/* condition variables */ +/* most of the condition variable implementation is actually inline */ + +int _al_cond_timedwait(_AL_COND *cond, _AL_MUTEX *mutex, + const ALLEGRO_TIMEOUT *timeout) +{ + ALLEGRO_TIMEOUT_SDL *timeout_sdl = (void *)timeout; + int r = SDL_CondWaitTimeout(cond->cond, mutex->mutex, timeout_sdl->ms); + + return (r == SDL_MUTEX_TIMEDOUT) ? -1 : 0; +} diff --git a/allegro/src/sdl/sdl_time.c b/allegro/src/sdl/sdl_time.c new file mode 100644 index 00000000..8cc5a2e3 --- /dev/null +++ b/allegro/src/sdl/sdl_time.c @@ -0,0 +1,43 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL time driver. + * + * See LICENSE.txt for copyright information. + */ +#include "SDL.h" + +#include "allegro5/altime.h" +#include "allegro5/platform/allegro_internal_sdl.h" +#include "allegro5/debug.h" + +ALLEGRO_DEBUG_CHANNEL("SDL") + +double _al_sdl_get_time(void) +{ + return 1.0 * SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency(); +} + + + +void _al_sdl_rest(double seconds) +{ + SDL_Delay(seconds * 1000); +} + + + +void _al_sdl_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds) +{ + ALLEGRO_TIMEOUT_SDL *timeout_sdl = (void *)timeout; + timeout_sdl->ms = seconds * 1000; +} + +/* vim: set sts=3 sw=3 et */ diff --git a/allegro/src/sdl/sdl_touch.c b/allegro/src/sdl/sdl_touch.c new file mode 100644 index 00000000..6afde2ca --- /dev/null +++ b/allegro/src/sdl/sdl_touch.c @@ -0,0 +1,268 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * SDL touch driver. + * + * See LICENSE.txt for copyright information. + */ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/platform/allegro_internal_sdl.h" + +ALLEGRO_DEBUG_CHANNEL("SDL") + +typedef struct ALLEGRO_TOUCH_INPUT_SDL +{ + ALLEGRO_TOUCH_INPUT touch_input; + ALLEGRO_TOUCH_INPUT_STATE state; + ALLEGRO_DISPLAY *display; + int touches; +} ALLEGRO_TOUCH_INPUT_SDL; + +static ALLEGRO_TOUCH_INPUT_DRIVER *vt; +static ALLEGRO_TOUCH_INPUT_SDL *touch_input; +static ALLEGRO_MOUSE_STATE mouse_state; + +static void generate_touch_input_event(unsigned int type, double timestamp, + int id, float x, float y, float dx, float dy, bool primary, + ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_EVENT event; + + bool want_touch_event = _al_event_source_needs_to_generate_event(&touch_input->touch_input.es); + bool want_mouse_emulation_event; + + if (touch_input->touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_5_0_x) { + want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input->touch_input.mouse_emulation_es) && al_is_mouse_installed(); + } + else { + want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input->touch_input.mouse_emulation_es) && primary && al_is_mouse_installed(); + } + + if (touch_input->touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_NONE) + want_mouse_emulation_event = false; + else if (touch_input->touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_INCLUSIVE) + want_touch_event = al_is_mouse_installed() ? (want_touch_event && !primary) : want_touch_event; + else if (touch_input->touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_EXCLUSIVE) + want_touch_event = al_is_mouse_installed() ? false : want_touch_event; + + + if (!want_touch_event && !want_mouse_emulation_event) + return; + + if (want_touch_event) { + event.touch.type = type; + event.touch.display = (ALLEGRO_DISPLAY*)disp; + event.touch.timestamp = timestamp; + event.touch.id = id; + event.touch.x = x; + event.touch.y = y; + event.touch.dx = dx; + event.touch.dy = dy; + event.touch.primary = primary; + + _al_event_source_lock(&touch_input->touch_input.es); + _al_event_source_emit_event(&touch_input->touch_input.es, &event); + _al_event_source_unlock(&touch_input->touch_input.es); + } + + if (touch_input->touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_NONE) { + mouse_state.x = (int)x; + mouse_state.y = (int)y; + if (type == ALLEGRO_EVENT_TOUCH_BEGIN) + mouse_state.buttons++; + else if (type == ALLEGRO_EVENT_TOUCH_END) + mouse_state.buttons--; + + mouse_state.pressure = mouse_state.buttons ? 1.0 : 0.0; /* TODO */ + + _al_event_source_lock(&touch_input->touch_input.mouse_emulation_es); + if (want_mouse_emulation_event) { + + switch (type) { + case ALLEGRO_EVENT_TOUCH_BEGIN: type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; break; + case ALLEGRO_EVENT_TOUCH_CANCEL: + case ALLEGRO_EVENT_TOUCH_END: type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; break; + case ALLEGRO_EVENT_TOUCH_MOVE: type = ALLEGRO_EVENT_MOUSE_AXES; break; + } + + event.mouse.type = type; + event.mouse.timestamp = timestamp; + event.mouse.display = (ALLEGRO_DISPLAY*)disp; + event.mouse.x = (int)x; + event.mouse.y = (int)y; + event.mouse.dx = (int)dx; + event.mouse.dy = (int)dy; + event.mouse.dz = 0; + event.mouse.dw = 0; + if (touch_input->touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_5_0_x) { + event.mouse.button = 1; + } + else { + event.mouse.button = id; + } + event.mouse.pressure = mouse_state.pressure; + + if (touch_input->touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_5_0_x) { + al_set_mouse_xy(event.mouse.display, event.mouse.x, event.mouse.y); + } + + _al_event_source_emit_event(&touch_input->touch_input.mouse_emulation_es, &event); + } + _al_event_source_unlock(&touch_input->touch_input.mouse_emulation_es); + } +} + +void _al_sdl_touch_input_event(SDL_Event *e) +{ + if (!touch_input) + return; + + ALLEGRO_EVENT_TYPE type; + + ALLEGRO_DISPLAY *d = NULL; + /* Use the first display as event source if we have any displays. */ + ALLEGRO_SYSTEM *s = al_get_system_driver(); + if (_al_vector_size(&s->displays) > 0) { + void **v = (void **)_al_vector_ref(&s->displays, 0); + d = *v; + } + if (!d) { + return; + } + + int touchId = e->tfinger.fingerId; + + // SDL2 only returns absolute positions of touches on the input device. This means we have to fake them + // in order to make them related to the display, which is what Allegro returns in its API. + // This is likely to break in lots of cases, but should work well with non-rotated fullscreen or Wayland windows. + // NOTE: SDL 2.0.10 is going to have SDL_GetTouchDeviceType API which may be somewhat helpful here. + + touch_input->state.touches[touchId].x = e->tfinger.x * al_get_display_width(d); + touch_input->state.touches[touchId].y = e->tfinger.y * al_get_display_height(d); + touch_input->state.touches[touchId].dx = e->tfinger.dx * al_get_display_width(d); + touch_input->state.touches[touchId].dy = e->tfinger.dy * al_get_display_height(d); + + if (e->type == SDL_FINGERDOWN) { + type = ALLEGRO_EVENT_TOUCH_BEGIN; + touch_input->state.touches[touchId].id = touchId; + touch_input->state.touches[touchId].primary = (touch_input->touches == 0); + touch_input->touches++; + } + else if (e->type == SDL_FINGERMOTION) { + type = ALLEGRO_EVENT_TOUCH_MOVE; + } + else if (e->type == SDL_FINGERUP) { + type = ALLEGRO_EVENT_TOUCH_END; + touch_input->touches--; + touch_input->state.touches[touchId].id = -1; + } else { + return; + } + + generate_touch_input_event(type, e->tfinger.timestamp / 1000.0, touchId, + touch_input->state.touches[touchId].x, + touch_input->state.touches[touchId].y, + touch_input->state.touches[touchId].dx, + touch_input->state.touches[touchId].dy, + touch_input->state.touches[touchId].primary, + d); +} + +static bool sdl_init_touch_input(void) +{ + touch_input = al_calloc(1, sizeof *touch_input); + _al_event_source_init(&touch_input->touch_input.es); + + _al_event_source_init(&touch_input->touch_input.mouse_emulation_es); + touch_input->touch_input.mouse_emulation_mode = ALLEGRO_MOUSE_EMULATION_TRANSPARENT; + + int i; + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; i++) { + touch_input->state.touches[i].id = -1; + } + + return true; +} + +static void sdl_exit_touch_input(void) +{ +} + +static ALLEGRO_TOUCH_INPUT *sdl_get_touch_input(void) +{ + return &touch_input->touch_input; +} + + +static void sdl_get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state) +{ + _al_event_source_lock(&touch_input->touch_input.es); + *ret_state = touch_input->state; + _al_event_source_unlock(&touch_input->touch_input.es); +} + +static void touch_input_handle_cancel(int index, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_TOUCH_STATE* state = touch_input->state.touches + index; + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input->touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input->touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_CANCEL, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, disp); + + _al_event_source_lock(&touch_input->touch_input.es); + state->id = -1; + _al_event_source_unlock(&touch_input->touch_input.es); +} + +static void sdl_set_mouse_emulation_mode(int mode) +{ + if (touch_input->touch_input.mouse_emulation_mode != mode) { + + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) { + + ALLEGRO_TOUCH_STATE* touch = touch_input->state.touches + i; + + if (touch->id > 0) { + touch_input_handle_cancel(i, al_get_time(), + touch->x, touch->y, touch->primary, touch->display); + } + } + + touch_input->touch_input.mouse_emulation_mode = mode; + } +} + +ALLEGRO_TOUCH_INPUT_DRIVER *_al_sdl_touch_input_driver(void) +{ + if (vt) + return vt; + + vt = al_calloc(1, sizeof *vt); + vt->init_touch_input = sdl_init_touch_input; + vt->exit_touch_input = sdl_exit_touch_input; + vt->get_touch_input = sdl_get_touch_input; + vt->get_touch_input_state = sdl_get_touch_input_state; + vt->set_mouse_emulation_mode = sdl_set_mouse_emulation_mode; + + return vt; +} diff --git a/allegro/src/shader.c b/allegro/src/shader.c new file mode 100644 index 00000000..be47fbf4 --- /dev/null +++ b/allegro/src/shader.c @@ -0,0 +1,504 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Shader API. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_shader.h" +#include "allegro5/internal/aintern_system.h" + +#ifdef ALLEGRO_CFG_SHADER_GLSL +#include "allegro5/allegro_opengl.h" +#endif + +ALLEGRO_DEBUG_CHANNEL("shader") + +#include "shader_source.inc" + + +static ALLEGRO_SHADER_PLATFORM resolve_platform(ALLEGRO_SHADER_PLATFORM platform) +{ + if (platform == ALLEGRO_SHADER_AUTO) { + ALLEGRO_DISPLAY *display = al_get_current_display(); + ASSERT(display); + if (al_get_display_flags(display) & ALLEGRO_OPENGL) { + platform = ALLEGRO_SHADER_GLSL; + } + else { + platform = ALLEGRO_SHADER_HLSL; + } + } + + return platform; +} + +/* Function: al_create_shader + */ +ALLEGRO_SHADER *al_create_shader(ALLEGRO_SHADER_PLATFORM platform) +{ + ALLEGRO_SHADER *shader = NULL; + + platform = resolve_platform(platform); + + if (false) { + } +#ifdef ALLEGRO_CFG_SHADER_GLSL + else if (platform == ALLEGRO_SHADER_GLSL) { + shader = _al_create_shader_glsl(platform); + } +#endif +#ifdef ALLEGRO_CFG_SHADER_HLSL + else if (platform == ALLEGRO_SHADER_HLSL) { + shader = _al_create_shader_hlsl(platform); + } +#endif + + if (shader) { + ASSERT(shader->platform); + ASSERT(shader->vt); + shader->dtor_item = _al_register_destructor(_al_dtor_list, "shader", shader, + (void (*)(void *))al_destroy_shader); + } + else { + ALLEGRO_WARN("Failed to create shader\n"); + } + return shader; +} + +/* Function: al_attach_shader_source + */ +bool al_attach_shader_source(ALLEGRO_SHADER *shader, ALLEGRO_SHADER_TYPE type, + const char *source) +{ + ASSERT(shader); + return shader->vt->attach_shader_source(shader, type, source); +} + +/* Function: al_attach_shader_source_file + */ +bool al_attach_shader_source_file(ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *filename) +{ + ALLEGRO_FILE *fp; + ALLEGRO_USTR *str; + bool ret; + + fp = al_fopen(filename, "r"); + if (!fp) { + ALLEGRO_WARN("Failed to open %s\n", filename); + al_ustr_free(shader->log); + shader->log = al_ustr_newf("Failed to open %s", filename); + return false; + } + str = al_ustr_new(""); + for (;;) { + char buf[512]; + size_t n; + ALLEGRO_USTR_INFO info; + + n = al_fread(fp, buf, sizeof(buf)); + if (n <= 0) + break; + al_ustr_append(str, al_ref_buffer(&info, buf, n)); + } + al_fclose(fp); + ret = al_attach_shader_source(shader, type, al_cstr(str)); + al_ustr_free(str); + return ret; +} + +/* Function: al_build_shader + */ +bool al_build_shader(ALLEGRO_SHADER *shader) +{ + ASSERT(shader); + return shader->vt->build_shader(shader); +} + +/* Function: al_get_shader_log + */ +const char *al_get_shader_log(ALLEGRO_SHADER *shader) +{ + ASSERT(shader); + + return (shader->log) ? al_cstr(shader->log) : ""; +} + +/* Function: al_get_shader_platform + */ +ALLEGRO_SHADER_PLATFORM al_get_shader_platform(ALLEGRO_SHADER *shader) +{ + ASSERT(shader); + return shader->platform; +} + +/* Function: al_use_shader + */ +bool al_use_shader(ALLEGRO_SHADER *shader) +{ + ALLEGRO_BITMAP *bmp = al_get_target_bitmap(); + ALLEGRO_DISPLAY *disp; + + if (!bmp) { + ALLEGRO_WARN("No current target bitmap.\n"); + return false; + } + if (al_get_bitmap_flags(bmp) & ALLEGRO_MEMORY_BITMAP) { + ALLEGRO_WARN("Target bitmap is memory bitmap.\n"); + return false; + } + disp = _al_get_bitmap_display(bmp); + ASSERT(disp); + + if (shader) { + if (shader->vt->use_shader(shader, disp, true)) { + _al_set_bitmap_shader_field(bmp, shader); + ALLEGRO_DEBUG("use_shader succeeded\n"); + return true; + } + else { + _al_set_bitmap_shader_field(bmp, NULL); + ALLEGRO_ERROR("use_shader failed\n"); + if (disp->default_shader) { + disp->default_shader->vt->use_shader( + disp->default_shader, disp, true); + } + return false; + } + } + else { + if (bmp->shader) { + bmp->shader->vt->unuse_shader(bmp->shader, disp); + _al_set_bitmap_shader_field(bmp, NULL); + } + if (disp->default_shader) { + disp->default_shader->vt->use_shader( + disp->default_shader, disp, true); + } + return true; + } +} + +/* Function: al_destroy_shader + */ +void al_destroy_shader(ALLEGRO_SHADER *shader) +{ + ALLEGRO_BITMAP *bmp; + unsigned i; + + if (!shader) + return; + + /* As a convenience, implicitly unuse the shader on the target bitmap + * if currently used. + */ + bmp = al_get_target_bitmap(); + if (bmp && _al_vector_contains(&shader->bitmaps, &bmp)) { + ALLEGRO_DEBUG("implicitly unusing shader on target bitmap\n"); + al_use_shader(NULL); + } + + _al_unregister_destructor(_al_dtor_list, shader->dtor_item); + + al_ustr_free(shader->vertex_copy); + shader->vertex_copy = NULL; + al_ustr_free(shader->pixel_copy); + shader->pixel_copy = NULL; + al_ustr_free(shader->log); + shader->log = NULL; + + /* Clear references to this shader from all bitmaps. */ + for (i = 0; i < _al_vector_size(&shader->bitmaps); i++) { + ALLEGRO_BITMAP **slot = _al_vector_ref(&shader->bitmaps, i); + ALLEGRO_BITMAP *bitmap = *slot; + ASSERT(bitmap->shader == shader); + bitmap->shader = NULL; + } + _al_vector_free(&shader->bitmaps); + + shader->vt->destroy_shader(shader); +} + +/* Function: al_set_shader_sampler + */ +bool al_set_shader_sampler(const char *name, + ALLEGRO_BITMAP *bitmap, int unit) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_SHADER *shader; + + if ((bmp = al_get_target_bitmap()) != NULL) { + if ((shader = bmp->shader) != NULL) { + return shader->vt->set_shader_sampler(shader, name, bitmap, unit); + } + else { + return false; + } + } + else { + return false; + } +} + +/* Function: al_set_shader_matrix + */ +bool al_set_shader_matrix(const char *name, + const ALLEGRO_TRANSFORM *matrix) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_SHADER *shader; + + if ((bmp = al_get_target_bitmap()) != NULL) { + if ((shader = bmp->shader) != NULL) { + return shader->vt->set_shader_matrix(shader, name, matrix); + } + else { + return false; + } + } + else { + return false; + } +} + +/* Function: al_set_shader_int + */ +bool al_set_shader_int(const char *name, int i) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_SHADER *shader; + + if ((bmp = al_get_target_bitmap()) != NULL) { + if ((shader = bmp->shader) != NULL) { + return shader->vt->set_shader_int(shader, name, i); + } + else { + return false; + } + } + else { + return false; + } +} + +/* Function: al_set_shader_float + */ +bool al_set_shader_float(const char *name, float f) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_SHADER *shader; + + if ((bmp = al_get_target_bitmap()) != NULL) { + if ((shader = bmp->shader) != NULL) { + return shader->vt->set_shader_float(shader, name, f); + } + else { + return false; + } + } + else { + return false; + } +} + +/* Function: al_set_shader_int_vector + */ +bool al_set_shader_int_vector(const char *name, + int num_components, const int *i, int num_elems) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_SHADER *shader; + + if ((bmp = al_get_target_bitmap()) != NULL) { + if ((shader = bmp->shader) != NULL) { + return shader->vt->set_shader_int_vector(shader, name, num_components, i, num_elems); + } + else { + return false; + } + } + else { + return false; + } +} + +/* Function: al_set_shader_float_vector + */ +bool al_set_shader_float_vector(const char *name, + int num_components, const float *f, int num_elems) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_SHADER *shader; + + if ((bmp = al_get_target_bitmap()) != NULL) { + if ((shader = bmp->shader) != NULL) { + return shader->vt->set_shader_float_vector(shader, name, num_components, f, num_elems); + } + else { + return false; + } + } + else { + return false; + } +} + +/* Function: al_set_shader_bool + */ +bool al_set_shader_bool(const char *name, bool b) +{ + ALLEGRO_BITMAP *bmp; + ALLEGRO_SHADER *shader; + + if ((bmp = al_get_target_bitmap()) != NULL) { + if ((shader = bmp->shader) != NULL) { + return shader->vt->set_shader_bool(shader, name, b); + } + else { + return false; + } + } + else { + return false; + } +} + +/* Function: al_get_default_shader_source + */ +char const *al_get_default_shader_source(ALLEGRO_SHADER_PLATFORM platform, + ALLEGRO_SHADER_TYPE type) +{ + (void)type; + switch (resolve_platform(platform)) { + case ALLEGRO_SHADER_GLSL: +#ifdef ALLEGRO_CFG_SHADER_GLSL + switch (type) { + case ALLEGRO_VERTEX_SHADER: + return default_glsl_vertex_source; + case ALLEGRO_PIXEL_SHADER: + return default_glsl_pixel_source; + } +#endif + break; + + case ALLEGRO_SHADER_HLSL: +#ifdef ALLEGRO_CFG_SHADER_HLSL + switch (type) { + case ALLEGRO_VERTEX_SHADER: + return default_hlsl_vertex_source; + case ALLEGRO_PIXEL_SHADER: + return default_hlsl_pixel_source; + } +#endif + break; + + case ALLEGRO_SHADER_AUTO: + ASSERT(0); + } + return NULL; +} + +void _al_set_bitmap_shader_field(ALLEGRO_BITMAP *bmp, ALLEGRO_SHADER *shader) +{ + ASSERT(bmp); + + if (bmp->shader != shader) { + if (bmp->shader) { + _al_unregister_shader_bitmap(bmp->shader, bmp); + } + bmp->shader = shader; + if (bmp->shader) { + _al_register_shader_bitmap(bmp->shader, bmp); + } + } +} + +void _al_register_shader_bitmap(ALLEGRO_SHADER *shader, ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_BITMAP **slot; + ASSERT(shader); + ASSERT(bmp); + + slot = _al_vector_alloc_back(&shader->bitmaps); + *slot = bmp; +} + +void _al_unregister_shader_bitmap(ALLEGRO_SHADER *shader, ALLEGRO_BITMAP *bmp) +{ + bool deleted; + ASSERT(shader); + ASSERT(bmp); + + deleted = _al_vector_find_and_delete(&shader->bitmaps, &bmp); + ASSERT(deleted); +} + +ALLEGRO_SHADER *_al_create_default_shader(int display_flags) +{ + ALLEGRO_SHADER_PLATFORM platform = ALLEGRO_SHADER_AUTO; + ALLEGRO_SHADER *shader; + (void)display_flags; + + if (false) { + } +#ifdef ALLEGRO_CFG_SHADER_GLSL + else if (display_flags & ALLEGRO_OPENGL) { + platform = ALLEGRO_SHADER_GLSL; + } +#endif +#ifdef ALLEGRO_CFG_SHADER_HLSL + else if (display_flags & ALLEGRO_DIRECT3D_INTERNAL) { + platform = ALLEGRO_SHADER_HLSL; + } +#endif + + if (platform == ALLEGRO_SHADER_AUTO) { + ALLEGRO_ERROR("No suitable shader platform found for creating the default shader.\n"); + return false; + } + + _al_push_destructor_owner(); + shader = al_create_shader(platform); + _al_pop_destructor_owner(); + + if (!shader) { + ALLEGRO_ERROR("Error creating default shader.\n"); + return false; + } + if (!al_attach_shader_source(shader, ALLEGRO_VERTEX_SHADER, + al_get_default_shader_source(platform, ALLEGRO_VERTEX_SHADER))) { + ALLEGRO_ERROR("al_attach_shader_source for vertex shader failed: %s\n", + al_get_shader_log(shader)); + goto fail; + } + if (!al_attach_shader_source(shader, ALLEGRO_PIXEL_SHADER, + al_get_default_shader_source(platform, ALLEGRO_PIXEL_SHADER))) { + ALLEGRO_ERROR("al_attach_shader_source for pixel shader failed: %s\n", + al_get_shader_log(shader)); + goto fail; + } + if (!al_build_shader(shader)) { + ALLEGRO_ERROR("al_build_shader failed: %s\n", al_get_shader_log(shader)); + goto fail; + } + return shader; + +fail: + al_destroy_shader(shader); + return NULL; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/shader_source.inc b/allegro/src/shader_source.inc new file mode 100644 index 00000000..d102f369 --- /dev/null +++ b/allegro/src/shader_source.inc @@ -0,0 +1,140 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Default shader sources. + * + * See LICENSE.txt for copyright information. + */ + + +#ifdef ALLEGRO_CFG_SHADER_GLSL + +static const char *default_glsl_vertex_source = + "attribute vec4 " ALLEGRO_SHADER_VAR_POS ";\n" + "attribute vec4 " ALLEGRO_SHADER_VAR_COLOR ";\n" + "attribute vec2 " ALLEGRO_SHADER_VAR_TEXCOORD ";\n" + "uniform mat4 " ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX ";\n" + "uniform bool " ALLEGRO_SHADER_VAR_USE_TEX_MATRIX ";\n" + "uniform mat4 " ALLEGRO_SHADER_VAR_TEX_MATRIX ";\n" + "varying vec4 varying_color;\n" + "varying vec2 varying_texcoord;\n" + "void main()\n" + "{\n" + " varying_color = " ALLEGRO_SHADER_VAR_COLOR ";\n" + " if (" ALLEGRO_SHADER_VAR_USE_TEX_MATRIX ") {\n" + " vec4 uv = " ALLEGRO_SHADER_VAR_TEX_MATRIX " * vec4(" ALLEGRO_SHADER_VAR_TEXCOORD ", 0, 1);\n" + " varying_texcoord = vec2(uv.x, uv.y);\n" + " }\n" + " else\n" + " varying_texcoord = " ALLEGRO_SHADER_VAR_TEXCOORD";\n" + " gl_Position = " ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX " * " ALLEGRO_SHADER_VAR_POS ";\n" + "}\n"; + +static const char *default_glsl_pixel_source = + "#ifdef GL_ES\n" + "precision lowp float;\n" + "#endif\n" + "uniform sampler2D " ALLEGRO_SHADER_VAR_TEX ";\n" + "uniform bool " ALLEGRO_SHADER_VAR_USE_TEX ";\n" + "uniform bool " ALLEGRO_SHADER_VAR_ALPHA_TEST ";\n" + "uniform int " ALLEGRO_SHADER_VAR_ALPHA_FUNCTION ";\n" + "uniform float " ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE ";\n" + "varying vec4 varying_color;\n" + "varying vec2 varying_texcoord;\n" + "\n" + "bool alpha_test_func(float x, int op, float compare);\n" + "\n" + "void main()\n" + "{\n" + " vec4 c;\n" + " if (" ALLEGRO_SHADER_VAR_USE_TEX ")\n" + " c = varying_color * texture2D(" ALLEGRO_SHADER_VAR_TEX ", varying_texcoord);\n" + " else\n" + " c = varying_color;\n" + " if (!" ALLEGRO_SHADER_VAR_ALPHA_TEST " || alpha_test_func(c.a, " ALLEGRO_SHADER_VAR_ALPHA_FUNCTION ", " + ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE "))\n" + " gl_FragColor = c;\n" + " else\n" + " discard;\n" + "}\n" + "\n" + "bool alpha_test_func(float x, int op, float compare)\n" + "{\n" + // Note: These must be aligned with the ALLEGRO_RENDER_FUNCTION enum values. + " if (op == 0) return false;\n" // ALLEGRO_RENDER_NEVER + " else if (op == 1) return true;\n" // ALLEGRO_RENDER_ALWAYS + " else if (op == 2) return x < compare;\n" // ALLEGRO_RENDER_LESS + " else if (op == 3) return x == compare;\n" // ALLEGRO_RENDER_EQUAL + " else if (op == 4) return x <= compare;\n" // ALLEGRO_RENDER_LESS_EQUAL + " else if (op == 5) return x > compare;\n" // ALLEGRO_RENDER_GREATER + " else if (op == 6) return x != compare;\n" // ALLEGRO_RENDER_NOT_EQUAL + " else if (op == 7) return x >= compare;\n" // ALLEGRO_RENDER_GREATER_EQUAL + " return false;\n" + "}\n"; + +#endif /* ALLEGRO_CFG_SHADER_GLSL */ + + +#ifdef ALLEGRO_CFG_SHADER_HLSL + +static const char *default_hlsl_vertex_source = + "struct VS_INPUT\n" + "{\n" + " float4 Position : POSITION0;\n" + " float2 TexCoord : TEXCOORD0;\n" + " float4 Color : TEXCOORD1;\n" + "};\n" + "struct VS_OUTPUT\n" + "{\n" + " float4 Position : POSITION0;\n" + " float4 Color : COLOR0;\n" + " float2 TexCoord : TEXCOORD0;\n" + "};\n" + "\n" + "float4x4 " ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX ";\n" + "bool " ALLEGRO_SHADER_VAR_USE_TEX_MATRIX ";\n" + "float4x4 " ALLEGRO_SHADER_VAR_TEX_MATRIX ";\n" + "\n" + "VS_OUTPUT vs_main(VS_INPUT Input)\n" + "{\n" + " VS_OUTPUT Output;\n" + " Output.Color = Input.Color;\n" + " if (" ALLEGRO_SHADER_VAR_USE_TEX_MATRIX ") {\n" + " Output.TexCoord = mul(float4(Input.TexCoord, 1.0f, 0.0f), " + ALLEGRO_SHADER_VAR_TEX_MATRIX ").xy;\n" + " }\n" + " else {\n" + " Output.TexCoord = Input.TexCoord;\n" + " }\n" + " Output.Position = mul(Input.Position, " ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX ");\n" + " return Output;\n" + "}\n"; + +static const char *default_hlsl_pixel_source = + "bool " ALLEGRO_SHADER_VAR_USE_TEX ";\n" + "texture " ALLEGRO_SHADER_VAR_TEX ";\n" + "sampler2D s = sampler_state {\n" + " texture = <" ALLEGRO_SHADER_VAR_TEX ">;\n" + "};\n" + "\n" + "float4 ps_main(VS_OUTPUT Input) : COLOR0\n" + "{\n" + " if (" ALLEGRO_SHADER_VAR_USE_TEX ") {\n" + " return Input.Color * tex2D(s, Input.TexCoord);\n" + " }\n" + " else {\n" + " return Input.Color;\n" + " }\n" + "}\n"; + +#endif /* ALLEGRO_CFG_SHADER_HLSL */ + + +/* vim: set ft=c sts=3 sw=3 et: */ diff --git a/allegro/src/system.c b/allegro/src/system.c new file mode 100644 index 00000000..bbf81d2b --- /dev/null +++ b/allegro/src/system.c @@ -0,0 +1,534 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New system driver. + * + * By Elias Pschernig. + * + * Modified by Trent Gamblin. + */ + +/* Title: System routines + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#ifdef ALLEGRO_CFG_SHADER_GLSL +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_opengl.h" +#endif +#include ALLEGRO_INTERNAL_HEADER +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_debug.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/internal/aintern_timer.h" +#include "allegro5/internal/aintern_tls.h" +#include "allegro5/internal/aintern_vector.h" + +ALLEGRO_DEBUG_CHANNEL("system") + +static ALLEGRO_SYSTEM *active_sysdrv = NULL; +static ALLEGRO_CONFIG *sys_config = NULL; + +_AL_VECTOR _al_system_interfaces; +static _AL_VECTOR _user_system_interfaces = _AL_VECTOR_INITIALIZER(ALLEGRO_SYSTEM_INTERFACE *); + +_AL_DTOR_LIST *_al_dtor_list = NULL; + +static bool atexit_virgin = true; + +static char _al_app_name[256] = ""; +static char _al_org_name[256] = ""; + + + +static ALLEGRO_SYSTEM *find_system(_AL_VECTOR *vector) +{ + ALLEGRO_SYSTEM_INTERFACE **sptr; + ALLEGRO_SYSTEM_INTERFACE *sys_interface; + ALLEGRO_SYSTEM *system; + unsigned int i; + + for (i = 0; i < vector->_size; i++) { + sptr = _al_vector_ref(vector, i); + sys_interface = *sptr; + if ((system = sys_interface->initialize(0)) != NULL) + return system; + } + + return NULL; +} + + + +static void shutdown_system_driver(void) +{ + if (active_sysdrv) { + if (active_sysdrv->user_exe_path) + al_destroy_path(active_sysdrv->user_exe_path); + if (active_sysdrv->vt && active_sysdrv->vt->shutdown_system) + active_sysdrv->vt->shutdown_system(); + active_sysdrv = NULL; + + while (!_al_vector_is_empty(&_al_system_interfaces)) + _al_vector_delete_at(&_al_system_interfaces, _al_vector_size(&_al_system_interfaces)-1); + _al_vector_free(&_al_system_interfaces); + _al_vector_init(&_al_system_interfaces, sizeof(ALLEGRO_SYSTEM_INTERFACE *)); + } + al_destroy_config(sys_config); + sys_config = NULL; +} + + + +/* al_get_standard_path() does not work before the system driver is + * initialised. Before that, we need to call the underlying functions + * directly. + */ +static ALLEGRO_PATH *early_get_exename_path(void) +{ +#if defined(ALLEGRO_WINDOWS) + return _al_win_get_path(ALLEGRO_EXENAME_PATH); +#elif defined(ALLEGRO_MACOSX) + return _al_osx_get_path(ALLEGRO_EXENAME_PATH); +#elif defined(ALLEGRO_IPHONE) + return _al_iphone_get_path(ALLEGRO_EXENAME_PATH); +#elif defined(ALLEGRO_UNIX) + return _al_unix_get_path(ALLEGRO_EXENAME_PATH); +#elif defined(ALLEGRO_ANDROID) + return _al_android_get_path(ALLEGRO_EXENAME_PATH); +#elif defined(ALLEGRO_SDL) + char* p = SDL_GetBasePath(); + ALLEGRO_PATH *path = al_create_path_for_directory(p); + SDL_free(p); + return path; +#else + #error early_get_exename_path not implemented +#endif +} + + + +static void read_allegro_cfg(void) +{ + /* We assume that the stdio file interface is in effect. */ + + ALLEGRO_PATH *path; + ALLEGRO_CONFIG *temp; + + if (!sys_config) + sys_config = al_create_config(); + +#if defined(ALLEGRO_UNIX) && !defined(ALLEGRO_IPHONE) + temp = al_load_config_file("/etc/allegro5rc"); + if (temp) { + al_merge_config_into(sys_config, temp); + al_destroy_config(temp); + } + + path = _al_unix_get_path(ALLEGRO_USER_HOME_PATH); + if (path) { + al_set_path_filename(path, "allegro5rc"); + temp = al_load_config_file(al_path_cstr(path, '/')); + if (temp) { + al_merge_config_into(sys_config, temp); + al_destroy_config(temp); + } + al_set_path_filename(path, ".allegro5rc"); + temp = al_load_config_file(al_path_cstr(path, '/')); + if (temp) { + al_merge_config_into(sys_config, temp); + al_destroy_config(temp); + } + al_destroy_path(path); + } +#endif + + path = early_get_exename_path(); + if (path) { + al_set_path_filename(path, "allegro5.cfg"); + temp = al_load_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); + if (temp) { + al_merge_config_into(sys_config, temp); + al_destroy_config(temp); + } + al_destroy_path(path); + } + /* Reconfigure logging in case something changed. */ + _al_configure_logging(); +} + + + +/* + * Can a binary with version a use a library with version b? + * + * Let a = xa.ya.za.* + * Let b = xb.yb.zb.* + * + * When a has the unstable bit, a is compatible with b if xa.ya.za = xb.yb.zb. + * Otherwise, a is compatible with b if xa.ya = xb.yb and zb >= za. + * + * Otherwise a and b are incompatible. + */ +static bool compatible_versions(int a, int b) +{ + int a_unstable = a & _ALLEGRO_UNSTABLE_BIT_SET; + + int a_major = (a & 0x7f000000) >> 24; + int a_sub = (a & 0x00ff0000) >> 16; + int a_wip = (a & 0x0000ff00) >> 8; + + int b_major = (b & 0x7f000000) >> 24; + int b_sub = (b & 0x00ff0000) >> 16; + int b_wip = (b & 0x0000ff00) >> 8; + + if (a_major != b_major) { + return false; + } + if (a_unstable && a_wip != b_wip) { + return false; + } + if (a_sub != b_sub) { + return false; + } + if (a_wip > b_wip) { + return false; + } + return true; +} + + + +/* Function: al_install_system + */ +bool al_install_system(int version, int (*atexit_ptr)(void (*)(void))) +{ + ALLEGRO_SYSTEM bootstrap; + ALLEGRO_SYSTEM *real_system; + int library_version = al_get_allegro_version(); + + if (active_sysdrv) { + return true; + } + + /* Note: We cannot call logging functions yet. + * TODO: Maybe we want to do the check after the "bootstrap" system + * is available at least? + */ + if (!compatible_versions(version, library_version)) + return false; + + _al_tls_init_once(); + _al_reinitialize_tls_values(); + + _al_vector_init(&_al_system_interfaces, sizeof(ALLEGRO_SYSTEM_INTERFACE *)); + + /* Set up a bootstrap system so the calls expecting it don't freak out */ + memset(&bootstrap, 0, sizeof(bootstrap)); + active_sysdrv = &bootstrap; + read_allegro_cfg(); + +#ifdef ALLEGRO_BCC32 + /* This supresses exceptions on floating point divide by zero */ + _control87(MCW_EM, MCW_EM); +#endif + + /* Register builtin system drivers */ + _al_register_system_interfaces(); + + /* Check for a user-defined system driver first */ + real_system = find_system(&_user_system_interfaces); + + /* If a user-defined driver is not found, look for a builtin one */ + if (real_system == NULL) { + real_system = find_system(&_al_system_interfaces); + } + + if (real_system == NULL) { + active_sysdrv = NULL; + return false; + } + + active_sysdrv = real_system; + active_sysdrv->mouse_wheel_precision = 1; + + const char *min_bitmap_size = al_get_config_value( + al_get_system_config(), "graphics", "min_bitmap_size"); + active_sysdrv->min_bitmap_size = min_bitmap_size ? atoi(min_bitmap_size) : 16; + + ALLEGRO_INFO("Allegro version: %s\n", ALLEGRO_VERSION_STR); + + if (strcmp(al_get_app_name(), "") == 0) { + al_set_app_name(NULL); + } + + _al_add_exit_func(shutdown_system_driver, "shutdown_system_driver"); + + _al_dtor_list = _al_init_destructors(); + + _al_init_events(); + + _al_init_iio_table(); + + _al_init_convert_bitmap_list(); + + _al_init_timers(); + +#ifdef ALLEGRO_CFG_SHADER_GLSL + _al_glsl_init_shaders(); +#endif + + if (active_sysdrv->vt->heartbeat_init) + active_sysdrv->vt->heartbeat_init(); + + if (atexit_ptr && atexit_virgin) { +#ifndef ALLEGRO_ANDROID + atexit_ptr(al_uninstall_system); +#endif + atexit_virgin = false; + } + + /* Clear errnos set while searching for config files. */ + al_set_errno(0); + + active_sysdrv->installed = true; + + _al_srand(time(NULL)); + + return true; +} + +/* Function: al_uninstall_system + */ +void al_uninstall_system(void) +{ + /* Note: al_uninstall_system may get called multiple times without an + * al_install_system in between. For example if the user manually + * calls it at the end of the program it is called right again + * because it's installed as an atexit function by al_init. + */ + + _al_run_destructors(_al_dtor_list); + _al_run_exit_funcs(); + _al_shutdown_destructors(_al_dtor_list); + _al_dtor_list = NULL; + +#ifdef ALLEGRO_CFG_SHADER_GLSL + _al_glsl_shutdown_shaders(); +#endif + + _al_shutdown_logging(); + + /* shutdown_system_driver is registered as an exit func so we don't need + * to do any more here. + */ + + ASSERT(active_sysdrv == NULL); +} + + + +/* Function: al_is_system_installed + */ +bool al_is_system_installed(void) +{ + return (active_sysdrv && active_sysdrv->installed) ? true : false; +} + + +/* Hidden function: al_get_system_driver + * This was exported and documented in 5.0rc1 but probably shouldn't have been + * as ALLEGRO_SYSTEM is not documented. + */ +ALLEGRO_SYSTEM *al_get_system_driver(void) +{ + return active_sysdrv; +} + +/* Function: al_get_system_id + */ +ALLEGRO_SYSTEM_ID al_get_system_id(void) +{ + ASSERT(active_sysdrv); + return active_sysdrv->vt->id; +} + +/* Function: al_get_system_config + */ +ALLEGRO_CONFIG *al_get_system_config(void) +{ + if (!sys_config) + sys_config = al_create_config(); + return sys_config; +} + + +/* Function: al_get_standard_path + */ +ALLEGRO_PATH *al_get_standard_path(int id) +{ + ASSERT(active_sysdrv); + ASSERT(active_sysdrv->vt); + ASSERT(active_sysdrv->vt->get_path); + + if (id == ALLEGRO_EXENAME_PATH && active_sysdrv->user_exe_path) + return al_clone_path(active_sysdrv->user_exe_path); + + if (id == ALLEGRO_RESOURCES_PATH && active_sysdrv->user_exe_path) { + ALLEGRO_PATH *exe_dir = al_clone_path(active_sysdrv->user_exe_path); + al_set_path_filename(exe_dir, NULL); + return exe_dir; + } + + if (active_sysdrv->vt->get_path) + return active_sysdrv->vt->get_path(id); + + return NULL; +} + + +/* Function: al_set_exe_name + */ +void al_set_exe_name(char const *path) +{ + ASSERT(active_sysdrv); + if (active_sysdrv->user_exe_path) { + al_destroy_path(active_sysdrv->user_exe_path); + } + active_sysdrv->user_exe_path = al_create_path(path); +} + + +/* Function: al_set_org_name + */ +void al_set_org_name(const char *org_name) +{ + if (!org_name) + org_name = ""; + + _al_sane_strncpy(_al_org_name, org_name, sizeof(_al_org_name)); +} + + +/* Function: al_set_app_name + */ +void al_set_app_name(const char *app_name) +{ + if (app_name) { + _al_sane_strncpy(_al_app_name, app_name, sizeof(_al_app_name)); + } + else { + ALLEGRO_PATH *path; + path = al_get_standard_path(ALLEGRO_EXENAME_PATH); + _al_sane_strncpy(_al_app_name, al_get_path_filename(path), sizeof(_al_app_name)); + al_destroy_path(path); + } +} + + +/* Function: al_get_org_name + */ +const char *al_get_org_name(void) +{ + return _al_org_name; +} + + +/* Function: al_get_app_name + */ +const char *al_get_app_name(void) +{ + return _al_app_name; +} + + +/* Function: al_inhibit_screensaver + */ +bool al_inhibit_screensaver(bool inhibit) +{ + ASSERT(active_sysdrv); + + if (active_sysdrv->vt->inhibit_screensaver) + return active_sysdrv->vt->inhibit_screensaver(inhibit); + else + return false; +} + + +void *_al_open_library(const char *filename) +{ + ASSERT(active_sysdrv); + + if (active_sysdrv->vt->open_library) + return active_sysdrv->vt->open_library(filename); + else + return NULL; +} + + +void *_al_import_symbol(void *library, const char *symbol) +{ + ASSERT(active_sysdrv); + + if (active_sysdrv->vt->import_symbol) + return active_sysdrv->vt->import_symbol(library, symbol); + else + return NULL; +} + + +void _al_close_library(void *library) +{ + ASSERT(active_sysdrv); + + if (active_sysdrv->vt->close_library) + active_sysdrv->vt->close_library(library); +} + + +/* Function: al_get_time + */ +double al_get_time(void) +{ + ASSERT(active_sysdrv); + + if (active_sysdrv->vt->get_time) + return active_sysdrv->vt->get_time(); + return 0.0; +} + + +/* Function: al_rest + */ +void al_rest(double seconds) +{ + ASSERT(active_sysdrv); + + if (active_sysdrv->vt->rest) + active_sysdrv->vt->rest(seconds); +} + + +/* Function: al_init_timeout + */ +void al_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds) +{ + ASSERT(active_sysdrv); + + if (active_sysdrv->vt->init_timeout) + active_sysdrv->vt->init_timeout(timeout, seconds); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/threads.c b/allegro/src/threads.c new file mode 100644 index 00000000..3a770613 --- /dev/null +++ b/allegro/src/threads.c @@ -0,0 +1,417 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Public threads interface. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/internal/aintern_system.h" + + + +typedef enum THREAD_STATE { + THREAD_STATE_CREATED, /* -> starting or -> joining */ + THREAD_STATE_STARTING, /* -> started */ + THREAD_STATE_STARTED, /* -> joining */ + THREAD_STATE_JOINING, /* -> joined */ + THREAD_STATE_JOINED, /* -> destroyed */ + THREAD_STATE_DESTROYED, + THREAD_STATE_DETACHED +} THREAD_STATE; + + +struct ALLEGRO_THREAD { + _AL_THREAD thread; + _AL_MUTEX mutex; + _AL_COND cond; + THREAD_STATE thread_state; + void *proc; + void *arg; + void *retval; +}; + + +struct ALLEGRO_MUTEX { + _AL_MUTEX mutex; +}; + + +struct ALLEGRO_COND { + _AL_COND cond; +}; + + +static void thread_func_trampoline(_AL_THREAD *inner, void *_outer) +{ + ALLEGRO_THREAD *outer = (ALLEGRO_THREAD *) _outer; + ALLEGRO_SYSTEM *system = al_get_system_driver(); + (void)inner; + + if (system && system->vt && system->vt->thread_init) { + system->vt->thread_init(outer); + } + + /* Wait to start the actual user thread function. The thread could also be + * destroyed before ever running the user function. + */ + _al_mutex_lock(&outer->mutex); + while (outer->thread_state == THREAD_STATE_CREATED) { + _al_cond_wait(&outer->cond, &outer->mutex); + } + _al_mutex_unlock(&outer->mutex); + + if (outer->thread_state == THREAD_STATE_STARTING) { + outer->thread_state = THREAD_STATE_STARTED; + outer->retval = + ((void *(*)(ALLEGRO_THREAD *, void *))outer->proc)(outer, outer->arg); + } + + if (system && system->vt && system->vt->thread_exit) { + system->vt->thread_exit(outer); + } +} + + +static void detached_thread_func_trampoline(_AL_THREAD *inner, void *_outer) +{ + ALLEGRO_THREAD *outer = (ALLEGRO_THREAD *) _outer; + (void)inner; + + ((void *(*)(void *))outer->proc)(outer->arg); + al_free(outer); +} + + +static ALLEGRO_THREAD *create_thread(void) +{ + ALLEGRO_THREAD *outer; + + outer = al_malloc(sizeof(*outer)); + if (!outer) { + return NULL; + } + _AL_MARK_MUTEX_UNINITED(outer->mutex); /* required */ + outer->retval = NULL; + return outer; +} + + +/* Function: al_create_thread + */ +ALLEGRO_THREAD *al_create_thread( + void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg) +{ + ALLEGRO_THREAD *outer = create_thread(); + outer->thread_state = THREAD_STATE_CREATED; + _al_mutex_init(&outer->mutex); + _al_cond_init(&outer->cond); + outer->arg = arg; + outer->proc = proc; + _al_thread_create(&outer->thread, thread_func_trampoline, outer); + /* XXX _al_thread_create should return an error code */ + return outer; +} + +/* Function: al_create_thread_with_stacksize + */ +ALLEGRO_THREAD *al_create_thread_with_stacksize( + void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg, size_t stacksize) +{ + ALLEGRO_THREAD *outer = create_thread(); + outer->thread_state = THREAD_STATE_CREATED; + _al_mutex_init(&outer->mutex); + _al_cond_init(&outer->cond); + outer->arg = arg; + outer->proc = proc; + _al_thread_create_with_stacksize(&outer->thread, thread_func_trampoline, outer, stacksize); + /* XXX _al_thread_create should return an error code */ + return outer; +} + +/* Function: al_run_detached_thread + */ +void al_run_detached_thread(void *(*proc)(void *arg), void *arg) +{ + ALLEGRO_THREAD *outer = create_thread(); + outer->thread_state = THREAD_STATE_DETACHED; + outer->arg = arg; + outer->proc = proc; + _al_thread_create(&outer->thread, detached_thread_func_trampoline, outer); + _al_thread_detach(&outer->thread); +} + + +/* Function: al_start_thread + */ +void al_start_thread(ALLEGRO_THREAD *thread) +{ + ASSERT(thread); + + switch (thread->thread_state) { + case THREAD_STATE_CREATED: + _al_mutex_lock(&thread->mutex); + thread->thread_state = THREAD_STATE_STARTING; + _al_cond_broadcast(&thread->cond); + _al_mutex_unlock(&thread->mutex); + break; + case THREAD_STATE_STARTING: + break; + case THREAD_STATE_STARTED: + break; + /* invalid cases */ + case THREAD_STATE_JOINING: + ASSERT(thread->thread_state != THREAD_STATE_JOINING); + break; + case THREAD_STATE_JOINED: + ASSERT(thread->thread_state != THREAD_STATE_JOINED); + break; + case THREAD_STATE_DESTROYED: + ASSERT(thread->thread_state != THREAD_STATE_DESTROYED); + break; + case THREAD_STATE_DETACHED: + ASSERT(thread->thread_state != THREAD_STATE_DETACHED); + break; + } +} + + +/* Function: al_join_thread + */ +void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value) +{ + ASSERT(thread); + + /* If al_join_thread() is called soon after al_start_thread(), the thread + * function may not yet have noticed the STARTING state and executed the + * user's thread function. Hence we must wait until the thread enters the + * STARTED state. + */ + while (thread->thread_state == THREAD_STATE_STARTING) { + al_rest(0.001); + } + + switch (thread->thread_state) { + case THREAD_STATE_CREATED: /* fall through */ + case THREAD_STATE_STARTED: + _al_mutex_lock(&thread->mutex); + thread->thread_state = THREAD_STATE_JOINING; + _al_cond_broadcast(&thread->cond); + _al_mutex_unlock(&thread->mutex); + _al_cond_destroy(&thread->cond); + _al_mutex_destroy(&thread->mutex); + _al_thread_join(&thread->thread); + thread->thread_state = THREAD_STATE_JOINED; + break; + case THREAD_STATE_STARTING: + ASSERT(thread->thread_state != THREAD_STATE_STARTING); + break; + case THREAD_STATE_JOINING: + ASSERT(thread->thread_state != THREAD_STATE_JOINING); + break; + case THREAD_STATE_JOINED: + ASSERT(thread->thread_state != THREAD_STATE_JOINED); + break; + case THREAD_STATE_DESTROYED: + ASSERT(thread->thread_state != THREAD_STATE_DESTROYED); + break; + case THREAD_STATE_DETACHED: + ASSERT(thread->thread_state != THREAD_STATE_DETACHED); + break; + } + + if (ret_value) { + *ret_value = thread->retval; + } +} + + +/* Function: al_set_thread_should_stop + */ +void al_set_thread_should_stop(ALLEGRO_THREAD *thread) +{ + ASSERT(thread); + _al_thread_set_should_stop(&thread->thread); +} + + +/* Function: al_get_thread_should_stop + */ +bool al_get_thread_should_stop(ALLEGRO_THREAD *thread) +{ + ASSERT(thread); + return _al_get_thread_should_stop(&thread->thread); +} + + +/* Function: al_destroy_thread + */ +void al_destroy_thread(ALLEGRO_THREAD *thread) +{ + if (!thread) { + return; + } + + /* Join if required. */ + switch (thread->thread_state) { + case THREAD_STATE_CREATED: /* fall through */ + case THREAD_STATE_STARTING: /* fall through */ + case THREAD_STATE_STARTED: + al_join_thread(thread, NULL); + break; + case THREAD_STATE_JOINING: + ASSERT(thread->thread_state != THREAD_STATE_JOINING); + break; + case THREAD_STATE_JOINED: + break; + case THREAD_STATE_DESTROYED: + ASSERT(thread->thread_state != THREAD_STATE_DESTROYED); + break; + case THREAD_STATE_DETACHED: + ASSERT(thread->thread_state != THREAD_STATE_DETACHED); + break; + } + + /* May help debugging. */ + thread->thread_state = THREAD_STATE_DESTROYED; + al_free(thread); +} + + +/* Function: al_create_mutex + */ +ALLEGRO_MUTEX *al_create_mutex(void) +{ + ALLEGRO_MUTEX *mutex = al_malloc(sizeof(*mutex)); + if (mutex) { + _AL_MARK_MUTEX_UNINITED(mutex->mutex); + _al_mutex_init(&mutex->mutex); + } + return mutex; +} + + +/* Function: al_create_mutex_recursive + */ +ALLEGRO_MUTEX *al_create_mutex_recursive(void) +{ + ALLEGRO_MUTEX *mutex = al_malloc(sizeof(*mutex)); + if (mutex) { + _AL_MARK_MUTEX_UNINITED(mutex->mutex); + _al_mutex_init_recursive(&mutex->mutex); + } + return mutex; +} + + +/* Function: al_lock_mutex + */ +void al_lock_mutex(ALLEGRO_MUTEX *mutex) +{ + ASSERT(mutex); + _al_mutex_lock(&mutex->mutex); +} + + + +/* Function: al_unlock_mutex + */ +void al_unlock_mutex(ALLEGRO_MUTEX *mutex) +{ + ASSERT(mutex); + _al_mutex_unlock(&mutex->mutex); +} + + +/* Function: al_destroy_mutex + */ +void al_destroy_mutex(ALLEGRO_MUTEX *mutex) +{ + if (mutex) { + _al_mutex_destroy(&mutex->mutex); + al_free(mutex); + } +} + + +/* Function: al_create_cond + */ +ALLEGRO_COND *al_create_cond(void) +{ + ALLEGRO_COND *cond = al_malloc(sizeof(*cond)); + if (cond) { + _al_cond_init(&cond->cond); + } + return cond; +} + + +/* Function: al_destroy_cond + */ +void al_destroy_cond(ALLEGRO_COND *cond) +{ + if (cond) { + _al_cond_destroy(&cond->cond); + al_free(cond); + } +} + + +/* Function: al_wait_cond + */ +void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex) +{ + ASSERT(cond); + ASSERT(mutex); + + _al_cond_wait(&cond->cond, &mutex->mutex); +} + + +/* Function: al_wait_cond_until + */ +int al_wait_cond_until(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex, + const ALLEGRO_TIMEOUT *timeout) +{ + ASSERT(cond); + ASSERT(mutex); + ASSERT(timeout); + + return _al_cond_timedwait(&cond->cond, &mutex->mutex, timeout); +} + + +/* Function: al_broadcast_cond + */ +void al_broadcast_cond(ALLEGRO_COND *cond) +{ + ASSERT(cond); + + _al_cond_broadcast(&cond->cond); +} + + +/* Function: al_signal_cond + */ +void al_signal_cond(ALLEGRO_COND *cond) +{ + ASSERT(cond); + + _al_cond_signal(&cond->cond); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/timernu.c b/allegro/src/timernu.c new file mode 100644 index 00000000..27f565c6 --- /dev/null +++ b/allegro/src/timernu.c @@ -0,0 +1,447 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New timer API. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + + +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_dtor.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_timer.h" + +#ifndef ALLEGRO_MSVC +#ifndef ALLEGRO_BCC32 + #include +#endif +#endif + + +/* forward declarations */ +static void timer_handle_tick(ALLEGRO_TIMER *timer); + + +struct ALLEGRO_TIMER +{ + ALLEGRO_EVENT_SOURCE es; + bool started; + double speed_secs; + int64_t count; + double counter; /* counts down to zero=blastoff */ + _AL_LIST_ITEM *dtor_item; +}; + + + +/* + * The timer thread that runs in the background to drive the timers. + */ + +static ALLEGRO_MUTEX *timers_mutex; +static _AL_VECTOR active_timers = _AL_VECTOR_INITIALIZER(ALLEGRO_TIMER *); +static _AL_THREAD * volatile timer_thread = NULL; +static ALLEGRO_COND *timer_cond = NULL; +static bool destroy_thread = false; + + +/* timer_thread_proc: [timer thread] + * The timer thread procedure itself. + */ +static void timer_thread_proc(_AL_THREAD *self, void *unused) +{ +#if 0 + /* Block all signals. */ + /* This was needed for some reason in v4, but I can't remember why, + * and it might not be relevant now. It has a tendency to create + * zombie processes if the program is aborted abnormally, so I'm + * taking it out for now. + */ + { + sigset_t mask; + sigfillset(&mask); + pthread_sigmask(SIG_BLOCK, &mask, NULL); + } +#endif + +#ifdef ALLEGRO_QNX + /* thread priority adjustment for QNX: + * The timer thread is set to the highest relative priority. + * (see the comment in src/qnx/qsystem.c about the scheduling policy) + */ + { + struct sched_param sparam; + int spolicy; + + if (pthread_getschedparam(pthread_self(), &spolicy, &sparam) == EOK) { + sparam.sched_priority += 4; + pthread_setschedparam(pthread_self(), spolicy, &sparam); + } + } +#endif + + double old_time = al_get_time(); + double new_time; + double interval = 0.032768; + + while (!_al_get_thread_should_stop(self)) { + al_lock_mutex(timers_mutex); + while (_al_vector_size(&active_timers) == 0 && !destroy_thread) { + al_wait_cond(timer_cond, timers_mutex); + old_time = al_get_time() - interval; + } + al_unlock_mutex(timers_mutex); + + al_rest(interval); + + al_lock_mutex(timers_mutex); + { + /* Calculate actual time elapsed. */ + new_time = al_get_time(); + interval = new_time - old_time; + old_time = new_time; + + /* Handle a tick. */ + interval = _al_timer_thread_handle_tick(interval); + } + al_unlock_mutex(timers_mutex); + } + + (void)unused; +} + + + +/* timer_thread_handle_tick: [timer thread] + * Call handle_tick() method of every timer in active_timers, and + * returns the duration that the timer thread should try to sleep + * next time. + */ +double _al_timer_thread_handle_tick(double interval) +{ + double new_delay = 0.032768; + unsigned int i; + + for (i = 0; i < _al_vector_size(&active_timers); i++) { + ALLEGRO_TIMER **slot = _al_vector_ref(&active_timers, i); + ALLEGRO_TIMER *timer = *slot; + + timer->counter -= interval; + + while (timer->counter <= 0) { + timer_handle_tick(timer); + timer->counter += timer->speed_secs; + } + + if ((timer->counter > 0) && (timer->counter < new_delay)) + new_delay = timer->counter; + } + + return new_delay; +} + + + +static void shutdown_timers(void) +{ + ASSERT(_al_vector_size(&active_timers) == 0); + + _al_vector_free(&active_timers); + + if (timer_thread != NULL) { + destroy_thread = true; + al_lock_mutex(timers_mutex); + al_signal_cond(timer_cond); + al_unlock_mutex(timers_mutex); + _al_thread_join(timer_thread); + } + + al_free(timer_thread); + + timer_thread = NULL; + + al_destroy_mutex(timers_mutex); + + al_destroy_cond(timer_cond); +} + + + +// logic common to al_start_timer and al_resume_timer +// al_start_timer : passes reset_counter = true to start from the beginning +// al_resume_timer: passes reset_counter = false to preserve the previous time +static void enable_timer(ALLEGRO_TIMER *timer, bool reset_counter) +{ + ASSERT(timer); + { + if (timer->started) + return; + + al_lock_mutex(timers_mutex); + { + ALLEGRO_TIMER **slot; + + timer->started = true; + + if (reset_counter) + timer->counter = timer->speed_secs; + + slot = _al_vector_alloc_back(&active_timers); + *slot = timer; + + al_signal_cond(timer_cond); + } + al_unlock_mutex(timers_mutex); + + if (timer_thread == NULL) { + destroy_thread = false; + timer_thread = al_malloc(sizeof(_AL_THREAD)); + _al_thread_create(timer_thread, timer_thread_proc, NULL); + } + } +} + + + +void _al_init_timers(void) +{ + timers_mutex = al_create_mutex(); + timer_cond = al_create_cond(); + _al_add_exit_func(shutdown_timers, "shutdown_timers"); +} + + + +int _al_get_active_timers_count(void) +{ + return _al_vector_size(&active_timers); +} + + +/* + * Timer objects + */ + + +/* Function: al_create_timer + */ +ALLEGRO_TIMER *al_create_timer(double speed_secs) +{ + ASSERT(speed_secs > 0); + { + ALLEGRO_TIMER *timer = al_malloc(sizeof *timer); + + ASSERT(timer); + + if (timer) { + _al_event_source_init(&timer->es); + timer->started = false; + timer->count = 0; + timer->speed_secs = speed_secs; + timer->counter = 0; + + timer->dtor_item = _al_register_destructor(_al_dtor_list, "timer", timer, + (void (*)(void *)) al_destroy_timer); + } + + return timer; + } +} + + + +/* Function: al_destroy_timer + */ +void al_destroy_timer(ALLEGRO_TIMER *timer) +{ + if (timer) { + al_stop_timer(timer); + + _al_unregister_destructor(_al_dtor_list, timer->dtor_item); + + _al_event_source_free(&timer->es); + al_free(timer); + } +} + + + +/* Function: al_start_timer + */ +void al_start_timer(ALLEGRO_TIMER *timer) +{ + enable_timer(timer, true); // true to reset the counter +} + + + +/* Function: al_resume_timer + */ +void al_resume_timer(ALLEGRO_TIMER *timer) +{ + enable_timer(timer, false); // false to preserve the counter +} + + + +/* Function: al_stop_timer + */ +void al_stop_timer(ALLEGRO_TIMER *timer) +{ + ASSERT(timer); + { + if (!timer->started) + return; + + al_lock_mutex(timers_mutex); + { + _al_vector_find_and_delete(&active_timers, &timer); + timer->started = false; + } + al_unlock_mutex(timers_mutex); + } +} + + + +/* Function: al_get_timer_started + */ +bool al_get_timer_started(const ALLEGRO_TIMER *timer) +{ + ASSERT(timer); + + return timer->started; +} + + + +/* Function: al_get_timer_speed + */ +double al_get_timer_speed(const ALLEGRO_TIMER *timer) +{ + ASSERT(timer); + + return timer->speed_secs; +} + + + +/* Function: al_set_timer_speed + */ +void al_set_timer_speed(ALLEGRO_TIMER *timer, double new_speed_secs) +{ + ASSERT(timer); + ASSERT(new_speed_secs > 0); + + al_lock_mutex(timers_mutex); + { + if (timer->started) { + timer->counter -= timer->speed_secs; + timer->counter += new_speed_secs; + } + + timer->speed_secs = new_speed_secs; + } + al_unlock_mutex(timers_mutex); +} + + + +/* Function: al_get_timer_count + */ +int64_t al_get_timer_count(const ALLEGRO_TIMER *timer) +{ + ASSERT(timer); + + return timer->count; +} + + + +/* Function: al_set_timer_count + */ +void al_set_timer_count(ALLEGRO_TIMER *timer, int64_t new_count) +{ + ASSERT(timer); + + al_lock_mutex(timers_mutex); + { + timer->count = new_count; + } + al_unlock_mutex(timers_mutex); +} + + + +/* Function: al_add_timer_count + */ +void al_add_timer_count(ALLEGRO_TIMER *timer, int64_t diff) +{ + ASSERT(timer); + + al_lock_mutex(timers_mutex); + { + timer->count += diff; + } + al_unlock_mutex(timers_mutex); +} + + +/* timer_handle_tick: [timer thread] + * Handle a single tick. + */ +static void timer_handle_tick(ALLEGRO_TIMER *timer) +{ + /* Lock out event source helper functions (e.g. the release hook + * could be invoked simultaneously with this function). + */ + _al_event_source_lock(&timer->es); + { + /* Update the count. */ + timer->count++; + + /* Generate an event, maybe. */ + if (_al_event_source_needs_to_generate_event(&timer->es)) { + ALLEGRO_EVENT event; + event.timer.type = ALLEGRO_EVENT_TIMER; + event.timer.timestamp = al_get_time(); + event.timer.count = timer->count; + event.timer.error = -timer->counter; + _al_event_source_emit_event(&timer->es, &event); + } + } + _al_event_source_unlock(&timer->es); +} + + + +/* Function: al_get_timer_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_timer_event_source(ALLEGRO_TIMER *timer) +{ + return &timer->es; +} + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/tls.c b/allegro/src/tls.c new file mode 100644 index 00000000..7372812a --- /dev/null +++ b/allegro/src/tls.c @@ -0,0 +1,976 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread local storage. + * + * By Trent Gamblin. + * + */ + +/* FIXME: + * + * There are several ways to get thread local storage: + * + * 1. pthreads. + * 2. __thread keyword in gcc. + * 3. __declspec(thread) in MSVC. + * 4. TLS API under Windows. + * + * Since pthreads is available from the system everywhere except in + * Windows, this is the only case which is problematic. It appears + * that except for old mingw versions (before gcc 4.2) we can simply + * use __thread, and for MSVC we can always use __declspec(thread): + * + * However there also is a WANT_TLS configuration variable which is on + * by default and forces use of the TLS API instead. At the same time, + * the implementation using the TLS API in this file does not work + * with static linking. Someone should either completely remove + * WANT_TLS, or fix the static linking case... + */ + +#include +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_file.h" +#include "allegro5/internal/aintern_fshook.h" +#include "allegro5/internal/aintern_shader.h" +#include "allegro5/internal/aintern_tls.h" + +#ifdef ALLEGRO_ANDROID +#include "allegro5/internal/aintern_android.h" +#endif + +#if defined(ALLEGRO_MINGW32) && !defined(ALLEGRO_CFG_DLL_TLS) + /* + * MinGW < 4.2.1 doesn't have builtin thread local storage, so we + * must use the Windows API. + */ + #if __GNUC__ < 4 + #define ALLEGRO_CFG_DLL_TLS + #elif __GNUC__ == 4 && __GNUC_MINOR__ < 2 + #define ALLEGRO_CFG_DLL_TLS + #elif __GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ < 1 + #define ALLEGRO_CFG_DLL_TLS + #endif +#endif + + +/* Thread local storage for various per-thread state. */ +typedef struct thread_local_state { + /* New display parameters */ + int new_display_flags; + int new_display_refresh_rate; + int new_display_adapter; + int new_window_x; + int new_window_y; + int new_bitmap_depth; + int new_bitmap_samples; + ALLEGRO_EXTRA_DISPLAY_SETTINGS new_display_settings; + + /* Current display */ + ALLEGRO_DISPLAY *current_display; + + /* Target bitmap */ + ALLEGRO_BITMAP *target_bitmap; + + /* Blender */ + ALLEGRO_BLENDER current_blender; + + /* Bitmap parameters */ + int new_bitmap_format; + int new_bitmap_flags; + + /* Files */ + const ALLEGRO_FILE_INTERFACE *new_file_interface; + const ALLEGRO_FS_INTERFACE *fs_interface; + + /* Error code */ + int allegro_errno; + + /* Title to use for a new window/display. + * This is a static buffer for API reasons. + */ + char new_window_title[ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE + 1]; + +#ifdef ALLEGRO_ANDROID + JNIEnv *jnienv; +#endif + + /* Destructor ownership count */ + int dtor_owner_count; +} thread_local_state; + + +typedef struct INTERNAL_STATE { + thread_local_state tls; + ALLEGRO_BLENDER stored_blender; + ALLEGRO_TRANSFORM stored_transform; + ALLEGRO_TRANSFORM stored_projection_transform; + int flags; +} INTERNAL_STATE; + +ALLEGRO_STATIC_ASSERT(tls, sizeof(ALLEGRO_STATE) > sizeof(INTERNAL_STATE)); + + +static void initialize_blender(ALLEGRO_BLENDER *b) +{ + b->blend_op = ALLEGRO_ADD; + b->blend_source = ALLEGRO_ONE, + b->blend_dest = ALLEGRO_INVERSE_ALPHA; + b->blend_alpha_op = ALLEGRO_ADD; + b->blend_alpha_source = ALLEGRO_ONE; + b->blend_alpha_dest = ALLEGRO_INVERSE_ALPHA; + b->blend_color = al_map_rgba_f(1.0f, 1.0f, 1.0f, 1.0f); +} + + +static void initialize_tls_values(thread_local_state *tls) +{ + memset(tls, 0, sizeof *tls); + + tls->new_display_adapter = ALLEGRO_DEFAULT_DISPLAY_ADAPTER; + tls->new_window_x = INT_MAX; + tls->new_window_y = INT_MAX; + + initialize_blender(&tls->current_blender); + tls->new_bitmap_flags = ALLEGRO_CONVERT_BITMAP; + tls->new_bitmap_format = ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA; + tls->new_file_interface = &_al_file_interface_stdio; + tls->fs_interface = &_al_fs_interface_stdio; + memset(tls->new_window_title, 0, ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE + 1); + + _al_fill_display_settings(&tls->new_display_settings); +} + +// FIXME: The TLS implementation below only works for dynamic linking +// right now - instead of using DllMain we should simply initialize +// on first request. +#ifdef ALLEGRO_STATICLINK + #undef ALLEGRO_CFG_DLL_TLS +#endif + +#if defined(ALLEGRO_CFG_DLL_TLS) + #include "tls_dll.inc" +#elif defined(ALLEGRO_MACOSX) || defined(ALLEGRO_IPHONE) || defined(ALLEGRO_ANDROID) || defined(ALLEGRO_RASPBERRYPI) + #include "tls_pthread.inc" +#else + #include "tls_native.inc" +#endif + + + +void _al_reinitialize_tls_values(void) +{ + thread_local_state *tls; + if ((tls = tls_get()) == NULL) + return; + initialize_tls_values(tls); +} + + + +void _al_set_new_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings) +{ + thread_local_state *tls; + if ((tls = tls_get()) == NULL) + return; + memmove(&tls->new_display_settings, settings, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); +} + + + +ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_get_new_display_settings(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return 0; + return &tls->new_display_settings; +} + + +/* Function: al_set_new_window_title + */ +void al_set_new_window_title(const char *title) +{ + thread_local_state *tls; + size_t size; + + if ((tls = tls_get()) == NULL) + return; + + size = strlen(title); + + if (size > ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE) { + size = ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE; + } + + _al_sane_strncpy(tls->new_window_title, title, size + 1); +} + + + +/* Function: al_get_new_window_title + */ +const char *al_get_new_window_title(void) +{ + thread_local_state *tls; + + /* Return app name in case of error or if not set before. */ + if ((tls = tls_get()) == NULL) + return al_get_app_name(); + + if (strlen(tls->new_window_title) < 1) + return al_get_app_name(); + + + return (const char *)tls->new_window_title; +} + + + + +/* Function: al_set_new_display_flags + */ +void al_set_new_display_flags(int flags) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + tls->new_display_flags = flags; +} + + + +/* Function: al_get_new_display_flags + */ +int al_get_new_display_flags(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return 0; + return tls->new_display_flags; +} + + + +/* Function: al_set_new_display_refresh_rate + */ +void al_set_new_display_refresh_rate(int refresh_rate) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + tls->new_display_refresh_rate = refresh_rate; +} + + + +/* Function: al_get_new_display_refresh_rate + */ +int al_get_new_display_refresh_rate(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return 0; + return tls->new_display_refresh_rate; +} + + + +/* Function: al_set_new_display_adapter + */ +void al_set_new_display_adapter(int adapter) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + + if (adapter < 0) { + tls->new_display_adapter = ALLEGRO_DEFAULT_DISPLAY_ADAPTER; + } + tls->new_display_adapter = adapter; +} + + + +/* Function: al_get_new_display_adapter + */ +int al_get_new_display_adapter(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return ALLEGRO_DEFAULT_DISPLAY_ADAPTER; + return tls->new_display_adapter; +} + + + +/* Function: al_set_new_window_position + */ +void al_set_new_window_position(int x, int y) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + tls->new_window_x = x; + tls->new_window_y = y; +} + + +/* Function: al_get_new_window_position + */ +void al_get_new_window_position(int *x, int *y) +{ + thread_local_state *tls; + int new_window_x = INT_MAX; + int new_window_y = INT_MAX; + + if ((tls = tls_get()) != NULL) { + new_window_x = tls->new_window_x; + new_window_y = tls->new_window_y; + } + + if (x) + *x = new_window_x; + if (y) + *y = new_window_y; +} + + + +/* Make the given display current, without changing the target bitmap. + * This is used internally to change the current display transiently. + */ +bool _al_set_current_display_only(ALLEGRO_DISPLAY *display) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return false; + + if (tls->current_display && + tls->current_display->vt && + tls->current_display->vt->unset_current_display) { + tls->current_display->vt->unset_current_display(tls->current_display); + tls->current_display = NULL; + } + + if (display && + display->vt && + display->vt->set_current_display) { + if (!display->vt->set_current_display(display)) + return false; + } + + tls->current_display = display; + return true; +} + + + +/* Function: al_get_current_display + */ +ALLEGRO_DISPLAY *al_get_current_display(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return NULL; + return tls->current_display; +} + + + +/* Function: al_set_target_bitmap + */ +void al_set_target_bitmap(ALLEGRO_BITMAP *bitmap) +{ + thread_local_state *tls; + ALLEGRO_DISPLAY *old_display; + ALLEGRO_DISPLAY *new_display; + ALLEGRO_SHADER *old_shader; + ALLEGRO_SHADER *new_shader; + bool same_shader; + int bitmap_flags = bitmap ? al_get_bitmap_flags(bitmap) : 0; + + ASSERT(!al_is_bitmap_drawing_held()); + + if (bitmap) { + if (bitmap->parent) { + bitmap->parent->dirty = true; + } + else { + bitmap->dirty = true; + } + } + + if ((tls = tls_get()) == NULL) + return; + + old_display = tls->current_display; + + if (tls->target_bitmap) + old_shader = tls->target_bitmap->shader; + else + old_shader = NULL; + + if (bitmap == NULL) { + /* Explicitly releasing the current rendering context. */ + new_display = NULL; + new_shader = NULL; + } + else if (bitmap_flags & ALLEGRO_MEMORY_BITMAP) { + /* Setting a memory bitmap doesn't change the rendering context. */ + new_display = old_display; + new_shader = NULL; + } + else { + new_display = _al_get_bitmap_display(bitmap); + new_shader = bitmap->shader; + } + + same_shader = (old_shader == new_shader && old_display == new_display); + + /* Unset the old shader if necessary. */ + if (old_shader && !same_shader) { + old_shader->vt->unuse_shader(old_shader, old_display); + } + + /* Change the rendering context if necessary. */ + if (old_display != new_display) { + if (old_display && + old_display->vt && + old_display->vt->unset_current_display) { + old_display->vt->unset_current_display(old_display); + } + + tls->current_display = new_display; + + if (new_display && + new_display->vt && + new_display->vt->set_current_display) { + new_display->vt->set_current_display(new_display); + } + } + + /* Change the target bitmap itself. */ + tls->target_bitmap = bitmap; + + if (bitmap && + !(bitmap_flags & ALLEGRO_MEMORY_BITMAP) && + new_display && + new_display->vt && + new_display->vt->set_target_bitmap) + { + new_display->vt->set_target_bitmap(new_display, bitmap); + + /* Set the new shader if necessary. This should done before the + * update_transformation call, which will also update the shader's + * al_projview_matrix variable. + */ + if (!same_shader || !new_shader) { + al_use_shader(new_shader); + } + + new_display->vt->update_transformation(new_display, bitmap); + } +} + + + +/* Function: al_set_target_backbuffer + */ +void al_set_target_backbuffer(ALLEGRO_DISPLAY *display) +{ + al_set_target_bitmap(al_get_backbuffer(display)); +} + + + +/* Function: al_get_target_bitmap + */ +ALLEGRO_BITMAP *al_get_target_bitmap(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return 0; + return tls->target_bitmap; +} + + + +/* Function: al_set_blender + */ +void al_set_blender(int op, int src, int dst) +{ + al_set_separate_blender(op, src, dst, op, src, dst); +} + + + +/* Function: al_set_blend_color +*/ +void al_set_blend_color(ALLEGRO_COLOR color) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + + tls->current_blender.blend_color = color; +} + + +/* Function: al_set_separate_blender + */ +void al_set_separate_blender(int op, int src, int dst, + int alpha_op, int alpha_src, int alpha_dst) +{ + thread_local_state *tls; + ALLEGRO_BLENDER *b; + + ASSERT(op >= 0 && op < ALLEGRO_NUM_BLEND_OPERATIONS); + ASSERT(src >= 0 && src < ALLEGRO_NUM_BLEND_MODES); + ASSERT(dst >= 0 && src < ALLEGRO_NUM_BLEND_MODES); + ASSERT(alpha_op >= 0 && alpha_op < ALLEGRO_NUM_BLEND_OPERATIONS); + ASSERT(alpha_src >= 0 && alpha_src < ALLEGRO_NUM_BLEND_MODES); + ASSERT(alpha_dst >= 0 && alpha_dst < ALLEGRO_NUM_BLEND_MODES); + + if ((tls = tls_get()) == NULL) + return; + + b = &tls->current_blender; + + b->blend_op = op; + b->blend_source = src; + b->blend_dest = dst; + b->blend_alpha_op = alpha_op; + b->blend_alpha_source = alpha_src; + b->blend_alpha_dest = alpha_dst; +} + + + +/* Function: al_get_blender + */ +void al_get_blender(int *op, int *src, int *dst) +{ + al_get_separate_blender(op, src, dst, NULL, NULL, NULL); +} + + + +/* Function: al_get_blend_color +*/ +ALLEGRO_COLOR al_get_blend_color(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return al_map_rgba(255, 255, 255, 255); + + return tls->current_blender.blend_color; +} + + +/* Function: al_get_separate_blender + */ +void al_get_separate_blender(int *op, int *src, int *dst, + int *alpha_op, int *alpha_src, int *alpha_dst) +{ + thread_local_state *tls; + ALLEGRO_BLENDER *b; + + if ((tls = tls_get()) == NULL) + return; + + b = &tls->current_blender; + + if (op) + *op = b->blend_op; + + if (src) + *src = b->blend_source; + + if (dst) + *dst = b->blend_dest; + + if (alpha_op) + *alpha_op = b->blend_alpha_op; + + if (alpha_src) + *alpha_src = b->blend_alpha_source; + + if (alpha_dst) + *alpha_dst = b->blend_alpha_dest; +} + + + +/* Function: al_set_new_bitmap_format + */ +void al_set_new_bitmap_format(int format) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + tls->new_bitmap_format = format; +} + + + +/* Function: al_set_new_bitmap_flags + */ +void al_set_new_bitmap_flags(int flags) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + + tls->new_bitmap_flags = flags; +} + + + +/* Function: al_add_new_bitmap_flag + */ +void al_add_new_bitmap_flag(int flag) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + tls->new_bitmap_flags |= flag; +} + + + +/* Function: al_get_new_bitmap_format + */ +int al_get_new_bitmap_format(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return 0; + return tls->new_bitmap_format; +} + + + +/* Function: al_get_new_bitmap_flags + */ +int al_get_new_bitmap_flags(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return 0; + return tls->new_bitmap_flags; +} + + + +/* Function: al_store_state + */ +void al_store_state(ALLEGRO_STATE *state, int flags) +{ + thread_local_state *tls; + INTERNAL_STATE *stored; + + if ((tls = tls_get()) == NULL) + return; + + stored = (void *)state; + stored->flags = flags; + +#define _STORE(x) (stored->tls.x = tls->x) + + if (flags & ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS) { + _STORE(new_display_flags); + _STORE(new_display_refresh_rate); + _STORE(new_display_adapter); + _STORE(new_window_x); + _STORE(new_window_y); + _STORE(new_display_settings); + _al_sane_strncpy(stored->tls.new_window_title, tls->new_window_title, + strlen(tls->new_window_title)); + } + + if (flags & ALLEGRO_STATE_NEW_BITMAP_PARAMETERS) { + _STORE(new_bitmap_format); + _STORE(new_bitmap_flags); + } + + if (flags & ALLEGRO_STATE_DISPLAY) { + _STORE(current_display); + } + + if (flags & ALLEGRO_STATE_TARGET_BITMAP) { + _STORE(target_bitmap); + } + + if (flags & ALLEGRO_STATE_BLENDER) { + stored->stored_blender = tls->current_blender; + } + + if (flags & ALLEGRO_STATE_NEW_FILE_INTERFACE) { + _STORE(new_file_interface); + _STORE(fs_interface); + } + + if (flags & ALLEGRO_STATE_TRANSFORM) { + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + if (!target) + al_identity_transform(&stored->stored_transform); + else + stored->stored_transform = target->transform; + } + + if (flags & ALLEGRO_STATE_PROJECTION_TRANSFORM) { + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + if (target) { + stored->stored_projection_transform = target->proj_transform; + } + } + +#undef _STORE +} + + + +/* Function: al_restore_state + */ +void al_restore_state(ALLEGRO_STATE const *state) +{ + thread_local_state *tls; + INTERNAL_STATE *stored; + int flags; + + if ((tls = tls_get()) == NULL) + return; + + stored = (void *)state; + flags = stored->flags; + +#define _RESTORE(x) (tls->x = stored->tls.x) + + if (flags & ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS) { + _RESTORE(new_display_flags); + _RESTORE(new_display_refresh_rate); + _RESTORE(new_display_adapter); + _RESTORE(new_window_x); + _RESTORE(new_window_y); + _RESTORE(new_display_settings); + _al_sane_strncpy(tls->new_window_title, stored->tls.new_window_title, + strlen(tls->new_window_title)); + } + + if (flags & ALLEGRO_STATE_NEW_BITMAP_PARAMETERS) { + _RESTORE(new_bitmap_format); + _RESTORE(new_bitmap_flags); + } + + if (flags & ALLEGRO_STATE_DISPLAY) { + if (tls->current_display != stored->tls.current_display) { + _al_set_current_display_only(stored->tls.current_display); + ASSERT(tls->current_display == stored->tls.current_display); + } + } + + if (flags & ALLEGRO_STATE_TARGET_BITMAP) { + if (tls->target_bitmap != stored->tls.target_bitmap) { + al_set_target_bitmap(stored->tls.target_bitmap); + ASSERT(tls->target_bitmap == stored->tls.target_bitmap); + } + } + + if (flags & ALLEGRO_STATE_BLENDER) { + tls->current_blender = stored->stored_blender; + } + + if (flags & ALLEGRO_STATE_NEW_FILE_INTERFACE) { + _RESTORE(new_file_interface); + _RESTORE(fs_interface); + } + + if (flags & ALLEGRO_STATE_TRANSFORM) { + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + if (bitmap) + al_use_transform(&stored->stored_transform); + } + + if (flags & ALLEGRO_STATE_PROJECTION_TRANSFORM) { + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + if (bitmap) + al_use_projection_transform(&stored->stored_projection_transform); + } + +#undef _RESTORE +} + + + +/* Function: al_get_new_file_interface + * FIXME: added a work-around for the situation where TLS has not yet been + * initialised when this function is called. This may happen if Allegro + * tries to load a configuration file before the system has been + * initialised. Should probably rethink the logic here... + */ +const ALLEGRO_FILE_INTERFACE *al_get_new_file_interface(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return &_al_file_interface_stdio; + + /* FIXME: this situation should never arise because tls_ has the stdio + * interface set as a default, but it arises on OS X if + * pthread_getspecific() is called before pthreads_thread_init()... + */ + if (tls->new_file_interface) + return tls->new_file_interface; + else + return &_al_file_interface_stdio; +} + + + +/* Function: al_set_new_file_interface + */ +void al_set_new_file_interface(const ALLEGRO_FILE_INTERFACE *file_interface) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + tls->new_file_interface = file_interface; +} + + + +/* Function: al_get_fs_interface + */ +const ALLEGRO_FS_INTERFACE *al_get_fs_interface(void) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return &_al_fs_interface_stdio; + + if (tls->fs_interface) + return tls->fs_interface; + else + return &_al_fs_interface_stdio; +} + + + +/* Function: al_set_fs_interface + */ +void al_set_fs_interface(const ALLEGRO_FS_INTERFACE *fs_interface) +{ + thread_local_state *tls; + + if ((tls = tls_get()) == NULL) + return; + tls->fs_interface = fs_interface; +} + + + +/* Function: al_set_standard_fs_interface + */ +void al_set_standard_fs_interface(void) +{ + al_set_fs_interface(&_al_fs_interface_stdio); +} + + +#define SETTER(name, value) \ +{ \ + thread_local_state *tls; \ + if ((tls = tls_get()) == NULL) \ + return; \ + tls->name = value; \ +} + +#define GETTER(name, value) \ +{ \ + thread_local_state *tls; \ + if ((tls = tls_get()) == NULL) \ + return value; \ + return tls->name; \ +} + +/* Function: al_get_errno + */ +int al_get_errno(void) +GETTER(allegro_errno, 0) + +/* Function: al_set_errno + */ +void al_set_errno(int errnum) +SETTER(allegro_errno, errnum) + +/* Function: al_get_new_bitmap_depth + */ +int al_get_new_bitmap_depth(void) +GETTER(new_bitmap_depth, 0) + +/* Function: al_set_new_bitmap_depth + */ +void al_set_new_bitmap_depth(int depth) +SETTER(new_bitmap_depth, depth) + +/* Function: al_get_new_bitmap_samples + */ +int al_get_new_bitmap_samples(void) +GETTER(new_bitmap_samples, 0) + +/* Function: al_set_new_bitmap_samples + */ +void al_set_new_bitmap_samples(int samples) +SETTER(new_bitmap_samples, samples) + + + +#ifdef ALLEGRO_ANDROID +JNIEnv *_al_android_get_jnienv(void) +GETTER(jnienv, 0) + +void _al_android_set_jnienv(JNIEnv *jnienv) +SETTER(jnienv, jnienv) +#endif + + +int *_al_tls_get_dtor_owner_count(void) +{ + thread_local_state *tls; + + tls = tls_get(); + return &tls->dtor_owner_count; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/tls_dll.inc b/allegro/src/tls_dll.inc new file mode 100644 index 00000000..87a259f3 --- /dev/null +++ b/allegro/src/tls_dll.inc @@ -0,0 +1,86 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread local storage. + * + * See LICENSE.txt for copyright information. + */ + +#include + + +/* Forward declaration to bypass strict warning. */ +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); + + +static DWORD tls_index; + + +void _al_tls_init_once(void) +{ + /* nothing */ +} + + +static thread_local_state *tls_get(void) +{ + thread_local_state *t = TlsGetValue(tls_index); + if (t == NULL) { + t = al_malloc(sizeof(*t)); + TlsSetValue(tls_index, t); + initialize_tls_values(t); + } + return t; +} + + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + thread_local_state *data; + + (void)hinstDLL; + (void)fdwReason; + (void)lpvReserved; + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + if ((tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) { + return false; + } + break; + + // The thread of the attached process terminates. + case DLL_THREAD_DETACH: + // Release the allocated memory for this thread. + data = TlsGetValue(tls_index); + if (data != NULL) + al_free(data); + + break; + + // DLL unload due to process termination or FreeLibrary. + case DLL_PROCESS_DETACH: + // Release the allocated memory for this thread. + data = TlsGetValue(tls_index); + if (data != NULL) + al_free(data); + // Release the TLS index. + TlsFree(tls_index); + break; + + default: + break; + } + + return true; +} + + +/* vim: set ft=c sts=3 sw=3: */ diff --git a/allegro/src/tls_native.inc b/allegro/src/tls_native.inc new file mode 100644 index 00000000..f1159bdc --- /dev/null +++ b/allegro/src/tls_native.inc @@ -0,0 +1,42 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread local storage. + * + * See LICENSE.txt for copyright information. + */ + +#if defined(ALLEGRO_MSVC) || defined(ALLEGRO_BCC32) + #define THREAD_LOCAL_QUALIFIER __declspec(thread) +#else + #define THREAD_LOCAL_QUALIFIER __thread +#endif + +static THREAD_LOCAL_QUALIFIER thread_local_state _tls; + + +void _al_tls_init_once(void) +{ + /* nothing */ +} + + +static thread_local_state *tls_get(void) +{ + static THREAD_LOCAL_QUALIFIER thread_local_state *ptr = NULL; + if (!ptr) { + ptr = &_tls; + initialize_tls_values(ptr); + } + return ptr; +} + + +/* vim: set ft=c sts=3 sw=3 et: */ diff --git a/allegro/src/tls_pthread.inc b/allegro/src/tls_pthread.inc new file mode 100644 index 00000000..c593f569 --- /dev/null +++ b/allegro/src/tls_pthread.inc @@ -0,0 +1,56 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread local storage. + * + * See LICENSE.txt for copyright information. + */ + + +static pthread_key_t tls_key = 0; +static thread_local_state _tls; + + +static void tls_dtor(void *ptr) +{ + al_free(ptr); +} + + +void _al_tls_init_once(void) +{ + pthread_key_create(&tls_key, tls_dtor); +} + + +static thread_local_state *pthreads_thread_init(void) +{ + /* Allocate and copy the 'template' object */ + thread_local_state *ptr = (thread_local_state *)al_malloc(sizeof(thread_local_state)); + memcpy(ptr, &_tls, sizeof(thread_local_state)); + pthread_setspecific(tls_key, ptr); + return ptr; +} + + +/* This function is short so it can hopefully be inlined. */ +static thread_local_state *tls_get(void) +{ + thread_local_state *ptr = (thread_local_state*)pthread_getspecific(tls_key); + if (ptr == NULL) { + /* Must create object. */ + ptr = pthreads_thread_init(); + initialize_tls_values(ptr); + } + return ptr; +} + + +/* vim: set ft=c sts=3 sw=3: */ diff --git a/allegro/src/touch_input.c b/allegro/src/touch_input.c new file mode 100644 index 00000000..9eb332f9 --- /dev/null +++ b/allegro/src/touch_input.c @@ -0,0 +1,145 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Touch input API. + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_exitfunc.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_touch_input.h" + + +/* the active driver */ +static ALLEGRO_TOUCH_INPUT_DRIVER *touch_input_driver = NULL; + + +/* Function: al_is_touch_input_installed + */ +bool al_is_touch_input_installed(void) +{ + return (touch_input_driver ? true : false); +} + + +/* Function: al_install_touch_input + */ +bool al_install_touch_input(void) +{ + if (touch_input_driver) + return true; + + if (al_get_system_driver()->vt->get_touch_input_driver) { + + touch_input_driver = al_get_system_driver()->vt->get_touch_input_driver(); + if (touch_input_driver) { + if (!touch_input_driver->init_touch_input()) { + touch_input_driver = NULL; + return false; + } + + _al_add_exit_func(al_uninstall_touch_input, "al_uninstall_touch_input"); + return true; + } + } + + return false; +} + + +/* Function: al_uninstall_touch_input + */ +void al_uninstall_touch_input(void) +{ + if (!touch_input_driver) + return; + + touch_input_driver->exit_touch_input(); + touch_input_driver = NULL; +} + + +static ALLEGRO_TOUCH_INPUT *get_touch_input(void) +{ + ALLEGRO_TOUCH_INPUT *touch_input; + + ASSERT(touch_input_driver); + + touch_input = touch_input_driver->get_touch_input(); + ASSERT(touch_input); + + return touch_input; +} + + +/* Function: al_get_touch_input_state + */ +void al_get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state) +{ + ASSERT(touch_input_driver); + ASSERT(ret_state); + + touch_input_driver->get_touch_input_state(ret_state); +} + + +/* Function: al_set_mouse_emulation_mode + */ +void al_set_mouse_emulation_mode(int mode) +{ + ASSERT(touch_input_driver); + + if (touch_input_driver->set_mouse_emulation_mode) + touch_input_driver->set_mouse_emulation_mode(mode); + else + get_touch_input()->mouse_emulation_mode = mode; +} + + +/* Function: al_get_mouse_emulation_mode + */ +int al_get_mouse_emulation_mode(void) +{ + ASSERT(touch_input_driver); + + if (touch_input_driver->get_mouse_emulation_mode) + return touch_input_driver->get_mouse_emulation_mode(); + else + return get_touch_input()->mouse_emulation_mode; +} + + +/* Function: al_get_touch_input_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_touch_input_event_source(void) +{ + ALLEGRO_TOUCH_INPUT *touch_input = get_touch_input(); + + return (touch_input) ? &touch_input->es : NULL; +} + + +/* Function: al_get_touch_input_mouse_emulation_event_source + */ +ALLEGRO_EVENT_SOURCE *al_get_touch_input_mouse_emulation_event_source(void) +{ + ALLEGRO_TOUCH_INPUT *touch_input = get_touch_input(); + + return (touch_input) ? &touch_input->mouse_emulation_es : NULL; +} diff --git a/allegro/src/transformations.c b/allegro/src/transformations.c new file mode 100644 index 00000000..740e2bbe --- /dev/null +++ b/allegro/src/transformations.c @@ -0,0 +1,652 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Transformations. + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_transform.h" +#include + +/* ALLEGRO_DEBUG_CHANNEL("transformations") */ + +/* Function: al_copy_transform + */ +void al_copy_transform(ALLEGRO_TRANSFORM *dest, const ALLEGRO_TRANSFORM *src) +{ + ASSERT(src); + ASSERT(dest); + + memcpy(dest, src, sizeof(ALLEGRO_TRANSFORM)); +} + +/* Function: al_use_transform + */ +void al_use_transform(const ALLEGRO_TRANSFORM *trans) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ALLEGRO_DISPLAY *display; + + if (!target) + return; + + /* Changes to a back buffer should affect the front buffer, and vice versa. + * Currently we rely on the fact that in the OpenGL drivers the back buffer + * and front buffer bitmaps are exactly the same, and the DirectX driver + * doesn't support front buffer bitmaps. + */ + + if (trans != &target->transform) { + al_copy_transform(&target->transform, trans); + + target->inverse_transform_dirty = true; + } + + /* + * When the drawing is held, we apply the transformations in software, + * so the hardware transformation has to be kept at identity. + */ + if (!al_is_bitmap_drawing_held()) { + display = _al_get_bitmap_display(target); + if (display) { + display->vt->update_transformation(display, target); + } + } +} + +/* Function: al_use_projection_transform + */ +void al_use_projection_transform(const ALLEGRO_TRANSFORM *trans) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ALLEGRO_DISPLAY *display; + + if (!target) + return; + + /* Memory bitmaps don't support custom projection transforms */ + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP) + return; + + /* Changes to a back buffer should affect the front buffer, and vice versa. + * Currently we rely on the fact that in the OpenGL drivers the back buffer + * and front buffer bitmaps are exactly the same, and the DirectX driver + * doesn't support front buffer bitmaps. + */ + + if (trans != &target->transform) { + al_copy_transform(&target->proj_transform, trans); + } + + display = _al_get_bitmap_display(target); + if (display) { + display->vt->update_transformation(display, target); + } +} + +/* Function: al_get_current_transform + */ +const ALLEGRO_TRANSFORM *al_get_current_transform(void) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + + if (!target) + return NULL; + + return &target->transform; +} + +/* Function: al_get_current_projection_transform + */ +const ALLEGRO_TRANSFORM *al_get_current_projection_transform(void) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + + if (!target) + return NULL; + + return &target->proj_transform; +} + +/* Function: al_get_current_inverse_transform + */ +const ALLEGRO_TRANSFORM *al_get_current_inverse_transform(void) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + + if (!target) + return NULL; + + if (target->inverse_transform_dirty) { + al_copy_transform(&target->inverse_transform, &target->transform); + al_invert_transform(&target->inverse_transform); + } + + return &target->inverse_transform; +} + +/* Function: al_identity_transform + */ +void al_identity_transform(ALLEGRO_TRANSFORM *trans) +{ + ASSERT(trans); + + trans->m[0][0] = 1; + trans->m[0][1] = 0; + trans->m[0][2] = 0; + trans->m[0][3] = 0; + + trans->m[1][0] = 0; + trans->m[1][1] = 1; + trans->m[1][2] = 0; + trans->m[1][3] = 0; + + trans->m[2][0] = 0; + trans->m[2][1] = 0; + trans->m[2][2] = 1; + trans->m[2][3] = 0; + + trans->m[3][0] = 0; + trans->m[3][1] = 0; + trans->m[3][2] = 0; + trans->m[3][3] = 1; +} + +/* Function: al_build_transform + */ +void al_build_transform(ALLEGRO_TRANSFORM *trans, float x, float y, + float sx, float sy, float theta) +{ + float c, s; + ASSERT(trans); + + c = cosf(theta); + s = sinf(theta); + + trans->m[0][0] = sx * c; + trans->m[0][1] = sy * s; + trans->m[0][2] = 0; + trans->m[0][3] = 0; + + trans->m[1][0] = -sx * s; + trans->m[1][1] = sy * c; + trans->m[1][2] = 0; + trans->m[1][3] = 0; + + trans->m[2][0] = 0; + trans->m[2][1] = 0; + trans->m[2][2] = 1; + trans->m[2][3] = 0; + + trans->m[3][0] = x; + trans->m[3][1] = y; + trans->m[3][2] = 0; + trans->m[3][3] = 1; +} + +/* Function: al_build_camera_transform + */ +void al_build_camera_transform(ALLEGRO_TRANSFORM *trans, + float position_x, float position_y, float position_z, + float look_x, float look_y, float look_z, + float up_x, float up_y, float up_z) +{ + float x = position_x; + float y = position_y; + float z = position_z; + float xx, xy, xz, xnorm; + float yx, yy, yz; + float zx, zy, zz, znorm; + + al_identity_transform(trans); + + /* Get the z-axis (direction towards viewer) and normalize it. + */ + zx = x - look_x; + zy = y - look_y; + zz = z - look_z; + znorm = sqrt(zx * zx + zy * zy + zz * zz); + if (znorm == 0) + return; + zx /= znorm; + zy /= znorm; + zz /= znorm; + + /* Get the x-axis (direction pointing to the right) as the cross product of + * the up-vector times the z-axis. We need to normalize it because we do + * neither require the up-vector to be normalized nor perpendicular. + */ + xx = up_y * zz - zy * up_z; + xy = up_z * zx - zz * up_x; + xz = up_x * zy - zx * up_y; + xnorm = sqrt(xx * xx + xy * xy + xz * xz); + if (xnorm == 0) + return; + xx /= xnorm; + xy /= xnorm; + xz /= xnorm; + + /* Now use the cross product of z-axis and x-axis as our y-axis. This can + * have a different direction than the original up-vector but it will + * already be normalized. + */ + yx = zy * xz - xy * zz; + yy = zz * xx - xz * zx; + yz = zx * xy - xx * zy; + + /* This is an inverse translation (subtract the camera position) followed by + * an inverse rotation (rotate in the opposite direction of the camera + * orientation). + */ + trans->m[0][0] = xx; + trans->m[1][0] = xy; + trans->m[2][0] = xz; + trans->m[3][0] = xx * -x + xy * -y + xz * -z; + trans->m[0][1] = yx; + trans->m[1][1] = yy; + trans->m[2][1] = yz; + trans->m[3][1] = yx * -x + yy * -y + yz * -z; + trans->m[0][2] = zx; + trans->m[1][2] = zy; + trans->m[2][2] = zz; + trans->m[3][2] = zx * -x + zy * -y + zz * -z; +} + +/* Function: al_invert_transform + */ +void al_invert_transform(ALLEGRO_TRANSFORM *trans) +{ + float det, t; + ASSERT(trans); + + det = trans->m[0][0] * trans->m[1][1] - trans->m[1][0] * trans->m[0][1]; + + t = trans->m[3][0]; + trans->m[3][0] = ( trans->m[1][0] * trans->m[3][1] - t * trans->m[1][1]) / det; + trans->m[3][1] = (t * trans->m[0][1] - trans->m[0][0] * trans->m[3][1]) / det; + + t = trans->m[0][0]; + trans->m[0][0] = trans->m[1][1] / det; + trans->m[1][1] = t / det; + + trans->m[0][1] = - trans->m[0][1] / det; + trans->m[1][0] = - trans->m[1][0] / det; +} + +/* Function: al_transpose_transform + */ +void al_transpose_transform(ALLEGRO_TRANSFORM *trans) +{ + int i, j; + ASSERT(trans); + + ALLEGRO_TRANSFORM t = *trans; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + trans->m[i][j] = t.m[j][i]; + } + } +} + +/* Function: al_check_inverse + */ +int al_check_inverse(const ALLEGRO_TRANSFORM *trans, float tol) +{ + float det, norm, c0, c1, c3; + ASSERT(trans); + + det = fabsf(trans->m[0][0] * trans->m[1][1] - trans->m[1][0] * trans->m[0][1]); + /* + We'll use the 1-norm, as it is the easiest to compute + */ + c0 = fabsf(trans->m[0][0]) + fabsf(trans->m[0][1]); + c1 = fabsf(trans->m[1][0]) + fabsf(trans->m[1][1]); + c3 = fabsf(trans->m[3][0]) + fabsf(trans->m[3][1]) + 1; + norm = _ALLEGRO_MAX(_ALLEGRO_MAX(1, c0), _ALLEGRO_MAX(c1, c3)); + + return det > tol * norm; +} + +/* Function: al_translate_transform + */ +void al_translate_transform(ALLEGRO_TRANSFORM *trans, float x, float y) +{ + ASSERT(trans); + + trans->m[3][0] += x; + trans->m[3][1] += y; +} + + +/* Function: al_translate_transform_3d + */ +void al_translate_transform_3d(ALLEGRO_TRANSFORM *trans, float x, float y, + float z) +{ + ASSERT(trans); + + trans->m[3][0] += x; + trans->m[3][1] += y; + trans->m[3][2] += z; +} + + +/* Function: al_rotate_transform + */ +void al_rotate_transform(ALLEGRO_TRANSFORM *trans, float theta) +{ + float c, s; + float t; + ASSERT(trans); + + c = cosf(theta); + s = sinf(theta); + + t = trans->m[0][0]; + trans->m[0][0] = t * c - trans->m[0][1] * s; + trans->m[0][1] = t * s + trans->m[0][1] * c; + + t = trans->m[1][0]; + trans->m[1][0] = t * c - trans->m[1][1] * s; + trans->m[1][1] = t * s + trans->m[1][1] * c; + + t = trans->m[3][0]; + trans->m[3][0] = t * c - trans->m[3][1] * s; + trans->m[3][1] = t * s + trans->m[3][1] * c; +} + +/* Function: al_scale_transform + */ +void al_scale_transform(ALLEGRO_TRANSFORM *trans, float sx, float sy) +{ + ASSERT(trans); + + trans->m[0][0] *= sx; + trans->m[0][1] *= sy; + + trans->m[1][0] *= sx; + trans->m[1][1] *= sy; + + trans->m[3][0] *= sx; + trans->m[3][1] *= sy; +} + + +/* Function: al_scale_transform_3d + */ +void al_scale_transform_3d(ALLEGRO_TRANSFORM *trans, float sx, float sy, + float sz) +{ + ASSERT(trans); + + trans->m[0][0] *= sx; + trans->m[0][1] *= sy; + trans->m[0][2] *= sz; + + trans->m[1][0] *= sx; + trans->m[1][1] *= sy; + trans->m[1][2] *= sz; + + trans->m[2][0] *= sx; + trans->m[2][1] *= sy; + trans->m[2][2] *= sz; + + trans->m[3][0] *= sx; + trans->m[3][1] *= sy; + trans->m[3][2] *= sz; +} + +/* Function: al_transform_coordinates + */ +void al_transform_coordinates(const ALLEGRO_TRANSFORM *trans, float *x, float *y) +{ + float t; + ASSERT(trans); + ASSERT(x); + ASSERT(y); + + t = *x; + + *x = t * trans->m[0][0] + *y * trans->m[1][0] + trans->m[3][0]; + *y = t * trans->m[0][1] + *y * trans->m[1][1] + trans->m[3][1]; +} + +/* Function: al_transform_coordinates_3d + */ +void al_transform_coordinates_3d(const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z) +{ + float rx, ry, rz; + ASSERT(trans); + ASSERT(x); + ASSERT(y); + ASSERT(z); + + #define M(i, j) trans->m[i][j] + + rx = M(0, 0) * *x + M(1, 0) * *y + M(2, 0) * *z + M(3, 0); + ry = M(0, 1) * *x + M(1, 1) * *y + M(2, 1) * *z + M(3, 1); + rz = M(0, 2) * *x + M(1, 2) * *y + M(2, 2) * *z + M(3, 2); + + #undef M + + *x = rx; + *y = ry; + *z = rz; +} + +/* Function: al_transform_coordinates_4d + */ +void al_transform_coordinates_4d(const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z, float *w) +{ + float rx, ry, rz, rw; + ASSERT(trans); + ASSERT(x); + ASSERT(y); + ASSERT(z); + ASSERT(w); + + #define M(i, j) trans->m[i][j] + + rx = M(0, 0) * *x + M(1, 0) * *y + M(2, 0) * *z + M(3, 0) * *w; + ry = M(0, 1) * *x + M(1, 1) * *y + M(2, 1) * *z + M(3, 1) * *w; + rz = M(0, 2) * *x + M(1, 2) * *y + M(2, 2) * *z + M(3, 2) * *w; + rw = M(0, 3) * *x + M(1, 3) * *y + M(2, 3) * *z + M(3, 3) * *w; + + #undef M + + *x = rx; + *y = ry; + *z = rz; + *w = rw; +} + +/* Function: al_transform_coordinates_3d_projective + */ +void al_transform_coordinates_3d_projective(const ALLEGRO_TRANSFORM *trans, + float *x, float *y, float *z) +{ + float w = 1; + al_transform_coordinates_4d(trans, x, y, z, &w); + *x /= w; + *y /= w; + *z /= w; +} + +/* Function: al_compose_transform + */ +void al_compose_transform(ALLEGRO_TRANSFORM *trans, const ALLEGRO_TRANSFORM *other) +{ + #define E(x, y) \ + (other->m[0][y] * trans->m[x][0] + \ + other->m[1][y] * trans->m[x][1] + \ + other->m[2][y] * trans->m[x][2] + \ + other->m[3][y] * trans->m[x][3]) \ + + const ALLEGRO_TRANSFORM tmp = {{ + { E(0, 0), E(0, 1), E(0, 2), E(0, 3) }, + { E(1, 0), E(1, 1), E(1, 2), E(1, 3) }, + { E(2, 0), E(2, 1), E(2, 2), E(2, 3) }, + { E(3, 0), E(3, 1), E(3, 2), E(3, 3) } + }}; + + *trans = tmp; + + #undef E +} + +bool _al_transform_is_translation(const ALLEGRO_TRANSFORM* trans, + float *dx, float *dy) +{ + if (trans->m[0][0] == 1 && + trans->m[1][0] == 0 && + trans->m[2][0] == 0 && + trans->m[0][1] == 0 && + trans->m[1][1] == 1 && + trans->m[2][1] == 0 && + trans->m[0][2] == 0 && + trans->m[1][2] == 0 && + trans->m[2][2] == 1 && + trans->m[3][2] == 0 && + trans->m[0][3] == 0 && + trans->m[1][3] == 0 && + trans->m[2][3] == 0 && + trans->m[3][3] == 1) { + *dx = trans->m[3][0]; + *dy = trans->m[3][1]; + return true; + } + return false; +} + +/* Function: al_orthographic_transform + */ +void al_orthographic_transform(ALLEGRO_TRANSFORM *trans, + float left, float top, float n, + float right, float bottom, float f) +{ + float delta_x = right - left; + float delta_y = top - bottom; + float delta_z = f - n; + ALLEGRO_TRANSFORM tmp; + + al_identity_transform(&tmp); + + tmp.m[0][0] = 2.0f / delta_x; + tmp.m[1][1] = 2.0f / delta_y; + tmp.m[2][2] = 2.0f / delta_z; + tmp.m[3][0] = -(right + left) / delta_x; + tmp.m[3][1] = -(top + bottom) / delta_y; + tmp.m[3][2] = -(f + n) / delta_z; + tmp.m[3][3] = 1.0f; + + al_compose_transform(trans, &tmp); +} + + +/* Function: al_rotate_transform_3d + */ +void al_rotate_transform_3d(ALLEGRO_TRANSFORM *trans, + float x, float y, float z, float angle) +{ + double s = sin(angle); + double c = cos(angle); + double cc = 1 - c; + ALLEGRO_TRANSFORM tmp; + + al_identity_transform(&tmp); + + tmp.m[0][0] = (cc * x * x) + c; + tmp.m[0][1] = (cc * x * y) + (z * s); + tmp.m[0][2] = (cc * x * z) - (y * s); + tmp.m[0][3] = 0; + + tmp.m[1][0] = (cc * x * y) - (z * s); + tmp.m[1][1] = (cc * y * y) + c; + tmp.m[1][2] = (cc * z * y) + (x * s); + tmp.m[1][3] = 0; + + tmp.m[2][0] = (cc * x * z) + (y * s); + tmp.m[2][1] = (cc * y * z) - (x * s); + tmp.m[2][2] = (cc * z * z) + c; + tmp.m[2][3] = 0; + + tmp.m[3][0] = 0; + tmp.m[3][1] = 0; + tmp.m[3][2] = 0; + tmp.m[3][3] = 1; + + al_compose_transform(trans, &tmp); +} + + +/* Function: al_perspective_transform + */ +void al_perspective_transform(ALLEGRO_TRANSFORM *trans, + float left, float top, float n, + float right, float bottom, float f) +{ + float delta_x = right - left; + float delta_y = top - bottom; + float delta_z = f - n; + ALLEGRO_TRANSFORM tmp; + + al_identity_transform(&tmp); + + tmp.m[0][0] = 2.0f * n / delta_x; + tmp.m[1][1] = 2.0f * n / delta_y; + tmp.m[2][0] = (right + left) / delta_x; + tmp.m[2][1] = (top + bottom) / delta_y; + tmp.m[2][2] = -(f + n) / delta_z; + tmp.m[2][3] = -1.0f; + tmp.m[3][2] = -2.0f * f * n / delta_z; + tmp.m[3][3] = 0; + + al_compose_transform(trans, &tmp); +} + +/* Function: al_horizontal_shear_transform + */ +void al_horizontal_shear_transform(ALLEGRO_TRANSFORM* trans, float theta) +{ + float s; + ASSERT(trans); + s = -tanf(theta); + + trans->m[0][0] += trans->m[0][1] * s; + trans->m[1][0] += trans->m[1][1] * s; + trans->m[3][0] += trans->m[3][1] * s; +} + + +/* Function: al_vertical_shear_transform + */ +void al_vertical_shear_transform(ALLEGRO_TRANSFORM* trans, float theta) +{ + float s; + ASSERT(trans); + s = tanf(theta); + + trans->m[0][1] += trans->m[0][0] * s; + trans->m[1][1] += trans->m[1][0] * s; + trans->m[3][1] += trans->m[3][0] * s; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/tri_soft.c b/allegro/src/tri_soft.c new file mode 100644 index 00000000..73262fbf --- /dev/null +++ b/allegro/src/tri_soft.c @@ -0,0 +1,848 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Software triangle implementation functions. + * + * + * By Pavel Sountsov. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_blend.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_tri_soft.h" +#include + +ALLEGRO_DEBUG_CHANNEL("tri_soft") + +#define MIN _ALLEGRO_MIN +#define MAX _ALLEGRO_MAX + +typedef void (*shader_draw)(uintptr_t, int, int, int); +typedef void (*shader_init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*); +typedef void (*shader_first)(uintptr_t, int, int, int, int); +typedef void (*shader_step)(uintptr_t, int); + +typedef struct { + ALLEGRO_BITMAP *target; + ALLEGRO_COLOR cur_color; +} state_solid_any_2d; + +static void shader_solid_any_init(uintptr_t state, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) +{ + state_solid_any_2d* s = (state_solid_any_2d*)state; + s->target = al_get_target_bitmap(); + s->cur_color = v1->color; + + (void)v2; + (void)v3; +} + +static void shader_solid_any_first(uintptr_t state, int x1, int y, int left_minor, int left_major) +{ + (void)state; + (void)x1; + (void)y; + (void)left_minor; + (void)left_major; +} + +static void shader_solid_any_step(uintptr_t state, int minor) +{ + (void)state; + (void)minor; +} + +/*----------------------------------------------------------------------------*/ + +typedef struct { + state_solid_any_2d solid; + + ALLEGRO_COLOR color_dx; + ALLEGRO_COLOR color_dy; + ALLEGRO_COLOR color_const; + + /* + These are catched for the left edge walking + */ + ALLEGRO_COLOR minor_color; + ALLEGRO_COLOR major_color; + + /* + We use these to increase the precision of interpolation + */ + float off_x; + float off_y; +} state_grad_any_2d; + +#define PLANE_DETS(var, u1, u2, u3) \ + float var##_det = u1 * minor3 - u2 * minor2 + u3 * minor1; \ + float var##_det_x = u1 * y32 - u2 * y31 + u3 * y21; \ + float var##_det_y = u1 * x23 - u2 * x13 + u3 * x12; + +#define INIT_PREAMBLE \ + const float x1 = 0; \ + const float y1 = 0; \ + \ + const float x2 = v2->x - v1->x; \ + const float y2 = v2->y - v1->y; \ + \ + const float x3 = v3->x - v1->x; \ + const float y3 = v3->y - v1->y; \ + \ + const float minor1 = x1 * y2 - x2 * y1; \ + const float minor2 = x1 * y3 - x3 * y1; \ + const float minor3 = x2 * y3 - x3 * y2; \ + \ + const float y32 = y3 - y2; \ + const float y31 = y3 - y1; \ + const float y21 = y2 - y1; \ + \ + const float x23 = x2 - x3; \ + const float x13 = x1 - x3; \ + const float x12 = x1 - x2; \ + \ + const float det_u = minor3 - minor1 + minor2; + +static void shader_grad_any_init(uintptr_t state, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) +{ + INIT_PREAMBLE + + ALLEGRO_COLOR v1c = v1->color; + ALLEGRO_COLOR v2c = v2->color; + ALLEGRO_COLOR v3c = v3->color; + + PLANE_DETS(r, v1c.r, v2c.r, v3c.r) + PLANE_DETS(g, v1c.g, v2c.g, v3c.g) + PLANE_DETS(b, v1c.b, v2c.b, v3c.b) + PLANE_DETS(a, v1c.a, v2c.a, v3c.a) + + state_grad_any_2d* s = (state_grad_any_2d*)state; + + s->solid.target = al_get_target_bitmap(); + + s->off_x = v1->x - 0.5f; + s->off_y = v1->y + 0.5f; + + if (det_u == 0.0) { + s->color_dx = s->color_dy = s->color_const = al_map_rgba_f(0, 0, 0, 0); + } + else { + s->color_dx.r = -r_det_x / det_u; + s->color_dy.r = -r_det_y / det_u; + s->color_const.r = r_det / det_u; + + s->color_dx.g = -g_det_x / det_u; + s->color_dy.g = -g_det_y / det_u; + s->color_const.g = g_det / det_u; + + s->color_dx.b = -b_det_x / det_u; + s->color_dy.b = -b_det_y / det_u; + s->color_const.b = b_det / det_u; + + s->color_dx.a = -a_det_x / det_u; + s->color_dy.a = -a_det_y / det_u; + s->color_const.a = a_det / det_u; + } +} + +static void shader_grad_any_first(uintptr_t state, int x1, int y, int left_minor, int left_major) +{ + state_grad_any_2d* s = (state_grad_any_2d*)state; + + const float cur_x = (float)x1 - s->off_x; + const float cur_y = (float)y - s->off_y; + + s->solid.cur_color.r = cur_x * s->color_dx.r + cur_y * s->color_dy.r + s->color_const.r; + s->solid.cur_color.g = cur_x * s->color_dx.g + cur_y * s->color_dy.g + s->color_const.g; + s->solid.cur_color.b = cur_x * s->color_dx.b + cur_y * s->color_dy.b + s->color_const.b; + s->solid.cur_color.a = cur_x * s->color_dx.a + cur_y * s->color_dy.a + s->color_const.a; + + s->minor_color.r = (float)left_minor * s->color_dx.r + s->color_dy.r; + s->minor_color.g = (float)left_minor * s->color_dx.g + s->color_dy.g; + s->minor_color.b = (float)left_minor * s->color_dx.b + s->color_dy.b; + s->minor_color.a = (float)left_minor * s->color_dx.a + s->color_dy.a; + + s->major_color.r = (float)left_major * s->color_dx.r + s->color_dy.r; + s->major_color.g = (float)left_major * s->color_dx.g + s->color_dy.g; + s->major_color.b = (float)left_major * s->color_dx.b + s->color_dy.b; + s->major_color.a = (float)left_major * s->color_dx.a + s->color_dy.a; +} + +static void shader_grad_any_step(uintptr_t state, int minor) +{ + state_grad_any_2d* s = (state_grad_any_2d*)state; + if (minor) { + s->solid.cur_color.r += s->minor_color.r; + s->solid.cur_color.g += s->minor_color.g; + s->solid.cur_color.b += s->minor_color.b; + s->solid.cur_color.a += s->minor_color.a; + } else { + s->solid.cur_color.r += s->major_color.r; + s->solid.cur_color.g += s->major_color.g; + s->solid.cur_color.b += s->major_color.b; + s->solid.cur_color.a += s->major_color.a; + } +} + +/*========================== Textured Shaders ================================*/ + +#define SHADE_COLORS(A, B) \ + A.r = B.r * A.r; \ + A.g = B.g * A.g; \ + A.b = B.b * A.b; \ + A.a = B.a * A.a; + +typedef struct { + ALLEGRO_BITMAP *target; + ALLEGRO_COLOR cur_color; + + float du_dx, du_dy, u_const; + float dv_dx, dv_dy, v_const; + + double u, v; + double minor_du; + double minor_dv; + double major_du; + double major_dv; + + float off_x; + float off_y; + + ALLEGRO_BITMAP* texture; + int w, h; +} state_texture_solid_any_2d; + +static void shader_texture_solid_any_init(uintptr_t state, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) +{ + INIT_PREAMBLE + + PLANE_DETS(u, v1->u, v2->u, v3->u) + PLANE_DETS(v, v1->v, v2->v, v3->v) + + state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; + + s->target = al_get_target_bitmap(); + s->cur_color = v1->color; + + s->off_x = v1->x - 0.5f; + s->off_y = v1->y + 0.5f; + + s->w = al_get_bitmap_width(s->texture); + s->h = al_get_bitmap_height(s->texture); + + if (det_u == 0.0f) { + s->du_dx = s->du_dy = s->u_const = 0.0f; + s->dv_dx = s->dv_dy = s->v_const = 0.0f; + } + else { + s->du_dx = -u_det_x / det_u; + s->du_dy = -u_det_y / det_u; + s->u_const = u_det / det_u; + + s->dv_dx = -v_det_x / det_u; + s->dv_dy = -v_det_y / det_u; + s->v_const = v_det / det_u; + } +} + +static void shader_texture_solid_any_first(uintptr_t state, int x1, int y, int left_minor, int left_major) +{ + state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; + + const float cur_x = (float)x1 - s->off_x; + const float cur_y = (float)y - s->off_y; + + s->u = cur_x * s->du_dx + cur_y * s->du_dy + s->u_const; + s->v = cur_x * s->dv_dx + cur_y * s->dv_dy + s->v_const; + + s->minor_du = (double)left_minor * s->du_dx + s->du_dy; + s->minor_dv = (double)left_minor * s->dv_dx + s->dv_dy; + + s->major_du = (float)left_major * s->du_dx + s->du_dy; + s->major_dv = (float)left_major * s->dv_dx + s->dv_dy; +} + +static void shader_texture_solid_any_step(uintptr_t state, int minor) +{ + state_texture_solid_any_2d* s = (state_texture_solid_any_2d*)state; + if (minor) { + s->u += s->minor_du; + s->v += s->minor_dv; + } else { + s->u += s->major_du; + s->v += s->major_dv; + } +} + +/*----------------------------------------------------------------------------*/ + +typedef struct { + state_texture_solid_any_2d solid; + + ALLEGRO_COLOR color_dx; + ALLEGRO_COLOR color_dy; + ALLEGRO_COLOR color_const; + + /* + These are catched for the left edge walking + */ + ALLEGRO_COLOR minor_color; + ALLEGRO_COLOR major_color; +} state_texture_grad_any_2d; + +static void shader_texture_grad_any_init(uintptr_t state, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) +{ + INIT_PREAMBLE + + ALLEGRO_COLOR v1c = v1->color; + ALLEGRO_COLOR v2c = v2->color; + ALLEGRO_COLOR v3c = v3->color; + + PLANE_DETS(r, v1c.r, v2c.r, v3c.r) + PLANE_DETS(g, v1c.g, v2c.g, v3c.g) + PLANE_DETS(b, v1c.b, v2c.b, v3c.b) + PLANE_DETS(a, v1c.a, v2c.a, v3c.a) + PLANE_DETS(u, v1->u, v2->u, v3->u) + PLANE_DETS(v, v1->v, v2->v, v3->v) + + state_texture_grad_any_2d* s = (state_texture_grad_any_2d*)state; + + s->solid.target = al_get_target_bitmap(); + s->solid.w = al_get_bitmap_width(s->solid.texture); + s->solid.h = al_get_bitmap_height(s->solid.texture); + + s->solid.off_x = v1->x - 0.5f; + s->solid.off_y = v1->y + 0.5f; + + if (det_u == 0.0) { + s->solid.du_dx = s->solid.du_dy = s->solid.u_const = 0.0; + s->solid.dv_dx = s->solid.dv_dy = s->solid.v_const = 0.0; + s->color_dx = s->color_dy = s->color_const = al_map_rgba_f(0, 0, 0, 0); + } + else { + s->solid.du_dx = -u_det_x / det_u; + s->solid.du_dy = -u_det_y / det_u; + s->solid.u_const = u_det / det_u; + + s->solid.dv_dx = -v_det_x / det_u; + s->solid.dv_dy = -v_det_y / det_u; + s->solid.v_const = v_det / det_u; + + s->color_dx.r = -r_det_x / det_u; + s->color_dy.r = -r_det_y / det_u; + s->color_const.r = r_det / det_u; + + s->color_dx.g = -g_det_x / det_u; + s->color_dy.g = -g_det_y / det_u; + s->color_const.g = g_det / det_u; + + s->color_dx.b = -b_det_x / det_u; + s->color_dy.b = -b_det_y / det_u; + s->color_const.b = b_det / det_u; + + s->color_dx.a = -a_det_x / det_u; + s->color_dy.a = -a_det_y / det_u; + s->color_const.a = a_det / det_u; + } +} + +static void shader_texture_grad_any_first(uintptr_t state, int x1, int y, int left_minor, int left_major) +{ + state_texture_grad_any_2d* s = (state_texture_grad_any_2d*)state; + float cur_x; + float cur_y; + + shader_texture_solid_any_first(state, x1, y, left_minor, left_major); + + cur_x = (float)x1 - s->solid.off_x; + cur_y = (float)y - s->solid.off_y; + + s->solid.cur_color.r = cur_x * s->color_dx.r + cur_y * s->color_dy.r + s->color_const.r; + s->solid.cur_color.g = cur_x * s->color_dx.g + cur_y * s->color_dy.g + s->color_const.g; + s->solid.cur_color.b = cur_x * s->color_dx.b + cur_y * s->color_dy.b + s->color_const.b; + s->solid.cur_color.a = cur_x * s->color_dx.a + cur_y * s->color_dy.a + s->color_const.a; + + s->minor_color.r = (float)left_minor * s->color_dx.r + s->color_dy.r; + s->minor_color.g = (float)left_minor * s->color_dx.g + s->color_dy.g; + s->minor_color.b = (float)left_minor * s->color_dx.b + s->color_dy.b; + s->minor_color.a = (float)left_minor * s->color_dx.a + s->color_dy.a; + + s->major_color.r = (float)left_major * s->color_dx.r + s->color_dy.r; + s->major_color.g = (float)left_major * s->color_dx.g + s->color_dy.g; + s->major_color.b = (float)left_major * s->color_dx.b + s->color_dy.b; + s->major_color.a = (float)left_major * s->color_dx.a + s->color_dy.a; +} + +static void shader_texture_grad_any_step(uintptr_t state, int minor) +{ + state_texture_grad_any_2d* s = (state_texture_grad_any_2d*)state; + shader_texture_solid_any_step(state, minor); + if (minor) { + s->solid.cur_color.r += s->minor_color.r; + s->solid.cur_color.g += s->minor_color.g; + s->solid.cur_color.b += s->minor_color.b; + s->solid.cur_color.a += s->minor_color.a; + } else { + s->solid.cur_color.r += s->major_color.r; + s->solid.cur_color.g += s->major_color.g; + s->solid.cur_color.b += s->major_color.b; + s->solid.cur_color.a += s->major_color.a; + } +} + + +/* Include generated routines. */ +#include "scanline_drawers.inc" + + +static void triangle_stepper(uintptr_t state, + shader_init init, shader_first first, shader_step step, shader_draw draw, + ALLEGRO_VERTEX* vtx1, ALLEGRO_VERTEX* vtx2, ALLEGRO_VERTEX* vtx3) +{ + float Coords[6] = {vtx1->x - 0.5f, vtx1->y + 0.5f, vtx2->x - 0.5f, vtx2->y + 0.5f, vtx3->x - 0.5f, vtx3->y + 0.5f}; + float *V1 = Coords, *V2 = &Coords[2], *V3 = &Coords[4], *s; + + float left_error = 0; + float right_error = 0; + + float left_y_delta; + float right_y_delta; + + float left_x_delta; + float right_x_delta; + + int left_first, right_first, left_step, right_step; + int left_x, right_x, cur_y, mid_y, end_y; + float left_d_er, right_d_er; + + /* + The reason these things are declared implicitly, is because we need to determine which + of the edges is on the left, and which is on the right (because they are treated differently, + as described above) + We then can reuse these values in the actual calculation + */ + float major_x_delta, major_y_delta, minor_x_delta, minor_y_delta; + int major_on_the_left; + + // sort vertices so that V1 <= V2 <= V3 + if (V2[1] < V1[1]) { + s = V2; + V2 = V1; + V1 = s; + } + if (V3[1] < V1[1]) { + s = V3; + V3 = V1; + V1 = s; + } + if (V3[1] < V2[1]) { + s = V3; + V3 = V2; + V2 = s; + } + + /* + We set our integer based coordinates to be above their floating point counterparts + */ + cur_y = ceilf(V1[1]); + mid_y = ceilf(V2[1]); + end_y = ceilf(V3[1]); + + if (cur_y == end_y) + return; + + /* + As per definition, we take the ceiling + */ + left_x = ceilf(V1[0]); + + /* + Determine which edge is the left one + V1-V2 + | / + V3 + When the cross product is negative, the major is on the left + */ + + major_x_delta = V3[0] - V1[0]; + major_y_delta = V3[1] - V1[1]; + minor_x_delta = V2[0] - V1[0]; + minor_y_delta = V2[1] - V1[1]; + + if (major_x_delta * minor_y_delta - major_y_delta * minor_x_delta < 0) + major_on_the_left = 1; + else + major_on_the_left = 0; + + init(state, vtx1, vtx2, vtx3); + + /* + Do the first segment, if it exists + */ + if (cur_y != mid_y) { + /* + As per definition, we take the floor + */ + right_x = floorf(V1[0]); + + /* + Depending on where V2 is located, choose the correct delta's + */ + if (major_on_the_left) { + left_x_delta = major_x_delta; + right_x_delta = minor_x_delta; + left_y_delta = major_y_delta; + right_y_delta = minor_y_delta; + } else { + left_x_delta = minor_x_delta; + right_x_delta = major_x_delta; + left_y_delta = minor_y_delta; + right_y_delta = major_y_delta; + } + + /* + Calculate the initial errors... doesn't look too pretty, but it only has to be done a couple of times + per triangle drawing operation, so its not that bad + */ + left_error = ((float)cur_y - V1[1]) * left_x_delta - ((float)left_x - V1[0]) * left_y_delta; + right_error = ((float)cur_y - V1[1]) * right_x_delta - ((float)right_x - V1[0]) * right_y_delta; + + /* + Calculate the first step of the edge steppers, it is potentially different from all other steps + */ + left_first = ceilf((left_error) / left_y_delta); + /* + Introduce a tiny bias into the calculation, a problem with the floorf implementation + because it does not have a properly defined 0 point. I think this is a hack, + however, so if anyone has a better idea of how to fix this, by all means implement it. + + N.B. the same offset in the bottom segment as well + */ + right_first = floorf((right_error) / right_y_delta - 0.000001f); + + /* + Calculate the normal steps + */ + left_step = ceilf(left_x_delta / left_y_delta); + left_d_er = -(float)left_step * left_y_delta; + + right_step = ceilf(right_x_delta / right_y_delta); + right_d_er = -(float)right_step * right_y_delta; + + /* + Take the first step + */ + if (cur_y < mid_y) { + left_x += left_first; + left_error -= (float)left_first * left_y_delta; + + right_x += right_first; + right_error -= (float)right_first * right_y_delta; + + first(state, left_x, cur_y, left_step, left_step - 1); + + if (right_x >= left_x) { + draw(state, left_x, cur_y, right_x); + } + + cur_y++; + left_error += left_x_delta; + right_error += right_x_delta; + } + + /* + ...and then continue taking normal steps until we finish the segment + */ + while (cur_y < mid_y) { + left_error += left_d_er; + left_x += left_step; + + /* + If we dip to the right of the line, we shift one pixel to the left + If dx > 0, this corresponds to taking the minor step + If dx < 0, this corresponds to taking the major step + */ + if (left_error + left_y_delta <= 0) { + left_error += left_y_delta; + left_x -= 1; + step(state, 0); + } else + step(state, 1); + + right_error += right_d_er; + right_x += right_step; + + if (right_error <= 0) { + right_error += right_y_delta; + right_x -= 1; + } + + if (right_x >= left_x) { + draw(state, left_x, cur_y, right_x); + } + + cur_y++; + left_error += left_x_delta; + right_error += right_x_delta; + } + } + + /* + Draw the second segment, if possible + */ + if (cur_y < end_y) { + if (major_on_the_left) { + right_x = ceilf(V2[0]); + + left_x_delta = major_x_delta; + right_x_delta = V3[0] - V2[0]; + left_y_delta = major_y_delta; + right_y_delta = V3[1] - V2[1]; + + left_error = ((float)cur_y - V1[1]) * left_x_delta - ((float)left_x - V1[0]) * left_y_delta; + right_error = ((float)cur_y - V2[1]) * right_x_delta - ((float)right_x - V2[0]) * right_y_delta; + } else { + right_x = floorf(V2[0]); + + left_x_delta = V3[0] - V2[0]; + right_x_delta = major_x_delta; + left_y_delta = V3[1] - V2[1]; + right_y_delta = major_y_delta; + + left_error = ((float)cur_y - V2[1]) * left_x_delta - ((float)left_x - V2[0]) * left_y_delta; + right_error = ((float)cur_y - V1[1]) * right_x_delta - ((float)right_x - V1[0]) * right_y_delta; + } + + left_first = ceilf((left_error) / left_y_delta); + right_first = floorf((right_error) / right_y_delta - 0.000001f); + + left_step = ceilf(left_x_delta / left_y_delta); + left_d_er = -(float)left_step * left_y_delta; + + right_step = ceilf(right_x_delta / right_y_delta); + right_d_er = -(float)right_step * right_y_delta; + + if (cur_y < end_y) { + left_x += left_first; + left_error -= (float)left_first * left_y_delta; + + right_x += right_first; + right_error -= (float)right_first * right_y_delta; + + first(state, left_x, cur_y, left_step, left_step - 1); + + if (right_x >= left_x) { + draw(state, left_x, cur_y, right_x); + } + + cur_y++; + left_error += left_x_delta; + right_error += right_x_delta; + } + + while (cur_y < end_y) { + left_error += left_d_er; + left_x += left_step; + + if (left_error + left_y_delta <= 0) { + left_error += left_y_delta; + left_x -= 1; + step(state, 0); + } else + step(state, 1); + + right_error += right_d_er; + right_x += right_step; + + if (right_error <= 0) { + right_error += right_y_delta; + right_x -= 1; + } + + if (right_x >= left_x) { + draw(state, left_x, cur_y, right_x); + } + + cur_y++; + left_error += left_x_delta; + right_error += right_x_delta; + } + } +} + +/* +This one will check to see what exactly we need to draw... +I.e. this will call all of the actual renderers and set the appropriate callbacks +*/ +void _al_triangle_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) +{ + int shade = 1; + int grad = 1; + int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha; + ALLEGRO_COLOR v1c, v2c, v3c; + + v1c = v1->color; + v2c = v2->color; + v3c = v3->color; + + al_get_separate_bitmap_blender(&op, + &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); + if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED) { + shade = 0; + } + + if ((v1c.r == v2c.r && v2c.r == v3c.r) && + (v1c.g == v2c.g && v2c.g == v3c.g) && + (v1c.b == v2c.b && v2c.b == v3c.b) && + (v1c.a == v2c.a && v2c.a == v3c.a)) { + grad = 0; + } + + if (texture) { + if (grad) { + state_texture_grad_any_2d state; + state.solid.texture = texture; + + if (shade) { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_grad_any_init, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_grad_any_draw_shade); + } else { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_grad_any_init, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_grad_any_draw_opaque); + } + } else { + int white = 0; + state_texture_solid_any_2d state; + + if (v1c.r == 1 && v1c.g == 1 && v1c.b == 1 && v1c.a == 1) { + white = 1; + } + state.texture = texture; + if (shade) { + if (white) { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade_white); + } else { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade); + } + } else { + if (white) { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque_white); + } else { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque); + } + } + } + } else { + if (grad) { + state_grad_any_2d state; + if (shade) { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_grad_any_init, shader_grad_any_first, shader_grad_any_step, shader_grad_any_draw_shade); + } else { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_grad_any_init, shader_grad_any_first, shader_grad_any_step, shader_grad_any_draw_opaque); + } + } else { + state_solid_any_2d state; + if (shade) { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_solid_any_init, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_shade); + } else { + _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_solid_any_init, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_opaque); + } + } + } +} + +static int bitmap_region_is_locked(ALLEGRO_BITMAP* bmp, int x1, int y1, int w, int h) +{ + ASSERT(bmp); + + if (!al_is_bitmap_locked(bmp)) + return 0; + if (x1 + w > bmp->lock_x && y1 + h > bmp->lock_y && x1 < bmp->lock_x + bmp->lock_w && y1 < bmp->lock_y + bmp->lock_h) + return 1; + return 0; +} + +void _al_draw_soft_triangle( + ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state, + void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), + void (*first)(uintptr_t, int, int, int, int), + void (*step)(uintptr_t, int), + void (*draw)(uintptr_t, int, int, int)) +{ + /* + ALLEGRO_VERTEX copy_v1, copy_v2; <- may be needed for clipping later on + */ + ALLEGRO_VERTEX* vtx1 = v1; + ALLEGRO_VERTEX* vtx2 = v2; + ALLEGRO_VERTEX* vtx3 = v3; + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + int need_unlock = 0; + ALLEGRO_LOCKED_REGION *lr; + int min_x, max_x, min_y, max_y; + int clip_min_x, clip_min_y, clip_max_x, clip_max_y; + + al_get_clipping_rectangle(&clip_min_x, &clip_min_y, &clip_max_x, &clip_max_y); + clip_max_x += clip_min_x; + clip_max_y += clip_min_y; + + /* + TODO: Need to clip them first, make a copy of the vertices first then + */ + + /* + Lock the region we are drawing to. We are choosing the minimum and maximum + possible pixels touched from the formula (easily verified by following the + above algorithm. + */ + + min_x = (int)floorf(MIN(vtx1->x, MIN(vtx2->x, vtx3->x))) - 1; + min_y = (int)floorf(MIN(vtx1->y, MIN(vtx2->y, vtx3->y))) - 1; + max_x = (int)ceilf(MAX(vtx1->x, MAX(vtx2->x, vtx3->x))) + 1; + max_y = (int)ceilf(MAX(vtx1->y, MAX(vtx2->y, vtx3->y))) + 1; + + /* + TODO: This bit is temporary, the min max's will be guaranteed to be within the bitmap + once clipping is implemented + */ + if (min_x >= clip_max_x || min_y >= clip_max_y) + return; + if (max_x >= clip_max_x) + max_x = clip_max_x; + if (max_y >= clip_max_y) + max_y = clip_max_y; + + if (max_x < clip_min_x || max_y < clip_min_y) + return; + if (min_x < clip_min_x) + min_x = clip_min_x; + if (min_y < clip_min_y) + min_y = clip_min_y; + + if (al_is_bitmap_locked(target)) { + if (!bitmap_region_is_locked(target, min_x, min_y, max_x - min_x, max_y - min_y) || + _al_pixel_format_is_video_only(target->locked_region.format)) + return; + } else { + if (!(lr = al_lock_bitmap_region(target, min_x, min_y, max_x - min_x, max_y - min_y, ALLEGRO_PIXEL_FORMAT_ANY, 0))) + return; + need_unlock = 1; + } + + triangle_stepper(state, init, first, step, draw, v1, v2, v3); + + if (need_unlock) + al_unlock_bitmap(target); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/unix/udrvlist.c b/allegro/src/unix/udrvlist.c new file mode 100644 index 00000000..75d03cbe --- /dev/null +++ b/allegro/src/unix/udrvlist.c @@ -0,0 +1,47 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Dynamic driver lists shared by Unixy system drivers. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_system.h" + +#if defined ALLEGRO_WITH_XWINDOWS +#ifndef ALLEGRO_RASPBERRYPI +#include "allegro5/platform/aintxglx.h" +#else +#include "allegro5/internal/aintern_raspberrypi.h" +#endif +#endif + + + +/* This is a function each platform must define to register all available + * system drivers. + */ +void _al_register_system_interfaces(void) +{ + ALLEGRO_SYSTEM_INTERFACE **add; +#if defined ALLEGRO_WITH_XWINDOWS && !defined ALLEGRO_RASPBERRYPI + add = _al_vector_alloc_back(&_al_system_interfaces); + *add = _al_system_xglx_driver(); +#elif defined ALLEGRO_RASPBERRYPI + add = _al_vector_alloc_back(&_al_system_interfaces); + *add = _al_system_raspberrypi_driver(); +#endif +} + diff --git a/allegro/src/unix/ufdwatch.c b/allegro/src/unix/ufdwatch.c new file mode 100644 index 00000000..54539795 --- /dev/null +++ b/allegro/src/unix/ufdwatch.c @@ -0,0 +1,198 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Unix fd watcher thread. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + * + * This module implements a background thread that waits for data + * to arrive in file descriptors, at which point it dispatches to + * functions which will process that data. + */ + + +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/platform/aintunix.h" + + + +typedef struct WATCH_ITEM +{ + int fd; + void (*callback)(void *); + void *cb_data; +} WATCH_ITEM; + + +static _AL_THREAD fd_watch_thread; +static _AL_MUTEX fd_watch_mutex = _AL_MUTEX_UNINITED; +static _AL_VECTOR fd_watch_list = _AL_VECTOR_INITIALIZER(WATCH_ITEM); + + + +/* fd_watch_thread_func: [fdwatch thread] + * The thread loop function. + */ +static void fd_watch_thread_func(_AL_THREAD *self, void *unused) +{ + (void)unused; + + while (!_al_get_thread_should_stop(self)) { + + fd_set rfds; + int max_fd; + + /* set up max_fd and rfds */ + _al_mutex_lock(&fd_watch_mutex); + { + WATCH_ITEM *wi; + unsigned int i; + + FD_ZERO(&rfds); + max_fd = -1; + + for (i = 0; i < _al_vector_size(&fd_watch_list); i++) { + wi = _al_vector_ref(&fd_watch_list, i); + FD_SET(wi->fd, &rfds); + if (wi->fd > max_fd) + max_fd = wi->fd; + } + } + _al_mutex_unlock(&fd_watch_mutex); + + /* wait for something to happen on one of the fds */ + { + struct timeval tv; + int retval; + + tv.tv_sec = 0; + tv.tv_usec = 250000; + + retval = select(max_fd+1, &rfds, NULL, NULL, &tv); + if (retval < 1) + continue; + } + + /* one or more of the fds has activity */ + _al_mutex_lock(&fd_watch_mutex); + { + WATCH_ITEM *wi; + unsigned int i; + + for (i = 0; i < _al_vector_size(&fd_watch_list); i++) { + wi = _al_vector_ref(&fd_watch_list, i); + if (FD_ISSET(wi->fd, &rfds)) { + /* The callback is allowed to modify the watch list so the mutex + * must be recursive. + */ + wi->callback(wi->cb_data); + } + } + } + _al_mutex_unlock(&fd_watch_mutex); + } +} + + + +/* _al_unix_start_watching_fd: [primary thread] + * + * Start watching for data on file descriptor `fd'. This is done in + * a background thread, which is started if necessary. When there is + * data waiting to be read on fd, `callback' is applied to `cb_data'. + * The callback function should read as much data off fd as possible. + * + * Note: the callback is run from the background thread. You can + * assume there is only one callback being called from the fdwatch + * module at a time. + */ +void _al_unix_start_watching_fd(int fd, void (*callback)(void *), void *cb_data) +{ + ASSERT(fd >= 0); + ASSERT(callback); + + /* start the background thread if necessary */ + if (_al_vector_size(&fd_watch_list) == 0) { + /* We need a recursive mutex to allow callbacks to modify the fd watch + * list. + */ + _al_mutex_init_recursive(&fd_watch_mutex); + _al_thread_create(&fd_watch_thread, fd_watch_thread_func, NULL); + } + + /* now add the watch item to the list */ + _al_mutex_lock(&fd_watch_mutex); + { + WATCH_ITEM *wi = _al_vector_alloc_back(&fd_watch_list); + + wi->fd = fd; + wi->callback = callback; + wi->cb_data = cb_data; + } + _al_mutex_unlock(&fd_watch_mutex); +} + + + +/* _al_unix_stop_watching_fd: [primary thread] + * + * Stop watching for data on `fd'. Once there are no more file + * descriptors to watch, the background thread will be stopped. This + * function is synchronised with the background thread, so you don't + * have to do any locking before calling it. + */ +void _al_unix_stop_watching_fd(int fd) +{ + bool list_empty = false; + + /* find the fd in the watch list and remove it */ + _al_mutex_lock(&fd_watch_mutex); + { + WATCH_ITEM *wi; + unsigned int i; + + for (i = 0; i < _al_vector_size(&fd_watch_list); i++) { + wi = _al_vector_ref(&fd_watch_list, i); + if (wi->fd == fd) { + _al_vector_delete_at(&fd_watch_list, i); + list_empty = _al_vector_is_empty(&fd_watch_list); + break; + } + } + } + _al_mutex_unlock(&fd_watch_mutex); + + /* if no more fd's are being watched, stop the background thread */ + if (list_empty) { + _al_thread_join(&fd_watch_thread); + _al_mutex_destroy(&fd_watch_mutex); + _al_vector_free(&fd_watch_list); + } +} + + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/src/unix/ugfxdrv.c b/allegro/src/unix/ugfxdrv.c new file mode 100644 index 00000000..e69de29b diff --git a/allegro/src/unix/uhapdrv.c b/allegro/src/unix/uhapdrv.c new file mode 100644 index 00000000..eae23e65 --- /dev/null +++ b/allegro/src/unix/uhapdrv.c @@ -0,0 +1,30 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * List of Unix haptic drivers. + * + * By Beoran. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_haptic.h" + + + +_AL_BEGIN_HAPTIC_DRIVER_LIST +#if defined ALLEGRO_HAVE_LINUX_INPUT_H && (defined ALLEGRO_WITH_XWINDOWS || defined ALLEGRO_RASPBERRYPI) + { _ALLEGRO_HAPDRV_LINUX, &_al_hapdrv_linux, true }, +#endif +_AL_END_HAPTIC_DRIVER_LIST diff --git a/allegro/src/unix/ujoydrv.c b/allegro/src/unix/ujoydrv.c new file mode 100644 index 00000000..adab45ac --- /dev/null +++ b/allegro/src/unix/ujoydrv.c @@ -0,0 +1,30 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * List of Unix joystick drivers. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_joystick.h" + + + +_AL_BEGIN_JOYSTICK_DRIVER_LIST +#if defined ALLEGRO_HAVE_LINUX_INPUT_H && (defined ALLEGRO_WITH_XWINDOWS || defined ALLEGRO_RASPBERRYPI) + { _ALLEGRO_JOYDRV_LINUX, &_al_joydrv_linux, true }, +#endif +_AL_END_JOYSTICK_DRIVER_LIST diff --git a/allegro/src/unix/ukeybd.c b/allegro/src/unix/ukeybd.c new file mode 100644 index 00000000..fb57a204 --- /dev/null +++ b/allegro/src/unix/ukeybd.c @@ -0,0 +1,29 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Unix keyboard module. + * + * By Michael Bukin. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_driver.h" + + + +/* list the available drivers */ +_AL_DRIVER_INFO _al_keyboard_driver_list[] = +{ + { 0, NULL, 0 } +}; + diff --git a/allegro/src/unix/umouse.c b/allegro/src/unix/umouse.c new file mode 100644 index 00000000..1664e9b0 --- /dev/null +++ b/allegro/src/unix/umouse.c @@ -0,0 +1,29 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Unix mouse module. + * + * By Michael Bukin. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_driver.h" + + + +/* list the available drivers */ +_AL_DRIVER_INFO _al_mouse_driver_list[] = +{ + { 0, NULL, 0 } +}; + diff --git a/allegro/src/unix/upath.c b/allegro/src/unix/upath.c new file mode 100644 index 00000000..df408eaf --- /dev/null +++ b/allegro/src/unix/upath.c @@ -0,0 +1,507 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * List of system pathes for the Unix library. + * + * By Michael Bukin. + * + * See readme.txt for copyright information. + */ + + +#include +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/fshook.h" +#include "allegro5/path.h" + +#ifdef ALLEGRO_HAVE_SYS_UTSNAME_H + #include +#endif + +#ifdef ALLEGRO_HAVE_SV_PROCFS_H + #include + #include + #include +#endif + +ALLEGRO_DEBUG_CHANNEL("upath") + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +#ifndef ALLEGRO_MACOSX +/* _find_executable_file: + * Helper function: searches path and current directory for executable. + * Returns 1 on succes, 0 on failure. + */ +static ALLEGRO_PATH *_find_executable_file(const char *filename) +{ + char *env; + + /* If filename has an explicit path, search current directory */ + if (strchr(filename, '/')) { + if (filename[0] == '/') { + /* Full path; done */ + return al_create_path(filename); + } + else { + struct stat finfo; + char *cwd; + + /* Prepend current directory */ + cwd = al_get_current_directory(); + if (cwd) { + ALLEGRO_PATH *path = al_create_path_for_directory(cwd); + al_free(cwd); + al_set_path_filename(path, filename); + + if (stat(al_path_cstr(path, '/'), &finfo) == 0 + && !S_ISDIR(finfo.st_mode)) { + return path; + } + + al_destroy_path(path); + } + } + } + /* If filename has no explicit path, but we do have $PATH, search + * there + */ + else if ((env = getenv("PATH"))) { + struct stat finfo; + ALLEGRO_USTR *us = al_ustr_new(env); + int start_pos = 0; + while (start_pos >= 0) { + int next_start_pos = al_ustr_find_chr(us, start_pos + 1, ':'); + int end_pos = next_start_pos; + if (next_start_pos < 0) + end_pos = al_ustr_size(us); + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *sub = al_ref_ustr(&info, us, start_pos, end_pos); + + ALLEGRO_PATH *path = al_create_path_for_directory(al_cstr(sub)); + al_set_path_filename(path, filename); + + if (stat(al_path_cstr(path, '/'), &finfo) == 0 && + !S_ISDIR (finfo.st_mode)) { + al_ustr_free(us); + return path; + } + + al_destroy_path(path); + + start_pos = next_start_pos; + } + al_ustr_free(us); + } + + return NULL; +} + +/* Return full path to the current executable, use proc fs if + * available. + */ +static ALLEGRO_PATH *get_executable_name(void) +{ + ALLEGRO_PATH *path; + + #ifdef ALLEGRO_HAVE_GETEXECNAME + { + const char *s = getexecname(); + if (s) { + if (s[0] == '/') { /* Absolute path */ + return al_create_path(s); + } + else { /* Not an absolute path */ + path = _find_executable_file(s); + if (path) + return path; + } + } + } + #endif + + /* We need the PID in order to query procfs */ + pid_t pid = getpid(); + + /* Try a Linux-like procfs */ + /* get symolic link to executable from proc fs */ + char linkname[1024]; + char filename[1024]; + struct stat finfo; + sprintf(linkname, "/proc/%d/exe", (int)pid); + if (stat(linkname, &finfo) == 0) { + int len = readlink(linkname, filename, sizeof(filename) - 1); + if (len > -1) { + filename[len] = '\0'; + return al_create_path(filename); + } + } + + /* Use System V procfs calls if available */ +#ifdef ALLEGRO_HAVE_SV_PROCFS_H + struct prpsinfo psinfo; + int fd; + sprintf(linkname, "/proc/%d/exe", (int)pid); + fd = open(linkname, O_RDONLY); + if (fd != -1) { + ioctl(fd, PIOCPSINFO, &psinfo); + close(fd); + + /* Use argv[0] directly if we can */ +#ifdef ALLEGRO_HAVE_PROCFS_ARGCV + if (psinfo.pr_argv && psinfo.pr_argc) { + path = _find_executable_file(psinfo.pr_argv[0]); + if (path) + return path; + } + else +#endif + { + /* Emulate it */ + /* We use the pr_psargs field to find argv[0] + * This is better than using the pr_fname field because we need + * the additional path information that may be present in argv[0] + */ + + /* Skip other args */ + char *s = strchr(psinfo.pr_psargs, ' '); + if (s) + s[0] = '\0'; + path = _find_executable_file(psinfo.pr_psargs); + if (path) + return path; + } + + /* Try the pr_fname just for completeness' sake if argv[0] fails */ + path = _find_executable_file(psinfo.pr_fname); + if (path) + return path; + } +#endif + + /* Last resort: try using the output of the ps command to at least find */ + /* the name of the file if not the full path */ + char command[1024]; + sprintf(command, "ps -p %d", (int)pid); + FILE *pipe = popen(command, "r"); + if (pipe) { + char* ret; + /* The first line of output is a header */ + ret = fgets(linkname, sizeof(linkname), pipe); + if (!ret) + ALLEGRO_ERROR("Failed to read the name of the executable file.\n"); + + /* The information we want is in the last column; find it */ + int len = strlen(linkname); + while (linkname[len] != ' ' && linkname[len] != '\t') + len--; + + /* The second line contains the info we want */ + ret = fgets(linkname, sizeof(linkname), pipe); + if (!ret) + ALLEGRO_ERROR("Failed to read the name of the executable file.\n"); + pclose(pipe); + + /* Treat special cases: filename between [] and - for login shell */ + if (linkname[len] == '-') + len++; + + if (linkname[len] == '[' && linkname[strlen(linkname)] == ']') { + len++; + linkname[strlen(linkname)] = '\0'; + } + + /* Now, the filename should be in the last column */ + _al_sane_strncpy(filename, linkname+len+1, strlen(linkname)-len+1); + + path = _find_executable_file(filename); + if (path) + return path; + + /* Just return the output from ps... */ + return al_create_path(filename); + } + + /* Give up; return empty string */ + return al_create_path(""); +} + +static ALLEGRO_PATH *follow_symlinks(ALLEGRO_PATH *path) +{ + for (;;) { + const char *path_str = al_path_cstr(path, '/'); + char buf[PATH_MAX]; + int len; + + len = readlink(path_str, buf, sizeof(buf) - 1); + if (len <= 0) + break; + buf[len] = '\0'; + al_destroy_path(path); + path = al_create_path(buf); + } + + /* Make absolute path. */ + { + const char *cwd = al_get_current_directory(); + ALLEGRO_PATH *cwd_path = al_create_path_for_directory(cwd); + if (al_rebase_path(cwd_path, path)) + al_make_path_canonical(path); + al_destroy_path(cwd_path); + al_free((void *) cwd); + } + + return path; +} + +#endif + +#define XDG_MAX_PATH_LEN 1000 + +/* get_xdg_path - locate an XDG user dir + */ +static ALLEGRO_PATH *_get_xdg_path(const char *location) +{ + ALLEGRO_PATH *location_path = NULL; + ALLEGRO_PATH *xdg_config_path = NULL; + ALLEGRO_FILE *xdg_config_file = NULL; + const char *xdg_config_home = getenv("XDG_CONFIG_HOME"); + int fd; + + if (xdg_config_home) { + /* use $XDG_CONFIG_HOME since it exists */ + xdg_config_path = al_create_path_for_directory(xdg_config_home); + } + else { + /* the default XDG location is ~/.config */ + xdg_config_path = al_get_standard_path(ALLEGRO_USER_HOME_PATH); + if (!xdg_config_path) return NULL; + al_append_path_component(xdg_config_path, ".config"); + } + + al_set_path_filename(xdg_config_path, "user-dirs.dirs"); + fd = open(al_path_cstr(xdg_config_path, '/'), O_RDONLY); + if (fd != -1) { + xdg_config_file = al_fopen_fd(fd, "r"); + } + al_destroy_path(xdg_config_path); + + if (!xdg_config_file) return NULL; + + while (!al_feof(xdg_config_file)) { + char line[XDG_MAX_PATH_LEN]; /* one line of the config file */ + const char *p = line; /* where we're at in the line */ + char component[XDG_MAX_PATH_LEN]; /* the path component being parsed */ + int i = 0; /* how long the current component is */ + + al_fgets(xdg_config_file, line, XDG_MAX_PATH_LEN); + + /* skip leading white space */ + while (*p == ' ' || *p == '\t') p++; + + /* skip the line if it does not begin with XDG_location_DIR */ + if (strncmp(p, "XDG_", 4)) continue; + p += 4; + + if (strncmp(p, location, strlen(location))) continue; + p += strlen(location); + + if (strncmp(p, "_DIR", 4)) continue; + p += 4; + + /* skip past the =", allowing for white space */ + while (*p == ' ' || *p == '\t') p++; + if (*p++ != '=') continue; + while (*p == ' ' || *p == '\t') p++; + if (*p++ != '"') continue; + + /* We've found the right line. Now parse it, basically assuming + that it is in a sane format. + */ + if (!strncmp(p, "$HOME", 5)) { + /* $HOME is the only environment variable that the path is + allowed to use, and it must be first, by specification. */ + location_path = al_get_standard_path(ALLEGRO_USER_HOME_PATH); + p += 5; + } + else { + location_path = al_create_path("/"); + } + + while (*p) { + if (*p == '"' || *p == '/') { + /* add the component (if non-empty) to the path */ + if (i > 0) { + component[i] = 0; + al_append_path_component(location_path, component); + i = 0; + } + if (*p == '"') break; + } + else { + if (*p == '\\') { + /* treat any escaped character as a literal */ + p++; + if (!*p) break; + } + component[i++] = *p; + } + + p++; + } + + /* Finished parsing the path. */ + break; + } + + al_fclose(xdg_config_file); + + return location_path; +} + +static ALLEGRO_PATH *_unix_find_home(void) +{ + char *home_env = getenv("HOME"); + + if (!home_env || home_env[0] == '\0') { + /* since HOME isn't set, we have to ask libc for the info */ + + /* get user id */ + uid_t uid = getuid(); + + /* grab user information */ + struct passwd *pass = getpwuid(uid); + if (!pass) { + al_set_errno(errno); + return NULL; + } + + if (pass->pw_dir) { + /* hey, we got our home directory */ + return al_create_path_for_directory(pass->pw_dir); + } + al_set_errno(ENOENT); + return NULL; + } + else { + return al_create_path_for_directory(home_env); + } +} + +ALLEGRO_PATH *_al_unix_get_path(int id) +{ + switch (id) { + case ALLEGRO_TEMP_PATH: { + /* Check: TMP, TMPDIR, TEMP or TEMPDIR */ + char *envs[] = { "TMP", "TMPDIR", "TEMP", "TEMPDIR", NULL}; + uint32_t i = 0; + for (; envs[i] != NULL; ++i) { + char *tmp = getenv(envs[i]); + if (tmp) { + return al_create_path_for_directory(tmp); + } + } + + /* next try: /tmp /var/tmp /usr/tmp */ + char *paths[] = { "/tmp/", "/var/tmp/", "/usr/tmp/", NULL }; + for (i=0; paths[i] != NULL; ++i) { + ALLEGRO_FS_ENTRY *fse = al_create_fs_entry(paths[i]); + bool found = (al_get_fs_entry_mode(fse) & ALLEGRO_FILEMODE_ISDIR) != 0; + al_destroy_fs_entry(fse); + if (found) { + return al_create_path_for_directory(paths[i]); + } + } + + /* Give up? */ + return NULL; + } break; + + case ALLEGRO_RESOURCES_PATH: { + ALLEGRO_PATH *exe = get_executable_name(); + exe = follow_symlinks(exe); + al_set_path_filename(exe, NULL); + return exe; + + } break; + + case ALLEGRO_USER_DATA_PATH: + case ALLEGRO_USER_SETTINGS_PATH: { + ALLEGRO_PATH *local_path = NULL; + const char *org_name = al_get_org_name(); + const char *app_name = al_get_app_name(); + + /* to avoid writing directly into the user's directory, require at least an app name */ + if (!app_name) + return NULL; + + /* find the appropriate path from the xdg environment variables, if possible */ + if (id == ALLEGRO_USER_DATA_PATH) { + const char *xdg_data_home = getenv("XDG_DATA_HOME"); + local_path = al_create_path_for_directory(xdg_data_home ? xdg_data_home : ".local/share"); + } + else { + const char *xdg_config_home = getenv("XDG_CONFIG_HOME"); + local_path = al_create_path_for_directory(xdg_config_home ? xdg_config_home : ".config"); + } + + if (!local_path) + return NULL; + + /* if the path is relative, prepend the user's home directory */ + if (al_path_cstr(local_path, '/')[0] != '/') { + ALLEGRO_PATH *home_path = _unix_find_home(); + if (!home_path) + return NULL; + + al_rebase_path(home_path, local_path); + al_destroy_path(home_path); + } + + /* only add org name if not blank */ + if (org_name && org_name[0]) { + al_append_path_component(local_path, al_get_org_name()); + } + + al_append_path_component(local_path, al_get_app_name()); + + return local_path; + } break; + + case ALLEGRO_USER_HOME_PATH: + return _unix_find_home(); + + case ALLEGRO_USER_DOCUMENTS_PATH: { + ALLEGRO_PATH *local_path = _get_xdg_path("DOCUMENTS"); + return local_path ? local_path : _unix_find_home(); + } break; + + case ALLEGRO_EXENAME_PATH: + return get_executable_name(); + break; + + default: + return NULL; + } + + return NULL; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/unix/utime.c b/allegro/src/unix/utime.c new file mode 100644 index 00000000..70a21422 --- /dev/null +++ b/allegro/src/unix/utime.c @@ -0,0 +1,95 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Unix time module. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + + +#include +#include + +#include "allegro5/altime.h" +#include "allegro5/debug.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/platform/aintuthr.h" + +ALLEGRO_STATIC_ASSERT(utime, + sizeof(ALLEGRO_TIMEOUT_UNIX) <= sizeof(ALLEGRO_TIMEOUT)); + + +/* Marks the time Allegro was initialised, for al_get_time(). */ +struct timeval _al_unix_initial_time; + + + +/* _al_unix_init_time: + * Called by the system driver to mark the beginning of time. + */ +void _al_unix_init_time(void) +{ + gettimeofday(&_al_unix_initial_time, NULL); +} + + + +double _al_unix_get_time(void) +{ + struct timeval now; + double time; + + gettimeofday(&now, NULL); + time = (double) (now.tv_sec - _al_unix_initial_time.tv_sec) + + (double) (now.tv_usec - _al_unix_initial_time.tv_usec) * 1.0e-6; + return time; +} + + + +void _al_unix_rest(double seconds) +{ + struct timespec timeout; + double fsecs = floor(seconds); + timeout.tv_sec = (time_t) fsecs; + timeout.tv_nsec = (suseconds_t) ((seconds - fsecs) * 1e9); + nanosleep(&timeout, 0); +} + + + +void _al_unix_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds) +{ + ALLEGRO_TIMEOUT_UNIX *ut = (ALLEGRO_TIMEOUT_UNIX *) timeout; + struct timeval now; + double integral; + double frac; + + ASSERT(ut); + + gettimeofday(&now, NULL); + + if (seconds <= 0.0) { + ut->abstime.tv_sec = now.tv_sec; + ut->abstime.tv_nsec = now.tv_usec * 1000; + } + else { + frac = modf(seconds, &integral); + + ut->abstime.tv_sec = now.tv_sec + integral; + ut->abstime.tv_nsec = (now.tv_usec * 1000) + (frac * 1000000000L); + ut->abstime.tv_sec += ut->abstime.tv_nsec / 1000000000L; + ut->abstime.tv_nsec = ut->abstime.tv_nsec % 1000000000L; + } +} + +/* vim: set sts=3 sw=3 et */ diff --git a/allegro/src/unix/uxthread.c b/allegro/src/unix/uxthread.c new file mode 100644 index 00000000..067fcd34 --- /dev/null +++ b/allegro/src/unix/uxthread.c @@ -0,0 +1,201 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Internal cross-platform threading API for Unix. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + + +#define _XOPEN_SOURCE 500 /* for Unix98 recursive mutexes */ + /* XXX: added configure test */ + +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/platform/aintunix.h" + +#ifdef ALLEGRO_ANDROID +#include "allegro5/internal/aintern_android.h" +#endif + + + +/* threads */ + +static void *thread_proc_trampoline(void *data) +{ + _AL_THREAD *thread = data; + /* Android is special and needs to attach/detach threads with Java */ +#ifdef ALLEGRO_ANDROID + _al_android_thread_created(); +#endif + (*thread->proc)(thread, thread->arg); +#ifdef ALLEGRO_ANDROID + _al_android_thread_ended(); +#endif + return NULL; +} + + +void _al_thread_create(_AL_THREAD *thread, void (*proc)(_AL_THREAD*, void*), void *arg) +{ + ASSERT(thread); + ASSERT(proc); + { + int status; + + pthread_mutex_init(&thread->mutex, NULL); + + thread->should_stop = false; + thread->proc = proc; + thread->arg = arg; + + status = pthread_create(&thread->thread, NULL, thread_proc_trampoline, thread); + ASSERT(status == 0); + if (status != 0) + abort(); + } +} + + +void _al_thread_create_with_stacksize(_AL_THREAD* thread, void (*proc)(_AL_THREAD*, void*), void *arg, size_t stacksize) +{ +#ifndef __GNU__ + ASSERT(stacksize >= PTHREAD_STACK_MIN); +#endif + ASSERT(thread); + ASSERT(proc); + { + int status; + + pthread_mutex_init(&thread->mutex, NULL); + + thread->should_stop = false; + thread->proc = proc; + thread->arg = arg; + + pthread_attr_t thread_attr; + int result = 0; + result = pthread_attr_init(&thread_attr); + ASSERT(result == 0); + + // On some systems, pthread_attr_setstacksize() can fail + // if stacksize is not a multiple of the system page size. + result = pthread_attr_setstacksize(&thread_attr, stacksize); + ASSERT(result == 0); + + status = pthread_create(&thread->thread, &thread_attr, thread_proc_trampoline, thread); + ASSERT(status == 0); + if (status != 0) + abort(); + } +} + + +void _al_thread_set_should_stop(_AL_THREAD *thread) +{ + ASSERT(thread); + + pthread_mutex_lock(&thread->mutex); + { + thread->should_stop = true; + } + pthread_mutex_unlock(&thread->mutex); +} + + + +void _al_thread_join(_AL_THREAD *thread) +{ + ASSERT(thread); + + _al_thread_set_should_stop(thread); + pthread_join(thread->thread, NULL); + + pthread_mutex_destroy(&thread->mutex); +} + + +void _al_thread_detach(_AL_THREAD *thread) +{ + ASSERT(thread); + pthread_mutex_destroy(&thread->mutex); + pthread_detach(thread->thread); +} + + +/* mutexes */ + +void _al_mutex_init(_AL_MUTEX *mutex) +{ + ASSERT(mutex); + + pthread_mutex_init(&mutex->mutex, NULL); + mutex->inited = true; +} + + +void _al_mutex_init_recursive(_AL_MUTEX *mutex) +{ + pthread_mutexattr_t attr; + + ASSERT(mutex); + + pthread_mutexattr_init(&attr); + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == EINVAL) { + pthread_mutexattr_destroy(&attr); + abort(); /* XXX */ + } + + pthread_mutex_init(&mutex->mutex, &attr); + mutex->inited = true; + + pthread_mutexattr_destroy(&attr); +} + + +void _al_mutex_destroy(_AL_MUTEX *mutex) +{ + ASSERT(mutex); + + if (mutex->inited) { + pthread_mutex_destroy(&mutex->mutex); + mutex->inited = false; + } +} + + +/* condition variables */ +/* most of the condition variable implementation is actually inline */ + +int _al_cond_timedwait(_AL_COND *cond, _AL_MUTEX *mutex, + const ALLEGRO_TIMEOUT *timeout) +{ + ALLEGRO_TIMEOUT_UNIX *unix_timeout = (ALLEGRO_TIMEOUT_UNIX *) timeout; + int retcode; + + retcode = pthread_cond_timedwait(&cond->cond, &mutex->mutex, + &unix_timeout->abstime); + + return (retcode == ETIMEDOUT) ? -1 : 0; +} + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ diff --git a/allegro/src/utf8.c b/allegro/src/utf8.c new file mode 100644 index 00000000..1a6e55d8 --- /dev/null +++ b/allegro/src/utf8.c @@ -0,0 +1,1175 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * UTF-8 string handling functions. + * + * By Peter Wang. + * + * See LICENSE.txt for copyright information. + */ + + +#include +#include "allegro5/allegro.h" +#include "allegro5/utf8.h" +#include "allegro5/internal/bstrlib.h" +#include "allegro5/internal/aintern.h" + +ALLEGRO_STATIC_ASSERT(utf8, + sizeof(ALLEGRO_USTR_INFO) >= sizeof(struct _al_tagbstring)); + +#ifdef ALLEGRO_MSVC + #pragma warning (disable: 4066) +#endif + +#ifndef ALLEGRO_HAVE_VA_COPY + /* If va_copy() is not defined we assume that a simple assignment suffices. + * From a few web searches, this appears to be true for MSVC 7. + */ + #define va_copy(a, b) ((a) = (b)) +#endif + + +#define IS_SINGLE_BYTE(c) (((unsigned)(c) & 0x80) == 0) +#define IS_LEAD_BYTE(c) (((unsigned)(c) - 0xC0) < 0x3E) +#define IS_TRAIL_BYTE(c) (((unsigned)(c) & 0xC0) == 0x80) + + +static bool all_ascii(const ALLEGRO_USTR *us) +{ + const unsigned char *data = (const unsigned char *) _al_bdata(us); + int size = _al_blength(us); + + while (size-- > 0) { + if (*data > 127) + return false; + data++; + } + + return true; +} + + +/* Function: al_ustr_new + */ +ALLEGRO_USTR *al_ustr_new(const char *s) +{ + return _al_bfromcstr(s); +} + + +/* Function: al_ustr_new_from_buffer + */ +ALLEGRO_USTR *al_ustr_new_from_buffer(const char *s, size_t size) +{ + return _al_blk2bstr(s, size); +} + + +/* Function: al_ustr_newf + */ +ALLEGRO_USTR *al_ustr_newf(const char *fmt, ...) +{ + ALLEGRO_USTR *us; + va_list ap; + + us = al_ustr_new(""); + va_start(ap, fmt); + al_ustr_vappendf(us, fmt, ap); + va_end(ap); + return us; +} + + +/* Function: al_ustr_free + */ +void al_ustr_free(ALLEGRO_USTR *us) +{ + _al_bdestroy(us); +} + + +/* Function: al_cstr + */ +const char *al_cstr(const ALLEGRO_USTR *us) +{ + /* May or may not be NUL terminated. */ + return _al_bdata(us); +} + + +/* Function: al_ustr_to_buffer + */ +void al_ustr_to_buffer(const ALLEGRO_USTR *us, char *buffer, int size) +{ + int need; + + if (size <= 0) + return; + /* add 1 for terminating 0 byte */ + need = _al_blength(us) + 1; + if (size > need) + size = need; + _al_sane_strncpy(buffer, _al_bdata(us), size); +} + + +/* Function: al_cstr_dup + */ +char *al_cstr_dup(const ALLEGRO_USTR *us) +{ + return _al_bstr2cstr(us, '\0'); +} + + +/* Function: al_ustr_dup + */ +ALLEGRO_USTR *al_ustr_dup(const ALLEGRO_USTR *us) +{ + return _al_bstrcpy(us); +} + + +/* Function: al_ustr_dup_substr + */ +ALLEGRO_USTR *al_ustr_dup_substr(const ALLEGRO_USTR *us, int start_pos, + int end_pos) +{ + return _al_bmidstr(us, start_pos, end_pos - start_pos); +} + + +/* Function: al_ustr_empty_string + */ +const ALLEGRO_USTR *al_ustr_empty_string(void) +{ + static struct _al_tagbstring empty = _al_bsStatic(""); + return ∅ +} + + +/* Function: al_ref_cstr + */ +const ALLEGRO_USTR *al_ref_cstr(ALLEGRO_USTR_INFO *info, const char *s) +{ + struct _al_tagbstring *tb = (struct _al_tagbstring *) info; + ASSERT(info); + ASSERT(s); + + _al_btfromcstr(*tb, s); + return tb; +} + + +/* Function: al_ref_buffer + */ +const ALLEGRO_USTR *al_ref_buffer(ALLEGRO_USTR_INFO *info, const char *s, size_t size) +{ + struct _al_tagbstring *tb = (struct _al_tagbstring *) info; + ASSERT(s); + + _al_blk2tbstr(*tb, s, size); + return tb; +} + + +/* Function: al_ref_ustr + */ +const ALLEGRO_USTR *al_ref_ustr(ALLEGRO_USTR_INFO *info, const ALLEGRO_USTR *us, + int start_pos, int end_pos) +{ + struct _al_tagbstring *tb = (struct _al_tagbstring *) info; + + _al_bmid2tbstr(*tb, us, start_pos, end_pos - start_pos); + return tb; +} + + +/* Function: al_ustr_size + */ +size_t al_ustr_size(const ALLEGRO_USTR *us) +{ + return _al_blength(us); +} + + +/* Function: al_ustr_length + */ +size_t al_ustr_length(const ALLEGRO_USTR *us) +{ + int pos = 0; + int c = 0; + + while (al_ustr_next(us, &pos)) + c++; + + return c; +} + + +/* Function: al_ustr_offset + */ +int al_ustr_offset(const ALLEGRO_USTR *us, int index) +{ + int pos = 0; + + if (index < 0) + index += al_ustr_length(us); + + while (index-- > 0) { + if (!al_ustr_next(us, &pos)) + return pos; + } + + return pos; +} + + +/* Function: al_ustr_next + */ +bool al_ustr_next(const ALLEGRO_USTR *us, int *pos) +{ + const unsigned char *data = (const unsigned char *) _al_bdata(us); + int size = _al_blength(us); + int c; + + if (*pos >= size) { + return false; + } + + while (++(*pos) < size) { + c = data[*pos]; + if (IS_SINGLE_BYTE(c) || IS_LEAD_BYTE(c)) + break; + } + + return true; +} + + +/* Function: al_ustr_prev + */ +bool al_ustr_prev(const ALLEGRO_USTR *us, int *pos) +{ + const unsigned char *data = (const unsigned char *) _al_bdata(us); + int c; + + if (!data) + return false; + + if (*pos <= 0) + return false; + + while (*pos > 0) { + (*pos)--; + c = data[*pos]; + if (IS_SINGLE_BYTE(c) || IS_LEAD_BYTE(c)) + break; + } + + return true; +} + + +/* Function: al_ustr_get + */ +int32_t al_ustr_get(const ALLEGRO_USTR *ub, int pos) +{ + int32_t c; + int remain; + int32_t minc; + const unsigned char *data; + + c = _al_bchare(ub, pos, -1); + + if (c < 0) { + /* Out of bounds. */ + al_set_errno(ERANGE); + return -1; + } + + if (c <= 0x7F) { + /* Plain ASCII. */ + return c; + } + + if (c <= 0xC1) { + /* Trailing byte of multi-byte sequence or an overlong encoding for + * code point <= 127. + */ + al_set_errno(EILSEQ); + return -2; + } + + if (c <= 0xDF) { + /* 2-byte sequence. */ + c &= 0x1F; + remain = 1; + minc = 0x80; + } + else if (c <= 0xEF) { + /* 3-byte sequence. */ + c &= 0x0F; + remain = 2; + minc = 0x800; + } + else if (c <= 0xF4) { + /* 4-byte sequence. */ + c &= 0x07; + remain = 3; + minc = 0x10000; + } + else { + /* Otherwise invalid. */ + al_set_errno(EILSEQ); + return -2; + } + + if (pos + remain > _al_blength(ub)) { + al_set_errno(EILSEQ); + return -2; + } + + data = (const unsigned char *) _al_bdata(ub); + while (remain--) { + int d = data[++pos]; + + if (!IS_TRAIL_BYTE(d)) { + al_set_errno(EILSEQ); + return -2; + } + + c = (c << 6) | (d & 0x3F); + } + + /* Check for overlong forms, which could be used to bypass security + * validations. We could also check code points aren't above U+10FFFF or in + * the surrogate ranges, but we don't. + */ + + if (c < minc) { + al_set_errno(EILSEQ); + return -2; + } + + return c; +} + + +/* Function: al_ustr_get_next + */ +int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos) +{ + int32_t c = al_ustr_get(us, *pos); + + if (c >= 0) { + (*pos) += al_utf8_width(c); + return c; + } + + if (c == -1) { + /* Past end. */ + return c; + } + + /* Some invalid byte sequence. */ + al_ustr_next(us, pos); + return c; +} + + +/* Function: al_ustr_prev_get + */ +int32_t al_ustr_prev_get(const ALLEGRO_USTR *us, int *pos) +{ + if (al_ustr_prev(us, pos)) { + return al_ustr_get(us, *pos); + } + + /* Past beginning. */ + return -1; +} + + +/* Function: al_ustr_insert + */ +bool al_ustr_insert(ALLEGRO_USTR *us1, int pos, const ALLEGRO_USTR *us2) +{ + return _al_binsert(us1, pos, us2, '\0') == _AL_BSTR_OK; +} + + +/* Function: al_ustr_insert_cstr + */ +bool al_ustr_insert_cstr(ALLEGRO_USTR *us, int pos, const char *s) +{ + ALLEGRO_USTR_INFO info; + + return al_ustr_insert(us, pos, al_ref_cstr(&info, s)); +} + + +/* Function: al_ustr_insert_chr + */ +size_t al_ustr_insert_chr(ALLEGRO_USTR *us, int pos, int32_t c) +{ + uint32_t uc = c; + size_t sz; + + if (uc < 128) { + return (_al_binsertch(us, pos, 1, uc) == _AL_BSTR_OK) ? 1 : 0; + } + + sz = al_utf8_width(c); + if (_al_binsertch(us, pos, sz, '\0') == _AL_BSTR_OK) { + char* data = _al_bdataofs(us, pos); + if (data) + return al_utf8_encode(data, c); + else + return 0; + } + + return 0; +} + + +/* Function: al_ustr_append + */ +bool al_ustr_append(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +{ + return _al_bconcat(us1, us2) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_append_cstr + */ +bool al_ustr_append_cstr(ALLEGRO_USTR *us, const char *s) +{ + return _al_bcatcstr(us, s) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_append_chr + */ +size_t al_ustr_append_chr(ALLEGRO_USTR *us, int32_t c) +{ + uint32_t uc = c; + + if (uc < 128) { + return (_al_bconchar(us, uc) == _AL_BSTR_OK) ? 1 : 0; + } + + return al_ustr_insert_chr(us, al_ustr_size(us), c); +} + + +/* Function: al_ustr_appendf + */ +bool al_ustr_appendf(ALLEGRO_USTR *us, const char *fmt, ...) +{ + va_list ap; + bool rc; + + va_start(ap, fmt); + rc = al_ustr_vappendf(us, fmt, ap); + va_end(ap); + return rc; +} + + +/* Function: al_ustr_vappendf + */ +bool al_ustr_vappendf(ALLEGRO_USTR *us, const char *fmt, va_list ap) +{ + va_list arglist; + int sz; + int rc; + +#ifdef DEBUGMODE + /* Exercise resizing logic more often. */ + sz = 1; +#else + sz = 128; +#endif + + for (;;) { + /* Make a copy of the argument list as vsnprintf() may clobber it. */ + va_copy(arglist, ap); + rc = _al_bvcformata(us, sz, fmt, arglist); + va_end(arglist); + + if (rc >= 0) { + return true; + } + + if (rc == _AL_BSTR_ERR) { + /* A real error? */ + return false; + } + + /* Increase size */ + sz = -rc; + } +} + + +/* Function: al_ustr_remove_chr + */ +bool al_ustr_remove_chr(ALLEGRO_USTR *us, int pos) +{ + int32_t c; + size_t w; + + c = al_ustr_get(us, pos); + if (c < 0) + return false; + + w = al_utf8_width(c); + return _al_bdelete(us, pos, w) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_remove_range + */ +bool al_ustr_remove_range(ALLEGRO_USTR *us, int start_pos, int end_pos) +{ + return _al_bdelete(us, start_pos, end_pos - start_pos) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_truncate + */ +bool al_ustr_truncate(ALLEGRO_USTR *us, int start_pos) +{ + return _al_btrunc(us, start_pos) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_ltrim_ws + */ +bool al_ustr_ltrim_ws(ALLEGRO_USTR *us) +{ + return _al_bltrimws(us) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_rtrim_ws + */ +bool al_ustr_rtrim_ws(ALLEGRO_USTR *us) +{ + return _al_brtrimws(us) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_trim_ws + */ +bool al_ustr_trim_ws(ALLEGRO_USTR *us) +{ + return _al_btrimws(us) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_assign + */ +bool al_ustr_assign(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +{ + return _al_bassign(us1, us2) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_assign_substr + */ +bool al_ustr_assign_substr(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, + int start_pos, int end_pos) +{ + int rc = _al_bassignmidstr(us1, us2, start_pos, end_pos - start_pos); + return rc == _AL_BSTR_OK; +} + + +/* Function: al_ustr_assign_cstr + */ +bool al_ustr_assign_cstr(ALLEGRO_USTR *us1, const char *s) +{ + return _al_bassigncstr(us1, s) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_set_chr + */ +size_t al_ustr_set_chr(ALLEGRO_USTR *us, int start_pos, int32_t c) +{ + int32_t oldc; + size_t oldw; + size_t neww; + int rc; + + oldc = al_ustr_get(us, start_pos); + if (oldc == -2) + return 0; + + oldw = al_utf8_width(oldc); + neww = al_utf8_width(c); + if (neww == 0) + return 0; + + if (oldw > neww) + rc = _al_bdelete(us, start_pos, oldw - neww); + else if (neww > oldw) + rc = _al_binsertch(us, start_pos, neww - oldw, '\0'); + else + rc = _AL_BSTR_OK; + + if (rc == _AL_BSTR_OK) { + char* data = _al_bdataofs(us, start_pos); + if (data) { + return al_utf8_encode(data, c); + } + else { + return 0; + } + } + else { + return 0; + } +} + + +/* Function: al_ustr_replace_range + */ +bool al_ustr_replace_range(ALLEGRO_USTR *us1, int start_pos1, int end_pos1, + const ALLEGRO_USTR *us2) +{ + return _al_breplace(us1, start_pos1, end_pos1 - start_pos1, us2, '\0') + == _AL_BSTR_OK; +} + + +/* Function: al_ustr_find_chr + */ +int al_ustr_find_chr(const ALLEGRO_USTR *us, int start_pos, int32_t c) +{ + char encc[4]; + size_t sizec; + struct _al_tagbstring enctb; + int rc; + + /* Fast path for ASCII characters. */ + if (c < 128) { + rc = _al_bstrchrp(us, c, start_pos); + return (rc == _AL_BSTR_ERR) ? -1 : rc; + } + + /* Non-ASCII. We can simply encode the character into a string and search + * for that. + */ + + sizec = al_utf8_encode(encc, c); + if (!sizec) { + al_set_errno(EINVAL); + return -1; /* error */ + } + + _al_blk2tbstr(enctb, encc, sizec); + rc = _al_binstr(us, start_pos, &enctb); + return (rc == _AL_BSTR_ERR) ? -1 : rc; +} + + +/* Function: al_ustr_rfind_chr + */ +int al_ustr_rfind_chr(const ALLEGRO_USTR *us, int end_pos, int32_t c) +{ + char encc[4]; + size_t sizec; + struct _al_tagbstring enctb; + int rc; + + /* Fast path for ASCII characters. */ + if (c < 128) { + rc = _al_bstrrchrp(us, c, end_pos - 1); + return (rc == _AL_BSTR_ERR) ? -1 : rc; + } + + /* Non-ASCII. We can simply encode the character into a string and search + * for that. + */ + + sizec = al_utf8_encode(encc, c); + if (!sizec) { + al_set_errno(EINVAL); + return -1; /* error */ + } + + _al_blk2tbstr(enctb, encc, sizec); + rc = _al_binstrr(us, end_pos - sizec, &enctb); + return (rc == _AL_BSTR_ERR) ? -1 : rc; +} + + +/* Function: al_ustr_find_set + */ +int al_ustr_find_set(const ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *accept) +{ + int rc; + int32_t c, d; + int pos; + int set_pos; + + /* Fast path for ASCII characters. */ + if (all_ascii(accept)) { + rc = _al_binchr(us, start_pos, accept); + return (rc == _AL_BSTR_ERR) ? -1 : rc; + } + + /* Non-ASCII. */ + pos = 0; + while ((c = al_ustr_get(us, pos)) != -1) { + if (c == -2) { + /* Invalid byte sequence. */ + pos++; + continue; + } + + set_pos = 0; + while ((d = al_ustr_get_next(accept, &set_pos)) != -1) { + if (c == d) + return pos; + } + + pos += al_utf8_width(c); + } + + return -1; +} + + +/* Function: al_ustr_find_set_cstr + */ +int al_ustr_find_set_cstr(const ALLEGRO_USTR *us, int start_pos, + const char *accept) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *accept_us = al_ref_cstr(&info, accept); + + return al_ustr_find_set(us, start_pos, accept_us); +} + + +/* Function: al_ustr_find_cset + */ +int al_ustr_find_cset(const ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *reject) +{ + int rc; + int32_t c, d; + int pos; + int set_pos; + + /* Fast path for ASCII characters. */ + if (all_ascii(reject)) { + rc = _al_bninchr(us, start_pos, reject); + return (rc == _AL_BSTR_ERR) ? -1 : rc; + } + + /* Non-ASCII. */ + pos = 0; + while ((c = al_ustr_get(us, pos)) != -1) { + if (c == -2) { + /* Invalid byte sequence. */ + pos++; + continue; + } + + set_pos = 0; + while ((d = al_ustr_get_next(reject, &set_pos)) != -1) { + if (c == d) + break; + } + + if (d == -1) { + return pos; + } + + pos += al_utf8_width(c); + } + + return -1; +} + + +/* Function: al_ustr_find_cset_cstr + */ +int al_ustr_find_cset_cstr(const ALLEGRO_USTR *us, int start_pos, + const char *reject) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *reject_us = al_ref_cstr(&info, reject); + + return al_ustr_find_cset(us, start_pos, reject_us); +} + + +/* Function: al_ustr_find_str + */ +int al_ustr_find_str(const ALLEGRO_USTR *haystack, int start_pos, + const ALLEGRO_USTR *needle) +{ + int rc = _al_binstr(haystack, start_pos, needle); + return (rc == _AL_BSTR_ERR) ? -1 : rc; +} + + +/* Function: al_ustr_find_cstr + */ +int al_ustr_find_cstr(const ALLEGRO_USTR *haystack, int start_pos, + const char *needle) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *needle_us = al_ref_cstr(&info, needle); + + return al_ustr_find_str(haystack, start_pos, needle_us); +} + + +/* Function: al_ustr_rfind_str + */ +int al_ustr_rfind_str(const ALLEGRO_USTR *haystack, int end_pos, + const ALLEGRO_USTR *needle) +{ + int rc = _al_binstrr(haystack, end_pos - _al_blength(needle), needle); + return (rc == _AL_BSTR_ERR) ? -1 : rc; +} + + +/* Function: al_ustr_rfind_cstr + */ +int al_ustr_rfind_cstr(const ALLEGRO_USTR *haystack, int end_pos, + const char *needle) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *needle_us = al_ref_cstr(&info, needle); + + return al_ustr_rfind_str(haystack, end_pos, needle_us); +} + + +/* Function: al_ustr_find_replace + */ +bool al_ustr_find_replace(ALLEGRO_USTR *us, int start_pos, + const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace) +{ + return _al_bfindreplace(us, find, replace, start_pos) == _AL_BSTR_OK; +} + + +/* Function: al_ustr_find_replace_cstr + */ +bool al_ustr_find_replace_cstr(ALLEGRO_USTR *us, int start_pos, + const char *find, const char *replace) +{ + ALLEGRO_USTR_INFO find_info; + ALLEGRO_USTR_INFO repl_info; + const ALLEGRO_USTR *find_us = al_ref_cstr(&find_info, find); + const ALLEGRO_USTR *repl_us = al_ref_cstr(&repl_info, replace); + + return al_ustr_find_replace(us, start_pos, find_us, repl_us); +} + + +/* Function: al_ustr_equal + */ +bool al_ustr_equal(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +{ + return _al_biseq(us1, us2) == 1; +} + + +/* Function: al_ustr_compare + */ +int al_ustr_compare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +{ + int pos1 = 0; + int pos2 = 0; + + for (;;) { + int32_t c1 = al_ustr_get_next(us1, &pos1); + int32_t c2 = al_ustr_get_next(us2, &pos2); + + if (c1 != c2) { + /* This happens to work even when one of c1 or c2 is -1. */ + return c1 - c2; + } + + if (c1 == -1) /* == c2 */ + return 0; + } +} + + +/* Function: al_ustr_ncompare + */ +int al_ustr_ncompare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int n) +{ + int pos1 = 0; + int pos2 = 0; + + if (n <= 0) + return 0; + + for (;;) { + int32_t c1 = al_ustr_get_next(us1, &pos1); + int32_t c2 = al_ustr_get_next(us2, &pos2); + + if (c1 != c2) { + /* This happens to work even when one of c1 or c2 is -1. */ + return c1 - c2; + } + + if ((c1 == -1) || (--n <= 0)) + return 0; + } +} + + +/* Function: al_ustr_has_prefix + */ +bool al_ustr_has_prefix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +{ + return 0 == _al_bstrncmp(us1, us2, _al_blength(us2)); +} + + +/* Function: al_ustr_has_prefix_cstr + */ +bool al_ustr_has_prefix_cstr(const ALLEGRO_USTR *us1, const char *s2) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us2 = al_ref_cstr(&info, s2); + + return al_ustr_has_prefix(us1, us2); +} + + +/* Function: al_ustr_has_suffix + */ +bool al_ustr_has_suffix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2) +{ + struct _al_tagbstring tb1; + int pos; + + pos = _al_blength(us1) - _al_blength(us2); + _al_bmid2tbstr(tb1, us1, pos, INT_MAX); + return _al_biseq(&tb1, us2); +} + + +/* Function: al_ustr_has_suffix_cstr + */ +bool al_ustr_has_suffix_cstr(const ALLEGRO_USTR *us1, const char *s2) +{ + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *us2 = al_ref_cstr(&info, s2); + + return al_ustr_has_suffix(us1, us2); +} + + +/* Function: al_utf8_width + */ +size_t al_utf8_width(int32_t c) +{ + /* So we don't need to check for negative values nor use unsigned ints + * in the interface, which are a pain. + */ + uint32_t uc = c; + + if (uc <= 0x7f) + return 1; + if (uc <= 0x7ff) + return 2; + if (uc <= 0xffff) + return 3; + if (uc <= 0x10ffff) + return 4; + /* The rest are illegal. */ + return 0; +} + + +/* Function: al_utf8_encode + */ +size_t al_utf8_encode(char s[], int32_t c) +{ + uint32_t uc = c; + + if (uc <= 0x7f) { + s[0] = uc; + return 1; + } + + if (uc <= 0x7ff) { + s[0] = 0xC0 | ((uc >> 6) & 0x1F); + s[1] = 0x80 | (uc & 0x3F); + return 2; + } + + if (uc <= 0xffff) { + s[0] = 0xE0 | ((uc >> 12) & 0x0F); + s[1] = 0x80 | ((uc >> 6) & 0x3F); + s[2] = 0x80 | (uc & 0x3F); + return 3; + } + + if (uc <= 0x10ffff) { + s[0] = 0xF0 | ((uc >> 18) & 0x07); + s[1] = 0x80 | ((uc >> 12) & 0x3F); + s[2] = 0x80 | ((uc >> 6) & 0x3F); + s[3] = 0x80 | (uc & 0x3F); + return 4; + } + + /* Otherwise is illegal. */ + return 0; +} + + +/* Function: al_utf16_width + */ +size_t al_utf16_width(int c) +{ + /* So we don't need to check for negative values nor use unsigned ints + * in the interface, which are a pain. + */ + uint32_t uc = c; + + /* We do not check for invalid code points. */ + if (uc <= 0xffff) + return 2; + if (uc <= 0x10ffff) + return 4; + + /* The rest are illegal. */ + return 0; +} + + +/* Function: al_utf16_encode + */ +size_t al_utf16_encode(uint16_t s[], int32_t c) +{ + uint32_t uc = c; + + if (uc <= 0xffff) { + /* Note: We always assume the native endianness here. */ + s[0] = uc; + return 2; + } + + if (uc <= 0x10ffff) { + uint32_t u_ = uc - 0x10000; + /* Note: We always assume the native endianness here. */ + s[0] = 0xd800 | (u_ >> 10); + s[1] = 0xdc00 | (u_ & 0x3ff); + return 4; + } + + /* Otherwise is illegal. */ + return 0; +} + + +static size_t _al_utf16_get(uint16_t const *s, int n, int *c) +{ + if (s[0] < 0xd800 || s[0] > 0xdfff) { + *c = s[0]; + return 1; + } + if (n < 2) + return 0; + *c = 0x10000 | ((s[0] & 0x3ff) << 10) | (s[1] & 0x3ff); + return 2; +} + + +/* Function: al_ustr_new_from_utf16 + */ +ALLEGRO_USTR *al_ustr_new_from_utf16(uint16_t const *s) +{ + unsigned int i = 0; + ALLEGRO_USTR *ustr = al_ustr_new(""); + while (1) { + int c; + /* We expect the passed string to be 0 terminated, so there are + * always 2 words available. + */ + size_t n = _al_utf16_get(s + i, 2, &c); + /* Note: The string already is 0 terminated. */ + if (c == 0) + break; + al_ustr_append_chr(ustr, c); + i += n; + } + return ustr; +} + + +/* Function: al_ustr_size_utf16 + */ +size_t al_ustr_size_utf16(const ALLEGRO_USTR *us) +{ + int pos = 0; + size_t sz = 0; + while (1) { + int32_t c = al_ustr_get_next(us, &pos); + if (c < 0) + break; + sz += al_utf16_width(c); + } + /* Size of terminating 0 character - al_ustr_get_next will not + * return it. + */ + sz += 2; + return sz; +} + + +/* Function: al_ustr_encode_utf16 + */ +size_t al_ustr_encode_utf16(const ALLEGRO_USTR *us, uint16_t *s, + size_t n) +{ + int pos = 0; + size_t i = 0; + while (1) { + /* Used to hold one encoded UTF-16 character. */ + uint16_t encoded[2] = {0, 0}; + size_t sz; + int32_t c = al_ustr_get_next(us, &pos); + if (c < 0) + break; + sz = al_utf16_encode(encoded, c); + /* Need two bytes for terminating 0. */ + if (i * 2 + sz > n - 2) + break; + s[i++] = encoded[0]; + if (sz == 4) + s[i++] = encoded[1]; + } + /* Append terminating 0 - al_ustr_get_next withheld it. */ + if (i * 2 + 1 < n) + s[i++] = 0; + + return i * 2; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/d3d.h b/allegro/src/win/d3d.h new file mode 100644 index 00000000..348e14c3 --- /dev/null +++ b/allegro/src/win/d3d.h @@ -0,0 +1,86 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_direct3d.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_direct3d.h" +#include "allegro5/internal/aintern_shader.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/platform/alplatf.h" + +#include + +/* The MinGW copy of d3d9.h doesn't currently define this constant. */ +#ifndef D3D9b_SDK_VERSION + #ifdef D3D_DEBUG_INFO + #define D3D9b_SDK_VERSION (31 | 0x80000000) + #else + #define D3D9b_SDK_VERSION 31 + #endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Flexible vertex formats */ +// Fixed pipeline vertex +#define D3DFVF_FIXED_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) +// Programmable pipeline vertex +#define D3DFVF_ALLEGRO_VERTEX (D3DFVF_XYZ | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE4(1)) + +// Vertex structure when using fixed pipeline (otherwise it's ALLEGRO_VERTEX) +struct D3D_FIXED_VERTEX { + float x, y, z; + D3DCOLOR color; + float u, v; +}; + +typedef struct ALLEGRO_SYSTEM_D3D ALLEGRO_SYSTEM_D3D; + +extern LPDIRECT3D9 _al_d3d; + +ALLEGRO_BITMAP_INTERFACE *_al_bitmap_d3d_driver(void); + +int _al_pixel_format_to_d3d(int format); +int _al_d3d_format_to_allegro(int d3d_fmt); +bool _al_d3d_render_to_texture_supported(void); +void _al_d3d_set_bitmap_clip(ALLEGRO_BITMAP *bitmap); + +void _al_d3d_release_default_pool_textures(ALLEGRO_DISPLAY *display); +void _al_d3d_refresh_texture_memory(ALLEGRO_DISPLAY *display); +bool _al_d3d_recreate_bitmap_textures(ALLEGRO_DISPLAY_D3D *disp); +void _al_d3d_set_bitmap_clip(ALLEGRO_BITMAP *bitmap); +bool _al_d3d_supports_separate_alpha_blend(ALLEGRO_DISPLAY *display); +void _al_d3d_bmp_destroy(void); + +void _al_d3d_generate_display_format_list(void); +int _al_d3d_num_display_formats(void); +void _al_d3d_get_nth_format(int i, int *allegro, D3DFORMAT *d3d); +void _al_d3d_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref); +void _al_d3d_destroy_display_format_list(void); +ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_d3d_get_display_settings(int i); +void _al_d3d_resort_display_settings(void); + +#ifdef ALLEGRO_CFG_SHADER_HLSL +void _al_d3d_on_lost_shaders(ALLEGRO_DISPLAY *display); +void _al_d3d_on_reset_shaders(ALLEGRO_DISPLAY *display); +void _al_d3d_init_shaders(void); +void _al_d3d_shutdown_shaders(void); +#endif + +extern ALLEGRO_MUTEX *_al_d3d_lost_device_mutex; + +/* Helper to get smallest fitting power of two. */ +AL_INLINE_STATIC(int, pot, (int x), +{ + int y = 1; + while (y < x) y *= 2; + return y; +}) + +#ifdef __cplusplus +} +#endif diff --git a/allegro/src/win/d3d_bmp.cpp b/allegro/src/win/d3d_bmp.cpp new file mode 100644 index 00000000..1a553426 --- /dev/null +++ b/allegro/src/win/d3d_bmp.cpp @@ -0,0 +1,1034 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Direct3D bitmap driver + * + * By Trent Gamblin. + * + */ + +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/system.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_memblit.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_tri_soft.h" // For ALLEGRO_VERTEX +#include "allegro5/platform/aintwin.h" + +#include "d3d.h" + +ALLEGRO_DEBUG_CHANNEL("d3d") + + +static ALLEGRO_BITMAP_INTERFACE *vt; + +// C++ needs to cast void pointers +#define get_extra(b) ((ALLEGRO_BITMAP_EXTRA_D3D *)\ + (b->parent ? b->parent->extra : b->extra)) + +static bool convert_compressed(LPDIRECT3DTEXTURE9 dest, LPDIRECT3DTEXTURE9 src, + int x, int y, int width, int height) { +#ifdef ALLEGRO_CFG_D3DX9 + bool ok = true; + LPDIRECT3DSURFACE9 dest_texture_surface = NULL; + LPDIRECT3DSURFACE9 src_texture_surface = NULL; + + if (dest->GetSurfaceLevel(0, &dest_texture_surface) != D3D_OK) { + ALLEGRO_ERROR("convert_compressed: GetSurfaceLevel failed on dest.\n"); + ok = false; + } + + if (ok && src->GetSurfaceLevel(0, &src_texture_surface) != D3D_OK) { + ALLEGRO_ERROR("convert_compressed: GetSurfaceLevel failed on src.\n"); + ok = false; + } + + RECT rect; + rect.left = x; + rect.top = y; + rect.right = x + width; + rect.bottom = y + height; + + if (ok && _al_imp_D3DXLoadSurfaceFromSurface && + _al_imp_D3DXLoadSurfaceFromSurface(dest_texture_surface, + NULL, + &rect, + src_texture_surface, + NULL, + &rect, + D3DX_FILTER_NONE, + 0) != D3D_OK) { + ALLEGRO_ERROR("convert_compressed: D3DXLoadSurfaceFromSurface failed.\n"); + ok = false; + } + + int i; + if (src_texture_surface) { + if ((i = src_texture_surface->Release()) != 0) { + ALLEGRO_DEBUG("convert_compressed (src) ref count == %d\n", i); + } + } + if (dest_texture_surface) { + if ((i = dest_texture_surface->Release()) != 0) { + // This can be non-zero + ALLEGRO_DEBUG("convert_compressed (dest) ref count == %d\n", i); + } + } + return ok; +#else + (void)dest; + (void)src; + (void)x; + (void)y; + (void)width; + (void)height; + return false; +#endif +} + +/* Function: al_get_d3d_texture_size + */ +bool al_get_d3d_texture_size(ALLEGRO_BITMAP *bitmap, int *width, int *height) +{ + int bitmap_flags = al_get_bitmap_flags(bitmap); + ASSERT(bitmap); + ASSERT(width); + ASSERT(height); + + if (!(bitmap_flags & _ALLEGRO_INTERNAL_OPENGL) && + !(bitmap_flags & ALLEGRO_MEMORY_BITMAP)) { + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + *width = d3d_bmp->texture_w; + *height = d3d_bmp->texture_h; + return true; + } + else { + *width = 0; + *height = 0; + return false; + } +} + +void _al_d3d_bmp_destroy(void) +{ + al_free(vt); + vt = NULL; +} + +static INLINE void transform_vertex(float* x, float* y, float* z) +{ + al_transform_coordinates_3d(al_get_current_transform(), x, y, z); +} + +/* + * Draw a textured quad + */ +static void d3d_draw_textured_quad( + ALLEGRO_DISPLAY_D3D *disp, ALLEGRO_BITMAP *bmp, ALLEGRO_COLOR tint, + float sx, float sy, float sw, float sh, int flags) +{ + float right; + float bottom; + float tu_start; + float tv_start; + float tu_end; + float tv_end; + int texture_w; + int texture_h; + ALLEGRO_BITMAP_EXTRA_D3D *extra = get_extra(bmp); + + const float z = 0.0f; + + ALLEGRO_DISPLAY* aldisp = (ALLEGRO_DISPLAY*)disp; + + if (aldisp->num_cache_vertices != 0 && (uintptr_t)bmp != aldisp->cache_texture) { + aldisp->vt->flush_vertex_cache(aldisp); + } + aldisp->cache_texture = (uintptr_t)bmp; + + right = sw; + bottom = sh; + + texture_w = extra->texture_w; + texture_h = extra->texture_h; + tu_start = sx / texture_w; + tv_start = sy / texture_h; + tu_end = sw / texture_w + tu_start; + tv_end = sh / texture_h + tv_start; + + if (flags & ALLEGRO_FLIP_HORIZONTAL) { + float temp = tu_start; + tu_start = tu_end; + tu_end = temp; + } + if (flags & ALLEGRO_FLIP_VERTICAL) { + float temp = tv_start; + tv_start = tv_end; + tv_end = temp; + } + +#define ALLEGRO_COLOR_TO_D3D(c) D3DCOLOR_COLORVALUE(c.r, c.g, c.b, c.a) + +#define SET(f) \ + vertices[0].x = 0; \ + vertices[0].y = 0; \ + vertices[0].z = z; \ + vertices[0].color = f(tint); \ + vertices[0].u = tu_start; \ + vertices[0].v = tv_start; \ + \ + vertices[1].x = right; \ + vertices[1].y = 0; \ + vertices[1].z = z; \ + vertices[1].color = f(tint); \ + vertices[1].u = tu_end; \ + vertices[1].v = tv_start; \ + \ + vertices[2].x = right; \ + vertices[2].y = bottom; \ + vertices[2].z = z; \ + vertices[2].color = f(tint); \ + vertices[2].u = tu_end; \ + vertices[2].v = tv_end; \ + \ + vertices[5].x = 0; \ + vertices[5].y = bottom; \ + vertices[5].z = z; \ + vertices[5].color = f(tint); \ + vertices[5].u = tu_start; \ + vertices[5].v = tv_end; \ +\ + if (aldisp->cache_enabled) { \ + transform_vertex(&vertices[0].x, &vertices[0].y, &vertices[0].z); \ + transform_vertex(&vertices[1].x, &vertices[1].y, &vertices[1].z); \ + transform_vertex(&vertices[2].x, &vertices[2].y, &vertices[2].z); \ + transform_vertex(&vertices[5].x, &vertices[5].y, &vertices[5].z); \ + } \ + \ + vertices[3] = vertices[0]; \ + vertices[4] = vertices[2]; + + bool pp = (aldisp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) != 0; + + if (pp) { + ALLEGRO_VERTEX *vertices = (ALLEGRO_VERTEX *)aldisp->vt->prepare_vertex_cache(aldisp, 6); + SET(ALLEGRO_COLOR) + } + else { + D3D_FIXED_VERTEX *vertices = (D3D_FIXED_VERTEX *)aldisp->vt->prepare_vertex_cache(aldisp, 6); + SET(ALLEGRO_COLOR_TO_D3D) + } + + if (!aldisp->cache_enabled) + aldisp->vt->flush_vertex_cache(aldisp); +} + +/* Copy texture memory to bitmap->memory */ +static void d3d_sync_bitmap_memory(ALLEGRO_BITMAP *bitmap) +{ + D3DLOCKED_RECT locked_rect; + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + LPDIRECT3DTEXTURE9 texture; + int bitmap_format = al_get_bitmap_format(bitmap); + + if (_al_d3d_render_to_texture_supported() && + !_al_pixel_format_is_compressed(bitmap_format)) + texture = d3d_bmp->system_texture; + else + texture = d3d_bmp->video_texture; + + if (texture->LockRect(0, &locked_rect, NULL, 0) == D3D_OK) { + int block_size = al_get_pixel_block_size(bitmap_format); + int block_width = al_get_pixel_block_width(bitmap_format); + int block_height = al_get_pixel_block_height(bitmap_format); + int mem_pitch = _al_get_least_multiple(bitmap->w, block_width) * + block_size / block_width; + _al_copy_bitmap_data(locked_rect.pBits, locked_rect.Pitch, + bitmap->memory, mem_pitch, + 0, 0, 0, 0, _al_get_least_multiple(bitmap->w, block_width), + _al_get_least_multiple(bitmap->h, block_height), bitmap_format); + texture->UnlockRect(0); + } + else { + ALLEGRO_ERROR("d3d_sync_bitmap_memory: Couldn't lock texture.\n"); + } +} + +/* Copy bitmap->memory to texture memory */ +static void d3d_sync_bitmap_texture(ALLEGRO_BITMAP *bitmap, + int x, int y, int width, int height) +{ + D3DLOCKED_RECT locked_rect; + RECT rect; + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + LPDIRECT3DTEXTURE9 texture; + int bitmap_format = al_get_bitmap_format(bitmap); + + if (bitmap->parent) return; + + rect.left = x; + rect.top = y; + rect.right = x + width; + rect.bottom = y + height; + + if (_al_d3d_render_to_texture_supported() && + !_al_pixel_format_is_compressed(bitmap_format)) + texture = d3d_bmp->system_texture; + else + texture = d3d_bmp->video_texture; + + if (texture->LockRect(0, &locked_rect, &rect, 0) == D3D_OK) { + int block_size = al_get_pixel_block_size(bitmap_format); + int block_width = al_get_pixel_block_width(bitmap_format); + int mem_pitch = _al_get_least_multiple(bitmap->w, block_width) * + block_size / block_width; + _al_copy_bitmap_data(bitmap->memory, mem_pitch, + locked_rect.pBits, locked_rect.Pitch, + x, y, 0, 0, width, height, bitmap_format); + texture->UnlockRect(0); + } + else { + ALLEGRO_ERROR("d3d_sync_bitmap_texture: Couldn't lock texture to upload.\n"); + } +} + +static void d3d_do_upload(ALLEGRO_BITMAP *bmp, int x, int y, int width, + int height, bool sync_from_memory) +{ + if (sync_from_memory) { + d3d_sync_bitmap_texture(bmp, x, y, width, height); + } + + if (_al_d3d_render_to_texture_supported() + && !_al_pixel_format_is_compressed(al_get_bitmap_format(bmp))) { + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bitmap = get_extra(bmp); + if (d3d_bitmap->display->device->UpdateTexture( + (IDirect3DBaseTexture9 *)d3d_bitmap->system_texture, + (IDirect3DBaseTexture9 *)d3d_bitmap->video_texture) != D3D_OK) { + ALLEGRO_ERROR("d3d_do_upload: Couldn't update texture.\n"); + return; + } + } +} + +/* + * Release all default pool textures. This must be done before + * resetting the device. + */ +void _al_d3d_release_default_pool_textures(ALLEGRO_DISPLAY *disp) +{ + unsigned int i; + + for (i = 0; i < disp->bitmaps._size; i++) { + ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&disp->bitmaps, i); + ALLEGRO_BITMAP *albmp = *bptr; + + if ((al_get_bitmap_flags(albmp) & ALLEGRO_MEMORY_BITMAP) || (albmp->parent)) + continue; + + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(albmp); + if (!d3d_bmp->is_backbuffer && d3d_bmp->render_target) { + d3d_bmp->render_target->Release(); + d3d_bmp->render_target = NULL; + } + if (d3d_bmp->video_texture) { + d3d_bmp->video_texture->Release(); + d3d_bmp->video_texture = NULL; + } + } +} + +static bool d3d_create_textures(ALLEGRO_DISPLAY_D3D *disp, int w, int h, + int flags, + LPDIRECT3DTEXTURE9 *video_texture, LPDIRECT3DTEXTURE9 *system_texture, + int video_format, int system_format) +{ + int levels; + int autogenmipmap; + int err; + bool compressed = _al_pixel_format_is_compressed(video_format); + + if (flags & ALLEGRO_MIPMAP) { + /* "0" for all possible levels, required for auto mipmap generation. */ + levels = 0; + autogenmipmap = D3DUSAGE_AUTOGENMIPMAP; + } + else { + levels = 1; + autogenmipmap = 0; + } + + if (_al_d3d_render_to_texture_supported()) { + if (video_texture) { + int usage = compressed ? 0 : D3DUSAGE_RENDERTARGET; + /* XXX: Compressed video bitmaps are managed, so in principle + * there is no need to manually sync them for device loss. + * It is still necessary to do so for resizing purposes, + * however... not sure there's any real savings to be had here. + */ + D3DPOOL pool = compressed ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT; + err = disp->device->CreateTexture(w, h, levels, + usage | autogenmipmap, + (D3DFORMAT)_al_pixel_format_to_d3d(video_format), pool, + video_texture, NULL); + if (err != D3D_OK && err != D3DOK_NOAUTOGEN) { + ALLEGRO_ERROR("d3d_create_textures: Unable to create video texture.\n"); + return false; + } + } + + if (system_texture) { + err = disp->device->CreateTexture(w, h, 1, + 0, (D3DFORMAT)_al_pixel_format_to_d3d(system_format), D3DPOOL_SYSTEMMEM, + system_texture, NULL); + if (err != D3D_OK) { + ALLEGRO_ERROR("d3d_create_textures: Unable to create system texture.\n"); + if (video_texture && (*video_texture)) { + (*video_texture)->Release(); + *video_texture = NULL; + } + return false; + } + } + + return true; + } + else { + if (video_texture) { + err = disp->device->CreateTexture(w, h, 1, + 0, (D3DFORMAT)_al_pixel_format_to_d3d(video_format), D3DPOOL_MANAGED, + video_texture, NULL); + if (err != D3D_OK) { + ALLEGRO_ERROR("d3d_create_textures: Unable to create video texture (no render-to-texture).\n"); + return false; + } + } + + return true; + } +} + +static ALLEGRO_BITMAP + *d3d_create_bitmap_from_surface(LPDIRECT3DSURFACE9 surface, + int format, int flags) +{ + ALLEGRO_BITMAP *bitmap; + ALLEGRO_BITMAP_EXTRA_D3D *extra; + D3DSURFACE_DESC desc; + D3DLOCKED_RECT surf_locked_rect; + D3DLOCKED_RECT sys_locked_rect; + unsigned int y; + ASSERT(!_al_pixel_format_is_compressed(format)); + + if (surface->GetDesc(&desc) != D3D_OK) { + ALLEGRO_ERROR("d3d_create_bitmap_from_surface: GetDesc failed.\n"); + return NULL; + } + + if (surface->LockRect(&surf_locked_rect, 0, D3DLOCK_READONLY) != D3D_OK) { + ALLEGRO_ERROR("d3d_create_bitmap_from_surface: LockRect failed.\n"); + return NULL; + } + + bitmap = _al_create_bitmap_params(al_get_current_display(), + desc.Width, desc.Height, format, flags, 0, 0); + if (!bitmap) { + surface->UnlockRect(); + return NULL; + } + + extra = get_extra(bitmap); + + if (extra->system_texture->LockRect(0, &sys_locked_rect, 0, 0) != D3D_OK) { + surface->UnlockRect(); + al_destroy_bitmap(bitmap); + ALLEGRO_ERROR("d3d_create_bitmap_from_surface: Lock system texture failed.\n"); + return NULL; + } + + for (y = 0; y < desc.Height; y++) { + memcpy( + ((char*)sys_locked_rect.pBits)+(sys_locked_rect.Pitch*y), + ((char*)surf_locked_rect.pBits)+(surf_locked_rect.Pitch*y), + desc.Width*al_get_pixel_size(format) + ); + } + + surface->UnlockRect(); + extra->system_texture->UnlockRect(0); + + + if (extra->display->device->UpdateTexture( + (IDirect3DBaseTexture9 *)extra->system_texture, + (IDirect3DBaseTexture9 *)extra->video_texture) != D3D_OK) { + ALLEGRO_ERROR("d3d_create_bitmap_from_surface: Couldn't update texture.\n"); + } + + return bitmap; +} + +/* Copies video texture to system texture and bitmap->memory */ +static bool _al_d3d_sync_bitmap(ALLEGRO_BITMAP *dest) +{ + ALLEGRO_BITMAP_EXTRA_D3D *d3d_dest; + LPDIRECT3DSURFACE9 system_texture_surface; + LPDIRECT3DSURFACE9 video_texture_surface; + bool ok; + UINT i; + + if (!_al_d3d_render_to_texture_supported()) { + ALLEGRO_ERROR("Render-to-texture not supported.\n"); + return false; + } + + if (dest->locked) { + ALLEGRO_ERROR("Already locked.\n"); + return false; + } + + d3d_dest = get_extra(dest); + + if (d3d_dest->system_texture == NULL || d3d_dest->video_texture == NULL) { + ALLEGRO_ERROR("A texture is null.\n"); + return false; + } + + if (dest->parent) { + dest = dest->parent; + } + + ok = true; + system_texture_surface = NULL; + video_texture_surface = NULL; + + if (d3d_dest->system_texture->GetSurfaceLevel( + 0, &system_texture_surface) != D3D_OK) { + ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetSurfaceLevel failed while updating system texture.\n"); + ok = false; + } + + if (ok && d3d_dest->video_texture->GetSurfaceLevel( + 0, &video_texture_surface) != D3D_OK) { + ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetSurfaceLevel failed while updating system texture.\n"); + ok = false; + } + + if (ok && d3d_dest->display->device->GetRenderTargetData( + video_texture_surface, + system_texture_surface) != D3D_OK) { + ALLEGRO_ERROR("_al_d3d_sync_bitmap: GetRenderTargetData failed.\n"); + ok = false; + } + + if (system_texture_surface) { + if ((i = system_texture_surface->Release()) != 0) { + ALLEGRO_DEBUG("_al_d3d_sync_bitmap (system) ref count == %d\n", i); + } + } + if (video_texture_surface) { + if ((i = video_texture_surface->Release()) != 0) { + // This can be non-zero + ALLEGRO_DEBUG("_al_d3d_sync_bitmap (video) ref count == %d\n", i); + } + } + + if (ok) { + d3d_sync_bitmap_memory(dest); + } + + return ok; +} + +// Copy texture to system memory +static void d3d_backup_dirty_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_DISPLAY *display = bitmap->_display; + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)display; + + if (d3d_display->device_lost) + return; + + if (!_al_d3d_render_to_texture_supported()) + return; + + al_lock_mutex(_al_d3d_lost_device_mutex); + + ALLEGRO_BITMAP_EXTRA_D3D *extra = get_extra(bitmap); + int bitmap_flags = al_get_bitmap_flags(bitmap); + if (!( + (bitmap_flags & ALLEGRO_MEMORY_BITMAP) || + (bitmap_flags & ALLEGRO_NO_PRESERVE_TEXTURE) || + !bitmap->dirty || + extra->is_backbuffer || + bitmap->parent + )) + { + if (_al_pixel_format_is_compressed(al_get_bitmap_format(bitmap))) + d3d_sync_bitmap_memory(bitmap); + else + _al_d3d_sync_bitmap(bitmap); + } + + bitmap->dirty = false; + + al_unlock_mutex(_al_d3d_lost_device_mutex); +} + +/* + * Called after the resize is done. + */ +bool _al_d3d_recreate_bitmap_textures(ALLEGRO_DISPLAY_D3D *disp) +{ + unsigned int i; + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)disp; + + for (i = 0; i < display->bitmaps._size; i++) { + ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&display->bitmaps, i); + ALLEGRO_BITMAP *bmp = *bptr; + ALLEGRO_BITMAP_EXTRA_D3D *extra = get_extra(bmp); + + if ((void *)_al_get_bitmap_display(bmp) == (void *)disp) { + int block_width = + al_get_pixel_block_width(al_get_bitmap_format(bmp)); + int block_height = + al_get_pixel_block_height(al_get_bitmap_format(bmp)); + if (!d3d_create_textures(disp, extra->texture_w, + extra->texture_h, + al_get_bitmap_flags(bmp), + &extra->video_texture, + &extra->system_texture, + al_get_bitmap_format(bmp), + extra->system_format)) + return false; + d3d_do_upload(bmp, 0, 0, + _al_get_least_multiple(bmp->w, block_width), + _al_get_least_multiple(bmp->h, block_height), true); + } + } + + return true; +} + +/* + * Refresh the texture memory. This must be done after a device is + * lost or after it is reset. + */ +void _al_d3d_refresh_texture_memory(ALLEGRO_DISPLAY *display) +{ + unsigned int i; + + /* Refresh video hardware textures */ + for (i = 0; i < display->bitmaps._size; i++) { + ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&display->bitmaps, i); + ALLEGRO_BITMAP *bmp = *bptr; + ALLEGRO_BITMAP_EXTRA_D3D *extra = get_extra(bmp); + ALLEGRO_DISPLAY_D3D *bmps_display = + (ALLEGRO_DISPLAY_D3D *)_al_get_bitmap_display(bmp); + int bitmap_flags = al_get_bitmap_flags(bmp); + + if ((bitmap_flags & ALLEGRO_MEMORY_BITMAP) || bmp->parent) { + continue; + } + + d3d_create_textures(bmps_display, extra->texture_w, + extra->texture_h, bitmap_flags, + &extra->video_texture, /*&bmp->system_texture*/0, al_get_bitmap_format(bmp), 0); + if (!(bitmap_flags & ALLEGRO_NO_PRESERVE_TEXTURE)) { + int block_width = al_get_pixel_block_width(al_get_bitmap_format(bmp)); + int block_height = al_get_pixel_block_height(al_get_bitmap_format(bmp)); + d3d_sync_bitmap_texture(bmp, + 0, 0, + _al_get_least_multiple(bmp->w, block_width), + _al_get_least_multiple(bmp->h, block_height)); + if (_al_d3d_render_to_texture_supported() + && !_al_pixel_format_is_compressed(al_get_bitmap_format(bmp))) { + extra->display->device->UpdateTexture( + (IDirect3DBaseTexture9 *)extra->system_texture, + (IDirect3DBaseTexture9 *)extra->video_texture); + } + } + } +} + +static bool d3d_upload_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + ALLEGRO_SYSTEM *system = al_get_system_driver(); + int bitmap_format = al_get_bitmap_format(bitmap); + int system_format = d3d_bmp->system_format; + int block_width = al_get_pixel_block_width(bitmap_format); + int block_height = al_get_pixel_block_height(bitmap_format); + int w = _al_get_least_multiple(bitmap->w, block_width); + int h = _al_get_least_multiple(bitmap->h, block_height); + + if (d3d_bmp->display->device_lost) + return false; + + if (d3d_bmp->initialized != true) { + bool non_pow2 = al_have_d3d_non_pow2_texture_support(); + bool non_square = al_have_d3d_non_square_texture_support(); + + if (non_pow2 && non_square) { + // Any shape and size + d3d_bmp->texture_w = w; + d3d_bmp->texture_h = h; + } + else if (non_pow2) { + // Must be square + int max = _ALLEGRO_MAX(w, h); + d3d_bmp->texture_w = max; + d3d_bmp->texture_h = max; + } + else { + // Must be POW2 + d3d_bmp->texture_w = pot(w); + d3d_bmp->texture_h = pot(h); + } + + // Some cards/drivers don't like small textures + if (d3d_bmp->texture_w < system->min_bitmap_size) d3d_bmp->texture_w = system->min_bitmap_size; + if (d3d_bmp->texture_h < system->min_bitmap_size) d3d_bmp->texture_h = system->min_bitmap_size; + + ASSERT(d3d_bmp->texture_w % block_width == 0); + ASSERT(d3d_bmp->texture_h % block_height == 0); + + if (d3d_bmp->video_texture == 0) + if (!d3d_create_textures(d3d_bmp->display, + d3d_bmp->texture_w, + d3d_bmp->texture_h, + al_get_bitmap_flags(bitmap), + &d3d_bmp->video_texture, + &d3d_bmp->system_texture, + bitmap_format, + system_format)) { + return false; + } + + d3d_bmp->initialized = true; + } + + d3d_do_upload(bitmap, 0, 0, w, h, false); + + return true; +} + +static void d3d_draw_bitmap_region( + ALLEGRO_BITMAP *src, + ALLEGRO_COLOR tint, + float sx, float sy, float sw, float sh, int flags) +{ + ALLEGRO_BITMAP *dest = al_get_target_bitmap(); + ALLEGRO_BITMAP_EXTRA_D3D *d3d_dest = get_extra(dest); + ALLEGRO_BITMAP_EXTRA_D3D *d3d_src = get_extra(src); + + ASSERT(src->parent == NULL); + + if (!_al_d3d_render_to_texture_supported()) { + _al_draw_bitmap_region_memory(src, tint, + (int)sx, (int)sy, (int)sw, (int)sh, 0, 0, + (int)flags); + return; + } + + if (d3d_dest->display->device_lost) + return; + + _al_d3d_set_bitmap_clip(dest); + + /* For sub-bitmaps */ + if (dest->parent) { + dest = dest->parent; + d3d_dest = get_extra(dest); + } + + if (d3d_src->is_backbuffer) { + IDirect3DSurface9 *surface; + D3DSURFACE_DESC desc; + if (d3d_src->display->render_target->GetDesc(&desc) != D3D_OK) { + ALLEGRO_ERROR("d3d_draw_bitmap_region: GetDesc failed.\n"); + return; + } + if (desc.MultiSampleType == D3DMULTISAMPLE_NONE) { + surface = d3d_src->display->render_target; + } + else { + RECT r; + if (d3d_src->display->device->CreateRenderTarget( + desc.Width, + desc.Height, + desc.Format, + D3DMULTISAMPLE_NONE, + 0, + TRUE, + &surface, + NULL + ) != D3D_OK) { + ALLEGRO_ERROR( + "d3d_draw_bitmap_region: CreateRenderTarget failed.\n"); + return; + } + r.top = 0; + r.left = 0; + r.right = desc.Width; + r.bottom = desc.Height; + if (d3d_src->display->device->StretchRect( + d3d_src->display->render_target, + &r, + surface, + &r, + D3DTEXF_NONE + ) != D3D_OK) { + ALLEGRO_ERROR("d3d_draw_bitmap_region: StretchRect failed.\n"); + surface->Release(); + return; + } + } + ALLEGRO_BITMAP *tmp_bmp = d3d_create_bitmap_from_surface( + surface, + al_get_bitmap_format(src), + al_get_bitmap_flags(src) + ); + if (tmp_bmp) { + d3d_draw_bitmap_region(tmp_bmp, tint, + sx, sy, sw, sh, flags); + al_destroy_bitmap(tmp_bmp); + if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) { + surface->Release(); + } + } + return; + } + + _al_d3d_set_blender(d3d_dest->display); + + d3d_draw_textured_quad( + d3d_dest->display, src, tint, + sx, sy, sw, sh, flags); +} + +static ALLEGRO_LOCKED_REGION *d3d_lock_region(ALLEGRO_BITMAP *bitmap, + int x, int y, int w, int h, int format, + int flags) +{ + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + int bitmap_format = al_get_bitmap_format(bitmap); + int system_format = d3d_bmp->system_format; + + if (d3d_bmp->display->device_lost) + return NULL; + + RECT rect; + DWORD Flags = flags & ALLEGRO_LOCK_READONLY ? D3DLOCK_READONLY : 0; + int f = _al_get_real_pixel_format(al_get_current_display(), format); + if (f < 0) { + return NULL; + } + + rect.left = x; + rect.right = x + w; + rect.top = y; + rect.bottom = y + h; + + if (d3d_bmp->is_backbuffer) { + ALLEGRO_DISPLAY_D3D *d3d_disp = + (ALLEGRO_DISPLAY_D3D *)_al_get_bitmap_display(bitmap); + if (d3d_disp->render_target->LockRect(&d3d_bmp->locked_rect, &rect, Flags) != D3D_OK) { + ALLEGRO_ERROR("LockRect failed in d3d_lock_region.\n"); + return NULL; + } + } + else { + LPDIRECT3DTEXTURE9 texture; + if (_al_pixel_format_is_compressed(bitmap_format)) { + if (!(flags & ALLEGRO_LOCK_WRITEONLY)) { + if(!convert_compressed( + d3d_bmp->system_texture, d3d_bmp->video_texture, + x, y, w, h)) { + ALLEGRO_ERROR("Could not decompress.\n"); + return NULL; + } + } + texture = d3d_bmp->system_texture; + } + else if (_al_d3d_render_to_texture_supported()) { + /* + * Sync bitmap->memory with texture + */ + bitmap->locked = false; + if (!(flags & ALLEGRO_LOCK_WRITEONLY) && !_al_d3d_sync_bitmap(bitmap)) { + return NULL; + } + bitmap->locked = true; + texture = d3d_bmp->system_texture; + } + else { + texture = d3d_bmp->video_texture; + } + if (texture->LockRect(0, &d3d_bmp->locked_rect, &rect, Flags) != D3D_OK) { + ALLEGRO_ERROR("LockRect failed in d3d_lock_region.\n"); + return NULL; + } + } + + if (format == ALLEGRO_PIXEL_FORMAT_ANY || system_format == format || system_format == f) { + bitmap->locked_region.data = d3d_bmp->locked_rect.pBits; + bitmap->locked_region.format = system_format; + bitmap->locked_region.pitch = d3d_bmp->locked_rect.Pitch; + bitmap->locked_region.pixel_size = al_get_pixel_size(system_format); + } + else { + bitmap->locked_region.pitch = al_get_pixel_size(f) * w; + bitmap->locked_region.data = al_malloc(bitmap->locked_region.pitch*h); + bitmap->locked_region.format = f; + bitmap->locked_region.pixel_size = al_get_pixel_size(f); + if (!(bitmap->lock_flags & ALLEGRO_LOCK_WRITEONLY)) { + _al_convert_bitmap_data( + d3d_bmp->locked_rect.pBits, system_format, d3d_bmp->locked_rect.Pitch, + bitmap->locked_region.data, f, bitmap->locked_region.pitch, + 0, 0, 0, 0, w, h); + } + } + + return &bitmap->locked_region; +} + +static void d3d_unlock_region(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + int system_format = d3d_bmp->system_format; + + if (bitmap->locked_region.format != 0 && bitmap->locked_region.format != system_format) { + if (!(bitmap->lock_flags & ALLEGRO_LOCK_READONLY)) { + _al_convert_bitmap_data( + bitmap->locked_region.data, bitmap->locked_region.format, bitmap->locked_region.pitch, + d3d_bmp->locked_rect.pBits, system_format, d3d_bmp->locked_rect.Pitch, + 0, 0, 0, 0, bitmap->lock_w, bitmap->lock_h); + } + al_free(bitmap->locked_region.data); + } + + if (d3d_bmp->is_backbuffer) { + ALLEGRO_DISPLAY_D3D *d3d_disp = + (ALLEGRO_DISPLAY_D3D *)_al_get_bitmap_display(bitmap); + d3d_disp->render_target->UnlockRect(); + } + else { + LPDIRECT3DTEXTURE9 texture; + int bitmap_format = al_get_bitmap_format(bitmap); + bool compressed = _al_pixel_format_is_compressed(bitmap_format); + if (_al_d3d_render_to_texture_supported() || compressed) + texture = d3d_bmp->system_texture; + else + texture = d3d_bmp->video_texture; + texture->UnlockRect(0); + if (bitmap->lock_flags & ALLEGRO_LOCK_READONLY) + return; + + if (compressed) { + int block_width = al_get_pixel_block_width(bitmap_format); + int block_height = al_get_pixel_block_height(bitmap_format); + int xc = (bitmap->lock_x / block_width) * block_width; + int yc = (bitmap->lock_y / block_height) * block_height; + int wc = + _al_get_least_multiple(bitmap->lock_x + bitmap->lock_w, block_width) - xc; + int hc = + _al_get_least_multiple(bitmap->lock_y + bitmap->lock_h, block_height) - yc; + if(!convert_compressed( + d3d_bmp->video_texture, d3d_bmp->system_texture, xc, yc, wc, hc)) { + ALLEGRO_ERROR("Could not compress.\n"); + } + } + else { + d3d_do_upload(bitmap, bitmap->lock_x, bitmap->lock_y, + bitmap->lock_w, bitmap->lock_h, false); + } + } +} + + +static void d3d_update_clipping_rectangle(ALLEGRO_BITMAP *bitmap) +{ + _al_d3d_set_bitmap_clip(bitmap); +} + + +static ALLEGRO_LOCKED_REGION *d3d_lock_compressed_region( + ALLEGRO_BITMAP *bitmap, int x, int y, int w, int h, + int flags) +{ + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + int bitmap_format = al_get_bitmap_format(bitmap); + + if (d3d_bmp->display->device_lost) + return NULL; + + ASSERT(_al_pixel_format_is_compressed(bitmap_format)); + + RECT rect; + DWORD Flags = flags & ALLEGRO_LOCK_READONLY ? D3DLOCK_READONLY : 0; + + rect.left = x; + rect.right = x + w; + rect.top = y; + rect.bottom = y + h; + + if (d3d_bmp->video_texture->LockRect(0, &d3d_bmp->locked_rect, &rect, Flags) != D3D_OK) { + ALLEGRO_ERROR("LockRect failed in d3d_lock_region.\n"); + return NULL; + } + + bitmap->locked_region.data = d3d_bmp->locked_rect.pBits; + bitmap->locked_region.format = bitmap_format; + bitmap->locked_region.pitch = d3d_bmp->locked_rect.Pitch; + bitmap->locked_region.pixel_size = al_get_pixel_block_size(bitmap_format); + + return &bitmap->locked_region; +} + + +static void d3d_unlock_compressed_region(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + ASSERT(_al_pixel_format_is_compressed(al_get_bitmap_format(bitmap))); + + d3d_bmp->video_texture->UnlockRect(0); +} + + +/* Obtain a reference to this driver. */ +ALLEGRO_BITMAP_INTERFACE *_al_bitmap_d3d_driver(void) +{ + if (vt) + return vt; + + vt = (ALLEGRO_BITMAP_INTERFACE *)al_malloc(sizeof *vt); + memset(vt, 0, sizeof *vt); + + vt->draw_bitmap_region = d3d_draw_bitmap_region; + vt->upload_bitmap = d3d_upload_bitmap; + vt->update_clipping_rectangle = NULL; + vt->destroy_bitmap = _al_d3d_destroy_bitmap; + vt->lock_region = d3d_lock_region; + vt->unlock_region = d3d_unlock_region; + vt->lock_compressed_region = d3d_lock_compressed_region; + vt->unlock_compressed_region = d3d_unlock_compressed_region; + vt->update_clipping_rectangle = d3d_update_clipping_rectangle; + vt->backup_dirty_bitmap = d3d_backup_dirty_bitmap; + + return vt; +} + diff --git a/allegro/src/win/d3d_d3dx9.cpp b/allegro/src/win/d3d_d3dx9.cpp new file mode 100644 index 00000000..76c7cd15 --- /dev/null +++ b/allegro/src/win/d3d_d3dx9.cpp @@ -0,0 +1,126 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * D3DX9 DLL dynamic loading. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_direct3d.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_direct3d.h" + +#ifdef ALLEGRO_CFG_D3DX9 + +#include +#include + +#include "d3d.h" + +ALLEGRO_DEBUG_CHANNEL("d3dx9") + +// DXSDK redistributable install d3dx9_xx.dll from version +// 24 to 43. It's unlikely that any new version will come, +// since HLSL compiler was moved to D3DCompiler_xx.dll and +// most recent versions of this utility library are bound +// to DirectX 11. +// +// However, if any new version appears anyway, this range +// should be changed. +#define D3DX9_MIN_VERSION 24 +#define D3DX9_MAX_VERSION 43 + +static HMODULE _imp_d3dx9_module = 0; +_ALLEGRO_D3DXCREATEEFFECTPROC _al_imp_D3DXCreateEffect = NULL; +_ALLEGRO_D3DXLSFLSPROC _al_imp_D3DXLoadSurfaceFromSurface = NULL; + +extern "C" +void _al_unload_d3dx9_module() +{ + FreeLibrary(_imp_d3dx9_module); + _imp_d3dx9_module = NULL; +} + +static bool _imp_load_d3dx9_module_version(int version) +{ + char module_name[16]; + + // Sanity check + // Comented out, to not reject choice of the user if any new version + // appears. See force_d3dx9_version entry in config file. + /* + if (version < 24 || version > 43) { + ALLEGRO_ERROR("Error: Requested version (%d) of D3DX9 library is invalid.\n", version); + return false; + } + */ + + sprintf(module_name, "d3dx9_%d.dll", version); + + _imp_d3dx9_module = _al_win_safe_load_library(module_name); + if (NULL == _imp_d3dx9_module) + return false; + + _al_imp_D3DXCreateEffect = (_ALLEGRO_D3DXCREATEEFFECTPROC)GetProcAddress(_imp_d3dx9_module, "D3DXCreateEffect"); + if (NULL == _al_imp_D3DXCreateEffect) { + FreeLibrary(_imp_d3dx9_module); + _imp_d3dx9_module = NULL; + return false; + } + + _al_imp_D3DXLoadSurfaceFromSurface = + (_ALLEGRO_D3DXLSFLSPROC)GetProcAddress(_imp_d3dx9_module, "D3DXLoadSurfaceFromSurface"); + if (NULL == _al_imp_D3DXLoadSurfaceFromSurface) { + FreeLibrary(_imp_d3dx9_module); + _imp_d3dx9_module = NULL; + return false; + } + + ALLEGRO_INFO("Module \"%s\" loaded.\n", module_name); + + return true; +} + +extern "C" +bool _al_load_d3dx9_module() +{ + long version; + char const *value; + + if (_imp_d3dx9_module) { + return true; + } + + value = al_get_config_value(al_get_system_config(), + "shader", "force_d3dx9_version"); + if (value) { + errno = 0; + version = strtol(value, NULL, 10); + if (errno) { + ALLEGRO_ERROR("Failed to override D3DX9 version. \"%s\" is not valid integer number.\n", value); + return false; + } + else + return _imp_load_d3dx9_module_version((int)version); + } + + // Iterate over all valid versions. + for (version = D3DX9_MAX_VERSION; version >= D3DX9_MIN_VERSION; version--) + if (_imp_load_d3dx9_module_version((int)version)) + return true; + + ALLEGRO_ERROR("Failed to load D3DX9 library. Library is not installed.\n"); + + return false; +} + +#endif diff --git a/allegro/src/win/d3d_disp.cpp b/allegro/src/win/d3d_disp.cpp new file mode 100644 index 00000000..c44314bb --- /dev/null +++ b/allegro/src/win/d3d_disp.cpp @@ -0,0 +1,3019 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Direct3D display driver + * + * By Trent Gamblin. + * + */ + +#include + +#include +#include +#include +#include + +#include "allegro5/allegro.h" + +#include "allegro5/system.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/internal/aintern_tri_soft.h" // For ALLEGRO_VERTEX +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/internal/aintern_wclipboard.h" +#include "allegro5/platform/aintwin.h" + +#include "d3d.h" + +// Based on the code in but that header is not +// available on Windows 7 SDK and earlier. +static BOOL is_windows_vista_or_greater() { + OSVERSIONINFOEX info; + ULONGLONG mask = 0; + VER_SET_CONDITION(mask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(mask, VER_MINORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + memset(&info, 0, sizeof(info)); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + info.dwMajorVersion = 6; + + return VerifyVersionInfo(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, mask) != FALSE; +} + +static void d3d_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); +static void d3d_update_transformation(ALLEGRO_DISPLAY* disp, ALLEGRO_BITMAP *target); +static bool d3d_init_display(); + +// C++ needs to cast void pointers +#define get_extra(b) ((ALLEGRO_BITMAP_EXTRA_D3D *)\ + (b->parent ? b->parent->extra : b->extra)) + +static const char* _al_d3d_module_name = "d3d9.dll"; + +ALLEGRO_DEBUG_CHANNEL("d3d") + +static ALLEGRO_DISPLAY_INTERFACE *vt = 0; + +static HMODULE _al_d3d_module = 0; + +typedef LPDIRECT3D9 (WINAPI *DIRECT3DCREATE9PROC)(UINT); + +static DIRECT3DCREATE9PROC _al_d3d_create = (DIRECT3DCREATE9PROC)NULL; + +#ifdef ALLEGRO_CFG_D3D9EX +typedef HRESULT (WINAPI *DIRECT3DCREATE9EXPROC)(UINT, LPDIRECT3D9EX*); + +static DIRECT3DCREATE9EXPROC _al_d3d_create_ex = (DIRECT3DCREATE9EXPROC)NULL; +#endif + +LPDIRECT3D9 _al_d3d = 0; + +static D3DPRESENT_PARAMETERS d3d_pp; + +static HWND fullscreen_focus_window; +static bool ffw_set = false; + +static bool d3d_can_wait_for_vsync; + +static bool render_to_texture_supported = true; +static bool is_vista = false; +static int num_faux_fullscreen_windows = 0; +static bool already_fullscreen = false; /* real fullscreen */ + +static ALLEGRO_MUTEX *present_mutex; +ALLEGRO_MUTEX *_al_d3d_lost_device_mutex; + +#define FOURCC(c0, c1, c2, c3) ((int)(c0) | ((int)(c1) << 8) | ((int)(c2) << 16) | ((int)(c3) << 24)) + +/* + * These parameters cannot be gotten by the display thread because + * they're thread local. We get them in the calling thread first. + */ +typedef struct D3D_DISPLAY_PARAMETERS { + ALLEGRO_DISPLAY_D3D *display; + volatile bool init_failed; + HANDLE AckEvent; + int window_x, window_y; + /* Not owned. */ + const char *window_title; +} D3D_DISPLAY_PARAMETERS; + + +static int allegro_formats[] = { + ALLEGRO_PIXEL_FORMAT_ANY, + ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_XRGB_8888, + ALLEGRO_PIXEL_FORMAT_ARGB_8888, + //ALLEGRO_PIXEL_FORMAT_ARGB_4444, this format seems not to be allowed + ALLEGRO_PIXEL_FORMAT_RGB_565, + //ALLEGRO_PIXEL_FORMAT_ARGB_1555, this format seems not to be allowed + ALLEGRO_PIXEL_FORMAT_ABGR_F32, + ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3, + ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5, + -1 +}; + +/* Mapping of Allegro formats to D3D formats */ +static int d3d_formats[] = { + ALLEGRO_PIXEL_FORMAT_ANY, + ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA, + ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA, + D3DFMT_X8R8G8B8, + D3DFMT_A8R8G8B8, + //D3DFMT_A4R4G4B4, + D3DFMT_R5G6B5, + //D3DFMT_A1R5G5B5, + D3DFMT_A32B32G32R32F, + D3DFMT_L8, + FOURCC('D', 'X', 'T', '1'), + FOURCC('D', 'X', 'T', '3'), + FOURCC('D', 'X', 'T', '5'), + -1 +}; + +static void (*d3d_release_callback)(ALLEGRO_DISPLAY *display) = NULL; +static void (*d3d_restore_callback)(ALLEGRO_DISPLAY *display) = NULL; + +#define ERR(e) case e: return #e; +static char const *_al_d3d_error_string(HRESULT e) +{ + switch (e) { + ERR(D3D_OK) + ERR(D3DERR_NOTAVAILABLE) + ERR(D3DERR_DEVICELOST) + ERR(D3DERR_INVALIDCALL) + ERR(D3DERR_OUTOFVIDEOMEMORY) + ERR(E_OUTOFMEMORY) + } + return "UNKNOWN"; +} +#undef ERR + +static D3DFORMAT d3d_get_depth_stencil_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings) +{ + struct DEPTH_STENCIL_DESC { + int d; + int s; + D3DFORMAT format; + }; + + DEPTH_STENCIL_DESC formats[] = { + { 0, 0, (D3DFORMAT)0 }, + { 32, 0, D3DFMT_D32 }, + { 15, 1, D3DFMT_D15S1 }, + { 24, 8, D3DFMT_D24S8 }, + { 24, 0, D3DFMT_D24X8 }, + { 24, 4, D3DFMT_D24X4S4 }, + { 16, 0, D3DFMT_D16 }, + { -1, -1, (D3DFORMAT)0 } + }; + + + for (int i = 0; formats[i].d >= 0; i++) { + if (settings->settings[ALLEGRO_DEPTH_SIZE] == formats[i].d && + settings->settings[ALLEGRO_STENCIL_SIZE] == formats[i].s) + return formats[i].format; + } + + return (D3DFORMAT)0; +} + +static void d3d_call_callbacks(_AL_VECTOR *v, ALLEGRO_DISPLAY *display) +{ + int i; + for (i = 0; i < (int)v->_size; i++) { + void (**callback)(ALLEGRO_DISPLAY *) = (void (**)(ALLEGRO_DISPLAY *))_al_vector_ref(v, i); + (*callback)(display); + } +} + +/* Function: al_set_d3d_device_release_callback + */ +void al_set_d3d_device_release_callback( + void (*callback)(ALLEGRO_DISPLAY *display)) +{ + d3d_release_callback = callback; +} + +/* Function: al_set_d3d_device_restore_callback + */ +void al_set_d3d_device_restore_callback( + void (*callback)(ALLEGRO_DISPLAY *display)) +{ + d3d_restore_callback = callback; +} + +bool _al_d3d_supports_separate_alpha_blend(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)display; + return d3d_disp->supports_separate_alpha_blend; +} + +/* Function: al_have_d3d_non_pow2_texture_support + */ +bool al_have_d3d_non_pow2_texture_support(void) +{ + D3DCAPS9 caps; + int adapter = al_get_new_display_adapter(); + + if (!_al_d3d && !d3d_init_display()) + return false; + if (adapter < 0) + adapter = 0; + + /* This might have to change for multihead */ + if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_HAL, &caps) != D3D_OK) { + if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_REF, &caps) != D3D_OK) { + return false; + } + } + + if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0) { + return true; + } + + return false; +} + +static int d3d_get_max_texture_size(int adapter) +{ + D3DCAPS9 caps; + + if (!_al_d3d && !d3d_init_display()) + return -1; + + if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_HAL, &caps) != D3D_OK) { + if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_REF, &caps) != D3D_OK) { + return -1; + } + } + + return _ALLEGRO_MIN(caps.MaxTextureWidth, caps.MaxTextureHeight); +} + +/* Function: al_have_d3d_non_square_texture_support + */ +bool al_have_d3d_non_square_texture_support(void) +{ + D3DCAPS9 caps; + int adapter = al_get_new_display_adapter(); + if (!_al_d3d && !d3d_init_display()) + return false; + if (adapter < 0) + adapter = 0; + + /* This might have to change for multihead */ + if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_HAL, &caps) != D3D_OK) { + if (_al_d3d->GetDeviceCaps(adapter, D3DDEVTYPE_REF, &caps) != D3D_OK) { + return false; + } + } + + if ((caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0) { + return true; + } + + return false; +} + + +int _al_pixel_format_to_d3d(int format) +{ + int i; + + for (i = 0; allegro_formats[i] >= 0; i++) { + if (!_al_pixel_format_is_real(allegro_formats[i])) + continue; + if (allegro_formats[i] == format) { + return d3d_formats[i]; + } + } + + //return D3DFMT_R5G6B5; + return -1; +} + +int _al_d3d_format_to_allegro(int d3d_fmt) +{ + int i; + + for (i = 0; d3d_formats[i] >= 0; i++) { + if (!_al_pixel_format_is_real(allegro_formats[i])) + continue; + if (d3d_formats[i] == d3d_fmt) { + return allegro_formats[i]; + } + } + + return -1; +} + +int _al_d3d_num_display_formats(void) +{ + return sizeof(d3d_formats) / sizeof(d3d_formats[0]); +} + +void _al_d3d_get_nth_format(int i, int *allegro, D3DFORMAT *d3d) +{ + *allegro = allegro_formats[i]; + *d3d = (D3DFORMAT)d3d_formats[i]; +} + +static void d3d_reset_state(ALLEGRO_DISPLAY_D3D *disp) +{ + if (disp->device_lost) + return; + + disp->blender_state_op = -1; + disp->blender_state_src = -1; + disp->blender_state_dst = -1; + disp->blender_state_alpha_op = -1; + disp->blender_state_alpha_src = -1; + disp->blender_state_alpha_dst = -1; + + disp->scissor_state.bottom = -1; + disp->scissor_state.top = -1; + disp->scissor_state.left = -1; + disp->scissor_state.right = -1; + + disp->device->SetRenderState(D3DRS_LIGHTING, FALSE); + disp->device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + disp->device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + _al_d3d_update_render_state((ALLEGRO_DISPLAY *)disp); + + if (disp->device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP) != D3D_OK) + ALLEGRO_ERROR("SetSamplerState failed\n"); + if (disp->device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP) != D3D_OK) + ALLEGRO_ERROR("SetSamplerState failed\n"); +} + +static bool d3d_display_mode_matches(D3DDISPLAYMODE *dm, int w, int h, int format, int refresh_rate) +{ + if ((dm->Width == (unsigned int)w) && + (dm->Height == (unsigned int)h) && + ((!refresh_rate) || (dm->RefreshRate == (unsigned int)refresh_rate)) && + ((int)dm->Format == (int)_al_pixel_format_to_d3d(format))) { + return true; + } + return false; +} + +static bool d3d_check_mode(int w, int h, int format, int refresh_rate, UINT adapter) +{ + UINT num_modes; + UINT i; + D3DDISPLAYMODE display_mode; + + if (!_al_d3d && !d3d_init_display()) + return false; + + num_modes = _al_d3d->GetAdapterModeCount(adapter, (D3DFORMAT)_al_pixel_format_to_d3d(format)); + + for (i = 0; i < num_modes; i++) { + if (_al_d3d->EnumAdapterModes(adapter, (D3DFORMAT)_al_pixel_format_to_d3d(format), i, &display_mode) != D3D_OK) { + return false; + } + if (d3d_display_mode_matches(&display_mode, w, h, format, refresh_rate)) { + return true; + } + } + + return false; +} + +static int d3d_get_default_refresh_rate(UINT adapter) +{ + D3DDISPLAYMODE d3d_dm; + if (!_al_d3d && !d3d_init_display()) + return 0; + _al_d3d->GetAdapterDisplayMode(adapter, &d3d_dm); + return d3d_dm.RefreshRate; +} + + +static bool d3d_create_fullscreen_device(ALLEGRO_DISPLAY_D3D *d, + int format, int refresh_rate, int flags) +{ + int ret; + bool reset_all = false; + ALLEGRO_DISPLAY_WIN *win_display = &d->win_display; + ALLEGRO_DISPLAY *al_display = &win_display->display; + + (void)flags; + + if (!d3d_check_mode(al_display->w, al_display->h, format, refresh_rate, win_display->adapter)) { + ALLEGRO_ERROR("d3d_create_fullscreen_device: Mode not supported.\n"); + return 0; + } + + ZeroMemory(&d3d_pp, sizeof(d3d_pp)); + d3d_pp.BackBufferFormat = (D3DFORMAT)_al_pixel_format_to_d3d(format); + d3d_pp.BackBufferWidth = al_display->w; + d3d_pp.BackBufferHeight = al_display->h; + d3d_pp.BackBufferCount = 1; + d3d_pp.Windowed = 0; + if (d->vsync) { + d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } + else { + d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + + if (d->depth_stencil_format) { + d3d_pp.EnableAutoDepthStencil = true; + d3d_pp.AutoDepthStencilFormat = d->depth_stencil_format; + } + if (d->samples) { + d3d_pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; + d3d_pp.MultiSampleQuality = d->samples; + } + else + d3d_pp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + + if (d->single_buffer) { + d3d_pp.SwapEffect = D3DSWAPEFFECT_COPY; + } + else { + d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + } + d3d_pp.hDeviceWindow = win_display->window; + + if (refresh_rate) { + d3d_pp.FullScreen_RefreshRateInHz = refresh_rate; + } + else { + d3d_pp.FullScreen_RefreshRateInHz = d3d_get_default_refresh_rate(win_display->adapter); + al_display->refresh_rate = d3d_pp.FullScreen_RefreshRateInHz; + } + + if (ffw_set == false) { + fullscreen_focus_window = win_display->window; + ffw_set = true; + } + else { + reset_all = true; + } + +#ifdef ALLEGRO_CFG_D3D9EX + if (is_vista) { + D3DDISPLAYMODEEX mode; + IDirect3D9Ex *d3d = (IDirect3D9Ex *)_al_d3d; + mode.Size = sizeof(D3DDISPLAYMODEEX); + mode.Width = al_display->w; + mode.Height = al_display->h; + mode.RefreshRate = d3d_pp.FullScreen_RefreshRateInHz; + mode.Format = d3d_pp.BackBufferFormat; + mode.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE; + + if ((ret = d3d->CreateDeviceEx(win_display->adapter, + D3DDEVTYPE_HAL, fullscreen_focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED|D3DCREATE_SCREENSAVER, + &d3d_pp, &mode, (IDirect3DDevice9Ex **)(&d->device))) != D3D_OK) { + if ((ret = d3d->CreateDeviceEx(win_display->adapter, + D3DDEVTYPE_HAL, fullscreen_focus_window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED|D3DCREATE_SCREENSAVER, + &d3d_pp, &mode, (IDirect3DDevice9Ex **)(&d->device))) != D3D_OK) { + if ((ret = d3d->CreateDeviceEx(win_display->adapter, + D3DDEVTYPE_REF, fullscreen_focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED|D3DCREATE_SCREENSAVER, + &d3d_pp, &mode, (IDirect3DDevice9Ex **)(&d->device))) != D3D_OK) { + if ((ret = d3d->CreateDeviceEx(win_display->adapter, + D3DDEVTYPE_REF, fullscreen_focus_window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED|D3DCREATE_SCREENSAVER, + &d3d_pp, &mode, (IDirect3DDevice9Ex **)(&d->device))) != D3D_OK) { + switch (ret) { + case D3DERR_INVALIDCALL: + ALLEGRO_ERROR("D3DERR_INVALIDCALL in create_device.\n"); + break; + case D3DERR_NOTAVAILABLE: + ALLEGRO_ERROR("D3DERR_NOTAVAILABLE in create_device.\n"); + break; + case D3DERR_OUTOFVIDEOMEMORY: + ALLEGRO_ERROR("D3DERR_OUTOFVIDEOMEMORY in create_device.\n"); + break; + case D3DERR_DEVICELOST: + ALLEGRO_ERROR("D3DERR_DEVICELOST in create_device.\n"); + break; + default: + ALLEGRO_ERROR("Direct3D Device creation failed.\n"); + break; + } + return 0; + } } + } + } + } + else +#endif + { + if ((ret = _al_d3d->CreateDevice(win_display->adapter, + D3DDEVTYPE_HAL, fullscreen_focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, + &d3d_pp, &d->device)) != D3D_OK) { + if ((ret = _al_d3d->CreateDevice(win_display->adapter, + D3DDEVTYPE_HAL, fullscreen_focus_window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, + &d3d_pp, &d->device)) != D3D_OK) { + if ((ret = _al_d3d->CreateDevice(win_display->adapter, + D3DDEVTYPE_REF, fullscreen_focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, + &d3d_pp, &d->device)) != D3D_OK) { + if ((ret = _al_d3d->CreateDevice(win_display->adapter, + D3DDEVTYPE_REF, fullscreen_focus_window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, + &d3d_pp, &d->device)) != D3D_OK) { + switch (ret) { + case D3DERR_INVALIDCALL: + ALLEGRO_ERROR("D3DERR_INVALIDCALL in create_device.\n"); + break; + case D3DERR_NOTAVAILABLE: + ALLEGRO_ERROR("D3DERR_NOTAVAILABLE in create_device.\n"); + break; + case D3DERR_OUTOFVIDEOMEMORY: + ALLEGRO_ERROR("D3DERR_OUTOFVIDEOMEMORY in create_device.\n"); + break; + case D3DERR_DEVICELOST: + ALLEGRO_ERROR("D3DERR_DEVICELOST in create_device.\n"); + break; + default: + ALLEGRO_ERROR("Direct3D Device creation failed.\n"); + break; + } + return 0; + } + } + } + } + } + + d->device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d->render_target); + + ALLEGRO_INFO("Fullscreen Direct3D device created.\n"); + + d->device->BeginScene(); + + ALLEGRO_SYSTEM *system = (ALLEGRO_SYSTEM *)al_get_system_driver(); + + if (reset_all) { + int i; + for (i = 0; i < (int)system->displays._size; i++) { + ALLEGRO_DISPLAY_D3D **dptr = (ALLEGRO_DISPLAY_D3D **)_al_vector_ref(&system->displays, i); + ALLEGRO_DISPLAY_D3D *disp = *dptr; + if (disp != d) { + if (disp != d && (disp->win_display.display.flags & ALLEGRO_FULLSCREEN)) { + disp->do_reset = true; + while (!disp->reset_done) { + al_rest(0.001); + } + disp->reset_done = false; + } + } + } + } + + return 1; +} + +static void d3d_destroy_device(ALLEGRO_DISPLAY_D3D *disp) +{ + while (disp->device->Release() != 0) { + ALLEGRO_WARN("d3d_destroy_device: ref count not 0\n"); + } + disp->device = NULL; +} + + +bool _al_d3d_render_to_texture_supported(void) +{ + return render_to_texture_supported; +} + + + +static bool d3d_init_display() +{ + D3DDISPLAYMODE d3d_dm; + + _al_d3d_module = _al_win_safe_load_library(_al_d3d_module_name); + if (_al_d3d_module == NULL) { + ALLEGRO_ERROR("Failed to open '%s' library\n", _al_d3d_module_name); + return false; + } + + is_vista = is_windows_vista_or_greater(); + +#ifdef ALLEGRO_CFG_D3D9EX + if (is_vista) { + _al_d3d_create_ex = (DIRECT3DCREATE9EXPROC)GetProcAddress(_al_d3d_module, "Direct3DCreate9Ex"); + if (_al_d3d_create_ex != NULL) { + if (_al_d3d_create_ex(D3D_SDK_VERSION, (LPDIRECT3D9EX *)&_al_d3d) != D3D_OK) { + ALLEGRO_ERROR("Direct3DCreate9Ex failed\n"); + FreeLibrary(_al_d3d_module); + return false; + } + } + else { + ALLEGRO_INFO("Direct3DCreate9Ex not in %s\n", _al_d3d_module_name); + is_vista = false; + } + } + + if (!is_vista) +#endif + { + _al_d3d_create = (DIRECT3DCREATE9PROC)GetProcAddress(_al_d3d_module, "Direct3DCreate9"); + if (_al_d3d_create != NULL) { + if ((_al_d3d = _al_d3d_create(D3D9b_SDK_VERSION)) == NULL) { + ALLEGRO_ERROR("Direct3DCreate9 failed.\n"); + FreeLibrary(_al_d3d_module); + return false; + } + } + else { + ALLEGRO_ERROR("Direct3DCreate9 not in %s\n", _al_d3d_module_name); + FreeLibrary(_al_d3d_module); + return false; + } + } + + _al_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3d_dm); + + if (_al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, d3d_dm.Format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_TEXTURE, d3d_dm.Format) != D3D_OK) { + if (_al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, + D3DDEVTYPE_REF, d3d_dm.Format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_TEXTURE, d3d_dm.Format) != D3D_OK) { + render_to_texture_supported = false; + } + else + render_to_texture_supported = true; + } + else + render_to_texture_supported = true; + + + ALLEGRO_INFO("Render-to-texture: %d\n", render_to_texture_supported); + + present_mutex = al_create_mutex(); + _al_d3d_lost_device_mutex = al_create_mutex(); + +#ifdef ALLEGRO_CFG_SHADER_HLSL + _al_d3d_init_shaders(); +#endif + + return true; +} + + +static ALLEGRO_DISPLAY_D3D *d3d_create_display_internals(ALLEGRO_DISPLAY_D3D *d3d_display, bool free_on_error); +static void d3d_destroy_display_internals(ALLEGRO_DISPLAY_D3D *display); + + +static void d3d_make_faux_fullscreen_stage_one(ALLEGRO_DISPLAY_D3D *d3d_display) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + + if (already_fullscreen || num_faux_fullscreen_windows) { + int i; + for (i = 0; i < (int)system->displays._size; i++) { + ALLEGRO_DISPLAY_D3D **dptr = (ALLEGRO_DISPLAY_D3D **)_al_vector_ref(&system->displays, i); + ALLEGRO_DISPLAY_D3D *disp = *dptr; + if (disp != d3d_display) {// && (disp->win_display.display.flags & ALLEGRO_FULLSCREEN)) { + d3d_destroy_display_internals(disp); + disp->win_display.end_thread = false; + disp->win_display.thread_ended = false; + } + } + } +} + + +static void d3d_make_faux_fullscreen_stage_two(ALLEGRO_DISPLAY_D3D *d3d_display) +{ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + + if (already_fullscreen || num_faux_fullscreen_windows) { + int i; + already_fullscreen = false; + for (i = 0; i < (int)system->displays._size; i++) { + ALLEGRO_DISPLAY_D3D **dptr = (ALLEGRO_DISPLAY_D3D **)_al_vector_ref(&system->displays, i); + ALLEGRO_DISPLAY_D3D *disp = *dptr; + if (disp != d3d_display) {// && (disp->win_display.display.flags & ALLEGRO_FULLSCREEN)) { + if (disp->win_display.display.flags & ALLEGRO_FULLSCREEN) + disp->faux_fullscreen = true; + disp = d3d_create_display_internals(disp, true); + if (!disp) { + ALLEGRO_ERROR("d3d_create_display_internals failed.\n"); + /* XXX we don't try to recover from this yet */ + abort(); + } + ASSERT(disp); + _al_d3d_recreate_bitmap_textures(disp); + } + } + } +} + +static bool d3d_create_device(ALLEGRO_DISPLAY_D3D *d, + int format, int refresh_rate, int flags, bool convert_to_faux) +{ + HRESULT hr; + ALLEGRO_DISPLAY_WIN *win_display = &d->win_display; + ALLEGRO_DISPLAY *al_display = &win_display->display; + int adapter = win_display->adapter; + + (void)refresh_rate; + (void)flags; + + /* Ideally if you're targetting vanilla Direct3D 9 you should create + * your windowed displays before any fullscreen ones. If you don't, + * your fullscreen displays will be turned into "faux-fullscreen" + * displays, basically screen-filling windows set out in front of + * everything else. + */ +#ifdef ALLEGRO_CFG_D3D9EX + if (convert_to_faux) + d3d_make_faux_fullscreen_stage_one(d); +#else + (void)convert_to_faux; +#endif + + ZeroMemory(&d3d_pp, sizeof(d3d_pp)); + + d3d_pp.BackBufferFormat = (D3DFORMAT)_al_pixel_format_to_d3d(format); + + d3d_pp.BackBufferWidth = al_display->w; + d3d_pp.BackBufferHeight = al_display->h; + d3d_pp.BackBufferCount = 1; + d3d_pp.Windowed = 1; + if (d->vsync) { + d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } + else { + d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + + if (d->depth_stencil_format) { + d3d_pp.EnableAutoDepthStencil = true; + d3d_pp.AutoDepthStencilFormat = d->depth_stencil_format; + ALLEGRO_INFO("Chose depth stencil format %d\n", d->depth_stencil_format); + } + else { + ALLEGRO_INFO("Using no depth stencil buffer\n"); + } + + if (d->samples) { + d3d_pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; + d3d_pp.MultiSampleQuality = d->samples; + } + else + d3d_pp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + + if (d->single_buffer) { + d3d_pp.SwapEffect = D3DSWAPEFFECT_COPY; + } + else { + d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + } + d3d_pp.hDeviceWindow = win_display->window; + + if (!refresh_rate) { + al_display->refresh_rate = d3d_get_default_refresh_rate(win_display->adapter); + } + + if (adapter < 0) + adapter = 0; + + if ((hr = _al_d3d->CreateDevice(adapter, + D3DDEVTYPE_HAL, win_display->window, + D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, + &d3d_pp, (LPDIRECT3DDEVICE9 *)&d->device)) != D3D_OK) { + ALLEGRO_DEBUG("trying D3DCREATE_SOFTWARE_VERTEXPROCESSING\n"); + if ((hr = _al_d3d->CreateDevice(adapter, + D3DDEVTYPE_HAL, win_display->window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, + &d3d_pp, (LPDIRECT3DDEVICE9 *)&d->device)) != D3D_OK) { + ALLEGRO_DEBUG("trying D3DDEVTYPE_REF\n"); + if ((hr = _al_d3d->CreateDevice(adapter, + D3DDEVTYPE_REF, win_display->window, + D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, + &d3d_pp, (LPDIRECT3DDEVICE9 *)&d->device)) != D3D_OK) { + ALLEGRO_DEBUG("trying D3DDEVTYPE_REF|D3DCREATE_SOFTWARE_VERTEXPROCESSING\n"); + if ((hr = _al_d3d->CreateDevice(adapter, + D3DDEVTYPE_REF, win_display->window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE|D3DCREATE_MULTITHREADED, + &d3d_pp, (LPDIRECT3DDEVICE9 *)&d->device)) != D3D_OK) { + + ALLEGRO_ERROR("CreateDevice failed: %s\n", _al_d3d_error_string(hr)); + return 0; + } + } + } + } + + if (d->device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d->render_target) != D3D_OK) { + //if (d->device->GetRenderTarget(0, &d->render_target) != D3D_OK) { + ALLEGRO_ERROR("d3d_create_device: GetBackBuffer failed.\n"); + return 0; + } + + if (d->device->BeginScene() != D3D_OK) { + ALLEGRO_ERROR("BeginScene failed in create_device\n"); + } + else { + ALLEGRO_DEBUG("BeginScene succeeded in create_device\n"); + } + +#ifdef ALLEGRO_CFG_D3D9EX + if (convert_to_faux) + d3d_make_faux_fullscreen_stage_two(d); +#endif + + ALLEGRO_DEBUG("Success\n"); + + return 1; +} + +/* When a display is destroyed, its bitmaps get converted + * to memory bitmaps + */ +static void d3d_release_bitmaps(ALLEGRO_DISPLAY *display) +{ + while (display->bitmaps._size > 0) { + ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref_back(&display->bitmaps); + ALLEGRO_BITMAP *b = *bptr; + _al_convert_to_memory_bitmap(b); + } +} + + +static void d3d_destroy_display_internals(ALLEGRO_DISPLAY_D3D *d3d_display) +{ + ALLEGRO_DISPLAY *al_display = (ALLEGRO_DISPLAY *)d3d_display; + ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; + + if (d3d_display->device) { +#ifdef ALLEGRO_CFG_SHADER_HLSL + _al_remove_display_invalidated_callback(al_display, _al_d3d_on_lost_shaders); + _al_remove_display_validated_callback(al_display, _al_d3d_on_reset_shaders); +#endif + d3d_call_callbacks(&al_display->display_invalidated_callbacks, al_display); +#ifdef ALLEGRO_CFG_SHADER_HLSL + _al_add_display_invalidated_callback(al_display, _al_d3d_on_lost_shaders); + _al_add_display_validated_callback(al_display, _al_d3d_on_reset_shaders); +#endif + d3d_display->device->EndScene(); + } + + d3d_release_bitmaps((ALLEGRO_DISPLAY *)d3d_display); + + ALLEGRO_DEBUG("waiting for display %p's thread to end\n", d3d_display); + if (win_display->window) { + SendMessage(win_display->window, _al_win_msg_suicide, 0, 0); + while (!win_display->thread_ended) + al_rest(0.001); + } + + ASSERT(al_display->vt); +} + +static void d3d_destroy_display(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)display; + ALLEGRO_DISPLAY *old_disp = al_get_current_display(); + + ALLEGRO_INFO("destroying display %p (current %p)\n", display, old_disp); + + if (old_disp != display) + _al_set_current_display_only(display); + + if (system->mouse_grab_display == display) + al_ungrab_mouse(); + + _al_win_destroy_display_icons(display); + + d3d_destroy_display_internals(d3d_display); + + _al_vector_free(&display->display_invalidated_callbacks); + _al_vector_free(&display->display_validated_callbacks); + + _al_vector_find_and_delete(&system->system.displays, &display); + + if (system->system.displays._size <= 0) { + ffw_set = false; + already_fullscreen = false; + } + + if (d3d_display->es_inited) { + _al_event_source_free(&display->es); + d3d_display->es_inited = false; + } + + _al_vector_free(&display->bitmaps); + _al_vector_free(&((ALLEGRO_DISPLAY_WIN*) display)->msg_callbacks); + + if (old_disp != display) + _al_set_current_display_only(old_disp); + + al_free(display->vertex_cache); + al_free(display); +} + +void _al_d3d_prepare_for_reset(ALLEGRO_DISPLAY_D3D *disp) +{ + ALLEGRO_DISPLAY *al_display = (ALLEGRO_DISPLAY *)disp; + + if (d3d_release_callback) { + (*d3d_release_callback)(al_display); + } + + d3d_call_callbacks(&al_display->display_invalidated_callbacks, al_display); + + _al_d3d_release_default_pool_textures((ALLEGRO_DISPLAY *)disp); + while (disp->render_target && disp->render_target->Release() != 0) { + ALLEGRO_WARN("_al_d3d_prepare_for_reset: (bb) ref count not 0\n"); + } + disp->render_target = NULL; + get_extra(al_get_backbuffer(al_display))->render_target = NULL; +} + +static bool _al_d3d_reset_device(ALLEGRO_DISPLAY_D3D *d3d_display) +{ + ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; + ALLEGRO_DISPLAY *al_display = &win_display->display; + + al_lock_mutex(_al_d3d_lost_device_mutex); + + _al_d3d_prepare_for_reset(d3d_display); + + if (al_display->flags & ALLEGRO_FULLSCREEN) { + HRESULT hr; + + ZeroMemory(&d3d_pp, sizeof(d3d_pp)); + d3d_pp.BackBufferFormat = (D3DFORMAT)_al_pixel_format_to_d3d(_al_deduce_color_format(&al_display->extra_settings)); + d3d_pp.BackBufferWidth = al_display->w; + d3d_pp.BackBufferHeight = al_display->h; + d3d_pp.BackBufferCount = 1; + d3d_pp.Windowed = 0; + d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3d_pp.hDeviceWindow = win_display->window; + if (d3d_display->vsync) { + d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } + else { + d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + + if (d3d_display->depth_stencil_format) { + d3d_pp.EnableAutoDepthStencil = true; + d3d_pp.AutoDepthStencilFormat = d3d_display->depth_stencil_format; + } + if (d3d_display->samples) { + d3d_pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; + d3d_pp.MultiSampleQuality = d3d_display->samples; + } + else + d3d_pp.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + + if (d3d_display->single_buffer) { + d3d_pp.SwapEffect = D3DSWAPEFFECT_COPY; + } + else { + d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + } + if (al_display->refresh_rate) { + d3d_pp.FullScreen_RefreshRateInHz = + al_display->refresh_rate; + } + else { + d3d_pp.FullScreen_RefreshRateInHz = d3d_get_default_refresh_rate(win_display->adapter); + } +#ifdef ALLEGRO_CFG_D3D9EX + if (is_vista) { + D3DDISPLAYMODEEX mode; + IDirect3DDevice9Ex *dev = (IDirect3DDevice9Ex *)d3d_display->device; + mode.Size = sizeof(D3DDISPLAYMODEEX); + mode.Width = d3d_pp.BackBufferWidth; + mode.Height = d3d_pp.BackBufferHeight; + mode.RefreshRate = d3d_pp.FullScreen_RefreshRateInHz; + mode.Format = d3d_pp.BackBufferFormat; + mode.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE; + hr = dev->ResetEx(&d3d_pp, &mode); + } + else +#endif + { + hr = d3d_display->device->Reset(&d3d_pp); + } + if (hr != D3D_OK) { + switch (hr) { + case D3DERR_INVALIDCALL: + ALLEGRO_ERROR("D3DERR_INVALIDCALL in reset.\n"); + break; + case D3DERR_NOTAVAILABLE: + ALLEGRO_ERROR("D3DERR_NOTAVAILABLE in reset.\n"); + break; + case D3DERR_OUTOFVIDEOMEMORY: + ALLEGRO_ERROR("D3DERR_OUTOFVIDEOMEMORY in reset.\n"); + break; + case D3DERR_DEVICELOST: + ALLEGRO_ERROR("D3DERR_DEVICELOST in reset.\n"); + d3d_display->device_lost = true; + break; + default: + ALLEGRO_ERROR("Direct3D Device reset failed (unknown reason).\n"); + break; + } + al_unlock_mutex(_al_d3d_lost_device_mutex); + return 0; + } + } + else { + ZeroMemory(&d3d_pp, sizeof(d3d_pp)); + d3d_pp.BackBufferFormat = (D3DFORMAT)_al_pixel_format_to_d3d(_al_deduce_color_format(&al_display->extra_settings)); + d3d_pp.BackBufferWidth = al_display->w; + d3d_pp.BackBufferHeight = al_display->h; + d3d_pp.BackBufferCount = 1; + d3d_pp.Windowed = 1; + d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3d_pp.hDeviceWindow = win_display->window; + if (d3d_display->vsync) { + d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } + else { + d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + + if (d3d_display->depth_stencil_format) { + d3d_pp.EnableAutoDepthStencil = true; + d3d_pp.AutoDepthStencilFormat = d3d_display->depth_stencil_format; + } + if (d3d_display->samples) { + d3d_pp.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE; + d3d_pp.MultiSampleQuality = d3d_display->samples; + } + else + d3d_pp.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + + if (d3d_display->single_buffer) { + d3d_pp.SwapEffect = D3DSWAPEFFECT_COPY; + } + else { + d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + } + + /* Must be 0 for windowed modes */ + d3d_pp.FullScreen_RefreshRateInHz = 0; + + HRESULT hr = d3d_display->device->Reset(&d3d_pp); + if (hr != D3D_OK) { + switch (hr) { + case D3DERR_INVALIDCALL: + ALLEGRO_ERROR("D3DERR_INVALIDCALL in reset.\n"); + break; + case D3DERR_NOTAVAILABLE: + ALLEGRO_ERROR("D3DERR_NOTAVAILABLE in reset.\n"); + break; + case D3DERR_OUTOFVIDEOMEMORY: + ALLEGRO_ERROR("D3DERR_OUTOFVIDEOMEMORY in reset.\n"); + break; + case D3DERR_DEVICELOST: + ALLEGRO_ERROR("D3DERR_DEVICELOST in reset.\n"); + d3d_display->device_lost = true; + break; + default: + ALLEGRO_ERROR("Direct3D Device reset failed (unknown reason).\n"); + break; + } + al_unlock_mutex(_al_d3d_lost_device_mutex); + return 0; + } + } + + d3d_display->device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3d_display->render_target); + + _al_d3d_refresh_texture_memory(al_display); + + d3d_display->device->BeginScene(); + + d3d_reset_state(d3d_display); + + /* Restore the target bitmap. */ + if (d3d_display->target_bitmap) { + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY*)d3d_display; + d3d_set_target_bitmap(display, d3d_display->target_bitmap); + d3d_update_transformation(display, d3d_display->target_bitmap); + } + + al_unlock_mutex(_al_d3d_lost_device_mutex); + + return 1; +} + +static int d3d_choose_display_format(int fake) +{ + /* Pick an appropriate format if the user is vague */ + switch (fake) { + case ALLEGRO_PIXEL_FORMAT_ANY: + case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: + case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: + fake = ALLEGRO_PIXEL_FORMAT_XRGB_8888; + break; + case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: + fake = ALLEGRO_PIXEL_FORMAT_RGB_565; + break; + default: + break; + } + + return fake; +} + +static BOOL IsTextureFormatOk(D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat) +{ + HRESULT hr = _al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + AdapterFormat, + 0, + D3DRTYPE_TEXTURE, + TextureFormat); + + if (hr != D3D_OK) { + hr = _al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, + D3DDEVTYPE_REF, + AdapterFormat, + 0, + D3DRTYPE_TEXTURE, + TextureFormat); + } + + return SUCCEEDED(hr); +} + +/* Same as above, but using Allegro's formats */ +static bool is_texture_format_ok(ALLEGRO_DISPLAY *display, int texture_format) +{ + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D*)display; + return IsTextureFormatOk((D3DFORMAT)_al_pixel_format_to_d3d(texture_format), + (D3DFORMAT)_al_pixel_format_to_d3d(d3d_display->format)); +} + +static int real_choose_bitmap_format(ALLEGRO_DISPLAY_D3D *d3d_display, + int bits, bool alpha) +{ + int i; + + for (i = 0; allegro_formats[i] >= 0; i++) { + int aformat = allegro_formats[i]; + D3DFORMAT dformat; + D3DFORMAT adapter_format; + int adapter_format_allegro; + if (!_al_pixel_format_is_real(aformat)) { + ALLEGRO_DEBUG("Fake format\n"); + continue; + } + if (bits && al_get_pixel_format_bits(aformat) != bits) { + ALLEGRO_DEBUG("#Bits don't match\n"); + continue; + } + if (alpha && !_al_pixel_format_has_alpha(aformat)) { + ALLEGRO_DEBUG("Alpha doesn't match\n"); + continue; + } + dformat = (D3DFORMAT)d3d_formats[i]; + adapter_format_allegro = d3d_display->format; + if (!_al_pixel_format_is_real(adapter_format_allegro)) + adapter_format_allegro = d3d_choose_display_format(adapter_format_allegro); + ALLEGRO_DEBUG("Adapter format is %d\n", adapter_format_allegro); + adapter_format = (D3DFORMAT)_al_pixel_format_to_d3d(adapter_format_allegro); + if (IsTextureFormatOk(dformat, adapter_format)) { + ALLEGRO_DEBUG("Found a format\n"); + return aformat; + } + ALLEGRO_DEBUG("Texture format not OK\n"); + } + + ALLEGRO_WARN("Failed to find format\n"); + + return -1; +} + +static int d3d_choose_bitmap_format(ALLEGRO_DISPLAY_D3D *d3d_display, int fake) +{ + switch (fake) { + case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: + fake = real_choose_bitmap_format(d3d_display, 0, false); + break; + case ALLEGRO_PIXEL_FORMAT_ANY: + case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: + fake = real_choose_bitmap_format(d3d_display, 0, true); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: + fake = real_choose_bitmap_format(d3d_display, 32, false); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: + fake = real_choose_bitmap_format(d3d_display, 32, true); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: + fake = real_choose_bitmap_format(d3d_display, 24, false); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: + fake = real_choose_bitmap_format(d3d_display, 16, false); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: + fake = real_choose_bitmap_format(d3d_display, 16, true); + break; + case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: + fake = real_choose_bitmap_format(d3d_display, 15, false); + break; + default: + fake = -1; + } + + return fake; +} + +struct CREATE_WINDOW_INFO { + ALLEGRO_DISPLAY *display; + DISPLAY_DEVICE dd; + ALLEGRO_MONITOR_INFO mi; + int w; + int h; + int refresh_rate; + int flags; + bool inited; + bool quit; +}; + +static void d3d_create_window_proc(CREATE_WINDOW_INFO *info) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)info->display; + + win_display->window = _al_win_create_window( + info->display, + info->w, + info->h, + info->flags + ); +} + +static void *d3d_create_faux_fullscreen_window_proc(void *arg) +{ + CREATE_WINDOW_INFO *info = (CREATE_WINDOW_INFO *)arg; + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)info->display; + + win_display->window = + _al_win_create_faux_fullscreen_window( + info->dd.DeviceName, + info->display, + info->mi.x1, + info->mi.y1, + info->w, + info->h, + info->refresh_rate, + info->flags + ); + + return NULL; +} + +/* + * Display must be created in same thread that resets it + */ +static void *d3d_display_thread_proc(void *arg) +{ + ALLEGRO_DISPLAY_D3D *d3d_display; + ALLEGRO_DISPLAY_WIN *win_display; + ALLEGRO_DISPLAY *al_display; + D3D_DISPLAY_PARAMETERS *params = (D3D_DISPLAY_PARAMETERS *)arg; + int new_format; + bool convert_to_faux; + CREATE_WINDOW_INFO *info = (CREATE_WINDOW_INFO *)al_calloc(1, sizeof(*info)); + HRESULT hr; + bool lost_event_generated = false; + D3DCAPS9 caps; + MSG msg; + + d3d_display = params->display; + win_display = &d3d_display->win_display; + al_display = &win_display->display; + + if (al_display->flags & ALLEGRO_FULLSCREEN) { + convert_to_faux = true; + } + else { + convert_to_faux = false; + } + + /* So that we can call the functions using TLS from this thread. */ + al_set_new_display_flags(al_display->flags); + al_set_new_window_position(params->window_x, params->window_y); + al_set_new_window_title(params->window_title); + + new_format = _al_deduce_color_format(&al_display->extra_settings); + + /* This should never happen, I think */ + if (!_al_pixel_format_is_real(_al_deduce_color_format(&al_display->extra_settings))) { + int f = d3d_choose_display_format(_al_deduce_color_format(&al_display->extra_settings)); + if (f < 0) { + d3d_destroy_display(al_display); + params->init_failed = true; + SetEvent(params->AckEvent); + return NULL; + } + new_format = f; + _al_set_color_components(new_format, &al_display->extra_settings, ALLEGRO_REQUIRE); + } + + ALLEGRO_INFO("Chose a display format: %d\n", new_format); + d3d_display->format = new_format; + + if (d3d_display->faux_fullscreen) { + DEVMODE dm; + bool found = true; + int refresh_rate; + + num_faux_fullscreen_windows++; + + d3d_make_faux_fullscreen_stage_one(d3d_display); + + al_get_monitor_info(win_display->adapter, &info->mi); + /* Yes this is an "infinite" loop (suggested by MS on msdn) */ + for (int i = 0; ; i++) { + info->dd.cb = sizeof(info->dd); + if (!EnumDisplayDevices(NULL, i, &info->dd, 0)) { + found = false; + break; + } + if (!EnumDisplaySettings(info->dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) { + continue; + } + if (info->mi.x1 == dm.dmPosition.x && info->mi.y1 == dm.dmPosition.y) { + break; + } + + } + if (!found) { + ALLEGRO_ERROR("d3d_display_thread_proc: Error setting faux fullscreen mode.\n"); + num_faux_fullscreen_windows--; + d3d_destroy_display(al_display); + params->init_failed = true; + SetEvent(params->AckEvent); + return NULL; + } + if (al_display->refresh_rate) { + refresh_rate = al_display->refresh_rate; + } + else { + refresh_rate = d3d_get_default_refresh_rate(win_display->adapter); + } + d3d_display->device_name = (TCHAR *)al_malloc(sizeof(TCHAR)*32); + strcpy((char*)d3d_display->device_name, (char*)info->dd.DeviceName); + ALLEGRO_DEBUG("going to call _al_win_create_faux_fullscreen_window\n"); + + info->display = al_display; + info->w = al_display->w; + info->h = al_display->h; + info->refresh_rate = refresh_rate; + info->flags = al_display->flags; + + d3d_create_faux_fullscreen_window_proc(info); + + if (!win_display->window) { + ALLEGRO_DEBUG("Failed to create window (faux)fullscreen.\n"); + d3d_destroy_display(al_display); + params->init_failed = true; + SetEvent(params->AckEvent); + return NULL; + } + + ALLEGRO_DEBUG("Called _al_win_create_faux_fullscreen_window.\n"); + + d3d_make_faux_fullscreen_stage_two(d3d_display); + + convert_to_faux = false; + } + else { + ALLEGRO_INFO("Normal window.\n"); + + info->display = al_display; + info->w = al_display->w; + info->h = al_display->h; + info->flags = al_display->flags; + + d3d_create_window_proc(info); + } + + if (!win_display->window) { + ALLEGRO_DEBUG("Failed to create regular window.\n"); + d3d_destroy_display(al_display); + params->init_failed = true; + SetEvent(params->AckEvent); + return NULL; + } + + if (!(al_display->flags & ALLEGRO_FULLSCREEN) || d3d_display->faux_fullscreen) { + if (!d3d_create_device(d3d_display, _al_deduce_color_format(&al_display->extra_settings), + al_display->refresh_rate, al_display->flags, convert_to_faux)) { + d3d_destroy_display(al_display); + params->init_failed = true; + SetEvent(params->AckEvent); + return NULL; + } + } + else { + ALLEGRO_DEBUG("Creating real fullscreen device\n"); + if (!d3d_create_fullscreen_device(d3d_display, _al_deduce_color_format(&al_display->extra_settings), + al_display->refresh_rate, al_display->flags)) { + d3d_destroy_display(al_display); + params->init_failed = true; + SetEvent(params->AckEvent); + return NULL; + } + ALLEGRO_INFO("Real fullscreen device created\n"); + } + + al_display->backbuffer_format = _al_deduce_color_format(&al_display->extra_settings); + + + d3d_display->device->GetDeviceCaps(&caps); + d3d_can_wait_for_vsync = ((caps.Caps & D3DCAPS_READ_SCANLINE) != 0); + + params->init_failed = false; + win_display->thread_ended = false; + win_display->end_thread = false; + SetEvent(params->AckEvent); + + while (!win_display->end_thread) { + al_rest(0.001); + + if (PeekMessage(&msg, NULL, 0, 0, FALSE)) { + if (GetMessage(&msg, NULL, 0, 0) != 0) + DispatchMessage(&msg); + else + break; /* WM_QUIT received or error (GetMessage returned -1) */ + } + + if (!d3d_display->device) { + continue; + } + + if (d3d_display->device_lost) { + hr = d3d_display->device->TestCooperativeLevel(); + + if (hr == D3D_OK) { + d3d_display->device_lost = false; + } + else if (hr == D3DERR_DEVICELOST) { + /* device remains lost */ + if (!lost_event_generated) { + ALLEGRO_DEBUG("D3DERR_DEVICELOST: d3d_display=%p\n", d3d_display); + lost_event_generated = true; + if (d3d_display->suppress_lost_events) { + ALLEGRO_DEBUG("DISPLAY_LOST event suppressed\n"); + } + else { + _al_event_source_lock(&al_display->es); + if (_al_event_source_needs_to_generate_event(&al_display->es)) { + ALLEGRO_EVENT event; + memset(&event, 0, sizeof(event)); + event.display.type = ALLEGRO_EVENT_DISPLAY_LOST; + event.display.timestamp = al_get_time(); + _al_event_source_emit_event(&al_display->es, &event); + } + _al_event_source_unlock(&al_display->es); + al_rest(0.5); // give user time to respond + } + } + } + else if (hr == D3DERR_DEVICENOTRESET) { + if (_al_d3d_reset_device(d3d_display)) { + d3d_display->device_lost = false; + d3d_reset_state(d3d_display); + _al_event_source_lock(&al_display->es); + if (_al_event_source_needs_to_generate_event(&al_display->es)) { + ALLEGRO_EVENT event; + memset(&event, 0, sizeof(event)); + event.display.type = ALLEGRO_EVENT_DISPLAY_FOUND; + event.display.timestamp = al_get_time(); + _al_event_source_emit_event(&al_display->es, &event); + } + _al_event_source_unlock(&al_display->es); + lost_event_generated = false; + d3d_call_callbacks(&al_display->display_validated_callbacks, al_display); + if (d3d_restore_callback) { + (*d3d_restore_callback)(al_display); + } + } + } + } + if (d3d_display->do_reset) { + d3d_display->reset_success = _al_d3d_reset_device(d3d_display); + if (d3d_restore_callback) { + (*d3d_restore_callback)(al_display); + } + d3d_display->do_reset = false; + d3d_display->reset_done = true; + } + } + + d3d_destroy_device(d3d_display); + + if (d3d_display->faux_fullscreen) { + ChangeDisplaySettingsEx(d3d_display->device_name, NULL, NULL, 0, NULL); + al_free(d3d_display->device_name); + num_faux_fullscreen_windows--; + } + + win_display->thread_ended = true; + + al_free(info); + + ALLEGRO_INFO("d3d display thread exits\n"); + + return NULL; +} + + +static ALLEGRO_DISPLAY_D3D *d3d_create_display_helper(int w, int h) +{ + ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)al_malloc(sizeof(ALLEGRO_DISPLAY_D3D)); + ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; + ALLEGRO_DISPLAY *al_display = &win_display->display; + + memset(d3d_display, 0, sizeof *d3d_display); + + win_display->adapter = _al_win_determine_adapter(); + + /* w/h may be reset below if ALLEGRO_FULLSCREEN_WINDOW is set */ + al_display->w = w; + al_display->h = h; + al_display->refresh_rate = al_get_new_display_refresh_rate(); + al_display->flags = al_get_new_display_flags(); + al_display->vt = vt; + ASSERT(al_display->vt); + +#ifdef ALLEGRO_CFG_D3D9EX + if (!is_vista) +#endif + { + if (al_display->flags & ALLEGRO_FULLSCREEN) { + if (already_fullscreen || system->system.displays._size != 0) { + d3d_display->faux_fullscreen = true; + } + else { + already_fullscreen = true; + d3d_display->faux_fullscreen = false; + } + } + } +#ifdef ALLEGRO_CFG_D3D9EX + else { + d3d_display->faux_fullscreen = false; + } +#endif + + if (!(al_display->flags & ALLEGRO_FULLSCREEN)) { + if (al_display->flags & ALLEGRO_FULLSCREEN_WINDOW) { + ALLEGRO_MONITOR_INFO mi; + al_get_monitor_info(win_display->adapter, &mi); + al_display->w = mi.x2 - mi.x1; + al_display->h = mi.y2 - mi.y1; + d3d_display->faux_fullscreen = true; + } + else { + d3d_display->faux_fullscreen = false; + } + win_display->toggle_w = w; + win_display->toggle_h = h; + } + + return d3d_display; +} + +/* This function may return the original d3d_display argument, + * or a new one, or NULL on error. + */ +static ALLEGRO_DISPLAY_D3D *d3d_create_display_internals( + ALLEGRO_DISPLAY_D3D *d3d_display, bool free_on_error) +{ + D3D_DISPLAY_PARAMETERS params; + ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; + ALLEGRO_DISPLAY *al_display = &win_display->display; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref = _al_get_new_display_settings(); + int num_modes; + int i; + int window_x, window_y; + /* save width and height in case new fullscreen-mode + * fails inside d3d_display_thread_proc and destroys al_display */ + int pre_destroy_w = al_display->w; + int pre_destroy_h = al_display->h; + + params.display = d3d_display; + + /* The window is created in a separate thread so we need to pass this + * TLS on + */ + al_get_new_window_position(&window_x, &window_y); + params.window_x = window_x; + params.window_y = window_y; + params.window_title = al_get_new_window_title(); + + _al_d3d_generate_display_format_list(); + + _al_d3d_score_display_settings(ref); + + /* Checking each mode is slow, so do a resolution check first */ + if (al_display->flags & ALLEGRO_FULLSCREEN) { + num_modes = al_get_num_display_modes(); + while (num_modes >= 0) { + ALLEGRO_DISPLAY_MODE mode; + al_get_display_mode(num_modes, &mode); + if (mode.width == al_display->w && mode.height == al_display->h) { + break; + } + num_modes--; + } + if (num_modes < 0) { + // Failing resolution test is like failing to create a window + // This helps determining if the window message thread needs + // to be destroyed. + win_display->window = NULL; + if (free_on_error) { + al_free(d3d_display); + } + return NULL; + } + } + + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = NULL; + for (i = 0; (eds = _al_d3d_get_display_settings(i)); i++) { + ALLEGRO_DEBUG("Trying format %d.\n", eds->index); + + d3d_display->depth_stencil_format = d3d_get_depth_stencil_format(eds); + d3d_display->samples = eds->settings[ALLEGRO_SAMPLES]; + d3d_display->single_buffer = eds->settings[ALLEGRO_SINGLE_BUFFER] ? true : false; + d3d_display->vsync = eds->settings[ALLEGRO_VSYNC] == 1; + + memcpy(&al_display->extra_settings, eds, sizeof al_display->extra_settings); + + params.init_failed = true; + win_display->thread_ended = true; + params.AckEvent = CreateEvent(NULL, false, false, NULL); + + al_run_detached_thread(d3d_display_thread_proc, ¶ms); + /* Wait some _finite_ time (10 secs or so) for display thread to init, and + * give up if something horrible happened to it, unless we're in debug mode + * and we may have intentionally stopped the execution to analyze the code. + */ +#ifdef DEBUGMODE + WaitForSingleObject(params.AckEvent, INFINITE); +#else + WaitForSingleObject(params.AckEvent, 10*1000); +#endif + ALLEGRO_DEBUG("Resumed after wait.\n"); + + CloseHandle(params.AckEvent); + + if (!params.init_failed) { + break; + } + + ALLEGRO_INFO("Format %d failed.\n", i); + + // Display has been destroyed in d3d_display_thread_proc, create empty template again + d3d_display = d3d_create_display_helper(pre_destroy_w, pre_destroy_h); + win_display = &d3d_display->win_display; + al_display = &win_display->display; + params.display = d3d_display; + + ALLEGRO_DEBUG("d3d_display = %p\n", d3d_display); + ALLEGRO_DEBUG("win_display = %p\n", win_display); + ALLEGRO_DEBUG("al_display = %p\n", al_display); + ASSERT(al_display->vt); + } + + // Re-sort the display format list for use later + _al_d3d_resort_display_settings(); + + if (!eds) { + ALLEGRO_WARN("All %d formats failed.\n", i); + if (free_on_error) { + al_free(d3d_display); + } + return NULL; + } + + ALLEGRO_INFO("Format %d succeeded.\n", eds->index); + + d3d_reset_state(d3d_display); + + d3d_display->backbuffer_bmp.extra = &d3d_display->backbuffer_bmp_extra; + d3d_display->backbuffer_bmp_extra.is_backbuffer = true; + d3d_display->backbuffer_bmp._display = al_display; + d3d_display->backbuffer_bmp._format = _al_deduce_color_format(&al_display->extra_settings); + d3d_display->backbuffer_bmp._memory_format = d3d_display->backbuffer_bmp._format; + d3d_display->backbuffer_bmp_extra.system_format = d3d_display->backbuffer_bmp._format; + d3d_display->backbuffer_bmp._flags = ALLEGRO_VIDEO_BITMAP; + d3d_display->backbuffer_bmp.w = al_display->w; + d3d_display->backbuffer_bmp.h = al_display->h; + d3d_display->backbuffer_bmp_extra.texture_w = al_display->w; + d3d_display->backbuffer_bmp_extra.texture_h = al_display->h; + d3d_display->backbuffer_bmp.cl = 0; + d3d_display->backbuffer_bmp.ct = 0; + d3d_display->backbuffer_bmp.cr_excl = al_display->w; + d3d_display->backbuffer_bmp.cb_excl = al_display->h; + d3d_display->backbuffer_bmp.vt = (ALLEGRO_BITMAP_INTERFACE *)_al_bitmap_d3d_driver(); + d3d_display->backbuffer_bmp_extra.display = d3d_display; + d3d_display->target_bitmap = NULL; + al_identity_transform(&d3d_display->backbuffer_bmp.transform); + al_identity_transform(&d3d_display->backbuffer_bmp.proj_transform); + al_orthographic_transform(&d3d_display->backbuffer_bmp.proj_transform, 0, 0, -1.0, al_display->w, al_display->h, 1.0); + + /* Alpha blending is the default */ + d3d_display->device->SetRenderState(D3DRS_ALPHABLENDENABLE, true); + d3d_display->device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3d_display->device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + ALLEGRO_DEBUG("Returning d3d_display: %p\n", d3d_display); + return d3d_display; +} + +static ALLEGRO_DISPLAY *d3d_create_display_locked(int w, int h) +{ + ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); + ALLEGRO_DISPLAY_D3D *d3d_display = d3d_create_display_helper(w, h); + ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; + ALLEGRO_DISPLAY *al_display = &win_display->display; + ALLEGRO_DISPLAY_D3D **add; + D3DCAPS9 caps; + + ALLEGRO_INFO("faux_fullscreen=%d\n", d3d_display->faux_fullscreen); + ALLEGRO_DEBUG("al_display=%p\n", al_display); + ALLEGRO_DEBUG("al_display->vt=%p\n", al_display->vt); + ASSERT(al_display->vt); + + d3d_display = d3d_create_display_internals(d3d_display, true); + if (!d3d_display) { + ALLEGRO_ERROR("d3d_create_display failed.\n"); + return NULL; + } + win_display = &d3d_display->win_display; + al_display = &win_display->display; + ALLEGRO_DEBUG("al_display=%p\n", al_display); + ALLEGRO_DEBUG("al_display->vt=%p\n", al_display->vt); + ASSERT(al_display->vt); + + /* Add ourself to the list of displays. */ + add = (ALLEGRO_DISPLAY_D3D **)_al_vector_alloc_back(&system->system.displays); + *add = d3d_display; + + /* Each display is an event source. */ + _al_event_source_init(&al_display->es); + d3d_display->es_inited = true; + +#if 0 + /* Setup the mouse */ + if (al_display->flags & ALLEGRO_FULLSCREEN && al_is_mouse_installed()) { + RAWINPUTDEVICE rid[1]; + rid[0].usUsagePage = 0x01; + rid[0].usUsage = 0x02; + rid[0].dwFlags = RIDEV_NOLEGACY; + rid[0].hwndTarget = 0; + if (RegisterRawInputDevices(rid, 1, sizeof(rid[0])) == FALSE) { + ALLEGRO_WARN("Failed to init mouse.\n"); + } + } +#endif + + win_display->mouse_selected_hcursor = 0; + win_display->mouse_cursor_shown = false; + win_display->can_acknowledge = false; + + SetForegroundWindow(win_display->window); + _al_win_grab_input(win_display); + + _al_win_show_mouse_cursor(al_display); + + if (_al_d3d->GetDeviceCaps(win_display->adapter, D3DDEVTYPE_HAL, &caps) != D3D_OK + && _al_d3d->GetDeviceCaps(win_display->adapter, D3DDEVTYPE_REF, &caps) != D3D_OK) { + d3d_display->supports_separate_alpha_blend = false; + } + else { + d3d_display->supports_separate_alpha_blend = + ((caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) != 0); + } + + ASSERT(al_display->vt); + return al_display; +} + +static ALLEGRO_DISPLAY *d3d_create_display(int w, int h) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_DISPLAY_WIN *win_display; + int *s; + + al_lock_mutex(present_mutex); + display = d3d_create_display_locked(w, h); + win_display = (ALLEGRO_DISPLAY_WIN *)display; + al_unlock_mutex(present_mutex); + + if (!display) + return NULL; + + ASSERT(display->vt); + + s = display->extra_settings.settings; + s[ALLEGRO_MAX_BITMAP_SIZE] = d3d_get_max_texture_size(win_display->adapter); + s[ALLEGRO_SUPPORT_SEPARATE_ALPHA] = _al_d3d_supports_separate_alpha_blend(display); + s[ALLEGRO_SUPPORT_NPOT_BITMAP] = al_have_d3d_non_pow2_texture_support(); + s[ALLEGRO_CAN_DRAW_INTO_BITMAP] = render_to_texture_supported; + +#ifdef ALLEGRO_CFG_D3DX9 + _al_load_d3dx9_module(); +#endif + + _al_win_post_create_window(display); + + return display; +} + +static bool d3d_set_current_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)d; + + if (d3d_display->do_reset) + return false; + + _al_d3d_update_render_state(d); + + return true; +} + + +static int d3d_al_blender_to_d3d(int al_mode) +{ + const int d3d_modes[ALLEGRO_NUM_BLEND_MODES] = { + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_SRCALPHA, + D3DBLEND_INVSRCALPHA, + D3DBLEND_SRCCOLOR, + D3DBLEND_DESTCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_BLENDFACTOR, + D3DBLEND_INVBLENDFACTOR + }; + + return d3d_modes[al_mode]; +} + +void _al_d3d_set_blender(ALLEGRO_DISPLAY_D3D *d3d_display) +{ + bool blender_changed; + int op, src, dst, alpha_op, alpha_src, alpha_dst; + ALLEGRO_COLOR color; + unsigned char r, g, b, a; + DWORD allegro_to_d3d_blendop[ALLEGRO_NUM_BLEND_OPERATIONS] = { + D3DBLENDOP_ADD, + D3DBLENDOP_SUBTRACT, + D3DBLENDOP_REVSUBTRACT + }; + + blender_changed = false; + + al_get_separate_bitmap_blender(&op, &src, &dst, + &alpha_op, &alpha_src, &alpha_dst); + color = al_get_bitmap_blend_color(); + al_unmap_rgba(color, &r, &g, &b, &a); + + if (d3d_display->blender_state_op != op) { + /* These may not be supported but they will always fall back to ADD + * in that case. + */ + d3d_display->device->SetRenderState(D3DRS_BLENDOP, allegro_to_d3d_blendop[op]); + d3d_display->blender_state_op = op; + blender_changed = true; + } + + if (d3d_display->blender_state_alpha_op != alpha_op) { + /* These may not be supported but they will always fall back to ADD + * in that case. + */ + d3d_display->device->SetRenderState(D3DRS_BLENDOPALPHA, allegro_to_d3d_blendop[alpha_op]); + d3d_display->blender_state_alpha_op = alpha_op; + blender_changed = true; + } + + if (d3d_display->blender_state_src != src) { + if (d3d_display->device->SetRenderState(D3DRS_SRCBLEND, d3d_al_blender_to_d3d(src)) != D3D_OK) + ALLEGRO_ERROR("Failed to set source blender\n"); + d3d_display->blender_state_src = src; + blender_changed = true; + } + + if (d3d_display->blender_state_dst != dst) { + if (d3d_display->device->SetRenderState(D3DRS_DESTBLEND, d3d_al_blender_to_d3d(dst)) != D3D_OK) + ALLEGRO_ERROR("Failed to set dest blender\n"); + d3d_display->blender_state_dst = dst; + blender_changed = true; + } + + if (d3d_display->blender_state_alpha_src != alpha_src) { + if (d3d_display->device->SetRenderState(D3DRS_SRCBLENDALPHA, d3d_al_blender_to_d3d(alpha_src)) != D3D_OK) + ALLEGRO_ERROR("Failed to set source alpha blender\n"); + d3d_display->blender_state_alpha_src = alpha_src; + blender_changed = true; + } + + if (d3d_display->blender_state_alpha_dst != alpha_dst) { + if (d3d_display->device->SetRenderState(D3DRS_DESTBLENDALPHA, d3d_al_blender_to_d3d(alpha_dst)) != D3D_OK) + ALLEGRO_ERROR("Failed to set dest alpha blender\n"); + d3d_display->blender_state_alpha_dst = alpha_dst; + blender_changed = true; + } + + if (blender_changed) { + bool enable_separate_blender = (op != alpha_op) || (src != alpha_src) || (dst != alpha_dst); + d3d_display->device->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(r, g, b, a)); + if (enable_separate_blender) { + if (d3d_display->device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true) != D3D_OK) + ALLEGRO_ERROR("D3DRS_SEPARATEALPHABLENDENABLE failed\n"); + } + + /* thedmd: Why is this function called anyway? */ + d3d_display->device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + } +} + +static void d3d_clear(ALLEGRO_DISPLAY *al_display, ALLEGRO_COLOR *color) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ALLEGRO_DISPLAY_D3D* d3d_display = (ALLEGRO_DISPLAY_D3D*)al_display; + + if (target->parent) target = target->parent; + + if (d3d_display->device_lost) + return; + if (d3d_display->device->Clear(0, NULL, D3DCLEAR_TARGET, + D3DCOLOR_ARGB((int)(color->a*255), (int)(color->r*255), + (int)(color->g*255), (int)(color->b*255)), 0, 0) != D3D_OK) { + ALLEGRO_ERROR("Clear failed\n"); + } +} + +static void d3d_clear_depth_buffer(ALLEGRO_DISPLAY *al_display, float z) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ALLEGRO_DISPLAY_D3D* d3d_display = (ALLEGRO_DISPLAY_D3D*)al_display; + + if (target->parent) target = target->parent; + + if (d3d_display->device_lost) + return; + if (d3d_display->device->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, z, 0) + != D3D_OK) { + ALLEGRO_ERROR("Clear zbuffer failed\n"); + } +} + + + +// FIXME: does this need a programmable pipeline path? +static void d3d_draw_pixel(ALLEGRO_DISPLAY *disp, float x, float y, ALLEGRO_COLOR *color) +{ + ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)disp; + + _al_d3d_set_blender(d3d_disp); + +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + UINT required_passes; + ALLEGRO_VERTEX vertices[1]; + vertices[0].x = x; + vertices[0].y = y; + vertices[0].z = 0; + vertices[0].color = *color; + + d3d_disp->device->SetFVF(D3DFVF_ALLEGRO_VERTEX); + d3d_disp->effect->SetBool(ALLEGRO_SHADER_VAR_USE_TEX, false); + d3d_disp->effect->Begin(&required_passes, 0); + for (unsigned int i = 0; i < required_passes; i++) { + d3d_disp->effect->BeginPass(i); + if (d3d_disp->device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, + vertices, sizeof(ALLEGRO_VERTEX)) != D3D_OK) { + ALLEGRO_ERROR("d3d_draw_pixel: DrawPrimitive failed.\n"); + return; + } + d3d_disp->effect->EndPass(); + } + d3d_disp->effect->End(); + } + else +#endif + { + D3D_FIXED_VERTEX vertices[1]; + vertices[0].x = x; + vertices[0].y = y; + vertices[0].z = 0; + vertices[0].color = D3DCOLOR_COLORVALUE(color->r, color->g, color->b, color->a); + + d3d_disp->device->SetFVF(D3DFVF_FIXED_VERTEX); + d3d_disp->device->SetTexture(0, NULL); + if (d3d_disp->device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, + vertices, sizeof(D3D_FIXED_VERTEX)) != D3D_OK) { + ALLEGRO_ERROR("d3d_draw_pixel: DrawPrimitive failed.\n"); + return; + } + } +} + +static void d3d_flip_display(ALLEGRO_DISPLAY *al_display) +{ + ALLEGRO_DISPLAY_D3D* d3d_display = (ALLEGRO_DISPLAY_D3D*)al_display; + ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; + HRESULT hr; + + if (d3d_display->device_lost) + return; + + al_lock_mutex(present_mutex); + + d3d_display->device->EndScene(); + + hr = d3d_display->device->Present(NULL, NULL, win_display->window, NULL); + + d3d_display->device->BeginScene(); + + al_unlock_mutex(present_mutex); + + if (hr == D3DERR_DEVICELOST) { + d3d_display->device_lost = true; + return; + } + else { + al_backup_dirty_bitmaps(al_display); + } +} + +static void d3d_update_display_region(ALLEGRO_DISPLAY *al_display, + int x, int y, + int width, int height) +{ + ALLEGRO_DISPLAY_D3D* d3d_display = (ALLEGRO_DISPLAY_D3D*)al_display; + ALLEGRO_DISPLAY_WIN *win_display = &d3d_display->win_display; + HRESULT hr; + RGNDATA *rgndata; + + if (d3d_display->device_lost) + return; + + if (d3d_display->single_buffer) { + RECT rect; + + rect.left = x; + rect.right = x+width; + rect.top = y; + rect.bottom = y+height; + + rgndata = (RGNDATA *)al_malloc(sizeof(RGNDATA)+sizeof(RECT)-1); + rgndata->rdh.dwSize = sizeof(RGNDATAHEADER); + rgndata->rdh.iType = RDH_RECTANGLES; + rgndata->rdh.nCount = 1; + rgndata->rdh.nRgnSize = sizeof(RECT); + memcpy(&rgndata->rdh.rcBound, &rect, sizeof(RECT)); + memcpy(rgndata->Buffer, &rect, sizeof(RECT)); + + d3d_display->device->EndScene(); + + hr = d3d_display->device->Present(&rect, &rect, win_display->window, rgndata); + + d3d_display->device->BeginScene(); + + al_free(rgndata); + + if (hr == D3DERR_DEVICELOST) { + d3d_display->device_lost = true; + return; + } + } + else { + d3d_flip_display(al_display); + } +} + +/* + * Sets a clipping rectangle + */ +void _al_d3d_set_bitmap_clip(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + ALLEGRO_DISPLAY_D3D *disp = d3d_bmp->display; + RECT rect; + + if (!disp) + return; + + if (bitmap->parent) { + rect.left = bitmap->xofs + bitmap->cl; + rect.right = bitmap->xofs + bitmap->cr_excl; + rect.top = bitmap->yofs + bitmap->ct; + rect.bottom = bitmap->yofs + bitmap->cb_excl; + } + else { + rect.left = bitmap->cl; + rect.right = bitmap->cr_excl; + rect.top = bitmap->ct; + rect.bottom = bitmap->cb_excl; + } + + if (memcmp(&disp->scissor_state, &rect, sizeof(RECT)) != 0) { + + if (rect.left == 0 && rect.top == 0 && rect.right == disp->win_display.display.w && rect.left == disp->win_display.display.h) { + disp->device->SetRenderState(D3DRS_SCISSORTESTENABLE, false); + return; + } + + disp->device->SetRenderState(D3DRS_SCISSORTESTENABLE, true); + disp->device->SetScissorRect(&rect); + + disp->scissor_state = rect; + } +} + +static bool d3d_acknowledge_resize(ALLEGRO_DISPLAY *d) +{ + WINDOWINFO wi; + ALLEGRO_DISPLAY_D3D *disp = (ALLEGRO_DISPLAY_D3D *)d; + ALLEGRO_DISPLAY_WIN *win_display = &disp->win_display; + int w, h; + ALLEGRO_STATE state; + + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(win_display->window, &wi); + w = wi.rcClient.right - wi.rcClient.left; + h = wi.rcClient.bottom - wi.rcClient.top; + + if (w > 0 && h > 0) { + d->w = w; + d->h = h; + } + + disp->backbuffer_bmp.w = d->w; + disp->backbuffer_bmp.h = d->h; + disp->backbuffer_bmp.cl = 0; + disp->backbuffer_bmp.ct = 0; + disp->backbuffer_bmp.cr_excl = w; + disp->backbuffer_bmp.cb_excl = h; + al_identity_transform(&disp->backbuffer_bmp.proj_transform); + al_orthographic_transform(&disp->backbuffer_bmp.proj_transform, 0, 0, -1.0, w, h, 1.0); + + disp->do_reset = true; + while (!disp->reset_done) { + al_rest(0.001); + } + disp->reset_done = false; + + /* XXX: This is not very efficient, it'd probably be better to call + * the necessary functions directly. */ + al_store_state(&state, ALLEGRO_STATE_DISPLAY | ALLEGRO_STATE_TARGET_BITMAP); + al_set_target_bitmap(al_get_backbuffer(d)); + al_set_clipping_rectangle(0, 0, d->w, d->h); + al_restore_state(&state); + + return disp->reset_success; +} + +static bool d3d_resize_helper(ALLEGRO_DISPLAY *d, int width, int height) +{ + ALLEGRO_DISPLAY_D3D *disp = (ALLEGRO_DISPLAY_D3D *)d; + ALLEGRO_DISPLAY_WIN *win_display = &disp->win_display; + ALLEGRO_DISPLAY_D3D *new_disp; + int full_w, full_h; + ALLEGRO_MONITOR_INFO mi; + int adapter = win_display->adapter; + + ALLEGRO_STATE backup; + + al_get_monitor_info(adapter, &mi); + full_w = mi.x2 - mi.x1; + full_h = mi.y2 - mi.y1; + + if ((d->flags & ALLEGRO_FULLSCREEN_WINDOW) && + (full_w != width || full_h != height)) { + win_display->toggle_w = width; + win_display->toggle_h = height; + return true; + } + + win_display->can_acknowledge = false; + + if (d->flags & ALLEGRO_FULLSCREEN) { + /* Don't generate ALLEGRO_EVENT_DISPLAY_LOST events when destroying a + * display for resizing. + */ + disp->suppress_lost_events = true; + d3d_destroy_display_internals(disp); + + d->w = width; + d->h = height; + /* reset refresh rate (let new mode choose one) */ + d->refresh_rate = 0; + win_display->end_thread = false; + win_display->thread_ended = false; + /* What's this? */ + ALLEGRO_SYSTEM *system = al_get_system_driver(); + if (system->displays._size <= 1) { + ffw_set = false; + } + /* The original display needs to remain intact so we can + * recover if resizing a display fails. + */ + new_disp = d3d_create_display_internals(disp, false); + if (!new_disp) { + ALLEGRO_ERROR("d3d_create_display_internals failed.\n"); + ASSERT(d->vt); + return false; + } + ASSERT(new_disp == disp); + ASSERT(d->vt); + + disp->suppress_lost_events = false; + + _al_d3d_recreate_bitmap_textures(disp); + + disp->backbuffer_bmp.w = width; + disp->backbuffer_bmp.h = height; + + } + else { + RECT win_size; + WINDOWINFO wi; + + win_size.left = 0; + win_size.top = 0; + win_size.right = width; + win_size.bottom = height; + + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(win_display->window, &wi); + + AdjustWindowRectEx(&win_size, wi.dwStyle, GetMenu(win_display->window) ? TRUE : FALSE, wi.dwExStyle); + + // FIXME: Handle failure (for example if window constraints are active?) + SetWindowPos(win_display->window, HWND_TOP, + 0, 0, + win_size.right-win_size.left, + win_size.bottom-win_size.top, + SWP_NOMOVE|SWP_NOZORDER); + + if (!(d->flags & ALLEGRO_FULLSCREEN_WINDOW)) { + win_display->toggle_w = width; + win_display->toggle_h = height; + } + + /* + * The clipping rectangle and bitmap size must be + * changed to match the new size. + */ + al_store_state(&backup, ALLEGRO_STATE_TARGET_BITMAP); + al_set_target_bitmap(&disp->backbuffer_bmp); + disp->backbuffer_bmp.w = width; + disp->backbuffer_bmp.h = height; + al_set_clipping_rectangle(0, 0, width, height); + _al_d3d_set_bitmap_clip(&disp->backbuffer_bmp); + al_restore_state(&backup); + + } + + return true; +} + +static bool d3d_resize_display(ALLEGRO_DISPLAY *d, int width, int height) +{ + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)d; + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)d; + int orig_w = d->w; + int orig_h = d->h; + bool ret; + + al_backup_dirty_bitmaps(d); + + win_display->ignore_resize = true; + + if (!d3d_resize_helper(d, width, height)) { + ALLEGRO_WARN("trying to restore original size: %d, %d\n", + orig_w, orig_h); + if (!d3d_resize_helper(d, orig_w, orig_h)) { + ALLEGRO_ERROR("failed to restore original size: %d, %d\n", + orig_w, orig_h); + } + ret = false; + } else { + ret = true; + d3d_acknowledge_resize(d); + } + + win_display->ignore_resize = false; + + return ret; +} + +static ALLEGRO_BITMAP *d3d_create_bitmap(ALLEGRO_DISPLAY *d, + int w, int h, int format, int flags) +{ + ALLEGRO_BITMAP *bitmap; + ALLEGRO_BITMAP_EXTRA_D3D *extra; + + if (!_al_pixel_format_is_real(format)) { + format = d3d_choose_bitmap_format((ALLEGRO_DISPLAY_D3D *)d, format); + if (format < 0) { + return NULL; + } + } + + if (_al_pixel_format_to_d3d(format) < 0) { + ALLEGRO_ERROR("Requested bitmap format not supported (%s).\n", + _al_pixel_format_name((ALLEGRO_PIXEL_FORMAT)format)); + return NULL; + } + + if (!is_texture_format_ok(d, format)) { + ALLEGRO_ERROR("Requested bitmap format not supported (%s).\n", + _al_pixel_format_name((ALLEGRO_PIXEL_FORMAT)format)); + return NULL; + } + + bool compressed = _al_pixel_format_is_compressed(format); + if (compressed) { + if (!_al_d3d_render_to_texture_supported()) { + /* Not implemented. XXX: Why not? */ + return NULL; + } + } + int block_width = al_get_pixel_block_width(format); + int block_height = al_get_pixel_block_height(format); + int block_size = al_get_pixel_block_size(format); + + ALLEGRO_INFO("Chose bitmap format %d\n", format); + + bitmap = (ALLEGRO_BITMAP *)al_malloc(sizeof *bitmap); + ASSERT(bitmap); + memset(bitmap, 0, sizeof(*bitmap)); + + bitmap->vt = _al_bitmap_d3d_driver(); + bitmap->_format = format; + bitmap->_flags = flags; + al_identity_transform(&bitmap->transform); + + bitmap->pitch = + _al_get_least_multiple(w, block_width) / block_width * block_size; + bitmap->memory = (unsigned char *)al_malloc( + bitmap->pitch * _al_get_least_multiple(h, block_height) / block_height); + + extra = (ALLEGRO_BITMAP_EXTRA_D3D *)al_calloc(1, sizeof *extra); + bitmap->extra = extra; + extra->video_texture = 0; + extra->system_texture = 0; + extra->initialized = false; + extra->is_backbuffer = false; + extra->render_target = NULL; + extra->system_format = compressed ? ALLEGRO_PIXEL_FORMAT_ARGB_8888 : format; + + extra->display = (ALLEGRO_DISPLAY_D3D *)d; + + return bitmap; +} + +void _al_d3d_destroy_bitmap(ALLEGRO_BITMAP *bitmap) +{ + ASSERT(!al_is_sub_bitmap(bitmap)); + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D*)_al_get_bitmap_display(bitmap); + + if (bitmap == d3d_display->target_bitmap) { + d3d_display->target_bitmap = NULL; + } + + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap); + + if (d3d_bmp->video_texture) { + if (d3d_bmp->video_texture->Release() != 0) { + ALLEGRO_WARN("d3d_destroy_bitmap: Release video texture failed.\n"); + } + } + if (d3d_bmp->system_texture) { + if (d3d_bmp->system_texture->Release() != 0) { + ALLEGRO_WARN("d3d_destroy_bitmap: Release system texture failed.\n"); + } + } + + if (d3d_bmp->render_target) { + if (d3d_bmp->render_target->Release() != 0) { + ALLEGRO_WARN("d3d_destroy_bitmap: Release render target failed.\n"); + } + } + + al_free(bitmap->extra); +} + +static void d3d_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP *target; + ALLEGRO_BITMAP_EXTRA_D3D *d3d_target; + ALLEGRO_BITMAP_EXTRA_D3D *old_target = NULL; + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)display; + + if (d3d_display->device_lost) + return; + + if (bitmap->parent) { + target = bitmap->parent; + } + else { + target = bitmap; + } + + d3d_target = get_extra(target); + if (d3d_display->target_bitmap) + old_target = get_extra(d3d_display->target_bitmap); + + /* Release the previous target bitmap if it was not the backbuffer */ + if (old_target && !old_target->is_backbuffer) { + ALLEGRO_BITMAP *parent; + if (d3d_display->target_bitmap->parent) + parent = d3d_display->target_bitmap->parent; + else + parent = d3d_display->target_bitmap; + ALLEGRO_BITMAP_EXTRA_D3D *e = get_extra(parent); + if (e && e->render_target) { + e->render_target->Release(); + e->render_target = NULL; + } + } + d3d_display->target_bitmap = NULL; + + /* Set the render target */ + if (d3d_target->is_backbuffer) { + d3d_display = d3d_target->display; + if (d3d_display->device->SetRenderTarget(0, d3d_display->render_target) != D3D_OK) { + ALLEGRO_ERROR("d3d_set_target_bitmap: Unable to set render target to texture surface.\n"); + return; + } + d3d_target->render_target = d3d_display->render_target; + d3d_display->target_bitmap = bitmap; + } + else if (_al_pixel_format_is_compressed(al_get_bitmap_format(target))) { + /* Do nothing, as it is impossible to directly draw to compressed textures via D3D. + * Instead, everything will be handled by the memory routines. */ + } + else { + d3d_display = (ALLEGRO_DISPLAY_D3D *)display; + if (_al_d3d_render_to_texture_supported()) { + d3d_display->target_bitmap = bitmap; + if (!d3d_target->video_texture) { + /* This can happen if the user tries to set the target bitmap as + * the device is lost, before the DISPLAY_LOST event is received. + */ + ALLEGRO_WARN("d3d_set_target_bitmap: No video texture.\n"); + return; + } + if (d3d_target->video_texture->GetSurfaceLevel(0, &d3d_target->render_target) != D3D_OK) { + ALLEGRO_ERROR("d3d_set_target_bitmap: Unable to get texture surface level.\n"); + return; + } + if (d3d_display->device->SetRenderTarget(0, d3d_target->render_target) != D3D_OK) { + ALLEGRO_ERROR("d3d_set_target_bitmap: Unable to set render target to texture surface.\n"); + d3d_target->render_target->Release(); + return; + } + } + if (d3d_display->samples) { + d3d_display->device->SetDepthStencilSurface(NULL); + } + } + + d3d_reset_state(d3d_display); + + _al_d3d_set_bitmap_clip(bitmap); +} + +static ALLEGRO_BITMAP *d3d_get_backbuffer(ALLEGRO_DISPLAY *display) +{ + return (ALLEGRO_BITMAP *)&(((ALLEGRO_DISPLAY_D3D *)display)->backbuffer_bmp); +} + +static bool d3d_is_compatible_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) +{ + return display == _al_get_bitmap_display(bitmap); +} + +static void d3d_switch_out(ALLEGRO_DISPLAY *display) +{ + (void)display; +} + +static void d3d_switch_in(ALLEGRO_DISPLAY *display) +{ + (void)display; +} + +static bool d3d_wait_for_vsync(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_D3D *d3d_display; + D3DRASTER_STATUS status; + + if (!d3d_can_wait_for_vsync) + return false; + + d3d_display = (ALLEGRO_DISPLAY_D3D *)display; + + do { + d3d_display->device->GetRasterStatus(0, &status); + } while (!status.InVBlank); + + return true; +} + + +/* Exposed stuff */ + +/* Function: al_get_d3d_device + */ +LPDIRECT3DDEVICE9 al_get_d3d_device(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)display; + return d3d_display->device; +} + +/* Function: al_get_d3d_system_texture + */ +LPDIRECT3DTEXTURE9 al_get_d3d_system_texture(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_D3D *e = get_extra(bitmap); + return e->system_texture; +} + +/* Function: al_get_d3d_video_texture + */ +LPDIRECT3DTEXTURE9 al_get_d3d_video_texture(ALLEGRO_BITMAP *bitmap) +{ + ALLEGRO_BITMAP_EXTRA_D3D *e = get_extra(bitmap); + return e->video_texture; +} + +/* Function: al_get_d3d_texture_position + */ +void al_get_d3d_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v) +{ + ASSERT(bitmap); + ASSERT(u); + ASSERT(v); + + *u = bitmap->xofs; + *v = bitmap->yofs; +} + +/* Function: al_is_d3d_device_lost + */ +bool al_is_d3d_device_lost(ALLEGRO_DISPLAY *display) +{ + return ((ALLEGRO_DISPLAY_D3D *)display)->device_lost; +} + +static void d3d_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +{ + _al_win_set_window_position(((ALLEGRO_DISPLAY_WIN *)display)->window, x, y); +} + +static void d3d_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + if (display->flags & ALLEGRO_FULLSCREEN) { + ALLEGRO_MONITOR_INFO info; + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + al_get_monitor_info(win_display->adapter, &info); + *x = info.x1; + *y = info.y1; + } + else { + _al_win_get_window_position(((ALLEGRO_DISPLAY_WIN *)display)->window, x, y); + } +} + + +void _al_d3d_shutdown_display(void) +{ + if (!vt) + return; + + _al_d3d_destroy_display_format_list(); + + if (_al_d3d) + _al_d3d->Release(); + al_destroy_mutex(present_mutex); + al_destroy_mutex(_al_d3d_lost_device_mutex); + + _al_d3d_bmp_destroy(); + +#ifdef ALLEGRO_CFG_SHADER_HLSL + _al_d3d_shutdown_shaders(); +#endif + + FreeLibrary(_al_d3d_module); + _al_d3d_module = NULL; + +#ifdef ALLEGRO_CFG_D3DX9 + _al_unload_d3dx9_module(); +#endif + + al_free(vt); + vt = NULL; +} + +static void* d3d_prepare_vertex_cache(ALLEGRO_DISPLAY* disp, + int num_new_vertices) +{ + int size; + + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + size = sizeof(ALLEGRO_VERTEX); + } + else { + size = sizeof(D3D_FIXED_VERTEX); + } + + disp->num_cache_vertices += num_new_vertices; + if (!disp->vertex_cache) { + disp->vertex_cache = al_malloc(num_new_vertices * size); + + disp->vertex_cache_size = num_new_vertices; + } else if (disp->num_cache_vertices > disp->vertex_cache_size) { + disp->vertex_cache = al_realloc(disp->vertex_cache, + 2 * disp->num_cache_vertices * size); + + disp->vertex_cache_size = 2 * disp->num_cache_vertices; + } + return (unsigned char *)disp->vertex_cache + + (disp->num_cache_vertices - num_new_vertices) * size; +} + +static void d3d_flush_vertex_cache(ALLEGRO_DISPLAY* disp) +{ + if (!disp->vertex_cache) + return; + if (disp->num_cache_vertices == 0) + return; + + ALLEGRO_DISPLAY_D3D* d3d_disp = (ALLEGRO_DISPLAY_D3D*)disp; + ALLEGRO_BITMAP* cache_bmp = (ALLEGRO_BITMAP*)disp->cache_texture; + ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(cache_bmp); + int bitmap_flags = al_get_bitmap_flags(cache_bmp); + + if (d3d_disp->device_lost) + return; + + if (bitmap_flags & ALLEGRO_MIN_LINEAR) { + d3d_disp->device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + } + else { + d3d_disp->device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + } + if (bitmap_flags & ALLEGRO_MAG_LINEAR) { + d3d_disp->device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + } + else { + d3d_disp->device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + } + if (bitmap_flags & ALLEGRO_MIPMAP) { + d3d_disp->device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + } + else { + d3d_disp->device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + } + + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->device->SetFVF(D3DFVF_ALLEGRO_VERTEX); + } + +#ifdef ALLEGRO_CFG_SHADER_HLSL + UINT required_passes; + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->SetBool(ALLEGRO_SHADER_VAR_USE_TEX, true); + d3d_disp->effect->SetTexture(ALLEGRO_SHADER_VAR_TEX, d3d_bmp->video_texture); + d3d_disp->effect->Begin(&required_passes, 0); + ASSERT(required_passes > 0); + } +#endif + + if (d3d_disp->device->SetTexture(0, d3d_bmp->video_texture) != D3D_OK) { + ALLEGRO_ERROR("d3d_flush_vertex_cache: SetTexture failed.\n"); + return; + } + + int size; + +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + size = sizeof(ALLEGRO_VERTEX); + for (unsigned int i = 0; i < required_passes; i++) { + d3d_disp->effect->BeginPass(i); + if (d3d_disp->device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, disp->num_cache_vertices / 3, + (void *)disp->vertex_cache, size) != D3D_OK) { + ALLEGRO_ERROR("d3d_flush_vertex_cache: DrawPrimitive failed.\n"); + return; + } + d3d_disp->effect->EndPass(); + } + } + else +#endif + { + d3d_disp->device->SetFVF(D3DFVF_FIXED_VERTEX); + size = sizeof(D3D_FIXED_VERTEX); + if (d3d_disp->device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, disp->num_cache_vertices / 3, + (void *)disp->vertex_cache, size) != D3D_OK) { + ALLEGRO_ERROR("d3d_flush_vertex_cache: DrawPrimitive failed.\n"); + return; + } + } + + disp->num_cache_vertices = 0; +#ifdef ALLEGRO_CFG_SHADER_HLSL + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { + d3d_disp->effect->End(); + d3d_disp->effect->SetBool(ALLEGRO_SHADER_VAR_USE_TEX, false); + d3d_disp->effect->SetTexture(ALLEGRO_SHADER_VAR_TEX, NULL); + } +#endif + + d3d_disp->device->SetTexture(0, NULL); +} + +static void d3d_update_transformation(ALLEGRO_DISPLAY* disp, ALLEGRO_BITMAP *target) +{ + ALLEGRO_DISPLAY_D3D* d3d_disp = (ALLEGRO_DISPLAY_D3D*)disp; + ALLEGRO_TRANSFORM proj; + + al_copy_transform(&proj, &target->proj_transform); + /* Direct3D uses different clipping in projection space than OpenGL. + * In OpenGL the final clip space is [-1..1] x [-1..1] x [-1..1]. + * + * In D3D the clip space is [-1..1] x [-1..1] x [0..1]. + * + * So we need to scale and translate the final z component from [-1..1] + * to [0..1]. We do that by scaling with 0.5 then translating by 0.5 + * below. + * + * The effect can be seen for example ex_projection - it is broken + * without this. + */ + ALLEGRO_TRANSFORM fix_d3d; + al_identity_transform(&fix_d3d); + al_scale_transform_3d(&fix_d3d, 1, 1, 0.5); + al_translate_transform_3d(&fix_d3d, 0.0, 0.0, 0.5); + /* + * Shift by half a pixel to make the output match the OpenGL output. + * Don't shift the actual proj_transform because if the user grabs it via + * al_get_current_projection_transform() and then sends it to + * al_use_projection_transform() the shift will be applied twice. + */ + al_translate_transform(&fix_d3d, -1.0 / al_get_bitmap_width(target), + 1.0 / al_get_bitmap_height(target)); + + al_compose_transform(&proj, &fix_d3d); + + if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { +#ifdef ALLEGRO_CFG_SHADER_HLSL + LPD3DXEFFECT effect = d3d_disp->effect; + ALLEGRO_TRANSFORM projview; + al_copy_transform(&projview, &target->transform); + al_compose_transform(&projview, &proj); + al_copy_transform(&disp->projview_transform, &projview); + if (effect) { + _al_hlsl_set_projview_matrix(effect, &projview); + } +#endif + } + else { + d3d_disp->device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *)proj.m); + d3d_disp->device->SetTransform(D3DTS_VIEW, (D3DMATRIX *)target->transform.m); + } + + D3DVIEWPORT9 viewport; + viewport.MinZ = 0; + viewport.MaxZ = 1; + viewport.Width = al_get_bitmap_width(target); + viewport.Height = al_get_bitmap_height(target); + if (target->parent) { + viewport.X = target->xofs; + viewport.Y = target->yofs; + } + else { + viewport.X = 0; + viewport.Y = 0; + } + d3d_disp->device->SetViewport(&viewport); +} + +/* Initialize and obtain a reference to this driver. */ +ALLEGRO_DISPLAY_INTERFACE *_al_display_d3d_driver(void) +{ + if (vt) + return vt; + + if (!d3d_init_display()) + return NULL; + + vt = (ALLEGRO_DISPLAY_INTERFACE *)al_malloc(sizeof *vt); + memset(vt, 0, sizeof *vt); + + vt->create_display = d3d_create_display; + vt->destroy_display = d3d_destroy_display; + vt->set_current_display = d3d_set_current_display; + vt->clear = d3d_clear; + vt->clear_depth_buffer = d3d_clear_depth_buffer; + vt->draw_pixel = d3d_draw_pixel; + vt->flip_display = d3d_flip_display; + vt->update_display_region = d3d_update_display_region; + vt->acknowledge_resize = d3d_acknowledge_resize; + vt->resize_display = d3d_resize_display; + vt->create_bitmap = d3d_create_bitmap; + vt->set_target_bitmap = d3d_set_target_bitmap; + vt->get_backbuffer = d3d_get_backbuffer; + vt->is_compatible_bitmap = d3d_is_compatible_bitmap; + vt->switch_out = d3d_switch_out; + vt->switch_in = d3d_switch_in; + vt->draw_memory_bitmap_region = NULL; + vt->wait_for_vsync = d3d_wait_for_vsync; + + vt->set_mouse_cursor = _al_win_set_mouse_cursor; + vt->set_system_mouse_cursor = _al_win_set_system_mouse_cursor; + vt->show_mouse_cursor = _al_win_show_mouse_cursor; + vt->hide_mouse_cursor = _al_win_hide_mouse_cursor; + + vt->set_icons = _al_win_set_display_icons; + vt->set_window_position = d3d_set_window_position; + vt->get_window_position = d3d_get_window_position; + vt->set_window_constraints = _al_win_set_window_constraints; + vt->get_window_constraints = _al_win_get_window_constraints; + vt->apply_window_constraints = _al_win_apply_window_constraints; + vt->set_display_flag = _al_win_set_display_flag; + vt->set_window_title = _al_win_set_window_title; + + vt->flush_vertex_cache = d3d_flush_vertex_cache; + vt->prepare_vertex_cache = d3d_prepare_vertex_cache; + + vt->update_transformation = d3d_update_transformation; + + vt->update_render_state = _al_d3d_update_render_state; + + _al_win_add_clipboard_functions(vt); + + return vt; +} + +int _al_d3d_get_num_display_modes(int format, int refresh_rate, int flags) +{ + UINT num_modes; + UINT i, j; + D3DDISPLAYMODE display_mode; + int matches = 0; + + if (!_al_d3d && !d3d_init_display()) + return 0; + + (void)flags; + + /* If any, go through all formats */ + if (!_al_pixel_format_is_real(format)) { + j = 0; + } + /* Else find the matching format */ + else { + for (j = 0; allegro_formats[j] != -1; j++) { + if (allegro_formats[j] == format) + break; + } + if (allegro_formats[j] == -1) + return 0; + } + + for (; allegro_formats[j] != -1; j++) { + int adapter = al_get_new_display_adapter(); + if (adapter < 0) + adapter = 0; + + if (!_al_pixel_format_is_real(allegro_formats[j]) || _al_pixel_format_has_alpha(allegro_formats[j])) + continue; + + num_modes = _al_d3d->GetAdapterModeCount(adapter, (D3DFORMAT)d3d_formats[j]); + + for (i = 0; i < num_modes; i++) { + if (_al_d3d->EnumAdapterModes(adapter, (D3DFORMAT)d3d_formats[j], i, &display_mode) != D3D_OK) { + return matches; + } + if (refresh_rate && display_mode.RefreshRate != (unsigned)refresh_rate) + continue; + matches++; + } + + if (_al_pixel_format_is_real(format)) + break; + } + + return matches; +} + +ALLEGRO_DISPLAY_MODE *_al_d3d_get_display_mode(int index, int format, + int refresh_rate, int flags, ALLEGRO_DISPLAY_MODE *mode) +{ + UINT num_modes; + UINT i, j; + D3DDISPLAYMODE display_mode; + int matches = 0; + + if (!_al_d3d && !d3d_init_display()) + return NULL; + + (void)flags; + + /* If any, go through all formats */ + if (!_al_pixel_format_is_real(format)) { + j = 0; + } + /* Else find the matching format */ + else { + for (j = 0; allegro_formats[j] != -1; j++) { + if (allegro_formats[j] == format) + break; + } + if (allegro_formats[j] == -1) + return NULL; + } + + for (; allegro_formats[j] != -1; j++) { + int adapter = al_get_new_display_adapter(); + if (adapter < 0) + adapter = 0; + + if (!_al_pixel_format_is_real(allegro_formats[j]) || _al_pixel_format_has_alpha(allegro_formats[j])) + continue; + + num_modes = _al_d3d->GetAdapterModeCount(adapter, (D3DFORMAT)d3d_formats[j]); + + for (i = 0; i < num_modes; i++) { + if (_al_d3d->EnumAdapterModes(adapter, (D3DFORMAT)d3d_formats[j], i, &display_mode) != D3D_OK) { + return NULL; + } + if (refresh_rate && display_mode.RefreshRate != (unsigned)refresh_rate) + continue; + if (matches == index) { + mode->width = display_mode.Width; + mode->height = display_mode.Height; + mode->format = allegro_formats[j]; + mode->refresh_rate = display_mode.RefreshRate; + return mode; + } + matches++; + } + + if (_al_pixel_format_is_real(format)) + break; + } + + return mode; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/d3d_display_formats.cpp b/allegro/src/win/d3d_display_formats.cpp new file mode 100644 index 00000000..14f749a3 --- /dev/null +++ b/allegro/src/win/d3d_display_formats.cpp @@ -0,0 +1,191 @@ +#include "d3d.h" + +ALLEGRO_DEBUG_CHANNEL("d3d") + +struct DEPTH_STENCIL_DESC { + int d; + int s; + D3DFORMAT format; +}; + +static DEPTH_STENCIL_DESC depth_stencil_formats[] = { + { 0, 0, (D3DFORMAT)0 }, + { 32, 0, D3DFMT_D32 }, + { 15, 1, D3DFMT_D15S1 }, + { 24, 8, D3DFMT_D24S8 }, + { 24, 0, D3DFMT_D24X8 }, + { 24, 4, D3DFMT_D24X4S4 }, + { 16, 0, D3DFMT_D16 }, +}; + +static BOOL IsDepthFormatExisting(D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat) +{ + HRESULT hr = _al_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + AdapterFormat, + D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, + DepthFormat); + + return SUCCEEDED(hr); +} + +static const int D3D_DEPTH_FORMATS = sizeof(depth_stencil_formats) / sizeof(*depth_stencil_formats); + +static _AL_VECTOR eds_list; + +void _al_d3d_destroy_display_format_list(void) +{ + /* Free the display format list */ + for (int j = 0; j < (int)_al_vector_size(&eds_list); j++) { + void **eds = (void **)_al_vector_ref(&eds_list, j); + al_free(*eds); + } + _al_vector_free(&eds_list); +} + +void _al_d3d_generate_display_format_list(void) +{ + static bool fullscreen = !(al_get_new_display_flags() & ALLEGRO_FULLSCREEN); /* stop warning */ + static int adapter = ~al_get_new_display_adapter(); /* stop warning */ + int i; + + if (!_al_vector_is_empty(&eds_list) && (fullscreen == (bool)(al_get_new_display_flags() & ALLEGRO_FULLSCREEN)) + && (adapter == al_get_new_display_adapter())) { + return; + } + else if (!_al_vector_is_empty(&eds_list)) { + _al_d3d_destroy_display_format_list(); + } + + fullscreen = (al_get_new_display_flags() & ALLEGRO_FULLSCREEN) != 0; + adapter = al_get_new_display_adapter(); + if (adapter < 0) + adapter = 0; + + _al_vector_init(&eds_list, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS *)); + + /* Loop through each bit combination of: + * bit 0: 16/32 bit + * bit 1: single-buffer + * bit 2: vsync + */ + for (i = 0; i < 8; i++) { + int format_num = !!(i & 1); + int single_buffer = !!(i & 2); + int vsync = !!(i & 4); + int allegro_format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; + if (format_num == 1) allegro_format = ALLEGRO_PIXEL_FORMAT_RGB_565; + D3DFORMAT d3d_format = (D3DFORMAT)_al_pixel_format_to_d3d(allegro_format); + + /* Count available multisample quality levels. */ + DWORD quality_levels = 0; + + if (_al_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, d3d_format, + !fullscreen, D3DMULTISAMPLE_NONMASKABLE, &quality_levels) != D3D_OK) { + _al_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_REF, d3d_format, + !fullscreen, D3DMULTISAMPLE_NONMASKABLE, &quality_levels); + } + + /* Loop through available depth/stencil formats. */ + for (int j = 0; j < D3D_DEPTH_FORMATS; j++) { + if (j == 0 || IsDepthFormatExisting( + depth_stencil_formats[j].format, d3d_format)) { + DEPTH_STENCIL_DESC *ds = depth_stencil_formats + j; + for (int k = 0; k < (int)quality_levels + 1; k++) { + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, **peds; + peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS **)_al_vector_alloc_back(&eds_list); + eds = *peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS *)al_malloc(sizeof *eds); + memset(eds->settings, 0, sizeof(int) * ALLEGRO_DISPLAY_OPTIONS_COUNT); + + eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; + + if (format_num == 0) { + eds->settings[ALLEGRO_RED_SIZE] = 8; + eds->settings[ALLEGRO_GREEN_SIZE] = 8; + eds->settings[ALLEGRO_BLUE_SIZE] = 8; + eds->settings[ALLEGRO_RED_SHIFT] = 16; + eds->settings[ALLEGRO_GREEN_SHIFT] = 8; + eds->settings[ALLEGRO_BLUE_SHIFT] = 0; + eds->settings[ALLEGRO_COLOR_SIZE] = 32; + } + else if (format_num == 1) { + eds->settings[ALLEGRO_RED_SIZE] = 5; + eds->settings[ALLEGRO_GREEN_SIZE] = 6; + eds->settings[ALLEGRO_BLUE_SIZE] = 5; + eds->settings[ALLEGRO_RED_SHIFT] = 11; + eds->settings[ALLEGRO_GREEN_SHIFT] = 5; + eds->settings[ALLEGRO_BLUE_SHIFT] = 0; + eds->settings[ALLEGRO_COLOR_SIZE] = 16; + } + + if (single_buffer) { + eds->settings[ALLEGRO_SINGLE_BUFFER] = 1; + eds->settings[ALLEGRO_UPDATE_DISPLAY_REGION] = 1; + } + + if (vsync) { + eds->settings[ALLEGRO_VSYNC] = 1; + } + + eds->settings[ALLEGRO_DEPTH_SIZE] = ds->d; + eds->settings[ALLEGRO_STENCIL_SIZE] = ds->s; + + if (k > 1) { + eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 1; + // TODO: Is it ok to use the quality level here? + eds->settings[ALLEGRO_SAMPLES] = k; + } + } + } + } + + } + ALLEGRO_INFO("found %d format combinations\n", _al_vector_size(&eds_list)); +} + +void _al_d3d_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref) +{ + for (int i = 0; i < (int)_al_vector_size(&eds_list); i++) { + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, **peds; + peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS **)_al_vector_ref(&eds_list, i); + eds = *peds; + eds->score = _al_score_display_settings(eds, ref); + eds->index = i; + } + + qsort(eds_list._items, eds_list._size, eds_list._itemsize, _al_display_settings_sorter); +} + +/* Helper function for sorting pixel formats by index */ +static int d3d_display_list_resorter(const void *p0, const void *p1) +{ + const ALLEGRO_EXTRA_DISPLAY_SETTINGS *f0 = *((ALLEGRO_EXTRA_DISPLAY_SETTINGS **)p0); + const ALLEGRO_EXTRA_DISPLAY_SETTINGS *f1 = *((ALLEGRO_EXTRA_DISPLAY_SETTINGS **)p1); + + if (!f0) + return 1; + if (!f1) + return -1; + if (f0->index == f1->index) { + return 0; + } + else if (f0->index < f1->index) { + return -1; + } + else { + return 1; + } +} + +void _al_d3d_resort_display_settings(void) +{ + qsort(eds_list._items, eds_list._size, eds_list._itemsize, d3d_display_list_resorter); +} + +ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_d3d_get_display_settings(int i) +{ + if (i < (int)_al_vector_size(&eds_list)) + return *(ALLEGRO_EXTRA_DISPLAY_SETTINGS **)_al_vector_ref(&eds_list, i); + return NULL; +} diff --git a/allegro/src/win/d3d_render_state.cpp b/allegro/src/win/d3d_render_state.cpp new file mode 100644 index 00000000..f2c6f3c3 --- /dev/null +++ b/allegro/src/win/d3d_render_state.cpp @@ -0,0 +1,46 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_display.h" +#include "d3d.h" + +/* Note: synched to ALLEGRO_RENDER_FUNCTION values as array indices */ +static int _d3d_funcs[] = { + D3DCMP_NEVER, + D3DCMP_ALWAYS, + D3DCMP_LESS, + D3DCMP_EQUAL, + D3DCMP_LESSEQUAL, + D3DCMP_GREATER, + D3DCMP_NOTEQUAL, + D3DCMP_GREATEREQUAL +}; + +void _al_d3d_update_render_state(ALLEGRO_DISPLAY *display) +{ + _ALLEGRO_RENDER_STATE *r = &display->render_state; + ALLEGRO_DISPLAY_D3D *disp = (ALLEGRO_DISPLAY_D3D *)display; + + if (!disp->device) return; + + /* TODO: We could store the previous state and/or mark updated states to + * avoid so many redundant SetRenderState calls. + */ + + disp->device->SetRenderState(D3DRS_ALPHATESTENABLE, + r->alpha_test ? TRUE : FALSE); + disp->device->SetRenderState(D3DRS_ALPHAFUNC, _d3d_funcs[r->alpha_function]); + disp->device->SetRenderState(D3DRS_ALPHAREF, r->alpha_test_value); + + disp->device->SetRenderState(D3DRS_ZENABLE, + r->depth_test ? D3DZB_TRUE : D3DZB_FALSE); + disp->device->SetRenderState(D3DRS_ZFUNC, _d3d_funcs[r->depth_function]); + + disp->device->SetRenderState(D3DRS_ZWRITEENABLE, + (r->write_mask & ALLEGRO_MASK_DEPTH) ? TRUE : FALSE); + + disp->device->SetRenderState(D3DRS_COLORWRITEENABLE, + ((r->write_mask & ALLEGRO_MASK_RED) ? D3DCOLORWRITEENABLE_RED : 0) | + ((r->write_mask & ALLEGRO_MASK_GREEN) ? D3DCOLORWRITEENABLE_GREEN : 0) | + ((r->write_mask & ALLEGRO_MASK_BLUE) ? D3DCOLORWRITEENABLE_BLUE : 0) | + ((r->write_mask & ALLEGRO_MASK_ALPHA) ? D3DCOLORWRITEENABLE_ALPHA : 0)); + +} diff --git a/allegro/src/win/d3d_shader.cpp b/allegro/src/win/d3d_shader.cpp new file mode 100644 index 00000000..9f18a1f8 --- /dev/null +++ b/allegro/src/win/d3d_shader.cpp @@ -0,0 +1,455 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Direct3D shader support. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/allegro_direct3d.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_direct3d.h" +#include "allegro5/internal/aintern_shader.h" + +#ifdef ALLEGRO_CFG_SHADER_HLSL + +#include +#include + +#include "d3d.h" + +ALLEGRO_DEBUG_CHANNEL("shader") + +static _AL_VECTOR shaders; + +typedef struct ALLEGRO_SHADER_HLSL_S ALLEGRO_SHADER_HLSL_S; + +struct ALLEGRO_SHADER_HLSL_S +{ + ALLEGRO_SHADER shader; + LPD3DXEFFECT hlsl_shader; +}; + +static const char *null_source = ""; + +static const char *technique_source_vertex = + "technique TECH\n" + "{\n" + " pass p1\n" + " {\n" + " VertexShader = compile vs_2_0 vs_main();\n" + " PixelShader = null;\n" + " }\n" + "}\n"; + +static const char *technique_source_pixel = + "technique TECH\n" + "{\n" + " pass p1\n" + " {\n" + " VertexShader = null;\n" + " PixelShader = compile ps_2_0 ps_main();\n" + " }\n" + "}\n\n"; + +static const char *technique_source_both = + "technique TECH\n" + "{\n" + " pass p1\n" + " {\n" + " VertexShader = compile vs_2_0 vs_main();\n" + " PixelShader = compile ps_2_0 ps_main();\n" + " }\n" + "}\n"; + + +static bool hlsl_attach_shader_source(ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *source); +static bool hlsl_build_shader(ALLEGRO_SHADER *shader); +static bool hlsl_use_shader(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *display, + bool set_projview_matrix_from_display); +static void hlsl_unuse_shader(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *display); +static void hlsl_destroy_shader(ALLEGRO_SHADER *shader); +static void hlsl_on_lost_device(ALLEGRO_SHADER *shader); +static void hlsl_on_reset_device(ALLEGRO_SHADER *shader); +static bool hlsl_set_shader_sampler(ALLEGRO_SHADER *shader, + const char *name, ALLEGRO_BITMAP *bitmap, int unit); +static bool hlsl_set_shader_matrix(ALLEGRO_SHADER *shader, + const char *name, const ALLEGRO_TRANSFORM *matrix); +static bool hlsl_set_shader_int(ALLEGRO_SHADER *shader, + const char *name, int i); +static bool hlsl_set_shader_float(ALLEGRO_SHADER *shader, + const char *name, float f); +static bool hlsl_set_shader_int_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const int *i, int num_elems); +static bool hlsl_set_shader_float_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const float *f, int num_elems); +static bool hlsl_set_shader_bool(ALLEGRO_SHADER *shader, + const char *name, bool b); + +static struct ALLEGRO_SHADER_INTERFACE shader_hlsl_vt = +{ + hlsl_attach_shader_source, + hlsl_build_shader, + hlsl_use_shader, + hlsl_unuse_shader, + hlsl_destroy_shader, + hlsl_on_lost_device, + hlsl_on_reset_device, + hlsl_set_shader_sampler, + hlsl_set_shader_matrix, + hlsl_set_shader_int, + hlsl_set_shader_float, + hlsl_set_shader_int_vector, + hlsl_set_shader_float_vector, + hlsl_set_shader_bool +}; + +void _al_d3d_on_lost_shaders(ALLEGRO_DISPLAY *display) +{ + unsigned i; + (void)display; + + for (i = 0; i < _al_vector_size(&shaders); i++) { + ALLEGRO_SHADER **shader = (ALLEGRO_SHADER **)_al_vector_ref(&shaders, i); + (*shader)->vt->on_lost_device(*shader); + } +} + +void _al_d3d_on_reset_shaders(ALLEGRO_DISPLAY *display) +{ + unsigned i; + (void)display; + + for (i = 0; i < _al_vector_size(&shaders); i++) { + ALLEGRO_SHADER **shader = (ALLEGRO_SHADER **)_al_vector_ref(&shaders, i); + (*shader)->vt->on_reset_device(*shader); + } +} + +ALLEGRO_SHADER *_al_create_shader_hlsl(ALLEGRO_SHADER_PLATFORM platform) +{ + ALLEGRO_SHADER_HLSL_S *shader; + + if (NULL == _al_imp_D3DXCreateEffect) { + ALLEGRO_ERROR("D3DXCreateEffect unavailable\n"); + return NULL; + } + + shader = (ALLEGRO_SHADER_HLSL_S *)al_calloc(1, sizeof(ALLEGRO_SHADER_HLSL_S)); + if (!shader) + return NULL; + shader->shader.platform = platform; + shader->shader.vt = &shader_hlsl_vt; + _al_vector_init(&shader->shader.bitmaps, sizeof(ALLEGRO_BITMAP *)); + + // For simplicity, these fields are never NULL in this backend. + shader->shader.pixel_copy = al_ustr_new(""); + shader->shader.vertex_copy = al_ustr_new(""); + + ALLEGRO_SHADER **back = (ALLEGRO_SHADER **)_al_vector_alloc_back(&shaders); + *back = (ALLEGRO_SHADER *)shader; + + _al_add_display_invalidated_callback(al_get_current_display(), _al_d3d_on_lost_shaders); + _al_add_display_validated_callback(al_get_current_display(), _al_d3d_on_reset_shaders); + + return (ALLEGRO_SHADER *)shader; +} + +static bool hlsl_attach_shader_source(ALLEGRO_SHADER *shader, + ALLEGRO_SHADER_TYPE type, const char *source) +{ + bool add_technique; + ALLEGRO_USTR *full_source; + LPD3DXBUFFER errors; + const char *vertex_source, *pixel_source, *technique_source; + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + ALLEGRO_DISPLAY *display = al_get_current_display(); + ASSERT(display); + ASSERT(display->flags & ALLEGRO_DIRECT3D); + + if (source == NULL) { + if (type == ALLEGRO_VERTEX_SHADER) { + if (shader->vertex_copy) { + al_ustr_truncate(shader->vertex_copy, 0); + hlsl_shader->hlsl_shader->Release(); + } + vertex_source = null_source; + pixel_source = al_cstr(shader->pixel_copy); + } + else { + if (shader->pixel_copy) { + al_ustr_truncate(shader->pixel_copy, 0); + hlsl_shader->hlsl_shader->Release(); + } + pixel_source = null_source; + vertex_source = al_cstr(shader->vertex_copy); + } + } + else { + if (type == ALLEGRO_VERTEX_SHADER) { + vertex_source = source; + al_ustr_truncate(shader->vertex_copy, 0); + al_ustr_append_cstr(shader->vertex_copy, vertex_source); + pixel_source = al_cstr(shader->pixel_copy); + } + else { + pixel_source = source; + al_ustr_truncate(shader->pixel_copy, 0); + al_ustr_append_cstr(shader->pixel_copy, pixel_source); + vertex_source = al_cstr(shader->vertex_copy); + } + } + + if (vertex_source[0] == 0 && pixel_source[0] == 0) { + return false; + } + + if (strstr(vertex_source, "technique") || strstr(pixel_source, "technique")) + add_technique = false; + else + add_technique = true; + + if (add_technique) { + if (vertex_source[0] == 0) { + technique_source = technique_source_pixel; + } + else if (pixel_source[0] == 0) { + technique_source = technique_source_vertex; + } + else { + technique_source = technique_source_both; + } + } + else { + technique_source = null_source; + } + + // HLSL likes the source in one buffer + full_source = al_ustr_newf("%s\n#line 1\n%s\n%s\n", + vertex_source, pixel_source, technique_source); + + // Release the shader if we already created it + if (hlsl_shader->hlsl_shader) + hlsl_shader->hlsl_shader->Release(); + + DWORD ok = _al_imp_D3DXCreateEffect( + al_get_d3d_device(display), + al_cstr(full_source), + al_ustr_size(full_source), + NULL, + NULL, + D3DXSHADER_PACKMATRIX_ROWMAJOR, + NULL, + &hlsl_shader->hlsl_shader, + &errors + ); + + al_ustr_free(full_source); + + if (ok != D3D_OK) { + hlsl_shader->hlsl_shader = NULL; + char *msg = (char *)errors->GetBufferPointer(); + if (shader->log) { + al_ustr_truncate(shader->log, 0); + al_ustr_append_cstr(shader->log, msg); + } else { + shader->log = al_ustr_new(msg); + } + ALLEGRO_ERROR("Error: %s\n", msg); + return false; + } + + D3DXHANDLE hTech; + hTech = hlsl_shader->hlsl_shader->GetTechniqueByName("TECH"); + hlsl_shader->hlsl_shader->ValidateTechnique(hTech); + hlsl_shader->hlsl_shader->SetTechnique(hTech); + + return true; +} + +static bool hlsl_build_shader(ALLEGRO_SHADER *shader) +{ + (void)shader; + return true; +} + +static bool hlsl_use_shader(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *display, + bool set_projview_matrix_from_display) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + LPD3DXEFFECT effect = hlsl_shader->hlsl_shader; + ALLEGRO_DISPLAY_D3D *d3d_disp; + + if (!(display->flags & ALLEGRO_DIRECT3D)) { + return false; + } + d3d_disp = (ALLEGRO_DISPLAY_D3D *)display; + + if (set_projview_matrix_from_display) { + if (!_al_hlsl_set_projview_matrix(effect, &display->projview_transform)) { + d3d_disp->effect = NULL; + return false; + } + } + + d3d_disp->effect = hlsl_shader->hlsl_shader; + return true; +} + +static void hlsl_unuse_shader(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_D3D *d3d_disp = (ALLEGRO_DISPLAY_D3D *)display; + + (void)shader; + //effect->EndPass(); + //effect->End(); + d3d_disp->effect = NULL; +} + +static void hlsl_destroy_shader(ALLEGRO_SHADER *shader) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + + if (hlsl_shader->hlsl_shader) + hlsl_shader->hlsl_shader->Release(); + + _al_vector_find_and_delete(&shaders, &shader); + + al_free(shader); +} + +static void hlsl_on_lost_device(ALLEGRO_SHADER *shader) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + hlsl_shader->hlsl_shader->OnLostDevice(); +} + +static void hlsl_on_reset_device(ALLEGRO_SHADER *shader) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + hlsl_shader->hlsl_shader->OnResetDevice(); +} + +static bool hlsl_set_shader_sampler(ALLEGRO_SHADER *shader, + const char *name, ALLEGRO_BITMAP *bitmap, int unit) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + + (void)unit; + + if (al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP) + return false; + + LPDIRECT3DTEXTURE9 vid_texture = al_get_d3d_video_texture(bitmap); + result = hlsl_shader->hlsl_shader->SetTexture(name, vid_texture); + ((ALLEGRO_DISPLAY_D3D *)_al_get_bitmap_display(bitmap)) + ->device->SetTexture(0, vid_texture); + + return result == D3D_OK; +} + +static bool hlsl_set_shader_matrix(ALLEGRO_SHADER *shader, + const char *name, const ALLEGRO_TRANSFORM *matrix) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + + D3DXMATRIX m; + + memcpy(m.m, matrix->m, sizeof(float)*16); + + result = hlsl_shader->hlsl_shader->SetMatrix(name, &m); + + return result == D3D_OK; +} + +static bool hlsl_set_shader_int(ALLEGRO_SHADER *shader, + const char *name, int i) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + + result = hlsl_shader->hlsl_shader->SetInt(name, i); + + return result == D3D_OK; +} + +static bool hlsl_set_shader_float(ALLEGRO_SHADER *shader, + const char *name, float f) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + + result = hlsl_shader->hlsl_shader->SetFloat(name, f); + + return result == D3D_OK; +} + +static bool hlsl_set_shader_int_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const int *i, int num_elems) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + + result = hlsl_shader->hlsl_shader->SetIntArray(name, i, + num_components * num_elems); + + return result == D3D_OK; +} + +static bool hlsl_set_shader_float_vector(ALLEGRO_SHADER *shader, + const char *name, int num_components, const float *f, int num_elems) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + + result = hlsl_shader->hlsl_shader->SetFloatArray(name, f, + num_components * num_elems); + + return result == D3D_OK; +} + +static bool hlsl_set_shader_bool(ALLEGRO_SHADER *shader, + const char *name, bool b) +{ + ALLEGRO_SHADER_HLSL_S *hlsl_shader = (ALLEGRO_SHADER_HLSL_S *)shader; + HRESULT result; + + result = hlsl_shader->hlsl_shader->SetBool(name, b); + + return result == D3D_OK; +} + +bool _al_hlsl_set_projview_matrix( + LPD3DXEFFECT effect, const ALLEGRO_TRANSFORM *t) +{ + HRESULT result = effect->SetMatrix(ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX, + (LPD3DXMATRIX)t->m); + return result == D3D_OK; +} + +void _al_d3d_init_shaders(void) +{ + _al_vector_init(&shaders, sizeof(ALLEGRO_SHADER *)); +} + +void _al_d3d_shutdown_shaders(void) +{ + _al_vector_free(&shaders); +} + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/wclipboard.c b/allegro/src/win/wclipboard.c new file mode 100644 index 00000000..08cc57bd --- /dev/null +++ b/allegro/src/win/wclipboard.c @@ -0,0 +1,143 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_//_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows clipboard handling. + * + * By Beoran. + * + * See readme.txt for copyright information. + */ + + +#define _WIN32_WINNT 0x0501 +#ifndef WINVER +#define WINVER 0x0501 +#endif + +#include +#include + + +#include + +#include "allegro5/allegro_windows.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_wclipboard.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_wunicode.h" +#include "allegro5/platform/aintwin.h" + + +ALLEGRO_DEBUG_CHANNEL("clipboard") + +#ifdef UNICODE +#define TEXT_FORMAT CF_UNICODETEXT +#else +#define TEXT_FORMAT CF_TEXT +#endif + + +/* Get any application owned window handle for clipboard association */ +static HWND get_window_handle(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + if (!win_display) + return NULL; + + return win_display->window; +} + +static bool win_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text) +{ + HWND handle = get_window_handle(display); + HANDLE hMem = NULL; + TCHAR *tstr = NULL; + size_t size; + size_t len; + LPTSTR dst; + + if (!OpenClipboard(handle)) { + ALLEGRO_DEBUG("Could not open clipboard for handle %p", handle); + return false; + } + + /* Convert the text from UTF-8 to Windows Unicode */ + tstr = _twin_utf8_to_tchar(text); + len = _twin_tchar_strlen(tstr); + size = (len+1) * sizeof(TCHAR); + /* Save the data to the clipboard */ + hMem = GlobalAlloc(GMEM_MOVEABLE, size); + + if (!hMem) { + al_free(tstr); + ALLEGRO_DEBUG("GlobalAlloc failed to allocate memory for the clipboard data"); + return false; + } + + dst = (LPTSTR)GlobalLock(hMem); + /* Copy the text over. Unlike SDL, do NOT convert newlines, that's for the + * use to decide. */ + memmove(dst, tstr, size); + dst[len] = 0; + GlobalUnlock(hMem); + EmptyClipboard(); + if (!SetClipboardData(TEXT_FORMAT, hMem)) { + al_free(tstr); + ALLEGRO_DEBUG("Couldn't set clipboard data"); + return false; + } + al_free(tstr); + CloseClipboard(); + return true; +} + +static char *win_get_clipboard_text(ALLEGRO_DISPLAY *display) +{ + char *text; + + text = NULL; + if (IsClipboardFormatAvailable(TEXT_FORMAT) && + OpenClipboard(get_window_handle(display))) { + HANDLE hMem; + LPTSTR tstr; + + hMem = GetClipboardData(TEXT_FORMAT); + if (hMem) { + tstr = (LPTSTR)GlobalLock(hMem); + text = _twin_tchar_to_utf8(tstr); + GlobalUnlock(hMem); + } else { + ALLEGRO_DEBUG("Couldn't get clipboard data"); + } + CloseClipboard(); + } + return text; +} + +static bool win_has_clipboard_text(ALLEGRO_DISPLAY *display) +{ + if (!IsClipboardFormatAvailable(TEXT_FORMAT)) + return false; + if (!OpenClipboard(get_window_handle(display))) + return false; + + CloseClipboard(); + return true; +} + + +void _al_win_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt) +{ + vt->set_clipboard_text = win_set_clipboard_text; + vt->get_clipboard_text = win_get_clipboard_text; + vt->has_clipboard_text = win_has_clipboard_text; +} + +/* vi: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/src/win/wgl.h b/allegro/src/win/wgl.h new file mode 100644 index 00000000..c8363e56 --- /dev/null +++ b/allegro/src/win/wgl.h @@ -0,0 +1,16 @@ +#include "allegro5/internal/aintern_display.h" +#include "allegro5/platform/aintwin.h" + +#include + + +typedef struct ALLEGRO_DISPLAY_WGL +{ + ALLEGRO_DISPLAY_WIN win_display; /* This must be the first member. */ + + /* Driver specifics */ + HDC dc; + HGLRC glrc; +} ALLEGRO_DISPLAY_WGL; + +int _al_win_determine_adapter(void); diff --git a/allegro/src/win/wgl_disp.c b/allegro/src/win/wgl_disp.c new file mode 100644 index 00000000..ae857918 --- /dev/null +++ b/allegro/src/win/wgl_disp.c @@ -0,0 +1,1642 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows OpenGL display driver + * + * By Milan Mimica. + * Based on AllegroGL Windows display driver. + * + */ + +#if 0 +/* Raw input */ +#define _WIN32_WINNT 0x0501 +#ifndef WINVER +#define WINVER 0x0501 +#endif +#endif + +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/system.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/internal/aintern_wclipboard.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_wunicode.h" + +#include "wgl.h" + +#include + +ALLEGRO_DEBUG_CHANNEL("display") + +static ALLEGRO_DISPLAY_INTERFACE vt; + +/* Forward declarations: */ +static void display_thread_proc(void *arg); +static void destroy_display_internals(ALLEGRO_DISPLAY_WGL *wgl_disp); +static bool wgl_acknowledge_resize(ALLEGRO_DISPLAY *d); + +/* Prevents switching to desktop resolution when destroying the display. Used + on full screen resize. */ +static bool _wgl_do_not_change_display_mode = false; + +/* + * These parameters cannot be gotten by the display thread because + * they're thread local. We get them in the calling thread first. + */ +typedef struct WGL_DISPLAY_PARAMETERS { + ALLEGRO_DISPLAY_WGL *display; + volatile bool init_failed; + HANDLE AckEvent; + int window_x, window_y; + /* Not owned. */ + const char* window_title; +} WGL_DISPLAY_PARAMETERS; + +static bool is_wgl_extension_supported(_ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB, const char *extension, HDC dc) +{ + int ret; + + /* XXX deprecated in OpenGL 3.0 */ + if (!glGetString(GL_EXTENSIONS)) + return false; + if (!_wglGetExtensionsStringARB) + return false; + + ret = _al_ogl_look_for_an_extension(extension, + (const GLubyte*)_wglGetExtensionsStringARB(dc)); + + return ret; +} + + +static HGLRC init_temp_context(HWND wnd) +{ + PIXELFORMATDESCRIPTOR pfd; + int pf; + HDC dc; + HGLRC glrc; + + dc = GetDC(wnd); + + memset(&pfd, 0, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL + | PFD_DOUBLEBUFFER_DONTCARE | PFD_STEREO_DONTCARE; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.iLayerType = PFD_MAIN_PLANE; + pfd.cColorBits = 32; + + pf = ChoosePixelFormat(dc, &pfd); + if (!pf) { + ALLEGRO_ERROR("Unable to chose a temporary pixel format. %s\n", + _al_win_last_error()); + return NULL; + } + + memset(&pfd, 0, sizeof(pfd)); + if (!SetPixelFormat(dc, pf, &pfd)) { + ALLEGRO_ERROR("Unable to set a temporary pixel format. %s\n", + _al_win_last_error()); + return NULL; + } + + glrc = wglCreateContext(dc); + if (!glrc) { + ALLEGRO_ERROR("Unable to create a render context. %s\n", + _al_win_last_error()); + return NULL; + } + + if (!wglMakeCurrent(dc, glrc)) { + ALLEGRO_ERROR("Unable to set the render context as current. %s\n", + _al_win_last_error()); + wglDeleteContext(glrc); + return NULL; + } + + return glrc; +} + + +static _ALLEGRO_wglGetPixelFormatAttribivARB_t _wglGetPixelFormatAttribivARB = NULL; +static _ALLEGRO_wglGetPixelFormatAttribivEXT_t _wglGetPixelFormatAttribivEXT = NULL; + +static bool init_pixel_format_extensions(void) +{ + /* Load the ARB_p_f symbol - Note, we shouldn't use the extension + * mechanism here, because it hasn't been initialized yet! + */ + _wglGetPixelFormatAttribivARB = + (_ALLEGRO_wglGetPixelFormatAttribivARB_t)wglGetProcAddress("wglGetPixelFormatAttribivARB"); + _wglGetPixelFormatAttribivEXT = + (_ALLEGRO_wglGetPixelFormatAttribivEXT_t)wglGetProcAddress("wglGetPixelFormatAttribivEXT"); + + if (!_wglGetPixelFormatAttribivARB && !_wglGetPixelFormatAttribivEXT) { + ALLEGRO_ERROR("WGL_ARB/EXT_pf not supported.\n"); + return false; + } + + return true; +} + + +static _ALLEGRO_wglCreateContextAttribsARB_t _wglCreateContextAttribsARB = NULL; + +static bool init_context_creation_extensions(void) +{ + _wglCreateContextAttribsARB = + (_ALLEGRO_wglCreateContextAttribsARB_t)wglGetProcAddress("wglCreateContextAttribsARB"); + + if (!_wglCreateContextAttribsARB) { + ALLEGRO_ERROR("wglCreateContextAttribs not supported!\n"); + return false; + } + + return true; +} + + +static int get_pixel_formats_count_old(HDC dc) +{ + PIXELFORMATDESCRIPTOR pfd; + int ret; + + ret = DescribePixelFormat(dc, 1, sizeof(pfd), &pfd); + if (!ret) { + ALLEGRO_ERROR("DescribePixelFormat failed! %s\n", + _al_win_last_error()); + } + + return ret; +} + + +static int get_pixel_formats_count_ext(HDC dc) +{ + int attrib[1]; + int value[1]; + + attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB; + if ((_wglGetPixelFormatAttribivARB(dc, 0, 0, 1, attrib, value) == GL_FALSE) + && (_wglGetPixelFormatAttribivEXT(dc, 0, 0, 1, attrib, value) == GL_FALSE)) { + ALLEGRO_ERROR("WGL_ARB/EXT_pixel_format use failed! %s\n", + _al_win_last_error()); + } + + return value[0]; +} + + +static void display_pixel_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) +{ + ALLEGRO_INFO("Accelerated: %s\n", eds->settings[ALLEGRO_RENDER_METHOD] ? "yes" : "no"); + ALLEGRO_INFO("Single-buffer: %s\n", eds->settings[ALLEGRO_SINGLE_BUFFER] ? "yes" : "no"); + if (eds->settings[ALLEGRO_SWAP_METHOD] > 0) + ALLEGRO_INFO("Swap method: %s\n", eds->settings[ALLEGRO_SWAP_METHOD] == 2 ? "flip" : "copy"); + else + ALLEGRO_INFO("Swap method: undefined\n"); + ALLEGRO_INFO("Color format: r%i g%i b%i a%i, %i bit\n", + eds->settings[ALLEGRO_RED_SIZE], + eds->settings[ALLEGRO_GREEN_SIZE], + eds->settings[ALLEGRO_BLUE_SIZE], + eds->settings[ALLEGRO_ALPHA_SIZE], + eds->settings[ALLEGRO_COLOR_SIZE]); + ALLEGRO_INFO("Depth buffer: %i bits\n", eds->settings[ALLEGRO_DEPTH_SIZE]); + ALLEGRO_INFO("Sample buffers: %s\n", eds->settings[ALLEGRO_SAMPLE_BUFFERS] ? "yes" : "no"); + ALLEGRO_INFO("Samples: %i\n", eds->settings[ALLEGRO_SAMPLES]); +} + + +static int decode_pixel_format_old(PIXELFORMATDESCRIPTOR *pfd, + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) +{ + ALLEGRO_INFO("Decoding:\n"); + + /* Not interested if it doesn't support OpenGL and RGBA */ + if (!(pfd->dwFlags & PFD_SUPPORT_OPENGL)) { + ALLEGRO_INFO("OpenGL Unsupported\n"); + return false; + } + if (pfd->iPixelType != PFD_TYPE_RGBA) { + ALLEGRO_INFO("Not RGBA mode\n"); + return false; + } + + /* hardware acceleration */ + if (((pfd->dwFlags & PFD_GENERIC_ACCELERATED) && (pfd->dwFlags & PFD_GENERIC_FORMAT)) + || (!(pfd->dwFlags & PFD_GENERIC_ACCELERATED) && !(pfd->dwFlags & PFD_GENERIC_FORMAT))) + eds->settings[ALLEGRO_RENDER_METHOD] = 1; + else + eds->settings[ALLEGRO_RENDER_METHOD] = 0; + + /* Depths of colour buffers */ + eds->settings[ALLEGRO_RED_SIZE] = pfd->cRedBits; + eds->settings[ALLEGRO_GREEN_SIZE] = pfd->cGreenBits; + eds->settings[ALLEGRO_BLUE_SIZE] = pfd->cBlueBits; + eds->settings[ALLEGRO_ALPHA_SIZE] = pfd->cAlphaBits; + + /* Depths of accumulation buffer */ + eds->settings[ALLEGRO_ACC_RED_SIZE] = pfd->cAccumRedBits; + eds->settings[ALLEGRO_ACC_GREEN_SIZE] = pfd->cAccumGreenBits; + eds->settings[ALLEGRO_ACC_BLUE_SIZE] = pfd->cAccumBlueBits; + eds->settings[ALLEGRO_ACC_ALPHA_SIZE] = pfd->cAccumAlphaBits; + + /* Miscellaneous settings */ + eds->settings[ALLEGRO_SINGLE_BUFFER] = !(pfd->dwFlags & PFD_DOUBLEBUFFER); + eds->settings[ALLEGRO_DEPTH_SIZE] = pfd->cDepthBits; + eds->settings[ALLEGRO_STENCIL_SIZE] = pfd->cStencilBits; + eds->settings[ALLEGRO_COLOR_SIZE] = pfd->cColorBits; + eds->settings[ALLEGRO_STEREO] = pfd->dwFlags & PFD_STEREO; + eds->settings[ALLEGRO_AUX_BUFFERS] = pfd->cAuxBuffers; + + /* These are the component shifts. */ + eds->settings[ALLEGRO_RED_SHIFT] = pfd->cRedShift; + eds->settings[ALLEGRO_GREEN_SHIFT] = pfd->cGreenShift; + eds->settings[ALLEGRO_BLUE_SHIFT] = pfd->cBlueShift; + eds->settings[ALLEGRO_ALPHA_SHIFT] = pfd->cAlphaShift; + + /* Multisampling isn't supported under Windows if we don't also use + * WGL_ARB_pixel_format or WGL_EXT_pixel_format. + */ + eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 0; + eds->settings[ALLEGRO_SAMPLES] = 0; + + /* Swap method can't be detected without WGL_ARB_pixel_format or + * WGL_EXT_pixel_format + */ + eds->settings[ALLEGRO_SWAP_METHOD] = 0; + + /* Float depth/color isn't supported under Windows if we don't also use + * AGL_ARB_pixel_format or WGL_EXT_pixel_format. + */ + eds->settings[ALLEGRO_FLOAT_COLOR] = 0; + eds->settings[ALLEGRO_FLOAT_DEPTH] = 0; + + // FIXME + + eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; + + return true; +} + + +static bool decode_pixel_format_attrib(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, int num_attribs, + const int *attrib, const int *value) +{ + int i; + + ALLEGRO_INFO("Decoding:\n"); + + eds->settings[ALLEGRO_SAMPLES] = 0; + eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 0; + eds->settings[ALLEGRO_FLOAT_DEPTH] = 0; + eds->settings[ALLEGRO_FLOAT_COLOR] = 0; + eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; + + for (i = 0; i < num_attribs; i++) { + /* Not interested if it doesn't support OpenGL or window drawing or RGBA. */ + if (attrib[i] == WGL_SUPPORT_OPENGL_ARB && value[i] == 0) { + ALLEGRO_INFO("OpenGL Unsupported\n"); + return false; + } + else if (attrib[i] == WGL_DRAW_TO_WINDOW_ARB && value[i] == 0) { + ALLEGRO_INFO("Can't draw to window\n"); + return false; + } + else if (attrib[i] == WGL_PIXEL_TYPE_ARB + && (value[i] != WGL_TYPE_RGBA_ARB && value[i] != WGL_TYPE_RGBA_FLOAT_ARB)) { + ALLEGRO_INFO("Not RGBA mode\n"); + return false; + } + /* hardware acceleration */ + else if (attrib[i] == WGL_ACCELERATION_ARB) { + eds->settings[ALLEGRO_RENDER_METHOD] = (value[i] == WGL_NO_ACCELERATION_ARB) ? 0 : 1; + } + /* Depths of colour buffers */ + else if (attrib[i] == WGL_RED_BITS_ARB) { + eds->settings[ALLEGRO_RED_SIZE] = value[i]; + } + else if (attrib[i] == WGL_GREEN_BITS_ARB) { + eds->settings[ALLEGRO_GREEN_SIZE] = value[i]; + } + else if (attrib[i] == WGL_BLUE_BITS_ARB) { + eds->settings[ALLEGRO_BLUE_SIZE] = value[i]; + } + else if (attrib[i] == WGL_ALPHA_BITS_ARB) { + eds->settings[ALLEGRO_ALPHA_SIZE] = value[i]; + } + /* Shift of color components */ + else if (attrib[i] == WGL_RED_SHIFT_ARB) { + eds->settings[ALLEGRO_RED_SHIFT] = value[i]; + } + else if (attrib[i] == WGL_GREEN_SHIFT_ARB) { + eds->settings[ALLEGRO_GREEN_SHIFT] = value[i]; + } + else if (attrib[i] == WGL_BLUE_SHIFT_ARB) { + eds->settings[ALLEGRO_BLUE_SHIFT] = value[i]; + } + else if (attrib[i] == WGL_ALPHA_SHIFT_ARB) { + eds->settings[ALLEGRO_ALPHA_SHIFT] = value[i]; + } + /* Miscellaneous settings */ + else if (attrib[i] == WGL_DOUBLE_BUFFER_ARB) { + eds->settings[ALLEGRO_SINGLE_BUFFER] = !(value[i]); + } + else if (attrib[i] == WGL_SWAP_METHOD_ARB) { + if (value[i] == WGL_SWAP_UNDEFINED_ARB) + eds->settings[ALLEGRO_SWAP_METHOD] = 0; + else if (value[i] == WGL_SWAP_COPY_ARB) + eds->settings[ALLEGRO_SWAP_METHOD] = 1; + else if (value[i] == WGL_SWAP_EXCHANGE_ARB) + eds->settings[ALLEGRO_SWAP_METHOD] = 2; + } + + else if (attrib[i] == WGL_STEREO_ARB) { + eds->settings[ALLEGRO_STEREO] = value[i]; + } + else if (attrib[i] == WGL_AUX_BUFFERS_ARB) { + eds->settings[ALLEGRO_AUX_BUFFERS] = value[i]; + } + else if (attrib[i] == WGL_STENCIL_BITS_ARB) { + eds->settings[ALLEGRO_STENCIL_SIZE] = value[i]; + } + /* Depths of accumulation buffer */ + else if (attrib[i] == WGL_ACCUM_RED_BITS_ARB) { + eds->settings[ALLEGRO_ACC_RED_SIZE] = value[i]; + } + else if (attrib[i] == WGL_ACCUM_GREEN_BITS_ARB) { + eds->settings[ALLEGRO_ACC_GREEN_SIZE] = value[i]; + } + else if (attrib[i] == WGL_ACCUM_BLUE_BITS_ARB) { + eds->settings[ALLEGRO_ACC_BLUE_SIZE] = value[i]; + } + else if (attrib[i] == WGL_ACCUM_ALPHA_BITS_ARB) { + eds->settings[ALLEGRO_ACC_ALPHA_SIZE] = value[i]; + } + + else if (attrib[i] == WGL_DEPTH_BITS_ARB) { + eds->settings[ALLEGRO_DEPTH_SIZE] = value[i]; + } + else if (attrib[i] == WGL_COLOR_BITS_ARB) { + eds->settings[ALLEGRO_COLOR_SIZE] = value[i]; + } + /* Multisampling bits */ + else if (attrib[i] == WGL_SAMPLE_BUFFERS_ARB) { + eds->settings[ALLEGRO_SAMPLE_BUFFERS] = value[i]; + } + else if (attrib[i] == WGL_SAMPLES_ARB) { + eds->settings[ALLEGRO_SAMPLES] = value[i]; + } + /* Float color */ + if (attrib[i] == WGL_PIXEL_TYPE_ARB && value[i] == WGL_TYPE_RGBA_FLOAT_ARB) { + eds->settings[ALLEGRO_FLOAT_COLOR] = true; + } + /* Float depth */ + else if (attrib[i] == WGL_DEPTH_FLOAT_EXT) { + eds->settings[ALLEGRO_FLOAT_DEPTH] = value[i]; + } + } + + return true; +} + + +static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_pixel_format_old(int fmt, HDC dc) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = NULL; + PIXELFORMATDESCRIPTOR pfd; + int result; + + result = DescribePixelFormat(dc, fmt+1, sizeof(pfd), &pfd); + if (!result) { + ALLEGRO_WARN("DescribePixelFormat() failed. %s\n", _al_win_last_error()); + return NULL; + } + + eds = al_calloc(1, sizeof *eds); + if (!decode_pixel_format_old(&pfd, eds)) { + al_free(eds); + return NULL; + } + + return eds; +} + + +static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_pixel_format_ext(_ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB, int fmt, HDC dc) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = NULL; + + /* Note: Even though we use te ARB suffix, all those enums are compatible + * with EXT_pixel_format. + */ + int attrib[] = { + WGL_SUPPORT_OPENGL_ARB, + WGL_DRAW_TO_WINDOW_ARB, + WGL_PIXEL_TYPE_ARB, + WGL_ACCELERATION_ARB, + WGL_DOUBLE_BUFFER_ARB, + WGL_DEPTH_BITS_ARB, + WGL_SWAP_METHOD_ARB, + WGL_COLOR_BITS_ARB, + WGL_RED_BITS_ARB, + WGL_GREEN_BITS_ARB, + WGL_BLUE_BITS_ARB, + WGL_ALPHA_BITS_ARB, + WGL_RED_SHIFT_ARB, + WGL_GREEN_SHIFT_ARB, + WGL_BLUE_SHIFT_ARB, + WGL_ALPHA_SHIFT_ARB, + WGL_STENCIL_BITS_ARB, + WGL_STEREO_ARB, + WGL_ACCUM_BITS_ARB, + WGL_ACCUM_RED_BITS_ARB, + WGL_ACCUM_GREEN_BITS_ARB, + WGL_ACCUM_BLUE_BITS_ARB, + WGL_ACCUM_ALPHA_BITS_ARB, + WGL_AUX_BUFFERS_ARB, + + /* The following are used by extensions that add to WGL_pixel_format. + * If WGL_p_f isn't supported though, we can't use the (then invalid) + * enums. We can't use any magic number either, so we settle for + * replicating one. The pixel format decoder + * (decode_pixel_format_attrib()) doesn't care about duplicates. + */ + WGL_AUX_BUFFERS_ARB, /* placeholder for WGL_SAMPLE_BUFFERS_ARB */ + WGL_AUX_BUFFERS_ARB, /* placeholder for WGL_SAMPLES_ARB */ + WGL_AUX_BUFFERS_ARB, /* placeholder for WGL_DEPTH_FLOAT_EXT */ + }; + + const int num_attribs = sizeof(attrib) / sizeof(attrib[0]); + int *value = (int*)al_malloc(sizeof(int) * num_attribs); + int ret; + + if (!value) + return NULL; + + /* If multisampling is supported, query for it. */ + if (is_wgl_extension_supported(_wglGetExtensionsStringARB, "WGL_ARB_multisample", dc)) { + attrib[num_attribs - 3] = WGL_SAMPLE_BUFFERS_ARB; + attrib[num_attribs - 2] = WGL_SAMPLES_ARB; + } + if (is_wgl_extension_supported(_wglGetExtensionsStringARB, "WGL_EXT_depth_float", dc)) { + attrib[num_attribs - 1] = WGL_DEPTH_FLOAT_EXT; + } + + /* Get the pf attributes */ + if (_wglGetPixelFormatAttribivARB) { + ret = _wglGetPixelFormatAttribivARB(dc, fmt+1, 0, num_attribs, attrib, value); + } + else if (_wglGetPixelFormatAttribivEXT) { + ret = _wglGetPixelFormatAttribivEXT(dc, fmt+1, 0, num_attribs, attrib, value); + } + else { + ret = 0; + } + + if (!ret) { + ALLEGRO_ERROR("wglGetPixelFormatAttrib failed! %s\n", _al_win_last_error()); + al_free(value); + return NULL; + } + + eds = al_calloc(1, sizeof *eds); + if (!decode_pixel_format_attrib(eds, num_attribs, attrib, value)) { + al_free(eds); + eds = NULL; + } + + al_free(value); + + /* Hack: for some reason this happens for me under Wine. */ + if (eds && + eds->settings[ALLEGRO_RED_SHIFT] == 0 && + eds->settings[ALLEGRO_GREEN_SHIFT] == 0 && + eds->settings[ALLEGRO_BLUE_SHIFT] == 0 && + eds->settings[ALLEGRO_ALPHA_SHIFT] == 0) { + eds->settings[ALLEGRO_RED_SHIFT] = 0; + eds->settings[ALLEGRO_GREEN_SHIFT] = 8; + eds->settings[ALLEGRO_BLUE_SHIFT] = 16; + eds->settings[ALLEGRO_ALPHA_SHIFT] = 24; + } + + return eds; +} + + +static bool change_display_mode(ALLEGRO_DISPLAY *d) +{ + DEVMODE dm; + DEVMODE fallback_dm; + DISPLAY_DEVICE dd; + TCHAR* dev_name = NULL; + int i, modeswitch, result; + int fallback_dm_valid = 0; + int bpp; + int adapter = al_get_new_display_adapter(); + + if (adapter >= 0) { + memset(&dd, 0, sizeof(dd)); + dd.cb = sizeof(dd); + if (EnumDisplayDevices(NULL, adapter, &dd, 0) == false) + return false; + dev_name = dd.DeviceName; + } + + memset(&fallback_dm, 0, sizeof(fallback_dm)); + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(DEVMODE); + + bpp = d->extra_settings.settings[ALLEGRO_COLOR_SIZE]; + if (!bpp) + bpp = 32; + + i = 0; + do { + modeswitch = EnumDisplaySettings(dev_name, i, &dm); + if (!modeswitch) + break; + + if ((dm.dmPelsWidth == (unsigned) d->w) + && (dm.dmPelsHeight == (unsigned) d->h) + && (dm.dmBitsPerPel == (unsigned) bpp) + && (dm.dmDisplayFrequency != (unsigned) d->refresh_rate)) + { + /* Keep it as fallback if refresh rate request could not + * be satisfied. Try to get as close to 60Hz as possible though, + * it's a bit better for a fallback than just blindly picking + * something like 47Hz or 200Hz. + */ + if (!fallback_dm_valid) { + fallback_dm = dm; + fallback_dm_valid = 1; + } + else if (dm.dmDisplayFrequency >= 60) { + if (dm.dmDisplayFrequency < fallback_dm.dmDisplayFrequency) { + fallback_dm = dm; + } + } + } + i++; + } + while ((dm.dmPelsWidth != (unsigned) d->w) + || (dm.dmPelsHeight != (unsigned) d->h) + || (dm.dmBitsPerPel != (unsigned) bpp) + || (dm.dmDisplayFrequency != (unsigned) d->refresh_rate)); + + if (!modeswitch && !fallback_dm_valid) { + ALLEGRO_ERROR("Mode not found.\n"); + return false; + } + + if (!modeswitch && fallback_dm_valid) + dm = fallback_dm; + + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + result = ChangeDisplaySettingsEx(dev_name, &dm, NULL, CDS_FULLSCREEN, 0); + + d->refresh_rate = dm.dmDisplayFrequency; + + if (result != DISP_CHANGE_SUCCESSFUL) { + ALLEGRO_ERROR("Unable to set mode. %s\n", _al_win_last_error()); + return false; + } + + ALLEGRO_INFO("Mode seccessfuly set.\n"); + return true; +} + + +static HGLRC init_ogl_context_ex(_ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB, HDC dc, bool fc, int major, int minor) +{ + HWND testwnd = NULL; + HDC testdc = NULL; + HGLRC testrc = NULL; + HGLRC old_rc = NULL; + HDC old_dc = NULL; + HGLRC glrc = NULL; + + testwnd = _al_win_create_hidden_window(); + if (!testwnd) + return NULL; + + old_rc = wglGetCurrentContext(); + old_dc = wglGetCurrentDC(); + + testdc = GetDC(testwnd); + testrc = init_temp_context(testwnd); + if (!testrc) + goto bail; + + if (is_wgl_extension_supported(_wglGetExtensionsStringARB, "WGL_ARB_create_context", testdc)) { + int attrib[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, major, + WGL_CONTEXT_MINOR_VERSION_ARB, minor, + WGL_CONTEXT_FLAGS_ARB, 0, + 0}; + if (fc) + attrib[5] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + if (!init_context_creation_extensions()) + goto bail; + /* TODO: we could use the context sharing feature */ + glrc = _wglCreateContextAttribsARB(dc, 0, attrib); + } + else + goto bail; + +bail: + wglMakeCurrent(NULL, NULL); + if (testrc) { + wglDeleteContext(testrc); + } + + wglMakeCurrent(old_dc, old_rc); + + _wglCreateContextAttribsARB = NULL; + + if (testwnd) { + ReleaseDC(testwnd, testdc); + DestroyWindow(testwnd); + } + + return glrc; +} + + +static ALLEGRO_EXTRA_DISPLAY_SETTINGS** get_available_pixel_formats_ext(_ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB, int *count) +{ + HWND testwnd = NULL; + HDC testdc = NULL; + HGLRC testrc = NULL; + HGLRC old_rc = NULL; + HDC old_dc = NULL; + ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds_list = NULL; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; + int maxindex; + int i, j; + + *count = 0; + ref = _al_get_new_display_settings(); + + /* We need to create a dummy window with a pixel format to get the + * list of valid PFDs + */ + testwnd = _al_win_create_hidden_window(); + if (!testwnd) + return false; + + old_rc = wglGetCurrentContext(); + old_dc = wglGetCurrentDC(); + + testdc = GetDC(testwnd); + testrc = init_temp_context(testwnd); + if (!testrc) + goto bail; + + if (!is_wgl_extension_supported(_wglGetExtensionsStringARB, "WGL_ARB_pixel_format", testdc) && + !is_wgl_extension_supported(_wglGetExtensionsStringARB, "WGL_EXT_pixel_format", testdc)) { + ALLEGRO_ERROR("WGL_ARB/EXT_pf not supported.\n"); + goto bail; + } + + if (!init_pixel_format_extensions()) + goto bail; + + maxindex = get_pixel_formats_count_ext(testdc); + if (maxindex < 1) + goto bail; + + ALLEGRO_INFO("Got %i visuals.\n", maxindex); + + eds_list = al_calloc(maxindex, sizeof(*eds_list)); + if (!eds_list) + goto bail; + + for (j = i = 0; i < maxindex; i++) { + ALLEGRO_INFO("-- \n"); + ALLEGRO_INFO("Decoding visual no. %i...\n", i+1); + eds_list[j] = read_pixel_format_ext(_wglGetExtensionsStringARB, i, testdc); + if (!eds_list[j]) + continue; + // Fill vsync setting here and enable/disable it after display creation + eds_list[j]->settings[ALLEGRO_VSYNC] = ref->settings[ALLEGRO_VSYNC]; + display_pixel_format(eds_list[j]); + eds_list[j]->score = _al_score_display_settings(eds_list[j], ref); + if (eds_list[j]->score == -1) { + al_free(eds_list[j]); + eds_list[j] = NULL; + continue; + } + /* In WinAPI first index is 1 ::) */ + eds_list[j]->index = i+1; + j++; + } + + ALLEGRO_INFO("%i visuals are good enough.\n", j); + *count = j; + +bail: + wglMakeCurrent(NULL, NULL); + if (testrc) { + wglDeleteContext(testrc); + } + + wglMakeCurrent(old_dc, old_rc); + + _wglGetPixelFormatAttribivARB = NULL; + _wglGetPixelFormatAttribivEXT = NULL; + + if (testwnd) { + ReleaseDC(testwnd, testdc); + DestroyWindow(testwnd); + } + + return eds_list; +} + + +static ALLEGRO_EXTRA_DISPLAY_SETTINGS** get_available_pixel_formats_old(int *count, HDC dc) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds_list = NULL; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; + int maxindex; + int i, j; + + *count = 0; + ref = _al_get_new_display_settings(); + + maxindex = get_pixel_formats_count_old(dc); + if (maxindex < 1) + return NULL; + + ALLEGRO_INFO("Got %i visuals.\n", maxindex); + + eds_list = al_calloc(maxindex, sizeof(*eds_list)); + if (!eds_list) + return NULL; + + for (j = i = 0; i < maxindex; i++) { + ALLEGRO_INFO("-- \n"); + ALLEGRO_INFO("Decoding visual no. %i...\n", i+1); + eds_list[j] = read_pixel_format_old(i, dc); + if (!eds_list[j]) + continue; +#ifdef DEBUGMODE + display_pixel_format(eds_list[j]); +#endif + eds_list[j]->score = _al_score_display_settings(eds_list[j], ref); + if (eds_list[j]->score == -1) { + al_free(eds_list[j]); + eds_list[j] = NULL; + continue; + } + /* In WinAPI first index is 1 ::) */ + eds_list[j]->index = i+1; + j++; + } + + ALLEGRO_INFO("%i visuals are good enough.\n", j); + *count = j; + + return eds_list; +} + + +static bool select_pixel_format(_ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB, ALLEGRO_DISPLAY_WGL *d, HDC dc) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds = NULL; + ALLEGRO_CONFIG *sys_cfg = al_get_system_config(); + int eds_count = 0; + int i; + bool force_old = false; + const char *selection_mode; + + selection_mode = al_get_config_value(sys_cfg, "graphics", + "config_selection"); + if (selection_mode && selection_mode[0] != '\0') { + if (!_al_stricmp(selection_mode, "old")) { + ALLEGRO_INFO("Forcing OLD visual selection method.\n"); + force_old = true; + } + else if (!_al_stricmp(selection_mode, "new")) + force_old = false; + } + + if (!force_old) + eds = get_available_pixel_formats_ext(_wglGetExtensionsStringARB, &eds_count); + if (!eds) + eds = get_available_pixel_formats_old(&eds_count, dc); + + if (!eds || !eds_count) { + ALLEGRO_ERROR("Didn't find any suitable pixel format!\n"); + return false; + } + + qsort(eds, eds_count, sizeof(eds[0]), _al_display_settings_sorter); + + for (i = 0; i < eds_count ; i++) { + if (SetPixelFormat(d->dc, eds[i]->index, NULL)) { + ALLEGRO_INFO("Chose visual no. %i\n\n", eds[i]->index); + display_pixel_format(eds[i]); + break; + } + else { + ALLEGRO_WARN("Unable to set pixel format! %s\n", _al_win_last_error()); + ALLEGRO_WARN("Trying next one.\n"); + } + } + + if (i == eds_count) { + ALLEGRO_ERROR("Unable to set any pixel format! %s\n", _al_win_last_error()); + for (i = 0; i < eds_count; i++) + al_free(eds[i]); + al_free(eds); + return false; + } + + memcpy(&d->win_display.display.extra_settings, eds[i], sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); + + for (i = 0; i < eds_count; i++) + al_free(eds[i]); + if (eds) + al_free(eds); + + return true; +} + +static bool create_display_internals(_ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB, ALLEGRO_DISPLAY_WGL *wgl_disp) +{ + ALLEGRO_DISPLAY *disp = (void*)wgl_disp; + ALLEGRO_DISPLAY_WIN *win_disp = (void*)wgl_disp; + WGL_DISPLAY_PARAMETERS ndp; + int window_x, window_y; + int major, minor; + + /* The window is created in a separate thread so we need to pass this + * TLS on + */ + al_get_new_window_position(&window_x, &window_y); + ndp.window_x = window_x; + ndp.window_y = window_y; + ndp.window_title = al_get_new_window_title(); + + /* _beginthread closes the handle automatically. */ + ndp.display = wgl_disp; + ndp.init_failed = true; + ndp.AckEvent = CreateEvent(NULL, false, false, NULL); + _beginthread(display_thread_proc, 0, &ndp); + + /* Wait some _finite_ time (10 secs or so) for display thread to init, and + * give up if something horrible happened to it, unless we're in debug mode + * and we may have intentionally stopped the execution to analyze the code. + */ +#ifdef DEBUGMODE + WaitForSingleObject(ndp.AckEvent, INFINITE); +#else + WaitForSingleObject(ndp.AckEvent, 10*1000); +#endif + + CloseHandle(ndp.AckEvent); + + if (ndp.init_failed) { + ALLEGRO_ERROR("Failed to create display.\n"); + return false; + } + + /* WGL display lists cannot be shared with the API currently in use. */ + disp->ogl_extras->is_shared = false; + + if (!select_pixel_format(_wglGetExtensionsStringARB, wgl_disp, wgl_disp->dc)) { + destroy_display_internals(wgl_disp); + return false; + } + + major = al_get_new_display_option(ALLEGRO_OPENGL_MAJOR_VERSION, 0); + minor = al_get_new_display_option(ALLEGRO_OPENGL_MINOR_VERSION, 0); + + // TODO: request GLES context in GLES builds + if ((disp->flags & ALLEGRO_OPENGL_3_0) || major != 0) { + if (major == 0) + major = 3; + bool fc = (disp->flags & ALLEGRO_OPENGL_FORWARD_COMPATIBLE) != 0; + wgl_disp->glrc = init_ogl_context_ex(_wglGetExtensionsStringARB, wgl_disp->dc, fc, major, + minor); + } + else { + wgl_disp->glrc = wglCreateContext(wgl_disp->dc); + } + + if (!wgl_disp->glrc) { + ALLEGRO_ERROR("Unable to create a render context! %s\n", _al_win_last_error()); + destroy_display_internals(wgl_disp); + return false; + } + + /* make the context the current one */ + if (!wglMakeCurrent(wgl_disp->dc, wgl_disp->glrc)) { + ALLEGRO_ERROR("Unable to make the context current! %s\n", _al_win_last_error()); + destroy_display_internals(wgl_disp); + return false; + } + + _al_ogl_manage_extensions(disp); + _al_ogl_set_extensions(disp->ogl_extras->extension_api); + + if (disp->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_1_2) { + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings(); + if (eds->required & (1<extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0; + } + + /* Fill in the display settings for opengl major and minor versions...*/ + const int v = disp->ogl_extras->ogl_info.version; + disp->extra_settings.settings[ALLEGRO_OPENGL_MAJOR_VERSION] = (v >> 24) & 0xFF; + disp->extra_settings.settings[ALLEGRO_OPENGL_MINOR_VERSION] = (v >> 16) & 0xFF; + + /* Try to enable or disable vsync as requested */ + /* NOTE: my drivers claim I don't have WGL_EXT_swap_control + * (according to al_have_opengl_extension), but wglSwapIntervalEXT + * does get loaded, so just check for that. + */ + if (wglSwapIntervalEXT) { + if (disp->extra_settings.settings[ALLEGRO_VSYNC] == 1) { + wglSwapIntervalEXT(1); + } + else if (disp->extra_settings.settings[ALLEGRO_VSYNC] == 2) { + wglSwapIntervalEXT(0); + } + } + + win_disp->mouse_selected_hcursor = 0; + win_disp->mouse_cursor_shown = false; + win_disp->can_acknowledge = false; + + _al_win_grab_input(win_disp); + + if (disp->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY]) + _al_ogl_setup_gl(disp); + + return true; +} + + +static ALLEGRO_DISPLAY* wgl_create_display(int w, int h) +{ + ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); + ALLEGRO_DISPLAY_WGL **add; + ALLEGRO_DISPLAY_WGL *wgl_display = al_calloc(1, sizeof *wgl_display); + ALLEGRO_DISPLAY *ogl_display = (void*)wgl_display; + ALLEGRO_DISPLAY *display = (void*)ogl_display; + ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)display; + + win_disp->adapter = _al_win_determine_adapter(); + + display->w = w; + display->h = h; + display->refresh_rate = al_get_new_display_refresh_rate(); + display->flags = al_get_new_display_flags(); +#ifdef ALLEGRO_CFG_OPENGLES2 + display->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + display->flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + display->vt = &vt; + + display->ogl_extras = al_calloc(1, sizeof(ALLEGRO_OGL_EXTRAS)); + + _ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB + = (_ALLEGRO_wglGetExtensionsStringARB_t)wglGetProcAddress("wglGetExtensionsStringARB"); + if (!create_display_internals(_wglGetExtensionsStringARB, wgl_display)) { + al_free(display->ogl_extras); + al_free(display); + return NULL; + } + + /* Print out OpenGL version info */ + ALLEGRO_INFO("OpenGL Version: %s\n", (const char*)glGetString(GL_VERSION)); + ALLEGRO_INFO("Vendor: %s\n", (const char*)glGetString(GL_VENDOR)); + ALLEGRO_INFO("Renderer: %s\n\n", (const char*)glGetString(GL_RENDERER)); + + /* Add ourself to the list of displays. */ + add = _al_vector_alloc_back(&system->system.displays); + *add = wgl_display; + + /* Each display is an event source. */ + _al_event_source_init(&display->es); + + _al_win_set_system_mouse_cursor(display, ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW); + _al_win_show_mouse_cursor(display); + + _al_win_post_create_window(display); + + return display; +} + + +static void destroy_display_internals(ALLEGRO_DISPLAY_WGL *wgl_disp) +{ + ALLEGRO_DISPLAY *disp = (ALLEGRO_DISPLAY *)wgl_disp; + ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)wgl_disp; + + /* We need to convert all our bitmaps to display independent (memory) + * bitmaps because WGL driver doesn't support sharing of resources. */ + while (disp->bitmaps._size > 0) { + ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&disp->bitmaps); + ALLEGRO_BITMAP *bmp = *bptr; + _al_convert_to_memory_bitmap(bmp); + } + + if (disp->ogl_extras->backbuffer) + _al_ogl_destroy_backbuffer(disp->ogl_extras->backbuffer); + disp->ogl_extras->backbuffer = NULL; + + _al_ogl_unmanage_extensions(disp); + + PostMessage(win_disp->window, _al_win_msg_suicide, (WPARAM)win_disp, 0); + + while (!win_disp->thread_ended) + al_rest(0.001); + + if (wgl_disp->glrc) { + wglDeleteContext(wgl_disp->glrc); + wgl_disp->glrc = NULL; + } + if (wgl_disp->dc) { + ReleaseDC(win_disp->window, wgl_disp->dc); + wgl_disp->dc = NULL; + } + + if (disp->flags & ALLEGRO_FULLSCREEN && !_wgl_do_not_change_display_mode) { + ChangeDisplaySettings(NULL, 0); + } + + if (win_disp->window) { + DestroyWindow(win_disp->window); + win_disp->window = NULL; + } +} + + +static void wgl_destroy_display(ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); + ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)disp; + ALLEGRO_DISPLAY *old_disp = al_get_current_display(); + + if (old_disp != disp) + _al_set_current_display_only(disp); + + if (system->mouse_grab_display == disp) + system->mouse_grab_display = NULL; + + _al_win_destroy_display_icons(disp); + + destroy_display_internals(wgl_disp); + _al_event_source_free(&disp->es); + _al_vector_find_and_delete(&system->system.displays, &disp); + + _al_vector_free(&disp->bitmaps); + _al_vector_free(&((ALLEGRO_DISPLAY_WIN*) disp)->msg_callbacks); + al_free(disp->ogl_extras); + + if (old_disp != disp) + _al_set_current_display_only(old_disp); + + al_free(disp->vertex_cache); + al_free(wgl_disp); +} + + +static bool wgl_set_current_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)d; + HGLRC current_glrc; + + current_glrc = wglGetCurrentContext(); + + if (!current_glrc || (current_glrc && current_glrc != wgl_disp->glrc)) { + /* make the context the current one */ + if (!wglMakeCurrent(wgl_disp->dc, wgl_disp->glrc)) { + ALLEGRO_ERROR("Unable to make the context current! %s\n", + _al_win_last_error()); + return false; + } + + _al_ogl_set_extensions(d->ogl_extras->extension_api); + } + + _al_ogl_update_render_state(d); + + return true; +} + + +static void wgl_unset_current_display(ALLEGRO_DISPLAY *d) +{ + (void)d; + + if (!wglMakeCurrent(NULL, NULL)) { + ALLEGRO_ERROR("Unable unset the current context! %s\n", _al_win_last_error()); + } +} + + +/* + * The window must be created in the same thread that + * runs the message loop. + */ +static void display_thread_proc(void *arg) +{ + WGL_DISPLAY_PARAMETERS *ndp = arg; + ALLEGRO_DISPLAY *disp = (ALLEGRO_DISPLAY*)ndp->display; + ALLEGRO_DISPLAY_WGL *wgl_disp = (void*)disp; + ALLEGRO_DISPLAY_WIN *win_disp = (void*)disp; + MSG msg; + + /* So that we can call the functions using TLS from this thread. */ + al_set_new_display_flags(disp->flags); + al_set_new_window_position(ndp->window_x, ndp->window_y); + al_set_new_window_title(ndp->window_title); + + if (disp->flags & ALLEGRO_FULLSCREEN) { + if (!change_display_mode(disp)) { + win_disp->thread_ended = true; + destroy_display_internals(wgl_disp); + SetEvent(ndp->AckEvent); + return; + } + } + else if (disp->flags & ALLEGRO_FULLSCREEN_WINDOW) { + ALLEGRO_MONITOR_INFO mi; + int adapter = win_disp->adapter; + al_get_monitor_info(adapter, &mi); + + win_disp->toggle_w = disp->w; + win_disp->toggle_h = disp->h; + + disp->w = mi.x2 - mi.x1; + disp->h = mi.y2 - mi.y1; + + disp->refresh_rate = al_get_monitor_refresh_rate(adapter); + } + else { + int adapter = win_disp->adapter; + win_disp->toggle_w = disp->w; + win_disp->toggle_h = disp->h; + + disp->refresh_rate = al_get_monitor_refresh_rate(adapter); + } + + win_disp->window = _al_win_create_window(disp, disp->w, disp->h, disp->flags); + + if (!win_disp->window) { + win_disp->thread_ended = true; + destroy_display_internals(wgl_disp); + SetEvent(ndp->AckEvent); + return; + } + + /* FIXME: can't _al_win_create_window() do this? */ + if ((disp->flags & ALLEGRO_FULLSCREEN) || + (disp->flags & ALLEGRO_FULLSCREEN_WINDOW)) { + RECT rect; + rect.left = 0; + rect.right = disp->w; + rect.top = 0; + rect.bottom = disp->h; + SetWindowPos(win_disp->window, 0, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_NOZORDER | SWP_FRAMECHANGED); + } + + if (disp->flags & ALLEGRO_FULLSCREEN_WINDOW) { + bool frameless = true; + _al_win_set_window_frameless(disp, win_disp->window, frameless); + } + + /* Yep, the following is really needed sometimes. */ + /* ... Or is it now that we have dumped DInput? */ + /* Win98/2k/XP's window forground rules don't let us + * make our window the topmost window on launch. This causes issues on + * full-screen apps, as DInput loses input focus on them. + * We use this trick to force the window to be topmost, when switching + * to full-screen only. Note that this only works for Win98 and greater. + * Win95 will ignore our SystemParametersInfo() calls. + * + * See http://support.microsoft.com:80/support/kb/articles/Q97/9/25.asp + * for details. + */ + { + DWORD lock_time; + HWND wnd = win_disp->window; + +#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 +#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 + if (disp->flags & ALLEGRO_FULLSCREEN) { + SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, + 0, (LPVOID)&lock_time, 0); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, + 0, (LPVOID)0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); + } + + ShowWindow(wnd, SW_SHOWNORMAL); + SetForegroundWindow(wnd); + /* In some rare cases, it doesn't seem to work without the loop. And we + * absolutely need this to succeed, else we trap the user in a + * fullscreen window without input. + */ + while (GetForegroundWindow() != wnd) { + al_rest(0.01); + SetForegroundWindow(wnd); + } + UpdateWindow(wnd); + + if (disp->flags & ALLEGRO_FULLSCREEN) { + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, + 0, (LPVOID)&lock_time, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); + } +#undef SPI_GETFOREGROUNDLOCKTIMEOUT +#undef SPI_SETFOREGROUNDLOCKTIMEOUT + } + +#if 0 + if (disp->flags & ALLEGRO_FULLSCREEN && al_is_mouse_installed()) { + RAWINPUTDEVICE rid[1]; + rid[0].usUsagePage = 0x01; + rid[0].usUsage = 0x02; + rid[0].dwFlags = RIDEV_NOLEGACY; + rid[0].hwndTarget = 0; + if (RegisterRawInputDevices(rid, 1, sizeof(rid[0])) == FALSE) { + ALLEGRO_ERROR( + "Failed to init mouse. %s\n", get_error_desc(GetLastError())); + } + } +#endif + + /* get the device context of our window */ + wgl_disp->dc = GetDC(win_disp->window); + + win_disp->thread_ended = false; + win_disp->end_thread = false; + ndp->init_failed = false; + SetEvent(ndp->AckEvent); + + while (!win_disp->end_thread) { + /* get a message from the queue */ + if (GetMessage(&msg, NULL, 0, 0) != 0) + DispatchMessage(&msg); + else + break; /* WM_QUIT received or error (GetMessage returned -1) */ + } + + ALLEGRO_INFO("wgl display thread exits\n"); + win_disp->thread_ended = true; +} + + +static void wgl_flip_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DISPLAY_WGL* disp = (ALLEGRO_DISPLAY_WGL*)d; + glFlush(); + if (!d->extra_settings.settings[ALLEGRO_SINGLE_BUFFER]) + SwapBuffers(disp->dc); +} + + +static void wgl_update_display_region(ALLEGRO_DISPLAY *d, + int x, int y, int width, int height) +{ + if (al_get_opengl_extension_list()->ALLEGRO_WGL_WIN_swap_hint) { + /* FIXME: This is just a driver hint and there is no guarantee that the + * contens of the front buffer outside the given rectangle will be preserved, + * thus we should really return false here and do nothing. */ + ALLEGRO_DISPLAY_WGL* disp = (ALLEGRO_DISPLAY_WGL*)d; + wglAddSwapHintRectWIN(x, y, width, height); + glFlush(); + SwapBuffers(disp->dc); + return; + } + wgl_flip_display(d); +} + + +static bool wgl_resize_helper(_ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB, ALLEGRO_DISPLAY *d, int width, int height) +{ + ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)d; + ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)d; + int full_w, full_h; + ALLEGRO_MONITOR_INFO mi; + int adapter = al_get_new_display_adapter(); + if (adapter < 0) + adapter = 0; + al_get_monitor_info(adapter, &mi); + full_w = mi.x2 - mi.x1; + full_h = mi.y2 - mi.y1; + + if ((d->flags & ALLEGRO_FULLSCREEN_WINDOW) && (full_w != width || full_h != height)) { + win_disp->toggle_w = width; + win_disp->toggle_h = height; + return true; + } + + win_disp->can_acknowledge = false; + + if (d->flags & ALLEGRO_FULLSCREEN) { + ALLEGRO_BITMAP *target_bmp; + _AL_VECTOR disp_bmps; + bool was_backbuffer = false; + size_t i; + + target_bmp = al_get_target_bitmap(); + if (target_bmp && target_bmp->vt) { + ALLEGRO_BITMAP_EXTRA_OPENGL *extra = target_bmp->parent ? + target_bmp->parent->extra : target_bmp->extra; + was_backbuffer = extra->is_backbuffer; + } + + /* Remember display bitmaps. */ + _al_vector_init(&disp_bmps, sizeof(ALLEGRO_BITMAP*)); + for (i = 0; i < _al_vector_size(&d->bitmaps); i++) { + ALLEGRO_BITMAP **dis = _al_vector_ref(&d->bitmaps, i); + ALLEGRO_BITMAP **mem = _al_vector_alloc_back(&disp_bmps); + *mem = *dis; + } + + /* This flag prevents from switching to desktop resolution in between. */ + _wgl_do_not_change_display_mode = true; + destroy_display_internals(wgl_disp); + _wgl_do_not_change_display_mode = false; + + d->w = width; + d->h = height; + if(!create_display_internals(_wglGetExtensionsStringARB, wgl_disp)) + return false; + + /* We have a new backbuffer now. */ + if (was_backbuffer) + al_set_target_bitmap(al_get_backbuffer(d)); + + /* Reupload bitmaps. */ + while (_al_vector_is_nonempty(&disp_bmps)) { + ALLEGRO_BITMAP **back = _al_vector_ref_back(&disp_bmps); + _al_convert_to_display_bitmap(*back); + _al_vector_delete_at(&disp_bmps, _al_vector_size(&disp_bmps) - 1); + } + } + else { + RECT win_size; + WINDOWINFO wi; + + win_size.left = 0; + win_size.top = 0; + win_size.right = width; + win_size.bottom = height; + + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(win_disp->window, &wi); + + AdjustWindowRectEx(&win_size, wi.dwStyle, GetMenu(win_disp->window) ? TRUE : FALSE, wi.dwExStyle); + + if (!SetWindowPos(win_disp->window, HWND_TOP, + 0, 0, + win_size.right - win_size.left, + win_size.bottom - win_size.top, + SWP_NOMOVE|SWP_NOZORDER)) + return false; + + d->w = width; + d->h = height; + if (!(d->flags & ALLEGRO_FULLSCREEN_WINDOW)) { + win_disp->toggle_w = width; + win_disp->toggle_h = height; + } + } + + return true; +} + +static bool wgl_resize_display(ALLEGRO_DISPLAY *d, int width, int height) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)d; + int orig_w = d->w; + int orig_h = d->h; + bool ret; + + win_display->ignore_resize = true; + + _ALLEGRO_wglGetExtensionsStringARB_t _wglGetExtensionsStringARB + = (_ALLEGRO_wglGetExtensionsStringARB_t)wglGetProcAddress("wglGetExtensionsStringARB"); + if (!wgl_resize_helper(_wglGetExtensionsStringARB, d, width, height)) { + wgl_resize_helper(_wglGetExtensionsStringARB, d, orig_w, orig_h); + ret = false; + } else { + ret = true; + wgl_acknowledge_resize(d); + } + + win_display->ignore_resize = false; + + return ret; +} + +static bool wgl_acknowledge_resize(ALLEGRO_DISPLAY *d) +{ + WINDOWINFO wi; + ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)d; + int w, h; + ALLEGRO_STATE state; + + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(win_disp->window, &wi); + w = wi.rcClient.right - wi.rcClient.left; + h = wi.rcClient.bottom - wi.rcClient.top; + + d->w = w; + d->h = h; + + _al_ogl_setup_gl(d); + _al_ogl_update_render_state(d); + + al_store_state(&state, ALLEGRO_STATE_DISPLAY | ALLEGRO_STATE_TARGET_BITMAP); + al_set_target_backbuffer(d); + al_set_clipping_rectangle(0, 0, w, h); + al_restore_state(&state); + + return true; +} + + +static bool wgl_is_compatible_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap) +{ + /* Note: WGL driver doesn't support sharing of resources between contexts, + * thus all bitmaps are tied to the display which was current at the time + * al_create_bitmap was called. + */ + return display == _al_get_bitmap_display(bitmap); +} + + +static void wgl_switch_in(ALLEGRO_DISPLAY *display) +{ + (void)display; + /* + ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)display; + + if (al_is_mouse_installed()) + al_set_mouse_range(win_disp->mouse_range_x1, win_disp->mouse_range_y1, + win_disp->mouse_range_x2, win_disp->mouse_range_y2); + */ +} + + +static void wgl_switch_out(ALLEGRO_DISPLAY *display) +{ + (void)display; +} + + +static void wgl_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +{ + _al_win_set_window_position(((ALLEGRO_DISPLAY_WIN *)display)->window, x, y); +} + + +static void wgl_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + _al_win_get_window_position(((ALLEGRO_DISPLAY_WIN *)display)->window, x, y); +} + + +/* Obtain a reference to this driver. */ +ALLEGRO_DISPLAY_INTERFACE *_al_display_wgl_driver(void) +{ + if (vt.create_display) + return &vt; + + vt.create_display = wgl_create_display; + vt.destroy_display = wgl_destroy_display; + vt.resize_display = wgl_resize_display; + vt.set_current_display = wgl_set_current_display; + vt.unset_current_display = wgl_unset_current_display; + vt.flip_display = wgl_flip_display; + vt.update_display_region = wgl_update_display_region; + vt.acknowledge_resize = wgl_acknowledge_resize; + vt.create_bitmap = _al_ogl_create_bitmap; + vt.get_backbuffer = _al_ogl_get_backbuffer; + vt.set_target_bitmap = _al_ogl_set_target_bitmap; + vt.is_compatible_bitmap = wgl_is_compatible_bitmap; + vt.switch_in = wgl_switch_in; + vt.switch_out = wgl_switch_out; + + vt.set_mouse_cursor = _al_win_set_mouse_cursor; + vt.set_system_mouse_cursor = _al_win_set_system_mouse_cursor; + vt.show_mouse_cursor = _al_win_show_mouse_cursor; + vt.hide_mouse_cursor = _al_win_hide_mouse_cursor; + + vt.set_icons = _al_win_set_display_icons; + vt.set_window_position = wgl_set_window_position; + vt.get_window_position = wgl_get_window_position; + vt.set_window_constraints = _al_win_set_window_constraints; + vt.get_window_constraints = _al_win_get_window_constraints; + vt.apply_window_constraints = _al_win_apply_window_constraints; + vt.set_display_flag = _al_win_set_display_flag; + vt.set_window_title = _al_win_set_window_title; + + vt.update_render_state = _al_ogl_update_render_state; + _al_ogl_add_drawing_functions(&vt); + _al_win_add_clipboard_functions(&vt); + + return &vt; +} + +int _al_wgl_get_num_display_modes(int format, int refresh_rate, int flags) +{ + DEVMODE dm; + int count = 0; + + /* FIXME: Ignoring format. + * To get a list of pixel formats we have to create a window with a valid DC, which + * would even require to change the video mode in fullscreen cases and we really + * don't want to do that. + */ + (void)format; + (void)refresh_rate; + (void)flags; + + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + + while (EnumDisplaySettings(NULL, count, &dm) != false) { + count++; + } + + return count; +} + + +ALLEGRO_DISPLAY_MODE *_al_wgl_get_display_mode(int index, int format, + int refresh_rate, int flags, + ALLEGRO_DISPLAY_MODE *mode) +{ + DEVMODE dm; + + /* + * FIXME: see the comment in _al_wgl_get_num_display_modes + */ + (void)format; + (void)refresh_rate; + (void)flags; + + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (!EnumDisplaySettings(NULL, index, &dm)) + return NULL; + + mode->width = dm.dmPelsWidth; + mode->height = dm.dmPelsHeight; + mode->refresh_rate = dm.dmDisplayFrequency; + mode->format = format; + switch (dm.dmBitsPerPel) { + case 32: + if (format == ALLEGRO_PIXEL_FORMAT_ANY) + mode->format = ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA; + else if (format == ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA) + mode->format = ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA; + break; + case 24: + mode->format = ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA; + break; + case 16: + if (format == ALLEGRO_PIXEL_FORMAT_ANY) + mode->format = ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA; + else if(format == ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA) + mode->format = ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA; + break; + default: + break; + } + + return mode; +} + +/* vi: set sts=3 sw=3 et: */ + diff --git a/allegro/src/win/whapall.c b/allegro/src/win/whapall.c new file mode 100644 index 00000000..265f2ea2 --- /dev/null +++ b/allegro/src/win/whapall.c @@ -0,0 +1,343 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows wrapper haptic (force-feedback) device driver. + * This wraps around the XInput and DirectInput drivers to support both. + * By Beoran. + * + * See LICENSE.txt for copyright information. + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#define DIRECTINPUT_VERSION 0x0800 + +/* For waitable timers */ +#define _WIN32_WINNT 0x0501 + +#include "allegro5/allegro.h" +#include "allegro5/haptic.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_haptic.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_bitmap.h" + +#ifdef ALLEGRO_CFG_XINPUT +/* Don't compile this lot if xinput and directinput isn't supported. */ + +#include "allegro5/internal/aintern_wjoyall.h" + +ALLEGRO_DEBUG_CHANNEL("haptic") + +/* forward declarations */ +static bool hapall_init_haptic(void); +static void hapall_exit_haptic(void); + +static bool hapall_is_mouse_haptic(ALLEGRO_MOUSE *dev); +static bool hapall_is_joystick_haptic(ALLEGRO_JOYSTICK *); +static bool hapall_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev); +static bool hapall_is_display_haptic(ALLEGRO_DISPLAY *dev); +static bool hapall_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev); + +static ALLEGRO_HAPTIC *hapall_get_from_mouse(ALLEGRO_MOUSE *dev); +static ALLEGRO_HAPTIC *hapall_get_from_joystick(ALLEGRO_JOYSTICK *dev); +static ALLEGRO_HAPTIC *hapall_get_from_keyboard(ALLEGRO_KEYBOARD *dev); +static ALLEGRO_HAPTIC *hapall_get_from_display(ALLEGRO_DISPLAY *dev); +static ALLEGRO_HAPTIC *hapall_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev); + +static bool hapall_release(ALLEGRO_HAPTIC *haptic); + +static bool hapall_get_active(ALLEGRO_HAPTIC *hap); +static int hapall_get_capabilities(ALLEGRO_HAPTIC *dev); +static double hapall_get_gain(ALLEGRO_HAPTIC *dev); +static bool hapall_set_gain(ALLEGRO_HAPTIC *dev, double); +static int hapall_get_max_effects(ALLEGRO_HAPTIC *dev); + +static bool hapall_is_effect_ok(ALLEGRO_HAPTIC *dev, ALLEGRO_HAPTIC_EFFECT *eff); +static bool hapall_upload_effect(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *eff, + ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool hapall_play_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop); +static bool hapall_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool hapall_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool hapall_release_effect(ALLEGRO_HAPTIC_EFFECT_ID *id); + +static double hapall_get_autocenter(ALLEGRO_HAPTIC *dev); +static bool hapall_set_autocenter(ALLEGRO_HAPTIC *dev, double); + + +ALLEGRO_HAPTIC_DRIVER _al_hapdrv_windows_all = +{ + AL_HAPTIC_TYPE_WINDOWS_ALL, + "", + "", + "Windows haptic(s)", + hapall_init_haptic, + hapall_exit_haptic, + + hapall_is_mouse_haptic, + hapall_is_joystick_haptic, + hapall_is_keyboard_haptic, + hapall_is_display_haptic, + hapall_is_touch_input_haptic, + + hapall_get_from_mouse, + hapall_get_from_joystick, + hapall_get_from_keyboard, + hapall_get_from_display, + hapall_get_from_touch_input, + + hapall_get_active, + hapall_get_capabilities, + hapall_get_gain, + hapall_set_gain, + hapall_get_max_effects, + + hapall_is_effect_ok, + hapall_upload_effect, + hapall_play_effect, + hapall_stop_effect, + hapall_is_effect_playing, + hapall_release_effect, + + hapall_release, + + hapall_get_autocenter, + hapall_set_autocenter +}; + + +/* Mutex for thread protection. */ +static ALLEGRO_MUTEX *hapall_mutex = NULL; + + +/* Initializes the combined haptic system. */ +static bool hapall_init_haptic(void) +{ + bool xi_ok, di_ok; + ASSERT(hapall_mutex == NULL); + + /* Create the mutex. */ + hapall_mutex = al_create_mutex_recursive(); + if (!hapall_mutex) + return false; + + al_lock_mutex(hapall_mutex); + + xi_ok = _al_hapdrv_xinput.init_haptic(); + di_ok = _al_hapdrv_directx.init_haptic(); + al_unlock_mutex(hapall_mutex); + return xi_ok || di_ok; +} + +static void hapall_exit_haptic(void) +{ + ASSERT(hapall_mutex); + al_destroy_mutex(hapall_mutex); + hapall_mutex = NULL; +} + +static bool hapall_get_active(ALLEGRO_HAPTIC *haptic) +{ + return haptic->driver->get_active(haptic); +} + + +static bool hapall_is_mouse_haptic(ALLEGRO_MOUSE *mouse) +{ + (void)mouse; + return false; +} + + +static bool hapall_is_joystick_haptic(ALLEGRO_JOYSTICK *joy) +{ + bool dx_ok = false, xi_ok = false; + ASSERT(joy->driver); + + if (joy->driver == &_al_joydrv_xinput) { + dx_ok = _al_hapdrv_xinput.is_joystick_haptic(joy); + } + else if (joy->driver == &_al_joydrv_directx) { + xi_ok = _al_hapdrv_directx.is_joystick_haptic(joy); + } + return dx_ok || xi_ok; +} + + +static bool hapall_is_display_haptic(ALLEGRO_DISPLAY *dev) +{ + (void)dev; + return false; +} + + +static bool hapall_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev) +{ + (void)dev; + return false; +} + + +static bool hapall_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev) +{ + (void)dev; + return false; +} + + +static ALLEGRO_HAPTIC *hapall_get_from_mouse(ALLEGRO_MOUSE *mouse) +{ + (void)mouse; + return NULL; +} + + +static ALLEGRO_HAPTIC *hapall_get_from_joystick(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_HAPTIC *haptic = NULL; + if (!al_is_joystick_haptic(joy)) + return NULL; + + al_lock_mutex(hapall_mutex); + + if (joy->driver == &_al_joydrv_xinput) { + haptic = _al_hapdrv_xinput.get_from_joystick(joy); + if (haptic) { + haptic->driver = &_al_hapdrv_xinput; + } + } + else if (joy->driver == &_al_joydrv_directx) { + haptic = _al_hapdrv_directx.get_from_joystick(joy); + if (haptic) { + haptic->driver = &_al_hapdrv_directx; + } + } + + al_unlock_mutex(hapall_mutex); + return haptic; +} + + +static ALLEGRO_HAPTIC *hapall_get_from_display(ALLEGRO_DISPLAY *dev) +{ + (void)dev; + return NULL; +} + + +static ALLEGRO_HAPTIC *hapall_get_from_keyboard(ALLEGRO_KEYBOARD *dev) +{ + (void)dev; + return NULL; +} + + +static ALLEGRO_HAPTIC *hapall_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev) +{ + (void)dev; + return NULL; +} + + +static int hapall_get_capabilities(ALLEGRO_HAPTIC *dev) +{ + return dev->driver->get_capabilities(dev); +} + + +static double hapall_get_gain(ALLEGRO_HAPTIC *dev) +{ + return dev->driver->get_gain(dev); +} + + +static bool hapall_set_gain(ALLEGRO_HAPTIC *dev, double gain) +{ + return dev->driver->set_gain(dev, gain); +} + + +double hapall_get_autocenter(ALLEGRO_HAPTIC *dev) +{ + return dev->driver->get_autocenter(dev); +} + +static bool hapall_set_autocenter(ALLEGRO_HAPTIC *dev, double intensity) +{ + return dev->driver->set_autocenter(dev, intensity); +} + +static int hapall_get_max_effects(ALLEGRO_HAPTIC *dev) +{ + return dev->driver->get_max_effects(dev); +} + + +static bool hapall_is_effect_ok(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + return dev->driver->is_effect_ok(dev, effect); +} + + +static bool hapall_upload_effect(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + /* store the driver we'll need it later. */ + id->driver = dev->driver; + return dev->driver->upload_effect(dev, effect, id); +} + +static bool hapall_play_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loops) +{ + ALLEGRO_HAPTIC_DRIVER *driver = id->driver; + /* Use the stored driver to perform the operation. */ + return driver->play_effect(id, loops); +} + + +static bool hapall_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_DRIVER *driver = id->driver; + /* Use the stored driver to perform the operation. */ + return driver->stop_effect(id); +} + + +static bool hapall_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_DRIVER *driver = id->driver; + /* Use the stored driver to perform the operation. */ + return driver->is_effect_playing(id); +} + +static bool hapall_release_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_DRIVER *driver = id->driver; + /* Use the stored driver to perform the operation. */ + return driver->release_effect(id); +} + + +static bool hapall_release(ALLEGRO_HAPTIC *haptic) +{ + if (!haptic) + return false; + + return haptic->driver->release(haptic); +} + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/whapdrv.c b/allegro/src/win/whapdrv.c new file mode 100644 index 00000000..7d803a0c --- /dev/null +++ b/allegro/src/win/whapdrv.c @@ -0,0 +1,31 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * List of Windows joystick drivers, kept in a seperate file so that + * they can be overriden by user programs. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_haptic.h" + +#ifndef ALLEGRO_WINDOWS +#error something is wrong with the makefile +#endif + +/* Construct the DirectInput haptics driver list */ +_AL_BEGIN_HAPTIC_DRIVER_LIST +_AL_HAPTIC_DRIVER_DIRECTX +_AL_END_HAPTIC_DRIVER_LIST diff --git a/allegro/src/win/whaptic.cpp b/allegro/src/win/whaptic.cpp new file mode 100644 index 00000000..8fb1c0e9 --- /dev/null +++ b/allegro/src/win/whaptic.cpp @@ -0,0 +1,1439 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows haptic (force-feedback) device driver. + * + * By Beoran. + * + * See LICENSE.txt for copyright information. + */ + + + +#define ALLEGRO_NO_COMPATIBILITY + +#define DIRECTINPUT_VERSION 0x0800 + +/* For waitable timers */ +#define _WIN32_WINNT 0x0501 + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_haptic.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_bitmap.h" + +#ifndef ALLEGRO_WINDOWS +#error something is wrong with the makefile +#endif + +#ifdef ALLEGRO_MINGW32 +#undef MAKEFOURCC +#endif + +#include +#include +#include +#include +#include +#include +/* #include */ + +#include "allegro5/internal/aintern_wjoydxnu.h" + +ALLEGRO_DEBUG_CHANNEL("whaptic") + +/* Support at most 32 haptic devices. */ +#define HAPTICS_MAX 32 +/* Support at most 16 effects per device. */ +#define HAPTICS_EFFECTS_MAX 16 +/* Support at most 3 axes per device. */ +#define HAPTICS_AXES_MAX 3 + +/** This union is needed to avoid + dynamical memory allocation. */ +typedef union +{ + DICONSTANTFORCE constant; + DIRAMPFORCE ramp; + DIPERIODIC periodic; + DICONDITION condition; + DICUSTOMFORCE custom; +} ALLEGRO_HAPTIC_PARAMETER_WINDOWS; + + +/* + * Haptic effect system data. + */ +typedef struct +{ + int id; + bool active; + DIEFFECT effect; + DIENVELOPE envelope; + LPDIRECTINPUTEFFECT ref; + DWORD axes[HAPTICS_AXES_MAX]; + LONG directions[HAPTICS_AXES_MAX]; + ALLEGRO_HAPTIC_PARAMETER_WINDOWS parameter; + const GUID *guid; +} ALLEGRO_HAPTIC_EFFECT_WINDOWS; + + + +typedef struct +{ + struct ALLEGRO_HAPTIC parent; /* must be first */ + bool active; + LPDIRECTINPUTDEVICE2 device; + GUID guid; + DIDEVICEINSTANCE instance; + DIDEVCAPS capabilities; + LPDIRECTINPUTDEVICE8 device8; + ALLEGRO_DISPLAY_WIN *display; + int flags; + ALLEGRO_HAPTIC_EFFECT_WINDOWS effects[HAPTICS_EFFECTS_MAX]; + DWORD axes[HAPTICS_AXES_MAX]; + int naxes; +} ALLEGRO_HAPTIC_WINDOWS; + + +#define LONG_BITS (sizeof(long) * 8) +#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS) +/* Tests if a bit in an array of longs is set. */ +#define TEST_BIT(nr, addr) \ + ((1UL << ((nr) % LONG_BITS)) & (addr)[(nr) / LONG_BITS]) + + +/* forward declarations */ +static bool whap_init_haptic(void); +static void whap_exit_haptic(void); + +static bool whap_is_mouse_haptic(ALLEGRO_MOUSE *dev); +static bool whap_is_joystick_haptic(ALLEGRO_JOYSTICK *); +static bool whap_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev); +static bool whap_is_display_haptic(ALLEGRO_DISPLAY *dev); +static bool whap_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev); + +static ALLEGRO_HAPTIC *whap_get_from_mouse(ALLEGRO_MOUSE *dev); +static ALLEGRO_HAPTIC *whap_get_from_joystick(ALLEGRO_JOYSTICK *dev); +static ALLEGRO_HAPTIC *whap_get_from_keyboard(ALLEGRO_KEYBOARD *dev); +static ALLEGRO_HAPTIC *whap_get_from_display(ALLEGRO_DISPLAY *dev); +static ALLEGRO_HAPTIC *whap_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev); + +static bool whap_release(ALLEGRO_HAPTIC *haptic); + +static bool whap_get_active(ALLEGRO_HAPTIC *hap); +static int whap_get_capabilities(ALLEGRO_HAPTIC *dev); +static double whap_get_gain(ALLEGRO_HAPTIC *dev); +static bool whap_set_gain(ALLEGRO_HAPTIC *dev, double); +static int whap_get_max_effects(ALLEGRO_HAPTIC *dev); + +static bool whap_is_effect_ok(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *eff); +static bool whap_upload_effect(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *eff, + ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool whap_play_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop); +static bool whap_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool whap_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool whap_release_effect(ALLEGRO_HAPTIC_EFFECT_ID *id); + +static double whap_get_autocenter(ALLEGRO_HAPTIC *dev); +static bool whap_set_autocenter(ALLEGRO_HAPTIC *dev, double); + +ALLEGRO_HAPTIC_DRIVER _al_hapdrv_directx = { + AL_HAPTIC_TYPE_DIRECTX, + "", + "", + "Windows haptic(s)", + whap_init_haptic, + whap_exit_haptic, + + whap_is_mouse_haptic, + whap_is_joystick_haptic, + whap_is_keyboard_haptic, + whap_is_display_haptic, + whap_is_touch_input_haptic, + + whap_get_from_mouse, + whap_get_from_joystick, + whap_get_from_keyboard, + whap_get_from_display, + whap_get_from_touch_input, + + whap_get_active, + whap_get_capabilities, + whap_get_gain, + whap_set_gain, + whap_get_max_effects, + + whap_is_effect_ok, + whap_upload_effect, + whap_play_effect, + whap_stop_effect, + whap_is_effect_playing, + whap_release_effect, + + whap_release, + + whap_get_autocenter, + whap_set_autocenter +}; + + +static ALLEGRO_HAPTIC_WINDOWS haptics[HAPTICS_MAX]; +static ALLEGRO_MUTEX *haptic_mutex = NULL; + +/* Capability map between directinput effects and allegro effect types. */ +struct CAP_MAP +{ + GUID guid; + int allegro_bit; +}; + +/* GUID values are borrowed from Wine */ +#define DEFINE_PRIVATE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + static const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + +DEFINE_PRIVATE_GUID(_al_GUID_None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + +static const struct CAP_MAP cap_map[] = { + { GUID_ConstantForce, ALLEGRO_HAPTIC_CONSTANT }, + { GUID_Spring, ALLEGRO_HAPTIC_SPRING }, + { GUID_Spring, ALLEGRO_HAPTIC_FRICTION }, + { GUID_Damper, ALLEGRO_HAPTIC_DAMPER }, + { GUID_Inertia, ALLEGRO_HAPTIC_INERTIA }, + { GUID_RampForce, ALLEGRO_HAPTIC_RAMP }, + { GUID_Square, ALLEGRO_HAPTIC_SQUARE }, + { GUID_Triangle, ALLEGRO_HAPTIC_TRIANGLE }, + { GUID_Sine, ALLEGRO_HAPTIC_SINE }, + { GUID_SawtoothUp, ALLEGRO_HAPTIC_SAW_UP }, + { GUID_SawtoothDown, ALLEGRO_HAPTIC_SAW_DOWN }, + { GUID_CustomForce, ALLEGRO_HAPTIC_CUSTOM }, + /*{ { _al_GUID_None }, -1 } */ +}; + + +static bool whap_init_haptic(void) +{ + int i; + + ASSERT(haptic_mutex == NULL); + haptic_mutex = al_create_mutex(); + if (!haptic_mutex) + return false; + + for (i = 0; i < HAPTICS_MAX; i++) { + haptics[i].active = false; + } + + return true; +} + + +static ALLEGRO_HAPTIC_WINDOWS *whap_get_available_haptic(void) +{ + int i; + + for (i = 0; i < HAPTICS_MAX; i++) { + if (!haptics[i].active) { + haptics[i].active = true; + return &haptics[i]; + } + } + + return NULL; +} + +/* Look for a free haptic effect slot for a device and return it, + * or NULL if exhausted. Also initializes the effect + * reference to NULL. */ +static ALLEGRO_HAPTIC_EFFECT_WINDOWS +*whap_get_available_effect(ALLEGRO_HAPTIC_WINDOWS *whap) +{ + ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff; + int i; + for (i = 0; i < al_get_max_haptic_effects(&whap->parent); i++) { + if (!whap->effects[i].active) { + weff = whap->effects + i; + weff->id = i; + weff->active = true; + weff->ref = NULL; + return weff; + } + } + return NULL; +} + + +/* Releases a windows haptics effect and unloads it from the device. */ +static bool whap_release_effect_windows(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff) +{ + bool result = true; + if (!weff) + return false; /* make it easy to handle all cases later on. */ + if (!weff->active) + return false; /* already not in use, bail out. */ + + /* Unload the effect from the device. */ + if (weff->ref) { + HRESULT ret; + ret = IDirectInputEffect_Unload(weff->ref); + if (FAILED(ret)) { + ALLEGRO_WARN("Could not unload effect."); + result = false; + } + } + /* Custom force needs to clean up it's data. */ + if (weff->guid == &GUID_CustomForce) { + al_free(weff->parameter.custom.rglForceData); + weff->parameter.custom.rglForceData = NULL; + } + weff->active = false; /* not in use */ + weff->ref = NULL; /* No reference to effect anymore. */ + return result; +} + + +/* Converts a generic haptic device to a Windows-specific one. */ +static ALLEGRO_HAPTIC_WINDOWS *whap_from_al(ALLEGRO_HAPTIC *hap) +{ + return (ALLEGRO_HAPTIC_WINDOWS *)hap; +} + +static void whap_exit_haptic(void) +{ + ASSERT(haptic_mutex); + al_destroy_mutex(haptic_mutex); + haptic_mutex = NULL; +} + +/* Convert the type of the periodic allegro effect to the windows effect*/ +static bool whap_periodictype2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + switch (effect->data.periodic.waveform) { + case ALLEGRO_HAPTIC_SINE: + weff->guid = &GUID_Sine; + return true; + + case ALLEGRO_HAPTIC_SQUARE: + weff->guid = &GUID_Square; + return true; + + case ALLEGRO_HAPTIC_TRIANGLE: + weff->guid = &GUID_Triangle; + return true; + + case ALLEGRO_HAPTIC_SAW_UP: + weff->guid = &GUID_SawtoothUp; + return true; + + case ALLEGRO_HAPTIC_SAW_DOWN: + weff->guid = &GUID_SawtoothDown; + return true; + + case ALLEGRO_HAPTIC_CUSTOM: + weff->guid = &GUID_CustomForce; + return true; + default: + return false; + } +} + + + +/* Convert the type of the allegro effect to the windows effect*/ +static bool whap_type2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + switch (effect->type) { + case ALLEGRO_HAPTIC_RUMBLE: + weff->guid = &GUID_Sine; + return true; + case ALLEGRO_HAPTIC_PERIODIC: + return whap_periodictype2win(weff, effect); + case ALLEGRO_HAPTIC_CONSTANT: + weff->guid = &GUID_ConstantForce; + return true; + case ALLEGRO_HAPTIC_SPRING: + weff->guid = &GUID_Spring; + return true; + case ALLEGRO_HAPTIC_FRICTION: + weff->guid = &GUID_Friction; + return true; + case ALLEGRO_HAPTIC_DAMPER: + weff->guid = &GUID_Damper; + return true; + case ALLEGRO_HAPTIC_INERTIA: + weff->guid = &GUID_Inertia; + return true; + case ALLEGRO_HAPTIC_RAMP: + weff->guid = &GUID_RampForce; + return true; + default: + return NULL; + } + return true; +} + +/* Convert the direction of the allegro effect to the windows effect*/ +static bool whap_direction2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect, + ALLEGRO_HAPTIC_WINDOWS *whap) +{ + unsigned int index; + double calc_x, calc_y; + + /* It seems that (at least for sine motions), 1 or 2 axes work, but 0 or 3 don't + for my test joystick. Also, while polar or spherical coordinates are accepted, + they don't cause any vibration for a periodic effect. All in + all it seems that cartesian is the only well-supported axis system, + at least for periodic effects. Need more tests with other joysticks to see + their behavior. + Annoyingly there seems to be no way to discover + what kind of axis system is supported without trying to upload the + effect... Hence, use a 1 or 2 axis cartesian system and hope for the + best for non-periodic effects. + */ + + + /* Use CARTESIAN coordinates since those seem to be the only well suppported + ones. */ + weff->effect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + /* Prepare axes. If whap naxes is > 2, use 2 because more than 2 + axes isn't always supported. */ + weff->effect.cAxes = whap->naxes; + if (weff->effect.cAxes > 2) { + weff->effect.cAxes = 2; + } + memset((void *)weff->axes, 0, sizeof(weff->axes)); + for (index = 0; index < weff->effect.cAxes; index++) { + weff->axes[index] = whap->axes[index]; + } + weff->effect.rgdwAxes = weff->axes; + /* Set up directions as well.. */ + memset((void *)weff->directions, 0, sizeof(weff->directions)); + /* Calculate the X and Y coordinates of the effect based on the angle. + That is map angular coordinates to cartesian ones. */ + calc_x = + sin(effect->direction.angle) * effect->direction.radius * + DI_FFNOMINALMAX; + calc_y = + cos(effect->direction.angle) * effect->direction.radius * + DI_FFNOMINALMAX; + + /* Set X if there is 1 axis and also y if there are more . + */ + if (weff->effect.cAxes > 1) { + weff->directions[0] = (long)calc_x; + } + if (whap->naxes > 2) { + weff->directions[1] = (long)calc_y; + } + weff->effect.rglDirection = weff->directions; + return true; +} + +/* Converts the time in seconds to a Windows-compatible time. + * Return false if out of bounds. + */ +static bool whap_time2win(DWORD *res, double sec) +{ + ASSERT(res); + + if (sec < 0.0 || sec >= 4294.967296) + return false; + (*res) = (DWORD)floor(sec * DI_SECONDS); + return true; +} + +/* Converts the level in range 0.0 to 1.0 to a Windows-compatible level. + * Returns false if out of bounds. + */ +static bool whap_level2win(DWORD *res, double level) +{ + ASSERT(res); + + if (level < 0.0 || level > 1.0) + return false; + *res = (DWORD)floor(level * DI_FFNOMINALMAX); + return true; +} + + +/* Converts the level in range -1.0 to 1.0 to a Windows-compatible level. + * Returns false if out of bounds. + */ +static bool whap_slevel2win(LONG *res, double level) +{ + ASSERT(res); + + if (level < -1.0 || level > 1.0) + return false; + *res = (LONG)(level * DI_FFNOMINALMAX); + return true; +} + +/* Converts a phase in range 0.0 to 1.0 to a Windows-compatible level. + * Returns false if out of bounds. + */ +static bool whap_phase2win(DWORD *res, double phase) +{ + ASSERT(res); + + if (phase < 0.0 || phase > 1.0) + return false; + *res = (DWORD)(phase * 35999); + return true; +} + + +/* Converts replay data to Widows-compatible data. */ +static bool whap_replay2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + return whap_time2win(&weff->effect.dwStartDelay, effect->replay.delay) + && whap_time2win(&weff->effect.dwDuration, effect->replay.length); +} + + +/* Converts an Allegro haptic effect envelope to DirectInput API. */ +static bool whap_envelope2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_ENVELOPE *aenv) +{ + /* Prepare envelope. */ + DIENVELOPE *wenv = &weff->envelope; + + /* Do not set any envelope if all values are 0.0 */ + if ((aenv->attack_length == 0.0) && + (aenv->fade_length == 0.0) && + (aenv->attack_level == 0.0) && (aenv->fade_level == 0.0)) { + return true; + } + + /* Prepare the envelope. */ + memset((void *)wenv, 0, sizeof(DIENVELOPE)); + weff->envelope.dwSize = sizeof(DIENVELOPE); + weff->effect.lpEnvelope = wenv; + + /* Set the values. */ + return whap_time2win(&wenv->dwAttackTime, aenv->attack_length) + && whap_time2win(&wenv->dwFadeTime, aenv->fade_length) + && whap_level2win(&wenv->dwAttackLevel, aenv->attack_level) + && whap_level2win(&wenv->dwFadeLevel, aenv->fade_level); +} + +/* Converts a constant effect to directinput API. */ +static bool whap_constant2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + weff->effect.cbTypeSpecificParams = sizeof(weff->parameter.constant); + weff->effect.lpvTypeSpecificParams = &weff->parameter.constant; + return whap_envelope2win(weff, &effect->data.constant.envelope) + && whap_slevel2win(&weff->parameter.constant.lMagnitude, + effect->data.constant.level); +} + + +/* Converts a ramp effect to directinput input API. */ +static bool whap_ramp2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + weff->effect.cbTypeSpecificParams = sizeof(weff->parameter.ramp); + weff->effect.lpvTypeSpecificParams = &weff->parameter.ramp; + + return whap_envelope2win(weff, &effect->data.ramp.envelope) + && whap_slevel2win(&weff->parameter.ramp.lStart, + effect->data.ramp.start_level) + && whap_slevel2win(&weff->parameter.ramp.lEnd, + effect->data.ramp.end_level); +} + +/* Converts a condition effect to directinput input API. */ +static bool whap_condition2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + weff->effect.cbTypeSpecificParams = sizeof(weff->parameter.condition); + weff->effect.lpvTypeSpecificParams = &weff->parameter.condition; + /* XXX: no envelope here ??? */ + + return whap_level2win(&weff->parameter.condition.dwNegativeSaturation, + effect->data.condition.left_saturation) + && whap_level2win(&weff->parameter.condition.dwPositiveSaturation, + effect->data.condition.right_saturation) + && whap_slevel2win(&weff->parameter.condition.lNegativeCoefficient, + effect->data.condition.left_coeff) + && whap_slevel2win(&weff->parameter.condition.lPositiveCoefficient, + effect->data.condition.right_coeff) + && whap_slevel2win(&weff->parameter.condition.lDeadBand, + effect->data.condition.deadband) + && whap_slevel2win(&weff->parameter.condition.lOffset, + effect->data.condition.center); +} + +/* Converts a custom effect to directinput input API. */ +static bool whap_custom2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + int index; + weff->effect.cbTypeSpecificParams = sizeof(weff->parameter.custom); + weff->effect.lpvTypeSpecificParams = &weff->parameter.custom; + weff->parameter.custom.cChannels = 1; + weff->parameter.custom.cSamples = effect->data.periodic.custom_len; + /* Use al malloc only in this case since the custom_data can be arbitrarily long. */ + weff->parameter.custom.rglForceData = + (LONG *)al_malloc(sizeof(LONG) * effect->data.periodic.custom_len); + if (!weff->parameter.custom.rglForceData) + return false; + /* Gotta copy this to long values, and scale them too... */ + for (index = 0; index < effect->data.periodic.custom_len; index++) { + weff->parameter.custom.rglForceData[index] = + (LONG)(effect->data.periodic.custom_data[index] * + ((double)(1 << 31))); + } + return true; +} + + +/* Converts a periodic effect to directinput input API. */ +static bool whap_periodic2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + if (effect->data.periodic.waveform == ALLEGRO_HAPTIC_CUSTOM) { + return whap_custom2win(weff, effect); + } + + weff->effect.cbTypeSpecificParams = sizeof(weff->parameter.periodic); + weff->effect.lpvTypeSpecificParams = &weff->parameter.periodic; + + return whap_envelope2win(weff, &effect->data.periodic.envelope) + && whap_level2win(&weff->parameter.periodic.dwMagnitude, + effect->data.periodic.magnitude) + && whap_phase2win(&weff->parameter.periodic.dwPhase, + effect->data.periodic.phase) + && whap_time2win(&weff->parameter.periodic.dwPeriod, + effect->data.periodic.period) + && whap_slevel2win(&weff->parameter.periodic.lOffset, + effect->data.periodic.offset); +} + + +/* Converts a periodic effect to directinput input API. */ +static bool whap_rumble2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + weff->effect.cbTypeSpecificParams = sizeof(weff->parameter.periodic); + weff->effect.lpvTypeSpecificParams = &weff->parameter.periodic; + + return whap_level2win(&weff->parameter.periodic.dwMagnitude, + effect->data.rumble.strong_magnitude) + && whap_phase2win(&weff->parameter.periodic.dwPhase, 0) + && whap_time2win(&weff->parameter.periodic.dwPeriod, 0.01) + && whap_slevel2win(&weff->parameter.periodic.lOffset, 0); +} + +/* Converts Allegro haptic effect to dinput API. */ +static bool whap_effect2win(ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, + ALLEGRO_HAPTIC_EFFECT *effect, + ALLEGRO_HAPTIC_WINDOWS *whap) +{ + /* Generic setup */ + memset((void *)weff, 0, sizeof(*weff)); + /* Set global stuff. */ + weff->effect.dwSize = sizeof(DIEFFECT); + weff->effect.dwGain = DI_FFNOMINALMAX; + weff->effect.dwSamplePeriod = 0; + weff->effect.dwFlags = DIEFF_OBJECTOFFSETS; + weff->effect.lpEnvelope = NULL; + /* Gain of the effect must be set to max, otherwise it won't be felt + (enough) as the per effect gain multiplies with the per-device gain. */ + weff->effect.dwGain = DI_FFNOMINALMAX; + /* This effect is not mapped to a trigger, and must be played explicitly. */ + weff->effect.dwTriggerButton = DIEB_NOTRIGGER; + + if (!whap_type2win(weff, effect)) { + return false; + } + + if (!whap_direction2win(weff, effect, whap)) { + return false; + } + + if (!whap_replay2win(weff, effect)) { + return false; + } + + + switch (effect->type) { + case ALLEGRO_HAPTIC_RUMBLE: + return whap_rumble2win(weff, effect); + case ALLEGRO_HAPTIC_PERIODIC: + return whap_periodic2win(weff, effect); + case ALLEGRO_HAPTIC_CONSTANT: + return whap_constant2win(weff, effect); + case ALLEGRO_HAPTIC_RAMP: + return whap_ramp2win(weff, effect); + case ALLEGRO_HAPTIC_SPRING: + case ALLEGRO_HAPTIC_FRICTION: + case ALLEGRO_HAPTIC_DAMPER: + case ALLEGRO_HAPTIC_INERTIA: + return whap_condition2win(weff, effect); + default: + return false; + } +} + +static bool whap_get_active(ALLEGRO_HAPTIC *haptic) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(haptic); + return whap->active; +} + + +static bool whap_is_dinput_device_haptic(LPDIRECTINPUTDEVICE2 device) +{ + HRESULT ret; + DIDEVCAPS dicaps; + /* Get capabilities. */ + ALLEGRO_DEBUG("IDirectInputDevice_GetCapabilities on %p\n", device); + dicaps.dwSize = sizeof(dicaps); + ret = IDirectInputDevice_GetCapabilities(device, &dicaps); + if (FAILED(ret)) { + ALLEGRO_ERROR("IDirectInputDevice_GetCapabilities failed on %p\n", + device); + return false; + } + /** Is it a haptic device? */ + bool ishaptic = (dicaps.dwFlags & DIDC_FORCEFEEDBACK); + ALLEGRO_DEBUG("dicaps.dwFlags: %lu, %d, %d\n", dicaps.dwFlags, + DIDC_FORCEFEEDBACK, ishaptic); + return(ishaptic); +} + + + +static bool whap_is_mouse_haptic(ALLEGRO_MOUSE *mouse) +{ + (void)mouse; + return false; +} + + +static bool whap_is_joystick_haptic(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_DIRECTX *joydx = (ALLEGRO_JOYSTICK_DIRECTX *)joy; + (void)joydx; + if (!al_is_joystick_installed()) + return false; + if (!al_get_joystick_active(joy)) + return false; + ALLEGRO_DEBUG("Checking capabilities of joystick %s\n", joydx->name); + return whap_is_dinput_device_haptic(joydx->device); +} + + +static bool whap_is_display_haptic(ALLEGRO_DISPLAY *dev) +{ + (void)dev; + return false; +} + + +static bool whap_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev) +{ + (void)dev; + return false; +} + + +static bool whap_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev) +{ + (void)dev; + return false; +} + + +static ALLEGRO_HAPTIC *whap_get_from_mouse(ALLEGRO_MOUSE *mouse) +{ + (void)mouse; + return NULL; +} + + +/* Sets the force feedback gain on a directinput device. + Returns true on success and false on failure. */ +static bool whap_set_dinput_device_gain(LPDIRECTINPUTDEVICE2 device, + double gain) +{ + HRESULT ret; + DIPROPDWORD dipdw; + if (gain < 0.0) + return false; + if (gain > 1.0) + return false; + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = gain * DI_FFNOMINALMAX; + + ret = IDirectInputDevice_SetProperty(device, DIPROP_FFGAIN, &dipdw.diph); + return(!FAILED(ret)); +} + +/* Sets the force feedback autocentering intensity on a directinput device. + Returns true on success and false on failure. */ +static bool whap_set_dinput_device_autocenter(LPDIRECTINPUTDEVICE2 device, + double intensity) +{ + HRESULT ret; + DIPROPDWORD dipdw; + if (intensity < 0.0) + return false; + if (intensity > 1.0) + return false; + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + if (intensity < 0.5) { + dipdw.dwData = DIPROPAUTOCENTER_OFF; + } + else { + dipdw.dwData = DIPROPAUTOCENTER_ON; + } + /* Try to set the autocenter. */ + ret = IDirectInputDevice_SetProperty(device, DIPROP_AUTOCENTER, &dipdw.diph); + return(!FAILED(ret)); +} + + +/* Callback to check which effect types are supported. */ +static BOOL CALLBACK +whap_check_effect_callback(LPCDIEFFECTINFO info, LPVOID data) +{ + ALLEGRO_HAPTIC *haptic = (ALLEGRO_HAPTIC *)data; + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(haptic); + + const CAP_MAP *map; + for (map = cap_map; map->allegro_bit != -1; map++) { + if (GUID_EQUAL(info->guid, map->guid)) { + whap->flags |= map->allegro_bit; + } + } + /* Check for more supported effect types. */ + return DIENUM_CONTINUE; +} + + +/* Callback to check which axes are supported. */ +static BOOL CALLBACK +whap_check_axes_callback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID data) +{ + ALLEGRO_HAPTIC *haptic = (ALLEGRO_HAPTIC *)data; + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(haptic); + + if ((dev->dwType & DIDFT_AXIS) && (dev->dwFlags & DIDOI_FFACTUATOR)) { + whap->axes[whap->naxes] = dev->dwOfs; + whap->naxes++; + + /* Stop if the axes limit is reached */ + if (whap->naxes >= HAPTICS_AXES_MAX) { + return DIENUM_STOP; + } + } + return DIENUM_CONTINUE; +} + +/* Acquires an exclusive lock on the device. */ +static bool whap_acquire_lock(ALLEGRO_HAPTIC_WINDOWS *whap) +{ + HRESULT ret; + + /* Release previous acquire lock on device if any */ + ret = IDirectInputDevice_Unacquire(whap->device); + if (FAILED(ret)) { + ALLEGRO_WARN + ("IDirectInputDevice_Unacquire failed for haptic device.\n"); + return false; + } + + /* Need a display to lock the cooperative level of the haptic device on */ + whap->display = (ALLEGRO_DISPLAY_WIN *)al_get_current_display(); + if (!whap->display) { + ALLEGRO_WARN("No active window available to lock the haptic device on."); + return false; + } + + /* Must set the cooperative level to exclusive now to enable force feedback. + */ + ret = + IDirectInputDevice_SetCooperativeLevel(whap->device, + whap->display->window, + DISCL_BACKGROUND | + DISCL_EXCLUSIVE); + if (FAILED(ret)) { + ALLEGRO_WARN + ("IDirectInputDevice_SetCooperativeLevel failed for haptic device.\n"); + return false; + } + + /* Get acquire lock on device */ + ret = IDirectInputDevice_Acquire(whap->device); + if (FAILED(ret)) { + ALLEGRO_WARN("IDirectInputDevice_Acquire failed for haptic device.\n"); + return false; + } + return true; +} + + +/* Initializes the haptic device for use with DirectInput */ +static bool whap_initialize_dinput(ALLEGRO_HAPTIC_WINDOWS *whap) +{ + HRESULT ret; + ALLEGRO_HAPTIC *haptic = &whap->parent; + /* Set number of axes to zero, and then ... */ + whap->naxes = 0; + /* ... get number of axes. */ + ret = IDirectInputDevice_EnumObjects(whap->device, + whap_check_axes_callback, + haptic, DIDFT_AXIS); + if (FAILED(ret)) { + ALLEGRO_WARN("Could not get haptic device axes \n"); + return false; + } + + /* Support angle and radius if we have at least 2 axes. + * Axis support on DirectInput is a big mess, so Azimuth is unlikely to be + * supported. + */ + if (whap->naxes >= 1) { + whap->flags |= ALLEGRO_HAPTIC_ANGLE; + whap->flags |= ALLEGRO_HAPTIC_RADIUS; + } + + if (!whap_acquire_lock(whap)) { + ALLEGRO_WARN("Could not lock haptic device \n"); + return false; + } + /* Reset all actuators in case some where active */ + ret = IDirectInputDevice8_SendForceFeedbackCommand(whap->device, + DISFFC_RESET); + if (FAILED(ret)) { + ALLEGRO_WARN("Could not reset haptic device \n"); + } + + /* Enable all actuators. */ + ret = IDirectInputDevice8_SendForceFeedbackCommand(whap->device, + DISFFC_SETACTUATORSON); + if (FAILED(ret)) { + ALLEGRO_WARN("Could not enable haptic device actuators\n"); + return false; + } + + /* Get known supported effects. */ + ret = IDirectInputDevice8_EnumEffects(whap->device, + whap_check_effect_callback, haptic, + DIEFT_ALL); + if (FAILED(ret)) { + ALLEGRO_WARN("Could not get haptic device supported effects\n"); + return false; + } + + /* Check if any periodic effects are supported. */ + bool periodic_ok = al_is_haptic_capable(haptic, ALLEGRO_HAPTIC_SINE); + periodic_ok |= al_is_haptic_capable(haptic, ALLEGRO_HAPTIC_SQUARE); + periodic_ok |= al_is_haptic_capable(haptic, ALLEGRO_HAPTIC_TRIANGLE); + periodic_ok |= al_is_haptic_capable(haptic, ALLEGRO_HAPTIC_SAW_DOWN); + periodic_ok |= al_is_haptic_capable(haptic, ALLEGRO_HAPTIC_SAW_UP); + + if (periodic_ok) { + /* If we have any of the effects above, we can use + periodic and rumble effects. */ + whap->flags |= (ALLEGRO_HAPTIC_PERIODIC | ALLEGRO_HAPTIC_RUMBLE); + } + + if (whap_set_dinput_device_gain(whap->device, 1.0)) { + whap->flags |= ALLEGRO_HAPTIC_GAIN; + } + + /* Check autocenter and turn it off in one go. */ + if (whap_set_dinput_device_autocenter(whap->device, 0.0)) { + whap->flags |= ALLEGRO_HAPTIC_AUTOCENTER; + } + + return true; +} + + + + +static ALLEGRO_HAPTIC *whap_get_from_joystick(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_DIRECTX *joydx = (ALLEGRO_JOYSTICK_DIRECTX *)joy; + ALLEGRO_HAPTIC_WINDOWS *whap; + + int i; + + if (!al_is_joystick_haptic(joy)) + return NULL; + + al_lock_mutex(haptic_mutex); + + whap = whap_get_available_haptic(); + + if (!whap) { + al_unlock_mutex(haptic_mutex); + return NULL; + } + + whap->parent.driver = &_al_hapdrv_directx; + whap->parent.device = joy; + whap->parent.from = _AL_HAPTIC_FROM_JOYSTICK; + + whap->guid = joydx->guid; + whap->device = joydx->device; + whap->active = true; + for (i = 0; i < HAPTICS_EFFECTS_MAX; i++) { + whap->effects[i].active = false; /* not in use */ + } + whap->parent.gain = 1.0; + whap->parent.autocenter = 0.0; + + /* result is ok if init functions returns true. */ + if (!whap_initialize_dinput(whap)) { + al_release_haptic(&whap->parent); + al_unlock_mutex(haptic_mutex); + return NULL; + } + + al_unlock_mutex(haptic_mutex); + + return &whap->parent; +} + + +static ALLEGRO_HAPTIC *whap_get_from_display(ALLEGRO_DISPLAY *dev) +{ + (void)dev; + return NULL; +} + + +static ALLEGRO_HAPTIC *whap_get_from_keyboard(ALLEGRO_KEYBOARD *dev) +{ + (void)dev; + return NULL; +} + + +static ALLEGRO_HAPTIC *whap_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev) +{ + (void)dev; + return NULL; +} + + +static int whap_get_capabilities(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(dev); + return whap->flags; +} + + +static double whap_get_gain(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(dev); + /* Just return the stored gain, it's easier than querying. */ + return whap->parent.gain; +} + + +static bool whap_set_gain(ALLEGRO_HAPTIC *dev, double gain) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(dev); + bool ok = whap_set_dinput_device_gain(whap->device, gain); + if (ok) { + whap->parent.gain = gain; + } + else { + whap->parent.gain = 1.0; + } + return ok; +} + + +double whap_get_autocenter(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(dev); + /* Return the stored autocenter value. It's easiest like that. */ + return whap->parent.autocenter; +} + + +static bool whap_set_autocenter(ALLEGRO_HAPTIC *dev, double intensity) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(dev); + bool ok = whap_set_dinput_device_autocenter(whap->device, intensity); + if (ok) { + whap->parent.autocenter = intensity; + } + else { + whap->parent.autocenter = 0.0; + } + return ok; +} + +static int whap_get_max_effects(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(dev); + int n_effects; + (void)n_effects, (void)whap; + + return HAPTICS_EFFECTS_MAX; +} + + +static bool whap_is_effect_ok(ALLEGRO_HAPTIC *haptic, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + int caps; + + caps = al_get_haptic_capabilities(haptic); + if (caps & effect->type) { + return true; + } + /* XXX: should do more checking here? */ + return false; +} + + +struct dinput_error_pair +{ + HRESULT error; + const char *text; +}; + +#define DIMKEP(ERROR) { ((HRESULT)ERROR), # ERROR } + +struct dinput_error_pair dinput_errors[] = { + DIMKEP(DI_BUFFEROVERFLOW), + DIMKEP(DI_DOWNLOADSKIPPED), + DIMKEP(DI_EFFECTRESTARTED), + DIMKEP(DI_NOEFFECT), + DIMKEP(DI_NOTATTACHED), + DIMKEP(DI_OK), + DIMKEP(DI_POLLEDDEVICE), + DIMKEP(DI_PROPNOEFFECT), + DIMKEP(DI_SETTINGSNOTSAVED), + DIMKEP(DI_TRUNCATED), + DIMKEP(DI_TRUNCATEDANDRESTARTED), + DIMKEP(DI_WRITEPROTECT), + DIMKEP(DIERR_ACQUIRED), + DIMKEP(DIERR_ALREADYINITIALIZED), + DIMKEP(DIERR_BADDRIVERVER), + DIMKEP(DIERR_BETADIRECTINPUTVERSION), + DIMKEP(DIERR_DEVICEFULL), + DIMKEP(DIERR_DEVICENOTREG), + DIMKEP(DIERR_EFFECTPLAYING), + DIMKEP(DIERR_GENERIC), + DIMKEP(DIERR_HANDLEEXISTS), + DIMKEP(DIERR_HASEFFECTS), + DIMKEP(DIERR_INCOMPLETEEFFECT), + DIMKEP(DIERR_INPUTLOST), + DIMKEP(DIERR_INVALIDPARAM), + DIMKEP(DIERR_MAPFILEFAIL), + DIMKEP(DIERR_MOREDATA), + DIMKEP(DIERR_NOAGGREGATION), + DIMKEP(DIERR_NOINTERFACE), + DIMKEP(DIERR_NOTACQUIRED), + DIMKEP(DIERR_NOTBUFFERED), + DIMKEP(DIERR_NOTDOWNLOADED), + DIMKEP(DIERR_NOTEXCLUSIVEACQUIRED), + DIMKEP(DIERR_NOTFOUND), + DIMKEP(DIERR_NOTINITIALIZED), + DIMKEP(DIERR_OBJECTNOTFOUND), + DIMKEP(DIERR_OLDDIRECTINPUTVERSION), + DIMKEP(DIERR_OTHERAPPHASPRIO), + DIMKEP(DIERR_OUTOFMEMORY), + DIMKEP(DIERR_READONLY), + DIMKEP(DIERR_REPORTFULL), + DIMKEP(DIERR_UNPLUGGED), + DIMKEP(DIERR_UNSUPPORTED), + DIMKEP(E_HANDLE), + DIMKEP(E_PENDING), + DIMKEP(E_POINTER), + { 0, NULL } +}; + +static void warn_on_error(HRESULT hr) +{ + struct dinput_error_pair *pair = dinput_errors; + while (pair->text) { + if (hr == pair->error) { + ALLEGRO_WARN("HRESULT error: %s\n", pair->text); + } + pair++; + } + ALLEGRO_WARN("Unknown HRESULT error: %u\n", (unsigned int)hr); +} + + + +static bool whap_upload_effect_helper + (ALLEGRO_HAPTIC_WINDOWS *whap, + ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff, ALLEGRO_HAPTIC_EFFECT *effect) +{ + HRESULT ret; + + if (!whap_effect2win(weff, effect, whap)) { + ALLEGRO_WARN("Could not convert haptic effect.\n"); + return false; + } + + /* Create the effect. */ + ret = IDirectInputDevice8_CreateEffect(whap->device, (*weff->guid), + &weff->effect, + &weff->ref, NULL); + + /* XXX Need to re-lock since the joystick driver steals my thunder + * by calling Unacquire on the device. + * The better way would be to fix this in that driver somehow. + */ + if (!whap_acquire_lock(whap)) { + ALLEGRO_WARN("Could not lock haptic device.\n"); + return false; + } + + + /* Create the effect. */ + ret = IDirectInputDevice8_CreateEffect(whap->device, (*weff->guid), + &weff->effect, &weff->ref, NULL); + + if (FAILED(ret)) { + ALLEGRO_WARN("Could not create haptic effect.\n"); + warn_on_error(ret); + return false; + } + + /* Upload the effect to the device. */ + ret = IDirectInputEffect_Download(weff->ref); + if (FAILED(ret)) { + ALLEGRO_WARN("Could not upload haptic effect.\n"); + warn_on_error(ret); + return false; + } + + return true; +} + +static bool whap_upload_effect(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *effect, + ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + bool ok = FALSE; + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(dev); + ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff = NULL; + + ASSERT(dev); + ASSERT(id); + ASSERT(effect); + + /* Set id's values to indicate failure beforehand. */ + id->_haptic = NULL; + id->_id = -1; + id->_pointer = NULL; + id->_playing = false; + id->_effect_duration = 0.0; + id->_start_time = 0.0; + id->_end_time = 0.0; + + al_lock_mutex(haptic_mutex); + + /* Look for a free haptic effect slot. */ + weff = whap_get_available_effect(whap); + /* Returns NULL if there is no more space for an effect. */ + if (weff) { + if (whap_upload_effect_helper(whap, weff, effect)) { + /* set ID handle to signify success */ + id->_haptic = dev; + id->_pointer = weff; + id->_id = weff->id; + id->_effect_duration = al_get_haptic_effect_duration(effect); + ok = true; + } + else { + ALLEGRO_WARN("Could not upload effect."); + } + } + else { + ALLEGRO_WARN("No free effect slot."); + } + + al_unlock_mutex(haptic_mutex); + return ok; +} + + +static bool whap_play_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loops) +{ + HRESULT res; + ALLEGRO_HAPTIC_WINDOWS *whap = (ALLEGRO_HAPTIC_WINDOWS *)id->_haptic; + ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff; + if ((!whap) || (id->_id < 0)) + return false; + weff = whap->effects + id->_id; + + /* Need to re-lock since the joystick driver steals the haptics' thunder + * by calling Unacquire on the device. + * The better way would be to fix this in that driver somehow. + */ + if (!whap_acquire_lock(whap)) { + ALLEGRO_WARN("Could not lock haptic device \n"); + return false; + } + + res = IDirectInputEffect_Start(weff->ref, loops, 0); + if (FAILED(res)) { + ALLEGRO_WARN("Failed to play an effect."); + warn_on_error(res); + return false; + } + id->_playing = true; + id->_start_time = al_get_time(); + id->_end_time = id->_start_time; + id->_end_time += id->_effect_duration * (double)loops; + return true; +} + + +static bool whap_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + HRESULT res; + ALLEGRO_HAPTIC_WINDOWS *whap = (ALLEGRO_HAPTIC_WINDOWS *)id->_haptic; + ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff; + + if ((!whap) || (id->_id < 0)) + return false; + + weff = whap->effects + id->_id; + + res = IDirectInputEffect_Stop(weff->ref); + if (FAILED(res)) { + ALLEGRO_WARN("Failed to play an effect."); + return false; + } + id->_playing = false; + + + return true; +} + + +static bool whap_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ASSERT(id); + HRESULT res; + DWORD flags = 0; + ALLEGRO_HAPTIC_WINDOWS *whap = (ALLEGRO_HAPTIC_WINDOWS *)id->_haptic; + ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff; + + if ((!whap) || (id->_id < 0) || (!id->_playing)) + return false; + + weff = whap->effects + id->_id; + + res = IDirectInputEffect_GetEffectStatus(weff->ref, &flags); + if (FAILED(res)) { + ALLEGRO_WARN("Failed to get the status of effect."); + /* If we get here, then use the play time in stead to + * see if the effect should still be playing. + * Do this because in case GeteffectStatus fails, we can't + * assume the sample isn't playing. In fact, if the play command + * was successful, it should still be playing as long as the play + * time has not passed. + */ + return(al_get_time() < id->_end_time); + } + if (flags & DIEGES_PLAYING) + return true; + /* WINE is bugged here, it doesn't set flags, but it also + * just returns DI_OK. Thats why here, don't believe the API + * when it the playing flag isn't set if the effect's duration + * has not passed. On real Windows it should probably always be the + * case that the effect will have played completely when + * the play time has ended. + */ + return(al_get_time() < id->_end_time); +} + + + +static bool whap_release_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = (ALLEGRO_HAPTIC_WINDOWS *)id->_haptic; + ALLEGRO_HAPTIC_EFFECT_WINDOWS *weff; + if ((!whap) || (id->_id < 0)) + return false; + + whap_stop_effect(id); + + weff = whap->effects + id->_id; + return whap_release_effect_windows(weff); +} + + +static bool whap_release(ALLEGRO_HAPTIC *haptic) +{ + ALLEGRO_HAPTIC_WINDOWS *whap = whap_from_al(haptic); + int index; + HRESULT res; + + ASSERT(haptic); + + if (!whap->active) + return false; + + /* Release all effects for this device. */ + for (index = 0; index < HAPTICS_EFFECTS_MAX; index++) { + whap_release_effect_windows(whap->effects + index); + } + + /* Release the acquire lock on the device */ + IDirectInputDevice_Unacquire(whap->device); + + /* Reset the cooperative level to nonexclusive. + */ + res = + IDirectInputDevice_SetCooperativeLevel(whap->device, + whap->display->window, + DISCL_FOREGROUND | + DISCL_NONEXCLUSIVE); + if (FAILED(res)) { + ALLEGRO_WARN + ("IDirectInputDevice8_SetCooperativeLevel NONEXCLUSIVE failed for haptic device.\n"); + } + + whap->display = NULL; + whap->active = false; + whap->device = NULL; + return true; +} + + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/whapxi.c b/allegro/src/win/whapxi.c new file mode 100644 index 00000000..29932721 --- /dev/null +++ b/allegro/src/win/whapxi.c @@ -0,0 +1,839 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows haptic (force-feedback) device driver. + * + * By Beoran. + * + * See LICENSE.txt for copyright information. + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#define DIRECTINPUT_VERSION 0x0800 + +/* For waitable timers */ +#define _WIN32_WINNT 0x0501 + +#include "allegro5/allegro.h" +#include "allegro5/haptic.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_haptic.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_bitmap.h" + +#ifdef ALLEGRO_CFG_XINPUT +/* Don't compile this lot if xinput isn't supported. */ + +#ifndef ALLEGRO_WINDOWS +#error something is wrong with the makefile +#endif + +#ifndef ALLEGRO_XINPUT_POLL_DELAY +#define ALLEGRO_XINPUT_POLL_DELAY 0.1 +#endif + +#ifdef ALLEGRO_MINGW32 + #undef MAKEFOURCC +#endif + +#include +#include +#include +#include +#include + +/* The official DirectX xinput.h uses SAL annotations. + * Need the sal.h header to get rid of them. On some other platforms + * such as MinGW on Linux this header is lacking because it is not needed there. + * So, simply try to include sal.h IF we have it , and if not, hope + * for the best. + * This does no harm on msys2 either, they have a sal.h header. + */ +#ifdef ALLEGRO_HAVE_SAL_H + #include +#endif + +#include + +#include "allegro5/internal/aintern_wjoyxi.h" + + + +ALLEGRO_DEBUG_CHANNEL("haptic") + +/* Support at most 4 haptic devices. */ +#define HAPTICS_MAX 4 + +/* Support at most 1 rumble effect per device, because + * XInput doesn't really support uploading the effects. */ +#define HAPTIC_EFFECTS_MAX 1 + +/* Enum for the state of a haptic effect. The playback is managed by a small + * finite state machine. + */ + +typedef enum ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE +{ + ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_INACTIVE = 0, + ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_READY = 1, + ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_STARTING = 2, + ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_PLAYING = 3, + ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_DELAYED = 4, + ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_STOPPING = 5, +} ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE; + +/* Allowed state transitions: + * from inactive to ready, + * from ready to starting + * from starting to delayed or playing + * from delayed to playing + * from playing to delayed (for loops) or stopping + * from stopping to ready + * from ready to inactive + */ + +typedef struct ALLEGRO_HAPTIC_EFFECT_XINPUT +{ + ALLEGRO_HAPTIC_EFFECT effect; + XINPUT_VIBRATION vibration; + int id; + double start_time; + double loop_start; + double stop_time; + int repeats; + int delay_repeated; + int play_repeated; + ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE state; +} ALLEGRO_HAPTIC_EFFECT_XINPUT; + + +typedef struct ALLEGRO_HAPTIC_XINPUT +{ + /* Important, parent must be first. */ + ALLEGRO_HAPTIC parent; + ALLEGRO_JOYSTICK_XINPUT *xjoy; + bool active; + ALLEGRO_HAPTIC_EFFECT_XINPUT effect; + int flags; + /* Only one effect is supported since the XInput API allows only one pair of + vibration speeds to be set to the device. */ +} ALLEGRO_HAPTIC_XINPUT; + + +/* forward declarations */ +static bool hapxi_init_haptic(void); +static void hapxi_exit_haptic(void); + +static bool hapxi_is_mouse_haptic(ALLEGRO_MOUSE *dev); +static bool hapxi_is_joystick_haptic(ALLEGRO_JOYSTICK *); +static bool hapxi_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev); +static bool hapxi_is_display_haptic(ALLEGRO_DISPLAY *dev); +static bool hapxi_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev); + +static ALLEGRO_HAPTIC *hapxi_get_from_mouse(ALLEGRO_MOUSE *dev); +static ALLEGRO_HAPTIC *hapxi_get_from_joystick(ALLEGRO_JOYSTICK *dev); +static ALLEGRO_HAPTIC *hapxi_get_from_keyboard(ALLEGRO_KEYBOARD *dev); +static ALLEGRO_HAPTIC *hapxi_get_from_display(ALLEGRO_DISPLAY *dev); +static ALLEGRO_HAPTIC *hapxi_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev); + +static bool hapxi_release(ALLEGRO_HAPTIC *haptic); + +static bool hapxi_get_active(ALLEGRO_HAPTIC *hap); +static int hapxi_get_capabilities(ALLEGRO_HAPTIC *dev); +static double hapxi_get_gain(ALLEGRO_HAPTIC *dev); +static bool hapxi_set_gain(ALLEGRO_HAPTIC *dev, double); +static int hapxi_get_max_effects(ALLEGRO_HAPTIC *dev); + +static bool hapxi_is_effect_ok(ALLEGRO_HAPTIC *dev, ALLEGRO_HAPTIC_EFFECT *eff); +static bool hapxi_upload_effect(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *eff, + ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool hapxi_play_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop); +static bool hapxi_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool hapxi_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id); +static bool hapxi_release_effect(ALLEGRO_HAPTIC_EFFECT_ID *id); + +static double hapxi_get_autocenter(ALLEGRO_HAPTIC *dev); +static bool hapxi_set_autocenter(ALLEGRO_HAPTIC *dev, double); + +static void *hapxi_poll_thread(ALLEGRO_THREAD *thread, void *arg); + +ALLEGRO_HAPTIC_DRIVER _al_hapdrv_xinput = +{ + AL_HAPTIC_TYPE_XINPUT, + "", + "", + "Windows XInput haptic(s)", + hapxi_init_haptic, + hapxi_exit_haptic, + + hapxi_is_mouse_haptic, + hapxi_is_joystick_haptic, + hapxi_is_keyboard_haptic, + hapxi_is_display_haptic, + hapxi_is_touch_input_haptic, + + hapxi_get_from_mouse, + hapxi_get_from_joystick, + hapxi_get_from_keyboard, + hapxi_get_from_display, + hapxi_get_from_touch_input, + + hapxi_get_active, + hapxi_get_capabilities, + hapxi_get_gain, + hapxi_set_gain, + hapxi_get_max_effects, + + hapxi_is_effect_ok, + hapxi_upload_effect, + hapxi_play_effect, + hapxi_stop_effect, + hapxi_is_effect_playing, + hapxi_release_effect, + + hapxi_release, + + hapxi_get_autocenter, + hapxi_set_autocenter +}; + + +static ALLEGRO_HAPTIC_XINPUT haptics[HAPTICS_MAX]; +/* For the background thread */ +static ALLEGRO_THREAD *hapxi_thread = NULL; +static ALLEGRO_MUTEX *hapxi_mutex = NULL; +/* Use a condition variable to put the thread to sleep and prevent too + frequent polling. */ +static ALLEGRO_COND *hapxi_cond = NULL; + +typedef DWORD(WINAPI *XInputSetStatePROC)(DWORD, XINPUT_VIBRATION*); +extern XInputSetStatePROC _al_imp_XInputSetState; + +/* Forces vibration to stop immediately. */ +static bool hapxi_force_stop(ALLEGRO_HAPTIC_XINPUT *hapxi, + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + XINPUT_VIBRATION no_vibration = { 0, 0 }; + ALLEGRO_DEBUG("XInput haptic effect stopped.\n"); + _al_imp_XInputSetState(hapxi->xjoy->index, &no_vibration); + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_READY; + return true; +} + +/* starts vibration immediately. If successfully also sets playing */ +static bool hapxi_force_play(ALLEGRO_HAPTIC_XINPUT *hapxi, + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + DWORD res; + res = _al_imp_XInputSetState(hapxi->xjoy->index, &effxi->vibration); + ALLEGRO_DEBUG("Starting to play back haptic effect: %d.\n", (int)(res)); + if (res == ERROR_SUCCESS) { + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_PLAYING; + return true; + } + else { + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_READY; + return false; + } +} + + + +static bool hapxi_poll_haptic_effect_ready(ALLEGRO_HAPTIC_XINPUT *hapxi, + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + (void)hapxi; (void)effxi; + /* when ready do nothing */ + return true; +} + +static bool hapxi_poll_haptic_effect_starting(ALLEGRO_HAPTIC_XINPUT *hapxi, + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + /* when starting switch to delayed mode or play mode */ + double now = al_get_time(); + if ((now - effxi->start_time) < effxi->effect.replay.delay) { + effxi->loop_start = al_get_time(); + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_DELAYED; + } + else { + hapxi_force_play(hapxi, effxi); + } + ALLEGRO_DEBUG("Polling XInput haptic effect. Really Starting: %d!\n", effxi->state); + return true; +} + +static bool hapxi_poll_haptic_effect_playing(ALLEGRO_HAPTIC_XINPUT *hapxi, + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + double now = al_get_time(); + double stop = effxi->loop_start + effxi->effect.replay.delay + + effxi->effect.replay.length; + (void)hapxi; + if (now > stop) { + /* may need to repeat play because of "loop" in playback. */ + effxi->play_repeated++; + if (effxi->play_repeated < effxi->repeats) { + /* need to play another loop. Stop playing now. */ + hapxi_force_stop(hapxi, effxi); + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_DELAYED; + effxi->loop_start = al_get_time(); + } + else { + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_STOPPING; + } + return true; + } + return false; +} + +static bool hapxi_poll_haptic_effect_delayed(ALLEGRO_HAPTIC_XINPUT *hapxi, + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + double now = al_get_time(); + if (now > (effxi->loop_start + effxi->effect.replay.delay)) { + return hapxi_force_play(hapxi, effxi); + } + return false; +} + +static bool hapxi_poll_haptic_effect_stopping(ALLEGRO_HAPTIC_XINPUT *hapxi, + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + /* when stopping, force stop and go to ready state (hapxi_force_stop does this)*/ + return hapxi_force_stop(hapxi, effxi); +} + + +/* Polls the xinput API for a single haptic device and effect. */ +static bool hapxi_poll_haptic_effect(ALLEGRO_HAPTIC_XINPUT *hapxi, + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + /* Check the state of the effect. */ + switch (effxi->state) { + case ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_INACTIVE: + return false; + case ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_READY: + return hapxi_poll_haptic_effect_ready(hapxi, effxi); + case ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_STARTING: + return hapxi_poll_haptic_effect_starting(hapxi, effxi); + case ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_PLAYING: + return hapxi_poll_haptic_effect_playing(hapxi, effxi); + case ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_DELAYED: + return hapxi_poll_haptic_effect_delayed(hapxi, effxi); + case ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_STOPPING: + return hapxi_poll_haptic_effect_stopping(hapxi, effxi); + default: + ALLEGRO_DEBUG("XInput haptic effect state not valid :%d.\n", effxi->state); + return false; + } +} + +/* Polls the xinput API for a single haptic device. */ +static void hapxi_poll_haptic(ALLEGRO_HAPTIC_XINPUT *hapxi) +{ + hapxi_poll_haptic_effect(hapxi, &hapxi->effect); +} + +/* Polls the xinput API for hapxi effect and starts + * or stops playback when needed. + */ +static void hapxi_poll_haptics(void) +{ + int i; + + for (i = 0; i < HAPTICS_MAX; i++) { + if (haptics[i].active) { + hapxi_poll_haptic(haptics + i); + } + } +} + + +/* Function for the haptics polling thread. */ +static void *hapxi_poll_thread(ALLEGRO_THREAD *thread, void *arg) +{ + ALLEGRO_TIMEOUT timeout; + al_lock_mutex(hapxi_mutex); + while (!al_get_thread_should_stop(thread)) { + /* Poll once every 10 milliseconds. XXX: Should this be configurable? */ + al_init_timeout(&timeout, ALLEGRO_XINPUT_POLL_DELAY); + /* Wait for the condition to allow the + polling thread to be awoken when needed. */ + al_wait_cond_until(hapxi_cond, hapxi_mutex, &timeout); + /* If we get here poll joystick for new input or connection + * and dispatch events. */ + hapxi_poll_haptics(); + } + al_unlock_mutex(hapxi_mutex); + return arg; +} + + + +/* Initializes the XInput haptic system. */ +static bool hapxi_init_haptic(void) +{ + int i; + + ASSERT(hapxi_mutex == NULL); + ASSERT(hapxi_thread == NULL); + ASSERT(hapxi_cond == NULL); + + + /* Create the mutex and a condition vaiable. */ + hapxi_mutex = al_create_mutex_recursive(); + if (!hapxi_mutex) + return false; + hapxi_cond = al_create_cond(); + if (!hapxi_cond) + return false; + + al_lock_mutex(hapxi_mutex); + + for (i = 0; i < HAPTICS_MAX; i++) { + haptics[i].active = false; + } + + /* Now start a polling background thread, since XInput is a polled API, + and also to make it possible for effects to stop running when their + duration has passed. */ + hapxi_thread = al_create_thread(hapxi_poll_thread, NULL); + al_unlock_mutex(hapxi_mutex); + if (hapxi_thread) al_start_thread(hapxi_thread); + return(hapxi_thread != NULL); +} + + +/* Converts a generic haptic device to a Windows-specific one. */ +static ALLEGRO_HAPTIC_XINPUT *hapxi_from_al(ALLEGRO_HAPTIC *hap) +{ + return (ALLEGRO_HAPTIC_XINPUT *)hap; +} + +static void hapxi_exit_haptic(void) +{ + void *ret_value; + ASSERT(hapxi_thread); + ASSERT(hapxi_mutex); + ASSERT(hapxi_cond); + + /* Request the event thread to shut down, signal the condition, then join the thread. */ + al_set_thread_should_stop(hapxi_thread); + al_signal_cond(hapxi_cond); + al_join_thread(hapxi_thread, &ret_value); + + /* clean it all up. */ + al_destroy_thread(hapxi_thread); + al_destroy_cond(hapxi_cond); + + al_destroy_mutex(hapxi_mutex); + hapxi_mutex = NULL; +} + +/* Converts a float to a unsigned WORD range */ +static bool hapxi_magnitude2win(WORD *word, double value) +{ + if (!word) return false; + (*word) = (WORD)(65535 * value); + return true; +} + +/* Converts Allegro haptic effect to xinput API. */ +static bool hapxi_effect2win( + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi, + ALLEGRO_HAPTIC_EFFECT *effect, + ALLEGRO_HAPTIC_XINPUT *hapxi) +{ + (void)hapxi; + /* Generic setup */ + if (effect->type != ALLEGRO_HAPTIC_RUMBLE) + return false; + + /* Right motor is "weaker" than left one, That is, right produces a less + violent vibration than left. */ + return + hapxi_magnitude2win(&effxi->vibration.wRightMotorSpeed, + effect->data.rumble.weak_magnitude) && + hapxi_magnitude2win(&effxi->vibration.wLeftMotorSpeed, + effect->data.rumble.strong_magnitude); +} + +static bool hapxi_get_active(ALLEGRO_HAPTIC *haptic) +{ + ALLEGRO_HAPTIC_XINPUT *hapxi = hapxi_from_al(haptic); + return hapxi->active; +} + + + +static bool hapxi_is_mouse_haptic(ALLEGRO_MOUSE *mouse) +{ + (void)mouse; + return false; +} + + +static bool hapxi_is_joystick_haptic(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_XINPUT *joyxi = (ALLEGRO_JOYSTICK_XINPUT *)joy; + if (!al_is_joystick_installed()) + return false; + if (!al_get_joystick_active(joy)) + return false; + + /* IF this flag is not supported, then it means we're compiling against + an older XInput library. In this case, the Flags are inoperable, + and force feedback must be assumed to be always available. */ +#ifndef XINPUT_CAPS_FFB_SUPPORTED + (void)joyxi; + ALLEGRO_DEBUG("Compiled against older XInput library, assuming force feedback support is available.\n"); + return true; +#else + ALLEGRO_DEBUG("joyxi->capabilities.Flags: %d <-> %d\n", joyxi->capabilities.Flags, XINPUT_CAPS_FFB_SUPPORTED); + return(joyxi->capabilities.Flags & XINPUT_CAPS_FFB_SUPPORTED); +#endif +} + + +static bool hapxi_is_display_haptic(ALLEGRO_DISPLAY *dev) +{ + (void)dev; + return false; +} + + +static bool hapxi_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev) +{ + (void)dev; + return false; +} + + +static bool hapxi_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev) +{ + (void)dev; + return false; +} + + +static ALLEGRO_HAPTIC *hapxi_get_from_mouse(ALLEGRO_MOUSE *mouse) +{ + (void)mouse; + return NULL; +} + + +static ALLEGRO_HAPTIC *hapxi_get_from_joystick(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_XINPUT *joyxi = (ALLEGRO_JOYSTICK_XINPUT *)joy; + ALLEGRO_HAPTIC_XINPUT *hapxi; + + if (!al_is_joystick_haptic(joy)) + return NULL; + + al_lock_mutex(hapxi_mutex); + + hapxi = haptics + joyxi->index; + hapxi->parent.driver = &_al_hapdrv_xinput; + hapxi->parent.device = joyxi; + hapxi->parent.from = _AL_HAPTIC_FROM_JOYSTICK; + hapxi->active = true; + hapxi->effect.state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_INACTIVE; + /* not in use */ + hapxi->parent.gain = 1.0; + hapxi->parent.autocenter = 0.0; + hapxi->flags = ALLEGRO_HAPTIC_RUMBLE; + hapxi->xjoy = joyxi; + al_unlock_mutex(hapxi_mutex); + + return &hapxi->parent; +} + + +static ALLEGRO_HAPTIC *hapxi_get_from_display(ALLEGRO_DISPLAY *dev) +{ + (void)dev; + return NULL; +} + + +static ALLEGRO_HAPTIC *hapxi_get_from_keyboard(ALLEGRO_KEYBOARD *dev) +{ + (void)dev; + return NULL; +} + + +static ALLEGRO_HAPTIC *hapxi_get_from_touch_input(ALLEGRO_TOUCH_INPUT *dev) +{ + (void)dev; + return NULL; +} + + +static int hapxi_get_capabilities(ALLEGRO_HAPTIC *dev) +{ + ALLEGRO_HAPTIC_XINPUT *hapxi = hapxi_from_al(dev); + return hapxi->flags; +} + + +static double hapxi_get_gain(ALLEGRO_HAPTIC *dev) +{ + (void)dev; + /* Just return the 1.0, gain isn't supported */ + return 1.0; +} + + +static bool hapxi_set_gain(ALLEGRO_HAPTIC *dev, double gain) +{ + (void)dev; (void)gain; + /* Gain not supported*/ + return false; +} + + +double hapxi_get_autocenter(ALLEGRO_HAPTIC *dev) +{ + (void)dev; + /* Autocenter not supported so return 0.0. */ + return 0.0; +} + + +static bool hapxi_set_autocenter(ALLEGRO_HAPTIC *dev, double intensity) +{ + (void)dev; (void)intensity; + /* Autocenter not supported*/ + return false; +} + +static int hapxi_get_max_effects(ALLEGRO_HAPTIC *dev) +{ + (void)dev; + /* Support only one effect */ + return 1; +} + + +static bool hapxi_is_effect_ok(ALLEGRO_HAPTIC *haptic, + ALLEGRO_HAPTIC_EFFECT *effect) +{ + int caps; + + caps = al_get_haptic_capabilities(haptic); + if (caps & effect->type) { + return true; + } + return false; +} + +/* Gets an available haptic effect slot from the device or NULL if not + * available. + */ +static ALLEGRO_HAPTIC_EFFECT_XINPUT * +hapxi_get_available_effect(ALLEGRO_HAPTIC_XINPUT *hapxi) +{ + if (hapxi->effect.state == ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_INACTIVE) { + /* Set up ID here. */ + hapxi->effect.id = 0; + return &hapxi->effect; + } + return NULL; +} + +static bool hapxi_release_effect_windows(ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi) +{ + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_INACTIVE; + return true; +} + +static bool hapxi_upload_effect(ALLEGRO_HAPTIC *dev, + ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_XINPUT *hapxi = hapxi_from_al(dev); + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi = NULL; + + ASSERT(dev); + ASSERT(id); + ASSERT(effect); + + /* Set id's values to indicate failure beforehand. */ + id->_haptic = NULL; + id->_id = -1; + id->_pointer = NULL; + id->_playing = false; + id->_effect_duration = 0.0; + id->_start_time = 0.0; + id->_end_time = 0.0; + + if (!al_is_haptic_effect_ok(dev, effect)) + return false; + + al_lock_mutex(hapxi_mutex); + + /* Is a haptic effect slot available? */ + effxi = hapxi_get_available_effect(hapxi); + /* No more space for an effect. */ + if (!effxi) { + ALLEGRO_WARN("No free effect slot."); + al_unlock_mutex(hapxi_mutex); + return false; + } + + if (!hapxi_effect2win(effxi, effect, hapxi)) { + ALLEGRO_WARN("Cannot convert haptic effect to XINPUT effect.\n"); + al_unlock_mutex(hapxi_mutex); + return false; + } + + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_READY; + effxi->effect = (*effect); + /* set ID handle to signify success */ + id->_haptic = dev; + id->_pointer = effxi; + id->_id = effxi->id; + id->_effect_duration = al_get_haptic_effect_duration(effect); + + al_unlock_mutex(hapxi_mutex); + return true; +} + + +static ALLEGRO_HAPTIC_XINPUT * +hapxi_device_for_id(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + return (ALLEGRO_HAPTIC_XINPUT *)id->_haptic; +} + + +static ALLEGRO_HAPTIC_EFFECT_XINPUT * +hapxi_effect_for_id(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + return (ALLEGRO_HAPTIC_EFFECT_XINPUT *)id->_pointer; +} + +static bool hapxi_play_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loops) +{ + ALLEGRO_HAPTIC_XINPUT *hapxi = hapxi_device_for_id(id); + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi = hapxi_effect_for_id(id); + + if ((!hapxi) || (id->_id < 0) || (!effxi) || (loops < 1)) + return false; + al_lock_mutex(hapxi_mutex); + /* Simply set some flags. The polling thread will see this and start playing. + after the effect's delay has passed. */ + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_STARTING; + effxi->start_time = al_get_time(); + effxi->stop_time = effxi->start_time + al_get_haptic_effect_duration(&effxi->effect) * loops; + effxi->repeats = loops; + effxi->play_repeated = 0; + effxi->loop_start = effxi->start_time; + + id->_playing = true; + id->_start_time = al_get_time(); + id->_start_time = effxi->start_time; + id->_end_time = effxi->stop_time; + al_unlock_mutex(hapxi_mutex); + al_signal_cond(hapxi_cond); + return true; +} + + +static bool hapxi_stop_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_XINPUT *hapxi = hapxi_device_for_id(id); + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi = hapxi_effect_for_id(id); + + if ((!hapxi) || (id->_id < 0)) + return false; + /* Simply set some flags. The polling thread will see this and stop playing.*/ + effxi = (ALLEGRO_HAPTIC_EFFECT_XINPUT *)id->_pointer; + if (effxi->state <= ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_READY) return false; + al_lock_mutex(hapxi_mutex); + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_STOPPING; + id->_playing = false; + al_unlock_mutex(hapxi_mutex); + al_signal_cond(hapxi_cond); + return true; +} + + +static bool hapxi_is_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_XINPUT *hapxi; + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi; + bool result; + ASSERT(id); + + hapxi = hapxi_device_for_id(id); + effxi = hapxi_effect_for_id(id); + + if ((!hapxi) || (id->_id < 0) || (!id->_playing)) + return false; + al_lock_mutex(hapxi_mutex); + ALLEGRO_DEBUG("Playing effect state: %d %p %lf %lf\n", effxi->state, effxi, al_get_time(), id->_end_time); + + result = (effxi->state > ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_READY); + al_unlock_mutex(hapxi_mutex); + al_signal_cond(hapxi_cond); + + return result; +} + + +static bool hapxi_release_effect(ALLEGRO_HAPTIC_EFFECT_ID *id) +{ + ALLEGRO_HAPTIC_XINPUT *hapxi = hapxi_device_for_id(id); + ALLEGRO_HAPTIC_EFFECT_XINPUT *effxi = hapxi_effect_for_id(id); + bool result; + if ((!hapxi) || (!effxi)) + return false; + + al_lock_mutex(hapxi_mutex); + /* Forcefully stop since a normal stop may not be instant. */ + hapxi_force_stop(hapxi, effxi); + effxi->state = ALLEGRO_HAPTIC_EFFECT_XINPUT_STATE_INACTIVE; + result = hapxi_release_effect_windows(effxi); + al_unlock_mutex(hapxi_mutex); + return result; +} + + +static bool hapxi_release(ALLEGRO_HAPTIC *haptic) +{ + ALLEGRO_HAPTIC_XINPUT *hapxi = hapxi_from_al(haptic); + ASSERT(haptic); + + if (!hapxi->active) + return false; + al_lock_mutex(hapxi_mutex); + + /* Release the effect for this device. */ + /* Forcefully stop since a normal stop may not be instant. */ + hapxi_force_stop(hapxi, &hapxi->effect); + hapxi_release_effect_windows(&hapxi->effect); + + hapxi->active = false; + hapxi->parent.device = NULL; + al_unlock_mutex(hapxi_mutex); + return true; +} + +#endif + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/wjoyall.c b/allegro/src/win/wjoyall.c new file mode 100644 index 00000000..8475d99f --- /dev/null +++ b/allegro/src/win/wjoyall.c @@ -0,0 +1,230 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows wrap-all joystick driver. + * By Beoran. + * See readme.txt for copyright information. + * + * This driver exists because on Windows, DirectInput and XInput are two + * different joystick input APIs which bith need to be supported simultaneously. + * + * Although DirectInput is deprecated, it is a far more capable API in terms + * of joystick layout and force feedback effects. XInput is a much simpler + * API but it only supports joysticks that have a layout similar to that of an + * XBOX controller. XInput also has very limited force feedback effects, + * it only supportd rubmble style vibrations. + * + * Older joystics or input devices such as steering wheels that do not map + * cleanly to an XBOX controller tend to have DirectInput drivers available, + * while more recent joypads tend to have a XInput driver available. In theory + * XInput devices also support DirectInput, and some devices even have a switch + * that lets the user select the API. But XInput devices only partially support + * DirectInput. In particular, XInput devices do not support force feedback when + * using DirectInput to access them. + * + * For all these reasons, both directinput and xinput drivers should be + * supported on Windows to allow greates comfort to end users. + * The wjoyall.c and whapall.c drivers are wrapper drivers that combine + * the Allegro XInput and DirectInput drivers into a single driver. + * For this reason, the same joystick ormay show up twice + * in the joystick list. However, XInput devices will appear before DirectInput + * devices in the list, so when in doubt, use the joystick with the lowest ID. + * + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +/* For waitable timers */ +#define _WIN32_WINNT 0x0501 + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_bitmap.h" + + +#ifdef ALLEGRO_CFG_XINPUT + +/* Don't compile this lot if xinput isn't supported. */ + +#ifndef ALLEGRO_WINDOWS +#error something is wrong with the makefile +#endif + +#ifdef ALLEGRO_MINGW32 + #undef MAKEFOURCC +#endif + +#include + +ALLEGRO_DEBUG_CHANNEL("wjoyall") + +#include "allegro5/joystick.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_wjoyall.h" + +/* forward declarations */ +static bool joyall_init_joystick(void); +static void joyall_exit_joystick(void); +static bool joyall_reconfigure_joysticks(void); +static int joyall_get_num_joysticks(void); +static ALLEGRO_JOYSTICK *joyall_get_joystick(int num); +static void joyall_release_joystick(ALLEGRO_JOYSTICK *joy); +static void joyall_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state); +static const char *joyall_get_name(ALLEGRO_JOYSTICK *joy); +static bool joyall_get_active(ALLEGRO_JOYSTICK *joy); + + +/* the driver vtable */ +ALLEGRO_JOYSTICK_DRIVER _al_joydrv_windows_all = +{ + AL_JOY_TYPE_WINDOWS_ALL, + "", + "", + "Windows Joystick", + joyall_init_joystick, + joyall_exit_joystick, + joyall_reconfigure_joysticks, + joyall_get_num_joysticks, + joyall_get_joystick, + joyall_release_joystick, + joyall_get_joystick_state, + joyall_get_name, + joyall_get_active +}; + +/* Mutex to protect state access. XXX is this needed? */ +static ALLEGRO_MUTEX *joyall_mutex = NULL; + +static bool ok_xi = false; +static bool ok_di = false; + +/* Sets up all joysticks from the two wrapped apis. */ +static void joyall_setup_joysticks(void) +{ + int index; + int num_xinput = 0; + int num_dinput = 0; + if (ok_di) + num_dinput = _al_joydrv_directx.num_joysticks(); + if (ok_xi) + num_xinput = _al_joydrv_xinput.num_joysticks(); + + for (index = 0; index < num_xinput; index++) { + ALLEGRO_JOYSTICK *joystick = _al_joydrv_xinput.get_joystick(index); + joystick->driver = &_al_joydrv_xinput; + } + + for (index = 0; index < num_dinput; index++) { + ALLEGRO_JOYSTICK *joystick = _al_joydrv_directx.get_joystick(index); + joystick->driver = &_al_joydrv_directx; + } +} + + +/* Initialization API function. */ +static bool joyall_init_joystick(void) +{ + /* Create the mutex and a condition vaiable. */ + joyall_mutex = al_create_mutex_recursive(); + if (!joyall_mutex) + return false; + + al_lock_mutex(joyall_mutex); + + ok_xi = _al_joydrv_xinput.init_joystick(); + ok_di = _al_joydrv_directx.init_joystick(); + joyall_setup_joysticks(); + al_unlock_mutex(joyall_mutex); + return ok_xi || ok_di; +} + + +static void joyall_exit_joystick(void) +{ + al_lock_mutex(joyall_mutex); + _al_joydrv_xinput.exit_joystick(); + _al_joydrv_directx.exit_joystick(); + al_unlock_mutex(joyall_mutex); + al_destroy_mutex(joyall_mutex); +} + +static bool joyall_reconfigure_joysticks(void) +{ + al_lock_mutex(joyall_mutex); + if (ok_xi) + _al_joydrv_xinput.reconfigure_joysticks(); + if (ok_di) + _al_joydrv_directx.reconfigure_joysticks(); + joyall_setup_joysticks(); + al_unlock_mutex(joyall_mutex); + return true; +} + +static int joyall_get_num_joysticks(void) +{ + int ret = 0; + if (ok_xi) + ret += _al_joydrv_xinput.num_joysticks(); + if (ok_di) + ret += _al_joydrv_directx.num_joysticks(); + return ret; +} + +static ALLEGRO_JOYSTICK *joyall_get_joystick(int num) +{ + int num_xinput = 0; + int num_dinput = 0; + if (ok_di) + num_dinput = _al_joydrv_directx.num_joysticks(); + if (ok_xi) + num_xinput = _al_joydrv_xinput.num_joysticks(); + if (num < 0) return NULL; + /* Shift the joystick number to fit the range of each of the subdrivers */ + if (num < num_xinput) { + return _al_joydrv_xinput.get_joystick(num); + } + else if (num < (num_xinput + num_dinput)) { + return _al_joydrv_directx.get_joystick(num - num_xinput); + } + return NULL; +} + +static void joyall_release_joystick(ALLEGRO_JOYSTICK *joy) +{ + /* Forward to the driver's function. Here it's OK to use joy + * since the get_joystick function returns a + * pointer to the real underlying driver-specific joystick data. + */ + if (joy) { + joy->driver->release_joystick(joy); + } +} + +static void joyall_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + joy->driver->get_joystick_state(joy, ret_state); +} + +static const char *joyall_get_name(ALLEGRO_JOYSTICK *joy) +{ + return joy->driver->get_name(joy); +} + +static bool joyall_get_active(ALLEGRO_JOYSTICK *joy) +{ + return joy->driver->get_active(joy); +} + + +#endif /* #ifdef ALLEGRO_CFG_XINPUT */ diff --git a/allegro/src/win/wjoydrv.c b/allegro/src/win/wjoydrv.c new file mode 100644 index 00000000..8db36f3c --- /dev/null +++ b/allegro/src/win/wjoydrv.c @@ -0,0 +1,36 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * List of Windows joystick drivers, kept in a seperate file so that + * they can be overriden by user programs. + * + * By Shawn Hargreaves. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_joystick.h" + +#ifndef ALLEGRO_WINDOWS +#error something is wrong with the makefile +#endif + + + +_AL_BEGIN_JOYSTICK_DRIVER_LIST +_AL_JOYSTICK_DRIVER_DIRECTX +#ifdef ALLEGRO_CFG_XINPUT +_AL_JOYSTICK_DRIVER_XINPUT +_AL_JOYSTICK_DRIVER_WINDOWS_ALL +#endif +_AL_END_JOYSTICK_DRIVER_LIST diff --git a/allegro/src/win/wjoydxnu.cpp b/allegro/src/win/wjoydxnu.cpp new file mode 100644 index 00000000..c13c050a --- /dev/null +++ b/allegro/src/win/wjoydxnu.cpp @@ -0,0 +1,1680 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows DirectInput joystick driver. + * + * By Eric Botcazou. + * + * Omar Cornut fixed it to handle a weird peculiarity of + * the DirectInput joystick API. + * + * Modified extensively for the new joystick API by Peter Wang. + * + * See readme.txt for copyright information. + */ + + +/* + * Driver operation: + * + * 1. When the driver is initialised all the joysticks on the system + * are enumerated. For each joystick, an ALLEGRO_JOYSTICK_DIRECTX structure + * is created. A win32 Event is also created for each joystick and DirectInput + * is told to set that event whenever the joystick state changes. For some + * devices this is not possible -- they must be polled. In that case, a + * Waitable Timer object is used instead of a win32 Event. Once all the + * joysticks are set up, a dedicated background thread is started. + * + * 2. When al_get_joystick() is called the address of one of the + * ALLEGRO_JOYSTICK_DIRECTX structures is returned to the user. + * + * 3. The background thread waits upon the win32 Events/Waitable Timer + * objects. When one of them is triggered, the thread wakes up and + * reads in buffered joystick events. An internal ALLEGRO_JOYSTICK_STATE + * structure (part of ALLEGRO_JOYSTICK_DIRECTX) is updated accordingly. + * Also, any Allegro events are generated if necessary. + * + * 4. When the user calls al_get_joystick_state() the contents of the + * internal ALLEGRO_JOYSTICK_STATE structure are copied to a user + * ALLEGRO_JOYSTICK_STATE structure. + * + * 5. Every second or so, all the joysticks on the system are enumerated again. + * We compare the GUIDs of the enumerated joysticks with the existing + * ALLEGRO_JOYSTICK structures to tell if any new joysticks have been connected, + * or old ones disconnected. + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#define DIRECTINPUT_VERSION 0x0800 + +/* For waitable timers */ +#define _WIN32_WINNT 0x0501 + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_bitmap.h" + + +#ifndef ALLEGRO_WINDOWS +#error something is wrong with the makefile +#endif + +#ifdef ALLEGRO_MINGW32 + #undef MAKEFOURCC +#endif + +#include +#include +#include +#include + +/* We need XInput detection if we actually compile the XInput driver in. +*/ +#ifdef ALLEGRO_CFG_XINPUT + /* Windows XP is required. If you still use older Windows, + XInput won't work anyway. */ + #undef WIN32_LEAN_AND_MEAN + #include + #include + #define ALLEGRO_DINPUT_FILTER_XINPUT +#endif + +ALLEGRO_DEBUG_CHANNEL("dinput") + +#include "allegro5/joystick.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_wjoydxnu.h" +#include "allegro5/internal/aintern_wunicode.h" + + + +/* forward declarations */ +static bool joydx_init_joystick(void); +static void joydx_exit_joystick(void); +static bool joydx_reconfigure_joysticks(void); +static int joydx_get_num_joysticks(void); +static ALLEGRO_JOYSTICK *joydx_get_joystick(int num); +static void joydx_release_joystick(ALLEGRO_JOYSTICK *joy); +static void joydx_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state); +static const char *joydx_get_name(ALLEGRO_JOYSTICK *joy); +static bool joydx_get_active(ALLEGRO_JOYSTICK *joy); + +static void joydx_inactivate_joy(ALLEGRO_JOYSTICK_DIRECTX *joy); + +static unsigned __stdcall joydx_thread_proc(LPVOID unused); +static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy); +static void handle_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, const AXIS_MAPPING *axis_mapping, DWORD value); +static void handle_pov_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, DWORD value); +static void handle_button_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int button, bool down); +static void generate_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, int axis, float pos); +static void generate_button_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int button, ALLEGRO_EVENT_TYPE event_type); + + + +/* the driver vtable */ +ALLEGRO_JOYSTICK_DRIVER _al_joydrv_directx = +{ + AL_JOY_TYPE_DIRECTX, + "", + "", + "DirectInput joystick", + joydx_init_joystick, + joydx_exit_joystick, + joydx_reconfigure_joysticks, + joydx_get_num_joysticks, + joydx_get_joystick, + joydx_release_joystick, + joydx_get_joystick_state, + joydx_get_name, + joydx_get_active +}; + + +/* GUID values are borrowed from Wine */ +#define DEFINE_PRIVATE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + static const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + +DEFINE_PRIVATE_GUID(__al_GUID_XAxis, 0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_PRIVATE_GUID(__al_GUID_YAxis, 0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_PRIVATE_GUID(__al_GUID_ZAxis, 0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_PRIVATE_GUID(__al_GUID_RxAxis,0xA36D02F4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_PRIVATE_GUID(__al_GUID_RyAxis,0xA36D02F5,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_PRIVATE_GUID(__al_GUID_RzAxis,0xA36D02E3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_PRIVATE_GUID(__al_GUID_Slider,0xA36D02E4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_PRIVATE_GUID(__al_GUID_Button,0xA36D02F0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_PRIVATE_GUID(__al_GUID_POV, 0xA36D02F2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + +DEFINE_PRIVATE_GUID(__al_IID_IDirectInput8W, 0xBF798031,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00); +DEFINE_PRIVATE_GUID(__al_IID_IDirectInput8A, 0xBF798030,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00); +DEFINE_PRIVATE_GUID(__al_IID_IDirectInputDevice8A,0x54D41080,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79); +DEFINE_PRIVATE_GUID(__al_IID_IDirectInputDevice8W,0x54D41081,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79); + +#ifdef UNICODE +#define __al_IID_IDirectInput8 __al_IID_IDirectInput8W +#define __al_IID_IDirectInputDevice8 __al_IID_IDirectInputDevice8W +#else +#define __al_IID_IDirectInput __al_IID_IDirectInput8A +#define __al_IID_IDirectInputDevice __al_IID_IDirectInputDevice8A +#endif + +/* definition of DirectInput Joystick was borrowed from Wine implementation */ +#define DIDFT_AXIS 0x00000003 +#define DIDFT_ANYINSTANCE 0x00FFFF00 +#define DIDFT_OPTIONAL 0x80000000 + +static const DIOBJECTDATAFORMAT __al_dfDIJoystick[] = { + { &__al_GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, + { &__al_GUID_POV, DIJOFS_POV(3), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(0), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(1), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(2), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(3), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(4), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(5), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(6), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(7), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(8), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(9), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(10), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(11), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(12), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(13), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(14), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(15), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(16), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(17), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(18), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(19), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(20), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(21), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(22), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(23), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(24), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(25), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(26), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(27), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(28), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(29), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(30), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, + { NULL, DIJOFS_BUTTON(31), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0}, +}; + +static const DIDATAFORMAT __al_c_dfDIJoystick = { + sizeof(DIDATAFORMAT), + sizeof(DIOBJECTDATAFORMAT), + DIDF_ABSAXIS, + sizeof(DIJOYSTATE), + sizeof(__al_dfDIJoystick) / sizeof(*__al_dfDIJoystick), + (LPDIOBJECTDATAFORMAT)__al_dfDIJoystick +}; +/* end of Wine code */ + + +/* DirectInput creation prototype */ +typedef HRESULT (WINAPI *DIRECTINPUT8CREATEPROC)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID * ppvOut, LPUNKNOWN punkOuter); + +/* DirectInput module name */ +static const char* _al_dinput_module_name = "dinput8.dll"; + +/* DirecInput module handle */ +static HMODULE _al_dinput_module = NULL; + +/* DirectInput creation procedure */ +static DIRECTINPUT8CREATEPROC _al_dinput_create = (DIRECTINPUT8CREATEPROC)NULL; + +/* a handle to the DirectInput interface */ +static LPDIRECTINPUT joystick_dinput = NULL; + +/* last display which acquired the devices */ +static ALLEGRO_DISPLAY_WIN *win_disp; + +/* number of joysticks visible to user */ +static int joydx_num_joysticks; + +/* the joystick structures */ +static ALLEGRO_JOYSTICK_DIRECTX joydx_joystick[MAX_JOYSTICKS]; + +/* for the background thread */ +static HANDLE joydx_thread = NULL; +static CRITICAL_SECTION joydx_thread_cs; + +/* whether the DirectInput devices need to be enumerated again */ +static bool need_device_enumeration = false; + +/* whether the user should call al_reconfigure_joysticks */ +static bool config_needs_merging = false; + +/* An array of objects that are to wake the background thread when + * something interesting happens. The first handle is for thread + * termination. The rest point to joydx_joystick[i].waker_event values, + * for each active joystick. joydx_joystick[i].waker_event is NOT + * necessarily at JOYSTICK_WAKER(i). + */ +static HANDLE joydx_thread_wakers[1+MAX_JOYSTICKS]; +#define STOP_EVENT (joydx_thread_wakers[0]) +#define JOYSTICK_WAKER(n) (joydx_thread_wakers[1+(n)]) + + +/* names for things in case DirectInput doesn't provide them */ +static char default_name_x[] = "X"; +static char default_name_y[] = "Y"; +static char default_name_z[] = "Z"; +static char default_name_rx[] = "RX"; +static char default_name_ry[] = "RY"; +static char default_name_rz[] = "RZ"; +static char default_name_stick[] = "stick"; +static char default_name_slider[] = "slider"; +static char default_name_hat[] = "hat"; +static const char *default_name_button[MAX_BUTTONS] = { + "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", + "B9", "B10", "B11", "B12", "B13", "B14", "B15", "B16", + "B17", "B18", "B19", "B20", "B21", "B22", "B23", "B24", + "B25", "B26", "B27", "B28", "B29", "B30", "B31", "B32" +}; + + +#define JOY_POVFORWARD_WRAP 36000 + + +/* Returns a pointer to a static buffer, for debugging. */ +static char *guid_to_string(const GUID * guid) +{ + static char buf[200]; + + sprintf(buf, "%lx-%x-%x-%x%x%x%x%x%x%x%x", + guid->Data1, + guid->Data2, + guid->Data3, + guid->Data4[0], + guid->Data4[1], + guid->Data4[2], + guid->Data4[3], + guid->Data4[4], + guid->Data4[5], + guid->Data4[6], + guid->Data4[7] + ); + + return buf; +} + + +/* Returns a pointer to a static buffer, for debugging. */ +static char *joydx_guid_string(ALLEGRO_JOYSTICK_DIRECTX *joy) +{ + return guid_to_string((const GUID *)&joy->guid); +} + + +/* dinput_err_str: + * Returns a DirectInput error string. + */ +#ifdef DEBUGMODE +static char* dinput_err_str(long err) +{ + static char err_str[64]; + + switch (err) { + + case DIERR_ACQUIRED: + _al_sane_strncpy(err_str, "the device is acquired", sizeof(err_str)); + break; + + case DIERR_NOTACQUIRED: + _al_sane_strncpy(err_str, "the device is not acquired", sizeof(err_str)); + break; + + case DIERR_INPUTLOST: + _al_sane_strncpy(err_str, "access to the device was not granted", sizeof(err_str)); + break; + + case DIERR_INVALIDPARAM: + _al_sane_strncpy(err_str, "the device does not have a selected data format", sizeof(err_str)); + break; + + case DIERR_OTHERAPPHASPRIO: + _al_sane_strncpy(err_str, "can't acquire the device in background", sizeof(err_str)); + break; + + default: + _al_sane_strncpy(err_str, "unknown error", sizeof(err_str)); + } + + return err_str; +} +#else +#define dinput_err_str(hr) "\0" +#endif + + +/* _al_win_joystick_dinput_acquire: [window thread] + * Acquires the joystick devices. + */ +static void joystick_dinput_acquire(void) +{ + HRESULT hr; + int i; + + if (!joystick_dinput) + return; + + for (i=0; i < MAX_JOYSTICKS; i++) { + if (joydx_joystick[i].device) { + hr = IDirectInputDevice8_Acquire(joydx_joystick[i].device); + + if (FAILED(hr)) + ALLEGRO_ERROR("acquire joystick %d failed: %s\n", i, dinput_err_str(hr)); + } + } +} + + +/* _al_win_joystick_dinput_trigger_enumeration: [window thread] + * Let joydx_thread_proc() know to reenumerate joysticks. + */ +void _al_win_joystick_dinput_trigger_enumeration(void) +{ + if (!joystick_dinput) + return; + EnterCriticalSection(&joydx_thread_cs); + need_device_enumeration = true; + LeaveCriticalSection(&joydx_thread_cs); +} + +/* _al_win_joystick_dinput_unacquire: [window thread] + * Unacquires the joystick devices. + */ +void _al_win_joystick_dinput_unacquire(void *unused) +{ + int i; + + (void)unused; + + if (joystick_dinput && win_disp) { + for (i=0; i < MAX_JOYSTICKS; i++) { + if (joydx_joystick[i].device) { + ALLEGRO_DEBUG("Unacquiring joystick device at slot %d\n", i); + IDirectInputDevice8_Unacquire(joydx_joystick[i].device); + } + } + } +} + + +/* _al_win_joystick_dinput_grab: [window thread] + * Grabs the joystick devices. + */ +void _al_win_joystick_dinput_grab(void *param) +{ + int i; + + if (!joystick_dinput) + return; + + /* Release the input from the previous window just in case, + otherwise set cooperative level will fail. */ + if (win_disp) { + _al_win_wnd_call_proc(win_disp->window, _al_win_joystick_dinput_unacquire, NULL); + } + + win_disp = (ALLEGRO_DISPLAY_WIN *)param; + + /* set cooperative level */ + for (i = 0; i < MAX_JOYSTICKS; i++) { + HRESULT hr; + + if (!joydx_joystick[i].device) + continue; + + hr = IDirectInputDevice8_SetCooperativeLevel(joydx_joystick[i].device, win_disp->window, + DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); + if (FAILED(hr)) { + ALLEGRO_ERROR("IDirectInputDevice8_SetCooperativeLevel failed.\n"); + return; + } + } + + joystick_dinput_acquire(); +} + + +static ALLEGRO_JOYSTICK_DIRECTX *joydx_by_guid(const GUID guid, + const GUID product_guid) +{ + unsigned i; + + for (i = 0; i < MAX_JOYSTICKS; i++) { + if ( + GUID_EQUAL(joydx_joystick[i].guid, guid) && + GUID_EQUAL(joydx_joystick[i].product_guid, product_guid) + /* && + joydx_joystick[i].config_state == STATE_ALIVE */ + ) + return &joydx_joystick[i]; + } + + return NULL; +} + + +static ALLEGRO_JOYSTICK_DIRECTX *joydx_allocate_structure(int *num) +{ + int i; + + for (i = 0; i < MAX_JOYSTICKS; i++) { + if (joydx_joystick[i].config_state == STATE_UNUSED) { + *num = i; + return &joydx_joystick[i]; + } + } + + *num = -1; + return NULL; +} + + +/* object_enum_callback: [primary thread] + * Helper function to find out what objects we have on the device. + */ +static BOOL CALLBACK object_enum_callback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) +{ +#define GUIDTYPE_EQ(x) GUID_EQUAL(lpddoi->guidType, x) + + CAPS_AND_NAMES *can = (CAPS_AND_NAMES *)pvRef; + + if (GUIDTYPE_EQ(__al_GUID_XAxis)) { + can->have_x = true; + _tcsncpy(can->name_x, lpddoi->tszName, NAME_LEN); + } + else if (GUIDTYPE_EQ(__al_GUID_YAxis)) { + can->have_y = true; + _tcsncpy(can->name_y, lpddoi->tszName, NAME_LEN); + } + else if (GUIDTYPE_EQ(__al_GUID_ZAxis)) { + can->have_z = true; + _tcsncpy(can->name_z, lpddoi->tszName, NAME_LEN); + } + else if (GUIDTYPE_EQ(__al_GUID_RxAxis)) { + can->have_rx = true; + _tcsncpy(can->name_rx, lpddoi->tszName, NAME_LEN); + } + else if (GUIDTYPE_EQ(__al_GUID_RyAxis)) { + can->have_ry = true; + _tcsncpy(can->name_ry, lpddoi->tszName, NAME_LEN); + } + else if (GUIDTYPE_EQ(__al_GUID_RzAxis)) { + can->have_rz = true; + _tcsncpy(can->name_rz, lpddoi->tszName, NAME_LEN); + } + else if (GUIDTYPE_EQ(__al_GUID_Slider)) { + if (can->num_sliders < MAX_SLIDERS) { + _tcsncpy(can->name_slider[can->num_sliders], lpddoi->tszName, + NAME_LEN); + can->num_sliders++; + } + } + else if (GUIDTYPE_EQ(__al_GUID_POV)) { + if (can->num_povs < MAX_POVS) { + _tcsncpy(can->name_pov[can->num_povs], lpddoi->tszName, + NAME_LEN); + can->num_povs++; + } + } + else if (GUIDTYPE_EQ(__al_GUID_Button)) { + if (can->num_buttons < MAX_BUTTONS) { + _tcsncpy(can->name_button[can->num_buttons], lpddoi->tszName, + NAME_LEN); + can->num_buttons++; + } + } + + return DIENUM_CONTINUE; + +#undef GUIDTYPE_EQ +} + + +static char *add_string(char *buf, const TCHAR *src, int *pos, int bufsize, const char* dfl) +{ + char *dest; + + dest = buf + *pos; + if (*pos >= bufsize - 1) { + /* Out of space. */ + ALLEGRO_ASSERT(dest[0] == '\0'); + return dest; + } + + if (*pos > 0) { + /* Skip over NUL separator. */ + dest++; + (*pos)++; + } + if (src) { + dest = _twin_copy_tchar_to_utf8(dest, src, bufsize - *pos); + } else { + dest = _al_sane_strncpy(dest, dfl, bufsize - *pos); + } + ALLEGRO_ASSERT(dest != 0); + if (dest) { + (*pos) += strlen(dest); + ALLEGRO_ASSERT(*pos < bufsize); + } + return dest; +} + + +/* fill_joystick_info_using_caps_and_names: [primary thread] + * Helper to fill in the contents of the joystick structure using the + * information painstakingly stored into the caps_and_names substructure. + */ +static void fill_joystick_info_using_caps_and_names(ALLEGRO_JOYSTICK_DIRECTX *joy, + const CAPS_AND_NAMES *can) +{ + _AL_JOYSTICK_INFO *info = &joy->parent.info; + int pos = 0; + int i; + +#define N_STICK (info->num_sticks) +#define N_AXIS (info->stick[N_STICK].num_axes) +#define ADD_STRING(A, dfl) \ + (add_string(joy->all_names, (A), &pos, \ + sizeof(joy->all_names), (dfl))) + + /* the X, Y, Z axes make up the first stick */ + if (can->have_x || can->have_y || can->have_z) { + if (can->have_x) { + info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; + info->stick[N_STICK].axis[N_AXIS].name = ADD_STRING(can->name_x, default_name_x); + joy->x_mapping.stick = N_STICK; + joy->x_mapping.axis = N_AXIS; + N_AXIS++; + } + + if (can->have_y) { + info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; + info->stick[N_STICK].axis[N_AXIS].name = ADD_STRING(can->name_y, default_name_y); + joy->y_mapping.stick = N_STICK; + joy->y_mapping.axis = N_AXIS; + N_AXIS++; + } + + if (can->have_z) { + info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; + info->stick[N_STICK].axis[N_AXIS].name = ADD_STRING(can->name_z, default_name_z); + joy->z_mapping.stick = N_STICK; + joy->z_mapping.axis = N_AXIS; + N_AXIS++; + } + + info->stick[N_STICK].name = ADD_STRING(NULL, default_name_stick); + N_STICK++; + } + + /* the Rx, Ry, Rz axes make up the next stick */ + if (can->have_rx || can->have_ry || can->have_rz) { + if (can->have_rx) { + info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; + info->stick[N_STICK].axis[N_AXIS].name = ADD_STRING(can->name_rx, default_name_rx); + joy->rx_mapping.stick = N_STICK; + joy->rx_mapping.axis = N_AXIS; + N_AXIS++; + } + + if (can->have_ry) { + info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; + info->stick[N_STICK].axis[N_AXIS].name = ADD_STRING(can->name_ry, default_name_ry); + joy->ry_mapping.stick = N_STICK; + joy->ry_mapping.axis = N_AXIS; + N_AXIS++; + } + + if (can->have_rz) { + info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; + info->stick[N_STICK].axis[N_AXIS].name = ADD_STRING(can->name_rz, default_name_rz); + joy->rz_mapping.stick = N_STICK; + joy->rz_mapping.axis = N_AXIS; + N_AXIS++; + } + + info->stick[N_STICK].name = ADD_STRING(NULL, default_name_stick); + N_STICK++; + } + + /* sliders are assigned to one stick each */ + for (i = 0; i < can->num_sliders; i++) { + info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL | ALLEGRO_JOYFLAG_ANALOGUE; + info->stick[N_STICK].num_axes = 1; + info->stick[N_STICK].axis[0].name = ADD_STRING(NULL, "axis"); + info->stick[N_STICK].name = ADD_STRING(can->name_slider[i], default_name_slider); + joy->slider_mapping[i].stick = N_STICK; + joy->slider_mapping[i].axis = 0; + N_STICK++; + } + + /* POV devices are assigned to one stick each */ + for (i = 0; i < can->num_povs; i++) { + info->stick[N_STICK].flags = ALLEGRO_JOYFLAG_DIGITAL; + info->stick[N_STICK].num_axes = 2; + info->stick[N_STICK].axis[0].name = ADD_STRING(NULL, "left/right"); + info->stick[N_STICK].axis[1].name = ADD_STRING(NULL, "up/down"); + info->stick[N_STICK].name = ADD_STRING(can->name_pov[i], default_name_hat); + joy->pov_mapping_stick[i] = N_STICK; + N_STICK++; + } + + /* buttons */ + for (i = 0; i < can->num_buttons; i++) { + info->button[i].name = ADD_STRING(can->name_button[i], default_name_button[i]); + } + + info->num_buttons = can->num_buttons; + + /* correct buggy MP-8866 Dual USB Joypad info received from DirectInput */ + if (strstr(joy->name, "MP-8866")) { + /* axes were mapped weird; remap as expected */ + /* really R-stick X axis */ + joy->z_mapping.stick = 1; + joy->z_mapping.axis = 0; + + /* really R-stick Y axis */ + joy->rz_mapping.stick = 1; + joy->rz_mapping.axis = 1; + + info->stick[0].num_axes = 2; + info->stick[1].num_axes = 2; + + /* reuse the axis names from the first stick */ + info->stick[2].axis[0].name = info->stick[1].axis[0].name = info->stick[0].axis[0].name; + info->stick[2].axis[1].name = info->stick[1].axis[1].name = info->stick[0].axis[1].name; + + /* first four button names contained junk; replace with valid strings */ + info->button[ 0].name = ADD_STRING(NULL, "Triangle"); + info->button[ 1].name = ADD_STRING(NULL, "Circle"); + info->button[ 2].name = ADD_STRING(NULL, "X"); + info->button[ 3].name = ADD_STRING(NULL, "Square"); + + /* while we're at it, give these controls more sensible names, too */ + info->stick[0].name = ADD_STRING(NULL, "[L-stick] or D-pad"); + info->stick[1].name = ADD_STRING(NULL, "[R-stick]"); + info->stick[2].name = ADD_STRING(NULL, "[D-pad]"); + } + +#undef N_AXIS +#undef N_STICK +#undef ADD_STRING +} + + +#ifdef ALLEGRO_DINPUT_FILTER_XINPUT + +/* A better Xinput detection method inspired by from SDL. +* The method proposed by Microsoft on their web site is problematic because it +* requires non standard compiler extensions and hard to get headers. +* This method only needs Windows XP and user32.dll. +*/ +static bool dinput_is_device_xinput(const GUID *guid) +{ + PRAWINPUTDEVICELIST device_list = NULL; + UINT amount = 0; + UINT i; + bool result = false; + bool found = false; + + /* Go through RAWINPUT (WinXP and later) to find HID devices. */ + if ((GetRawInputDeviceList(NULL, &amount, sizeof (RAWINPUTDEVICELIST)) + != 0)) { + ALLEGRO_ERROR("Could not get amount of raw input devices.\n"); + return false; /* drat... */ + } + + if (amount < 1) { + ALLEGRO_ERROR("Could not get any of raw input devices.\n"); + return false; /* drat again... */ + } + + device_list = (PRAWINPUTDEVICELIST) + al_malloc(sizeof(RAWINPUTDEVICELIST) * amount); + + if (!device_list) { + ALLEGRO_ERROR("Could allocate memory for raw input devices.\n"); + return false; /* No luck. */ + } + + if (GetRawInputDeviceList(device_list, &amount, sizeof(RAWINPUTDEVICELIST)) + == ((UINT)-1)) { + ALLEGRO_ERROR("Could not retrieve %d raw input devices.\n", amount); + al_free((void *)device_list); + return false; + } + + for (i = 0; i < amount; i++) { + PRAWINPUTDEVICELIST device = device_list + i; + RID_DEVICE_INFO rdi; + char device_name[128]; + UINT rdi_size = sizeof (rdi); + UINT name_size = 127; + rdi.cbSize = sizeof (rdi); + + /* Get device info. */ + if (GetRawInputDeviceInfoA(device->hDevice, RIDI_DEVICEINFO, + &rdi, &rdi_size) == ((UINT)-1)) { + ALLEGRO_ERROR("Could not get raw device info for list index %d.\n", i); + continue; + } + /* See if vendor and product id match. */ + if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) + != ((LONG)guid->Data1)) + continue; + found = true; + /* Get device name */ + memset(device_name, 0, 128); + if(GetRawInputDeviceInfoA(device->hDevice, RIDI_DEVICENAME, + device_name, &name_size) == ((UINT)-1)) { + ALLEGRO_ERROR("Could not get raw device name for list index %d.\n", i); + continue; + } + /* See if there is IG_ in the name, if it is , it's an XInput device. */ + ALLEGRO_DEBUG("Checking for XInput : %s\n", device_name); + if (strstr(device_name, "IG_") != NULL) { + ALLEGRO_DEBUG("Device %s is an XInput device.\n", device_name); + result = true; + break; + } + } + if (!found) { + ALLEGRO_ERROR("Could not find device %s in the raw device list.\n", + guid_to_string(guid)); + result = true; + /* Ignore "mystery" devices. Testing shows that on MinGW these are never + valid DirectInput devices. Real ones should show up in + the raw device list. */ + } + al_free((void *)device_list); + return result; +} + +#endif + +/* joystick_enum_callback: [primary thread] + * Helper function to find out how many joysticks we have and set them up. + * At the end joydx_num_joysticks and joydx_joystick[] will be initialised. + */ +static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) +{ + DIPROPRANGE property_range = + { + /* the header */ + { + sizeof(DIPROPRANGE), // diph.dwSize + sizeof(DIPROPHEADER), // diph.dwHeaderSize + 0, // diph.dwObj + DIPH_DEVICE, // diph.dwHow + }, + + /* the data */ + -32767, // lMin + +32767 // lMax + }; + + DIPROPDWORD property_deadzone = + { + /* the header */ + { + sizeof(DIPROPDWORD), // diph.dwSize + sizeof(DIPROPHEADER), // diph.dwHeaderSize + 0, // diph.dwObj + DIPH_DEVICE, // diph.dwHow + }, + + /* the data */ + 2000, // dwData + }; + + DIPROPDWORD property_buffersize = + { + /* the header */ + { + sizeof(DIPROPDWORD), // diph.dwSize + sizeof(DIPROPHEADER), // diph.dwHeaderSize + 0, // diph.dwObj + DIPH_DEVICE, // diph.dwHow + }, + + /* the data */ + DEVICE_BUFFER_SIZE // number of data items + }; + + LPDIRECTINPUTDEVICE _dinput_device1; + LPDIRECTINPUTDEVICE2 dinput_device = NULL; + HRESULT hr; + LPVOID temp; + CAPS_AND_NAMES caps_and_names; + ALLEGRO_JOYSTICK_DIRECTX *joy = NULL; + int num; + + (void)pvRef; + + + + /* check if the joystick already existed before + * Aslo have to check the product GUID because devices like the Logitech + * F710 have a backside switch that will change the product GUID, + * but not the instance guid. + */ + joy = joydx_by_guid(lpddi->guidInstance, lpddi->guidProduct); + if (joy) { + ALLEGRO_DEBUG("Device %s still exists\n", joydx_guid_string(joy)); + joy->marked = true; + return DIENUM_CONTINUE; + } + + /* If we are compiling the XInput driver, ignore XInput devices, those can + go though the XInput driver, unless if the DirectInput driver + was set explicitly in the configuration. */ + #ifdef ALLEGRO_DINPUT_FILTER_XINPUT + if (dinput_is_device_xinput(&lpddi->guidProduct)) { + ALLEGRO_DEBUG("Filtered out XInput device %s\n", guid_to_string(&lpddi->guidInstance)); + goto Error; + } + #endif + + /* create the DirectInput joystick device */ + hr = IDirectInput8_CreateDevice(joystick_dinput, lpddi->guidInstance, &_dinput_device1, NULL); + if (FAILED(hr)) + goto Error; + + /* query the DirectInputDevice2 interface needed for the poll() method */ + hr = IDirectInputDevice8_QueryInterface(_dinput_device1, __al_IID_IDirectInputDevice8, &temp); + IDirectInputDevice8_Release(_dinput_device1); + if (FAILED(hr)) + goto Error; + + dinput_device = (LPDIRECTINPUTDEVICE2)temp; + + /* enumerate objects available on the device */ + memset(&caps_and_names, 0, sizeof(caps_and_names)); + hr = IDirectInputDevice8_EnumObjects(dinput_device, object_enum_callback, + &caps_and_names, DIDFT_PSHBUTTON | DIDFT_AXIS | DIDFT_POV); + if (FAILED(hr)) + goto Error; + + /* set data format */ + hr = IDirectInputDevice8_SetDataFormat(dinput_device, &__al_c_dfDIJoystick); + if (FAILED(hr)) + goto Error; + + /* set the range of axes */ + hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_RANGE, &property_range.diph); + if (FAILED(hr)) + goto Error; + + /* set the dead zone of axes */ + hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_DEADZONE, &property_deadzone.diph); + if (FAILED(hr)) + goto Error; + + /* set the buffer size */ + hr = IDirectInputDevice8_SetProperty(dinput_device, DIPROP_BUFFERSIZE, &property_buffersize.diph); + if (FAILED(hr)) + goto Error; + + /* set up the joystick structure */ + joy = joydx_allocate_structure(&num); + if (!joy) { + ALLEGRO_ERROR("Joystick array full\n"); + goto Error; + } + + joy->config_state = STATE_BORN; + joy->marked = true; + joy->device = dinput_device; + memcpy(&joy->guid, &lpddi->guidInstance, sizeof(GUID)); + memcpy(&joy->product_guid, &lpddi->guidProduct, sizeof(GUID)); + + _twin_copy_tchar_to_utf8(joy->name, lpddi->tszInstanceName, sizeof(joy->name)); + + /* fill in the joystick structure */ + fill_joystick_info_using_caps_and_names(joy, &caps_and_names); + + /* create a thread event for this joystick, unless it was already created */ + joy->waker_event = CreateEvent(NULL, false, false, NULL); + + /* tell the joystick background thread to wake up when this joystick + * device's state changes + */ + hr = IDirectInputDevice8_SetEventNotification(joy->device, joy->waker_event); + + if (FAILED(hr)) { + ALLEGRO_ERROR("SetEventNotification failed for joystick %d: %s\n", + num, dinput_err_str(hr)); + goto Error; + } + + if (hr == DI_POLLEDDEVICE) { + /* This joystick device must be polled -- replace the Event with + * a Waitable Timer object. + * + * Theoretically all polled devices could share a single + * waitable timer object. But, really, how many such devices + * are there going to be on a system? + */ + + CloseHandle(joy->waker_event); + + joy->waker_event = CreateWaitableTimer(NULL, false, NULL); + if (joy->waker_event == NULL) { + ALLEGRO_ERROR("CreateWaitableTimer failed for polled device.\n"); + goto Error; + } + + { + LARGE_INTEGER due_time = { 0 }; + due_time.QuadPart = -1; /* Start ASAP... */ + SetWaitableTimer(joy->waker_event, + &due_time, 15, /* ... then periodic, every 15ms*/ + NULL, NULL, false); + } + } + + ALLEGRO_INFO("Joystick %d initialized, GUID: %s\n", + num, joydx_guid_string(joy)); + + config_needs_merging = true; + + return DIENUM_CONTINUE; + + Error: + + if (dinput_device) + IDirectInputDevice8_Release(dinput_device); + + if (joy) { + joy->device = NULL; + joydx_inactivate_joy(joy); + } + + return DIENUM_CONTINUE; +} + + +static void joydx_inactivate_joy(ALLEGRO_JOYSTICK_DIRECTX *joy) +{ + if (joy->config_state == STATE_UNUSED) + return; + joy->config_state = STATE_UNUSED; + joy->marked = false; + + if (joy->device) { + IDirectInputDevice8_SetEventNotification(joy->device, NULL); + IDirectInputDevice8_Release(joy->device); + joy->device = NULL; + } + + memset(&joy->guid, 0, sizeof(GUID)); + + if (joy->waker_event) { + CloseHandle(joy->waker_event); + joy->waker_event = NULL; + } + + memset(&joy->parent.info, 0, sizeof(joy->parent.info)); + /* XXX the joystick name really belongs in joy->parent.info too */ + joy->name[0] = '\0'; + memset(&joy->joystate, 0, sizeof(joy->joystate)); + /* Don't forget to wipe the guids as well! */ + memset(&joy->guid, 0, sizeof(joy->guid)); + memset(&joy->product_guid, 0, sizeof(joy->product_guid)); + +} + + +static void joydx_generate_configure_event(void) +{ + ALLEGRO_EVENT event; + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; + event.joystick.timestamp = al_get_time(); + + _al_generate_joystick_event(&event); +} + + +static bool joydx_scan(bool configure) +{ + HRESULT hr; + unsigned i; + + /* Clear mark bits. */ + for (i = 0; i < MAX_JOYSTICKS; i++) + joydx_joystick[i].marked = false; + + /* enumerate the joysticks attached to the system */ + hr = IDirectInput8_EnumDevices(joystick_dinput, DI8DEVCLASS_GAMECTRL, + joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY); + if (FAILED(hr)) { + /* XXX will this ruin everything? */ + IDirectInput8_Release(joystick_dinput); + joystick_dinput = NULL; + return false; + } + + /* Schedule unmarked structures to be inactivated. */ + for (i = 0; i < MAX_JOYSTICKS; i++) { + ALLEGRO_JOYSTICK_DIRECTX *joy = &joydx_joystick[i]; + + if (joy->config_state == STATE_ALIVE && !joy->marked) { + ALLEGRO_DEBUG("Joystick %s to be inactivated\n", joydx_guid_string(joy)); + joy->config_state = STATE_DYING; + config_needs_merging = true; + } + } + + if (config_needs_merging && configure) + joydx_generate_configure_event(); + + return config_needs_merging; +} + + +static void joydx_merge(void) +{ + unsigned i; + HRESULT hr; + + config_needs_merging = false; + joydx_num_joysticks = 0; + + for (i = 0; i < MAX_JOYSTICKS; i++) { + ALLEGRO_JOYSTICK_DIRECTX *joy = &joydx_joystick[i]; + + switch (joy->config_state) { + case STATE_UNUSED: + break; + + case STATE_BORN: + hr = IDirectInputDevice8_Acquire(joy->device); + if (FAILED(hr)) { + ALLEGRO_ERROR("acquire joystick %d failed: %s\n", + i, dinput_err_str(hr)); + } + joy->config_state = STATE_ALIVE; + /* fall through */ + case STATE_ALIVE: + JOYSTICK_WAKER(joydx_num_joysticks) = joy->waker_event; + joydx_num_joysticks++; + break; + + case STATE_DYING: + joydx_inactivate_joy(joy); + break; + } + } + + ALLEGRO_INFO("Merged, num joysticks=%d\n", joydx_num_joysticks); + + joystick_dinput_acquire(); +} + + +/* joydx_init_joystick: [primary thread] + * + * Initialises the DirectInput joystick devices. + * + * To avoid enumerating the the joysticks over and over, this does + * the enumeration once and does almost all the setting up required + * of the devices. joydx_get_joystick() is left with very little work + * to do. + */ +static bool joydx_init_joystick(void) +{ + HRESULT hr; + ALLEGRO_SYSTEM *system; + size_t i; + + MAKE_UNION(&joystick_dinput, LPDIRECTINPUT *); + + ALLEGRO_ASSERT(!joystick_dinput); + ALLEGRO_ASSERT(!joydx_num_joysticks); + ALLEGRO_ASSERT(!joydx_thread); + ALLEGRO_ASSERT(!STOP_EVENT); + + /* load DirectInput module */ + _al_dinput_module = _al_win_safe_load_library(_al_dinput_module_name); + if (_al_dinput_module == NULL) { + ALLEGRO_ERROR("Failed to open '%s' library\n", _al_dinput_module_name); + joystick_dinput = NULL; + return false; + } + + /* import DirectInput create proc */ + _al_dinput_create = (DIRECTINPUT8CREATEPROC)GetProcAddress(_al_dinput_module, "DirectInput8Create"); + if (_al_dinput_create == NULL) { + ALLEGRO_ERROR("DirectInput8Create not in %s\n", _al_dinput_module_name); + FreeLibrary(_al_dinput_module); + joystick_dinput = NULL; + return false; + } + + /* get the DirectInput interface */ + hr = _al_dinput_create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, __al_IID_IDirectInput8, u.v, NULL); + if (FAILED(hr)) { + ALLEGRO_ERROR("Failed to create DirectInput interface\n"); + FreeLibrary(_al_dinput_module); + joystick_dinput = NULL; + return false; + } + + /* initialise the lock for the background thread */ + InitializeCriticalSection(&joydx_thread_cs); + + // This initializes present joystick state + joydx_scan(false); + + // This copies present state to user state + joydx_merge(); + + /* create the dedicated thread stopping event */ + STOP_EVENT = CreateEvent(NULL, false, false, NULL); + + /* If one of our windows is the foreground window make it grab the input. */ + system = al_get_system_driver(); + for (i = 0; i < _al_vector_size(&system->displays); i++) { + ALLEGRO_DISPLAY_WIN **pwin_disp = (ALLEGRO_DISPLAY_WIN **)_al_vector_ref(&system->displays, i); + ALLEGRO_DISPLAY_WIN *win_disp = *pwin_disp; + if (win_disp->window == GetForegroundWindow()) { + _al_win_wnd_call_proc(win_disp->window, + _al_win_joystick_dinput_grab, win_disp); + } + } + + /* start the background thread */ + joydx_thread = (HANDLE) _beginthreadex(NULL, 0, joydx_thread_proc, NULL, 0, NULL); + + return true; +} + + + +/* joydx_exit_joystick: [primary thread] + * Shuts down the DirectInput joystick devices. + */ +static void joydx_exit_joystick(void) +{ + int i; + ALLEGRO_SYSTEM *system; + size_t j; + + ALLEGRO_DEBUG("Entering joydx_exit_joystick\n"); + + ALLEGRO_ASSERT(joydx_thread); + + /* stop the thread */ + SetEvent(STOP_EVENT); + WaitForSingleObject(joydx_thread, INFINITE); + CloseHandle(joydx_thread); + joydx_thread = NULL; + + /* free thread resources */ + CloseHandle(STOP_EVENT); + STOP_EVENT = NULL; + DeleteCriticalSection(&joydx_thread_cs); + + /* The toplevel display is assumed to have the input acquired. Release it. */ + system = al_get_system_driver(); + for (j = 0; j < _al_vector_size(&system->displays); j++) { + ALLEGRO_DISPLAY_WIN **pwin_disp = (ALLEGRO_DISPLAY_WIN **)_al_vector_ref(&system->displays, j); + ALLEGRO_DISPLAY_WIN *win_disp = *pwin_disp; + if (win_disp->window == GetForegroundWindow()) { + ALLEGRO_DEBUG("Requesting window unacquire joystick devices\n"); + _al_win_wnd_call_proc(win_disp->window, + _al_win_joystick_dinput_unacquire, + win_disp); + } + } + + /* destroy the devices */ + for (i = 0; i < MAX_JOYSTICKS; i++) { + joydx_inactivate_joy(&joydx_joystick[i]); + } + joydx_num_joysticks = 0; + + for (i = 0; i < MAX_JOYSTICKS; i++) { + JOYSTICK_WAKER(i) = NULL; + } + + /* destroy the DirectInput interface */ + IDirectInput8_Release(joystick_dinput); + joystick_dinput = NULL; + + /* release module handle */ + FreeLibrary(_al_dinput_module); + _al_dinput_module = NULL; + + ALLEGRO_DEBUG("Leaving joydx_exit_joystick\n"); +} + + + +/* joydx_reconfigure_joysticks: [primary thread] + */ +static bool joydx_reconfigure_joysticks(void) +{ + bool ret = false; + + EnterCriticalSection(&joydx_thread_cs); + + if (config_needs_merging) { + joydx_merge(); + ret = true; + } + + LeaveCriticalSection(&joydx_thread_cs); + + return ret; +} + + + +/* joydx_get_num_joysticks: [primary thread] + * Return the number of joysticks available on the system. + */ +static int joydx_get_num_joysticks(void) +{ + return joydx_num_joysticks; +} + + + +/* joydx_get_joystick: [primary thread] + * + * Returns the address of a ALLEGRO_JOYSTICK structure for the device + * number NUM. + */ +static ALLEGRO_JOYSTICK *joydx_get_joystick(int num) +{ + ALLEGRO_JOYSTICK *ret = NULL; + unsigned i; + ALLEGRO_ASSERT(num >= 0); + + EnterCriticalSection(&joydx_thread_cs); + + for (i = 0; i < MAX_JOYSTICKS; i++) { + ALLEGRO_JOYSTICK_DIRECTX *joy = &joydx_joystick[i]; + + if (ACTIVE_STATE(joy->config_state)) { + if (num == 0) { + ret = (ALLEGRO_JOYSTICK *)joy; + break; + } + num--; + } + } + /* Must set the driver of the joystick for the wrapper driver */ + ret->driver = &_al_joydrv_directx; + + LeaveCriticalSection(&joydx_thread_cs); + +#if 0 + /* is this needed? */ + if (ret) { + ALLEGRO_DISPLAY *display = al_get_current_display(); + if (display) + _al_win_joystick_dinput_grab(display); + } +#endif + + return ret; +} + + + +/* joydx_release_joystick: [primary thread] + * Releases a previously gotten joystick. + */ +static void joydx_release_joystick(ALLEGRO_JOYSTICK *joy) +{ + (void)joy; +} + + +/* joydx_get_joystick_state: [primary thread] + * Copy the internal joystick state to a user-provided structure. + */ +static void joydx_get_joystick_state(ALLEGRO_JOYSTICK *joy_, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + ALLEGRO_JOYSTICK_DIRECTX *joy = (ALLEGRO_JOYSTICK_DIRECTX *)joy_; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + _al_event_source_lock(es); + { + *ret_state = joy->joystate; + } + _al_event_source_unlock(es); +} + + +static const char *joydx_get_name(ALLEGRO_JOYSTICK *joy_) +{ + ALLEGRO_JOYSTICK_DIRECTX *joy = (ALLEGRO_JOYSTICK_DIRECTX *)joy_; + return joy->name; +} + + +static bool joydx_get_active(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_DIRECTX *joydx = (ALLEGRO_JOYSTICK_DIRECTX *)joy; + + return ACTIVE_STATE(joydx->config_state); +} + + +/* joydx_thread_proc: [joystick thread] + * Thread loop function for the joystick thread. + */ +static unsigned __stdcall joydx_thread_proc(LPVOID unused) +{ + double last_update = al_get_time(); + + /* XXX is this needed? */ + _al_win_thread_init(); + + while (true) { + DWORD result; + result = WaitForMultipleObjects(joydx_num_joysticks + 1, /* +1 for STOP_EVENT */ + joydx_thread_wakers, + false, /* wait for any */ + 1000); /* 1 second wait */ + + if (result == WAIT_OBJECT_0) + break; /* STOP_EVENT */ + + EnterCriticalSection(&joydx_thread_cs); + { + /* handle hot plugging */ + if (al_get_time() > last_update+1 || result == WAIT_TIMEOUT) { + if (need_device_enumeration) { + joydx_scan(true); + need_device_enumeration = false; + } + last_update = al_get_time(); + } + + if (result != WAIT_TIMEOUT) { + int waker_num = result - WAIT_OBJECT_0 - 1; /* -1 for STOP_EVENT */ + HANDLE waker = JOYSTICK_WAKER(waker_num); + unsigned i; + + for (i = 0; i < MAX_JOYSTICKS; i++) { + if (waker == joydx_joystick[i].waker_event) { + update_joystick(&joydx_joystick[i]); + break; + } + } + + if (i == MAX_JOYSTICKS) { + ALLEGRO_WARN("unable to match event to joystick\n"); + } + } + } + LeaveCriticalSection(&joydx_thread_cs); + } + + _al_win_thread_exit(); + + (void)unused; + return 0; +} + + + +/* update_joystick: [joystick thread] + * Reads in data for a single DirectInput joystick device, updates + * the internal ALLEGRO_JOYSTICK_STATE structure, and generates any Allegro + * events required. + */ +static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy) +{ + DIDEVICEOBJECTDATA buffer[DEVICE_BUFFER_SIZE]; + DWORD num_items = DEVICE_BUFFER_SIZE; + HRESULT hr; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + /* some devices require polling */ + IDirectInputDevice8_Poll(joy->device); + + /* get device data into buffer */ + hr = IDirectInputDevice8_GetDeviceData(joy->device, sizeof(DIDEVICEOBJECTDATA), buffer, &num_items, 0); + + if (hr != DI_OK && hr != DI_BUFFEROVERFLOW) { + if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) { + ALLEGRO_WARN("joystick device not acquired or lost\n"); + } + else { + ALLEGRO_ERROR("unexpected error while polling the joystick\n"); + } + return; + } + + /* don't bother locking the event source if there's no work to do */ + /* this happens a lot for polled devices */ + if (num_items == 0) + return; + + _al_event_source_lock(es); + { + unsigned int i; + + for (i = 0; i < num_items; i++) { + const DIDEVICEOBJECTDATA *item = &buffer[i]; + const int dwOfs = item->dwOfs; + const DWORD dwData = item->dwData; + + if (dwOfs == DIJOFS_X) + handle_axis_event(joy, &joy->x_mapping, dwData); + else if (dwOfs == DIJOFS_Y) + handle_axis_event(joy, &joy->y_mapping, dwData); + else if (dwOfs == DIJOFS_Z) + handle_axis_event(joy, &joy->z_mapping, dwData); + else if (dwOfs == DIJOFS_RX) + handle_axis_event(joy, &joy->rx_mapping, dwData); + else if (dwOfs == DIJOFS_RY) + handle_axis_event(joy, &joy->ry_mapping, dwData); + else if (dwOfs == DIJOFS_RZ) + handle_axis_event(joy, &joy->rz_mapping, dwData); + else if ((unsigned int)dwOfs == DIJOFS_SLIDER(0)) + handle_axis_event(joy, &joy->slider_mapping[0], dwData); + else if ((unsigned int)dwOfs == DIJOFS_SLIDER(1)) + handle_axis_event(joy, &joy->slider_mapping[1], dwData); + else if ((unsigned int)dwOfs == DIJOFS_POV(0)) + handle_pov_event(joy, joy->pov_mapping_stick[0], dwData); + else if ((unsigned int)dwOfs == DIJOFS_POV(1)) + handle_pov_event(joy, joy->pov_mapping_stick[1], dwData); + else if ((unsigned int)dwOfs == DIJOFS_POV(2)) + handle_pov_event(joy, joy->pov_mapping_stick[2], dwData); + else if ((unsigned int)dwOfs == DIJOFS_POV(3)) + handle_pov_event(joy, joy->pov_mapping_stick[3], dwData); + else { + /* buttons */ + if ((dwOfs >= DIJOFS_BUTTON0) && + (dwOfs < DIJOFS_BUTTON(joy->parent.info.num_buttons))) + { + int num = (dwOfs - DIJOFS_BUTTON0) / (DIJOFS_BUTTON1 - DIJOFS_BUTTON0); + handle_button_event(joy, num, (dwData & 0x80)); + } + } + } + } + _al_event_source_unlock(es); +} + + + +/* handle_axis_event: [joystick thread] + * Helper function to handle a state change in a non-POV axis. + * The joystick must be locked BEFORE entering this function. + */ +static void handle_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, const AXIS_MAPPING *axis_mapping, DWORD value) +{ + const int stick = axis_mapping->stick; + const int axis = axis_mapping->axis; + float pos; + + if (stick < 0 || stick >= joy->parent.info.num_sticks) + return; + + if (axis < 0 || axis >= joy->parent.info.stick[stick].num_axes) + return; + + pos = (int)value / 32767.0; + joy->joystate.stick[stick].axis[axis] = pos; + generate_axis_event(joy, stick, axis, pos); +} + + + +/* handle_pov_event: [joystick thread] + * Helper function to handle a state change in a POV device. + * The joystick must be locked BEFORE entering this function. + */ +static void handle_pov_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, DWORD _value) +{ + int value = _value; + float old_p0, old_p1; + float p0, p1; + + if (stick < 0 || stick >= joy->parent.info.num_sticks) + return; + + old_p0 = joy->joystate.stick[stick].axis[0]; + old_p1 = joy->joystate.stick[stick].axis[1]; + + /* left */ + if ((value > JOY_POVBACKWARD) && (value < JOY_POVFORWARD_WRAP)) + joy->joystate.stick[stick].axis[0] = p0 = -1.0; + /* right */ + else if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) + joy->joystate.stick[stick].axis[0] = p0 = +1.0; + else + joy->joystate.stick[stick].axis[0] = p0 = 0.0; + + /* forward */ + if (((value > JOY_POVLEFT) && (value <= JOY_POVFORWARD_WRAP)) || + ((value >= JOY_POVFORWARD) && (value < JOY_POVRIGHT))) + joy->joystate.stick[stick].axis[1] = p1 = -1.0; + /* backward */ + else if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) + joy->joystate.stick[stick].axis[1] = p1 = +1.0; + else + joy->joystate.stick[stick].axis[1] = p1 = 0.0; + + if (old_p0 != p0) { + generate_axis_event(joy, stick, 0, p0); + } + + if (old_p1 != p1) { + generate_axis_event(joy, stick, 1, p1); + } +} + + + +/* handle_button_event: [joystick thread] + * Helper function to handle a state change in a button. + * The joystick must be locked BEFORE entering this function. + */ +static void handle_button_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int button, bool down) +{ + if (button < 0 && button >= joy->parent.info.num_buttons) + return; + + if (down) { + joy->joystate.button[button] = 32767; + generate_button_event(joy, button, ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN); + } + else { + joy->joystate.button[button] = 0; + generate_button_event(joy, button, ALLEGRO_EVENT_JOYSTICK_BUTTON_UP); + } +} + + + +/* generate_axis_event: [joystick thread] + * Helper to generate an event after an axis is moved. + * The joystick must be locked BEFORE entering this function. + */ +static void generate_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, int axis, float pos) +{ + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(es)) + return; + + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.timestamp = al_get_time(); + event.joystick.id = (ALLEGRO_JOYSTICK *)joy; + event.joystick.stick = stick; + event.joystick.axis = axis; + event.joystick.pos = pos; + event.joystick.button = 0; + + _al_event_source_emit_event(es, &event); +} + + + +/* generate_button_event: [joystick thread] + * Helper to generate an event after a button is pressed or released. + * The joystick must be locked BEFORE entering this function. + */ +static void generate_button_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int button, ALLEGRO_EVENT_TYPE event_type) +{ + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(es)) + return; + + event.joystick.type = event_type; + event.joystick.timestamp = al_get_time(); + event.joystick.id = (ALLEGRO_JOYSTICK *)joy; + event.joystick.stick = 0; + event.joystick.axis = 0; + event.joystick.pos = 0.0; + event.joystick.button = button; + + _al_event_source_emit_event(es, &event); +} + + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/wjoyxi.c b/allegro/src/win/wjoyxi.c new file mode 100644 index 00000000..1dc49d13 --- /dev/null +++ b/allegro/src/win/wjoyxi.c @@ -0,0 +1,721 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows XInput joystick driver. + * + * By Beoran. + * + * + * See readme.txt for copyright information. + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +/* For waitable timers */ +#define _WIN32_WINNT 0x0501 + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_bitmap.h" + + +#ifdef ALLEGRO_CFG_XINPUT +/* Don't compile this lot if xinput isn't supported. */ + +#ifndef ALLEGRO_WINDOWS +#error something is wrong with the makefile +#endif + +#ifdef ALLEGRO_MINGW32 + #undef MAKEFOURCC +#endif + +/* Poll connected joysticks frequently and non-connected ones infrequently. */ +#ifndef ALLEGRO_XINPUT_POLL_DELAY +#define ALLEGRO_XINPUT_POLL_DELAY 0.01 +#endif + +#ifndef ALLEGRO_XINPUT_DISCONNECTED_POLL_DELAY +#define ALLEGRO_XINPUT_DISCONNECTED_POLL_DELAY 1.50 +#endif + + +#include +#include +#include +#include + +/* The official DirectX xinput.h uses SAL annotations. + * Need the sal.h header to get rid of them. On some other platforms + * such as MinGW on Linux this header is lacking because it is not needed there. + * So, simply try to include sal.h IF we have it , and if not, hope + * for the best. + * This does no harm on msys2 either, they have a sal.h header. + */ +#ifdef ALLEGRO_HAVE_SAL_H +#include +#endif + +#include + +ALLEGRO_DEBUG_CHANNEL("xinput") + +#include "allegro5/joystick.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_wjoyxi.h" + + +/* forward declarations */ +static bool joyxi_init_joystick(void); +static void joyxi_exit_joystick(void); +static bool joyxi_reconfigure_joysticks(void); +static int joyxi_get_num_joysticks(void); +static ALLEGRO_JOYSTICK *joyxi_get_joystick(int num); +static void joyxi_release_joystick(ALLEGRO_JOYSTICK *joy); +static void joyxi_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state); +static const char *joyxi_get_name(ALLEGRO_JOYSTICK *joy); +static bool joyxi_get_active(ALLEGRO_JOYSTICK *joy); + + +/* the driver vtable */ +ALLEGRO_JOYSTICK_DRIVER _al_joydrv_xinput = +{ + AL_JOY_TYPE_XINPUT, + "", + "", + "XInput Joystick", + joyxi_init_joystick, + joyxi_exit_joystick, + joyxi_reconfigure_joysticks, + joyxi_get_num_joysticks, + joyxi_get_joystick, + joyxi_release_joystick, + joyxi_get_joystick_state, + joyxi_get_name, + joyxi_get_active +}; + +#define XINPUT_MIN_VERSION 3 +#define XINPUT_MAX_VERSION 4 + +typedef void (WINAPI *XInputEnablePROC)(BOOL); +typedef DWORD (WINAPI *XInputSetStatePROC)(DWORD, XINPUT_VIBRATION*); +typedef DWORD (WINAPI *XInputGetStatePROC)(DWORD, XINPUT_STATE*); +typedef DWORD (WINAPI *XInputGetCapabilitiesPROC)(DWORD, DWORD, XINPUT_CAPABILITIES*); + +static HMODULE _imp_xinput_module = 0; + +static XInputEnablePROC _imp_XInputEnable = NULL; +static XInputGetStatePROC _imp_XInputGetState = NULL; +static XInputGetCapabilitiesPROC _imp_XInputGetCapabilities = NULL; +XInputSetStatePROC _al_imp_XInputSetState = NULL; + +/* the joystick structures */ +static ALLEGRO_JOYSTICK_XINPUT joyxi_joysticks[MAX_JOYSTICKS]; + +/* For the background threads. */ +static ALLEGRO_THREAD *joyxi_thread = NULL; +static ALLEGRO_THREAD *joyxi_disconnected_thread = NULL; +static ALLEGRO_MUTEX *joyxi_mutex = NULL; +/* Use condition variables to put the thread to sleep and prevent too + frequent polling*/ +static ALLEGRO_COND *joyxi_cond = NULL; +static ALLEGRO_COND *joyxi_disconnected_cond = NULL; + +/* Names for things in because XInput doesn't provide them. */ + +/* Names of the sticks.*/ +static char *const joyxi_stick_names[MAX_STICKS] = { + "Left Thumbstick", + "Right Thumbstick", + "Left Trigger", + "Right Trigger", +}; + +/* Names of the axis */ +static char *const joyxi_axis_names[MAX_STICKS][MAX_AXES] = { + { "X", "Y" }, + { "X", "Y" }, + { "Ramp", "Error" }, + { "Ramp", "Error" }, +}; + +/* Sticks per axis */ +static const int joyxi_axis_per_stick[MAX_STICKS] = { + 2, 2, 1, 1, +}; + + +/* Struct to help mapping. */ +struct _AL_XINPUT_BUTTON_MAPPING +{ + int flags; + int button; + const char *name; +}; + +/* The data in this array helps to map from XINPUT button input to + ALLEGRO's. */ +static const struct _AL_XINPUT_BUTTON_MAPPING + joyxi_button_mapping[MAX_BUTTONS] = { + { XINPUT_GAMEPAD_A, 0, "A" }, + { XINPUT_GAMEPAD_B, 1, "B" }, + { XINPUT_GAMEPAD_X, 2, "X" }, + { XINPUT_GAMEPAD_Y, 3, "Y" }, + { XINPUT_GAMEPAD_RIGHT_SHOULDER, 4, "RB" }, + { XINPUT_GAMEPAD_LEFT_SHOULDER, 5, "LB" }, + { XINPUT_GAMEPAD_RIGHT_THUMB, 6, "RT" }, + { XINPUT_GAMEPAD_LEFT_THUMB, 7, "LT" }, + { XINPUT_GAMEPAD_BACK, 8, "BACK" }, + { XINPUT_GAMEPAD_START, 9, "START" }, + { XINPUT_GAMEPAD_DPAD_RIGHT, 10, "RIGHT DPAD" }, + { XINPUT_GAMEPAD_DPAD_LEFT, 11, "LEFT DPAD" }, + { XINPUT_GAMEPAD_DPAD_DOWN, 12, "DOWN DPAD" }, + { XINPUT_GAMEPAD_DPAD_UP, 13, "UP DPAD" }, +}; + +static void unload_xinput_module(void) +{ + FreeLibrary(_imp_xinput_module); + _imp_xinput_module = NULL; +} + +static bool _imp_load_xinput_module_version(int version) +{ + char module_name[16]; + + sprintf(module_name, "xinput1_%d.dll", version); + + _imp_xinput_module = _al_win_safe_load_library(module_name); + if (NULL == _imp_xinput_module) + return false; + + _imp_XInputEnable = (XInputEnablePROC)GetProcAddress(_imp_xinput_module, "XInputEnable"); + if (NULL == _imp_XInputEnable) { + FreeLibrary(_imp_xinput_module); + _imp_xinput_module = NULL; + return false; + } + _imp_XInputGetState = (XInputGetStatePROC)GetProcAddress(_imp_xinput_module, "XInputGetState"); + _imp_XInputGetCapabilities = (XInputGetCapabilitiesPROC)GetProcAddress(_imp_xinput_module, "XInputGetCapabilities"); + _al_imp_XInputSetState = (XInputSetStatePROC)GetProcAddress(_imp_xinput_module, "XInputSetState"); + + ALLEGRO_INFO("Module \"%s\" loaded.\n", module_name); + + return true; +} + +static bool load_xinput_module(void) +{ + long version; + char const *value; + + if (_imp_xinput_module) { + return true; + } + + value = al_get_config_value(al_get_system_config(), + "joystick", "force_xinput_version"); + if (value) { + errno = 0; + version = strtol(value, NULL, 10); + if (errno) { + ALLEGRO_ERROR("Failed to override XInput version. \"%s\" is not valid integer number.", value); + return false; + } + else + return _imp_load_xinput_module_version((int)version); + } + + // Iterate over all valid versions. + for (version = XINPUT_MAX_VERSION; version >= XINPUT_MIN_VERSION; version--) + if (_imp_load_xinput_module_version((int)version)) + return true; + + ALLEGRO_ERROR("Failed to load XInput library. Library is not installed."); + + return false; +} + +/* generate_axis_event: [joystick thread] + * Helper to generate an event when reconfiguration is needed. + * The joystick must be locked BEFORE entering this function. + */ + +static void joyxi_generate_reconfigure_event(void) +{ + ALLEGRO_EVENT_SOURCE *source; + ALLEGRO_EVENT event; + + /* There is a potential race condition with all of the generate functions + * in this source file where al_get_joystick_event_source is returning NULL + * because the joystick driver init functions haven't finished and + * therefore new_joystick_driver in joynu.c isn't set yet. So we check that + * the driver has fully installed before proceeding. + */ + if (!al_is_joystick_installed()) + return; + + source = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(source)) + return; + + event.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION; + event.any.timestamp = al_get_time(); + event.any.source = source; + _al_event_source_emit_event(source, &event); +} + +/* Helper to generate an event after an axis is moved. + * The joystick must be locked BEFORE entering this function. + */ +static void joyxi_generate_axis_event(ALLEGRO_JOYSTICK_XINPUT *joy, int stick, int axis, float pos) +{ + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es; + + if (!al_is_joystick_installed()) + return; + + es = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(es)) + return; + + event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS; + event.joystick.timestamp = al_get_time(); + event.joystick.id = (ALLEGRO_JOYSTICK *)&joy->parent; + event.joystick.stick = stick; + event.joystick.axis = axis; + event.joystick.pos = pos; + event.joystick.button = 0; + ALLEGRO_DEBUG("Generating an axis event on stick %d axis %d value %f:\n", stick, axis, pos); + + _al_event_source_emit_event(es, &event); +} + + +/* Helper to generate an event after a button is pressed or released. + * The joystick must be locked BEFORE entering this function. + */ +static void joyxi_generate_button_event(ALLEGRO_JOYSTICK_XINPUT *joy, int button, ALLEGRO_EVENT_TYPE event_type) +{ + ALLEGRO_EVENT event; + ALLEGRO_EVENT_SOURCE *es; + + if (!al_is_joystick_installed()) + return; + + es = al_get_joystick_event_source(); + + if (!_al_event_source_needs_to_generate_event(es)) + return; + + event.joystick.type = event_type; + event.joystick.timestamp = al_get_time(); + event.joystick.id = (ALLEGRO_JOYSTICK *)joy; + event.joystick.stick = 0; + event.joystick.axis = 0; + event.joystick.pos = 0.0; + event.joystick.button = button; + ALLEGRO_DEBUG("Generating an button event on button %d type %d:\n", button, event_type); + + _al_event_source_emit_event(es, &event); +} + + +/* Converts an XINPUT axis value to one suitable for Allegro's axes.*/ +static float joyxi_convert_axis(SHORT value) +{ + if (value >= 0) return(((float)value) / 32767.0); + return(((float)value) / 32768.0); +} + +/* Converts an XINPUT trigger value to one suitable for Allegro's axes.*/ +static float joyxi_convert_trigger(BYTE value) +{ + return(((float)value) / 255.0); +} + +/* Converts an XInput state to an Allegro joystick state. */ +static void joyxi_convert_state(ALLEGRO_JOYSTICK_STATE *alstate, XINPUT_STATE *xistate) +{ + int index; + /* Wipe the allegro state clean. */ + memset(alstate, 0, sizeof(*alstate)); + + /* Map the buttons. Make good use of the mapping data. */ + for (index = 0; index < MAX_BUTTONS; index++) { + const struct _AL_XINPUT_BUTTON_MAPPING *mapping = joyxi_button_mapping + index; + if (xistate->Gamepad.wButtons & mapping->flags) { + alstate->button[mapping->button] = 32767; + } + else { + alstate->button[mapping->button] = 0; + } + } + /* Map the x and y axes of both sticks. */ + alstate->stick[0].axis[0] = joyxi_convert_axis(xistate->Gamepad.sThumbLX); + alstate->stick[0].axis[1] = -joyxi_convert_axis(xistate->Gamepad.sThumbLY); + alstate->stick[1].axis[0] = joyxi_convert_axis(xistate->Gamepad.sThumbRX); + alstate->stick[1].axis[1] = -joyxi_convert_axis(xistate->Gamepad.sThumbRY); + /* Map the triggers as two individual sticks and axes each . */ + alstate->stick[2].axis[0] = joyxi_convert_trigger(xistate->Gamepad.bLeftTrigger); + alstate->stick[3].axis[0] = joyxi_convert_trigger(xistate->Gamepad.bRightTrigger); + return; +} + + +/* Emits joystick events for the difference between the new and old joystick state. */ +static void joyxi_emit_events( + ALLEGRO_JOYSTICK_XINPUT *xjoy, + ALLEGRO_JOYSTICK_STATE *newstate, ALLEGRO_JOYSTICK_STATE *oldstate) +{ + int index, subdex; + /* Send events for buttons. */ + for (index = 0; index < MAX_BUTTONS; index++) { + int newbutton = newstate->button[index]; + int oldbutton = oldstate->button[index]; + if (newbutton != oldbutton) { + int type = (oldbutton > newbutton ? + ALLEGRO_EVENT_JOYSTICK_BUTTON_UP : + ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN); + joyxi_generate_button_event(xjoy, index, type); + } + } + /* Send events for the thumb pad axes and triggers . */ + for (index = 0; index < MAX_STICKS; index++) { + for (subdex = 0; subdex < joyxi_axis_per_stick[index]; subdex++) { + float oldaxis = oldstate->stick[index].axis[subdex]; + float newaxis = newstate->stick[index].axis[subdex]; + if (oldaxis != newaxis) { + joyxi_generate_axis_event(xjoy, index, subdex, newaxis); + } + } + } +} + + +/* Polling function for a joystick that is currently active. */ +static void joyxi_poll_connected_joystick(ALLEGRO_JOYSTICK_XINPUT *xjoy) +{ + XINPUT_STATE xistate; + ALLEGRO_JOYSTICK_STATE alstate; + DWORD res = _imp_XInputGetState(xjoy->index, &xistate); + if (res != ERROR_SUCCESS) { + /* Assume joystick was disconnected, need to reconfigure. */ + joyxi_generate_reconfigure_event(); + return; + } + + /* Check if the sequence is different. If not, no state change so + don't do anything. */ + if (xistate.dwPacketNumber == xjoy->state.dwPacketNumber) + return; + + ALLEGRO_DEBUG("XInput joystick state change detected.\n"); + + /* If we get here translate the state and send the needed events. */ + joyxi_convert_state(&alstate, &xistate); + joyxi_emit_events(xjoy, &alstate, &xjoy->joystate); + + /* Finally copy over the states. */ + xjoy->state = xistate; + xjoy->joystate = alstate; +} + + +/* Polling function for a joystick that is currently not active. Care is taken to do this infrequently so + performance doesn't suffer too much. */ +static void joyxi_poll_disconnected_joystick(ALLEGRO_JOYSTICK_XINPUT *xjoy) +{ + XINPUT_CAPABILITIES xicapas; + DWORD res; + res = _imp_XInputGetCapabilities(xjoy->index, 0, &xicapas); + if (res == ERROR_SUCCESS) { + /* Got capabilities, joystick was connected, need to reconfigure. */ + joyxi_generate_reconfigure_event(); + return; + } + /* Nothing to do if we get here. */ +} + + +/** Polls all connected joysticks. */ +static void joyxi_poll_connected_joysticks(void) +{ + int index; + + for (index = 0; index < MAX_JOYSTICKS; index++) { + if ((joyxi_joysticks + index)->active) { + joyxi_poll_connected_joystick(joyxi_joysticks + index); + } + } +} + +/** Polls all disconnected joysticks. */ +static void joyxi_poll_disconnected_joysticks(void) +{ + int index; + + for (index = 0; index < MAX_JOYSTICKS; index++) { + if (!((joyxi_joysticks + index)->active)) { + joyxi_poll_disconnected_joystick(joyxi_joysticks + index); + } + } +} + +/** Thread function that polls the active xinput joysticks. */ +static void *joyxi_poll_thread(ALLEGRO_THREAD *thread, void *arg) +{ + ALLEGRO_TIMEOUT timeout; + al_lock_mutex(joyxi_mutex); + /* Poll once every so much time, 10ms by default. */ + while (!al_get_thread_should_stop(thread)) { + al_init_timeout(&timeout, ALLEGRO_XINPUT_POLL_DELAY); + /* Wait for the condition for the polling time in stead of using + al_rest to allows the polling thread to be awoken when needed. */ + al_wait_cond_until(joyxi_cond, joyxi_mutex, &timeout); + /* If we get here poll joystick for new input or connection + * and dispatch events. The mutexhas always been locked + * so this should be OK. */ + joyxi_poll_connected_joysticks(); + } + al_unlock_mutex(joyxi_mutex); + return arg; +} + +/** Thread function that polls the disconnected joysticks. */ +static void *joyxi_poll_disconnected_thread(ALLEGRO_THREAD *thread, void *arg) +{ + ALLEGRO_TIMEOUT timeout; + al_lock_mutex(joyxi_mutex); + /* Poll once every so much time, 10ms by default. */ + while (!al_get_thread_should_stop(thread)) { + al_init_timeout(&timeout, ALLEGRO_XINPUT_DISCONNECTED_POLL_DELAY); + /* Wait for the condition for the polling time in stead of using + al_rest to allows the polling thread to be awoken when needed. */ + al_wait_cond_until(joyxi_disconnected_cond, joyxi_mutex, &timeout); + /* If we get here poll joystick for new input or connection + * and dispatch events. The mutex has always been locked + * so this should be OK. */ + joyxi_poll_disconnected_joysticks(); + } + al_unlock_mutex(joyxi_mutex); + return arg; +} + + + +/* Initializes the info part of the joystick. */ +static void joyxi_init_joystick_info(ALLEGRO_JOYSTICK_XINPUT *xjoy) +{ + int index, subdex; + _AL_JOYSTICK_INFO *info = &xjoy->parent.info; + /* Map xinput to 4 sticks: 2 thumb pads and 2 triggers. */ + info->num_sticks = 4; + /* Map xinput to 14 buttons */ + info->num_buttons = MAX_BUTTONS; + /* Map button names. */ + for (index = 0; index < MAX_BUTTONS; index++) { + info->button[index].name = joyxi_button_mapping[index].name; + } + /* Map stick and axis names. */ + for (index = 0; index < MAX_STICKS; index++) { + info->stick[index].name = joyxi_stick_names[index]; + info->stick[index].num_axes = joyxi_axis_per_stick[index]; + info->stick[index].flags = ALLEGRO_JOYFLAG_ANALOGUE; + for (subdex = 0; subdex < joyxi_axis_per_stick[index]; subdex++) { + info->stick[index].axis[subdex].name = joyxi_axis_names[index][subdex]; + } + } +} + +/* Initialization API function. */ +static bool joyxi_init_joystick(void) +{ + int index; + + if (!load_xinput_module()) + return false; + + /* Create the mutex and two condition variables. */ + joyxi_mutex = al_create_mutex_recursive(); + if (!joyxi_mutex) + return false; + joyxi_cond = al_create_cond(); + if (!joyxi_cond) + return false; + joyxi_disconnected_cond = al_create_cond(); + if (!joyxi_disconnected_cond) + return false; + + al_lock_mutex(joyxi_mutex); + + /* Fill in the joystick structs */ + for (index = 0; index < MAX_JOYSTICKS; index++) { + joyxi_joysticks[index].active = false; + sprintf(joyxi_joysticks[index].name, "XInput Joystick %d", index); + joyxi_joysticks[index].index = (DWORD)index; + joyxi_init_joystick_info(joyxi_joysticks + index); + } + /* Now, enable XInput*/ + _imp_XInputEnable(TRUE); + /* Now check which joysticks are enabled and poll them for the first time + * but without sending any events. + */ + for (index = 0; index < MAX_JOYSTICKS; index++) { + DWORD res = _imp_XInputGetCapabilities(joyxi_joysticks[index].index, 0, &joyxi_joysticks[index].capabilities); + joyxi_joysticks[index].active = (res == ERROR_SUCCESS); + if (joyxi_joysticks[index].active) { + res = _imp_XInputGetState(joyxi_joysticks[index].index, &joyxi_joysticks[index].state); + joyxi_joysticks[index].active = (res == ERROR_SUCCESS); + } + } + /* Now start two polling background thread, since XInput is a polled API. + * The first thread will poll the active joysticks frequently, the second + * thread will poll the inactive joysticks infrequently. + * This is done like this to preserve performance. + */ + joyxi_thread = al_create_thread(joyxi_poll_thread, NULL); + joyxi_disconnected_thread = al_create_thread(joyxi_poll_disconnected_thread, NULL); + + al_unlock_mutex(joyxi_mutex); + + if (joyxi_thread) al_start_thread(joyxi_thread); + if (joyxi_disconnected_thread) al_start_thread(joyxi_disconnected_thread); + + return (joyxi_thread != NULL) && (joyxi_disconnected_thread != NULL); +} + + +static void joyxi_exit_joystick(void) +{ + int index; + void *ret_value = NULL; + if (!joyxi_mutex) return; + if (!joyxi_cond) return; + if (!joyxi_thread) return; + /* Request the event thread to shut down, signal the condition, then join the thread. */ + al_set_thread_should_stop(joyxi_thread); + al_signal_cond(joyxi_cond); + al_join_thread(joyxi_thread, &ret_value); + al_set_thread_should_stop(joyxi_disconnected_thread); + al_signal_cond(joyxi_disconnected_cond); + al_join_thread(joyxi_disconnected_thread, &ret_value); + + /* clean it all up. */ + al_destroy_thread(joyxi_disconnected_thread); + al_destroy_cond(joyxi_disconnected_cond); + al_destroy_thread(joyxi_thread); + al_destroy_cond(joyxi_cond); + + al_lock_mutex(joyxi_mutex); + /* Disable xinput */ + _imp_XInputEnable(FALSE); + /* Wipe the joystick structs */ + for (index = 0; index < MAX_JOYSTICKS; index++) { + joyxi_joysticks[index].active = false; + } + al_unlock_mutex(joyxi_mutex); + al_destroy_mutex(joyxi_mutex); + + unload_xinput_module(); +} + + +static bool joyxi_reconfigure_joysticks(void) +{ + int index; + al_lock_mutex(joyxi_mutex); + for (index = 0; index < MAX_JOYSTICKS; index++) { + DWORD res = _imp_XInputGetCapabilities(joyxi_joysticks[index].index, 0, &joyxi_joysticks[index].capabilities); + joyxi_joysticks[index].active = (res == ERROR_SUCCESS); + if (joyxi_joysticks[index].active) { + res = _imp_XInputGetState(joyxi_joysticks[index].index, &joyxi_joysticks[index].state); + joyxi_joysticks[index].active = (res == ERROR_SUCCESS); + } + } + al_unlock_mutex(joyxi_mutex); + /** Signal the conditions so new events are sent immediately for the new joysticks. */ + al_signal_cond(joyxi_cond); + /** Signal the disconnected thread in case another joystick got connected. */ + al_signal_cond(joyxi_disconnected_cond); + return true; +} + +static int joyxi_get_num_joysticks(void) +{ + int result = 0, index; + for (index = 0; index < MAX_JOYSTICKS; index++) { + if (joyxi_joysticks[index].active) + result++; + } + return result; +} + +static ALLEGRO_JOYSTICK *joyxi_get_joystick(int num) +{ + int al_number = 0, index; + /* Use a linear scan, so the first active joystick ends up as the first + * allegro joystick etc. */ + for (index = 0; index < MAX_JOYSTICKS; index++) { + if (joyxi_joysticks[index].active) { + if (num == al_number) + return &joyxi_joysticks[index].parent; + else + al_number++; + } + } + return NULL; +} + + +static void joyxi_release_joystick(ALLEGRO_JOYSTICK *joy) +{ + /* No need to do anything. */ + (void)joy; +} + +static void joyxi_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state) +{ + ALLEGRO_JOYSTICK_XINPUT *xjoy = (ALLEGRO_JOYSTICK_XINPUT *)joy; + ASSERT(xjoy); + ASSERT(ret_state); + /* Copy the data with the mutex + * locked to prevent changes during copying. */ + al_lock_mutex(joyxi_mutex); + (*ret_state) = xjoy->joystate; + al_unlock_mutex(joyxi_mutex); +} + + +static const char *joyxi_get_name(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_XINPUT *xjoy = (ALLEGRO_JOYSTICK_XINPUT *)joy; + ASSERT(xjoy); + return xjoy->name; +} + + +static bool joyxi_get_active(ALLEGRO_JOYSTICK *joy) +{ + ALLEGRO_JOYSTICK_XINPUT *xjoy = (ALLEGRO_JOYSTICK_XINPUT *)joy; + ASSERT(xjoy); + return xjoy->active; +} + + +#endif /* #ifdef ALLEGRO_CFG_XINPUT */ diff --git a/allegro/src/win/wkeyboard.c b/allegro/src/win/wkeyboard.c new file mode 100644 index 00000000..1a666e98 --- /dev/null +++ b/allegro/src/win/wkeyboard.c @@ -0,0 +1,480 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows keyboard driver. + * + * By Milan Mimica. + * + * See readme.txt for copyright information. + * + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/platform/aintwin.h" + +/* Missing from MSVC 2005 headers. */ +#ifndef MAPVK_VSC_TO_VK_EX + #define MAPVK_VSC_TO_VK_EX 3 +#endif + +static bool installed = false; +static ALLEGRO_KEYBOARD the_keyboard; +static ALLEGRO_KEYBOARD_STATE the_state; +static int modifiers = 0; + +/* lookup table for converting virtualkey VK_* codes into Allegro ALLEGRO_KEY_* codes */ +/* For handling of extended keys, extkey_to_keycode() takes priority over this. */ +/* Last unknown key sequence: 39*/ +static const unsigned char hw_to_mycode[256] = +{ + /* 0x00 */ 0, ALLEGRO_KEY_UNKNOWN+0, ALLEGRO_KEY_UNKNOWN+1, ALLEGRO_KEY_UNKNOWN+2, + /* 0x04 */ ALLEGRO_KEY_UNKNOWN+3, ALLEGRO_KEY_UNKNOWN+4, ALLEGRO_KEY_UNKNOWN+5, 0, + /* 0x08 */ ALLEGRO_KEY_BACKSPACE, ALLEGRO_KEY_TAB, 0, 0, + /* 0x0C */ ALLEGRO_KEY_PAD_5, ALLEGRO_KEY_ENTER, 0, 0, + /* 0x10 */ 0/*L or R shift*/, ALLEGRO_KEY_LCTRL, ALLEGRO_KEY_ALT, ALLEGRO_KEY_PAUSE, + /* 0x14 */ ALLEGRO_KEY_CAPSLOCK, ALLEGRO_KEY_KANA, 0, ALLEGRO_KEY_UNKNOWN+6, + /* 0x18 */ ALLEGRO_KEY_UNKNOWN+7, ALLEGRO_KEY_KANJI, 0, ALLEGRO_KEY_ESCAPE, + /* 0x1C */ ALLEGRO_KEY_CONVERT, ALLEGRO_KEY_NOCONVERT, ALLEGRO_KEY_UNKNOWN+8, ALLEGRO_KEY_UNKNOWN+9, + /* 0x20 */ ALLEGRO_KEY_SPACE, ALLEGRO_KEY_PAD_9, ALLEGRO_KEY_PAD_3, ALLEGRO_KEY_PAD_1, + /* 0x24 */ ALLEGRO_KEY_PAD_7, ALLEGRO_KEY_PAD_4, ALLEGRO_KEY_PAD_8, ALLEGRO_KEY_PAD_6, + /* 0x28 */ ALLEGRO_KEY_PAD_2, ALLEGRO_KEY_UNKNOWN+10, ALLEGRO_KEY_UNKNOWN+11, ALLEGRO_KEY_UNKNOWN+12, + /* 0x2C */ ALLEGRO_KEY_PRINTSCREEN, ALLEGRO_KEY_PAD_0, ALLEGRO_KEY_PAD_DELETE, ALLEGRO_KEY_UNKNOWN+13, + /* 0x30 */ ALLEGRO_KEY_0, ALLEGRO_KEY_1, ALLEGRO_KEY_2, ALLEGRO_KEY_3, + /* 0x34 */ ALLEGRO_KEY_4, ALLEGRO_KEY_5, ALLEGRO_KEY_6, ALLEGRO_KEY_7, + /* 0x38 */ ALLEGRO_KEY_8, ALLEGRO_KEY_9, 0, 0, + /* 0x3C */ 0, 0, 0, 0, + /* 0x40 */ 0, ALLEGRO_KEY_A, ALLEGRO_KEY_B, ALLEGRO_KEY_C, + /* 0x44 */ ALLEGRO_KEY_D, ALLEGRO_KEY_E, ALLEGRO_KEY_F, ALLEGRO_KEY_G, + /* 0x48 */ ALLEGRO_KEY_H, ALLEGRO_KEY_I, ALLEGRO_KEY_J, ALLEGRO_KEY_K, + /* 0x4C */ ALLEGRO_KEY_L, ALLEGRO_KEY_M, ALLEGRO_KEY_N, ALLEGRO_KEY_O, + /* 0x50 */ ALLEGRO_KEY_P, ALLEGRO_KEY_Q, ALLEGRO_KEY_R, ALLEGRO_KEY_S, + /* 0x54 */ ALLEGRO_KEY_T, ALLEGRO_KEY_U, ALLEGRO_KEY_V, ALLEGRO_KEY_W, + /* 0x58 */ ALLEGRO_KEY_X, ALLEGRO_KEY_Y, ALLEGRO_KEY_Z, ALLEGRO_KEY_LWIN, + /* 0x5C */ ALLEGRO_KEY_RWIN, ALLEGRO_KEY_MENU, 0, 0, + /* 0x60 */ ALLEGRO_KEY_PAD_0, ALLEGRO_KEY_PAD_1, ALLEGRO_KEY_PAD_2, ALLEGRO_KEY_PAD_3, + /* 0x64 */ ALLEGRO_KEY_PAD_4, ALLEGRO_KEY_PAD_5, ALLEGRO_KEY_PAD_6, ALLEGRO_KEY_PAD_7, + /* 0x68 */ ALLEGRO_KEY_PAD_8, ALLEGRO_KEY_PAD_9, ALLEGRO_KEY_PAD_ASTERISK, ALLEGRO_KEY_PAD_PLUS, + /* 0x6C */ ALLEGRO_KEY_UNKNOWN+15, ALLEGRO_KEY_PAD_MINUS, ALLEGRO_KEY_PAD_DELETE, ALLEGRO_KEY_PAD_SLASH, + /* 0x70 */ ALLEGRO_KEY_F1, ALLEGRO_KEY_F2, ALLEGRO_KEY_F3, ALLEGRO_KEY_F4, + /* 0x74 */ ALLEGRO_KEY_F5, ALLEGRO_KEY_F6, ALLEGRO_KEY_F7, ALLEGRO_KEY_F8, + /* 0x78 */ ALLEGRO_KEY_F9, ALLEGRO_KEY_F10, ALLEGRO_KEY_F11, ALLEGRO_KEY_F12, + /* 0x7C */ ALLEGRO_KEY_UNKNOWN+17, ALLEGRO_KEY_UNKNOWN+18, ALLEGRO_KEY_UNKNOWN+19, ALLEGRO_KEY_UNKNOWN+20, + /* 0x80 */ ALLEGRO_KEY_UNKNOWN+21, ALLEGRO_KEY_UNKNOWN+22, ALLEGRO_KEY_UNKNOWN+23, ALLEGRO_KEY_UNKNOWN+24, + /* 0x84 */ ALLEGRO_KEY_UNKNOWN+25, ALLEGRO_KEY_UNKNOWN+26, ALLEGRO_KEY_UNKNOWN+27, ALLEGRO_KEY_UNKNOWN+28, + /* 0x88 */ 0, 0, 0, 0, + /* 0x8C */ 0, 0, 0, 0, + /* 0x90 */ ALLEGRO_KEY_NUMLOCK, ALLEGRO_KEY_SCROLLLOCK, 0, 0, + /* 0x94 */ 0, 0, 0, 0, + /* 0x98 */ 0, 0, 0, 0, + /* 0x9C */ 0, 0, 0, 0, + /* 0xA0 */ ALLEGRO_KEY_LSHIFT, ALLEGRO_KEY_RSHIFT, ALLEGRO_KEY_LCTRL, ALLEGRO_KEY_RCTRL, + /* 0xA4 */ ALLEGRO_KEY_ALT, ALLEGRO_KEY_ALTGR, 0, 0, + /* 0xA8 */ 0, 0, 0, 0, + /* 0xAC */ 0, 0, 0, 0, + /* 0xB0 */ 0, 0, 0, 0, + /* 0xB4 */ 0, 0, 0, 0, + /* 0xB8 */ 0, 0, ALLEGRO_KEY_SEMICOLON, ALLEGRO_KEY_EQUALS, + /* 0xBC */ ALLEGRO_KEY_COMMA, ALLEGRO_KEY_MINUS, ALLEGRO_KEY_FULLSTOP, ALLEGRO_KEY_SLASH, + /* 0xC0 */ ALLEGRO_KEY_TILDE, 0, 0, 0, + /* 0xC4 */ 0, 0, 0, 0, + /* 0xC8 */ 0, 0, 0, 0, + /* 0xCC */ 0, 0, 0, 0, + /* 0xD0 */ 0, 0, 0, 0, + /* 0xD4 */ 0, 0, 0, 0, + /* 0xD8 */ 0, 0, 0, ALLEGRO_KEY_OPENBRACE, + /* 0xDC */ ALLEGRO_KEY_BACKSLASH, ALLEGRO_KEY_CLOSEBRACE, ALLEGRO_KEY_QUOTE, 0, + /* 0xE0 */ 0, 0, ALLEGRO_KEY_BACKSLASH2, 0, + /* 0xE4 */ 0, ALLEGRO_KEY_UNKNOWN+29, 0, 0, + /* 0xE8 */ 0, 0, 0, 0, + /* 0xEC */ 0, 0, 0, 0, + /* 0xF0 */ 0, 0, 0, 0, + /* 0xF4 */ 0, 0, ALLEGRO_KEY_UNKNOWN+30, ALLEGRO_KEY_UNKNOWN+31, + /* 0xF8 */ ALLEGRO_KEY_UNKNOWN+32, ALLEGRO_KEY_UNKNOWN+33, ALLEGRO_KEY_UNKNOWN+34, ALLEGRO_KEY_UNKNOWN+35, + /* 0xFC */ ALLEGRO_KEY_UNKNOWN+36, ALLEGRO_KEY_UNKNOWN+37, ALLEGRO_KEY_UNKNOWN+38, 0 + }; + + +/* forward declarations */ +static bool init_keyboard(void); +static void exit_keyboard(void); +static void get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state); +static void clear_keyboard_state(void); +static ALLEGRO_KEYBOARD *get_keyboard(void); + + +/* the driver vtable */ +#define KEYBOARD_WINAPI AL_ID('W','A','P','I') + +static ALLEGRO_KEYBOARD_DRIVER keyboard_winapi = +{ + KEYBOARD_WINAPI, + 0, + 0, + "WinAPI keyboard", + init_keyboard, + exit_keyboard, + get_keyboard, + NULL, /* bool set_leds(int leds) */ + NULL, /* const char* keycode_to_name(int keycode)*/ + get_keyboard_state, + clear_keyboard_state, +}; + + + +/* list the available drivers */ +_AL_DRIVER_INFO _al_keyboard_driver_list[] = +{ + { KEYBOARD_WINAPI, &keyboard_winapi, true }, + { 0, NULL, 0 } +}; + + +/* init_keyboard: + * Initialise the keyboard driver. + */ +static bool init_keyboard(void) +{ + memset(&the_keyboard, 0, sizeof the_keyboard); + memset(&the_state, 0, sizeof the_state); + modifiers = 0; + + /* Initialise the keyboard object for use as an event source. */ + _al_event_source_init(&the_keyboard.es); + + installed = true; + return true; +} + + + +/* exit_keyboard: + * Shut down the keyboard driver. + */ +static void exit_keyboard(void) +{ + _al_event_source_free(&the_keyboard.es); + + /* This may help catch bugs in the user program, since the pointer + * we return to the user is always the same. + */ + memset(&the_keyboard, 0, sizeof the_keyboard); + + installed = false; +} + + + +/* _al_win_fix_modifiers: + * Fix the modifiers. + */ +void _al_win_fix_modifiers(void) +{ + modifiers = 0; +} + + + +/* get_keyboard: + * Returns the address of a ALLEGRO_KEYBOARD structure representing the keyboard. + */ +static ALLEGRO_KEYBOARD *get_keyboard(void) +{ + return &the_keyboard; +} + + + +/* get_keyboard_state: + * Copy the current keyboard state into RET_STATE. + */ +static void get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) +{ + unsigned int i; + ALLEGRO_DISPLAY *disp = NULL; + ALLEGRO_SYSTEM *sys; + + sys = al_get_system_driver(); + for (i = 0; i < sys->displays._size; i++) { + ALLEGRO_DISPLAY_WIN **d = (void*)_al_vector_ref(&sys->displays, i); + if ((*d)->window == GetForegroundWindow()) { + disp = (void*)*d; + break; + } + } + the_state.display = disp; + *ret_state = the_state; +} + + + +/* clear_keyboard_state: + * Clear the current keyboard state. + */ +static void clear_keyboard_state(void) +{ + memset(&the_state, 0, sizeof(the_state)); +} + + + +/* extkey_to_keycode: + * Given a VK code, returns the Allegro keycode for the corresponding extended + * key. If no code is found, returns zero. + */ +static int extkey_to_keycode(int vcode) +{ + switch (vcode) { + /* These are ordered by VK value, lowest first. */ + case VK_CANCEL: return ALLEGRO_KEY_PAUSE; + case VK_RETURN: return ALLEGRO_KEY_PAD_ENTER; + case VK_CONTROL: return ALLEGRO_KEY_RCTRL; + case VK_MENU: return ALLEGRO_KEY_ALTGR; + case VK_PRIOR: return ALLEGRO_KEY_PGUP; + case VK_NEXT: return ALLEGRO_KEY_PGDN; + case VK_END: return ALLEGRO_KEY_END; + case VK_HOME: return ALLEGRO_KEY_HOME; + case VK_LEFT: return ALLEGRO_KEY_LEFT; + case VK_UP: return ALLEGRO_KEY_UP; + case VK_RIGHT: return ALLEGRO_KEY_RIGHT; + case VK_DOWN: return ALLEGRO_KEY_DOWN; + case VK_SNAPSHOT: return ALLEGRO_KEY_PRINTSCREEN; + case VK_INSERT: return ALLEGRO_KEY_INSERT; + case VK_DELETE: return ALLEGRO_KEY_DELETE; + case VK_LWIN: return ALLEGRO_KEY_LWIN; + case VK_RWIN: return ALLEGRO_KEY_RWIN; + case VK_APPS: return ALLEGRO_KEY_MENU; + case VK_DIVIDE: return ALLEGRO_KEY_PAD_SLASH; + case VK_NUMLOCK: return ALLEGRO_KEY_NUMLOCK; + default: return 0; + } +} + +static void update_modifiers(int code, bool pressed) +{ +#define ON_OFF2(code) \ +{ \ + if (!pressed) \ + modifiers &= ~code; \ + else \ + modifiers |= code; \ + break; \ +} + + switch (code) { + case ALLEGRO_KEY_LSHIFT: + ON_OFF2(ALLEGRO_KEYMOD_SHIFT); + case ALLEGRO_KEY_RSHIFT: + ON_OFF2(ALLEGRO_KEYMOD_SHIFT); + case ALLEGRO_KEY_RCTRL: + ON_OFF2(ALLEGRO_KEYMOD_CTRL); + case ALLEGRO_KEY_LCTRL: + ON_OFF2(ALLEGRO_KEYMOD_CTRL); + case ALLEGRO_KEY_ALT: + ON_OFF2(ALLEGRO_KEYMOD_ALT); + case ALLEGRO_KEY_ALTGR: + ON_OFF2(ALLEGRO_KEYMOD_ALTGR); + case ALLEGRO_KEY_LWIN: + ON_OFF2(ALLEGRO_KEYMOD_LWIN); + case ALLEGRO_KEY_RWIN: + ON_OFF2(ALLEGRO_KEYMOD_RWIN); + case ALLEGRO_KEY_MENU: + ON_OFF2(ALLEGRO_KEYMOD_MENU); + } + +#undef ON_OFF2 +} + + + +/* update_toggle_modifiers: + * Update the state of Num Lock, Caps Lock, and Scroll Lock. + */ +static void update_toggle_modifiers(void) +{ +#define ON_OFF(code, on) \ +{ \ + if (on) \ + modifiers |= code; \ + else \ + modifiers &= ~code; \ +} + /* GetKeyState appears to be the only reliable way of doing this. GetKeyboardState + * is updated a bit too late in some cases. Maybe it would work if WM_CHARs were + * used, since they arrive after the WM_KEYDOWNs that trigger them. + */ + ON_OFF(ALLEGRO_KEYMOD_NUMLOCK, GetKeyState(VK_NUMLOCK) & 1); + ON_OFF(ALLEGRO_KEYMOD_CAPSLOCK, GetKeyState(VK_CAPITAL) & 1); + ON_OFF(ALLEGRO_KEYMOD_SCROLLLOCK, GetKeyState(VK_SCROLL) & 1); + +#undef ON_OFF +} + + + +/* _al_win_kbd_handle_key_press: + * Does stuff when a key is pressed. + */ +void _al_win_kbd_handle_key_press(int scode, int vcode, bool extended, + bool repeated, ALLEGRO_DISPLAY_WIN *win_disp) +{ + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)win_disp; + ALLEGRO_EVENT event; + int my_code; + bool actual_repeat; + int char_count; + int event_count; + int i; + bool ks_state; + BYTE ks[256]; + WCHAR buf[8] = { 0 }; + + if (!installed) + return; + + /* Check for an extended key first. */ + my_code = 0; + if (extended) + my_code = extkey_to_keycode(vcode); + + /* Map a non-extended key. This also works as a fallback in case + the key was extended, but no extended mapping was found. */ + if (my_code == 0) { + if (vcode == VK_SHIFT) /* Left or right Shift key? */ + vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX); + my_code = hw_to_mycode[vcode]; + } + update_modifiers(my_code, true); + + actual_repeat = repeated && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, my_code); + _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, my_code); + + if (!_al_event_source_needs_to_generate_event(&the_keyboard.es)) + return; + + event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = display; + event.keyboard.keycode = my_code; + event.keyboard.unichar = 0; + update_toggle_modifiers(); + event.keyboard.modifiers = modifiers; + event.keyboard.repeat = false; + + _al_event_source_lock(&the_keyboard.es); + + if (my_code > 0 && !actual_repeat) { + _al_event_source_emit_event(&the_keyboard.es, &event); + } + + /* Send char events, but not for modifier keys or dead keys. */ + if (my_code < ALLEGRO_KEY_MODIFIERS) { + ks_state = GetKeyboardState(ks); + if(ks_state && ks[VK_CONTROL] && (modifiers & ALLEGRO_KEYMOD_CTRL)) { + ks[VK_CONTROL] = 0; + } + char_count = ToUnicode(vcode, scode, ks_state ? ks : NULL, buf, 8, 0); + /* Send ASCII code 127 for both Del keys. */ + if (char_count == 0 && vcode == VK_DELETE) { + char_count = 1; + buf[0] = 127; + } + if (char_count != -1) { /* -1 means it was a dead key. */ + event_count = char_count ? char_count : 1; + event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; + update_toggle_modifiers(); + event.keyboard.modifiers = modifiers; + event.keyboard.repeat = actual_repeat; + for (i = 0; i < event_count; i++) { + event.keyboard.unichar = buf[i]; + _al_event_source_emit_event(&the_keyboard.es, &event); + } + } + } + _al_event_source_unlock(&the_keyboard.es); + + /* Toggle mouse grab key. */ + if (my_code && !repeated) { + ALLEGRO_SYSTEM_WIN *system = (void *)al_get_system_driver(); + if (system->toggle_mouse_grab_keycode && my_code == system->toggle_mouse_grab_keycode && + (modifiers & system->toggle_mouse_grab_modifiers) == system->toggle_mouse_grab_modifiers) + { + if (system->mouse_grab_display == display) { + al_ungrab_mouse(); + } + else { + al_grab_mouse(display); + } + } + } +} + + + +/* _al_win_kbd_handle_key_release: + * Does stuff when a key is released. + */ +void _al_win_kbd_handle_key_release(int scode, int vcode, bool extended, ALLEGRO_DISPLAY_WIN *win_disp) +{ + ALLEGRO_EVENT event; + int my_code; + + if (!installed) + return; + + my_code = 0; + if (extended) + my_code = extkey_to_keycode(vcode); + + if (my_code == 0) { + if (vcode == VK_SHIFT) + vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX); + my_code = hw_to_mycode[vcode]; + } + update_modifiers(my_code, false); + + _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, my_code); + + /* Windows only sends a WM_KEYUP message for the Shift keys when + both have been released. If one of the Shift keys is still reported + as down, we need to release it as well. */ + if (my_code == ALLEGRO_KEY_LSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_RSHIFT)) + _al_win_kbd_handle_key_release(scode, VK_RSHIFT, extended, win_disp); + else if (my_code == ALLEGRO_KEY_RSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_LSHIFT)) + _al_win_kbd_handle_key_release(scode, VK_LSHIFT, extended, win_disp); + + if (!_al_event_source_needs_to_generate_event(&the_keyboard.es)) + return; + + event.keyboard.type = ALLEGRO_EVENT_KEY_UP; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = (void*)win_disp; + event.keyboard.keycode = my_code; + event.keyboard.unichar = 0; + update_toggle_modifiers(); + event.keyboard.modifiers = modifiers; + + _al_event_source_lock(&the_keyboard.es); + _al_event_source_emit_event(&the_keyboard.es, &event); + _al_event_source_unlock(&the_keyboard.es); +} + + +/* + * Local Variables: + * c-basic-offset: 3 + * indent-tabs-mode: nil + * End: + */ +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/wmcursor.c b/allegro/src/win/wmcursor.c new file mode 100644 index 00000000..33fc506c --- /dev/null +++ b/allegro/src/win/wmcursor.c @@ -0,0 +1,486 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows mouse cursors. + * + * By Evert Glebbeek. + * + * Adapted for Allegro 4.9 by Peter Wang. + * + * GDI code adapted from src/win/gdi.c. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/platform/aintwin.h" + + +static void local_stretch_blit_to_hdc(ALLEGRO_BITMAP *bitmap, HDC dc, + int src_x, int src_y, int src_w, int src_h, + int dest_x, int dest_y, int dest_w, int dest_h); +static void local_draw_to_hdc(HDC dc, ALLEGRO_BITMAP *bitmap, int x, int y); + + +HICON _al_win_create_icon(HWND wnd, + ALLEGRO_BITMAP *sprite, int xfocus, int yfocus, bool is_cursor, bool resize) +{ + int x, y; + int sys_sm_cx, sys_sm_cy; + HDC h_dc; + HDC h_and_dc; + HDC h_xor_dc; + ICONINFO iconinfo; + HBITMAP and_mask; + HBITMAP xor_mask; + HBITMAP hOldAndMaskBitmap; + HBITMAP hOldXorMaskBitmap; + HICON icon; + bool was_locked; + ALLEGRO_BITMAP *tmp = sprite; + + if (resize) { + if (is_cursor) { + /* Get allowed cursor size - Windows can't make cursors of arbitrary size */ + sys_sm_cx = GetSystemMetrics(SM_CXCURSOR); + sys_sm_cy = GetSystemMetrics(SM_CYCURSOR); + } + else { + sys_sm_cx = GetSystemMetrics(SM_CXICON); + sys_sm_cy = GetSystemMetrics(SM_CYICON); + } + + if ((tmp->w > sys_sm_cx) || (tmp->h > sys_sm_cy)) { + float ratio = tmp->w / (float)tmp->h; + int w, h; + ALLEGRO_STATE state; + if (ratio > 1) { + w = sys_sm_cx; + h = sys_sm_cy / ratio; + } + else { + w = sys_sm_cx * ratio; + h = sys_sm_cy; + } + al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | + ALLEGRO_STATE_BLENDER); + tmp = _al_create_bitmap_params(al_get_current_display(), w, h, + al_get_bitmap_format(tmp), ALLEGRO_MEMORY_BITMAP, 0, 0); + al_set_target_bitmap(tmp); + al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); + al_draw_scaled_bitmap( + sprite, + 0, 0, sprite->w, sprite->h, + 0, 0, w, h, + 0 + ); + al_restore_state(&state); + } + } + else { + sys_sm_cx = al_get_bitmap_width(tmp); + sys_sm_cy = al_get_bitmap_height(tmp); + } + + /* Create bitmap */ + h_dc = GetDC(wnd); + h_xor_dc = CreateCompatibleDC(h_dc); + h_and_dc = CreateCompatibleDC(h_dc); + + /* Prepare AND (monochrome) and XOR (colour) mask */ + and_mask = CreateBitmap(sys_sm_cx, sys_sm_cy, 1, 1, NULL); + xor_mask = CreateCompatibleBitmap(h_dc, sys_sm_cx, sys_sm_cy); + hOldAndMaskBitmap = (HBITMAP) SelectObject(h_and_dc, and_mask); + hOldXorMaskBitmap = (HBITMAP) SelectObject(h_xor_dc, xor_mask); + + /* Create transparent cursor */ + for (y = 0; y < sys_sm_cy; y++) { + for (x = 0; x < sys_sm_cx; x++) { + SetPixel(h_and_dc, x, y, WINDOWS_RGB(255, 255, 255)); + SetPixel(h_xor_dc, x, y, WINDOWS_RGB(0, 0, 0)); + } + } + + /* Lock sprite to speed up repeated get pixel calls. */ + was_locked = al_is_bitmap_locked(tmp); + if (!was_locked) { + al_lock_bitmap(tmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + } + + local_draw_to_hdc(h_xor_dc, tmp, 0, 0); + + /* Make cursor background transparent */ + for (y = 0; y < tmp->h; y++) { + for (x = 0; x < tmp->w; x++) { + ALLEGRO_COLOR c; + unsigned char r, g, b, a; + + c = al_get_pixel(tmp, x, y); + al_unmap_rgba(c, &r, &g, &b, &a); + if (a != 0) { + /* Don't touch XOR value */ + SetPixel(h_and_dc, x, y, 0); + } + else { + /* No need to touch AND value */ + SetPixel(h_xor_dc, x, y, WINDOWS_RGB(0, 0, 0)); + } + } + } + + if (!was_locked) { + al_unlock_bitmap(tmp); + } + + SelectObject(h_and_dc, hOldAndMaskBitmap); + SelectObject(h_xor_dc, hOldXorMaskBitmap); + DeleteDC(h_and_dc); + DeleteDC(h_xor_dc); + ReleaseDC(wnd, h_dc); + + iconinfo.fIcon = is_cursor ? false : true; + iconinfo.xHotspot = xfocus; + iconinfo.yHotspot = yfocus; + iconinfo.hbmMask = and_mask; + iconinfo.hbmColor = xor_mask; + + icon = CreateIconIndirect(&iconinfo); + + DeleteObject(and_mask); + DeleteObject(xor_mask); + + if (sprite != tmp) { + al_destroy_bitmap(tmp); + } + + return icon; +} + + +ALLEGRO_MOUSE_CURSOR *_al_win_create_mouse_cursor(ALLEGRO_BITMAP *sprite, + int xfocus, int yfocus) +{ + HWND wnd; + HCURSOR hcursor; + ALLEGRO_MOUSE_CURSOR_WIN *win_cursor; + + /* A null HWND retrieves the DC for the entire screen. */ + wnd = NULL; + + hcursor = (HCURSOR)_al_win_create_icon(wnd, sprite, xfocus, yfocus, true, true); + if (!hcursor) { + return NULL; + } + + win_cursor = al_malloc(sizeof *win_cursor); + if (!win_cursor) { + DestroyIcon(hcursor); + return NULL; + } + + win_cursor->hcursor = hcursor; + return (ALLEGRO_MOUSE_CURSOR *)win_cursor; +} + + + +void _al_win_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) +{ + ALLEGRO_MOUSE_CURSOR_WIN *win_cursor = (ALLEGRO_MOUSE_CURSOR_WIN *) cursor; + ALLEGRO_SYSTEM *sys = al_get_system_driver(); + unsigned i; + + ASSERT(win_cursor); + + /* XXX not at all thread safe */ + + for (i = 0; i < _al_vector_size(&sys->displays); i++) { + ALLEGRO_DISPLAY_WIN **slot = _al_vector_ref(&sys->displays, i); + ALLEGRO_DISPLAY_WIN *win_display = *slot; + + if (win_cursor->hcursor == win_display->mouse_selected_hcursor) { + _al_win_set_system_mouse_cursor((ALLEGRO_DISPLAY *)win_display, + ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW); + } + } + + DestroyIcon(win_cursor->hcursor); + al_free(win_cursor); +} + + + +bool _al_win_set_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_MOUSE_CURSOR *cursor) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; + ALLEGRO_MOUSE_CURSOR_WIN *win_cursor = (ALLEGRO_MOUSE_CURSOR_WIN *) cursor; + + ASSERT(win_cursor); + ASSERT(win_cursor->hcursor); + + win_display->mouse_selected_hcursor = win_cursor->hcursor; + + if (win_display->mouse_cursor_shown) { + POINT p; + + SetCursor(win_cursor->hcursor); + + /* Windows is too stupid to actually display the mouse pointer when we + * change it and waits until it is moved, so we have to generate a fake + * mouse move to actually show the cursor. + */ + GetCursorPos(&p); + SetCursorPos(p.x, p.y); + } + + return true; +} + + +bool _al_win_show_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; + ALLEGRO_MOUSE_CURSOR_WIN tmp_cursor; + ALLEGRO_MOUSE_CURSOR_WIN *tmp_cursor_ptr = &tmp_cursor; + + /* XXX do we need this? */ + if (!win_display->mouse_selected_hcursor) { + _al_win_set_system_mouse_cursor(display, ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW); + } + + tmp_cursor.hcursor = win_display->mouse_selected_hcursor; + win_display->mouse_cursor_shown = true; + _al_win_set_mouse_cursor(display, (ALLEGRO_MOUSE_CURSOR *)tmp_cursor_ptr); + + return true; +} + +bool _al_win_hide_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; + win_display->mouse_cursor_shown = false; + PostMessage(win_display->window, WM_SETCURSOR, 0, 0); + + return true; +} + + +static HCURSOR system_cursor_to_hcursor(ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +{ + switch (cursor_id) { + case ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW: + return LoadCursor(NULL, IDC_ARROW); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY: + return LoadCursor(NULL, IDC_WAIT); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION: + return LoadCursor(NULL, IDC_HELP); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT: + return LoadCursor(NULL, IDC_IBEAM); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE: + return LoadCursor(NULL, IDC_SIZEALL); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S: + return LoadCursor(NULL, IDC_SIZENS); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W: + return LoadCursor(NULL, IDC_SIZEWE); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW: + return LoadCursor(NULL, IDC_SIZENESW); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE: + return LoadCursor(NULL, IDC_SIZENWSE); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS: + return LoadCursor(NULL, IDC_APPSTARTING); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION: + return LoadCursor(NULL, IDC_CROSS); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK: + return LoadCursor(NULL, IDC_HAND); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT: + return LoadCursor(NULL, IDC_UPARROW); + case ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE: + return LoadCursor(NULL, IDC_NO); + default: + return NULL; + } +} + + +bool _al_win_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; + HCURSOR wc; + + wc = system_cursor_to_hcursor(cursor_id); + if (!wc) { + return false; + } + + win_display->mouse_selected_hcursor = wc; + + if (win_display->mouse_cursor_shown) { + /* + MySetCursor(wc); + PostMessage(wgl_display->window, WM_MOUSEMOVE, 0, 0); + */ + ALLEGRO_MOUSE_CURSOR_WIN tmp_cursor; + ALLEGRO_MOUSE_CURSOR_WIN *tmp_cursor_ptr = &tmp_cursor; + tmp_cursor.hcursor = wc; + _al_win_set_mouse_cursor(display, (ALLEGRO_MOUSE_CURSOR *)tmp_cursor_ptr); + } + return true; +} + + + +/* GDI stuff - this really belongs elsewhere */ + + +/* get_bitmap_info: + * Returns a BITMAPINFO structure suited to an ALLEGRO_BITMAP. + * You have to free the memory allocated by this function. + * + * This version always returns a 32-bit BITMAPINFO. + */ +static BITMAPINFO *get_bitmap_info(ALLEGRO_BITMAP *bitmap) +{ + BITMAPINFO *bi; + int i; + + bi = (BITMAPINFO *) al_malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 256); + + ZeroMemory(&bi->bmiHeader, sizeof(BITMAPINFOHEADER)); + + bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi->bmiHeader.biBitCount = 32; + bi->bmiHeader.biPlanes = 1; + bi->bmiHeader.biWidth = al_get_bitmap_width(bitmap); + bi->bmiHeader.biHeight = -al_get_bitmap_height(bitmap); + bi->bmiHeader.biClrUsed = 256; + bi->bmiHeader.biCompression = BI_RGB; + + for (i = 0; i < 256; i++) { + bi->bmiColors[i].rgbRed = 0; + bi->bmiColors[i].rgbGreen = 0; + bi->bmiColors[i].rgbBlue = 0; + bi->bmiColors[i].rgbReserved = 0; + } + + return bi; +} + + + +/* get_dib_from_bitmap_32: + * Creates a Windows device-independent bitmap (DIB) from an Allegro BITMAP. + * You have to free the memory allocated by this function. + * + * This version always creates a 32-bit DIB. + */ +static BYTE *get_dib_from_bitmap_32(ALLEGRO_BITMAP *bitmap) +{ + int w, h; + int x, y; + int pitch; + BYTE *pixels; + BYTE *dst; + + w = al_get_bitmap_width(bitmap); + h = al_get_bitmap_height(bitmap); + pitch = w * 4; + + pixels = (BYTE *) al_malloc(h * pitch); + if (!pixels) + return NULL; + + for (y = 0; y < h; y++) { + dst = pixels + y * pitch; + + for (x = 0; x < w; x++) { + ALLEGRO_COLOR col; + unsigned char r, g, b, a; + + col = al_get_pixel(bitmap, x, y); + al_unmap_rgba(col, &r, &g, &b, &a); + + /* BGR */ + dst[0] = b; + dst[1] = g; + dst[2] = r; + dst[3] = a; + + dst += 4; + } + } + + return pixels; +} + + + +/* draw_to_hdc: + * Draws an entire Allegro BITMAP to a Windows DC. Has a syntax similar to + * draw_sprite(). + */ +static void local_draw_to_hdc(HDC dc, ALLEGRO_BITMAP *bitmap, int x, int y) +{ + int w = al_get_bitmap_width(bitmap); + int h = al_get_bitmap_height(bitmap); + local_stretch_blit_to_hdc(bitmap, dc, 0, 0, w, h, x, y, w, h); +} + + + +/* stretch_blit_to_hdc: + * Blits an Allegro BITMAP to a Windows DC. Has a syntax similar to + * stretch_blit(). + */ +static void local_stretch_blit_to_hdc(ALLEGRO_BITMAP *bitmap, HDC dc, + int src_x, int src_y, int src_w, int src_h, + int dest_x, int dest_y, int dest_w, int dest_h) +{ + const int bitmap_h = al_get_bitmap_height(bitmap); + const int bottom_up_src_y = bitmap_h - src_y - src_h; + BYTE *pixels; + BITMAPINFO *bi; + + bi = get_bitmap_info(bitmap); + pixels = get_dib_from_bitmap_32(bitmap); + + /* Windows treats all source bitmaps as bottom-up when using StretchDIBits + * unless the source (x,y) is (0,0). To work around this buggy behavior, we + * can use negative heights to reverse the direction of the blits. + * + * See for a detailed explanation. + */ + if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) { + StretchDIBits(dc, dest_x, dest_h+dest_y-1, dest_w, -dest_h, + src_x, bitmap_h - src_y + 1, src_w, -src_h, pixels, bi, + DIB_RGB_COLORS, SRCCOPY); + } + else { + StretchDIBits(dc, dest_x, dest_y, dest_w, dest_h, + src_x, bottom_up_src_y, src_w, src_h, pixels, bi, + DIB_RGB_COLORS, SRCCOPY); + } + + al_free(pixels); + al_free(bi); +} + + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/wmouse.c b/allegro/src/win/wmouse.c new file mode 100644 index 00000000..dad084c2 --- /dev/null +++ b/allegro/src/win/wmouse.c @@ -0,0 +1,417 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows mouse driver. + * + * By Milan Mimica. + * + * See readme.txt for copyright information. + */ + +#if 0 +/* Raw input */ +#define _WIN32_WINNT 0x0501 +#ifndef WINVER +#define WINVER 0x0600 +#endif +#endif +#include + +/* + * Even the most recent MinGW at the moment of writing this is missing + * this symbol. + */ +#ifndef SM_MOUSEHORIZONTALWHEELPRESENT +#define SM_MOUSEHORIZONTALWHEELPRESENT 91 +#endif + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_display.h" + +static ALLEGRO_MOUSE_STATE mouse_state; +static ALLEGRO_MOUSE the_mouse; +static bool installed = false; + +// The raw versions of z/w in the mouse_state. They are related to them by a scaling constant. +static int raw_mouse_z = 0; +static int raw_mouse_w = 0; + + +static bool init_mouse(void) +{ + ALLEGRO_DISPLAY *display; + + if (installed) + return false; + + /* If the display was created before the mouse is installed and the mouse + * cursor is initially within the window, then the display field has correct + * and useful info so don't clobber it. + */ + display = mouse_state.display; + memset(&mouse_state, 0, sizeof(mouse_state)); + mouse_state.display = display; + + _al_event_source_init(&the_mouse.es); + +#if 0 + if (al_get_new_display_flags() & ALLEGRO_FULLSCREEN) { + RAWINPUTDEVICE rid[1]; + rid[0].usUsagePage = 0x01; + rid[0].usUsage = 0x02; + rid[0].dwFlags = RIDEV_NOLEGACY; + rid[0].hwndTarget = 0; + if (RegisterRawInputDevices(rid, 1, sizeof(rid[0])) == FALSE) { + return false; + } + } +#endif + + installed = true; + + return true; +} + + +static void exit_mouse(void) +{ + if (!installed) + return; + + memset(&mouse_state, 0, sizeof(mouse_state)); + _al_event_source_free(&the_mouse.es); + installed = false; +} + + +static void generate_mouse_event(unsigned int type, + int x, int y, int z, int w, float pressure, + int dx, int dy, int dz, int dw, + unsigned int button, + ALLEGRO_DISPLAY *source) +{ + ALLEGRO_EVENT event; + + if (!_al_event_source_needs_to_generate_event(&the_mouse.es)) + return; + + _al_event_source_lock(&the_mouse.es); + event.mouse.type = type; + event.mouse.timestamp = al_get_time(); + event.mouse.display = source; + event.mouse.x = x; + event.mouse.y = y; + event.mouse.z = z; + event.mouse.w = w; + event.mouse.dx = dx; + event.mouse.dy = dy; + event.mouse.dz = dz; + event.mouse.dw = dw; + event.mouse.button = button; + event.mouse.pressure = pressure; + _al_event_source_emit_event(&the_mouse.es, &event); + _al_event_source_unlock(&the_mouse.es); +} + + +static ALLEGRO_MOUSE* get_mouse(void) +{ + return &the_mouse; +} + + +static unsigned int get_num_buttons(void) +{ + return GetSystemMetrics(SM_CMOUSEBUTTONS); +} + + +static unsigned int get_num_axes(void) +{ + bool x = GetSystemMetrics(SM_MOUSEHORIZONTALWHEELPRESENT); + bool z = GetSystemMetrics(SM_MOUSEWHEELPRESENT); + if (x && z) + return 4; + if (x || z) + return 3; + return 2; +} + + +static bool set_mouse_xy(ALLEGRO_DISPLAY *disp, int x, int y) +{ + int dx, dy; + POINT pt; + ALLEGRO_DISPLAY_WIN *win_disp = (void*)disp; + + if (!installed) + return false; + + dx = x - mouse_state.x; + dy = y - mouse_state.y; + + if (dx || dy) { + mouse_state.x = x; + mouse_state.y = y; + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_WARPED, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + dx, dy, 0, 0, + 0, (void*)win_disp); + } + + pt.x = x; + pt.y = y; + + ClientToScreen(win_disp->window, &pt); + + SetCursorPos(pt.x, pt.y); + + return true; +} + + +static bool set_mouse_axis(int which, int val) +{ + /* Vertical mouse wheel. */ + if (which == 2) { + int dz = (val - mouse_state.z); + + raw_mouse_z = WHEEL_DELTA * val / al_get_mouse_wheel_precision(); + + if (dz != 0) { + mouse_state.z = val; + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_AXES, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + 0, 0, dz, 0, + 0, mouse_state.display); + } + + return true; + } + + /* Horizontal mouse wheel. */ + if (which == 3) { + int dw = (val - mouse_state.w); + + raw_mouse_w = WHEEL_DELTA * val / al_get_mouse_wheel_precision(); + + if (dw != 0) { + mouse_state.w = val; + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_AXES, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + 0, 0, 0, dw, + 0, mouse_state.display); + } + + return true; + } + + return false; +} + + +static void get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + _al_event_source_lock(&the_mouse.es); + *ret_state = mouse_state; + _al_event_source_unlock(&the_mouse.es); +} + + +/* the driver vtable */ +#define MOUSE_WINAPI AL_ID('W','A','P','I') + +static ALLEGRO_MOUSE_DRIVER mousedrv_winapi = +{ + MOUSE_WINAPI, + "", + "", + "WinAPI mouse", + init_mouse, + exit_mouse, + get_mouse, + get_num_buttons, + get_num_axes, + set_mouse_xy, + set_mouse_axis, + get_mouse_state +}; + + +_AL_DRIVER_INFO _al_mouse_driver_list[] = +{ + {MOUSE_WINAPI, &mousedrv_winapi, true}, + {0, NULL, 0} +}; + + +void _al_win_mouse_handle_leave(ALLEGRO_DISPLAY_WIN *win_disp) +{ + /* The state should be updated even if the mouse is not installed so that + * it will be correct if the mouse is installed later. + */ + if (mouse_state.display == (void*)win_disp) + mouse_state.display = NULL; + + if (!installed) + return; + + generate_mouse_event(ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + 0, 0, 0, 0, + 0, (void*)win_disp); +} + + +void _al_win_mouse_handle_enter(ALLEGRO_DISPLAY_WIN *win_disp) +{ + /* The state should be updated even if the mouse is not installed so that + * it will be correct if the mouse is installed later. + */ + mouse_state.display = (void*)win_disp; + + if (!installed) + return; + + generate_mouse_event(ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + 0, 0, 0, 0, + 0, (void*)win_disp); +} + + +void _al_win_mouse_handle_move(int x, int y, bool abs, ALLEGRO_DISPLAY_WIN *win_disp) +{ + int dx, dy; + int oldx, oldy; + + oldx = mouse_state.x; + oldy = mouse_state.y; + + if (!installed) + return; + + if (!abs) { + mouse_state.x += x; + mouse_state.y += y; + dx = x; + dy = y; + } + else { + dx = x - mouse_state.x; + dy = y - mouse_state.y; + mouse_state.x = x; + mouse_state.y = y; + } + + if (oldx != mouse_state.x || oldy != mouse_state.y) { + generate_mouse_event(ALLEGRO_EVENT_MOUSE_AXES, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + dx, dy, 0, 0, + 0, (void*)win_disp); + } +} + + +void _al_win_mouse_handle_wheel(int raw_dz, bool abs, ALLEGRO_DISPLAY_WIN *win_disp) +{ + int d; + int new_z; + + if (!installed) + return; + + if (!abs) { + raw_mouse_z += raw_dz; + } + else { + raw_mouse_z = raw_dz; + } + + new_z = al_get_mouse_wheel_precision() * raw_mouse_z / WHEEL_DELTA; + d = new_z - mouse_state.z; + mouse_state.z = new_z; + + generate_mouse_event(ALLEGRO_EVENT_MOUSE_AXES, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + 0, 0, d, 0, + 0, (void*)win_disp); +} + + +void _al_win_mouse_handle_hwheel(int raw_dw, bool abs, ALLEGRO_DISPLAY_WIN *win_disp) +{ + int d; + int new_w; + + if (!installed) + return; + + if (!abs) { + raw_mouse_w += raw_dw; + } + else { + raw_mouse_w = raw_dw; + } + + new_w = al_get_mouse_wheel_precision() * raw_mouse_w / WHEEL_DELTA; + d = new_w - mouse_state.w; + mouse_state.w = new_w; + + generate_mouse_event(ALLEGRO_EVENT_MOUSE_AXES, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + 0, 0, 0, d, + 0, (void*)win_disp); +} + + + +void _al_win_mouse_handle_button(int button, bool down, int x, int y, bool abs, + ALLEGRO_DISPLAY_WIN *win_disp) +{ + int type = down ? ALLEGRO_EVENT_MOUSE_BUTTON_DOWN + : ALLEGRO_EVENT_MOUSE_BUTTON_UP; + + if (!installed) + return; + + if (!abs) { + mouse_state.x += x; + mouse_state.y += y; + } + else { + mouse_state.x = x; + mouse_state.y = y; + } + + if (down) + mouse_state.buttons |= (1 << (button-1)); + else + mouse_state.buttons &= ~(1 << (button-1)); + + mouse_state.pressure = mouse_state.buttons ? 1.0 : 0.0; /* TODO */ + + generate_mouse_event(type, + mouse_state.x, mouse_state.y, mouse_state.z, mouse_state.w, mouse_state.pressure, + 0, 0, 0, 0, + button, (void*)win_disp); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/wsystem.c b/allegro/src/win/wsystem.c new file mode 100644 index 00000000..602aebd9 --- /dev/null +++ b/allegro/src/win/wsystem.c @@ -0,0 +1,974 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New Windows system driver + * + * Based on the X11 OpenGL driver by Elias Pschernig. + * + * Heavily modified by Trent Gamblin. + */ + +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_system.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_wunicode.h" + +#if defined ALLEGRO_CFG_OPENGL + #include "allegro5/allegro_opengl.h" +#endif + +#include +#include + +ALLEGRO_DEBUG_CHANNEL("system") + + +/* FIXME: should we check for psapi _WIN32_IE and shlobj? +{ */ + #include + + #if _WIN32_IE < 0x500 + #undef _WIN32_IE + #define _WIN32_IE 0x500 + #endif + #include + #include +/* } */ + +bool _al_win_disable_screensaver = false; + +static ALLEGRO_SYSTEM_INTERFACE *vt = 0; +static bool using_higher_res_timer; + +static ALLEGRO_SYSTEM_WIN *_al_win_system; + +/* _WinMain: + * Entry point for Windows GUI programs, hooked by a macro in alwin.h, + * which makes it look as if the application can still have a normal + * main() function. + */ +int _WinMain(void *_main, void *hInst, void *hPrev, char *Cmd, int nShow) +{ + int (*mainfunc) (int argc, char *argv[]) = (int (*)(int, char *[]))_main; + char *argbuf; + char **argv; + int argc; + int argc_max; + int i, q; + + (void)hInst; + (void)hPrev; + (void)Cmd; + (void)nShow; + + /* can't use parameter because it doesn't include the executable name */ + argbuf = _twin_tchar_to_utf8(GetCommandLine()); + + argc = 0; + argc_max = 64; + argv = al_malloc(sizeof(char *) * argc_max); + if (!argv) { + al_free(argbuf); + return 1; + } + + i = 0; + + /* parse commandline into argc/argv format */ + while (argbuf[i]) { + while ((argbuf[i]) && (isspace(argbuf[i]))) + i++; + + if (argbuf[i]) { + if ((argbuf[i] == '\'') || (argbuf[i] == '"')) { + q = argbuf[i++]; + if (!argbuf[i]) + break; + } + else + q = 0; + + argv[argc++] = &argbuf[i]; + + if (argc >= argc_max) { + argc_max += 64; + argv = al_realloc(argv, sizeof(char *) * argc_max); + if (!argv) { + al_free(argbuf); + return 1; + } + } + + while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (!isspace(argbuf[i])))) + i++; + + if (argbuf[i]) { + argbuf[i] = 0; + i++; + } + } + } + + argv[argc] = NULL; + + /* call the application entry point */ + i = mainfunc(argc, argv); + + al_free(argv); + al_free(argbuf); + + return i; +} + + +static void set_dpi_awareness(void) +{ + bool dpi_awareness_set = false; + /* We load the shcore DLL and the APIs dynamically because these are + * not often included in MinGW headers. */ + HMODULE shcore_dll = _al_win_safe_load_library("shcore.dll"); + if (shcore_dll) { + typedef enum _AL_PROCESS_DPI_AWARENESS { + AL_PROCESS_DPI_UNAWARE = 0, + AL_PROCESS_SYSTEM_DPI_AWARE = 1, + AL_PROCESS_PER_MONITOR_DPI_AWARE = 2 + } AL_PROCESS_DPI_AWARENESS; + typedef HRESULT (WINAPI *SetProcessDpiAwarenessPROC)(AL_PROCESS_DPI_AWARENESS); + SetProcessDpiAwarenessPROC imp_SetProcessDpiAwareness = + (SetProcessDpiAwarenessPROC)GetProcAddress(shcore_dll, "SetProcessDpiAwareness"); + if (imp_SetProcessDpiAwareness) { + /* Try setting the per-monitor awareness first. It might fail on Win 8.1. */ + HRESULT ret = imp_SetProcessDpiAwareness(AL_PROCESS_PER_MONITOR_DPI_AWARE); + if (ret == E_INVALIDARG) { + ret = imp_SetProcessDpiAwareness(AL_PROCESS_SYSTEM_DPI_AWARE); + } + if (ret == S_OK) { + dpi_awareness_set = true; + } + } + FreeLibrary(shcore_dll); + } + + /* SetProcessDPIAware is an older API that corresponds to system dpi + * awareness above. This is the only option on pre-8.1 systems. */ + if (!dpi_awareness_set) { + HMODULE user32_dll = _al_win_safe_load_library("user32.dll"); + if (user32_dll) { + typedef BOOL (WINAPI *SetProcessDPIAwarePROC)(void); + SetProcessDPIAwarePROC imp_SetProcessDPIAware = + (SetProcessDPIAwarePROC)GetProcAddress(user32_dll, "SetProcessDPIAware"); + if (imp_SetProcessDPIAware) { + imp_SetProcessDPIAware(); + } + FreeLibrary(user32_dll); + } + } +} + + +/* Create a new system object. */ +static ALLEGRO_SYSTEM *win_initialize(int flags) +{ + (void)flags; + + set_dpi_awareness(); + + _al_win_system = al_calloc(1, sizeof *_al_win_system); + + // Request a 1ms resolution from our timer + if (timeBeginPeriod(1) != TIMERR_NOCANDO) { + using_higher_res_timer = true; + } + _al_win_init_time(); + + _al_win_init_window(); + + _al_vector_init(&_al_win_system->system.displays, sizeof (ALLEGRO_SYSTEM_WIN *)); + + _al_win_system->system.vt = vt; + + return &_al_win_system->system; +} + + +static void win_shutdown(void) +{ + ALLEGRO_SYSTEM *s; + ASSERT(vt); + + /* Close all open displays. */ + s = al_get_system_driver(); + while (_al_vector_size(&s->displays) > 0) { + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); + ALLEGRO_DISPLAY *d = *dptr; + al_destroy_display(d); + } + + _al_vector_free(&s->displays); + +#ifdef ALLEGRO_CFG_D3D + _al_d3d_shutdown_display(); +#endif + + _al_win_shutdown_time(); + + if (using_higher_res_timer) { + timeEndPeriod(1); + } + + al_free(vt); + vt = NULL; + + ASSERT(_al_win_system); + al_free(_al_win_system); +} + + +static ALLEGRO_DISPLAY_INTERFACE *win_get_display_driver(void) +{ + const int flags = al_get_new_display_flags(); + ALLEGRO_SYSTEM *sys = al_get_system_driver(); + ALLEGRO_CONFIG *sys_cfg = al_get_system_config(); + ALLEGRO_SYSTEM_WIN *syswin = (ALLEGRO_SYSTEM_WIN *)sys; + const char *s; + + /* Look up the toggle_mouse_grab_key binding. This isn't such a great place + * to do it, but the config file is not available in win_initialize, + * and this is neutral between the D3D and OpenGL display drivers. + */ + if (!syswin->toggle_mouse_grab_keycode) { + const char *binding = al_get_config_value(sys_cfg, "keyboard", + "toggle_mouse_grab_key"); + if (binding) { + syswin->toggle_mouse_grab_keycode = _al_parse_key_binding(binding, + &syswin->toggle_mouse_grab_modifiers); + if (syswin->toggle_mouse_grab_keycode) { + ALLEGRO_DEBUG("Toggle mouse grab key: '%s'\n", binding); + } + else { + ALLEGRO_WARN("Cannot parse key binding '%s'\n", binding); + } + } + } + + /* Programmatic selection. */ +#ifdef ALLEGRO_CFG_D3D + if (flags & ALLEGRO_DIRECT3D_INTERNAL) { + ALLEGRO_DISPLAY_INTERFACE* iface = _al_display_d3d_driver(); + if (iface == NULL) + ALLEGRO_WARN("Direct3D graphics driver not available.\n"); + return iface; + } +#endif +#ifdef ALLEGRO_CFG_OPENGL + if (flags & ALLEGRO_OPENGL) { + return _al_display_wgl_driver(); + } +#endif + + /* Selection by configuration file. The configuration value is non-binding. + * The user may unknowingly set a value which was configured out at compile + * time. The value should have no effect instead of causing a failure. + */ + s = al_get_config_value(sys_cfg, "graphics", "driver"); + if (s) { + ALLEGRO_DEBUG("Configuration value graphics.driver = %s\n", s); + if (0 == _al_stricmp(s, "DIRECT3D") || 0 == _al_stricmp(s, "D3D")) { +#ifdef ALLEGRO_CFG_D3D + ALLEGRO_DISPLAY_INTERFACE* iface = _al_display_d3d_driver(); + if (iface != NULL) { + al_set_new_display_flags(flags | ALLEGRO_DIRECT3D_INTERNAL); + return iface; + } +#endif + } + else if (0 == _al_stricmp(s, "OPENGL")) { +#ifdef ALLEGRO_CFG_OPENGL + al_set_new_display_flags(flags | ALLEGRO_OPENGL); + return _al_display_wgl_driver(); +#endif + } + else if (0 != _al_stricmp(s, "DEFAULT")) { + ALLEGRO_WARN("Graphics driver selection unrecognised: %s\n", s); + } + } + + /* Automatic graphics driver selection. */ + /* XXX is implicitly setting new_display_flags the desired behaviour? */ +#ifdef ALLEGRO_CFG_D3D + { + ALLEGRO_DISPLAY_INTERFACE* iface = _al_display_d3d_driver(); + if (iface != NULL) { + al_set_new_display_flags(flags | ALLEGRO_DIRECT3D_INTERNAL); + return iface; + } + } +#endif +#ifdef ALLEGRO_CFG_OPENGL + { + al_set_new_display_flags(flags | ALLEGRO_OPENGL); + return _al_display_wgl_driver(); + } +#endif + ALLEGRO_WARN("No graphics driver available.\n"); + return NULL; +} + +/* FIXME: use the list */ +static ALLEGRO_KEYBOARD_DRIVER *win_get_keyboard_driver(void) +{ + return _al_keyboard_driver_list[0].driver; +} + + +/* Checks whether the configured joystick driver is of the given name. + * Also returns false if the configuration entry was not set. + */ +static bool win_configured_joystick_driver_is(const char * name) +{ + const char * driver; + ALLEGRO_CONFIG * sysconf = al_get_system_config(); + if (!sysconf) return false; + driver = al_get_config_value(sysconf, "joystick", "driver"); + if (!driver) return false; + ALLEGRO_DEBUG("Configuration value joystick.driver = %s\n", driver); + return (0 == _al_stricmp(driver, name)); +} + + +/* Checks whether xinput should be used or not not according + * to configuration. + */ +static bool win_use_xinput(void) +{ + return win_configured_joystick_driver_is("XINPUT"); +} + +/* Checks whether directinput should be used or not not according + * to configuration. + */ +static bool win_use_directinput(void) +{ + return win_configured_joystick_driver_is("DIRECTINPUT"); +} + + +/* By default the combined xinput/directinput driver is used unless directinput + * or xinput exclusive is set.*/ +static ALLEGRO_JOYSTICK_DRIVER *win_get_joystick_driver(void) +{ + if (win_use_directinput()) { + ALLEGRO_DEBUG("Selected DirectInput joystick driver.\n"); + return &_al_joydrv_directx; + } + + if (win_use_xinput()) { +#ifdef ALLEGRO_CFG_XINPUT + ALLEGRO_DEBUG("Selected XInput joystick driver.\n"); + return &_al_joydrv_xinput; +#else + ALLEGRO_WARN("XInput joystick driver not supported.\n"); +#endif + } + +#ifdef ALLEGRO_CFG_XINPUT + ALLEGRO_DEBUG("Selected combined XInput/DirectInput joystick driver.\n"); + return &_al_joydrv_windows_all; +#else + ALLEGRO_WARN("Combined XInput/DirectInput joystick driver not supported. Usign DirectInput in stead.\n"); + return &_al_joydrv_directx; +#endif +} + +/* By default the combined haptic driver is used unless directinput or + * xinput exclusive is set in the configuration.*/ +static ALLEGRO_HAPTIC_DRIVER *win_get_haptic_driver(void) +{ + if (win_use_directinput()) { + ALLEGRO_DEBUG("Selected DirectInput haptic driver.\n"); + return &_al_hapdrv_directx; + } + + if (win_use_xinput()) { +#ifdef ALLEGRO_CFG_XINPUT + ALLEGRO_DEBUG("Selected XInput haptic driver.\n"); + return &_al_hapdrv_xinput; +#else + ALLEGRO_WARN("XInput haptic driver not supported.\n"); +#endif + } + +#ifdef ALLEGRO_CFG_XINPUT + ALLEGRO_DEBUG("Selected combined XInput/DirectInput haptic driver.\n"); + return &_al_hapdrv_windows_all; +#else + ALLEGRO_WARN("Combined XInput/DirectInput haptic driver not supported. Using DirectInput in stead.\n"); + return &_al_hapdrv_directx; +#endif +} + + +static int win_get_num_display_modes(void) +{ + int format = _al_deduce_color_format(_al_get_new_display_settings()); + int refresh_rate = al_get_new_display_refresh_rate(); + int flags = al_get_new_display_flags(); + +#if defined ALLEGRO_CFG_OPENGL + if (flags & ALLEGRO_OPENGL) { + return _al_wgl_get_num_display_modes(format, refresh_rate, flags); + } +#endif +#if defined ALLEGRO_CFG_D3D + return _al_d3d_get_num_display_modes(format, refresh_rate, flags); +#endif + + return 0; +} + +static ALLEGRO_DISPLAY_MODE *win_get_display_mode(int index, + ALLEGRO_DISPLAY_MODE *mode) +{ + int format = _al_deduce_color_format(_al_get_new_display_settings()); + int refresh_rate = al_get_new_display_refresh_rate(); + int flags = al_get_new_display_flags(); + +#if defined ALLEGRO_CFG_OPENGL + if (flags & ALLEGRO_OPENGL) { + return _al_wgl_get_display_mode(index, format, refresh_rate, flags, mode); + } +#endif +#if defined ALLEGRO_CFG_D3D + return _al_d3d_get_display_mode(index, format, refresh_rate, flags, mode); +#endif + + + return NULL; +} + +static int win_get_num_video_adapters(void) +{ + DISPLAY_DEVICE dd; + int count = 0; + int c = 0; + + memset(&dd, 0, sizeof(dd)); + dd.cb = sizeof(dd); + + while (EnumDisplayDevices(NULL, count, &dd, 0) != false) { + if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) + c++; + count++; + } + + return c; +} + +static int win_find_nth_adapter_with_desktop(DISPLAY_DEVICE* pdd, int adapter) +{ + int count = 0; + int c = 0; + + while (EnumDisplayDevices(NULL, count, pdd, 0)) { + if (pdd->StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { + if (c == adapter) + return true; + c++; + } + count++; + } + + return false; +} + +static int win_get_monitor_refresh_rate(int adapter) +{ + DISPLAY_DEVICE dd; + DEVMODE dm; + + memset(&dd, 0, sizeof(dd)); + dd.cb = sizeof(dd); + if (!win_find_nth_adapter_with_desktop(&dd, adapter)) { + return 0; + } + + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + if (!EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) { + return 0; + } + + return dm.dmDisplayFrequency; +} + +static bool win_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +{ + DISPLAY_DEVICE dd; + DEVMODE dm; + + memset(&dd, 0, sizeof(dd)); + dd.cb = sizeof(dd); + if (!win_find_nth_adapter_with_desktop(&dd, adapter)) { + return false; + } + + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + if (!EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) { + return false; + } + + ASSERT(dm.dmFields & DM_PELSHEIGHT); + ASSERT(dm.dmFields & DM_PELSWIDTH); + /* Disabled this assertion for now as it fails under Wine 1.2. */ + /* ASSERT(dm.dmFields & DM_POSITION); */ + + info->x1 = dm.dmPosition.x; + info->y1 = dm.dmPosition.y; + info->x2 = info->x1 + dm.dmPelsWidth; + info->y2 = info->y1 + dm.dmPelsHeight; + return true; +} + +BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) +{ + HMONITOR *h_monitor = (HMONITOR *) dwData; + + if (hMonitor) { + *h_monitor = hMonitor; + return false; + } + + return true; +} + +static HMONITOR win_get_monitor(ALLEGRO_MONITOR_INFO *info) +{ + HMONITOR h_monitor; + RECT rect; + + rect.left = info->x1; + rect.top = info->y1; + rect.right = info->x2; + rect.bottom = info->y2; + + EnumDisplayMonitors(NULL, &rect, monitor_enum_proc, (LPARAM) &h_monitor); + + return h_monitor; +} + +static int win_get_monitor_dpi(int adapter) +{ + ALLEGRO_MONITOR_INFO info; + HMODULE shcore_dll = _al_win_safe_load_library("shcore.dll"); + int dpi_hori; + int dpi_vert; + + typedef enum _AL_MONITOR_DPI_TYPE { + AL_MDT_EFFECTIVE_DPI = 0, + AL_MDT_ANGULAR_DPI = 1, + AL_MDT_RAW_DPI = 2, + AL_MDT_DEFAULT = AL_MDT_EFFECTIVE_DPI + } AL_MONITOR_DPI_TYPE; + + typedef HRESULT (WINAPI *GetDpiForMonitorPROC)(HMONITOR hmonitor, AL_MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY); + + GetDpiForMonitorPROC imp_GetDpiForMonitor = + (GetDpiForMonitorPROC) GetProcAddress(shcore_dll, "GetDpiForMonitor"); + + if (!shcore_dll) { + FreeLibrary(shcore_dll); + return 0; + } + + if (!win_get_monitor_info(adapter, &info)) { + FreeLibrary(shcore_dll); + return 0; + } + + imp_GetDpiForMonitor(win_get_monitor(&info), 0, &dpi_hori, &dpi_vert); + + FreeLibrary(shcore_dll); + + return sqrt(dpi_hori * dpi_vert); +} + +static bool win_get_cursor_position(int *ret_x, int *ret_y) +{ + POINT p; + GetCursorPos(&p); + *ret_x = p.x; + *ret_y = p.y; + return true; +} + +static bool win_grab_mouse(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_SYSTEM_WIN *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_WIN *win_disp = (void *)display; + RECT rect; + + GetWindowRect(win_disp->window, &rect); + if (ClipCursor(&rect) != 0) { + system->mouse_grab_display = display; + return true; + } + + return false; +} + +static bool win_ungrab_mouse(void) +{ + ALLEGRO_SYSTEM_WIN *system = (void *)al_get_system_driver(); + + ClipCursor(NULL); + system->mouse_grab_display = NULL; + return true; +} + +static ALLEGRO_MOUSE_DRIVER *win_get_mouse_driver(void) +{ + return _al_mouse_driver_list[0].driver; +} + +static ALLEGRO_TOUCH_INPUT_DRIVER *win_get_touch_input_driver(void) +{ + return _al_touch_input_driver_list[0].driver; +} + +/* _al_win_get_path: + * Returns full path to various system and user diretories + */ +ALLEGRO_PATH *_al_win_get_path(int id) +{ + char path[MAX_PATH]; + wchar_t pathw[MAX_PATH]; + ALLEGRO_USTR *pathu; + uint32_t csidl = 0; + HRESULT ret = 0; + ALLEGRO_PATH *cisdl_path = NULL; + + switch (id) { + case ALLEGRO_TEMP_PATH: { + /* Check: TMP, TMPDIR, TEMP or TEMPDIR */ + + DWORD ret = GetTempPathW(MAX_PATH, pathw); + if (ret > MAX_PATH) { + /* should this ever happen, windows is more broken than I ever thought */ + return NULL; + } + pathu = al_ustr_new_from_utf16(pathw); + al_ustr_to_buffer(pathu, path, sizeof path); + al_ustr_free(pathu); + return al_create_path_for_directory(path); + + } break; + + case ALLEGRO_RESOURCES_PATH: { /* where the program is in */ + HANDLE process = GetCurrentProcess(); + char *ptr; + + GetModuleFileNameExW(process, NULL, pathw, MAX_PATH); + pathu = al_ustr_new_from_utf16(pathw); + al_ustr_to_buffer(pathu, path, sizeof path); + al_ustr_free(pathu); + ptr = strrchr(path, '\\'); + if (!ptr) { /* shouldn't happen */ + return NULL; + } + + /* chop off everything including and after the last slash */ + /* should this not chop the slash? */ + *ptr = '\0'; + + return al_create_path_for_directory(path); + } break; + + case ALLEGRO_USER_DATA_PATH: /* CSIDL_APPDATA */ + case ALLEGRO_USER_SETTINGS_PATH: + csidl = CSIDL_APPDATA; + break; + + case ALLEGRO_USER_HOME_PATH: /* CSIDL_PROFILE */ + csidl = CSIDL_PROFILE; + break; + + case ALLEGRO_USER_DOCUMENTS_PATH: /* CSIDL_PERSONAL */ + csidl = CSIDL_PERSONAL; + break; + + case ALLEGRO_EXENAME_PATH: { /* full path to the exe including its name */ + HANDLE process = GetCurrentProcess(); + + GetModuleFileNameExW(process, NULL, pathw, MAX_PATH); + pathu = al_ustr_new_from_utf16(pathw); + al_ustr_to_buffer(pathu, path, sizeof path); + al_ustr_free(pathu); + + return al_create_path(path); + } break; + + default: + return NULL; + } + + ret = SHGetFolderPathW(NULL, csidl, NULL, SHGFP_TYPE_CURRENT, pathw); + if (ret != S_OK) { + return NULL; + } + + pathu = al_ustr_new_from_utf16(pathw); + al_ustr_to_buffer(pathu, path, sizeof path); + al_ustr_free(pathu); + + cisdl_path = al_create_path_for_directory(path); + if (!cisdl_path) + return NULL; + + if (csidl == CSIDL_APPDATA) { + const char *org_name = al_get_org_name(); + const char *app_name = al_get_app_name(); + + if (!app_name || !app_name[0]) { + /* this shouldn't ever happen. */ + al_destroy_path(cisdl_path); + return NULL; + } + + if (org_name && org_name[0]) { + al_append_path_component(cisdl_path, org_name); + } + + al_append_path_component(cisdl_path, app_name); + } + + return cisdl_path; +} + +static bool win_inhibit_screensaver(bool inhibit) +{ + _al_win_disable_screensaver = inhibit; + return true; +} + +static HMODULE load_library_at_path(const TCHAR *path_str) +{ + HMODULE lib; + + /* + * XXX LoadLibrary will search the current directory for any dependencies of + * the library we are loading. Using LoadLibraryEx with the appropriate + * flags would fix that, but when I tried it I was unable to load dsound.dll + * on Vista. + */ + char* upath_str = _twin_tchar_to_utf8(path_str); + ALLEGRO_DEBUG("Calling LoadLibrary %s\n", upath_str); + lib = LoadLibrary(path_str); + if (lib) { + ALLEGRO_INFO("Loaded %s\n", upath_str); + } + else { + DWORD error = GetLastError(); + HRESULT hr = HRESULT_FROM_WIN32(error); + /* XXX do something with it */ + (void)hr; + ALLEGRO_WARN("Failed to load %s (error: %ld)\n", upath_str, error); + } + al_free(upath_str); + return lib; +} + +static bool is_build_config_name(const char *s) +{ + return s && + ( 0 == strcmp(s, "Debug") + || 0 == strcmp(s, "Release") + || 0 == strcmp(s, "RelWithDebInfo") + || 0 == strcmp(s, "Profile")); +} + +static ALLEGRO_PATH *maybe_parent_dir(const ALLEGRO_PATH *path) +{ + ALLEGRO_PATH *path2; + + if (!path) + return NULL; + + if (!is_build_config_name(al_get_path_tail(path))) + return NULL; + + path2 = al_clone_path(path); + if (path2) { + al_drop_path_tail(path2); + al_set_path_filename(path2, NULL); + ALLEGRO_DEBUG("Also searching %s\n", al_path_cstr(path2, '\\')); + } + + return path2; +} + +/* + * Calling LoadLibrary with a relative file name is a security risk: + * see e.g. Microsoft Security Advisory (2269637) + * "Insecure Library Loading Could Allow Remote Code Execution" + */ +HMODULE _al_win_safe_load_library(const char *filename) +{ + ALLEGRO_PATH *path1 = NULL; + ALLEGRO_PATH *path2 = NULL; + TCHAR buf[MAX_PATH]; + const TCHAR *other_dirs[3]; + HMODULE lib = NULL; + bool msvc_only = false; + TCHAR* tfilename; + + /* MSVC only: if the executable is in the build configuration directory, + * which is also just under the current directory, then also try to load the + * library from the current directory. This leads to less surprises when + * running example programs. + */ +#if defined(ALLEGRO_MSVC) + msvc_only = true; +#endif + + /* Try to load the library from the directory containing the running + * executable, the Windows system directories, or directories on the PATH. + * Do NOT try to load the library from the current directory. + */ + + if (al_is_system_installed()) { + path1 = al_get_standard_path(ALLEGRO_RESOURCES_PATH); + } + else if (GetModuleFileName(NULL, buf, sizeof(buf)) < sizeof(buf)) { + char* tmp = _twin_tchar_to_utf8(buf); + path1 = al_create_path(tmp); + al_free(tmp); + } + if (msvc_only) { + path2 = maybe_parent_dir(path1); + } + + other_dirs[0] = path1 ? _twin_ustr_to_tchar(al_path_ustr(path1, '\\')) : NULL; + other_dirs[1] = path2 ? _twin_ustr_to_tchar(al_path_ustr(path2, '\\')) : NULL; + other_dirs[2] = NULL; /* sentinel */ + tfilename = _twin_utf8_to_tchar(filename); + _tcsncpy(buf, tfilename, MAX_PATH); + al_free(tfilename); + if (PathFindOnPath(buf, other_dirs)) { + char* tmp = _twin_tchar_to_utf8(buf); + ALLEGRO_DEBUG("PathFindOnPath found: %s\n", tmp); + al_free(tmp); + lib = load_library_at_path(buf); + } + else { + ALLEGRO_WARN("PathFindOnPath failed to find %s\n", filename); + } + al_free((void*) other_dirs[0]); + al_free((void*) other_dirs[1]); + al_destroy_path(path1); + al_destroy_path(path2); + + return lib; +} + +static void *win_open_library(const char *filename) +{ + return _al_win_safe_load_library(filename); +} + +static void *win_import_symbol(void *library, const char *symbol) +{ + ASSERT(library); + return GetProcAddress(library, symbol); +} + +static void win_close_library(void *library) +{ + ASSERT(library); + FreeLibrary(library); +} + +static ALLEGRO_SYSTEM_INTERFACE *_al_system_win_driver(void) +{ + if (vt) return vt; + + vt = al_calloc(1, sizeof *vt); + + vt->id = ALLEGRO_SYSTEM_ID_WINDOWS; + vt->initialize = win_initialize; + vt->get_display_driver = win_get_display_driver; + vt->get_keyboard_driver = win_get_keyboard_driver; + vt->get_mouse_driver = win_get_mouse_driver; + vt->get_touch_input_driver = win_get_touch_input_driver; + vt->get_haptic_driver = win_get_haptic_driver; + vt->get_joystick_driver = win_get_joystick_driver; + vt->get_num_display_modes = win_get_num_display_modes; + vt->get_display_mode = win_get_display_mode; + vt->shutdown_system = win_shutdown; + vt->get_num_video_adapters = win_get_num_video_adapters; + vt->create_mouse_cursor = _al_win_create_mouse_cursor; + vt->destroy_mouse_cursor = _al_win_destroy_mouse_cursor; + vt->get_monitor_info = win_get_monitor_info; + vt->get_monitor_dpi = win_get_monitor_dpi; + vt->get_monitor_refresh_rate = win_get_monitor_refresh_rate; + vt->get_cursor_position = win_get_cursor_position; + vt->grab_mouse = win_grab_mouse; + vt->ungrab_mouse = win_ungrab_mouse; + vt->get_path = _al_win_get_path; + vt->inhibit_screensaver = win_inhibit_screensaver; + vt->open_library = win_open_library; + vt->import_symbol = win_import_symbol; + vt->close_library = win_close_library; + vt->get_time = _al_win_get_time; + vt->rest = _al_win_rest; + vt->init_timeout = _al_win_init_timeout; + + return vt; +} + +void _al_register_system_interfaces() +{ + ALLEGRO_SYSTEM_INTERFACE **add; + + add = _al_vector_alloc_back(&_al_system_interfaces); + *add = _al_system_win_driver(); +} + +const char* _al_win_error(DWORD err) { + LPTSTR msg = NULL; + int len; + static char buf[2048]; + + len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, err, 0, (LPTSTR)&msg, 0, NULL); + if (len == 0) { + _al_sane_strncpy(buf, "(Unable to decode the error code)", sizeof(buf)); + } + else { + /* Truncate trailing CRLF if it has one */ + if (len >= 2 && _tcscmp(msg + len - 2, TEXT("\r\n")) == 0) { + msg[len - 2] = (TCHAR)0; + } + _twin_copy_tchar_to_utf8(buf, msg, sizeof(buf)); + LocalFree(msg); + } + return buf; +} +const char* _al_win_last_error() { + return _al_win_error(GetLastError()); +} +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/wthread.c b/allegro/src/win/wthread.c new file mode 100644 index 00000000..4e2972e1 --- /dev/null +++ b/allegro/src/win/wthread.c @@ -0,0 +1,87 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Thread management. + * + * By Stefan Schimanski. + * + * Synchronization functions added by Eric Botcazou. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/platform/aintwin.h" + +#include + +#ifndef ALLEGRO_WINDOWS +#error something is wrong with the makefile +#endif + +ALLEGRO_DEBUG_CHANNEL("system") + + +/* COINIT_MULTITHREADED is not defined in objbase.h for MSVC */ +#define _COINIT_MULTITHREADED 0 + +typedef HRESULT(CALLBACK * _CoInitializeEx_ptr) (LPVOID, DWORD); +static _CoInitializeEx_ptr _CoInitializeEx = NULL; +static int first_call = 1; + + + +/* _al_win_thread_init: + * Initializes COM interface for the calling thread. + * Attempts to use Distributed COM if available (installed by default + * on every 32-bit Windows starting with Win98 and Win NT4). + */ +void _al_win_thread_init(void) +{ + HMODULE ole32 = NULL; + + if (first_call) { + first_call = 0; + + ole32 = GetModuleHandle(TEXT("OLE32.DLL")); + if (ole32 != NULL) { + _CoInitializeEx = (_CoInitializeEx_ptr) GetProcAddress( + ole32, "CoInitializeEx"); + } + else { + ALLEGRO_WARN("OLE32.DLL can't be loaded.\n"); + } + + if (_CoInitializeEx == NULL) { + ALLEGRO_WARN("Microsoft Distributed COM is not installed on this system. If you have problems "); + ALLEGRO_WARN("with this application, please install the DCOM update. You can find it on the "); + ALLEGRO_WARN("Microsoft homepage\n"); + } + } + + if (_CoInitializeEx != NULL) + _CoInitializeEx(NULL, _COINIT_MULTITHREADED); + else + CoInitialize(NULL); +} + + + +/* _al_win_thread_exit: + * Shuts down COM interface for the calling thread. + */ +void _al_win_thread_exit(void) +{ + CoUninitialize(); +} + + diff --git a/allegro/src/win/wtime.c b/allegro/src/win/wtime.c new file mode 100644 index 00000000..9d3f7463 --- /dev/null +++ b/allegro/src/win/wtime.c @@ -0,0 +1,146 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows time module. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_thread.h" +#include "allegro5/platform/aintwin.h" + +#include + +ALLEGRO_STATIC_ASSERT(wtime, + sizeof(ALLEGRO_TIMEOUT_WIN) <= sizeof(ALLEGRO_TIMEOUT)); + + +#define LARGE_INTEGER_TO_INT64(li) (((int64_t)li.HighPart << 32) | \ + (int64_t)li.LowPart) + +static int64_t high_res_timer_freq; +static int64_t _al_win_prev_time; +static double _al_win_total_time; + +static double (*real_get_time_func)(void); + +static _AL_MUTEX time_mutex = _AL_MUTEX_UNINITED; + + +static double low_res_current_time(void) +{ + int64_t cur_time; + double ellapsed_time; + + _al_mutex_lock(&time_mutex); + + cur_time = (int64_t) timeGetTime(); + ellapsed_time = (double) (cur_time - _al_win_prev_time) / 1000; + + if (cur_time < _al_win_prev_time) { + ellapsed_time += 4294967.295; + } + + _al_win_total_time += ellapsed_time; + _al_win_prev_time = cur_time; + + _al_mutex_unlock(&time_mutex); + + return _al_win_total_time; +} + + +static double high_res_current_time(void) +{ + LARGE_INTEGER count; + int64_t cur_time; + double ellapsed_time; + + _al_mutex_lock(&time_mutex); + + QueryPerformanceCounter(&count); + + cur_time = LARGE_INTEGER_TO_INT64(count); + ellapsed_time = (double)(cur_time - _al_win_prev_time) / (double)high_res_timer_freq; + + _al_win_total_time += ellapsed_time; + _al_win_prev_time = cur_time; + + _al_mutex_unlock(&time_mutex); + + return _al_win_total_time; +} + + +double _al_win_get_time(void) +{ + return (*real_get_time_func)(); +} + + +void _al_win_init_time(void) +{ + LARGE_INTEGER tmp_freq; + _al_win_total_time = 0; + + _al_mutex_init(&time_mutex); + + if (QueryPerformanceFrequency(&tmp_freq) == 0) { + real_get_time_func = low_res_current_time; + _al_win_prev_time = (int64_t) timeGetTime(); + } + else { + LARGE_INTEGER count; + high_res_timer_freq = LARGE_INTEGER_TO_INT64(tmp_freq); + real_get_time_func = high_res_current_time; + QueryPerformanceCounter(&count); + _al_win_prev_time = LARGE_INTEGER_TO_INT64(count); + } +} + + + +void _al_win_shutdown_time(void) +{ + _al_mutex_destroy(&time_mutex); +} + + + +void _al_win_rest(double seconds) +{ + if (seconds <= 0) + return; + + Sleep((DWORD)(seconds * 1000.0)); +} + + + +void _al_win_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds) +{ + ALLEGRO_TIMEOUT_WIN *wt = (ALLEGRO_TIMEOUT_WIN *) timeout; + + ASSERT(wt); + ASSERT(seconds <= INT_MAX/1000.0); + + if (seconds <= 0.0) { + wt->abstime = timeGetTime(); + } + else { + wt->abstime = timeGetTime() + (DWORD)(seconds * 1000.0); + } +} + +/* vim: set sts=3 sw=3 et */ diff --git a/allegro/src/win/wtouch_input.c b/allegro/src/win/wtouch_input.c new file mode 100644 index 00000000..21b6fa00 --- /dev/null +++ b/allegro/src/win/wtouch_input.c @@ -0,0 +1,421 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows touch input driver. + * + * By Michał Cichoń. + * + * See readme.txt for copyright information. + */ + +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_driver.h" +#include "allegro5/internal/aintern_touch_input.h" +#include "allegro5/platform/aintwin.h" +#include "allegro5/internal/aintern_display.h" + +ALLEGRO_DEBUG_CHANNEL("touch") + +static ALLEGRO_TOUCH_INPUT_STATE touch_input_state; +static ALLEGRO_TOUCH_INPUT touch_input; +static bool installed = false; +static size_t initiali_time_stamp = ~0; + + +/* WinAPI import related stuff. */ +static int touch_input_api_reference_counter = 0; +static void* user32_module = NULL; + +CLOSETOUCHINPUTHANDLEPROC _al_win_close_touch_input_handle = NULL; +GETTOUCHINPUTINFOPROC _al_win_get_touch_input_info = NULL; +ISTOUCHWINDOWPROC _al_win_is_touch_window = NULL; +REGISTERTOUCHWINDOWPROC _al_win_register_touch_window = NULL; +UNREGISTERTOUCHWINDOWPROC _al_win_unregister_touch_window = NULL; + +bool _al_win_init_touch_input_api(void) +{ + /* Reference counter will be negative if we already tried to initialize the driver. + * Lack of touch input API is persistent state, so do not test for it again. */ + if (touch_input_api_reference_counter < 0) + return false; + + /* Increase API reference counter if it is already initialized. */ + if (touch_input_api_reference_counter > 0) + { + touch_input_api_reference_counter++; + return true; + } + + /* Open handle to user32.dll. This one should be always present. */ + user32_module = _al_open_library("user32.dll"); + if (NULL == user32_module) + return false; + + _al_win_close_touch_input_handle = (CLOSETOUCHINPUTHANDLEPROC)_al_import_symbol(user32_module, "CloseTouchInputHandle"); + _al_win_get_touch_input_info = (GETTOUCHINPUTINFOPROC) _al_import_symbol(user32_module, "GetTouchInputInfo"); + _al_win_is_touch_window = (ISTOUCHWINDOWPROC) _al_import_symbol(user32_module, "IsTouchWindow"); + _al_win_register_touch_window = (REGISTERTOUCHWINDOWPROC) _al_import_symbol(user32_module, "RegisterTouchWindow"); + _al_win_unregister_touch_window = (UNREGISTERTOUCHWINDOWPROC)_al_import_symbol(user32_module, "UnregisterTouchWindow"); + + if (NULL == _al_win_close_touch_input_handle || NULL == _al_win_get_touch_input_info || + NULL == _al_win_is_touch_window || NULL == _al_win_register_touch_window || + NULL == _al_win_unregister_touch_window) { + + _al_close_library(user32_module); + + _al_win_close_touch_input_handle = NULL; + _al_win_get_touch_input_info = NULL; + _al_win_is_touch_window = NULL; + _al_win_register_touch_window = NULL; + _al_win_unregister_touch_window = NULL; + + /* Mark as 'do not try this again'. */ + touch_input_api_reference_counter = -1; + ALLEGRO_WARN("failed loading the touch input API\n"); + return false; + } + + /* Set initial reference count. */ + touch_input_api_reference_counter = 1; + ALLEGRO_INFO("touch input API installed successfully\n"); + return true; +} + +void _al_win_exit_touch_input_api(void) +{ + if (touch_input_api_reference_counter > 1) + { + --touch_input_api_reference_counter; + return; + } + + if (touch_input_api_reference_counter != 1) + return; + + _al_close_library(user32_module); + + _al_win_close_touch_input_handle = NULL; + _al_win_get_touch_input_info = NULL; + _al_win_is_touch_window = NULL; + _al_win_register_touch_window = NULL; + _al_win_unregister_touch_window = NULL; + + touch_input_api_reference_counter = 0; +} + + +/* Actual driver implementation. */ + +static void generate_touch_input_event(int type, double timestamp, int id, float x, float y, float dx, float dy, bool primary, ALLEGRO_DISPLAY_WIN *win_disp) +{ + ALLEGRO_EVENT event; + + bool want_touch_event = _al_event_source_needs_to_generate_event(&touch_input.es); + bool want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input.mouse_emulation_es) && primary && al_is_mouse_installed(); + + if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_NONE) + want_mouse_emulation_event = false; + else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_INCLUSIVE) + want_touch_event = want_mouse_emulation_event ? (want_touch_event && !primary) : want_touch_event; + else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_EXCLUSIVE) + want_touch_event = want_mouse_emulation_event ? false : want_touch_event; + + if (!want_touch_event && !want_mouse_emulation_event) + return; + + if (want_touch_event) { + + event.touch.type = type; + event.touch.display = (ALLEGRO_DISPLAY*)win_disp; + event.touch.timestamp = timestamp; + event.touch.id = id; + event.touch.x = x; + event.touch.y = y; + event.touch.dx = dx; + event.touch.dy = dy; + event.touch.primary = primary; + + _al_event_source_lock(&touch_input.es); + _al_event_source_emit_event(&touch_input.es, &event); + _al_event_source_unlock(&touch_input.es); + } + + if (want_mouse_emulation_event) { + + ALLEGRO_MOUSE_STATE state; + + switch (type) { + case ALLEGRO_EVENT_TOUCH_BEGIN: type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; break; + case ALLEGRO_EVENT_TOUCH_CANCEL: + case ALLEGRO_EVENT_TOUCH_END: type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; break; + case ALLEGRO_EVENT_TOUCH_MOVE: type = ALLEGRO_EVENT_MOUSE_AXES; break; + } + + al_get_mouse_state(&state); + + event.mouse.type = type; + event.mouse.timestamp = timestamp; + event.mouse.display = (ALLEGRO_DISPLAY*)win_disp; + event.mouse.x = (int)x; + event.mouse.y = (int)y; + event.mouse.z = state.z; + event.mouse.w = state.w; + event.mouse.dx = (int)dx; + event.mouse.dy = (int)dy; + event.mouse.dz = 0; + event.mouse.dw = 0; + event.mouse.button = 1; + event.mouse.pressure = state.pressure; + + al_set_mouse_xy(event.mouse.display, event.mouse.x, event.mouse.y); + + _al_event_source_lock(&touch_input.mouse_emulation_es); + _al_event_source_emit_event(&touch_input.mouse_emulation_es, &event); + _al_event_source_unlock(&touch_input.mouse_emulation_es); + } +} + +static bool init_touch_input(void) +{ + unsigned i; + ALLEGRO_SYSTEM* system; + + if (installed) + return false; + + if (!_al_win_init_touch_input_api()) + return false; + + memset(&touch_input_state, 0, sizeof(touch_input_state)); + + _al_event_source_init(&touch_input.es); + _al_event_source_init(&touch_input.mouse_emulation_es); + + touch_input.mouse_emulation_mode = ALLEGRO_MOUSE_EMULATION_TRANSPARENT; + + installed = true; + + system = al_get_system_driver(); + for (i = 0; i < _al_vector_size(&system->displays); ++i) { + bool r; + ALLEGRO_DISPLAY_WIN *win_display = *((ALLEGRO_DISPLAY_WIN**)_al_vector_ref(&system->displays, i)); + r = _al_win_register_touch_window(win_display->window, 0); + ALLEGRO_INFO("registering touch window %p: %d\n", win_display, r); + if (!r) { + ALLEGRO_ERROR("RegisterTouchWindow failed: %s\n", _al_win_last_error()); + return false; + } + } + + return true; +} + + +static void exit_touch_input(void) +{ + if (!installed) + return; + + memset(&touch_input_state, 0, sizeof(touch_input_state)); + + _al_event_source_free(&touch_input.es); + _al_event_source_free(&touch_input.mouse_emulation_es); + + _al_win_exit_touch_input_api(); + + installed = false; +} + + +static ALLEGRO_TOUCH_INPUT* get_touch_input(void) +{ + return &touch_input; +} + + +static void get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state) +{ + _al_event_source_lock(&touch_input.es); + *ret_state = touch_input_state; + _al_event_source_unlock(&touch_input.es); +} + + +static void set_mouse_emulation_mode(int mode) +{ + if (touch_input.mouse_emulation_mode != mode) { + + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) { + + ALLEGRO_TOUCH_STATE* touch = touch_input_state.touches + i; + + if (touch->id > 0) { + _al_win_touch_input_handle_cancel(touch->id, initiali_time_stamp, + touch->x, touch->y, touch->primary, (ALLEGRO_DISPLAY_WIN*)touch->display); + } + } + + touch_input.mouse_emulation_mode = mode; + } +} + + +static ALLEGRO_TOUCH_STATE* find_free_touch_state(void) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) + if (touch_input_state.touches[i].id <= 0) + return touch_input_state.touches + i; + + return NULL; +} + + +static ALLEGRO_TOUCH_STATE* find_touch_state_with_id(int id) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; ++i) + if (touch_input_state.touches[i].id == id) + return touch_input_state.touches + i; + + return NULL; +} + + +static double get_time_stamp(size_t timestamp) +{ + return al_get_time() - ((timestamp - initiali_time_stamp) / 1000.0); +} + + +void _al_win_touch_input_set_time_stamp(size_t timestamp) +{ + if (initiali_time_stamp != (size_t)~0) + initiali_time_stamp = timestamp; +} + + +void _al_win_touch_input_handle_begin(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp) +{ + ALLEGRO_TOUCH_STATE* state = find_free_touch_state(); + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->id = id; + state->x = x; + state->y = y; + state->dx = 0.0f; + state->dy = 0.0f; + state->primary = primary; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_BEGIN, get_time_stamp(timestamp), + state->id, state->x, state->y, state->dx, state->dy, state->primary, win_disp); +} + + +void _al_win_touch_input_handle_end(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp) +{ + ALLEGRO_TOUCH_STATE* state; + (void)primary; + + state = find_touch_state_with_id(id); + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_END, get_time_stamp(timestamp), + state->id, state->x, state->y, state->dx, state->dy, state->primary, win_disp); + + _al_event_source_lock(&touch_input.es); + memset(state, 0, sizeof(ALLEGRO_TOUCH_STATE)); + _al_event_source_unlock(&touch_input.es); +} + + +void _al_win_touch_input_handle_move(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp) +{ + ALLEGRO_TOUCH_STATE* state; + (void)primary; + + state = find_touch_state_with_id(id); + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_MOVE, get_time_stamp(timestamp), + state->id, state->x, state->y, state->dx, state->dy, state->primary, win_disp); +} + + +void _al_win_touch_input_handle_cancel(int id, size_t timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY_WIN *win_disp) +{ + ALLEGRO_TOUCH_STATE* state; + (void)primary; + + state = find_touch_state_with_id(id); + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_CANCEL, get_time_stamp(timestamp), + state->id, state->x, state->y, state->dx, state->dy, state->primary, win_disp); + + _al_event_source_lock(&touch_input.es); + memset(state, 0, sizeof(ALLEGRO_TOUCH_STATE)); + _al_event_source_unlock(&touch_input.es); +} + + +/* the driver vtable */ +#define TOUCH_INPUT_WINAPI AL_ID('W','T','I','D') + +static ALLEGRO_TOUCH_INPUT_DRIVER touch_input_driver = +{ + TOUCH_INPUT_WINAPI, + init_touch_input, + exit_touch_input, + get_touch_input, + get_touch_input_state, + set_mouse_emulation_mode, + NULL +}; + +_AL_DRIVER_INFO _al_touch_input_driver_list[] = +{ + {TOUCH_INPUT_WINAPI, &touch_input_driver, true}, + {0, NULL, 0} +}; diff --git a/allegro/src/win/wunicode.c b/allegro/src/win/wunicode.c new file mode 100644 index 00000000..c5df0729 --- /dev/null +++ b/allegro/src/win/wunicode.c @@ -0,0 +1,335 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Windows "UNICODE" helper routines. + * + * See LICENSE.txt for copyright information. + */ + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_wunicode.h" + +#include + +ALLEGRO_DEBUG_CHANNEL("wunicode") + +/* _al_win_ustr_to_utf16: + * Convert ALLEGRO_USTR to newly-allocated UTF-16 buffer + */ +wchar_t *_al_win_ustr_to_utf16(const ALLEGRO_USTR *u) +{ + int wslen; + wchar_t *ws; + const char* us = al_cstr(u); + size_t uslen = al_ustr_size(u); + + if (uslen == 0) { + ws = al_malloc(sizeof(wchar_t)); + ws[0] = 0; + return ws; + } + wslen = MultiByteToWideChar(CP_UTF8, 0, us, uslen, NULL, 0); + if (wslen == 0) { + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + /* For the NUL at the end. */ + wslen += 1; + ws = al_malloc(sizeof(wchar_t) * wslen); + if (!ws) { + ALLEGRO_ERROR("Out of memory\n"); + return NULL; + } + if (0 == MultiByteToWideChar(CP_UTF8, 0, us, uslen, ws, wslen)) { + al_free(ws); + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + ws[wslen - 1] = 0; + return ws; +} + +/* _al_win_utf8_to_ansi: + * Convert UTF-8 to newly-allocated ansi buffer + */ +char* _al_win_ustr_to_ansi(const ALLEGRO_USTR *u) { + int wslen; + wchar_t *ws; + int slen; + char *s; + const char* us = al_cstr(u); + size_t uslen = al_ustr_size(u); + + if (uslen == 0) { + s = al_malloc(sizeof(char)); + s[0] = 0; + return s; + } + wslen = MultiByteToWideChar(CP_UTF8, 0, us, uslen, NULL, 0); + if (wslen == 0) { + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + ws = al_malloc(sizeof(wchar_t) * wslen); + if (!ws) { + ALLEGRO_ERROR("Out of memory\n"); + return NULL; + } + if (0 == MultiByteToWideChar(CP_UTF8, 0, us, uslen, ws, wslen)) { + al_free(ws); + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + slen = WideCharToMultiByte(CP_ACP, 0, ws, wslen, NULL, 0, NULL, NULL); + if (slen == 0) { + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + al_free(ws); + return NULL; + } + /* For the NUL at the end. */ + slen += 1; + s = al_malloc(sizeof(char) * slen); + if (!s) { + ALLEGRO_ERROR("Out of memory\n"); + al_free(ws); + return NULL; + } + if (0 == WideCharToMultiByte(CP_ACP, 0, ws, wslen, s, slen, NULL, NULL)) { + al_free(ws); + al_free(s); + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + return NULL; + } + s[slen - 1] = 0; + al_free(ws); + return s; +} + +/* _al_win_utf8_to_utf16: + * Convert UTF-8 to newly-allocated UTF-16 buffer + */ +wchar_t *_al_win_utf8_to_utf16(const char *us) +{ + int wslen; + wchar_t *ws; + + if (us == NULL) { + return NULL; + } + wslen = MultiByteToWideChar(CP_UTF8, 0, us, -1, NULL, 0); + if (wslen == 0) { + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + ws = al_malloc(sizeof(wchar_t) * wslen); + if (!ws) { + ALLEGRO_ERROR("Out of memory\n"); + return NULL; + } + if (0 == MultiByteToWideChar(CP_UTF8, 0, us, -1, ws, wslen)) { + al_free(ws); + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + return ws; +} + +/* _al_win_utf16_to_utf8: + * Convert UTF-16 to newly-allocated UTF-8 buffer + */ +char *_al_win_utf16_to_utf8(const wchar_t *ws) +{ + int uslen; + char *us; + + if (ws == NULL) { + return NULL; + } + uslen = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL); + if (uslen == 0) { + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + return NULL; + } + us = al_malloc(sizeof(char) * uslen); + if (!us) { + ALLEGRO_ERROR("Out of memory\n"); + return NULL; + } + if (0 == WideCharToMultiByte(CP_UTF8, 0, ws, -1, us, uslen, NULL, NULL)) { + al_free(us); + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + return NULL; + } + return us; +} +/* _al_win_utf8_to_ansi: + * Convert UTF-8 to newly-allocated ansi buffer + */ +char* _al_win_utf8_to_ansi(const char *us) { + int wslen; + wchar_t *ws; + int slen; + char *s; + + if (us == NULL) { + return NULL; + } + wslen = MultiByteToWideChar(CP_UTF8, 0, us, -1, NULL, 0); + if (wslen == 0) { + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + ws = al_malloc(sizeof(wchar_t) * wslen); + if (!ws) { + ALLEGRO_ERROR("Out of memory\n"); + return NULL; + } + if (0 == MultiByteToWideChar(CP_UTF8, 0, us, -1, ws, wslen)) { + al_free(ws); + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + slen = WideCharToMultiByte(CP_ACP, 0, ws, -1, NULL, 0, NULL, NULL); + if (slen == 0) { + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + al_free(ws); + return NULL; + } + s = al_malloc(sizeof(char) * slen); + if (!s) { + ALLEGRO_ERROR("Out of memory\n"); + al_free(ws); + return NULL; + } + if (0 == WideCharToMultiByte(CP_ACP, 0, ws, -1, s, slen, NULL, NULL)) { + al_free(ws); + al_free(s); + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + return NULL; + } + al_free(ws); + return s; +} + +/* _al_win_ansi_to_utf8: + * Convert ansi to newly-allocated UTF-8 buffer + */ +char* _al_win_ansi_to_utf8(const char *s) { + int wslen; + wchar_t *ws; + int uslen; + char *us; + + if (s == NULL) { + return NULL; + } + wslen = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0); + if (wslen == 0) { + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + ws = al_malloc(sizeof(wchar_t) * wslen); + if (!ws) { + ALLEGRO_ERROR("Out of memory\n"); + return NULL; + } + if (0 == MultiByteToWideChar(CP_ACP, 0, s, -1, ws, wslen)) { + al_free(ws); + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + uslen = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL); + if (uslen == 0) { + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + al_free(ws); + return NULL; + } + us = al_malloc(sizeof(char) * uslen); + if (!s) { + ALLEGRO_ERROR("Out of memory\n"); + al_free(ws); + return NULL; + } + if (0 == WideCharToMultiByte(CP_UTF8, 0, ws, -1, us, uslen, NULL, NULL)) { + al_free(ws); + al_free(us); + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + return NULL; + } + al_free(ws); + return us; +} + +/* _al_win_copy_utf16_to_utf8: Copy string and convert to UTF-8. + * This takes a string and copies a UTF-8 version of it to + * a buffer of fixed size. + * If successful, the string will be zero-terminated and is + * the return value of the function. + * If unsuccesful, NULL will be returned. + * If the representation would overflow the buffer, nothing + * is copied and the return value is NULL. + */ +char *_al_win_copy_utf16_to_utf8(char* us, const wchar_t *ws, size_t uslen) +{ + int rc = WideCharToMultiByte(CP_UTF8, 0, ws, -1, us, uslen, NULL, NULL); + if (rc == 0) { + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + return NULL; + } + return us; +} + +char *_al_win_copy_utf8_to_ansi(char* s, const char *us, size_t slen) +{ + int wslen = MultiByteToWideChar(CP_UTF8, 0, us, -1, NULL, 0); + if (wslen == 0) { + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + wchar_t* ws = al_malloc(wslen * sizeof(wchar_t)); + if (!ws) { + ALLEGRO_ERROR("Out of memory\n"); + return NULL; + } + MultiByteToWideChar(CP_UTF8, 0, us, -1, ws, wslen); + int rc = WideCharToMultiByte(CP_ACP, 0, ws, wslen, s, slen, NULL, NULL); + al_free(ws); + if (rc == 0) { + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + return NULL; + } + return s; +} + +char *_al_win_copy_ansi_to_utf8(char* us, const char *s, size_t uslen) +{ + int wslen = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0); + if (wslen == 0) { + ALLEGRO_ERROR("MultiByteToWideChar failed\n"); + return NULL; + } + wchar_t* ws = al_malloc(wslen * sizeof(wchar_t)); + if (!ws) { + ALLEGRO_ERROR("Out of memory\n"); + return NULL; + } + MultiByteToWideChar(CP_ACP, 0, s, -1, ws, wslen); + int rc = WideCharToMultiByte(CP_UTF8, 0, ws, wslen, us, uslen, NULL, NULL); + al_free(ws); + if (rc == 0) { + ALLEGRO_ERROR("WideCharToMultiByte failed\n"); + return NULL; + } + return us; +} + + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/win/wwindow.c b/allegro/src/win/wwindow.c new file mode 100644 index 00000000..75104f12 --- /dev/null +++ b/allegro/src/win/wwindow.c @@ -0,0 +1,1465 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * New Windows window handling + * + * By Trent Gamblin. + * + */ + +/* Raw input */ +#define _WIN32_WINNT 0x0501 +#ifndef WINVER +#define WINVER 0x0501 +#endif + +#include +#include +#include +#include +#include + +/* Only used for Vista and up. */ +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif + +#include +#include + +#include "allegro5/allegro_windows.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_vector.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_wunicode.h" +#include "allegro5/internal/aintern_joystick.h" +#include "allegro5/internal/aintern_wjoydxnu.h" +#include "allegro5/platform/aintwin.h" + + +ALLEGRO_DEBUG_CHANNEL("wwindow") + +static WNDCLASS window_class; + +static bool resize_postponed = false; +static bool we_hid_the_mouse = false; + + +UINT _al_win_msg_call_proc = 0; +UINT _al_win_msg_suicide = 0; + + +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 +#endif + + +static void display_flags_to_window_styles(int flags, + DWORD *style, DWORD *ex_style) +{ + if (flags & ALLEGRO_FULLSCREEN) { + *style = WS_POPUP; + *ex_style = WS_EX_APPWINDOW; + } + else if (flags & ALLEGRO_MAXIMIZED) { + *style = WS_OVERLAPPEDWINDOW; + *ex_style = WS_EX_APPWINDOW; + } + else if (flags & ALLEGRO_RESIZABLE) { + *style = WS_OVERLAPPEDWINDOW; + *ex_style = WS_EX_APPWINDOW | WS_EX_OVERLAPPEDWINDOW; + } + else { + *style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + *ex_style = WS_EX_APPWINDOW; + } +} + +// Clears a window to black +static void clear_window(HWND window, int w, int h) +{ + PAINTSTRUCT ps; + HDC hdc; + + hdc = BeginPaint(window, &ps); + + SelectObject(hdc, GetStockObject(DC_BRUSH)); + SetDCBrushColor(hdc, RGB(0, 0, 0)); + + Rectangle(hdc, 0, 0, w, h); +} + +HWND _al_win_create_hidden_window() +{ + HWND window = CreateWindowEx(0, + TEXT("ALEX"), TEXT("hidden"), WS_POPUP, + -5000, -5000, 0, 0, + NULL,NULL,window_class.hInstance,0); + return window; +} + +static void _al_win_get_window_center( + ALLEGRO_DISPLAY_WIN *win_display, int width, int height, int *out_x, int *out_y) +{ + int a = win_display->adapter; + bool *is_fullscreen; + ALLEGRO_MONITOR_INFO info; + RECT win_size; + + ALLEGRO_SYSTEM *sys = al_get_system_driver(); + unsigned int num; + unsigned int i; + unsigned int fullscreen_found = 0; + num = al_get_num_video_adapters(); + is_fullscreen = al_calloc(num, sizeof(bool)); + for (i = 0; i < sys->displays._size; i++) { + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&sys->displays, i); + ALLEGRO_DISPLAY *d = *dptr; + if (d->flags & ALLEGRO_FULLSCREEN) { + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)d; + is_fullscreen[win_display->adapter] = true; + fullscreen_found++; + } + } + if (fullscreen_found && fullscreen_found < num) { + for (i = 0; i < num; i++) { + if (is_fullscreen[i] == false) { + a = i; + break; + } + } + } + al_free(is_fullscreen); + + al_get_monitor_info(a, &info); + + win_size.left = info.x1 + (info.x2 - info.x1 - width) / 2; + win_size.top = info.y1 + (info.y2 - info.y1 - height) / 2; + + *out_x = win_size.left; + *out_y = win_size.top; +} + +HWND _al_win_create_window(ALLEGRO_DISPLAY *display, int width, int height, int flags) +{ + HWND my_window; + DWORD style; + DWORD ex_style; + DEV_BROADCAST_DEVICEINTERFACE notification_filter; + int pos_x, pos_y; + bool center = false; + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + WINDOWINFO wi; + int lsize, rsize, tsize, bsize; // left, right, top, bottom border sizes + TCHAR* window_title; + + wi.cbSize = sizeof(WINDOWINFO); + + display_flags_to_window_styles(flags, &style, &ex_style); + + al_get_new_window_position(&pos_x, &pos_y); + if ((flags & ALLEGRO_FULLSCREEN) || (flags & ALLEGRO_FULLSCREEN_WINDOW)) { + pos_x = pos_y = 0; + } + else if (pos_x == INT_MAX) { + pos_x = pos_y = 0; + center = true; + } + + if (center) { + _al_win_get_window_center(win_display, width, height, &pos_x, &pos_y); + } + + window_title = _twin_utf8_to_tchar(al_get_new_window_title()); + my_window = CreateWindowEx(ex_style, + TEXT("ALEX"), window_title, style, + pos_x, pos_y, width, height, + NULL,NULL,window_class.hInstance,0); + al_free(window_title); + + if (_al_win_register_touch_window) + _al_win_register_touch_window(my_window, 0); + + ZeroMemory(¬ification_filter, sizeof(notification_filter)); + notification_filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); + notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + RegisterDeviceNotification(my_window, ¬ification_filter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES); + + GetWindowInfo(my_window, &wi); + + lsize = (wi.rcClient.left - wi.rcWindow.left); + tsize = (wi.rcClient.top - wi.rcWindow.top); + rsize = (wi.rcWindow.right - wi.rcClient.right); + bsize = (wi.rcWindow.bottom - wi.rcClient.bottom); + + SetWindowPos(my_window, 0, 0, 0, + width+lsize+rsize, + height+tsize+bsize, + SWP_NOZORDER | SWP_NOMOVE); + SetWindowPos(my_window, 0, pos_x-lsize, pos_y-tsize, + 0, 0, + SWP_NOZORDER | SWP_NOSIZE); + + if (flags & ALLEGRO_FRAMELESS) { + SetWindowLong(my_window, GWL_STYLE, WS_VISIBLE); + SetWindowLong(my_window, GWL_EXSTYLE, WS_EX_APPWINDOW); + SetWindowPos(my_window, 0, pos_x, pos_y, width, height, SWP_NOZORDER | SWP_FRAMECHANGED); + } + + ShowWindow(my_window, SW_SHOW); + + clear_window(my_window, width, height); + + if (!(flags & ALLEGRO_RESIZABLE) && !(flags & ALLEGRO_FULLSCREEN)) { + /* Make the window non-resizable */ + HMENU menu; + menu = GetSystemMenu(my_window, false); + DeleteMenu(menu, SC_SIZE, MF_BYCOMMAND); + DeleteMenu(menu, SC_MAXIMIZE, MF_BYCOMMAND); + DrawMenuBar(my_window); + } + + _al_vector_init(&win_display->msg_callbacks, sizeof(ALLEGRO_DISPLAY_WIN_CALLBACK)); + + return my_window; +} + + +HWND _al_win_create_faux_fullscreen_window(LPCTSTR devname, ALLEGRO_DISPLAY *display, + int x1, int y1, int width, int height, int refresh_rate, int flags) +{ + HWND my_window; + DWORD style; + DWORD ex_style; + DEVMODE mode; + LONG temp; + TCHAR* window_title; + + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + (void)flags; + + _al_vector_init(&win_display->msg_callbacks, sizeof(ALLEGRO_DISPLAY_WIN_CALLBACK)); + + style = WS_VISIBLE; + ex_style = WS_EX_TOPMOST; + + window_title = _twin_utf8_to_tchar(al_get_new_window_title()); + my_window = CreateWindowEx(ex_style, + TEXT("ALEX"), window_title, style, + x1, y1, width, height, + NULL,NULL,window_class.hInstance,0); + al_free(window_title); + + if (_al_win_register_touch_window) + _al_win_register_touch_window(my_window, 0); + + temp = GetWindowLong(my_window, GWL_STYLE); + temp &= ~WS_CAPTION; + SetWindowLong(my_window, GWL_STYLE, temp); + SetWindowPos(my_window, HWND_TOP, 0, 0, width, height, SWP_NOMOVE | SWP_FRAMECHANGED); + + /* Go fullscreen */ + memset(&mode, 0, sizeof(DEVMODE)); + mode.dmSize = sizeof(DEVMODE); + mode.dmDriverExtra = 0; + mode.dmBitsPerPel = al_get_new_display_option(ALLEGRO_COLOR_SIZE, NULL); + mode.dmPelsWidth = width; + mode.dmPelsHeight = height; + mode.dmDisplayFlags = 0; + mode.dmDisplayFrequency = refresh_rate; + mode.dmPosition.x = x1; + mode.dmPosition.y = y1; + mode.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFLAGS| + DM_DISPLAYFREQUENCY|DM_POSITION; + + ChangeDisplaySettingsEx(devname, &mode, NULL, 0, NULL/*CDS_FULLSCREEN*/); + + clear_window(my_window, width, height); + + return my_window; +} + + +/* _al_win_grab_input: + * Makes the passed display grab the input. All consequent input events will be + * generated the this display's window. The display's window must the the + * foreground window. + */ +void _al_win_grab_input(ALLEGRO_DISPLAY_WIN *win_disp) +{ + _al_win_wnd_schedule_proc(win_disp->window, + _al_win_joystick_dinput_grab, + win_disp); +} + +/* Generate a resize event if the size has changed. We cannot asynchronously + * change the display size here yet, since the user will only know about a + * changed size after receiving the resize event. Here we merely add the + * event to the queue. + */ +static void win_generate_resize_event(ALLEGRO_DISPLAY_WIN *win_display) +{ + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)win_display; + ALLEGRO_EVENT_SOURCE *es = &display->es; + WINDOWINFO wi; + int x, y, w, h; + + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(win_display->window, &wi); + x = wi.rcClient.left; + y = wi.rcClient.top; + w = wi.rcClient.right - wi.rcClient.left; + h = wi.rcClient.bottom - wi.rcClient.top; + + /* Don't generate events when restoring after minimise. */ + if (w == 0 && h == 0 && x == -32000 && y == -32000) + return; + + /* Always generate resize event when constraints are used. + * This is needed because d3d_acknowledge_resize() updates d->w, d->h + * before this function will be called. + */ + if (display->use_constraints || display->w != w || display->h != h) { + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; + event.display.timestamp = al_get_time(); + event.display.x = x; + event.display.y = y; + event.display.width = w; + event.display.height = h; + event.display.source = display; + _al_event_source_emit_event(es, &event); + + /* Generate an expose event. */ + /* This seems a bit redundant after a resize. */ + if (win_display->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) { + event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE; + _al_event_source_emit_event(es, &event); + } + } + _al_event_source_unlock(es); + } +} + +static void postpone_thread_proc(void *arg) +{ + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)arg; + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + + Sleep(50); + + if (win_display->ignore_resize) { + win_display->ignore_resize = false; + } + else { + win_generate_resize_event(win_display); + } + + resize_postponed = false; + win_display->can_acknowledge = true; +} + + +static void handle_mouse_capture(bool down, HWND hWnd) +{ + int i; + bool any_button_down = false; + ALLEGRO_MOUSE_STATE state; + + if (!al_is_mouse_installed()) + return; + + al_get_mouse_state(&state); + for (i = 1; i <= 5; i++) { + any_button_down |= al_mouse_button_down(&state, i); + } + + if (down && GetCapture() != hWnd) { + SetCapture(hWnd); + } + else if (!any_button_down) { + ReleaseCapture(); + } +} + +static void break_window_message_pump(ALLEGRO_DISPLAY_WIN *win_display, HWND hWnd) +{ + /* Get the ID of the thread which created the HWND and is processing its messages */ + DWORD wnd_thread_id = GetWindowThreadProcessId(hWnd, NULL); + + /* Set the "end_thread" flag to stop the message pump */ + win_display->end_thread = true; + + /* Wake-up the message pump so the thread can read the new value of "end_thread" */ + PostThreadMessage(wnd_thread_id, WM_NULL, 0, 0); +} + +/* Windows Touch Input emulate WM_MOUSE* events. If we are using touch input explicitly, + * we do not want to use this, because Allegro driver provide emulation already. This + * way we can be consistent across platforms. + */ +static bool accept_mouse_event(void) +{ + if (!al_is_touch_input_installed()) + return true; + + return !((GetMessageExtraInfo() & _AL_MOUSEEVENTF_FROMTOUCH) == _AL_MOUSEEVENTF_FROMTOUCH); +} + +static LRESULT CALLBACK window_callback(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + ALLEGRO_DISPLAY *d = NULL; + ALLEGRO_DISPLAY_WIN *win_display = NULL; + //WINDOWINFO wi; + unsigned int i; + ALLEGRO_EVENT_SOURCE *es = NULL; + ALLEGRO_SYSTEM *system = al_get_system_driver(); + + //wi.cbSize = sizeof(WINDOWINFO); + + if (message == _al_win_msg_call_proc) { + ((void (*)(void*))wParam) ((void*)lParam); + return 0; + } + + if (!system) { + return DefWindowProc(hWnd,message,wParam,lParam); + } + + if (message == _al_win_msg_suicide && wParam) { + win_display = (ALLEGRO_DISPLAY_WIN*)wParam; + break_window_message_pump(win_display, hWnd); + if (_al_win_unregister_touch_window) + _al_win_unregister_touch_window(hWnd); + DestroyWindow(hWnd); + return 0; + } + + for (i = 0; i < system->displays._size; i++) { + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&system->displays, i); + d = *dptr; + win_display = (void*)d; + if (win_display->window == hWnd) { + es = &d->es; + break; + } + } + + if (i == system->displays._size) + return DefWindowProc(hWnd,message,wParam,lParam); + + if (message == _al_win_msg_suicide) { + break_window_message_pump(win_display, hWnd); + if (_al_win_unregister_touch_window) + _al_win_unregister_touch_window(hWnd); + DestroyWindow(hWnd); + return 0; + } + + for (i = 0; i < _al_vector_size(&win_display->msg_callbacks); ++i) { + LRESULT result = TRUE; + ALLEGRO_DISPLAY_WIN_CALLBACK *ptr = _al_vector_ref(&win_display->msg_callbacks, i); + if ((ptr->proc)(d, message, wParam, lParam, &result, ptr->userdata)) + return result; + } + + switch (message) { + case WM_INPUT: + { + /* RAW Input is currently unused. */ + UINT dwSize; + LPBYTE lpb; + RAWINPUT* raw; + + /* We can't uninstall WM_INPUT mesages. */ + if (!al_is_mouse_installed()) + break; + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, + sizeof(RAWINPUTHEADER)); + lpb = al_malloc(sizeof(BYTE)*dwSize); + if (lpb == NULL) + break; + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)); + raw = (RAWINPUT*)lpb; + + if (raw->header.dwType != RIM_TYPEMOUSE) { + al_free(lpb); + break; + } + + { + RAWMOUSE *rm = &raw->data.mouse; + int x = raw->data.mouse.lLastX; + int y = raw->data.mouse.lLastY; + bool abs = (rm->usFlags & (MOUSE_MOVE_ABSOLUTE + | MOUSE_VIRTUAL_DESKTOP)) != 0; + if (abs || x || y) + _al_win_mouse_handle_move(x, y, abs, win_display); + + if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) + _al_win_mouse_handle_button(1, true, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_UP) + _al_win_mouse_handle_button(1, false, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) + _al_win_mouse_handle_button(2, true, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_UP) + _al_win_mouse_handle_button(2, false, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) + _al_win_mouse_handle_button(3, true, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_UP) + _al_win_mouse_handle_button(3, false, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) + _al_win_mouse_handle_button(4, true, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_UP) + _al_win_mouse_handle_button(4, false, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) + _al_win_mouse_handle_button(5, true, x, y, abs, win_display); + if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_UP) + _al_win_mouse_handle_button(5, false, x, y, abs, win_display); + + if (rm->usButtonFlags & RI_MOUSE_WHEEL) { + SHORT z = (SHORT)rm->usButtonData; + _al_win_mouse_handle_wheel(z, false, win_display); + } + } + + al_free(lpb); + break; + } + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: { + if (accept_mouse_event()) { + int mx = GET_X_LPARAM(lParam); + int my = GET_Y_LPARAM(lParam); + bool down = (message == WM_LBUTTONDOWN); + _al_win_mouse_handle_button(1, down, mx, my, true, win_display); + handle_mouse_capture(down, hWnd); + } + break; + } + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: { + if (accept_mouse_event()) { + int mx = GET_X_LPARAM(lParam); + int my = GET_Y_LPARAM(lParam); + bool down = (message == WM_MBUTTONDOWN); + _al_win_mouse_handle_button(3, down, mx, my, true, win_display); + handle_mouse_capture(down, hWnd); + } + break; + } + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: { + if (accept_mouse_event()) { + int mx = GET_X_LPARAM(lParam); + int my = GET_Y_LPARAM(lParam); + bool down = (message == WM_RBUTTONDOWN); + _al_win_mouse_handle_button(2, down, mx, my, true, win_display); + handle_mouse_capture(down, hWnd); + } + break; + } + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: { + if (accept_mouse_event()) { + int mx = GET_X_LPARAM(lParam); + int my = GET_Y_LPARAM(lParam); + int button = HIWORD(wParam); + bool down = (message == WM_XBUTTONDOWN); + if (button == XBUTTON1) + _al_win_mouse_handle_button(4, down, mx, my, true, win_display); + else if (button == XBUTTON2) + _al_win_mouse_handle_button(5, down, mx, my, true, win_display); + handle_mouse_capture(down, hWnd); + return TRUE; + } + break; + } + case WM_MOUSEWHEEL: { + if (accept_mouse_event()) { + int d = GET_WHEEL_DELTA_WPARAM(wParam); + _al_win_mouse_handle_wheel(d, false, win_display); + return TRUE; + } + break; + } + case WM_MOUSEHWHEEL: { + if (accept_mouse_event()) { + int d = GET_WHEEL_DELTA_WPARAM(wParam); + _al_win_mouse_handle_hwheel(d, false, win_display); + return TRUE; + } + break; + } + case WM_MOUSEMOVE: { + if (accept_mouse_event()) { + TRACKMOUSEEVENT tme; + int mx = GET_X_LPARAM(lParam); + int my = GET_Y_LPARAM(lParam); + + if (win_display->mouse_cursor_shown && we_hid_the_mouse) { + we_hid_the_mouse = false; + win_display->display.vt->hide_mouse_cursor((void*)win_display); + } + + _al_win_mouse_handle_move(mx, my, true, win_display); + if (mx >= 0 && my >= 0 && mx < d->w && my < d->h) { + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_QUERY; + if (TrackMouseEvent(&tme) && !tme.hwndTrack) { + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hWnd; + tme.dwHoverTime = 0; + TrackMouseEvent(&tme); + _al_win_mouse_handle_enter(win_display); + } + } + } + + /* WM_SETCURSOR messages are not received while the mouse is + * captured. We call SetCursor here so that changing the mouse + * cursor has an effect while the user is holding down the mouse + * button. + */ + if (GetCapture() == hWnd && win_display->mouse_cursor_shown) { + SetCursor(win_display->mouse_selected_hcursor); + } + + break; + } + case WM_MOUSELEAVE: { + if (accept_mouse_event()) { + _al_win_mouse_handle_leave(win_display); + } + break; + } + case _AL_WM_TOUCH: { + if (_al_win_get_touch_input_info && _al_win_close_touch_input_handle) { + int number_of_touches = LOWORD(wParam); + + TOUCHINPUT* touches = al_malloc(number_of_touches * sizeof(TOUCHINPUT)); + + if (_al_win_get_touch_input_info((HANDLE)lParam, number_of_touches, touches, sizeof(TOUCHINPUT))) { + + if (al_is_touch_input_installed()) { + + int i; + + POINT origin = { 0, 0 }; + + ClientToScreen(hWnd, &origin); + + _al_win_touch_input_set_time_stamp((touches + number_of_touches - 1)->dwTime); + + for (i = 0; i < number_of_touches; ++i) { + + TOUCHINPUT* touch = touches + i; + + float x = touch->x / 100.0f - (float)origin.x; + float y = touch->y / 100.0f - (float)origin.y; + + bool primary = touch->dwFlags & _AL_TOUCHEVENTF_PRIMARY ? true : false; + + if (touch->dwFlags & _AL_TOUCHEVENTF_DOWN) + _al_win_touch_input_handle_begin((int)touch->dwID, (size_t)touch->dwTime, x, y, primary, win_display); + else if (touch->dwFlags & _AL_TOUCHEVENTF_UP) + _al_win_touch_input_handle_end((int)touch->dwID, (size_t)touch->dwTime, x, y, primary, win_display); + else if (touch->dwFlags & _AL_TOUCHEVENTF_MOVE) + _al_win_touch_input_handle_move((int)touch->dwID, (size_t)touch->dwTime, x, y, primary, win_display); + } + } + + _al_win_close_touch_input_handle((HANDLE)lParam); + } + + al_free(touches); + } + break; + } + case WM_CAPTURECHANGED: { + if (al_is_mouse_installed()) { + int i; + ALLEGRO_MOUSE_STATE state; + if (!lParam || (HWND)lParam == hWnd) + break; + al_get_mouse_state(&state); + for (i = 1; i <= 5; i++) { + if (al_mouse_button_down(&state, i)) + _al_win_mouse_handle_button(i, 0, 0, 0, true, win_display); + } + } + break; + } + case WM_NCMOUSEMOVE: { + if (!win_display->mouse_cursor_shown) { + we_hid_the_mouse = true; + win_display->display.vt->show_mouse_cursor((void*)win_display); + } + break; + } + case WM_SYSKEYDOWN: { + int vcode = wParam; + bool extended = (lParam >> 24) & 0x1; + bool repeated = (lParam >> 30) & 0x1; + _al_win_kbd_handle_key_press(0, vcode, extended, repeated, win_display); + break; + } + case WM_KEYDOWN: { + int vcode = wParam; + int scode = (lParam >> 16) & 0xff; + bool extended = (lParam >> 24) & 0x1; + bool repeated = (lParam >> 30) & 0x1; + /* We can't use TranslateMessage() because we don't know if it will + produce a WM_CHAR or not. */ + _al_win_kbd_handle_key_press(scode, vcode, extended, repeated, win_display); + break; + } + case WM_SYSKEYUP: + case WM_KEYUP: { + int vcode = wParam; + int scode = (lParam >> 16) & 0xff; + bool extended = (lParam >> 24) & 0x1; + _al_win_kbd_handle_key_release(scode, vcode, extended, win_display); + break; + } + case WM_SYSCOMMAND: { + if (_al_win_disable_screensaver && + ((wParam & 0xfff0) == SC_MONITORPOWER || (wParam & 0xfff0) == SC_SCREENSAVE)) { + return 0; + } + else if ((wParam & 0xfff0) == SC_KEYMENU) { + /* Prevent Windows from intercepting the ALT key. + (Disables opening menus via the ALT key.) */ + return 0; + } + /* This is used by WM_GETMINMAXINFO to set constraints. */ + else if ((wParam & 0xfff0) == SC_MAXIMIZE) { + d->flags |= ALLEGRO_MAXIMIZED; + SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + } + else if ((wParam & 0xfff0) == SC_RESTORE) { + d->flags &= ~ALLEGRO_MAXIMIZED; + SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_OVERLAPPEDWINDOW); + } + break; + } + case WM_PAINT: { + if (win_display->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) { + RECT r; + HRGN hrgn; + GetWindowRect(win_display->window, &r); + hrgn = CreateRectRgn(r.left, r.top, r.right, r.bottom); + if (GetUpdateRgn(win_display->window, hrgn, false) != ERROR) { + PAINTSTRUCT ps; + DWORD size; + LPRGNDATA rgndata; + int n; + int i; + RECT *rects; + BeginPaint(win_display->window, &ps); + size = GetRegionData(hrgn, 0, NULL); + rgndata = al_malloc(size); + GetRegionData(hrgn, size, rgndata); + n = rgndata->rdh.nCount; + rects = (RECT *)rgndata->Buffer; + //GetWindowInfo(win_display->window, &wi); + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE; + event.display.timestamp = al_get_time(); + for (i = 0; i < n; i++) { + event.display.x = rects[i].left; + event.display.y = rects[i].top; + event.display.width = rects[i].right - rects[i].left; + event.display.height = rects[i].bottom - rects[i].top; + _al_event_source_emit_event(es, &event); + } + } + _al_event_source_unlock(es); + al_free(rgndata); + EndPaint(win_display->window, &ps); + DeleteObject(hrgn); + } + return 0; + } + break; + } + + case WM_SETCURSOR: + switch (LOWORD(lParam)) { + case HTLEFT: + case HTRIGHT: + SetCursor(LoadCursor(NULL, IDC_SIZEWE)); + break; + case HTBOTTOM: + case HTTOP: + SetCursor(LoadCursor(NULL, IDC_SIZENS)); + break; + case HTBOTTOMLEFT: + case HTTOPRIGHT: + SetCursor(LoadCursor(NULL, IDC_SIZENESW)); + break; + case HTBOTTOMRIGHT: + case HTTOPLEFT: + SetCursor(LoadCursor(NULL, IDC_SIZENWSE)); + break; + default: + if (win_display->mouse_cursor_shown) { + SetCursor(win_display->mouse_selected_hcursor); + } + else { + SetCursor(NULL); + } + break; + } + return 1; + case WM_ACTIVATE: + if (HIWORD(wParam) && LOWORD(wParam) != WA_INACTIVE) + break; + + if (HIWORD(wParam)) + d->flags |= ALLEGRO_MINIMIZED; + else + d->flags &= ~ALLEGRO_MINIMIZED; + + if (LOWORD(wParam) != WA_INACTIVE) { + // Make fullscreen windows TOPMOST again + if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) { + SetWindowPos(win_display->window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } + if (d->vt->switch_in) + d->vt->switch_in(d); + _al_win_fix_modifiers(); + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + memset(&event, 0, sizeof(event)); + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; + event.display.timestamp = al_get_time(); + _al_event_source_emit_event(es, &event); + } + _al_event_source_unlock(es); + _al_win_grab_input(win_display); + return 0; + } + else { + // Remove TOPMOST flag from fullscreen windows so we can alt-tab. Also must raise the new activated window + if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) { + SetWindowPos(win_display->window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + SetWindowPos(GetForegroundWindow(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } + if (d->flags & ALLEGRO_FULLSCREEN) { + d->vt->switch_out(d); + } + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + memset(&event, 0, sizeof(event)); + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; + event.display.timestamp = al_get_time(); + _al_event_source_emit_event(es, &event); + } + _al_event_source_unlock(es); + return 0; + } + break; + case WM_MENUCHAR : + return (MNC_CLOSE << 16) | (wParam & 0xffff); + case WM_CLOSE: + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + memset(&event, 0, sizeof(event)); + event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; + event.display.timestamp = al_get_time(); + _al_event_source_emit_event(es, &event); + } + _al_event_source_unlock(es); + return 0; + case WM_GETMINMAXINFO: + /* Set window constraints only when needed. */ + if (d->use_constraints) { + LPMINMAXINFO p_info = (LPMINMAXINFO)lParam; + RECT wRect; + RECT cRect; + int wWidth; + int wHeight; + int cWidth; + int cHeight; + + GetWindowRect(hWnd, &wRect); + GetClientRect(hWnd, &cRect); + wWidth = wRect.right - wRect.left; + wHeight = wRect.bottom - wRect.top; + cWidth = cRect.right - cRect.left; + cHeight = cRect.bottom - cRect.top; + + /* Client size is zero when the window is restored. */ + if (cWidth != 0 && cHeight != 0) { + int total_border_width = wWidth - cWidth; + int total_border_height = wHeight - cHeight; + POINT wmin, wmax; + + wmin.x = (d->min_w > 0) ? d->min_w + total_border_width : p_info->ptMinTrackSize.x; + wmin.y = (d->min_h > 0) ? d->min_h + total_border_height : p_info->ptMinTrackSize.y; + + /* don't use max_w & max_h constraints when window maximized */ + if (d->flags & ALLEGRO_MAXIMIZED) { + wmax.x = p_info->ptMaxTrackSize.x; + wmax.y = p_info->ptMaxTrackSize.y; + } + else { + wmax.x = (d->max_w > 0) ? d->max_w + total_border_width : p_info->ptMaxTrackSize.x; + wmax.y = (d->max_h > 0) ? d->max_h + total_border_height : p_info->ptMaxTrackSize.y; + } + + p_info->ptMinTrackSize = wmin; + p_info->ptMaxTrackSize = wmax; + } + } + break; + case WM_SIZE: + if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED) { + /* + * Delay the resize event so we don't get bogged down with them + */ + if (!resize_postponed) { + resize_postponed = true; + _beginthread(postpone_thread_proc, 0, (void *)d); + } + d->flags &= ~ALLEGRO_MAXIMIZED; + if (wParam == SIZE_MAXIMIZED) { + d->flags |= ALLEGRO_MAXIMIZED; + } + } + else if (d->use_constraints) { + /* al_apply_window_constraints() resizes a window if the current + * width & height do not fit in the constraint's range. + * We have to create the resize event, so the application could + * redraw its content. + */ + if (!resize_postponed) { + resize_postponed = true; + _beginthread(postpone_thread_proc, 0, (void *)d); + } + } + return 0; + case WM_ENTERSIZEMOVE: + /* DefWindowProc for WM_ENTERSIZEMOVE enters a modal loop, which also + * ends up blocking the loop in d3d_display_thread_proc (which is + * where we are called from, if using D3D). Rather than batching up + * intermediate resize events which the user cannot acknowledge in the + * meantime anyway, make it so only a single resize event is generated + * at WM_EXITSIZEMOVE. + */ + if (d->flags & ALLEGRO_DIRECT3D_INTERNAL) { + resize_postponed = true; + } + break; + case WM_EXITSIZEMOVE: + if (resize_postponed) { + win_generate_resize_event(win_display); + win_display->ignore_resize = false; + resize_postponed = false; + win_display->can_acknowledge = true; + } + break; + case WM_DPICHANGED: + if ((d->flags & ALLEGRO_RESIZABLE) && !(d->flags & ALLEGRO_FULLSCREEN)) { + RECT* rect = (RECT*)lParam; + // XXX: This doesn't seem to actually move the window... why? + SetWindowPos( + hWnd, + 0, + rect->left, + rect->top, + rect->right - rect->left, + rect->bottom - rect->top, + SWP_NOZORDER | SWP_NOACTIVATE); + win_generate_resize_event(win_display); + } + break; + case WM_DEVICECHANGE: + _al_win_joystick_dinput_trigger_enumeration(); + break; + } + + return DefWindowProc(hWnd,message,wParam,lParam); +} + +int _al_win_init_window() +{ + // Create A Window Class Structure + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hbrBackground = NULL; + window_class.hCursor = NULL; + window_class.hIcon = NULL; + window_class.hInstance = GetModuleHandle(NULL); + window_class.lpfnWndProc = window_callback; + window_class.lpszClassName = TEXT("ALEX"); + window_class.lpszMenuName = NULL; + window_class.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC; + + RegisterClass(&window_class); + + if (_al_win_msg_call_proc == 0 && _al_win_msg_suicide == 0) { + _al_win_msg_call_proc = RegisterWindowMessage(TEXT("Allegro call proc")); + _al_win_msg_suicide = RegisterWindowMessage(TEXT("Allegro window suicide")); + } + + return true; +} + + +static int win_choose_icon_bitmap(const int sys_w, const int sys_h, + const int num_icons, ALLEGRO_BITMAP *bmps[]) +{ + int best_i = 0; + int best_score = INT_MAX; + int i; + + for (i = 0; i < num_icons; i++) { + int bmp_w = al_get_bitmap_width(bmps[i]); + int bmp_h = al_get_bitmap_height(bmps[i]); + int score; + + if (bmp_w == sys_w && bmp_h == sys_h) + return i; + + /* We prefer to scale up smaller bitmaps to the desired size than to + * scale down larger bitmaps. At these resolutions, scaled up bitmaps + * look blocky, but scaled down bitmaps can look even worse due to to + * dropping crucial pixels. + */ + if (bmp_w * bmp_h <= sys_w * sys_h) + score = (sys_w * sys_h) - (bmp_w * bmp_h); + else + score = bmp_w * bmp_h; + + if (score < best_score) { + best_score = score; + best_i = i; + } + } + + return best_i; +} + +static void win_set_display_icon(ALLEGRO_DISPLAY_WIN *win_display, + const WPARAM icon_type, const int sys_w, const int sys_h, + const int num_icons, ALLEGRO_BITMAP *bmps[]) +{ + HICON icon; + HICON old_icon; + ALLEGRO_BITMAP *bmp; + int bmp_w; + int bmp_h; + int i; + + i = win_choose_icon_bitmap(sys_w, sys_h, num_icons, bmps); + bmp = bmps[i]; + bmp_w = al_get_bitmap_width(bmp); + bmp_h = al_get_bitmap_height(bmp); + + if (bmp_w == sys_w && bmp_h == sys_h) { + icon = _al_win_create_icon(win_display->window, bmp, 0, 0, false, false); + } + else { + ALLEGRO_BITMAP *tmp_bmp; + ALLEGRO_STATE backup; + + tmp_bmp = al_create_bitmap(sys_w, sys_h); + if (!tmp_bmp) + return; + + al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER); + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ARGB_8888); + + al_set_target_bitmap(tmp_bmp); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_draw_scaled_bitmap(bmp, 0, 0, bmp_w, bmp_h, 0, 0, sys_w, sys_h, 0); + + al_restore_state(&backup); + + icon = _al_win_create_icon(win_display->window, tmp_bmp, 0, 0, false, + false); + + al_destroy_bitmap(tmp_bmp); + } + + old_icon = (HICON)SendMessage(win_display->window, WM_SETICON, + icon_type, (LPARAM)icon); + + if (old_icon) + DestroyIcon(old_icon); +} + +void _al_win_set_display_icons(ALLEGRO_DISPLAY *display, + int num_icons, ALLEGRO_BITMAP *bmps[]) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + int sys_w; + int sys_h; + + sys_w = GetSystemMetrics(SM_CXSMICON); + sys_h = GetSystemMetrics(SM_CYSMICON); + win_set_display_icon(win_display, ICON_SMALL, sys_w, sys_h, + num_icons, bmps); + + sys_w = GetSystemMetrics(SM_CXICON); + sys_h = GetSystemMetrics(SM_CYICON); + win_set_display_icon(win_display, ICON_BIG, sys_w, sys_h, + num_icons, bmps); +} + +void _al_win_destroy_display_icons(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + HICON old_icon; + + old_icon = (HICON)SendMessage(win_display->window, WM_SETICON, ICON_SMALL, 0); + if (old_icon) + DestroyIcon(old_icon); + old_icon = (HICON)SendMessage(win_display->window, WM_SETICON, ICON_BIG, 0); + if (old_icon) + DestroyIcon(old_icon); +} + +void _al_win_set_window_position(HWND window, int x, int y) +{ + SetWindowPos( + window, + HWND_TOP, + x, + y, + 0, + 0, + SWP_NOSIZE | SWP_NOZORDER); +} + +void _al_win_get_window_position(HWND window, int *x, int *y) +{ + RECT r; + GetWindowRect(window, &r); + + if (x) { + *x = r.left; + } + if (y) { + *y = r.top; + } +} + + +void _al_win_set_window_frameless(ALLEGRO_DISPLAY *display, HWND hWnd, + bool frameless) +{ + int w = display->w; + int h = display->h; + + if (frameless) { + SetWindowLong(hWnd, GWL_STYLE, WS_VISIBLE); + SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + SetWindowPos(hWnd, 0, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); + } + else { + RECT r; + DWORD style; + DWORD exStyle; + + display_flags_to_window_styles(display->flags, &style, &exStyle); + style |= WS_VISIBLE; + + GetWindowRect(hWnd, &r); + AdjustWindowRectEx(&r, style, GetMenu(hWnd) ? TRUE : FALSE, exStyle); + + w = r.right - r.left; + h = r.bottom - r.top; + + SetWindowLong(hWnd, GWL_STYLE, style); + SetWindowLong(hWnd, GWL_EXSTYLE, exStyle); + SetWindowPos(hWnd, 0, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); + } +} + + +bool _al_win_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff) +{ + ALLEGRO_DISPLAY_WIN *win_display = (void*)display; + //double timeout; + ALLEGRO_MONITOR_INFO mi; + + memset(&mi, 0, sizeof(mi)); + + switch (flag) { + case ALLEGRO_FRAMELESS: { + if (onoff) { + display->flags |= ALLEGRO_FRAMELESS; + } + else { + display->flags &= ~ALLEGRO_FRAMELESS; + } + _al_win_set_window_frameless(display, win_display->window, + (display->flags & ALLEGRO_FRAMELESS)); + return true; + } + + case ALLEGRO_FULLSCREEN_WINDOW: + if ((display->flags & ALLEGRO_FULLSCREEN_WINDOW) && onoff) { + ALLEGRO_DEBUG("Already a fullscreen window\n"); + return true; + } + if (!(display->flags & ALLEGRO_FULLSCREEN_WINDOW) && !onoff) { + ALLEGRO_DEBUG("Already a non-fullscreen window\n"); + return true; + } + + if (onoff) { + /* Switch off frame in fullscreen window mode. */ + _al_win_set_window_frameless(display, win_display->window, true); + } + else { + /* Respect display flag in windowed mode. */ + _al_win_set_window_frameless(display, win_display->window, + (display->flags & ALLEGRO_FRAMELESS)); + } + + if (onoff) { + int adapter = win_display->adapter; + al_get_monitor_info(adapter, &mi); + display->flags |= ALLEGRO_FULLSCREEN_WINDOW; + display->w = mi.x2 - mi.x1; + display->h = mi.y2 - mi.y1; + } + else { + display->flags &= ~ALLEGRO_FULLSCREEN_WINDOW; + display->w = win_display->toggle_w; + display->h = win_display->toggle_h; + } + + ASSERT(!!(display->flags & ALLEGRO_FULLSCREEN_WINDOW) == onoff); + + // Hide the window temporarily + SetWindowPos(win_display->window, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE); + + al_resize_display(display, display->w, display->h); + + if (onoff) { + // Re-set the TOPMOST flag and move to position + SetWindowPos(win_display->window, HWND_TOPMOST, mi.x1, mi.y1, 0, 0, SWP_NOSIZE); + } + else { + int pos_x = 0; + int pos_y = 0; + WINDOWINFO wi; + int bw, bh; + + // Unset the topmost flag + SetWindowPos(win_display->window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + + // Center the window + _al_win_get_window_center(win_display, display->w, display->h, &pos_x, &pos_y); + GetWindowInfo(win_display->window, &wi); + bw = (wi.rcClient.left - wi.rcWindow.left) + (wi.rcWindow.right - wi.rcClient.right), + bh = (wi.rcClient.top - wi.rcWindow.top) + (wi.rcWindow.bottom - wi.rcClient.bottom), + SetWindowPos( + win_display->window, HWND_TOP, 0, 0, display->w+bw, display->h+bh, SWP_NOMOVE + ); + SetWindowPos( + win_display->window, HWND_TOP, pos_x-bw/2, pos_y-bh/2, 0, 0, SWP_NOSIZE + ); + } + + // Show the window again + SetWindowPos(win_display->window, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE); + + // Clear the window to black + clear_window(win_display->window, display->w, display->h); + + ASSERT(!!(display->flags & ALLEGRO_FULLSCREEN_WINDOW) == onoff); + return true; + case ALLEGRO_MAXIMIZED: + if ((!!(display->flags & ALLEGRO_MAXIMIZED)) == onoff) + return true; + if (onoff) { + ShowWindow(win_display->window, SW_SHOWMAXIMIZED); + } + else { + ShowWindow(win_display->window, SW_RESTORE); + } + return true; + } + return false; +} + + +void _al_win_set_window_title(ALLEGRO_DISPLAY *display, const char *title) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + TCHAR *ttitle = _twin_utf8_to_tchar(title); + SetWindowText(win_display->window, ttitle); + al_free(ttitle); +} + +bool _al_win_set_window_constraints(ALLEGRO_DISPLAY *display, + int min_w, int min_h, int max_w, int max_h) +{ + display->min_w = min_w; + display->min_h = min_h; + display->max_w = max_w; + display->max_h = max_h; + + return true; +} + +void _al_win_apply_window_constraints(ALLEGRO_DISPLAY *display, bool onoff) +{ + if (!(display->flags & ALLEGRO_MAXIMIZED)) + al_resize_display(display, display->w, display->h); +} + +void _al_win_post_create_window(ALLEGRO_DISPLAY *display) +{ + /* Ideally the d3d/wgl window creation would already create the + * window maximized - but that code looks too messy to me to touch + * right now. + */ + if (display->flags & ALLEGRO_MAXIMIZED) { + display->flags &= ~ALLEGRO_MAXIMIZED; + al_set_display_flag(display, ALLEGRO_MAXIMIZED, true); + } +} + +bool _al_win_get_window_constraints(ALLEGRO_DISPLAY *display, + int *min_w, int *min_h, int *max_w, int *max_h) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)display; + *min_w = win_display->display.min_w; + *min_h = win_display->display.min_h; + *max_w = win_display->display.max_w; + *max_h = win_display->display.max_h; + + return true; +} + + +/* _al_win_wnd_call_proc: + * instructs the specifed window thread to call the specified procedure. Waits + * until the procedure has returned. + */ +void _al_win_wnd_call_proc(HWND wnd, void (*proc) (void*), void* param) +{ + ASSERT(_al_win_msg_call_proc); + SendMessage(wnd, _al_win_msg_call_proc, (WPARAM)proc, (LPARAM)param); +} + + +/* _al_win_wnd_schedule_proc: + * instructs the specifed window thread to call the specified procedure but + * doesn't wait until the procedure has returned. + */ +void _al_win_wnd_schedule_proc(HWND wnd, void (*proc) (void*), void* param) +{ + ASSERT(_al_win_msg_call_proc); + if (!PostMessage(wnd, _al_win_msg_call_proc, (WPARAM)proc, (LPARAM)param)) { + ALLEGRO_ERROR("_al_win_wnd_schedule_proc failed.\n"); + } +} + + +/* Function: al_get_win_window_handle + */ +HWND al_get_win_window_handle(ALLEGRO_DISPLAY *display) +{ + if (!display) + return NULL; + return ((ALLEGRO_DISPLAY_WIN *)display)->window; +} + + +int _al_win_determine_adapter(void) +{ + int a = al_get_new_display_adapter(); + if (a == -1) { + int num_screens = al_get_num_video_adapters(); + int cScreen = 0; + ALLEGRO_MONITOR_INFO temp_info; + for (cScreen = 0; cScreen < num_screens; cScreen++) { + al_get_monitor_info(cScreen, &temp_info); + if (temp_info.x1 == 0 && temp_info.y1 == 0) { // ..probably found primary display + return cScreen; + } + } + return 0; // safety measure, probably not necessary + } + return a; +} + +/* Function: al_win_add_window_callback + */ +bool al_win_add_window_callback(ALLEGRO_DISPLAY *display, + bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam, + LPARAM lparam, LRESULT *result, void *userdata), void *userdata) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; + ALLEGRO_DISPLAY_WIN_CALLBACK *ptr; + + if (!display || !callback) { + return false; + } + else { + size_t i; + for (i = 0; i < _al_vector_size(&win_display->msg_callbacks); ++i) { + ALLEGRO_DISPLAY_WIN_CALLBACK *ptr = _al_vector_ref(&win_display->msg_callbacks, i); + if (ptr->proc == callback && ptr->userdata == userdata) + return false; + } + } + + if (!(ptr = _al_vector_alloc_back(&win_display->msg_callbacks))) + return false; + + ptr->proc = callback; + ptr->userdata = userdata; + return true; +} + +/* Function: al_win_remove_window_callback + */ +bool al_win_remove_window_callback(ALLEGRO_DISPLAY *display, + bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam, + LPARAM lparam, LRESULT *result, void *userdata), void *userdata) +{ + ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; + + if (display && callback) { + size_t i; + for (i = 0; i < _al_vector_size(&win_display->msg_callbacks); ++i) { + ALLEGRO_DISPLAY_WIN_CALLBACK *ptr = _al_vector_ref(&win_display->msg_callbacks, i); + if (ptr->proc == callback && ptr->userdata == userdata) { + _al_vector_delete_at(&win_display->msg_callbacks, i); + return true; + } + } + } + + return false; +} + +/* vi: set ts=8 sts=3 sw=3 et: */ diff --git a/allegro/src/win/wxthread.c b/allegro/src/win/wxthread.c new file mode 100644 index 00000000..6c6b40d3 --- /dev/null +++ b/allegro/src/win/wxthread.c @@ -0,0 +1,425 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Internal cross-platform threading API for Windows. + * + * By Peter Wang. + * + * See readme.txt for copyright information. + */ + + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_thread.h" + +#include +#include + + + +/* threads */ + +static unsigned __stdcall thread_proc_trampoline(void *data) +{ + _AL_THREAD *thread = data; + (*thread->proc)(thread, thread->arg); + + /* _endthreadex does not automatically close the thread handle, + * unlike _endthread. We rely on this in al_join_thread(). + */ + _endthreadex(0); + return 0; +} + + +void _al_thread_create(_AL_THREAD *thread, void (*proc)(_AL_THREAD*, void*), void *arg) +{ + ASSERT(thread); + ASSERT(proc); + { + InitializeCriticalSection(&thread->cs); + + thread->should_stop = false; + thread->proc = proc; + thread->arg = arg; + + thread->thread = (void *)_beginthreadex(NULL, 0, + thread_proc_trampoline, thread, 0, NULL); + } +} + + +void _al_thread_create_with_stacksize(_AL_THREAD* thread, void (*proc)(_AL_THREAD*, void*), void *arg, size_t stacksize) +{ + ASSERT(thread); + ASSERT(proc); + { + InitializeCriticalSection(&thread->cs); + + thread->should_stop = false; + thread->proc = proc; + thread->arg = arg; + + thread->thread = (void *)_beginthreadex(NULL, stacksize, + thread_proc_trampoline, thread, 0, NULL); + } +} + + +void _al_thread_set_should_stop(_AL_THREAD *thread) +{ + ASSERT(thread); + + EnterCriticalSection(&thread->cs); + { + thread->should_stop = true; + } + LeaveCriticalSection(&thread->cs); +} + + + +void _al_thread_join(_AL_THREAD *thread) +{ + ASSERT(thread); + + _al_thread_set_should_stop(thread); + WaitForSingleObject(thread->thread, INFINITE); + + CloseHandle(thread->thread); + DeleteCriticalSection(&thread->cs); +} + + +void _al_thread_detach(_AL_THREAD *thread) +{ + ASSERT(thread); + + CloseHandle(thread->thread); + DeleteCriticalSection(&thread->cs); +} + + + +/* mutexes */ + +void _al_mutex_init(_AL_MUTEX *mutex) +{ + ASSERT(mutex); + + if (!mutex->cs) + mutex->cs = al_malloc(sizeof *mutex->cs); + ASSERT(mutex->cs); + if (mutex->cs) + InitializeCriticalSection(mutex->cs); + else + abort(); +} + + +void _al_mutex_init_recursive(_AL_MUTEX *mutex) +{ + /* These are the same on Windows. */ + _al_mutex_init(mutex); +} + + +void _al_mutex_destroy(_AL_MUTEX *mutex) +{ + ASSERT(mutex); + + if (mutex->cs) { + DeleteCriticalSection(mutex->cs); + al_free(mutex->cs); + mutex->cs = NULL; + } +} + + +/* condition variables */ + +/* + * The algorithm used was originally designed for the pthread-win32 + * package. I translated the pseudo-code below line for line. + * + * --- From pthread-win32: --- + * Algorithm: + * The algorithm used in this implementation is that developed by + * Alexander Terekhov in colaboration with Louis Thomas. The bulk + * of the discussion is recorded in the file README.CV, which contains + * several generations of both colaborators original algorithms. The final + * algorithm used here is the one referred to as + * + * Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL + * + * presented below in pseudo-code as it appeared: + * + * [snip] + * ------------------------------------------------------------- + * + * Algorithm 9 / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL + * + * presented below in pseudo-code; basically 8a... + * ...BUT W/O "spurious wakes" prevention: + * + * + * given: + * semBlockLock - bin.semaphore + * semBlockQueue - semaphore + * mtxExternal - mutex or CS + * mtxUnblockLock - mutex or CS + * nWaitersGone - int + * nWaitersBlocked - int + * nWaitersToUnblock - int + * + * wait( timeout ) { + * + * [auto: register int result ] // error checking omitted + * [auto: register int nSignalsWasLeft ] + * + * sem_wait( semBlockLock ); + * ++nWaitersBlocked; + * sem_post( semBlockLock ); + * + * unlock( mtxExternal ); + * bTimedOut = sem_wait( semBlockQueue,timeout ); + * + * lock( mtxUnblockLock ); + * if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) { + * --nWaitersToUnblock; + * } + * else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or + * // spurious semaphore :-) + * sem_wait( semBlockLock ); + * nWaitersBlocked -= nWaitersGone; // something is going on here + * // - test of timeouts? :-) + * sem_post( semBlockLock ); + * nWaitersGone = 0; + * } + * unlock( mtxUnblockLock ); + * + * if ( 1 == nSignalsWasLeft ) { + * sem_post( semBlockLock ); // open the gate + * } + * + * lock( mtxExternal ); + * + * return ( bTimedOut ) ? ETIMEOUT : 0; + * } + * + * signal(bAll) { + * + * [auto: register int result ] + * [auto: register int nSignalsToIssue] + * + * lock( mtxUnblockLock ); + * + * if ( 0 != nWaitersToUnblock ) { // the gate is closed!!! + * if ( 0 == nWaitersBlocked ) { // NO-OP + * return unlock( mtxUnblockLock ); + * } + * if (bAll) { + * nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked; + * nWaitersBlocked = 0; + * } + * else { + * nSignalsToIssue = 1; + * ++nWaitersToUnblock; + * --nWaitersBlocked; + * } + * } + * else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION! + * sem_wait( semBlockLock ); // close the gate + * if ( 0 != nWaitersGone ) { + * nWaitersBlocked -= nWaitersGone; + * nWaitersGone = 0; + * } + * if (bAll) { + * nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked; + * nWaitersBlocked = 0; + * } + * else { + * nSignalsToIssue = nWaitersToUnblock = 1; + * --nWaitersBlocked; + * } + * } + * else { // NO-OP + * return unlock( mtxUnblockLock ); + * } + * + * unlock( mtxUnblockLock ); + * sem_post( semBlockQueue,nSignalsToIssue ); + * return result; + * } + * ------------------------------------------------------------- + */ + + +void _al_cond_init(_AL_COND *cond) +{ + cond->nWaitersBlocked = 0; + cond->nWaitersGone = 0; + cond->nWaitersToUnblock = 0; + cond->semBlockQueue = CreateSemaphore(NULL, 0, INT_MAX, NULL); + InitializeCriticalSection(&cond->semBlockLock); + InitializeCriticalSection(&cond->mtxUnblockLock); +} + + +void _al_cond_destroy(_AL_COND *cond) +{ + DeleteCriticalSection(&cond->mtxUnblockLock); + DeleteCriticalSection(&cond->semBlockLock); + CloseHandle(cond->semBlockQueue); +} + + +/* returns -1 on timeout */ +static int cond_wait(_AL_COND *cond, _AL_MUTEX *mtxExternal, DWORD timeout) +{ + int nSignalsWasLeft; + bool bTimedOut; + DWORD dwWaitResult; + + EnterCriticalSection(&cond->semBlockLock); + ++cond->nWaitersBlocked; + LeaveCriticalSection(&cond->semBlockLock); + + _al_mutex_unlock(mtxExternal); + + dwWaitResult = WaitForSingleObject(cond->semBlockQueue, timeout); + if (dwWaitResult == WAIT_TIMEOUT) + bTimedOut = true; + else if (dwWaitResult == WAIT_OBJECT_0) + bTimedOut = false; + else { + /* bad! what to do? */ + _al_mutex_lock(mtxExternal); + ASSERT(false); + return 0; + } + + EnterCriticalSection(&cond->mtxUnblockLock); + if (0 != (nSignalsWasLeft = cond->nWaitersToUnblock)) { + --(cond->nWaitersToUnblock); + } + else if (INT_MAX/2 == ++(cond->nWaitersGone)) { /* timeout/canceled or spurious semaphore :-) */ + EnterCriticalSection(&cond->semBlockLock); + cond->nWaitersBlocked -= cond->nWaitersGone; /* something is going on here + - test of timeouts? :-) */ + LeaveCriticalSection(&cond->semBlockLock); + cond->nWaitersGone = 0; + } + LeaveCriticalSection(&cond->mtxUnblockLock); + + if (1 == nSignalsWasLeft) { + LeaveCriticalSection(&cond->semBlockLock); /* open the gate */ + } + + _al_mutex_lock(mtxExternal); + + return bTimedOut ? -1 : 0; +} + + +void _al_cond_wait(_AL_COND *cond, _AL_MUTEX *mtxExternal) +{ + int result; + + ASSERT(cond); + ASSERT(mtxExternal); + + result = cond_wait(cond, mtxExternal, INFINITE); + ASSERT(result != -1); + (void)result; +} + + +int _al_cond_timedwait(_AL_COND *cond, _AL_MUTEX *mtxExternal, + const ALLEGRO_TIMEOUT *timeout) +{ + ALLEGRO_TIMEOUT_WIN *win_timeout = (ALLEGRO_TIMEOUT_WIN *) timeout; + DWORD now; + DWORD rel_msecs; + + ASSERT(cond); + ASSERT(mtxExternal); + + now = timeGetTime(); + rel_msecs = win_timeout->abstime - now; + if (rel_msecs > INT_MAX) { + rel_msecs = 0; + } + + return cond_wait(cond, mtxExternal, rel_msecs); +} + + +static void cond_signal(_AL_COND *cond, bool bAll) +{ + int nSignalsToIssue; + + EnterCriticalSection(&cond->mtxUnblockLock); + + if (0 != cond->nWaitersToUnblock) { /* the gate is closed!!! */ + if (0 == cond->nWaitersBlocked) { /* NO-OP */ + LeaveCriticalSection(&cond->mtxUnblockLock); + return; + } + if (bAll) { + cond->nWaitersToUnblock += (nSignalsToIssue = cond->nWaitersBlocked); + cond->nWaitersBlocked = 0; + } + else { + nSignalsToIssue = 1; + ++cond->nWaitersToUnblock; + --cond->nWaitersBlocked; + } + } + else if (cond->nWaitersBlocked > cond->nWaitersGone) { /* HARMLESS RACE CONDITION! */ + EnterCriticalSection(&cond->semBlockLock); /* close the gate */ + if (0 != cond->nWaitersGone) { + cond->nWaitersBlocked -= cond->nWaitersGone; + cond->nWaitersGone = 0; + } + if (bAll) { + nSignalsToIssue = (cond->nWaitersToUnblock = cond->nWaitersBlocked); + cond->nWaitersBlocked = 0; + } + else { + nSignalsToIssue = cond->nWaitersToUnblock = 1; + --cond->nWaitersBlocked; + } + } + else { /* NO-OP */ + LeaveCriticalSection(&cond->mtxUnblockLock); + return; + } + + LeaveCriticalSection(&cond->mtxUnblockLock); + ReleaseSemaphore(cond->semBlockQueue, nSignalsToIssue, NULL); + return; +} + + +void _al_cond_broadcast(_AL_COND *cond) +{ + cond_signal(cond, true); +} + + +void _al_cond_signal(_AL_COND *cond) +{ + cond_signal(cond, false); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/icon.xpm b/allegro/src/x/icon.xpm new file mode 100644 index 00000000..e25d4a96 --- /dev/null +++ b/allegro/src/x/icon.xpm @@ -0,0 +1,57 @@ +/* XPM */ +static char *icon_xpm[] = { +"48 48 6 1", +" c None", +". c #080808", +"+ c #FCFCFC", +"@ c #486028", +"# c #587834", +"$ c #A4C47C", +" .... .... ", +" .... .... ", +" .++++.. .++++.. ", +" .++++.. .++++.. ", +" ...... ...++.......++... ", +" ...... ...++.......++... ", +"..@@####............@@###....##@.. ", +"..@@####............@@###....##@.. ", +"..###########################..#@@.. ", +"..###########################..#@@.. ", +".............................#####.. ", +".............................#####.. ", +" ...#########@@.. ", +" ......#####..#######.. ", +" ......#####..#######.. ", +" .....######.....$$#######.. ", +" .....######.....$$#######.. ", +" .....#####...... ..$$#######.. ", +" .....#####...... ..$$#######.. ", +" ..#####..... .$$##..###@@.. ", +" ..#####..... .$$##..###@@.. ", +" ..... .......###@@.. ", +" ..... .......###@@.. ", +" ..#########.@@.. ", +" ..##.......@##.. ", +" ..##.......@##.. ", +" ...$$$$#####.. ", +" ...$$$$#####.. ", +" .$$$$#####.. .. ", +" .$$$$#####.. .. ", +" .$$$$#####.. ..@@.", +" .$$$$#####.. ..@@.", +" .$$..#####@@.. ..@@.", +" .$$..#####@@.. ..@@.", +" ..####@..##.. ..##@@.", +" ..####@..##.. ..##@@.", +" ..####@..####...##@@$$.", +" .####@@.$$#######@@$$.. ", +" .####@@.$$#######@@$$.. ", +" .##@@.....$$$$$$$$$.. ", +" .##@@.....$$$$$$$$$.. ", +" ..##@@............ ", +" ..##@@............ ", +" ...######.@@.. ", +" ...######.@@.. ", +" ..#####@@###..@@.. ", +" ..#####@@###..@@.. ", +" .................. "}; diff --git a/allegro/src/x/xclipboard.c b/allegro/src/x/xclipboard.c new file mode 100644 index 00000000..5273846f --- /dev/null +++ b/allegro/src/x/xclipboard.c @@ -0,0 +1,235 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_//_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * X11 clipboard handling. + * + * By Beoran. + * + * See readme.txt for copyright information. + */ + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xclipboard.h" +#include "allegro5/internal/aintern_xcursor.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xsystem.h" + +#ifdef ALLEGRO_RASPBERRYPI +#include "allegro5/internal/aintern_raspberrypi.h" +#define ALLEGRO_SYSTEM_XGLX ALLEGRO_SYSTEM_RASPBERRYPI +#define ALLEGRO_DISPLAY_XGLX ALLEGRO_DISPLAY_RASPBERRYPI +#endif + +ALLEGRO_DEBUG_CHANNEL("clipboard") + + +void _al_xwin_display_selection_notify(ALLEGRO_DISPLAY *display, XSelectionEvent *xselection) +{ + (void) display; (void) xselection; +} + + +void _al_xwin_display_selection_request(ALLEGRO_DISPLAY *display, XSelectionRequestEvent *xselectionrequest) +{ + (void) display; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Display *xdisplay = system->x11display; + + + XSelectionRequestEvent *req; + XEvent sevent = { 0 }; + int seln_format; + unsigned long nbytes; + unsigned long overflow; + unsigned char *seln_data; + + req = xselectionrequest; + + ALLEGRO_DEBUG("window %p: SelectionRequest (requestor = %ld, target = %ld)\n", xdisplay, + req->requestor, req->target); + + memset(&sevent, 0, sizeof(sevent)); + sevent.xany.type = SelectionNotify; + sevent.xselection.selection = req->selection; + sevent.xselection.target = None; + sevent.xselection.property = None; + sevent.xselection.requestor = req->requestor; + sevent.xselection.time = req->time; + + if (XGetWindowProperty(xdisplay, DefaultRootWindow(xdisplay), + XA_CUT_BUFFER0, 0, INT_MAX/4, False, req->target, + &sevent.xselection.target, &seln_format, &nbytes, + &overflow, &seln_data) == Success) { + Atom XA_TARGETS = XInternAtom(xdisplay, "TARGETS", 0); + if (sevent.xselection.target == req->target) { + XChangeProperty(xdisplay, req->requestor, req->property, + sevent.xselection.target, seln_format, PropModeReplace, + seln_data, nbytes); + sevent.xselection.property = req->property; + } else if (XA_TARGETS == req->target) { + Atom SupportedFormats[] = { sevent.xselection.target, XA_TARGETS }; + XChangeProperty(xdisplay, req->requestor, req->property, + XA_ATOM, 32, PropModeReplace, + (unsigned char *)SupportedFormats, + sizeof(SupportedFormats)/sizeof(*SupportedFormats)); + sevent.xselection.property = req->property; + } + XFree(seln_data); + } + XSendEvent(xdisplay, req->requestor, False, 0, &sevent); + XSync(xdisplay, False); +} + + +/* Waits for a selection (copy/paste or DND event) */ +static bool _al_display_xglx_await_selection_event(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + ALLEGRO_TIMEOUT timeout; + + ALLEGRO_DEBUG("Awaiting selection event\n"); + + XSync(system->x11display, False); + + /* Wait until the selection event is notified. + * Don't wait forever if an event never comes. + */ + al_init_timeout(&timeout, 1.0); + if (_al_cond_timedwait(&glx->selectioned, &system->lock, &timeout) == -1) { + ALLEGRO_ERROR("Timeout while waiting for selection event.\n"); + return false; + } + + return true; +} + + +static bool xdpy_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text) +{ + + ALLEGRO_DISPLAY_XGLX *glx = (void *)display; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Display *xdisplay = system->x11display; + Window xwindow = glx->window; + + Atom format; + Atom XA_CLIPBOARD = XInternAtom(xdisplay, "CLIPBOARD", 0); + + /* Get the window that will own the selection */ + if (xwindow == None) { + ALLEGRO_DEBUG("Couldn't find a window to own the selection"); + return false; + } + + /* Save the selection on the root window */ + /* If you don't support UTF-8, you might use XA_STRING here */ + format = XInternAtom(xdisplay, "UTF8_STRING", False); + XChangeProperty(xdisplay, DefaultRootWindow(xdisplay), + XA_CUT_BUFFER0, format, 8, PropModeReplace, + (const unsigned char *)text, strlen(text)); + + if (XA_CLIPBOARD != None && + XGetSelectionOwner(xdisplay, XA_CLIPBOARD) != xwindow) { + XSetSelectionOwner(xdisplay, XA_CLIPBOARD, xwindow, CurrentTime); + } + + if (XGetSelectionOwner(xdisplay, XA_PRIMARY) != xwindow) { + XSetSelectionOwner(xdisplay, XA_PRIMARY, xwindow, CurrentTime); + } + + return true; +} + + +static char *xdpy_get_clipboard_text(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_XGLX *glx = (void *)display; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Display *xdisplay = system->x11display; + Window xwindow = glx->window; + + Atom format; + Window owner; + Atom selection; + Atom seln_type; + int seln_format; + unsigned long nbytes; + unsigned long overflow; + unsigned char *src; + char *text = NULL; + + Atom XA_CLIPBOARD = XInternAtom(xdisplay, "CLIPBOARD", 0); + if (XA_CLIPBOARD == None) { + ALLEGRO_DEBUG("Couldn't access X clipboard"); + return NULL; + } + + /* Get the window that holds the selection */ + format = XInternAtom(xdisplay, "UTF8_STRING", 0); + owner = XGetSelectionOwner(xdisplay, XA_CLIPBOARD); + if ((owner == None) || (owner == xwindow)) { + owner = DefaultRootWindow(xdisplay); + selection = XA_CUT_BUFFER0; + } else { + /* Request that the selection owner copy the data to our window. */ + owner = xwindow; + selection = XInternAtom(xdisplay, "ALLEGRO_SELECTION", False); + XConvertSelection(xdisplay, XA_CLIPBOARD, format, selection, owner, + CurrentTime); + + glx->is_selectioned = false; + if (!_al_display_xglx_await_selection_event(display)) + return NULL; + } + + if (XGetWindowProperty(xdisplay, owner, selection, 0, INT_MAX/4, False, + format, &seln_type, &seln_format, &nbytes, &overflow, &src) + == Success) { + if (seln_type == format) { + text = (char *)al_malloc(nbytes+1); + if (text) { + memcpy(text, src, nbytes); + text[nbytes] = '\0'; + } + } + } + XFree(src); + return text; +} + +static bool xdpy_has_clipboard_text(ALLEGRO_DISPLAY *display) +{ + char *text = xdpy_get_clipboard_text(display); + + if (!text) { + return false; + } + + al_free(text); + return true; +} + + + +void _al_xwin_add_clipboard_functions(ALLEGRO_DISPLAY_INTERFACE *vt) +{ + vt->set_clipboard_text = xdpy_set_clipboard_text; + vt->get_clipboard_text = xdpy_get_clipboard_text; + vt->has_clipboard_text = xdpy_has_clipboard_text; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/xcursor.c b/allegro/src/x/xcursor.c new file mode 100644 index 00000000..0932a137 --- /dev/null +++ b/allegro/src/x/xcursor.c @@ -0,0 +1,297 @@ +#include +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xcursor.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xsystem.h" + +#ifdef ALLEGRO_RASPBERRYPI +#include "allegro5/internal/aintern_raspberrypi.h" +#define ALLEGRO_SYSTEM_XGLX ALLEGRO_SYSTEM_RASPBERRYPI +#define ALLEGRO_DISPLAY_XGLX ALLEGRO_DISPLAY_RASPBERRYPI +#endif + +#include + +#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR +#include +#else +/* This requirement could be lifted for compatibility with older systems at the + * expense of functionality, but it's probably not worthwhile. + */ +#error This file requires Xcursor. +#endif + +ALLEGRO_MOUSE_CURSOR *_al_xwin_create_mouse_cursor(ALLEGRO_BITMAP *bmp, + int x_focus, int y_focus) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + Display *xdisplay = system->x11display; + + int bmp_w; + int bmp_h; + ALLEGRO_MOUSE_CURSOR_XWIN *xcursor; + XcursorImage *image; + int c, ix, iy; + bool was_locked; + + bmp_w = al_get_bitmap_width(bmp); + bmp_h = al_get_bitmap_height(bmp); + + xcursor = al_malloc(sizeof *xcursor); + if (!xcursor) { + return NULL; + } + + image = XcursorImageCreate(bmp->w, bmp->h); + if (image == None) { + al_free(xcursor); + return NULL; + } + + was_locked = al_is_bitmap_locked(bmp); + if (!was_locked) { + al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + } + + c = 0; + for (iy = 0; iy < bmp_h; iy++) { + for (ix = 0; ix < bmp_w; ix++) { + ALLEGRO_COLOR col; + unsigned char r, g, b, a; + + col = al_get_pixel(bmp, ix, iy); + al_unmap_rgba(col, &r, &g, &b, &a); + image->pixels[c++] = (a<<24) | (r<<16) | (g<<8) | (b); + } + } + + if (!was_locked) { + al_unlock_bitmap(bmp); + } + + image->xhot = x_focus; + image->yhot = y_focus; + + _al_mutex_lock(&system->lock); + xcursor->cursor = XcursorImageLoadCursor(xdisplay, image); + _al_mutex_unlock(&system->lock); + + XcursorImageDestroy(image); + + return (ALLEGRO_MOUSE_CURSOR *)xcursor; +} + + + +void _al_xwin_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) +{ + ALLEGRO_MOUSE_CURSOR_XWIN *xcursor = (ALLEGRO_MOUSE_CURSOR_XWIN *)cursor; + ALLEGRO_SYSTEM *sys = al_get_system_driver(); + ALLEGRO_SYSTEM_XGLX *sysx = (ALLEGRO_SYSTEM_XGLX *)sys; + unsigned i; + + _al_mutex_lock(&sysx->lock); + + for (i = 0; i < _al_vector_size(&sys->displays); i++) { + ALLEGRO_DISPLAY_XGLX **slot = _al_vector_ref(&sys->displays, i); + ALLEGRO_DISPLAY_XGLX *glx = *slot; + + if (glx->current_cursor == xcursor->cursor) { + if (!glx->cursor_hidden) + XUndefineCursor(sysx->x11display, glx->window); + glx->current_cursor = None; + } + } + + XFreeCursor(sysx->x11display, xcursor->cursor); + al_free(xcursor); + + _al_mutex_unlock(&sysx->lock); +} + + + +static bool xdpy_set_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_MOUSE_CURSOR *cursor) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + ALLEGRO_MOUSE_CURSOR_XWIN *xcursor = (ALLEGRO_MOUSE_CURSOR_XWIN *)cursor; + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + Display *xdisplay = system->x11display; + Window xwindow = glx->window; + + glx->current_cursor = xcursor->cursor; + + if (!glx->cursor_hidden) { + _al_mutex_lock(&system->lock); + XDefineCursor(xdisplay, xwindow, glx->current_cursor); + _al_mutex_unlock(&system->lock); + } + + return true; +} + + + +static bool xdpy_set_system_mouse_cursor(ALLEGRO_DISPLAY *display, + ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + Display *xdisplay = system->x11display; + Window xwindow = glx->window; + unsigned int cursor_shape; + + switch (cursor_id) { + case ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW: + case ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS: + cursor_shape = XC_left_ptr; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY: + cursor_shape = XC_watch; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION: + cursor_shape = XC_question_arrow; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT: + cursor_shape = XC_xterm; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE: + cursor_shape = XC_fleur; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N: + cursor_shape = XC_top_side; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S: + cursor_shape = XC_bottom_side; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E: + cursor_shape = XC_right_side; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W: + cursor_shape = XC_left_side; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE: + cursor_shape = XC_top_right_corner; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW: + cursor_shape = XC_bottom_left_corner; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW: + cursor_shape = XC_top_left_corner; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE: + cursor_shape = XC_bottom_right_corner; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION: + cursor_shape = XC_crosshair; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK: + cursor_shape = XC_hand2; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT: + cursor_shape = XC_hand1; + break; + case ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE: + cursor_shape = XC_X_cursor; + break; + default: + return false; + } + + _al_mutex_lock(&system->lock); + + glx->current_cursor = XCreateFontCursor(xdisplay, cursor_shape); + /* XXX: leak? */ + + if (!glx->cursor_hidden) { + XDefineCursor(xdisplay, xwindow, glx->current_cursor); + } + + _al_mutex_unlock(&system->lock); + + return true; +} + + + +/* Show the system mouse cursor. */ +static bool xdpy_show_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_XGLX *glx = (void *)display; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Display *xdisplay = system->x11display; + Window xwindow = glx->window; + + if (!glx->cursor_hidden) + return true; + + _al_mutex_lock(&system->lock); + XDefineCursor(xdisplay, xwindow, glx->current_cursor); + glx->cursor_hidden = false; + _al_mutex_unlock(&system->lock); + return true; +} + + + +/* Hide the system mouse cursor. */ +static bool xdpy_hide_mouse_cursor(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_XGLX *glx = (void *)display; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Display *xdisplay = system->x11display; + Window xwindow = glx->window; + + if (glx->cursor_hidden) + return true; + + _al_mutex_lock(&system->lock); + + if (glx->invisible_cursor == None) { + unsigned long gcmask; + XGCValues gcvalues; + + Pixmap pixmap = XCreatePixmap(xdisplay, xwindow, 1, 1, 1); + + GC temp_gc; + XColor color; + + gcmask = GCFunction | GCForeground | GCBackground; + gcvalues.function = GXcopy; + gcvalues.foreground = 0; + gcvalues.background = 0; + temp_gc = XCreateGC(xdisplay, pixmap, gcmask, &gcvalues); + XDrawPoint(xdisplay, pixmap, temp_gc, 0, 0); + XFreeGC(xdisplay, temp_gc); + color.pixel = 0; + color.red = color.green = color.blue = 0; + color.flags = DoRed | DoGreen | DoBlue; + glx->invisible_cursor = XCreatePixmapCursor(xdisplay, pixmap, + pixmap, &color, &color, 0, 0); + XFreePixmap(xdisplay, pixmap); + } + + XDefineCursor(xdisplay, xwindow, glx->invisible_cursor); + glx->cursor_hidden = true; + + _al_mutex_unlock(&system->lock); + + return true; +} + + + +void _al_xwin_add_cursor_functions(ALLEGRO_DISPLAY_INTERFACE *vt) +{ + vt->set_mouse_cursor = xdpy_set_mouse_cursor; + vt->set_system_mouse_cursor = xdpy_set_system_mouse_cursor; + vt->show_mouse_cursor = xdpy_show_mouse_cursor; + vt->hide_mouse_cursor = xdpy_hide_mouse_cursor; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/xdisplay.c b/allegro/src/x/xdisplay.c new file mode 100644 index 00000000..81e83398 --- /dev/null +++ b/allegro/src/x/xdisplay.c @@ -0,0 +1,1453 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xcursor.h" +#include "allegro5/internal/aintern_xclipboard.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xfullscreen.h" +#include "allegro5/internal/aintern_xglx_config.h" +#include "allegro5/internal/aintern_xsystem.h" +#include "allegro5/internal/aintern_xtouch.h" +#include "allegro5/internal/aintern_xwindow.h" +#include "allegro5/platform/aintxglx.h" + +#include +#ifdef ALLEGRO_XWINDOWS_WITH_XINPUT2 +#include +#endif + +#ifdef ALLEGRO_XWINDOWS_WITH_XPM +#include +#endif + +#include "xicon.h" + +ALLEGRO_DEBUG_CHANNEL("display") + +static ALLEGRO_DISPLAY_INTERFACE xdpy_vt; +static const ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE default_overridable_vt; +static const ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE *gtk_override_vt = NULL; + +static void xdpy_destroy_display(ALLEGRO_DISPLAY *d); +static bool xdpy_acknowledge_resize(ALLEGRO_DISPLAY *d); + + +/* XXX where does this belong? */ +static void _al_xglx_use_adapter(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + ALLEGRO_DEBUG("use adapter %i\n", adapter); + s->adapter_use_count++; + s->adapter_map[adapter]++; +} + + +static void _al_xglx_unuse_adapter(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + ALLEGRO_DEBUG("unuse adapter %i\n", adapter); + s->adapter_use_count--; + s->adapter_map[adapter]--; +} + + +static bool check_adapter_use_count(ALLEGRO_SYSTEM_XGLX *system) +{ + /* If we're in multi-head X mode, bail out if we try to use more than one + * display as there are bugs in X/glX that cause us to hang in X if we try + * to use more than one. + * If we're in real xinerama mode, also bail out, X makes mouse use evil. + */ + bool true_xinerama_active = false; +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + bool xrandr_active = false; +#ifdef ALLEGRO_XWINDOWS_WITH_XRANDR + xrandr_active = system->xrandr_available; +#endif + true_xinerama_active = !xrandr_active && system->xinerama_available; +#endif + + if ((true_xinerama_active || ScreenCount(system->x11display) > 1) + && system->adapter_use_count > 0) + { + int i, adapter_use_count = 0; + + /* XXX magic constant */ + for (i = 0; i < 32; i++) { + if (system->adapter_map[i]) + adapter_use_count++; + } + + if (adapter_use_count > 1) { + ALLEGRO_ERROR("Use of more than one adapter at once in " + "multi-head X or X with true Xinerama active is not possible.\n"); + return false; + } + } + + return true; +} + + +static int query_glx_version(ALLEGRO_SYSTEM_XGLX *system) +{ + int major, minor; + int version; + + glXQueryVersion(system->x11display, &major, &minor); + version = major * 100 + minor * 10; + ALLEGRO_INFO("GLX %.1f.\n", version / 100.f); + return version; +} + + +static int xdpy_swap_control(ALLEGRO_DISPLAY *display, int vsync_setting) +{ + /* We set the swap interval to 0 if vsync is forced off, and to 1 + * if it is forced on. + * http://www.opengl.org/registry/specs/SGI/swap_control.txt + * If the option is set to 0, we simply use the system default. The + * above extension specifies vsync on as default though, so in the + * end with GLX we can't force vsync on, just off. + */ + ALLEGRO_DEBUG("requested vsync=%d.\n", vsync_setting); + + if (vsync_setting) { + if (display->ogl_extras->extension_list->ALLEGRO_GLX_SGI_swap_control) { + int x = (vsync_setting == 2) ? 0 : 1; + if (glXSwapIntervalSGI(x)) { + ALLEGRO_WARN("glXSwapIntervalSGI(%d) failed.\n", x); + } + } + else { + ALLEGRO_WARN("no vsync, GLX_SGI_swap_control missing.\n"); + /* According to the specification that means it's on, but + * the driver might have disabled it. So we do not know. + */ + vsync_setting = 0; + } + } + + return vsync_setting; +} + +static bool should_bypass_compositor(int flags) +{ + const char* value = al_get_config_value(al_get_system_config(), "x11", "bypass_compositor"); + if (value && strcmp(value, "always") == 0) { + return true; + } + if (value && strcmp(value, "never") == 0) { + return false; + } + // default to "fullscreen_only" + return (flags & ALLEGRO_FULLSCREEN) || (flags & ALLEGRO_FULLSCREEN_WINDOW); +} + +static void set_compositor_bypass_flag(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + const long _NET_WM_BYPASS_COMPOSITOR_HINT_ON = should_bypass_compositor(display->flags); + Atom _NET_WM_BYPASS_COMPOSITOR; + + _NET_WM_BYPASS_COMPOSITOR = XInternAtom(system->x11display, + "_NET_WM_BYPASS_COMPOSITOR", + False); + XChangeProperty(system->x11display, glx->window, _NET_WM_BYPASS_COMPOSITOR, + XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)&_NET_WM_BYPASS_COMPOSITOR_HINT_ON, 1); +} + + +static bool xdpy_create_display_window(ALLEGRO_SYSTEM_XGLX *system, + ALLEGRO_DISPLAY_XGLX *d, int w, int h, int adapter) +{ + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)d; + + /* Create a colormap. */ + Colormap cmap = XCreateColormap(system->x11display, + RootWindow(system->x11display, d->xvinfo->screen), + d->xvinfo->visual, AllocNone); + + /* Create an X11 window */ + XSetWindowAttributes swa; + int mask = CWBorderPixel | CWColormap | CWEventMask; + swa.colormap = cmap; + swa.border_pixel = 0; + swa.event_mask = + KeyPressMask | + KeyReleaseMask | + StructureNotifyMask | + EnterWindowMask | + LeaveWindowMask | + FocusChangeMask | + ExposureMask | + PropertyChangeMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask; + + /* For a non-compositing window manager, a black background can look + * less broken if the application doesn't react to expose events fast + * enough. However in some cases like resizing, the black background + * causes horrible flicker. + */ + if (!(display->flags & ALLEGRO_RESIZABLE)) { + mask |= CWBackPixel; + swa.background_pixel = BlackPixel(system->x11display, d->xvinfo->screen); + } + + int x_off = INT_MAX; + int y_off = INT_MAX; + if (display->flags & ALLEGRO_FULLSCREEN) { + _al_xglx_get_display_offset(system, d->adapter, &x_off, &y_off); + } + else { + /* We want new_display_adapter's offset to add to the + * new_window_position. + */ + int xscr_x = 0; + int xscr_y = 0; + al_get_new_window_position(&x_off, &y_off); + + if (adapter >= 0) { + /* Non default adapter. I'm assuming this means the user wants the + * window to be placed on the adapter offset by new display pos. + */ + _al_xglx_get_display_offset(system, d->adapter, &xscr_x, &xscr_y); + if (x_off != INT_MAX) + x_off += xscr_x; + if (y_off != INT_MAX) + y_off += xscr_y; + } + } + + d->window = XCreateWindow(system->x11display, + RootWindow(system->x11display, d->xvinfo->screen), + x_off != INT_MAX ? x_off : 0, + y_off != INT_MAX ? y_off : 0, + w, h, 0, d->xvinfo->depth, + InputOutput, d->xvinfo->visual, mask, &swa); + + ALLEGRO_DEBUG("Window ID: %ld\n", (long)d->window); + + /* Try to set full screen mode if requested, fail if we can't. */ + if (display->flags & ALLEGRO_FULLSCREEN) { + /* According to the spec, the window manager is supposed to disable + * window decorations when _NET_WM_STATE_FULLSCREEN is in effect. + * However, some WMs may not be fully compliant, e.g. Fluxbox. + */ + _al_xwin_set_frame(display, false); + _al_xwin_set_above(display, 1); + if (!_al_xglx_fullscreen_set_mode(system, d, w, h, 0, + display->refresh_rate)) { + ALLEGRO_DEBUG("xdpy: failed to set fullscreen mode.\n"); + return false; + } + } + + if (display->flags & ALLEGRO_FRAMELESS) { + _al_xwin_set_frame(display, false); + } + + ALLEGRO_DEBUG("X11 window created.\n"); + + /* Set the PID related to the window. */ + Atom _NET_WM_PID = XInternAtom(system->x11display, "_NET_WM_PID", False); + int pid = getpid(); + XChangeProperty(system->x11display, d->window, _NET_WM_PID, XA_CARDINAL, + 32, PropModeReplace, (unsigned char *)&pid, 1); + + _al_xwin_set_size_hints(display, x_off, y_off); + + /* Let the window manager know we're a "normal" window */ + Atom _NET_WM_WINDOW_TYPE; + Atom _NET_WM_WINDOW_TYPE_NORMAL; + + _NET_WM_WINDOW_TYPE = XInternAtom(system->x11display, "_NET_WM_WINDOW_TYPE", + False); + _NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(system->x11display, + "_NET_WM_WINDOW_TYPE_NORMAL", + False); + XChangeProperty(system->x11display, d->window, _NET_WM_WINDOW_TYPE, XA_ATOM, + 32, PropModeReplace, + (unsigned char *)&_NET_WM_WINDOW_TYPE_NORMAL, 1); + + /* This seems like a good idea */ + set_compositor_bypass_flag(display); + +#ifdef ALLEGRO_XWINDOWS_WITH_XINPUT2 + /* listen for touchscreen events */ + XIEventMask event_mask; + event_mask.deviceid = XIAllMasterDevices; + event_mask.mask_len = XIMaskLen(XI_TouchEnd); + event_mask.mask = (unsigned char*)al_calloc(3, sizeof(char)); + XISetMask(event_mask.mask, XI_TouchBegin); + XISetMask(event_mask.mask, XI_TouchUpdate); + XISetMask(event_mask.mask, XI_TouchEnd); + + XISelectEvents(system->x11display, d->window, &event_mask, 1); + + al_free(event_mask.mask); +#endif + + return true; +} + + +static ALLEGRO_DISPLAY_XGLX *xdpy_create_display_locked( + ALLEGRO_SYSTEM_XGLX *system, int flags, int w, int h, int adapter) +{ + ALLEGRO_DISPLAY_XGLX *d = al_calloc(1, sizeof *d); + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)d; + ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl); + display->ogl_extras = ogl; + + d->glx_version = query_glx_version(system); + + display->w = w; + display->h = h; + display->vt = _al_display_xglx_driver(); + display->refresh_rate = al_get_new_display_refresh_rate(); + display->flags = flags; + // FIXME: default? Is this the right place to set this? + display->flags |= ALLEGRO_OPENGL; +#ifdef ALLEGRO_CFG_OPENGLES2 + display->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; +#endif +#ifdef ALLEGRO_CFG_OPENGLES + display->flags |= ALLEGRO_OPENGL_ES_PROFILE; +#endif + + /* Store our initial virtual adapter, used by fullscreen and positioning + * code. + */ + ALLEGRO_DEBUG("selected adapter %i\n", adapter); + if (adapter < 0) + d->adapter = _al_xglx_get_default_adapter(system); + else + d->adapter = adapter; + + ALLEGRO_DEBUG("xdpy: selected adapter %i\n", d->adapter); + _al_xglx_use_adapter(system, d->adapter); + if (!check_adapter_use_count(system)) { + goto EarlyError; + } + + /* Store our initial X Screen, used by window creation, fullscreen, and glx + * visual code. + */ + d->xscreen = _al_xglx_get_xscreen(system, d->adapter); + ALLEGRO_DEBUG("xdpy: selected xscreen %i\n", d->xscreen); + + d->wm_delete_window_atom = None; + + d->is_mapped = false; + _al_cond_init(&d->mapped); + + d->is_selectioned = false; + _al_cond_init(&d->selectioned); + + + d->resize_count = 0; + d->programmatic_resize = false; + + _al_xglx_config_select_visual(d); + + if (!d->xvinfo) { + ALLEGRO_ERROR("FIXME: Need better visual selection.\n"); + ALLEGRO_ERROR("No matching visual found.\n"); + goto EarlyError; + } + + ALLEGRO_INFO("Selected X11 visual %lu.\n", d->xvinfo->visualid); + + /* Add ourself to the list of displays. */ + ALLEGRO_DISPLAY_XGLX **add; + add = _al_vector_alloc_back(&system->system.displays); + *add = d; + + /* Each display is an event source. */ + _al_event_source_init(&display->es); + + if (!xdpy_create_display_window(system, d, w, h, adapter)) { + goto LateError; + } + + /* Send any pending requests to the X server. + * This is necessary to make the window ID immediately valid + * for a GtkSocket. + */ + XSync(system->x11display, False); + + if (display->flags & ALLEGRO_GTK_TOPLEVEL_INTERNAL) { + ASSERT(gtk_override_vt); + if (!gtk_override_vt->create_display_hook(display, w, h)) { + goto LateError; + } + } + else { + default_overridable_vt.set_window_title(display, al_get_new_window_title()); + if (!default_overridable_vt.create_display_hook(display, w, h)) { + goto LateError; + } + } + + /* overridable_vt should be set by the create_display_hook. */ + ASSERT(d->overridable_vt); + + /* Send any pending requests to the X server. */ + XSync(system->x11display, False); + + /* To avoid race conditions where some X11 functions fail before the window + * is mapped, we wait here until it is mapped. Note that the thread is + * locked, so the event could not possibly have been processed yet in the + * events thread. So as long as no other map events occur, the condition + * should only be signalled when our window gets mapped. + */ + while (!d->is_mapped) { + _al_cond_wait(&d->mapped, &system->lock); + } + /* In tiling WMs, we might get resize events pretty much immediately after + * Window creation. This location seems to catch them reliably, tested with + * dwm, awesome, xmonad and i3. */ + if ((display->flags & ALLEGRO_RESIZABLE) && d->resize_count > 0) { + xdpy_acknowledge_resize(display); + } + + /* We can do this at any time, but if we already have a mapped + * window when switching to fullscreen it will use the same + * monitor (with the MetaCity version I'm using here right now). + */ + if ((display->flags & ALLEGRO_FULLSCREEN_WINDOW)) { + ALLEGRO_INFO("Toggling fullscreen flag for %d x %d window.\n", + display->w, display->h); + _al_xwin_reset_size_hints(display); + _al_xwin_set_fullscreen_window(display, 2); + _al_xwin_set_size_hints(display, INT_MAX, INT_MAX); + + XWindowAttributes xwa; + XGetWindowAttributes(system->x11display, d->window, &xwa); + display->w = xwa.width; + display->h = xwa.height; + ALLEGRO_INFO("Using ALLEGRO_FULLSCREEN_WINDOW of %d x %d\n", + display->w, display->h); + } + + if (display->flags & ALLEGRO_FULLSCREEN) { + /* kwin wants these here */ + /* metacity wants these here too */ + /* XXX compiz is quiky, can't seem to find a combination of hints that + * make sure we are layerd over panels, and are positioned properly */ + + //_al_xwin_set_fullscreen_window(display, 1); + _al_xwin_set_above(display, 1); + + _al_xglx_fullscreen_to_display(system, d); + + /* Grab mouse if we only have one display, ungrab it if we have more than + * one. + */ + if (_al_vector_size(&system->system.displays) == 1) { + al_grab_mouse(display); + } + else if (_al_vector_size(&system->system.displays) > 1) { + al_ungrab_mouse(); + } + } + + if (flags & ALLEGRO_MAXIMIZED) { + _al_xwin_maximize(display, true); + } + + if (!_al_xglx_config_create_context(d)) { + goto LateError; + } + + /* Make our GLX context current for reading and writing in the current + * thread. + */ + if (d->fbc) { + if (!glXMakeContextCurrent(system->gfxdisplay, d->glxwindow, + d->glxwindow, d->context)) { + ALLEGRO_ERROR("glXMakeContextCurrent failed\n"); + } + } + else { + if (!glXMakeCurrent(system->gfxdisplay, d->glxwindow, d->context)) { + ALLEGRO_ERROR("glXMakeCurrent failed\n"); + } + } + + _al_ogl_manage_extensions(display); + _al_ogl_set_extensions(ogl->extension_api); + + /* Print out OpenGL version info */ + ALLEGRO_INFO("OpenGL Version: %s\n", (const char*)glGetString(GL_VERSION)); + ALLEGRO_INFO("Vendor: %s\n", (const char*)glGetString(GL_VENDOR)); + ALLEGRO_INFO("Renderer: %s\n", (const char*)glGetString(GL_RENDERER)); + + /* Fill in opengl version */ + const int v = display->ogl_extras->ogl_info.version; + display->extra_settings.settings[ALLEGRO_OPENGL_MAJOR_VERSION] = (v >> 24) & 0xFF; + display->extra_settings.settings[ALLEGRO_OPENGL_MINOR_VERSION] = (v >> 16) & 0xFF; + + if (display->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_1_2) { + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings(); + if (eds->required & (1<extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0; + } + + if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY]) + _al_ogl_setup_gl(display); + + /* vsync */ + int vsync_setting = _al_get_new_display_settings()->settings[ALLEGRO_VSYNC]; + vsync_setting = xdpy_swap_control(display, vsync_setting); + display->extra_settings.settings[ALLEGRO_VSYNC] = vsync_setting; + + d->invisible_cursor = None; /* Will be created on demand. */ + d->current_cursor = None; /* Initially, we use the root cursor. */ + d->cursor_hidden = false; + + d->icon = None; + d->icon_mask = None; + + return d; + +EarlyError: + al_free(d); + al_free(ogl); + return NULL; + +LateError: + xdpy_destroy_display(display); + return NULL; +} + +static void set_initial_icon(Display *x11display, Window window) +{ +#ifdef ALLEGRO_XWINDOWS_WITH_XPM + XWMHints *wm_hints; + + if (x11_xpm == NULL) + return; + + wm_hints = XAllocWMHints(); + + wm_hints->flags |= IconPixmapHint | IconMaskHint; + XpmCreatePixmapFromData(x11display, window, x11_xpm, + &wm_hints->icon_pixmap, &wm_hints->icon_mask, NULL); + + XSetWMHints(x11display, window, wm_hints); + XFree(wm_hints); +#else + (void)x11display; + (void)window; +#endif +} + +static bool xdpy_create_display_hook_default(ALLEGRO_DISPLAY *display, + int w, int h) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; + (void)w; + (void)h; + + set_initial_icon(system->x11display, d->window); + + XLockDisplay(system->x11display); + + XMapWindow(system->x11display, d->window); + ALLEGRO_DEBUG("X11 window mapped.\n"); + + d->wm_delete_window_atom = XInternAtom(system->x11display, + "WM_DELETE_WINDOW", False); + XSetWMProtocols(system->x11display, d->window, &d->wm_delete_window_atom, 1); + + XUnlockDisplay(system->x11display); + + d->overridable_vt = &default_overridable_vt; + + return true; +} + + +/* Create a new X11 display, which maps directly to a GLX window. */ +static ALLEGRO_DISPLAY *xdpy_create_display(int w, int h) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *display; + int flags; + int adapter; + + if (system->x11display == NULL) { + ALLEGRO_WARN("Not connected to X server.\n"); + return NULL; + } + + if (w <= 0 || h <= 0) { + ALLEGRO_ERROR("Invalid window size %dx%d\n", w, h); + return NULL; + } + + flags = al_get_new_display_flags(); + if (flags & ALLEGRO_GTK_TOPLEVEL_INTERNAL) { + if (gtk_override_vt == NULL) { + ALLEGRO_ERROR("GTK requested but unavailable\n"); + return NULL; + } + if (flags & ALLEGRO_FULLSCREEN) { + ALLEGRO_ERROR("GTK incompatible with fullscreen\n"); + return NULL; + } + } + + _al_mutex_lock(&system->lock); + + adapter = al_get_new_display_adapter(); + display = xdpy_create_display_locked(system, flags, w, h, adapter); + + _al_mutex_unlock(&system->lock); + + return (ALLEGRO_DISPLAY *)display; +} + + +static void convert_display_bitmaps_to_memory_bitmap(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_DEBUG("converting display bitmaps to memory bitmaps.\n"); + + while (d->bitmaps._size > 0) { + ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps); + ALLEGRO_BITMAP *b = *bptr; + _al_convert_to_memory_bitmap(b); + } +} + + +static void transfer_display_bitmaps_to_any_other_display( + ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY *d) +{ + size_t i; + ALLEGRO_DISPLAY *living = NULL; + ASSERT(s->system.displays._size > 1); + + for (i = 0; i < s->system.displays._size; i++) { + ALLEGRO_DISPLAY **slot = _al_vector_ref(&s->system.displays, i); + living = *slot; + if (living != d) + break; + } + + ALLEGRO_DEBUG("transferring display bitmaps to other display.\n"); + + for (i = 0; i < d->bitmaps._size; i++) { + ALLEGRO_BITMAP **add = _al_vector_alloc_back(&(living->bitmaps)); + ALLEGRO_BITMAP **ref = _al_vector_ref(&d->bitmaps, i); + *add = *ref; + (*add)->_display = living; + } +} + + +static void restore_mode_if_last_fullscreen_display(ALLEGRO_SYSTEM_XGLX *s, + ALLEGRO_DISPLAY_XGLX *d) +{ + bool last_fullscreen = true; + size_t i; + + /* If any other fullscreen display is still active on the same adapter, + * we must not touch the video mode. + */ + for (i = 0; i < s->system.displays._size; i++) { + ALLEGRO_DISPLAY_XGLX **slot = _al_vector_ref(&s->system.displays, i); + ALLEGRO_DISPLAY_XGLX *living = *slot; + + if (living == d) + continue; + + /* Check for fullscreen displays on the same adapter. */ + if (living->adapter == d->adapter + && (living->display.flags & ALLEGRO_FULLSCREEN)) { + last_fullscreen = false; + } + } + + if (last_fullscreen) { + ALLEGRO_DEBUG("restore mode.\n"); + _al_xglx_restore_video_mode(s, d->adapter); + } + else { + ALLEGRO_DEBUG("*not* restoring mode.\n"); + } +} + + +static void xdpy_destroy_display_hook_default(ALLEGRO_DISPLAY *d, bool is_last) +{ + ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + (void)is_last; + + if (glx->context) { + glXDestroyContext(s->gfxdisplay, glx->context); + glx->context = NULL; + ALLEGRO_DEBUG("destroy context.\n"); + } + + if (glx->fbc) { + al_free(glx->fbc); + glx->fbc = NULL; + XFree(glx->xvinfo); + glx->xvinfo = NULL; + } + else if (glx->xvinfo) { + al_free(glx->xvinfo); + glx->xvinfo = NULL; + } + + if ((glx->glxwindow) && (glx->glxwindow != glx->window)) { + glXDestroyWindow(s->x11display, glx->glxwindow); + glx->glxwindow = 0; + ALLEGRO_DEBUG("destroy glx window\n"); + } + + _al_cond_destroy(&glx->mapped); + _al_cond_destroy(&glx->selectioned); + + ALLEGRO_DEBUG("destroy window.\n"); + XDestroyWindow(s->x11display, glx->window); + + _al_xglx_unuse_adapter(s, glx->adapter); + + if (d->flags & ALLEGRO_FULLSCREEN) { + restore_mode_if_last_fullscreen_display(s, glx); + } +} + + +static void xdpy_destroy_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; + bool is_last; + + ALLEGRO_DEBUG("destroying display.\n"); + + /* If we're the last display, convert all bitmaps to display independent + * (memory) bitmaps. Otherwise, pass all bitmaps to any other living + * display. We assume all displays are compatible.) + */ + is_last = (s->system.displays._size == 1); + if (is_last) + convert_display_bitmaps_to_memory_bitmap(d); + else + transfer_display_bitmaps_to_any_other_display(s, d); + + _al_ogl_unmanage_extensions(d); + ALLEGRO_DEBUG("unmanaged extensions.\n"); + + _al_mutex_lock(&s->lock); + _al_vector_find_and_delete(&s->system.displays, &d); + + if (ogl->backbuffer) { + _al_ogl_destroy_backbuffer(ogl->backbuffer); + ogl->backbuffer = NULL; + ALLEGRO_DEBUG("destroy backbuffer.\n"); + } + + if (glx->overridable_vt) { + glx->overridable_vt->destroy_display_hook(d, is_last); + } + + if (s->mouse_grab_display == d) { + s->mouse_grab_display = NULL; + } + + _al_vector_free(&d->bitmaps); + _al_event_source_free(&d->es); + + al_free(d->ogl_extras); + al_free(d->vertex_cache); + al_free(d); + + _al_mutex_unlock(&s->lock); + + ALLEGRO_DEBUG("destroy display finished.\n"); +} + + +static bool xdpy_make_current(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + + /* Make our GLX context current for reading and writing in the current + * thread. + */ + if (glx->fbc) { + return glXMakeContextCurrent(system->gfxdisplay, glx->glxwindow, + glx->glxwindow, glx->context); + } + else { + return glXMakeCurrent(system->gfxdisplay, glx->glxwindow, glx->context); + } +} + + +static bool xdpy_set_current_display(ALLEGRO_DISPLAY *d) +{ + bool rc; + + rc = xdpy_make_current(d); + if (rc) { + ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; + _al_ogl_set_extensions(ogl->extension_api); + _al_ogl_update_render_state(d); + } + + return rc; +} + + +static void xdpy_unset_current_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + glXMakeContextCurrent(system->gfxdisplay, None, None, NULL); + (void)d; +} + + +static void xdpy_flip_display(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + + int e = glGetError(); + if (e) { + ALLEGRO_ERROR("OpenGL error was not 0: %s\n", _al_gl_error_string(e)); + } + + if (d->extra_settings.settings[ALLEGRO_SINGLE_BUFFER]) + glFlush(); + else + glXSwapBuffers(system->gfxdisplay, glx->glxwindow); +} + + +static void xdpy_update_display_region(ALLEGRO_DISPLAY *d, int x, int y, + int w, int h) +{ + (void)x; + (void)y; + (void)w; + (void)h; + xdpy_flip_display(d); +} + + +static bool xdpy_acknowledge_resize(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + XWindowAttributes xwa; + unsigned int w, h; + + _al_mutex_lock(&system->lock); + + /* glXQueryDrawable is GLX 1.3+. */ + /* + glXQueryDrawable(system->x11display, glx->glxwindow, GLX_WIDTH, &w); + glXQueryDrawable(system->x11display, glx->glxwindow, GLX_HEIGHT, &h); + */ + + XGetWindowAttributes(system->x11display, glx->window, &xwa); + w = xwa.width; + h = xwa.height; + + if ((int)w != d->w || (int)h != d->h) { + d->w = w; + d->h = h; + + ALLEGRO_DEBUG("xdpy: acknowledge_resize (%d, %d)\n", d->w, d->h); + + /* No context yet means this is a stray call happening during + * initialization. + */ + if (glx->context) { + _al_ogl_setup_gl(d); + } + + _al_xwin_check_maximized(d); + } + + _al_mutex_unlock(&system->lock); + + return true; +} + + +/* Note: The system mutex must be locked (exactly once) so when we + * wait for the condition variable it gets auto-unlocked. For a + * nested lock that would not be the case. + */ +void _al_display_xglx_await_resize(ALLEGRO_DISPLAY *d, int old_resize_count, + bool delay_hack) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + ALLEGRO_TIMEOUT timeout; + + ALLEGRO_DEBUG("Awaiting resize event\n"); + + XSync(system->x11display, False); + + /* Wait until we are actually resized. + * Don't wait forever if an event never comes. + */ + al_init_timeout(&timeout, 1.0); + while (old_resize_count == glx->resize_count) { + if (_al_cond_timedwait(&system->resized, &system->lock, &timeout) == -1) { + ALLEGRO_ERROR("Timeout while waiting for resize event.\n"); + return; + } + } + + /* XXX: This hack helps when toggling between fullscreen windows and not, + * on various window managers. + */ + if (delay_hack) { + al_rest(0.2); + } + + xdpy_acknowledge_resize(d); +} + + +static bool xdpy_resize_display_default(ALLEGRO_DISPLAY *d, int w, int h) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + XWindowAttributes xwa; + int attempts; + bool ret = false; + + _al_mutex_lock(&system->lock); + + /* It seems some X servers will treat the resize as a no-op if the window is + * already the right size, so check for it to avoid a deadlock later. + */ + XGetWindowAttributes(system->x11display, glx->window, &xwa); + if (xwa.width == w && xwa.height == h) { + _al_mutex_unlock(&system->lock); + return false; + } + + if (d->flags & ALLEGRO_FULLSCREEN) { + _al_xwin_set_fullscreen_window(d, 0); + if (!_al_xglx_fullscreen_set_mode(system, glx, w, h, 0, 0)) { + ret = false; + goto skip_resize; + } + attempts = 3; + } + else { + attempts = 1; + } + + /* Hack: try multiple times to resize the window, with delays. KDE reacts + * slowly to the video mode change, and won't resize our window until a + * while after. It would be better to wait for some sort of event rather + * than just waiting some amount of time, but I didn't manage to find that + * event. --pw + */ + for (; attempts >= 0; attempts--) { + const int old_resize_count = glx->resize_count; + ALLEGRO_DEBUG("calling XResizeWindow, attempts=%d\n", attempts); + _al_xwin_reset_size_hints(d); + glx->programmatic_resize = true; + XResizeWindow(system->x11display, glx->window, w, h); + _al_display_xglx_await_resize(d, old_resize_count, + (d->flags & ALLEGRO_FULLSCREEN)); + glx->programmatic_resize = false; + _al_xwin_set_size_hints(d, INT_MAX, INT_MAX); + + if (d->w == w && d->h == h) { + ret = true; + break; + } + + /* Wait before trying again. */ + al_rest(0.333); + } + + if (attempts == 0) { + ALLEGRO_ERROR("XResizeWindow didn't work; giving up\n"); + } + +skip_resize: + + if (d->flags & ALLEGRO_FULLSCREEN) { + _al_xwin_set_fullscreen_window(d, 1); + _al_xwin_set_above(d, 1); + _al_xglx_fullscreen_to_display(system, glx); + ALLEGRO_DEBUG("xdpy: resize fullscreen?\n"); + } + + _al_mutex_unlock(&system->lock); + return ret; +} + + +static bool xdpy_resize_display(ALLEGRO_DISPLAY *d, int w, int h) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + + /* A fullscreen-window can't be resized. */ + if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) + return false; + + return glx->overridable_vt->resize_display(d, w, h); +} + + +void _al_xglx_display_configure(ALLEGRO_DISPLAY *d, int x, int y, + int width, int height, bool setglxy) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + + ALLEGRO_EVENT_SOURCE *es = &glx->display.es; + _al_event_source_lock(es); + + /* Generate a resize event if the size has changed non-programmatically. + * We cannot asynchronously change the display size here yet, since the user + * will only know about a changed size after receiving the resize event. + * Here we merely add the event to the queue. + */ + if (!glx->programmatic_resize && + (d->w != width || + d->h != height)) { + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE; + event.display.timestamp = al_get_time(); + event.display.x = x; + event.display.y = y; + event.display.width = width; + event.display.height = height; + _al_event_source_emit_event(es, &event); + } + } + + if (setglxy) { + glx->x = x; + glx->y = y; + } + + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX*)al_get_system_driver(); + ALLEGRO_MONITOR_INFO mi; + int center_x = (glx->x + (glx->x + width)) / 2; + int center_y = (glx->y + (glx->y + height)) / 2; + + _al_xglx_get_monitor_info(system, glx->adapter, &mi); + + ALLEGRO_DEBUG("xconfigure event! %ix%i\n", x, y); + + /* check if we're no longer inside the stored adapter */ + if ((center_x < mi.x1 && center_x > mi.x2) || + (center_y < mi.y1 && center_y > mi.x2)) + { + int new_adapter = _al_xglx_get_adapter(system, glx, true); + if (new_adapter != glx->adapter) { + ALLEGRO_DEBUG("xdpy: adapter change!\n"); + _al_xglx_unuse_adapter(system, glx->adapter); + if (d->flags & ALLEGRO_FULLSCREEN) + _al_xglx_restore_video_mode(system, glx->adapter); + glx->adapter = new_adapter; + _al_xglx_use_adapter(system, glx->adapter); + } + + } + + _al_xwin_check_maximized(d); + + _al_event_source_unlock(es); +} + + +/* Handle an X11 configure event. [X11 thread] + * Only called from the event handler with the system locked. + */ +void _al_xglx_display_configure_event(ALLEGRO_DISPLAY *d, XEvent *xevent) +{ + /* We receive two configure events when toggling the window frame. + * We ignore the first one as it has bogus coordinates. + * The only way to tell them apart seems to be the send_event field. + * Unfortunately, we also end up ignoring the only event we receive in + * response to a XMoveWindow request so we have to compensate for that. + */ + bool setglxy = (xevent->xconfigure.send_event); + _al_xglx_display_configure(d, xevent->xconfigure.x, xevent->xconfigure.y, + xevent->xconfigure.width, xevent->xconfigure.height, setglxy); +} + + + +/* Handle X11 switch event. [X11 thread] + */ +void _al_xwin_display_switch_handler(ALLEGRO_DISPLAY *display, + XFocusChangeEvent *xevent) +{ + /* Anything but NotifyNormal seem to indicate the switch is not "real". + * TODO: Find out details? + */ + if (xevent->mode != NotifyNormal) + return; + + _al_xwin_display_switch_handler_inner(display, (xevent->type == FocusIn)); +} + + + +/* Handle X11 switch event. [X11 thread] + */ +void _al_xwin_display_switch_handler_inner(ALLEGRO_DISPLAY *display, bool focus_in) +{ + ALLEGRO_EVENT_SOURCE *es = &display->es; + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + if (focus_in) + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN; + else + event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT; + event.display.timestamp = al_get_time(); + _al_event_source_emit_event(es, &event); + } + _al_event_source_unlock(es); +} + + + +void _al_xwin_display_expose(ALLEGRO_DISPLAY *display, + XExposeEvent *xevent) +{ + ALLEGRO_EVENT_SOURCE *es = &display->es; + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE; + event.display.timestamp = al_get_time(); + event.display.x = xevent->x; + event.display.y = xevent->y; + event.display.width = xevent->width; + event.display.height = xevent->height; + _al_event_source_emit_event(es, &event); + } + _al_event_source_unlock(es); +} + + +static bool xdpy_is_compatible_bitmap(ALLEGRO_DISPLAY *display, + ALLEGRO_BITMAP *bitmap) +{ + /* All GLX bitmaps are compatible. */ + (void)display; + (void)bitmap; + return true; +} + + +static void xdpy_set_window_title_default(ALLEGRO_DISPLAY *display, const char *title) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + + { + Atom WM_NAME = XInternAtom(system->x11display, "WM_NAME", False); + Atom _NET_WM_NAME = XInternAtom(system->x11display, "_NET_WM_NAME", False); + char *list[1] = { (char *) title }; + XTextProperty property; + + Xutf8TextListToTextProperty(system->x11display, list, 1, XUTF8StringStyle, + &property); + XSetTextProperty(system->x11display, glx->window, &property, WM_NAME); + XSetTextProperty(system->x11display, glx->window, &property, _NET_WM_NAME); + XSetTextProperty(system->x11display, glx->window, &property, XA_WM_NAME); + XFree(property.value); + } + { + XClassHint *hint = XAllocClassHint(); + if (hint) { + ALLEGRO_PATH *exepath = al_get_standard_path(ALLEGRO_EXENAME_PATH); + // hint doesn't use a const char*, so we use strdup to create a non const string + hint->res_name = strdup(al_get_path_basename(exepath)); + hint->res_class = strdup(al_get_path_basename(exepath)); + XSetClassHint(system->x11display, glx->window, hint); + free(hint->res_name); + free(hint->res_class); + XFree(hint); + al_destroy_path(exepath); + } + } +} + + +static void xdpy_set_window_title(ALLEGRO_DISPLAY *display, const char *title) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + + _al_mutex_lock(&system->lock); + glx->overridable_vt->set_window_title(display, title); + _al_mutex_unlock(&system->lock); +} + + +static void xdpy_set_window_position_default(ALLEGRO_DISPLAY *display, + int x, int y) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Window root, parent, child, *children; + unsigned int n; + + _al_mutex_lock(&system->lock); + + /* To account for the window border, we have to find the parent window which + * draws the border. If the parent is the root though, then we should not + * translate. + */ + XQueryTree(system->x11display, glx->window, &root, &parent, &children, &n); + if (parent != root) { + XTranslateCoordinates(system->x11display, parent, glx->window, + x, y, &x, &y, &child); + } + + XMoveWindow(system->x11display, glx->window, x, y); + XFlush(system->x11display); + + /* We have to store these immediately, as we will ignore the XConfigureEvent + * that we receive in response. _al_display_xglx_configure() knows why. + */ + glx->x = x; + glx->y = y; + + _al_mutex_unlock(&system->lock); +} + + +static void xdpy_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + glx->overridable_vt->set_window_position(display, x, y); +} + + +static void xdpy_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + /* We could also query the X11 server, but it just would take longer, and + * would not be synchronized to our events. The latter can be an advantage + * or disadvantage. + */ + *x = glx->x; + *y = glx->y; +} + + +static bool xdpy_set_window_constraints_default(ALLEGRO_DISPLAY *display, + int min_w, int min_h, int max_w, int max_h) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + + glx->display.min_w = min_w; + glx->display.min_h = min_h; + glx->display.max_w = max_w; + glx->display.max_h = max_h; + + return true; +} + + +static bool xdpy_set_window_constraints(ALLEGRO_DISPLAY *display, + int min_w, int min_h, int max_w, int max_h) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + return glx->overridable_vt->set_window_constraints(display, + min_w, min_h, max_w, max_h); +} + + +static bool xdpy_get_window_constraints(ALLEGRO_DISPLAY *display, + int *min_w, int *min_h, int *max_w, int * max_h) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + + *min_w = glx->display.min_w; + *min_h = glx->display.min_h; + *max_w = glx->display.max_w; + *max_h = glx->display.max_h; + + return true; +} + + +static void xdpy_apply_window_constraints(ALLEGRO_DISPLAY *display, + bool onoff) +{ + int posX; + int posY; + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + + _al_mutex_lock(&system->lock); + + if (onoff) { + al_get_window_position(display, &posX, &posY); + _al_xwin_set_size_hints(display, posX, posY); + } + else { + _al_xwin_reset_size_hints(display); + } + + _al_mutex_unlock(&system->lock); + al_resize_display(display, display->w, display->h); +} + + +static void xdpy_set_fullscreen_window_default(ALLEGRO_DISPLAY *display, bool onoff) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + if (onoff == !(display->flags & ALLEGRO_FULLSCREEN_WINDOW)) { + _al_mutex_lock(&system->lock); + _al_xwin_reset_size_hints(display); + _al_xwin_set_fullscreen_window(display, 2); + /* XXX Technically, the user may fiddle with the _NET_WM_STATE_FULLSCREEN + * property outside of Allegro so this flag may not be in sync with + * reality. + */ + display->flags ^= ALLEGRO_FULLSCREEN_WINDOW; + _al_xwin_set_size_hints(display, INT_MAX, INT_MAX); + + set_compositor_bypass_flag(display); + _al_mutex_unlock(&system->lock); + } +} + + +static void xdpy_set_fullscreen_window(ALLEGRO_DISPLAY *display, bool onoff) +{ + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + glx->overridable_vt->set_fullscreen_window(display, onoff); +} + + +static bool xdpy_set_display_flag(ALLEGRO_DISPLAY *display, int flag, + bool flag_onoff) +{ + switch (flag) { + case ALLEGRO_FRAMELESS: + /* The ALLEGRO_FRAMELESS flag is backwards. */ + _al_xwin_set_frame(display, !flag_onoff); + return true; + case ALLEGRO_FULLSCREEN_WINDOW: + xdpy_set_fullscreen_window(display, flag_onoff); + return true; + case ALLEGRO_MAXIMIZED: + _al_xwin_maximize(display, flag_onoff); + return true; + } + return false; +} + + +static bool xdpy_wait_for_vsync(ALLEGRO_DISPLAY *display) +{ + (void) display; + + if (al_get_opengl_extension_list()->ALLEGRO_GLX_SGI_video_sync) { + unsigned int count; + glXGetVideoSyncSGI(&count); + glXWaitVideoSyncSGI(2, (count+1) & 1, &count); + return true; + } + + return false; +} + + +/* Obtain a reference to this driver. */ +ALLEGRO_DISPLAY_INTERFACE *_al_display_xglx_driver(void) +{ + if (xdpy_vt.create_display) + return &xdpy_vt; + + xdpy_vt.create_display = xdpy_create_display; + xdpy_vt.destroy_display = xdpy_destroy_display; + xdpy_vt.set_current_display = xdpy_set_current_display; + xdpy_vt.unset_current_display = xdpy_unset_current_display; + xdpy_vt.flip_display = xdpy_flip_display; + xdpy_vt.update_display_region = xdpy_update_display_region; + xdpy_vt.acknowledge_resize = xdpy_acknowledge_resize; + xdpy_vt.create_bitmap = _al_ogl_create_bitmap; + xdpy_vt.get_backbuffer = _al_ogl_get_backbuffer; + xdpy_vt.set_target_bitmap = _al_ogl_set_target_bitmap; + xdpy_vt.is_compatible_bitmap = xdpy_is_compatible_bitmap; + xdpy_vt.resize_display = xdpy_resize_display; + xdpy_vt.set_icons = _al_xwin_set_icons; + xdpy_vt.set_window_title = xdpy_set_window_title; + xdpy_vt.set_window_position = xdpy_set_window_position; + xdpy_vt.get_window_position = xdpy_get_window_position; + xdpy_vt.set_window_constraints = xdpy_set_window_constraints; + xdpy_vt.get_window_constraints = xdpy_get_window_constraints; + xdpy_vt.apply_window_constraints = xdpy_apply_window_constraints; + xdpy_vt.set_display_flag = xdpy_set_display_flag; + xdpy_vt.wait_for_vsync = xdpy_wait_for_vsync; + xdpy_vt.update_render_state = _al_ogl_update_render_state; + + _al_xwin_add_cursor_functions(&xdpy_vt); + _al_xwin_add_clipboard_functions(&xdpy_vt); + _al_ogl_add_drawing_functions(&xdpy_vt); + + return &xdpy_vt; +} + + +static const ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE default_overridable_vt = +{ + xdpy_create_display_hook_default, + xdpy_destroy_display_hook_default, + xdpy_resize_display_default, + xdpy_set_window_title_default, + xdpy_set_fullscreen_window_default, + xdpy_set_window_position_default, + xdpy_set_window_constraints_default +}; + + +bool _al_xwin_set_gtk_display_overridable_interface(uint32_t check_version, + const ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE *vt) +{ + /* The version of the native dialogs addon must exactly match the core + * library version. + */ + if (vt && check_version == ALLEGRO_VERSION_INT) { + ALLEGRO_DEBUG("GTK vtable made available\n"); + gtk_override_vt = vt; + return true; + } + + ALLEGRO_DEBUG("GTK vtable reset\n"); + gtk_override_vt = NULL; + return (vt == NULL); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/xevents.c b/allegro/src/x/xevents.c new file mode 100644 index 00000000..4e70aa4f --- /dev/null +++ b/allegro/src/x/xevents.c @@ -0,0 +1,245 @@ +#include + +#include "allegro5/allegro.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xclipboard.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xembed.h" +#include "allegro5/internal/aintern_xevents.h" +#include "allegro5/internal/aintern_xfullscreen.h" +#include "allegro5/internal/aintern_xkeyboard.h" +#include "allegro5/internal/aintern_xmouse.h" +#include "allegro5/internal/aintern_xsystem.h" +#include "allegro5/internal/aintern_xtouch.h" + +#ifdef ALLEGRO_RASPBERRYPI +#include "allegro5/internal/aintern_raspberrypi.h" +#define ALLEGRO_SYSTEM_XGLX ALLEGRO_SYSTEM_RASPBERRYPI +#define ALLEGRO_DISPLAY_XGLX ALLEGRO_DISPLAY_RASPBERRYPI +#endif + +ALLEGRO_DEBUG_CHANNEL("xevents") + +/* Handle an X11 close button event. [X11 thread] + * Only called from the event handler with the system locked. + */ +void _al_display_xglx_closebutton(ALLEGRO_DISPLAY *d, XEvent *xevent) +{ + ALLEGRO_EVENT_SOURCE *es = &d->es; + (void)xevent; + + _al_event_source_lock(es); + if (_al_event_source_needs_to_generate_event(es)) { + ALLEGRO_EVENT event; + event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE; + event.display.timestamp = al_get_time(); + _al_event_source_emit_event(es, &event); + } + _al_event_source_unlock(es); +} + +static void process_x11_event(ALLEGRO_SYSTEM_XGLX *s, XEvent event) +{ + unsigned int i; + ALLEGRO_DISPLAY_XGLX *d = NULL; + + /* With many windows, it's bad to loop through them all, but typically + * we have one or at most two or so. + */ + for (i = 0; i < _al_vector_size(&s->system.displays); i++) { + ALLEGRO_DISPLAY_XGLX **dptr = _al_vector_ref(&s->system.displays, i); + d = *dptr; + if (d->window == event.xany.window) { + break; + } + } + + if (!d) { + /* The display was probably destroyed already. */ + return; + } + + switch (event.type) { + case KeyPress: + _al_xwin_keyboard_handler(&event.xkey, &d->display); + break; + case KeyRelease: + _al_xwin_keyboard_handler(&event.xkey, &d->display); + break; + case MotionNotify: + _al_xwin_mouse_motion_notify_handler( + event.xmotion.x, event.xmotion.y, &d->display); + break; + case ButtonPress: + _al_xwin_mouse_button_press_handler(event.xbutton.button, + &d->display); + break; + case ButtonRelease: + _al_xwin_mouse_button_release_handler(event.xbutton.button, + &d->display); + break; + case ClientMessage: + if (event.xclient.message_type == s->AllegroAtom) { + d->mouse_warp = true; + break; + } + if (d->wm_delete_window_atom != None && + (Atom)event.xclient.data.l[0] == d->wm_delete_window_atom) + { + _al_display_xglx_closebutton(&d->display, &event); + break; + } +#ifndef ALLEGRO_RASPBERRYPI + if (event.xclient.message_type == s->XEmbedAtom) { + const long xtime = event.xclient.data.l[0]; + const long major = event.xclient.data.l[1]; + const long detail = event.xclient.data.l[2]; + const long data1 = event.xclient.data.l[3]; + const long data2 = event.xclient.data.l[4]; + + (void)xtime; + (void)detail; + (void)data2; + + switch (major) { + case XEMBED_EMBEDDED_NOTIFY: + d->embedder_window = data1; + ALLEGRO_INFO("XEmbed begin: embedder window = %ld\n", data1); + break; + case XEMBED_FOCUS_IN: + ALLEGRO_DEBUG("XEmbed focus in\n"); + _al_xwin_display_switch_handler_inner(&d->display, true); + _al_xwin_keyboard_switch_handler(&d->display, true); + break; + case XEMBED_FOCUS_OUT: + ALLEGRO_DEBUG("XEmbed focus out\n"); + _al_xwin_display_switch_handler_inner(&d->display, false); + _al_xwin_keyboard_switch_handler(&d->display, false); + break; + } + break; + } + break; + case EnterNotify: + _al_xwin_mouse_switch_handler(&d->display, &event.xcrossing); + break; + case LeaveNotify: + _al_xwin_mouse_switch_handler(&d->display, &event.xcrossing); + break; + case FocusIn: + _al_xwin_display_switch_handler(&d->display, &event.xfocus); + _al_xwin_keyboard_switch_handler(&d->display, true); + break; + case FocusOut: + _al_xwin_display_switch_handler(&d->display, &event.xfocus); + _al_xwin_keyboard_switch_handler(&d->display, false); + break; + case ConfigureNotify: + _al_xglx_display_configure_event(&d->display, &event); + d->resize_count++; + _al_cond_signal(&s->resized); + break; + case MapNotify: + d->display.flags &= ~ALLEGRO_MINIMIZED; + d->is_mapped = true; + _al_cond_signal(&d->mapped); + break; + case UnmapNotify: + d->display.flags |= ALLEGRO_MINIMIZED; + break; + case Expose: + if (d->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) { + _al_xwin_display_expose(&d->display, &event.xexpose); + } + break; + case ReparentNotify: + if (event.xreparent.parent == RootWindow(s->x11display, d->xscreen)) { + ALLEGRO_INFO("XEmbed protocol finished.\n"); + d->embedder_window = None; + } + break; + + case SelectionNotify: + _al_xwin_display_selection_notify(&d->display, &event.xselection); + d->is_selectioned = true; + _al_cond_signal(&d->selectioned); + break; + + case SelectionRequest: + _al_xwin_display_selection_request(&d->display, &event.xselectionrequest); + break; + + default: + _al_x_handle_touch_event(s, d, &event); + _al_xglx_handle_mmon_event(s, d, &event); + break; +#endif + } +} + +void _al_xwin_background_thread(_AL_THREAD *self, void *arg) +{ + ALLEGRO_SYSTEM_XGLX *s = arg; + XEvent event; + double last_reset_screensaver_time = 0.0; + + while (!_al_get_thread_should_stop(self)) { + /* Note: + * Most older X11 implementations are not thread-safe no matter what, so + * we simply cannot sit inside a blocking XNextEvent from another thread + * if another thread also uses X11 functions. + * + * The usual use of XNextEvent is to only call it from the main thread. We + * could of course do this for A5, just needs some slight adjustments to + * the events system (polling for an Allegro event would call a function + * of the system driver). + * + * As an alternative, we can use locking. This however can never fully + * work, as for example OpenGL implementations also will access X11, in a + * way we cannot know and cannot control (and we can't require users to + * only call graphics functions inside a lock). + * + * However, most X11 implementations are somewhat thread safe, and do + * use locking quite a bit themselves, so locking mostly does work. + * + * (Yet another alternative might be to use a separate X11 display + * connection for graphics output.) + * + */ + + _al_mutex_lock(&s->lock); + + while (XEventsQueued(s->x11display, QueuedAfterFlush)) { + XNextEvent(s->x11display, &event); + process_x11_event(s, event); + } + + /* The Xlib manual is particularly useless about the XResetScreenSaver() + * function. Nevertheless, this does seem to work to inhibit the native + * screensaver facility. Probably it won't do anything for other + * systems, though. + */ + if (!s->screen_saver_query_available && s->inhibit_screensaver) { + double now = al_get_time(); + if (now - last_reset_screensaver_time > 10.0) { + XResetScreenSaver(s->x11display); + last_reset_screensaver_time = now; + } + } + + _al_mutex_unlock(&s->lock); + + /* If no X11 events are there, unlock so other threads can run. We use + * a select call to wake up when as soon as anything is available on + * the X11 connection - and just for safety also wake up 10 times + * a second regardless. + */ + int x11_fd = ConnectionNumber(s->x11display); + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(x11_fd, &fdset); + struct timeval small_time = {0, 100000}; /* 10 times a second */ + select(x11_fd + 1, &fdset, NULL, NULL, &small_time); + } +} diff --git a/allegro/src/x/xfullscreen.c b/allegro/src/x/xfullscreen.c new file mode 100644 index 00000000..0651e466 --- /dev/null +++ b/allegro/src/x/xfullscreen.c @@ -0,0 +1,997 @@ +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xfullscreen.h" +#include "allegro5/internal/aintern_xsystem.h" + +ALLEGRO_DEBUG_CHANNEL("display") + +/* globals - this might be better in ALLEGRO_SYSTEM_XGLX */ +_ALLEGRO_XGLX_MMON_INTERFACE _al_xglx_mmon_interface; + +/* generic multi-head x */ +int _al_xsys_mheadx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) +{ + int i; + + ALLEGRO_DEBUG("mhead get default adapter\n"); + + if (ScreenCount(s->x11display) == 1) + return 0; + + _al_mutex_lock(&s->lock); + + Window focus; + int revert_to = 0; + XWindowAttributes attr; + Screen *focus_screen; + + if (!XGetInputFocus(s->x11display, &focus, &revert_to)) { + ALLEGRO_ERROR("XGetInputFocus failed!"); + _al_mutex_unlock(&s->lock); + return 0; + } + + if (focus == None) { + ALLEGRO_ERROR("XGetInputFocus returned None!\n"); + _al_mutex_unlock(&s->lock); + return 0; + } + else if (focus == PointerRoot) { + ALLEGRO_DEBUG("XGetInputFocus returned PointerRoot.\n"); + /* XXX TEST THIS >:( */ + Window root, child; + int root_x, root_y; + int win_x, win_y; + unsigned int mask; + + if (XQueryPointer(s->x11display, focus, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask) == False) { + ALLEGRO_ERROR("XQueryPointer failed :("); + _al_mutex_unlock(&s->lock); + return 0; + } + + focus = root; + } + else { + ALLEGRO_DEBUG("XGetInputFocus returned %i!\n", (int)focus); + } + + XGetWindowAttributes(s->x11display, focus, &attr); + focus_screen = attr.screen; + + int ret = 0; + for (i = 0; i < ScreenCount(s->x11display); i++) { + if (ScreenOfDisplay(s->x11display, i) == focus_screen) { + _al_mutex_unlock(&s->lock); + ret = i; + break; + } + } + + _al_mutex_unlock(&s->lock); + return ret; +} + +/* in pure multi-head mode, allegro's virtual adapters map directly to X Screens. */ +int _al_xsys_mheadx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + (void)s; + ALLEGRO_DEBUG("mhead get screen %i\n", adapter); + return adapter; +} + +/* +Returns the parent window of "window" (i.e. the ancestor of window +that is a direct child of the root, or window itself if it is a direct child). +If window is the root window, returns window. +*/ +static Window get_toplevel_parent(ALLEGRO_SYSTEM_XGLX *s, Window window) +{ + Window parent; + Window root; + Window * children; + unsigned int num_children; + + while (1) { + /* XXX enlightenment shows some very strange errors here, + * for some reason 'window' isn't valid when the mouse happens + * to be over the windeco when this is called.. */ + if (0 == XQueryTree(s->x11display, window, &root, &parent, &children, &num_children)) { + ALLEGRO_ERROR("XQueryTree error\n"); + return None; + } + if (children) { /* must test for NULL */ + XFree(children); + } + if (window == root || parent == root) { + return window; + } + else { + window = parent; + } + } + + return None; +} + +/* used for xinerama and pure xrandr modes */ +void _al_xsys_get_active_window_center(ALLEGRO_SYSTEM_XGLX *s, int *x, int *y) +{ + Window focus; + int revert_to = 0; + + _al_mutex_lock(&s->lock); + + if (!XGetInputFocus(s->x11display, &focus, &revert_to)) { + ALLEGRO_ERROR("XGetInputFocus failed!\n"); + _al_mutex_unlock(&s->lock); + return; + } + + if (focus == None || focus == PointerRoot) { + ALLEGRO_DEBUG("XGetInputFocus returned special window, selecting default root!\n"); + focus = DefaultRootWindow(s->x11display); + } + else { + /* this horribleness is due to toolkits like GTK (and probably Qt) creating + * a 1x1 window under the window you're looking at that actually accepts + * all input, so we need to grab the top level parent window rather than + * whatever happens to have focus */ + + focus = get_toplevel_parent(s, focus); + } + + ALLEGRO_DEBUG("XGetInputFocus returned %i\n", (int)focus); + + XWindowAttributes attr; + + if (XGetWindowAttributes(s->x11display, focus, &attr) == 0) { + ALLEGRO_ERROR("XGetWindowAttributes failed :(\n"); + _al_mutex_unlock(&s->lock); + return; + } + + _al_mutex_unlock(&s->lock); + + /* check the center of the window with focus + * might be a bit more useful than just checking the top left */ + ALLEGRO_DEBUG("focus geom: %ix%i %ix%i\n", attr.x, attr.y, attr.width, attr.height); + *x = (attr.x + (attr.x + attr.width)) / 2; + *y = (attr.y + (attr.y + attr.height)) / 2; +} + +/*--------------------------------------------------------------------------- + * + * Xinerama + * + */ + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + +static void xinerama_init(ALLEGRO_SYSTEM_XGLX *s) +{ + int event_base = 0; + int error_base = 0; + + /* init xinerama info to defaults */ + s->xinerama_available = 0; + s->xinerama_screen_count = 0; + s->xinerama_screen_info = NULL; + + _al_mutex_lock(&s->lock); + + if (XineramaQueryExtension(s->x11display, &event_base, &error_base)) { + int minor_version = 0, major_version = 0; + int status = XineramaQueryVersion(s->x11display, &major_version, &minor_version); + ALLEGRO_INFO("Xinerama version: %i.%i\n", major_version, minor_version); + + if (status && !XineramaIsActive(s->x11display)) { + ALLEGRO_WARN("Xinerama is not active\n"); + } + else { + s->xinerama_screen_info = XineramaQueryScreens(s->x11display, &s->xinerama_screen_count); + if (!s->xinerama_screen_info) { + ALLEGRO_ERROR("Xinerama failed to query screens.\n"); + } + else { + s->xinerama_available = 1; + ALLEGRO_INFO("Xinerama is active\n"); + } + } + } + + if (!s->xinerama_available) { + ALLEGRO_WARN("Xinerama extension is not available.\n"); + } + + _al_mutex_unlock(&s->lock); +} + +static void xinerama_exit(ALLEGRO_SYSTEM_XGLX *s) +{ + if (!s->xinerama_available) + return; + + ALLEGRO_DEBUG("xfullscreen: xinerama exit.\n"); + if (s->xinerama_screen_info) + XFree(s->xinerama_screen_info); + + s->xinerama_available = 0; + s->xinerama_screen_count = 0; + s->xinerama_screen_info = NULL; +} + +#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE + +static void xinerama_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y) +{ + ALLEGRO_ASSERT(adapter >= 0 && adapter < s->xinerama_screen_count); + *x = s->xinerama_screen_info[adapter].x_org; + *y = s->xinerama_screen_info[adapter].y_org; + ALLEGRO_DEBUG("xinerama dpy off %ix%i\n", *x, *y); +} + +static bool xinerama_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *mi) +{ + if (adapter < 0 || adapter >= s->xinerama_screen_count) + return false; + + mi->x1 = s->xinerama_screen_info[adapter].x_org; + mi->y1 = s->xinerama_screen_info[adapter].y_org; + mi->x2 = mi->x1 + s->xinerama_screen_info[adapter].width; + mi->y2 = mi->y1 + s->xinerama_screen_info[adapter].height; + return true; +} + +static ALLEGRO_DISPLAY_MODE *xinerama_get_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int i, ALLEGRO_DISPLAY_MODE *mode) +{ + if (adapter < 0 || adapter >= s->xinerama_screen_count) + return NULL; + + if (i != 0) + return NULL; + + mode->width = s->xinerama_screen_info[adapter].width; + mode->height = s->xinerama_screen_info[adapter].height; + mode->format = 0; + mode->refresh_rate = 0; + + return mode; +} + +static int xinerama_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) +{ + int center_x = 0, center_y = 0; + ALLEGRO_DEBUG("xinerama get default adapter\n"); + + _al_xsys_get_active_window_center(s, ¢er_x, ¢er_y); + ALLEGRO_DEBUG("xinerama got active center: %ix%i\n", center_x, center_y); + + int i; + for (i = 0; i < s->xinerama_screen_count; i++) { + if (center_x >= s->xinerama_screen_info[i].x_org && center_x <= s->xinerama_screen_info[i].x_org + s->xinerama_screen_info[i].width && + center_y >= s->xinerama_screen_info[i].y_org && center_y <= s->xinerama_screen_info[i].y_org + s->xinerama_screen_info[i].height) + { + ALLEGRO_DEBUG("center is inside (%i) %ix%i %ix%i\n", i, s->xinerama_screen_info[i].x_org, s->xinerama_screen_info[i].y_org, s->xinerama_screen_info[i].width, s->xinerama_screen_info[i].height); + return i; + } + } + + ALLEGRO_DEBUG("xinerama returning default 0\n"); + return 0; +} + +/* similar to multi-head x, but theres only one X Screen, so we return 0 always */ +static int xinerama_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + (void)s; + (void)adapter; + return 0; +} + +#endif /* ALLEGRO_XWINDOWS_WITH_XF86VIDMODE */ + +#endif /* ALLEGRO_XWINDOWS_WITH_XINERAMA */ + + + +/*--------------------------------------------------------------------------- + * + * XF86VidMode + * + */ + +#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE + +// XXX retest under multi-head! +static int xfvm_get_num_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { + if (adapter < 0 || adapter > s->xinerama_screen_count) + return 0; + + /* due to braindeadedness of the NVidia binary driver we can't know what an individual + * monitor's modes are, as the NVidia binary driver only reports combined "BigDesktop" + * or "TwinView" modes to user-space. There is no way to set modes on individual screens. + * As such, we can only do one thing here and report one single mode, + * which will end up being the xinerama size for the requested adapter */ + return 1; + } +#endif + + if (adapter < 0 || adapter > s->xfvm_screen_count) + return 0; + + return s->xfvm_screen[adapter].mode_count; +} + +static ALLEGRO_DISPLAY_MODE *xfvm_get_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int i, ALLEGRO_DISPLAY_MODE *mode) +{ + int denom; + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + /* TwinView gives us one large screen via xfvm, and no way to + * properly change modes on individual monitors, so we want to query + * xinerama for the lone mode. */ + if (s->xinerama_available && s->xfvm_screen_count != s->xinerama_screen_count) { + return xinerama_get_mode(s, adapter, i, mode); + } +#endif + + if (adapter < 0 || adapter > s->xfvm_screen_count) + return NULL; + + if (i < 0 || i > s->xfvm_screen[adapter].mode_count) + return NULL; + + mode->width = s->xfvm_screen[adapter].modes[i]->hdisplay; + mode->height = s->xfvm_screen[adapter].modes[i]->vdisplay; + mode->format = 0; + denom = s->xfvm_screen[adapter].modes[i]->htotal * s->xfvm_screen[adapter].modes[i]->vtotal; + if (denom > 0) + mode->refresh_rate = s->xfvm_screen[adapter].modes[i]->dotclock * 1000L / denom; + else + mode->refresh_rate = 0; + + return mode; +} + +static bool xfvm_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w, int h, int format, int refresh_rate) +{ + int mode_idx = -1; + int adapter = _al_xglx_get_adapter(s, d, false); + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ + if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { + /* at least pretend we set a mode if its the current mode */ + if (s->xinerama_screen_info[adapter].width != w || s->xinerama_screen_info[adapter].height != h) + return false; + + return true; + } +#endif + + mode_idx = _al_xglx_fullscreen_select_mode(s, adapter, w, h, format, refresh_rate); + if (mode_idx == -1) + return false; + + if (!XF86VidModeSwitchToMode(s->x11display, adapter, s->xfvm_screen[adapter].modes[mode_idx])) { + ALLEGRO_ERROR("xfullscreen: XF86VidModeSwitchToMode failed\n"); + return false; + } + + return true; +} + +static void xfvm_store_video_mode(ALLEGRO_SYSTEM_XGLX *s) +{ + int n; + + ALLEGRO_DEBUG("xfullscreen: xfvm_store_video_mode\n"); + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ + if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { + return; + } +#endif + + // save all original modes + int i; + for (i = 0; i < s->xfvm_screen_count; i++) { + n = xfvm_get_num_modes(s, i); + if (n == 0) { + /* XXX what to do here? */ + continue; + } + + s->xfvm_screen[i].original_mode = s->xfvm_screen[i].modes[0]; + + int j; + for (j = 0; j < s->xfvm_screen[i].mode_count; j++) { + ALLEGRO_DEBUG("xfvm: screen[%d] mode[%d] = (%d, %d)\n", + i, j, s->xfvm_screen[i].modes[j]->hdisplay, s->xfvm_screen[i].modes[j]->vdisplay); + } + ALLEGRO_INFO("xfvm: screen[%d] original mode = (%d, %d)\n", + i, s->xfvm_screen[i].original_mode->hdisplay, s->xfvm_screen[i].original_mode->vdisplay); + } +} + +static void xfvm_restore_video_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + Bool ok; + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ + if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { + return; + } +#endif + + if (adapter < 0 || adapter > s->xfvm_screen_count) + return; + + ASSERT(s->xfvm_screen[adapter].original_mode); + ALLEGRO_DEBUG("xfullscreen: xfvm_restore_video_mode (%d, %d)\n", + s->xfvm_screen[adapter].original_mode->hdisplay, s->xfvm_screen[adapter].original_mode->vdisplay); + + ok = XF86VidModeSwitchToMode(s->x11display, adapter, s->xfvm_screen[adapter].original_mode); + if (!ok) { + ALLEGRO_ERROR("xfullscreen: XF86VidModeSwitchToMode failed\n"); + } + + if (s->mouse_grab_display) { + XUngrabPointer(s->gfxdisplay, CurrentTime); + s->mouse_grab_display = NULL; + } + + /* This is needed, at least on my machine, or the program may terminate + * before the screen mode is actually reset. --pw + */ + /* can we move this into shutdown_system? It could speed up mode restores -TF */ + XFlush(s->gfxdisplay); +} + +static void xfvm_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y) +{ + int tmp_x = 0, tmp_y = 0; + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + if (s->xinerama_available) { + xinerama_get_display_offset(s, adapter, &tmp_x, &tmp_y); + } //else +#else + (void)s; + (void)adapter; +#endif + /* don't set the output params if function fails */ + /* XXX I don't think this part makes sense at all. + * in multi-head mode, the origin is always 0x0 + * in Xinerama, its caught by xinerama, and xfvm is NEVER + * used when xrandr is active -TF */ + //if (!XF86VidModeGetViewPort(s->x11display, adapter, &tmp_x, &tmp_y)) + // return; + + *x = tmp_x; + *y = tmp_y; + + ALLEGRO_DEBUG("xfvm dpy off %ix%i\n", *x, *y); +} + +static int xfvm_get_num_adapters(ALLEGRO_SYSTEM_XGLX *s) +{ +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + if (s->xinerama_available) { + return s->xinerama_screen_count; + } +#endif + return s->xfvm_screen_count; +} + +static bool xfvm_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *mi) +{ +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + if (s->xinerama_available) { + return xinerama_get_monitor_info(s, adapter, mi); + } +#endif + + if (adapter < 0 || adapter > s->xfvm_screen_count) + return false; + + XWindowAttributes xwa; + Window root; + + _al_mutex_lock(&s->lock); + root = RootWindow(s->x11display, adapter); + XGetWindowAttributes(s->x11display, root, &xwa); + _al_mutex_unlock(&s->lock); + + /* under plain X, each screen has its own origin, + and theres no way to figure out orientation + or relative position */ + mi->x1 = 0; + mi->y1 = 0; + mi->x2 = xwa.width; + mi->y2 = xwa.height; + return true; +} + +static int xfvm_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) +{ + ALLEGRO_DEBUG("xfvm get default adapter\n"); + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + if (s->xinerama_available) { + return xinerama_get_default_adapter(s); + } +#endif + + return _al_xsys_mheadx_get_default_adapter(s); +} + +static int xfvm_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + ALLEGRO_DEBUG("xfvm get xscreen for adapter %i\n", adapter); + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + if (s->xinerama_available) { + return xinerama_get_xscreen(s, adapter); + } +#endif + + return _al_xsys_mheadx_get_xscreen(s, adapter); +} + +static void xfvm_post_setup(ALLEGRO_SYSTEM_XGLX *s, + ALLEGRO_DISPLAY_XGLX *d) +{ + int x = 0, y = 0; + XWindowAttributes xwa; + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ + if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { + return; + } +#endif + + int adapter = _al_xglx_get_adapter(s, d, false); + + XGetWindowAttributes(s->x11display, d->window, &xwa); + xfvm_get_display_offset(s, adapter, &x, &y); + + /* some window managers like to move our window even if we explicitly tell it not to + * so we need to get the correct offset here */ + x = xwa.x - x; + y = xwa.y - y; + + ALLEGRO_DEBUG("xfvm set view port: %ix%i\n", x, y); + + XF86VidModeSetViewPort(s->x11display, adapter, x, y); +} + + +static void xfvm_init(ALLEGRO_SYSTEM_XGLX *s) +{ + int event_base = 0; + int error_base = 0; + + /* init xfvm info to defaults */ + s->xfvm_available = 0; + s->xfvm_screen_count = 0; + s->xfvm_screen = NULL; + + _al_mutex_lock(&s->lock); + + if (XF86VidModeQueryExtension(s->x11display, &event_base, &error_base)) { + int minor_version = 0, major_version = 0; + int status = XF86VidModeQueryVersion(s->x11display, &major_version, &minor_version); + ALLEGRO_INFO("XF86VidMode version: %i.%i\n", major_version, minor_version); + + if (!status) { + ALLEGRO_WARN("XF86VidMode not available, XF86VidModeQueryVersion failed.\n"); + } + else { + // I don't actually know what versions are required here, just going to assume any is ok for now. + ALLEGRO_INFO("XF86VidMode %i.%i is active\n", major_version, minor_version); + s->xfvm_available = 1; + } + } + else { + ALLEGRO_WARN("XF86VidMode extension is not available.\n"); + } + + if (s->xfvm_available) { + int num_screens; +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + /* This is some fun stuff right here, if XRANDR is available, we can't use the xinerama screen count + * and we really want the xrandr init in xglx_initialize to come last so it overrides xf86vm if available + * and I really don't want to add more XRRQuery* or #ifdefs here. + * I don't think XRandR can be disabled once its loaded, + * so just seeing if its in the extension list should be fine. */ + /* interesting thing to note is if XRandR is available, that means we have TwinView, + * and not multi-head Xinerama mode, as True Xinerama disables XRandR on my NVidia. + * which means all of those xfvm_screen_count != xinerama_screen_count tests + * only apply to TwinView. As this code below sets xfvm_screen_count to xinerama_screen_count + * making all those compares fail, and make us fall back to the normal xfvm multi-head code. */ + /* second note, if FakeXinerama is disabled on TwinView setups, we will end up using + * XRandR, as there is no other way to detect TwinView outside of libNVCtrl */ + + int ext_op, ext_evt, ext_err; + Bool ext_ret = XQueryExtension(s->x11display, "RANDR", &ext_op, &ext_evt, &ext_err); + + if (s->xinerama_available && ext_ret == False) { + num_screens = s->xinerama_screen_count; + } + else +#endif + { + num_screens = ScreenCount(s->x11display); + } + + ALLEGRO_DEBUG("XF86VidMode Got %d screens.\n", num_screens); + s->xfvm_screen_count = num_screens; + + s->xfvm_screen = al_calloc(num_screens, sizeof(*s->xfvm_screen)); + if (!s->xfvm_screen) { + ALLEGRO_ERROR("XF86VidMode: failed to allocate screen array.\n"); + s->xfvm_available = 0; + } + else { + int i; + for (i = 0; i < num_screens; i++) { + ALLEGRO_DEBUG("XF86VidMode GetAllModeLines on screen %d.\n", i); + if (!XF86VidModeGetAllModeLines(s->x11display, i, &(s->xfvm_screen[i].mode_count), &(s->xfvm_screen[i].modes))) { + /* XXX what to do here? */ + } + } + + _al_xglx_mmon_interface.get_num_display_modes = xfvm_get_num_modes; + _al_xglx_mmon_interface.get_display_mode = xfvm_get_mode; + _al_xglx_mmon_interface.set_mode = xfvm_set_mode; + _al_xglx_mmon_interface.store_mode = xfvm_store_video_mode; + _al_xglx_mmon_interface.restore_mode = xfvm_restore_video_mode; + _al_xglx_mmon_interface.get_display_offset = xfvm_get_display_offset; + _al_xglx_mmon_interface.get_num_adapters = xfvm_get_num_adapters; + _al_xglx_mmon_interface.get_monitor_info = xfvm_get_monitor_info; + _al_xglx_mmon_interface.get_default_adapter = xfvm_get_default_adapter; + _al_xglx_mmon_interface.get_xscreen = xfvm_get_xscreen; + _al_xglx_mmon_interface.post_setup = xfvm_post_setup; + } + } + + _al_mutex_unlock(&s->lock); +} + +static void xfvm_exit(ALLEGRO_SYSTEM_XGLX *s) +{ + int adapter; + ALLEGRO_DEBUG("xfullscreen: XFVM exit\n"); + + for (adapter = 0; adapter < s->xfvm_screen_count; adapter++) { + if (s->xfvm_screen[adapter].mode_count > 0) { + int i; + for (i = 0; i < s->xfvm_screen[adapter].mode_count; i++) { + if (s->xfvm_screen[adapter].modes[i]->privsize > 0) { + //XFree(s->xfvm_screen[adapter].modes[i]->private); + } + } + //XFree(s->xfvm_screen[adapter].modes); + } + + s->xfvm_screen[adapter].mode_count = 0; + s->xfvm_screen[adapter].modes = NULL; + s->xfvm_screen[adapter].original_mode = NULL; + + ALLEGRO_DEBUG("xfullscreen: XFVM freed adapter %d.\n", adapter); + } + + al_free(s->xfvm_screen); + s->xfvm_screen = NULL; +} + +#endif /* ALLEGRO_XWINDOWS_WITH_XF86VIDMODE */ + + + +/*--------------------------------------------------------------------------- + * + * Generic multi-monitor interface + * + */ + +static bool init_mmon_interface(ALLEGRO_SYSTEM_XGLX *s) +{ + if (s->x11display == NULL) { + ALLEGRO_WARN("Not connected to X server.\n"); + return false; + } + + if (s->mmon_interface_inited) + return true; + + /* Shouldn't we avoid initing any more of these than we need? */ + /* nope, no way to tell which is going to be used on any given system + * this way, xrandr always overrides everything else should it succeed. + * And when xfvm is chosen, it needs xinerama inited, + * incase there are multiple screens. + */ + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + xinerama_init(s); +#endif + +#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE + xfvm_init(s); +#endif + +#ifdef ALLEGRO_XWINDOWS_WITH_XRANDR + _al_xsys_xrandr_init(s); +#endif + + if (_al_xglx_mmon_interface.store_mode) + _al_xglx_mmon_interface.store_mode(s); + + s->mmon_interface_inited = true; + + return true; +} + +void _al_xsys_mmon_exit(ALLEGRO_SYSTEM_XGLX *s) +{ + if (!s->mmon_interface_inited) + return; + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + xinerama_exit(s); +#endif + +#ifdef ALLEGRO_XWINDOWS_WITH_XF86VIDMODE + xfvm_exit(s); +#endif + +#ifdef ALLEGRO_XWINDOWS_WITH_XRANDR + _al_xsys_xrandr_exit(s); +#endif + + s->mmon_interface_inited = false; +} + +int _al_xglx_get_num_display_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + if (!init_mmon_interface(s)) + return 0; + + if (adapter < 0) + adapter = _al_xglx_get_default_adapter(s); + + if (!_al_xglx_mmon_interface.get_num_display_modes) { + if (adapter != 0) + return 0; + + return 1; + } + + return _al_xglx_mmon_interface.get_num_display_modes(s, adapter); +} + +ALLEGRO_DISPLAY_MODE *_al_xglx_get_display_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int index, + ALLEGRO_DISPLAY_MODE *mode) +{ + if (!init_mmon_interface(s)) + return NULL; + + if (adapter < 0) + adapter = _al_xglx_get_default_adapter(s); + + if (!_al_xglx_mmon_interface.get_display_mode) { + mode->width = DisplayWidth(s->x11display, DefaultScreen(s->x11display)); + mode->height = DisplayHeight(s->x11display, DefaultScreen(s->x11display)); + mode->format = 0; + mode->refresh_rate = 0; + return NULL; + } + + return _al_xglx_mmon_interface.get_display_mode(s, adapter, index, mode); +} + +int _al_xglx_fullscreen_select_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int w, int h, int format, int refresh_rate) +{ + int i; + int n; + + if (!init_mmon_interface(s)) + return -1; + + if (adapter < 0) + adapter = _al_xglx_get_default_adapter(s); + + n = _al_xglx_get_num_display_modes(s, adapter); + if (!n) + return -1; + + /* Find all modes with correct parameters. */ + ALLEGRO_DISPLAY_MODE mode = {0, 0, 0, 0}; + int possible_modes[n]; + int possible_count = 0; + for (i = 0; i < n; i++) { + if (!_al_xglx_get_display_mode(s, adapter, i, &mode)) { + continue; + } + if (mode.width == w && mode.height == h && + (format == 0 || mode.format == format) && + (refresh_rate == 0 || mode.refresh_rate == refresh_rate)) + { + possible_modes[possible_count++] = i; + } + } + if (!possible_count) + return -1; + + /* Choose mode with highest refresh rate. */ + int best_mode = possible_modes[0]; + _al_xglx_get_display_mode(s, adapter, best_mode, &mode); + for (i = 1; i < possible_count; i++) { + ALLEGRO_DISPLAY_MODE mode2; + if (!_al_xglx_get_display_mode(s, adapter, possible_modes[i], &mode2)) { + continue; + } + if (mode2.refresh_rate > mode.refresh_rate) { + mode = mode2; + best_mode = possible_modes[i]; + } + } + + ALLEGRO_INFO("best mode [%d] = (%d, %d)\n", best_mode, mode.width, mode.height); + + return best_mode; +} + +bool _al_xglx_fullscreen_set_mode(ALLEGRO_SYSTEM_XGLX *s, + ALLEGRO_DISPLAY_XGLX *d, int w, int h, int format, int refresh_rate) +{ + if (!init_mmon_interface(s)) + return false; + + if (!_al_xglx_mmon_interface.set_mode) + return false; + + return _al_xglx_mmon_interface.set_mode(s, d, w, h, format, refresh_rate); +} + +void _al_xglx_fullscreen_to_display(ALLEGRO_SYSTEM_XGLX *s, + ALLEGRO_DISPLAY_XGLX *d) +{ + if (!init_mmon_interface(s)) + return; + + if (!_al_xglx_mmon_interface.post_setup) + return; + + _al_xglx_mmon_interface.post_setup(s, d); + +} + +void _al_xglx_store_video_mode(ALLEGRO_SYSTEM_XGLX *s) +{ + if (!init_mmon_interface(s)) + return; + + if (!_al_xglx_mmon_interface.store_mode) + return; + + _al_xglx_mmon_interface.store_mode(s); +} + +void _al_xglx_restore_video_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + if (!init_mmon_interface(s)) + return; + + if (!_al_xglx_mmon_interface.restore_mode) + return; + + _al_xglx_mmon_interface.restore_mode(s, adapter); +} + +void _al_xglx_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y) +{ + if (!init_mmon_interface(s)) + return; + + if (!_al_xglx_mmon_interface.get_display_offset) + return; + + _al_xglx_mmon_interface.get_display_offset(s, adapter, x, y); +} + +bool _al_xglx_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *info) +{ + if (!init_mmon_interface(s)) + return false; + + if (!_al_xglx_mmon_interface.get_monitor_info) { + _al_mutex_lock(&s->lock); + info->x1 = 0; + info->y1 = 0; + info->x2 = DisplayWidth(s->x11display, DefaultScreen(s->x11display)); + info->y2 = DisplayHeight(s->x11display, DefaultScreen(s->x11display)); + _al_mutex_unlock(&s->lock); + return true; + } + + return _al_xglx_mmon_interface.get_monitor_info(s, adapter, info); +} + +int _al_xglx_get_num_video_adapters(ALLEGRO_SYSTEM_XGLX *s) +{ + if (!init_mmon_interface(s)) + return 0; + + if (!_al_xglx_mmon_interface.get_num_adapters) + return 1; + + return _al_xglx_mmon_interface.get_num_adapters(s); +} + +int _al_xglx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) +{ + ALLEGRO_DEBUG("get default adapter\n"); + + if (!init_mmon_interface(s)) + return 0; + + if (!_al_xglx_mmon_interface.get_default_adapter) + return 0; + + return _al_xglx_mmon_interface.get_default_adapter(s); +} + +int _al_xglx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + ALLEGRO_DEBUG("get xscreen\n"); + + if (!init_mmon_interface(s)) + return 0; + + if (!_al_xglx_mmon_interface.get_xscreen) + return 0; + + return _al_xglx_mmon_interface.get_xscreen(s, adapter); +} + +int _al_xglx_get_adapter(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, bool recalc) +{ + if (!init_mmon_interface(s)) + return 0; + + if (d->adapter >= 0 && !recalc) + return d->adapter; + + if (!_al_xglx_mmon_interface.get_adapter) + return 0; + + return _al_xglx_mmon_interface.get_adapter(s, d); +} + +void _al_xglx_handle_mmon_event(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, XEvent *e) +{ + ALLEGRO_DEBUG("got event %i\n", e->type); + // if we haven't setup the mmon interface, just bail + if (!s->mmon_interface_inited) + return; + + // bail if the current mmon interface doesn't implement the handle_xevent method + if (!_al_xglx_mmon_interface.handle_xevent) + return; + + _al_xglx_mmon_interface.handle_xevent(s, d, e); +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/xglx_config.c b/allegro/src/x/xglx_config.c new file mode 100644 index 00000000..601dff98 --- /dev/null +++ b/allegro/src/x/xglx_config.c @@ -0,0 +1,598 @@ +#include "allegro5/allegro.h" +#include "allegro5/allegro_opengl.h" +#include "allegro5/opengl/gl_ext.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_display.h" +#include "allegro5/internal/aintern_opengl.h" +#include "allegro5/internal/aintern_pixels.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xglx_config.h" +#include "allegro5/internal/aintern_xsystem.h" + +ALLEGRO_DEBUG_CHANNEL("xglx_config") + +#ifdef DEBUGMODE +static void display_pixel_format(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds) +{ + ALLEGRO_DEBUG("Single-buffer: %s\n", eds->settings[ALLEGRO_SINGLE_BUFFER] ? "yes" : "no"); + if (eds->settings[ALLEGRO_SWAP_METHOD] > 0) + ALLEGRO_DEBUG("Swap method: %s\n", eds->settings[ALLEGRO_SWAP_METHOD] == 2 ? "flip" : "copy"); + else + ALLEGRO_DEBUG("Swap method: undefined\n"); + ALLEGRO_DEBUG("Color format: r%i g%i b%i a%i, %i bit\n", + eds->settings[ALLEGRO_RED_SIZE], + eds->settings[ALLEGRO_GREEN_SIZE], + eds->settings[ALLEGRO_BLUE_SIZE], + eds->settings[ALLEGRO_ALPHA_SIZE], + eds->settings[ALLEGRO_COLOR_SIZE]); + ALLEGRO_DEBUG("Depth buffer: %i bits\n", eds->settings[ALLEGRO_DEPTH_SIZE]); + ALLEGRO_DEBUG("Sample buffers: %s\n", eds->settings[ALLEGRO_SAMPLE_BUFFERS] ? "yes" : "no"); + ALLEGRO_DEBUG("Samples: %i\n", eds->settings[ALLEGRO_SAMPLES]); +} +#endif + +static int get_shift(int mask) +{ + int i = 0, j = 1; + if (!mask) + return -1; + while (!(j & mask)) { + i++; + j <<= 1; + } + return i; +} + +static void figure_out_colors(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, XVisualInfo *v) +{ + eds->settings[ALLEGRO_RED_SHIFT] = get_shift(v->red_mask); + eds->settings[ALLEGRO_GREEN_SHIFT] = get_shift(v->green_mask); + eds->settings[ALLEGRO_BLUE_SHIFT] = get_shift(v->blue_mask); + eds->settings[ALLEGRO_ALPHA_SHIFT] = 0; + + eds->settings[ALLEGRO_COLOR_SIZE] = 0; + + if (eds->settings[ALLEGRO_RED_SIZE] == 3 + && eds->settings[ALLEGRO_GREEN_SIZE] == 3 + && eds->settings[ALLEGRO_BLUE_SIZE] == 2) { + eds->settings[ALLEGRO_COLOR_SIZE] = 8; + } + + if (eds->settings[ALLEGRO_RED_SIZE] == 5 + && eds->settings[ALLEGRO_BLUE_SIZE] == 5) { + if (eds->settings[ALLEGRO_GREEN_SIZE] == 5) { + eds->settings[ALLEGRO_COLOR_SIZE] = 15; + } + if (eds->settings[ALLEGRO_GREEN_SIZE] == 6) { + eds->settings[ALLEGRO_COLOR_SIZE] = 16; + } + } + + if (eds->settings[ALLEGRO_RED_SIZE] == 8 + && eds->settings[ALLEGRO_GREEN_SIZE] == 8 + && eds->settings[ALLEGRO_BLUE_SIZE] == 8) { + if (eds->settings[ALLEGRO_ALPHA_SIZE] == 0) { + eds->settings[ALLEGRO_COLOR_SIZE] = 24; + } + if (eds->settings[ALLEGRO_ALPHA_SIZE] == 8) { + eds->settings[ALLEGRO_COLOR_SIZE] = 32; + /* small hack that tries to guess alpha shifting */ + eds->settings[ALLEGRO_ALPHA_SHIFT] = 48 - eds->settings[ALLEGRO_RED_SHIFT] + - eds->settings[ALLEGRO_GREEN_SHIFT] + - eds->settings[ALLEGRO_BLUE_SHIFT]; + } + } +} + +static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_fbconfig(Display *dpy, + GLXFBConfig fbc) +{ + int render_type, visual_type, buffer_size, sbuffers, samples; + int drawable_type, renderable, swap_method, double_buffer; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds; + XVisualInfo *v; + + eds = al_calloc(1, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); + eds->settings[ALLEGRO_RENDER_METHOD] = 2; + + if (glXGetFBConfigAttrib (dpy, fbc, GLX_RENDER_TYPE, + &render_type) + || glXGetFBConfigAttrib (dpy, fbc, GLX_X_RENDERABLE, + &renderable) + || glXGetFBConfigAttrib (dpy, fbc, GLX_DRAWABLE_TYPE, + &drawable_type) + || glXGetFBConfigAttrib (dpy, fbc, GLX_X_VISUAL_TYPE, + &visual_type) + || glXGetFBConfigAttrib (dpy, fbc, GLX_BUFFER_SIZE, + &buffer_size) + || glXGetFBConfigAttrib (dpy, fbc, GLX_DEPTH_SIZE, + &eds->settings[ALLEGRO_DEPTH_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_STEREO, + &eds->settings[ALLEGRO_STEREO]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_RED_SIZE, + &eds->settings[ALLEGRO_RED_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_GREEN_SIZE, + &eds->settings[ALLEGRO_GREEN_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_BLUE_SIZE, + &eds->settings[ALLEGRO_BLUE_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_ALPHA_SIZE, + &eds->settings[ALLEGRO_ALPHA_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_DOUBLEBUFFER, + &double_buffer) + || glXGetFBConfigAttrib (dpy, fbc, GLX_AUX_BUFFERS, + &eds->settings[ALLEGRO_AUX_BUFFERS]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_STENCIL_SIZE, + &eds->settings[ALLEGRO_STENCIL_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_ACCUM_RED_SIZE, + &eds->settings[ALLEGRO_ACC_RED_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_ACCUM_GREEN_SIZE, + &eds->settings[ALLEGRO_ACC_GREEN_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_ACCUM_BLUE_SIZE, + &eds->settings[ALLEGRO_ACC_BLUE_SIZE]) + || glXGetFBConfigAttrib (dpy, fbc, GLX_ACCUM_ALPHA_SIZE, + &eds->settings[ALLEGRO_ACC_ALPHA_SIZE])) { + ALLEGRO_DEBUG("Incomplete glX mode ...\n"); + al_free(eds); + return NULL; + } + eds->settings[ALLEGRO_SINGLE_BUFFER] = !double_buffer; + + if (!(render_type & GLX_RGBA_BIT) && !(render_type & GLX_RGBA_FLOAT_BIT_ARB)) { + ALLEGRO_DEBUG("Not RGBA mode\n"); + al_free(eds); + return NULL; + } + + if (!(drawable_type & GLX_WINDOW_BIT)) { + ALLEGRO_DEBUG("Cannot render to a window.\n"); + al_free(eds); + return NULL; + } + + if (renderable == False) { + ALLEGRO_DEBUG("GLX windows not supported.\n"); + al_free(eds); + return NULL; + } + + if (visual_type != GLX_TRUE_COLOR && visual_type != GLX_DIRECT_COLOR) { + ALLEGRO_DEBUG("visual type other than TrueColor and " + "DirectColor.\n"); + al_free(eds); + return NULL; + } + + /* Floating-point depth is not supported as glx extension (yet). */ + eds->settings[ALLEGRO_FLOAT_DEPTH] = 0; + + eds->settings[ALLEGRO_FLOAT_COLOR] = (render_type & GLX_RGBA_FLOAT_BIT_ARB); + + v = glXGetVisualFromFBConfig(dpy, fbc); + if (!v) { + ALLEGRO_DEBUG("Cannot get associated visual for the FBConfig.\n"); + al_free(eds); + return NULL; + } + figure_out_colors(eds, v); + + if (glXGetConfig(dpy, v, GLX_SAMPLE_BUFFERS, &sbuffers)) { + /* Multisample extension is not supported */ + eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 0; + } + else { + eds->settings[ALLEGRO_SAMPLE_BUFFERS] = sbuffers; + } + if (glXGetConfig(dpy, v, GLX_SAMPLES, &samples)) { + /* Multisample extension is not supported */ + eds->settings[ALLEGRO_SAMPLES] = 0; + } + else { + eds->settings[ALLEGRO_SAMPLES] = samples; + } + if (glXGetFBConfigAttrib(dpy, fbc, GLX_SWAP_METHOD_OML, + &swap_method) == GLX_BAD_ATTRIBUTE) { + /* GLX_OML_swap_method extension is not supported */ + eds->settings[ALLEGRO_SWAP_METHOD] = 0; + } + else { + eds->settings[ALLEGRO_SWAP_METHOD] = swap_method; + } + + /* We can only guarantee vsync is off. */ + eds->settings[ALLEGRO_VSYNC] = 2; + + eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = (_al_deduce_color_format(eds) + != ALLEGRO_PIXEL_FORMAT_ANY); + + XFree(v); + + return eds; +} + + +static ALLEGRO_EXTRA_DISPLAY_SETTINGS** get_visuals_new(ALLEGRO_DISPLAY_XGLX *glx, int *eds_count) +{ + int num_fbconfigs, i, j; + GLXFBConfig *fbconfig; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; + ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds = NULL; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + ref = _al_get_new_display_settings(); + + fbconfig = glXGetFBConfigs(system->gfxdisplay, glx->xscreen, &num_fbconfigs); + if (!fbconfig || !num_fbconfigs) { + if (fbconfig) { + XFree(fbconfig); + } + ALLEGRO_DEBUG("glXGetFBConfigs(xscreen=%d) returned NULL.\n", glx->xscreen); + return NULL; + } + + eds = al_malloc(num_fbconfigs * sizeof(*eds)); + + ALLEGRO_INFO("%i formats.\n", num_fbconfigs); + + for (i = j = 0; i < num_fbconfigs; i++) { + ALLEGRO_DEBUG("-- \n"); + ALLEGRO_DEBUG("Decoding visual no. %i...\n", i); + eds[j] = read_fbconfig(system->gfxdisplay, fbconfig[i]); + if (!eds[j]) + continue; +#ifdef DEBUGMODE + display_pixel_format(eds[j]); +#endif + eds[j]->score = _al_score_display_settings(eds[j], ref); + if (eds[j]->score == -1) { + al_free(eds[j]); + continue; + } + eds[j]->index = i; + eds[j]->info = al_malloc(sizeof(GLXFBConfig)); + memcpy(eds[j]->info, &fbconfig[i], sizeof(GLXFBConfig)); + j++; + } + + *eds_count = j; + ALLEGRO_INFO("%i visuals are good enough.\n", j); + if (j == 0) { + al_free(eds); + eds = NULL; + } + + XFree(fbconfig); + + return eds; +} + + +static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_xvisual(Display *dpy, + XVisualInfo *v) +{ + int rgba, buffer_size, use_gl, sbuffers, samples, double_buffer; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds; + + /* We can only support TrueColor and DirectColor visuals -- + * we only support RGBA mode */ + if (v->class != TrueColor && v->class != DirectColor) + return NULL; + + eds = al_calloc(1, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); + eds->settings[ALLEGRO_RENDER_METHOD] = 2; + + if (glXGetConfig (dpy, v, GLX_RGBA, &rgba) + || glXGetConfig (dpy, v, GLX_USE_GL, &use_gl) + || glXGetConfig (dpy, v, GLX_BUFFER_SIZE, &buffer_size) + || glXGetConfig (dpy, v, GLX_RED_SIZE, &eds->settings[ALLEGRO_RED_SIZE]) + || glXGetConfig (dpy, v, GLX_GREEN_SIZE, &eds->settings[ALLEGRO_GREEN_SIZE]) + || glXGetConfig (dpy, v, GLX_BLUE_SIZE, &eds->settings[ALLEGRO_BLUE_SIZE]) + || glXGetConfig (dpy, v, GLX_ALPHA_SIZE, &eds->settings[ALLEGRO_ALPHA_SIZE]) + || glXGetConfig (dpy, v, GLX_DOUBLEBUFFER, &double_buffer) + || glXGetConfig (dpy, v, GLX_STEREO, &eds->settings[ALLEGRO_STEREO]) + || glXGetConfig (dpy, v, GLX_AUX_BUFFERS, &eds->settings[ALLEGRO_AUX_BUFFERS]) + || glXGetConfig (dpy, v, GLX_DEPTH_SIZE, &eds->settings[ALLEGRO_DEPTH_SIZE]) + || glXGetConfig (dpy, v, GLX_STENCIL_SIZE, &eds->settings[ALLEGRO_STENCIL_SIZE]) + || glXGetConfig (dpy, v, GLX_ACCUM_RED_SIZE, + &eds->settings[ALLEGRO_ACC_RED_SIZE]) + || glXGetConfig (dpy, v, GLX_ACCUM_GREEN_SIZE, + &eds->settings[ALLEGRO_ACC_GREEN_SIZE]) + || glXGetConfig (dpy, v, GLX_ACCUM_BLUE_SIZE, + &eds->settings[ALLEGRO_ACC_BLUE_SIZE]) + || glXGetConfig (dpy, v, GLX_ACCUM_ALPHA_SIZE, + &eds->settings[ALLEGRO_ACC_ALPHA_SIZE])) { + ALLEGRO_DEBUG("Incomplete glX mode ...\n"); + al_free(eds); + return NULL; + } + eds->settings[ALLEGRO_SINGLE_BUFFER] = !double_buffer; + + if (!rgba) { + ALLEGRO_DEBUG("Not RGBA mode\n"); + al_free(eds); + return NULL; + } + + if (!use_gl) { + ALLEGRO_DEBUG("OpenGL Unsupported\n"); + al_free(eds); + return NULL; + } + + eds->settings[ALLEGRO_COLOR_SIZE] = 0; + figure_out_colors(eds, v); + + eds->settings[ALLEGRO_FLOAT_COLOR] = 0; + eds->settings[ALLEGRO_FLOAT_DEPTH] = 0; + + if (glXGetConfig(dpy, v, GLX_SAMPLE_BUFFERS, &sbuffers) == GLX_BAD_ATTRIBUTE) { + /* Multisample extension is not supported */ + eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 0; + } + else { + eds->settings[ALLEGRO_SAMPLE_BUFFERS] = sbuffers; + } + if (glXGetConfig(dpy, v, GLX_SAMPLES, &samples) == GLX_BAD_ATTRIBUTE) { + /* Multisample extension is not supported */ + eds->settings[ALLEGRO_SAMPLES] = 0; + } + else { + eds->settings[ALLEGRO_SAMPLES] = samples; + } + + eds->settings[ALLEGRO_SWAP_METHOD] = 0; + eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = (_al_deduce_color_format(eds) + != ALLEGRO_PIXEL_FORMAT_ANY); + + return eds; +} + +static ALLEGRO_EXTRA_DISPLAY_SETTINGS** get_visuals_old(int *eds_count) +{ + int i, j, num_visuals; + XVisualInfo *xv; + ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; + ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + ref = _al_get_new_display_settings(); + + xv = XGetVisualInfo(system->gfxdisplay, 0, NULL, &num_visuals); + if (!xv || !num_visuals) + return NULL; + + eds = al_malloc(num_visuals * sizeof(*eds)); + + ALLEGRO_INFO("%i formats.\n", num_visuals); + + for (i = j = 0; i < num_visuals; i++) { + ALLEGRO_DEBUG("-- \n"); + ALLEGRO_DEBUG("Decoding visual no. %i...\n", i); + eds[j] = read_xvisual(system->gfxdisplay, xv + i); + if (!eds[j]) + continue; +#ifdef DEBUGMODE + display_pixel_format(eds[j]); +#endif + eds[j]->score = _al_score_display_settings(eds[j], ref); + if (eds[j]->score == -1) { + al_free(eds[j]); + continue; + } + eds[j]->index = i; + /* Seems that XVinfo is static. */ + eds[j]->info = al_malloc(sizeof(XVisualInfo)); + memcpy(eds[j]->info, xv + i, sizeof(XVisualInfo)); + j++; + } + + *eds_count = j; + ALLEGRO_INFO("%i visuals are good enough.\n", j); + if (j == 0) { + al_free(eds); + eds = NULL; + } + + XFree(xv); + + return eds; +} + + +static void select_best_visual(ALLEGRO_DISPLAY_XGLX *glx, + ALLEGRO_EXTRA_DISPLAY_SETTINGS* *eds, int eds_count, + bool using_fbc) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + qsort(eds, eds_count, sizeof(*eds), _al_display_settings_sorter); + + ASSERT(eds_count > 0); + ASSERT(eds[0] != NULL); + + if (!eds[0]->info) { + ALLEGRO_ERROR("No matching displays found.\n"); + glx->xvinfo = NULL; + return; + } + + ALLEGRO_INFO("Chose visual no. %i\n", eds[0]->index); +#ifdef DEBUGMODE + display_pixel_format(eds[0]); +#endif + if (using_fbc) { + glx->fbc = al_malloc(sizeof(GLXFBConfig)); + memcpy(glx->fbc, eds[0]->info, sizeof(GLXFBConfig)); + + glx->xvinfo = glXGetVisualFromFBConfig(system->gfxdisplay, *glx->fbc); + } + else { + glx->xvinfo = al_malloc(sizeof(XVisualInfo)); + memcpy(glx->xvinfo, eds[0]->info, sizeof(XVisualInfo)); + } + + ALLEGRO_INFO("Corresponding X11 visual id: %lu\n", glx->xvinfo->visualid); + memcpy(&glx->display.extra_settings, eds[0], sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); +} + + + +void _al_xglx_config_select_visual(ALLEGRO_DISPLAY_XGLX *glx) +{ + ALLEGRO_EXTRA_DISPLAY_SETTINGS **eds; + int eds_count, i; + bool force_old = false; + bool using_fbc; + + const char *selection_mode; + selection_mode = al_get_config_value(al_get_system_config(), "graphics", + "config_selection"); + if (selection_mode && selection_mode[0] != '\0') { + if (!_al_stricmp(selection_mode, "old")) { + ALLEGRO_WARN("Forcing OLD visual selection method.\n"); + force_old = true; + } + else if (!_al_stricmp(selection_mode, "new")) + force_old = false; + } + + if (glx->glx_version >= 130 && !force_old) + eds = get_visuals_new(glx, &eds_count); + else + eds = NULL; + + if (!eds) { + eds = get_visuals_old(&eds_count); + using_fbc = false; + } + else + using_fbc = true; + + if (!eds) { + ALLEGRO_ERROR("Failed to get any visual info.\n"); + return; + } + + select_best_visual(glx, eds, eds_count, using_fbc); + + for (i = 0; i < eds_count; i++) { + if (eds[i]) { + al_free(eds[i]->info); + al_free(eds[i]); + } + } + al_free(eds); +} + +static GLXContext create_context_new(int ver, Display *dpy, GLXFBConfig fb, + GLXContext ctx, bool forward_compat, bool want_es, bool core_profile, int major, int minor) +{ + typedef GLXContext (*GCCA_PROC) (Display*, GLXFBConfig, GLXContext, Bool, const int*); + GCCA_PROC _xglx_glXCreateContextAttribsARB = NULL; + + if (ver >= 140) { + /* GLX 1.4 should have this, if it's defined, use it directly. */ + /* OTOH it *could* be there but only available through dynamic loading. */ + /* In that case, fallback to calling glxXGetProcAddress. */ +#ifdef glXCreateContextAttribsARB + _xglx_glXCreateContextAttribsARB = glXCreateContextAttribsARB; +#endif // glXCreateContextAttribsARB + } + if (!_xglx_glXCreateContextAttribsARB) { + /* Load the extension manually. */ + _xglx_glXCreateContextAttribsARB = + (GCCA_PROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); + } + if (!_xglx_glXCreateContextAttribsARB) { + ALLEGRO_ERROR("GLX_ARB_create_context not supported and needed for OpenGL 3\n"); + return NULL; + } + + int attrib[] = {GLX_CONTEXT_MAJOR_VERSION_ARB, major, + GLX_CONTEXT_MINOR_VERSION_ARB, minor, + GLX_CONTEXT_FLAGS_ARB, 0, + 0, 0, + 0}; + if (forward_compat) + attrib[5] = GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + if (want_es) { + attrib[6] = GLX_CONTEXT_PROFILE_MASK_ARB; + attrib[7] = GLX_CONTEXT_ES_PROFILE_BIT_EXT; + } + else if (core_profile) { + attrib[6] = GLX_CONTEXT_PROFILE_MASK_ARB; + attrib[7] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + } + return _xglx_glXCreateContextAttribsARB(dpy, fb, ctx, True, attrib); +} + +bool _al_xglx_config_create_context(ALLEGRO_DISPLAY_XGLX *glx) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY *disp = (void*)glx; + GLXContext existing_ctx = NULL; + + /* Find an existing context with which to share display lists. */ + if (_al_vector_size(&system->system.displays) > 1) { + ALLEGRO_DISPLAY_XGLX **existing_dpy; + existing_dpy = _al_vector_ref_front(&system->system.displays); + if (*existing_dpy != glx) + existing_ctx = (*existing_dpy)->context; + } + + int major = al_get_new_display_option(ALLEGRO_OPENGL_MAJOR_VERSION, 0); + int minor = al_get_new_display_option(ALLEGRO_OPENGL_MINOR_VERSION, 0); + + if (glx->fbc) { + bool forward_compat = (disp->flags & ALLEGRO_OPENGL_FORWARD_COMPATIBLE) != 0; + bool core_profile = (disp->flags & ALLEGRO_OPENGL_CORE_PROFILE) != 0; + /* Create a GLX context from FBC. */ + if (disp->flags & ALLEGRO_OPENGL_ES_PROFILE) { + if (major == 0) + major = 2; + glx->context = create_context_new(glx->glx_version, + system->gfxdisplay, *glx->fbc, existing_ctx, forward_compat, + true, core_profile, major, minor); + } + else if ((disp->flags & ALLEGRO_OPENGL_3_0) || major != 0 || core_profile) { + if (major == 0) + major = 3; + if (core_profile && major == 3 && minor < 2) // core profile requires at least 3.2 + minor = 2; + glx->context = create_context_new(glx->glx_version, + system->gfxdisplay, *glx->fbc, existing_ctx, forward_compat, + false, core_profile, major, minor); + /* TODO: Right now Allegro's own OpenGL driver only works with a 3.0+ + * context when using the programmable pipeline, for some reason. All + * that's missing is probably a default shader though. + */ + disp->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; + if (forward_compat && !(disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) + disp->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0; + } + else { + glx->context = glXCreateNewContext(system->gfxdisplay, *glx->fbc, + GLX_RGBA_TYPE, existing_ctx, True); + } + + /* Create a GLX subwindow inside our window. */ + glx->glxwindow = glXCreateWindow(system->gfxdisplay, *glx->fbc, + glx->window, 0); + } + else { + /* Create a GLX context from visual info. */ + glx->context = glXCreateContext(system->gfxdisplay, glx->xvinfo, + existing_ctx, True); + glx->glxwindow = glx->window; + } + + if (!glx->context || !glx->glxwindow) { + ALLEGRO_ERROR("Failed to create GLX context.\n"); + return false; + } + + disp->ogl_extras->is_shared = true; + + ALLEGRO_DEBUG("Got GLX context.\n"); + return true; +} diff --git a/allegro/src/x/xicon.h b/allegro/src/x/xicon.h new file mode 100644 index 00000000..cbd4900c --- /dev/null +++ b/allegro/src/x/xicon.h @@ -0,0 +1,6 @@ +#ifndef XICON_H +#define XICON_H + +extern char **x11_xpm; + +#endif // XICON_H diff --git a/allegro/src/x/xkeyboard.c b/allegro/src/x/xkeyboard.c new file mode 100644 index 00000000..c9dd58cf --- /dev/null +++ b/allegro/src/x/xkeyboard.c @@ -0,0 +1,1139 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * X keyboard driver. + * + * By Elias Pschernig. + * + * Modified for the new keyboard API by Peter Wang. + * + * See readme.txt for copyright information. + */ + +#define ALLEGRO_NO_COMPATIBILITY + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_events.h" +#include "allegro5/internal/aintern_keyboard.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xkeyboard.h" +#include "allegro5/internal/aintern_xsystem.h" + +#ifdef ALLEGRO_RASPBERRYPI +#include "allegro5/internal/aintern_raspberrypi.h" +#define ALLEGRO_SYSTEM_XGLX ALLEGRO_SYSTEM_RASPBERRYPI +#endif + +ALLEGRO_DEBUG_CHANNEL("keyboard") + +/*----------------------------------------------------------------------*/ +static void handle_key_press(int mycode, int unichar, int filtered, + unsigned int modifiers, ALLEGRO_DISPLAY *display); +static void handle_key_release(int mycode, unsigned int modifiers, ALLEGRO_DISPLAY *display); +static int _key_shifts; +/*----------------------------------------------------------------------*/ + + +typedef struct ALLEGRO_KEYBOARD_XWIN +{ + ALLEGRO_KEYBOARD parent; + ALLEGRO_KEYBOARD_STATE state; + // Quit if Ctrl-Alt-Del is pressed. + bool three_finger_flag; +} ALLEGRO_KEYBOARD_XWIN; + + +typedef struct ALLEGRO_KEY_REPEAT_DATA { + XKeyEvent *event; + bool found; +} ALLEGRO_KEY_REPEAT_DATA; + + +/* the one and only keyboard object */ +static ALLEGRO_KEYBOARD_XWIN the_keyboard; + +static int last_press_code = -1; + +#ifdef ALLEGRO_XWINDOWS_WITH_XIM +static XIM xim = NULL; +static XIC xic = NULL; +#endif +static XModifierKeymap *xmodmap = NULL; +static int xkeyboard_installed = 0; +static int used[ALLEGRO_KEY_MAX]; +static int sym_per_key; +static int min_keycode, max_keycode; +static KeySym *keysyms = NULL; +static int main_pid; /* The pid to kill with ctrl-alt-del. */ +static int pause_key = 0; /* Allegro's special pause key state. */ +static int keycode_to_scancode[256]; + +/* This table can be ammended to provide more reasonable defaults for + * mappings other than US/UK. They are used to map X11 KeySyms as found in + * X11/keysym.h to Allegro's ALLEGRO_KEY_* codes. This will only work well on US/UK + * keyboards since Allegro simply doesn't have ALLEGRO_KEY_* codes for non US/UK + * keyboards. So with other mappings, the unmapped keys will be distributed + * arbitrarily to the remaining ALLEGRO_KEY_* codes. + * + * Double mappings should be avoided, else they can lead to different keys + * producing the same ALLEGRO_KEY_* code on some mappings. + * + * In cases where there is no other way to detect a key, since we have no + * ASCII applied to it, like ALLEGRO_KEY_LEFT or ALLEGRO_KEY_PAUSE, multiple mappings should + * be ok though. This table will never be able to be 100% perfect, so just + * try to make it work for as many as possible, using additional hacks in + * some cases. There is also still the possibility to override keys with + * the [xkeyboard] config section, so users can always re-map keys. (E.g. + * to play an Allegro game which hard-coded ALLEGRO_KEY_Y and ALLEGRO_KEY_X for left and + * right.) + */ +static struct { + KeySym keysym; + int allegro_key; +} +translation_table[] = { + {XK_a, ALLEGRO_KEY_A}, + {XK_b, ALLEGRO_KEY_B}, + {XK_c, ALLEGRO_KEY_C}, + {XK_d, ALLEGRO_KEY_D}, + {XK_e, ALLEGRO_KEY_E}, + {XK_f, ALLEGRO_KEY_F}, + {XK_g, ALLEGRO_KEY_G}, + {XK_h, ALLEGRO_KEY_H}, + {XK_i, ALLEGRO_KEY_I}, + {XK_j, ALLEGRO_KEY_J}, + {XK_k, ALLEGRO_KEY_K}, + {XK_l, ALLEGRO_KEY_L}, + {XK_m, ALLEGRO_KEY_M}, + {XK_n, ALLEGRO_KEY_N}, + {XK_o, ALLEGRO_KEY_O}, + {XK_p, ALLEGRO_KEY_P}, + {XK_q, ALLEGRO_KEY_Q}, + {XK_r, ALLEGRO_KEY_R}, + {XK_s, ALLEGRO_KEY_S}, + {XK_t, ALLEGRO_KEY_T}, + {XK_u, ALLEGRO_KEY_U}, + {XK_v, ALLEGRO_KEY_V}, + {XK_w, ALLEGRO_KEY_W}, + {XK_x, ALLEGRO_KEY_X}, + {XK_y, ALLEGRO_KEY_Y}, + {XK_z, ALLEGRO_KEY_Z}, + {XK_0, ALLEGRO_KEY_0}, + {XK_1, ALLEGRO_KEY_1}, + {XK_2, ALLEGRO_KEY_2}, + {XK_3, ALLEGRO_KEY_3}, + {XK_4, ALLEGRO_KEY_4}, + {XK_5, ALLEGRO_KEY_5}, + {XK_6, ALLEGRO_KEY_6}, + {XK_7, ALLEGRO_KEY_7}, + {XK_8, ALLEGRO_KEY_8}, + {XK_9, ALLEGRO_KEY_9}, + + /* Double mappings for numeric keyboard. + * If an X server actually uses both at the same time, Allegro will + * detect them as the same. But normally, an X server just reports it as + * either of them, and therefore we always get the keys as ALLEGRO_KEY_PAD_*. + */ + {XK_KP_0, ALLEGRO_KEY_PAD_0}, + {XK_KP_Insert, ALLEGRO_KEY_PAD_0}, + {XK_KP_1, ALLEGRO_KEY_PAD_1}, + {XK_KP_End, ALLEGRO_KEY_PAD_1}, + {XK_KP_2, ALLEGRO_KEY_PAD_2}, + {XK_KP_Down, ALLEGRO_KEY_PAD_2}, + {XK_KP_3, ALLEGRO_KEY_PAD_3}, + {XK_KP_Page_Down, ALLEGRO_KEY_PAD_3}, + {XK_KP_4, ALLEGRO_KEY_PAD_4}, + {XK_KP_Left, ALLEGRO_KEY_PAD_4}, + {XK_KP_5, ALLEGRO_KEY_PAD_5}, + {XK_KP_Begin, ALLEGRO_KEY_PAD_5}, + {XK_KP_6, ALLEGRO_KEY_PAD_6}, + {XK_KP_Right, ALLEGRO_KEY_PAD_6}, + {XK_KP_7, ALLEGRO_KEY_PAD_7}, + {XK_KP_Home, ALLEGRO_KEY_PAD_7}, + {XK_KP_8, ALLEGRO_KEY_PAD_8}, + {XK_KP_Up, ALLEGRO_KEY_PAD_8}, + {XK_KP_9, ALLEGRO_KEY_PAD_9}, + {XK_KP_Page_Up, ALLEGRO_KEY_PAD_9}, + {XK_KP_Delete, ALLEGRO_KEY_PAD_DELETE}, + {XK_KP_Decimal, ALLEGRO_KEY_PAD_DELETE}, + + /* Double mapping! + * Same as above - but normally, the X server just reports one or the + * other for the Pause key, and the other is not reported for any key. + */ + {XK_Pause, ALLEGRO_KEY_PAUSE}, + {XK_Break, ALLEGRO_KEY_PAUSE}, + + {XK_F1, ALLEGRO_KEY_F1}, + {XK_F2, ALLEGRO_KEY_F2}, + {XK_F3, ALLEGRO_KEY_F3}, + {XK_F4, ALLEGRO_KEY_F4}, + {XK_F5, ALLEGRO_KEY_F5}, + {XK_F6, ALLEGRO_KEY_F6}, + {XK_F7, ALLEGRO_KEY_F7}, + {XK_F8, ALLEGRO_KEY_F8}, + {XK_F9, ALLEGRO_KEY_F9}, + {XK_F10, ALLEGRO_KEY_F10}, + {XK_F11, ALLEGRO_KEY_F11}, + {XK_F12, ALLEGRO_KEY_F12}, + {XK_Escape, ALLEGRO_KEY_ESCAPE}, + {XK_grave, ALLEGRO_KEY_TILDE}, /* US left of 1 */ + {XK_minus, ALLEGRO_KEY_MINUS}, /* US right of 0 */ + {XK_equal, ALLEGRO_KEY_EQUALS}, /* US 2 right of 0 */ + {XK_BackSpace, ALLEGRO_KEY_BACKSPACE}, + {XK_Tab, ALLEGRO_KEY_TAB}, + {XK_bracketleft, ALLEGRO_KEY_OPENBRACE}, /* US right of P */ + {XK_bracketright, ALLEGRO_KEY_CLOSEBRACE}, /* US 2 right of P */ + {XK_Return, ALLEGRO_KEY_ENTER}, + {XK_semicolon, ALLEGRO_KEY_SEMICOLON}, /* US right of L */ + {XK_apostrophe, ALLEGRO_KEY_QUOTE}, /* US 2 right of L */ + {XK_backslash, ALLEGRO_KEY_BACKSLASH}, /* US 3 right of L */ + {XK_less, ALLEGRO_KEY_BACKSLASH2}, /* US left of Y */ + {XK_comma, ALLEGRO_KEY_COMMA}, /* US right of M */ + {XK_period, ALLEGRO_KEY_FULLSTOP}, /* US 2 right of M */ + {XK_slash, ALLEGRO_KEY_SLASH}, /* US 3 right of M */ + {XK_space, ALLEGRO_KEY_SPACE}, + {XK_Insert, ALLEGRO_KEY_INSERT}, + {XK_Delete, ALLEGRO_KEY_DELETE}, + {XK_Home, ALLEGRO_KEY_HOME}, + {XK_End, ALLEGRO_KEY_END}, + {XK_Page_Up, ALLEGRO_KEY_PGUP}, + {XK_Page_Down, ALLEGRO_KEY_PGDN}, + {XK_Left, ALLEGRO_KEY_LEFT}, + {XK_Right, ALLEGRO_KEY_RIGHT}, + {XK_Up, ALLEGRO_KEY_UP}, + {XK_Down, ALLEGRO_KEY_DOWN}, + {XK_KP_Divide, ALLEGRO_KEY_PAD_SLASH}, + {XK_KP_Multiply, ALLEGRO_KEY_PAD_ASTERISK}, + {XK_KP_Subtract, ALLEGRO_KEY_PAD_MINUS}, + {XK_KP_Add, ALLEGRO_KEY_PAD_PLUS}, + {XK_KP_Enter, ALLEGRO_KEY_PAD_ENTER}, + {XK_Print, ALLEGRO_KEY_PRINTSCREEN}, + + //{, ALLEGRO_KEY_ABNT_C1}, + //{, ALLEGRO_KEY_YEN}, + //{, ALLEGRO_KEY_KANA}, + //{, ALLEGRO_KEY_CONVERT}, + //{, ALLEGRO_KEY_NOCONVERT}, + //{, ALLEGRO_KEY_AT}, + //{, ALLEGRO_KEY_CIRCUMFLEX}, + //{, ALLEGRO_KEY_COLON2}, + //{, ALLEGRO_KEY_KANJI}, + {XK_KP_Equal, ALLEGRO_KEY_PAD_EQUALS}, /* MacOS X */ + //{, ALLEGRO_KEY_BACKQUOTE}, /* MacOS X */ + //{, ALLEGRO_KEY_SEMICOLON}, /* MacOS X */ + //{, ALLEGRO_KEY_COMMAND}, /* MacOS X */ + + {XK_Shift_L, ALLEGRO_KEY_LSHIFT}, + {XK_Shift_R, ALLEGRO_KEY_RSHIFT}, + {XK_Control_L, ALLEGRO_KEY_LCTRL}, + {XK_Control_R, ALLEGRO_KEY_RCTRL}, + {XK_Alt_L, ALLEGRO_KEY_ALT}, + + /* Double mappings. This is a bit of a problem, since you can configure + * X11 differently to what report for those keys. + */ + {XK_Alt_R, ALLEGRO_KEY_ALTGR}, + {XK_ISO_Level3_Shift, ALLEGRO_KEY_ALTGR}, + {XK_Meta_L, ALLEGRO_KEY_LWIN}, + {XK_Super_L, ALLEGRO_KEY_LWIN}, + {XK_Meta_R, ALLEGRO_KEY_RWIN}, + {XK_Super_R, ALLEGRO_KEY_RWIN}, + + {XK_Menu, ALLEGRO_KEY_MENU}, + {XK_Scroll_Lock, ALLEGRO_KEY_SCROLLLOCK}, + {XK_Num_Lock, ALLEGRO_KEY_NUMLOCK}, + {XK_Caps_Lock, ALLEGRO_KEY_CAPSLOCK} +}; + +/* Table of: Allegro's modifier flag, associated X11 flag, toggle method. */ +static int modifier_flags[8][3] = { + {ALLEGRO_KEYMOD_SHIFT, ShiftMask, 0}, + {ALLEGRO_KEYMOD_CAPSLOCK, LockMask, 1}, + {ALLEGRO_KEYMOD_CTRL, ControlMask, 0}, + {ALLEGRO_KEYMOD_ALT, Mod1Mask, 0}, + {ALLEGRO_KEYMOD_NUMLOCK, Mod2Mask, 1}, + {ALLEGRO_KEYMOD_SCROLLLOCK, Mod3Mask, 1}, + {ALLEGRO_KEYMOD_LWIN | ALLEGRO_KEYMOD_RWIN, Mod4Mask, 0}, /* Should we use only one? */ + {ALLEGRO_KEYMOD_MENU, Mod5Mask, 0} /* AltGr */ +}; + +/* Table of key names. */ +static char const *key_names[ALLEGRO_KEY_MAX]; + + + +/* update_shifts + * Update Allegro's key_shifts variable, directly from the corresponding + * X11 modifiers state. + */ +static void update_shifts(XKeyEvent *event) +{ + int mask = 0; + int i; + + for (i = 0; i < 8; i++) { + int j; + /* This is the state of the modifiers just before the key + * press/release. + */ + if (event->state & modifier_flags[i][1]) + mask |= modifier_flags[i][0]; + + /* In case a modifier key itself was pressed, we now need to update + * the above state for Allegro, which wants the state after the + * press, not before as reported by X. + */ + for (j = 0; j < xmodmap->max_keypermod; j++) { + if (event->keycode && event->keycode == + xmodmap->modifiermap[i * xmodmap->max_keypermod + j]) { + if (event->type == KeyPress) { + /* Modifier key pressed - toggle or set flag. */ + if (modifier_flags[i][2]) + mask ^= modifier_flags[i][0]; + else + mask |= modifier_flags[i][0]; + } + else if (event->type == KeyRelease) { + /* Modifier key of non-toggle key released - remove flag. */ + if (!modifier_flags[i][2]) + mask &= ~modifier_flags[i][0]; + } + } + } + } + _key_shifts = mask; +} + + + +/* find_unknown_key_assignment + * In some cases, X11 doesn't report any KeySym for a key - so the earliest + * time we can map it to an Allegro key is when it is first pressed. + */ +static int find_unknown_key_assignment(int i) +{ + int j; + + for (j = 1; j < ALLEGRO_KEY_MAX; j++) { + if (!used[j]) { + const char *str; + keycode_to_scancode[i] = j; + str = XKeysymToString(keysyms[sym_per_key * (i - min_keycode)]); + if (str) + key_names[j] = str; + else { + key_names[j] = _al_keyboard_common_names[j]; + } + used[j] = 1; + break; + } + } + + if (j == ALLEGRO_KEY_MAX) { + ALLEGRO_ERROR("You have more keys reported by X than Allegro's " + "maximum of %i keys. Please send a bug report.\n", ALLEGRO_KEY_MAX); + keycode_to_scancode[i] = 0; + } + + char str[1024]; + sprintf(str, "Key %i missing:", i); + for (j = 0; j < sym_per_key; j++) { + char *sym_str = XKeysymToString(keysyms[sym_per_key * (i - min_keycode) + j]); + sprintf(str + strlen(str), " %s", sym_str ? sym_str : "NULL"); + } + ALLEGRO_DEBUG("%s assigned to %i.\n", str, keycode_to_scancode[i]); + + return keycode_to_scancode[i]; +} + + +/* XCheckIfAny predicate that checks if this event may be a key repeat event */ +static Bool check_for_repeat(Display *display, XEvent *event, XPointer arg) +{ + ALLEGRO_KEY_REPEAT_DATA *d = (ALLEGRO_KEY_REPEAT_DATA *)arg; + + (void)display; + + if (event->type == KeyPress && + event->xkey.keycode == d->event->keycode && + (event->xkey.time - d->event->time) < 4) { + d->found = true; + } + + return False; +} + + +/* _al_xwin_keyboard_handler: + * Keyboard "interrupt" handler. + */ +void _al_xwin_keyboard_handler(XKeyEvent *event, ALLEGRO_DISPLAY *display) +{ + int keycode; + + if (!xkeyboard_installed) + return; + + keycode = keycode_to_scancode[event->keycode]; + if (keycode == -1) + keycode = find_unknown_key_assignment(event->keycode); + + update_shifts(event); + + /* Special case the pause key. */ + if (keycode == ALLEGRO_KEY_PAUSE) { + /* Allegro ignore's releasing of the pause key. */ + if (event->type == KeyRelease) + return; + if (pause_key) { + event->type = KeyRelease; + pause_key = 0; + } + else { + pause_key = 1; + } + } + + if (event->type == KeyPress) { /* Key pressed. */ + int len; + char buffer[16]; + int unicode = 0; + int filtered = 0; + +#if defined (ALLEGRO_XWINDOWS_WITH_XIM) && defined(X_HAVE_UTF8_STRING) + if (xic) { + len = Xutf8LookupString(xic, event, buffer, sizeof buffer, NULL, NULL); + } + else +#endif + { + /* XLookupString is supposed to only use ASCII. */ + len = XLookupString(event, buffer, sizeof buffer, NULL, NULL); + } + buffer[len] = '\0'; + ALLEGRO_USTR_INFO info; + const ALLEGRO_USTR *ustr = al_ref_cstr(&info, buffer); + unicode = al_ustr_get(ustr, 0); + if (unicode < 0) + unicode = 0; + +#ifdef ALLEGRO_XWINDOWS_WITH_XIM + ALLEGRO_DISPLAY_XGLX *glx = (void *)display; + filtered = XFilterEvent((XEvent *)event, glx->window); +#endif + if (keycode || unicode) { + handle_key_press(keycode, unicode, filtered, _key_shifts, display); + } + } + else { /* Key release. */ + /* HACK: + * Detect key repeat by looking forward to see if this release is + * followed by a press event, in which case we assume that this release + * event was generated in response to that key press event. Events are + * simultaneous if they are separated by less than 4 ms (a value that + * worked well on one machine where this hack was needed). + * + * This is unnecessary on systems where XkbSetDetectableAutorepeat works. + */ + if (XPending(event->display) > 0) { + ALLEGRO_KEY_REPEAT_DATA d; + XEvent dummy; + d.event = event; + d.found = false; + XCheckIfEvent(event->display, &dummy, check_for_repeat, (XPointer)&d); + if (d.found) { + return; + } + } + handle_key_release(keycode, _key_shifts, display); + } +} + + + +/* _al_xwin_keyboard_switch_handler: + * Handle a focus switch event. + */ +void _al_xwin_keyboard_switch_handler(ALLEGRO_DISPLAY *display, bool focus_in) +{ + _al_event_source_lock(&the_keyboard.parent.es); + + if (focus_in) { + the_keyboard.state.display = display; +#ifdef ALLEGRO_XWINDOWS_WITH_XIM + if (xic) { + ALLEGRO_DISPLAY_XGLX *display_glx = (void *)display; + XSetICValues(xic, XNClientWindow, display_glx->window, NULL); + } +#endif + } + else { + the_keyboard.state.display = NULL; + } + + _al_event_source_unlock(&the_keyboard.parent.es); +} + + + +/* find_allegro_key + * Search the translation table for the Allegro key corresponding to the + * given KeySym. + */ +static int find_allegro_key(KeySym sym) +{ + int i; + int n = sizeof translation_table / sizeof *translation_table; + + for (i = 0; i < n; i++) { + if (translation_table[i].keysym == sym) + return translation_table[i].allegro_key; + } + return 0; +} + + + +/* scancode_to_name: + * Converts the given scancode to a description of the key. + */ +static const char *x_scancode_to_name(int scancode) +{ + ASSERT (scancode >= 0 && scancode < ALLEGRO_KEY_MAX); + + return key_names[scancode]; +} + + + +/* _al_xwin_get_keyboard_mapping: + * Generate a mapping from X11 keycodes to Allegro ALLEGRO_KEY_* codes. We have + * two goals: Every keypress should be mapped to a distinct Allegro ALLEGRO_KEY_* + * code. And we want the ALLEGRO_KEY_* codes to match the pressed + * key to some extent. To do the latter, the X11 KeySyms produced by a key + * are examined. If a match is found in the table above, the mapping is + * added to the mapping table. If no known KeySym is found for a key (or + * the same KeySym is found for more keys) - the remaining keys are + * distributed arbitrarily to the remaining ALLEGRO_KEY_* codes. + * + * In a future version, this could be simplified by mapping *all* the X11 + * KeySyms to ALLEGRO_KEY_* codes. + */ + +static bool _al_xwin_get_keyboard_mapping(void) +{ + int i; + int count; + int missing = 0; + + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + memset(used, 0, sizeof used); + memset(keycode_to_scancode, 0, sizeof keycode_to_scancode); + + XDisplayKeycodes(system->x11display, &min_keycode, &max_keycode); + count = 1 + max_keycode - min_keycode; + + if (keysyms) { + XFree(keysyms); + } + keysyms = XGetKeyboardMapping(system->x11display, min_keycode, + count, &sym_per_key); + + ALLEGRO_INFO("%i keys, %i symbols per key.\n", count, sym_per_key); + + if (sym_per_key <= 0) { + return false; + } + + missing = 0; + + for (i = min_keycode; i <= max_keycode; i++) { + KeySym sym = keysyms[sym_per_key * (i - min_keycode)]; + KeySym sym2 = keysyms[sym_per_key * (i - min_keycode) + 1]; + char *sym_str, *sym2_str; + int allegro_key = 0; + char str[1024]; + + sym_str = XKeysymToString(sym); + sym2_str = XKeysymToString(sym2); + + snprintf(str, sizeof str, "key [%i: %s %s]", i, + sym_str ? sym_str : "NULL", sym2_str ? sym2_str : "NULL"); + + /* Hack for French keyboards, to correctly map ALLEGRO_KEY_0 to ALLEGRO_KEY_9. */ + if (sym2 >= XK_0 && sym2 <= XK_9) { + allegro_key = find_allegro_key(sym2); + } + + if (!allegro_key) { + if (sym != NoSymbol) { + allegro_key = find_allegro_key(sym); + + if (allegro_key == 0) { + missing++; + ALLEGRO_DEBUG("%s defering.\n", str); + } + } + else { + /* No KeySym for this key - ignore it. */ + keycode_to_scancode[i] = -1; + ALLEGRO_DEBUG("%s not assigned.\n", str); + } + } + + if (allegro_key) { + bool is_double = false; + if (used[allegro_key]) { + is_double = true; + } + keycode_to_scancode[i] = allegro_key; + key_names[allegro_key] = + XKeysymToString(keysyms[sym_per_key * (i - min_keycode)]); + used[allegro_key] = 1; + ALLEGRO_DEBUG("%s%s assigned to %i.\n", str, + is_double ? " *double*" : "", allegro_key); + } + } + + if (missing) { + /* The keys still not assigned are just assigned arbitrarily now. */ + for (i = min_keycode; i <= max_keycode; i++) { + if (keycode_to_scancode[i] == 0) { + find_unknown_key_assignment(i); + } + } + } + + if (xmodmap) + XFreeModifiermap(xmodmap); + xmodmap = XGetModifierMapping(system->x11display); + for (i = 0; i < 8; i++) { + int j; + char str[1024]; + sprintf(str, "Modifier %d:", i + 1); + for (j = 0; j < xmodmap->max_keypermod; j++) { + KeyCode keycode = xmodmap->modifiermap[i * xmodmap->max_keypermod + j]; + // XKeycodeToKeysym is deprecated + //KeySym sym = XKeycodeToKeysym(system->x11display, keycode, 0); + KeySym sym = XkbKeycodeToKeysym(system->x11display, keycode, 0, 0); + + char *sym_str = XKeysymToString(sym); + sprintf(str + strlen(str), " %s", sym_str ? sym_str : "NULL"); + } + ALLEGRO_DEBUG("%s\n", str); + } + + /* The [xkeymap] section can be useful, e.g. if trying to play a + * game which has X and Y hardcoded as ALLEGRO_KEY_X and ALLEGRO_KEY_Y to mean + * left/right movement, but on the X11 keyboard X and Y are far apart. + * For normal use, a user never should have to touch [xkeymap] anymore + * though, and proper written programs will not hardcode such mappings. + */ + ALLEGRO_CONFIG *c = al_get_system_config(); + + char const *key; + ALLEGRO_CONFIG_ENTRY *it; + key = al_get_first_config_entry(c, "xkeymap", &it); + while (key) { + char const *val; + val = al_get_config_value(c, "xkeymap", key); + int keycode = strtol(key, NULL, 10); + int scancode = strtol(val, NULL, 10); + if (keycode > 0 && scancode > 0) { + keycode_to_scancode[keycode] = scancode; + ALLEGRO_WARN("User override: KeySym %i assigned to %i.\n", + keycode, scancode); + } + key = al_get_next_config_entry(&it); + } + + return true; +} + + + +/* x_set_leds: + * Update the keyboard LEDs. + */ +static void x_set_leds(int leds) +{ + XKeyboardControl values; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + ASSERT(xkeyboard_installed); + + _al_mutex_lock(&system->lock); + + values.led = 1; + values.led_mode = leds & ALLEGRO_KEYMOD_NUMLOCK ? LedModeOn : LedModeOff; + XChangeKeyboardControl(system->x11display, KBLed | KBLedMode, &values); + + values.led = 2; + values.led_mode = leds & ALLEGRO_KEYMOD_CAPSLOCK ? LedModeOn : LedModeOff; + XChangeKeyboardControl(system->x11display, KBLed | KBLedMode, &values); + + values.led = 3; + values.led_mode = leds & ALLEGRO_KEYMOD_SCROLLLOCK ? LedModeOn : LedModeOff; + XChangeKeyboardControl(system->x11display, KBLed | KBLedMode, &values); + + _al_mutex_unlock(&system->lock); +} + + + +/* x_keyboard_init + * Initialise the X11 keyboard driver. + */ +static int x_keyboard_init(void) +{ +#ifdef ALLEGRO_XWINDOWS_WITH_XIM + char *old_locale; + XIMStyles *xim_styles; + XIMStyle xim_style = 0; + char *imvalret; + int i; +#endif + ALLEGRO_SYSTEM_XGLX *s = (void *)al_get_system_driver(); + + if (xkeyboard_installed) + return 0; + + if (s->x11display == NULL) + return 0; + + main_pid = getpid(); + + memcpy(key_names, _al_keyboard_common_names, sizeof key_names); + + _al_mutex_lock(&s->lock); + + /* HACK: XkbSetDetectableAutoRepeat is broken in some versions of X.Org */ + Bool supported; + XkbSetDetectableAutoRepeat(s->x11display, True, &supported); + if (!supported) { + ALLEGRO_WARN("XkbSetDetectableAutoRepeat failed.\n"); + } + +#ifdef ALLEGRO_XWINDOWS_WITH_XIM + ALLEGRO_INFO("Using X Input Method.\n"); + + old_locale = setlocale(LC_CTYPE, NULL); + ALLEGRO_DEBUG("Old locale: %s\n", old_locale ? old_locale : "(null)"); + if (old_locale) { + /* The return value of setlocale() may be clobbered by the next call + * to setlocale() so we must copy it. + */ + old_locale = strdup(old_locale); + } + + /* Otherwise we are restricted to ISO-8859-1 characters. */ + if (setlocale(LC_CTYPE, "") == NULL) { + ALLEGRO_WARN("Could not set default locale.\n"); + } + + /* By default never use an input method as we are not prepared to + * handle any of them. This is still enough to get composed keys. + */ + char const *modifiers = XSetLocaleModifiers("@im=none"); + if (modifiers == NULL) { + ALLEGRO_WARN("XSetLocaleModifiers failed.\n"); + } + + xim = XOpenIM(s->x11display, NULL, NULL, NULL); + if (xim == NULL) { + ALLEGRO_WARN("XOpenIM failed.\n"); + } + + if (old_locale) { + ALLEGRO_DEBUG("Restoring old locale: %s\n", old_locale); + setlocale(LC_CTYPE, old_locale); + free(old_locale); + } + + if (xim) { + imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL); + if (imvalret != NULL || xim_styles == NULL) { + ALLEGRO_WARN("Input method doesn't support any styles.\n"); + } + + if (xim_styles) { + xim_style = 0; + for (i = 0; i < xim_styles->count_styles; i++) { + if (xim_styles->supported_styles[i] == + (XIMPreeditNothing | XIMStatusNothing)) { + xim_style = xim_styles->supported_styles[i]; + break; + } + } + + if (xim_style == 0) { + ALLEGRO_WARN("Input method doesn't support the style we support.\n"); + } + else { + ALLEGRO_INFO("Input method style = %ld\n", xim_style); + } + XFree(xim_styles); + } + } + + if (xim && xim_style) { + xic = XCreateIC(xim, + XNInputStyle, xim_style, + NULL); + if (xic == NULL) { + ALLEGRO_WARN("XCreateIC failed.\n"); + } + else { + ALLEGRO_INFO("XCreateIC succeeded.\n"); + } + + /* In case al_install_keyboard() is called when there already is + * a display, we set it as client window. + */ + ALLEGRO_DISPLAY *display = al_get_current_display(); + ALLEGRO_DISPLAY_XGLX *display_glx = (void *)display; + if (display_glx && xic) + XSetICValues(xic, XNClientWindow, display_glx->window, NULL); + } +#endif + + if (!_al_xwin_get_keyboard_mapping()) { + return 1; + } + + _al_mutex_unlock(&s->lock); + + xkeyboard_installed = 1; + + return 0; +} + + + +/* x_keyboard_exit + * Shut down the X11 keyboard driver. + */ +static void x_keyboard_exit(void) +{ + if (!xkeyboard_installed) + return; + xkeyboard_installed = 0; + + ALLEGRO_SYSTEM_XGLX *s = (void *)al_get_system_driver(); + + _al_mutex_lock(&s->lock); + +#ifdef ALLEGRO_XWINDOWS_WITH_XIM + + if (xic) { + XDestroyIC(xic); + xic = NULL; + } + + if (xim) { + XCloseIM(xim); + xim = NULL; + } + +#endif + + if (xmodmap) { + XFreeModifiermap(xmodmap); + xmodmap = NULL; + } + + if (keysyms) { + XFree(keysyms); + keysyms = NULL; + } + + _al_mutex_unlock(&s->lock); +} + + + +/*---------------------------------------------------------------------- + * + * Supports for new API. For now this code is kept separate from the + * above to ease merging changes made in the trunk. + * + */ + + +/* forward declarations */ +static bool xkeybd_init_keyboard(void); +static void xkeybd_exit_keyboard(void); +static ALLEGRO_KEYBOARD *xkeybd_get_keyboard(void); +static bool xkeybd_set_keyboard_leds(int leds); +static const char *xkeybd_keycode_to_name(int keycode); +static void xkeybd_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state); +static void xkeybd_clear_keyboard_state(void); + + + +/* the driver vtable */ +#define KEYDRV_XWIN AL_ID('X','W','I','N') + +static ALLEGRO_KEYBOARD_DRIVER keydrv_xwin = +{ + KEYDRV_XWIN, + "", + "", + "X11 keyboard", + xkeybd_init_keyboard, + xkeybd_exit_keyboard, + xkeybd_get_keyboard, + xkeybd_set_keyboard_leds, + xkeybd_keycode_to_name, + xkeybd_get_keyboard_state, + xkeybd_clear_keyboard_state +}; + + + +ALLEGRO_KEYBOARD_DRIVER *_al_xwin_keyboard_driver(void) +{ + return &keydrv_xwin; +} + + + +/* xkeybd_init_keyboard: + * Initialise the driver. + */ +static bool xkeybd_init_keyboard(void) +{ + if (x_keyboard_init() != 0) + return false; + + memset(&the_keyboard, 0, sizeof the_keyboard); + + _al_event_source_init(&the_keyboard.parent.es); + + the_keyboard.three_finger_flag = true; + + const char *value = al_get_config_value(al_get_system_config(), + "keyboard", "enable_three_finger_exit"); + if (value) { + the_keyboard.three_finger_flag = !strncmp(value, "true", 4); + } + ALLEGRO_DEBUG("Three finger flag enabled: %s\n", + the_keyboard.three_finger_flag ? "true" : "false"); + + //_xwin_keydrv_set_leds(_key_shifts); + + /* Get the pid, which we use for the three finger salute */ + main_pid = getpid(); + + return true; +} + + + +/* xkeybd_exit_keyboard: + * Shut down the keyboard driver. + */ +static void xkeybd_exit_keyboard(void) +{ + x_keyboard_exit(); + + _al_event_source_free(&the_keyboard.parent.es); +} + + + +/* xkeybd_get_keyboard: + * Returns the address of a ALLEGRO_KEYBOARD structure representing the keyboard. + */ +static ALLEGRO_KEYBOARD *xkeybd_get_keyboard(void) +{ + return (ALLEGRO_KEYBOARD *)&the_keyboard; +} + + + +/* xkeybd_set_keyboard_leds: + * Updates the LED state. + */ +static bool xkeybd_set_keyboard_leds(int leds) +{ + x_set_leds(leds); + return true; +} + + + +/* xkeybd_keycode_to_name: + * Converts the given keycode to a description of the key. + */ +static const char *xkeybd_keycode_to_name(int keycode) +{ + return x_scancode_to_name(keycode); +} + + + +/* xkeybd_get_keyboard_state: + * Copy the current keyboard state into RET_STATE, with any necessary locking. + */ +static void xkeybd_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state) +{ + _al_event_source_lock(&the_keyboard.parent.es); + { + *ret_state = the_keyboard.state; + } + _al_event_source_unlock(&the_keyboard.parent.es); +} + + + +/* xkeybd_get_keyboard_state: + * Clear the current keyboard state, with any necessary locking. + */ +static void xkeybd_clear_keyboard_state(void) +{ + _al_event_source_lock(&the_keyboard.parent.es); + { + last_press_code = -1; + memset(&the_keyboard.state, 0, sizeof(the_keyboard.state)); + } + _al_event_source_unlock(&the_keyboard.parent.es); +} + + + +/* handle_key_press: [bgman thread] + * Hook for the X event dispatcher to handle key presses. + * The caller must lock the X-display. + */ +static void handle_key_press(int mycode, int unichar, int filtered, + unsigned int modifiers, ALLEGRO_DISPLAY *display) +{ + bool is_repeat; + + is_repeat = (last_press_code == mycode); + if (mycode > 0) + last_press_code = mycode; + + _al_event_source_lock(&the_keyboard.parent.es); + { + /* Update the key_down array. */ + _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_keyboard.state, mycode); + + /* Generate the events if necessary. */ + if (_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) { + ALLEGRO_EVENT event; + + event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = display; + event.keyboard.keycode = last_press_code; + event.keyboard.unichar = 0; + event.keyboard.modifiers = modifiers; + event.keyboard.repeat = false; + + /* Don't send KEY_DOWN for non-physical key events. */ + if (mycode > 0 && !is_repeat) { + _al_event_source_emit_event(&the_keyboard.parent.es, &event); + } + + /* Don't send KEY_CHAR for events filtered by an input method, + * nor modifier keys. + */ + if (!filtered && mycode < ALLEGRO_KEY_MODIFIERS) { + event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR; + event.keyboard.unichar = unichar; + event.keyboard.modifiers = modifiers; + event.keyboard.repeat = is_repeat; + _al_event_source_emit_event(&the_keyboard.parent.es, &event); + } + } + } + _al_event_source_unlock(&the_keyboard.parent.es); + +// FIXME? +#ifndef ALLEGRO_RASPBERRYPI + /* Toggle mouse grab key. The system driver should not be locked here. */ + if (last_press_code && !is_repeat) { + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + if (system->toggle_mouse_grab_keycode && + system->toggle_mouse_grab_keycode == mycode && + (modifiers & system->toggle_mouse_grab_modifiers) + == system->toggle_mouse_grab_modifiers) + { + if (system->mouse_grab_display == display) + al_ungrab_mouse(); + else + al_grab_mouse(display); + } + } +#endif + + /* Exit by Ctrl-Alt-End. */ + if ((the_keyboard.three_finger_flag) + && ((mycode == ALLEGRO_KEY_DELETE) || (mycode == ALLEGRO_KEY_END)) + && (modifiers & ALLEGRO_KEYMOD_CTRL) + && (modifiers & (ALLEGRO_KEYMOD_ALT | ALLEGRO_KEYMOD_ALTGR))) + { + ALLEGRO_WARN("Three finger combo detected. SIGTERMing " + "pid %d\n", main_pid); + kill(main_pid, SIGTERM); + } +} + + + +/* handle_key_release: [bgman thread] + * Hook for the X event dispatcher to handle key releases. + * The caller must lock the X-display. + */ +static void handle_key_release(int mycode, unsigned int modifiers, ALLEGRO_DISPLAY *display) +{ + if (last_press_code == mycode) + last_press_code = -1; + + _al_event_source_lock(&the_keyboard.parent.es); + { + /* Update the key_down array. */ + _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_keyboard.state, mycode); + + /* Generate the release event if necessary. */ + if (_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) { + ALLEGRO_EVENT event; + event.keyboard.type = ALLEGRO_EVENT_KEY_UP; + event.keyboard.timestamp = al_get_time(); + event.keyboard.display = display; + event.keyboard.keycode = mycode; + event.keyboard.unichar = 0; + event.keyboard.modifiers = modifiers; + _al_event_source_emit_event(&the_keyboard.parent.es, &event); + } + } + _al_event_source_unlock(&the_keyboard.parent.es); +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/xmousenu.c b/allegro/src/x/xmousenu.c new file mode 100644 index 00000000..c2a258ee --- /dev/null +++ b/allegro/src/x/xmousenu.c @@ -0,0 +1,610 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * X-Windows mouse module. + * + * By Peter Wang. + * + * Original by Michael Bukin. + * + * See readme.txt for copyright information. + */ + + +#define ALLEGRO_NO_COMPATIBILITY + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xmouse.h" +#include "allegro5/internal/aintern_xsystem.h" + +#ifdef ALLEGRO_RASPBERRYPI +#include "allegro5/internal/aintern_raspberrypi.h" +#include "allegro5/internal/aintern_vector.h" +#define ALLEGRO_SYSTEM_XGLX ALLEGRO_SYSTEM_RASPBERRYPI +#define ALLEGRO_DISPLAY_XGLX ALLEGRO_DISPLAY_RASPBERRYPI +#endif + +ALLEGRO_DEBUG_CHANNEL("mouse") + +typedef struct ALLEGRO_MOUSE_XWIN +{ + ALLEGRO_MOUSE parent; + ALLEGRO_MOUSE_STATE state; + int min_x, min_y; + int max_x, max_y; +} ALLEGRO_MOUSE_XWIN; + + + +static bool xmouse_installed = false; + +/* the one and only mouse object */ +static ALLEGRO_MOUSE_XWIN the_mouse; + + + +/* forward declarations */ +static bool xmouse_init(void); +static void xmouse_exit(void); +static ALLEGRO_MOUSE *xmouse_get_mouse(void); +static unsigned int xmouse_get_mouse_num_buttons(void); +static unsigned int xmouse_get_mouse_num_axes(void); +static bool xmouse_set_mouse_xy(ALLEGRO_DISPLAY *,int x, int y); +static bool xmouse_set_mouse_axis(int which, int z); +static void xmouse_get_state(ALLEGRO_MOUSE_STATE *ret_state); + +static void wheel_motion_handler(int x_button, ALLEGRO_DISPLAY *display); +static unsigned int x_button_to_al_button(unsigned int x_button); +static void generate_mouse_event(unsigned int type, + int x, int y, int z, int w, float pressure, + int dx, int dy, int dz, int dw, + unsigned int button, + ALLEGRO_DISPLAY *display); + + + +/* the driver vtable */ +#define MOUSEDRV_XWIN AL_ID('X','W','I','N') + +static ALLEGRO_MOUSE_DRIVER mousedrv_xwin = +{ + MOUSEDRV_XWIN, + "", + "", + "X-Windows mouse", + xmouse_init, + xmouse_exit, + xmouse_get_mouse, + xmouse_get_mouse_num_buttons, + xmouse_get_mouse_num_axes, + xmouse_set_mouse_xy, + xmouse_set_mouse_axis, + xmouse_get_state +}; + + + +ALLEGRO_MOUSE_DRIVER *_al_xwin_mouse_driver(void) +{ + return &mousedrv_xwin; +} + + +/* xmouse_init: + * Initialise the driver. + */ +static bool xmouse_init(void) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY *display; + int x, y; + + if (system->x11display == NULL) + return false; + if (xmouse_installed) + return false; + + /* Don't clobber mouse position in case the display was created before + * the mouse is installed. + */ + display = the_mouse.state.display; + x = the_mouse.state.x; + y = the_mouse.state.y; + memset(&the_mouse, 0, sizeof the_mouse); + the_mouse.state.display = display; + the_mouse.state.x = x; + the_mouse.state.y = y; + + _al_event_source_init(&the_mouse.parent.es); + + xmouse_installed = true; + + return true; +} + + + +/* xmouse_exit: + * Shut down the mouse driver. + */ +static void xmouse_exit(void) +{ + if (!xmouse_installed) + return; + xmouse_installed = false; + + _al_event_source_free(&the_mouse.parent.es); +} + + + +/* xmouse_get_mouse: + * Returns the address of a ALLEGRO_MOUSE structure representing the mouse. + */ +static ALLEGRO_MOUSE *xmouse_get_mouse(void) +{ + ASSERT(xmouse_installed); + + return (ALLEGRO_MOUSE *)&the_mouse; +} + + + +/* xmouse_get_mouse_num_buttons: + * Return the number of buttons on the mouse. + */ +static unsigned int xmouse_get_mouse_num_buttons(void) +{ + int num_buttons; + unsigned char map[32]; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + ASSERT(xmouse_installed); + + _al_mutex_lock(&system->lock); + num_buttons = XGetPointerMapping(system->x11display, map, sizeof(map)); + _al_mutex_unlock(&system->lock); + + if (num_buttons > (int)sizeof(map)) + num_buttons = sizeof(map); + + #ifdef DEBUGMODE + char debug[num_buttons * 4 + 1]; + debug[0] = 0; + int i; + for (i = 0; i < num_buttons; i++) { + sprintf(debug + strlen(debug), "%2d,", map[i]); + } + ALLEGRO_DEBUG("XGetPointerMapping: %s\n", debug); + #endif + + if (num_buttons < 1) + num_buttons = 1; + + return num_buttons; +} + + + +/* xmouse_get_mouse_num_axes: + * Return the number of axes on the mouse. + */ +static unsigned int xmouse_get_mouse_num_axes(void) +{ + ASSERT(xmouse_installed); + + /* TODO: is there a way to detect whether z/w axis actually exist? */ + return 4; +} + + + +/* xmouse_set_mouse_xy: + * Set the mouse position. Return true if successful. + */ +static bool xmouse_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y) +{ + if (!xmouse_installed) + return false; + + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Display *x11display = system->x11display; + ALLEGRO_DISPLAY_XGLX *d = (void *)display; + + int window_width = al_get_display_width(display); + int window_height = al_get_display_height(display); + if (x < 0 || y < 0 || x >= window_width || y >= window_height) + return false; + + the_mouse.state.x = x; + the_mouse.state.y = y; + +#ifdef ALLEGRO_RASPBERRYPI + float scale_x, scale_y; + _al_raspberrypi_get_mouse_scale_ratios(&scale_x, &scale_y); + x /= scale_x; + y /= scale_y; +#endif + + _al_mutex_lock(&system->lock); + + /* We prepend the mouse motion event generated by XWarpPointer + * with our own event to distinguish real and generated + * events. + */ + XEvent event; + memset(&event, 0, sizeof event); + event.xclient.type = ClientMessage; + event.xclient.serial = 0; + event.xclient.send_event = True; + event.xclient.display = x11display; + event.xclient.window = d->window; + event.xclient.message_type = system->AllegroAtom; + event.xclient.format = 32; + XSendEvent(x11display, d->window, False, NoEventMask, &event); + + XWarpPointer(x11display, None, d->window, 0, 0, 0, 0, x, y); + _al_mutex_unlock(&system->lock); + + return true; +} + + + +/* xmouse_set_mouse_axis: + * Set the mouse wheel position. Return true if successful. + */ +static bool xmouse_set_mouse_axis(int which, int v) +{ + ASSERT(xmouse_installed); + + if (which != 2 && which != 3) { + return false; + } + + _al_event_source_lock(&the_mouse.parent.es); + { + int z = which == 2 ? v : the_mouse.state.z; + int w = which == 3 ? v : the_mouse.state.w; + int dz = z - the_mouse.state.z; + int dw = w - the_mouse.state.w; + + if (dz != 0 || dw != 0) { + the_mouse.state.z = z; + the_mouse.state.w = w; + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_AXES, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + the_mouse.state.w, the_mouse.state.pressure, + 0, 0, dz, dw, + 0, the_mouse.state.display); + } + } + _al_event_source_unlock(&the_mouse.parent.es); + + return true; +} + + + + +/* xmouse_get_state: + * Copy the current mouse state into RET_STATE, with any necessary locking. + */ +static void xmouse_get_state(ALLEGRO_MOUSE_STATE *ret_state) +{ + ASSERT(xmouse_installed); + + _al_event_source_lock(&the_mouse.parent.es); + { + *ret_state = the_mouse.state; + } + _al_event_source_unlock(&the_mouse.parent.es); +} + + + +/* _al_xwin_mouse_button_press_handler: [bgman thread] + * Called by _xwin_process_event() for ButtonPress events received from the X + * server. + */ +void _al_xwin_mouse_button_press_handler(int x_button, + ALLEGRO_DISPLAY *display) +{ + unsigned int al_button; + + if (!xmouse_installed) + return; + + wheel_motion_handler(x_button, display); + + /* Is this button supported by the Allegro API? */ + al_button = x_button_to_al_button(x_button); + if (al_button == 0) + return; + + _al_event_source_lock(&the_mouse.parent.es); + { + the_mouse.state.buttons |= (1 << (al_button - 1)); + the_mouse.state.pressure = the_mouse.state.buttons ? 1.0 : 0.0; /* TODO */ + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + the_mouse.state.w, the_mouse.state.pressure, + 0, 0, 0, 0, + al_button, display); + } + _al_event_source_unlock(&the_mouse.parent.es); +} + + + +/* wheel_motion_handler: [bgman thread] + * Called by _al_xwin_mouse_button_press_handler() if the ButtonPress event + * received from the X server is actually for a mouse wheel movement. + */ +static void wheel_motion_handler(int x_button, ALLEGRO_DISPLAY *display) +{ + int dz = 0, dw = 0; + if (x_button == Button4) dz = 1; + if (x_button == Button5) dz = -1; + if (x_button == 6) dw = -1; + if (x_button == 7) dw = 1; + if (dz == 0 && dw == 0) return; + + dz *= al_get_mouse_wheel_precision(); + dw *= al_get_mouse_wheel_precision(); + + _al_event_source_lock(&the_mouse.parent.es); + { + the_mouse.state.z += dz; + the_mouse.state.w += dw; + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_AXES, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + the_mouse.state.w, the_mouse.state.pressure, + 0, 0, dz, dw, + 0, display); + } + _al_event_source_unlock(&the_mouse.parent.es); +} + + + +/* _al_xwin_mouse_button_release_handler: [bgman thread] + * Called by _xwin_process_event() for ButtonRelease events received from the + * X server. + */ +void _al_xwin_mouse_button_release_handler(int x_button, + ALLEGRO_DISPLAY *display) +{ + int al_button; + + if (!xmouse_installed) + return; + + al_button = x_button_to_al_button(x_button); + if (al_button == 0) + return; + + _al_event_source_lock(&the_mouse.parent.es); + { + the_mouse.state.buttons &=~ (1 << (al_button - 1)); + the_mouse.state.pressure = the_mouse.state.buttons ? 1.0 : 0.0; /* TODO */ + + generate_mouse_event( + ALLEGRO_EVENT_MOUSE_BUTTON_UP, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + the_mouse.state.w, the_mouse.state.pressure, + 0, 0, 0, 0, + al_button, display); + } + _al_event_source_unlock(&the_mouse.parent.es); +} + + + +/* _al_xwin_mouse_motion_notify_handler: [bgman thread] + * Called by _xwin_process_event() for MotionNotify events received from the X + * server. + */ +void _al_xwin_mouse_motion_notify_handler(int x, int y, + ALLEGRO_DISPLAY *display) +{ + ALLEGRO_DISPLAY_XGLX *glx = (void *)display; + int event_type = ALLEGRO_EVENT_MOUSE_AXES; + + if (!xmouse_installed) + return; + + /* Is this an event generated in response to al_set_mouse_xy? */ + if (glx->mouse_warp) { + glx->mouse_warp = false; + event_type = ALLEGRO_EVENT_MOUSE_WARPED; + } + + _al_event_source_lock(&the_mouse.parent.es); + +#ifdef ALLEGRO_RASPBERRYPI + float scale_x, scale_y; + _al_raspberrypi_get_mouse_scale_ratios(&scale_x, &scale_y); + x *= scale_x; + y *= scale_y; +#endif + + int dx = x - the_mouse.state.x; + int dy = y - the_mouse.state.y; + + the_mouse.state.x = x; + the_mouse.state.y = y; + the_mouse.state.display = display; + + generate_mouse_event( + event_type, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, + the_mouse.state.w, the_mouse.state.pressure, + dx, dy, 0, 0, + 0, display); + + _al_event_source_unlock(&the_mouse.parent.es); +} + + + +/* x_button_to_al_button: [bgman thread] + * Map a X button number to an Allegro button number. + */ +static unsigned int x_button_to_al_button(unsigned int x_button) +{ + switch (x_button) { + case Button1: + return 1; + case Button2: + return 3; + case Button3: + return 2; + case Button4: + case Button5: + case 6: + case 7: + // hardcoded for z and w wheel + return 0; + default: + if (x_button >= 8 && x_button <= 36) { + return 4 + x_button - 8; + } + return 0; + } +} + + + +/* generate_mouse_event: [bgman thread] + * Helper to generate a mouse event. + */ +static void generate_mouse_event(unsigned int type, + int x, int y, int z, int w, float pressure, + int dx, int dy, int dz, int dw, + unsigned int button, + ALLEGRO_DISPLAY *display) +{ + ALLEGRO_EVENT event; + + if (!_al_event_source_needs_to_generate_event(&the_mouse.parent.es)) + return; + + event.mouse.type = type; + event.mouse.timestamp = al_get_time(); + event.mouse.display = display; + event.mouse.x = x; + event.mouse.y = y; + event.mouse.z = z; + event.mouse.w = w; + event.mouse.dx = dx; + event.mouse.dy = dy; + event.mouse.dz = dz; + event.mouse.dw = dw; + event.mouse.button = button; + event.mouse.pressure = pressure; + _al_event_source_emit_event(&the_mouse.parent.es, &event); +} + + + +/* _al_xwin_mouse_switch_handler: + * Handle a focus switch event. + */ +void _al_xwin_mouse_switch_handler(ALLEGRO_DISPLAY *display, + const XCrossingEvent *event) +{ + int event_type; + + /* Ignore events where any of the buttons are held down. */ + if (event->state & (Button1Mask | Button2Mask | Button3Mask | + Button4Mask | Button5Mask)) { + return; + } + + _al_event_source_lock(&the_mouse.parent.es); + + switch (event->type) { + case EnterNotify: + the_mouse.state.display = display; + the_mouse.state.x = event->x; + the_mouse.state.y = event->y; + event_type = ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY; + break; + case LeaveNotify: + the_mouse.state.display = NULL; + the_mouse.state.x = event->x; + the_mouse.state.y = event->y; + event_type = ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY; + break; + default: + ASSERT(false); + event_type = 0; + break; + } + + generate_mouse_event( + event_type, + the_mouse.state.x, the_mouse.state.y, the_mouse.state.z, the_mouse.state.pressure, + the_mouse.state.w, + 0, 0, 0, 0, + 0, display); + + _al_event_source_unlock(&the_mouse.parent.es); +} + +bool _al_xwin_grab_mouse(ALLEGRO_DISPLAY *display) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + int grab; + bool ret; + + _al_mutex_lock(&system->lock); + grab = XGrabPointer(system->x11display, glx->window, False, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, glx->window, None, CurrentTime); + if (grab == GrabSuccess) { + system->mouse_grab_display = display; + ret = true; + } + else { + ret = false; + } + _al_mutex_unlock(&system->lock); + return ret; +} + +bool _al_xwin_ungrab_mouse(void) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + _al_mutex_lock(&system->lock); + XUngrabPointer(system->x11display, CurrentTime); + system->mouse_grab_display = NULL; + _al_mutex_unlock(&system->lock); + return true; +} + + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/xrandr.c b/allegro/src/x/xrandr.c new file mode 100644 index 00000000..36f38578 --- /dev/null +++ b/allegro/src/x/xrandr.c @@ -0,0 +1,906 @@ +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xfullscreen.h" +#include "allegro5/internal/aintern_xsystem.h" + +#ifdef ALLEGRO_XWINDOWS_WITH_XRANDR + +ALLEGRO_DEBUG_CHANNEL("xrandr") + +typedef struct xrandr_screen xrandr_screen; +typedef struct xrandr_crtc xrandr_crtc; +typedef struct xrandr_output xrandr_output; +typedef struct xrandr_mode xrandr_mode; + +struct xrandr_screen { + int id; + Time timestamp; + Time configTimestamp; + _AL_VECTOR crtcs; // xrandr_crtc + _AL_VECTOR outputs; // xrandr_output + _AL_VECTOR modes; // xrandr_mode + + XRRScreenResources *res; +}; + +enum xrandr_crtc_position { + CRTC_POS_NONE = 0, + CRTC_POS_ABOVE, + CRTC_POS_LEFTOF, + CRTC_POS_BELOW, + CRTC_POS_RIGHTOF +}; + +struct xrandr_crtc { + RRCrtc id; + Time timestamp; + int x, y; + unsigned int width, height; + RRMode mode; + Rotation rotation; + _AL_VECTOR connected; + _AL_VECTOR possible; + + RRMode original_mode; + int original_xoff; + int original_yoff; + RRCrtc align_to; + int align; +}; + +struct xrandr_output { + RROutput id; + Time timestamp; + RRCrtc crtc; + char *name; + int namelen; + unsigned long mm_width; + unsigned long mm_height; + Connection connection; + SubpixelOrder subpixel_order; + _AL_VECTOR crtcs; // RRCrtc + _AL_VECTOR clones; // RROutput + RRMode prefered_mode; + _AL_VECTOR modes; // RRMode +}; + +struct xrandr_mode { + RRMode id; + unsigned int width; + unsigned int height; + unsigned int refresh; +}; + +struct xrandr_rect { + int x1; + int y1; + int x2; + int y2; +}; + +static void xrandr_copy_mode(xrandr_mode *mode, XRRModeInfo *rrmode) +{ + mode->id = rrmode->id; + mode->width = rrmode->width; + mode->height = rrmode->height; + + if (rrmode->hTotal && rrmode->vTotal) { + mode->refresh = ((float) rrmode->dotClock / ((float) rrmode->hTotal * (float) rrmode->vTotal)); + } + else { + mode->refresh = 0; + } +} + +static void xrandr_clear_fake_refresh_rates(xrandr_mode *modes, int nmode) +{ + int i; + + if (nmode < 2) + return; + + /* The Nvidia proprietary driver may return fake refresh rates when + * DynamicTwinView is enabled, so that all modes are unique. The user has + * no use for that wrong information so zero it out if we detect it. + */ + + for (i = 1; i < nmode; i++) { + if (modes[i].refresh != modes[i-1].refresh + 1) { + return; + } + } + + ALLEGRO_WARN("Zeroing out fake refresh rates from nvidia proprietary driver.\n"); + ALLEGRO_WARN("Disable the DynamicTwinView driver option to avoid this.\n"); + + for (i = 0; i < nmode; i++) { + modes[i].refresh = 0; + } +} + +static void xrandr_copy_output(xrandr_output *output, RROutput id, XRROutputInfo *rroutput) +{ + output->id = id; + output->timestamp = rroutput->timestamp; + output->crtc = rroutput->crtc; + output->name = strdup(rroutput->name); + output->namelen = rroutput->nameLen; + output->mm_width = rroutput->mm_width; + output->mm_height = rroutput->mm_height; + output->connection = rroutput->connection; + output->subpixel_order = rroutput->subpixel_order; + + ALLEGRO_DEBUG("output[%s] %s on crtc %i.\n", output->name, output->connection == RR_Connected ? "Connected" : "Not Connected", (int)output->crtc); + + _al_vector_init(&output->crtcs, sizeof(RRCrtc)); + if(rroutput->ncrtc) { + _al_vector_append_array(&output->crtcs, rroutput->ncrtc, rroutput->crtcs); + } + + _al_vector_init(&output->clones, sizeof(RROutput)); + if(rroutput->nclone) { + _al_vector_append_array(&output->clones, rroutput->nclone, rroutput->clones); + } + + _al_vector_init(&output->modes, sizeof(RRMode)); + if(rroutput->nmode) { + _al_vector_append_array(&output->modes, rroutput->nmode, rroutput->modes); + } + + /* npreferred isn't the prefered mode index, it's the number of prefered modes + * starting from 0. So just load up the first prefered mode. + * We don't actually use it yet anyway, so it's not really important. + */ + if(rroutput->npreferred) { + output->prefered_mode = rroutput->modes[0]; + } +} + +static void xrandr_copy_crtc(xrandr_crtc *crtc, RRCrtc id, XRRCrtcInfo *rrcrtc) +{ + crtc->id = id; + crtc->timestamp = rrcrtc->timestamp; + crtc->x = rrcrtc->x; + crtc->y = rrcrtc->y; + crtc->width = rrcrtc->width; + crtc->height = rrcrtc->height; + crtc->mode = rrcrtc->mode; + crtc->rotation = rrcrtc->rotation; + + _al_vector_init(&crtc->connected, sizeof(RROutput)); + if(rrcrtc->noutput) { + _al_vector_append_array(&crtc->connected, rrcrtc->noutput, rrcrtc->outputs); + } + + ALLEGRO_DEBUG("found %i outputs.\n", rrcrtc->noutput); + + _al_vector_init(&crtc->possible, sizeof(RROutput)); + if(rrcrtc->npossible) { + _al_vector_append_array(&crtc->possible, rrcrtc->npossible, rrcrtc->possible); + + int i; + for(i = 0; i < rrcrtc->npossible; i++) { + ALLEGRO_DEBUG("output[%i] %i.\n", i, (int)rrcrtc->possible[i]); + } + } + + crtc->original_mode = crtc->mode; + crtc->original_xoff = crtc->x; + crtc->original_yoff = crtc->y; + crtc->align_to = 0; + crtc->align = CRTC_POS_NONE; +} + +static void xrandr_copy_screen(ALLEGRO_SYSTEM_XGLX *s, xrandr_screen *screen, XRRScreenResources *res) +{ + int j; + + _al_vector_init(&screen->modes, sizeof(xrandr_mode)); + if(res->nmode) { + for(j = 0; j < res->nmode; j++) { + xrandr_mode *mode = _al_vector_alloc_back(&screen->modes); + xrandr_copy_mode(mode, &res->modes[j]); + } + + xrandr_clear_fake_refresh_rates(_al_vector_ref_front(&screen->modes), res->nmode); + } + + _al_vector_init(&screen->crtcs, sizeof(xrandr_crtc)); + if(res->ncrtc) { + ALLEGRO_DEBUG("found %i crtcs.\n", res->ncrtc); + for(j = 0; j < res->ncrtc; j++) { + ALLEGRO_DEBUG("crtc[%i] %i.\n", j, (int)res->crtcs[j]); + xrandr_crtc *crtc = _al_vector_alloc_back(&screen->crtcs); + XRRCrtcInfo *rrcrtc = XRRGetCrtcInfo(s->x11display, res, res->crtcs[j]); + + xrandr_copy_crtc(crtc, res->crtcs[j], rrcrtc); + + XRRFreeCrtcInfo(rrcrtc); + } + } + + _al_vector_init(&screen->outputs, sizeof(xrandr_output)); + if(res->noutput) { + ALLEGRO_DEBUG("found %i outputs.\n", res->noutput); + for(j = 0; j < res->noutput; j++) { + ALLEGRO_DEBUG("output[%i] %i.\n", j, (int)res->outputs[j]); + xrandr_output *output = _al_vector_alloc_back(&screen->outputs); + XRROutputInfo *rroutput = XRRGetOutputInfo(s->x11display, res, res->outputs[j]); + + xrandr_copy_output(output, res->outputs[j], rroutput); + + XRRFreeOutputInfo(rroutput); + XSync(s->x11display, False); + } + } +} + +static xrandr_crtc *xrandr_fetch_crtc(ALLEGRO_SYSTEM_XGLX *s, int sid, RRCrtc id) +{ + unsigned int i; + + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, sid); + + for(i = 0; i < _al_vector_size(&screen->crtcs); i++) { + xrandr_crtc *crtc = _al_vector_ref(&screen->crtcs, i); + if(crtc->id == id) + return crtc; + } + + return NULL; +} + +static xrandr_output *xrandr_fetch_output(ALLEGRO_SYSTEM_XGLX *s, int sid, RROutput id) +{ + unsigned int i; + + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, sid); + + for(i = 0; i < _al_vector_size(&screen->outputs); i++) { + xrandr_output *output = _al_vector_ref(&screen->outputs, i); + if(output->id == id) + return output; + } + + return NULL; +} + +static xrandr_mode *xrandr_fetch_mode(ALLEGRO_SYSTEM_XGLX *s, int sid, RRMode id) +{ + unsigned int i; + + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, sid); + + for(i = 0; i < _al_vector_size(&screen->modes); i++) { + xrandr_mode *mode = _al_vector_ref(&screen->modes, i); + if(mode->id == id) + return mode; + } + + return NULL; +} + +static inline xrandr_crtc *xrandr_map_to_crtc(ALLEGRO_SYSTEM_XGLX *s, int sid, int adapter) +{ + return xrandr_fetch_crtc(s, sid, *(RRCrtc*)_al_vector_ref(&s->xrandr_adaptermap, adapter)); +} + +static inline xrandr_output *xrandr_map_adapter(ALLEGRO_SYSTEM_XGLX *s, int sid, int adapter) +{ + xrandr_crtc *crtc = xrandr_map_to_crtc(s, sid, adapter); + return xrandr_fetch_output(s, sid, *(RROutput*)_al_vector_ref(&crtc->connected, 0)); +} + +static void xrandr_combine_output_rect(struct xrandr_rect *rect, xrandr_crtc *crtc) +{ + if(rect->x1 > crtc->x) + rect->x1 = crtc->x; + + if(rect->y1 > crtc->y) + rect->y1 = crtc->y; + + if(crtc->x + (int)crtc->width > rect->x2) + rect->x2 = crtc->x + crtc->width; + + if(crtc->y + (int)crtc->height > rect->y2) + rect->y2 = crtc->y + crtc->height; +} + +/* begin vtable methods */ + +static int xrandr_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter); + +static bool xrandr_query(ALLEGRO_SYSTEM_XGLX *s) +{ + int screen_count = ScreenCount(s->x11display); + int i; + bool ret = true; + + _al_vector_init(&s->xrandr_screens, sizeof(xrandr_screen)); + _al_vector_init(&s->xrandr_adaptermap, sizeof(RROutput)); + + for(i = 0; i < screen_count; i++) { + xrandr_screen *screen = _al_vector_alloc_back(&s->xrandr_screens); + + XRRScreenResources *res = XRRGetScreenResources(s->x11display, XRootWindow(s->x11display, i)); + if(!res) { + ALLEGRO_DEBUG("failed to get screen resources for screen %i\n", i); + continue; + } + + if(!res->noutput) { + ALLEGRO_DEBUG("screen %i doesn't have any outputs.\n", i); + continue; + } + + xrandr_copy_screen(s, screen, res); + + screen->res = res; + + /* Detect clones */ + int j; + for(j = 0; j < (int)_al_vector_size(&screen->crtcs); j++) { + xrandr_crtc *crtc = _al_vector_ref(&screen->crtcs, j); + + /* Skip crtc with no connected outputs. */ + if(_al_vector_size(&crtc->connected) < 1) + continue; + + // XXX it might be nessesary to do something more clever about detecting clones + // XXX for now I'm going with a plain origin test, it aught to work for most cases. + // the other alternative is to check the crtc's connected outputs's clone's list... + // sounds like pain to me. + int k; + bool not_clone = true; + for(k = 0; k < j; k++) { + xrandr_crtc *crtc_k = _al_vector_ref(&screen->crtcs, k); + + /* Skip crtc with no connected outputs. */ + if(_al_vector_size(&crtc_k->connected) < 1) + continue; + + if(crtc->x == crtc_k->x && crtc->y == crtc_k->y) + not_clone = false; + } + + if(not_clone) { + RRCrtc *crtc_ptr = _al_vector_alloc_back(&s->xrandr_adaptermap); + ALLEGRO_DEBUG("Map Allegro Adadpter %i to RandR CRTC %i.\n", (int)(_al_vector_size(&s->xrandr_adaptermap)-1), (int)crtc->id); + *crtc_ptr = crtc->id; + } + else { + ALLEGRO_DEBUG("RandR CRTC %i is a clone, ignoring.\n", (int)crtc->id); + } + } + + int mask = RRScreenChangeNotifyMask | + RRCrtcChangeNotifyMask | + RROutputChangeNotifyMask | + RROutputPropertyNotifyMask; + + XRRSelectInput( s->x11display, RootWindow(s->x11display, i), 0); + XRRSelectInput( s->x11display, RootWindow(s->x11display, i), mask); + } + + /* map out crtc positions and alignments */ + /* this code makes Adapter 0 the root display, everything will hang off it */ + for(i = 1; i < (int)_al_vector_size(&s->xrandr_adaptermap); i++) { + int xscreen = xrandr_get_xscreen(s, i); + xrandr_crtc *crtc = xrandr_fetch_crtc(s, xscreen, *(RRCrtc*)_al_vector_ref(&s->xrandr_adaptermap, i)); + + int j; + for(j = 0; j < (int)_al_vector_size(&s->xrandr_adaptermap); j++) { + int xscreen_j = xrandr_get_xscreen(s, j); + xrandr_crtc *crtc_j = xrandr_fetch_crtc(s, xscreen_j, *(RRCrtc*)_al_vector_ref(&s->xrandr_adaptermap, j)); + + if(crtc->x == crtc_j->x + (int)crtc_j->width) { + crtc->align_to = crtc_j->id; + crtc->align = CRTC_POS_RIGHTOF; + ALLEGRO_DEBUG("Adapter %i is RightOf Adapter %i.\n", i, j); + } + else if(crtc->x + (int)crtc->width == crtc_j->x) { + crtc->align_to = crtc_j->id; + crtc->align = CRTC_POS_LEFTOF; + ALLEGRO_DEBUG("Adapter %i is LeftOf Adapter %i.\n", i, j); + } + else if(crtc->y == crtc_j->y + (int)crtc_j->height) { + crtc->align_to = crtc_j->id; + crtc->align = CRTC_POS_BELOW; + ALLEGRO_DEBUG("Adapter %i is Below Adapter %i.\n", i, j); + } + else if(crtc->y + (int)crtc->height == crtc_j->y) { + crtc->align_to = crtc_j->id; + crtc->align = CRTC_POS_ABOVE; + ALLEGRO_DEBUG("Adapter %i is Above Adapter %i.\n", i, j); + } + } + } + +#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA + if (s->xinerama_available && s->xinerama_screen_count != (int)_al_vector_size(&s->xrandr_adaptermap)) { + ALLEGRO_WARN("XRandR and Xinerama seem to disagree on how many screens there are (%i vs %i), going to ignore XRandR.\n", (int)_al_vector_size(&s->xrandr_adaptermap), s->xinerama_screen_count); + // only actually going to ignore the output count, and setting of modes on the extra xinerama screens. + ret = false; + } +#endif + + return ret; +} + +static int xrandr_get_num_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + if(adapter < 0 || adapter >= (int)_al_vector_size(&s->xrandr_adaptermap)) + return 0; + + int xscreen = _al_xglx_get_xscreen(s, adapter); + xrandr_output *output = xrandr_map_adapter(s, xscreen, adapter); + return _al_vector_size(&output->modes); +} + +static ALLEGRO_DISPLAY_MODE *xrandr_get_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int id, ALLEGRO_DISPLAY_MODE *amode) +{ + int xscreen = _al_xglx_get_xscreen(s, adapter); + xrandr_output *output = xrandr_map_adapter(s, xscreen, adapter); + + if(id < 0 || id > (int)_al_vector_size(&output->modes)) + return NULL; + + xrandr_mode *mode = xrandr_fetch_mode(s, xscreen, *(RRMode*)_al_vector_ref(&output->modes, id)); + + amode->width = mode->width; + amode->height = mode->height; + amode->format = 0; + amode->refresh_rate = mode->refresh; + + return amode; +} + +static bool xrandr_realign_crtc_origin(ALLEGRO_SYSTEM_XGLX *s, int xscreen, xrandr_crtc *crtc, int new_w, int new_h, int *x, int *y) +{ + bool ret; + + if(crtc->align_to == 0) + return false; + + xrandr_crtc *align_to = xrandr_fetch_crtc(s, xscreen, crtc->align_to); + + switch(crtc->align) { + case CRTC_POS_RIGHTOF: + *x = align_to->x + align_to->width; + *y = align_to->y; + ret = true; + break; + + case CRTC_POS_LEFTOF: + *x = align_to->x - new_w; + *y = align_to->y; + ret = true; + break; + + case CRTC_POS_BELOW: + *x = align_to->x; + *y = align_to->y + align_to->height; + ret = true; + break; + + case CRTC_POS_ABOVE: + *x = align_to->x; + *y = align_to->y - new_h; + ret = true; + break; + + default: + ALLEGRO_WARN("unknown crtc alignment flag (%i)!", crtc->align); + ret = false; + break; + } + + return ret; +} + +static bool xrandr_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w, int h, int format, int refresh) +{ + int adapter = _al_xglx_get_adapter(s, d, false); + int xscreen = _al_xglx_get_xscreen(s, adapter); + + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, xscreen); + + xrandr_crtc *crtc = xrandr_map_to_crtc(s, xscreen, adapter); + xrandr_mode *cur_mode = xrandr_fetch_mode(s, xscreen, crtc->mode); + + if((int)cur_mode->width == w && (int)cur_mode->height == h && (refresh == 0 || refresh == (int)cur_mode->refresh)) { + ALLEGRO_DEBUG("mode already set, good to go\n"); + return true; + } + else { + ALLEGRO_DEBUG("new mode: %dx%d@%d old mode: %dx%d@%d.\n", w, h, refresh, cur_mode->width, cur_mode->height, cur_mode->refresh); + } + + int mode_idx = _al_xglx_fullscreen_select_mode(s, adapter, w, h, format, refresh); + if(mode_idx == -1) { + ALLEGRO_DEBUG("mode %dx%d@%d not found\n", w, h, refresh); + return false; + } + + xrandr_output *output = xrandr_fetch_output(s, xscreen, *(RROutput*)_al_vector_ref(&crtc->connected, 0)); + xrandr_mode *mode = xrandr_fetch_mode(s, xscreen, *(RRMode*)_al_vector_ref(&output->modes, mode_idx)); + + int new_x = crtc->x, new_y = crtc->y; + + xrandr_realign_crtc_origin(s, xscreen, crtc, w, h, &new_x, &new_y); + + ALLEGRO_DEBUG("xrandr: set mode %i+%i-%ix%i on adapter %i\n", new_x, new_y, w, h, adapter); + + _al_mutex_lock(&s->lock); + + int ok = XRRSetCrtcConfig( + s->x11display, + screen->res, + crtc->id, + crtc->timestamp, + new_x, + new_y, + mode->id, + crtc->rotation, + _al_vector_ref_front(&crtc->connected), + _al_vector_size(&crtc->connected) + ); + + if (ok != RRSetConfigSuccess) { + ALLEGRO_ERROR("XRandR failed to set mode.\n"); + _al_mutex_unlock(&s->lock); + return false; + } + + /* make sure the virtual screen size is large enough after setting our mode */ + int i; + struct xrandr_rect rect = { 0, 0, 0, 0 }; + for(i = 0; i < (int)_al_vector_size(&screen->crtcs); i++) { + xrandr_crtc *c = _al_vector_ref(&screen->crtcs, i); + if(_al_vector_size(&c->connected) > 0) { + xrandr_combine_output_rect(&rect, crtc); + } + } + + int new_width = rect.x2 - rect.x1; + int new_height = rect.y2 - rect.y1; + + if(new_width > DisplayWidth(s->x11display, xscreen) || + new_height > DisplayHeight(s->x11display, xscreen)) + { + XRRSetScreenSize(s->x11display, + RootWindow(s->x11display, xscreen), + new_width, new_height, + DisplayWidthMM(s->x11display, xscreen), + DisplayHeightMM(s->x11display, xscreen)); + } + + _al_mutex_unlock(&s->lock); + + return true; +} + +static void xrandr_restore_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + int xscreen = _al_xglx_get_xscreen(s, adapter); + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, xscreen); + xrandr_crtc *crtc = xrandr_map_to_crtc(s, xscreen, adapter); + + if(crtc->mode == crtc->original_mode) { + ALLEGRO_DEBUG("current crtc mode (%i) equals the original mode (%i), not restoring.\n", (int)crtc->mode, (int)crtc->original_mode); + return; + } + + xrandr_mode *orig_mode = xrandr_fetch_mode(s, xscreen, crtc->original_mode); + + ALLEGRO_DEBUG("restore mode %i+%i-%ix%i@%i on adapter %i\n", crtc->original_xoff, crtc->original_yoff, orig_mode->width, orig_mode->height, orig_mode->refresh, adapter); + + _al_mutex_lock(&s->lock); + + int ok = XRRSetCrtcConfig + ( + s->x11display, + screen->res, + crtc->id, + crtc->timestamp, + crtc->original_xoff, + crtc->original_yoff, + orig_mode->id, + crtc->rotation, + _al_vector_ref_front(&crtc->connected), + _al_vector_size(&crtc->connected) + ); + + if(ok != RRSetConfigSuccess) { + ALLEGRO_ERROR("failed to restore mode.\n"); + } + + // XSync(s->x11display, False); + + _al_mutex_unlock(&s->lock); +} + +static void xrandr_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y) +{ + int xscreen = _al_xglx_get_xscreen(s, adapter); + + xrandr_crtc *crtc = xrandr_map_to_crtc(s, xscreen, adapter); + + // XXX Should we always return original_[xy]off here? + // When does a user want to query the offset after the modes are set? + + *x = crtc->x; + *y = crtc->y; + + ALLEGRO_DEBUG("display offset: %ix%i.\n", *x, *y); +} + +static int xrandr_get_num_adapters(ALLEGRO_SYSTEM_XGLX *s) +{ + return _al_vector_size(&s->xrandr_adaptermap); +} + +static bool xrandr_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *mi) +{ + if(adapter < 0 || adapter >= (int)_al_vector_size(&s->xrandr_adaptermap)) + return false; + + int xscreen = _al_xglx_get_xscreen(s, adapter); + xrandr_output *output = xrandr_map_adapter(s, xscreen, adapter); + + xrandr_crtc *crtc = xrandr_fetch_crtc(s, xscreen, output->crtc); + + mi->x1 = crtc->x; + mi->y1 = crtc->y; + mi->x2 = crtc->x + crtc->width; + mi->y2 = crtc->y + crtc->height; + return true; +} + +static int xrandr_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s) +{ + // if we have more than one xrandr_screen, we're in multi-head x mode + if(_al_vector_size(&s->xrandr_screens) > 1) + return _al_xsys_mheadx_get_default_adapter(s); + + int center_x = 0, center_y = 0; + _al_xsys_get_active_window_center(s, ¢er_x, ¢er_y); + + int i, default_adapter = 0; + for(i = 0; i < (int)_al_vector_size(&s->xrandr_adaptermap); i++) { + xrandr_crtc *crtc = xrandr_map_to_crtc(s, 0, i); + + if(center_x >= (int)crtc->x && center_x <= (int)(crtc->x + crtc->width) && + center_y >= (int)crtc->y && center_y <= (int)(crtc->y + crtc->height)) + { + default_adapter = i; + break; + } + } + + ALLEGRO_DEBUG("selected default adapter: %i.\n", default_adapter); + + return default_adapter; +} + +static int xrandr_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter) +{ + // more than one screen means we have multi-head x mode + if(_al_vector_size(&s->xrandr_screens) > 1) + return _al_xsys_mheadx_get_xscreen(s, adapter); + + // Normal XRandR will normally give us one X screen, so return 0 always. + return 0; +} + +static void xrandr_handle_xevent(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, XEvent *e) +{ + if(e->type == s->xrandr_event_base + RRNotify) { + XRRNotifyEvent *rre = (XRRNotifyEvent*)e; + if(rre->subtype == RRNotify_CrtcChange) { + XRRCrtcChangeNotifyEvent *rrce = (XRRCrtcChangeNotifyEvent*)rre; + ALLEGRO_DEBUG("RRNotify_CrtcChange!\n"); + + xrandr_crtc *crtc = xrandr_fetch_crtc(s, d->xscreen, rrce->crtc); + if(!crtc) { + ALLEGRO_DEBUG("invalid RRCrtc(%i).\n", (int)rrce->crtc); + return; + } + + if(rrce->mode != crtc->mode) { + ALLEGRO_DEBUG("mode changed from %i to %i.\n", (int)crtc->mode, (int)rrce->mode); + crtc->mode = rrce->mode; + } + + if(rrce->rotation != crtc->rotation) { + ALLEGRO_DEBUG("rotation changed from %i to %i.\n", crtc->rotation, rrce->rotation); + crtc->rotation = rrce->rotation; + } + + if(rrce->x != crtc->x || rrce->y != crtc->y) { + ALLEGRO_DEBUG("origin changed from %i+%i to %i+%i.\n", crtc->x, crtc->y, rrce->x, rrce->y); + crtc->x = rrce->x; + crtc->y = rrce->y; + } + + if(rrce->width != crtc->width || rrce->height != crtc->height) { + ALLEGRO_DEBUG("size changed from %ix%i to %ix%i.\n", crtc->width, crtc->height, rrce->width, rrce->height); + crtc->width = rrce->width; + crtc->height = rrce->height; + } + + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, d->xscreen); + crtc->timestamp = screen->timestamp; + } + else if(rre->subtype == RRNotify_OutputChange) { + XRROutputChangeNotifyEvent *rroe = (XRROutputChangeNotifyEvent*)rre; + + xrandr_output *output = xrandr_fetch_output(s, d->xscreen, rroe->output); + if(!output) { + ALLEGRO_DEBUG("invalid RROutput(%i).\n", (int)rroe->output); + return; + } + + ALLEGRO_DEBUG("xrandr: RRNotify_OutputChange %s!\n", output->name); + + if(rroe->crtc != output->crtc) { + ALLEGRO_DEBUG("crtc changed from %i to %i.\n", (int)output->crtc, (int)rroe->crtc); + output->crtc = rroe->crtc; + } + + // XXX I'm not sure how monitor connections are handled here, + // that is, what happens when a monitor is connected, and disconnected... + // IE: CHECK! + if(rroe->connection != output->connection) { + ALLEGRO_DEBUG("connection changed from %i to %i.\n", output->connection, rroe->connection); + output->connection = rroe->connection; + } + + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, d->xscreen); + output->timestamp = screen->timestamp; + } + else if(rre->subtype == RRNotify_OutputProperty) { + ALLEGRO_DEBUG("xrandr: RRNotify_OutputProperty!\n"); + } + else { + ALLEGRO_DEBUG("xrandr: RRNotify_Unknown(%i)!\n", rre->subtype); + } + } + else if(e->type == s->xrandr_event_base + RRScreenChangeNotify) { + XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*)e; + XRRUpdateConfiguration( e ); + + ALLEGRO_DEBUG("RRScreenChangeNotify!\n"); + + /* XXX I don't think we need to actually handle this event fully, + * it only really deals with the virtual screen as a whole it seems + * The interesting changes get sent with the RRNotify event. + */ + + /* update the timestamps */ + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, d->xscreen); + screen->timestamp = rre->timestamp; + screen->configTimestamp = rre->config_timestamp; + } +} + +/* begin "public" ctor/dtor methods */ + +void _al_xsys_xrandr_init(ALLEGRO_SYSTEM_XGLX *s) +{ + int error_base = 0; + + _al_mutex_lock(&s->lock); + + if (XRRQueryExtension(s->x11display, &s->xrandr_event_base, &error_base)) { + int minor_version = 0, major_version = 0; + int status = XRRQueryVersion(s->x11display, &major_version, &minor_version); + ALLEGRO_INFO("XRandR version: %i.%i\n", major_version, minor_version); + + if (!status) { + ALLEGRO_WARN("XRandR not available, XRRQueryVersion failed.\n"); + } + else if (major_version == 1 && minor_version < 2) { + /* this is unlikely to happen, unless the user has an ancient Xorg, + Xorg will just emulate the latest version and return that + instead of what the driver actually supports, stupid. */ + ALLEGRO_WARN("XRandR not available, unsupported version: %i.%i\n", major_version, minor_version); + } + else { + bool ret = xrandr_query(s); + if (ret) { + ALLEGRO_INFO("XRandR is active\n"); + s->xrandr_available = 1; + } + else { + ALLEGRO_INFO("XRandR is not active\n"); + } + } + } + else { + ALLEGRO_WARN("XRandR extension is not available.\n"); + } + + if (s->xrandr_available) { + memset(&_al_xglx_mmon_interface, 0, sizeof(_al_xglx_mmon_interface)); + _al_xglx_mmon_interface.get_num_display_modes = xrandr_get_num_modes; + _al_xglx_mmon_interface.get_display_mode = xrandr_get_mode; + _al_xglx_mmon_interface.set_mode = xrandr_set_mode; + _al_xglx_mmon_interface.restore_mode = xrandr_restore_mode; + _al_xglx_mmon_interface.get_display_offset = xrandr_get_display_offset; + _al_xglx_mmon_interface.get_num_adapters = xrandr_get_num_adapters; + _al_xglx_mmon_interface.get_monitor_info = xrandr_get_monitor_info; + _al_xglx_mmon_interface.get_default_adapter = xrandr_get_default_adapter; + _al_xglx_mmon_interface.get_xscreen = xrandr_get_xscreen; + _al_xglx_mmon_interface.handle_xevent = xrandr_handle_xevent; + } + + _al_mutex_unlock(&s->lock); +} + +void _al_xsys_xrandr_exit(ALLEGRO_SYSTEM_XGLX *s) +{ +#if 0 + // int i; + ALLEGRO_DEBUG("XRandR exiting.\n"); + + // for (i = 0; i < s->xrandr_output_count; i++) { + // XRRFreeOutputInfo(s->xrandr_outputs[i]); + // } + + // for (i = 0; i < s->xrandr_res_count; i++) { + // XRRFreeScreenResources(s->xrandr_res[i]); + // } + + ALLEGRO_DEBUG("XRRFreeScreenResources\n"); + //if (s->xrandr_res) + // XRRFreeScreenResources(s->xrandr_res); + + al_free(s->xrandr_outputs); + al_free(s->xrandr_res); + + s->xrandr_available = 0; + s->xrandr_res_count = 0; + s->xrandr_res = NULL; + s->xrandr_output_count = 0; + s->xrandr_outputs = NULL; + + ALLEGRO_DEBUG("XRandR exit finished.\n"); +#endif /* 0 */ + + int i; + for(i = 0; i < (int)_al_vector_size(&s->xrandr_screens); i++) { + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, i); + int j; + + for (j = 0; j < (int)_al_vector_size(&screen->crtcs); j++) { + xrandr_crtc *crtc = _al_vector_ref(&screen->crtcs, j); + _al_vector_free(&crtc->connected); + _al_vector_free(&crtc->possible); + } + + for(j = 0; j < (int)_al_vector_size(&screen->outputs); j++) { + xrandr_output *output = _al_vector_ref(&screen->outputs, j); + free(output->name); + _al_vector_free(&output->crtcs); + _al_vector_free(&output->clones); + _al_vector_free(&output->modes); + } + + _al_vector_free(&screen->crtcs); + _al_vector_free(&screen->outputs); + _al_vector_free(&screen->modes); + + XRRFreeScreenResources(screen->res); + screen->res = NULL; + } + + _al_vector_free(&s->xrandr_screens); + _al_vector_free(&s->xrandr_adaptermap); + +} + +#endif /* ALLEGRO_XWINDOWS_WITH_XRANDR */ + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/xsystem.c b/allegro/src/x/xsystem.c new file mode 100644 index 00000000..5767cc30 --- /dev/null +++ b/allegro/src/x/xsystem.c @@ -0,0 +1,468 @@ +#ifdef DEBUG_X11 +extern int _Xdebug; /* part of Xlib */ +#endif + +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xcursor.h" +#include "allegro5/internal/aintern_xembed.h" +#include "allegro5/internal/aintern_xevents.h" +#include "allegro5/internal/aintern_xfullscreen.h" +#include "allegro5/internal/aintern_xkeyboard.h" +#include "allegro5/internal/aintern_xmouse.h" +#include "allegro5/internal/aintern_xsystem.h" +#include "allegro5/platform/aintunix.h" +#include "allegro5/platform/aintxglx.h" + +#include "allegro5/allegro_x.h" + +#include "xicon.h" + +ALLEGRO_DEBUG_CHANNEL("system") + +static ALLEGRO_SYSTEM_INTERFACE *xglx_vt; + +char **x11_xpm = NULL; + +static bool xglx_inhibit_screensaver(bool inhibit); + +#ifdef ALLEGRO_XWINDOWS_WITH_XPM +#include +#include "icon.xpm" + +static bool x11_xpm_set; +static int x11_xpm_rows; + +static char **bitmap_to_xpm(ALLEGRO_BITMAP *bitmap, int *nrows_ret) +{ + _AL_VECTOR v; + int w, h, x, y; + int ncolors, nrows; + char **xpm; + char buf[100]; + int i; + + ALLEGRO_LOCKED_REGION *lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READONLY); + if (lr == NULL) + return NULL; + + _al_vector_init(&v, sizeof(uint32_t)); + + w = al_get_bitmap_width(bitmap); + h = al_get_bitmap_height(bitmap); + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + uint32_t c = *(uint32_t *)((((char *)lr->data) + lr->pitch * y + x * 4)); + int alpha = (c >> 24) & 0xff; + if (alpha != 255) { + c = 0; + } + int sz = _al_vector_size(&v); + bool found = false; + for (i = 0; i < sz; i++) { + if (*((uint32_t *)_al_vector_ref(&v, i)) == c) { + found = true; + break; + } + } + if (found == false) { + uint32_t *p = _al_vector_alloc_back(&v); + *p = c; + } + } + } + + ncolors = _al_vector_size(&v); + nrows = 2 + ncolors + h; + + xpm = malloc(nrows * sizeof(char *)); + if (xpm == NULL) + return NULL; + + snprintf(buf, 100, "%d %d %d 8", w, h, ncolors + 1); + + xpm[0] = strdup(buf); + + xpm[1] = strdup("00000000\tc None"); + + for (i = 0; i < ncolors; i++) { + uint32_t c = *((uint32_t *)_al_vector_ref(&v, i)); + int r = c & 0xff; + int g = (c >> 8) & 0xff; + int b = (c >> 16) & 0xff; + snprintf(buf, 100, "%08x\tc #%02x%02x%02x", i+1, r, g, b); + xpm[i+2] = strdup(buf); + } + + for (y = 0; y < h; y++) { + int row = y + 2 + ncolors; + xpm[row] = malloc(8 * w + 1); + xpm[row][8 * w] = 0; + uint32_t *p = (uint32_t *)(((char *)lr->data) + lr->pitch * y); + for (x = 0; x < w; x++) { + uint32_t pixel = *p; + int alpha = (pixel >> 24) & 0xff; + if (alpha != 255) { + snprintf(buf, 100, "%s", "00000000"); + } + else { + for (i = 0; i < (int)_al_vector_size(&v); i++) { + uint32_t pixel2 = *((uint32_t *)_al_vector_ref(&v, i)); + if (pixel == pixel2) + break; + } + snprintf(buf, 100, "%08x", i+1); + } + for (i = 0; i < 8; i++) { + xpm[row][8*x+i] = buf[i]; + } + p++; + } + } + + _al_vector_free(&v); + + *nrows_ret = nrows; + + al_unlock_bitmap(bitmap); + + // debug + /* + for (i = 0; i < nrows; i++) { + printf("%s\n", xpm[i]); + } + */ + + return xpm; +} +#endif + +/* Function: al_x_set_initial_icon + */ +bool al_x_set_initial_icon(ALLEGRO_BITMAP *bitmap) +{ +#ifdef ALLEGRO_XWINDOWS_WITH_XPM + if (x11_xpm_set) { + int i; + for (i = 0; i < x11_xpm_rows; i++) { + free(x11_xpm[i]); + } + free(x11_xpm); + x11_xpm_set = false; + } + x11_xpm = bitmap_to_xpm(bitmap, &x11_xpm_rows); + if (x11_xpm == NULL) + return false; + x11_xpm_set = true; + return true; +#else + (void)bitmap; + return false; +#endif +} + +static ALLEGRO_SYSTEM *xglx_initialize(int flags) +{ + Display *x11display; + Display *gfxdisplay; + ALLEGRO_SYSTEM_XGLX *s; + + (void)flags; + +#ifdef DEBUG_X11 + _Xdebug = 1; +#endif + + XInitThreads(); + + /* Get an X11 display handle. */ + x11display = XOpenDisplay(0); + if (x11display) { + /* Never ask. */ + gfxdisplay = XOpenDisplay(0); + if (!gfxdisplay) { + ALLEGRO_ERROR("XOpenDisplay failed second time.\n"); + XCloseDisplay(x11display); + return NULL; + } + } + else { + ALLEGRO_INFO("XOpenDisplay failed; assuming headless mode.\n"); + gfxdisplay = NULL; + } + + _al_unix_init_time(); + + s = al_calloc(1, sizeof *s); + + _al_mutex_init_recursive(&s->lock); + _al_cond_init(&s->resized); + s->inhibit_screensaver = false; + s->screen_saver_query_available = false; + + _al_vector_init(&s->system.displays, sizeof (ALLEGRO_DISPLAY_XGLX *)); + + s->system.vt = xglx_vt; + + s->gfxdisplay = gfxdisplay; + s->x11display = x11display; + + if (s->x11display) { + ALLEGRO_INFO("XGLX driver connected to X11 (%s %d).\n", + ServerVendor(s->x11display), VendorRelease(s->x11display)); + ALLEGRO_INFO("X11 protocol version %d.%d.\n", + ProtocolVersion(s->x11display), ProtocolRevision(s->x11display)); + + /* We need to put *some* atom into the ClientMessage we send for + * faking mouse movements with al_set_mouse_xy - so let's ask X11 + * for one here. + */ + s->AllegroAtom = XInternAtom(x11display, "AllegroAtom", False); + + /* Message type for XEmbed protocol. */ + s->XEmbedAtom = XInternAtom(x11display, "_XEMBED", False); + + _al_thread_create(&s->xevents_thread, _al_xwin_background_thread, s); + s->have_xevents_thread = true; + ALLEGRO_INFO("events thread spawned.\n"); + } + + const char *binding = al_get_config_value(al_get_system_config(), + "keyboard", "toggle_mouse_grab_key"); + if (binding) { + s->toggle_mouse_grab_keycode = _al_parse_key_binding(binding, + &s->toggle_mouse_grab_modifiers); + if (s->toggle_mouse_grab_keycode) { + ALLEGRO_DEBUG("Toggle mouse grab key: '%s'\n", binding); + } + else { + ALLEGRO_WARN("Cannot parse key binding '%s'\n", binding); + } + } + +#ifdef ALLEGRO_XWINDOWS_WITH_XPM + x11_xpm = icon_xpm; +#endif + + return &s->system; +} + +static void xglx_shutdown_system(void) +{ + ALLEGRO_SYSTEM *s = al_get_system_driver(); + ALLEGRO_SYSTEM_XGLX *sx = (void *)s; + + ALLEGRO_INFO("shutting down.\n"); + + if (sx->have_xevents_thread) { + _al_thread_join(&sx->xevents_thread); + sx->have_xevents_thread = false; + } + + /* Close all open displays. */ + while (_al_vector_size(&s->displays) > 0) { + ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); + ALLEGRO_DISPLAY *d = *dptr; + al_destroy_display(d); + } + _al_vector_free(&s->displays); + + if (sx->inhibit_screensaver) { + xglx_inhibit_screensaver(false); + } + + // Makes sure we wait for any commands sent to the X server when destroying the displays. + // Should make sure we don't shutdown before modes are restored. + if (sx->x11display) { + XSync(sx->x11display, False); + } + + _al_xsys_mmon_exit(sx); + + if (sx->x11display) { + XCloseDisplay(sx->x11display); + sx->x11display = None; + ALLEGRO_DEBUG("xsys: close x11display.\n"); + } + + if (sx->gfxdisplay) { + XCloseDisplay(sx->gfxdisplay); + sx->gfxdisplay = None; + } + + al_free(sx); +} + +static ALLEGRO_DISPLAY_INTERFACE *xglx_get_display_driver(void) +{ + return _al_display_xglx_driver(); +} + +static ALLEGRO_KEYBOARD_DRIVER *xglx_get_keyboard_driver(void) +{ + return _al_xwin_keyboard_driver(); +} + +static ALLEGRO_MOUSE_DRIVER *xglx_get_mouse_driver(void) +{ + return _al_xwin_mouse_driver(); +} + +static ALLEGRO_JOYSTICK_DRIVER *xglx_get_joystick_driver(void) +{ + return _al_joystick_driver_list[0].driver; +} + +static ALLEGRO_HAPTIC_DRIVER *xglx_get_haptic_driver(void) +{ + return _al_haptic_driver_list[0].driver; +} + +static ALLEGRO_TOUCH_INPUT_DRIVER *xglx_get_touch_driver(void) +{ + return _al_touch_input_driver_list[0].driver; +} + +static int xglx_get_num_video_adapters(void) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + return _al_xglx_get_num_video_adapters(system); +} + +static bool xglx_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + + return _al_xglx_get_monitor_info(system, adapter, info); +} + +static bool xglx_get_cursor_position(int *ret_x, int *ret_y) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Window root = RootWindow(system->x11display, 0); + Window child; + int wx, wy; + unsigned int mask; + + _al_mutex_lock(&system->lock); + XQueryPointer(system->x11display, root, &root, &child, ret_x, ret_y, + &wx, &wy, &mask); + _al_mutex_unlock(&system->lock); + return true; +} + +static bool xglx_inhibit_screensaver(bool inhibit) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + int temp, version_min, version_max; + +#ifdef ALLEGRO_XWINDOWS_WITH_XSCREENSAVER + if (!XScreenSaverQueryExtension(system->x11display, &temp, &temp) || + !XScreenSaverQueryVersion(system->x11display, &version_max, &version_min) || + version_max < 1 || (version_max == 1 && version_min < 1)) { + system->screen_saver_query_available = false; + } + else { + system->screen_saver_query_available = true; + + /* X11 maintains a counter on the number of identical calls to + * XScreenSaverSuspend for a given display. So, only call it if 'inhibit' is + * different to the previous invocation; otherwise we'd need to call it an + * identical number of times with the negated value if there were a change. + */ + if (inhibit != system->inhibit_screensaver) { + XScreenSaverSuspend(system->x11display, inhibit); + } + } +#else + (void)temp; + (void)version_min; + (void)version_max; +#endif + + system->inhibit_screensaver = inhibit; + return true; +} + +static int xglx_get_num_display_modes(void) +{ + int adapter = al_get_new_display_adapter(); + ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + + return _al_xglx_get_num_display_modes(s, adapter); +} + +static ALLEGRO_DISPLAY_MODE *xglx_get_display_mode(int mode, ALLEGRO_DISPLAY_MODE *dm) +{ + int adapter = al_get_new_display_adapter(); + ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + + return _al_xglx_get_display_mode(s, adapter, mode, dm); +} + +static int xglx_get_monitor_dpi(int adapter) +{ + ALLEGRO_MONITOR_INFO info; + ALLEGRO_SYSTEM_XGLX *s = (void *)al_get_system_driver(); + int x2_mm; + int y2_mm; + int dpi_hori; + int dpi_vert; + + if(!_al_xglx_get_monitor_info(s, adapter, &info)) { + return 0; + } + + x2_mm = DisplayWidthMM(s->x11display, DefaultScreen(s->x11display)); + y2_mm = DisplayHeightMM(s->x11display, DefaultScreen(s->x11display)); + + dpi_hori = (info.x2 - info.x1) / (_AL_INCHES_PER_MM * x2_mm); + dpi_vert = (info.y2 - info.y1) / (_AL_INCHES_PER_MM * y2_mm); + + return sqrt(dpi_hori * dpi_vert); +} + +/* Internal function to get a reference to this driver. */ +ALLEGRO_SYSTEM_INTERFACE *_al_system_xglx_driver(void) +{ + if (xglx_vt) + return xglx_vt; + + xglx_vt = al_calloc(1, sizeof *xglx_vt); + + xglx_vt->id = ALLEGRO_SYSTEM_ID_XGLX; + xglx_vt->initialize = xglx_initialize; + xglx_vt->get_display_driver = xglx_get_display_driver; + xglx_vt->get_keyboard_driver = xglx_get_keyboard_driver; + xglx_vt->get_mouse_driver = xglx_get_mouse_driver; + xglx_vt->get_joystick_driver = xglx_get_joystick_driver; + xglx_vt->get_haptic_driver = xglx_get_haptic_driver; + xglx_vt->get_touch_input_driver = xglx_get_touch_driver; + xglx_vt->get_num_display_modes = xglx_get_num_display_modes; + xglx_vt->get_display_mode = xglx_get_display_mode; + xglx_vt->shutdown_system = xglx_shutdown_system; + xglx_vt->get_num_video_adapters = xglx_get_num_video_adapters; + xglx_vt->get_monitor_info = xglx_get_monitor_info; + xglx_vt->get_monitor_dpi = xglx_get_monitor_dpi; + xglx_vt->create_mouse_cursor = _al_xwin_create_mouse_cursor; + xglx_vt->destroy_mouse_cursor = _al_xwin_destroy_mouse_cursor; + xglx_vt->get_cursor_position = xglx_get_cursor_position; + xglx_vt->grab_mouse = _al_xwin_grab_mouse; + xglx_vt->ungrab_mouse = _al_xwin_ungrab_mouse; + xglx_vt->get_path = _al_unix_get_path; + xglx_vt->inhibit_screensaver = xglx_inhibit_screensaver; + xglx_vt->get_time = _al_unix_get_time; + xglx_vt->rest = _al_unix_rest; + xglx_vt->init_timeout = _al_unix_init_timeout; + + return xglx_vt; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/src/x/xtouch.c b/allegro/src/x/xtouch.c new file mode 100644 index 00000000..bd858cac --- /dev/null +++ b/allegro/src/x/xtouch.c @@ -0,0 +1,478 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * X-Windows touch module. + * + * By Ryan Gumbs. + * + * See readme.txt for copyright information. + */ + +#define ALLEGRO_NO_COMPATIBILITY + +#include "allegro5/allegro.h" +#include "allegro5/internal/aintern.h" +#include "allegro5/internal/aintern_mouse.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xmouse.h" +#include "allegro5/internal/aintern_xsystem.h" +#include "allegro5/internal/aintern_xtouch.h" + +#ifdef ALLEGRO_XWINDOWS_WITH_XINPUT2 + +#include +#include + + + +ALLEGRO_DEBUG_CHANNEL("touch") + + +/* the one and only touch object */ +static ALLEGRO_TOUCH_INPUT_STATE touch_input_state; +static ALLEGRO_TOUCH_INPUT touch_input; +static ALLEGRO_MOUSE_STATE mouse_state; +static int touch_ids[ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT]; /* the XInput id for touches */ +static int primary_touch_id = -1; +static bool installed = false; +static size_t initiali_time_stamp = ~0; +static int opcode; + + +static void reset_touch_input_state(void) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; i++) { + touch_input_state.touches[i].id = -1; + } +} + + +static void generate_touch_input_event(unsigned int type, double timestamp, + int id, float x, float y, float dx, float dy, bool primary, + ALLEGRO_DISPLAY *disp) +{ + ALLEGRO_EVENT event; + + bool want_touch_event = _al_event_source_needs_to_generate_event(&touch_input.es); + bool want_mouse_emulation_event; + + if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_5_0_x) { + want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input.mouse_emulation_es) && al_is_mouse_installed(); + } + else { + want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input.mouse_emulation_es) && primary && al_is_mouse_installed(); + } + + if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_NONE) + want_mouse_emulation_event = false; + else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_INCLUSIVE) + want_touch_event = al_is_mouse_installed() ? (want_touch_event && !primary) : want_touch_event; + else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_EXCLUSIVE) + want_touch_event = al_is_mouse_installed() ? false : want_touch_event; + + + if (!want_touch_event && !want_mouse_emulation_event) + return; + + if (want_touch_event) { + event.touch.type = type; + event.touch.display = (ALLEGRO_DISPLAY*)disp; + event.touch.timestamp = timestamp; + event.touch.id = id; + event.touch.x = x; + event.touch.y = y; + event.touch.dx = dx; + event.touch.dy = dy; + event.touch.primary = primary; + + _al_event_source_lock(&touch_input.es); + _al_event_source_emit_event(&touch_input.es, &event); + _al_event_source_unlock(&touch_input.es); + } + + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_NONE) { + mouse_state.x = (int)x; + mouse_state.y = (int)y; + if (type == ALLEGRO_EVENT_TOUCH_BEGIN) + mouse_state.buttons++; + else if (type == ALLEGRO_EVENT_TOUCH_END) + mouse_state.buttons--; + + mouse_state.pressure = mouse_state.buttons ? 1.0 : 0.0; /* TODO */ + + _al_event_source_lock(&touch_input.mouse_emulation_es); + if (want_mouse_emulation_event) { + + switch (type) { + case ALLEGRO_EVENT_TOUCH_BEGIN: type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; break; + case ALLEGRO_EVENT_TOUCH_CANCEL: + case ALLEGRO_EVENT_TOUCH_END: type = ALLEGRO_EVENT_MOUSE_BUTTON_UP; break; + case ALLEGRO_EVENT_TOUCH_MOVE: type = ALLEGRO_EVENT_MOUSE_AXES; break; + } + + event.mouse.type = type; + event.mouse.timestamp = timestamp; + event.mouse.display = (ALLEGRO_DISPLAY*)disp; + event.mouse.x = (int)x; + event.mouse.y = (int)y; + event.mouse.dx = (int)dx; + event.mouse.dy = (int)dy; + event.mouse.dz = 0; + event.mouse.dw = 0; + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_5_0_x) { + event.mouse.button = 1; + } + else { + event.mouse.button = id; + } + event.mouse.pressure = mouse_state.pressure; + + if (touch_input.mouse_emulation_mode != ALLEGRO_MOUSE_EMULATION_5_0_x) { + al_set_mouse_xy(event.mouse.display, event.mouse.x, event.mouse.y); + } + + _al_event_source_emit_event(&touch_input.mouse_emulation_es, &event); + } + _al_event_source_unlock(&touch_input.mouse_emulation_es); + } +} + + +static int find_free_touch_state_index(void) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; i++) + if (touch_input_state.touches[i].id < 0) + return i; + + return -1; +} + + +static int find_touch_state_index_with_id(int id) +{ + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; i++) + if (touch_ids[i] == id) + return i; + + return -1; +} + + +static void touch_input_handle_begin(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + int index= find_free_touch_state_index(); + if (index < 0) + return; + + ALLEGRO_TOUCH_STATE* state = touch_input_state.touches + index; + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->id = index; + state->x = x; + state->y = y; + state->dx = 0.0f; + state->dy = 0.0f; + state->primary = primary; + state->display = disp; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_BEGIN, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, + disp); + + touch_ids[index]= id; +} + + +static void touch_input_handle_end(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + int index= find_touch_state_index_with_id(id); + if (index < 0) + return; + + ALLEGRO_TOUCH_STATE* state = touch_input_state.touches + index; + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_END, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, + disp); + + _al_event_source_lock(&touch_input.es); + state->id = -1; + touch_ids[index]= -1; + _al_event_source_unlock(&touch_input.es); +} + + +static void touch_input_handle_move(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + int index= find_touch_state_index_with_id(id); + if (index < 0) + return; + + ALLEGRO_TOUCH_STATE* state = touch_input_state.touches + index; + (void)primary; + + if (NULL == state) + return; + + if (x == state->x && y == state->y) + return; /* coordinates haven't changed */ + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_MOVE, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, + disp); +} + + +static void touch_input_handle_cancel(int id, double timestamp, float x, float y, bool primary, ALLEGRO_DISPLAY *disp) +{ + int index= find_touch_state_index_with_id(id); + if (index < 0) + return; + + ALLEGRO_TOUCH_STATE* state = touch_input_state.touches + index; + (void)primary; + + if (NULL == state) + return; + + _al_event_source_lock(&touch_input.es); + state->dx = x - state->x; + state->dy = y - state->y; + state->x = x; + state->y = y; + _al_event_source_unlock(&touch_input.es); + + generate_touch_input_event(ALLEGRO_EVENT_TOUCH_CANCEL, timestamp, + state->id, state->x, state->y, state->dx, state->dy, state->primary, disp); + + _al_event_source_lock(&touch_input.es); + state->id = -1; + _al_event_source_unlock(&touch_input.es); +} + + +static bool init_touch_input_api(void) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + Display *dpy = system->x11display; + + /* check XInput extension */ + int ev; + int err; + if (!XQueryExtension(dpy, "XInputExtension", &opcode, &ev, &err)) { + ALLEGRO_DEBUG("XInput extension not available. Touch input unavailable.\n"); + return false; + } + + /* check the version of XInput */ + int major = 2; + int minor = 2; + int rc = XIQueryVersion(dpy, &major, &minor); + if (rc != Success) { + ALLEGRO_DEBUG("XInput version is too old (%d.%d): Needs 2.2. Touch input unavailable.\n", major, minor); + return false; + } + + /* select device */ + int cnt; + int i, j; + int touch_devid; + XIDeviceInfo *di = XIQueryDevice(dpy, XIAllDevices, &cnt); + for (i = 0; i < cnt; i++) { + XIDeviceInfo *dev = &di[i]; + for (j = 0; j < dev->num_classes; j++) { + XITouchClassInfo *class = (XITouchClassInfo*)(dev->classes[j]); + if (class->type == XITouchClass) { + touch_devid = dev->deviceid; + ALLEGRO_DEBUG("Found touchscreen deviceid: %i\n", touch_devid); + goto STOP_SEARCH_DEVICE; + } + } + } +STOP_SEARCH_DEVICE: + XIFreeDeviceInfo(di); + + if (i >= cnt) { + /* no device found */ + ALLEGRO_DEBUG("No touchscreen device found.\n"); + return false; + } + + return true; +} + + +static bool xtouch_init(void) +{ + if (installed) + return false; + + if (!init_touch_input_api()) + return false; + + ALLEGRO_DEBUG("XInput2 touch input initialized.\n"); + + memset(&touch_input, 0, sizeof(touch_input)); + reset_touch_input_state(); + + /* Initialise the touch object for use as an event source. */ + _al_event_source_init(&touch_input.es); + + _al_event_source_init(&touch_input.mouse_emulation_es); + touch_input.mouse_emulation_mode = ALLEGRO_MOUSE_EMULATION_TRANSPARENT; + + initiali_time_stamp = al_get_time(); + + installed = true; + + return true; +} + + +static void xtouch_exit(void) +{ +} + + +static ALLEGRO_TOUCH_INPUT* get_touch_input(void) +{ + return &touch_input; +} + + +static void get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state) +{ + _al_event_source_lock(&touch_input.es); + *ret_state = touch_input_state; + _al_event_source_unlock(&touch_input.es); +} + + +static void set_mouse_emulation_mode(int mode) +{ + if (touch_input.mouse_emulation_mode != mode) { + int i; + + for (i = 0; i < ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT; i++) { + ALLEGRO_TOUCH_STATE* touch = touch_input_state.touches + i; + + if (touch->id > 0) { + touch_input_handle_cancel(touch_ids[i], initiali_time_stamp, + touch->x, touch->y, touch->primary, touch->display); + } + } + + touch_input.mouse_emulation_mode = mode; + } +} + + +/* the driver vtable */ +#define TOUCHDRV_XWIN AL_ID('X','W','I','N') + +static ALLEGRO_TOUCH_INPUT_DRIVER touchdrv_xwin = +{ + TOUCHDRV_XWIN, + xtouch_init, + xtouch_exit, + get_touch_input, + get_touch_input_state, + set_mouse_emulation_mode, + NULL +}; + +#endif + +_AL_DRIVER_INFO _al_touch_input_driver_list[] = +{ +#ifdef ALLEGRO_XWINDOWS_WITH_XINPUT2 + {TOUCHDRV_XWIN, &touchdrv_xwin, true}, +#endif + {0, NULL, 0} +}; + +void _al_x_handle_touch_event(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, XEvent *e) +{ +#ifdef ALLEGRO_XWINDOWS_WITH_XINPUT2 + Display *x11display = s->x11display; + XGenericEventCookie *cookie = &e->xcookie; + if (!installed) + return; + /* extended event */ + if (XGetEventData(x11display, cookie)) { + /* check if this belongs to XInput */ + if (cookie->type == GenericEvent && cookie->extension == opcode) { + XIDeviceEvent *devev; + + devev = cookie->data; + + /* ignore events from a different display */ + if (devev->display != x11display) + return; + + switch (devev->evtype) { + case XI_TouchBegin: + /* the next new touch gets primary flag if it's not set */ + if (primary_touch_id < 0) + primary_touch_id= devev->detail; + + touch_input_handle_begin(devev->detail, al_get_time(), + devev->event_x, devev->event_y, primary_touch_id == devev->detail, &d->display); + break; + case XI_TouchUpdate: + touch_input_handle_move(devev->detail, al_get_time(), + devev->event_x, devev->event_y, primary_touch_id == devev->detail, &d->display); + break; + case XI_TouchEnd: + touch_input_handle_end(devev->detail, al_get_time(), + devev->event_x, devev->event_y, primary_touch_id == devev->detail, &d->display); + + if (primary_touch_id == devev->detail) + primary_touch_id = -1; + break; + } + } + } +#else + (void)s; + (void)d; + (void)e; +#endif +} diff --git a/allegro/src/x/xwindow.c b/allegro/src/x/xwindow.c new file mode 100644 index 00000000..b0899fea --- /dev/null +++ b/allegro/src/x/xwindow.c @@ -0,0 +1,403 @@ +#include +#include +#include + +#include "allegro5/allegro.h" +#include "allegro5/allegro_x.h" +#include "allegro5/internal/aintern_x.h" +#include "allegro5/internal/aintern_xdisplay.h" +#include "allegro5/internal/aintern_xsystem.h" +#include "allegro5/internal/aintern_xwindow.h" + +#ifdef ALLEGRO_RASPBERRYPI +#include "allegro5/internal/aintern_raspberrypi.h" +#define ALLEGRO_SYSTEM_XGLX ALLEGRO_SYSTEM_RASPBERRYPI +#define ALLEGRO_DISPLAY_XGLX ALLEGRO_DISPLAY_RASPBERRYPI +#endif + +ALLEGRO_DEBUG_CHANNEL("xwindow") + +#define X11_ATOM(x) XInternAtom(x11, #x, False); + +void _al_xwin_set_size_hints(ALLEGRO_DISPLAY *d, int x_off, int y_off) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (void *)d; + XSizeHints *sizehints; + XWMHints *wmhints; + XClassHint *classhints; + int w, h; + + sizehints = XAllocSizeHints(); + sizehints->flags = 0; + +#ifdef ALLEGRO_RASPBERRYPI + int x, y; + _al_raspberrypi_get_screen_info(&x, &y, &w, &h); +#else + w = d->w; + h = d->h; +#endif + + /* Do not force the size of the window on resizeable or fullscreen windows */ + /* on fullscreen windows, it confuses most X Window Managers */ + if (!(d->flags & ALLEGRO_RESIZABLE) && !(d->flags & ALLEGRO_FULLSCREEN)) { + sizehints->flags |= PMinSize | PMaxSize | PBaseSize; + sizehints->min_width = sizehints->max_width = sizehints->base_width = w; + sizehints->min_height = sizehints->max_height = sizehints->base_height = h; + } + + /* Constrain the window if needed. */ + if (d->use_constraints && (d->flags & ALLEGRO_RESIZABLE) && + (d->min_w > 0 || d->min_h > 0 || d->max_w > 0 || d->max_h > 0)) + { + sizehints->flags |= PMinSize | PMaxSize | PBaseSize; + sizehints->min_width = (d->min_w > 0) ? d->min_w : 0; + sizehints->min_height = (d->min_h > 0) ? d->min_h : 0; + sizehints->max_width = (d->max_w > 0) ? d->max_w : INT_MAX; + sizehints->max_height = (d->max_h > 0) ? d->max_h : INT_MAX; + sizehints->base_width = w; + sizehints->base_height = h; + } + + // Tell WMs to respect our chosen position, otherwise the x_off/y_off + // positions passed to XCreateWindow will be ignored by most WMs. + if (x_off != INT_MAX && y_off != INT_MAX) { + ALLEGRO_DEBUG("Force window position to %d, %d.\n", x_off, y_off); + sizehints->flags |= PPosition; + sizehints->x = x_off; + sizehints->y = y_off; + } + + if (d->flags & ALLEGRO_FULLSCREEN) { + /* kwin will improperly layer a panel over our window on a second display without this. + * some other Size flags may cause glitches with various WMs, but this seems to be ok + * with metacity and kwin. As noted in xdpy_create_display, compiz is just broken. + */ + sizehints->flags |= PBaseSize; + sizehints->base_width = w; + sizehints->base_height = h; + } + + /* Setup the input hints so we get keyboard input */ + wmhints = XAllocWMHints(); + wmhints->input = True; + wmhints->flags = InputHint; + + ALLEGRO_PATH *exepath = al_get_standard_path(ALLEGRO_EXENAME_PATH); + + /* Setup the class hints so we can get an icon (AfterStep) + * We must use the executable filename here. + */ + classhints = XAllocClassHint(); + classhints->res_name = strdup(al_get_path_basename(exepath)); + classhints->res_class = strdup(al_get_path_basename(exepath)); + + /* Set the size, input and class hints, and define WM_CLIENT_MACHINE and WM_LOCALE_NAME */ + XSetWMProperties(system->x11display, glx->window, NULL, NULL, NULL, 0, + sizehints, wmhints, classhints); + + free(classhints->res_name); + free(classhints->res_class); + XFree(sizehints); + XFree(wmhints); + XFree(classhints); + + al_destroy_path(exepath); +} + + +void _al_xwin_reset_size_hints(ALLEGRO_DISPLAY *d) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (void *)d; + XSizeHints *hints; + + hints = XAllocSizeHints(); + hints->flags = PMinSize | PMaxSize; + hints->min_width = 0; + hints->min_height = 0; + // FIXME: Is there a way to remove/reset max dimensions? + hints->max_width = 32768; + hints->max_height = 32768; + XSetWMNormalHints(system->x11display, glx->window, hints); + + XFree(hints); +} + + +/* Note: The system mutex must be locked (exactly once) before + * calling this as we call _al_display_xglx_await_resize. + */ +void _al_xwin_set_fullscreen_window(ALLEGRO_DISPLAY *display, int value) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + Display *x11 = system->x11display; +#ifndef ALLEGRO_RASPBERRYPI + int old_resize_count = glx->resize_count; +#endif + + ALLEGRO_DEBUG("Toggling _NET_WM_STATE_FULLSCREEN hint: %d\n", value); + + XEvent xev; + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.message_type = X11_ATOM(_NET_WM_STATE); + xev.xclient.window = glx->window; + xev.xclient.format = 32; + + // Note: It seems 0 is not reliable except when mapping a window - + // 2 is all we need though. + xev.xclient.data.l[0] = value; /* 0 = off, 1 = on, 2 = toggle */ + + xev.xclient.data.l[1] = X11_ATOM(_NET_WM_STATE_FULLSCREEN); + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 1; + + XSendEvent( + x11, +#if !defined ALLEGRO_RASPBERRYPI + RootWindowOfScreen(ScreenOfDisplay(x11, glx->xscreen)), +#else + RootWindowOfScreen(ScreenOfDisplay(x11, DefaultScreen(x11))), +#endif + False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); + +#if !defined ALLEGRO_RASPBERRYPI + if (value == 2) { + /* Only wait for a resize if toggling. */ + _al_display_xglx_await_resize(display, old_resize_count, true); + } +#endif +} + + +void _al_xwin_set_above(ALLEGRO_DISPLAY *display, int value) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + Display *x11 = system->x11display; + + ALLEGRO_DEBUG("Toggling _NET_WM_STATE_ABOVE hint: %d\n", value); + + XEvent xev; + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.message_type = X11_ATOM(_NET_WM_STATE); + xev.xclient.window = glx->window; + xev.xclient.format = 32; + + // Note: It seems 0 is not reliable except when mapping a window - + // 2 is all we need though. + xev.xclient.data.l[0] = value; /* 0 = off, 1 = on, 2 = toggle */ + + xev.xclient.data.l[1] = X11_ATOM(_NET_WM_STATE_ABOVE); + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 1; + + XSendEvent(x11, DefaultRootWindow(x11), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); +} + + +void _al_xwin_set_frame(ALLEGRO_DISPLAY *display, bool frame_on) +{ + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + Display *x11 = system->x11display; + Atom hints; + + _al_mutex_lock(&system->lock); + +#if 1 + /* This code is taken from the GDK sources. So it works perfectly in Gnome, + * no idea if it will work anywhere else. X11 documentation itself only + * describes a way how to make the window completely unmanaged, but that + * would also require special care in the event handler. + */ + hints = XInternAtom(x11, "_MOTIF_WM_HINTS", True); + if (hints) { + struct { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; + } motif = {2, 0, frame_on, 0, 0}; + XChangeProperty(x11, glx->window, hints, hints, 32, PropModeReplace, + (void *)&motif, sizeof motif / 4); + + if (frame_on) + display->flags &= ~ALLEGRO_FRAMELESS; + else + display->flags |= ALLEGRO_FRAMELESS; + } +#endif + + _al_mutex_unlock(&system->lock); +} + + +/* Helper to set a window icon. We use the _NET_WM_ICON property which is + * supported by modern window managers. + * + * The old method is XSetWMHints but the (antiquated) ICCCM talks about 1-bit + * pixmaps. For colour icons, perhaps you're supposed use the icon_window, + * and draw the window yourself? + */ +static bool xdpy_set_icon_inner(Display *x11display, Window window, + ALLEGRO_BITMAP *bitmap, int prop_mode) +{ + int w, h; + int data_size; + unsigned long *data; /* Yes, unsigned long, even on 64-bit platforms! */ + ALLEGRO_LOCKED_REGION *lr; + bool ret; + + w = al_get_bitmap_width(bitmap); + h = al_get_bitmap_height(bitmap); + data_size = 2 + w * h; + data = al_malloc(data_size * sizeof(data[0])); + if (!data) + return false; + + lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA, + ALLEGRO_LOCK_READONLY); + if (lr) { + int x, y; + ALLEGRO_COLOR c; + unsigned char r, g, b, a; + Atom _NET_WM_ICON; + + data[0] = w; + data[1] = h; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + c = al_get_pixel(bitmap, x, y); + al_unmap_rgba(c, &r, &g, &b, &a); + data[2 + y*w + x] = ((unsigned long)a << 24) | ((unsigned long)r << 16) | + ((unsigned long)g << 8) | (unsigned long)b; + } + } + + _NET_WM_ICON = XInternAtom(x11display, "_NET_WM_ICON", False); + XChangeProperty(x11display, window, _NET_WM_ICON, XA_CARDINAL, 32, + prop_mode, (unsigned char *)data, data_size); + + al_unlock_bitmap(bitmap); + ret = true; + } + else { + ret = false; + } + + al_free(data); + + return ret; +} + + +void _al_xwin_set_icons(ALLEGRO_DISPLAY *d, + int num_icons, ALLEGRO_BITMAP *bitmaps[]) +{ + ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; + int prop_mode = PropModeReplace; + int i; + + _al_mutex_lock(&system->lock); + + for (i = 0; i < num_icons; i++) { + if (xdpy_set_icon_inner(system->x11display, glx->window, bitmaps[i], + prop_mode)) { + prop_mode = PropModeAppend; + } + } + + _al_mutex_unlock(&system->lock); +} + + +void _al_xwin_maximize(ALLEGRO_DISPLAY *display, bool maximized) +{ +#ifndef ALLEGRO_RASPBERRYPI + if (!!(display->flags & ALLEGRO_MAXIMIZED) == maximized) + return; + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + Display *x11 = system->x11display; + int old_resize_count = glx->resize_count; + + XEvent xev; + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.message_type = X11_ATOM(_NET_WM_STATE); + xev.xclient.window = glx->window; + xev.xclient.format = 32; + + xev.xclient.data.l[0] = maximized ? 1 : 0; + xev.xclient.data.l[1] = X11_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); + xev.xclient.data.l[2] = X11_ATOM(_NET_WM_STATE_MAXIMIZED_VERT); + xev.xclient.data.l[3] = 0; + + XSendEvent( + x11, + RootWindowOfScreen(ScreenOfDisplay(x11, glx->xscreen)), + False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); + + _al_display_xglx_await_resize(display, old_resize_count, true); +#endif +} + + +void _al_xwin_check_maximized(ALLEGRO_DISPLAY *display) +{ +#ifndef ALLEGRO_RASPBERRYPI + ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); + ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; + Display *x11 = system->x11display; + Atom type; + Atom horz = X11_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); + Atom vert = X11_ATOM(_NET_WM_STATE_MAXIMIZED_VERT); + Atom property = X11_ATOM(_NET_WM_STATE); + int format; + int maximized = 0; + unsigned long n, remaining, i, *p32; + unsigned char *p8 = NULL; + if (XGetWindowProperty(x11, glx->window, property, 0, INT_MAX, + False, AnyPropertyType, &type, &format, &n, &remaining, &p8) + != Success) { + return; + } + p32 = (unsigned long *)p8; + for (i = 0; i < n; i++) { + if (p32[i] == horz) + maximized |= 1; + if (p32[i] == vert) + maximized |= 2; + } + XFree(p8); + display->flags &= ~ALLEGRO_MAXIMIZED; + if (maximized == 3) + display->flags |= ALLEGRO_MAXIMIZED; +#endif +} + + +/* Function: al_get_x_window_id + */ +XID al_get_x_window_id(ALLEGRO_DISPLAY *display) +{ + ASSERT(display != NULL); + return ((ALLEGRO_DISPLAY_XGLX*)display)->window; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/tests/CMakeLists.txt b/allegro/tests/CMakeLists.txt new file mode 100644 index 00000000..7b87a6e6 --- /dev/null +++ b/allegro/tests/CMakeLists.txt @@ -0,0 +1,110 @@ +if(NOT ALLEGRO_LINK_WITH OR NOT ALLEGRO_MAIN_LINK_WITH OR + NOT IMAGE_LINK_WITH OR NOT COLOR_LINK_WITH OR + NOT FONT_LINK_WITH OR NOT TTF_LINK_WITH OR + NOT PRIMITIVES_LINK_WITH) + message(STATUS "Not building tests due to missing library. " + "Have: ${ALLEGRO_LINK_WITH} ${ALLEGRO_MAIN_LINK_WITH} " + "${IMAGE_LINK_WITH} ${COLOR_LINK_WITH} " + "${FONT_LINK_WITH} ${TTF_LINK_WITH} " + "${PRIMITIVES_LINK_WITH}") + return() +endif() + +include_directories( + ../addons/acodec + ../addons/audio + ../addons/color + ../addons/font + ../addons/image + ../addons/main + ../addons/memfile + ../addons/native_dialog + ../addons/physfs + ../addons/primitives + ../addons/shader + ../addons/ttf + ) + +if(MSVC) + set(EXECUTABLE_TYPE) +endif(MSVC) + +if(WANT_MONOLITH) + add_our_executable( + test_driver + LIBS + ${ALLEGRO_MONOLITH_LINK_WITH} + ) +else(WANT_MONOLITH) + add_our_executable( + test_driver + LIBS + ${ALLEGRO_LINK_WITH} + ${ALLEGRO_MAIN_LINK_WITH} + ${IMAGE_LINK_WITH} + ${COLOR_LINK_WITH} + ${FONT_LINK_WITH} + ${TTF_LINK_WITH} + ${PRIMITIVES_LINK_WITH} + ${SHADER_LINK_WITH} + ) +endif(WANT_MONOLITH) + +set(test_files + ${CMAKE_CURRENT_SOURCE_DIR}/test_bitmaps.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_bitmaps2.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_blend.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_locking.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_locking2.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_backbuffer.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_image.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_fonts.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_prim.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_prim2.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_convert.ini + ${CMAKE_CURRENT_SOURCE_DIR}/test_ciede2000.ini + ) + +add_dependencies(test_driver copy_example_data) + +add_custom_target(run_tests + DEPENDS test_driver + COMMAND test_driver ${test_files} + ) + +add_custom_target(run_tests_gl + DEPENDS test_driver + COMMAND test_driver --force-opengl ${test_files} + ) + +add_custom_target(run_tests_gl12 + DEPENDS test_driver + COMMAND test_driver --force-opengl-1.2 ${test_files} + ) + +add_custom_target(run_tests_gl20 + DEPENDS test_driver + COMMAND test_driver --force-opengl-2.0 ${test_files} + ) + +add_custom_target(run_tests_d3d + DEPENDS test_driver + COMMAND test_driver --force-d3d ${test_files} + ) + +add_custom_target(run_tests_wine + DEPENDS test_driver + COMMAND wine test_driver ${test_files} + ) + +add_custom_target(run_tests_wine_gl + DEPENDS test_driver + COMMAND wine test_driver --force-opengl ${test_files} + ) + +add_custom_target(run_tests_shaders + DEPENDS test_driver + COMMAND test_driver --use-shaders ${test_files} + ) + +# vim: set sts=4 sw=4 et: diff --git a/allegro/tests/grab_bitmap_suites.sh b/allegro/tests/grab_bitmap_suites.sh new file mode 100644 index 00000000..b8f90969 --- /dev/null +++ b/allegro/tests/grab_bitmap_suites.sh @@ -0,0 +1,17 @@ +# bmp suite 1 +wget -N http://entropymine.com/jason/bmpsuite/bmpsuite.zip +unzip -u -d bmpsuite bmpsuite.zip + +# bmp suite 2 +wget --no-check-certificate -N http://downloads.sourceforge.net/project/bmptestsuite/bmptestsuite/bmptestsuite-0.9/bmptestsuite-0.9.zip +unzip -u bmptestsuite-0.9.zip + +# bmp suite 3 +wget -N -P wvnet https://download.tuxfamily.org/allegro/files/bmpsuite/wvnet/test32bfv4.bmp +wget -N -P wvnet https://download.tuxfamily.org/allegro/files/bmpsuite/wvnet/test32v5.bmp +wget -N -P wvnet https://download.tuxfamily.org/allegro/files/bmpsuite/wvnet/trans.bmp + +# bmp suite 4 +wget -N http://entropymine.com/jason/bmpsuite/releases/bmpsuite-2.4.zip +unzip -u bmpsuite-2.4.zip +mv bmpsuite-2.4 bmpsuite2 diff --git a/allegro/tests/manual_bmpsuite1.ini b/allegro/tests/manual_bmpsuite1.ini new file mode 100644 index 00000000..dfc9567c --- /dev/null +++ b/allegro/tests/manual_bmpsuite1.ini @@ -0,0 +1,175 @@ +# Test BMP loader with images from this source: +# http://entropymine.com/jason/bmpsuite/ + +[bitmaps] +g01bg =bmpsuite/g01bg.bmp +g01bw =bmpsuite/g01bw.bmp +g01p1 =bmpsuite/g01p1.bmp +g01wb =bmpsuite/g01wb.bmp +g04 =bmpsuite/g04.bmp +g04p4 =bmpsuite/g04p4.bmp +g04rle =bmpsuite/g04rle.bmp +g08 =bmpsuite/g08.bmp +g08offs =bmpsuite/g08offs.bmp +g08os2 =bmpsuite/g08os2.bmp +g08p64 =bmpsuite/g08p64.bmp +g08p256 =bmpsuite/g08p256.bmp +g08pi64 =bmpsuite/g08pi64.bmp +g08pi256 =bmpsuite/g08pi256.bmp +g08res11 =bmpsuite/g08res11.bmp +g08res21 =bmpsuite/g08res21.bmp +g08res22 =bmpsuite/g08res22.bmp +g08rle =bmpsuite/g08rle.bmp +g08s0 =bmpsuite/g08s0.bmp +g08w124 =bmpsuite/g08w124.bmp +g08w125 =bmpsuite/g08w125.bmp +g08w126 =bmpsuite/g08w126.bmp +g16bf555 =bmpsuite/g16bf555.bmp +g16bf565 =bmpsuite/g16bf565.bmp +g16def555=bmpsuite/g16def555.bmp +g24 =bmpsuite/g24.bmp +g32bf =bmpsuite/g32bf.bmp +g32def =bmpsuite/g32def.bmp + +[template] +op0=al_draw_bitmap(bmp, 0, 0, 0) + +[test bmpsuite g01bg] +extend=template +bmp=g01bg +hash=9846dc91 + +[test bmpsuite g01bw] +extend=template +bmp=g01bw +hash=e20721a5 + +[test bmpsuite g01p1] +extend=template +bmp=g01p1 +hash=87931dc5 + +[test bmpsuite g01wb] +extend=template +bmp=g01wb +hash=e20721a5 + +[test bmpsuite g04] +extend=template +bmp=g04 +hash=3ba8f12f + +[test bmpsuite g04p4] +extend=template +bmp=g04p4 +hash=ab1a2d4d + +[test bmpsuite g04rle] +extend=template +bmp=g04rle +hash=3ba8f12f + +[test bmpsuite g08] +extend=template +bmp=g08 +hash=7d8eb943 + +[test bmpsuite g08offs] +extend=template +bmp=g08offs +hash=7d8eb943 + +[test bmpsuite g08os2] +extend=template +bmp=g08os2 +hash=7d8eb943 + +[test bmpsuite g08p64] +extend=template +bmp=g08p64 +hash=7b1f9739 + +[test bmpsuite g08p256] +extend=template +bmp=g08p256 +hash=7d8eb943 + +[test bmpsuite g08pi64] +extend=template +bmp=g08pi64 +hash=7d8eb943 + +[test bmpsuite g08pi256] +extend=template +bmp=g08pi256 +hash=7d8eb943 + +[test bmpsuite g08res11] +extend=template +bmp=g08res11 +hash=7d8eb943 + +[test bmpsuite g08res21] +extend=template +bmp=g08res21 +hash=7d8eb943 + +[test bmpsuite g08res22] +extend=template +bmp=g08res22 +hash=7d8eb943 + +[test bmpsuite g08rle] +extend=template +bmp=g08rle +hash=7d8eb943 + +[test bmpsuite g08s0] +extend=template +bmp=g08s0 +hash=7d8eb943 + +[test bmpsuite g08w124] +extend=template +bmp=g08w124 +hash=a18fef34 + +[test bmpsuite g08w125] +extend=template +bmp=g08w125 +hash=a25db914 + +[test bmpsuite g08w126] +extend=template +bmp=g08w126 +hash=dde9c6c4 + +[test bmpsuite g16bf555] +extend=template +bmp=g16bf555 +hash=096251dc + +[test bmpsuite g16bf565] +extend=template +bmp=g16bf565 +hash=09f60795 + +[test bmpsuite g16def555] +extend=template +bmp=g16def555 +hash=096251dc + +[test bmpsuite g24] +extend=template +bmp=g24 +hash=f5bdf572 + +[test bmpsuite g32bf] +extend=template +bmp=g32bf +hash=f5bdf572 + +[test bmpsuite g32def] +extend=template +bmp=g32def +hash=f5bdf572 diff --git a/allegro/tests/manual_bmpsuite2.ini b/allegro/tests/manual_bmpsuite2.ini new file mode 100644 index 00000000..7ba0f69c --- /dev/null +++ b/allegro/tests/manual_bmpsuite2.ini @@ -0,0 +1,421 @@ +# Test BMP loader with images from this source: +# http://bmptestsuite.sourceforge.net/ + +[bitmaps] +1bpp-1x1 =bmptestsuite-0.9/valid/1bpp-1x1.bmp +1bpp-320x240 =bmptestsuite-0.9/valid/1bpp-320x240.bmp +1bpp-320x240-color =bmptestsuite-0.9/valid/1bpp-320x240-color.bmp +1bpp-320x240-overlappingcolor =bmptestsuite-0.9/valid/1bpp-320x240-overlappingcolor.bmp +1bpp-321x240 =bmptestsuite-0.9/valid/1bpp-321x240.bmp +1bpp-322x240 =bmptestsuite-0.9/valid/1bpp-322x240.bmp +1bpp-323x240 =bmptestsuite-0.9/valid/1bpp-323x240.bmp +1bpp-324x240 =bmptestsuite-0.9/valid/1bpp-324x240.bmp +1bpp-325x240 =bmptestsuite-0.9/valid/1bpp-325x240.bmp +1bpp-326x240 =bmptestsuite-0.9/valid/1bpp-326x240.bmp +1bpp-327x240 =bmptestsuite-0.9/valid/1bpp-327x240.bmp +1bpp-328x240 =bmptestsuite-0.9/valid/1bpp-328x240.bmp +1bpp-329x240 =bmptestsuite-0.9/valid/1bpp-329x240.bmp +1bpp-330x240 =bmptestsuite-0.9/valid/1bpp-330x240.bmp +1bpp-331x240 =bmptestsuite-0.9/valid/1bpp-331x240.bmp +1bpp-332x240 =bmptestsuite-0.9/valid/1bpp-332x240.bmp +1bpp-333x240 =bmptestsuite-0.9/valid/1bpp-333x240.bmp +1bpp-334x240 =bmptestsuite-0.9/valid/1bpp-334x240.bmp +1bpp-335x240 =bmptestsuite-0.9/valid/1bpp-335x240.bmp +1bpp-topdown-320x240 =bmptestsuite-0.9/valid/1bpp-topdown-320x240.bmp +4bpp-1x1 =bmptestsuite-0.9/valid/4bpp-1x1.bmp +4bpp-320x240 =bmptestsuite-0.9/valid/4bpp-320x240.bmp +4bpp-321x240 =bmptestsuite-0.9/valid/4bpp-321x240.bmp +4bpp-322x240 =bmptestsuite-0.9/valid/4bpp-322x240.bmp +4bpp-323x240 =bmptestsuite-0.9/valid/4bpp-323x240.bmp +4bpp-324x240 =bmptestsuite-0.9/valid/4bpp-324x240.bmp +4bpp-325x240 =bmptestsuite-0.9/valid/4bpp-325x240.bmp +4bpp-326x240 =bmptestsuite-0.9/valid/4bpp-326x240.bmp +4bpp-327x240 =bmptestsuite-0.9/valid/4bpp-327x240.bmp +4bpp-topdown-320x240 =bmptestsuite-0.9/valid/4bpp-topdown-320x240.bmp +8bpp-1x1 =bmptestsuite-0.9/valid/8bpp-1x1.bmp +# 8bpp-1x64000 =bmptestsuite-0.9/valid/8bpp-1x64000.bmp +# due to hardware limitation +8bpp-320x240 =bmptestsuite-0.9/valid/8bpp-320x240.bmp +8bpp-321x240 =bmptestsuite-0.9/valid/8bpp-321x240.bmp +8bpp-322x240 =bmptestsuite-0.9/valid/8bpp-322x240.bmp +8bpp-323x240 =bmptestsuite-0.9/valid/8bpp-323x240.bmp +8bpp-colorsimportant-two =bmptestsuite-0.9/valid/8bpp-colorsimportant-two.bmp +8bpp-colorsused-zero =bmptestsuite-0.9/valid/8bpp-colorsused-zero.bmp +8bpp-topdown-320x240 =bmptestsuite-0.9/valid/8bpp-topdown-320x240.bmp +24bpp-1x1 =bmptestsuite-0.9/valid/24bpp-1x1.bmp +24bpp-320x240 =bmptestsuite-0.9/valid/24bpp-320x240.bmp +24bpp-321x240 =bmptestsuite-0.9/valid/24bpp-321x240.bmp +24bpp-322x240 =bmptestsuite-0.9/valid/24bpp-322x240.bmp +24bpp-323x240 =bmptestsuite-0.9/valid/24bpp-323x240.bmp +24bpp-imagesize-zero =bmptestsuite-0.9/valid/24bpp-imagesize-zero.bmp +24bpp-topdown-320x240 =bmptestsuite-0.9/valid/24bpp-topdown-320x240.bmp +32bpp-1x1 =bmptestsuite-0.9/valid/32bpp-1x1.bmp +32bpp-320x240 =bmptestsuite-0.9/valid/32bpp-320x240.bmp +32bpp-888-optimalpalette-320x240=bmptestsuite-0.9/valid/32bpp-888-optimalpalette-320x240.bmp +32bpp-101110-320x240 =bmptestsuite-0.9/valid/32bpp-101110-320x240.bmp +32bpp-optimalpalette-320x240 =bmptestsuite-0.9/valid/32bpp-optimalpalette-320x240.bmp +32bpp-topdown-320x240 =bmptestsuite-0.9/valid/32bpp-topdown-320x240.bmp +555-1x1 =bmptestsuite-0.9/valid/555-1x1.bmp +555-320x240 =bmptestsuite-0.9/valid/555-320x240.bmp +555-321x240 =bmptestsuite-0.9/valid/555-321x240.bmp +565-1x1 =bmptestsuite-0.9/valid/565-1x1.bmp +565-320x240 =bmptestsuite-0.9/valid/565-320x240.bmp +565-320x240-topdown =bmptestsuite-0.9/valid/565-320x240-topdown.bmp +565-321x240 =bmptestsuite-0.9/valid/565-321x240.bmp +565-321x240-topdown =bmptestsuite-0.9/valid/565-321x240-topdown.bmp +565-322x240 =bmptestsuite-0.9/valid/565-322x240.bmp +565-322x240-topdown =bmptestsuite-0.9/valid/565-322x240-topdown.bmp +rle4-absolute-320x240 =bmptestsuite-0.9/valid/rle4-absolute-320x240.bmp +rle4-alternate-320x240 =bmptestsuite-0.9/valid/rle4-alternate-320x240.bmp +rle4-delta-320x240 =bmptestsuite-0.9/valid/rle4-delta-320x240.bmp +rle4-encoded-320x240 =bmptestsuite-0.9/valid/rle4-encoded-320x240.bmp +# rle8-64000x1 =bmptestsuite-0.9/valid/rle8-64000x1.bmp +# due to hardware limitation +rle8-absolute-320x240 =bmptestsuite-0.9/valid/rle8-absolute-320x240.bmp +rle8-blank-160x120 =bmptestsuite-0.9/valid/rle8-blank-160x120.bmp +rle8-delta-320x240 =bmptestsuite-0.9/valid/rle8-delta-320x240.bmp +rle8-encoded-320x240 =bmptestsuite-0.9/valid/rle8-encoded-320x240.bmp + +[template] +op0=buf = al_create_bitmap(640, 480) +op1=al_set_target_bitmap(buf) +op2=al_clear_to_color(#ff00ff) +op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op4=al_draw_bitmap(bmp, 0, 0, 0) +op5=al_set_target_bitmap(target) +op6=al_draw_bitmap(buf, 0, 0, 0) + +[test bmpsuite 1bpp-1x1] +extend=template +bmp=1bpp-1x1 +hash=c6c3a3fd + +[test bmpsuite 1bpp-320x240] +extend=template +bmp=1bpp-320x240 +hash=6050ef7d + +[test bmpsuite 1bpp-320x240-color] +extend=template +bmp=1bpp-320x240-color +hash=9a3e4ae9 + +[test bmpsuite 1bpp-320x240-overlappingcolor] +extend=template +bmp=1bpp-320x240-overlappingcolor +hash=9ebc16c5 + +[test bmpsuite 1bpp-323x240] +extend=template +bmp=1bpp-323x240 +hash=a9d171bd + +[test bmpsuite 1bpp-324x240] +extend=template +bmp=1bpp-324x240 +hash=c83ad13d + +[test bmpsuite 1bpp-325x240] +extend=template +bmp=1bpp-325x240 +hash=d20c6b6d + +[test bmpsuite 1bpp-326x240] +extend=template +bmp=1bpp-326x240 +hash=9cfd0a6d + +[test bmpsuite 1bpp-327x240] +extend=template +bmp=1bpp-327x240 +hash=2c50ba1d + +[test bmpsuite 1bpp-328x240] +extend=template +bmp=1bpp-328x240 +hash=c8ba84ed + +[test bmpsuite 1bpp-329x240] +extend=template +bmp=1bpp-329x240 +hash=5763db1d + +[test bmpsuite 1bpp-330x240] +extend=template +bmp=1bpp-330x240 +hash=6ab7842d + +[test bmpsuite 1bpp-331x240] +extend=template +bmp=1bpp-331x240 +hash=adbad50d + +[test bmpsuite 1bpp-332x240] +extend=template +bmp=1bpp-332x240 +hash=c6ae5b5d + +[test bmpsuite 1bpp-333x240] +extend=template +bmp=1bpp-333x240 +hash=cd269f7d + +[test bmpsuite 1bpp-334x240] +extend=template +bmp=1bpp-334x240 +hash=76d2f81d + +[test bmpsuite 1bpp-335x240] +extend=template +bmp=1bpp-335x240 +hash=74e8607d + +[test bmpsuite 1bpp-topdown-320x240] +extend=template +bmp=1bpp-topdown-320x240 +hash=6050ef7d + +[test bmpsuite 4bpp-1x1] +extend=template +bmp=4bpp-1x1 +hash=5413ad0c + +[test bmpsuite 4bpp-320x240] +extend=template +bmp=4bpp-320x240 +hash=14e6fb1d + +[test bmpsuite 4bpp-321x240] +extend=template +bmp=4bpp-321x240 +hash=05a7bc6d + +[test bmpsuite 4bpp-322x240] +extend=template +bmp=4bpp-322x240 +hash=4d583135 + +[test bmpsuite 4bpp-323x240] +extend=template +bmp=4bpp-323x240 +hash=69d41ddd + +[test bmpsuite 4bpp-324x240] +extend=template +bmp=4bpp-324x240 +hash=97b402cd + +[test bmpsuite 4bpp-325x240] +extend=template +bmp=4bpp-325x240 +hash=e54ba235 + +[test bmpsuite 4bpp-326x240] +extend=template +bmp=4bpp-326x240 +hash=f0ca000d + +[test bmpsuite 4bpp-327x240] +extend=template +bmp=4bpp-327x240 +hash=c7c5e10d + +[test bmpsuite 4bpp-topdown-320x240] +extend=template +bmp=4bpp-topdown-320x240 +hash=14e6fb1d + +[test bmpsuite 8bpp-1x1] +extend=template +bmp=8bpp-1x1 +hash=5413ad0c + +[test bmpsuite 8bpp-320x240] +extend=template +bmp=8bpp-320x240 +hash=14e6fb1d + +[test bmpsuite 8bpp-321x240] +extend=template +bmp=8bpp-321x240 +hash=05a7bc6d + +[test bmpsuite 8bpp-322x240] +extend=template +bmp=8bpp-322x240 +hash=4d583135 + +[test bmpsuite 8bpp-323x240] +extend=template +bmp=8bpp-323x240 +hash=69d41ddd + +[test bmpsuite 8bpp-colorsimportant-two] +extend=template +bmp=8bpp-colorsimportant-two +hash=14e6fb1d + +[test bmpsuite 8bpp-colorsused-zero] +extend=template +bmp=8bpp-colorsused-zero +hash=14e6fb1d + +[test bmpsuite 8bpp-topdown-320x240] +extend=template +bmp=8bpp-topdown-320x240 +hash=14e6fb1d + +[test bmpsuite 24bpp-1x1] +extend=template +bmp=24bpp-1x1 +hash=5413ad0c + +[test bmpsuite 24bpp-320x240] +extend=template +bmp=24bpp-320x240 +hash=14e6fb1d + +[test bmpsuite 24bpp-321x240] +extend=template +bmp=24bpp-321x240 +hash=05a7bc6d + +[test bmpsuite 24bpp-322x240] +extend=template +bmp=24bpp-322x240 +hash=4d583135 + +[test bmpsuite 24bpp-323x240] +extend=template +bmp=24bpp-323x240 +hash=69d41ddd + +[test bmpsuite 24bpp-imagesize-zero] +extend=template +bmp=24bpp-imagesize-zero +hash=14e6fb1d + +[test bmpsuite 24bpp-topdown-320x240] +extend=template +bmp=24bpp-topdown-320x240 +hash=14e6fb1d + +[test bmpsuite 32bpp-1x1] +extend=template +bmp=32bpp-1x1 +hash=5413ad0c + +[test bmpsuite 32bpp-320x240] +extend=template +bmp=32bpp-320x240 +hash=14e6fb1d + +[test bmpsuite 32bpp-888-optimalpalette-320x240] +extend=template +bmp=32bpp-888-optimalpalette-320x240 +hash=14e6fb1d + +[test bmpsuite 32bpp-101110-320x240] +extend=template +bmp=32bpp-101110-320x240 +hash=14e6fb1d + +[test bmpsuite 32bpp-optimalpalette-320x240] +extend=template +bmp=32bpp-optimalpalette-320x240 +hash=14e6fb1d + +[test bmpsuite 32bpp-topdown-320x240] +extend=template +bmp=32bpp-topdown-320x240 +hash=14e6fb1d + +[test bmpsuite 555-1x1] +extend=template +bmp=555-1x1 +hash=5413ad0c + +[test bmpsuite 555-320x240] +extend=template +bmp=555-320x240 +hash=14e6fb1d + +[test bmpsuite 555-321x240] +extend=template +bmp=555-321x240 +hash=05a7bc6d + +[test bmpsuite 565-1x1] +extend=template +bmp=565-1x1 +hash=5413ad0c + +[test bmpsuite 565-320x240] +extend=template +bmp=565-320x240 +hash=14e6fb1d + +[test bmpsuite 565-320x240-topdown] +extend=template +bmp=565-320x240-topdown +hash=14e6fb1d + +[test bmpsuite 565-321x240] +extend=template +bmp=565-321x240 +hash=05a7bc6d + +[test bmpsuite 565-321x240-topdown] +extend=template +bmp=565-321x240-topdown +hash=05a7bc6d + +[test bmpsuite 565-322x240] +extend=template +bmp=565-322x240 +hash=4d583135 + +[test bmpsuite 565-322x240-topdown] +extend=template +bmp=565-322x240-topdown +hash=4d583135 + +[test bmpsuite rle4-absolute-320x240] +extend=template +bmp=rle4-absolute-320x240 +hash=14e6fb1d + +[test bmpsuite rle4-alternate-320x240] +extend=template +bmp=rle4-alternate-320x240 +hash=bcf6e8cd + +[test bmpsuite rle4-delta-320x240] +extend=template +bmp=rle4-delta-320x240 +hash=ef879d9d + +[test bmpsuite rle4-encoded-320x240] +extend=template +bmp=rle4-encoded-320x240 +hash=14e6fb1d + +[test bmpsuite rle8-absolute-320x240] +extend=template +bmp=rle8-absolute-320x240 +hash=14e6fb1d + +[test bmpsuite rle8-blank-160x120] +extend=template +bmp=rle8-blank-160x120 +hash=6a451dc5 + +[test bmpsuite rle8-delta-320x240] +extend=template +bmp=rle8-delta-320x240 +hash=ef879d9d + +[test bmpsuite rle8-encoded-320x240] +extend=template +bmp=rle8-encoded-320x240 +hash=14e6fb1d diff --git a/allegro/tests/manual_bmpsuite3.ini b/allegro/tests/manual_bmpsuite3.ini new file mode 100644 index 00000000..c3207960 --- /dev/null +++ b/allegro/tests/manual_bmpsuite3.ini @@ -0,0 +1,35 @@ +# Test BMP loader with images from this source: +# http://wvnvms.wvnet.edu/vmswww/bmp.html (dead link) +# http://pxd.me/dompdf/www/test/image_bmp.html + +[bitmaps] +test32bfv4 = wvnet/test32bfv4.bmp +test32v5 = wvnet/test32v5.bmp +# test4os2v2= wvnet/test4os2v2.bmp +# OS/2 v2 headers not supported +trans = wvnet/trans.bmp + +[template] +op0=buf = al_create_bitmap(640, 480) +op1=al_set_target_bitmap(buf) +op2=al_clear_to_color(#ff00ff) +op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op4=al_draw_bitmap(bmp, 0, 0, 0) +op5=al_set_target_bitmap(target) +op6=al_draw_bitmap(buf, 0, 0, 0) + +[test bmpsuite test32bfv4] +extend=template +bmp=test32bfv4 +# This image really *is* fully transparent. +hash=6a451dc5 + +[test bmpsuite test32v5] +extend=template +bmp=test32v5 +hash=f5c38217 + +[test bmpsuite trans] +extend=template +bmp=trans +hash=da824687 diff --git a/allegro/tests/manual_bmpsuite4.ini b/allegro/tests/manual_bmpsuite4.ini new file mode 100644 index 00000000..8b9a272f --- /dev/null +++ b/allegro/tests/manual_bmpsuite4.ini @@ -0,0 +1,394 @@ +# Test BMP loader with images from this source: +# http://entropymine.com/jason/bmpsuite/ (version 2) + +[bitmaps] +# --- Common ("good") bmp files +gpal1bg = bmpsuite2/g/pal1bg.bmp +gpal1 = bmpsuite2/g/pal1.bmp +gpal1wb = bmpsuite2/g/pal1wb.bmp +gpal4 = bmpsuite2/g/pal4.bmp +gpal4gs = bmpsuite2/g/pal4gs.bmp +gpal4rle = bmpsuite2/g/pal4rle.bmp +gpal8-0 = bmpsuite2/g/pal8-0.bmp +gpal8 = bmpsuite2/g/pal8.bmp +gpal8gs = bmpsuite2/g/pal8gs.bmp +gpal8nonsquare = bmpsuite2/g/pal8nonsquare.bmp +gpal8os2 = bmpsuite2/g/pal8os2.bmp +gpal8rle = bmpsuite2/g/pal8rle.bmp +gpal8topdown = bmpsuite2/g/pal8topdown.bmp +gpal8v4 = bmpsuite2/g/pal8v4.bmp +gpal8v5 = bmpsuite2/g/pal8v5.bmp +gpal8w124 = bmpsuite2/g/pal8w124.bmp +gpal8w125 = bmpsuite2/g/pal8w125.bmp +gpal8w126 = bmpsuite2/g/pal8w126.bmp +grgb16-565 = bmpsuite2/g/rgb16-565.bmp +grgb16-565pal = bmpsuite2/g/rgb16-565pal.bmp +grgb16 = bmpsuite2/g/rgb16.bmp +grgb24 = bmpsuite2/g/rgb24.bmp +grgb24pal = bmpsuite2/g/rgb24pal.bmp +grgb32 = bmpsuite2/g/rgb32.bmp +grgb32bf = bmpsuite2/g/rgb32bf.bmp + +# --- Obscure ("questionable") bmp files +qpal1p1 = bmpsuite2/q/pal1p1.bmp +qpal2 = bmpsuite2/q/pal2.bmp +qpal2color = bmpsuite2/q/pal2color.bmp +qpal8os2-sz = bmpsuite2/q/pal8os2-sz.bmp +qpal8os2v2-40sz = bmpsuite2/q/pal8os2v2-40sz.bmp +qrgb24lprof = bmpsuite2/q/rgb24lprof.bmp +qrgb24prof = bmpsuite2/q/rgb24prof.bmp +qrgb24largepal = bmpsuite2/q/rgb24largepal.bmp +qpal8oversizepal = bmpsuite2/q/pal8oversizepal.bmp +qpal8os2sp = bmpsuite2/q/pal8os2sp.bmp +qrgb16-231 = bmpsuite2/q/rgb16-231.bmp +qrgb16-3103 = bmpsuite2/q/rgb16-3103.bmp +qrgb32-111110 = bmpsuite2/q/rgb32-111110.bmp +qrgb32-7187 = bmpsuite2/q/rgb32-7187.bmp +qrgba16-1924 = bmpsuite2/q/rgba16-1924.bmp +qrgba16-4444 = bmpsuite2/q/rgba16-4444.bmp +qrgba32-61754 = bmpsuite2/q/rgba32-61754.bmp +qrgba32-81284 = bmpsuite2/q/rgba32-81284.bmp +qrgba32 = bmpsuite2/q/rgba32.bmp + +# activates the alpha channel detection hack +# output is not "correct", but it is what we want +qrgb32fakealpha = bmpsuite2/q/rgb32fakealpha.bmp + +# multiple "correct" outputs, we choose palette 0 to fill empty spaces +# note: output of the "rlecut" variants is intended to have purple lines +qpal4rletrns = bmpsuite2/q/pal4rletrns.bmp +qpal8rletrns = bmpsuite2/q/pal8rletrns.bmp +qpal4rlecut = bmpsuite2/q/pal4rlecut.bmp +qpal8rlecut = bmpsuite2/q/pal8rlecut.bmp + +# allegro bails on unrecognized header sizes +#qrgb32h52 = bmpsuite2/q/rgb32h52.bmp +#qrgba32h56 = bmpsuite2/q/rgba32h56.bmp + +# OS2v2 format not supported +#qpal8os2v2-16 = bmpsuite2/q/pal8os2v2-16.bmp +#qpal8os2v2 = bmpsuite2/q/pal8os2v2.bmp +#qpal8os2v2-sz = bmpsuite2/q/pal8os2v2-sz.bmp + +# BI_ALHPABITFIELDS not supported +#qrgba32abf = bmpsuite2/q/rgba32abf.bmp + +# JPEG/PNG compression not supported +#qrgb24jpeg = bmpsuite2/q/rgb24jpeg.bmp +#qrgb24png = bmpsuite2/q/rgb24png.bmp + +# --- Invalid ("bad") bmp files + +# Ensure empty palette entries are consistently colored +bpal8badindex = bmpsuite2/b/pal8badindex.bmp + +# Ensure unspecified pixels are consistently colored +bshortfile = bmpsuite2/b/shortfile.bmp + +# Ensure zero-length bitfields are consistently handled +brgb16-880 = bmpsuite2/b/rgb16-880.bmp + +# Ensure RLE top-down images remain working +brletopdown = bmpsuite2/b/rletopdown.bmp + +[template] +op0=al_draw_bitmap(bmp, 0, 0, 0) + +[template_premul] +op0=bmp = al_load_bitmap(filename) +op1=al_draw_bitmap(bmp, 0, 0, 0) + +[test bmpsuite2 gpal1bg] +extend=template +bmp=gpal1bg +hash=0d098169 + +[test bmpsuite2 gpal1] +extend=template +bmp=gpal1 +hash=0a1884dd + +[test bmpsuite2 gpal1wb] +extend=template +bmp=gpal1wb +hash=0a1884dd + +[test bmpsuite2 gpal4] +extend=template +bmp=gpal4 +hash=a1f65579 + +[test bmpsuite2 gpal4gs] +extend=template +bmp=gpal4gs +hash=c17d0e68 + +[test bmpsuite2 gpal4rle] +extend=template +bmp=gpal4rle +hash=a1f65579 + +[test bmpsuite2 gpal8-0] +extend=template +bmp=gpal8-0 +hash=3f98d122 + +[test bmpsuite2 gpal8] +extend=template +bmp=gpal8 +hash=3f98d122 + +[test bmpsuite2 gpal8gs] +extend=template +bmp=gpal8gs +hash=644b7fcb + +[test bmpsuite2 gpal8nonsquare] +extend=template +bmp=gpal8nonsquare +hash=92123f8e + +[test bmpsuite2 gpal8os2] +extend=template +bmp=gpal8os2 +hash=3f98d122 + +[test bmpsuite2 gpal8rle] +extend=template +bmp=gpal8rle +hash=3f98d122 + +[test bmpsuite2 gpal8topdown] +extend=template +bmp=gpal8topdown +hash=3f98d122 + +[test bmpsuite2 gpal8v4] +extend=template +bmp=gpal8v4 +hash=3f98d122 + +[test bmpsuite2 gpal8v5] +extend=template +bmp=gpal8v5 +hash=3f98d122 + +[test bmpsuite2 gpal8w124] +extend=template +bmp=gpal8w124 +hash=0a409ae9 + +[test bmpsuite2 gpal8w125] +extend=template +bmp=gpal8w125 +hash=57e4822b + +[test bmpsuite2 gpal8w126] +extend=template +bmp=gpal8w126 +hash=226f73e5 + +[test bmpsuite2 grgb16-565] +extend=template +bmp=grgb16-565 +hash=250c9fae + +[test bmpsuite2 grgb16-565pal] +extend=template +bmp=grgb16-565pal +hash=250c9fae + +[test bmpsuite2 grgb16] +extend=template +bmp=grgb16 +hash=7af81b6e + +[test bmpsuite2 grgb24] +extend=template +bmp=grgb24 +hash=68c13e2b + +[test bmpsuite2 grgb24pal] +extend=template +bmp=grgb24pal +hash=68c13e2b + +[test bmpsuite2 grgb32] +extend=template +bmp=grgb32 +hash=68c13e2b + +[test bmpsuite2 grgb32bf] +extend=template +bmp=grgb32bf +hash=68c13e2b + +[test bmpsuite2 qpal1p1] +extend=template +bmp=qpal1p1 +hash=87931dc5 + +[test bmpsuite2 qpal2] +extend=template +bmp=qpal2 +hash=e9f2003f + +[test bmpsuite2 qpal2color] +extend=template +bmp=qpal2color +hash=441e2930 + +[test bmpsuite2 qpal8os2-sz] +extend=template +bmp=qpal8os2-sz +hash=3f98d122 + +[test bmpsuite2 qpal8os2v2-40sz] +extend=template +bmp=qpal8os2v2-40sz +hash=3f98d122 + +[test bmpsuite2 qrgb24lprof] +extend=template +bmp=qrgb24lprof +hash=68c13e2b + +[test bmpsuite2 qrgb24prof] +extend=template +bmp=qrgb24prof +hash=68c13e2b + +[test bmpsuite2 qrgb24largepal] +extend=template +bmp=qrgb24largepal +hash=68c13e2b + +[test bmpsuite2 qpal8oversizepal] +extend=template +bmp=qpal8oversizepal +hash=3f98d122 + +[test bmpsuite2 qpal8os2sp] +extend=template +bmp=qpal8os2sp +hash=3f98d122 + +[test bmpsuite2 qrgb16-231] +extend=template +bmp=qrgb16-231 +hash=ac77a449 + +[test bmpsuite2 qrgb16-3103] +extend=template +bmp=qrgb16-3103 +hash=6c258348 + +[test bmpsuite2 qrgb32-111110] +extend=template +bmp=qrgb32-111110 +hash=84580522 + +[test bmpsuite2 qrgb32-7187] +extend=template +bmp=qrgb32-7187 +hash=dc097ec5 + +[test bmpsuite2 qrgba16-1924] +extend=template +bmp=qrgba16-1924 +hash=1e8da1d6 + +[test bmpsuite2 qrgba16-4444] +extend=template +bmp=qrgba16-4444 +hash=e76fc7c2 + +[test bmpsuite2 qrgba32-61754] +extend=template +bmp=qrgba32-61754 +hash=26e36575 + +[test bmpsuite2 qrgba32-81284] +extend=template +bmp=qrgba32-81284 +hash=d90b3b69 + +[test bmpsuite2 qrgba32] +extend=template +bmp=qrgba32 +hash=8a20727d + +[test bmpsuite2 qrgb32fakealpha] +extend=template +bmp=qrgb32fakealpha +hash=f645af5b + +[test bmpsuite2 qpal4rletrns] +extend=template +bmp=qpal4rletrns +hash=a52bd5f5 + +[test bmpsuite2 qpal8rletrns] +extend=template +bmp=qpal8rletrns +hash=66933b5a + +[test bmpsuite2 qpal4rlecut] +extend=template +bmp=qpal4rlecut +hash=f6a25391 + +[test bmpsuite2 qpal8rlecut] +extend=template +bmp=qpal8rlecut +hash=828ee98c + +[test bmpsuite2 bpal8badindex] +extend=template +bmp=bpal8badindex +hash=eb1512c3 + +[test bmpsuite2 bshortfile] +extend=template +bmp=bshortfile +hash=76ba6cd6 + +[test bmpsuite2 brgb16-880] +extend=template +bmp=brgb16-880 +hash=db0c5b9c + +[test bmpsuite2 brletopdown] +extend=template +bmp=brletopdown +hash=3f98d122 + +[test bmpsuite2 qrgba16-1924_premul] +extend=template_premul +filename=bmpsuite2/q/rgba16-1924.bmp +hash=e2f9488d + +[test bmpsuite2 qrgba16-4444_premul] +extend=template_premul +filename=bmpsuite2/q/rgba16-4444.bmp +hash=463e4ca9 + +[test bmpsuite2 qrgba32-61754_premul] +extend=template_premul +filename=bmpsuite2/q/rgba32-61754.bmp +hash=d7e0e0e2 + +[test bmpsuite2 qrgba32-81284_premul] +extend=template_premul +filename=bmpsuite2/q/rgba32-81284.bmp +hash=cd6f937e + +[test bmpsuite2 qrgba32_premul] +extend=template_premul +filename=bmpsuite2/q/rgba32.bmp +hash=b4aca763 + +[test bmpsuite2 qrgb32fakealpha_premul] +extend=template_premul +filename=bmpsuite2/q/rgb32fakealpha.bmp +hash=5cf7f0d4 diff --git a/allegro/tests/test_backbuffer.ini b/allegro/tests/test_backbuffer.ini new file mode 100644 index 00000000..3064d7a1 --- /dev/null +++ b/allegro/tests/test_backbuffer.ini @@ -0,0 +1,111 @@ +[bitmaps] +allegro=../examples/data/allegro.pcx +mysha=../examples/data/mysha.pcx + +# Test backbuffer to backbuffer. + +# Self-blitting support is not scheduled for 5.0.0. + +#[test bb2bb] +#op0=al_draw_bitmap(allegro, 0, 0, 0) +#op1=al_draw_bitmap_region(target, 0, 0, 320, 200, 100, 100, flags) +#flags=0 +#hash=BROKEN + +#[test bb2bb hflip] +#extend=test bb2bb +#flags=ALLEGRO_FLIP_HORIZONTAL +#hash=BROKEN + +#[test bb2bb vflip] +#extend=test bb2bb +#flags=ALLEGRO_FLIP_VERTICAL +#hash=BROKEN + +#[test bb2bb vhflip] +#extend=test bb2bb +#flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +#hash=BROKEN + + +# Test drawing backbuffer to non-backbuffer bitmaps. + +[test bbsrc] +op0=al_draw_bitmap(mysha, 0, 0, 0) +op1=bmp = al_create_bitmap(400, 300) +op2=al_set_target_bitmap(bmp) +op3=al_clear_to_color(yellow) +op4=al_draw_bitmap(target, 0, 0, flags) +op5=al_set_target_bitmap(target) +op6=al_draw_bitmap(bmp, 200, 150, 0) +flags=0 +hash=a22aae19 + +[test bbsrc translate] +extend=test bbsrc +op4=al_draw_bitmap(target, 160, 100, flags) +hash=9cf6fa5d + +[test bbsrc outside] +extend=test bbsrc +op4=al_draw_bitmap(target, -160, -100, flags) +hash=882edf64 + +# In Allegro 5.0.0, tinting as well as blending is ignored when the +# source bitmap is the screen (and locking is not used). + +[test bbsrc tint] +skip_on_xvfb=true +extend=test bbsrc +op4=al_draw_tinted_bitmap(target, #008000, 0, 0, flags) +hash=a47a96d4 +hash_hw=a22aae19 + +# Support for transforming the back-buffer is not on the feature list +# for 5.0.0. + +#[test bbsrc hflip] +#extend=test bbsrc +#flags=ALLEGRO_FLIP_HORIZONTAL + +#[test bbsrc vflip] +#extend=test bbsrc +#flags=ALLEGRO_FLIP_VERTICAL + +#[test bbsrc vhflip] +#extend=test bbsrc +#flags=ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL + + +#[test bbsrc scale] +#extend=test bbsrc +#op4=al_draw_scaled_bitmap(target, 0, 0, 320, 200, 0, 0, 640, 480, flags) + +#[test bbsrc scale hflip] +#extend=test bbsrc scale +#flags=ALLEGRO_FLIP_HORIZONTAL + +#[test bbsrc scale vflip] +#extend=test bbsrc scale +#flags=ALLEGRO_FLIP_VERTICAL + +#[test bbsrc scale vhflip] +#extend=test bbsrc scale +#flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL + + +#[test bbsrc rotate] +#extend=test bbsrc +#op4=al_draw_rotated_bitmap(target, 0, 0, 0, 0, 0.2, flags) + +#[test bbsrc rotate hflip] +#extend=test bbsrc rotate +#flags=ALLEGRO_FLIP_HORIZONTAL + +#[test bbsrc rotate vflip] +#extend=test bbsrc rotate +#flags=ALLEGRO_FLIP_VERTICAL + +#[test bbsrc rotate vhflip] +#extend=test bbsrc rotate +#flags=ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL diff --git a/allegro/tests/test_bitmaps.ini b/allegro/tests/test_bitmaps.ini new file mode 100644 index 00000000..696b6f88 --- /dev/null +++ b/allegro/tests/test_bitmaps.ini @@ -0,0 +1,444 @@ +[bitmaps] +mysha=../examples/data/mysha.pcx +allegro=../examples/data/allegro.pcx + +[test blit] +op0=al_clear_to_color(red) +op1=al_draw_bitmap(mysha, 37, 47, flags) +flags=0 +hash=dabe9c74 + +[test blit vflip] +extend=test blit +flags=ALLEGRO_FLIP_VERTICAL +hash=ee8c112c + +[test blit hflip] +extend=test blit +flags=ALLEGRO_FLIP_HORIZONTAL +hash=7e343e90 + +[test blit vhflip] +extend=test blit +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +hash=72d59a18 + +[test region] +op0=al_clear_to_color(red) +op1=al_draw_bitmap(mysha, 37, 47, flags) +op2=al_draw_bitmap_region(mysha, 111, 51, 77, 99, 37, 47, flags) +flags=0 +hash=8e5335ae + +[test region hflip] +extend=test region +flags=ALLEGRO_FLIP_HORIZONTAL +hash=569472fc + +[test region vflip] +extend=test region +flags=ALLEGRO_FLIP_VERTICAL +hash=f479bb0d + +[test region vhflip] +extend=test region +flags=ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL +hash=cadc1987 + +[test scale min] +op0=al_clear_to_color(red) +op1=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 11, 17, 77, 99, flags) +flags=0 +hash=ae4b4301 + +[test scale min vflip] +extend=test scale min +flags=ALLEGRO_FLIP_VERTICAL +hash=973bd6bd +sig=DLLLLLLLLELLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test scale min hflip] +extend=test scale min +flags=ALLEGRO_FLIP_HORIZONTAL +hash=807e7ae5 + +[test scale min vhflip] +extend=test scale min +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +hash=5c2b54ad + +[test scale max] +op0=al_clear_to_color(blue) +op1=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 11, 17, 611, 415, flags) +flags=0 +hash=1ede4355 +sig=EEEEEEDDCEFGPGEEDDFKjsebEDDGwvsVaEEDHvcgQPKDDHogTKMFEE4EaNLN9DE22254I222DDDDDDDDD + +[test scale max hflip] +extend=test scale max +flags=ALLEGRO_FLIP_HORIZONTAL +hash=99b05f69 +sig=CDEEEEEEECDEMFRFFECDEairgGFDEIZburwFDEMOTlrvGDECLLUeqGDD2HMNaA3222385222DDDDDDDDD + +[test scale max vflip] +extend=test scale max +flags=ALLEGRO_FLIP_VERTICAL +hash=d9f0a6ea +sig=22221222222VM2K222GmePLLDEEJrmeRQJEDHuuoTUHDDFlovXaEDDEFPsgVEDCEEEEEEEDCIIIIIIHHH + +[test scale max2] +op0=al_clear_to_color(aqua) +op1=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 320, 240, dw, dh, flags) +dw=600 +dh=600 +flags=0 +hash=edba302f +sig=ggggggggggggggggggggggggggggggggggggggggXPQQQggggQEEEEggggQEEFFggggQFOtsggggQFomt + +[test scale max2 vflip] +extend=test scale max2 +flags=ALLEGRO_FLIP_VERTICAL +hash=e6bc6d52 +sig=ggggggggggggggggggggggggggggggggggggggggTJJJJggggJ222BggggJ22LGggggJ1baOggggVIkgP + +[test scale max2 negy hflip] +extend=test scale max2 +dh=-600 +flags=ALLEGRO_FLIP_HORIZONTAL +hash=e6bc6d52 +sig=ggggPDEEYggggPCDEXggggPDDEDggggOCDDEggggYTTUUgggggggggggggggggggggggggggggggggggg + +[test scale max2 negy vhflip] +extend=test scale max2 +dh=-600 +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +hash=cf1b15e6 +sig=ggggQEEDMggggQDE7HggggJ1211ggggJ2222ggggWPPPPgggggggggggggggggggggggggggggggggggg + +[test scale max2 negx vflip] +extend=test scale max2 +dw=-600 +flags=ALLEGRO_FLIP_VERTICAL +hash=635d9cf1 +sig=ggggggggggggggggggggggggggggggggggggJJJJWgggg9222PggggHK22PggggOab1PggggQgkIYgggg + +[test scale max2 negx negy] +extend=test scale max2 +dw=-600 +dh=-600 +sig=tmnFUggggrrIFUggggFFEEUggggEEEEUggggUUUTbgggggggggggggggggggggggggggggggggggggggg + +[test scale max2 negx negy hflip] +extend=test scale max2 negx negy +flags=ALLEGRO_FLIP_HORIZONTAL +sig=ZEEDTggggXEDCTggggDEDCTggggEDDCTggggUTTTagggggggggggggggggggggggggggggggggggggggg + +[test scale max2 negx negy vflip] +extend=test scale max2 negx negy +flags=ALLEGRO_FLIP_VERTICAL +sig=QgkHYggggOaZ2PggggHH22Pgggg9222PggggPPPPZgggggggggggggggggggggggggggggggggggggggg + +[test scale max2 negx negy vhflip] +extend=test scale max2 negx negy +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +sig=MCEEUggggG7EDUgggg1121Pgggg2222PggggPPPPZgggggggggggggggggggggggggggggggggggggggg + +[test rotate] +op0=al_clear_to_color(purple) +op1=al_draw_rotated_bitmap(allegro, 50, 50, 320, 240, theta, flags) +op2=al_draw_pixel(320, 240, cyan) +theta=0 +flags=0 +hash=435c5d10 + +[test rotate 0.5] +extend=test rotate +theta=0.5 +hash=f03d3240 +sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLULLLLLLLLRKLLLLLLLQaaTLLLLOKSOkRLLLLGQXTLLLLLLINOL + +[test rotate 1.0] +extend=test rotate +theta=1.0 +hash=78bf9ff5 +sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLkLLLLLLLIRLLLLLLOLcLLLLLLLOQkLLLLLLGaXeLLLLLLSinLL + +[test rotate 1.0 vflip] +extend=test rotate 1.0 +flags=ALLEGRO_FLIP_VERTICAL +hash=5b75eca4 +sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLSNLLLLLLYTPHLLLLLLeVNLLLLLLL+WMLLLLLLhgNLL + +[test rotate -1.0] +extend=test rotate +theta=-1.0 +hash=d86fa86f +sig=LLLLLVmMLLLLLLYhNNLLLLKlUOLLLLLUdbHLLLLLTOLLLLLLLbLMLLLLLLLNLLLLLLLLLLLLLLLLLLLLL + +[test rotate -2.0] +extend=test rotate +theta=-2.0 +hash=1b5ff6da +sig=LLifZHLLLLLLgUJLLLLLLaYKLLLLLLKfOILLLLLLTJLLLLLLLkLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test rotate -2.0 hflip] +extend=test rotate -2.0 +flags=ALLEGRO_FLIP_HORIZONTAL +hash=0a4986c3 +sig=LLVSMGLLLLLLYSKLLLLLLabULLLLLLPTNMLLLLLLlNLLLLLLLiLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test rotate -2.0 vhflip] +extend=test rotate -2.0 +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +hash=4ddeb3e3 +sig=LLJPcKLLLLLLJcZLLLLLLKWgLLLLLLIYUjLLLLLLNBLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test scaled rotate] +op0=al_clear_to_color(firebrick) +op1=al_draw_scaled_rotated_bitmap(allegro, 50, 50, 320, 240, xscale, yscale, theta, flags) +op2=al_draw_pixel(320, 240, cyan) +xscale=0.25 +yscale=0.25 +theta=0.7854 +flags=0 +hash=dc4ad82d +sig=KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKdKKKKKKKKIKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK + +[test scaled rotate 2] +extend=test scaled rotate +xscale=0.777 +yscale=0.777 +hash=8fc7ecf8 +sig=KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKXKKKKKKKKTKKKKKKKNehKKKKKKHSsgKKKKKKHTgKKKKKKKMKKK + +[test scaled rotate 2 neg] +extend=test scaled rotate +xscale=-0.777 +yscale=-0.777 +hash=96153b14 +sig=KKKLKKKKKKKbTHKKKKKKhxSHKKKKKKheNKKKKKKKVKKKKKKKKXKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK + +[test scaled rotate 3] +extend=test scaled rotate +xscale=1.777 +yscale=1.777 +hash=1d003c91 +sig=KKKKKKKKKKKKKKKKKKKKKKXKKKKKKKllQKKKKKJYQYKKKKKJRTjKKKKNNQYdnKKKOKKQUnZRKKLMYWjgf + +[test scaled rotate 4] +extend=test scaled rotate +xscale=3.0 +yscale=3.0 +theta=-2.5 +hash=31a17741 +sig=nhjTTOLOOlgdgSOJMMNnORRVNKLKOngKDEHKKKTnQYYKKKKMfnifKKKKKThiKKKKKKKWkKKKKKKKKKKKK + +[test scaled rotate 4 vflip] +extend=test scaled rotate 4 +flags=ALLEGRO_FLIP_VERTICAL +hash=055000e8 +sig=NSTPVQYDjMHQMTVWYnGKJKOJPXVFHOOQJKNKKGMONQMKKKKKSOPMKKKKKINNKKKKKKKONKKKKKKKKKKKK + +[test scaled rotate 4 hflip] +extend=test scaled rotate 4 +flags=ALLEGRO_FLIP_HORIZONTAL +hash=59ba09c8 +sig=mbfcaSMKOieel/TMNNQihgcHMONOYfi//DNKLbgclyqKKKLdhcnmKKKKKiflKKKKKKLlhKKKKKKKLKKKK + +[test scaled rotate 4 vhflip] +extend=test scaled rotate 4 +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +hash=e3236edd +sig=NVTZGmClnNRYXVf/ClGPUTPRsDhGJQSLMNlKKKMKNLOKKKKMLNNNKKKKKLLNKKKKKKKNNKKKKKKKKKKKK + +[test scaled rotate 5] +extend=test scaled rotate +xscale=200 +yscale=3.0 +theta=-2 +# It is known that the sw version is slightly offset from the hw version. +hash=e941f051 +sig=LXnQfPMOMKTkQXUGJLKRjmYGKJOKKXnUfQKNKKTkQXVJJKKRjnYCHJKKKYneaQLKKKTkQXWJKKKQimYDN + +[test sub src] +op0=al_clear_to_color(teal) +op1=b = al_create_sub_bitmap(allegro, 3, 40, 310, 70) +op2=al_draw_bitmap(b, 50, 50, flags) +op3=al_draw_rectangle(49.5, 49.5, 360.5, 120.5, black, 1) +flags=0 +hash=ec890555 + +[test sub src hflip] +extend=test sub src +flags=ALLEGRO_FLIP_HORIZONTAL +hash=8862d735 +sig=QNOQQLLLLDGbSVLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test sub src outside] +op0=al_clear_to_color(teal) +op1=al_draw_rectangle(9.5, 9.5, 380.5, 260.5, black, 1) +op2=b = al_create_sub_bitmap(allegro, -50, -50, 370, 250) +op3=al_draw_bitmap(b, 10, 10, flags) +flags=0 +hash=208f7025 + +[test sub src outside hflip] +extend=test sub src outside +flags=ALLEGRO_FLIP_HORIZONTAL +hash=c72f2d45 + +[test sub src outside vflip] +extend=test sub src outside +flags=ALLEGRO_FLIP_VERTICAL +hash=287e0fbd + +[test sub src outside vhflip] +extend=test sub src outside +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +hash=4696783d + +[test sub src outside scale] +op0=al_clear_to_color(teal) +op1=b = al_create_sub_bitmap(allegro, -50, -50, 370, 250) +op2=al_draw_rectangle(9.5, 9.5, 610.5, 410.5, black, 1) +op3=al_draw_scaled_bitmap(b, 0, 0, 370, 250, 10, 10, 600, 400, flags) +flags=0 +hash=ac298a45 +sig=LLLLLLLLLLTNKKNXbkLmnkkffVhLnNOhcv/zLKZPaepcOLKNKZYYNOLMNMMOSOOLONIHHKLNLLLLLLLLL + +[test sub src outside scale hflip] +extend=test sub src outside scale +flags=ALLEGRO_FLIP_HORIZONTAL +hash=898f5e8d +sig=LLLLLLLLLjcRKKKRWLYYheknnjLW/P+UWYkLQ/qgPaRRLLQWZXQJKLNRQOKONQLLMIFGOKNLLLLLLLLLL + +[test sub src outside scale vflip] +extend=test sub src outside scale +flags=ALLEGRO_FLIP_VERTICAL +hash=762b67d5 +sig=LMPLHHMLMLQMHJSWNNLLPMZXYSNLMdMjbdLDLcbOmfgkmLjhTQReegLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test sub src outside scale vhflip] +extend=test sub src outside scale +flags=ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL +hash=7c95685d +sig=LNJGGONOLNNVMMGKPLMUfdWRKJLh/hcUaYVLmkekXhYjLfeYVPYjkLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test sub dest] +op0=b = al_create_sub_bitmap(target, 35, 37, 103, 104) +op1=al_set_target_bitmap(b) +op2=al_draw_bitmap(allegro, 0, 0, 0) +hash=1127286c + +[test sub dest pixel] +op0=b = al_create_sub_bitmap(target, 35, 37, 103, 104) +op1=al_set_target_bitmap(b) +op2=al_draw_pixel(0.5, 0.5, red) +op3=al_put_pixel(1, 0, limegreen) +op4=al_draw_pixel(14.5, 17.5, red) +op5=al_put_pixel(15, 17, limegreen) +op6=al_draw_pixel(24.5, 27.5, red) +op7=al_put_pixel(25, 27, limegreen) +hash=b4d84cb9 +hash_hw=663b41cf +sig_hw=000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +[test subsub dest] +op0=al_clear_to_color(tan) +op1=b1 = al_create_sub_bitmap(target, 70, 90, 200, 200) +op2=al_set_target_bitmap(b1) +op3=al_clear_to_color(seagreen) +op4=b2 = al_create_sub_bitmap(b1, -50, -50, 200, 200) +op5=al_set_target_bitmap(b2) +op6=al_clear_to_color(royalblue) +op7=al_draw_bitmap(allegro, 10, 10, 0) +hash=066a6e10 + +[test sub transform] +op0=al_clear_to_color(teal) +op1=b = al_create_sub_bitmap(mysha, 160, 0, 160, 200) +op2=al_translate_transform(Tt, -80, 0) +op3=al_use_transform(Tt) +op4=al_draw_bitmap(b, 320, 10, flags) +op5=al_use_transform(Ti) +op6=al_draw_line(320.5, 0, 320.5, 480, #ffffff, 1) +flags=0 +hash=945d520b +sig=LLLZLCLLLLLLPLDLLLLLLMLDLLLLLL2A2LLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL + +[test sub transform hflip] +extend=test sub transform +flags=ALLEGRO_FLIP_HORIZONTAL +hash=ee8a23a0 +sig=LLLCLZLLLLLLDLPLLLLLLDLMLLLLLL2A2LLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL + +[test sub transform vflip] +extend=test sub transform +flags=ALLEGRO_FLIP_VERTICAL +hash=9290db87 +sig=LLL2B1LLLLLLKLDLLLLLLVLCLLLLLLEKCLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL + +[test sub transform vhflip] +extend=test sub transform +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +hash=d43a7e7c +sig=LLL1A2LLLLLLDLLLLLLLLCLVLLLLLLCKELLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL + +[test region transform] +op0=al_clear_to_color(teal) +op1=al_translate_transform(Tt, -80, 0) +op2=al_use_transform(Tt) +op3=al_draw_bitmap_region(mysha, 160, 0, 160, 200, 320, 10, flags) +op4=al_use_transform(Ti) +op5=al_draw_line(320.5, 0, 320.5, 480, #ffffff, 1) +flags=0 +hash=945d520b +sig=LLLZLCLLLLLLPLDLLLLLLMLDLLLLLL2A2LLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL + +[test region transform hflip] +extend=test region transform +flags=ALLEGRO_FLIP_HORIZONTAL +hash=ee8a23a0 +sig=LLLCLZLLLLLLDLPLLLLLLDLMLLLLLL2A2LLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL + +[test region transform vflip] +extend=test region transform +flags=ALLEGRO_FLIP_VERTICAL +hash=9290db87 +sig=LLL2B1LLLLLLKLDLLLLLLVLCLLLLLLEKCLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL + +[test region transform vhflip] +extend=test region transform +flags=ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL +hash=d43a7e7c +sig=LLL1A2LLLLLLDLLLLLLLLCLVLLLLLLCKELLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLLLLLLRLLLL + +[test transform compose] +op0=al_translate_transform(Tt, 200, 50) +op1=al_use_transform(Tt) +op2=al_draw_bitmap(allegro, 0, 0, 0) +op3=al_rotate_transform(Tr, 0.5) +op4=al_use_transform(Tr) +op5=al_draw_bitmap(mysha, 0, 0, 0) +op6=al_scale_transform(T, 1.5, 0.7) +op7=al_compose_transform(T, Tr) +op8=al_compose_transform(T, Tt) +op9=al_use_transform(T) +op10=al_draw_bitmap(allegro, 0, 0, 0) +hash=e1c88814 +sig=E0075AAD0wElcvfjm0pYKUlWto0LLKKZnPM02CEHKZNe002100JZPl000000MNV000000000000000000 + +[test transform per bitmap] +op0=al_clear_to_color(gray) +op1=al_build_transform(T1, 200, 50, 1, 1, -0.333) +op2=al_use_transform(T1) +op3=sub = al_create_sub_bitmap(target, 30, 150, 400, 300) +op4=al_set_target_bitmap(sub) +op5=al_clear_to_color(azure) +op6=al_build_transform(Tsub, 0, 0, 1.5, 1.5, 0.5) +op7=al_use_transform(Tsub) +op8=al_draw_bitmap(mysha, 0, 0, 0) +op9=al_set_target_bitmap(target) +op10=al_draw_bitmap(allegro, 0, 0, 0) +hash=341b718b +sig=WWWVngLbWWWWBUUaNWWWWJNKLLWE++POGWWWFEP+++WWWmtEE++WWWqvlFD+WWWjaPQECWWWVLKPDCWWW diff --git a/allegro/tests/test_bitmaps2.ini b/allegro/tests/test_bitmaps2.ini new file mode 100644 index 00000000..ae00d03b --- /dev/null +++ b/allegro/tests/test_bitmaps2.ini @@ -0,0 +1,103 @@ +# Test al_draw_tinted_bitmap et al. + +[bitmaps] +mysha=../examples/data/mysha.pcx +allegro=../examples/data/allegro.pcx + +[test tint blit] +op0=al_clear_to_color(red) +op1=al_draw_tinted_bitmap(mysha, #ccaa44, 37, 47, flags) +flags=0 +hash=706d8440 +sig=BBBBALLLL8LS77LLLL9UID7LLLL9MB37LLLL11211LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test tint region] +op0=al_clear_to_color(red) +op1=al_draw_tinted_bitmap_region(mysha, #ccaa44, 111, 51, 77, 99, 37, 47, flags) +flags=0 +hash=1faa6d4d +sig=SLLLLLLLLBLLLLLLLLFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test tint scale min] +op0=al_clear_to_color(red) +op1=al_draw_tinted_scaled_bitmap(mysha, #ccaa44, 0, 0, 320, 200, 11, 17, 77, 99, flags) +flags=0 +hash=742e9335 +sig=8LLLLLLLL1LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test tint scale max] +op0=al_clear_to_color(blue) +op1=al_draw_tinted_scaled_bitmap(mysha, #ccaa44, 0, 0, 320, 200, 11, 17, 611, 415, flags) +flags=0 +hash=c09b38b8 +sig=777777776789D977778BQVNL7779XWUHL8779WLOEEB779SOGBC87728KDBD57711122A111CCCCCCCCC + +[test tint rotate] +op0=al_clear_to_color(purple) +op1=al_draw_tinted_rotated_bitmap(allegro, #88aa44, 50, 50, 320, 240, theta, flags) +op2=al_draw_pixel(320, 240, cyan) +theta=-1.0 +hash=da5afb88 +sig=LLLLLJNALLLLLLHLBBLLLLGNHDLLLLLEKL8LLLLKGDALLLLLLHABLLLLLLLCLLLLLLLLLLLLLLLLLLLLL + +[test tint scaled rotate] +op0=al_clear_to_color(firebrick) +op1=al_draw_tinted_scaled_rotated_bitmap(allegro, #88aa44, 50, 50, 320, 240, xscale, yscale, theta, flags) +op2=al_draw_pixel(320, 240, cyan) +xscale=0.25 +yscale=0.25 +theta=0.7854 +flags=0 +hash=3f12b882 +sig=KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK8KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK + +[test tint transform compose] +op0=al_translate_transform(Tt, 200, 50) +op1=al_use_transform(Tt) +op2=al_draw_tinted_bitmap(allegro, #aa0000, 0, 0, 0) +op3=al_rotate_transform(Tr, 0.5) +op4=al_use_transform(Tr) +op5=al_draw_tinted_bitmap(mysha, #00aa00, 0, 0, 0) +op6=al_scale_transform(T, 1.5, 0.7) +op7=al_compose_transform(T, Tr) +op8=al_compose_transform(T, Tt) +op9=al_use_transform(T) +op10=al_draw_tinted_bitmap(allegro, #0000aa, 0, 0, 0) +hash=68ba872b +sig=200112220C2A9DCCB0B642AAEB044433A53002234006000000300A000000557000000000000000000 + +[test al_draw_tinted_scaled_rotated_bitmap_region] +op0=al_draw_tinted_scaled_rotated_bitmap_region(mysha, 80, 50, 160, 100, #8080ff, 0, 0, 320, 240, 1.41, 1.41, -0.78, 0) +op1=al_draw_tinted_scaled_rotated_bitmap_region(mysha, 80, 50, 160, 100, #8080ff, 60, 0, 320, 240, 1.41, 1.41, 0.78, 0) +hash=7669c5a4 +sig=000000000000000000000000PF0000R0YIE0000dPcMD000ROMYD00000EH90000000A0000000090000 + +[test horizontal shear] +op0=al_horizontal_shear_transform(T1, -0.5) +op1=al_use_transform(T1) +op2=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 0, 0, 64, 128, 0) +op3=al_translate_transform(T2, 64, 0) +op4=al_horizontal_shear_transform(T2, -0.5) +op5=al_use_transform(T2) +op6=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 0, 0, 64, 64, 0) +op7=al_translate_transform(T3, 64, 64) +op8=al_horizontal_shear_transform(T3, -0.5) +op9=al_use_transform(T3) +op10=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 0, 0, 64, 64, 0) +hash=380bb87f +sig=YF0000000Rt0000000000000000000000000000000000000000000000000000000000000000000000 + +[test vertical shear] +op0=al_vertical_shear_transform(T1, 0.5) +op1=al_use_transform(T1) +op2=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 0, 0, 64, 128, 0) +op3=al_translate_transform(T2, 64, 0) +op4=al_vertical_shear_transform(T2, 0.5) +op5=al_use_transform(T2) +op6=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 0, 0, 64, 64, 0) +op7=al_translate_transform(T3, 64, 64) +op8=al_vertical_shear_transform(T3, 0.5) +op9=al_use_transform(T3) +op10=al_draw_scaled_bitmap(mysha, 0, 0, 320, 200, 0, 0, 64, 64, 0) +hash=2af248da +sig=D00000000750000000F50000000000000000000000000000000000000000000000000000000000000 diff --git a/allegro/tests/test_blend.ini b/allegro/tests/test_blend.ini new file mode 100644 index 00000000..62dc19c2 --- /dev/null +++ b/allegro/tests/test_blend.ini @@ -0,0 +1,658 @@ +[bitmaps] +allegro=../examples/data/allegro.pcx +green=../examples/data/green.png +bkg=../examples/data/bkg.png + +# We can't assume that a backbuffer with alpha is available, so draw +# to a temporary bitmap. +[template] +op0=b = al_create_bitmap(640, 480) +op1=al_set_target_bitmap(b) +op2=al_draw_tinted_scaled_bitmap(allegro, #aaaaaa80, 0, 0, 320, 200, 0, 0, 640, 480, 0) +op3=al_set_blender(mode, src, dst1) +op4=al_set_blend_color(#abcdeffe) +op5=al_draw_bitmap(green, x, 5, 0) +op6=al_set_blender(mode, src, dst2) +op7=al_draw_bitmap(green, x, 125, 0) +op8=al_set_blender(mode, src, dst3) +op9=al_draw_bitmap(green, x, 245, 0) +op10=al_set_blender(mode, src, dst4) +op11=al_draw_bitmap(green, x, 365, 0) +op12=al_set_target_bitmap(target) +op13=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) +op14=al_draw_bitmap(bkg, 0, 0, 0) +op15=al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE) +op16=al_draw_bitmap(b, 0, 0, 0) +x=140 + +[template dst=1,0,a,ia] +extend=template +dst1=ALLEGRO_ONE +dst2=ALLEGRO_ZERO +dst3=ALLEGRO_ALPHA +dst4=ALLEGRO_INVERSE_ALPHA + +[template dst=sc,dc,isc,idc] +extend=template +dst1=ALLEGRO_SRC_COLOR +dst2=ALLEGRO_DEST_COLOR +dst3=ALLEGRO_INVERSE_SRC_COLOR +dst4=ALLEGRO_INVERSE_DEST_COLOR + +[template dst=cc,icc] +extend=template +dst1=ALLEGRO_SRC_COLOR +dst2=ALLEGRO_DEST_COLOR +dst3=ALLEGRO_SRC_COLOR +dst4=ALLEGRO_DEST_COLOR + +#-----------------------------------------------------------------------------# + +[template mode=ADD dst=1,0,a,ia] +extend=template dst=1,0,a,ia +mode=ALLEGRO_ADD + +[test blend mode=ADD src=1 dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_ONE +hash=7bc85f46 +sig=GDD9PNGlHJJqJIHHHHEDL3566KLCCH78T6QCBCCBDFHCF9A76MM5bBCAZ66676BBAP7B8ALAABJ8CUBQA + +[test blend mode=ADD src=0 dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_ZERO +hash=441baf02 +sig=GDA9BAGHHJJJJIHHHHED665767LCC676766CBCCBDFHCF9A66A95ABCA866676BBA77A7A6AAB6886B5A + +[test blend mode=ADD src=a dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_ALPHA +hash=a8d416f9 +sig=GDB9NMGlHJJoJIHHHHEDJ5576KLCCH76T6PCBCCBDFHCF9A66LL5bBCAY66676BBAM7A9ALAABI89TBPA + +[test blend mode=ADD src=ia dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_INVERSE_ALPHA +hash=16223282 +sig=GDB9DCGIHJJMJIHHHHED655566LCC676666CBCCBDFHCF9A76BB5ABCA966676BBA87B7A6AAB6896B5A + +[test blend mode=ADD src=sc dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_SRC_COLOR +hash=f926f4cd +sig=GDA9KJGeHJJhJIHHHHEDF5556ELCCB76L6ICBCCBDFHCF9A66II5TBCAR66676BBAH7A7AFAABC89LBIA + +[test blend mode=ADD src=dc dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_DEST_COLOR +hash=b2630b89 +sig=GDA9HGGeHJJjJIHHHHED855568LCC776D68CBCCBDFHCF9A66IH5MBCAE66676BBA87A6A6AAB6885B6A + +[test blend mode=ADD src=isc dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_INVERSE_SRC_COLOR +hash=1e52eaf0 +sig=GDC9FEGLHJJQJIHHHHED655566LCC676766CBCCBDFHCF9A76DC5EBCAC66676BBA97B7A7AAB6896B6A + +[test blend mode=ADD src=idc dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_INVERSE_DEST_COLOR +hash=fe52c382 +sig=GDC9LKGgHJJiJIHHHHED955568LCC87686ACBCCBDFHCF9A76JI5YBCAW66676BBAD7A7ABAABB8AFBCA + +[test blend mode=ADD src=cc dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_CONST_COLOR +hash=4ee1eaca +sig=GDC9OMGkHJJoJIHHHHEDH3556GLCCE77N6KCBCCBDFHCF9A76LL5ZBCAW66676BBAK7B8AHAABG8BOBLA + +[test blend mode=ADD src=icc dst=1,0,a,ia] +extend=template mode=ADD dst=1,0,a,ia +src=ALLEGRO_INVERSE_CONST_COLOR +hash=83ed9c53 +sig=GDA9CBGJHJJMJIHHHHED665767LCC676766CBCCBDFHCF9A66BA5DBCAA66676BBA87A7A7AAB6886B5A + +#-----------------------------------------------------------------------------# + +[template mode=ADD dst=sc,dc,isc,idc] +extend=template dst=sc,dc,isc,idc +mode=ALLEGRO_ADD + +[test blend mode=ADD src=1 dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_ONE +hash=0ce01bb8 +sig=GD76AA6VHJJZ66676HEDV6AG7YLCCT6Dn8ZCBCCBDFIDF9ACCPPDYBCAXCCEFABBAU98E7TAABR7Ca8YA + +[test blend mode=ADD src=0 dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_ZERO +hash=90e041ac +sig=GD664468HJJA66676HED869879LCC867C88CBCCBDFIDF9AAC88D5BCA6CCEFABBA878878AAB777787A + +[test blend mode=ADD src=a dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_ALPHA +hash=a2c1dee3 +sig=GD66BA6VHJJY66676HEDS69F7XLCCR6An8ZCBCCBDFIDF9AACMMDXBCAUCCEFABBAS88D7SAABQ79a8YA + +[test blend mode=ADD src=ia dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_ALPHA +hash=597e5032 +sig=GD763369HJJC66676HED96A97ALCC969D88CBCCBDFIDF9ABCAAD6BCA7CCEFABBA988978AAB878787A + +[test blend mode=ADD src=sc dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_SRC_COLOR +hash=901f4244 +sig=GD66776NHJJR66676HEDN69D7RLCCM69f8RCBCCBDFIDF9AACJJDQBCAOCCEFABBAN88C7MAABK78S8QA + +[test blend mode=ADD src=dc dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_DEST_COLOR +hash=b80bdb24 +sig=GD66556OHJJS66676HEDI6AC7LLCCH69a8JCBCCBDFIDF9AACEEDBBCA8CCEFABBAE88A7DAABC77B8EA + +[test blend mode=ADD src=isc dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_SRC_COLOR +hash=020d43da +sig=GD76556CHJJF66676HEDB6AA7CLCCB69F8ACBCCBDFIDF9ABCBBD6BCA8CCEFABBAB8897AAABA79989A + +[test blend mode=ADD src=idc dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_DEST_COLOR +hash=2349d015 +sig=GD76996QHJJS66676HEDI6AC7LLCCH6AU8MCBCCBDFIDF9ABCFEDGBCAICCEFABBAL88B7KAABJ79Q8OA + +[test blend mode=ADD src=cc dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_CONST_COLOR +hash=d2c79eaa +sig=GD76996THJJX66676HEDT6AF7WLCCR6Cl8XCBCCBDFIDF9ACCNNDTBCASCCEFABBAS98E7RAABP7BX8WA + +[test blend mode=ADD src=icc dst=sc,dc,isc,idc] +extend=template mode=ADD dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_CONST_COLOR +hash=5f617039 +sig=GD66556BHJJD66676HED96987ALCC967E89CBCCBDFIDF9AAC88D6BCA7CCEFABBA978879AAB877888A + +#-----------------------------------------------------------------------------# + +[template mode=ADD dst=cc,icc] +extend=template dst=cc,icc +mode=ALLEGRO_ADD + + +[test blend mode=ADD src=1 dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_ONE +hash=65dca8dc +sig=GD76AA6VHJJZ66676HEDV6AG7YLCCT6Dn8ZCBCCBDFIDF9A76BB5TBCAV66676BBAP4685NAABL59V6SA + +[test blend mode=ADD src=0 dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_ZERO +hash=182efe77 +sig=GD664468HJJA66676HED869879LCC867C88CBCCBDFIDF9A665556BCA666676BBA656656AAB555565A + +[test blend mode=ADD src=a dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_ALPHA +hash=8272bd59 +sig=GD66BA6VHJJY66676HEDS69F7XLCCR6An8ZCBCCBDFIDF9A66BB5TBCAT66676BBAO5685NAABK57V6SA + +[test blend mode=ADD src=ia dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_INVERSE_ALPHA +hash=6202d315 +sig=GD763369HJJC66676HED96A97ALCC969D88CBCCBDFIDF9A764456BCA666676BBA746556AAB556565A + +[test blend mode=ADD src=sc dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_SRC_COLOR +hash=0a7aa6df +sig=GD66776NHJJR66676HEDN69D7RLCCM69f8RCBCCBDFIDF9A66885LBCAN66676BBAI5665GAABE56N6KA + +[test blend mode=ADD src=dc dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_DEST_COLOR +hash=a314996a +sig=GD66556OHJJS66676HEDI6AC7LLCCH69a8JCBCCBDFIDF9A66885EBCAA66676BBA956658AAB755668A + +[test blend mode=ADD src=isc dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_INVERSE_SRC_COLOR +hash=81205c32 +sig=GD76556CHJJF66676HEDB6AA7CLCCB69F8ACBCCBDFIDF9A76665ABCAA66676BBA846657AAB756767A + +[test blend mode=ADD src=idc dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_INVERSE_DEST_COLOR +hash=3c6243b3 +sig=GD76996QHJJS66676HEDI6AC7LLCCH6AU8MCBCCBDFIDF9A76995QBCAR66676BBAG5675FAABE57L6IA + +[test blend mode=ADD src=cc dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_CONST_COLOR +hash=15e071c8 +sig=GD76996THJJX66676HEDT6AF7WLCCR6Cl8XCBCCBDFIDF9A76AA5RBCAS66676BBAM4675KAABH58Q6OA + +[test blend mode=ADD src=icc dst=cc,icc] +extend=template mode=ADD dst=cc,icc +src=ALLEGRO_INVERSE_CONST_COLOR +hash=de752105 +sig=GD66556BHJJD66676HED96987ALCC967E89CBCCBDFIDF9A666659BCA866676BBA756657AAB655666A + +#-----------------------------------------------------------------------------# + +[template mode=DEST_MINUS_SRC dst=1,0,a,ia] +extend=template dst=1,0,a,ia +mode=ALLEGRO_DEST_MINUS_SRC + +[test blend mode=DEST_MINUS_SRC src=1 dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_ONE +hash=2e819fcc +sig=GD9966G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA76A7A7AAB6886B6A + +[test blend mode=DEST_MINUS_SRC src=0 dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_ZERO +hash=441baf02 +sig=GDA9BAGHHJJJJIHHHHED665767LCC676766CBCCBDFHCF9A66A95ABCA866676BBA77A7A6AAB6886B5A + +[test blend mode=DEST_MINUS_SRC src=a dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_ALPHA +hash=6fcd619c +sig=GD9977G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA86A7A7AAB6886B6A + +[test blend mode=DEST_MINUS_SRC src=ia dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_INVERSE_ALPHA +hash=77192dfe +sig=GD9998GGHJJHJIHHHHED665767LCC676766CBCCBDFHCF9A66985ABCA766676BBA76A7A7AAB6886B6A + +[test blend mode=DEST_MINUS_SRC src=sc dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_SRC_COLOR +hash=2dc73562 +sig=GD9977G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA86A7A7AAB6886B6A + +[test blend mode=DEST_MINUS_SRC src=dc dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_DEST_COLOR +hash=683a8d24 +sig=GD9977G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA86A7A7AAB6886B6A + +[test blend mode=DEST_MINUS_SRC src=isc dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_INVERSE_SRC_COLOR +hash=c590b4b7 +sig=GD9977GCHJJEJIHHHHED665767LCC676766CBCCBDFHCF9A668756BCA566676BBA76A7A7AAB6886B6A + +[test blend mode=DEST_MINUS_SRC src=idc dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_INVERSE_DEST_COLOR +hash=c0986966 +sig=GD9977G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA76A7A7AAB6886B6A + +[test blend mode=DEST_MINUS_SRC src=cc dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_CONST_COLOR +hash=38f39dec +sig=GD9966G6HJJ7JIHHHHED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA86A7A7AAB6886B6A + +[test blend mode=DEST_MINUS_SRC src=icc dst=1,0,a,ia] +extend=template mode=DEST_MINUS_SRC dst=1,0,a,ia +src=ALLEGRO_INVERSE_CONST_COLOR +hash=6eb30b02 +sig=GDA9A9GEHJJGJIHHHHED665767LCC676766CBCCBDFHCF9A669957BCA566676BBA77A7A7AAB6886B6A + +#-----------------------------------------------------------------------------# + +[template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc] +extend=template dst=sc,dc,isc,idc +mode=ALLEGRO_DEST_MINUS_SRC + +[test blend mode=DEST_MINUS_SRC src=1 dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_ONE +hash=8b11d273 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC65D6BCA6CCEFABBA768777AAB677686A + +[test blend mode=DEST_MINUS_SRC src=0 dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_ZERO +hash=90e041ac +sig=GD664468HJJA66676HED869879LCC867C88CBCCBDFIDF9AAC88D5BCA6CCEFABBA878878AAB777787A + +[test blend mode=DEST_MINUS_SRC src=a dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_ALPHA +hash=b4a2ce11 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB677686A + +[test blend mode=DEST_MINUS_SRC src=ia dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_ALPHA +hash=59fcf94a +sig=GD665568HJJA66676HED769778LCC767B88CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB777686A + +[test blend mode=DEST_MINUS_SRC src=sc dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_SRC_COLOR +hash=861e7e3e +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB677686A + +[test blend mode=DEST_MINUS_SRC src=dc dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_DEST_COLOR +hash=d0317d02 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB677686A + +[test blend mode=DEST_MINUS_SRC src=isc dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_SRC_COLOR +hash=6d493d98 +sig=GD664466HJJ866676HED669777LCC667A87CBCCBDFIDF9AAC55D6BCA6CCEFABBA668776AAB677585A + +[test blend mode=DEST_MINUS_SRC src=idc dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_DEST_COLOR +hash=18079776 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC55D6BCA6CCEFABBA768777AAB677686A + +[test blend mode=DEST_MINUS_SRC src=cc dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_CONST_COLOR +hash=ed43510b +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9AAC65D6BCA6CCEFABBA768777AAB677686A + +[test blend mode=DEST_MINUS_SRC src=icc dst=sc,dc,isc,idc] +extend=template mode=DEST_MINUS_SRC dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_CONST_COLOR +hash=c347651f +sig=GD663366HJJ866676HED769878LCC767A86CBCCBDFIDF9AAC88D6BCA6CCEFABBA778877AAB676585A + +#-----------------------------------------------------------------------------# + +[template mode=DEST_MINUS_SRC dst=cc,icc] +extend=template dst=cc,icc +mode=ALLEGRO_DEST_MINUS_SRC + +[test blend mode=DEST_MINUS_SRC src=1 dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_ONE +hash=d68bdd68 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9A666556BCA666676BBA766757AAB655666A + +[test blend mode=DEST_MINUS_SRC src=0 dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_ZERO +hash=182efe77 +sig=GD664468HJJA66676HED869879LCC867C88CBCCBDFIDF9A665556BCA666676BBA656656AAB555565A + +[test blend mode=DEST_MINUS_SRC src=a dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_ALPHA +hash=cb2229b3 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9A666556BCA666676BBA766757AAB655666A + +[test blend mode=DEST_MINUS_SRC src=ia dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_INVERSE_ALPHA +hash=cbb32185 +sig=GD665568HJJA66676HED769778LCC767B88CBCCBDFIDF9A666656BCA566676BBA666756AAB655565A + +[test blend mode=DEST_MINUS_SRC src=sc dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_SRC_COLOR +hash=128074a2 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9A666556BCA666676BBA766757AAB655666A + +[test blend mode=DEST_MINUS_SRC src=dc dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_DEST_COLOR +hash=07b128cd +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9A666556BCA666676BBA766757AAB655666A + +[test blend mode=DEST_MINUS_SRC src=isc dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_INVERSE_SRC_COLOR +hash=3704cd4c +sig=GD664466HJJ866676HED669777LCC667A87CBCCBDFIDF9A665555BCA566676BBA666756AAB555564A + +[test blend mode=DEST_MINUS_SRC src=idc dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_INVERSE_DEST_COLOR +hash=6df57d07 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9A666556BCA666676BBA766757AAB655666A + +[test blend mode=DEST_MINUS_SRC src=cc dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_CONST_COLOR +hash=66a06ce3 +sig=GD666666HJJ666676HED669777LCC667786CBCCBDFIDF9A666556BCA666676BBA766757AAB655666A + +[test blend mode=DEST_MINUS_SRC src=icc dst=cc,icc] +extend=template mode=DEST_MINUS_SRC dst=cc,icc +src=ALLEGRO_INVERSE_CONST_COLOR +hash=1222ba8b +sig=GD663366HJJ866676HED769878LCC767A86CBCCBDFIDF9A664454BCA466676BBA556655AAB555464A + + +#-----------------------------------------------------------------------------# + +[template mode=SRC_MINUS_DEST dst=1,0,a,ia] +extend=template dst=1,0,a,ia +mode=ALLEGRO_SRC_MINUS_DEST + +[test blend mode=SRC_MINUS_DEST src=1 dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_ONE +hash=2a79c7ac +sig=GD666667HJJ766676HEDL3566KLCCH78T6QCBCCBDFHCF9A665559BCAC66676BBAL5775KAABH67T7PA + +[test blend mode=SRC_MINUS_DEST src=0 dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_ZERO +hash=82bce5d4 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=a dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_ALPHA +hash=98761b88 +sig=GD666667HJJ766676HEDJ5576KLCCH76T6PCBCCBDFHCF9A666659BCAB66676BBAJ6785KAABG67S7PA + +[test blend mode=SRC_MINUS_DEST src=ia dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_INVERSE_ALPHA +hash=5bc32bdb +sig=GD666666HJJ666676HED655566LCC676666CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=sc dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_SRC_COLOR +hash=bebf46ff +sig=GD666667HJJ766676HEDF5556ELCCB76L6ICBCCBDFHCF9A665558BCAA66676BBAF6765EAABB66L7IA + +[test blend mode=SRC_MINUS_DEST src=dc dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_DEST_COLOR +hash=721318ba +sig=GD666666HJJ666676HED855568LCC776D68CBCCBDFHCF9A666556BCA666676BBA767656AAB666576A + +[test blend mode=SRC_MINUS_DEST src=isc dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_INVERSE_SRC_COLOR +hash=b3cf8aac +sig=GD666666HJJ666676HED655566LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=idc dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_INVERSE_DEST_COLOR +hash=0793889c +sig=GD666666HJJ666676HED955568LCC87686ACBCCBDFHCF9A666556BCA666676BBAB6775BAABA67F7CA + +[test blend mode=SRC_MINUS_DEST src=cc dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_CONST_COLOR +hash=8d0c7f68 +sig=GD665565HJJ666676HEDH3556GLCCE77N6KCBCCBDFHCF9A665457BCAA66676BBAH5765GAABD67N7KA + +[test blend mode=SRC_MINUS_DEST src=icc dst=1,0,a,ia] +extend=template mode=SRC_MINUS_DEST dst=1,0,a,ia +src=ALLEGRO_INVERSE_CONST_COLOR +hash=82bce5d4 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +#-----------------------------------------------------------------------------# + +[template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc] +extend=template dst=sc,dc,isc,idc +mode=ALLEGRO_SRC_MINUS_DEST + +[test blend mode=SRC_MINUS_DEST src=1 dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_ONE +hash=a5bc2ba0 +sig=GD666669HJJA66676HEDB55569LCC97696ECBCCBDFHCF9A66885IBCAM66676BBAC5755BAAB967H7DA + +[test blend mode=SRC_MINUS_DEST src=0 dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_ZERO +hash=82bce5d4 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=a dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_ALPHA +hash=eda1ec1b +sig=GD667769HJJ966676HEDA65769LCC97696ECBCCBDFHCF9A66985IBCAL66676BBAB6765BAAB966G7DA + +[test blend mode=SRC_MINUS_DEST src=ia dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_ALPHA +hash=33a0483e +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A665555BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=sc dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_SRC_COLOR +hash=fb2978c6 +sig=GD666667HJJ766676HED965669LCC77696BCBCCBDFHCF9A66775FBCAG66676BBAA67659AAB866D7BA + +[test blend mode=SRC_MINUS_DEST src=dc dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_DEST_COLOR +hash=5a1c8feb +sig=GD666666HJJ666676HED665666LCC675666CBCCBDFHCF9A665555BCA566676BBA667655AAB566574A + +[test blend mode=SRC_MINUS_DEST src=isc dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_SRC_COLOR +hash=612ad8c8 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A665555BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=idc dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_DEST_COLOR +hash=77b28a0b +sig=GD666666HJJ666676HED665666LCC676567CBCCBDFHCF9A666659BCAC66676BBA767757AAB766876A + +[test blend mode=SRC_MINUS_DEST src=cc dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_CONST_COLOR +hash=70d42cc2 +sig=GD665667HJJ766676HED955567LCC77666BCBCCBDFHCF9A66775FBCAH66676BBA957558AAB766D79A + +[test blend mode=SRC_MINUS_DEST src=icc dst=sc,dc,isc,idc] +extend=template mode=SRC_MINUS_DEST dst=sc,dc,isc,idc +src=ALLEGRO_INVERSE_CONST_COLOR +hash=82bce5d4 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +#-----------------------------------------------------------------------------# + +[template mode=SRC_MINUS_DEST dst=cc,icc] +extend=template dst=cc,icc +mode=ALLEGRO_SRC_MINUS_DEST + +[test blend mode=SRC_MINUS_DEST src=1 dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_ONE +hash=ec7a13cf +sig=GD666669HJJA66676HEDB55569LCC97696ECBCCBDFHCF9A66665CBCAE66676BBAF5765FAABD67M7IA + +[test blend mode=SRC_MINUS_DEST src=0 dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_ZERO +hash=82bce5d4 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=a dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_ALPHA +hash=4176dbb1 +sig=GD667769HJJ966676HEDA65769LCC97696ECBCCBDFHCF9A66665CBCAD66676BBAF6775FAABC67L7IA + +[test blend mode=SRC_MINUS_DEST src=ia dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_INVERSE_ALPHA +hash=8db00872 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=sc dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_SRC_COLOR +hash=1bd139f8 +sig=GD666667HJJ766676HED965669LCC77696BCBCCBDFHCF9A665558BCAA66676BBAB6765BAAB966G7DA + +[test blend mode=SRC_MINUS_DEST src=dc dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_DEST_COLOR +hash=ac5b10cc +sig=GD666666HJJ666676HED665666LCC675666CBCCBDFHCF9A666556BCA666676BBA667656AAB666575A + +[test blend mode=SRC_MINUS_DEST src=isc dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_INVERSE_SRC_COLOR +hash=e2a893a6 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A + +[test blend mode=SRC_MINUS_DEST src=idc dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_INVERSE_DEST_COLOR +hash=c7613016 +sig=GD666666HJJ666676HED665666LCC676567CBCCBDFHCF9A666556BCA666676BBA867758AAB766A78A + +[test blend mode=SRC_MINUS_DEST src=cc dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_CONST_COLOR +hash=abe19282 +sig=GD665667HJJ766676HED955567LCC77666BCBCCBDFHCF9A665559BCAC66676BBAD5755CAABA67I7EA + +[test blend mode=SRC_MINUS_DEST src=icc dst=cc,icc] +extend=template mode=SRC_MINUS_DEST dst=cc,icc +src=ALLEGRO_INVERSE_CONST_COLOR +hash=82bce5d4 +sig=GD666666HJJ666676HED665767LCC676766CBCCBDFHCF9A666556BCA666676BBA767757AAB666676A +#-----------------------------------------------------------------------------# +#-----------------------------------------------------------------------------# + +[test blend bullet] +op0=image = al_create_bitmap(180, 160) +op1=al_set_target_bitmap(image) +op2=al_clear_to_color(#ffffff) +op3=al_set_target_bitmap(target) +op4=al_clear_to_color(#808080) +op5=al_draw_line(10, 10, 190, 10, white, 2) +op6=al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ALPHA, ALLEGRO_ONE) +op7=al_draw_bitmap(image, 10, 20, 0) +op8=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op9=al_draw_line(10, 190, 190, 190, white, 2) +hash=610f2805 diff --git a/allegro/tests/test_blend_target.ini b/allegro/tests/test_blend_target.ini new file mode 100644 index 00000000..4ed24ff1 --- /dev/null +++ b/allegro/tests/test_blend_target.ini @@ -0,0 +1,31 @@ +[bitmaps] +mysha=../examples/data/mysha.pcx + +[test basic] +op0=t1 = al_create_sub_bitmap(target, 0, 0, 300, 200) +op1=t2 = al_create_sub_bitmap(target, 300, 0, 300, 200) +op2=al_set_target_bitmap(t1) +op3=al_set_bitmap_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) +op4=al_set_target_bitmap(t2) +op5=al_set_bitmap_blender(ALLEGRO_ADD, ALLEGRO_SRC_COLOR, ALLEGRO_ZERO) +op6=al_set_target_bitmap(target) +op7=al_set_target_bitmap(t1) +op8=al_draw_bitmap(mysha, 0, 0, 0) +op9=al_draw_pixel(116.5, 116.5, #ffffcc) +op10=al_put_blended_pixel(132, 132, #ffffcc) +op11=al_draw_rectangle(100, 100, 8, 8, #ffffcc, 2) +op12=al_set_target_bitmap(t2) +op13=al_draw_bitmap(mysha, 0, 0, 0) +op14=al_draw_pixel(116.5, 116.5, #ffffcc) +op15=al_put_blended_pixel(132, 132, #ffffcc) +op16=al_draw_rectangle(100, 100, 8, 8, #ffffcc, 2) +hash=252ba460 +sig=FtZD39g32vmREBdCA3jLLEIP813222200100000000000000000000000000000000000000000000000 + +[test reset] +op0=al_set_bitmap_blender(ALLEGRO_ADD, ALLEGRO_SRC_COLOR, ALLEGRO_ZERO) +op1=al_draw_bitmap(mysha, 0, 0, 0) +op2=al_reset_bitmap_blender(mysha) +op3=al_draw_bitmap(mysha, 100, 0, 0) +hash=f2a787d7 +sig=3EanED000oIsWOD000WGfK7E000022422000000000000000000000000000000000000000000000000 diff --git a/allegro/tests/test_ciede2000.ini b/allegro/tests/test_ciede2000.ini new file mode 100644 index 00000000..56d7484d --- /dev/null +++ b/allegro/tests/test_ciede2000.ini @@ -0,0 +1,357 @@ +# test data taken from http://www.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf +[fonts] +builtin=al_create_builtin_font() + +[ciede2000] +op0=c1 = al_color_lab(l1, a1, b1) +op1=c2 = al_color_lab(l2, a2, b2) +op2=d = al_color_distance_ciede2000(c1, c2) +op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA) +op4=x=fdif(d, d2000) +# we only test if the result is within one percent because we are not +# very numerically stable +op5=x=fmul(x, 100) +op6=x=round(x) +op7=al_draw_text(builtin, white, 0, 0, ALLEGRO_ALIGN_LEFT, x); +hash=fd053345 +sw_only=true + +[test ciede2000 1] +extend=ciede2000 +l1=0.500000 +a1=0.026772 +b1=-0.797751 +l2=0.500000 +a2=0.000000 +b2=-0.827485 +d2000=0.020425 + +[test ciede2000 2] +extend=ciede2000 +l1=0.500000 +a1=0.031571 +b1=-0.772803 +l2=0.500000 +a2=0.000000 +b2=-0.827485 +d2000=0.028615 + +[test ciede2000 3] +extend=ciede2000 +l1=0.500000 +a1=0.028361 +b1=-0.740200 +l2=0.500000 +a2=0.000000 +b2=-0.827485 +d2000=0.034412 + +[test ciede2000 4] +extend=ciede2000 +l1=0.500000 +a1=-0.013802 +b1=-0.842814 +l2=0.500000 +a2=0.000000 +b2=-0.827485 +d2000=0.010000 + +[test ciede2000 5] +extend=ciede2000 +l1=0.500000 +a1=-0.011848 +b1=-0.848006 +l2=0.500000 +a2=0.000000 +b2=-0.827485 +d2000=0.010000 + +[test ciede2000 6] +extend=ciede2000 +l1=0.500000 +a1=-0.009009 +b1=-0.855211 +l2=0.500000 +a2=0.000000 +b2=-0.827485 +d2000=0.010000 + +[test ciede2000 7] +extend=ciede2000 +l1=0.500000 +a1=0.000000 +b1=0.000000 +l2=0.500000 +a2=-0.010000 +b2=0.020000 +d2000=0.023669 + +[test ciede2000 8] +extend=ciede2000 +l1=0.500000 +a1=-0.010000 +b1=0.020000 +l2=0.500000 +a2=0.000000 +b2=0.000000 +d2000=0.023669 + +[test ciede2000 9] +extend=ciede2000 +l1=0.500000 +a1=0.024900 +b1=-0.000010 +l2=0.500000 +a2=-0.024900 +b2=0.000009 +d2000=0.071792 + +[test ciede2000 10] +extend=ciede2000 +l1=0.500000 +a1=0.024900 +b1=-0.000010 +l2=0.500000 +a2=-0.024900 +b2=0.000010 +d2000=0.071792 + +[test ciede2000 11] +extend=ciede2000 +l1=0.500000 +a1=0.024900 +b1=-0.000010 +l2=0.500000 +a2=-0.024900 +b2=0.000011 +d2000=0.072195 + +[test ciede2000 12] +extend=ciede2000 +l1=0.500000 +a1=0.024900 +b1=-0.000010 +l2=0.500000 +a2=-0.024900 +b2=0.000012 +d2000=0.072195 + +[test ciede2000 13] +extend=ciede2000 +l1=0.500000 +a1=-0.000010 +b1=0.024900 +l2=0.500000 +a2=0.000009 +b2=-0.024900 +d2000=0.048045 + +[test ciede2000 14] +extend=ciede2000 +l1=0.500000 +a1=-0.000010 +b1=0.024900 +l2=0.500000 +a2=0.000010 +b2=-0.024900 +d2000=0.048045 + +[test ciede2000 15] +extend=ciede2000 +l1=0.500000 +a1=-0.000010 +b1=0.024900 +l2=0.500000 +a2=0.000011 +b2=-0.024900 +d2000=0.047461 + +[test ciede2000 16] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.500000 +a2=0.000000 +b2=-0.025000 +d2000=0.043065 + +[test ciede2000 17] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.730000 +a2=0.250000 +b2=-0.180000 +d2000=0.271492 + +[test ciede2000 18] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.610000 +a2=-0.050000 +b2=0.290000 +d2000=0.228977 + +[test ciede2000 19] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.560000 +a2=-0.270000 +b2=-0.030000 +d2000=0.319030 + +[test ciede2000 20] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.580000 +a2=0.240000 +b2=0.150000 +d2000=0.194535 + +[test ciede2000 21] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.500000 +a2=0.031736 +b2=0.005854 +d2000=0.010000 + +[test ciede2000 22] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.500000 +a2=0.032972 +b2=0.000000 +d2000=0.010000 + +[test ciede2000 23] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.500000 +a2=0.018634 +b2=0.005757 +d2000=0.010000 + +[test ciede2000 24] +extend=ciede2000 +l1=0.500000 +a1=0.025000 +b1=0.000000 +l2=0.500000 +a2=0.032592 +b2=0.003350 +d2000=0.010000 + +[test ciede2000 25] +extend=ciede2000 +l1=0.602574 +a1=-0.340099 +b1=0.362677 +l2=0.604626 +a2=-0.341751 +b2=0.394387 +d2000=0.012644 + +[test ciede2000 26] +extend=ciede2000 +l1=0.630109 +a1=-0.310961 +b1=-0.058663 +l2=0.628187 +a2=-0.297946 +b2=-0.040864 +d2000=0.012630 + +[test ciede2000 27] +extend=ciede2000 +l1=0.612901 +a1=0.037196 +b1=-0.053901 +l2=0.614292 +a2=0.022480 +b2=-0.049620 +d2000=0.018731 + +[test ciede2000 28] +extend=ciede2000 +l1=0.350831 +a1=-0.441164 +b1=0.037933 +l2=0.350232 +a2=-0.400716 +b2=0.015901 +d2000=0.018645 + +[test ciede2000 29] +extend=ciede2000 +l1=0.227233 +a1=0.200904 +b1=-0.466940 +l2=0.230331 +a2=0.149730 +b2=-0.425619 +d2000=0.020373 + +[test ciede2000 30] +extend=ciede2000 +l1=0.364612 +a1=0.478580 +b1=0.183852 +l2=0.362715 +a2=0.505065 +b2=0.212231 +d2000=0.014146 + +[test ciede2000 31] +extend=ciede2000 +l1=0.908027 +a1=-0.020831 +b1=0.014410 +l2=0.911528 +a2=-0.016435 +b2=0.000447 +d2000=0.014441 + +[test ciede2000 32] +extend=ciede2000 +l1=0.909257 +a1=-0.005406 +b1=-0.009208 +l2=0.886381 +a2=-0.008985 +b2=-0.007239 +d2000=0.015381 + +[test ciede2000 33] +extend=ciede2000 +l1=0.067747 +a1=-0.002908 +b1=-0.024247 +l2=0.058714 +a2=-0.000985 +b2=-0.022286 +d2000=0.006377 + +[test ciede2000 34] +extend=ciede2000 +l1=0.020776 +a1=0.000795 +b1=-0.011350 +l2=0.009033 +a2=-0.000636 +b2=-0.005514 +d2000=0.009082 diff --git a/allegro/tests/test_compressed.ini b/allegro/tests/test_compressed.ini new file mode 100644 index 00000000..00957372 --- /dev/null +++ b/allegro/tests/test_compressed.ini @@ -0,0 +1,168 @@ +# All of these are hardware only as compressed bitmaps are a video-bitmap only feature. + +[loading] +hw_only = true +op0=b = al_load_bitmap(filename) +op1=al_draw_bitmap(b, 0, 0, 0) + +[test loading dxt1] +extend=loading +filename = ../examples/data/mysha_dxt1.dds +sig=ftZD50000um0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[test loading dxt3] +extend=loading +filename = ../examples/data/mysha_dxt3.dds +sig=ftZE50000um0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[test loading dxt5] +extend=loading +filename = ../examples/data/mysha_dxt5.dds +sig=ftZE50000um0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[dest rw] +hw_only = true +op0=b = al_load_bitmap(filename) +op1=al_set_target_bitmap(b) +# Need to lock, otherwise the triangles of the rectangle will lock separately and result in diagonal artifacts +op2=al_lock_bitmap_region(b, 7, 7, 166, 126, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE) +op3=al_draw_filled_rectangle(8, 8, 164, 124, #ff00ff) +op4=al_unlock_bitmap(b) +op5=al_set_target_bitmap(target) +op6=al_draw_bitmap(b, 0, 0, 0) + +[test dest rw dxt1] +extend=dest rw +filename = ../examples/data/mysha_dxt1.dds +sig=ggZD50000gg0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[test dest rw dxt3] +extend=dest rw +filename = ../examples/data/mysha_dxt3.dds +sig=ggZE50000gg0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[test dest rw dxt5] +extend=dest rw +filename = ../examples/data/mysha_dxt5.dds +sig=ggZE50000gg0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[dest wo] +hw_only = true +filename2 = ../examples/data/blue_box.png +op0=b = al_load_bitmap(filename) +op1=b2 = al_load_bitmap(filename2) +op2=al_set_target_bitmap(b) +op3=al_draw_bitmap(b2, 16, 16, 0) +op4=al_set_target_bitmap(target) +op5=al_draw_bitmap(b, 0, 0, 0) + +[test dest wo dxt1] +extend=dest wo +filename = ../examples/data/mysha_dxt1.dds +sig=OOZD50000OO0050000aML050000222200000000000000000000000000000000000000000000000000 + +[test dest wo dxt3] +extend=dest wo +filename = ../examples/data/mysha_dxt3.dds +sig=OOZD50000OO0050000aML050000222200000000000000000000000000000000000000000000000000 + +[test dest wo dxt5] +extend=dest wo +filename = ../examples/data/mysha_dxt5.dds +sig=OOZD50000OO0050000aML050000222200000000000000000000000000000000000000000000000000 + +[src] +hw_only = true +filename2 = ../examples/data/fakeamp.bmp +op0=b = al_load_bitmap(filename) +op1=b2 = al_load_bitmap(filename2) +op2=al_set_target_bitmap(b2) +op3=al_draw_bitmap_region(b, 16, 16, 128, 128, 16, 16, 0) +op4=al_set_target_bitmap(target) +op5=al_draw_bitmap(b2, 0, 0, 0) + +[test src dxt1] +extend=src +filename = ../examples/data/mysha_dxt1.dds +sig=ftwu00000um0w00000QB0r00000vrnv00000000000000000000000000000000000000000000000000 + + +[test src dxt3] +extend=src +filename = ../examples/data/mysha_dxt3.dds +sig=ftwu00000um0w00000QB0r00000vrnv00000000000000000000000000000000000000000000000000 + + +[test src dxt5] +extend=src +filename = ../examples/data/mysha_dxt5.dds +sig=ftwu00000um0w00000QB0r00000vrnv00000000000000000000000000000000000000000000000000 + +[dest sub] +hw_only = true +op0=b = al_load_bitmap(filename) +op1=b2 = al_create_sub_bitmap(b, 16, 16, 128, 128); +op2=al_set_target_bitmap(b2) +op3=al_clear_to_color(#00ff00) +op4=al_set_target_bitmap(target) +op5=al_draw_bitmap(b, 0, 0, 0) + +[test dest sub dxt1] +extend=dest sub +filename = ../examples/data/mysha_dxt1.dds +sig=LLZD50000LL0050000ZLL050000222200000000000000000000000000000000000000000000000000 + +[test dest sub dxt3] +extend=dest sub +filename = ../examples/data/mysha_dxt3.dds +sig=LLZD50000LL0050000ZLL050000222200000000000000000000000000000000000000000000000000 + +[test dest sub dxt5] +extend=dest sub +filename = ../examples/data/mysha_dxt5.dds +sig=LLZD50000LL0050000ZLL050000222200000000000000000000000000000000000000000000000000 + +[convert from] +hw_only = true +op0=b = al_load_bitmap(filename) +op1=al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_565) +op2=al_convert_bitmap(b) +op3=al_draw_bitmap(b, 0, 0, 0) + +[test convert from dxt1] +extend=convert from +filename = ../examples/data/mysha_dxt1.dds +sig=ftZD50000um0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[test convert from dxt3] +extend=convert from +filename = ../examples/data/mysha_dxt3.dds +sig=ftZD50000um0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[test convert from dxt5] +extend=convert from +filename = ../examples/data/mysha_dxt5.dds +sig=ftZD50000um0050000jLL050000222200000000000000000000000000000000000000000000000000 + +[convert to] +hw_only = true +filename = ../examples/data/blue_box.png +op0=al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_565) +op1=b = al_load_bitmap(filename) +op3=al_convert_bitmap(b) +op4=al_draw_bitmap(b, 0, 0, 0) + +[test convert to dxt1] +extend=convert to +op2=al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1) +sig=OA0000000OA0000000000000000000000000000000000000000000000000000000000000000000000 + +[test convert to dxt3] +extend=convert to +op2=al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3) +sig=OA0000000OA0000000000000000000000000000000000000000000000000000000000000000000000 + +[test convert to dxt5] +extend=convert to +op2=al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5) +sig=OA0000000OA0000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/allegro/tests/test_convert.ini b/allegro/tests/test_convert.ini new file mode 100644 index 00000000..946a7694 --- /dev/null +++ b/allegro/tests/test_convert.ini @@ -0,0 +1,25 @@ +[test convert] +# This test relies on needing a video bitmap. +hw_only = true +skip_on_xvfb = true +op0= al_clear_to_color(#554321) +op1= al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP) +op2= al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_565) +op3= bmp = al_create_bitmap(360, 120) +op4= al_set_target_bitmap(bmp) +op5= al_clear_to_color(#00000000) +op6= al_draw_filled_rectangle(0, 0, 120, 120, red) +op7= al_draw_filled_rectangle(120, 0, 240, 120, green) +op8= al_draw_filled_rectangle(240, 0, 360, 120, blue) +op9= al_set_target_bitmap(target) +op10=al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP) +op11=al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGBA_8888) +op12=al_convert_bitmap(bmp) +op13=al_draw_bitmap(bmp, 0, 0, 0) +hash=955d3cc5 + +[test convert back] +extend=test convert +op1=al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP) +op10=al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP) +hash=77b58ac5 diff --git a/allegro/tests/test_driver.c b/allegro/tests/test_driver.c new file mode 100644 index 00000000..b21a7972 --- /dev/null +++ b/allegro/tests/test_driver.c @@ -0,0 +1,1886 @@ +/* + * Automated testing driver program for Allegro. + * + * By Peter Wang. + */ + +#define ALLEGRO_UNSTABLE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_BITMAPS 128 +#define MAX_TRANS 8 +#define MAX_FONTS 16 +#define MAX_VERTICES 100 +#define MAX_POLYGONS 8 + +typedef struct { + ALLEGRO_USTR *name; + ALLEGRO_BITMAP *bitmap[2]; +} Bitmap; + +typedef enum { + SW = 0, + HW = 1 +} BmpType; + +typedef struct { + ALLEGRO_USTR *name; + ALLEGRO_TRANSFORM transform; +} Transform; + +typedef struct { + int x; + int y; + int w; + int h; + ALLEGRO_LOCKED_REGION *lr; +} LockRegion; + +typedef struct { + ALLEGRO_USTR *name; + ALLEGRO_FONT *font; +} NamedFont; + +int argc; +char **argv; +ALLEGRO_DISPLAY *display; +ALLEGRO_BITMAP *membuf; +Bitmap bitmaps[MAX_BITMAPS]; +LockRegion lock_region; +Transform transforms[MAX_TRANS]; +NamedFont fonts[MAX_FONTS]; +ALLEGRO_VERTEX vertices[MAX_VERTICES]; +float simple_vertices[2 * MAX_VERTICES]; +int num_simple_vertices; +int vertex_counts[MAX_POLYGONS]; +int num_global_bitmaps; +float delay = 0.0; +bool save_outputs = false; +bool save_on_failure = false; +bool quiet = false; +bool want_display = true; +bool on_xvfb = true; +int verbose = 0; +int total_tests = 0; +int passed_tests = 0; +int failed_tests = 0; +int skipped_tests = 0; + +#define streq(a, b) (0 == strcmp((a), (b))) + +/* Helper macros for scanning statements. */ +#define PAT " %80[A-Za-z0-9_.$|#-] " +#define PAT1 PAT +#define PAT2 PAT1 "," PAT1 +#define PAT3 PAT2 "," PAT1 +#define PAT4 PAT3 "," PAT1 +#define PAT5 PAT4 "," PAT1 +#define PAT6 PAT5 "," PAT1 +#define PAT7 PAT6 "," PAT1 +#define PAT8 PAT7 "," PAT1 +#define PAT9 PAT8 "," PAT1 +#define PAT10 PAT9 "," PAT1 +#define PAT11 PAT10 "," PAT1 +#define PAT12 PAT11 "," PAT1 +#define PAT13 PAT12 "," PAT1 +#define PAT14 PAT13 "," PAT1 +#define ARGS1 arg[0] +#define ARGS2 ARGS1, arg[1] +#define ARGS3 ARGS2, arg[2] +#define ARGS4 ARGS3, arg[3] +#define ARGS5 ARGS4, arg[4] +#define ARGS6 ARGS5, arg[5] +#define ARGS7 ARGS6, arg[6] +#define ARGS8 ARGS7, arg[7] +#define ARGS9 ARGS8, arg[8] +#define ARGS10 ARGS9, arg[9] +#define ARGS11 ARGS10, arg[10] +#define ARGS12 ARGS11, arg[11] +#define ARGS13 ARGS12, arg[12] +#define ARGS14 ARGS13, arg[13] +#define V(a) resolve_var(cfg, section, arg[(a)]) +#define I(a) atoi(V(a)) +#define F(a) atof(V(a)) +#define C(a) get_color(V(a)) +#define B(a) get_bitmap(V(a), bmp_type, target) +#define SCAN0(fn) \ + (sscanf(stmt, fn " %80[(]" " )", ARGS1) == 1) +#define SCAN(fn, arity) \ + (sscanf(stmt, fn " (" PAT##arity " )", ARGS##arity) == arity) +#define SCANLVAL(fn, arity) \ + (sscanf(stmt, PAT " = " fn " (" PAT##arity " )", lval, ARGS##arity) \ + == 1 + arity) + +static void fatal_error(char const *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + fprintf(stderr, "test_driver: "); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(EXIT_FAILURE); +} + +static char const *bmp_type_to_string(BmpType bmp_type) +{ + switch (bmp_type) { + case SW: return "sw"; + case HW: return "hw"; + } + return "error"; +} + +static ALLEGRO_BITMAP *create_fallback_bitmap(void) +{ + ALLEGRO_BITMAP *bmp = al_create_bitmap(256, 256); + ALLEGRO_FONT *builtin_font = al_create_builtin_font(); + ALLEGRO_STATE state; + + if (!bmp) { + fatal_error("couldn't create a backup bitmap"); + } + if (!builtin_font) { + fatal_error("couldn't create a builtin font"); + } + al_store_state(&state, ALLEGRO_STATE_BITMAP); + al_set_target_bitmap(bmp); + al_clear_to_color(al_map_rgb_f(0.5, 0, 0)); + al_draw_text(builtin_font, al_map_rgb_f(1, 1, 1), 0, 0, 0, "fallback"); + al_restore_state(&state); + al_destroy_font(builtin_font); + + return bmp; +} + +static ALLEGRO_BITMAP *load_relative_bitmap(char const *filename, int flags) +{ + ALLEGRO_BITMAP *bmp; + + bmp = al_load_bitmap_flags(filename, flags); + if (!bmp) { + fprintf(stderr, "test_driver: failed to load %s\n", filename); + bmp = create_fallback_bitmap(); + } + return bmp; +} + +static void load_bitmaps(ALLEGRO_CONFIG const *cfg, const char *section, + BmpType bmp_type, int flags) +{ + int i = 0; + ALLEGRO_CONFIG_ENTRY *iter; + char const *key; + char const *value; + + key = al_get_first_config_entry(cfg, section, &iter); + while (key && i < MAX_BITMAPS) { + value = al_get_config_value(cfg, section, key); + + bitmaps[i].name = al_ustr_new(key); + bitmaps[i].bitmap[bmp_type] = load_relative_bitmap(value, flags); + + key = al_get_next_config_entry(&iter); + i++; + } + + if (i == MAX_BITMAPS) + fatal_error("bitmap limit reached"); + + num_global_bitmaps = i; +} + +static ALLEGRO_BITMAP **reserve_local_bitmap(const char *name, BmpType bmp_type) +{ + int i; + + for (i = num_global_bitmaps; i < MAX_BITMAPS; i++) { + if (!bitmaps[i].name) { + bitmaps[i].name = al_ustr_new(name); + return &bitmaps[i].bitmap[bmp_type]; + } + } + + fatal_error("bitmap limit reached"); + return NULL; +} + +static void unload_data(void) +{ + int i; + + for (i = 0; i < MAX_BITMAPS; i++) { + al_ustr_free(bitmaps[i].name); + al_destroy_bitmap(bitmaps[i].bitmap[0]); + al_destroy_bitmap(bitmaps[i].bitmap[1]); + } + memset(bitmaps, 0, sizeof(bitmaps)); + + for (i = 0; i < MAX_FONTS; i++) { + al_ustr_free(fonts[i].name); + al_destroy_font(fonts[i].font); + } + memset(fonts, 0, sizeof(fonts)); + + num_global_bitmaps = 0; +} + +static void set_target_reset(ALLEGRO_BITMAP *target) +{ + ALLEGRO_TRANSFORM ident; + + al_set_target_bitmap(target); + al_clear_to_color(al_map_rgb(0, 0, 0)); + al_reset_clipping_rectangle(); + al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + al_identity_transform(&ident); + al_use_transform(&ident); + al_orthographic_transform(&ident, 0, 0, -1, al_get_bitmap_width(target), al_get_bitmap_height(target), 1); + al_use_projection_transform(&ident); +} + +static char const *resolve_var(ALLEGRO_CONFIG const *cfg, char const *section, + char const *v) +{ + char const *vv = al_get_config_value(cfg, section, v); + return (vv) ? vv : v; +} + +static bool get_bool(char const *value) +{ + return streq(value, "true") ? true + : streq(value, "false") ? false + : atoi(value); +} + +static ALLEGRO_COLOR get_color(char const *value) +{ + int r, g, b, a; + float rf, gf, bf; + + if (sscanf(value, "#%02x%02x%02x%02x", &r, &g, &b, &a) == 4) + return al_map_rgba(r, g, b, a); + if (sscanf(value, "#%02x%02x%02x", &r, &g, &b) == 3) + return al_map_rgb(r, g, b); + if (sscanf(value, "%f/%f/%f", &rf, &gf, &bf) == 3) + return al_map_rgb_f(rf, gf, bf); + return al_color_name(value); +} + +static ALLEGRO_BITMAP *get_bitmap(char const *value, BmpType bmp_type, + ALLEGRO_BITMAP *target) +{ + int i; + + for (i = 0; i < MAX_BITMAPS; i++) { + if (bitmaps[i].name && streq(al_cstr(bitmaps[i].name), value)) + return bitmaps[i].bitmap[bmp_type]; + } + + if (streq(value, "target")) + return target; + + if (streq(value, "0") || streq(value, "NULL")) + return NULL; + + fatal_error("undefined bitmap: %s", value); + return NULL; +} + +static int get_load_bitmap_flag(char const *value) +{ + if (streq(value, "ALLEGRO_NO_PREMULTIPLIED_ALPHA")) + return ALLEGRO_NO_PREMULTIPLIED_ALPHA; + if (streq(value, "ALLEGRO_KEEP_INDEX")) + return ALLEGRO_KEEP_INDEX; + return atoi(value); +} + +static int get_draw_bitmap_flag(char const *value) +{ + if (streq(value, "ALLEGRO_FLIP_HORIZONTAL")) + return ALLEGRO_FLIP_HORIZONTAL; + if (streq(value, "ALLEGRO_FLIP_VERTICAL")) + return ALLEGRO_FLIP_VERTICAL; + if (streq(value, "ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL")) + return ALLEGRO_FLIP_VERTICAL|ALLEGRO_FLIP_HORIZONTAL; + if (streq(value, "ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL")) + return ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL; + return atoi(value); +} + +static int get_blender_op(char const *value) +{ + return streq(value, "ALLEGRO_ADD") ? ALLEGRO_ADD + : streq(value, "ALLEGRO_DEST_MINUS_SRC") ? ALLEGRO_DEST_MINUS_SRC + : streq(value, "ALLEGRO_SRC_MINUS_DEST") ? ALLEGRO_SRC_MINUS_DEST + : atoi(value); +} + +static int get_blend_factor(char const *value) +{ + return streq(value, "ALLEGRO_ZERO") ? ALLEGRO_ZERO + : streq(value, "ALLEGRO_ONE") ? ALLEGRO_ONE + : streq(value, "ALLEGRO_ALPHA") ? ALLEGRO_ALPHA + : streq(value, "ALLEGRO_INVERSE_ALPHA") ? ALLEGRO_INVERSE_ALPHA + : streq(value, "ALLEGRO_SRC_COLOR") ? ALLEGRO_SRC_COLOR + : streq(value, "ALLEGRO_DEST_COLOR") ? ALLEGRO_DEST_COLOR + : streq(value, "ALLEGRO_INVERSE_SRC_COLOR") ? ALLEGRO_INVERSE_SRC_COLOR + : streq(value, "ALLEGRO_INVERSE_DEST_COLOR") ? ALLEGRO_INVERSE_DEST_COLOR + : streq(value, "ALLEGRO_CONST_COLOR") ? ALLEGRO_CONST_COLOR + : streq(value, "ALLEGRO_INVERSE_CONST_COLOR") ? ALLEGRO_INVERSE_CONST_COLOR + : atoi(value); +} + +static ALLEGRO_TRANSFORM *get_transform(const char *name) +{ + int i; + + for (i = 0; i < MAX_TRANS; i++) { + if (!transforms[i].name) { + transforms[i].name = al_ustr_new(name); + al_identity_transform(&transforms[i].transform); + return &transforms[i].transform; + } + + if (transforms[i].name && streq(al_cstr(transforms[i].name), name)) + return &transforms[i].transform; + } + + fatal_error("transforms limit reached"); + return NULL; +} + +static int get_pixel_format(char const *v) +{ + int format = streq(v, "ALLEGRO_PIXEL_FORMAT_ANY") ? ALLEGRO_PIXEL_FORMAT_ANY + : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA + : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA + : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA + : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA + : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA + : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA + : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA + : streq(v, "ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA") ? ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA + : streq(v, "ALLEGRO_PIXEL_FORMAT_ARGB_8888") ? ALLEGRO_PIXEL_FORMAT_ARGB_8888 + : streq(v, "ALLEGRO_PIXEL_FORMAT_RGBA_8888") ? ALLEGRO_PIXEL_FORMAT_RGBA_8888 + : streq(v, "ALLEGRO_PIXEL_FORMAT_ARGB_4444") ? ALLEGRO_PIXEL_FORMAT_ARGB_4444 + : streq(v, "ALLEGRO_PIXEL_FORMAT_RGB_888") ? ALLEGRO_PIXEL_FORMAT_RGB_888 + : streq(v, "ALLEGRO_PIXEL_FORMAT_RGB_565") ? ALLEGRO_PIXEL_FORMAT_RGB_565 + : streq(v, "ALLEGRO_PIXEL_FORMAT_RGB_555") ? ALLEGRO_PIXEL_FORMAT_RGB_555 + : streq(v, "ALLEGRO_PIXEL_FORMAT_RGBA_5551") ? ALLEGRO_PIXEL_FORMAT_RGBA_5551 + : streq(v, "ALLEGRO_PIXEL_FORMAT_ARGB_1555") ? ALLEGRO_PIXEL_FORMAT_ARGB_1555 + : streq(v, "ALLEGRO_PIXEL_FORMAT_ABGR_8888") ? ALLEGRO_PIXEL_FORMAT_ABGR_8888 + : streq(v, "ALLEGRO_PIXEL_FORMAT_XBGR_8888") ? ALLEGRO_PIXEL_FORMAT_XBGR_8888 + : streq(v, "ALLEGRO_PIXEL_FORMAT_BGR_888") ? ALLEGRO_PIXEL_FORMAT_BGR_888 + : streq(v, "ALLEGRO_PIXEL_FORMAT_BGR_565") ? ALLEGRO_PIXEL_FORMAT_BGR_565 + : streq(v, "ALLEGRO_PIXEL_FORMAT_BGR_555") ? ALLEGRO_PIXEL_FORMAT_BGR_555 + : streq(v, "ALLEGRO_PIXEL_FORMAT_RGBX_8888") ? ALLEGRO_PIXEL_FORMAT_RGBX_8888 + : streq(v, "ALLEGRO_PIXEL_FORMAT_XRGB_8888") ? ALLEGRO_PIXEL_FORMAT_XRGB_8888 + : streq(v, "ALLEGRO_PIXEL_FORMAT_ABGR_F32") ? ALLEGRO_PIXEL_FORMAT_ABGR_F32 + : streq(v, "ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE") ? ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE + : streq(v, "ALLEGRO_PIXEL_FORMAT_RGBA_4444") ? ALLEGRO_PIXEL_FORMAT_RGBA_4444 + : streq(v, "ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1") ? ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1 + : streq(v, "ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3") ? ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3 + : streq(v, "ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5") ? ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5 + : -1; + if (format == -1) + fatal_error("invalid format: %s", v); + return format; +} + +static int get_lock_bitmap_flags(char const *v) +{ + return streq(v, "ALLEGRO_LOCK_READWRITE") ? ALLEGRO_LOCK_READWRITE + : streq(v, "ALLEGRO_LOCK_READONLY") ? ALLEGRO_LOCK_READONLY + : streq(v, "ALLEGRO_LOCK_WRITEONLY") ? ALLEGRO_LOCK_WRITEONLY + : atoi(v); +} + +static int get_bitmap_flags(char const *v) +{ + return streq(v, "ALLEGRO_MEMORY_BITMAP") ? ALLEGRO_MEMORY_BITMAP + : streq(v, "ALLEGRO_VIDEO_BITMAP") ? ALLEGRO_VIDEO_BITMAP + : atoi(v); +} + +static void fill_lock_region(LockRegion *lr, float alphafactor, bool blended) +{ + int x, y; + float r, g, b, a; + ALLEGRO_COLOR c; + + for (y = 0; y < lr->h; y++) { + for (x = 0; x < lr->w; x++) { + /* -1 to make the last pixel use the full color, allows easier + * manual inspection of the test results as we have a fixed + * color on each side. + */ + r = (float)x / (lr->w - 1); + b = (float)y / (lr->h - 1); + g = r*b; + a = r * alphafactor; + c = al_map_rgba_f(r, g, b, a); + if (blended) + al_put_blended_pixel(lr->x + x, lr->y + y, c); + else + al_put_pixel(lr->x + x, lr->y + y, c); + } + } +} + +static int get_load_font_flags(char const *v) +{ + return streq(v, "ALLEGRO_NO_PREMULTIPLIED_ALPHA") ? ALLEGRO_NO_PREMULTIPLIED_ALPHA + : streq(v, "ALLEGRO_TTF_NO_KERNING") ? ALLEGRO_TTF_NO_KERNING + : streq(v, "ALLEGRO_TTF_MONOCHROME") ? ALLEGRO_TTF_MONOCHROME + : atoi(v); +} + +static void load_fonts(ALLEGRO_CONFIG const *cfg, const char *section) +{ +#define MAXBUF 80 + + int i = 0; + ALLEGRO_CONFIG_ENTRY *iter; + char const *key; + char arg[14][MAXBUF]; + + key = al_get_first_config_entry(cfg, section, &iter); + while (key && i < MAX_FONTS) { + char const *stmt = al_get_config_value(cfg, section, key); + ALLEGRO_FONT *font = NULL; + bool load_stmt = false; + + if (SCAN("al_load_font", 3)) { + font = al_load_font(V(0), I(1), get_load_font_flags(V(2))); + load_stmt = true; + } + else if (SCAN("al_load_ttf_font", 3)) { + font = al_load_ttf_font(V(0), I(1), get_load_font_flags(V(2))); + load_stmt = true; + } + else if (SCAN("al_load_ttf_font_stretch", 4)) { + font = al_load_ttf_font_stretch(V(0), I(1), I(2), + get_load_font_flags(V(3))); + load_stmt = true; + } + else if (SCAN0("al_create_builtin_font")) { + font = al_create_builtin_font(); + load_stmt = true; + } + + if (load_stmt) { + if (!font) { + fatal_error("failed to load font: %s", key); + } + fonts[i].name = al_ustr_new(key); + fonts[i].font = font; + i++; + } + + key = al_get_next_config_entry(&iter); + } + + if (i == MAX_FONTS) + fatal_error("font limit reached"); + +#undef MAXBUF +} + +static ALLEGRO_FONT *get_font(char const *name) +{ + int i; + + if (streq(name, "NULL")) + return NULL; + + for (i = 0; i < MAX_FONTS; i++) { + if (fonts[i].name && streq(al_cstr(fonts[i].name), name)) + return fonts[i].font; + } + + fatal_error("undefined font: %s", name); + return NULL; +} + +static int get_font_align(char const *value) +{ + return streq(value, "ALLEGRO_ALIGN_LEFT") ? ALLEGRO_ALIGN_LEFT + : streq(value, "ALLEGRO_ALIGN_CENTRE") ? ALLEGRO_ALIGN_CENTRE + : streq(value, "ALLEGRO_ALIGN_RIGHT") ? ALLEGRO_ALIGN_RIGHT + : streq(value, "ALLEGRO_ALIGN_INTEGER") ? ALLEGRO_ALIGN_INTEGER + : streq(value, "ALLEGRO_ALIGN_LEFT|ALLEGRO_ALIGN_INTEGER") + ? ALLEGRO_ALIGN_LEFT | ALLEGRO_ALIGN_INTEGER + : streq(value, "ALLEGRO_ALIGN_RIGHT|ALLEGRO_ALIGN_INTEGER") + ? ALLEGRO_ALIGN_RIGHT | ALLEGRO_ALIGN_INTEGER + : streq(value, "ALLEGRO_ALIGN_CENTRE|ALLEGRO_ALIGN_INTEGER") + ? ALLEGRO_ALIGN_CENTRE | ALLEGRO_ALIGN_INTEGER + : atoi(value); +} + +static void set_config_int(ALLEGRO_CONFIG *cfg, char const *section, + char const *var, int value) +{ + char buf[40]; + sprintf(buf, "%d", value); + al_set_config_value(cfg, section, var, buf); +} + +static void set_config_float(ALLEGRO_CONFIG *cfg, char const *section, + char const *var, float value) +{ + char buf[40]; + sprintf(buf, "%f", value); + al_set_config_value(cfg, section, var, buf); +} + +static void fill_vertices(ALLEGRO_CONFIG const *cfg, char const *name) +{ +#define MAXBUF 80 + + char const *value; + char buf[MAXBUF]; + float x, y, z; + float u, v; + int i; + + memset(vertices, 0, sizeof(vertices)); + + for (i = 0; i < MAX_VERTICES; i++) { + sprintf(buf, "v%d", i); + value = al_get_config_value(cfg, name, buf); + if (!value) + return; + + if (sscanf(value, " %f , %f , %f ; %f , %f ; %s", + &x, &y, &z, &u, &v, buf) == 6) { + vertices[i].x = x; + vertices[i].y = y; + vertices[i].z = z; + vertices[i].u = u; + vertices[i].v = v; + vertices[i].color = get_color(buf); + } + } + +#undef MAXBUF +} + +static void fill_simple_vertices(ALLEGRO_CONFIG const *cfg, char const *name) +{ +#define MAXBUF 80 + + char const *value; + char buf[MAXBUF]; + float x, y; + int i; + + memset(simple_vertices, 0, sizeof(simple_vertices)); + + for (i = 0; i < MAX_VERTICES; i++) { + sprintf(buf, "v%d", i); + value = al_get_config_value(cfg, name, buf); + if (!value) + break; + + if (sscanf(value, " %f , %f", &x, &y) == 2) { + simple_vertices[2*i + 0] = x; + simple_vertices[2*i + 1] = y; + } + } + + num_simple_vertices = i; + +#undef MAXBUF +} + +static void fill_vertex_counts(ALLEGRO_CONFIG const *cfg, char const *name) +{ +#define MAXBUF 80 + + char const *value; + char buf[MAXBUF]; + int count; + int i; + + memset(vertex_counts, 0, sizeof(vertex_counts)); + + for (i = 0; i < MAX_POLYGONS; i++) { + sprintf(buf, "p%d", i); + value = al_get_config_value(cfg, name, buf); + if (!value) + break; + + if (sscanf(value, " %d ", &count) == 1) { + vertex_counts[i] = count; + } + } + +#undef MAXBUF +} + +static int get_prim_type(char const *value) +{ + return streq(value, "ALLEGRO_PRIM_POINT_LIST") ? ALLEGRO_PRIM_POINT_LIST + : streq(value, "ALLEGRO_PRIM_LINE_LIST") ? ALLEGRO_PRIM_LINE_LIST + : streq(value, "ALLEGRO_PRIM_LINE_STRIP") ? ALLEGRO_PRIM_LINE_STRIP + : streq(value, "ALLEGRO_PRIM_LINE_LOOP") ? ALLEGRO_PRIM_LINE_LOOP + : streq(value, "ALLEGRO_PRIM_TRIANGLE_LIST") ? ALLEGRO_PRIM_TRIANGLE_LIST + : streq(value, "ALLEGRO_PRIM_TRIANGLE_STRIP") ? ALLEGRO_PRIM_TRIANGLE_STRIP + : streq(value, "ALLEGRO_PRIM_TRIANGLE_FAN") ? ALLEGRO_PRIM_TRIANGLE_FAN + : atoi(value); +} + +static int get_line_join(char const *value) +{ + return streq(value, "ALLEGRO_LINE_JOIN_NONE") ? ALLEGRO_LINE_JOIN_NONE + : streq(value, "ALLEGRO_LINE_JOIN_BEVEL") ? ALLEGRO_LINE_JOIN_BEVEL + : streq(value, "ALLEGRO_LINE_JOIN_ROUND") ? ALLEGRO_LINE_JOIN_ROUND + : streq(value, "ALLEGRO_LINE_JOIN_MITER") ? ALLEGRO_LINE_JOIN_MITER + : atoi(value); +} + +static int get_line_cap(char const *value) +{ + return streq(value, "ALLEGRO_LINE_CAP_NONE") ? ALLEGRO_LINE_CAP_NONE + : streq(value, "ALLEGRO_LINE_CAP_SQUARE") ? ALLEGRO_LINE_CAP_SQUARE + : streq(value, "ALLEGRO_LINE_CAP_ROUND") ? ALLEGRO_LINE_CAP_ROUND + : streq(value, "ALLEGRO_LINE_CAP_TRIANGLE") ? ALLEGRO_LINE_CAP_TRIANGLE + : streq(value, "ALLEGRO_LINE_CAP_CLOSED") ? ALLEGRO_LINE_CAP_CLOSED + : atoi(value); +} + +/* FNV-1a algorithm, parameters from: + * http://www.isthe.com/chongo/tech/comp/fnv/index.html + */ +#define FNV_OFFSET_BASIS 2166136261UL +#define FNV_PRIME 16777619 + +static uint32_t hash_bitmap(ALLEGRO_BITMAP *bmp) +{ + ALLEGRO_LOCKED_REGION *lr; + int x, y, w, h; + uint32_t hash; + + w = al_get_bitmap_width(bmp); + h = al_get_bitmap_height(bmp); + hash = FNV_OFFSET_BASIS; + + lr = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, + ALLEGRO_LOCK_READONLY); + + for (y = 0; y < h; y++) { + /* Oops, I unintentially committed the first version of this with signed + * chars and computing in BGRA order, so leave it like that so we don't + * have to update a bunch of old hashes. + */ + signed char const *data = ((signed char const *)lr->data) + y*lr->pitch; + for (x = 0; x < w; x++) { + hash ^= data[x*4 + 3]; hash *= FNV_PRIME; + hash ^= data[x*4 + 2]; hash *= FNV_PRIME; + hash ^= data[x*4 + 1]; hash *= FNV_PRIME; + hash ^= data[x*4 + 0]; hash *= FNV_PRIME; + } + } + + al_unlock_bitmap(bmp); + + return hash; +} + +/* Image "signature" I just made up: + * We take the average intensity of 7x7 patches centred at 9x9 grid points on + * the image. Each of these values is reduced down to 6 bits so it can be + * represented by one printable character in base64 encoding. This gives a + * reasonable signature length. + */ + +#define SIG_GRID 9 +#define SIG_LEN (SIG_GRID * SIG_GRID) +#define SIG_LENZ (SIG_LEN + 1) + +static int patch_intensity(ALLEGRO_BITMAP *bmp, int cx, int cy) +{ + float sum = 0.0; + int x, y; + + for (y = -3; y <= 3; y++) { + for (x = -3; x <= 3; x++) { + ALLEGRO_COLOR c = al_get_pixel(bmp, cx + x, cy + y); + sum += c.r + c.g + c.b; + } + } + + return 255 * sum/(7*7*3); +} + +static char const base64[64] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; + +static int base64_decode(char c) +{ + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'A' && c <= 'Z') return 10 + (c - 'A'); + if (c >= 'a' && c <= 'z') return 36 + (c - 'a'); + if (c == '+') return 62; + if (c == '/') return 63; + fatal_error("invalid base64 character: %c", c); + return -1; +} + +static void compute_signature(ALLEGRO_BITMAP *bmp, char sig[SIG_LENZ]) +{ + int w = al_get_bitmap_width(bmp); + int h = al_get_bitmap_height(bmp); + int x, y; + int n = 0; + + al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); + + for (y = 0; y < SIG_GRID; y++) { + for (x = 0; x < SIG_GRID; x++) { + int cx = (1 + x) * w/(1 + SIG_GRID); + int cy = (1 + y) * h/(1 + SIG_GRID); + int level = patch_intensity(bmp, cx, cy); + sig[n] = base64[level >> 2]; + n++; + } + } + + sig[n] = '\0'; + + al_unlock_bitmap(bmp); +} + +static bool similar_signatures(char const sig1[SIG_LEN], char const sig2[SIG_LEN]) +{ + int correct = 0; + int i; + + for (i = 0; i < SIG_LEN; i++) { + int q1 = base64_decode(sig1[i]); + int q2 = base64_decode(sig2[i]); + + /* A difference of one quantisation level could be because two values + * which were originally close by straddled a quantisation boundary. + * A difference of two quantisation levels is a significant deviation. + */ + if (abs(q1 - q2) > 1) + return false; + + correct++; + } + + return ((float)correct / SIG_LEN) > 0.95; +} + +static bool check_hash(ALLEGRO_CONFIG const *cfg, char const *testname, + ALLEGRO_BITMAP *bmp, BmpType bmp_type) +{ + char const *bt = bmp_type_to_string(bmp_type); + char hash[16]; + char sig[SIG_LENZ]; + char const *exp; + char const *sigexp; + + exp = al_get_config_value(cfg, testname, "hash"); + + sigexp = al_get_config_value(cfg, testname, "sig"); + + if (exp && streq(exp, "off")) { + printf("OK %s [%s] - hash check off\n", testname, bt); + passed_tests++; + return true; + } + + sprintf(hash, "%08x", hash_bitmap(bmp)); + compute_signature(bmp, sig); + + if (verbose) { + printf("hash=%s\n", hash); + printf("sig=%s\n", sig); + } + + if (!exp && !sigexp) { + printf("NEW %s [%s]\n\thash=%s\n\tsig=%s\n", + testname, bt, hash, sig); + return true; + } + + if (exp && streq(hash, exp)) { + printf("OK %s [%s]\n", testname, bt); + passed_tests++; + return true; + } + + if (sigexp && strlen(sigexp) != SIG_LEN) { + printf("WARNING: ignoring bad signature: %s\n", sigexp); + sigexp = NULL; + } + + if (sigexp && similar_signatures(sig, sigexp)) { + printf("OK %s [%s] - by signature\n", testname, bt); + passed_tests++; + return true; + } + + printf("FAIL %s [%s] - hash=%s\n", testname, bt, hash); + failed_tests++; + return false; +} + +static double bitmap_dissimilarity(ALLEGRO_BITMAP *bmp1, ALLEGRO_BITMAP *bmp2) +{ + ALLEGRO_LOCKED_REGION *lr1; + ALLEGRO_LOCKED_REGION *lr2; + int x, y, w, h; + double sqerr = 0.0; + + lr1 = al_lock_bitmap(bmp1, ALLEGRO_PIXEL_FORMAT_RGBA_8888, + ALLEGRO_LOCK_READONLY); + lr2 = al_lock_bitmap(bmp2, ALLEGRO_PIXEL_FORMAT_RGBA_8888, + ALLEGRO_LOCK_READONLY); + + w = al_get_bitmap_width(bmp1); + h = al_get_bitmap_height(bmp1); + + for (y = 0; y < h; y++) { + char const *data1 = ((char const *)lr1->data) + y*lr1->pitch; + char const *data2 = ((char const *)lr2->data) + y*lr2->pitch; + + for (x = 0; x < w*4; x++) { + double err = (double)data1[x] - (double)data2[x]; + sqerr += err*err; + } + } + + al_unlock_bitmap(bmp1); + al_unlock_bitmap(bmp2); + + return sqrt(sqerr / (w*h*4.0)); +} + +static bool check_similarity(ALLEGRO_CONFIG const *cfg, + char const *testname, + ALLEGRO_BITMAP *bmp1, ALLEGRO_BITMAP *bmp2, BmpType bmp_type, bool reliable) +{ + char const *bt = bmp_type_to_string(bmp_type); + double rms = bitmap_dissimilarity(bmp1, bmp2); + double tolerance; + char const *value; + + if (bmp_type == HW) { + char const *exp = al_get_config_value(cfg, testname, "hash_hw"); + char const *sigexp = al_get_config_value(cfg, testname, "sig_hw"); + char hash[16]; + char sig[SIG_LENZ]; + sprintf(hash, "%08x", hash_bitmap(bmp1)); + if (exp && streq(hash, exp)) { + printf("OK %s [%s]\n", testname, bt); + passed_tests++; + return true; + } + + if (sigexp && strlen(sigexp) != SIG_LEN) { + printf("WARNING: ignoring bad signature: %s\n", sigexp); + sigexp = NULL; + } + + compute_signature(bmp1, sig); + + if (sigexp && similar_signatures(sig, sigexp)) { + printf("OK %s [%s] - by signature\n", testname, bt); + passed_tests++; + return true; + } + } + + /* The default cutoff is "empirically determined" only. */ + if ((value = al_get_config_value(cfg, testname, "tolerance"))) + tolerance = atof(value); + else + tolerance = 17.5; + + if (rms <= tolerance) { + if (reliable) + printf("OK %s [%s]\n", testname, bt); + else + printf("OK? %s [%s]\n", testname, bt); + passed_tests++; + return true; + } + else { + char const *exp = al_get_config_value(cfg, testname, "hash"); + char hash[16]; + char sig[SIG_LENZ]; + sprintf(hash, "%08x", hash_bitmap(bmp1)); + + if (exp && streq(hash, exp)) { + printf("OK %s [%s]\n", testname, bt); + passed_tests++; + return true; + } + + printf("FAIL %s [%s] - RMS error is %g\n", testname, bt, rms); + printf("hash_hw=%s\n", hash); + compute_signature(bmp1, sig); + printf("sig_hw=%s\n", sig); + failed_tests++; + return false; + } +} + +static bool do_test(ALLEGRO_CONFIG *cfg, char const *testname, + ALLEGRO_BITMAP *target, int bmp_type, bool reliable, bool do_check_hash) +{ +#define MAXBUF 80 + + const char *section = testname; + int op; + char const *stmt; + char buf[MAXBUF]; + char arg[14][MAXBUF]; + char lval[MAXBUF]; + int i; + + if (verbose) { + /* So in case it segfaults, we know which test to re-run. */ + printf("\nRunning %s [%s].\n", testname, bmp_type_to_string(bmp_type)); + fflush(stdout); + } + + set_target_reset(target); + + for (op = 0; ; op++) { + sprintf(buf, "op%d", op); + stmt = al_get_config_value(cfg, testname, buf); + if (!stmt) { + /* Check for a common mistake. */ + sprintf(buf, "op%d", op+1); + stmt = al_get_config_value(cfg, testname, buf); + if (!stmt) + break; + printf("WARNING: op%d skipped, continuing at op%d\n", op, op+1); + op++; + } + + if (verbose > 1) + printf("# %s\n", stmt); + + if (streq(stmt, "")) + continue; + + if (SCAN("al_set_target_bitmap", 1)) { + al_set_target_bitmap(B(0)); + continue; + } + + if (SCAN("al_set_clipping_rectangle", 4)) { + al_set_clipping_rectangle(I(0), I(1), I(2), I(3)); + continue; + } + + if (SCAN("al_set_blender", 3)) { + al_set_blender( + get_blender_op(V(0)), + get_blend_factor(V(1)), + get_blend_factor(V(2))); + continue; + } + + if (SCAN("al_set_separate_blender", 6)) { + al_set_separate_blender( + get_blender_op(V(0)), + get_blend_factor(V(1)), + get_blend_factor(V(2)), + get_blender_op(V(3)), + get_blend_factor(V(4)), + get_blend_factor(V(5))); + continue; + } + + if (SCAN("al_set_bitmap_blender", 3)) { + al_set_bitmap_blender( + get_blender_op(V(0)), + get_blend_factor(V(1)), + get_blend_factor(V(2))); + continue; + } + + if (SCAN0("al_reset_bitmap_blender")) { + al_reset_bitmap_blender(); + continue; + } + + if (SCAN("al_set_new_bitmap_flags", 1)) { + al_set_new_bitmap_flags(get_bitmap_flags(V(0))); + continue; + } + + if (SCAN("al_set_new_bitmap_format", 1)) { + al_set_new_bitmap_format(get_pixel_format(V(0))); + continue; + } + + if (SCAN("al_clear_to_color", 1)) { + al_clear_to_color(C(0)); + continue; + } + + if (SCANLVAL("al_clone_bitmap", 1)) { + ALLEGRO_BITMAP **bmp = reserve_local_bitmap(lval, bmp_type); + (*bmp) = al_clone_bitmap(B(0)); + continue; + } + + if (SCAN("al_draw_bitmap", 4)) { + al_draw_bitmap(B(0), F(1), F(2), + get_draw_bitmap_flag(V(3))); + continue; + } + + if (SCAN("al_draw_tinted_bitmap", 5)) { + al_draw_tinted_bitmap(B(0), C(1), F(2), F(3), + get_draw_bitmap_flag(V(4))); + continue; + } + + if (SCAN("al_draw_bitmap_region", 8)) { + al_draw_bitmap_region(B(0), + F(1), F(2), F(3), F(4), F(5), F(6), + get_draw_bitmap_flag(V(7))); + continue; + } + + if (SCAN("al_draw_tinted_bitmap_region", 9)) { + al_draw_tinted_bitmap_region(B(0), C(1), + F(2), F(3), F(4), F(5), F(6), F(7), + get_draw_bitmap_flag(V(8))); + continue; + } + + if (SCAN("al_draw_rotated_bitmap", 7)) { + al_draw_rotated_bitmap(B(0), F(1), F(2), F(3), F(4), F(5), + get_draw_bitmap_flag(V(6))); + continue; + } + + if (SCAN("al_draw_tinted_rotated_bitmap", 8)) { + al_draw_tinted_rotated_bitmap(B(0), C(1), + F(2), F(3), F(4), F(5), F(6), + get_draw_bitmap_flag(V(7))); + continue; + } + + if (SCAN("al_draw_scaled_bitmap", 10)) { + al_draw_scaled_bitmap(B(0), + F(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), + get_draw_bitmap_flag(V(9))); + continue; + } + + if (SCAN("al_draw_tinted_scaled_bitmap", 11)) { + al_draw_tinted_scaled_bitmap(B(0), C(1), + F(2), F(3), F(4), F(5), F(6), F(7), F(8), F(9), + get_draw_bitmap_flag(V(10))); + continue; + } + + if (SCAN("al_draw_scaled_rotated_bitmap", 9)) { + al_draw_scaled_rotated_bitmap(B(0), + F(1), F(2), F(3), F(4), F(5), F(6), F(7), + get_draw_bitmap_flag(V(8))); + continue; + } + + if (SCAN("al_draw_tinted_scaled_rotated_bitmap", 10)) { + al_draw_tinted_scaled_rotated_bitmap(B(0), C(1), + F(2), F(3), F(4), F(5), F(6), F(7), F(8), + get_draw_bitmap_flag(V(9))); + continue; + } + + if (SCAN("al_draw_tinted_scaled_rotated_bitmap_region", 14)) { + al_draw_tinted_scaled_rotated_bitmap_region(B(0), F(1), F(2), + F(3), F(4), C(5), + F(6), F(7), F(8), F(9), F(10), F(11), F(12), + get_draw_bitmap_flag(V(13))); + continue; + } + + if (SCAN("al_draw_pixel", 3)) { + al_draw_pixel(F(0), F(1), C(2)); + continue; + } + + if (SCAN("al_put_pixel", 3)) { + al_put_pixel(I(0), I(1), C(2)); + continue; + } + + if (SCAN("al_put_blended_pixel", 3)) { + al_put_blended_pixel(I(0), I(1), C(2)); + continue; + } + + if (SCANLVAL("al_create_bitmap", 2)) { + ALLEGRO_BITMAP **bmp = reserve_local_bitmap(lval, bmp_type); + (*bmp) = al_create_bitmap(I(0), I(1)); + continue; + } + + if (SCANLVAL("al_create_sub_bitmap", 5)) { + ALLEGRO_BITMAP **bmp = reserve_local_bitmap(lval, bmp_type); + (*bmp) = al_create_sub_bitmap(B(0), I(1), I(2), I(3), I(4)); + continue; + } + + if (SCANLVAL("al_load_bitmap", 1)) { + ALLEGRO_BITMAP **bmp = reserve_local_bitmap(lval, bmp_type); + (*bmp) = load_relative_bitmap(V(0), 0); + continue; + } + if (SCANLVAL("al_load_bitmap_flags", 2)) { + ALLEGRO_BITMAP **bmp = reserve_local_bitmap(lval, bmp_type); + (*bmp) = load_relative_bitmap(V(0), get_load_bitmap_flag(V(1))); + continue; + } + if (SCAN("al_save_bitmap", 2)) { + if (!al_save_bitmap(V(0), B(1))) { + fatal_error("failed to save %s", V(0)); + } + continue; + } + if (SCANLVAL("al_identify_bitmap", 1)) { + char const *ext = al_identify_bitmap(V(0)); + if (!ext) + ext = "NULL"; + al_set_config_value(cfg, testname, lval, ext); + continue; + } + + if (SCAN("al_hold_bitmap_drawing", 1)) { + al_hold_bitmap_drawing(get_bool(V(0))); + continue; + } + + /* Transformations */ + if (SCAN("al_copy_transform", 2)) { + al_copy_transform(get_transform(V(0)), get_transform(V(1))); + continue; + } + if (SCAN("al_use_transform", 1)) { + al_use_transform(get_transform(V(0))); + continue; + } + if (SCAN("al_build_transform", 6)) { + al_build_transform(get_transform(V(0)), F(1), F(2), F(3), F(4), F(5)); + continue; + } + if (SCAN("al_translate_transform", 3)) { + al_translate_transform(get_transform(V(0)), F(1), F(2)); + continue; + } + if (SCAN("al_scale_transform", 3)) { + al_scale_transform(get_transform(V(0)), F(1), F(2)); + continue; + } + if (SCAN("al_rotate_transform", 2)) { + al_rotate_transform(get_transform(V(0)), F(1)); + continue; + } + if (SCAN("al_compose_transform", 2)) { + al_compose_transform(get_transform(V(0)), get_transform(V(1))); + continue; + } + + /* Conversion */ + if (SCAN("al_convert_bitmap", 1)) { + ALLEGRO_BITMAP *bmp = B(0); + al_convert_bitmap(bmp); + continue; + } + + /* Locking */ + if (SCAN("al_lock_bitmap", 3)) { + ALLEGRO_BITMAP *bmp = B(0); + lock_region.x = 0; + lock_region.y = 0; + lock_region.w = al_get_bitmap_width(bmp); + lock_region.h = al_get_bitmap_height(bmp); + lock_region.lr = al_lock_bitmap(bmp, + get_pixel_format(V(1)), + get_lock_bitmap_flags(V(2))); + continue; + } + if (SCAN("al_lock_bitmap_region", 7)) { + ALLEGRO_BITMAP *bmp = B(0); + lock_region.x = I(1); + lock_region.y = I(2); + lock_region.w = I(3); + lock_region.h = I(4); + lock_region.lr = al_lock_bitmap_region(bmp, + lock_region.x, lock_region.y, + lock_region.w, lock_region.h, + get_pixel_format(V(5)), + get_lock_bitmap_flags(V(6))); + continue; + } + if (SCAN("al_unlock_bitmap", 1)) { + al_unlock_bitmap(B(0)); + lock_region.lr = NULL; + continue; + } + if (SCAN("fill_lock_region", 2)) { + fill_lock_region(&lock_region, F(0), get_bool(V(1))); + continue; + } + + /* Fonts */ + if (SCAN("al_draw_text", 6)) { + al_draw_text(get_font(V(0)), C(1), F(2), F(3), get_font_align(V(4)), + V(5)); + continue; + } + if (SCAN("al_draw_justified_text", 8)) { + al_draw_justified_text(get_font(V(0)), C(1), F(2), F(3), F(4), F(5), + get_font_align(V(6)), V(7)); + continue; + } + if (SCANLVAL("al_get_text_width", 2)) { + int w = al_get_text_width(get_font(V(0)), V(1)); + set_config_int(cfg, testname, lval, w); + continue; + } + if (SCANLVAL("al_get_font_line_height", 1)) { + int h = al_get_font_line_height(get_font(V(0))); + set_config_int(cfg, testname, lval, h); + continue; + } + if (SCANLVAL("al_get_font_ascent", 1)) { + int as = al_get_font_ascent(get_font(V(0))); + set_config_int(cfg, testname, lval, as); + continue; + } + if (SCANLVAL("al_get_font_descent", 1)) { + int de = al_get_font_descent(get_font(V(0))); + set_config_int(cfg, testname, lval, de); + continue; + } + if (SCAN("al_get_text_dimensions", 6)) { + int bbx, bby, bbw, bbh; + al_get_text_dimensions(get_font(V(0)), V(1), &bbx, &bby, &bbw, &bbh); + set_config_int(cfg, testname, V(2), bbx); + set_config_int(cfg, testname, V(3), bby); + set_config_int(cfg, testname, V(4), bbw); + set_config_int(cfg, testname, V(5), bbh); + continue; + } + if (SCAN("al_set_fallback_font", 2)) { + al_set_fallback_font(get_font(V(0)), get_font(V(1))); + continue; + } + + /* Primitives */ + if (SCAN("al_draw_line", 6)) { + al_draw_line(F(0), F(1), F(2), F(3), C(4), F(5)); + continue; + } + if (SCAN("al_draw_triangle", 8)) { + al_draw_triangle(F(0), F(1), F(2), F(3), F(4), F(5), + C(6), F(7)); + continue; + } + if (SCAN("al_draw_filled_triangle", 7)) { + al_draw_filled_triangle(F(0), F(1), F(2), F(3), F(4), F(5), C(6)); + continue; + } + if (SCAN("al_draw_rectangle", 6)) { + al_draw_rectangle(F(0), F(1), F(2), F(3), C(4), F(5)); + continue; + } + if (SCAN("al_draw_filled_rectangle", 5)) { + al_draw_filled_rectangle(F(0), F(1), F(2), F(3), C(4)); + continue; + } + if (SCAN("al_draw_rounded_rectangle", 8)) { + al_draw_rounded_rectangle(F(0), F(1), F(2), F(3), F(4), F(5), C(6), + F(7)); + continue; + } + if (SCAN("al_draw_filled_rounded_rectangle", 7)) { + al_draw_filled_rounded_rectangle(F(0), F(1), F(2), F(3), F(4), F(5), + C(6)); + continue; + } + if (SCAN("al_draw_pieslice", 7)) { + al_draw_pieslice(F(0), F(1), F(2), F(3), F(4), C(5), F(6)); + continue; + } + if (SCAN("al_draw_filled_pieslice", 6)) { + al_draw_filled_pieslice(F(0), F(1), F(2), F(3), F(4), C(5)); + continue; + } + if (SCAN("al_draw_ellipse", 6)) { + al_draw_ellipse(F(0), F(1), F(2), F(3), C(4), F(5)); + continue; + } + if (SCAN("al_draw_filled_ellipse", 5)) { + al_draw_filled_ellipse(F(0), F(1), F(2), F(3), C(4)); + continue; + } + if (SCAN("al_draw_circle", 5)) { + al_draw_circle(F(0), F(1), F(2), C(3), F(4)); + continue; + } + if (SCAN("al_draw_filled_circle", 4)) { + al_draw_filled_circle(F(0), F(1), F(2), C(3)); + continue; + } + if (SCAN("al_draw_arc", 7)) { + al_draw_arc(F(0), F(1), F(2), F(3), F(4), C(5), F(6)); + continue; + } + if (SCAN("al_draw_elliptical_arc", 8)) { + al_draw_elliptical_arc(F(0), F(1), F(2), F(3), F(4), F(5), C(6), F(7)); + continue; + } + if (SCAN("al_draw_spline", 3)) { + float pt[8]; + if (sscanf(V(0), "%f, %f, %f, %f, %f, %f, %f, %f", + pt+0, pt+1, pt+2, pt+3, pt+4, pt+5, pt+6, pt+7) == 8) { + al_draw_spline(pt, C(1), F(2)); + continue; + } + } + if (SCAN("al_draw_prim", 6)) { + fill_vertices(cfg, V(0)); + /* decl arg is ignored */ + al_draw_prim(vertices, NULL, B(2), I(3), I(4), get_prim_type(V(5))); + continue; + } + + /* Keep 5.0 and 5.1 functions separate for easier merging. */ + + /* Primitives (5.1) */ + if (SCAN("al_draw_polyline", 6)) { + fill_simple_vertices(cfg, V(0)); + al_draw_polyline(simple_vertices, 2 * sizeof(float), + num_simple_vertices, get_line_join(V(1)), get_line_cap(V(2)), + C(3), F(4), F(5)); + continue; + } + if (SCAN("al_draw_polygon", 5)) { + fill_simple_vertices(cfg, V(0)); + al_draw_polygon(simple_vertices, num_simple_vertices, + get_line_join(V(1)), C(2), F(3), F(4)); + continue; + } + if (SCAN("al_draw_filled_polygon", 2)) { + fill_simple_vertices(cfg, V(0)); + al_draw_filled_polygon(simple_vertices, num_simple_vertices, C(1)); + continue; + } + if (SCAN("al_draw_filled_polygon_with_holes", 3)) { + fill_simple_vertices(cfg, V(0)); + fill_vertex_counts(cfg, V(1)); + al_draw_filled_polygon_with_holes(simple_vertices, vertex_counts, C(2)); + continue; + } + + /* Transformations (5.1) */ + if (SCAN("al_horizontal_shear_transform", 2)) { + al_horizontal_shear_transform(get_transform(V(0)), F(1)); + continue; + } + if (SCAN("al_vertical_shear_transform", 2)) { + al_vertical_shear_transform(get_transform(V(0)), F(1)); + continue; + } + if (SCAN("al_orthographic_transform", 7)) { + al_orthographic_transform(get_transform(V(0)), F(1), F(2), F(3), F(4), F(5), F(6)); + continue; + } + if (SCAN("al_use_projection_transform", 1)) { + al_use_projection_transform(get_transform(V(0))); + continue; + } + if (SCAN("al_set_blend_color", 1)) { + al_set_blend_color(C(0)); + continue; + } + + /* Simple arithmetic, generally useful. (5.1) */ + if (SCANLVAL("isum", 2)) { + int result = I(0) + I(1); + set_config_int(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("idif", 2)) { + int result = I(0) - I(1); + set_config_int(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("imul", 2)) { + int result = I(0) * I(1); + set_config_int(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("idiv", 2)) { + int result = I(0) / I(1); + set_config_int(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("fsum", 2)) { + float result = F(0) + F(1); + set_config_float(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("fdif", 2)) { + float result = F(0) - F(1); + set_config_float(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("fmul", 2)) { + float result = F(0) * F(1); + set_config_float(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("fdiv", 2)) { + float result = F(0) / F(1); + set_config_float(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("round", 1)) { + int result = round(F(0)); + set_config_int(cfg, testname, lval, result); + continue; + } + + /* Dynamical variable initialisation, needed to properly initialize + * variables (5.1)*/ + if (SCANLVAL("int", 1)) { + float result = F(0); + set_config_float(cfg, testname, lval, result); + continue; + } + if (SCANLVAL("float", 1)) { + float result = F(0); + set_config_float(cfg, testname, lval, result); + continue; + } + + /* Fonts: per glyph text handling (5.1) */ + if (SCAN("al_draw_glyph", 5)) { + al_draw_glyph(get_font(V(0)), C(1), F(2), F(3), I(4)); + continue; + } + if (SCANLVAL("al_get_glyph_advance", 3)) { + int kerning = al_get_glyph_advance(get_font(V(0)), I(1), I(2)); + set_config_int(cfg, testname, lval, kerning); + continue; + } + if (SCANLVAL("al_get_glyph_width", 2)) { + int w = al_get_glyph_width(get_font(V(0)), I(1)); + set_config_int(cfg, testname, lval, w); + continue; + } + if (SCANLVAL("al_get_glyph_dimensions", 6)) { + int bbx, bby, bbw, bbh; + bool ok = al_get_glyph_dimensions(get_font(V(0)), I(1), &bbx, &bby, &bbw, &bbh); + set_config_int(cfg, testname, V(2), bbx); + set_config_int(cfg, testname, V(3), bby); + set_config_int(cfg, testname, V(4), bbw); + set_config_int(cfg, testname, V(5), bbh); + set_config_int(cfg, testname, lval, ok); + continue; + } + + if (SCANLVAL("al_color_distance_ciede2000", 2)) { + float d = al_color_distance_ciede2000(C(0), C(1)); + set_config_float(cfg, testname, lval, d); + continue; + } + if (SCANLVAL("al_color_lab", 3)) { + ALLEGRO_COLOR rgb = al_color_lab(F(0), F(1), F(2)); + char hex[100]; + sprintf(hex, "%f/%f/%f", rgb.r, rgb.g, rgb.b); + al_set_config_value(cfg, testname, lval, hex); + continue; + } + + fatal_error("statement didn't scan: %s", stmt); + } + + al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA); + + bool good; + if (do_check_hash) { + good = check_hash(cfg, testname, target, bmp_type); + } + else { + good = check_similarity(cfg, testname, target, membuf, bmp_type, reliable); + } + + total_tests++; + + if (save_outputs && (!save_on_failure || !good)) { + ALLEGRO_USTR *filename = al_ustr_newf("%s [%s].png", testname, + bmp_type_to_string(bmp_type)); + al_save_bitmap(al_cstr(filename), target); + al_ustr_free(filename); + } + + if (!quiet) { + if (target != al_get_backbuffer(display)) { + set_target_reset(al_get_backbuffer(display)); + al_draw_bitmap(target, 0, 0, 0); + } + + al_flip_display(); + al_rest(delay); + } + + /* Ensure we don't target a bitmap which is about to be destroyed. */ + al_set_target_bitmap(display ? al_get_backbuffer(display) : NULL); + + /* Destroy local bitmaps. */ + for (i = num_global_bitmaps; i < MAX_BITMAPS; i++) { + if (bitmaps[i].name) { + al_ustr_free(bitmaps[i].name); + bitmaps[i].name = NULL; + al_destroy_bitmap(bitmaps[i].bitmap[bmp_type]); + bitmaps[i].bitmap[bmp_type] = NULL; + } + } + + /* Free transform names. */ + for (i = 0; i < MAX_TRANS; i++) { + al_ustr_free(transforms[i].name); + transforms[i].name = NULL; + } + + return good; +#undef MAXBUF +} + +static void sw_hw_test(ALLEGRO_CONFIG *cfg, char const *testname) +{ + bool reliable = true; + char const *hw_only_str = al_get_config_value(cfg, testname, "hw_only"); + char const *sw_only_str = al_get_config_value(cfg, testname, "sw_only"); + char const *skip_on_xvfb_str = al_get_config_value(cfg, testname, "skip_on_xvfb"); + bool hw_only = hw_only_str && get_bool(hw_only_str); + bool sw_only = sw_only_str && get_bool(sw_only_str); + bool skip_on_xvfb = skip_on_xvfb_str && get_bool(skip_on_xvfb_str); + + if (skip_on_xvfb && on_xvfb) { + skipped_tests++; + return; + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + if (!hw_only) { + reliable = do_test(cfg, testname, membuf, SW, true, true); + } + + if (sw_only) return; + + if (display) { + al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); + do_test(cfg, testname, al_get_backbuffer(display), HW, reliable, hw_only); + } else if (hw_only) { + printf("WARNING: Skipping hardware-only test due to the --no-display flag: %s\n", + testname); + skipped_tests++; + } +} + +static bool section_exists(ALLEGRO_CONFIG const *cfg, char const *section) +{ + ALLEGRO_CONFIG_ENTRY *iter; + + return al_get_first_config_entry(cfg, section, &iter) != NULL; +} + +static void merge_config_sections( + ALLEGRO_CONFIG *targ_cfg, char const *targ_section, + ALLEGRO_CONFIG const *src_cfg, char const *src_section) +{ + char const *key; + char const *value; + ALLEGRO_CONFIG_ENTRY *iter; + + value = al_get_config_value(src_cfg, src_section, "extend"); + if (value) { + if (streq(value, src_section)) { + fatal_error("section cannot extend itself: %s " + "(did you forget to rename a section?)", src_section); + } + merge_config_sections(targ_cfg, targ_section, src_cfg, value); + } + + key = al_get_first_config_entry(src_cfg, src_section, &iter); + if (!key) { + fatal_error("missing section: %s", src_section); + } + for (; key != NULL; key = al_get_next_config_entry(&iter)) { + value = al_get_config_value(src_cfg, src_section, key); + al_set_config_value(targ_cfg, targ_section, key, value); + } +} + +static void run_test(ALLEGRO_CONFIG const *cfg, char const *section) +{ + char const *extend; + ALLEGRO_CONFIG *cfg2; + + if (!section_exists(cfg, section)) { + fatal_error("section not found: %s", section); + } + + cfg2 = al_create_config(); + al_merge_config_into(cfg2, cfg); + extend = al_get_config_value(cfg, section, "extend"); + if (extend) { + merge_config_sections(cfg2, section, cfg, section); + } + sw_hw_test(cfg2, section); + al_destroy_config(cfg2); +} + +static void run_matching_tests(ALLEGRO_CONFIG const *cfg, const char *prefix) +{ + ALLEGRO_CONFIG_SECTION *iter; + char const *section; + + for (section = al_get_first_config_section(cfg, &iter); + section != NULL; + section = al_get_next_config_section(&iter)) { + if (0 == strncmp(section, prefix, strlen(prefix))) { + run_test(cfg, section); + } + } +} + +static void partial_tests(ALLEGRO_CONFIG const *cfg, int n) +{ + ALLEGRO_USTR *name = al_ustr_new(""); + + while (n > 0) { + /* Automatically prepend "test" for convenience. */ + if (0 == strncmp(argv[0], "test ", 5)) { + al_ustr_assign_cstr(name, argv[0]); + } + else { + al_ustr_truncate(name, 0); + al_ustr_appendf(name, "test %s", argv[0]); + } + + /* Star suffix means run all matching tests. */ + if (al_ustr_has_suffix_cstr(name, "*")) { + al_ustr_truncate(name, al_ustr_size(name) - 1); + run_matching_tests(cfg, al_cstr(name)); + } + else { + run_test(cfg, al_cstr(name)); + } + + argc--; + argv++; + n--; + } + + al_ustr_free(name); +} + +static bool has_suffix(char const *s, char const *suf) +{ + return (strlen(s) >= strlen(suf)) + && streq(s + strlen(s) - strlen(suf), suf); +} + +static void process_ini_files(void) +{ + ALLEGRO_CONFIG *cfg; + int n; + + while (argc > 0) { + if (!has_suffix(argv[0], ".ini")) + fatal_error("expected .ini argument: %s\n", argv[0]); + cfg = al_load_config_file(argv[0]); + if (!cfg) + fatal_error("failed to load config file %s", argv[0]); + + if (verbose) + printf("Running %s\n", argv[0]); + + argc--; + argv++; + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + load_bitmaps(cfg, "bitmaps", SW, ALLEGRO_NO_PREMULTIPLIED_ALPHA); + + if (display) { + al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); + load_bitmaps(cfg, "bitmaps", HW, ALLEGRO_NO_PREMULTIPLIED_ALPHA); + } + + load_fonts(cfg, "fonts"); + + for (n = 0; n < argc; n++) { + if (has_suffix(argv[n], ".ini")) + break; + } + + if (n == 0) + run_matching_tests(cfg, "test "); + else + partial_tests(cfg, n); + + unload_data(); + + al_destroy_config(cfg); + } +} + +const char* help_str = +" [OPTION] CONFIG_FILE [TEST_NAME]... [CONFIG_FILE [TEST_NAME]...]...\n" +"\n" +"Run Allegro graphical output tests within one or more CONFIG_FILEs (each\n" +"having an .ini extension). By default this program runs all the tests in a\n" +"file, but individual TEST_NAMEs can be specified after each CONFIG_FILE.\n" +"\n" +"Options:\n" +" -d, --delay duration (in sec) to wait between tests\n" +" --force-d3d force using D3D (Windows only)\n" +" --force-opengl-1.2 force using OpenGL 1.2\n" +" --force-opengl-2.0 force using OpenGL 2.0\n" +" --force-opengl force using OpenGL\n" +" -f, --save_on_failure save the output of failred tests in the current directory\n" +" -h, --help display this message\n" +" -n, --no-display do not create a display (hardware drawing is disabled)\n" +" -s, --save save the output of each test in the current directory\n" +" --use-shaders use the programmable pipeline for drawing\n" +" -v, --verbose show additional information after each test\n" +" -q, --quiet do not draw test output to the display\n" +" --xvfb indicates that we're running on XVFB, skipping tests if necessary\n"; + +int main(int _argc, char *_argv[]) +{ + int display_flags = 0; + + argc = _argc; + argv = _argv; + + if (argc == 1) { + fatal_error("requires config file argument.\nSee --help for usage"); + } + argc--; + argv++; + + if (!al_init()) { + fatal_error("failed to initialise Allegro"); + } + al_init_image_addon(); + al_init_font_addon(); + al_init_ttf_addon(); + al_init_primitives_addon(); + + for (; argc > 0; argc--, argv++) { + char const *opt = argv[0]; + if (streq(opt, "-d") || streq(opt, "--delay")) { + delay = 1.0; + } + else if (streq(opt, "-s") || streq(opt, "--save")) { + save_outputs = true; + } + else if (streq(opt, "-f") || streq(opt, "--save_on_failure")) { + save_on_failure = true; + save_outputs = true; + } + else if (streq(opt, "--xvfb")) { + on_xvfb = true; + } + else if (streq(opt, "-q") || streq(opt, "--quiet")) { + quiet = true; + } + else if (streq(opt, "-n") || streq(opt, "--no-display")) { + want_display = false; + quiet = true; + } + else if (streq(opt, "-v") || streq(opt, "--verbose")) { + verbose++; + } + else if (streq(opt, "--force-opengl-1.2")) { + ALLEGRO_CONFIG *cfg = al_get_system_config(); + al_set_config_value(cfg, "opengl", "force_opengl_version", "1.2"); + display_flags |= ALLEGRO_OPENGL; + } + else if (streq(opt, "--force-opengl-2.0")) { + ALLEGRO_CONFIG *cfg = al_get_system_config(); + al_set_config_value(cfg, "opengl", "force_opengl_version", "2.0"); + display_flags |= ALLEGRO_OPENGL; + } + else if (streq(opt, "--force-opengl")) { + display_flags |= ALLEGRO_OPENGL; + } + else if (streq(opt, "--force-d3d")) { + /* Don't try this at home. */ + display_flags |= ALLEGRO_DIRECT3D_INTERNAL; + } + else if (streq(opt, "--use-shaders")) { + display_flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; + } + else if (streq(opt, "-h") || streq(opt, "--help")) { + printf("Usage:\n%s%s", _argv[0], help_str); + return 0; + } + else { + break; + } + } + + if (want_display) { + al_set_new_display_flags(display_flags); + display = al_create_display(640, 480); + if (!display) { + fatal_error("failed to create display"); + } + } + + al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); + + if (want_display) { + membuf = al_create_bitmap( + al_get_display_width(display), + al_get_display_height(display)); + } + else { + membuf = al_create_bitmap(640, 480); + } + + process_ini_files(); + + printf("\n"); + printf("total tests: %d\n", total_tests); + printf("passed tests: %d\n", passed_tests); + printf("failed tests: %d\n", failed_tests); + printf("skipped tests: %d\n", skipped_tests); + printf("\n"); + + return !!failed_tests; +} + +/* vim: set sts=3 sw=3 et: */ diff --git a/allegro/tests/test_driver.txt b/allegro/tests/test_driver.txt new file mode 100644 index 00000000..1bd37489 --- /dev/null +++ b/allegro/tests/test_driver.txt @@ -0,0 +1,101 @@ +Usage +===== + + test_driver [OPTIONS] config1.ini [TESTS ...] [config2.ini [TESTS...]] ... + +where options are: + + -d, --delay + delay between tests + + -s, --save + save output images as .png + + -q, --quiet + don't display graphical output + + -v, --verbose + print extra output + + -v -v + extra extra verbose + + --force-opengl + select OpenGL driver + + --force-opengl-1.2 + restrict Allegro to OpenGL 1.2 + + --force-opengl-2.0 + restrict Allegro to OpenGL 2.0 + + --force-d3d + select Direct3D driver + +If the list of tests is omitted then every test in the config file will be run. +Otherwise each test named on the command line is run. For convenience, you may +drop the "test " prefix on test names. + +If a test name ends with an asterisk, then all tests which match that prefix +will be run, e.g. + + ./test_driver -d test_bitmaps.ini 'scaled rotate*' + +Every test is run with both memory and video bitmaps. The software rendered +result is checked against an expected hash code. The hardware rendered result +is checked for similarity with the software result. + + +Config file format +================== + +Each [test ...] section defines a single test, containing one or more +operations named by the keys op0, op1, ... opN. The value of each op +key is a call to an Allegro function, or empty. Each argument of the +call must be a literal of the correct type, or a variable name. + +A variable name is just another key in the section, whose value is taken +as a _literal_ to be substituted in place of the variable. + +A test may inherit the keys of another section using the 'extend' key. +Keys in the child section override keys in the parent. + +The [bitmaps] section defines a list of bitmaps to load, relative to the +tests directory. Each key name is then a valid bitmap literal. +The name 'target' refers to the default target bitmap. + +ALLEGRO_COLOR literals may be written as #rrggbb, #rrggbbaa or a named +color (e.g. purple). + +Integer, float and enumeration literals are written as per C. +(Note that "ALLEGRO_FLIP_HORIZONTAL|ALLEGRO_FLIP_VERTICAL" must be written +without whitespace, because we don't have a proper parser.) + +String literals are not supported, but you can use a variable whose value +is treated as the string contents (no quotes). + +Transformations are automatically created the first time they are mentioned, +and set to the identity matrix. + +Each test section contains a key called 'hash', containing the hash code +of the expected output for that test. When writing a test you should +check (visually) that the output looks correct, then add the hash code +computed hash code to the test section. + +Some tests produce slightly different (but still acceptable) output depending +on the hardware, compiler or optimisation settings. As an alternative to +'hash', which will only pass if the result is exactly the same, you can use +the 'sig' key. This will perform a loose comparison on "signatures" which are +computed from the average intensity levels (greyscale) at 81 points on the +image. Hopefully it is still strict enough to catch any major regressions. +You can supply both 'hash' and 'sig' keys. + +Finally, 'hash=off' will disable hash checking entirely. For example, TTF +rendering depends on the FreeType configuration, and the differences are big +enough to show up even in the thumbnails. + +The hardware implementation is compared against the software implementation, +with some tolerance. The tolerance is arbitrary but you can set it if +necessary with the 'tolerance' key. In case the HW results is supposed +to look different, a separate hash can be specifeid with 'hw_hash' +instead of the similarity comparison. diff --git a/allegro/tests/test_fonts.ini b/allegro/tests/test_fonts.ini new file mode 100644 index 00000000..caab8f86 --- /dev/null +++ b/allegro/tests/test_fonts.ini @@ -0,0 +1,282 @@ +[fonts] +bmpfont=al_load_font(bmp_filename, 24, flags) +asciifont=al_load_font(ascii_filename, 24, flags) +builtin=al_create_builtin_font() +ttf=al_load_font(ttf_filename, 24, flags) +ttf_tall=al_load_ttf_font_stretch(ttf_filename, 24, 48, flags) +ttf_wide=al_load_ttf_font_stretch(ttf_filename, 48, 24, flags) +ttf_px1=al_load_font(ttf_filename, -32, flags) +ttf_px2=al_load_ttf_font_stretch(ttf_filename, 0, -32, flags) +ttf_px3=al_load_ttf_font_stretch(ttf_filename, -24, -32, flags) +# arguments +bmp_filename=../examples/data/a4_font.tga +ascii_filename=../examples/data/fixed_font.tga +ttf_filename=../examples/data/DejaVuSans.ttf +flags=ALLEGRO_NO_PREMULTIPLIED_ALPHA + +[text] +en=Welcome to Allegro +gr=Καλώς ήρθατε στο Allegro +latin1=aábdðeéfghiíjkprstuúvxyýþæö +missing=here -> á <- is unicode #00E1 + +[test font bmp] +extend=text +op0=al_clear_to_color(rosybrown) +op1=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op2= +op3=al_draw_text(font, darkred, 320, 100, ALLEGRO_ALIGN_LEFT, en) +op4=al_draw_text(font, white, 320, 150, ALLEGRO_ALIGN_CENTRE, en) +op5=al_draw_text(font, blue, 320, 200, ALLEGRO_ALIGN_RIGHT, en) +op6= +font=bmpfont +hash=68f73534 + +[test font bmp hold] +extend=test font bmp +op2=al_hold_bitmap_drawing(true) +op6=al_hold_bitmap_drawing(false) + +[test font builtin] +extend=text +op0=al_clear_to_color(rosybrown) +op1=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op2=al_draw_text(font, darkred, 320, 100, ALLEGRO_ALIGN_LEFT, en) +op3=al_draw_text(font, white, 320, 150, ALLEGRO_ALIGN_CENTRE, latin1) +font=builtin +hash=502aa12f + +[test font ttf] +extend=test font bmp +op6=al_draw_text(font, khaki, 320, 300, ALLEGRO_ALIGN_CENTRE, gr) +font=ttf +# Result changes with the FreeType configuration of the system. +hash=off + +[test font ttf hold] +extend=test font ttf +op2=al_hold_bitmap_drawing(true) +op7=al_hold_bitmap_drawing(false) + +[test font ttf tall] +extend=test font ttf +font=ttf_tall + +[test font ttf wide] +extend=test font ttf +font=ttf_wide + +[test font ttf pixelsize 1] +extend=test font ttf +font=ttf_px1 + +[test font ttf pixelsize 2] +extend=test font ttf +font=ttf_px2 + +[test font ttf pixelsize 3] +extend=test font ttf +font=ttf_px3 + +[test font bmp justify] +extend=text +op0=al_clear_to_color(#886655) +op1=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op2=al_draw_justified_text(bmpfont, black, 100, 540, 100, 0, 0, en) +op3=al_draw_justified_text(bmpfont, black, 100, 540, 150, 1000, 0, en) +hash=6a402079 + +[test font ttf justify] +extend=test font bmp justify +op4=al_draw_justified_text(ttf, black, 100, 540, 300, 0, 0, gr) +op5=al_draw_justified_text(ttf, black, 100, 540, 350, 1000, 0, gr) +# Result changes with the FreeType configuration of the system. +hash=off + +[test font complex] +extend=text +op0=al_clear_to_color(#665544) +op1=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op2=al_build_transform(T, cx, cy, 2.0, 2.0, -0.3) +op3=al_use_transform(T) +op4=al_draw_text(ttf, #aabbcc80, 0, 0, ALLEGRO_ALIGN_CENTRE, en) +op5=al_build_transform(T, cx, cy, 2.0, 2.0, 0.3) +op6=al_use_transform(T) +op7=al_draw_text(ttf, #eebbaa80, 0, 0, ALLEGRO_ALIGN_CENTRE, gr) +op8=al_build_transform(T2, cx, 360, 20, 20, 0) +op9=al_use_transform(T2) +op10=al_draw_text(bmpfont, #88888855, 0, 0, ALLEGRO_ALIGN_CENTRE, yeah) +cx=320 +cy=200 +yeah=yeah! +# Result changes with the FreeType configuration of the system. +hash=off + +[test font dimensions ttf en] +op0= al_clear_to_color(#665544) +op1= al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op2= al_translate_transform(T, 100, 100) +op3= al_use_transform(T) +op4= al_get_text_dimensions(font, str, bbx, bby, bbw, bbh) +# We can't actually draw it without introducing arithmetic. +#op5=al_draw_rectangle(bbx, bby, bbx+bbw, bby+bbh, black, 0) +op5= +op6= al_draw_text(font, #aabbcc80, 0, 0, ALLEGRO_ALIGN_LEFT, str) +op7= +op8= al_translate_transform(T, 0, 100) +op9= al_use_transform(T) +op10=w = al_get_text_width(font, str) +op11=h = al_get_font_line_height(font) +op12=as = al_get_font_ascent(font) +op13=de = al_get_font_descent(font) +# Note: the hw version blurs the lines because we can't add 0.5 offsets. +op14=al_draw_rectangle(0, 0, w, h, black, 0) +op15=al_draw_line(0, as, w, as, black, 0) +op16=al_draw_line(0, de, w, de, black, 0) +op17=al_draw_text(font, #aabbcc80, 0, 0, ALLEGRO_ALIGN_LEFT, str) +font=ttf +str=Welcome to Allegro +hash=off + +[test font dimensions ttf gr] +extend=test font dimensions ttf en +str=Καλώς ήρθατε στο Allegro +hash=off + +[test font dimensions bmp] +extend=test font dimensions ttf en +font=bmpfont +hash=4284d74d + +# Not a font test but requires a font. +[test d3d cache state bug] +op0=image = al_create_bitmap(20, 20) +op1=al_set_target_bitmap(image) +op2=al_clear_to_color(white) +op3=al_set_target_bitmap(target) +op4=al_clear_to_color(#00000000) +op5=al_draw_text(bmpfont, red, 0, 0, ALLEGRO_ALIGN_LEFT, str) +op6=al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ALPHA, ALLEGRO_ONE) +op7=al_draw_rectangle(45, 45, 75, 75, #ffffff40, 1) +op8=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA) +op9=al_draw_tinted_bitmap(image, #ffffffff, 50, 50, 0) +str=Hello +hash=249efe55 + +# Per glyph drawing +[test font glyph simple builtin en] +op0= al_clear_to_color(#665544) +op1= al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op2= x = int(100) +op3= y = int(100) +op4= +# al_hold_bitmap_drawing(1) +op5= al_draw_glyph(font, glyph_color, x, y, glyph) +# op6= al_hold_bitmap_drawing(0) +font=builtin +glyph=84 +x=100 +y=100 +glyph_color=#00ff00ff +hash=5a674455 + +[test font glyph simple bmp en] +extend=test font glyph simple builtin en +font=bmpfont +hash=5a674455 + + +[test font glyph simple ttf en] +extend=test font glyph simple builtin en +font=ttf +hash=6ed595a5 +sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test font glyph simple ttf gr] +extend=test font glyph simple builtin en +font=ttf +glyph=922 +hash=f02da2af +sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +# Per glyph drawing +[test font glyph match builtin en] +op0= al_clear_to_color(#665544) +op1= al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op2= x = int(100) +op3= y = int(100) +op4= +# al_hold_bitmap_drawing(0) +op5= al_draw_text(font, blue, x, y, ALLEGRO_ALIGN_LEFT, str) +op6= al_draw_text(font, text_color, x, y, ALLEGRO_ALIGN_LEFT, str) +op7= glyph_Tu_k = al_get_glyph_advance(font, glyph_T, glyph_u) +op8= glyph_ul_k = al_get_glyph_advance(font, glyph_u, glyph_l) +op9= glyph_li_k = al_get_glyph_advance(font, glyph_l, glyph_i) +op10= glyph_ip_k = al_get_glyph_advance(font, glyph_i, glyph_p) +op11= al_draw_glyph(font, glyph_color, x, y, glyph_T) +op12= x = isum(x, glyph_Tu_k) +op13= al_draw_glyph(font, glyph_color, x, y, glyph_u) +op14= x = isum(x, glyph_ul_k) +op15= al_draw_glyph(font, glyph_color, x, y, glyph_l) +op16= x = isum(x, glyph_li_k) +op17= al_draw_glyph(font, glyph_color, x, y, glyph_i) +op18= x = isum(x, glyph_ip_k) +op19= al_draw_glyph(font, glyph_color, x, y, glyph_p) +op20= x = isum(x, glyph_p_w) +op21= h = al_get_font_line_height(font) +op22= x = int(100) +op23= y = int(100) +op24= +# al_hold_bitmap_drawing(0) +font=builtin +str=Tulip +glyph_T=84 +glyph_u=117 +glyph_l=108 +glyph_i=105 +glyph_p=112 +glyph_Tu_k=0 +glyph_ul_k=0 +glyph_li_k=0 +glyph_ip_k=0 +x=100 +y=100 +text_color=#ff0000ff +glyph_color=#00ff00ff +hash=60affa5d + + +[test font glyph match bmp en] +extend=test font glyph match builtin en +font=bmpfont +str=Tulip +hash=60affa5d + +[test font glyph match ttf en] +extend=test font glyph match builtin en +font=ttf +hash=5857f828 +sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test font glyph match ttf gr] +extend=test font glyph match ttf en +glyph_T=922 +glyph_u=945 +glyph_l=955 +glyph_i=974 +glyph_p=962 +str=Καλώς +font=ttf +hash=f0ff79f6 +sig=LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL + +[test font fallback] +extend=text +op0=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op1=al_clear_to_color(black) +op2=al_draw_text(asciifont, yellow, 100, 100, 0, missing) +op3=al_set_fallback_font(asciifont, builtin) +op4=al_draw_text(asciifont, yellow, 100, 120, 0, missing) +op5=al_set_fallback_font(asciifont, NULL) +op6=al_draw_text(builtin, yellow, 100, 140, 0, missing) +hash=c4ee101f diff --git a/allegro/tests/test_image.ini b/allegro/tests/test_image.ini new file mode 100644 index 00000000..c81cee86 --- /dev/null +++ b/allegro/tests/test_image.ini @@ -0,0 +1,185 @@ +[bitmaps] +allegro=../examples/data/allegro.pcx + +[fonts] +builtin=al_create_builtin_font() + +# We can't assume that a backbuffer with alpha is available, so draw +# to a temporary bitmap. +[template] +op0=temp = al_create_bitmap(640, 480) +op1=al_set_target_bitmap(temp) +op2=al_clear_to_color(brown) +op3=b = al_load_bitmap_flags(filename, flags) +op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA) +op5=al_draw_bitmap(b, 0, 0, 0) +op6=al_set_target_bitmap(target) +op7=al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE) +op8=al_draw_bitmap(temp, 0, 0, 0) +flags=ALLEGRO_NO_PREMULTIPLIED_ALPHA + +[test bmp] +extend=template +filename=../examples/data/fakeamp.bmp +hash=62176b87 + +[test bmp 8bpp] +extend=template +filename=../examples/data/alexlogo.bmp +hash=08b3a51d + +[test jpg] +extend=template +filename=../examples/data/obp.jpg +hash=8e37f5f3 +sig=lXWWYJaWKicWTKIXYKdecgPKaYKaeHLRLbYKhJSEFHbZKhJIHFJdYKn1IEFabVKPSQNPNNNKKKKKKKKKK + +[test pcx] +extend=template +filename=../examples/data/allegro.pcx +hash=c44929e5 + +[test png] +extend=template +filename=../examples/data/mysha256x256.png +hash=771a3491 + +[test png premul] +extend=template +filename=../examples/data/mysha256x256.png +flags=0 +hash=48965052 + +[test tga] +extend=template +filename=../examples/data/fixed_font.tga +hash=64fa3221 + +[test webp] +extend=template +filename=../examples/data/mysha256x256.webp +hash=771a3491 + +[test webp premul] +extend=template +filename=../examples/data/mysha256x256.webp +flags=0 +hash=48965052 + + +# These indexed images may be displayed in shades of red (OpenGL >= 3) +# or greyscale (OpenGL < 3). + +[test bmp indexed] +extend=template +filename=../examples/data/alexlogo.bmp +flags=ALLEGRO_KEEP_INDEX +hash=1d899e47 + +[test bmp indexed uncompressed] +extend=template +filename=../examples/data/gradient1.bmp +flags=ALLEGRO_KEEP_INDEX +hash=b5ba9d35 + +[test pcx indexed] +extend=template +filename=../examples/data/allegro.pcx +flags=ALLEGRO_KEEP_INDEX +hash=681b712d +hash_hw=6fb8e2d5 + +[test png indexed] +extend=template +filename=../examples/data/alexlogo.png +flags=ALLEGRO_KEEP_INDEX +hash=1d899e47 + +[test png palette] +extend=template +filename=../examples/data/mysha_pal.png +flags=0 +# TODO: Figure out why this fails on 32 bits. +sig=FlOKKKKKKugMKKKKKKjLKKKKKKK26FKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK + +[test png interlaced] +extend=template +filename=../examples/data/icon.png +flags=0 +hash=9e6b5342 + +[save template] +op0=al_save_bitmap(filename, allegro) +op1=b = al_load_bitmap_flags(filename, ALLEGRO_NO_PREMULTIPLIED_ALPHA) +op2=al_clear_to_color(brown) +op3=al_draw_bitmap(b, 0, 0, 0) + +[test save bmp] +extend=save template +filename=tmp.bmp +hash=c44929e5 + +[test save jpg] +extend=save template +filename=tmp.jpg +sig=jdelWKKKKaYmeXKKKKLNVNKKKKKHHHLLKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK + +[test save pcx] +extend=save template +filename=tmp.pcx +hash=c44929e5 + +[test save png] +extend=save template +filename=tmp.png +hash=c44929e5 + +[test save tga] +extend=save template +filename=tmp.tga +hash=c44929e5 + +[test save webp] +extend=save template +filename=tmp.webp +hash=c44929e5 + +[identify] +op0=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA) +op1=ext = al_identify_bitmap(filename) +op2=al_draw_text(builtin, yellow, 0, 0, 0, ext) + +[test identify bmp] +extend = identify +filename=../examples/data/fakeamp.bmp +hash=b5436ae7 + +[test identify png] +extend = identify +filename=../examples/data/alexlogo.png +hash=05da299b + +[test identify jpg] +extend = identify +filename=../examples/data/obp.jpg +hash=6e2b0f7d + +[test identify pcx] +extend = identify +filename=../examples/data/allegro.pcx +hash=5d1d24db + +[test identify tga] +extend = identify +filename=../examples/data/fixed_font.tga +hash=fca11c13 + +[test identify webp] +extend = identify +filename=../examples/data/mysha256x256.webp +hash=30a6aae7 + +[test identify dds] +extend = identify +filename=../examples/data/mysha_dxt5.dds +hash=84ab6fb5 diff --git a/allegro/tests/test_locking.ini b/allegro/tests/test_locking.ini new file mode 100644 index 00000000..08e54a80 --- /dev/null +++ b/allegro/tests/test_locking.ini @@ -0,0 +1,128 @@ +# Too many parameters to test... +# target: memory, backbuffer, off-screen texture +# mode: WRITEONLY, READWRITE, READONLY +# all the pixel formats (24b especially problematic) +# odd sizes especially problematic +# lock region or entire bitmap + +# Locking an off-screen bitmap + +[texture] +op0= al_clear_to_color(#554321) +op1= +op2= bmp = al_create_bitmap(640, 480) +op3= al_set_target_bitmap(bmp) +op4= al_clear_to_color(#00000000) +op5= al_lock_bitmap_region(bmp, 133, 65, 381, 327, format, flags) +op6= fill_lock_region(alphafactor, false) +op7= al_unlock_bitmap(bmp) +op8= +op9= al_set_target_bitmap(target) +op10=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op11=al_draw_bitmap(bmp, 0, 0, 0) +flags=ALLEGRO_LOCK_WRITEONLY +alphafactor=1.0 + +[test texture 32b ARGB_8888] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_ARGB_8888 +hash=25e01c26 +sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF + +[test texture 32b RGBA_8888] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_RGBA_8888 +hash=25e01c26 +sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF + +[test texture 16b ARGB_4444] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_ARGB_4444 +hash=94ba90ac +sig=FFFFFFFFFFFDDDEIKFFFEEFIMOFFFEEHKQSFFFFGKOWXFFFFHMRabFFFGIOVffFFFGJQXkjFFFFFFFFFF + +[test texture 24b RGB_888] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_RGB_888 +hash=5a844e39 +sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF + +[test texture 16b RGB_565] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_RGB_565 +hash=7ee470cd + +[test texture 15b RGB_555] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_RGB_555 +hash=d8bcc9c6 + +[test texture 16b RGBA_5551] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_RGBA_5551 +alphafactor=2.0 +hash=752a4074 + +[test texture 16b ARGB_1555] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_ARGB_1555 +alphafactor=2.0 +hash=752a4074 + +[test texture 32b ABGR_8888] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_ABGR_8888 +hash=25e01c26 +sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF + +[test texture 32b XBGR_8888] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_XBGR_8888 +hash=5a844e39 +sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF + +[test texture 24b BGR_888] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_BGR_888 +hash=5a844e39 +sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF + +[test texture 16b BGR_565] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_BGR_565 +hash=7ee470cd + +[test texture 15b BGR_555] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_BGR_555 +hash=d8bcc9c6 + +[test texture 32b RGBX_8888] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_RGBX_8888 +hash=5a844e39 +sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF + +[test texture 32b XRGB_8888] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_XRGB_8888 +hash=5a844e39 +sig=FFFFFFFFFFF59DHLMFFF9DIMQQFFFCHMRWVFFFGLRWcZFFFJPWcieFFFNUahniFFFRYfmtnFFFFFFFFFF + +[test texture f32 ABGR_F32] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_ABGR_F32 +hash=25e01c26 +sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF + +[test texture 32b ABGR_8888_LE] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE +hash=25e01c26 +sig=FFFFFFFFFFFDDEGKMFFFEEGJOQFFFEGINTVFFFFHLQYZFFFFINUcdFFFGKPXhiFFFHLSbmmFFFFFFFFFF + +[test texture 16b RGBA_4444] +extend=texture +format=ALLEGRO_PIXEL_FORMAT_RGBA_4444 +hash=94ba90ac +sig=FFFFFFFFFFFDDDEIKFFFEEFIMOFFFEEHKQSFFFFGKOWXFFFFHMRabFFFGIOVffFFFGJQXkjFFFFFFFFFF diff --git a/allegro/tests/test_locking2.ini b/allegro/tests/test_locking2.ini new file mode 100644 index 00000000..4d61c6c2 --- /dev/null +++ b/allegro/tests/test_locking2.ini @@ -0,0 +1,116 @@ +[texture rw] +op0= al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op1= +op2= bmp = al_create_bitmap(640, 480) +op3= al_set_target_bitmap(bmp) +op4= al_clear_to_color(#554321) +op5= al_lock_bitmap_region(bmp, 133, 65, 381, 327, format, flags) +op6= fill_lock_region(alphafactor, true) +op7= al_unlock_bitmap(bmp) +op8= +op9= al_set_target_bitmap(target) +op10=al_clear_to_color(#00ff00) +# Don't assume the screen has an alpha channel, it may be 24 bit. +op11=al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE) +op12=al_draw_bitmap(bmp, 0, 0, 0) +flags=ALLEGRO_LOCK_READWRITE +alphafactor=1.0 + +[test texture rw 32b ARGB_8888] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_ARGB_8888 +hash=d4866407 +sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF + +[test texture rw 32b RGBA_8888] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_RGBA_8888 +hash=d4866407 +sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF + +[test texture rw 16b ARGB_4444] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_ARGB_4444 +hash=32b551c9 + +[test texture rw 24b RGB_888] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_RGB_888 +hash=dc5525e2 + +[test texture rw 16b RGB_565] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_RGB_565 +hash=a51f89f0 + +[test texture rw 15b RGB_555] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_RGB_555 +hash=200647c4 + +[test texture rw 16b RGBA_5551] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_RGBA_5551 +hash=c42fb611 +# NOTE: the correct output for this is all green except for one pixel column +# on the right. + +[test texture rw 16b ARGB_1555] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_ARGB_1555 +hash=c42fb611 +# NOTE: the correct output for this is all green except for one pixel column +# on the right. + +[test texture rw 32b ABGR_8888] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_ABGR_8888 +hash=d4866407 +sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF + +[test texture rw 32b XBGR_8888] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_XBGR_8888 +hash=dc5525e2 + +[test texture rw 24b BGR_888] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_BGR_888 +hash=dc5525e2 + +[test texture rw 16b BGR_565] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_BGR_565 +hash=a51f89f0 + +[test texture rw 15b BGR_555] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_BGR_555 +hash=200647c4 + +[test texture rw 32b RGBX_8888] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_RGBX_8888 +hash=dc5525e2 + +[test texture rw 32b XRGB_8888] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_XRGB_8888 +hash=dc5525e2 + +[test texture rw f32 ABGR_F32] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_ABGR_F32 +hash=d4866407 +sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF + +[test texture rw 32b ABGR_8888_LE] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE +hash=d4866407 +sig=FFFFFFFFFFFEEFHKMFFFFFHKOQFFFFHJMSUFFFGILPWZFFFGJMSadFFFHKOUeiFFFHLQXimFFFFFFFFFF + +[test texture rw 16b RGBA_4444] +extend=texture rw +format=ALLEGRO_PIXEL_FORMAT_RGBA_4444 +hash=32b551c9 diff --git a/allegro/tests/test_prim.ini b/allegro/tests/test_prim.ini new file mode 100644 index 00000000..07298748 --- /dev/null +++ b/allegro/tests/test_prim.ini @@ -0,0 +1,424 @@ +[bitmaps] +bkg=../examples/data/bkg.png +texture=../examples/data/texture.tga +obp=../examples/data/obp.jpg + + +[ll] +op0= al_draw_bitmap(bkg, 0, 0, 0) +op1= al_build_transform(trans, 320, 240, 1, 1, 1.0) +op2= +op3= al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) +op4= al_use_transform(trans) +op5= al_draw_prim(verts, 0, tex, 0, 4, ALLEGRO_PRIM_LINE_LIST) +op6= al_draw_prim(verts, 0, tex, 4, 9, ALLEGRO_PRIM_LINE_STRIP) +op7= al_draw_prim(verts, 0, tex, 9, 13, ALLEGRO_PRIM_LINE_LOOP) +verts=vtx_ll +tex=0 + +[test ll notex blend] +extend=ll +hash=3e2bdb71 + +[test ll notex opaque] +extend=ll +op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) +hash=8e491071 + +[test ll tex blend] +extend=ll +tex=texture +hash=002007ce + +[test ll tex blend white] +extend=ll +verts=vtx_ll_white +tex=texture +hash=cccd8111 + +[test ll tex opaque] +extend=ll +op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) +tex=texture +hash=be2f916a + +[test ll tex opaque white] +extend=ll +op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) +verts=vtx_ll_white +tex=texture +hash=92099701 + + +[hl] +op0= al_draw_bitmap(bkg, 0, 0, 0) +op1= al_build_transform(trans, 320, 240, 0.75, 0.75, theta) +op2= +op3= al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) +op4= al_use_transform(trans) +op5= al_draw_line(-300, -200, 300, 200, #008080ff, thickness) +op6= al_draw_triangle(-150, -250, 0, 250, 150, -250, #800080ff, thickness) +op7= al_draw_rectangle(-300, -200, 300, 200, #800000ff, thickness) +op8= al_draw_rounded_rectangle(-200, -125, 200, 125, 50, 100, #333300ff, thickness) +op9= al_draw_ellipse(0, 0, 300, 150, #008080ff, thickness) +op10=al_draw_arc(0, 0, 200, -1.5707, 3.1415, #803f00ff, thickness) +op11= +op12= +op13=al_draw_spline(points, #193380ff, thickness) +points=-300,-200, 700,200, -700,200, 300,-200 +theta=0.5 +thickness=1 + +[hl2] +# hl2 is like hl but the spline is not rotated. +# We received a report on i386 where the rotated spline is drawn with +# a single pixel difference, but still acceptable. +extend=hl +op11=al_build_transform(trans, 320, 240, 0.75, 0.75, 0) +op12=al_use_transform(trans) + +[test hl thick-0] +extend=hl +thickness=0 +hash=d62736a8 +sig=766666666769966A66656659677676767A66866697567669A6556766786676665767A876776666766 + +[test hl thick-1] +extend=hl +thickness=1 +sig=766666666769966966656659677676767A66866697566669965567667866766657679876776666766 + +[test hl thick-2] +extend=hl +thickness=2 +hash=639f3cad + +[test hl thick-10] +extend=hl +thickness=10 +hash=019f07b9 + +[test hl2 thick-50] +extend=hl2 +thickness=50 +hash=a0129b37 + +[test hl2 thick-50 clip] +extend=test hl2 thick-50 +op2=al_set_clipping_rectangle(220, 140, 420, 340) +hash=9039ee00 + +[test hl2 thick-50 nolight] +extend=test hl2 thick-50 +op3= +hash=dc66bfe1 + +[test hl2 thick-50 nolight clip] +extend=test hl2 thick-50 clip +op3= +hash=2e3bd424 + +[test hl fill] +op0= al_draw_bitmap(bkg, 0, 0, 0) +op1= al_build_transform(trans, 320, 240, 0.75, 0.75, theta) +op2= +op3= al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) +op4= al_use_transform(trans) +op5= +op6= al_draw_filled_triangle(-100, -100, -150, 200, 100, 200, #80b24c) +op7= al_draw_filled_rectangle(20, -50, 200, 50, #4c3399) +op8= al_draw_filled_ellipse(-250, 0, 100, 150, #4c4c4c) +op9= al_draw_filled_rounded_rectangle(50, -250, 350, -75, 50, 70, #333300) +theta=0.5 +hash=effa21ee +sig=76N6666667PP6667666OP657EF76QPd67EFF7P6c6UDFE66cb6TS6F66cc66766657677576776666766 + +[test hl fill clip] +extend=test hl fill +op2=al_set_clipping_rectangle(220, 140, 420, 340) +hash=923737a4 + +[test hl fill nolight] +extend=test hl fill +op3= +hash=400eca07 + +[test hl fill subbmp dest] +op0= subbmp = al_create_sub_bitmap(target, 60, 60, 540, 380) +op1= al_set_target_bitmap(subbmp) +op2= al_draw_bitmap(bkg, 0, 0, 0) +op3= +op4= al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) +op5= al_build_transform(trans, 320, 240, 0.75, 0.75, theta) +op6= al_use_transform(trans) +op7= al_draw_filled_triangle(-100, -100, -150, 200, 100, 200, #80b24c) +op8= al_draw_filled_rectangle(20, -50, 200, 50, #4c3399) +op9= al_draw_filled_ellipse(-250, 0, 100, 150, #4c4c4c) +op10=al_draw_filled_rounded_rectangle(50, -250, 350, -75, 50, 70, #333300) +theta=0.5 +hash=457ddb11 +sig=00000000075666667677QP7757676PP665F97APQY56FE75P7c76EE766bbTSUF776db77777666c7666 + +[test hl fill subbmp dest clip] +extend=test hl fill subbmp dest +op3=al_set_clipping_rectangle(220, 140, 300, 200) +hash=52d7f9fd + +[test circle] +op0=al_clear_to_color(#884444) +op1=al_draw_circle(200, 150, 100, #66aa0080, 10) +op2=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ONE) +op3=al_draw_circle(350, 250, 200, #00aaaa80, 50) +op4=al_draw_filled_circle(250, 175, 75, #aa660080) +hash=484ad11f + +[test small arc crash] +op0=al_build_transform(t, 100, 100, scale, scale, 0.0) +scale=0.005 +op1=al_use_transform(t) +op2=al_draw_ellipse(0, 0, 32, 16, red, 2) +op3=al_draw_rounded_rectangle(50.5, 0.5, 100.5, 50.5, 5, 5, green, 3) +op4=al_draw_filled_rounded_rectangle(0, 100, 50, 150, 5, 5, blue) +op5=al_draw_arc(100, 100, 50, 0, 1.7, yellow, 4) +hash=f2391dc5 + +[test filled notex blend] +op0= +op1=al_draw_bitmap(bkg, 0, 0, 0) +op2=al_build_transform(t, 320, 240, 1, 1, 1.0) +op3=al_use_transform(t) +op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) +op5=al_draw_prim(vtx_notex, 0, 0, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) +op6=al_draw_prim(vtx_notex, 0, 0, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST) +op7=al_draw_prim(vtx_notex, 0, 0, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP) +hash=1312b9c9 +sig=766666666766P66766656657K776767676667666975I5666LK556766KPJ6766657NJ7576776666766 + +[test filled notex opaque] +extend=test filled notex blend +op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) +hash=2ac96499 +sig=766666666766I66766656657E776767676667666775B5666FE556766EID6766657GC7576776666766 + +[test filled textured blend] +op0= +op1=al_draw_bitmap(bkg, 0, 0, 0) +op2=al_build_transform(t, 320, 240, 1, 1, 1.0) +op3=al_use_transform(t) +op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) +op5=al_draw_prim(vtx_tex, 0, tex, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) +op6=al_draw_prim(vtx_tex, 0, tex, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST) +op7=al_draw_prim(vtx_tex, 0, tex, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP) +tex=texture +hash=04d0ae2f +sig=766666666766B66766656657977676767666766687585666NP556766RXS6766657fR7576776666766 + +[test filled textured blend clip] +extend=test filled textured blend +op0=al_set_clipping_rectangle(150, 80, 340, 280) +hash=4b485162 +sig=000000000006B66700006657900006767600006687500006NP550000RXS6700000000000000000000 + +[test filled textured opaque] +extend=test filled textured blend +op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) +hash=67cc8955 +sig=766666666766466766656657377676767666766677515666IK556766LTN6766657cK7576776666766 + +[test filled textured opaque clip] +extend=test filled textured opaque +op0=al_set_clipping_rectangle(150, 80, 340, 280) +hash=42db2b52 +sig=000000000006466700006657300006767600006677500006IK550000LTN6700000000000000000000 + +[test filled subtexture blend] +# Note: sub-bitmap textures may not repeat/tile. +op0=tex = al_create_sub_bitmap(obp, 70, 60, 322, 303) +op1=al_draw_bitmap(bkg, 0, 0, 0) +op2=al_build_transform(t, 320, 240, 1, 1, 1.0) +op3=al_use_transform(t) +op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE) +op5=al_draw_prim(vtx_tex2, 0, tex, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) +op6=al_draw_prim(vtx_tex2, 0, tex, 7, 13, ALLEGRO_PRIM_TRIANGLE_LIST) +op7=al_draw_prim(vtx_tex2, 0, tex, 14, 20, ALLEGRO_PRIM_TRIANGLE_STRIP) +hash=891747fe +sig=766666666766J66766656657D776767676667666A75G5666ML556766NNK6766657MM7576776666766 + +[test filled subtexture opaque] +extend=test filled subtexture blend +op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO) +hash=325bf4a2 +sig=766666666766C66766656657777676767666766687595666GF556766GHE6766657GE7576776666766 + +[test filled textured solid non-white tint] +op0= +op1=al_draw_bitmap(bkg, 0, 0, 0) +op2=al_build_transform(t, 320, 240, 1, 1, 1.0) +op3=al_use_transform(t) +op4=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op5=al_draw_prim(vtx_tex3, 0, texture, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) +hash=e16da3fc +sig=7666666667666667666566576776767676667666675656669A556766ACA6766657FA7576776666766 + +[test filled textured subbmp dest] +op0=al_clear_to_color(gray) +op1=sub = al_create_sub_bitmap(target, 30, 150, 400, 300) +op2=al_set_target_bitmap(sub) +op3=al_clear_to_color(orange) +op4= +op5=al_build_transform(Tsub, 300, 10, 5, 4, 1.0) +op6=al_use_transform(Tsub) +op7=al_draw_prim(vtx_tex, 0, texture, 0, 6, ALLEGRO_PRIM_TRIANGLE_FAN) +hash=19fb34dc +sig=WWWWWWWWWWWWWWWWWWWWWWWWWWWZZZZgZWWWZZY7bZWWWZgEM5ZWWWgUaHAeWWWP8gUf7WWWCUEgNgWWW + +[test filled textured subbmp dest clip] +extend=test filled textured subbmp dest +op4=al_set_clipping_rectangle(50, 50, 300, 200) +hash=49c3d736 + +[test div-by-zero] +# This test used to cause a division-by-zero. +op0=al_build_transform(t, 320, 240, 1, 1, theta) +op1=al_use_transform(t) +op2=al_draw_prim(vtx_divbyzero, 0, texture, 0, 4, ALLEGRO_PRIM_TRIANGLE_FAN) +theta=4.84207964 +hash=a95ea313 +sig=0000000000000Ca000000EgW00000bBgSK0000TWPYa0000NMgEX00000gbX000000MM0000000000000 + +[test pieslice] +# 5.1 additions scheduled to be backported to 5.0.6 +op0=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op1=al_draw_pieslice(160, 240, 100, 1.0, 6.0, blue, 10) +op2=al_draw_pieslice(160, 240, 100, 1.0, 6.0, yellow, 1) +op3=al_draw_filled_pieslice(480, 240, 200, 1.0, 1.5, #aa333388) +op4=al_draw_filled_pieslice(480, 240, 200, 2.0, 1.5, #33aa3399) +op5=al_draw_filled_pieslice(480, 240, 200, 3.0, 1.5, #3333aa88) +hash=64ef5e16 +sig=00000000000000C6000OO0CCC005002ICC00C00IIII0030O1DDI300NN0DICC000000ICC0000000CC0 + +[test elliptical arc] +# 5.1 addition scheduled to be backported to 5.0.6 +op0=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op1=al_draw_elliptical_arc(160, 240, 50, 100, -1.5, 4.5, #ff5555aa, 50) +op2=al_draw_elliptical_arc(160, 240, 50, 100, 2.0, 4.5, #55ff55aa, 40) +op3=al_draw_elliptical_arc(160, 240, 50, 100, 2.0, 4.5, yellow, 0) +op4=al_draw_elliptical_arc(440, 240, 100, 50, -1.5, 4.5, #ff5555aa, 10) +op5=al_draw_elliptical_arc(440, 240, 100, 50, 2.0, 4.5, #55ff55aa, 20) +op6=al_draw_elliptical_arc(440, 240, 100, 50, 2.0, 4.5, yellow, 1) +hash=6a88fcfc + +[vtx_ll] +v0 = 200.000000, 0.000000, 0.000000; 128.000000, 0.000000; #408000 +v1 = 177.091202, 92.944641, 0.000000; 113.338371, 59.484570; #800040 +v2 = 113.612938, 164.596771, 0.000000; 72.712280, 105.341934; #004080 +v3 = 24.107338, 198.541779, 0.000000; 15.428697, 127.066742; #408000 +v4 = -70.920990, 187.003250, 0.000000; -45.389435, 119.682083; #800040 +v5 =-149.702148, 132.624527, 0.000000; -95.809372, 84.879700; #004080 +v6 =-194.188370, 47.863136, 0.000000; -124.280556, 30.632408; #408000 +v7 =-194.188354, -47.863167, 0.000000; -124.280548, -30.632427; #800040 +v8 =-149.702133, -132.624557, 0.000000; -95.809364, -84.879715; #004080 +v9 = -70.920914, -187.003265, 0.000000; -45.389385, -119.682091; #408000 +v10= 24.107349, -198.541779, 0.000000; 15.428703, -127.066742; #800040 +v11= 113.612984, -164.596741, 0.000000; 72.712311, -105.341911; #004080 +v12= 177.091202, -92.944641, 0.000000; 113.338371, -59.484570; #408000 + +[vtx_ll_white] +v0 = 200.000000, 0.000000, 0.000000; 128.000000, 0.000000; #ffffff +v1 = 177.091202, 92.944641, 0.000000; 113.338371, 59.484570; #ffffff +v2 = 113.612938, 164.596771, 0.000000; 72.712280, 105.341934; #ffffff +v3 = 24.107338, 198.541779, 0.000000; 15.428697, 127.066742; #ffffff +v4 = -70.920990, 187.003250, 0.000000; -45.389435, 119.682083; #ffffff +v5 =-149.702148, 132.624527, 0.000000; -95.809372, 84.879700; #ffffff +v6 =-194.188370, 47.863136, 0.000000; -124.280556, 30.632408; #ffffff +v7 =-194.188354, -47.863167, 0.000000; -124.280548, -30.632427; #ffffff +v8 =-149.702133, -132.624557, 0.000000; -95.809364, -84.879715; #ffffff +v9 = -70.920914, -187.003265, 0.000000; -45.389385, -119.682091; #ffffff +v10= 24.107349, -198.541779, 0.000000; 15.428703, -127.066742; #ffffff +v11= 113.612984, -164.596741, 0.000000; 72.712311, -105.341911; #ffffff +v12= 177.091202, -92.944641, 0.000000; 113.338371, -59.484570; #ffffff + +[vtx_notex] +v0 = 0.000000, 0.000000, 0.000000; 0.000000, 0.000000; #408000 +v1 = 190.211304, 61.803402, 0.000000; 0.000000, 0.000000; #804040 +v2 = 121.352547, 88.167786, 0.000000; 0.000000, 0.000000; #000080 +v3 = 117.557053, 161.803406, 0.000000; 0.000000, 0.000000; #408000 +v4 = 46.352547, 142.658478, 0.000000; 0.000000, 0.000000; #804040 +v5 = -0.000009, 200.000000, 0.000000; 0.000000, 0.000000; #000080 +v6 = -46.352554, 142.658478, 0.000000; 0.000000, 0.000000; #408000 +v7 = -117.557037, 161.803406, 0.000000; 0.000000, 0.000000; #804040 +v8 = -121.352547, 88.167778, 0.000000; 0.000000, 0.000000; #000080 +v9 = -190.211304, 61.803406, 0.000000; 0.000000, 0.000000; #408000 +v10= -150.000000, -0.000013, 0.000000; 0.000000, 0.000000; #804040 +v11= -190.211304, -61.803394, 0.000000; 0.000000, 0.000000; #000080 +v12= -121.352539, -88.167801, 0.000000; 0.000000, 0.000000; #408000 +v13= -117.557083, -161.803360, 0.000000; 0.000000, 0.000000; #804040 +v14= -46.352562, -142.658478, 0.000000; 0.000000, 0.000000; #000080 +v15= 0.000002, -200.000000, 0.000000; 0.000000, 0.000000; #408000 +v16= 46.352570, -142.658478, 0.000000; 0.000000, 0.000000; #804040 +v17= 117.557098, -161.803360, 0.000000; 0.000000, 0.000000; #000080 +v18= 121.352539, -88.167793, 0.000000; 0.000000, 0.000000; #408000 +v19= 190.211304, -61.803391, 0.000000; 0.000000, 0.000000; #804040 +v20= 150.000000, 0.000026, 0.000000; 0.000000, 0.000000; #000080 + +[vtx_tex] +v0 = 0.000000, 0.000000, 0.000000; 0.000000, 0.000000; #ffffff +v1 = 190.211304, 61.803402, 0.000000; 121.735237, 39.554176; #ffffff +v2 = 121.352547, 88.167786, 0.000000; 77.665627, 56.427383; #ffffff +v3 = 117.557053, 161.803406, 0.000000; 75.236511, 103.554176; #ffffff +v4 = 46.352547, 142.658478, 0.000000; 29.665630, 91.301422; #ffffff +v5 = -0.000009, 200.000000, 0.000000; -0.000006, 128.000000; #ffffff +v6 = -46.352554, 142.658478, 0.000000; -29.665634, 91.301422; #ffffff +v7 = -117.557037, 161.803406, 0.000000; -75.236504, 103.554176; #ffffff +v8 = -121.352547, 88.167778, 0.000000; -77.665627, 56.427380; #ffffff +v9 = -190.211304, 61.803406, 0.000000; -121.735237, 39.554180; #ffffff +v10= -150.000000, -0.000013, 0.000000; -96.000000, -0.000008; #804040 +v11= -190.211304, -61.803394, 0.000000; -121.735237, -39.554173; #000080 +v12= -121.352539, -88.167801, 0.000000; -77.665627, -56.427391; #408000 +v13= -117.557083, -161.803360, 0.000000; -75.236534, -103.554153; #804040 +v14= -46.352562, -142.658478, 0.000000; -29.665640, -91.301422; #000080 +v15= 0.000002, -200.000000, 0.000000; 0.000002, -128.000000; #408000 +v16= 46.352570, -142.658478, 0.000000; 29.665644, -91.301422; #804040 +v17= 117.557098, -161.803360, 0.000000; 75.236542, -103.554153; #000080 +v18= 121.352539, -88.167793, 0.000000; 77.665627, -56.427387; #408000 +v19= 190.211304, -61.803391, 0.000000; 121.735237, -39.554169; #804040 +v20= 150.000000, 0.000026, 0.000000; 96.000000, 0.000017; #000080 + +[vtx_tex2] +v0 = 0.000000, 0.000000, 0.000000; 161.000000, 151.500000; #ffffff +v1 = 190.211304, 61.803402, 0.000000; 314.120087, 198.316071; #ffffff +v2 = 121.352547, 88.167786, 0.000000; 258.688812, 218.287094; #ffffff +v3 = 117.557053, 161.803406, 0.000000; 255.633423, 274.066071; #ffffff +v4 = 46.352547, 142.658478, 0.000000; 198.313797, 259.563782; #ffffff +v5 = -0.000009, 200.000000, 0.000000; 161.000000, 303.000000; #ffffff +v6 = -46.352554, 142.658478, 0.000000; 123.686195, 259.563782; #ffffff +v7 = -117.557037, 161.803406, 0.000000; 66.366585, 274.066071; #ffffff +v8 = -121.352547, 88.167778, 0.000000; 63.311199, 218.287094; #ffffff +v9 = -190.211304, 61.803406, 0.000000; 7.879900, 198.316086; #ffffff +v10= -150.000000, -0.000013, 0.000000; 40.250000, 151.499985; #804040 +v11= -190.211304, -61.803394, 0.000000; 7.879900, 104.683929; #000080 +v12= -121.352539, -88.167801, 0.000000; 63.311207, 84.712891; #408000 +v13= -117.557083, -161.803360, 0.000000; 66.366547, 28.933954; #804040 +v14= -46.352562, -142.658478, 0.000000; 123.686188, 43.436203; #000080 +v15= 0.000002, -200.000000, 0.000000; 161.000000, 0.000000; #408000 +v16= 46.352570, -142.658478, 0.000000; 198.313812, 43.436203; #804040 +v17= 117.557098, -161.803360, 0.000000; 255.633469, 28.933954; #000080 +v18= 121.352539, -88.167793, 0.000000; 258.688782, 84.712898; #408000 +v19= 190.211304, -61.803391, 0.000000; 314.120087, 104.683929; #804040 +v20= 150.000000, 0.000026, 0.000000; 281.750000, 151.500015; #000080 + +[vtx_tex3] +# All vertices have same non-white colour. +v0 = 0.000000, 0.000000, 0.000000; 0.000000, 0.000000; #ff883366 +v1 = 190.211304, 61.803402, 0.000000; 121.735237, 39.554176; #ff883366 +v2 = 121.352547, 88.167786, 0.000000; 77.665627, 56.427383; #ff883366 +v3 = 117.557053, 161.803406, 0.000000; 75.236511, 103.554176; #ff883366 +v4 = 46.352547, 142.658478, 0.000000; 29.665630, 91.301422; #ff883366 +v5 = -0.000009, 200.000000, 0.000000; -0.000006, 128.000000; #ff883366 +v6 = -46.352554, 142.658478, 0.000000; -29.665634, 91.301422; #ff883366 + +[vtx_divbyzero] +v0= 200.000000, 0.000000, 0.000000; 128.00, 0.0; #ffffff +v1= 0.000000, 200.000000, 0.000000; 0.0, 128.0; #ffffff +v2= -200.000000, 0.000000, 0.000000; -128.0, 0.0; #ffffff +v3= 0.000000, -200.000000, 0.000000; 0.0, -128.0; #ffffff diff --git a/allegro/tests/test_prim2.ini b/allegro/tests/test_prim2.ini new file mode 100644 index 00000000..72ffb9ce --- /dev/null +++ b/allegro/tests/test_prim2.ini @@ -0,0 +1,219 @@ +# Test primitives which are only in the 5.1 branch. + +[test projection] +# Projection doesn't work on memory bitmaps +hw_only = true +op0=al_orthographic_transform(trans, -1, -1, -1, 1, 1, 1) +op1=al_use_projection_transform(trans) +op2=al_draw_filled_circle(0, 0, 1, #aa6600) +hash=cb2630a9 +sig=0DMMMMMC0CMMMMMMM9MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM9MMMMMMM60AMMMMM80 + +[test projection flipped] +# Projection doesn't work on memory bitmaps +hw_only = true +op0=al_orthographic_transform(trans, -1, 1, -1, 1, -1, 1) +op1=al_use_projection_transform(trans) +op2=al_draw_filled_circle(0, 0, 1, #aa6600) +hash=cb2630a9 +sig=0DMMMMMC0CMMMMMMM9MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM9MMMMMMM60AMMMMM80 + +[triangle base] +op0=al_clear_to_color(white) +op1=al_draw_polyline(verts, join, cap, color, thickness, miter_limit) +verts=vtx_triangle +join=ALLEGRO_LINE_JOIN_NONE +cap=ALLEGRO_LINE_CAP_NONE +color=#8080aa +thickness=1.0 +miter_limit=1.0 + +[squiggle base] +extend=triangle base +verts=vtx_squiggle +thickness=25 + +[test polyline collinear 50] +extend=triangle base +verts=vtx_collinear +thickness=50 +hash=553ab2e5 + +[test polyline triangle 50] +extend=triangle base +thickness=50 +hash=019534c0 + +[test polyline squiggle 0] +extend=squiggle base +thickness=0 +hash=1b5e258d + +[test polyline squiggle 1] +extend=squiggle base +thickness=1 +hash=08066329 + +[test polyline join bevel] +extend=squiggle base +join=ALLEGRO_LINE_JOIN_BEVEL +hash=1452f13d + +[test polyline join round] +extend=squiggle base +join=ALLEGRO_LINE_JOIN_ROUND +hash=e3be6520 + +[test polyline join miter1] +extend=squiggle base +join=ALLEGRO_LINE_JOIN_MITER +miter_limit=1.0 +hash=0cc7a65d + +[test polyline join miter2] +extend=squiggle base +join=ALLEGRO_LINE_JOIN_MITER +miter_limit=2.0 +hash=973b5a4d + +[test polyline cap square] +extend=squiggle base +cap=ALLEGRO_LINE_CAP_SQUARE +hash=8df5cafc + +[test polyline cap round] +extend=squiggle base +cap=ALLEGRO_LINE_CAP_ROUND +hash=a308506c + +[test polyline cap triangle] +extend=squiggle base +cap=ALLEGRO_LINE_CAP_TRIANGLE +hash=680ab634 + +[test polyline cap closed] +extend=squiggle base +cap=ALLEGRO_LINE_CAP_CLOSED +hash=6f62fb5c + +# The backbuffer may not have an alpha channel so we draw to an +# intermediate bitmap. +[test polygon] +op0=b = al_create_bitmap(640, 480) +op1=al_set_target_bitmap(b) +op2=al_clear_to_color(white) +op3=al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) +op4=al_draw_polygon(vtx_concave, join, #4444aa80, 25, 1) +op5=al_set_target_bitmap(target) +op6=al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE) +op7=al_clear_to_color(brown) +op8=al_draw_bitmap(b, 0, 0, 0) +join=ALLEGRO_LINE_JOIN_ROUND +hash=2c6d9cdc + +[test filled polygon] +extend=test polygon +op4=al_draw_filled_polygon(vtx_concave, #4444aa80) +hash=de3f4621 + +[test filled polygon with holes] +extend=test polygon +op4=al_draw_filled_polygon_with_holes(decep.vtx, decep.counts, #4444aa80) +hash=23b1a895 + + +[vtx_collinear] +v0 = 100, 100 +v1 = 300, 100 +v2 = 200, 100 + +[vtx_triangle] +v0 = 96.00, 195.00 +v1 = 251.00, 297.00 +v2 = 150.00, 206.00 + +[vtx_squiggle] +v0 = 41.00, 219.00 +v1 = 193.00, 316.00 +v2 = 137.00, 178.00 +v3 = 287.00, 172.00 +v4 = 242.00, 270.00 +v5 = 387.00, 273.00 +v6 = 382.00, 174.00 +v7 = 313.00, 77.00 +v8 = 468.00, 63.00 +v9 = 496.00, 130.00 +v10 = 416.00, 151.00 +v11 = 501.00, 249.00 + +[vtx_concave] +v0 = 80.00, 296.00 +v1 = 330.00, 297.00 +v2 = 268.00, 251.00 +v3 = 331.00, 242.00 +v4 = 292.00, 192.00 +v5 = 290.00, 231.00 +v6 = 235.00, 223.00 +v7 = 250.00, 172.00 +v8 = 272.00, 215.00 +v9 = 278.00, 165.00 +v10 = 367.00, 180.00 +v11 = 361.00, 115.00 +v12 = 300.00, 71.00 +v13 = 333.00, 130.00 +v14 = 292.00, 122.00 +v15 = 262.00, 76.00 +v16 = 245.00, 118.00 +v17 = 247.00, 140.00 +v18 = 202.00, 146.00 +v19 = 185.00, 102.00 +v20 = 128.00, 93.00 +v21 = 122.00, 138.00 +v22 = 179.00, 161.00 +v23 = 100.00, 170.00 +v24 = 88.00, 236.00 +v25 = 127.00, 186.00 +v26 = 195.00, 242.00 +v27 = 163.00, 271.00 +v28 = 165.00, 191.00 + +[decep.vtx] +v0 = 314.00, 438.00 +v1 = 459.00, 207.00 +v2 = 485.00, 44.00 +v3 = 431.00, 111.00 +v4 = 373.00, 130.00 +v5 = 368.00, 167.00 +v6 = 427.00, 153.00 +v7 = 426.00, 159.00 +v8 = 366.00, 177.00 +v9 = 360.00, 204.00 +v10= 420.00, 188.00 +v11= 419.00, 196.00 +v12= 350.00, 217.00 +v13= 314.00, 257.00 +v14= 280.00, 218.00 +v15= 206.00, 197.00 +v16= 205.00, 188.00 +v17= 270.00, 208.00 +v18= 263.00, 177.00 +v19= 205.00, 161.00 +v20= 201.00, 151.00 +v21= 263.00, 171.00 +v22= 251.00, 131.00 +v23= 196.00, 110.00 +v24= 140.00, 41.00 +v25= 168.00, 211.00 +v26= 225.00, 234.00 +v27= 266.00, 245.00 +v28= 280.00, 275.00 +v29= 242.00, 255.00 +v30= 364.00, 245.00 +v31= 402.00, 234.00 +v32= 388.00, 255.00 +v33= 349.00, 275.00 + +[decep.counts] +p0=26 +p1=4 +p2=4 diff --git a/allegro/tools/macosx/fixbundle.c b/allegro/tools/macosx/fixbundle.c new file mode 100644 index 00000000..76b6c814 --- /dev/null +++ b/allegro/tools/macosx/fixbundle.c @@ -0,0 +1,679 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * MacOS X application bundle fixer utility. Creates an application + * bundle out of an executable and some optional icon image files. + * + * By Angelo Mottola. + * + * See readme.txt for copyright information. + */ + +#define ALLEGRO_USE_CONSOLE + +#include +#include +#include +#include +#include +#include + +#undef TRUE +#undef FALSE + +#ifndef SCAN_DEPEND + #include +#endif + +#undef TRUE +#undef FALSE +#define TRUE -1 +#define FALSE 0 + +/* 16x16 */ +#define ICON_SMALL 0 +/* 32x32 */ +#define ICON_LARGE 1 +/* 48x48 */ +#define ICON_HUGE 2 +/* 128x128 */ +#define ICON_THUMBNAIL 3 + + +#define F_SMALL_DEFINED 0x1 +#define F_LARGE_DEFINED 0x2 +#define F_HUGE_DEFINED 0x4 +#define F_THUMBNAIL_DEFINED 0x8 +#define F_ICONS_DEFINED 0xf +#define F_MOVE 0x10 +#define F_GOT_VERSION 0x20 +#define F_GOT_LONG_VERSION 0x40 +#define F_EMBED_FRAMEWORK 0x80 + +#define MAX_STRING_SIZE 1024 +#define ONE_SIXTH (1.0 / 6.0) + + +typedef struct ICON_DATA +{ + BITMAP *original, *workspace, *scaled; + int size; + OSType data, mask8, mask1; + int defined; +} ICON_DATA; + + +static ICON_DATA icon_data[4] = { + { NULL, NULL, NULL, 16, kSmall32BitData, kSmall8BitMask, kSmall1BitMask, F_SMALL_DEFINED }, + { NULL, NULL, NULL, 32, kLarge32BitData, kLarge8BitMask, kLarge1BitMask, F_LARGE_DEFINED }, + { NULL, NULL, NULL, 48, kHuge32BitData, kHuge8BitMask, kHuge1BitMask, F_HUGE_DEFINED }, + { NULL, NULL, NULL, 128, kThumbnail32BitData, kThumbnail8BitMask, 0, F_THUMBNAIL_DEFINED } +}; +static int flags = 0; + + + +static float cubic_bspline(float x) +{ + float a, b, c, d; + + if (x <= -2.0) + a = 0.0; + else + a = (x + 2.0) * (x + 2.0) * (x + 2.0); + + if (x <= -1.0) + b = 0.0; + else + b = ((x + 1.0) * (x + 1.0) * (x + 1.0)) * -4.0; + + if (x <= 0) + c = 0.0; + else + c = (x * x * x) * 6.0; + + if (x <= 1.0) + d = 0.0; + else + d = ((x - 1.0) * (x - 1.0) * (x - 1.0)) * -4.0; + + return (a + b + c + d) * ONE_SIXTH; +} + + + +static int scale_icon(ICON_DATA *icon) +{ + BITMAP *shape; + int size, x_ofs = 2, y_ofs = 2; + int x, y, m, n; + int i_x, i_y; + float k, f_x, f_y, a, b, r1, r2; + float red, green, blue, alpha; + unsigned char *p; + unsigned int color; + + if (icon->original->w > icon->original->h) { + size = 4 + icon->original->w; + y_ofs = 2 + ((icon->original->w - icon->original->h) / 2); + } + else { + size = 4 + icon->original->h; + x_ofs = 2 + ((icon->original->h - icon->original->w) / 2); + } + k = (float)(size - 4) / (float)icon->size; + icon->workspace = create_bitmap_ex(32, size, size); + if (!icon->workspace) + return -1; + icon->scaled = create_bitmap_ex(32, icon->size, icon->size); + if (!icon->scaled) + return -1; + shape = create_bitmap_ex(32, icon->original->w, icon->original->h); + if (!shape) + return -1; + blit(icon->original, shape, 0, 0, 0, 0, icon->original->w, icon->original->h); + clear_to_color(icon->workspace, makeacol32(0, 0, 0, 255)); + shape->vtable->mask_color = makeacol32(255, 0, 255, 0); + masked_blit(shape, icon->workspace, 0, 0, x_ofs, y_ofs, shape->w, shape->h); + destroy_bitmap(shape); + + for (y = 0; y < icon->size; y++) { + f_y = (float)y * k; + i_y = (int)floor(f_y); + a = f_y - floor(f_y); + for (x = 0; x < icon->size; x++) { + f_x = (float)x * k; + i_x = (int)floor(f_x); + b = f_x - floor(f_x); + red = green = blue = alpha = 0.0; + for (m = -1; m < 3; m++) { + r1 = cubic_bspline((float)m - a); + for (n = -1; n < 3; n++) { + r2 = cubic_bspline(b - (float)n); + color = ((unsigned int *)(icon->workspace->line[i_y + m + 2]))[i_x + n + 2]; + red += ((float)getr32(color) * r1 * r2); + green += ((float)getg32(color) * r1 * r2); + blue += ((float)getb32(color) * r1 * r2); + alpha += ((float)geta32(color) * r1 * r2); + } + } + color = makeacol32((int)floor(red), (int)floor(green), (int)floor(blue), 255 - (int)floor(alpha)); + ((unsigned int *)(icon->scaled->line[y]))[x] = color; + } + } + + return 0; +} + + + +static int load_resource(char *datafile, char *name, ICON_DATA *icon) +{ + DATAFILE *data; + BITMAP *temp, *bitmap = NULL; + RLE_SPRITE *rle_sprite; + PALETTE palette; + int size, type, i; + int result = 0; + + if (datafile[0] != '\0') { + data = load_datafile_object(datafile, name); + if (!data) { + fprintf(stderr, "Error loading object '%s' from %s\n", name, datafile); + return -1; + } + switch (data->type) { + + case DAT_BITMAP: + temp = (BITMAP *)data->dat; + bitmap = create_bitmap_ex(temp->vtable->color_depth, temp->w, temp->h); + blit(temp, bitmap, 0, 0, 0, 0, temp->w, temp->h); + break; + + case DAT_RLE_SPRITE: + rle_sprite = (RLE_SPRITE *)data->dat; + bitmap = create_bitmap_ex(rle_sprite->color_depth, rle_sprite->w, rle_sprite->h); + clear_to_color(bitmap, bitmap->vtable->mask_color); + draw_rle_sprite(bitmap, rle_sprite, 0, 0); + break; + + case DAT_PALETTE: + select_palette((RGB *)data->dat); + unload_datafile_object(data); + return 0; + + default: + fprintf(stderr, "'%s' is not a BITMAP, RLE_SPRITE or PALETTE object in datafile '%s'\n", name, datafile); + unload_datafile_object(data); + return -1; + } + unload_datafile_object(data); + } + else { + bitmap = load_bitmap(name, palette); + select_palette(palette); + if (!bitmap) { + fprintf(stderr, "Unable to load '%s'\n", name); + return -1; + } + } + + if (!icon) { + size = MAX(bitmap->w, bitmap->h); + if (size <= 16) + type = ICON_SMALL; + else if (size <= 32) + type = ICON_LARGE; + else if (size <= 48) + type = ICON_HUGE; + else + type = ICON_THUMBNAIL; + icon = &icon_data[type]; + if (flags & icon->defined) { + for (i = 0; i < 3; i++) { + type = (type + 1) % 4; + icon = &icon_data[type]; + if (!(flags & icon->defined)) + break; + } + if (flags & icon->defined) { + fprintf(stderr, "Too many icon resources!"); + result = -1; + goto exit_error; + } + } + } + else { + if (icon->scaled) { + fprintf(stderr, "Multiple icon resources of the same size"); + result = -1; + goto exit_error; + } + } + icon->original = create_bitmap_ex(bitmap->vtable->color_depth, bitmap->w, bitmap->h); + blit(bitmap, icon->original, 0, 0, 0, 0, bitmap->w, bitmap->h); + result = scale_icon(icon); + flags |= icon->defined; + +exit_error: + destroy_bitmap(bitmap); + + return result; +} + + + +static void usage(void) +{ + fprintf(stderr, "\nMacOS X application bundle fixer utility for Allegro " ALLEGRO_VERSION_STR "\n" + "By Angelo Mottola, " ALLEGRO_DATE_STR "\n\n" + "Usage: fixbundle exename [-m] [-o bundlename] [-v version] [-V long_version]\n" + "\t\t[-e] [[-d datafile] [[palette] [-{16,32,48,128}] icon] ...]\n" + "\twhere icon is either a datafile bitmap or a RLE sprite object, either\n" + "\tan image file.\n" + "Options:\n" + "\t-m\t\tMoves executable inside bundle instead of copying it\n" + "\t-o bundlename\tSpecifies a bundle name (default: exename.app)\n" + "\t-v version\tSets application version string (default: 1.0)\n" + "\t-V long_version\tSets long application version string\n" + "\t-e\t\tEmbeds the Allegro framework into the application bundle\n" + "\t-d datafile\tUses datafile as source for objects and palettes\n" + "\t-{16,32,48,128}\tForces next icon image into the 16x16, 32x32, 48x48 or\n" + "\t\t\t128x128 icon resource slot\n" + "\n"); + exit(EXIT_FAILURE); +} + + + +static int copy_file(const char *filename, const char *dest_path) +{ + char *buffer = NULL; + char dest_file[1024]; + PACKFILE *f; + size_t size; + + if (!exists(filename)) + return -1; + buffer = malloc(size = file_size_ex(filename)); + if (!buffer) + return -1; + append_filename(dest_file, dest_path, get_filename(filename), 1024); + f = pack_fopen(filename, F_READ); + if (!f) { + free(buffer); + return -1; + } + pack_fread(buffer, size, f); + pack_fclose(f); + f = pack_fopen(dest_file, F_WRITE); + if (!f) { + free(buffer); + return -1; + } + pack_fwrite(buffer, size, f); + pack_fclose(f); + free(buffer); + + return 0; +} + + + +/* main: + * Guess what this function does. + */ +int main(int argc, char *argv[]) +{ + PACKFILE *f; + CFURLRef cf_url_ref; + FSRef fs_ref; + FSSpec fs_spec; + IconFamilyHandle icon_family; + Handle raw_data; + char datafile[MAX_STRING_SIZE]; + char bundle[MAX_STRING_SIZE]; + char bundle_dir[MAX_STRING_SIZE]; + char bundle_contents_dir[MAX_STRING_SIZE]; + char bundle_contents_resources_dir[MAX_STRING_SIZE]; + char bundle_contents_macos_dir[MAX_STRING_SIZE]; + char bundle_contents_frameworks_dir[MAX_STRING_SIZE]; + char *bundle_exe = NULL; + char bundle_plist[MAX_STRING_SIZE]; + char bundle_pkginfo[MAX_STRING_SIZE]; + char bundle_icns[MAX_STRING_SIZE]; + char bundle_version[MAX_STRING_SIZE]; + char bundle_long_version[MAX_STRING_SIZE]; + char *buffer = NULL; + int arg, type = 0, result = 0; + int i, size, x, y, mask_bit, mask_byte; + unsigned char *data; + + install_allegro(SYSTEM_NONE, &errno, &atexit); + set_color_depth(32); + set_color_conversion(COLORCONV_TOTAL | COLORCONV_KEEP_TRANS); + + if (argc < 2) + usage(); + + datafile[0] = '\0'; + bundle[0] = '\0'; + select_palette(black_palette); + + /* Parse command line and load any given resource */ + for (arg = 2; arg < argc; arg++) { + if (!strcmp(argv[arg], "-m")) + flags |= F_MOVE; + else if (!strcmp(argv[arg], "-e")) + flags |= F_EMBED_FRAMEWORK; + else if (!strcmp(argv[arg], "-o")) { + if ((argc < arg + 2) || (bundle[0] != '\0')) + usage(); + strcpy(bundle, argv[++arg]); + } + else if (!strcmp(argv[arg], "-v")) { + if (argc < arg + 2) + usage(); + flags |= F_GOT_VERSION; + strcpy(bundle_version, argv[++arg]); + } + else if (!strcmp(argv[arg], "-V")) { + if (argc < arg + 2) + usage(); + flags |= F_GOT_LONG_VERSION; + strcpy(bundle_long_version, argv[++arg]); + } + else if (!strcmp(argv[arg], "-d")) { + if (argc < arg + 2) + usage(); + strcpy(datafile, argv[++arg]); + } + else if ((!strcmp(argv[arg], "-16")) || (!strcmp(argv[arg], "-32")) || + (!strcmp(argv[arg], "-48")) || (!strcmp(argv[arg], "-128"))) { + if (argc < arg + 2) + usage(); + switch (atoi(&argv[arg][1])) { + case 16: type = 0; break; + case 32: type = 1; break; + case 48: type = 2; break; + case 128: type = 3; break; + } + if (load_resource(datafile, argv[++arg], &icon_data[type])) { + result = -1; + goto exit_error; + } + } + else { + if (load_resource(datafile, argv[arg], NULL)) { + result = -1; + goto exit_error; + } + } + } + + buffer = malloc(4096); + if (!buffer) { + result = -1; + goto exit_error_bundle; + } + + bundle_exe = argv[1]; + if (!exists(bundle_exe)) { + fprintf(stderr, "Cannot locate executable file '%s'\n", bundle_exe); + result = -1; + goto exit_error; + } + if (bundle[0] == '\0') + strcpy(bundle, bundle_exe); + replace_extension(bundle_dir, bundle, "app", MAX_STRING_SIZE); + strcpy(bundle_contents_dir, bundle_dir); + strcat(bundle_contents_dir, "/Contents"); + strcpy(bundle_contents_resources_dir, bundle_contents_dir); + strcat(bundle_contents_resources_dir, "/Resources"); + strcpy(bundle_contents_macos_dir, bundle_contents_dir); + strcat(bundle_contents_macos_dir, "/MacOS"); + strcpy(bundle_contents_frameworks_dir, bundle_contents_dir); + strcat(bundle_contents_frameworks_dir, "/Frameworks"); + bundle_icns[0] = '\0'; + bundle_plist[0] = '\0'; + bundle_pkginfo[0] = '\0'; + + /* Create bundle structure */ + if ((mkdir(bundle_dir, 0777) && (errno != EEXIST)) || + (mkdir(bundle_contents_dir, 0777) && (errno != EEXIST)) || + (mkdir(bundle_contents_resources_dir, 0777) && (errno != EEXIST)) || + (mkdir(bundle_contents_macos_dir, 0777) && (errno != EEXIST))) { + fprintf(stderr, "Cannot create %s\n", bundle_dir); + result = -1; + goto exit_error_bundle; + } + + /* Copy/move executable into the bundle */ + if (copy_file(bundle_exe, bundle_contents_macos_dir)) { + fprintf(stderr, "Cannot create %s\n", bundle_contents_macos_dir); + result = -1; + goto exit_error_bundle; + } + strcat(bundle_contents_macos_dir, "/"); + strcat(bundle_contents_macos_dir, get_filename(bundle_exe)); + chmod(bundle_contents_macos_dir, 0755); + if (flags & F_MOVE) + unlink(bundle_exe); + + /* Embed Allegro framework if requested */ + if (flags & F_EMBED_FRAMEWORK) { + if (!file_exists("/Library/Frameworks/Allegro.framework", FA_RDONLY | FA_DIREC, NULL)) { + fprintf(stderr, "Cannot find Allegro framework\n"); + result = -1; + goto exit_error_bundle; + } + if (!exists("/Library/Frameworks/Allegro.framework/Resources/Embeddable")) { + fprintf(stderr, "Cannot embed system wide Allegro framework; install embeddable version first!\n"); + result = -1; + goto exit_error_bundle; + } + sprintf(buffer, "/Developer/Tools/pbxcp -exclude .DS_Store -exclude CVS -resolve-src-symlinks /Library/Frameworks/Allegro.framework %s", bundle_contents_frameworks_dir); + if ((mkdir(bundle_contents_frameworks_dir, 0777) && (errno != EEXIST)) || + (system(buffer))) { + fprintf(stderr, "Cannot create %s\n", bundle_contents_frameworks_dir); + result = -1; + goto exit_error_bundle; + } + } + + /* Setup the .icns resource */ + if (flags & F_ICONS_DEFINED) { + strcat(bundle_contents_resources_dir, "/"); + strcat(bundle_contents_resources_dir, get_filename(bundle)); + replace_extension(bundle_icns, bundle_contents_resources_dir, "icns", MAX_STRING_SIZE); + + icon_family = (IconFamilyHandle)NewHandle(0); + + for (i = 0; i < 4; i++) { + if (flags & icon_data[i].defined) { + /* Set 32bit RGBA data */ + raw_data = NewHandle(icon_data[i].size * icon_data[i].size * 4); + data = *(unsigned char **)raw_data; + for (y = 0; y < icon_data[i].size; y++) { + for (x = 0; x < icon_data[i].size; x++) { + *data++ = geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); + *data++ = getr32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); + *data++ = getg32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); + *data++ = getb32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); + } + } + if (SetIconFamilyData(icon_family, icon_data[i].data, raw_data) != noErr) { + DisposeHandle(raw_data); + fprintf(stderr, "Error setting %dx%d icon resource RGBA data\n", icon_data[i].size, icon_data[i].size); + result = -1; + goto exit_error_bundle; + } + DisposeHandle(raw_data); + /* Set 8bit mask */ + raw_data = NewHandle(icon_data[i].size * icon_data[i].size); + data = *(unsigned char **)raw_data; + for (y = 0; y < icon_data[i].size; y++) { + for (x = 0; x < icon_data[i].size; x++) { + *data++ = geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]); + } + } + if (SetIconFamilyData(icon_family, icon_data[i].mask8, raw_data) != noErr) { + DisposeHandle(raw_data); + fprintf(stderr, "Error setting %dx%d icon resource 8bit mask\n", icon_data[i].size, icon_data[i].size); + result = -1; + goto exit_error_bundle; + } + DisposeHandle(raw_data); + /* Set 1bit mask */ + if (icon_data[i].mask1) { + size = ((icon_data[i].size * icon_data[i].size) + 7) / 8; + raw_data = NewHandle(size * 2); + data = *(unsigned char **)raw_data; + mask_byte = 0; + mask_bit = 7; + for (y = 0; y < icon_data[i].size; y++) { + for (x = 0; x < icon_data[i].size; x++) { + if (geta32(((unsigned int *)(icon_data[i].scaled->line[y]))[x]) >= 0xfd) + mask_byte |= (1 << mask_bit); + mask_bit--; + if (mask_bit < 0) { + *data++ = mask_byte; + mask_byte = 0; + mask_bit = 7; + } + } + } + memcpy(*raw_data + size, *raw_data, size); + if (SetIconFamilyData(icon_family, icon_data[i].mask1, raw_data) != noErr) { + DisposeHandle(raw_data); + fprintf(stderr, "Error setting %dx%d icon resource 1bit mask\n", icon_data[i].size, icon_data[i].size); + result = -1; + goto exit_error_bundle; + } + DisposeHandle(raw_data); + } + } + } + + f = pack_fopen(bundle_icns, F_WRITE); + if (!f) { + fprintf(stderr, "Cannot create %s\n", bundle_icns); + result = -1; + goto exit_error_bundle; + } + pack_fclose(f); + + cf_url_ref = CFURLCreateWithBytes(kCFAllocatorDefault, (unsigned char *)bundle_icns, strlen(bundle_icns), 0, NULL); + if (!cf_url_ref) { + fprintf(stderr, "Cannot create %s\n", bundle_icns); + result = -1; + goto exit_error_bundle; + } + CFURLGetFSRef(cf_url_ref, &fs_ref); + CFRelease(cf_url_ref); + if ((FSGetCatalogInfo(&fs_ref, kFSCatInfoNone, NULL, NULL, &fs_spec, NULL)) || + (WriteIconFile(icon_family, &fs_spec) != noErr)) { + fprintf(stderr, "Cannot create %s\n", bundle_icns); + result = -1; + goto exit_error_bundle; + } + DisposeHandle((Handle)icon_family); + } + + /* Setup Info.plist */ + sprintf(bundle_plist, "%s/Info.plist", bundle_contents_dir); + f = pack_fopen(bundle_plist, F_WRITE); + if (!f) { + fprintf(stderr, "Cannot create %s\n", bundle_plist); + result = -1; + goto exit_error_bundle; + } + sprintf(buffer, "\n" + "\n" + "\n" + "\n" + "\tCFBundleExecutable\n" + "\t%s\n" + "\tCFBundleInfoDictionaryVersion\n" + "\t6.0\n" + "\tCFBundlePackageType\n" + "\tAPPL\n" + "\tCFBundleSignature\n" + "\t%s\n" + "\tCFBundleVersion\n" + "\t%s\n" + "\tCFBundleDocumentTypes\n" + "\t\n" + "\t\t\n" + "\t\t\tCFBundleTypeExtensions\n" + "\t\t\t\n" + "\t\t\t\t*\n" + "\t\t\t\n" + "\t\t\tCFBundleTypeName\n" + "\t\t\tNSStringPboardType\n" + "\t\t\tCFBundleTypeOSTypes\n" + "\t\t\t\n" + "\t\t\t\t****\n" + "\t\t\t\n" + "\t\t\tCFBundleTypeRole\n" + "\t\t\tViewer\n" + "\t\t\n" + "\t\n", + get_filename(bundle_exe), "????", (flags & F_GOT_VERSION) ? bundle_version : "1.0"); + pack_fputs(buffer, f); + if (flags & F_GOT_LONG_VERSION) { + sprintf(buffer, "\tCFBundleGetInfoString\n" + "\t%s\n", bundle_long_version); + pack_fputs(buffer, f); + } + if (flags & F_ICONS_DEFINED) { + sprintf(buffer, "\tCFBundleIconFile\n" + "\t%s\n", get_filename(bundle_icns)); + pack_fputs(buffer, f); + } + pack_fputs("\n\n", f); + pack_fclose(f); + + /* Setup PkgInfo */ + sprintf(bundle_pkginfo, "%s/PkgInfo", bundle_contents_dir); + f = pack_fopen(bundle_pkginfo, F_WRITE); + if (!f) { + fprintf(stderr, "Cannot create %s\n", bundle_pkginfo); + result = -1; + goto exit_error_bundle; + } + pack_fputs("APPL????", f); + pack_fclose(f); + +exit_error: + if (buffer) + free(buffer); + for (i = 0; i < 4; i++) { + if (icon_data[i].original) + destroy_bitmap(icon_data[i].original); + if (icon_data[i].workspace) + destroy_bitmap(icon_data[i].workspace); + if (icon_data[i].scaled) + destroy_bitmap(icon_data[i].scaled); + } + return result; + +exit_error_bundle: + sprintf(buffer, "%s/%s", bundle_contents_macos_dir, get_filename(bundle_exe)); + unlink(buffer); + unlink(bundle_plist); + unlink(bundle_pkginfo); + unlink(bundle_icns); + rmdir(bundle_dir); + rmdir(bundle_contents_dir); + rmdir(bundle_contents_resources_dir); + rmdir(bundle_contents_macos_dir); + goto exit_error; +} diff --git a/allegro/tools/win/wfixicon.c b/allegro/tools/win/wfixicon.c new file mode 100644 index 00000000..3a916333 --- /dev/null +++ b/allegro/tools/win/wfixicon.c @@ -0,0 +1,326 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Allegro bitmap -> Windows icon converter. + * + * By Elias Pschernig. + * + * See readme.txt for copyright information. + */ + + +#define ALLEGRO_USE_CONSOLE + +#include +#include +#include +#include + + +#define ICON_MAX 16 + + + +/* save_ico: + * Saves bitmaps as an .ico, using as palette for 8-bit bitmaps. + * Other color depths are saved as 24-bit. + */ +int save_ico(const char *filename, BITMAP *bmp[], int num, PALETTE pal[]) +{ + PACKFILE *f; + int depth, bpp, bw, bitsw; + int size, offset, n, i; + int c, x, y, b, m, v; + + errno = 0; + + f = pack_fopen(filename, F_WRITE); + if (!f) + return errno; + + offset = 6 + num * 16; /* ICONDIR + ICONDIRENTRYs */ + + /* ICONDIR */ + pack_iputw(0, f); /* reserved */ + pack_iputw(1, f); /* resource type: ICON */ + pack_iputw(num, f); /* number of icons */ + + for(n = 0; n < num; n++) { + depth = bitmap_color_depth(bmp[n]); + bpp = (depth == 8) ? 8 : 24; + bw = (((bmp[n]->w * bpp / 8) + 3) / 4) * 4; + bitsw = ((((bmp[n]->w + 7) / 8) + 3) / 4) * 4; + size = bmp[n]->h * (bw + bitsw) + 40; + + if (bpp == 8) + size += 256 * 4; + + /* ICONDIRENTRY */ + pack_putc(bmp[n]->w, f); /* width */ + pack_putc(bmp[n]->h, f); /* height */ + pack_putc(0, f); /* color count */ + pack_putc(0, f); /* reserved */ + pack_iputw(1, f); /* color planes */ + pack_iputw(bpp, f); /* bits per pixel */ + pack_iputl(size, f); /* size in bytes of image data */ + pack_iputl(offset, f); /* file offset to image data */ + + offset += size; + } + + for(n = 0; n < num; n++) { + depth = bitmap_color_depth(bmp[n]); + bpp = (depth == 8) ? 8 : 24; + bw = (((bmp[n]->w * bpp / 8) + 3) / 4) * 4; + bitsw = ((((bmp[n]->w + 7) / 8) + 3) / 4) * 4; + size = bmp[n]->h * (bw + bitsw) + 40; + + if (bpp == 8) + size += 256 * 4; + + /* BITMAPINFOHEADER */ + pack_iputl(40, f); /* size */ + pack_iputl(bmp[n]->w, f); /* width */ + pack_iputl(bmp[n]->h * 2, f); /* height x 2 */ + pack_iputw(1, f); /* planes */ + pack_iputw(bpp, f); /* bitcount */ + pack_iputl(0, f); /* unused for ico */ + pack_iputl(size, f); /* size */ + pack_iputl(0, f); /* unused for ico */ + pack_iputl(0, f); /* unused for ico */ + pack_iputl(0, f); /* unused for ico */ + pack_iputl(0, f); /* unused for ico */ + + /* PALETTE */ + if (bpp == 8) { + pack_iputl(0, f); /* color 0 is black, so the XOR mask works */ + + for (i = 1; i<256; i++) { + if (pal[n]) { + pack_putc(_rgb_scale_6[pal[n][i].b], f); + pack_putc(_rgb_scale_6[pal[n][i].g], f); + pack_putc(_rgb_scale_6[pal[n][i].r], f); + pack_putc(0, f); + } + else { + pack_iputl(0, f); + } + } + } + + /* XOR MASK */ + for (y = bmp[n]->h - 1; y >= 0; y--) { + for (x = 0; x < bmp[n]->w; x++) { + if (bpp == 8) { + pack_putc(getpixel(bmp[n], x, y), f); + } + else { + c = getpixel(bmp[n], x, y); + pack_putc(getb_depth(depth, c), f); + pack_putc(getg_depth(depth, c), f); + pack_putc(getr_depth(depth, c), f); + } + } + + /* every scanline must be 32-bit aligned */ + while (x&3) { + pack_putc(0, f); + x++; + } + } + + /* AND MASK */ + for (y = bmp[n]->h - 1; y >= 0; y--) { + for (x = 0; x < (bmp[n]->w + 7)/8; x++) { + m = 0; + v = 128; + + for (b = 0; b < 8; b++) { + c = getpixel(bmp[n], x * 8 + b, y); + if (c == bitmap_mask_color(bmp[n])) + m += v; + v /= 2; + } + + pack_putc(m, f); + } + + /* every scanline must be 32-bit aligned */ + while (x&3) { + pack_putc(0, f); + x++; + } + } + } + + pack_fclose(f); + + return errno; +} + + + +void usage(void) +{ + printf("\nWindows icon converter for Allegro " ALLEGRO_VERSION_STR "\n"); + printf("By Elias Pschernig, " ALLEGRO_DATE_STR "\n\n"); + printf("Usage: wfixicon icon [-r[o]] bitmap [bitmap...]\n"); + printf(" or\n"); + printf(" wfixicon icon [-r[o]] -d datafile object [palette] [object...]\n"); + printf(" where each 'object' is a bitmap or a RLE sprite.\n"); + printf("Options:\n"); + printf(" -r output .rc file for the icon\n"); + printf(" -ro call the resource compiler on the .rc file\n"); + + exit(1); +} + + + +int main(int argc, char *argv[]) +{ + char dat_name[128], rc_name[128], res_name[128], str[256]; + int icon_num = 0, pal_start = 0; + int create_rc = FALSE, call_windres = FALSE; + int i, j, arg; + BITMAP *bmp[ICON_MAX]; + PALETTE pal[ICON_MAX]; + RLE_SPRITE *sprite; + DATAFILE *dat; + PACKFILE *f; + + if (install_allegro(SYSTEM_NONE, &errno, atexit) != 0) + exit(EXIT_FAILURE); + set_color_conversion(COLORCONV_NONE); + + if (argc < 3) + usage(); + + dat_name[0] = '\0'; + + for (arg = 2; arg < argc; arg++) { + + if (argv[arg][0] == '-') { + + switch(argv[arg][1]) { + + case 'd': /* datafile argument */ + if (argc < arg+2) + usage(); + + strcpy(dat_name, argv[++arg]); + pal_start = icon_num; + break; + + case 'r': + create_rc = TRUE; + + if (argv[arg][2] == 'o') { + call_windres = TRUE; + } + break; + + default: + usage(); + } + } /* end of '-' handling */ + else { + if (dat_name[0]) { + dat = load_datafile_object(dat_name, argv[arg]); + + if (!dat) { + printf("Error reading %s from %s.\n", argv[arg], dat_name); + exit(EXIT_FAILURE); + } + + switch (dat->type) { + + case DAT_BITMAP: + bmp[icon_num] = (BITMAP *)dat->dat; + icon_num++; + break; + + case DAT_RLE_SPRITE: + sprite = (RLE_SPRITE *)dat->dat; + bmp[icon_num] = create_bitmap_ex(sprite->color_depth, sprite->w, sprite->h); + clear_to_color(bmp[icon_num], bitmap_mask_color(bmp[icon_num])); + draw_rle_sprite(bmp[icon_num], sprite, 0, 0); + icon_num++; + break; + + case DAT_PALETTE: + if (pal_start == icon_num) + usage(); + + for (j = pal_start; j < icon_num; j++) + for (i = 0; i < PAL_SIZE; i++) + pal[j][i] = ((RGB *)dat->dat)[i]; + + pal_start = icon_num; + break; + + default: + usage(); + } + } + else { + bmp[icon_num] = load_bitmap(argv[arg], pal[icon_num]); + if (!bmp[icon_num]) { + printf("Error reading %s.\n", argv[arg]); + exit(EXIT_FAILURE); + } + + icon_num++; + } + + if (icon_num == ICON_MAX) + break; + } /* end of normal argument handling */ + } + + if (icon_num == 0) + usage(); + + /* do the hard work */ + if (save_ico(argv[1], bmp, icon_num, pal) != 0) { + printf("Error writing %s.\n", argv[1]); + exit(EXIT_FAILURE); + } + + /* output a .rc file along with the ico, to be processed by the resource compiler */ + if (create_rc) { + replace_extension(rc_name, argv[1], "rc", sizeof(rc_name)); + + f = pack_fopen(rc_name, F_WRITE); + + sprintf(str, "allegro_icon ICON %s\n", argv[1]); + pack_fwrite(str, strlen(str), f); + + pack_fclose(f); + + if (call_windres) { + replace_extension(res_name, argv[1], "res", sizeof(res_name)); + +#if defined ALLEGRO_MINGW32 + sprintf(str, "windres -O coff -o %s -i %s", res_name, rc_name); +#elif defined ALLEGRO_MSVC + sprintf(str, "rc -fo %s %s", res_name, rc_name); +#elif defined ALLEGRO_BCC32 + sprintf(str, "brc32 -r -fo %s %s", res_name, rc_name); +#endif + + system(str); + delete_file(argv[1]); + delete_file(rc_name); + } + } + + return 0; +} diff --git a/allegro/tools/win/wfixicon.txt b/allegro/tools/win/wfixicon.txt new file mode 100644 index 00000000..aad81b4d --- /dev/null +++ b/allegro/tools/win/wfixicon.txt @@ -0,0 +1,65 @@ + + ____ _ _ _ _ ___ __ _ + |_ | \/ | | | | |\ | + | | _/\_ | |__ |_| | \| + + + by Elias Pschernig + + + +The wfixicon utility converts Allegro images to Windows icons, that +is it lets you convert one or several images in any format supported by +Allegro into icons suitable to be included in your Windows executable. + +It has two main execution modes: you can either directly pass it image files +from your hard drive or bitmaps and RLE sprites from an Allegro datafile. +The only difference between the two modes is for 8-bit images: in the former +case, wfixicon will automatically extract the palette from the image file, +whereas in the latter case you will have to explicitly provide a palette +object from the datafile. + +The general syntax for the first mode is as follows: + + 'wfixicon icon [options] bitmap [bitmap...]' + +where 'icon' is the icon file to be generated (usually with the standard +.ico extension) and each 'bitmap' is a source bitmaps to be processed. + +The general syntax for the second mode is as follows: + + 'wfixicon icon [options] -d datafile object [palette] [object...]' + +where 'icon' is the icon file to be generated (see above), 'datafile' is the +source from which all objects are taken, and each 'object' is a bitmap +or RLE sprite (DAT_BITMAP or DAT_RLE) within the datafile, specified by +name. + +If you have used any 8-bit images, you must also specify a palette. For +each palette object you include on the command line, any images between +it and the last palette will be given that palette. For example: + + + 'wfixicon i.ico -d d.dat icon icon2 pal1 tool tool2 pal2' + +will give the icons called 'icon' and 'icon2' the palette 'pal1', and +the icons 'tool' and 'tool2' will be given 'pal2'. + +The wfixicon utility accepts the following options: + + '-r' + Outputs a resource source file (.rc) suited to the icon, in addition + to the icon itself. When compiled and linked to an Allegro Windows + executable, this file attachs the icon to the executable and makes it + the default icon, displayed in the window caption and the task list. + + '-ro' + Same as '-r' but additionally call the resource compiler on the .rc + file, making it produce an object file ready to be linked to an + Allegro Windows executable, with the same effects as described above. + + +An example of use is provided in the Allegro distribution: the demo program +gets a nice little icon (or an ugly one, it's up to you...) extracted from +its datafile (with the Borland C++ compiler you need to type 'make fixdemo' +from the main directory once you have properly installed the library). diff --git a/allegro/tools/x11/xf2pcx.c b/allegro/tools/x11/xf2pcx.c new file mode 100644 index 00000000..961cfab0 --- /dev/null +++ b/allegro/tools/x11/xf2pcx.c @@ -0,0 +1,319 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Utility to convert X11 fonts to a PCX file, ready for use in the + * grabber. + * + * By Michael Bukin, 1998. + * + * Minor changes in 2002 by Peter Wang. + * + * Minor changes in 2003 by Elias Pschernig. + * + * See readme.txt for copyright information. + */ + +#include +#include +#include +#include + +#ifndef SCAN_DEPEND + #include + #include +#endif + + +/* usage: + * Show usage information. + */ +static void usage(char *argv0) +{ + printf("Usage: %s [OPTIONS]\n\n", argv0); + printf(" -f FONTNAME Font name pattern ('*' by default).\n" + " -o FILENAME Output file name ('font.pcx' by default).\n" + " -r NUM-NUM Character range, default = 0x20-0xff.\n" + " -c COLOR Character color (default 000000000 -- black).\n" + " -b COLOR Background color (default 255255255 -- white).\n" + " -g COLOR Grid color (default 255000255 -- magenta).\n" + " Colors are specified as RRRGGGBBB values,\n" + " with each RRR, GGG and BBB in the range [0, 255].\n" + " -h This help.\n" + "\n" + "Find the font you want to convert using xlsfonts or xfontsel.\n\n" + "Example 1:\n" + "bash> xlsfonts -fn '*' | less\n" + "bash> %s -f '-adobe-courier-medium-r-normal--34-*'\n" + "bash> grabber\n\n" + "In grabber, create a new font 'Object|New|Font'. Use 'Object|Grab'\n" + "on this object and choose the pcx file with the font (font.pcx).\n\n" + "Example 2:\n" + "./xf2pcx -f '-*-clearlyu-*-*-*-*-17-*-*-*-p--iso10646-1' -r 0x2800-0x28ff -o braille.pcx\n\n" + "Writes the Braille alphabet into braille.pcx.\n", argv0); +} + + +int main(int argc, char *argv[]) +{ + /* default values for -f, -i, -r, -c, -b, -g */ + char *fontname = "*"; + char *filename = "font.pcx"; + int start_char = 32, end_char = 255; + int ccolor = 000000000; + int bcolor = 255255255; + int gcolor = 255000255; + /* X11 variables */ + Display *display; + int screen_number; + int default_depth; + Window window; + Font font; + GC gc, gc2; + Pixmap pixmap; + XImage *image; + XCharStruct overall; + /* misc variables */ + int bitmap_width, bitmap_height; + int max_ascent, max_descent; + int max_width, max_height; + int i, opt, x, y, cx, cy, sx, sy, lines; + unsigned long black, white; + BITMAP *bitmap; + RGB palette[256]; + + /* show usage if no options */ + if (argc == 1) { + usage(argv[0]); + exit(EXIT_SUCCESS); + } + + /* only to access bitmap operations */ + install_allegro(SYSTEM_NONE, &errno, atexit); + + /* parse options */ + opterr = 0; + while ((opt = getopt(argc, argv, "f:o:z:c:b:g:r:h")) != EOF) { + switch (opt) { + case 'f': + fontname = optarg; + break; + case 'o': + filename = optarg; + break; + case 'c': + ccolor = atol(optarg); + break; + case 'b': + bcolor = atol(optarg); + break; + case 'g': + gcolor = atol(optarg); + break; + case 'r': + { + char *str; + start_char = strtol(optarg, &str, 0); + end_char = strtol(str + 1, NULL, 0); + break; + } + case 'h': + usage(argv[0]); + exit(EXIT_SUCCESS); + default: + fprintf(stderr, "%s: unrecognized option -- '%c'\n", argv[0], + optopt); + fprintf(stderr, "%s: try '%s -h' for more information\n", + argv[0], argv[0]); + exit(EXIT_FAILURE); + } + } + + /* open display */ + display = XOpenDisplay(0); + if (display == 0) { + fprintf(stderr, "%s: XOpenDisplay failed\n", argv[0]); + exit(EXIT_FAILURE); + } + + /* default screen number and window */ + screen_number = XDefaultScreen(display); + default_depth = XDefaultDepth(display, screen_number); + window = XDefaultRootWindow(display); + + /* load font */ + font = XLoadFont(display, fontname); + + /* create gcs */ + { + unsigned long val_mask; + XGCValues val_bits; + val_mask = GCForeground | GCBackground | GCFont | GCFunction; + val_bits.function = GXcopy; + val_bits.foreground = white = WhitePixel(display, screen_number); + val_bits.background = black = BlackPixel(display, screen_number); + val_bits.font = font; + gc = XCreateGC(display, window, val_mask, &val_bits); + val_mask = GCForeground; + val_bits.foreground = black; + gc2 = XCreateGC(display, window, val_mask, &val_bits); + } + + /* query font ascent and descent */ + { + XFontStruct *xfs; + int min, max; + xfs = XQueryFont(display, font); + max_ascent = xfs->ascent; + max_descent = xfs->descent; + + if (xfs->min_byte1 == 0 && xfs->max_byte1 == 0) { + min = xfs->min_char_or_byte2; + max = xfs->max_char_or_byte2; + } + else { + min = (xfs->min_byte1 << 8) + xfs->min_char_or_byte2; + max = (xfs->max_byte1 << 8) + xfs->max_char_or_byte2; + } + + if (start_char < min || end_char > max) + fprintf(stderr, + "You specified characters %04x-%04x, but this font " + "only has the range %04x-%04x\n", start_char, end_char, + min, max); + + XFreeFontInfo(NULL, xfs, 0); + } + + /* calculate bitmap width and maximum ascent and descent of characters + * (can exceed the font ascent/descent queried above!) */ + max_width = 0; + lines = 1 + (end_char - start_char) / 16; + for (cy = 0; cy < lines; cy++) { + + for (cx = 0; cx < 16 && start_char + cy * 16 + cx <= end_char; cx++) { + int dir, ascent, descent; + int width; + XChar2b string[2] = { {0, 0}, {0, 0} }; + + /* query character size */ + string[0].byte1 = (start_char + cy * 16 + cx) >> 8; + string[0].byte2 = (start_char + cy * 16 + cx) & 255; + XQueryTextExtents16(display, font, string, 1, &dir, &ascent, + &descent, &overall); + width = overall.width; + if (width < 1) + width = 1; + + if (width > max_width) + max_width = width; + + if (max_ascent < overall.ascent) + max_ascent = overall.ascent; + if (max_descent < overall.descent) + max_descent = overall.descent; + } + + } + + max_height = max_ascent + max_descent; + + bitmap_width = (max_width + 1) * 16 + 1; + bitmap_height = (max_height + 1) * lines + 1; + + /* create bitmap */ + bitmap = create_bitmap(bitmap_width, bitmap_height); + if (bitmap == 0) { + fprintf(stderr, "%s: can not create bitmap\n", argv[0]); + exit(EXIT_FAILURE); + } + + /* fill with filler color */ + clear_to_color(bitmap, 255); + + /* process all characters */ + sy = 1; + for (cy = 0; cy < lines; cy++) { + + sx = 1; + for (cx = 0; cx < 16 && start_char + cy * 16 + cx <= end_char; cx++) { + int dir, ascent, descent; + XChar2b string[2] = { {0, 0}, {0, 0} }; + + /* query character size */ + string[0].byte1 = (start_char + cy * 16 + cx) >> 8; + string[0].byte2 = (start_char + cy * 16 + cx) & 255; + XQueryTextExtents16(display, font, string, 1, &dir, &ascent, + &descent, &overall); + + if (overall.width < 1) + overall.width = 1; + + /* create pixmap and draw character there */ + pixmap = + XCreatePixmap(display, window, overall.width, max_height, + default_depth); + /* some fonts draw outside their ascent/descent, so we need to clear + * the pixmap before drawing the glyph */ + XFillRectangle(display, pixmap, gc2, 0, 0, overall.width, + max_height); + XDrawImageString16(display, pixmap, gc, 0, max_ascent, string, 1); + + /* create image with pixmap contents */ + image = + XGetImage(display, pixmap, 0, 0, overall.width, max_height, + AllPlanes, ZPixmap); + if (image == 0) { + fprintf(stderr, "%s: can not get image\n", argv[0]); + exit(EXIT_FAILURE); + } + + /* copy image to bitmap */ + for (y = 0; y < max_height; y++) + for (x = 0; x < overall.width; x++) { + if (XGetPixel(image, x, y) == white) + putpixel(bitmap, sx + x, sy + y, 1); + else + putpixel(bitmap, sx + x, sy + y, 0); + } + + XDestroyImage(image); + XFreePixmap(display, pixmap); + + sx += max_width + 1; + } + sy += max_height + 1; + } + + /* initialize palette */ + for (i = 0; i < 256; i++) + palette[i].r = palette[i].g = palette[i].b = 0; + +#define CLAMP(v) (((v / 4) > 63) ? 63 : (v / 4)) + palette[0].r = CLAMP(bcolor / 1000000); + palette[0].g = CLAMP((bcolor % 1000000) / 1000); + palette[0].b = CLAMP(bcolor % 1000); + palette[1].r = CLAMP(ccolor / 1000000); + palette[1].g = CLAMP((ccolor % 1000000) / 1000); + palette[1].b = CLAMP(ccolor % 1000); + palette[255].r = CLAMP(gcolor / 1000000); + palette[255].g = CLAMP((gcolor % 1000000) / 1000); + palette[255].b = CLAMP(gcolor % 1000); +#undef CLAMP + save_pcx(filename, bitmap, palette); + + /* clean up */ + destroy_bitmap(bitmap); + XFreeGC(display, gc); + XFreeGC(display, gc2); + XUnloadFont(display, font); + XCloseDisplay(display); + + exit(EXIT_SUCCESS); +} diff --git a/allegro/tools/x11/xfixicon.sh b/allegro/tools/x11/xfixicon.sh new file mode 100644 index 00000000..28d826ca --- /dev/null +++ b/allegro/tools/x11/xfixicon.sh @@ -0,0 +1,50 @@ +#! /bin/sh + +# Generate X11 icon +# Usage: xfixicon iconfile + +if test -z "$1"; then + echo "Usage:" + echo " xfixicon iconfile [-o outputfile]" + echo "this will generate a C file that can be linked with your application" + echo "to set the X11 icon automatically." + echo "" + echo "Options:" + echo " -o Set the name of the output file. Default name is allegro_icon.c" + exit +fi + +outfile="allegro_icon.c" + +while !(test -z "$1"); do + if (test "$1" = "-o"); then + outfile=$2 + shift + else + file=$1 + fi + shift +done + +if !(test -e "$file"); then + echo "File not found: $file" + exit 1 +fi + +if !(convert -transparent "magenta" "$file" "/tmp/allegico_xpm.xpm"); then + echo "Conversion failed" + exit 1 +fi + +echo "#include " > $outfile +cat /tmp/allegico_xpm.xpm | sed -e 's,static char,static const char,' >> $outfile +echo "#if defined ALLEGRO_WITH_XWINDOWS && defined ALLEGRO_USE_CONSTRUCTOR" >> $outfile +echo "extern void *allegro_icon;" >> $outfile +echo "CONSTRUCTOR_FUNCTION(static void _set_allegro_icon(void));" >> $outfile +echo "static void _set_allegro_icon(void)" >> $outfile +echo "{" >> $outfile +echo " allegro_icon = allegico_xpm;" >> $outfile +echo "}" >> $outfile +echo "#endif" >> $outfile + +rm /tmp/allegico_xpm.xpm diff --git a/allegro/tools/x11/xkeymap.c b/allegro/tools/x11/xkeymap.c new file mode 100644 index 00000000..29657a7d --- /dev/null +++ b/allegro/tools/x11/xkeymap.c @@ -0,0 +1,307 @@ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ + * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ + * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ + * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ + * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ + * /\____/ + * \_/__/ + * + * Utility to create mapping from X keycodes to Allegro scancodes. + * + * By Michael Bukin, modified by Elias Pschernig. + * + * See readme.txt for copyright information. + */ + +#include + +#include +#include +#include + +#define FILENAME_LENGTH 1024 + +char unicode_description[256] = ""; +static DIALOG main_dialog[]; +static DIALOG keymap_dialog[]; + +static int black = 0; +static int white = 1; +static int red = 2; +static int yellow = 3; + +static volatile int waiting_for_key = 0; +static volatile int new_keycode = 0; +static int keycode_to_scancode[256]; + +static void get_raw_keycode(int pressed, int keycode) +{ + if (pressed && waiting_for_key) { + new_keycode = keycode; + waiting_for_key = 0; + } +} + +static const char *keycode_getter(int index, int *list_size) +{ + if (index >= 0) { + return scancode_to_name(index + 1); + } + else { + *list_size = KEY_MAX - 1; + return NULL; + } +} + +static DIALOG keymap_dialog[] = { + /* 0 */{d_clear_proc, 0, 0, 250, 230, 0, 0, 0, 0, 0, 0, 0, NULL, NULL}, + /* 1 */{d_ctext_proc, 125, 10, 0, 16, 0, 255, 0, 0, 0, 0, "Select Keycode:", NULL, NULL}, + /* 2 */{d_list_proc, 0, 32, 230, 92, 0, 255, 0, D_EXIT, 0, 0, (void *)keycode_getter, NULL, NULL}, + /* 3 */{d_ctext_proc, 125, 142, 0, 16, 0, 255, 0, 0, 0, 0, unicode_description, NULL, NULL}, + /* 4 */{d_button_proc, 10, 164, 230, 16, 0, 255, 0, D_EXIT, 0, 0, "Define &X Key !", NULL, NULL}, + /* 5 */{d_button_proc, 10, 186, 110, 16, 0, 255, 27, D_EXIT, 0, 0, "&Cancel", NULL, NULL}, + /* 6 */{d_button_proc, 130, 186, 110, 16 , 0, 255, 0, D_EXIT, 0, 0, "&Done", NULL, NULL}, + /* 7 */{d_ctext_proc, 125, 208, 0, 16, 0, 255, 0, 0, 0, 0, "", NULL, NULL}, + {d_yield_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL}, + {NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL} +}; + +/* handle the setup command */ +static void setup_all_keys(void) +{ + int focus = 2; + int i; + + /* Prepare dialog. */ + set_dialog_color(keymap_dialog, black, white); + centre_dialog(keymap_dialog); + + /* Parse input. */ + while (1) { + focus = do_dialog(keymap_dialog, focus); + switch (focus) { + case 2: + case 4: + + textprintf_centre_ex (screen, font, + keymap_dialog[7].x, keymap_dialog[7].y, red, -1, + "Press a key to map to the current scancode"); + textprintf_centre_ex (screen, font, + keymap_dialog[7].x, keymap_dialog[7].y + 8, red, -1, + "(or a mouse button to leave it unchanged)"); + + /* Wait for new key press. */ + new_keycode = -1; + waiting_for_key = 1; + + do { + poll_keyboard(); + poll_mouse(); + + if (mouse_b) + waiting_for_key = 0; + } + while (waiting_for_key); + + /* Save keycode to scancode mapping. */ + if ((new_keycode >= 0) && (new_keycode < 256)) { + keycode_to_scancode[new_keycode] = keymap_dialog[2].d1 + 1; + } + + clear_keybuf(); + + break; + case 5: + return; + case 6: + for (i = 0; i < 256; i++) { + if (keycode_to_scancode[i] >= 0) + _xwin.keycode_to_scancode[i] = keycode_to_scancode[i]; + } + return; + } + } +} + +static void test_key_map(void) +{ + int i, k, u; + static int key_was_pressed[KEY_MAX + 1] = {0}; + static int key_is_pressed[KEY_MAX + 1] = {0}; + static char *welcome[] = { + "Key that is pressed now is marked with red", + "Key that was pressed is marked with yellow", + "Press mouse button or Escape to exit test", + 0 + }; + + /* Clear screen and output prompt. */ + clear_to_color(screen, white); + for (i = 0; welcome[i] != 0; i++) + textout_ex(screen, font, welcome[i], 8, i * 8 + 8, black, -1); + + clear_to_color(screen, white); + for (i = 0; i < KEY_MAX; i++) + textprintf_ex(screen, font, 32 + (i % 4) * 160, + 32 + (i / 4) * 14, black, -1, "%s", scancode_to_name (i)); + do { + poll_keyboard(); + poll_mouse(); + } + while ((key[KEY_ESC]) || (mouse_b)); + + do { + + while (keypressed()) { + u = ureadkey (&k); + textprintf_centre_ex (screen, font, SCREEN_W / 2, 8, + red, white, "> %c <", u); + } + + poll_keyboard(); + poll_mouse(); + + for (i = 0; i < KEY_MAX; i++) { + if (key[i]) + key_was_pressed[i] = key_is_pressed[i] = 1; + else + key_is_pressed[i] = 0; + } + + for (i = 0; i < KEY_MAX; i++) { + int x = 16 + (i % 4) * 160; + int y = 32 + (i / 4) * 14; + + if (key_is_pressed[i]) + rectfill(screen, x, y, x + 7, y + 7, red); + else if (key_was_pressed[i]) + rectfill(screen, x, y, x + 7, y + 7, yellow); + else + rectfill(screen, x, y, x + 7, y + 7, white); + } + + rest(1); + } + while ((!key[KEY_ESC]) && (!mouse_b)); + + do { + poll_keyboard(); + poll_mouse(); + } + while ((key[KEY_ESC]) || (mouse_b)); + + clear_keybuf(); +} + +/* handle the save command */ +static void save_key_map(void) +{ + int i; + char *section, *option_format, option[80], tmp1[80], tmp2[80]; + + set_config_file("xkeymap.cfg"); + section = uconvert_ascii("xkeymap", tmp1); + option_format = uconvert_ascii("keycode%d", tmp2); + + for (i = 0; i < 256; i++) { + if (keycode_to_scancode[i] > 0) { + uszprintf(option, sizeof(option), option_format, i); + set_config_int(section, option, keycode_to_scancode[i]); + } + } +} + +/* reads a specific keymapping table from the config file */ +void load_table(unsigned short *table, char *section) +{ + char name[80]; + int i; + + for (i=0; i + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/sdl2.2.0.5/build/native/docs/README.txt b/packages/sdl2.2.0.5/build/native/docs/README.txt new file mode 100644 index 00000000..f76a633b --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/docs/README.txt @@ -0,0 +1,21 @@ + + Simple DirectMedia Layer + + (SDL) + + Version 2.0 + +--- +http://www.libsdl.org/ + +Simple DirectMedia Layer is a cross-platform development library designed +to provide low level access to audio, keyboard, mouse, joystick, and graphics +hardware via OpenGL and Direct3D. It is used by video playback software, +emulators, and popular games including Valve's award winning catalog +and many Humble Bundle games. + +More extensive documentation is available in the docs directory, starting +with README.md + +Enjoy! + Sam Lantinga (slouken@libsdl.org) diff --git a/packages/sdl2.2.0.5/build/native/include/SDL.h b/packages/sdl2.2.0.5/build/native/include/SDL.h new file mode 100644 index 00000000..1a3fa285 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL.h @@ -0,0 +1,132 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL.h + * + * Main include header for the SDL library + */ + + +#ifndef _SDL_H +#define _SDL_H + +#include "SDL_main.h" +#include "SDL_stdinc.h" +#include "SDL_assert.h" +#include "SDL_atomic.h" +#include "SDL_audio.h" +#include "SDL_clipboard.h" +#include "SDL_cpuinfo.h" +#include "SDL_endian.h" +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_filesystem.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_haptic.h" +#include "SDL_hints.h" +#include "SDL_loadso.h" +#include "SDL_log.h" +#include "SDL_messagebox.h" +#include "SDL_mutex.h" +#include "SDL_power.h" +#include "SDL_render.h" +#include "SDL_rwops.h" +#include "SDL_system.h" +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_version.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* As of version 0.5, SDL is loaded dynamically into the application */ + +/** + * \name SDL_INIT_* + * + * These are the flags which may be passed to SDL_Init(). You should + * specify the subsystems which you will be using in your application. + */ +/* @{ */ +#define SDL_INIT_TIMER 0x00000001u +#define SDL_INIT_AUDIO 0x00000010u +#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ +#define SDL_INIT_JOYSTICK 0x00000200u /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ +#define SDL_INIT_HAPTIC 0x00001000u +#define SDL_INIT_GAMECONTROLLER 0x00002000u /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ +#define SDL_INIT_EVENTS 0x00004000u +#define SDL_INIT_NOPARACHUTE 0x00100000u /**< compatibility; this flag is ignored. */ +#define SDL_INIT_EVERYTHING ( \ + SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \ + SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \ + ) +/* @} */ + +/** + * This function initializes the subsystems specified by \c flags + */ +extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags); + +/** + * This function initializes specific SDL subsystems + * + * Subsystem initialization is ref-counted, you must call + * SDL_QuitSubSystem() for each SDL_InitSubSystem() to correctly + * shutdown a subsystem manually (or call SDL_Quit() to force shutdown). + * If a subsystem is already loaded then this call will + * increase the ref-count and return. + */ +extern DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags); + +/** + * This function cleans up specific SDL subsystems + */ +extern DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags); + +/** + * This function returns a mask of the specified subsystems which have + * previously been initialized. + * + * If \c flags is 0, it returns a mask of all initialized subsystems. + */ +extern DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 flags); + +/** + * This function cleans up all initialized subsystems. You should + * call it upon all exit conditions. + */ +extern DECLSPEC void SDLCALL SDL_Quit(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_assert.h b/packages/sdl2.2.0.5/build/native/include/SDL_assert.h new file mode 100644 index 00000000..402981f9 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_assert.h @@ -0,0 +1,289 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_assert_h +#define _SDL_assert_h + +#include "SDL_config.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SDL_ASSERT_LEVEL +#ifdef SDL_DEFAULT_ASSERT_LEVEL +#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL +#elif defined(_DEBUG) || defined(DEBUG) || \ + (defined(__GNUC__) && !defined(__OPTIMIZE__)) +#define SDL_ASSERT_LEVEL 2 +#else +#define SDL_ASSERT_LEVEL 1 +#endif +#endif /* SDL_ASSERT_LEVEL */ + +/* +These are macros and not first class functions so that the debugger breaks +on the assertion line and not in some random guts of SDL, and so each +assert can have unique static variables associated with it. +*/ + +#if defined(_MSC_VER) +/* Don't include intrin.h here because it contains C++ code */ + extern void __cdecl __debugbreak(void); + #define SDL_TriggerBreakpoint() __debugbreak() +#elif (!defined(__NACL__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) +#elif defined(HAVE_SIGNAL_H) + #include + #define SDL_TriggerBreakpoint() raise(SIGTRAP) +#else + /* How do we trigger breakpoints on this platform? */ + #define SDL_TriggerBreakpoint() +#endif + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */ +# define SDL_FUNCTION __func__ +#elif ((__GNUC__ >= 2) || defined(_MSC_VER)) +# define SDL_FUNCTION __FUNCTION__ +#else +# define SDL_FUNCTION "???" +#endif +#define SDL_FILE __FILE__ +#define SDL_LINE __LINE__ + +/* +sizeof (x) makes the compiler still parse the expression even without +assertions enabled, so the code is always checked at compile time, but +doesn't actually generate code for it, so there are no side effects or +expensive checks at run time, just the constant size of what x WOULD be, +which presumably gets optimized out as unused. +This also solves the problem of... + + int somevalue = blah(); + SDL_assert(somevalue == 1); + +...which would cause compiles to complain that somevalue is unused if we +disable assertions. +*/ + +/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking + this condition isn't constant. And looks like an owl's face! */ +#ifdef _MSC_VER /* stupid /W4 warnings. */ +#define SDL_NULL_WHILE_LOOP_CONDITION (0,0) +#else +#define SDL_NULL_WHILE_LOOP_CONDITION (0) +#endif + +#define SDL_disabled_assert(condition) \ + do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION) + +typedef enum +{ + SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */ + SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */ + SDL_ASSERTION_ABORT, /**< Terminate the program. */ + SDL_ASSERTION_IGNORE, /**< Ignore the assert. */ + SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */ +} SDL_AssertState; + +typedef struct SDL_AssertData +{ + int always_ignore; + unsigned int trigger_count; + const char *condition; + const char *filename; + int linenum; + const char *function; + const struct SDL_AssertData *next; +} SDL_AssertData; + +#if (SDL_ASSERT_LEVEL > 0) + +/* Never call this directly. Use the SDL_assert* macros. */ +extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, + const char *, + const char *, int) +#if defined(__clang__) +#if __has_feature(attribute_analyzer_noreturn) +/* this tells Clang's static analysis that we're a custom assert function, + and that the analyzer should assume the condition was always true past this + SDL_assert test. */ + __attribute__((analyzer_noreturn)) +#endif +#endif +; + +/* the do {} while(0) avoids dangling else problems: + if (x) SDL_assert(y); else blah(); + ... without the do/while, the "else" could attach to this macro's "if". + We try to handle just the minimum we need here in a macro...the loop, + the static vars, and break points. The heavy lifting is handled in + SDL_ReportAssertion(), in SDL_assert.c. +*/ +#define SDL_enabled_assert(condition) \ + do { \ + while ( !(condition) ) { \ + static struct SDL_AssertData sdl_assert_data = { \ + 0, 0, #condition, 0, 0, 0, 0 \ + }; \ + const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ + if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ + continue; /* go again. */ \ + } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \ + SDL_TriggerBreakpoint(); \ + } \ + break; /* not retrying. */ \ + } \ + } while (SDL_NULL_WHILE_LOOP_CONDITION) + +#endif /* enabled assertions support code */ + +/* Enable various levels of assertions. */ +#if SDL_ASSERT_LEVEL == 0 /* assertions disabled */ +# define SDL_assert(condition) SDL_disabled_assert(condition) +# define SDL_assert_release(condition) SDL_disabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 1 /* release settings. */ +# define SDL_assert(condition) SDL_disabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 2 /* normal settings. */ +# define SDL_assert(condition) SDL_enabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */ +# define SDL_assert(condition) SDL_enabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition) +#else +# error Unknown assertion level. +#endif + +/* this assertion is never disabled at any level. */ +#define SDL_assert_always(condition) SDL_enabled_assert(condition) + + +typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)( + const SDL_AssertData* data, void* userdata); + +/** + * \brief Set an application-defined assertion handler. + * + * This allows an app to show its own assertion UI and/or force the + * response to an assertion failure. If the app doesn't provide this, SDL + * will try to do the right thing, popping up a system-specific GUI dialog, + * and probably minimizing any fullscreen windows. + * + * This callback may fire from any thread, but it runs wrapped in a mutex, so + * it will only fire from one thread at a time. + * + * Setting the callback to NULL restores SDL's original internal handler. + * + * This callback is NOT reset to SDL's internal handler upon SDL_Quit()! + * + * \return SDL_AssertState value of how to handle the assertion failure. + * + * \param handler Callback function, called when an assertion fails. + * \param userdata A pointer passed to the callback as-is. + */ +extern DECLSPEC void SDLCALL SDL_SetAssertionHandler( + SDL_AssertionHandler handler, + void *userdata); + +/** + * \brief Get the default assertion handler. + * + * This returns the function pointer that is called by default when an + * assertion is triggered. This is an internal function provided by SDL, + * that is used for assertions when SDL_SetAssertionHandler() hasn't been + * used to provide a different function. + * + * \return The default SDL_AssertionHandler that is called when an assert triggers. + */ +extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void); + +/** + * \brief Get the current assertion handler. + * + * This returns the function pointer that is called when an assertion is + * triggered. This is either the value last passed to + * SDL_SetAssertionHandler(), or if no application-specified function is + * set, is equivalent to calling SDL_GetDefaultAssertionHandler(). + * + * \param puserdata Pointer to a void*, which will store the "userdata" + * pointer that was passed to SDL_SetAssertionHandler(). + * This value will always be NULL for the default handler. + * If you don't care about this data, it is safe to pass + * a NULL pointer to this function to ignore it. + * \return The SDL_AssertionHandler that is called when an assert triggers. + */ +extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata); + +/** + * \brief Get a list of all assertion failures. + * + * Get all assertions triggered since last call to SDL_ResetAssertionReport(), + * or the start of the program. + * + * The proper way to examine this data looks something like this: + * + * + * const SDL_AssertData *item = SDL_GetAssertionReport(); + * while (item) { + * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n", + * item->condition, item->function, item->filename, + * item->linenum, item->trigger_count, + * item->always_ignore ? "yes" : "no"); + * item = item->next; + * } + * + * + * \return List of all assertions. + * \sa SDL_ResetAssertionReport + */ +extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void); + +/** + * \brief Reset the list of all assertion failures. + * + * Reset list of all assertions triggered. + * + * \sa SDL_GetAssertionReport + */ +extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void); + + +/* these had wrong naming conventions until 2.0.4. Please update your app! */ +#define SDL_assert_state SDL_AssertState +#define SDL_assert_data SDL_AssertData + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_assert_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_atomic.h b/packages/sdl2.2.0.5/build/native/include/SDL_atomic.h new file mode 100644 index 00000000..56aa81df --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_atomic.h @@ -0,0 +1,268 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_atomic.h + * + * Atomic operations. + * + * IMPORTANT: + * If you are not an expert in concurrent lockless programming, you should + * only be using the atomic lock and reference counting functions in this + * file. In all other cases you should be protecting your data structures + * with full mutexes. + * + * The list of "safe" functions to use are: + * SDL_AtomicLock() + * SDL_AtomicUnlock() + * SDL_AtomicIncRef() + * SDL_AtomicDecRef() + * + * Seriously, here be dragons! + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * + * You can find out a little more about lockless programming and the + * subtle issues that can arise here: + * http://msdn.microsoft.com/en-us/library/ee418650%28v=vs.85%29.aspx + * + * There's also lots of good information here: + * http://www.1024cores.net/home/lock-free-algorithms + * http://preshing.com/ + * + * These operations may or may not actually be implemented using + * processor specific atomic operations. When possible they are + * implemented as true processor specific atomic operations. When that + * is not possible the are implemented using locks that *do* use the + * available atomic operations. + * + * All of the atomic operations that modify memory are full memory barriers. + */ + +#ifndef _SDL_atomic_h_ +#define _SDL_atomic_h_ + +#include "SDL_stdinc.h" +#include "SDL_platform.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SDL AtomicLock + * + * The atomic locks are efficient spinlocks using CPU instructions, + * but are vulnerable to starvation and can spin forever if a thread + * holding a lock has been terminated. For this reason you should + * minimize the code executed inside an atomic lock and never do + * expensive things like API or system calls while holding them. + * + * The atomic locks are not safe to lock recursively. + * + * Porting Note: + * The spin lock functions and type are required and can not be + * emulated because they are used in the atomic emulation code. + */ +/* @{ */ + +typedef int SDL_SpinLock; + +/** + * \brief Try to lock a spin lock by setting it to a non-zero value. + * + * \param lock Points to the lock. + * + * \return SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already held. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock(SDL_SpinLock *lock); + +/** + * \brief Lock a spin lock by setting it to a non-zero value. + * + * \param lock Points to the lock. + */ +extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock); + +/** + * \brief Unlock a spin lock by setting it to 0. Always returns immediately + * + * \param lock Points to the lock. + */ +extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock); + +/* @} *//* SDL AtomicLock */ + + +/** + * The compiler barrier prevents the compiler from reordering + * reads and writes to globally visible variables across the call. + */ +#if defined(_MSC_VER) && (_MSC_VER > 1200) +void _ReadWriteBarrier(void); +#pragma intrinsic(_ReadWriteBarrier) +#define SDL_CompilerBarrier() _ReadWriteBarrier() +#elif (defined(__GNUC__) && !defined(__EMSCRIPTEN__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) +/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */ +#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") +#else +#define SDL_CompilerBarrier() \ +{ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); } +#endif + +/** + * Memory barriers are designed to prevent reads and writes from being + * reordered by the compiler and being seen out of order on multi-core CPUs. + * + * A typical pattern would be for thread A to write some data and a flag, + * and for thread B to read the flag and get the data. In this case you + * would insert a release barrier between writing the data and the flag, + * guaranteeing that the data write completes no later than the flag is + * written, and you would insert an acquire barrier between reading the + * flag and reading the data, to ensure that all the reads associated + * with the flag have completed. + * + * In this pattern you should always see a release barrier paired with + * an acquire barrier and you should gate the data reads/writes with a + * single flag variable. + * + * For more information on these semantics, take a look at the blog post: + * http://preshing.com/20120913/acquire-and-release-semantics + */ +#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory") +#elif defined(__GNUC__) && defined(__arm__) +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) +#ifdef __thumb__ +/* The mcr instruction isn't available in thumb mode, use real functions */ +extern DECLSPEC void SDLCALL SDL_MemoryBarrierRelease(); +extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquire(); +#else +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") +#endif /* __thumb__ */ +#else +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory") +#endif /* __GNUC__ && __arm__ */ +#else +#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) +/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */ +#include +#define SDL_MemoryBarrierRelease() __machine_rel_barrier() +#define SDL_MemoryBarrierAcquire() __machine_acq_barrier() +#else +/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */ +#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier() +#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier() +#endif +#endif + +/** + * \brief A type representing an atomic integer value. It is a struct + * so people don't accidentally use numeric operations on it. + */ +typedef struct { int value; } SDL_atomic_t; + +/** + * \brief Set an atomic variable to a new value if it is currently an old value. + * + * \return SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. + * + * \note If you don't know what this function is for, you shouldn't use it! +*/ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval); + +/** + * \brief Set an atomic variable to a value. + * + * \return The previous value of the atomic variable. + */ +extern DECLSPEC int SDLCALL SDL_AtomicSet(SDL_atomic_t *a, int v); + +/** + * \brief Get the value of an atomic variable + */ +extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_atomic_t *a); + +/** + * \brief Add to an atomic variable. + * + * \return The previous value of the atomic variable. + * + * \note This same style can be used for any number operation + */ +extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int v); + +/** + * \brief Increment an atomic variable used as a reference count. + */ +#ifndef SDL_AtomicIncRef +#define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1) +#endif + +/** + * \brief Decrement an atomic variable used as a reference count. + * + * \return SDL_TRUE if the variable reached zero after decrementing, + * SDL_FALSE otherwise + */ +#ifndef SDL_AtomicDecRef +#define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1) +#endif + +/** + * \brief Set a pointer to a new value if it is currently an old value. + * + * \return SDL_TRUE if the pointer was set, SDL_FALSE otherwise. + * + * \note If you don't know what this function is for, you shouldn't use it! +*/ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval); + +/** + * \brief Set a pointer to a value atomically. + * + * \return The previous value of the pointer. + */ +extern DECLSPEC void* SDLCALL SDL_AtomicSetPtr(void **a, void* v); + +/** + * \brief Get the value of a pointer atomically. + */ +extern DECLSPEC void* SDLCALL SDL_AtomicGetPtr(void **a); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#include "close_code.h" + +#endif /* _SDL_atomic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_audio.h b/packages/sdl2.2.0.5/build/native/include/SDL_audio.h new file mode 100644 index 00000000..d51f0d1c --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_audio.h @@ -0,0 +1,672 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_audio.h + * + * Access to the raw audio mixing buffer for the SDL library. + */ + +#ifndef _SDL_audio_h +#define _SDL_audio_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_endian.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Audio format flags. + * + * These are what the 16 bits in SDL_AudioFormat currently mean... + * (Unspecified bits are always zero). + * + * \verbatim + ++-----------------------sample is signed if set + || + || ++-----------sample is bigendian if set + || || + || || ++---sample is float if set + || || || + || || || +---sample bit size---+ + || || || | | + 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 + \endverbatim + * + * There are macros in SDL 2.0 and later to query these bits. + */ +typedef Uint16 SDL_AudioFormat; + +/** + * \name Audio flags + */ +/* @{ */ + +#define SDL_AUDIO_MASK_BITSIZE (0xFF) +#define SDL_AUDIO_MASK_DATATYPE (1<<8) +#define SDL_AUDIO_MASK_ENDIAN (1<<12) +#define SDL_AUDIO_MASK_SIGNED (1<<15) +#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE) +#define SDL_AUDIO_ISFLOAT(x) (x & SDL_AUDIO_MASK_DATATYPE) +#define SDL_AUDIO_ISBIGENDIAN(x) (x & SDL_AUDIO_MASK_ENDIAN) +#define SDL_AUDIO_ISSIGNED(x) (x & SDL_AUDIO_MASK_SIGNED) +#define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x)) +#define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x)) +#define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x)) + +/** + * \name Audio format flags + * + * Defaults to LSB byte order. + */ +/* @{ */ +#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ +#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ +#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ +#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ +#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ +#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ +#define AUDIO_U16 AUDIO_U16LSB +#define AUDIO_S16 AUDIO_S16LSB +/* @} */ + +/** + * \name int32 support + */ +/* @{ */ +#define AUDIO_S32LSB 0x8020 /**< 32-bit integer samples */ +#define AUDIO_S32MSB 0x9020 /**< As above, but big-endian byte order */ +#define AUDIO_S32 AUDIO_S32LSB +/* @} */ + +/** + * \name float32 support + */ +/* @{ */ +#define AUDIO_F32LSB 0x8120 /**< 32-bit floating point samples */ +#define AUDIO_F32MSB 0x9120 /**< As above, but big-endian byte order */ +#define AUDIO_F32 AUDIO_F32LSB +/* @} */ + +/** + * \name Native audio byte ordering + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define AUDIO_U16SYS AUDIO_U16LSB +#define AUDIO_S16SYS AUDIO_S16LSB +#define AUDIO_S32SYS AUDIO_S32LSB +#define AUDIO_F32SYS AUDIO_F32LSB +#else +#define AUDIO_U16SYS AUDIO_U16MSB +#define AUDIO_S16SYS AUDIO_S16MSB +#define AUDIO_S32SYS AUDIO_S32MSB +#define AUDIO_F32SYS AUDIO_F32MSB +#endif +/* @} */ + +/** + * \name Allow change flags + * + * Which audio format changes are allowed when opening a device. + */ +/* @{ */ +#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001 +#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002 +#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004 +#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE) +/* @} */ + +/* @} *//* Audio flags */ + +/** + * This function is called when the audio device needs more data. + * + * \param userdata An application-specific parameter saved in + * the SDL_AudioSpec structure + * \param stream A pointer to the audio data buffer. + * \param len The length of that buffer in bytes. + * + * Once the callback returns, the buffer will no longer be valid. + * Stereo samples are stored in a LRLRLR ordering. + * + * You can choose to avoid callbacks and use SDL_QueueAudio() instead, if + * you like. Just open your audio device with a NULL callback. + */ +typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, + int len); + +/** + * The calculated values in this structure are calculated by SDL_OpenAudio(). + */ +typedef struct SDL_AudioSpec +{ + int freq; /**< DSP frequency -- samples per second */ + SDL_AudioFormat format; /**< Audio data format */ + Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ + Uint8 silence; /**< Audio buffer silence value (calculated) */ + Uint16 samples; /**< Audio buffer size in samples (power of 2) */ + Uint16 padding; /**< Necessary for some compile environments */ + Uint32 size; /**< Audio buffer size in bytes (calculated) */ + SDL_AudioCallback callback; /**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). */ + void *userdata; /**< Userdata passed to callback (ignored for NULL callbacks). */ +} SDL_AudioSpec; + + +struct SDL_AudioCVT; +typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt, + SDL_AudioFormat format); + +/** + * A structure to hold a set of audio conversion filters and buffers. + */ +#ifdef __GNUC__ +/* This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't + pad it out to 88 bytes to guarantee ABI compatibility between compilers. + vvv + The next time we rev the ABI, make sure to size the ints and add padding. +*/ +#define SDL_AUDIOCVT_PACKED __attribute__((packed)) +#else +#define SDL_AUDIOCVT_PACKED +#endif +/* */ +typedef struct SDL_AudioCVT +{ + int needed; /**< Set to 1 if conversion possible */ + SDL_AudioFormat src_format; /**< Source audio format */ + SDL_AudioFormat dst_format; /**< Target audio format */ + double rate_incr; /**< Rate conversion increment */ + Uint8 *buf; /**< Buffer to hold entire audio data */ + int len; /**< Length of original audio buffer */ + int len_cvt; /**< Length of converted audio buffer */ + int len_mult; /**< buffer must be len*len_mult big */ + double len_ratio; /**< Given len, final size is len*len_ratio */ + SDL_AudioFilter filters[10]; /**< Filter list */ + int filter_index; /**< Current audio conversion function */ +} SDL_AUDIOCVT_PACKED SDL_AudioCVT; + + +/* Function prototypes */ + +/** + * \name Driver discovery functions + * + * These functions return the list of built in audio drivers, in the + * order that they are normally initialized by default. + */ +/* @{ */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void); +extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index); +/* @} */ + +/** + * \name Initialization and cleanup + * + * \internal These functions are used internally, and should not be used unless + * you have a specific need to specify the audio driver you want to + * use. You should normally use SDL_Init() or SDL_InitSubSystem(). + */ +/* @{ */ +extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name); +extern DECLSPEC void SDLCALL SDL_AudioQuit(void); +/* @} */ + +/** + * This function returns the name of the current audio driver, or NULL + * if no driver has been initialized. + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void); + +/** + * This function opens the audio device with the desired parameters, and + * returns 0 if successful, placing the actual hardware parameters in the + * structure pointed to by \c obtained. If \c obtained is NULL, the audio + * data passed to the callback function will be guaranteed to be in the + * requested format, and will be automatically converted to the hardware + * audio format if necessary. This function returns -1 if it failed + * to open the audio device, or couldn't set up the audio thread. + * + * When filling in the desired audio spec structure, + * - \c desired->freq should be the desired audio frequency in samples-per- + * second. + * - \c desired->format should be the desired audio format. + * - \c desired->samples is the desired size of the audio buffer, in + * samples. This number should be a power of two, and may be adjusted by + * the audio driver to a value more suitable for the hardware. Good values + * seem to range between 512 and 8096 inclusive, depending on the + * application and CPU speed. Smaller values yield faster response time, + * but can lead to underflow if the application is doing heavy processing + * and cannot fill the audio buffer in time. A stereo sample consists of + * both right and left channels in LR ordering. + * Note that the number of samples is directly related to time by the + * following formula: \code ms = (samples*1000)/freq \endcode + * - \c desired->size is the size in bytes of the audio buffer, and is + * calculated by SDL_OpenAudio(). + * - \c desired->silence is the value used to set the buffer to silence, + * and is calculated by SDL_OpenAudio(). + * - \c desired->callback should be set to a function that will be called + * when the audio device is ready for more data. It is passed a pointer + * to the audio buffer, and the length in bytes of the audio buffer. + * This function usually runs in a separate thread, and so you should + * protect data structures that it accesses by calling SDL_LockAudio() + * and SDL_UnlockAudio() in your code. Alternately, you may pass a NULL + * pointer here, and call SDL_QueueAudio() with some frequency, to queue + * more audio samples to be played (or for capture devices, call + * SDL_DequeueAudio() with some frequency, to obtain audio samples). + * - \c desired->userdata is passed as the first parameter to your callback + * function. If you passed a NULL callback, this value is ignored. + * + * The audio device starts out playing silence when it's opened, and should + * be enabled for playing by calling \c SDL_PauseAudio(0) when you are ready + * for your audio callback function to be called. Since the audio driver + * may modify the requested size of the audio buffer, you should allocate + * any local mixing buffers after you open the audio device. + */ +extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, + SDL_AudioSpec * obtained); + +/** + * SDL Audio Device IDs. + * + * A successful call to SDL_OpenAudio() is always device id 1, and legacy + * SDL audio APIs assume you want this device ID. SDL_OpenAudioDevice() calls + * always returns devices >= 2 on success. The legacy calls are good both + * for backwards compatibility and when you don't care about multiple, + * specific, or capture devices. + */ +typedef Uint32 SDL_AudioDeviceID; + +/** + * Get the number of available devices exposed by the current driver. + * Only valid after a successfully initializing the audio subsystem. + * Returns -1 if an explicit list of devices can't be determined; this is + * not an error. For example, if SDL is set up to talk to a remote audio + * server, it can't list every one available on the Internet, but it will + * still allow a specific host to be specified to SDL_OpenAudioDevice(). + * + * In many common cases, when this function returns a value <= 0, it can still + * successfully open the default device (NULL for first argument of + * SDL_OpenAudioDevice()). + */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture); + +/** + * Get the human-readable name of a specific audio device. + * Must be a value between 0 and (number of audio devices-1). + * Only valid after a successfully initializing the audio subsystem. + * The values returned by this function reflect the latest call to + * SDL_GetNumAudioDevices(); recall that function to redetect available + * hardware. + * + * The string returned by this function is UTF-8 encoded, read-only, and + * managed internally. You are not to free it. If you need to keep the + * string for any length of time, you should make your own copy of it, as it + * will be invalid next time any of several other SDL functions is called. + */ +extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index, + int iscapture); + + +/** + * Open a specific audio device. Passing in a device name of NULL requests + * the most reasonable default (and is equivalent to calling SDL_OpenAudio()). + * + * The device name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but + * some drivers allow arbitrary and driver-specific strings, such as a + * hostname/IP address for a remote audio server, or a filename in the + * diskaudio driver. + * + * \return 0 on error, a valid device ID that is >= 2 on success. + * + * SDL_OpenAudio(), unlike this function, always acts on device ID 1. + */ +extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice(const char + *device, + int iscapture, + const + SDL_AudioSpec * + desired, + SDL_AudioSpec * + obtained, + int + allowed_changes); + + + +/** + * \name Audio state + * + * Get the current audio state. + */ +/* @{ */ +typedef enum +{ + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED +} SDL_AudioStatus; +extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioStatus(void); + +extern DECLSPEC SDL_AudioStatus SDLCALL +SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev); +/* @} *//* Audio State */ + +/** + * \name Pause audio functions + * + * These functions pause and unpause the audio callback processing. + * They should be called with a parameter of 0 after opening the audio + * device to start playing sound. This is so you can safely initialize + * data for your callback function after opening the audio device. + * Silence will be written to the audio device during the pause. + */ +/* @{ */ +extern DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on); +extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev, + int pause_on); +/* @} *//* Pause audio functions */ + +/** + * This function loads a WAVE from the data source, automatically freeing + * that source if \c freesrc is non-zero. For example, to load a WAVE file, + * you could do: + * \code + * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, ...); + * \endcode + * + * If this function succeeds, it returns the given SDL_AudioSpec, + * filled with the audio data format of the wave data, and sets + * \c *audio_buf to a malloc()'d buffer containing the audio data, + * and sets \c *audio_len to the length of that audio buffer, in bytes. + * You need to free the audio buffer with SDL_FreeWAV() when you are + * done with it. + * + * This function returns NULL and sets the SDL error message if the + * wave file cannot be opened, uses an unknown data format, or is + * corrupt. Currently raw and MS-ADPCM WAVE files are supported. + */ +extern DECLSPEC SDL_AudioSpec *SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, + int freesrc, + SDL_AudioSpec * spec, + Uint8 ** audio_buf, + Uint32 * audio_len); + +/** + * Loads a WAV from a file. + * Compatibility convenience function. + */ +#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ + SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) + +/** + * This function frees data previously allocated with SDL_LoadWAV_RW() + */ +extern DECLSPEC void SDLCALL SDL_FreeWAV(Uint8 * audio_buf); + +/** + * This function takes a source format and rate and a destination format + * and rate, and initializes the \c cvt structure with information needed + * by SDL_ConvertAudio() to convert a buffer of audio data from one format + * to the other. + * + * \return -1 if the format conversion is not supported, 0 if there's + * no conversion needed, or 1 if the audio filter is set up. + */ +extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt, + SDL_AudioFormat src_format, + Uint8 src_channels, + int src_rate, + SDL_AudioFormat dst_format, + Uint8 dst_channels, + int dst_rate); + +/** + * Once you have initialized the \c cvt structure using SDL_BuildAudioCVT(), + * created an audio buffer \c cvt->buf, and filled it with \c cvt->len bytes of + * audio data in the source format, this function will convert it in-place + * to the desired format. + * + * The data conversion may expand the size of the audio data, so the buffer + * \c cvt->buf should be allocated after the \c cvt structure is initialized by + * SDL_BuildAudioCVT(), and should be \c cvt->len*cvt->len_mult bytes long. + */ +extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT * cvt); + +#define SDL_MIX_MAXVOLUME 128 +/** + * This takes two audio buffers of the playing audio format and mixes + * them, performing addition, volume adjustment, and overflow clipping. + * The volume ranges from 0 - 128, and should be set to ::SDL_MIX_MAXVOLUME + * for full audio volume. Note this does not change hardware volume. + * This is provided for convenience -- you can mix your own audio data. + */ +extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src, + Uint32 len, int volume); + +/** + * This works like SDL_MixAudio(), but you specify the audio format instead of + * using the format of audio device 1. Thus it can be used when no audio + * device is open at all. + */ +extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, + const Uint8 * src, + SDL_AudioFormat format, + Uint32 len, int volume); + +/** + * Queue more audio on non-callback devices. + * + * (If you are looking to retrieve queued audio from a non-callback capture + * device, you want SDL_DequeueAudio() instead. This will return -1 to + * signify an error if you use it with capture devices.) + * + * SDL offers two ways to feed audio to the device: you can either supply a + * callback that SDL triggers with some frequency to obtain more audio + * (pull method), or you can supply no callback, and then SDL will expect + * you to supply data at regular intervals (push method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Queued data will drain to the device as + * necessary without further intervention from you. If the device needs + * audio but there is not enough queued, it will play silence to make up + * the difference. This means you will have skips in your audio playback + * if you aren't routinely queueing sufficient data. + * + * This function copies the supplied data, so you are safe to free it when + * the function returns. This function is thread-safe, but queueing to the + * same device from two threads at once does not promise which buffer will + * be queued first. + * + * You may not queue audio on a device that is using an application-supplied + * callback; doing so returns an error. You have to use the audio callback + * or queue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before queueing; SDL + * handles locking internally for this function. + * + * \param dev The device ID to which we will queue audio. + * \param data The data to queue to the device for later playback. + * \param len The number of bytes (not samples!) to which (data) points. + * \return zero on success, -1 on error. + * + * \sa SDL_GetQueuedAudioSize + * \sa SDL_ClearQueuedAudio + */ +extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len); + +/** + * Dequeue more audio on non-callback devices. + * + * (If you are looking to queue audio for output on a non-callback playback + * device, you want SDL_QueueAudio() instead. This will always return 0 + * if you use it with playback devices.) + * + * SDL offers two ways to retrieve audio from a capture device: you can + * either supply a callback that SDL triggers with some frequency as the + * device records more audio data, (push method), or you can supply no + * callback, and then SDL will expect you to retrieve data at regular + * intervals (pull method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Data from the device will keep queuing as + * necessary without further intervention from you. This means you will + * eventually run out of memory if you aren't routinely dequeueing data. + * + * Capture devices will not queue data when paused; if you are expecting + * to not need captured audio for some length of time, use + * SDL_PauseAudioDevice() to stop the capture device from queueing more + * data. This can be useful during, say, level loading times. When + * unpaused, capture devices will start queueing data from that point, + * having flushed any capturable data available while paused. + * + * This function is thread-safe, but dequeueing from the same device from + * two threads at once does not promise which thread will dequeued data + * first. + * + * You may not dequeue audio from a device that is using an + * application-supplied callback; doing so returns an error. You have to use + * the audio callback, or dequeue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before queueing; SDL + * handles locking internally for this function. + * + * \param dev The device ID from which we will dequeue audio. + * \param data A pointer into where audio data should be copied. + * \param len The number of bytes (not samples!) to which (data) points. + * \return number of bytes dequeued, which could be less than requested. + * + * \sa SDL_GetQueuedAudioSize + * \sa SDL_ClearQueuedAudio + */ +extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len); + +/** + * Get the number of bytes of still-queued audio. + * + * For playback device: + * + * This is the number of bytes that have been queued for playback with + * SDL_QueueAudio(), but have not yet been sent to the hardware. This + * number may shrink at any time, so this only informs of pending data. + * + * Once we've sent it to the hardware, this function can not decide the + * exact byte boundary of what has been played. It's possible that we just + * gave the hardware several kilobytes right before you called this + * function, but it hasn't played any of it yet, or maybe half of it, etc. + * + * For capture devices: + * + * This is the number of bytes that have been captured by the device and + * are waiting for you to dequeue. This number may grow at any time, so + * this only informs of the lower-bound of available data. + * + * You may not queue audio on a device that is using an application-supplied + * callback; calling this function on such a device always returns 0. + * You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use + * the audio callback, but not both. + * + * You should not call SDL_LockAudio() on the device before querying; SDL + * handles locking internally for this function. + * + * \param dev The device ID of which we will query queued audio size. + * \return Number of bytes (not samples!) of queued audio. + * + * \sa SDL_QueueAudio + * \sa SDL_ClearQueuedAudio + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev); + +/** + * Drop any queued audio data. For playback devices, this is any queued data + * still waiting to be submitted to the hardware. For capture devices, this + * is any data that was queued by the device that hasn't yet been dequeued by + * the application. + * + * Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For + * playback devices, the hardware will start playing silence if more audio + * isn't queued. Unpaused capture devices will start filling the queue again + * as soon as they have more data available (which, depending on the state + * of the hardware and the thread, could be before this function call + * returns!). + * + * This will not prevent playback of queued audio that's already been sent + * to the hardware, as we can not undo that, so expect there to be some + * fraction of a second of audio that might still be heard. This can be + * useful if you want to, say, drop any pending music during a level change + * in your game. + * + * You may not queue audio on a device that is using an application-supplied + * callback; calling this function on such a device is always a no-op. + * You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use + * the audio callback, but not both. + * + * You should not call SDL_LockAudio() on the device before clearing the + * queue; SDL handles locking internally for this function. + * + * This function always succeeds and thus returns void. + * + * \param dev The device ID of which to clear the audio queue. + * + * \sa SDL_QueueAudio + * \sa SDL_GetQueuedAudioSize + */ +extern DECLSPEC void SDLCALL SDL_ClearQueuedAudio(SDL_AudioDeviceID dev); + + +/** + * \name Audio lock functions + * + * The lock manipulated by these functions protects the callback function. + * During a SDL_LockAudio()/SDL_UnlockAudio() pair, you can be guaranteed that + * the callback function is not running. Do not call these from the callback + * function or you will cause deadlock. + */ +/* @{ */ +extern DECLSPEC void SDLCALL SDL_LockAudio(void); +extern DECLSPEC void SDLCALL SDL_LockAudioDevice(SDL_AudioDeviceID dev); +extern DECLSPEC void SDLCALL SDL_UnlockAudio(void); +extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev); +/* @} *//* Audio lock functions */ + +/** + * This function shuts down audio processing and closes the audio device. + */ +extern DECLSPEC void SDLCALL SDL_CloseAudio(void); +extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_audio_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_bits.h b/packages/sdl2.2.0.5/build/native/include/SDL_bits.h new file mode 100644 index 00000000..528da2ea --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_bits.h @@ -0,0 +1,97 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_bits.h + * + * Functions for fiddling with bits and bitmasks. + */ + +#ifndef _SDL_bits_h +#define _SDL_bits_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_bits.h + */ + +/** + * Get the index of the most significant bit. Result is undefined when called + * with 0. This operation can also be stated as "count leading zeroes" and + * "log base 2". + * + * \return Index of the most significant bit, or -1 if the value is 0. + */ +SDL_FORCE_INLINE int +SDL_MostSignificantBitIndex32(Uint32 x) +{ +#if defined(__GNUC__) && __GNUC__ >= 4 + /* Count Leading Zeroes builtin in GCC. + * http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html + */ + if (x == 0) { + return -1; + } + return 31 - __builtin_clz(x); +#else + /* Based off of Bit Twiddling Hacks by Sean Eron Anderson + * , released in the public domain. + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog + */ + const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; + const int S[] = {1, 2, 4, 8, 16}; + + int msbIndex = 0; + int i; + + if (x == 0) { + return -1; + } + + for (i = 4; i >= 0; i--) + { + if (x & b[i]) + { + x >>= S[i]; + msbIndex |= S[i]; + } + } + + return msbIndex; +#endif +} + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_bits_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_blendmode.h b/packages/sdl2.2.0.5/build/native/include/SDL_blendmode.h new file mode 100644 index 00000000..56d8ad66 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_blendmode.h @@ -0,0 +1,63 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_blendmode.h + * + * Header file declaring the SDL_BlendMode enumeration + */ + +#ifndef _SDL_blendmode_h +#define _SDL_blendmode_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The blend mode used in SDL_RenderCopy() and drawing operations. + */ +typedef enum +{ + SDL_BLENDMODE_NONE = 0x00000000, /**< no blending + dstRGBA = srcRGBA */ + SDL_BLENDMODE_BLEND = 0x00000001, /**< alpha blending + dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) + dstA = srcA + (dstA * (1-srcA)) */ + SDL_BLENDMODE_ADD = 0x00000002, /**< additive blending + dstRGB = (srcRGB * srcA) + dstRGB + dstA = dstA */ + SDL_BLENDMODE_MOD = 0x00000004 /**< color modulate + dstRGB = srcRGB * dstRGB + dstA = dstA */ +} SDL_BlendMode; + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_blendmode_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_clipboard.h b/packages/sdl2.2.0.5/build/native/include/SDL_clipboard.h new file mode 100644 index 00000000..a5556f21 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_clipboard.h @@ -0,0 +1,71 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_clipboard.h + * + * Include file for SDL clipboard handling + */ + +#ifndef _SDL_clipboard_h +#define _SDL_clipboard_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * \brief Put UTF-8 text into the clipboard + * + * \sa SDL_GetClipboardText() + */ +extern DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text); + +/** + * \brief Get UTF-8 text from the clipboard, which must be freed with SDL_free() + * + * \sa SDL_SetClipboardText() + */ +extern DECLSPEC char * SDLCALL SDL_GetClipboardText(void); + +/** + * \brief Returns a flag indicating whether the clipboard exists and contains a text string that is non-empty + * + * \sa SDL_GetClipboardText() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasClipboardText(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_clipboard_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_config.h b/packages/sdl2.2.0.5/build/native/include/SDL_config.h new file mode 100644 index 00000000..890986cc --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_config.h @@ -0,0 +1,221 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_config_windows_h +#define _SDL_config_windows_h + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +#define HAVE_DDRAW_H 1 +#define HAVE_DINPUT_H 1 +#define HAVE_DSOUND_H 1 +#define HAVE_DXGI_H 1 +#define HAVE_XINPUT_H 1 + +/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ +#ifdef HAVE_LIBC +/* Useful headers */ +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE__STRLWR 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE__LTOA 1 +#define HAVE__ULTOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_ACOS 1 +#define HAVE_ASIN 1 +#define HAVE_CEIL 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_POW 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#if _MSC_VER >= 1800 +#define HAVE_STRTOLL 1 +#define HAVE_VSSCANF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_SCALBN 1 +#endif +#if !defined(_MSC_VER) || defined(_USE_MATH_DEFINES) +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_DSOUND 1 +#define SDL_AUDIO_DRIVER_XAUDIO2 1 +#define SDL_AUDIO_DRIVER_WINMM 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_DINPUT 1 +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_DINPUT 1 +#define SDL_HAPTIC_XINPUT 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +#ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 1 +#endif +#ifndef SDL_VIDEO_RENDER_D3D11 +#define SDL_VIDEO_RENDER_D3D11 0 +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_WGL +#define SDL_VIDEO_OPENGL_WGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif + + +/* Enable system power support */ +#define SDL_POWER_WINDOWS 1 + +/* Enable filesystem support */ +#define SDL_FILESYSTEM_WINDOWS 1 + +/* Enable assembly routines (Win64 doesn't have inline asm) */ +#ifndef _WIN64 +#define SDL_ASSEMBLY_ROUTINES 1 +#endif + +#endif /* _SDL_config_windows_h */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_cpuinfo.h b/packages/sdl2.2.0.5/build/native/include/SDL_cpuinfo.h new file mode 100644 index 00000000..d0ba47bf --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_cpuinfo.h @@ -0,0 +1,161 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_cpuinfo.h + * + * CPU feature detection for SDL. + */ + +#ifndef _SDL_cpuinfo_h +#define _SDL_cpuinfo_h + +#include "SDL_stdinc.h" + +/* Need to do this here because intrin.h has C++ code in it */ +/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64)) +#include +#ifndef _WIN64 +#define __MMX__ +#define __3dNOW__ +#endif +#define __SSE__ +#define __SSE2__ +#elif defined(__MINGW64_VERSION_MAJOR) +#include +#else +#ifdef __ALTIVEC__ +#if HAVE_ALTIVEC_H && !defined(__APPLE_ALTIVEC__) +#include +#undef pixel +#endif +#endif +#ifdef __MMX__ +#include +#endif +#ifdef __3dNOW__ +#include +#endif +#ifdef __SSE__ +#include +#endif +#ifdef __SSE2__ +#include +#endif +#endif + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is a guess for the cacheline size used for padding. + * Most x86 processors have a 64 byte cache line. + * The 64-bit PowerPC processors have a 128 byte cache line. + * We'll use the larger value to be generally safe. + */ +#define SDL_CACHELINE_SIZE 128 + +/** + * This function returns the number of CPU cores available. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCount(void); + +/** + * This function returns the L1 cache line size of the CPU + * + * This is useful for determining multi-threaded structure padding + * or SIMD prefetch sizes. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); + +/** + * This function returns true if the CPU has the RDTSC instruction. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); + +/** + * This function returns true if the CPU has AltiVec features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); + +/** + * This function returns true if the CPU has MMX features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); + +/** + * This function returns true if the CPU has 3DNow! features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); + +/** + * This function returns true if the CPU has SSE features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); + +/** + * This function returns true if the CPU has SSE2 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); + +/** + * This function returns true if the CPU has SSE3 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE3(void); + +/** + * This function returns true if the CPU has SSE4.1 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void); + +/** + * This function returns true if the CPU has SSE4.2 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void); + +/** + * This function returns true if the CPU has AVX features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void); + +/** + * This function returns true if the CPU has AVX2 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void); + +/** + * This function returns the amount of RAM configured in the system, in MB. + */ +extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_cpuinfo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_egl.h b/packages/sdl2.2.0.5/build/native/include/SDL_egl.h new file mode 100644 index 00000000..bea2a6c0 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_egl.h @@ -0,0 +1,1673 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_egl.h + * + * This is a simple file to encapsulate the EGL API headers. + */ +#ifndef _MSC_VER + +#include +#include + +#else /* _MSC_VER */ + +/* EGL headers for Visual Studio */ + +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. +* +* $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ +* +* Adopters may modify this file to suit their platform. Adopters are +* encouraged to submit platform specific modifications to the Khronos +* group so that they can be included in future versions of this file. +* Please submit changes by sending them to the public Khronos Bugzilla +* (http://khronos.org/bugzilla) by filing a bug against product +* "Khronos (general)" component "Registry". +* +* A predefined template which fills in some of the bug fields can be +* reached using http://tinyurl.com/khrplatform-h-bugreport, but you +* must create a Bugzilla login first. +* +* +* See the Implementer's Guidelines for information about where this file +* should be located on your system and for more details of its use: +* http://www.khronos.org/registry/implementers_guide.pdf +* +* This file should be included as +* #include +* by Khronos client API header files that use its types and defines. +* +* The types in khrplatform.h should only be used to define API-specific types. +* +* Types defined in khrplatform.h: +* khronos_int8_t signed 8 bit +* khronos_uint8_t unsigned 8 bit +* khronos_int16_t signed 16 bit +* khronos_uint16_t unsigned 16 bit +* khronos_int32_t signed 32 bit +* khronos_uint32_t unsigned 32 bit +* khronos_int64_t signed 64 bit +* khronos_uint64_t unsigned 64 bit +* khronos_intptr_t signed same number of bits as a pointer +* khronos_uintptr_t unsigned same number of bits as a pointer +* khronos_ssize_t signed size +* khronos_usize_t unsigned size +* khronos_float_t signed 32 bit floating point +* khronos_time_ns_t unsigned 64 bit time in nanoseconds +* khronos_utime_nanoseconds_t unsigned time interval or absolute time in +* nanoseconds +* khronos_stime_nanoseconds_t signed time interval in nanoseconds +* khronos_boolean_enum_t enumerated boolean type. This should +* only be used as a base type when a client API's boolean type is +* an enum. Client APIs which use an integer or other type for +* booleans cannot use this as the base type for their boolean. +* +* Tokens defined in khrplatform.h: +* +* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. +* +* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. +* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. +* +* Calling convention macros defined in this file: +* KHRONOS_APICALL +* KHRONOS_APIENTRY +* KHRONOS_APIATTRIBUTES +* +* These may be used in function prototypes as: +* +* KHRONOS_APICALL void KHRONOS_APIENTRY funcname( +* int arg1, +* int arg2) KHRONOS_APIATTRIBUTES; +*/ + +/*------------------------------------------------------------------------- +* Definition of KHRONOS_APICALL +*------------------------------------------------------------------------- +* This precedes the return type of the function in the function prototype. +*/ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- +* Definition of KHRONOS_APIENTRY +*------------------------------------------------------------------------- +* This follows the return type of the function and precedes the function +* name in the function prototype. +*/ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) +/* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- +* Definition of KHRONOS_APIATTRIBUTES +*------------------------------------------------------------------------- +* This follows the closing parenthesis of the function prototype arguments. +*/ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- +* basic type definitions +*-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* +* Using +*/ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* +* Using +*/ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* +* Win32 +*/ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* +* Sun or Digital +*/ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* +* Hypothetical platform with no float or int64 support +*/ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* +* Generic fallback +*/ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* +* Types that are (so far) the same on all platforms +*/ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* +* Types that differ between LLP64 and LP64 architectures - in LLP64, +* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears +* to be the only LLP64 architecture in current use. +*/ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* +* Float type +*/ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types +* +* These types can be used to represent a time interval in nanoseconds or +* an absolute Unadjusted System Time. Unadjusted System Time is the number +* of nanoseconds since some arbitrary system event (e.g. since the last +* time the system booted). The Unadjusted System Time is an unsigned +* 64 bit value that wraps back to 0 every 584 years. Time intervals +* may be either signed or unsigned. +*/ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* +* Dummy value used to pad enum types to 32 bits. +*/ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* +* Enumerated boolean type +* +* Values other than zero should be considered to be true. Therefore +* comparisons should not be made against KHRONOS_TRUE. +*/ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ + + +#ifndef __eglplatform_h_ +#define __eglplatform_h_ + +/* +** Copyright (c) 2007-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Platform-specific types and definitions for egl.h +* $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $ +* +* Adopters may modify khrplatform.h and this file to suit their platform. +* You are encouraged to submit all modifications to the Khronos group so that +* they can be included in future versions of this file. Please submit changes +* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) +* by filing a bug against product "EGL" component "Registry". +*/ + +/*#include */ + +/* Macros used in EGL function prototype declarations. +* +* EGL functions should be prototyped as: +* +* EGLAPI return-type EGLAPIENTRY eglFunction(arguments); +* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments); +* +* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h +*/ + +#ifndef EGLAPI +#define EGLAPI KHRONOS_APICALL +#endif + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY KHRONOS_APIENTRY +#endif +#define EGLAPIENTRYP EGLAPIENTRY* + +/* The types NativeDisplayType, NativeWindowType, and NativePixmapType +* are aliases of window-system-dependent types, such as X Display * or +* Windows Device Context. They must be defined in platform-specific +* code below. The EGL-prefixed versions of Native*Type are the same +* types, renamed in EGL 1.3 so all types in the API start with "EGL". +* +* Khronos STRONGLY RECOMMENDS that you use the default definitions +* provided below, since these changes affect both binary and source +* portability of applications using EGL running on different EGL +* implementations. +*/ + +#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include + +#if __WINRT__ +#include +typedef IUnknown * EGLNativeWindowType; +typedef IUnknown * EGLNativePixmapType; +typedef IUnknown * EGLNativeDisplayType; +#else +typedef HDC EGLNativeDisplayType; +typedef HBITMAP EGLNativePixmapType; +typedef HWND EGLNativeWindowType; +#endif + +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ + +typedef int EGLNativeDisplayType; +typedef void *EGLNativeWindowType; +typedef void *EGLNativePixmapType; + +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + +#elif defined(__GBM__) + +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__ANDROID__) /* Android */ + +struct ANativeWindow; +struct egl_native_pixmap_t; + +typedef struct ANativeWindow *EGLNativeWindowType; +typedef struct egl_native_pixmap_t *EGLNativePixmapType; +typedef void *EGLNativeDisplayType; + +#elif defined(MIR_EGL_PLATFORM) + +#include +typedef MirEGLNativeDisplayType EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef MirEGLNativeWindowType EGLNativeWindowType; + +#elif defined(__unix__) + +#ifdef MESA_EGL_NO_X11_HEADERS + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#else + +/* X11 (tentative) */ +#include +#include + +typedef Display *EGLNativeDisplayType; +typedef Pixmap EGLNativePixmapType; +typedef Window EGLNativeWindowType; + +#endif /* MESA_EGL_NO_X11_HEADERS */ + +#else +#error "Platform not recognized" +#endif + +/* EGL 1.2 types, renamed for consistency in EGL 1.3 */ +typedef EGLNativeDisplayType NativeDisplayType; +typedef EGLNativePixmapType NativePixmapType; +typedef EGLNativeWindowType NativeWindowType; + + +/* Define EGLint. This must be a signed integral type large enough to contain +* all legal attribute names and values passed into and out of EGL, whether +* their type is boolean, bitmask, enumerant (symbolic constant), integer, +* handle, or other. While in general a 32-bit integer will suffice, if +* handles are 64 bit types, then EGLint should be defined as a signed 64-bit +* integer type. +*/ +typedef khronos_int32_t EGLint; + +#endif /* __eglplatform_h */ + +#ifndef __egl_h_ +#define __egl_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $ +*/ + +/*#include */ + +/* Generated on date 20150623 */ + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_VERSION_1_0 +#define EGL_VERSION_1_0 1 +typedef unsigned int EGLBoolean; +typedef void *EGLDisplay; +typedef void *EGLConfig; +typedef void *EGLSurface; +typedef void *EGLContext; +typedef void (*__eglMustCastToProperFunctionPointerType)(void); +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BAD_ACCESS 0x3002 +#define EGL_BAD_ALLOC 0x3003 +#define EGL_BAD_ATTRIBUTE 0x3004 +#define EGL_BAD_CONFIG 0x3005 +#define EGL_BAD_CONTEXT 0x3006 +#define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DISPLAY 0x3008 +#define EGL_BAD_MATCH 0x3009 +#define EGL_BAD_NATIVE_PIXMAP 0x300A +#define EGL_BAD_NATIVE_WINDOW 0x300B +#define EGL_BAD_PARAMETER 0x300C +#define EGL_BAD_SURFACE 0x300D +#define EGL_BLUE_SIZE 0x3022 +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_CORE_NATIVE_ENGINE 0x305B +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_DONT_CARE ((EGLint)-1) +#define EGL_DRAW 0x3059 +#define EGL_EXTENSIONS 0x3055 +#define EGL_FALSE 0 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_HEIGHT 0x3056 +#define EGL_LARGEST_PBUFFER 0x3058 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_NONE 0x3038 +#define EGL_NON_CONFORMANT_CONFIG 0x3051 +#define EGL_NOT_INITIALIZED 0x3001 +#define EGL_NO_CONTEXT ((EGLContext)0) +#define EGL_NO_DISPLAY ((EGLDisplay)0) +#define EGL_NO_SURFACE ((EGLSurface)0) +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_PIXMAP_BIT 0x0002 +#define EGL_READ 0x305A +#define EGL_RED_SIZE 0x3024 +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SLOW_CONFIG 0x3050 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_SUCCESS 0x3000 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_TRANSPARENT_RGB 0x3052 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRUE 1 +#define EGL_VENDOR 0x3053 +#define EGL_VERSION 0x3054 +#define EGL_WIDTH 0x3057 +#define EGL_WINDOW_BIT 0x0004 +EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void); +EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw); +EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id); +EGLAPI EGLint EGLAPIENTRY eglGetError (void); +EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname); +EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor); +EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); +#endif /* EGL_VERSION_1_0 */ + +#ifndef EGL_VERSION_1_1 +#define EGL_VERSION_1_1 1 +#define EGL_BACK_BUFFER 0x3084 +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_CONTEXT_LOST 0x300E +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_MIPMAP_TEXTURE 0x3082 +#define EGL_MIPMAP_LEVEL 0x3083 +#define EGL_NO_TEXTURE 0x305C +#define EGL_TEXTURE_2D 0x305F +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_RGB 0x305D +#define EGL_TEXTURE_RGBA 0x305E +#define EGL_TEXTURE_TARGET 0x3081 +EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval); +#endif /* EGL_VERSION_1_1 */ + +#ifndef EGL_VERSION_1_2 +#define EGL_VERSION_1_2 1 +typedef unsigned int EGLenum; +typedef void *EGLClientBuffer; +#define EGL_ALPHA_FORMAT 0x3088 +#define EGL_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_ALPHA_FORMAT_PRE 0x308C +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_BUFFER_PRESERVED 0x3094 +#define EGL_BUFFER_DESTROYED 0x3095 +#define EGL_CLIENT_APIS 0x308D +#define EGL_COLORSPACE 0x3087 +#define EGL_COLORSPACE_sRGB 0x3089 +#define EGL_COLORSPACE_LINEAR 0x308A +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_CONTEXT_CLIENT_TYPE 0x3097 +#define EGL_DISPLAY_SCALING 10000 +#define EGL_HORIZONTAL_RESOLUTION 0x3090 +#define EGL_LUMINANCE_BUFFER 0x308F +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_OPENGL_ES_BIT 0x0001 +#define EGL_OPENVG_BIT 0x0002 +#define EGL_OPENGL_ES_API 0x30A0 +#define EGL_OPENVG_API 0x30A1 +#define EGL_OPENVG_IMAGE 0x3096 +#define EGL_PIXEL_ASPECT_RATIO 0x3092 +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_RGB_BUFFER 0x308E +#define EGL_SINGLE_BUFFER 0x3085 +#define EGL_SWAP_BEHAVIOR 0x3093 +#define EGL_UNKNOWN ((EGLint)-1) +#define EGL_VERTICAL_RESOLUTION 0x3091 +EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api); +EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); +#endif /* EGL_VERSION_1_2 */ + +#ifndef EGL_VERSION_1_3 +#define EGL_VERSION_1_3 1 +#define EGL_CONFORMANT 0x3042 +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 +#define EGL_OPENGL_ES2_BIT 0x0004 +#define EGL_VG_ALPHA_FORMAT 0x3088 +#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_VG_ALPHA_FORMAT_PRE 0x308C +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 +#define EGL_VG_COLORSPACE 0x3087 +#define EGL_VG_COLORSPACE_sRGB 0x3089 +#define EGL_VG_COLORSPACE_LINEAR 0x308A +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 +#endif /* EGL_VERSION_1_3 */ + +#ifndef EGL_VERSION_1_4 +#define EGL_VERSION_1_4 1 +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 +#define EGL_MULTISAMPLE_RESOLVE 0x3099 +#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A +#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B +#define EGL_OPENGL_API 0x30A2 +#define EGL_OPENGL_BIT 0x0008 +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); +#endif /* EGL_VERSION_1_4 */ + +#ifndef EGL_VERSION_1_5 +#define EGL_VERSION_1_5 1 +typedef void *EGLSync; +typedef intptr_t EGLAttrib; +typedef khronos_utime_nanoseconds_t EGLTime; +typedef void *EGLImage; +#define EGL_CONTEXT_MAJOR_VERSION 0x3098 +#define EGL_CONTEXT_MINOR_VERSION 0x30FB +#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD +#define EGL_NO_RESET_NOTIFICATION 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2 +#define EGL_OPENGL_ES3_BIT 0x00000040 +#define EGL_CL_EVENT_HANDLE 0x309C +#define EGL_SYNC_CL_EVENT 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 +#define EGL_SYNC_TYPE 0x30F7 +#define EGL_SYNC_STATUS 0x30F1 +#define EGL_SYNC_CONDITION 0x30F8 +#define EGL_SIGNALED 0x30F2 +#define EGL_UNSIGNALED 0x30F3 +#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001 +#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull +#define EGL_TIMEOUT_EXPIRED 0x30F5 +#define EGL_CONDITION_SATISFIED 0x30F6 +#define EGL_NO_SYNC ((EGLSync)0) +#define EGL_SYNC_FENCE 0x30F9 +#define EGL_GL_COLORSPACE 0x309D +#define EGL_GL_COLORSPACE_SRGB 0x3089 +#define EGL_GL_COLORSPACE_LINEAR 0x308A +#define EGL_GL_RENDERBUFFER 0x30B9 +#define EGL_GL_TEXTURE_2D 0x30B1 +#define EGL_GL_TEXTURE_LEVEL 0x30BC +#define EGL_GL_TEXTURE_3D 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET 0x30BD +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 +#define EGL_IMAGE_PRESERVED 0x30D2 +#define EGL_NO_IMAGE ((EGLImage)0) +EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image); +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags); +#endif /* EGL_VERSION_1_5 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __egl_h_ */ + + + +#ifndef __eglext_h_ +#define __eglext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $ +*/ + +/*#include */ + +#define EGL_EGLEXT_VERSION 20150623 + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: _nomatch_^ + * Default extensions included: egl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_KHR_cl_event +#define EGL_KHR_cl_event 1 +#define EGL_CL_EVENT_HANDLE_KHR 0x309C +#define EGL_SYNC_CL_EVENT_KHR 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF +#endif /* EGL_KHR_cl_event */ + +#ifndef EGL_KHR_cl_event2 +#define EGL_KHR_cl_event2 1 +typedef void *EGLSyncKHR; +typedef intptr_t EGLAttribKHR; +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); +#endif +#endif /* EGL_KHR_cl_event2 */ + +#ifndef EGL_KHR_client_get_all_proc_addresses +#define EGL_KHR_client_get_all_proc_addresses 1 +#endif /* EGL_KHR_client_get_all_proc_addresses */ + +#ifndef EGL_KHR_config_attribs +#define EGL_KHR_config_attribs 1 +#define EGL_CONFORMANT_KHR 0x3042 +#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 +#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 +#endif /* EGL_KHR_config_attribs */ + +#ifndef EGL_KHR_create_context +#define EGL_KHR_create_context 1 +#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB +#define EGL_CONTEXT_FLAGS_KHR 0x30FC +#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD +#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF +#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 +#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 +#endif /* EGL_KHR_create_context */ + +#ifndef EGL_KHR_create_context_no_error +#define EGL_KHR_create_context_no_error 1 +#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 +#endif /* EGL_KHR_create_context_no_error */ + +#ifndef EGL_KHR_fence_sync +#define EGL_KHR_fence_sync 1 +typedef khronos_utime_nanoseconds_t EGLTimeKHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE_KHR 0x30F9 +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_fence_sync */ + +#ifndef EGL_KHR_get_all_proc_addresses +#define EGL_KHR_get_all_proc_addresses 1 +#endif /* EGL_KHR_get_all_proc_addresses */ + +#ifndef EGL_KHR_gl_colorspace +#define EGL_KHR_gl_colorspace 1 +#define EGL_GL_COLORSPACE_KHR 0x309D +#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 +#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A +#endif /* EGL_KHR_gl_colorspace */ + +#ifndef EGL_KHR_gl_renderbuffer_image +#define EGL_KHR_gl_renderbuffer_image 1 +#define EGL_GL_RENDERBUFFER_KHR 0x30B9 +#endif /* EGL_KHR_gl_renderbuffer_image */ + +#ifndef EGL_KHR_gl_texture_2D_image +#define EGL_KHR_gl_texture_2D_image 1 +#define EGL_GL_TEXTURE_2D_KHR 0x30B1 +#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC +#endif /* EGL_KHR_gl_texture_2D_image */ + +#ifndef EGL_KHR_gl_texture_3D_image +#define EGL_KHR_gl_texture_3D_image 1 +#define EGL_GL_TEXTURE_3D_KHR 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD +#endif /* EGL_KHR_gl_texture_3D_image */ + +#ifndef EGL_KHR_gl_texture_cubemap_image +#define EGL_KHR_gl_texture_cubemap_image 1 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 +#endif /* EGL_KHR_gl_texture_cubemap_image */ + +#ifndef EGL_KHR_image +#define EGL_KHR_image 1 +typedef void *EGLImageKHR; +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 +#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_KHR_image */ + +#ifndef EGL_KHR_image_base +#define EGL_KHR_image_base 1 +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 +#endif /* EGL_KHR_image_base */ + +#ifndef EGL_KHR_image_pixmap +#define EGL_KHR_image_pixmap 1 +#endif /* EGL_KHR_image_pixmap */ + +#ifndef EGL_KHR_lock_surface +#define EGL_KHR_lock_surface 1 +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 +#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 +#define EGL_MATCH_FORMAT_KHR 0x3043 +#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 +#define EGL_FORMAT_RGB_565_KHR 0x30C1 +#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 +#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#define EGL_BITMAP_ORIGIN_KHR 0x30C8 +#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 +#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA +#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB +#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC +#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD +#define EGL_LOWER_LEFT_KHR 0x30CE +#define EGL_UPPER_LEFT_KHR 0x30CF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface); +#endif +#endif /* EGL_KHR_lock_surface */ + +#ifndef EGL_KHR_lock_surface2 +#define EGL_KHR_lock_surface2 1 +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 +#endif /* EGL_KHR_lock_surface2 */ + +#ifndef EGL_KHR_lock_surface3 +#define EGL_KHR_lock_surface3 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value); +#endif +#endif /* EGL_KHR_lock_surface3 */ + +#ifndef EGL_KHR_partial_update +#define EGL_KHR_partial_update 1 +#define EGL_BUFFER_AGE_KHR 0x313D +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_partial_update */ + +#ifndef EGL_KHR_platform_android +#define EGL_KHR_platform_android 1 +#define EGL_PLATFORM_ANDROID_KHR 0x3141 +#endif /* EGL_KHR_platform_android */ + +#ifndef EGL_KHR_platform_gbm +#define EGL_KHR_platform_gbm 1 +#define EGL_PLATFORM_GBM_KHR 0x31D7 +#endif /* EGL_KHR_platform_gbm */ + +#ifndef EGL_KHR_platform_wayland +#define EGL_KHR_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 +#endif /* EGL_KHR_platform_wayland */ + +#ifndef EGL_KHR_platform_x11 +#define EGL_KHR_platform_x11 1 +#define EGL_PLATFORM_X11_KHR 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6 +#endif /* EGL_KHR_platform_x11 */ + +#ifndef EGL_KHR_reusable_sync +#define EGL_KHR_reusable_sync 1 +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_STATUS_KHR 0x30F1 +#define EGL_SIGNALED_KHR 0x30F2 +#define EGL_UNSIGNALED_KHR 0x30F3 +#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 +#define EGL_CONDITION_SATISFIED_KHR 0x30F6 +#define EGL_SYNC_TYPE_KHR 0x30F7 +#define EGL_SYNC_REUSABLE_KHR 0x30FA +#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 +#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull +#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_reusable_sync */ + +#ifndef EGL_KHR_stream +#define EGL_KHR_stream 1 +typedef void *EGLStreamKHR; +typedef khronos_uint64_t EGLuint64KHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0) +#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 +#define EGL_PRODUCER_FRAME_KHR 0x3212 +#define EGL_CONSUMER_FRAME_KHR 0x3213 +#define EGL_STREAM_STATE_KHR 0x3214 +#define EGL_STREAM_STATE_CREATED_KHR 0x3215 +#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 +#define EGL_STREAM_STATE_EMPTY_KHR 0x3217 +#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218 +#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219 +#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A +#define EGL_BAD_STREAM_KHR 0x321B +#define EGL_BAD_STATE_KHR 0x321C +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream */ + +#ifndef EGL_KHR_stream_consumer_gltexture +#define EGL_KHR_stream_consumer_gltexture 1 +#ifdef EGL_KHR_stream +#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_consumer_gltexture */ + +#ifndef EGL_KHR_stream_cross_process_fd +#define EGL_KHR_stream_cross_process_fd 1 +typedef int EGLNativeFileDescriptorKHR; +#ifdef EGL_KHR_stream +#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1)) +typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_cross_process_fd */ + +#ifndef EGL_KHR_stream_fifo +#define EGL_KHR_stream_fifo 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC +#define EGL_STREAM_TIME_NOW_KHR 0x31FD +#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE +#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_fifo */ + +#ifndef EGL_KHR_stream_producer_aldatalocator +#define EGL_KHR_stream_producer_aldatalocator 1 +#ifdef EGL_KHR_stream +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_aldatalocator */ + +#ifndef EGL_KHR_stream_producer_eglsurface +#define EGL_KHR_stream_producer_eglsurface 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_BIT_KHR 0x0800 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_eglsurface */ + +#ifndef EGL_KHR_surfaceless_context +#define EGL_KHR_surfaceless_context 1 +#endif /* EGL_KHR_surfaceless_context */ + +#ifndef EGL_KHR_swap_buffers_with_damage +#define EGL_KHR_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_swap_buffers_with_damage */ + +#ifndef EGL_KHR_vg_parent_image +#define EGL_KHR_vg_parent_image 1 +#define EGL_VG_PARENT_IMAGE_KHR 0x30BA +#endif /* EGL_KHR_vg_parent_image */ + +#ifndef EGL_KHR_wait_sync +#define EGL_KHR_wait_sync 1 +typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#endif +#endif /* EGL_KHR_wait_sync */ + +#ifndef EGL_ANDROID_blob_cache +#define EGL_ANDROID_blob_cache 1 +typedef khronos_ssize_t EGLsizeiANDROID; +typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); +typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); +typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#endif +#endif /* EGL_ANDROID_blob_cache */ + +#ifndef EGL_ANDROID_framebuffer_target +#define EGL_ANDROID_framebuffer_target 1 +#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 +#endif /* EGL_ANDROID_framebuffer_target */ + +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 +#endif /* EGL_ANDROID_image_native_buffer */ + +#ifndef EGL_ANDROID_native_fence_sync +#define EGL_ANDROID_native_fence_sync 1 +#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144 +#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145 +#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146 +#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1 +typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync); +#endif +#endif /* EGL_ANDROID_native_fence_sync */ + +#ifndef EGL_ANDROID_recordable +#define EGL_ANDROID_recordable 1 +#define EGL_RECORDABLE_ANDROID 0x3142 +#endif /* EGL_ANDROID_recordable */ + +#ifndef EGL_ANGLE_d3d_share_handle_client_buffer +#define EGL_ANGLE_d3d_share_handle_client_buffer 1 +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */ + +#ifndef EGL_ANGLE_device_d3d +#define EGL_ANGLE_device_d3d 1 +#define EGL_D3D9_DEVICE_ANGLE 0x33A0 +#define EGL_D3D11_DEVICE_ANGLE 0x33A1 +#endif /* EGL_ANGLE_device_d3d */ + +#ifndef EGL_ANGLE_query_surface_pointer +#define EGL_ANGLE_query_surface_pointer 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif +#endif /* EGL_ANGLE_query_surface_pointer */ + +#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle +#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 +#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ + +#ifndef EGL_ANGLE_window_fixed_size +#define EGL_ANGLE_window_fixed_size 1 +#define EGL_FIXED_SIZE_ANGLE 0x3201 +#endif /* EGL_ANGLE_window_fixed_size */ + +#ifndef EGL_ARM_pixmap_multisample_discard +#define EGL_ARM_pixmap_multisample_discard 1 +#define EGL_DISCARD_SAMPLES_ARM 0x3286 +#endif /* EGL_ARM_pixmap_multisample_discard */ + +#ifndef EGL_EXT_buffer_age +#define EGL_EXT_buffer_age 1 +#define EGL_BUFFER_AGE_EXT 0x313D +#endif /* EGL_EXT_buffer_age */ + +#ifndef EGL_EXT_client_extensions +#define EGL_EXT_client_extensions 1 +#endif /* EGL_EXT_client_extensions */ + +#ifndef EGL_EXT_create_context_robustness +#define EGL_EXT_create_context_robustness 1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 +#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF +#endif /* EGL_EXT_create_context_robustness */ + +#ifndef EGL_EXT_device_base +#define EGL_EXT_device_base 1 +typedef void *EGLDeviceEXT; +#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)(0)) +#define EGL_BAD_DEVICE_EXT 0x322B +#define EGL_DEVICE_EXT 0x322C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#endif +#endif /* EGL_EXT_device_base */ + +#ifndef EGL_EXT_device_drm +#define EGL_EXT_device_drm 1 +#define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#endif /* EGL_EXT_device_drm */ + +#ifndef EGL_EXT_device_enumeration +#define EGL_EXT_device_enumeration 1 +#endif /* EGL_EXT_device_enumeration */ + +#ifndef EGL_EXT_device_openwf +#define EGL_EXT_device_openwf 1 +#define EGL_OPENWF_DEVICE_ID_EXT 0x3237 +#endif /* EGL_EXT_device_openwf */ + +#ifndef EGL_EXT_device_query +#define EGL_EXT_device_query 1 +#endif /* EGL_EXT_device_query */ + +#ifndef EGL_EXT_image_dma_buf_import +#define EGL_EXT_image_dma_buf_import 1 +#define EGL_LINUX_DMA_BUF_EXT 0x3270 +#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 +#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 +#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 +#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 +#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 +#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 +#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 +#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 +#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 +#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A +#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B +#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C +#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D +#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E +#define EGL_ITU_REC601_EXT 0x327F +#define EGL_ITU_REC709_EXT 0x3280 +#define EGL_ITU_REC2020_EXT 0x3281 +#define EGL_YUV_FULL_RANGE_EXT 0x3282 +#define EGL_YUV_NARROW_RANGE_EXT 0x3283 +#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284 +#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 +#endif /* EGL_EXT_image_dma_buf_import */ + +#ifndef EGL_EXT_multiview_window +#define EGL_EXT_multiview_window 1 +#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 +#endif /* EGL_EXT_multiview_window */ + +#ifndef EGL_EXT_output_base +#define EGL_EXT_output_base 1 +typedef void *EGLOutputLayerEXT; +typedef void *EGLOutputPortEXT; +#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0) +#define EGL_NO_OUTPUT_PORT_EXT ((EGLOutputPortEXT)0) +#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D +#define EGL_BAD_OUTPUT_PORT_EXT 0x322E +#define EGL_SWAP_INTERVAL_EXT 0x322F +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#endif +#endif /* EGL_EXT_output_base */ + +#ifndef EGL_EXT_output_drm +#define EGL_EXT_output_drm 1 +#define EGL_DRM_CRTC_EXT 0x3234 +#define EGL_DRM_PLANE_EXT 0x3235 +#define EGL_DRM_CONNECTOR_EXT 0x3236 +#endif /* EGL_EXT_output_drm */ + +#ifndef EGL_EXT_output_openwf +#define EGL_EXT_output_openwf 1 +#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238 +#define EGL_OPENWF_PORT_ID_EXT 0x3239 +#endif /* EGL_EXT_output_openwf */ + +#ifndef EGL_EXT_platform_base +#define EGL_EXT_platform_base 1 +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#endif +#endif /* EGL_EXT_platform_base */ + +#ifndef EGL_EXT_platform_device +#define EGL_EXT_platform_device 1 +#define EGL_PLATFORM_DEVICE_EXT 0x313F +#endif /* EGL_EXT_platform_device */ + +#ifndef EGL_EXT_platform_wayland +#define EGL_EXT_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_EXT 0x31D8 +#endif /* EGL_EXT_platform_wayland */ + +#ifndef EGL_EXT_platform_x11 +#define EGL_EXT_platform_x11 1 +#define EGL_PLATFORM_X11_EXT 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 +#endif /* EGL_EXT_platform_x11 */ + +#ifndef EGL_EXT_protected_surface +#define EGL_EXT_protected_surface 1 +#define EGL_PROTECTED_CONTENT_EXT 0x32C0 +#endif /* EGL_EXT_protected_surface */ + +#ifndef EGL_EXT_stream_consumer_egloutput +#define EGL_EXT_stream_consumer_egloutput 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#endif +#endif /* EGL_EXT_stream_consumer_egloutput */ + +#ifndef EGL_EXT_swap_buffers_with_damage +#define EGL_EXT_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_EXT_swap_buffers_with_damage */ + +#ifndef EGL_EXT_yuv_surface +#define EGL_EXT_yuv_surface 1 +#define EGL_YUV_ORDER_EXT 0x3301 +#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 +#define EGL_YUV_SUBSAMPLE_EXT 0x3312 +#define EGL_YUV_DEPTH_RANGE_EXT 0x3317 +#define EGL_YUV_CSC_STANDARD_EXT 0x330A +#define EGL_YUV_PLANE_BPP_EXT 0x331A +#define EGL_YUV_BUFFER_EXT 0x3300 +#define EGL_YUV_ORDER_YUV_EXT 0x3302 +#define EGL_YUV_ORDER_YVU_EXT 0x3303 +#define EGL_YUV_ORDER_YUYV_EXT 0x3304 +#define EGL_YUV_ORDER_UYVY_EXT 0x3305 +#define EGL_YUV_ORDER_YVYU_EXT 0x3306 +#define EGL_YUV_ORDER_VYUY_EXT 0x3307 +#define EGL_YUV_ORDER_AYUV_EXT 0x3308 +#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313 +#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314 +#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315 +#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318 +#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319 +#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B +#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C +#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D +#define EGL_YUV_PLANE_BPP_0_EXT 0x331B +#define EGL_YUV_PLANE_BPP_8_EXT 0x331C +#define EGL_YUV_PLANE_BPP_10_EXT 0x331D +#endif /* EGL_EXT_yuv_surface */ + +#ifndef EGL_HI_clientpixmap +#define EGL_HI_clientpixmap 1 +struct EGLClientPixmapHI { + void *pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; +}; +#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#endif +#endif /* EGL_HI_clientpixmap */ + +#ifndef EGL_HI_colorformats +#define EGL_HI_colorformats 1 +#define EGL_COLOR_FORMAT_HI 0x8F70 +#define EGL_COLOR_RGB_HI 0x8F71 +#define EGL_COLOR_RGBA_HI 0x8F72 +#define EGL_COLOR_ARGB_HI 0x8F73 +#endif /* EGL_HI_colorformats */ + +#ifndef EGL_IMG_context_priority +#define EGL_IMG_context_priority 1 +#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 +#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 +#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 +#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 +#endif /* EGL_IMG_context_priority */ + +#ifndef EGL_MESA_drm_image +#define EGL_MESA_drm_image 1 +#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 +#define EGL_DRM_BUFFER_USE_MESA 0x31D1 +#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 +#define EGL_DRM_BUFFER_MESA 0x31D3 +#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 +#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 +#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif +#endif /* EGL_MESA_drm_image */ + +#ifndef EGL_MESA_image_dma_buf_export +#define EGL_MESA_image_dma_buf_export 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#endif +#endif /* EGL_MESA_image_dma_buf_export */ + +#ifndef EGL_MESA_platform_gbm +#define EGL_MESA_platform_gbm 1 +#define EGL_PLATFORM_GBM_MESA 0x31D7 +#endif /* EGL_MESA_platform_gbm */ + +#ifndef EGL_NOK_swap_region +#define EGL_NOK_swap_region 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#endif +#endif /* EGL_NOK_swap_region */ + +#ifndef EGL_NOK_swap_region2 +#define EGL_NOK_swap_region2 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#endif +#endif /* EGL_NOK_swap_region2 */ + +#ifndef EGL_NOK_texture_from_pixmap +#define EGL_NOK_texture_from_pixmap 1 +#define EGL_Y_INVERTED_NOK 0x307F +#endif /* EGL_NOK_texture_from_pixmap */ + +#ifndef EGL_NV_3dvision_surface +#define EGL_NV_3dvision_surface 1 +#define EGL_AUTO_STEREO_NV 0x3136 +#endif /* EGL_NV_3dvision_surface */ + +#ifndef EGL_NV_coverage_sample +#define EGL_NV_coverage_sample 1 +#define EGL_COVERAGE_BUFFERS_NV 0x30E0 +#define EGL_COVERAGE_SAMPLES_NV 0x30E1 +#endif /* EGL_NV_coverage_sample */ + +#ifndef EGL_NV_coverage_sample_resolve +#define EGL_NV_coverage_sample_resolve 1 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 +#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 +#endif /* EGL_NV_coverage_sample_resolve */ + +#ifndef EGL_NV_cuda_event +#define EGL_NV_cuda_event 1 +#define EGL_CUDA_EVENT_HANDLE_NV 0x323B +#define EGL_SYNC_CUDA_EVENT_NV 0x323C +#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D +#endif /* EGL_NV_cuda_event */ + +#ifndef EGL_NV_depth_nonlinear +#define EGL_NV_depth_nonlinear 1 +#define EGL_DEPTH_ENCODING_NV 0x30E2 +#define EGL_DEPTH_ENCODING_NONE_NV 0 +#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 +#endif /* EGL_NV_depth_nonlinear */ + +#ifndef EGL_NV_device_cuda +#define EGL_NV_device_cuda 1 +#define EGL_CUDA_DEVICE_NV 0x323A +#endif /* EGL_NV_device_cuda */ + +#ifndef EGL_NV_native_query +#define EGL_NV_native_query 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#endif +#endif /* EGL_NV_native_query */ + +#ifndef EGL_NV_post_convert_rounding +#define EGL_NV_post_convert_rounding 1 +#endif /* EGL_NV_post_convert_rounding */ + +#ifndef EGL_NV_post_sub_buffer +#define EGL_NV_post_sub_buffer 1 +#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif +#endif /* EGL_NV_post_sub_buffer */ + +#ifndef EGL_NV_stream_sync +#define EGL_NV_stream_sync 1 +#define EGL_SYNC_NEW_FRAME_NV 0x321F +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#endif +#endif /* EGL_NV_stream_sync */ + +#ifndef EGL_NV_sync +#define EGL_NV_sync 1 +typedef void *EGLSyncNV; +typedef khronos_utime_nanoseconds_t EGLTimeNV; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6 +#define EGL_SYNC_STATUS_NV 0x30E7 +#define EGL_SIGNALED_NV 0x30E8 +#define EGL_UNSIGNALED_NV 0x30E9 +#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001 +#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull +#define EGL_ALREADY_SIGNALED_NV 0x30EA +#define EGL_TIMEOUT_EXPIRED_NV 0x30EB +#define EGL_CONDITION_SATISFIED_NV 0x30EC +#define EGL_SYNC_TYPE_NV 0x30ED +#define EGL_SYNC_CONDITION_NV 0x30EE +#define EGL_SYNC_FENCE_NV 0x30EF +#define EGL_NO_SYNC_NV ((EGLSyncNV)0) +typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync); +EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_sync */ + +#ifndef EGL_NV_system_time +#define EGL_NV_system_time 1 +typedef khronos_utime_nanoseconds_t EGLuint64NV; +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void); +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_system_time */ + +#ifndef EGL_TIZEN_image_native_buffer +#define EGL_TIZEN_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_TIZEN 0x32A0 +#endif /* EGL_TIZEN_image_native_buffer */ + +#ifndef EGL_TIZEN_image_native_surface +#define EGL_TIZEN_image_native_surface 1 +#define EGL_NATIVE_SURFACE_TIZEN 0x32A1 +#endif /* EGL_TIZEN_image_native_surface */ + +#ifdef __cplusplus +} +#endif + +#endif /* __eglext_h_ */ + + +#endif /* _MSC_VER */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_endian.h b/packages/sdl2.2.0.5/build/native/include/SDL_endian.h new file mode 100644 index 00000000..9100b103 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_endian.h @@ -0,0 +1,239 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_endian.h + * + * Functions for reading and writing endian-specific values + */ + +#ifndef _SDL_endian_h +#define _SDL_endian_h + +#include "SDL_stdinc.h" + +/** + * \name The two types of endianness + */ +/* @{ */ +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 +/* @} */ + +#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ +#ifdef __linux__ +#include +#define SDL_BYTEORDER __BYTE_ORDER +#else /* __linux__ */ +#if defined(__hppa__) || \ + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MISPEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__sparc__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#endif +#endif /* __linux__ */ +#endif /* !SDL_BYTEORDER */ + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_endian.h + */ +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + int result; + + __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); + return (Uint16)result; +} +#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#else +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + return SDL_static_cast(Uint16, ((x << 8) | (x >> 8))); +} +#endif + +#if defined(__GNUC__) && defined(__i386__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswap %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswapl %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + Uint32 result; + + __asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x)); + __asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x)); + __asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x)); + return result; +} +#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#else +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) | + ((x >> 8) & 0x0000FF00) | (x >> 24))); +} +#endif + +#if defined(__GNUC__) && defined(__i386__) +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + union + { + struct + { + Uint32 a, b; + } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a), + "1"(v.s. + b)); + return v.u; +} +#elif defined(__GNUC__) && defined(__x86_64__) +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + __asm__("bswapq %0": "=r"(x):"0"(x)); + return x; +} +#else +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + Uint32 hi, lo; + + /* Separate into high and low 32-bit values and swap them */ + lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x >>= 32; + hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return (x); +} +#endif + + +SDL_FORCE_INLINE float +SDL_SwapFloat(float x) +{ + union + { + float f; + Uint32 ui32; + } swapper; + swapper.f = x; + swapper.ui32 = SDL_Swap32(swapper.ui32); + return swapper.f; +} + + +/** + * \name Swap to native + * Byteswap item from the specified endianness to the native endianness. + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SDL_SwapLE16(X) (X) +#define SDL_SwapLE32(X) (X) +#define SDL_SwapLE64(X) (X) +#define SDL_SwapFloatLE(X) (X) +#define SDL_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(X) +#define SDL_SwapFloatBE(X) SDL_SwapFloat(X) +#else +#define SDL_SwapLE16(X) SDL_Swap16(X) +#define SDL_SwapLE32(X) SDL_Swap32(X) +#define SDL_SwapLE64(X) SDL_Swap64(X) +#define SDL_SwapFloatLE(X) SDL_SwapFloat(X) +#define SDL_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) +#define SDL_SwapFloatBE(X) (X) +#endif +/* @} *//* Swap to native */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_endian_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_error.h b/packages/sdl2.2.0.5/build/native/include/SDL_error.h new file mode 100644 index 00000000..2f3b4b50 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_error.h @@ -0,0 +1,76 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_error.h + * + * Simple error message routines for SDL. + */ + +#ifndef _SDL_error_h +#define _SDL_error_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Public functions */ +/* SDL_SetError() unconditionally returns -1. */ +extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); +extern DECLSPEC const char *SDLCALL SDL_GetError(void); +extern DECLSPEC void SDLCALL SDL_ClearError(void); + +/** + * \name Internal error functions + * + * \internal + * Private error reporting function - used internally. + */ +/* @{ */ +#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) +#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) +#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param)) +typedef enum +{ + SDL_ENOMEM, + SDL_EFREAD, + SDL_EFWRITE, + SDL_EFSEEK, + SDL_UNSUPPORTED, + SDL_LASTERROR +} SDL_errorcode; +/* SDL_Error() unconditionally returns -1. */ +extern DECLSPEC int SDLCALL SDL_Error(SDL_errorcode code); +/* @} *//* Internal error functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_error_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_events.h b/packages/sdl2.2.0.5/build/native/include/SDL_events.h new file mode 100644 index 00000000..edb89ef4 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_events.h @@ -0,0 +1,754 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_events.h + * + * Include file for SDL event handling. + */ + +#ifndef _SDL_events_h +#define _SDL_events_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_quit.h" +#include "SDL_gesture.h" +#include "SDL_touch.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* General keyboard/mouse state definitions */ +#define SDL_RELEASED 0 +#define SDL_PRESSED 1 + +/** + * \brief The types of events that can be delivered. + */ +typedef enum +{ + SDL_FIRSTEVENT = 0, /**< Unused (do not remove) */ + + /* Application events */ + SDL_QUIT = 0x100, /**< User-requested quit */ + + /* These application events have special meaning on iOS, see README-ios.md for details */ + SDL_APP_TERMINATING, /**< The application is being terminated by the OS + Called on iOS in applicationWillTerminate() + Called on Android in onDestroy() + */ + SDL_APP_LOWMEMORY, /**< The application is low on memory, free memory if possible. + Called on iOS in applicationDidReceiveMemoryWarning() + Called on Android in onLowMemory() + */ + SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background + Called on iOS in applicationWillResignActive() + Called on Android in onPause() + */ + SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time + Called on iOS in applicationDidEnterBackground() + Called on Android in onPause() + */ + SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground + Called on iOS in applicationWillEnterForeground() + Called on Android in onResume() + */ + SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive + Called on iOS in applicationDidBecomeActive() + Called on Android in onResume() + */ + + /* Window events */ + SDL_WINDOWEVENT = 0x200, /**< Window state change */ + SDL_SYSWMEVENT, /**< System specific event */ + + /* Keyboard events */ + SDL_KEYDOWN = 0x300, /**< Key pressed */ + SDL_KEYUP, /**< Key released */ + SDL_TEXTEDITING, /**< Keyboard text editing (composition) */ + SDL_TEXTINPUT, /**< Keyboard text input */ + SDL_KEYMAPCHANGED, /**< Keymap changed due to a system event such as an + input language or keyboard layout change. + */ + + /* Mouse events */ + SDL_MOUSEMOTION = 0x400, /**< Mouse moved */ + SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ + SDL_MOUSEBUTTONUP, /**< Mouse button released */ + SDL_MOUSEWHEEL, /**< Mouse wheel motion */ + + /* Joystick events */ + SDL_JOYAXISMOTION = 0x600, /**< Joystick axis motion */ + SDL_JOYBALLMOTION, /**< Joystick trackball motion */ + SDL_JOYHATMOTION, /**< Joystick hat position change */ + SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ + SDL_JOYBUTTONUP, /**< Joystick button released */ + SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ + SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ + + /* Game controller events */ + SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ + SDL_CONTROLLERBUTTONDOWN, /**< Game controller button pressed */ + SDL_CONTROLLERBUTTONUP, /**< Game controller button released */ + SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */ + SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */ + SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */ + + /* Touch events */ + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + + /* Gesture events */ + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + + /* Clipboard events */ + SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */ + + /* Drag and drop events */ + SDL_DROPFILE = 0x1000, /**< The system requests a file open */ + SDL_DROPTEXT, /**< text/plain drag-and-drop event */ + SDL_DROPBEGIN, /**< A new set of drops is beginning (NULL filename) */ + SDL_DROPCOMPLETE, /**< Current set of drops is now complete (NULL filename) */ + + /* Audio hotplug events */ + SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */ + SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */ + + /* Render events */ + SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */ + SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */ + + /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use, + * and should be allocated with SDL_RegisterEvents() + */ + SDL_USEREVENT = 0x8000, + + /** + * This last event is only for bounding internal arrays + */ + SDL_LASTEVENT = 0xFFFF +} SDL_EventType; + +/** + * \brief Fields shared by every event + */ +typedef struct SDL_CommonEvent +{ + Uint32 type; + Uint32 timestamp; +} SDL_CommonEvent; + +/** + * \brief Window state change event data (event.window.*) + */ +typedef struct SDL_WindowEvent +{ + Uint32 type; /**< ::SDL_WINDOWEVENT */ + Uint32 timestamp; + Uint32 windowID; /**< The associated window */ + Uint8 event; /**< ::SDL_WindowEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ + Sint32 data2; /**< event dependent data */ +} SDL_WindowEvent; + +/** + * \brief Keyboard button event structure (event.key.*) + */ +typedef struct SDL_KeyboardEvent +{ + Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ + Uint32 timestamp; + Uint32 windowID; /**< The window with keyboard focus, if any */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 repeat; /**< Non-zero if this is a key repeat */ + Uint8 padding2; + Uint8 padding3; + SDL_Keysym keysym; /**< The key that was pressed or released */ +} SDL_KeyboardEvent; + +#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text editing event structure (event.edit.*) + */ +typedef struct SDL_TextEditingEvent +{ + Uint32 type; /**< ::SDL_TEXTEDITING */ + Uint32 timestamp; + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */ + Sint32 start; /**< The start cursor of selected editing text */ + Sint32 length; /**< The length of selected editing text */ +} SDL_TextEditingEvent; + + +#define SDL_TEXTINPUTEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text input event structure (event.text.*) + */ +typedef struct SDL_TextInputEvent +{ + Uint32 type; /**< ::SDL_TEXTINPUT */ + Uint32 timestamp; + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */ +} SDL_TextInputEvent; + +/** + * \brief Mouse motion event structure (event.motion.*) + */ +typedef struct SDL_MouseMotionEvent +{ + Uint32 type; /**< ::SDL_MOUSEMOTION */ + Uint32 timestamp; + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint32 state; /**< The current button state */ + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ + Sint32 xrel; /**< The relative motion in the X direction */ + Sint32 yrel; /**< The relative motion in the Y direction */ +} SDL_MouseMotionEvent; + +/** + * \brief Mouse button event structure (event.button.*) + */ +typedef struct SDL_MouseButtonEvent +{ + Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */ + Uint32 timestamp; + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint8 button; /**< The mouse button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */ + Uint8 padding1; + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ +} SDL_MouseButtonEvent; + +/** + * \brief Mouse wheel event structure (event.wheel.*) + */ +typedef struct SDL_MouseWheelEvent +{ + Uint32 type; /**< ::SDL_MOUSEWHEEL */ + Uint32 timestamp; + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ + Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ + Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ +} SDL_MouseWheelEvent; + +/** + * \brief Joystick axis motion event structure (event.jaxis.*) + */ +typedef struct SDL_JoyAxisEvent +{ + Uint32 type; /**< ::SDL_JOYAXISMOTION */ + Uint32 timestamp; + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The joystick axis index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_JoyAxisEvent; + +/** + * \brief Joystick trackball motion event structure (event.jball.*) + */ +typedef struct SDL_JoyBallEvent +{ + Uint32 type; /**< ::SDL_JOYBALLMOTION */ + Uint32 timestamp; + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 ball; /**< The joystick trackball index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 xrel; /**< The relative motion in the X direction */ + Sint16 yrel; /**< The relative motion in the Y direction */ +} SDL_JoyBallEvent; + +/** + * \brief Joystick hat position change event structure (event.jhat.*) + */ +typedef struct SDL_JoyHatEvent +{ + Uint32 type; /**< ::SDL_JOYHATMOTION */ + Uint32 timestamp; + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 hat; /**< The joystick hat index */ + Uint8 value; /**< The hat position value. + * \sa ::SDL_HAT_LEFTUP ::SDL_HAT_UP ::SDL_HAT_RIGHTUP + * \sa ::SDL_HAT_LEFT ::SDL_HAT_CENTERED ::SDL_HAT_RIGHT + * \sa ::SDL_HAT_LEFTDOWN ::SDL_HAT_DOWN ::SDL_HAT_RIGHTDOWN + * + * Note that zero means the POV is centered. + */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyHatEvent; + +/** + * \brief Joystick button event structure (event.jbutton.*) + */ +typedef struct SDL_JoyButtonEvent +{ + Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */ + Uint32 timestamp; + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The joystick button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyButtonEvent; + +/** + * \brief Joystick device event structure (event.jdevice.*) + */ +typedef struct SDL_JoyDeviceEvent +{ + Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ + Uint32 timestamp; + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ +} SDL_JoyDeviceEvent; + + +/** + * \brief Game controller axis motion event structure (event.caxis.*) + */ +typedef struct SDL_ControllerAxisEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */ + Uint32 timestamp; + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_ControllerAxisEvent; + + +/** + * \brief Game controller button event structure (event.cbutton.*) + */ +typedef struct SDL_ControllerButtonEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ + Uint32 timestamp; + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The controller button (SDL_GameControllerButton) */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_ControllerButtonEvent; + + +/** + * \brief Controller device event structure (event.cdevice.*) + */ +typedef struct SDL_ControllerDeviceEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ + Uint32 timestamp; + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ +} SDL_ControllerDeviceEvent; + +/** + * \brief Audio device event structure (event.adevice.*) + */ +typedef struct SDL_AudioDeviceEvent +{ + Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */ + Uint32 timestamp; + Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ + Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; +} SDL_AudioDeviceEvent; + + +/** + * \brief Touch finger event structure (event.tfinger.*) + */ +typedef struct SDL_TouchFingerEvent +{ + Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */ + Uint32 timestamp; + SDL_TouchID touchId; /**< The touch device id */ + SDL_FingerID fingerId; + float x; /**< Normalized in the range 0...1 */ + float y; /**< Normalized in the range 0...1 */ + float dx; /**< Normalized in the range -1...1 */ + float dy; /**< Normalized in the range -1...1 */ + float pressure; /**< Normalized in the range 0...1 */ +} SDL_TouchFingerEvent; + + +/** + * \brief Multiple Finger Gesture Event (event.mgesture.*) + */ +typedef struct SDL_MultiGestureEvent +{ + Uint32 type; /**< ::SDL_MULTIGESTURE */ + Uint32 timestamp; + SDL_TouchID touchId; /**< The touch device index */ + float dTheta; + float dDist; + float x; + float y; + Uint16 numFingers; + Uint16 padding; +} SDL_MultiGestureEvent; + + +/** + * \brief Dollar Gesture Event (event.dgesture.*) + */ +typedef struct SDL_DollarGestureEvent +{ + Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */ + Uint32 timestamp; + SDL_TouchID touchId; /**< The touch device id */ + SDL_GestureID gestureId; + Uint32 numFingers; + float error; + float x; /**< Normalized center of gesture */ + float y; /**< Normalized center of gesture */ +} SDL_DollarGestureEvent; + + +/** + * \brief An event used to request a file open by the system (event.drop.*) + * This event is enabled by default, you can disable it with SDL_EventState(). + * \note If this event is enabled, you must free the filename in the event. + */ +typedef struct SDL_DropEvent +{ + Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ + Uint32 timestamp; + char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ + Uint32 windowID; /**< The window that was dropped on, if any */ +} SDL_DropEvent; + + +/** + * \brief The "quit requested" event + */ +typedef struct SDL_QuitEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; +} SDL_QuitEvent; + +/** + * \brief OS Specific event + */ +typedef struct SDL_OSEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; +} SDL_OSEvent; + +/** + * \brief A user-defined event type (event.user.*) + */ +typedef struct SDL_UserEvent +{ + Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */ + Uint32 timestamp; + Uint32 windowID; /**< The associated window if any */ + Sint32 code; /**< User defined event code */ + void *data1; /**< User defined data pointer */ + void *data2; /**< User defined data pointer */ +} SDL_UserEvent; + + +struct SDL_SysWMmsg; +typedef struct SDL_SysWMmsg SDL_SysWMmsg; + +/** + * \brief A video driver dependent system event (event.syswm.*) + * This event is disabled by default, you can enable it with SDL_EventState() + * + * \note If you want to use this event, you should include SDL_syswm.h. + */ +typedef struct SDL_SysWMEvent +{ + Uint32 type; /**< ::SDL_SYSWMEVENT */ + Uint32 timestamp; + SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */ +} SDL_SysWMEvent; + +/** + * \brief General event structure + */ +typedef union SDL_Event +{ + Uint32 type; /**< Event type, shared with all events */ + SDL_CommonEvent common; /**< Common event data */ + SDL_WindowEvent window; /**< Window event data */ + SDL_KeyboardEvent key; /**< Keyboard event data */ + SDL_TextEditingEvent edit; /**< Text editing event data */ + SDL_TextInputEvent text; /**< Text input event data */ + SDL_MouseMotionEvent motion; /**< Mouse motion event data */ + SDL_MouseButtonEvent button; /**< Mouse button event data */ + SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ + SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ + SDL_JoyBallEvent jball; /**< Joystick ball event data */ + SDL_JoyHatEvent jhat; /**< Joystick hat event data */ + SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ + SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ + SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ + SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ + SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ + SDL_AudioDeviceEvent adevice; /**< Audio device event data */ + SDL_QuitEvent quit; /**< Quit request event data */ + SDL_UserEvent user; /**< Custom event data */ + SDL_SysWMEvent syswm; /**< System dependent window event data */ + SDL_TouchFingerEvent tfinger; /**< Touch finger event data */ + SDL_MultiGestureEvent mgesture; /**< Gesture event data */ + SDL_DollarGestureEvent dgesture; /**< Gesture event data */ + SDL_DropEvent drop; /**< Drag and drop event data */ + + /* This is necessary for ABI compatibility between Visual C++ and GCC + Visual C++ will respect the push pack pragma and use 52 bytes for + this structure, and GCC will use the alignment of the largest datatype + within the union, which is 8 bytes. + + So... we'll add padding to force the size to be 56 bytes for both. + */ + Uint8 padding[56]; +} SDL_Event; + + +/* Function prototypes */ + +/** + * Pumps the event loop, gathering events from the input devices. + * + * This function updates the event queue and internal input device state. + * + * This should only be run in the thread that sets the video mode. + */ +extern DECLSPEC void SDLCALL SDL_PumpEvents(void); + +/* @{ */ +typedef enum +{ + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT +} SDL_eventaction; + +/** + * Checks the event queue for messages and optionally returns them. + * + * If \c action is ::SDL_ADDEVENT, up to \c numevents events will be added to + * the back of the event queue. + * + * If \c action is ::SDL_PEEKEVENT, up to \c numevents events at the front + * of the event queue, within the specified minimum and maximum type, + * will be returned and will not be removed from the queue. + * + * If \c action is ::SDL_GETEVENT, up to \c numevents events at the front + * of the event queue, within the specified minimum and maximum type, + * will be returned and will be removed from the queue. + * + * \return The number of events actually stored, or -1 if there was an error. + * + * This function is thread-safe. + */ +extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, + SDL_eventaction action, + Uint32 minType, Uint32 maxType); +/* @} */ + +/** + * Checks to see if certain event types are in the event queue. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 type); +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType); + +/** + * This function clears events from the event queue + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + */ +extern DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type); +extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType); + +/** + * \brief Polls for currently pending events. + * + * \return 1 if there are any pending events, or 0 if there are none available. + * + * \param event If not NULL, the next event is removed from the queue and + * stored in that area. + */ +extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event); + +/** + * \brief Waits indefinitely for the next available event. + * + * \return 1, or 0 if there was an error while waiting for events. + * + * \param event If not NULL, the next event is removed from the queue and + * stored in that area. + */ +extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event); + +/** + * \brief Waits until the specified timeout (in milliseconds) for the next + * available event. + * + * \return 1, or 0 if there was an error while waiting for events. + * + * \param event If not NULL, the next event is removed from the queue and + * stored in that area. + * \param timeout The timeout (in milliseconds) to wait for next event. + */ +extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event, + int timeout); + +/** + * \brief Add an event to the event queue. + * + * \return 1 on success, 0 if the event was filtered, or -1 if the event queue + * was full or there was some other error. + */ +extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event * event); + +typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event); + +/** + * Sets up a filter to process all events before they change internal state and + * are posted to the internal event queue. + * + * The filter is prototyped as: + * \code + * int SDL_EventFilter(void *userdata, SDL_Event * event); + * \endcode + * + * If the filter returns 1, then the event will be added to the internal queue. + * If it returns 0, then the event will be dropped from the queue, but the + * internal state will still be updated. This allows selective filtering of + * dynamically arriving events. + * + * \warning Be very careful of what you do in the event filter function, as + * it may run in a different thread! + * + * There is one caveat when dealing with the ::SDL_QuitEvent event type. The + * event filter is only called when the window manager desires to close the + * application window. If the event filter returns 1, then the window will + * be closed, otherwise the window will remain open if possible. + * + * If the quit event is generated by an interrupt signal, it will bypass the + * internal queue and be delivered to the application at the next event poll. + */ +extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, + void *userdata); + +/** + * Return the current event filter - can be used to "chain" filters. + * If there is no event filter set, this function returns SDL_FALSE. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetEventFilter(SDL_EventFilter * filter, + void **userdata); + +/** + * Add a function which is called when an event is added to the queue. + */ +extern DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Remove an event watch function added with SDL_AddEventWatch() + */ +extern DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Run the filter function on the current event queue, removing any + * events for which the filter returns 0. + */ +extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, + void *userdata); + +/* @{ */ +#define SDL_QUERY -1 +#define SDL_IGNORE 0 +#define SDL_DISABLE 0 +#define SDL_ENABLE 1 + +/** + * This function allows you to set the state of processing certain events. + * - If \c state is set to ::SDL_IGNORE, that event will be automatically + * dropped from the event queue and will not event be filtered. + * - If \c state is set to ::SDL_ENABLE, that event will be processed + * normally. + * - If \c state is set to ::SDL_QUERY, SDL_EventState() will return the + * current processing state of the specified event. + */ +extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state); +/* @} */ +#define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY) + +/** + * This function allocates a set of user-defined events, and returns + * the beginning event number for that set of events. + * + * If there aren't enough user-defined events left, this function + * returns (Uint32)-1 + */ +extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_events_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_filesystem.h b/packages/sdl2.2.0.5/build/native/include/SDL_filesystem.h new file mode 100644 index 00000000..02999ed2 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_filesystem.h @@ -0,0 +1,136 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_filesystem.h + * + * \brief Include file for filesystem SDL API functions + */ + +#ifndef _SDL_filesystem_h +#define _SDL_filesystem_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Get the path where the application resides. + * + * Get the "base path". This is the directory where the application was run + * from, which is probably the installation directory, and may or may not + * be the process's current working directory. + * + * This returns an absolute path in UTF-8 encoding, and is guaranteed to + * end with a path separator ('\\' on Windows, '/' most other places). + * + * The pointer returned by this function is owned by you. Please call + * SDL_free() on the pointer when you are done with it, or it will be a + * memory leak. This is not necessarily a fast call, though, so you should + * call this once near startup and save the string if you need it. + * + * Some platforms can't determine the application's path, and on other + * platforms, this might be meaningless. In such cases, this function will + * return NULL. + * + * \return String of base dir in UTF-8 encoding, or NULL on error. + * + * \sa SDL_GetPrefPath + */ +extern DECLSPEC char *SDLCALL SDL_GetBasePath(void); + +/** + * \brief Get the user-and-app-specific path where files can be written. + * + * Get the "pref dir". This is meant to be where users can write personal + * files (preferences and save games, etc) that are specific to your + * application. This directory is unique per user, per application. + * + * This function will decide the appropriate location in the native filesystem, + * create the directory if necessary, and return a string of the absolute + * path to the directory in UTF-8 encoding. + * + * On Windows, the string might look like: + * "C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\" + * + * On Linux, the string might look like: + * "/home/bob/.local/share/My Program Name/" + * + * On Mac OS X, the string might look like: + * "/Users/bob/Library/Application Support/My Program Name/" + * + * (etc.) + * + * You specify the name of your organization (if it's not a real organization, + * your name or an Internet domain you own might do) and the name of your + * application. These should be untranslated proper names. + * + * Both the org and app strings may become part of a directory name, so + * please follow these rules: + * + * - Try to use the same org string (including case-sensitivity) for + * all your applications that use this function. + * - Always use a unique app string for each one, and make sure it never + * changes for an app once you've decided on it. + * - Unicode characters are legal, as long as it's UTF-8 encoded, but... + * - ...only use letters, numbers, and spaces. Avoid punctuation like + * "Game Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. + * + * This returns an absolute path in UTF-8 encoding, and is guaranteed to + * end with a path separator ('\\' on Windows, '/' most other places). + * + * The pointer returned by this function is owned by you. Please call + * SDL_free() on the pointer when you are done with it, or it will be a + * memory leak. This is not necessarily a fast call, though, so you should + * call this once near startup and save the string if you need it. + * + * You should assume the path returned by this function is the only safe + * place to write files (and that SDL_GetBasePath(), while it might be + * writable, or even the parent of the returned path, aren't where you + * should be writing things). + * + * Some platforms can't determine the pref path, and on other + * platforms, this might be meaningless. In such cases, this function will + * return NULL. + * + * \param org The name of your organization. + * \param app The name of your application. + * \return UTF-8 string of user dir in platform-dependent notation. NULL + * if there's a problem (creating directory failed, etc). + * + * \sa SDL_GetBasePath + */ +extern DECLSPEC char *SDLCALL SDL_GetPrefPath(const char *org, const char *app); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_filesystem_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_gamecontroller.h b/packages/sdl2.2.0.5/build/native/include/SDL_gamecontroller.h new file mode 100644 index 00000000..e67fd9fd --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_gamecontroller.h @@ -0,0 +1,323 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gamecontroller.h + * + * Include file for SDL game controller event handling + */ + +#ifndef _SDL_gamecontroller_h +#define _SDL_gamecontroller_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_rwops.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_gamecontroller.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_GAMECONTROLLER flag. This causes SDL to scan the system + * for game controllers, and load appropriate drivers. + * + * If you would like to receive controller updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/* The gamecontroller structure used to identify an SDL game controller */ +struct _SDL_GameController; +typedef struct _SDL_GameController SDL_GameController; + + +typedef enum +{ + SDL_CONTROLLER_BINDTYPE_NONE = 0, + SDL_CONTROLLER_BINDTYPE_BUTTON, + SDL_CONTROLLER_BINDTYPE_AXIS, + SDL_CONTROLLER_BINDTYPE_HAT +} SDL_GameControllerBindType; + +/** + * Get the SDL joystick layer binding for this controller button/axis mapping + */ +typedef struct SDL_GameControllerButtonBind +{ + SDL_GameControllerBindType bindType; + union + { + int button; + int axis; + struct { + int hat; + int hat_mask; + } hat; + } value; + +} SDL_GameControllerButtonBind; + + +/** + * To count the number of game controllers in the system for the following: + * int nJoysticks = SDL_NumJoysticks(); + * int nGameControllers = 0; + * for ( int i = 0; i < nJoysticks; i++ ) { + * if ( SDL_IsGameController(i) ) { + * nGameControllers++; + * } + * } + * + * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: + * guid,name,mappings + * + * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. + * Under Windows there is a reserved GUID of "xinput" that covers any XInput devices. + * The mapping format for joystick is: + * bX - a joystick button, index X + * hX.Y - hat X with value Y + * aX - axis X of the joystick + * Buttons can be used as a controller axis and vice versa. + * + * This string shows an example of a valid mapping for a controller + * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", + * + */ + +/** + * Load a set of mappings from a seekable SDL data stream (memory or file), filtered by the current SDL_GetPlatform() + * A community sourced database of controllers is available at https://raw.github.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt + * + * If \c freerw is non-zero, the stream will be closed after being read. + * + * \return number of mappings added, -1 on error + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMappingsFromRW( SDL_RWops * rw, int freerw ); + +/** + * Load a set of mappings from a file, filtered by the current SDL_GetPlatform() + * + * Convenience macro. + */ +#define SDL_GameControllerAddMappingsFromFile(file) SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Add or update an existing mapping configuration + * + * \return 1 if mapping is added, 0 if updated, -1 on error + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping( const char* mappingString ); + +/** + * Get a mapping string for a GUID + * + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid ); + +/** + * Get a mapping string for an open GameController + * + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMapping( SDL_GameController * gamecontroller ); + +/** + * Is the joystick on this index supported by the game controller interface? + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index); + + +/** + * Get the implementation dependent name of a game controller. + * This can be called before any controllers are opened. + * If no name can be found, this function returns NULL. + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); + +/** + * Open a game controller for use. + * The index passed as an argument refers to the N'th game controller on the system. + * This index is not the value which will identify this controller in future + * controller events. The joystick's instance id (::SDL_JoystickID) will be + * used there instead. + * + * \return A controller identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index); + +/** + * Return the SDL_GameController associated with an instance id. + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL_JoystickID joyid); + +/** + * Return the name for this currently opened controller + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller); + +/** + * Returns SDL_TRUE if the controller has been opened and currently connected, + * or SDL_FALSE if it has not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerGetAttached(SDL_GameController *gamecontroller); + +/** + * Get the underlying joystick object used by a controller + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller); + +/** + * Enable/disable controller event polling. + * + * If controller events are disabled, you must call SDL_GameControllerUpdate() + * yourself and check the state of the controller when you want controller + * information. + * + * The state can be one of ::SDL_QUERY, ::SDL_ENABLE or ::SDL_IGNORE. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerEventState(int state); + +/** + * Update the current state of the open game controllers. + * + * This is called automatically by the event loop if any game controller + * events are enabled. + */ +extern DECLSPEC void SDLCALL SDL_GameControllerUpdate(void); + + +/** + * The list of axes available from a controller + */ +typedef enum +{ + SDL_CONTROLLER_AXIS_INVALID = -1, + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_AXIS_RIGHTY, + SDL_CONTROLLER_AXIS_TRIGGERLEFT, + SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + SDL_CONTROLLER_AXIS_MAX +} SDL_GameControllerAxis; + +/** + * turn this string into a axis mapping + */ +extern DECLSPEC SDL_GameControllerAxis SDLCALL SDL_GameControllerGetAxisFromString(const char *pchString); + +/** + * turn this axis enum into a string mapping + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis); + +/** + * Get the SDL joystick layer binding for this controller button mapping + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, + SDL_GameControllerAxis axis); + +/** + * Get the current state of an axis control on a game controller. + * + * The state is a value ranging from -32768 to 32767 (except for the triggers, + * which range from 0 to 32767). + * + * The axis indices start at index 0. + */ +extern DECLSPEC Sint16 SDLCALL +SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, + SDL_GameControllerAxis axis); + +/** + * The list of buttons available from a controller + */ +typedef enum +{ + SDL_CONTROLLER_BUTTON_INVALID = -1, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_MAX +} SDL_GameControllerButton; + +/** + * turn this string into a button mapping + */ +extern DECLSPEC SDL_GameControllerButton SDLCALL SDL_GameControllerGetButtonFromString(const char *pchString); + +/** + * turn this button enum into a string mapping + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForButton(SDL_GameControllerButton button); + +/** + * Get the SDL joystick layer binding for this controller button mapping + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + + +/** + * Get the current state of a button on a game controller. + * + * The button indices start at index 0. + */ +extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Close a controller previously opened with SDL_GameControllerOpen(). + */ +extern DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController *gamecontroller); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_gamecontroller_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_gesture.h b/packages/sdl2.2.0.5/build/native/include/SDL_gesture.h new file mode 100644 index 00000000..3c29ca7a --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_gesture.h @@ -0,0 +1,87 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gesture.h + * + * Include file for SDL gesture event handling. + */ + +#ifndef _SDL_gesture_h +#define _SDL_gesture_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "SDL_touch.h" + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_GestureID; + +/* Function prototypes */ + +/** + * \brief Begin Recording a gesture on the specified touch, or all touches (-1) + * + * + */ +extern DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId); + + +/** + * \brief Save all currently loaded Dollar Gesture templates + * + * + */ +extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *dst); + +/** + * \brief Save a currently loaded Dollar Gesture template + * + * + */ +extern DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *dst); + + +/** + * \brief Load Dollar Gesture templates from a file + * + * + */ +extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_gesture_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_haptic.h b/packages/sdl2.2.0.5/build/native/include/SDL_haptic.h new file mode 100644 index 00000000..9421c8f1 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_haptic.h @@ -0,0 +1,1223 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_haptic.h + * + * \brief The SDL Haptic subsystem allows you to control haptic (force feedback) + * devices. + * + * The basic usage is as follows: + * - Initialize the Subsystem (::SDL_INIT_HAPTIC). + * - Open a Haptic Device. + * - SDL_HapticOpen() to open from index. + * - SDL_HapticOpenFromJoystick() to open from an existing joystick. + * - Create an effect (::SDL_HapticEffect). + * - Upload the effect with SDL_HapticNewEffect(). + * - Run the effect with SDL_HapticRunEffect(). + * - (optional) Free the effect with SDL_HapticDestroyEffect(). + * - Close the haptic device with SDL_HapticClose(). + * + * \par Simple rumble example: + * \code + * SDL_Haptic *haptic; + * + * // Open the device + * haptic = SDL_HapticOpen( 0 ); + * if (haptic == NULL) + * return -1; + * + * // Initialize simple rumble + * if (SDL_HapticRumbleInit( haptic ) != 0) + * return -1; + * + * // Play effect at 50% strength for 2 seconds + * if (SDL_HapticRumblePlay( haptic, 0.5, 2000 ) != 0) + * return -1; + * SDL_Delay( 2000 ); + * + * // Clean up + * SDL_HapticClose( haptic ); + * \endcode + * + * \par Complete example: + * \code + * int test_haptic( SDL_Joystick * joystick ) { + * SDL_Haptic *haptic; + * SDL_HapticEffect effect; + * int effect_id; + * + * // Open the device + * haptic = SDL_HapticOpenFromJoystick( joystick ); + * if (haptic == NULL) return -1; // Most likely joystick isn't haptic + * + * // See if it can do sine waves + * if ((SDL_HapticQuery(haptic) & SDL_HAPTIC_SINE)==0) { + * SDL_HapticClose(haptic); // No sine effect + * return -1; + * } + * + * // Create the effect + * memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default + * effect.type = SDL_HAPTIC_SINE; + * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates + * effect.periodic.direction.dir[0] = 18000; // Force comes from south + * effect.periodic.period = 1000; // 1000 ms + * effect.periodic.magnitude = 20000; // 20000/32767 strength + * effect.periodic.length = 5000; // 5 seconds long + * effect.periodic.attack_length = 1000; // Takes 1 second to get max strength + * effect.periodic.fade_length = 1000; // Takes 1 second to fade away + * + * // Upload the effect + * effect_id = SDL_HapticNewEffect( haptic, &effect ); + * + * // Test the effect + * SDL_HapticRunEffect( haptic, effect_id, 1 ); + * SDL_Delay( 5000); // Wait for the effect to finish + * + * // We destroy the effect, although closing the device also does this + * SDL_HapticDestroyEffect( haptic, effect_id ); + * + * // Close the device + * SDL_HapticClose(haptic); + * + * return 0; // Success + * } + * \endcode + */ + +#ifndef _SDL_haptic_h +#define _SDL_haptic_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \typedef SDL_Haptic + * + * \brief The haptic structure used to identify an SDL haptic. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticClose + */ +struct _SDL_Haptic; +typedef struct _SDL_Haptic SDL_Haptic; + + +/** + * \name Haptic features + * + * Different haptic features a device can have. + */ +/* @{ */ + +/** + * \name Haptic effects + */ +/* @{ */ + +/** + * \brief Constant effect supported. + * + * Constant haptic effect. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_CONSTANT (1u<<0) + +/** + * \brief Sine wave effect supported. + * + * Periodic haptic effect that simulates sine waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SINE (1u<<1) + +/** + * \brief Left/Right effect supported. + * + * Haptic effect for direct control over high/low frequency motors. + * + * \sa SDL_HapticLeftRight + * \warning this value was SDL_HAPTIC_SQUARE right before 2.0.0 shipped. Sorry, + * we ran out of bits, and this is important for XInput devices. + */ +#define SDL_HAPTIC_LEFTRIGHT (1u<<2) + +/* !!! FIXME: put this back when we have more bits in 2.1 */ +/* #define SDL_HAPTIC_SQUARE (1<<2) */ + +/** + * \brief Triangle wave effect supported. + * + * Periodic haptic effect that simulates triangular waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_TRIANGLE (1u<<3) + +/** + * \brief Sawtoothup wave effect supported. + * + * Periodic haptic effect that simulates saw tooth up waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SAWTOOTHUP (1u<<4) + +/** + * \brief Sawtoothdown wave effect supported. + * + * Periodic haptic effect that simulates saw tooth down waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SAWTOOTHDOWN (1u<<5) + +/** + * \brief Ramp effect supported. + * + * Ramp haptic effect. + * + * \sa SDL_HapticRamp + */ +#define SDL_HAPTIC_RAMP (1u<<6) + +/** + * \brief Spring effect supported - uses axes position. + * + * Condition haptic effect that simulates a spring. Effect is based on the + * axes position. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_SPRING (1u<<7) + +/** + * \brief Damper effect supported - uses axes velocity. + * + * Condition haptic effect that simulates dampening. Effect is based on the + * axes velocity. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_DAMPER (1u<<8) + +/** + * \brief Inertia effect supported - uses axes acceleration. + * + * Condition haptic effect that simulates inertia. Effect is based on the axes + * acceleration. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_INERTIA (1u<<9) + +/** + * \brief Friction effect supported - uses axes movement. + * + * Condition haptic effect that simulates friction. Effect is based on the + * axes movement. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_FRICTION (1u<<10) + +/** + * \brief Custom effect is supported. + * + * User defined custom haptic effect. + */ +#define SDL_HAPTIC_CUSTOM (1u<<11) + +/* @} *//* Haptic effects */ + +/* These last few are features the device has, not effects */ + +/** + * \brief Device can set global gain. + * + * Device supports setting the global gain. + * + * \sa SDL_HapticSetGain + */ +#define SDL_HAPTIC_GAIN (1u<<12) + +/** + * \brief Device can set autocenter. + * + * Device supports setting autocenter. + * + * \sa SDL_HapticSetAutocenter + */ +#define SDL_HAPTIC_AUTOCENTER (1u<<13) + +/** + * \brief Device can be queried for effect status. + * + * Device can be queried for effect status. + * + * \sa SDL_HapticGetEffectStatus + */ +#define SDL_HAPTIC_STATUS (1u<<14) + +/** + * \brief Device can be paused. + * + * \sa SDL_HapticPause + * \sa SDL_HapticUnpause + */ +#define SDL_HAPTIC_PAUSE (1u<<15) + + +/** + * \name Direction encodings + */ +/* @{ */ + +/** + * \brief Uses polar coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_POLAR 0 + +/** + * \brief Uses cartesian coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_CARTESIAN 1 + +/** + * \brief Uses spherical coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_SPHERICAL 2 + +/* @} *//* Direction encodings */ + +/* @} *//* Haptic features */ + +/* + * Misc defines. + */ + +/** + * \brief Used to play a device an infinite number of times. + * + * \sa SDL_HapticRunEffect + */ +#define SDL_HAPTIC_INFINITY 4294967295U + + +/** + * \brief Structure that represents a haptic direction. + * + * This is the direction where the force comes from, + * instead of the direction in which the force is exerted. + * + * Directions can be specified by: + * - ::SDL_HAPTIC_POLAR : Specified by polar coordinates. + * - ::SDL_HAPTIC_CARTESIAN : Specified by cartesian coordinates. + * - ::SDL_HAPTIC_SPHERICAL : Specified by spherical coordinates. + * + * Cardinal directions of the haptic device are relative to the positioning + * of the device. North is considered to be away from the user. + * + * The following diagram represents the cardinal directions: + * \verbatim + .--. + |__| .-------. + |=.| |.-----.| + |--| || || + | | |'-----'| + |__|~')_____(' + [ COMPUTER ] + + + North (0,-1) + ^ + | + | + (-1,0) West <----[ HAPTIC ]----> East (1,0) + | + | + v + South (0,1) + + + [ USER ] + \|||/ + (o o) + ---ooO-(_)-Ooo--- + \endverbatim + * + * If type is ::SDL_HAPTIC_POLAR, direction is encoded by hundredths of a + * degree starting north and turning clockwise. ::SDL_HAPTIC_POLAR only uses + * the first \c dir parameter. The cardinal directions would be: + * - North: 0 (0 degrees) + * - East: 9000 (90 degrees) + * - South: 18000 (180 degrees) + * - West: 27000 (270 degrees) + * + * If type is ::SDL_HAPTIC_CARTESIAN, direction is encoded by three positions + * (X axis, Y axis and Z axis (with 3 axes)). ::SDL_HAPTIC_CARTESIAN uses + * the first three \c dir parameters. The cardinal directions would be: + * - North: 0,-1, 0 + * - East: 1, 0, 0 + * - South: 0, 1, 0 + * - West: -1, 0, 0 + * + * The Z axis represents the height of the effect if supported, otherwise + * it's unused. In cartesian encoding (1, 2) would be the same as (2, 4), you + * can use any multiple you want, only the direction matters. + * + * If type is ::SDL_HAPTIC_SPHERICAL, direction is encoded by two rotations. + * The first two \c dir parameters are used. The \c dir parameters are as + * follows (all values are in hundredths of degrees): + * - Degrees from (1, 0) rotated towards (0, 1). + * - Degrees towards (0, 0, 1) (device needs at least 3 axes). + * + * + * Example of force coming from the south with all encodings (force coming + * from the south means the user will have to pull the stick to counteract): + * \code + * SDL_HapticDirection direction; + * + * // Cartesian directions + * direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding. + * direction.dir[0] = 0; // X position + * direction.dir[1] = 1; // Y position + * // Assuming the device has 2 axes, we don't need to specify third parameter. + * + * // Polar directions + * direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding. + * direction.dir[0] = 18000; // Polar only uses first parameter + * + * // Spherical coordinates + * direction.type = SDL_HAPTIC_SPHERICAL; // Spherical encoding + * direction.dir[0] = 9000; // Since we only have two axes we don't need more parameters. + * \endcode + * + * \sa SDL_HAPTIC_POLAR + * \sa SDL_HAPTIC_CARTESIAN + * \sa SDL_HAPTIC_SPHERICAL + * \sa SDL_HapticEffect + * \sa SDL_HapticNumAxes + */ +typedef struct SDL_HapticDirection +{ + Uint8 type; /**< The type of encoding. */ + Sint32 dir[3]; /**< The encoded direction. */ +} SDL_HapticDirection; + + +/** + * \brief A structure containing a template for a Constant effect. + * + * The struct is exclusive to the ::SDL_HAPTIC_CONSTANT effect. + * + * A constant effect applies a constant force in the specified direction + * to the joystick. + * + * \sa SDL_HAPTIC_CONSTANT + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticConstant +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_CONSTANT */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Constant */ + Sint16 level; /**< Strength of the constant effect. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticConstant; + +/** + * \brief A structure containing a template for a Periodic effect. + * + * The struct handles the following effects: + * - ::SDL_HAPTIC_SINE + * - ::SDL_HAPTIC_LEFTRIGHT + * - ::SDL_HAPTIC_TRIANGLE + * - ::SDL_HAPTIC_SAWTOOTHUP + * - ::SDL_HAPTIC_SAWTOOTHDOWN + * + * A periodic effect consists in a wave-shaped effect that repeats itself + * over time. The type determines the shape of the wave and the parameters + * determine the dimensions of the wave. + * + * Phase is given by hundredth of a degree meaning that giving the phase a value + * of 9000 will displace it 25% of its period. Here are sample values: + * - 0: No phase displacement. + * - 9000: Displaced 25% of its period. + * - 18000: Displaced 50% of its period. + * - 27000: Displaced 75% of its period. + * - 36000: Displaced 100% of its period, same as 0, but 0 is preferred. + * + * Examples: + * \verbatim + SDL_HAPTIC_SINE + __ __ __ __ + / \ / \ / \ / + / \__/ \__/ \__/ + + SDL_HAPTIC_SQUARE + __ __ __ __ __ + | | | | | | | | | | + | |__| |__| |__| |__| | + + SDL_HAPTIC_TRIANGLE + /\ /\ /\ /\ /\ + / \ / \ / \ / \ / + / \/ \/ \/ \/ + + SDL_HAPTIC_SAWTOOTHUP + /| /| /| /| /| /| /| + / | / | / | / | / | / | / | + / |/ |/ |/ |/ |/ |/ | + + SDL_HAPTIC_SAWTOOTHDOWN + \ |\ |\ |\ |\ |\ |\ | + \ | \ | \ | \ | \ | \ | \ | + \| \| \| \| \| \| \| + \endverbatim + * + * \sa SDL_HAPTIC_SINE + * \sa SDL_HAPTIC_LEFTRIGHT + * \sa SDL_HAPTIC_TRIANGLE + * \sa SDL_HAPTIC_SAWTOOTHUP + * \sa SDL_HAPTIC_SAWTOOTHDOWN + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticPeriodic +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_SINE, ::SDL_HAPTIC_LEFTRIGHT, + ::SDL_HAPTIC_TRIANGLE, ::SDL_HAPTIC_SAWTOOTHUP or + ::SDL_HAPTIC_SAWTOOTHDOWN */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Periodic */ + Uint16 period; /**< Period of the wave. */ + Sint16 magnitude; /**< Peak value; if negative, equivalent to 180 degrees extra phase shift. */ + Sint16 offset; /**< Mean value of the wave. */ + Uint16 phase; /**< Positive phase shift given by hundredth of a degree. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticPeriodic; + +/** + * \brief A structure containing a template for a Condition effect. + * + * The struct handles the following effects: + * - ::SDL_HAPTIC_SPRING: Effect based on axes position. + * - ::SDL_HAPTIC_DAMPER: Effect based on axes velocity. + * - ::SDL_HAPTIC_INERTIA: Effect based on axes acceleration. + * - ::SDL_HAPTIC_FRICTION: Effect based on axes movement. + * + * Direction is handled by condition internals instead of a direction member. + * The condition effect specific members have three parameters. The first + * refers to the X axis, the second refers to the Y axis and the third + * refers to the Z axis. The right terms refer to the positive side of the + * axis and the left terms refer to the negative side of the axis. Please + * refer to the ::SDL_HapticDirection diagram for which side is positive and + * which is negative. + * + * \sa SDL_HapticDirection + * \sa SDL_HAPTIC_SPRING + * \sa SDL_HAPTIC_DAMPER + * \sa SDL_HAPTIC_INERTIA + * \sa SDL_HAPTIC_FRICTION + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCondition +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_SPRING, ::SDL_HAPTIC_DAMPER, + ::SDL_HAPTIC_INERTIA or ::SDL_HAPTIC_FRICTION */ + SDL_HapticDirection direction; /**< Direction of the effect - Not used ATM. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Condition */ + Uint16 right_sat[3]; /**< Level when joystick is to the positive side; max 0xFFFF. */ + Uint16 left_sat[3]; /**< Level when joystick is to the negative side; max 0xFFFF. */ + Sint16 right_coeff[3]; /**< How fast to increase the force towards the positive side. */ + Sint16 left_coeff[3]; /**< How fast to increase the force towards the negative side. */ + Uint16 deadband[3]; /**< Size of the dead zone; max 0xFFFF: whole axis-range when 0-centered. */ + Sint16 center[3]; /**< Position of the dead zone. */ +} SDL_HapticCondition; + +/** + * \brief A structure containing a template for a Ramp effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_RAMP effect. + * + * The ramp effect starts at start strength and ends at end strength. + * It augments in linear fashion. If you use attack and fade with a ramp + * the effects get added to the ramp effect making the effect become + * quadratic instead of linear. + * + * \sa SDL_HAPTIC_RAMP + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticRamp +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_RAMP */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Ramp */ + Sint16 start; /**< Beginning strength level. */ + Sint16 end; /**< Ending strength level. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticRamp; + +/** + * \brief A structure containing a template for a Left/Right effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect. + * + * The Left/Right effect is used to explicitly control the large and small + * motors, commonly found in modern game controllers. One motor is high + * frequency, the other is low frequency. + * + * \sa SDL_HAPTIC_LEFTRIGHT + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticLeftRight +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_LEFTRIGHT */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + + /* Rumble */ + Uint16 large_magnitude; /**< Control of the large controller motor. */ + Uint16 small_magnitude; /**< Control of the small controller motor. */ +} SDL_HapticLeftRight; + +/** + * \brief A structure containing a template for the ::SDL_HAPTIC_CUSTOM effect. + * + * A custom force feedback effect is much like a periodic effect, where the + * application can define its exact shape. You will have to allocate the + * data yourself. Data should consist of channels * samples Uint16 samples. + * + * If channels is one, the effect is rotated using the defined direction. + * Otherwise it uses the samples in data for the different axes. + * + * \sa SDL_HAPTIC_CUSTOM + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCustom +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_CUSTOM */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Custom */ + Uint8 channels; /**< Axes to use, minimum of one. */ + Uint16 period; /**< Sample periods. */ + Uint16 samples; /**< Amount of samples. */ + Uint16 *data; /**< Should contain channels*samples items. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticCustom; + +/** + * \brief The generic template for any haptic effect. + * + * All values max at 32767 (0x7FFF). Signed values also can be negative. + * Time values unless specified otherwise are in milliseconds. + * + * You can also pass ::SDL_HAPTIC_INFINITY to length instead of a 0-32767 + * value. Neither delay, interval, attack_length nor fade_length support + * ::SDL_HAPTIC_INFINITY. Fade will also not be used since effect never ends. + * + * Additionally, the ::SDL_HAPTIC_RAMP effect does not support a duration of + * ::SDL_HAPTIC_INFINITY. + * + * Button triggers may not be supported on all devices, it is advised to not + * use them if possible. Buttons start at index 1 instead of index 0 like + * the joystick. + * + * If both attack_length and fade_level are 0, the envelope is not used, + * otherwise both values are used. + * + * Common parts: + * \code + * // Replay - All effects have this + * Uint32 length; // Duration of effect (ms). + * Uint16 delay; // Delay before starting effect. + * + * // Trigger - All effects have this + * Uint16 button; // Button that triggers effect. + * Uint16 interval; // How soon before effect can be triggered again. + * + * // Envelope - All effects except condition effects have this + * Uint16 attack_length; // Duration of the attack (ms). + * Uint16 attack_level; // Level at the start of the attack. + * Uint16 fade_length; // Duration of the fade out (ms). + * Uint16 fade_level; // Level at the end of the fade. + * \endcode + * + * + * Here we have an example of a constant effect evolution in time: + * \verbatim + Strength + ^ + | + | effect level --> _________________ + | / \ + | / \ + | / \ + | / \ + | attack_level --> | \ + | | | <--- fade_level + | + +--------------------------------------------------> Time + [--] [---] + attack_length fade_length + + [------------------][-----------------------] + delay length + \endverbatim + * + * Note either the attack_level or the fade_level may be above the actual + * effect level. + * + * \sa SDL_HapticConstant + * \sa SDL_HapticPeriodic + * \sa SDL_HapticCondition + * \sa SDL_HapticRamp + * \sa SDL_HapticLeftRight + * \sa SDL_HapticCustom + */ +typedef union SDL_HapticEffect +{ + /* Common for all force feedback effects */ + Uint16 type; /**< Effect type. */ + SDL_HapticConstant constant; /**< Constant effect. */ + SDL_HapticPeriodic periodic; /**< Periodic effect. */ + SDL_HapticCondition condition; /**< Condition effect. */ + SDL_HapticRamp ramp; /**< Ramp effect. */ + SDL_HapticLeftRight leftright; /**< Left/Right effect. */ + SDL_HapticCustom custom; /**< Custom effect. */ +} SDL_HapticEffect; + + +/* Function prototypes */ +/** + * \brief Count the number of haptic devices attached to the system. + * + * \return Number of haptic devices detected on the system. + */ +extern DECLSPEC int SDLCALL SDL_NumHaptics(void); + +/** + * \brief Get the implementation dependent name of a Haptic device. + * + * This can be called before any joysticks are opened. + * If no name can be found, this function returns NULL. + * + * \param device_index Index of the device to get its name. + * \return Name of the device or NULL on error. + * + * \sa SDL_NumHaptics + */ +extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index); + +/** + * \brief Opens a Haptic device for usage. + * + * The index passed as an argument refers to the N'th Haptic device on this + * system. + * + * When opening a haptic device, its gain will be set to maximum and + * autocenter will be disabled. To modify these values use + * SDL_HapticSetGain() and SDL_HapticSetAutocenter(). + * + * \param device_index Index of the device to open. + * \return Device identifier or NULL on error. + * + * \sa SDL_HapticIndex + * \sa SDL_HapticOpenFromMouse + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticClose + * \sa SDL_HapticSetGain + * \sa SDL_HapticSetAutocenter + * \sa SDL_HapticPause + * \sa SDL_HapticStopAll + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpen(int device_index); + +/** + * \brief Checks if the haptic device at index has been opened. + * + * \param device_index Index to check to see if it has been opened. + * \return 1 if it has been opened or 0 if it hasn't. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticIndex + */ +extern DECLSPEC int SDLCALL SDL_HapticOpened(int device_index); + +/** + * \brief Gets the index of a haptic device. + * + * \param haptic Haptic device to get the index of. + * \return The index of the haptic device or -1 on error. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpened + */ +extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic); + +/** + * \brief Gets whether or not the current mouse has haptic capabilities. + * + * \return SDL_TRUE if the mouse is haptic, SDL_FALSE if it isn't. + * + * \sa SDL_HapticOpenFromMouse + */ +extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void); + +/** + * \brief Tries to open a haptic device from the current mouse. + * + * \return The haptic device identifier or NULL on error. + * + * \sa SDL_MouseIsHaptic + * \sa SDL_HapticOpen + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromMouse(void); + +/** + * \brief Checks to see if a joystick has haptic features. + * + * \param joystick Joystick to test for haptic capabilities. + * \return 1 if the joystick is haptic, 0 if it isn't + * or -1 if an error ocurred. + * + * \sa SDL_HapticOpenFromJoystick + */ +extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick); + +/** + * \brief Opens a Haptic device for usage from a Joystick device. + * + * You must still close the haptic device separately. It will not be closed + * with the joystick. + * + * When opening from a joystick you should first close the haptic device before + * closing the joystick device. If not, on some implementations the haptic + * device will also get unallocated and you'll be unable to use force feedback + * on that device. + * + * \param joystick Joystick to create a haptic device from. + * \return A valid haptic device identifier on success or NULL on error. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticClose + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick * + joystick); + +/** + * \brief Closes a Haptic device previously opened with SDL_HapticOpen(). + * + * \param haptic Haptic device to close. + */ +extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic); + +/** + * \brief Returns the number of effects a haptic device can store. + * + * On some platforms this isn't fully supported, and therefore is an + * approximation. Always check to see if your created effect was actually + * created and do not rely solely on SDL_HapticNumEffects(). + * + * \param haptic The haptic device to query effect max. + * \return The number of effects the haptic device can store or + * -1 on error. + * + * \sa SDL_HapticNumEffectsPlaying + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic); + +/** + * \brief Returns the number of effects a haptic device can play at the same + * time. + * + * This is not supported on all platforms, but will always return a value. + * Added here for the sake of completeness. + * + * \param haptic The haptic device to query maximum playing effects. + * \return The number of effects the haptic device can play at the same time + * or -1 on error. + * + * \sa SDL_HapticNumEffects + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic); + +/** + * \brief Gets the haptic device's supported features in bitwise manner. + * + * Example: + * \code + * if (SDL_HapticQuery(haptic) & SDL_HAPTIC_CONSTANT) { + * printf("We have constant haptic effect!"); + * } + * \endcode + * + * \param haptic The haptic device to query. + * \return Haptic features in bitwise manner (OR'd). + * + * \sa SDL_HapticNumEffects + * \sa SDL_HapticEffectSupported + */ +extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic); + + +/** + * \brief Gets the number of haptic axes the device has. + * + * \sa SDL_HapticDirection + */ +extern DECLSPEC int SDLCALL SDL_HapticNumAxes(SDL_Haptic * haptic); + +/** + * \brief Checks to see if effect is supported by haptic. + * + * \param haptic Haptic device to check on. + * \param effect Effect to check to see if it is supported. + * \return SDL_TRUE if effect is supported, SDL_FALSE if it isn't or -1 on error. + * + * \sa SDL_HapticQuery + * \sa SDL_HapticNewEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic, + SDL_HapticEffect * + effect); + +/** + * \brief Creates a new haptic effect on the device. + * + * \param haptic Haptic device to create the effect on. + * \param effect Properties of the effect to create. + * \return The id of the effect on success or -1 on error. + * + * \sa SDL_HapticUpdateEffect + * \sa SDL_HapticRunEffect + * \sa SDL_HapticDestroyEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic, + SDL_HapticEffect * effect); + +/** + * \brief Updates the properties of an effect. + * + * Can be used dynamically, although behaviour when dynamically changing + * direction may be strange. Specifically the effect may reupload itself + * and start playing from the start. You cannot change the type either when + * running SDL_HapticUpdateEffect(). + * + * \param haptic Haptic device that has the effect. + * \param effect Effect to update. + * \param data New effect properties to use. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticNewEffect + * \sa SDL_HapticRunEffect + * \sa SDL_HapticDestroyEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic, + int effect, + SDL_HapticEffect * data); + +/** + * \brief Runs the haptic effect on its associated haptic device. + * + * If iterations are ::SDL_HAPTIC_INFINITY, it'll run the effect over and over + * repeating the envelope (attack and fade) every time. If you only want the + * effect to last forever, set ::SDL_HAPTIC_INFINITY in the effect's length + * parameter. + * + * \param haptic Haptic device to run the effect on. + * \param effect Identifier of the haptic effect to run. + * \param iterations Number of iterations to run the effect. Use + * ::SDL_HAPTIC_INFINITY for infinity. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticStopEffect + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticGetEffectStatus + */ +extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic, + int effect, + Uint32 iterations); + +/** + * \brief Stops the haptic effect on its associated haptic device. + * + * \param haptic Haptic device to stop the effect on. + * \param effect Identifier of the effect to stop. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticRunEffect + * \sa SDL_HapticDestroyEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic, + int effect); + +/** + * \brief Destroys a haptic effect on the device. + * + * This will stop the effect if it's running. Effects are automatically + * destroyed when the device is closed. + * + * \param haptic Device to destroy the effect on. + * \param effect Identifier of the effect to destroy. + * + * \sa SDL_HapticNewEffect + */ +extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic, + int effect); + +/** + * \brief Gets the status of the current effect on the haptic device. + * + * Device must support the ::SDL_HAPTIC_STATUS feature. + * + * \param haptic Haptic device to query the effect status on. + * \param effect Identifier of the effect to query its status. + * \return 0 if it isn't playing, 1 if it is playing or -1 on error. + * + * \sa SDL_HapticRunEffect + * \sa SDL_HapticStopEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic, + int effect); + +/** + * \brief Sets the global gain of the device. + * + * Device must support the ::SDL_HAPTIC_GAIN feature. + * + * The user may specify the maximum gain by setting the environment variable + * SDL_HAPTIC_GAIN_MAX which should be between 0 and 100. All calls to + * SDL_HapticSetGain() will scale linearly using SDL_HAPTIC_GAIN_MAX as the + * maximum. + * + * \param haptic Haptic device to set the gain on. + * \param gain Value to set the gain to, should be between 0 and 100. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain); + +/** + * \brief Sets the global autocenter of the device. + * + * Autocenter should be between 0 and 100. Setting it to 0 will disable + * autocentering. + * + * Device must support the ::SDL_HAPTIC_AUTOCENTER feature. + * + * \param haptic Haptic device to set autocentering on. + * \param autocenter Value to set autocenter to, 0 disables autocentering. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic, + int autocenter); + +/** + * \brief Pauses a haptic device. + * + * Device must support the ::SDL_HAPTIC_PAUSE feature. Call + * SDL_HapticUnpause() to resume playback. + * + * Do not modify the effects nor add new ones while the device is paused. + * That can cause all sorts of weird errors. + * + * \param haptic Haptic device to pause. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticUnpause + */ +extern DECLSPEC int SDLCALL SDL_HapticPause(SDL_Haptic * haptic); + +/** + * \brief Unpauses a haptic device. + * + * Call to unpause after SDL_HapticPause(). + * + * \param haptic Haptic device to unpause. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticPause + */ +extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic); + +/** + * \brief Stops all the currently playing effects on a haptic device. + * + * \param haptic Haptic device to stop. + * \return 0 on success or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic); + +/** + * \brief Checks to see if rumble is supported on a haptic device. + * + * \param haptic Haptic device to check to see if it supports rumble. + * \return SDL_TRUE if effect is supported, SDL_FALSE if it isn't or -1 on error. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic * haptic); + +/** + * \brief Initializes the haptic device for simple rumble playback. + * + * \param haptic Haptic device to initialize for simple rumble playback. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticRumbleSupported + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleInit(SDL_Haptic * haptic); + +/** + * \brief Runs simple rumble on a haptic device + * + * \param haptic Haptic device to play rumble effect on. + * \param strength Strength of the rumble to play as a 0-1 float value. + * \param length Length of the rumble to play in milliseconds. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticRumbleSupported + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumbleStop + */ +extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length ); + +/** + * \brief Stops the simple rumble on a haptic device. + * + * \param haptic Haptic to stop the rumble on. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticRumbleSupported + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_haptic_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_hints.h b/packages/sdl2.2.0.5/build/native/include/SDL_hints.h new file mode 100644 index 00000000..dd154643 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_hints.h @@ -0,0 +1,795 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_hints.h + * + * Official documentation for SDL configuration variables + * + * This file contains functions to set and get configuration hints, + * as well as listing each of them alphabetically. + * + * The convention for naming hints is SDL_HINT_X, where "SDL_X" is + * the environment variable that can be used to override the default. + * + * In general these hints are just that - they may or may not be + * supported or applicable on any given platform, but they provide + * a way for an application or user to give the library a hint as + * to how they would like the library to work. + */ + +#ifndef _SDL_hints_h +#define _SDL_hints_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface. + * + * SDL can try to accelerate the SDL screen surface by using streaming + * textures with a 3D rendering engine. This variable controls whether and + * how this is done. + * + * This variable can be set to the following values: + * "0" - Disable 3D acceleration + * "1" - Enable 3D acceleration, using the default renderer. + * "X" - Enable 3D acceleration, using X where X is one of the valid rendering drivers. (e.g. "direct3d", "opengl", etc.) + * + * By default SDL tries to make a best guess for each platform whether + * to use acceleration or not. + */ +#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION" + +/** + * \brief A variable specifying which render driver to use. + * + * If the application doesn't pick a specific renderer to use, this variable + * specifies the name of the preferred renderer. If the preferred renderer + * can't be initialized, the normal default renderer is used. + * + * This variable is case insensitive and can be set to the following values: + * "direct3d" + * "opengl" + * "opengles2" + * "opengles" + * "software" + * + * The default varies by platform, but it's the first one in the list that + * is available on the current platform. + */ +#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER" + +/** + * \brief A variable controlling whether the OpenGL render driver uses shaders if they are available. + * + * This variable can be set to the following values: + * "0" - Disable shaders + * "1" - Enable shaders + * + * By default shaders are used if OpenGL supports them. + */ +#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS" + +/** + * \brief A variable controlling whether the Direct3D device is initialized for thread-safe operations. + * + * This variable can be set to the following values: + * "0" - Thread-safety is not enabled (faster) + * "1" - Thread-safety is enabled + * + * By default the Direct3D device is created with thread-safety disabled. + */ +#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE "SDL_RENDER_DIRECT3D_THREADSAFE" + +/** + * \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer. + * + * This variable does not have any effect on the Direct3D 9 based renderer. + * + * This variable can be set to the following values: + * "0" - Disable Debug Layer use + * "1" - Enable Debug Layer use + * + * By default, SDL does not use Direct3D Debug Layer. + */ +#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG" + +/** + * \brief A variable controlling the scaling quality + * + * This variable can be set to the following values: + * "0" or "nearest" - Nearest pixel sampling + * "1" or "linear" - Linear filtering (supported by OpenGL and Direct3D) + * "2" or "best" - Currently this is the same as "linear" + * + * By default nearest pixel sampling is used + */ +#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY" + +/** + * \brief A variable controlling whether updates to the SDL screen surface should be synchronized with the vertical refresh, to avoid tearing. + * + * This variable can be set to the following values: + * "0" - Disable vsync + * "1" - Enable vsync + * + * By default SDL does not sync screen surface updates with vertical refresh. + */ +#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" + +/** + * \brief A variable controlling whether the screensaver is enabled. + * + * This variable can be set to the following values: + * "0" - Disable screensaver + * "1" - Enable screensaver + * + * By default SDL will disable the screensaver. + */ +#define SDL_HINT_VIDEO_ALLOW_SCREENSAVER "SDL_VIDEO_ALLOW_SCREENSAVER" + +/** + * \brief A variable controlling whether the X11 VidMode extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XVidMode + * "1" - Enable XVidMode + * + * By default SDL will use XVidMode if it is available. + */ +#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE" + +/** + * \brief A variable controlling whether the X11 Xinerama extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable Xinerama + * "1" - Enable Xinerama + * + * By default SDL will use Xinerama if it is available. + */ +#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA" + +/** + * \brief A variable controlling whether the X11 XRandR extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XRandR + * "1" - Enable XRandR + * + * By default SDL will not use XRandR because of window manager issues. + */ +#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR" + +/** + * \brief A variable controlling whether the X11 _NET_WM_PING protocol should be supported. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_PING + * "1" - Enable _NET_WM_PING + * + * By default SDL will use _NET_WM_PING, but for applications that know they + * will not always be able to respond to ping requests in a timely manner they can + * turn it off to avoid the window manager thinking the app is hung. + * The hint is checked in CreateWindow. + */ +#define SDL_HINT_VIDEO_X11_NET_WM_PING "SDL_VIDEO_X11_NET_WM_PING" + +/** + * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden + * + * This variable can be set to the following values: + * "0" - The window frame is not interactive when the cursor is hidden (no move, resize, etc) + * "1" - The window frame is interactive when the cursor is hidden + * + * By default SDL will allow interaction with the window frame when the cursor is hidden + */ +#define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" + +/** + * \brief A variable controlling whether the windows message loop is processed by SDL + * + * This variable can be set to the following values: + * "0" - The window message loop is not run + * "1" - The window message loop is processed in SDL_PumpEvents() + * + * By default SDL will process the windows message loop + */ +#define SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP "SDL_WINDOWS_ENABLE_MESSAGELOOP" + +/** + * \brief A variable controlling whether grabbing input grabs the keyboard + * + * This variable can be set to the following values: + * "0" - Grab will affect only the mouse + * "1" - Grab will affect mouse and keyboard + * + * By default SDL will not grab the keyboard so system shortcuts still work. + */ +#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" + +/** + * \brief A variable controlling whether relative mouse mode is implemented using mouse warping + * + * This variable can be set to the following values: + * "0" - Relative mouse mode uses raw input + * "1" - Relative mouse mode uses mouse warping + * + * By default SDL will use raw input for relative mouse mode + */ +#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP" + +/** + * \brief Allow mouse click events when clicking to focus an SDL window + * + * This variable can be set to the following values: + * "0" - Ignore mouse clicks that activate a window + * "1" - Generate events for mouse clicks that activate a window + * + * By default SDL will ignore mouse clicks that activate a window + */ +#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH" + +/** + * \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to true. + * + */ +#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" + +/** + * \brief A variable controlling whether the idle timer is disabled on iOS. + * + * When an iOS app does not receive touches for some time, the screen is + * dimmed automatically. For games where the accelerometer is the only input + * this is problematic. This functionality can be disabled by setting this + * hint. + * + * As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver() + * accomplish the same thing on iOS. They should be preferred over this hint. + * + * This variable can be set to the following values: + * "0" - Enable idle timer + * "1" - Disable idle timer + */ +#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED" + +/** + * \brief A variable controlling which orientations are allowed on iOS. + * + * In some circumstances it is necessary to be able to explicitly control + * which UI orientations are allowed. + * + * This variable is a space delimited list of the following values: + * "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown" + */ +#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" + +/** + * \brief A variable controlling whether controllers used with the Apple TV + * generate UI events. + * + * When UI events are generated by controller input, the app will be + * backgrounded when the Apple TV remote's menu button is pressed, and when the + * pause or B buttons on gamepads are pressed. + * + * More information about properly making use of controllers for the Apple TV + * can be found here: + * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/ + * + * This variable can be set to the following values: + * "0" - Controller input does not generate UI events (the default). + * "1" - Controller input generates UI events. + */ +#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS" + +/** + * \brief A variable controlling whether the Apple TV remote's joystick axes + * will automatically match the rotation of the remote. + * + * This variable can be set to the following values: + * "0" - Remote orientation does not affect joystick axes (the default). + * "1" - Joystick axes are based on the orientation of the remote. + */ +#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION" + +/** + * \brief A variable controlling whether the Android / iOS built-in + * accelerometer should be listed as a joystick device, rather than listing + * actual joysticks only. + * + * This variable can be set to the following values: + * "0" - List only real joysticks and accept input from them + * "1" - List real joysticks along with the accelerometer as if it were a 3 axis joystick (the default). + */ +#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK" + + +/** + * \brief A variable that lets you disable the detection and use of Xinput gamepad devices + * + * The variable can be set to the following values: + * "0" - Disable XInput detection (only uses direct input) + * "1" - Enable XInput detection (the default) + */ +#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED" + + +/** + * \brief A variable that causes SDL to use the old axis and button mapping for XInput devices. + * + * This hint is for backwards compatibility only and will be removed in SDL 2.1 + * + * The default value is "0". This hint must be set before SDL_Init() + */ +#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" + + +/** + * \brief A variable that lets you manually hint extra gamecontroller db entries + * + * The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG" + + +/** + * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background. + * + * The variable can be set to the following values: + * "0" - Disable joystick & gamecontroller input events when the + * application is in the background. + * "1" - Enable joystick & gamecontroller input events when the + * application is in the background. + * + * The default value is "0". This hint may be set at any time. + */ +#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" + + +/** + * \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it. + * This is a debugging aid for developers and not expected to be used by end users. The default is "1" + * + * This variable can be set to the following values: + * "0" - don't allow topmost + * "1" - allow topmost + */ +#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST" + + +/** + * \brief A variable that controls the timer resolution, in milliseconds. + * + * The higher resolution the timer, the more frequently the CPU services + * timer interrupts, and the more precise delays are, but this takes up + * power and CPU time. This hint is only used on Windows 7 and earlier. + * + * See this blog post for more information: + * http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/ + * + * If this variable is set to "0", the system timer resolution is not set. + * + * The default value is "1". This hint may be set at any time. + */ +#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION" + + + +/** +* \brief A string specifying SDL's threads stack size in bytes or "0" for the backend's default size +* +* Use this hint in case you need to set SDL's threads stack size to other than the default. +* This is specially useful if you build SDL against a non glibc libc library (such as musl) which +* provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses). +* Support for this hint is currently available only in the pthread, Windows, and PSP backend. +*/ +#define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE" + +/** + * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS) + */ +#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED" + +/** + * \brief A variable that determines whether ctrl+click should generate a right-click event on Mac + * + * If present, holding ctrl while left clicking will generate a right click + * event when on Mac. + */ +#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK" + +/** +* \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries +* +* SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It +* can use two different sets of binaries, those compiled by the user from source +* or those provided by the Chrome browser. In the later case, these binaries require +* that SDL loads a DLL providing the shader compiler. +* +* This variable can be set to the following values: +* "d3dcompiler_46.dll" - default, best for Vista or later. +* "d3dcompiler_43.dll" - for XP support. +* "none" - do not load any library, useful if you compiled ANGLE from source and included the compiler in your binaries. +* +*/ +#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" + +/** +* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). +* +* If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has +* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly +* created SDL_Window: +* +* 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is +* needed for example when sharing an OpenGL context across multiple windows. +* +* 2. The flag SDL_WINDOW_OPENGL will be set on the new window so it can be used for +* OpenGL rendering. +* +* This variable can be set to the following values: +* The address (as a string "%p") of the SDL_Window* that new windows created with SDL_CreateWindowFrom() should +* share a pixel format with. +*/ +#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT" + +/** + * \brief A URL to a WinRT app's privacy policy + * + * All network-enabled WinRT apps must make a privacy policy available to its + * users. On Windows 8, 8.1, and RT, Microsoft mandates that this policy be + * be available in the Windows Settings charm, as accessed from within the app. + * SDL provides code to add a URL-based link there, which can point to the app's + * privacy policy. + * + * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL + * before calling any SDL_Init() functions. The contents of the hint should + * be a valid URL. For example, "http://www.example.com". + * + * The default value is "", which will prevent SDL from adding a privacy policy + * link to the Settings charm. This hint should only be set during app init. + * + * The label text of an app's "Privacy Policy" link may be customized via another + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that on Windows Phone, Microsoft does not provide standard UI + * for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL + * will not get used on that platform. Network-enabled phone apps should display + * their privacy policy through some other, in-app means. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_URL "SDL_WINRT_PRIVACY_POLICY_URL" + +/** \brief Label text for a WinRT app's privacy policy link + * + * Network-enabled WinRT apps must include a privacy policy. On Windows 8, 8.1, and RT, + * Microsoft mandates that this policy be available via the Windows Settings charm. + * SDL provides code to add a link there, with its label text being set via the + * optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that a privacy policy's contents are not set via this hint. A separate + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the + * policy. + * + * The contents of this hint should be encoded as a UTF8 string. + * + * The default value is "Privacy Policy". This hint should only be set during app + * initialization, preferably before any calls to SDL_Init(). + * + * For additional information on linking to a privacy policy, see the documentation for + * SDL_HINT_WINRT_PRIVACY_POLICY_URL. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_WINRT_PRIVACY_POLICY_LABEL" + +/** \brief Allows back-button-press events on Windows Phone to be marked as handled + * + * Windows Phone devices typically feature a Back button. When pressed, + * the OS will emit back-button-press events, which apps are expected to + * handle in an appropriate manner. If apps do not explicitly mark these + * events as 'Handled', then the OS will invoke its default behavior for + * unhandled back-button-press events, which on Windows Phone 8 and 8.1 is to + * terminate the app (and attempt to switch to the previous app, or to the + * device's home screen). + * + * Setting the SDL_HINT_WINRT_HANDLE_BACK_BUTTON hint to "1" will cause SDL + * to mark back-button-press events as Handled, if and when one is sent to + * the app. + * + * Internally, Windows Phone sends back button events as parameters to + * special back-button-press callback functions. Apps that need to respond + * to back-button-press events are expected to register one or more + * callback functions for such, shortly after being launched (during the + * app's initialization phase). After the back button is pressed, the OS + * will invoke these callbacks. If the app's callback(s) do not explicitly + * mark the event as handled by the time they return, or if the app never + * registers one of these callback, the OS will consider the event + * un-handled, and it will apply its default back button behavior (terminate + * the app). + * + * SDL registers its own back-button-press callback with the Windows Phone + * OS. This callback will emit a pair of SDL key-press events (SDL_KEYDOWN + * and SDL_KEYUP), each with a scancode of SDL_SCANCODE_AC_BACK, after which + * it will check the contents of the hint, SDL_HINT_WINRT_HANDLE_BACK_BUTTON. + * If the hint's value is set to "1", the back button event's Handled + * property will get set to 'true'. If the hint's value is set to something + * else, or if it is unset, SDL will leave the event's Handled property + * alone. (By default, the OS sets this property to 'false', to note.) + * + * SDL apps can either set SDL_HINT_WINRT_HANDLE_BACK_BUTTON well before a + * back button is pressed, or can set it in direct-response to a back button + * being pressed. + * + * In order to get notified when a back button is pressed, SDL apps should + * register a callback function with SDL_AddEventWatch(), and have it listen + * for SDL_KEYDOWN events that have a scancode of SDL_SCANCODE_AC_BACK. + * (Alternatively, SDL_KEYUP events can be listened-for. Listening for + * either event type is suitable.) Any value of SDL_HINT_WINRT_HANDLE_BACK_BUTTON + * set by such a callback, will be applied to the OS' current + * back-button-press event. + * + * More details on back button behavior in Windows Phone apps can be found + * at the following page, on Microsoft's developer site: + * http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx + */ +#define SDL_HINT_WINRT_HANDLE_BACK_BUTTON "SDL_WINRT_HANDLE_BACK_BUTTON" + +/** + * \brief A variable that dictates policy for fullscreen Spaces on Mac OS X. + * + * This hint only applies to Mac OS X. + * + * The variable can be set to the following values: + * "0" - Disable Spaces support (FULLSCREEN_DESKTOP won't use them and + * SDL_WINDOW_RESIZABLE windows won't offer the "fullscreen" + * button on their titlebars). + * "1" - Enable Spaces support (FULLSCREEN_DESKTOP will use them and + * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen" + * button on their titlebars). + * + * The default value is "1". Spaces are disabled regardless of this hint if + * the OS isn't at least Mac OS X Lion (10.7). This hint must be set before + * any windows are created. + */ +#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES" + +/** +* \brief When set don't force the SDL app to become a foreground process +* +* This hint only applies to Mac OS X. +* +*/ +#define SDL_HINT_MAC_BACKGROUND_APP "SDL_MAC_BACKGROUND_APP" + +/** + * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION" + +/** + * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION" + +/** + * \brief A variable to control whether certain IMEs should handle text editing internally instead of sending SDL_TEXTEDITING events. + * + * The variable can be set to the following values: + * "0" - SDL_TEXTEDITING events are sent, and it is the application's + * responsibility to render the text from these events and + * differentiate it somehow from committed text. (default) + * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent, + * and text that is being composed will be rendered in its own UI. + */ +#define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING" + + /** + * \brief A variable to control whether mouse and touch events are to be treated together or separately + * + * The variable can be set to the following values: + * "0" - Mouse events will be handled as touch events, and touch will raise fake mouse + * events. This is the behaviour of SDL <= 2.0.3. (default) + * "1" - Mouse events will be handled separately from pure touch events. + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH" + +/** + * \brief override the binding element for keyboard inputs for Emscripten builds + * + * This hint only applies to the emscripten platform + * + * The variable can be one of + * "#window" - The javascript window object (this is the default) + * "#document" - The javascript document object + * "#screen" - the javascript window.screen object + * "#canvas" - the WebGL canvas element + * any other string without a leading # sign applies to the element on the page with that ID. + */ +#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT" + +/** + * \brief Tell SDL not to catch the SIGINT or SIGTERM signals. + * + * This hint only applies to Unix-like platforms. + * + * The variable can be set to the following values: + * "0" - SDL will install a SIGINT and SIGTERM handler, and when it + * catches a signal, convert it into an SDL_QUIT event. + * "1" - SDL will not install a signal handler at all. + */ +#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS" + +/** + * \brief Tell SDL not to generate window-close events for Alt+F4 on Windows. + * + * The variable can be set to the following values: + * "0" - SDL will generate a window-close event when it sees Alt+F4. + * "1" - SDL will only do normal key handling for Alt+F4. + */ +#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" + +/** + * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs. + * + * The bitmap header version 4 is required for proper alpha channel support and + * SDL will use it when required. Should this not be desired, this hint can + * force the use of the 40 byte header version which is supported everywhere. + * + * The variable can be set to the following values: + * "0" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file with an alpha mask. SDL will use the bitmap + * header version 4 and set the alpha mask accordingly. + * "1" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file without an alpha mask. The alpha channel data + * will be in the file, but applications are going to ignore it. + * + * The default value is "0". + */ +#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT" + +/** + * \brief Tell SDL not to name threads on Windows. + * + * The variable can be set to the following values: + * "0" - SDL will raise the 0x406D1388 Exception to name threads. + * This is the default behavior of SDL <= 2.0.4. (default) + * "1" - SDL will not raise this exception, and threads will be unnamed. + * For .NET languages this is required when running under a debugger. + */ +#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" + +/** + * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI + * + * Also known as Z-order. The variable can take a negative or positive value. + * The default is 10000. + */ +#define SDL_HINT_RPI_VIDEO_LAYER "SDL_RPI_VIDEO_LAYER" + +/** + * \brief An enumeration of hint priorities + */ +typedef enum +{ + SDL_HINT_DEFAULT, + SDL_HINT_NORMAL, + SDL_HINT_OVERRIDE +} SDL_HintPriority; + + +/** + * \brief Set a hint with a specific priority + * + * The priority controls the behavior when setting a hint that already + * has a value. Hints will replace existing hints of their priority and + * lower. Environment variables are considered to have override priority. + * + * \return SDL_TRUE if the hint was set, SDL_FALSE otherwise + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name, + const char *value, + SDL_HintPriority priority); + +/** + * \brief Set a hint with normal priority + * + * \return SDL_TRUE if the hint was set, SDL_FALSE otherwise + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name, + const char *value); + +/** + * \brief Get a hint + * + * \return The string value of a hint variable. + */ +extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); + +/** + * \brief Get a hint + * + * \return The boolean value of a hint variable. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value); + +/** + * \brief Add a function to watch a particular hint + * + * \param name The hint to watch + * \param callback The function to call when the hint value changes + * \param userdata A pointer to pass to the callback function + */ +typedef void (*SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue); +extern DECLSPEC void SDLCALL SDL_AddHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * \brief Remove a function watching a particular hint + * + * \param name The hint being watched + * \param callback The function being called when the hint value changes + * \param userdata A pointer being passed to the callback function + */ +extern DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * \brief Clear all hints + * + * This function is called during SDL_Quit() to free stored hints. + */ +extern DECLSPEC void SDLCALL SDL_ClearHints(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_hints_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_joystick.h b/packages/sdl2.2.0.5/build/native/include/SDL_joystick.h new file mode 100644 index 00000000..f5dbc948 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_joystick.h @@ -0,0 +1,273 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_joystick.h + * + * Include file for SDL joystick event handling + * + * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick + * behind a device_index changing as joysticks are plugged and unplugged. + * + * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted + * then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in. + * + * The term JoystickGUID is a stable 128-bit identifier for a joystick device that does not change over time, it identifies class of + * the device (a X360 wired controller for example). This identifier is platform dependent. + * + * + */ + +#ifndef _SDL_joystick_h +#define _SDL_joystick_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_joystick.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system + * for joysticks, and load appropriate drivers. + * + * If you would like to receive joystick updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/* The joystick structure used to identify an SDL joystick */ +struct _SDL_Joystick; +typedef struct _SDL_Joystick SDL_Joystick; + +/* A structure that encodes the stable unique id for a joystick device */ +typedef struct { + Uint8 data[16]; +} SDL_JoystickGUID; + +typedef Sint32 SDL_JoystickID; + +typedef enum +{ + SDL_JOYSTICK_POWER_UNKNOWN = -1, + SDL_JOYSTICK_POWER_EMPTY, + SDL_JOYSTICK_POWER_LOW, + SDL_JOYSTICK_POWER_MEDIUM, + SDL_JOYSTICK_POWER_FULL, + SDL_JOYSTICK_POWER_WIRED, + SDL_JOYSTICK_POWER_MAX +} SDL_JoystickPowerLevel; + +/* Function prototypes */ +/** + * Count the number of joysticks attached to the system right now + */ +extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); + +/** + * Get the implementation dependent name of a joystick. + * This can be called before any joysticks are opened. + * If no name can be found, this function returns NULL. + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); + +/** + * Open a joystick for use. + * The index passed as an argument refers to the N'th joystick on the system. + * This index is not the value which will identify this joystick in future + * joystick events. The joystick's instance id (::SDL_JoystickID) will be used + * there instead. + * + * \return A joystick identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index); + +/** + * Return the SDL_Joystick associated with an instance id. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID joyid); + +/** + * Return the name for this currently opened joystick. + * If no name can be found, this function returns NULL. + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick); + +/** + * Return the GUID for the joystick at this index + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetDeviceGUID(int device_index); + +/** + * Return the GUID for this opened joystick + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick * joystick); + +/** + * Return a string representation for this guid. pszGUID must point to at least 33 bytes + * (32 for the string plus a NULL terminator). + */ +extern DECLSPEC void SDLCALL SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID); + +/** + * convert a string into a joystick formatted guid + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUIDFromString(const char *pchGUID); + +/** + * Returns SDL_TRUE if the joystick has been opened and currently connected, or SDL_FALSE if it has not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick * joystick); + +/** + * Get the instance ID of an opened joystick or -1 if the joystick is invalid. + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick * joystick); + +/** + * Get the number of general axis controls on a joystick. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick * joystick); + +/** + * Get the number of trackballs on a joystick. + * + * Joystick trackballs have only relative motion events associated + * with them and their state cannot be polled. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick * joystick); + +/** + * Get the number of POV hats on a joystick. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick * joystick); + +/** + * Get the number of buttons on a joystick. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick * joystick); + +/** + * Update the current state of the open joysticks. + * + * This is called automatically by the event loop if any joystick + * events are enabled. + */ +extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); + +/** + * Enable/disable joystick event polling. + * + * If joystick events are disabled, you must call SDL_JoystickUpdate() + * yourself and check the state of the joystick when you want joystick + * information. + * + * The state can be one of ::SDL_QUERY, ::SDL_ENABLE or ::SDL_IGNORE. + */ +extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); + +/** + * Get the current state of an axis control on a joystick. + * + * The state is a value ranging from -32768 to 32767. + * + * The axis indices start at index 0. + */ +extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick * joystick, + int axis); + +/** + * \name Hat positions + */ +/* @{ */ +#define SDL_HAT_CENTERED 0x00 +#define SDL_HAT_UP 0x01 +#define SDL_HAT_RIGHT 0x02 +#define SDL_HAT_DOWN 0x04 +#define SDL_HAT_LEFT 0x08 +#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) +#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) +#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) +#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) +/* @} */ + +/** + * Get the current state of a POV hat on a joystick. + * + * The hat indices start at index 0. + * + * \return The return value is one of the following positions: + * - ::SDL_HAT_CENTERED + * - ::SDL_HAT_UP + * - ::SDL_HAT_RIGHT + * - ::SDL_HAT_DOWN + * - ::SDL_HAT_LEFT + * - ::SDL_HAT_RIGHTUP + * - ::SDL_HAT_RIGHTDOWN + * - ::SDL_HAT_LEFTUP + * - ::SDL_HAT_LEFTDOWN + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick * joystick, + int hat); + +/** + * Get the ball axis change since the last poll. + * + * \return 0, or -1 if you passed it invalid parameters. + * + * The ball indices start at index 0. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick * joystick, + int ball, int *dx, int *dy); + +/** + * Get the current state of a button on a joystick. + * + * The button indices start at index 0. + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick, + int button); + +/** + * Close a joystick previously opened with SDL_JoystickOpen(). + */ +extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick * joystick); + +/** + * Return the battery level of this joystick + */ +extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick * joystick); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_joystick_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_keyboard.h b/packages/sdl2.2.0.5/build/native/include/SDL_keyboard.h new file mode 100644 index 00000000..f80b6d2d --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_keyboard.h @@ -0,0 +1,217 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_keyboard.h + * + * Include file for SDL keyboard event handling + */ + +#ifndef _SDL_keyboard_h +#define _SDL_keyboard_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_keycode.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The SDL keysym structure, used in key events. + * + * \note If you are looking for translated character input, see the ::SDL_TEXTINPUT event. + */ +typedef struct SDL_Keysym +{ + SDL_Scancode scancode; /**< SDL physical key code - see ::SDL_Scancode for details */ + SDL_Keycode sym; /**< SDL virtual key code - see ::SDL_Keycode for details */ + Uint16 mod; /**< current key modifiers */ + Uint32 unused; +} SDL_Keysym; + +/* Function prototypes */ + +/** + * \brief Get the window which currently has keyboard focus. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetKeyboardFocus(void); + +/** + * \brief Get a snapshot of the current state of the keyboard. + * + * \param numkeys if non-NULL, receives the length of the returned array. + * + * \return An array of key states. Indexes into this array are obtained by using ::SDL_Scancode values. + * + * \b Example: + * \code + * const Uint8 *state = SDL_GetKeyboardState(NULL); + * if ( state[SDL_SCANCODE_RETURN] ) { + * printf(" is pressed.\n"); + * } + * \endcode + */ +extern DECLSPEC const Uint8 *SDLCALL SDL_GetKeyboardState(int *numkeys); + +/** + * \brief Get the current key modifier state for the keyboard. + */ +extern DECLSPEC SDL_Keymod SDLCALL SDL_GetModState(void); + +/** + * \brief Set the current key modifier state for the keyboard. + * + * \note This does not change the keyboard state, only the key modifier flags. + */ +extern DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate); + +/** + * \brief Get the key code corresponding to the given scancode according + * to the current keyboard layout. + * + * See ::SDL_Keycode for details. + * + * \sa SDL_GetKeyName() + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scancode); + +/** + * \brief Get the scancode corresponding to the given key code according to the + * current keyboard layout. + * + * See ::SDL_Scancode for details. + * + * \sa SDL_GetScancodeName() + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key); + +/** + * \brief Get a human-readable name for a scancode. + * + * \return A pointer to the name for the scancode. + * If the scancode doesn't have a name, this function returns + * an empty string (""). + * + * \sa SDL_Scancode + */ +extern DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_Scancode scancode); + +/** + * \brief Get a scancode from a human-readable name + * + * \return scancode, or SDL_SCANCODE_UNKNOWN if the name wasn't recognized + * + * \sa SDL_Scancode + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *name); + +/** + * \brief Get a human-readable name for a key. + * + * \return A pointer to a UTF-8 string that stays valid at least until the next + * call to this function. If you need it around any longer, you must + * copy it. If the key doesn't have a name, this function returns an + * empty string (""). + * + * \sa SDL_Keycode + */ +extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key); + +/** + * \brief Get a key code from a human-readable name + * + * \return key code, or SDLK_UNKNOWN if the name wasn't recognized + * + * \sa SDL_Keycode + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name); + +/** + * \brief Start accepting Unicode text input events. + * This function will show the on-screen keyboard if supported. + * + * \sa SDL_StopTextInput() + * \sa SDL_SetTextInputRect() + * \sa SDL_HasScreenKeyboardSupport() + */ +extern DECLSPEC void SDLCALL SDL_StartTextInput(void); + +/** + * \brief Return whether or not Unicode text input events are enabled. + * + * \sa SDL_StartTextInput() + * \sa SDL_StopTextInput() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputActive(void); + +/** + * \brief Stop receiving any text input events. + * This function will hide the on-screen keyboard if supported. + * + * \sa SDL_StartTextInput() + * \sa SDL_HasScreenKeyboardSupport() + */ +extern DECLSPEC void SDLCALL SDL_StopTextInput(void); + +/** + * \brief Set the rectangle used to type Unicode text inputs. + * This is used as a hint for IME and on-screen keyboard placement. + * + * \sa SDL_StartTextInput() + */ +extern DECLSPEC void SDLCALL SDL_SetTextInputRect(SDL_Rect *rect); + +/** + * \brief Returns whether the platform has some screen keyboard support. + * + * \return SDL_TRUE if some keyboard support is available else SDL_FALSE. + * + * \note Not all screen keyboard functions are supported on all platforms. + * + * \sa SDL_IsScreenKeyboardShown() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasScreenKeyboardSupport(void); + +/** + * \brief Returns whether the screen keyboard is shown for given window. + * + * \param window The window for which screen keyboard should be queried. + * + * \return SDL_TRUE if screen keyboard is shown else SDL_FALSE. + * + * \sa SDL_HasScreenKeyboardSupport() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_keyboard_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_keycode.h b/packages/sdl2.2.0.5/build/native/include/SDL_keycode.h new file mode 100644 index 00000000..7be96357 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_keycode.h @@ -0,0 +1,341 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_keycode.h + * + * Defines constants which identify keyboard keys and modifiers. + */ + +#ifndef _SDL_keycode_h +#define _SDL_keycode_h + +#include "SDL_stdinc.h" +#include "SDL_scancode.h" + +/** + * \brief The SDL virtual key representation. + * + * Values of this type are used to represent keyboard keys using the current + * layout of the keyboard. These values include Unicode values representing + * the unmodified character that would be generated by pressing the key, or + * an SDLK_* constant for those keys that do not generate characters. + */ +typedef Sint32 SDL_Keycode; + +#define SDLK_SCANCODE_MASK (1<<30) +#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK) + +enum +{ + SDLK_UNKNOWN = 0, + + SDLK_RETURN = '\r', + SDLK_ESCAPE = '\033', + SDLK_BACKSPACE = '\b', + SDLK_TAB = '\t', + SDLK_SPACE = ' ', + SDLK_EXCLAIM = '!', + SDLK_QUOTEDBL = '"', + SDLK_HASH = '#', + SDLK_PERCENT = '%', + SDLK_DOLLAR = '$', + SDLK_AMPERSAND = '&', + SDLK_QUOTE = '\'', + SDLK_LEFTPAREN = '(', + SDLK_RIGHTPAREN = ')', + SDLK_ASTERISK = '*', + SDLK_PLUS = '+', + SDLK_COMMA = ',', + SDLK_MINUS = '-', + SDLK_PERIOD = '.', + SDLK_SLASH = '/', + SDLK_0 = '0', + SDLK_1 = '1', + SDLK_2 = '2', + SDLK_3 = '3', + SDLK_4 = '4', + SDLK_5 = '5', + SDLK_6 = '6', + SDLK_7 = '7', + SDLK_8 = '8', + SDLK_9 = '9', + SDLK_COLON = ':', + SDLK_SEMICOLON = ';', + SDLK_LESS = '<', + SDLK_EQUALS = '=', + SDLK_GREATER = '>', + SDLK_QUESTION = '?', + SDLK_AT = '@', + /* + Skip uppercase letters + */ + SDLK_LEFTBRACKET = '[', + SDLK_BACKSLASH = '\\', + SDLK_RIGHTBRACKET = ']', + SDLK_CARET = '^', + SDLK_UNDERSCORE = '_', + SDLK_BACKQUOTE = '`', + SDLK_a = 'a', + SDLK_b = 'b', + SDLK_c = 'c', + SDLK_d = 'd', + SDLK_e = 'e', + SDLK_f = 'f', + SDLK_g = 'g', + SDLK_h = 'h', + SDLK_i = 'i', + SDLK_j = 'j', + SDLK_k = 'k', + SDLK_l = 'l', + SDLK_m = 'm', + SDLK_n = 'n', + SDLK_o = 'o', + SDLK_p = 'p', + SDLK_q = 'q', + SDLK_r = 'r', + SDLK_s = 's', + SDLK_t = 't', + SDLK_u = 'u', + SDLK_v = 'v', + SDLK_w = 'w', + SDLK_x = 'x', + SDLK_y = 'y', + SDLK_z = 'z', + + SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK), + + SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1), + SDLK_F2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2), + SDLK_F3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3), + SDLK_F4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4), + SDLK_F5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5), + SDLK_F6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6), + SDLK_F7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7), + SDLK_F8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8), + SDLK_F9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9), + SDLK_F10 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10), + SDLK_F11 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11), + SDLK_F12 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12), + + SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN), + SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK), + SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE), + SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT), + SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME), + SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP), + SDLK_DELETE = '\177', + SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END), + SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN), + SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT), + SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT), + SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN), + SDLK_UP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP), + + SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR), + SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE), + SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY), + SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS), + SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS), + SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER), + SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1), + SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2), + SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3), + SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4), + SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5), + SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6), + SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7), + SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8), + SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9), + SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0), + SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD), + + SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION), + SDLK_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER), + SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS), + SDLK_F13 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13), + SDLK_F14 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14), + SDLK_F15 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15), + SDLK_F16 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16), + SDLK_F17 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17), + SDLK_F18 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18), + SDLK_F19 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19), + SDLK_F20 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20), + SDLK_F21 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21), + SDLK_F22 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22), + SDLK_F23 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23), + SDLK_F24 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24), + SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE), + SDLK_HELP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP), + SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU), + SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT), + SDLK_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP), + SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN), + SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO), + SDLK_CUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT), + SDLK_COPY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY), + SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE), + SDLK_FIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND), + SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE), + SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP), + SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN), + SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA), + SDLK_KP_EQUALSAS400 = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400), + + SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE), + SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ), + SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL), + SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR), + SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR), + SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2), + SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR), + SDLK_OUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT), + SDLK_OPER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER), + SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN), + SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL), + SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL), + + SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00), + SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000), + SDLK_THOUSANDSSEPARATOR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR), + SDLK_DECIMALSEPARATOR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR), + SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT), + SDLK_CURRENCYSUBUNIT = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT), + SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN), + SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN), + SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE), + SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE), + SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB), + SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE), + SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A), + SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B), + SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C), + SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D), + SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E), + SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F), + SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR), + SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER), + SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT), + SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS), + SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER), + SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND), + SDLK_KP_DBLAMPERSAND = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND), + SDLK_KP_VERTICALBAR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR), + SDLK_KP_DBLVERTICALBAR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR), + SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON), + SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH), + SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE), + SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT), + SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM), + SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE), + SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL), + SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR), + SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD), + SDLK_KP_MEMSUBTRACT = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT), + SDLK_KP_MEMMULTIPLY = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY), + SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE), + SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS), + SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR), + SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY), + SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY), + SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL), + SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL), + SDLK_KP_HEXADECIMAL = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL), + + SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL), + SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT), + SDLK_LALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT), + SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI), + SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL), + SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT), + SDLK_RALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT), + SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI), + + SDLK_MODE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE), + + SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIONEXT), + SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPREV), + SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOSTOP), + SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY), + SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE), + SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT), + SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW), + SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL), + SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR), + SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER), + SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH), + SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME), + SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK), + SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD), + SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP), + SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH), + SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS), + + SDLK_BRIGHTNESSDOWN = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSDOWN), + SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSUP), + SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DISPLAYSWITCH), + SDLK_KBDILLUMTOGGLE = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMTOGGLE), + SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN), + SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP), + SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT), + SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP) +}; + +/** + * \brief Enumeration of valid key mods (possibly OR'd together). + */ +typedef enum +{ + KMOD_NONE = 0x0000, + KMOD_LSHIFT = 0x0001, + KMOD_RSHIFT = 0x0002, + KMOD_LCTRL = 0x0040, + KMOD_RCTRL = 0x0080, + KMOD_LALT = 0x0100, + KMOD_RALT = 0x0200, + KMOD_LGUI = 0x0400, + KMOD_RGUI = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_RESERVED = 0x8000 +} SDL_Keymod; + +#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL) +#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT) +#define KMOD_ALT (KMOD_LALT|KMOD_RALT) +#define KMOD_GUI (KMOD_LGUI|KMOD_RGUI) + +#endif /* _SDL_keycode_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_loadso.h b/packages/sdl2.2.0.5/build/native/include/SDL_loadso.h new file mode 100644 index 00000000..3d540bd7 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_loadso.h @@ -0,0 +1,81 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_loadso.h + * + * System dependent library loading routines + * + * Some things to keep in mind: + * \li These functions only work on C function names. Other languages may + * have name mangling and intrinsic language support that varies from + * compiler to compiler. + * \li Make sure you declare your function pointers with the same calling + * convention as the actual library function. Your code will crash + * mysteriously if you do not do this. + * \li Avoid namespace collisions. If you load a symbol from the library, + * it is not defined whether or not it goes into the global symbol + * namespace for the application. If it does and it conflicts with + * symbols in your code or other shared libraries, you will not get + * the results you expect. :) + */ + +#ifndef _SDL_loadso_h +#define _SDL_loadso_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This function dynamically loads a shared object and returns a pointer + * to the object handle (or NULL if there was an error). + * The 'sofile' parameter is a system dependent name of the object file. + */ +extern DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile); + +/** + * Given an object handle, this function looks up the address of the + * named function in the shared object and returns it. This address + * is no longer valid after calling SDL_UnloadObject(). + */ +extern DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle, + const char *name); + +/** + * Unload a shared object from memory. + */ +extern DECLSPEC void SDLCALL SDL_UnloadObject(void *handle); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_loadso_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_log.h b/packages/sdl2.2.0.5/build/native/include/SDL_log.h new file mode 100644 index 00000000..09be1104 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_log.h @@ -0,0 +1,211 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_log.h + * + * Simple log messages with categories and priorities. + * + * By default logs are quiet, but if you're debugging SDL you might want: + * + * SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN); + * + * Here's where the messages go on different platforms: + * Windows: debug output stream + * Android: log output + * Others: standard error output (stderr) + */ + +#ifndef _SDL_log_h +#define _SDL_log_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief The maximum size of a log message + * + * Messages longer than the maximum size will be truncated + */ +#define SDL_MAX_LOG_MESSAGE 4096 + +/** + * \brief The predefined log categories + * + * By default the application category is enabled at the INFO level, + * the assert category is enabled at the WARN level, test is enabled + * at the VERBOSE level and all other categories are enabled at the + * CRITICAL level. + */ +enum +{ + SDL_LOG_CATEGORY_APPLICATION, + SDL_LOG_CATEGORY_ERROR, + SDL_LOG_CATEGORY_ASSERT, + SDL_LOG_CATEGORY_SYSTEM, + SDL_LOG_CATEGORY_AUDIO, + SDL_LOG_CATEGORY_VIDEO, + SDL_LOG_CATEGORY_RENDER, + SDL_LOG_CATEGORY_INPUT, + SDL_LOG_CATEGORY_TEST, + + /* Reserved for future SDL library use */ + SDL_LOG_CATEGORY_RESERVED1, + SDL_LOG_CATEGORY_RESERVED2, + SDL_LOG_CATEGORY_RESERVED3, + SDL_LOG_CATEGORY_RESERVED4, + SDL_LOG_CATEGORY_RESERVED5, + SDL_LOG_CATEGORY_RESERVED6, + SDL_LOG_CATEGORY_RESERVED7, + SDL_LOG_CATEGORY_RESERVED8, + SDL_LOG_CATEGORY_RESERVED9, + SDL_LOG_CATEGORY_RESERVED10, + + /* Beyond this point is reserved for application use, e.g. + enum { + MYAPP_CATEGORY_AWESOME1 = SDL_LOG_CATEGORY_CUSTOM, + MYAPP_CATEGORY_AWESOME2, + MYAPP_CATEGORY_AWESOME3, + ... + }; + */ + SDL_LOG_CATEGORY_CUSTOM +}; + +/** + * \brief The predefined log priorities + */ +typedef enum +{ + SDL_LOG_PRIORITY_VERBOSE = 1, + SDL_LOG_PRIORITY_DEBUG, + SDL_LOG_PRIORITY_INFO, + SDL_LOG_PRIORITY_WARN, + SDL_LOG_PRIORITY_ERROR, + SDL_LOG_PRIORITY_CRITICAL, + SDL_NUM_LOG_PRIORITIES +} SDL_LogPriority; + + +/** + * \brief Set the priority of all log categories + */ +extern DECLSPEC void SDLCALL SDL_LogSetAllPriority(SDL_LogPriority priority); + +/** + * \brief Set the priority of a particular log category + */ +extern DECLSPEC void SDLCALL SDL_LogSetPriority(int category, + SDL_LogPriority priority); + +/** + * \brief Get the priority of a particular log category + */ +extern DECLSPEC SDL_LogPriority SDLCALL SDL_LogGetPriority(int category); + +/** + * \brief Reset all priorities to default. + * + * \note This is called in SDL_Quit(). + */ +extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void); + +/** + * \brief Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO + */ +extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_VERBOSE + */ +extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_DEBUG + */ +extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_INFO + */ +extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_WARN + */ +extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_ERROR + */ +extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_CRITICAL + */ +extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with the specified category and priority. + */ +extern DECLSPEC void SDLCALL SDL_LogMessage(int category, + SDL_LogPriority priority, + SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3); + +/** + * \brief Log a message with the specified category and priority. + */ +extern DECLSPEC void SDLCALL SDL_LogMessageV(int category, + SDL_LogPriority priority, + const char *fmt, va_list ap); + +/** + * \brief The prototype for the log output function + */ +typedef void (*SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message); + +/** + * \brief Get the current log output function. + */ +extern DECLSPEC void SDLCALL SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata); + +/** + * \brief This function allows you to replace the default log output + * function with one of your own. + */ +extern DECLSPEC void SDLCALL SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_log_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_main.h b/packages/sdl2.2.0.5/build/native/include/SDL_main.h new file mode 100644 index 00000000..67afea5e --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_main.h @@ -0,0 +1,161 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_main_h +#define _SDL_main_h + +#include "SDL_stdinc.h" + +/** + * \file SDL_main.h + * + * Redefine main() on some platforms so that it is called by SDL. + */ + +#ifndef SDL_MAIN_HANDLED +#if defined(__WIN32__) +/* On Windows SDL provides WinMain(), which parses the command line and passes + the arguments to your main function. + + If you provide your own WinMain(), you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#elif defined(__WINRT__) +/* On WinRT, SDL provides a main function that initializes CoreApplication, + creating an instance of IFrameworkView in the process. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. In non-XAML apps, the file, + src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled + into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be + called, with a pointer to the Direct3D-hosted XAML control passed in. +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__IPHONEOS__) +/* On iOS SDL provides a main function that creates an application delegate + and starts the iOS application run loop. + + See src/video/uikit/SDL_uikitappdelegate.m for more details. + */ +#define SDL_MAIN_NEEDED + +#elif defined(__ANDROID__) +/* On Android SDL provides a Java class in SDLActivity.java that is the + main activity entry point. + + See README-android.md for more details on extending that class. + */ +#define SDL_MAIN_NEEDED + +#elif defined(__NACL__) +/* On NACL we use ppapi_simple to set up the application helper code, + then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before + starting the user main function. + All user code is run in a separate thread by ppapi_simple, thus + allowing for blocking io to take place via nacl_io +*/ +#define SDL_MAIN_NEEDED + +#endif +#endif /* SDL_MAIN_HANDLED */ + +#ifdef __cplusplus +#define C_LINKAGE "C" +#else +#define C_LINKAGE +#endif /* __cplusplus */ + +/** + * \file SDL_main.h + * + * The application's main() function must be called with C linkage, + * and should be declared like this: + * \code + * #ifdef __cplusplus + * extern "C" + * #endif + * int main(int argc, char *argv[]) + * { + * } + * \endcode + */ + +#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) +#define main SDL_main +#endif + +/** + * The prototype for the application's main() function + */ +extern C_LINKAGE int SDL_main(int argc, char *argv[]); + + +#include "begin_code.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This is called by the real SDL main function to let the rest of the + * library know that initialization was done properly. + * + * Calling this yourself without knowing what you're doing can cause + * crashes and hard to diagnose problems with your application. + */ +extern DECLSPEC void SDLCALL SDL_SetMainReady(void); + +#ifdef __WIN32__ + +/** + * This can be called to set the application class at startup + */ +extern DECLSPEC int SDLCALL SDL_RegisterApp(char *name, Uint32 style, + void *hInst); +extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); + +#endif /* __WIN32__ */ + + +#ifdef __WINRT__ + +/** + * \brief Initializes and launches an SDL/WinRT application. + * + * \param mainFunction The SDL app's C-style main(). + * \param reserved Reserved for future use; should be NULL + * \return 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more + * information on the failure. + */ +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * reserved); + +#endif /* __WINRT__ */ + + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_main_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_messagebox.h b/packages/sdl2.2.0.5/build/native/include/SDL_messagebox.h new file mode 100644 index 00000000..ec370dbb --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_messagebox.h @@ -0,0 +1,144 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_messagebox_h +#define _SDL_messagebox_h + +#include "SDL_stdinc.h" +#include "SDL_video.h" /* For SDL_Window */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SDL_MessageBox flags. If supported will display warning icon, etc. + */ +typedef enum +{ + SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ + SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ + SDL_MESSAGEBOX_INFORMATION = 0x00000040 /**< informational dialog */ +} SDL_MessageBoxFlags; + +/** + * \brief Flags for SDL_MessageBoxButtonData. + */ +typedef enum +{ + SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, /**< Marks the default button when return is hit */ + SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002 /**< Marks the default button when escape is hit */ +} SDL_MessageBoxButtonFlags; + +/** + * \brief Individual button data. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxButtonFlags */ + int buttonid; /**< User defined button id (value returned via SDL_ShowMessageBox) */ + const char * text; /**< The UTF-8 button text */ +} SDL_MessageBoxButtonData; + +/** + * \brief RGB value used in a message box color scheme + */ +typedef struct +{ + Uint8 r, g, b; +} SDL_MessageBoxColor; + +typedef enum +{ + SDL_MESSAGEBOX_COLOR_BACKGROUND, + SDL_MESSAGEBOX_COLOR_TEXT, + SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, + SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, + SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, + SDL_MESSAGEBOX_COLOR_MAX +} SDL_MessageBoxColorType; + +/** + * \brief A set of colors to use for message box dialogs + */ +typedef struct +{ + SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]; +} SDL_MessageBoxColorScheme; + +/** + * \brief MessageBox structure containing title, text, window, etc. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxFlags */ + SDL_Window *window; /**< Parent window, can be NULL */ + const char *title; /**< UTF-8 title */ + const char *message; /**< UTF-8 message text */ + + int numbuttons; + const SDL_MessageBoxButtonData *buttons; + + const SDL_MessageBoxColorScheme *colorScheme; /**< ::SDL_MessageBoxColorScheme, can be NULL to use system settings */ +} SDL_MessageBoxData; + +/** + * \brief Create a modal message box. + * + * \param messageboxdata The SDL_MessageBoxData structure with title, text, etc. + * \param buttonid The pointer to which user id of hit button should be copied. + * + * \return -1 on error, otherwise 0 and buttonid contains user id of button + * hit or -1 if dialog was closed. + * + * \note This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or + * closes the messagebox. + */ +extern DECLSPEC int SDLCALL SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +/** + * \brief Create a simple modal message box + * + * \param flags ::SDL_MessageBoxFlags + * \param title UTF-8 title text + * \param message UTF-8 message text + * \param window The parent window, or NULL for no parent + * + * \return 0 on success, -1 on error + * + * \sa SDL_ShowMessageBox + */ +extern DECLSPEC int SDLCALL SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_messagebox_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_mouse.h b/packages/sdl2.2.0.5/build/native/include/SDL_mouse.h new file mode 100644 index 00000000..46f046d0 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_mouse.h @@ -0,0 +1,302 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_mouse.h + * + * Include file for SDL mouse event handling. + */ + +#ifndef _SDL_mouse_h +#define _SDL_mouse_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SDL_Cursor SDL_Cursor; /* Implementation dependent */ + +/** + * \brief Cursor types for SDL_CreateSystemCursor(). + */ +typedef enum +{ + SDL_SYSTEM_CURSOR_ARROW, /**< Arrow */ + SDL_SYSTEM_CURSOR_IBEAM, /**< I-beam */ + SDL_SYSTEM_CURSOR_WAIT, /**< Wait */ + SDL_SYSTEM_CURSOR_CROSSHAIR, /**< Crosshair */ + SDL_SYSTEM_CURSOR_WAITARROW, /**< Small wait cursor (or Wait if not available) */ + SDL_SYSTEM_CURSOR_SIZENWSE, /**< Double arrow pointing northwest and southeast */ + SDL_SYSTEM_CURSOR_SIZENESW, /**< Double arrow pointing northeast and southwest */ + SDL_SYSTEM_CURSOR_SIZEWE, /**< Double arrow pointing west and east */ + SDL_SYSTEM_CURSOR_SIZENS, /**< Double arrow pointing north and south */ + SDL_SYSTEM_CURSOR_SIZEALL, /**< Four pointed arrow pointing north, south, east, and west */ + SDL_SYSTEM_CURSOR_NO, /**< Slashed circle or crossbones */ + SDL_SYSTEM_CURSOR_HAND, /**< Hand */ + SDL_NUM_SYSTEM_CURSORS +} SDL_SystemCursor; + +/** + * \brief Scroll direction types for the Scroll event + */ +typedef enum +{ + SDL_MOUSEWHEEL_NORMAL, /**< The scroll direction is normal */ + SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */ +} SDL_MouseWheelDirection; + +/* Function prototypes */ + +/** + * \brief Get the window which currently has mouse focus. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void); + +/** + * \brief Retrieve the current state of the mouse. + * + * The current button state is returned as a button bitmask, which can + * be tested using the SDL_BUTTON(X) macros, and x and y are set to the + * mouse cursor position relative to the focus window for the currently + * selected mouse. You can pass NULL for either x or y. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y); + +/** + * \brief Get the current state of the mouse, in relation to the desktop + * + * This works just like SDL_GetMouseState(), but the coordinates will be + * reported relative to the top-left of the desktop. This can be useful if + * you need to track the mouse outside of a specific window and + * SDL_CaptureMouse() doesn't fit your needs. For example, it could be + * useful if you need to track the mouse while dragging a window, where + * coordinates relative to a window might not be in sync at all times. + * + * \note SDL_GetMouseState() returns the mouse position as SDL understands + * it from the last pump of the event queue. This function, however, + * queries the OS for the current mouse position, and as such, might + * be a slightly less efficient function. Unless you know what you're + * doing and have a good reason to use this function, you probably want + * SDL_GetMouseState() instead. + * + * \param x Returns the current X coord, relative to the desktop. Can be NULL. + * \param y Returns the current Y coord, relative to the desktop. Can be NULL. + * \return The current button state as a bitmask, which can be tested using the SDL_BUTTON(X) macros. + * + * \sa SDL_GetMouseState + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(int *x, int *y); + +/** + * \brief Retrieve the relative state of the mouse. + * + * The current button state is returned as a button bitmask, which can + * be tested using the SDL_BUTTON(X) macros, and x and y are set to the + * mouse deltas since the last call to SDL_GetRelativeMouseState(). + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); + +/** + * \brief Moves the mouse to the given position within the window. + * + * \param window The window to move the mouse into, or NULL for the current mouse focus + * \param x The x coordinate within the window + * \param y The y coordinate within the window + * + * \note This function generates a mouse motion event + */ +extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window, + int x, int y); + +/** + * \brief Moves the mouse to the given position in global screen space. + * + * \param x The x coordinate + * \param y The y coordinate + * \return 0 on success, -1 on error (usually: unsupported by a platform). + * + * \note This function generates a mouse motion event + */ +extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(int x, int y); + +/** + * \brief Set relative mouse mode. + * + * \param enabled Whether or not to enable relative mode + * + * \return 0 on success, or -1 if relative mode is not supported. + * + * While the mouse is in relative mode, the cursor is hidden, and the + * driver will try to report continuous motion in the current window. + * Only relative motion events will be delivered, the mouse position + * will not change. + * + * \note This function will flush any pending mouse motion. + * + * \sa SDL_GetRelativeMouseMode() + */ +extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled); + +/** + * \brief Capture the mouse, to track input outside an SDL window. + * + * \param enabled Whether or not to enable capturing + * + * Capturing enables your app to obtain mouse events globally, instead of + * just within your window. Not all video targets support this function. + * When capturing is enabled, the current window will get all mouse events, + * but unlike relative mode, no change is made to the cursor and it is + * not restrained to your window. + * + * This function may also deny mouse input to other windows--both those in + * your application and others on the system--so you should use this + * function sparingly, and in small bursts. For example, you might want to + * track the mouse while the user is dragging something, until the user + * releases a mouse button. It is not recommended that you capture the mouse + * for long periods of time, such as the entire time your app is running. + * + * While captured, mouse events still report coordinates relative to the + * current (foreground) window, but those coordinates may be outside the + * bounds of the window (including negative values). Capturing is only + * allowed for the foreground window. If the window loses focus while + * capturing, the capture will be disabled automatically. + * + * While capturing is enabled, the current window will have the + * SDL_WINDOW_MOUSE_CAPTURE flag set. + * + * \return 0 on success, or -1 if not supported. + */ +extern DECLSPEC int SDLCALL SDL_CaptureMouse(SDL_bool enabled); + +/** + * \brief Query whether relative mouse mode is enabled. + * + * \sa SDL_SetRelativeMouseMode() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void); + +/** + * \brief Create a cursor, using the specified bitmap data and + * mask (in MSB format). + * + * The cursor width must be a multiple of 8 bits. + * + * The cursor is created in black and white according to the following: + *
+ * + * + * + * + * + *
data mask resulting pixel on screen
0 1 White
1 1 Black
0 0 Transparent
1 0 Inverted color if possible, black + * if not.
+ * + * \sa SDL_FreeCursor() + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateCursor(const Uint8 * data, + const Uint8 * mask, + int w, int h, int hot_x, + int hot_y); + +/** + * \brief Create a color cursor. + * + * \sa SDL_FreeCursor() + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface, + int hot_x, + int hot_y); + +/** + * \brief Create a system cursor. + * + * \sa SDL_FreeCursor() + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id); + +/** + * \brief Set the active cursor. + */ +extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor * cursor); + +/** + * \brief Return the active cursor. + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void); + +/** + * \brief Return the default cursor. + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void); + +/** + * \brief Frees a cursor created with SDL_CreateCursor() or similar functions. + * + * \sa SDL_CreateCursor() + * \sa SDL_CreateColorCursor() + * \sa SDL_CreateSystemCursor() + */ +extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor); + +/** + * \brief Toggle whether or not the cursor is shown. + * + * \param toggle 1 to show the cursor, 0 to hide it, -1 to query the current + * state. + * + * \return 1 if the cursor is shown, or 0 if the cursor is hidden. + */ +extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); + +/** + * Used as a mask when testing buttons in buttonstate. + * - Button 1: Left mouse button + * - Button 2: Middle mouse button + * - Button 3: Right mouse button + */ +#define SDL_BUTTON(X) (1 << ((X)-1)) +#define SDL_BUTTON_LEFT 1 +#define SDL_BUTTON_MIDDLE 2 +#define SDL_BUTTON_RIGHT 3 +#define SDL_BUTTON_X1 4 +#define SDL_BUTTON_X2 5 +#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) +#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) +#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) +#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1) +#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2) + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_mouse_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_mutex.h b/packages/sdl2.2.0.5/build/native/include/SDL_mutex.h new file mode 100644 index 00000000..b7e39734 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_mutex.h @@ -0,0 +1,251 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_mutex_h +#define _SDL_mutex_h + +/** + * \file SDL_mutex.h + * + * Functions to provide thread synchronization primitives. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Synchronization functions which can time out return this value + * if they time out. + */ +#define SDL_MUTEX_TIMEDOUT 1 + +/** + * This is the timeout value which corresponds to never time out. + */ +#define SDL_MUTEX_MAXWAIT (~(Uint32)0) + + +/** + * \name Mutex functions + */ +/* @{ */ + +/* The SDL mutex structure, defined in SDL_sysmutex.c */ +struct SDL_mutex; +typedef struct SDL_mutex SDL_mutex; + +/** + * Create a mutex, initialized unlocked. + */ +extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void); + +/** + * Lock the mutex. + * + * \return 0, or -1 on error. + */ +#define SDL_mutexP(m) SDL_LockMutex(m) +extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex); + +/** + * Try to lock the mutex + * + * \return 0, SDL_MUTEX_TIMEDOUT, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex); + +/** + * Unlock the mutex. + * + * \return 0, or -1 on error. + * + * \warning It is an error to unlock a mutex that has not been locked by + * the current thread, and doing so results in undefined behavior. + */ +#define SDL_mutexV(m) SDL_UnlockMutex(m) +extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex); + +/** + * Destroy a mutex. + */ +extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex * mutex); + +/* @} *//* Mutex functions */ + + +/** + * \name Semaphore functions + */ +/* @{ */ + +/* The SDL semaphore structure, defined in SDL_syssem.c */ +struct SDL_semaphore; +typedef struct SDL_semaphore SDL_sem; + +/** + * Create a semaphore, initialized with value, returns NULL on failure. + */ +extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value); + +/** + * Destroy a semaphore. + */ +extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem); + +/** + * This function suspends the calling thread until the semaphore pointed + * to by \c sem has a positive count. It then atomically decreases the + * semaphore count. + */ +extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem); + +/** + * Non-blocking variant of SDL_SemWait(). + * + * \return 0 if the wait succeeds, ::SDL_MUTEX_TIMEDOUT if the wait would + * block, and -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); + +/** + * Variant of SDL_SemWait() with a timeout in milliseconds. + * + * \return 0 if the wait succeeds, ::SDL_MUTEX_TIMEDOUT if the wait does not + * succeed in the allotted time, and -1 on error. + * + * \warning On some platforms this function is implemented by looping with a + * delay of 1 ms, and so should be avoided if possible. + */ +extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem * sem, Uint32 ms); + +/** + * Atomically increases the semaphore's count (not blocking). + * + * \return 0, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem); + +/** + * Returns the current count of the semaphore. + */ +extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem * sem); + +/* @} *//* Semaphore functions */ + + +/** + * \name Condition variable functions + */ +/* @{ */ + +/* The SDL condition variable structure, defined in SDL_syscond.c */ +struct SDL_cond; +typedef struct SDL_cond SDL_cond; + +/** + * Create a condition variable. + * + * Typical use of condition variables: + * + * Thread A: + * SDL_LockMutex(lock); + * while ( ! condition ) { + * SDL_CondWait(cond, lock); + * } + * SDL_UnlockMutex(lock); + * + * Thread B: + * SDL_LockMutex(lock); + * ... + * condition = true; + * ... + * SDL_CondSignal(cond); + * SDL_UnlockMutex(lock); + * + * There is some discussion whether to signal the condition variable + * with the mutex locked or not. There is some potential performance + * benefit to unlocking first on some platforms, but there are some + * potential race conditions depending on how your code is structured. + * + * In general it's safer to signal the condition variable while the + * mutex is locked. + */ +extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void); + +/** + * Destroy a condition variable. + */ +extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond); + +/** + * Restart one of the threads that are waiting on the condition variable. + * + * \return 0 or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond); + +/** + * Restart all threads that are waiting on the condition variable. + * + * \return 0 or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond); + +/** + * Wait on the condition variable, unlocking the provided mutex. + * + * \warning The mutex must be locked before entering this function! + * + * The mutex is re-locked once the condition variable is signaled. + * + * \return 0 when it is signaled, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex); + +/** + * Waits for at most \c ms milliseconds, and returns 0 if the condition + * variable is signaled, ::SDL_MUTEX_TIMEDOUT if the condition is not + * signaled in the allotted time, and -1 on error. + * + * \warning On some platforms this function is implemented by looping with a + * delay of 1 ms, and so should be avoided if possible. + */ +extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond, + SDL_mutex * mutex, Uint32 ms); + +/* @} *//* Condition variable functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_mutex_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_name.h b/packages/sdl2.2.0.5/build/native/include/SDL_name.h new file mode 100644 index 00000000..06cd4a5e --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_name.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDLname_h_ +#define _SDLname_h_ + +#if defined(__STDC__) || defined(__cplusplus) +#define NeedFunctionPrototypes 1 +#endif + +#define SDL_NAME(X) SDL_##X + +#endif /* _SDLname_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_opengl.h b/packages/sdl2.2.0.5/build/native/include/SDL_opengl.h new file mode 100644 index 00000000..780919bc --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_opengl.h @@ -0,0 +1,2176 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengl.h + * + * This is a simple file to encapsulate the OpenGL API headers. + */ + +/** + * \def NO_SDL_GLEXT + * + * Define this if you have your own version of glext.h and want to disable the + * version included in SDL_opengl.h. + */ + +#ifndef _SDL_opengl_h +#define _SDL_opengl_h + +#include "SDL_config.h" + +#ifndef __IPHONEOS__ /* No OpenGL on iOS. */ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * 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. + */ + + +#ifndef __gl_h_ +#define __gl_h_ + +#if defined(USE_MGL_NAMESPACE) +#include "gl_mangle.h" +#endif + + +/********************************************************************** + * Begin system-specific stuff. + */ + +#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) +#define __WIN32__ +#endif + +#if defined(__WIN32__) && !defined(__CYGWIN__) +# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */ +# define GLAPI __declspec(dllexport) +# elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ +# define GLAPI __declspec(dllimport) +# else /* for use with static link lib build of Win32 edition only */ +# define GLAPI extern +# endif /* _STATIC_MESA support */ +# if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */ +# define GLAPIENTRY +# else +# define GLAPIENTRY __stdcall +# endif +#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ +# define GLAPI extern +# define GLAPIENTRY __stdcall +#elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define GLAPI __attribute__((visibility("default"))) +# define GLAPIENTRY +#endif /* WIN32 && !CYGWIN */ + +/* + * WINDOWS: Include windows.h here to define APIENTRY. + * It is also useful when applications include this file by + * including only glut.h, since glut.h depends on windows.h. + * Applications needing to include windows.h with parms other + * than "WIN32_LEAN_AND_MEAN" may include windows.h before + * glut.h or gl.h. + */ +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#ifndef GLAPI +#define GLAPI extern +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifndef APIENTRY +#define APIENTRY GLAPIENTRY +#endif + +/* "P" suffix to be used for a pointer to a function */ +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#ifndef GLAPIENTRYP +#define GLAPIENTRYP GLAPIENTRY * +#endif + +#if defined(PRAGMA_EXPORT_SUPPORTED) +#pragma export on +#endif + +/* + * End system-specific stuff. + **********************************************************************/ + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define GL_VERSION_1_1 1 +#define GL_VERSION_1_2 1 +#define GL_VERSION_1_3 1 +#define GL_ARB_imaging 1 + + +/* + * Datatypes + */ +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef signed char GLbyte; /* 1-byte signed */ +typedef short GLshort; /* 2-byte signed */ +typedef int GLint; /* 4-byte signed */ +typedef unsigned char GLubyte; /* 1-byte unsigned */ +typedef unsigned short GLushort; /* 2-byte unsigned */ +typedef unsigned int GLuint; /* 4-byte unsigned */ +typedef int GLsizei; /* 4-byte signed */ +typedef float GLfloat; /* single precision float */ +typedef float GLclampf; /* single precision float in [0,1] */ +typedef double GLdouble; /* double precision float */ +typedef double GLclampd; /* double precision float in [0,1] */ + + + +/* + * Constants + */ + +/* Boolean values */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* Data types */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A + +/* Primitives */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 + +/* Vertex Arrays */ +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D + +/* Matrix Mode */ +#define GL_MATRIX_MODE 0x0BA0 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 + +/* Points */ +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_RANGE 0x0B12 + +/* Lines */ +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 + +/* Polygons */ +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 + +/* Display Lists */ +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_LIST_MODE 0x0B30 + +/* Depth buffer */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_COMPONENT 0x1902 + +/* Lighting */ +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_SHININESS 0x1601 +#define GL_EMISSION 0x1600 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_SHADE_MODEL 0x0B54 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_NORMALIZE 0x0BA1 + +/* User clipping planes */ +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 + +/* Accumulation buffer */ +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_ACCUM 0x0100 +#define GL_ADD 0x0104 +#define GL_LOAD 0x0101 +#define GL_MULT 0x0103 +#define GL_RETURN 0x0102 + +/* Alpha testing */ +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALPHA_TEST_FUNC 0x0BC1 + +/* Blending */ +#define GL_BLEND 0x0BE2 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_DST 0x0BE0 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 + +/* Render Mode */ +#define GL_FEEDBACK 0x1C01 +#define GL_RENDER 0x1C00 +#define GL_SELECT 0x1C02 + +/* Feedback */ +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 + +/* Selection */ +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 + +/* Fog */ +#define GL_FOG 0x0B60 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_COLOR 0x0B66 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_LINEAR 0x2601 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 + +/* Logic Ops */ +#define GL_LOGIC_OP 0x0BF1 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_CLEAR 0x1500 +#define GL_SET 0x150F +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_NOOP 0x1505 +#define GL_INVERT 0x150A +#define GL_AND 0x1501 +#define GL_NAND 0x150E +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_XOR 0x1506 +#define GL_EQUIV 0x1509 +#define GL_AND_REVERSE 0x1502 +#define GL_AND_INVERTED 0x1504 +#define GL_OR_REVERSE 0x150B +#define GL_OR_INVERTED 0x150D + +/* Stencil */ +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_INDEX 0x1901 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 + +/* Buffers, Pixel Drawing/Reading */ +#define GL_NONE 0 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +/*GL_FRONT 0x0404 */ +/*GL_BACK 0x0405 */ +/*GL_FRONT_AND_BACK 0x0408 */ +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_COLOR_INDEX 0x1900 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_ALPHA_BITS 0x0D55 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_INDEX_BITS 0x0D51 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_READ_BUFFER 0x0C02 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_BITMAP 0x1A00 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_DITHER 0x0BD0 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 + +/* Implementation limits */ +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B + +/* Gets */ +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_MODE 0x0C30 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_RENDER_MODE 0x0C40 +#define GL_RGBA_MODE 0x0C31 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_VIEWPORT 0x0BA2 + +/* Evaluators */ +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 + +/* Hints */ +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* Scissor box */ +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 + +/* Pixel Mode / Transfer */ +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 + +/* Texture mapping */ +#define GL_TEXTURE_ENV 0x2300 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_LINEAR 0x2400 +#define GL_EYE_PLANE 0x2502 +#define GL_SPHERE_MAP 0x2402 +#define GL_DECAL 0x2101 +#define GL_MODULATE 0x2100 +#define GL_NEAREST 0x2600 +#define GL_REPEAT 0x2901 +#define GL_CLAMP 0x2900 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 + +/* Utility */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* Errors */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 + +/* glPush/PopAttrib bits */ +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000FFFFF + + +/* OpenGL 1.1 */ +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF + + + +/* + * Miscellaneous + */ + +GLAPI void GLAPIENTRY glClearIndex( GLfloat c ); + +GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); + +GLAPI void GLAPIENTRY glClear( GLbitfield mask ); + +GLAPI void GLAPIENTRY glIndexMask( GLuint mask ); + +GLAPI void GLAPIENTRY glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); + +GLAPI void GLAPIENTRY glAlphaFunc( GLenum func, GLclampf ref ); + +GLAPI void GLAPIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor ); + +GLAPI void GLAPIENTRY glLogicOp( GLenum opcode ); + +GLAPI void GLAPIENTRY glCullFace( GLenum mode ); + +GLAPI void GLAPIENTRY glFrontFace( GLenum mode ); + +GLAPI void GLAPIENTRY glPointSize( GLfloat size ); + +GLAPI void GLAPIENTRY glLineWidth( GLfloat width ); + +GLAPI void GLAPIENTRY glLineStipple( GLint factor, GLushort pattern ); + +GLAPI void GLAPIENTRY glPolygonMode( GLenum face, GLenum mode ); + +GLAPI void GLAPIENTRY glPolygonOffset( GLfloat factor, GLfloat units ); + +GLAPI void GLAPIENTRY glPolygonStipple( const GLubyte *mask ); + +GLAPI void GLAPIENTRY glGetPolygonStipple( GLubyte *mask ); + +GLAPI void GLAPIENTRY glEdgeFlag( GLboolean flag ); + +GLAPI void GLAPIENTRY glEdgeFlagv( const GLboolean *flag ); + +GLAPI void GLAPIENTRY glScissor( GLint x, GLint y, GLsizei width, GLsizei height); + +GLAPI void GLAPIENTRY glClipPlane( GLenum plane, const GLdouble *equation ); + +GLAPI void GLAPIENTRY glGetClipPlane( GLenum plane, GLdouble *equation ); + +GLAPI void GLAPIENTRY glDrawBuffer( GLenum mode ); + +GLAPI void GLAPIENTRY glReadBuffer( GLenum mode ); + +GLAPI void GLAPIENTRY glEnable( GLenum cap ); + +GLAPI void GLAPIENTRY glDisable( GLenum cap ); + +GLAPI GLboolean GLAPIENTRY glIsEnabled( GLenum cap ); + + +GLAPI void GLAPIENTRY glEnableClientState( GLenum cap ); /* 1.1 */ + +GLAPI void GLAPIENTRY glDisableClientState( GLenum cap ); /* 1.1 */ + + +GLAPI void GLAPIENTRY glGetBooleanv( GLenum pname, GLboolean *params ); + +GLAPI void GLAPIENTRY glGetDoublev( GLenum pname, GLdouble *params ); + +GLAPI void GLAPIENTRY glGetFloatv( GLenum pname, GLfloat *params ); + +GLAPI void GLAPIENTRY glGetIntegerv( GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glPushAttrib( GLbitfield mask ); + +GLAPI void GLAPIENTRY glPopAttrib( void ); + + +GLAPI void GLAPIENTRY glPushClientAttrib( GLbitfield mask ); /* 1.1 */ + +GLAPI void GLAPIENTRY glPopClientAttrib( void ); /* 1.1 */ + + +GLAPI GLint GLAPIENTRY glRenderMode( GLenum mode ); + +GLAPI GLenum GLAPIENTRY glGetError( void ); + +GLAPI const GLubyte * GLAPIENTRY glGetString( GLenum name ); + +GLAPI void GLAPIENTRY glFinish( void ); + +GLAPI void GLAPIENTRY glFlush( void ); + +GLAPI void GLAPIENTRY glHint( GLenum target, GLenum mode ); + + +/* + * Depth Buffer + */ + +GLAPI void GLAPIENTRY glClearDepth( GLclampd depth ); + +GLAPI void GLAPIENTRY glDepthFunc( GLenum func ); + +GLAPI void GLAPIENTRY glDepthMask( GLboolean flag ); + +GLAPI void GLAPIENTRY glDepthRange( GLclampd near_val, GLclampd far_val ); + + +/* + * Accumulation Buffer + */ + +GLAPI void GLAPIENTRY glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); + +GLAPI void GLAPIENTRY glAccum( GLenum op, GLfloat value ); + + +/* + * Transformation + */ + +GLAPI void GLAPIENTRY glMatrixMode( GLenum mode ); + +GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble near_val, GLdouble far_val ); + +GLAPI void GLAPIENTRY glFrustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble near_val, GLdouble far_val ); + +GLAPI void GLAPIENTRY glViewport( GLint x, GLint y, + GLsizei width, GLsizei height ); + +GLAPI void GLAPIENTRY glPushMatrix( void ); + +GLAPI void GLAPIENTRY glPopMatrix( void ); + +GLAPI void GLAPIENTRY glLoadIdentity( void ); + +GLAPI void GLAPIENTRY glLoadMatrixd( const GLdouble *m ); +GLAPI void GLAPIENTRY glLoadMatrixf( const GLfloat *m ); + +GLAPI void GLAPIENTRY glMultMatrixd( const GLdouble *m ); +GLAPI void GLAPIENTRY glMultMatrixf( const GLfloat *m ); + +GLAPI void GLAPIENTRY glRotated( GLdouble angle, + GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glRotatef( GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ); + +GLAPI void GLAPIENTRY glScaled( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z ); + +GLAPI void GLAPIENTRY glTranslated( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z ); + + +/* + * Display Lists + */ + +GLAPI GLboolean GLAPIENTRY glIsList( GLuint list ); + +GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range ); + +GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range ); + +GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode ); + +GLAPI void GLAPIENTRY glEndList( void ); + +GLAPI void GLAPIENTRY glCallList( GLuint list ); + +GLAPI void GLAPIENTRY glCallLists( GLsizei n, GLenum type, + const GLvoid *lists ); + +GLAPI void GLAPIENTRY glListBase( GLuint base ); + + +/* + * Drawing Functions + */ + +GLAPI void GLAPIENTRY glBegin( GLenum mode ); + +GLAPI void GLAPIENTRY glEnd( void ); + + +GLAPI void GLAPIENTRY glVertex2d( GLdouble x, GLdouble y ); +GLAPI void GLAPIENTRY glVertex2f( GLfloat x, GLfloat y ); +GLAPI void GLAPIENTRY glVertex2i( GLint x, GLint y ); +GLAPI void GLAPIENTRY glVertex2s( GLshort x, GLshort y ); + +GLAPI void GLAPIENTRY glVertex3d( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glVertex3f( GLfloat x, GLfloat y, GLfloat z ); +GLAPI void GLAPIENTRY glVertex3i( GLint x, GLint y, GLint z ); +GLAPI void GLAPIENTRY glVertex3s( GLshort x, GLshort y, GLshort z ); + +GLAPI void GLAPIENTRY glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); +GLAPI void GLAPIENTRY glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); +GLAPI void GLAPIENTRY glVertex4i( GLint x, GLint y, GLint z, GLint w ); +GLAPI void GLAPIENTRY glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w ); + +GLAPI void GLAPIENTRY glVertex2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex2iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glVertex3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex3iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glVertex4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex4iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glNormal3b( GLbyte nx, GLbyte ny, GLbyte nz ); +GLAPI void GLAPIENTRY glNormal3d( GLdouble nx, GLdouble ny, GLdouble nz ); +GLAPI void GLAPIENTRY glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz ); +GLAPI void GLAPIENTRY glNormal3i( GLint nx, GLint ny, GLint nz ); +GLAPI void GLAPIENTRY glNormal3s( GLshort nx, GLshort ny, GLshort nz ); + +GLAPI void GLAPIENTRY glNormal3bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glNormal3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glNormal3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glNormal3iv( const GLint *v ); +GLAPI void GLAPIENTRY glNormal3sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glIndexd( GLdouble c ); +GLAPI void GLAPIENTRY glIndexf( GLfloat c ); +GLAPI void GLAPIENTRY glIndexi( GLint c ); +GLAPI void GLAPIENTRY glIndexs( GLshort c ); +GLAPI void GLAPIENTRY glIndexub( GLubyte c ); /* 1.1 */ + +GLAPI void GLAPIENTRY glIndexdv( const GLdouble *c ); +GLAPI void GLAPIENTRY glIndexfv( const GLfloat *c ); +GLAPI void GLAPIENTRY glIndexiv( const GLint *c ); +GLAPI void GLAPIENTRY glIndexsv( const GLshort *c ); +GLAPI void GLAPIENTRY glIndexubv( const GLubyte *c ); /* 1.1 */ + +GLAPI void GLAPIENTRY glColor3b( GLbyte red, GLbyte green, GLbyte blue ); +GLAPI void GLAPIENTRY glColor3d( GLdouble red, GLdouble green, GLdouble blue ); +GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue ); +GLAPI void GLAPIENTRY glColor3i( GLint red, GLint green, GLint blue ); +GLAPI void GLAPIENTRY glColor3s( GLshort red, GLshort green, GLshort blue ); +GLAPI void GLAPIENTRY glColor3ub( GLubyte red, GLubyte green, GLubyte blue ); +GLAPI void GLAPIENTRY glColor3ui( GLuint red, GLuint green, GLuint blue ); +GLAPI void GLAPIENTRY glColor3us( GLushort red, GLushort green, GLushort blue ); + +GLAPI void GLAPIENTRY glColor4b( GLbyte red, GLbyte green, + GLbyte blue, GLbyte alpha ); +GLAPI void GLAPIENTRY glColor4d( GLdouble red, GLdouble green, + GLdouble blue, GLdouble alpha ); +GLAPI void GLAPIENTRY glColor4f( GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ); +GLAPI void GLAPIENTRY glColor4i( GLint red, GLint green, + GLint blue, GLint alpha ); +GLAPI void GLAPIENTRY glColor4s( GLshort red, GLshort green, + GLshort blue, GLshort alpha ); +GLAPI void GLAPIENTRY glColor4ub( GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha ); +GLAPI void GLAPIENTRY glColor4ui( GLuint red, GLuint green, + GLuint blue, GLuint alpha ); +GLAPI void GLAPIENTRY glColor4us( GLushort red, GLushort green, + GLushort blue, GLushort alpha ); + + +GLAPI void GLAPIENTRY glColor3bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glColor3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glColor3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glColor3iv( const GLint *v ); +GLAPI void GLAPIENTRY glColor3sv( const GLshort *v ); +GLAPI void GLAPIENTRY glColor3ubv( const GLubyte *v ); +GLAPI void GLAPIENTRY glColor3uiv( const GLuint *v ); +GLAPI void GLAPIENTRY glColor3usv( const GLushort *v ); + +GLAPI void GLAPIENTRY glColor4bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glColor4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glColor4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glColor4iv( const GLint *v ); +GLAPI void GLAPIENTRY glColor4sv( const GLshort *v ); +GLAPI void GLAPIENTRY glColor4ubv( const GLubyte *v ); +GLAPI void GLAPIENTRY glColor4uiv( const GLuint *v ); +GLAPI void GLAPIENTRY glColor4usv( const GLushort *v ); + + +GLAPI void GLAPIENTRY glTexCoord1d( GLdouble s ); +GLAPI void GLAPIENTRY glTexCoord1f( GLfloat s ); +GLAPI void GLAPIENTRY glTexCoord1i( GLint s ); +GLAPI void GLAPIENTRY glTexCoord1s( GLshort s ); + +GLAPI void GLAPIENTRY glTexCoord2d( GLdouble s, GLdouble t ); +GLAPI void GLAPIENTRY glTexCoord2f( GLfloat s, GLfloat t ); +GLAPI void GLAPIENTRY glTexCoord2i( GLint s, GLint t ); +GLAPI void GLAPIENTRY glTexCoord2s( GLshort s, GLshort t ); + +GLAPI void GLAPIENTRY glTexCoord3d( GLdouble s, GLdouble t, GLdouble r ); +GLAPI void GLAPIENTRY glTexCoord3f( GLfloat s, GLfloat t, GLfloat r ); +GLAPI void GLAPIENTRY glTexCoord3i( GLint s, GLint t, GLint r ); +GLAPI void GLAPIENTRY glTexCoord3s( GLshort s, GLshort t, GLshort r ); + +GLAPI void GLAPIENTRY glTexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q ); +GLAPI void GLAPIENTRY glTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q ); +GLAPI void GLAPIENTRY glTexCoord4i( GLint s, GLint t, GLint r, GLint q ); +GLAPI void GLAPIENTRY glTexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q ); + +GLAPI void GLAPIENTRY glTexCoord1dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord1fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord1iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord1sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord2iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord3iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord4iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glRasterPos2d( GLdouble x, GLdouble y ); +GLAPI void GLAPIENTRY glRasterPos2f( GLfloat x, GLfloat y ); +GLAPI void GLAPIENTRY glRasterPos2i( GLint x, GLint y ); +GLAPI void GLAPIENTRY glRasterPos2s( GLshort x, GLshort y ); + +GLAPI void GLAPIENTRY glRasterPos3d( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glRasterPos3f( GLfloat x, GLfloat y, GLfloat z ); +GLAPI void GLAPIENTRY glRasterPos3i( GLint x, GLint y, GLint z ); +GLAPI void GLAPIENTRY glRasterPos3s( GLshort x, GLshort y, GLshort z ); + +GLAPI void GLAPIENTRY glRasterPos4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); +GLAPI void GLAPIENTRY glRasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); +GLAPI void GLAPIENTRY glRasterPos4i( GLint x, GLint y, GLint z, GLint w ); +GLAPI void GLAPIENTRY glRasterPos4s( GLshort x, GLshort y, GLshort z, GLshort w ); + +GLAPI void GLAPIENTRY glRasterPos2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos2iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glRasterPos3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos3iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glRasterPos4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos4iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ); +GLAPI void GLAPIENTRY glRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ); +GLAPI void GLAPIENTRY glRecti( GLint x1, GLint y1, GLint x2, GLint y2 ); +GLAPI void GLAPIENTRY glRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ); + + +GLAPI void GLAPIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 ); +GLAPI void GLAPIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 ); +GLAPI void GLAPIENTRY glRectiv( const GLint *v1, const GLint *v2 ); +GLAPI void GLAPIENTRY glRectsv( const GLshort *v1, const GLshort *v2 ); + + +/* + * Vertex Arrays (1.1) + */ + +GLAPI void GLAPIENTRY glVertexPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glNormalPointer( GLenum type, GLsizei stride, + const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glColorPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glIndexPointer( GLenum type, GLsizei stride, + const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glTexCoordPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glGetPointerv( GLenum pname, GLvoid **params ); + +GLAPI void GLAPIENTRY glArrayElement( GLint i ); + +GLAPI void GLAPIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ); + +GLAPI void GLAPIENTRY glDrawElements( GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices ); + +GLAPI void GLAPIENTRY glInterleavedArrays( GLenum format, GLsizei stride, + const GLvoid *pointer ); + +/* + * Lighting + */ + +GLAPI void GLAPIENTRY glShadeModel( GLenum mode ); + +GLAPI void GLAPIENTRY glLightf( GLenum light, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glLighti( GLenum light, GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glLightfv( GLenum light, GLenum pname, + const GLfloat *params ); +GLAPI void GLAPIENTRY glLightiv( GLenum light, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glGetLightfv( GLenum light, GLenum pname, + GLfloat *params ); +GLAPI void GLAPIENTRY glGetLightiv( GLenum light, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glLightModelf( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glLightModeli( GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glLightModelfv( GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glLightModeliv( GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glMaterialf( GLenum face, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glMateriali( GLenum face, GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glMaterialfv( GLenum face, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glMaterialiv( GLenum face, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetMaterialiv( GLenum face, GLenum pname, GLint *params ); + +GLAPI void GLAPIENTRY glColorMaterial( GLenum face, GLenum mode ); + + +/* + * Raster functions + */ + +GLAPI void GLAPIENTRY glPixelZoom( GLfloat xfactor, GLfloat yfactor ); + +GLAPI void GLAPIENTRY glPixelStoref( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glPixelStorei( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glPixelTransferf( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glPixelTransferi( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glPixelMapfv( GLenum map, GLsizei mapsize, + const GLfloat *values ); +GLAPI void GLAPIENTRY glPixelMapuiv( GLenum map, GLsizei mapsize, + const GLuint *values ); +GLAPI void GLAPIENTRY glPixelMapusv( GLenum map, GLsizei mapsize, + const GLushort *values ); + +GLAPI void GLAPIENTRY glGetPixelMapfv( GLenum map, GLfloat *values ); +GLAPI void GLAPIENTRY glGetPixelMapuiv( GLenum map, GLuint *values ); +GLAPI void GLAPIENTRY glGetPixelMapusv( GLenum map, GLushort *values ); + +GLAPI void GLAPIENTRY glBitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ); + +GLAPI void GLAPIENTRY glReadPixels( GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels ); + +GLAPI void GLAPIENTRY glDrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glCopyPixels( GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type ); + +/* + * Stenciling + */ + +GLAPI void GLAPIENTRY glStencilFunc( GLenum func, GLint ref, GLuint mask ); + +GLAPI void GLAPIENTRY glStencilMask( GLuint mask ); + +GLAPI void GLAPIENTRY glStencilOp( GLenum fail, GLenum zfail, GLenum zpass ); + +GLAPI void GLAPIENTRY glClearStencil( GLint s ); + + + +/* + * Texture mapping + */ + +GLAPI void GLAPIENTRY glTexGend( GLenum coord, GLenum pname, GLdouble param ); +GLAPI void GLAPIENTRY glTexGenf( GLenum coord, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexGeni( GLenum coord, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexGendv( GLenum coord, GLenum pname, const GLdouble *params ); +GLAPI void GLAPIENTRY glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glTexGeniv( GLenum coord, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexGendv( GLenum coord, GLenum pname, GLdouble *params ); +GLAPI void GLAPIENTRY glGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexGeniv( GLenum coord, GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexEnvf( GLenum target, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexEnvi( GLenum target, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glTexEnviv( GLenum target, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexEnviv( GLenum target, GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexParameterfv( GLenum target, GLenum pname, + const GLfloat *params ); +GLAPI void GLAPIENTRY glTexParameteriv( GLenum target, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexParameterfv( GLenum target, + GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv( GLenum target, + GLenum pname, GLint *params ); + +GLAPI void GLAPIENTRY glGetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexImage1D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glTexImage2D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glGetTexImage( GLenum target, GLint level, + GLenum format, GLenum type, + GLvoid *pixels ); + + +/* 1.1 functions */ + +GLAPI void GLAPIENTRY glGenTextures( GLsizei n, GLuint *textures ); + +GLAPI void GLAPIENTRY glDeleteTextures( GLsizei n, const GLuint *textures); + +GLAPI void GLAPIENTRY glBindTexture( GLenum target, GLuint texture ); + +GLAPI void GLAPIENTRY glPrioritizeTextures( GLsizei n, + const GLuint *textures, + const GLclampf *priorities ); + +GLAPI GLboolean GLAPIENTRY glAreTexturesResident( GLsizei n, + const GLuint *textures, + GLboolean *residences ); + +GLAPI GLboolean GLAPIENTRY glIsTexture( GLuint texture ); + + +GLAPI void GLAPIENTRY glTexSubImage1D( GLenum target, GLint level, + GLint xoffset, + GLsizei width, GLenum format, + GLenum type, const GLvoid *pixels ); + + +GLAPI void GLAPIENTRY glTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +GLAPI void GLAPIENTRY glCopyTexImage1D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, + GLsizei width, GLint border ); + + +GLAPI void GLAPIENTRY glCopyTexImage2D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLint border ); + + +GLAPI void GLAPIENTRY glCopyTexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, + GLsizei width ); + + +GLAPI void GLAPIENTRY glCopyTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height ); + + +/* + * Evaluators + */ + +GLAPI void GLAPIENTRY glMap1d( GLenum target, GLdouble u1, GLdouble u2, + GLint stride, + GLint order, const GLdouble *points ); +GLAPI void GLAPIENTRY glMap1f( GLenum target, GLfloat u1, GLfloat u2, + GLint stride, + GLint order, const GLfloat *points ); + +GLAPI void GLAPIENTRY glMap2d( GLenum target, + GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, + GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, + const GLdouble *points ); +GLAPI void GLAPIENTRY glMap2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points ); + +GLAPI void GLAPIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v ); +GLAPI void GLAPIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v ); +GLAPI void GLAPIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v ); + +GLAPI void GLAPIENTRY glEvalCoord1d( GLdouble u ); +GLAPI void GLAPIENTRY glEvalCoord1f( GLfloat u ); + +GLAPI void GLAPIENTRY glEvalCoord1dv( const GLdouble *u ); +GLAPI void GLAPIENTRY glEvalCoord1fv( const GLfloat *u ); + +GLAPI void GLAPIENTRY glEvalCoord2d( GLdouble u, GLdouble v ); +GLAPI void GLAPIENTRY glEvalCoord2f( GLfloat u, GLfloat v ); + +GLAPI void GLAPIENTRY glEvalCoord2dv( const GLdouble *u ); +GLAPI void GLAPIENTRY glEvalCoord2fv( const GLfloat *u ); + +GLAPI void GLAPIENTRY glMapGrid1d( GLint un, GLdouble u1, GLdouble u2 ); +GLAPI void GLAPIENTRY glMapGrid1f( GLint un, GLfloat u1, GLfloat u2 ); + +GLAPI void GLAPIENTRY glMapGrid2d( GLint un, GLdouble u1, GLdouble u2, + GLint vn, GLdouble v1, GLdouble v2 ); +GLAPI void GLAPIENTRY glMapGrid2f( GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ); + +GLAPI void GLAPIENTRY glEvalPoint1( GLint i ); + +GLAPI void GLAPIENTRY glEvalPoint2( GLint i, GLint j ); + +GLAPI void GLAPIENTRY glEvalMesh1( GLenum mode, GLint i1, GLint i2 ); + +GLAPI void GLAPIENTRY glEvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); + + +/* + * Fog + */ + +GLAPI void GLAPIENTRY glFogf( GLenum pname, GLfloat param ); + +GLAPI void GLAPIENTRY glFogi( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glFogfv( GLenum pname, const GLfloat *params ); + +GLAPI void GLAPIENTRY glFogiv( GLenum pname, const GLint *params ); + + +/* + * Selection and Feedback + */ + +GLAPI void GLAPIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ); + +GLAPI void GLAPIENTRY glPassThrough( GLfloat token ); + +GLAPI void GLAPIENTRY glSelectBuffer( GLsizei size, GLuint *buffer ); + +GLAPI void GLAPIENTRY glInitNames( void ); + +GLAPI void GLAPIENTRY glLoadName( GLuint name ); + +GLAPI void GLAPIENTRY glPushName( GLuint name ); + +GLAPI void GLAPIENTRY glPopName( void ); + + + +/* + * OpenGL 1.2 + */ + +#define GL_RESCALE_NORMAL 0x803A +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_TEXTURE_BINDING_3D 0x806A + +GLAPI void GLAPIENTRY glDrawRangeElements( GLenum mode, GLuint start, + GLuint end, GLsizei count, GLenum type, const GLvoid *indices ); + +GLAPI void GLAPIENTRY glTexImage3D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLsizei depth, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, + GLenum format, + GLenum type, const GLvoid *pixels); + +GLAPI void GLAPIENTRY glCopyTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLint x, + GLint y, GLsizei width, + GLsizei height ); + +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + + +/* + * GL_ARB_imaging + */ + +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_BLEND_EQUATION 0x8009 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_COLOR 0x8005 + + +GLAPI void GLAPIENTRY glColorTable( GLenum target, GLenum internalformat, + GLsizei width, GLenum format, + GLenum type, const GLvoid *table ); + +GLAPI void GLAPIENTRY glColorSubTable( GLenum target, + GLsizei start, GLsizei count, + GLenum format, GLenum type, + const GLvoid *data ); + +GLAPI void GLAPIENTRY glColorTableParameteriv(GLenum target, GLenum pname, + const GLint *params); + +GLAPI void GLAPIENTRY glColorTableParameterfv(GLenum target, GLenum pname, + const GLfloat *params); + +GLAPI void GLAPIENTRY glCopyColorSubTable( GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glCopyColorTable( GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glGetColorTable( GLenum target, GLenum format, + GLenum type, GLvoid *table ); + +GLAPI void GLAPIENTRY glGetColorTableParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetColorTableParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glBlendEquation( GLenum mode ); + +GLAPI void GLAPIENTRY glBlendColor( GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha ); + +GLAPI void GLAPIENTRY glHistogram( GLenum target, GLsizei width, + GLenum internalformat, GLboolean sink ); + +GLAPI void GLAPIENTRY glResetHistogram( GLenum target ); + +GLAPI void GLAPIENTRY glGetHistogram( GLenum target, GLboolean reset, + GLenum format, GLenum type, + GLvoid *values ); + +GLAPI void GLAPIENTRY glGetHistogramParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetHistogramParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glMinmax( GLenum target, GLenum internalformat, + GLboolean sink ); + +GLAPI void GLAPIENTRY glResetMinmax( GLenum target ); + +GLAPI void GLAPIENTRY glGetMinmax( GLenum target, GLboolean reset, + GLenum format, GLenum types, + GLvoid *values ); + +GLAPI void GLAPIENTRY glGetMinmaxParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetMinmaxParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glConvolutionFilter1D( GLenum target, + GLenum internalformat, GLsizei width, GLenum format, GLenum type, + const GLvoid *image ); + +GLAPI void GLAPIENTRY glConvolutionFilter2D( GLenum target, + GLenum internalformat, GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *image ); + +GLAPI void GLAPIENTRY glConvolutionParameterf( GLenum target, GLenum pname, + GLfloat params ); + +GLAPI void GLAPIENTRY glConvolutionParameterfv( GLenum target, GLenum pname, + const GLfloat *params ); + +GLAPI void GLAPIENTRY glConvolutionParameteri( GLenum target, GLenum pname, + GLint params ); + +GLAPI void GLAPIENTRY glConvolutionParameteriv( GLenum target, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glCopyConvolutionFilter1D( GLenum target, + GLenum internalformat, GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glCopyConvolutionFilter2D( GLenum target, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height); + +GLAPI void GLAPIENTRY glGetConvolutionFilter( GLenum target, GLenum format, + GLenum type, GLvoid *image ); + +GLAPI void GLAPIENTRY glGetConvolutionParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetConvolutionParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target, + GLenum internalformat, GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *row, const GLvoid *column ); + +GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format, + GLenum type, GLvoid *row, GLvoid *column, GLvoid *span ); + + + + +/* + * OpenGL 1.3 + */ + +/* multitexture */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +/* texture_cube_map */ +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +/* texture_compression */ +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +/* multisample */ +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +/* transpose_matrix */ +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +/* texture_env_combine */ +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +/* texture_env_dot3 */ +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +/* texture_border_clamp */ +#define GL_CLAMP_TO_BORDER 0x812D + +GLAPI void GLAPIENTRY glActiveTexture( GLenum texture ); + +GLAPI void GLAPIENTRY glClientActiveTexture( GLenum texture ); + +GLAPI void GLAPIENTRY glCompressedTexImage1D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexImage3D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glGetCompressedTexImage( GLenum target, GLint lod, GLvoid *img ); + +GLAPI void GLAPIENTRY glMultiTexCoord1d( GLenum target, GLdouble s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1f( GLenum target, GLfloat s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1i( GLenum target, GLint s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1s( GLenum target, GLshort s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2d( GLenum target, GLdouble s, GLdouble t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2f( GLenum target, GLfloat s, GLfloat t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2i( GLenum target, GLint s, GLint t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2s( GLenum target, GLshort s, GLshort t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3d( GLenum target, GLdouble s, GLdouble t, GLdouble r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3f( GLenum target, GLfloat s, GLfloat t, GLfloat r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3i( GLenum target, GLint s, GLint t, GLint r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3s( GLenum target, GLshort s, GLshort t, GLshort r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4d( GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4f( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4i( GLenum target, GLint s, GLint t, GLint r, GLint q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4s( GLenum target, GLshort s, GLshort t, GLshort r, GLshort q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4sv( GLenum target, const GLshort *v ); + + +GLAPI void GLAPIENTRY glLoadTransposeMatrixd( const GLdouble m[16] ); + +GLAPI void GLAPIENTRY glLoadTransposeMatrixf( const GLfloat m[16] ); + +GLAPI void GLAPIENTRY glMultTransposeMatrixd( const GLdouble m[16] ); + +GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] ); + +GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert ); + + +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); + + + +/* + * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1) + */ +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 + +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture); +GLAPI void GLAPIENTRY glClientActiveTextureARB(GLenum texture); +GLAPI void GLAPIENTRY glMultiTexCoord1dARB(GLenum target, GLdouble s); +GLAPI void GLAPIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord1fARB(GLenum target, GLfloat s); +GLAPI void GLAPIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord1iARB(GLenum target, GLint s); +GLAPI void GLAPIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord1sARB(GLenum target, GLshort s); +GLAPI void GLAPIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord2iARB(GLenum target, GLint s, GLint t); +GLAPI void GLAPIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t); +GLAPI void GLAPIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort *v); + +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#endif /* GL_ARB_multitexture */ + + + +/* + * Define this token if you want "old-style" header file behaviour (extensions + * defined in gl.h). Otherwise, extensions will be included from glext.h. + */ +#if !defined(NO_SDL_GLEXT) && !defined(GL_GLEXT_LEGACY) +#include "SDL_opengl_glext.h" +#endif /* GL_GLEXT_LEGACY */ + + + +/* + * ???. GL_MESA_packed_depth_stencil + * XXX obsolete + */ +#ifndef GL_MESA_packed_depth_stencil +#define GL_MESA_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_MESA 0x8750 +#define GL_UNSIGNED_INT_24_8_MESA 0x8751 +#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752 +#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753 +#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754 + +#endif /* GL_MESA_packed_depth_stencil */ + + +#ifndef GL_ATI_blend_equation_separate +#define GL_ATI_blend_equation_separate 1 + +#define GL_ALPHA_BLEND_EQUATION_ATI 0x883D + +GLAPI void GLAPIENTRY glBlendEquationSeparateATI( GLenum modeRGB, GLenum modeA ); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEATIPROC) (GLenum modeRGB, GLenum modeA); + +#endif /* GL_ATI_blend_equation_separate */ + + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GLAPI void APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + + +/** + ** NOTE!!!!! If you add new functions to this file, or update + ** glext.h be sure to regenerate the gl_mangle.h file. See comments + ** in that file for details. + **/ + + + +/********************************************************************** + * Begin system-specific stuff + */ +#if defined(PRAGMA_EXPORT_SUPPORTED) +#pragma export off +#endif + +/* + * End system-specific stuff + **********************************************************************/ + + +#ifdef __cplusplus +} +#endif + +#endif /* __gl_h_ */ + +#endif /* !__IPHONEOS__ */ + +#endif /* _SDL_opengl_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_opengl_glext.h b/packages/sdl2.2.0.5/build/native/include/SDL_opengl_glext.h new file mode 100644 index 00000000..cd3869fe --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_opengl_glext.h @@ -0,0 +1,11177 @@ +#ifndef __glext_h_ +#define __glext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 26745 $ on $Date: 2014-05-21 03:12:26 -0700 (Wed, 21 May 2014) $ +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +#define GL_GLEXT_VERSION 20140521 + +/* Generated C header for: + * API: gl + * Profile: compatibility + * Versions considered: .* + * Versions emitted: 1\.[2-9]|[234]\.[0-9] + * Default extensions included: gl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_RESCALE_NORMAL 0x803A +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_VERSION_1_2 */ + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTexture (GLenum texture); +GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, void *img); +GLAPI void APIENTRY glClientActiveTexture (GLenum texture); +GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s); +GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s); +GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s); +GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s); +GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t); +GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t); +GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t); +GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t); +GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r); +GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v); +GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m); +GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m); +GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m); +GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); +#endif +#endif /* GL_VERSION_1_3 */ + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); +GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); +GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); +GLAPI void APIENTRY glFogCoordf (GLfloat coord); +GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord); +GLAPI void APIENTRY glFogCoordd (GLdouble coord); +GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord); +GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v); +GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v); +GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v); +GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue); +GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v); +GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue); +GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v); +GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v); +GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue); +GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v); +GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue); +GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v); +GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2iv (const GLint *v); +GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2sv (const GLshort *v); +GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3iv (const GLint *v); +GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3sv (const GLshort *v); +GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void APIENTRY glBlendEquation (GLenum mode); +#endif +#endif /* GL_VERSION_1_4 */ + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#include +#ifdef __MACOSX__ +typedef long GLsizeiptr; +typedef long GLintptr; +#else +typedef ptrdiff_t GLsizeiptr; +typedef ptrdiff_t GLintptr; +#endif +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_COORD 0x8451 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_RGB 0x8582 +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC2_ALPHA 0x858A +typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); +typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsQuery (GLuint id); +GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); +GLAPI void APIENTRY glEndQuery (GLenum target); +GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); +GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, void *data); +GLAPI void *APIENTRY glMapBuffer (GLenum target, GLenum access); +GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); +GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_VERSION_1_5 */ + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +typedef char GLchar; +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_TEXTURE_COORDS 0x8871 +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); +GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GLAPI void APIENTRY glCompileShader (GLuint shader); +GLAPI GLuint APIENTRY glCreateProgram (void); +GLAPI GLuint APIENTRY glCreateShader (GLenum type); +GLAPI void APIENTRY glDeleteProgram (GLuint program); +GLAPI void APIENTRY glDeleteShader (GLuint shader); +GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); +GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); +GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); +GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GLAPI GLboolean APIENTRY glIsProgram (GLuint program); +GLAPI GLboolean APIENTRY glIsShader (GLuint shader); +GLAPI void APIENTRY glLinkProgram (GLuint program); +GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GLAPI void APIENTRY glUseProgram (GLuint program); +GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); +GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); +GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glValidateProgram (GLuint program); +GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +#endif +#endif /* GL_VERSION_2_0 */ + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_VERSION_2_1 */ + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 +typedef unsigned short GLhalf; +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_INDEX 0x8222 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_ALPHA_INTEGER 0x8D97 +typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void *(APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); +GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); +GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); +GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); +GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedback (void); +GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); +GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); +GLAPI void APIENTRY glEndConditionalRender (void); +GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); +GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); +GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); +GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); +GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); +GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index); +GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); +GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); +GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateMipmap (GLenum target); +GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void *APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glBindVertexArray (GLuint array); +GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); +#endif +#endif /* GL_VERSION_3_0 */ + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); +typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); +GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +#endif +#endif /* GL_VERSION_3_1 */ + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 +typedef struct __GLsync *GLsync; +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glxext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif +typedef uint64_t GLuint64; +typedef int64_t GLint64; +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); +typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); +typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); +typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); +typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +GLAPI void APIENTRY glProvokingVertex (GLenum mode); +GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GLAPI GLboolean APIENTRY glIsSync (GLsync sync); +GLAPI void APIENTRY glDeleteSync (GLsync sync); +GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); +GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); +GLAPI void APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); +#endif +#endif /* GL_VERSION_3_2 */ + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_SRC1_COLOR 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 +#define GL_INT_2_10_10_10_REV 0x8D9F +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); +GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); +GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); +GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); +GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); +GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); +GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color); +GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color); +GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color); +GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color); +#endif +#endif /* GL_VERSION_3_3 */ + +#ifndef GL_VERSION_4_0 +#define GL_VERSION_4_0 1 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); +typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); +typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); +typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); +typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); +typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); +typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); +typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); +typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); +typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); +typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMinSampleShading (GLfloat value); +GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); +GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); +GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); +GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); +GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); +GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); +GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); +GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); +GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); +GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); +GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); +GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); +GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); +GLAPI void APIENTRY glPauseTransformFeedback (void); +GLAPI void APIENTRY glResumeTransformFeedback (void); +GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); +GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); +GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); +GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); +GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); +#endif +#endif /* GL_VERSION_4_0 */ + +#ifndef GL_VERSION_4_1 +#define GL_VERSION_4_1 1 +#define GL_FIXED 0x140C +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_RGB565 0x8D62 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_MAX_VIEWPORTS 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_UNDEFINED_VERTEX 0x8260 +typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); +typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); +typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); +typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); +typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReleaseShaderCompiler (void); +GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GLAPI void APIENTRY glClearDepthf (GLfloat d); +GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); +GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); +GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); +GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); +GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); +GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); +GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); +GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); +GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); +GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); +GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); +GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); +GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); +GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f); +GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); +GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); +#endif +#endif /* GL_VERSION_4_1 */ + +#ifndef GL_VERSION_4_2 +#define GL_VERSION_4_2 1 +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); +typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); +GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount); +GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#endif +#endif /* GL_VERSION_4_2 */ + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 1 +typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_MIPMAP 0x8293 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_COLOR_ENCODING 0x8296 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_FILTER 0x829A +#define GL_VERTEX_TEXTURE 0x829B +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F +#define GL_IS_PER_PATCH 0x92E7 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_DISPLAY_LIST 0x82E7 +typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); +typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); +typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); +GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); +GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer); +GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GLAPI void APIENTRY glPopDebugGroup (void); +GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +#endif /* GL_VERSION_4_3 */ + +#ifndef GL_VERSION_4_4 +#define GL_VERSION_4_4 1 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_CLEAR_TEXTURE 0x9365 +#define GL_LOCATION_COMPONENT 0x934A +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 +typedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); +typedef void (APIENTRYP PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); +typedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); +typedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers); +typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); +typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferStorage (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +GLAPI void APIENTRY glClearTexImage (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glBindBuffersBase (GLenum target, GLuint first, GLsizei count, const GLuint *buffers); +GLAPI void APIENTRY glBindBuffersRange (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); +GLAPI void APIENTRY glBindTextures (GLuint first, GLsizei count, const GLuint *textures); +GLAPI void APIENTRY glBindSamplers (GLuint first, GLsizei count, const GLuint *samplers); +GLAPI void APIENTRY glBindImageTextures (GLuint first, GLsizei count, const GLuint *textures); +GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +#endif +#endif /* GL_VERSION_4_4 */ + +#ifndef GL_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 +#endif /* GL_ARB_ES2_compatibility */ + +#ifndef GL_ARB_ES3_compatibility +#define GL_ARB_ES3_compatibility 1 +#endif /* GL_ARB_ES3_compatibility */ + +#ifndef GL_ARB_arrays_of_arrays +#define GL_ARB_arrays_of_arrays 1 +#endif /* GL_ARB_arrays_of_arrays */ + +#ifndef GL_ARB_base_instance +#define GL_ARB_base_instance 1 +#endif /* GL_ARB_base_instance */ + +#ifndef GL_ARB_bindless_texture +#define GL_ARB_bindless_texture 1 +typedef uint64_t GLuint64EXT; +#define GL_UNSIGNED_INT64_ARB 0x140F +typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); +typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint64 APIENTRY glGetTextureHandleARB (GLuint texture); +GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleARB (GLuint texture, GLuint sampler); +GLAPI void APIENTRY glMakeTextureHandleResidentARB (GLuint64 handle); +GLAPI void APIENTRY glMakeTextureHandleNonResidentARB (GLuint64 handle); +GLAPI GLuint64 APIENTRY glGetImageHandleARB (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +GLAPI void APIENTRY glMakeImageHandleResidentARB (GLuint64 handle, GLenum access); +GLAPI void APIENTRY glMakeImageHandleNonResidentARB (GLuint64 handle); +GLAPI void APIENTRY glUniformHandleui64ARB (GLint location, GLuint64 value); +GLAPI void APIENTRY glUniformHandleui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniformHandleui64ARB (GLuint program, GLint location, GLuint64 value); +GLAPI void APIENTRY glProgramUniformHandleui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +GLAPI GLboolean APIENTRY glIsTextureHandleResidentARB (GLuint64 handle); +GLAPI GLboolean APIENTRY glIsImageHandleResidentARB (GLuint64 handle); +GLAPI void APIENTRY glVertexAttribL1ui64ARB (GLuint index, GLuint64EXT x); +GLAPI void APIENTRY glVertexAttribL1ui64vARB (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glGetVertexAttribLui64vARB (GLuint index, GLenum pname, GLuint64EXT *params); +#endif +#endif /* GL_ARB_bindless_texture */ + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended 1 +#endif /* GL_ARB_blend_func_extended */ + +#ifndef GL_ARB_buffer_storage +#define GL_ARB_buffer_storage 1 +#endif /* GL_ARB_buffer_storage */ + +#ifndef GL_ARB_cl_event +#define GL_ARB_cl_event 1 +struct _cl_context; +struct _cl_event; +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 +typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, struct _cl_event *event, GLbitfield flags); +#endif +#endif /* GL_ARB_cl_event */ + +#ifndef GL_ARB_clear_buffer_object +#define GL_ARB_clear_buffer_object 1 +#endif /* GL_ARB_clear_buffer_object */ + +#ifndef GL_ARB_clear_texture +#define GL_ARB_clear_texture 1 +#endif /* GL_ARB_clear_texture */ + +#ifndef GL_ARB_color_buffer_float +#define GL_ARB_color_buffer_float 1 +#define GL_RGBA_FLOAT_MODE_ARB 0x8820 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +#define GL_FIXED_ONLY_ARB 0x891D +typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); +#endif +#endif /* GL_ARB_color_buffer_float */ + +#ifndef GL_ARB_compatibility +#define GL_ARB_compatibility 1 +#endif /* GL_ARB_compatibility */ + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_ARB_compressed_texture_pixel_storage 1 +#endif /* GL_ARB_compressed_texture_pixel_storage */ + +#ifndef GL_ARB_compute_shader +#define GL_ARB_compute_shader 1 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#endif /* GL_ARB_compute_shader */ + +#ifndef GL_ARB_compute_variable_group_size +#define GL_ARB_compute_variable_group_size 1 +#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344 +#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB +#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345 +#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z); +#endif +#endif /* GL_ARB_compute_variable_group_size */ + +#ifndef GL_ARB_conservative_depth +#define GL_ARB_conservative_depth 1 +#endif /* GL_ARB_conservative_depth */ + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#endif /* GL_ARB_copy_buffer */ + +#ifndef GL_ARB_copy_image +#define GL_ARB_copy_image 1 +#endif /* GL_ARB_copy_image */ + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +#endif +#endif /* GL_ARB_debug_output */ + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 +#endif /* GL_ARB_depth_buffer_float */ + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp 1 +#endif /* GL_ARB_depth_clamp */ + +#ifndef GL_ARB_depth_texture +#define GL_ARB_depth_texture 1 +#define GL_DEPTH_COMPONENT16_ARB 0x81A5 +#define GL_DEPTH_COMPONENT24_ARB 0x81A6 +#define GL_DEPTH_COMPONENT32_ARB 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A +#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B +#endif /* GL_ARB_depth_texture */ + +#ifndef GL_ARB_draw_buffers +#define GL_ARB_draw_buffers 1 +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 +#define GL_DRAW_BUFFER0_ARB 0x8825 +#define GL_DRAW_BUFFER1_ARB 0x8826 +#define GL_DRAW_BUFFER2_ARB 0x8827 +#define GL_DRAW_BUFFER3_ARB 0x8828 +#define GL_DRAW_BUFFER4_ARB 0x8829 +#define GL_DRAW_BUFFER5_ARB 0x882A +#define GL_DRAW_BUFFER6_ARB 0x882B +#define GL_DRAW_BUFFER7_ARB 0x882C +#define GL_DRAW_BUFFER8_ARB 0x882D +#define GL_DRAW_BUFFER9_ARB 0x882E +#define GL_DRAW_BUFFER10_ARB 0x882F +#define GL_DRAW_BUFFER11_ARB 0x8830 +#define GL_DRAW_BUFFER12_ARB 0x8831 +#define GL_DRAW_BUFFER13_ARB 0x8832 +#define GL_DRAW_BUFFER14_ARB 0x8833 +#define GL_DRAW_BUFFER15_ARB 0x8834 +typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_ARB_draw_buffers */ + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend 1 +typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#endif +#endif /* GL_ARB_draw_buffers_blend */ + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex 1 +#endif /* GL_ARB_draw_elements_base_vertex */ + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect 1 +#endif /* GL_ARB_draw_indirect */ + +#ifndef GL_ARB_draw_instanced +#define GL_ARB_draw_instanced 1 +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_ARB_draw_instanced */ + +#ifndef GL_ARB_enhanced_layouts +#define GL_ARB_enhanced_layouts 1 +#endif /* GL_ARB_enhanced_layouts */ + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location 1 +#endif /* GL_ARB_explicit_attrib_location */ + +#ifndef GL_ARB_explicit_uniform_location +#define GL_ARB_explicit_uniform_location 1 +#endif /* GL_ARB_explicit_uniform_location */ + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions 1 +#endif /* GL_ARB_fragment_coord_conventions */ + +#ifndef GL_ARB_fragment_layer_viewport +#define GL_ARB_fragment_layer_viewport 1 +#endif /* GL_ARB_fragment_layer_viewport */ + +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void *string); +typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void *string); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const void *string); +GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program); +GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs); +GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, void *string); +GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); +#endif +#endif /* GL_ARB_fragment_program */ + +#ifndef GL_ARB_fragment_program_shadow +#define GL_ARB_fragment_program_shadow 1 +#endif /* GL_ARB_fragment_program_shadow */ + +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader 1 +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif /* GL_ARB_fragment_shader */ + +#ifndef GL_ARB_framebuffer_no_attachments +#define GL_ARB_framebuffer_no_attachments 1 +#endif /* GL_ARB_framebuffer_no_attachments */ + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 +#endif /* GL_ARB_framebuffer_object */ + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 +#endif /* GL_ARB_framebuffer_sRGB */ + +#ifndef GL_KHR_context_flush_control +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#endif /* GL_KHR_context_flush_control */ + +#ifndef GL_ARB_geometry_shader4 +#define GL_ARB_geometry_shader4 1 +#define GL_LINES_ADJACENCY_ARB 0x000A +#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B +#define GL_TRIANGLES_ADJACENCY_ARB 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D +#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 +#define GL_GEOMETRY_SHADER_ARB 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value); +GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif +#endif /* GL_ARB_geometry_shader4 */ + +#ifndef GL_ARB_get_program_binary +#define GL_ARB_get_program_binary 1 +#endif /* GL_ARB_get_program_binary */ + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 1 +#endif /* GL_ARB_gpu_shader5 */ + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 1 +#endif /* GL_ARB_gpu_shader_fp64 */ + +#ifndef GL_ARB_half_float_pixel +#define GL_ARB_half_float_pixel 1 +typedef unsigned short GLhalfARB; +#define GL_HALF_FLOAT_ARB 0x140B +#endif /* GL_ARB_half_float_pixel */ + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 +#endif /* GL_ARB_half_float_vertex */ + +#ifndef GL_ARB_imaging +#define GL_ARB_imaging 1 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_EQUATION 0x8009 +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, void *table); +GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params); +GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params); +GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, void *image); +GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glResetHistogram (GLenum target); +GLAPI void APIENTRY glResetMinmax (GLenum target); +#endif +#endif /* GL_ARB_imaging */ + +#ifndef GL_ARB_indirect_parameters +#define GL_ARB_indirect_parameters 1 +#define GL_PARAMETER_BUFFER_ARB 0x80EE +#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_ARB_indirect_parameters */ + +#ifndef GL_ARB_instanced_arrays +#define GL_ARB_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE +typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor); +#endif +#endif /* GL_ARB_instanced_arrays */ + +#ifndef GL_ARB_internalformat_query +#define GL_ARB_internalformat_query 1 +#endif /* GL_ARB_internalformat_query */ + +#ifndef GL_ARB_internalformat_query2 +#define GL_ARB_internalformat_query2 1 +#define GL_SRGB_DECODE_ARB 0x8299 +#endif /* GL_ARB_internalformat_query2 */ + +#ifndef GL_ARB_invalidate_subdata +#define GL_ARB_invalidate_subdata 1 +#endif /* GL_ARB_invalidate_subdata */ + +#ifndef GL_ARB_map_buffer_alignment +#define GL_ARB_map_buffer_alignment 1 +#endif /* GL_ARB_map_buffer_alignment */ + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 +#endif /* GL_ARB_map_buffer_range */ + +#ifndef GL_ARB_matrix_palette +#define GL_ARB_matrix_palette 1 +#define GL_MATRIX_PALETTE_ARB 0x8840 +#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 +#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 +#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 +#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 +#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 +#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 +#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 +#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 +#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 +typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); +typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); +typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index); +GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices); +GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices); +GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices); +GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_ARB_matrix_palette */ + +#ifndef GL_ARB_multi_bind +#define GL_ARB_multi_bind 1 +#endif /* GL_ARB_multi_bind */ + +#ifndef GL_ARB_multi_draw_indirect +#define GL_ARB_multi_draw_indirect 1 +#endif /* GL_ARB_multi_draw_indirect */ + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleCoverageARB (GLfloat value, GLboolean invert); +#endif +#endif /* GL_ARB_multisample */ + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveTextureARB (GLenum texture); +GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture); +GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s); +GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s); +GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s); +GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s); +GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t); +GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t); +GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t); +GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t); +GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r); +GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v); +GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v); +GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v); +GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v); +GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v); +#endif +#endif /* GL_ARB_multitexture */ + +#ifndef GL_ARB_occlusion_query +#define GL_ARB_occlusion_query 1 +#define GL_QUERY_COUNTER_BITS_ARB 0x8864 +#define GL_CURRENT_QUERY_ARB 0x8865 +#define GL_QUERY_RESULT_ARB 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 +#define GL_SAMPLES_PASSED_ARB 0x8914 +typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id); +GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id); +GLAPI void APIENTRY glEndQueryARB (GLenum target); +GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params); +#endif +#endif /* GL_ARB_occlusion_query */ + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 1 +#endif /* GL_ARB_occlusion_query2 */ + +#ifndef GL_ARB_pixel_buffer_object +#define GL_ARB_pixel_buffer_object 1 +#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF +#endif /* GL_ARB_pixel_buffer_object */ + +#ifndef GL_ARB_point_parameters +#define GL_ARB_point_parameters 1 +#define GL_POINT_SIZE_MIN_ARB 0x8126 +#define GL_POINT_SIZE_MAX_ARB 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_ARB_point_parameters */ + +#ifndef GL_ARB_point_sprite +#define GL_ARB_point_sprite 1 +#define GL_POINT_SPRITE_ARB 0x8861 +#define GL_COORD_REPLACE_ARB 0x8862 +#endif /* GL_ARB_point_sprite */ + +#ifndef GL_ARB_program_interface_query +#define GL_ARB_program_interface_query 1 +#endif /* GL_ARB_program_interface_query */ + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex 1 +#endif /* GL_ARB_provoking_vertex */ + +#ifndef GL_ARB_query_buffer_object +#define GL_ARB_query_buffer_object 1 +#endif /* GL_ARB_query_buffer_object */ + +#ifndef GL_ARB_robust_buffer_access_behavior +#define GL_ARB_robust_buffer_access_behavior 1 +#endif /* GL_ARB_robust_buffer_access_behavior */ + +#ifndef GL_ARB_robustness +#define GL_ARB_robustness 1 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 +typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); +typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); +typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img); +typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); +typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); +typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); +GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img); +GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, void *img); +GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values); +GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values); +GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values); +GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern); +GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +#endif +#endif /* GL_ARB_robustness */ + +#ifndef GL_ARB_robustness_isolation +#define GL_ARB_robustness_isolation 1 +#endif /* GL_ARB_robustness_isolation */ + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading 1 +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 +typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); +#endif +#endif /* GL_ARB_sample_shading */ + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects 1 +#endif /* GL_ARB_sampler_objects */ + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map 1 +#endif /* GL_ARB_seamless_cube_map */ + +#ifndef GL_ARB_seamless_cubemap_per_texture +#define GL_ARB_seamless_cubemap_per_texture 1 +#endif /* GL_ARB_seamless_cubemap_per_texture */ + +#ifndef GL_ARB_separate_shader_objects +#define GL_ARB_separate_shader_objects 1 +#endif /* GL_ARB_separate_shader_objects */ + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ARB_shader_atomic_counters 1 +#endif /* GL_ARB_shader_atomic_counters */ + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 +#endif /* GL_ARB_shader_bit_encoding */ + +#ifndef GL_ARB_shader_draw_parameters +#define GL_ARB_shader_draw_parameters 1 +#endif /* GL_ARB_shader_draw_parameters */ + +#ifndef GL_ARB_shader_group_vote +#define GL_ARB_shader_group_vote 1 +#endif /* GL_ARB_shader_group_vote */ + +#ifndef GL_ARB_shader_image_load_store +#define GL_ARB_shader_image_load_store 1 +#endif /* GL_ARB_shader_image_load_store */ + +#ifndef GL_ARB_shader_image_size +#define GL_ARB_shader_image_size 1 +#endif /* GL_ARB_shader_image_size */ + +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef char GLcharARB; +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); +typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); +typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj); +GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname); +GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj); +GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType); +GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length); +GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj); +GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); +GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj); +GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj); +GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj); +GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj); +GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0); +GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0); +GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name); +GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params); +GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params); +GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); +#endif +#endif /* GL_ARB_shader_objects */ + +#ifndef GL_ARB_shader_precision +#define GL_ARB_shader_precision 1 +#endif /* GL_ARB_shader_precision */ + +#ifndef GL_ARB_shader_stencil_export +#define GL_ARB_shader_stencil_export 1 +#endif /* GL_ARB_shader_stencil_export */ + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 +#endif /* GL_ARB_shader_storage_buffer_object */ + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine 1 +#endif /* GL_ARB_shader_subroutine */ + +#ifndef GL_ARB_shader_texture_lod +#define GL_ARB_shader_texture_lod 1 +#endif /* GL_ARB_shader_texture_lod */ + +#ifndef GL_ARB_shading_language_100 +#define GL_ARB_shading_language_100 1 +#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C +#endif /* GL_ARB_shading_language_100 */ + +#ifndef GL_ARB_shading_language_420pack +#define GL_ARB_shading_language_420pack 1 +#endif /* GL_ARB_shading_language_420pack */ + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include 1 +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA +typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); +typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); +typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); +typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); +typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); +GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); +GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length); +GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); +GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); +GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); +#endif +#endif /* GL_ARB_shading_language_include */ + +#ifndef GL_ARB_shading_language_packing +#define GL_ARB_shading_language_packing 1 +#endif /* GL_ARB_shading_language_packing */ + +#ifndef GL_ARB_shadow +#define GL_ARB_shadow 1 +#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C +#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D +#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E +#endif /* GL_ARB_shadow */ + +#ifndef GL_ARB_shadow_ambient +#define GL_ARB_shadow_ambient 1 +#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF +#endif /* GL_ARB_shadow_ambient */ + +#ifndef GL_ARB_sparse_texture +#define GL_ARB_sparse_texture 1 +#define GL_TEXTURE_SPARSE_ARB 0x91A6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 +#define GL_MIN_SPARSE_LEVEL_ARB 0x919B +#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 +#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 +typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +#endif +#endif /* GL_ARB_sparse_texture */ + +#ifndef GL_ARB_stencil_texturing +#define GL_ARB_stencil_texturing 1 +#endif /* GL_ARB_stencil_texturing */ + +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 +#endif /* GL_ARB_sync */ + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader 1 +#endif /* GL_ARB_tessellation_shader */ + +#ifndef GL_ARB_texture_border_clamp +#define GL_ARB_texture_border_clamp 1 +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif /* GL_ARB_texture_border_clamp */ + +#ifndef GL_ARB_texture_buffer_object +#define GL_ARB_texture_buffer_object 1 +#define GL_TEXTURE_BUFFER_ARB 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E +typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer); +#endif +#endif /* GL_ARB_texture_buffer_object */ + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 1 +#endif /* GL_ARB_texture_buffer_object_rgb32 */ + +#ifndef GL_ARB_texture_buffer_range +#define GL_ARB_texture_buffer_range 1 +#endif /* GL_ARB_texture_buffer_range */ + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void *img); +#endif +#endif /* GL_ARB_texture_compression */ + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc 1 +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif /* GL_ARB_texture_compression_bptc */ + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 +#endif /* GL_ARB_texture_compression_rgtc */ + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif /* GL_ARB_texture_cube_map */ + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array 1 +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F +#endif /* GL_ARB_texture_cube_map_array */ + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif /* GL_ARB_texture_env_add */ + +#ifndef GL_ARB_texture_env_combine +#define GL_ARB_texture_env_combine 1 +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#endif /* GL_ARB_texture_env_combine */ + +#ifndef GL_ARB_texture_env_crossbar +#define GL_ARB_texture_env_crossbar 1 +#endif /* GL_ARB_texture_env_crossbar */ + +#ifndef GL_ARB_texture_env_dot3 +#define GL_ARB_texture_env_dot3 1 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif /* GL_ARB_texture_env_dot3 */ + +#ifndef GL_ARB_texture_float +#define GL_ARB_texture_float 1 +#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 +#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 +#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 +#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 +#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 +#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 +#define GL_RGBA32F_ARB 0x8814 +#define GL_RGB32F_ARB 0x8815 +#define GL_ALPHA32F_ARB 0x8816 +#define GL_INTENSITY32F_ARB 0x8817 +#define GL_LUMINANCE32F_ARB 0x8818 +#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 +#define GL_RGBA16F_ARB 0x881A +#define GL_RGB16F_ARB 0x881B +#define GL_ALPHA16F_ARB 0x881C +#define GL_INTENSITY16F_ARB 0x881D +#define GL_LUMINANCE16F_ARB 0x881E +#define GL_LUMINANCE_ALPHA16F_ARB 0x881F +#endif /* GL_ARB_texture_float */ + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather 1 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F +#endif /* GL_ARB_texture_gather */ + +#ifndef GL_ARB_texture_mirror_clamp_to_edge +#define GL_ARB_texture_mirror_clamp_to_edge 1 +#endif /* GL_ARB_texture_mirror_clamp_to_edge */ + +#ifndef GL_ARB_texture_mirrored_repeat +#define GL_ARB_texture_mirrored_repeat 1 +#define GL_MIRRORED_REPEAT_ARB 0x8370 +#endif /* GL_ARB_texture_mirrored_repeat */ + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 +#endif /* GL_ARB_texture_multisample */ + +#ifndef GL_ARB_texture_non_power_of_two +#define GL_ARB_texture_non_power_of_two 1 +#endif /* GL_ARB_texture_non_power_of_two */ + +#ifndef GL_ARB_texture_query_levels +#define GL_ARB_texture_query_levels 1 +#endif /* GL_ARB_texture_query_levels */ + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod 1 +#endif /* GL_ARB_texture_query_lod */ + +#ifndef GL_ARB_texture_rectangle +#define GL_ARB_texture_rectangle 1 +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 +#endif /* GL_ARB_texture_rectangle */ + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 +#endif /* GL_ARB_texture_rg */ + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui 1 +#endif /* GL_ARB_texture_rgb10_a2ui */ + +#ifndef GL_ARB_texture_stencil8 +#define GL_ARB_texture_stencil8 1 +#endif /* GL_ARB_texture_stencil8 */ + +#ifndef GL_ARB_texture_storage +#define GL_ARB_texture_storage 1 +#endif /* GL_ARB_texture_storage */ + +#ifndef GL_ARB_texture_storage_multisample +#define GL_ARB_texture_storage_multisample 1 +#endif /* GL_ARB_texture_storage_multisample */ + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle 1 +#endif /* GL_ARB_texture_swizzle */ + +#ifndef GL_ARB_texture_view +#define GL_ARB_texture_view 1 +#endif /* GL_ARB_texture_view */ + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 +#endif /* GL_ARB_timer_query */ + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 1 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#endif /* GL_ARB_transform_feedback2 */ + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 1 +#endif /* GL_ARB_transform_feedback3 */ + +#ifndef GL_ARB_transform_feedback_instanced +#define GL_ARB_transform_feedback_instanced 1 +#endif /* GL_ARB_transform_feedback_instanced */ + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m); +GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m); +GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m); +GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); +#endif +#endif /* GL_ARB_transpose_matrix */ + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object 1 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#endif /* GL_ARB_uniform_buffer_object */ + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra 1 +#endif /* GL_ARB_vertex_array_bgra */ + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 +#endif /* GL_ARB_vertex_array_object */ + +#ifndef GL_ARB_vertex_attrib_64bit +#define GL_ARB_vertex_attrib_64bit 1 +#endif /* GL_ARB_vertex_attrib_64bit */ + +#ifndef GL_ARB_vertex_attrib_binding +#define GL_ARB_vertex_attrib_binding 1 +#endif /* GL_ARB_vertex_attrib_binding */ + +#ifndef GL_ARB_vertex_blend +#define GL_ARB_vertex_blend 1 +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); +typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); +typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); +typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); +typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); +typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); +typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); +typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights); +GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights); +GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights); +GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights); +GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights); +GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights); +GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights); +GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights); +GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glVertexBlendARB (GLint count); +#endif +#endif /* GL_ARB_vertex_blend */ + +#ifndef GL_ARB_vertex_buffer_object +#define GL_ARB_vertex_buffer_object 1 +#ifdef __MACOSX__ /* The OS X headers haven't caught up with Khronos yet */ +typedef long GLsizeiptrARB; +typedef long GLintptrARB; +#else +typedef ptrdiff_t GLsizeiptrARB; +typedef ptrdiff_t GLintptrARB; +#endif +#define GL_BUFFER_SIZE_ARB 0x8764 +#define GL_BUFFER_USAGE_ARB 0x8765 +#define GL_ARRAY_BUFFER_ARB 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 +#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F +#define GL_READ_ONLY_ARB 0x88B8 +#define GL_WRITE_ONLY_ARB 0x88B9 +#define GL_READ_WRITE_ARB 0x88BA +#define GL_BUFFER_ACCESS_ARB 0x88BB +#define GL_BUFFER_MAPPED_ARB 0x88BC +#define GL_BUFFER_MAP_POINTER_ARB 0x88BD +#define GL_STREAM_DRAW_ARB 0x88E0 +#define GL_STREAM_READ_ARB 0x88E1 +#define GL_STREAM_COPY_ARB 0x88E2 +#define GL_STATIC_DRAW_ARB 0x88E4 +#define GL_STATIC_READ_ARB 0x88E5 +#define GL_STATIC_COPY_ARB 0x88E6 +#define GL_DYNAMIC_DRAW_ARB 0x88E8 +#define GL_DYNAMIC_READ_ARB 0x88E9 +#define GL_DYNAMIC_COPY_ARB 0x88EA +typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); +typedef void *(APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer); +GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers); +GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers); +GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer); +GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); +GLAPI void *APIENTRY glMapBufferARB (GLenum target, GLenum access); +GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target); +GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_ARB_vertex_buffer_object */ + +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index); +GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index); +GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, void **pointer); +#endif +#endif /* GL_ARB_vertex_program */ + +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name); +GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name); +#endif +#endif /* GL_ARB_vertex_shader */ + +#ifndef GL_ARB_vertex_type_10f_11f_11f_rev +#define GL_ARB_vertex_type_10f_11f_11f_rev 1 +#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */ + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev 1 +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +#ifndef GL_ARB_viewport_array +#define GL_ARB_viewport_array 1 +#endif /* GL_ARB_viewport_array */ + +#ifndef GL_ARB_window_pos +#define GL_ARB_window_pos 1 +typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v); +GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v); +GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v); +GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); +#endif +#endif /* GL_ARB_window_pos */ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#endif /* GL_KHR_debug */ + +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif /* GL_KHR_texture_compression_astc_hdr */ + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif /* GL_KHR_texture_compression_astc_ldr */ + +#ifndef GL_OES_byte_coordinates +#define GL_OES_byte_coordinates 1 +typedef void (APIENTRYP PFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2BOESPROC) (GLenum texture, GLbyte s, GLbyte t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4BOESPROC) (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4BVOESPROC) (GLenum texture, const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD1BOESPROC) (GLbyte s); +typedef void (APIENTRYP PFNGLTEXCOORD1BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD2BOESPROC) (GLbyte s, GLbyte t); +typedef void (APIENTRYP PFNGLTEXCOORD2BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); +typedef void (APIENTRYP PFNGLTEXCOORD3BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); +typedef void (APIENTRYP PFNGLTEXCOORD4BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x); +typedef void (APIENTRYP PFNGLVERTEX2BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y); +typedef void (APIENTRYP PFNGLVERTEX3BVOESPROC) (const GLbyte *coords); +typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z); +typedef void (APIENTRYP PFNGLVERTEX4BVOESPROC) (const GLbyte *coords); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiTexCoord1bOES (GLenum texture, GLbyte s); +GLAPI void APIENTRY glMultiTexCoord1bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord2bOES (GLenum texture, GLbyte s, GLbyte t); +GLAPI void APIENTRY glMultiTexCoord2bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord3bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r); +GLAPI void APIENTRY glMultiTexCoord3bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glMultiTexCoord4bOES (GLenum texture, GLbyte s, GLbyte t, GLbyte r, GLbyte q); +GLAPI void APIENTRY glMultiTexCoord4bvOES (GLenum texture, const GLbyte *coords); +GLAPI void APIENTRY glTexCoord1bOES (GLbyte s); +GLAPI void APIENTRY glTexCoord1bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord2bOES (GLbyte s, GLbyte t); +GLAPI void APIENTRY glTexCoord2bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord3bOES (GLbyte s, GLbyte t, GLbyte r); +GLAPI void APIENTRY glTexCoord3bvOES (const GLbyte *coords); +GLAPI void APIENTRY glTexCoord4bOES (GLbyte s, GLbyte t, GLbyte r, GLbyte q); +GLAPI void APIENTRY glTexCoord4bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex2bOES (GLbyte x); +GLAPI void APIENTRY glVertex2bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y); +GLAPI void APIENTRY glVertex3bvOES (const GLbyte *coords); +GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z); +GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords); +#endif +#endif /* GL_OES_byte_coordinates */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif /* GL_OES_compressed_paletted_texture */ + +#ifndef GL_OES_fixed_point +#define GL_OES_fixed_point 1 +typedef GLint GLfixed; +#define GL_FIXED_OES 0x140C +typedef void (APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref); +typedef void (APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCLEARDEPTHXOESPROC) (GLfixed depth); +typedef void (APIENTRYP PFNGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed *equation); +typedef void (APIENTRYP PFNGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLDEPTHRANGEXOESPROC) (GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLFOGXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLFOGXVOESPROC) (GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLFRUSTUMXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLGETCLIPPLANEXOESPROC) (GLenum plane, GLfixed *equation); +typedef void (APIENTRYP PFNGLGETFIXEDVOESPROC) (GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXENVXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLLINEWIDTHXOESPROC) (GLfixed width); +typedef void (APIENTRYP PFNGLLOADMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed *param); +typedef void (APIENTRYP PFNGLMULTMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (APIENTRYP PFNGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz); +typedef void (APIENTRYP PFNGLORTHOXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +typedef void (APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size); +typedef void (APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); +typedef void (APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); +typedef void (APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLACCUMXOESPROC) (GLenum op, GLfixed value); +typedef void (APIENTRYP PFNGLBITMAPXOESPROC) (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); +typedef void (APIENTRYP PFNGLBLENDCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCLEARACCUMXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +typedef void (APIENTRYP PFNGLCOLOR3XOESPROC) (GLfixed red, GLfixed green, GLfixed blue); +typedef void (APIENTRYP PFNGLCOLOR3XVOESPROC) (const GLfixed *components); +typedef void (APIENTRYP PFNGLCOLOR4XVOESPROC) (const GLfixed *components); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLEVALCOORD1XOESPROC) (GLfixed u); +typedef void (APIENTRYP PFNGLEVALCOORD1XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLEVALCOORD2XOESPROC) (GLfixed u, GLfixed v); +typedef void (APIENTRYP PFNGLEVALCOORD2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLFEEDBACKBUFFERXOESPROC) (GLsizei n, GLenum type, const GLfixed *buffer); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETMAPXVOESPROC) (GLenum target, GLenum query, GLfixed *v); +typedef void (APIENTRYP PFNGLGETMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLGETPIXELMAPXVPROC) (GLenum map, GLint size, GLfixed *values); +typedef void (APIENTRYP PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERXVOESPROC) (GLenum target, GLint level, GLenum pname, GLfixed *params); +typedef void (APIENTRYP PFNGLINDEXXOESPROC) (GLfixed component); +typedef void (APIENTRYP PFNGLINDEXXVOESPROC) (const GLfixed *component); +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMAP1XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); +typedef void (APIENTRYP PFNGLMAP2XOESPROC) (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); +typedef void (APIENTRYP PFNGLMAPGRID1XOESPROC) (GLint n, GLfixed u1, GLfixed u2); +typedef void (APIENTRYP PFNGLMAPGRID2XOESPROC) (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXXOESPROC) (const GLfixed *m); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1XOESPROC) (GLenum texture, GLfixed s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2XOESPROC) (GLenum texture, GLfixed s, GLfixed t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4XVOESPROC) (GLenum texture, const GLfixed *coords); +typedef void (APIENTRYP PFNGLNORMAL3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLPASSTHROUGHXOESPROC) (GLfixed token); +typedef void (APIENTRYP PFNGLPIXELMAPXPROC) (GLenum map, GLint size, const GLfixed *values); +typedef void (APIENTRYP PFNGLPIXELSTOREXPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLPIXELTRANSFERXOESPROC) (GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLPIXELZOOMXOESPROC) (GLfixed xfactor, GLfixed yfactor); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESXOESPROC) (GLsizei n, const GLuint *textures, const GLfixed *priorities); +typedef void (APIENTRYP PFNGLRASTERPOS2XOESPROC) (GLfixed x, GLfixed y); +typedef void (APIENTRYP PFNGLRASTERPOS2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRASTERPOS3XOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLRASTERPOS3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRASTERPOS4XOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed w); +typedef void (APIENTRYP PFNGLRASTERPOS4XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLRECTXOESPROC) (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); +typedef void (APIENTRYP PFNGLRECTXVOESPROC) (const GLfixed *v1, const GLfixed *v2); +typedef void (APIENTRYP PFNGLTEXCOORD1XOESPROC) (GLfixed s); +typedef void (APIENTRYP PFNGLTEXCOORD1XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD2XOESPROC) (GLfixed s, GLfixed t); +typedef void (APIENTRYP PFNGLTEXCOORD2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD3XOESPROC) (GLfixed s, GLfixed t, GLfixed r); +typedef void (APIENTRYP PFNGLTEXCOORD3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXCOORD4XOESPROC) (GLfixed s, GLfixed t, GLfixed r, GLfixed q); +typedef void (APIENTRYP PFNGLTEXCOORD4XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param); +typedef void (APIENTRYP PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params); +typedef void (APIENTRYP PFNGLVERTEX2XOESPROC) (GLfixed x); +typedef void (APIENTRYP PFNGLVERTEX2XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLVERTEX3XOESPROC) (GLfixed x, GLfixed y); +typedef void (APIENTRYP PFNGLVERTEX3XVOESPROC) (const GLfixed *coords); +typedef void (APIENTRYP PFNGLVERTEX4XOESPROC) (GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLVERTEX4XVOESPROC) (const GLfixed *coords); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAlphaFuncxOES (GLenum func, GLfixed ref); +GLAPI void APIENTRY glClearColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glClearDepthxOES (GLfixed depth); +GLAPI void APIENTRY glClipPlanexOES (GLenum plane, const GLfixed *equation); +GLAPI void APIENTRY glColor4xOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glDepthRangexOES (GLfixed n, GLfixed f); +GLAPI void APIENTRY glFogxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glFogxvOES (GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glFrustumxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +GLAPI void APIENTRY glGetClipPlanexOES (GLenum plane, GLfixed *equation); +GLAPI void APIENTRY glGetFixedvOES (GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexEnvxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glLightModelxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glLightModelxvOES (GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glLightxOES (GLenum light, GLenum pname, GLfixed param); +GLAPI void APIENTRY glLightxvOES (GLenum light, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glLineWidthxOES (GLfixed width); +GLAPI void APIENTRY glLoadMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMaterialxOES (GLenum face, GLenum pname, GLfixed param); +GLAPI void APIENTRY glMaterialxvOES (GLenum face, GLenum pname, const GLfixed *param); +GLAPI void APIENTRY glMultMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMultiTexCoord4xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); +GLAPI void APIENTRY glNormal3xOES (GLfixed nx, GLfixed ny, GLfixed nz); +GLAPI void APIENTRY glOrthoxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); +GLAPI void APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glPointSizexOES (GLfixed size); +GLAPI void APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units); +GLAPI void APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glSampleCoverageOES (GLfixed value, GLboolean invert); +GLAPI void APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glTexParameterxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glTranslatexOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glAccumxOES (GLenum op, GLfixed value); +GLAPI void APIENTRY glBitmapxOES (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap); +GLAPI void APIENTRY glBlendColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glClearAccumxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); +GLAPI void APIENTRY glColor3xOES (GLfixed red, GLfixed green, GLfixed blue); +GLAPI void APIENTRY glColor3xvOES (const GLfixed *components); +GLAPI void APIENTRY glColor4xvOES (const GLfixed *components); +GLAPI void APIENTRY glConvolutionParameterxOES (GLenum target, GLenum pname, GLfixed param); +GLAPI void APIENTRY glConvolutionParameterxvOES (GLenum target, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glEvalCoord1xOES (GLfixed u); +GLAPI void APIENTRY glEvalCoord1xvOES (const GLfixed *coords); +GLAPI void APIENTRY glEvalCoord2xOES (GLfixed u, GLfixed v); +GLAPI void APIENTRY glEvalCoord2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glFeedbackBufferxOES (GLsizei n, GLenum type, const GLfixed *buffer); +GLAPI void APIENTRY glGetConvolutionParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetHistogramParameterxvOES (GLenum target, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetLightxOES (GLenum light, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetMapxvOES (GLenum target, GLenum query, GLfixed *v); +GLAPI void APIENTRY glGetMaterialxOES (GLenum face, GLenum pname, GLfixed param); +GLAPI void APIENTRY glGetPixelMapxv (GLenum map, GLint size, GLfixed *values); +GLAPI void APIENTRY glGetTexGenxvOES (GLenum coord, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glGetTexLevelParameterxvOES (GLenum target, GLint level, GLenum pname, GLfixed *params); +GLAPI void APIENTRY glIndexxOES (GLfixed component); +GLAPI void APIENTRY glIndexxvOES (const GLfixed *component); +GLAPI void APIENTRY glLoadTransposeMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMap1xOES (GLenum target, GLfixed u1, GLfixed u2, GLint stride, GLint order, GLfixed points); +GLAPI void APIENTRY glMap2xOES (GLenum target, GLfixed u1, GLfixed u2, GLint ustride, GLint uorder, GLfixed v1, GLfixed v2, GLint vstride, GLint vorder, GLfixed points); +GLAPI void APIENTRY glMapGrid1xOES (GLint n, GLfixed u1, GLfixed u2); +GLAPI void APIENTRY glMapGrid2xOES (GLint n, GLfixed u1, GLfixed u2, GLfixed v1, GLfixed v2); +GLAPI void APIENTRY glMultTransposeMatrixxOES (const GLfixed *m); +GLAPI void APIENTRY glMultiTexCoord1xOES (GLenum texture, GLfixed s); +GLAPI void APIENTRY glMultiTexCoord1xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord2xOES (GLenum texture, GLfixed s, GLfixed t); +GLAPI void APIENTRY glMultiTexCoord2xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord3xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r); +GLAPI void APIENTRY glMultiTexCoord3xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glMultiTexCoord4xvOES (GLenum texture, const GLfixed *coords); +GLAPI void APIENTRY glNormal3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glPassThroughxOES (GLfixed token); +GLAPI void APIENTRY glPixelMapx (GLenum map, GLint size, const GLfixed *values); +GLAPI void APIENTRY glPixelStorex (GLenum pname, GLfixed param); +GLAPI void APIENTRY glPixelTransferxOES (GLenum pname, GLfixed param); +GLAPI void APIENTRY glPixelZoomxOES (GLfixed xfactor, GLfixed yfactor); +GLAPI void APIENTRY glPrioritizeTexturesxOES (GLsizei n, const GLuint *textures, const GLfixed *priorities); +GLAPI void APIENTRY glRasterPos2xOES (GLfixed x, GLfixed y); +GLAPI void APIENTRY glRasterPos2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRasterPos3xOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glRasterPos3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRasterPos4xOES (GLfixed x, GLfixed y, GLfixed z, GLfixed w); +GLAPI void APIENTRY glRasterPos4xvOES (const GLfixed *coords); +GLAPI void APIENTRY glRectxOES (GLfixed x1, GLfixed y1, GLfixed x2, GLfixed y2); +GLAPI void APIENTRY glRectxvOES (const GLfixed *v1, const GLfixed *v2); +GLAPI void APIENTRY glTexCoord1xOES (GLfixed s); +GLAPI void APIENTRY glTexCoord1xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord2xOES (GLfixed s, GLfixed t); +GLAPI void APIENTRY glTexCoord2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord3xOES (GLfixed s, GLfixed t, GLfixed r); +GLAPI void APIENTRY glTexCoord3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexCoord4xOES (GLfixed s, GLfixed t, GLfixed r, GLfixed q); +GLAPI void APIENTRY glTexCoord4xvOES (const GLfixed *coords); +GLAPI void APIENTRY glTexGenxOES (GLenum coord, GLenum pname, GLfixed param); +GLAPI void APIENTRY glTexGenxvOES (GLenum coord, GLenum pname, const GLfixed *params); +GLAPI void APIENTRY glVertex2xOES (GLfixed x); +GLAPI void APIENTRY glVertex2xvOES (const GLfixed *coords); +GLAPI void APIENTRY glVertex3xOES (GLfixed x, GLfixed y); +GLAPI void APIENTRY glVertex3xvOES (const GLfixed *coords); +GLAPI void APIENTRY glVertex4xOES (GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glVertex4xvOES (const GLfixed *coords); +#endif +#endif /* GL_OES_fixed_point */ + +#ifndef GL_OES_query_matrix +#define GL_OES_query_matrix 1 +typedef GLbitfield (APIENTRYP PFNGLQUERYMATRIXXOESPROC) (GLfixed *mantissa, GLint *exponent); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLbitfield APIENTRY glQueryMatrixxOES (GLfixed *mantissa, GLint *exponent); +#endif +#endif /* GL_OES_query_matrix */ + +#ifndef GL_OES_read_format +#define GL_OES_read_format 1 +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#endif /* GL_OES_read_format */ + +#ifndef GL_OES_single_precision +#define GL_OES_single_precision 1 +typedef void (APIENTRYP PFNGLCLEARDEPTHFOESPROC) (GLclampf depth); +typedef void (APIENTRYP PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat *equation); +typedef void (APIENTRYP PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f); +typedef void (APIENTRYP PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +typedef void (APIENTRYP PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat *equation); +typedef void (APIENTRYP PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClearDepthfOES (GLclampf depth); +GLAPI void APIENTRY glClipPlanefOES (GLenum plane, const GLfloat *equation); +GLAPI void APIENTRY glDepthRangefOES (GLclampf n, GLclampf f); +GLAPI void APIENTRY glFrustumfOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +GLAPI void APIENTRY glGetClipPlanefOES (GLenum plane, GLfloat *equation); +GLAPI void APIENTRY glOrthofOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); +#endif +#endif /* GL_OES_single_precision */ + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif /* GL_3DFX_multisample */ + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask); +#endif +#endif /* GL_3DFX_tbuffer */ + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif /* GL_3DFX_texture_compression_FXT1 */ + +#ifndef GL_AMD_blend_minmax_factor +#define GL_AMD_blend_minmax_factor 1 +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FACTOR_MAX_AMD 0x901D +#endif /* GL_AMD_blend_minmax_factor */ + +#ifndef GL_AMD_conservative_depth +#define GL_AMD_conservative_depth 1 +#endif /* GL_AMD_conservative_depth */ + +#ifndef GL_AMD_debug_output +#define GL_AMD_debug_output 1 +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 +#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 +#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 +#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A +#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B +#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C +#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D +#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E +#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F +#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 +typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +#endif +#endif /* GL_AMD_debug_output */ + +#ifndef GL_AMD_depth_clamp_separate +#define GL_AMD_depth_clamp_separate 1 +#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E +#define GL_DEPTH_CLAMP_FAR_AMD 0x901F +#endif /* GL_AMD_depth_clamp_separate */ + +#ifndef GL_AMD_draw_buffers_blend +#define GL_AMD_draw_buffers_blend 1 +typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +#endif +#endif /* GL_AMD_draw_buffers_blend */ + +#ifndef GL_AMD_gcn_shader +#define GL_AMD_gcn_shader 1 +#endif /* GL_AMD_gcn_shader */ + +#ifndef GL_AMD_gpu_shader_int64 +#define GL_AMD_gpu_shader_int64 1 +typedef int64_t GLint64EXT; +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); +GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); +GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); +GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params); +GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); +GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); +GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#endif +#endif /* GL_AMD_gpu_shader_int64 */ + +#ifndef GL_AMD_interleaved_elements +#define GL_AMD_interleaved_elements 1 +#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 +#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5 +typedef void (APIENTRYP PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribParameteriAMD (GLuint index, GLenum pname, GLint param); +#endif +#endif /* GL_AMD_interleaved_elements */ + +#ifndef GL_AMD_multi_draw_indirect +#define GL_AMD_multi_draw_indirect 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const void *indirect, GLsizei primcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const void *indirect, GLsizei primcount, GLsizei stride); +#endif +#endif /* GL_AMD_multi_draw_indirect */ + +#ifndef GL_AMD_name_gen_delete +#define GL_AMD_name_gen_delete 1 +#define GL_DATA_BUFFER_AMD 0x9151 +#define GL_PERFORMANCE_MONITOR_AMD 0x9152 +#define GL_QUERY_OBJECT_AMD 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 +#define GL_SAMPLER_OBJECT_AMD 0x9155 +typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names); +typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names); +typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names); +GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names); +GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name); +#endif +#endif /* GL_AMD_name_gen_delete */ + +#ifndef GL_AMD_occlusion_query_event +#define GL_AMD_occlusion_query_event 1 +#define GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F +#define GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 +#define GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 +#define GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 +#define GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 +#define GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF +typedef void (APIENTRYP PFNGLQUERYOBJECTPARAMETERUIAMDPROC) (GLenum target, GLuint id, GLenum pname, GLuint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glQueryObjectParameteruiAMD (GLenum target, GLuint id, GLenum pname, GLuint param); +#endif +#endif /* GL_AMD_occlusion_query_event */ + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); +GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +#endif /* GL_AMD_performance_monitor */ + +#ifndef GL_AMD_pinned_memory +#define GL_AMD_pinned_memory 1 +#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160 +#endif /* GL_AMD_pinned_memory */ + +#ifndef GL_AMD_query_buffer_object +#define GL_AMD_query_buffer_object 1 +#define GL_QUERY_BUFFER_AMD 0x9192 +#define GL_QUERY_BUFFER_BINDING_AMD 0x9193 +#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194 +#endif /* GL_AMD_query_buffer_object */ + +#ifndef GL_AMD_sample_positions +#define GL_AMD_sample_positions 1 +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); +#endif +#endif /* GL_AMD_sample_positions */ + +#ifndef GL_AMD_seamless_cubemap_per_texture +#define GL_AMD_seamless_cubemap_per_texture 1 +#endif /* GL_AMD_seamless_cubemap_per_texture */ + +#ifndef GL_AMD_shader_atomic_counter_ops +#define GL_AMD_shader_atomic_counter_ops 1 +#endif /* GL_AMD_shader_atomic_counter_ops */ + +#ifndef GL_AMD_shader_stencil_export +#define GL_AMD_shader_stencil_export 1 +#endif /* GL_AMD_shader_stencil_export */ + +#ifndef GL_AMD_shader_trinary_minmax +#define GL_AMD_shader_trinary_minmax 1 +#endif /* GL_AMD_shader_trinary_minmax */ + +#ifndef GL_AMD_sparse_texture +#define GL_AMD_sparse_texture 1 +#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197 +#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A +#define GL_MIN_SPARSE_LEVEL_AMD 0x919B +#define GL_MIN_LOD_WARNING_AMD 0x919C +#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001 +typedef void (APIENTRYP PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +typedef void (APIENTRYP PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexStorageSparseAMD (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +GLAPI void APIENTRY glTextureStorageSparseAMD (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags); +#endif +#endif /* GL_AMD_sparse_texture */ + +#ifndef GL_AMD_stencil_operation_extended +#define GL_AMD_stencil_operation_extended 1 +#define GL_SET_AMD 0x874A +#define GL_REPLACE_VALUE_AMD 0x874B +#define GL_STENCIL_OP_VALUE_AMD 0x874C +#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D +typedef void (APIENTRYP PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value); +#endif +#endif /* GL_AMD_stencil_operation_extended */ + +#ifndef GL_AMD_texture_texture4 +#define GL_AMD_texture_texture4 1 +#endif /* GL_AMD_texture_texture4 */ + +#ifndef GL_AMD_transform_feedback3_lines_triangles +#define GL_AMD_transform_feedback3_lines_triangles 1 +#endif /* GL_AMD_transform_feedback3_lines_triangles */ + +#ifndef GL_AMD_transform_feedback4 +#define GL_AMD_transform_feedback4 1 +#define GL_STREAM_RASTERIZATION_AMD 0x91A0 +#endif /* GL_AMD_transform_feedback4 */ + +#ifndef GL_AMD_vertex_shader_layer +#define GL_AMD_vertex_shader_layer 1 +#endif /* GL_AMD_vertex_shader_layer */ + +#ifndef GL_AMD_vertex_shader_tessellator +#define GL_AMD_vertex_shader_tessellator 1 +#define GL_SAMPLER_BUFFER_AMD 0x9001 +#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 +#define GL_TESSELLATION_MODE_AMD 0x9004 +#define GL_TESSELLATION_FACTOR_AMD 0x9005 +#define GL_DISCRETE_AMD 0x9006 +#define GL_CONTINUOUS_AMD 0x9007 +typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor); +GLAPI void APIENTRY glTessellationModeAMD (GLenum mode); +#endif +#endif /* GL_AMD_vertex_shader_tessellator */ + +#ifndef GL_AMD_vertex_shader_viewport_index +#define GL_AMD_vertex_shader_viewport_index 1 +#endif /* GL_AMD_vertex_shader_viewport_index */ + +#ifndef GL_APPLE_aux_depth_stencil +#define GL_APPLE_aux_depth_stencil 1 +#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 +#endif /* GL_APPLE_aux_depth_stencil */ + +#ifndef GL_APPLE_client_storage +#define GL_APPLE_client_storage 1 +#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 +#endif /* GL_APPLE_client_storage */ + +#ifndef GL_APPLE_element_array +#define GL_APPLE_element_array 1 +#define GL_ELEMENT_ARRAY_APPLE 0x8A0C +#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D +#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E +typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const void *pointer); +GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count); +GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); +GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); +#endif +#endif /* GL_APPLE_element_array */ + +#ifndef GL_APPLE_fence +#define GL_APPLE_fence 1 +#define GL_DRAW_PIXELS_APPLE 0x8A0A +#define GL_FENCE_APPLE 0x8A0B +typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); +typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); +typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences); +GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences); +GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence); +GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence); +GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name); +GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name); +#endif +#endif /* GL_APPLE_fence */ + +#ifndef GL_APPLE_float_pixels +#define GL_APPLE_float_pixels 1 +#define GL_HALF_APPLE 0x140B +#define GL_RGBA_FLOAT32_APPLE 0x8814 +#define GL_RGB_FLOAT32_APPLE 0x8815 +#define GL_ALPHA_FLOAT32_APPLE 0x8816 +#define GL_INTENSITY_FLOAT32_APPLE 0x8817 +#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 +#define GL_RGBA_FLOAT16_APPLE 0x881A +#define GL_RGB_FLOAT16_APPLE 0x881B +#define GL_ALPHA_FLOAT16_APPLE 0x881C +#define GL_INTENSITY_FLOAT16_APPLE 0x881D +#define GL_LUMINANCE_FLOAT16_APPLE 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F +#define GL_COLOR_FLOAT_APPLE 0x8A0F +#endif /* GL_APPLE_float_pixels */ + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size); +#endif +#endif /* GL_APPLE_flush_buffer_range */ + +#ifndef GL_APPLE_object_purgeable +#define GL_APPLE_object_purgeable 1 +#define GL_BUFFER_OBJECT_APPLE 0x85B3 +#define GL_RELEASED_APPLE 0x8A19 +#define GL_VOLATILE_APPLE 0x8A1A +#define GL_RETAINED_APPLE 0x8A1B +#define GL_UNDEFINED_APPLE 0x8A1C +#define GL_PURGEABLE_APPLE 0x8A1D +typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); +typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); +GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); +GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params); +#endif +#endif /* GL_APPLE_object_purgeable */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_RAW_422_APPLE 0x8A51 +#endif /* GL_APPLE_rgb_422 */ + +#ifndef GL_APPLE_row_bytes +#define GL_APPLE_row_bytes 1 +#define GL_PACK_ROW_BYTES_APPLE 0x8A15 +#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 +#endif /* GL_APPLE_row_bytes */ + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif /* GL_APPLE_specular_vector */ + +#ifndef GL_APPLE_texture_range +#define GL_APPLE_texture_range 1 +#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 +#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_STORAGE_PRIVATE_APPLE 0x85BD +#define GL_STORAGE_CACHED_APPLE 0x85BE +#define GL_STORAGE_SHARED_APPLE 0x85BF +typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const void *pointer); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const void *pointer); +GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_APPLE_texture_range */ + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif /* GL_APPLE_transform_hint */ + +#ifndef GL_APPLE_vertex_array_object +#define GL_APPLE_vertex_array_object 1 +#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array); +GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays); +GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays); +GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array); +#endif +#endif /* GL_APPLE_vertex_array_object */ + +#ifndef GL_APPLE_vertex_array_range +#define GL_APPLE_vertex_array_range 1 +#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E +#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F +#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 +#define GL_STORAGE_CLIENT_APPLE 0x85B4 +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); +typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, void *pointer); +GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, void *pointer); +GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param); +#endif +#endif /* GL_APPLE_vertex_array_range */ + +#ifndef GL_APPLE_vertex_program_evaluators +#define GL_APPLE_vertex_program_evaluators 1 +#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 +#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 +#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 +#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 +#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 +#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 +#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 +#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 +#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 +#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); +typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname); +GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname); +GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname); +GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +#endif +#endif /* GL_APPLE_vertex_program_evaluators */ + +#ifndef GL_APPLE_ycbcr_422 +#define GL_APPLE_ycbcr_422 1 +#define GL_YCBCR_422_APPLE 0x85B9 +#endif /* GL_APPLE_ycbcr_422 */ + +#ifndef GL_ATI_draw_buffers +#define GL_ATI_draw_buffers 1 +#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 +#define GL_DRAW_BUFFER0_ATI 0x8825 +#define GL_DRAW_BUFFER1_ATI 0x8826 +#define GL_DRAW_BUFFER2_ATI 0x8827 +#define GL_DRAW_BUFFER3_ATI 0x8828 +#define GL_DRAW_BUFFER4_ATI 0x8829 +#define GL_DRAW_BUFFER5_ATI 0x882A +#define GL_DRAW_BUFFER6_ATI 0x882B +#define GL_DRAW_BUFFER7_ATI 0x882C +#define GL_DRAW_BUFFER8_ATI 0x882D +#define GL_DRAW_BUFFER9_ATI 0x882E +#define GL_DRAW_BUFFER10_ATI 0x882F +#define GL_DRAW_BUFFER11_ATI 0x8830 +#define GL_DRAW_BUFFER12_ATI 0x8831 +#define GL_DRAW_BUFFER13_ATI 0x8832 +#define GL_DRAW_BUFFER14_ATI 0x8833 +#define GL_DRAW_BUFFER15_ATI 0x8834 +typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_ATI_draw_buffers */ + +#ifndef GL_ATI_element_array +#define GL_ATI_element_array 1 +#define GL_ELEMENT_ARRAY_ATI 0x8768 +#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 +#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A +typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glElementPointerATI (GLenum type, const void *pointer); +GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count); +GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count); +#endif +#endif /* GL_ATI_element_array */ + +#ifndef GL_ATI_envmap_bumpmap +#define GL_ATI_envmap_bumpmap 1 +#define GL_BUMP_ROT_MATRIX_ATI 0x8775 +#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 +#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 +#define GL_BUMP_TEX_UNITS_ATI 0x8778 +#define GL_DUDV_ATI 0x8779 +#define GL_DU8DV8_ATI 0x877A +#define GL_BUMP_ENVMAP_ATI 0x877B +#define GL_BUMP_TARGET_ATI 0x877C +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param); +GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param); +GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param); +#endif +#endif /* GL_ATI_envmap_bumpmap */ + +#ifndef GL_ATI_fragment_shader +#define GL_ATI_fragment_shader 1 +#define GL_FRAGMENT_SHADER_ATI 0x8920 +#define GL_REG_0_ATI 0x8921 +#define GL_REG_1_ATI 0x8922 +#define GL_REG_2_ATI 0x8923 +#define GL_REG_3_ATI 0x8924 +#define GL_REG_4_ATI 0x8925 +#define GL_REG_5_ATI 0x8926 +#define GL_REG_6_ATI 0x8927 +#define GL_REG_7_ATI 0x8928 +#define GL_REG_8_ATI 0x8929 +#define GL_REG_9_ATI 0x892A +#define GL_REG_10_ATI 0x892B +#define GL_REG_11_ATI 0x892C +#define GL_REG_12_ATI 0x892D +#define GL_REG_13_ATI 0x892E +#define GL_REG_14_ATI 0x892F +#define GL_REG_15_ATI 0x8930 +#define GL_REG_16_ATI 0x8931 +#define GL_REG_17_ATI 0x8932 +#define GL_REG_18_ATI 0x8933 +#define GL_REG_19_ATI 0x8934 +#define GL_REG_20_ATI 0x8935 +#define GL_REG_21_ATI 0x8936 +#define GL_REG_22_ATI 0x8937 +#define GL_REG_23_ATI 0x8938 +#define GL_REG_24_ATI 0x8939 +#define GL_REG_25_ATI 0x893A +#define GL_REG_26_ATI 0x893B +#define GL_REG_27_ATI 0x893C +#define GL_REG_28_ATI 0x893D +#define GL_REG_29_ATI 0x893E +#define GL_REG_30_ATI 0x893F +#define GL_REG_31_ATI 0x8940 +#define GL_CON_0_ATI 0x8941 +#define GL_CON_1_ATI 0x8942 +#define GL_CON_2_ATI 0x8943 +#define GL_CON_3_ATI 0x8944 +#define GL_CON_4_ATI 0x8945 +#define GL_CON_5_ATI 0x8946 +#define GL_CON_6_ATI 0x8947 +#define GL_CON_7_ATI 0x8948 +#define GL_CON_8_ATI 0x8949 +#define GL_CON_9_ATI 0x894A +#define GL_CON_10_ATI 0x894B +#define GL_CON_11_ATI 0x894C +#define GL_CON_12_ATI 0x894D +#define GL_CON_13_ATI 0x894E +#define GL_CON_14_ATI 0x894F +#define GL_CON_15_ATI 0x8950 +#define GL_CON_16_ATI 0x8951 +#define GL_CON_17_ATI 0x8952 +#define GL_CON_18_ATI 0x8953 +#define GL_CON_19_ATI 0x8954 +#define GL_CON_20_ATI 0x8955 +#define GL_CON_21_ATI 0x8956 +#define GL_CON_22_ATI 0x8957 +#define GL_CON_23_ATI 0x8958 +#define GL_CON_24_ATI 0x8959 +#define GL_CON_25_ATI 0x895A +#define GL_CON_26_ATI 0x895B +#define GL_CON_27_ATI 0x895C +#define GL_CON_28_ATI 0x895D +#define GL_CON_29_ATI 0x895E +#define GL_CON_30_ATI 0x895F +#define GL_CON_31_ATI 0x8960 +#define GL_MOV_ATI 0x8961 +#define GL_ADD_ATI 0x8963 +#define GL_MUL_ATI 0x8964 +#define GL_SUB_ATI 0x8965 +#define GL_DOT3_ATI 0x8966 +#define GL_DOT4_ATI 0x8967 +#define GL_MAD_ATI 0x8968 +#define GL_LERP_ATI 0x8969 +#define GL_CND_ATI 0x896A +#define GL_CND0_ATI 0x896B +#define GL_DOT2_ADD_ATI 0x896C +#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D +#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E +#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F +#define GL_NUM_PASSES_ATI 0x8970 +#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 +#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 +#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 +#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 +#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 +#define GL_SWIZZLE_STR_ATI 0x8976 +#define GL_SWIZZLE_STQ_ATI 0x8977 +#define GL_SWIZZLE_STR_DR_ATI 0x8978 +#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 +#define GL_SWIZZLE_STRQ_ATI 0x897A +#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B +#define GL_RED_BIT_ATI 0x00000001 +#define GL_GREEN_BIT_ATI 0x00000002 +#define GL_BLUE_BIT_ATI 0x00000004 +#define GL_2X_BIT_ATI 0x00000001 +#define GL_4X_BIT_ATI 0x00000002 +#define GL_8X_BIT_ATI 0x00000004 +#define GL_HALF_BIT_ATI 0x00000008 +#define GL_QUARTER_BIT_ATI 0x00000010 +#define GL_EIGHTH_BIT_ATI 0x00000020 +#define GL_SATURATE_BIT_ATI 0x00000040 +#define GL_COMP_BIT_ATI 0x00000002 +#define GL_NEGATE_BIT_ATI 0x00000004 +#define GL_BIAS_BIT_ATI 0x00000008 +typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); +typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); +typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); +typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range); +GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id); +GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id); +GLAPI void APIENTRY glBeginFragmentShaderATI (void); +GLAPI void APIENTRY glEndFragmentShaderATI (void); +GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle); +GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle); +GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); +GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); +GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); +GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value); +#endif +#endif /* GL_ATI_fragment_shader */ + +#ifndef GL_ATI_map_object_buffer +#define GL_ATI_map_object_buffer 1 +typedef void *(APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void *APIENTRY glMapObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer); +#endif +#endif /* GL_ATI_map_object_buffer */ + +#ifndef GL_ATI_meminfo +#define GL_ATI_meminfo 1 +#define GL_VBO_FREE_MEMORY_ATI 0x87FB +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC +#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD +#endif /* GL_ATI_meminfo */ + +#ifndef GL_ATI_pixel_format_float +#define GL_ATI_pixel_format_float 1 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#endif /* GL_ATI_pixel_format_float */ + +#ifndef GL_ATI_pn_triangles +#define GL_ATI_pn_triangles 1 +#define GL_PN_TRIANGLES_ATI 0x87F0 +#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 +#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 +#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 +#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 +#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 +#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 +#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 +#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 +typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param); +GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param); +#endif +#endif /* GL_ATI_pn_triangles */ + +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); +#endif +#endif /* GL_ATI_separate_stencil */ + +#ifndef GL_ATI_text_fragment_shader +#define GL_ATI_text_fragment_shader 1 +#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 +#endif /* GL_ATI_text_fragment_shader */ + +#ifndef GL_ATI_texture_env_combine3 +#define GL_ATI_texture_env_combine3 1 +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 +#endif /* GL_ATI_texture_env_combine3 */ + +#ifndef GL_ATI_texture_float +#define GL_ATI_texture_float 1 +#define GL_RGBA_FLOAT32_ATI 0x8814 +#define GL_RGB_FLOAT32_ATI 0x8815 +#define GL_ALPHA_FLOAT32_ATI 0x8816 +#define GL_INTENSITY_FLOAT32_ATI 0x8817 +#define GL_LUMINANCE_FLOAT32_ATI 0x8818 +#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 +#define GL_RGBA_FLOAT16_ATI 0x881A +#define GL_RGB_FLOAT16_ATI 0x881B +#define GL_ALPHA_FLOAT16_ATI 0x881C +#define GL_INTENSITY_FLOAT16_ATI 0x881D +#define GL_LUMINANCE_FLOAT16_ATI 0x881E +#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F +#endif /* GL_ATI_texture_float */ + +#ifndef GL_ATI_texture_mirror_once +#define GL_ATI_texture_mirror_once 1 +#define GL_MIRROR_CLAMP_ATI 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 +#endif /* GL_ATI_texture_mirror_once */ + +#ifndef GL_ATI_vertex_array_object +#define GL_ATI_vertex_array_object 1 +#define GL_STATIC_ATI 0x8760 +#define GL_DYNAMIC_ATI 0x8761 +#define GL_PRESERVE_ATI 0x8762 +#define GL_DISCARD_ATI 0x8763 +#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 +#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 +#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 +#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 +typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const void *pointer, GLenum usage); +typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const void *pointer, GLenum usage); +GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const void *pointer, GLenum preserve); +GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer); +GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params); +GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params); +#endif +#endif /* GL_ATI_vertex_array_object */ + +#ifndef GL_ATI_vertex_attrib_array_object +#define GL_ATI_vertex_attrib_array_object 1 +typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); +GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params); +#endif +#endif /* GL_ATI_vertex_attrib_array_object */ + +#ifndef GL_ATI_vertex_streams +#define GL_ATI_vertex_streams 1 +#define GL_MAX_VERTEX_STREAMS_ATI 0x876B +#define GL_VERTEX_STREAM0_ATI 0x876C +#define GL_VERTEX_STREAM1_ATI 0x876D +#define GL_VERTEX_STREAM2_ATI 0x876E +#define GL_VERTEX_STREAM3_ATI 0x876F +#define GL_VERTEX_STREAM4_ATI 0x8770 +#define GL_VERTEX_STREAM5_ATI 0x8771 +#define GL_VERTEX_STREAM6_ATI 0x8772 +#define GL_VERTEX_STREAM7_ATI 0x8773 +#define GL_VERTEX_SOURCE_ATI 0x8774 +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); +typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x); +GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x); +GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x); +GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x); +GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y); +GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords); +GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz); +GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords); +GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz); +GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords); +GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords); +GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords); +GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream); +GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param); +GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); +#endif +#endif /* GL_ATI_vertex_streams */ + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif /* GL_EXT_422_pixels */ + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#define GL_ABGR_EXT 0x8000 +#endif /* GL_EXT_abgr */ + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif /* GL_EXT_bgra */ + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); +typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); +GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); +GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); +#endif +#endif /* GL_EXT_bindable_uniform */ + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendColorEXT (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +#endif +#endif /* GL_EXT_blend_color */ + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 1 +#define GL_BLEND_EQUATION_RGB_EXT 0x8009 +#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha); +#endif +#endif /* GL_EXT_blend_equation_separate */ + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif +#endif /* GL_EXT_blend_func_separate */ + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif /* GL_EXT_blend_logic_op */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_BLEND_EQUATION_EXT 0x8009 +typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendEquationEXT (GLenum mode); +#endif +#endif /* GL_EXT_blend_minmax */ + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif /* GL_EXT_blend_subtract */ + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif /* GL_EXT_clip_volume_hint */ + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif /* GL_EXT_cmyka */ + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif +#endif /* GL_EXT_color_subtable */ + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count); +GLAPI void APIENTRY glUnlockArraysEXT (void); +#endif +#endif /* GL_EXT_compiled_vertex_array */ + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *image); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *image); +GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params); +GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params); +GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, void *image); +GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, void *row, void *column, void *span); +GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *row, const void *column); +#endif +#endif /* GL_EXT_convolution */ + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz); +GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz); +GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz); +GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz); +GLAPI void APIENTRY glTangent3ivEXT (const GLint *v); +GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz); +GLAPI void APIENTRY glTangent3svEXT (const GLshort *v); +GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz); +GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz); +GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz); +GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz); +GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v); +GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz); +GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v); +GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_coordinate_frame */ + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_EXT_copy_texture */ + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params); +GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_cull_vertex */ + +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +typedef void (APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +#endif /* GL_EXT_debug_label */ + +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +typedef void (APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GLAPI void APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GLAPI void APIENTRY glPopGroupMarkerEXT (void); +#endif +#endif /* GL_EXT_debug_marker */ + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 1 +#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 +#define GL_DEPTH_BOUNDS_EXT 0x8891 +typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax); +#endif +#endif /* GL_EXT_depth_bounds_test */ + +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 +#define GL_PROGRAM_MATRIX_EXT 0x8E2D +#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E +#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F +typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); +typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); +typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void **data); +typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, void *img); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, void *img); +typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void **params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index); +typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array); +typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void **param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode); +GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glMatrixPopEXT (GLenum mode); +GLAPI void APIENTRY glMatrixPushEXT (GLenum mode); +GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask); +GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask); +GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture); +GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); +GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params); +GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data); +GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data); +GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, void **data); +GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index); +GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index); +GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); +GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); +GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); +GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, void *img); +GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); +GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, void *img); +GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); +GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void *APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access); +GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer); +GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, void **params); +GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); +GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); +GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); +GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params); +GLAPI void APIENTRY glEnableClientStateiEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glDisableClientStateiEXT (GLenum array, GLuint index); +GLAPI void APIENTRY glGetFloati_vEXT (GLenum pname, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetDoublei_vEXT (GLenum pname, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetPointeri_vEXT (GLenum pname, GLuint index, void **params); +GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string); +GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params); +GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params); +GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params); +GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, void *string); +GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target); +GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target); +GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target); +GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode); +GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode); +GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glVertexArrayVertexOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayEdgeFlagOffsetEXT (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayIndexOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayNormalOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayMultiTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayFogCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArraySecondaryColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayVertexAttribOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glVertexArrayVertexAttribIOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glEnableVertexArrayEXT (GLuint vaobj, GLenum array); +GLAPI void APIENTRY glDisableVertexArrayEXT (GLuint vaobj, GLenum array); +GLAPI void APIENTRY glEnableVertexArrayAttribEXT (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glDisableVertexArrayAttribEXT (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glGetVertexArrayIntegervEXT (GLuint vaobj, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayPointervEXT (GLuint vaobj, GLenum pname, void **param); +GLAPI void APIENTRY glGetVertexArrayIntegeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayPointeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, void **param); +GLAPI void *APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glNamedBufferStorageEXT (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +GLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param); +GLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x); +GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y); +GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); +GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +GLAPI void APIENTRY glVertexArrayVertexAttribDivisorEXT (GLuint vaobj, GLuint index, GLuint divisor); +#endif +#endif /* GL_EXT_direct_state_access */ + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 +typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +#endif +#endif /* GL_EXT_draw_buffers2 */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_EXT_draw_instanced */ + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +#endif +#endif /* GL_EXT_draw_range_elements */ + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord); +GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord); +GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord); +GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord); +GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_fog_coord */ + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_EXT_framebuffer_blit */ + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_EXT_framebuffer_multisample */ + +#ifndef GL_EXT_framebuffer_multisample_blit_scaled +#define GL_EXT_framebuffer_multisample_blit_scaled 1 +#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB +#endif /* GL_EXT_framebuffer_multisample_blit_scaled */ + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer); +GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers); +GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer); +GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers); +GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers); +GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target); +GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target); +#endif +#endif /* GL_EXT_framebuffer_object */ + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif /* GL_EXT_framebuffer_sRGB */ + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +#endif +#endif /* GL_EXT_geometry_shader4 */ + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +#endif +#endif /* GL_EXT_gpu_program_parameters */ + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); +GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); +GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0); +GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); +#endif +#endif /* GL_EXT_gpu_shader4 */ + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, void *values); +GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink); +GLAPI void APIENTRY glResetHistogramEXT (GLenum target); +GLAPI void APIENTRY glResetMinmaxEXT (GLenum target); +#endif +#endif /* GL_EXT_histogram */ + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif /* GL_EXT_index_array_formats */ + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref); +#endif +#endif /* GL_EXT_index_func */ + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode); +#endif +#endif /* GL_EXT_index_material */ + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif /* GL_EXT_index_texture */ + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glApplyTextureEXT (GLenum mode); +GLAPI void APIENTRY glTextureLightEXT (GLenum pname); +GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); +#endif +#endif /* GL_EXT_light_texture */ + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif /* GL_EXT_misc_attribute */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#endif +#endif /* GL_EXT_multi_draw_arrays */ + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#define GL_MULTISAMPLE_BIT_EXT 0x20000000 +typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert); +GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern); +#endif +#endif /* GL_EXT_multisample */ + +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#endif /* GL_EXT_packed_depth_stencil */ + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif /* GL_EXT_packed_float */ + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif /* GL_EXT_packed_pixels */ + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void *data); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, void *data); +GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_paletted_texture */ + +#ifndef GL_EXT_pixel_buffer_object +#define GL_EXT_pixel_buffer_object 1 +#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF +#endif /* GL_EXT_pixel_buffer_object */ + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetPixelTransformParameterivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetPixelTransformParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_EXT_pixel_transform */ + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif /* GL_EXT_pixel_transform_color_table */ + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_EXT_point_parameters */ + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); +#endif +#endif /* GL_EXT_polygon_offset */ + +#ifndef GL_EXT_provoking_vertex +#define GL_EXT_provoking_vertex 1 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_PROVOKING_VERTEX_EXT 0x8E4F +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); +#endif +#endif /* GL_EXT_provoking_vertex */ + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif /* GL_EXT_rescale_normal */ + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue); +GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v); +GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue); +GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v); +GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue); +GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v); +GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue); +GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v); +GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue); +GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v); +GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue); +GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v); +GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue); +GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v); +GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue); +GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v); +GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_secondary_color */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#define GL_ACTIVE_PROGRAM_EXT 0x8B8D +typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); +typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program); +GLAPI void APIENTRY glActiveProgramEXT (GLuint program); +GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string); +#endif +#endif /* GL_EXT_separate_shader_objects */ + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif /* GL_EXT_separate_specular_color */ + +#ifndef GL_EXT_shader_image_load_formatted +#define GL_EXT_shader_image_load_formatted 1 +#endif /* GL_EXT_shader_image_load_formatted */ + +#ifndef GL_EXT_shader_image_load_store +#define GL_EXT_shader_image_load_store 1 +#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 +#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A +#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B +#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C +#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D +#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E +#define GL_IMAGE_1D_EXT 0x904C +#define GL_IMAGE_2D_EXT 0x904D +#define GL_IMAGE_3D_EXT 0x904E +#define GL_IMAGE_2D_RECT_EXT 0x904F +#define GL_IMAGE_CUBE_EXT 0x9050 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_IMAGE_1D_ARRAY_EXT 0x9052 +#define GL_IMAGE_2D_ARRAY_EXT 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 +#define GL_INT_IMAGE_1D_EXT 0x9057 +#define GL_INT_IMAGE_2D_EXT 0x9058 +#define GL_INT_IMAGE_3D_EXT 0x9059 +#define GL_INT_IMAGE_2D_RECT_EXT 0x905A +#define GL_INT_IMAGE_CUBE_EXT 0x905B +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D +#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C +#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D +#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 +#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 +#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF +typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); +GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); +#endif +#endif /* GL_EXT_shader_image_load_store */ + +#ifndef GL_EXT_shader_integer_mix +#define GL_EXT_shader_integer_mix 1 +#endif /* GL_EXT_shader_integer_mix */ + +#ifndef GL_EXT_shadow_funcs +#define GL_EXT_shadow_funcs 1 +#endif /* GL_EXT_shadow_funcs */ + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif /* GL_EXT_shared_texture_palette */ + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag); +#endif +#endif /* GL_EXT_stencil_clear_tag */ + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face); +#endif +#endif /* GL_EXT_stencil_two_side */ + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif /* GL_EXT_stencil_wrap */ + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_EXT_subtexture */ + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif /* GL_EXT_texture */ + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_EXT_texture3D */ + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +#endif /* GL_EXT_texture_array */ + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); +#endif +#endif /* GL_EXT_texture_buffer_object */ + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif /* GL_EXT_texture_compression_latc */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif /* GL_EXT_texture_compression_rgtc */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifndef GL_EXT_texture_cube_map +#define GL_EXT_texture_cube_map 1 +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif /* GL_EXT_texture_cube_map */ + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif /* GL_EXT_texture_env_add */ + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif /* GL_EXT_texture_env_combine */ + +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif /* GL_EXT_texture_env_dot3 */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); +GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif +#endif /* GL_EXT_texture_integer */ + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif /* GL_EXT_texture_lod_bias */ + +#ifndef GL_EXT_texture_mirror_clamp +#define GL_EXT_texture_mirror_clamp 1 +#define GL_MIRROR_CLAMP_EXT 0x8742 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 +#endif /* GL_EXT_texture_mirror_clamp */ + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture); +GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures); +GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures); +GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture); +GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif +#endif /* GL_EXT_texture_object */ + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); +#endif +#endif /* GL_EXT_texture_perturb_normal */ + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif /* GL_EXT_texture_sRGB */ + +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif /* GL_EXT_texture_sRGB_decode */ + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif /* GL_EXT_texture_shared_exponent */ + +#ifndef GL_EXT_texture_snorm +#define GL_EXT_texture_snorm 1 +#define GL_ALPHA_SNORM 0x9010 +#define GL_LUMINANCE_SNORM 0x9011 +#define GL_LUMINANCE_ALPHA_SNORM 0x9012 +#define GL_INTENSITY_SNORM 0x9013 +#define GL_ALPHA8_SNORM 0x9014 +#define GL_LUMINANCE8_SNORM 0x9015 +#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 +#define GL_INTENSITY8_SNORM 0x9017 +#define GL_ALPHA16_SNORM 0x9018 +#define GL_LUMINANCE16_SNORM 0x9019 +#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A +#define GL_INTENSITY16_SNORM 0x901B +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#endif /* GL_EXT_texture_snorm */ + +#ifndef GL_EXT_texture_swizzle +#define GL_EXT_texture_swizzle 1 +#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 +#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 +#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 +#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 +#endif /* GL_EXT_texture_swizzle */ + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 +#define GL_TIME_ELAPSED_EXT 0x88BF +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +#endif +#endif /* GL_EXT_timer_query */ + +#ifndef GL_EXT_transform_feedback +#define GL_EXT_transform_feedback 1 +#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F +#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C +#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 +#define GL_RASTERIZER_DISCARD_EXT 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedbackEXT (void); +GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +#endif +#endif /* GL_EXT_transform_feedback */ + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, void **params); +typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glArrayElementEXT (GLint i); +GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count); +GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer); +GLAPI void APIENTRY glGetPointervEXT (GLenum pname, void **params); +GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const void *pointer); +#endif +#endif /* GL_EXT_vertex_array */ + +#ifndef GL_EXT_vertex_array_bgra +#define GL_EXT_vertex_array_bgra 1 +#endif /* GL_EXT_vertex_array_bgra */ + +#ifndef GL_EXT_vertex_attrib_64bit +#define GL_EXT_vertex_attrib_64bit 1 +#define GL_DOUBLE_VEC2_EXT 0x8FFC +#define GL_DOUBLE_VEC3_EXT 0x8FFD +#define GL_DOUBLE_VEC4_EXT 0x8FFE +#define GL_DOUBLE_MAT2_EXT 0x8F46 +#define GL_DOUBLE_MAT3_EXT 0x8F47 +#define GL_DOUBLE_MAT4_EXT 0x8F48 +#define GL_DOUBLE_MAT2x3_EXT 0x8F49 +#define GL_DOUBLE_MAT2x4_EXT 0x8F4A +#define GL_DOUBLE_MAT3x2_EXT 0x8F4B +#define GL_DOUBLE_MAT3x4_EXT 0x8F4C +#define GL_DOUBLE_MAT4x2_EXT 0x8F4D +#define GL_DOUBLE_MAT4x3_EXT 0x8F4E +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params); +#endif +#endif /* GL_EXT_vertex_attrib_64bit */ + +#ifndef GL_EXT_vertex_shader +#define GL_EXT_vertex_shader 1 +#define GL_VERTEX_SHADER_EXT 0x8780 +#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 +#define GL_OP_INDEX_EXT 0x8782 +#define GL_OP_NEGATE_EXT 0x8783 +#define GL_OP_DOT3_EXT 0x8784 +#define GL_OP_DOT4_EXT 0x8785 +#define GL_OP_MUL_EXT 0x8786 +#define GL_OP_ADD_EXT 0x8787 +#define GL_OP_MADD_EXT 0x8788 +#define GL_OP_FRAC_EXT 0x8789 +#define GL_OP_MAX_EXT 0x878A +#define GL_OP_MIN_EXT 0x878B +#define GL_OP_SET_GE_EXT 0x878C +#define GL_OP_SET_LT_EXT 0x878D +#define GL_OP_CLAMP_EXT 0x878E +#define GL_OP_FLOOR_EXT 0x878F +#define GL_OP_ROUND_EXT 0x8790 +#define GL_OP_EXP_BASE_2_EXT 0x8791 +#define GL_OP_LOG_BASE_2_EXT 0x8792 +#define GL_OP_POWER_EXT 0x8793 +#define GL_OP_RECIP_EXT 0x8794 +#define GL_OP_RECIP_SQRT_EXT 0x8795 +#define GL_OP_SUB_EXT 0x8796 +#define GL_OP_CROSS_PRODUCT_EXT 0x8797 +#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 +#define GL_OP_MOV_EXT 0x8799 +#define GL_OUTPUT_VERTEX_EXT 0x879A +#define GL_OUTPUT_COLOR0_EXT 0x879B +#define GL_OUTPUT_COLOR1_EXT 0x879C +#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D +#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E +#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F +#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 +#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 +#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 +#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 +#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 +#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 +#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 +#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 +#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 +#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 +#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA +#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB +#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC +#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD +#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE +#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF +#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 +#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 +#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 +#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 +#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 +#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 +#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 +#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 +#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 +#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 +#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA +#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB +#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC +#define GL_OUTPUT_FOG_EXT 0x87BD +#define GL_SCALAR_EXT 0x87BE +#define GL_VECTOR_EXT 0x87BF +#define GL_MATRIX_EXT 0x87C0 +#define GL_VARIANT_EXT 0x87C1 +#define GL_INVARIANT_EXT 0x87C2 +#define GL_LOCAL_CONSTANT_EXT 0x87C3 +#define GL_LOCAL_EXT 0x87C4 +#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 +#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 +#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 +#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 +#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD +#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE +#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF +#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 +#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 +#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 +#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 +#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 +#define GL_X_EXT 0x87D5 +#define GL_Y_EXT 0x87D6 +#define GL_Z_EXT 0x87D7 +#define GL_W_EXT 0x87D8 +#define GL_NEGATIVE_X_EXT 0x87D9 +#define GL_NEGATIVE_Y_EXT 0x87DA +#define GL_NEGATIVE_Z_EXT 0x87DB +#define GL_NEGATIVE_W_EXT 0x87DC +#define GL_ZERO_EXT 0x87DD +#define GL_ONE_EXT 0x87DE +#define GL_NEGATIVE_ONE_EXT 0x87DF +#define GL_NORMALIZED_RANGE_EXT 0x87E0 +#define GL_FULL_RANGE_EXT 0x87E1 +#define GL_CURRENT_VERTEX_EXT 0x87E2 +#define GL_MVP_MATRIX_EXT 0x87E3 +#define GL_VARIANT_VALUE_EXT 0x87E4 +#define GL_VARIANT_DATATYPE_EXT 0x87E5 +#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 +#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 +#define GL_VARIANT_ARRAY_EXT 0x87E8 +#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 +#define GL_INVARIANT_VALUE_EXT 0x87EA +#define GL_INVARIANT_DATATYPE_EXT 0x87EB +#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC +#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED +typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); +typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); +typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); +typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); +typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const void *addr); +typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const void *addr); +typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); +typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); +typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); +typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); +typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); +typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); +typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); +typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); +typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const void *addr); +typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); +typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); +typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); +typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); +typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, void **data); +typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); +typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVertexShaderEXT (void); +GLAPI void APIENTRY glEndVertexShaderEXT (void); +GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id); +GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range); +GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id); +GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1); +GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2); +GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); +GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); +GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num); +GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num); +GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); +GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const void *addr); +GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const void *addr); +GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr); +GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr); +GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr); +GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr); +GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr); +GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr); +GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr); +GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr); +GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const void *addr); +GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id); +GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id); +GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value); +GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value); +GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value); +GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value); +GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value); +GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap); +GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, void **data); +GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); +GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data); +GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data); +#endif +#endif /* GL_EXT_vertex_shader */ + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3 +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6 +#define GL_MODELVIEW1_MATRIX_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT 0x1700 +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight); +GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight); +GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei stride, const void *pointer); +#endif +#endif /* GL_EXT_vertex_weighting */ + +#ifndef GL_EXT_x11_sync_object +#define GL_EXT_x11_sync_object 1 +#define GL_SYNC_X11_FENCE_EXT 0x90E1 +typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags); +#endif +#endif /* GL_EXT_x11_sync_object */ + +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 +typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); +#endif +#endif /* GL_GREMEDY_frame_terminator */ + +#ifndef GL_GREMEDY_string_marker +#define GL_GREMEDY_string_marker 1 +typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const void *string); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const void *string); +#endif +#endif /* GL_GREMEDY_string_marker */ + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif /* GL_HP_convolution_border_modes */ + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params); +#endif +#endif /* GL_HP_image_transform */ + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif /* GL_HP_occlusion_test */ + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif /* GL_HP_texture_lighting */ + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#define GL_CULL_VERTEX_IBM 103050 +#endif /* GL_IBM_cull_vertex */ + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, GLint modestride); +#endif +#endif /* GL_IBM_multimode_draw_arrays */ + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif /* GL_IBM_rasterpos_clip */ + +#ifndef GL_IBM_static_data +#define GL_IBM_static_data 1 +#define GL_ALL_STATIC_DATA_IBM 103060 +#define GL_STATIC_VERTEX_ARRAY_IBM 103061 +typedef void (APIENTRYP PFNGLFLUSHSTATICDATAIBMPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushStaticDataIBM (GLenum target); +#endif +#endif /* GL_IBM_static_data */ + +#ifndef GL_IBM_texture_mirrored_repeat +#define GL_IBM_texture_mirrored_repeat 1 +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif /* GL_IBM_texture_mirrored_repeat */ + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean **pointer, GLint ptrstride); +GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const void **pointer, GLint ptrstride); +#endif +#endif /* GL_IBM_vertex_array_lists */ + +#ifndef GL_INGR_blend_func_separate +#define GL_INGR_blend_func_separate 1 +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif +#endif /* GL_INGR_blend_func_separate */ + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif /* GL_INGR_color_clamp */ + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#define GL_INTERLACE_READ_INGR 0x8568 +#endif /* GL_INGR_interlace_read */ + +#ifndef GL_INTEL_fragment_shader_ordering +#define GL_INTEL_fragment_shader_ordering 1 +#endif /* GL_INTEL_fragment_shader_ordering */ + +#ifndef GL_INTEL_map_texture +#define GL_INTEL_map_texture 1 +#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF +#define GL_LAYOUT_DEFAULT_INTEL 0 +#define GL_LAYOUT_LINEAR_INTEL 1 +#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2 +typedef void (APIENTRYP PFNGLSYNCTEXTUREINTELPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level); +typedef void *(APIENTRYP PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSyncTextureINTEL (GLuint texture); +GLAPI void APIENTRY glUnmapTexture2DINTEL (GLuint texture, GLint level); +GLAPI void *APIENTRY glMapTexture2DINTEL (GLuint texture, GLint level, GLbitfield access, GLint *stride, GLenum *layout); +#endif +#endif /* GL_INTEL_map_texture */ + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const void **pointer); +GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const void **pointer); +GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const void **pointer); +GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const void **pointer); +#endif +#endif /* GL_INTEL_parallel_arrays */ + +#ifndef GL_INTEL_performance_query +#define GL_INTEL_performance_query 1 +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 +#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 +#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 +#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 +#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 +#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 +#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 +#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 +#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA +#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB +#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC +#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD +#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE +#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF +#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 +typedef void (APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle); +typedef void (APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); +typedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); +typedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +typedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); +typedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle); +GLAPI void APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); +GLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); +GLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); +GLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +GLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); +GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#endif +#endif /* GL_INTEL_performance_query */ + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#endif /* GL_MESAX_texture_stack */ + +#ifndef GL_MESA_pack_invert +#define GL_MESA_pack_invert 1 +#define GL_PACK_INVERT_MESA 0x8758 +#endif /* GL_MESA_pack_invert */ + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glResizeBuffersMESA (void); +#endif +#endif /* GL_MESA_resize_buffers */ + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y); +GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y); +GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y); +GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y); +GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v); +GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z); +GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v); +GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v); +GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v); +GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v); +GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); +#endif +#endif /* GL_MESA_window_pos */ + +#ifndef GL_MESA_ycbcr_texture +#define GL_MESA_ycbcr_texture 1 +#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB +#define GL_YCBCR_MESA 0x8757 +#endif /* GL_MESA_ycbcr_texture */ + +#ifndef GL_NVX_conditional_render +#define GL_NVX_conditional_render 1 +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginConditionalRenderNVX (GLuint id); +GLAPI void APIENTRY glEndConditionalRenderNVX (void); +#endif +#endif /* GL_NVX_conditional_render */ + +#ifndef GL_NVX_gpu_memory_info +#define GL_NVX_gpu_memory_info 1 +#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047 +#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048 +#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049 +#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A +#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B +#endif /* GL_NVX_gpu_memory_info */ + +#ifndef GL_NV_bindless_multi_draw_indirect +#define GL_NV_bindless_multi_draw_indirect 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); +#endif +#endif /* GL_NV_bindless_multi_draw_indirect */ + +#ifndef GL_NV_bindless_texture +#define GL_NV_bindless_texture 1 +typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); +typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); +typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint64 APIENTRY glGetTextureHandleNV (GLuint texture); +GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler); +GLAPI void APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle); +GLAPI void APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle); +GLAPI GLuint64 APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +GLAPI void APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access); +GLAPI void APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle); +GLAPI void APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value); +GLAPI void APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value); +GLAPI void APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +GLAPI GLboolean APIENTRY glIsTextureHandleResidentNV (GLuint64 handle); +GLAPI GLboolean APIENTRY glIsImageHandleResidentNV (GLuint64 handle); +#endif +#endif /* GL_NV_bindless_texture */ + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLUE_NV 0x1905 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_GREEN_NV 0x1904 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_RED_NV 0x1903 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_XOR_NV 0x1506 +typedef void (APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLBLENDBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendParameteriNV (GLenum pname, GLint value); +GLAPI void APIENTRY glBlendBarrierNV (void); +#endif +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_NV_blend_equation_advanced_coherent +#define GL_NV_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#endif /* GL_NV_blend_equation_advanced_coherent */ + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif /* GL_NV_blend_square */ + +#ifndef GL_NV_compute_program5 +#define GL_NV_compute_program5 1 +#define GL_COMPUTE_PROGRAM_NV 0x90FB +#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC +#endif /* GL_NV_compute_program5 */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); +GLAPI void APIENTRY glEndConditionalRenderNV (void); +#endif +#endif /* GL_NV_conditional_render */ + +#ifndef GL_NV_copy_depth_to_color +#define GL_NV_copy_depth_to_color 1 +#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E +#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F +#endif /* GL_NV_copy_depth_to_color */ + +#ifndef GL_NV_copy_image +#define GL_NV_copy_image 1 +typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* GL_NV_copy_image */ + +#ifndef GL_NV_deep_texture3D +#define GL_NV_deep_texture3D 1 +#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0 +#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1 +#endif /* GL_NV_deep_texture3D */ + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); +GLAPI void APIENTRY glClearDepthdNV (GLdouble depth); +GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); +#endif +#endif /* GL_NV_depth_buffer_float */ + +#ifndef GL_NV_depth_clamp +#define GL_NV_depth_clamp 1 +#define GL_DEPTH_CLAMP_NV 0x864F +#endif /* GL_NV_depth_clamp */ + +#ifndef GL_NV_draw_texture +#define GL_NV_draw_texture 1 +typedef void (APIENTRYP PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawTextureNV (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +#endif +#endif /* GL_NV_draw_texture */ + +#ifndef GL_NV_evaluators +#define GL_NV_evaluators 1 +#define GL_EVAL_2D_NV 0x86C0 +#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 +#define GL_MAP_TESSELLATION_NV 0x86C2 +#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 +#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 +#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 +#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 +#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 +#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 +#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 +#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA +#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB +#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC +#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD +#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE +#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF +#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 +#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 +#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 +#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 +#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 +#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 +#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 +#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 +typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); +typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const void *points); +GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, void *points); +GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode); +#endif +#endif /* GL_NV_evaluators */ + +#ifndef GL_NV_explicit_multisample +#define GL_NV_explicit_multisample 1 +#define GL_SAMPLE_POSITION_NV 0x8E50 +#define GL_SAMPLE_MASK_NV 0x8E51 +#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 +#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 +#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 +#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 +#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 +#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 +#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 +#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val); +GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask); +GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer); +#endif +#endif /* GL_NV_explicit_multisample */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence); +GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence); +GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GLAPI void APIENTRY glFinishFenceNV (GLuint fence); +GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +#endif /* GL_NV_fence */ + +#ifndef GL_NV_float_buffer +#define GL_NV_float_buffer 1 +#define GL_FLOAT_R_NV 0x8880 +#define GL_FLOAT_RG_NV 0x8881 +#define GL_FLOAT_RGB_NV 0x8882 +#define GL_FLOAT_RGBA_NV 0x8883 +#define GL_FLOAT_R16_NV 0x8884 +#define GL_FLOAT_R32_NV 0x8885 +#define GL_FLOAT_RG16_NV 0x8886 +#define GL_FLOAT_RG32_NV 0x8887 +#define GL_FLOAT_RGB16_NV 0x8888 +#define GL_FLOAT_RGB32_NV 0x8889 +#define GL_FLOAT_RGBA16_NV 0x888A +#define GL_FLOAT_RGBA32_NV 0x888B +#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C +#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D +#define GL_FLOAT_RGBA_MODE_NV 0x888E +#endif /* GL_NV_float_buffer */ + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +#endif /* GL_NV_fog_distance */ + +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); +GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); +GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); +GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); +#endif +#endif /* GL_NV_fragment_program */ + +#ifndef GL_NV_fragment_program2 +#define GL_NV_fragment_program2 1 +#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 +#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 +#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 +#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 +#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 +#endif /* GL_NV_fragment_program2 */ + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 +#endif /* GL_NV_fragment_program4 */ + +#ifndef GL_NV_fragment_program_option +#define GL_NV_fragment_program_option 1 +#endif /* GL_NV_fragment_program_option */ + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_NV_framebuffer_multisample_coverage */ + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); +GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif +#endif /* GL_NV_geometry_program4 */ + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 +#endif /* GL_NV_geometry_shader4 */ + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); +GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); +GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); +GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); +GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); +#endif +#endif /* GL_NV_gpu_program4 */ + +#ifndef GL_NV_gpu_program5 +#define GL_NV_gpu_program5 1 +#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C +#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F +#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 +#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 +typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params); +GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param); +#endif +#endif /* GL_NV_gpu_program5 */ + +#ifndef GL_NV_gpu_program5_mem_extended +#define GL_NV_gpu_program5_mem_extended 1 +#endif /* GL_NV_gpu_program5_mem_extended */ + +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 +#endif /* GL_NV_gpu_shader5 */ + +#ifndef GL_NV_half_float +#define GL_NV_half_float 1 +typedef unsigned short GLhalfNV; +#define GL_HALF_FLOAT_NV 0x140B +typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); +typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y); +GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z); +GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s); +GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t); +GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r); +GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s); +GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t); +GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v); +GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); +GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); +GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); +GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); +GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); +GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x); +GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y); +GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v); +#endif +#endif /* GL_NV_half_float */ + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif /* GL_NV_light_max_exponent */ + +#ifndef GL_NV_multisample_coverage +#define GL_NV_multisample_coverage 1 +#define GL_COLOR_SAMPLES_NV 0x8E20 +#endif /* GL_NV_multisample_coverage */ + +#ifndef GL_NV_multisample_filter_hint +#define GL_NV_multisample_filter_hint 1 +#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 +#endif /* GL_NV_multisample_filter_hint */ + +#ifndef GL_NV_occlusion_query +#define GL_NV_occlusion_query 1 +#define GL_PIXEL_COUNTER_BITS_NV 0x8864 +#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 +#define GL_PIXEL_COUNT_NV 0x8866 +#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 +typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id); +GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id); +GLAPI void APIENTRY glEndOcclusionQueryNV (void); +GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params); +#endif +#endif /* GL_NV_occlusion_query */ + +#ifndef GL_NV_packed_depth_stencil +#define GL_NV_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_NV 0x84F9 +#define GL_UNSIGNED_INT_24_8_NV 0x84FA +#endif /* GL_NV_packed_depth_stencil */ + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLfloat *params); +GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLint *params); +GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, const GLuint *params); +#endif +#endif /* GL_NV_parameter_buffer_object */ + +#ifndef GL_NV_parameter_buffer_object2 +#define GL_NV_parameter_buffer_object2 1 +#endif /* GL_NV_parameter_buffer_object2 */ + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +typedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path); +typedef void (APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); +typedef void (APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +typedef void (APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); +typedef void (APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +typedef void (APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); +typedef void (APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); +typedef void (APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); +typedef void (APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +typedef void (APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); +typedef void (APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); +typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); +typedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); +typedef void (APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); +typedef void (APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); +typedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); +typedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +typedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +typedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); +typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); +typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); +typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glGenPathsNV (GLsizei range); +GLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range); +GLAPI GLboolean APIENTRY glIsPathNV (GLuint path); +GLAPI void APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +GLAPI void APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString); +GLAPI void APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI void APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI void APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +GLAPI void APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath); +GLAPI void APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +GLAPI void APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value); +GLAPI void APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value); +GLAPI void APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value); +GLAPI void APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value); +GLAPI void APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +GLAPI void APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask); +GLAPI void APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units); +GLAPI void APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask); +GLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask); +GLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func); +GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); +GLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); +GLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); +GLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value); +GLAPI void APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands); +GLAPI void APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords); +GLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); +GLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +GLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +GLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); +GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); +GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); +GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); +GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); +GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +#endif +#endif /* GL_NV_path_rendering */ + +#ifndef GL_NV_pixel_data_range +#define GL_NV_pixel_data_range 1 +#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 +#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 +#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A +#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B +#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C +#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D +typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const void *pointer); +typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, const void *pointer); +GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target); +#endif +#endif /* GL_NV_pixel_data_range */ + +#ifndef GL_NV_point_sprite +#define GL_NV_point_sprite 1 +#define GL_POINT_SPRITE_NV 0x8861 +#define GL_COORD_REPLACE_NV 0x8862 +#define GL_POINT_SPRITE_R_MODE_NV 0x8863 +typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param); +GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params); +#endif +#endif /* GL_NV_point_sprite */ + +#ifndef GL_NV_present_video +#define GL_NV_present_video 1 +#define GL_FRAME_NV 0x8E26 +#define GL_FIELDS_NV 0x8E27 +#define GL_CURRENT_TIME_NV 0x8E28 +#define GL_NUM_FILL_STREAMS_NV 0x8E29 +#define GL_PRESENT_TIME_NV 0x8E2A +#define GL_PRESENT_DURATION_NV 0x8E2B +typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params); +GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params); +GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params); +#endif +#endif /* GL_NV_present_video */ + +#ifndef GL_NV_primitive_restart +#define GL_NV_primitive_restart 1 +#define GL_PRIMITIVE_RESTART_NV 0x8558 +#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPrimitiveRestartNV (void); +GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); +#endif +#endif /* GL_NV_primitive_restart */ + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param); +GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params); +GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param); +GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params); +#endif +#endif /* GL_NV_register_combiners */ + +#ifndef GL_NV_register_combiners2 +#define GL_NV_register_combiners2 1 +#define GL_PER_STAGE_CONSTANTS_NV 0x8535 +typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params); +#endif +#endif /* GL_NV_register_combiners2 */ + +#ifndef GL_NV_shader_atomic_counters +#define GL_NV_shader_atomic_counters 1 +#endif /* GL_NV_shader_atomic_counters */ + +#ifndef GL_NV_shader_atomic_float +#define GL_NV_shader_atomic_float 1 +#endif /* GL_NV_shader_atomic_float */ + +#ifndef GL_NV_shader_buffer_load +#define GL_NV_shader_buffer_load 1 +#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D +#define GL_GPU_ADDRESS_NV 0x8F34 +#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 +typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); +typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); +typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); +typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); +typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); +typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result); +typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); +typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access); +GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target); +GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target); +GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access); +GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer); +GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer); +GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result); +GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value); +GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value); +GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#endif +#endif /* GL_NV_shader_buffer_load */ + +#ifndef GL_NV_shader_buffer_store +#define GL_NV_shader_buffer_store 1 +#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 +#endif /* GL_NV_shader_buffer_store */ + +#ifndef GL_NV_shader_storage_buffer_object +#define GL_NV_shader_storage_buffer_object 1 +#endif /* GL_NV_shader_storage_buffer_object */ + +#ifndef GL_NV_shader_thread_group +#define GL_NV_shader_thread_group 1 +#define GL_WARP_SIZE_NV 0x9339 +#define GL_WARPS_PER_SM_NV 0x933A +#define GL_SM_COUNT_NV 0x933B +#endif /* GL_NV_shader_thread_group */ + +#ifndef GL_NV_shader_thread_shuffle +#define GL_NV_shader_thread_shuffle 1 +#endif /* GL_NV_shader_thread_shuffle */ + +#ifndef GL_NV_tessellation_program5 +#define GL_NV_tessellation_program5 1 +#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 +#define GL_TESS_CONTROL_PROGRAM_NV 0x891E +#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F +#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 +#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 +#endif /* GL_NV_tessellation_program5 */ + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif /* GL_NV_texgen_emboss */ + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif /* GL_NV_texgen_reflection */ + +#ifndef GL_NV_texture_barrier +#define GL_NV_texture_barrier 1 +typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureBarrierNV (void); +#endif +#endif /* GL_NV_texture_barrier */ + +#ifndef GL_NV_texture_compression_vtc +#define GL_NV_texture_compression_vtc 1 +#endif /* GL_NV_texture_compression_vtc */ + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif /* GL_NV_texture_env_combine4 */ + +#ifndef GL_NV_texture_expand_normal +#define GL_NV_texture_expand_normal 1 +#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F +#endif /* GL_NV_texture_expand_normal */ + +#ifndef GL_NV_texture_multisample +#define GL_NV_texture_multisample 1 +#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 +#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); +GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); +#endif +#endif /* GL_NV_texture_multisample */ + +#ifndef GL_NV_texture_rectangle +#define GL_NV_texture_rectangle 1 +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif /* GL_NV_texture_rectangle */ + +#ifndef GL_NV_texture_shader +#define GL_NV_texture_shader 1 +#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C +#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D +#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E +#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 +#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA +#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB +#define GL_DSDT_MAG_INTENSITY_NV 0x86DC +#define GL_SHADER_CONSISTENT_NV 0x86DD +#define GL_TEXTURE_SHADER_NV 0x86DE +#define GL_SHADER_OPERATION_NV 0x86DF +#define GL_CULL_MODES_NV 0x86E0 +#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 +#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 +#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2 +#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 +#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 +#define GL_CONST_EYE_NV 0x86E5 +#define GL_PASS_THROUGH_NV 0x86E6 +#define GL_CULL_FRAGMENT_NV 0x86E7 +#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 +#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 +#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA +#define GL_DOT_PRODUCT_NV 0x86EC +#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED +#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE +#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 +#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 +#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 +#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 +#define GL_HILO_NV 0x86F4 +#define GL_DSDT_NV 0x86F5 +#define GL_DSDT_MAG_NV 0x86F6 +#define GL_DSDT_MAG_VIB_NV 0x86F7 +#define GL_HILO16_NV 0x86F8 +#define GL_SIGNED_HILO_NV 0x86F9 +#define GL_SIGNED_HILO16_NV 0x86FA +#define GL_SIGNED_RGBA_NV 0x86FB +#define GL_SIGNED_RGBA8_NV 0x86FC +#define GL_SIGNED_RGB_NV 0x86FE +#define GL_SIGNED_RGB8_NV 0x86FF +#define GL_SIGNED_LUMINANCE_NV 0x8701 +#define GL_SIGNED_LUMINANCE8_NV 0x8702 +#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 +#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 +#define GL_SIGNED_ALPHA_NV 0x8705 +#define GL_SIGNED_ALPHA8_NV 0x8706 +#define GL_SIGNED_INTENSITY_NV 0x8707 +#define GL_SIGNED_INTENSITY8_NV 0x8708 +#define GL_DSDT8_NV 0x8709 +#define GL_DSDT8_MAG8_NV 0x870A +#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B +#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C +#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D +#define GL_HI_SCALE_NV 0x870E +#define GL_LO_SCALE_NV 0x870F +#define GL_DS_SCALE_NV 0x8710 +#define GL_DT_SCALE_NV 0x8711 +#define GL_MAGNITUDE_SCALE_NV 0x8712 +#define GL_VIBRANCE_SCALE_NV 0x8713 +#define GL_HI_BIAS_NV 0x8714 +#define GL_LO_BIAS_NV 0x8715 +#define GL_DS_BIAS_NV 0x8716 +#define GL_DT_BIAS_NV 0x8717 +#define GL_MAGNITUDE_BIAS_NV 0x8718 +#define GL_VIBRANCE_BIAS_NV 0x8719 +#define GL_TEXTURE_BORDER_VALUES_NV 0x871A +#define GL_TEXTURE_HI_SIZE_NV 0x871B +#define GL_TEXTURE_LO_SIZE_NV 0x871C +#define GL_TEXTURE_DS_SIZE_NV 0x871D +#define GL_TEXTURE_DT_SIZE_NV 0x871E +#define GL_TEXTURE_MAG_SIZE_NV 0x871F +#endif /* GL_NV_texture_shader */ + +#ifndef GL_NV_texture_shader2 +#define GL_NV_texture_shader2 1 +#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF +#endif /* GL_NV_texture_shader2 */ + +#ifndef GL_NV_texture_shader3 +#define GL_NV_texture_shader3 1 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 +#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 +#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 +#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 +#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 +#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 +#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 +#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 +#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A +#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B +#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C +#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D +#define GL_HILO8_NV 0x885E +#define GL_SIGNED_HILO8_NV 0x885F +#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 +#endif /* GL_NV_texture_shader3 */ + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#define GL_LAYER_NV 0x8DAA +#define GL_NEXT_BUFFER_NV -2 +#define GL_SKIP_COMPONENTS4_NV -3 +#define GL_SKIP_COMPONENTS3_NV -4 +#define GL_SKIP_COMPONENTS2_NV -5 +#define GL_SKIP_COMPONENTS1_NV -6 +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedbackNV (void); +GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode); +GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); +GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); +GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); +#endif +#endif /* GL_NV_transform_feedback */ + +#ifndef GL_NV_transform_feedback2 +#define GL_NV_transform_feedback2 1 +#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 +typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids); +typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids); +GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids); +GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id); +GLAPI void APIENTRY glPauseTransformFeedbackNV (void); +GLAPI void APIENTRY glResumeTransformFeedbackNV (void); +GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); +#endif +#endif /* GL_NV_transform_feedback2 */ + +#ifndef GL_NV_vdpau_interop +#define GL_NV_vdpau_interop 1 +typedef GLintptr GLvdpauSurfaceNV; +#define GL_SURFACE_STATE_NV 0x86EB +#define GL_SURFACE_REGISTERED_NV 0x86FD +#define GL_SURFACE_MAPPED_NV 0x8700 +#define GL_WRITE_DISCARD_NV 0x88BE +typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const void *vdpDevice, const void *getProcAddress); +typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void); +typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +typedef GLboolean (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); +typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); +typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); +typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVDPAUInitNV (const void *vdpDevice, const void *getProcAddress); +GLAPI void APIENTRY glVDPAUFiniNV (void); +GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); +GLAPI GLboolean APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface); +GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface); +GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access); +GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); +GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); +#endif +#endif /* GL_NV_vdpau_interop */ + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const void *pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); +GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const void *pointer); +#endif +#endif /* GL_NV_vertex_array_range */ + +#ifndef GL_NV_vertex_array_range2 +#define GL_NV_vertex_array_range2 1 +#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 +#endif /* GL_NV_vertex_array_range2 */ + +#ifndef GL_NV_vertex_attrib_integer_64bit +#define GL_NV_vertex_attrib_integer_64bit 1 +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x); +GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y); +GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v); +GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x); +GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y); +GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v); +GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params); +GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params); +GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); +#endif +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +#ifndef GL_NV_vertex_buffer_unified_memory +#define GL_NV_vertex_buffer_unified_memory 1 +#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E +#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F +#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 +#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 +#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 +#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 +#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 +#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 +#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 +#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 +#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 +#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 +#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A +#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B +#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C +#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D +#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E +#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F +#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 +#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 +#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 +#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 +#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 +#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 +#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 +typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); +typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); +typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); +GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride); +GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride); +GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); +GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); +GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result); +#endif +#endif /* GL_NV_vertex_buffer_unified_memory */ + +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 +#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 +#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 +#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 +#define GL_CURRENT_ATTRIB_NV 0x8626 +#define GL_PROGRAM_LENGTH_NV 0x8627 +#define GL_PROGRAM_STRING_NV 0x8628 +#define GL_MODELVIEW_PROJECTION_NV 0x8629 +#define GL_IDENTITY_NV 0x862A +#define GL_INVERSE_NV 0x862B +#define GL_TRANSPOSE_NV 0x862C +#define GL_INVERSE_TRANSPOSE_NV 0x862D +#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E +#define GL_MAX_TRACK_MATRICES_NV 0x862F +#define GL_MATRIX0_NV 0x8630 +#define GL_MATRIX1_NV 0x8631 +#define GL_MATRIX2_NV 0x8632 +#define GL_MATRIX3_NV 0x8633 +#define GL_MATRIX4_NV 0x8634 +#define GL_MATRIX5_NV 0x8635 +#define GL_MATRIX6_NV 0x8636 +#define GL_MATRIX7_NV 0x8637 +#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 +#define GL_CURRENT_MATRIX_NV 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 +#define GL_PROGRAM_PARAMETER_NV 0x8644 +#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 +#define GL_PROGRAM_TARGET_NV 0x8646 +#define GL_PROGRAM_RESIDENT_NV 0x8647 +#define GL_TRACK_MATRIX_NV 0x8648 +#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 +#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 +#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 +#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 +#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 +#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 +#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 +#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 +#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 +#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 +#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 +#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A +#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B +#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C +#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D +#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E +#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F +#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 +#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 +#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 +#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 +#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 +#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 +#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 +#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 +#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 +#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 +#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A +#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B +#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C +#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D +#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E +#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F +#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 +#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 +#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 +#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 +#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 +#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 +#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 +#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 +#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 +#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 +#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A +#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B +#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C +#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D +#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E +#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F +typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); +typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); +typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); +typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void **pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); +typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); +typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences); +GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params); +GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs); +GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program); +GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, void **pointer); +GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id); +GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v); +GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v); +GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs); +GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform); +GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v); +GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v); +#endif +#endif /* GL_NV_vertex_program */ + +#ifndef GL_NV_vertex_program1_1 +#define GL_NV_vertex_program1_1 1 +#endif /* GL_NV_vertex_program1_1 */ + +#ifndef GL_NV_vertex_program2 +#define GL_NV_vertex_program2 1 +#endif /* GL_NV_vertex_program2 */ + +#ifndef GL_NV_vertex_program2_option +#define GL_NV_vertex_program2_option 1 +#endif /* GL_NV_vertex_program2_option */ + +#ifndef GL_NV_vertex_program3 +#define GL_NV_vertex_program3 1 +#endif /* GL_NV_vertex_program3 */ + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); +GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); +GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); +GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); +GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); +#endif +#endif /* GL_NV_vertex_program4 */ + +#ifndef GL_NV_video_capture +#define GL_NV_video_capture 1 +#define GL_VIDEO_BUFFER_NV 0x9020 +#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 +#define GL_FIELD_UPPER_NV 0x9022 +#define GL_FIELD_LOWER_NV 0x9023 +#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 +#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 +#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 +#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 +#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 +#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 +#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A +#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B +#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C +#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D +#define GL_PARTIAL_SUCCESS_NV 0x902E +#define GL_SUCCESS_NV 0x902F +#define GL_FAILURE_NV 0x9030 +#define GL_YCBYCR8_422_NV 0x9031 +#define GL_YCBAYCR8A_4224_NV 0x9032 +#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 +#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 +#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 +#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 +#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 +#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 +#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 +#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A +#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B +#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C +typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); +typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot); +GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); +GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); +GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot); +GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); +GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); +GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); +GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); +#endif +#endif /* GL_NV_video_capture */ + +#ifndef GL_OML_interlace +#define GL_OML_interlace 1 +#define GL_INTERLACE_OML 0x8980 +#define GL_INTERLACE_READ_OML 0x8981 +#endif /* GL_OML_interlace */ + +#ifndef GL_OML_resample +#define GL_OML_resample 1 +#define GL_PACK_RESAMPLE_OML 0x8984 +#define GL_UNPACK_RESAMPLE_OML 0x8985 +#define GL_RESAMPLE_REPLICATE_OML 0x8986 +#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 +#define GL_RESAMPLE_AVERAGE_OML 0x8988 +#define GL_RESAMPLE_DECIMATE_OML 0x8989 +#endif /* GL_OML_resample */ + +#ifndef GL_OML_subsample +#define GL_OML_subsample 1 +#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 +#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 +#endif /* GL_OML_subsample */ + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode); +#endif +#endif /* GL_PGI_misc_hints */ + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif /* GL_PGI_vertex_hints */ + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif /* GL_REND_screen_coordinates */ + +#ifndef GL_S3_s3tc +#define GL_S3_s3tc 1 +#define GL_RGB_S3TC 0x83A0 +#define GL_RGB4_S3TC 0x83A1 +#define GL_RGBA_S3TC 0x83A2 +#define GL_RGBA4_S3TC 0x83A3 +#define GL_RGBA_DXT5_S3TC 0x83A4 +#define GL_RGBA4_DXT5_S3TC 0x83A5 +#endif /* GL_S3_s3tc */ + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points); +#endif +#endif /* GL_SGIS_detail_texture */ + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points); +#endif +#endif /* GL_SGIS_fog_function */ + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif /* GL_SGIS_generate_mipmap */ + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert); +GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern); +#endif +#endif /* GL_SGIS_multisample */ + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param); +GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params); +GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params); +GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params); +#endif +#endif /* GL_SGIS_pixel_texture */ + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif /* GL_SGIS_point_line_texgen */ + +#ifndef GL_SGIS_point_parameters +#define GL_SGIS_point_parameters 1 +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params); +#endif +#endif /* GL_SGIS_point_parameters */ + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); +GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points); +#endif +#endif /* GL_SGIS_sharpen_texture */ + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const void *pixels); +#endif +#endif /* GL_SGIS_texture4D */ + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif /* GL_SGIS_texture_border_clamp */ + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif +#endif /* GL_SGIS_texture_color_mask */ + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif /* GL_SGIS_texture_edge_clamp */ + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights); +GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif +#endif /* GL_SGIS_texture_filter4 */ + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif /* GL_SGIS_texture_lod */ + +#ifndef GL_SGIS_texture_select +#define GL_SGIS_texture_select 1 +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif /* GL_SGIS_texture_select */ + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#define GL_ASYNC_MARKER_SGIX 0x8329 +typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker); +GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp); +GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp); +GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range); +GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range); +GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker); +#endif +#endif /* GL_SGIX_async */ + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif /* GL_SGIX_async_histogram */ + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif /* GL_SGIX_async_pixel */ + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif /* GL_SGIX_blend_alpha_minmax */ + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif /* GL_SGIX_calligraphic_fragment */ + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif /* GL_SGIX_clipmap */ + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif /* GL_SGIX_convolution_accuracy */ + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif /* GL_SGIX_depth_pass_instrument */ + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif /* GL_SGIX_depth_texture */ + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFlushRasterSGIX (void); +#endif +#endif /* GL_SGIX_flush_raster */ + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif /* GL_SGIX_fog_offset */ + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode); +GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params); +GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params); +GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param); +GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param); +GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params); +GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param); +#endif +#endif /* GL_SGIX_fragment_lighting */ + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameZoomSGIX (GLint factor); +#endif +#endif /* GL_SGIX_framezoom */ + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const void *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const void *params); +#endif +#endif /* GL_SGIX_igloo_interface */ + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); +GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer); +GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p); +GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker); +GLAPI void APIENTRY glStartInstrumentsSGIX (void); +GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker); +#endif +#endif /* GL_SGIX_instruments */ + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#define GL_INTERLACE_SGIX 0x8094 +#endif /* GL_SGIX_interlace */ + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif /* GL_SGIX_ir_instrument1 */ + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#define GL_LIST_PRIORITY_SGIX 0x8182 +typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params); +GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param); +GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param); +GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params); +#endif +#endif /* GL_SGIX_list_priority */ + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode); +#endif +#endif /* GL_SGIX_pixel_texture */ + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif /* GL_SGIX_pixel_tiles */ + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +GLAPI void APIENTRY glDeformSGIX (GLbitfield mask); +GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask); +#endif +#endif /* GL_SGIX_polynomial_ffd */ + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); +#endif +#endif /* GL_SGIX_reference_plane */ + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif /* GL_SGIX_resample */ + +#ifndef GL_SGIX_scalebias_hint +#define GL_SGIX_scalebias_hint 1 +#define GL_SCALEBIAS_HINT_SGIX 0x8322 +#endif /* GL_SGIX_scalebias_hint */ + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif /* GL_SGIX_shadow */ + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif /* GL_SGIX_shadow_ambient */ + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param); +GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param); +GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params); +#endif +#endif /* GL_SGIX_sprite */ + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif /* GL_SGIX_subsample */ + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTagSampleBufferSGIX (void); +#endif +#endif /* GL_SGIX_tag_sample_buffer */ + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif /* GL_SGIX_texture_add_env */ + +#ifndef GL_SGIX_texture_coordinate_clamp +#define GL_SGIX_texture_coordinate_clamp 1 +#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 +#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A +#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B +#endif /* GL_SGIX_texture_coordinate_clamp */ + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif /* GL_SGIX_texture_lod_bias */ + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif /* GL_SGIX_texture_multi_buffer */ + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif /* GL_SGIX_texture_scale_bias */ + +#ifndef GL_SGIX_vertex_preclip +#define GL_SGIX_vertex_preclip 1 +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif /* GL_SGIX_vertex_preclip */ + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif /* GL_SGIX_ycrcb */ + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif /* GL_SGIX_ycrcb_subsample */ + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif /* GL_SGIX_ycrcba */ + +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif /* GL_SGI_color_matrix */ + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, void *table); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void *table); +GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, void *table); +GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params); +#endif +#endif /* GL_SGI_color_table */ + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif /* GL_SGI_texture_color_table */ + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFinishTextureSUNX (void); +#endif +#endif /* GL_SUNX_constant_data */ + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif /* GL_SUN_convolution_border_modes */ + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor); +GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor); +GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor); +GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor); +GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor); +GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor); +GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor); +GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor); +#endif +#endif /* GL_SUN_global_alpha */ + +#ifndef GL_SUN_mesh_array +#define GL_SUN_mesh_array 1 +#define GL_QUAD_MESH_SUN 0x8614 +#define GL_TRIANGLE_MESH_SUN 0x8615 +typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width); +#endif +#endif /* GL_SUN_mesh_array */ + +#ifndef GL_SUN_slice_accum +#define GL_SUN_slice_accum 1 +#define GL_SLICE_ACCUM_SUN 0x85CC +#endif /* GL_SUN_slice_accum */ + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#define GL_RESTART_SUN 0x0001 +#define GL_REPLACE_MIDDLE_SUN 0x0002 +#define GL_REPLACE_OLDEST_SUN 0x0003 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const void **pointer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code); +GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code); +GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code); +GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code); +GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code); +GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code); +GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const void **pointer); +#endif +#endif /* GL_SUN_triangle_list */ + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif +#endif /* GL_SUN_vertex */ + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif /* GL_WIN_phong_shading */ + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif /* GL_WIN_specular_fog */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_opengles.h b/packages/sdl2.2.0.5/build/native/include/SDL_opengles.h new file mode 100644 index 00000000..15abee79 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_opengles.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengles.h + * + * This is a simple file to encapsulate the OpenGL ES 1.X API headers. + */ +#include "SDL_config.h" + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_opengles2.h b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2.h new file mode 100644 index 00000000..c961f0f7 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2.h @@ -0,0 +1,52 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengles2.h + * + * This is a simple file to encapsulate the OpenGL ES 2.0 API headers. + */ +#include "SDL_config.h" + +#ifndef _MSC_VER + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#include +#endif + +#else /* _MSC_VER */ + +/* OpenGL ES2 headers for Visual Studio */ +#include "SDL_opengles2_khrplatform.h" +#include "SDL_opengles2_gl2platform.h" +#include "SDL_opengles2_gl2.h" +#include "SDL_opengles2_gl2ext.h" + +#endif /* _MSC_VER */ + +#ifndef APIENTRY +#define APIENTRY GL_APIENTRY +#endif diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2.h b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2.h new file mode 100644 index 00000000..c62fb0a5 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2.h @@ -0,0 +1,621 @@ +#ifndef __gl2_h_ +#define __gl2_h_ + +/* $Revision: 20555 $ on $Date:: 2013-02-12 14:32:47 -0800 #$ */ + +/*#include */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +typedef void GLvoid; +typedef char GLchar; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; + +/* GL types for handling large vertex buffer objects */ +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_2_0 1 + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 + +/* AlphaFunction (not supported in ES20) */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +/*------------------------------------------------------------------------- + * GL core functions. + *-----------------------------------------------------------------------*/ + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2_h_ */ + diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2ext.h b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2ext.h new file mode 100644 index 00000000..e8ca8b13 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2ext.h @@ -0,0 +1,2050 @@ +#ifndef __gl2ext_h_ +#define __gl2ext_h_ + +/* $Revision: 22801 $ on $Date:: 2013-08-21 03:20:48 -0700 #$ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +#ifndef GL_APIENTRYP +# define GL_APIENTRYP GL_APIENTRY* +#endif + +/* New types shared by several extensions */ + +#ifndef __gl3_h_ +/* These are defined with respect to in the + * Apple extension spec, but they are also used by non-APPLE + * extensions, and in the Khronos header we use the Khronos + * portable types in khrplatform.h, which must be defined. + */ +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef struct __GLsync *GLsync; +#endif + + +/*------------------------------------------------------------------------* + * OES extension tokens + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#endif + +/* GL_OES_depth_texture */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +/* GLeglImageOES defined in GL_OES_EGL_image already. */ +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_UNSIGNED_INT 0x1405 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_OES_required_internalformat */ +#ifndef GL_OES_required_internalformat +#define GL_ALPHA8_OES 0x803C +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +/* reuse GL_DEPTH_COMPONENT24_OES */ +/* reuse GL_DEPTH24_STENCIL8_OES */ +/* reuse GL_DEPTH_COMPONENT32_OES */ +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_RGBA4_OES 0x8056 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB565_OES 0x8D62 +/* reuse GL_RGB8_OES */ +/* reuse GL_RGBA8_OES */ +/* reuse GL_RGB10_EXT */ +/* reuse GL_RGB10_A2_EXT */ +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#endif + +#ifndef GL_OES_surfaceless_context +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +#endif + +/* GL_OES_texture_float */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_HALF_FLOAT_OES 0x8D61 +#endif + +/* GL_OES_texture_half_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_npot */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_vertex_array_object */ +#ifndef GL_OES_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +#endif + +/* GL_OES_vertex_half_float */ +/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */ + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#endif + +/*------------------------------------------------------------------------* + * KHR extension tokens + *------------------------------------------------------------------------*/ + +#ifndef GL_KHR_debug +typedef void (GL_APIENTRYP GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_BUFFER_KHR 0x82E0 +#define GL_SHADER_KHR 0x82E1 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_QUERY_KHR 0x82E3 +/* PROGRAM_PIPELINE only in GL */ +#define GL_SAMPLER_KHR 0x82E6 +/* DISPLAY_LIST only in GL */ +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif + +/*------------------------------------------------------------------------* + * AMD extension tokens + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#endif + +/* GL_AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_Z400_BINARY_AMD 0x8740 +#endif + +/*------------------------------------------------------------------------* + * ANGLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_depth_texture */ +#ifndef GL_ANGLE_depth_texture +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +#endif + +/* GL_ANGLE_instanced_arrays */ +#ifndef GL_ANGLE_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif + +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#endif + +/* GL_ANGLE_translated_shader_source */ +#ifndef GL_ANGLE_translated_shader_source +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +#endif + +/*------------------------------------------------------------------------* + * APPLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_APPLE_copy_texture_levels */ +/* No new tokens introduced by this extension. */ + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +#endif + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +/* GL_APPLE_sync */ +#ifndef GL_APPLE_sync + +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#endif + +/*------------------------------------------------------------------------* + * ARM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_program_binary */ +#ifndef GL_ARM_mali_program_binary +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#endif + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#endif + +/* GL_ARM_rgba8 */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* + * EXT extension tokens + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#ifndef GL_EXT_blend_minmax +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#endif + +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_RG16F_EXT 0x822F +#define GL_R16F_EXT 0x822D +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#endif + +/* GL_EXT_debug_marker */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_discard_framebuffer */ +#ifndef GL_EXT_discard_framebuffer +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 +#endif + +#ifndef GL_EXT_disjoint_timer_query +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_GPU_DISJOINT_EXT 0x8FBB +#endif + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#endif + +/* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_map_buffer_range +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +#endif + +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */ +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +/* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_draw_buffers +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +#endif + +/* GL_EXT_multi_draw_arrays */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#endif + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_BGRA_EXT 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#endif + +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +/* reuse GL_NO_ERROR */ +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +#endif + +/* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif + +/* GL_EXT_shader_texture_lod */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#endif + +/* GL_EXT_sRGB_write_control */ +#ifndef GL_EXT_sRGB_write_control +#define GL_EXT_sRGB_write_control 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#endif + +/* GL_EXT_texture_sRGB_decode */ +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +/* reuse GL_RGBA16F_EXT */ +/* reuse GL_RGB16F_EXT */ +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGB10_EXT 0x8052 +#define GL_BGRA8_EXT 0x93A1 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#define GL_R32F_EXT 0x822E +#define GL_RG32F_EXT 0x8230 +#define GL_R16F_EXT 0x822D +#define GL_RG16F_EXT 0x822F +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif + +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#endif + +/*------------------------------------------------------------------------* + * DMP extension tokens + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_SHADER_BINARY_DMP 0x9250 +#endif + +/*------------------------------------------------------------------------* + * FJ extension tokens + *------------------------------------------------------------------------*/ + +/* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#endif + +/*------------------------------------------------------------------------* + * IMG extension tokens + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#ifndef GL_IMG_program_binary +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#endif + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_BGRA_IMG 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#endif + +/* GL_IMG_shader_binary */ +#ifndef GL_IMG_shader_binary +#define GL_SGX_BINARY_IMG 0x8C0A +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif + +/* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#endif + +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +#endif + +/*------------------------------------------------------------------------* + * NV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +#endif + +/* GL_NV_draw_instanced */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */ +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +/* GL_NV_framebuffer_blit */ +#ifndef GL_NV_framebuffer_blit +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +#endif + +/* GL_NV_framebuffer_multisample */ +#ifndef GL_NV_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_MAX_SAMPLES_NV 0x8D57 +#endif + +/* GL_NV_generate_mipmap_sRGB */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_instanced_arrays */ +#ifndef GL_NV_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_READ_BUFFER_NV 0x0C02 +#endif + +/* GL_NV_read_buffer_front */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_shadow_samplers_array */ +#ifndef GL_NV_shadow_samplers_array +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#endif + +/* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_shadow_samplers_cube +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#endif + +/* GL_NV_sRGB_formats */ +#ifndef GL_NV_sRGB_formats +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SRGB8_NV 0x8C41 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_ETC1_SRGB8_NV 0x88EE +#endif + +/* GL_NV_texture_border_clamp */ +#ifndef GL_NV_texture_border_clamp +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_CLAMP_TO_BORDER_NV 0x812D +#endif + +/* GL_NV_texture_compression_s3tc_update */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_texture_npot_2D_mipmap */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* + * QCOM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +#endif + +/* GL_QCOM_binning_control */ +#ifndef GL_QCOM_binning_control +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#endif + +/* GL_QCOM_driver_control */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_extended_get */ +#ifndef GL_QCOM_extended_get +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC +#endif + +/* GL_QCOM_extended_get2 */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#endif + +/* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_writeonly_rendering +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#endif + +/* GL_QCOM_tiled_rendering */ +#ifndef GL_QCOM_tiled_rendering +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +#endif + +/*------------------------------------------------------------------------* + * VIV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_SHADER_BINARY_VIV 0x8FC4 +#endif + +/*------------------------------------------------------------------------* + * End of extension tokens, start of corresponding extension functions + *------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------* + * OES extension functions + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_OES_compressed_ETC1_RGB8_texture 1 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_OES_depth24 1 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_OES_depth32 1 +#endif + +/* GL_OES_depth_texture */ +#ifndef GL_OES_depth_texture +#define GL_OES_depth_texture 1 +#endif + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +#define GL_OES_EGL_image_external 1 +/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */ +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_OES_element_index_uint 1 +#endif + +/* GL_OES_fbo_render_mipmap */ +#ifndef GL_OES_fbo_render_mipmap +#define GL_OES_fbo_render_mipmap 1 +#endif + +/* GL_OES_fragment_precision_high */ +#ifndef GL_OES_fragment_precision_high +#define GL_OES_fragment_precision_high 1 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_OES_get_program_binary 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +#endif +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_OES_mapbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); +GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid **params); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid **params); +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_OES_packed_depth_stencil 1 +#endif + +/* GL_OES_required_internalformat */ +#ifndef GL_OES_required_internalformat +#define GL_OES_required_internalformat 1 +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_OES_rgb8_rgba8 1 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_OES_standard_derivatives 1 +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_OES_stencil1 1 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_OES_stencil4 1 +#endif + +#ifndef GL_OES_surfaceless_context +#define GL_OES_surfaceless_context 1 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_OES_texture_3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif + +/* GL_OES_texture_float */ +#ifndef GL_OES_texture_float +#define GL_OES_texture_float 1 +#endif + +/* GL_OES_texture_float_linear */ +#ifndef GL_OES_texture_float_linear +#define GL_OES_texture_float_linear 1 +#endif + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_OES_texture_half_float 1 +#endif + +/* GL_OES_texture_half_float_linear */ +#ifndef GL_OES_texture_half_float_linear +#define GL_OES_texture_half_float_linear 1 +#endif + +/* GL_OES_texture_npot */ +#ifndef GL_OES_texture_npot +#define GL_OES_texture_npot 1 +#endif + +/* GL_OES_vertex_array_object */ +#ifndef GL_OES_vertex_array_object +#define GL_OES_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); +#endif +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); +#endif + +/* GL_OES_vertex_half_float */ +#ifndef GL_OES_vertex_half_float +#define GL_OES_vertex_half_float 1 +#endif + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_OES_vertex_type_10_10_10_2 1 +#endif + +/*------------------------------------------------------------------------* + * KHR extension functions + *------------------------------------------------------------------------*/ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam); +GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void); +GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, GLvoid **params); +#endif +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam); +typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, GLvoid **params); +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif + + +/*------------------------------------------------------------------------* + * AMD extension functions + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_AMD_compressed_3DC_texture 1 +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_AMD_compressed_ATC_texture 1 +#endif + +/* AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_AMD_program_binary_Z400 1 +#endif + +/*------------------------------------------------------------------------* + * ANGLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_depth_texture */ +#ifndef GL_ANGLE_depth_texture +#define GL_ANGLE_depth_texture 1 +#endif + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 +#endif + +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 +#endif + +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif + +/*------------------------------------------------------------------------* + * APPLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_APPLE_copy_texture_levels */ +#ifndef GL_APPLE_copy_texture_levels +#define GL_APPLE_copy_texture_levels 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif +typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_APPLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); +#endif + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#endif + +/* GL_APPLE_sync */ +#ifndef GL_APPLE_sync +#define GL_APPLE_sync 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_APPLE_texture_format_BGRA8888 1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_APPLE_texture_max_level 1 +#endif + +/*------------------------------------------------------------------------* + * ARM extension functions + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_program_binary */ +#ifndef GL_ARM_mali_program_binary +#define GL_ARM_mali_program_binary 1 +#endif + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_ARM_mali_shader_binary 1 +#endif + +/* GL_ARM_rgba8 */ +#ifndef GL_ARM_rgba8 +#define GL_ARM_rgba8 1 +#endif + +/*------------------------------------------------------------------------* + * EXT extension functions + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#endif + +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_EXT_color_buffer_half_float 1 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif + +/* GL_EXT_debug_marker */ +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); +#endif +typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#endif + +/* GL_EXT_discard_framebuffer */ +#ifndef GL_EXT_discard_framebuffer +#define GL_EXT_discard_framebuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif +typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif + +#ifndef GL_EXT_disjoint_timer_query +#define GL_EXT_disjoint_timer_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); +GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +#endif +typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#endif /* GL_EXT_disjoint_timer_query */ + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs); +#endif /* GL_EXT_draw_buffers */ + +/* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_map_buffer_range +#define GL_EXT_map_buffer_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#endif + +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + +/* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_draw_buffers +#define GL_EXT_multiview_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index); +GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices); +GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data); +#endif +typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +#endif + +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_EXT_occlusion_query_boolean 1 +/* All entry points also exist in GL_EXT_disjoint_timer_query */ +#endif + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_EXT_read_format_bgra 1 +#endif + +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +#define GL_EXT_robustness 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); +GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x); +GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif + +/* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 +#endif + +/* GL_EXT_shader_texture_lod */ +#ifndef GL_EXT_shader_texture_lod +#define GL_EXT_shader_texture_lod 1 +#endif + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_EXT_shadow_samplers 1 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_EXT_texture_format_BGRA8888 1 +#endif + +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_EXT_texture_rg 1 +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_EXT_texture_type_2_10_10_10_REV 1 +#endif + +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_EXT_unpack_subimage 1 +#endif + +/*------------------------------------------------------------------------* + * DMP extension functions + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_DMP_shader_binary 1 +#endif + +/*------------------------------------------------------------------------* + * FJ extension functions + *------------------------------------------------------------------------*/ + +/* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_FJ_shader_binary_GCCSO 1 +#endif + +/*------------------------------------------------------------------------* + * IMG extension functions + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#ifndef GL_IMG_program_binary +#define GL_IMG_program_binary 1 +#endif + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_IMG_read_format 1 +#endif + +/* GL_IMG_shader_binary */ +#ifndef GL_IMG_shader_binary +#define GL_IMG_shader_binary 1 +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_IMG_texture_compression_pvrtc 1 +#endif + +/* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_IMG_texture_compression_pvrtc2 1 +#endif + +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + +/*------------------------------------------------------------------------* + * NV extension functions + *------------------------------------------------------------------------*/ + +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_NV_coverage_sample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); +GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); +#endif +typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); +typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_NV_depth_nonlinear 1 +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_NV_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); +#endif + +/* GL_NV_draw_instanced */ +#ifndef GL_NV_draw_instanced +#define GL_NV_draw_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_NV_fbo_color_attachments 1 +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +/* GL_NV_framebuffer_blit */ +#ifndef GL_NV_framebuffer_blit +#define GL_NV_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_NV_framebuffer_multisample */ +#ifndef GL_NV_framebuffer_multisample +#define GL_NV_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +/* GL_NV_generate_mipmap_sRGB */ +#ifndef GL_NV_generate_mipmap_sRGB +#define GL_NV_generate_mipmap_sRGB 1 +#endif + +/* GL_NV_instanced_arrays */ +#ifndef GL_NV_instanced_arrays +#define GL_NV_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor); +#endif +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_NV_read_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); +#endif +typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); +#endif + +/* GL_NV_read_buffer_front */ +#ifndef GL_NV_read_buffer_front +#define GL_NV_read_buffer_front 1 +#endif + +/* GL_NV_read_depth */ +#ifndef GL_NV_read_depth +#define GL_NV_read_depth 1 +#endif + +/* GL_NV_read_depth_stencil */ +#ifndef GL_NV_read_depth_stencil +#define GL_NV_read_depth_stencil 1 +#endif + +/* GL_NV_read_stencil */ +#ifndef GL_NV_read_stencil +#define GL_NV_read_stencil 1 +#endif + +/* GL_NV_shadow_samplers_array */ +#ifndef GL_NV_shadow_samplers_array +#define GL_NV_shadow_samplers_array 1 +#endif + +/* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_shadow_samplers_cube +#define GL_NV_shadow_samplers_cube 1 +#endif + +/* GL_NV_sRGB_formats */ +#ifndef GL_NV_sRGB_formats +#define GL_NV_sRGB_formats 1 +#endif + +/* GL_NV_texture_border_clamp */ +#ifndef GL_NV_texture_border_clamp +#define GL_NV_texture_border_clamp 1 +#endif + +/* GL_NV_texture_compression_s3tc_update */ +#ifndef GL_NV_texture_compression_s3tc_update +#define GL_NV_texture_compression_s3tc_update 1 +#endif + +/* GL_NV_texture_npot_2D_mipmap */ +#ifndef GL_NV_texture_npot_2D_mipmap +#define GL_NV_texture_npot_2D_mipmap 1 +#endif + +/*------------------------------------------------------------------------* + * QCOM extension functions + *------------------------------------------------------------------------*/ + +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_QCOM_alpha_test 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); +#endif +typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); +#endif + +/* GL_QCOM_binning_control */ +#ifndef GL_QCOM_binning_control +#define GL_QCOM_binning_control 1 +#endif + +/* GL_QCOM_driver_control */ +#ifndef GL_QCOM_driver_control +#define GL_QCOM_driver_control 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); +GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); +GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); +#endif +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +#endif + +/* GL_QCOM_extended_get */ +#ifndef GL_QCOM_extended_get +#define GL_QCOM_extended_get 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures); +GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); +GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params); +#endif +typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params); +#endif + +/* GL_QCOM_extended_get2 */ +#ifndef GL_QCOM_extended_get2 +#define GL_QCOM_extended_get2 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders); +GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program); +GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif +typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_QCOM_perfmon_global_mode 1 +#endif + +/* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_writeonly_rendering +#define GL_QCOM_writeonly_rendering 1 +#endif + +/* GL_QCOM_tiled_rendering */ +#ifndef GL_QCOM_tiled_rendering +#define GL_QCOM_tiled_rendering 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); +#endif +typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); +#endif + +/*------------------------------------------------------------------------* + * VIV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_VIV_shader_binary 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2ext_h_ */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2platform.h b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2platform.h new file mode 100644 index 00000000..c325686f --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_gl2platform.h @@ -0,0 +1,30 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +/*#include */ + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl2platform_h_ */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_khrplatform.h b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_khrplatform.h new file mode 100644 index 00000000..c9e6f17d --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_opengles2_khrplatform.h @@ -0,0 +1,282 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_pixels.h b/packages/sdl2.2.0.5/build/native/include/SDL_pixels.h new file mode 100644 index 00000000..cf6a33f0 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_pixels.h @@ -0,0 +1,468 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_pixels.h + * + * Header for the enumerated pixel format definitions. + */ + +#ifndef _SDL_pixels_h +#define _SDL_pixels_h + +#include "SDL_stdinc.h" +#include "SDL_endian.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Transparency definitions + * + * These define alpha as the opacity of a surface. + */ +/* @{ */ +#define SDL_ALPHA_OPAQUE 255 +#define SDL_ALPHA_TRANSPARENT 0 +/* @} */ + +/** Pixel type. */ +enum +{ + SDL_PIXELTYPE_UNKNOWN, + SDL_PIXELTYPE_INDEX1, + SDL_PIXELTYPE_INDEX4, + SDL_PIXELTYPE_INDEX8, + SDL_PIXELTYPE_PACKED8, + SDL_PIXELTYPE_PACKED16, + SDL_PIXELTYPE_PACKED32, + SDL_PIXELTYPE_ARRAYU8, + SDL_PIXELTYPE_ARRAYU16, + SDL_PIXELTYPE_ARRAYU32, + SDL_PIXELTYPE_ARRAYF16, + SDL_PIXELTYPE_ARRAYF32 +}; + +/** Bitmap pixel order, high bit -> low bit. */ +enum +{ + SDL_BITMAPORDER_NONE, + SDL_BITMAPORDER_4321, + SDL_BITMAPORDER_1234 +}; + +/** Packed component order, high bit -> low bit. */ +enum +{ + SDL_PACKEDORDER_NONE, + SDL_PACKEDORDER_XRGB, + SDL_PACKEDORDER_RGBX, + SDL_PACKEDORDER_ARGB, + SDL_PACKEDORDER_RGBA, + SDL_PACKEDORDER_XBGR, + SDL_PACKEDORDER_BGRX, + SDL_PACKEDORDER_ABGR, + SDL_PACKEDORDER_BGRA +}; + +/** Array component order, low byte -> high byte. */ +/* !!! FIXME: in 2.1, make these not overlap differently with + !!! FIXME: SDL_PACKEDORDER_*, so we can simplify SDL_ISPIXELFORMAT_ALPHA */ +enum +{ + SDL_ARRAYORDER_NONE, + SDL_ARRAYORDER_RGB, + SDL_ARRAYORDER_RGBA, + SDL_ARRAYORDER_ARGB, + SDL_ARRAYORDER_BGR, + SDL_ARRAYORDER_BGRA, + SDL_ARRAYORDER_ABGR +}; + +/** Packed component layout. */ +enum +{ + SDL_PACKEDLAYOUT_NONE, + SDL_PACKEDLAYOUT_332, + SDL_PACKEDLAYOUT_4444, + SDL_PACKEDLAYOUT_1555, + SDL_PACKEDLAYOUT_5551, + SDL_PACKEDLAYOUT_565, + SDL_PACKEDLAYOUT_8888, + SDL_PACKEDLAYOUT_2101010, + SDL_PACKEDLAYOUT_1010102 +}; + +#define SDL_DEFINE_PIXELFOURCC(A, B, C, D) SDL_FOURCC(A, B, C, D) + +#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \ + ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \ + ((bits) << 8) | ((bytes) << 0)) + +#define SDL_PIXELFLAG(X) (((X) >> 28) & 0x0F) +#define SDL_PIXELTYPE(X) (((X) >> 24) & 0x0F) +#define SDL_PIXELORDER(X) (((X) >> 20) & 0x0F) +#define SDL_PIXELLAYOUT(X) (((X) >> 16) & 0x0F) +#define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF) +#define SDL_BYTESPERPIXEL(X) \ + (SDL_ISPIXELFORMAT_FOURCC(X) ? \ + ((((X) == SDL_PIXELFORMAT_YUY2) || \ + ((X) == SDL_PIXELFORMAT_UYVY) || \ + ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF)) + +#define SDL_ISPIXELFORMAT_INDEXED(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8))) + +#define SDL_ISPIXELFORMAT_PACKED(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED8) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED32))) + +#define SDL_ISPIXELFORMAT_ARRAY(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU8) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU32) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF32))) + +#define SDL_ISPIXELFORMAT_ALPHA(format) \ + ((SDL_ISPIXELFORMAT_PACKED(format) && \ + ((SDL_PIXELORDER(format) == SDL_PACKEDORDER_ARGB) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_RGBA) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA))) || \ + (SDL_ISPIXELFORMAT_ARRAY(format) && \ + ((SDL_PIXELORDER(format) == SDL_ARRAYORDER_ARGB) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_RGBA) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_ABGR) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_BGRA)))) + +/* The flag is set to 1 because 0x1? is not in the printable ASCII range */ +#define SDL_ISPIXELFORMAT_FOURCC(format) \ + ((format) && (SDL_PIXELFLAG(format) != 1)) + +/* Note: If you modify this list, update SDL_GetPixelFormatName() */ +enum +{ + SDL_PIXELFORMAT_UNKNOWN, + SDL_PIXELFORMAT_INDEX1LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0, + 1, 0), + SDL_PIXELFORMAT_INDEX1MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, + 1, 0), + SDL_PIXELFORMAT_INDEX4LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, + 4, 0), + SDL_PIXELFORMAT_INDEX4MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0, + 4, 0), + SDL_PIXELFORMAT_INDEX8 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1), + SDL_PIXELFORMAT_RGB332 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_332, 8, 1), + SDL_PIXELFORMAT_RGB444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_4444, 12, 2), + SDL_PIXELFORMAT_RGB555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_BGR555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_ARGB4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_RGBA4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_ABGR4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_BGRA4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_ARGB1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_1555, 16, 2), + SDL_PIXELFORMAT_RGBA5551 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_5551, 16, 2), + SDL_PIXELFORMAT_ABGR1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_1555, 16, 2), + SDL_PIXELFORMAT_BGRA5551 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_5551, 16, 2), + SDL_PIXELFORMAT_RGB565 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_565, 16, 2), + SDL_PIXELFORMAT_BGR565 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_565, 16, 2), + SDL_PIXELFORMAT_RGB24 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0, + 24, 3), + SDL_PIXELFORMAT_BGR24 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, + 24, 3), + SDL_PIXELFORMAT_RGB888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_RGBX8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_BGR888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_BGRX8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_ARGB8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_RGBA8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_ABGR8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_BGRA8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_ARGB2101010 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_2101010, 32, 4), + + /* Aliases for RGBA byte arrays of color data, for the current platform */ +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888, +#else + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888, +#endif + + SDL_PIXELFORMAT_YV12 = /**< Planar mode: Y + V + U (3 planes) */ + SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'), + SDL_PIXELFORMAT_IYUV = /**< Planar mode: Y + U + V (3 planes) */ + SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'), + SDL_PIXELFORMAT_YUY2 = /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'), + SDL_PIXELFORMAT_UYVY = /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'), + SDL_PIXELFORMAT_YVYU = /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'), + SDL_PIXELFORMAT_NV12 = /**< Planar mode: Y + U/V interleaved (2 planes) */ + SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'), + SDL_PIXELFORMAT_NV21 = /**< Planar mode: Y + V/U interleaved (2 planes) */ + SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1') +}; + +typedef struct SDL_Color +{ + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} SDL_Color; +#define SDL_Colour SDL_Color + +typedef struct SDL_Palette +{ + int ncolors; + SDL_Color *colors; + Uint32 version; + int refcount; +} SDL_Palette; + +/** + * \note Everything in the pixel format structure is read-only. + */ +typedef struct SDL_PixelFormat +{ + Uint32 format; + SDL_Palette *palette; + Uint8 BitsPerPixel; + Uint8 BytesPerPixel; + Uint8 padding[2]; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Aloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + int refcount; + struct SDL_PixelFormat *next; +} SDL_PixelFormat; + +/** + * \brief Get the human readable name of a pixel format + */ +extern DECLSPEC const char* SDLCALL SDL_GetPixelFormatName(Uint32 format); + +/** + * \brief Convert one of the enumerated pixel formats to a bpp and RGBA masks. + * + * \return SDL_TRUE, or SDL_FALSE if the conversion wasn't possible. + * + * \sa SDL_MasksToPixelFormatEnum() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format, + int *bpp, + Uint32 * Rmask, + Uint32 * Gmask, + Uint32 * Bmask, + Uint32 * Amask); + +/** + * \brief Convert a bpp and RGBA masks to an enumerated pixel format. + * + * \return The pixel format, or ::SDL_PIXELFORMAT_UNKNOWN if the conversion + * wasn't possible. + * + * \sa SDL_PixelFormatEnumToMasks() + */ +extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); + +/** + * \brief Create an SDL_PixelFormat structure from a pixel format enum. + */ +extern DECLSPEC SDL_PixelFormat * SDLCALL SDL_AllocFormat(Uint32 pixel_format); + +/** + * \brief Free an SDL_PixelFormat structure. + */ +extern DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format); + +/** + * \brief Create a palette structure with the specified number of color + * entries. + * + * \return A new palette, or NULL if there wasn't enough memory. + * + * \note The palette entries are initialized to white. + * + * \sa SDL_FreePalette() + */ +extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors); + +/** + * \brief Set the palette for a pixel format structure. + */ +extern DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat * format, + SDL_Palette *palette); + +/** + * \brief Set a range of colors in a palette. + * + * \param palette The palette to modify. + * \param colors An array of colors to copy into the palette. + * \param firstcolor The index of the first palette entry to modify. + * \param ncolors The number of entries to modify. + * + * \return 0 on success, or -1 if not all of the colors could be set. + */ +extern DECLSPEC int SDLCALL SDL_SetPaletteColors(SDL_Palette * palette, + const SDL_Color * colors, + int firstcolor, int ncolors); + +/** + * \brief Free a palette created with SDL_AllocPalette(). + * + * \sa SDL_AllocPalette() + */ +extern DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette * palette); + +/** + * \brief Maps an RGB triple to an opaque pixel value for a given pixel format. + * + * \sa SDL_MapRGBA + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGB(const SDL_PixelFormat * format, + Uint8 r, Uint8 g, Uint8 b); + +/** + * \brief Maps an RGBA quadruple to a pixel value for a given pixel format. + * + * \sa SDL_MapRGB + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormat * format, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * \brief Get the RGB components from a pixel of the specified format. + * + * \sa SDL_GetRGBA + */ +extern DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, + const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b); + +/** + * \brief Get the RGBA components from a pixel of the specified format. + * + * \sa SDL_GetRGB + */ +extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, + const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * \brief Calculate a 256 entry gamma ramp for a gamma value. + */ +extern DECLSPEC void SDLCALL SDL_CalculateGammaRamp(float gamma, Uint16 * ramp); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_pixels_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_platform.h b/packages/sdl2.2.0.5/build/native/include/SDL_platform.h new file mode 100644 index 00000000..03cf1706 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_platform.h @@ -0,0 +1,185 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_platform.h + * + * Try to get a standard set of platform defines. + */ + +#ifndef _SDL_platform_h +#define _SDL_platform_h + +#if defined(_AIX) +#undef __AIX__ +#define __AIX__ 1 +#endif +#if defined(__HAIKU__) +#undef __HAIKU__ +#define __HAIKU__ 1 +#endif +#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) +#undef __BSDI__ +#define __BSDI__ 1 +#endif +#if defined(_arch_dreamcast) +#undef __DREAMCAST__ +#define __DREAMCAST__ 1 +#endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#undef __FREEBSD__ +#define __FREEBSD__ 1 +#endif +#if defined(hpux) || defined(__hpux) || defined(__hpux__) +#undef __HPUX__ +#define __HPUX__ 1 +#endif +#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) +#undef __IRIX__ +#define __IRIX__ 1 +#endif +#if (defined(linux) || defined(__linux) || defined(__linux__)) +#undef __LINUX__ +#define __LINUX__ 1 +#endif +#if defined(ANDROID) || defined(__ANDROID__) +#undef __ANDROID__ +#undef __LINUX__ /* do we need to do this? */ +#define __ANDROID__ 1 +#endif + +#if defined(__APPLE__) +/* lets us know what version of Mac OS X we're compiling on */ +#include "AvailabilityMacros.h" +#include "TargetConditionals.h" +#if TARGET_OS_TV +#undef __TVOS__ +#define __TVOS__ 1 +#endif +#if TARGET_OS_IPHONE +/* if compiling for iOS */ +#undef __IPHONEOS__ +#define __IPHONEOS__ 1 +#undef __MACOSX__ +#else +/* if not compiling for iOS */ +#undef __MACOSX__ +#define __MACOSX__ 1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +# error SDL for Mac OS X only supports deploying on 10.6 and above. +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ +#endif /* TARGET_OS_IPHONE */ +#endif /* defined(__APPLE__) */ + +#if defined(__NetBSD__) +#undef __NETBSD__ +#define __NETBSD__ 1 +#endif +#if defined(__OpenBSD__) +#undef __OPENBSD__ +#define __OPENBSD__ 1 +#endif +#if defined(__OS2__) +#undef __OS2__ +#define __OS2__ 1 +#endif +#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) +#undef __OSF__ +#define __OSF__ 1 +#endif +#if defined(__QNXNTO__) +#undef __QNXNTO__ +#define __QNXNTO__ 1 +#endif +#if defined(riscos) || defined(__riscos) || defined(__riscos__) +#undef __RISCOS__ +#define __RISCOS__ 1 +#endif +#if defined(__sun) && defined(__SVR4) +#undef __SOLARIS__ +#define __SOLARIS__ 1 +#endif + +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) +/* Try to find out if we're compiling for WinRT or non-WinRT */ +/* If _USING_V110_SDK71_ is defined it means we are using the v110_xp or v120_xp toolset. */ +#if (defined(_MSC_VER) && (_MSC_VER >= 1700) && !_USING_V110_SDK71_) /* _MSC_VER==1700 for MSVC 2012 */ +#include +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#undef __WINDOWS__ +#define __WINDOWS__ 1 +/* See if we're compiling for WinRT: */ +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#undef __WINRT__ +#define __WINRT__ 1 +#endif +#else +#undef __WINDOWS__ +#define __WINDOWS__ 1 +#endif /* _MSC_VER < 1700 */ +#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */ + +#if defined(__WINDOWS__) +#undef __WIN32__ +#define __WIN32__ 1 +#endif +#if defined(__PSP__) +#undef __PSP__ +#define __PSP__ 1 +#endif + +/* The NACL compiler defines __native_client__ and __pnacl__ + * Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi + */ +#if defined(__native_client__) +#undef __LINUX__ +#undef __NACL__ +#define __NACL__ 1 +#endif +#if defined(__pnacl__) +#undef __LINUX__ +#undef __PNACL__ +#define __PNACL__ 1 +/* PNACL with newlib supports static linking only */ +#define __SDL_NOGETPROCADDR__ +#endif + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Gets the name of the platform. + */ +extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_platform_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_power.h b/packages/sdl2.2.0.5/build/native/include/SDL_power.h new file mode 100644 index 00000000..24c05011 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_power.h @@ -0,0 +1,75 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_power_h +#define _SDL_power_h + +/** + * \file SDL_power.h + * + * Header for the SDL power management routines. + */ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The basic state for the system's power supply. + */ +typedef enum +{ + SDL_POWERSTATE_UNKNOWN, /**< cannot determine power status */ + SDL_POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */ + SDL_POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */ + SDL_POWERSTATE_CHARGING, /**< Plugged in, charging battery */ + SDL_POWERSTATE_CHARGED /**< Plugged in, battery charged */ +} SDL_PowerState; + + +/** + * \brief Get the current power supply details. + * + * \param secs Seconds of battery life left. You can pass a NULL here if + * you don't care. Will return -1 if we can't determine a + * value, or we're not running on a battery. + * + * \param pct Percentage of battery life left, between 0 and 100. You can + * pass a NULL here if you don't care. Will return -1 if we + * can't determine a value, or we're not running on a battery. + * + * \return The state of the battery (if any). + */ +extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_power_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_quit.h b/packages/sdl2.2.0.5/build/native/include/SDL_quit.h new file mode 100644 index 00000000..cc06f28d --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_quit.h @@ -0,0 +1,58 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_quit.h + * + * Include file for SDL quit event handling. + */ + +#ifndef _SDL_quit_h +#define _SDL_quit_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/** + * \file SDL_quit.h + * + * An ::SDL_QUIT event is generated when the user tries to close the application + * window. If it is ignored or filtered out, the window will remain open. + * If it is not ignored or filtered, it is queued normally and the window + * is allowed to close. When the window is closed, screen updates will + * complete, but have no effect. + * + * SDL_Init() installs signal handlers for SIGINT (keyboard interrupt) + * and SIGTERM (system termination request), if handlers do not already + * exist, that generate ::SDL_QUIT events as well. There is no way + * to determine the cause of an ::SDL_QUIT event, but setting a signal + * handler in your application will override the default generation of + * quit events for that signal. + * + * \sa SDL_Quit() + */ + +/* There are no functions directly affecting the quit event */ + +#define SDL_QuitRequested() \ + (SDL_PumpEvents(), (SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_QUIT,SDL_QUIT) > 0)) + +#endif /* _SDL_quit_h */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_rect.h b/packages/sdl2.2.0.5/build/native/include/SDL_rect.h new file mode 100644 index 00000000..bbcb9a3b --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_rect.h @@ -0,0 +1,148 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_rect.h + * + * Header file for SDL_rect definition and management functions. + */ + +#ifndef _SDL_rect_h +#define _SDL_rect_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_pixels.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The structure that defines a point + * + * \sa SDL_EnclosePoints + * \sa SDL_PointInRect + */ +typedef struct SDL_Point +{ + int x; + int y; +} SDL_Point; + +/** + * \brief A rectangle, with the origin at the upper left. + * + * \sa SDL_RectEmpty + * \sa SDL_RectEquals + * \sa SDL_HasIntersection + * \sa SDL_IntersectRect + * \sa SDL_UnionRect + * \sa SDL_EnclosePoints + */ +typedef struct SDL_Rect +{ + int x, y; + int w, h; +} SDL_Rect; + +/** + * \brief Returns true if point resides inside a rectangle. + */ +SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) +{ + return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; +} + +/** + * \brief Returns true if the rectangle has no area. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r) +{ + return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * \brief Returns true if the two rectangles are equal. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b) +{ + return (a && b && (a->x == b->x) && (a->y == b->y) && + (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * \brief Determine whether two rectangles intersect. + * + * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect * A, + const SDL_Rect * B); + +/** + * \brief Calculate the intersection of two rectangles. + * + * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * \brief Calculate the union of two rectangles. + */ +extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * \brief Calculate a minimal rectangle enclosing a set of points + * + * \return SDL_TRUE if any points were within the clipping rect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points, + int count, + const SDL_Rect * clip, + SDL_Rect * result); + +/** + * \brief Calculate the intersection of a rectangle and line segment. + * + * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect * + rect, int *X1, + int *Y1, int *X2, + int *Y2); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_rect_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_render.h b/packages/sdl2.2.0.5/build/native/include/SDL_render.h new file mode 100644 index 00000000..60c87b66 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_render.h @@ -0,0 +1,905 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_render.h + * + * Header file for SDL 2D rendering functions. + * + * This API supports the following features: + * * single pixel points + * * single pixel lines + * * filled rectangles + * * texture images + * + * The primitives may be drawn in opaque, blended, or additive modes. + * + * The texture images may be drawn in opaque, blended, or additive modes. + * They can have an additional color tint or alpha modulation applied to + * them, and may also be stretched with linear interpolation. + * + * This API is designed to accelerate simple 2D operations. You may + * want more functionality such as polygons and particle effects and + * in that case you should use SDL's OpenGL/Direct3D support or one + * of the many good 3D engines. + * + * These functions must be called from the main thread. + * See this bug for details: http://bugzilla.libsdl.org/show_bug.cgi?id=1995 + */ + +#ifndef _SDL_render_h +#define _SDL_render_h + +#include "SDL_stdinc.h" +#include "SDL_rect.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Flags used when creating a rendering context + */ +typedef enum +{ + SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */ + SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware + acceleration */ + SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized + with the refresh rate */ + SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports + rendering to texture */ +} SDL_RendererFlags; + +/** + * \brief Information on the capabilities of a render driver or context. + */ +typedef struct SDL_RendererInfo +{ + const char *name; /**< The name of the renderer */ + Uint32 flags; /**< Supported ::SDL_RendererFlags */ + Uint32 num_texture_formats; /**< The number of available texture formats */ + Uint32 texture_formats[16]; /**< The available texture formats */ + int max_texture_width; /**< The maximum texture width */ + int max_texture_height; /**< The maximum texture height */ +} SDL_RendererInfo; + +/** + * \brief The access pattern allowed for a texture. + */ +typedef enum +{ + SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */ + SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */ + SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */ +} SDL_TextureAccess; + +/** + * \brief The texture channel modulation used in SDL_RenderCopy(). + */ +typedef enum +{ + SDL_TEXTUREMODULATE_NONE = 0x00000000, /**< No modulation */ + SDL_TEXTUREMODULATE_COLOR = 0x00000001, /**< srcC = srcC * color */ + SDL_TEXTUREMODULATE_ALPHA = 0x00000002 /**< srcA = srcA * alpha */ +} SDL_TextureModulate; + +/** + * \brief Flip constants for SDL_RenderCopyEx + */ +typedef enum +{ + SDL_FLIP_NONE = 0x00000000, /**< Do not flip */ + SDL_FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */ + SDL_FLIP_VERTICAL = 0x00000002 /**< flip vertically */ +} SDL_RendererFlip; + +/** + * \brief A structure representing rendering state + */ +struct SDL_Renderer; +typedef struct SDL_Renderer SDL_Renderer; + +/** + * \brief An efficient driver-specific representation of pixel data + */ +struct SDL_Texture; +typedef struct SDL_Texture SDL_Texture; + + +/* Function prototypes */ + +/** + * \brief Get the number of 2D rendering drivers available for the current + * display. + * + * A render driver is a set of code that handles rendering and texture + * management on a particular display. Normally there is only one, but + * some drivers may have several available with different capabilities. + * + * \sa SDL_GetRenderDriverInfo() + * \sa SDL_CreateRenderer() + */ +extern DECLSPEC int SDLCALL SDL_GetNumRenderDrivers(void); + +/** + * \brief Get information about a specific 2D rendering driver for the current + * display. + * + * \param index The index of the driver to query information about. + * \param info A pointer to an SDL_RendererInfo struct to be filled with + * information on the rendering driver. + * + * \return 0 on success, -1 if the index was out of range. + * + * \sa SDL_CreateRenderer() + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDriverInfo(int index, + SDL_RendererInfo * info); + +/** + * \brief Create a window and default renderer + * + * \param width The width of the window + * \param height The height of the window + * \param window_flags The flags used to create the window + * \param window A pointer filled with the window, or NULL on error + * \param renderer A pointer filled with the renderer, or NULL on error + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_CreateWindowAndRenderer( + int width, int height, Uint32 window_flags, + SDL_Window **window, SDL_Renderer **renderer); + + +/** + * \brief Create a 2D rendering context for a window. + * + * \param window The window where rendering is displayed. + * \param index The index of the rendering driver to initialize, or -1 to + * initialize the first one supporting the requested flags. + * \param flags ::SDL_RendererFlags. + * + * \return A valid rendering context or NULL if there was an error. + * + * \sa SDL_CreateSoftwareRenderer() + * \sa SDL_GetRendererInfo() + * \sa SDL_DestroyRenderer() + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window, + int index, Uint32 flags); + +/** + * \brief Create a 2D software rendering context for a surface. + * + * \param surface The surface where rendering is done. + * + * \return A valid rendering context or NULL if there was an error. + * + * \sa SDL_CreateRenderer() + * \sa SDL_DestroyRenderer() + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface * surface); + +/** + * \brief Get the renderer associated with a window. + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window); + +/** + * \brief Get information about a rendering context. + */ +extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer, + SDL_RendererInfo * info); + +/** + * \brief Get the output size in pixels of a rendering context. + */ +extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer, + int *w, int *h); + +/** + * \brief Create a texture for a rendering context. + * + * \param renderer The renderer. + * \param format The format of the texture. + * \param access One of the enumerated values in ::SDL_TextureAccess. + * \param w The width of the texture in pixels. + * \param h The height of the texture in pixels. + * + * \return The created texture is returned, or NULL if no rendering context was + * active, the format was unsupported, or the width or height were out + * of range. + * + * \sa SDL_QueryTexture() + * \sa SDL_UpdateTexture() + * \sa SDL_DestroyTexture() + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer, + Uint32 format, + int access, int w, + int h); + +/** + * \brief Create a texture from an existing surface. + * + * \param renderer The renderer. + * \param surface The surface containing pixel data used to fill the texture. + * + * \return The created texture is returned, or NULL on error. + * + * \note The surface is not modified or freed by this function. + * + * \sa SDL_QueryTexture() + * \sa SDL_DestroyTexture() + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface); + +/** + * \brief Query the attributes of a texture + * + * \param texture A texture to be queried. + * \param format A pointer filled in with the raw format of the texture. The + * actual format may differ, but pixel transfers will use this + * format. + * \param access A pointer filled in with the actual access to the texture. + * \param w A pointer filled in with the width of the texture in pixels. + * \param h A pointer filled in with the height of the texture in pixels. + * + * \return 0 on success, or -1 if the texture is not valid. + */ +extern DECLSPEC int SDLCALL SDL_QueryTexture(SDL_Texture * texture, + Uint32 * format, int *access, + int *w, int *h); + +/** + * \brief Set an additional color value used in render copy operations. + * + * \param texture The texture to update. + * \param r The red color value multiplied into copy operations. + * \param g The green color value multiplied into copy operations. + * \param b The blue color value multiplied into copy operations. + * + * \return 0 on success, or -1 if the texture is not valid or color modulation + * is not supported. + * + * \sa SDL_GetTextureColorMod() + */ +extern DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture * texture, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * \brief Get the additional color value used in render copy operations. + * + * \param texture The texture to query. + * \param r A pointer filled in with the current red color value. + * \param g A pointer filled in with the current green color value. + * \param b A pointer filled in with the current blue color value. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \sa SDL_SetTextureColorMod() + */ +extern DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture * texture, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * \brief Set an additional alpha value used in render copy operations. + * + * \param texture The texture to update. + * \param alpha The alpha value multiplied into copy operations. + * + * \return 0 on success, or -1 if the texture is not valid or alpha modulation + * is not supported. + * + * \sa SDL_GetTextureAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture * texture, + Uint8 alpha); + +/** + * \brief Get the additional alpha value used in render copy operations. + * + * \param texture The texture to query. + * \param alpha A pointer filled in with the current alpha value. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \sa SDL_SetTextureAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_GetTextureAlphaMod(SDL_Texture * texture, + Uint8 * alpha); + +/** + * \brief Set the blend mode used for texture copy operations. + * + * \param texture The texture to update. + * \param blendMode ::SDL_BlendMode to use for texture blending. + * + * \return 0 on success, or -1 if the texture is not valid or the blend mode is + * not supported. + * + * \note If the blend mode is not supported, the closest supported mode is + * chosen. + * + * \sa SDL_GetTextureBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_SetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode blendMode); + +/** + * \brief Get the blend mode used for texture copy operations. + * + * \param texture The texture to query. + * \param blendMode A pointer filled in with the current blend mode. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \sa SDL_SetTextureBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_GetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode *blendMode); + +/** + * \brief Update the given texture rectangle with new pixel data. + * + * \param texture The texture to update + * \param rect A pointer to the rectangle of pixels to update, or NULL to + * update the entire texture. + * \param pixels The raw pixel data. + * \param pitch The number of bytes in a row of pixel data, including padding between lines. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \note This is a fairly slow function. + */ +extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const void *pixels, int pitch); + +/** + * \brief Update a rectangle within a planar YV12 or IYUV texture with new pixel data. + * + * \param texture The texture to update + * \param rect A pointer to the rectangle of pixels to update, or NULL to + * update the entire texture. + * \param Yplane The raw pixel data for the Y plane. + * \param Ypitch The number of bytes between rows of pixel data for the Y plane. + * \param Uplane The raw pixel data for the U plane. + * \param Upitch The number of bytes between rows of pixel data for the U plane. + * \param Vplane The raw pixel data for the V plane. + * \param Vpitch The number of bytes between rows of pixel data for the V plane. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \note You can use SDL_UpdateTexture() as long as your pixel data is + * a contiguous block of Y and U/V planes in the proper order, but + * this function is available if your pixel data is not contiguous. + */ +extern DECLSPEC int SDLCALL SDL_UpdateYUVTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); + +/** + * \brief Lock a portion of the texture for write-only pixel access. + * + * \param texture The texture to lock for access, which was created with + * ::SDL_TEXTUREACCESS_STREAMING. + * \param rect A pointer to the rectangle to lock for access. If the rect + * is NULL, the entire texture will be locked. + * \param pixels This is filled in with a pointer to the locked pixels, + * appropriately offset by the locked area. + * \param pitch This is filled in with the pitch of the locked pixels. + * + * \return 0 on success, or -1 if the texture is not valid or was not created with ::SDL_TEXTUREACCESS_STREAMING. + * + * \sa SDL_UnlockTexture() + */ +extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture * texture, + const SDL_Rect * rect, + void **pixels, int *pitch); + +/** + * \brief Unlock a texture, uploading the changes to video memory, if needed. + * + * \sa SDL_LockTexture() + */ +extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture); + +/** + * \brief Determines whether a window supports the use of render targets + * + * \param renderer The renderer that will be checked + * + * \return SDL_TRUE if supported, SDL_FALSE if not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderTargetSupported(SDL_Renderer *renderer); + +/** + * \brief Set a texture as the current rendering target. + * + * \param renderer The renderer. + * \param texture The targeted texture, which must be created with the SDL_TEXTUREACCESS_TARGET flag, or NULL for the default render target + * + * \return 0 on success, or -1 on error + * + * \sa SDL_GetRenderTarget() + */ +extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, + SDL_Texture *texture); + +/** + * \brief Get the current render target or NULL for the default render target. + * + * \return The current render target + * + * \sa SDL_SetRenderTarget() + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer); + +/** + * \brief Set device independent resolution for rendering + * + * \param renderer The renderer for which resolution should be set. + * \param w The width of the logical resolution + * \param h The height of the logical resolution + * + * This function uses the viewport and scaling functionality to allow a fixed logical + * resolution for rendering, regardless of the actual output resolution. If the actual + * output resolution doesn't have the same aspect ratio the output rendering will be + * centered within the output display. + * + * If the output display is a window, mouse events in the window will be filtered + * and scaled so they seem to arrive within the logical resolution. + * + * \note If this function results in scaling or subpixel drawing by the + * rendering backend, it will be handled using the appropriate + * quality hints. + * + * \sa SDL_RenderGetLogicalSize() + * \sa SDL_RenderSetScale() + * \sa SDL_RenderSetViewport() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h); + +/** + * \brief Get device independent resolution for rendering + * + * \param renderer The renderer from which resolution should be queried. + * \param w A pointer filled with the width of the logical resolution + * \param h A pointer filled with the height of the logical resolution + * + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h); + +/** + * \brief Set whether to force integer scales for resolution-independent rendering + * + * \param renderer The renderer for which integer scaling should be set. + * \param enable Enable or disable integer scaling + * + * This function restricts the logical viewport to integer values - that is, when + * a resolution is between two multiples of a logical size, the viewport size is + * rounded down to the lower multiple. + * + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetIntegerScale(SDL_Renderer * renderer, + SDL_bool enable); + +/** + * \brief Get whether integer scales are forced for resolution-independent rendering + * + * \param renderer The renderer from which integer scaling should be queried. + * + * \sa SDL_RenderSetIntegerScale() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer); + +/** + * \brief Set the drawing area for rendering on the current target. + * + * \param renderer The renderer for which the drawing area should be set. + * \param rect The rectangle representing the drawing area, or NULL to set the viewport to the entire target. + * + * The x,y of the viewport rect represents the origin for rendering. + * + * \return 0 on success, or -1 on error + * + * \note If the window associated with the renderer is resized, the viewport is automatically reset. + * + * \sa SDL_RenderGetViewport() + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * \brief Get the drawing area for the current target. + * + * \sa SDL_RenderSetViewport() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * \brief Set the clip rectangle for the current target. + * + * \param renderer The renderer for which clip rectangle should be set. + * \param rect A pointer to the rectangle to set as the clip rectangle, or + * NULL to disable clipping. + * + * \return 0 on success, or -1 on error + * + * \sa SDL_RenderGetClipRect() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * \brief Get the clip rectangle for the current target. + * + * \param renderer The renderer from which clip rectangle should be queried. + * \param rect A pointer filled in with the current clip rectangle, or + * an empty rectangle if clipping is disabled. + * + * \sa SDL_RenderSetClipRect() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * \brief Get whether clipping is enabled on the given renderer. + * + * \param renderer The renderer from which clip state should be queried. + * + * \sa SDL_RenderGetClipRect() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderIsClipEnabled(SDL_Renderer * renderer); + + +/** + * \brief Set the drawing scale for rendering on the current target. + * + * \param renderer The renderer for which the drawing scale should be set. + * \param scaleX The horizontal scaling factor + * \param scaleY The vertical scaling factor + * + * The drawing coordinates are scaled by the x/y scaling factors + * before they are used by the renderer. This allows resolution + * independent drawing with a single coordinate system. + * + * \note If this results in scaling or subpixel drawing by the + * rendering backend, it will be handled using the appropriate + * quality hints. For best results use integer scaling factors. + * + * \sa SDL_RenderGetScale() + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, + float scaleX, float scaleY); + +/** + * \brief Get the drawing scale for the current target. + * + * \param renderer The renderer from which drawing scale should be queried. + * \param scaleX A pointer filled in with the horizontal scaling factor + * \param scaleY A pointer filled in with the vertical scaling factor + * + * \sa SDL_RenderSetScale() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, + float *scaleX, float *scaleY); + +/** + * \brief Set the color used for drawing operations (Rect, Line and Clear). + * + * \param renderer The renderer for which drawing color should be set. + * \param r The red value used to draw on the rendering target. + * \param g The green value used to draw on the rendering target. + * \param b The blue value used to draw on the rendering target. + * \param a The alpha value used to draw on the rendering target, usually + * ::SDL_ALPHA_OPAQUE (255). + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * \brief Get the color used for drawing operations (Rect, Line and Clear). + * + * \param renderer The renderer from which drawing color should be queried. + * \param r A pointer to the red value used to draw on the rendering target. + * \param g A pointer to the green value used to draw on the rendering target. + * \param b A pointer to the blue value used to draw on the rendering target. + * \param a A pointer to the alpha value used to draw on the rendering target, + * usually ::SDL_ALPHA_OPAQUE (255). + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawColor(SDL_Renderer * renderer, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * \brief Set the blend mode used for drawing operations (Fill and Line). + * + * \param renderer The renderer for which blend mode should be set. + * \param blendMode ::SDL_BlendMode to use for blending. + * + * \return 0 on success, or -1 on error + * + * \note If the blend mode is not supported, the closest supported mode is + * chosen. + * + * \sa SDL_GetRenderDrawBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode blendMode); + +/** + * \brief Get the blend mode used for drawing operations. + * + * \param renderer The renderer from which blend mode should be queried. + * \param blendMode A pointer filled in with the current blend mode. + * + * \return 0 on success, or -1 on error + * + * \sa SDL_SetRenderDrawBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode *blendMode); + +/** + * \brief Clear the current rendering target with the drawing color + * + * This function clears the entire rendering target, ignoring the viewport and + * the clip rectangle. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer); + +/** + * \brief Draw a point on the current rendering target. + * + * \param renderer The renderer which should draw a point. + * \param x The x coordinate of the point. + * \param y The y coordinate of the point. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoint(SDL_Renderer * renderer, + int x, int y); + +/** + * \brief Draw multiple points on the current rendering target. + * + * \param renderer The renderer which should draw multiple points. + * \param points The points to draw + * \param count The number of points to draw + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * \brief Draw a line on the current rendering target. + * + * \param renderer The renderer which should draw a line. + * \param x1 The x coordinate of the start point. + * \param y1 The y coordinate of the start point. + * \param x2 The x coordinate of the end point. + * \param y2 The y coordinate of the end point. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLine(SDL_Renderer * renderer, + int x1, int y1, int x2, int y2); + +/** + * \brief Draw a series of connected lines on the current rendering target. + * + * \param renderer The renderer which should draw multiple lines. + * \param points The points along the lines + * \param count The number of points, drawing count-1 lines + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * \brief Draw a rectangle on the current rendering target. + * + * \param renderer The renderer which should draw a rectangle. + * \param rect A pointer to the destination rectangle, or NULL to outline the entire rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * \brief Draw some number of rectangles on the current rendering target. + * + * \param renderer The renderer which should draw multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * \brief Fill a rectangle on the current rendering target with the drawing color. + * + * \param renderer The renderer which should fill a rectangle. + * \param rect A pointer to the destination rectangle, or NULL for the entire + * rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * \brief Fill some number of rectangles on the current rendering target with the drawing color. + * + * \param renderer The renderer which should fill multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * \brief Copy a portion of the texture to the current rendering target. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); + +/** + * \brief Copy a portion of the source texture to the current rendering target, rotating it by angle around the given center + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \param angle An angle in degrees that indicates the rotation that will be applied to dstrect + * \param center A pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done around dstrect.w/2, dstrect.h/2). + * \param flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyEx(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect, + const double angle, + const SDL_Point *center, + const SDL_RendererFlip flip); + +/** + * \brief Read pixels from the current rendering target. + * + * \param renderer The renderer from which pixels should be read. + * \param rect A pointer to the rectangle to read, or NULL for the entire + * render target. + * \param format The desired format of the pixel data, or 0 to use the format + * of the rendering target + * \param pixels A pointer to be filled in with the pixel data + * \param pitch The pitch of the pixels parameter. + * + * \return 0 on success, or -1 if pixel reading is not supported. + * + * \warning This is a very slow operation, and should not be used frequently. + */ +extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer * renderer, + const SDL_Rect * rect, + Uint32 format, + void *pixels, int pitch); + +/** + * \brief Update the screen with rendering performed. + */ +extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer); + +/** + * \brief Destroy the specified texture. + * + * \sa SDL_CreateTexture() + * \sa SDL_CreateTextureFromSurface() + */ +extern DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_Texture * texture); + +/** + * \brief Destroy the rendering context for a window and free associated + * textures. + * + * \sa SDL_CreateRenderer() + */ +extern DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_Renderer * renderer); + + +/** + * \brief Bind the texture to the current OpenGL/ES/ES2 context for use with + * OpenGL instructions. + * + * \param texture The SDL texture to bind + * \param texw A pointer to a float that will be filled with the texture width + * \param texh A pointer to a float that will be filled with the texture height + * + * \return 0 on success, or -1 if the operation is not supported + */ +extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh); + +/** + * \brief Unbind a texture from the current OpenGL/ES/ES2 context. + * + * \param texture The SDL texture to unbind + * + * \return 0 on success, or -1 if the operation is not supported + */ +extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_render_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_revision.h b/packages/sdl2.2.0.5/build/native/include/SDL_revision.h new file mode 100644 index 00000000..341dc5cc --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_revision.h @@ -0,0 +1,2 @@ +#define SDL_REVISION "hg-10556:007dfe83abf8" +#define SDL_REVISION_NUMBER 10556 diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_rwops.h b/packages/sdl2.2.0.5/build/native/include/SDL_rwops.h new file mode 100644 index 00000000..1ad3ac40 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_rwops.h @@ -0,0 +1,231 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_rwops.h + * + * This file provides a general interface for SDL to read and write + * data streams. It can easily be extended to files, memory, etc. + */ + +#ifndef _SDL_rwops_h +#define _SDL_rwops_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* RWops Types */ +#define SDL_RWOPS_UNKNOWN 0U /* Unknown stream type */ +#define SDL_RWOPS_WINFILE 1U /* Win32 file */ +#define SDL_RWOPS_STDFILE 2U /* Stdio file */ +#define SDL_RWOPS_JNIFILE 3U /* Android asset */ +#define SDL_RWOPS_MEMORY 4U /* Memory stream */ +#define SDL_RWOPS_MEMORY_RO 5U /* Read-Only memory stream */ + +/** + * This is the read/write operation structure -- very basic. + */ +typedef struct SDL_RWops +{ + /** + * Return the size of the file in this rwops, or -1 if unknown + */ + Sint64 (SDLCALL * size) (struct SDL_RWops * context); + + /** + * Seek to \c offset relative to \c whence, one of stdio's whence values: + * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END + * + * \return the final offset in the data stream, or -1 on error. + */ + Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, + int whence); + + /** + * Read up to \c maxnum objects each of size \c size from the data + * stream to the area pointed at by \c ptr. + * + * \return the number of objects read, or 0 at error or end of file. + */ + size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr, + size_t size, size_t maxnum); + + /** + * Write exactly \c num objects each of size \c size from the area + * pointed at by \c ptr to data stream. + * + * \return the number of objects written, or 0 at error or end of file. + */ + size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, + size_t size, size_t num); + + /** + * Close and free an allocated SDL_RWops structure. + * + * \return 0 if successful or -1 on write error when flushing data. + */ + int (SDLCALL * close) (struct SDL_RWops * context); + + Uint32 type; + union + { +#if defined(__ANDROID__) + struct + { + void *fileNameRef; + void *inputStreamRef; + void *readableByteChannelRef; + void *readMethod; + void *assetFileDescriptorRef; + long position; + long size; + long offset; + int fd; + } androidio; +#elif defined(__WIN32__) + struct + { + SDL_bool append; + void *h; + struct + { + void *data; + size_t size; + size_t left; + } buffer; + } windowsio; +#endif + +#ifdef HAVE_STDIO_H + struct + { + SDL_bool autoclose; + FILE *fp; + } stdio; +#endif + struct + { + Uint8 *base; + Uint8 *here; + Uint8 *stop; + } mem; + struct + { + void *data1; + void *data2; + } unknown; + } hidden; + +} SDL_RWops; + + +/** + * \name RWFrom functions + * + * Functions to create SDL_RWops structures from various data streams. + */ +/* @{ */ + +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, + const char *mode); + +#ifdef HAVE_STDIO_H +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(FILE * fp, + SDL_bool autoclose); +#else +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(void * fp, + SDL_bool autoclose); +#endif + +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, int size); +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, + int size); + +/* @} *//* RWFrom functions */ + + +extern DECLSPEC SDL_RWops *SDLCALL SDL_AllocRW(void); +extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); + +#define RW_SEEK_SET 0 /**< Seek from the beginning of data */ +#define RW_SEEK_CUR 1 /**< Seek relative to current read point */ +#define RW_SEEK_END 2 /**< Seek relative to the end of data */ + +/** + * \name Read/write macros + * + * Macros to easily read and write from an SDL_RWops structure. + */ +/* @{ */ +#define SDL_RWsize(ctx) (ctx)->size(ctx) +#define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence) +#define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, RW_SEEK_CUR) +#define SDL_RWread(ctx, ptr, size, n) (ctx)->read(ctx, ptr, size, n) +#define SDL_RWwrite(ctx, ptr, size, n) (ctx)->write(ctx, ptr, size, n) +#define SDL_RWclose(ctx) (ctx)->close(ctx) +/* @} *//* Read/write macros */ + + +/** + * \name Read endian functions + * + * Read an item of the specified endianness and return in native format. + */ +/* @{ */ +extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); +extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); +extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); +extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); +extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); +extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); +extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); +/* @} *//* Read endian functions */ + +/** + * \name Write endian functions + * + * Write an item of native format to the specified endianness. + */ +/* @{ */ +extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); +extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); +extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); +extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); +extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); +extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); +extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); +/* @} *//* Write endian functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_rwops_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_scancode.h b/packages/sdl2.2.0.5/build/native/include/SDL_scancode.h new file mode 100644 index 00000000..0af1dd59 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_scancode.h @@ -0,0 +1,401 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_scancode.h + * + * Defines keyboard scancodes. + */ + +#ifndef _SDL_scancode_h +#define _SDL_scancode_h + +#include "SDL_stdinc.h" + +/** + * \brief The SDL keyboard scancode representation. + * + * Values of this type are used to represent keyboard keys, among other places + * in the \link SDL_Keysym::scancode key.keysym.scancode \endlink field of the + * SDL_Event structure. + * + * The values in this enumeration are based on the USB usage page standard: + * http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf + */ +typedef enum +{ + SDL_SCANCODE_UNKNOWN = 0, + + /** + * \name Usage page 0x07 + * + * These values are from usage page 0x07 (USB keyboard page). + */ + /* @{ */ + + SDL_SCANCODE_A = 4, + SDL_SCANCODE_B = 5, + SDL_SCANCODE_C = 6, + SDL_SCANCODE_D = 7, + SDL_SCANCODE_E = 8, + SDL_SCANCODE_F = 9, + SDL_SCANCODE_G = 10, + SDL_SCANCODE_H = 11, + SDL_SCANCODE_I = 12, + SDL_SCANCODE_J = 13, + SDL_SCANCODE_K = 14, + SDL_SCANCODE_L = 15, + SDL_SCANCODE_M = 16, + SDL_SCANCODE_N = 17, + SDL_SCANCODE_O = 18, + SDL_SCANCODE_P = 19, + SDL_SCANCODE_Q = 20, + SDL_SCANCODE_R = 21, + SDL_SCANCODE_S = 22, + SDL_SCANCODE_T = 23, + SDL_SCANCODE_U = 24, + SDL_SCANCODE_V = 25, + SDL_SCANCODE_W = 26, + SDL_SCANCODE_X = 27, + SDL_SCANCODE_Y = 28, + SDL_SCANCODE_Z = 29, + + SDL_SCANCODE_1 = 30, + SDL_SCANCODE_2 = 31, + SDL_SCANCODE_3 = 32, + SDL_SCANCODE_4 = 33, + SDL_SCANCODE_5 = 34, + SDL_SCANCODE_6 = 35, + SDL_SCANCODE_7 = 36, + SDL_SCANCODE_8 = 37, + SDL_SCANCODE_9 = 38, + SDL_SCANCODE_0 = 39, + + SDL_SCANCODE_RETURN = 40, + SDL_SCANCODE_ESCAPE = 41, + SDL_SCANCODE_BACKSPACE = 42, + SDL_SCANCODE_TAB = 43, + SDL_SCANCODE_SPACE = 44, + + SDL_SCANCODE_MINUS = 45, + SDL_SCANCODE_EQUALS = 46, + SDL_SCANCODE_LEFTBRACKET = 47, + SDL_SCANCODE_RIGHTBRACKET = 48, + SDL_SCANCODE_BACKSLASH = 49, /**< Located at the lower left of the return + * key on ISO keyboards and at the right end + * of the QWERTY row on ANSI keyboards. + * Produces REVERSE SOLIDUS (backslash) and + * VERTICAL LINE in a US layout, REVERSE + * SOLIDUS and VERTICAL LINE in a UK Mac + * layout, NUMBER SIGN and TILDE in a UK + * Windows layout, DOLLAR SIGN and POUND SIGN + * in a Swiss German layout, NUMBER SIGN and + * APOSTROPHE in a German layout, GRAVE + * ACCENT and POUND SIGN in a French Mac + * layout, and ASTERISK and MICRO SIGN in a + * French Windows layout. + */ + SDL_SCANCODE_NONUSHASH = 50, /**< ISO USB keyboards actually use this code + * instead of 49 for the same key, but all + * OSes I've seen treat the two codes + * identically. So, as an implementor, unless + * your keyboard generates both of those + * codes and your OS treats them differently, + * you should generate SDL_SCANCODE_BACKSLASH + * instead of this code. As a user, you + * should not rely on this code because SDL + * will never generate it with most (all?) + * keyboards. + */ + SDL_SCANCODE_SEMICOLON = 51, + SDL_SCANCODE_APOSTROPHE = 52, + SDL_SCANCODE_GRAVE = 53, /**< Located in the top left corner (on both ANSI + * and ISO keyboards). Produces GRAVE ACCENT and + * TILDE in a US Windows layout and in US and UK + * Mac layouts on ANSI keyboards, GRAVE ACCENT + * and NOT SIGN in a UK Windows layout, SECTION + * SIGN and PLUS-MINUS SIGN in US and UK Mac + * layouts on ISO keyboards, SECTION SIGN and + * DEGREE SIGN in a Swiss German layout (Mac: + * only on ISO keyboards), CIRCUMFLEX ACCENT and + * DEGREE SIGN in a German layout (Mac: only on + * ISO keyboards), SUPERSCRIPT TWO and TILDE in a + * French Windows layout, COMMERCIAL AT and + * NUMBER SIGN in a French Mac layout on ISO + * keyboards, and LESS-THAN SIGN and GREATER-THAN + * SIGN in a Swiss German, German, or French Mac + * layout on ANSI keyboards. + */ + SDL_SCANCODE_COMMA = 54, + SDL_SCANCODE_PERIOD = 55, + SDL_SCANCODE_SLASH = 56, + + SDL_SCANCODE_CAPSLOCK = 57, + + SDL_SCANCODE_F1 = 58, + SDL_SCANCODE_F2 = 59, + SDL_SCANCODE_F3 = 60, + SDL_SCANCODE_F4 = 61, + SDL_SCANCODE_F5 = 62, + SDL_SCANCODE_F6 = 63, + SDL_SCANCODE_F7 = 64, + SDL_SCANCODE_F8 = 65, + SDL_SCANCODE_F9 = 66, + SDL_SCANCODE_F10 = 67, + SDL_SCANCODE_F11 = 68, + SDL_SCANCODE_F12 = 69, + + SDL_SCANCODE_PRINTSCREEN = 70, + SDL_SCANCODE_SCROLLLOCK = 71, + SDL_SCANCODE_PAUSE = 72, + SDL_SCANCODE_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but + does send code 73, not 117) */ + SDL_SCANCODE_HOME = 74, + SDL_SCANCODE_PAGEUP = 75, + SDL_SCANCODE_DELETE = 76, + SDL_SCANCODE_END = 77, + SDL_SCANCODE_PAGEDOWN = 78, + SDL_SCANCODE_RIGHT = 79, + SDL_SCANCODE_LEFT = 80, + SDL_SCANCODE_DOWN = 81, + SDL_SCANCODE_UP = 82, + + SDL_SCANCODE_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards + */ + SDL_SCANCODE_KP_DIVIDE = 84, + SDL_SCANCODE_KP_MULTIPLY = 85, + SDL_SCANCODE_KP_MINUS = 86, + SDL_SCANCODE_KP_PLUS = 87, + SDL_SCANCODE_KP_ENTER = 88, + SDL_SCANCODE_KP_1 = 89, + SDL_SCANCODE_KP_2 = 90, + SDL_SCANCODE_KP_3 = 91, + SDL_SCANCODE_KP_4 = 92, + SDL_SCANCODE_KP_5 = 93, + SDL_SCANCODE_KP_6 = 94, + SDL_SCANCODE_KP_7 = 95, + SDL_SCANCODE_KP_8 = 96, + SDL_SCANCODE_KP_9 = 97, + SDL_SCANCODE_KP_0 = 98, + SDL_SCANCODE_KP_PERIOD = 99, + + SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO + * keyboards have over ANSI ones, + * located between left shift and Y. + * Produces GRAVE ACCENT and TILDE in a + * US or UK Mac layout, REVERSE SOLIDUS + * (backslash) and VERTICAL LINE in a + * US or UK Windows layout, and + * LESS-THAN SIGN and GREATER-THAN SIGN + * in a Swiss German, German, or French + * layout. */ + SDL_SCANCODE_APPLICATION = 101, /**< windows contextual menu, compose */ + SDL_SCANCODE_POWER = 102, /**< The USB document says this is a status flag, + * not a physical key - but some Mac keyboards + * do have a power key. */ + SDL_SCANCODE_KP_EQUALS = 103, + SDL_SCANCODE_F13 = 104, + SDL_SCANCODE_F14 = 105, + SDL_SCANCODE_F15 = 106, + SDL_SCANCODE_F16 = 107, + SDL_SCANCODE_F17 = 108, + SDL_SCANCODE_F18 = 109, + SDL_SCANCODE_F19 = 110, + SDL_SCANCODE_F20 = 111, + SDL_SCANCODE_F21 = 112, + SDL_SCANCODE_F22 = 113, + SDL_SCANCODE_F23 = 114, + SDL_SCANCODE_F24 = 115, + SDL_SCANCODE_EXECUTE = 116, + SDL_SCANCODE_HELP = 117, + SDL_SCANCODE_MENU = 118, + SDL_SCANCODE_SELECT = 119, + SDL_SCANCODE_STOP = 120, + SDL_SCANCODE_AGAIN = 121, /**< redo */ + SDL_SCANCODE_UNDO = 122, + SDL_SCANCODE_CUT = 123, + SDL_SCANCODE_COPY = 124, + SDL_SCANCODE_PASTE = 125, + SDL_SCANCODE_FIND = 126, + SDL_SCANCODE_MUTE = 127, + SDL_SCANCODE_VOLUMEUP = 128, + SDL_SCANCODE_VOLUMEDOWN = 129, +/* not sure whether there's a reason to enable these */ +/* SDL_SCANCODE_LOCKINGCAPSLOCK = 130, */ +/* SDL_SCANCODE_LOCKINGNUMLOCK = 131, */ +/* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */ + SDL_SCANCODE_KP_COMMA = 133, + SDL_SCANCODE_KP_EQUALSAS400 = 134, + + SDL_SCANCODE_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see + footnotes in USB doc */ + SDL_SCANCODE_INTERNATIONAL2 = 136, + SDL_SCANCODE_INTERNATIONAL3 = 137, /**< Yen */ + SDL_SCANCODE_INTERNATIONAL4 = 138, + SDL_SCANCODE_INTERNATIONAL5 = 139, + SDL_SCANCODE_INTERNATIONAL6 = 140, + SDL_SCANCODE_INTERNATIONAL7 = 141, + SDL_SCANCODE_INTERNATIONAL8 = 142, + SDL_SCANCODE_INTERNATIONAL9 = 143, + SDL_SCANCODE_LANG1 = 144, /**< Hangul/English toggle */ + SDL_SCANCODE_LANG2 = 145, /**< Hanja conversion */ + SDL_SCANCODE_LANG3 = 146, /**< Katakana */ + SDL_SCANCODE_LANG4 = 147, /**< Hiragana */ + SDL_SCANCODE_LANG5 = 148, /**< Zenkaku/Hankaku */ + SDL_SCANCODE_LANG6 = 149, /**< reserved */ + SDL_SCANCODE_LANG7 = 150, /**< reserved */ + SDL_SCANCODE_LANG8 = 151, /**< reserved */ + SDL_SCANCODE_LANG9 = 152, /**< reserved */ + + SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */ + SDL_SCANCODE_SYSREQ = 154, + SDL_SCANCODE_CANCEL = 155, + SDL_SCANCODE_CLEAR = 156, + SDL_SCANCODE_PRIOR = 157, + SDL_SCANCODE_RETURN2 = 158, + SDL_SCANCODE_SEPARATOR = 159, + SDL_SCANCODE_OUT = 160, + SDL_SCANCODE_OPER = 161, + SDL_SCANCODE_CLEARAGAIN = 162, + SDL_SCANCODE_CRSEL = 163, + SDL_SCANCODE_EXSEL = 164, + + SDL_SCANCODE_KP_00 = 176, + SDL_SCANCODE_KP_000 = 177, + SDL_SCANCODE_THOUSANDSSEPARATOR = 178, + SDL_SCANCODE_DECIMALSEPARATOR = 179, + SDL_SCANCODE_CURRENCYUNIT = 180, + SDL_SCANCODE_CURRENCYSUBUNIT = 181, + SDL_SCANCODE_KP_LEFTPAREN = 182, + SDL_SCANCODE_KP_RIGHTPAREN = 183, + SDL_SCANCODE_KP_LEFTBRACE = 184, + SDL_SCANCODE_KP_RIGHTBRACE = 185, + SDL_SCANCODE_KP_TAB = 186, + SDL_SCANCODE_KP_BACKSPACE = 187, + SDL_SCANCODE_KP_A = 188, + SDL_SCANCODE_KP_B = 189, + SDL_SCANCODE_KP_C = 190, + SDL_SCANCODE_KP_D = 191, + SDL_SCANCODE_KP_E = 192, + SDL_SCANCODE_KP_F = 193, + SDL_SCANCODE_KP_XOR = 194, + SDL_SCANCODE_KP_POWER = 195, + SDL_SCANCODE_KP_PERCENT = 196, + SDL_SCANCODE_KP_LESS = 197, + SDL_SCANCODE_KP_GREATER = 198, + SDL_SCANCODE_KP_AMPERSAND = 199, + SDL_SCANCODE_KP_DBLAMPERSAND = 200, + SDL_SCANCODE_KP_VERTICALBAR = 201, + SDL_SCANCODE_KP_DBLVERTICALBAR = 202, + SDL_SCANCODE_KP_COLON = 203, + SDL_SCANCODE_KP_HASH = 204, + SDL_SCANCODE_KP_SPACE = 205, + SDL_SCANCODE_KP_AT = 206, + SDL_SCANCODE_KP_EXCLAM = 207, + SDL_SCANCODE_KP_MEMSTORE = 208, + SDL_SCANCODE_KP_MEMRECALL = 209, + SDL_SCANCODE_KP_MEMCLEAR = 210, + SDL_SCANCODE_KP_MEMADD = 211, + SDL_SCANCODE_KP_MEMSUBTRACT = 212, + SDL_SCANCODE_KP_MEMMULTIPLY = 213, + SDL_SCANCODE_KP_MEMDIVIDE = 214, + SDL_SCANCODE_KP_PLUSMINUS = 215, + SDL_SCANCODE_KP_CLEAR = 216, + SDL_SCANCODE_KP_CLEARENTRY = 217, + SDL_SCANCODE_KP_BINARY = 218, + SDL_SCANCODE_KP_OCTAL = 219, + SDL_SCANCODE_KP_DECIMAL = 220, + SDL_SCANCODE_KP_HEXADECIMAL = 221, + + SDL_SCANCODE_LCTRL = 224, + SDL_SCANCODE_LSHIFT = 225, + SDL_SCANCODE_LALT = 226, /**< alt, option */ + SDL_SCANCODE_LGUI = 227, /**< windows, command (apple), meta */ + SDL_SCANCODE_RCTRL = 228, + SDL_SCANCODE_RSHIFT = 229, + SDL_SCANCODE_RALT = 230, /**< alt gr, option */ + SDL_SCANCODE_RGUI = 231, /**< windows, command (apple), meta */ + + SDL_SCANCODE_MODE = 257, /**< I'm not sure if this is really not covered + * by any of the above, but since there's a + * special KMOD_MODE for it I'm adding it here + */ + + /* @} *//* Usage page 0x07 */ + + /** + * \name Usage page 0x0C + * + * These values are mapped from usage page 0x0C (USB consumer page). + */ + /* @{ */ + + SDL_SCANCODE_AUDIONEXT = 258, + SDL_SCANCODE_AUDIOPREV = 259, + SDL_SCANCODE_AUDIOSTOP = 260, + SDL_SCANCODE_AUDIOPLAY = 261, + SDL_SCANCODE_AUDIOMUTE = 262, + SDL_SCANCODE_MEDIASELECT = 263, + SDL_SCANCODE_WWW = 264, + SDL_SCANCODE_MAIL = 265, + SDL_SCANCODE_CALCULATOR = 266, + SDL_SCANCODE_COMPUTER = 267, + SDL_SCANCODE_AC_SEARCH = 268, + SDL_SCANCODE_AC_HOME = 269, + SDL_SCANCODE_AC_BACK = 270, + SDL_SCANCODE_AC_FORWARD = 271, + SDL_SCANCODE_AC_STOP = 272, + SDL_SCANCODE_AC_REFRESH = 273, + SDL_SCANCODE_AC_BOOKMARKS = 274, + + /* @} *//* Usage page 0x0C */ + + /** + * \name Walther keys + * + * These are values that Christian Walther added (for mac keyboard?). + */ + /* @{ */ + + SDL_SCANCODE_BRIGHTNESSDOWN = 275, + SDL_SCANCODE_BRIGHTNESSUP = 276, + SDL_SCANCODE_DISPLAYSWITCH = 277, /**< display mirroring/dual display + switch, video mode switch */ + SDL_SCANCODE_KBDILLUMTOGGLE = 278, + SDL_SCANCODE_KBDILLUMDOWN = 279, + SDL_SCANCODE_KBDILLUMUP = 280, + SDL_SCANCODE_EJECT = 281, + SDL_SCANCODE_SLEEP = 282, + + SDL_SCANCODE_APP1 = 283, + SDL_SCANCODE_APP2 = 284, + + /* @} *//* Walther keys */ + + /* Add any other keys here. */ + + SDL_NUM_SCANCODES = 512 /**< not a key, just marks the number of scancodes + for array bounds */ +} SDL_Scancode; + +#endif /* _SDL_scancode_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_shape.h b/packages/sdl2.2.0.5/build/native/include/SDL_shape.h new file mode 100644 index 00000000..db10a8f0 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_shape.h @@ -0,0 +1,143 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_shape_h +#define _SDL_shape_h + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** \file SDL_shape.h + * + * Header file for the shaped window API. + */ + +#define SDL_NONSHAPEABLE_WINDOW -1 +#define SDL_INVALID_SHAPE_ARGUMENT -2 +#define SDL_WINDOW_LACKS_SHAPE -3 + +/** + * \brief Create a window that can be shaped with the specified position, dimensions, and flags. + * + * \param title The title of the window, in UTF-8 encoding. + * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param w The width of the window. + * \param h The height of the window. + * \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with any of the following: + * ::SDL_WINDOW_OPENGL, ::SDL_WINDOW_INPUT_GRABBED, + * ::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_RESIZABLE, + * ::SDL_WINDOW_MAXIMIZED, ::SDL_WINDOW_MINIMIZED, + * ::SDL_WINDOW_BORDERLESS is always set, and ::SDL_WINDOW_FULLSCREEN is always unset. + * + * \return The window created, or NULL if window creation failed. + * + * \sa SDL_DestroyWindow() + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags); + +/** + * \brief Return whether the given window is a shaped window. + * + * \param window The window to query for being shaped. + * + * \return SDL_TRUE if the window is a window that can be shaped, SDL_FALSE if the window is unshaped or NULL. + * \sa SDL_CreateShapedWindow + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsShapedWindow(const SDL_Window *window); + +/** \brief An enum denoting the specific type of contents present in an SDL_WindowShapeParams union. */ +typedef enum { + /** \brief The default mode, a binarized alpha cutoff of 1. */ + ShapeModeDefault, + /** \brief A binarized alpha cutoff with a given integer value. */ + ShapeModeBinarizeAlpha, + /** \brief A binarized alpha cutoff with a given integer value, but with the opposite comparison. */ + ShapeModeReverseBinarizeAlpha, + /** \brief A color key is applied. */ + ShapeModeColorKey +} WindowShapeMode; + +#define SDL_SHAPEMODEALPHA(mode) (mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha) + +/** \brief A union containing parameters for shaped windows. */ +typedef union { + /** \brief a cutoff alpha value for binarization of the window shape's alpha channel. */ + Uint8 binarizationCutoff; + SDL_Color colorKey; +} SDL_WindowShapeParams; + +/** \brief A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. */ +typedef struct SDL_WindowShapeMode { + /** \brief The mode of these window-shape parameters. */ + WindowShapeMode mode; + /** \brief Window-shape parameters. */ + SDL_WindowShapeParams parameters; +} SDL_WindowShapeMode; + +/** + * \brief Set the shape and parameters of a shaped window. + * + * \param window The shaped window whose parameters should be set. + * \param shape A surface encoding the desired shape for the window. + * \param shape_mode The parameters to set for the shaped window. + * + * \return 0 on success, SDL_INVALID_SHAPE_ARGUMENT on invalid an invalid shape argument, or SDL_NONSHAPEABLE_WINDOW + * if the SDL_Window* given does not reference a valid shaped window. + * + * \sa SDL_WindowShapeMode + * \sa SDL_GetShapedWindowMode. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); + +/** + * \brief Get the shape parameters of a shaped window. + * + * \param window The shaped window whose parameters should be retrieved. + * \param shape_mode An empty shape-mode structure to fill, or NULL to check whether the window has a shape. + * + * \return 0 if the window has a shape and, provided shape_mode was not NULL, shape_mode has been filled with the mode + * data, SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped window, or SDL_WINDOW_LACKS_SHAPE if + * the SDL_Window* given is a shapeable window currently lacking a shape. + * + * \sa SDL_WindowShapeMode + * \sa SDL_SetWindowShape + */ +extern DECLSPEC int SDLCALL SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shape_mode); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_shape_h */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_stdinc.h b/packages/sdl2.2.0.5/build/native/include/SDL_stdinc.h new file mode 100644 index 00000000..fdf96415 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_stdinc.h @@ -0,0 +1,531 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_stdinc.h + * + * This is a general header that includes C language support. + */ + +#ifndef _SDL_stdinc_h +#define _SDL_stdinc_h + +#include "SDL_config.h" + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif +#if defined(STDC_HEADERS) +# include +# include +# include +#else +# if defined(HAVE_STDLIB_H) +# include +# elif defined(HAVE_MALLOC_H) +# include +# endif +# if defined(HAVE_STDDEF_H) +# include +# endif +# if defined(HAVE_STDARG_H) +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#if defined(HAVE_INTTYPES_H) +# include +#elif defined(HAVE_STDINT_H) +# include +#endif +#ifdef HAVE_CTYPE_H +# include +#endif +#ifdef HAVE_MATH_H +# if defined(__WINRT__) +/* Defining _USE_MATH_DEFINES is required to get M_PI to be defined on + WinRT. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx + for more information. +*/ +# define _USE_MATH_DEFINES +# endif +# include +#endif +#ifdef HAVE_FLOAT_H +# include +#endif + +/** + * The number of elements in an array. + */ +#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) +#define SDL_TABLESIZE(table) SDL_arraysize(table) + +/** + * Macro useful for building other macros with strings in them + * + * e.g. #define LOG_ERROR(X) OutputDebugString(SDL_STRINGIFY_ARG(__FUNCTION__) ": " X "\n") + */ +#define SDL_STRINGIFY_ARG(arg) #arg + +/** + * \name Cast operators + * + * Use proper C++ casts when compiled as C++ to be compatible with the option + * -Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above). + */ +/* @{ */ +#ifdef __cplusplus +#define SDL_reinterpret_cast(type, expression) reinterpret_cast(expression) +#define SDL_static_cast(type, expression) static_cast(expression) +#define SDL_const_cast(type, expression) const_cast(expression) +#else +#define SDL_reinterpret_cast(type, expression) ((type)(expression)) +#define SDL_static_cast(type, expression) ((type)(expression)) +#define SDL_const_cast(type, expression) ((type)(expression)) +#endif +/* @} *//* Cast operators */ + +/* Define a four character code as a Uint32 */ +#define SDL_FOURCC(A, B, C, D) \ + ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24)) + +/** + * \name Basic data types + */ +/* @{ */ + +typedef enum +{ + SDL_FALSE = 0, + SDL_TRUE = 1 +} SDL_bool; + +/** + * \brief A signed 8-bit integer type. + */ +typedef int8_t Sint8; +/** + * \brief An unsigned 8-bit integer type. + */ +typedef uint8_t Uint8; +/** + * \brief A signed 16-bit integer type. + */ +typedef int16_t Sint16; +/** + * \brief An unsigned 16-bit integer type. + */ +typedef uint16_t Uint16; +/** + * \brief A signed 32-bit integer type. + */ +typedef int32_t Sint32; +/** + * \brief An unsigned 32-bit integer type. + */ +typedef uint32_t Uint32; + +/** + * \brief A signed 64-bit integer type. + */ +typedef int64_t Sint64; +/** + * \brief An unsigned 64-bit integer type. + */ +typedef uint64_t Uint64; + +/* @} *//* Basic data types */ + +/* Make sure we have macros for printing 64 bit values. + * should define these but this is not true all platforms. + * (for example win32) */ +#ifndef SDL_PRIs64 +#ifdef PRIs64 +#define SDL_PRIs64 PRIs64 +#elif defined(__WIN32__) +#define SDL_PRIs64 "I64d" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIs64 "ld" +#else +#define SDL_PRIs64 "lld" +#endif +#endif +#ifndef SDL_PRIu64 +#ifdef PRIu64 +#define SDL_PRIu64 PRIu64 +#elif defined(__WIN32__) +#define SDL_PRIu64 "I64u" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIu64 "lu" +#else +#define SDL_PRIu64 "llu" +#endif +#endif +#ifndef SDL_PRIx64 +#ifdef PRIx64 +#define SDL_PRIx64 PRIx64 +#elif defined(__WIN32__) +#define SDL_PRIx64 "I64x" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIx64 "lx" +#else +#define SDL_PRIx64 "llx" +#endif +#endif +#ifndef SDL_PRIX64 +#ifdef PRIX64 +#define SDL_PRIX64 PRIX64 +#elif defined(__WIN32__) +#define SDL_PRIX64 "I64X" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIX64 "lX" +#else +#define SDL_PRIX64 "llX" +#endif +#endif + +/* Annotations to help code analysis tools */ +#ifdef SDL_DISABLE_ANALYZE_MACROS +#define SDL_IN_BYTECAP(x) +#define SDL_INOUT_Z_CAP(x) +#define SDL_OUT_Z_CAP(x) +#define SDL_OUT_CAP(x) +#define SDL_OUT_BYTECAP(x) +#define SDL_OUT_Z_BYTECAP(x) +#define SDL_PRINTF_FORMAT_STRING +#define SDL_SCANF_FORMAT_STRING +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#else +#if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */ +#include + +#define SDL_IN_BYTECAP(x) _In_bytecount_(x) +#define SDL_INOUT_Z_CAP(x) _Inout_z_cap_(x) +#define SDL_OUT_Z_CAP(x) _Out_z_cap_(x) +#define SDL_OUT_CAP(x) _Out_cap_(x) +#define SDL_OUT_BYTECAP(x) _Out_bytecap_(x) +#define SDL_OUT_Z_BYTECAP(x) _Out_z_bytecap_(x) + +#define SDL_PRINTF_FORMAT_STRING _Printf_format_string_ +#define SDL_SCANF_FORMAT_STRING _Scanf_format_string_impl_ +#else +#define SDL_IN_BYTECAP(x) +#define SDL_INOUT_Z_CAP(x) +#define SDL_OUT_Z_CAP(x) +#define SDL_OUT_CAP(x) +#define SDL_OUT_BYTECAP(x) +#define SDL_OUT_Z_BYTECAP(x) +#define SDL_PRINTF_FORMAT_STRING +#define SDL_SCANF_FORMAT_STRING +#endif +#if defined(__GNUC__) +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 ))) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 ))) +#else +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#endif +#endif /* SDL_DISABLE_ANALYZE_MACROS */ + +#define SDL_COMPILE_TIME_ASSERT(name, x) \ + typedef int SDL_dummy_ ## name[(x) * 2 - 1] +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); +SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); +SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); +SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); +SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); +SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); +SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8); +SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +/* Check to make sure enums are the size of ints, for structure packing. + For both Watcom C/C++ and Borland C/C++ the compiler option that makes + enums having the size of an int must be enabled. + This is "-b" for Borland C/C++ and "-ei" for Watcom C/C++ (v11). +*/ + +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +#if !defined(__ANDROID__) + /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */ +typedef enum +{ + DUMMY_ENUM_VALUE +} SDL_DUMMY_ENUM; + +SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); +#endif +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(HAVE_ALLOCA) && !defined(alloca) +# if defined(HAVE_ALLOCA_H) +# include +# elif defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined(_MSC_VER) +# include +# define alloca _alloca +# elif defined(__WATCOMC__) +# include +# elif defined(__BORLANDC__) +# include +# elif defined(__DMC__) +# include +# elif defined(__AIX__) +#pragma alloca +# elif defined(__MRC__) +void *alloca(unsigned); +# else +char *alloca(); +# endif +#endif +#ifdef HAVE_ALLOCA +#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) +#define SDL_stack_free(data) +#else +#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) +#define SDL_stack_free(data) SDL_free(data) +#endif + +extern DECLSPEC void *SDLCALL SDL_malloc(size_t size); +extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); +extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); +extern DECLSPEC void SDLCALL SDL_free(void *mem); + +extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); +extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); + +extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *)); + +extern DECLSPEC int SDLCALL SDL_abs(int x); + +/* !!! FIXME: these have side effects. You probably shouldn't use them. */ +/* !!! FIXME: Maybe we do forceinline functions of SDL_mini, SDL_minf, etc? */ +#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) +#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) + +extern DECLSPEC int SDLCALL SDL_isdigit(int x); +extern DECLSPEC int SDLCALL SDL_isspace(int x); +extern DECLSPEC int SDLCALL SDL_toupper(int x); +extern DECLSPEC int SDLCALL SDL_tolower(int x); + +extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len); + +#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) +#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) + +/* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */ +SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) +{ +#if defined(__GNUC__) && defined(i386) + int u0, u1, u2; + __asm__ __volatile__ ( + "cld \n\t" + "rep ; stosl \n\t" + : "=&D" (u0), "=&a" (u1), "=&c" (u2) + : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, dwords)) + : "memory" + ); +#else + size_t _n = (dwords + 3) / 4; + Uint32 *_p = SDL_static_cast(Uint32 *, dst); + Uint32 _val = (val); + if (dwords == 0) + return; + switch (dwords % 4) + { + case 0: do { *_p++ = _val; + case 3: *_p++ = _val; + case 2: *_p++ = _val; + case 1: *_p++ = _val; + } while ( --_n ); + } +#endif +} + + +extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); + +extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); +extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len); + +extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr); +extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); +extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); + +extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str); +extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); +extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_bytes); +extern DECLSPEC size_t SDLCALL SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); +extern DECLSPEC char *SDLCALL SDL_strdup(const char *str); +extern DECLSPEC char *SDLCALL SDL_strrev(char *str); +extern DECLSPEC char *SDLCALL SDL_strupr(char *str); +extern DECLSPEC char *SDLCALL SDL_strlwr(char *str); +extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c); +extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c); +extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle); + +extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_uitoa(unsigned int value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *str, int radix); + +extern DECLSPEC int SDLCALL SDL_atoi(const char *str); +extern DECLSPEC double SDLCALL SDL_atof(const char *str); +extern DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base); +extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *str, char **endp, int base); +extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *str, char **endp, int base); +extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *str, char **endp, int base); +extern DECLSPEC double SDLCALL SDL_strtod(const char *str, char **endp); + +extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2); +extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen); +extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2); +extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len); + +extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2); +extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3); +extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap); + +#ifndef HAVE_M_PI +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 /* pi */ +#endif +#endif + +extern DECLSPEC double SDLCALL SDL_acos(double x); +extern DECLSPEC double SDLCALL SDL_asin(double x); +extern DECLSPEC double SDLCALL SDL_atan(double x); +extern DECLSPEC double SDLCALL SDL_atan2(double x, double y); +extern DECLSPEC double SDLCALL SDL_ceil(double x); +extern DECLSPEC double SDLCALL SDL_copysign(double x, double y); +extern DECLSPEC double SDLCALL SDL_cos(double x); +extern DECLSPEC float SDLCALL SDL_cosf(float x); +extern DECLSPEC double SDLCALL SDL_fabs(double x); +extern DECLSPEC double SDLCALL SDL_floor(double x); +extern DECLSPEC double SDLCALL SDL_log(double x); +extern DECLSPEC double SDLCALL SDL_pow(double x, double y); +extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n); +extern DECLSPEC double SDLCALL SDL_sin(double x); +extern DECLSPEC float SDLCALL SDL_sinf(float x); +extern DECLSPEC double SDLCALL SDL_sqrt(double x); +extern DECLSPEC float SDLCALL SDL_sqrtf(float x); +extern DECLSPEC double SDLCALL SDL_tan(double x); +extern DECLSPEC float SDLCALL SDL_tanf(float x); + +/* The SDL implementation of iconv() returns these error codes */ +#define SDL_ICONV_ERROR (size_t)-1 +#define SDL_ICONV_E2BIG (size_t)-2 +#define SDL_ICONV_EILSEQ (size_t)-3 +#define SDL_ICONV_EINVAL (size_t)-4 + +/* SDL_iconv_* are now always real symbols/types, not macros or inlined. */ +typedef struct _SDL_iconv_t *SDL_iconv_t; +extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, + const char *fromcode); +extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, + size_t * inbytesleft, char **outbuf, + size_t * outbytesleft); +/** + * This function converts a string between encodings in one pass, returning a + * string that must be freed with SDL_free() or NULL on error. + */ +extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, + const char *fromcode, + const char *inbuf, + size_t inbytesleft); +#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) + +/* force builds using Clang's static analysis tools to use literal C runtime + here, since there are possibly tests that are ineffective otherwise. */ +#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) +#define SDL_malloc malloc +#define SDL_calloc calloc +#define SDL_realloc realloc +#define SDL_free free +#define SDL_memset memset +#define SDL_memcpy memcpy +#define SDL_memmove memmove +#define SDL_memcmp memcmp +#define SDL_strlen strlen +#define SDL_strlcpy strlcpy +#define SDL_strlcat strlcat +#define SDL_strdup strdup +#define SDL_strchr strchr +#define SDL_strrchr strrchr +#define SDL_strstr strstr +#define SDL_strcmp strcmp +#define SDL_strncmp strncmp +#define SDL_strcasecmp strcasecmp +#define SDL_strncasecmp strncasecmp +#define SDL_sscanf sscanf +#define SDL_vsscanf vsscanf +#define SDL_snprintf snprintf +#define SDL_vsnprintf vsnprintf +#endif + +SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords) +{ + return SDL_memcpy(dst, src, dwords * 4); +} + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_stdinc_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_surface.h b/packages/sdl2.2.0.5/build/native/include/SDL_surface.h new file mode 100644 index 00000000..e4a06a20 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_surface.h @@ -0,0 +1,513 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_surface.h + * + * Header file for ::SDL_Surface definition and management functions. + */ + +#ifndef _SDL_surface_h +#define _SDL_surface_h + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_blendmode.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Surface flags + * + * These are the currently supported flags for the ::SDL_Surface. + * + * \internal + * Used internally (read-only). + */ +/* @{ */ +#define SDL_SWSURFACE 0 /**< Just here for compatibility */ +#define SDL_PREALLOC 0x00000001 /**< Surface uses preallocated memory */ +#define SDL_RLEACCEL 0x00000002 /**< Surface is RLE encoded */ +#define SDL_DONTFREE 0x00000004 /**< Surface is referenced internally */ +/* @} *//* Surface flags */ + +/** + * Evaluates to true if the surface needs to be locked before access. + */ +#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0) + +/** + * \brief A collection of pixels used in software blitting. + * + * \note This structure should be treated as read-only, except for \c pixels, + * which, if not NULL, contains the raw pixel data for the surface. + */ +typedef struct SDL_Surface +{ + Uint32 flags; /**< Read-only */ + SDL_PixelFormat *format; /**< Read-only */ + int w, h; /**< Read-only */ + int pitch; /**< Read-only */ + void *pixels; /**< Read-write */ + + /** Application data associated with the surface */ + void *userdata; /**< Read-write */ + + /** information needed for surfaces requiring locks */ + int locked; /**< Read-only */ + void *lock_data; /**< Read-only */ + + /** clipping information */ + SDL_Rect clip_rect; /**< Read-only */ + + /** info for fast blit mapping to other surfaces */ + struct SDL_BlitMap *map; /**< Private */ + + /** Reference count -- used when freeing surface */ + int refcount; /**< Read-mostly */ +} SDL_Surface; + +/** + * \brief The type of function used for surface blitting functions. + */ +typedef int (*SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect, + struct SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Allocate and free an RGB surface. + * + * If the depth is 4 or 8 bits, an empty palette is allocated for the surface. + * If the depth is greater than 8 bits, the pixel format is set using the + * flags '[RGB]mask'. + * + * If the function runs out of memory, it will return NULL. + * + * \param flags The \c flags are obsolete and should be set to 0. + * \param width The width in pixels of the surface to create. + * \param height The height in pixels of the surface to create. + * \param depth The depth in bits of the surface to create. + * \param Rmask The red mask of the surface to create. + * \param Gmask The green mask of the surface to create. + * \param Bmask The blue mask of the surface to create. + * \param Amask The alpha mask of the surface to create. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormat + (Uint32 flags, int width, int height, int depth, Uint32 format); +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, + int width, + int height, + int depth, + int pitch, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormatFrom + (void *pixels, int width, int height, int depth, int pitch, Uint32 format); +extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface); + +/** + * \brief Set the palette used by a surface. + * + * \return 0, or -1 if the surface format doesn't use a palette. + * + * \note A single palette can be shared with many surfaces. + */ +extern DECLSPEC int SDLCALL SDL_SetSurfacePalette(SDL_Surface * surface, + SDL_Palette * palette); + +/** + * \brief Sets up a surface for directly accessing the pixels. + * + * Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write + * to and read from \c surface->pixels, using the pixel format stored in + * \c surface->format. Once you are done accessing the surface, you should + * use SDL_UnlockSurface() to release it. + * + * Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates + * to 0, then you can read and write to the surface at any time, and the + * pixel format of the surface will not change. + * + * No operating system or library calls should be made between lock/unlock + * pairs, as critical system locks may be held during this time. + * + * SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked. + * + * \sa SDL_UnlockSurface() + */ +extern DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface * surface); +/** \sa SDL_LockSurface() */ +extern DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface * surface); + +/** + * Load a surface from a seekable SDL data stream (memory or file). + * + * If \c freesrc is non-zero, the stream will be closed after being read. + * + * The new surface should be freed with SDL_FreeSurface(). + * + * \return the new surface, or NULL if there was an error. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP_RW(SDL_RWops * src, + int freesrc); + +/** + * Load a surface from a file. + * + * Convenience macro. + */ +#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Save a surface to a seekable SDL data stream (memory or file). + * + * Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the + * BMP directly. Other RGB formats with 8-bit or higher get converted to a + * 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit + * surface before they are saved. YUV and paletted 1-bit and 4-bit formats are + * not supported. + * + * If \c freedst is non-zero, the stream will be closed after being written. + * + * \return 0 if successful or -1 if there was an error. + */ +extern DECLSPEC int SDLCALL SDL_SaveBMP_RW + (SDL_Surface * surface, SDL_RWops * dst, int freedst); + +/** + * Save a surface to a file. + * + * Convenience macro. + */ +#define SDL_SaveBMP(surface, file) \ + SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) + +/** + * \brief Sets the RLE acceleration hint for a surface. + * + * \return 0 on success, or -1 if the surface is not valid + * + * \note If RLE is enabled, colorkey and alpha blending blits are much faster, + * but the surface must be locked before directly accessing the pixels. + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface, + int flag); + +/** + * \brief Sets the color key (transparent pixel) in a blittable surface. + * + * \param surface The surface to update + * \param flag Non-zero to enable colorkey and 0 to disable colorkey + * \param key The transparent pixel in the native surface format + * + * \return 0 on success, or -1 if the surface is not valid + * + * You can pass SDL_RLEACCEL to enable RLE accelerated blits. + */ +extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface, + int flag, Uint32 key); + +/** + * \brief Gets the color key (transparent pixel) in a blittable surface. + * + * \param surface The surface to update + * \param key A pointer filled in with the transparent pixel in the native + * surface format + * + * \return 0 on success, or -1 if the surface is not valid or colorkey is not + * enabled. + */ +extern DECLSPEC int SDLCALL SDL_GetColorKey(SDL_Surface * surface, + Uint32 * key); + +/** + * \brief Set an additional color value used in blit operations. + * + * \param surface The surface to update. + * \param r The red color value multiplied into blit operations. + * \param g The green color value multiplied into blit operations. + * \param b The blue color value multiplied into blit operations. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_GetSurfaceColorMod() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface * surface, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * \brief Get the additional color value used in blit operations. + * + * \param surface The surface to query. + * \param r A pointer filled in with the current red color value. + * \param g A pointer filled in with the current green color value. + * \param b A pointer filled in with the current blue color value. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_SetSurfaceColorMod() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface * surface, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * \brief Set an additional alpha value used in blit operations. + * + * \param surface The surface to update. + * \param alpha The alpha value multiplied into blit operations. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_GetSurfaceAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 alpha); + +/** + * \brief Get the additional alpha value used in blit operations. + * + * \param surface The surface to query. + * \param alpha A pointer filled in with the current alpha value. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_SetSurfaceAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 * alpha); + +/** + * \brief Set the blend mode used for blit operations. + * + * \param surface The surface to update. + * \param blendMode ::SDL_BlendMode to use for blit blending. + * + * \return 0 on success, or -1 if the parameters are not valid. + * + * \sa SDL_GetSurfaceBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode blendMode); + +/** + * \brief Get the blend mode used for blit operations. + * + * \param surface The surface to query. + * \param blendMode A pointer filled in with the current blend mode. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_SetSurfaceBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode *blendMode); + +/** + * Sets the clipping rectangle for the destination surface in a blit. + * + * If the clip rectangle is NULL, clipping will be disabled. + * + * If the clip rectangle doesn't intersect the surface, the function will + * return SDL_FALSE and blits will be completely clipped. Otherwise the + * function returns SDL_TRUE and blits to the surface will be clipped to + * the intersection of the surface area and the clipping rectangle. + * + * Note that blits are automatically clipped to the edges of the source + * and destination surfaces. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetClipRect(SDL_Surface * surface, + const SDL_Rect * rect); + +/** + * Gets the clipping rectangle for the destination surface in a blit. + * + * \c rect must be a pointer to a valid rectangle which will be filled + * with the correct values. + */ +extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface * surface, + SDL_Rect * rect); + +/** + * Creates a new surface of the specified format, and then copies and maps + * the given surface to it so the blit of the converted surface will be as + * fast as possible. If this function fails, it returns NULL. + * + * The \c flags parameter is passed to SDL_CreateRGBSurface() and has those + * semantics. You can also pass ::SDL_RLEACCEL in the flags parameter and + * SDL will try to RLE accelerate colorkey and alpha blits in the resulting + * surface. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface + (SDL_Surface * src, const SDL_PixelFormat * fmt, Uint32 flags); +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurfaceFormat + (SDL_Surface * src, Uint32 pixel_format, Uint32 flags); + +/** + * \brief Copy a block of pixels of one format to another format + * + * \return 0 on success, or -1 if there was an error + */ +extern DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, + Uint32 src_format, + const void * src, int src_pitch, + Uint32 dst_format, + void * dst, int dst_pitch); + +/** + * Performs a fast fill of the given rectangle with \c color. + * + * If \c rect is NULL, the whole surface will be filled with \c color. + * + * The color should be a pixel of the format used by the surface, and + * can be generated by the SDL_MapRGB() function. + * + * \return 0 on success, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_FillRect + (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color); +extern DECLSPEC int SDLCALL SDL_FillRects + (SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color); + +/** + * Performs a fast blit from the source surface to the destination surface. + * + * This assumes that the source and destination rectangles are + * the same size. If either \c srcrect or \c dstrect are NULL, the entire + * surface (\c src or \c dst) is copied. The final blit rectangles are saved + * in \c srcrect and \c dstrect after all clipping is performed. + * + * \return If the blit is successful, it returns 0, otherwise it returns -1. + * + * The blit function should not be called on a locked surface. + * + * The blit semantics for surfaces with and without blending and colorkey + * are defined as follows: + * \verbatim + RGBA->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB, set destination alpha to source per-surface alpha value. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + + RGBA->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy all of RGBA to the destination. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + \endverbatim + * + * You should call SDL_BlitSurface() unless you know exactly how SDL + * blitting works internally and how to use the other blit functions. + */ +#define SDL_BlitSurface SDL_UpperBlit + +/** + * This is the public blit function, SDL_BlitSurface(), and it performs + * rectangle validation and clipping before passing it to SDL_LowerBlit() + */ +extern DECLSPEC int SDLCALL SDL_UpperBlit + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * This is a semi-private blit function and it performs low-level surface + * blitting only. + */ +extern DECLSPEC int SDLCALL SDL_LowerBlit + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * \brief Perform a fast, low quality, stretch blit between two surfaces of the + * same pixel format. + * + * \note This function uses a static buffer, and is not thread-safe. + */ +extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src, + const SDL_Rect * srcrect, + SDL_Surface * dst, + const SDL_Rect * dstrect); + +#define SDL_BlitScaled SDL_UpperBlitScaled + +/** + * This is the public scaled blit function, SDL_BlitScaled(), and it performs + * rectangle validation and clipping before passing it to SDL_LowerBlitScaled() + */ +extern DECLSPEC int SDLCALL SDL_UpperBlitScaled + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * This is a semi-private blit function and it performs low-level surface + * scaled blitting only. + */ +extern DECLSPEC int SDLCALL SDL_LowerBlitScaled + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_surface_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_system.h b/packages/sdl2.2.0.5/build/native/include/SDL_system.h new file mode 100644 index 00000000..5da9adb4 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_system.h @@ -0,0 +1,216 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_system.h + * + * Include file for platform specific SDL API functions + */ + +#ifndef _SDL_system_h +#define _SDL_system_h + +#include "SDL_stdinc.h" +#include "SDL_keyboard.h" +#include "SDL_render.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* Platform specific functions for Windows */ +#ifdef __WIN32__ + +/** + \brief Set a function that is called for every windows message, before TranslateMessage() +*/ +typedef void (SDLCALL * SDL_WindowsMessageHook)(void *userdata, void *hWnd, unsigned int message, Uint64 wParam, Sint64 lParam); +extern DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata); + +/** + \brief Returns the D3D9 adapter index that matches the specified display index. + + This adapter index can be passed to IDirect3D9::CreateDevice and controls + on which monitor a full screen application will appear. +*/ +extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); + +typedef struct IDirect3DDevice9 IDirect3DDevice9; +/** + \brief Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer. + + Once you are done using the device, you should release it to avoid a resource leak. + */ +extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); + +/** + \brief Returns the DXGI Adapter and Output indices for the specified display index. + + These can be passed to EnumAdapters and EnumOutputs respectively to get the objects + required to create a DX10 or DX11 device and swap chain. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex ); + +#endif /* __WIN32__ */ + + +/* Platform specific functions for iOS */ +#if defined(__IPHONEOS__) && __IPHONEOS__ + +#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam) +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); + +#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) +extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); + +#endif /* __IPHONEOS__ */ + + +/* Platform specific functions for Android */ +#if defined(__ANDROID__) && __ANDROID__ + +/** + \brief Get the JNI environment for the current thread + + This returns JNIEnv*, but the prototype is void* so we don't need jni.h + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(); + +/** + \brief Get the SDL Activity object for the application + + This returns jobject, but the prototype is void* so we don't need jni.h + The jobject returned by SDL_AndroidGetActivity is a local reference. + It is the caller's responsibility to properly release it + (using env->Push/PopLocalFrame or manually with env->DeleteLocalRef) + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(); + +/** + See the official Android developer guide for more information: + http://developer.android.com/guide/topics/data/data-storage.html +*/ +#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 +#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 + +/** + \brief Get the path used for internal storage for this application. + + This path is unique to your application and cannot be written to + by other applications. + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(); + +/** + \brief Get the current state of external storage, a bitmask of these values: + SDL_ANDROID_EXTERNAL_STORAGE_READ + SDL_ANDROID_EXTERNAL_STORAGE_WRITE + + If external storage is currently unavailable, this will return 0. +*/ +extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(); + +/** + \brief Get the path used for external storage for this application. + + This path is unique to your application, but is public and can be + written to by other applications. + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(); + +#endif /* __ANDROID__ */ + +/* Platform specific functions for WinRT */ +#if defined(__WINRT__) && __WINRT__ + +/** + * \brief WinRT / Windows Phone path types + */ +typedef enum +{ + /** \brief The installed app's root directory. + Files here are likely to be read-only. */ + SDL_WINRT_PATH_INSTALLED_LOCATION, + + /** \brief The app's local data store. Files may be written here */ + SDL_WINRT_PATH_LOCAL_FOLDER, + + /** \brief The app's roaming data store. Unsupported on Windows Phone. + Files written here may be copied to other machines via a network + connection. + */ + SDL_WINRT_PATH_ROAMING_FOLDER, + + /** \brief The app's temporary data store. Unsupported on Windows Phone. + Files written here may be deleted at any time. */ + SDL_WINRT_PATH_TEMP_FOLDER +} SDL_WinRT_Path; + + +/** + * \brief Retrieves a WinRT defined path on the local file system + * + * \note Documentation on most app-specific path types on WinRT + * can be found on MSDN, at the URL: + * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType The type of path to retrieve. + * \return A UCS-2 string (16-bit, wide-char) containing the path, or NULL + * if the path is not available for any reason. Not all paths are + * available on all versions of Windows. This is especially true on + * Windows Phone. Check the documentation for the given + * SDL_WinRT_Path for more information on which path types are + * supported where. + */ +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType); + +/** + * \brief Retrieves a WinRT defined path on the local file system + * + * \note Documentation on most app-specific path types on WinRT + * can be found on MSDN, at the URL: + * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType The type of path to retrieve. + * \return A UTF-8 string (8-bit, multi-byte) containing the path, or NULL + * if the path is not available for any reason. Not all paths are + * available on all versions of Windows. This is especially true on + * Windows Phone. Check the documentation for the given + * SDL_WinRT_Path for more information on which path types are + * supported where. + */ +extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); + +#endif /* __WINRT__ */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_system_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_syswm.h b/packages/sdl2.2.0.5/build/native/include/SDL_syswm.h new file mode 100644 index 00000000..71ba5f1f --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_syswm.h @@ -0,0 +1,321 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_syswm.h + * + * Include file for SDL custom system window manager hooks. + */ + +#ifndef _SDL_syswm_h +#define _SDL_syswm_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_version.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_syswm.h + * + * Your application has access to a special type of event ::SDL_SYSWMEVENT, + * which contains window-manager specific information and arrives whenever + * an unhandled window event occurs. This event is ignored by default, but + * you can enable it with SDL_EventState(). + */ +#ifdef SDL_PROTOTYPES_ONLY +struct SDL_SysWMinfo; +#else + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#endif + +#if defined(SDL_VIDEO_DRIVER_WINRT) +#include +#endif + +/* This is the structure for custom window manager events */ +#if defined(SDL_VIDEO_DRIVER_X11) +#if defined(__APPLE__) && defined(__MACH__) +/* conflicts with Quickdraw.h */ +#define Cursor X11Cursor +#endif + +#include +#include + +#if defined(__APPLE__) && defined(__MACH__) +/* matches the re-define above */ +#undef Cursor +#endif + +#endif /* defined(SDL_VIDEO_DRIVER_X11) */ + +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) +#include +#endif + +#if defined(SDL_VIDEO_DRIVER_COCOA) +#ifdef __OBJC__ +@class NSWindow; +#else +typedef struct _NSWindow NSWindow; +#endif +#endif + +#if defined(SDL_VIDEO_DRIVER_UIKIT) +#ifdef __OBJC__ +#include +#else +typedef struct _UIWindow UIWindow; +typedef struct _UIViewController UIViewController; +#endif +typedef Uint32 GLuint; +#endif + +#if defined(SDL_VIDEO_DRIVER_ANDROID) +typedef struct ANativeWindow ANativeWindow; +typedef void *EGLSurface; +#endif + +#if defined(SDL_VIDEO_DRIVER_VIVANTE) +#include "SDL_egl.h" +#endif + +/** + * These are the various supported windowing subsystems + */ +typedef enum +{ + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, + SDL_SYSWM_WINRT, + SDL_SYSWM_ANDROID, + SDL_SYSWM_VIVANTE +} SDL_SYSWM_TYPE; + +/** + * The custom event structure. + */ +struct SDL_SysWMmsg +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + struct { + HWND hwnd; /**< The window for the message */ + UINT msg; /**< The type of message */ + WPARAM wParam; /**< WORD message parameter */ + LPARAM lParam; /**< LONG message parameter */ + } win; +#endif +#if defined(SDL_VIDEO_DRIVER_X11) + struct { + XEvent event; + } x11; +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + struct { + DFBEvent event; + } dfb; +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + struct + { + /* Latest version of Xcode clang complains about empty structs in C v. C++: + error: empty struct has size 0 in C, size 1 in C++ + */ + int dummy; + /* No Cocoa window events yet */ + } cocoa; +#endif +#if defined(SDL_VIDEO_DRIVER_UIKIT) + struct + { + int dummy; + /* No UIKit window events yet */ + } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + int dummy; + /* No Vivante window events yet */ + } vivante; +#endif + /* Can't have an empty union */ + int dummy; + } msg; +}; + +/** + * The custom window manager information structure. + * + * When this structure is returned, it holds information about which + * low level system it is using, and will be one of SDL_SYSWM_TYPE. + */ +struct SDL_SysWMinfo +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + struct + { + HWND window; /**< The window handle */ + HDC hdc; /**< The window device context */ + } win; +#endif +#if defined(SDL_VIDEO_DRIVER_WINRT) + struct + { + IInspectable * window; /**< The WinRT CoreWindow */ + } winrt; +#endif +#if defined(SDL_VIDEO_DRIVER_X11) + struct + { + Display *display; /**< The X11 display */ + Window window; /**< The X11 window */ + } x11; +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + struct + { + IDirectFB *dfb; /**< The directfb main interface */ + IDirectFBWindow *window; /**< The directfb window handle */ + IDirectFBSurface *surface; /**< The directfb client surface */ + } dfb; +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + struct + { +#if defined(__OBJC__) && defined(__has_feature) && __has_feature(objc_arc) + NSWindow __unsafe_unretained *window; /* The Cocoa window */ +#else + NSWindow *window; /* The Cocoa window */ +#endif + } cocoa; +#endif +#if defined(SDL_VIDEO_DRIVER_UIKIT) + struct + { +#if defined(__OBJC__) && defined(__has_feature) && __has_feature(objc_arc) + UIWindow __unsafe_unretained *window; /* The UIKit window */ +#else + UIWindow *window; /* The UIKit window */ +#endif + GLuint framebuffer; /* The GL view's Framebuffer Object. It must be bound when rendering to the screen using GL. */ + GLuint colorbuffer; /* The GL view's color Renderbuffer Object. It must be bound when SDL_GL_SwapWindow is called. */ + GLuint resolveFramebuffer; /* The Framebuffer Object which holds the resolve color Renderbuffer, when MSAA is used. */ + } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_WAYLAND) + struct + { + struct wl_display *display; /**< Wayland display */ + struct wl_surface *surface; /**< Wayland surface */ + struct wl_shell_surface *shell_surface; /**< Wayland shell_surface (window manager handle) */ + } wl; +#endif +#if defined(SDL_VIDEO_DRIVER_MIR) + struct + { + struct MirConnection *connection; /**< Mir display server connection */ + struct MirSurface *surface; /**< Mir surface */ + } mir; +#endif + +#if defined(SDL_VIDEO_DRIVER_ANDROID) + struct + { + ANativeWindow *window; + EGLSurface surface; + } android; +#endif + +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + EGLNativeDisplayType display; + EGLNativeWindowType window; + } vivante; +#endif + + /* Can't have an empty union */ + int dummy; + } info; +}; + +#endif /* SDL_PROTOTYPES_ONLY */ + +typedef struct SDL_SysWMinfo SDL_SysWMinfo; + +/* Function prototypes */ +/** + * \brief This function allows access to driver-dependent window information. + * + * \param window The window about which information is being requested + * \param info This structure must be initialized with the SDL version, and is + * then filled in with information about the given window. + * + * \return SDL_TRUE if the function is implemented and the version member of + * the \c info struct is valid, SDL_FALSE otherwise. + * + * You typically use this function like this: + * \code + * SDL_SysWMinfo info; + * SDL_VERSION(&info.version); + * if ( SDL_GetWindowWMInfo(window, &info) ) { ... } + * \endcode + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowWMInfo(SDL_Window * window, + SDL_SysWMinfo * info); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_syswm_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test.h b/packages/sdl2.2.0.5/build/native/include/SDL_test.h new file mode 100644 index 00000000..217847bf --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test.h @@ -0,0 +1,68 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef _SDL_test_h +#define _SDL_test_h + +#include "SDL.h" +#include "SDL_test_common.h" +#include "SDL_test_font.h" +#include "SDL_test_random.h" +#include "SDL_test_fuzzer.h" +#include "SDL_test_crc32.h" +#include "SDL_test_md5.h" +#include "SDL_test_log.h" +#include "SDL_test_assert.h" +#include "SDL_test_harness.h" +#include "SDL_test_images.h" +#include "SDL_test_compare.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Global definitions */ + +/* + * Note: Maximum size of SDLTest log message is less than SDL's limit + * to ensure we can fit additional information such as the timestamp. + */ +#define SDLTEST_MAX_LOGMESSAGE_LENGTH 3584 + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_assert.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_assert.h new file mode 100644 index 00000000..29277e12 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_assert.h @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_assert.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + * + * Assert API for test code and test cases + * + */ + +#ifndef _SDL_test_assert_h +#define _SDL_test_assert_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Fails the assert. + */ +#define ASSERT_FAIL 0 + +/** + * \brief Passes the assert. + */ +#define ASSERT_PASS 1 + +/** + * \brief Assert that logs and break execution flow on failures. + * + * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). + * \param assertDescription Message to log with the assert describing it. + */ +void SDLTest_Assert(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Assert for test cases that logs but does not break execution flow on failures. Updates assertion counters. + * + * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). + * \param assertDescription Message to log with the assert describing it. + * + * \returns Returns the assertCondition so it can be used to externally to break execution flow if desired. + */ +int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Explicitly pass without checking an assertion condition. Updates assertion counter. + * + * \param assertDescription Message to log with the assert describing it. + */ +void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * \brief Resets the assert summary counters to zero. + */ +void SDLTest_ResetAssertSummary(); + +/** + * \brief Logs summary of all assertions (total, pass, fail) since last reset as INFO or ERROR. + */ +void SDLTest_LogAssertSummary(); + + +/** + * \brief Converts the current assert summary state to a test result. + * + * \returns TEST_RESULT_PASSED, TEST_RESULT_FAILED, or TEST_RESULT_NO_ASSERT + */ +int SDLTest_AssertSummaryToTestResult(); + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_assert_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_common.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_common.h new file mode 100644 index 00000000..0ebf31cb --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_common.h @@ -0,0 +1,188 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_common.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* Ported from original test\common.h file. */ + +#ifndef _SDL_test_common_h +#define _SDL_test_common_h + +#include "SDL.h" + +#if defined(__PSP__) +#define DEFAULT_WINDOW_WIDTH 480 +#define DEFAULT_WINDOW_HEIGHT 272 +#else +#define DEFAULT_WINDOW_WIDTH 640 +#define DEFAULT_WINDOW_HEIGHT 480 +#endif + +#define VERBOSE_VIDEO 0x00000001 +#define VERBOSE_MODES 0x00000002 +#define VERBOSE_RENDER 0x00000004 +#define VERBOSE_EVENT 0x00000008 +#define VERBOSE_AUDIO 0x00000010 + +typedef struct +{ + /* SDL init flags */ + char **argv; + Uint32 flags; + Uint32 verbose; + + /* Video info */ + const char *videodriver; + int display; + const char *window_title; + const char *window_icon; + Uint32 window_flags; + int window_x; + int window_y; + int window_w; + int window_h; + int window_minW; + int window_minH; + int window_maxW; + int window_maxH; + int logical_w; + int logical_h; + float scale; + int depth; + int refresh_rate; + int num_windows; + SDL_Window **windows; + + /* Renderer info */ + const char *renderdriver; + Uint32 render_flags; + SDL_bool skip_renderer; + SDL_Renderer **renderers; + SDL_Texture **targets; + + /* Audio info */ + const char *audiodriver; + SDL_AudioSpec audiospec; + + /* GL settings */ + int gl_red_size; + int gl_green_size; + int gl_blue_size; + int gl_alpha_size; + int gl_buffer_size; + int gl_depth_size; + int gl_stencil_size; + int gl_double_buffer; + int gl_accum_red_size; + int gl_accum_green_size; + int gl_accum_blue_size; + int gl_accum_alpha_size; + int gl_stereo; + int gl_multisamplebuffers; + int gl_multisamplesamples; + int gl_retained_backing; + int gl_accelerated; + int gl_major_version; + int gl_minor_version; + int gl_debug; + int gl_profile_mask; +} SDLTest_CommonState; + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * \brief Parse command line parameters and create common state. + * + * \param argv Array of command line parameters + * \param flags Flags indicating which subsystem to initialize (i.e. SDL_INIT_VIDEO | SDL_INIT_AUDIO) + * + * \returns Returns a newly allocated common state object. + */ +SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags); + +/** + * \brief Process one common argument. + * + * \param state The common state describing the test window to create. + * \param index The index of the argument to process in argv[]. + * + * \returns The number of arguments processed (i.e. 1 for --fullscreen, 2 for --video [videodriver], or -1 on error. + */ +int SDLTest_CommonArg(SDLTest_CommonState * state, int index); + +/** + * \brief Returns common usage information + * + * \param state The common state describing the test window to create. + * + * \returns String with usage information + */ +const char *SDLTest_CommonUsage(SDLTest_CommonState * state); + +/** + * \brief Open test window. + * + * \param state The common state describing the test window to create. + * + * \returns True if initialization succeeded, false otherwise + */ +SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state); + +/** + * \brief Common event handler for test windows. + * + * \param state The common state used to create test window. + * \param event The event to handle. + * \param done Flag indicating we are done. + * + */ +void SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done); + +/** + * \brief Close test window. + * + * \param state The common state used to create test window. + * + */ +void SDLTest_CommonQuit(SDLTest_CommonState * state); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_common_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_compare.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_compare.h new file mode 100644 index 00000000..772cf9fb --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_compare.h @@ -0,0 +1,69 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_compare.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Defines comparison functions (i.e. for surfaces). + +*/ + +#ifndef _SDL_test_compare_h +#define _SDL_test_compare_h + +#include "SDL.h" + +#include "SDL_test_images.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Compares a surface and with reference image data for equality + * + * \param surface Surface used in comparison + * \param referenceSurface Test Surface used in comparison + * \param allowable_error Allowable difference (=sum of squared difference for each RGB component) in blending accuracy. + * + * \returns 0 if comparison succeeded, >0 (=number of pixels for which the comparison failed) if comparison failed, -1 if any of the surfaces were NULL, -2 if the surface sizes differ. + */ +int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_compare_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_crc32.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_crc32.h new file mode 100644 index 00000000..572a3d95 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_crc32.h @@ -0,0 +1,124 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_crc32.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Implements CRC32 calculations (default output is Perl String::CRC32 compatible). + +*/ + +#ifndef _SDL_test_crc32_h +#define _SDL_test_crc32_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* ------------ Definitions --------- */ + +/* Definition shared by all CRC routines */ + +#ifndef CrcUint32 + #define CrcUint32 unsigned int +#endif +#ifndef CrcUint8 + #define CrcUint8 unsigned char +#endif + +#ifdef ORIGINAL_METHOD + #define CRC32_POLY 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */ +#else + #define CRC32_POLY 0xEDB88320 /* Perl String::CRC32 compatible */ +#endif + +/** + * Data structure for CRC32 (checksum) computation + */ + typedef struct { + CrcUint32 crc32_table[256]; /* CRC table */ + } SDLTest_Crc32Context; + +/* ---------- Function Prototypes ------------- */ + +/** + * \brief Initialize the CRC context + * + * Note: The function initializes the crc table required for all crc calculations. + * + * \param crcContext pointer to context variable + * + * \returns 0 for OK, -1 on error + * + */ + int SDLTest_Crc32Init(SDLTest_Crc32Context * crcContext); + + +/** + * \brief calculate a crc32 from a data block + * + * \param crcContext pointer to context variable + * \param inBuf input buffer to checksum + * \param inLen length of input buffer + * \param crc32 pointer to Uint32 to store the final CRC into + * + * \returns 0 for OK, -1 on error + * + */ +int SDLTest_crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); + +/* Same routine broken down into three steps */ +int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); +int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); +int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); + + +/** + * \brief clean up CRC context + * + * \param crcContext pointer to context variable + * + * \returns 0 for OK, -1 on error + * +*/ + +int SDLTest_Crc32Done(SDLTest_Crc32Context * crcContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_crc32_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_font.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_font.h new file mode 100644 index 00000000..3378ea85 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_font.h @@ -0,0 +1,76 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_font.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef _SDL_test_font_h +#define _SDL_test_font_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +#define FONT_CHARACTER_SIZE 8 + +/** + * \brief Draw a string in the currently set font. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the character. + * \param y The Y coordinate of the upper left corner of the character. + * \param c The character to draw. + * + * \returns Returns 0 on success, -1 on failure. + */ +int SDLTest_DrawCharacter( SDL_Renderer *renderer, int x, int y, char c ); + +/** + * \brief Draw a string in the currently set font. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the string. + * \param y The Y coordinate of the upper left corner of the string. + * \param s The string to draw. + * + * \returns Returns 0 on success, -1 on failure. + */ +int SDLTest_DrawString( SDL_Renderer * renderer, int x, int y, const char *s ); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_font_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_fuzzer.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_fuzzer.h new file mode 100644 index 00000000..9603652b --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_fuzzer.h @@ -0,0 +1,384 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_fuzzer.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Data generators for fuzzing test data in a reproducible way. + +*/ + +#ifndef _SDL_test_fuzzer_h +#define _SDL_test_fuzzer_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* + Based on GSOC code by Markus Kauppila +*/ + + +/** + * \file + * Note: The fuzzer implementation uses a static instance of random context + * internally which makes it thread-UNsafe. + */ + +/** + * Initializes the fuzzer for a test + * + * \param execKey Execution "Key" that initializes the random number generator uniquely for the test. + * + */ +void SDLTest_FuzzerInit(Uint64 execKey); + + +/** + * Returns a random Uint8 + * + * \returns Generated integer + */ +Uint8 SDLTest_RandomUint8(); + +/** + * Returns a random Sint8 + * + * \returns Generated signed integer + */ +Sint8 SDLTest_RandomSint8(); + + +/** + * Returns a random Uint16 + * + * \returns Generated integer + */ +Uint16 SDLTest_RandomUint16(); + +/** + * Returns a random Sint16 + * + * \returns Generated signed integer + */ +Sint16 SDLTest_RandomSint16(); + + +/** + * Returns a random integer + * + * \returns Generated integer + */ +Sint32 SDLTest_RandomSint32(); + + +/** + * Returns a random positive integer + * + * \returns Generated integer + */ +Uint32 SDLTest_RandomUint32(); + +/** + * Returns random Uint64. + * + * \returns Generated integer + */ +Uint64 SDLTest_RandomUint64(); + + +/** + * Returns random Sint64. + * + * \returns Generated signed integer + */ +Sint64 SDLTest_RandomSint64(); + +/** + * \returns random float in range [0.0 - 1.0[ + */ +float SDLTest_RandomUnitFloat(); + +/** + * \returns random double in range [0.0 - 1.0[ + */ +double SDLTest_RandomUnitDouble(); + +/** + * \returns random float. + * + */ +float SDLTest_RandomFloat(); + +/** + * \returns random double. + * + */ +double SDLTest_RandomDouble(); + +/** + * Returns a random boundary value for Uint8 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint8BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint8BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint8BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint8BoundaryValue(0, 255, SDL_FALSE) returns 0 (error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns Random boundary value for the given range and domain or 0 with error set + */ +Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint16 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint16BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint16BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint16BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint16BoundaryValue(0, 0xFFFF, SDL_FALSE) returns 0 (error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns Random boundary value for the given range and domain or 0 with error set + */ +Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint32 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint32BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint32BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint32BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint32BoundaryValue(0, 0xFFFFFFFF, SDL_FALSE) returns 0 (with error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns Random boundary value for the given range and domain or 0 with error set + */ +Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Uint64 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomUint64BoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 + * RandomUint64BoundaryValue(1, 20, SDL_FALSE) returns 0 or 21 + * RandomUint64BoundaryValue(0, 99, SDL_FALSE) returns 100 + * RandomUint64BoundaryValue(0, 0xFFFFFFFFFFFFFFFF, SDL_FALSE) returns 0 (with error set) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns Random boundary value for the given range and domain or 0 with error set + */ +Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint8 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint8BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint8BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint8BoundaryValue(SINT8_MIN, 99, SDL_FALSE) returns 100 + * RandomSint8BoundaryValue(SINT8_MIN, SINT8_MAX, SDL_FALSE) returns SINT8_MIN (== error value) with error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns Random boundary value for the given range and domain or SINT8_MIN with error set + */ +Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain); + + +/** + * Returns a random boundary value for Sint16 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint16BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint16BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint16BoundaryValue(SINT16_MIN, 99, SDL_FALSE) returns 100 + * RandomSint16BoundaryValue(SINT16_MIN, SINT16_MAX, SDL_FALSE) returns SINT16_MIN (== error value) with error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns Random boundary value for the given range and domain or SINT16_MIN with error set + */ +Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint32 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint32BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint32BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint32BoundaryValue(SINT32_MIN, 99, SDL_FALSE) returns 100 + * RandomSint32BoundaryValue(SINT32_MIN, SINT32_MAX, SDL_FALSE) returns SINT32_MIN (== error value) + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns Random boundary value for the given range and domain or SINT32_MIN with error set + */ +Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain); + +/** + * Returns a random boundary value for Sint64 within the given boundaries. + * Boundaries are inclusive, see the usage examples below. If validDomain + * is true, the function will only return valid boundaries, otherwise non-valid + * boundaries are also possible. + * If boundary1 > boundary2, the values are swapped + * + * Usage examples: + * RandomSint64BoundaryValue(-10, 20, SDL_TRUE) returns -11, -10, 19 or 20 + * RandomSint64BoundaryValue(-100, -10, SDL_FALSE) returns -101 or -9 + * RandomSint64BoundaryValue(SINT64_MIN, 99, SDL_FALSE) returns 100 + * RandomSint64BoundaryValue(SINT64_MIN, SINT64_MAX, SDL_FALSE) returns SINT64_MIN (== error value) and error set + * + * \param boundary1 Lower boundary limit + * \param boundary2 Upper boundary limit + * \param validDomain Should the generated boundary be valid (=within the bounds) or not? + * + * \returns Random boundary value for the given range and domain or SINT64_MIN with error set + */ +Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain); + + +/** + * Returns integer in range [min, max] (inclusive). + * Min and max values can be negative values. + * If Max in smaller than min, then the values are swapped. + * Min and max are the same value, that value will be returned. + * + * \param min Minimum inclusive value of returned random number + * \param max Maximum inclusive value of returned random number + * + * \returns Generated random integer in range + */ +Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max); + + +/** + * Generates random null-terminated string. The minimum length for + * the string is 1 character, maximum length for the string is 255 + * characters and it can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \returns Newly allocated random string; or NULL if length was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiString(); + + +/** + * Generates random null-terminated string. The maximum length for + * the string is defined by the maxLength parameter. + * String can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \param maxLength The maximum length of the generated string. + * + * \returns Newly allocated random string; or NULL if maxLength was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength); + + +/** + * Generates random null-terminated string. The length for + * the string is defined by the size parameter. + * String can contain ASCII characters from 32 to 126. + * + * Note: Returned string needs to be deallocated. + * + * \param size The length of the generated string + * + * \returns Newly allocated random string; or NULL if size was invalid or string could not be allocated. + */ +char * SDLTest_RandomAsciiStringOfSize(int size); + +/** + * Returns the invocation count for the fuzzer since last ...FuzzerInit. + */ +int SDLTest_GetFuzzerInvocationCount(); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_fuzzer_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_harness.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_harness.h new file mode 100644 index 00000000..74c0950c --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_harness.h @@ -0,0 +1,123 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_harness.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + Defines types for test case definitions and the test execution harness API. + + Based on original GSOC code by Markus Kauppila +*/ + +#ifndef _SDL_test_harness_h +#define _SDL_test_harness_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* ! Definitions for test case structures */ +#define TEST_ENABLED 1 +#define TEST_DISABLED 0 + +/* ! Definition of all the possible test return values of the test case method */ +#define TEST_ABORTED -1 +#define TEST_STARTED 0 +#define TEST_COMPLETED 1 +#define TEST_SKIPPED 2 + +/* ! Definition of all the possible test results for the harness */ +#define TEST_RESULT_PASSED 0 +#define TEST_RESULT_FAILED 1 +#define TEST_RESULT_NO_ASSERT 2 +#define TEST_RESULT_SKIPPED 3 +#define TEST_RESULT_SETUP_FAILURE 4 + +/* !< Function pointer to a test case setup function (run before every test) */ +typedef void (*SDLTest_TestCaseSetUpFp)(void *arg); + +/* !< Function pointer to a test case function */ +typedef int (*SDLTest_TestCaseFp)(void *arg); + +/* !< Function pointer to a test case teardown function (run after every test) */ +typedef void (*SDLTest_TestCaseTearDownFp)(void *arg); + +/** + * Holds information about a single test case. + */ +typedef struct SDLTest_TestCaseReference { + /* !< Func2Stress */ + SDLTest_TestCaseFp testCase; + /* !< Short name (or function name) "Func2Stress" */ + char *name; + /* !< Long name or full description "This test pushes func2() to the limit." */ + char *description; + /* !< Set to TEST_ENABLED or TEST_DISABLED (test won't be run) */ + int enabled; +} SDLTest_TestCaseReference; + +/** + * Holds information about a test suite (multiple test cases). + */ +typedef struct SDLTest_TestSuiteReference { + /* !< "PlatformSuite" */ + char *name; + /* !< The function that is run before each test. NULL skips. */ + SDLTest_TestCaseSetUpFp testSetUp; + /* !< The test cases that are run as part of the suite. Last item should be NULL. */ + const SDLTest_TestCaseReference **testCases; + /* !< The function that is run after each test. NULL skips. */ + SDLTest_TestCaseTearDownFp testTearDown; +} SDLTest_TestSuiteReference; + + +/** + * \brief Execute a test suite using the given run seed and execution key. + * + * \param testSuites Suites containing the test case. + * \param userRunSeed Custom run seed provided by user, or NULL to autogenerate one. + * \param userExecKey Custom execution key provided by user, or 0 to autogenerate one. + * \param filter Filter specification. NULL disables. Case sensitive. + * \param testIterations Number of iterations to run each test case. + * + * \returns Test run result; 0 when all tests passed, 1 if any tests failed. + */ +int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *userRunSeed, Uint64 userExecKey, const char *filter, int testIterations); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_harness_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_images.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_images.h new file mode 100644 index 00000000..8c64b4fe --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_images.h @@ -0,0 +1,78 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_images.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + Defines some images for tests. + +*/ + +#ifndef _SDL_test_images_h +#define _SDL_test_images_h + +#include "SDL.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + *Type for test images. + */ +typedef struct SDLTest_SurfaceImage_s { + int width; + int height; + unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ + const char *pixel_data; +} SDLTest_SurfaceImage_t; + +/* Test images */ +SDL_Surface *SDLTest_ImageBlit(); +SDL_Surface *SDLTest_ImageBlitColor(); +SDL_Surface *SDLTest_ImageBlitAlpha(); +SDL_Surface *SDLTest_ImageBlitBlendAdd(); +SDL_Surface *SDLTest_ImageBlitBlend(); +SDL_Surface *SDLTest_ImageBlitBlendMod(); +SDL_Surface *SDLTest_ImageBlitBlendNone(); +SDL_Surface *SDLTest_ImageBlitBlendAll(); +SDL_Surface *SDLTest_ImageFace(); +SDL_Surface *SDLTest_ImagePrimitives(); +SDL_Surface *SDLTest_ImagePrimitivesBlend(); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_images_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_log.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_log.h new file mode 100644 index 00000000..73a5c016 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_log.h @@ -0,0 +1,67 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_log.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + * + * Wrapper to log in the TEST category + * + */ + +#ifndef _SDL_test_log_h +#define _SDL_test_log_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Prints given message with a timestamp in the TEST category and INFO priority. + * + * \param fmt Message to be logged + */ +void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * \brief Prints given message with a timestamp in the TEST category and the ERROR priority. + * + * \param fmt Message to be logged + */ +void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_log_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_md5.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_md5.h new file mode 100644 index 00000000..f2d9a7d7 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_md5.h @@ -0,0 +1,129 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_md5.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + *********************************************************************** + ** Header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** +*/ + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5Init ** + ** (2) Call MD5Update on mdContext and M ** + ** (3) Call MD5Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** +*/ + +#ifndef _SDL_test_md5_h +#define _SDL_test_md5_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------ Definitions --------- */ + +/* typedef a 32-bit type */ + typedef unsigned long int MD5UINT4; + +/* Data structure for MD5 (Message-Digest) computation */ + typedef struct { + MD5UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + MD5UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after Md5Final call */ + } SDLTest_Md5Context; + +/* ---------- Function Prototypes ------------- */ + +/** + * \brief initialize the context + * + * \param mdContext pointer to context variable + * + * Note: The function initializes the message-digest context + * mdContext. Call before each new use of the context - + * all fields are set to zero. + */ + void SDLTest_Md5Init(SDLTest_Md5Context * mdContext); + + +/** + * \brief update digest from variable length data + * + * \param mdContext pointer to context variable + * \param inBuf pointer to data array/string + * \param inLen length of data array/string + * + * Note: The function updates the message-digest context to account + * for the presence of each of the characters inBuf[0..inLen-1] + * in the message whose digest is being computed. +*/ + + void SDLTest_Md5Update(SDLTest_Md5Context * mdContext, unsigned char *inBuf, + unsigned int inLen); + + +/** + * \brief complete digest computation + * + * \param mdContext pointer to context variable + * + * Note: The function terminates the message-digest computation and + * ends with the desired message digest in mdContext.digest[0..15]. + * Always call before using the digest[] variable. +*/ + + void SDLTest_Md5Final(SDLTest_Md5Context * mdContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_md5_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_test_random.h b/packages/sdl2.2.0.5/build/native/include/SDL_test_random.h new file mode 100644 index 00000000..91c36526 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_test_random.h @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_random.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +/* + + A "32-bit Multiply with carry random number generator. Very fast. + Includes a list of recommended multipliers. + + multiply-with-carry generator: x(n) = a*x(n-1) + carry mod 2^32. + period: (a*2^31)-1 + +*/ + +#ifndef _SDL_test_random_h +#define _SDL_test_random_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* --- Definitions */ + +/* + * Macros that return a random number in a specific format. + */ +#define SDLTest_RandomInt(c) ((int)SDLTest_Random(c)) + +/* + * Context structure for the random number generator state. + */ + typedef struct { + unsigned int a; + unsigned int x; + unsigned int c; + unsigned int ah; + unsigned int al; + } SDLTest_RandomContext; + + +/* --- Function prototypes */ + +/** + * \brief Initialize random number generator with two integers. + * + * Note: The random sequence of numbers returned by ...Random() is the + * same for the same two integers and has a period of 2^31. + * + * \param rndContext pointer to context structure + * \param xi integer that defines the random sequence + * \param ci integer that defines the random sequence + * + */ + void SDLTest_RandomInit(SDLTest_RandomContext * rndContext, unsigned int xi, + unsigned int ci); + +/** + * \brief Initialize random number generator based on current system time. + * + * \param rndContext pointer to context structure + * + */ + void SDLTest_RandomInitTime(SDLTest_RandomContext *rndContext); + + +/** + * \brief Initialize random number generator based on current system time. + * + * Note: ...RandomInit() or ...RandomInitTime() must have been called + * before using this function. + * + * \param rndContext pointer to context structure + * + * \returns A random number (32bit unsigned integer) + * + */ + unsigned int SDLTest_Random(SDLTest_RandomContext *rndContext); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_test_random_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_thread.h b/packages/sdl2.2.0.5/build/native/include/SDL_thread.h new file mode 100644 index 00000000..377e6c73 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_thread.h @@ -0,0 +1,287 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_thread_h +#define _SDL_thread_h + +/** + * \file SDL_thread.h + * + * Header for the SDL thread management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/* Thread synchronization primitives */ +#include "SDL_atomic.h" +#include "SDL_mutex.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The SDL thread structure, defined in SDL_thread.c */ +struct SDL_Thread; +typedef struct SDL_Thread SDL_Thread; + +/* The SDL thread ID */ +typedef unsigned long SDL_threadID; + +/* Thread local storage ID, 0 is the invalid ID */ +typedef unsigned int SDL_TLSID; + +/** + * The SDL thread priority. + * + * \note On many systems you require special privileges to set high priority. + */ +typedef enum { + SDL_THREAD_PRIORITY_LOW, + SDL_THREAD_PRIORITY_NORMAL, + SDL_THREAD_PRIORITY_HIGH +} SDL_ThreadPriority; + +/** + * The function passed to SDL_CreateThread(). + * It is passed a void* user context parameter and returns an int. + */ +typedef int (SDLCALL * SDL_ThreadFunction) (void *data); + +#if defined(__WIN32__) && !defined(HAVE_LIBC) +/** + * \file SDL_thread.h + * + * We compile SDL into a DLL. This means, that it's the DLL which + * creates a new thread for the calling process with the SDL_CreateThread() + * API. There is a problem with this, that only the RTL of the SDL.DLL will + * be initialized for those threads, and not the RTL of the calling + * application! + * + * To solve this, we make a little hack here. + * + * We'll always use the caller's _beginthread() and _endthread() APIs to + * start a new thread. This way, if it's the SDL.DLL which uses this API, + * then the RTL of SDL.DLL will be used to create the new thread, and if it's + * the application, then the RTL of the application will be used. + * + * So, in short: + * Always use the _beginthread() and _endthread() of the calling runtime + * library! + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD +#include /* This has _beginthread() and _endthread() defined! */ + +typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, + unsigned (__stdcall * + func) (void + *), + void *arg, unsigned, + unsigned *threadID); +typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); + +/** + * Create a thread. + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + +/** + * Create a thread. + */ +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex) +#endif + +#else + +/** + * Create a thread. + * + * Thread naming is a little complicated: Most systems have very small + * limits for the string length (Haiku has 32 bytes, Linux currently has 16, + * Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll + * have to see what happens with your system's debugger. The name should be + * UTF-8 (but using the naming limits of C identifiers is a better bet). + * There are no requirements for thread naming conventions, so long as the + * string is null-terminated UTF-8, but these guidelines are helpful in + * choosing a name: + * + * http://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * If a system imposes requirements, SDL will try to munge the string for + * it (truncate, etc), but the original string contents will be available + * from SDL_GetThreadName(). + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data); + +#endif + +/** + * Get the thread name, as it was specified in SDL_CreateThread(). + * This function returns a pointer to a UTF-8 string that names the + * specified thread, or NULL if it doesn't have a name. This is internal + * memory, not to be free()'d by the caller, and remains valid until the + * specified thread is cleaned up by SDL_WaitThread(). + */ +extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread); + +/** + * Get the thread identifier for the current thread. + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void); + +/** + * Get the thread identifier for the specified thread. + * + * Equivalent to SDL_ThreadID() if the specified thread is NULL. + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_GetThreadID(SDL_Thread * thread); + +/** + * Set the priority for the current thread + */ +extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_ThreadPriority priority); + +/** + * Wait for a thread to finish. Threads that haven't been detached will + * remain (as a "zombie") until this function cleans them up. Not doing so + * is a resource leak. + * + * Once a thread has been cleaned up through this function, the SDL_Thread + * that references it becomes invalid and should not be referenced again. + * As such, only one thread may call SDL_WaitThread() on another. + * + * The return code for the thread function is placed in the area + * pointed to by \c status, if \c status is not NULL. + * + * You may not wait on a thread that has been used in a call to + * SDL_DetachThread(). Use either that function or this one, but not + * both, or behavior is undefined. + * + * It is safe to pass NULL to this function; it is a no-op. + */ +extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status); + +/** + * A thread may be "detached" to signify that it should not remain until + * another thread has called SDL_WaitThread() on it. Detaching a thread + * is useful for long-running threads that nothing needs to synchronize + * with or further manage. When a detached thread is done, it simply + * goes away. + * + * There is no way to recover the return code of a detached thread. If you + * need this, don't detach the thread and instead use SDL_WaitThread(). + * + * Once a thread is detached, you should usually assume the SDL_Thread isn't + * safe to reference again, as it will become invalid immediately upon + * the detached thread's exit, instead of remaining until someone has called + * SDL_WaitThread() to finally clean it up. As such, don't detach the same + * thread more than once. + * + * If a thread has already exited when passed to SDL_DetachThread(), it will + * stop waiting for a call to SDL_WaitThread() and clean up immediately. + * It is not safe to detach a thread that might be used with SDL_WaitThread(). + * + * You may not call SDL_WaitThread() on a thread that has been detached. + * Use either that function or this one, but not both, or behavior is + * undefined. + * + * It is safe to pass NULL to this function; it is a no-op. + */ +extern DECLSPEC void SDLCALL SDL_DetachThread(SDL_Thread * thread); + +/** + * \brief Create an identifier that is globally visible to all threads but refers to data that is thread-specific. + * + * \return The newly created thread local storage identifier, or 0 on error + * + * \code + * static SDL_SpinLock tls_lock; + * static SDL_TLSID thread_local_storage; + * + * void SetMyThreadData(void *value) + * { + * if (!thread_local_storage) { + * SDL_AtomicLock(&tls_lock); + * if (!thread_local_storage) { + * thread_local_storage = SDL_TLSCreate(); + * } + * SDL_AtomicUnlock(&tls_lock); + * } + * SDL_TLSSet(thread_local_storage, value, 0); + * } + * + * void *GetMyThreadData(void) + * { + * return SDL_TLSGet(thread_local_storage); + * } + * \endcode + * + * \sa SDL_TLSGet() + * \sa SDL_TLSSet() + */ +extern DECLSPEC SDL_TLSID SDLCALL SDL_TLSCreate(void); + +/** + * \brief Get the value associated with a thread local storage ID for the current thread. + * + * \param id The thread local storage ID + * + * \return The value associated with the ID for the current thread, or NULL if no value has been set. + * + * \sa SDL_TLSCreate() + * \sa SDL_TLSSet() + */ +extern DECLSPEC void * SDLCALL SDL_TLSGet(SDL_TLSID id); + +/** + * \brief Set the value associated with a thread local storage ID for the current thread. + * + * \param id The thread local storage ID + * \param value The value to associate with the ID for the current thread + * \param destructor A function called when the thread exits, to free the value. + * + * \return 0 on success, -1 on error + * + * \sa SDL_TLSCreate() + * \sa SDL_TLSGet() + */ +extern DECLSPEC int SDLCALL SDL_TLSSet(SDL_TLSID id, const void *value, void (*destructor)(void*)); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_thread_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_timer.h b/packages/sdl2.2.0.5/build/native/include/SDL_timer.h new file mode 100644 index 00000000..e0d3785e --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_timer.h @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_timer_h +#define _SDL_timer_h + +/** + * \file SDL_timer.h + * + * Header for the SDL time management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Get the number of milliseconds since the SDL library initialization. + * + * \note This value wraps if the program runs for more than ~49 days. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); + +/** + * \brief Compare SDL ticks values, and return true if A has passed B + * + * e.g. if you want to wait 100 ms, you could do this: + * Uint32 timeout = SDL_GetTicks() + 100; + * while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { + * ... do work until timeout has elapsed + * } + */ +#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) + +/** + * \brief Get the current value of the high resolution counter + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceCounter(void); + +/** + * \brief Get the count per second of the high resolution counter + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void); + +/** + * \brief Wait a specified number of milliseconds before returning. + */ +extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); + +/** + * Function prototype for the timer callback function. + * + * The callback function is passed the current timer interval and returns + * the next timer interval. If the returned value is the same as the one + * passed in, the periodic alarm continues, otherwise a new alarm is + * scheduled. If the callback returns 0, the periodic alarm is cancelled. + */ +typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param); + +/** + * Definition of the timer ID type. + */ +typedef int SDL_TimerID; + +/** + * \brief Add a new timer to the pool of timers already running. + * + * \return A timer ID, or 0 when an error occurs. + */ +extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval, + SDL_TimerCallback callback, + void *param); + +/** + * \brief Remove a timer knowing its ID. + * + * \return A boolean value indicating success or failure. + * + * \warning It is not safe to remove a timer multiple times. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL_TimerID id); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_timer_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_touch.h b/packages/sdl2.2.0.5/build/native/include/SDL_touch.h new file mode 100644 index 00000000..2643e367 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_touch.h @@ -0,0 +1,86 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_touch.h + * + * Include file for SDL touch event handling. + */ + +#ifndef _SDL_touch_h +#define _SDL_touch_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_TouchID; +typedef Sint64 SDL_FingerID; + +typedef struct SDL_Finger +{ + SDL_FingerID id; + float x; + float y; + float pressure; +} SDL_Finger; + +/* Used as the device ID for mouse events simulated with touch input */ +#define SDL_TOUCH_MOUSEID ((Uint32)-1) + + +/* Function prototypes */ + +/** + * \brief Get the number of registered touch devices. + */ +extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void); + +/** + * \brief Get the touch ID with the given index, or 0 if the index is invalid. + */ +extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index); + +/** + * \brief Get the number of active fingers for a given touch device. + */ +extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID); + +/** + * \brief Get the finger object of the given touch, with the given index. + */ +extern DECLSPEC SDL_Finger * SDLCALL SDL_GetTouchFinger(SDL_TouchID touchID, int index); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_touch_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_types.h b/packages/sdl2.2.0.5/build/native/include/SDL_types.h new file mode 100644 index 00000000..5118af21 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_types.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_types.h + * + * \deprecated + */ + +/* DEPRECATED */ +#include "SDL_stdinc.h" diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_version.h b/packages/sdl2.2.0.5/build/native/include/SDL_version.h new file mode 100644 index 00000000..1700efdd --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_version.h @@ -0,0 +1,162 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_version.h + * + * This header defines the current SDL version. + */ + +#ifndef _SDL_version_h +#define _SDL_version_h + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Information the version of SDL in use. + * + * Represents the library's version as three levels: major revision + * (increments with massive changes, additions, and enhancements), + * minor revision (increments with backwards-compatible changes to the + * major revision), and patchlevel (increments with fixes to the minor + * revision). + * + * \sa SDL_VERSION + * \sa SDL_GetVersion + */ +typedef struct SDL_version +{ + Uint8 major; /**< major version */ + Uint8 minor; /**< minor version */ + Uint8 patch; /**< update version */ +} SDL_version; + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_MAJOR_VERSION 2 +#define SDL_MINOR_VERSION 0 +#define SDL_PATCHLEVEL 5 + +/** + * \brief Macro to determine SDL version program was compiled against. + * + * This macro fills in a SDL_version structure with the version of the + * library you compiled against. This is determined by what header the + * compiler uses. Note that if you dynamically linked the library, you might + * have a slightly newer or older version at runtime. That version can be + * determined with SDL_GetVersion(), which, unlike SDL_VERSION(), + * is not a macro. + * + * \param x A pointer to a SDL_version struct to initialize. + * + * \sa SDL_version + * \sa SDL_GetVersion + */ +#define SDL_VERSION(x) \ +{ \ + (x)->major = SDL_MAJOR_VERSION; \ + (x)->minor = SDL_MINOR_VERSION; \ + (x)->patch = SDL_PATCHLEVEL; \ +} + +/** + * This macro turns the version numbers into a numeric value: + * \verbatim + (1,2,3) -> (1203) + \endverbatim + * + * This assumes that there will never be more than 100 patchlevels. + */ +#define SDL_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) + +/** + * This is the version number macro for the current SDL version. + */ +#define SDL_COMPILEDVERSION \ + SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) + +/** + * This macro will evaluate to true if compiled with SDL at least X.Y.Z. + */ +#define SDL_VERSION_ATLEAST(X, Y, Z) \ + (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) + +/** + * \brief Get the version of SDL that is linked against your program. + * + * If you are linking to SDL dynamically, then it is possible that the + * current version will be different than the version you compiled against. + * This function returns the current version, while SDL_VERSION() is a + * macro that tells you what version you compiled with. + * + * \code + * SDL_version compiled; + * SDL_version linked; + * + * SDL_VERSION(&compiled); + * SDL_GetVersion(&linked); + * printf("We compiled against SDL version %d.%d.%d ...\n", + * compiled.major, compiled.minor, compiled.patch); + * printf("But we linked against SDL version %d.%d.%d.\n", + * linked.major, linked.minor, linked.patch); + * \endcode + * + * This function may be called safely at any time, even before SDL_Init(). + * + * \sa SDL_VERSION + */ +extern DECLSPEC void SDLCALL SDL_GetVersion(SDL_version * ver); + +/** + * \brief Get the code revision of SDL that is linked against your program. + * + * Returns an arbitrary string (a hash value) uniquely identifying the + * exact revision of the SDL library in use, and is only useful in comparing + * against other revisions. It is NOT an incrementing number. + */ +extern DECLSPEC const char *SDLCALL SDL_GetRevision(void); + +/** + * \brief Get the revision number of SDL that is linked against your program. + * + * Returns a number uniquely identifying the exact revision of the SDL + * library in use. It is an incrementing number based on commits to + * hg.libsdl.org. + */ +extern DECLSPEC int SDLCALL SDL_GetRevisionNumber(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_version_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/packages/sdl2.2.0.5/build/native/include/SDL_video.h b/packages/sdl2.2.0.5/build/native/include/SDL_video.h new file mode 100644 index 00000000..73c33eb3 --- /dev/null +++ b/packages/sdl2.2.0.5/build/native/include/SDL_video.h @@ -0,0 +1,1218 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_video.h + * + * Header file for SDL video functions. + */ + +#ifndef _SDL_video_h +#define _SDL_video_h + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The structure that defines a display mode + * + * \sa SDL_GetNumDisplayModes() + * \sa SDL_GetDisplayMode() + * \sa SDL_GetDesktopDisplayMode() + * \sa SDL_GetCurrentDisplayMode() + * \sa SDL_GetClosestDisplayMode() + * \sa SDL_SetWindowDisplayMode() + * \sa SDL_GetWindowDisplayMode() + */ +typedef struct +{ + Uint32 format; /**< pixel format */ + int w; /**< width, in screen coordinates */ + int h; /**< height, in screen coordinates */ + int refresh_rate; /**< refresh rate (or zero for unspecified) */ + void *driverdata; /**< driver-specific data, initialize to 0 */ +} SDL_DisplayMode; + +/** + * \brief The type used to identify a window + * + * \sa SDL_CreateWindow() + * \sa SDL_CreateWindowFrom() + * \sa SDL_DestroyWindow() + * \sa SDL_GetWindowData() + * \sa SDL_GetWindowFlags() + * \sa SDL_GetWindowGrab() + * \sa SDL_GetWindowPosition() + * \sa SDL_GetWindowSize() + * \sa SDL_GetWindowTitle() + * \sa SDL_HideWindow() + * \sa SDL_MaximizeWindow() + * \sa SDL_MinimizeWindow() + * \sa SDL_RaiseWindow() + * \sa SDL_RestoreWindow() + * \sa SDL_SetWindowData() + * \sa SDL_SetWindowFullscreen() + * \sa SDL_SetWindowGrab() + * \sa SDL_SetWindowIcon() + * \sa SDL_SetWindowPosition() + * \sa SDL_SetWindowSize() + * \sa SDL_SetWindowBordered() + * \sa SDL_SetWindowResizable() + * \sa SDL_SetWindowTitle() + * \sa SDL_ShowWindow() + */ +typedef struct SDL_Window SDL_Window; + +/** + * \brief The flags on a window + * + * \sa SDL_GetWindowFlags() + */ +typedef enum +{ + /* !!! FIXME: change this to name = (1<